From 46368c37e5e8ed3c6f47dca7263741a57f958a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9C=E5=87=AF?= Date: Fri, 6 Jan 2023 18:20:37 +0800 Subject: [PATCH] [Update] first commit --- APACHE.license | 201 + AUTHORS | 23 + CMakeLists.txt | 218 + COPYING | 126 + ChangeLog | 17 + INSTALL | 265 + LGPL.license | 475 + NEWS | 0 README | 63 + README.PACKAGE | 11 + REQUESTS | 4 + cmake/CLuceneBoost.cmake | 23 + cmake/CLuceneDocs.cmake | 151 + cmake/CreateClucenePackages.cmake | 91 + cmake/DefineOptions.cmake | 53 + cmake/Toolchain-g++32.cmake | 20 + cmake/Toolchain-llvm.cmake | 8 + cmake/Toolchain-mingw32.cmake | 32 + cmake/TurboPFOR.cmake | 15 + cmake/cmake_uninstall.cmake.in | 23 + dist-test.sh | 272 + doc/Doxyfile.cmake | 237 + doc/coding standards.txt | 113 + doc/doxygen.css.cmake | 163 + doc/helpfooter.htm.cmake | 4 + doc/helpheader.htm.cmake | 24 + .../analysis/LanguageBasedAnalyzer.cpp | 65 + .../CLucene/analysis/LanguageBasedAnalyzer.h | 26 + .../CLucene/analysis/PorterStemmer.cpp | 313 + .../CLucene/analysis/PorterStemmer.h | 151 + .../CLucene/analysis/cjk/CJKAnalyzer.cpp | 190 + .../CLucene/analysis/cjk/CJKAnalyzer.h | 94 + .../CLucene/analysis/de/GermanAnalyzer.cpp | 149 + .../CLucene/analysis/de/GermanAnalyzer.h | 108 + .../CLucene/analysis/de/GermanStemFilter.cpp | 60 + .../CLucene/analysis/de/GermanStemFilter.h | 54 + .../CLucene/analysis/de/GermanStemmer.cpp | 213 + .../CLucene/analysis/de/GermanStemmer.h | 98 + .../CLucene/highlighter/Encoder.cpp | 19 + .../CLucene/highlighter/Encoder.h | 56 + .../CLucene/highlighter/Formatter.cpp | 18 + .../CLucene/highlighter/Formatter.h | 49 + .../CLucene/highlighter/Fragmenter.cpp | 19 + .../CLucene/highlighter/Fragmenter.h | 52 + .../CLucene/highlighter/HighlightScorer.h | 63 + .../CLucene/highlighter/Highlighter.cpp | 525 + .../CLucene/highlighter/Highlighter.h | 226 + .../CLucene/highlighter/QueryScorer.cpp | 118 + .../CLucene/highlighter/QueryScorer.h | 114 + .../highlighter/QueryTermExtractor.cpp | 135 + .../CLucene/highlighter/QueryTermExtractor.h | 82 + src/contribs-lib/CLucene/highlighter/Scorer.h | 61 + .../CLucene/highlighter/SimpleFragmenter.cpp | 55 + .../CLucene/highlighter/SimpleFragmenter.h | 70 + .../CLucene/highlighter/SimpleHTMLEncoder.cpp | 83 + .../CLucene/highlighter/SimpleHTMLEncoder.h | 45 + .../highlighter/SimpleHTMLFormatter.cpp | 56 + .../CLucene/highlighter/SimpleHTMLFormatter.h | 59 + .../CLucene/highlighter/TextFragment.cpp | 78 + .../CLucene/highlighter/TextFragment.h | 87 + .../CLucene/highlighter/TokenGroup.cpp | 123 + .../CLucene/highlighter/TokenGroup.h | 83 + .../CLucene/highlighter/TokenSources.cpp | 229 + .../CLucene/highlighter/TokenSources.h | 86 + .../CLucene/highlighter/WeightedTerm.cpp | 101 + .../CLucene/highlighter/WeightedTerm.h | 79 + .../CLucene/snowball/SNOWBALL_README | 82 + .../CLucene/snowball/Snowball.cpp | 137 + .../CLucene/snowball/SnowballAnalyzer.h | 44 + .../CLucene/snowball/SnowballFilter.h | 41 + .../CLucene/snowball/include/libstemmer.h | 82 + .../CLucene/snowball/libstemmer.h | 79 + .../CLucene/snowball/libstemmer/libstemmer.c | 92 + .../CLucene/snowball/libstemmer/modules.h | 166 + .../CLucene/snowball/runtime/api.c | 69 + .../CLucene/snowball/runtime/api.h | 30 + .../CLucene/snowball/runtime/header.h | 61 + .../CLucene/snowball/runtime/utilities.c | 446 + .../CLucene/snowball/snowball.version | 2 + .../snowball/src_c/stem_ISO_8859_1_danish.c | 338 + .../snowball/src_c/stem_ISO_8859_1_danish.h | 16 + .../snowball/src_c/stem_ISO_8859_1_dutch.c | 635 + .../snowball/src_c/stem_ISO_8859_1_dutch.h | 16 + .../snowball/src_c/stem_ISO_8859_1_english.c | 1156 + .../snowball/src_c/stem_ISO_8859_1_english.h | 16 + .../snowball/src_c/stem_ISO_8859_1_finnish.c | 792 + .../snowball/src_c/stem_ISO_8859_1_finnish.h | 16 + .../snowball/src_c/stem_ISO_8859_1_french.c | 1276 + .../snowball/src_c/stem_ISO_8859_1_french.h | 16 + .../snowball/src_c/stem_ISO_8859_1_german.c | 512 + .../snowball/src_c/stem_ISO_8859_1_german.h | 16 + .../snowball/src_c/stem_ISO_8859_1_italian.c | 1091 + .../snowball/src_c/stem_ISO_8859_1_italian.h | 16 + .../src_c/stem_ISO_8859_1_norwegian.c | 296 + .../src_c/stem_ISO_8859_1_norwegian.h | 16 + .../snowball/src_c/stem_ISO_8859_1_porter.c | 776 + .../snowball/src_c/stem_ISO_8859_1_porter.h | 16 + .../src_c/stem_ISO_8859_1_portuguese.c | 1035 + .../src_c/stem_ISO_8859_1_portuguese.h | 16 + .../snowball/src_c/stem_ISO_8859_1_spanish.c | 1119 + .../snowball/src_c/stem_ISO_8859_1_spanish.h | 16 + .../snowball/src_c/stem_ISO_8859_1_swedish.c | 307 + .../snowball/src_c/stem_ISO_8859_1_swedish.h | 16 + .../snowball/src_c/stem_KOI8_R_russian.c | 701 + .../snowball/src_c/stem_KOI8_R_russian.h | 16 + .../snowball/src_c/stem_UTF_8_danish.c | 344 + .../snowball/src_c/stem_UTF_8_danish.h | 16 + .../CLucene/snowball/src_c/stem_UTF_8_dutch.c | 653 + .../CLucene/snowball/src_c/stem_UTF_8_dutch.h | 16 + .../snowball/src_c/stem_UTF_8_english.c | 1178 + .../snowball/src_c/stem_UTF_8_english.h | 16 + .../snowball/src_c/stem_UTF_8_finnish.c | 808 + .../snowball/src_c/stem_UTF_8_finnish.h | 16 + .../snowball/src_c/stem_UTF_8_french.c | 1296 + .../snowball/src_c/stem_UTF_8_french.h | 16 + .../snowball/src_c/stem_UTF_8_german.c | 526 + .../snowball/src_c/stem_UTF_8_german.h | 16 + .../snowball/src_c/stem_UTF_8_italian.c | 1113 + .../snowball/src_c/stem_UTF_8_italian.h | 16 + .../snowball/src_c/stem_UTF_8_norwegian.c | 302 + .../snowball/src_c/stem_UTF_8_norwegian.h | 16 + .../snowball/src_c/stem_UTF_8_porter.c | 794 + .../snowball/src_c/stem_UTF_8_porter.h | 16 + .../snowball/src_c/stem_UTF_8_portuguese.c | 1055 + .../snowball/src_c/stem_UTF_8_portuguese.h | 16 + .../snowball/src_c/stem_UTF_8_russian.c | 709 + .../snowball/src_c/stem_UTF_8_russian.h | 16 + .../snowball/src_c/stem_UTF_8_spanish.c | 1137 + .../snowball/src_c/stem_UTF_8_spanish.h | 16 + .../snowball/src_c/stem_UTF_8_swedish.c | 313 + .../snowball/src_c/stem_UTF_8_swedish.h | 16 + .../CLucene/util/arrayinputstream.h | 68 + .../CLucene/util/byteinputstream.h | 17 + .../CLucene/util/gzipcompressstream.cpp | 126 + .../CLucene/util/gzipcompressstream.h | 34 + .../CLucene/util/gzipinputstream.cpp | 184 + .../CLucene/util/gzipinputstream.h | 39 + src/contribs-lib/CLucene/util/streamarray.h | 32 + src/contribs-lib/CMakeLists.txt | 114 + src/contribs-lib/cmake/FindIconv.cmake | 57 + src/contribs/CMakeLists.txt | 2 + .../bashscripts/findPatchThatBrokeUnitTest.sh | 113 + src/contribs/bashscripts/simpleupdate.sh | 41 + src/contribs/bashscripts/twofileupdate.sh | 42 + src/contribs/benchmarker/Benchmarker.cpp | 39 + src/contribs/benchmarker/Benchmarker.h | 23 + src/contribs/benchmarker/CMakeLists.txt | 20 + src/contribs/benchmarker/Main.cpp | 109 + src/contribs/benchmarker/TestCLString.cpp | 57 + src/contribs/benchmarker/TestCLString.h | 23 + src/contribs/benchmarker/Timer.h | 48 + src/contribs/benchmarker/Unit.cpp | 94 + src/contribs/benchmarker/Unit.h | 29 + src/contribs/benchmarker/stdafx.cpp | 11 + src/contribs/benchmarker/stdafx.h | 37 + src/contribs/contribs-lib-test/CMakeLists.txt | 33 + src/contribs/contribs-lib-test/CuTest.cpp | 536 + src/contribs/contribs-lib-test/CuTest.h | 122 + .../contribs-lib-test/TestAnalysis.cpp | 190 + .../contribs-lib-test/TestHighlight.cpp | 269 + .../contribs-lib-test/TestSnowball.cpp | 36 + .../contribs-lib-test/TestStreams.cpp | 66 + src/contribs/contribs-lib-test/TestUtf8.cpp | 189 + .../contribs-lib-test/contribTests.cpp | 16 + src/contribs/contribs-lib-test/test.h | 50 + src/contribs/contribs-lib-test/testall.cpp | 216 + src/core/CLucene.h | 48 + src/core/CLucene/CLConfig.h | 236 + src/core/CLucene/CLMonolithic.cpp | 137 + src/core/CLucene/StdHeader.cpp | 44 + src/core/CLucene/StdHeader.h | 40 + src/core/CLucene/_ApiHeader.h | 24 + src/core/CLucene/analysis/AnalysisHeader.cpp | 85 + src/core/CLucene/analysis/AnalysisHeader.h | 362 + src/core/CLucene/analysis/Analyzers.cpp | 595 + src/core/CLucene/analysis/Analyzers.h | 462 + .../CLucene/analysis/CachingTokenFilter.cpp | 66 + .../CLucene/analysis/CachingTokenFilter.h | 33 + .../analysis/standard/StandardAnalyzer.cpp | 106 + .../analysis/standard/StandardAnalyzer.h | 75 + .../analysis/standard/StandardFilter.cpp | 58 + .../analysis/standard/StandardFilter.h | 35 + .../analysis/standard/StandardTokenizer.cpp | 465 + .../analysis/standard/StandardTokenizer.h | 88 + .../standard/StandardTokenizerConstants.h | 27 + src/core/CLucene/debug/error.cpp | 108 + src/core/CLucene/debug/error.h | 105 + src/core/CLucene/debug/lucenebase.h | 44 + src/core/CLucene/debug/mem.h | 64 + src/core/CLucene/document/DateField.cpp | 61 + src/core/CLucene/document/DateField.h | 59 + src/core/CLucene/document/DateTools.cpp | 292 + src/core/CLucene/document/DateTools.h | 101 + src/core/CLucene/document/Document.cpp | 183 + src/core/CLucene/document/Document.h | 178 + src/core/CLucene/document/Field.cpp | 336 + src/core/CLucene/document/Field.h | 328 + src/core/CLucene/document/FieldSelector.cpp | 65 + src/core/CLucene/document/FieldSelector.h | 142 + src/core/CLucene/document/NumberTools.cpp | 99 + src/core/CLucene/document/NumberTools.h | 78 + src/core/CLucene/index/CompoundFile.cpp | 456 + .../CLucene/index/DirectoryIndexReader.cpp | 302 + src/core/CLucene/index/DirectoryIndexReader.h | 139 + src/core/CLucene/index/DocumentsWriter.cpp | 1683 + .../index/DocumentsWriterThreadState.cpp | 1326 + src/core/CLucene/index/FieldInfos.cpp | 236 + src/core/CLucene/index/FieldsReader.cpp | 565 + src/core/CLucene/index/FieldsWriter.cpp | 269 + .../CLucene/index/IndexDeletionPolicy.cpp | 140 + src/core/CLucene/index/IndexDeletionPolicy.h | 152 + src/core/CLucene/index/IndexFileDeleter.cpp | 530 + .../CLucene/index/IndexFileNameFilter.cpp | 84 + src/core/CLucene/index/IndexFileNames.cpp | 179 + src/core/CLucene/index/IndexModifier.cpp | 277 + src/core/CLucene/index/IndexModifier.h | 332 + src/core/CLucene/index/IndexReader.cpp | 532 + src/core/CLucene/index/IndexReader.h | 688 + src/core/CLucene/index/IndexWriter.cpp | 2917 + src/core/CLucene/index/IndexWriter.h | 1370 + src/core/CLucene/index/MergePolicy.cpp | 521 + src/core/CLucene/index/MergePolicy.h | 438 + src/core/CLucene/index/MergeScheduler.cpp | 34 + src/core/CLucene/index/MergeScheduler.h | 50 + src/core/CLucene/index/MultiReader.cpp | 363 + src/core/CLucene/index/MultiReader.h | 129 + src/core/CLucene/index/MultiSegmentReader.cpp | 904 + .../CLucene/index/MultipleTermPositions.cpp | 199 + .../CLucene/index/MultipleTermPositions.h | 92 + src/core/CLucene/index/Payload.cpp | 108 + src/core/CLucene/index/Payload.h | 128 + src/core/CLucene/index/SDocumentWriter.cpp | 1342 + src/core/CLucene/index/SDocumentWriter.h | 786 + src/core/CLucene/index/SegmentInfos.cpp | 1133 + src/core/CLucene/index/SegmentMergeInfo.cpp | 107 + src/core/CLucene/index/SegmentMergeQueue.cpp | 76 + src/core/CLucene/index/SegmentMerger.cpp | 813 + src/core/CLucene/index/SegmentReader.cpp | 1126 + src/core/CLucene/index/SegmentTermDocs.cpp | 210 + src/core/CLucene/index/SegmentTermEnum.cpp | 395 + .../CLucene/index/SegmentTermPositions.cpp | 169 + src/core/CLucene/index/SegmentTermVector.cpp | 156 + src/core/CLucene/index/SkipListReader.cpp | 357 + src/core/CLucene/index/SkipListWriter.cpp | 187 + src/core/CLucene/index/Term.cpp | 450 + src/core/CLucene/index/Term.h | 177 + src/core/CLucene/index/TermInfo.cpp | 98 + src/core/CLucene/index/TermInfosReader.cpp | 477 + src/core/CLucene/index/TermInfosWriter.cpp | 418 + src/core/CLucene/index/TermVector.h | 159 + src/core/CLucene/index/TermVectorReader.cpp | 551 + src/core/CLucene/index/TermVectorWriter.cpp | 230 + src/core/CLucene/index/Terms.cpp | 30 + src/core/CLucene/index/Terms.h | 189 + src/core/CLucene/index/_CompoundFile.h | 144 + src/core/CLucene/index/_DocumentsWriter.h | 1005 + src/core/CLucene/index/_FieldInfo.h | 13 + src/core/CLucene/index/_FieldInfos.h | 199 + src/core/CLucene/index/_FieldsReader.h | 169 + src/core/CLucene/index/_FieldsWriter.h | 62 + src/core/CLucene/index/_IndexFileDeleter.h | 224 + src/core/CLucene/index/_IndexFileNameFilter.h | 54 + src/core/CLucene/index/_IndexFileNames.h | 55 + src/core/CLucene/index/_MultiSegmentReader.h | 232 + src/core/CLucene/index/_SegmentHeader.h | 451 + src/core/CLucene/index/_SegmentInfos.h | 532 + src/core/CLucene/index/_SegmentMergeInfo.h | 48 + src/core/CLucene/index/_SegmentMergeQueue.h | 34 + src/core/CLucene/index/_SegmentMerger.h | 198 + src/core/CLucene/index/_SegmentTermEnum.h | 133 + src/core/CLucene/index/_SkipListReader.h | 183 + src/core/CLucene/index/_SkipListWriter.h | 130 + src/core/CLucene/index/_Term.h | 36 + src/core/CLucene/index/_TermInfo.h | 52 + src/core/CLucene/index/_TermInfosReader.h | 131 + src/core/CLucene/index/_TermInfosWriter.h | 148 + src/core/CLucene/index/_TermVector.h | 330 + src/core/CLucene/index/bpacking.cpp | 13859 + src/core/CLucene/index/bpacking.h | 726 + src/core/CLucene/index/common.h | 26 + src/core/CLucene/index/compression.h | 88 + src/core/CLucene/index/turbocompression.h | 183 + src/core/CLucene/index/turbopacking32.h | 3836 + src/core/CLucene/index/turbopacking64.h | 9695 + src/core/CLucene/index/util.h | 83 + .../CLucene/queryParser/FastCharStream.cpp | 121 + .../queryParser/MultiFieldQueryParser.cpp | 181 + .../queryParser/MultiFieldQueryParser.h | 163 + src/core/CLucene/queryParser/QueryParser.cpp | 1504 + src/core/CLucene/queryParser/QueryParser.h | 530 + .../queryParser/QueryParserConstants.h | 68 + .../queryParser/QueryParserTokenManager.cpp | 1265 + .../queryParser/QueryParserTokenManager.h | 112 + src/core/CLucene/queryParser/QueryToken.cpp | 51 + src/core/CLucene/queryParser/QueryToken.h | 94 + src/core/CLucene/queryParser/_CharStream.h | 121 + .../CLucene/queryParser/_FastCharStream.h | 66 + src/core/CLucene/queryParser/legacy/Lexer.cpp | 371 + .../legacy/MultiFieldQueryParser.cpp | 216 + .../legacy/MultiFieldQueryParser.h | 131 + .../queryParser/legacy/QueryParser.cpp | 507 + .../CLucene/queryParser/legacy/QueryParser.h | 336 + .../queryParser/legacy/QueryParserBase.cpp | 384 + .../CLucene/queryParser/legacy/QueryToken.cpp | 72 + .../CLucene/queryParser/legacy/QueryToken.h | 70 + .../CLucene/queryParser/legacy/TokenList.cpp | 79 + src/core/CLucene/queryParser/legacy/_Lexer.h | 65 + .../CLucene/queryParser/legacy/_TokenList.h | 36 + src/core/CLucene/search/BooleanClause.h | 107 + src/core/CLucene/search/BooleanQuery.cpp | 581 + src/core/CLucene/search/BooleanQuery.h | 159 + src/core/CLucene/search/BooleanScorer.cpp | 299 + src/core/CLucene/search/BooleanScorer2.cpp | 688 + src/core/CLucene/search/CachingSpanFilter.cpp | 120 + src/core/CLucene/search/CachingSpanFilter.h | 60 + .../CLucene/search/CachingWrapperFilter.cpp | 114 + .../CLucene/search/CachingWrapperFilter.h | 66 + src/core/CLucene/search/ChainedFilter.cpp | 219 + src/core/CLucene/search/ChainedFilter.h | 86 + src/core/CLucene/search/Compare.cpp | 120 + src/core/CLucene/search/Compare.h | 74 + src/core/CLucene/search/ConjunctionScorer.cpp | 133 + .../CLucene/search/ConstantScoreQuery.cpp | 313 + src/core/CLucene/search/ConstantScoreQuery.h | 125 + src/core/CLucene/search/DateFilter.cpp | 98 + src/core/CLucene/search/DateFilter.h | 61 + .../CLucene/search/DisjunctionSumScorer.cpp | 201 + src/core/CLucene/search/ExactPhraseScorer.cpp | 91 + src/core/CLucene/search/Explanation.cpp | 176 + src/core/CLucene/search/Explanation.h | 120 + src/core/CLucene/search/FieldCache.cpp | 65 + src/core/CLucene/search/FieldCache.h | 174 + src/core/CLucene/search/FieldCacheImpl.cpp | 577 + src/core/CLucene/search/FieldDoc.h | 52 + .../CLucene/search/FieldDocSortedHitQueue.cpp | 171 + .../CLucene/search/FieldSortedHitQueue.cpp | 258 + src/core/CLucene/search/FieldSortedHitQueue.h | 196 + src/core/CLucene/search/Filter.h | 42 + src/core/CLucene/search/FilterResultCache.cpp | 48 + src/core/CLucene/search/FilterResultCache.h | 68 + src/core/CLucene/search/FilteredTermEnum.cpp | 119 + src/core/CLucene/search/FilteredTermEnum.h | 58 + src/core/CLucene/search/FuzzyQuery.cpp | 425 + src/core/CLucene/search/FuzzyQuery.h | 204 + src/core/CLucene/search/HitQueue.cpp | 108 + src/core/CLucene/search/Hits.cpp | 232 + src/core/CLucene/search/Hits.h | 102 + src/core/CLucene/search/IndexSearcher.cpp | 441 + src/core/CLucene/search/IndexSearcher.h | 100 + src/core/CLucene/search/MatchAllDocsQuery.cpp | 201 + src/core/CLucene/search/MatchAllDocsQuery.h | 74 + src/core/CLucene/search/MultiPhraseQuery.cpp | 441 + src/core/CLucene/search/MultiPhraseQuery.h | 116 + src/core/CLucene/search/MultiSearcher.cpp | 244 + src/core/CLucene/search/MultiSearcher.h | 81 + src/core/CLucene/search/MultiTermQuery.cpp | 104 + src/core/CLucene/search/MultiTermQuery.h | 64 + src/core/CLucene/search/PhrasePositions.cpp | 114 + src/core/CLucene/search/PhraseQuery.cpp | 485 + src/core/CLucene/search/PhraseQuery.h | 107 + src/core/CLucene/search/PhraseScorer.cpp | 223 + src/core/CLucene/search/PrefixQuery.cpp | 311 + src/core/CLucene/search/PrefixQuery.h | 80 + src/core/CLucene/search/Query.h | 154 + src/core/CLucene/search/QueryFilter.cpp | 88 + src/core/CLucene/search/QueryFilter.h | 40 + src/core/CLucene/search/RangeFilter.cpp | 148 + src/core/CLucene/search/RangeFilter.h | 75 + src/core/CLucene/search/RangeQuery.cpp | 194 + src/core/CLucene/search/RangeQuery.h | 92 + src/core/CLucene/search/Scorer.cpp | 41 + src/core/CLucene/search/Scorer.h | 134 + src/core/CLucene/search/ScorerDocQueue.cpp | 191 + src/core/CLucene/search/ScorerDocQueue.h | 54 + src/core/CLucene/search/SearchHeader.cpp | 232 + src/core/CLucene/search/SearchHeader.h | 152 + src/core/CLucene/search/Searchable.h | 182 + src/core/CLucene/search/Similarity.cpp | 243 + src/core/CLucene/search/Similarity.h | 279 + .../CLucene/search/SloppyPhraseScorer.cpp | 175 + src/core/CLucene/search/Sort.cpp | 340 + src/core/CLucene/search/Sort.h | 426 + src/core/CLucene/search/SpanFilter.h | 39 + src/core/CLucene/search/SpanFilterResult.h | 130 + src/core/CLucene/search/SpanQueryFilter.cpp | 89 + src/core/CLucene/search/SpanQueryFilter.h | 74 + src/core/CLucene/search/TermQuery.cpp | 251 + src/core/CLucene/search/TermQuery.h | 52 + src/core/CLucene/search/TermScorer.cpp | 129 + src/core/CLucene/search/WildcardQuery.cpp | 151 + src/core/CLucene/search/WildcardQuery.h | 70 + src/core/CLucene/search/WildcardTermEnum.cpp | 182 + src/core/CLucene/search/WildcardTermEnum.h | 65 + src/core/CLucene/search/_BooleanScorer.h | 101 + src/core/CLucene/search/_BooleanScorer2.h | 46 + src/core/CLucene/search/_ConjunctionScorer.h | 41 + .../CLucene/search/_DisjunctionSumScorer.h | 139 + src/core/CLucene/search/_ExactPhraseScorer.h | 28 + src/core/CLucene/search/_FieldCacheImpl.h | 119 + .../CLucene/search/_FieldDocSortedHitQueue.h | 120 + src/core/CLucene/search/_HitQueue.h | 57 + src/core/CLucene/search/_PhrasePositions.h | 44 + src/core/CLucene/search/_PhraseQueue.h | 38 + src/core/CLucene/search/_PhraseScorer.h | 78 + src/core/CLucene/search/_SloppyPhraseScorer.h | 78 + src/core/CLucene/search/_TermScorer.h | 82 + .../CLucene/search/spans/NearSpansOrdered.cpp | 285 + .../search/spans/NearSpansUnordered.cpp | 271 + .../CLucene/search/spans/SpanFirstQuery.cpp | 205 + .../CLucene/search/spans/SpanFirstQuery.h | 66 + .../CLucene/search/spans/SpanNearQuery.cpp | 204 + src/core/CLucene/search/spans/SpanNearQuery.h | 112 + .../CLucene/search/spans/SpanNotQuery.cpp | 274 + src/core/CLucene/search/spans/SpanNotQuery.h | 67 + src/core/CLucene/search/spans/SpanOrQuery.cpp | 304 + src/core/CLucene/search/spans/SpanOrQuery.h | 104 + src/core/CLucene/search/spans/SpanQuery.h | 40 + src/core/CLucene/search/spans/SpanScorer.cpp | 122 + src/core/CLucene/search/spans/SpanScorer.h | 51 + .../CLucene/search/spans/SpanTermQuery.cpp | 104 + src/core/CLucene/search/spans/SpanTermQuery.h | 59 + src/core/CLucene/search/spans/SpanWeight.cpp | 180 + src/core/CLucene/search/spans/SpanWeight.h | 46 + src/core/CLucene/search/spans/Spans.h | 54 + src/core/CLucene/search/spans/TermSpans.cpp | 99 + src/core/CLucene/search/spans/_EmptySpans.h | 35 + .../CLucene/search/spans/_NearSpansOrdered.h | 106 + .../search/spans/_NearSpansUnordered.h | 103 + src/core/CLucene/search/spans/_TermSpans.h | 47 + src/core/CLucene/store/ByteArrayDataInput.cpp | 148 + src/core/CLucene/store/ByteArrayDataInput.h | 68 + src/core/CLucene/store/Directory.cpp | 78 + src/core/CLucene/store/Directory.h | 100 + src/core/CLucene/store/FSDirectory.cpp | 693 + src/core/CLucene/store/FSDirectory.h | 168 + src/core/CLucene/store/IndexInput.cpp | 323 + src/core/CLucene/store/IndexInput.h | 202 + src/core/CLucene/store/IndexOutput.cpp | 240 + src/core/CLucene/store/IndexOutput.h | 175 + src/core/CLucene/store/Lock.cpp | 174 + src/core/CLucene/store/Lock.h | 50 + src/core/CLucene/store/LockFactory.cpp | 159 + src/core/CLucene/store/LockFactory.h | 77 + src/core/CLucene/store/MMapInput.cpp | 301 + src/core/CLucene/store/RAMDirectory.cpp | 579 + src/core/CLucene/store/RAMDirectory.h | 98 + src/core/CLucene/store/_Lock.h | 134 + src/core/CLucene/store/_MMapIndexInput.h | 40 + src/core/CLucene/store/_RAMDirectory.h | 159 + src/core/CLucene/util/Array.h | 340 + src/core/CLucene/util/BitSet.cpp | 198 + src/core/CLucene/util/BitSet.h | 99 + src/core/CLucene/util/BitUtil.cpp | 24 + src/core/CLucene/util/BitUtil.h | 28 + src/core/CLucene/util/BytesRef.cpp | 73 + src/core/CLucene/util/BytesRef.h | 95 + src/core/CLucene/util/BytesRefBuilder.cpp | 50 + src/core/CLucene/util/BytesRefBuilder.h | 78 + src/core/CLucene/util/CLStreams.h | 379 + src/core/CLucene/util/CodecUtil.cpp | 53 + src/core/CLucene/util/CodecUtil.h | 36 + src/core/CLucene/util/Equators.cpp | 172 + src/core/CLucene/util/Equators.h | 283 + src/core/CLucene/util/FastCharStream.cpp | 109 + src/core/CLucene/util/FixedBitSet.cpp | 37 + src/core/CLucene/util/FixedBitSet.h | 24 + src/core/CLucene/util/FutureArrays.cpp | 246 + src/core/CLucene/util/FutureArrays.h | 134 + src/core/CLucene/util/IntroSorter.cpp | 66 + src/core/CLucene/util/IntroSorter.h | 45 + src/core/CLucene/util/LongBitSet.cpp | 41 + src/core/CLucene/util/LongBitSet.h | 25 + src/core/CLucene/util/MD5Digester.cpp | 337 + src/core/CLucene/util/MSBRadixSorter.cpp | 207 + src/core/CLucene/util/MSBRadixSorter.h | 134 + src/core/CLucene/util/NumericUtils.cpp | 124 + src/core/CLucene/util/NumericUtils.h | 60 + src/core/CLucene/util/OfflineSorter.h | 53 + src/core/CLucene/util/PriorityQueue.h | 206 + src/core/CLucene/util/Reader.cpp | 577 + src/core/CLucene/util/Reader.h | 19 + src/core/CLucene/util/Sorter.cpp | 200 + src/core/CLucene/util/Sorter.h | 89 + src/core/CLucene/util/StringIntern.cpp | 122 + src/core/CLucene/util/ThreadLocal.cpp | 266 + src/core/CLucene/util/Time.h | 20 + src/core/CLucene/util/VoidList.h | 186 + src/core/CLucene/util/VoidMap.h | 327 + src/core/CLucene/util/_Arrays.h | 155 + src/core/CLucene/util/_FastCharStream.h | 54 + src/core/CLucene/util/_MD5Digester.h | 110 + src/core/CLucene/util/_StringIntern.h | 56 + src/core/CLucene/util/_ThreadLocal.h | 89 + src/core/CLucene/util/_VoidList.h | 19 + src/core/CLucene/util/_VoidMap.h | 19 + src/core/CLucene/util/_bufferedstream.h | 185 + src/core/CLucene/util/_streambase.h | 210 + src/core/CLucene/util/_streambuffer.h | 167 + .../CLucene/util/bkd/bkd_docid_iterator.h | 112 + .../CLucene/util/bkd/bkd_msb_radix_sorter.cpp | 119 + .../CLucene/util/bkd/bkd_msb_radix_sorter.h | 37 + src/core/CLucene/util/bkd/bkd_reader.cpp | 588 + src/core/CLucene/util/bkd/bkd_reader.h | 215 + src/core/CLucene/util/bkd/bkd_writer.cpp | 984 + src/core/CLucene/util/bkd/bkd_writer.h | 180 + src/core/CLucene/util/bkd/docIds_writer.cpp | 247 + src/core/CLucene/util/bkd/docIds_writer.h | 41 + .../CLucene/util/bkd/heap_point_reader.cpp | 79 + src/core/CLucene/util/bkd/heap_point_reader.h | 51 + .../CLucene/util/bkd/heap_point_writer.cpp | 259 + src/core/CLucene/util/bkd/heap_point_writer.h | 67 + src/core/CLucene/util/bkd/index_tree.cpp | 91 + src/core/CLucene/util/bkd/index_tree.h | 41 + .../CLucene/util/bkd/legacy_index_tree.cpp | 76 + src/core/CLucene/util/bkd/legacy_index_tree.h | 29 + .../CLucene/util/bkd/packed_index_tree.cpp | 136 + src/core/CLucene/util/bkd/packed_index_tree.h | 38 + src/core/CLucene/util/bkd/point_reader.cpp | 46 + src/core/CLucene/util/bkd/point_reader.h | 25 + src/core/CLucene/util/bkd/point_writer.h | 27 + src/core/CLucene/util/croaring/LICENSE | 235 + src/core/CLucene/util/croaring/README.md | 44 + src/core/CLucene/util/croaring/roaring.c | 19542 ++ src/core/CLucene/util/croaring/roaring.h | 1031 + src/core/CLucene/util/croaring/roaring.hh | 2016 + src/core/CLucene/util/stringUtil.cpp | 51 + src/core/CLucene/util/stringUtil.h | 27 + src/core/CMakeLists.txt | 348 + src/core/files_list.txt | 314 + src/core/libclucene-core.pc.cmake | 11 + src/core/vp4.h | 355 + src/demo/CMakeLists.txt | 44 + src/demo/DeleteFiles.cpp | 42 + src/demo/IndexFiles.cpp | 207 + src/demo/Main.cpp | 87 + src/demo/Main_Index.cpp | 79 + src/demo/README | 2 + src/demo/SearchFiles.cpp | 100 + src/demo/Statistics.cpp | 47 + src/demo/TestAnalyzer.cpp | 83 + src/ext/CMakeLists.txt | 15 + src/ext/boost/assert.hpp | 50 + src/ext/boost/checked_delete.hpp | 69 + src/ext/boost/config.hpp | 70 + src/ext/boost/config/abi/borland_prefix.hpp | 27 + src/ext/boost/config/abi/borland_suffix.hpp | 12 + src/ext/boost/config/abi/msvc_prefix.hpp | 22 + src/ext/boost/config/abi/msvc_suffix.hpp | 8 + src/ext/boost/config/abi_prefix.hpp | 25 + src/ext/boost/config/abi_suffix.hpp | 27 + src/ext/boost/config/auto_link.hpp | 373 + src/ext/boost/config/compiler/borland.hpp | 267 + src/ext/boost/config/compiler/codegear.hpp | 163 + src/ext/boost/config/compiler/comeau.hpp | 59 + src/ext/boost/config/compiler/common_edg.hpp | 97 + src/ext/boost/config/compiler/compaq_cxx.hpp | 19 + src/ext/boost/config/compiler/digitalmars.hpp | 93 + src/ext/boost/config/compiler/gcc.hpp | 204 + src/ext/boost/config/compiler/gcc_xml.hpp | 30 + src/ext/boost/config/compiler/greenhills.hpp | 28 + src/ext/boost/config/compiler/hp_acc.hpp | 127 + src/ext/boost/config/compiler/intel.hpp | 173 + src/ext/boost/config/compiler/kai.hpp | 33 + src/ext/boost/config/compiler/metrowerks.hpp | 139 + src/ext/boost/config/compiler/mpw.hpp | 81 + src/ext/boost/config/compiler/pgi.hpp | 62 + src/ext/boost/config/compiler/sgi_mipspro.hpp | 29 + src/ext/boost/config/compiler/sunpro_cc.hpp | 130 + src/ext/boost/config/compiler/vacpp.hpp | 88 + src/ext/boost/config/compiler/visualc.hpp | 258 + src/ext/boost/config/no_tr1/cmath.hpp | 28 + src/ext/boost/config/no_tr1/complex.hpp | 28 + src/ext/boost/config/no_tr1/functional.hpp | 28 + src/ext/boost/config/no_tr1/memory.hpp | 28 + src/ext/boost/config/no_tr1/utility.hpp | 28 + src/ext/boost/config/platform/aix.hpp | 33 + src/ext/boost/config/platform/amigaos.hpp | 15 + src/ext/boost/config/platform/beos.hpp | 26 + src/ext/boost/config/platform/bsd.hpp | 86 + src/ext/boost/config/platform/cygwin.hpp | 51 + src/ext/boost/config/platform/hpux.hpp | 87 + src/ext/boost/config/platform/irix.hpp | 31 + src/ext/boost/config/platform/linux.hpp | 98 + src/ext/boost/config/platform/macos.hpp | 86 + src/ext/boost/config/platform/qnxnto.hpp | 31 + src/ext/boost/config/platform/solaris.hpp | 28 + src/ext/boost/config/platform/vxworks.hpp | 31 + src/ext/boost/config/platform/win32.hpp | 58 + src/ext/boost/config/posix_features.hpp | 95 + src/ext/boost/config/requires_threads.hpp | 92 + .../boost/config/select_compiler_config.hpp | 119 + .../boost/config/select_platform_config.hpp | 94 + src/ext/boost/config/select_stdlib_config.hpp | 77 + src/ext/boost/config/stdlib/dinkumware.hpp | 138 + src/ext/boost/config/stdlib/libcomo.hpp | 71 + src/ext/boost/config/stdlib/libstdcpp3.hpp | 127 + src/ext/boost/config/stdlib/modena.hpp | 55 + src/ext/boost/config/stdlib/msl.hpp | 83 + src/ext/boost/config/stdlib/roguewave.hpp | 179 + src/ext/boost/config/stdlib/sgi.hpp | 136 + src/ext/boost/config/stdlib/stlport.hpp | 236 + src/ext/boost/config/stdlib/vacpp.hpp | 43 + src/ext/boost/config/suffix.hpp | 601 + src/ext/boost/config/user.hpp | 124 + src/ext/boost/config/warning_disable.hpp | 47 + src/ext/boost/current_function.hpp | 67 + src/ext/boost/detail/algorithm.hpp | 222 + src/ext/boost/detail/allocator_utilities.hpp | 212 + src/ext/boost/detail/atomic_count.hpp | 21 + src/ext/boost/detail/binary_search.hpp | 216 + src/ext/boost/detail/call_traits.hpp | 164 + src/ext/boost/detail/catch_exceptions.hpp | 146 + src/ext/boost/detail/compressed_pair.hpp | 443 + src/ext/boost/detail/container_fwd.hpp | 99 + src/ext/boost/detail/dynamic_bitset.hpp | 229 + src/ext/boost/detail/endian.hpp | 73 + .../boost/detail/has_default_constructor.hpp | 29 + src/ext/boost/detail/identifier.hpp | 89 + src/ext/boost/detail/indirect_traits.hpp | 487 + src/ext/boost/detail/interlocked.hpp | 142 + .../boost/detail/is_function_ref_tester.hpp | 135 + src/ext/boost/detail/is_incrementable.hpp | 134 + src/ext/boost/detail/is_xxx.hpp | 61 + src/ext/boost/detail/iterator.hpp | 494 + src/ext/boost/detail/lcast_precision.hpp | 184 + src/ext/boost/detail/lightweight_mutex.hpp | 22 + src/ext/boost/detail/lightweight_test.hpp | 91 + src/ext/boost/detail/lightweight_thread.hpp | 135 + src/ext/boost/detail/limits.hpp | 449 + .../boost/detail/named_template_params.hpp | 177 + .../boost/detail/no_exceptions_support.hpp | 87 + src/ext/boost/detail/none_t.hpp | 28 + src/ext/boost/detail/numeric_traits.hpp | 191 + src/ext/boost/detail/ob_call_traits.hpp | 168 + src/ext/boost/detail/ob_compressed_pair.hpp | 510 + src/ext/boost/detail/quick_allocator.hpp | 23 + src/ext/boost/detail/reference_content.hpp | 141 + .../boost/detail/scoped_enum_emulation.hpp | 56 + src/ext/boost/detail/select_type.hpp | 36 + src/ext/boost/detail/sp_typeinfo.hpp | 129 + src/ext/boost/detail/templated_streams.hpp | 74 + src/ext/boost/detail/utf8_codecvt_facet.hpp | 190 + src/ext/boost/detail/workaround.hpp | 262 + src/ext/boost/exception/all.hpp | 36 + .../exception/current_exception_cast.hpp | 43 + .../exception/detail/attribute_noreturn.hpp | 17 + .../exception/detail/error_info_impl.hpp | 75 + .../boost/exception/detail/exception_ptr.hpp | 490 + .../exception/detail/is_output_streamable.hpp | 47 + .../exception/detail/object_hex_dump.hpp | 50 + src/ext/boost/exception/detail/type_info.hpp | 79 + .../exception/diagnostic_information.hpp | 182 + .../exception/enable_current_exception.hpp | 6 + src/ext/boost/exception/enable_error_info.hpp | 6 + .../boost/exception/errinfo_api_function.hpp | 22 + src/ext/boost/exception/errinfo_at_line.hpp | 18 + src/ext/boost/exception/errinfo_errno.hpp | 44 + .../boost/exception/errinfo_file_handle.hpp | 20 + src/ext/boost/exception/errinfo_file_name.hpp | 26 + .../exception/errinfo_file_open_mode.hpp | 26 + .../exception/errinfo_nested_exception.hpp | 17 + .../exception/errinfo_type_info_name.hpp | 23 + src/ext/boost/exception/error_info.hpp | 6 + src/ext/boost/exception/exception.hpp | 422 + src/ext/boost/exception/get_error_info.hpp | 130 + src/ext/boost/exception/info.hpp | 167 + src/ext/boost/exception/info_tuple.hpp | 76 + src/ext/boost/exception/to_string.hpp | 83 + src/ext/boost/exception/to_string_stub.hpp | 109 + src/ext/boost/memory_order.hpp | 53 + src/ext/boost/shared_ptr.hpp | 19 + src/ext/boost/smart_ptr/bad_weak_ptr.hpp | 59 + .../boost/smart_ptr/detail/atomic_count.hpp | 119 + .../smart_ptr/detail/atomic_count_gcc.hpp | 72 + .../smart_ptr/detail/atomic_count_gcc_x86.hpp | 77 + .../detail/atomic_count_pthreads.hpp | 96 + .../smart_ptr/detail/atomic_count_solaris.hpp | 59 + .../smart_ptr/detail/atomic_count_sync.hpp | 61 + .../smart_ptr/detail/atomic_count_win32.hpp | 63 + .../smart_ptr/detail/lightweight_mutex.hpp | 42 + src/ext/boost/smart_ptr/detail/lwm_nop.hpp | 37 + .../boost/smart_ptr/detail/lwm_pthreads.hpp | 87 + .../boost/smart_ptr/detail/lwm_win32_cs.hpp | 108 + .../boost/smart_ptr/detail/operator_bool.hpp | 56 + .../smart_ptr/detail/quick_allocator.hpp | 199 + .../smart_ptr/detail/shared_array_nmt.hpp | 151 + .../boost/smart_ptr/detail/shared_count.hpp | 444 + .../boost/smart_ptr/detail/shared_ptr_nmt.hpp | 182 + .../boost/smart_ptr/detail/sp_convertible.hpp | 76 + .../smart_ptr/detail/sp_counted_base.hpp | 70 + .../detail/sp_counted_base_acc_ia64.hpp | 150 + .../detail/sp_counted_base_cw_ppc.hpp | 170 + .../detail/sp_counted_base_cw_x86.hpp | 158 + .../detail/sp_counted_base_gcc_ia64.hpp | 157 + .../detail/sp_counted_base_gcc_mips.hpp | 172 + .../detail/sp_counted_base_gcc_ppc.hpp | 181 + .../detail/sp_counted_base_gcc_sparc.hpp | 166 + .../detail/sp_counted_base_gcc_x86.hpp | 173 + .../smart_ptr/detail/sp_counted_base_nt.hpp | 107 + .../smart_ptr/detail/sp_counted_base_pt.hpp | 135 + .../detail/sp_counted_base_solaris.hpp | 113 + .../smart_ptr/detail/sp_counted_base_spin.hpp | 131 + .../smart_ptr/detail/sp_counted_base_sync.hpp | 155 + .../smart_ptr/detail/sp_counted_base_w32.hpp | 130 + .../smart_ptr/detail/sp_counted_impl.hpp | 231 + .../boost/smart_ptr/detail/sp_has_sync.hpp | 49 + src/ext/boost/smart_ptr/detail/spinlock.hpp | 53 + .../smart_ptr/detail/spinlock_gcc_arm.hpp | 85 + .../boost/smart_ptr/detail/spinlock_nt.hpp | 89 + .../boost/smart_ptr/detail/spinlock_pool.hpp | 87 + .../boost/smart_ptr/detail/spinlock_pt.hpp | 79 + .../boost/smart_ptr/detail/spinlock_sync.hpp | 87 + .../boost/smart_ptr/detail/spinlock_w32.hpp | 113 + src/ext/boost/smart_ptr/detail/yield_k.hpp | 149 + .../smart_ptr/enable_shared_from_this.hpp | 79 + .../smart_ptr/enable_shared_from_this2.hpp | 132 + src/ext/boost/smart_ptr/intrusive_ptr.hpp | 299 + src/ext/boost/smart_ptr/make_shared.hpp | 506 + src/ext/boost/smart_ptr/scoped_array.hpp | 107 + src/ext/boost/smart_ptr/scoped_ptr.hpp | 131 + src/ext/boost/smart_ptr/shared_array.hpp | 147 + src/ext/boost/smart_ptr/shared_ptr.hpp | 701 + src/ext/boost/smart_ptr/weak_ptr.hpp | 230 + src/ext/boost/throw_exception.hpp | 75 + src/ext/boost/version.hpp | 35 + src/ext/for/README.md | 585 + src/ext/for/bitpack.c | 426 + src/ext/for/bitpack.h | 310 + src/ext/for/bitpack_.h | 5190 + src/ext/for/bitunpack.c | 1231 + src/ext/for/bitunpack_.h | 6049 + src/ext/for/bitutil.c | 689 + src/ext/for/bitutil.h | 547 + src/ext/for/conf.h | 282 + src/ext/for/eliasfano.c | 208 + src/ext/for/eliasfano.h | 61 + src/ext/for/fp.c | 684 + src/ext/for/fp.h | 125 + src/ext/for/icapp.c | 1909 + src/ext/for/icbench.c | 1736 + src/ext/for/idx.h | 53 + src/ext/for/idxcr.c | 175 + src/ext/for/idxqry.c | 684 + src/ext/for/idxseg.c | 133 + src/ext/for/index.md | 567 + src/ext/for/jic.c | 172 + src/ext/for/lz.c | 442 + src/ext/for/makefile | 156 + src/ext/for/makefile.vs | 78 + src/ext/for/plugins.cc | 798 + src/ext/for/plugins.h | 74 + src/ext/for/sse_neon.h | 355 + src/ext/for/time_.h | 252 + src/ext/for/transpose.c | 1223 + src/ext/for/transpose.h | 113 + src/ext/for/trle.h | 72 + src/ext/for/trle_.h | 60 + src/ext/for/trlec.c | 343 + src/ext/for/trled.c | 413 + src/ext/for/v8.c | 1465 + src/ext/for/vint.c | 407 + src/ext/for/vint.h | 401 + src/ext/for/vp4.h | 355 + src/ext/for/vp4c.c | 423 + src/ext/for/vp4d.c | 534 + src/ext/for/vs/bitpack_avx2.c | 2 + src/ext/for/vs/bitpack_sse.c | 2 + src/ext/for/vs/bitunpack_avx2.c | 2 + src/ext/for/vs/bitunpack_sse.c | 2 + src/ext/for/vs/getopt.c | 562 + src/ext/for/vs/getopt.h | 97 + src/ext/for/vs/inttypes.h | 306 + src/ext/for/vs/stdint.h | 259 + src/ext/for/vs/transpose_avx2.c | 2 + src/ext/for/vs/transpose_sse.c | 2 + src/ext/for/vs/vp4c_avx2.c | 2 + src/ext/for/vs/vp4c_sse.c | 2 + src/ext/for/vs/vp4d_avx2.c | 2 + src/ext/for/vs/vp4d_sse.c | 2 + src/ext/for/vs/vs2017/TurboPFor.sln | 41 + src/ext/for/vs/vs2017/TurboPFor.vcxproj | 226 + .../for/vs/vs2017/TurboPFor.vcxproj.filters | 101 + src/ext/for/vs/vs2017/icapp.vcxproj | 175 + src/ext/for/vs/vs2017/icapp.vcxproj.filters | 21 + src/ext/for/vsimple.c | 536 + src/ext/for/vsimple.h | 47 + src/ext/zlib/ChangeLog | 855 + src/ext/zlib/FAQ | 339 + src/ext/zlib/INDEX | 51 + src/ext/zlib/README | 125 + src/ext/zlib/adler32.c | 149 + src/ext/zlib/algorithm.txt | 209 + src/ext/zlib/compress.c | 79 + src/ext/zlib/crc32.c | 423 + src/ext/zlib/crc32.h | 441 + src/ext/zlib/deflate.c | 1736 + src/ext/zlib/deflate.h | 331 + src/ext/zlib/gzio.c | 1026 + src/ext/zlib/inffast.c | 318 + src/ext/zlib/inffast.h | 11 + src/ext/zlib/inffixed.h | 94 + src/ext/zlib/inflate.c | 1368 + src/ext/zlib/inflate.h | 115 + src/ext/zlib/inftrees.c | 329 + src/ext/zlib/inftrees.h | 55 + src/ext/zlib/trees.c | 1219 + src/ext/zlib/trees.h | 128 + src/ext/zlib/zconf.h | 332 + src/ext/zlib/zlib.h | 1357 + src/ext/zlib/zutil.c | 318 + src/ext/zlib/zutil.h | 269 + src/gtest/CMakeLists.txt | 26 + src/gtest/parser/main.cpp | 14 + src/htdocs/README | 9 + src/htdocs/_footer.html | 55 + src/htdocs/_header.html | 37 + src/htdocs/_index.php | 9 + src/htdocs/clucene.jpg | Bin 0 -> 7432 bytes src/htdocs/contribute.shtml | 36 + src/htdocs/download.shtml | 168 + src/htdocs/images/disk.png | Bin 0 -> 620 bytes src/htdocs/images/img01.gif | Bin 0 -> 1945 bytes src/htdocs/images/img02.gif | Bin 0 -> 11174 bytes src/htdocs/images/img03.gif | Bin 0 -> 47 bytes src/htdocs/images/img04.jpg | Bin 0 -> 5009 bytes src/htdocs/images/img05.jpg | Bin 0 -> 564 bytes src/htdocs/images/img06.jpg | Bin 0 -> 2438 bytes src/htdocs/images/img07.gif | Bin 0 -> 469 bytes src/htdocs/images/img08.jpg | Bin 0 -> 10067 bytes src/htdocs/images/img09.jpg | Bin 0 -> 1571 bytes src/htdocs/images/img10.jpg | Bin 0 -> 1071 bytes src/htdocs/images/img11.gif | Bin 0 -> 272 bytes src/htdocs/images/spacer.gif | Bin 0 -> 43 bytes src/htdocs/index.shtml | 19 + src/htdocs/style.css | 344 + src/shared/CLucene/CLSharedMonolithic.cpp | 26 + src/shared/CLucene/LuceneThreads.h | 176 + src/shared/CLucene/SharedHeader.cpp | 32 + src/shared/CLucene/SharedHeader.h | 213 + src/shared/CLucene/_SharedHeader.h | 71 + src/shared/CLucene/_clucene-config.h.cmake | 112 + src/shared/CLucene/clucene-config.h.cmake | 148 + src/shared/CLucene/config/_gunichartables.h | 11264 + src/shared/CLucene/config/_threads.h | 125 + src/shared/CLucene/config/gunichartables.cpp | 377 + src/shared/CLucene/config/repl_lltot.cpp | 47 + src/shared/CLucene/config/repl_tchar.h | 181 + src/shared/CLucene/config/repl_tcscasecmp.cpp | 21 + src/shared/CLucene/config/repl_tcslwr.cpp | 15 + src/shared/CLucene/config/repl_tcstod.cpp | 24 + src/shared/CLucene/config/repl_tcstoll.cpp | 53 + src/shared/CLucene/config/repl_tprintf.cpp | 149 + src/shared/CLucene/config/repl_wchar.h | 89 + src/shared/CLucene/config/repl_wctype.h | 76 + src/shared/CLucene/config/threads.cpp | 292 + src/shared/CLucene/config/utf8.cpp | 249 + src/shared/CLucene/debug/_condition.h | 69 + src/shared/CLucene/debug/condition.cpp | 78 + src/shared/CLucene/util/Misc.cpp | 739 + src/shared/CLucene/util/Misc.h | 116 + src/shared/CLucene/util/StringBuffer.cpp | 430 + src/shared/CLucene/util/StringBuffer.h | 99 + src/shared/CLucene/util/deflate.cpp | 1714 + src/shared/CLucene/util/dirent.cpp | 224 + src/shared/CLucene/util/dirent.h | 109 + src/shared/CMakeLists.txt | 375 + src/shared/README | 5 + src/shared/cmake/CheckAtomicFunctions.cmake | 25 + src/shared/cmake/CheckErrorHandling.cmake | 12 + src/shared/cmake/CheckFloatByte.cmake | 37 + src/shared/cmake/CheckFloatByte.cpp.in | 81 + src/shared/cmake/CheckHashmaps.cmake | 72 + src/shared/cmake/CheckNamespace.cmake | 8 + src/shared/cmake/CheckPthread.cmake | 27 + src/shared/cmake/CheckSnprintf.cmake | 42 + .../cmake/CheckStdCallFunctionExists.cmake | 89 + .../cmake/CheckStdCallFunctionExists.cpp.in | 12 + src/shared/cmake/DefineDword.cmake | 17 + src/shared/cmake/DefineFloat.cmake | 29 + src/shared/cmake/DefineLongLongSyntax.cmake | 14 + src/shared/cmake/DefineMAXPATHValue.cmake | 30 + src/shared/cmake/DefineStaticSyntax.cmake | 13 + .../cmake/MacroCheckGccVisibility.cmake | 58 + src/shared/cmake/MacroChooseFunction.cmake | 49 + src/shared/cmake/MacroChooseMisc.cmake | 82 + src/shared/cmake/MacroChooseSymbol.cmake | 62 + src/shared/cmake/MacroChooseType.cmake | 49 + src/shared/cmake/MacroEnsureVersion.cmake | 71 + src/shared/cmake/MacroGetVariableValue.c.in | 20 + src/shared/cmake/MacroGetVariableValue.cmake | 33 + src/shared/cmake/MacroMustDefine.cmake | 69 + src/shared/cmake/Macro_ChooseStatus.cmake | 20 + src/test/CLMonolithic_Test.cpp | 67 + src/test/CMakeLists.txt | 276 + src/test/CuTest.cpp | 639 + src/test/CuTest.h | 139 + src/test/README | 239 + src/test/analysis/TestAnalysis.cpp | 110 + src/test/analysis/TestAnalyzers.cpp | 524 + .../analysis/de/TestGermanStemFilter.cpp | 65 + src/test/data/StopWords.test | 12 + .../data/contribs-lib/analysis/de/data.txt | 51 + src/test/data/french_unicode.bin | Bin 0 -> 5604 bytes src/test/data/readme.txt | 41 + src/test/data/reuters-21578-index/_z.f0 | 1 + src/test/data/reuters-21578-index/_z.f1 | 1 + src/test/data/reuters-21578-index/_z.fdt | Bin 0 -> 616 bytes src/test/data/reuters-21578-index/_z.fdx | Bin 0 -> 248 bytes src/test/data/reuters-21578-index/_z.fnm | 1 + src/test/data/reuters-21578-index/_z.frq | 1047 + src/test/data/reuters-21578-index/_z.prx | Bin 0 -> 388750 bytes src/test/data/reuters-21578-index/_z.tii | Bin 0 -> 3462 bytes src/test/data/reuters-21578-index/_z.tis | Bin 0 -> 248046 bytes src/test/data/reuters-21578-index/deletable | Bin 0 -> 4 bytes src/test/data/reuters-21578-index/segments | Bin 0 -> 27 bytes src/test/data/reuters-21578/LEWIS.DTD | 60 + src/test/data/reuters-21578/README.TXT | 816 + .../all-exchanges-strings.lc.txt | 39 + .../reuters-21578/all-orgs-strings.lc.txt | 56 + .../reuters-21578/all-people-strings.lc.txt | 267 + .../reuters-21578/all-places-strings.lc.txt | 175 + .../reuters-21578/all-topics-strings.lc.txt | 135 + .../reuters-21578/cat-descriptions_120396.txt | 1203 + .../feldman-cia-worldfactbook-data.txt | 5199 + src/test/data/reuters-21578/reut2-000.sgm | 2032 + src/test/data/reuters-21578/reut2-001.sgm | 2010 + src/test/data/reuters-21578/reut2-002.sgm | 2013 + src/test/data/reuters-21578/reut2-003.sgm | 2006 + src/test/data/reuters-21578/reut2-004.sgm | 2023 + src/test/data/reuters-21578/reut2-005.sgm | 2012 + src/test/data/reuters-21578/reut2-006.sgm | 2012 + src/test/data/reuters-21578/reut2-007.sgm | 2010 + src/test/data/reuters-21578/reut2-008.sgm | 2019 + src/test/data/reuters-21578/reut2-009.sgm | 2003 + src/test/data/reuters-21578/reut2-010.sgm | 2002 + src/test/data/reuters-21578/reut2-011.sgm | 2010 + src/test/data/reuters-21578/reut2-012.sgm | 2010 + src/test/data/reuters-21578/reut2-013.sgm | 2011 + src/test/data/reuters-21578/reut2-014.sgm | 2029 + src/test/data/reuters-21578/reut2-015.sgm | 2003 + src/test/data/reuters-21578/reut2-016.sgm | 2030 + src/test/data/reuters-21578/reut2-017.sgm | 2014 + src/test/data/reuters-21578/reut2-018.sgm | 2004 + src/test/data/reuters-21578/reut2-019.sgm | 2013 + src/test/data/reuters-21578/reut2-020.sgm | 2041 + src/test/data/reuters-21578/reut2-021.sgm | 2002 + src/test/data/utf8text/arabic_utf8.txt | 15 + src/test/data/utf8text/chinese_utf8.txt | 32 + src/test/data/utf8text/czech_utf8.txt | 78 + src/test/data/utf8text/english_utf8.txt | 70 + src/test/data/utf8text/french_utf8.txt | 30 + src/test/data/utf8text/german_utf8.txt | 20 + src/test/data/utf8text/greek_utf8.txt | 14 + src/test/data/utf8text/hebrew_utf8.txt | 408 + src/test/data/utf8text/japanese_utf8.txt | 28 + src/test/data/utf8text/korean_utf8.txt | 51 + src/test/data/utf8text/polish_utf8.txt | 65 + src/test/data/utf8text/russian_utf8.txt | 11 + src/test/debug/TestError.cpp | 100 + src/test/document/TestDateTools.cpp | 122 + src/test/document/TestDocument.cpp | 480 + src/test/document/TestField.cpp | 35 + src/test/document/TestNumberTools.cpp | 80 + src/test/index/IndexWriter4Test.cpp | 44 + src/test/index/IndexWriter4Test.h | 35 + src/test/index/TestAddIndexesNoOptimize.cpp | 592 + src/test/index/TestHighFreqTerms.cpp | 86 + src/test/index/TestIndexModifier.cpp | 215 + src/test/index/TestIndexReader.cpp | 309 + src/test/index/TestIndexWriter.cpp | 668 + src/test/index/TestReuters.cpp | 234 + src/test/index/TestTermVectorsReader.cpp | 466 + src/test/index/TestThreading.cpp | 161 + src/test/index/TestUtf8.cpp | 189 + src/test/nanobench.h | 3367 + .../queryParser/TestMultiFieldQueryParser.cpp | 171 + src/test/queryParser/TestQueryParser.cpp | 885 + src/test/search/BaseTestRangeFilter.cpp | 115 + src/test/search/BaseTestRangeFilter.h | 47 + src/test/search/CheckHits.cpp | 542 + src/test/search/CheckHits.h | 120 + src/test/search/MockHitCollector.h | 40 + src/test/search/MockScorer.h | 93 + src/test/search/QueryUtils.cpp | 376 + src/test/search/QueryUtils.h | 54 + src/test/search/TestBoolean.cpp | 197 + .../search/TestConstantScoreRangeQuery.cpp | 533 + src/test/search/TestDateFilter.cpp | 201 + src/test/search/TestExplanations.cpp | 237 + src/test/search/TestExplanations.h | 151 + src/test/search/TestExtractTerms.cpp | 309 + src/test/search/TestForDuplicates.cpp | 164 + src/test/search/TestIndexSearcher.cpp | 99 + src/test/search/TestQueries.cpp | 384 + src/test/search/TestRangeFilter.cpp | 342 + src/test/search/TestSearch.cpp | 483 + src/test/search/TestSort.cpp | 552 + src/test/search/TestTermVector.cpp | 272 + src/test/search/TestWildcard.cpp | 132 + src/test/search/spans/TestBasics.cpp | 588 + src/test/search/spans/TestBasics.h | 64 + .../search/spans/TestNearSpansOrdered.cpp | 221 + src/test/search/spans/TestNearSpansOrdered.h | 50 + .../search/spans/TestSpanExplanations.cpp | 269 + src/test/search/spans/TestSpanExplanations.h | 57 + .../TestSpanExplanationsOfNonMatches.cpp | 22 + .../spans/TestSpanExplanationsOfNonMatches.h | 28 + src/test/search/spans/TestSpanQueries.cpp | 186 + src/test/search/spans/TestSpans.cpp | 300 + src/test/search/spans/TestSpans.h | 60 + src/test/search/spans/TestSpansAdvanced.cpp | 136 + src/test/search/spans/TestSpansAdvanced.h | 59 + src/test/search/spans/TestSpansAdvanced2.cpp | 85 + src/test/search/spans/TestSpansAdvanced2.h | 33 + src/test/store/MockRAMDirectory.cpp | 326 + src/test/store/MockRAMDirectory.h | 176 + src/test/store/TestRAMDirectory.cpp | 218 + src/test/store/TestStore.cpp | 123 + src/test/test.h | 159 + src/test/testall.cpp | 345 + src/test/tests.cpp | 51 + src/test/util/English.cpp | 134 + src/test/util/TestBKD.cpp | 960 + src/test/util/TestBKD.h | 110 + src/test/util/TestBitSet.cpp | 266 + src/test/util/TestMSBRadixSorter.cpp | 123 + src/test/util/TestMSBRadixSorter.h | 71 + src/test/util/TestPriorityQueue.cpp | 77 + src/test/util/TestStringBuffer.cpp | 116 + src/tokenizer/CMakeLists.txt | 23 + src/tokenizer/etc/unigram.txt | 218464 +++++++++++++++ src/tokenizer/etc/unigram.txt.uni | Bin 0 -> 3729280 bytes src/tokenizer/etc/wwsearch_mmseg.ini | 5 + src/tokenizer/etc/wwsearch_mmseg_uni.lib | Bin 0 -> 3730552 bytes src/tokenizer/include/ICorpusReader.h | 44 + src/tokenizer/include/SegmentPkg.h | 121 + src/tokenizer/include/Segmenter.h | 166 + src/tokenizer/include/SegmenterManager.h | 72 + src/tokenizer/include/Singleton.h | 100 + src/tokenizer/include/StringTokenizer.h | 44 + src/tokenizer/include/SynonymsDict.h | 100 + src/tokenizer/include/ThesaurusDict.h | 43 + src/tokenizer/include/UnigramCorpusReader.h | 55 + src/tokenizer/include/UnigramDict.h | 72 + src/tokenizer/include/UnigramRecord.h | 41 + src/tokenizer/include/Utf8_16.h | 145 + src/tokenizer/include/bsd_getopt.h | 38 + src/tokenizer/include/config.h | 92 + src/tokenizer/include/csr.h | 33 + src/tokenizer/include/csr_assert.h | 44 + src/tokenizer/include/csr_mmap.h | 21 + src/tokenizer/include/csr_pool.h | 112 + src/tokenizer/include/csr_typedefs.h | 77 + src/tokenizer/include/csr_utils.h | 49 + src/tokenizer/include/darts.h | 595 + src/tokenizer/include/dictionary.h | 174 + src/tokenizer/include/freelist.h | 72 + src/tokenizer/include/iniparser.h | 281 + src/tokenizer/include/mmseg_wrapper.h | 91 + src/tokenizer/include/mmthunk.h | 236 + src/tokenizer/include/os.h | 27 + src/tokenizer/include/scoped_ptr.h | 75 + src/tokenizer/include/tolowercase.h | 892 + src/tokenizer/src/SegmentPkg.cpp | 396 + src/tokenizer/src/SegmenterManager.cpp | 180 + src/tokenizer/src/StringTokenizer.cpp | 121 + src/tokenizer/src/SynonymsDict.cpp | 328 + src/tokenizer/src/ThesaurusDict.cpp | 180 + src/tokenizer/src/UnigramCorpusReader.cpp | 148 + src/tokenizer/src/UnigramDict.cpp | 126 + src/tokenizer/src/UnigramRecord.cpp | 30 + src/tokenizer/src/Utf8_16.cpp | 438 + src/tokenizer/src/assert.cpp | 58 + src/tokenizer/src/bsd_getopt.cpp | 49 + src/tokenizer/src/csr_mmap.cpp | 189 + src/tokenizer/src/csr_utils.cpp | 126 + src/tokenizer/src/dictionary.cpp | 412 + src/tokenizer/src/iniparser.cpp | 657 + src/tokenizer/src/mmseg_wrapper.cpp | 46 + src/tokenizer/src/mmthunk.cpp | 233 + src/tokenizer/src/segmenter.cpp | 320 + 1081 files changed, 546185 insertions(+) create mode 100644 APACHE.license create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 LGPL.license create mode 100644 NEWS create mode 100644 README create mode 100644 README.PACKAGE create mode 100644 REQUESTS create mode 100644 cmake/CLuceneBoost.cmake create mode 100644 cmake/CLuceneDocs.cmake create mode 100644 cmake/CreateClucenePackages.cmake create mode 100644 cmake/DefineOptions.cmake create mode 100644 cmake/Toolchain-g++32.cmake create mode 100644 cmake/Toolchain-llvm.cmake create mode 100644 cmake/Toolchain-mingw32.cmake create mode 100644 cmake/TurboPFOR.cmake create mode 100644 cmake/cmake_uninstall.cmake.in create mode 100755 dist-test.sh create mode 100644 doc/Doxyfile.cmake create mode 100644 doc/coding standards.txt create mode 100644 doc/doxygen.css.cmake create mode 100644 doc/helpfooter.htm.cmake create mode 100644 doc/helpheader.htm.cmake create mode 100644 src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.cpp create mode 100644 src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.h create mode 100644 src/contribs-lib/CLucene/analysis/PorterStemmer.cpp create mode 100644 src/contribs-lib/CLucene/analysis/PorterStemmer.h create mode 100644 src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp create mode 100644 src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.h create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.cpp create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.h create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanStemFilter.cpp create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanStemFilter.h create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanStemmer.cpp create mode 100644 src/contribs-lib/CLucene/analysis/de/GermanStemmer.h create mode 100644 src/contribs-lib/CLucene/highlighter/Encoder.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/Encoder.h create mode 100644 src/contribs-lib/CLucene/highlighter/Formatter.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/Formatter.h create mode 100644 src/contribs-lib/CLucene/highlighter/Fragmenter.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/Fragmenter.h create mode 100644 src/contribs-lib/CLucene/highlighter/HighlightScorer.h create mode 100644 src/contribs-lib/CLucene/highlighter/Highlighter.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/Highlighter.h create mode 100644 src/contribs-lib/CLucene/highlighter/QueryScorer.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/QueryScorer.h create mode 100644 src/contribs-lib/CLucene/highlighter/QueryTermExtractor.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/QueryTermExtractor.h create mode 100644 src/contribs-lib/CLucene/highlighter/Scorer.h create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleFragmenter.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleFragmenter.h create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.h create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.h create mode 100644 src/contribs-lib/CLucene/highlighter/TextFragment.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/TextFragment.h create mode 100644 src/contribs-lib/CLucene/highlighter/TokenGroup.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/TokenGroup.h create mode 100644 src/contribs-lib/CLucene/highlighter/TokenSources.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/TokenSources.h create mode 100644 src/contribs-lib/CLucene/highlighter/WeightedTerm.cpp create mode 100644 src/contribs-lib/CLucene/highlighter/WeightedTerm.h create mode 100644 src/contribs-lib/CLucene/snowball/SNOWBALL_README create mode 100644 src/contribs-lib/CLucene/snowball/Snowball.cpp create mode 100644 src/contribs-lib/CLucene/snowball/SnowballAnalyzer.h create mode 100644 src/contribs-lib/CLucene/snowball/SnowballFilter.h create mode 100644 src/contribs-lib/CLucene/snowball/include/libstemmer.h create mode 100644 src/contribs-lib/CLucene/snowball/libstemmer.h create mode 100644 src/contribs-lib/CLucene/snowball/libstemmer/libstemmer.c create mode 100644 src/contribs-lib/CLucene/snowball/libstemmer/modules.h create mode 100644 src/contribs-lib/CLucene/snowball/runtime/api.c create mode 100644 src/contribs-lib/CLucene/snowball/runtime/api.h create mode 100644 src/contribs-lib/CLucene/snowball/runtime/header.h create mode 100644 src/contribs-lib/CLucene/snowball/runtime/utilities.c create mode 100644 src/contribs-lib/CLucene/snowball/snowball.version create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.h create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.c create mode 100644 src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.h create mode 100644 src/contribs-lib/CLucene/util/arrayinputstream.h create mode 100644 src/contribs-lib/CLucene/util/byteinputstream.h create mode 100644 src/contribs-lib/CLucene/util/gzipcompressstream.cpp create mode 100644 src/contribs-lib/CLucene/util/gzipcompressstream.h create mode 100644 src/contribs-lib/CLucene/util/gzipinputstream.cpp create mode 100644 src/contribs-lib/CLucene/util/gzipinputstream.h create mode 100644 src/contribs-lib/CLucene/util/streamarray.h create mode 100644 src/contribs-lib/CMakeLists.txt create mode 100644 src/contribs-lib/cmake/FindIconv.cmake create mode 100644 src/contribs/CMakeLists.txt create mode 100644 src/contribs/bashscripts/findPatchThatBrokeUnitTest.sh create mode 100644 src/contribs/bashscripts/simpleupdate.sh create mode 100644 src/contribs/bashscripts/twofileupdate.sh create mode 100644 src/contribs/benchmarker/Benchmarker.cpp create mode 100644 src/contribs/benchmarker/Benchmarker.h create mode 100644 src/contribs/benchmarker/CMakeLists.txt create mode 100644 src/contribs/benchmarker/Main.cpp create mode 100644 src/contribs/benchmarker/TestCLString.cpp create mode 100644 src/contribs/benchmarker/TestCLString.h create mode 100644 src/contribs/benchmarker/Timer.h create mode 100644 src/contribs/benchmarker/Unit.cpp create mode 100644 src/contribs/benchmarker/Unit.h create mode 100644 src/contribs/benchmarker/stdafx.cpp create mode 100644 src/contribs/benchmarker/stdafx.h create mode 100644 src/contribs/contribs-lib-test/CMakeLists.txt create mode 100644 src/contribs/contribs-lib-test/CuTest.cpp create mode 100644 src/contribs/contribs-lib-test/CuTest.h create mode 100644 src/contribs/contribs-lib-test/TestAnalysis.cpp create mode 100644 src/contribs/contribs-lib-test/TestHighlight.cpp create mode 100644 src/contribs/contribs-lib-test/TestSnowball.cpp create mode 100644 src/contribs/contribs-lib-test/TestStreams.cpp create mode 100644 src/contribs/contribs-lib-test/TestUtf8.cpp create mode 100644 src/contribs/contribs-lib-test/contribTests.cpp create mode 100644 src/contribs/contribs-lib-test/test.h create mode 100644 src/contribs/contribs-lib-test/testall.cpp create mode 100644 src/core/CLucene.h create mode 100644 src/core/CLucene/CLConfig.h create mode 100644 src/core/CLucene/CLMonolithic.cpp create mode 100644 src/core/CLucene/StdHeader.cpp create mode 100644 src/core/CLucene/StdHeader.h create mode 100644 src/core/CLucene/_ApiHeader.h create mode 100644 src/core/CLucene/analysis/AnalysisHeader.cpp create mode 100644 src/core/CLucene/analysis/AnalysisHeader.h create mode 100644 src/core/CLucene/analysis/Analyzers.cpp create mode 100644 src/core/CLucene/analysis/Analyzers.h create mode 100644 src/core/CLucene/analysis/CachingTokenFilter.cpp create mode 100644 src/core/CLucene/analysis/CachingTokenFilter.h create mode 100644 src/core/CLucene/analysis/standard/StandardAnalyzer.cpp create mode 100644 src/core/CLucene/analysis/standard/StandardAnalyzer.h create mode 100644 src/core/CLucene/analysis/standard/StandardFilter.cpp create mode 100644 src/core/CLucene/analysis/standard/StandardFilter.h create mode 100644 src/core/CLucene/analysis/standard/StandardTokenizer.cpp create mode 100644 src/core/CLucene/analysis/standard/StandardTokenizer.h create mode 100644 src/core/CLucene/analysis/standard/StandardTokenizerConstants.h create mode 100644 src/core/CLucene/debug/error.cpp create mode 100644 src/core/CLucene/debug/error.h create mode 100644 src/core/CLucene/debug/lucenebase.h create mode 100644 src/core/CLucene/debug/mem.h create mode 100644 src/core/CLucene/document/DateField.cpp create mode 100644 src/core/CLucene/document/DateField.h create mode 100644 src/core/CLucene/document/DateTools.cpp create mode 100644 src/core/CLucene/document/DateTools.h create mode 100644 src/core/CLucene/document/Document.cpp create mode 100644 src/core/CLucene/document/Document.h create mode 100644 src/core/CLucene/document/Field.cpp create mode 100644 src/core/CLucene/document/Field.h create mode 100644 src/core/CLucene/document/FieldSelector.cpp create mode 100644 src/core/CLucene/document/FieldSelector.h create mode 100644 src/core/CLucene/document/NumberTools.cpp create mode 100644 src/core/CLucene/document/NumberTools.h create mode 100644 src/core/CLucene/index/CompoundFile.cpp create mode 100644 src/core/CLucene/index/DirectoryIndexReader.cpp create mode 100644 src/core/CLucene/index/DirectoryIndexReader.h create mode 100644 src/core/CLucene/index/DocumentsWriter.cpp create mode 100644 src/core/CLucene/index/DocumentsWriterThreadState.cpp create mode 100644 src/core/CLucene/index/FieldInfos.cpp create mode 100644 src/core/CLucene/index/FieldsReader.cpp create mode 100644 src/core/CLucene/index/FieldsWriter.cpp create mode 100644 src/core/CLucene/index/IndexDeletionPolicy.cpp create mode 100644 src/core/CLucene/index/IndexDeletionPolicy.h create mode 100644 src/core/CLucene/index/IndexFileDeleter.cpp create mode 100644 src/core/CLucene/index/IndexFileNameFilter.cpp create mode 100644 src/core/CLucene/index/IndexFileNames.cpp create mode 100644 src/core/CLucene/index/IndexModifier.cpp create mode 100644 src/core/CLucene/index/IndexModifier.h create mode 100644 src/core/CLucene/index/IndexReader.cpp create mode 100644 src/core/CLucene/index/IndexReader.h create mode 100644 src/core/CLucene/index/IndexWriter.cpp create mode 100644 src/core/CLucene/index/IndexWriter.h create mode 100644 src/core/CLucene/index/MergePolicy.cpp create mode 100644 src/core/CLucene/index/MergePolicy.h create mode 100644 src/core/CLucene/index/MergeScheduler.cpp create mode 100644 src/core/CLucene/index/MergeScheduler.h create mode 100644 src/core/CLucene/index/MultiReader.cpp create mode 100644 src/core/CLucene/index/MultiReader.h create mode 100644 src/core/CLucene/index/MultiSegmentReader.cpp create mode 100644 src/core/CLucene/index/MultipleTermPositions.cpp create mode 100644 src/core/CLucene/index/MultipleTermPositions.h create mode 100644 src/core/CLucene/index/Payload.cpp create mode 100644 src/core/CLucene/index/Payload.h create mode 100644 src/core/CLucene/index/SDocumentWriter.cpp create mode 100644 src/core/CLucene/index/SDocumentWriter.h create mode 100644 src/core/CLucene/index/SegmentInfos.cpp create mode 100644 src/core/CLucene/index/SegmentMergeInfo.cpp create mode 100644 src/core/CLucene/index/SegmentMergeQueue.cpp create mode 100644 src/core/CLucene/index/SegmentMerger.cpp create mode 100644 src/core/CLucene/index/SegmentReader.cpp create mode 100644 src/core/CLucene/index/SegmentTermDocs.cpp create mode 100644 src/core/CLucene/index/SegmentTermEnum.cpp create mode 100644 src/core/CLucene/index/SegmentTermPositions.cpp create mode 100644 src/core/CLucene/index/SegmentTermVector.cpp create mode 100644 src/core/CLucene/index/SkipListReader.cpp create mode 100644 src/core/CLucene/index/SkipListWriter.cpp create mode 100644 src/core/CLucene/index/Term.cpp create mode 100644 src/core/CLucene/index/Term.h create mode 100644 src/core/CLucene/index/TermInfo.cpp create mode 100644 src/core/CLucene/index/TermInfosReader.cpp create mode 100644 src/core/CLucene/index/TermInfosWriter.cpp create mode 100644 src/core/CLucene/index/TermVector.h create mode 100644 src/core/CLucene/index/TermVectorReader.cpp create mode 100644 src/core/CLucene/index/TermVectorWriter.cpp create mode 100644 src/core/CLucene/index/Terms.cpp create mode 100644 src/core/CLucene/index/Terms.h create mode 100644 src/core/CLucene/index/_CompoundFile.h create mode 100644 src/core/CLucene/index/_DocumentsWriter.h create mode 100644 src/core/CLucene/index/_FieldInfo.h create mode 100644 src/core/CLucene/index/_FieldInfos.h create mode 100644 src/core/CLucene/index/_FieldsReader.h create mode 100644 src/core/CLucene/index/_FieldsWriter.h create mode 100644 src/core/CLucene/index/_IndexFileDeleter.h create mode 100644 src/core/CLucene/index/_IndexFileNameFilter.h create mode 100644 src/core/CLucene/index/_IndexFileNames.h create mode 100644 src/core/CLucene/index/_MultiSegmentReader.h create mode 100644 src/core/CLucene/index/_SegmentHeader.h create mode 100644 src/core/CLucene/index/_SegmentInfos.h create mode 100644 src/core/CLucene/index/_SegmentMergeInfo.h create mode 100644 src/core/CLucene/index/_SegmentMergeQueue.h create mode 100644 src/core/CLucene/index/_SegmentMerger.h create mode 100644 src/core/CLucene/index/_SegmentTermEnum.h create mode 100644 src/core/CLucene/index/_SkipListReader.h create mode 100644 src/core/CLucene/index/_SkipListWriter.h create mode 100644 src/core/CLucene/index/_Term.h create mode 100644 src/core/CLucene/index/_TermInfo.h create mode 100644 src/core/CLucene/index/_TermInfosReader.h create mode 100644 src/core/CLucene/index/_TermInfosWriter.h create mode 100644 src/core/CLucene/index/_TermVector.h create mode 100644 src/core/CLucene/index/bpacking.cpp create mode 100644 src/core/CLucene/index/bpacking.h create mode 100644 src/core/CLucene/index/common.h create mode 100644 src/core/CLucene/index/compression.h create mode 100644 src/core/CLucene/index/turbocompression.h create mode 100644 src/core/CLucene/index/turbopacking32.h create mode 100644 src/core/CLucene/index/turbopacking64.h create mode 100644 src/core/CLucene/index/util.h create mode 100644 src/core/CLucene/queryParser/FastCharStream.cpp create mode 100644 src/core/CLucene/queryParser/MultiFieldQueryParser.cpp create mode 100644 src/core/CLucene/queryParser/MultiFieldQueryParser.h create mode 100644 src/core/CLucene/queryParser/QueryParser.cpp create mode 100644 src/core/CLucene/queryParser/QueryParser.h create mode 100644 src/core/CLucene/queryParser/QueryParserConstants.h create mode 100644 src/core/CLucene/queryParser/QueryParserTokenManager.cpp create mode 100644 src/core/CLucene/queryParser/QueryParserTokenManager.h create mode 100644 src/core/CLucene/queryParser/QueryToken.cpp create mode 100644 src/core/CLucene/queryParser/QueryToken.h create mode 100644 src/core/CLucene/queryParser/_CharStream.h create mode 100644 src/core/CLucene/queryParser/_FastCharStream.h create mode 100644 src/core/CLucene/queryParser/legacy/Lexer.cpp create mode 100644 src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.cpp create mode 100644 src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.h create mode 100644 src/core/CLucene/queryParser/legacy/QueryParser.cpp create mode 100644 src/core/CLucene/queryParser/legacy/QueryParser.h create mode 100644 src/core/CLucene/queryParser/legacy/QueryParserBase.cpp create mode 100644 src/core/CLucene/queryParser/legacy/QueryToken.cpp create mode 100644 src/core/CLucene/queryParser/legacy/QueryToken.h create mode 100644 src/core/CLucene/queryParser/legacy/TokenList.cpp create mode 100644 src/core/CLucene/queryParser/legacy/_Lexer.h create mode 100644 src/core/CLucene/queryParser/legacy/_TokenList.h create mode 100644 src/core/CLucene/search/BooleanClause.h create mode 100644 src/core/CLucene/search/BooleanQuery.cpp create mode 100644 src/core/CLucene/search/BooleanQuery.h create mode 100644 src/core/CLucene/search/BooleanScorer.cpp create mode 100644 src/core/CLucene/search/BooleanScorer2.cpp create mode 100644 src/core/CLucene/search/CachingSpanFilter.cpp create mode 100644 src/core/CLucene/search/CachingSpanFilter.h create mode 100644 src/core/CLucene/search/CachingWrapperFilter.cpp create mode 100644 src/core/CLucene/search/CachingWrapperFilter.h create mode 100644 src/core/CLucene/search/ChainedFilter.cpp create mode 100644 src/core/CLucene/search/ChainedFilter.h create mode 100644 src/core/CLucene/search/Compare.cpp create mode 100644 src/core/CLucene/search/Compare.h create mode 100644 src/core/CLucene/search/ConjunctionScorer.cpp create mode 100644 src/core/CLucene/search/ConstantScoreQuery.cpp create mode 100644 src/core/CLucene/search/ConstantScoreQuery.h create mode 100644 src/core/CLucene/search/DateFilter.cpp create mode 100644 src/core/CLucene/search/DateFilter.h create mode 100644 src/core/CLucene/search/DisjunctionSumScorer.cpp create mode 100644 src/core/CLucene/search/ExactPhraseScorer.cpp create mode 100644 src/core/CLucene/search/Explanation.cpp create mode 100644 src/core/CLucene/search/Explanation.h create mode 100644 src/core/CLucene/search/FieldCache.cpp create mode 100644 src/core/CLucene/search/FieldCache.h create mode 100644 src/core/CLucene/search/FieldCacheImpl.cpp create mode 100644 src/core/CLucene/search/FieldDoc.h create mode 100644 src/core/CLucene/search/FieldDocSortedHitQueue.cpp create mode 100644 src/core/CLucene/search/FieldSortedHitQueue.cpp create mode 100644 src/core/CLucene/search/FieldSortedHitQueue.h create mode 100644 src/core/CLucene/search/Filter.h create mode 100644 src/core/CLucene/search/FilterResultCache.cpp create mode 100644 src/core/CLucene/search/FilterResultCache.h create mode 100644 src/core/CLucene/search/FilteredTermEnum.cpp create mode 100644 src/core/CLucene/search/FilteredTermEnum.h create mode 100644 src/core/CLucene/search/FuzzyQuery.cpp create mode 100644 src/core/CLucene/search/FuzzyQuery.h create mode 100644 src/core/CLucene/search/HitQueue.cpp create mode 100644 src/core/CLucene/search/Hits.cpp create mode 100644 src/core/CLucene/search/Hits.h create mode 100644 src/core/CLucene/search/IndexSearcher.cpp create mode 100644 src/core/CLucene/search/IndexSearcher.h create mode 100644 src/core/CLucene/search/MatchAllDocsQuery.cpp create mode 100644 src/core/CLucene/search/MatchAllDocsQuery.h create mode 100644 src/core/CLucene/search/MultiPhraseQuery.cpp create mode 100644 src/core/CLucene/search/MultiPhraseQuery.h create mode 100644 src/core/CLucene/search/MultiSearcher.cpp create mode 100644 src/core/CLucene/search/MultiSearcher.h create mode 100644 src/core/CLucene/search/MultiTermQuery.cpp create mode 100644 src/core/CLucene/search/MultiTermQuery.h create mode 100644 src/core/CLucene/search/PhrasePositions.cpp create mode 100644 src/core/CLucene/search/PhraseQuery.cpp create mode 100644 src/core/CLucene/search/PhraseQuery.h create mode 100644 src/core/CLucene/search/PhraseScorer.cpp create mode 100644 src/core/CLucene/search/PrefixQuery.cpp create mode 100644 src/core/CLucene/search/PrefixQuery.h create mode 100644 src/core/CLucene/search/Query.h create mode 100644 src/core/CLucene/search/QueryFilter.cpp create mode 100644 src/core/CLucene/search/QueryFilter.h create mode 100644 src/core/CLucene/search/RangeFilter.cpp create mode 100644 src/core/CLucene/search/RangeFilter.h create mode 100644 src/core/CLucene/search/RangeQuery.cpp create mode 100644 src/core/CLucene/search/RangeQuery.h create mode 100644 src/core/CLucene/search/Scorer.cpp create mode 100644 src/core/CLucene/search/Scorer.h create mode 100644 src/core/CLucene/search/ScorerDocQueue.cpp create mode 100644 src/core/CLucene/search/ScorerDocQueue.h create mode 100644 src/core/CLucene/search/SearchHeader.cpp create mode 100644 src/core/CLucene/search/SearchHeader.h create mode 100644 src/core/CLucene/search/Searchable.h create mode 100644 src/core/CLucene/search/Similarity.cpp create mode 100644 src/core/CLucene/search/Similarity.h create mode 100644 src/core/CLucene/search/SloppyPhraseScorer.cpp create mode 100644 src/core/CLucene/search/Sort.cpp create mode 100644 src/core/CLucene/search/Sort.h create mode 100644 src/core/CLucene/search/SpanFilter.h create mode 100644 src/core/CLucene/search/SpanFilterResult.h create mode 100644 src/core/CLucene/search/SpanQueryFilter.cpp create mode 100644 src/core/CLucene/search/SpanQueryFilter.h create mode 100644 src/core/CLucene/search/TermQuery.cpp create mode 100644 src/core/CLucene/search/TermQuery.h create mode 100644 src/core/CLucene/search/TermScorer.cpp create mode 100644 src/core/CLucene/search/WildcardQuery.cpp create mode 100644 src/core/CLucene/search/WildcardQuery.h create mode 100644 src/core/CLucene/search/WildcardTermEnum.cpp create mode 100644 src/core/CLucene/search/WildcardTermEnum.h create mode 100644 src/core/CLucene/search/_BooleanScorer.h create mode 100644 src/core/CLucene/search/_BooleanScorer2.h create mode 100644 src/core/CLucene/search/_ConjunctionScorer.h create mode 100644 src/core/CLucene/search/_DisjunctionSumScorer.h create mode 100644 src/core/CLucene/search/_ExactPhraseScorer.h create mode 100644 src/core/CLucene/search/_FieldCacheImpl.h create mode 100644 src/core/CLucene/search/_FieldDocSortedHitQueue.h create mode 100644 src/core/CLucene/search/_HitQueue.h create mode 100644 src/core/CLucene/search/_PhrasePositions.h create mode 100644 src/core/CLucene/search/_PhraseQueue.h create mode 100644 src/core/CLucene/search/_PhraseScorer.h create mode 100644 src/core/CLucene/search/_SloppyPhraseScorer.h create mode 100644 src/core/CLucene/search/_TermScorer.h create mode 100644 src/core/CLucene/search/spans/NearSpansOrdered.cpp create mode 100644 src/core/CLucene/search/spans/NearSpansUnordered.cpp create mode 100644 src/core/CLucene/search/spans/SpanFirstQuery.cpp create mode 100644 src/core/CLucene/search/spans/SpanFirstQuery.h create mode 100644 src/core/CLucene/search/spans/SpanNearQuery.cpp create mode 100644 src/core/CLucene/search/spans/SpanNearQuery.h create mode 100644 src/core/CLucene/search/spans/SpanNotQuery.cpp create mode 100644 src/core/CLucene/search/spans/SpanNotQuery.h create mode 100644 src/core/CLucene/search/spans/SpanOrQuery.cpp create mode 100644 src/core/CLucene/search/spans/SpanOrQuery.h create mode 100644 src/core/CLucene/search/spans/SpanQuery.h create mode 100644 src/core/CLucene/search/spans/SpanScorer.cpp create mode 100644 src/core/CLucene/search/spans/SpanScorer.h create mode 100644 src/core/CLucene/search/spans/SpanTermQuery.cpp create mode 100644 src/core/CLucene/search/spans/SpanTermQuery.h create mode 100644 src/core/CLucene/search/spans/SpanWeight.cpp create mode 100644 src/core/CLucene/search/spans/SpanWeight.h create mode 100644 src/core/CLucene/search/spans/Spans.h create mode 100644 src/core/CLucene/search/spans/TermSpans.cpp create mode 100644 src/core/CLucene/search/spans/_EmptySpans.h create mode 100644 src/core/CLucene/search/spans/_NearSpansOrdered.h create mode 100644 src/core/CLucene/search/spans/_NearSpansUnordered.h create mode 100644 src/core/CLucene/search/spans/_TermSpans.h create mode 100644 src/core/CLucene/store/ByteArrayDataInput.cpp create mode 100644 src/core/CLucene/store/ByteArrayDataInput.h create mode 100644 src/core/CLucene/store/Directory.cpp create mode 100644 src/core/CLucene/store/Directory.h create mode 100644 src/core/CLucene/store/FSDirectory.cpp create mode 100644 src/core/CLucene/store/FSDirectory.h create mode 100644 src/core/CLucene/store/IndexInput.cpp create mode 100644 src/core/CLucene/store/IndexInput.h create mode 100644 src/core/CLucene/store/IndexOutput.cpp create mode 100644 src/core/CLucene/store/IndexOutput.h create mode 100644 src/core/CLucene/store/Lock.cpp create mode 100644 src/core/CLucene/store/Lock.h create mode 100644 src/core/CLucene/store/LockFactory.cpp create mode 100644 src/core/CLucene/store/LockFactory.h create mode 100644 src/core/CLucene/store/MMapInput.cpp create mode 100644 src/core/CLucene/store/RAMDirectory.cpp create mode 100644 src/core/CLucene/store/RAMDirectory.h create mode 100644 src/core/CLucene/store/_Lock.h create mode 100644 src/core/CLucene/store/_MMapIndexInput.h create mode 100644 src/core/CLucene/store/_RAMDirectory.h create mode 100644 src/core/CLucene/util/Array.h create mode 100644 src/core/CLucene/util/BitSet.cpp create mode 100644 src/core/CLucene/util/BitSet.h create mode 100644 src/core/CLucene/util/BitUtil.cpp create mode 100644 src/core/CLucene/util/BitUtil.h create mode 100644 src/core/CLucene/util/BytesRef.cpp create mode 100644 src/core/CLucene/util/BytesRef.h create mode 100644 src/core/CLucene/util/BytesRefBuilder.cpp create mode 100644 src/core/CLucene/util/BytesRefBuilder.h create mode 100644 src/core/CLucene/util/CLStreams.h create mode 100644 src/core/CLucene/util/CodecUtil.cpp create mode 100644 src/core/CLucene/util/CodecUtil.h create mode 100644 src/core/CLucene/util/Equators.cpp create mode 100644 src/core/CLucene/util/Equators.h create mode 100644 src/core/CLucene/util/FastCharStream.cpp create mode 100644 src/core/CLucene/util/FixedBitSet.cpp create mode 100644 src/core/CLucene/util/FixedBitSet.h create mode 100644 src/core/CLucene/util/FutureArrays.cpp create mode 100644 src/core/CLucene/util/FutureArrays.h create mode 100644 src/core/CLucene/util/IntroSorter.cpp create mode 100644 src/core/CLucene/util/IntroSorter.h create mode 100644 src/core/CLucene/util/LongBitSet.cpp create mode 100644 src/core/CLucene/util/LongBitSet.h create mode 100644 src/core/CLucene/util/MD5Digester.cpp create mode 100644 src/core/CLucene/util/MSBRadixSorter.cpp create mode 100644 src/core/CLucene/util/MSBRadixSorter.h create mode 100644 src/core/CLucene/util/NumericUtils.cpp create mode 100644 src/core/CLucene/util/NumericUtils.h create mode 100644 src/core/CLucene/util/OfflineSorter.h create mode 100644 src/core/CLucene/util/PriorityQueue.h create mode 100644 src/core/CLucene/util/Reader.cpp create mode 100644 src/core/CLucene/util/Reader.h create mode 100644 src/core/CLucene/util/Sorter.cpp create mode 100644 src/core/CLucene/util/Sorter.h create mode 100644 src/core/CLucene/util/StringIntern.cpp create mode 100644 src/core/CLucene/util/ThreadLocal.cpp create mode 100644 src/core/CLucene/util/Time.h create mode 100644 src/core/CLucene/util/VoidList.h create mode 100644 src/core/CLucene/util/VoidMap.h create mode 100644 src/core/CLucene/util/_Arrays.h create mode 100644 src/core/CLucene/util/_FastCharStream.h create mode 100644 src/core/CLucene/util/_MD5Digester.h create mode 100644 src/core/CLucene/util/_StringIntern.h create mode 100644 src/core/CLucene/util/_ThreadLocal.h create mode 100644 src/core/CLucene/util/_VoidList.h create mode 100644 src/core/CLucene/util/_VoidMap.h create mode 100644 src/core/CLucene/util/_bufferedstream.h create mode 100644 src/core/CLucene/util/_streambase.h create mode 100644 src/core/CLucene/util/_streambuffer.h create mode 100644 src/core/CLucene/util/bkd/bkd_docid_iterator.h create mode 100644 src/core/CLucene/util/bkd/bkd_msb_radix_sorter.cpp create mode 100644 src/core/CLucene/util/bkd/bkd_msb_radix_sorter.h create mode 100644 src/core/CLucene/util/bkd/bkd_reader.cpp create mode 100644 src/core/CLucene/util/bkd/bkd_reader.h create mode 100644 src/core/CLucene/util/bkd/bkd_writer.cpp create mode 100644 src/core/CLucene/util/bkd/bkd_writer.h create mode 100644 src/core/CLucene/util/bkd/docIds_writer.cpp create mode 100644 src/core/CLucene/util/bkd/docIds_writer.h create mode 100644 src/core/CLucene/util/bkd/heap_point_reader.cpp create mode 100644 src/core/CLucene/util/bkd/heap_point_reader.h create mode 100644 src/core/CLucene/util/bkd/heap_point_writer.cpp create mode 100644 src/core/CLucene/util/bkd/heap_point_writer.h create mode 100644 src/core/CLucene/util/bkd/index_tree.cpp create mode 100644 src/core/CLucene/util/bkd/index_tree.h create mode 100644 src/core/CLucene/util/bkd/legacy_index_tree.cpp create mode 100644 src/core/CLucene/util/bkd/legacy_index_tree.h create mode 100644 src/core/CLucene/util/bkd/packed_index_tree.cpp create mode 100644 src/core/CLucene/util/bkd/packed_index_tree.h create mode 100644 src/core/CLucene/util/bkd/point_reader.cpp create mode 100644 src/core/CLucene/util/bkd/point_reader.h create mode 100644 src/core/CLucene/util/bkd/point_writer.h create mode 100644 src/core/CLucene/util/croaring/LICENSE create mode 100644 src/core/CLucene/util/croaring/README.md create mode 100644 src/core/CLucene/util/croaring/roaring.c create mode 100644 src/core/CLucene/util/croaring/roaring.h create mode 100644 src/core/CLucene/util/croaring/roaring.hh create mode 100644 src/core/CLucene/util/stringUtil.cpp create mode 100644 src/core/CLucene/util/stringUtil.h create mode 100644 src/core/CMakeLists.txt create mode 100644 src/core/files_list.txt create mode 100644 src/core/libclucene-core.pc.cmake create mode 100644 src/core/vp4.h create mode 100644 src/demo/CMakeLists.txt create mode 100644 src/demo/DeleteFiles.cpp create mode 100644 src/demo/IndexFiles.cpp create mode 100644 src/demo/Main.cpp create mode 100644 src/demo/Main_Index.cpp create mode 100644 src/demo/README create mode 100644 src/demo/SearchFiles.cpp create mode 100644 src/demo/Statistics.cpp create mode 100644 src/demo/TestAnalyzer.cpp create mode 100644 src/ext/CMakeLists.txt create mode 100644 src/ext/boost/assert.hpp create mode 100644 src/ext/boost/checked_delete.hpp create mode 100644 src/ext/boost/config.hpp create mode 100644 src/ext/boost/config/abi/borland_prefix.hpp create mode 100644 src/ext/boost/config/abi/borland_suffix.hpp create mode 100644 src/ext/boost/config/abi/msvc_prefix.hpp create mode 100644 src/ext/boost/config/abi/msvc_suffix.hpp create mode 100644 src/ext/boost/config/abi_prefix.hpp create mode 100644 src/ext/boost/config/abi_suffix.hpp create mode 100644 src/ext/boost/config/auto_link.hpp create mode 100644 src/ext/boost/config/compiler/borland.hpp create mode 100644 src/ext/boost/config/compiler/codegear.hpp create mode 100644 src/ext/boost/config/compiler/comeau.hpp create mode 100644 src/ext/boost/config/compiler/common_edg.hpp create mode 100644 src/ext/boost/config/compiler/compaq_cxx.hpp create mode 100644 src/ext/boost/config/compiler/digitalmars.hpp create mode 100644 src/ext/boost/config/compiler/gcc.hpp create mode 100644 src/ext/boost/config/compiler/gcc_xml.hpp create mode 100644 src/ext/boost/config/compiler/greenhills.hpp create mode 100644 src/ext/boost/config/compiler/hp_acc.hpp create mode 100644 src/ext/boost/config/compiler/intel.hpp create mode 100644 src/ext/boost/config/compiler/kai.hpp create mode 100644 src/ext/boost/config/compiler/metrowerks.hpp create mode 100644 src/ext/boost/config/compiler/mpw.hpp create mode 100644 src/ext/boost/config/compiler/pgi.hpp create mode 100644 src/ext/boost/config/compiler/sgi_mipspro.hpp create mode 100644 src/ext/boost/config/compiler/sunpro_cc.hpp create mode 100644 src/ext/boost/config/compiler/vacpp.hpp create mode 100644 src/ext/boost/config/compiler/visualc.hpp create mode 100644 src/ext/boost/config/no_tr1/cmath.hpp create mode 100644 src/ext/boost/config/no_tr1/complex.hpp create mode 100644 src/ext/boost/config/no_tr1/functional.hpp create mode 100644 src/ext/boost/config/no_tr1/memory.hpp create mode 100644 src/ext/boost/config/no_tr1/utility.hpp create mode 100644 src/ext/boost/config/platform/aix.hpp create mode 100644 src/ext/boost/config/platform/amigaos.hpp create mode 100644 src/ext/boost/config/platform/beos.hpp create mode 100644 src/ext/boost/config/platform/bsd.hpp create mode 100644 src/ext/boost/config/platform/cygwin.hpp create mode 100644 src/ext/boost/config/platform/hpux.hpp create mode 100644 src/ext/boost/config/platform/irix.hpp create mode 100644 src/ext/boost/config/platform/linux.hpp create mode 100644 src/ext/boost/config/platform/macos.hpp create mode 100644 src/ext/boost/config/platform/qnxnto.hpp create mode 100644 src/ext/boost/config/platform/solaris.hpp create mode 100644 src/ext/boost/config/platform/vxworks.hpp create mode 100644 src/ext/boost/config/platform/win32.hpp create mode 100644 src/ext/boost/config/posix_features.hpp create mode 100644 src/ext/boost/config/requires_threads.hpp create mode 100644 src/ext/boost/config/select_compiler_config.hpp create mode 100644 src/ext/boost/config/select_platform_config.hpp create mode 100644 src/ext/boost/config/select_stdlib_config.hpp create mode 100644 src/ext/boost/config/stdlib/dinkumware.hpp create mode 100644 src/ext/boost/config/stdlib/libcomo.hpp create mode 100644 src/ext/boost/config/stdlib/libstdcpp3.hpp create mode 100644 src/ext/boost/config/stdlib/modena.hpp create mode 100644 src/ext/boost/config/stdlib/msl.hpp create mode 100644 src/ext/boost/config/stdlib/roguewave.hpp create mode 100644 src/ext/boost/config/stdlib/sgi.hpp create mode 100644 src/ext/boost/config/stdlib/stlport.hpp create mode 100644 src/ext/boost/config/stdlib/vacpp.hpp create mode 100644 src/ext/boost/config/suffix.hpp create mode 100644 src/ext/boost/config/user.hpp create mode 100644 src/ext/boost/config/warning_disable.hpp create mode 100644 src/ext/boost/current_function.hpp create mode 100644 src/ext/boost/detail/algorithm.hpp create mode 100644 src/ext/boost/detail/allocator_utilities.hpp create mode 100644 src/ext/boost/detail/atomic_count.hpp create mode 100644 src/ext/boost/detail/binary_search.hpp create mode 100644 src/ext/boost/detail/call_traits.hpp create mode 100644 src/ext/boost/detail/catch_exceptions.hpp create mode 100644 src/ext/boost/detail/compressed_pair.hpp create mode 100644 src/ext/boost/detail/container_fwd.hpp create mode 100644 src/ext/boost/detail/dynamic_bitset.hpp create mode 100644 src/ext/boost/detail/endian.hpp create mode 100644 src/ext/boost/detail/has_default_constructor.hpp create mode 100644 src/ext/boost/detail/identifier.hpp create mode 100644 src/ext/boost/detail/indirect_traits.hpp create mode 100644 src/ext/boost/detail/interlocked.hpp create mode 100644 src/ext/boost/detail/is_function_ref_tester.hpp create mode 100644 src/ext/boost/detail/is_incrementable.hpp create mode 100644 src/ext/boost/detail/is_xxx.hpp create mode 100644 src/ext/boost/detail/iterator.hpp create mode 100644 src/ext/boost/detail/lcast_precision.hpp create mode 100644 src/ext/boost/detail/lightweight_mutex.hpp create mode 100644 src/ext/boost/detail/lightweight_test.hpp create mode 100644 src/ext/boost/detail/lightweight_thread.hpp create mode 100644 src/ext/boost/detail/limits.hpp create mode 100644 src/ext/boost/detail/named_template_params.hpp create mode 100644 src/ext/boost/detail/no_exceptions_support.hpp create mode 100644 src/ext/boost/detail/none_t.hpp create mode 100644 src/ext/boost/detail/numeric_traits.hpp create mode 100644 src/ext/boost/detail/ob_call_traits.hpp create mode 100644 src/ext/boost/detail/ob_compressed_pair.hpp create mode 100644 src/ext/boost/detail/quick_allocator.hpp create mode 100644 src/ext/boost/detail/reference_content.hpp create mode 100644 src/ext/boost/detail/scoped_enum_emulation.hpp create mode 100644 src/ext/boost/detail/select_type.hpp create mode 100644 src/ext/boost/detail/sp_typeinfo.hpp create mode 100644 src/ext/boost/detail/templated_streams.hpp create mode 100644 src/ext/boost/detail/utf8_codecvt_facet.hpp create mode 100644 src/ext/boost/detail/workaround.hpp create mode 100644 src/ext/boost/exception/all.hpp create mode 100644 src/ext/boost/exception/current_exception_cast.hpp create mode 100644 src/ext/boost/exception/detail/attribute_noreturn.hpp create mode 100644 src/ext/boost/exception/detail/error_info_impl.hpp create mode 100644 src/ext/boost/exception/detail/exception_ptr.hpp create mode 100644 src/ext/boost/exception/detail/is_output_streamable.hpp create mode 100644 src/ext/boost/exception/detail/object_hex_dump.hpp create mode 100644 src/ext/boost/exception/detail/type_info.hpp create mode 100644 src/ext/boost/exception/diagnostic_information.hpp create mode 100644 src/ext/boost/exception/enable_current_exception.hpp create mode 100644 src/ext/boost/exception/enable_error_info.hpp create mode 100644 src/ext/boost/exception/errinfo_api_function.hpp create mode 100644 src/ext/boost/exception/errinfo_at_line.hpp create mode 100644 src/ext/boost/exception/errinfo_errno.hpp create mode 100644 src/ext/boost/exception/errinfo_file_handle.hpp create mode 100644 src/ext/boost/exception/errinfo_file_name.hpp create mode 100644 src/ext/boost/exception/errinfo_file_open_mode.hpp create mode 100644 src/ext/boost/exception/errinfo_nested_exception.hpp create mode 100644 src/ext/boost/exception/errinfo_type_info_name.hpp create mode 100644 src/ext/boost/exception/error_info.hpp create mode 100644 src/ext/boost/exception/exception.hpp create mode 100644 src/ext/boost/exception/get_error_info.hpp create mode 100644 src/ext/boost/exception/info.hpp create mode 100644 src/ext/boost/exception/info_tuple.hpp create mode 100644 src/ext/boost/exception/to_string.hpp create mode 100644 src/ext/boost/exception/to_string_stub.hpp create mode 100644 src/ext/boost/memory_order.hpp create mode 100644 src/ext/boost/shared_ptr.hpp create mode 100644 src/ext/boost/smart_ptr/bad_weak_ptr.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_gcc.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_pthreads.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_solaris.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_sync.hpp create mode 100644 src/ext/boost/smart_ptr/detail/atomic_count_win32.hpp create mode 100644 src/ext/boost/smart_ptr/detail/lightweight_mutex.hpp create mode 100644 src/ext/boost/smart_ptr/detail/lwm_nop.hpp create mode 100644 src/ext/boost/smart_ptr/detail/lwm_pthreads.hpp create mode 100644 src/ext/boost/smart_ptr/detail/lwm_win32_cs.hpp create mode 100644 src/ext/boost/smart_ptr/detail/operator_bool.hpp create mode 100644 src/ext/boost/smart_ptr/detail/quick_allocator.hpp create mode 100644 src/ext/boost/smart_ptr/detail/shared_array_nmt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/shared_count.hpp create mode 100644 src/ext/boost/smart_ptr/detail/shared_ptr_nmt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_convertible.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_base_w32.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 src/ext/boost/smart_ptr/detail/sp_has_sync.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_nt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_pool.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_pt.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_sync.hpp create mode 100644 src/ext/boost/smart_ptr/detail/spinlock_w32.hpp create mode 100644 src/ext/boost/smart_ptr/detail/yield_k.hpp create mode 100644 src/ext/boost/smart_ptr/enable_shared_from_this.hpp create mode 100644 src/ext/boost/smart_ptr/enable_shared_from_this2.hpp create mode 100644 src/ext/boost/smart_ptr/intrusive_ptr.hpp create mode 100644 src/ext/boost/smart_ptr/make_shared.hpp create mode 100644 src/ext/boost/smart_ptr/scoped_array.hpp create mode 100644 src/ext/boost/smart_ptr/scoped_ptr.hpp create mode 100644 src/ext/boost/smart_ptr/shared_array.hpp create mode 100644 src/ext/boost/smart_ptr/shared_ptr.hpp create mode 100644 src/ext/boost/smart_ptr/weak_ptr.hpp create mode 100644 src/ext/boost/throw_exception.hpp create mode 100644 src/ext/boost/version.hpp create mode 100644 src/ext/for/README.md create mode 100644 src/ext/for/bitpack.c create mode 100644 src/ext/for/bitpack.h create mode 100644 src/ext/for/bitpack_.h create mode 100644 src/ext/for/bitunpack.c create mode 100644 src/ext/for/bitunpack_.h create mode 100644 src/ext/for/bitutil.c create mode 100644 src/ext/for/bitutil.h create mode 100644 src/ext/for/conf.h create mode 100644 src/ext/for/eliasfano.c create mode 100644 src/ext/for/eliasfano.h create mode 100644 src/ext/for/fp.c create mode 100644 src/ext/for/fp.h create mode 100644 src/ext/for/icapp.c create mode 100644 src/ext/for/icbench.c create mode 100644 src/ext/for/idx.h create mode 100644 src/ext/for/idxcr.c create mode 100644 src/ext/for/idxqry.c create mode 100644 src/ext/for/idxseg.c create mode 100644 src/ext/for/index.md create mode 100644 src/ext/for/jic.c create mode 100644 src/ext/for/lz.c create mode 100644 src/ext/for/makefile create mode 100644 src/ext/for/makefile.vs create mode 100644 src/ext/for/plugins.cc create mode 100644 src/ext/for/plugins.h create mode 100755 src/ext/for/sse_neon.h create mode 100644 src/ext/for/time_.h create mode 100644 src/ext/for/transpose.c create mode 100644 src/ext/for/transpose.h create mode 100644 src/ext/for/trle.h create mode 100644 src/ext/for/trle_.h create mode 100644 src/ext/for/trlec.c create mode 100644 src/ext/for/trled.c create mode 100644 src/ext/for/v8.c create mode 100644 src/ext/for/vint.c create mode 100644 src/ext/for/vint.h create mode 100644 src/ext/for/vp4.h create mode 100644 src/ext/for/vp4c.c create mode 100644 src/ext/for/vp4d.c create mode 100644 src/ext/for/vs/bitpack_avx2.c create mode 100644 src/ext/for/vs/bitpack_sse.c create mode 100644 src/ext/for/vs/bitunpack_avx2.c create mode 100644 src/ext/for/vs/bitunpack_sse.c create mode 100644 src/ext/for/vs/getopt.c create mode 100644 src/ext/for/vs/getopt.h create mode 100644 src/ext/for/vs/inttypes.h create mode 100644 src/ext/for/vs/stdint.h create mode 100644 src/ext/for/vs/transpose_avx2.c create mode 100644 src/ext/for/vs/transpose_sse.c create mode 100644 src/ext/for/vs/vp4c_avx2.c create mode 100644 src/ext/for/vs/vp4c_sse.c create mode 100644 src/ext/for/vs/vp4d_avx2.c create mode 100644 src/ext/for/vs/vp4d_sse.c create mode 100644 src/ext/for/vs/vs2017/TurboPFor.sln create mode 100644 src/ext/for/vs/vs2017/TurboPFor.vcxproj create mode 100644 src/ext/for/vs/vs2017/TurboPFor.vcxproj.filters create mode 100644 src/ext/for/vs/vs2017/icapp.vcxproj create mode 100644 src/ext/for/vs/vs2017/icapp.vcxproj.filters create mode 100644 src/ext/for/vsimple.c create mode 100644 src/ext/for/vsimple.h create mode 100755 src/ext/zlib/ChangeLog create mode 100755 src/ext/zlib/FAQ create mode 100755 src/ext/zlib/INDEX create mode 100755 src/ext/zlib/README create mode 100755 src/ext/zlib/adler32.c create mode 100755 src/ext/zlib/algorithm.txt create mode 100755 src/ext/zlib/compress.c create mode 100755 src/ext/zlib/crc32.c create mode 100755 src/ext/zlib/crc32.h create mode 100755 src/ext/zlib/deflate.c create mode 100755 src/ext/zlib/deflate.h create mode 100755 src/ext/zlib/gzio.c create mode 100755 src/ext/zlib/inffast.c create mode 100755 src/ext/zlib/inffast.h create mode 100755 src/ext/zlib/inffixed.h create mode 100755 src/ext/zlib/inflate.c create mode 100755 src/ext/zlib/inflate.h create mode 100755 src/ext/zlib/inftrees.c create mode 100755 src/ext/zlib/inftrees.h create mode 100755 src/ext/zlib/trees.c create mode 100755 src/ext/zlib/trees.h create mode 100755 src/ext/zlib/zconf.h create mode 100755 src/ext/zlib/zlib.h create mode 100755 src/ext/zlib/zutil.c create mode 100755 src/ext/zlib/zutil.h create mode 100644 src/gtest/CMakeLists.txt create mode 100644 src/gtest/parser/main.cpp create mode 100644 src/htdocs/README create mode 100644 src/htdocs/_footer.html create mode 100644 src/htdocs/_header.html create mode 100644 src/htdocs/_index.php create mode 100644 src/htdocs/clucene.jpg create mode 100644 src/htdocs/contribute.shtml create mode 100644 src/htdocs/download.shtml create mode 100644 src/htdocs/images/disk.png create mode 100644 src/htdocs/images/img01.gif create mode 100644 src/htdocs/images/img02.gif create mode 100644 src/htdocs/images/img03.gif create mode 100644 src/htdocs/images/img04.jpg create mode 100644 src/htdocs/images/img05.jpg create mode 100644 src/htdocs/images/img06.jpg create mode 100644 src/htdocs/images/img07.gif create mode 100644 src/htdocs/images/img08.jpg create mode 100644 src/htdocs/images/img09.jpg create mode 100644 src/htdocs/images/img10.jpg create mode 100644 src/htdocs/images/img11.gif create mode 100644 src/htdocs/images/spacer.gif create mode 100644 src/htdocs/index.shtml create mode 100644 src/htdocs/style.css create mode 100644 src/shared/CLucene/CLSharedMonolithic.cpp create mode 100644 src/shared/CLucene/LuceneThreads.h create mode 100644 src/shared/CLucene/SharedHeader.cpp create mode 100644 src/shared/CLucene/SharedHeader.h create mode 100644 src/shared/CLucene/_SharedHeader.h create mode 100644 src/shared/CLucene/_clucene-config.h.cmake create mode 100644 src/shared/CLucene/clucene-config.h.cmake create mode 100644 src/shared/CLucene/config/_gunichartables.h create mode 100644 src/shared/CLucene/config/_threads.h create mode 100644 src/shared/CLucene/config/gunichartables.cpp create mode 100644 src/shared/CLucene/config/repl_lltot.cpp create mode 100644 src/shared/CLucene/config/repl_tchar.h create mode 100644 src/shared/CLucene/config/repl_tcscasecmp.cpp create mode 100644 src/shared/CLucene/config/repl_tcslwr.cpp create mode 100644 src/shared/CLucene/config/repl_tcstod.cpp create mode 100644 src/shared/CLucene/config/repl_tcstoll.cpp create mode 100644 src/shared/CLucene/config/repl_tprintf.cpp create mode 100644 src/shared/CLucene/config/repl_wchar.h create mode 100644 src/shared/CLucene/config/repl_wctype.h create mode 100644 src/shared/CLucene/config/threads.cpp create mode 100644 src/shared/CLucene/config/utf8.cpp create mode 100644 src/shared/CLucene/debug/_condition.h create mode 100644 src/shared/CLucene/debug/condition.cpp create mode 100644 src/shared/CLucene/util/Misc.cpp create mode 100644 src/shared/CLucene/util/Misc.h create mode 100644 src/shared/CLucene/util/StringBuffer.cpp create mode 100644 src/shared/CLucene/util/StringBuffer.h create mode 100644 src/shared/CLucene/util/deflate.cpp create mode 100644 src/shared/CLucene/util/dirent.cpp create mode 100644 src/shared/CLucene/util/dirent.h create mode 100644 src/shared/CMakeLists.txt create mode 100644 src/shared/README create mode 100644 src/shared/cmake/CheckAtomicFunctions.cmake create mode 100644 src/shared/cmake/CheckErrorHandling.cmake create mode 100644 src/shared/cmake/CheckFloatByte.cmake create mode 100644 src/shared/cmake/CheckFloatByte.cpp.in create mode 100644 src/shared/cmake/CheckHashmaps.cmake create mode 100644 src/shared/cmake/CheckNamespace.cmake create mode 100644 src/shared/cmake/CheckPthread.cmake create mode 100644 src/shared/cmake/CheckSnprintf.cmake create mode 100644 src/shared/cmake/CheckStdCallFunctionExists.cmake create mode 100644 src/shared/cmake/CheckStdCallFunctionExists.cpp.in create mode 100644 src/shared/cmake/DefineDword.cmake create mode 100644 src/shared/cmake/DefineFloat.cmake create mode 100644 src/shared/cmake/DefineLongLongSyntax.cmake create mode 100644 src/shared/cmake/DefineMAXPATHValue.cmake create mode 100644 src/shared/cmake/DefineStaticSyntax.cmake create mode 100644 src/shared/cmake/MacroCheckGccVisibility.cmake create mode 100644 src/shared/cmake/MacroChooseFunction.cmake create mode 100644 src/shared/cmake/MacroChooseMisc.cmake create mode 100644 src/shared/cmake/MacroChooseSymbol.cmake create mode 100644 src/shared/cmake/MacroChooseType.cmake create mode 100644 src/shared/cmake/MacroEnsureVersion.cmake create mode 100644 src/shared/cmake/MacroGetVariableValue.c.in create mode 100644 src/shared/cmake/MacroGetVariableValue.cmake create mode 100644 src/shared/cmake/MacroMustDefine.cmake create mode 100644 src/shared/cmake/Macro_ChooseStatus.cmake create mode 100644 src/test/CLMonolithic_Test.cpp create mode 100644 src/test/CMakeLists.txt create mode 100644 src/test/CuTest.cpp create mode 100644 src/test/CuTest.h create mode 100644 src/test/README create mode 100644 src/test/analysis/TestAnalysis.cpp create mode 100644 src/test/analysis/TestAnalyzers.cpp create mode 100644 src/test/contribs-lib/analysis/de/TestGermanStemFilter.cpp create mode 100644 src/test/data/StopWords.test create mode 100644 src/test/data/contribs-lib/analysis/de/data.txt create mode 100644 src/test/data/french_unicode.bin create mode 100644 src/test/data/readme.txt create mode 100644 src/test/data/reuters-21578-index/_z.f0 create mode 100644 src/test/data/reuters-21578-index/_z.f1 create mode 100644 src/test/data/reuters-21578-index/_z.fdt create mode 100644 src/test/data/reuters-21578-index/_z.fdx create mode 100644 src/test/data/reuters-21578-index/_z.fnm create mode 100644 src/test/data/reuters-21578-index/_z.frq create mode 100644 src/test/data/reuters-21578-index/_z.prx create mode 100644 src/test/data/reuters-21578-index/_z.tii create mode 100644 src/test/data/reuters-21578-index/_z.tis create mode 100644 src/test/data/reuters-21578-index/deletable create mode 100644 src/test/data/reuters-21578-index/segments create mode 100644 src/test/data/reuters-21578/LEWIS.DTD create mode 100644 src/test/data/reuters-21578/README.TXT create mode 100644 src/test/data/reuters-21578/all-exchanges-strings.lc.txt create mode 100644 src/test/data/reuters-21578/all-orgs-strings.lc.txt create mode 100644 src/test/data/reuters-21578/all-people-strings.lc.txt create mode 100644 src/test/data/reuters-21578/all-places-strings.lc.txt create mode 100644 src/test/data/reuters-21578/all-topics-strings.lc.txt create mode 100644 src/test/data/reuters-21578/cat-descriptions_120396.txt create mode 100644 src/test/data/reuters-21578/feldman-cia-worldfactbook-data.txt create mode 100644 src/test/data/reuters-21578/reut2-000.sgm create mode 100644 src/test/data/reuters-21578/reut2-001.sgm create mode 100644 src/test/data/reuters-21578/reut2-002.sgm create mode 100644 src/test/data/reuters-21578/reut2-003.sgm create mode 100644 src/test/data/reuters-21578/reut2-004.sgm create mode 100644 src/test/data/reuters-21578/reut2-005.sgm create mode 100644 src/test/data/reuters-21578/reut2-006.sgm create mode 100644 src/test/data/reuters-21578/reut2-007.sgm create mode 100644 src/test/data/reuters-21578/reut2-008.sgm create mode 100644 src/test/data/reuters-21578/reut2-009.sgm create mode 100644 src/test/data/reuters-21578/reut2-010.sgm create mode 100644 src/test/data/reuters-21578/reut2-011.sgm create mode 100644 src/test/data/reuters-21578/reut2-012.sgm create mode 100644 src/test/data/reuters-21578/reut2-013.sgm create mode 100644 src/test/data/reuters-21578/reut2-014.sgm create mode 100644 src/test/data/reuters-21578/reut2-015.sgm create mode 100644 src/test/data/reuters-21578/reut2-016.sgm create mode 100644 src/test/data/reuters-21578/reut2-017.sgm create mode 100644 src/test/data/reuters-21578/reut2-018.sgm create mode 100644 src/test/data/reuters-21578/reut2-019.sgm create mode 100644 src/test/data/reuters-21578/reut2-020.sgm create mode 100644 src/test/data/reuters-21578/reut2-021.sgm create mode 100644 src/test/data/utf8text/arabic_utf8.txt create mode 100644 src/test/data/utf8text/chinese_utf8.txt create mode 100644 src/test/data/utf8text/czech_utf8.txt create mode 100644 src/test/data/utf8text/english_utf8.txt create mode 100644 src/test/data/utf8text/french_utf8.txt create mode 100644 src/test/data/utf8text/german_utf8.txt create mode 100644 src/test/data/utf8text/greek_utf8.txt create mode 100644 src/test/data/utf8text/hebrew_utf8.txt create mode 100644 src/test/data/utf8text/japanese_utf8.txt create mode 100644 src/test/data/utf8text/korean_utf8.txt create mode 100644 src/test/data/utf8text/polish_utf8.txt create mode 100644 src/test/data/utf8text/russian_utf8.txt create mode 100644 src/test/debug/TestError.cpp create mode 100644 src/test/document/TestDateTools.cpp create mode 100644 src/test/document/TestDocument.cpp create mode 100644 src/test/document/TestField.cpp create mode 100644 src/test/document/TestNumberTools.cpp create mode 100644 src/test/index/IndexWriter4Test.cpp create mode 100644 src/test/index/IndexWriter4Test.h create mode 100644 src/test/index/TestAddIndexesNoOptimize.cpp create mode 100644 src/test/index/TestHighFreqTerms.cpp create mode 100644 src/test/index/TestIndexModifier.cpp create mode 100644 src/test/index/TestIndexReader.cpp create mode 100644 src/test/index/TestIndexWriter.cpp create mode 100644 src/test/index/TestReuters.cpp create mode 100644 src/test/index/TestTermVectorsReader.cpp create mode 100644 src/test/index/TestThreading.cpp create mode 100644 src/test/index/TestUtf8.cpp create mode 100644 src/test/nanobench.h create mode 100644 src/test/queryParser/TestMultiFieldQueryParser.cpp create mode 100644 src/test/queryParser/TestQueryParser.cpp create mode 100644 src/test/search/BaseTestRangeFilter.cpp create mode 100644 src/test/search/BaseTestRangeFilter.h create mode 100644 src/test/search/CheckHits.cpp create mode 100644 src/test/search/CheckHits.h create mode 100644 src/test/search/MockHitCollector.h create mode 100644 src/test/search/MockScorer.h create mode 100644 src/test/search/QueryUtils.cpp create mode 100644 src/test/search/QueryUtils.h create mode 100644 src/test/search/TestBoolean.cpp create mode 100644 src/test/search/TestConstantScoreRangeQuery.cpp create mode 100644 src/test/search/TestDateFilter.cpp create mode 100644 src/test/search/TestExplanations.cpp create mode 100644 src/test/search/TestExplanations.h create mode 100644 src/test/search/TestExtractTerms.cpp create mode 100644 src/test/search/TestForDuplicates.cpp create mode 100644 src/test/search/TestIndexSearcher.cpp create mode 100644 src/test/search/TestQueries.cpp create mode 100644 src/test/search/TestRangeFilter.cpp create mode 100644 src/test/search/TestSearch.cpp create mode 100644 src/test/search/TestSort.cpp create mode 100644 src/test/search/TestTermVector.cpp create mode 100644 src/test/search/TestWildcard.cpp create mode 100644 src/test/search/spans/TestBasics.cpp create mode 100644 src/test/search/spans/TestBasics.h create mode 100644 src/test/search/spans/TestNearSpansOrdered.cpp create mode 100644 src/test/search/spans/TestNearSpansOrdered.h create mode 100644 src/test/search/spans/TestSpanExplanations.cpp create mode 100644 src/test/search/spans/TestSpanExplanations.h create mode 100644 src/test/search/spans/TestSpanExplanationsOfNonMatches.cpp create mode 100644 src/test/search/spans/TestSpanExplanationsOfNonMatches.h create mode 100644 src/test/search/spans/TestSpanQueries.cpp create mode 100644 src/test/search/spans/TestSpans.cpp create mode 100644 src/test/search/spans/TestSpans.h create mode 100644 src/test/search/spans/TestSpansAdvanced.cpp create mode 100644 src/test/search/spans/TestSpansAdvanced.h create mode 100644 src/test/search/spans/TestSpansAdvanced2.cpp create mode 100644 src/test/search/spans/TestSpansAdvanced2.h create mode 100644 src/test/store/MockRAMDirectory.cpp create mode 100644 src/test/store/MockRAMDirectory.h create mode 100644 src/test/store/TestRAMDirectory.cpp create mode 100644 src/test/store/TestStore.cpp create mode 100644 src/test/test.h create mode 100644 src/test/testall.cpp create mode 100644 src/test/tests.cpp create mode 100644 src/test/util/English.cpp create mode 100644 src/test/util/TestBKD.cpp create mode 100644 src/test/util/TestBKD.h create mode 100644 src/test/util/TestBitSet.cpp create mode 100644 src/test/util/TestMSBRadixSorter.cpp create mode 100644 src/test/util/TestMSBRadixSorter.h create mode 100644 src/test/util/TestPriorityQueue.cpp create mode 100644 src/test/util/TestStringBuffer.cpp create mode 100644 src/tokenizer/CMakeLists.txt create mode 100644 src/tokenizer/etc/unigram.txt create mode 100644 src/tokenizer/etc/unigram.txt.uni create mode 100644 src/tokenizer/etc/wwsearch_mmseg.ini create mode 100644 src/tokenizer/etc/wwsearch_mmseg_uni.lib create mode 100644 src/tokenizer/include/ICorpusReader.h create mode 100644 src/tokenizer/include/SegmentPkg.h create mode 100644 src/tokenizer/include/Segmenter.h create mode 100644 src/tokenizer/include/SegmenterManager.h create mode 100644 src/tokenizer/include/Singleton.h create mode 100644 src/tokenizer/include/StringTokenizer.h create mode 100644 src/tokenizer/include/SynonymsDict.h create mode 100644 src/tokenizer/include/ThesaurusDict.h create mode 100644 src/tokenizer/include/UnigramCorpusReader.h create mode 100644 src/tokenizer/include/UnigramDict.h create mode 100644 src/tokenizer/include/UnigramRecord.h create mode 100644 src/tokenizer/include/Utf8_16.h create mode 100644 src/tokenizer/include/bsd_getopt.h create mode 100644 src/tokenizer/include/config.h create mode 100644 src/tokenizer/include/csr.h create mode 100644 src/tokenizer/include/csr_assert.h create mode 100644 src/tokenizer/include/csr_mmap.h create mode 100644 src/tokenizer/include/csr_pool.h create mode 100644 src/tokenizer/include/csr_typedefs.h create mode 100644 src/tokenizer/include/csr_utils.h create mode 100644 src/tokenizer/include/darts.h create mode 100644 src/tokenizer/include/dictionary.h create mode 100644 src/tokenizer/include/freelist.h create mode 100644 src/tokenizer/include/iniparser.h create mode 100644 src/tokenizer/include/mmseg_wrapper.h create mode 100644 src/tokenizer/include/mmthunk.h create mode 100644 src/tokenizer/include/os.h create mode 100644 src/tokenizer/include/scoped_ptr.h create mode 100644 src/tokenizer/include/tolowercase.h create mode 100644 src/tokenizer/src/SegmentPkg.cpp create mode 100644 src/tokenizer/src/SegmenterManager.cpp create mode 100644 src/tokenizer/src/StringTokenizer.cpp create mode 100644 src/tokenizer/src/SynonymsDict.cpp create mode 100644 src/tokenizer/src/ThesaurusDict.cpp create mode 100644 src/tokenizer/src/UnigramCorpusReader.cpp create mode 100644 src/tokenizer/src/UnigramDict.cpp create mode 100644 src/tokenizer/src/UnigramRecord.cpp create mode 100644 src/tokenizer/src/Utf8_16.cpp create mode 100644 src/tokenizer/src/assert.cpp create mode 100644 src/tokenizer/src/bsd_getopt.cpp create mode 100644 src/tokenizer/src/csr_mmap.cpp create mode 100644 src/tokenizer/src/csr_utils.cpp create mode 100644 src/tokenizer/src/dictionary.cpp create mode 100644 src/tokenizer/src/iniparser.cpp create mode 100644 src/tokenizer/src/mmseg_wrapper.cpp create mode 100644 src/tokenizer/src/mmthunk.cpp create mode 100644 src/tokenizer/src/segmenter.cpp diff --git a/APACHE.license b/APACHE.license new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/APACHE.license @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000000..a9ed2f98ce8 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,23 @@ +As with most development projects, contributions come from many people and in +many forms. The CLucene project would like to thank it's many contributors. +Omissions are merely accidental, please e-mail ustramooner@users.sourceforge.net +if you have been left out or a contribution is not mentioned. + +CLucene was originally ported to C++ by Ben van Klinken (ustramooner@users.sourceforge.net) +from Doug Cutting's popular java search engine, Lucene (see http://lucene.apache.org). + +Here is a list of contributors. Please send me an email at ustramooner@users.sourceforge.net +if I have left you out. + +Doug Cutting cutting@users.sourceforge.net +John Wheeler j_wheeler@users.sourceforge.net +Robert G. Ristroph rgristroph@users.sourceforge.net +David Rushby woodsplitter@users.sourceforge.net +Jimmy Pritts jpritts@sdf.lonestar.org +Peter Edwards peter@dragonstaff.co.uk +Jorge Sabater Redondo jsabater@elderecho.com +Daniel Glassey danglassey@ntlworld.com +Peter Gladkikh batyi@mail.ru +Pedja amigo@max3d.com +Peter Hodges hodges.peter@gmail.com +Itamar Syn-Hershko synhershko@users.sourceforge.net diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..2b2104e82ec --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,218 @@ +PROJECT (clucene) + +#Rules for version: +#MAJOR and MINOR versions are purely political (tracks JLucene compatibility) +#REVISION version MUST be revised if the headers or compatibility change +#PATCH should be 0 unless a patch is made that doesn't affect the public signature (i.e. clients don't need to re-compile). +SET(CLUCENE_VERSION_MAJOR "2") +SET(CLUCENE_VERSION_MINOR "3") +SET(CLUCENE_VERSION_REVISION "3") +SET(CLUCENE_VERSION_PATCH "4") + +# SOVERSION information +#Must be incremented for releases if the api is not backwards compatible +SET(CLUCENE_SOVERSION "1") + +MATH(EXPR CLUCENE_INT_VERSION "(${CLUCENE_VERSION_MAJOR} * 1000000) + (${CLUCENE_VERSION_MINOR} * 10000) + (${CLUCENE_VERSION_REVISION} * 100) + (${CLUCENE_VERSION_PATCH} * 1)" ) +SET(CLUCENE_VERSION "${CLUCENE_VERSION_MAJOR}.${CLUCENE_VERSION_MINOR}.${CLUCENE_VERSION_REVISION}.${CLUCENE_VERSION_PATCH}") + +#CMake 2.6+ is recommended to an improved Boost module +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0 FATAL_ERROR) + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +if(COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) + cmake_policy(SET CMP0043 NEW) + cmake_policy(SET CMP0054 NEW) +endif(COMMAND cmake_policy) + +#set various platform specific global options +if(WIN32) + set(CMAKE_DEBUG_POSTFIX "d") +endif(WIN32) + + +# include specific modules +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +#remove FOR cmake,use shell script +include(cmake/TurboPFOR.cmake) + +#define options... + +include(cmake/CLuceneDocs.cmake) +Include (FindThreads) + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." + FORCE) +ELSE(NOT CMAKE_BUILD_TYPE) + MESSAGE( "Compiling as ${CMAKE_BUILD_TYPE}" ) +ENDIF(NOT CMAKE_BUILD_TYPE) + +OPTION(ENABLE_DEBUG + "enable debug support" + OFF) +OPTION(ENABLE_MMAP + "enable mmap support (experimental)" + OFF) +OPTION(DISABLE_MULTITHREADING + "disable multithreading - remove all locking code" + OFF) +OPTION(ENABLE_DMALLOC + "enable dmalloc memory leak checker" + OFF) +OPTION(ENABLE_ASCII_MODE + "enable ascii support" + OFF) + +SET(ENABLE_ANSI_MODE OFF) +IF(CMAKE_COMPILER_IS_GNUCXX) + SET(ENABLE_ANSI_MODE ON) + + #exceptions: + IF(MINGW OR CYGWIN) + SET(ENABLE_ANSI_MODE OFF) + ENDIF(MINGW OR CYGWIN) +ENDIF(CMAKE_COMPILER_IS_GNUCXX) + +SET(ENABLE_ANSI_MODE OFF) + +OPTION(ENABLE_ANSI_MODE + "compile with -ansi flag" + ${ENABLE_ANSI_MODE}) +OPTION(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS + "use internal character functions. required to run tests correctly" + ON) +OPTION(ENABLE_PACKAGING + "create build scripts for creating clucene packages" + OFF) +OPTION(BUILD_STATIC_LIBRARIES + "create targets for building static libraries" + ON) +OPTION(BUILD_CONTRIBS + "create targets for building the clucene-contribs" + OFF) +OPTION(BUILD_CONTRIBS_LIB + "create targets for building the clucene-contribs-lib" + OFF) +SET(LUCENE_SYS_INCLUDES "" CACHE PATH + "location for non-system independent files. defaults to CMAKE_INSTALL_PREFIX. see INSTALL documentation for further information." + ) +#install path options +SET(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) +SET(LIB_DESTINATION "lib${LIB_SUFFIX}") + + +SET ( ENABLE_COMPILE_TESTS_VALUE ON ) +IF ( MSVC_IDE ) + #this is annoying... + SET ( ENABLE_COMPILE_TESTS_VALUE OFF ) +ENDIF( MSVC_IDE ) + +OPTION(ENABLE_COMPILE_TESTS + "enable various projects that test alternative build switches" + ${ENABLE_COMPILE_TESTS_VALUE}) + +if (__COMPILER_CLANG) + SET(CXX_FLAGS_ASAN "${CXX_GCC_FLAGS} -O0 -fsanitize=address -DADDRESS_SANITIZER") + SET(CXX_FLAGS_LSAN "${CXX_GCC_FLAGS} -O0 -fsanitize=leak -DLEAK_SANITIZER") +else () + SET(CXX_FLAGS_ASAN "${CXX_GCC_FLAGS} -O0 -fsanitize=address -DADDRESS_SANITIZER -static-libasan") + SET(CXX_FLAGS_LSAN "${CXX_GCC_FLAGS} -O0 -fsanitize=leak -DLEAK_SANITIZER -static-liblsan") +endif () + +# Set compile flags based on the build type. +if ("${CMAKE_BUILD_TYPE}" STREQUAL "ASAN") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_ASAN}") +elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "LSAN") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS_LSAN}") +endif() + +if (USE_AVX2) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_AVX2") +endif() +if (__COMPILER_CLANG) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++11-narrowing") +else () + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing") +endif () + +#check flags... +INCLUDE (TestCXXAcceptsFlag) +IF ( CMAKE_COMPILER_IS_GNUCC ) + CHECK_CXX_ACCEPTS_FLAG(-pg GccFlagPg) + IF ( GccFlagPg ) + OPTION(ENABLE_GPROF + "turn on gprof profiling support" + OFF) + + IF ( ENABLE_GPROF ) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg") + SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -pg") + ENDIF ( ENABLE_GPROF ) + ENDIF ( GccFlagPg ) + + IF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) + ENDIF("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + + #IF( ENABLE_ANSI_MODE ) + # SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi") + #ENDIF ( ENABLE_ANSI_MODE ) +ENDIF(CMAKE_COMPILER_IS_GNUCC) + + +#Single output directory for building all executables and libraries. +SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Executable Output Directory" FORCE) +SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE PATH "Library Output Directory" FORCE) + +option(ENABLE_TESTS "Enable tests" OFF) +#add tests +ENABLE_TESTING() +ADD_TEST(SimpleTest ${EXECUTABLE_OUTPUT_PATH}/cl_test ) + +#use single output directory +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/shared ) +INCLUDE_DIRECTORIES( ${clucene_BINARY_DIR}/src/shared ) +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/core ) + +#set boost path. we need src/ext to be defined before this works... +include(cmake/CLuceneBoost.cmake) +GET_BOOST_INCLUDE_PATH(_CL_BOOST_INCLUDE_PATH) +INCLUDE_DIRECTORIES( ${_CL_BOOST_INCLUDE_PATH} ) + +#include the projects +ADD_SUBDIRECTORY (src/ext) +ADD_SUBDIRECTORY (src/shared) +ADD_SUBDIRECTORY (src/core) +ADD_SUBDIRECTORY (src/test) +ADD_SUBDIRECTORY (src/demo EXCLUDE_FROM_ALL) + +IF ( BUILD_CONTRIBS ) + ADD_SUBDIRECTORY (src/contribs EXCLUDE_FROM_ALL) + SET(BUILD_CONTRIBS_LIB 1) +ENDIF ( BUILD_CONTRIBS ) +IF ( BUILD_CONTRIBS_LIB ) + ADD_SUBDIRECTORY (src/contribs-lib EXCLUDE_FROM_ALL) +ENDIF ( BUILD_CONTRIBS_LIB ) + +#add uninstall command +CONFIGURE_FILE( + "${CMAKE_MODULE_PATH}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +#ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + +#this must go last... +IF (ENABLE_PACKAGING) + INCLUDE(CreateClucenePackages) +ENDIF ( ENABLE_PACKAGING) + +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + diff --git a/COPYING b/COPYING new file mode 100644 index 00000000000..13dc1663b65 --- /dev/null +++ b/COPYING @@ -0,0 +1,126 @@ +License + +The CLucene code is split into two sections for licensing reasons. The 'Core' +is strictly dual licensed Apache 2 and LGPL. The CLucene Contributions code +could not be licensed under Apache because of the subcomponents it uses. + +CLUCENE CORE: + +The CLucene Core Library uses a dual license strategy for the source code. +These licenses are the GNU Lesser General Public License (LGPL) and the Apache +License (Version 2.0). Users can choose the license they wish to distribute +their software under. This means that you do not need to abide by *both* +licenses, but rather than you can choose the license which most suits your +needs. + +For details of these licenses see APACHE.license and LGPL.license in the root +of the source distribution. + +Some components of CLucene Core use other licenses. See the CLUCENE CORE SUBCOMPONENTS +section for details. We understand that these licenses are compatible with LGPL and/or +Apache v2, but please consult with a lawyer to be certain of this. + +To rephrase the licensing and to make it perfectly clear: +CLucene is distributed under the GNU Lesser General Public License (LGPL) + *or* +the Apache License, Version 2.0 + +However, we are an open source project, and we encourage users to participate fully +in the free software community by contributing their code back to the project. +Dual licensing of the CLucene source code provides open and free access to the +technology both for the GPL community and for other developers or companies +that cannot use the GPL license. + +You can freely modify, extend, and improve the CLucene source code. The only +question is whether or not you must provide the source code and contribute +modifications to the community. The GNU and Apache licenses allow different +ranges of flexibility in this regard, but in the end, regardless of the license +used, we highly recommend that you submit any bugs, incompatibilities or +added features. + +Note that this same license does *not* apply to the CLucene Contributions +package. You should read the COPYING file in that directory or package for +more information. + + +CLUCENE CORE SUBCOMPONENTS: + +CLucene includes a number of subcomponents with separate copyright +notices and license terms. Your use of the source code for the +these subcomponents is subject to the terms and conditions of the +following licenses. + +For the src\CLucene\util\MD5Digester.cpp component: +/* + * This is work is derived from material Copyright RSA Data Security, Inc. + * + * The RSA copyright statement and Licence for that original material is + * included below. This is followed by the Apache copyright statement and + * licence for the modifications made to that material. + */ +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + */ + + + +the cmake/MacroCheckGccVisibility.cmake and MacroEnsureVersion.cmake components: +# +# Copyright (c) 2006, Alexander Neundorf +# Copyright (c) 2006, Laurent Montel, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +the src/core/util/Compress.cpp component: +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly jloup@gzip.org + Mark Adler madler@alumni.caltech.edu + +*/ + + + +CLUCENE CONTRIBUTIONS CODE: + +PorterStemmer code: couldn't find license. This component is deprecated and will be removed very soon. + +Snowball code: needs to be researched. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000000..137d92d0c35 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,17 @@ +Removed jstreams namespace. Sorry, I couldn't think of a way to nicely deprecate jstreams. + +version 0.9.23: +Changes: +* Static object fields have been changed to method accessors (SortField::FIELDDOC now chould be accessed as SortField::FIELDDOC(), for example). Classes changed: FieldCache, ScoreDocComparator, + This was necessary for creating static libraries work on certain platforms. +* Folders were reorganised, this seems like a good time to do it +* Some deprecated functions were removed. +* moved platform configuration type code and utility code into 'shared' project. This enables tests to be built with a shared library on windows +* Moved moved of the platform specific logic into cmake in order to reduce #ifdefs in code (i love cmake!) +* added contributions code into the trunk. this will hopefully mean more exposure to the contributions. need to make clear about the licensing still, though. +* Deletor::Array was renamed to Deletor::vArray. +* re-worked the install location for system-dependent files (clucene-config.h). this was a confusing issue, and i think it's better to stick to the standards rather than push the more compatible (in my opinion) way of doing things. this one has been getting so many complaints from downstream. however, LUCENE_SYS_INCLUDES is available to install the clucene-config.h type files into the library directory (or any other place). + +Here is a summary of changes that you'll need to look at for this release: +* Action deprecated features. Some features that were deprecated for a long time have now been finally removed. +* fix things that may affect you, such as the LUCENE_SYS_INCLUDES change, and the reorganisation of code (install locations are still the same though). Also autotools removals may affect your work, depending on how you use clucene. diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000000..71f33297bb1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,265 @@ +* There are packages available for most linux distributions through the usual channels. +* The Clucene Sourceforge website also has some distributions available. + +Also in this document is information how to build from source, troubleshooting, +performance, and how to create a new distribution. + + +Building from source: +-------------------- + +Dependencies: +* CMake version 2.4.2 or later. +* A functioning and fairly new C++ compiler. We test mostly on GCC and Visual Studio 6+. +Anything other than that may not work. +* Something to unzip/untar the source code. + +Build instructions: +1.) Download the latest sourcecode from http://www.sourceforge.net/projects/clucene + [Choose stable if you want the 'time tested' version of code. However, often + the unstable version will suite your needs more since it is newer and has had + more work put into it. The decision is up to you.] +2.) Unpack the tarball/zip/bzip/whatever +3.) Open a command prompt, terminal window, or cygwin session. +4.) Change directory into the root of the sourcecode (from now on referred to as ) +# cd +5.) Create and change directory into an 'out-of-source' directory for your build. + [This is by far the easiest way to build, it has the benefit of being able to + create different types of builds in the same source-tree.] +# mkdir /build-name +# cd /build-name +6.) Configure using cmake. This can be done many different ways, but the basic syntax is +# cmake [-G "Script name"] .. + [Where "Script name" is the name of the scripts to build (e.g. Visual Studio 8 2005). + A list of supported build scripts can be found by] +# cmake --help +7.) You can configure several options such as the build type, debugging information, + mmap support, etc, by using the CMake GUI or by calling +# ccmake .. + Make sure you call configure again if you make any changes. +8.) Start the build. This depends on which build script you specified, but it would be something like +# make +or +# nmake + Or open the solution files with your IDE. + + [You can also specify to just build a certain target (such as cl_test, cl_demo, + clucene-core (shared library), clucene-core-static (static library).] +9.) The binary files will be available in build-name/bin +10.)Test the code. (After building the tests - this is done by default, or by calling make cl_test) +# ctest -V +11.)At this point you can install the library: +# make install + [There are options to do this from the IDE, but I find it easier to create a + distribution (see instructions below) and install that instead.] +or +# make cl_demo + [This creates the demo application, which demonstrates a simple text indexing and searching]. +or + Adjust build values using ccmake or the Cmake GUI and rebuild. + +12.)Now you can develop your own code. This is beyond the scope of this document. + Read the README for information about documentation or to get help on the mailinglist. + +Other platforms: +---------------- +Some platforms require specific actions to get cmake working. Here are some general tips: + +Solaris: +I had problems when using the standard stl library. Using the -stlport4 switch worked. Had +to specify compiler from the command line: cmake -DCXX_COMPILER=xxx -stlport4 + +Building Performance +-------------------- +Use of ccache will speed up build times a lot. I found it easiest to add the /usr/lib/ccache directory to the beginning of your paths. This works for most common compilers. + +PATH=/usr/lib/ccache:$PATH + +Note: you must do this BEFORE you configure the path, since you cannot change the compiler path after it is configured. + +Installing: +----------- +CLucene is installed in CMAKE_INSTALL_PREFIX by default. + +CLucene used to put config headers next to the library. this was done +because these headers are generated and are relevant to the library. +CMAKE_INSTALL_PREFIX was for system-independent files. the idea is that +you could have several versions of the library installed (ascii version, +ucs2 version, multithread, etc) and have only one set of headers. +in version 0.9.24+ we allow this feature, but you have to use +LUCENE_SYS_INCLUDES to specify where to install these files. + +Troubleshooting: +---------------- + +'Too many open files' +Some platforms don't provide enough file handles to run CLucene properly. +To solve this, increase the open file limit: + +On Solaris: +ulimit -n 1024 +set rlim_fd_cur=1024 + +GDB - GNU debugging tool (linux only) +------------------------ +If you get an error, try doing this. More information on GDB can be found on the internet + +#gdb bin/cl_test +# gdb> run +when gdb shows a crash run +# gdb> bt +a backtrace will be printed. This may help to solve any problems. + +Code layout +-------------- +File locations: +* clucene-config.h is required and is distributed next to the library, so that multiple libraries can exist on the + same machine, but use the same header files. +* _HeaderFile.h files are private, and are not to be used or distributed by anything besides the clucene-core library. +* _clucene-config.h should NOT be used, it is also internal +* HeaderFile.h are public and are distributed and the classes within should be exported using CLUCENE_EXPORT. +* The exception to the internal/public conventions is if you use the static library. In this case the internal + symbols will be available (this is the way the tests program tests internal code). However this is not recommended. + +Memory management +------------------ +Memory in CLucene has been a bit of a difficult thing to manage because of the +unclear specification about who owns what memory. This was mostly a result of +CLucene's java-esque coding style resulting from porting from java to c++ without +too much re-writing of the API. However, CLucene is slowly improving +in this respect and we try and follow these development and coding rules (though +we dont guarantee that they are all met at this stage): + +1. Whenever possible the caller must create the object that is being filled. For example: +IndexReader->getDocument(id, document); +As opposed to the old method of document = IndexReader->getDocument(id); + +2. Clone always returns a new object that must be cleaned up manually. + +Questions: +1. What should be the convention for an object taking ownership of memory? + Some documenting is available on this, but not much + +Working with valgrind +---------------------- +Valgrind reports memory leaks and memory problems. Tests should always pass +valgrind before being passed. + +#valgrind --leak-check=full + +Memory leak tracking with dmalloc +--------------------------------- +dmalloc (http://dmalloc.com/) is also a nice tool for finding memory leaks. +To enable, set the ENABLE_DMALLOC flag to ON in cmake. You will of course +have to have the dmalloc lib installed for this to work. + +The cl_test file will by default print a low number of errors and leaks into +the dmalloc.log.txt file (however, this has a tendency to print false positives). +You can override this by setting your environment variable DMALLOC_OPTIONS. +See http://dmalloc.com/ or dmalloc --usage for more information on how to use dmalloc + +For example: +# DMALLOC_OPTIONS=medium,log=dmalloc.log.txt +# export DMALLOC_OPTIONS + +UPDATE: when i upgrade my machine to Ubuntu 9.04, dmalloc stopped working (caused +clucene to crash). + +Performance with callgrind +-------------------------- +Really simple + +valgrind --tool=callgrind +this will create a file like callgrind.out.12345. you can open this with kcachegrind or some +tool like that. + + +Performance with gprof +---------------------- +Note: I recommend callgrind, it works much better. + +Compile with gprof turned on (ENABLE_GPROF in cmake gui or using ccmake). +I've found (at least on windows cygwin) that gprof wasn't working over +dll boundaries, running the cl_test-pedantic monolithic build worked better. + +This is typically what I use to produce some meaningful output after a -pg +compiled application has exited: +# gprof bin/cl_test-pedantic.exe gmon.out >gprof.txt + +Code coverage with gcov +----------------------- +To create a code coverage report of the test, you can use gcov. Here are the +steps I followed to create a nice html report. You'll need the lcov package +installed to generate html. Also, I recommend using an out-of-source build +directory as there are lots of files that will be generated. + +NOTE: you must have lcov installed for this to work + +* It is normally recommended to compile with no optimisations, so change CMAKE_BUILD_TYPE +to Debug. + +* I have created a cl_test-gcov target which contains the necessary gcc switches +already. So all you need to do is +# make test-gcov + +If everything goes well, there will be a directory called code-coverage containing the report. + +If you want to do this process manually, then: +# lcov --directory ./src/test/CMakeFiles/cl_test-gcov.dir/__/core/CLucene -c -o clucene-coverage.info +# lcov --remove clucene-coverage.info "/usr/*" > clucene-coverage.clean +# genhtml -o clucene-coverage clucene-coverage.clean + +If both those commands pass, then there will be a clucene coverage report in the +clucene-coverage directory. + +Benchmarks +---------- +Very little benchmarking has been done on clucene. Andi Vajda posted some +limited statistics on the clucene list a while ago with the following results. + +There are 250 HTML files under $JAVA_HOME/docs/api/java/util for about +6108kb of HTML text. +org.apache.lucene.demo.IndexFiles with java and gcj: +on mac os x 10.3.1 (panther) powerbook g4 1ghz 1gb: + . running with java 1.4.1_01-99 : 20379 ms + . running with gcj 3.3.2 -O2 : 17842 ms + . running clucene 0.8.9's demo : 9930 ms + +I recently did some more tests and came up with these rough tests: +663mb (797 files) of Guttenberg texts +on a Pentium 4 running Windows XP with 1 GB of RAM. Indexing max 100,000 fields +- Jlucene: 646453ms. peak mem usage ~72mb, avg ~14mb ram +- Clucene: 232141. peak mem usage ~60, avg ~4mb ram + +Searching indexing using 10,000 single word queries +- Jlucene: ~60078ms and used ~13mb ram +- Clucene: ~48359ms and used ~4.2mb ram + +Distribution +------------ +CPack is used for creating distributions. +* Create a out-of-source build as per usual +* Make sure the version number is correct (see /CMakeList.txt, right at the top of the file) +* Make sure you are compiling in the correct release mode (check ccmake or the cmake gui) +* Make sure you enable ENABLE_PACKAGING (check ccmake or the cmake gui) +* Next, check that the package is compliant using several tests (must be done from a linux terminal, or cygwin): +# cd /build-name +# ../dist-check.sh +* Make sure the source directory is clean. Make sure there are no unknown svn files: +# svn stat .. +* Run the tests to make sure that the code is ok (documented above) +* If all tests pass, then run +# make package +for the binary package (and header files). This will only create a tar.gz package. +and/or +# make package_source +for the source package. This will create a ZIP on windows, and tar.bz2 and tar.gz packages on other platforms. + +There are also options for create RPM, Cygwin, NSIS, Debian packages, etc. It depends on your version of CPack. +Call +# cpack --help +to get a list of generators. + +Then create a special package by calling +# cpack -G CPackConfig.cmake + diff --git a/LGPL.license b/LGPL.license new file mode 100644 index 00000000000..422c76072f5 --- /dev/null +++ b/LGPL.license @@ -0,0 +1,475 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + +------------------------------------------------------------------------------- + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + +------------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +------------------------------------------------------------------------------- + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + +------------------------------------------------------------------------------- + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +------------------------------------------------------------------------------- + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +------------------------------------------------------------------------------- + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + +------------------------------------------------------------------------------- + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +------------------------------------------------------------------------------- + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/NEWS b/NEWS new file mode 100644 index 00000000000..e69de29bb2d diff --git a/README b/README new file mode 100644 index 00000000000..9b411e7ae0e --- /dev/null +++ b/README @@ -0,0 +1,63 @@ +CLucene README +============== + +------------------------------------------------------ +CLucene is a C++ port of Lucene. +It is a high-performance, full-featured text search +engine written in C++. CLucene is faster than lucene +as it is written in C++. +------------------------------------------------------ + +CLucene has contributions from many, see AUTHORS + +CLucene is distributed under the GNU Lesser General Public License (LGPL) + *or* +the Apache License, Version 2.0 +See the LGPL.license and APACHE.license for the respective license information. +Read COPYING for more about the license. + + +Installation +------------ +Read the INSTALL file + + +Mailing List +------------ +Questions and discussion should be directed to the CLucene mailing list + at clucene-developers@lists.sourceforge.net +Find subscription instructions at + http://lists.sourceforge.net/lists/listinfo/clucene-developers +Suggestions and bug reports can be made on our bug tracking database + (http://sourceforge.net/tracker/?group_id=80013&atid=558446) + + +The latest version +------------------ +Details of the latest version can be found on the CLucene sourceforge project +web site: http://www.sourceforge.net/projects/clucene + + +Documentation +------------- +You can build your own documentation by running 'make DoxygenDoc' from your +'out-of-source' cmake-configured build directory. +CLucene is a very close port of Java Lucene, so you can also try looking at the +Java Docs on http://lucene.apache.org/java/ +There is an online version (which won't be as up to date as if you build your +own) at http://clucene.sourceforge.net/doc/html/ + + +Acknowledgments +---------------- +The Apache Lucene project is the basis for this software, so the biggest +acknoledgment goes to that project. + +We wish to acknowledge the following copyrighted works that +make up portions of the CLucene software: + +This software contains code derived from the RSA Data Security +Inc. MD5 Message-Digest Algorithm. + +CLucene relies heavily on the use of cmake to provide a stable build environment. + diff --git a/README.PACKAGE b/README.PACKAGE new file mode 100644 index 00000000000..e33b1d4036b --- /dev/null +++ b/README.PACKAGE @@ -0,0 +1,11 @@ +CLucene is a C++ port of the popular Apache Lucene search engine +(http://lucene.apache.org/java). It is released under LGPL or the Apache +License. + +CLucene aims to be a high-speed alternative to Java Lucene, its API is very +similar to that of the Java version. CLucene has recently been brought up to +date with Lucene 2.3.2. It contains most of the same functionality as the +Java version. + +This package contains the files necessary for running applications that +use the libclucene library. diff --git a/REQUESTS b/REQUESTS new file mode 100644 index 00000000000..762fce5b974 --- /dev/null +++ b/REQUESTS @@ -0,0 +1,4 @@ +The todo list has been moved to the tracker at +http://sourceforge.net/tracker/?func=browse&group_id=80013&atid=558449 + +You need to be logged into sourceforge to view this list. diff --git a/cmake/CLuceneBoost.cmake b/cmake/CLuceneBoost.cmake new file mode 100644 index 00000000000..f6e2558911b --- /dev/null +++ b/cmake/CLuceneBoost.cmake @@ -0,0 +1,23 @@ +#Locate Boost libs. Windows users: make sure BOOST_ROOT and BOOST_PATH are set correctly on your environment. +#See the site FAQ for more details. + +MACRO (GET_BOOST_INCLUDE_PATH path) + #todo: allow this to fall back on a local distributed copy, so user doesn't have to d/l Boost seperately + SET(Boost_USE_MULTITHREAD ON) + message(STATUS "old Boost_INCLUDE_DIR : ${Boost_INCLUDE_DIR}") + FIND_PACKAGE( Boost ) + + #todo: limit Boost version? + #todo: use COMPONENTS threads to locate boost_threads without breaking the current support + IF(Boost_FOUND) + IF (NOT _boost_IN_CACHE) + MESSAGE( "Boost found" ) + message(STATUS "Boost_INCLUDE_DIR : ${Boost_INCLUDE_DIR}") + ENDIF (NOT _boost_IN_CACHE) + SET(${path} ${Boost_INCLUDE_DIRS} ) + ELSE() + MESSAGE( "Boost not found, using local: ${clucene_SOURCE_DIR}/src/ext" ) + SET(${path} ${clucene_SOURCE_DIR}/src/ext ) + ENDIF() +ENDMACRO (GET_BOOST_INCLUDE_PATH path) + diff --git a/cmake/CLuceneDocs.cmake b/cmake/CLuceneDocs.cmake new file mode 100644 index 00000000000..d46eed99035 --- /dev/null +++ b/cmake/CLuceneDocs.cmake @@ -0,0 +1,151 @@ +# - CLuceneDocs.cmake +# This file provides support for building the CLucene Documentation. +# To build the documention, you will have to enable it +# and then do the equivalent of "make doc". +OPTION(ENABLE_CLDOCS "Build the clucene documentation." OFF) + +MACRO(SET_YESNO) + FOREACH(param ${ARGV}) + IF ( ${param} ) + SET(${param} "YES") + ELSE ( ${param} ) + SET(${param} "NO") + ENDIF ( ${param} ) + ENDFOREACH(param) +ENDMACRO(SET_YESNO) +MACRO(SET_BLANK) + FOREACH(param ${ARGV}) + IF ( NOT ${param} ) + SET(${param} "") + ENDIF ( NOT ${param} ) + ENDFOREACH(param) +ENDMACRO(SET_BLANK) + +IF (ENABLE_CLDOCS) + OPTION(CLDOCS_HTML_HELP + "Doxygen should compile HTML into a Help file (CHM)." NO) + + OPTION(CLDOCS_HTML + "Doxygen should build HTML documentation." YES) + OPTION(CLDOCS_XML + "Doxygen should build XML documentation." NO) + OPTION(CLDOCS_RTF + "Doxygen should build RTF documentation." NO) + OPTION(CLDOCS_MAN + "Doxygen should build man documentation." NO) + OPTION(CLDOCS_TAGFILE + "Doxygen should build a tagfile." NO) + + OPTION(CLDOCS_LATEX + "Doxygen should build Latex documentation." NO ) + + MARK_AS_ADVANCED( + CLDOCS_HTML_HELP + CLDOCS_LATEX + CLDOCS_XML + CLDOCS_HTML + CLDOCS_RTF + CLDOCS_MAN + CLDOCS_TAGFILE + ) + + # + # Check for the tools + # + FIND_PACKAGE(Doxygen) + + IF ( DOXYGEN_FOUND ) + # This creates a new target to build documentation. + # It runs ${DOXYGEN_EXECUTABLE} which is the full path and executable to + # Doxygen on your system, set by the FindDoxygen.cmake module + # (called by FindDocumentation.cmake). + # It runs the final generated Doxyfile against it. + # The DOT_PATH is substituted into the Doxyfile. + ADD_CUSTOM_TARGET(doc + ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/doc/doxyfile + ) + + IF ( CLDOCS_HTML_HELP ) + IF ( NOT CLDOCS_HTML ) + MESSAGE ( FATAL_ERROR "CLDOCS_HTML is required to buidl CLDOCS_HTML_HELP" ) + ENDIF ( NOT CLDOCS_HTML ) + FIND_PACKAGE(HTMLHelp) + IF ( NOT HTML_HELP_COMPILER ) + MESSAGE(FATAL_ERROR "HTML Help compiler not found, turn CLDOCS_HTML_HELP off to proceed") + ENDIF ( NOT HTML_HELP_COMPILER ) + + #make cygwin work with hhc... + IF ( CYGWIN ) + EXECUTE_PROCESS ( COMMAND cygpath "${HTML_HELP_COMPILER}" + OUTPUT_VARIABLE HTML_HELP_COMPILER_EX ) + STRING ( REPLACE "\n" "" HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER_EX} ) + STRING ( REPLACE "\r" "" HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER_EX} ) + SET ( HTML_HELP_COMPILER_EX "\"${HTML_HELP_COMPILER_EX}\"" ) + ELSE ( CYGWIN ) + SET ( HTML_HELP_COMPILER_EX ${HTML_HELP_COMPILER} ) + ENDIF ( CYGWIN ) + ENDIF ( CLDOCS_HTML_HELP ) + + IF ( CLDOCS_LATEX ) + FIND_PACKAGE(LATEX) + IF ( NOT LATEX_COMPILER ) + MESSAGE(FATAL_ERROR "Latex compiler not found, turn CLDOCS_LATEX off to proceed") + ENDIF ( NOT LATEX_COMPILER ) + ENDIF ( CLDOCS_LATEX ) + + FIND_PACKAGE(Perl) + + IF ( DOXYGEN_DOT_EXECUTABLE ) + SET ( HAVE_DOT "YES" ) + ELSE ( DOXYGEN_DOT_EXECUTABLE ) + SET ( HAVE_DOT "NO" ) + ENDIF ( DOXYGEN_DOT_EXECUTABLE ) + + #doxygen expects YES/NO parameters + SET_YESNO( + CLDOCS_HTML_HELP + CLDOCS_LATEX + CLDOCS_XML + CLDOCS_HTML + CLDOCS_RTF + CLDOCS_MAN + ) + #empty out paths if not found + SET_BLANK( + PERL_EXECUTABLE + DOXYGEN_DOT_EXECUTABLE + HTML_HELP_COMPILER + LATEX_COMPILER + ) + + IF ( CLDOCS_TAGFILE ) + SET ( CLDOCS_TAGFILE_LOCATION "${PROJECT_BINARY_DIR}/doc/tag/clucene.tag" ) + ENDIF ( CLDOCS_TAGFILE ) + + # This processes our Doxyfile.cmake and substitutes paths to generate a final Doxyfile + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/Doxyfile.cmake ${PROJECT_BINARY_DIR}/doc/doxyfile ) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpheader.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpheader.htm ) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/helpfooter.htm.cmake ${PROJECT_BINARY_DIR}/doc/helpfooter.htm ) + CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/doxygen.css.cmake ${PROJECT_BINARY_DIR}/doc/html/doxygen.css ) + + #create a target for tar.gz html help + FIND_PACKAGE(UnixCommands) + IF ( TAR AND GZIP ) + ADD_CUSTOM_TARGET(doc-tarz + COMMAND "${TAR}" "-cf" "doc/clucene-core-doc.tar" "${PROJECT_BINARY_DIR}/doc/html/" + COMMAND "${GZIP}" "doc/clucene-core-doc.tar" + #DEPENDS doc-doxygen + ) + ENDIF ( TAR AND GZIP ) + + #install man if it was built + IF ( CLDOCS_MAN ) + INSTALL(DIRECTORY ${PROJECT_BINARY_DIR}/doc/man/ DESTINATION man) + ENDIF ( CLDOCS_MAN ) + + ELSE ( DOXYGEN_FOUND ) + MESSAGE(FATAL_ERROR "Doxygen not found, turn ENABLE_CLDOCS off to proceed") + ENDIF ( DOXYGEN_FOUND ) + + +ENDIF (ENABLE_CLDOCS) diff --git a/cmake/CreateClucenePackages.cmake b/cmake/CreateClucenePackages.cmake new file mode 100644 index 00000000000..b9de7b1676c --- /dev/null +++ b/cmake/CreateClucenePackages.cmake @@ -0,0 +1,91 @@ +#Creates all the relevant packages + +#Rules for version: +#MAJOR and MINOR versions are purely political +#REVISION version MUST be revised if the headers or compatibility change +#PATCH should be 0 unless a patch is made that doesn't affect the public signature (i.e. clients don't need to re-compile). + +SET(CPACK_PACKAGE_VERSION_MAJOR ${CLUCENE_VERSION_MAJOR}) +SET(CPACK_PACKAGE_VERSION_MINOR ${CLUCENE_VERSION_MINOR}) +SET(CPACK_PACKAGE_VERSION_REVISION ${CLUCENE_VERSION_REVISION}) +SET(CPACK_PACKAGE_VERSION_PATCH ${CLUCENE_VERSION_MAJOR}) + +SET(CPACK_PACKAGE_VERSION ${CLUCENE_VERSION}) +SET(CPACK_PACKAGE_SOVERSION ${CLUCENE_SOVERSION}) + +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "library for full-featured text search engine (runtime)") +SET(CPACK_PACKAGE_VENDOR "Ben van Klinken") +SET(CPACK_PACKAGE_CONTACT "clucene-developers@lists.sourceforge.net") +SET(CPACK_PACKAGE_NAME "libclucene1") + +SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "CLucene - a C++ search engine, ported from the popular Apache Lucene") + +SET(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") +SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") +SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/README.PACKAGE") + +#so, what are we going to install? +SET(CPACK_INSTALL_CMAKE_PROJECTS + "${CMAKE_BINARY_DIR};clucene-core;ALL;/" + "${CMAKE_BINARY_DIR};clucene-shared;ALL;/") +SET(CPACK_COMPONENTS_ALL development runtime) +SET(CPACK_GENERATOR "TGZ") +SET(CPACK_PACKAGE_FILE_NAME "clucene-core-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}") + +IF(WIN32 AND NOT UNIX) + SET(CPACK_SOURCE_GENERATOR "ZIP") +ELSE(WIN32 AND NOT UNIX) + SET(CPACK_SOURCE_GENERATOR "TBZ2;TGZ") +ENDIF(WIN32 AND NOT UNIX) +SET(CPACK_SOURCE_PACKAGE_FILE_NAME "clucene-core-${CPACK_PACKAGE_VERSION}-Source") + +#specific packaging requirements: +SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.4), libgcc1 (>= 1:4.1.1-21), libstdc++6 (>= 4.1.1-21), zlib1g") +SET(CPACK_DEBIAN_PACKAGE_SECTION "libs") +SET(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0") +SET(CPACK_RPM_PACKAGE_GROUP "libs") +SET(CPACK_RPM_PACKAGE_REQUIRES "libz") + +#don't include the current binary dir. +get_filename_component(clucene_BINARY_DIR_name ${clucene_BINARY_DIR} NAME) +SET(CPACK_SOURCE_IGNORE_FILES + "/\\\\.svn/" + "/\\\\.git/" + "\\\\.swp$" + "\\\\.#;/#" + ".*~" + ".*\\\\.tmp" + ".*\\\\.save" + "/${clucene_BINARY_DIR_name}/" +) + +IF(WIN32 AND NOT UNIX) + # There is a bug in NSI that does not handle full unix paths properly. Make + # sure there is at least one set of four (4) backlasshes. + SET(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS") + #SET(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp") + #SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\MyExecutable.exe") + SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} CLucene Core Library") + SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\clucene.sourceforge.net") + SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\clucene.sourceforge.net") + SET(CPACK_NSIS_CONTACT "clucene-developers@lists.sourceforge.net") + #SET(CPACK_NSIS_MODIFY_PATH ON) +ELSE(WIN32 AND NOT UNIX) +# SET(CPACK_STRIP_FILES "bin/xxx") + SET(CPACK_SOURCE_STRIP_FILES "") +ENDIF(WIN32 AND NOT UNIX) +#SET(CPACK_PACKAGE_EXECUTABLES "MyExecutable" "My Executable") + + +ADD_CUSTOM_TARGET(dist-package + COMMAND rsync -avP -e ssh ${CPACK_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ +# DEPENDS package +) +ADD_CUSTOM_TARGET(dist-package_source + COMMAND rsync -avP -e ssh ${CPACK_SOURCE_PACKAGE_FILE_NAME}.* ustramooner@frs.sourceforge.net:uploads/ +# DEPENDS package_source +) + +#this must be last +INCLUDE(CPack) diff --git a/cmake/DefineOptions.cmake b/cmake/DefineOptions.cmake new file mode 100644 index 00000000000..97d63770610 --- /dev/null +++ b/cmake/DefineOptions.cmake @@ -0,0 +1,53 @@ +#define global options, this makes it easy to use ccmake, or the cmake gui +MACRO (DEFINE_OPTIONS extraOptions extraLibs) + IF(ENABLE_DEBUG) + SET (${extraOptions} "${${extraOptions}} -D_DEBUG") + ENDIF(ENABLE_DEBUG) + + IF(ENABLE_MMAP) + SET (${extraOptions} "${${extraOptions}} -DLUCENE_FS_MMAP") + ENDIF(ENABLE_MMAP) + + IF(ENABLE_DMALLOC) + SET (${extraOptions} "${${extraOptions}} -DDMALLOC") + IF ( DISABLE_MULTITHREADING ) + SET (${extraLibs} ${${extraLibs}} "dmalloccxx") + ELSE( DISABLE_MULTITHREADING ) + SET (${extraLibs} ${${extraLibs}} "dmallocthcxx") + ENDIF ( DISABLE_MULTITHREADING ) + ENDIF(ENABLE_DMALLOC) + + IF(DISABLE_MULTITHREADING) + SET (${extraOptions} "${${extraOptions}} -D_CL_DISABLE_MULTITHREADING") + ELSE(DISABLE_MULTITHREADING) + SET(${extraOptions} "${${extraOptions}} -D_REENTRANT") + ENDIF(DISABLE_MULTITHREADING) + + IF(ENABLE_ASCII_MODE) + SET (${extraOptions} "${${extraOptions}} -D_ASCII") + ELSE(ENABLE_ASCII_MODE) + SET (${extraOptions} "${${extraOptions}} -D_UCS2") + SET (${extraOptions} "${${extraOptions}} -D_UNICODE") + ENDIF(ENABLE_ASCII_MODE) + + IF ( MSVC80 OR MSVC90) + #todo: remove this once crt functions are fixed... + SET (${extraOptions} "${${extraOptions}} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE") + ENDIF ( MSVC80 OR MSVC90 ) + + IF(CYGWIN) + ADD_DEFINITIONS(-D__LARGE64_FILES) + ENDIF(CYGWIN) + + # calm mdown msvc + IF(MSVC) + IF ( NOT MSVC60 ) + #ADD_DEFINITIONS(-wd4251) # 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2' + #ADD_DEFINITIONS(-wd4275) # non DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier' + #ADD_DEFINITIONS(-wd4309) # 'conversion' : truncation of constant value + #ADD_DEFINITIONS(-wd4503) # decorated name length exceeded + #ADD_DEFINITIONS(-wd4786) # identifier was truncated to '255' characters in the debug information + ENDIF ( NOT MSVC60 ) + ENDIF(MSVC) + +ENDMACRO (DEFINE_OPTIONS) diff --git a/cmake/Toolchain-g++32.cmake b/cmake/Toolchain-g++32.cmake new file mode 100644 index 00000000000..e8913243806 --- /dev/null +++ b/cmake/Toolchain-g++32.cmake @@ -0,0 +1,20 @@ +# Cross compiling from linux using g++-multilib to create 32 bit output +# On ubuntu, you'll need to install the packages: g++-multilib gcc-multilib +# +# Use of this file: +# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-g++32.cmake .. + +SET(CMAKE_CXX_FLAGS "-m32") +SET(CMAKE_C_FLAGS "-m32") +SET(CMAKE_EXE_LINKER_FLAGS "-m32") +SET(CMAKE_MODULE_LINKER_FLAGS "-m32") + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/lib32 ) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + diff --git a/cmake/Toolchain-llvm.cmake b/cmake/Toolchain-llvm.cmake new file mode 100644 index 00000000000..b8616bbb197 --- /dev/null +++ b/cmake/Toolchain-llvm.cmake @@ -0,0 +1,8 @@ +# Use of this file: +# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-llvm.cmake .. + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER clang) +SET(CMAKE_CXX_COMPILER clang++) + + diff --git a/cmake/Toolchain-mingw32.cmake b/cmake/Toolchain-mingw32.cmake new file mode 100644 index 00000000000..ec5e72967ec --- /dev/null +++ b/cmake/Toolchain-mingw32.cmake @@ -0,0 +1,32 @@ +# Cross compiling from linux using mingw32 tools +# On ubuntu, you'll need to install the packages: mingw32, mingw32-binutils, mingw32-runtime +# +# Use of this file: +# cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake -C ../cmake/Define-mingw32.cmake .. + +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER i586-mingw32msvc-gcc) +SET(CMAKE_CXX_COMPILER i586-mingw32msvc-g++) + +# here is the target environment located +SET(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc /home/alex/mingw-install ) + +INCLUDE_DIRECTORIES(/usr/lib/gcc/i586-mingw32msvc/4.2.1-sjlj/include/c++) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +SET(_CL_HAVE_GCCVISIBILITYPATCH 0) +SET(_CL_HAVE_NAMESPACES_EXITCODE 0) +SET(_CL_HAVE_NO_SNPRINTF_BUG_EXITCODE 0) +SET(_CL_HAVE_NO_SNWPRINTF_BUG_EXITCODE 0) +SET(LUCENE_STATIC_CONSTANT_SYNTAX_EXITCODE 1) +SET(_CL_HAVE_TRY_BLOCKS_EXITCODE 0) + diff --git a/cmake/TurboPFOR.cmake b/cmake/TurboPFOR.cmake new file mode 100644 index 00000000000..d84daffdca3 --- /dev/null +++ b/cmake/TurboPFOR.cmake @@ -0,0 +1,15 @@ +PROJECT(turbo-pfor) +set(PFOR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/ext/for) + +add_custom_target(build_ic ALL + COMMAND make USE_AVX2=${USE_AVX2} libic.a -j 8 + WORKING_DIRECTORY ${PFOR_SOURCE_DIR} + COMMENT "Original Turbo-PFOR makefile target") + +add_library(ic STATIC IMPORTED) +set_target_properties(ic PROPERTIES IMPORTED_LOCATION "${PFOR_SOURCE_DIR}/libic.a") +add_dependencies(ic build_ic) + +install(FILES ${PFOR_SOURCE_DIR}/libic.a + DESTINATION "lib" + COMPONENT development) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in new file mode 100644 index 00000000000..eee28b6958d --- /dev/null +++ b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,23 @@ +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"${file}\"") + IF(EXISTS "${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF("${rm_retval}" STREQUAL 0) + ELSE("${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"${file}\"") + ENDIF("${rm_retval}" STREQUAL 0) + + #ELSE(EXISTS "${file}") + # MESSAGE(STATUS "File \"${file}\" does not exist.") + ENDIF(EXISTS "${file}") +ENDFOREACH(file) diff --git a/dist-test.sh b/dist-test.sh new file mode 100755 index 00000000000..e556d746031 --- /dev/null +++ b/dist-test.sh @@ -0,0 +1,272 @@ +#!/bin/bash +#Check compliance with Coding standards... + +#where to keep the temp files... +TMP=disttest + +function usage { + echo "usage: ../dist-test.sh [all | " + echo " " + echo " " + echo " " + echo " ]" + echo " ]" + echo " ]" + echo " ]" + echo " ]" + exit 1; +} +t_all=0 +t_env=0 +t_c_all=0 +t_inline=0 +t_compile=0 +t_c_h=0 +t_license=0 +t_ifdefs=0 +t_exports=0 +FAIL=0 + +if [ $# -eq 0 ]; then + usage +else + while [ "$1" != "" ]; do + if [ "$1" == "all" ]; then + t_all=1 + elif [ "$1" == "env" ]; then + t_env=1 + elif [ "$1" == "c_all" ]; then + t_c_all=1 + elif [ "$1" == "inline" ]; then + t_inline=1 + elif [ "$1" == "compile" ]; then + t_compile=1 + elif [ "$1" == "c_header" ]; then + t_c_h=1 + elif [ "$1" == "license" ]; then + t_license=1 + elif [ "$1" == "ifdefs" ]; then + t_ifdefs=1 + elif [ "$1" == "exports" ]; then + t_exports=1 + else + usage + fi + shift + done +fi + +if [ $t_all -eq 1 ]; then + t_env=1 + t_c_all=1 + t_c_h=1 + t_inline=1 + t_compile=1 + t_license=1 + t_ifdefs=1 + t_exports=1 +fi + + +#check to see that no #ifdefs exist in headers that don't belong +function checkForIfdefs { + I=0 + grep "#if" $1| grep -v "_UCS2" |grep -v "_CL_HAVE_" |grep -v "_ASCII" |grep -v "_WIN32"|grep -v "_MSC_"|grep -v "__MINGW32__" |grep -v "_WIN64" | while read line; do + I=`expr $I + 1` + if [ $I -gt 1 ]; then + echo $1 might have invalid ifdef: $line + fi + done +} + + +if [ $t_env -eq 1 ]; then + rm -fdr $TMP 2>/dev/null + mkdir $TMP + + #create header file for testing of symbols in headers. + echo "#include \"CLucene/StdHeader.h"\" >$TMP/pub-headers.cpp + + #iterate all headers + for H in `find ../src/shared/CLucene| grep "\.h$"` `find ../src/core/CLucene| grep "\.h$"`; do + BH=`basename "$H"` + DN=`dirname "$H"` + if [ "${BH:0:1}" != "_" ]; then + DH=`dirname "${H:3}"` + + if [ "${H:7}" != "core/CLucene/util/Reader.h" ]; then + #move headers somewhere to compile + mkdir -p "$TMP/$DH" 2>/dev/null + ln -s "`cd "$DN" && pwd`/$BH" "$TMP/${H:3}" 2>/dev/null + + #create pub-headers.cpp + echo "#include \"${H:7}\"" >>$TMP/pub-headers.cpp + fi + fi + done + + echo "int main(){return 0;}" >>$TMP/pub-headers.cpp +fi + + +################################################ +#now the environment is finished being setup... +################################################ +echo "Starting tests..." + +if [ $t_c_h -eq 1 ] || [ $t_ifdefs -eq 1 ] || [ $t_exports -eq 1 ]; then + for H in `find $TMP/src | grep "\.h$"`; do + BH=`basename "$H"` + DH=`dirname "${H:3}"` + + if [ $t_ifdefs -eq 1 ]; then + checkForIfdefs $H + fi + + #check that all classes are exported + if [ $t_exports -eq 1 ]; then + if [ "${H:0:1}" == "_" ]; then + #internal headers... none must be exported + XX=`awk '/^[ \t]*(class|struct)/ { print $line }' $H| grep -v ";$"| grep -v CLUCENE_EXPORT| grep -v CLUCENE_INLINE_EXPORT| grep -v CLUCENE_SHARED_EXPORT| grep -v CLUCENE_SHARED_INLINE_EXPORT` + if [ "$XX" == "" ]; then + echo "$H is internal but has exported class: $XX" + echo "" + FAIL=1 + fi + else + #external headers... all must be exported + XX=`awk '/^[ \t]*(class|struct)/ { print $line }' $H| grep -v ";$"| grep -v CLUCENE_EXPORT| grep -v CLUCENE_INLINE_EXPORT| grep -v CLUCENE_SHARED_EXPORT| grep -v CLUCENE_SHARED_INLINE_EXPORT` + if [ "$XX" != "" ]; then + echo "$H has unexported class: $XX" + echo "" + FAIL=1 + fi + fi + fi + + #test that each header compiles independently... + if [ $t_c_h -eq 1 ]; then + echo "#include \"CLucene/StdHeader.h"\" >$TMP/pub-header.cpp + echo "#include \"$H"\" >>$TMP/pub-header.cpp + echo "int main(){ return 0; }" >>"$TMP/pub-header.cpp" + ERROR=`g++ -I. -I$TMP/src/shared -I./src/shared -I../src/ext -I$TMP/src/core $TMP/pub-header.cpp` + if [ $? -ne 0 ]; then + echo "" + echo "$H doesn't compile seperately..." + echo $ERROR + FAIL=1; + fi + fi + done + + + if [ $t_ifdefs -eq 1 ]; then + echo "Not all ifdefs are invalid, you have to figure it out for yourself :-)" + echo "If defs in classes which change depending on a user setting can cause big problems due to offset changes" + echo "for example:" + echo "class X {" + echo " #ifdef _DEBUG" + echo " int x;" + echo " #endif" + echo " int y;" + echo "}" + echo "If the library is compiled with _DEBUG, and then a user calls y without _DEBUG defined, unexpected behaviour will occur" + fi +fi + +#iterate all our code... +if [ $t_license -eq 1 ]; then + for H in `find ../src`; do + BH=`basename "$H"` + BH_len=${#BH} + + if [ "${BH:BH_len-2}" == ".h" ] || [ "${BH:BH_len-2}" == ".c" ] || [ "${BH:BH_len-4}" == ".cpp" ]; then + + #snowball has its own license... + if [ "echo $H|grep 'snowball/src_c'" != "" ]; then + continue + fi + #snowball has its own license... + if [ "echo $H|grep 'libstemmer'" != "" ]; then + continue + fi + #zlib has its own license... + if [ "echo $H|grep 'CLucene/util/zlib'" != "" ]; then + continue + fi + + if [ "`awk '/\* Copyright \(C\) [0-9]*-[0-9]* .*$/ { print $line }' $H`" == "" ]; then + if [ "`awk '/\* Copyright [0-9]*-[0-9]* .*$/ { print $line }' $H`" == "" ]; then + echo "$H ($BH) has invalid license" + FAIL=1 + fi + fi + fi + done +fi + + +#test if headers can compile together by themselves: +if [ $t_c_all -eq 1 ]; then + g++ -I$TMP/src -I../src/ext -I$TMP/src/shared -I$TMP/src/core $TMP/pub-headers.cpp -I./src/shared +fi + +if [ $t_inline -eq 1 ]; then + if [ ! -d "./doc" ]; then + echo "Couldn't find docs, run:" + echo "# cmake -DENABLE_CLDOCS:BOOLEAN=TRUE ." + echo "# make doc" + echo "and then try again" + exit 1 + fi + + INLINES=0 + grep -c "\[inline" doc/html/*.html|grep -v ":0$"|grep -v "util"|grep -v "jstreams" | while read line; do + + #ignore some actual inlines... + if [ "doc/html/classlucene_1_1index_1_1Term.html:1" == $line ]; then + continue; + fi + if [ "doc/html/classlucene_1_1search_1_1Similarity.html:1" == $line ]; then + continue; + fi + if [ "doc/html/classlucene_1_1store_1_1BufferedIndexInput.html:1" == $line ]; then + continue; + fi + + if [ $INLINES -eq 0 ]; then + echo "These files report inline code:" + INLINES=1 + FAIL=1 + fi + echo $line + done +fi + +if [ $t_compile -eq 1 ]; then + #compile serperately + make cl_test + if [ $? -ne 0 ]; then + FAIL=1; + fi + + echo "Undefines for shared lib:" + nm -u --demangle bin/libclucene-shared.so |grep -E "lucene::" + echo "Undefines for core lib:" + nm -u --demangle bin/libclucene-core.so |grep -E "lucene::"|grep -v "lucene::util::Misc" |grep -v "lucene::util::mutex" |grep -v "lucene::util::StringBuffer"|grep -v "lucene::util::shared_condition" + + #compile together + make test-all + if [ $? -ne 0 ]; then + FAIL=1; + fi + + +fi + + +if [ $FAIL == 1 ]; then + echo "There were errors, please correct them and re-run" + exit 1 +fi +exit 0 diff --git a/doc/Doxyfile.cmake b/doc/Doxyfile.cmake new file mode 100644 index 00000000000..ab090e3a8b0 --- /dev/null +++ b/doc/Doxyfile.cmake @@ -0,0 +1,237 @@ +# Doxyfile 1.2.18 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +PROJECT_NAME = CLucene-core +PROJECT_NUMBER = @CPACK_PACKAGE_VERSION@ + +OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc +OUTPUT_LANGUAGE = English + +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ALIASES = "memory=\par Memory management:\n" +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = @PROJECT_BINARY_DIR@/doc/doxygen.warnings.log + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +INPUT = @PROJECT_SOURCE_DIR@/src/core/CLucene +INPUT += @PROJECT_SOURCE_DIR@/src/shared/CLucene +FILE_PATTERNS = *.h +RECURSIVE = YES +#EXCLUDE = mem.h bufferedstream.h fileinputstream.h stringreader.h Misc.h LuceneThreads.h jstreamconfig.h +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = "**/config/**" \ + "**/.svn/**" \ + "**/debug/**" \ + "_*.h" +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +GENERATE_HTML = @CLDOCS_HTML@ +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = @PROJECT_BINARY_DIR@/doc/helpheader.htm +HTML_FOOTER = @PROJECT_BINARY_DIR@/doc/helpfooter.htm +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES + +GENERATE_HTMLHELP = @CLDOCS_HTML_HELP@ +CHM_FILE = ../clucene.chm +HHC_LOCATION = @HTML_HELP_COMPILER_EX@ +GENERATE_CHI = YES +BINARY_TOC = YES +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +GENERATE_LATEX = @CLDOCS_LATEX@ +LATEX_OUTPUT = latex +LATEX_CMD_NAME = @LATEX_COMPILER@ +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +GENERATE_RTF = @CLDOCS_RTF@ +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = @CLDOCS_MAN@ +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +GENERATE_XML = @CLDOCS_XML@ +XML_SCHEMA = +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = @PROJECT_SOURCE_DIR@/src/core +INCLUDE_PATH += @PROJECT_SOURCE_DIR@/src/shared +INCLUDE_PATH += @PROJECT_BINARY_DIR@/src/shared +INCLUDE_FILE_PATTERNS = + +PREDEFINED = "_MSC_VER=1400" +PREDEFINED += "WIN32" +PREDEFINED += "_CL_DISABLE_MULTITHREADING" +PREDEFINED += "_CL_DEPRECATED(x)=" + +#namespaces +PREDEFINED += "CL_NS(sub)=lucene::sub" +PREDEFINED += "CL_NS2(sub,sub2)=lucene::sub:sub2" +PREDEFINED += "CL_NS_DEF(sub)=namespace lucene{ namespace sub{" +PREDEFINED += "CL_NS_DEF2(sub,sub2)=namespace lucene{ namespace sub{ namespace sub2 {" +PREDEFINED += "CL_NS_END=}}" +PREDEFINED += "CL_NS_END2=}}}" +PREDEFINED += "CL_NS_USE(sub)=using namespace lucene::sub" +PREDEFINED += "CL_NS_USE2(sub,sub2)=using namespace lucene::sub::sub2" +PREDEFINED += "CL_NS_STD(func)=std::func" +PREDEFINED += "CL_NS_HASHING(func)=std::func" + +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +TAGFILES = +GENERATE_TAGFILE = @CLDOCS_TAGFILE_LOCATION@ +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = @PERL_EXECUTABLE@ + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = @HAVE_DOT@ +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = @DOXYGEN_DOT_EXECUTABLE@ +DOTFILE_DIRS = +GENERATE_LEGEND = YES +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +SEARCHENGINE = NO diff --git a/doc/coding standards.txt b/doc/coding standards.txt new file mode 100644 index 00000000000..fc4a6497fa6 --- /dev/null +++ b/doc/coding standards.txt @@ -0,0 +1,113 @@ +Coding Style +------------ + +CLucene follows a hybrid coding style. Because of the nature of the code being +a java port, there are naturally some java like syntax. + +* Never use CL_NS_USE(x) in a header file (use CL_NS(x):: for each class), it defeats the purpose of namespaces. +* Use CL_NS_USE(x) in .cpp files if there are more than a few usages of that namespace. + + +Headers: +* _headername.h headers are private, and will not be distributed. Don't include these files from public headers. +* The shared library is not distributed, except for: SharedHeader.h and clucene-config.h +* Keep _ifdef's in public headers to an absolute minimum. +* Public headers should contain only classes that are exported (class CLUCENE_EXPORT classname). +* All classes should have a destructor, + the destructor should be virtual if there is any chance of the class being overridden + +Documentation: +Although CLucene documentation is not complete, it would be nice to see documentation created for new files. +We used doxygen to create documentation. 2 basic formats of documentation are: + +/** documentation must have ** to be included */ +void function(); +void function2(); //< can also document functions retrospectively by adding < + + +/** +* You can also document memory with the special @memory alias. +* @memory you must delete data returned from this function using _CLDELETE +*/ +Object createObject(); + + +Cross platform specifics: +* Use macros provided in shared project. This applies to data types and functions +* static const int32_t x=1; Should be coded as: Use LUCENE_STATIC_CONSTANT (int32_t, x=1). Else it is not portable. +* Static objects should not be initialised in the class header. ( class x{ static object a; }; ). This will not work + everywhere. Instead use a getter. + + class x{ + static object* a; + public: + static Object* getA(); + static void CLUCENE_LOCAL _shutdown(); + }; + + Then in the implementation code + + Object* x::a = NULL; + Object* x::getA(){ + if ( a == NULL ) + x::a = _CLNEW Object; + return a; + } + void x::_shutdown(){ + _CLDELETE(a); + } + + In CLucene/StdHeader.cpp, add x::_shutdown() to the list _lucene_shutdown function. + +* This is bad: + + class x{ + LUCENE_STATIC_CONSTANT(int32_t, x=1) + void func( int32_t value=x); + }; + + This will fail on some platforms. It is better to do: + int32_t value=-1 (-1 should be some logical value, not necessarily -1). + then in the implementation, check if -1 and default to the x static constant. +* Try and use the functions in util/Array.h instead of Void Map/List functions. Void Map/List will be deprecated for public access +* Most compilers don't complain about this (in normal mode), but we require pedantic mode behaviour. Some important things for this are: + 1. Initialise variables in correct order as in the class + class x{ + int a; + int b; + x(): + b(12), + a(11) //THIS IS WRONG! a is initialised after b. + { + } + }; + +Good development tips +--------------------- +When developing, use the available clucene debugging tools: +* _CND_DEBUG - condition debugging, an 'assert' type system (or configure with --enable-cnddebug) + +Good performance tips: +---------------------- +CLucene has a lot of new changes to help improve performance. +Some of them are still being tuned... + +MSVC profiling tutorial: +http://webserver.tc.cornell.edu/services/edu/topics/Performance/Profiling/more.asp + +For GCC see gprof +you can enable gprof by configuring with ENABLE_GPROF + +Developing +---------- +When developing, please keep in mind cross-platform issues and also +character set issues (unicode/ascii). + +Hint: +To do a quick test to see if the code compiles +run this command from the root directory of clucene. +It will compile all the CLucene code monolithically. + + % test-pedantic + +This will do a quick compile then run all the clucene tests. diff --git a/doc/doxygen.css.cmake b/doc/doxygen.css.cmake new file mode 100644 index 00000000000..b9fae69c1c5 --- /dev/null +++ b/doc/doxygen.css.cmake @@ -0,0 +1,163 @@ +H1 { + text-align: center; + font-family: Arial, Helvetica, sans-serif; +} +H2 { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +CAPTION { font-weight: bold } +DIV.qindex { width: 100%; + background-color: #eeeeff; + border: 4px solid #eeeeff; + text-align: center; + margin-bottom: 2px +} +A.qindex { text-decoration: none; font-weight: bold; } +A.qindex:hover { text-decoration: none; background-color: #ddddff } +A.qindexHL { text-decoration: none; font-weight: bold; + background-color: #6666cc; + color: #ffffff + } +A.qindexHL:hover { text-decoration: none; background-color: #6666cc } +A.qindexRef { text-decoration: none; font-weight: bold; } +A.qindexRef:hover { text-decoration: none; background-color: #ddddff } +A.qindexRefHL { text-decoration: none; font-weight: bold; + background-color: #6666cc; + color: #ffffff + } +A.qindexRefHL:hover { text-decoration: none; background-color: #6666cc } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code { text-decoration: none; font-weight: normal; color: #4444ee } +A.codeRef { font-weight: normal; color: #4444ee } +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +DIV.fragment { + width: 98%; + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + padding-left: 4px; + margin: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; +margin-bottom: 3px; margin-top: 3px } +TD.md { background-color: #f2f2ff; font-weight: bold; } +TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } +TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; +width: 600px; } +DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; +font-weight: bold } +DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +TD.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdTable { + border: 1px solid #868686; + background-color: #f2f2ff; +} +.mdRow { + padding: 8px 20px; +} +.mdescLeft { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + background-color: #FAFAFA; + padding-left: 8px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + font-style: italic; + background-color: #FAFAFA; + padding-left: 4px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; + padding-bottom: 0px; + padding-right: 8px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} +.memItemRight { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 13px; +} diff --git a/doc/helpfooter.htm.cmake b/doc/helpfooter.htm.cmake new file mode 100644 index 00000000000..d12f5bb7288 --- /dev/null +++ b/doc/helpfooter.htm.cmake @@ -0,0 +1,4 @@ +
+

clucene.sourceforge.net

+ + \ No newline at end of file diff --git a/doc/helpheader.htm.cmake b/doc/helpheader.htm.cmake new file mode 100644 index 00000000000..f75de0e078f --- /dev/null +++ b/doc/helpheader.htm.cmake @@ -0,0 +1,24 @@ + + + +CLucene API Documentation (Version @CPACK_PACKAGE_VERSION@) + + + + + + + + + + + +

CLucene - a full-featured, c++ search engine
+API Documentation +

+
diff --git a/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.cpp b/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.cpp new file mode 100644 index 00000000000..da28cbe01fc --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.cpp @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "LanguageBasedAnalyzer.h" +#include "CLucene/analysis/cjk/CJKAnalyzer.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/analysis/standard/StandardTokenizer.h" +#include "CLucene/analysis/standard/StandardFilter.h" +#include "CLucene/snowball/SnowballFilter.h" + +CL_NS_USE(util) +CL_NS_USE2(analysis,cjk) +CL_NS_USE2(analysis,standard) +CL_NS_USE2(analysis,snowball) + +CL_NS_DEF(analysis) + +LanguageBasedAnalyzer::LanguageBasedAnalyzer(const TCHAR* language, bool stem) +{ + if ( language == NULL ) + _tcsncpy(lang,LUCENE_BLANK_STRING,100); + else + _tcsncpy(lang,language,100); + this->stem = stem; +} +LanguageBasedAnalyzer::~LanguageBasedAnalyzer(){ +} +void LanguageBasedAnalyzer::setLanguage(const TCHAR* language){ + _tcsncpy(lang,language,100); +} +void LanguageBasedAnalyzer::setStem(bool stem){ + this->stem = stem; +} +TokenStream* LanguageBasedAnalyzer::tokenStream(const TCHAR* fieldName, Reader* reader) { + TokenStream* ret = NULL; + if ( _tcscmp(lang, _T("cjk"))==0 ){ + ret = _CLNEW CL_NS2(analysis,cjk)::CJKTokenizer(reader); + }else{ + BufferedReader* bufferedReader = reader->__asBufferedReader(); + if ( bufferedReader == NULL ) + ret = _CLNEW StandardTokenizer( _CLNEW FilteredBufferedReader(reader, false), true ); + else + ret = _CLNEW StandardTokenizer(bufferedReader); + + ret = _CLNEW StandardFilter(ret,true); + + if ( stem ) + ret = _CLNEW SnowballFilter(ret,lang, true); //todo: should check whether snowball supports the language + + if ( stem ) //hmm... this could be configured seperately from stem + ret = _CLNEW ISOLatin1AccentFilter(ret, true); //todo: this should really only be applied to latin languages... + + //lower case after the latin1 filter + ret = _CLNEW LowerCaseFilter(ret,true); + } + //todo: could add a stop filter based on the language - need to fix the stoplist loader first + + return ret; +} + +CL_NS_END diff --git a/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.h b/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.h new file mode 100644 index 00000000000..596c86bd99d --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/LanguageBasedAnalyzer.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_languagebasedanalyzer_ +#define _lucene_analysis_languagebasedanalyzer_ + +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF(analysis) + +class CLUCENE_CONTRIBS_EXPORT LanguageBasedAnalyzer: public CL_NS(analysis)::Analyzer{ + TCHAR lang[100]; + bool stem; +public: + LanguageBasedAnalyzer(const TCHAR* language=NULL, bool stem=true); + ~LanguageBasedAnalyzer(); + void setLanguage(const TCHAR* language); + void setStem(bool stem); + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + }; + +CL_NS_END +#endif diff --git a/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp b/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp new file mode 100644 index 00000000000..d5ec3a6776e --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/PorterStemmer.cpp @@ -0,0 +1,313 @@ +/* This is the Porter stemming algorithm, originally written by Martin Porter. + It may be regarded as cononical, in that it follows the + algorithm presented in + + Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14, + no. 3, pp 130-137, + + See also http://www.tartarus.org/~martin/PorterStemmer + + Modified by "Hemant Muthiyan" + email: hemant_muthiyan@yahoo.co.in + +*/ + +#include "CLucene/_ApiHeader.h" +#include "PorterStemmer.h" + +CL_NS_DEF(analysis) + + bool PorterStemmer::cons(size_t i) { + switch (b[i]) { + case 'a': case 'e': case 'i': case 'o': case 'u': + return false; + case 'y': + return (i==k0) ? true : !cons(i-1); + default: + return true; + } + } + + int32_t PorterStemmer::m() { + int32_t n = 0; + size_t i = k0; + while(true) { + if (i > j) + return n; + if (! cons(i)) + break; + i++; + } + i++; + while(true) { + while(true) { + if (i > j) + return n; + if (cons(i)) + break; + i++; + } + i++; + n++; + while(true) { + if (i > j) + return n; + if (! cons(i)) + break; + i++; + } + i++; + } + } + + bool PorterStemmer::vowelinstem() { + for (size_t i = k0; i <= j; i++) + if (! cons(i)) + return true; + return false; + } + + /* doublec(j) is true <=> j,(j-1) contain a double consonant. */ + bool PorterStemmer::doublec(size_t j) { + if (j < k0+1) + return false; + if (b[j] != b[j-1]) + return false; + return cons(j); + } + + /* cvc(i) is true <=> i-2,i-1,i has the form consonant - vowel - consonant + and also if the second c is not w,x or y. this is used when trying to + restore an e at the end of a short word. e.g. + + cav(e), lov(e), hop(e), crim(e), but + snow, box, tray. + + */ + bool PorterStemmer::cvc(size_t i) { + if (i < k0+2 || !cons(i) || cons(i-1) || !cons(i-2)) + return false; + else { + int32_t ch = b[i]; + if (ch == 'w' || ch == 'x' || ch == 'y') return false; + } + return true; + } + + bool PorterStemmer::ends(TCHAR *s) { + size_t l = _tcslen(s); + size_t o = k-l+1; + if (o < k0) + return false; + for (size_t i = 0; i < l; i++) + if (b[o+i] != s[i]) + return false; + j = (l > k) ? 0 : k-l; + return true; + } + + void PorterStemmer::setto(const TCHAR *s) { + size_t l = _tcslen(s); + size_t o = j+1; + for (size_t i = 0; i < l; i++) + b[o+i] = s[i]; + k = j+l; + dirty = true; + } + + void PorterStemmer::r(const TCHAR *s) { + if (m() > 0) setto(s); + } + + void PorterStemmer::step1() { + if (b[k] == _T('s')) { + if (ends(_T("sses"))) k -= 2; + else if (ends(_T("ies"))) setto(_T("i")); + else if (b[k-1] != _T('s')) k--; + } + if (ends(_T("eed"))) { + if (m() > 0) + k--; + } + else if ((ends(_T("ed")) || ends(_T("ing"))) && vowelinstem()) { + k = j; + if (ends(_T("at"))) setto(_T("ate")); + else if (ends(_T("bl"))) setto(_T("ble")); + else if (ends(_T("iz"))) setto(_T("ize")); + else if (doublec(k)) { + int32_t ch = b[k--]; + if (ch == _T('l') || ch == _T('s') || ch == _T('z')) + k++; + } + else if (m() == 1 && cvc(k)) + setto(_T("e")); + } + } + + void PorterStemmer::step2() { + if (ends(_T("y")) && vowelinstem()) { + b[k] = 'i'; + dirty = true; + } + } + + void PorterStemmer::step3() { + if (k == k0) return; /* For Bug 1 */ + switch (b[k-1]) { + case 'a': + if (ends(_T("ational"))) { r(_T("ate")); break; } + if (ends(_T("tional"))) { r(_T("tion")); break; } + break; + case 'c': + if (ends(_T("enci"))) { r(_T("ence")); break; } + if (ends(_T("anci"))) { r(_T("ance")); break; } + break; + case 'e': + if (ends(_T("izer"))) { r(_T("ize")); break; } + break; + case 'l': + if (ends(_T("bli"))) { r(_T("ble")); break; } + if (ends(_T("alli"))) { r(_T("al")); break; } + if (ends(_T("entli"))) { r(_T("ent")); break; } + if (ends(_T("eli"))) { r(_T("e")); break; } + if (ends(_T("ousli"))) { r(_T("ous")); break; } + break; + case 'o': + if (ends(_T("ization"))) { r(_T("ize")); break; } + if (ends(_T("ation"))) { r(_T("ate")); break; } + if (ends(_T("ator"))) { r(_T("ate")); break; } + break; + case 's': + if (ends(_T("alism"))) { r(_T("al")); break; } + if (ends(_T("iveness"))) { r(_T("ive")); break; } + if (ends(_T("fulness"))) { r(_T("ful")); break; } + if (ends(_T("ousness"))) { r(_T("ous")); break; } + break; + case 't': + if (ends(_T("aliti"))) { r(_T("al")); break; } + if (ends(_T("iviti"))) { r(_T("ive")); break; } + if (ends(_T("biliti"))) { r(_T("ble")); break; } + break; + case 'g': + if (ends(_T("logi"))) { r(_T("log")); break; } + } + } + + void PorterStemmer::step4() { + switch (b[k]) { + case 'e': + if (ends(_T("icate"))) { r(_T("ic")); break; } + if (ends(_T("ative"))) { r(LUCENE_BLANK_STRING); break; } + if (ends(_T("alize"))) { r(_T("al")); break; } + break; + case 'i': + if (ends(_T("iciti"))) { r(_T("ic")); break; } + break; + case 'l': + if (ends(_T("ical"))) { r(_T("ic")); break; } + if (ends(_T("ful"))) { r(LUCENE_BLANK_STRING); break; } + break; + case 's': + if (ends(_T("ness"))) { r(LUCENE_BLANK_STRING); break; } + break; + } + } + + void PorterStemmer::step5() { + if (k == k0) return; /* for Bug 1 */ + switch (b[k-1]) { + case 'a': + if (ends(_T("al"))) break; + return; + case 'c': + if (ends(_T("ance"))) break; + if (ends(_T("ence"))) break; + return; + case 'e': + if (ends(_T("er"))) break; return; + case 'i': + if (ends(_T("ic"))) break; return; + case 'l': + if (ends(_T("able"))) break; + if (ends(_T("ible"))) break; return; + case 'n': + if (ends(_T("ant"))) break; + if (ends(_T("ement"))) break; + if (ends(_T("ment"))) break; + /* element etc. not stripped before the m */ + if (ends(_T("ent"))) break; + return; + case 'o': + if (ends(_T("ion")) && j >= 0 && (b[j] == 's' || b[j] == 't')) break; + /* j >= 0 fixes Bug 2 */ + if (ends(_T("ou"))) break; + return; + /* takes care of -ous */ + case 's': + if (ends(_T("ism"))) break; + return; + case 't': + if (ends(_T("ate"))) break; + if (ends(_T("iti"))) break; + return; + case 'u': + if (ends(_T("ous"))) break; + return; + case 'v': + if (ends(_T("ive"))) break; + return; + case 'z': + if (ends(_T("ize"))) break; + return; + default: + return; + } + if (m() > 1) + k = j; + } + + void PorterStemmer::step6() { + j = k; + if (b[k] == 'e') { + int32_t a = m(); + if (a > 1 || a == 1 && !cvc(k-1)) + k--; + } + if (b[k] == 'l' && doublec(k) && m() > 1) + k--; + } + + + PorterStemmer::PorterStemmer(TCHAR *Text) { + b = Text; + i = _tcslen(b); + dirty = false; + } + + PorterStemmer::~PorterStemmer(){ + b = NULL; + } + + + int32_t PorterStemmer::getResultLength() { return i; } + + bool PorterStemmer::stem() { + //i = strlen(b); + k = i -1; + k0 = 0; + if (k > k0+1) { + step1(); step2(); step3(); step4(); step5(); step6(); + } + // Also, a word is considered dirty if we lopped off letters + // Thanks to Ifigenia Vairelles for pointing this out. + if (i != k+1) + dirty = true; + i = k+1; + return dirty; + } + + const TCHAR* PorterStemmer::getResultBuffer() { + return b; + } + +CL_NS_END diff --git a/src/contribs-lib/CLucene/analysis/PorterStemmer.h b/src/contribs-lib/CLucene/analysis/PorterStemmer.h new file mode 100644 index 00000000000..35ff817addb --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/PorterStemmer.h @@ -0,0 +1,151 @@ +/* This is the Porter stemming algorithm, originally written by Martin Porter. + It may be regarded as cononical, in that it follows the + algorithm presented in + + Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14, + no. 3, pp 130-137, + + See also http://www.tartarus.org/~martin/PorterStemmer + + Modified by "Hemant Muthiyan" + email: hemant_muthiyan@yahoo.co.in + + The Porter stemmer should be regarded as frozen, that is, strictly defined, + and not amenable to further modification. As a stemmer, it is slightly inferior + to the Snowball English or Porter2 stemmer, which derives from it, and which is + subjected to occasional improvements. For practical work, therefore, the new + Snowball stemmer is recommended. The Porter stemmer is appropriate to IR + research work involving stemming where the experiments need to be exactly + repeatable. + +*/ +#ifndef _lucene_analysis_PorterStemmer_ +#define _lucene_analysis_PorterStemmer_ + +CL_NS_DEF(analysis) + +class CLUCENE_CONTRIBS_EXPORT PorterStemmer +{ +private: + TCHAR *b; + size_t i, /* offset into b */ + j, k, k0; + bool dirty; + //private static final int32_t EXTRA = 1; + + /* cons(i) is true <=> b[i] is a consonant. */ + +private: + bool cons(size_t i); + + /* m() measures the number of consonant sequences between k0 and j. if c is + a consonant sequence and v a vowel sequence, and <..> indicates arbitrary + presence, + + gives 0 + vc gives 1 + vcvc gives 2 + vcvcvc gives 3 + .... + */ + + int32_t m(); + + /* vowelinstem() is true <=> k0,...j contains a vowel */ + + bool vowelinstem(); + + /* doublec(j) is true <=> j,(j-1) contain a double consonant. */ + bool doublec(size_t j); + + /* cvc(i) is true <=> i-2,i-1,i has the form consonant - vowel - consonant + and also if the second c is not w,x or y. this is used when trying to + restore an e at the end of a short word. e.g. + + cav(e), lov(e), hop(e), crim(e), but + snow, box, tray. + + */ + bool cvc(size_t i); + + bool ends(TCHAR *s); + + /* setto(s) sets (j+1),...k to the characters in the string s, readjusting + k. */ + + void setto(const TCHAR *s); + + /* r(s) is used further down. */ + + void r(const TCHAR *s); + + /* step1() gets rid of plurals and -ed or -ing. e.g. + + caresses -> caress + ponies -> poni + ties -> ti + caress -> caress + cats -> cat + + feed -> feed + agreed -> agree + disabled -> disable + + matting -> mat + mating -> mate + meeting -> meet + milling -> mill + messing -> mess + + meetings -> meet + + */ + + void step1(); + + /* step2() turns terminal y to i when there is another vowel in the stem. */ + + void step2(); + + /* step3() maps double suffices to single ones. so -ization ( = -ize plus + -ation) maps to -ize etc. note that the string before the suffix must give + m() > 0. */ + + void step3(); + + /* step4() deals with -ic-, -full, -ness etc. similar strategy to step3. */ + + void step4(); + + /* step5() takes off -ant, -ence etc., in context vcvc. */ + + void step5(); + + /* step6() removes a final -e if m() > 1. */ + + void step6(); + + public: + + PorterStemmer(TCHAR *Text); + ~PorterStemmer(); + + + /** + * Returns the length of the word resulting from the stemming process. + */ + int32_t getResultLength(); + + bool stem(); + + /** + * Returns a reference to a character buffer containing the results of + * the stemming process. You also need to consult getResultLength() + * to determine the length of the result. + */ + const TCHAR* getResultBuffer(); + +}; +CL_NS_END + +#endif diff --git a/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp b/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp new file mode 100644 index 00000000000..05a17e50720 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.cpp @@ -0,0 +1,190 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CJKAnalyzer.h" +#include "CLucene/util/CLStreams.h" + +CL_NS_DEF2(analysis,cjk) +CL_NS_USE(analysis) +CL_NS_USE(util) + + +const TCHAR* CJKTokenizer::tokenTypeSingle = _T("single"); +const TCHAR* CJKTokenizer::tokenTypeDouble = _T("double"); + +CJKTokenizer::CJKTokenizer(Reader* in): + Tokenizer(in) +{ + tokenType = Token::getDefaultType(); + offset = 0; + bufferIndex = 0; + dataLen = 0; + preIsTokened = false; + ignoreSurrogates = true; +} + +CL_NS(analysis)::Token* CJKTokenizer::next(Token* token){ + /** how many character(s) has been stored in buffer */ + int32_t length = 0; + + /** the position used to create Token */ + int32_t start = offset; + + while (true) { + /** current character */ + clunichar c; + int charlen = 1; + + offset++; + + if (bufferIndex >= dataLen) { + dataLen = input->read(ioBuffer, 1, LUCENE_IO_BUFFER_SIZE); + bufferIndex = 0; + } + + if (dataLen == -1) { + if (length > 0) { + if (preIsTokened == true) { + length = 0; + preIsTokened = false; + } + + break; + } else { + return NULL; + } + } else { + //get current character + c = ioBuffer[bufferIndex++]; + } + + //to support surrogates, we'll need to convert the incoming utf16 into + //ucs4(c variable). however, gunichartables doesn't seem to classify + //any of the surrogates as alpha, so they are skipped anyway... + //so for now we just convert to ucs4 so that we dont corrupt the input. + if ( c >= 0xd800 || c <= 0xdfff ){ + clunichar c2 = ioBuffer[bufferIndex]; + if ( c2 >= 0xdc00 && c2 <= 0xdfff ){ + bufferIndex++; + offset++; + charlen=2; + + c = (((c & 0x03ffL) << 10) | ((c2 & 0x03ffL) << 0)) + 0x00010000L; + } + } + + //if the current character is ASCII or Extend ASCII + if ((c <= 0xFF) //is BASIC_LATIN + || (c>=0xFF00 && c<=0xFFEF) //ascii >0x74 cast to unsigned... + ) { + if (c >= 0xFF00) { + //todo: test this... only happens on platforms where char is signed, i think... + /** convert HALFWIDTH_AND_FULLWIDTH_FORMS to BASIC_LATIN */ + c -= 0xFEE0; + } + + // if the current character is a letter or "_" "+" "#" + if (_istalnum(c) || ((c == '_') || (c == '+') || (c == '#')) ) { + if (length == 0) { + // "javaC1C2C3C4linux"
+ // ^--: the current character begin to token the ASCII + // letter + start = offset - 1; + } else if (tokenType == tokenTypeDouble) { + // "javaC1C2C3C4linux"
+ // ^--: the previous non-ASCII + // : the current character + offset-=charlen; + bufferIndex-=charlen; + tokenType = tokenTypeSingle; + + if (preIsTokened == true) { + // there is only one non-ASCII has been stored + length = 0; + preIsTokened = false; + + break; + } else { + break; + } + } + + // store the LowerCase(c) in the buffer + buffer[length++] = _totlower((TCHAR)c); + tokenType = tokenTypeSingle; + + // break the procedure if buffer overflowed! + if (length == LUCENE_MAX_WORD_LEN) { + break; + } + } else if (length > 0) { + if (preIsTokened == true) { + length = 0; + preIsTokened = false; + } else { + break; + } + } + } else { + // non-ASCII letter, eg."C1C2C3C4" + if ( _istalpha(c) || (!ignoreSurrogates && c>=0x10000) ) { + if (length == 0) { + start = offset - 1; + + if ( c < 0x00010000L ) + buffer[length++] = (TCHAR)c; + else{ + clunichar ucs4 = c - 0x00010000L; + buffer[length++] = (TCHAR)((ucs4 >> 10) & 0x3ff) | 0xd800; + buffer[length++] = (TCHAR)((ucs4 >> 0) & 0x3ff) | 0xdc00; + } + + tokenType = tokenTypeDouble; + } else { + if (tokenType == tokenTypeSingle) { + offset-=charlen; + bufferIndex-=charlen; + + //return the previous ASCII characters + break; + } else { + if ( c < 0x00010000L ) + buffer[length++] = (TCHAR)c; + else{ + clunichar ucs4 = c - 0x00010000L; + buffer[length++] = (TCHAR)((ucs4 >> 10) & 0x3ff) | 0xd800; + buffer[length++] = (TCHAR)((ucs4 >> 0) & 0x3ff) | 0xdc00; + } + tokenType = tokenTypeDouble; + + if (length >= 2) { + offset-=charlen; + bufferIndex-=charlen; + preIsTokened = true; + + break; + } + } + } + } else if (length > 0) { + if (preIsTokened == true) { + // empty the buffer + length = 0; + preIsTokened = false; + } else { + break; + } + } + } + } + + buffer[length]='\0'; + token->set(buffer,start, start+length, tokenType); + return token; +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.h b/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.h new file mode 100644 index 00000000000..978ad81a7f2 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/cjk/CJKAnalyzer.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_cjk_cjkanalyzer_ +#define _lucene_analysis_cjk_cjkanalyzer_ + +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF2(analysis,cjk) + +/** + * CJKTokenizer was modified from StopTokenizer which does a decent job for + * most European languages. It performs other token methods for double-byte + * Characters: the token will return at each two charactors with overlap match.
+ * Example: "java C1C2C3C4" will be segment to: "java" "C1C2" "C2C3" "C3C4" it + * also need filter filter zero length token ""
+ * for Digit: digit, '+', '#' will token as letter
+ * for more info on Asia language(Chinese Japanese Korean) text segmentation: + * please search google + * + * @author Che, Dong + */ +class CLUCENE_CONTRIBS_EXPORT CJKTokenizer: public CL_NS(analysis)::Tokenizer { +private: + /** word offset, used to imply which character(in ) is parsed */ + int32_t offset; + + /** the index used only for ioBuffer */ + int32_t bufferIndex; + + /** data length */ + int32_t dataLen; + + /** + * character buffer, store the characters which are used to compose
+ * the returned Token + */ + TCHAR buffer[LUCENE_MAX_WORD_LEN]; + + /** + * I/O buffer, used to store the content of the input(one of the
+ * members of Tokenizer) + */ + const TCHAR* ioBuffer; + + /** word type: single=>ASCII double=>non-ASCII word=>default */ + const TCHAR* tokenType; + + static const TCHAR* tokenTypeSingle; + static const TCHAR* tokenTypeDouble; + + /** + * tag: previous character is a cached double-byte character "C1C2C3C4" + * ----(set the C1 isTokened) C1C2 "C2C3C4" ----(set the C2 isTokened) + * C1C2 C2C3 "C3C4" ----(set the C3 isTokened) "C1C2 C2C3 C3C4" + */ + bool preIsTokened; + + + bool ignoreSurrogates; + +public: + /** + * Construct a token stream processing the given input. + * + * @param in I/O reader + */ + CJKTokenizer(CL_NS(util)::Reader* in); + + /** + * Returns the next token in the stream, or null at EOS. + * See http://java.sun.com/j2se/1.3/docs/api/java/lang/Character.UnicodeBlock.html + * for detail. + * + * @return Token + * + * @throws java.io.IOException - throw IOException when read error
+ * hanppened in the InputStream + * + */ + CL_NS(analysis)::Token* next(CL_NS(analysis)::Token* token); + + bool getIgnoreSurrogates(){ return ignoreSurrogates; }; + void setIgnoreSurrogates(bool ignoreSurrogates){ this->ignoreSurrogates = ignoreSurrogates; }; +}; + + + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.cpp b/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.cpp new file mode 100644 index 00000000000..b2fe172942f --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.cpp @@ -0,0 +1,149 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/analysis/standard/StandardTokenizer.h" +#include "CLucene/analysis/standard/StandardFilter.h" +#include "CLucene/util/StringBuffer.h" +#include "GermanAnalyzer.h" +#include "GermanStemmer.h" +#include "GermanStemFilter.h" + +CL_NS_USE(analysis) +CL_NS_USE2(analysis,de) +CL_NS_USE2(analysis,standard) + + const TCHAR GermanAnalyzer_DASZ[] = { 0x64, 0x61, 0xdf }; + const TCHAR GermanAnalyzer_FUER[] = { 0x66, 0xfc, 0x72 }; + const TCHAR* GermanAnalyzer_GERMAN_STOP_WORDS[] = { + _T("einer"), _T("eine"), _T("eines"), _T("einem"), _T("einen"), + _T("der"), _T("die"), _T("das"), _T("dass"), GermanAnalyzer_DASZ, + _T("du"), _T("er"), _T("sie"), _T("es"), + _T("was"), _T("wer"), _T("wie"), _T("wir"), + _T("und"), _T("oder"), _T("ohne"), _T("mit"), + _T("am"), _T("im"),_T("in"), _T("aus"), _T("auf"), + _T("ist"), _T("sein"), _T("war"), _T("wird"), + _T("ihr"), _T("ihre"), _T("ihres"), + _T("als"), GermanAnalyzer_FUER, _T("von"), _T("mit"), + _T("dich"), _T("dir"), _T("mich"), _T("mir"), + _T("mein"), _T("sein"), _T("kein"), + _T("durch"), _T("wegen"), _T("wird") + }; + + CL_NS(util)::ConstValueArray GermanAnalyzer::GERMAN_STOP_WORDS( GermanAnalyzer_GERMAN_STOP_WORDS, 48 ); + + class GermanAnalyzer::SavedStreams : public TokenStream { + public: + StandardTokenizer* tokenStream; + TokenStream* filteredTokenStream; + + SavedStreams():tokenStream(NULL), filteredTokenStream(NULL) + { + } + + void close(){} + Token* next(Token* token) {return NULL;} + }; + + GermanAnalyzer::GermanAnalyzer() { + exclusionSet = NULL; + stopSet = _CLNEW CLTCSetList; + StopFilter::fillStopTable(stopSet, GERMAN_STOP_WORDS.values); + } + + GermanAnalyzer::GermanAnalyzer(const TCHAR** stopwords) { + exclusionSet = NULL; + stopSet = _CLNEW CLTCSetList; + StopFilter::fillStopTable(stopSet, stopwords); + } + + GermanAnalyzer::GermanAnalyzer(CL_NS(analysis)::CLTCSetList* stopwords) { + exclusionSet = NULL; + stopSet = stopwords; + } + + GermanAnalyzer::GermanAnalyzer(const char* stopwordsFile, const char* enc) { + exclusionSet = NULL; + stopSet = WordlistLoader::getWordSet(stopwordsFile, enc); + } + + GermanAnalyzer::GermanAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool deleteReader) { + exclusionSet = NULL; + stopSet = WordlistLoader::getWordSet(stopwordsReader, NULL, deleteReader); + } + + GermanAnalyzer::~GermanAnalyzer() { + _CLLDELETE(stopSet); + _CLLDELETE(exclusionSet); + } + + void GermanAnalyzer::setStemExclusionTable(const TCHAR** exclusionlist) { + if (exclusionSet != NULL) { + exclusionSet->clear(); + } else { + exclusionSet = _CLNEW CLTCSetList; + } + + CL_NS(analysis)::StopFilter::fillStopTable(exclusionSet, exclusionlist); + } + + void GermanAnalyzer::setStemExclusionTable(CL_NS(analysis)::CLTCSetList* exclusionlist) { + if (exclusionSet != exclusionlist) { + _CLLDELETE(exclusionSet); + exclusionSet = exclusionlist; + } + } + + void GermanAnalyzer::setStemExclusionTable(const char* exclusionlistFile, const char* enc) { + exclusionSet = WordlistLoader::getWordSet(exclusionlistFile, enc, exclusionSet); + } + + void GermanAnalyzer::setStemExclusionTable(CL_NS(util)::Reader* exclusionlistReader, const bool deleteReader) { + exclusionSet = WordlistLoader::getWordSet(exclusionlistReader, exclusionSet, deleteReader); + } + + TokenStream* GermanAnalyzer::tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) { + TokenStream* result; + CL_NS(util)::BufferedReader* bufferedReader = reader->__asBufferedReader(); + + if ( bufferedReader == NULL ) + result = _CLNEW StandardTokenizer( _CLNEW CL_NS(util)::FilteredBufferedReader(reader, false), true ); + else + result = _CLNEW StandardTokenizer(bufferedReader); + + result = _CLNEW StandardFilter(result, true); + result = _CLNEW LowerCaseFilter(result, true); + result = _CLNEW StopFilter(result, true, stopSet); + result = _CLNEW GermanStemFilter(result, true, exclusionSet); + + return result; + } + + TokenStream* GermanAnalyzer::reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) + { + SavedStreams* streams = reinterpret_cast(getPreviousTokenStream()); + + if (streams == NULL) { + streams = _CLNEW SavedStreams(); + CL_NS(util)::BufferedReader* bufferedReader = reader->__asBufferedReader(); + + if ( bufferedReader == NULL ) + streams->tokenStream = _CLNEW StandardTokenizer( _CLNEW CL_NS(util)::FilteredBufferedReader(reader, false), true ); + else + streams->tokenStream = _CLNEW StandardTokenizer(bufferedReader); + + streams->filteredTokenStream = _CLNEW StandardFilter(streams->tokenStream, true); + streams->filteredTokenStream = _CLNEW LowerCaseFilter(streams->filteredTokenStream, true); + streams->filteredTokenStream = _CLNEW StopFilter(streams->filteredTokenStream, true, stopSet); + streams->filteredTokenStream = _CLNEW GermanStemFilter(streams->filteredTokenStream, true, exclusionSet); + setPreviousTokenStream(streams); + } else + streams->tokenStream->reset(reader); + + return streams->filteredTokenStream; + } diff --git a/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.h b/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.h new file mode 100644 index 00000000000..9c02073b512 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanAnalyzer.h @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_de_GermanAnalyzer +#define _lucene_analysis_de_GermanAnalyzer + +CL_NS_DEF2(analysis,de) + +/** + * Analyzer for German language. Supports an external list of stopwords (words that + * will not be indexed at all) and an external list of exclusions (word that will + * not be stemmed, but indexed). + * A default set of stopwords is used unless an alternative list is specified, the + * exclusion list is empty by default. + * + * + * @version $Id: GermanAnalyzer.java 564236 2007-08-09 15:21:19Z gsingers $ + */ +class CLUCENE_CONTRIBS_EXPORT GermanAnalyzer : public CL_NS(analysis)::Analyzer { +public: + + /** + * List of typical german stopwords. + */ + static CL_NS(util)::ConstValueArray GERMAN_STOP_WORDS; + +private: + + class SavedStreams; + + /** + * Contains the stopwords used with the StopFilter. + */ + CL_NS(analysis)::CLTCSetList* stopSet; + + /** + * Contains words that should be indexed but not stemmed. + */ + CL_NS(analysis)::CLTCSetList* exclusionSet; + +public: + + /** + * Builds an analyzer with the default stop words + * (GERMAN_STOP_WORDS). + */ + GermanAnalyzer(); + + /** + * Builds an analyzer with the given stop words. + */ + GermanAnalyzer(const TCHAR** stopWords); + + /** + * Builds an analyzer with the given stop words. + */ + GermanAnalyzer(CL_NS(analysis)::CLTCSetList* stopwords); + + /** + * Builds an analyzer with the given stop words. + */ + GermanAnalyzer(const char* stopwordsFile, const char* enc = NULL); + + /** + * Builds an analyzer with the given stop words. + */ + GermanAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool deleteReader = false); + + /** + */ + virtual ~GermanAnalyzer(); + + /** + * Builds an exclusionlist from an array of Strings. + */ + void setStemExclusionTable(const TCHAR** exclusionlist); + + /** + * Builds an exclusionlist from a Hashtable. + */ + void setStemExclusionTable(CL_NS(analysis)::CLTCSetList* exclusionlist); + + /** + * Builds an exclusionlist from the words contained in the given file. + */ + void setStemExclusionTable(const char* exclusionlistFile, const char* enc = NULL); + + /** + * Builds an exclusionlist from the words contained in the given file. + */ + void setStemExclusionTable(CL_NS(util)::Reader* exclusionlistReader, const bool deleteReader = false); + + /** + * Creates a TokenStream which tokenizes all the text in the provided Reader. + * + * @return A TokenStream build from a StandardTokenizer filtered with + * StandardFilter, LowerCaseFilter, StopFilter, GermanStemFilter + */ + virtual TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + virtual TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.cpp b/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.cpp new file mode 100644 index 00000000000..ad709514c0d --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.cpp @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/util/StringBuffer.h" +#include "GermanStemmer.h" +#include "GermanStemFilter.h" + +CL_NS_USE(analysis) +CL_NS_USE2(analysis,de) + + GermanStemFilter::GermanStemFilter(TokenStream* in, bool deleteTS) : + TokenFilter(in, deleteTS) + { + stemmer = _CLNEW GermanStemmer(); + exclusionSet = NULL; + } + + GermanStemFilter::GermanStemFilter(TokenStream* in, bool deleteTS, CLTCSetList* exclusionSet) : + TokenFilter(in, deleteTS) + { + stemmer = _CLNEW GermanStemmer(); + this->exclusionSet = exclusionSet; + } + + Token* GermanStemFilter::next(Token* t) { + if (input->next(t) == NULL) { + return NULL; + } else if (exclusionSet != NULL && exclusionSet->find(t->termBuffer()) != exclusionSet->end()) { // Check the exclusiontable + return t; + } else { + TCHAR* s = stemmer->stem(t->termBuffer(), t->termLength()); + // If not stemmed, dont waste the time creating a new token + if (_tcscmp(s, t->termBuffer()) != 0) { + t->setText(s); + } + return t; + } + } + + void GermanStemFilter::setStemmer(GermanStemmer* stemmer) { + if (stemmer != NULL && this->stemmer != stemmer) { + _CLLDELETE(this->stemmer); + this->stemmer = stemmer; + } + } + + /** + * Set an alternative exclusion list for this filter. + */ + void GermanStemFilter::setExclusionSet(CLTCSetList* exclusionSet) { + if (this->exclusionSet != exclusionSet) { + _CLLDELETE(exclusionSet); + this->exclusionSet = exclusionSet; + } + } diff --git a/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.h b/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.h new file mode 100644 index 00000000000..ab5366829a1 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanStemFilter.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_de_GermanStemFilter +#define _lucene_analysis_de_GermanStemFilter + +CL_NS_DEF2(analysis,de) + +/** + * A filter that stems German words. It supports a table of words that should + * not be stemmed at all. The stemmer used can be changed at runtime after the + * filter object is created (as long as it is a GermanStemmer). + */ +class CLUCENE_CONTRIBS_EXPORT GermanStemFilter : public CL_NS(analysis)::TokenFilter +{ +private: + + /** + * The actual token in the input stream. + */ + CL_NS(analysis)::Token* token; + GermanStemmer* stemmer; + CL_NS(analysis)::CLTCSetList* exclusionSet; + +public: + + GermanStemFilter(TokenStream* in, bool deleteTS = false); + + /** + * Builds a GermanStemFilter that uses an exclusiontable. + */ + GermanStemFilter(TokenStream* in, bool deleteTS, CL_NS(analysis)::CLTCSetList* exclusionSet); + + /** + * @return Returns the next token in the stream, or null at EOS + */ + virtual Token* next(Token* t); + + /** + * Set a alternative/custom GermanStemmer for this filter. + */ + void setStemmer(GermanStemmer* stemmer); + + /** + * Set an alternative exclusion list for this filter. + */ + void setExclusionSet(CL_NS(analysis)::CLTCSetList* exclusionSet); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/analysis/de/GermanStemmer.cpp b/src/contribs-lib/CLucene/analysis/de/GermanStemmer.cpp new file mode 100644 index 00000000000..e31d6f845e4 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanStemmer.cpp @@ -0,0 +1,213 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/StringBuffer.h" +#include "GermanStemmer.h" + +CL_NS_USE(util) +CL_NS_USE2(analysis,de) + + GermanStemmer::GermanStemmer() : + sb() { + } + + TCHAR* GermanStemmer::stem(const TCHAR* term, size_t length) { + if (length < 0) { + length = _tcslen(term); + } + + // Reset the StringBuffer. + sb.clear(); + sb.append(term, length); + + if (!isStemmable(sb.getBuffer(), sb.length())) + return sb.giveBuffer(); + + // Stemming starts here... + substitute(sb); + strip(sb); + optimize(sb); + resubstitute(sb); + removeParticleDenotion(sb); + + return sb.giveBuffer(); + } + + bool GermanStemmer::isStemmable(const TCHAR* term, size_t length) const { + if (length < 0) { + length = _tcslen(term); + } + for (size_t c = 0; c < length; c++) { + if (_istalpha(term[c]) == 0) + return false; + } + return true; + } + + void GermanStemmer::strip(StringBuffer& buffer) + { + bool doMore = true; + while ( doMore && buffer.length() > 3 ) { + if ( ( buffer.length() + substCount > 5 ) && + buffer.substringEquals( buffer.length() - 2, buffer.length(), _T("nd"), 2 ) ) + { + buffer.deleteChars( buffer.length() - 2, buffer.length() ); + } + else if ( ( buffer.length() + substCount > 4 ) && + buffer.substringEquals( buffer.length() - 2, buffer.length(), _T("em"), 2 ) ) { + buffer.deleteChars( buffer.length() - 2, buffer.length() ); + } + else if ( ( buffer.length() + substCount > 4 ) && + buffer.substringEquals( buffer.length() - 2, buffer.length(), _T("er"), 2 ) ) { + buffer.deleteChars( buffer.length() - 2, buffer.length() ); + } + else if ( buffer.charAt( buffer.length() - 1 ) == _T('e') ) { + buffer.deleteCharAt( buffer.length() - 1 ); + } + else if ( buffer.charAt( buffer.length() - 1 ) == _T('s') ) { + buffer.deleteCharAt( buffer.length() - 1 ); + } + else if ( buffer.charAt( buffer.length() - 1 ) == _T('n') ) { + buffer.deleteCharAt( buffer.length() - 1 ); + } + // "t" occurs only as suffix of verbs. + else if ( buffer.charAt( buffer.length() - 1 ) == _T('t') ) { + buffer.deleteCharAt( buffer.length() - 1 ); + } + else { + doMore = false; + } + } + } + + void GermanStemmer::optimize(StringBuffer& buffer) { + // Additional step for female plurals of professions and inhabitants. + if ( buffer.length() > 5 && buffer.substringEquals( buffer.length() - 5, buffer.length(), _T("erin*"), 5 ) ) { + buffer.deleteCharAt( buffer.length() -1 ); + strip( buffer ); + } + // Additional step for irregular plural nouns like "Matrizen -> Matrix". + if ( buffer.charAt( buffer.length() - 1 ) == ( _T('z') ) ) { + buffer.setCharAt( buffer.length() - 1, _T('x') ); + } + } + + void GermanStemmer::removeParticleDenotion(StringBuffer& buffer) { + if ( buffer.length() > 4 ) { + for ( size_t c = 0; c < buffer.length() - 3; c++ ) { + if ( buffer.substringEquals( c, c + 4, _T("gege"), 4 ) ) { + buffer.deleteChars( c, c + 2 ); + return; + } + } + } + } + + void GermanStemmer::substitute(StringBuffer& buffer) { + substCount = 0; + + for ( size_t i = 0; i < buffer.length(); i++ ) { +#ifdef _UCS2 + TCHAR c = buffer.charAt(i); +#else + unsigned char c = buffer.charAt(i); +#endif + // Replace the second char of a pair of the equal characters with an asterisk + if ( i > 0 && c == buffer.charAt ( i - 1 ) ) { + buffer.setCharAt( i, _T('*') ); + } + // Substitute Umlauts. + else if ( c == 0xe4 ) { + buffer.setCharAt( i, _T('a') ); + } + else if ( c == 0xf6 ) { + buffer.setCharAt( i, _T('o') ); + } + else if ( c == 0xfc ) { + buffer.setCharAt( i, _T('u') ); + } + // Fix bug so that 'ß' at the end of a word is replaced. + else if ( c == 0xdf ) { + buffer.setCharAt( i, _T('s') ); + buffer.insert( i + 1, _T('s') ); + substCount++; + } + // Take care that at least one character is left left side from the current one + if ( i < buffer.length() - 1 ) { + // Masking several common character combinations with an token + if ( ( i < buffer.length() - 2 ) && c == _T('s') && + buffer.charAt( i + 1 ) == _T('c') && buffer.charAt( i + 2 ) == _T('h') ) + { + buffer.setCharAt( i, _T('$') ); + buffer.deleteChars( i + 1, i + 3 ); + substCount =+ 2; + } + else if ( c == _T('c') && buffer.charAt( i + 1 ) == _T('h') ) { + buffer.setCharAt( i, 0xa7 ); // section sign in UTF-16 + buffer.deleteCharAt( i + 1 ); + substCount++; + } + else if ( c == _T('e') && buffer.charAt( i + 1 ) == _T('i') ) { + buffer.setCharAt( i, _T('%') ); + buffer.deleteCharAt( i + 1 ); + substCount++; + } + else if ( c == _T('i') && buffer.charAt( i + 1 ) == _T('e') ) { + buffer.setCharAt( i, _T('&') ); + buffer.deleteCharAt( i + 1 ); + substCount++; + } + else if ( c == _T('i') && buffer.charAt( i + 1 ) == _T('g') ) { + buffer.setCharAt( i, _T('#') ); + buffer.deleteCharAt( i + 1 ); + substCount++; + } + else if ( c == _T('s') && buffer.charAt( i + 1 ) == _T('t') ) { + buffer.setCharAt( i, _T('!') ); + buffer.deleteCharAt( i + 1 ); + substCount++; + } + } + } + } + + void GermanStemmer::resubstitute(StringBuffer& buffer) { + for ( size_t i = 0; i < buffer.length(); i++ ) { +#ifdef _UCS2 + TCHAR c = buffer.charAt(i); +#else + unsigned char c = buffer.charAt(i); +#endif + if ( c == _T('*') ) { + buffer.setCharAt( i, buffer.charAt( i - 1 ) ); + } + else if ( c == _T('$') ) { + buffer.setCharAt( i, 's' ); + buffer.insert( i + 1, _T("ch"), 2 ); + } + else if ( c == 0xa7 ) { // section sign in UTF-16 + buffer.setCharAt( i, _T('c') ); + buffer.insert( i + 1, _T('h') ); + } + else if ( c == _T('%') ) { + buffer.setCharAt( i, _T('e') ); + buffer.insert( i + 1, _T('i') ); + } + else if ( c == _T('&') ) { + buffer.setCharAt( i, _T('i') ); + buffer.insert( i + 1, _T('e') ); + } + else if ( c == _T('#') ) { + buffer.setCharAt( i, _T('i') ); + buffer.insert( i + 1, _T('g') ); + } + else if ( c == _T('!') ) { + buffer.setCharAt( i, _T('s') ); + buffer.insert( i + 1, _T('t') ); + } + } + } diff --git a/src/contribs-lib/CLucene/analysis/de/GermanStemmer.h b/src/contribs-lib/CLucene/analysis/de/GermanStemmer.h new file mode 100644 index 00000000000..5743e94adc6 --- /dev/null +++ b/src/contribs-lib/CLucene/analysis/de/GermanStemmer.h @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_de_GermanStemmer +#define _lucene_analysis_de_GermanStemmer + +CL_CLASS_DEF(util,StringBuffer) + +CL_NS_DEF2(analysis,de) + +/** + * A stemmer for German words. The algorithm is based on the report + * "A Fast and Simple Stemming Algorithm for German Words" by Jörg + * Caumanns (joerg.caumanns at isst.fhg.de). + */ +class CLUCENE_CONTRIBS_EXPORT GermanStemmer +{ +private: + + /** + * Buffer for the terms while stemming them. + */ + CL_NS(util)::StringBuffer sb; + + /** + * Amount of characters that are removed with substitute() while stemming. + */ + int substCount; + +public: + + /** + */ + GermanStemmer(); + + /** + * Stemms the given term to an unique discriminator. + * + * @param term The term that should be stemmed. + * @return Discriminator for term + */ + TCHAR* stem(const TCHAR* term, size_t length = -1); + +private: + + /** + * Checks if a term could be stemmed. + * + * @return true if, and only if, the given term consists in letters. + */ + bool isStemmable(const TCHAR* term, size_t length = -1) const; + + /** + * suffix stripping (stemming) on the current term. The stripping is reduced + * to the seven "base" suffixes "e", "s", "n", "t", "em", "er" and * "nd", + * from which all regular suffixes are build of. The simplification causes + * some overstemming, and way more irregular stems, but still provides unique. + * discriminators in the most of those cases. + * The algorithm is context free, except of the length restrictions. + */ + void strip(CL_NS(util)::StringBuffer& buffer); + + /** + * Does some optimizations on the term. This optimisations are + * contextual. + */ + void optimize(CL_NS(util)::StringBuffer& buffer); + + /** + * Removes a particle denotion ("ge") from a term. + */ + void removeParticleDenotion(CL_NS(util)::StringBuffer& buffer); + + /** + * Do some substitutions for the term to reduce overstemming: + * + * - Substitute Umlauts with their corresponding vowel: äöü -> aou, + * "ß" is substituted by "ss" + * - Substitute a second char of a pair of equal characters with + * an asterisk: ?? -> ?* + * - Substitute some common character combinations with a token: + * sch/ch/ei/ie/ig/st -> $/§/%/&/#/! + */ + void substitute(CL_NS(util)::StringBuffer& buffer); + + /** + * Undoes the changes made by substitute(). That are character pairs and + * character combinations. Umlauts will remain as their corresponding vowel, + * as "ß" remains as "ss". + */ + void resubstitute(CL_NS(util)::StringBuffer& buffer); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/highlighter/Encoder.cpp b/src/contribs-lib/CLucene/highlighter/Encoder.cpp new file mode 100644 index 00000000000..9541c35f8bc --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Encoder.cpp @@ -0,0 +1,19 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "Encoder.h" + diff --git a/src/contribs-lib/CLucene/highlighter/Encoder.h b/src/contribs-lib/CLucene/highlighter/Encoder.h new file mode 100644 index 00000000000..b91ab29423d --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Encoder.h @@ -0,0 +1,56 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _lucene_search_highlight_encoder_ +#define _lucene_search_highlight_encoder_ + + +CL_NS_DEF2(search,highlight) + +/** + * Encodes original text. The Encoder works with the Formatter to generate the output. + * + */ +class CLUCENE_CONTRIBS_EXPORT Encoder:LUCENE_BASE +{ +public: + /** Virtual destructor */ + virtual ~Encoder(){ + } + + /** + * @param originalText The section of text being output + */ + virtual TCHAR* encodeText(TCHAR* originalText) = 0; +}; + +/** + * Simple {@link Encoder} implementation that does not modify the output + * @author Nicko Cadell + * + */ +class DefaultEncoder: public Encoder +{ +public: + TCHAR* encodeText(TCHAR* originalText) + { + return STRDUP_TtoT(originalText); + } +}; + + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/Formatter.cpp b/src/contribs-lib/CLucene/highlighter/Formatter.cpp new file mode 100644 index 00000000000..88b8a0ed265 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Formatter.cpp @@ -0,0 +1,18 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "Formatter.h" diff --git a/src/contribs-lib/CLucene/highlighter/Formatter.h b/src/contribs-lib/CLucene/highlighter/Formatter.h new file mode 100644 index 00000000000..39c3315dfaa --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Formatter.h @@ -0,0 +1,49 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_formatter_ +#define _lucene_search_highlight_formatter_ + +CL_NS_DEF2(search,highlight) +class TokenGroup; + +/** + * Processes terms found in the original text, typically by applying some form + * of mark-up to highlight terms in HTML search results pages. + * + */ +class CLUCENE_CONTRIBS_EXPORT Formatter:LUCENE_BASE +{ +public: + + /** Virtual destructor */ + virtual ~Formatter(){ + } + + /** + * @param originalText The section of text being considered for markup + * @param tokenGroup contains one or several overlapping Tokens along with + * their scores and positions. + */ + virtual TCHAR* highlightTerm(const TCHAR* originalTermText, const TokenGroup* tokenGroup) = 0; +}; + +CL_NS_END2 + +#endif + + + diff --git a/src/contribs-lib/CLucene/highlighter/Fragmenter.cpp b/src/contribs-lib/CLucene/highlighter/Fragmenter.cpp new file mode 100644 index 00000000000..5d174b4dace --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Fragmenter.cpp @@ -0,0 +1,19 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "Fragmenter.h" + diff --git a/src/contribs-lib/CLucene/highlighter/Fragmenter.h b/src/contribs-lib/CLucene/highlighter/Fragmenter.h new file mode 100644 index 00000000000..5a1b8c4797c --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Fragmenter.h @@ -0,0 +1,52 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_fragmenter_ +#define _lucene_search_highlight_fragmenter_ + + +CL_CLASS_DEF(analysis, Token) + +CL_NS_DEF2(search,highlight) + +/** + * Implements the policy for breaking text into multiple fragments for consideration + * by the {@link Highlighter} class. A sophisticated implementation may do this on the basis + * of detecting end of sentences in the text. + */ +class CLUCENE_CONTRIBS_EXPORT Fragmenter:LUCENE_BASE +{ +public: + /** Virtual destructor */ + virtual ~Fragmenter(){ + } + + /** + * Initializes the Fragmenter + * @param originalText + */ + virtual void start(const TCHAR* originalText) = 0; + + /** + * Test to see if this token from the stream should be held in a new TextFragment + * @param nextToken + */ + virtual bool isNewFragment(const CL_NS(analysis)::Token * nextToken) = 0; +}; + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/HighlightScorer.h b/src/contribs-lib/CLucene/highlighter/HighlightScorer.h new file mode 100644 index 00000000000..ed739989cb9 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/HighlightScorer.h @@ -0,0 +1,63 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_highlighterscorer_ +#define _lucene_search_highlight_highlighterscorer_ + + +CL_CLASS_DEF(analysis, Token) +//#include "TextFragment.h" + +CL_NS_DEF2(search,highlight) +class TextFragment; + +/** + * Adds to the score for a fragment based on its tokens + */ +class CLUCENE_CONTRIBS_EXPORT HighlightScorer:LUCENE_BASE +{ +public: + virtual ~HighlightScorer(){ + } + + /** + * called when a new fragment is started for consideration + * @param newFragment + */ + virtual void startFragment(TextFragment* newFragment) = 0; + + /** + * Called for each token in the current fragment + * @param token The token to be scored + * @return a score which is passed to the Highlighter class to influence the mark-up of the text + * (this return value is NOT used to score the fragment) + */ + virtual float_t getTokenScore(CL_NS(analysis)::Token* token) = 0; + + + /** + * Called when the highlighter has no more tokens for the current fragment - the scorer returns + * the weighting it has derived for the most recent fragment, typically based on the tokens + * passed to getTokenScore(). + * + */ + virtual float_t getFragmentScore() = 0; +}; + +CL_NS_END2 +#endif + + diff --git a/src/contribs-lib/CLucene/highlighter/Highlighter.cpp b/src/contribs-lib/CLucene/highlighter/Highlighter.cpp new file mode 100644 index 00000000000..5a8401c158d --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Highlighter.cpp @@ -0,0 +1,525 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "Highlighter.h" +#include "TokenGroup.h" +#include "Encoder.h" +#include "Scorer.h" +#include "Formatter.h" +#include "HighlightScorer.h" +#include "Fragmenter.h" +#include "TextFragment.h" +#include "SimpleFragmenter.h" +#include "SimpleHTMLFormatter.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/util/PriorityQueue.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/CLStreams.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(analysis) +CL_NS_USE(util) + + class FragmentQueue : public CL_NS(util)::PriorityQueue > + { + public: + FragmentQueue(int32_t size) + { + initialize(size, true); + } + + protected: + bool lessThan(TextFragment * fragA, TextFragment * fragB) + { + if (fragA->getScore() == fragB->getScore()) + return fragA->getFragNum() > fragB->getFragNum(); + else + return fragA->getScore() < fragB->getScore(); + } + }; + + + Highlighter::Highlighter(HighlightScorer * fragmentScorer): + delete_textFragmenter(true), + delete_fragmentScorer(false), + delete_formatter(true), + delete_encoder(true) + { + maxDocBytesToAnalyze = DEFAULT_MAX_DOC_BYTES_TO_ANALYZE; + + _textFragmenter = _CLNEW SimpleFragmenter(); + _fragmentScorer = fragmentScorer; + _formatter = _CLNEW SimpleHTMLFormatter(); + _encoder = _CLNEW DefaultEncoder(); + } + + Highlighter::Highlighter(Formatter * formatter, HighlightScorer * fragmentScorer): + delete_textFragmenter(true), + delete_fragmentScorer(false), + delete_formatter(false), + delete_encoder(true) + { + maxDocBytesToAnalyze = DEFAULT_MAX_DOC_BYTES_TO_ANALYZE; + + _textFragmenter = _CLNEW SimpleFragmenter(); + _fragmentScorer = fragmentScorer; + _formatter = formatter; + _encoder = _CLNEW DefaultEncoder(); + } + + Highlighter::Highlighter(Formatter * formatter, Encoder* encoder, HighlightScorer * fragmentScorer): + delete_textFragmenter(true), + delete_fragmentScorer(false), + delete_formatter(false), + delete_encoder(false) + { + maxDocBytesToAnalyze = DEFAULT_MAX_DOC_BYTES_TO_ANALYZE; + _textFragmenter = _CLNEW SimpleFragmenter(); + _fragmentScorer = fragmentScorer; + _formatter = formatter; + _encoder = encoder; + } + + Highlighter::~Highlighter() + { + if ( delete_textFragmenter ) + _CLDELETE ( _textFragmenter ); + + if ( delete_fragmentScorer ) + _CLDELETE(_fragmentScorer); + + if( delete_formatter ) + _CLDELETE(_formatter); + + if ( delete_encoder ) + _CLDELETE(_encoder); + } + + TCHAR* Highlighter::getBestFragment(TokenStream * tokenStream, const TCHAR* text) + { + TCHAR** results = getBestFragments(tokenStream,text, 1); + TCHAR* result = 0; + + if (results[0] != NULL ) + result = stringDuplicate(results[0]); + + _CLDELETE_CARRAY_ALL(results); + + return result; + } + + /** + * Highlights chosen terms in a text, extracting the most relevant section. + * This is a convenience method that calls + * {@link #getBestFragment(TokenStream, const TCHAR*)} + * + * @param analyzer the analyzer that will be used to split text + * into chunks + * @param text text to highlight terms in + * @param fieldName Name of field used to influence analyzer's tokenization policy + * + * @return highlighted text fragment or NULL if no terms found + */ + TCHAR* Highlighter::getBestFragment(Analyzer* analyzer, const TCHAR* fieldName, const TCHAR* text) + { + TokenStream* tokenStream = analyzer->tokenStream(fieldName, _CLNEW StringReader(text)); + return getBestFragment(tokenStream, text); + } + + TCHAR** Highlighter::getBestFragments( + TokenStream * tokenStream, + const TCHAR* text, + int32_t maxNumFragments) + { + maxNumFragments = cl_max((int32_t)1, maxNumFragments); //sanity check + + StringBuffer buffer; + TextFragment** frags = getBestTextFragments(&buffer,tokenStream,text, true,maxNumFragments); + + //Get text + std::vector fragTexts; + for (uint32_t i=0; frags[i]!=NULL; i++) + { + TextFragment* f = frags[i]; + if ((f != NULL) && (f->getScore() > 0)) + { + fragTexts.push_back(f->toString(&buffer)); + } + _CLDELETE(f); + } + + _CLDELETE_ARRAY(frags); + + size_t l = fragTexts.size(); + TCHAR** ret = _CL_NEWARRAY(TCHAR*,l+1); + for ( size_t j=0;j 0) + { + result.append(separator); + } + result.append(sections[i]); + } + + _CLDELETE_CARRAY_ALL(sections); + return result.toString(); + } + + TextFragment** Highlighter::getBestTextFragments( + StringBuffer* writeTo, + TokenStream * tokenStream, + const TCHAR* text, + bool mergeContiguousFragments, + int32_t maxNumFragments) + { + CLArrayList docFrags(false); + TextFragment* currentFrag = _CLNEW TextFragment(writeTo->length(), docFrags.size()); + _fragmentScorer->startFragment(currentFrag); + docFrags.push_back(currentFrag); + + FragmentQueue fragQueue(maxNumFragments); + + try + { + int32_t startOffset; + int32_t endOffset; + int32_t lastEndOffset = 0; + _textFragmenter->start(text); + TCHAR substringBuffer[LUCENE_MAX_WORD_LEN]; + + TokenGroup* tokenGroup=_CLNEW TokenGroup(); + + TCHAR buffer[LUCENE_MAX_FIELD_LEN+1]; + Token token; + while ( tokenStream->next(&token) ) + { + if((tokenGroup->getNumTokens()>0)&&(tokenGroup->isDistinct(&token))){ + //the current token is distinct from previous tokens - + // markup the cached token group info + startOffset = tokenGroup->getStartOffset(); + endOffset = tokenGroup->getEndOffset(); + + _tcsncpy(substringBuffer,text+startOffset,endOffset-startOffset); + substringBuffer[endOffset-startOffset]=_T('\0'); + + TCHAR* encoded = _encoder->encodeText(substringBuffer); + TCHAR* markedUpText=_formatter->highlightTerm(encoded, tokenGroup); + _CLDELETE_CARRAY(encoded); + + //store any whitespace etc from between this and last group + if (startOffset > lastEndOffset){ + int len = startOffset-lastEndOffset; + if ( len > LUCENE_MAX_FIELD_LEN ) + len = LUCENE_MAX_FIELD_LEN; + _tcsncpy(buffer,text+lastEndOffset,len); + buffer[len]=_T('\0'); + + TCHAR* encoded = _encoder->encodeText(buffer); + writeTo->append(encoded); + _CLDELETE_CARRAY(encoded); + } + writeTo->append(markedUpText); + lastEndOffset=endOffset; + tokenGroup->clear(); + _CLDELETE_CARRAY(markedUpText); + + //check if current token marks the start of a new fragment + if (_textFragmenter->isNewFragment(&token)) + { + currentFrag->setScore(_fragmentScorer->getFragmentScore()); + //record stats for a new fragment + currentFrag->setTextEndPos( writeTo->length() ); + currentFrag =_CLNEW TextFragment(writeTo->length(), docFrags.size()); + _fragmentScorer->startFragment(currentFrag); + docFrags.push_back(currentFrag); + } + } + + // does query contain current token? + float_t score=_fragmentScorer->getTokenScore(&token); + //TCHAR* highlightedTerm = _formatter->highlightTerm(&substringBuffer, token->termText(), score, startOffset); + //newText->append(highlightedTerm); + //_CLDELETE_CARRAY(highlightedTerm); + //_CLDELETE(token); + + tokenGroup->addToken(&token,_fragmentScorer->getTokenScore(&token)); + + if(lastEndOffset>maxDocBytesToAnalyze) + { + break; + } + } + currentFrag->setScore(_fragmentScorer->getFragmentScore()); + + if(tokenGroup->getNumTokens()>0) + { + //flush the accumulated text (same code as in above loop) + startOffset = tokenGroup->getStartOffset(); + endOffset = tokenGroup->getEndOffset(); + + _tcsncpy(substringBuffer,text+startOffset,endOffset-startOffset); + substringBuffer[endOffset-startOffset]=_T('\0'); + + TCHAR* encoded = _encoder->encodeText(substringBuffer); + TCHAR* markedUpText=_formatter->highlightTerm(encoded, tokenGroup); + _CLDELETE_CARRAY(encoded); + + //store any whitespace etc from between this and last group + if (startOffset > lastEndOffset){ + int len = startOffset-lastEndOffset; + if ( len > LUCENE_MAX_FIELD_LEN ) + len = LUCENE_MAX_FIELD_LEN; + _tcsncpy(buffer,text+lastEndOffset,len); + buffer[len]=_T('\0'); + + TCHAR* encoded = _encoder->encodeText(buffer); + writeTo->append(encoded); + _CLDELETE_CARRAY(encoded); + } + writeTo->append(markedUpText); + lastEndOffset=endOffset; + + _CLDELETE_CARRAY(markedUpText); + } + + // append text after end of last token + //if (lastEndOffset < (int32_t)_tcslen(text)) + //newText->append(text+lastEndOffset); + + currentFrag->setTextEndPos(writeTo->length()); + + //sort the most relevant sections of the text + while (docFrags.size() > 0) { + //for (TextFragmentList::iterator i = docFrags.begin(); i != docFrags.end(); i++) + //{ + currentFrag = (TextFragment*) docFrags[0]; + docFrags.remove(0); + + //If you are running with a version of Lucene before 11th Sept 03 + // you do not have PriorityQueue.insert() - so uncomment the code below + + /*if (currentFrag->getScore() >= minScore) + { + fragQueue.put(currentFrag); + if (fragQueue.size() > maxNumFragments) + { // if hit queue overfull + _CLLDELETE(fragQueue.pop()); // remove lowest in hit queue + minScore = ((TextFragment *) fragQueue.top())->getScore(); // reset minScore + } + + + } else { + _CLDELETE(currentFrag); + }*/ + + //The above code caused a problem as a result of Christoph Goller's 11th Sept 03 + //fix to PriorityQueue. The correct method to use here is the new "insert" method + // USE ABOVE CODE IF THIS DOES NOT COMPILE! + if ( !fragQueue.insert(currentFrag) ) + _CLDELETE(currentFrag); + + //todo: check this + } + + //return the most relevant fragments + int32_t fragsLen = fragQueue.size(); + TextFragment** frags = _CL_NEWARRAY(TextFragment*,fragsLen+1); + for ( int32_t i=0;i fragTexts; + for (int32_t i = 0; i < fragsLen; i++) + { + TextFragment* tf = frags[i]; + if ((tf != NULL) && (tf->getScore() > 0)) + fragTexts.push_back(tf); + else + _CLDELETE(tf); + } + _CLDELETE_ARRAY(frags); + frags = _CL_NEWARRAY(TextFragment*,fragTexts.size()+1); + fragTexts.toArray_nullTerminated(frags); + } + + _CLDELETE(tokenGroup); + //_CLDELETE(newText); + return frags; + + } + _CLFINALLY( + if (tokenStream) + { + try + { + tokenStream->close(); + } + catch (...) + { + } + } + ) + } + + + void Highlighter::_mergeContiguousFragments(TextFragment** frag, int32_t fragsLen) + { + bool mergingStillBeingDone; + if ( frag[0] != NULL ) + do + { + mergingStillBeingDone = false; //initialise loop control flag + //for each fragment, scan other frags looking for contiguous blocks + for (int32_t i=0; ifollows(frag[x])) + { + frag1 = frag[x]; + frag1Num = x; + frag2 = frag[i]; + frag2Num = i; + } + else if (frag[x]->follows(frag[i])) + { + frag1 = frag[i]; + frag1Num = i; + frag2 = frag[x]; + frag2Num = x; + } + //merging required.. + if (frag1 != NULL) + { + if (frag1->getScore() > frag2->getScore()) + { + bestScoringFragNum = frag1Num; + worstScoringFragNum = frag2Num; + } + else + { + bestScoringFragNum = frag2Num; + worstScoringFragNum = frag1Num; + } + frag1->merge(frag2); + frag[worstScoringFragNum]= NULL; + mergingStillBeingDone = true; + frag[bestScoringFragNum]=frag1; + _CLDELETE(frag2); + } + } + } + } + while (mergingStillBeingDone); + } + + int32_t Highlighter::getMaxDocBytesToAnalyze() + { + return maxDocBytesToAnalyze; + } + + void Highlighter::setMaxDocBytesToAnalyze(int32_t byteCount) + { + maxDocBytesToAnalyze = byteCount; + } + + Fragmenter * Highlighter::getTextFragmenter() + { + return _textFragmenter; + } + + void Highlighter::setTextFragmenter(Fragmenter * fragmenter) + { + if ( delete_textFragmenter ){ + _CLDELETE(_textFragmenter); + delete_textFragmenter = false; + } + _textFragmenter = fragmenter; + } + + HighlightScorer * Highlighter::getFragmentScorer() + { + return _fragmentScorer; + } + + + void Highlighter::setFragmentScorer(HighlightScorer * scorer) + { + if ( delete_fragmentScorer ){ + delete_fragmentScorer = false; + _CLDELETE(scorer); + } + _fragmentScorer = scorer; + } + + + Encoder* Highlighter::getEncoder() + { + return _encoder; + } + void Highlighter::setEncoder(Encoder* encoder) + { + if ( delete_encoder ){ + _CLDELETE(encoder); + delete_encoder = false; + } + this->_encoder = encoder; + } + + + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/Highlighter.h b/src/contribs-lib/CLucene/highlighter/Highlighter.h new file mode 100644 index 00000000000..99f3f8e3f60 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Highlighter.h @@ -0,0 +1,226 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_highlighter_ +#define _lucene_search_highlight_highlighter_ + + + +CL_CLASS_DEF(util, StringBuffer) +//#include "CLucene/util/VoidList.h" +CL_CLASS_DEF2(search,highlight,Formatter) +CL_CLASS_DEF2(search,highlight,Encoder) +CL_CLASS_DEF2(search,highlight,HighlightScorer) +CL_CLASS_DEF2(search,highlight,Fragmenter) +CL_CLASS_DEF2(search,highlight,TextFragment) +CL_CLASS_DEF(analysis, TokenStream) +CL_CLASS_DEF(analysis, Analyzer) + +//#include "HighlightScorer.h" +//#include "SimpleFragmenter.h" +//#include "TextFragment.h" + +CL_NS_DEF2(search,highlight) + +/** +* Class used to markup highlighted terms found in the best sections of a +* text, using configurable {@link Fragmenter}, {@link Scorer}, {@link Formatter}, +* and tokenizers. +* {@link Encoder} and tokenizers. +*/ +class CLUCENE_CONTRIBS_EXPORT Highlighter :LUCENE_BASE +{ +private: + int32_t maxDocBytesToAnalyze; + + Formatter * _formatter; + bool delete_formatter; + + Encoder* _encoder; + bool delete_encoder; + + Fragmenter * _textFragmenter; + bool delete_textFragmenter; + + HighlightScorer * _fragmentScorer; + bool delete_fragmentScorer; + + /** Improves readability of a score-sorted list of TextFragments by merging any fragments + * that were contiguous in the original text into one larger fragment with the correct order. + * This will leave a "null" in the array entry for the lesser scored fragment. + * + * @param frag An array of document fragments in descending score + */ + void _mergeContiguousFragments(TextFragment** frag, int32_t fragsLen); + +public: + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_DOC_BYTES_TO_ANALYZE=50*1024); + + /** + * Constructs a Highlighter object with the provided scorer. The HighlightScorer object is owned + * by the Highlighter object, and it will freed in the destructor. + */ + Highlighter(HighlightScorer * fragmentScorer); + + Highlighter(Formatter * formatter, HighlightScorer * fragmentScorer); + + Highlighter(Formatter * formatter, Encoder* encoder, HighlightScorer * fragmentScorer); + + + /** + * Destructor for Highlighter. It deletes the owned HighlightScorer, formatter and textFragmenter. + */ + ~Highlighter(); + + /** + * Highlights chosen terms in a text, extracting the most relevant section. + * The document text is analysed in chunks to record hit statistics + * across the document. After accumulating stats, the fragment with the highest score + * is returned + * + * @param tokenStream a stream of tokens identified in the text parameter, including offset information. + * This is typically produced by an analyzer re-parsing a document's + * text. Some work may be done on retrieving TokenStreams more efficently + * by adding support for storing original text position data in the Lucene + * index but this support is not currently available (as of Lucene 1.4 rc2). + * @param text text to highlight terms in + * + * @return highlighted text fragment or null if no terms found + */ + TCHAR* getBestFragment(CL_NS(analysis)::TokenStream * tokenStream, const TCHAR* text); + + /** + * Highlights chosen terms in a text, extracting the most relevant section. + * This is a convenience method that calls + * {@link #getBestFragment(TokenStream, const TCHAR*)} + * + * @param analyzer the analyzer that will be used to split text + * into chunks + * @param text text to highlight terms in + * @param fieldName Name of field used to influence analyzer's tokenization policy + * + * @return highlighted text fragment or null if no terms found + */ + TCHAR* getBestFragment(CL_NS(analysis)::Analyzer* analyzer, const TCHAR* fieldName, const TCHAR* text); + + /** + * Highlights chosen terms in a text, extracting the most relevant sections. + * This is a convenience method that calls + * {@link #getBestFragments(TokenStream, const TCHAR*, int)} + * + * @param analyzer the analyzer that will be used to split text + * into chunks + * @param text text to highlight terms in + * @param maxNumFragments the maximum number of fragments. + * + * @return highlighted text fragments (between 0 and maxNumFragments number of fragments) + */ + TCHAR** getBestFragments( + CL_NS(analysis)::Analyzer* analyzer, + const TCHAR* text, + int32_t maxNumFragments); + + /** + * Highlights chosen terms in a text, extracting the most relevant sections. + * The document text is analysed in chunks to record hit statistics + * across the document. After accumulating stats, the fragments with the highest scores + * are returned as an array of strings in order of score (contiguous fragments are merged into + * one in their original order to improve readability) + * + * @param text text to highlight terms in + * @param maxNumFragments the maximum number of fragments. + * + * @return highlighted text fragments (between 0 and maxNumFragments number of fragments) + */ + TCHAR** getBestFragments( + CL_NS(analysis)::TokenStream * tokenStream, + const TCHAR* text, + int32_t maxNumFragments); + + /** + * Low level api to get the most relevant (formatted) sections of the document. + * This method has been made public to allow visibility of score information held in TextFragment objects. + * Thanks to Jason Calabrese for help in redefining the interface. + * @param tokenStream + * @param text + * @param maxNumFragments + * @param mergeContiguousFragments + */ + TextFragment** getBestTextFragments( + CL_NS(util)::StringBuffer* writeTo, + CL_NS(analysis)::TokenStream * tokenStream, + const TCHAR* text, + bool mergeContiguousFragments, + int32_t maxNumFragments); + + /** + * Highlights terms in the text , extracting the most relevant sections + * and concatenating the chosen fragments with a separator (typically "..."). + * The document text is analysed in chunks to record hit statistics + * across the document. After accumulating stats, the fragments with the highest scores + * are returned in order as "separator" delimited strings. + * + * @param text text to highlight terms in + * @param maxNumFragments the maximum number of fragments. + * @param separator the separator used to intersperse the document fragments (typically "...") + * + * @return highlighted text + */ + TCHAR* getBestFragments( + CL_NS(analysis)::TokenStream * tokenStream, + const TCHAR* text, + int32_t maxNumFragments, + const TCHAR* separator); + + /** + * @return the maximum number of bytes to be tokenized per doc + */ + int32_t getMaxDocBytesToAnalyze(); + + /** + * @param byteCount the maximum number of bytes to be tokenized per doc + * (This can improve performance with large documents) + */ + void setMaxDocBytesToAnalyze(int32_t byteCount); + + /** + */ + Fragmenter * getTextFragmenter(); + + /** + * @param fragmenter + */ + void setTextFragmenter(Fragmenter * fragmenter); + + /** + * @return Object used to score each text fragment + */ + HighlightScorer * getFragmentScorer(); + + /** + * @param HighlightScorer + */ + void setFragmentScorer(HighlightScorer * scorer); + + Encoder* getEncoder(); + void setEncoder(Encoder* encoder); +}; + + +CL_NS_END2 + +#endif + diff --git a/src/contribs-lib/CLucene/highlighter/QueryScorer.cpp b/src/contribs-lib/CLucene/highlighter/QueryScorer.cpp new file mode 100644 index 00000000000..3ae172265a7 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/QueryScorer.cpp @@ -0,0 +1,118 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "QueryScorer.h" +#include "WeightedTerm.h" +#include "QueryTermExtractor.h" +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(index) +CL_NS_USE(analysis) + + QueryScorer::QueryScorer(const Query * query): + _termsToFind(false,true), + _uniqueTermsInFragment(true) + { + WeightedTerm** _weighted_terms = QueryTermExtractor::getTerms(query); + initialize(_weighted_terms); + _CLDELETE_ARRAY(_weighted_terms); + } + QueryScorer::~QueryScorer() + { + } + +/* QueryScorer(Query* query, CL_NS(index)::IndexReader* reader, const TCHAR* fieldName) + { + WeightedTerm** _weighted_terms = QueryTermExtractor.getIdfWeightedTerms(query, reader, fieldName); + initialize(_weighted_terms); + }*/ + + + QueryScorer::QueryScorer(WeightedTerm** weightedTerms) + { + initialize(weightedTerms); + } + + void QueryScorer::initialize(WeightedTerm** weightedTerms) + { + _currentTextFragment = NULL; + _totalScore = 0; + _maxTermWeight = 0; + + // Copy external weighted terms + int i=0; + while ( weightedTerms[i] != NULL ){ + const WeightedTerm* existingTerm=_termsToFind.get(weightedTerms[i]->getTerm()); + if( (existingTerm==NULL) ||(existingTerm->getWeight()getWeight()) ) + { + //if a term is defined more than once, always use the highest scoring weight + WeightedTerm* term = weightedTerms[i]; + _termsToFind.put(term->getTerm(), term); + + _maxTermWeight=cl_max(_maxTermWeight,weightedTerms[i]->getWeight()); + }else + _CLDELETE(weightedTerms[i]); + + i++; + } + } + + void QueryScorer::startFragment(TextFragment * newFragment) + { + _uniqueTermsInFragment.clear(); + _currentTextFragment=newFragment; + _totalScore=0; + + } + + float_t QueryScorer::getTokenScore(Token * token) + { + const TCHAR* termText=token->termBuffer(); + + const WeightedTerm* queryTerm = _termsToFind.get(termText); + if(queryTerm==NULL) + { + //not a query term - return + return 0; + } + //found a query term - is it unique in this doc? + if(_uniqueTermsInFragment.find((TCHAR*)termText)==_uniqueTermsInFragment.end()) + { + _totalScore+=queryTerm->getWeight(); + TCHAR* owned_term = stringDuplicate(termText); + _uniqueTermsInFragment.insert(owned_term); + } + return queryTerm->getWeight(); + } + + /** + * + * @return The highest weighted term (useful for passing to GradientFormatter to set + * top end of coloring scale. + */ + float_t QueryScorer::getMaxTermWeight() + { + return _maxTermWeight; + } + + + float_t QueryScorer::getFragmentScore(){ + return _totalScore; + } + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/QueryScorer.h b/src/contribs-lib/CLucene/highlighter/QueryScorer.h new file mode 100644 index 00000000000..c89a6cf11e3 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/QueryScorer.h @@ -0,0 +1,114 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_queryscorer_ +#define _lucene_search_highlight_queryscorer_ + + +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF(search, Query) + +//#include "CLucene/search/SearchHeader.h" +//#include "TextFragment.h" + +#include "HighlightScorer.h" + +CL_NS_DEF2(search,highlight) + +class WeightedTerm; +class QueryTermExtractor; +class TextFragment; + +/** + * {@link Scorer} implementation which scores text fragments by the number of unique query terms found. + * This class uses the {@link QueryTermExtractor} class to process determine the query terms and + * their boosts to be used. + */ +//TODO: provide option to boost score of fragments near beginning of document +// based on fragment.getFragNum() +class CLUCENE_CONTRIBS_EXPORT QueryScorer : public HighlightScorer +{ +private: + TextFragment * _currentTextFragment; + CL_NS(util)::CLHashSet _uniqueTermsInFragment; + float_t _totalScore; + float_t _maxTermWeight; + CL_NS(util)::CLHashMap > _termsToFind; + +public: + /** + * + * @param query a Lucene query (ideally rewritten using query.rewrite + * before being passed to this class and the searcher) + */ + QueryScorer(const Query * query); + + /** + * + * @param query a Lucene query (ideally rewritten using query.rewrite + * before being passed to this class and the searcher) + * @param reader used to compute IDF which can be used to a) score selected fragments better + * b) use graded highlights eg set font color intensity + * @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based + */ + QueryScorer(const Query* query, CL_NS(index)::IndexReader* reader, const TCHAR* fieldName); + + QueryScorer(WeightedTerm** weightedTerms); + + ~QueryScorer(); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.FragmentScorer#startFragment(org.apache.lucene.search.highlight.TextFragment) + */ + void startFragment(TextFragment* newFragment); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.FragmentScorer#scoreToken(org.apache.lucene.analysis.Token) + */ + float_t getTokenScore(CL_NS(analysis)::Token * token); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.FragmentScorer#endFragment(org.apache.lucene.search.highlight.TextFragment) + */ + float_t getFragmentScore(); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.FragmentScorer#allFragmentsProcessed() + */ + void allFragmentsProcessed(); + + /** + * + * @return The highest weighted term (useful for passing to GradientFormatter to set + * top end of coloring scale. + */ + float_t getMaxTermWeight(); + +private: + void initialize(WeightedTerm** weightedTerms); + +}; + +CL_NS_END2 + +#endif + diff --git a/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.cpp b/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.cpp new file mode 100644 index 00000000000..d3fe0eef3b5 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.cpp @@ -0,0 +1,135 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "QueryTermExtractor.h" + +#include "CLucene/search/Query.h" +#include "CLucene/search/BooleanQuery.h" +#include "CLucene/search/TermQuery.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/Term.h" + +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); + +CL_NS_DEF2(search,highlight) +CL_NS_USE(index) + + WeightedTerm** QueryTermExtractor::getTerms(const Query * query, bool prohibited, const TCHAR* fieldName) + { + WeightedTermList terms(false); + getTerms(query,&terms,prohibited,fieldName); + + // Return extracted terms + WeightedTerm** ret = _CL_NEWARRAY(WeightedTerm*,terms.size()+1); + terms.toArray_nullTerminated(ret); + + return ret; + } + + void QueryTermExtractor::getTerms(const Query * query, WeightedTermList * terms, bool prohibited, const TCHAR* fieldName) + { + if (query->instanceOf( BooleanQuery::getClassName() )) + { + getTermsFromBooleanQuery((BooleanQuery *) query, terms, prohibited, fieldName); + } +// FilteredQuery not implemented yet +// else if (query->instanceOf( FilteredQuery::getClassName() )) +// getTermsFromFilteredQuery((FilteredQuery *) query, terms); + else + { + TermSet nonWeightedTerms; + query->extractTerms(&nonWeightedTerms); + for (TermSet::iterator iter = nonWeightedTerms.begin(); iter != nonWeightedTerms.end(); iter++) + { + Term * term = (Term *)(*iter); + if ( fieldName == NULL || term->field() == fieldName ) + terms->insert(_CLNEW WeightedTerm(query->getBoost(), term->text())); + _CLLDECDELETE( term ); + } + } + } + + /** + * Extracts all terms texts of a given Query into an array of WeightedTerms + * + * @param query Query to extract term texts from + * @param reader used to compute IDF which can be used to a) score selected fragments better + * b) use graded highlights eg chaning intensity of font color + * @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based + * @return an array of the terms used in a query, plus their weights. + */ + WeightedTerm** QueryTermExtractor::getIdfWeightedTerms(const Query* query, IndexReader* reader, const TCHAR* fieldName) + { + WeightedTermList terms(true); + getTerms(query,&terms,false,fieldName); + + int32_t totalNumDocs=reader->numDocs(); + + WeightedTermList::iterator itr = terms.begin(); + while ( itr != terms.end() ) + { + try + { + Term* term = _CLNEW Term(fieldName,(*itr)->getTerm()); + int32_t docFreq=reader->docFreq(term); + _CLDECDELETE(term); + + //IDF algorithm taken from DefaultSimilarity class + float_t idf=(float_t)(log(totalNumDocs/(float_t)(docFreq+1)) + 1.0); + (*itr)->setWeight((*itr)->getWeight() * idf); + }catch (CLuceneError& e){ + if ( e.number()!=CL_ERR_IO ) + throw e; + } + + itr++; + } + + // Return extracted terms + WeightedTerm** ret = _CL_NEWARRAY(WeightedTerm*,terms.size()+1); + terms.toArray_nullTerminated(ret); + + return ret; + } + + void QueryTermExtractor::getTermsFromBooleanQuery(const BooleanQuery * query, WeightedTermList * terms, bool prohibited, const TCHAR* fieldName) + { + uint32_t numClauses = query->getClauseCount(); + BooleanClause** queryClauses = _CL_NEWARRAY(BooleanClause*,numClauses); + query->getClauses(queryClauses); + + for (uint32_t i = 0; i < numClauses; i++) + { + if (prohibited || !queryClauses[i]->prohibited){ + Query* qry = queryClauses[i]->getQuery(); + getTerms(qry, terms, prohibited, fieldName); + } + } + _CLDELETE_ARRAY(queryClauses); + } + +// FilteredQuery not implemented yet +// void QueryTermExtractor::getTermsFromFilteredQuery(const FilteredQuery * query, WeightedTermList * terms, bool prohibited) +// { +// getTerms(query->getQuery(), terms, prohibited); +// } + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.h b/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.h new file mode 100644 index 00000000000..b66b7207612 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/QueryTermExtractor.h @@ -0,0 +1,82 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _lucene_search_highlight_querytermextractor_ +#define _lucene_search_highlight_querytermextractor_ + +CL_CLASS_DEF(search, Query) +CL_CLASS_DEF(search, BooleanQuery) +CL_CLASS_DEF(search, PhraseQuery) +CL_CLASS_DEF(search, TermQuery) +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF(index, Term) + +#include "WeightedTerm.h" + +CL_NS_DEF2(search,highlight) + +/** + * Utility class used to extract the terms used in a query, plus any weights. + * This class will not find terms for MultiTermQuery, RangeQuery and PrefixQuery classes + * so the caller must pass a rewritten query (see Query.rewrite) to obtain a list of + * expanded terms. + * + */ +class CLUCENE_CONTRIBS_EXPORT QueryTermExtractor +{ + QueryTermExtractor(){ + } +public: + + /** + * Extracts all terms texts of a given Query into an returned array of WeightedTerms + * + * @param query Query to extract term texts from + * @param prohibited true to extract "prohibited" terms, too + * @param fieldName field name used for filtering query terms, MUST be interned prior to this call + * @return an array of the terms used in a query, plus their weights.Memory owned by the caller + */ + static WeightedTerm** getTerms(const Query *query, bool prohibited = false, const TCHAR* fieldName = NULL); + + /** + * Extracts all terms texts of a given Query into an array of WeightedTerms + * + * @param query Query to extract term texts from + * @param reader used to compute IDF which can be used to a) score selected fragments better + * b) use graded highlights eg chaning intensity of font color + * @param fieldName the field on which Inverse Document Frequency (IDF) calculations are based + * @return an array of the terms used in a query, plus their weights. + */ + static WeightedTerm** getIdfWeightedTerms(const Query* query, CL_NS(index)::IndexReader* reader, const TCHAR* fieldName); + + /** + * Extracts all terms texts of a given Query into given array of WeightedTerms + * + * @param query Query to extract term texts from + * @param prohibited true to extract "prohibited" terms, too + * @param fieldName field name used for filtering query terms, MUST be interned prior to this call + * @return an array of the terms used in a query, plus their weights.Memory owned by the caller + */ + static void getTerms(const Query * query, WeightedTermList*, bool prohibited = false, const TCHAR* fieldName = NULL); + + static void getTermsFromBooleanQuery(const BooleanQuery * query, WeightedTermList* terms, bool prohibited, const TCHAR* fieldName); +// static void getTermsFromFilteredQuery(const FilteredQuery * query, WeightedTermList* terms); +}; + +CL_NS_END2 + + + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/Scorer.h b/src/contribs-lib/CLucene/highlighter/Scorer.h new file mode 100644 index 00000000000..7d558cab6f5 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/Scorer.h @@ -0,0 +1,61 @@ +#ifndef _lucene_search_highlight_scorer_h_ +#define _lucene_search_highlight_scorer_h_ + +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#include + +CL_NS_USE(analysis) + +/** + * Adds to the score for a fragment based on its tokens + */ +namespace lucene { namespace search { namespace highlight { + + class TextFragment; + +class CLUCENE_CONTRIBS_EXPORT Scorer +{ +public: + virtual ~Scorer(){}; + /** + * called when a new fragment is started for consideration + * @param newFragment + */ + virtual void startFragment(TextFragment * newFragment) = 0; + + /** + * Called for each token in the current fragment + * @param token The token to be scored + * @return a score which is passed to the TermHighlighter class to influence the mark-up of the text + * (this return value is NOT used to score the fragment) + */ + virtual float_t getTokenScore(Token * token) = 0; + + + /** + * Called when the highlighter has no more tokens for the current fragment - the scorer will typically + * call setScore() on the fragment passed in startFragment to record total info + * + */ + virtual float_t getFragmentScore() = 0; + +}; + +}}} + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.cpp b/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.cpp new file mode 100644 index 00000000000..e366eba934a --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.cpp @@ -0,0 +1,55 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "SimpleFragmenter.h" +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(analysis) + +SimpleFragmenter::SimpleFragmenter(int32_t fragmentSize) + : _fragmentSize(fragmentSize), _currentNumFrags(0) +{ +} +SimpleFragmenter::~SimpleFragmenter(){ +} + +void SimpleFragmenter::start(const TCHAR*) +{ + _currentNumFrags=1; +} + +bool SimpleFragmenter::isNewFragment(const Token * token) +{ + bool isNewFrag= token->endOffset()>=(_fragmentSize*_currentNumFrags); + if (isNewFrag) { + _currentNumFrags++; + } + return isNewFrag; +} + +int32_t SimpleFragmenter::getFragmentSize() const +{ + return _fragmentSize; +} + +void SimpleFragmenter::setFragmentSize(int32_t size) +{ + _fragmentSize = size; +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.h b/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.h new file mode 100644 index 00000000000..1d3170daa3f --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleFragmenter.h @@ -0,0 +1,70 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_simplefragmenter_ +#define _lucene_search_highlight_simplefragmenter_ + + +#include "Fragmenter.h" + +CL_NS_DEF2(search,highlight) + +/** + * {@link Fragmenter} implementation which breaks text up into same-size + * fragments with no concerns over spotting sentence boundaries. + */ + +class CLUCENE_CONTRIBS_EXPORT SimpleFragmenter:public Fragmenter +{ +private: + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_FRAGMENT_SIZE =100 ); + int32_t _currentNumFrags; + int32_t _fragmentSize; + +public: + /** + * + * @param fragmentSize size in bytes of each fragment + */ + SimpleFragmenter(int32_t fragmentSize = DEFAULT_FRAGMENT_SIZE); + + ~SimpleFragmenter(); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.TextFragmenter#start(const TCHAR*) + */ + void start(const TCHAR* originalText); + + /* (non-Javadoc) + * @see org.apache.lucene.search.highlight.TextFragmenter#isNewFragment(org.apache.lucene.analysis.Token) + */ + bool isNewFragment(const CL_NS(analysis)::Token * token); + + /** + * @return size in bytes of each fragment + */ + int32_t getFragmentSize() const; + + /** + * @param size size in bytes of each fragment + */ + void setFragmentSize(int32_t size); + +}; + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.cpp b/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.cpp new file mode 100644 index 00000000000..cd684f4ad79 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.cpp @@ -0,0 +1,83 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "SimpleHTMLEncoder.h" +#include "Formatter.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_DEF2(search,highlight) + +SimpleHTMLEncoder::SimpleHTMLEncoder(void) +{ +} + +SimpleHTMLEncoder::~SimpleHTMLEncoder(void) +{ +} + +TCHAR* SimpleHTMLEncoder::encodeText(TCHAR* originalText) +{ + return htmlEncode(originalText); +} + +TCHAR* SimpleHTMLEncoder::htmlEncode(TCHAR* plainText) +{ + size_t plainTextLen = _tcslen(plainText); + if (plainText == NULL || plainTextLen == 0) + { + return STRDUP_TtoT(_T("")); + } + + CL_NS(util)::StringBuffer result(plainTextLen); + + for (int32_t index=0; index': + result.append(_T(">")); + break; + + default: + if (ch < 128) + result.appendChar(ch); + else{ + result.append(_T("&#")); + result.appendInt(ch); + result.append(_T(";")); + } + } + } + + return result.toString(); +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.h b/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.h new file mode 100644 index 00000000000..8a6080a33da --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleHTMLEncoder.h @@ -0,0 +1,45 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_simplehtmlencoder_ +#define _lucene_search_highlight_simplehtmlencoder_ + + +#include "Encoder.h" + +CL_NS_DEF2(search,highlight) + +/** + * Simple {@link Encoder} implementation to escape text for HTML output + * + */ +class CLUCENE_CONTRIBS_EXPORT SimpleHTMLEncoder:public Encoder +{ +public: + SimpleHTMLEncoder(void); + ~SimpleHTMLEncoder(void); + + TCHAR* encodeText(TCHAR* originalText); + + /** + * Encode string into HTML + */ + static TCHAR* htmlEncode(TCHAR* plainText) ; +}; + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.cpp b/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.cpp new file mode 100644 index 00000000000..8c7d08992d9 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.cpp @@ -0,0 +1,56 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "SimpleHTMLFormatter.h" +#include "TokenGroup.h" +#include "CLucene/util/StringBuffer.h" + + +CL_NS_DEF2(search,highlight) +CL_NS_USE(util) + +SimpleHTMLFormatter::SimpleHTMLFormatter(const TCHAR* preTag, const TCHAR* postTag): + _preTag(stringDuplicate(preTag)), + _postTag(stringDuplicate(postTag)) +{ +} + +SimpleHTMLFormatter::SimpleHTMLFormatter() +{ + _preTag = stringDuplicate(_T("")); + _postTag = stringDuplicate(_T("")); +} + +SimpleHTMLFormatter::~SimpleHTMLFormatter() +{ + _CLDELETE_CARRAY(_preTag); + _CLDELETE_CARRAY(_postTag); +} + +TCHAR* SimpleHTMLFormatter::highlightTerm(const TCHAR* originalText, const TokenGroup* tokenGroup) +{ + if(tokenGroup->getTotalScore()>0){ + StringBuffer sb; + sb.append(_preTag); + sb.append(originalText); + sb.append(_postTag); + return sb.toString(); + } + return stringDuplicate(originalText); +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.h b/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.h new file mode 100644 index 00000000000..69b110d5d32 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/SimpleHTMLFormatter.h @@ -0,0 +1,59 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_simplehtmlformatter_ +#define _lucene_search_highlight_simplehtmlformatter_ + + +#include "Formatter.h" + +CL_NS_DEF2(search,highlight) + +/** + * Simple {@link Formatter} implementation to highlight terms with a pre and post tag + * + */ +class CLUCENE_CONTRIBS_EXPORT SimpleHTMLFormatter :public Formatter +{ +private: + TCHAR* _preTag; + TCHAR* _postTag; + +public: + ~SimpleHTMLFormatter(); + + + SimpleHTMLFormatter(const TCHAR* preTag, const TCHAR* postTag); + + /** + * Default constructor uses HTML: <B> tags to markup terms + * + **/ + SimpleHTMLFormatter(); + + + /** + * Returns the original text enclosed in _preTag and _postTag, if the score is greater + * than 0. Otherwise, it returns the original text. + * It doesn't use the stemmed text nor the startOffset. + * It allocates memory for the returned text, and it has to be freed by the caller. + */ + TCHAR* highlightTerm(const TCHAR* originalText, const TokenGroup* tokenGroup); +}; + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/TextFragment.cpp b/src/contribs-lib/CLucene/highlighter/TextFragment.cpp new file mode 100644 index 00000000000..306ad224195 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TextFragment.cpp @@ -0,0 +1,78 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "TextFragment.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(util) + + TextFragment::TextFragment(int32_t textStartPos, int32_t fragNum) + { + _textStartPos = textStartPos; + _textEndPos=0; + _fragNum = fragNum; + } + TextFragment::~TextFragment(){ + } + + void TextFragment::setScore(float_t score) + { + _score=score; + } + + float_t TextFragment::getScore() const + { + return _score; + } + + /** + * @param frag2 Fragment to be merged into this one + */ + void TextFragment::merge(const TextFragment * frag2) + { + _textEndPos = frag2->_textEndPos; + _score=cl_max(_score,frag2->_score); + } + /** + * @param fragment + * @return true if this fragment follows the one passed + */ + bool TextFragment::follows(const TextFragment * fragment) const + { + return _textStartPos == fragment->_textEndPos; + } + + /** + * @return the fragment sequence number + */ + int32_t TextFragment::getFragNum() const + { + return _fragNum; + } + + /* Returns the marked-up text for this text fragment + */ + TCHAR* TextFragment::toString(StringBuffer* buffer) { + TCHAR* ret = _CL_NEWARRAY(TCHAR,_textEndPos-_textStartPos+1); + _tcsncpy(ret,buffer->getBuffer()+_textStartPos,_textEndPos-_textStartPos); + ret[_textEndPos-_textStartPos]=_T('\0'); + + return ret; + } + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/TextFragment.h b/src/contribs-lib/CLucene/highlighter/TextFragment.h new file mode 100644 index 00000000000..9af86342284 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TextFragment.h @@ -0,0 +1,87 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_textfragment_ +#define _lucene_search_highlight_textfragment_ + + +CL_CLASS_DEF(util, StringBuffer) +//#include "CLucene/util/VoidList.h" + +CL_NS_DEF2(search,highlight) + +/** + * Low-level class used to record information about a section of a document + * with a score. + */ +class CLUCENE_CONTRIBS_EXPORT TextFragment:LUCENE_BASE +{ + int32_t _fragNum; + int32_t _textStartPos; + int32_t _textEndPos; + float_t _score; + +public: + TextFragment(int32_t textStartPos, int32_t fragNum); + ~TextFragment(); + + void setScore(float_t score); + float_t getScore() const; + + int32_t textEndPos(){ return _textEndPos; } + void setTextEndPos(int32_t val){ _textEndPos = val; } + + /** + * @param frag2 Fragment to be merged into this one + */ + void merge(const TextFragment * frag2); + + /** + * @param fragment + * @return true if this fragment follows the one passed + */ + bool follows(const TextFragment * fragment) const; + + /** + * @return the fragment sequence number + */ + int32_t getFragNum() const; + + /* Returns the marked-up text for this text fragment + */ + TCHAR* toString(CL_NS(util)::StringBuffer* buffer); + + /** + * Compare weighted terms, according to the term text. + * @todo Do we have to take boost factors into account + */ + class Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base // + { + public: + //todo: this should be more efficient, but will be using a hash table soon, anyway + bool operator()( TextFragment* t1, TextFragment* t2 ) const; + size_t operator()( TextFragment* t ) const; + }; +}; + +/** + * Text fragment list. + */ +//typedef CL_NS(util)::CLSetList > TextFragmentList; + +CL_NS_END2 + +#endif diff --git a/src/contribs-lib/CLucene/highlighter/TokenGroup.cpp b/src/contribs-lib/CLucene/highlighter/TokenGroup.cpp new file mode 100644 index 00000000000..8fa13679b40 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TokenGroup.cpp @@ -0,0 +1,123 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "TokenGroup.h" +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(analysis) + +TokenGroup::TokenGroup(void) +{ + numTokens=0; + startOffset=0; + endOffset=0; + tokens = new Token[MAX_NUM_TOKENS_PER_GROUP]; +} + +TokenGroup::~TokenGroup(void) +{ + delete[] tokens; +} + +void TokenGroup::addToken(Token* token, float_t score) +{ + if(numTokens < MAX_NUM_TOKENS_PER_GROUP) + { + if(numTokens==0) + { + startOffset=token->startOffset(); + endOffset=token->endOffset(); + } + else + { + startOffset=cl_min(startOffset,token->startOffset()); + endOffset=cl_max(endOffset,token->endOffset()); + } + tokens[numTokens].set(token->termBuffer(),token->startOffset(),token->endOffset(),token->type());; + scores[numTokens]=score; + numTokens++; + } +} + +CL_NS(analysis)::Token& TokenGroup::getToken(int32_t index) +{ + return tokens[index]; +} + +float_t TokenGroup::getScore(int32_t index) const +{ + return scores[index]; +} + +int32_t TokenGroup::getEndOffset() const +{ + return endOffset; +} + +int32_t TokenGroup::getNumTokens() const +{ + return numTokens; +} + +int32_t TokenGroup::getStartOffset() const +{ + return startOffset; +} + +float_t TokenGroup::getTotalScore() const +{ + float_t total=0; + for (int32_t i = 0; i < numTokens; i++) + { + total+=scores[i]; + } + return total; +} + +/*void addToken(CL_NS(analysis)::Token* token, float_t score) +{ + if(numTokens < MAX_NUM_TOKENS_PER_GROUP) + { + if(numTokens==0) + { + startOffset=token->startOffset(); + endOffset=token->endOffset(); + } + else + { + startOffset=min(startOffset,token->startOffset()); + endOffset=max(endOffset,token->endOffset()); + } + tokens[numTokens]=token; + scores[numTokens]=score; + numTokens++; + } +}*/ + +bool TokenGroup::isDistinct(CL_NS(analysis)::Token* token) const +{ + return token->startOffset() > endOffset; +} + + +void TokenGroup::clear() +{ + numTokens=0; +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/TokenGroup.h b/src/contribs-lib/CLucene/highlighter/TokenGroup.h new file mode 100644 index 00000000000..3fa82b7238b --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TokenGroup.h @@ -0,0 +1,83 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_tokengroup_ +#define _lucene_search_highlight_tokengroup_ + + +CL_CLASS_DEF(analysis, Token) + +CL_NS_DEF2(search,highlight) + +/** + * One, or several overlapping tokens, along with the score(s) and the + * scope of the original text + */ +class CLUCENE_CONTRIBS_EXPORT TokenGroup: LUCENE_BASE +{ + LUCENE_STATIC_CONSTANT(int32_t,MAX_NUM_TOKENS_PER_GROUP=50); + CL_NS(analysis)::Token* tokens; + float_t scores[MAX_NUM_TOKENS_PER_GROUP]; + int32_t numTokens; + int32_t startOffset; + int32_t endOffset; + +public: + TokenGroup(void); + ~TokenGroup(void); + + void addToken(CL_NS(analysis)::Token* token, float_t score); + + /** + * + * @param index a value between 0 and numTokens -1 + * @return the "n"th token + */ + CL_NS(analysis)::Token& getToken(int32_t index); + + /** + * + * @param index a value between 0 and numTokens -1 + * @return the "n"th score + */ + float_t getScore(int32_t index) const; + + /** + * @return the end position in the original text + */ + int32_t getEndOffset() const; + + /** + * @return the number of tokens in this group + */ + int32_t getNumTokens() const; + + /** + * @return the start position in the original text + */ + int32_t getStartOffset() const; + + /** + * @return all tokens' scores summed up + */ + float_t getTotalScore() const; + + bool isDistinct(CL_NS(analysis)::Token* token) const; + void clear(); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/highlighter/TokenSources.cpp b/src/contribs-lib/CLucene/highlighter/TokenSources.cpp new file mode 100644 index 00000000000..18c1f0cd6d7 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TokenSources.cpp @@ -0,0 +1,229 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "TokenSources.h" + +#include "CLucene/util/VoidList.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/TermVector.h" +#include "CLucene/document/Document.h" + +CL_NS_DEF2(search,highlight) +CL_NS_USE(analysis) +CL_NS_USE(index) +CL_NS_USE(util) + + +///Compares the Token for their order +class TokenOrderCompare:LUCENE_BASE, public CL_NS(util)::Compare::_base // +{ +public: + bool operator()( Token* t1, Token* t2 ) const{ + if(t1->startOffset()>t2->startOffset()) + return false; + if(t1->startOffset()startOffset()) + return true; + return true; +} +}; + +TokenSources::TokenSources(void) +{ +} + +TokenSources::~TokenSources(void) +{ +} + +TokenStream* TokenSources::getAnyTokenStream(IndexReader* reader,int32_t docId, TCHAR* field, Analyzer* analyzer) +{ + TokenStream* ts=NULL; + + TermFreqVector* tfv=reader->getTermFreqVector(docId,field); + if(tfv!=NULL) + { + TermPositionVector* tmp = tfv->__asTermPositionVector(); + if ( tmp != NULL ) + ts=getTokenStream(tmp); + } + //No token info stored so fall back to analyzing raw content + if(ts==NULL) + { + ts=getTokenStream(reader,docId,field,analyzer); + } + return ts; +} + + +TokenStream* TokenSources::getTokenStream(TermPositionVector* tpv) +{ + //assumes the worst and makes no assumptions about token position sequences. + return getTokenStream(tpv,false); +} + +TokenStream* TokenSources::getTokenStream(TermPositionVector* tpv, bool tokenPositionsGuaranteedContiguous) +{ + //an object used to iterate across an array of tokens + /*class StoredTokenStream extends TokenStream + { + Token tokens[]; + int32_t currentToken=0; + StoredTokenStream(Token tokens[]) + { + this.tokens=tokens; + } + public Token next() + { + if(currentToken>=tokens.length) + { + return NULL; + } + return tokens[currentToken++]; + } + } */ + //code to reconstruct the original sequence of Tokens + const ArrayBase* terms = tpv->getTerms(); + const ArrayBase* freq=tpv->getTermFrequencies(); + + size_t totalTokens=0; + for (int32_t i = 0; i < freq->length; i++) + totalTokens+=freq->values[i]; + + Token** tokensInOriginalOrder=NULL; + CLSetList* unsortedTokens = NULL; + for (int32_t t = 0; t < freq->length; t++) + { + const ArrayBase* offsets=tpv->getOffsets(t); + if(offsets==NULL) + return NULL; + + const ArrayBase* pos=NULL; + if(tokenPositionsGuaranteedContiguous) + { + //try get the token position info to speed up assembly of tokens into sorted sequence + pos=tpv->getTermPositions(t); + } + + if ( tokensInOriginalOrder != NULL ) + tokensInOriginalOrder = _CL_NEWARRAY(Token*, totalTokens+1); + + if(pos==NULL) + { + //tokens NOT stored with positions or not guaranteed contiguous - must add to list and sort later + if(unsortedTokens==NULL) + unsortedTokens=_CLNEW CLSetList(false); + for (int32_t tp=0; tp < offsets->length; tp++) + { + unsortedTokens->insert(_CLNEW Token(terms->values[t], + (*offsets)[tp]->getStartOffset(), + (*offsets)[tp]->getEndOffset())); + } + } + else + { + //We have positions stored and a guarantee that the token position information is contiguous + + // This may be fast BUT wont work if Tokenizers used which create >1 token in same position or + // creates jumps in position numbers - this code would fail under those circumstances + + //tokens stored with positions - can use this to index straight into sorted array + for (int32_t tp = 0; tp < pos->length; tp++) + { + tokensInOriginalOrder[(*pos)[tp]]=_CLNEW Token(terms->values[t], + (*offsets)[tp]->getStartOffset(), + (*offsets)[tp]->getEndOffset()); + } + } + } + //If the field has been stored without position data we must perform a sort + if(unsortedTokens!=NULL) + { + if ( totalTokenssize() ){ + _CLDELETE_ARRAY(tokensInOriginalOrder); + tokensInOriginalOrder = _CL_NEWARRAY(Token*,unsortedTokens->size()+1); + } + //the list has already sorted our items //todo:check that this is true... + unsortedTokens->toArray_nullTerminated(tokensInOriginalOrder); + + return _CLNEW StoredTokenStream(tokensInOriginalOrder,unsortedTokens->size()); + }else + return _CLNEW StoredTokenStream(tokensInOriginalOrder,totalTokens); +} + +TokenStream* TokenSources::getTokenStream(IndexReader* reader,int32_t docId, TCHAR* field) +{ + TermFreqVector* tfv=reader->getTermFreqVector(docId,field); + if(tfv==NULL) + { + TCHAR buf[250]; + _sntprintf(buf,250,_T("%s in doc #%d does not have any term position data stored"),field,docId); + _CLTHROWT(CL_ERR_IllegalArgument,buf); + return NULL; + } + + TermPositionVector* tmp = NULL; + tmp = tfv->__asTermPositionVector(); + + if ( tmp != NULL ){ + return getTokenStream(tmp); + }else{ + TCHAR buf[250]; + _sntprintf(buf,250,_T("%s in doc #%d does not have any term position data stored"),field,docId); + _CLTHROWT(CL_ERR_IllegalArgument,buf); + return NULL; + } +} + +//convenience method +TokenStream* TokenSources::getTokenStream(IndexReader* reader,int32_t docId, TCHAR* field,Analyzer* analyzer) +{ + CL_NS(document)::Document doc; + reader->document(docId, doc); + const TCHAR* contents=doc.get(field); + if(contents==NULL) + { + TCHAR buf[250]; + _sntprintf(buf,250,_T("Field %s in document #%d is not stored and cannot be analyzed"),field,docId); + _CLTHROWT(CL_ERR_IllegalArgument,buf); + return NULL; + } + return analyzer->tokenStream(field,_CLNEW StringReader(contents)); +} + +TokenSources::StoredTokenStream::StoredTokenStream(CL_NS(analysis)::Token** tokens, size_t len) +{ + currentToken = 0; + this->tokens=tokens; + this->length = len; +} +CL_NS(analysis)::Token* TokenSources::StoredTokenStream::next(CL_NS(analysis)::Token* token) +{ + if(currentToken>=length) + { + return NULL; + } + Token* t = tokens[currentToken++]; + + token->set(t->termBuffer(),t->startOffset(),t->endOffset(),t->type());; + return token; +} +void TokenSources::StoredTokenStream::close(){ + +} + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/TokenSources.h b/src/contribs-lib/CLucene/highlighter/TokenSources.h new file mode 100644 index 00000000000..d1da4d5c813 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/TokenSources.h @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_search_highlight_tokensources_ +#define _lucene_search_highlight_tokensources_ + +#include "CLucene/analysis/AnalysisHeader.h" +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF(index, TermPositionVector) +//#include "CLucene/index/IndexReader.h" +//#include "CLucene/index/TermVector.h" + +CL_NS_DEF2(search,highlight) + +class CLUCENE_CONTRIBS_EXPORT TokenSources: LUCENE_BASE +{ + //an object used to iterate across an array of tokens + class StoredTokenStream:public CL_NS(analysis)::TokenStream + { + public: + CL_NS(analysis)::Token** tokens; + size_t length; + int32_t currentToken; + StoredTokenStream(CL_NS(analysis)::Token** tokens, size_t len); + CL_NS(analysis)::Token* next(CL_NS(analysis)::Token* token); + void close(); + }; +public: + TokenSources(void); + ~TokenSources(void); + + /** + * A convenience method that tries a number of approaches to getting a token stream. + * The cost of finding there are no termVectors in the index is minimal (1000 invocations still + * registers 0 ms). So this "lazy" (flexible?) approach to coding is probably acceptable + * @param reader + * @param docId + * @param field + * @param analyzer + * @return null if field not stored correctly + * @throws IOException + */ + static CL_NS(analysis)::TokenStream* getAnyTokenStream(CL_NS(index)::IndexReader* reader,int32_t docId, TCHAR* field, CL_NS(analysis)::Analyzer* analyzer); + + static CL_NS(analysis)::TokenStream* getTokenStream(CL_NS(index)::TermPositionVector* tpv); + + /** + * Low level api. + * Returns a token stream or null if no offset info available in index. + * This can be used to feed the highlighter with a pre-parsed token stream + * + * In my tests the speeds to recreate 1000 token streams using this method are: + * - with TermVector offset only data stored - 420 milliseconds + * - with TermVector offset AND position data stored - 271 milliseconds + * (nb timings for TermVector with position data are based on a tokenizer with contiguous + * positions - no overlaps or gaps) + * The cost of not using TermPositionVector to store + * pre-parsed content and using an analyzer to re-parse the original content: + * - reanalyzing the original content - 980 milliseconds + * + * The re-analyze timings will typically vary depending on - + * 1) The complexity of the analyzer code (timings above were using a + * stemmer/lowercaser/stopword combo) + * 2) The number of other fields (Lucene reads ALL fields off the disk + * when accessing just one document field - can cost dear!) + * 3) Use of compression on field storage - could be faster cos of compression (less disk IO) + * or slower (more CPU burn) depending on the content. + * + * @param tpv + * @param tokenPositionsGuaranteedContiguous true if the token position numbers have no overlaps or gaps. If looking + * to eek out the last drops of performance, set to true. If in doubt, set to false. + */ + static CL_NS(analysis)::TokenStream* getTokenStream(CL_NS(index)::TermPositionVector* tpv, bool tokenPositionsGuaranteedContiguous); + + static CL_NS(analysis)::TokenStream* getTokenStream(CL_NS(index)::IndexReader* reader,int32_t docId, TCHAR* field); + + //convenience method + static CL_NS(analysis)::TokenStream* getTokenStream(CL_NS(index)::IndexReader* reader,int32_t docId, TCHAR* field,CL_NS(analysis)::Analyzer* analyzer); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/highlighter/WeightedTerm.cpp b/src/contribs-lib/CLucene/highlighter/WeightedTerm.cpp new file mode 100644 index 00000000000..b3bb0a8ca38 --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/WeightedTerm.cpp @@ -0,0 +1,101 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CLucene/_ApiHeader.h" +#include "WeightedTerm.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/Misc.h" + +CL_NS_DEF2(search,highlight) + + WeightedTerm::WeightedTerm (float_t weight,const TCHAR* term) + { + _weight=weight; + _term = stringDuplicate(term); + cachedHashCode = 0; + } + + WeightedTerm::~WeightedTerm() + { + _CLDELETE_CARRAY(_term); + } + + WeightedTerm::WeightedTerm(const WeightedTerm& other) + { + _weight = other.getWeight(); + _term = STRDUP_TtoT(other.getTerm()); + } + + WeightedTerm* WeightedTerm::clone() const{ + return _CLNEW WeightedTerm(*this); + } + + /** + * @return the term value (stemmed) + */ + const TCHAR* WeightedTerm::getTerm() const + { + return _term; + } + + /** + * @return the weight associated with this term + */ + float_t WeightedTerm::getWeight() const + { + return _weight; + } + + /** + * @param term the term value (stemmed) + */ + void WeightedTerm::setTerm(TCHAR* term) + { + _CLDELETE_CARRAY(this->_term); + this->_term = STRDUP_TtoT(_term); + cachedHashCode = 0; + } + + /** + * @param weight the weight associated with this term + */ + void WeightedTerm::setWeight(float_t weight) { + this->_weight = _weight; + cachedHashCode = 0; + } + + size_t WeightedTerm::hashCode(){ + if ( cachedHashCode == 0 ){ + cachedHashCode = ( CL_NS(util)::Misc::thashCode(this->_term) ^ CL_NS(search)::Similarity::floatToByte(_weight) ); + } + + return cachedHashCode; + } + + bool WeightedTerm::Compare::operator()( WeightedTerm* t1, WeightedTerm* t2 ) const{ + int r = _tcscmp(t1->getTerm(), t2->getTerm()); + if ( r < 0 ) + return true; + else if ( r == 0 ) + return t1->getWeight() < t2->getWeight(); + else + return false; + } + size_t WeightedTerm::Compare::operator()( WeightedTerm* t ) const{ + return t->hashCode(); + } + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/highlighter/WeightedTerm.h b/src/contribs-lib/CLucene/highlighter/WeightedTerm.h new file mode 100644 index 00000000000..0428e50e6cc --- /dev/null +++ b/src/contribs-lib/CLucene/highlighter/WeightedTerm.h @@ -0,0 +1,79 @@ +/** + * Copyright 2002-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _lucene_search_highlight_weightedterm_ +#define _lucene_search_highlight_weightedterm_ + + +//#include "CLucene/util/VoidList.h" + +CL_NS_DEF2(search,highlight) + +/** Lightweight class to hold term and a weight value used for scoring this term + */ +class CLUCENE_CONTRIBS_EXPORT WeightedTerm:LUCENE_BASE +{ +private: + float_t _weight; // multiplier + TCHAR* _term; //stemmed form + size_t cachedHashCode; + WeightedTerm(const WeightedTerm& other); +public: + WeightedTerm (float_t weight,const TCHAR* term); + ~WeightedTerm(); + + /** + * @return the term value (stemmed) + */ + const TCHAR* getTerm() const; + + /** + * @return the weight associated with this term + */ + float_t getWeight() const ; + + /** + * @param term the term value (stemmed) + */ + void setTerm(TCHAR* term); + /** + * @param weight the weight associated with this term + */ + void setWeight(float_t weight); + + size_t hashCode(); + WeightedTerm* clone() const; + + /** + * Compare weighted terms, according to the term text. + * @todo Do we have to take boost factors into account + */ + class Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base // + { + public: + //todo: this should be more efficient, but will be using a hash table soon, anyway + bool operator()( WeightedTerm* t1, WeightedTerm* t2 ) const; + size_t operator()( WeightedTerm* t ) const; + }; +}; + +/** CLHashSet of WeightedTerm */ +typedef CL_NS(util)::CLHashSet > WeightedTermList; + +CL_NS_END2 + +#endif + diff --git a/src/contribs-lib/CLucene/snowball/SNOWBALL_README b/src/contribs-lib/CLucene/snowball/SNOWBALL_README new file mode 100644 index 00000000000..3ff66e4f361 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/SNOWBALL_README @@ -0,0 +1,82 @@ +libstemmer_c +============ + +This document pertains to the C version of the libstemmer distribution, +available for download from: + +http://snowball.tartarus.org/dist/libstemmer_c.tgz + + +Compiling the library +===================== + +A simple makefile is provided for Unix style systems. On such systems, it +should be possible simply to run "make", and the file "libstemmer.o" +and the example program "stemwords" will be generated. + +If this doesn't work on your system, you need to write your own build +system (or call the compiler directly). The files to compile are +all contained in the "libstemmer", "runtime" and "src_c" directories, +and the public header file is contained in the "include" directory. + + +Using the library +================= + +The library provides a simple C API. Essentially, a new stemmer can +be obtained by using "sb_stemmer_new". "sb_stemmer_stem" is then +used to stem a word, "sb_stemmer_length" returns the stemmed +length of the last word processed, and "sb_stemmer_delete" is +used to delete a stemmer. + +Creating a stemmer is a relatively expensive operation - the expected +usage pattern is that a new stemmer is created when needed, used +to stem many words, and deleted after some time. + +Stemmers are re-entrant, but not threadsafe. In other words, if +you wish to access the same stemmer object from multiple threads, +you must ensure that all access is protected by a mutex or similar +device. + +libstemmer does not currently incorporate any mechanism for caching the results +of stemming operations. Such caching can greatly increase the performance of a +stemmer under certain situations, so suitable patches will be considered for +inclusion. + +The standard libstemmer sources contain an algorithm for each of the supported +languages. The algorithm may be selected using the english name of the +language, or using the 2 or 3 letter ISO 639 language codes. In addition, +the traditional "Porter" stemming algorithm for english is included for +backwards compatibility purposes, but we recommend use of the "English" +stemmer in preference for new projects. + +(Some minor algorithms which are included only as curiosities in the snowball +website, such as the Lovins stemmer and the Kraaij Pohlmann stemmer, are not +included in the standard libstemmer sources. These are not really supported by +the snowball project, but it would be possible to compile a modified libstemmer +library containing these if desired.) + + +The stemwords example +===================== + +The stemwords example program allows you to run any of the stemmers +compiled into the libstemmer library on a sample vocabulary. For +details on how to use it, run it with the "-h" command line option. + + +Using the library in a larger system +==================================== + +If you are incorporating the library into the build system of a larger +program, I recommend copying the unpacked tarball without modification into +a subdirectory of the sources of your program. Future versions of the +library are intended to keep the same structure, so this will keep the +work required to move to a new version of the library to a minimum. + +As an additional convenience, the list of source and header files used +in the library is detailed in mkinc.mak - a file which is in a suitable +format for inclusion by a Makefile. By including this file in your build +system, you can link the snowball system into your program with a few +extra rules. + diff --git a/src/contribs-lib/CLucene/snowball/Snowball.cpp b/src/contribs-lib/CLucene/snowball/Snowball.cpp new file mode 100644 index 00000000000..411c5d4a593 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/Snowball.cpp @@ -0,0 +1,137 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "SnowballAnalyzer.h" +#include "SnowballFilter.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/analysis/standard/StandardTokenizer.h" +#include "CLucene/analysis/standard/StandardFilter.h" + +CL_NS_USE(analysis) +CL_NS_USE(util) +CL_NS_USE2(analysis,standard) + +CL_NS_DEF2(analysis,snowball) + + /** Builds the named analyzer with no stop words. */ + SnowballAnalyzer::SnowballAnalyzer(const TCHAR* language) { + this->language = STRDUP_TtoT(language); + stopSet = NULL; + } + + SnowballAnalyzer::~SnowballAnalyzer(){ + _CLDELETE_CARRAY(language); + if ( stopSet != NULL ) + _CLDELETE(stopSet); + } + + /** Builds the named analyzer with the given stop words. + */ + SnowballAnalyzer::SnowballAnalyzer(const TCHAR* language, const TCHAR** stopWords) { + this->language = STRDUP_TtoT(language); + + stopSet = _CLNEW CLTCSetList(true); + StopFilter::fillStopTable(stopSet,stopWords); + } + + TokenStream* SnowballAnalyzer::tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) { + return this->tokenStream(fieldName,reader,false); + } + + /** Constructs a {@link StandardTokenizer} filtered by a {@link + StandardFilter}, a {@link LowerCaseFilter} and a {@link StopFilter}. */ + TokenStream* SnowballAnalyzer::tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader, bool deleteReader) { + BufferedReader* bufferedReader = reader->__asBufferedReader(); + TokenStream* result; + + if ( bufferedReader == NULL ) + result = _CLNEW StandardTokenizer( _CLNEW FilteredBufferedReader(reader, deleteReader), true ); + else + result = _CLNEW StandardTokenizer(bufferedReader, deleteReader); + + result = _CLNEW StandardFilter(result, true); + result = _CLNEW CL_NS(analysis)::LowerCaseFilter(result, true); + if (stopSet != NULL) + result = _CLNEW CL_NS(analysis)::StopFilter(result, true, stopSet); + result = _CLNEW SnowballFilter(result, language, true); + return result; + } + + + + + + + + /** Construct the named stemming filter. + * + * @param in the input tokens to stem + * @param name the name of a stemmer + */ + SnowballFilter::SnowballFilter(TokenStream* in, const TCHAR* language, bool deleteTS): + TokenFilter(in,deleteTS) + { + TCHAR tlang[50]; + char lang[50]; + _tcsncpy(tlang,language,50); + _tcslwr(tlang); + + STRCPY_TtoA(lang,tlang,50); + stemmer = sb_stemmer_new(lang, NULL); //use utf8 encoding + + if ( stemmer == NULL ){ + _CLTHROWA(CL_ERR_IllegalArgument, "language not available for stemming\n"); //todo: richer error + } + } + + SnowballFilter::~SnowballFilter(){ + sb_stemmer_delete(stemmer); + } + + /** Returns the next input Token, after being stemmed */ + Token* SnowballFilter::next(Token* token){ + if (input->next(token) == NULL) + return NULL; + + unsigned char uctext[LUCENE_MAX_WORD_LEN]; + TCHAR tchartext[LUCENE_MAX_WORD_LEN]; + +#ifdef _UCS2 + char utf8text[LUCENE_MAX_WORD_LEN]; + + size_t len = lucene_wcstoutf8(utf8text,token->termBuffer(),LUCENE_MAX_WORD_LEN); + memcpy(uctext,utf8text,len); + uctext[len]='\0'; +#else + const char* tmp = token->termText(); + int len = token->termTextLength(); + for (int i=0;iset(tchartext,token->startOffset(), token->endOffset(), token->type()); + return token; + } + + +CL_NS_END2 diff --git a/src/contribs-lib/CLucene/snowball/SnowballAnalyzer.h b/src/contribs-lib/CLucene/snowball/SnowballAnalyzer.h new file mode 100644 index 00000000000..cfc77e5e86f --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/SnowballAnalyzer.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_snowball_analyser_ +#define _lucene_analysis_snowball_analyser_ + +#include "CLucene/analysis/AnalysisHeader.h" + +CL_CLASS_DEF(util,BufferedReader) +CL_NS_DEF2(analysis,snowball) + +/** Filters {@link StandardTokenizer} with {@link StandardFilter}, {@link + * LowerCaseFilter}, {@link StopFilter} and {@link SnowballFilter}. + * + * Available stemmers are listed in {@link net.sf.snowball.ext}. The name of a + * stemmer is the part of the class name before "Stemmer", e.g., the stemmer in + * {@link EnglishStemmer} is named "English". + */ +class CLUCENE_CONTRIBS_EXPORT SnowballAnalyzer: public Analyzer { + TCHAR* language; + CLTCSetList* stopSet; + +public: + /** Builds the named analyzer with no stop words. */ + SnowballAnalyzer(const TCHAR* language=_T("english")); + + /** Builds the named analyzer with the given stop words. + */ + SnowballAnalyzer(const TCHAR* language, const TCHAR** stopWords); + + ~SnowballAnalyzer(); + + /** Constructs a {@link StandardTokenizer} filtered by a {@link + StandardFilter}, a {@link LowerCaseFilter} and a {@link StopFilter}. */ + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader, bool deleteReader); +}; + +CL_NS_END2 +#endif + diff --git a/src/contribs-lib/CLucene/snowball/SnowballFilter.h b/src/contribs-lib/CLucene/snowball/SnowballFilter.h new file mode 100644 index 00000000000..40550e65bad --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/SnowballFilter.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_snowball_filter_ +#define _lucene_analysis_snowball_filter_ + +#include "CLucene/analysis/AnalysisHeader.h" +#include "libstemmer.h" + +CL_NS_DEF2(analysis,snowball) + +/** A filter that stems words using a Snowball-generated stemmer. + * + * Available stemmers are listed in {@link net.sf.snowball.ext}. The name of a + * stemmer is the part of the class name before "Stemmer", e.g., the stemmer in + * {@link EnglishStemmer} is named "English". + * + * Note: todo: This is not thread safe... + */ +class CLUCENE_CONTRIBS_EXPORT SnowballFilter: public TokenFilter { + struct sb_stemmer * stemmer; +public: + + /** Construct the named stemming filter. + * + * @param in the input tokens to stem + * @param name the name of a stemmer + */ + SnowballFilter(TokenStream* in, const TCHAR* language, bool deleteTS); + + ~SnowballFilter(); + + /** Returns the next input Token, after being stemmed */ + Token* next(Token* token); +}; + +CL_NS_END2 +#endif diff --git a/src/contribs-lib/CLucene/snowball/include/libstemmer.h b/src/contribs-lib/CLucene/snowball/include/libstemmer.h new file mode 100644 index 00000000000..9ca5e9c8f91 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/include/libstemmer.h @@ -0,0 +1,82 @@ +#ifndef LIBSTEMMER_INCLUDE_LIBSTEMMER_H +#define LIBSTEMMER_INCLUDE_LIBSTEMMER_H + +/* Make header file work when included from C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +struct sb_stemmer; +typedef unsigned char sb_symbol; + +/* FIXME - should be able to get a version number for each stemming + * algorithm (which will be incremented each time the output changes). */ + +/** Returns an array of the names of the available stemming algorithms. + * Note that these are the canonical names - aliases (ie, other names for + * the same algorithm) will not be included in the list. + * The list is terminated with a null pointer. + * + * The list must not be modified in any way. + */ +const char ** sb_stemmer_list(void); + +/** Create a new stemmer object, using the specified algorithm, for the + * specified character encoding. + * + * All algorithms will usually be available in UTF-8, but may also be + * available in other character encodings. + * + * @param algorithm The algorithm name. This is either the english + * name of the algorithm, or the 2 or 3 letter ISO 639 codes for the + * language. Note that case is significant in this parameter - the + * value should be supplied in lower case. + * + * @param charenc The character encoding. NULL may be passed as + * this value, in which case UTF-8 encoding will be assumed. Otherwise, + * the argument may be one of "UTF_8", "ISO_8859_1" (ie, Latin 1), + * "CP850" (ie, MS-DOS Latin 1) or "KOI8_R" (Russian). Note that + * case is significant in this parameter. + * + * @return NULL if the specified algorithm is not recognised, or the + * algorithm is not available for the requested encoding. Otherwise, + * returns a pointer to a newly created stemmer for the requested algorithm. + * The returned pointer must be deleted by calling sb_stemmer_delete(). + * + * @note NULL will also be returned if an out of memory error occurs. + */ +struct sb_stemmer * sb_stemmer_new(const char * algorithm, const char * charenc); + +/** Delete a stemmer object. + * + * This frees all resources allocated for the stemmer. After calling + * this function, the supplied stemmer may no longer be used in any way. + * + * It is safe to pass a null pointer to this function - this will have + * no effect. + */ +void sb_stemmer_delete(struct sb_stemmer * stemmer); + +/** Stem a word. + * + * The return value is owned by the stemmer - it must not be freed or + * modified, and it will become invalid when the stemmer is called again, + * or if the stemmer is freed. + * + * The length of the return value can be obtained using sb_stemmer_length(). + * + * If an out-of-memory error occurs, this will return NULL. + */ +const sb_symbol * sb_stemmer_stem(struct sb_stemmer * stemmer, + const sb_symbol * word, int size); + +/** Get the length of the result of the last stemmed word. + * This should not be called before sb_stemmer_stem() has been called. + */ +int sb_stemmer_length(struct sb_stemmer * stemmer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/contribs-lib/CLucene/snowball/libstemmer.h b/src/contribs-lib/CLucene/snowball/libstemmer.h new file mode 100644 index 00000000000..9d86b8581c5 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/libstemmer.h @@ -0,0 +1,79 @@ + +/* Make header file work when included from C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +struct sb_stemmer; +typedef unsigned char sb_symbol; + +/* FIXME - should be able to get a version number for each stemming + * algorithm (which will be incremented each time the output changes). */ + +/** Returns an array of the names of the available stemming algorithms. + * Note that these are the canonical names - aliases (ie, other names for + * the same algorithm) will not be included in the list. + * The list is terminated with a null pointer. + * + * The list must not be modified in any way. + */ +const char ** sb_stemmer_list(void); + +/** Create a new stemmer object, using the specified algorithm, for the + * specified character encoding. + * + * All algorithms will usually be available in UTF-8, but may also be + * available in other character encodings. + * + * @param algorithm The algorithm name. This is either the english + * name of the algorithm, or the 2 or 3 letter ISO 639 codes for the + * language. Note that case is significant in this parameter - the + * value should be supplied in lower case. + * + * @param charenc The character encoding. NULL may be passed as + * this value, in which case UTF-8 encoding will be assumed. Otherwise, + * the argument may be one of "UTF_8", "ISO_8859_1" (ie, Latin 1), + * "CP850" (ie, MS-DOS Latin 1) or "KOI8_R" (Russian). Note that + * case is significant in this parameter. + * + * @return NULL if the specified algorithm is not recognised, or the + * algorithm is not available for the requested encoding. Otherwise, + * returns a pointer to a newly created stemmer for the requested algorithm. + * The returned pointer must be deleted by calling sb_stemmer_delete(). + * + * @note NULL will also be returned if an out of memory error occurs. + */ +struct sb_stemmer * sb_stemmer_new(const char * algorithm, const char * charenc); + +/** Delete a stemmer object. + * + * This frees all resources allocated for the stemmer. After calling + * this function, the supplied stemmer may no longer be used in any way. + * + * It is safe to pass a null pointer to this function - this will have + * no effect. + */ +void sb_stemmer_delete(struct sb_stemmer * stemmer); + +/** Stem a word. + * + * The return value is owned by the stemmer - it must not be freed or + * modified, and it will become invalid when the stemmer is called again, + * or if the stemmer is freed. + * + * The length of the return value can be obtained using sb_stemmer_length(). + * + * If an out-of-memory error occurs, this will return NULL. + */ +const sb_symbol * sb_stemmer_stem(struct sb_stemmer * stemmer, + const sb_symbol * word, int size); + +/** Get the length of the result of the last stemmed word. + * This should not be called before sb_stemmer_stem() has been called. + */ +int sb_stemmer_length(struct sb_stemmer * stemmer); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/libstemmer/libstemmer.c b/src/contribs-lib/CLucene/snowball/libstemmer/libstemmer.c new file mode 100644 index 00000000000..77da8db910c --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/libstemmer/libstemmer.c @@ -0,0 +1,92 @@ + +#include +#include +#include "../include/libstemmer.h" +#include "../runtime/api.h" +#include "modules.h" + +struct sb_stemmer { + struct SN_env * (*create)(void); + void (*close)(struct SN_env *); + int (*stem)(struct SN_env *); + + struct SN_env * env; +}; + +extern const char ** +sb_stemmer_list(void) +{ + return algorithm_names; +} + +static stemmer_encoding sb_getenc(const char * charenc) +{ + struct stemmer_encoding * encoding; + if (charenc == NULL) return ENC_UTF_8; + for (encoding = encodings; encoding->name != 0; encoding++) { + if (strcmp(encoding->name, charenc) == 0) break; + } + if (encoding->name == NULL) return ENC_UNKNOWN; + return encoding->enc; +} + +extern struct sb_stemmer * +sb_stemmer_new(const char * algorithm, const char * charenc) +{ + stemmer_encoding enc; + struct stemmer_modules * module; + struct sb_stemmer * stemmer = + (struct sb_stemmer *) malloc(sizeof(struct sb_stemmer)); + if (stemmer == NULL) return NULL; + enc = sb_getenc(charenc); + if (enc == ENC_UNKNOWN) return NULL; + + for (module = modules; module->name != 0; module++) { + if (strcmp(module->name, algorithm) == 0 && module->enc == enc) break; + } + if (module->name == NULL) return NULL; + + stemmer->create = module->create; + stemmer->close = module->close; + stemmer->stem = module->stem; + + stemmer->env = stemmer->create(); + if (stemmer->env == NULL) + { + sb_stemmer_delete(stemmer); + return NULL; + } + + return stemmer; +} + +void +sb_stemmer_delete(struct sb_stemmer * stemmer) +{ + if (stemmer == 0) return; + if (stemmer->close == 0) return; + stemmer->close(stemmer->env); + stemmer->close = 0; + free(stemmer); +} + +const sb_symbol * +sb_stemmer_stem(struct sb_stemmer * stemmer, const sb_symbol * word, int size) +{ + int ret; + if (SN_set_current(stemmer->env, size, word)) + { + stemmer->env->l = 0; + return NULL; + } + ret = stemmer->stem(stemmer->env); + if (ret < 0) return NULL; + stemmer->env->p[stemmer->env->l] = 0; + return stemmer->env->p; +} + +int +sb_stemmer_length(struct sb_stemmer * stemmer) +{ + return stemmer->env->l; +} diff --git a/src/contribs-lib/CLucene/snowball/libstemmer/modules.h b/src/contribs-lib/CLucene/snowball/libstemmer/modules.h new file mode 100644 index 00000000000..57df305a874 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/libstemmer/modules.h @@ -0,0 +1,166 @@ +#ifndef LIBSTEMMER_MODULES_H +#define LIBSTEMMER_MODULES_H + +/* libstemmer/modules.h: List of stemming modules. + * + * This file is generated by mkmodules.pl from a list of module names. + * Do not edit manually. + * + * Modules included by this file are: danish, dutch, english, finnish, french, + * german, italian, norwegian, porter, portuguese, russian, spanish, swedish + */ + +#include "../src_c/stem_ISO_8859_1_danish.h" +#include "../src_c/stem_UTF_8_danish.h" +#include "../src_c/stem_ISO_8859_1_dutch.h" +#include "../src_c/stem_UTF_8_dutch.h" +#include "../src_c/stem_ISO_8859_1_english.h" +#include "../src_c/stem_UTF_8_english.h" +#include "../src_c/stem_ISO_8859_1_finnish.h" +#include "../src_c/stem_UTF_8_finnish.h" +#include "../src_c/stem_ISO_8859_1_french.h" +#include "../src_c/stem_UTF_8_french.h" +#include "../src_c/stem_ISO_8859_1_german.h" +#include "../src_c/stem_UTF_8_german.h" +#include "../src_c/stem_ISO_8859_1_italian.h" +#include "../src_c/stem_UTF_8_italian.h" +#include "../src_c/stem_ISO_8859_1_norwegian.h" +#include "../src_c/stem_UTF_8_norwegian.h" +#include "../src_c/stem_ISO_8859_1_porter.h" +#include "../src_c/stem_UTF_8_porter.h" +#include "../src_c/stem_ISO_8859_1_portuguese.h" +#include "../src_c/stem_UTF_8_portuguese.h" +#include "../src_c/stem_KOI8_R_russian.h" +#include "../src_c/stem_UTF_8_russian.h" +#include "../src_c/stem_ISO_8859_1_spanish.h" +#include "../src_c/stem_UTF_8_spanish.h" +#include "../src_c/stem_ISO_8859_1_swedish.h" +#include "../src_c/stem_UTF_8_swedish.h" + +typedef enum { + ENC_UNKNOWN, + ENC_ISO_8859_1, + ENC_KOI8_R, + ENC_UTF_8, +} stemmer_encoding; + +struct stemmer_encoding { + const char * name; + stemmer_encoding enc; +}; +static struct stemmer_encoding encodings[] = { + {"ISO_8859_1", ENC_ISO_8859_1}, + {"KOI8_R", ENC_KOI8_R}, + {"UTF_8", ENC_UTF_8}, + {0,0} +}; + +struct stemmer_modules { + const char * name; + stemmer_encoding enc; + struct SN_env * (*create)(void); + void (*close)(struct SN_env *); + int (*stem)(struct SN_env *); +}; +static struct stemmer_modules modules[] = { + {"da", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"da", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"dan", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"dan", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"danish", ENC_ISO_8859_1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, + {"danish", ENC_UTF_8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, + {"de", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"de", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"deu", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"deu", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"dut", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"dut", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"dutch", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"dutch", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"en", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"en", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"eng", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"eng", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"english", ENC_ISO_8859_1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + {"english", ENC_UTF_8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, + {"es", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"es", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"esl", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"esl", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"fi", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"fi", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fin", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"fin", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"finnish", ENC_ISO_8859_1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, + {"finnish", ENC_UTF_8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, + {"fr", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fr", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fra", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fra", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"fre", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"fre", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"french", ENC_ISO_8859_1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, + {"french", ENC_UTF_8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, + {"ger", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"ger", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"german", ENC_ISO_8859_1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, + {"german", ENC_UTF_8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, + {"it", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"it", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"ita", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"ita", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"italian", ENC_ISO_8859_1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, + {"italian", ENC_UTF_8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, + {"nl", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"nl", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"nld", ENC_ISO_8859_1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, + {"nld", ENC_UTF_8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, + {"no", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"no", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"nor", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"nor", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"norwegian", ENC_ISO_8859_1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, + {"norwegian", ENC_UTF_8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, + {"por", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"por", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"porter", ENC_ISO_8859_1, porter_ISO_8859_1_create_env, porter_ISO_8859_1_close_env, porter_ISO_8859_1_stem}, + {"porter", ENC_UTF_8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, + {"portuguese", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"portuguese", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"pt", ENC_ISO_8859_1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, + {"pt", ENC_UTF_8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, + {"ru", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"ru", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"rus", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"rus", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"russian", ENC_KOI8_R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, + {"russian", ENC_UTF_8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, + {"spa", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"spa", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"spanish", ENC_ISO_8859_1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, + {"spanish", ENC_UTF_8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, + {"sv", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"sv", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swe", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"swe", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {"swedish", ENC_ISO_8859_1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, + {"swedish", ENC_UTF_8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, + {0,0,0,0,0} +}; +static const char * algorithm_names[] = { + "danish", + "dutch", + "english", + "finnish", + "french", + "german", + "italian", + "norwegian", + "porter", + "portuguese", + "russian", + "spanish", + "swedish", + 0 +}; +#endif diff --git a/src/contribs-lib/CLucene/snowball/runtime/api.c b/src/contribs-lib/CLucene/snowball/runtime/api.c new file mode 100644 index 00000000000..9dd5a3b8fa8 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/runtime/api.c @@ -0,0 +1,69 @@ + +#include /* for calloc, free */ +#include "header.h" + +extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size) +{ + struct SN_env * z = (struct SN_env *) calloc(1, sizeof(struct SN_env)); + if (z == NULL) return NULL; + z->p = create_s(); + if (z->p == NULL) goto error; + if (S_size) + { + int i; + z->S = (symbol * *) calloc(S_size, sizeof(symbol *)); + if (z->S == NULL) goto error; + + for (i = 0; i < S_size; i++) + { + z->S[i] = create_s(); + if (z->S[i] == NULL) goto error; + } + z->S_size = S_size; + } + + if (I_size) + { + z->I = (int *) calloc(I_size, sizeof(int)); + if (z->I == NULL) goto error; + z->I_size = I_size; + } + + if (B_size) + { + z->B = (symbol *) calloc(B_size, sizeof(symbol)); + if (z->B == NULL) goto error; + z->B_size = B_size; + } + + return z; +error: + SN_close_env(z); + return NULL; +} + +extern void SN_close_env(struct SN_env * z) +{ + if (z == NULL) return; + if (z->S_size) + { + int i; + for (i = 0; i < z->S_size; i++) + { + lose_s(z->S[i]); + } + free(z->S); + } + if (z->I_size) free(z->I); + if (z->B_size) free(z->B); + if (z->p) lose_s(z->p); + free(z); +} + +extern int SN_set_current(struct SN_env * z, int size, const symbol * s) +{ + int err = replace_s(z, 0, z->l, size, s, NULL); + z->c = 0; + return err; +} + diff --git a/src/contribs-lib/CLucene/snowball/runtime/api.h b/src/contribs-lib/CLucene/snowball/runtime/api.h new file mode 100644 index 00000000000..7338deebcde --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/runtime/api.h @@ -0,0 +1,30 @@ +#ifndef LIBSTEMMER_RUNTIME_API_H +#define LIBSTEMMER_RUNTIME_API_H + +typedef unsigned char symbol; + +/* Or replace 'char' above with 'short' for 16 bit characters. + + More precisely, replace 'char' with whatever type guarantees the + character width you need. Note however that sizeof(symbol) should divide + HEAD, defined in header.h as 2*sizeof(int), without remainder, otherwise + there is an alignment problem. In the unlikely event of a problem here, + consult Martin Porter. + +*/ + +struct SN_env { + symbol * p; + int c; int a; int l; int lb; int bra; int ket; + int S_size; int I_size; int B_size; + symbol * * S; + int * I; + symbol * B; +}; + +extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size); +extern void SN_close_env(struct SN_env * z); + +extern int SN_set_current(struct SN_env * z, int size, const symbol * s); + +#endif diff --git a/src/contribs-lib/CLucene/snowball/runtime/header.h b/src/contribs-lib/CLucene/snowball/runtime/header.h new file mode 100644 index 00000000000..af02b5eca7d --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/runtime/header.h @@ -0,0 +1,61 @@ +#ifndef LIBSTEMMER_RUNTIME_HEADER_H +#define LIBSTEMMER_RUNTIME_HEADER_H + +#include + +#include "api.h" + +#define MAXINT INT_MAX +#define MININT INT_MIN + +#define HEAD 2*sizeof(int) + +#define SIZE(p) ((int *)(p))[-1] +#define SET_SIZE(p, n) ((int *)(p))[-1] = n +#define CAPACITY(p) ((int *)(p))[-2] + +struct among +{ int s_size; /* number of chars in string */ + symbol * s; /* search string */ + int substring_i;/* index to longest matching substring */ + int result; /* result of the lookup */ + int (* function)(struct SN_env *); +}; + +extern symbol * create_s(void); +extern void lose_s(symbol * p); + +extern int skip_utf8(const symbol * p, int c, int lb, int l, int n); + +extern int in_grouping_U(struct SN_env * z, unsigned char * s, int min, int max); +extern int in_grouping_b_U(struct SN_env * z, unsigned char * s, int min, int max); +extern int out_grouping_U(struct SN_env * z, unsigned char * s, int min, int max); +extern int out_grouping_b_U(struct SN_env * z, unsigned char * s, int min, int max); + +extern int in_grouping(struct SN_env * z, unsigned char * s, int min, int max); +extern int in_grouping_b(struct SN_env * z, unsigned char * s, int min, int max); +extern int out_grouping(struct SN_env * z, unsigned char * s, int min, int max); +extern int out_grouping_b(struct SN_env * z, unsigned char * s, int min, int max); + +extern int eq_s(struct SN_env * z, int s_size, symbol * s); +extern int eq_s_b(struct SN_env * z, int s_size, symbol * s); +extern int eq_v(struct SN_env * z, symbol * p); +extern int eq_v_b(struct SN_env * z, symbol * p); + +extern int find_among(struct SN_env * z, struct among * v, int v_size); +extern int find_among_b(struct SN_env * z, struct among * v, int v_size); + +extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjustment); +extern int slice_from_s(struct SN_env * z, int s_size, symbol * s); +extern int slice_from_v(struct SN_env * z, symbol * p); +extern int slice_del(struct SN_env * z); + +extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, symbol * s); +extern int insert_v(struct SN_env * z, int bra, int ket, symbol * p); + +extern symbol * slice_to(struct SN_env * z, symbol * p); +extern symbol * assign_to(struct SN_env * z, symbol * p); + +extern void debug(struct SN_env * z, int number, int line_count); + +#endif diff --git a/src/contribs-lib/CLucene/snowball/runtime/utilities.c b/src/contribs-lib/CLucene/snowball/runtime/utilities.c new file mode 100644 index 00000000000..a6bfa5c76a5 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/runtime/utilities.c @@ -0,0 +1,446 @@ + +#include +#include +#include + +#include "header.h" + +#define unless(C) if(!(C)) + +#define CREATE_SIZE 1 + +extern symbol * create_s(void) { + symbol * p; + void * mem = malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol)); + if (mem == NULL) return NULL; + p = (symbol *) (HEAD + (char *) mem); + CAPACITY(p) = CREATE_SIZE; + SET_SIZE(p, CREATE_SIZE); + return p; +} + +extern void lose_s(symbol * p) { + if (p == NULL) return; + free((char *) p - HEAD); +} + +/* + new_p = X_skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c + if n +ve, or n characters backwards from p +c - 1 if n -ve. new_p is the new + position, or 0 on failure. + + -- used to implement hop and next in the utf8 case. +*/ + +extern int skip_utf8(const symbol * p, int c, int lb, int l, int n) { + int b; + if (n >= 0) { + for (; n > 0; n--) { + if (c >= l) return -1; + b = p[c++]; + if (b >= 0xC0) { /* 1100 0000 */ + while (c < l) { + b = p[c]; + if (b >= 0xC0 || b < 0x80) break; + /* break unless b is 10------ */ + c++; + } + } + } + } else { + for (; n < 0; n++) { + if (c <= lb) return -1; + b = p[--c]; + if (b >= 0x80) { /* 1000 0000 */ + while (c > lb) { + b = p[c]; + if (b >= 0xC0) break; /* 1100 0000 */ + c--; + } + } + } + } + return c; +} + +/* Code for character groupings: utf8 cases */ + +static int get_utf8(const symbol * p, int c, int l, int * slot) { + int b0, b1; + if (c >= l) return 0; + b0 = p[c++]; + if (b0 < 0xC0 || c == l) { /* 1100 0000 */ + * slot = b0; return 1; + } + b1 = p[c++]; + if (b0 < 0xE0 || c == l) { /* 1110 0000 */ + * slot = (b0 & 0x1F) << 6 | (b1 & 0x3F); return 2; + } + * slot = (b0 & 0xF) << 12 | (b1 & 0x3F) << 6 | (*p & 0x3F); return 3; +} + +static int get_b_utf8(const symbol * p, int c, int lb, int * slot) { + int b0, b1; + if (c <= lb) return 0; + b0 = p[--c]; + if (b0 < 0x80 || c == lb) { /* 1000 0000 */ + * slot = b0; return 1; + } + b1 = p[--c]; + if (b1 >= 0xC0 || c == lb) { /* 1100 0000 */ + * slot = (b1 & 0x1F) << 6 | (b0 & 0x3F); return 2; + } + * slot = (*p & 0xF) << 12 | (b1 & 0x3F) << 6 | (b0 & 0x3F); return 3; +} + +extern int in_grouping_U(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + int w = get_utf8(z->p, z->c, z->l, & ch); + unless (w) return 0; + if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c += w; return 1; +} + +extern int in_grouping_b_U(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + int w = get_b_utf8(z->p, z->c, z->lb, & ch); + unless (w) return 0; + if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c -= w; return 1; +} + +extern int out_grouping_U(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + int w = get_utf8(z->p, z->c, z->l, & ch); + unless (w) return 0; + unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c += w; return 1; +} + +extern int out_grouping_b_U(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + int w = get_b_utf8(z->p, z->c, z->lb, & ch); + unless (w) return 0; + unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c -= w; return 1; +} + +/* Code for character groupings: non-utf8 cases */ + +extern int in_grouping(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + if (z->c >= z->l) return 0; + ch = z->p[z->c]; + if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c++; return 1; +} + +extern int in_grouping_b(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + if (z->c <= z->lb) return 0; + ch = z->p[z->c - 1]; + if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c--; return 1; +} + +extern int out_grouping(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + if (z->c >= z->l) return 0; + ch = z->p[z->c]; + unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c++; return 1; +} + +extern int out_grouping_b(struct SN_env * z, unsigned char * s, int min, int max) { + int ch; + if (z->c <= z->lb) return 0; + ch = z->p[z->c - 1]; + unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return 0; + z->c--; return 1; +} + +extern int eq_s(struct SN_env * z, int s_size, symbol * s) { + if (z->l - z->c < s_size || memcmp(z->p + z->c, s, s_size * sizeof(symbol)) != 0) return 0; + z->c += s_size; return 1; +} + +extern int eq_s_b(struct SN_env * z, int s_size, symbol * s) { + if (z->c - z->lb < s_size || memcmp(z->p + z->c - s_size, s, s_size * sizeof(symbol)) != 0) return 0; + z->c -= s_size; return 1; +} + +extern int eq_v(struct SN_env * z, symbol * p) { + return eq_s(z, SIZE(p), p); +} + +extern int eq_v_b(struct SN_env * z, symbol * p) { + return eq_s_b(z, SIZE(p), p); +} + +extern int find_among(struct SN_env * z, struct among * v, int v_size) { + + int i = 0; + int j = v_size; + + int c = z->c; int l = z->l; + symbol * q = z->p + c; + + struct among * w; + + int common_i = 0; + int common_j = 0; + + int first_key_inspected = 0; + + while(1) { + int k = i + ((j - i) >> 1); + int diff = 0; + int common = common_i < common_j ? common_i : common_j; /* smaller */ + w = v + k; + { + int i; for (i = common; i < w->s_size; i++) { + if (c + common == l) { diff = -1; break; } + diff = q[common] - w->s[i]; + if (diff != 0) break; + common++; + } + } + if (diff < 0) { j = k; common_j = common; } + else { i = k; common_i = common; } + if (j - i <= 1) { + if (i > 0) break; /* v->s has been inspected */ + if (j == i) break; /* only one item in v */ + + /* - but now we need to go round once more to get + v->s inspected. This looks messy, but is actually + the optimal approach. */ + + if (first_key_inspected) break; + first_key_inspected = 1; + } + } + while(1) { + w = v + i; + if (common_i >= w->s_size) { + z->c = c + w->s_size; + if (w->function == 0) return w->result; + { + int res = w->function(z); + z->c = c + w->s_size; + if (res) return w->result; + } + } + i = w->substring_i; + if (i < 0) return 0; + } +} + +/* find_among_b is for backwards processing. Same comments apply */ + +extern int find_among_b(struct SN_env * z, struct among * v, int v_size) { + + int i = 0; + int j = v_size; + + int c = z->c; int lb = z->lb; + symbol * q = z->p + c - 1; + + struct among * w; + + int common_i = 0; + int common_j = 0; + + int first_key_inspected = 0; + + while(1) { + int k = i + ((j - i) >> 1); + int diff = 0; + int common = common_i < common_j ? common_i : common_j; + w = v + k; + { + int i; for (i = w->s_size - 1 - common; i >= 0; i--) { + if (c - common == lb) { diff = -1; break; } + diff = q[- common] - w->s[i]; + if (diff != 0) break; + common++; + } + } + if (diff < 0) { j = k; common_j = common; } + else { i = k; common_i = common; } + if (j - i <= 1) { + if (i > 0) break; + if (j == i) break; + if (first_key_inspected) break; + first_key_inspected = 1; + } + } + while(1) { + w = v + i; + if (common_i >= w->s_size) { + z->c = c - w->s_size; + if (w->function == 0) return w->result; + { + int res = w->function(z); + z->c = c - w->s_size; + if (res) return w->result; + } + } + i = w->substring_i; + if (i < 0) return 0; + } +} + + +/* Increase the size of the buffer pointed to by p to at least n symbols. + * If insufficient memory, returns NULL and frees the old buffer. + */ +static symbol * increase_size(symbol * p, int n) { + symbol * q; + int new_size = n + 20; + void * mem = realloc((char *) p - HEAD, + HEAD + (new_size + 1) * sizeof(symbol)); + if (mem == NULL) { + lose_s(p); + return NULL; + } + q = (symbol *) (HEAD + (char *)mem); + CAPACITY(q) = new_size; + return q; +} + +/* to replace symbols between c_bra and c_ket in z->p by the + s_size symbols at s. + Returns 0 on success, -1 on error. + Also, frees z->p (and sets it to NULL) on error. +*/ +extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjptr) +{ + int adjustment; + int len; + if (z->p == NULL) { + z->p = create_s(); + if (z->p == NULL) return -1; + } + adjustment = s_size - (c_ket - c_bra); + len = SIZE(z->p); + if (adjustment != 0) { + if (adjustment + len > CAPACITY(z->p)) { + z->p = increase_size(z->p, adjustment + len); + if (z->p == NULL) return -1; + } + memmove(z->p + c_ket + adjustment, + z->p + c_ket, + (len - c_ket) * sizeof(symbol)); + SET_SIZE(z->p, adjustment + len); + z->l += adjustment; + if (z->c >= c_ket) + z->c += adjustment; + else + if (z->c > c_bra) + z->c = c_bra; + } + unless (s_size == 0) memmove(z->p + c_bra, s, s_size * sizeof(symbol)); + if (adjptr != NULL) + *adjptr = adjustment; + return 0; +} + +static int slice_check(struct SN_env * z) { + + if (z->bra < 0 || + z->bra > z->ket || + z->ket > z->l || + z->p == NULL || + z->l > SIZE(z->p)) /* this line could be removed */ + { +#if 0 + fprintf(stderr, "faulty slice operation:\n"); + debug(z, -1, 0); +#endif + return -1; + } + return 0; +} + +extern int slice_from_s(struct SN_env * z, int s_size, symbol * s) { + if (slice_check(z)) return -1; + return replace_s(z, z->bra, z->ket, s_size, s, NULL); +} + +extern int slice_from_v(struct SN_env * z, symbol * p) { + return slice_from_s(z, SIZE(p), p); +} + +extern int slice_del(struct SN_env * z) { + return slice_from_s(z, 0, 0); +} + +extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, symbol * s) { + int adjustment; + if (replace_s(z, bra, ket, s_size, s, &adjustment)) + return -1; + if (bra <= z->bra) z->bra += adjustment; + if (bra <= z->ket) z->ket += adjustment; + return 0; +} + +extern int insert_v(struct SN_env * z, int bra, int ket, symbol * p) { + int adjustment; + if (replace_s(z, bra, ket, SIZE(p), p, &adjustment)) + return -1; + if (bra <= z->bra) z->bra += adjustment; + if (bra <= z->ket) z->ket += adjustment; + return 0; +} + +extern symbol * slice_to(struct SN_env * z, symbol * p) { + if (slice_check(z)) { + lose_s(p); + return NULL; + } + { + int len = z->ket - z->bra; + if (CAPACITY(p) < len) { + p = increase_size(p, len); + if (p == NULL) + return NULL; + } + memmove(p, z->p + z->bra, len * sizeof(symbol)); + SET_SIZE(p, len); + } + return p; +} + +extern symbol * assign_to(struct SN_env * z, symbol * p) { + int len = z->l; + if (CAPACITY(p) < len) { + p = increase_size(p, len); + if (p == NULL) + return NULL; + } + memmove(p, z->p, len * sizeof(symbol)); + SET_SIZE(p, len); + return p; +} + +#if 0 +extern void debug(struct SN_env * z, int number, int line_count) { + int i; + int limit = SIZE(z->p); + /*if (number >= 0) printf("%3d (line %4d): '", number, line_count);*/ + if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit); + for (i = 0; i <= limit; i++) { + if (z->lb == i) printf("{"); + if (z->bra == i) printf("["); + if (z->c == i) printf("|"); + if (z->ket == i) printf("]"); + if (z->l == i) printf("}"); + if (i < limit) + { int ch = z->p[i]; + if (ch == 0) ch = '#'; + printf("%c", ch); + } + } + printf("'\n"); +} +#endif diff --git a/src/contribs-lib/CLucene/snowball/snowball.version b/src/contribs-lib/CLucene/snowball/snowball.version new file mode 100644 index 00000000000..73e4cbea2e1 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/snowball.version @@ -0,0 +1,2 @@ +May 2005 + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.c new file mode 100644 index 00000000000..fe0fa76c355 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.c @@ -0,0 +1,338 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int danish_ISO_8859_1_stem(struct SN_env * z); +static int r_undouble(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * danish_ISO_8859_1_create_env(void); +extern void danish_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[3] = { 'h', 'e', 'd' }; +static symbol s_0_1[5] = { 'e', 't', 'h', 'e', 'd' }; +static symbol s_0_2[4] = { 'e', 'r', 'e', 'd' }; +static symbol s_0_3[1] = { 'e' }; +static symbol s_0_4[5] = { 'e', 'r', 'e', 'd', 'e' }; +static symbol s_0_5[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_0_6[6] = { 'e', 'r', 'e', 'n', 'd', 'e' }; +static symbol s_0_7[3] = { 'e', 'n', 'e' }; +static symbol s_0_8[4] = { 'e', 'r', 'n', 'e' }; +static symbol s_0_9[3] = { 'e', 'r', 'e' }; +static symbol s_0_10[2] = { 'e', 'n' }; +static symbol s_0_11[5] = { 'h', 'e', 'd', 'e', 'n' }; +static symbol s_0_12[4] = { 'e', 'r', 'e', 'n' }; +static symbol s_0_13[2] = { 'e', 'r' }; +static symbol s_0_14[5] = { 'h', 'e', 'd', 'e', 'r' }; +static symbol s_0_15[4] = { 'e', 'r', 'e', 'r' }; +static symbol s_0_16[1] = { 's' }; +static symbol s_0_17[4] = { 'h', 'e', 'd', 's' }; +static symbol s_0_18[2] = { 'e', 's' }; +static symbol s_0_19[5] = { 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_20[7] = { 'e', 'r', 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_21[4] = { 'e', 'n', 'e', 's' }; +static symbol s_0_22[5] = { 'e', 'r', 'n', 'e', 's' }; +static symbol s_0_23[4] = { 'e', 'r', 'e', 's' }; +static symbol s_0_24[3] = { 'e', 'n', 's' }; +static symbol s_0_25[6] = { 'h', 'e', 'd', 'e', 'n', 's' }; +static symbol s_0_26[5] = { 'e', 'r', 'e', 'n', 's' }; +static symbol s_0_27[3] = { 'e', 'r', 's' }; +static symbol s_0_28[3] = { 'e', 't', 's' }; +static symbol s_0_29[5] = { 'e', 'r', 'e', 't', 's' }; +static symbol s_0_30[2] = { 'e', 't' }; +static symbol s_0_31[4] = { 'e', 'r', 'e', 't' }; + +static struct among a_0[32] = +{ +/* 0 */ { 3, s_0_0, -1, 1, 0}, +/* 1 */ { 5, s_0_1, 0, 1, 0}, +/* 2 */ { 4, s_0_2, -1, 1, 0}, +/* 3 */ { 1, s_0_3, -1, 1, 0}, +/* 4 */ { 5, s_0_4, 3, 1, 0}, +/* 5 */ { 4, s_0_5, 3, 1, 0}, +/* 6 */ { 6, s_0_6, 5, 1, 0}, +/* 7 */ { 3, s_0_7, 3, 1, 0}, +/* 8 */ { 4, s_0_8, 3, 1, 0}, +/* 9 */ { 3, s_0_9, 3, 1, 0}, +/* 10 */ { 2, s_0_10, -1, 1, 0}, +/* 11 */ { 5, s_0_11, 10, 1, 0}, +/* 12 */ { 4, s_0_12, 10, 1, 0}, +/* 13 */ { 2, s_0_13, -1, 1, 0}, +/* 14 */ { 5, s_0_14, 13, 1, 0}, +/* 15 */ { 4, s_0_15, 13, 1, 0}, +/* 16 */ { 1, s_0_16, -1, 2, 0}, +/* 17 */ { 4, s_0_17, 16, 1, 0}, +/* 18 */ { 2, s_0_18, 16, 1, 0}, +/* 19 */ { 5, s_0_19, 18, 1, 0}, +/* 20 */ { 7, s_0_20, 19, 1, 0}, +/* 21 */ { 4, s_0_21, 18, 1, 0}, +/* 22 */ { 5, s_0_22, 18, 1, 0}, +/* 23 */ { 4, s_0_23, 18, 1, 0}, +/* 24 */ { 3, s_0_24, 16, 1, 0}, +/* 25 */ { 6, s_0_25, 24, 1, 0}, +/* 26 */ { 5, s_0_26, 24, 1, 0}, +/* 27 */ { 3, s_0_27, 16, 1, 0}, +/* 28 */ { 3, s_0_28, 16, 1, 0}, +/* 29 */ { 5, s_0_29, 28, 1, 0}, +/* 30 */ { 2, s_0_30, -1, 1, 0}, +/* 31 */ { 4, s_0_31, 30, 1, 0} +}; + +static symbol s_1_0[2] = { 'g', 'd' }; +static symbol s_1_1[2] = { 'd', 't' }; +static symbol s_1_2[2] = { 'g', 't' }; +static symbol s_1_3[2] = { 'k', 't' }; + +static struct among a_1[4] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'g' }; +static symbol s_2_1[3] = { 'l', 'i', 'g' }; +static symbol s_2_2[4] = { 'e', 'l', 'i', 'g' }; +static symbol s_2_3[3] = { 'e', 'l', 's' }; +static symbol s_2_4[4] = { 'l', 0xF8, 's', 't' }; + +static struct among a_2[5] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 4, s_2_2, 1, 1, 0}, +/* 3 */ { 3, s_2_3, -1, 1, 0}, +/* 4 */ { 4, s_2_4, -1, 2, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; + +static unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }; + +static symbol s_0[] = { 's', 't' }; +static symbol s_1[] = { 'i', 'g' }; +static symbol s_2[] = { 'l', 0xF8, 's' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 33 */ + { int c = z->c + 3; + if (0 > c || c > z->l) return 0; + z->c = c; /* hop, line 33 */ + } + z->I[1] = z->c; /* setmark x, line 33 */ + z->c = c_test; + } + while(1) { /* goto, line 34 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 248))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + if (z->c >= z->l) return 0; + z->c++; /* goto, line 34 */ + } + while(1) { /* gopast, line 34 */ + if (!(out_grouping(z, g_v, 97, 248))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 34 */ + } + z->I[0] = z->c; /* setmark p1, line 34 */ + /* try, line 35 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 41 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 41 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 41 */ + among_var = find_among_b(z, a_0, 32); /* substring, line 41 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 41 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 48 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b(z, g_s_ending, 97, 229))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 50 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 55 */ + { int m3; /* setlimit, line 56 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 56 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 56 */ + if (!(find_among_b(z, a_1, 4))) { z->lb = m3; return 0; } /* substring, line 56 */ + z->bra = z->c; /* ], line 56 */ + z->lb = m3; + } + z->c = z->l - m_test; + } + if (z->c <= z->lb) return 0; + z->c--; /* next, line 62 */ + z->bra = z->c; /* ], line 62 */ + { int ret; + ret = slice_del(z); /* delete, line 62 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 66 */ + z->ket = z->c; /* [, line 66 */ + if (!(eq_s_b(z, 2, s_0))) goto lab0; + z->bra = z->c; /* ], line 66 */ + if (!(eq_s_b(z, 2, s_1))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 66 */ + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m; + } + { int m3; /* setlimit, line 67 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 67 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 67 */ + among_var = find_among_b(z, a_2, 5); /* substring, line 67 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 67 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 70 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* do, line 70 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab1; /* call consonant_pair, line 70 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_2); /* <-, line 72 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_undouble(struct SN_env * z) { + { int m3; /* setlimit, line 76 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 76 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 76 */ + if (!(out_grouping_b(z, g_v, 97, 248))) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 76 */ + z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */ + if (z->S[0] == 0) return -1; /* -> ch, line 76 */ + z->lb = m3; + } + if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */ + { int ret; + ret = slice_del(z); /* delete, line 78 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int danish_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 84 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 84 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 85 */ + + { int m = z->l - z->c; (void) m; /* do, line 86 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 86 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 87 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 87 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 88 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 88 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 89 */ + { int ret = r_undouble(z); + if (ret == 0) goto lab4; /* call undouble, line 89 */ + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * danish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 0); } + +extern void danish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.h new file mode 100644 index 00000000000..49c5559cdfc --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_danish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * danish_ISO_8859_1_create_env(void); +extern void danish_ISO_8859_1_close_env(struct SN_env * z); + +extern int danish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.c new file mode 100644 index 00000000000..36de3b50f5d --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.c @@ -0,0 +1,635 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int dutch_ISO_8859_1_stem(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_undouble(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_en_ending(struct SN_env * z); +static int r_e_ending(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * dutch_ISO_8859_1_create_env(void); +extern void dutch_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 0xE1 }; +static symbol s_0_2[1] = { 0xE4 }; +static symbol s_0_3[1] = { 0xE9 }; +static symbol s_0_4[1] = { 0xEB }; +static symbol s_0_5[1] = { 0xED }; +static symbol s_0_6[1] = { 0xEF }; +static symbol s_0_7[1] = { 0xF3 }; +static symbol s_0_8[1] = { 0xF6 }; +static symbol s_0_9[1] = { 0xFA }; +static symbol s_0_10[1] = { 0xFC }; + +static struct among a_0[11] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 1, s_0_1, 0, 1, 0}, +/* 2 */ { 1, s_0_2, 0, 1, 0}, +/* 3 */ { 1, s_0_3, 0, 2, 0}, +/* 4 */ { 1, s_0_4, 0, 2, 0}, +/* 5 */ { 1, s_0_5, 0, 3, 0}, +/* 6 */ { 1, s_0_6, 0, 3, 0}, +/* 7 */ { 1, s_0_7, 0, 4, 0}, +/* 8 */ { 1, s_0_8, 0, 4, 0}, +/* 9 */ { 1, s_0_9, 0, 5, 0}, +/* 10 */ { 1, s_0_10, 0, 5, 0} +}; + +static symbol s_1_1[1] = { 'I' }; +static symbol s_1_2[1] = { 'Y' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 1, s_1_1, 0, 2, 0}, +/* 2 */ { 1, s_1_2, 0, 1, 0} +}; + +static symbol s_2_0[2] = { 'd', 'd' }; +static symbol s_2_1[2] = { 'k', 'k' }; +static symbol s_2_2[2] = { 't', 't' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 2, s_2_1, -1, -1, 0}, +/* 2 */ { 2, s_2_2, -1, -1, 0} +}; + +static symbol s_3_0[3] = { 'e', 'n', 'e' }; +static symbol s_3_1[2] = { 's', 'e' }; +static symbol s_3_2[2] = { 'e', 'n' }; +static symbol s_3_3[5] = { 'h', 'e', 'd', 'e', 'n' }; +static symbol s_3_4[1] = { 's' }; + +static struct among a_3[5] = +{ +/* 0 */ { 3, s_3_0, -1, 2, 0}, +/* 1 */ { 2, s_3_1, -1, 3, 0}, +/* 2 */ { 2, s_3_2, -1, 2, 0}, +/* 3 */ { 5, s_3_3, 2, 1, 0}, +/* 4 */ { 1, s_3_4, -1, 3, 0} +}; + +static symbol s_4_0[3] = { 'e', 'n', 'd' }; +static symbol s_4_1[2] = { 'i', 'g' }; +static symbol s_4_2[3] = { 'i', 'n', 'g' }; +static symbol s_4_3[4] = { 'l', 'i', 'j', 'k' }; +static symbol s_4_4[4] = { 'b', 'a', 'a', 'r' }; +static symbol s_4_5[3] = { 'b', 'a', 'r' }; + +static struct among a_4[6] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 2, 0}, +/* 2 */ { 3, s_4_2, -1, 1, 0}, +/* 3 */ { 4, s_4_3, -1, 3, 0}, +/* 4 */ { 4, s_4_4, -1, 4, 0}, +/* 5 */ { 3, s_4_5, -1, 5, 0} +}; + +static symbol s_5_0[2] = { 'a', 'a' }; +static symbol s_5_1[2] = { 'e', 'e' }; +static symbol s_5_2[2] = { 'o', 'o' }; +static symbol s_5_3[2] = { 'u', 'u' }; + +static struct among a_5[4] = +{ +/* 0 */ { 2, s_5_0, -1, -1, 0}, +/* 1 */ { 2, s_5_1, -1, -1, 0}, +/* 2 */ { 2, s_5_2, -1, -1, 0}, +/* 3 */ { 2, s_5_3, -1, -1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static unsigned char g_v_I[] = { 1, 0, 0, 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static unsigned char g_v_j[] = { 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static symbol s_0[] = { 'a' }; +static symbol s_1[] = { 'e' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'o' }; +static symbol s_4[] = { 'u' }; +static symbol s_5[] = { 'y' }; +static symbol s_6[] = { 'Y' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 'I' }; +static symbol s_9[] = { 'y' }; +static symbol s_10[] = { 'Y' }; +static symbol s_11[] = { 'y' }; +static symbol s_12[] = { 'i' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'g', 'e', 'm' }; +static symbol s_15[] = { 'h', 'e', 'i', 'd' }; +static symbol s_16[] = { 'h', 'e', 'i', 'd' }; +static symbol s_17[] = { 'c' }; +static symbol s_18[] = { 'e', 'n' }; +static symbol s_19[] = { 'i', 'g' }; +static symbol s_20[] = { 'e' }; +static symbol s_21[] = { 'e' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + { int c_test = z->c; /* test, line 42 */ + while(1) { /* repeat, line 42 */ + int c = z->c; + z->bra = z->c; /* [, line 43 */ + among_var = find_among(z, a_0, 11); /* substring, line 43 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 43 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 47 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 49 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 51 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 53 */ + if (ret < 0) return ret; + } + break; + case 6: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 54 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + { int c = z->c; /* try, line 57 */ + z->bra = z->c; /* [, line 57 */ + if (!(eq_s(z, 1, s_5))) { z->c = c; goto lab1; } + z->ket = z->c; /* ], line 57 */ + { int ret; + ret = slice_from_s(z, 1, s_6); /* <-, line 57 */ + if (ret < 0) return ret; + } + lab1: + ; + } + while(1) { /* repeat, line 58 */ + int c = z->c; + while(1) { /* goto, line 58 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 232))) goto lab3; + z->bra = z->c; /* [, line 59 */ + { int c = z->c; /* or, line 59 */ + if (!(eq_s(z, 1, s_7))) goto lab5; + z->ket = z->c; /* ], line 59 */ + if (!(in_grouping(z, g_v, 97, 232))) goto lab5; + { int ret; + ret = slice_from_s(z, 1, s_8); /* <-, line 59 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = c; + if (!(eq_s(z, 1, s_9))) goto lab3; + z->ket = z->c; /* ], line 60 */ + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 60 */ + if (ret < 0) return ret; + } + } + lab4: + z->c = c; + break; + lab3: + z->c = c; + if (z->c >= z->l) goto lab2; + z->c++; /* goto, line 58 */ + } + continue; + lab2: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + while(1) { /* gopast, line 69 */ + if (!(in_grouping(z, g_v, 97, 232))) goto lab0; + break; + lab0: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 69 */ + } + while(1) { /* gopast, line 69 */ + if (!(out_grouping(z, g_v, 97, 232))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 69 */ + } + z->I[0] = z->c; /* setmark p1, line 69 */ + /* try, line 70 */ + if (!(z->I[0] < 3)) goto lab2; + z->I[0] = 3; +lab2: + while(1) { /* gopast, line 71 */ + if (!(in_grouping(z, g_v, 97, 232))) goto lab3; + break; + lab3: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 71 */ + } + while(1) { /* gopast, line 71 */ + if (!(out_grouping(z, g_v, 97, 232))) goto lab4; + break; + lab4: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 71 */ + } + z->I[1] = z->c; /* setmark p2, line 71 */ + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 75 */ + int c = z->c; + z->bra = z->c; /* [, line 77 */ + among_var = find_among(z, a_1, 3); /* substring, line 77 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 77 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 80 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_undouble(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 91 */ + if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */ + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 91 */ + if (z->c <= z->lb) return 0; + z->c--; /* next, line 91 */ + z->bra = z->c; /* ], line 91 */ + { int ret; + ret = slice_del(z); /* delete, line 91 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_e_ending(struct SN_env * z) { + z->B[0] = 0; /* unset e_found, line 95 */ + z->ket = z->c; /* [, line 96 */ + if (!(eq_s_b(z, 1, s_13))) return 0; + z->bra = z->c; /* ], line 96 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 96 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 96 */ + if (!(out_grouping_b(z, g_v, 97, 232))) return 0; + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 96 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set e_found, line 97 */ + { int ret = r_undouble(z); + if (ret == 0) return 0; /* call undouble, line 98 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_en_ending(struct SN_env * z) { + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 102 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* and, line 102 */ + if (!(out_grouping_b(z, g_v, 97, 232))) return 0; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* not, line 102 */ + if (!(eq_s_b(z, 3, s_14))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + } + { int ret; + ret = slice_del(z); /* delete, line 102 */ + if (ret < 0) return ret; + } + { int ret = r_undouble(z); + if (ret == 0) return 0; /* call undouble, line 103 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 107 */ + z->ket = z->c; /* [, line 108 */ + among_var = find_among_b(z, a_3, 5); /* substring, line 108 */ + if (!(among_var)) goto lab0; + z->bra = z->c; /* ], line 108 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 110 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_15); /* <-, line 110 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_en_ending(z); + if (ret == 0) goto lab0; /* call en_ending, line 113 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 116 */ + if (ret < 0) return ret; + } + if (!(out_grouping_b(z, g_v_j, 97, 232))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 116 */ + if (ret < 0) return ret; + } + break; + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 120 */ + { int ret = r_e_ending(z); + if (ret == 0) goto lab1; /* call e_ending, line 120 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 122 */ + z->ket = z->c; /* [, line 122 */ + if (!(eq_s_b(z, 4, s_16))) goto lab2; + z->bra = z->c; /* ], line 122 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 122 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 122 */ + if (!(eq_s_b(z, 1, s_17))) goto lab3; + goto lab2; + lab3: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 122 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 123 */ + if (!(eq_s_b(z, 2, s_18))) goto lab2; + z->bra = z->c; /* ], line 123 */ + { int ret = r_en_ending(z); + if (ret == 0) goto lab2; /* call en_ending, line 123 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 126 */ + z->ket = z->c; /* [, line 127 */ + among_var = find_among_b(z, a_4, 6); /* substring, line 127 */ + if (!(among_var)) goto lab4; + z->bra = z->c; /* ], line 127 */ + switch(among_var) { + case 0: goto lab4; + case 1: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 129 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 129 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* or, line 130 */ + z->ket = z->c; /* [, line 130 */ + if (!(eq_s_b(z, 2, s_19))) goto lab6; + z->bra = z->c; /* ], line 130 */ + { int ret = r_R2(z); + if (ret == 0) goto lab6; /* call R2, line 130 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 130 */ + if (!(eq_s_b(z, 1, s_20))) goto lab7; + goto lab6; + lab7: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 130 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_undouble(z); + if (ret == 0) goto lab4; /* call undouble, line 130 */ + if (ret < 0) return ret; + } + } + lab5: + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 133 */ + if (!(eq_s_b(z, 1, s_21))) goto lab8; + goto lab4; + lab8: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 136 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 136 */ + if (ret < 0) return ret; + } + { int ret = r_e_ending(z); + if (ret == 0) goto lab4; /* call e_ending, line 136 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 139 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 142 */ + if (ret < 0) return ret; + } + if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */ + { int ret; + ret = slice_del(z); /* delete, line 142 */ + if (ret < 0) return ret; + } + break; + } + lab4: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 146 */ + if (!(out_grouping_b(z, g_v_I, 73, 232))) goto lab9; + { int m_test = z->l - z->c; /* test, line 148 */ + if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */ + if (!(out_grouping_b(z, g_v, 97, 232))) goto lab9; + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 152 */ + if (z->c <= z->lb) goto lab9; + z->c--; /* next, line 152 */ + z->bra = z->c; /* ], line 152 */ + { int ret; + ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + return 1; +} + +extern int dutch_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 159 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 159 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 160 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 160 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 161 */ + + { int m = z->l - z->c; (void) m; /* do, line 162 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab2; /* call standard_suffix, line 162 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 163 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab3; /* call postlude, line 163 */ + if (ret < 0) return ret; + } + lab3: + z->c = c; + } + return 1; +} + +extern struct SN_env * dutch_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void dutch_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.h new file mode 100644 index 00000000000..e67d11152cd --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_dutch.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * dutch_ISO_8859_1_create_env(void); +extern void dutch_ISO_8859_1_close_env(struct SN_env * z); + +extern int dutch_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.c new file mode 100644 index 00000000000..d8625125d02 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.c @@ -0,0 +1,1156 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int english_ISO_8859_1_stem(struct SN_env * z); +static int r_exception2(struct SN_env * z); +static int r_exception1(struct SN_env * z); +static int r_Step_5(struct SN_env * z); +static int r_Step_4(struct SN_env * z); +static int r_Step_3(struct SN_env * z); +static int r_Step_2(struct SN_env * z); +static int r_Step_1c(struct SN_env * z); +static int r_Step_1b(struct SN_env * z); +static int r_Step_1a(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_shortv(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * english_ISO_8859_1_create_env(void); +extern void english_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[6] = { 'c', 'o', 'm', 'm', 'u', 'n' }; +static symbol s_0_1[5] = { 'g', 'e', 'n', 'e', 'r' }; + +static struct among a_0[2] = +{ +/* 0 */ { 6, s_0_0, -1, -1, 0}, +/* 1 */ { 5, s_0_1, -1, -1, 0} +}; + +static symbol s_1_0[1] = { '\'' }; +static symbol s_1_1[3] = { '\'', 's', '\'' }; +static symbol s_1_2[2] = { '\'', 's' }; + +static struct among a_1[3] = +{ +/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 1 */ { 3, s_1_1, 0, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0} +}; + +static symbol s_2_0[3] = { 'i', 'e', 'd' }; +static symbol s_2_1[1] = { 's' }; +static symbol s_2_2[3] = { 'i', 'e', 's' }; +static symbol s_2_3[4] = { 's', 's', 'e', 's' }; +static symbol s_2_4[2] = { 's', 's' }; +static symbol s_2_5[2] = { 'u', 's' }; + +static struct among a_2[6] = +{ +/* 0 */ { 3, s_2_0, -1, 2, 0}, +/* 1 */ { 1, s_2_1, -1, 3, 0}, +/* 2 */ { 3, s_2_2, 1, 2, 0}, +/* 3 */ { 4, s_2_3, 1, 1, 0}, +/* 4 */ { 2, s_2_4, 1, -1, 0}, +/* 5 */ { 2, s_2_5, 1, -1, 0} +}; + +static symbol s_3_1[2] = { 'b', 'b' }; +static symbol s_3_2[2] = { 'd', 'd' }; +static symbol s_3_3[2] = { 'f', 'f' }; +static symbol s_3_4[2] = { 'g', 'g' }; +static symbol s_3_5[2] = { 'b', 'l' }; +static symbol s_3_6[2] = { 'm', 'm' }; +static symbol s_3_7[2] = { 'n', 'n' }; +static symbol s_3_8[2] = { 'p', 'p' }; +static symbol s_3_9[2] = { 'r', 'r' }; +static symbol s_3_10[2] = { 'a', 't' }; +static symbol s_3_11[2] = { 't', 't' }; +static symbol s_3_12[2] = { 'i', 'z' }; + +static struct among a_3[13] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_3_1, 0, 2, 0}, +/* 2 */ { 2, s_3_2, 0, 2, 0}, +/* 3 */ { 2, s_3_3, 0, 2, 0}, +/* 4 */ { 2, s_3_4, 0, 2, 0}, +/* 5 */ { 2, s_3_5, 0, 1, 0}, +/* 6 */ { 2, s_3_6, 0, 2, 0}, +/* 7 */ { 2, s_3_7, 0, 2, 0}, +/* 8 */ { 2, s_3_8, 0, 2, 0}, +/* 9 */ { 2, s_3_9, 0, 2, 0}, +/* 10 */ { 2, s_3_10, 0, 1, 0}, +/* 11 */ { 2, s_3_11, 0, 2, 0}, +/* 12 */ { 2, s_3_12, 0, 1, 0} +}; + +static symbol s_4_0[2] = { 'e', 'd' }; +static symbol s_4_1[3] = { 'e', 'e', 'd' }; +static symbol s_4_2[3] = { 'i', 'n', 'g' }; +static symbol s_4_3[4] = { 'e', 'd', 'l', 'y' }; +static symbol s_4_4[5] = { 'e', 'e', 'd', 'l', 'y' }; +static symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' }; + +static struct among a_4[6] = +{ +/* 0 */ { 2, s_4_0, -1, 2, 0}, +/* 1 */ { 3, s_4_1, 0, 1, 0}, +/* 2 */ { 3, s_4_2, -1, 2, 0}, +/* 3 */ { 4, s_4_3, -1, 2, 0}, +/* 4 */ { 5, s_4_4, 3, 1, 0}, +/* 5 */ { 5, s_4_5, -1, 2, 0} +}; + +static symbol s_5_0[4] = { 'a', 'n', 'c', 'i' }; +static symbol s_5_1[4] = { 'e', 'n', 'c', 'i' }; +static symbol s_5_2[3] = { 'o', 'g', 'i' }; +static symbol s_5_3[2] = { 'l', 'i' }; +static symbol s_5_4[3] = { 'b', 'l', 'i' }; +static symbol s_5_5[4] = { 'a', 'b', 'l', 'i' }; +static symbol s_5_6[4] = { 'a', 'l', 'l', 'i' }; +static symbol s_5_7[5] = { 'f', 'u', 'l', 'l', 'i' }; +static symbol s_5_8[6] = { 'l', 'e', 's', 's', 'l', 'i' }; +static symbol s_5_9[5] = { 'o', 'u', 's', 'l', 'i' }; +static symbol s_5_10[5] = { 'e', 'n', 't', 'l', 'i' }; +static symbol s_5_11[5] = { 'a', 'l', 'i', 't', 'i' }; +static symbol s_5_12[6] = { 'b', 'i', 'l', 'i', 't', 'i' }; +static symbol s_5_13[5] = { 'i', 'v', 'i', 't', 'i' }; +static symbol s_5_14[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_5_15[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_5_16[5] = { 'a', 'l', 'i', 's', 'm' }; +static symbol s_5_17[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_5_18[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' }; +static symbol s_5_19[4] = { 'i', 'z', 'e', 'r' }; +static symbol s_5_20[4] = { 'a', 't', 'o', 'r' }; +static symbol s_5_21[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' }; +static symbol s_5_22[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' }; +static symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; + +static struct among a_5[24] = +{ +/* 0 */ { 4, s_5_0, -1, 3, 0}, +/* 1 */ { 4, s_5_1, -1, 2, 0}, +/* 2 */ { 3, s_5_2, -1, 13, 0}, +/* 3 */ { 2, s_5_3, -1, 16, 0}, +/* 4 */ { 3, s_5_4, 3, 12, 0}, +/* 5 */ { 4, s_5_5, 4, 4, 0}, +/* 6 */ { 4, s_5_6, 3, 8, 0}, +/* 7 */ { 5, s_5_7, 3, 14, 0}, +/* 8 */ { 6, s_5_8, 3, 15, 0}, +/* 9 */ { 5, s_5_9, 3, 10, 0}, +/* 10 */ { 5, s_5_10, 3, 5, 0}, +/* 11 */ { 5, s_5_11, -1, 8, 0}, +/* 12 */ { 6, s_5_12, -1, 12, 0}, +/* 13 */ { 5, s_5_13, -1, 11, 0}, +/* 14 */ { 6, s_5_14, -1, 1, 0}, +/* 15 */ { 7, s_5_15, 14, 7, 0}, +/* 16 */ { 5, s_5_16, -1, 8, 0}, +/* 17 */ { 5, s_5_17, -1, 7, 0}, +/* 18 */ { 7, s_5_18, 17, 6, 0}, +/* 19 */ { 4, s_5_19, -1, 6, 0}, +/* 20 */ { 4, s_5_20, -1, 7, 0}, +/* 21 */ { 7, s_5_21, -1, 11, 0}, +/* 22 */ { 7, s_5_22, -1, 9, 0}, +/* 23 */ { 7, s_5_23, -1, 10, 0} +}; + +static symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' }; +static symbol s_6_1[5] = { 'a', 't', 'i', 'v', 'e' }; +static symbol s_6_2[5] = { 'a', 'l', 'i', 'z', 'e' }; +static symbol s_6_3[5] = { 'i', 'c', 'i', 't', 'i' }; +static symbol s_6_4[4] = { 'i', 'c', 'a', 'l' }; +static symbol s_6_5[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_6_6[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_6_7[3] = { 'f', 'u', 'l' }; +static symbol s_6_8[4] = { 'n', 'e', 's', 's' }; + +static struct among a_6[9] = +{ +/* 0 */ { 5, s_6_0, -1, 4, 0}, +/* 1 */ { 5, s_6_1, -1, 6, 0}, +/* 2 */ { 5, s_6_2, -1, 3, 0}, +/* 3 */ { 5, s_6_3, -1, 4, 0}, +/* 4 */ { 4, s_6_4, -1, 4, 0}, +/* 5 */ { 6, s_6_5, -1, 1, 0}, +/* 6 */ { 7, s_6_6, 5, 2, 0}, +/* 7 */ { 3, s_6_7, -1, 5, 0}, +/* 8 */ { 4, s_6_8, -1, 5, 0} +}; + +static symbol s_7_0[2] = { 'i', 'c' }; +static symbol s_7_1[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_7_2[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_7_3[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_7_4[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_7_5[3] = { 'a', 't', 'e' }; +static symbol s_7_6[3] = { 'i', 'v', 'e' }; +static symbol s_7_7[3] = { 'i', 'z', 'e' }; +static symbol s_7_8[3] = { 'i', 't', 'i' }; +static symbol s_7_9[2] = { 'a', 'l' }; +static symbol s_7_10[3] = { 'i', 's', 'm' }; +static symbol s_7_11[3] = { 'i', 'o', 'n' }; +static symbol s_7_12[2] = { 'e', 'r' }; +static symbol s_7_13[3] = { 'o', 'u', 's' }; +static symbol s_7_14[3] = { 'a', 'n', 't' }; +static symbol s_7_15[3] = { 'e', 'n', 't' }; +static symbol s_7_16[4] = { 'm', 'e', 'n', 't' }; +static symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' }; + +static struct among a_7[18] = +{ +/* 0 */ { 2, s_7_0, -1, 1, 0}, +/* 1 */ { 4, s_7_1, -1, 1, 0}, +/* 2 */ { 4, s_7_2, -1, 1, 0}, +/* 3 */ { 4, s_7_3, -1, 1, 0}, +/* 4 */ { 4, s_7_4, -1, 1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 3, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 3, s_7_8, -1, 1, 0}, +/* 9 */ { 2, s_7_9, -1, 1, 0}, +/* 10 */ { 3, s_7_10, -1, 1, 0}, +/* 11 */ { 3, s_7_11, -1, 2, 0}, +/* 12 */ { 2, s_7_12, -1, 1, 0}, +/* 13 */ { 3, s_7_13, -1, 1, 0}, +/* 14 */ { 3, s_7_14, -1, 1, 0}, +/* 15 */ { 3, s_7_15, -1, 1, 0}, +/* 16 */ { 4, s_7_16, 15, 1, 0}, +/* 17 */ { 5, s_7_17, 16, 1, 0} +}; + +static symbol s_8_0[1] = { 'e' }; +static symbol s_8_1[1] = { 'l' }; + +static struct among a_8[2] = +{ +/* 0 */ { 1, s_8_0, -1, 1, 0}, +/* 1 */ { 1, s_8_1, -1, 2, 0} +}; + +static symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' }; +static symbol s_9_1[7] = { 'p', 'r', 'o', 'c', 'e', 'e', 'd' }; +static symbol s_9_2[6] = { 'e', 'x', 'c', 'e', 'e', 'd' }; +static symbol s_9_3[7] = { 'c', 'a', 'n', 'n', 'i', 'n', 'g' }; +static symbol s_9_4[6] = { 'i', 'n', 'n', 'i', 'n', 'g' }; +static symbol s_9_5[7] = { 'e', 'a', 'r', 'r', 'i', 'n', 'g' }; +static symbol s_9_6[7] = { 'h', 'e', 'r', 'r', 'i', 'n', 'g' }; +static symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' }; + +static struct among a_9[8] = +{ +/* 0 */ { 7, s_9_0, -1, -1, 0}, +/* 1 */ { 7, s_9_1, -1, -1, 0}, +/* 2 */ { 6, s_9_2, -1, -1, 0}, +/* 3 */ { 7, s_9_3, -1, -1, 0}, +/* 4 */ { 6, s_9_4, -1, -1, 0}, +/* 5 */ { 7, s_9_5, -1, -1, 0}, +/* 6 */ { 7, s_9_6, -1, -1, 0}, +/* 7 */ { 6, s_9_7, -1, -1, 0} +}; + +static symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' }; +static symbol s_10_1[5] = { 'a', 't', 'l', 'a', 's' }; +static symbol s_10_2[4] = { 'b', 'i', 'a', 's' }; +static symbol s_10_3[6] = { 'c', 'o', 's', 'm', 'o', 's' }; +static symbol s_10_4[5] = { 'd', 'y', 'i', 'n', 'g' }; +static symbol s_10_5[5] = { 'e', 'a', 'r', 'l', 'y' }; +static symbol s_10_6[6] = { 'g', 'e', 'n', 't', 'l', 'y' }; +static symbol s_10_7[4] = { 'h', 'o', 'w', 'e' }; +static symbol s_10_8[4] = { 'i', 'd', 'l', 'y' }; +static symbol s_10_9[5] = { 'l', 'y', 'i', 'n', 'g' }; +static symbol s_10_10[4] = { 'n', 'e', 'w', 's' }; +static symbol s_10_11[4] = { 'o', 'n', 'l', 'y' }; +static symbol s_10_12[6] = { 's', 'i', 'n', 'g', 'l', 'y' }; +static symbol s_10_13[5] = { 's', 'k', 'i', 'e', 's' }; +static symbol s_10_14[4] = { 's', 'k', 'i', 's' }; +static symbol s_10_15[3] = { 's', 'k', 'y' }; +static symbol s_10_16[5] = { 't', 'y', 'i', 'n', 'g' }; +static symbol s_10_17[4] = { 'u', 'g', 'l', 'y' }; + +static struct among a_10[18] = +{ +/* 0 */ { 5, s_10_0, -1, -1, 0}, +/* 1 */ { 5, s_10_1, -1, -1, 0}, +/* 2 */ { 4, s_10_2, -1, -1, 0}, +/* 3 */ { 6, s_10_3, -1, -1, 0}, +/* 4 */ { 5, s_10_4, -1, 3, 0}, +/* 5 */ { 5, s_10_5, -1, 9, 0}, +/* 6 */ { 6, s_10_6, -1, 7, 0}, +/* 7 */ { 4, s_10_7, -1, -1, 0}, +/* 8 */ { 4, s_10_8, -1, 6, 0}, +/* 9 */ { 5, s_10_9, -1, 4, 0}, +/* 10 */ { 4, s_10_10, -1, -1, 0}, +/* 11 */ { 4, s_10_11, -1, 10, 0}, +/* 12 */ { 6, s_10_12, -1, 11, 0}, +/* 13 */ { 5, s_10_13, -1, 2, 0}, +/* 14 */ { 4, s_10_14, -1, 1, 0}, +/* 15 */ { 3, s_10_15, -1, -1, 0}, +/* 16 */ { 5, s_10_16, -1, 5, 0}, +/* 17 */ { 4, s_10_17, -1, 8, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1 }; + +static unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; + +static unsigned char g_valid_LI[] = { 55, 141, 2 }; + +static symbol s_0[] = { '\'' }; +static symbol s_1[] = { 'y' }; +static symbol s_2[] = { 'Y' }; +static symbol s_3[] = { 'y' }; +static symbol s_4[] = { 'Y' }; +static symbol s_5[] = { 's', 's' }; +static symbol s_6[] = { 'i', 'e' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 'e', 'e' }; +static symbol s_9[] = { 'e' }; +static symbol s_10[] = { 'e' }; +static symbol s_11[] = { 'y' }; +static symbol s_12[] = { 'Y' }; +static symbol s_13[] = { 'i' }; +static symbol s_14[] = { 't', 'i', 'o', 'n' }; +static symbol s_15[] = { 'e', 'n', 'c', 'e' }; +static symbol s_16[] = { 'a', 'n', 'c', 'e' }; +static symbol s_17[] = { 'a', 'b', 'l', 'e' }; +static symbol s_18[] = { 'e', 'n', 't' }; +static symbol s_19[] = { 'i', 'z', 'e' }; +static symbol s_20[] = { 'a', 't', 'e' }; +static symbol s_21[] = { 'a', 'l' }; +static symbol s_22[] = { 'f', 'u', 'l' }; +static symbol s_23[] = { 'o', 'u', 's' }; +static symbol s_24[] = { 'i', 'v', 'e' }; +static symbol s_25[] = { 'b', 'l', 'e' }; +static symbol s_26[] = { 'l' }; +static symbol s_27[] = { 'o', 'g' }; +static symbol s_28[] = { 'f', 'u', 'l' }; +static symbol s_29[] = { 'l', 'e', 's', 's' }; +static symbol s_30[] = { 't', 'i', 'o', 'n' }; +static symbol s_31[] = { 'a', 't', 'e' }; +static symbol s_32[] = { 'a', 'l' }; +static symbol s_33[] = { 'i', 'c' }; +static symbol s_34[] = { 's' }; +static symbol s_35[] = { 't' }; +static symbol s_36[] = { 'l' }; +static symbol s_37[] = { 's', 'k', 'i' }; +static symbol s_38[] = { 's', 'k', 'y' }; +static symbol s_39[] = { 'd', 'i', 'e' }; +static symbol s_40[] = { 'l', 'i', 'e' }; +static symbol s_41[] = { 't', 'i', 'e' }; +static symbol s_42[] = { 'i', 'd', 'l' }; +static symbol s_43[] = { 'g', 'e', 'n', 't', 'l' }; +static symbol s_44[] = { 'u', 'g', 'l', 'i' }; +static symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' }; +static symbol s_46[] = { 'o', 'n', 'l', 'i' }; +static symbol s_47[] = { 's', 'i', 'n', 'g', 'l' }; +static symbol s_48[] = { 'Y' }; +static symbol s_49[] = { 'y' }; + +static int r_prelude(struct SN_env * z) { + z->B[0] = 0; /* unset Y_found, line 26 */ + { int c = z->c; /* do, line 27 */ + z->bra = z->c; /* [, line 27 */ + if (!(eq_s(z, 1, s_0))) goto lab0; + z->ket = z->c; /* ], line 27 */ + { int ret; + ret = slice_del(z); /* delete, line 27 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 28 */ + z->bra = z->c; /* [, line 28 */ + if (!(eq_s(z, 1, s_1))) goto lab1; + z->ket = z->c; /* ], line 28 */ + if (!(in_grouping(z, g_v, 97, 121))) goto lab1; + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 28 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 28 */ + lab1: + z->c = c; + } + { int c = z->c; /* do, line 29 */ + while(1) { /* repeat, line 29 */ + int c = z->c; + while(1) { /* goto, line 29 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 121))) goto lab4; + z->bra = z->c; /* [, line 29 */ + if (!(eq_s(z, 1, s_3))) goto lab4; + z->ket = z->c; /* ], line 29 */ + z->c = c; + break; + lab4: + z->c = c; + if (z->c >= z->l) goto lab3; + z->c++; /* goto, line 29 */ + } + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 29 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 29 */ + continue; + lab3: + z->c = c; + break; + } + z->c = c; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 35 */ + { int c = z->c; /* or, line 40 */ + if (!(find_among(z, a_0, 2))) goto lab2; /* among, line 36 */ + goto lab1; + lab2: + z->c = c; + while(1) { /* gopast, line 40 */ + if (!(in_grouping(z, g_v, 97, 121))) goto lab3; + break; + lab3: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 40 */ + } + while(1) { /* gopast, line 40 */ + if (!(out_grouping(z, g_v, 97, 121))) goto lab4; + break; + lab4: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 40 */ + } + } + lab1: + z->I[0] = z->c; /* setmark p1, line 41 */ + while(1) { /* gopast, line 42 */ + if (!(in_grouping(z, g_v, 97, 121))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 42 */ + } + while(1) { /* gopast, line 42 */ + if (!(out_grouping(z, g_v, 97, 121))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 42 */ + } + z->I[1] = z->c; /* setmark p2, line 42 */ + lab0: + z->c = c; + } + return 1; +} + +static int r_shortv(struct SN_env * z) { + { int m = z->l - z->c; (void) m; /* or, line 50 */ + if (!(out_grouping_b(z, g_v_WXY, 89, 121))) goto lab1; + if (!(in_grouping_b(z, g_v, 97, 121))) goto lab1; + if (!(out_grouping_b(z, g_v, 97, 121))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(out_grouping_b(z, g_v, 97, 121))) return 0; + if (!(in_grouping_b(z, g_v, 97, 121))) return 0; + if (z->c > z->lb) return 0; /* atlimit, line 51 */ + } +lab0: + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_Step_1a(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* try, line 58 */ + z->ket = z->c; /* [, line 59 */ + among_var = find_among_b(z, a_1, 3); /* substring, line 59 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 59 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 61 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + z->ket = z->c; /* [, line 64 */ + among_var = find_among_b(z, a_2, 6); /* substring, line 64 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 64 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_5); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 67 */ + if (z->c <= z->lb) goto lab2; + z->c--; /* next, line 67 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 67 */ + { int ret; + ret = slice_from_s(z, 2, s_6); /* <-, line 67 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 67 */ + if (ret < 0) return ret; + } + } + lab1: + break; + case 3: + if (z->c <= z->lb) return 0; + z->c--; /* next, line 68 */ + while(1) { /* gopast, line 68 */ + if (!(in_grouping_b(z, g_v, 97, 121))) goto lab3; + break; + lab3: + if (z->c <= z->lb) return 0; + z->c--; /* gopast, line 68 */ + } + { int ret; + ret = slice_del(z); /* delete, line 68 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_1b(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 74 */ + among_var = find_among_b(z, a_4, 6); /* substring, line 74 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 74 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 76 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m_test = z->l - z->c; /* test, line 79 */ + while(1) { /* gopast, line 79 */ + if (!(in_grouping_b(z, g_v, 97, 121))) goto lab0; + break; + lab0: + if (z->c <= z->lb) return 0; + z->c--; /* gopast, line 79 */ + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 79 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 80 */ + among_var = find_among_b(z, a_3, 13); /* substring, line 80 */ + if (!(among_var)) return 0; + z->c = z->l - m_test; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 82 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + case 2: + z->ket = z->c; /* [, line 85 */ + if (z->c <= z->lb) return 0; + z->c--; /* next, line 85 */ + z->bra = z->c; /* ], line 85 */ + { int ret; + ret = slice_del(z); /* delete, line 85 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c != z->I[0]) return 0; /* atmark, line 86 */ + { int m_test = z->l - z->c; /* test, line 86 */ + { int ret = r_shortv(z); + if (ret == 0) return 0; /* call shortv, line 86 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 86 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + } + break; + } + return 1; +} + +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; /* [, line 93 */ + { int m = z->l - z->c; (void) m; /* or, line 93 */ + if (!(eq_s_b(z, 1, s_11))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_12))) return 0; + } +lab0: + z->bra = z->c; /* ], line 93 */ + if (!(out_grouping_b(z, g_v, 97, 121))) return 0; + { int m = z->l - z->c; (void) m; /* not, line 94 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 94 */ + return 0; + lab2: + z->c = z->l - m; + } + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 95 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_2(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 99 */ + among_var = find_among_b(z, a_5, 24); /* substring, line 99 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 99 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 99 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_14); /* <-, line 100 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_15); /* <-, line 101 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_16); /* <-, line 102 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 4, s_17); /* <-, line 103 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 104 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 3, s_19); /* <-, line 106 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 108 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 2, s_21); /* <-, line 110 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 3, s_22); /* <-, line 111 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 3, s_23); /* <-, line 113 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 3, s_24); /* <-, line 115 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret; + ret = slice_from_s(z, 3, s_25); /* <-, line 117 */ + if (ret < 0) return ret; + } + break; + case 13: + if (!(eq_s_b(z, 1, s_26))) return 0; + { int ret; + ret = slice_from_s(z, 2, s_27); /* <-, line 118 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret; + ret = slice_from_s(z, 3, s_28); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 15: + { int ret; + ret = slice_from_s(z, 4, s_29); /* <-, line 120 */ + if (ret < 0) return ret; + } + break; + case 16: + if (!(in_grouping_b(z, g_valid_LI, 99, 116))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 121 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_3(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 126 */ + among_var = find_among_b(z, a_6, 9); /* substring, line 126 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 126 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 126 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_30); /* <-, line 127 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_31); /* <-, line 128 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 2, s_32); /* <-, line 129 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 2, s_33); /* <-, line 131 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 135 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 135 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_4(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 140 */ + among_var = find_among_b(z, a_7, 18); /* substring, line 140 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 140 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 140 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 144 */ + if (!(eq_s_b(z, 1, s_34))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_35))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 144 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_5(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_8, 2); /* substring, line 149 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 150 */ + { int ret = r_R2(z); + if (ret == 0) goto lab1; /* call R2, line 150 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 150 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 150 */ + { int ret = r_shortv(z); + if (ret == 0) goto lab2; /* call shortv, line 150 */ + if (ret < 0) return ret; + } + return 0; + lab2: + z->c = z->l - m; + } + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 150 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 151 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_36))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_exception2(struct SN_env * z) { + z->ket = z->c; /* [, line 157 */ + if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 157 */ + z->bra = z->c; /* ], line 157 */ + if (z->c > z->lb) return 0; /* atlimit, line 157 */ + return 1; +} + +static int r_exception1(struct SN_env * z) { + int among_var; + z->bra = z->c; /* [, line 169 */ + among_var = find_among(z, a_10, 18); /* substring, line 169 */ + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 169 */ + if (z->c < z->l) return 0; /* atlimit, line 169 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 3, s_37); /* <-, line 173 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_38); /* <-, line 174 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 3, s_39); /* <-, line 175 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 3, s_40); /* <-, line 176 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_41); /* <-, line 177 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 3, s_42); /* <-, line 181 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 5, s_43); /* <-, line 182 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 4, s_44); /* <-, line 183 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 5, s_45); /* <-, line 184 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 4, s_46); /* <-, line 185 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 5, s_47); /* <-, line 186 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + if (!(z->B[0])) return 0; /* Boolean test Y_found, line 202 */ + while(1) { /* repeat, line 202 */ + int c = z->c; + while(1) { /* goto, line 202 */ + int c = z->c; + z->bra = z->c; /* [, line 202 */ + if (!(eq_s(z, 1, s_48))) goto lab1; + z->ket = z->c; /* ], line 202 */ + z->c = c; + break; + lab1: + z->c = c; + if (z->c >= z->l) goto lab0; + z->c++; /* goto, line 202 */ + } + { int ret; + ret = slice_from_s(z, 1, s_49); /* <-, line 202 */ + if (ret < 0) return ret; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +extern int english_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* or, line 206 */ + { int ret = r_exception1(z); + if (ret == 0) goto lab1; /* call exception1, line 206 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = c; + { int c = z->c; /* not, line 207 */ + { int c = z->c + 3; + if (0 > c || c > z->l) goto lab3; + z->c = c; /* hop, line 207 */ + } + goto lab2; + lab3: + z->c = c; + } + goto lab0; + lab2: + z->c = c; + { int c = z->c; /* do, line 208 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab4; /* call prelude, line 208 */ + if (ret < 0) return ret; + } + lab4: + z->c = c; + } + { int c = z->c; /* do, line 209 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab5; /* call mark_regions, line 209 */ + if (ret < 0) return ret; + } + lab5: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 210 */ + + { int m = z->l - z->c; (void) m; /* do, line 212 */ + { int ret = r_Step_1a(z); + if (ret == 0) goto lab6; /* call Step_1a, line 212 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* or, line 214 */ + { int ret = r_exception2(z); + if (ret == 0) goto lab8; /* call exception2, line 214 */ + if (ret < 0) return ret; + } + goto lab7; + lab8: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 216 */ + { int ret = r_Step_1b(z); + if (ret == 0) goto lab9; /* call Step_1b, line 216 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 217 */ + { int ret = r_Step_1c(z); + if (ret == 0) goto lab10; /* call Step_1c, line 217 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 219 */ + { int ret = r_Step_2(z); + if (ret == 0) goto lab11; /* call Step_2, line 219 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 220 */ + { int ret = r_Step_3(z); + if (ret == 0) goto lab12; /* call Step_3, line 220 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 221 */ + { int ret = r_Step_4(z); + if (ret == 0) goto lab13; /* call Step_4, line 221 */ + if (ret < 0) return ret; + } + lab13: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 223 */ + { int ret = r_Step_5(z); + if (ret == 0) goto lab14; /* call Step_5, line 223 */ + if (ret < 0) return ret; + } + lab14: + z->c = z->l - m; + } + } + lab7: + z->c = z->lb; + { int c = z->c; /* do, line 226 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab15; /* call postlude, line 226 */ + if (ret < 0) return ret; + } + lab15: + z->c = c; + } + } +lab0: + return 1; +} + +extern struct SN_env * english_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void english_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.h new file mode 100644 index 00000000000..e685dcf7ef0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_english.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * english_ISO_8859_1_create_env(void); +extern void english_ISO_8859_1_close_env(struct SN_env * z); + +extern int english_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.c new file mode 100644 index 00000000000..0d851cd2c57 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.c @@ -0,0 +1,792 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int finnish_ISO_8859_1_stem(struct SN_env * z); +static int r_tidy(struct SN_env * z); +static int r_other_endings(struct SN_env * z); +static int r_t_plural(struct SN_env * z); +static int r_i_plural(struct SN_env * z); +static int r_case_ending(struct SN_env * z); +static int r_VI(struct SN_env * z); +static int r_LONG(struct SN_env * z); +static int r_possessive(struct SN_env * z); +static int r_particle_etc(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * finnish_ISO_8859_1_create_env(void); +extern void finnish_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[2] = { 'p', 'a' }; +static symbol s_0_1[3] = { 's', 't', 'i' }; +static symbol s_0_2[4] = { 'k', 'a', 'a', 'n' }; +static symbol s_0_3[3] = { 'h', 'a', 'n' }; +static symbol s_0_4[3] = { 'k', 'i', 'n' }; +static symbol s_0_5[3] = { 'h', 0xE4, 'n' }; +static symbol s_0_6[4] = { 'k', 0xE4, 0xE4, 'n' }; +static symbol s_0_7[2] = { 'k', 'o' }; +static symbol s_0_8[2] = { 'p', 0xE4 }; +static symbol s_0_9[2] = { 'k', 0xF6 }; + +static struct among a_0[10] = +{ +/* 0 */ { 2, s_0_0, -1, 1, 0}, +/* 1 */ { 3, s_0_1, -1, 2, 0}, +/* 2 */ { 4, s_0_2, -1, 1, 0}, +/* 3 */ { 3, s_0_3, -1, 1, 0}, +/* 4 */ { 3, s_0_4, -1, 1, 0}, +/* 5 */ { 3, s_0_5, -1, 1, 0}, +/* 6 */ { 4, s_0_6, -1, 1, 0}, +/* 7 */ { 2, s_0_7, -1, 1, 0}, +/* 8 */ { 2, s_0_8, -1, 1, 0}, +/* 9 */ { 2, s_0_9, -1, 1, 0} +}; + +static symbol s_1_0[3] = { 'l', 'l', 'a' }; +static symbol s_1_1[2] = { 'n', 'a' }; +static symbol s_1_2[3] = { 's', 's', 'a' }; +static symbol s_1_3[2] = { 't', 'a' }; +static symbol s_1_4[3] = { 'l', 't', 'a' }; +static symbol s_1_5[3] = { 's', 't', 'a' }; + +static struct among a_1[6] = +{ +/* 0 */ { 3, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 3, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 3, s_1_4, 3, -1, 0}, +/* 5 */ { 3, s_1_5, 3, -1, 0} +}; + +static symbol s_2_0[3] = { 'l', 'l', 0xE4 }; +static symbol s_2_1[2] = { 'n', 0xE4 }; +static symbol s_2_2[3] = { 's', 's', 0xE4 }; +static symbol s_2_3[2] = { 't', 0xE4 }; +static symbol s_2_4[3] = { 'l', 't', 0xE4 }; +static symbol s_2_5[3] = { 's', 't', 0xE4 }; + +static struct among a_2[6] = +{ +/* 0 */ { 3, s_2_0, -1, -1, 0}, +/* 1 */ { 2, s_2_1, -1, -1, 0}, +/* 2 */ { 3, s_2_2, -1, -1, 0}, +/* 3 */ { 2, s_2_3, -1, -1, 0}, +/* 4 */ { 3, s_2_4, 3, -1, 0}, +/* 5 */ { 3, s_2_5, 3, -1, 0} +}; + +static symbol s_3_0[3] = { 'l', 'l', 'e' }; +static symbol s_3_1[3] = { 'i', 'n', 'e' }; + +static struct among a_3[2] = +{ +/* 0 */ { 3, s_3_0, -1, -1, 0}, +/* 1 */ { 3, s_3_1, -1, -1, 0} +}; + +static symbol s_4_0[3] = { 'n', 's', 'a' }; +static symbol s_4_1[3] = { 'm', 'm', 'e' }; +static symbol s_4_2[3] = { 'n', 'n', 'e' }; +static symbol s_4_3[2] = { 'n', 'i' }; +static symbol s_4_4[2] = { 's', 'i' }; +static symbol s_4_5[2] = { 'a', 'n' }; +static symbol s_4_6[2] = { 'e', 'n' }; +static symbol s_4_7[2] = { 0xE4, 'n' }; +static symbol s_4_8[3] = { 'n', 's', 0xE4 }; + +static struct among a_4[9] = +{ +/* 0 */ { 3, s_4_0, -1, 3, 0}, +/* 1 */ { 3, s_4_1, -1, 3, 0}, +/* 2 */ { 3, s_4_2, -1, 3, 0}, +/* 3 */ { 2, s_4_3, -1, 2, 0}, +/* 4 */ { 2, s_4_4, -1, 1, 0}, +/* 5 */ { 2, s_4_5, -1, 4, 0}, +/* 6 */ { 2, s_4_6, -1, 6, 0}, +/* 7 */ { 2, s_4_7, -1, 5, 0}, +/* 8 */ { 3, s_4_8, -1, 3, 0} +}; + +static symbol s_5_0[2] = { 'a', 'a' }; +static symbol s_5_1[2] = { 'e', 'e' }; +static symbol s_5_2[2] = { 'i', 'i' }; +static symbol s_5_3[2] = { 'o', 'o' }; +static symbol s_5_4[2] = { 'u', 'u' }; +static symbol s_5_5[2] = { 0xE4, 0xE4 }; +static symbol s_5_6[2] = { 0xF6, 0xF6 }; + +static struct among a_5[7] = +{ +/* 0 */ { 2, s_5_0, -1, -1, 0}, +/* 1 */ { 2, s_5_1, -1, -1, 0}, +/* 2 */ { 2, s_5_2, -1, -1, 0}, +/* 3 */ { 2, s_5_3, -1, -1, 0}, +/* 4 */ { 2, s_5_4, -1, -1, 0}, +/* 5 */ { 2, s_5_5, -1, -1, 0}, +/* 6 */ { 2, s_5_6, -1, -1, 0} +}; + +static symbol s_6_0[1] = { 'a' }; +static symbol s_6_1[3] = { 'l', 'l', 'a' }; +static symbol s_6_2[2] = { 'n', 'a' }; +static symbol s_6_3[3] = { 's', 's', 'a' }; +static symbol s_6_4[2] = { 't', 'a' }; +static symbol s_6_5[3] = { 'l', 't', 'a' }; +static symbol s_6_6[3] = { 's', 't', 'a' }; +static symbol s_6_7[3] = { 't', 't', 'a' }; +static symbol s_6_8[3] = { 'l', 'l', 'e' }; +static symbol s_6_9[3] = { 'i', 'n', 'e' }; +static symbol s_6_10[3] = { 'k', 's', 'i' }; +static symbol s_6_11[1] = { 'n' }; +static symbol s_6_12[3] = { 'h', 'a', 'n' }; +static symbol s_6_13[3] = { 'd', 'e', 'n' }; +static symbol s_6_14[4] = { 's', 'e', 'e', 'n' }; +static symbol s_6_15[3] = { 'h', 'e', 'n' }; +static symbol s_6_16[4] = { 't', 't', 'e', 'n' }; +static symbol s_6_17[3] = { 'h', 'i', 'n' }; +static symbol s_6_18[4] = { 's', 'i', 'i', 'n' }; +static symbol s_6_19[3] = { 'h', 'o', 'n' }; +static symbol s_6_20[3] = { 'h', 0xE4, 'n' }; +static symbol s_6_21[3] = { 'h', 0xF6, 'n' }; +static symbol s_6_22[1] = { 0xE4 }; +static symbol s_6_23[3] = { 'l', 'l', 0xE4 }; +static symbol s_6_24[2] = { 'n', 0xE4 }; +static symbol s_6_25[3] = { 's', 's', 0xE4 }; +static symbol s_6_26[2] = { 't', 0xE4 }; +static symbol s_6_27[3] = { 'l', 't', 0xE4 }; +static symbol s_6_28[3] = { 's', 't', 0xE4 }; +static symbol s_6_29[3] = { 't', 't', 0xE4 }; + +static struct among a_6[30] = +{ +/* 0 */ { 1, s_6_0, -1, 8, 0}, +/* 1 */ { 3, s_6_1, 0, -1, 0}, +/* 2 */ { 2, s_6_2, 0, -1, 0}, +/* 3 */ { 3, s_6_3, 0, -1, 0}, +/* 4 */ { 2, s_6_4, 0, -1, 0}, +/* 5 */ { 3, s_6_5, 4, -1, 0}, +/* 6 */ { 3, s_6_6, 4, -1, 0}, +/* 7 */ { 3, s_6_7, 4, 9, 0}, +/* 8 */ { 3, s_6_8, -1, -1, 0}, +/* 9 */ { 3, s_6_9, -1, -1, 0}, +/* 10 */ { 3, s_6_10, -1, -1, 0}, +/* 11 */ { 1, s_6_11, -1, 7, 0}, +/* 12 */ { 3, s_6_12, 11, 1, 0}, +/* 13 */ { 3, s_6_13, 11, -1, r_VI}, +/* 14 */ { 4, s_6_14, 11, -1, r_LONG}, +/* 15 */ { 3, s_6_15, 11, 2, 0}, +/* 16 */ { 4, s_6_16, 11, -1, r_VI}, +/* 17 */ { 3, s_6_17, 11, 3, 0}, +/* 18 */ { 4, s_6_18, 11, -1, r_VI}, +/* 19 */ { 3, s_6_19, 11, 4, 0}, +/* 20 */ { 3, s_6_20, 11, 5, 0}, +/* 21 */ { 3, s_6_21, 11, 6, 0}, +/* 22 */ { 1, s_6_22, -1, 8, 0}, +/* 23 */ { 3, s_6_23, 22, -1, 0}, +/* 24 */ { 2, s_6_24, 22, -1, 0}, +/* 25 */ { 3, s_6_25, 22, -1, 0}, +/* 26 */ { 2, s_6_26, 22, -1, 0}, +/* 27 */ { 3, s_6_27, 26, -1, 0}, +/* 28 */ { 3, s_6_28, 26, -1, 0}, +/* 29 */ { 3, s_6_29, 26, 9, 0} +}; + +static symbol s_7_0[3] = { 'e', 'j', 'a' }; +static symbol s_7_1[3] = { 'm', 'm', 'a' }; +static symbol s_7_2[4] = { 'i', 'm', 'm', 'a' }; +static symbol s_7_3[3] = { 'm', 'p', 'a' }; +static symbol s_7_4[4] = { 'i', 'm', 'p', 'a' }; +static symbol s_7_5[3] = { 'm', 'm', 'i' }; +static symbol s_7_6[4] = { 'i', 'm', 'm', 'i' }; +static symbol s_7_7[3] = { 'm', 'p', 'i' }; +static symbol s_7_8[4] = { 'i', 'm', 'p', 'i' }; +static symbol s_7_9[3] = { 'e', 'j', 0xE4 }; +static symbol s_7_10[3] = { 'm', 'm', 0xE4 }; +static symbol s_7_11[4] = { 'i', 'm', 'm', 0xE4 }; +static symbol s_7_12[3] = { 'm', 'p', 0xE4 }; +static symbol s_7_13[4] = { 'i', 'm', 'p', 0xE4 }; + +static struct among a_7[14] = +{ +/* 0 */ { 3, s_7_0, -1, -1, 0}, +/* 1 */ { 3, s_7_1, -1, 1, 0}, +/* 2 */ { 4, s_7_2, 1, -1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 4, s_7_4, 3, -1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 4, s_7_6, 5, -1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 4, s_7_8, 7, -1, 0}, +/* 9 */ { 3, s_7_9, -1, -1, 0}, +/* 10 */ { 3, s_7_10, -1, 1, 0}, +/* 11 */ { 4, s_7_11, 10, -1, 0}, +/* 12 */ { 3, s_7_12, -1, 1, 0}, +/* 13 */ { 4, s_7_13, 12, -1, 0} +}; + +static symbol s_8_0[1] = { 'i' }; +static symbol s_8_1[1] = { 'j' }; + +static struct among a_8[2] = +{ +/* 0 */ { 1, s_8_0, -1, -1, 0}, +/* 1 */ { 1, s_8_1, -1, -1, 0} +}; + +static symbol s_9_0[3] = { 'm', 'm', 'a' }; +static symbol s_9_1[4] = { 'i', 'm', 'm', 'a' }; + +static struct among a_9[2] = +{ +/* 0 */ { 3, s_9_0, -1, 1, 0}, +/* 1 */ { 4, s_9_1, 0, -1, 0} +}; + +static unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; + +static unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static symbol s_0[] = { 'k' }; +static symbol s_1[] = { 'k', 's', 'e' }; +static symbol s_2[] = { 'k', 's', 'i' }; +static symbol s_3[] = { 'i' }; +static symbol s_4[] = { 'a' }; +static symbol s_5[] = { 'e' }; +static symbol s_6[] = { 'i' }; +static symbol s_7[] = { 'o' }; +static symbol s_8[] = { 0xE4 }; +static symbol s_9[] = { 0xF6 }; +static symbol s_10[] = { 'i', 'e' }; +static symbol s_11[] = { 'e' }; +static symbol s_12[] = { 'p', 'o' }; +static symbol s_13[] = { 't' }; +static symbol s_14[] = { 'p', 'o' }; +static symbol s_15[] = { 'j' }; +static symbol s_16[] = { 'o' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'o' }; +static symbol s_19[] = { 'j' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + while(1) { /* goto, line 46 */ + int c = z->c; + if (!(in_grouping(z, g_V1, 97, 246))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + if (z->c >= z->l) return 0; + z->c++; /* goto, line 46 */ + } + while(1) { /* gopast, line 46 */ + if (!(out_grouping(z, g_V1, 97, 246))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 46 */ + } + z->I[0] = z->c; /* setmark p1, line 46 */ + while(1) { /* goto, line 47 */ + int c = z->c; + if (!(in_grouping(z, g_V1, 97, 246))) goto lab2; + z->c = c; + break; + lab2: + z->c = c; + if (z->c >= z->l) return 0; + z->c++; /* goto, line 47 */ + } + while(1) { /* gopast, line 47 */ + if (!(out_grouping(z, g_V1, 97, 246))) goto lab3; + break; + lab3: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 47 */ + } + z->I[1] = z->c; /* setmark p2, line 47 */ + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_particle_etc(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 55 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 55 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 55 */ + among_var = find_among_b(z, a_0, 10); /* substring, line 55 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 55 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(in_grouping_b(z, g_particle_end, 97, 246))) return 0; + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 64 */ + if (ret < 0) return ret; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 66 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_possessive(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 69 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 69 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 69 */ + among_var = find_among_b(z, a_4, 9); /* substring, line 69 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 69 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 72 */ + if (!(eq_s_b(z, 1, s_0))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 72 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 74 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 74 */ + if (!(eq_s_b(z, 3, s_1))) return 0; + z->bra = z->c; /* ], line 74 */ + { int ret; + ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 78 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */ + { int ret; + ret = slice_del(z); /* delete, line 81 */ + if (ret < 0) return ret; + } + break; + case 5: + if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */ + { int ret; + ret = slice_del(z); /* delete, line 84 */ + if (ret < 0) return ret; + } + break; + case 6: + if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */ + { int ret; + ret = slice_del(z); /* delete, line 86 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_LONG(struct SN_env * z) { + if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */ + return 1; +} + +static int r_VI(struct SN_env * z) { + if (!(eq_s_b(z, 1, s_3))) return 0; + if (!(in_grouping_b(z, g_V2, 97, 246))) return 0; + return 1; +} + +static int r_case_ending(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 96 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 96 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 96 */ + among_var = find_among_b(z, a_6, 30); /* substring, line 96 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 96 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(eq_s_b(z, 1, s_4))) return 0; + break; + case 2: + if (!(eq_s_b(z, 1, s_5))) return 0; + break; + case 3: + if (!(eq_s_b(z, 1, s_6))) return 0; + break; + case 4: + if (!(eq_s_b(z, 1, s_7))) return 0; + break; + case 5: + if (!(eq_s_b(z, 1, s_8))) return 0; + break; + case 6: + if (!(eq_s_b(z, 1, s_9))) return 0; + break; + case 7: + { int m = z->l - z->c; (void) m; /* try, line 111 */ + { int m = z->l - z->c; (void) m; /* and, line 113 */ + { int m = z->l - z->c; (void) m; /* or, line 112 */ + { int ret = r_LONG(z); + if (ret == 0) goto lab2; /* call LONG, line 111 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m; goto lab0; } + } + lab1: + z->c = z->l - m; + if (z->c <= z->lb) { z->c = z->l - m; goto lab0; } + z->c--; /* next, line 113 */ + } + z->bra = z->c; /* ], line 113 */ + lab0: + ; + } + break; + case 8: + if (!(in_grouping_b(z, g_V1, 97, 246))) return 0; + if (!(out_grouping_b(z, g_V1, 97, 246))) return 0; + break; + case 9: + if (!(eq_s_b(z, 1, s_11))) return 0; + break; + } + { int ret; + ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set ending_removed, line 139 */ + return 1; +} + +static int r_other_endings(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 142 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[1]) return 0; + z->c = z->I[1]; /* tomark, line 142 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 142 */ + among_var = find_among_b(z, a_7, 14); /* substring, line 142 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 142 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 146 */ + if (!(eq_s_b(z, 2, s_12))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_i_plural(struct SN_env * z) { + { int m3; /* setlimit, line 154 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 154 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 154 */ + if (!(find_among_b(z, a_8, 2))) { z->lb = m3; return 0; } /* substring, line 154 */ + z->bra = z->c; /* ], line 154 */ + z->lb = m3; + } + { int ret; + ret = slice_del(z); /* delete, line 158 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_t_plural(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 161 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 161 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 162 */ + if (!(eq_s_b(z, 1, s_13))) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 162 */ + { int m_test = z->l - z->c; /* test, line 162 */ + if (!(in_grouping_b(z, g_V1, 97, 246))) { z->lb = m3; return 0; } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + z->lb = m3; + } + { int m3; /* setlimit, line 165 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[1]) return 0; + z->c = z->I[1]; /* tomark, line 165 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 165 */ + among_var = find_among_b(z, a_9, 2); /* substring, line 165 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 165 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 167 */ + if (!(eq_s_b(z, 2, s_14))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 170 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_tidy(struct SN_env * z) { + { int m3; /* setlimit, line 173 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 173 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 174 */ + { int m = z->l - z->c; (void) m; /* and, line 174 */ + { int ret = r_LONG(z); + if (ret == 0) goto lab0; /* call LONG, line 174 */ + if (ret < 0) return ret; + } + z->c = z->l - m; + z->ket = z->c; /* [, line 174 */ + if (z->c <= z->lb) goto lab0; + z->c--; /* next, line 174 */ + z->bra = z->c; /* ], line 174 */ + { int ret; + ret = slice_del(z); /* delete, line 174 */ + if (ret < 0) return ret; + } + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 175 */ + z->ket = z->c; /* [, line 175 */ + if (!(in_grouping_b(z, g_AEI, 97, 228))) goto lab1; + z->bra = z->c; /* ], line 175 */ + if (!(out_grouping_b(z, g_V1, 97, 246))) goto lab1; + { int ret; + ret = slice_del(z); /* delete, line 175 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 176 */ + z->ket = z->c; /* [, line 176 */ + if (!(eq_s_b(z, 1, s_15))) goto lab2; + z->bra = z->c; /* ], line 176 */ + { int m = z->l - z->c; (void) m; /* or, line 176 */ + if (!(eq_s_b(z, 1, s_16))) goto lab4; + goto lab3; + lab4: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_17))) goto lab2; + } + lab3: + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 177 */ + z->ket = z->c; /* [, line 177 */ + if (!(eq_s_b(z, 1, s_18))) goto lab5; + z->bra = z->c; /* ], line 177 */ + if (!(eq_s_b(z, 1, s_19))) goto lab5; + { int ret; + ret = slice_del(z); /* delete, line 177 */ + if (ret < 0) return ret; + } + lab5: + z->c = z->l - m; + } + z->lb = m3; + } + while(1) { /* goto, line 179 */ + int m = z->l - z->c; (void) m; + if (!(out_grouping_b(z, g_V1, 97, 246))) goto lab6; + z->c = z->l - m; + break; + lab6: + z->c = z->l - m; + if (z->c <= z->lb) return 0; + z->c--; /* goto, line 179 */ + } + z->ket = z->c; /* [, line 179 */ + if (z->c <= z->lb) return 0; + z->c--; /* next, line 179 */ + z->bra = z->c; /* ], line 179 */ + z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */ + if (z->S[0] == 0) return -1; /* -> x, line 179 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */ + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int finnish_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 185 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 185 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->B[0] = 0; /* unset ending_removed, line 186 */ + z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + + { int m = z->l - z->c; (void) m; /* do, line 188 */ + { int ret = r_particle_etc(z); + if (ret == 0) goto lab1; /* call particle_etc, line 188 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 189 */ + { int ret = r_possessive(z); + if (ret == 0) goto lab2; /* call possessive, line 189 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 190 */ + { int ret = r_case_ending(z); + if (ret == 0) goto lab3; /* call case_ending, line 190 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 191 */ + { int ret = r_other_endings(z); + if (ret == 0) goto lab4; /* call other_endings, line 191 */ + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* or, line 192 */ + if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */ + { int m = z->l - z->c; (void) m; /* do, line 192 */ + { int ret = r_i_plural(z); + if (ret == 0) goto lab7; /* call i_plural, line 192 */ + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m; + } + goto lab5; + lab6: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 192 */ + { int ret = r_t_plural(z); + if (ret == 0) goto lab8; /* call t_plural, line 192 */ + if (ret < 0) return ret; + } + lab8: + z->c = z->l - m; + } + } +lab5: + { int m = z->l - z->c; (void) m; /* do, line 193 */ + { int ret = r_tidy(z); + if (ret == 0) goto lab9; /* call tidy, line 193 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * finnish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 1); } + +extern void finnish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.h new file mode 100644 index 00000000000..c67b67b944f --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_finnish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * finnish_ISO_8859_1_create_env(void); +extern void finnish_ISO_8859_1_close_env(struct SN_env * z); + +extern int finnish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.c new file mode 100644 index 00000000000..e4eb80d3cf2 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.c @@ -0,0 +1,1276 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int french_ISO_8859_1_stem(struct SN_env * z); +static int r_un_accent(struct SN_env * z); +static int r_un_double(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_i_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * french_ISO_8859_1_create_env(void); +extern void french_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 'I' }; +static symbol s_0_2[1] = { 'U' }; +static symbol s_0_3[1] = { 'Y' }; + +static struct among a_0[4] = +{ +/* 0 */ { 0, 0, -1, 4, 0}, +/* 1 */ { 1, s_0_1, 0, 1, 0}, +/* 2 */ { 1, s_0_2, 0, 2, 0}, +/* 3 */ { 1, s_0_3, 0, 3, 0} +}; + +static symbol s_1_0[3] = { 'i', 'q', 'U' }; +static symbol s_1_1[3] = { 'a', 'b', 'l' }; +static symbol s_1_2[3] = { 'I', 0xE8, 'r' }; +static symbol s_1_3[3] = { 'i', 0xE8, 'r' }; +static symbol s_1_4[3] = { 'e', 'u', 's' }; +static symbol s_1_5[2] = { 'i', 'v' }; + +static struct among a_1[6] = +{ +/* 0 */ { 3, s_1_0, -1, 3, 0}, +/* 1 */ { 3, s_1_1, -1, 3, 0}, +/* 2 */ { 3, s_1_2, -1, 4, 0}, +/* 3 */ { 3, s_1_3, -1, 4, 0}, +/* 4 */ { 3, s_1_4, -1, 2, 0}, +/* 5 */ { 2, s_1_5, -1, 1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'c' }; +static symbol s_2_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_2_2[2] = { 'i', 'v' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, 2, 0}, +/* 1 */ { 4, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 3, 0} +}; + +static symbol s_3_0[4] = { 'i', 'q', 'U', 'e' }; +static symbol s_3_1[6] = { 'a', 't', 'r', 'i', 'c', 'e' }; +static symbol s_3_2[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_3_3[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_3_4[5] = { 'l', 'o', 'g', 'i', 'e' }; +static symbol s_3_5[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_3_6[4] = { 'i', 's', 'm', 'e' }; +static symbol s_3_7[4] = { 'e', 'u', 's', 'e' }; +static symbol s_3_8[4] = { 'i', 's', 't', 'e' }; +static symbol s_3_9[3] = { 'i', 'v', 'e' }; +static symbol s_3_10[2] = { 'i', 'f' }; +static symbol s_3_11[5] = { 'u', 's', 'i', 'o', 'n' }; +static symbol s_3_12[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_13[5] = { 'u', 't', 'i', 'o', 'n' }; +static symbol s_3_14[5] = { 'a', 't', 'e', 'u', 'r' }; +static symbol s_3_15[5] = { 'i', 'q', 'U', 'e', 's' }; +static symbol s_3_16[7] = { 'a', 't', 'r', 'i', 'c', 'e', 's' }; +static symbol s_3_17[5] = { 'a', 'n', 'c', 'e', 's' }; +static symbol s_3_18[5] = { 'e', 'n', 'c', 'e', 's' }; +static symbol s_3_19[6] = { 'l', 'o', 'g', 'i', 'e', 's' }; +static symbol s_3_20[5] = { 'a', 'b', 'l', 'e', 's' }; +static symbol s_3_21[5] = { 'i', 's', 'm', 'e', 's' }; +static symbol s_3_22[5] = { 'e', 'u', 's', 'e', 's' }; +static symbol s_3_23[5] = { 'i', 's', 't', 'e', 's' }; +static symbol s_3_24[4] = { 'i', 'v', 'e', 's' }; +static symbol s_3_25[3] = { 'i', 'f', 's' }; +static symbol s_3_26[6] = { 'u', 's', 'i', 'o', 'n', 's' }; +static symbol s_3_27[6] = { 'a', 't', 'i', 'o', 'n', 's' }; +static symbol s_3_28[6] = { 'u', 't', 'i', 'o', 'n', 's' }; +static symbol s_3_29[6] = { 'a', 't', 'e', 'u', 'r', 's' }; +static symbol s_3_30[5] = { 'm', 'e', 'n', 't', 's' }; +static symbol s_3_31[6] = { 'e', 'm', 'e', 'n', 't', 's' }; +static symbol s_3_32[9] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't', 's' }; +static symbol s_3_33[4] = { 'i', 't', 0xE9, 's' }; +static symbol s_3_34[4] = { 'm', 'e', 'n', 't' }; +static symbol s_3_35[5] = { 'e', 'm', 'e', 'n', 't' }; +static symbol s_3_36[8] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't' }; +static symbol s_3_37[6] = { 'a', 'm', 'm', 'e', 'n', 't' }; +static symbol s_3_38[6] = { 'e', 'm', 'm', 'e', 'n', 't' }; +static symbol s_3_39[3] = { 'a', 'u', 'x' }; +static symbol s_3_40[4] = { 'e', 'a', 'u', 'x' }; +static symbol s_3_41[3] = { 'e', 'u', 'x' }; +static symbol s_3_42[3] = { 'i', 't', 0xE9 }; + +static struct among a_3[43] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 6, s_3_1, -1, 2, 0}, +/* 2 */ { 4, s_3_2, -1, 1, 0}, +/* 3 */ { 4, s_3_3, -1, 5, 0}, +/* 4 */ { 5, s_3_4, -1, 3, 0}, +/* 5 */ { 4, s_3_5, -1, 1, 0}, +/* 6 */ { 4, s_3_6, -1, 1, 0}, +/* 7 */ { 4, s_3_7, -1, 11, 0}, +/* 8 */ { 4, s_3_8, -1, 1, 0}, +/* 9 */ { 3, s_3_9, -1, 8, 0}, +/* 10 */ { 2, s_3_10, -1, 8, 0}, +/* 11 */ { 5, s_3_11, -1, 4, 0}, +/* 12 */ { 5, s_3_12, -1, 2, 0}, +/* 13 */ { 5, s_3_13, -1, 4, 0}, +/* 14 */ { 5, s_3_14, -1, 2, 0}, +/* 15 */ { 5, s_3_15, -1, 1, 0}, +/* 16 */ { 7, s_3_16, -1, 2, 0}, +/* 17 */ { 5, s_3_17, -1, 1, 0}, +/* 18 */ { 5, s_3_18, -1, 5, 0}, +/* 19 */ { 6, s_3_19, -1, 3, 0}, +/* 20 */ { 5, s_3_20, -1, 1, 0}, +/* 21 */ { 5, s_3_21, -1, 1, 0}, +/* 22 */ { 5, s_3_22, -1, 11, 0}, +/* 23 */ { 5, s_3_23, -1, 1, 0}, +/* 24 */ { 4, s_3_24, -1, 8, 0}, +/* 25 */ { 3, s_3_25, -1, 8, 0}, +/* 26 */ { 6, s_3_26, -1, 4, 0}, +/* 27 */ { 6, s_3_27, -1, 2, 0}, +/* 28 */ { 6, s_3_28, -1, 4, 0}, +/* 29 */ { 6, s_3_29, -1, 2, 0}, +/* 30 */ { 5, s_3_30, -1, 15, 0}, +/* 31 */ { 6, s_3_31, 30, 6, 0}, +/* 32 */ { 9, s_3_32, 31, 12, 0}, +/* 33 */ { 4, s_3_33, -1, 7, 0}, +/* 34 */ { 4, s_3_34, -1, 15, 0}, +/* 35 */ { 5, s_3_35, 34, 6, 0}, +/* 36 */ { 8, s_3_36, 35, 12, 0}, +/* 37 */ { 6, s_3_37, 34, 13, 0}, +/* 38 */ { 6, s_3_38, 34, 14, 0}, +/* 39 */ { 3, s_3_39, -1, 10, 0}, +/* 40 */ { 4, s_3_40, 39, 9, 0}, +/* 41 */ { 3, s_3_41, -1, 1, 0}, +/* 42 */ { 3, s_3_42, -1, 7, 0} +}; + +static symbol s_4_0[3] = { 'i', 'r', 'a' }; +static symbol s_4_1[2] = { 'i', 'e' }; +static symbol s_4_2[4] = { 'i', 's', 's', 'e' }; +static symbol s_4_3[7] = { 'i', 's', 's', 'a', 'n', 't', 'e' }; +static symbol s_4_4[1] = { 'i' }; +static symbol s_4_5[4] = { 'i', 'r', 'a', 'i' }; +static symbol s_4_6[2] = { 'i', 'r' }; +static symbol s_4_7[4] = { 'i', 'r', 'a', 's' }; +static symbol s_4_8[3] = { 'i', 'e', 's' }; +static symbol s_4_9[4] = { 0xEE, 'm', 'e', 's' }; +static symbol s_4_10[5] = { 'i', 's', 's', 'e', 's' }; +static symbol s_4_11[8] = { 'i', 's', 's', 'a', 'n', 't', 'e', 's' }; +static symbol s_4_12[4] = { 0xEE, 't', 'e', 's' }; +static symbol s_4_13[2] = { 'i', 's' }; +static symbol s_4_14[5] = { 'i', 'r', 'a', 'i', 's' }; +static symbol s_4_15[6] = { 'i', 's', 's', 'a', 'i', 's' }; +static symbol s_4_16[6] = { 'i', 'r', 'i', 'o', 'n', 's' }; +static symbol s_4_17[7] = { 'i', 's', 's', 'i', 'o', 'n', 's' }; +static symbol s_4_18[5] = { 'i', 'r', 'o', 'n', 's' }; +static symbol s_4_19[6] = { 'i', 's', 's', 'o', 'n', 's' }; +static symbol s_4_20[7] = { 'i', 's', 's', 'a', 'n', 't', 's' }; +static symbol s_4_21[2] = { 'i', 't' }; +static symbol s_4_22[5] = { 'i', 'r', 'a', 'i', 't' }; +static symbol s_4_23[6] = { 'i', 's', 's', 'a', 'i', 't' }; +static symbol s_4_24[6] = { 'i', 's', 's', 'a', 'n', 't' }; +static symbol s_4_25[7] = { 'i', 'r', 'a', 'I', 'e', 'n', 't' }; +static symbol s_4_26[8] = { 'i', 's', 's', 'a', 'I', 'e', 'n', 't' }; +static symbol s_4_27[5] = { 'i', 'r', 'e', 'n', 't' }; +static symbol s_4_28[6] = { 'i', 's', 's', 'e', 'n', 't' }; +static symbol s_4_29[5] = { 'i', 'r', 'o', 'n', 't' }; +static symbol s_4_30[2] = { 0xEE, 't' }; +static symbol s_4_31[5] = { 'i', 'r', 'i', 'e', 'z' }; +static symbol s_4_32[6] = { 'i', 's', 's', 'i', 'e', 'z' }; +static symbol s_4_33[4] = { 'i', 'r', 'e', 'z' }; +static symbol s_4_34[5] = { 'i', 's', 's', 'e', 'z' }; + +static struct among a_4[35] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 1, 0}, +/* 2 */ { 4, s_4_2, -1, 1, 0}, +/* 3 */ { 7, s_4_3, -1, 1, 0}, +/* 4 */ { 1, s_4_4, -1, 1, 0}, +/* 5 */ { 4, s_4_5, 4, 1, 0}, +/* 6 */ { 2, s_4_6, -1, 1, 0}, +/* 7 */ { 4, s_4_7, -1, 1, 0}, +/* 8 */ { 3, s_4_8, -1, 1, 0}, +/* 9 */ { 4, s_4_9, -1, 1, 0}, +/* 10 */ { 5, s_4_10, -1, 1, 0}, +/* 11 */ { 8, s_4_11, -1, 1, 0}, +/* 12 */ { 4, s_4_12, -1, 1, 0}, +/* 13 */ { 2, s_4_13, -1, 1, 0}, +/* 14 */ { 5, s_4_14, 13, 1, 0}, +/* 15 */ { 6, s_4_15, 13, 1, 0}, +/* 16 */ { 6, s_4_16, -1, 1, 0}, +/* 17 */ { 7, s_4_17, -1, 1, 0}, +/* 18 */ { 5, s_4_18, -1, 1, 0}, +/* 19 */ { 6, s_4_19, -1, 1, 0}, +/* 20 */ { 7, s_4_20, -1, 1, 0}, +/* 21 */ { 2, s_4_21, -1, 1, 0}, +/* 22 */ { 5, s_4_22, 21, 1, 0}, +/* 23 */ { 6, s_4_23, 21, 1, 0}, +/* 24 */ { 6, s_4_24, -1, 1, 0}, +/* 25 */ { 7, s_4_25, -1, 1, 0}, +/* 26 */ { 8, s_4_26, -1, 1, 0}, +/* 27 */ { 5, s_4_27, -1, 1, 0}, +/* 28 */ { 6, s_4_28, -1, 1, 0}, +/* 29 */ { 5, s_4_29, -1, 1, 0}, +/* 30 */ { 2, s_4_30, -1, 1, 0}, +/* 31 */ { 5, s_4_31, -1, 1, 0}, +/* 32 */ { 6, s_4_32, -1, 1, 0}, +/* 33 */ { 4, s_4_33, -1, 1, 0}, +/* 34 */ { 5, s_4_34, -1, 1, 0} +}; + +static symbol s_5_0[1] = { 'a' }; +static symbol s_5_1[3] = { 'e', 'r', 'a' }; +static symbol s_5_2[4] = { 'a', 's', 's', 'e' }; +static symbol s_5_3[4] = { 'a', 'n', 't', 'e' }; +static symbol s_5_4[2] = { 0xE9, 'e' }; +static symbol s_5_5[2] = { 'a', 'i' }; +static symbol s_5_6[4] = { 'e', 'r', 'a', 'i' }; +static symbol s_5_7[2] = { 'e', 'r' }; +static symbol s_5_8[2] = { 'a', 's' }; +static symbol s_5_9[4] = { 'e', 'r', 'a', 's' }; +static symbol s_5_10[4] = { 0xE2, 'm', 'e', 's' }; +static symbol s_5_11[5] = { 'a', 's', 's', 'e', 's' }; +static symbol s_5_12[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_5_13[4] = { 0xE2, 't', 'e', 's' }; +static symbol s_5_14[3] = { 0xE9, 'e', 's' }; +static symbol s_5_15[3] = { 'a', 'i', 's' }; +static symbol s_5_16[5] = { 'e', 'r', 'a', 'i', 's' }; +static symbol s_5_17[4] = { 'i', 'o', 'n', 's' }; +static symbol s_5_18[6] = { 'e', 'r', 'i', 'o', 'n', 's' }; +static symbol s_5_19[7] = { 'a', 's', 's', 'i', 'o', 'n', 's' }; +static symbol s_5_20[5] = { 'e', 'r', 'o', 'n', 's' }; +static symbol s_5_21[4] = { 'a', 'n', 't', 's' }; +static symbol s_5_22[2] = { 0xE9, 's' }; +static symbol s_5_23[3] = { 'a', 'i', 't' }; +static symbol s_5_24[5] = { 'e', 'r', 'a', 'i', 't' }; +static symbol s_5_25[3] = { 'a', 'n', 't' }; +static symbol s_5_26[5] = { 'a', 'I', 'e', 'n', 't' }; +static symbol s_5_27[7] = { 'e', 'r', 'a', 'I', 'e', 'n', 't' }; +static symbol s_5_28[5] = { 0xE8, 'r', 'e', 'n', 't' }; +static symbol s_5_29[6] = { 'a', 's', 's', 'e', 'n', 't' }; +static symbol s_5_30[5] = { 'e', 'r', 'o', 'n', 't' }; +static symbol s_5_31[2] = { 0xE2, 't' }; +static symbol s_5_32[2] = { 'e', 'z' }; +static symbol s_5_33[3] = { 'i', 'e', 'z' }; +static symbol s_5_34[5] = { 'e', 'r', 'i', 'e', 'z' }; +static symbol s_5_35[6] = { 'a', 's', 's', 'i', 'e', 'z' }; +static symbol s_5_36[4] = { 'e', 'r', 'e', 'z' }; +static symbol s_5_37[1] = { 0xE9 }; + +static struct among a_5[38] = +{ +/* 0 */ { 1, s_5_0, -1, 3, 0}, +/* 1 */ { 3, s_5_1, 0, 2, 0}, +/* 2 */ { 4, s_5_2, -1, 3, 0}, +/* 3 */ { 4, s_5_3, -1, 3, 0}, +/* 4 */ { 2, s_5_4, -1, 2, 0}, +/* 5 */ { 2, s_5_5, -1, 3, 0}, +/* 6 */ { 4, s_5_6, 5, 2, 0}, +/* 7 */ { 2, s_5_7, -1, 2, 0}, +/* 8 */ { 2, s_5_8, -1, 3, 0}, +/* 9 */ { 4, s_5_9, 8, 2, 0}, +/* 10 */ { 4, s_5_10, -1, 3, 0}, +/* 11 */ { 5, s_5_11, -1, 3, 0}, +/* 12 */ { 5, s_5_12, -1, 3, 0}, +/* 13 */ { 4, s_5_13, -1, 3, 0}, +/* 14 */ { 3, s_5_14, -1, 2, 0}, +/* 15 */ { 3, s_5_15, -1, 3, 0}, +/* 16 */ { 5, s_5_16, 15, 2, 0}, +/* 17 */ { 4, s_5_17, -1, 1, 0}, +/* 18 */ { 6, s_5_18, 17, 2, 0}, +/* 19 */ { 7, s_5_19, 17, 3, 0}, +/* 20 */ { 5, s_5_20, -1, 2, 0}, +/* 21 */ { 4, s_5_21, -1, 3, 0}, +/* 22 */ { 2, s_5_22, -1, 2, 0}, +/* 23 */ { 3, s_5_23, -1, 3, 0}, +/* 24 */ { 5, s_5_24, 23, 2, 0}, +/* 25 */ { 3, s_5_25, -1, 3, 0}, +/* 26 */ { 5, s_5_26, -1, 3, 0}, +/* 27 */ { 7, s_5_27, 26, 2, 0}, +/* 28 */ { 5, s_5_28, -1, 2, 0}, +/* 29 */ { 6, s_5_29, -1, 3, 0}, +/* 30 */ { 5, s_5_30, -1, 2, 0}, +/* 31 */ { 2, s_5_31, -1, 3, 0}, +/* 32 */ { 2, s_5_32, -1, 2, 0}, +/* 33 */ { 3, s_5_33, 32, 2, 0}, +/* 34 */ { 5, s_5_34, 33, 2, 0}, +/* 35 */ { 6, s_5_35, 33, 3, 0}, +/* 36 */ { 4, s_5_36, 32, 2, 0}, +/* 37 */ { 1, s_5_37, -1, 2, 0} +}; + +static symbol s_6_0[1] = { 'e' }; +static symbol s_6_1[4] = { 'I', 0xE8, 'r', 'e' }; +static symbol s_6_2[4] = { 'i', 0xE8, 'r', 'e' }; +static symbol s_6_3[3] = { 'i', 'o', 'n' }; +static symbol s_6_4[3] = { 'I', 'e', 'r' }; +static symbol s_6_5[3] = { 'i', 'e', 'r' }; +static symbol s_6_6[1] = { 0xEB }; + +static struct among a_6[7] = +{ +/* 0 */ { 1, s_6_0, -1, 3, 0}, +/* 1 */ { 4, s_6_1, 0, 2, 0}, +/* 2 */ { 4, s_6_2, 0, 2, 0}, +/* 3 */ { 3, s_6_3, -1, 1, 0}, +/* 4 */ { 3, s_6_4, -1, 2, 0}, +/* 5 */ { 3, s_6_5, -1, 2, 0}, +/* 6 */ { 1, s_6_6, -1, 4, 0} +}; + +static symbol s_7_0[3] = { 'e', 'l', 'l' }; +static symbol s_7_1[4] = { 'e', 'i', 'l', 'l' }; +static symbol s_7_2[3] = { 'e', 'n', 'n' }; +static symbol s_7_3[3] = { 'o', 'n', 'n' }; +static symbol s_7_4[3] = { 'e', 't', 't' }; + +static struct among a_7[5] = +{ +/* 0 */ { 3, s_7_0, -1, -1, 0}, +/* 1 */ { 4, s_7_1, -1, -1, 0}, +/* 2 */ { 3, s_7_2, -1, -1, 0}, +/* 3 */ { 3, s_7_3, -1, -1, 0}, +/* 4 */ { 3, s_7_4, -1, -1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 }; + +static unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static symbol s_0[] = { 'u' }; +static symbol s_1[] = { 'U' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'I' }; +static symbol s_4[] = { 'y' }; +static symbol s_5[] = { 'Y' }; +static symbol s_6[] = { 'y' }; +static symbol s_7[] = { 'Y' }; +static symbol s_8[] = { 'q' }; +static symbol s_9[] = { 'u' }; +static symbol s_10[] = { 'U' }; +static symbol s_11[] = { 'i' }; +static symbol s_12[] = { 'u' }; +static symbol s_13[] = { 'y' }; +static symbol s_14[] = { 'i', 'c' }; +static symbol s_15[] = { 'i', 'q', 'U' }; +static symbol s_16[] = { 'l', 'o', 'g' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'e', 'n', 't' }; +static symbol s_19[] = { 'a', 't' }; +static symbol s_20[] = { 'e', 'u', 'x' }; +static symbol s_21[] = { 'i' }; +static symbol s_22[] = { 'a', 'b', 'l' }; +static symbol s_23[] = { 'i', 'q', 'U' }; +static symbol s_24[] = { 'a', 't' }; +static symbol s_25[] = { 'i', 'c' }; +static symbol s_26[] = { 'i', 'q', 'U' }; +static symbol s_27[] = { 'e', 'a', 'u' }; +static symbol s_28[] = { 'a', 'l' }; +static symbol s_29[] = { 'e', 'u', 'x' }; +static symbol s_30[] = { 'a', 'n', 't' }; +static symbol s_31[] = { 'e', 'n', 't' }; +static symbol s_32[] = { 'e' }; +static symbol s_33[] = { 's' }; +static symbol s_34[] = { 's' }; +static symbol s_35[] = { 't' }; +static symbol s_36[] = { 'i' }; +static symbol s_37[] = { 'g', 'u' }; +static symbol s_38[] = { 0xE9 }; +static symbol s_39[] = { 0xE8 }; +static symbol s_40[] = { 'e' }; +static symbol s_41[] = { 'Y' }; +static symbol s_42[] = { 'i' }; +static symbol s_43[] = { 0xE7 }; +static symbol s_44[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { + while(1) { /* repeat, line 38 */ + int c = z->c; + while(1) { /* goto, line 38 */ + int c = z->c; + { int c = z->c; /* or, line 44 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab3; + z->bra = z->c; /* [, line 40 */ + { int c = z->c; /* or, line 40 */ + if (!(eq_s(z, 1, s_0))) goto lab5; + z->ket = z->c; /* ], line 40 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab5; + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 40 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = c; + if (!(eq_s(z, 1, s_2))) goto lab6; + z->ket = z->c; /* ], line 41 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab6; + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 41 */ + if (ret < 0) return ret; + } + goto lab4; + lab6: + z->c = c; + if (!(eq_s(z, 1, s_4))) goto lab3; + z->ket = z->c; /* ], line 42 */ + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 42 */ + if (ret < 0) return ret; + } + } + lab4: + goto lab2; + lab3: + z->c = c; + z->bra = z->c; /* [, line 45 */ + if (!(eq_s(z, 1, s_6))) goto lab7; + z->ket = z->c; /* ], line 45 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab7; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 45 */ + if (ret < 0) return ret; + } + goto lab2; + lab7: + z->c = c; + if (!(eq_s(z, 1, s_8))) goto lab1; + z->bra = z->c; /* [, line 47 */ + if (!(eq_s(z, 1, s_9))) goto lab1; + z->ket = z->c; /* ], line 47 */ + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 47 */ + if (ret < 0) return ret; + } + } + lab2: + z->c = c; + break; + lab1: + z->c = c; + if (z->c >= z->l) goto lab0; + z->c++; /* goto, line 38 */ + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 56 */ + { int c = z->c; /* or, line 57 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab2; + if (!(in_grouping(z, g_v, 97, 251))) goto lab2; + if (z->c >= z->l) goto lab2; + z->c++; /* next, line 57 */ + goto lab1; + lab2: + z->c = c; + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 57 */ + while(1) { /* gopast, line 57 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab3; + break; + lab3: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 57 */ + } + } + lab1: + z->I[0] = z->c; /* setmark pV, line 58 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 60 */ + while(1) { /* gopast, line 61 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 61 */ + } + while(1) { /* gopast, line 61 */ + if (!(out_grouping(z, g_v, 97, 251))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 61 */ + } + z->I[1] = z->c; /* setmark p1, line 61 */ + while(1) { /* gopast, line 62 */ + if (!(in_grouping(z, g_v, 97, 251))) goto lab7; + break; + lab7: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 62 */ + } + while(1) { /* gopast, line 62 */ + if (!(out_grouping(z, g_v, 97, 251))) goto lab8; + break; + lab8: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 62 */ + } + z->I[2] = z->c; /* setmark p2, line 62 */ + lab4: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 66 */ + int c = z->c; + z->bra = z->c; /* [, line 68 */ + among_var = find_among(z, a_0, 4); /* substring, line 68 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 68 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 70 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 4: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 72 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 83 */ + among_var = find_among_b(z, a_3, 43); /* substring, line 83 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 83 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 87 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 90 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 90 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 91 */ + z->ket = z->c; /* [, line 91 */ + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 91 */ + { int m = z->l - z->c; (void) m; /* or, line 91 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 91 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 91 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_15); /* <-, line 91 */ + if (ret < 0) return ret; + } + } + lab1: + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 95 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_16); /* <-, line 95 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_17); /* <-, line 98 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 101 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 101 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 105 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 105 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 106 */ + z->ket = z->c; /* [, line 107 */ + among_var = find_among_b(z, a_1, 6); /* substring, line 107 */ + if (!(among_var)) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 107 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab3; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 108 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 108 */ + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 108 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 108 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 109 */ + { int ret = r_R2(z); + if (ret == 0) goto lab5; /* call R2, line 109 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 109 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R1, line 109 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 109 */ + if (ret < 0) return ret; + } + } + lab4: + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 111 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call RV, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_21); /* <-, line 113 */ + if (ret < 0) return ret; + } + break; + } + lab3: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 120 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 120 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 121 */ + z->ket = z->c; /* [, line 122 */ + among_var = find_among_b(z, a_2, 3); /* substring, line 122 */ + if (!(among_var)) { z->c = z->l - m; goto lab6; } + z->bra = z->c; /* ], line 122 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab6; } + case 1: + { int m = z->l - z->c; (void) m; /* or, line 123 */ + { int ret = r_R2(z); + if (ret == 0) goto lab8; /* call R2, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + goto lab7; + lab8: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_22); /* <-, line 123 */ + if (ret < 0) return ret; + } + } + lab7: + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 124 */ + { int ret = r_R2(z); + if (ret == 0) goto lab10; /* call R2, line 124 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 124 */ + if (ret < 0) return ret; + } + goto lab9; + lab10: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_23); /* <-, line 124 */ + if (ret < 0) return ret; + } + } + lab9: + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab6; } /* call R2, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + break; + } + lab6: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 132 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 132 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 133 */ + z->ket = z->c; /* [, line 133 */ + if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m; goto lab11; } + z->bra = z->c; /* ], line 133 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab11; } /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 133 */ + if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m; goto lab11; } + z->bra = z->c; /* ], line 133 */ + { int m = z->l - z->c; (void) m; /* or, line 133 */ + { int ret = r_R2(z); + if (ret == 0) goto lab13; /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + goto lab12; + lab13: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_26); /* <-, line 133 */ + if (ret < 0) return ret; + } + } + lab12: + lab11: + ; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 3, s_27); /* <-, line 135 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 136 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_28); /* <-, line 136 */ + if (ret < 0) return ret; + } + break; + case 11: + { int m = z->l - z->c; (void) m; /* or, line 138 */ + { int ret = r_R2(z); + if (ret == 0) goto lab15; /* call R2, line 138 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + goto lab14; + lab15: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 138 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_29); /* <-, line 138 */ + if (ret < 0) return ret; + } + } + lab14: + break; + case 12: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 141 */ + if (ret < 0) return ret; + } + if (!(out_grouping_b(z, g_v, 97, 251))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 141 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 146 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_30); /* <-, line 146 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 146 */ + break; + case 14: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 147 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_31); /* <-, line 147 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 147 */ + break; + case 15: + { int m_test = z->l - z->c; /* test, line 149 */ + if (!(in_grouping_b(z, g_v, 97, 251))) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 149 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 149 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 149 */ + break; + } + return 1; +} + +static int r_i_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 154 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 154 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 155 */ + among_var = find_among_b(z, a_4, 35); /* substring, line 155 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 155 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + if (!(out_grouping_b(z, g_v, 97, 251))) { z->lb = m3; return 0; } + { int ret; + ret = slice_del(z); /* delete, line 161 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 165 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 165 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 166 */ + among_var = find_among_b(z, a_5, 38); /* substring, line 166 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 166 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->lb = m3; return 0; } /* call R2, line 168 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 168 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 181 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 182 */ + z->ket = z->c; /* [, line 182 */ + if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 182 */ + { int ret; + ret = slice_del(z); /* delete, line 182 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* try, line 190 */ + z->ket = z->c; /* [, line 190 */ + if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 190 */ + { int m_test = z->l - z->c; /* test, line 190 */ + if (!(out_grouping_b(z, g_keep_with_s, 97, 232))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 190 */ + if (ret < 0) return ret; + } + lab0: + ; + } + { int m3; /* setlimit, line 191 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 191 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 192 */ + among_var = find_among_b(z, a_6, 7); /* substring, line 192 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 192 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->lb = m3; return 0; } /* call R2, line 193 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* or, line 193 */ + if (!(eq_s_b(z, 1, s_34))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_35))) { z->lb = m3; return 0; } + } + lab1: + { int ret; + ret = slice_del(z); /* delete, line 193 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_36); /* <-, line 195 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 196 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(eq_s_b(z, 2, s_37))) { z->lb = m3; return 0; } + { int ret; + ret = slice_del(z); /* delete, line 197 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_un_double(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 203 */ + if (!(find_among_b(z, a_7, 5))) return 0; /* among, line 203 */ + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 203 */ + if (z->c <= z->lb) return 0; + z->c--; /* next, line 203 */ + z->bra = z->c; /* ], line 203 */ + { int ret; + ret = slice_del(z); /* delete, line 203 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_un_accent(struct SN_env * z) { + { int i = 1; + while(1) { /* atleast, line 207 */ + if (!(out_grouping_b(z, g_v, 97, 251))) goto lab0; + i--; + continue; + lab0: + break; + } + if (i > 0) return 0; + } + z->ket = z->c; /* [, line 208 */ + { int m = z->l - z->c; (void) m; /* or, line 208 */ + if (!(eq_s_b(z, 1, s_38))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_39))) return 0; + } +lab1: + z->bra = z->c; /* ], line 208 */ + { int ret; + ret = slice_from_s(z, 1, s_40); /* <-, line 208 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int french_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 214 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 214 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 215 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 215 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 216 */ + + { int m = z->l - z->c; (void) m; /* do, line 218 */ + { int m = z->l - z->c; (void) m; /* or, line 228 */ + { int m = z->l - z->c; (void) m; /* and, line 224 */ + { int m = z->l - z->c; (void) m; /* or, line 220 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab6; /* call standard_suffix, line 220 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_i_verb_suffix(z); + if (ret == 0) goto lab7; /* call i_verb_suffix, line 221 */ + if (ret < 0) return ret; + } + goto lab5; + lab7: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab4; /* call verb_suffix, line 222 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* try, line 225 */ + z->ket = z->c; /* [, line 225 */ + { int m = z->l - z->c; (void) m; /* or, line 225 */ + if (!(eq_s_b(z, 1, s_41))) goto lab10; + z->bra = z->c; /* ], line 225 */ + { int ret; + ret = slice_from_s(z, 1, s_42); /* <-, line 225 */ + if (ret < 0) return ret; + } + goto lab9; + lab10: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_43))) { z->c = z->l - m; goto lab8; } + z->bra = z->c; /* ], line 226 */ + { int ret; + ret = slice_from_s(z, 1, s_44); /* <-, line 226 */ + if (ret < 0) return ret; + } + } + lab9: + lab8: + ; + } + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab2; /* call residual_suffix, line 229 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 234 */ + { int ret = r_un_double(z); + if (ret == 0) goto lab11; /* call un_double, line 234 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 235 */ + { int ret = r_un_accent(z); + if (ret == 0) goto lab12; /* call un_accent, line 235 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 237 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab13; /* call postlude, line 237 */ + if (ret < 0) return ret; + } + lab13: + z->c = c; + } + return 1; +} + +extern struct SN_env * french_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void french_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.h new file mode 100644 index 00000000000..21244d61621 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_french.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * french_ISO_8859_1_create_env(void); +extern void french_ISO_8859_1_close_env(struct SN_env * z); + +extern int french_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.c new file mode 100644 index 00000000000..633bf03ba49 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.c @@ -0,0 +1,512 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int german_ISO_8859_1_stem(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * german_ISO_8859_1_create_env(void); +extern void german_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 'U' }; +static symbol s_0_2[1] = { 'Y' }; +static symbol s_0_3[1] = { 0xE4 }; +static symbol s_0_4[1] = { 0xF6 }; +static symbol s_0_5[1] = { 0xFC }; + +static struct among a_0[6] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 1, s_0_1, 0, 2, 0}, +/* 2 */ { 1, s_0_2, 0, 1, 0}, +/* 3 */ { 1, s_0_3, 0, 3, 0}, +/* 4 */ { 1, s_0_4, 0, 4, 0}, +/* 5 */ { 1, s_0_5, 0, 5, 0} +}; + +static symbol s_1_0[1] = { 'e' }; +static symbol s_1_1[2] = { 'e', 'm' }; +static symbol s_1_2[2] = { 'e', 'n' }; +static symbol s_1_3[3] = { 'e', 'r', 'n' }; +static symbol s_1_4[2] = { 'e', 'r' }; +static symbol s_1_5[1] = { 's' }; +static symbol s_1_6[2] = { 'e', 's' }; + +static struct among a_1[7] = +{ +/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 3 */ { 3, s_1_3, -1, 1, 0}, +/* 4 */ { 2, s_1_4, -1, 1, 0}, +/* 5 */ { 1, s_1_5, -1, 2, 0}, +/* 6 */ { 2, s_1_6, 5, 1, 0} +}; + +static symbol s_2_0[2] = { 'e', 'n' }; +static symbol s_2_1[2] = { 'e', 'r' }; +static symbol s_2_2[2] = { 's', 't' }; +static symbol s_2_3[3] = { 'e', 's', 't' }; + +static struct among a_2[4] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 2, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 2, 0}, +/* 3 */ { 3, s_2_3, 2, 1, 0} +}; + +static symbol s_3_0[2] = { 'i', 'g' }; +static symbol s_3_1[4] = { 'l', 'i', 'c', 'h' }; + +static struct among a_3[2] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0} +}; + +static symbol s_4_0[3] = { 'e', 'n', 'd' }; +static symbol s_4_1[2] = { 'i', 'g' }; +static symbol s_4_2[3] = { 'u', 'n', 'g' }; +static symbol s_4_3[4] = { 'l', 'i', 'c', 'h' }; +static symbol s_4_4[4] = { 'i', 's', 'c', 'h' }; +static symbol s_4_5[2] = { 'i', 'k' }; +static symbol s_4_6[4] = { 'h', 'e', 'i', 't' }; +static symbol s_4_7[4] = { 'k', 'e', 'i', 't' }; + +static struct among a_4[8] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 2, 0}, +/* 2 */ { 3, s_4_2, -1, 1, 0}, +/* 3 */ { 4, s_4_3, -1, 3, 0}, +/* 4 */ { 4, s_4_4, -1, 2, 0}, +/* 5 */ { 2, s_4_5, -1, 2, 0}, +/* 6 */ { 4, s_4_6, -1, 3, 0}, +/* 7 */ { 4, s_4_7, -1, 4, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 }; + +static unsigned char g_s_ending[] = { 117, 30, 5 }; + +static unsigned char g_st_ending[] = { 117, 30, 4 }; + +static symbol s_0[] = { 0xDF }; +static symbol s_1[] = { 's', 's' }; +static symbol s_2[] = { 'u' }; +static symbol s_3[] = { 'U' }; +static symbol s_4[] = { 'y' }; +static symbol s_5[] = { 'Y' }; +static symbol s_6[] = { 'y' }; +static symbol s_7[] = { 'u' }; +static symbol s_8[] = { 'a' }; +static symbol s_9[] = { 'o' }; +static symbol s_10[] = { 'u' }; +static symbol s_11[] = { 'i', 'g' }; +static symbol s_12[] = { 'e' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'e', 'r' }; +static symbol s_15[] = { 'e', 'n' }; + +static int r_prelude(struct SN_env * z) { + { int c_test = z->c; /* test, line 30 */ + while(1) { /* repeat, line 30 */ + int c = z->c; + { int c = z->c; /* or, line 33 */ + z->bra = z->c; /* [, line 32 */ + if (!(eq_s(z, 1, s_0))) goto lab2; + z->ket = z->c; /* ], line 32 */ + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 32 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = c; + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 33 */ + } + lab1: + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + while(1) { /* repeat, line 36 */ + int c = z->c; + while(1) { /* goto, line 36 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 252))) goto lab4; + z->bra = z->c; /* [, line 37 */ + { int c = z->c; /* or, line 37 */ + if (!(eq_s(z, 1, s_2))) goto lab6; + z->ket = z->c; /* ], line 37 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab6; + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 37 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = c; + if (!(eq_s(z, 1, s_4))) goto lab4; + z->ket = z->c; /* ], line 38 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab4; + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 38 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = c; + break; + lab4: + z->c = c; + if (z->c >= z->l) goto lab3; + z->c++; /* goto, line 36 */ + } + continue; + lab3: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c_test = z->c; /* test, line 47 */ + { int c = z->c + 3; + if (0 > c || c > z->l) return 0; + z->c = c; /* hop, line 47 */ + } + z->I[2] = z->c; /* setmark x, line 47 */ + z->c = c_test; + } + while(1) { /* gopast, line 49 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab0; + break; + lab0: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 49 */ + } + while(1) { /* gopast, line 49 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 49 */ + } + z->I[0] = z->c; /* setmark p1, line 49 */ + /* try, line 50 */ + if (!(z->I[0] < z->I[2])) goto lab2; + z->I[0] = z->I[2]; +lab2: + while(1) { /* gopast, line 51 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab3; + break; + lab3: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 51 */ + } + while(1) { /* gopast, line 51 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab4; + break; + lab4: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 51 */ + } + z->I[1] = z->c; /* setmark p2, line 51 */ + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 55 */ + int c = z->c; + z->bra = z->c; /* [, line 57 */ + among_var = find_among(z, a_0, 6); /* substring, line 57 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 57 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_6); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_8); /* <-, line 60 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_9); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 62 */ + if (ret < 0) return ret; + } + break; + case 6: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 63 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 74 */ + z->ket = z->c; /* [, line 75 */ + among_var = find_among_b(z, a_1, 7); /* substring, line 75 */ + if (!(among_var)) goto lab0; + z->bra = z->c; /* ], line 75 */ + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 75 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 77 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b(z, g_s_ending, 98, 116))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 80 */ + if (ret < 0) return ret; + } + break; + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 84 */ + z->ket = z->c; /* [, line 85 */ + among_var = find_among_b(z, a_2, 4); /* substring, line 85 */ + if (!(among_var)) goto lab1; + z->bra = z->c; /* ], line 85 */ + { int ret = r_R1(z); + if (ret == 0) goto lab1; /* call R1, line 85 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab1; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b(z, g_st_ending, 98, 116))) goto lab1; + { int c = z->c - 3; + if (z->lb > c || c > z->l) goto lab1; + z->c = c; /* hop, line 90 */ + } + { int ret; + ret = slice_del(z); /* delete, line 90 */ + if (ret < 0) return ret; + } + break; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 94 */ + z->ket = z->c; /* [, line 95 */ + among_var = find_among_b(z, a_4, 8); /* substring, line 95 */ + if (!(among_var)) goto lab2; + z->bra = z->c; /* ], line 95 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 95 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab2; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 97 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 98 */ + z->ket = z->c; /* [, line 98 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 98 */ + { int m = z->l - z->c; (void) m; /* not, line 98 */ + if (!(eq_s_b(z, 1, s_12))) goto lab4; + { z->c = z->l - m; goto lab3; } + lab4: + z->c = z->l - m; + } + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 98 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* not, line 101 */ + if (!(eq_s_b(z, 1, s_13))) goto lab5; + goto lab2; + lab5: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 101 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 104 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 105 */ + z->ket = z->c; /* [, line 106 */ + { int m = z->l - z->c; (void) m; /* or, line 106 */ + if (!(eq_s_b(z, 2, s_14))) goto lab8; + goto lab7; + lab8: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m; goto lab6; } + } + lab7: + z->bra = z->c; /* ], line 106 */ + { int ret = r_R1(z); + if (ret == 0) { z->c = z->l - m; goto lab6; } /* call R1, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 106 */ + if (ret < 0) return ret; + } + lab6: + ; + } + break; + case 4: + { int ret; + ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_3, 2); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m; goto lab9; } + z->bra = z->c; /* ], line 112 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab9; } /* call R2, line 112 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab9; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 114 */ + if (ret < 0) return ret; + } + break; + } + lab9: + ; + } + break; + } + lab2: + z->c = z->l - m; + } + return 1; +} + +extern int german_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 125 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 125 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 126 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 126 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 127 */ + + { int m = z->l - z->c; (void) m; /* do, line 128 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab2; /* call standard_suffix, line 128 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 129 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab3; /* call postlude, line 129 */ + if (ret < 0) return ret; + } + lab3: + z->c = c; + } + return 1; +} + +extern struct SN_env * german_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void german_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.h new file mode 100644 index 00000000000..85253892278 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_german.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * german_ISO_8859_1_create_env(void); +extern void german_ISO_8859_1_close_env(struct SN_env * z); + +extern int german_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.c new file mode 100644 index 00000000000..9fe97766d14 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.c @@ -0,0 +1,1091 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int italian_ISO_8859_1_stem(struct SN_env * z); +static int r_vowel_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_attached_pronoun(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * italian_ISO_8859_1_create_env(void); +extern void italian_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[2] = { 'q', 'u' }; +static symbol s_0_2[1] = { 0xE1 }; +static symbol s_0_3[1] = { 0xE9 }; +static symbol s_0_4[1] = { 0xED }; +static symbol s_0_5[1] = { 0xF3 }; +static symbol s_0_6[1] = { 0xFA }; + +static struct among a_0[7] = +{ +/* 0 */ { 0, 0, -1, 7, 0}, +/* 1 */ { 2, s_0_1, 0, 6, 0}, +/* 2 */ { 1, s_0_2, 0, 1, 0}, +/* 3 */ { 1, s_0_3, 0, 2, 0}, +/* 4 */ { 1, s_0_4, 0, 3, 0}, +/* 5 */ { 1, s_0_5, 0, 4, 0}, +/* 6 */ { 1, s_0_6, 0, 5, 0} +}; + +static symbol s_1_1[1] = { 'I' }; +static symbol s_1_2[1] = { 'U' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 1, s_1_1, 0, 1, 0}, +/* 2 */ { 1, s_1_2, 0, 2, 0} +}; + +static symbol s_2_0[2] = { 'l', 'a' }; +static symbol s_2_1[4] = { 'c', 'e', 'l', 'a' }; +static symbol s_2_2[6] = { 'g', 'l', 'i', 'e', 'l', 'a' }; +static symbol s_2_3[4] = { 'm', 'e', 'l', 'a' }; +static symbol s_2_4[4] = { 't', 'e', 'l', 'a' }; +static symbol s_2_5[4] = { 'v', 'e', 'l', 'a' }; +static symbol s_2_6[2] = { 'l', 'e' }; +static symbol s_2_7[4] = { 'c', 'e', 'l', 'e' }; +static symbol s_2_8[6] = { 'g', 'l', 'i', 'e', 'l', 'e' }; +static symbol s_2_9[4] = { 'm', 'e', 'l', 'e' }; +static symbol s_2_10[4] = { 't', 'e', 'l', 'e' }; +static symbol s_2_11[4] = { 'v', 'e', 'l', 'e' }; +static symbol s_2_12[2] = { 'n', 'e' }; +static symbol s_2_13[4] = { 'c', 'e', 'n', 'e' }; +static symbol s_2_14[6] = { 'g', 'l', 'i', 'e', 'n', 'e' }; +static symbol s_2_15[4] = { 'm', 'e', 'n', 'e' }; +static symbol s_2_16[4] = { 's', 'e', 'n', 'e' }; +static symbol s_2_17[4] = { 't', 'e', 'n', 'e' }; +static symbol s_2_18[4] = { 'v', 'e', 'n', 'e' }; +static symbol s_2_19[2] = { 'c', 'i' }; +static symbol s_2_20[2] = { 'l', 'i' }; +static symbol s_2_21[4] = { 'c', 'e', 'l', 'i' }; +static symbol s_2_22[6] = { 'g', 'l', 'i', 'e', 'l', 'i' }; +static symbol s_2_23[4] = { 'm', 'e', 'l', 'i' }; +static symbol s_2_24[4] = { 't', 'e', 'l', 'i' }; +static symbol s_2_25[4] = { 'v', 'e', 'l', 'i' }; +static symbol s_2_26[3] = { 'g', 'l', 'i' }; +static symbol s_2_27[2] = { 'm', 'i' }; +static symbol s_2_28[2] = { 's', 'i' }; +static symbol s_2_29[2] = { 't', 'i' }; +static symbol s_2_30[2] = { 'v', 'i' }; +static symbol s_2_31[2] = { 'l', 'o' }; +static symbol s_2_32[4] = { 'c', 'e', 'l', 'o' }; +static symbol s_2_33[6] = { 'g', 'l', 'i', 'e', 'l', 'o' }; +static symbol s_2_34[4] = { 'm', 'e', 'l', 'o' }; +static symbol s_2_35[4] = { 't', 'e', 'l', 'o' }; +static symbol s_2_36[4] = { 'v', 'e', 'l', 'o' }; + +static struct among a_2[37] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 4, s_2_1, 0, -1, 0}, +/* 2 */ { 6, s_2_2, 0, -1, 0}, +/* 3 */ { 4, s_2_3, 0, -1, 0}, +/* 4 */ { 4, s_2_4, 0, -1, 0}, +/* 5 */ { 4, s_2_5, 0, -1, 0}, +/* 6 */ { 2, s_2_6, -1, -1, 0}, +/* 7 */ { 4, s_2_7, 6, -1, 0}, +/* 8 */ { 6, s_2_8, 6, -1, 0}, +/* 9 */ { 4, s_2_9, 6, -1, 0}, +/* 10 */ { 4, s_2_10, 6, -1, 0}, +/* 11 */ { 4, s_2_11, 6, -1, 0}, +/* 12 */ { 2, s_2_12, -1, -1, 0}, +/* 13 */ { 4, s_2_13, 12, -1, 0}, +/* 14 */ { 6, s_2_14, 12, -1, 0}, +/* 15 */ { 4, s_2_15, 12, -1, 0}, +/* 16 */ { 4, s_2_16, 12, -1, 0}, +/* 17 */ { 4, s_2_17, 12, -1, 0}, +/* 18 */ { 4, s_2_18, 12, -1, 0}, +/* 19 */ { 2, s_2_19, -1, -1, 0}, +/* 20 */ { 2, s_2_20, -1, -1, 0}, +/* 21 */ { 4, s_2_21, 20, -1, 0}, +/* 22 */ { 6, s_2_22, 20, -1, 0}, +/* 23 */ { 4, s_2_23, 20, -1, 0}, +/* 24 */ { 4, s_2_24, 20, -1, 0}, +/* 25 */ { 4, s_2_25, 20, -1, 0}, +/* 26 */ { 3, s_2_26, 20, -1, 0}, +/* 27 */ { 2, s_2_27, -1, -1, 0}, +/* 28 */ { 2, s_2_28, -1, -1, 0}, +/* 29 */ { 2, s_2_29, -1, -1, 0}, +/* 30 */ { 2, s_2_30, -1, -1, 0}, +/* 31 */ { 2, s_2_31, -1, -1, 0}, +/* 32 */ { 4, s_2_32, 31, -1, 0}, +/* 33 */ { 6, s_2_33, 31, -1, 0}, +/* 34 */ { 4, s_2_34, 31, -1, 0}, +/* 35 */ { 4, s_2_35, 31, -1, 0}, +/* 36 */ { 4, s_2_36, 31, -1, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_3_1[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_3_2[2] = { 'a', 'r' }; +static symbol s_3_3[2] = { 'e', 'r' }; +static symbol s_3_4[2] = { 'i', 'r' }; + +static struct among a_3[5] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0}, +/* 2 */ { 2, s_3_2, -1, 2, 0}, +/* 3 */ { 2, s_3_3, -1, 2, 0}, +/* 4 */ { 2, s_3_4, -1, 2, 0} +}; + +static symbol s_4_0[2] = { 'i', 'c' }; +static symbol s_4_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_4_2[2] = { 'o', 's' }; +static symbol s_4_3[2] = { 'i', 'v' }; + +static struct among a_4[4] = +{ +/* 0 */ { 2, s_4_0, -1, -1, 0}, +/* 1 */ { 4, s_4_1, -1, -1, 0}, +/* 2 */ { 2, s_4_2, -1, -1, 0}, +/* 3 */ { 2, s_4_3, -1, 1, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_5_2[2] = { 'i', 'v' }; + +static struct among a_5[3] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 2, s_5_2, -1, 1, 0} +}; + +static symbol s_6_0[3] = { 'i', 'c', 'a' }; +static symbol s_6_1[5] = { 'l', 'o', 'g', 'i', 'a' }; +static symbol s_6_2[3] = { 'o', 's', 'a' }; +static symbol s_6_3[4] = { 'i', 's', 't', 'a' }; +static symbol s_6_4[3] = { 'i', 'v', 'a' }; +static symbol s_6_5[4] = { 'a', 'n', 'z', 'a' }; +static symbol s_6_6[4] = { 'e', 'n', 'z', 'a' }; +static symbol s_6_7[3] = { 'i', 'c', 'e' }; +static symbol s_6_8[6] = { 'a', 't', 'r', 'i', 'c', 'e' }; +static symbol s_6_9[4] = { 'i', 'c', 'h', 'e' }; +static symbol s_6_10[5] = { 'l', 'o', 'g', 'i', 'e' }; +static symbol s_6_11[5] = { 'a', 'b', 'i', 'l', 'e' }; +static symbol s_6_12[5] = { 'i', 'b', 'i', 'l', 'e' }; +static symbol s_6_13[6] = { 'u', 's', 'i', 'o', 'n', 'e' }; +static symbol s_6_14[6] = { 'a', 'z', 'i', 'o', 'n', 'e' }; +static symbol s_6_15[6] = { 'u', 'z', 'i', 'o', 'n', 'e' }; +static symbol s_6_16[5] = { 'a', 't', 'o', 'r', 'e' }; +static symbol s_6_17[3] = { 'o', 's', 'e' }; +static symbol s_6_18[4] = { 'a', 'n', 't', 'e' }; +static symbol s_6_19[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_20[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_21[4] = { 'i', 's', 't', 'e' }; +static symbol s_6_22[3] = { 'i', 'v', 'e' }; +static symbol s_6_23[4] = { 'a', 'n', 'z', 'e' }; +static symbol s_6_24[4] = { 'e', 'n', 'z', 'e' }; +static symbol s_6_25[3] = { 'i', 'c', 'i' }; +static symbol s_6_26[6] = { 'a', 't', 'r', 'i', 'c', 'i' }; +static symbol s_6_27[4] = { 'i', 'c', 'h', 'i' }; +static symbol s_6_28[5] = { 'a', 'b', 'i', 'l', 'i' }; +static symbol s_6_29[5] = { 'i', 'b', 'i', 'l', 'i' }; +static symbol s_6_30[4] = { 'i', 's', 'm', 'i' }; +static symbol s_6_31[6] = { 'u', 's', 'i', 'o', 'n', 'i' }; +static symbol s_6_32[6] = { 'a', 'z', 'i', 'o', 'n', 'i' }; +static symbol s_6_33[6] = { 'u', 'z', 'i', 'o', 'n', 'i' }; +static symbol s_6_34[5] = { 'a', 't', 'o', 'r', 'i' }; +static symbol s_6_35[3] = { 'o', 's', 'i' }; +static symbol s_6_36[4] = { 'a', 'n', 't', 'i' }; +static symbol s_6_37[6] = { 'a', 'm', 'e', 'n', 't', 'i' }; +static symbol s_6_38[6] = { 'i', 'm', 'e', 'n', 't', 'i' }; +static symbol s_6_39[4] = { 'i', 's', 't', 'i' }; +static symbol s_6_40[3] = { 'i', 'v', 'i' }; +static symbol s_6_41[3] = { 'i', 'c', 'o' }; +static symbol s_6_42[4] = { 'i', 's', 'm', 'o' }; +static symbol s_6_43[3] = { 'o', 's', 'o' }; +static symbol s_6_44[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static symbol s_6_45[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static symbol s_6_46[3] = { 'i', 'v', 'o' }; +static symbol s_6_47[3] = { 'i', 't', 0xE0 }; +static symbol s_6_48[4] = { 'i', 's', 't', 0xE0 }; +static symbol s_6_49[4] = { 'i', 's', 't', 0xE8 }; +static symbol s_6_50[4] = { 'i', 's', 't', 0xEC }; + +static struct among a_6[51] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 5, s_6_1, -1, 3, 0}, +/* 2 */ { 3, s_6_2, -1, 1, 0}, +/* 3 */ { 4, s_6_3, -1, 1, 0}, +/* 4 */ { 3, s_6_4, -1, 9, 0}, +/* 5 */ { 4, s_6_5, -1, 1, 0}, +/* 6 */ { 4, s_6_6, -1, 5, 0}, +/* 7 */ { 3, s_6_7, -1, 1, 0}, +/* 8 */ { 6, s_6_8, 7, 1, 0}, +/* 9 */ { 4, s_6_9, -1, 1, 0}, +/* 10 */ { 5, s_6_10, -1, 3, 0}, +/* 11 */ { 5, s_6_11, -1, 1, 0}, +/* 12 */ { 5, s_6_12, -1, 1, 0}, +/* 13 */ { 6, s_6_13, -1, 4, 0}, +/* 14 */ { 6, s_6_14, -1, 2, 0}, +/* 15 */ { 6, s_6_15, -1, 4, 0}, +/* 16 */ { 5, s_6_16, -1, 2, 0}, +/* 17 */ { 3, s_6_17, -1, 1, 0}, +/* 18 */ { 4, s_6_18, -1, 1, 0}, +/* 19 */ { 5, s_6_19, -1, 1, 0}, +/* 20 */ { 6, s_6_20, 19, 7, 0}, +/* 21 */ { 4, s_6_21, -1, 1, 0}, +/* 22 */ { 3, s_6_22, -1, 9, 0}, +/* 23 */ { 4, s_6_23, -1, 1, 0}, +/* 24 */ { 4, s_6_24, -1, 5, 0}, +/* 25 */ { 3, s_6_25, -1, 1, 0}, +/* 26 */ { 6, s_6_26, 25, 1, 0}, +/* 27 */ { 4, s_6_27, -1, 1, 0}, +/* 28 */ { 5, s_6_28, -1, 1, 0}, +/* 29 */ { 5, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, -1, 1, 0}, +/* 31 */ { 6, s_6_31, -1, 4, 0}, +/* 32 */ { 6, s_6_32, -1, 2, 0}, +/* 33 */ { 6, s_6_33, -1, 4, 0}, +/* 34 */ { 5, s_6_34, -1, 2, 0}, +/* 35 */ { 3, s_6_35, -1, 1, 0}, +/* 36 */ { 4, s_6_36, -1, 1, 0}, +/* 37 */ { 6, s_6_37, -1, 6, 0}, +/* 38 */ { 6, s_6_38, -1, 6, 0}, +/* 39 */ { 4, s_6_39, -1, 1, 0}, +/* 40 */ { 3, s_6_40, -1, 9, 0}, +/* 41 */ { 3, s_6_41, -1, 1, 0}, +/* 42 */ { 4, s_6_42, -1, 1, 0}, +/* 43 */ { 3, s_6_43, -1, 1, 0}, +/* 44 */ { 6, s_6_44, -1, 6, 0}, +/* 45 */ { 6, s_6_45, -1, 6, 0}, +/* 46 */ { 3, s_6_46, -1, 9, 0}, +/* 47 */ { 3, s_6_47, -1, 8, 0}, +/* 48 */ { 4, s_6_48, -1, 1, 0}, +/* 49 */ { 4, s_6_49, -1, 1, 0}, +/* 50 */ { 4, s_6_50, -1, 1, 0} +}; + +static symbol s_7_0[4] = { 'i', 's', 'c', 'a' }; +static symbol s_7_1[4] = { 'e', 'n', 'd', 'a' }; +static symbol s_7_2[3] = { 'a', 't', 'a' }; +static symbol s_7_3[3] = { 'i', 't', 'a' }; +static symbol s_7_4[3] = { 'u', 't', 'a' }; +static symbol s_7_5[3] = { 'a', 'v', 'a' }; +static symbol s_7_6[3] = { 'e', 'v', 'a' }; +static symbol s_7_7[3] = { 'i', 'v', 'a' }; +static symbol s_7_8[6] = { 'e', 'r', 'e', 'b', 'b', 'e' }; +static symbol s_7_9[6] = { 'i', 'r', 'e', 'b', 'b', 'e' }; +static symbol s_7_10[4] = { 'i', 's', 'c', 'e' }; +static symbol s_7_11[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_7_12[3] = { 'a', 'r', 'e' }; +static symbol s_7_13[3] = { 'e', 'r', 'e' }; +static symbol s_7_14[3] = { 'i', 'r', 'e' }; +static symbol s_7_15[4] = { 'a', 's', 's', 'e' }; +static symbol s_7_16[3] = { 'a', 't', 'e' }; +static symbol s_7_17[5] = { 'a', 'v', 'a', 't', 'e' }; +static symbol s_7_18[5] = { 'e', 'v', 'a', 't', 'e' }; +static symbol s_7_19[5] = { 'i', 'v', 'a', 't', 'e' }; +static symbol s_7_20[3] = { 'e', 't', 'e' }; +static symbol s_7_21[5] = { 'e', 'r', 'e', 't', 'e' }; +static symbol s_7_22[5] = { 'i', 'r', 'e', 't', 'e' }; +static symbol s_7_23[3] = { 'i', 't', 'e' }; +static symbol s_7_24[6] = { 'e', 'r', 'e', 's', 't', 'e' }; +static symbol s_7_25[6] = { 'i', 'r', 'e', 's', 't', 'e' }; +static symbol s_7_26[3] = { 'u', 't', 'e' }; +static symbol s_7_27[4] = { 'e', 'r', 'a', 'i' }; +static symbol s_7_28[4] = { 'i', 'r', 'a', 'i' }; +static symbol s_7_29[4] = { 'i', 's', 'c', 'i' }; +static symbol s_7_30[4] = { 'e', 'n', 'd', 'i' }; +static symbol s_7_31[4] = { 'e', 'r', 'e', 'i' }; +static symbol s_7_32[4] = { 'i', 'r', 'e', 'i' }; +static symbol s_7_33[4] = { 'a', 's', 's', 'i' }; +static symbol s_7_34[3] = { 'a', 't', 'i' }; +static symbol s_7_35[3] = { 'i', 't', 'i' }; +static symbol s_7_36[6] = { 'e', 'r', 'e', 's', 't', 'i' }; +static symbol s_7_37[6] = { 'i', 'r', 'e', 's', 't', 'i' }; +static symbol s_7_38[3] = { 'u', 't', 'i' }; +static symbol s_7_39[3] = { 'a', 'v', 'i' }; +static symbol s_7_40[3] = { 'e', 'v', 'i' }; +static symbol s_7_41[3] = { 'i', 'v', 'i' }; +static symbol s_7_42[4] = { 'i', 's', 'c', 'o' }; +static symbol s_7_43[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_7_44[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_7_45[4] = { 'Y', 'a', 'm', 'o' }; +static symbol s_7_46[4] = { 'i', 'a', 'm', 'o' }; +static symbol s_7_47[5] = { 'a', 'v', 'a', 'm', 'o' }; +static symbol s_7_48[5] = { 'e', 'v', 'a', 'm', 'o' }; +static symbol s_7_49[5] = { 'i', 'v', 'a', 'm', 'o' }; +static symbol s_7_50[5] = { 'e', 'r', 'e', 'm', 'o' }; +static symbol s_7_51[5] = { 'i', 'r', 'e', 'm', 'o' }; +static symbol s_7_52[6] = { 'a', 's', 's', 'i', 'm', 'o' }; +static symbol s_7_53[4] = { 'a', 'm', 'm', 'o' }; +static symbol s_7_54[4] = { 'e', 'm', 'm', 'o' }; +static symbol s_7_55[6] = { 'e', 'r', 'e', 'm', 'm', 'o' }; +static symbol s_7_56[6] = { 'i', 'r', 'e', 'm', 'm', 'o' }; +static symbol s_7_57[4] = { 'i', 'm', 'm', 'o' }; +static symbol s_7_58[3] = { 'a', 'n', 'o' }; +static symbol s_7_59[6] = { 'i', 's', 'c', 'a', 'n', 'o' }; +static symbol s_7_60[5] = { 'a', 'v', 'a', 'n', 'o' }; +static symbol s_7_61[5] = { 'e', 'v', 'a', 'n', 'o' }; +static symbol s_7_62[5] = { 'i', 'v', 'a', 'n', 'o' }; +static symbol s_7_63[6] = { 'e', 'r', 'a', 'n', 'n', 'o' }; +static symbol s_7_64[6] = { 'i', 'r', 'a', 'n', 'n', 'o' }; +static symbol s_7_65[3] = { 'o', 'n', 'o' }; +static symbol s_7_66[6] = { 'i', 's', 'c', 'o', 'n', 'o' }; +static symbol s_7_67[5] = { 'a', 'r', 'o', 'n', 'o' }; +static symbol s_7_68[5] = { 'e', 'r', 'o', 'n', 'o' }; +static symbol s_7_69[5] = { 'i', 'r', 'o', 'n', 'o' }; +static symbol s_7_70[8] = { 'e', 'r', 'e', 'b', 'b', 'e', 'r', 'o' }; +static symbol s_7_71[8] = { 'i', 'r', 'e', 'b', 'b', 'e', 'r', 'o' }; +static symbol s_7_72[6] = { 'a', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_73[6] = { 'e', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_74[6] = { 'i', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_75[3] = { 'a', 't', 'o' }; +static symbol s_7_76[3] = { 'i', 't', 'o' }; +static symbol s_7_77[3] = { 'u', 't', 'o' }; +static symbol s_7_78[3] = { 'a', 'v', 'o' }; +static symbol s_7_79[3] = { 'e', 'v', 'o' }; +static symbol s_7_80[3] = { 'i', 'v', 'o' }; +static symbol s_7_81[2] = { 'a', 'r' }; +static symbol s_7_82[2] = { 'i', 'r' }; +static symbol s_7_83[3] = { 'e', 'r', 0xE0 }; +static symbol s_7_84[3] = { 'i', 'r', 0xE0 }; +static symbol s_7_85[3] = { 'e', 'r', 0xF2 }; +static symbol s_7_86[3] = { 'i', 'r', 0xF2 }; + +static struct among a_7[87] = +{ +/* 0 */ { 4, s_7_0, -1, 1, 0}, +/* 1 */ { 4, s_7_1, -1, 1, 0}, +/* 2 */ { 3, s_7_2, -1, 1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 3, s_7_4, -1, 1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 3, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 6, s_7_8, -1, 1, 0}, +/* 9 */ { 6, s_7_9, -1, 1, 0}, +/* 10 */ { 4, s_7_10, -1, 1, 0}, +/* 11 */ { 4, s_7_11, -1, 1, 0}, +/* 12 */ { 3, s_7_12, -1, 1, 0}, +/* 13 */ { 3, s_7_13, -1, 1, 0}, +/* 14 */ { 3, s_7_14, -1, 1, 0}, +/* 15 */ { 4, s_7_15, -1, 1, 0}, +/* 16 */ { 3, s_7_16, -1, 1, 0}, +/* 17 */ { 5, s_7_17, 16, 1, 0}, +/* 18 */ { 5, s_7_18, 16, 1, 0}, +/* 19 */ { 5, s_7_19, 16, 1, 0}, +/* 20 */ { 3, s_7_20, -1, 1, 0}, +/* 21 */ { 5, s_7_21, 20, 1, 0}, +/* 22 */ { 5, s_7_22, 20, 1, 0}, +/* 23 */ { 3, s_7_23, -1, 1, 0}, +/* 24 */ { 6, s_7_24, -1, 1, 0}, +/* 25 */ { 6, s_7_25, -1, 1, 0}, +/* 26 */ { 3, s_7_26, -1, 1, 0}, +/* 27 */ { 4, s_7_27, -1, 1, 0}, +/* 28 */ { 4, s_7_28, -1, 1, 0}, +/* 29 */ { 4, s_7_29, -1, 1, 0}, +/* 30 */ { 4, s_7_30, -1, 1, 0}, +/* 31 */ { 4, s_7_31, -1, 1, 0}, +/* 32 */ { 4, s_7_32, -1, 1, 0}, +/* 33 */ { 4, s_7_33, -1, 1, 0}, +/* 34 */ { 3, s_7_34, -1, 1, 0}, +/* 35 */ { 3, s_7_35, -1, 1, 0}, +/* 36 */ { 6, s_7_36, -1, 1, 0}, +/* 37 */ { 6, s_7_37, -1, 1, 0}, +/* 38 */ { 3, s_7_38, -1, 1, 0}, +/* 39 */ { 3, s_7_39, -1, 1, 0}, +/* 40 */ { 3, s_7_40, -1, 1, 0}, +/* 41 */ { 3, s_7_41, -1, 1, 0}, +/* 42 */ { 4, s_7_42, -1, 1, 0}, +/* 43 */ { 4, s_7_43, -1, 1, 0}, +/* 44 */ { 4, s_7_44, -1, 1, 0}, +/* 45 */ { 4, s_7_45, -1, 1, 0}, +/* 46 */ { 4, s_7_46, -1, 1, 0}, +/* 47 */ { 5, s_7_47, -1, 1, 0}, +/* 48 */ { 5, s_7_48, -1, 1, 0}, +/* 49 */ { 5, s_7_49, -1, 1, 0}, +/* 50 */ { 5, s_7_50, -1, 1, 0}, +/* 51 */ { 5, s_7_51, -1, 1, 0}, +/* 52 */ { 6, s_7_52, -1, 1, 0}, +/* 53 */ { 4, s_7_53, -1, 1, 0}, +/* 54 */ { 4, s_7_54, -1, 1, 0}, +/* 55 */ { 6, s_7_55, 54, 1, 0}, +/* 56 */ { 6, s_7_56, 54, 1, 0}, +/* 57 */ { 4, s_7_57, -1, 1, 0}, +/* 58 */ { 3, s_7_58, -1, 1, 0}, +/* 59 */ { 6, s_7_59, 58, 1, 0}, +/* 60 */ { 5, s_7_60, 58, 1, 0}, +/* 61 */ { 5, s_7_61, 58, 1, 0}, +/* 62 */ { 5, s_7_62, 58, 1, 0}, +/* 63 */ { 6, s_7_63, -1, 1, 0}, +/* 64 */ { 6, s_7_64, -1, 1, 0}, +/* 65 */ { 3, s_7_65, -1, 1, 0}, +/* 66 */ { 6, s_7_66, 65, 1, 0}, +/* 67 */ { 5, s_7_67, 65, 1, 0}, +/* 68 */ { 5, s_7_68, 65, 1, 0}, +/* 69 */ { 5, s_7_69, 65, 1, 0}, +/* 70 */ { 8, s_7_70, -1, 1, 0}, +/* 71 */ { 8, s_7_71, -1, 1, 0}, +/* 72 */ { 6, s_7_72, -1, 1, 0}, +/* 73 */ { 6, s_7_73, -1, 1, 0}, +/* 74 */ { 6, s_7_74, -1, 1, 0}, +/* 75 */ { 3, s_7_75, -1, 1, 0}, +/* 76 */ { 3, s_7_76, -1, 1, 0}, +/* 77 */ { 3, s_7_77, -1, 1, 0}, +/* 78 */ { 3, s_7_78, -1, 1, 0}, +/* 79 */ { 3, s_7_79, -1, 1, 0}, +/* 80 */ { 3, s_7_80, -1, 1, 0}, +/* 81 */ { 2, s_7_81, -1, 1, 0}, +/* 82 */ { 2, s_7_82, -1, 1, 0}, +/* 83 */ { 3, s_7_83, -1, 1, 0}, +/* 84 */ { 3, s_7_84, -1, 1, 0}, +/* 85 */ { 3, s_7_85, -1, 1, 0}, +/* 86 */ { 3, s_7_86, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 }; + +static unsigned char g_AEIO[] = { 17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2 }; + +static unsigned char g_CG[] = { 17 }; + +static symbol s_0[] = { 0xE0 }; +static symbol s_1[] = { 0xE8 }; +static symbol s_2[] = { 0xEC }; +static symbol s_3[] = { 0xF2 }; +static symbol s_4[] = { 0xF9 }; +static symbol s_5[] = { 'q', 'U' }; +static symbol s_6[] = { 'u' }; +static symbol s_7[] = { 'U' }; +static symbol s_8[] = { 'i' }; +static symbol s_9[] = { 'I' }; +static symbol s_10[] = { 'i' }; +static symbol s_11[] = { 'u' }; +static symbol s_12[] = { 'e' }; +static symbol s_13[] = { 'i', 'c' }; +static symbol s_14[] = { 'l', 'o', 'g' }; +static symbol s_15[] = { 'u' }; +static symbol s_16[] = { 'e', 'n', 't', 'e' }; +static symbol s_17[] = { 'a', 't' }; +static symbol s_18[] = { 'a', 't' }; +static symbol s_19[] = { 'i', 'c' }; +static symbol s_20[] = { 'i' }; +static symbol s_21[] = { 'h' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + { int c_test = z->c; /* test, line 35 */ + while(1) { /* repeat, line 35 */ + int c = z->c; + z->bra = z->c; /* [, line 36 */ + among_var = find_among(z, a_0, 7); /* substring, line 36 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 36 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_0); /* <-, line 37 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 38 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 39 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 40 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 41 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 2, s_5); /* <-, line 42 */ + if (ret < 0) return ret; + } + break; + case 7: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 43 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + while(1) { /* repeat, line 46 */ + int c = z->c; + while(1) { /* goto, line 46 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 249))) goto lab2; + z->bra = z->c; /* [, line 47 */ + { int c = z->c; /* or, line 47 */ + if (!(eq_s(z, 1, s_6))) goto lab4; + z->ket = z->c; /* ], line 47 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab4; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 47 */ + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = c; + if (!(eq_s(z, 1, s_8))) goto lab2; + z->ket = z->c; /* ], line 48 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab2; + { int ret; + ret = slice_from_s(z, 1, s_9); /* <-, line 48 */ + if (ret < 0) return ret; + } + } + lab3: + z->c = c; + break; + lab2: + z->c = c; + if (z->c >= z->l) goto lab1; + z->c++; /* goto, line 46 */ + } + continue; + lab1: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 58 */ + { int c = z->c; /* or, line 60 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab2; + { int c = z->c; /* or, line 59 */ + if (!(out_grouping(z, g_v, 97, 249))) goto lab4; + while(1) { /* gopast, line 59 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 59 */ + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping(z, g_v, 97, 249))) goto lab2; + while(1) { /* gopast, line 59 */ + if (!(out_grouping(z, g_v, 97, 249))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab2; + z->c++; /* gopast, line 59 */ + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping(z, g_v, 97, 249))) goto lab0; + { int c = z->c; /* or, line 61 */ + if (!(out_grouping(z, g_v, 97, 249))) goto lab8; + while(1) { /* gopast, line 61 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab9; + break; + lab9: + if (z->c >= z->l) goto lab8; + z->c++; /* gopast, line 61 */ + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping(z, g_v, 97, 249))) goto lab0; + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 61 */ + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 62 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 64 */ + while(1) { /* gopast, line 65 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab11; + break; + lab11: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 65 */ + } + while(1) { /* gopast, line 65 */ + if (!(out_grouping(z, g_v, 97, 249))) goto lab12; + break; + lab12: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 65 */ + } + z->I[1] = z->c; /* setmark p1, line 65 */ + while(1) { /* gopast, line 66 */ + if (!(in_grouping(z, g_v, 97, 249))) goto lab13; + break; + lab13: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 66 */ + } + while(1) { /* gopast, line 66 */ + if (!(out_grouping(z, g_v, 97, 249))) goto lab14; + break; + lab14: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 66 */ + } + z->I[2] = z->c; /* setmark p2, line 66 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 70 */ + int c = z->c; + z->bra = z->c; /* [, line 72 */ + among_var = find_among(z, a_1, 3); /* substring, line 72 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 72 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 73 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 75 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_attached_pronoun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 87 */ + if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */ + z->bra = z->c; /* ], line 87 */ + among_var = find_among_b(z, a_3, 5); /* among, line 97 */ + if (!(among_var)) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 97 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 98 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 99 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 104 */ + among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 104 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 111 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 113 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 114 */ + z->ket = z->c; /* [, line 114 */ + if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 114 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 114 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 114 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 117 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_14); /* <-, line 117 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 119 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_15); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 121 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_16); /* <-, line 121 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 126 */ + z->ket = z->c; /* [, line 127 */ + among_var = find_among_b(z, a_4, 4); /* substring, line 127 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 127 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 127 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + z->ket = z->c; /* [, line 128 */ + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 128 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 128 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 128 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 134 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 135 */ + z->ket = z->c; /* [, line 136 */ + among_var = find_among_b(z, a_5, 3); /* substring, line 136 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 136 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 137 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 137 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 9: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 142 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 142 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 143 */ + z->ket = z->c; /* [, line 143 */ + if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 143 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 143 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 143 */ + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 143 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 143 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 148 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 148 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_7, 87); /* substring, line 149 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_vowel_suffix(struct SN_env * z) { + { int m = z->l - z->c; (void) m; /* try, line 171 */ + z->ket = z->c; /* [, line 172 */ + if (!(in_grouping_b(z, g_AEIO, 97, 242))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 172 */ + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 172 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 172 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 173 */ + if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 173 */ + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 173 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 173 */ + if (ret < 0) return ret; + } + lab0: + ; + } + { int m = z->l - z->c; (void) m; /* try, line 175 */ + z->ket = z->c; /* [, line 176 */ + if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 176 */ + if (!(in_grouping_b(z, g_CG, 99, 103))) { z->c = z->l - m; goto lab1; } + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call RV, line 176 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + lab1: + ; + } + return 1; +} + +extern int italian_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 182 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 182 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 183 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 183 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 184 */ + + { int m = z->l - z->c; (void) m; /* do, line 185 */ + { int ret = r_attached_pronoun(z); + if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 186 */ + { int m = z->l - z->c; (void) m; /* or, line 186 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab5; /* call standard_suffix, line 186 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab3; /* call verb_suffix, line 186 */ + if (ret < 0) return ret; + } + } + lab4: + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 187 */ + { int ret = r_vowel_suffix(z); + if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 189 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab7; /* call postlude, line 189 */ + if (ret < 0) return ret; + } + lab7: + z->c = c; + } + return 1; +} + +extern struct SN_env * italian_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void italian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.h new file mode 100644 index 00000000000..dccbfd5e971 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_italian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * italian_ISO_8859_1_create_env(void); +extern void italian_ISO_8859_1_close_env(struct SN_env * z); + +extern int italian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.c new file mode 100644 index 00000000000..c28e2f01f90 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.c @@ -0,0 +1,296 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int norwegian_ISO_8859_1_stem(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * norwegian_ISO_8859_1_create_env(void); +extern void norwegian_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 'a' }; +static symbol s_0_1[1] = { 'e' }; +static symbol s_0_2[3] = { 'e', 'd', 'e' }; +static symbol s_0_3[4] = { 'a', 'n', 'd', 'e' }; +static symbol s_0_4[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_0_5[3] = { 'a', 'n', 'e' }; +static symbol s_0_6[3] = { 'e', 'n', 'e' }; +static symbol s_0_7[6] = { 'h', 'e', 't', 'e', 'n', 'e' }; +static symbol s_0_8[4] = { 'e', 'r', 't', 'e' }; +static symbol s_0_9[2] = { 'e', 'n' }; +static symbol s_0_10[5] = { 'h', 'e', 't', 'e', 'n' }; +static symbol s_0_11[2] = { 'a', 'r' }; +static symbol s_0_12[2] = { 'e', 'r' }; +static symbol s_0_13[5] = { 'h', 'e', 't', 'e', 'r' }; +static symbol s_0_14[1] = { 's' }; +static symbol s_0_15[2] = { 'a', 's' }; +static symbol s_0_16[2] = { 'e', 's' }; +static symbol s_0_17[4] = { 'e', 'd', 'e', 's' }; +static symbol s_0_18[5] = { 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_19[4] = { 'e', 'n', 'e', 's' }; +static symbol s_0_20[7] = { 'h', 'e', 't', 'e', 'n', 'e', 's' }; +static symbol s_0_21[3] = { 'e', 'n', 's' }; +static symbol s_0_22[6] = { 'h', 'e', 't', 'e', 'n', 's' }; +static symbol s_0_23[3] = { 'e', 'r', 's' }; +static symbol s_0_24[3] = { 'e', 't', 's' }; +static symbol s_0_25[2] = { 'e', 't' }; +static symbol s_0_26[3] = { 'h', 'e', 't' }; +static symbol s_0_27[3] = { 'e', 'r', 't' }; +static symbol s_0_28[3] = { 'a', 's', 't' }; + +static struct among a_0[29] = +{ +/* 0 */ { 1, s_0_0, -1, 1, 0}, +/* 1 */ { 1, s_0_1, -1, 1, 0}, +/* 2 */ { 3, s_0_2, 1, 1, 0}, +/* 3 */ { 4, s_0_3, 1, 1, 0}, +/* 4 */ { 4, s_0_4, 1, 1, 0}, +/* 5 */ { 3, s_0_5, 1, 1, 0}, +/* 6 */ { 3, s_0_6, 1, 1, 0}, +/* 7 */ { 6, s_0_7, 6, 1, 0}, +/* 8 */ { 4, s_0_8, 1, 3, 0}, +/* 9 */ { 2, s_0_9, -1, 1, 0}, +/* 10 */ { 5, s_0_10, 9, 1, 0}, +/* 11 */ { 2, s_0_11, -1, 1, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 5, s_0_13, 12, 1, 0}, +/* 14 */ { 1, s_0_14, -1, 2, 0}, +/* 15 */ { 2, s_0_15, 14, 1, 0}, +/* 16 */ { 2, s_0_16, 14, 1, 0}, +/* 17 */ { 4, s_0_17, 16, 1, 0}, +/* 18 */ { 5, s_0_18, 16, 1, 0}, +/* 19 */ { 4, s_0_19, 16, 1, 0}, +/* 20 */ { 7, s_0_20, 19, 1, 0}, +/* 21 */ { 3, s_0_21, 14, 1, 0}, +/* 22 */ { 6, s_0_22, 21, 1, 0}, +/* 23 */ { 3, s_0_23, 14, 1, 0}, +/* 24 */ { 3, s_0_24, 14, 1, 0}, +/* 25 */ { 2, s_0_25, -1, 1, 0}, +/* 26 */ { 3, s_0_26, 25, 1, 0}, +/* 27 */ { 3, s_0_27, -1, 3, 0}, +/* 28 */ { 3, s_0_28, -1, 1, 0} +}; + +static symbol s_1_0[2] = { 'd', 't' }; +static symbol s_1_1[2] = { 'v', 't' }; + +static struct among a_1[2] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0} +}; + +static symbol s_2_0[3] = { 'l', 'e', 'g' }; +static symbol s_2_1[4] = { 'e', 'l', 'e', 'g' }; +static symbol s_2_2[2] = { 'i', 'g' }; +static symbol s_2_3[3] = { 'e', 'i', 'g' }; +static symbol s_2_4[3] = { 'l', 'i', 'g' }; +static symbol s_2_5[4] = { 'e', 'l', 'i', 'g' }; +static symbol s_2_6[3] = { 'e', 'l', 's' }; +static symbol s_2_7[3] = { 'l', 'o', 'v' }; +static symbol s_2_8[4] = { 'e', 'l', 'o', 'v' }; +static symbol s_2_9[4] = { 's', 'l', 'o', 'v' }; +static symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' }; + +static struct among a_2[11] = +{ +/* 0 */ { 3, s_2_0, -1, 1, 0}, +/* 1 */ { 4, s_2_1, 0, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 1, 0}, +/* 3 */ { 3, s_2_3, 2, 1, 0}, +/* 4 */ { 3, s_2_4, 2, 1, 0}, +/* 5 */ { 4, s_2_5, 4, 1, 0}, +/* 6 */ { 3, s_2_6, -1, 1, 0}, +/* 7 */ { 3, s_2_7, -1, 1, 0}, +/* 8 */ { 4, s_2_8, 7, 1, 0}, +/* 9 */ { 4, s_2_9, 7, 1, 0}, +/* 10 */ { 7, s_2_10, 9, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; + +static unsigned char g_s_ending[] = { 119, 125, 149, 1 }; + +static symbol s_0[] = { 'k' }; +static symbol s_1[] = { 'e', 'r' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 30 */ + { int c = z->c + 3; + if (0 > c || c > z->l) return 0; + z->c = c; /* hop, line 30 */ + } + z->I[1] = z->c; /* setmark x, line 30 */ + z->c = c_test; + } + while(1) { /* goto, line 31 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 248))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + if (z->c >= z->l) return 0; + z->c++; /* goto, line 31 */ + } + while(1) { /* gopast, line 31 */ + if (!(out_grouping(z, g_v, 97, 248))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 31 */ + } + z->I[0] = z->c; /* setmark p1, line 31 */ + /* try, line 32 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 38 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 38 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 38 */ + among_var = find_among_b(z, a_0, 29); /* substring, line 38 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 38 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 46 */ + if (!(in_grouping_b(z, g_s_ending, 98, 122))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_0))) return 0; + if (!(out_grouping_b(z, g_v, 97, 248))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 48 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 53 */ + { int m3; /* setlimit, line 54 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 54 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 54 */ + if (!(find_among_b(z, a_1, 2))) { z->lb = m3; return 0; } /* substring, line 54 */ + z->bra = z->c; /* ], line 54 */ + z->lb = m3; + } + z->c = z->l - m_test; + } + if (z->c <= z->lb) return 0; + z->c--; /* next, line 59 */ + z->bra = z->c; /* ], line 59 */ + { int ret; + ret = slice_del(z); /* delete, line 59 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 63 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 63 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 63 */ + among_var = find_among_b(z, a_2, 11); /* substring, line 63 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 63 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 67 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 74 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 74 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 75 */ + + { int m = z->l - z->c; (void) m; /* do, line 76 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 76 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 77 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 77 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 78 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 78 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * norwegian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void norwegian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.h new file mode 100644 index 00000000000..e09e34e52f3 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * norwegian_ISO_8859_1_create_env(void); +extern void norwegian_ISO_8859_1_close_env(struct SN_env * z); + +extern int norwegian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.c new file mode 100644 index 00000000000..b2c6ad097a0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.c @@ -0,0 +1,776 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int porter_ISO_8859_1_stem(struct SN_env * z); +static int r_Step_5b(struct SN_env * z); +static int r_Step_5a(struct SN_env * z); +static int r_Step_4(struct SN_env * z); +static int r_Step_3(struct SN_env * z); +static int r_Step_2(struct SN_env * z); +static int r_Step_1c(struct SN_env * z); +static int r_Step_1b(struct SN_env * z); +static int r_Step_1a(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_shortv(struct SN_env * z); + +extern struct SN_env * porter_ISO_8859_1_create_env(void); +extern void porter_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 's' }; +static symbol s_0_1[3] = { 'i', 'e', 's' }; +static symbol s_0_2[4] = { 's', 's', 'e', 's' }; +static symbol s_0_3[2] = { 's', 's' }; + +static struct among a_0[4] = +{ +/* 0 */ { 1, s_0_0, -1, 3, 0}, +/* 1 */ { 3, s_0_1, 0, 2, 0}, +/* 2 */ { 4, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, -1, 0} +}; + +static symbol s_1_1[2] = { 'b', 'b' }; +static symbol s_1_2[2] = { 'd', 'd' }; +static symbol s_1_3[2] = { 'f', 'f' }; +static symbol s_1_4[2] = { 'g', 'g' }; +static symbol s_1_5[2] = { 'b', 'l' }; +static symbol s_1_6[2] = { 'm', 'm' }; +static symbol s_1_7[2] = { 'n', 'n' }; +static symbol s_1_8[2] = { 'p', 'p' }; +static symbol s_1_9[2] = { 'r', 'r' }; +static symbol s_1_10[2] = { 'a', 't' }; +static symbol s_1_11[2] = { 't', 't' }; +static symbol s_1_12[2] = { 'i', 'z' }; + +static struct among a_1[13] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_1_1, 0, 2, 0}, +/* 2 */ { 2, s_1_2, 0, 2, 0}, +/* 3 */ { 2, s_1_3, 0, 2, 0}, +/* 4 */ { 2, s_1_4, 0, 2, 0}, +/* 5 */ { 2, s_1_5, 0, 1, 0}, +/* 6 */ { 2, s_1_6, 0, 2, 0}, +/* 7 */ { 2, s_1_7, 0, 2, 0}, +/* 8 */ { 2, s_1_8, 0, 2, 0}, +/* 9 */ { 2, s_1_9, 0, 2, 0}, +/* 10 */ { 2, s_1_10, 0, 1, 0}, +/* 11 */ { 2, s_1_11, 0, 2, 0}, +/* 12 */ { 2, s_1_12, 0, 1, 0} +}; + +static symbol s_2_0[2] = { 'e', 'd' }; +static symbol s_2_1[3] = { 'e', 'e', 'd' }; +static symbol s_2_2[3] = { 'i', 'n', 'g' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, 2, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 3, s_2_2, -1, 2, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 'c', 'i' }; +static symbol s_3_1[4] = { 'e', 'n', 'c', 'i' }; +static symbol s_3_2[4] = { 'a', 'b', 'l', 'i' }; +static symbol s_3_3[3] = { 'e', 'l', 'i' }; +static symbol s_3_4[4] = { 'a', 'l', 'l', 'i' }; +static symbol s_3_5[5] = { 'o', 'u', 's', 'l', 'i' }; +static symbol s_3_6[5] = { 'e', 'n', 't', 'l', 'i' }; +static symbol s_3_7[5] = { 'a', 'l', 'i', 't', 'i' }; +static symbol s_3_8[6] = { 'b', 'i', 'l', 'i', 't', 'i' }; +static symbol s_3_9[5] = { 'i', 'v', 'i', 't', 'i' }; +static symbol s_3_10[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_3_11[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_3_12[5] = { 'a', 'l', 'i', 's', 'm' }; +static symbol s_3_13[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_14[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_15[4] = { 'i', 'z', 'e', 'r' }; +static symbol s_3_16[4] = { 'a', 't', 'o', 'r' }; +static symbol s_3_17[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' }; +static symbol s_3_18[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' }; +static symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; + +static struct among a_3[20] = +{ +/* 0 */ { 4, s_3_0, -1, 3, 0}, +/* 1 */ { 4, s_3_1, -1, 2, 0}, +/* 2 */ { 4, s_3_2, -1, 4, 0}, +/* 3 */ { 3, s_3_3, -1, 6, 0}, +/* 4 */ { 4, s_3_4, -1, 9, 0}, +/* 5 */ { 5, s_3_5, -1, 12, 0}, +/* 6 */ { 5, s_3_6, -1, 5, 0}, +/* 7 */ { 5, s_3_7, -1, 10, 0}, +/* 8 */ { 6, s_3_8, -1, 14, 0}, +/* 9 */ { 5, s_3_9, -1, 13, 0}, +/* 10 */ { 6, s_3_10, -1, 1, 0}, +/* 11 */ { 7, s_3_11, 10, 8, 0}, +/* 12 */ { 5, s_3_12, -1, 10, 0}, +/* 13 */ { 5, s_3_13, -1, 8, 0}, +/* 14 */ { 7, s_3_14, 13, 7, 0}, +/* 15 */ { 4, s_3_15, -1, 7, 0}, +/* 16 */ { 4, s_3_16, -1, 8, 0}, +/* 17 */ { 7, s_3_17, -1, 13, 0}, +/* 18 */ { 7, s_3_18, -1, 11, 0}, +/* 19 */ { 7, s_3_19, -1, 12, 0} +}; + +static symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; +static symbol s_4_1[5] = { 'a', 't', 'i', 'v', 'e' }; +static symbol s_4_2[5] = { 'a', 'l', 'i', 'z', 'e' }; +static symbol s_4_3[5] = { 'i', 'c', 'i', 't', 'i' }; +static symbol s_4_4[4] = { 'i', 'c', 'a', 'l' }; +static symbol s_4_5[3] = { 'f', 'u', 'l' }; +static symbol s_4_6[4] = { 'n', 'e', 's', 's' }; + +static struct among a_4[7] = +{ +/* 0 */ { 5, s_4_0, -1, 2, 0}, +/* 1 */ { 5, s_4_1, -1, 3, 0}, +/* 2 */ { 5, s_4_2, -1, 1, 0}, +/* 3 */ { 5, s_4_3, -1, 2, 0}, +/* 4 */ { 4, s_4_4, -1, 2, 0}, +/* 5 */ { 3, s_4_5, -1, 3, 0}, +/* 6 */ { 4, s_4_6, -1, 3, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_5_2[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_5_3[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_5_4[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_5_5[3] = { 'a', 't', 'e' }; +static symbol s_5_6[3] = { 'i', 'v', 'e' }; +static symbol s_5_7[3] = { 'i', 'z', 'e' }; +static symbol s_5_8[3] = { 'i', 't', 'i' }; +static symbol s_5_9[2] = { 'a', 'l' }; +static symbol s_5_10[3] = { 'i', 's', 'm' }; +static symbol s_5_11[3] = { 'i', 'o', 'n' }; +static symbol s_5_12[2] = { 'e', 'r' }; +static symbol s_5_13[3] = { 'o', 'u', 's' }; +static symbol s_5_14[3] = { 'a', 'n', 't' }; +static symbol s_5_15[3] = { 'e', 'n', 't' }; +static symbol s_5_16[4] = { 'm', 'e', 'n', 't' }; +static symbol s_5_17[5] = { 'e', 'm', 'e', 'n', 't' }; +static symbol s_5_18[2] = { 'o', 'u' }; + +static struct among a_5[19] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 4, s_5_2, -1, 1, 0}, +/* 3 */ { 4, s_5_3, -1, 1, 0}, +/* 4 */ { 4, s_5_4, -1, 1, 0}, +/* 5 */ { 3, s_5_5, -1, 1, 0}, +/* 6 */ { 3, s_5_6, -1, 1, 0}, +/* 7 */ { 3, s_5_7, -1, 1, 0}, +/* 8 */ { 3, s_5_8, -1, 1, 0}, +/* 9 */ { 2, s_5_9, -1, 1, 0}, +/* 10 */ { 3, s_5_10, -1, 1, 0}, +/* 11 */ { 3, s_5_11, -1, 2, 0}, +/* 12 */ { 2, s_5_12, -1, 1, 0}, +/* 13 */ { 3, s_5_13, -1, 1, 0}, +/* 14 */ { 3, s_5_14, -1, 1, 0}, +/* 15 */ { 3, s_5_15, -1, 1, 0}, +/* 16 */ { 4, s_5_16, 15, 1, 0}, +/* 17 */ { 5, s_5_17, 16, 1, 0}, +/* 18 */ { 2, s_5_18, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1 }; + +static unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; + +static symbol s_0[] = { 's', 's' }; +static symbol s_1[] = { 'i' }; +static symbol s_2[] = { 'e', 'e' }; +static symbol s_3[] = { 'e' }; +static symbol s_4[] = { 'e' }; +static symbol s_5[] = { 'y' }; +static symbol s_6[] = { 'Y' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 't', 'i', 'o', 'n' }; +static symbol s_9[] = { 'e', 'n', 'c', 'e' }; +static symbol s_10[] = { 'a', 'n', 'c', 'e' }; +static symbol s_11[] = { 'a', 'b', 'l', 'e' }; +static symbol s_12[] = { 'e', 'n', 't' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'i', 'z', 'e' }; +static symbol s_15[] = { 'a', 't', 'e' }; +static symbol s_16[] = { 'a', 'l' }; +static symbol s_17[] = { 'a', 'l' }; +static symbol s_18[] = { 'f', 'u', 'l' }; +static symbol s_19[] = { 'o', 'u', 's' }; +static symbol s_20[] = { 'i', 'v', 'e' }; +static symbol s_21[] = { 'b', 'l', 'e' }; +static symbol s_22[] = { 'a', 'l' }; +static symbol s_23[] = { 'i', 'c' }; +static symbol s_24[] = { 's' }; +static symbol s_25[] = { 't' }; +static symbol s_26[] = { 'e' }; +static symbol s_27[] = { 'l' }; +static symbol s_28[] = { 'l' }; +static symbol s_29[] = { 'y' }; +static symbol s_30[] = { 'Y' }; +static symbol s_31[] = { 'y' }; +static symbol s_32[] = { 'Y' }; +static symbol s_33[] = { 'Y' }; +static symbol s_34[] = { 'y' }; + +static int r_shortv(struct SN_env * z) { + if (!(out_grouping_b(z, g_v_WXY, 89, 121))) return 0; + if (!(in_grouping_b(z, g_v, 97, 121))) return 0; + if (!(out_grouping_b(z, g_v, 97, 121))) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_Step_1a(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 25 */ + among_var = find_among_b(z, a_0, 4); /* substring, line 25 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 25 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 27 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 29 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_1b(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 34 */ + among_var = find_among_b(z, a_2, 3); /* substring, line 34 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 34 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 35 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m_test = z->l - z->c; /* test, line 38 */ + while(1) { /* gopast, line 38 */ + if (!(in_grouping_b(z, g_v, 97, 121))) goto lab0; + break; + lab0: + if (z->c <= z->lb) return 0; + z->c--; /* gopast, line 38 */ + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 38 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 39 */ + among_var = find_among_b(z, a_1, 13); /* substring, line 39 */ + if (!(among_var)) return 0; + z->c = z->l - m_test; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + case 2: + z->ket = z->c; /* [, line 44 */ + if (z->c <= z->lb) return 0; + z->c--; /* next, line 44 */ + z->bra = z->c; /* ], line 44 */ + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c != z->I[0]) return 0; /* atmark, line 45 */ + { int m_test = z->l - z->c; /* test, line 45 */ + { int ret = r_shortv(z); + if (ret == 0) return 0; /* call shortv, line 45 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + } + break; + } + return 1; +} + +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; /* [, line 52 */ + { int m = z->l - z->c; (void) m; /* or, line 52 */ + if (!(eq_s_b(z, 1, s_5))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_6))) return 0; + } +lab0: + z->bra = z->c; /* ], line 52 */ + while(1) { /* gopast, line 53 */ + if (!(in_grouping_b(z, g_v, 97, 121))) goto lab2; + break; + lab2: + if (z->c <= z->lb) return 0; + z->c--; /* gopast, line 53 */ + } + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 54 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_2(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 58 */ + among_var = find_among_b(z, a_3, 20); /* substring, line 58 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 58 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 58 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_8); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_9); /* <-, line 60 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_10); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 4, s_11); /* <-, line 62 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_12); /* <-, line 63 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 64 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 3, s_14); /* <-, line 66 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 3, s_15); /* <-, line 68 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 2, s_16); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 2, s_17); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 72 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret; + ret = slice_from_s(z, 3, s_19); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret; + ret = slice_from_s(z, 3, s_21); /* <-, line 77 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_3(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 82 */ + among_var = find_among_b(z, a_4, 7); /* substring, line 82 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 82 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 82 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_22); /* <-, line 83 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_23); /* <-, line 85 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_4(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 92 */ + among_var = find_among_b(z, a_5, 19); /* substring, line 92 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 92 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 92 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 95 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 96 */ + if (!(eq_s_b(z, 1, s_24))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_25))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 96 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_5a(struct SN_env * z) { + z->ket = z->c; /* [, line 101 */ + if (!(eq_s_b(z, 1, s_26))) return 0; + z->bra = z->c; /* ], line 101 */ + { int m = z->l - z->c; (void) m; /* or, line 102 */ + { int ret = r_R2(z); + if (ret == 0) goto lab1; /* call R2, line 102 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 102 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 102 */ + { int ret = r_shortv(z); + if (ret == 0) goto lab2; /* call shortv, line 102 */ + if (ret < 0) return ret; + } + return 0; + lab2: + z->c = z->l - m; + } + } +lab0: + { int ret; + ret = slice_del(z); /* delete, line 103 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_5b(struct SN_env * z) { + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 1, s_27))) return 0; + z->bra = z->c; /* ], line 107 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 108 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_28))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 109 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int porter_ISO_8859_1_stem(struct SN_env * z) { + z->B[0] = 0; /* unset Y_found, line 115 */ + { int c = z->c; /* do, line 116 */ + z->bra = z->c; /* [, line 116 */ + if (!(eq_s(z, 1, s_29))) goto lab0; + z->ket = z->c; /* ], line 116 */ + { int ret; + ret = slice_from_s(z, 1, s_30); /* <-, line 116 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 116 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 117 */ + while(1) { /* repeat, line 117 */ + int c = z->c; + while(1) { /* goto, line 117 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 121))) goto lab3; + z->bra = z->c; /* [, line 117 */ + if (!(eq_s(z, 1, s_31))) goto lab3; + z->ket = z->c; /* ], line 117 */ + z->c = c; + break; + lab3: + z->c = c; + if (z->c >= z->l) goto lab2; + z->c++; /* goto, line 117 */ + } + { int ret; + ret = slice_from_s(z, 1, s_32); /* <-, line 117 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 117 */ + continue; + lab2: + z->c = c; + break; + } + z->c = c; + } + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 121 */ + while(1) { /* gopast, line 122 */ + if (!(in_grouping(z, g_v, 97, 121))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 122 */ + } + while(1) { /* gopast, line 122 */ + if (!(out_grouping(z, g_v, 97, 121))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 122 */ + } + z->I[0] = z->c; /* setmark p1, line 122 */ + while(1) { /* gopast, line 123 */ + if (!(in_grouping(z, g_v, 97, 121))) goto lab7; + break; + lab7: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 123 */ + } + while(1) { /* gopast, line 123 */ + if (!(out_grouping(z, g_v, 97, 121))) goto lab8; + break; + lab8: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 123 */ + } + z->I[1] = z->c; /* setmark p2, line 123 */ + lab4: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 126 */ + + { int m = z->l - z->c; (void) m; /* do, line 127 */ + { int ret = r_Step_1a(z); + if (ret == 0) goto lab9; /* call Step_1a, line 127 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 128 */ + { int ret = r_Step_1b(z); + if (ret == 0) goto lab10; /* call Step_1b, line 128 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 129 */ + { int ret = r_Step_1c(z); + if (ret == 0) goto lab11; /* call Step_1c, line 129 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 130 */ + { int ret = r_Step_2(z); + if (ret == 0) goto lab12; /* call Step_2, line 130 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 131 */ + { int ret = r_Step_3(z); + if (ret == 0) goto lab13; /* call Step_3, line 131 */ + if (ret < 0) return ret; + } + lab13: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 132 */ + { int ret = r_Step_4(z); + if (ret == 0) goto lab14; /* call Step_4, line 132 */ + if (ret < 0) return ret; + } + lab14: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 133 */ + { int ret = r_Step_5a(z); + if (ret == 0) goto lab15; /* call Step_5a, line 133 */ + if (ret < 0) return ret; + } + lab15: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 134 */ + { int ret = r_Step_5b(z); + if (ret == 0) goto lab16; /* call Step_5b, line 134 */ + if (ret < 0) return ret; + } + lab16: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 137 */ + if (!(z->B[0])) goto lab17; /* Boolean test Y_found, line 137 */ + while(1) { /* repeat, line 137 */ + int c = z->c; + while(1) { /* goto, line 137 */ + int c = z->c; + z->bra = z->c; /* [, line 137 */ + if (!(eq_s(z, 1, s_33))) goto lab19; + z->ket = z->c; /* ], line 137 */ + z->c = c; + break; + lab19: + z->c = c; + if (z->c >= z->l) goto lab18; + z->c++; /* goto, line 137 */ + } + { int ret; + ret = slice_from_s(z, 1, s_34); /* <-, line 137 */ + if (ret < 0) return ret; + } + continue; + lab18: + z->c = c; + break; + } + lab17: + z->c = c; + } + return 1; +} + +extern struct SN_env * porter_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void porter_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.h new file mode 100644 index 00000000000..5c8fd01db17 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_porter.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * porter_ISO_8859_1_create_env(void); +extern void porter_ISO_8859_1_close_env(struct SN_env * z); + +extern int porter_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.c new file mode 100644 index 00000000000..d5869099375 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.c @@ -0,0 +1,1035 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int portuguese_ISO_8859_1_stem(struct SN_env * z); +static int r_residual_form(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * portuguese_ISO_8859_1_create_env(void); +extern void portuguese_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 0xE3 }; +static symbol s_0_2[1] = { 0xF5 }; + +static struct among a_0[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 1, s_0_1, 0, 1, 0}, +/* 2 */ { 1, s_0_2, 0, 2, 0} +}; + +static symbol s_1_1[2] = { 'a', '~' }; +static symbol s_1_2[2] = { 'o', '~' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_1_1, 0, 1, 0}, +/* 2 */ { 2, s_1_2, 0, 2, 0} +}; + +static symbol s_2_0[2] = { 'i', 'c' }; +static symbol s_2_1[2] = { 'a', 'd' }; +static symbol s_2_2[2] = { 'o', 's' }; +static symbol s_2_3[2] = { 'i', 'v' }; + +static struct among a_2[4] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 2, s_2_1, -1, -1, 0}, +/* 2 */ { 2, s_2_2, -1, -1, 0}, +/* 3 */ { 2, s_2_3, -1, 1, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 't', 'e' }; +static symbol s_3_1[4] = { 'a', 'v', 'e', 'l' }; +static symbol s_3_2[4] = { 0xED, 'v', 'e', 'l' }; + +static struct among a_3[3] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0}, +/* 2 */ { 4, s_3_2, -1, 1, 0} +}; + +static symbol s_4_0[2] = { 'i', 'c' }; +static symbol s_4_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_4_2[2] = { 'i', 'v' }; + +static struct among a_4[3] = +{ +/* 0 */ { 2, s_4_0, -1, 1, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 2, s_4_2, -1, 1, 0} +}; + +static symbol s_5_0[3] = { 'i', 'c', 'a' }; +static symbol s_5_1[5] = { 0xE2, 'n', 'c', 'i', 'a' }; +static symbol s_5_2[5] = { 0xEA, 'n', 'c', 'i', 'a' }; +static symbol s_5_3[3] = { 'i', 'r', 'a' }; +static symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' }; +static symbol s_5_5[3] = { 'o', 's', 'a' }; +static symbol s_5_6[4] = { 'i', 's', 't', 'a' }; +static symbol s_5_7[3] = { 'i', 'v', 'a' }; +static symbol s_5_8[3] = { 'e', 'z', 'a' }; +static symbol s_5_9[5] = { 'l', 'o', 'g', 0xED, 'a' }; +static symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' }; +static symbol s_5_11[4] = { 'a', 'n', 't', 'e' }; +static symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_5_14[4] = { 0xE1, 'v', 'e', 'l' }; +static symbol s_5_15[4] = { 0xED, 'v', 'e', 'l' }; +static symbol s_5_16[5] = { 'u', 'c', 'i', 0xF3, 'n' }; +static symbol s_5_17[3] = { 'i', 'c', 'o' }; +static symbol s_5_18[4] = { 'i', 's', 'm', 'o' }; +static symbol s_5_19[3] = { 'o', 's', 'o' }; +static symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static symbol s_5_22[3] = { 'i', 'v', 'o' }; +static symbol s_5_23[5] = { 'a', 0xE7, 'a', '~', 'o' }; +static symbol s_5_24[4] = { 'a', 'd', 'o', 'r' }; +static symbol s_5_25[4] = { 'i', 'c', 'a', 's' }; +static symbol s_5_26[6] = { 0xEA, 'n', 'c', 'i', 'a', 's' }; +static symbol s_5_27[4] = { 'i', 'r', 'a', 's' }; +static symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static symbol s_5_29[4] = { 'o', 's', 'a', 's' }; +static symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' }; +static symbol s_5_31[4] = { 'i', 'v', 'a', 's' }; +static symbol s_5_32[4] = { 'e', 'z', 'a', 's' }; +static symbol s_5_33[6] = { 'l', 'o', 'g', 0xED, 'a', 's' }; +static symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; +static symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_5_38[6] = { 'a', 0xE7, 'o', '~', 'e', 's' }; +static symbol s_5_39[4] = { 'i', 'c', 'o', 's' }; +static symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' }; +static symbol s_5_41[4] = { 'o', 's', 'o', 's' }; +static symbol s_5_42[7] = { 'a', 'm', 'e', 'n', 't', 'o', 's' }; +static symbol s_5_43[7] = { 'i', 'm', 'e', 'n', 't', 'o', 's' }; +static symbol s_5_44[4] = { 'i', 'v', 'o', 's' }; + +static struct among a_5[45] = +{ +/* 0 */ { 3, s_5_0, -1, 1, 0}, +/* 1 */ { 5, s_5_1, -1, 1, 0}, +/* 2 */ { 5, s_5_2, -1, 4, 0}, +/* 3 */ { 3, s_5_3, -1, 9, 0}, +/* 4 */ { 5, s_5_4, -1, 1, 0}, +/* 5 */ { 3, s_5_5, -1, 1, 0}, +/* 6 */ { 4, s_5_6, -1, 1, 0}, +/* 7 */ { 3, s_5_7, -1, 8, 0}, +/* 8 */ { 3, s_5_8, -1, 1, 0}, +/* 9 */ { 5, s_5_9, -1, 2, 0}, +/* 10 */ { 5, s_5_10, -1, 7, 0}, +/* 11 */ { 4, s_5_11, -1, 1, 0}, +/* 12 */ { 5, s_5_12, -1, 6, 0}, +/* 13 */ { 6, s_5_13, 12, 5, 0}, +/* 14 */ { 4, s_5_14, -1, 1, 0}, +/* 15 */ { 4, s_5_15, -1, 1, 0}, +/* 16 */ { 5, s_5_16, -1, 3, 0}, +/* 17 */ { 3, s_5_17, -1, 1, 0}, +/* 18 */ { 4, s_5_18, -1, 1, 0}, +/* 19 */ { 3, s_5_19, -1, 1, 0}, +/* 20 */ { 6, s_5_20, -1, 1, 0}, +/* 21 */ { 6, s_5_21, -1, 1, 0}, +/* 22 */ { 3, s_5_22, -1, 8, 0}, +/* 23 */ { 5, s_5_23, -1, 1, 0}, +/* 24 */ { 4, s_5_24, -1, 1, 0}, +/* 25 */ { 4, s_5_25, -1, 1, 0}, +/* 26 */ { 6, s_5_26, -1, 4, 0}, +/* 27 */ { 4, s_5_27, -1, 9, 0}, +/* 28 */ { 6, s_5_28, -1, 1, 0}, +/* 29 */ { 4, s_5_29, -1, 1, 0}, +/* 30 */ { 5, s_5_30, -1, 1, 0}, +/* 31 */ { 4, s_5_31, -1, 8, 0}, +/* 32 */ { 4, s_5_32, -1, 1, 0}, +/* 33 */ { 6, s_5_33, -1, 2, 0}, +/* 34 */ { 6, s_5_34, -1, 7, 0}, +/* 35 */ { 7, s_5_35, -1, 3, 0}, +/* 36 */ { 6, s_5_36, -1, 1, 0}, +/* 37 */ { 5, s_5_37, -1, 1, 0}, +/* 38 */ { 6, s_5_38, -1, 1, 0}, +/* 39 */ { 4, s_5_39, -1, 1, 0}, +/* 40 */ { 5, s_5_40, -1, 1, 0}, +/* 41 */ { 4, s_5_41, -1, 1, 0}, +/* 42 */ { 7, s_5_42, -1, 1, 0}, +/* 43 */ { 7, s_5_43, -1, 1, 0}, +/* 44 */ { 4, s_5_44, -1, 8, 0} +}; + +static symbol s_6_0[3] = { 'a', 'd', 'a' }; +static symbol s_6_1[3] = { 'i', 'd', 'a' }; +static symbol s_6_2[2] = { 'i', 'a' }; +static symbol s_6_3[4] = { 'a', 'r', 'i', 'a' }; +static symbol s_6_4[4] = { 'e', 'r', 'i', 'a' }; +static symbol s_6_5[4] = { 'i', 'r', 'i', 'a' }; +static symbol s_6_6[3] = { 'a', 'r', 'a' }; +static symbol s_6_7[3] = { 'e', 'r', 'a' }; +static symbol s_6_8[3] = { 'i', 'r', 'a' }; +static symbol s_6_9[3] = { 'a', 'v', 'a' }; +static symbol s_6_10[4] = { 'a', 's', 's', 'e' }; +static symbol s_6_11[4] = { 'e', 's', 's', 'e' }; +static symbol s_6_12[4] = { 'i', 's', 's', 'e' }; +static symbol s_6_13[4] = { 'a', 's', 't', 'e' }; +static symbol s_6_14[4] = { 'e', 's', 't', 'e' }; +static symbol s_6_15[4] = { 'i', 's', 't', 'e' }; +static symbol s_6_16[2] = { 'e', 'i' }; +static symbol s_6_17[4] = { 'a', 'r', 'e', 'i' }; +static symbol s_6_18[4] = { 'e', 'r', 'e', 'i' }; +static symbol s_6_19[4] = { 'i', 'r', 'e', 'i' }; +static symbol s_6_20[2] = { 'a', 'm' }; +static symbol s_6_21[3] = { 'i', 'a', 'm' }; +static symbol s_6_22[5] = { 'a', 'r', 'i', 'a', 'm' }; +static symbol s_6_23[5] = { 'e', 'r', 'i', 'a', 'm' }; +static symbol s_6_24[5] = { 'i', 'r', 'i', 'a', 'm' }; +static symbol s_6_25[4] = { 'a', 'r', 'a', 'm' }; +static symbol s_6_26[4] = { 'e', 'r', 'a', 'm' }; +static symbol s_6_27[4] = { 'i', 'r', 'a', 'm' }; +static symbol s_6_28[4] = { 'a', 'v', 'a', 'm' }; +static symbol s_6_29[2] = { 'e', 'm' }; +static symbol s_6_30[4] = { 'a', 'r', 'e', 'm' }; +static symbol s_6_31[4] = { 'e', 'r', 'e', 'm' }; +static symbol s_6_32[4] = { 'i', 'r', 'e', 'm' }; +static symbol s_6_33[5] = { 'a', 's', 's', 'e', 'm' }; +static symbol s_6_34[5] = { 'e', 's', 's', 'e', 'm' }; +static symbol s_6_35[5] = { 'i', 's', 's', 'e', 'm' }; +static symbol s_6_36[3] = { 'a', 'd', 'o' }; +static symbol s_6_37[3] = { 'i', 'd', 'o' }; +static symbol s_6_38[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_6_39[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_6_40[4] = { 'i', 'n', 'd', 'o' }; +static symbol s_6_41[5] = { 'a', 'r', 'a', '~', 'o' }; +static symbol s_6_42[5] = { 'e', 'r', 'a', '~', 'o' }; +static symbol s_6_43[5] = { 'i', 'r', 'a', '~', 'o' }; +static symbol s_6_44[2] = { 'a', 'r' }; +static symbol s_6_45[2] = { 'e', 'r' }; +static symbol s_6_46[2] = { 'i', 'r' }; +static symbol s_6_47[2] = { 'a', 's' }; +static symbol s_6_48[4] = { 'a', 'd', 'a', 's' }; +static symbol s_6_49[4] = { 'i', 'd', 'a', 's' }; +static symbol s_6_50[3] = { 'i', 'a', 's' }; +static symbol s_6_51[5] = { 'a', 'r', 'i', 'a', 's' }; +static symbol s_6_52[5] = { 'e', 'r', 'i', 'a', 's' }; +static symbol s_6_53[5] = { 'i', 'r', 'i', 'a', 's' }; +static symbol s_6_54[4] = { 'a', 'r', 'a', 's' }; +static symbol s_6_55[4] = { 'e', 'r', 'a', 's' }; +static symbol s_6_56[4] = { 'i', 'r', 'a', 's' }; +static symbol s_6_57[4] = { 'a', 'v', 'a', 's' }; +static symbol s_6_58[2] = { 'e', 's' }; +static symbol s_6_59[5] = { 'a', 'r', 'd', 'e', 's' }; +static symbol s_6_60[5] = { 'e', 'r', 'd', 'e', 's' }; +static symbol s_6_61[5] = { 'i', 'r', 'd', 'e', 's' }; +static symbol s_6_62[4] = { 'a', 'r', 'e', 's' }; +static symbol s_6_63[4] = { 'e', 'r', 'e', 's' }; +static symbol s_6_64[4] = { 'i', 'r', 'e', 's' }; +static symbol s_6_65[5] = { 'a', 's', 's', 'e', 's' }; +static symbol s_6_66[5] = { 'e', 's', 's', 'e', 's' }; +static symbol s_6_67[5] = { 'i', 's', 's', 'e', 's' }; +static symbol s_6_68[5] = { 'a', 's', 't', 'e', 's' }; +static symbol s_6_69[5] = { 'e', 's', 't', 'e', 's' }; +static symbol s_6_70[5] = { 'i', 's', 't', 'e', 's' }; +static symbol s_6_71[2] = { 'i', 's' }; +static symbol s_6_72[3] = { 'a', 'i', 's' }; +static symbol s_6_73[3] = { 'e', 'i', 's' }; +static symbol s_6_74[5] = { 'a', 'r', 'e', 'i', 's' }; +static symbol s_6_75[5] = { 'e', 'r', 'e', 'i', 's' }; +static symbol s_6_76[5] = { 'i', 'r', 'e', 'i', 's' }; +static symbol s_6_77[5] = { 0xE1, 'r', 'e', 'i', 's' }; +static symbol s_6_78[5] = { 0xE9, 'r', 'e', 'i', 's' }; +static symbol s_6_79[5] = { 0xED, 'r', 'e', 'i', 's' }; +static symbol s_6_80[6] = { 0xE1, 's', 's', 'e', 'i', 's' }; +static symbol s_6_81[6] = { 0xE9, 's', 's', 'e', 'i', 's' }; +static symbol s_6_82[6] = { 0xED, 's', 's', 'e', 'i', 's' }; +static symbol s_6_83[5] = { 0xE1, 'v', 'e', 'i', 's' }; +static symbol s_6_84[4] = { 0xED, 'e', 'i', 's' }; +static symbol s_6_85[6] = { 'a', 'r', 0xED, 'e', 'i', 's' }; +static symbol s_6_86[6] = { 'e', 'r', 0xED, 'e', 'i', 's' }; +static symbol s_6_87[6] = { 'i', 'r', 0xED, 'e', 'i', 's' }; +static symbol s_6_88[4] = { 'a', 'd', 'o', 's' }; +static symbol s_6_89[4] = { 'i', 'd', 'o', 's' }; +static symbol s_6_90[4] = { 'a', 'm', 'o', 's' }; +static symbol s_6_91[6] = { 0xE1, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_92[6] = { 0xE9, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_93[6] = { 0xED, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_94[6] = { 0xE1, 'v', 'a', 'm', 'o', 's' }; +static symbol s_6_95[5] = { 0xED, 'a', 'm', 'o', 's' }; +static symbol s_6_96[7] = { 'a', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_6_97[7] = { 'e', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_6_98[7] = { 'i', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_6_99[4] = { 'e', 'm', 'o', 's' }; +static symbol s_6_100[6] = { 'a', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_101[6] = { 'e', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_102[6] = { 'i', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_103[7] = { 0xE1, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_104[7] = { 0xEA, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_105[7] = { 0xED, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_106[4] = { 'i', 'm', 'o', 's' }; +static symbol s_6_107[5] = { 'a', 'r', 'm', 'o', 's' }; +static symbol s_6_108[5] = { 'e', 'r', 'm', 'o', 's' }; +static symbol s_6_109[5] = { 'i', 'r', 'm', 'o', 's' }; +static symbol s_6_110[4] = { 0xE1, 'm', 'o', 's' }; +static symbol s_6_111[4] = { 'a', 'r', 0xE1, 's' }; +static symbol s_6_112[4] = { 'e', 'r', 0xE1, 's' }; +static symbol s_6_113[4] = { 'i', 'r', 0xE1, 's' }; +static symbol s_6_114[2] = { 'e', 'u' }; +static symbol s_6_115[2] = { 'i', 'u' }; +static symbol s_6_116[2] = { 'o', 'u' }; +static symbol s_6_117[3] = { 'a', 'r', 0xE1 }; +static symbol s_6_118[3] = { 'e', 'r', 0xE1 }; +static symbol s_6_119[3] = { 'i', 'r', 0xE1 }; + +static struct among a_6[120] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 3, s_6_1, -1, 1, 0}, +/* 2 */ { 2, s_6_2, -1, 1, 0}, +/* 3 */ { 4, s_6_3, 2, 1, 0}, +/* 4 */ { 4, s_6_4, 2, 1, 0}, +/* 5 */ { 4, s_6_5, 2, 1, 0}, +/* 6 */ { 3, s_6_6, -1, 1, 0}, +/* 7 */ { 3, s_6_7, -1, 1, 0}, +/* 8 */ { 3, s_6_8, -1, 1, 0}, +/* 9 */ { 3, s_6_9, -1, 1, 0}, +/* 10 */ { 4, s_6_10, -1, 1, 0}, +/* 11 */ { 4, s_6_11, -1, 1, 0}, +/* 12 */ { 4, s_6_12, -1, 1, 0}, +/* 13 */ { 4, s_6_13, -1, 1, 0}, +/* 14 */ { 4, s_6_14, -1, 1, 0}, +/* 15 */ { 4, s_6_15, -1, 1, 0}, +/* 16 */ { 2, s_6_16, -1, 1, 0}, +/* 17 */ { 4, s_6_17, 16, 1, 0}, +/* 18 */ { 4, s_6_18, 16, 1, 0}, +/* 19 */ { 4, s_6_19, 16, 1, 0}, +/* 20 */ { 2, s_6_20, -1, 1, 0}, +/* 21 */ { 3, s_6_21, 20, 1, 0}, +/* 22 */ { 5, s_6_22, 21, 1, 0}, +/* 23 */ { 5, s_6_23, 21, 1, 0}, +/* 24 */ { 5, s_6_24, 21, 1, 0}, +/* 25 */ { 4, s_6_25, 20, 1, 0}, +/* 26 */ { 4, s_6_26, 20, 1, 0}, +/* 27 */ { 4, s_6_27, 20, 1, 0}, +/* 28 */ { 4, s_6_28, 20, 1, 0}, +/* 29 */ { 2, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, 29, 1, 0}, +/* 31 */ { 4, s_6_31, 29, 1, 0}, +/* 32 */ { 4, s_6_32, 29, 1, 0}, +/* 33 */ { 5, s_6_33, 29, 1, 0}, +/* 34 */ { 5, s_6_34, 29, 1, 0}, +/* 35 */ { 5, s_6_35, 29, 1, 0}, +/* 36 */ { 3, s_6_36, -1, 1, 0}, +/* 37 */ { 3, s_6_37, -1, 1, 0}, +/* 38 */ { 4, s_6_38, -1, 1, 0}, +/* 39 */ { 4, s_6_39, -1, 1, 0}, +/* 40 */ { 4, s_6_40, -1, 1, 0}, +/* 41 */ { 5, s_6_41, -1, 1, 0}, +/* 42 */ { 5, s_6_42, -1, 1, 0}, +/* 43 */ { 5, s_6_43, -1, 1, 0}, +/* 44 */ { 2, s_6_44, -1, 1, 0}, +/* 45 */ { 2, s_6_45, -1, 1, 0}, +/* 46 */ { 2, s_6_46, -1, 1, 0}, +/* 47 */ { 2, s_6_47, -1, 1, 0}, +/* 48 */ { 4, s_6_48, 47, 1, 0}, +/* 49 */ { 4, s_6_49, 47, 1, 0}, +/* 50 */ { 3, s_6_50, 47, 1, 0}, +/* 51 */ { 5, s_6_51, 50, 1, 0}, +/* 52 */ { 5, s_6_52, 50, 1, 0}, +/* 53 */ { 5, s_6_53, 50, 1, 0}, +/* 54 */ { 4, s_6_54, 47, 1, 0}, +/* 55 */ { 4, s_6_55, 47, 1, 0}, +/* 56 */ { 4, s_6_56, 47, 1, 0}, +/* 57 */ { 4, s_6_57, 47, 1, 0}, +/* 58 */ { 2, s_6_58, -1, 1, 0}, +/* 59 */ { 5, s_6_59, 58, 1, 0}, +/* 60 */ { 5, s_6_60, 58, 1, 0}, +/* 61 */ { 5, s_6_61, 58, 1, 0}, +/* 62 */ { 4, s_6_62, 58, 1, 0}, +/* 63 */ { 4, s_6_63, 58, 1, 0}, +/* 64 */ { 4, s_6_64, 58, 1, 0}, +/* 65 */ { 5, s_6_65, 58, 1, 0}, +/* 66 */ { 5, s_6_66, 58, 1, 0}, +/* 67 */ { 5, s_6_67, 58, 1, 0}, +/* 68 */ { 5, s_6_68, 58, 1, 0}, +/* 69 */ { 5, s_6_69, 58, 1, 0}, +/* 70 */ { 5, s_6_70, 58, 1, 0}, +/* 71 */ { 2, s_6_71, -1, 1, 0}, +/* 72 */ { 3, s_6_72, 71, 1, 0}, +/* 73 */ { 3, s_6_73, 71, 1, 0}, +/* 74 */ { 5, s_6_74, 73, 1, 0}, +/* 75 */ { 5, s_6_75, 73, 1, 0}, +/* 76 */ { 5, s_6_76, 73, 1, 0}, +/* 77 */ { 5, s_6_77, 73, 1, 0}, +/* 78 */ { 5, s_6_78, 73, 1, 0}, +/* 79 */ { 5, s_6_79, 73, 1, 0}, +/* 80 */ { 6, s_6_80, 73, 1, 0}, +/* 81 */ { 6, s_6_81, 73, 1, 0}, +/* 82 */ { 6, s_6_82, 73, 1, 0}, +/* 83 */ { 5, s_6_83, 73, 1, 0}, +/* 84 */ { 4, s_6_84, 73, 1, 0}, +/* 85 */ { 6, s_6_85, 84, 1, 0}, +/* 86 */ { 6, s_6_86, 84, 1, 0}, +/* 87 */ { 6, s_6_87, 84, 1, 0}, +/* 88 */ { 4, s_6_88, -1, 1, 0}, +/* 89 */ { 4, s_6_89, -1, 1, 0}, +/* 90 */ { 4, s_6_90, -1, 1, 0}, +/* 91 */ { 6, s_6_91, 90, 1, 0}, +/* 92 */ { 6, s_6_92, 90, 1, 0}, +/* 93 */ { 6, s_6_93, 90, 1, 0}, +/* 94 */ { 6, s_6_94, 90, 1, 0}, +/* 95 */ { 5, s_6_95, 90, 1, 0}, +/* 96 */ { 7, s_6_96, 95, 1, 0}, +/* 97 */ { 7, s_6_97, 95, 1, 0}, +/* 98 */ { 7, s_6_98, 95, 1, 0}, +/* 99 */ { 4, s_6_99, -1, 1, 0}, +/*100 */ { 6, s_6_100, 99, 1, 0}, +/*101 */ { 6, s_6_101, 99, 1, 0}, +/*102 */ { 6, s_6_102, 99, 1, 0}, +/*103 */ { 7, s_6_103, 99, 1, 0}, +/*104 */ { 7, s_6_104, 99, 1, 0}, +/*105 */ { 7, s_6_105, 99, 1, 0}, +/*106 */ { 4, s_6_106, -1, 1, 0}, +/*107 */ { 5, s_6_107, -1, 1, 0}, +/*108 */ { 5, s_6_108, -1, 1, 0}, +/*109 */ { 5, s_6_109, -1, 1, 0}, +/*110 */ { 4, s_6_110, -1, 1, 0}, +/*111 */ { 4, s_6_111, -1, 1, 0}, +/*112 */ { 4, s_6_112, -1, 1, 0}, +/*113 */ { 4, s_6_113, -1, 1, 0}, +/*114 */ { 2, s_6_114, -1, 1, 0}, +/*115 */ { 2, s_6_115, -1, 1, 0}, +/*116 */ { 2, s_6_116, -1, 1, 0}, +/*117 */ { 3, s_6_117, -1, 1, 0}, +/*118 */ { 3, s_6_118, -1, 1, 0}, +/*119 */ { 3, s_6_119, -1, 1, 0} +}; + +static symbol s_7_0[1] = { 'a' }; +static symbol s_7_1[1] = { 'i' }; +static symbol s_7_2[1] = { 'o' }; +static symbol s_7_3[2] = { 'o', 's' }; +static symbol s_7_4[1] = { 0xE1 }; +static symbol s_7_5[1] = { 0xED }; +static symbol s_7_6[1] = { 0xF3 }; + +static struct among a_7[7] = +{ +/* 0 */ { 1, s_7_0, -1, 1, 0}, +/* 1 */ { 1, s_7_1, -1, 1, 0}, +/* 2 */ { 1, s_7_2, -1, 1, 0}, +/* 3 */ { 2, s_7_3, -1, 1, 0}, +/* 4 */ { 1, s_7_4, -1, 1, 0}, +/* 5 */ { 1, s_7_5, -1, 1, 0}, +/* 6 */ { 1, s_7_6, -1, 1, 0} +}; + +static symbol s_8_0[1] = { 'e' }; +static symbol s_8_1[1] = { 0xE7 }; +static symbol s_8_2[1] = { 0xE9 }; +static symbol s_8_3[1] = { 0xEA }; + +static struct among a_8[4] = +{ +/* 0 */ { 1, s_8_0, -1, 1, 0}, +/* 1 */ { 1, s_8_1, -1, 2, 0}, +/* 2 */ { 1, s_8_2, -1, 1, 0}, +/* 3 */ { 1, s_8_3, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 }; + +static symbol s_0[] = { 'a', '~' }; +static symbol s_1[] = { 'o', '~' }; +static symbol s_2[] = { 0xE3 }; +static symbol s_3[] = { 0xF5 }; +static symbol s_4[] = { 'l', 'o', 'g' }; +static symbol s_5[] = { 'u' }; +static symbol s_6[] = { 'e', 'n', 't', 'e' }; +static symbol s_7[] = { 'a', 't' }; +static symbol s_8[] = { 'a', 't' }; +static symbol s_9[] = { 'e' }; +static symbol s_10[] = { 'i', 'r' }; +static symbol s_11[] = { 'u' }; +static symbol s_12[] = { 'g' }; +static symbol s_13[] = { 'i' }; +static symbol s_14[] = { 'c' }; +static symbol s_15[] = { 'c' }; +static symbol s_16[] = { 'i' }; +static symbol s_17[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 36 */ + int c = z->c; + z->bra = z->c; /* [, line 37 */ + among_var = find_among(z, a_0, 3); /* substring, line 37 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 37 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 39 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 40 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 50 */ + { int c = z->c; /* or, line 52 */ + if (!(in_grouping(z, g_v, 97, 250))) goto lab2; + { int c = z->c; /* or, line 51 */ + if (!(out_grouping(z, g_v, 97, 250))) goto lab4; + while(1) { /* gopast, line 51 */ + if (!(in_grouping(z, g_v, 97, 250))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 51 */ + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping(z, g_v, 97, 250))) goto lab2; + while(1) { /* gopast, line 51 */ + if (!(out_grouping(z, g_v, 97, 250))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab2; + z->c++; /* gopast, line 51 */ + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping(z, g_v, 97, 250))) goto lab0; + { int c = z->c; /* or, line 53 */ + if (!(out_grouping(z, g_v, 97, 250))) goto lab8; + while(1) { /* gopast, line 53 */ + if (!(in_grouping(z, g_v, 97, 250))) goto lab9; + break; + lab9: + if (z->c >= z->l) goto lab8; + z->c++; /* gopast, line 53 */ + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping(z, g_v, 97, 250))) goto lab0; + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 53 */ + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 54 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 56 */ + while(1) { /* gopast, line 57 */ + if (!(in_grouping(z, g_v, 97, 250))) goto lab11; + break; + lab11: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 57 */ + } + while(1) { /* gopast, line 57 */ + if (!(out_grouping(z, g_v, 97, 250))) goto lab12; + break; + lab12: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 57 */ + } + z->I[1] = z->c; /* setmark p1, line 57 */ + while(1) { /* gopast, line 58 */ + if (!(in_grouping(z, g_v, 97, 250))) goto lab13; + break; + lab13: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 58 */ + } + while(1) { /* gopast, line 58 */ + if (!(out_grouping(z, g_v, 97, 250))) goto lab14; + break; + lab14: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 58 */ + } + z->I[2] = z->c; /* setmark p2, line 58 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 62 */ + int c = z->c; + z->bra = z->c; /* [, line 63 */ + among_var = find_among(z, a_1, 3); /* substring, line 63 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 63 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 64 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 66 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 77 */ + among_var = find_among_b(z, a_5, 45); /* substring, line 77 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 77 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 93 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 93 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 102 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 110 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_2, 4); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 112 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 112 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 112 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + z->ket = z->c; /* [, line 113 */ + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 113 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 113 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + break; + case 6: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 122 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 122 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 123 */ + z->ket = z->c; /* [, line 124 */ + among_var = find_among_b(z, a_3, 3); /* substring, line 124 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 124 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 127 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 134 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 135 */ + z->ket = z->c; /* [, line 136 */ + among_var = find_among_b(z, a_4, 3); /* substring, line 136 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 136 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 139 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 146 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 146 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 147 */ + z->ket = z->c; /* [, line 148 */ + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 148 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 148 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 148 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + case 9: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 153 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_9))) return 0; + { int ret; + ret = slice_from_s(z, 2, s_10); /* <-, line 154 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 159 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 159 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 160 */ + among_var = find_among_b(z, a_6, 120); /* substring, line 160 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 160 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 184 */ + among_var = find_among_b(z, a_7, 7); /* substring, line 184 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 184 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 187 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 187 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_residual_form(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 192 */ + among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 192 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 194 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 194 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 194 */ + { int m = z->l - z->c; (void) m; /* or, line 194 */ + if (!(eq_s_b(z, 1, s_11))) goto lab1; + z->bra = z->c; /* ], line 194 */ + { int m_test = z->l - z->c; /* test, line 194 */ + if (!(eq_s_b(z, 1, s_12))) goto lab1; + z->c = z->l - m_test; + } + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_13))) return 0; + z->bra = z->c; /* ], line 195 */ + { int m_test = z->l - z->c; /* test, line 195 */ + if (!(eq_s_b(z, 1, s_14))) return 0; + z->c = z->l - m_test; + } + } + lab0: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 195 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 195 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_15); /* <-, line 196 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 202 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 202 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 203 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 203 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + + { int m = z->l - z->c; (void) m; /* do, line 205 */ + { int m = z->l - z->c; (void) m; /* or, line 209 */ + { int m = z->l - z->c; (void) m; /* and, line 207 */ + { int m = z->l - z->c; (void) m; /* or, line 206 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab6; /* call standard_suffix, line 206 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab4; /* call verb_suffix, line 206 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 207 */ + z->ket = z->c; /* [, line 207 */ + if (!(eq_s_b(z, 1, s_16))) goto lab7; + z->bra = z->c; /* ], line 207 */ + { int m_test = z->l - z->c; /* test, line 207 */ + if (!(eq_s_b(z, 1, s_17))) goto lab7; + z->c = z->l - m_test; + } + { int ret = r_RV(z); + if (ret == 0) goto lab7; /* call RV, line 207 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 207 */ + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m; + } + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab2; /* call residual_suffix, line 209 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 211 */ + { int ret = r_residual_form(z); + if (ret == 0) goto lab8; /* call residual_form, line 211 */ + if (ret < 0) return ret; + } + lab8: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 213 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab9; /* call postlude, line 213 */ + if (ret < 0) return ret; + } + lab9: + z->c = c; + } + return 1; +} + +extern struct SN_env * portuguese_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void portuguese_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.h new file mode 100644 index 00000000000..0279bc94da6 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * portuguese_ISO_8859_1_create_env(void); +extern void portuguese_ISO_8859_1_close_env(struct SN_env * z); + +extern int portuguese_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.c new file mode 100644 index 00000000000..acc4fa97511 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.c @@ -0,0 +1,1119 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int spanish_ISO_8859_1_stem(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_y_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_attached_pronoun(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); + +extern struct SN_env * spanish_ISO_8859_1_create_env(void); +extern void spanish_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 0xE1 }; +static symbol s_0_2[1] = { 0xE9 }; +static symbol s_0_3[1] = { 0xED }; +static symbol s_0_4[1] = { 0xF3 }; +static symbol s_0_5[1] = { 0xFA }; + +static struct among a_0[6] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 1, s_0_1, 0, 1, 0}, +/* 2 */ { 1, s_0_2, 0, 2, 0}, +/* 3 */ { 1, s_0_3, 0, 3, 0}, +/* 4 */ { 1, s_0_4, 0, 4, 0}, +/* 5 */ { 1, s_0_5, 0, 5, 0} +}; + +static symbol s_1_0[2] = { 'l', 'a' }; +static symbol s_1_1[4] = { 's', 'e', 'l', 'a' }; +static symbol s_1_2[2] = { 'l', 'e' }; +static symbol s_1_3[2] = { 'm', 'e' }; +static symbol s_1_4[2] = { 's', 'e' }; +static symbol s_1_5[2] = { 'l', 'o' }; +static symbol s_1_6[4] = { 's', 'e', 'l', 'o' }; +static symbol s_1_7[3] = { 'l', 'a', 's' }; +static symbol s_1_8[5] = { 's', 'e', 'l', 'a', 's' }; +static symbol s_1_9[3] = { 'l', 'e', 's' }; +static symbol s_1_10[3] = { 'l', 'o', 's' }; +static symbol s_1_11[5] = { 's', 'e', 'l', 'o', 's' }; +static symbol s_1_12[3] = { 'n', 'o', 's' }; + +static struct among a_1[13] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 4, s_1_1, 0, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 2, s_1_4, -1, -1, 0}, +/* 5 */ { 2, s_1_5, -1, -1, 0}, +/* 6 */ { 4, s_1_6, 5, -1, 0}, +/* 7 */ { 3, s_1_7, -1, -1, 0}, +/* 8 */ { 5, s_1_8, 7, -1, 0}, +/* 9 */ { 3, s_1_9, -1, -1, 0}, +/* 10 */ { 3, s_1_10, -1, -1, 0}, +/* 11 */ { 5, s_1_11, 10, -1, 0}, +/* 12 */ { 3, s_1_12, -1, -1, 0} +}; + +static symbol s_2_0[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_2_1[5] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_2_2[5] = { 'y', 'e', 'n', 'd', 'o' }; +static symbol s_2_3[4] = { 0xE1, 'n', 'd', 'o' }; +static symbol s_2_4[5] = { 'i', 0xE9, 'n', 'd', 'o' }; +static symbol s_2_5[2] = { 'a', 'r' }; +static symbol s_2_6[2] = { 'e', 'r' }; +static symbol s_2_7[2] = { 'i', 'r' }; +static symbol s_2_8[2] = { 0xE1, 'r' }; +static symbol s_2_9[2] = { 0xE9, 'r' }; +static symbol s_2_10[2] = { 0xED, 'r' }; + +static struct among a_2[11] = +{ +/* 0 */ { 4, s_2_0, -1, 6, 0}, +/* 1 */ { 5, s_2_1, -1, 6, 0}, +/* 2 */ { 5, s_2_2, -1, 7, 0}, +/* 3 */ { 4, s_2_3, -1, 2, 0}, +/* 4 */ { 5, s_2_4, -1, 1, 0}, +/* 5 */ { 2, s_2_5, -1, 6, 0}, +/* 6 */ { 2, s_2_6, -1, 6, 0}, +/* 7 */ { 2, s_2_7, -1, 6, 0}, +/* 8 */ { 2, s_2_8, -1, 3, 0}, +/* 9 */ { 2, s_2_9, -1, 4, 0}, +/* 10 */ { 2, s_2_10, -1, 5, 0} +}; + +static symbol s_3_0[2] = { 'i', 'c' }; +static symbol s_3_1[2] = { 'a', 'd' }; +static symbol s_3_2[2] = { 'o', 's' }; +static symbol s_3_3[2] = { 'i', 'v' }; + +static struct among a_3[4] = +{ +/* 0 */ { 2, s_3_0, -1, -1, 0}, +/* 1 */ { 2, s_3_1, -1, -1, 0}, +/* 2 */ { 2, s_3_2, -1, -1, 0}, +/* 3 */ { 2, s_3_3, -1, 1, 0} +}; + +static symbol s_4_0[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_4_1[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_4_2[4] = { 'a', 'n', 't', 'e' }; + +static struct among a_4[3] = +{ +/* 0 */ { 4, s_4_0, -1, 1, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 4, s_4_2, -1, 1, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_5_2[2] = { 'i', 'v' }; + +static struct among a_5[3] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 2, s_5_2, -1, 1, 0} +}; + +static symbol s_6_0[3] = { 'i', 'c', 'a' }; +static symbol s_6_1[5] = { 'a', 'n', 'c', 'i', 'a' }; +static symbol s_6_2[5] = { 'e', 'n', 'c', 'i', 'a' }; +static symbol s_6_3[5] = { 'a', 'd', 'o', 'r', 'a' }; +static symbol s_6_4[3] = { 'o', 's', 'a' }; +static symbol s_6_5[4] = { 'i', 's', 't', 'a' }; +static symbol s_6_6[3] = { 'i', 'v', 'a' }; +static symbol s_6_7[4] = { 'a', 'n', 'z', 'a' }; +static symbol s_6_8[5] = { 'l', 'o', 'g', 0xED, 'a' }; +static symbol s_6_9[4] = { 'i', 'd', 'a', 'd' }; +static symbol s_6_10[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_6_11[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_6_12[4] = { 'a', 'n', 't', 'e' }; +static symbol s_6_13[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_14[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_15[5] = { 'a', 'c', 'i', 0xF3, 'n' }; +static symbol s_6_16[5] = { 'u', 'c', 'i', 0xF3, 'n' }; +static symbol s_6_17[3] = { 'i', 'c', 'o' }; +static symbol s_6_18[4] = { 'i', 's', 'm', 'o' }; +static symbol s_6_19[3] = { 'o', 's', 'o' }; +static symbol s_6_20[7] = { 'a', 'm', 'i', 'e', 'n', 't', 'o' }; +static symbol s_6_21[7] = { 'i', 'm', 'i', 'e', 'n', 't', 'o' }; +static symbol s_6_22[3] = { 'i', 'v', 'o' }; +static symbol s_6_23[4] = { 'a', 'd', 'o', 'r' }; +static symbol s_6_24[4] = { 'i', 'c', 'a', 's' }; +static symbol s_6_25[6] = { 'a', 'n', 'c', 'i', 'a', 's' }; +static symbol s_6_26[6] = { 'e', 'n', 'c', 'i', 'a', 's' }; +static symbol s_6_27[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static symbol s_6_28[4] = { 'o', 's', 'a', 's' }; +static symbol s_6_29[5] = { 'i', 's', 't', 'a', 's' }; +static symbol s_6_30[4] = { 'i', 'v', 'a', 's' }; +static symbol s_6_31[5] = { 'a', 'n', 'z', 'a', 's' }; +static symbol s_6_32[6] = { 'l', 'o', 'g', 0xED, 'a', 's' }; +static symbol s_6_33[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; +static symbol s_6_34[5] = { 'a', 'b', 'l', 'e', 's' }; +static symbol s_6_35[5] = { 'i', 'b', 'l', 'e', 's' }; +static symbol s_6_36[7] = { 'a', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_6_37[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_6_38[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static symbol s_6_39[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_6_40[4] = { 'i', 'c', 'o', 's' }; +static symbol s_6_41[5] = { 'i', 's', 'm', 'o', 's' }; +static symbol s_6_42[4] = { 'o', 's', 'o', 's' }; +static symbol s_6_43[8] = { 'a', 'm', 'i', 'e', 'n', 't', 'o', 's' }; +static symbol s_6_44[8] = { 'i', 'm', 'i', 'e', 'n', 't', 'o', 's' }; +static symbol s_6_45[4] = { 'i', 'v', 'o', 's' }; + +static struct among a_6[46] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 5, s_6_1, -1, 2, 0}, +/* 2 */ { 5, s_6_2, -1, 5, 0}, +/* 3 */ { 5, s_6_3, -1, 2, 0}, +/* 4 */ { 3, s_6_4, -1, 1, 0}, +/* 5 */ { 4, s_6_5, -1, 1, 0}, +/* 6 */ { 3, s_6_6, -1, 9, 0}, +/* 7 */ { 4, s_6_7, -1, 1, 0}, +/* 8 */ { 5, s_6_8, -1, 3, 0}, +/* 9 */ { 4, s_6_9, -1, 8, 0}, +/* 10 */ { 4, s_6_10, -1, 1, 0}, +/* 11 */ { 4, s_6_11, -1, 1, 0}, +/* 12 */ { 4, s_6_12, -1, 2, 0}, +/* 13 */ { 5, s_6_13, -1, 7, 0}, +/* 14 */ { 6, s_6_14, 13, 6, 0}, +/* 15 */ { 5, s_6_15, -1, 2, 0}, +/* 16 */ { 5, s_6_16, -1, 4, 0}, +/* 17 */ { 3, s_6_17, -1, 1, 0}, +/* 18 */ { 4, s_6_18, -1, 1, 0}, +/* 19 */ { 3, s_6_19, -1, 1, 0}, +/* 20 */ { 7, s_6_20, -1, 1, 0}, +/* 21 */ { 7, s_6_21, -1, 1, 0}, +/* 22 */ { 3, s_6_22, -1, 9, 0}, +/* 23 */ { 4, s_6_23, -1, 2, 0}, +/* 24 */ { 4, s_6_24, -1, 1, 0}, +/* 25 */ { 6, s_6_25, -1, 2, 0}, +/* 26 */ { 6, s_6_26, -1, 5, 0}, +/* 27 */ { 6, s_6_27, -1, 2, 0}, +/* 28 */ { 4, s_6_28, -1, 1, 0}, +/* 29 */ { 5, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, -1, 9, 0}, +/* 31 */ { 5, s_6_31, -1, 1, 0}, +/* 32 */ { 6, s_6_32, -1, 3, 0}, +/* 33 */ { 6, s_6_33, -1, 8, 0}, +/* 34 */ { 5, s_6_34, -1, 1, 0}, +/* 35 */ { 5, s_6_35, -1, 1, 0}, +/* 36 */ { 7, s_6_36, -1, 2, 0}, +/* 37 */ { 7, s_6_37, -1, 4, 0}, +/* 38 */ { 6, s_6_38, -1, 2, 0}, +/* 39 */ { 5, s_6_39, -1, 2, 0}, +/* 40 */ { 4, s_6_40, -1, 1, 0}, +/* 41 */ { 5, s_6_41, -1, 1, 0}, +/* 42 */ { 4, s_6_42, -1, 1, 0}, +/* 43 */ { 8, s_6_43, -1, 1, 0}, +/* 44 */ { 8, s_6_44, -1, 1, 0}, +/* 45 */ { 4, s_6_45, -1, 9, 0} +}; + +static symbol s_7_0[2] = { 'y', 'a' }; +static symbol s_7_1[2] = { 'y', 'e' }; +static symbol s_7_2[3] = { 'y', 'a', 'n' }; +static symbol s_7_3[3] = { 'y', 'e', 'n' }; +static symbol s_7_4[5] = { 'y', 'e', 'r', 'o', 'n' }; +static symbol s_7_5[5] = { 'y', 'e', 'n', 'd', 'o' }; +static symbol s_7_6[2] = { 'y', 'o' }; +static symbol s_7_7[3] = { 'y', 'a', 's' }; +static symbol s_7_8[3] = { 'y', 'e', 's' }; +static symbol s_7_9[4] = { 'y', 'a', 'i', 's' }; +static symbol s_7_10[5] = { 'y', 'a', 'm', 'o', 's' }; +static symbol s_7_11[2] = { 'y', 0xF3 }; + +static struct among a_7[12] = +{ +/* 0 */ { 2, s_7_0, -1, 1, 0}, +/* 1 */ { 2, s_7_1, -1, 1, 0}, +/* 2 */ { 3, s_7_2, -1, 1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 5, s_7_4, -1, 1, 0}, +/* 5 */ { 5, s_7_5, -1, 1, 0}, +/* 6 */ { 2, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 3, s_7_8, -1, 1, 0}, +/* 9 */ { 4, s_7_9, -1, 1, 0}, +/* 10 */ { 5, s_7_10, -1, 1, 0}, +/* 11 */ { 2, s_7_11, -1, 1, 0} +}; + +static symbol s_8_0[3] = { 'a', 'b', 'a' }; +static symbol s_8_1[3] = { 'a', 'd', 'a' }; +static symbol s_8_2[3] = { 'i', 'd', 'a' }; +static symbol s_8_3[3] = { 'a', 'r', 'a' }; +static symbol s_8_4[4] = { 'i', 'e', 'r', 'a' }; +static symbol s_8_5[2] = { 0xED, 'a' }; +static symbol s_8_6[4] = { 'a', 'r', 0xED, 'a' }; +static symbol s_8_7[4] = { 'e', 'r', 0xED, 'a' }; +static symbol s_8_8[4] = { 'i', 'r', 0xED, 'a' }; +static symbol s_8_9[2] = { 'a', 'd' }; +static symbol s_8_10[2] = { 'e', 'd' }; +static symbol s_8_11[2] = { 'i', 'd' }; +static symbol s_8_12[3] = { 'a', 's', 'e' }; +static symbol s_8_13[4] = { 'i', 'e', 's', 'e' }; +static symbol s_8_14[4] = { 'a', 's', 't', 'e' }; +static symbol s_8_15[4] = { 'i', 's', 't', 'e' }; +static symbol s_8_16[2] = { 'a', 'n' }; +static symbol s_8_17[4] = { 'a', 'b', 'a', 'n' }; +static symbol s_8_18[4] = { 'a', 'r', 'a', 'n' }; +static symbol s_8_19[5] = { 'i', 'e', 'r', 'a', 'n' }; +static symbol s_8_20[3] = { 0xED, 'a', 'n' }; +static symbol s_8_21[5] = { 'a', 'r', 0xED, 'a', 'n' }; +static symbol s_8_22[5] = { 'e', 'r', 0xED, 'a', 'n' }; +static symbol s_8_23[5] = { 'i', 'r', 0xED, 'a', 'n' }; +static symbol s_8_24[2] = { 'e', 'n' }; +static symbol s_8_25[4] = { 'a', 's', 'e', 'n' }; +static symbol s_8_26[5] = { 'i', 'e', 's', 'e', 'n' }; +static symbol s_8_27[4] = { 'a', 'r', 'o', 'n' }; +static symbol s_8_28[5] = { 'i', 'e', 'r', 'o', 'n' }; +static symbol s_8_29[4] = { 'a', 'r', 0xE1, 'n' }; +static symbol s_8_30[4] = { 'e', 'r', 0xE1, 'n' }; +static symbol s_8_31[4] = { 'i', 'r', 0xE1, 'n' }; +static symbol s_8_32[3] = { 'a', 'd', 'o' }; +static symbol s_8_33[3] = { 'i', 'd', 'o' }; +static symbol s_8_34[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_8_35[5] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_8_36[2] = { 'a', 'r' }; +static symbol s_8_37[2] = { 'e', 'r' }; +static symbol s_8_38[2] = { 'i', 'r' }; +static symbol s_8_39[2] = { 'a', 's' }; +static symbol s_8_40[4] = { 'a', 'b', 'a', 's' }; +static symbol s_8_41[4] = { 'a', 'd', 'a', 's' }; +static symbol s_8_42[4] = { 'i', 'd', 'a', 's' }; +static symbol s_8_43[4] = { 'a', 'r', 'a', 's' }; +static symbol s_8_44[5] = { 'i', 'e', 'r', 'a', 's' }; +static symbol s_8_45[3] = { 0xED, 'a', 's' }; +static symbol s_8_46[5] = { 'a', 'r', 0xED, 'a', 's' }; +static symbol s_8_47[5] = { 'e', 'r', 0xED, 'a', 's' }; +static symbol s_8_48[5] = { 'i', 'r', 0xED, 'a', 's' }; +static symbol s_8_49[2] = { 'e', 's' }; +static symbol s_8_50[4] = { 'a', 's', 'e', 's' }; +static symbol s_8_51[5] = { 'i', 'e', 's', 'e', 's' }; +static symbol s_8_52[5] = { 'a', 'b', 'a', 'i', 's' }; +static symbol s_8_53[5] = { 'a', 'r', 'a', 'i', 's' }; +static symbol s_8_54[6] = { 'i', 'e', 'r', 'a', 'i', 's' }; +static symbol s_8_55[4] = { 0xED, 'a', 'i', 's' }; +static symbol s_8_56[6] = { 'a', 'r', 0xED, 'a', 'i', 's' }; +static symbol s_8_57[6] = { 'e', 'r', 0xED, 'a', 'i', 's' }; +static symbol s_8_58[6] = { 'i', 'r', 0xED, 'a', 'i', 's' }; +static symbol s_8_59[5] = { 'a', 's', 'e', 'i', 's' }; +static symbol s_8_60[6] = { 'i', 'e', 's', 'e', 'i', 's' }; +static symbol s_8_61[6] = { 'a', 's', 't', 'e', 'i', 's' }; +static symbol s_8_62[6] = { 'i', 's', 't', 'e', 'i', 's' }; +static symbol s_8_63[3] = { 0xE1, 'i', 's' }; +static symbol s_8_64[3] = { 0xE9, 'i', 's' }; +static symbol s_8_65[5] = { 'a', 'r', 0xE9, 'i', 's' }; +static symbol s_8_66[5] = { 'e', 'r', 0xE9, 'i', 's' }; +static symbol s_8_67[5] = { 'i', 'r', 0xE9, 'i', 's' }; +static symbol s_8_68[4] = { 'a', 'd', 'o', 's' }; +static symbol s_8_69[4] = { 'i', 'd', 'o', 's' }; +static symbol s_8_70[4] = { 'a', 'm', 'o', 's' }; +static symbol s_8_71[6] = { 0xE1, 'b', 'a', 'm', 'o', 's' }; +static symbol s_8_72[6] = { 0xE1, 'r', 'a', 'm', 'o', 's' }; +static symbol s_8_73[7] = { 'i', 0xE9, 'r', 'a', 'm', 'o', 's' }; +static symbol s_8_74[5] = { 0xED, 'a', 'm', 'o', 's' }; +static symbol s_8_75[7] = { 'a', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_8_76[7] = { 'e', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_8_77[7] = { 'i', 'r', 0xED, 'a', 'm', 'o', 's' }; +static symbol s_8_78[4] = { 'e', 'm', 'o', 's' }; +static symbol s_8_79[6] = { 'a', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_80[6] = { 'e', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_81[6] = { 'i', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_82[6] = { 0xE1, 's', 'e', 'm', 'o', 's' }; +static symbol s_8_83[7] = { 'i', 0xE9, 's', 'e', 'm', 'o', 's' }; +static symbol s_8_84[4] = { 'i', 'm', 'o', 's' }; +static symbol s_8_85[4] = { 'a', 'r', 0xE1, 's' }; +static symbol s_8_86[4] = { 'e', 'r', 0xE1, 's' }; +static symbol s_8_87[4] = { 'i', 'r', 0xE1, 's' }; +static symbol s_8_88[2] = { 0xED, 's' }; +static symbol s_8_89[3] = { 'a', 'r', 0xE1 }; +static symbol s_8_90[3] = { 'e', 'r', 0xE1 }; +static symbol s_8_91[3] = { 'i', 'r', 0xE1 }; +static symbol s_8_92[3] = { 'a', 'r', 0xE9 }; +static symbol s_8_93[3] = { 'e', 'r', 0xE9 }; +static symbol s_8_94[3] = { 'i', 'r', 0xE9 }; +static symbol s_8_95[2] = { 'i', 0xF3 }; + +static struct among a_8[96] = +{ +/* 0 */ { 3, s_8_0, -1, 2, 0}, +/* 1 */ { 3, s_8_1, -1, 2, 0}, +/* 2 */ { 3, s_8_2, -1, 2, 0}, +/* 3 */ { 3, s_8_3, -1, 2, 0}, +/* 4 */ { 4, s_8_4, -1, 2, 0}, +/* 5 */ { 2, s_8_5, -1, 2, 0}, +/* 6 */ { 4, s_8_6, 5, 2, 0}, +/* 7 */ { 4, s_8_7, 5, 2, 0}, +/* 8 */ { 4, s_8_8, 5, 2, 0}, +/* 9 */ { 2, s_8_9, -1, 2, 0}, +/* 10 */ { 2, s_8_10, -1, 2, 0}, +/* 11 */ { 2, s_8_11, -1, 2, 0}, +/* 12 */ { 3, s_8_12, -1, 2, 0}, +/* 13 */ { 4, s_8_13, -1, 2, 0}, +/* 14 */ { 4, s_8_14, -1, 2, 0}, +/* 15 */ { 4, s_8_15, -1, 2, 0}, +/* 16 */ { 2, s_8_16, -1, 2, 0}, +/* 17 */ { 4, s_8_17, 16, 2, 0}, +/* 18 */ { 4, s_8_18, 16, 2, 0}, +/* 19 */ { 5, s_8_19, 16, 2, 0}, +/* 20 */ { 3, s_8_20, 16, 2, 0}, +/* 21 */ { 5, s_8_21, 20, 2, 0}, +/* 22 */ { 5, s_8_22, 20, 2, 0}, +/* 23 */ { 5, s_8_23, 20, 2, 0}, +/* 24 */ { 2, s_8_24, -1, 1, 0}, +/* 25 */ { 4, s_8_25, 24, 2, 0}, +/* 26 */ { 5, s_8_26, 24, 2, 0}, +/* 27 */ { 4, s_8_27, -1, 2, 0}, +/* 28 */ { 5, s_8_28, -1, 2, 0}, +/* 29 */ { 4, s_8_29, -1, 2, 0}, +/* 30 */ { 4, s_8_30, -1, 2, 0}, +/* 31 */ { 4, s_8_31, -1, 2, 0}, +/* 32 */ { 3, s_8_32, -1, 2, 0}, +/* 33 */ { 3, s_8_33, -1, 2, 0}, +/* 34 */ { 4, s_8_34, -1, 2, 0}, +/* 35 */ { 5, s_8_35, -1, 2, 0}, +/* 36 */ { 2, s_8_36, -1, 2, 0}, +/* 37 */ { 2, s_8_37, -1, 2, 0}, +/* 38 */ { 2, s_8_38, -1, 2, 0}, +/* 39 */ { 2, s_8_39, -1, 2, 0}, +/* 40 */ { 4, s_8_40, 39, 2, 0}, +/* 41 */ { 4, s_8_41, 39, 2, 0}, +/* 42 */ { 4, s_8_42, 39, 2, 0}, +/* 43 */ { 4, s_8_43, 39, 2, 0}, +/* 44 */ { 5, s_8_44, 39, 2, 0}, +/* 45 */ { 3, s_8_45, 39, 2, 0}, +/* 46 */ { 5, s_8_46, 45, 2, 0}, +/* 47 */ { 5, s_8_47, 45, 2, 0}, +/* 48 */ { 5, s_8_48, 45, 2, 0}, +/* 49 */ { 2, s_8_49, -1, 1, 0}, +/* 50 */ { 4, s_8_50, 49, 2, 0}, +/* 51 */ { 5, s_8_51, 49, 2, 0}, +/* 52 */ { 5, s_8_52, -1, 2, 0}, +/* 53 */ { 5, s_8_53, -1, 2, 0}, +/* 54 */ { 6, s_8_54, -1, 2, 0}, +/* 55 */ { 4, s_8_55, -1, 2, 0}, +/* 56 */ { 6, s_8_56, 55, 2, 0}, +/* 57 */ { 6, s_8_57, 55, 2, 0}, +/* 58 */ { 6, s_8_58, 55, 2, 0}, +/* 59 */ { 5, s_8_59, -1, 2, 0}, +/* 60 */ { 6, s_8_60, -1, 2, 0}, +/* 61 */ { 6, s_8_61, -1, 2, 0}, +/* 62 */ { 6, s_8_62, -1, 2, 0}, +/* 63 */ { 3, s_8_63, -1, 2, 0}, +/* 64 */ { 3, s_8_64, -1, 1, 0}, +/* 65 */ { 5, s_8_65, 64, 2, 0}, +/* 66 */ { 5, s_8_66, 64, 2, 0}, +/* 67 */ { 5, s_8_67, 64, 2, 0}, +/* 68 */ { 4, s_8_68, -1, 2, 0}, +/* 69 */ { 4, s_8_69, -1, 2, 0}, +/* 70 */ { 4, s_8_70, -1, 2, 0}, +/* 71 */ { 6, s_8_71, 70, 2, 0}, +/* 72 */ { 6, s_8_72, 70, 2, 0}, +/* 73 */ { 7, s_8_73, 70, 2, 0}, +/* 74 */ { 5, s_8_74, 70, 2, 0}, +/* 75 */ { 7, s_8_75, 74, 2, 0}, +/* 76 */ { 7, s_8_76, 74, 2, 0}, +/* 77 */ { 7, s_8_77, 74, 2, 0}, +/* 78 */ { 4, s_8_78, -1, 1, 0}, +/* 79 */ { 6, s_8_79, 78, 2, 0}, +/* 80 */ { 6, s_8_80, 78, 2, 0}, +/* 81 */ { 6, s_8_81, 78, 2, 0}, +/* 82 */ { 6, s_8_82, 78, 2, 0}, +/* 83 */ { 7, s_8_83, 78, 2, 0}, +/* 84 */ { 4, s_8_84, -1, 2, 0}, +/* 85 */ { 4, s_8_85, -1, 2, 0}, +/* 86 */ { 4, s_8_86, -1, 2, 0}, +/* 87 */ { 4, s_8_87, -1, 2, 0}, +/* 88 */ { 2, s_8_88, -1, 2, 0}, +/* 89 */ { 3, s_8_89, -1, 2, 0}, +/* 90 */ { 3, s_8_90, -1, 2, 0}, +/* 91 */ { 3, s_8_91, -1, 2, 0}, +/* 92 */ { 3, s_8_92, -1, 2, 0}, +/* 93 */ { 3, s_8_93, -1, 2, 0}, +/* 94 */ { 3, s_8_94, -1, 2, 0}, +/* 95 */ { 2, s_8_95, -1, 2, 0} +}; + +static symbol s_9_0[1] = { 'a' }; +static symbol s_9_1[1] = { 'e' }; +static symbol s_9_2[1] = { 'o' }; +static symbol s_9_3[2] = { 'o', 's' }; +static symbol s_9_4[1] = { 0xE1 }; +static symbol s_9_5[1] = { 0xE9 }; +static symbol s_9_6[1] = { 0xED }; +static symbol s_9_7[1] = { 0xF3 }; + +static struct among a_9[8] = +{ +/* 0 */ { 1, s_9_0, -1, 1, 0}, +/* 1 */ { 1, s_9_1, -1, 2, 0}, +/* 2 */ { 1, s_9_2, -1, 1, 0}, +/* 3 */ { 2, s_9_3, -1, 1, 0}, +/* 4 */ { 1, s_9_4, -1, 1, 0}, +/* 5 */ { 1, s_9_5, -1, 2, 0}, +/* 6 */ { 1, s_9_6, -1, 1, 0}, +/* 7 */ { 1, s_9_7, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 }; + +static symbol s_0[] = { 'a' }; +static symbol s_1[] = { 'e' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'o' }; +static symbol s_4[] = { 'u' }; +static symbol s_5[] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_6[] = { 'a', 'n', 'd', 'o' }; +static symbol s_7[] = { 'a', 'r' }; +static symbol s_8[] = { 'e', 'r' }; +static symbol s_9[] = { 'i', 'r' }; +static symbol s_10[] = { 'u' }; +static symbol s_11[] = { 'i', 'c' }; +static symbol s_12[] = { 'l', 'o', 'g' }; +static symbol s_13[] = { 'u' }; +static symbol s_14[] = { 'e', 'n', 't', 'e' }; +static symbol s_15[] = { 'a', 't' }; +static symbol s_16[] = { 'a', 't' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'u' }; +static symbol s_19[] = { 'g' }; +static symbol s_20[] = { 'u' }; +static symbol s_21[] = { 'g' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 37 */ + { int c = z->c; /* or, line 39 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab2; + { int c = z->c; /* or, line 38 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab4; + while(1) { /* gopast, line 38 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab5; + break; + lab5: + if (z->c >= z->l) goto lab4; + z->c++; /* gopast, line 38 */ + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping(z, g_v, 97, 252))) goto lab2; + while(1) { /* gopast, line 38 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab6; + break; + lab6: + if (z->c >= z->l) goto lab2; + z->c++; /* gopast, line 38 */ + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping(z, g_v, 97, 252))) goto lab0; + { int c = z->c; /* or, line 40 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab8; + while(1) { /* gopast, line 40 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab9; + break; + lab9: + if (z->c >= z->l) goto lab8; + z->c++; /* gopast, line 40 */ + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping(z, g_v, 97, 252))) goto lab0; + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 40 */ + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 41 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 43 */ + while(1) { /* gopast, line 44 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab11; + break; + lab11: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 44 */ + } + while(1) { /* gopast, line 44 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab12; + break; + lab12: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 44 */ + } + z->I[1] = z->c; /* setmark p1, line 44 */ + while(1) { /* gopast, line 45 */ + if (!(in_grouping(z, g_v, 97, 252))) goto lab13; + break; + lab13: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 45 */ + } + while(1) { /* gopast, line 45 */ + if (!(out_grouping(z, g_v, 97, 252))) goto lab14; + break; + lab14: + if (z->c >= z->l) goto lab10; + z->c++; /* gopast, line 45 */ + } + z->I[2] = z->c; /* setmark p2, line 45 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 49 */ + int c = z->c; + z->bra = z->c; /* [, line 50 */ + among_var = find_among(z, a_0, 6); /* substring, line 50 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 50 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 52 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 54 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 55 */ + if (ret < 0) return ret; + } + break; + case 6: + if (z->c >= z->l) goto lab0; + z->c++; /* next, line 57 */ + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_attached_pronoun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 68 */ + if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */ + z->bra = z->c; /* ], line 68 */ + among_var = find_among_b(z, a_2, 11); /* substring, line 72 */ + if (!(among_var)) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 72 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + z->bra = z->c; /* ], line 73 */ + { int ret; + ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ + if (ret < 0) return ret; + } + break; + case 2: + z->bra = z->c; /* ], line 74 */ + { int ret; + ret = slice_from_s(z, 4, s_6); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + z->bra = z->c; /* ], line 75 */ + { int ret; + ret = slice_from_s(z, 2, s_7); /* <-, line 75 */ + if (ret < 0) return ret; + } + break; + case 4: + z->bra = z->c; /* ], line 76 */ + { int ret; + ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 5: + z->bra = z->c; /* ], line 77 */ + { int ret; + ret = slice_from_s(z, 2, s_9); /* <-, line 77 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_del(z); /* delete, line 81 */ + if (ret < 0) return ret; + } + break; + case 7: + if (!(eq_s_b(z, 1, s_10))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 82 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 87 */ + among_var = find_among_b(z, a_6, 46); /* substring, line 87 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 87 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 99 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 99 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 105 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 105 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 106 */ + z->ket = z->c; /* [, line 106 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 106 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 106 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_12); /* <-, line 111 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 115 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 115 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 119 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_14); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 124 */ + z->ket = z->c; /* [, line 125 */ + among_var = find_among_b(z, a_3, 4); /* substring, line 125 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 125 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + z->ket = z->c; /* [, line 126 */ + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 126 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 126 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 126 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 135 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 135 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 136 */ + z->ket = z->c; /* [, line 137 */ + among_var = find_among_b(z, a_4, 3); /* substring, line 137 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 137 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 140 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 140 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 147 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 147 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 148 */ + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_5, 3); /* substring, line 149 */ + if (!(among_var)) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab3; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 152 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + break; + } + lab3: + ; + } + break; + case 9: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 159 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 159 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 160 */ + z->ket = z->c; /* [, line 161 */ + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m; goto lab4; } + z->bra = z->c; /* ], line 161 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab4; } /* call R2, line 161 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 161 */ + if (ret < 0) return ret; + } + lab4: + ; + } + break; + } + return 1; +} + +static int r_y_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 168 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 168 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 168 */ + among_var = find_among_b(z, a_7, 12); /* substring, line 168 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 168 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(eq_s_b(z, 1, s_17))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 171 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 176 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 176 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 176 */ + among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 176 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* try, line 179 */ + if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m; goto lab0; } + { int m_test = z->l - z->c; /* test, line 179 */ + if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + lab0: + ; + } + z->bra = z->c; /* ], line 179 */ + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 200 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 205 */ + among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 205 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 208 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 208 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 210 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 210 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 210 */ + z->ket = z->c; /* [, line 210 */ + if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 210 */ + { int m_test = z->l - z->c; /* test, line 210 */ + if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 210 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 210 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + } + return 1; +} + +extern int spanish_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 216 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 216 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 217 */ + + { int m = z->l - z->c; (void) m; /* do, line 218 */ + { int ret = r_attached_pronoun(z); + if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 219 */ + { int m = z->l - z->c; (void) m; /* or, line 219 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab4; /* call standard_suffix, line 219 */ + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_y_verb_suffix(z); + if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */ + if (ret < 0) return ret; + } + goto lab3; + lab5: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab2; /* call verb_suffix, line 221 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 223 */ + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab6; /* call residual_suffix, line 223 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 225 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab7; /* call postlude, line 225 */ + if (ret < 0) return ret; + } + lab7: + z->c = c; + } + return 1; +} + +extern struct SN_env * spanish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void spanish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.h new file mode 100644 index 00000000000..83f1498403f --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_spanish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * spanish_ISO_8859_1_create_env(void); +extern void spanish_ISO_8859_1_close_env(struct SN_env * z); + +extern int spanish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.c new file mode 100644 index 00000000000..c571fd9370b --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.c @@ -0,0 +1,307 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int swedish_ISO_8859_1_stem(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * swedish_ISO_8859_1_create_env(void); +extern void swedish_ISO_8859_1_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 'a' }; +static symbol s_0_1[4] = { 'a', 'r', 'n', 'a' }; +static symbol s_0_2[4] = { 'e', 'r', 'n', 'a' }; +static symbol s_0_3[7] = { 'h', 'e', 't', 'e', 'r', 'n', 'a' }; +static symbol s_0_4[4] = { 'o', 'r', 'n', 'a' }; +static symbol s_0_5[2] = { 'a', 'd' }; +static symbol s_0_6[1] = { 'e' }; +static symbol s_0_7[3] = { 'a', 'd', 'e' }; +static symbol s_0_8[4] = { 'a', 'n', 'd', 'e' }; +static symbol s_0_9[4] = { 'a', 'r', 'n', 'e' }; +static symbol s_0_10[3] = { 'a', 'r', 'e' }; +static symbol s_0_11[4] = { 'a', 's', 't', 'e' }; +static symbol s_0_12[2] = { 'e', 'n' }; +static symbol s_0_13[5] = { 'a', 'n', 'd', 'e', 'n' }; +static symbol s_0_14[4] = { 'a', 'r', 'e', 'n' }; +static symbol s_0_15[5] = { 'h', 'e', 't', 'e', 'n' }; +static symbol s_0_16[3] = { 'e', 'r', 'n' }; +static symbol s_0_17[2] = { 'a', 'r' }; +static symbol s_0_18[2] = { 'e', 'r' }; +static symbol s_0_19[5] = { 'h', 'e', 't', 'e', 'r' }; +static symbol s_0_20[2] = { 'o', 'r' }; +static symbol s_0_21[1] = { 's' }; +static symbol s_0_22[2] = { 'a', 's' }; +static symbol s_0_23[5] = { 'a', 'r', 'n', 'a', 's' }; +static symbol s_0_24[5] = { 'e', 'r', 'n', 'a', 's' }; +static symbol s_0_25[5] = { 'o', 'r', 'n', 'a', 's' }; +static symbol s_0_26[2] = { 'e', 's' }; +static symbol s_0_27[4] = { 'a', 'd', 'e', 's' }; +static symbol s_0_28[5] = { 'a', 'n', 'd', 'e', 's' }; +static symbol s_0_29[3] = { 'e', 'n', 's' }; +static symbol s_0_30[5] = { 'a', 'r', 'e', 'n', 's' }; +static symbol s_0_31[6] = { 'h', 'e', 't', 'e', 'n', 's' }; +static symbol s_0_32[4] = { 'e', 'r', 'n', 's' }; +static symbol s_0_33[2] = { 'a', 't' }; +static symbol s_0_34[5] = { 'a', 'n', 'd', 'e', 't' }; +static symbol s_0_35[3] = { 'h', 'e', 't' }; +static symbol s_0_36[3] = { 'a', 's', 't' }; + +static struct among a_0[37] = +{ +/* 0 */ { 1, s_0_0, -1, 1, 0}, +/* 1 */ { 4, s_0_1, 0, 1, 0}, +/* 2 */ { 4, s_0_2, 0, 1, 0}, +/* 3 */ { 7, s_0_3, 2, 1, 0}, +/* 4 */ { 4, s_0_4, 0, 1, 0}, +/* 5 */ { 2, s_0_5, -1, 1, 0}, +/* 6 */ { 1, s_0_6, -1, 1, 0}, +/* 7 */ { 3, s_0_7, 6, 1, 0}, +/* 8 */ { 4, s_0_8, 6, 1, 0}, +/* 9 */ { 4, s_0_9, 6, 1, 0}, +/* 10 */ { 3, s_0_10, 6, 1, 0}, +/* 11 */ { 4, s_0_11, 6, 1, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 5, s_0_13, 12, 1, 0}, +/* 14 */ { 4, s_0_14, 12, 1, 0}, +/* 15 */ { 5, s_0_15, 12, 1, 0}, +/* 16 */ { 3, s_0_16, -1, 1, 0}, +/* 17 */ { 2, s_0_17, -1, 1, 0}, +/* 18 */ { 2, s_0_18, -1, 1, 0}, +/* 19 */ { 5, s_0_19, 18, 1, 0}, +/* 20 */ { 2, s_0_20, -1, 1, 0}, +/* 21 */ { 1, s_0_21, -1, 2, 0}, +/* 22 */ { 2, s_0_22, 21, 1, 0}, +/* 23 */ { 5, s_0_23, 22, 1, 0}, +/* 24 */ { 5, s_0_24, 22, 1, 0}, +/* 25 */ { 5, s_0_25, 22, 1, 0}, +/* 26 */ { 2, s_0_26, 21, 1, 0}, +/* 27 */ { 4, s_0_27, 26, 1, 0}, +/* 28 */ { 5, s_0_28, 26, 1, 0}, +/* 29 */ { 3, s_0_29, 21, 1, 0}, +/* 30 */ { 5, s_0_30, 29, 1, 0}, +/* 31 */ { 6, s_0_31, 29, 1, 0}, +/* 32 */ { 4, s_0_32, 21, 1, 0}, +/* 33 */ { 2, s_0_33, -1, 1, 0}, +/* 34 */ { 5, s_0_34, -1, 1, 0}, +/* 35 */ { 3, s_0_35, -1, 1, 0}, +/* 36 */ { 3, s_0_36, -1, 1, 0} +}; + +static symbol s_1_0[2] = { 'd', 'd' }; +static symbol s_1_1[2] = { 'g', 'd' }; +static symbol s_1_2[2] = { 'n', 'n' }; +static symbol s_1_3[2] = { 'd', 't' }; +static symbol s_1_4[2] = { 'g', 't' }; +static symbol s_1_5[2] = { 'k', 't' }; +static symbol s_1_6[2] = { 't', 't' }; + +static struct among a_1[7] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 2, s_1_4, -1, -1, 0}, +/* 5 */ { 2, s_1_5, -1, -1, 0}, +/* 6 */ { 2, s_1_6, -1, -1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'g' }; +static symbol s_2_1[3] = { 'l', 'i', 'g' }; +static symbol s_2_2[3] = { 'e', 'l', 's' }; +static symbol s_2_3[5] = { 'f', 'u', 'l', 'l', 't' }; +static symbol s_2_4[4] = { 'l', 0xF6, 's', 't' }; + +static struct among a_2[5] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 3, s_2_2, -1, 1, 0}, +/* 3 */ { 5, s_2_3, -1, 3, 0}, +/* 4 */ { 4, s_2_4, -1, 2, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 }; + +static unsigned char g_s_ending[] = { 119, 127, 149 }; + +static symbol s_0[] = { 'l', 0xF6, 's' }; +static symbol s_1[] = { 'f', 'u', 'l', 'l' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 29 */ + { int c = z->c + 3; + if (0 > c || c > z->l) return 0; + z->c = c; /* hop, line 29 */ + } + z->I[1] = z->c; /* setmark x, line 29 */ + z->c = c_test; + } + while(1) { /* goto, line 30 */ + int c = z->c; + if (!(in_grouping(z, g_v, 97, 246))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + if (z->c >= z->l) return 0; + z->c++; /* goto, line 30 */ + } + while(1) { /* gopast, line 30 */ + if (!(out_grouping(z, g_v, 97, 246))) goto lab1; + break; + lab1: + if (z->c >= z->l) return 0; + z->c++; /* gopast, line 30 */ + } + z->I[0] = z->c; /* setmark p1, line 30 */ + /* try, line 31 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 37 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 37 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 37 */ + among_var = find_among_b(z, a_0, 37); /* substring, line 37 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 37 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b(z, g_s_ending, 98, 121))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m3; /* setlimit, line 50 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 50 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* and, line 52 */ + if (!(find_among_b(z, a_1, 7))) { z->lb = m3; return 0; } /* among, line 51 */ + z->c = z->l - m; + z->ket = z->c; /* [, line 52 */ + if (z->c <= z->lb) { z->lb = m3; return 0; } + z->c--; /* next, line 52 */ + z->bra = z->c; /* ], line 52 */ + { int ret; + ret = slice_del(z); /* delete, line 52 */ + if (ret < 0) return ret; + } + } + z->lb = m3; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 55 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 55 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 56 */ + among_var = find_among_b(z, a_2, 5); /* substring, line 56 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 56 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 57 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_0); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_1); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +extern int swedish_ISO_8859_1_stem(struct SN_env * z) { + { int c = z->c; /* do, line 66 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 66 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 67 */ + + { int m = z->l - z->c; (void) m; /* do, line 68 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 68 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 69 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 69 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 70 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 70 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * swedish_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void swedish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.h new file mode 100644 index 00000000000..4184e5ca39e --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_ISO_8859_1_swedish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * swedish_ISO_8859_1_create_env(void); +extern void swedish_ISO_8859_1_close_env(struct SN_env * z); + +extern int swedish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.c new file mode 100644 index 00000000000..0a68a3bc6f1 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.c @@ -0,0 +1,701 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int russian_KOI8_R_stem(struct SN_env * z); +static int r_tidy_up(struct SN_env * z); +static int r_derivational(struct SN_env * z); +static int r_noun(struct SN_env * z); +static int r_verb(struct SN_env * z); +static int r_reflexive(struct SN_env * z); +static int r_adjectival(struct SN_env * z); +static int r_adjective(struct SN_env * z); +static int r_perfective_gerund(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * russian_KOI8_R_create_env(void); +extern void russian_KOI8_R_close_env(struct SN_env * z); + +static symbol s_0_0[3] = { 0xD7, 0xDB, 0xC9 }; +static symbol s_0_1[4] = { 0xC9, 0xD7, 0xDB, 0xC9 }; +static symbol s_0_2[4] = { 0xD9, 0xD7, 0xDB, 0xC9 }; +static symbol s_0_3[1] = { 0xD7 }; +static symbol s_0_4[2] = { 0xC9, 0xD7 }; +static symbol s_0_5[2] = { 0xD9, 0xD7 }; +static symbol s_0_6[5] = { 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 }; +static symbol s_0_7[6] = { 0xC9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 }; +static symbol s_0_8[6] = { 0xD9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 }; + +static struct among a_0[9] = +{ +/* 0 */ { 3, s_0_0, -1, 1, 0}, +/* 1 */ { 4, s_0_1, 0, 2, 0}, +/* 2 */ { 4, s_0_2, 0, 2, 0}, +/* 3 */ { 1, s_0_3, -1, 1, 0}, +/* 4 */ { 2, s_0_4, 3, 2, 0}, +/* 5 */ { 2, s_0_5, 3, 2, 0}, +/* 6 */ { 5, s_0_6, -1, 1, 0}, +/* 7 */ { 6, s_0_7, 6, 2, 0}, +/* 8 */ { 6, s_0_8, 6, 2, 0} +}; + +static symbol s_1_0[2] = { 0xC0, 0xC0 }; +static symbol s_1_1[2] = { 0xC5, 0xC0 }; +static symbol s_1_2[2] = { 0xCF, 0xC0 }; +static symbol s_1_3[2] = { 0xD5, 0xC0 }; +static symbol s_1_4[2] = { 0xC5, 0xC5 }; +static symbol s_1_5[2] = { 0xC9, 0xC5 }; +static symbol s_1_6[2] = { 0xCF, 0xC5 }; +static symbol s_1_7[2] = { 0xD9, 0xC5 }; +static symbol s_1_8[2] = { 0xC9, 0xC8 }; +static symbol s_1_9[2] = { 0xD9, 0xC8 }; +static symbol s_1_10[3] = { 0xC9, 0xCD, 0xC9 }; +static symbol s_1_11[3] = { 0xD9, 0xCD, 0xC9 }; +static symbol s_1_12[2] = { 0xC5, 0xCA }; +static symbol s_1_13[2] = { 0xC9, 0xCA }; +static symbol s_1_14[2] = { 0xCF, 0xCA }; +static symbol s_1_15[2] = { 0xD9, 0xCA }; +static symbol s_1_16[2] = { 0xC5, 0xCD }; +static symbol s_1_17[2] = { 0xC9, 0xCD }; +static symbol s_1_18[2] = { 0xCF, 0xCD }; +static symbol s_1_19[2] = { 0xD9, 0xCD }; +static symbol s_1_20[3] = { 0xC5, 0xC7, 0xCF }; +static symbol s_1_21[3] = { 0xCF, 0xC7, 0xCF }; +static symbol s_1_22[2] = { 0xC1, 0xD1 }; +static symbol s_1_23[2] = { 0xD1, 0xD1 }; +static symbol s_1_24[3] = { 0xC5, 0xCD, 0xD5 }; +static symbol s_1_25[3] = { 0xCF, 0xCD, 0xD5 }; + +static struct among a_1[26] = +{ +/* 0 */ { 2, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 3 */ { 2, s_1_3, -1, 1, 0}, +/* 4 */ { 2, s_1_4, -1, 1, 0}, +/* 5 */ { 2, s_1_5, -1, 1, 0}, +/* 6 */ { 2, s_1_6, -1, 1, 0}, +/* 7 */ { 2, s_1_7, -1, 1, 0}, +/* 8 */ { 2, s_1_8, -1, 1, 0}, +/* 9 */ { 2, s_1_9, -1, 1, 0}, +/* 10 */ { 3, s_1_10, -1, 1, 0}, +/* 11 */ { 3, s_1_11, -1, 1, 0}, +/* 12 */ { 2, s_1_12, -1, 1, 0}, +/* 13 */ { 2, s_1_13, -1, 1, 0}, +/* 14 */ { 2, s_1_14, -1, 1, 0}, +/* 15 */ { 2, s_1_15, -1, 1, 0}, +/* 16 */ { 2, s_1_16, -1, 1, 0}, +/* 17 */ { 2, s_1_17, -1, 1, 0}, +/* 18 */ { 2, s_1_18, -1, 1, 0}, +/* 19 */ { 2, s_1_19, -1, 1, 0}, +/* 20 */ { 3, s_1_20, -1, 1, 0}, +/* 21 */ { 3, s_1_21, -1, 1, 0}, +/* 22 */ { 2, s_1_22, -1, 1, 0}, +/* 23 */ { 2, s_1_23, -1, 1, 0}, +/* 24 */ { 3, s_1_24, -1, 1, 0}, +/* 25 */ { 3, s_1_25, -1, 1, 0} +}; + +static symbol s_2_0[2] = { 0xC5, 0xCD }; +static symbol s_2_1[2] = { 0xCE, 0xCE }; +static symbol s_2_2[2] = { 0xD7, 0xDB }; +static symbol s_2_3[3] = { 0xC9, 0xD7, 0xDB }; +static symbol s_2_4[3] = { 0xD9, 0xD7, 0xDB }; +static symbol s_2_5[1] = { 0xDD }; +static symbol s_2_6[2] = { 0xC0, 0xDD }; +static symbol s_2_7[3] = { 0xD5, 0xC0, 0xDD }; + +static struct among a_2[8] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 2, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 1, 0}, +/* 3 */ { 3, s_2_3, 2, 2, 0}, +/* 4 */ { 3, s_2_4, 2, 2, 0}, +/* 5 */ { 1, s_2_5, -1, 1, 0}, +/* 6 */ { 2, s_2_6, 5, 1, 0}, +/* 7 */ { 3, s_2_7, 6, 2, 0} +}; + +static symbol s_3_0[2] = { 0xD3, 0xD1 }; +static symbol s_3_1[2] = { 0xD3, 0xD8 }; + +static struct among a_3[2] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 2, s_3_1, -1, 1, 0} +}; + +static symbol s_4_0[1] = { 0xC0 }; +static symbol s_4_1[2] = { 0xD5, 0xC0 }; +static symbol s_4_2[2] = { 0xCC, 0xC1 }; +static symbol s_4_3[3] = { 0xC9, 0xCC, 0xC1 }; +static symbol s_4_4[3] = { 0xD9, 0xCC, 0xC1 }; +static symbol s_4_5[2] = { 0xCE, 0xC1 }; +static symbol s_4_6[3] = { 0xC5, 0xCE, 0xC1 }; +static symbol s_4_7[3] = { 0xC5, 0xD4, 0xC5 }; +static symbol s_4_8[3] = { 0xC9, 0xD4, 0xC5 }; +static symbol s_4_9[3] = { 0xCA, 0xD4, 0xC5 }; +static symbol s_4_10[4] = { 0xC5, 0xCA, 0xD4, 0xC5 }; +static symbol s_4_11[4] = { 0xD5, 0xCA, 0xD4, 0xC5 }; +static symbol s_4_12[2] = { 0xCC, 0xC9 }; +static symbol s_4_13[3] = { 0xC9, 0xCC, 0xC9 }; +static symbol s_4_14[3] = { 0xD9, 0xCC, 0xC9 }; +static symbol s_4_15[1] = { 0xCA }; +static symbol s_4_16[2] = { 0xC5, 0xCA }; +static symbol s_4_17[2] = { 0xD5, 0xCA }; +static symbol s_4_18[1] = { 0xCC }; +static symbol s_4_19[2] = { 0xC9, 0xCC }; +static symbol s_4_20[2] = { 0xD9, 0xCC }; +static symbol s_4_21[2] = { 0xC5, 0xCD }; +static symbol s_4_22[2] = { 0xC9, 0xCD }; +static symbol s_4_23[2] = { 0xD9, 0xCD }; +static symbol s_4_24[1] = { 0xCE }; +static symbol s_4_25[2] = { 0xC5, 0xCE }; +static symbol s_4_26[2] = { 0xCC, 0xCF }; +static symbol s_4_27[3] = { 0xC9, 0xCC, 0xCF }; +static symbol s_4_28[3] = { 0xD9, 0xCC, 0xCF }; +static symbol s_4_29[2] = { 0xCE, 0xCF }; +static symbol s_4_30[3] = { 0xC5, 0xCE, 0xCF }; +static symbol s_4_31[3] = { 0xCE, 0xCE, 0xCF }; +static symbol s_4_32[2] = { 0xC0, 0xD4 }; +static symbol s_4_33[3] = { 0xD5, 0xC0, 0xD4 }; +static symbol s_4_34[2] = { 0xC5, 0xD4 }; +static symbol s_4_35[3] = { 0xD5, 0xC5, 0xD4 }; +static symbol s_4_36[2] = { 0xC9, 0xD4 }; +static symbol s_4_37[2] = { 0xD1, 0xD4 }; +static symbol s_4_38[2] = { 0xD9, 0xD4 }; +static symbol s_4_39[2] = { 0xD4, 0xD8 }; +static symbol s_4_40[3] = { 0xC9, 0xD4, 0xD8 }; +static symbol s_4_41[3] = { 0xD9, 0xD4, 0xD8 }; +static symbol s_4_42[3] = { 0xC5, 0xDB, 0xD8 }; +static symbol s_4_43[3] = { 0xC9, 0xDB, 0xD8 }; +static symbol s_4_44[2] = { 0xCE, 0xD9 }; +static symbol s_4_45[3] = { 0xC5, 0xCE, 0xD9 }; + +static struct among a_4[46] = +{ +/* 0 */ { 1, s_4_0, -1, 2, 0}, +/* 1 */ { 2, s_4_1, 0, 2, 0}, +/* 2 */ { 2, s_4_2, -1, 1, 0}, +/* 3 */ { 3, s_4_3, 2, 2, 0}, +/* 4 */ { 3, s_4_4, 2, 2, 0}, +/* 5 */ { 2, s_4_5, -1, 1, 0}, +/* 6 */ { 3, s_4_6, 5, 2, 0}, +/* 7 */ { 3, s_4_7, -1, 1, 0}, +/* 8 */ { 3, s_4_8, -1, 2, 0}, +/* 9 */ { 3, s_4_9, -1, 1, 0}, +/* 10 */ { 4, s_4_10, 9, 2, 0}, +/* 11 */ { 4, s_4_11, 9, 2, 0}, +/* 12 */ { 2, s_4_12, -1, 1, 0}, +/* 13 */ { 3, s_4_13, 12, 2, 0}, +/* 14 */ { 3, s_4_14, 12, 2, 0}, +/* 15 */ { 1, s_4_15, -1, 1, 0}, +/* 16 */ { 2, s_4_16, 15, 2, 0}, +/* 17 */ { 2, s_4_17, 15, 2, 0}, +/* 18 */ { 1, s_4_18, -1, 1, 0}, +/* 19 */ { 2, s_4_19, 18, 2, 0}, +/* 20 */ { 2, s_4_20, 18, 2, 0}, +/* 21 */ { 2, s_4_21, -1, 1, 0}, +/* 22 */ { 2, s_4_22, -1, 2, 0}, +/* 23 */ { 2, s_4_23, -1, 2, 0}, +/* 24 */ { 1, s_4_24, -1, 1, 0}, +/* 25 */ { 2, s_4_25, 24, 2, 0}, +/* 26 */ { 2, s_4_26, -1, 1, 0}, +/* 27 */ { 3, s_4_27, 26, 2, 0}, +/* 28 */ { 3, s_4_28, 26, 2, 0}, +/* 29 */ { 2, s_4_29, -1, 1, 0}, +/* 30 */ { 3, s_4_30, 29, 2, 0}, +/* 31 */ { 3, s_4_31, 29, 1, 0}, +/* 32 */ { 2, s_4_32, -1, 1, 0}, +/* 33 */ { 3, s_4_33, 32, 2, 0}, +/* 34 */ { 2, s_4_34, -1, 1, 0}, +/* 35 */ { 3, s_4_35, 34, 2, 0}, +/* 36 */ { 2, s_4_36, -1, 2, 0}, +/* 37 */ { 2, s_4_37, -1, 2, 0}, +/* 38 */ { 2, s_4_38, -1, 2, 0}, +/* 39 */ { 2, s_4_39, -1, 1, 0}, +/* 40 */ { 3, s_4_40, 39, 2, 0}, +/* 41 */ { 3, s_4_41, 39, 2, 0}, +/* 42 */ { 3, s_4_42, -1, 1, 0}, +/* 43 */ { 3, s_4_43, -1, 2, 0}, +/* 44 */ { 2, s_4_44, -1, 1, 0}, +/* 45 */ { 3, s_4_45, 44, 2, 0} +}; + +static symbol s_5_0[1] = { 0xC0 }; +static symbol s_5_1[2] = { 0xC9, 0xC0 }; +static symbol s_5_2[2] = { 0xD8, 0xC0 }; +static symbol s_5_3[1] = { 0xC1 }; +static symbol s_5_4[1] = { 0xC5 }; +static symbol s_5_5[2] = { 0xC9, 0xC5 }; +static symbol s_5_6[2] = { 0xD8, 0xC5 }; +static symbol s_5_7[2] = { 0xC1, 0xC8 }; +static symbol s_5_8[2] = { 0xD1, 0xC8 }; +static symbol s_5_9[3] = { 0xC9, 0xD1, 0xC8 }; +static symbol s_5_10[1] = { 0xC9 }; +static symbol s_5_11[2] = { 0xC5, 0xC9 }; +static symbol s_5_12[2] = { 0xC9, 0xC9 }; +static symbol s_5_13[3] = { 0xC1, 0xCD, 0xC9 }; +static symbol s_5_14[3] = { 0xD1, 0xCD, 0xC9 }; +static symbol s_5_15[4] = { 0xC9, 0xD1, 0xCD, 0xC9 }; +static symbol s_5_16[1] = { 0xCA }; +static symbol s_5_17[2] = { 0xC5, 0xCA }; +static symbol s_5_18[3] = { 0xC9, 0xC5, 0xCA }; +static symbol s_5_19[2] = { 0xC9, 0xCA }; +static symbol s_5_20[2] = { 0xCF, 0xCA }; +static symbol s_5_21[2] = { 0xC1, 0xCD }; +static symbol s_5_22[2] = { 0xC5, 0xCD }; +static symbol s_5_23[3] = { 0xC9, 0xC5, 0xCD }; +static symbol s_5_24[2] = { 0xCF, 0xCD }; +static symbol s_5_25[2] = { 0xD1, 0xCD }; +static symbol s_5_26[3] = { 0xC9, 0xD1, 0xCD }; +static symbol s_5_27[1] = { 0xCF }; +static symbol s_5_28[1] = { 0xD1 }; +static symbol s_5_29[2] = { 0xC9, 0xD1 }; +static symbol s_5_30[2] = { 0xD8, 0xD1 }; +static symbol s_5_31[1] = { 0xD5 }; +static symbol s_5_32[2] = { 0xC5, 0xD7 }; +static symbol s_5_33[2] = { 0xCF, 0xD7 }; +static symbol s_5_34[1] = { 0xD8 }; +static symbol s_5_35[1] = { 0xD9 }; + +static struct among a_5[36] = +{ +/* 0 */ { 1, s_5_0, -1, 1, 0}, +/* 1 */ { 2, s_5_1, 0, 1, 0}, +/* 2 */ { 2, s_5_2, 0, 1, 0}, +/* 3 */ { 1, s_5_3, -1, 1, 0}, +/* 4 */ { 1, s_5_4, -1, 1, 0}, +/* 5 */ { 2, s_5_5, 4, 1, 0}, +/* 6 */ { 2, s_5_6, 4, 1, 0}, +/* 7 */ { 2, s_5_7, -1, 1, 0}, +/* 8 */ { 2, s_5_8, -1, 1, 0}, +/* 9 */ { 3, s_5_9, 8, 1, 0}, +/* 10 */ { 1, s_5_10, -1, 1, 0}, +/* 11 */ { 2, s_5_11, 10, 1, 0}, +/* 12 */ { 2, s_5_12, 10, 1, 0}, +/* 13 */ { 3, s_5_13, 10, 1, 0}, +/* 14 */ { 3, s_5_14, 10, 1, 0}, +/* 15 */ { 4, s_5_15, 14, 1, 0}, +/* 16 */ { 1, s_5_16, -1, 1, 0}, +/* 17 */ { 2, s_5_17, 16, 1, 0}, +/* 18 */ { 3, s_5_18, 17, 1, 0}, +/* 19 */ { 2, s_5_19, 16, 1, 0}, +/* 20 */ { 2, s_5_20, 16, 1, 0}, +/* 21 */ { 2, s_5_21, -1, 1, 0}, +/* 22 */ { 2, s_5_22, -1, 1, 0}, +/* 23 */ { 3, s_5_23, 22, 1, 0}, +/* 24 */ { 2, s_5_24, -1, 1, 0}, +/* 25 */ { 2, s_5_25, -1, 1, 0}, +/* 26 */ { 3, s_5_26, 25, 1, 0}, +/* 27 */ { 1, s_5_27, -1, 1, 0}, +/* 28 */ { 1, s_5_28, -1, 1, 0}, +/* 29 */ { 2, s_5_29, 28, 1, 0}, +/* 30 */ { 2, s_5_30, 28, 1, 0}, +/* 31 */ { 1, s_5_31, -1, 1, 0}, +/* 32 */ { 2, s_5_32, -1, 1, 0}, +/* 33 */ { 2, s_5_33, -1, 1, 0}, +/* 34 */ { 1, s_5_34, -1, 1, 0}, +/* 35 */ { 1, s_5_35, -1, 1, 0} +}; + +static symbol s_6_0[3] = { 0xCF, 0xD3, 0xD4 }; +static symbol s_6_1[4] = { 0xCF, 0xD3, 0xD4, 0xD8 }; + +static struct among a_6[2] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 4, s_6_1, -1, 1, 0} +}; + +static symbol s_7_0[4] = { 0xC5, 0xCA, 0xDB, 0xC5 }; +static symbol s_7_1[1] = { 0xCE }; +static symbol s_7_2[1] = { 0xD8 }; +static symbol s_7_3[3] = { 0xC5, 0xCA, 0xDB }; + +static struct among a_7[4] = +{ +/* 0 */ { 4, s_7_0, -1, 1, 0}, +/* 1 */ { 1, s_7_1, -1, 2, 0}, +/* 2 */ { 1, s_7_2, -1, 3, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0} +}; + +static unsigned char g_v[] = { 35, 130, 34, 18 }; + +static symbol s_0[] = { 0xC1 }; +static symbol s_1[] = { 0xD1 }; +static symbol s_2[] = { 0xC1 }; +static symbol s_3[] = { 0xD1 }; +static symbol s_4[] = { 0xC1 }; +static symbol s_5[] = { 0xD1 }; +static symbol s_6[] = { 0xCE }; +static symbol s_7[] = { 0xCE }; +static symbol s_8[] = { 0xCE }; +static symbol s_9[] = { 0xC9 }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 63 */ + while(1) { /* gopast, line 64 */ + if (!(in_grouping(z, g_v, 192, 220))) goto lab1; + break; + lab1: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 64 */ + } + z->I[0] = z->c; /* setmark pV, line 64 */ + while(1) { /* gopast, line 64 */ + if (!(out_grouping(z, g_v, 192, 220))) goto lab2; + break; + lab2: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 64 */ + } + while(1) { /* gopast, line 65 */ + if (!(in_grouping(z, g_v, 192, 220))) goto lab3; + break; + lab3: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 65 */ + } + while(1) { /* gopast, line 65 */ + if (!(out_grouping(z, g_v, 192, 220))) goto lab4; + break; + lab4: + if (z->c >= z->l) goto lab0; + z->c++; /* gopast, line 65 */ + } + z->I[1] = z->c; /* setmark p2, line 65 */ + lab0: + z->c = c; + } + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_perfective_gerund(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 74 */ + among_var = find_among_b(z, a_0, 9); /* substring, line 74 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 74 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 78 */ + if (!(eq_s_b(z, 1, s_0))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_1))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 78 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 85 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_adjective(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 90 */ + among_var = find_among_b(z, a_1, 26); /* substring, line 90 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 90 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 99 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_adjectival(struct SN_env * z) { + int among_var; + { int ret = r_adjective(z); + if (ret == 0) return 0; /* call adjective, line 104 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_2, 8); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 112 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + { int m = z->l - z->c; (void) m; /* or, line 117 */ + if (!(eq_s_b(z, 1, s_2))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_3))) { z->c = z->l - m; goto lab0; } + } + lab1: + { int ret; + ret = slice_del(z); /* delete, line 117 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 124 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + return 1; +} + +static int r_reflexive(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 131 */ + among_var = find_among_b(z, a_3, 2); /* substring, line 131 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 131 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 139 */ + among_var = find_among_b(z, a_4, 46); /* substring, line 139 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 139 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 145 */ + if (!(eq_s_b(z, 1, s_4))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_5))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 145 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 153 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_noun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 162 */ + among_var = find_among_b(z, a_5, 36); /* substring, line 162 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 162 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 169 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_derivational(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 178 */ + among_var = find_among_b(z, a_6, 2); /* substring, line 178 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 178 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 178 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 181 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_tidy_up(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 186 */ + among_var = find_among_b(z, a_7, 4); /* substring, line 186 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 186 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 190 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 191 */ + if (!(eq_s_b(z, 1, s_6))) return 0; + z->bra = z->c; /* ], line 191 */ + if (!(eq_s_b(z, 1, s_7))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 191 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(eq_s_b(z, 1, s_8))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 194 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 196 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int russian_KOI8_R_stem(struct SN_env * z) { + { int c = z->c; /* do, line 203 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 203 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + + { int m3; /* setlimit, line 204 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 204 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 205 */ + { int m = z->l - z->c; (void) m; /* or, line 206 */ + { int ret = r_perfective_gerund(z); + if (ret == 0) goto lab3; /* call perfective_gerund, line 206 */ + if (ret < 0) return ret; + } + goto lab2; + lab3: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* try, line 207 */ + { int ret = r_reflexive(z); + if (ret == 0) { z->c = z->l - m; goto lab4; } /* call reflexive, line 207 */ + if (ret < 0) return ret; + } + lab4: + ; + } + { int m = z->l - z->c; (void) m; /* or, line 208 */ + { int ret = r_adjectival(z); + if (ret == 0) goto lab6; /* call adjectival, line 208 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_verb(z); + if (ret == 0) goto lab7; /* call verb, line 208 */ + if (ret < 0) return ret; + } + goto lab5; + lab7: + z->c = z->l - m; + { int ret = r_noun(z); + if (ret == 0) goto lab1; /* call noun, line 208 */ + if (ret < 0) return ret; + } + } + lab5: + ; + } + lab2: + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* try, line 211 */ + z->ket = z->c; /* [, line 211 */ + if (!(eq_s_b(z, 1, s_9))) { z->c = z->l - m; goto lab8; } + z->bra = z->c; /* ], line 211 */ + { int ret; + ret = slice_del(z); /* delete, line 211 */ + if (ret < 0) return ret; + } + lab8: + ; + } + { int m = z->l - z->c; (void) m; /* do, line 214 */ + { int ret = r_derivational(z); + if (ret == 0) goto lab9; /* call derivational, line 214 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 215 */ + { int ret = r_tidy_up(z); + if (ret == 0) goto lab10; /* call tidy_up, line 215 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + z->lb = m3; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * russian_KOI8_R_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void russian_KOI8_R_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.h new file mode 100644 index 00000000000..de2179d29f0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_KOI8_R_russian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * russian_KOI8_R_create_env(void); +extern void russian_KOI8_R_close_env(struct SN_env * z); + +extern int russian_KOI8_R_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.c new file mode 100644 index 00000000000..bb98298acd4 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.c @@ -0,0 +1,344 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int danish_UTF_8_stem(struct SN_env * z); +static int r_undouble(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * danish_UTF_8_create_env(void); +extern void danish_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[3] = { 'h', 'e', 'd' }; +static symbol s_0_1[5] = { 'e', 't', 'h', 'e', 'd' }; +static symbol s_0_2[4] = { 'e', 'r', 'e', 'd' }; +static symbol s_0_3[1] = { 'e' }; +static symbol s_0_4[5] = { 'e', 'r', 'e', 'd', 'e' }; +static symbol s_0_5[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_0_6[6] = { 'e', 'r', 'e', 'n', 'd', 'e' }; +static symbol s_0_7[3] = { 'e', 'n', 'e' }; +static symbol s_0_8[4] = { 'e', 'r', 'n', 'e' }; +static symbol s_0_9[3] = { 'e', 'r', 'e' }; +static symbol s_0_10[2] = { 'e', 'n' }; +static symbol s_0_11[5] = { 'h', 'e', 'd', 'e', 'n' }; +static symbol s_0_12[4] = { 'e', 'r', 'e', 'n' }; +static symbol s_0_13[2] = { 'e', 'r' }; +static symbol s_0_14[5] = { 'h', 'e', 'd', 'e', 'r' }; +static symbol s_0_15[4] = { 'e', 'r', 'e', 'r' }; +static symbol s_0_16[1] = { 's' }; +static symbol s_0_17[4] = { 'h', 'e', 'd', 's' }; +static symbol s_0_18[2] = { 'e', 's' }; +static symbol s_0_19[5] = { 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_20[7] = { 'e', 'r', 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_21[4] = { 'e', 'n', 'e', 's' }; +static symbol s_0_22[5] = { 'e', 'r', 'n', 'e', 's' }; +static symbol s_0_23[4] = { 'e', 'r', 'e', 's' }; +static symbol s_0_24[3] = { 'e', 'n', 's' }; +static symbol s_0_25[6] = { 'h', 'e', 'd', 'e', 'n', 's' }; +static symbol s_0_26[5] = { 'e', 'r', 'e', 'n', 's' }; +static symbol s_0_27[3] = { 'e', 'r', 's' }; +static symbol s_0_28[3] = { 'e', 't', 's' }; +static symbol s_0_29[5] = { 'e', 'r', 'e', 't', 's' }; +static symbol s_0_30[2] = { 'e', 't' }; +static symbol s_0_31[4] = { 'e', 'r', 'e', 't' }; + +static struct among a_0[32] = +{ +/* 0 */ { 3, s_0_0, -1, 1, 0}, +/* 1 */ { 5, s_0_1, 0, 1, 0}, +/* 2 */ { 4, s_0_2, -1, 1, 0}, +/* 3 */ { 1, s_0_3, -1, 1, 0}, +/* 4 */ { 5, s_0_4, 3, 1, 0}, +/* 5 */ { 4, s_0_5, 3, 1, 0}, +/* 6 */ { 6, s_0_6, 5, 1, 0}, +/* 7 */ { 3, s_0_7, 3, 1, 0}, +/* 8 */ { 4, s_0_8, 3, 1, 0}, +/* 9 */ { 3, s_0_9, 3, 1, 0}, +/* 10 */ { 2, s_0_10, -1, 1, 0}, +/* 11 */ { 5, s_0_11, 10, 1, 0}, +/* 12 */ { 4, s_0_12, 10, 1, 0}, +/* 13 */ { 2, s_0_13, -1, 1, 0}, +/* 14 */ { 5, s_0_14, 13, 1, 0}, +/* 15 */ { 4, s_0_15, 13, 1, 0}, +/* 16 */ { 1, s_0_16, -1, 2, 0}, +/* 17 */ { 4, s_0_17, 16, 1, 0}, +/* 18 */ { 2, s_0_18, 16, 1, 0}, +/* 19 */ { 5, s_0_19, 18, 1, 0}, +/* 20 */ { 7, s_0_20, 19, 1, 0}, +/* 21 */ { 4, s_0_21, 18, 1, 0}, +/* 22 */ { 5, s_0_22, 18, 1, 0}, +/* 23 */ { 4, s_0_23, 18, 1, 0}, +/* 24 */ { 3, s_0_24, 16, 1, 0}, +/* 25 */ { 6, s_0_25, 24, 1, 0}, +/* 26 */ { 5, s_0_26, 24, 1, 0}, +/* 27 */ { 3, s_0_27, 16, 1, 0}, +/* 28 */ { 3, s_0_28, 16, 1, 0}, +/* 29 */ { 5, s_0_29, 28, 1, 0}, +/* 30 */ { 2, s_0_30, -1, 1, 0}, +/* 31 */ { 4, s_0_31, 30, 1, 0} +}; + +static symbol s_1_0[2] = { 'g', 'd' }; +static symbol s_1_1[2] = { 'd', 't' }; +static symbol s_1_2[2] = { 'g', 't' }; +static symbol s_1_3[2] = { 'k', 't' }; + +static struct among a_1[4] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'g' }; +static symbol s_2_1[3] = { 'l', 'i', 'g' }; +static symbol s_2_2[4] = { 'e', 'l', 'i', 'g' }; +static symbol s_2_3[3] = { 'e', 'l', 's' }; +static symbol s_2_4[5] = { 'l', 0xC3, 0xB8, 's', 't' }; + +static struct among a_2[5] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 4, s_2_2, 1, 1, 0}, +/* 3 */ { 3, s_2_3, -1, 1, 0}, +/* 4 */ { 5, s_2_4, -1, 2, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; + +static unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }; + +static symbol s_0[] = { 's', 't' }; +static symbol s_1[] = { 'i', 'g' }; +static symbol s_2[] = { 'l', 0xC3, 0xB8, 's' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 33 */ + { int c = skip_utf8(z->p, z->c, 0, z->l, + 3); + if (c < 0) return 0; + z->c = c; /* hop, line 33 */ + } + z->I[1] = z->c; /* setmark x, line 33 */ + z->c = c_test; + } + while(1) { /* goto, line 34 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 248))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* goto, line 34 */ + } + } + while(1) { /* gopast, line 34 */ + if (!(out_grouping_U(z, g_v, 97, 248))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 34 */ + } + } + z->I[0] = z->c; /* setmark p1, line 34 */ + /* try, line 35 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 41 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 41 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 41 */ + among_var = find_among_b(z, a_0, 32); /* substring, line 41 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 41 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 48 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b_U(z, g_s_ending, 97, 229))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 50 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 55 */ + { int m3; /* setlimit, line 56 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 56 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 56 */ + if (!(find_among_b(z, a_1, 4))) { z->lb = m3; return 0; } /* substring, line 56 */ + z->bra = z->c; /* ], line 56 */ + z->lb = m3; + } + z->c = z->l - m_test; + } + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 62 */ + } + z->bra = z->c; /* ], line 62 */ + { int ret; + ret = slice_del(z); /* delete, line 62 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 66 */ + z->ket = z->c; /* [, line 66 */ + if (!(eq_s_b(z, 2, s_0))) goto lab0; + z->bra = z->c; /* ], line 66 */ + if (!(eq_s_b(z, 2, s_1))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 66 */ + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m; + } + { int m3; /* setlimit, line 67 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 67 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 67 */ + among_var = find_among_b(z, a_2, 5); /* substring, line 67 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 67 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 70 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* do, line 70 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab1; /* call consonant_pair, line 70 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_2); /* <-, line 72 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_undouble(struct SN_env * z) { + { int m3; /* setlimit, line 76 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 76 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 76 */ + if (!(out_grouping_b_U(z, g_v, 97, 248))) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 76 */ + z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */ + if (z->S[0] == 0) return -1; /* -> ch, line 76 */ + z->lb = m3; + } + if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */ + { int ret; + ret = slice_del(z); /* delete, line 78 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int danish_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 84 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 84 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 85 */ + + { int m = z->l - z->c; (void) m; /* do, line 86 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 86 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 87 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 87 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 88 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 88 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 89 */ + { int ret = r_undouble(z); + if (ret == 0) goto lab4; /* call undouble, line 89 */ + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * danish_UTF_8_create_env(void) { return SN_create_env(1, 2, 0); } + +extern void danish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.h new file mode 100644 index 00000000000..ed744d454f0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_danish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * danish_UTF_8_create_env(void); +extern void danish_UTF_8_close_env(struct SN_env * z); + +extern int danish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.c new file mode 100644 index 00000000000..3de469b5233 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.c @@ -0,0 +1,653 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int dutch_UTF_8_stem(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_undouble(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_en_ending(struct SN_env * z); +static int r_e_ending(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * dutch_UTF_8_create_env(void); +extern void dutch_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[2] = { 0xC3, 0xA1 }; +static symbol s_0_2[2] = { 0xC3, 0xA4 }; +static symbol s_0_3[2] = { 0xC3, 0xA9 }; +static symbol s_0_4[2] = { 0xC3, 0xAB }; +static symbol s_0_5[2] = { 0xC3, 0xAD }; +static symbol s_0_6[2] = { 0xC3, 0xAF }; +static symbol s_0_7[2] = { 0xC3, 0xB3 }; +static symbol s_0_8[2] = { 0xC3, 0xB6 }; +static symbol s_0_9[2] = { 0xC3, 0xBA }; +static symbol s_0_10[2] = { 0xC3, 0xBC }; + +static struct among a_0[11] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 2, s_0_1, 0, 1, 0}, +/* 2 */ { 2, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, 2, 0}, +/* 4 */ { 2, s_0_4, 0, 2, 0}, +/* 5 */ { 2, s_0_5, 0, 3, 0}, +/* 6 */ { 2, s_0_6, 0, 3, 0}, +/* 7 */ { 2, s_0_7, 0, 4, 0}, +/* 8 */ { 2, s_0_8, 0, 4, 0}, +/* 9 */ { 2, s_0_9, 0, 5, 0}, +/* 10 */ { 2, s_0_10, 0, 5, 0} +}; + +static symbol s_1_1[1] = { 'I' }; +static symbol s_1_2[1] = { 'Y' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 1, s_1_1, 0, 2, 0}, +/* 2 */ { 1, s_1_2, 0, 1, 0} +}; + +static symbol s_2_0[2] = { 'd', 'd' }; +static symbol s_2_1[2] = { 'k', 'k' }; +static symbol s_2_2[2] = { 't', 't' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 2, s_2_1, -1, -1, 0}, +/* 2 */ { 2, s_2_2, -1, -1, 0} +}; + +static symbol s_3_0[3] = { 'e', 'n', 'e' }; +static symbol s_3_1[2] = { 's', 'e' }; +static symbol s_3_2[2] = { 'e', 'n' }; +static symbol s_3_3[5] = { 'h', 'e', 'd', 'e', 'n' }; +static symbol s_3_4[1] = { 's' }; + +static struct among a_3[5] = +{ +/* 0 */ { 3, s_3_0, -1, 2, 0}, +/* 1 */ { 2, s_3_1, -1, 3, 0}, +/* 2 */ { 2, s_3_2, -1, 2, 0}, +/* 3 */ { 5, s_3_3, 2, 1, 0}, +/* 4 */ { 1, s_3_4, -1, 3, 0} +}; + +static symbol s_4_0[3] = { 'e', 'n', 'd' }; +static symbol s_4_1[2] = { 'i', 'g' }; +static symbol s_4_2[3] = { 'i', 'n', 'g' }; +static symbol s_4_3[4] = { 'l', 'i', 'j', 'k' }; +static symbol s_4_4[4] = { 'b', 'a', 'a', 'r' }; +static symbol s_4_5[3] = { 'b', 'a', 'r' }; + +static struct among a_4[6] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 2, 0}, +/* 2 */ { 3, s_4_2, -1, 1, 0}, +/* 3 */ { 4, s_4_3, -1, 3, 0}, +/* 4 */ { 4, s_4_4, -1, 4, 0}, +/* 5 */ { 3, s_4_5, -1, 5, 0} +}; + +static symbol s_5_0[2] = { 'a', 'a' }; +static symbol s_5_1[2] = { 'e', 'e' }; +static symbol s_5_2[2] = { 'o', 'o' }; +static symbol s_5_3[2] = { 'u', 'u' }; + +static struct among a_5[4] = +{ +/* 0 */ { 2, s_5_0, -1, -1, 0}, +/* 1 */ { 2, s_5_1, -1, -1, 0}, +/* 2 */ { 2, s_5_2, -1, -1, 0}, +/* 3 */ { 2, s_5_3, -1, -1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static unsigned char g_v_I[] = { 1, 0, 0, 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static unsigned char g_v_j[] = { 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static symbol s_0[] = { 'a' }; +static symbol s_1[] = { 'e' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'o' }; +static symbol s_4[] = { 'u' }; +static symbol s_5[] = { 'y' }; +static symbol s_6[] = { 'Y' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 'I' }; +static symbol s_9[] = { 'y' }; +static symbol s_10[] = { 'Y' }; +static symbol s_11[] = { 'y' }; +static symbol s_12[] = { 'i' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'g', 'e', 'm' }; +static symbol s_15[] = { 'h', 'e', 'i', 'd' }; +static symbol s_16[] = { 'h', 'e', 'i', 'd' }; +static symbol s_17[] = { 'c' }; +static symbol s_18[] = { 'e', 'n' }; +static symbol s_19[] = { 'i', 'g' }; +static symbol s_20[] = { 'e' }; +static symbol s_21[] = { 'e' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + { int c_test = z->c; /* test, line 42 */ + while(1) { /* repeat, line 42 */ + int c = z->c; + z->bra = z->c; /* [, line 43 */ + among_var = find_among(z, a_0, 11); /* substring, line 43 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 43 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 47 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 49 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 51 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 53 */ + if (ret < 0) return ret; + } + break; + case 6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 54 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + { int c = z->c; /* try, line 57 */ + z->bra = z->c; /* [, line 57 */ + if (!(eq_s(z, 1, s_5))) { z->c = c; goto lab1; } + z->ket = z->c; /* ], line 57 */ + { int ret; + ret = slice_from_s(z, 1, s_6); /* <-, line 57 */ + if (ret < 0) return ret; + } + lab1: + ; + } + while(1) { /* repeat, line 58 */ + int c = z->c; + while(1) { /* goto, line 58 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 232))) goto lab3; + z->bra = z->c; /* [, line 59 */ + { int c = z->c; /* or, line 59 */ + if (!(eq_s(z, 1, s_7))) goto lab5; + z->ket = z->c; /* ], line 59 */ + if (!(in_grouping_U(z, g_v, 97, 232))) goto lab5; + { int ret; + ret = slice_from_s(z, 1, s_8); /* <-, line 59 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = c; + if (!(eq_s(z, 1, s_9))) goto lab3; + z->ket = z->c; /* ], line 60 */ + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 60 */ + if (ret < 0) return ret; + } + } + lab4: + z->c = c; + break; + lab3: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* goto, line 58 */ + } + } + continue; + lab2: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + while(1) { /* gopast, line 69 */ + if (!(in_grouping_U(z, g_v, 97, 232))) goto lab0; + break; + lab0: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 69 */ + } + } + while(1) { /* gopast, line 69 */ + if (!(out_grouping_U(z, g_v, 97, 232))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 69 */ + } + } + z->I[0] = z->c; /* setmark p1, line 69 */ + /* try, line 70 */ + if (!(z->I[0] < 3)) goto lab2; + z->I[0] = 3; +lab2: + while(1) { /* gopast, line 71 */ + if (!(in_grouping_U(z, g_v, 97, 232))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 71 */ + } + } + while(1) { /* gopast, line 71 */ + if (!(out_grouping_U(z, g_v, 97, 232))) goto lab4; + break; + lab4: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 71 */ + } + } + z->I[1] = z->c; /* setmark p2, line 71 */ + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 75 */ + int c = z->c; + z->bra = z->c; /* [, line 77 */ + among_var = find_among(z, a_1, 3); /* substring, line 77 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 77 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + if (ret < 0) return ret; + } + break; + case 3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 80 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_undouble(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 91 */ + if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */ + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 91 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 91 */ + } + z->bra = z->c; /* ], line 91 */ + { int ret; + ret = slice_del(z); /* delete, line 91 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_e_ending(struct SN_env * z) { + z->B[0] = 0; /* unset e_found, line 95 */ + z->ket = z->c; /* [, line 96 */ + if (!(eq_s_b(z, 1, s_13))) return 0; + z->bra = z->c; /* ], line 96 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 96 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 96 */ + if (!(out_grouping_b_U(z, g_v, 97, 232))) return 0; + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 96 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set e_found, line 97 */ + { int ret = r_undouble(z); + if (ret == 0) return 0; /* call undouble, line 98 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_en_ending(struct SN_env * z) { + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 102 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* and, line 102 */ + if (!(out_grouping_b_U(z, g_v, 97, 232))) return 0; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* not, line 102 */ + if (!(eq_s_b(z, 3, s_14))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + } + { int ret; + ret = slice_del(z); /* delete, line 102 */ + if (ret < 0) return ret; + } + { int ret = r_undouble(z); + if (ret == 0) return 0; /* call undouble, line 103 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 107 */ + z->ket = z->c; /* [, line 108 */ + among_var = find_among_b(z, a_3, 5); /* substring, line 108 */ + if (!(among_var)) goto lab0; + z->bra = z->c; /* ], line 108 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 110 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_15); /* <-, line 110 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_en_ending(z); + if (ret == 0) goto lab0; /* call en_ending, line 113 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 116 */ + if (ret < 0) return ret; + } + if (!(out_grouping_b_U(z, g_v_j, 97, 232))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 116 */ + if (ret < 0) return ret; + } + break; + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 120 */ + { int ret = r_e_ending(z); + if (ret == 0) goto lab1; /* call e_ending, line 120 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 122 */ + z->ket = z->c; /* [, line 122 */ + if (!(eq_s_b(z, 4, s_16))) goto lab2; + z->bra = z->c; /* ], line 122 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 122 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 122 */ + if (!(eq_s_b(z, 1, s_17))) goto lab3; + goto lab2; + lab3: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 122 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 123 */ + if (!(eq_s_b(z, 2, s_18))) goto lab2; + z->bra = z->c; /* ], line 123 */ + { int ret = r_en_ending(z); + if (ret == 0) goto lab2; /* call en_ending, line 123 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 126 */ + z->ket = z->c; /* [, line 127 */ + among_var = find_among_b(z, a_4, 6); /* substring, line 127 */ + if (!(among_var)) goto lab4; + z->bra = z->c; /* ], line 127 */ + switch(among_var) { + case 0: goto lab4; + case 1: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 129 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 129 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* or, line 130 */ + z->ket = z->c; /* [, line 130 */ + if (!(eq_s_b(z, 2, s_19))) goto lab6; + z->bra = z->c; /* ], line 130 */ + { int ret = r_R2(z); + if (ret == 0) goto lab6; /* call R2, line 130 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 130 */ + if (!(eq_s_b(z, 1, s_20))) goto lab7; + goto lab6; + lab7: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 130 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_undouble(z); + if (ret == 0) goto lab4; /* call undouble, line 130 */ + if (ret < 0) return ret; + } + } + lab5: + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 133 */ + if (!(eq_s_b(z, 1, s_21))) goto lab8; + goto lab4; + lab8: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 136 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 136 */ + if (ret < 0) return ret; + } + { int ret = r_e_ending(z); + if (ret == 0) goto lab4; /* call e_ending, line 136 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 139 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) goto lab4; /* call R2, line 142 */ + if (ret < 0) return ret; + } + if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */ + { int ret; + ret = slice_del(z); /* delete, line 142 */ + if (ret < 0) return ret; + } + break; + } + lab4: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 146 */ + if (!(out_grouping_b_U(z, g_v_I, 73, 232))) goto lab9; + { int m_test = z->l - z->c; /* test, line 148 */ + if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */ + if (!(out_grouping_b_U(z, g_v, 97, 232))) goto lab9; + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 152 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) goto lab9; + z->c = c; /* next, line 152 */ + } + z->bra = z->c; /* ], line 152 */ + { int ret; + ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + return 1; +} + +extern int dutch_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 159 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 159 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 160 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 160 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 161 */ + + { int m = z->l - z->c; (void) m; /* do, line 162 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab2; /* call standard_suffix, line 162 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 163 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab3; /* call postlude, line 163 */ + if (ret < 0) return ret; + } + lab3: + z->c = c; + } + return 1; +} + +extern struct SN_env * dutch_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void dutch_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.h new file mode 100644 index 00000000000..a99646452b0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_dutch.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * dutch_UTF_8_create_env(void); +extern void dutch_UTF_8_close_env(struct SN_env * z); + +extern int dutch_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.c new file mode 100644 index 00000000000..e825cb715a1 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.c @@ -0,0 +1,1178 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int english_UTF_8_stem(struct SN_env * z); +static int r_exception2(struct SN_env * z); +static int r_exception1(struct SN_env * z); +static int r_Step_5(struct SN_env * z); +static int r_Step_4(struct SN_env * z); +static int r_Step_3(struct SN_env * z); +static int r_Step_2(struct SN_env * z); +static int r_Step_1c(struct SN_env * z); +static int r_Step_1b(struct SN_env * z); +static int r_Step_1a(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_shortv(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * english_UTF_8_create_env(void); +extern void english_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[6] = { 'c', 'o', 'm', 'm', 'u', 'n' }; +static symbol s_0_1[5] = { 'g', 'e', 'n', 'e', 'r' }; + +static struct among a_0[2] = +{ +/* 0 */ { 6, s_0_0, -1, -1, 0}, +/* 1 */ { 5, s_0_1, -1, -1, 0} +}; + +static symbol s_1_0[1] = { '\'' }; +static symbol s_1_1[3] = { '\'', 's', '\'' }; +static symbol s_1_2[2] = { '\'', 's' }; + +static struct among a_1[3] = +{ +/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 1 */ { 3, s_1_1, 0, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0} +}; + +static symbol s_2_0[3] = { 'i', 'e', 'd' }; +static symbol s_2_1[1] = { 's' }; +static symbol s_2_2[3] = { 'i', 'e', 's' }; +static symbol s_2_3[4] = { 's', 's', 'e', 's' }; +static symbol s_2_4[2] = { 's', 's' }; +static symbol s_2_5[2] = { 'u', 's' }; + +static struct among a_2[6] = +{ +/* 0 */ { 3, s_2_0, -1, 2, 0}, +/* 1 */ { 1, s_2_1, -1, 3, 0}, +/* 2 */ { 3, s_2_2, 1, 2, 0}, +/* 3 */ { 4, s_2_3, 1, 1, 0}, +/* 4 */ { 2, s_2_4, 1, -1, 0}, +/* 5 */ { 2, s_2_5, 1, -1, 0} +}; + +static symbol s_3_1[2] = { 'b', 'b' }; +static symbol s_3_2[2] = { 'd', 'd' }; +static symbol s_3_3[2] = { 'f', 'f' }; +static symbol s_3_4[2] = { 'g', 'g' }; +static symbol s_3_5[2] = { 'b', 'l' }; +static symbol s_3_6[2] = { 'm', 'm' }; +static symbol s_3_7[2] = { 'n', 'n' }; +static symbol s_3_8[2] = { 'p', 'p' }; +static symbol s_3_9[2] = { 'r', 'r' }; +static symbol s_3_10[2] = { 'a', 't' }; +static symbol s_3_11[2] = { 't', 't' }; +static symbol s_3_12[2] = { 'i', 'z' }; + +static struct among a_3[13] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_3_1, 0, 2, 0}, +/* 2 */ { 2, s_3_2, 0, 2, 0}, +/* 3 */ { 2, s_3_3, 0, 2, 0}, +/* 4 */ { 2, s_3_4, 0, 2, 0}, +/* 5 */ { 2, s_3_5, 0, 1, 0}, +/* 6 */ { 2, s_3_6, 0, 2, 0}, +/* 7 */ { 2, s_3_7, 0, 2, 0}, +/* 8 */ { 2, s_3_8, 0, 2, 0}, +/* 9 */ { 2, s_3_9, 0, 2, 0}, +/* 10 */ { 2, s_3_10, 0, 1, 0}, +/* 11 */ { 2, s_3_11, 0, 2, 0}, +/* 12 */ { 2, s_3_12, 0, 1, 0} +}; + +static symbol s_4_0[2] = { 'e', 'd' }; +static symbol s_4_1[3] = { 'e', 'e', 'd' }; +static symbol s_4_2[3] = { 'i', 'n', 'g' }; +static symbol s_4_3[4] = { 'e', 'd', 'l', 'y' }; +static symbol s_4_4[5] = { 'e', 'e', 'd', 'l', 'y' }; +static symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' }; + +static struct among a_4[6] = +{ +/* 0 */ { 2, s_4_0, -1, 2, 0}, +/* 1 */ { 3, s_4_1, 0, 1, 0}, +/* 2 */ { 3, s_4_2, -1, 2, 0}, +/* 3 */ { 4, s_4_3, -1, 2, 0}, +/* 4 */ { 5, s_4_4, 3, 1, 0}, +/* 5 */ { 5, s_4_5, -1, 2, 0} +}; + +static symbol s_5_0[4] = { 'a', 'n', 'c', 'i' }; +static symbol s_5_1[4] = { 'e', 'n', 'c', 'i' }; +static symbol s_5_2[3] = { 'o', 'g', 'i' }; +static symbol s_5_3[2] = { 'l', 'i' }; +static symbol s_5_4[3] = { 'b', 'l', 'i' }; +static symbol s_5_5[4] = { 'a', 'b', 'l', 'i' }; +static symbol s_5_6[4] = { 'a', 'l', 'l', 'i' }; +static symbol s_5_7[5] = { 'f', 'u', 'l', 'l', 'i' }; +static symbol s_5_8[6] = { 'l', 'e', 's', 's', 'l', 'i' }; +static symbol s_5_9[5] = { 'o', 'u', 's', 'l', 'i' }; +static symbol s_5_10[5] = { 'e', 'n', 't', 'l', 'i' }; +static symbol s_5_11[5] = { 'a', 'l', 'i', 't', 'i' }; +static symbol s_5_12[6] = { 'b', 'i', 'l', 'i', 't', 'i' }; +static symbol s_5_13[5] = { 'i', 'v', 'i', 't', 'i' }; +static symbol s_5_14[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_5_15[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_5_16[5] = { 'a', 'l', 'i', 's', 'm' }; +static symbol s_5_17[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_5_18[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' }; +static symbol s_5_19[4] = { 'i', 'z', 'e', 'r' }; +static symbol s_5_20[4] = { 'a', 't', 'o', 'r' }; +static symbol s_5_21[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' }; +static symbol s_5_22[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' }; +static symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; + +static struct among a_5[24] = +{ +/* 0 */ { 4, s_5_0, -1, 3, 0}, +/* 1 */ { 4, s_5_1, -1, 2, 0}, +/* 2 */ { 3, s_5_2, -1, 13, 0}, +/* 3 */ { 2, s_5_3, -1, 16, 0}, +/* 4 */ { 3, s_5_4, 3, 12, 0}, +/* 5 */ { 4, s_5_5, 4, 4, 0}, +/* 6 */ { 4, s_5_6, 3, 8, 0}, +/* 7 */ { 5, s_5_7, 3, 14, 0}, +/* 8 */ { 6, s_5_8, 3, 15, 0}, +/* 9 */ { 5, s_5_9, 3, 10, 0}, +/* 10 */ { 5, s_5_10, 3, 5, 0}, +/* 11 */ { 5, s_5_11, -1, 8, 0}, +/* 12 */ { 6, s_5_12, -1, 12, 0}, +/* 13 */ { 5, s_5_13, -1, 11, 0}, +/* 14 */ { 6, s_5_14, -1, 1, 0}, +/* 15 */ { 7, s_5_15, 14, 7, 0}, +/* 16 */ { 5, s_5_16, -1, 8, 0}, +/* 17 */ { 5, s_5_17, -1, 7, 0}, +/* 18 */ { 7, s_5_18, 17, 6, 0}, +/* 19 */ { 4, s_5_19, -1, 6, 0}, +/* 20 */ { 4, s_5_20, -1, 7, 0}, +/* 21 */ { 7, s_5_21, -1, 11, 0}, +/* 22 */ { 7, s_5_22, -1, 9, 0}, +/* 23 */ { 7, s_5_23, -1, 10, 0} +}; + +static symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' }; +static symbol s_6_1[5] = { 'a', 't', 'i', 'v', 'e' }; +static symbol s_6_2[5] = { 'a', 'l', 'i', 'z', 'e' }; +static symbol s_6_3[5] = { 'i', 'c', 'i', 't', 'i' }; +static symbol s_6_4[4] = { 'i', 'c', 'a', 'l' }; +static symbol s_6_5[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_6_6[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_6_7[3] = { 'f', 'u', 'l' }; +static symbol s_6_8[4] = { 'n', 'e', 's', 's' }; + +static struct among a_6[9] = +{ +/* 0 */ { 5, s_6_0, -1, 4, 0}, +/* 1 */ { 5, s_6_1, -1, 6, 0}, +/* 2 */ { 5, s_6_2, -1, 3, 0}, +/* 3 */ { 5, s_6_3, -1, 4, 0}, +/* 4 */ { 4, s_6_4, -1, 4, 0}, +/* 5 */ { 6, s_6_5, -1, 1, 0}, +/* 6 */ { 7, s_6_6, 5, 2, 0}, +/* 7 */ { 3, s_6_7, -1, 5, 0}, +/* 8 */ { 4, s_6_8, -1, 5, 0} +}; + +static symbol s_7_0[2] = { 'i', 'c' }; +static symbol s_7_1[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_7_2[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_7_3[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_7_4[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_7_5[3] = { 'a', 't', 'e' }; +static symbol s_7_6[3] = { 'i', 'v', 'e' }; +static symbol s_7_7[3] = { 'i', 'z', 'e' }; +static symbol s_7_8[3] = { 'i', 't', 'i' }; +static symbol s_7_9[2] = { 'a', 'l' }; +static symbol s_7_10[3] = { 'i', 's', 'm' }; +static symbol s_7_11[3] = { 'i', 'o', 'n' }; +static symbol s_7_12[2] = { 'e', 'r' }; +static symbol s_7_13[3] = { 'o', 'u', 's' }; +static symbol s_7_14[3] = { 'a', 'n', 't' }; +static symbol s_7_15[3] = { 'e', 'n', 't' }; +static symbol s_7_16[4] = { 'm', 'e', 'n', 't' }; +static symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' }; + +static struct among a_7[18] = +{ +/* 0 */ { 2, s_7_0, -1, 1, 0}, +/* 1 */ { 4, s_7_1, -1, 1, 0}, +/* 2 */ { 4, s_7_2, -1, 1, 0}, +/* 3 */ { 4, s_7_3, -1, 1, 0}, +/* 4 */ { 4, s_7_4, -1, 1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 3, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 3, s_7_8, -1, 1, 0}, +/* 9 */ { 2, s_7_9, -1, 1, 0}, +/* 10 */ { 3, s_7_10, -1, 1, 0}, +/* 11 */ { 3, s_7_11, -1, 2, 0}, +/* 12 */ { 2, s_7_12, -1, 1, 0}, +/* 13 */ { 3, s_7_13, -1, 1, 0}, +/* 14 */ { 3, s_7_14, -1, 1, 0}, +/* 15 */ { 3, s_7_15, -1, 1, 0}, +/* 16 */ { 4, s_7_16, 15, 1, 0}, +/* 17 */ { 5, s_7_17, 16, 1, 0} +}; + +static symbol s_8_0[1] = { 'e' }; +static symbol s_8_1[1] = { 'l' }; + +static struct among a_8[2] = +{ +/* 0 */ { 1, s_8_0, -1, 1, 0}, +/* 1 */ { 1, s_8_1, -1, 2, 0} +}; + +static symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' }; +static symbol s_9_1[7] = { 'p', 'r', 'o', 'c', 'e', 'e', 'd' }; +static symbol s_9_2[6] = { 'e', 'x', 'c', 'e', 'e', 'd' }; +static symbol s_9_3[7] = { 'c', 'a', 'n', 'n', 'i', 'n', 'g' }; +static symbol s_9_4[6] = { 'i', 'n', 'n', 'i', 'n', 'g' }; +static symbol s_9_5[7] = { 'e', 'a', 'r', 'r', 'i', 'n', 'g' }; +static symbol s_9_6[7] = { 'h', 'e', 'r', 'r', 'i', 'n', 'g' }; +static symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' }; + +static struct among a_9[8] = +{ +/* 0 */ { 7, s_9_0, -1, -1, 0}, +/* 1 */ { 7, s_9_1, -1, -1, 0}, +/* 2 */ { 6, s_9_2, -1, -1, 0}, +/* 3 */ { 7, s_9_3, -1, -1, 0}, +/* 4 */ { 6, s_9_4, -1, -1, 0}, +/* 5 */ { 7, s_9_5, -1, -1, 0}, +/* 6 */ { 7, s_9_6, -1, -1, 0}, +/* 7 */ { 6, s_9_7, -1, -1, 0} +}; + +static symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' }; +static symbol s_10_1[5] = { 'a', 't', 'l', 'a', 's' }; +static symbol s_10_2[4] = { 'b', 'i', 'a', 's' }; +static symbol s_10_3[6] = { 'c', 'o', 's', 'm', 'o', 's' }; +static symbol s_10_4[5] = { 'd', 'y', 'i', 'n', 'g' }; +static symbol s_10_5[5] = { 'e', 'a', 'r', 'l', 'y' }; +static symbol s_10_6[6] = { 'g', 'e', 'n', 't', 'l', 'y' }; +static symbol s_10_7[4] = { 'h', 'o', 'w', 'e' }; +static symbol s_10_8[4] = { 'i', 'd', 'l', 'y' }; +static symbol s_10_9[5] = { 'l', 'y', 'i', 'n', 'g' }; +static symbol s_10_10[4] = { 'n', 'e', 'w', 's' }; +static symbol s_10_11[4] = { 'o', 'n', 'l', 'y' }; +static symbol s_10_12[6] = { 's', 'i', 'n', 'g', 'l', 'y' }; +static symbol s_10_13[5] = { 's', 'k', 'i', 'e', 's' }; +static symbol s_10_14[4] = { 's', 'k', 'i', 's' }; +static symbol s_10_15[3] = { 's', 'k', 'y' }; +static symbol s_10_16[5] = { 't', 'y', 'i', 'n', 'g' }; +static symbol s_10_17[4] = { 'u', 'g', 'l', 'y' }; + +static struct among a_10[18] = +{ +/* 0 */ { 5, s_10_0, -1, -1, 0}, +/* 1 */ { 5, s_10_1, -1, -1, 0}, +/* 2 */ { 4, s_10_2, -1, -1, 0}, +/* 3 */ { 6, s_10_3, -1, -1, 0}, +/* 4 */ { 5, s_10_4, -1, 3, 0}, +/* 5 */ { 5, s_10_5, -1, 9, 0}, +/* 6 */ { 6, s_10_6, -1, 7, 0}, +/* 7 */ { 4, s_10_7, -1, -1, 0}, +/* 8 */ { 4, s_10_8, -1, 6, 0}, +/* 9 */ { 5, s_10_9, -1, 4, 0}, +/* 10 */ { 4, s_10_10, -1, -1, 0}, +/* 11 */ { 4, s_10_11, -1, 10, 0}, +/* 12 */ { 6, s_10_12, -1, 11, 0}, +/* 13 */ { 5, s_10_13, -1, 2, 0}, +/* 14 */ { 4, s_10_14, -1, 1, 0}, +/* 15 */ { 3, s_10_15, -1, -1, 0}, +/* 16 */ { 5, s_10_16, -1, 5, 0}, +/* 17 */ { 4, s_10_17, -1, 8, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1 }; + +static unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; + +static unsigned char g_valid_LI[] = { 55, 141, 2 }; + +static symbol s_0[] = { '\'' }; +static symbol s_1[] = { 'y' }; +static symbol s_2[] = { 'Y' }; +static symbol s_3[] = { 'y' }; +static symbol s_4[] = { 'Y' }; +static symbol s_5[] = { 's', 's' }; +static symbol s_6[] = { 'i', 'e' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 'e', 'e' }; +static symbol s_9[] = { 'e' }; +static symbol s_10[] = { 'e' }; +static symbol s_11[] = { 'y' }; +static symbol s_12[] = { 'Y' }; +static symbol s_13[] = { 'i' }; +static symbol s_14[] = { 't', 'i', 'o', 'n' }; +static symbol s_15[] = { 'e', 'n', 'c', 'e' }; +static symbol s_16[] = { 'a', 'n', 'c', 'e' }; +static symbol s_17[] = { 'a', 'b', 'l', 'e' }; +static symbol s_18[] = { 'e', 'n', 't' }; +static symbol s_19[] = { 'i', 'z', 'e' }; +static symbol s_20[] = { 'a', 't', 'e' }; +static symbol s_21[] = { 'a', 'l' }; +static symbol s_22[] = { 'f', 'u', 'l' }; +static symbol s_23[] = { 'o', 'u', 's' }; +static symbol s_24[] = { 'i', 'v', 'e' }; +static symbol s_25[] = { 'b', 'l', 'e' }; +static symbol s_26[] = { 'l' }; +static symbol s_27[] = { 'o', 'g' }; +static symbol s_28[] = { 'f', 'u', 'l' }; +static symbol s_29[] = { 'l', 'e', 's', 's' }; +static symbol s_30[] = { 't', 'i', 'o', 'n' }; +static symbol s_31[] = { 'a', 't', 'e' }; +static symbol s_32[] = { 'a', 'l' }; +static symbol s_33[] = { 'i', 'c' }; +static symbol s_34[] = { 's' }; +static symbol s_35[] = { 't' }; +static symbol s_36[] = { 'l' }; +static symbol s_37[] = { 's', 'k', 'i' }; +static symbol s_38[] = { 's', 'k', 'y' }; +static symbol s_39[] = { 'd', 'i', 'e' }; +static symbol s_40[] = { 'l', 'i', 'e' }; +static symbol s_41[] = { 't', 'i', 'e' }; +static symbol s_42[] = { 'i', 'd', 'l' }; +static symbol s_43[] = { 'g', 'e', 'n', 't', 'l' }; +static symbol s_44[] = { 'u', 'g', 'l', 'i' }; +static symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' }; +static symbol s_46[] = { 'o', 'n', 'l', 'i' }; +static symbol s_47[] = { 's', 'i', 'n', 'g', 'l' }; +static symbol s_48[] = { 'Y' }; +static symbol s_49[] = { 'y' }; + +static int r_prelude(struct SN_env * z) { + z->B[0] = 0; /* unset Y_found, line 26 */ + { int c = z->c; /* do, line 27 */ + z->bra = z->c; /* [, line 27 */ + if (!(eq_s(z, 1, s_0))) goto lab0; + z->ket = z->c; /* ], line 27 */ + { int ret; + ret = slice_del(z); /* delete, line 27 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 28 */ + z->bra = z->c; /* [, line 28 */ + if (!(eq_s(z, 1, s_1))) goto lab1; + z->ket = z->c; /* ], line 28 */ + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab1; + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 28 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 28 */ + lab1: + z->c = c; + } + { int c = z->c; /* do, line 29 */ + while(1) { /* repeat, line 29 */ + int c = z->c; + while(1) { /* goto, line 29 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab4; + z->bra = z->c; /* [, line 29 */ + if (!(eq_s(z, 1, s_3))) goto lab4; + z->ket = z->c; /* ], line 29 */ + z->c = c; + break; + lab4: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab3; + z->c = c; /* goto, line 29 */ + } + } + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 29 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 29 */ + continue; + lab3: + z->c = c; + break; + } + z->c = c; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 35 */ + { int c = z->c; /* or, line 40 */ + if (!(find_among(z, a_0, 2))) goto lab2; /* among, line 36 */ + goto lab1; + lab2: + z->c = c; + while(1) { /* gopast, line 40 */ + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 40 */ + } + } + while(1) { /* gopast, line 40 */ + if (!(out_grouping_U(z, g_v, 97, 121))) goto lab4; + break; + lab4: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 40 */ + } + } + } + lab1: + z->I[0] = z->c; /* setmark p1, line 41 */ + while(1) { /* gopast, line 42 */ + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 42 */ + } + } + while(1) { /* gopast, line 42 */ + if (!(out_grouping_U(z, g_v, 97, 121))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 42 */ + } + } + z->I[1] = z->c; /* setmark p2, line 42 */ + lab0: + z->c = c; + } + return 1; +} + +static int r_shortv(struct SN_env * z) { + { int m = z->l - z->c; (void) m; /* or, line 50 */ + if (!(out_grouping_b_U(z, g_v_WXY, 89, 121))) goto lab1; + if (!(in_grouping_b_U(z, g_v, 97, 121))) goto lab1; + if (!(out_grouping_b_U(z, g_v, 97, 121))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(out_grouping_b_U(z, g_v, 97, 121))) return 0; + if (!(in_grouping_b_U(z, g_v, 97, 121))) return 0; + if (z->c > z->lb) return 0; /* atlimit, line 51 */ + } +lab0: + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_Step_1a(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* try, line 58 */ + z->ket = z->c; /* [, line 59 */ + among_var = find_among_b(z, a_1, 3); /* substring, line 59 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 59 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 61 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + z->ket = z->c; /* [, line 64 */ + among_var = find_among_b(z, a_2, 6); /* substring, line 64 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 64 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_5); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 67 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) goto lab2; + z->c = c; /* next, line 67 */ + } + if (z->c > z->lb) goto lab2; /* atlimit, line 67 */ + { int ret; + ret = slice_from_s(z, 2, s_6); /* <-, line 67 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 67 */ + if (ret < 0) return ret; + } + } + lab1: + break; + case 3: + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 68 */ + } + while(1) { /* gopast, line 68 */ + if (!(in_grouping_b_U(z, g_v, 97, 121))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* gopast, line 68 */ + } + } + { int ret; + ret = slice_del(z); /* delete, line 68 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_1b(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 74 */ + among_var = find_among_b(z, a_4, 6); /* substring, line 74 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 74 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 76 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m_test = z->l - z->c; /* test, line 79 */ + while(1) { /* gopast, line 79 */ + if (!(in_grouping_b_U(z, g_v, 97, 121))) goto lab0; + break; + lab0: + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* gopast, line 79 */ + } + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 79 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 80 */ + among_var = find_among_b(z, a_3, 13); /* substring, line 80 */ + if (!(among_var)) return 0; + z->c = z->l - m_test; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 82 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + case 2: + z->ket = z->c; /* [, line 85 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 85 */ + } + z->bra = z->c; /* ], line 85 */ + { int ret; + ret = slice_del(z); /* delete, line 85 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c != z->I[0]) return 0; /* atmark, line 86 */ + { int m_test = z->l - z->c; /* test, line 86 */ + { int ret = r_shortv(z); + if (ret == 0) return 0; /* call shortv, line 86 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 86 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + } + break; + } + return 1; +} + +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; /* [, line 93 */ + { int m = z->l - z->c; (void) m; /* or, line 93 */ + if (!(eq_s_b(z, 1, s_11))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_12))) return 0; + } +lab0: + z->bra = z->c; /* ], line 93 */ + if (!(out_grouping_b_U(z, g_v, 97, 121))) return 0; + { int m = z->l - z->c; (void) m; /* not, line 94 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 94 */ + return 0; + lab2: + z->c = z->l - m; + } + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 95 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_2(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 99 */ + among_var = find_among_b(z, a_5, 24); /* substring, line 99 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 99 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 99 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_14); /* <-, line 100 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_15); /* <-, line 101 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_16); /* <-, line 102 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 4, s_17); /* <-, line 103 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 104 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 3, s_19); /* <-, line 106 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 108 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 2, s_21); /* <-, line 110 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 3, s_22); /* <-, line 111 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 3, s_23); /* <-, line 113 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 3, s_24); /* <-, line 115 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret; + ret = slice_from_s(z, 3, s_25); /* <-, line 117 */ + if (ret < 0) return ret; + } + break; + case 13: + if (!(eq_s_b(z, 1, s_26))) return 0; + { int ret; + ret = slice_from_s(z, 2, s_27); /* <-, line 118 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret; + ret = slice_from_s(z, 3, s_28); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 15: + { int ret; + ret = slice_from_s(z, 4, s_29); /* <-, line 120 */ + if (ret < 0) return ret; + } + break; + case 16: + if (!(in_grouping_b_U(z, g_valid_LI, 99, 116))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 121 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_3(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 126 */ + among_var = find_among_b(z, a_6, 9); /* substring, line 126 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 126 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 126 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_30); /* <-, line 127 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_31); /* <-, line 128 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 2, s_32); /* <-, line 129 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 2, s_33); /* <-, line 131 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 135 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 135 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_4(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 140 */ + among_var = find_among_b(z, a_7, 18); /* substring, line 140 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 140 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 140 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 144 */ + if (!(eq_s_b(z, 1, s_34))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_35))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 144 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_5(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_8, 2); /* substring, line 149 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 150 */ + { int ret = r_R2(z); + if (ret == 0) goto lab1; /* call R2, line 150 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 150 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 150 */ + { int ret = r_shortv(z); + if (ret == 0) goto lab2; /* call shortv, line 150 */ + if (ret < 0) return ret; + } + return 0; + lab2: + z->c = z->l - m; + } + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 150 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 151 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_36))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_exception2(struct SN_env * z) { + z->ket = z->c; /* [, line 157 */ + if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 157 */ + z->bra = z->c; /* ], line 157 */ + if (z->c > z->lb) return 0; /* atlimit, line 157 */ + return 1; +} + +static int r_exception1(struct SN_env * z) { + int among_var; + z->bra = z->c; /* [, line 169 */ + among_var = find_among(z, a_10, 18); /* substring, line 169 */ + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 169 */ + if (z->c < z->l) return 0; /* atlimit, line 169 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 3, s_37); /* <-, line 173 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 3, s_38); /* <-, line 174 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 3, s_39); /* <-, line 175 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 3, s_40); /* <-, line 176 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_41); /* <-, line 177 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 3, s_42); /* <-, line 181 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 5, s_43); /* <-, line 182 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 4, s_44); /* <-, line 183 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 5, s_45); /* <-, line 184 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 4, s_46); /* <-, line 185 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 5, s_47); /* <-, line 186 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + if (!(z->B[0])) return 0; /* Boolean test Y_found, line 202 */ + while(1) { /* repeat, line 202 */ + int c = z->c; + while(1) { /* goto, line 202 */ + int c = z->c; + z->bra = z->c; /* [, line 202 */ + if (!(eq_s(z, 1, s_48))) goto lab1; + z->ket = z->c; /* ], line 202 */ + z->c = c; + break; + lab1: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* goto, line 202 */ + } + } + { int ret; + ret = slice_from_s(z, 1, s_49); /* <-, line 202 */ + if (ret < 0) return ret; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +extern int english_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* or, line 206 */ + { int ret = r_exception1(z); + if (ret == 0) goto lab1; /* call exception1, line 206 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = c; + { int c = z->c; /* not, line 207 */ + { int c = skip_utf8(z->p, z->c, 0, z->l, + 3); + if (c < 0) goto lab3; + z->c = c; /* hop, line 207 */ + } + goto lab2; + lab3: + z->c = c; + } + goto lab0; + lab2: + z->c = c; + { int c = z->c; /* do, line 208 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab4; /* call prelude, line 208 */ + if (ret < 0) return ret; + } + lab4: + z->c = c; + } + { int c = z->c; /* do, line 209 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab5; /* call mark_regions, line 209 */ + if (ret < 0) return ret; + } + lab5: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 210 */ + + { int m = z->l - z->c; (void) m; /* do, line 212 */ + { int ret = r_Step_1a(z); + if (ret == 0) goto lab6; /* call Step_1a, line 212 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* or, line 214 */ + { int ret = r_exception2(z); + if (ret == 0) goto lab8; /* call exception2, line 214 */ + if (ret < 0) return ret; + } + goto lab7; + lab8: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 216 */ + { int ret = r_Step_1b(z); + if (ret == 0) goto lab9; /* call Step_1b, line 216 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 217 */ + { int ret = r_Step_1c(z); + if (ret == 0) goto lab10; /* call Step_1c, line 217 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 219 */ + { int ret = r_Step_2(z); + if (ret == 0) goto lab11; /* call Step_2, line 219 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 220 */ + { int ret = r_Step_3(z); + if (ret == 0) goto lab12; /* call Step_3, line 220 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 221 */ + { int ret = r_Step_4(z); + if (ret == 0) goto lab13; /* call Step_4, line 221 */ + if (ret < 0) return ret; + } + lab13: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 223 */ + { int ret = r_Step_5(z); + if (ret == 0) goto lab14; /* call Step_5, line 223 */ + if (ret < 0) return ret; + } + lab14: + z->c = z->l - m; + } + } + lab7: + z->c = z->lb; + { int c = z->c; /* do, line 226 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab15; /* call postlude, line 226 */ + if (ret < 0) return ret; + } + lab15: + z->c = c; + } + } +lab0: + return 1; +} + +extern struct SN_env * english_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void english_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.h new file mode 100644 index 00000000000..619a8bc72ae --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_english.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * english_UTF_8_create_env(void); +extern void english_UTF_8_close_env(struct SN_env * z); + +extern int english_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.c new file mode 100644 index 00000000000..a221be65de1 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.c @@ -0,0 +1,808 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int finnish_UTF_8_stem(struct SN_env * z); +static int r_tidy(struct SN_env * z); +static int r_other_endings(struct SN_env * z); +static int r_t_plural(struct SN_env * z); +static int r_i_plural(struct SN_env * z); +static int r_case_ending(struct SN_env * z); +static int r_VI(struct SN_env * z); +static int r_LONG(struct SN_env * z); +static int r_possessive(struct SN_env * z); +static int r_particle_etc(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * finnish_UTF_8_create_env(void); +extern void finnish_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[2] = { 'p', 'a' }; +static symbol s_0_1[3] = { 's', 't', 'i' }; +static symbol s_0_2[4] = { 'k', 'a', 'a', 'n' }; +static symbol s_0_3[3] = { 'h', 'a', 'n' }; +static symbol s_0_4[3] = { 'k', 'i', 'n' }; +static symbol s_0_5[4] = { 'h', 0xC3, 0xA4, 'n' }; +static symbol s_0_6[6] = { 'k', 0xC3, 0xA4, 0xC3, 0xA4, 'n' }; +static symbol s_0_7[2] = { 'k', 'o' }; +static symbol s_0_8[3] = { 'p', 0xC3, 0xA4 }; +static symbol s_0_9[3] = { 'k', 0xC3, 0xB6 }; + +static struct among a_0[10] = +{ +/* 0 */ { 2, s_0_0, -1, 1, 0}, +/* 1 */ { 3, s_0_1, -1, 2, 0}, +/* 2 */ { 4, s_0_2, -1, 1, 0}, +/* 3 */ { 3, s_0_3, -1, 1, 0}, +/* 4 */ { 3, s_0_4, -1, 1, 0}, +/* 5 */ { 4, s_0_5, -1, 1, 0}, +/* 6 */ { 6, s_0_6, -1, 1, 0}, +/* 7 */ { 2, s_0_7, -1, 1, 0}, +/* 8 */ { 3, s_0_8, -1, 1, 0}, +/* 9 */ { 3, s_0_9, -1, 1, 0} +}; + +static symbol s_1_0[3] = { 'l', 'l', 'a' }; +static symbol s_1_1[2] = { 'n', 'a' }; +static symbol s_1_2[3] = { 's', 's', 'a' }; +static symbol s_1_3[2] = { 't', 'a' }; +static symbol s_1_4[3] = { 'l', 't', 'a' }; +static symbol s_1_5[3] = { 's', 't', 'a' }; + +static struct among a_1[6] = +{ +/* 0 */ { 3, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 3, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 3, s_1_4, 3, -1, 0}, +/* 5 */ { 3, s_1_5, 3, -1, 0} +}; + +static symbol s_2_0[4] = { 'l', 'l', 0xC3, 0xA4 }; +static symbol s_2_1[3] = { 'n', 0xC3, 0xA4 }; +static symbol s_2_2[4] = { 's', 's', 0xC3, 0xA4 }; +static symbol s_2_3[3] = { 't', 0xC3, 0xA4 }; +static symbol s_2_4[4] = { 'l', 't', 0xC3, 0xA4 }; +static symbol s_2_5[4] = { 's', 't', 0xC3, 0xA4 }; + +static struct among a_2[6] = +{ +/* 0 */ { 4, s_2_0, -1, -1, 0}, +/* 1 */ { 3, s_2_1, -1, -1, 0}, +/* 2 */ { 4, s_2_2, -1, -1, 0}, +/* 3 */ { 3, s_2_3, -1, -1, 0}, +/* 4 */ { 4, s_2_4, 3, -1, 0}, +/* 5 */ { 4, s_2_5, 3, -1, 0} +}; + +static symbol s_3_0[3] = { 'l', 'l', 'e' }; +static symbol s_3_1[3] = { 'i', 'n', 'e' }; + +static struct among a_3[2] = +{ +/* 0 */ { 3, s_3_0, -1, -1, 0}, +/* 1 */ { 3, s_3_1, -1, -1, 0} +}; + +static symbol s_4_0[3] = { 'n', 's', 'a' }; +static symbol s_4_1[3] = { 'm', 'm', 'e' }; +static symbol s_4_2[3] = { 'n', 'n', 'e' }; +static symbol s_4_3[2] = { 'n', 'i' }; +static symbol s_4_4[2] = { 's', 'i' }; +static symbol s_4_5[2] = { 'a', 'n' }; +static symbol s_4_6[2] = { 'e', 'n' }; +static symbol s_4_7[3] = { 0xC3, 0xA4, 'n' }; +static symbol s_4_8[4] = { 'n', 's', 0xC3, 0xA4 }; + +static struct among a_4[9] = +{ +/* 0 */ { 3, s_4_0, -1, 3, 0}, +/* 1 */ { 3, s_4_1, -1, 3, 0}, +/* 2 */ { 3, s_4_2, -1, 3, 0}, +/* 3 */ { 2, s_4_3, -1, 2, 0}, +/* 4 */ { 2, s_4_4, -1, 1, 0}, +/* 5 */ { 2, s_4_5, -1, 4, 0}, +/* 6 */ { 2, s_4_6, -1, 6, 0}, +/* 7 */ { 3, s_4_7, -1, 5, 0}, +/* 8 */ { 4, s_4_8, -1, 3, 0} +}; + +static symbol s_5_0[2] = { 'a', 'a' }; +static symbol s_5_1[2] = { 'e', 'e' }; +static symbol s_5_2[2] = { 'i', 'i' }; +static symbol s_5_3[2] = { 'o', 'o' }; +static symbol s_5_4[2] = { 'u', 'u' }; +static symbol s_5_5[4] = { 0xC3, 0xA4, 0xC3, 0xA4 }; +static symbol s_5_6[4] = { 0xC3, 0xB6, 0xC3, 0xB6 }; + +static struct among a_5[7] = +{ +/* 0 */ { 2, s_5_0, -1, -1, 0}, +/* 1 */ { 2, s_5_1, -1, -1, 0}, +/* 2 */ { 2, s_5_2, -1, -1, 0}, +/* 3 */ { 2, s_5_3, -1, -1, 0}, +/* 4 */ { 2, s_5_4, -1, -1, 0}, +/* 5 */ { 4, s_5_5, -1, -1, 0}, +/* 6 */ { 4, s_5_6, -1, -1, 0} +}; + +static symbol s_6_0[1] = { 'a' }; +static symbol s_6_1[3] = { 'l', 'l', 'a' }; +static symbol s_6_2[2] = { 'n', 'a' }; +static symbol s_6_3[3] = { 's', 's', 'a' }; +static symbol s_6_4[2] = { 't', 'a' }; +static symbol s_6_5[3] = { 'l', 't', 'a' }; +static symbol s_6_6[3] = { 's', 't', 'a' }; +static symbol s_6_7[3] = { 't', 't', 'a' }; +static symbol s_6_8[3] = { 'l', 'l', 'e' }; +static symbol s_6_9[3] = { 'i', 'n', 'e' }; +static symbol s_6_10[3] = { 'k', 's', 'i' }; +static symbol s_6_11[1] = { 'n' }; +static symbol s_6_12[3] = { 'h', 'a', 'n' }; +static symbol s_6_13[3] = { 'd', 'e', 'n' }; +static symbol s_6_14[4] = { 's', 'e', 'e', 'n' }; +static symbol s_6_15[3] = { 'h', 'e', 'n' }; +static symbol s_6_16[4] = { 't', 't', 'e', 'n' }; +static symbol s_6_17[3] = { 'h', 'i', 'n' }; +static symbol s_6_18[4] = { 's', 'i', 'i', 'n' }; +static symbol s_6_19[3] = { 'h', 'o', 'n' }; +static symbol s_6_20[4] = { 'h', 0xC3, 0xA4, 'n' }; +static symbol s_6_21[4] = { 'h', 0xC3, 0xB6, 'n' }; +static symbol s_6_22[2] = { 0xC3, 0xA4 }; +static symbol s_6_23[4] = { 'l', 'l', 0xC3, 0xA4 }; +static symbol s_6_24[3] = { 'n', 0xC3, 0xA4 }; +static symbol s_6_25[4] = { 's', 's', 0xC3, 0xA4 }; +static symbol s_6_26[3] = { 't', 0xC3, 0xA4 }; +static symbol s_6_27[4] = { 'l', 't', 0xC3, 0xA4 }; +static symbol s_6_28[4] = { 's', 't', 0xC3, 0xA4 }; +static symbol s_6_29[4] = { 't', 't', 0xC3, 0xA4 }; + +static struct among a_6[30] = +{ +/* 0 */ { 1, s_6_0, -1, 8, 0}, +/* 1 */ { 3, s_6_1, 0, -1, 0}, +/* 2 */ { 2, s_6_2, 0, -1, 0}, +/* 3 */ { 3, s_6_3, 0, -1, 0}, +/* 4 */ { 2, s_6_4, 0, -1, 0}, +/* 5 */ { 3, s_6_5, 4, -1, 0}, +/* 6 */ { 3, s_6_6, 4, -1, 0}, +/* 7 */ { 3, s_6_7, 4, 9, 0}, +/* 8 */ { 3, s_6_8, -1, -1, 0}, +/* 9 */ { 3, s_6_9, -1, -1, 0}, +/* 10 */ { 3, s_6_10, -1, -1, 0}, +/* 11 */ { 1, s_6_11, -1, 7, 0}, +/* 12 */ { 3, s_6_12, 11, 1, 0}, +/* 13 */ { 3, s_6_13, 11, -1, r_VI}, +/* 14 */ { 4, s_6_14, 11, -1, r_LONG}, +/* 15 */ { 3, s_6_15, 11, 2, 0}, +/* 16 */ { 4, s_6_16, 11, -1, r_VI}, +/* 17 */ { 3, s_6_17, 11, 3, 0}, +/* 18 */ { 4, s_6_18, 11, -1, r_VI}, +/* 19 */ { 3, s_6_19, 11, 4, 0}, +/* 20 */ { 4, s_6_20, 11, 5, 0}, +/* 21 */ { 4, s_6_21, 11, 6, 0}, +/* 22 */ { 2, s_6_22, -1, 8, 0}, +/* 23 */ { 4, s_6_23, 22, -1, 0}, +/* 24 */ { 3, s_6_24, 22, -1, 0}, +/* 25 */ { 4, s_6_25, 22, -1, 0}, +/* 26 */ { 3, s_6_26, 22, -1, 0}, +/* 27 */ { 4, s_6_27, 26, -1, 0}, +/* 28 */ { 4, s_6_28, 26, -1, 0}, +/* 29 */ { 4, s_6_29, 26, 9, 0} +}; + +static symbol s_7_0[3] = { 'e', 'j', 'a' }; +static symbol s_7_1[3] = { 'm', 'm', 'a' }; +static symbol s_7_2[4] = { 'i', 'm', 'm', 'a' }; +static symbol s_7_3[3] = { 'm', 'p', 'a' }; +static symbol s_7_4[4] = { 'i', 'm', 'p', 'a' }; +static symbol s_7_5[3] = { 'm', 'm', 'i' }; +static symbol s_7_6[4] = { 'i', 'm', 'm', 'i' }; +static symbol s_7_7[3] = { 'm', 'p', 'i' }; +static symbol s_7_8[4] = { 'i', 'm', 'p', 'i' }; +static symbol s_7_9[4] = { 'e', 'j', 0xC3, 0xA4 }; +static symbol s_7_10[4] = { 'm', 'm', 0xC3, 0xA4 }; +static symbol s_7_11[5] = { 'i', 'm', 'm', 0xC3, 0xA4 }; +static symbol s_7_12[4] = { 'm', 'p', 0xC3, 0xA4 }; +static symbol s_7_13[5] = { 'i', 'm', 'p', 0xC3, 0xA4 }; + +static struct among a_7[14] = +{ +/* 0 */ { 3, s_7_0, -1, -1, 0}, +/* 1 */ { 3, s_7_1, -1, 1, 0}, +/* 2 */ { 4, s_7_2, 1, -1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 4, s_7_4, 3, -1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 4, s_7_6, 5, -1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 4, s_7_8, 7, -1, 0}, +/* 9 */ { 4, s_7_9, -1, -1, 0}, +/* 10 */ { 4, s_7_10, -1, 1, 0}, +/* 11 */ { 5, s_7_11, 10, -1, 0}, +/* 12 */ { 4, s_7_12, -1, 1, 0}, +/* 13 */ { 5, s_7_13, 12, -1, 0} +}; + +static symbol s_8_0[1] = { 'i' }; +static symbol s_8_1[1] = { 'j' }; + +static struct among a_8[2] = +{ +/* 0 */ { 1, s_8_0, -1, -1, 0}, +/* 1 */ { 1, s_8_1, -1, -1, 0} +}; + +static symbol s_9_0[3] = { 'm', 'm', 'a' }; +static symbol s_9_1[4] = { 'i', 'm', 'm', 'a' }; + +static struct among a_9[2] = +{ +/* 0 */ { 3, s_9_0, -1, 1, 0}, +/* 1 */ { 4, s_9_1, 0, -1, 0} +}; + +static unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; + +static unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; + +static symbol s_0[] = { 'k' }; +static symbol s_1[] = { 'k', 's', 'e' }; +static symbol s_2[] = { 'k', 's', 'i' }; +static symbol s_3[] = { 'i' }; +static symbol s_4[] = { 'a' }; +static symbol s_5[] = { 'e' }; +static symbol s_6[] = { 'i' }; +static symbol s_7[] = { 'o' }; +static symbol s_8[] = { 0xC3, 0xA4 }; +static symbol s_9[] = { 0xC3, 0xB6 }; +static symbol s_10[] = { 'i', 'e' }; +static symbol s_11[] = { 'e' }; +static symbol s_12[] = { 'p', 'o' }; +static symbol s_13[] = { 't' }; +static symbol s_14[] = { 'p', 'o' }; +static symbol s_15[] = { 'j' }; +static symbol s_16[] = { 'o' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'o' }; +static symbol s_19[] = { 'j' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + while(1) { /* goto, line 46 */ + int c = z->c; + if (!(in_grouping_U(z, g_V1, 97, 246))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* goto, line 46 */ + } + } + while(1) { /* gopast, line 46 */ + if (!(out_grouping_U(z, g_V1, 97, 246))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 46 */ + } + } + z->I[0] = z->c; /* setmark p1, line 46 */ + while(1) { /* goto, line 47 */ + int c = z->c; + if (!(in_grouping_U(z, g_V1, 97, 246))) goto lab2; + z->c = c; + break; + lab2: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* goto, line 47 */ + } + } + while(1) { /* gopast, line 47 */ + if (!(out_grouping_U(z, g_V1, 97, 246))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 47 */ + } + } + z->I[1] = z->c; /* setmark p2, line 47 */ + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_particle_etc(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 55 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 55 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 55 */ + among_var = find_among_b(z, a_0, 10); /* substring, line 55 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 55 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(in_grouping_b_U(z, g_particle_end, 97, 246))) return 0; + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 64 */ + if (ret < 0) return ret; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 66 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_possessive(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 69 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 69 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 69 */ + among_var = find_among_b(z, a_4, 9); /* substring, line 69 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 69 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 72 */ + if (!(eq_s_b(z, 1, s_0))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 72 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 74 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 74 */ + if (!(eq_s_b(z, 3, s_1))) return 0; + z->bra = z->c; /* ], line 74 */ + { int ret; + ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 78 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */ + { int ret; + ret = slice_del(z); /* delete, line 81 */ + if (ret < 0) return ret; + } + break; + case 5: + if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */ + { int ret; + ret = slice_del(z); /* delete, line 84 */ + if (ret < 0) return ret; + } + break; + case 6: + if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */ + { int ret; + ret = slice_del(z); /* delete, line 86 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_LONG(struct SN_env * z) { + if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */ + return 1; +} + +static int r_VI(struct SN_env * z) { + if (!(eq_s_b(z, 1, s_3))) return 0; + if (!(in_grouping_b_U(z, g_V2, 97, 246))) return 0; + return 1; +} + +static int r_case_ending(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 96 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 96 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 96 */ + among_var = find_among_b(z, a_6, 30); /* substring, line 96 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 96 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(eq_s_b(z, 1, s_4))) return 0; + break; + case 2: + if (!(eq_s_b(z, 1, s_5))) return 0; + break; + case 3: + if (!(eq_s_b(z, 1, s_6))) return 0; + break; + case 4: + if (!(eq_s_b(z, 1, s_7))) return 0; + break; + case 5: + if (!(eq_s_b(z, 2, s_8))) return 0; + break; + case 6: + if (!(eq_s_b(z, 2, s_9))) return 0; + break; + case 7: + { int m = z->l - z->c; (void) m; /* try, line 111 */ + { int m = z->l - z->c; (void) m; /* and, line 113 */ + { int m = z->l - z->c; (void) m; /* or, line 112 */ + { int ret = r_LONG(z); + if (ret == 0) goto lab2; /* call LONG, line 111 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m; goto lab0; } + } + lab1: + z->c = z->l - m; + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) { z->c = z->l - m; goto lab0; } + z->c = c; /* next, line 113 */ + } + } + z->bra = z->c; /* ], line 113 */ + lab0: + ; + } + break; + case 8: + if (!(in_grouping_b_U(z, g_V1, 97, 246))) return 0; + if (!(out_grouping_b_U(z, g_V1, 97, 246))) return 0; + break; + case 9: + if (!(eq_s_b(z, 1, s_11))) return 0; + break; + } + { int ret; + ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set ending_removed, line 139 */ + return 1; +} + +static int r_other_endings(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 142 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[1]) return 0; + z->c = z->I[1]; /* tomark, line 142 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 142 */ + among_var = find_among_b(z, a_7, 14); /* substring, line 142 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 142 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 146 */ + if (!(eq_s_b(z, 2, s_12))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_i_plural(struct SN_env * z) { + { int m3; /* setlimit, line 154 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 154 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 154 */ + if (!(find_among_b(z, a_8, 2))) { z->lb = m3; return 0; } /* substring, line 154 */ + z->bra = z->c; /* ], line 154 */ + z->lb = m3; + } + { int ret; + ret = slice_del(z); /* delete, line 158 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_t_plural(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 161 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 161 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 162 */ + if (!(eq_s_b(z, 1, s_13))) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 162 */ + { int m_test = z->l - z->c; /* test, line 162 */ + if (!(in_grouping_b_U(z, g_V1, 97, 246))) { z->lb = m3; return 0; } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + z->lb = m3; + } + { int m3; /* setlimit, line 165 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[1]) return 0; + z->c = z->I[1]; /* tomark, line 165 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 165 */ + among_var = find_among_b(z, a_9, 2); /* substring, line 165 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 165 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* not, line 167 */ + if (!(eq_s_b(z, 2, s_14))) goto lab0; + return 0; + lab0: + z->c = z->l - m; + } + break; + } + { int ret; + ret = slice_del(z); /* delete, line 170 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_tidy(struct SN_env * z) { + { int m3; /* setlimit, line 173 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 173 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 174 */ + { int m = z->l - z->c; (void) m; /* and, line 174 */ + { int ret = r_LONG(z); + if (ret == 0) goto lab0; /* call LONG, line 174 */ + if (ret < 0) return ret; + } + z->c = z->l - m; + z->ket = z->c; /* [, line 174 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) goto lab0; + z->c = c; /* next, line 174 */ + } + z->bra = z->c; /* ], line 174 */ + { int ret; + ret = slice_del(z); /* delete, line 174 */ + if (ret < 0) return ret; + } + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 175 */ + z->ket = z->c; /* [, line 175 */ + if (!(in_grouping_b_U(z, g_AEI, 97, 228))) goto lab1; + z->bra = z->c; /* ], line 175 */ + if (!(out_grouping_b_U(z, g_V1, 97, 246))) goto lab1; + { int ret; + ret = slice_del(z); /* delete, line 175 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 176 */ + z->ket = z->c; /* [, line 176 */ + if (!(eq_s_b(z, 1, s_15))) goto lab2; + z->bra = z->c; /* ], line 176 */ + { int m = z->l - z->c; (void) m; /* or, line 176 */ + if (!(eq_s_b(z, 1, s_16))) goto lab4; + goto lab3; + lab4: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_17))) goto lab2; + } + lab3: + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 177 */ + z->ket = z->c; /* [, line 177 */ + if (!(eq_s_b(z, 1, s_18))) goto lab5; + z->bra = z->c; /* ], line 177 */ + if (!(eq_s_b(z, 1, s_19))) goto lab5; + { int ret; + ret = slice_del(z); /* delete, line 177 */ + if (ret < 0) return ret; + } + lab5: + z->c = z->l - m; + } + z->lb = m3; + } + while(1) { /* goto, line 179 */ + int m = z->l - z->c; (void) m; + if (!(out_grouping_b_U(z, g_V1, 97, 246))) goto lab6; + z->c = z->l - m; + break; + lab6: + z->c = z->l - m; + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* goto, line 179 */ + } + } + z->ket = z->c; /* [, line 179 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 179 */ + } + z->bra = z->c; /* ], line 179 */ + z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */ + if (z->S[0] == 0) return -1; /* -> x, line 179 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */ + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int finnish_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 185 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 185 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->B[0] = 0; /* unset ending_removed, line 186 */ + z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + + { int m = z->l - z->c; (void) m; /* do, line 188 */ + { int ret = r_particle_etc(z); + if (ret == 0) goto lab1; /* call particle_etc, line 188 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 189 */ + { int ret = r_possessive(z); + if (ret == 0) goto lab2; /* call possessive, line 189 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 190 */ + { int ret = r_case_ending(z); + if (ret == 0) goto lab3; /* call case_ending, line 190 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 191 */ + { int ret = r_other_endings(z); + if (ret == 0) goto lab4; /* call other_endings, line 191 */ + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* or, line 192 */ + if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */ + { int m = z->l - z->c; (void) m; /* do, line 192 */ + { int ret = r_i_plural(z); + if (ret == 0) goto lab7; /* call i_plural, line 192 */ + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m; + } + goto lab5; + lab6: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 192 */ + { int ret = r_t_plural(z); + if (ret == 0) goto lab8; /* call t_plural, line 192 */ + if (ret < 0) return ret; + } + lab8: + z->c = z->l - m; + } + } +lab5: + { int m = z->l - z->c; (void) m; /* do, line 193 */ + { int ret = r_tidy(z); + if (ret == 0) goto lab9; /* call tidy, line 193 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * finnish_UTF_8_create_env(void) { return SN_create_env(1, 2, 1); } + +extern void finnish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.h new file mode 100644 index 00000000000..d2f2fd96383 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_finnish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * finnish_UTF_8_create_env(void); +extern void finnish_UTF_8_close_env(struct SN_env * z); + +extern int finnish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.c new file mode 100644 index 00000000000..1f95c7ceec6 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.c @@ -0,0 +1,1296 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int french_UTF_8_stem(struct SN_env * z); +static int r_un_accent(struct SN_env * z); +static int r_un_double(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_i_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * french_UTF_8_create_env(void); +extern void french_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 'I' }; +static symbol s_0_2[1] = { 'U' }; +static symbol s_0_3[1] = { 'Y' }; + +static struct among a_0[4] = +{ +/* 0 */ { 0, 0, -1, 4, 0}, +/* 1 */ { 1, s_0_1, 0, 1, 0}, +/* 2 */ { 1, s_0_2, 0, 2, 0}, +/* 3 */ { 1, s_0_3, 0, 3, 0} +}; + +static symbol s_1_0[3] = { 'i', 'q', 'U' }; +static symbol s_1_1[3] = { 'a', 'b', 'l' }; +static symbol s_1_2[4] = { 'I', 0xC3, 0xA8, 'r' }; +static symbol s_1_3[4] = { 'i', 0xC3, 0xA8, 'r' }; +static symbol s_1_4[3] = { 'e', 'u', 's' }; +static symbol s_1_5[2] = { 'i', 'v' }; + +static struct among a_1[6] = +{ +/* 0 */ { 3, s_1_0, -1, 3, 0}, +/* 1 */ { 3, s_1_1, -1, 3, 0}, +/* 2 */ { 4, s_1_2, -1, 4, 0}, +/* 3 */ { 4, s_1_3, -1, 4, 0}, +/* 4 */ { 3, s_1_4, -1, 2, 0}, +/* 5 */ { 2, s_1_5, -1, 1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'c' }; +static symbol s_2_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_2_2[2] = { 'i', 'v' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, 2, 0}, +/* 1 */ { 4, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 3, 0} +}; + +static symbol s_3_0[4] = { 'i', 'q', 'U', 'e' }; +static symbol s_3_1[6] = { 'a', 't', 'r', 'i', 'c', 'e' }; +static symbol s_3_2[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_3_3[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_3_4[5] = { 'l', 'o', 'g', 'i', 'e' }; +static symbol s_3_5[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_3_6[4] = { 'i', 's', 'm', 'e' }; +static symbol s_3_7[4] = { 'e', 'u', 's', 'e' }; +static symbol s_3_8[4] = { 'i', 's', 't', 'e' }; +static symbol s_3_9[3] = { 'i', 'v', 'e' }; +static symbol s_3_10[2] = { 'i', 'f' }; +static symbol s_3_11[5] = { 'u', 's', 'i', 'o', 'n' }; +static symbol s_3_12[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_13[5] = { 'u', 't', 'i', 'o', 'n' }; +static symbol s_3_14[5] = { 'a', 't', 'e', 'u', 'r' }; +static symbol s_3_15[5] = { 'i', 'q', 'U', 'e', 's' }; +static symbol s_3_16[7] = { 'a', 't', 'r', 'i', 'c', 'e', 's' }; +static symbol s_3_17[5] = { 'a', 'n', 'c', 'e', 's' }; +static symbol s_3_18[5] = { 'e', 'n', 'c', 'e', 's' }; +static symbol s_3_19[6] = { 'l', 'o', 'g', 'i', 'e', 's' }; +static symbol s_3_20[5] = { 'a', 'b', 'l', 'e', 's' }; +static symbol s_3_21[5] = { 'i', 's', 'm', 'e', 's' }; +static symbol s_3_22[5] = { 'e', 'u', 's', 'e', 's' }; +static symbol s_3_23[5] = { 'i', 's', 't', 'e', 's' }; +static symbol s_3_24[4] = { 'i', 'v', 'e', 's' }; +static symbol s_3_25[3] = { 'i', 'f', 's' }; +static symbol s_3_26[6] = { 'u', 's', 'i', 'o', 'n', 's' }; +static symbol s_3_27[6] = { 'a', 't', 'i', 'o', 'n', 's' }; +static symbol s_3_28[6] = { 'u', 't', 'i', 'o', 'n', 's' }; +static symbol s_3_29[6] = { 'a', 't', 'e', 'u', 'r', 's' }; +static symbol s_3_30[5] = { 'm', 'e', 'n', 't', 's' }; +static symbol s_3_31[6] = { 'e', 'm', 'e', 'n', 't', 's' }; +static symbol s_3_32[9] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't', 's' }; +static symbol s_3_33[5] = { 'i', 't', 0xC3, 0xA9, 's' }; +static symbol s_3_34[4] = { 'm', 'e', 'n', 't' }; +static symbol s_3_35[5] = { 'e', 'm', 'e', 'n', 't' }; +static symbol s_3_36[8] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't' }; +static symbol s_3_37[6] = { 'a', 'm', 'm', 'e', 'n', 't' }; +static symbol s_3_38[6] = { 'e', 'm', 'm', 'e', 'n', 't' }; +static symbol s_3_39[3] = { 'a', 'u', 'x' }; +static symbol s_3_40[4] = { 'e', 'a', 'u', 'x' }; +static symbol s_3_41[3] = { 'e', 'u', 'x' }; +static symbol s_3_42[4] = { 'i', 't', 0xC3, 0xA9 }; + +static struct among a_3[43] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 6, s_3_1, -1, 2, 0}, +/* 2 */ { 4, s_3_2, -1, 1, 0}, +/* 3 */ { 4, s_3_3, -1, 5, 0}, +/* 4 */ { 5, s_3_4, -1, 3, 0}, +/* 5 */ { 4, s_3_5, -1, 1, 0}, +/* 6 */ { 4, s_3_6, -1, 1, 0}, +/* 7 */ { 4, s_3_7, -1, 11, 0}, +/* 8 */ { 4, s_3_8, -1, 1, 0}, +/* 9 */ { 3, s_3_9, -1, 8, 0}, +/* 10 */ { 2, s_3_10, -1, 8, 0}, +/* 11 */ { 5, s_3_11, -1, 4, 0}, +/* 12 */ { 5, s_3_12, -1, 2, 0}, +/* 13 */ { 5, s_3_13, -1, 4, 0}, +/* 14 */ { 5, s_3_14, -1, 2, 0}, +/* 15 */ { 5, s_3_15, -1, 1, 0}, +/* 16 */ { 7, s_3_16, -1, 2, 0}, +/* 17 */ { 5, s_3_17, -1, 1, 0}, +/* 18 */ { 5, s_3_18, -1, 5, 0}, +/* 19 */ { 6, s_3_19, -1, 3, 0}, +/* 20 */ { 5, s_3_20, -1, 1, 0}, +/* 21 */ { 5, s_3_21, -1, 1, 0}, +/* 22 */ { 5, s_3_22, -1, 11, 0}, +/* 23 */ { 5, s_3_23, -1, 1, 0}, +/* 24 */ { 4, s_3_24, -1, 8, 0}, +/* 25 */ { 3, s_3_25, -1, 8, 0}, +/* 26 */ { 6, s_3_26, -1, 4, 0}, +/* 27 */ { 6, s_3_27, -1, 2, 0}, +/* 28 */ { 6, s_3_28, -1, 4, 0}, +/* 29 */ { 6, s_3_29, -1, 2, 0}, +/* 30 */ { 5, s_3_30, -1, 15, 0}, +/* 31 */ { 6, s_3_31, 30, 6, 0}, +/* 32 */ { 9, s_3_32, 31, 12, 0}, +/* 33 */ { 5, s_3_33, -1, 7, 0}, +/* 34 */ { 4, s_3_34, -1, 15, 0}, +/* 35 */ { 5, s_3_35, 34, 6, 0}, +/* 36 */ { 8, s_3_36, 35, 12, 0}, +/* 37 */ { 6, s_3_37, 34, 13, 0}, +/* 38 */ { 6, s_3_38, 34, 14, 0}, +/* 39 */ { 3, s_3_39, -1, 10, 0}, +/* 40 */ { 4, s_3_40, 39, 9, 0}, +/* 41 */ { 3, s_3_41, -1, 1, 0}, +/* 42 */ { 4, s_3_42, -1, 7, 0} +}; + +static symbol s_4_0[3] = { 'i', 'r', 'a' }; +static symbol s_4_1[2] = { 'i', 'e' }; +static symbol s_4_2[4] = { 'i', 's', 's', 'e' }; +static symbol s_4_3[7] = { 'i', 's', 's', 'a', 'n', 't', 'e' }; +static symbol s_4_4[1] = { 'i' }; +static symbol s_4_5[4] = { 'i', 'r', 'a', 'i' }; +static symbol s_4_6[2] = { 'i', 'r' }; +static symbol s_4_7[4] = { 'i', 'r', 'a', 's' }; +static symbol s_4_8[3] = { 'i', 'e', 's' }; +static symbol s_4_9[5] = { 0xC3, 0xAE, 'm', 'e', 's' }; +static symbol s_4_10[5] = { 'i', 's', 's', 'e', 's' }; +static symbol s_4_11[8] = { 'i', 's', 's', 'a', 'n', 't', 'e', 's' }; +static symbol s_4_12[5] = { 0xC3, 0xAE, 't', 'e', 's' }; +static symbol s_4_13[2] = { 'i', 's' }; +static symbol s_4_14[5] = { 'i', 'r', 'a', 'i', 's' }; +static symbol s_4_15[6] = { 'i', 's', 's', 'a', 'i', 's' }; +static symbol s_4_16[6] = { 'i', 'r', 'i', 'o', 'n', 's' }; +static symbol s_4_17[7] = { 'i', 's', 's', 'i', 'o', 'n', 's' }; +static symbol s_4_18[5] = { 'i', 'r', 'o', 'n', 's' }; +static symbol s_4_19[6] = { 'i', 's', 's', 'o', 'n', 's' }; +static symbol s_4_20[7] = { 'i', 's', 's', 'a', 'n', 't', 's' }; +static symbol s_4_21[2] = { 'i', 't' }; +static symbol s_4_22[5] = { 'i', 'r', 'a', 'i', 't' }; +static symbol s_4_23[6] = { 'i', 's', 's', 'a', 'i', 't' }; +static symbol s_4_24[6] = { 'i', 's', 's', 'a', 'n', 't' }; +static symbol s_4_25[7] = { 'i', 'r', 'a', 'I', 'e', 'n', 't' }; +static symbol s_4_26[8] = { 'i', 's', 's', 'a', 'I', 'e', 'n', 't' }; +static symbol s_4_27[5] = { 'i', 'r', 'e', 'n', 't' }; +static symbol s_4_28[6] = { 'i', 's', 's', 'e', 'n', 't' }; +static symbol s_4_29[5] = { 'i', 'r', 'o', 'n', 't' }; +static symbol s_4_30[3] = { 0xC3, 0xAE, 't' }; +static symbol s_4_31[5] = { 'i', 'r', 'i', 'e', 'z' }; +static symbol s_4_32[6] = { 'i', 's', 's', 'i', 'e', 'z' }; +static symbol s_4_33[4] = { 'i', 'r', 'e', 'z' }; +static symbol s_4_34[5] = { 'i', 's', 's', 'e', 'z' }; + +static struct among a_4[35] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 1, 0}, +/* 2 */ { 4, s_4_2, -1, 1, 0}, +/* 3 */ { 7, s_4_3, -1, 1, 0}, +/* 4 */ { 1, s_4_4, -1, 1, 0}, +/* 5 */ { 4, s_4_5, 4, 1, 0}, +/* 6 */ { 2, s_4_6, -1, 1, 0}, +/* 7 */ { 4, s_4_7, -1, 1, 0}, +/* 8 */ { 3, s_4_8, -1, 1, 0}, +/* 9 */ { 5, s_4_9, -1, 1, 0}, +/* 10 */ { 5, s_4_10, -1, 1, 0}, +/* 11 */ { 8, s_4_11, -1, 1, 0}, +/* 12 */ { 5, s_4_12, -1, 1, 0}, +/* 13 */ { 2, s_4_13, -1, 1, 0}, +/* 14 */ { 5, s_4_14, 13, 1, 0}, +/* 15 */ { 6, s_4_15, 13, 1, 0}, +/* 16 */ { 6, s_4_16, -1, 1, 0}, +/* 17 */ { 7, s_4_17, -1, 1, 0}, +/* 18 */ { 5, s_4_18, -1, 1, 0}, +/* 19 */ { 6, s_4_19, -1, 1, 0}, +/* 20 */ { 7, s_4_20, -1, 1, 0}, +/* 21 */ { 2, s_4_21, -1, 1, 0}, +/* 22 */ { 5, s_4_22, 21, 1, 0}, +/* 23 */ { 6, s_4_23, 21, 1, 0}, +/* 24 */ { 6, s_4_24, -1, 1, 0}, +/* 25 */ { 7, s_4_25, -1, 1, 0}, +/* 26 */ { 8, s_4_26, -1, 1, 0}, +/* 27 */ { 5, s_4_27, -1, 1, 0}, +/* 28 */ { 6, s_4_28, -1, 1, 0}, +/* 29 */ { 5, s_4_29, -1, 1, 0}, +/* 30 */ { 3, s_4_30, -1, 1, 0}, +/* 31 */ { 5, s_4_31, -1, 1, 0}, +/* 32 */ { 6, s_4_32, -1, 1, 0}, +/* 33 */ { 4, s_4_33, -1, 1, 0}, +/* 34 */ { 5, s_4_34, -1, 1, 0} +}; + +static symbol s_5_0[1] = { 'a' }; +static symbol s_5_1[3] = { 'e', 'r', 'a' }; +static symbol s_5_2[4] = { 'a', 's', 's', 'e' }; +static symbol s_5_3[4] = { 'a', 'n', 't', 'e' }; +static symbol s_5_4[3] = { 0xC3, 0xA9, 'e' }; +static symbol s_5_5[2] = { 'a', 'i' }; +static symbol s_5_6[4] = { 'e', 'r', 'a', 'i' }; +static symbol s_5_7[2] = { 'e', 'r' }; +static symbol s_5_8[2] = { 'a', 's' }; +static symbol s_5_9[4] = { 'e', 'r', 'a', 's' }; +static symbol s_5_10[5] = { 0xC3, 0xA2, 'm', 'e', 's' }; +static symbol s_5_11[5] = { 'a', 's', 's', 'e', 's' }; +static symbol s_5_12[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_5_13[5] = { 0xC3, 0xA2, 't', 'e', 's' }; +static symbol s_5_14[4] = { 0xC3, 0xA9, 'e', 's' }; +static symbol s_5_15[3] = { 'a', 'i', 's' }; +static symbol s_5_16[5] = { 'e', 'r', 'a', 'i', 's' }; +static symbol s_5_17[4] = { 'i', 'o', 'n', 's' }; +static symbol s_5_18[6] = { 'e', 'r', 'i', 'o', 'n', 's' }; +static symbol s_5_19[7] = { 'a', 's', 's', 'i', 'o', 'n', 's' }; +static symbol s_5_20[5] = { 'e', 'r', 'o', 'n', 's' }; +static symbol s_5_21[4] = { 'a', 'n', 't', 's' }; +static symbol s_5_22[3] = { 0xC3, 0xA9, 's' }; +static symbol s_5_23[3] = { 'a', 'i', 't' }; +static symbol s_5_24[5] = { 'e', 'r', 'a', 'i', 't' }; +static symbol s_5_25[3] = { 'a', 'n', 't' }; +static symbol s_5_26[5] = { 'a', 'I', 'e', 'n', 't' }; +static symbol s_5_27[7] = { 'e', 'r', 'a', 'I', 'e', 'n', 't' }; +static symbol s_5_28[6] = { 0xC3, 0xA8, 'r', 'e', 'n', 't' }; +static symbol s_5_29[6] = { 'a', 's', 's', 'e', 'n', 't' }; +static symbol s_5_30[5] = { 'e', 'r', 'o', 'n', 't' }; +static symbol s_5_31[3] = { 0xC3, 0xA2, 't' }; +static symbol s_5_32[2] = { 'e', 'z' }; +static symbol s_5_33[3] = { 'i', 'e', 'z' }; +static symbol s_5_34[5] = { 'e', 'r', 'i', 'e', 'z' }; +static symbol s_5_35[6] = { 'a', 's', 's', 'i', 'e', 'z' }; +static symbol s_5_36[4] = { 'e', 'r', 'e', 'z' }; +static symbol s_5_37[2] = { 0xC3, 0xA9 }; + +static struct among a_5[38] = +{ +/* 0 */ { 1, s_5_0, -1, 3, 0}, +/* 1 */ { 3, s_5_1, 0, 2, 0}, +/* 2 */ { 4, s_5_2, -1, 3, 0}, +/* 3 */ { 4, s_5_3, -1, 3, 0}, +/* 4 */ { 3, s_5_4, -1, 2, 0}, +/* 5 */ { 2, s_5_5, -1, 3, 0}, +/* 6 */ { 4, s_5_6, 5, 2, 0}, +/* 7 */ { 2, s_5_7, -1, 2, 0}, +/* 8 */ { 2, s_5_8, -1, 3, 0}, +/* 9 */ { 4, s_5_9, 8, 2, 0}, +/* 10 */ { 5, s_5_10, -1, 3, 0}, +/* 11 */ { 5, s_5_11, -1, 3, 0}, +/* 12 */ { 5, s_5_12, -1, 3, 0}, +/* 13 */ { 5, s_5_13, -1, 3, 0}, +/* 14 */ { 4, s_5_14, -1, 2, 0}, +/* 15 */ { 3, s_5_15, -1, 3, 0}, +/* 16 */ { 5, s_5_16, 15, 2, 0}, +/* 17 */ { 4, s_5_17, -1, 1, 0}, +/* 18 */ { 6, s_5_18, 17, 2, 0}, +/* 19 */ { 7, s_5_19, 17, 3, 0}, +/* 20 */ { 5, s_5_20, -1, 2, 0}, +/* 21 */ { 4, s_5_21, -1, 3, 0}, +/* 22 */ { 3, s_5_22, -1, 2, 0}, +/* 23 */ { 3, s_5_23, -1, 3, 0}, +/* 24 */ { 5, s_5_24, 23, 2, 0}, +/* 25 */ { 3, s_5_25, -1, 3, 0}, +/* 26 */ { 5, s_5_26, -1, 3, 0}, +/* 27 */ { 7, s_5_27, 26, 2, 0}, +/* 28 */ { 6, s_5_28, -1, 2, 0}, +/* 29 */ { 6, s_5_29, -1, 3, 0}, +/* 30 */ { 5, s_5_30, -1, 2, 0}, +/* 31 */ { 3, s_5_31, -1, 3, 0}, +/* 32 */ { 2, s_5_32, -1, 2, 0}, +/* 33 */ { 3, s_5_33, 32, 2, 0}, +/* 34 */ { 5, s_5_34, 33, 2, 0}, +/* 35 */ { 6, s_5_35, 33, 3, 0}, +/* 36 */ { 4, s_5_36, 32, 2, 0}, +/* 37 */ { 2, s_5_37, -1, 2, 0} +}; + +static symbol s_6_0[1] = { 'e' }; +static symbol s_6_1[5] = { 'I', 0xC3, 0xA8, 'r', 'e' }; +static symbol s_6_2[5] = { 'i', 0xC3, 0xA8, 'r', 'e' }; +static symbol s_6_3[3] = { 'i', 'o', 'n' }; +static symbol s_6_4[3] = { 'I', 'e', 'r' }; +static symbol s_6_5[3] = { 'i', 'e', 'r' }; +static symbol s_6_6[2] = { 0xC3, 0xAB }; + +static struct among a_6[7] = +{ +/* 0 */ { 1, s_6_0, -1, 3, 0}, +/* 1 */ { 5, s_6_1, 0, 2, 0}, +/* 2 */ { 5, s_6_2, 0, 2, 0}, +/* 3 */ { 3, s_6_3, -1, 1, 0}, +/* 4 */ { 3, s_6_4, -1, 2, 0}, +/* 5 */ { 3, s_6_5, -1, 2, 0}, +/* 6 */ { 2, s_6_6, -1, 4, 0} +}; + +static symbol s_7_0[3] = { 'e', 'l', 'l' }; +static symbol s_7_1[4] = { 'e', 'i', 'l', 'l' }; +static symbol s_7_2[3] = { 'e', 'n', 'n' }; +static symbol s_7_3[3] = { 'o', 'n', 'n' }; +static symbol s_7_4[3] = { 'e', 't', 't' }; + +static struct among a_7[5] = +{ +/* 0 */ { 3, s_7_0, -1, -1, 0}, +/* 1 */ { 4, s_7_1, -1, -1, 0}, +/* 2 */ { 3, s_7_2, -1, -1, 0}, +/* 3 */ { 3, s_7_3, -1, -1, 0}, +/* 4 */ { 3, s_7_4, -1, -1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 }; + +static unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; + +static symbol s_0[] = { 'u' }; +static symbol s_1[] = { 'U' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'I' }; +static symbol s_4[] = { 'y' }; +static symbol s_5[] = { 'Y' }; +static symbol s_6[] = { 'y' }; +static symbol s_7[] = { 'Y' }; +static symbol s_8[] = { 'q' }; +static symbol s_9[] = { 'u' }; +static symbol s_10[] = { 'U' }; +static symbol s_11[] = { 'i' }; +static symbol s_12[] = { 'u' }; +static symbol s_13[] = { 'y' }; +static symbol s_14[] = { 'i', 'c' }; +static symbol s_15[] = { 'i', 'q', 'U' }; +static symbol s_16[] = { 'l', 'o', 'g' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'e', 'n', 't' }; +static symbol s_19[] = { 'a', 't' }; +static symbol s_20[] = { 'e', 'u', 'x' }; +static symbol s_21[] = { 'i' }; +static symbol s_22[] = { 'a', 'b', 'l' }; +static symbol s_23[] = { 'i', 'q', 'U' }; +static symbol s_24[] = { 'a', 't' }; +static symbol s_25[] = { 'i', 'c' }; +static symbol s_26[] = { 'i', 'q', 'U' }; +static symbol s_27[] = { 'e', 'a', 'u' }; +static symbol s_28[] = { 'a', 'l' }; +static symbol s_29[] = { 'e', 'u', 'x' }; +static symbol s_30[] = { 'a', 'n', 't' }; +static symbol s_31[] = { 'e', 'n', 't' }; +static symbol s_32[] = { 'e' }; +static symbol s_33[] = { 's' }; +static symbol s_34[] = { 's' }; +static symbol s_35[] = { 't' }; +static symbol s_36[] = { 'i' }; +static symbol s_37[] = { 'g', 'u' }; +static symbol s_38[] = { 0xC3, 0xA9 }; +static symbol s_39[] = { 0xC3, 0xA8 }; +static symbol s_40[] = { 'e' }; +static symbol s_41[] = { 'Y' }; +static symbol s_42[] = { 'i' }; +static symbol s_43[] = { 0xC3, 0xA7 }; +static symbol s_44[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { + while(1) { /* repeat, line 38 */ + int c = z->c; + while(1) { /* goto, line 38 */ + int c = z->c; + { int c = z->c; /* or, line 44 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab3; + z->bra = z->c; /* [, line 40 */ + { int c = z->c; /* or, line 40 */ + if (!(eq_s(z, 1, s_0))) goto lab5; + z->ket = z->c; /* ], line 40 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab5; + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 40 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = c; + if (!(eq_s(z, 1, s_2))) goto lab6; + z->ket = z->c; /* ], line 41 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab6; + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 41 */ + if (ret < 0) return ret; + } + goto lab4; + lab6: + z->c = c; + if (!(eq_s(z, 1, s_4))) goto lab3; + z->ket = z->c; /* ], line 42 */ + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 42 */ + if (ret < 0) return ret; + } + } + lab4: + goto lab2; + lab3: + z->c = c; + z->bra = z->c; /* [, line 45 */ + if (!(eq_s(z, 1, s_6))) goto lab7; + z->ket = z->c; /* ], line 45 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab7; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 45 */ + if (ret < 0) return ret; + } + goto lab2; + lab7: + z->c = c; + if (!(eq_s(z, 1, s_8))) goto lab1; + z->bra = z->c; /* [, line 47 */ + if (!(eq_s(z, 1, s_9))) goto lab1; + z->ket = z->c; /* ], line 47 */ + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 47 */ + if (ret < 0) return ret; + } + } + lab2: + z->c = c; + break; + lab1: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* goto, line 38 */ + } + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 56 */ + { int c = z->c; /* or, line 57 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab2; + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab2; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* next, line 57 */ + } + goto lab1; + lab2: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 57 */ + } + while(1) { /* gopast, line 57 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 57 */ + } + } + } + lab1: + z->I[0] = z->c; /* setmark pV, line 58 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 60 */ + while(1) { /* gopast, line 61 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 61 */ + } + } + while(1) { /* gopast, line 61 */ + if (!(out_grouping_U(z, g_v, 97, 251))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 61 */ + } + } + z->I[1] = z->c; /* setmark p1, line 61 */ + while(1) { /* gopast, line 62 */ + if (!(in_grouping_U(z, g_v, 97, 251))) goto lab7; + break; + lab7: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 62 */ + } + } + while(1) { /* gopast, line 62 */ + if (!(out_grouping_U(z, g_v, 97, 251))) goto lab8; + break; + lab8: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 62 */ + } + } + z->I[2] = z->c; /* setmark p2, line 62 */ + lab4: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 66 */ + int c = z->c; + z->bra = z->c; /* [, line 68 */ + among_var = find_among(z, a_0, 4); /* substring, line 68 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 68 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 70 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 4: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 72 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 83 */ + among_var = find_among_b(z, a_3, 43); /* substring, line 83 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 83 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 87 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 90 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 90 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 91 */ + z->ket = z->c; /* [, line 91 */ + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 91 */ + { int m = z->l - z->c; (void) m; /* or, line 91 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 91 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 91 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_15); /* <-, line 91 */ + if (ret < 0) return ret; + } + } + lab1: + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 95 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_16); /* <-, line 95 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_17); /* <-, line 98 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 101 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 101 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 105 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 105 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 106 */ + z->ket = z->c; /* [, line 107 */ + among_var = find_among_b(z, a_1, 6); /* substring, line 107 */ + if (!(among_var)) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 107 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab3; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 108 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 108 */ + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 108 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 108 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 109 */ + { int ret = r_R2(z); + if (ret == 0) goto lab5; /* call R2, line 109 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 109 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R1, line 109 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 109 */ + if (ret < 0) return ret; + } + } + lab4: + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 111 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call RV, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_21); /* <-, line 113 */ + if (ret < 0) return ret; + } + break; + } + lab3: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 120 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 120 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 121 */ + z->ket = z->c; /* [, line 122 */ + among_var = find_among_b(z, a_2, 3); /* substring, line 122 */ + if (!(among_var)) { z->c = z->l - m; goto lab6; } + z->bra = z->c; /* ], line 122 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab6; } + case 1: + { int m = z->l - z->c; (void) m; /* or, line 123 */ + { int ret = r_R2(z); + if (ret == 0) goto lab8; /* call R2, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + goto lab7; + lab8: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_22); /* <-, line 123 */ + if (ret < 0) return ret; + } + } + lab7: + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 124 */ + { int ret = r_R2(z); + if (ret == 0) goto lab10; /* call R2, line 124 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 124 */ + if (ret < 0) return ret; + } + goto lab9; + lab10: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_23); /* <-, line 124 */ + if (ret < 0) return ret; + } + } + lab9: + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab6; } /* call R2, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + break; + } + lab6: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 132 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 132 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 133 */ + z->ket = z->c; /* [, line 133 */ + if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m; goto lab11; } + z->bra = z->c; /* ], line 133 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab11; } /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 133 */ + if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m; goto lab11; } + z->bra = z->c; /* ], line 133 */ + { int m = z->l - z->c; (void) m; /* or, line 133 */ + { int ret = r_R2(z); + if (ret == 0) goto lab13; /* call R2, line 133 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + goto lab12; + lab13: + z->c = z->l - m; + { int ret; + ret = slice_from_s(z, 3, s_26); /* <-, line 133 */ + if (ret < 0) return ret; + } + } + lab12: + lab11: + ; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 3, s_27); /* <-, line 135 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 136 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_28); /* <-, line 136 */ + if (ret < 0) return ret; + } + break; + case 11: + { int m = z->l - z->c; (void) m; /* or, line 138 */ + { int ret = r_R2(z); + if (ret == 0) goto lab15; /* call R2, line 138 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + goto lab14; + lab15: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 138 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_29); /* <-, line 138 */ + if (ret < 0) return ret; + } + } + lab14: + break; + case 12: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 141 */ + if (ret < 0) return ret; + } + if (!(out_grouping_b_U(z, g_v, 97, 251))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 141 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 146 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_30); /* <-, line 146 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 146 */ + break; + case 14: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 147 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_31); /* <-, line 147 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 147 */ + break; + case 15: + { int m_test = z->l - z->c; /* test, line 149 */ + if (!(in_grouping_b_U(z, g_v, 97, 251))) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 149 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 149 */ + if (ret < 0) return ret; + } + return 0; /* fail, line 149 */ + break; + } + return 1; +} + +static int r_i_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 154 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 154 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 155 */ + among_var = find_among_b(z, a_4, 35); /* substring, line 155 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 155 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + if (!(out_grouping_b_U(z, g_v, 97, 251))) { z->lb = m3; return 0; } + { int ret; + ret = slice_del(z); /* delete, line 161 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 165 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 165 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 166 */ + among_var = find_among_b(z, a_5, 38); /* substring, line 166 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 166 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->lb = m3; return 0; } /* call R2, line 168 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 168 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 181 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 182 */ + z->ket = z->c; /* [, line 182 */ + if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 182 */ + { int ret; + ret = slice_del(z); /* delete, line 182 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* try, line 190 */ + z->ket = z->c; /* [, line 190 */ + if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 190 */ + { int m_test = z->l - z->c; /* test, line 190 */ + if (!(out_grouping_b_U(z, g_keep_with_s, 97, 232))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 190 */ + if (ret < 0) return ret; + } + lab0: + ; + } + { int m3; /* setlimit, line 191 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 191 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 192 */ + among_var = find_among_b(z, a_6, 7); /* substring, line 192 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 192 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->lb = m3; return 0; } /* call R2, line 193 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* or, line 193 */ + if (!(eq_s_b(z, 1, s_34))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_35))) { z->lb = m3; return 0; } + } + lab1: + { int ret; + ret = slice_del(z); /* delete, line 193 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_36); /* <-, line 195 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 196 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(eq_s_b(z, 2, s_37))) { z->lb = m3; return 0; } + { int ret; + ret = slice_del(z); /* delete, line 197 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_un_double(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 203 */ + if (!(find_among_b(z, a_7, 5))) return 0; /* among, line 203 */ + z->c = z->l - m_test; + } + z->ket = z->c; /* [, line 203 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 203 */ + } + z->bra = z->c; /* ], line 203 */ + { int ret; + ret = slice_del(z); /* delete, line 203 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_un_accent(struct SN_env * z) { + { int i = 1; + while(1) { /* atleast, line 207 */ + if (!(out_grouping_b_U(z, g_v, 97, 251))) goto lab0; + i--; + continue; + lab0: + break; + } + if (i > 0) return 0; + } + z->ket = z->c; /* [, line 208 */ + { int m = z->l - z->c; (void) m; /* or, line 208 */ + if (!(eq_s_b(z, 2, s_38))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_39))) return 0; + } +lab1: + z->bra = z->c; /* ], line 208 */ + { int ret; + ret = slice_from_s(z, 1, s_40); /* <-, line 208 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int french_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 214 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 214 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 215 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 215 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 216 */ + + { int m = z->l - z->c; (void) m; /* do, line 218 */ + { int m = z->l - z->c; (void) m; /* or, line 228 */ + { int m = z->l - z->c; (void) m; /* and, line 224 */ + { int m = z->l - z->c; (void) m; /* or, line 220 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab6; /* call standard_suffix, line 220 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_i_verb_suffix(z); + if (ret == 0) goto lab7; /* call i_verb_suffix, line 221 */ + if (ret < 0) return ret; + } + goto lab5; + lab7: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab4; /* call verb_suffix, line 222 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* try, line 225 */ + z->ket = z->c; /* [, line 225 */ + { int m = z->l - z->c; (void) m; /* or, line 225 */ + if (!(eq_s_b(z, 1, s_41))) goto lab10; + z->bra = z->c; /* ], line 225 */ + { int ret; + ret = slice_from_s(z, 1, s_42); /* <-, line 225 */ + if (ret < 0) return ret; + } + goto lab9; + lab10: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_43))) { z->c = z->l - m; goto lab8; } + z->bra = z->c; /* ], line 226 */ + { int ret; + ret = slice_from_s(z, 1, s_44); /* <-, line 226 */ + if (ret < 0) return ret; + } + } + lab9: + lab8: + ; + } + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab2; /* call residual_suffix, line 229 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 234 */ + { int ret = r_un_double(z); + if (ret == 0) goto lab11; /* call un_double, line 234 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 235 */ + { int ret = r_un_accent(z); + if (ret == 0) goto lab12; /* call un_accent, line 235 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 237 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab13; /* call postlude, line 237 */ + if (ret < 0) return ret; + } + lab13: + z->c = c; + } + return 1; +} + +extern struct SN_env * french_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void french_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.h new file mode 100644 index 00000000000..08e341846df --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_french.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * french_UTF_8_create_env(void); +extern void french_UTF_8_close_env(struct SN_env * z); + +extern int french_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.c new file mode 100644 index 00000000000..d66a137efea --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.c @@ -0,0 +1,526 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int german_UTF_8_stem(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * german_UTF_8_create_env(void); +extern void german_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[1] = { 'U' }; +static symbol s_0_2[1] = { 'Y' }; +static symbol s_0_3[2] = { 0xC3, 0xA4 }; +static symbol s_0_4[2] = { 0xC3, 0xB6 }; +static symbol s_0_5[2] = { 0xC3, 0xBC }; + +static struct among a_0[6] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 1, s_0_1, 0, 2, 0}, +/* 2 */ { 1, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, 3, 0}, +/* 4 */ { 2, s_0_4, 0, 4, 0}, +/* 5 */ { 2, s_0_5, 0, 5, 0} +}; + +static symbol s_1_0[1] = { 'e' }; +static symbol s_1_1[2] = { 'e', 'm' }; +static symbol s_1_2[2] = { 'e', 'n' }; +static symbol s_1_3[3] = { 'e', 'r', 'n' }; +static symbol s_1_4[2] = { 'e', 'r' }; +static symbol s_1_5[1] = { 's' }; +static symbol s_1_6[2] = { 'e', 's' }; + +static struct among a_1[7] = +{ +/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 3 */ { 3, s_1_3, -1, 1, 0}, +/* 4 */ { 2, s_1_4, -1, 1, 0}, +/* 5 */ { 1, s_1_5, -1, 2, 0}, +/* 6 */ { 2, s_1_6, 5, 1, 0} +}; + +static symbol s_2_0[2] = { 'e', 'n' }; +static symbol s_2_1[2] = { 'e', 'r' }; +static symbol s_2_2[2] = { 's', 't' }; +static symbol s_2_3[3] = { 'e', 's', 't' }; + +static struct among a_2[4] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 2, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 2, 0}, +/* 3 */ { 3, s_2_3, 2, 1, 0} +}; + +static symbol s_3_0[2] = { 'i', 'g' }; +static symbol s_3_1[4] = { 'l', 'i', 'c', 'h' }; + +static struct among a_3[2] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0} +}; + +static symbol s_4_0[3] = { 'e', 'n', 'd' }; +static symbol s_4_1[2] = { 'i', 'g' }; +static symbol s_4_2[3] = { 'u', 'n', 'g' }; +static symbol s_4_3[4] = { 'l', 'i', 'c', 'h' }; +static symbol s_4_4[4] = { 'i', 's', 'c', 'h' }; +static symbol s_4_5[2] = { 'i', 'k' }; +static symbol s_4_6[4] = { 'h', 'e', 'i', 't' }; +static symbol s_4_7[4] = { 'k', 'e', 'i', 't' }; + +static struct among a_4[8] = +{ +/* 0 */ { 3, s_4_0, -1, 1, 0}, +/* 1 */ { 2, s_4_1, -1, 2, 0}, +/* 2 */ { 3, s_4_2, -1, 1, 0}, +/* 3 */ { 4, s_4_3, -1, 3, 0}, +/* 4 */ { 4, s_4_4, -1, 2, 0}, +/* 5 */ { 2, s_4_5, -1, 2, 0}, +/* 6 */ { 4, s_4_6, -1, 3, 0}, +/* 7 */ { 4, s_4_7, -1, 4, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 }; + +static unsigned char g_s_ending[] = { 117, 30, 5 }; + +static unsigned char g_st_ending[] = { 117, 30, 4 }; + +static symbol s_0[] = { 0xC3, 0x9F }; +static symbol s_1[] = { 's', 's' }; +static symbol s_2[] = { 'u' }; +static symbol s_3[] = { 'U' }; +static symbol s_4[] = { 'y' }; +static symbol s_5[] = { 'Y' }; +static symbol s_6[] = { 'y' }; +static symbol s_7[] = { 'u' }; +static symbol s_8[] = { 'a' }; +static symbol s_9[] = { 'o' }; +static symbol s_10[] = { 'u' }; +static symbol s_11[] = { 'i', 'g' }; +static symbol s_12[] = { 'e' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'e', 'r' }; +static symbol s_15[] = { 'e', 'n' }; + +static int r_prelude(struct SN_env * z) { + { int c_test = z->c; /* test, line 30 */ + while(1) { /* repeat, line 30 */ + int c = z->c; + { int c = z->c; /* or, line 33 */ + z->bra = z->c; /* [, line 32 */ + if (!(eq_s(z, 2, s_0))) goto lab2; + z->ket = z->c; /* ], line 32 */ + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 32 */ + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 33 */ + } + } + lab1: + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + while(1) { /* repeat, line 36 */ + int c = z->c; + while(1) { /* goto, line 36 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab4; + z->bra = z->c; /* [, line 37 */ + { int c = z->c; /* or, line 37 */ + if (!(eq_s(z, 1, s_2))) goto lab6; + z->ket = z->c; /* ], line 37 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab6; + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 37 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = c; + if (!(eq_s(z, 1, s_4))) goto lab4; + z->ket = z->c; /* ], line 38 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab4; + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 38 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = c; + break; + lab4: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab3; + z->c = c; /* goto, line 36 */ + } + } + continue; + lab3: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c_test = z->c; /* test, line 47 */ + { int c = skip_utf8(z->p, z->c, 0, z->l, + 3); + if (c < 0) return 0; + z->c = c; /* hop, line 47 */ + } + z->I[2] = z->c; /* setmark x, line 47 */ + z->c = c_test; + } + while(1) { /* gopast, line 49 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab0; + break; + lab0: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 49 */ + } + } + while(1) { /* gopast, line 49 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 49 */ + } + } + z->I[0] = z->c; /* setmark p1, line 49 */ + /* try, line 50 */ + if (!(z->I[0] < z->I[2])) goto lab2; + z->I[0] = z->I[2]; +lab2: + while(1) { /* gopast, line 51 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 51 */ + } + } + while(1) { /* gopast, line 51 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab4; + break; + lab4: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 51 */ + } + } + z->I[1] = z->c; /* setmark p2, line 51 */ + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 55 */ + int c = z->c; + z->bra = z->c; /* [, line 57 */ + among_var = find_among(z, a_0, 6); /* substring, line 57 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 57 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_6); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_8); /* <-, line 60 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_9); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 62 */ + if (ret < 0) return ret; + } + break; + case 6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 63 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + { int m = z->l - z->c; (void) m; /* do, line 74 */ + z->ket = z->c; /* [, line 75 */ + among_var = find_among_b(z, a_1, 7); /* substring, line 75 */ + if (!(among_var)) goto lab0; + z->bra = z->c; /* ], line 75 */ + { int ret = r_R1(z); + if (ret == 0) goto lab0; /* call R1, line 75 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 77 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b_U(z, g_s_ending, 98, 116))) goto lab0; + { int ret; + ret = slice_del(z); /* delete, line 80 */ + if (ret < 0) return ret; + } + break; + } + lab0: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 84 */ + z->ket = z->c; /* [, line 85 */ + among_var = find_among_b(z, a_2, 4); /* substring, line 85 */ + if (!(among_var)) goto lab1; + z->bra = z->c; /* ], line 85 */ + { int ret = r_R1(z); + if (ret == 0) goto lab1; /* call R1, line 85 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab1; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b_U(z, g_st_ending, 98, 116))) goto lab1; + { int c = skip_utf8(z->p, z->c, z->lb, z->l, - 3); + if (c < 0) goto lab1; + z->c = c; /* hop, line 90 */ + } + { int ret; + ret = slice_del(z); /* delete, line 90 */ + if (ret < 0) return ret; + } + break; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 94 */ + z->ket = z->c; /* [, line 95 */ + among_var = find_among_b(z, a_4, 8); /* substring, line 95 */ + if (!(among_var)) goto lab2; + z->bra = z->c; /* ], line 95 */ + { int ret = r_R2(z); + if (ret == 0) goto lab2; /* call R2, line 95 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: goto lab2; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 97 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 98 */ + z->ket = z->c; /* [, line 98 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 98 */ + { int m = z->l - z->c; (void) m; /* not, line 98 */ + if (!(eq_s_b(z, 1, s_12))) goto lab4; + { z->c = z->l - m; goto lab3; } + lab4: + z->c = z->l - m; + } + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 98 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* not, line 101 */ + if (!(eq_s_b(z, 1, s_13))) goto lab5; + goto lab2; + lab5: + z->c = z->l - m; + } + { int ret; + ret = slice_del(z); /* delete, line 101 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 104 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 105 */ + z->ket = z->c; /* [, line 106 */ + { int m = z->l - z->c; (void) m; /* or, line 106 */ + if (!(eq_s_b(z, 2, s_14))) goto lab8; + goto lab7; + lab8: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m; goto lab6; } + } + lab7: + z->bra = z->c; /* ], line 106 */ + { int ret = r_R1(z); + if (ret == 0) { z->c = z->l - m; goto lab6; } /* call R1, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 106 */ + if (ret < 0) return ret; + } + lab6: + ; + } + break; + case 4: + { int ret; + ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_3, 2); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m; goto lab9; } + z->bra = z->c; /* ], line 112 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab9; } /* call R2, line 112 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab9; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 114 */ + if (ret < 0) return ret; + } + break; + } + lab9: + ; + } + break; + } + lab2: + z->c = z->l - m; + } + return 1; +} + +extern int german_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 125 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 125 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 126 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 126 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 127 */ + + { int m = z->l - z->c; (void) m; /* do, line 128 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab2; /* call standard_suffix, line 128 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 129 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab3; /* call postlude, line 129 */ + if (ret < 0) return ret; + } + lab3: + z->c = c; + } + return 1; +} + +extern struct SN_env * german_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void german_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.h new file mode 100644 index 00000000000..5bd84d431f0 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_german.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * german_UTF_8_create_env(void); +extern void german_UTF_8_close_env(struct SN_env * z); + +extern int german_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.c new file mode 100644 index 00000000000..5639b1cf7be --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.c @@ -0,0 +1,1113 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int italian_UTF_8_stem(struct SN_env * z); +static int r_vowel_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_attached_pronoun(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * italian_UTF_8_create_env(void); +extern void italian_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[2] = { 'q', 'u' }; +static symbol s_0_2[2] = { 0xC3, 0xA1 }; +static symbol s_0_3[2] = { 0xC3, 0xA9 }; +static symbol s_0_4[2] = { 0xC3, 0xAD }; +static symbol s_0_5[2] = { 0xC3, 0xB3 }; +static symbol s_0_6[2] = { 0xC3, 0xBA }; + +static struct among a_0[7] = +{ +/* 0 */ { 0, 0, -1, 7, 0}, +/* 1 */ { 2, s_0_1, 0, 6, 0}, +/* 2 */ { 2, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, 2, 0}, +/* 4 */ { 2, s_0_4, 0, 3, 0}, +/* 5 */ { 2, s_0_5, 0, 4, 0}, +/* 6 */ { 2, s_0_6, 0, 5, 0} +}; + +static symbol s_1_1[1] = { 'I' }; +static symbol s_1_2[1] = { 'U' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 1, s_1_1, 0, 1, 0}, +/* 2 */ { 1, s_1_2, 0, 2, 0} +}; + +static symbol s_2_0[2] = { 'l', 'a' }; +static symbol s_2_1[4] = { 'c', 'e', 'l', 'a' }; +static symbol s_2_2[6] = { 'g', 'l', 'i', 'e', 'l', 'a' }; +static symbol s_2_3[4] = { 'm', 'e', 'l', 'a' }; +static symbol s_2_4[4] = { 't', 'e', 'l', 'a' }; +static symbol s_2_5[4] = { 'v', 'e', 'l', 'a' }; +static symbol s_2_6[2] = { 'l', 'e' }; +static symbol s_2_7[4] = { 'c', 'e', 'l', 'e' }; +static symbol s_2_8[6] = { 'g', 'l', 'i', 'e', 'l', 'e' }; +static symbol s_2_9[4] = { 'm', 'e', 'l', 'e' }; +static symbol s_2_10[4] = { 't', 'e', 'l', 'e' }; +static symbol s_2_11[4] = { 'v', 'e', 'l', 'e' }; +static symbol s_2_12[2] = { 'n', 'e' }; +static symbol s_2_13[4] = { 'c', 'e', 'n', 'e' }; +static symbol s_2_14[6] = { 'g', 'l', 'i', 'e', 'n', 'e' }; +static symbol s_2_15[4] = { 'm', 'e', 'n', 'e' }; +static symbol s_2_16[4] = { 's', 'e', 'n', 'e' }; +static symbol s_2_17[4] = { 't', 'e', 'n', 'e' }; +static symbol s_2_18[4] = { 'v', 'e', 'n', 'e' }; +static symbol s_2_19[2] = { 'c', 'i' }; +static symbol s_2_20[2] = { 'l', 'i' }; +static symbol s_2_21[4] = { 'c', 'e', 'l', 'i' }; +static symbol s_2_22[6] = { 'g', 'l', 'i', 'e', 'l', 'i' }; +static symbol s_2_23[4] = { 'm', 'e', 'l', 'i' }; +static symbol s_2_24[4] = { 't', 'e', 'l', 'i' }; +static symbol s_2_25[4] = { 'v', 'e', 'l', 'i' }; +static symbol s_2_26[3] = { 'g', 'l', 'i' }; +static symbol s_2_27[2] = { 'm', 'i' }; +static symbol s_2_28[2] = { 's', 'i' }; +static symbol s_2_29[2] = { 't', 'i' }; +static symbol s_2_30[2] = { 'v', 'i' }; +static symbol s_2_31[2] = { 'l', 'o' }; +static symbol s_2_32[4] = { 'c', 'e', 'l', 'o' }; +static symbol s_2_33[6] = { 'g', 'l', 'i', 'e', 'l', 'o' }; +static symbol s_2_34[4] = { 'm', 'e', 'l', 'o' }; +static symbol s_2_35[4] = { 't', 'e', 'l', 'o' }; +static symbol s_2_36[4] = { 'v', 'e', 'l', 'o' }; + +static struct among a_2[37] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 4, s_2_1, 0, -1, 0}, +/* 2 */ { 6, s_2_2, 0, -1, 0}, +/* 3 */ { 4, s_2_3, 0, -1, 0}, +/* 4 */ { 4, s_2_4, 0, -1, 0}, +/* 5 */ { 4, s_2_5, 0, -1, 0}, +/* 6 */ { 2, s_2_6, -1, -1, 0}, +/* 7 */ { 4, s_2_7, 6, -1, 0}, +/* 8 */ { 6, s_2_8, 6, -1, 0}, +/* 9 */ { 4, s_2_9, 6, -1, 0}, +/* 10 */ { 4, s_2_10, 6, -1, 0}, +/* 11 */ { 4, s_2_11, 6, -1, 0}, +/* 12 */ { 2, s_2_12, -1, -1, 0}, +/* 13 */ { 4, s_2_13, 12, -1, 0}, +/* 14 */ { 6, s_2_14, 12, -1, 0}, +/* 15 */ { 4, s_2_15, 12, -1, 0}, +/* 16 */ { 4, s_2_16, 12, -1, 0}, +/* 17 */ { 4, s_2_17, 12, -1, 0}, +/* 18 */ { 4, s_2_18, 12, -1, 0}, +/* 19 */ { 2, s_2_19, -1, -1, 0}, +/* 20 */ { 2, s_2_20, -1, -1, 0}, +/* 21 */ { 4, s_2_21, 20, -1, 0}, +/* 22 */ { 6, s_2_22, 20, -1, 0}, +/* 23 */ { 4, s_2_23, 20, -1, 0}, +/* 24 */ { 4, s_2_24, 20, -1, 0}, +/* 25 */ { 4, s_2_25, 20, -1, 0}, +/* 26 */ { 3, s_2_26, 20, -1, 0}, +/* 27 */ { 2, s_2_27, -1, -1, 0}, +/* 28 */ { 2, s_2_28, -1, -1, 0}, +/* 29 */ { 2, s_2_29, -1, -1, 0}, +/* 30 */ { 2, s_2_30, -1, -1, 0}, +/* 31 */ { 2, s_2_31, -1, -1, 0}, +/* 32 */ { 4, s_2_32, 31, -1, 0}, +/* 33 */ { 6, s_2_33, 31, -1, 0}, +/* 34 */ { 4, s_2_34, 31, -1, 0}, +/* 35 */ { 4, s_2_35, 31, -1, 0}, +/* 36 */ { 4, s_2_36, 31, -1, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_3_1[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_3_2[2] = { 'a', 'r' }; +static symbol s_3_3[2] = { 'e', 'r' }; +static symbol s_3_4[2] = { 'i', 'r' }; + +static struct among a_3[5] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0}, +/* 2 */ { 2, s_3_2, -1, 2, 0}, +/* 3 */ { 2, s_3_3, -1, 2, 0}, +/* 4 */ { 2, s_3_4, -1, 2, 0} +}; + +static symbol s_4_0[2] = { 'i', 'c' }; +static symbol s_4_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_4_2[2] = { 'o', 's' }; +static symbol s_4_3[2] = { 'i', 'v' }; + +static struct among a_4[4] = +{ +/* 0 */ { 2, s_4_0, -1, -1, 0}, +/* 1 */ { 4, s_4_1, -1, -1, 0}, +/* 2 */ { 2, s_4_2, -1, -1, 0}, +/* 3 */ { 2, s_4_3, -1, 1, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_5_2[2] = { 'i', 'v' }; + +static struct among a_5[3] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 2, s_5_2, -1, 1, 0} +}; + +static symbol s_6_0[3] = { 'i', 'c', 'a' }; +static symbol s_6_1[5] = { 'l', 'o', 'g', 'i', 'a' }; +static symbol s_6_2[3] = { 'o', 's', 'a' }; +static symbol s_6_3[4] = { 'i', 's', 't', 'a' }; +static symbol s_6_4[3] = { 'i', 'v', 'a' }; +static symbol s_6_5[4] = { 'a', 'n', 'z', 'a' }; +static symbol s_6_6[4] = { 'e', 'n', 'z', 'a' }; +static symbol s_6_7[3] = { 'i', 'c', 'e' }; +static symbol s_6_8[6] = { 'a', 't', 'r', 'i', 'c', 'e' }; +static symbol s_6_9[4] = { 'i', 'c', 'h', 'e' }; +static symbol s_6_10[5] = { 'l', 'o', 'g', 'i', 'e' }; +static symbol s_6_11[5] = { 'a', 'b', 'i', 'l', 'e' }; +static symbol s_6_12[5] = { 'i', 'b', 'i', 'l', 'e' }; +static symbol s_6_13[6] = { 'u', 's', 'i', 'o', 'n', 'e' }; +static symbol s_6_14[6] = { 'a', 'z', 'i', 'o', 'n', 'e' }; +static symbol s_6_15[6] = { 'u', 'z', 'i', 'o', 'n', 'e' }; +static symbol s_6_16[5] = { 'a', 't', 'o', 'r', 'e' }; +static symbol s_6_17[3] = { 'o', 's', 'e' }; +static symbol s_6_18[4] = { 'a', 'n', 't', 'e' }; +static symbol s_6_19[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_20[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_21[4] = { 'i', 's', 't', 'e' }; +static symbol s_6_22[3] = { 'i', 'v', 'e' }; +static symbol s_6_23[4] = { 'a', 'n', 'z', 'e' }; +static symbol s_6_24[4] = { 'e', 'n', 'z', 'e' }; +static symbol s_6_25[3] = { 'i', 'c', 'i' }; +static symbol s_6_26[6] = { 'a', 't', 'r', 'i', 'c', 'i' }; +static symbol s_6_27[4] = { 'i', 'c', 'h', 'i' }; +static symbol s_6_28[5] = { 'a', 'b', 'i', 'l', 'i' }; +static symbol s_6_29[5] = { 'i', 'b', 'i', 'l', 'i' }; +static symbol s_6_30[4] = { 'i', 's', 'm', 'i' }; +static symbol s_6_31[6] = { 'u', 's', 'i', 'o', 'n', 'i' }; +static symbol s_6_32[6] = { 'a', 'z', 'i', 'o', 'n', 'i' }; +static symbol s_6_33[6] = { 'u', 'z', 'i', 'o', 'n', 'i' }; +static symbol s_6_34[5] = { 'a', 't', 'o', 'r', 'i' }; +static symbol s_6_35[3] = { 'o', 's', 'i' }; +static symbol s_6_36[4] = { 'a', 'n', 't', 'i' }; +static symbol s_6_37[6] = { 'a', 'm', 'e', 'n', 't', 'i' }; +static symbol s_6_38[6] = { 'i', 'm', 'e', 'n', 't', 'i' }; +static symbol s_6_39[4] = { 'i', 's', 't', 'i' }; +static symbol s_6_40[3] = { 'i', 'v', 'i' }; +static symbol s_6_41[3] = { 'i', 'c', 'o' }; +static symbol s_6_42[4] = { 'i', 's', 'm', 'o' }; +static symbol s_6_43[3] = { 'o', 's', 'o' }; +static symbol s_6_44[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static symbol s_6_45[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static symbol s_6_46[3] = { 'i', 'v', 'o' }; +static symbol s_6_47[4] = { 'i', 't', 0xC3, 0xA0 }; +static symbol s_6_48[5] = { 'i', 's', 't', 0xC3, 0xA0 }; +static symbol s_6_49[5] = { 'i', 's', 't', 0xC3, 0xA8 }; +static symbol s_6_50[5] = { 'i', 's', 't', 0xC3, 0xAC }; + +static struct among a_6[51] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 5, s_6_1, -1, 3, 0}, +/* 2 */ { 3, s_6_2, -1, 1, 0}, +/* 3 */ { 4, s_6_3, -1, 1, 0}, +/* 4 */ { 3, s_6_4, -1, 9, 0}, +/* 5 */ { 4, s_6_5, -1, 1, 0}, +/* 6 */ { 4, s_6_6, -1, 5, 0}, +/* 7 */ { 3, s_6_7, -1, 1, 0}, +/* 8 */ { 6, s_6_8, 7, 1, 0}, +/* 9 */ { 4, s_6_9, -1, 1, 0}, +/* 10 */ { 5, s_6_10, -1, 3, 0}, +/* 11 */ { 5, s_6_11, -1, 1, 0}, +/* 12 */ { 5, s_6_12, -1, 1, 0}, +/* 13 */ { 6, s_6_13, -1, 4, 0}, +/* 14 */ { 6, s_6_14, -1, 2, 0}, +/* 15 */ { 6, s_6_15, -1, 4, 0}, +/* 16 */ { 5, s_6_16, -1, 2, 0}, +/* 17 */ { 3, s_6_17, -1, 1, 0}, +/* 18 */ { 4, s_6_18, -1, 1, 0}, +/* 19 */ { 5, s_6_19, -1, 1, 0}, +/* 20 */ { 6, s_6_20, 19, 7, 0}, +/* 21 */ { 4, s_6_21, -1, 1, 0}, +/* 22 */ { 3, s_6_22, -1, 9, 0}, +/* 23 */ { 4, s_6_23, -1, 1, 0}, +/* 24 */ { 4, s_6_24, -1, 5, 0}, +/* 25 */ { 3, s_6_25, -1, 1, 0}, +/* 26 */ { 6, s_6_26, 25, 1, 0}, +/* 27 */ { 4, s_6_27, -1, 1, 0}, +/* 28 */ { 5, s_6_28, -1, 1, 0}, +/* 29 */ { 5, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, -1, 1, 0}, +/* 31 */ { 6, s_6_31, -1, 4, 0}, +/* 32 */ { 6, s_6_32, -1, 2, 0}, +/* 33 */ { 6, s_6_33, -1, 4, 0}, +/* 34 */ { 5, s_6_34, -1, 2, 0}, +/* 35 */ { 3, s_6_35, -1, 1, 0}, +/* 36 */ { 4, s_6_36, -1, 1, 0}, +/* 37 */ { 6, s_6_37, -1, 6, 0}, +/* 38 */ { 6, s_6_38, -1, 6, 0}, +/* 39 */ { 4, s_6_39, -1, 1, 0}, +/* 40 */ { 3, s_6_40, -1, 9, 0}, +/* 41 */ { 3, s_6_41, -1, 1, 0}, +/* 42 */ { 4, s_6_42, -1, 1, 0}, +/* 43 */ { 3, s_6_43, -1, 1, 0}, +/* 44 */ { 6, s_6_44, -1, 6, 0}, +/* 45 */ { 6, s_6_45, -1, 6, 0}, +/* 46 */ { 3, s_6_46, -1, 9, 0}, +/* 47 */ { 4, s_6_47, -1, 8, 0}, +/* 48 */ { 5, s_6_48, -1, 1, 0}, +/* 49 */ { 5, s_6_49, -1, 1, 0}, +/* 50 */ { 5, s_6_50, -1, 1, 0} +}; + +static symbol s_7_0[4] = { 'i', 's', 'c', 'a' }; +static symbol s_7_1[4] = { 'e', 'n', 'd', 'a' }; +static symbol s_7_2[3] = { 'a', 't', 'a' }; +static symbol s_7_3[3] = { 'i', 't', 'a' }; +static symbol s_7_4[3] = { 'u', 't', 'a' }; +static symbol s_7_5[3] = { 'a', 'v', 'a' }; +static symbol s_7_6[3] = { 'e', 'v', 'a' }; +static symbol s_7_7[3] = { 'i', 'v', 'a' }; +static symbol s_7_8[6] = { 'e', 'r', 'e', 'b', 'b', 'e' }; +static symbol s_7_9[6] = { 'i', 'r', 'e', 'b', 'b', 'e' }; +static symbol s_7_10[4] = { 'i', 's', 'c', 'e' }; +static symbol s_7_11[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_7_12[3] = { 'a', 'r', 'e' }; +static symbol s_7_13[3] = { 'e', 'r', 'e' }; +static symbol s_7_14[3] = { 'i', 'r', 'e' }; +static symbol s_7_15[4] = { 'a', 's', 's', 'e' }; +static symbol s_7_16[3] = { 'a', 't', 'e' }; +static symbol s_7_17[5] = { 'a', 'v', 'a', 't', 'e' }; +static symbol s_7_18[5] = { 'e', 'v', 'a', 't', 'e' }; +static symbol s_7_19[5] = { 'i', 'v', 'a', 't', 'e' }; +static symbol s_7_20[3] = { 'e', 't', 'e' }; +static symbol s_7_21[5] = { 'e', 'r', 'e', 't', 'e' }; +static symbol s_7_22[5] = { 'i', 'r', 'e', 't', 'e' }; +static symbol s_7_23[3] = { 'i', 't', 'e' }; +static symbol s_7_24[6] = { 'e', 'r', 'e', 's', 't', 'e' }; +static symbol s_7_25[6] = { 'i', 'r', 'e', 's', 't', 'e' }; +static symbol s_7_26[3] = { 'u', 't', 'e' }; +static symbol s_7_27[4] = { 'e', 'r', 'a', 'i' }; +static symbol s_7_28[4] = { 'i', 'r', 'a', 'i' }; +static symbol s_7_29[4] = { 'i', 's', 'c', 'i' }; +static symbol s_7_30[4] = { 'e', 'n', 'd', 'i' }; +static symbol s_7_31[4] = { 'e', 'r', 'e', 'i' }; +static symbol s_7_32[4] = { 'i', 'r', 'e', 'i' }; +static symbol s_7_33[4] = { 'a', 's', 's', 'i' }; +static symbol s_7_34[3] = { 'a', 't', 'i' }; +static symbol s_7_35[3] = { 'i', 't', 'i' }; +static symbol s_7_36[6] = { 'e', 'r', 'e', 's', 't', 'i' }; +static symbol s_7_37[6] = { 'i', 'r', 'e', 's', 't', 'i' }; +static symbol s_7_38[3] = { 'u', 't', 'i' }; +static symbol s_7_39[3] = { 'a', 'v', 'i' }; +static symbol s_7_40[3] = { 'e', 'v', 'i' }; +static symbol s_7_41[3] = { 'i', 'v', 'i' }; +static symbol s_7_42[4] = { 'i', 's', 'c', 'o' }; +static symbol s_7_43[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_7_44[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_7_45[4] = { 'Y', 'a', 'm', 'o' }; +static symbol s_7_46[4] = { 'i', 'a', 'm', 'o' }; +static symbol s_7_47[5] = { 'a', 'v', 'a', 'm', 'o' }; +static symbol s_7_48[5] = { 'e', 'v', 'a', 'm', 'o' }; +static symbol s_7_49[5] = { 'i', 'v', 'a', 'm', 'o' }; +static symbol s_7_50[5] = { 'e', 'r', 'e', 'm', 'o' }; +static symbol s_7_51[5] = { 'i', 'r', 'e', 'm', 'o' }; +static symbol s_7_52[6] = { 'a', 's', 's', 'i', 'm', 'o' }; +static symbol s_7_53[4] = { 'a', 'm', 'm', 'o' }; +static symbol s_7_54[4] = { 'e', 'm', 'm', 'o' }; +static symbol s_7_55[6] = { 'e', 'r', 'e', 'm', 'm', 'o' }; +static symbol s_7_56[6] = { 'i', 'r', 'e', 'm', 'm', 'o' }; +static symbol s_7_57[4] = { 'i', 'm', 'm', 'o' }; +static symbol s_7_58[3] = { 'a', 'n', 'o' }; +static symbol s_7_59[6] = { 'i', 's', 'c', 'a', 'n', 'o' }; +static symbol s_7_60[5] = { 'a', 'v', 'a', 'n', 'o' }; +static symbol s_7_61[5] = { 'e', 'v', 'a', 'n', 'o' }; +static symbol s_7_62[5] = { 'i', 'v', 'a', 'n', 'o' }; +static symbol s_7_63[6] = { 'e', 'r', 'a', 'n', 'n', 'o' }; +static symbol s_7_64[6] = { 'i', 'r', 'a', 'n', 'n', 'o' }; +static symbol s_7_65[3] = { 'o', 'n', 'o' }; +static symbol s_7_66[6] = { 'i', 's', 'c', 'o', 'n', 'o' }; +static symbol s_7_67[5] = { 'a', 'r', 'o', 'n', 'o' }; +static symbol s_7_68[5] = { 'e', 'r', 'o', 'n', 'o' }; +static symbol s_7_69[5] = { 'i', 'r', 'o', 'n', 'o' }; +static symbol s_7_70[8] = { 'e', 'r', 'e', 'b', 'b', 'e', 'r', 'o' }; +static symbol s_7_71[8] = { 'i', 'r', 'e', 'b', 'b', 'e', 'r', 'o' }; +static symbol s_7_72[6] = { 'a', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_73[6] = { 'e', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_74[6] = { 'i', 's', 's', 'e', 'r', 'o' }; +static symbol s_7_75[3] = { 'a', 't', 'o' }; +static symbol s_7_76[3] = { 'i', 't', 'o' }; +static symbol s_7_77[3] = { 'u', 't', 'o' }; +static symbol s_7_78[3] = { 'a', 'v', 'o' }; +static symbol s_7_79[3] = { 'e', 'v', 'o' }; +static symbol s_7_80[3] = { 'i', 'v', 'o' }; +static symbol s_7_81[2] = { 'a', 'r' }; +static symbol s_7_82[2] = { 'i', 'r' }; +static symbol s_7_83[4] = { 'e', 'r', 0xC3, 0xA0 }; +static symbol s_7_84[4] = { 'i', 'r', 0xC3, 0xA0 }; +static symbol s_7_85[4] = { 'e', 'r', 0xC3, 0xB2 }; +static symbol s_7_86[4] = { 'i', 'r', 0xC3, 0xB2 }; + +static struct among a_7[87] = +{ +/* 0 */ { 4, s_7_0, -1, 1, 0}, +/* 1 */ { 4, s_7_1, -1, 1, 0}, +/* 2 */ { 3, s_7_2, -1, 1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 3, s_7_4, -1, 1, 0}, +/* 5 */ { 3, s_7_5, -1, 1, 0}, +/* 6 */ { 3, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 6, s_7_8, -1, 1, 0}, +/* 9 */ { 6, s_7_9, -1, 1, 0}, +/* 10 */ { 4, s_7_10, -1, 1, 0}, +/* 11 */ { 4, s_7_11, -1, 1, 0}, +/* 12 */ { 3, s_7_12, -1, 1, 0}, +/* 13 */ { 3, s_7_13, -1, 1, 0}, +/* 14 */ { 3, s_7_14, -1, 1, 0}, +/* 15 */ { 4, s_7_15, -1, 1, 0}, +/* 16 */ { 3, s_7_16, -1, 1, 0}, +/* 17 */ { 5, s_7_17, 16, 1, 0}, +/* 18 */ { 5, s_7_18, 16, 1, 0}, +/* 19 */ { 5, s_7_19, 16, 1, 0}, +/* 20 */ { 3, s_7_20, -1, 1, 0}, +/* 21 */ { 5, s_7_21, 20, 1, 0}, +/* 22 */ { 5, s_7_22, 20, 1, 0}, +/* 23 */ { 3, s_7_23, -1, 1, 0}, +/* 24 */ { 6, s_7_24, -1, 1, 0}, +/* 25 */ { 6, s_7_25, -1, 1, 0}, +/* 26 */ { 3, s_7_26, -1, 1, 0}, +/* 27 */ { 4, s_7_27, -1, 1, 0}, +/* 28 */ { 4, s_7_28, -1, 1, 0}, +/* 29 */ { 4, s_7_29, -1, 1, 0}, +/* 30 */ { 4, s_7_30, -1, 1, 0}, +/* 31 */ { 4, s_7_31, -1, 1, 0}, +/* 32 */ { 4, s_7_32, -1, 1, 0}, +/* 33 */ { 4, s_7_33, -1, 1, 0}, +/* 34 */ { 3, s_7_34, -1, 1, 0}, +/* 35 */ { 3, s_7_35, -1, 1, 0}, +/* 36 */ { 6, s_7_36, -1, 1, 0}, +/* 37 */ { 6, s_7_37, -1, 1, 0}, +/* 38 */ { 3, s_7_38, -1, 1, 0}, +/* 39 */ { 3, s_7_39, -1, 1, 0}, +/* 40 */ { 3, s_7_40, -1, 1, 0}, +/* 41 */ { 3, s_7_41, -1, 1, 0}, +/* 42 */ { 4, s_7_42, -1, 1, 0}, +/* 43 */ { 4, s_7_43, -1, 1, 0}, +/* 44 */ { 4, s_7_44, -1, 1, 0}, +/* 45 */ { 4, s_7_45, -1, 1, 0}, +/* 46 */ { 4, s_7_46, -1, 1, 0}, +/* 47 */ { 5, s_7_47, -1, 1, 0}, +/* 48 */ { 5, s_7_48, -1, 1, 0}, +/* 49 */ { 5, s_7_49, -1, 1, 0}, +/* 50 */ { 5, s_7_50, -1, 1, 0}, +/* 51 */ { 5, s_7_51, -1, 1, 0}, +/* 52 */ { 6, s_7_52, -1, 1, 0}, +/* 53 */ { 4, s_7_53, -1, 1, 0}, +/* 54 */ { 4, s_7_54, -1, 1, 0}, +/* 55 */ { 6, s_7_55, 54, 1, 0}, +/* 56 */ { 6, s_7_56, 54, 1, 0}, +/* 57 */ { 4, s_7_57, -1, 1, 0}, +/* 58 */ { 3, s_7_58, -1, 1, 0}, +/* 59 */ { 6, s_7_59, 58, 1, 0}, +/* 60 */ { 5, s_7_60, 58, 1, 0}, +/* 61 */ { 5, s_7_61, 58, 1, 0}, +/* 62 */ { 5, s_7_62, 58, 1, 0}, +/* 63 */ { 6, s_7_63, -1, 1, 0}, +/* 64 */ { 6, s_7_64, -1, 1, 0}, +/* 65 */ { 3, s_7_65, -1, 1, 0}, +/* 66 */ { 6, s_7_66, 65, 1, 0}, +/* 67 */ { 5, s_7_67, 65, 1, 0}, +/* 68 */ { 5, s_7_68, 65, 1, 0}, +/* 69 */ { 5, s_7_69, 65, 1, 0}, +/* 70 */ { 8, s_7_70, -1, 1, 0}, +/* 71 */ { 8, s_7_71, -1, 1, 0}, +/* 72 */ { 6, s_7_72, -1, 1, 0}, +/* 73 */ { 6, s_7_73, -1, 1, 0}, +/* 74 */ { 6, s_7_74, -1, 1, 0}, +/* 75 */ { 3, s_7_75, -1, 1, 0}, +/* 76 */ { 3, s_7_76, -1, 1, 0}, +/* 77 */ { 3, s_7_77, -1, 1, 0}, +/* 78 */ { 3, s_7_78, -1, 1, 0}, +/* 79 */ { 3, s_7_79, -1, 1, 0}, +/* 80 */ { 3, s_7_80, -1, 1, 0}, +/* 81 */ { 2, s_7_81, -1, 1, 0}, +/* 82 */ { 2, s_7_82, -1, 1, 0}, +/* 83 */ { 4, s_7_83, -1, 1, 0}, +/* 84 */ { 4, s_7_84, -1, 1, 0}, +/* 85 */ { 4, s_7_85, -1, 1, 0}, +/* 86 */ { 4, s_7_86, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 }; + +static unsigned char g_AEIO[] = { 17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2 }; + +static unsigned char g_CG[] = { 17 }; + +static symbol s_0[] = { 0xC3, 0xA0 }; +static symbol s_1[] = { 0xC3, 0xA8 }; +static symbol s_2[] = { 0xC3, 0xAC }; +static symbol s_3[] = { 0xC3, 0xB2 }; +static symbol s_4[] = { 0xC3, 0xB9 }; +static symbol s_5[] = { 'q', 'U' }; +static symbol s_6[] = { 'u' }; +static symbol s_7[] = { 'U' }; +static symbol s_8[] = { 'i' }; +static symbol s_9[] = { 'I' }; +static symbol s_10[] = { 'i' }; +static symbol s_11[] = { 'u' }; +static symbol s_12[] = { 'e' }; +static symbol s_13[] = { 'i', 'c' }; +static symbol s_14[] = { 'l', 'o', 'g' }; +static symbol s_15[] = { 'u' }; +static symbol s_16[] = { 'e', 'n', 't', 'e' }; +static symbol s_17[] = { 'a', 't' }; +static symbol s_18[] = { 'a', 't' }; +static symbol s_19[] = { 'i', 'c' }; +static symbol s_20[] = { 'i' }; +static symbol s_21[] = { 'h' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + { int c_test = z->c; /* test, line 35 */ + while(1) { /* repeat, line 35 */ + int c = z->c; + z->bra = z->c; /* [, line 36 */ + among_var = find_among(z, a_0, 7); /* substring, line 36 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 36 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_0); /* <-, line 37 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 38 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 2, s_2); /* <-, line 39 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 2, s_3); /* <-, line 40 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 2, s_4); /* <-, line 41 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 2, s_5); /* <-, line 42 */ + if (ret < 0) return ret; + } + break; + case 7: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 43 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + z->c = c_test; + } + while(1) { /* repeat, line 46 */ + int c = z->c; + while(1) { /* goto, line 46 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab2; + z->bra = z->c; /* [, line 47 */ + { int c = z->c; /* or, line 47 */ + if (!(eq_s(z, 1, s_6))) goto lab4; + z->ket = z->c; /* ], line 47 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab4; + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 47 */ + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = c; + if (!(eq_s(z, 1, s_8))) goto lab2; + z->ket = z->c; /* ], line 48 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab2; + { int ret; + ret = slice_from_s(z, 1, s_9); /* <-, line 48 */ + if (ret < 0) return ret; + } + } + lab3: + z->c = c; + break; + lab2: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab1; + z->c = c; /* goto, line 46 */ + } + } + continue; + lab1: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 58 */ + { int c = z->c; /* or, line 60 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab2; + { int c = z->c; /* or, line 59 */ + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab4; + while(1) { /* gopast, line 59 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 59 */ + } + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab2; + while(1) { /* gopast, line 59 */ + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* gopast, line 59 */ + } + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab0; + { int c = z->c; /* or, line 61 */ + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab8; + while(1) { /* gopast, line 61 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab9; + break; + lab9: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab8; + z->c = c; /* gopast, line 61 */ + } + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab0; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 61 */ + } + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 62 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 64 */ + while(1) { /* gopast, line 65 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab11; + break; + lab11: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 65 */ + } + } + while(1) { /* gopast, line 65 */ + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab12; + break; + lab12: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 65 */ + } + } + z->I[1] = z->c; /* setmark p1, line 65 */ + while(1) { /* gopast, line 66 */ + if (!(in_grouping_U(z, g_v, 97, 249))) goto lab13; + break; + lab13: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 66 */ + } + } + while(1) { /* gopast, line 66 */ + if (!(out_grouping_U(z, g_v, 97, 249))) goto lab14; + break; + lab14: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 66 */ + } + } + z->I[2] = z->c; /* setmark p2, line 66 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 70 */ + int c = z->c; + z->bra = z->c; /* [, line 72 */ + among_var = find_among(z, a_1, 3); /* substring, line 72 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 72 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_10); /* <-, line 73 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_11); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 75 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_attached_pronoun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 87 */ + if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */ + z->bra = z->c; /* ], line 87 */ + among_var = find_among_b(z, a_3, 5); /* among, line 97 */ + if (!(among_var)) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 97 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 98 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_12); /* <-, line 99 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 104 */ + among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 104 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 111 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 113 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 114 */ + z->ket = z->c; /* [, line 114 */ + if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 114 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 114 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 114 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 117 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_14); /* <-, line 117 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 119 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_15); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 121 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_16); /* <-, line 121 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 126 */ + z->ket = z->c; /* [, line 127 */ + among_var = find_among_b(z, a_4, 4); /* substring, line 127 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 127 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 127 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + z->ket = z->c; /* [, line 128 */ + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 128 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 128 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 128 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 134 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 135 */ + z->ket = z->c; /* [, line 136 */ + among_var = find_among_b(z, a_5, 3); /* substring, line 136 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 136 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 137 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 137 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 9: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 142 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 142 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 143 */ + z->ket = z->c; /* [, line 143 */ + if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 143 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 143 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 143 */ + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 143 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 143 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 148 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 148 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_7, 87); /* substring, line 149 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_vowel_suffix(struct SN_env * z) { + { int m = z->l - z->c; (void) m; /* try, line 171 */ + z->ket = z->c; /* [, line 172 */ + if (!(in_grouping_b_U(z, g_AEIO, 97, 242))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 172 */ + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 172 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 172 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 173 */ + if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 173 */ + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 173 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 173 */ + if (ret < 0) return ret; + } + lab0: + ; + } + { int m = z->l - z->c; (void) m; /* try, line 175 */ + z->ket = z->c; /* [, line 176 */ + if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 176 */ + if (!(in_grouping_b_U(z, g_CG, 99, 103))) { z->c = z->l - m; goto lab1; } + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call RV, line 176 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 176 */ + if (ret < 0) return ret; + } + lab1: + ; + } + return 1; +} + +extern int italian_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 182 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 182 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 183 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 183 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 184 */ + + { int m = z->l - z->c; (void) m; /* do, line 185 */ + { int ret = r_attached_pronoun(z); + if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 186 */ + { int m = z->l - z->c; (void) m; /* or, line 186 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab5; /* call standard_suffix, line 186 */ + if (ret < 0) return ret; + } + goto lab4; + lab5: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab3; /* call verb_suffix, line 186 */ + if (ret < 0) return ret; + } + } + lab4: + lab3: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 187 */ + { int ret = r_vowel_suffix(z); + if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 189 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab7; /* call postlude, line 189 */ + if (ret < 0) return ret; + } + lab7: + z->c = c; + } + return 1; +} + +extern struct SN_env * italian_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void italian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.h new file mode 100644 index 00000000000..3bee080d52c --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_italian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * italian_UTF_8_create_env(void); +extern void italian_UTF_8_close_env(struct SN_env * z); + +extern int italian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.c new file mode 100644 index 00000000000..6a5ea99b608 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.c @@ -0,0 +1,302 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int norwegian_UTF_8_stem(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * norwegian_UTF_8_create_env(void); +extern void norwegian_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 'a' }; +static symbol s_0_1[1] = { 'e' }; +static symbol s_0_2[3] = { 'e', 'd', 'e' }; +static symbol s_0_3[4] = { 'a', 'n', 'd', 'e' }; +static symbol s_0_4[4] = { 'e', 'n', 'd', 'e' }; +static symbol s_0_5[3] = { 'a', 'n', 'e' }; +static symbol s_0_6[3] = { 'e', 'n', 'e' }; +static symbol s_0_7[6] = { 'h', 'e', 't', 'e', 'n', 'e' }; +static symbol s_0_8[4] = { 'e', 'r', 't', 'e' }; +static symbol s_0_9[2] = { 'e', 'n' }; +static symbol s_0_10[5] = { 'h', 'e', 't', 'e', 'n' }; +static symbol s_0_11[2] = { 'a', 'r' }; +static symbol s_0_12[2] = { 'e', 'r' }; +static symbol s_0_13[5] = { 'h', 'e', 't', 'e', 'r' }; +static symbol s_0_14[1] = { 's' }; +static symbol s_0_15[2] = { 'a', 's' }; +static symbol s_0_16[2] = { 'e', 's' }; +static symbol s_0_17[4] = { 'e', 'd', 'e', 's' }; +static symbol s_0_18[5] = { 'e', 'n', 'd', 'e', 's' }; +static symbol s_0_19[4] = { 'e', 'n', 'e', 's' }; +static symbol s_0_20[7] = { 'h', 'e', 't', 'e', 'n', 'e', 's' }; +static symbol s_0_21[3] = { 'e', 'n', 's' }; +static symbol s_0_22[6] = { 'h', 'e', 't', 'e', 'n', 's' }; +static symbol s_0_23[3] = { 'e', 'r', 's' }; +static symbol s_0_24[3] = { 'e', 't', 's' }; +static symbol s_0_25[2] = { 'e', 't' }; +static symbol s_0_26[3] = { 'h', 'e', 't' }; +static symbol s_0_27[3] = { 'e', 'r', 't' }; +static symbol s_0_28[3] = { 'a', 's', 't' }; + +static struct among a_0[29] = +{ +/* 0 */ { 1, s_0_0, -1, 1, 0}, +/* 1 */ { 1, s_0_1, -1, 1, 0}, +/* 2 */ { 3, s_0_2, 1, 1, 0}, +/* 3 */ { 4, s_0_3, 1, 1, 0}, +/* 4 */ { 4, s_0_4, 1, 1, 0}, +/* 5 */ { 3, s_0_5, 1, 1, 0}, +/* 6 */ { 3, s_0_6, 1, 1, 0}, +/* 7 */ { 6, s_0_7, 6, 1, 0}, +/* 8 */ { 4, s_0_8, 1, 3, 0}, +/* 9 */ { 2, s_0_9, -1, 1, 0}, +/* 10 */ { 5, s_0_10, 9, 1, 0}, +/* 11 */ { 2, s_0_11, -1, 1, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 5, s_0_13, 12, 1, 0}, +/* 14 */ { 1, s_0_14, -1, 2, 0}, +/* 15 */ { 2, s_0_15, 14, 1, 0}, +/* 16 */ { 2, s_0_16, 14, 1, 0}, +/* 17 */ { 4, s_0_17, 16, 1, 0}, +/* 18 */ { 5, s_0_18, 16, 1, 0}, +/* 19 */ { 4, s_0_19, 16, 1, 0}, +/* 20 */ { 7, s_0_20, 19, 1, 0}, +/* 21 */ { 3, s_0_21, 14, 1, 0}, +/* 22 */ { 6, s_0_22, 21, 1, 0}, +/* 23 */ { 3, s_0_23, 14, 1, 0}, +/* 24 */ { 3, s_0_24, 14, 1, 0}, +/* 25 */ { 2, s_0_25, -1, 1, 0}, +/* 26 */ { 3, s_0_26, 25, 1, 0}, +/* 27 */ { 3, s_0_27, -1, 3, 0}, +/* 28 */ { 3, s_0_28, -1, 1, 0} +}; + +static symbol s_1_0[2] = { 'd', 't' }; +static symbol s_1_1[2] = { 'v', 't' }; + +static struct among a_1[2] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0} +}; + +static symbol s_2_0[3] = { 'l', 'e', 'g' }; +static symbol s_2_1[4] = { 'e', 'l', 'e', 'g' }; +static symbol s_2_2[2] = { 'i', 'g' }; +static symbol s_2_3[3] = { 'e', 'i', 'g' }; +static symbol s_2_4[3] = { 'l', 'i', 'g' }; +static symbol s_2_5[4] = { 'e', 'l', 'i', 'g' }; +static symbol s_2_6[3] = { 'e', 'l', 's' }; +static symbol s_2_7[3] = { 'l', 'o', 'v' }; +static symbol s_2_8[4] = { 'e', 'l', 'o', 'v' }; +static symbol s_2_9[4] = { 's', 'l', 'o', 'v' }; +static symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' }; + +static struct among a_2[11] = +{ +/* 0 */ { 3, s_2_0, -1, 1, 0}, +/* 1 */ { 4, s_2_1, 0, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 1, 0}, +/* 3 */ { 3, s_2_3, 2, 1, 0}, +/* 4 */ { 3, s_2_4, 2, 1, 0}, +/* 5 */ { 4, s_2_5, 4, 1, 0}, +/* 6 */ { 3, s_2_6, -1, 1, 0}, +/* 7 */ { 3, s_2_7, -1, 1, 0}, +/* 8 */ { 4, s_2_8, 7, 1, 0}, +/* 9 */ { 4, s_2_9, 7, 1, 0}, +/* 10 */ { 7, s_2_10, 9, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; + +static unsigned char g_s_ending[] = { 119, 125, 149, 1 }; + +static symbol s_0[] = { 'k' }; +static symbol s_1[] = { 'e', 'r' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 30 */ + { int c = skip_utf8(z->p, z->c, 0, z->l, + 3); + if (c < 0) return 0; + z->c = c; /* hop, line 30 */ + } + z->I[1] = z->c; /* setmark x, line 30 */ + z->c = c_test; + } + while(1) { /* goto, line 31 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 248))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* goto, line 31 */ + } + } + while(1) { /* gopast, line 31 */ + if (!(out_grouping_U(z, g_v, 97, 248))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 31 */ + } + } + z->I[0] = z->c; /* setmark p1, line 31 */ + /* try, line 32 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 38 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 38 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 38 */ + among_var = find_among_b(z, a_0, 29); /* substring, line 38 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 38 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 46 */ + if (!(in_grouping_b_U(z, g_s_ending, 98, 122))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_0))) return 0; + if (!(out_grouping_b_U(z, g_v, 97, 248))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 48 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m_test = z->l - z->c; /* test, line 53 */ + { int m3; /* setlimit, line 54 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 54 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 54 */ + if (!(find_among_b(z, a_1, 2))) { z->lb = m3; return 0; } /* substring, line 54 */ + z->bra = z->c; /* ], line 54 */ + z->lb = m3; + } + z->c = z->l - m_test; + } + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 59 */ + } + z->bra = z->c; /* ], line 59 */ + { int ret; + ret = slice_del(z); /* delete, line 59 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 63 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 63 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 63 */ + among_var = find_among_b(z, a_2, 11); /* substring, line 63 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 63 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 67 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int norwegian_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 74 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 74 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 75 */ + + { int m = z->l - z->c; (void) m; /* do, line 76 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 76 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 77 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 77 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 78 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 78 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * norwegian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void norwegian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.h new file mode 100644 index 00000000000..c75444bcd95 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_norwegian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * norwegian_UTF_8_create_env(void); +extern void norwegian_UTF_8_close_env(struct SN_env * z); + +extern int norwegian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.c new file mode 100644 index 00000000000..1d22e7121ea --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.c @@ -0,0 +1,794 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int porter_UTF_8_stem(struct SN_env * z); +static int r_Step_5b(struct SN_env * z); +static int r_Step_5a(struct SN_env * z); +static int r_Step_4(struct SN_env * z); +static int r_Step_3(struct SN_env * z); +static int r_Step_2(struct SN_env * z); +static int r_Step_1c(struct SN_env * z); +static int r_Step_1b(struct SN_env * z); +static int r_Step_1a(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_shortv(struct SN_env * z); + +extern struct SN_env * porter_UTF_8_create_env(void); +extern void porter_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 's' }; +static symbol s_0_1[3] = { 'i', 'e', 's' }; +static symbol s_0_2[4] = { 's', 's', 'e', 's' }; +static symbol s_0_3[2] = { 's', 's' }; + +static struct among a_0[4] = +{ +/* 0 */ { 1, s_0_0, -1, 3, 0}, +/* 1 */ { 3, s_0_1, 0, 2, 0}, +/* 2 */ { 4, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, -1, 0} +}; + +static symbol s_1_1[2] = { 'b', 'b' }; +static symbol s_1_2[2] = { 'd', 'd' }; +static symbol s_1_3[2] = { 'f', 'f' }; +static symbol s_1_4[2] = { 'g', 'g' }; +static symbol s_1_5[2] = { 'b', 'l' }; +static symbol s_1_6[2] = { 'm', 'm' }; +static symbol s_1_7[2] = { 'n', 'n' }; +static symbol s_1_8[2] = { 'p', 'p' }; +static symbol s_1_9[2] = { 'r', 'r' }; +static symbol s_1_10[2] = { 'a', 't' }; +static symbol s_1_11[2] = { 't', 't' }; +static symbol s_1_12[2] = { 'i', 'z' }; + +static struct among a_1[13] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_1_1, 0, 2, 0}, +/* 2 */ { 2, s_1_2, 0, 2, 0}, +/* 3 */ { 2, s_1_3, 0, 2, 0}, +/* 4 */ { 2, s_1_4, 0, 2, 0}, +/* 5 */ { 2, s_1_5, 0, 1, 0}, +/* 6 */ { 2, s_1_6, 0, 2, 0}, +/* 7 */ { 2, s_1_7, 0, 2, 0}, +/* 8 */ { 2, s_1_8, 0, 2, 0}, +/* 9 */ { 2, s_1_9, 0, 2, 0}, +/* 10 */ { 2, s_1_10, 0, 1, 0}, +/* 11 */ { 2, s_1_11, 0, 2, 0}, +/* 12 */ { 2, s_1_12, 0, 1, 0} +}; + +static symbol s_2_0[2] = { 'e', 'd' }; +static symbol s_2_1[3] = { 'e', 'e', 'd' }; +static symbol s_2_2[3] = { 'i', 'n', 'g' }; + +static struct among a_2[3] = +{ +/* 0 */ { 2, s_2_0, -1, 2, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 3, s_2_2, -1, 2, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 'c', 'i' }; +static symbol s_3_1[4] = { 'e', 'n', 'c', 'i' }; +static symbol s_3_2[4] = { 'a', 'b', 'l', 'i' }; +static symbol s_3_3[3] = { 'e', 'l', 'i' }; +static symbol s_3_4[4] = { 'a', 'l', 'l', 'i' }; +static symbol s_3_5[5] = { 'o', 'u', 's', 'l', 'i' }; +static symbol s_3_6[5] = { 'e', 'n', 't', 'l', 'i' }; +static symbol s_3_7[5] = { 'a', 'l', 'i', 't', 'i' }; +static symbol s_3_8[6] = { 'b', 'i', 'l', 'i', 't', 'i' }; +static symbol s_3_9[5] = { 'i', 'v', 'i', 't', 'i' }; +static symbol s_3_10[6] = { 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_3_11[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' }; +static symbol s_3_12[5] = { 'a', 'l', 'i', 's', 'm' }; +static symbol s_3_13[5] = { 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_14[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' }; +static symbol s_3_15[4] = { 'i', 'z', 'e', 'r' }; +static symbol s_3_16[4] = { 'a', 't', 'o', 'r' }; +static symbol s_3_17[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' }; +static symbol s_3_18[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' }; +static symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; + +static struct among a_3[20] = +{ +/* 0 */ { 4, s_3_0, -1, 3, 0}, +/* 1 */ { 4, s_3_1, -1, 2, 0}, +/* 2 */ { 4, s_3_2, -1, 4, 0}, +/* 3 */ { 3, s_3_3, -1, 6, 0}, +/* 4 */ { 4, s_3_4, -1, 9, 0}, +/* 5 */ { 5, s_3_5, -1, 12, 0}, +/* 6 */ { 5, s_3_6, -1, 5, 0}, +/* 7 */ { 5, s_3_7, -1, 10, 0}, +/* 8 */ { 6, s_3_8, -1, 14, 0}, +/* 9 */ { 5, s_3_9, -1, 13, 0}, +/* 10 */ { 6, s_3_10, -1, 1, 0}, +/* 11 */ { 7, s_3_11, 10, 8, 0}, +/* 12 */ { 5, s_3_12, -1, 10, 0}, +/* 13 */ { 5, s_3_13, -1, 8, 0}, +/* 14 */ { 7, s_3_14, 13, 7, 0}, +/* 15 */ { 4, s_3_15, -1, 7, 0}, +/* 16 */ { 4, s_3_16, -1, 8, 0}, +/* 17 */ { 7, s_3_17, -1, 13, 0}, +/* 18 */ { 7, s_3_18, -1, 11, 0}, +/* 19 */ { 7, s_3_19, -1, 12, 0} +}; + +static symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; +static symbol s_4_1[5] = { 'a', 't', 'i', 'v', 'e' }; +static symbol s_4_2[5] = { 'a', 'l', 'i', 'z', 'e' }; +static symbol s_4_3[5] = { 'i', 'c', 'i', 't', 'i' }; +static symbol s_4_4[4] = { 'i', 'c', 'a', 'l' }; +static symbol s_4_5[3] = { 'f', 'u', 'l' }; +static symbol s_4_6[4] = { 'n', 'e', 's', 's' }; + +static struct among a_4[7] = +{ +/* 0 */ { 5, s_4_0, -1, 2, 0}, +/* 1 */ { 5, s_4_1, -1, 3, 0}, +/* 2 */ { 5, s_4_2, -1, 1, 0}, +/* 3 */ { 5, s_4_3, -1, 2, 0}, +/* 4 */ { 4, s_4_4, -1, 2, 0}, +/* 5 */ { 3, s_4_5, -1, 3, 0}, +/* 6 */ { 4, s_4_6, -1, 3, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'n', 'c', 'e' }; +static symbol s_5_2[4] = { 'e', 'n', 'c', 'e' }; +static symbol s_5_3[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_5_4[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_5_5[3] = { 'a', 't', 'e' }; +static symbol s_5_6[3] = { 'i', 'v', 'e' }; +static symbol s_5_7[3] = { 'i', 'z', 'e' }; +static symbol s_5_8[3] = { 'i', 't', 'i' }; +static symbol s_5_9[2] = { 'a', 'l' }; +static symbol s_5_10[3] = { 'i', 's', 'm' }; +static symbol s_5_11[3] = { 'i', 'o', 'n' }; +static symbol s_5_12[2] = { 'e', 'r' }; +static symbol s_5_13[3] = { 'o', 'u', 's' }; +static symbol s_5_14[3] = { 'a', 'n', 't' }; +static symbol s_5_15[3] = { 'e', 'n', 't' }; +static symbol s_5_16[4] = { 'm', 'e', 'n', 't' }; +static symbol s_5_17[5] = { 'e', 'm', 'e', 'n', 't' }; +static symbol s_5_18[2] = { 'o', 'u' }; + +static struct among a_5[19] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 4, s_5_2, -1, 1, 0}, +/* 3 */ { 4, s_5_3, -1, 1, 0}, +/* 4 */ { 4, s_5_4, -1, 1, 0}, +/* 5 */ { 3, s_5_5, -1, 1, 0}, +/* 6 */ { 3, s_5_6, -1, 1, 0}, +/* 7 */ { 3, s_5_7, -1, 1, 0}, +/* 8 */ { 3, s_5_8, -1, 1, 0}, +/* 9 */ { 2, s_5_9, -1, 1, 0}, +/* 10 */ { 3, s_5_10, -1, 1, 0}, +/* 11 */ { 3, s_5_11, -1, 2, 0}, +/* 12 */ { 2, s_5_12, -1, 1, 0}, +/* 13 */ { 3, s_5_13, -1, 1, 0}, +/* 14 */ { 3, s_5_14, -1, 1, 0}, +/* 15 */ { 3, s_5_15, -1, 1, 0}, +/* 16 */ { 4, s_5_16, 15, 1, 0}, +/* 17 */ { 5, s_5_17, 16, 1, 0}, +/* 18 */ { 2, s_5_18, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1 }; + +static unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; + +static symbol s_0[] = { 's', 's' }; +static symbol s_1[] = { 'i' }; +static symbol s_2[] = { 'e', 'e' }; +static symbol s_3[] = { 'e' }; +static symbol s_4[] = { 'e' }; +static symbol s_5[] = { 'y' }; +static symbol s_6[] = { 'Y' }; +static symbol s_7[] = { 'i' }; +static symbol s_8[] = { 't', 'i', 'o', 'n' }; +static symbol s_9[] = { 'e', 'n', 'c', 'e' }; +static symbol s_10[] = { 'a', 'n', 'c', 'e' }; +static symbol s_11[] = { 'a', 'b', 'l', 'e' }; +static symbol s_12[] = { 'e', 'n', 't' }; +static symbol s_13[] = { 'e' }; +static symbol s_14[] = { 'i', 'z', 'e' }; +static symbol s_15[] = { 'a', 't', 'e' }; +static symbol s_16[] = { 'a', 'l' }; +static symbol s_17[] = { 'a', 'l' }; +static symbol s_18[] = { 'f', 'u', 'l' }; +static symbol s_19[] = { 'o', 'u', 's' }; +static symbol s_20[] = { 'i', 'v', 'e' }; +static symbol s_21[] = { 'b', 'l', 'e' }; +static symbol s_22[] = { 'a', 'l' }; +static symbol s_23[] = { 'i', 'c' }; +static symbol s_24[] = { 's' }; +static symbol s_25[] = { 't' }; +static symbol s_26[] = { 'e' }; +static symbol s_27[] = { 'l' }; +static symbol s_28[] = { 'l' }; +static symbol s_29[] = { 'y' }; +static symbol s_30[] = { 'Y' }; +static symbol s_31[] = { 'y' }; +static symbol s_32[] = { 'Y' }; +static symbol s_33[] = { 'Y' }; +static symbol s_34[] = { 'y' }; + +static int r_shortv(struct SN_env * z) { + if (!(out_grouping_b_U(z, g_v_WXY, 89, 121))) return 0; + if (!(in_grouping_b_U(z, g_v, 97, 121))) return 0; + if (!(out_grouping_b_U(z, g_v, 97, 121))) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_Step_1a(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 25 */ + among_var = find_among_b(z, a_0, 4); /* substring, line 25 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 25 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 27 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 29 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_1b(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 34 */ + among_var = find_among_b(z, a_2, 3); /* substring, line 34 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 34 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 35 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m_test = z->l - z->c; /* test, line 38 */ + while(1) { /* gopast, line 38 */ + if (!(in_grouping_b_U(z, g_v, 97, 121))) goto lab0; + break; + lab0: + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* gopast, line 38 */ + } + } + z->c = z->l - m_test; + } + { int ret; + ret = slice_del(z); /* delete, line 38 */ + if (ret < 0) return ret; + } + { int m_test = z->l - z->c; /* test, line 39 */ + among_var = find_among_b(z, a_1, 13); /* substring, line 39 */ + if (!(among_var)) return 0; + z->c = z->l - m_test; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + case 2: + z->ket = z->c; /* [, line 44 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* next, line 44 */ + } + z->bra = z->c; /* ], line 44 */ + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 3: + if (z->c != z->I[0]) return 0; /* atmark, line 45 */ + { int m_test = z->l - z->c; /* test, line 45 */ + { int ret = r_shortv(z); + if (ret == 0) return 0; /* call shortv, line 45 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test; + } + { int ret; + { int c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + z->c = c; + } + if (ret < 0) return ret; + } + break; + } + break; + } + return 1; +} + +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; /* [, line 52 */ + { int m = z->l - z->c; (void) m; /* or, line 52 */ + if (!(eq_s_b(z, 1, s_5))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_6))) return 0; + } +lab0: + z->bra = z->c; /* ], line 52 */ + while(1) { /* gopast, line 53 */ + if (!(in_grouping_b_U(z, g_v, 97, 121))) goto lab2; + break; + lab2: + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) return 0; + z->c = c; /* gopast, line 53 */ + } + } + { int ret; + ret = slice_from_s(z, 1, s_7); /* <-, line 54 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_2(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 58 */ + among_var = find_among_b(z, a_3, 20); /* substring, line 58 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 58 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 58 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 4, s_8); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_9); /* <-, line 60 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_10); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 4, s_11); /* <-, line 62 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 3, s_12); /* <-, line 63 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 64 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret; + ret = slice_from_s(z, 3, s_14); /* <-, line 66 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret; + ret = slice_from_s(z, 3, s_15); /* <-, line 68 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret; + ret = slice_from_s(z, 2, s_16); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret; + ret = slice_from_s(z, 2, s_17); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret; + ret = slice_from_s(z, 3, s_18); /* <-, line 72 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret; + ret = slice_from_s(z, 3, s_19); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret; + ret = slice_from_s(z, 3, s_20); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret; + ret = slice_from_s(z, 3, s_21); /* <-, line 77 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_3(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 82 */ + among_var = find_among_b(z, a_4, 7); /* substring, line 82 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 82 */ + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 82 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_22); /* <-, line 83 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_23); /* <-, line 85 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_4(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 92 */ + among_var = find_among_b(z, a_5, 19); /* substring, line 92 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 92 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 92 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 95 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m = z->l - z->c; (void) m; /* or, line 96 */ + if (!(eq_s_b(z, 1, s_24))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_25))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 96 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_5a(struct SN_env * z) { + z->ket = z->c; /* [, line 101 */ + if (!(eq_s_b(z, 1, s_26))) return 0; + z->bra = z->c; /* ], line 101 */ + { int m = z->l - z->c; (void) m; /* or, line 102 */ + { int ret = r_R2(z); + if (ret == 0) goto lab1; /* call R2, line 102 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m; + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 102 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* not, line 102 */ + { int ret = r_shortv(z); + if (ret == 0) goto lab2; /* call shortv, line 102 */ + if (ret < 0) return ret; + } + return 0; + lab2: + z->c = z->l - m; + } + } +lab0: + { int ret; + ret = slice_del(z); /* delete, line 103 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Step_5b(struct SN_env * z) { + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 1, s_27))) return 0; + z->bra = z->c; /* ], line 107 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 108 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_28))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 109 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int porter_UTF_8_stem(struct SN_env * z) { + z->B[0] = 0; /* unset Y_found, line 115 */ + { int c = z->c; /* do, line 116 */ + z->bra = z->c; /* [, line 116 */ + if (!(eq_s(z, 1, s_29))) goto lab0; + z->ket = z->c; /* ], line 116 */ + { int ret; + ret = slice_from_s(z, 1, s_30); /* <-, line 116 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 116 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 117 */ + while(1) { /* repeat, line 117 */ + int c = z->c; + while(1) { /* goto, line 117 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab3; + z->bra = z->c; /* [, line 117 */ + if (!(eq_s(z, 1, s_31))) goto lab3; + z->ket = z->c; /* ], line 117 */ + z->c = c; + break; + lab3: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* goto, line 117 */ + } + } + { int ret; + ret = slice_from_s(z, 1, s_32); /* <-, line 117 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set Y_found, line 117 */ + continue; + lab2: + z->c = c; + break; + } + z->c = c; + } + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 121 */ + while(1) { /* gopast, line 122 */ + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 122 */ + } + } + while(1) { /* gopast, line 122 */ + if (!(out_grouping_U(z, g_v, 97, 121))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 122 */ + } + } + z->I[0] = z->c; /* setmark p1, line 122 */ + while(1) { /* gopast, line 123 */ + if (!(in_grouping_U(z, g_v, 97, 121))) goto lab7; + break; + lab7: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 123 */ + } + } + while(1) { /* gopast, line 123 */ + if (!(out_grouping_U(z, g_v, 97, 121))) goto lab8; + break; + lab8: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 123 */ + } + } + z->I[1] = z->c; /* setmark p2, line 123 */ + lab4: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 126 */ + + { int m = z->l - z->c; (void) m; /* do, line 127 */ + { int ret = r_Step_1a(z); + if (ret == 0) goto lab9; /* call Step_1a, line 127 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 128 */ + { int ret = r_Step_1b(z); + if (ret == 0) goto lab10; /* call Step_1b, line 128 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 129 */ + { int ret = r_Step_1c(z); + if (ret == 0) goto lab11; /* call Step_1c, line 129 */ + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 130 */ + { int ret = r_Step_2(z); + if (ret == 0) goto lab12; /* call Step_2, line 130 */ + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 131 */ + { int ret = r_Step_3(z); + if (ret == 0) goto lab13; /* call Step_3, line 131 */ + if (ret < 0) return ret; + } + lab13: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 132 */ + { int ret = r_Step_4(z); + if (ret == 0) goto lab14; /* call Step_4, line 132 */ + if (ret < 0) return ret; + } + lab14: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 133 */ + { int ret = r_Step_5a(z); + if (ret == 0) goto lab15; /* call Step_5a, line 133 */ + if (ret < 0) return ret; + } + lab15: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 134 */ + { int ret = r_Step_5b(z); + if (ret == 0) goto lab16; /* call Step_5b, line 134 */ + if (ret < 0) return ret; + } + lab16: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 137 */ + if (!(z->B[0])) goto lab17; /* Boolean test Y_found, line 137 */ + while(1) { /* repeat, line 137 */ + int c = z->c; + while(1) { /* goto, line 137 */ + int c = z->c; + z->bra = z->c; /* [, line 137 */ + if (!(eq_s(z, 1, s_33))) goto lab19; + z->ket = z->c; /* ], line 137 */ + z->c = c; + break; + lab19: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab18; + z->c = c; /* goto, line 137 */ + } + } + { int ret; + ret = slice_from_s(z, 1, s_34); /* <-, line 137 */ + if (ret < 0) return ret; + } + continue; + lab18: + z->c = c; + break; + } + lab17: + z->c = c; + } + return 1; +} + +extern struct SN_env * porter_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } + +extern void porter_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.h new file mode 100644 index 00000000000..82d469ac459 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_porter.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * porter_UTF_8_create_env(void); +extern void porter_UTF_8_close_env(struct SN_env * z); + +extern int porter_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.c new file mode 100644 index 00000000000..e2885443c86 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.c @@ -0,0 +1,1055 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int portuguese_UTF_8_stem(struct SN_env * z); +static int r_residual_form(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); +static int r_prelude(struct SN_env * z); + +extern struct SN_env * portuguese_UTF_8_create_env(void); +extern void portuguese_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[2] = { 0xC3, 0xA3 }; +static symbol s_0_2[2] = { 0xC3, 0xB5 }; + +static struct among a_0[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_0_1, 0, 1, 0}, +/* 2 */ { 2, s_0_2, 0, 2, 0} +}; + +static symbol s_1_1[2] = { 'a', '~' }; +static symbol s_1_2[2] = { 'o', '~' }; + +static struct among a_1[3] = +{ +/* 0 */ { 0, 0, -1, 3, 0}, +/* 1 */ { 2, s_1_1, 0, 1, 0}, +/* 2 */ { 2, s_1_2, 0, 2, 0} +}; + +static symbol s_2_0[2] = { 'i', 'c' }; +static symbol s_2_1[2] = { 'a', 'd' }; +static symbol s_2_2[2] = { 'o', 's' }; +static symbol s_2_3[2] = { 'i', 'v' }; + +static struct among a_2[4] = +{ +/* 0 */ { 2, s_2_0, -1, -1, 0}, +/* 1 */ { 2, s_2_1, -1, -1, 0}, +/* 2 */ { 2, s_2_2, -1, -1, 0}, +/* 3 */ { 2, s_2_3, -1, 1, 0} +}; + +static symbol s_3_0[4] = { 'a', 'n', 't', 'e' }; +static symbol s_3_1[4] = { 'a', 'v', 'e', 'l' }; +static symbol s_3_2[5] = { 0xC3, 0xAD, 'v', 'e', 'l' }; + +static struct among a_3[3] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0}, +/* 2 */ { 5, s_3_2, -1, 1, 0} +}; + +static symbol s_4_0[2] = { 'i', 'c' }; +static symbol s_4_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_4_2[2] = { 'i', 'v' }; + +static struct among a_4[3] = +{ +/* 0 */ { 2, s_4_0, -1, 1, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 2, s_4_2, -1, 1, 0} +}; + +static symbol s_5_0[3] = { 'i', 'c', 'a' }; +static symbol s_5_1[6] = { 0xC3, 0xA2, 'n', 'c', 'i', 'a' }; +static symbol s_5_2[6] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a' }; +static symbol s_5_3[3] = { 'i', 'r', 'a' }; +static symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' }; +static symbol s_5_5[3] = { 'o', 's', 'a' }; +static symbol s_5_6[4] = { 'i', 's', 't', 'a' }; +static symbol s_5_7[3] = { 'i', 'v', 'a' }; +static symbol s_5_8[3] = { 'e', 'z', 'a' }; +static symbol s_5_9[6] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a' }; +static symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' }; +static symbol s_5_11[4] = { 'a', 'n', 't', 'e' }; +static symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_5_14[5] = { 0xC3, 0xA1, 'v', 'e', 'l' }; +static symbol s_5_15[5] = { 0xC3, 0xAD, 'v', 'e', 'l' }; +static symbol s_5_16[6] = { 'u', 'c', 'i', 0xC3, 0xB3, 'n' }; +static symbol s_5_17[3] = { 'i', 'c', 'o' }; +static symbol s_5_18[4] = { 'i', 's', 'm', 'o' }; +static symbol s_5_19[3] = { 'o', 's', 'o' }; +static symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static symbol s_5_22[3] = { 'i', 'v', 'o' }; +static symbol s_5_23[6] = { 'a', 0xC3, 0xA7, 'a', '~', 'o' }; +static symbol s_5_24[4] = { 'a', 'd', 'o', 'r' }; +static symbol s_5_25[4] = { 'i', 'c', 'a', 's' }; +static symbol s_5_26[7] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a', 's' }; +static symbol s_5_27[4] = { 'i', 'r', 'a', 's' }; +static symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static symbol s_5_29[4] = { 'o', 's', 'a', 's' }; +static symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' }; +static symbol s_5_31[4] = { 'i', 'v', 'a', 's' }; +static symbol s_5_32[4] = { 'e', 'z', 'a', 's' }; +static symbol s_5_33[7] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a', 's' }; +static symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; +static symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_5_38[7] = { 'a', 0xC3, 0xA7, 'o', '~', 'e', 's' }; +static symbol s_5_39[4] = { 'i', 'c', 'o', 's' }; +static symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' }; +static symbol s_5_41[4] = { 'o', 's', 'o', 's' }; +static symbol s_5_42[7] = { 'a', 'm', 'e', 'n', 't', 'o', 's' }; +static symbol s_5_43[7] = { 'i', 'm', 'e', 'n', 't', 'o', 's' }; +static symbol s_5_44[4] = { 'i', 'v', 'o', 's' }; + +static struct among a_5[45] = +{ +/* 0 */ { 3, s_5_0, -1, 1, 0}, +/* 1 */ { 6, s_5_1, -1, 1, 0}, +/* 2 */ { 6, s_5_2, -1, 4, 0}, +/* 3 */ { 3, s_5_3, -1, 9, 0}, +/* 4 */ { 5, s_5_4, -1, 1, 0}, +/* 5 */ { 3, s_5_5, -1, 1, 0}, +/* 6 */ { 4, s_5_6, -1, 1, 0}, +/* 7 */ { 3, s_5_7, -1, 8, 0}, +/* 8 */ { 3, s_5_8, -1, 1, 0}, +/* 9 */ { 6, s_5_9, -1, 2, 0}, +/* 10 */ { 5, s_5_10, -1, 7, 0}, +/* 11 */ { 4, s_5_11, -1, 1, 0}, +/* 12 */ { 5, s_5_12, -1, 6, 0}, +/* 13 */ { 6, s_5_13, 12, 5, 0}, +/* 14 */ { 5, s_5_14, -1, 1, 0}, +/* 15 */ { 5, s_5_15, -1, 1, 0}, +/* 16 */ { 6, s_5_16, -1, 3, 0}, +/* 17 */ { 3, s_5_17, -1, 1, 0}, +/* 18 */ { 4, s_5_18, -1, 1, 0}, +/* 19 */ { 3, s_5_19, -1, 1, 0}, +/* 20 */ { 6, s_5_20, -1, 1, 0}, +/* 21 */ { 6, s_5_21, -1, 1, 0}, +/* 22 */ { 3, s_5_22, -1, 8, 0}, +/* 23 */ { 6, s_5_23, -1, 1, 0}, +/* 24 */ { 4, s_5_24, -1, 1, 0}, +/* 25 */ { 4, s_5_25, -1, 1, 0}, +/* 26 */ { 7, s_5_26, -1, 4, 0}, +/* 27 */ { 4, s_5_27, -1, 9, 0}, +/* 28 */ { 6, s_5_28, -1, 1, 0}, +/* 29 */ { 4, s_5_29, -1, 1, 0}, +/* 30 */ { 5, s_5_30, -1, 1, 0}, +/* 31 */ { 4, s_5_31, -1, 8, 0}, +/* 32 */ { 4, s_5_32, -1, 1, 0}, +/* 33 */ { 7, s_5_33, -1, 2, 0}, +/* 34 */ { 6, s_5_34, -1, 7, 0}, +/* 35 */ { 7, s_5_35, -1, 3, 0}, +/* 36 */ { 6, s_5_36, -1, 1, 0}, +/* 37 */ { 5, s_5_37, -1, 1, 0}, +/* 38 */ { 7, s_5_38, -1, 1, 0}, +/* 39 */ { 4, s_5_39, -1, 1, 0}, +/* 40 */ { 5, s_5_40, -1, 1, 0}, +/* 41 */ { 4, s_5_41, -1, 1, 0}, +/* 42 */ { 7, s_5_42, -1, 1, 0}, +/* 43 */ { 7, s_5_43, -1, 1, 0}, +/* 44 */ { 4, s_5_44, -1, 8, 0} +}; + +static symbol s_6_0[3] = { 'a', 'd', 'a' }; +static symbol s_6_1[3] = { 'i', 'd', 'a' }; +static symbol s_6_2[2] = { 'i', 'a' }; +static symbol s_6_3[4] = { 'a', 'r', 'i', 'a' }; +static symbol s_6_4[4] = { 'e', 'r', 'i', 'a' }; +static symbol s_6_5[4] = { 'i', 'r', 'i', 'a' }; +static symbol s_6_6[3] = { 'a', 'r', 'a' }; +static symbol s_6_7[3] = { 'e', 'r', 'a' }; +static symbol s_6_8[3] = { 'i', 'r', 'a' }; +static symbol s_6_9[3] = { 'a', 'v', 'a' }; +static symbol s_6_10[4] = { 'a', 's', 's', 'e' }; +static symbol s_6_11[4] = { 'e', 's', 's', 'e' }; +static symbol s_6_12[4] = { 'i', 's', 's', 'e' }; +static symbol s_6_13[4] = { 'a', 's', 't', 'e' }; +static symbol s_6_14[4] = { 'e', 's', 't', 'e' }; +static symbol s_6_15[4] = { 'i', 's', 't', 'e' }; +static symbol s_6_16[2] = { 'e', 'i' }; +static symbol s_6_17[4] = { 'a', 'r', 'e', 'i' }; +static symbol s_6_18[4] = { 'e', 'r', 'e', 'i' }; +static symbol s_6_19[4] = { 'i', 'r', 'e', 'i' }; +static symbol s_6_20[2] = { 'a', 'm' }; +static symbol s_6_21[3] = { 'i', 'a', 'm' }; +static symbol s_6_22[5] = { 'a', 'r', 'i', 'a', 'm' }; +static symbol s_6_23[5] = { 'e', 'r', 'i', 'a', 'm' }; +static symbol s_6_24[5] = { 'i', 'r', 'i', 'a', 'm' }; +static symbol s_6_25[4] = { 'a', 'r', 'a', 'm' }; +static symbol s_6_26[4] = { 'e', 'r', 'a', 'm' }; +static symbol s_6_27[4] = { 'i', 'r', 'a', 'm' }; +static symbol s_6_28[4] = { 'a', 'v', 'a', 'm' }; +static symbol s_6_29[2] = { 'e', 'm' }; +static symbol s_6_30[4] = { 'a', 'r', 'e', 'm' }; +static symbol s_6_31[4] = { 'e', 'r', 'e', 'm' }; +static symbol s_6_32[4] = { 'i', 'r', 'e', 'm' }; +static symbol s_6_33[5] = { 'a', 's', 's', 'e', 'm' }; +static symbol s_6_34[5] = { 'e', 's', 's', 'e', 'm' }; +static symbol s_6_35[5] = { 'i', 's', 's', 'e', 'm' }; +static symbol s_6_36[3] = { 'a', 'd', 'o' }; +static symbol s_6_37[3] = { 'i', 'd', 'o' }; +static symbol s_6_38[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_6_39[4] = { 'e', 'n', 'd', 'o' }; +static symbol s_6_40[4] = { 'i', 'n', 'd', 'o' }; +static symbol s_6_41[5] = { 'a', 'r', 'a', '~', 'o' }; +static symbol s_6_42[5] = { 'e', 'r', 'a', '~', 'o' }; +static symbol s_6_43[5] = { 'i', 'r', 'a', '~', 'o' }; +static symbol s_6_44[2] = { 'a', 'r' }; +static symbol s_6_45[2] = { 'e', 'r' }; +static symbol s_6_46[2] = { 'i', 'r' }; +static symbol s_6_47[2] = { 'a', 's' }; +static symbol s_6_48[4] = { 'a', 'd', 'a', 's' }; +static symbol s_6_49[4] = { 'i', 'd', 'a', 's' }; +static symbol s_6_50[3] = { 'i', 'a', 's' }; +static symbol s_6_51[5] = { 'a', 'r', 'i', 'a', 's' }; +static symbol s_6_52[5] = { 'e', 'r', 'i', 'a', 's' }; +static symbol s_6_53[5] = { 'i', 'r', 'i', 'a', 's' }; +static symbol s_6_54[4] = { 'a', 'r', 'a', 's' }; +static symbol s_6_55[4] = { 'e', 'r', 'a', 's' }; +static symbol s_6_56[4] = { 'i', 'r', 'a', 's' }; +static symbol s_6_57[4] = { 'a', 'v', 'a', 's' }; +static symbol s_6_58[2] = { 'e', 's' }; +static symbol s_6_59[5] = { 'a', 'r', 'd', 'e', 's' }; +static symbol s_6_60[5] = { 'e', 'r', 'd', 'e', 's' }; +static symbol s_6_61[5] = { 'i', 'r', 'd', 'e', 's' }; +static symbol s_6_62[4] = { 'a', 'r', 'e', 's' }; +static symbol s_6_63[4] = { 'e', 'r', 'e', 's' }; +static symbol s_6_64[4] = { 'i', 'r', 'e', 's' }; +static symbol s_6_65[5] = { 'a', 's', 's', 'e', 's' }; +static symbol s_6_66[5] = { 'e', 's', 's', 'e', 's' }; +static symbol s_6_67[5] = { 'i', 's', 's', 'e', 's' }; +static symbol s_6_68[5] = { 'a', 's', 't', 'e', 's' }; +static symbol s_6_69[5] = { 'e', 's', 't', 'e', 's' }; +static symbol s_6_70[5] = { 'i', 's', 't', 'e', 's' }; +static symbol s_6_71[2] = { 'i', 's' }; +static symbol s_6_72[3] = { 'a', 'i', 's' }; +static symbol s_6_73[3] = { 'e', 'i', 's' }; +static symbol s_6_74[5] = { 'a', 'r', 'e', 'i', 's' }; +static symbol s_6_75[5] = { 'e', 'r', 'e', 'i', 's' }; +static symbol s_6_76[5] = { 'i', 'r', 'e', 'i', 's' }; +static symbol s_6_77[6] = { 0xC3, 0xA1, 'r', 'e', 'i', 's' }; +static symbol s_6_78[6] = { 0xC3, 0xA9, 'r', 'e', 'i', 's' }; +static symbol s_6_79[6] = { 0xC3, 0xAD, 'r', 'e', 'i', 's' }; +static symbol s_6_80[7] = { 0xC3, 0xA1, 's', 's', 'e', 'i', 's' }; +static symbol s_6_81[7] = { 0xC3, 0xA9, 's', 's', 'e', 'i', 's' }; +static symbol s_6_82[7] = { 0xC3, 0xAD, 's', 's', 'e', 'i', 's' }; +static symbol s_6_83[6] = { 0xC3, 0xA1, 'v', 'e', 'i', 's' }; +static symbol s_6_84[5] = { 0xC3, 0xAD, 'e', 'i', 's' }; +static symbol s_6_85[7] = { 'a', 'r', 0xC3, 0xAD, 'e', 'i', 's' }; +static symbol s_6_86[7] = { 'e', 'r', 0xC3, 0xAD, 'e', 'i', 's' }; +static symbol s_6_87[7] = { 'i', 'r', 0xC3, 0xAD, 'e', 'i', 's' }; +static symbol s_6_88[4] = { 'a', 'd', 'o', 's' }; +static symbol s_6_89[4] = { 'i', 'd', 'o', 's' }; +static symbol s_6_90[4] = { 'a', 'm', 'o', 's' }; +static symbol s_6_91[7] = { 0xC3, 0xA1, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_92[7] = { 0xC3, 0xA9, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_93[7] = { 0xC3, 0xAD, 'r', 'a', 'm', 'o', 's' }; +static symbol s_6_94[7] = { 0xC3, 0xA1, 'v', 'a', 'm', 'o', 's' }; +static symbol s_6_95[6] = { 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_6_96[8] = { 'a', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_6_97[8] = { 'e', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_6_98[8] = { 'i', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_6_99[4] = { 'e', 'm', 'o', 's' }; +static symbol s_6_100[6] = { 'a', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_101[6] = { 'e', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_102[6] = { 'i', 'r', 'e', 'm', 'o', 's' }; +static symbol s_6_103[8] = { 0xC3, 0xA1, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_104[8] = { 0xC3, 0xAA, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_105[8] = { 0xC3, 0xAD, 's', 's', 'e', 'm', 'o', 's' }; +static symbol s_6_106[4] = { 'i', 'm', 'o', 's' }; +static symbol s_6_107[5] = { 'a', 'r', 'm', 'o', 's' }; +static symbol s_6_108[5] = { 'e', 'r', 'm', 'o', 's' }; +static symbol s_6_109[5] = { 'i', 'r', 'm', 'o', 's' }; +static symbol s_6_110[5] = { 0xC3, 0xA1, 'm', 'o', 's' }; +static symbol s_6_111[5] = { 'a', 'r', 0xC3, 0xA1, 's' }; +static symbol s_6_112[5] = { 'e', 'r', 0xC3, 0xA1, 's' }; +static symbol s_6_113[5] = { 'i', 'r', 0xC3, 0xA1, 's' }; +static symbol s_6_114[2] = { 'e', 'u' }; +static symbol s_6_115[2] = { 'i', 'u' }; +static symbol s_6_116[2] = { 'o', 'u' }; +static symbol s_6_117[4] = { 'a', 'r', 0xC3, 0xA1 }; +static symbol s_6_118[4] = { 'e', 'r', 0xC3, 0xA1 }; +static symbol s_6_119[4] = { 'i', 'r', 0xC3, 0xA1 }; + +static struct among a_6[120] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 3, s_6_1, -1, 1, 0}, +/* 2 */ { 2, s_6_2, -1, 1, 0}, +/* 3 */ { 4, s_6_3, 2, 1, 0}, +/* 4 */ { 4, s_6_4, 2, 1, 0}, +/* 5 */ { 4, s_6_5, 2, 1, 0}, +/* 6 */ { 3, s_6_6, -1, 1, 0}, +/* 7 */ { 3, s_6_7, -1, 1, 0}, +/* 8 */ { 3, s_6_8, -1, 1, 0}, +/* 9 */ { 3, s_6_9, -1, 1, 0}, +/* 10 */ { 4, s_6_10, -1, 1, 0}, +/* 11 */ { 4, s_6_11, -1, 1, 0}, +/* 12 */ { 4, s_6_12, -1, 1, 0}, +/* 13 */ { 4, s_6_13, -1, 1, 0}, +/* 14 */ { 4, s_6_14, -1, 1, 0}, +/* 15 */ { 4, s_6_15, -1, 1, 0}, +/* 16 */ { 2, s_6_16, -1, 1, 0}, +/* 17 */ { 4, s_6_17, 16, 1, 0}, +/* 18 */ { 4, s_6_18, 16, 1, 0}, +/* 19 */ { 4, s_6_19, 16, 1, 0}, +/* 20 */ { 2, s_6_20, -1, 1, 0}, +/* 21 */ { 3, s_6_21, 20, 1, 0}, +/* 22 */ { 5, s_6_22, 21, 1, 0}, +/* 23 */ { 5, s_6_23, 21, 1, 0}, +/* 24 */ { 5, s_6_24, 21, 1, 0}, +/* 25 */ { 4, s_6_25, 20, 1, 0}, +/* 26 */ { 4, s_6_26, 20, 1, 0}, +/* 27 */ { 4, s_6_27, 20, 1, 0}, +/* 28 */ { 4, s_6_28, 20, 1, 0}, +/* 29 */ { 2, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, 29, 1, 0}, +/* 31 */ { 4, s_6_31, 29, 1, 0}, +/* 32 */ { 4, s_6_32, 29, 1, 0}, +/* 33 */ { 5, s_6_33, 29, 1, 0}, +/* 34 */ { 5, s_6_34, 29, 1, 0}, +/* 35 */ { 5, s_6_35, 29, 1, 0}, +/* 36 */ { 3, s_6_36, -1, 1, 0}, +/* 37 */ { 3, s_6_37, -1, 1, 0}, +/* 38 */ { 4, s_6_38, -1, 1, 0}, +/* 39 */ { 4, s_6_39, -1, 1, 0}, +/* 40 */ { 4, s_6_40, -1, 1, 0}, +/* 41 */ { 5, s_6_41, -1, 1, 0}, +/* 42 */ { 5, s_6_42, -1, 1, 0}, +/* 43 */ { 5, s_6_43, -1, 1, 0}, +/* 44 */ { 2, s_6_44, -1, 1, 0}, +/* 45 */ { 2, s_6_45, -1, 1, 0}, +/* 46 */ { 2, s_6_46, -1, 1, 0}, +/* 47 */ { 2, s_6_47, -1, 1, 0}, +/* 48 */ { 4, s_6_48, 47, 1, 0}, +/* 49 */ { 4, s_6_49, 47, 1, 0}, +/* 50 */ { 3, s_6_50, 47, 1, 0}, +/* 51 */ { 5, s_6_51, 50, 1, 0}, +/* 52 */ { 5, s_6_52, 50, 1, 0}, +/* 53 */ { 5, s_6_53, 50, 1, 0}, +/* 54 */ { 4, s_6_54, 47, 1, 0}, +/* 55 */ { 4, s_6_55, 47, 1, 0}, +/* 56 */ { 4, s_6_56, 47, 1, 0}, +/* 57 */ { 4, s_6_57, 47, 1, 0}, +/* 58 */ { 2, s_6_58, -1, 1, 0}, +/* 59 */ { 5, s_6_59, 58, 1, 0}, +/* 60 */ { 5, s_6_60, 58, 1, 0}, +/* 61 */ { 5, s_6_61, 58, 1, 0}, +/* 62 */ { 4, s_6_62, 58, 1, 0}, +/* 63 */ { 4, s_6_63, 58, 1, 0}, +/* 64 */ { 4, s_6_64, 58, 1, 0}, +/* 65 */ { 5, s_6_65, 58, 1, 0}, +/* 66 */ { 5, s_6_66, 58, 1, 0}, +/* 67 */ { 5, s_6_67, 58, 1, 0}, +/* 68 */ { 5, s_6_68, 58, 1, 0}, +/* 69 */ { 5, s_6_69, 58, 1, 0}, +/* 70 */ { 5, s_6_70, 58, 1, 0}, +/* 71 */ { 2, s_6_71, -1, 1, 0}, +/* 72 */ { 3, s_6_72, 71, 1, 0}, +/* 73 */ { 3, s_6_73, 71, 1, 0}, +/* 74 */ { 5, s_6_74, 73, 1, 0}, +/* 75 */ { 5, s_6_75, 73, 1, 0}, +/* 76 */ { 5, s_6_76, 73, 1, 0}, +/* 77 */ { 6, s_6_77, 73, 1, 0}, +/* 78 */ { 6, s_6_78, 73, 1, 0}, +/* 79 */ { 6, s_6_79, 73, 1, 0}, +/* 80 */ { 7, s_6_80, 73, 1, 0}, +/* 81 */ { 7, s_6_81, 73, 1, 0}, +/* 82 */ { 7, s_6_82, 73, 1, 0}, +/* 83 */ { 6, s_6_83, 73, 1, 0}, +/* 84 */ { 5, s_6_84, 73, 1, 0}, +/* 85 */ { 7, s_6_85, 84, 1, 0}, +/* 86 */ { 7, s_6_86, 84, 1, 0}, +/* 87 */ { 7, s_6_87, 84, 1, 0}, +/* 88 */ { 4, s_6_88, -1, 1, 0}, +/* 89 */ { 4, s_6_89, -1, 1, 0}, +/* 90 */ { 4, s_6_90, -1, 1, 0}, +/* 91 */ { 7, s_6_91, 90, 1, 0}, +/* 92 */ { 7, s_6_92, 90, 1, 0}, +/* 93 */ { 7, s_6_93, 90, 1, 0}, +/* 94 */ { 7, s_6_94, 90, 1, 0}, +/* 95 */ { 6, s_6_95, 90, 1, 0}, +/* 96 */ { 8, s_6_96, 95, 1, 0}, +/* 97 */ { 8, s_6_97, 95, 1, 0}, +/* 98 */ { 8, s_6_98, 95, 1, 0}, +/* 99 */ { 4, s_6_99, -1, 1, 0}, +/*100 */ { 6, s_6_100, 99, 1, 0}, +/*101 */ { 6, s_6_101, 99, 1, 0}, +/*102 */ { 6, s_6_102, 99, 1, 0}, +/*103 */ { 8, s_6_103, 99, 1, 0}, +/*104 */ { 8, s_6_104, 99, 1, 0}, +/*105 */ { 8, s_6_105, 99, 1, 0}, +/*106 */ { 4, s_6_106, -1, 1, 0}, +/*107 */ { 5, s_6_107, -1, 1, 0}, +/*108 */ { 5, s_6_108, -1, 1, 0}, +/*109 */ { 5, s_6_109, -1, 1, 0}, +/*110 */ { 5, s_6_110, -1, 1, 0}, +/*111 */ { 5, s_6_111, -1, 1, 0}, +/*112 */ { 5, s_6_112, -1, 1, 0}, +/*113 */ { 5, s_6_113, -1, 1, 0}, +/*114 */ { 2, s_6_114, -1, 1, 0}, +/*115 */ { 2, s_6_115, -1, 1, 0}, +/*116 */ { 2, s_6_116, -1, 1, 0}, +/*117 */ { 4, s_6_117, -1, 1, 0}, +/*118 */ { 4, s_6_118, -1, 1, 0}, +/*119 */ { 4, s_6_119, -1, 1, 0} +}; + +static symbol s_7_0[1] = { 'a' }; +static symbol s_7_1[1] = { 'i' }; +static symbol s_7_2[1] = { 'o' }; +static symbol s_7_3[2] = { 'o', 's' }; +static symbol s_7_4[2] = { 0xC3, 0xA1 }; +static symbol s_7_5[2] = { 0xC3, 0xAD }; +static symbol s_7_6[2] = { 0xC3, 0xB3 }; + +static struct among a_7[7] = +{ +/* 0 */ { 1, s_7_0, -1, 1, 0}, +/* 1 */ { 1, s_7_1, -1, 1, 0}, +/* 2 */ { 1, s_7_2, -1, 1, 0}, +/* 3 */ { 2, s_7_3, -1, 1, 0}, +/* 4 */ { 2, s_7_4, -1, 1, 0}, +/* 5 */ { 2, s_7_5, -1, 1, 0}, +/* 6 */ { 2, s_7_6, -1, 1, 0} +}; + +static symbol s_8_0[1] = { 'e' }; +static symbol s_8_1[2] = { 0xC3, 0xA7 }; +static symbol s_8_2[2] = { 0xC3, 0xA9 }; +static symbol s_8_3[2] = { 0xC3, 0xAA }; + +static struct among a_8[4] = +{ +/* 0 */ { 1, s_8_0, -1, 1, 0}, +/* 1 */ { 2, s_8_1, -1, 2, 0}, +/* 2 */ { 2, s_8_2, -1, 1, 0}, +/* 3 */ { 2, s_8_3, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 }; + +static symbol s_0[] = { 'a', '~' }; +static symbol s_1[] = { 'o', '~' }; +static symbol s_2[] = { 0xC3, 0xA3 }; +static symbol s_3[] = { 0xC3, 0xB5 }; +static symbol s_4[] = { 'l', 'o', 'g' }; +static symbol s_5[] = { 'u' }; +static symbol s_6[] = { 'e', 'n', 't', 'e' }; +static symbol s_7[] = { 'a', 't' }; +static symbol s_8[] = { 'a', 't' }; +static symbol s_9[] = { 'e' }; +static symbol s_10[] = { 'i', 'r' }; +static symbol s_11[] = { 'u' }; +static symbol s_12[] = { 'g' }; +static symbol s_13[] = { 'i' }; +static symbol s_14[] = { 'c' }; +static symbol s_15[] = { 'c' }; +static symbol s_16[] = { 'i' }; +static symbol s_17[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 36 */ + int c = z->c; + z->bra = z->c; /* [, line 37 */ + among_var = find_among(z, a_0, 3); /* substring, line 37 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 37 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_1); /* <-, line 39 */ + if (ret < 0) return ret; + } + break; + case 3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 40 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 50 */ + { int c = z->c; /* or, line 52 */ + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab2; + { int c = z->c; /* or, line 51 */ + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab4; + while(1) { /* gopast, line 51 */ + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 51 */ + } + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab2; + while(1) { /* gopast, line 51 */ + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* gopast, line 51 */ + } + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab0; + { int c = z->c; /* or, line 53 */ + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab8; + while(1) { /* gopast, line 53 */ + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab9; + break; + lab9: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab8; + z->c = c; /* gopast, line 53 */ + } + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab0; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 53 */ + } + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 54 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 56 */ + while(1) { /* gopast, line 57 */ + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab11; + break; + lab11: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 57 */ + } + } + while(1) { /* gopast, line 57 */ + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab12; + break; + lab12: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 57 */ + } + } + z->I[1] = z->c; /* setmark p1, line 57 */ + while(1) { /* gopast, line 58 */ + if (!(in_grouping_U(z, g_v, 97, 250))) goto lab13; + break; + lab13: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 58 */ + } + } + while(1) { /* gopast, line 58 */ + if (!(out_grouping_U(z, g_v, 97, 250))) goto lab14; + break; + lab14: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 58 */ + } + } + z->I[2] = z->c; /* setmark p2, line 58 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 62 */ + int c = z->c; + z->bra = z->c; /* [, line 63 */ + among_var = find_among(z, a_1, 3); /* substring, line 63 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 63 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 2, s_2); /* <-, line 64 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 2, s_3); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 66 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 77 */ + among_var = find_among_b(z, a_5, 45); /* substring, line 77 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 77 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 93 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 93 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 98 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 102 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 110 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_2, 4); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 112 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 112 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 112 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + z->ket = z->c; /* [, line 113 */ + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 113 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 113 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 113 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + break; + case 6: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 122 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 122 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 123 */ + z->ket = z->c; /* [, line 124 */ + among_var = find_among_b(z, a_3, 3); /* substring, line 124 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 124 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 127 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 134 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 135 */ + z->ket = z->c; /* [, line 136 */ + among_var = find_among_b(z, a_4, 3); /* substring, line 136 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 136 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 139 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 146 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 146 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 147 */ + z->ket = z->c; /* [, line 148 */ + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 148 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 148 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 148 */ + if (ret < 0) return ret; + } + lab3: + ; + } + break; + case 9: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 153 */ + if (ret < 0) return ret; + } + if (!(eq_s_b(z, 1, s_9))) return 0; + { int ret; + ret = slice_from_s(z, 2, s_10); /* <-, line 154 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 159 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 159 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 160 */ + among_var = find_among_b(z, a_6, 120); /* substring, line 160 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 160 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 184 */ + among_var = find_among_b(z, a_7, 7); /* substring, line 184 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 184 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 187 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 187 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_residual_form(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 192 */ + among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 192 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 194 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 194 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 194 */ + { int m = z->l - z->c; (void) m; /* or, line 194 */ + if (!(eq_s_b(z, 1, s_11))) goto lab1; + z->bra = z->c; /* ], line 194 */ + { int m_test = z->l - z->c; /* test, line 194 */ + if (!(eq_s_b(z, 1, s_12))) goto lab1; + z->c = z->l - m_test; + } + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 1, s_13))) return 0; + z->bra = z->c; /* ], line 195 */ + { int m_test = z->l - z->c; /* test, line 195 */ + if (!(eq_s_b(z, 1, s_14))) return 0; + z->c = z->l - m_test; + } + } + lab0: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 195 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 195 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_15); /* <-, line 196 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int portuguese_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 202 */ + { int ret = r_prelude(z); + if (ret == 0) goto lab0; /* call prelude, line 202 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + { int c = z->c; /* do, line 203 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab1; /* call mark_regions, line 203 */ + if (ret < 0) return ret; + } + lab1: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + + { int m = z->l - z->c; (void) m; /* do, line 205 */ + { int m = z->l - z->c; (void) m; /* or, line 209 */ + { int m = z->l - z->c; (void) m; /* and, line 207 */ + { int m = z->l - z->c; (void) m; /* or, line 206 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab6; /* call standard_suffix, line 206 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab4; /* call verb_suffix, line 206 */ + if (ret < 0) return ret; + } + } + lab5: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 207 */ + z->ket = z->c; /* [, line 207 */ + if (!(eq_s_b(z, 1, s_16))) goto lab7; + z->bra = z->c; /* ], line 207 */ + { int m_test = z->l - z->c; /* test, line 207 */ + if (!(eq_s_b(z, 1, s_17))) goto lab7; + z->c = z->l - m_test; + } + { int ret = r_RV(z); + if (ret == 0) goto lab7; /* call RV, line 207 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 207 */ + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m; + } + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab2; /* call residual_suffix, line 209 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 211 */ + { int ret = r_residual_form(z); + if (ret == 0) goto lab8; /* call residual_form, line 211 */ + if (ret < 0) return ret; + } + lab8: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 213 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab9; /* call postlude, line 213 */ + if (ret < 0) return ret; + } + lab9: + z->c = c; + } + return 1; +} + +extern struct SN_env * portuguese_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void portuguese_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.h new file mode 100644 index 00000000000..9fe7f9aa811 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_portuguese.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * portuguese_UTF_8_create_env(void); +extern void portuguese_UTF_8_close_env(struct SN_env * z); + +extern int portuguese_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.c new file mode 100644 index 00000000000..19581ddeec6 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.c @@ -0,0 +1,709 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int russian_UTF_8_stem(struct SN_env * z); +static int r_tidy_up(struct SN_env * z); +static int r_derivational(struct SN_env * z); +static int r_noun(struct SN_env * z); +static int r_verb(struct SN_env * z); +static int r_reflexive(struct SN_env * z); +static int r_adjectival(struct SN_env * z); +static int r_adjective(struct SN_env * z); +static int r_perfective_gerund(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * russian_UTF_8_create_env(void); +extern void russian_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[10] = { 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C }; +static symbol s_0_1[12] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C }; +static symbol s_0_2[12] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C }; +static symbol s_0_3[2] = { 0xD0, 0xB2 }; +static symbol s_0_4[4] = { 0xD1, 0x8B, 0xD0, 0xB2 }; +static symbol s_0_5[4] = { 0xD0, 0xB8, 0xD0, 0xB2 }; +static symbol s_0_6[6] = { 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 }; +static symbol s_0_7[8] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 }; +static symbol s_0_8[8] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 }; + +static struct among a_0[9] = +{ +/* 0 */ { 10, s_0_0, -1, 1, 0}, +/* 1 */ { 12, s_0_1, 0, 2, 0}, +/* 2 */ { 12, s_0_2, 0, 2, 0}, +/* 3 */ { 2, s_0_3, -1, 1, 0}, +/* 4 */ { 4, s_0_4, 3, 2, 0}, +/* 5 */ { 4, s_0_5, 3, 2, 0}, +/* 6 */ { 6, s_0_6, -1, 1, 0}, +/* 7 */ { 8, s_0_7, 6, 2, 0}, +/* 8 */ { 8, s_0_8, 6, 2, 0} +}; + +static symbol s_1_0[6] = { 0xD0, 0xB5, 0xD0, 0xBC, 0xD1, 0x83 }; +static symbol s_1_1[6] = { 0xD0, 0xBE, 0xD0, 0xBC, 0xD1, 0x83 }; +static symbol s_1_2[4] = { 0xD1, 0x8B, 0xD1, 0x85 }; +static symbol s_1_3[4] = { 0xD0, 0xB8, 0xD1, 0x85 }; +static symbol s_1_4[4] = { 0xD1, 0x83, 0xD1, 0x8E }; +static symbol s_1_5[4] = { 0xD1, 0x8E, 0xD1, 0x8E }; +static symbol s_1_6[4] = { 0xD0, 0xB5, 0xD1, 0x8E }; +static symbol s_1_7[4] = { 0xD0, 0xBE, 0xD1, 0x8E }; +static symbol s_1_8[4] = { 0xD1, 0x8F, 0xD1, 0x8F }; +static symbol s_1_9[4] = { 0xD0, 0xB0, 0xD1, 0x8F }; +static symbol s_1_10[4] = { 0xD1, 0x8B, 0xD0, 0xB5 }; +static symbol s_1_11[4] = { 0xD0, 0xB5, 0xD0, 0xB5 }; +static symbol s_1_12[4] = { 0xD0, 0xB8, 0xD0, 0xB5 }; +static symbol s_1_13[4] = { 0xD0, 0xBE, 0xD0, 0xB5 }; +static symbol s_1_14[6] = { 0xD1, 0x8B, 0xD0, 0xBC, 0xD0, 0xB8 }; +static symbol s_1_15[6] = { 0xD0, 0xB8, 0xD0, 0xBC, 0xD0, 0xB8 }; +static symbol s_1_16[4] = { 0xD1, 0x8B, 0xD0, 0xB9 }; +static symbol s_1_17[4] = { 0xD0, 0xB5, 0xD0, 0xB9 }; +static symbol s_1_18[4] = { 0xD0, 0xB8, 0xD0, 0xB9 }; +static symbol s_1_19[4] = { 0xD0, 0xBE, 0xD0, 0xB9 }; +static symbol s_1_20[4] = { 0xD1, 0x8B, 0xD0, 0xBC }; +static symbol s_1_21[4] = { 0xD0, 0xB5, 0xD0, 0xBC }; +static symbol s_1_22[4] = { 0xD0, 0xB8, 0xD0, 0xBC }; +static symbol s_1_23[4] = { 0xD0, 0xBE, 0xD0, 0xBC }; +static symbol s_1_24[6] = { 0xD0, 0xB5, 0xD0, 0xB3, 0xD0, 0xBE }; +static symbol s_1_25[6] = { 0xD0, 0xBE, 0xD0, 0xB3, 0xD0, 0xBE }; + +static struct among a_1[26] = +{ +/* 0 */ { 6, s_1_0, -1, 1, 0}, +/* 1 */ { 6, s_1_1, -1, 1, 0}, +/* 2 */ { 4, s_1_2, -1, 1, 0}, +/* 3 */ { 4, s_1_3, -1, 1, 0}, +/* 4 */ { 4, s_1_4, -1, 1, 0}, +/* 5 */ { 4, s_1_5, -1, 1, 0}, +/* 6 */ { 4, s_1_6, -1, 1, 0}, +/* 7 */ { 4, s_1_7, -1, 1, 0}, +/* 8 */ { 4, s_1_8, -1, 1, 0}, +/* 9 */ { 4, s_1_9, -1, 1, 0}, +/* 10 */ { 4, s_1_10, -1, 1, 0}, +/* 11 */ { 4, s_1_11, -1, 1, 0}, +/* 12 */ { 4, s_1_12, -1, 1, 0}, +/* 13 */ { 4, s_1_13, -1, 1, 0}, +/* 14 */ { 6, s_1_14, -1, 1, 0}, +/* 15 */ { 6, s_1_15, -1, 1, 0}, +/* 16 */ { 4, s_1_16, -1, 1, 0}, +/* 17 */ { 4, s_1_17, -1, 1, 0}, +/* 18 */ { 4, s_1_18, -1, 1, 0}, +/* 19 */ { 4, s_1_19, -1, 1, 0}, +/* 20 */ { 4, s_1_20, -1, 1, 0}, +/* 21 */ { 4, s_1_21, -1, 1, 0}, +/* 22 */ { 4, s_1_22, -1, 1, 0}, +/* 23 */ { 4, s_1_23, -1, 1, 0}, +/* 24 */ { 6, s_1_24, -1, 1, 0}, +/* 25 */ { 6, s_1_25, -1, 1, 0} +}; + +static symbol s_2_0[4] = { 0xD0, 0xB2, 0xD1, 0x88 }; +static symbol s_2_1[6] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88 }; +static symbol s_2_2[6] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88 }; +static symbol s_2_3[2] = { 0xD1, 0x89 }; +static symbol s_2_4[4] = { 0xD1, 0x8E, 0xD1, 0x89 }; +static symbol s_2_5[6] = { 0xD1, 0x83, 0xD1, 0x8E, 0xD1, 0x89 }; +static symbol s_2_6[4] = { 0xD0, 0xB5, 0xD0, 0xBC }; +static symbol s_2_7[4] = { 0xD0, 0xBD, 0xD0, 0xBD }; + +static struct among a_2[8] = +{ +/* 0 */ { 4, s_2_0, -1, 1, 0}, +/* 1 */ { 6, s_2_1, 0, 2, 0}, +/* 2 */ { 6, s_2_2, 0, 2, 0}, +/* 3 */ { 2, s_2_3, -1, 1, 0}, +/* 4 */ { 4, s_2_4, 3, 1, 0}, +/* 5 */ { 6, s_2_5, 4, 2, 0}, +/* 6 */ { 4, s_2_6, -1, 1, 0}, +/* 7 */ { 4, s_2_7, -1, 1, 0} +}; + +static symbol s_3_0[4] = { 0xD1, 0x81, 0xD1, 0x8C }; +static symbol s_3_1[4] = { 0xD1, 0x81, 0xD1, 0x8F }; + +static struct among a_3[2] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 4, s_3_1, -1, 1, 0} +}; + +static symbol s_4_0[4] = { 0xD1, 0x8B, 0xD1, 0x82 }; +static symbol s_4_1[4] = { 0xD1, 0x8E, 0xD1, 0x82 }; +static symbol s_4_2[6] = { 0xD1, 0x83, 0xD1, 0x8E, 0xD1, 0x82 }; +static symbol s_4_3[4] = { 0xD1, 0x8F, 0xD1, 0x82 }; +static symbol s_4_4[4] = { 0xD0, 0xB5, 0xD1, 0x82 }; +static symbol s_4_5[6] = { 0xD1, 0x83, 0xD0, 0xB5, 0xD1, 0x82 }; +static symbol s_4_6[4] = { 0xD0, 0xB8, 0xD1, 0x82 }; +static symbol s_4_7[4] = { 0xD0, 0xBD, 0xD1, 0x8B }; +static symbol s_4_8[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD1, 0x8B }; +static symbol s_4_9[4] = { 0xD1, 0x82, 0xD1, 0x8C }; +static symbol s_4_10[6] = { 0xD1, 0x8B, 0xD1, 0x82, 0xD1, 0x8C }; +static symbol s_4_11[6] = { 0xD0, 0xB8, 0xD1, 0x82, 0xD1, 0x8C }; +static symbol s_4_12[6] = { 0xD0, 0xB5, 0xD1, 0x88, 0xD1, 0x8C }; +static symbol s_4_13[6] = { 0xD0, 0xB8, 0xD1, 0x88, 0xD1, 0x8C }; +static symbol s_4_14[2] = { 0xD1, 0x8E }; +static symbol s_4_15[4] = { 0xD1, 0x83, 0xD1, 0x8E }; +static symbol s_4_16[4] = { 0xD0, 0xBB, 0xD0, 0xB0 }; +static symbol s_4_17[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xB0 }; +static symbol s_4_18[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB0 }; +static symbol s_4_19[4] = { 0xD0, 0xBD, 0xD0, 0xB0 }; +static symbol s_4_20[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xB0 }; +static symbol s_4_21[6] = { 0xD0, 0xB5, 0xD1, 0x82, 0xD0, 0xB5 }; +static symbol s_4_22[6] = { 0xD0, 0xB8, 0xD1, 0x82, 0xD0, 0xB5 }; +static symbol s_4_23[6] = { 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 }; +static symbol s_4_24[8] = { 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 }; +static symbol s_4_25[8] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 }; +static symbol s_4_26[4] = { 0xD0, 0xBB, 0xD0, 0xB8 }; +static symbol s_4_27[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xB8 }; +static symbol s_4_28[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB8 }; +static symbol s_4_29[2] = { 0xD0, 0xB9 }; +static symbol s_4_30[4] = { 0xD1, 0x83, 0xD0, 0xB9 }; +static symbol s_4_31[4] = { 0xD0, 0xB5, 0xD0, 0xB9 }; +static symbol s_4_32[2] = { 0xD0, 0xBB }; +static symbol s_4_33[4] = { 0xD1, 0x8B, 0xD0, 0xBB }; +static symbol s_4_34[4] = { 0xD0, 0xB8, 0xD0, 0xBB }; +static symbol s_4_35[4] = { 0xD1, 0x8B, 0xD0, 0xBC }; +static symbol s_4_36[4] = { 0xD0, 0xB5, 0xD0, 0xBC }; +static symbol s_4_37[4] = { 0xD0, 0xB8, 0xD0, 0xBC }; +static symbol s_4_38[2] = { 0xD0, 0xBD }; +static symbol s_4_39[4] = { 0xD0, 0xB5, 0xD0, 0xBD }; +static symbol s_4_40[4] = { 0xD0, 0xBB, 0xD0, 0xBE }; +static symbol s_4_41[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xBE }; +static symbol s_4_42[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xBE }; +static symbol s_4_43[4] = { 0xD0, 0xBD, 0xD0, 0xBE }; +static symbol s_4_44[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xBE }; +static symbol s_4_45[6] = { 0xD0, 0xBD, 0xD0, 0xBD, 0xD0, 0xBE }; + +static struct among a_4[46] = +{ +/* 0 */ { 4, s_4_0, -1, 2, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 6, s_4_2, 1, 2, 0}, +/* 3 */ { 4, s_4_3, -1, 2, 0}, +/* 4 */ { 4, s_4_4, -1, 1, 0}, +/* 5 */ { 6, s_4_5, 4, 2, 0}, +/* 6 */ { 4, s_4_6, -1, 2, 0}, +/* 7 */ { 4, s_4_7, -1, 1, 0}, +/* 8 */ { 6, s_4_8, 7, 2, 0}, +/* 9 */ { 4, s_4_9, -1, 1, 0}, +/* 10 */ { 6, s_4_10, 9, 2, 0}, +/* 11 */ { 6, s_4_11, 9, 2, 0}, +/* 12 */ { 6, s_4_12, -1, 1, 0}, +/* 13 */ { 6, s_4_13, -1, 2, 0}, +/* 14 */ { 2, s_4_14, -1, 2, 0}, +/* 15 */ { 4, s_4_15, 14, 2, 0}, +/* 16 */ { 4, s_4_16, -1, 1, 0}, +/* 17 */ { 6, s_4_17, 16, 2, 0}, +/* 18 */ { 6, s_4_18, 16, 2, 0}, +/* 19 */ { 4, s_4_19, -1, 1, 0}, +/* 20 */ { 6, s_4_20, 19, 2, 0}, +/* 21 */ { 6, s_4_21, -1, 1, 0}, +/* 22 */ { 6, s_4_22, -1, 2, 0}, +/* 23 */ { 6, s_4_23, -1, 1, 0}, +/* 24 */ { 8, s_4_24, 23, 2, 0}, +/* 25 */ { 8, s_4_25, 23, 2, 0}, +/* 26 */ { 4, s_4_26, -1, 1, 0}, +/* 27 */ { 6, s_4_27, 26, 2, 0}, +/* 28 */ { 6, s_4_28, 26, 2, 0}, +/* 29 */ { 2, s_4_29, -1, 1, 0}, +/* 30 */ { 4, s_4_30, 29, 2, 0}, +/* 31 */ { 4, s_4_31, 29, 2, 0}, +/* 32 */ { 2, s_4_32, -1, 1, 0}, +/* 33 */ { 4, s_4_33, 32, 2, 0}, +/* 34 */ { 4, s_4_34, 32, 2, 0}, +/* 35 */ { 4, s_4_35, -1, 2, 0}, +/* 36 */ { 4, s_4_36, -1, 1, 0}, +/* 37 */ { 4, s_4_37, -1, 2, 0}, +/* 38 */ { 2, s_4_38, -1, 1, 0}, +/* 39 */ { 4, s_4_39, 38, 2, 0}, +/* 40 */ { 4, s_4_40, -1, 1, 0}, +/* 41 */ { 6, s_4_41, 40, 2, 0}, +/* 42 */ { 6, s_4_42, 40, 2, 0}, +/* 43 */ { 4, s_4_43, -1, 1, 0}, +/* 44 */ { 6, s_4_44, 43, 2, 0}, +/* 45 */ { 6, s_4_45, 43, 1, 0} +}; + +static symbol s_5_0[2] = { 0xD1, 0x83 }; +static symbol s_5_1[4] = { 0xD1, 0x8F, 0xD1, 0x85 }; +static symbol s_5_2[6] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD1, 0x85 }; +static symbol s_5_3[4] = { 0xD0, 0xB0, 0xD1, 0x85 }; +static symbol s_5_4[2] = { 0xD1, 0x8B }; +static symbol s_5_5[2] = { 0xD1, 0x8C }; +static symbol s_5_6[2] = { 0xD1, 0x8E }; +static symbol s_5_7[4] = { 0xD1, 0x8C, 0xD1, 0x8E }; +static symbol s_5_8[4] = { 0xD0, 0xB8, 0xD1, 0x8E }; +static symbol s_5_9[2] = { 0xD1, 0x8F }; +static symbol s_5_10[4] = { 0xD1, 0x8C, 0xD1, 0x8F }; +static symbol s_5_11[4] = { 0xD0, 0xB8, 0xD1, 0x8F }; +static symbol s_5_12[2] = { 0xD0, 0xB0 }; +static symbol s_5_13[4] = { 0xD0, 0xB5, 0xD0, 0xB2 }; +static symbol s_5_14[4] = { 0xD0, 0xBE, 0xD0, 0xB2 }; +static symbol s_5_15[2] = { 0xD0, 0xB5 }; +static symbol s_5_16[4] = { 0xD1, 0x8C, 0xD0, 0xB5 }; +static symbol s_5_17[4] = { 0xD0, 0xB8, 0xD0, 0xB5 }; +static symbol s_5_18[2] = { 0xD0, 0xB8 }; +static symbol s_5_19[4] = { 0xD0, 0xB5, 0xD0, 0xB8 }; +static symbol s_5_20[4] = { 0xD0, 0xB8, 0xD0, 0xB8 }; +static symbol s_5_21[6] = { 0xD1, 0x8F, 0xD0, 0xBC, 0xD0, 0xB8 }; +static symbol s_5_22[8] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD0, 0xBC, 0xD0, 0xB8 }; +static symbol s_5_23[6] = { 0xD0, 0xB0, 0xD0, 0xBC, 0xD0, 0xB8 }; +static symbol s_5_24[2] = { 0xD0, 0xB9 }; +static symbol s_5_25[4] = { 0xD0, 0xB5, 0xD0, 0xB9 }; +static symbol s_5_26[6] = { 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xB9 }; +static symbol s_5_27[4] = { 0xD0, 0xB8, 0xD0, 0xB9 }; +static symbol s_5_28[4] = { 0xD0, 0xBE, 0xD0, 0xB9 }; +static symbol s_5_29[4] = { 0xD1, 0x8F, 0xD0, 0xBC }; +static symbol s_5_30[6] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD0, 0xBC }; +static symbol s_5_31[4] = { 0xD0, 0xB0, 0xD0, 0xBC }; +static symbol s_5_32[4] = { 0xD0, 0xB5, 0xD0, 0xBC }; +static symbol s_5_33[6] = { 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xBC }; +static symbol s_5_34[4] = { 0xD0, 0xBE, 0xD0, 0xBC }; +static symbol s_5_35[2] = { 0xD0, 0xBE }; + +static struct among a_5[36] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 6, s_5_2, 1, 1, 0}, +/* 3 */ { 4, s_5_3, -1, 1, 0}, +/* 4 */ { 2, s_5_4, -1, 1, 0}, +/* 5 */ { 2, s_5_5, -1, 1, 0}, +/* 6 */ { 2, s_5_6, -1, 1, 0}, +/* 7 */ { 4, s_5_7, 6, 1, 0}, +/* 8 */ { 4, s_5_8, 6, 1, 0}, +/* 9 */ { 2, s_5_9, -1, 1, 0}, +/* 10 */ { 4, s_5_10, 9, 1, 0}, +/* 11 */ { 4, s_5_11, 9, 1, 0}, +/* 12 */ { 2, s_5_12, -1, 1, 0}, +/* 13 */ { 4, s_5_13, -1, 1, 0}, +/* 14 */ { 4, s_5_14, -1, 1, 0}, +/* 15 */ { 2, s_5_15, -1, 1, 0}, +/* 16 */ { 4, s_5_16, 15, 1, 0}, +/* 17 */ { 4, s_5_17, 15, 1, 0}, +/* 18 */ { 2, s_5_18, -1, 1, 0}, +/* 19 */ { 4, s_5_19, 18, 1, 0}, +/* 20 */ { 4, s_5_20, 18, 1, 0}, +/* 21 */ { 6, s_5_21, 18, 1, 0}, +/* 22 */ { 8, s_5_22, 21, 1, 0}, +/* 23 */ { 6, s_5_23, 18, 1, 0}, +/* 24 */ { 2, s_5_24, -1, 1, 0}, +/* 25 */ { 4, s_5_25, 24, 1, 0}, +/* 26 */ { 6, s_5_26, 25, 1, 0}, +/* 27 */ { 4, s_5_27, 24, 1, 0}, +/* 28 */ { 4, s_5_28, 24, 1, 0}, +/* 29 */ { 4, s_5_29, -1, 1, 0}, +/* 30 */ { 6, s_5_30, 29, 1, 0}, +/* 31 */ { 4, s_5_31, -1, 1, 0}, +/* 32 */ { 4, s_5_32, -1, 1, 0}, +/* 33 */ { 6, s_5_33, 32, 1, 0}, +/* 34 */ { 4, s_5_34, -1, 1, 0}, +/* 35 */ { 2, s_5_35, -1, 1, 0} +}; + +static symbol s_6_0[6] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82 }; +static symbol s_6_1[8] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x8C }; + +static struct among a_6[2] = +{ +/* 0 */ { 6, s_6_0, -1, 1, 0}, +/* 1 */ { 8, s_6_1, -1, 1, 0} +}; + +static symbol s_7_0[6] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x88 }; +static symbol s_7_1[2] = { 0xD1, 0x8C }; +static symbol s_7_2[8] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x88, 0xD0, 0xB5 }; +static symbol s_7_3[2] = { 0xD0, 0xBD }; + +static struct among a_7[4] = +{ +/* 0 */ { 6, s_7_0, -1, 1, 0}, +/* 1 */ { 2, s_7_1, -1, 3, 0}, +/* 2 */ { 8, s_7_2, -1, 1, 0}, +/* 3 */ { 2, s_7_3, -1, 2, 0} +}; + +static unsigned char g_v[] = { 33, 65, 8, 232 }; + +static symbol s_0[] = { 0xD0, 0xB0 }; +static symbol s_1[] = { 0xD1, 0x8F }; +static symbol s_2[] = { 0xD0, 0xB0 }; +static symbol s_3[] = { 0xD1, 0x8F }; +static symbol s_4[] = { 0xD0, 0xB0 }; +static symbol s_5[] = { 0xD1, 0x8F }; +static symbol s_6[] = { 0xD0, 0xBD }; +static symbol s_7[] = { 0xD0, 0xBD }; +static symbol s_8[] = { 0xD0, 0xBD }; +static symbol s_9[] = { 0xD0, 0xB8 }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + { int c = z->c; /* do, line 61 */ + while(1) { /* gopast, line 62 */ + if (!(in_grouping_U(z, g_v, 1072, 1103))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 62 */ + } + } + z->I[0] = z->c; /* setmark pV, line 62 */ + while(1) { /* gopast, line 62 */ + if (!(out_grouping_U(z, g_v, 1072, 1103))) goto lab2; + break; + lab2: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 62 */ + } + } + while(1) { /* gopast, line 63 */ + if (!(in_grouping_U(z, g_v, 1072, 1103))) goto lab3; + break; + lab3: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 63 */ + } + } + while(1) { /* gopast, line 63 */ + if (!(out_grouping_U(z, g_v, 1072, 1103))) goto lab4; + break; + lab4: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* gopast, line 63 */ + } + } + z->I[1] = z->c; /* setmark p2, line 63 */ + lab0: + z->c = c; + } + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_perfective_gerund(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 72 */ + among_var = find_among_b(z, a_0, 9); /* substring, line 72 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 72 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 76 */ + if (!(eq_s_b(z, 2, s_0))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_1))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 76 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 83 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_adjective(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 88 */ + among_var = find_among_b(z, a_1, 26); /* substring, line 88 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 88 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 97 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_adjectival(struct SN_env * z) { + int among_var; + { int ret = r_adjective(z); + if (ret == 0) return 0; /* call adjective, line 102 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 109 */ + z->ket = z->c; /* [, line 110 */ + among_var = find_among_b(z, a_2, 8); /* substring, line 110 */ + if (!(among_var)) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 110 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab0; } + case 1: + { int m = z->l - z->c; (void) m; /* or, line 115 */ + if (!(eq_s_b(z, 2, s_2))) goto lab2; + goto lab1; + lab2: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m; goto lab0; } + } + lab1: + { int ret; + ret = slice_del(z); /* delete, line 115 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 122 */ + if (ret < 0) return ret; + } + break; + } + lab0: + ; + } + return 1; +} + +static int r_reflexive(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 129 */ + among_var = find_among_b(z, a_3, 2); /* substring, line 129 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 129 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 132 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 137 */ + among_var = find_among_b(z, a_4, 46); /* substring, line 137 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 137 */ + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* or, line 143 */ + if (!(eq_s_b(z, 2, s_4))) goto lab1; + goto lab0; + lab1: + z->c = z->l - m; + if (!(eq_s_b(z, 2, s_5))) return 0; + } + lab0: + { int ret; + ret = slice_del(z); /* delete, line 143 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_noun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 160 */ + among_var = find_among_b(z, a_5, 36); /* substring, line 160 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 160 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 167 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_derivational(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 176 */ + among_var = find_among_b(z, a_6, 2); /* substring, line 176 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 176 */ + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 176 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_tidy_up(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 184 */ + among_var = find_among_b(z, a_7, 4); /* substring, line 184 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 184 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 188 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 189 */ + if (!(eq_s_b(z, 2, s_6))) return 0; + z->bra = z->c; /* ], line 189 */ + if (!(eq_s_b(z, 2, s_7))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 189 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(eq_s_b(z, 2, s_8))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 192 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_del(z); /* delete, line 194 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int russian_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 201 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 201 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 202 */ + + { int m3; /* setlimit, line 202 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 202 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* do, line 203 */ + { int m = z->l - z->c; (void) m; /* or, line 204 */ + { int ret = r_perfective_gerund(z); + if (ret == 0) goto lab3; /* call perfective_gerund, line 204 */ + if (ret < 0) return ret; + } + goto lab2; + lab3: + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* try, line 205 */ + { int ret = r_reflexive(z); + if (ret == 0) { z->c = z->l - m; goto lab4; } /* call reflexive, line 205 */ + if (ret < 0) return ret; + } + lab4: + ; + } + { int m = z->l - z->c; (void) m; /* or, line 206 */ + { int ret = r_adjectival(z); + if (ret == 0) goto lab6; /* call adjectival, line 206 */ + if (ret < 0) return ret; + } + goto lab5; + lab6: + z->c = z->l - m; + { int ret = r_verb(z); + if (ret == 0) goto lab7; /* call verb, line 206 */ + if (ret < 0) return ret; + } + goto lab5; + lab7: + z->c = z->l - m; + { int ret = r_noun(z); + if (ret == 0) goto lab1; /* call noun, line 206 */ + if (ret < 0) return ret; + } + } + lab5: + ; + } + lab2: + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* try, line 209 */ + z->ket = z->c; /* [, line 209 */ + if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m; goto lab8; } + z->bra = z->c; /* ], line 209 */ + { int ret; + ret = slice_del(z); /* delete, line 209 */ + if (ret < 0) return ret; + } + lab8: + ; + } + { int m = z->l - z->c; (void) m; /* do, line 212 */ + { int ret = r_derivational(z); + if (ret == 0) goto lab9; /* call derivational, line 212 */ + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 213 */ + { int ret = r_tidy_up(z); + if (ret == 0) goto lab10; /* call tidy_up, line 213 */ + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m; + } + z->lb = m3; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * russian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void russian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.h new file mode 100644 index 00000000000..4ef774ddccb --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_russian.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * russian_UTF_8_create_env(void); +extern void russian_UTF_8_close_env(struct SN_env * z); + +extern int russian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.c new file mode 100644 index 00000000000..77771ba4203 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.c @@ -0,0 +1,1137 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int spanish_UTF_8_stem(struct SN_env * z); +static int r_residual_suffix(struct SN_env * z); +static int r_verb_suffix(struct SN_env * z); +static int r_y_verb_suffix(struct SN_env * z); +static int r_standard_suffix(struct SN_env * z); +static int r_attached_pronoun(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_postlude(struct SN_env * z); + +extern struct SN_env * spanish_UTF_8_create_env(void); +extern void spanish_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_1[2] = { 0xC3, 0xA1 }; +static symbol s_0_2[2] = { 0xC3, 0xA9 }; +static symbol s_0_3[2] = { 0xC3, 0xAD }; +static symbol s_0_4[2] = { 0xC3, 0xB3 }; +static symbol s_0_5[2] = { 0xC3, 0xBA }; + +static struct among a_0[6] = +{ +/* 0 */ { 0, 0, -1, 6, 0}, +/* 1 */ { 2, s_0_1, 0, 1, 0}, +/* 2 */ { 2, s_0_2, 0, 2, 0}, +/* 3 */ { 2, s_0_3, 0, 3, 0}, +/* 4 */ { 2, s_0_4, 0, 4, 0}, +/* 5 */ { 2, s_0_5, 0, 5, 0} +}; + +static symbol s_1_0[2] = { 'l', 'a' }; +static symbol s_1_1[4] = { 's', 'e', 'l', 'a' }; +static symbol s_1_2[2] = { 'l', 'e' }; +static symbol s_1_3[2] = { 'm', 'e' }; +static symbol s_1_4[2] = { 's', 'e' }; +static symbol s_1_5[2] = { 'l', 'o' }; +static symbol s_1_6[4] = { 's', 'e', 'l', 'o' }; +static symbol s_1_7[3] = { 'l', 'a', 's' }; +static symbol s_1_8[5] = { 's', 'e', 'l', 'a', 's' }; +static symbol s_1_9[3] = { 'l', 'e', 's' }; +static symbol s_1_10[3] = { 'l', 'o', 's' }; +static symbol s_1_11[5] = { 's', 'e', 'l', 'o', 's' }; +static symbol s_1_12[3] = { 'n', 'o', 's' }; + +static struct among a_1[13] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 4, s_1_1, 0, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 2, s_1_4, -1, -1, 0}, +/* 5 */ { 2, s_1_5, -1, -1, 0}, +/* 6 */ { 4, s_1_6, 5, -1, 0}, +/* 7 */ { 3, s_1_7, -1, -1, 0}, +/* 8 */ { 5, s_1_8, 7, -1, 0}, +/* 9 */ { 3, s_1_9, -1, -1, 0}, +/* 10 */ { 3, s_1_10, -1, -1, 0}, +/* 11 */ { 5, s_1_11, 10, -1, 0}, +/* 12 */ { 3, s_1_12, -1, -1, 0} +}; + +static symbol s_2_0[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_2_1[5] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_2_2[5] = { 'y', 'e', 'n', 'd', 'o' }; +static symbol s_2_3[5] = { 0xC3, 0xA1, 'n', 'd', 'o' }; +static symbol s_2_4[6] = { 'i', 0xC3, 0xA9, 'n', 'd', 'o' }; +static symbol s_2_5[2] = { 'a', 'r' }; +static symbol s_2_6[2] = { 'e', 'r' }; +static symbol s_2_7[2] = { 'i', 'r' }; +static symbol s_2_8[3] = { 0xC3, 0xA1, 'r' }; +static symbol s_2_9[3] = { 0xC3, 0xA9, 'r' }; +static symbol s_2_10[3] = { 0xC3, 0xAD, 'r' }; + +static struct among a_2[11] = +{ +/* 0 */ { 4, s_2_0, -1, 6, 0}, +/* 1 */ { 5, s_2_1, -1, 6, 0}, +/* 2 */ { 5, s_2_2, -1, 7, 0}, +/* 3 */ { 5, s_2_3, -1, 2, 0}, +/* 4 */ { 6, s_2_4, -1, 1, 0}, +/* 5 */ { 2, s_2_5, -1, 6, 0}, +/* 6 */ { 2, s_2_6, -1, 6, 0}, +/* 7 */ { 2, s_2_7, -1, 6, 0}, +/* 8 */ { 3, s_2_8, -1, 3, 0}, +/* 9 */ { 3, s_2_9, -1, 4, 0}, +/* 10 */ { 3, s_2_10, -1, 5, 0} +}; + +static symbol s_3_0[2] = { 'i', 'c' }; +static symbol s_3_1[2] = { 'a', 'd' }; +static symbol s_3_2[2] = { 'o', 's' }; +static symbol s_3_3[2] = { 'i', 'v' }; + +static struct among a_3[4] = +{ +/* 0 */ { 2, s_3_0, -1, -1, 0}, +/* 1 */ { 2, s_3_1, -1, -1, 0}, +/* 2 */ { 2, s_3_2, -1, -1, 0}, +/* 3 */ { 2, s_3_3, -1, 1, 0} +}; + +static symbol s_4_0[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_4_1[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_4_2[4] = { 'a', 'n', 't', 'e' }; + +static struct among a_4[3] = +{ +/* 0 */ { 4, s_4_0, -1, 1, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 4, s_4_2, -1, 1, 0} +}; + +static symbol s_5_0[2] = { 'i', 'c' }; +static symbol s_5_1[4] = { 'a', 'b', 'i', 'l' }; +static symbol s_5_2[2] = { 'i', 'v' }; + +static struct among a_5[3] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 4, s_5_1, -1, 1, 0}, +/* 2 */ { 2, s_5_2, -1, 1, 0} +}; + +static symbol s_6_0[3] = { 'i', 'c', 'a' }; +static symbol s_6_1[5] = { 'a', 'n', 'c', 'i', 'a' }; +static symbol s_6_2[5] = { 'e', 'n', 'c', 'i', 'a' }; +static symbol s_6_3[5] = { 'a', 'd', 'o', 'r', 'a' }; +static symbol s_6_4[3] = { 'o', 's', 'a' }; +static symbol s_6_5[4] = { 'i', 's', 't', 'a' }; +static symbol s_6_6[3] = { 'i', 'v', 'a' }; +static symbol s_6_7[4] = { 'a', 'n', 'z', 'a' }; +static symbol s_6_8[6] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a' }; +static symbol s_6_9[4] = { 'i', 'd', 'a', 'd' }; +static symbol s_6_10[4] = { 'a', 'b', 'l', 'e' }; +static symbol s_6_11[4] = { 'i', 'b', 'l', 'e' }; +static symbol s_6_12[4] = { 'a', 'n', 't', 'e' }; +static symbol s_6_13[5] = { 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_14[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; +static symbol s_6_15[6] = { 'a', 'c', 'i', 0xC3, 0xB3, 'n' }; +static symbol s_6_16[6] = { 'u', 'c', 'i', 0xC3, 0xB3, 'n' }; +static symbol s_6_17[3] = { 'i', 'c', 'o' }; +static symbol s_6_18[4] = { 'i', 's', 'm', 'o' }; +static symbol s_6_19[3] = { 'o', 's', 'o' }; +static symbol s_6_20[7] = { 'a', 'm', 'i', 'e', 'n', 't', 'o' }; +static symbol s_6_21[7] = { 'i', 'm', 'i', 'e', 'n', 't', 'o' }; +static symbol s_6_22[3] = { 'i', 'v', 'o' }; +static symbol s_6_23[4] = { 'a', 'd', 'o', 'r' }; +static symbol s_6_24[4] = { 'i', 'c', 'a', 's' }; +static symbol s_6_25[6] = { 'a', 'n', 'c', 'i', 'a', 's' }; +static symbol s_6_26[6] = { 'e', 'n', 'c', 'i', 'a', 's' }; +static symbol s_6_27[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static symbol s_6_28[4] = { 'o', 's', 'a', 's' }; +static symbol s_6_29[5] = { 'i', 's', 't', 'a', 's' }; +static symbol s_6_30[4] = { 'i', 'v', 'a', 's' }; +static symbol s_6_31[5] = { 'a', 'n', 'z', 'a', 's' }; +static symbol s_6_32[7] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a', 's' }; +static symbol s_6_33[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; +static symbol s_6_34[5] = { 'a', 'b', 'l', 'e', 's' }; +static symbol s_6_35[5] = { 'i', 'b', 'l', 'e', 's' }; +static symbol s_6_36[7] = { 'a', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_6_37[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; +static symbol s_6_38[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static symbol s_6_39[5] = { 'a', 'n', 't', 'e', 's' }; +static symbol s_6_40[4] = { 'i', 'c', 'o', 's' }; +static symbol s_6_41[5] = { 'i', 's', 'm', 'o', 's' }; +static symbol s_6_42[4] = { 'o', 's', 'o', 's' }; +static symbol s_6_43[8] = { 'a', 'm', 'i', 'e', 'n', 't', 'o', 's' }; +static symbol s_6_44[8] = { 'i', 'm', 'i', 'e', 'n', 't', 'o', 's' }; +static symbol s_6_45[4] = { 'i', 'v', 'o', 's' }; + +static struct among a_6[46] = +{ +/* 0 */ { 3, s_6_0, -1, 1, 0}, +/* 1 */ { 5, s_6_1, -1, 2, 0}, +/* 2 */ { 5, s_6_2, -1, 5, 0}, +/* 3 */ { 5, s_6_3, -1, 2, 0}, +/* 4 */ { 3, s_6_4, -1, 1, 0}, +/* 5 */ { 4, s_6_5, -1, 1, 0}, +/* 6 */ { 3, s_6_6, -1, 9, 0}, +/* 7 */ { 4, s_6_7, -1, 1, 0}, +/* 8 */ { 6, s_6_8, -1, 3, 0}, +/* 9 */ { 4, s_6_9, -1, 8, 0}, +/* 10 */ { 4, s_6_10, -1, 1, 0}, +/* 11 */ { 4, s_6_11, -1, 1, 0}, +/* 12 */ { 4, s_6_12, -1, 2, 0}, +/* 13 */ { 5, s_6_13, -1, 7, 0}, +/* 14 */ { 6, s_6_14, 13, 6, 0}, +/* 15 */ { 6, s_6_15, -1, 2, 0}, +/* 16 */ { 6, s_6_16, -1, 4, 0}, +/* 17 */ { 3, s_6_17, -1, 1, 0}, +/* 18 */ { 4, s_6_18, -1, 1, 0}, +/* 19 */ { 3, s_6_19, -1, 1, 0}, +/* 20 */ { 7, s_6_20, -1, 1, 0}, +/* 21 */ { 7, s_6_21, -1, 1, 0}, +/* 22 */ { 3, s_6_22, -1, 9, 0}, +/* 23 */ { 4, s_6_23, -1, 2, 0}, +/* 24 */ { 4, s_6_24, -1, 1, 0}, +/* 25 */ { 6, s_6_25, -1, 2, 0}, +/* 26 */ { 6, s_6_26, -1, 5, 0}, +/* 27 */ { 6, s_6_27, -1, 2, 0}, +/* 28 */ { 4, s_6_28, -1, 1, 0}, +/* 29 */ { 5, s_6_29, -1, 1, 0}, +/* 30 */ { 4, s_6_30, -1, 9, 0}, +/* 31 */ { 5, s_6_31, -1, 1, 0}, +/* 32 */ { 7, s_6_32, -1, 3, 0}, +/* 33 */ { 6, s_6_33, -1, 8, 0}, +/* 34 */ { 5, s_6_34, -1, 1, 0}, +/* 35 */ { 5, s_6_35, -1, 1, 0}, +/* 36 */ { 7, s_6_36, -1, 2, 0}, +/* 37 */ { 7, s_6_37, -1, 4, 0}, +/* 38 */ { 6, s_6_38, -1, 2, 0}, +/* 39 */ { 5, s_6_39, -1, 2, 0}, +/* 40 */ { 4, s_6_40, -1, 1, 0}, +/* 41 */ { 5, s_6_41, -1, 1, 0}, +/* 42 */ { 4, s_6_42, -1, 1, 0}, +/* 43 */ { 8, s_6_43, -1, 1, 0}, +/* 44 */ { 8, s_6_44, -1, 1, 0}, +/* 45 */ { 4, s_6_45, -1, 9, 0} +}; + +static symbol s_7_0[2] = { 'y', 'a' }; +static symbol s_7_1[2] = { 'y', 'e' }; +static symbol s_7_2[3] = { 'y', 'a', 'n' }; +static symbol s_7_3[3] = { 'y', 'e', 'n' }; +static symbol s_7_4[5] = { 'y', 'e', 'r', 'o', 'n' }; +static symbol s_7_5[5] = { 'y', 'e', 'n', 'd', 'o' }; +static symbol s_7_6[2] = { 'y', 'o' }; +static symbol s_7_7[3] = { 'y', 'a', 's' }; +static symbol s_7_8[3] = { 'y', 'e', 's' }; +static symbol s_7_9[4] = { 'y', 'a', 'i', 's' }; +static symbol s_7_10[5] = { 'y', 'a', 'm', 'o', 's' }; +static symbol s_7_11[3] = { 'y', 0xC3, 0xB3 }; + +static struct among a_7[12] = +{ +/* 0 */ { 2, s_7_0, -1, 1, 0}, +/* 1 */ { 2, s_7_1, -1, 1, 0}, +/* 2 */ { 3, s_7_2, -1, 1, 0}, +/* 3 */ { 3, s_7_3, -1, 1, 0}, +/* 4 */ { 5, s_7_4, -1, 1, 0}, +/* 5 */ { 5, s_7_5, -1, 1, 0}, +/* 6 */ { 2, s_7_6, -1, 1, 0}, +/* 7 */ { 3, s_7_7, -1, 1, 0}, +/* 8 */ { 3, s_7_8, -1, 1, 0}, +/* 9 */ { 4, s_7_9, -1, 1, 0}, +/* 10 */ { 5, s_7_10, -1, 1, 0}, +/* 11 */ { 3, s_7_11, -1, 1, 0} +}; + +static symbol s_8_0[3] = { 'a', 'b', 'a' }; +static symbol s_8_1[3] = { 'a', 'd', 'a' }; +static symbol s_8_2[3] = { 'i', 'd', 'a' }; +static symbol s_8_3[3] = { 'a', 'r', 'a' }; +static symbol s_8_4[4] = { 'i', 'e', 'r', 'a' }; +static symbol s_8_5[3] = { 0xC3, 0xAD, 'a' }; +static symbol s_8_6[5] = { 'a', 'r', 0xC3, 0xAD, 'a' }; +static symbol s_8_7[5] = { 'e', 'r', 0xC3, 0xAD, 'a' }; +static symbol s_8_8[5] = { 'i', 'r', 0xC3, 0xAD, 'a' }; +static symbol s_8_9[2] = { 'a', 'd' }; +static symbol s_8_10[2] = { 'e', 'd' }; +static symbol s_8_11[2] = { 'i', 'd' }; +static symbol s_8_12[3] = { 'a', 's', 'e' }; +static symbol s_8_13[4] = { 'i', 'e', 's', 'e' }; +static symbol s_8_14[4] = { 'a', 's', 't', 'e' }; +static symbol s_8_15[4] = { 'i', 's', 't', 'e' }; +static symbol s_8_16[2] = { 'a', 'n' }; +static symbol s_8_17[4] = { 'a', 'b', 'a', 'n' }; +static symbol s_8_18[4] = { 'a', 'r', 'a', 'n' }; +static symbol s_8_19[5] = { 'i', 'e', 'r', 'a', 'n' }; +static symbol s_8_20[4] = { 0xC3, 0xAD, 'a', 'n' }; +static symbol s_8_21[6] = { 'a', 'r', 0xC3, 0xAD, 'a', 'n' }; +static symbol s_8_22[6] = { 'e', 'r', 0xC3, 0xAD, 'a', 'n' }; +static symbol s_8_23[6] = { 'i', 'r', 0xC3, 0xAD, 'a', 'n' }; +static symbol s_8_24[2] = { 'e', 'n' }; +static symbol s_8_25[4] = { 'a', 's', 'e', 'n' }; +static symbol s_8_26[5] = { 'i', 'e', 's', 'e', 'n' }; +static symbol s_8_27[4] = { 'a', 'r', 'o', 'n' }; +static symbol s_8_28[5] = { 'i', 'e', 'r', 'o', 'n' }; +static symbol s_8_29[5] = { 'a', 'r', 0xC3, 0xA1, 'n' }; +static symbol s_8_30[5] = { 'e', 'r', 0xC3, 0xA1, 'n' }; +static symbol s_8_31[5] = { 'i', 'r', 0xC3, 0xA1, 'n' }; +static symbol s_8_32[3] = { 'a', 'd', 'o' }; +static symbol s_8_33[3] = { 'i', 'd', 'o' }; +static symbol s_8_34[4] = { 'a', 'n', 'd', 'o' }; +static symbol s_8_35[5] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_8_36[2] = { 'a', 'r' }; +static symbol s_8_37[2] = { 'e', 'r' }; +static symbol s_8_38[2] = { 'i', 'r' }; +static symbol s_8_39[2] = { 'a', 's' }; +static symbol s_8_40[4] = { 'a', 'b', 'a', 's' }; +static symbol s_8_41[4] = { 'a', 'd', 'a', 's' }; +static symbol s_8_42[4] = { 'i', 'd', 'a', 's' }; +static symbol s_8_43[4] = { 'a', 'r', 'a', 's' }; +static symbol s_8_44[5] = { 'i', 'e', 'r', 'a', 's' }; +static symbol s_8_45[4] = { 0xC3, 0xAD, 'a', 's' }; +static symbol s_8_46[6] = { 'a', 'r', 0xC3, 0xAD, 'a', 's' }; +static symbol s_8_47[6] = { 'e', 'r', 0xC3, 0xAD, 'a', 's' }; +static symbol s_8_48[6] = { 'i', 'r', 0xC3, 0xAD, 'a', 's' }; +static symbol s_8_49[2] = { 'e', 's' }; +static symbol s_8_50[4] = { 'a', 's', 'e', 's' }; +static symbol s_8_51[5] = { 'i', 'e', 's', 'e', 's' }; +static symbol s_8_52[5] = { 'a', 'b', 'a', 'i', 's' }; +static symbol s_8_53[5] = { 'a', 'r', 'a', 'i', 's' }; +static symbol s_8_54[6] = { 'i', 'e', 'r', 'a', 'i', 's' }; +static symbol s_8_55[5] = { 0xC3, 0xAD, 'a', 'i', 's' }; +static symbol s_8_56[7] = { 'a', 'r', 0xC3, 0xAD, 'a', 'i', 's' }; +static symbol s_8_57[7] = { 'e', 'r', 0xC3, 0xAD, 'a', 'i', 's' }; +static symbol s_8_58[7] = { 'i', 'r', 0xC3, 0xAD, 'a', 'i', 's' }; +static symbol s_8_59[5] = { 'a', 's', 'e', 'i', 's' }; +static symbol s_8_60[6] = { 'i', 'e', 's', 'e', 'i', 's' }; +static symbol s_8_61[6] = { 'a', 's', 't', 'e', 'i', 's' }; +static symbol s_8_62[6] = { 'i', 's', 't', 'e', 'i', 's' }; +static symbol s_8_63[4] = { 0xC3, 0xA1, 'i', 's' }; +static symbol s_8_64[4] = { 0xC3, 0xA9, 'i', 's' }; +static symbol s_8_65[6] = { 'a', 'r', 0xC3, 0xA9, 'i', 's' }; +static symbol s_8_66[6] = { 'e', 'r', 0xC3, 0xA9, 'i', 's' }; +static symbol s_8_67[6] = { 'i', 'r', 0xC3, 0xA9, 'i', 's' }; +static symbol s_8_68[4] = { 'a', 'd', 'o', 's' }; +static symbol s_8_69[4] = { 'i', 'd', 'o', 's' }; +static symbol s_8_70[4] = { 'a', 'm', 'o', 's' }; +static symbol s_8_71[7] = { 0xC3, 0xA1, 'b', 'a', 'm', 'o', 's' }; +static symbol s_8_72[7] = { 0xC3, 0xA1, 'r', 'a', 'm', 'o', 's' }; +static symbol s_8_73[8] = { 'i', 0xC3, 0xA9, 'r', 'a', 'm', 'o', 's' }; +static symbol s_8_74[6] = { 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_8_75[8] = { 'a', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_8_76[8] = { 'e', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_8_77[8] = { 'i', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' }; +static symbol s_8_78[4] = { 'e', 'm', 'o', 's' }; +static symbol s_8_79[6] = { 'a', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_80[6] = { 'e', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_81[6] = { 'i', 'r', 'e', 'm', 'o', 's' }; +static symbol s_8_82[7] = { 0xC3, 0xA1, 's', 'e', 'm', 'o', 's' }; +static symbol s_8_83[8] = { 'i', 0xC3, 0xA9, 's', 'e', 'm', 'o', 's' }; +static symbol s_8_84[4] = { 'i', 'm', 'o', 's' }; +static symbol s_8_85[5] = { 'a', 'r', 0xC3, 0xA1, 's' }; +static symbol s_8_86[5] = { 'e', 'r', 0xC3, 0xA1, 's' }; +static symbol s_8_87[5] = { 'i', 'r', 0xC3, 0xA1, 's' }; +static symbol s_8_88[3] = { 0xC3, 0xAD, 's' }; +static symbol s_8_89[4] = { 'a', 'r', 0xC3, 0xA1 }; +static symbol s_8_90[4] = { 'e', 'r', 0xC3, 0xA1 }; +static symbol s_8_91[4] = { 'i', 'r', 0xC3, 0xA1 }; +static symbol s_8_92[4] = { 'a', 'r', 0xC3, 0xA9 }; +static symbol s_8_93[4] = { 'e', 'r', 0xC3, 0xA9 }; +static symbol s_8_94[4] = { 'i', 'r', 0xC3, 0xA9 }; +static symbol s_8_95[3] = { 'i', 0xC3, 0xB3 }; + +static struct among a_8[96] = +{ +/* 0 */ { 3, s_8_0, -1, 2, 0}, +/* 1 */ { 3, s_8_1, -1, 2, 0}, +/* 2 */ { 3, s_8_2, -1, 2, 0}, +/* 3 */ { 3, s_8_3, -1, 2, 0}, +/* 4 */ { 4, s_8_4, -1, 2, 0}, +/* 5 */ { 3, s_8_5, -1, 2, 0}, +/* 6 */ { 5, s_8_6, 5, 2, 0}, +/* 7 */ { 5, s_8_7, 5, 2, 0}, +/* 8 */ { 5, s_8_8, 5, 2, 0}, +/* 9 */ { 2, s_8_9, -1, 2, 0}, +/* 10 */ { 2, s_8_10, -1, 2, 0}, +/* 11 */ { 2, s_8_11, -1, 2, 0}, +/* 12 */ { 3, s_8_12, -1, 2, 0}, +/* 13 */ { 4, s_8_13, -1, 2, 0}, +/* 14 */ { 4, s_8_14, -1, 2, 0}, +/* 15 */ { 4, s_8_15, -1, 2, 0}, +/* 16 */ { 2, s_8_16, -1, 2, 0}, +/* 17 */ { 4, s_8_17, 16, 2, 0}, +/* 18 */ { 4, s_8_18, 16, 2, 0}, +/* 19 */ { 5, s_8_19, 16, 2, 0}, +/* 20 */ { 4, s_8_20, 16, 2, 0}, +/* 21 */ { 6, s_8_21, 20, 2, 0}, +/* 22 */ { 6, s_8_22, 20, 2, 0}, +/* 23 */ { 6, s_8_23, 20, 2, 0}, +/* 24 */ { 2, s_8_24, -1, 1, 0}, +/* 25 */ { 4, s_8_25, 24, 2, 0}, +/* 26 */ { 5, s_8_26, 24, 2, 0}, +/* 27 */ { 4, s_8_27, -1, 2, 0}, +/* 28 */ { 5, s_8_28, -1, 2, 0}, +/* 29 */ { 5, s_8_29, -1, 2, 0}, +/* 30 */ { 5, s_8_30, -1, 2, 0}, +/* 31 */ { 5, s_8_31, -1, 2, 0}, +/* 32 */ { 3, s_8_32, -1, 2, 0}, +/* 33 */ { 3, s_8_33, -1, 2, 0}, +/* 34 */ { 4, s_8_34, -1, 2, 0}, +/* 35 */ { 5, s_8_35, -1, 2, 0}, +/* 36 */ { 2, s_8_36, -1, 2, 0}, +/* 37 */ { 2, s_8_37, -1, 2, 0}, +/* 38 */ { 2, s_8_38, -1, 2, 0}, +/* 39 */ { 2, s_8_39, -1, 2, 0}, +/* 40 */ { 4, s_8_40, 39, 2, 0}, +/* 41 */ { 4, s_8_41, 39, 2, 0}, +/* 42 */ { 4, s_8_42, 39, 2, 0}, +/* 43 */ { 4, s_8_43, 39, 2, 0}, +/* 44 */ { 5, s_8_44, 39, 2, 0}, +/* 45 */ { 4, s_8_45, 39, 2, 0}, +/* 46 */ { 6, s_8_46, 45, 2, 0}, +/* 47 */ { 6, s_8_47, 45, 2, 0}, +/* 48 */ { 6, s_8_48, 45, 2, 0}, +/* 49 */ { 2, s_8_49, -1, 1, 0}, +/* 50 */ { 4, s_8_50, 49, 2, 0}, +/* 51 */ { 5, s_8_51, 49, 2, 0}, +/* 52 */ { 5, s_8_52, -1, 2, 0}, +/* 53 */ { 5, s_8_53, -1, 2, 0}, +/* 54 */ { 6, s_8_54, -1, 2, 0}, +/* 55 */ { 5, s_8_55, -1, 2, 0}, +/* 56 */ { 7, s_8_56, 55, 2, 0}, +/* 57 */ { 7, s_8_57, 55, 2, 0}, +/* 58 */ { 7, s_8_58, 55, 2, 0}, +/* 59 */ { 5, s_8_59, -1, 2, 0}, +/* 60 */ { 6, s_8_60, -1, 2, 0}, +/* 61 */ { 6, s_8_61, -1, 2, 0}, +/* 62 */ { 6, s_8_62, -1, 2, 0}, +/* 63 */ { 4, s_8_63, -1, 2, 0}, +/* 64 */ { 4, s_8_64, -1, 1, 0}, +/* 65 */ { 6, s_8_65, 64, 2, 0}, +/* 66 */ { 6, s_8_66, 64, 2, 0}, +/* 67 */ { 6, s_8_67, 64, 2, 0}, +/* 68 */ { 4, s_8_68, -1, 2, 0}, +/* 69 */ { 4, s_8_69, -1, 2, 0}, +/* 70 */ { 4, s_8_70, -1, 2, 0}, +/* 71 */ { 7, s_8_71, 70, 2, 0}, +/* 72 */ { 7, s_8_72, 70, 2, 0}, +/* 73 */ { 8, s_8_73, 70, 2, 0}, +/* 74 */ { 6, s_8_74, 70, 2, 0}, +/* 75 */ { 8, s_8_75, 74, 2, 0}, +/* 76 */ { 8, s_8_76, 74, 2, 0}, +/* 77 */ { 8, s_8_77, 74, 2, 0}, +/* 78 */ { 4, s_8_78, -1, 1, 0}, +/* 79 */ { 6, s_8_79, 78, 2, 0}, +/* 80 */ { 6, s_8_80, 78, 2, 0}, +/* 81 */ { 6, s_8_81, 78, 2, 0}, +/* 82 */ { 7, s_8_82, 78, 2, 0}, +/* 83 */ { 8, s_8_83, 78, 2, 0}, +/* 84 */ { 4, s_8_84, -1, 2, 0}, +/* 85 */ { 5, s_8_85, -1, 2, 0}, +/* 86 */ { 5, s_8_86, -1, 2, 0}, +/* 87 */ { 5, s_8_87, -1, 2, 0}, +/* 88 */ { 3, s_8_88, -1, 2, 0}, +/* 89 */ { 4, s_8_89, -1, 2, 0}, +/* 90 */ { 4, s_8_90, -1, 2, 0}, +/* 91 */ { 4, s_8_91, -1, 2, 0}, +/* 92 */ { 4, s_8_92, -1, 2, 0}, +/* 93 */ { 4, s_8_93, -1, 2, 0}, +/* 94 */ { 4, s_8_94, -1, 2, 0}, +/* 95 */ { 3, s_8_95, -1, 2, 0} +}; + +static symbol s_9_0[1] = { 'a' }; +static symbol s_9_1[1] = { 'e' }; +static symbol s_9_2[1] = { 'o' }; +static symbol s_9_3[2] = { 'o', 's' }; +static symbol s_9_4[2] = { 0xC3, 0xA1 }; +static symbol s_9_5[2] = { 0xC3, 0xA9 }; +static symbol s_9_6[2] = { 0xC3, 0xAD }; +static symbol s_9_7[2] = { 0xC3, 0xB3 }; + +static struct among a_9[8] = +{ +/* 0 */ { 1, s_9_0, -1, 1, 0}, +/* 1 */ { 1, s_9_1, -1, 2, 0}, +/* 2 */ { 1, s_9_2, -1, 1, 0}, +/* 3 */ { 2, s_9_3, -1, 1, 0}, +/* 4 */ { 2, s_9_4, -1, 1, 0}, +/* 5 */ { 2, s_9_5, -1, 2, 0}, +/* 6 */ { 2, s_9_6, -1, 1, 0}, +/* 7 */ { 2, s_9_7, -1, 1, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 }; + +static symbol s_0[] = { 'a' }; +static symbol s_1[] = { 'e' }; +static symbol s_2[] = { 'i' }; +static symbol s_3[] = { 'o' }; +static symbol s_4[] = { 'u' }; +static symbol s_5[] = { 'i', 'e', 'n', 'd', 'o' }; +static symbol s_6[] = { 'a', 'n', 'd', 'o' }; +static symbol s_7[] = { 'a', 'r' }; +static symbol s_8[] = { 'e', 'r' }; +static symbol s_9[] = { 'i', 'r' }; +static symbol s_10[] = { 'u' }; +static symbol s_11[] = { 'i', 'c' }; +static symbol s_12[] = { 'l', 'o', 'g' }; +static symbol s_13[] = { 'u' }; +static symbol s_14[] = { 'e', 'n', 't', 'e' }; +static symbol s_15[] = { 'a', 't' }; +static symbol s_16[] = { 'a', 't' }; +static symbol s_17[] = { 'u' }; +static symbol s_18[] = { 'u' }; +static symbol s_19[] = { 'g' }; +static symbol s_20[] = { 'u' }; +static symbol s_21[] = { 'g' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + z->I[1] = z->l; + z->I[2] = z->l; + { int c = z->c; /* do, line 37 */ + { int c = z->c; /* or, line 39 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab2; + { int c = z->c; /* or, line 38 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab4; + while(1) { /* gopast, line 38 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab5; + break; + lab5: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab4; + z->c = c; /* gopast, line 38 */ + } + } + goto lab3; + lab4: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab2; + while(1) { /* gopast, line 38 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab6; + break; + lab6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab2; + z->c = c; /* gopast, line 38 */ + } + } + } + lab3: + goto lab1; + lab2: + z->c = c; + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab0; + { int c = z->c; /* or, line 40 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab8; + while(1) { /* gopast, line 40 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab9; + break; + lab9: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab8; + z->c = c; /* gopast, line 40 */ + } + } + goto lab7; + lab8: + z->c = c; + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab0; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 40 */ + } + } + lab7: + ; + } + lab1: + z->I[0] = z->c; /* setmark pV, line 41 */ + lab0: + z->c = c; + } + { int c = z->c; /* do, line 43 */ + while(1) { /* gopast, line 44 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab11; + break; + lab11: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 44 */ + } + } + while(1) { /* gopast, line 44 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab12; + break; + lab12: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 44 */ + } + } + z->I[1] = z->c; /* setmark p1, line 44 */ + while(1) { /* gopast, line 45 */ + if (!(in_grouping_U(z, g_v, 97, 252))) goto lab13; + break; + lab13: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 45 */ + } + } + while(1) { /* gopast, line 45 */ + if (!(out_grouping_U(z, g_v, 97, 252))) goto lab14; + break; + lab14: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab10; + z->c = c; /* gopast, line 45 */ + } + } + z->I[2] = z->c; /* setmark p2, line 45 */ + lab10: + z->c = c; + } + return 1; +} + +static int r_postlude(struct SN_env * z) { + int among_var; + while(1) { /* repeat, line 49 */ + int c = z->c; + z->bra = z->c; /* [, line 50 */ + among_var = find_among(z, a_0, 6); /* substring, line 50 */ + if (!(among_var)) goto lab0; + z->ket = z->c; /* ], line 50 */ + switch(among_var) { + case 0: goto lab0; + case 1: + { int ret; + ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 1, s_1); /* <-, line 52 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret; + ret = slice_from_s(z, 1, s_3); /* <-, line 54 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret; + ret = slice_from_s(z, 1, s_4); /* <-, line 55 */ + if (ret < 0) return ret; + } + break; + case 6: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) goto lab0; + z->c = c; /* next, line 57 */ + } + break; + } + continue; + lab0: + z->c = c; + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; + return 1; +} + +static int r_attached_pronoun(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 68 */ + if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */ + z->bra = z->c; /* ], line 68 */ + among_var = find_among_b(z, a_2, 11); /* substring, line 72 */ + if (!(among_var)) return 0; + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 72 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: return 0; + case 1: + z->bra = z->c; /* ], line 73 */ + { int ret; + ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ + if (ret < 0) return ret; + } + break; + case 2: + z->bra = z->c; /* ], line 74 */ + { int ret; + ret = slice_from_s(z, 4, s_6); /* <-, line 74 */ + if (ret < 0) return ret; + } + break; + case 3: + z->bra = z->c; /* ], line 75 */ + { int ret; + ret = slice_from_s(z, 2, s_7); /* <-, line 75 */ + if (ret < 0) return ret; + } + break; + case 4: + z->bra = z->c; /* ], line 76 */ + { int ret; + ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + if (ret < 0) return ret; + } + break; + case 5: + z->bra = z->c; /* ], line 77 */ + { int ret; + ret = slice_from_s(z, 2, s_9); /* <-, line 77 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret; + ret = slice_del(z); /* delete, line 81 */ + if (ret < 0) return ret; + } + break; + case 7: + if (!(eq_s_b(z, 1, s_10))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 82 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 87 */ + among_var = find_among_b(z, a_6, 46); /* substring, line 87 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 87 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 99 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 99 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 105 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 105 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 106 */ + z->ket = z->c; /* [, line 106 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 106 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call R2, line 106 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 106 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + case 3: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 111 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 3, s_12); /* <-, line 111 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 115 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 1, s_13); /* <-, line 115 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 119 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_from_s(z, 4, s_14); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = r_R1(z); + if (ret == 0) return 0; /* call R1, line 123 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 124 */ + z->ket = z->c; /* [, line 125 */ + among_var = find_among_b(z, a_3, 4); /* substring, line 125 */ + if (!(among_var)) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 125 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 125 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + switch(among_var) { + case 0: { z->c = z->l - m; goto lab1; } + case 1: + z->ket = z->c; /* [, line 126 */ + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m; goto lab1; } + z->bra = z->c; /* ], line 126 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab1; } /* call R2, line 126 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 126 */ + if (ret < 0) return ret; + } + break; + } + lab1: + ; + } + break; + case 7: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 135 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 135 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 136 */ + z->ket = z->c; /* [, line 137 */ + among_var = find_among_b(z, a_4, 3); /* substring, line 137 */ + if (!(among_var)) { z->c = z->l - m; goto lab2; } + z->bra = z->c; /* ], line 137 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab2; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab2; } /* call R2, line 140 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 140 */ + if (ret < 0) return ret; + } + break; + } + lab2: + ; + } + break; + case 8: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 147 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 147 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 148 */ + z->ket = z->c; /* [, line 149 */ + among_var = find_among_b(z, a_5, 3); /* substring, line 149 */ + if (!(among_var)) { z->c = z->l - m; goto lab3; } + z->bra = z->c; /* ], line 149 */ + switch(among_var) { + case 0: { z->c = z->l - m; goto lab3; } + case 1: + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab3; } /* call R2, line 152 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + break; + } + lab3: + ; + } + break; + case 9: + { int ret = r_R2(z); + if (ret == 0) return 0; /* call R2, line 159 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 159 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 160 */ + z->ket = z->c; /* [, line 161 */ + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m; goto lab4; } + z->bra = z->c; /* ], line 161 */ + { int ret = r_R2(z); + if (ret == 0) { z->c = z->l - m; goto lab4; } /* call R2, line 161 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 161 */ + if (ret < 0) return ret; + } + lab4: + ; + } + break; + } + return 1; +} + +static int r_y_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 168 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 168 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 168 */ + among_var = find_among_b(z, a_7, 12); /* substring, line 168 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 168 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + if (!(eq_s_b(z, 1, s_17))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 171 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 176 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 176 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 176 */ + among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 176 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int m = z->l - z->c; (void) m; /* try, line 179 */ + if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m; goto lab0; } + { int m_test = z->l - z->c; /* test, line 179 */ + if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + lab0: + ; + } + z->bra = z->c; /* ], line 179 */ + { int ret; + ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_del(z); /* delete, line 200 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_residual_suffix(struct SN_env * z) { + int among_var; + z->ket = z->c; /* [, line 205 */ + among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 205 */ + switch(among_var) { + case 0: return 0; + case 1: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 208 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 208 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_RV(z); + if (ret == 0) return 0; /* call RV, line 210 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 210 */ + if (ret < 0) return ret; + } + { int m = z->l - z->c; (void) m; /* try, line 210 */ + z->ket = z->c; /* [, line 210 */ + if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m; goto lab0; } + z->bra = z->c; /* ], line 210 */ + { int m_test = z->l - z->c; /* test, line 210 */ + if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m; goto lab0; } + z->c = z->l - m_test; + } + { int ret = r_RV(z); + if (ret == 0) { z->c = z->l - m; goto lab0; } /* call RV, line 210 */ + if (ret < 0) return ret; + } + { int ret; + ret = slice_del(z); /* delete, line 210 */ + if (ret < 0) return ret; + } + lab0: + ; + } + break; + } + return 1; +} + +extern int spanish_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 216 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 216 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 217 */ + + { int m = z->l - z->c; (void) m; /* do, line 218 */ + { int ret = r_attached_pronoun(z); + if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 219 */ + { int m = z->l - z->c; (void) m; /* or, line 219 */ + { int ret = r_standard_suffix(z); + if (ret == 0) goto lab4; /* call standard_suffix, line 219 */ + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = z->l - m; + { int ret = r_y_verb_suffix(z); + if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */ + if (ret < 0) return ret; + } + goto lab3; + lab5: + z->c = z->l - m; + { int ret = r_verb_suffix(z); + if (ret == 0) goto lab2; /* call verb_suffix, line 221 */ + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 223 */ + { int ret = r_residual_suffix(z); + if (ret == 0) goto lab6; /* call residual_suffix, line 223 */ + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m; + } + z->c = z->lb; + { int c = z->c; /* do, line 225 */ + { int ret = r_postlude(z); + if (ret == 0) goto lab7; /* call postlude, line 225 */ + if (ret < 0) return ret; + } + lab7: + z->c = c; + } + return 1; +} + +extern struct SN_env * spanish_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void spanish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.h new file mode 100644 index 00000000000..10572ecc370 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_spanish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * spanish_UTF_8_create_env(void); +extern void spanish_UTF_8_close_env(struct SN_env * z); + +extern int spanish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.c b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.c new file mode 100644 index 00000000000..af7555100aa --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.c @@ -0,0 +1,313 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#include "../runtime/header.h" + +extern int swedish_UTF_8_stem(struct SN_env * z); +static int r_other_suffix(struct SN_env * z); +static int r_consonant_pair(struct SN_env * z); +static int r_main_suffix(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); + +extern struct SN_env * swedish_UTF_8_create_env(void); +extern void swedish_UTF_8_close_env(struct SN_env * z); + +static symbol s_0_0[1] = { 'a' }; +static symbol s_0_1[4] = { 'a', 'r', 'n', 'a' }; +static symbol s_0_2[4] = { 'e', 'r', 'n', 'a' }; +static symbol s_0_3[7] = { 'h', 'e', 't', 'e', 'r', 'n', 'a' }; +static symbol s_0_4[4] = { 'o', 'r', 'n', 'a' }; +static symbol s_0_5[2] = { 'a', 'd' }; +static symbol s_0_6[1] = { 'e' }; +static symbol s_0_7[3] = { 'a', 'd', 'e' }; +static symbol s_0_8[4] = { 'a', 'n', 'd', 'e' }; +static symbol s_0_9[4] = { 'a', 'r', 'n', 'e' }; +static symbol s_0_10[3] = { 'a', 'r', 'e' }; +static symbol s_0_11[4] = { 'a', 's', 't', 'e' }; +static symbol s_0_12[2] = { 'e', 'n' }; +static symbol s_0_13[5] = { 'a', 'n', 'd', 'e', 'n' }; +static symbol s_0_14[4] = { 'a', 'r', 'e', 'n' }; +static symbol s_0_15[5] = { 'h', 'e', 't', 'e', 'n' }; +static symbol s_0_16[3] = { 'e', 'r', 'n' }; +static symbol s_0_17[2] = { 'a', 'r' }; +static symbol s_0_18[2] = { 'e', 'r' }; +static symbol s_0_19[5] = { 'h', 'e', 't', 'e', 'r' }; +static symbol s_0_20[2] = { 'o', 'r' }; +static symbol s_0_21[1] = { 's' }; +static symbol s_0_22[2] = { 'a', 's' }; +static symbol s_0_23[5] = { 'a', 'r', 'n', 'a', 's' }; +static symbol s_0_24[5] = { 'e', 'r', 'n', 'a', 's' }; +static symbol s_0_25[5] = { 'o', 'r', 'n', 'a', 's' }; +static symbol s_0_26[2] = { 'e', 's' }; +static symbol s_0_27[4] = { 'a', 'd', 'e', 's' }; +static symbol s_0_28[5] = { 'a', 'n', 'd', 'e', 's' }; +static symbol s_0_29[3] = { 'e', 'n', 's' }; +static symbol s_0_30[5] = { 'a', 'r', 'e', 'n', 's' }; +static symbol s_0_31[6] = { 'h', 'e', 't', 'e', 'n', 's' }; +static symbol s_0_32[4] = { 'e', 'r', 'n', 's' }; +static symbol s_0_33[2] = { 'a', 't' }; +static symbol s_0_34[5] = { 'a', 'n', 'd', 'e', 't' }; +static symbol s_0_35[3] = { 'h', 'e', 't' }; +static symbol s_0_36[3] = { 'a', 's', 't' }; + +static struct among a_0[37] = +{ +/* 0 */ { 1, s_0_0, -1, 1, 0}, +/* 1 */ { 4, s_0_1, 0, 1, 0}, +/* 2 */ { 4, s_0_2, 0, 1, 0}, +/* 3 */ { 7, s_0_3, 2, 1, 0}, +/* 4 */ { 4, s_0_4, 0, 1, 0}, +/* 5 */ { 2, s_0_5, -1, 1, 0}, +/* 6 */ { 1, s_0_6, -1, 1, 0}, +/* 7 */ { 3, s_0_7, 6, 1, 0}, +/* 8 */ { 4, s_0_8, 6, 1, 0}, +/* 9 */ { 4, s_0_9, 6, 1, 0}, +/* 10 */ { 3, s_0_10, 6, 1, 0}, +/* 11 */ { 4, s_0_11, 6, 1, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 5, s_0_13, 12, 1, 0}, +/* 14 */ { 4, s_0_14, 12, 1, 0}, +/* 15 */ { 5, s_0_15, 12, 1, 0}, +/* 16 */ { 3, s_0_16, -1, 1, 0}, +/* 17 */ { 2, s_0_17, -1, 1, 0}, +/* 18 */ { 2, s_0_18, -1, 1, 0}, +/* 19 */ { 5, s_0_19, 18, 1, 0}, +/* 20 */ { 2, s_0_20, -1, 1, 0}, +/* 21 */ { 1, s_0_21, -1, 2, 0}, +/* 22 */ { 2, s_0_22, 21, 1, 0}, +/* 23 */ { 5, s_0_23, 22, 1, 0}, +/* 24 */ { 5, s_0_24, 22, 1, 0}, +/* 25 */ { 5, s_0_25, 22, 1, 0}, +/* 26 */ { 2, s_0_26, 21, 1, 0}, +/* 27 */ { 4, s_0_27, 26, 1, 0}, +/* 28 */ { 5, s_0_28, 26, 1, 0}, +/* 29 */ { 3, s_0_29, 21, 1, 0}, +/* 30 */ { 5, s_0_30, 29, 1, 0}, +/* 31 */ { 6, s_0_31, 29, 1, 0}, +/* 32 */ { 4, s_0_32, 21, 1, 0}, +/* 33 */ { 2, s_0_33, -1, 1, 0}, +/* 34 */ { 5, s_0_34, -1, 1, 0}, +/* 35 */ { 3, s_0_35, -1, 1, 0}, +/* 36 */ { 3, s_0_36, -1, 1, 0} +}; + +static symbol s_1_0[2] = { 'd', 'd' }; +static symbol s_1_1[2] = { 'g', 'd' }; +static symbol s_1_2[2] = { 'n', 'n' }; +static symbol s_1_3[2] = { 'd', 't' }; +static symbol s_1_4[2] = { 'g', 't' }; +static symbol s_1_5[2] = { 'k', 't' }; +static symbol s_1_6[2] = { 't', 't' }; + +static struct among a_1[7] = +{ +/* 0 */ { 2, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 2, s_1_2, -1, -1, 0}, +/* 3 */ { 2, s_1_3, -1, -1, 0}, +/* 4 */ { 2, s_1_4, -1, -1, 0}, +/* 5 */ { 2, s_1_5, -1, -1, 0}, +/* 6 */ { 2, s_1_6, -1, -1, 0} +}; + +static symbol s_2_0[2] = { 'i', 'g' }; +static symbol s_2_1[3] = { 'l', 'i', 'g' }; +static symbol s_2_2[3] = { 'e', 'l', 's' }; +static symbol s_2_3[5] = { 'f', 'u', 'l', 'l', 't' }; +static symbol s_2_4[5] = { 'l', 0xC3, 0xB6, 's', 't' }; + +static struct among a_2[5] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 3, s_2_1, 0, 1, 0}, +/* 2 */ { 3, s_2_2, -1, 1, 0}, +/* 3 */ { 5, s_2_3, -1, 3, 0}, +/* 4 */ { 5, s_2_4, -1, 2, 0} +}; + +static unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 }; + +static unsigned char g_s_ending[] = { 119, 127, 149 }; + +static symbol s_0[] = { 'l', 0xC3, 0xB6, 's' }; +static symbol s_1[] = { 'f', 'u', 'l', 'l' }; + +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c_test = z->c; /* test, line 29 */ + { int c = skip_utf8(z->p, z->c, 0, z->l, + 3); + if (c < 0) return 0; + z->c = c; /* hop, line 29 */ + } + z->I[1] = z->c; /* setmark x, line 29 */ + z->c = c_test; + } + while(1) { /* goto, line 30 */ + int c = z->c; + if (!(in_grouping_U(z, g_v, 97, 246))) goto lab0; + z->c = c; + break; + lab0: + z->c = c; + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* goto, line 30 */ + } + } + while(1) { /* gopast, line 30 */ + if (!(out_grouping_U(z, g_v, 97, 246))) goto lab1; + break; + lab1: + { int c = skip_utf8(z->p, z->c, 0, z->l, 1); + if (c < 0) return 0; + z->c = c; /* gopast, line 30 */ + } + } + z->I[0] = z->c; /* setmark p1, line 30 */ + /* try, line 31 */ + if (!(z->I[0] < z->I[1])) goto lab2; + z->I[0] = z->I[1]; +lab2: + return 1; +} + +static int r_main_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 37 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 37 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 37 */ + among_var = find_among_b(z, a_0, 37); /* substring, line 37 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 37 */ + z->lb = m3; + } + switch(among_var) { + case 0: return 0; + case 1: + { int ret; + ret = slice_del(z); /* delete, line 44 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(in_grouping_b_U(z, g_s_ending, 98, 121))) return 0; + { int ret; + ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_consonant_pair(struct SN_env * z) { + { int m3; /* setlimit, line 50 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 50 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + { int m = z->l - z->c; (void) m; /* and, line 52 */ + if (!(find_among_b(z, a_1, 7))) { z->lb = m3; return 0; } /* among, line 51 */ + z->c = z->l - m; + z->ket = z->c; /* [, line 52 */ + { int c = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (c < 0) { z->lb = m3; return 0; } + z->c = c; /* next, line 52 */ + } + z->bra = z->c; /* ], line 52 */ + { int ret; + ret = slice_del(z); /* delete, line 52 */ + if (ret < 0) return ret; + } + } + z->lb = m3; + } + return 1; +} + +static int r_other_suffix(struct SN_env * z) { + int among_var; + { int m3; /* setlimit, line 55 */ + int m = z->l - z->c; (void) m; + if (z->c < z->I[0]) return 0; + z->c = z->I[0]; /* tomark, line 55 */ + m3 = z->lb; z->lb = z->c; + z->c = z->l - m; + z->ket = z->c; /* [, line 56 */ + among_var = find_among_b(z, a_2, 5); /* substring, line 56 */ + if (!(among_var)) { z->lb = m3; return 0; } + z->bra = z->c; /* ], line 56 */ + switch(among_var) { + case 0: { z->lb = m3; return 0; } + case 1: + { int ret; + ret = slice_del(z); /* delete, line 57 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret; + ret = slice_from_s(z, 4, s_0); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret; + ret = slice_from_s(z, 4, s_1); /* <-, line 59 */ + if (ret < 0) return ret; + } + break; + } + z->lb = m3; + } + return 1; +} + +extern int swedish_UTF_8_stem(struct SN_env * z) { + { int c = z->c; /* do, line 66 */ + { int ret = r_mark_regions(z); + if (ret == 0) goto lab0; /* call mark_regions, line 66 */ + if (ret < 0) return ret; + } + lab0: + z->c = c; + } + z->lb = z->c; z->c = z->l; /* backwards, line 67 */ + + { int m = z->l - z->c; (void) m; /* do, line 68 */ + { int ret = r_main_suffix(z); + if (ret == 0) goto lab1; /* call main_suffix, line 68 */ + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 69 */ + { int ret = r_consonant_pair(z); + if (ret == 0) goto lab2; /* call consonant_pair, line 69 */ + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m; + } + { int m = z->l - z->c; (void) m; /* do, line 70 */ + { int ret = r_other_suffix(z); + if (ret == 0) goto lab3; /* call other_suffix, line 70 */ + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * swedish_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void swedish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z); } + diff --git a/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.h b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.h new file mode 100644 index 00000000000..1444ebb49a6 --- /dev/null +++ b/src/contribs-lib/CLucene/snowball/src_c/stem_UTF_8_swedish.h @@ -0,0 +1,16 @@ + +/* This file was generated automatically by the Snowball to ANSI C compiler */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * swedish_UTF_8_create_env(void); +extern void swedish_UTF_8_close_env(struct SN_env * z); + +extern int swedish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/contribs-lib/CLucene/util/arrayinputstream.h b/src/contribs-lib/CLucene/util/arrayinputstream.h new file mode 100644 index 00000000000..8225afcb088 --- /dev/null +++ b/src/contribs-lib/CLucene/util/arrayinputstream.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2009 Isidor Zeuner +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CLUCENE_UTIL_ARRAYINPUTSTREAM_H +#define CLUCENE_UTIL_ARRAYINPUTSTREAM_H + +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(util) + +template +class CLUCENE_CONTRIBS_EXPORT ArrayInputStream : public CL_NS(util)::CLStream { +public: + _CL_DEPRECATED(Use compressed field) ArrayInputStream(ArrayBase const* data); + int32_t read(const element*& start, int32_t min, int32_t max); + int64_t skip(int64_t ntoskip); + int64_t position(); + size_t size(); +private: + ArrayBase const* data; + int64_t current_position; +}; + +template +ArrayInputStream::ArrayInputStream(ArrayBase const* data) : +data(data), +current_position(0) { +} + +template +int32_t ArrayInputStream::read(const element*& start, int32_t min, int32_t max) { + int32_t to_read = min; + int32_t readable = data->length - current_position; + if (readable < to_read) { + to_read = readable; + } + start = data->values + current_position; + current_position += to_read; + return to_read; +} + +template +int64_t ArrayInputStream::skip(int64_t ntoskip) { + int64_t to_skip = ntoskip; + int64_t skippable = data->length - current_position; + if (skippable < to_skip) { + to_skip = skippable; + } + current_position += to_skip; + return to_skip; +} + +template +int64_t ArrayInputStream::position() { + return current_position; +} + +template +size_t ArrayInputStream::size() { + return data->length; +} +CL_NS_END +#endif diff --git a/src/contribs-lib/CLucene/util/byteinputstream.h b/src/contribs-lib/CLucene/util/byteinputstream.h new file mode 100644 index 00000000000..cf749c066d6 --- /dev/null +++ b/src/contribs-lib/CLucene/util/byteinputstream.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2009 Isidor Zeuner +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CLUCENE_UTIL_BYTEINPUTSTREAM_H +#define CLUCENE_UTIL_BYTEINPUTSTREAM_H + +#include "arrayinputstream.h" + +CL_NS_DEF(util) + +typedef ArrayInputStream ByteInputStream; + +CL_NS_END +#endif diff --git a/src/contribs-lib/CLucene/util/gzipcompressstream.cpp b/src/contribs-lib/CLucene/util/gzipcompressstream.cpp new file mode 100644 index 00000000000..3deaff9c9ae --- /dev/null +++ b/src/contribs-lib/CLucene/util/gzipcompressstream.cpp @@ -0,0 +1,126 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "gzipcompressstream.h" +#include "CLucene/util/_bufferedstream.h" +#include + +CL_NS_DEF(util) + +class GZipCompressInputStream::Internal: public CL_NS(util)::BufferedInputStreamImpl{ + z_stream_s* zstream; + InputStream* input; +protected: + int32_t fillBuffer(signed char* start, int32_t space){ + if (zstream == 0) return -1; + // make sure there is data to decompress + if (zstream->avail_in==0) { + // read data from the input stream + const signed char* inStart; + int32_t nread = input->read(inStart, 1, 0); + if (nread < 1) { + zstream->avail_in = 0; //bail... + if (deflate(zstream, Z_FINISH) != Z_STREAM_END) { + _CLTHROWA(CL_ERR_IO, "deflate should report Z_STREAM_END\n"); + } + int32_t nwritten = space - zstream->avail_out; + dealloc(); + return nwritten; + } + zstream->next_in = (Bytef*)inStart; + zstream->avail_in = nread; + } + + // make sure we can write into the buffer + zstream->avail_out = space; + zstream->next_out = (Bytef*)start; + + int r = deflate(zstream, Z_NO_FLUSH); + // inform the buffer of the number of bytes that was read + int32_t nwritten = space - zstream->avail_out; + switch (r) { + case Z_NEED_DICT: + _CLTHROWA(CL_ERR_IO, "Z_NEED_DICT while inflating stream."); + break; + case Z_DATA_ERROR: + _CLTHROWA(CL_ERR_IO, "Z_DATA_ERROR while inflating stream."); + break; + case Z_MEM_ERROR: + _CLTHROWA(CL_ERR_IO, "Z_MEM_ERROR while inflating stream."); + break; + } + return nwritten; + } +public: + void dealloc(){ + if (zstream) { + deflateEnd(zstream); + free(zstream); + zstream = 0; + } + } + void _setMinBufSize(int buf){ + this->setMinBufSize(buf); + } + Internal(InputStream* input, int level){ + if ( level < 0 || level > 9 ) + level = Z_DEFAULT_COMPRESSION; + + this->input = input; + + // initialize the z_stream + zstream = (z_stream_s*)malloc(sizeof(z_stream_s)); + zstream->zalloc = Z_NULL; + zstream->zfree = Z_NULL; + zstream->opaque = Z_NULL; + zstream->avail_in = 0; + + // initialize for writing gzip streams + int r = deflateInit(zstream, level); + if (r != Z_OK) { + dealloc(); + _CLTHROWA(CL_ERR_IO, "Error initializing GZipCompressInputStream."); + } + + // signal that we need to read into the buffer + zstream->avail_out = 1; + } + + ~Internal(){ + dealloc(); + } +}; + + +GZipCompressInputStream::GZipCompressInputStream ( InputStream* input, int level) +{ + internal = new Internal(input,level); +} +size_t GZipCompressInputStream::size(){ + return internal->size(); +} +GZipCompressInputStream::~GZipCompressInputStream () +{ + delete internal; +} +int32_t GZipCompressInputStream::read(const signed char*& start, int32_t min, int32_t max){ + return internal->read(start,min,max); +} +int64_t GZipCompressInputStream::position(){ + return internal->position(); +} +int64_t GZipCompressInputStream::reset(int64_t to){ + return internal->reset(to); +} +int64_t GZipCompressInputStream::skip(int64_t ntoskip){ + return internal->skip(ntoskip); +} +void GZipCompressInputStream::setMinBufSize(int32_t minbufsize){ + internal->_setMinBufSize(minbufsize); +} + +CL_NS_END diff --git a/src/contribs-lib/CLucene/util/gzipcompressstream.h b/src/contribs-lib/CLucene/util/gzipcompressstream.h new file mode 100644 index 00000000000..b58f8cda0c3 --- /dev/null +++ b/src/contribs-lib/CLucene/util/gzipcompressstream.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CLUENE_UTIL_GZIPCOMPRESSSTREAM_H +#define CLUENE_UTIL_GZIPCOMPRESSSTREAM_H + +#include "CLucene/util/CLStreams.h" + +struct z_stream_s; + +CL_NS_DEF(util) + +class CLUCENE_CONTRIBS_EXPORT GZipCompressInputStream : public InputStream{ +private: + class Internal; + Internal* internal; +public: + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_BUFFER_SIZE=4096); + _CL_DEPRECATED(Use compressed field) explicit GZipCompressInputStream(InputStream* input, int level=-1); + _CL_DEPRECATED(Use compressed field) virtual ~GZipCompressInputStream(); + + int32_t read(const signed char*& start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + size_t size(); + void setMinBufSize(int32_t minbufsize); +}; + +CL_NS_END +#endif diff --git a/src/contribs-lib/CLucene/util/gzipinputstream.cpp b/src/contribs-lib/CLucene/util/gzipinputstream.cpp new file mode 100644 index 00000000000..40e32e084cd --- /dev/null +++ b/src/contribs-lib/CLucene/util/gzipinputstream.cpp @@ -0,0 +1,184 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "gzipinputstream.h" +#include "CLucene/util/_bufferedstream.h" +#include + +CL_NS_DEF(util) + + +class GZipInputStream::Internal{ +public: + class JStreamsBuffer: public BufferedInputStreamImpl{ + z_stream_s* zstream; + BufferedInputStream* input; + protected: + + int32_t fillBuffer(signed char* start, int32_t space) { + if (zstream == 0) return -1; + // make sure there is data to decompress + if (zstream->avail_out) { + // read data from the input stream + const signed char* inStart; + int32_t nread = input->read(inStart, 1, 0); + if (nread < 1) { + _CLTHROWA(CL_ERR_IO, "unexpected end of stream"); + } else { + zstream->next_in = (Bytef*)inStart; + zstream->avail_in = nread; + } + } + // make sure we can write into the buffer + zstream->avail_out = space; + zstream->next_out = (Bytef*)start; + // decompress + int r = inflate(zstream, Z_SYNC_FLUSH); + // inform the buffer of the number of bytes that was read + int32_t nwritten = space - zstream->avail_out; + switch (r) { + case Z_NEED_DICT: + _CLTHROWA(CL_ERR_IO, "Z_NEED_DICT while inflating stream."); + break; + case Z_DATA_ERROR: + _CLTHROWA(CL_ERR_IO, "Z_DATA_ERROR while inflating stream."); + break; + case Z_MEM_ERROR: + _CLTHROWA(CL_ERR_IO, "Z_MEM_ERROR while inflating stream."); + break; + case Z_STREAM_END: + if (zstream->avail_in) { + input->reset(input->position()-zstream->avail_in); + } + // we are finished decompressing, + // (but this stream is not yet finished) + dealloc(); + } + return nwritten; + } + void dealloc() { + if (zstream) { + inflateEnd(zstream); + free(zstream); + zstream = 0; + } + } + bool checkMagic() { + const unsigned char* buf; + const signed char* begin; + int32_t nread; + + int64_t pos = input->position(); + nread = input->read(begin, 2, 2); + input->reset(pos); + if (nread != 2) { + return false; + } + + buf = (const unsigned char*)begin; + return buf[0] == 0x1f && buf[1] == 0x8b; + } + + public: + int encoding; + + JStreamsBuffer(BufferedInputStream* input, GZipInputStream::ZipFormat format){ + this->input = input; + + // check first bytes of stream before allocating buffer + if (format == GZipInputStream::GZIPFORMAT && !checkMagic()) { + _CLTHROWA(CL_ERR_IO, "Magic bytes are wrong."); + } + + // initialize the z_stream + zstream = (z_stream_s*)malloc(sizeof(z_stream_s)); + zstream->zalloc = Z_NULL; + zstream->zfree = Z_NULL; + zstream->opaque = Z_NULL; + zstream->avail_in = 0; + zstream->next_in = Z_NULL; + // initialize for reading gzip streams + // for reading libz streams, you need inflateInit(zstream) + int r; + switch(format) { + case GZipInputStream::ZLIBFORMAT: + r = inflateInit(zstream); + break; + case GZipInputStream::GZIPFORMAT: + r = inflateInit2(zstream, 15+16); + break; + case GZipInputStream::ZIPFORMAT: + default: + r = inflateInit2(zstream, -MAX_WBITS); + break; + } + if (r != Z_OK) { + dealloc(); + _CLTHROWA(CL_ERR_IO, "Error initializing GZipInputStream."); + } + + // signal that we need to read into the buffer + zstream->avail_out = 1; + } + void _setMinBufSize(int32_t bufsize){ + this->setMinBufSize(bufsize); + } + + ~JStreamsBuffer(){ + dealloc(); + } + }; + + JStreamsBuffer* jsbuffer; + + Internal(BufferedInputStream* input, GZipInputStream::ZipFormat format){ + jsbuffer = new JStreamsBuffer(input, format); + } + ~Internal(){ + delete jsbuffer; + } +}; + +GZipInputStream::GZipInputStream(InputStream* input, ZipFormat format) { + internal = new Internal(_CLNEW FilteredBufferedInputStream(input, false), format); +} +GZipInputStream::GZipInputStream(BufferedInputStream* input, ZipFormat format) { + internal = new Internal(input, format); +} + +GZipInputStream::~GZipInputStream() { + delete internal; +} + + +int32_t GZipInputStream::read(const signed char*& start, int32_t min, int32_t max){ + return internal->jsbuffer->read(start,min,max); +} +int32_t GZipInputStream::read(const unsigned char*& _start, int32_t min, int32_t max){ + const signed char* start = 0; + int32_t ret = internal->jsbuffer->read(start,min,max); + _start = (const unsigned char*)start; + return ret; +} +int64_t GZipInputStream::position(){ + return internal->jsbuffer->position(); +} +int64_t GZipInputStream::reset(int64_t to){ + return internal->jsbuffer->reset(to); +} +int64_t GZipInputStream::skip(int64_t ntoskip){ + return internal->jsbuffer->skip(ntoskip); +} +void GZipInputStream::setMinBufSize(int32_t minbufsize){ + internal->jsbuffer->_setMinBufSize(minbufsize); +} +size_t GZipInputStream::size(){ + return internal->jsbuffer->size(); +} + + +CL_NS_END diff --git a/src/contribs-lib/CLucene/util/gzipinputstream.h b/src/contribs-lib/CLucene/util/gzipinputstream.h new file mode 100644 index 00000000000..ae4dd49ed21 --- /dev/null +++ b/src/contribs-lib/CLucene/util/gzipinputstream.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CLUENE_UTIL_GZIPINPUTSTREAM_H +#define CLUENE_UTIL_GZIPINPUTSTREAM_H + +#include "CLucene/util/CLStreams.h" + +struct z_stream_s; + +CL_NS_DEF(util) + +class CLUCENE_CONTRIBS_EXPORT GZipInputStream : public CL_NS(util)::BufferedInputStream { +public: + enum ZipFormat { ZLIBFORMAT, GZIPFORMAT, ZIPFORMAT}; +private: + class Internal; + Internal* internal; +public: + _CL_DEPRECATED(Use compressed field) explicit GZipInputStream(BufferedInputStream* input, + ZipFormat format=GZIPFORMAT); + _CL_DEPRECATED(Use compressed field) explicit GZipInputStream(InputStream* input, + ZipFormat format=GZIPFORMAT); + ~GZipInputStream(); + + int32_t read(const signed char*& start, int32_t min, int32_t max); + int32_t read(const unsigned char*& start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + size_t size(); + void setMinBufSize(int32_t minbufsize); +}; + +CL_NS_END +#endif diff --git a/src/contribs-lib/CLucene/util/streamarray.h b/src/contribs-lib/CLucene/util/streamarray.h new file mode 100644 index 00000000000..bb1bbff46e0 --- /dev/null +++ b/src/contribs-lib/CLucene/util/streamarray.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2009 Isidor Zeuner +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CLUCENE_UTIL_STREAMARRAY_H +#define CLUCENE_UTIL_STREAMARRAY_H + +#include +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(util) + +template +ValueArray streamArray(CL_NS(util)::CLStream* stored) { + size_t const block_size = 4096; + element const* retrieved; + ValueArray result(0); + size_t available; + size_t offset = 0; + do { + available = stored->read(retrieved, block_size, block_size); + result.resize(result.length + sizeof(element) * available); + memcpy(result.values + offset, retrieved, sizeof(element) * available); + offset += available; + } while (block_size == available); + return result; +} +CL_NS_END +#endif diff --git a/src/contribs-lib/CMakeLists.txt b/src/contribs-lib/CMakeLists.txt new file mode 100644 index 00000000000..c3cd213407f --- /dev/null +++ b/src/contribs-lib/CMakeLists.txt @@ -0,0 +1,114 @@ +PROJECT(clucene-contribs-lib) + +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS} -DMAKE_CLUCENE_CONTRIBS_LIB) + +set(CMAKE_MODULE_PATH "${clucene-contribs-lib_SOURCE_DIR}/cmake") + +#add the files to our groups and core +SOURCE_GROUP("analysis" ./CLucene/analysis/*) +SOURCE_GROUP("util" ./CLucene/util/*) +#seems to be a bug in cmake, can't put these in analysis\\standard folder :( +SOURCE_GROUP("analysis-cjk" ./CLucene/analysis/cjk/*) +SOURCE_GROUP("analysis-de" ./CLucene/analysis/de/*) +SOURCE_GROUP("highlighter" ./CLucene/highlighter/*) +SOURCE_GROUP("index" ./CLucene/index/*) +SOURCE_GROUP("snowball" ./CLucene/snowball/*) +SOURCE_GROUP("snowball-impl" ./CLucene/snowball/include/*) +SOURCE_GROUP("snowball-impl" ./CLucene/snowball/libstemmer/*) +SOURCE_GROUP("snowball-impl" ./CLucene/snowball/runtime/*) +SOURCE_GROUP("snowball-impl" ./CLucene/snowball/src_c/*) + +SET(clucene_contribs_Files + ./CLucene/util/gzipcompressstream.cpp + ./CLucene/util/gzipinputstream.cpp + + ./CLucene/analysis/LanguageBasedAnalyzer.cpp + ./CLucene/analysis/cjk/CJKAnalyzer.cpp + + ./CLucene/analysis/de/GermanAnalyzer.cpp + ./CLucene/analysis/de/GermanStemFilter.cpp + ./CLucene/analysis/de/GermanStemmer.cpp + + ./CLucene/highlighter/Encoder.cpp + ./CLucene/highlighter/Formatter.cpp + ./CLucene/highlighter/Fragmenter.cpp + ./CLucene/highlighter/Highlighter.cpp + ./CLucene/highlighter/QueryScorer.cpp + ./CLucene/highlighter/QueryTermExtractor.cpp + ./CLucene/highlighter/SimpleFragmenter.cpp + ./CLucene/highlighter/SimpleHTMLEncoder.cpp + ./CLucene/highlighter/SimpleHTMLFormatter.cpp + ./CLucene/highlighter/TextFragment.cpp + ./CLucene/highlighter/TokenGroup.cpp + ./CLucene/highlighter/TokenSources.cpp + ./CLucene/highlighter/WeightedTerm.cpp + + ./CLucene/snowball/Snowball.cpp + ./CLucene/snowball/libstemmer/libstemmer.c + ./CLucene/snowball/runtime/api.c + ./CLucene/snowball/runtime/utilities.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_danish.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_dutch.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_english.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_finnish.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_french.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_german.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_italian.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_norwegian.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_porter.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_portuguese.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_spanish.c + ./CLucene/snowball/src_c/stem_ISO_8859_1_swedish.c + ./CLucene/snowball/src_c/stem_KOI8_R_russian.c + ./CLucene/snowball/src_c/stem_UTF_8_danish.c + ./CLucene/snowball/src_c/stem_UTF_8_dutch.c + ./CLucene/snowball/src_c/stem_UTF_8_english.c + ./CLucene/snowball/src_c/stem_UTF_8_finnish.c + ./CLucene/snowball/src_c/stem_UTF_8_french.c + ./CLucene/snowball/src_c/stem_UTF_8_german.c + ./CLucene/snowball/src_c/stem_UTF_8_italian.c + ./CLucene/snowball/src_c/stem_UTF_8_norwegian.c + ./CLucene/snowball/src_c/stem_UTF_8_porter.c + ./CLucene/snowball/src_c/stem_UTF_8_portuguese.c + ./CLucene/snowball/src_c/stem_UTF_8_russian.c + ./CLucene/snowball/src_c/stem_UTF_8_spanish.c + ./CLucene/snowball/src_c/stem_UTF_8_swedish.c +) +SET ( clucene_contrib_extra_libs clucene-core clucene-shared ${EXTRA_LIBS}) + +#find our headers +file(GLOB_RECURSE HEADERS ${clucene-contribs-lib_SOURCE_DIR}/*.h) + +#add extra capabilities +find_package(ZLIB) +IF ( NOT ZLIB_FOUND ) + MESSAGE ( FATAL "ZLib not found" ) +ENDIF ( NOT ZLIB_FOUND ) +INCLUDE_DIRECTORIES( ${ZLIB_INCLUDE_DIR} ) +SET ( clucene_contrib_extra_libs "${clucene_contrib_extra_libs}" ${ZLIB_LIBRARIES} ) + +find_package(Iconv) +#find_package(Strigi) +SET ( clucene-contrib-libs "" ) + +IF ( USE_SHARED_OBJECT_FILES ) + GET_SHARED_FILES(clucene_shared_Files) +ENDIF ( USE_SHARED_OBJECT_FILES ) + +#create the libraries +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/core ) +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/contribs-lib ) + +add_library(clucene-contribs-lib SHARED + ${clucene_contribs_Files} ${clucene_shared_Files} ${HEADERS} +) +TARGET_LINK_LIBRARIES(clucene-contribs-lib ${clucene_contrib_extra_libs}) + +#set properties on the libraries +SET_TARGET_PROPERTIES(clucene-contribs-lib PROPERTIES + VERSION ${CLUCENE_VERSION} + SOVERSION ${CLUCENE_SOVERSION} + COMPILE_DEFINITIONS_DEBUG _DEBUG +) diff --git a/src/contribs-lib/cmake/FindIconv.cmake b/src/contribs-lib/cmake/FindIconv.cmake new file mode 100644 index 00000000000..38f9e826134 --- /dev/null +++ b/src/contribs-lib/cmake/FindIconv.cmake @@ -0,0 +1,57 @@ +# - Try to find Iconv +# Once done this will define +# +# ICONV_FOUND - system has Iconv +# ICONV_INCLUDE_DIR - the Iconv include directory +# ICONV_LIBRARIES - Link these to use Iconv +# ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const +# +include(CheckCXXSourceCompiles) + +IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + # Already in cache, be silent + SET(ICONV_FIND_QUIETLY TRUE) +ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + +FIND_PATH(ICONV_INCLUDE_DIR iconv.h) + +FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c) + +IF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + SET(ICONV_FOUND TRUE) +ENDIF(ICONV_INCLUDE_DIR AND ICONV_LIBRARIES) + +set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR}) +set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) +IF(ICONV_FOUND) + check_cxx_source_compiles(" + #include + int main(){ + iconv_t conv = 0; + const char* in = 0; + size_t ilen = 0; + char* out = 0; + size_t olen = 0; + iconv(conv, &in, &ilen, &out, &olen); + return 0; + } +" ICONV_SECOND_ARGUMENT_IS_CONST ) +ENDIF(ICONV_FOUND) +set(CMAKE_REQUIRED_INCLUDES) +set(CMAKE_REQUIRED_LIBRARIES) + +IF(ICONV_FOUND) + IF(NOT ICONV_FIND_QUIETLY) + MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}") + ENDIF(NOT ICONV_FIND_QUIETLY) +ELSE(ICONV_FOUND) + IF(Iconv_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Iconv") + ENDIF(Iconv_FIND_REQUIRED) +ENDIF(ICONV_FOUND) + +MARK_AS_ADVANCED( + ICONV_INCLUDE_DIR + ICONV_LIBRARIES + ICONV_SECOND_ARGUMENT_IS_CONST +) diff --git a/src/contribs/CMakeLists.txt b/src/contribs/CMakeLists.txt new file mode 100644 index 00000000000..c17e5a76e20 --- /dev/null +++ b/src/contribs/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY (contribs-lib-test EXCLUDE_FROM_ALL) +ADD_SUBDIRECTORY (benchmarker EXCLUDE_FROM_ALL) diff --git a/src/contribs/bashscripts/findPatchThatBrokeUnitTest.sh b/src/contribs/bashscripts/findPatchThatBrokeUnitTest.sh new file mode 100644 index 00000000000..50ebf2f800e --- /dev/null +++ b/src/contribs/bashscripts/findPatchThatBrokeUnitTest.sh @@ -0,0 +1,113 @@ +#! /bin/bash +# +# (c) Jos van den Oever +# modified by (c) Ben van Klinken revisions +if (( $? != 0 )); then exit; fi + +for REVISION in `cat revisions`; do + runTest $REVISION; +done + +echo No revision was found in which the unit test worked. + diff --git a/src/contribs/bashscripts/simpleupdate.sh b/src/contribs/bashscripts/simpleupdate.sh new file mode 100644 index 00000000000..742735e2a85 --- /dev/null +++ b/src/contribs/bashscripts/simpleupdate.sh @@ -0,0 +1,41 @@ +#! /bin/bash + +# this test checks if the strigicmd utility properly detect creation and +# deletion of a file + +function fail() { + echo Test failed + exit 1 +} + +STRIGICMD="`find -type f -name strigicmd -type f -perm -o+x` " +echo Using $STRIGICMD +NTHREADS=1 + +rm -r x y 2> /dev/null +mkdir x +touch x/y +touch x/z +echo == $STRIGICMD create -t clucene -d y x == +if ! $STRIGICMD create -j 1 -t clucene -d y x; then + fail +fi +echo == $STRIGICMD listFiles -t clucene -d y == +if ! $STRIGICMD listFiles -t clucene -d y; then + fail +fi +rm x/y +echo == $STRIGICMD update -j $NTHREADS -t clucene -d y x == +if ! $STRIGICMD update -j $NTHREADS -t clucene -d y x; then + fail +fi +echo == $STRIGICMD listFiles -t clucene -d y == +if ! $STRIGICMD listFiles -t clucene -d y; then + fail +fi +OUT=`$STRIGICMD listFiles -t clucene -d y` +if [[ $OUT == $'x\nx/z' ]]; then + echo Test succesfull + exit 0 +fi +fail diff --git a/src/contribs/bashscripts/twofileupdate.sh b/src/contribs/bashscripts/twofileupdate.sh new file mode 100644 index 00000000000..166863adddc --- /dev/null +++ b/src/contribs/bashscripts/twofileupdate.sh @@ -0,0 +1,42 @@ +#! /bin/bash + +# this test checks if the strigicmd utility properly detect creation and +# deletion of a file + +function fail() { + echo Test failed + exit 1 +} + +#VG="valgrind --db-attach=yes " + +rm -r x y +mkdir x +touch x/y +touch x/z +echo == src/strigicmd/strigicmd create -t clucene -d y x == +if ! $VG src/strigicmd/strigicmd create -t clucene -d y x; then + fail +fi +echo == src/strigicmd/strigicmd listFiles -t clucene -d y == +if ! $VG src/strigicmd/strigicmd listFiles -t clucene -d y; then + fail +fi +sleep 1 +touch x/y +touch x/z +echo == src/strigicmd/strigicmd update -t clucene -d y x == +exit +if ! $VG src/strigicmd/strigicmd update -t clucene -d y x; then + fail +fi +echo == src/strigicmd/strigicmd listFiles -t clucene -d y == +if ! $VG src/strigicmd/strigicmd listFiles -t clucene -d y; then + fail +fi +OUT=`$VG src/strigicmd/strigicmd listFiles -t clucene -d y` +if [[ $OUT == 'x/z' ]]; then + echo Test succesfull + exit 0 +fi +fail diff --git a/src/contribs/benchmarker/Benchmarker.cpp b/src/contribs/benchmarker/Benchmarker.cpp new file mode 100644 index 00000000000..9784c70717a --- /dev/null +++ b/src/contribs/benchmarker/Benchmarker.cpp @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "stdafx.h" +#include "Benchmarker.h" +#include "Unit.h" + +void Benchmarker::Add(Unit* unit){ + tests.push_back(unit); +} +Benchmarker::Benchmarker(void) +{ + reset(); +} +void Benchmarker::reset(){ + timerTotal.reset(); + testsCountTotal=0; + testsCountSuccess=0; + testsRunTotal=0; + testsRunSuccess=0; +} +bool Benchmarker::run(){ + timerTotal.start(); + printf( ">> running tests...\n" ); + for ( int i=0;istart(this); + unit->stop(); + } + printf( "\n>> benchmarker ran a total of %d test cases(%d successes) in %d ms\n", + testsCountTotal,testsCountSuccess, + (int32_t)timerTotal.interval() ); + timerTotal.stop(); + + return testsCountSuccess > 0; +} diff --git a/src/contribs/benchmarker/Benchmarker.h b/src/contribs/benchmarker/Benchmarker.h new file mode 100644 index 00000000000..3e7583ec95a --- /dev/null +++ b/src/contribs/benchmarker/Benchmarker.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#pragma once + +class Benchmarker +{ + lucene::util::CLVector tests; +public: + Timer timerTotal; + int testsCountTotal; + int testsCountSuccess; + int testsRunTotal; + int testsRunSuccess; + + Benchmarker(void); + void Add(Unit* unit); + bool run(); + void reset(); +}; diff --git a/src/contribs/benchmarker/CMakeLists.txt b/src/contribs/benchmarker/CMakeLists.txt new file mode 100644 index 00000000000..7fcf06638cc --- /dev/null +++ b/src/contribs/benchmarker/CMakeLists.txt @@ -0,0 +1,20 @@ +PROJECT(clucene-benchmarker) + +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS}) + +file(GLOB_RECURSE benchmarker_HEADERS ${clucene-benchmarker_SOURCE_DIR}/*.h) + +SET(benchmarker_files + ./Benchmarker.cpp + ./Main.cpp + ./stdafx.cpp + ./Unit.cpp + + ./TestCLString.cpp + ${benchmarker_HEADERS} +) + +ADD_EXECUTABLE(cl_benchmarker EXCLUDE_FROM_ALL ${benchmarker_files} ) +TARGET_LINK_LIBRARIES(cl_benchmarker clucene-core clucene-shared ${EXTRA_LIBS}) diff --git a/src/contribs/benchmarker/Main.cpp b/src/contribs/benchmarker/Main.cpp new file mode 100644 index 00000000000..1d441892e57 --- /dev/null +++ b/src/contribs/benchmarker/Main.cpp @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "stdafx.h" +#include "TestCLString.h" + +#ifdef COMPILER_MSVC +#ifdef _DEBUG + #define CRTDBG_MAP_ALLOC + #include + #include +#endif +#endif + +#include + +#include +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_IO_H + #include +#endif + +using namespace std; +using namespace lucene::util; + +const char* cl_tempDir; +char clucene_data_location[1024]; + +int main( int argc, char** argv ){ + //Dumper Debug + #ifdef COMPILER_MSVC + #ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );//| _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); + #endif + #endif + + Benchmarker bench; + TestCLString clstring; + bool ret_result = false; + + cl_tempDir = NULL; + if ( Misc::dir_Exists("/tmp") ) + cl_tempDir = "/tmp"; + if ( getenv("TEMP") != NULL ) + cl_tempDir = getenv("TEMP"); + else if ( getenv("TMP") != NULL ) + cl_tempDir = getenv("TMP"); + + char* tmp = _CL_NEWARRAY(char,strlen(cl_tempDir)+9); + strcpy(tmp,cl_tempDir); + strcat(tmp,"/clucene"); + _mkdir(tmp); + if ( Misc::dir_Exists(tmp) ) + cl_tempDir=tmp; + + + clucene_data_location[0]=0; + if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION1 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION1); + else if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION2 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION2); + else if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION3 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION3); + else if ( getenv(CLUCENE_DATA_LOCATIONENV) != NULL ){ + strcpy(clucene_data_location,getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location,"/data/reuters-21578-index/segments"); + if ( CL_NS(util)::Misc::dir_Exists( clucene_data_location ) ){ + strcpy(clucene_data_location, getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location, "/data"); + }else + clucene_data_location[0]=0; + } + + /* first check that we are running the test for the correct position */ + //todo: make this configurable + if ( !*clucene_data_location ){ + fprintf(stderr,"%s must be run from a subdirectory of the application's root directory\n",argv[0]); + fprintf(stderr,"ensure that the test data exists in %s or %s or %s\n",CLUCENE_DATA_LOCATION1, CLUCENE_DATA_LOCATION2, CLUCENE_DATA_LOCATION3); + if ( getenv(CLUCENE_DATA_LOCATIONENV) != NULL ) + fprintf(stderr,"%s/data was also checked because of the " CLUCENE_DATA_LOCATIONENV " environment variable", getenv(CLUCENE_DATA_LOCATIONENV)); + ret_result = 1; + goto exit_point; + } + + + bench.Add(&clstring); + ret_result = bench.run(); + + + +exit_point: + _lucene_shutdown(); //clears all static memory + //print lucenebase debug + + return ret_result ? 0 : 1; + + //Debuggin techniques: + //For msvc, use this for breaking on memory leaks: + // _crtBreakAlloc + //for linux, use valgrind +} diff --git a/src/contribs/benchmarker/TestCLString.cpp b/src/contribs/benchmarker/TestCLString.cpp new file mode 100644 index 00000000000..ece7a57f59f --- /dev/null +++ b/src/contribs/benchmarker/TestCLString.cpp @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "stdafx.h" + +using namespace lucene::util; +using namespace lucene::analysis; +using namespace lucene::document; +using namespace lucene::index; +using namespace lucene::store; + +int BenchmarkDocumentWriter(Timer* timerCase) +{ + RAMDirectory ram; + SimpleAnalyzer an; + IndexWriter* ndx = _CLNEW IndexWriter(&ram, &an, true); + ndx->setMaxFieldLength(0x7FFFFFFF); + + char fname[1024]; + strcpy(fname, clucene_data_location); + strcat(fname, "reuters-21578/feldman-cia-worldfactbook-data.txt"); + + timerCase->start(); + for ( int i=0;i<10;i++ ){ + + FileReader* reader = _CLNEW FileReader(fname, "ASCII"); + Document doc; + doc.add(*_CLNEW Field(_T("contents"),reader, Field::STORE_YES | Field::INDEX_TOKENIZED)); + + ndx->addDocument(&doc); + } + ndx->close(); + timerCase->stop(); + + ram.close(); + _CLDELETE(ndx); + return 0; +} + +int BenchmarkTermDocs(Timer* timerCase){ + IndexReader* reader = IndexReader::open("index"); + timerCase->start(); + TermEnum* en = reader->terms(); + while (en->next()){ + Term* term = en->term(); + _CLDECDELETE(term); + } + en->close(); + _CLDELETE(en); + timerCase->stop(); + reader->close(); + _CLDELETE(reader); + return 0; +} diff --git a/src/contribs/benchmarker/TestCLString.h b/src/contribs/benchmarker/TestCLString.h new file mode 100644 index 00000000000..f5d795c8d0e --- /dev/null +++ b/src/contribs/benchmarker/TestCLString.h @@ -0,0 +1,23 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#pragma once + +int BenchmarkDocumentWriter(Timer*); +int BenchmarkTermDocs(Timer* timerCase); + +class TestCLString:public Unit +{ +protected: + void runTests(){ + this->runTest("BenchmarkDocumentWriter",BenchmarkDocumentWriter,10); + //this->runTest("BenchmarkTermDocs",BenchmarkTermDocs,100); + } +public: + const char* getName(){ + return "TestCLString"; + } +}; diff --git a/src/contribs/benchmarker/Timer.h b/src/contribs/benchmarker/Timer.h new file mode 100644 index 00000000000..92018bd0308 --- /dev/null +++ b/src/contribs/benchmarker/Timer.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#pragma once + +class Timer{ +public: + int64_t startTime; + int64_t stopTime; + bool running; + Timer(){ + running=false; + reset(); + } + void reset(){ + startTime=0; + stopTime=0; + running=false; + } + void start(){ + startTime = lucene::util::Misc::currentTimeMillis(); + running=true; + } + int32_t split(){ + return lucene::util::Misc::currentTimeMillis()-startTime; + } + int32_t stop(){ + if ( running ){ + running=false; + stopTime = lucene::util::Misc::currentTimeMillis(); + } + return stopTime-startTime; + } + int32_t interval(){ + if (running) + return lucene::util::Misc::currentTimeMillis()-startTime; + else + return stopTime-startTime; + } + +}; + + +typedef int (*PTEST_ROUTINE)(Timer*); +typedef PTEST_ROUTINE LPTEST_ROUTINE; diff --git a/src/contribs/benchmarker/Unit.cpp b/src/contribs/benchmarker/Unit.cpp new file mode 100644 index 00000000000..716a42996d7 --- /dev/null +++ b/src/contribs/benchmarker/Unit.cpp @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "stdafx.h" +#include "Unit.h" + +Unit::Unit() +{ + this->bm=NULL; + testsCountTotal=0; + testsCountSuccess=0; + testsRunTotal=0; + testsRunSuccess=0; + timerCase.reset(); + timerTotal.reset(); +} + +void Unit::stop(){ + timerTotal.stop(); + bm=NULL; + + printf( "> unit ran a total of %d test cases(%d successes) in %d ms\n", + testsCountTotal,testsCountSuccess, + (int)timerTotal.interval() ); +} + +void Unit::start(Benchmarker* bm){ + this->bm = bm; + timerTotal.start(); + + printf( "> running unit %s\n", getName() ); + runTests(); +} +void Unit::runTest(const char* testName,LPTEST_ROUTINE func, int iterations){ + if ( bm == NULL ) + _CLTHROWA(CL_ERR_NullPointer, "Unit not started with benchmarker!"); + float avg=0; + int32_t min=0; + int32_t max=0; + int count=0; + Timer total; + bool success = false; + + try { + total.start(); + printf("\n > running %s %d times...", testName, iterations); + for ( int i=0;i max ) + max = t; + avg = (avg + t)/2; + } + + testsRunTotal++; + bm->testsRunTotal++; + if ( success ){ + testsRunSuccess++; + bm->testsRunSuccess++; + } + count++; + } + success = true; + }catch(CLuceneError& err){ + printf("\n > error occurred: %s\n", err.what()); + }catch(...){ + printf("\n > unexpected error occurred\n >"); + } + testsCountTotal++; + bm->testsCountTotal++; + if ( success ){ + testsCountSuccess++; + bm->testsCountSuccess++; + } + printf(" it took %d milliseconds",total.stop()); + + if ( iterations > 1 ){ + printf("\n\tmin:%d",min); + printf(" max:%d,",max); + printf(" avg:%0.3f milliseconds",avg); + } + printf("\n"); +} diff --git a/src/contribs/benchmarker/Unit.h b/src/contribs/benchmarker/Unit.h new file mode 100644 index 00000000000..6ace5ca218a --- /dev/null +++ b/src/contribs/benchmarker/Unit.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#pragma once +#include "CLucene/util/Misc.h" + + +class Unit +{ +public: + void start(Benchmarker* benchmarker); + void stop(); + virtual const char* getName()=0; + Unit(); +protected: + Timer timerCase; + Timer timerTotal; + int testsCountTotal; + int testsCountSuccess; + int testsRunTotal; + int testsRunSuccess; + Benchmarker* bm; + + void runTest(const char* testName,LPTEST_ROUTINE func, int iterations); + virtual void runTests()=0; +}; diff --git a/src/contribs/benchmarker/stdafx.cpp b/src/contribs/benchmarker/stdafx.cpp new file mode 100644 index 00000000000..187b805149a --- /dev/null +++ b/src/contribs/benchmarker/stdafx.cpp @@ -0,0 +1,11 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +// stdafx.cpp : source file that includes just the standard includes +// demo.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/src/contribs/benchmarker/stdafx.h b/src/contribs/benchmarker/stdafx.h new file mode 100644 index 00000000000..fac231f7ff8 --- /dev/null +++ b/src/contribs/benchmarker/stdafx.h @@ -0,0 +1,37 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// +#ifndef _lucene_examples_benchmark_stdafx_ +#define _lucene_examples_benchmark_stdafx_ + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +//#include +#include + +#include "CLucene.h" +#include "CLucene/_clucene-config.h" +#include "CLucene/util/Misc.h" +#include "CLucene/store/RAMDirectory.h" + +#define CLUCENE_DATA_LOCATION1 "../../src/test/data/" +#define CLUCENE_DATA_LOCATION2 "../src/test/data/" +#define CLUCENE_DATA_LOCATION3 "../../../src/test/data/" +#define CLUCENE_DATA_LOCATIONENV "srcdir" + +extern const char* cl_tempDir; +extern char clucene_data_location[1024]; + +class Benchmarker; +#include "Timer.h" +#include "Unit.h" +#include "Benchmarker.h" + +#endif diff --git a/src/contribs/contribs-lib-test/CMakeLists.txt b/src/contribs/contribs-lib-test/CMakeLists.txt new file mode 100644 index 00000000000..44645463690 --- /dev/null +++ b/src/contribs/contribs-lib-test/CMakeLists.txt @@ -0,0 +1,33 @@ +PROJECT(clucene-contribs-lib-test) + +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS}) + +INCLUDE_DIRECTORIES( ${clucene-contribs-lib-test_SOURCE_DIR} ) +INCLUDE_DIRECTORIES( ${clucene-contribs-lib_SOURCE_DIR} ) + +file(GLOB_RECURSE test_HEADERS ${CMAKE_SOURCE_DIR}/test/*.h) + +SET(test_files + ./contribTests.cpp + ./TestHighlight.cpp + ./TestSnowball.cpp + ./TestStreams.cpp + ./TestUtf8.cpp + ./TestAnalysis.cpp + ./CuTest.cpp + ./testall.cpp + ${test_HEADERS} +) +IF ( USE_SHARED_OBJECT_FILES ) + GET_SHARED_FILES(clucene_shared_Files) +ENDIF ( USE_SHARED_OBJECT_FILES ) + +#todo: do glob header and include header files for IDE. +ADD_EXECUTABLE(cl_contribs-lib-test EXCLUDE_FROM_ALL ${clucene_shared_Files} ${test_files} ) + +#link the executable against the releavent clucene-shared library (if we aren't using the object files) +IF ( NOT USE_SHARED_OBJECT_FILES ) + TARGET_LINK_LIBRARIES(cl_contribs-lib-test clucene-core clucene-shared clucene-contribs-lib ${EXTRA_LIBS}) +ENDIF ( NOT USE_SHARED_OBJECT_FILES ) diff --git a/src/contribs/contribs-lib-test/CuTest.cpp b/src/contribs/contribs-lib-test/CuTest.cpp new file mode 100644 index 00000000000..0cd9caf72cc --- /dev/null +++ b/src/contribs/contribs-lib-test/CuTest.cpp @@ -0,0 +1,536 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CuTest.h" +#include +#include + +static int verbose = 0; +static int messyPrinting = 0; + +void CuInit(int argc, char *argv[]) { + int i; + + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-v")) { + verbose = 1; + } + if (!strcmp(argv[i], "-p")) { + messyPrinting = 1; + } + } +} + +/*-------------------------------------------------------------------------* + * CuTcs + *-------------------------------------------------------------------------*/ +TCHAR* CuStrAlloc(int size) { + TCHAR* n = (TCHAR*) malloc(sizeof (TCHAR) * (size)); + return n; +} + +TCHAR* CuTcsCopy(TCHAR* old) { + int len = _tcslen(old); + TCHAR* n = CuStrAlloc(len + 1); + _tcscpy(n, old); + return n; +} + +TCHAR* CuTcsCat(TCHAR* orig, TCHAR* add) { + int len = _tcslen(orig) + _tcslen(add); + TCHAR* n = CuStrAlloc(len + 1); + _tcscpy(n, orig); + _tcscat(n, add); + return n; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +TCHAR* CuTcsAlloc(int size) { + TCHAR* n = (TCHAR*) malloc(sizeof (TCHAR) * (size)); + return n; +} + +TCHAR* CuTcsCopy(const TCHAR* old) { + int len = _tcslen(old); + TCHAR* n = CuTcsAlloc(len + 1); + _tcscpy(n, old); + return n; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +void CuStringInit(CuString* str) { + str->length = 0; + str->size = STRING_MAX; + str->buffer = (TCHAR*) malloc(sizeof (TCHAR) * str->size); + str->buffer[0] = '\0'; +} + +CuString* CuStringNew(void) { + CuString* str = (CuString*) malloc(sizeof (CuString)); + str->length = 0; + str->size = STRING_MAX; + str->buffer = (TCHAR*) malloc(sizeof (TCHAR) * str->size); + str->buffer[0] = '\0'; + return str; +} + +void CuStringFree(CuString* str) { + free(str->buffer); + free(str); +} + +void CuStringResize(CuString* str, int newSize) { + str->buffer = (TCHAR*) realloc(str->buffer, sizeof (TCHAR) * newSize); + str->size = newSize; +} + +void CuStringAppend(CuString* str, const TCHAR* text) { + int length = _tcslen(text); + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + str->length += length; + _tcscat(str->buffer, text); +} + +void CuStringAppendChar(CuString* str, TCHAR ch) { + TCHAR text[2]; + text[0] = ch; + text[1] = '\0'; + CuStringAppend(str, text); +} + +void CuStringAppendFormat(CuString* str, const TCHAR* format, ...) { + TCHAR buf[HUGE_STRING_LEN]; + va_list argp; + va_start(argp, format); + _vsntprintf(buf, HUGE_STRING_LEN, format, argp); + va_end(argp); + CuStringAppend(str, buf); +} + +void CuStringRead(CuString *str, TCHAR *path) { + path = NULL; + CU_TDUP(path, str->buffer); +} + +/*-------------------------------------------------------------------------* + * CuTest + *-------------------------------------------------------------------------*/ + +void CuTestInit(CuTest* t, const TCHAR* name, TestFunction function) { + t->name = CuTcsCopy(name); + t->notimpl = 0; + t->failed = 0; + t->ran = 0; + t->message = NULL; + t->function = function; + // t->jumpBuf = NULL; +} + +CuTest* CuTestNew(const TCHAR* name, TestFunction function) { + CuTest* tc = CU_ALLOC(CuTest); + CuTestInit(tc, name, function); + return tc; +} + +void CuTestDelete(CuTest* tst) { + free(tst->name); + if (tst->message != NULL) + free(tst->message); + free(tst); +} + +void CuNotImpl(CuTest* tc, const TCHAR* message) { + CuString* newstr = CuStringNew(); + CuStringAppend(newstr, message); + CuStringAppend(newstr, _T(" not implemented on this platform")); + tc->notimpl = 1; + CuMessage(tc, newstr->buffer); + CuStringFree(newstr); + // if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0); +} + +void CuFail(CuTest* tc, const TCHAR* format, ...) { + tc->failed = 1; + + TCHAR buf[HUGE_STRING_LEN]; + va_list argp; + va_start(argp, format); + _vsntprintf(buf, HUGE_STRING_LEN, format, argp); + va_end(argp); + + // CuMessage(tc,buf); + _CLTHROWT(CL_ERR_Runtime, buf); +} + +void CuMessageV(CuTest* tc, const TCHAR* format, va_list& argp) { + TCHAR buf[HUGE_STRING_LEN]; + _vsntprintf(buf, HUGE_STRING_LEN, format, argp); + + TCHAR* old = tc->message; + if (messyPrinting) { + _tprintf(_T("%s"), buf); + } else { + if (old == NULL) { + tc->message = CuTcsCopy(buf); + } else { + tc->message = CuTcsCat(old, buf); + free(old); + } + } +} + +void CuMessage(CuTest* tc, const TCHAR* format, ...) { + va_list argp; + va_start(argp, format); + CuMessageV(tc, format, argp); + va_end(argp); +} + +void CuMessageA(CuTest* tc, const char* format, ...) { + va_list argp; + char buf[HUGE_STRING_LEN]; + TCHAR tbuf[HUGE_STRING_LEN]; + va_start(argp, format); + vsprintf(buf, format, argp); + va_end(argp); + + TCHAR* old = tc->message; + STRCPY_AtoT(tbuf, buf, HUGE_STRING_LEN); + if (messyPrinting) { + _tprintf(_T("%s"), buf); + } else { + if (old == NULL) { + tc->message = CuTcsCopy(tbuf); + } else { + tc->message = CuTcsCat(old, tbuf); + free(old); + } + } +} + +void CuAssert(CuTest* tc, const TCHAR* message, int condition) { + if (condition) return; + CuFail(tc, message); +} + +void CuAssertTrue(CuTest* tc, int condition) { + if (condition) return; + CuFail(tc, _T("assert failed")); +} + +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, const TCHAR* actual) { + CuString* message; + if (_tcscmp(expected, actual) == 0) return; + message = CuStringNew(); + CuStringAppend(message, preMessage); + CuStringAppend(message, _T(" : ")); + CuStringAppend(message, _T("expected\n---->\n")); + CuStringAppend(message, expected); + CuStringAppend(message, _T("\n<----\nbut saw\n---->\n")); + CuStringAppend(message, actual); + CuStringAppend(message, _T("\n<----")); + CuFail(tc, message->buffer); + CuStringFree(message); +} + +void CuAssertIntEquals(CuTest* tc, const TCHAR* preMessage, int expected, int actual) { + TCHAR buf[STRING_MAX]; + if (expected == actual) return; + _sntprintf(buf, STRING_MAX, _T("%s : expected <%d> but was <%d>"), preMessage, expected, actual); + CuFail(tc, buf); +} + +void CuAssertPtrEquals(CuTest* tc, const TCHAR* preMessage, const void* expected, const void* actual) { + TCHAR buf[STRING_MAX]; + if (expected == actual) return; + _sntprintf(buf, STRING_MAX, _T("%s : expected pointer <%p> but was <%p>"), preMessage, expected, actual); + CuFail(tc, buf); +} + +void CuAssertPtrNotNull(CuTest* tc, const TCHAR* preMessage, const void* pointer) { + TCHAR buf[STRING_MAX]; + if (pointer != NULL) return; + _sntprintf(buf, STRING_MAX, _T("%s : null pointer unexpected, but was <%p>"), preMessage, pointer); + CuFail(tc, buf); +} + +void CuTestRun(CuTest* tc) { + // jmp_buf buf; + // tc->jumpBuf = &buf; + // if (setjmp(buf) == 0) + // { + tc->ran = 1; + (tc->function)(tc); + // } + // tc->jumpBuf = 0; +} + +/*-------------------------------------------------------------------------* + * CuSuite + *-------------------------------------------------------------------------*/ + +void CuSuiteInit(CuSuite* testSuite, const TCHAR *name) { + testSuite->name = NULL; + CU_TDUP(testSuite->name, name); + testSuite->count = 0; + testSuite->failCount = 0; + testSuite->notimplCount = 0; + testSuite->timeTaken = 0; +} + +CuSuite* CuSuiteNew(const TCHAR *name) { + CuSuite* testSuite = CU_ALLOC(CuSuite); + CuSuiteInit(testSuite, name); + return testSuite; +} + +void CuSuiteDelete(CuSuite* suite) { + free(suite->name); + for (int i = 0; i < suite->count; i++) { + CuTestDelete(suite->list[i]); + } + free(suite); +} + +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) { + assert(testSuite->count < MAX_TEST_CASES); + testSuite->list[testSuite->count] = testCase; + testSuite->count++; +} + +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2) { + int i; + for (i = 0; i < testSuite2->count; ++i) { + CuTest* testCase = testSuite2->list[i]; + CuSuiteAdd(testSuite, testCase); + } +} + +void CuSuiteRun(CuSuite* testSuite) { + int i; + uint64_t start = Misc::currentTimeMillis(); + for (i = 0; i < testSuite->count; ++i) { + CuTest* testCase = testSuite->list[i]; + try { + CuTestRun(testCase); + } catch (CLuceneError& err) { + testCase->failed = 1; + CuMessage(testCase, err.twhat()); + } + testSuite->timeTaken = Misc::currentTimeMillis() - start; + if (testCase->failed) { + testSuite->failCount += 1; + } + if (testCase->notimpl) { + testSuite->notimplCount += 1; + } + } +} + +void CuSuiteSummary(CuSuite* testSuite, CuString* summary, bool times) { + int i; + for (i = 0; i < testSuite->count; ++i) { + CuTest* testCase = testSuite->list[i]; + CuStringAppend(summary, testCase->failed ? _T("F") : + testCase->notimpl ? _T("N") : _T(".")); + } + if (times) { + int bufferLen = 25 - summary->length - 10; + for (int i = 0; i < bufferLen; i++) + CuStringAppend(summary, _T(" ")); + CuStringAppendFormat(summary, _T(" - %dms"), testSuite->timeTaken); + } + CuStringAppend(summary, _T("\n")); +} + +void CuSuiteOverView(CuSuite* testSuite, CuString* details) { + CuStringAppendFormat(details, _T("%d %s run: %d passed, %d failed, ") + _T("%d not implemented.\n"), + testSuite->count, + testSuite->count == 1 ? "test" : "tests", + testSuite->count - testSuite->failCount - + testSuite->notimplCount, + testSuite->failCount, testSuite->notimplCount); +} + +void CuSuiteDetails(CuSuite* testSuite, CuString* details) { + int i; + int failCount = 0; + + if (testSuite->failCount != 0 && verbose) { + CuStringAppendFormat(details, _T("\nFailed tests in %s:\n"), testSuite->name); + for (i = 0; i < testSuite->count; ++i) { + CuTest* testCase = testSuite->list[i]; + if (testCase->failed) { + failCount++; + CuStringAppendFormat(details, _T("%d) %s: %s\n"), + failCount, testCase->name, testCase->message); + } + } + } + if (testSuite->notimplCount != 0 && verbose) { + CuStringAppendFormat(details, _T("\nNot Implemented tests in %s:\n"), testSuite->name); + for (i = 0; i < testSuite->count; ++i) { + CuTest* testCase = testSuite->list[i]; + if (testCase->notimpl) { + failCount++; + CuStringAppendFormat(details, _T("%d) %s: %s\n"), + failCount, testCase->name, testCase->message); + } + } + } +} + +/*-------------------------------------------------------------------------* + * CuSuiteList + *-------------------------------------------------------------------------*/ + +CuSuiteList* CuSuiteListNew(const TCHAR *name) { + CuSuiteList* testSuite = CU_ALLOC(CuSuiteList); + testSuite->name = NULL; + CU_TDUP(testSuite->name, name); + testSuite->count = 0; + return testSuite; +} + +void CuSuiteListDelete(CuSuiteList* lst) { + free(lst->name); + for (int i = 0; i < lst->count; i++) { + CuSuiteDelete(lst->list[i]); + } + free(lst); +} + +void CuSuiteListAdd(CuSuiteList *suites, CuSuite *origsuite) { + assert(suites->count < MAX_TEST_CASES); + suites->list[suites->count] = origsuite; + suites->count++; +} + +void CuSuiteListRun(CuSuiteList* testSuite) { + int i; + for (i = 0; i < testSuite->count; ++i) { + CuSuite* testCase = testSuite->list[i]; + CuSuiteRun(testCase); + } +} + +static const TCHAR *genspaces(int i) { + TCHAR *str = (TCHAR*) malloc((i + 1) * sizeof (TCHAR)); + for (int j = 0; j < i; j++) + str[j] = _T(' '); + str[i] = '\0'; + return str; +} + +void CuSuiteListRunWithSummary(CuSuiteList* testSuite, bool verbose, bool times) { + int i; + + _tprintf(_T("%s:\n"), testSuite->name); + for (i = 0; i < testSuite->count; ++i) { + bool hasprinted = false; + CuSuite* testCase = testSuite->list[i]; + CuString *str = CuStringNew(); + + size_t len = _tcslen(testCase->name); + const TCHAR* spaces = len > 31 ? NULL : genspaces(31 - len); + _tprintf(_T(" %s:%s"), testCase->name, len > 31 ? _T("") : spaces); + free((void*) spaces); + fflush(stdout); + + CuSuiteRun(testCase); + if (verbose) { + for (int i = 0; i < testCase->count; i++) { + if (testCase->list[i]->ran) { + if (testCase->list[i]->message != NULL) { + if (!hasprinted) + printf("\n"); + _tprintf(_T(" %s:\n"), testCase->list[i]->name); + + TCHAR* msg = testCase->list[i]->message; + bool nl = true; + //write out message, indenting on new lines + while (*msg != '\0') { + if (nl) { + printf(" "); + nl = false; + } + if (*msg == '\n') + nl = true; + putc(*msg, stdout); + + msg++; + } + + if (testCase->list[i]->message[_tcslen(testCase->list[i]->message) - 1] != '\n') + printf("\n"); + hasprinted = true; + } + } + } + } + CuSuiteSummary(testCase, str, times); + if (hasprinted) + _tprintf(_T(" Result: %s\n"), str->buffer); + else + _tprintf(_T(" %s"), str->buffer); + + CuStringFree(str); + } + _tprintf(_T("\n")); +} + +int CuSuiteListDetails(CuSuiteList* testSuite, CuString* details) { + int i; + int failCount = 0; + int notImplCount = 0; + int count = 0; + + for (i = 0; i < testSuite->count; ++i) { + failCount += testSuite->list[i]->failCount; + notImplCount += testSuite->list[i]->notimplCount; + count += testSuite->list[i]->count; + } + CuStringAppendFormat(details, _T("%d %s run: %d passed, %d failed, ") + _T("%d not implemented.\n"), + count, + count == 1 ? _T("test") : _T("tests"), + count - failCount - notImplCount, + failCount, notImplCount); + + if (failCount != 0 && verbose) { + for (i = 0; i < testSuite->count; ++i) { + CuString *str = CuStringNew(); + CuSuite* testCase = testSuite->list[i]; + if (testCase->failCount) { + CuSuiteDetails(testCase, str); + CuStringAppend(details, str->buffer); + } + CuStringFree(str); + } + } + if (notImplCount != 0 && verbose) { + for (i = 0; i < testSuite->count; ++i) { + CuString *str = CuStringNew(); + CuSuite* testCase = testSuite->list[i]; + if (testCase->notimplCount) { + CuSuiteDetails(testCase, str); + CuStringAppend(details, str->buffer); + } + CuStringFree(str); + } + } + return failCount; +} + diff --git a/src/contribs/contribs-lib-test/CuTest.h b/src/contribs/contribs-lib-test/CuTest.h new file mode 100644 index 00000000000..79b5c23fc70 --- /dev/null +++ b/src/contribs/contribs-lib-test/CuTest.h @@ -0,0 +1,122 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CU_TEST_H +#define CU_TEST_H + +/* CuString */ + +TCHAR* CuWstrAlloc(int size); +TCHAR* CuWstrCopy(const TCHAR* old); + +#define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) +#define CU_TDUP(dest,src) dest=((TCHAR*)malloc(sizeof(TCHAR)*_tcslen(src)+sizeof(TCHAR)));_tcscpy(dest,src); + +#define HUGE_STRING_LEN 8192 +#define STRING_MAX 256 +#define STRING_INC 256 + +#define CLUCENE_ASSERT(x) CuAssert(tc,_T("Assert Failed: ") _T(#x),x) + +typedef struct { + int length; + int size; + TCHAR* buffer; +} CuString; + +void CuStringInit(CuString* str); +CuString* CuStringNew(void); +void CuStringFree(CuString* str); +void CuStringRead(CuString* str, TCHAR* path); +void CuStringAppend(CuString* str, const TCHAR* text); +void CuStringAppendChar(CuString* str, TCHAR ch); +void CuStringAppendFormat(CuString* str, const TCHAR* format, ...); +void CuStringResize(CuString* str, int newSize); + +/* CuTest */ + +typedef struct CuTest CuTest; + +typedef void (*TestFunction)(CuTest *); + +struct CuTest { + TCHAR* name; + TestFunction function; + int notimpl; + int failed; + int ran; + TCHAR* message; + // jmp_buf *jumpBuf; +}; + + +void CuInit(int argc, char *argv[]); +void CuTestInit(CuTest* t, const TCHAR* name, TestFunction function); +CuTest* CuTestNew(const TCHAR* name, TestFunction function); +void CuTestDelete(CuTest* tst); +void CuFail(CuTest* tc, const TCHAR* format, ...); +void CuMessage(CuTest* tc, const TCHAR* message, ...); +void CuMessageV(CuTest* tc, const TCHAR* format, va_list& argp); +void CuMessageA(CuTest* tc, const char* format, ...); +void CuNotImpl(CuTest* tc, const TCHAR* message); +void CuAssert(CuTest* tc, const TCHAR* message, int condition); +void CuAssertTrue(CuTest* tc, int condition); +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, const TCHAR* actual); +void CuAssertIntEquals(CuTest* tc, const TCHAR* preMessage, int expected, int actual); +void CuAssertPtrEquals(CuTest* tc, const TCHAR* preMessage, const void* expected, const void* actual); +void CuAssertPtrNotNull(CuTest* tc, const TCHAR* preMessage, const void* pointer); + +void CuTestRun(CuTest* tc); + +/* CuSuite */ + +#define MAX_TEST_CASES 1024 + +#define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(_T(#TEST), TEST)) + +extern char clucene_data_location[1024]; + +typedef struct { + TCHAR *name; + int count; + CuTest * list[MAX_TEST_CASES]; + int failCount; + int notimplCount; + uint64_t timeTaken; +} CuSuite; + + +void CuSuiteInit(CuSuite* testSuite, const TCHAR* name); +CuSuite* CuSuiteNew(const TCHAR* name); +void CuSuiteDelete(CuSuite* suite); +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); +void CuSuiteRun(CuSuite* testSuite); +void CuSuiteSummary(CuSuite* testSuite, CuString* summary, bool times); +void CuSuiteOverView(CuSuite* testSuite, CuString* details); +void CuSuiteDetails(CuSuite* testSuite, CuString* details); + +typedef struct { + TCHAR *name; + int count; + CuSuite * list[MAX_TEST_CASES]; +} CuSuiteList; + +struct unittest { + const char *testname; + CuSuite * (*func)(void); +}; + +CuSuiteList* CuSuiteListNew(const TCHAR* name); +void CuSuiteListDelete(CuSuiteList* lst); +void CuSuiteListAdd(CuSuiteList* testSuite, CuSuite *testCase); +void CuSuiteListRun(CuSuiteList* testSuite); +void CuSuiteListRunWithSummary(CuSuiteList* testSuite, bool verbose, bool times); +//void CuSuiteListSummary(CuSuiteList* testSuite, CuString* summary); +/* Print details of test suite results; returns total number of + * tests which failed. */ +int CuSuiteListDetails(CuSuiteList* testSuite, CuString* details); +#endif /* CU_TEST_H */ diff --git a/src/contribs/contribs-lib-test/TestAnalysis.cpp b/src/contribs/contribs-lib-test/TestAnalysis.cpp new file mode 100644 index 00000000000..481b2f72b29 --- /dev/null +++ b/src/contribs/contribs-lib-test/TestAnalysis.cpp @@ -0,0 +1,190 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/analysis/cjk/CJKAnalyzer.h" +#include "CLucene/analysis/LanguageBasedAnalyzer.h" +#include "CLucene/snowball/SnowballFilter.h" + +#include +#ifdef _CL_HAVE_IO_H +#include +#endif +#ifdef _CL_HAVE_SYS_STAT_H +#include +#endif +#ifdef _CL_HAVE_UNISTD_H +#include +#endif +#ifdef _CL_HAVE_DIRECT_H +#include +#endif +#include + +CL_NS_USE2(analysis, cjk) +CL_NS_USE2(analysis, snowball) + +void test(CuTest *tc, char* orig, Reader* reader, bool verbose, int64_t bytes) { + StandardAnalyzer analyzer; + TokenStream* stream = analyzer.tokenStream(NULL, reader); + + uint64_t start = Misc::currentTimeMillis(); + + int32_t count = 0; + Token t; + char atmp[LUCENE_MAX_WORD_LEN + 1]; + TCHAR ttmp[LUCENE_MAX_WORD_LEN + 1]; + for (; stream->next(&t);) { + if (verbose) { + CuMessage(tc, _T("Text=%s start=%d end=%d\n"), t.termBuffer(), t.startOffset(), t.endOffset()); + } + int len = t.termLength(); + + //use the lucene strlwr function (so copy to TCHAR first then back) + strncpy(atmp, orig + t.startOffset(), len); + atmp[len] = 0; + STRCPY_AtoT(ttmp, atmp, len + 1); + _tcslwr(ttmp); + + if (_tcsncmp(t.termBuffer(), ttmp, len) != 0) { + TCHAR err[1024]; + _sntprintf(err, 1024, _T("token '%s' didnt match original text at %d-%d"), t.termBuffer(), t.startOffset(), t.endOffset()); + CuAssert(tc, err, false); + } + + // _CLDELETE(t); + count++; + } + + uint64_t end = Misc::currentTimeMillis(); + int64_t time = end - start; + CuMessageA(tc, "%d milliseconds to extract ", time); + CuMessageA(tc, "%d tokens\n", count); + CuMessageA(tc, "%f microseconds/token\n", (time * 1000.0) / count); + CuMessageA(tc, "%f megabytes/hour\n", (bytes * 1000.0 * 60.0 * 60.0) / (time * 1000000.0)); + + _CLDELETE(stream); +} + +void _testFile(CuTest *tc, const char* fname, bool verbose) { + struct fileStat buf; + fileStat(fname, &buf); + int64_t bytes = buf.st_size; + + char* orig = _CL_NEWARRAY(char, bytes); + { + FILE* f = fopen(fname, "rb"); + int64_t r = fread(orig, bytes, 1, f); + fclose(f); + } + + CuMessageA(tc, " Reading test file containing %d bytes.\n", bytes); + jstreams::FileReader fr(fname, "ASCII"); + const TCHAR *start; + size_t total = 0; + int32_t numRead; + do { + numRead = fr.read(start, 1, 0); + if (numRead == -1) + break; + total += numRead; + } while (numRead >= 0); + + jstreams::FileReader reader(fname, "ASCII"); + + test(tc, orig, &reader, verbose, total); + + _CLDELETE_CaARRAY(orig); +} + +void testFile(CuTest *tc) { + char loc[1024]; + strcpy(loc, clucene_data_location); + strcat(loc, "/reuters-21578/feldman-cia-worldfactbook-data.txt"); + CuAssert(tc, _T("reuters-21578/feldman-cia-worldfactbook-data.txt does not exist"), Misc::dir_Exists(loc)); + + _testFile(tc, loc, false); +} + +void _testCJK(CuTest *tc, const char* astr, const char** results, bool ignoreSurrogates = true) { + SimpleInputStreamReader r(new AStringReader(astr), SimpleInputStreamReader::UTF8); + + CJKTokenizer* tokenizer = _CLNEW CJKTokenizer(&r); + tokenizer->setIgnoreSurrogates(ignoreSurrogates); + int pos = 0; + Token tok; + TCHAR tres[LUCENE_MAX_WORD_LEN]; + + while (results[pos] != NULL) { + CLUCENE_ASSERT(tokenizer->next(&tok) != NULL); + + lucene_utf8towcs(tres, results[pos], LUCENE_MAX_WORD_LEN); + CuAssertStrEquals(tc, _T("unexpected token value"), tres, tok.termBuffer()); + + pos++; + } + CLUCENE_ASSERT(!tokenizer->next(&tok)); + + _CLDELETE(tokenizer); +} + +void testCJK(CuTest *tc) { + //utf16 test + //we have a very large unicode character: + //xEFFFF = utf8(F3 AF BF BF) = utf16(DB7F DFFF) = utf8(ED AD BF, ED BF BF) + static const char* exp3[4] = {"\xED\xAD\xBF\xED\xBF\xBF\xe5\x95\xa4", "\xe5\x95\xa4\xED\xAD\xBF\xED\xBF\xBF", "", NULL}; + _testCJK(tc, "\xED\xAD\xBF\xED\xBF\xBF\xe5\x95\xa4\xED\xAD\xBF\xED\xBF\xBF", exp3, false); + + static const char* exp1[5] = {"test", "t\xc3\xbcrm", "values", NULL}; + _testCJK(tc, "test t\xc3\xbcrm values", exp1); + + static const char* exp2[6] = {"a", "\xe5\x95\xa4\xe9\x85\x92", "\xe9\x85\x92\xe5\x95\xa4", "", "x", NULL}; + _testCJK(tc, "a\xe5\x95\xa4\xe9\x85\x92\xe5\x95\xa4x", exp2); +} + +void testLanguageBasedAnalyzer(CuTest* tc) { + LanguageBasedAnalyzer a; + CL_NS(util)::StringReader reader(_T("he abhorred accentueren")); + reader.mark(50); + TokenStream* ts; + Token t; + + //test with english + a.setLanguage(_T("English")); + a.setStem(false); + ts = a.tokenStream(_T("contents"), &reader); + + CLUCENE_ASSERT(ts->next(&t) != NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("he")) == 0); + CLUCENE_ASSERT(ts->next(&t) != NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("abhorred")) == 0); + _CLDELETE(ts); + + //now test with dutch + reader.reset(0); + a.setLanguage(_T("Dutch")); + a.setStem(true); + ts = a.tokenStream(_T("contents"), &reader); + + CLUCENE_ASSERT(ts->next(&t) != NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("he")) == 0); + CLUCENE_ASSERT(ts->next(&t) != NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("abhorred")) == 0); + CLUCENE_ASSERT(ts->next(&t) != NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("accentuer")) == 0); + _CLDELETE(ts); +} + +CuSuite *testanalysis(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Analysis Test")); + + SUITE_ADD_TEST(suite, testFile); + SUITE_ADD_TEST(suite, testCJK); + SUITE_ADD_TEST(suite, testLanguageBasedAnalyzer); + + return suite; +} +// EOF diff --git a/src/contribs/contribs-lib-test/TestHighlight.cpp b/src/contribs/contribs-lib-test/TestHighlight.cpp new file mode 100644 index 00000000000..4a87651ad56 --- /dev/null +++ b/src/contribs/contribs-lib-test/TestHighlight.cpp @@ -0,0 +1,269 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +#include "CLucene/store/RAMDirectory.h" +#include "CLucene/highlighter/QueryTermExtractor.h" +#include "CLucene/highlighter/QueryScorer.h" +#include "CLucene/highlighter/Highlighter.h" +#include "CLucene/highlighter/TokenGroup.h" +#include "CLucene/highlighter/SimpleHTMLFormatter.h" +#include "CLucene/highlighter/SimpleFragmenter.h" + +CL_NS_USE2(search, highlight); + +RAMDirectory hl_ramDir; +StandardAnalyzer hl_analyzer; + + +const TCHAR* hl_FIELD_NAME = _T("contents"); +Query* hl_originalquery = NULL; +Query* hl_query = NULL; +Query* hl_rewrittenquery = NULL; +IndexReader* hl_reader = NULL; +Searcher* hl_searcher = NULL; +Hits* hl_hits = NULL; + +class hl_formatterCls : public Formatter { +public: + int numHighlights; + + hl_formatterCls() { + numHighlights = 0; + } + + ~hl_formatterCls() { + } + + TCHAR* highlightTerm(const TCHAR* originalText, const TokenGroup* group) { + if (group->getTotalScore() <= 0) { + return STRDUP_TtoT(originalText); + } + numHighlights++; //update stats used in assertions + + int len = _tcslen(originalText) + 7; + TCHAR* ret = _CL_NEWARRAY(TCHAR, len + 1); + _tcscpy(ret, _T("")); + _tcscat(ret, originalText); + _tcscat(ret, _T("")); + + return ret; + } +}; +hl_formatterCls hl_formatter; + + +const TCHAR* hl_texts[6] ={ + _T("Hello this is a piece of text that is very long and contains too much preamble and the meat is really here which says kennedy has been shot"), + _T("This piece of text refers to Kennedy at the beginning then has a longer piece of text that is very long in the middle and finally ends with another reference to Kennedy"), + _T("JFK has been shot"), + _T("John Kennedy has been shot"), + _T("This text has a typo in referring to Keneddy"), + NULL +}; + +void doStandardHighlights(CuTest* tc) { + QueryScorer scorer(hl_query); + Highlighter highlighter(&hl_formatter, &scorer); + SimpleFragmenter frag(20); + highlighter.setTextFragmenter(&frag); + + for (int i = 0; i < hl_hits->length(); i++) { + const TCHAR* text = hl_hits->doc(i).get(hl_FIELD_NAME); + int maxNumFragmentsRequired = 2; + const TCHAR* fragmentSeparator = _T("..."); + StringReader reader(text); + TokenStream* tokenStream = hl_analyzer.tokenStream(hl_FIELD_NAME, &reader); + + TCHAR* result = + highlighter.getBestFragments( + tokenStream, + text, + maxNumFragmentsRequired, + fragmentSeparator); + + CuMessage(tc, _T("%s\n"), result == NULL ? _T("") : result); + _CLDELETE_CARRAY(result); + _CLDELETE(tokenStream); + } +} + +void doSearching(CuTest* tc, const TCHAR* queryString) { + if (hl_searcher == NULL) + hl_searcher = _CLNEW IndexSearcher(&hl_ramDir); + + if (hl_rewrittenquery != NULL && hl_originalquery != NULL) { + if (hl_originalquery != hl_rewrittenquery) + _CLDELETE(hl_rewrittenquery); + _CLDELETE(hl_originalquery); + } + hl_originalquery = QueryParser::parse(queryString, hl_FIELD_NAME, &hl_analyzer); + + //for any multi-term queries to work (prefix, wildcard, range,fuzzy etc) you must use a rewritten query! + hl_rewrittenquery = hl_originalquery->rewrite(hl_reader); + hl_query = hl_rewrittenquery; + + TCHAR* s = hl_originalquery->toString(hl_FIELD_NAME); + CuMessage(tc, _T("Searching for: %s\n"), s == NULL ? _T("") : s); + _CLDELETE_CARRAY(s); + + s = hl_rewrittenquery->toString(hl_FIELD_NAME); + CuMessage(tc, _T("Rewritten query: %s\n"), s == NULL ? _T("") : s); + _CLDELETE_CARRAY(s); + + if (hl_hits != NULL) + _CLDELETE(hl_hits); + hl_hits = hl_searcher->search(hl_query); + hl_formatter.numHighlights = 0; +} + +void testSimpleHighlighter(CuTest *tc) { + doSearching(tc, _T("Kennedy")); + QueryScorer scorer(hl_query); + Highlighter highlighter(&scorer); + SimpleFragmenter fragmenter(40); + + highlighter.setTextFragmenter(&fragmenter); + int maxNumFragmentsRequired = 2; + for (int i = 0; i < hl_hits->length(); i++) { + const TCHAR* text = hl_hits->doc(i).get(hl_FIELD_NAME); + StringReader reader(text); + TokenStream* tokenStream = hl_analyzer.tokenStream(hl_FIELD_NAME, &reader); + + TCHAR* result = highlighter.getBestFragments(tokenStream, text, maxNumFragmentsRequired, _T("...")); + CuMessage(tc, _T("%s\n"), result == NULL ? _T("") : result); + _CLDELETE_CARRAY(result); + _CLDELETE(tokenStream); + } + //Not sure we can assert anything here - just running to check we dont throw any exceptions +} + +void testGetFuzzyFragments(CuTest *tc) { + doSearching(tc, _T("Kinnedy~")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 5); +} + +void testGetWildCardFragments(CuTest *tc) { + doSearching(tc, _T("K?nnedy")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 4); +} + +void testGetBestFragmentsSimpleQuery(CuTest *tc) { + doSearching(tc, _T("Kennedy")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 4); +} + +void testGetMidWildCardFragments(CuTest *tc) { + doSearching(tc, _T("K*dy")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 5); +} + +void testGetBestFragmentsPhrase(CuTest *tc) { + doSearching(tc, _T("\"John Kennedy\"")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 2); +} + +void testGetBestFragmentsMultiTerm(CuTest *tc) { + doSearching(tc, _T("John Ken*")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 6); +} + +void testGetBestFragmentsWithOr(CuTest *tc) { + doSearching(tc, _T("JFK OR Kennedy")); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 5); +} + +void testGetRangeFragments(CuTest *tc) { + TCHAR qry[200]; + _sntprintf(qry, 200, _T("%s:[Kannedy TO Kznnedy]"), hl_FIELD_NAME); //bug?needs lower case + + doSearching(tc, qry); + doStandardHighlights(tc); + + TCHAR msg[1024]; + _sntprintf(msg, 1024, _T("Failed to find correct number of highlights %d found"), hl_formatter.numHighlights); + CuAssert(tc, msg, hl_formatter.numHighlights == 5); +} + +void setupHighlighter(CuTest *tc) { + IndexWriter writer(&hl_ramDir, &hl_analyzer, true); + for (int i = 0; hl_texts[i] != NULL; i++) { + Document d; + d.add(*_CLNEW Field(hl_FIELD_NAME, hl_texts[i], Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer.addDocument(&d); + } + + writer.optimize(); + writer.close(); + + hl_reader = IndexReader::open(&hl_ramDir); +} + +void cleanupHighlighter(CuTest *tc) { + + if (hl_originalquery != hl_rewrittenquery) + _CLDELETE(hl_rewrittenquery); + _CLDELETE(hl_originalquery); + _CLDELETE(hl_hits); + + if (hl_reader != NULL) { + hl_reader->close(); + _CLDELETE(hl_reader); + } + hl_ramDir.close(); + + if (hl_searcher != NULL) + _CLDELETE(hl_searcher); +} + +CuSuite *testhighlighter(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Highlight Test")); + + SUITE_ADD_TEST(suite, setupHighlighter); + + SUITE_ADD_TEST(suite, testSimpleHighlighter); + SUITE_ADD_TEST(suite, testGetBestFragmentsSimpleQuery); + SUITE_ADD_TEST(suite, testGetFuzzyFragments); + SUITE_ADD_TEST(suite, testGetWildCardFragments); + SUITE_ADD_TEST(suite, testGetMidWildCardFragments); + SUITE_ADD_TEST(suite, testGetRangeFragments); + SUITE_ADD_TEST(suite, testGetBestFragmentsPhrase); + SUITE_ADD_TEST(suite, testGetBestFragmentsMultiTerm); + SUITE_ADD_TEST(suite, testGetBestFragmentsWithOr); + + + SUITE_ADD_TEST(suite, cleanupHighlighter); + return suite; +} diff --git a/src/contribs/contribs-lib-test/TestSnowball.cpp b/src/contribs/contribs-lib-test/TestSnowball.cpp new file mode 100644 index 00000000000..6f53dbda000 --- /dev/null +++ b/src/contribs/contribs-lib-test/TestSnowball.cpp @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +#include "CLucene/snowball/SnowballAnalyzer.h" + +CL_NS_USE2(analysis, snowball); + +void testSnowball(CuTest *tc) { + SnowballAnalyzer an(_T("English")); + CL_NS(util)::StringReader reader(_T("he abhorred accents")); + + TokenStream* ts = an.tokenStream(_T("test"), &reader); + Token t; + CLUCENE_ASSERT(ts->next(&t)!=NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("he")) == 0); + CLUCENE_ASSERT(ts->next(&t)!=NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("abhor")) == 0); + CLUCENE_ASSERT(ts->next(&t)!=NULL); + CLUCENE_ASSERT(_tcscmp(t.termBuffer(), _T("accent")) == 0); + + CLUCENE_ASSERT(ts->next(&t) == NULL); + _CLDELETE(ts); +} + +CuSuite *testsnowball(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Snowball Test")); + + SUITE_ADD_TEST(suite, testSnowball); + + return suite; +} diff --git a/src/contribs/contribs-lib-test/TestStreams.cpp b/src/contribs/contribs-lib-test/TestStreams.cpp new file mode 100644 index 00000000000..772b4c33396 --- /dev/null +++ b/src/contribs/contribs-lib-test/TestStreams.cpp @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/util/gzipcompressstream.h" +#include "CLucene/util/gzipinputstream.h" +#include "CLucene/util/byteinputstream.h" +#include "CLucene/util/streamarray.h" +//#include "CLucene/util/_streambase.h" + +CL_NS_USE(store); +CL_NS_USE(util); + +void setupStreams(CuTest *tc) { +} + +void cleanupStreams(CuTest *tc) { +} + +void testDocument(CuTest* tc) { + //test adding a binary field to the index + RAMDirectory ram; + const signed char* tmp = 0; + const char* str2 = "we all love compressed fields"; + + { + SimpleAnalyzer an; + IndexWriter writer(&ram, &an, true); + Document doc2; + AStringReader stringReader2(str2); + GZipCompressInputStream* zipStream; + zipStream = new GZipCompressInputStream(&stringReader2); + + ValueArray stored = streamArray(zipStream); + doc2.add(*new Field(_T("test"), reinterpret_cast*>(&stored), Field::STORE_YES)); + writer.addDocument(&doc2); + + //done + writer.close(); + } + + //now read it back... + IndexReader* reader = IndexReader::open(&ram); + Document doc2; + CLUCENE_ASSERT(reader->document(0, doc2)); + ByteInputStream sb2(reinterpret_cast const*>(doc2.getField(_T("test"))->binaryValue())); + GZipInputStream zip2(&sb2, GZipInputStream::ZLIBFORMAT); + + int rd = zip2.read(tmp, 100000, 0); + std::string str((const char*) tmp, rd); + CLUCENE_ASSERT(str.compare(str2) == 0); + + _CLDELETE(reader); +} + +CuSuite *teststreams(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Streams Test")); + + //SUITE_ADD_TEST(suite, setupStreams); + SUITE_ADD_TEST(suite, testDocument); + //SUITE_ADD_TEST(suite, cleanupStreams); + return suite; +} diff --git a/src/contribs/contribs-lib-test/TestUtf8.cpp b/src/contribs/contribs-lib-test/TestUtf8.cpp new file mode 100644 index 00000000000..4ace699f147 --- /dev/null +++ b/src/contribs/contribs-lib-test/TestUtf8.cpp @@ -0,0 +1,189 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/util/dirent.h" +#include "CLucene/util/CLStreams.h" + +//this is basically a copy of the TestUtf8 located in the core, except using the iconv InputStreamReader... + +#ifdef _UCS2 + void _Index(CuTest *tc, IndexWriter* ndx, const char* file){ + char path[CL_MAX_PATH]; + TCHAR tlang[20]; + + strcpy(path,clucene_data_location); + strcat(path,"/utf8text"); + CuAssert(tc,_T("Utf8 directory does not exist"),Misc::dir_Exists(path)); + strcat(path,"/"); + strcat(path,file); + strcat(path,"_utf8.txt"); + CuAssert(tc,_T("Language file does not exist"),Misc::dir_Exists(path)); + + STRCPY_AtoT(tlang,file,CL_MAX_PATH); + + Document doc; + doc.add(*_CLNEW Field(_T("language"),tlang, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + + jstreams::FileReader* fr = new jstreams::FileReader(path, "UTF-8"); + doc.add(*_CLNEW Field(_T("contents"),fr, Field::STORE_YES | Field::INDEX_TOKENIZED )); + ndx->addDocument(&doc); + } + void _Search(CuTest *tc, IndexSearcher* srch, Analyzer* analyzer, const char* file, const char* query){ + TCHAR tlang[20]; + STRCPY_AtoT(tlang,file,CL_MAX_PATH); + + TCHAR tquery[80]; + lucene_utf8towcs(tquery,query,80); + + Query* q = QueryParser::parse(tquery,_T("contents"), analyzer); + Hits* h = srch->search(q); + CLUCENE_ASSERT( h->length() == 1 ); + + Document& doc = h->doc(0); + CLUCENE_ASSERT( _tcscmp(doc.get(_T("language")), tlang)==0 ); + + _CLDELETE(q); + _CLDELETE(h); + } + + void testUTF8(CuTest *tc) { + RAMDirectory ram; + Directory* pram = &ram; + SimpleAnalyzer a; + IndexWriter ndx(&ram,&a,true); + _Index(tc, &ndx,"arabic"); + _Index(tc, &ndx,"chinese"); + _Index(tc, &ndx,"czech"); + _Index(tc, &ndx,"english"); + _Index(tc, &ndx,"french"); + _Index(tc, &ndx,"german"); + _Index(tc, &ndx,"greek"); + _Index(tc, &ndx,"hebrew"); + _Index(tc, &ndx,"japanese"); + _Index(tc, &ndx,"korean"); + _Index(tc, &ndx,"polish"); + _Index(tc, &ndx,"russian"); + ndx.close(); + + IndexSearcher srch(&ram); + _Search(tc,&srch,&a,"arabic", "\xef\xbb\x9e\xef\xbb\xb4\xef\xbb\xa4\xef\xbb\xb3\xef\xba\xad"); //????? - arabic + _Search(tc,&srch,&a,"chinese", "\xe5\x95\xa4\xe9\x85\x92"); //?? - chinese + _Search(tc,&srch,&a,"czech", "Bud\xc4\x9bjovick\xc3\xbd" ); //Budejovick� - czech + + _Search(tc,&srch,&a,"english", "google"); //English - google + _Search(tc,&srch,&a,"french", "r\xc3\xa9put\xc3\xa9"); //r�put� - french + _Search(tc,&srch,&a,"german", "k\xc3\xb6nnen"); //k�nnen - german + _Search(tc,&srch,&a,"greek", "\xcf\x83\xcf\x84\xce\xb5\xce\xaf\xce\xbb\xcf\x84\xce\xb5"); //ste??te - greek + _Search(tc,&srch,&a,"hebrew", "\xd7\x91\xd7\x90\xd7\xa8\xd7\xa6\xd7\x95\xd7\xaa" ); //?????? - hebrew + _Search(tc,&srch,&a,"japanese", "\xe8\xa6\x8b\xe5\xad\xa6" ); //?? - japanese + _Search(tc,&srch,&a,"korean", "\xea\xb8\x88" ); //? - korean + _Search(tc,&srch,&a,"polish", "sp\xc3\xb3\xc5\x82ka"); ;//sp�lka - polish + _Search(tc,&srch,&a,"russian", "\xd0\x92\xd0\xb5\xd0\xbb\xd0\xb8\xd0\xba\xd0\xb8\xd0\xb5\x20"); //??????? - russian + + srch.close(); + } + + void readBuffered(CuTest* tc, Reader& utf8, Reader& unicode, int readLen){ + const TCHAR* buf1; + const TCHAR* buf2; + int32_t s; + size_t p, p1, p2; + p = p1 = p2 = 0; + while(true){ + s = utf8.read(buf1, readLen, readLen); + if ( s == -1 ) + break; + p1+=s; + + s = unicode.read(buf2, readLen, readLen); + if (s == -1) + break; + p2+=s; + + CLUCENE_ASSERT(p1==p2); //make sure both readers read the same amount. todo: i guess this is not strictly required... + for ( int32_t i=0;i +#include +#endif +#endif + +#include "test.h" +#include + +#include +#ifdef _CL_HAVE_DIRECT_H +#include +#endif +#ifdef _CL_HAVE_SYS_STAT_H +#include +#endif +#ifdef _CL_HAVE_IO_H +#include +#endif + +const char* cl_tempDir; +bool cl_quiet; +char clucene_data_location[1024]; + +int main(int argc, char *argv[]) { +#ifdef _MSC_VER +#ifdef _DEBUG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); //| _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); + _crtBreakAlloc = -1; +#endif +#endif + int ret_result = 0; + int i = 0; + int exclude = 0; + int list_provided = 0; + CuSuiteList *alltests = NULL; + CuString *output = CuStringNew(); + bool silent = false; + bool verbose = false; + bool times = true; + uint64_t startTime = 0; + + cl_tempDir = NULL; + if (Misc::dir_Exists("/tmp")) + cl_tempDir = "/tmp"; + if (getenv("TEMP") != NULL) + cl_tempDir = getenv("TEMP"); + else if (getenv("TMP") != NULL) + cl_tempDir = getenv("TMP"); + + char* tmp = _CL_NEWARRAY(char, strlen(cl_tempDir) + 9); + strcpy(tmp, cl_tempDir); + strcat(tmp, "/clucene"); + _mkdir(tmp); + if (Misc::dir_Exists(tmp)) + cl_tempDir = tmp; + + clucene_data_location[0] = 0; + if (CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION1 "/reuters-21578-index/segments")) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION1); + else if (CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION2 "/reuters-21578-index/segments")) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION2); + else if (CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION3 "/reuters-21578-index/segments")) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION3); + else if (getenv(CLUCENE_DATA_LOCATIONENV) != NULL) { + strcpy(clucene_data_location, getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location, "/data/reuters-21578-index/segments"); + if (CL_NS(util)::Misc::dir_Exists(clucene_data_location)) { + strcpy(clucene_data_location, getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location, "/data"); + } else + clucene_data_location[0] = 0; + } + + /* first check that we are running the test for the correct position */ + //todo: make this configurable + if (!*clucene_data_location) { + fprintf(stderr, "%s must be run from a subdirectory of the application's root directory\n", argv[0]); + fprintf(stderr, "ensure that the test data exists in %s or %s or %s\n", CLUCENE_DATA_LOCATION1, CLUCENE_DATA_LOCATION2, CLUCENE_DATA_LOCATION3); + if (getenv(CLUCENE_DATA_LOCATIONENV) != NULL) + fprintf(stderr, "%s/data was also checked because of the " CLUCENE_DATA_LOCATIONENV " environment variable", getenv(CLUCENE_DATA_LOCATIONENV)); + ret_result = 1; + goto exit_point; + } + + CuInit(argc, argv); + + /* see if we're in exclude mode, see if list of testcases provided */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help") || !strcmp(argv[i], "/?")) { + printf("%s [-l list] [-q quiet] [-v verbose] [-t show times] [-p printf messages immediatelly] [-x exclude] [tests...]\n", argv[0]); + goto exit_point; + } + if (!strcmp(argv[i], "-v")) { + verbose = true; + continue; + } + if (!strcmp(argv[i], "-p")) { //used in CuInit + continue; + } + if (!strcmp(argv[i], "-q")) { + silent = true; + continue; + } + if (!strcmp(argv[i], "-x")) { + exclude = 1; + continue; + } + if (!strcmp(argv[i], "-t")) { + times = true; + continue; + } + if (!strcmp(argv[i], "-l")) { + for (i = 0; tests[i].func != NULL; i++) { + printf("%s\n", tests[i].testname); + } + ret_result = 0; + goto exit_point; + } + if (argv[i][0] == '-') { + fprintf(stderr, "invalid option: `%s'\n", argv[i]); + ret_result = 1; + goto exit_point; + } + list_provided = 1; + } + + if (!list_provided) { + /* add everything */ + alltests = CuSuiteListNew(_T("All CLucene Tests")); + for (i = 0; tests[i].func != NULL; i++) { + CuSuiteListAdd(alltests, tests[i].func()); + } + } else if (exclude) { + /* add everything but the tests listed */ + alltests = CuSuiteListNew(_T("Partial CLucene Tests")); + for (i = 0; tests[i].func != NULL; i++) { + int this_test_excluded = 0; + int j; + + for (j = 1; j < argc && !this_test_excluded; j++) { + if (!strcmp(argv[j], tests[i].testname)) { + this_test_excluded = 1; + } + } + if (!this_test_excluded) { + CuSuiteListAdd(alltests, tests[i].func()); + } + } + } else { + /* add only the tests listed */ + alltests = CuSuiteListNew(_T("Partial CLucene Tests")); + for (i = 1; i < argc; i++) { + int j; + int found = 0; + + if (argv[i][0] == '-') { + continue; + } + for (j = 0; tests[j].func != NULL; j++) { + if (!strcmp(argv[i], tests[j].testname)) { + CuSuiteListAdd(alltests, tests[j].func()); + found = 1; + } + } + if (!found) { + fprintf(stderr, "invalid test name: `%s'\n", argv[i]); + ret_result = 1; + goto exit_point; + } + } + } + + startTime = Misc::currentTimeMillis(); + + printf("Key: .= pass N=not implemented F=fail\n"); + if (silent) + CuSuiteListRun(alltests); + else + CuSuiteListRunWithSummary(alltests, verbose, times); + i = CuSuiteListDetails(alltests, output); + _tprintf(_T("%s\n"), output->buffer); + + if (times) + printf("Tests run in %dms\n\n", (int32_t) (CL_NS(util)::Misc::currentTimeMillis() - startTime)); + +exit_point: + if (alltests != NULL) + CuSuiteListDelete(alltests); + CuStringFree(output); + _CLDELETE_LCaARRAY(const_cast(cl_tempDir)); + cl_tempDir = NULL; + + _lucene_shutdown(); //clears all static memory + //print lucenebase debug + + if (ret_result != 0) + return ret_result; + else + return i > 0 ? 1 : 0; + + //Debuggin techniques: + //For msvc, use this for breaking on memory leaks: + // _crtBreakAlloc + //for linux, use valgrind +} + diff --git a/src/core/CLucene.h b/src/core/CLucene.h new file mode 100644 index 00000000000..d0c654d1bf1 --- /dev/null +++ b/src/core/CLucene.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +//Includes some standard headers for searching and indexing. +#ifndef _lucene_CLucene_ +#define _lucene_CLucene_ + +#include "CLucene/StdHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/IndexWriter.h" +#include "CLucene/index/MultiReader.h" +#include "CLucene/index/Term.h" +#include "CLucene/search/IndexSearcher.h" +#include "CLucene/search/MultiSearcher.h" +#include "CLucene/search/DateFilter.h" +#include "CLucene/search/WildcardQuery.h" +#include "CLucene/search/FuzzyQuery.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/search/PrefixQuery.h" +#include "CLucene/search/RangeQuery.h" +#include "CLucene/search/BooleanQuery.h" +#include "CLucene/search/TermQuery.h" +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/search/Sort.h" +#include "CLucene/search/Hits.h" +#include "CLucene/search/Explanation.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "CLucene/document/DateField.h" +#include "CLucene/document/DateTools.h" +#include "CLucene/document/NumberTools.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/store/RAMDirectory.h" +//#include "CLucene/queryParser/QueryParser.h" +#include "CLucene/queryParser/QueryParser.h" +#include "CLucene/analysis/standard/StandardAnalyzer.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/PriorityQueue.h" +#include "CLucene/util/Misc.h" + +#endif diff --git a/src/core/CLucene/CLConfig.h b/src/core/CLucene/CLConfig.h new file mode 100644 index 00000000000..eca5dc5e1db --- /dev/null +++ b/src/core/CLucene/CLConfig.h @@ -0,0 +1,236 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_Config_ +#define _lucene_Config_ + + +//////////////////////////////////////////////////////////////////// +// this settings should be set up in the compiler, +// but are put here for reference as to what could be defined +//////////////////////////////////////////////////////////////////// +// +//define this if you want debugging code to be enabled +//#define _DEBUG +// +//define this if you want condition debugging to be enabled +#if defined(_DEBUG) && !defined(_CL__CND_DEBUG) + #define _CL__CND_DEBUG +#endif +// +//define this to print out lots of information about merges, etc +//requires __CL__CND_DEBUG to be defined +//#define _CL_DEBUG_INFO stdout +// +//to disable namespaces define this +//#define DISABLE_NAMESPACE +// +//disable hashmap/set usage. Just use map and set. +//this has been shown to be quicker than the hash equivalents in some impementations +#ifndef LUCENE_DISABLE_HASHING + #define LUCENE_DISABLE_HASHING +#endif +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// These options can be set depending on the particular needs of +// Your application +//////////////////////////////////////////////////////////////////// +// +//define this to enable mmap support in the fsdirectory IndexInput +//EXPERIMENTAL +//#define LUCENE_FS_MMAP +// +//define to true to actually use it (not just enable it) +#ifdef LUCENE_FS_MMAP + #define LUCENE_USE_MMAP true //yes, use if it's turned on. +#else + #define LUCENE_USE_MMAP false +#endif +// +//LOCK_DIR implementation: +//define this to set an exact directory for the lock dir (not recommended) +//all other methods of getting the temporary directory will be ignored +//#define LUCENE_LOCK_DIR "/tmp" +// +//define this to try and load the lock dir from this specified environment variable +#define LUCENE_LOCK_DIR_ENV_1 "TEMP" +//define this if you want to have look up this environment variable if the first one fails +#define LUCENE_LOCK_DIR_ENV_2 "TMP" +//define this if you want to have a fallback directory, if not defined then +//the lockdirectory will be the index directory +#define LUCENE_LOCK_DIR_ENV_FALLBACK "/tmp" +// +//////////////////////////////////////////////////////////////////// + + +//This must always be defined. They can be adjusted if required. But +//general Wildcard string would be '*' and Wildcard Char would be '?' +//Both are Required. +#define LUCENE_WILDCARDTERMENUM_WILDCARD_STRING '*' +#define LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR '?' +// +//////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////// +// memory handling configurations +//////////////////////////////////////////////////////////////////// +// +/*** +* If this is defined, lucene's configurations are changed +* to use less memory, but may run slower. +* todo: i dont think this actualy changes speed much, just memory +*/ +#define LUCENE_OPTIMIZE_FOR_MEMORY + +// +//enable this if you want to enable reference counting. This is +//not necessary or useful in most cases except when implementing wrappers +//which have reference counting. If the wrapper wraps a StringReader, +//for example, it should expect that the wrapped StringReader should not +//be deleted. However, when the stringreader is added into a Field, +//the Field usually takes over the stringReader and deletes it on completion. +//If reference counting is enabled, the wrapper can add a reference to any class +//and when _CLDECDELETE is called, the reference is decremented and only deleted +//if the refcount is zero. +//#define LUCENE_ENABLE_REFCOUNT + + +//////////////////////////////////////////////////////////////////// +// These options allow you to remove certain implementations +// out of clucene so that they can be implemented in the client +// application +//////////////////////////////////////////////////////////////////// +// +//define this if you want to implement the _Cnd_OutDebug routine yourself +//you can then easily customise in your own application how to handle debug messages +//#define _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// These options should not be changed. But you can experiment with +// them to optimize performance +//////////////////////////////////////////////////////////////////// +// +//some defaults, wouldn't usually need to be changed +//Buffer size for input/output streams. Required. +#define LUCENE_STREAM_BUFFER_SIZE 1024 +// +// DSR:2004.08.19: +// Formerly, StringBuffer used 1024 as the default size of its internal buffer. +// However, StringBuffer is used primarily for token- and term-oriented +// processing, e.g. in StandardTokenizer. I've calculated that the average +// token (as produced by StandardTokenizer) in all .txt files distributed in +// the Project Gutenberg CD Image (August 2003 release) has only 6 characters. +// Although most languages are likely to have a longer average word length than +// English due to the popularity of "non-atomized" conjugation and declension +// mechanisms, 1024 is still vastly excessive. +// I made two changes intended to deliver better overall performance: +// a) Switched to a default StringBuffer character capacity of 32. Though 32 +// is longer than the average token, the high cost of realloc makes a +// slightly liberal default size optimal. I chose the default size of 32 +// after fairly extensive experimentation on the Gutenberg e-texts. The +// results are summarized in the following table: +// ------------------------------------------------------------------------ +// LUCENE_DEFAULT_TOKEN_BUFFER_SIZE value | % faster than default size 1024 +// ------------------------------------------------------------------------ +// 8 : 4% +// 16 : 7% +// 32 : 6% +// 64 : 3% +// A default size of 32 is actually slightly slower than 16, but I was +// experimenting on English text; I expect that 32 will maintain decent +// performance in languages such as German, and in technical documents +// with long tokens. +// +// b) To offset the switch to a smaller default buffer size, I implemented a +// more aggressive growth strategy. A StringBuffer now [at least] doubles +// the size of its internal buffer every time it needs to grow, rather +// than [at least] increasing by LUCENE_DEFAULT_TOKEN_BUFFER_SIZE no +// matter how many times it has already grown. +//Required. +#define LUCENE_DEFAULT_TOKEN_BUFFER_SIZE 32 +//todo: should implement a similar strategy in analysis/token +// +//Size of TermScore cache. Required. +#define LUCENE_SCORE_CACHE_SIZE 512 +// +//analysis options +//maximum length that the CharTokenizer uses. Required. +//By adjusting this value, you can greatly improve the performance of searching +//and especially indexing. Default is 255, but smaller numbers will decrease +//the amount of memory used as well as increasing the speed. +#define LUCENE_MAX_WORD_LEN 255 +//Maximum length of a token word. +//Should be the same or more than LUCENE_MAX_WORD_LEN +//if not defined, then no token limit, but may be slower +//if defined will be faster (up to 15% in some cases), but will use more memory +#ifndef LUCENE_OPTIMIZE_FOR_MEMORY + #define LUCENE_TOKEN_WORD_LENGTH LUCENE_MAX_WORD_LEN +#endif +// +//maximum field length. some optimisation can be done if a maximum field +//length is given... The smaller the better +#define LUCENE_MAX_FIELD_LEN 100 +// +//The initial value set to BooleanQuery::maxClauseCount. Default is 1024 +#define LUCENE_BOOLEANQUERY_MAXCLAUSECOUNT 1024 +// +//bvk: 12.3.2005 +//============================================================================== +//Previously the way the tokenizer has worked has been changed to optionally +//use a a fixed word length. I have implemented this in the Term class as well. +//It seems that by predefining the text length instead of using new TCHAR[x] +//in the constructor greatly improves the performance by 20-30% for certain +//operations. +//Maximum length of a term text. +//Should be the same or more than LUCENE_MAX_WORD_LEN +//if not defined, then no term text limit, but may be slower +//if defined will be faster (up to 30% in some cases), but will use more memory +#ifndef LUCENE_OPTIMIZE_FOR_MEMORY + #define LUCENE_TERM_TEXT_LENGTH LUCENE_MAX_WORD_LEN +#endif +// +//Size of the CharTokenizer buffersize. Required. +#define LUCENE_IO_BUFFER_SIZE 1024 +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Date conversion settings for DateTools and DateField +//////////////////////////////////////////////////////////////////// +// +// DateField, which is now deprecated, had it's buffer size +// defined for 9 chars. DateTools currently is configured +// for 30 chars, but this needs to be revised after tests +// are written for those. +// +#define DATETOOLS_BUFFER_SIZE 30 +#define DATEFIELD_DATE_LEN DATETOOLS_BUFFER_SIZE +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// FuzzyQuery settings +//////////////////////////////////////////////////////////////////// +// +// This should be somewhere around the average long word. +// If it is longer, we waste time and space. If it is shorter, we waste a +// little bit of time growing the array as we encounter longer words. +// +#define LUCENE_TYPICAL_LONGEST_WORD_IN_INDEX 19 +// +//////////////////////////////////////////////////////////////////// + +#define PFOR_BLOCK_SIZE 512 + +#endif + diff --git a/src/core/CLucene/CLMonolithic.cpp b/src/core/CLucene/CLMonolithic.cpp new file mode 100644 index 00000000000..357de696e1e --- /dev/null +++ b/src/core/CLucene/CLMonolithic.cpp @@ -0,0 +1,137 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +/* +* this is a monolithic file that can be used to compile clucene using one source file. +* it simplifies some build processes by avoiding static & dynamic compalation pitfalls. +* +* note: when creating a project add either this file, or all the other .cpp files, not both! +*/ +#include "CLucene/StdHeader.cpp" +#include "CLucene/debug/error.cpp" +#include "CLucene/analysis/Analyzers.cpp" +#include "CLucene/analysis/AnalysisHeader.cpp" +#include "CLucene/analysis/standard/StandardAnalyzer.cpp" +#include "CLucene/analysis/standard/StandardFilter.cpp" +#include "CLucene/analysis/standard/StandardTokenizer.cpp" +#include "CLucene/document/DateField.cpp" +#include "CLucene/document/DateTools.cpp" +#include "CLucene/document/Document.cpp" +#include "CLucene/document/FieldSelector.cpp" +#include "CLucene/document/NumberTools.cpp" +#include "CLucene/document/Field.cpp" +#include "CLucene/index/CompoundFile.cpp" +#include "CLucene/index/DirectoryIndexReader.cpp" +#include "CLucene/index/DocumentsWriter.cpp" +#include "CLucene/index/DocumentsWriterThreadState.cpp" +#include "CLucene/index/FieldInfos.cpp" +#include "CLucene/index/FieldsReader.cpp" +#include "CLucene/index/FieldsWriter.cpp" +#include "CLucene/index/IndexDeletionPolicy.cpp" +#include "CLucene/index/IndexFileDeleter.cpp" +#include "CLucene/index/IndexFileNameFilter.cpp" +#include "CLucene/index/IndexFileNames.cpp" +#include "CLucene/index/IndexModifier.cpp" +#include "CLucene/index/IndexWriter.cpp" +#include "CLucene/index/IndexReader.cpp" +#include "CLucene/index/MergePolicy.cpp" +#include "CLucene/index/MergeScheduler.cpp" +#include "CLucene/index/MultipleTermPositions.cpp" +#include "CLucene/index/MultiReader.cpp" +#include "CLucene/index/MultiSegmentReader.cpp" +#include "CLucene/index/Payload.cpp" +#include "CLucene/index/SegmentInfos.cpp" +#include "CLucene/index/SegmentMergeInfo.cpp" +#include "CLucene/index/SegmentMergeQueue.cpp" +#include "CLucene/index/SegmentMerger.cpp" +#include "CLucene/index/SegmentReader.cpp" +#include "CLucene/index/SegmentTermDocs.cpp" +#include "CLucene/index/SegmentTermEnum.cpp" +#include "CLucene/index/SegmentTermPositions.cpp" +#include "CLucene/index/SegmentTermVector.cpp" +#include "CLucene/index/SkipListReader.cpp" +#include "CLucene/index/SkipListWriter.cpp" +#include "CLucene/index/Term.cpp" +#include "CLucene/index/Terms.cpp" +#include "CLucene/index/TermInfo.cpp" +#include "CLucene/index/TermInfosReader.cpp" +#include "CLucene/index/TermInfosWriter.cpp" +#include "CLucene/index/TermVectorReader.cpp" +#include "CLucene/index/TermVectorWriter.cpp" +#include "CLucene/queryParser/FastCharStream.cpp" +#include "CLucene/queryParser/QueryParserTokenManager.cpp" +#include "CLucene/queryParser/MultiFieldQueryParser.cpp" +#include "CLucene/queryParser/QueryParser.cpp" +#include "CLucene/queryParser/QueryToken.cpp" +#include "CLucene/search/BooleanQuery.cpp" +#include "CLucene/search/BooleanScorer.cpp" +#include "CLucene/search/BooleanScorer2.cpp" +#include "CLucene/search/CachingWrapperFilter.cpp" +#include "CLucene/search/ChainedFilter.cpp" +#include "CLucene/search/Compare.cpp" +#include "CLucene/search/ConstantScoreQuery.cpp" +#include "CLucene/search/DateFilter.cpp" +#include "CLucene/search/ConjunctionScorer.cpp" +#include "CLucene/search/DisjunctionSumScorer.cpp" +#include "CLucene/search/ExactPhraseScorer.cpp" +#include "CLucene/search/Explanation.cpp" +#include "CLucene/search/FieldCache.cpp" +#include "CLucene/search/FieldCacheImpl.cpp" +#include "CLucene/search/FieldDocSortedHitQueue.cpp" +#include "CLucene/search/FieldSortedHitQueue.cpp" +#include "CLucene/search/FilteredTermEnum.cpp" +#include "CLucene/search/FuzzyQuery.cpp" +#include "CLucene/search/Hits.cpp" +#include "CLucene/search/HitQueue.cpp" +#include "CLucene/search/IndexSearcher.cpp" +#include "CLucene/search/MatchAllDocsQuery.cpp" +#include "CLucene/search/MultiPhraseQuery.cpp" +#include "CLucene/search/MultiSearcher.cpp" +#include "CLucene/search/MultiTermQuery.cpp" +#include "CLucene/search/PhrasePositions.cpp" +#include "CLucene/search/PhraseQuery.cpp" +#include "CLucene/search/PhraseScorer.cpp" +#include "CLucene/search/PrefixQuery.cpp" +#include "CLucene/search/QueryFilter.cpp" +#include "CLucene/search/RangeQuery.cpp" +#include "CLucene/search/RangeFilter.cpp" +#include "CLucene/search/SearchHeader.cpp" +#include "CLucene/search/Similarity.cpp" +#include "CLucene/search/SloppyPhraseScorer.cpp" +#include "CLucene/search/Scorer.cpp" +#include "CLucene/search/ScorerDocQueue.cpp" +#include "CLucene/search/Sort.cpp" +#include "CLucene/search/TermQuery.cpp" +#include "CLucene/search/TermScorer.cpp" +#include "CLucene/search/WildcardQuery.cpp" +#include "CLucene/search/WildcardTermEnum.cpp" +#include "CLucene/search/spans/NearSpansOrdered.cpp" +#include "CLucene/search/spans/NearSpansUnordered.cpp" +#include "CLucene/search/spans/SpanFirstQuery.cpp" +#include "CLucene/search/spans/SpanNearQuery.cpp" +#include "CLucene/search/spans/SpanNotQuery.cpp" +#include "CLucene/search/spans/SpanOrQuery.cpp" +#include "CLucene/search/spans/SpanScorer.cpp" +#include "CLucene/search/spans/SpanTermQuery.cpp" +#include "CLucene/search/spans/SpanWeight.cpp" +#include "CLucene/search/spans/TermSpans.cpp" +#include "CLucene/store/FSDirectory.cpp" +#include "CLucene/store/IndexInput.cpp" +#include "CLucene/store/Lock.cpp" +#include "CLucene/store/LockFactory.cpp" +#include "CLucene/store/MMapInput.cpp" +#include "CLucene/store/IndexOutput.cpp" +#include "CLucene/store/Directory.cpp" +#include "CLucene/store/RAMDirectory.cpp" +#include "CLucene/util/BitSet.cpp" +#include "CLucene/util/Equators.cpp" +#include "CLucene/util/FastCharStream.cpp" +#include "CLucene/util/MD5Digester.cpp" +#include "CLucene/util/Reader.cpp" +#include "CLucene/util/StringIntern.cpp" +#include "CLucene/util/ThreadLocal.cpp" + +#include "CLucene/CLSharedMonolithic.cpp" diff --git a/src/core/CLucene/StdHeader.cpp b/src/core/CLucene/StdHeader.cpp new file mode 100644 index 00000000000..90a5e326831 --- /dev/null +++ b/src/core/CLucene/StdHeader.cpp @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/Misc.h" + +#include "CLucene/search/Sort.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/search/FieldCache.h" +#include "CLucene/index/TermVector.h" +#include "CLucene/index/_IndexFileNameFilter.h" +#include "CLucene/search/FieldSortedHitQueue.h" +#include "CLucene/store/LockFactory.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/_ThreadLocal.h" + +#if defined(_MSC_VER) && defined(_DEBUG) + #define CRTDBG_MAP_ALLOC + #include +#endif + +CL_NS_USE(util) +CL_NS_USE(search) +CL_NS_USE(index) +CL_NS_USE(store) + +//clears all static memory. do not attempt to do anything else +//in clucene after calling this function +void _lucene_shutdown(){ + FieldSortedHitQueue::_shutdown(); + Sort::_shutdown(); + ScoreDocComparator::_shutdown(); + SortField::_shutdown(); + FieldCache::_shutdown(); + Similarity::_shutdown(); + CLStringIntern::_shutdown(); + NoLockFactory::_shutdown(); + _ThreadLocal::_shutdown(); + IndexFileNameFilter::_shutdown(); + _CLDELETE (TermVectorOffsetInfo_EMPTY_OFFSET_INFO); +} diff --git a/src/core/CLucene/StdHeader.h b/src/core/CLucene/StdHeader.h new file mode 100644 index 00000000000..58bdea90097 --- /dev/null +++ b/src/core/CLucene/StdHeader.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef lucene_stdheader_h +#define lucene_stdheader_h + +/** +* This header contains public distributed code that needs to be included *before* +* any clucene-core code is included. It also uses the clucene-shared header +* which contains platform specific code configured by cmake. +*/ + +//configurations for library +#include "CLucene/CLConfig.h" + +//shared header +#include "CLucene/SharedHeader.h" + +//error handling macros/functions +#include "CLucene/debug/error.h" + +//todo: would be good to deprecate this... it's ugly +#define StringArrayWithDeletor CL_NS(util)::CLVector +#define CLuceneStringArray std::vector +#define StringArrayWithDeletor CL_NS(util)::CLVector +#define StringArrayConst std::vector +//#define StringArrayConstWithDeletor CL_NS(util)::CLVector + +#define AStringArray std::vector +#define AStringArrayWithDeletor CL_NS(util)::CLVector +#define AStringArrayConst std::vector +//#define AStringArrayConstWithDeletor CL_NS(util)::CLVector + +//call this at the end of running to clean up memory. +extern CLUCENE_EXPORT void _lucene_shutdown(); + +#endif // lucene_apiheader_h diff --git a/src/core/CLucene/_ApiHeader.h b/src/core/CLucene/_ApiHeader.h new file mode 100644 index 00000000000..5eac7cb69e2 --- /dev/null +++ b/src/core/CLucene/_ApiHeader.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef lucene_internal_apiheader_h +#define lucene_internal_apiheader_h + +/** +* This is the header that all clucene-core source code includes. +* We include the shared code header and the public StdHeader.h header. +*/ + +#include "CLucene/StdHeader.h" +#include "CLucene/_SharedHeader.h" + +//todo: this code needs to go to shared +#include "CLucene/util/_VoidMap.h" +#include "CLucene/util/_VoidList.h" + +using namespace std; + +#endif // lucene_apiheader_h diff --git a/src/core/CLucene/analysis/AnalysisHeader.cpp b/src/core/CLucene/analysis/AnalysisHeader.cpp new file mode 100644 index 00000000000..a7fd819e1b4 --- /dev/null +++ b/src/core/CLucene/analysis/AnalysisHeader.cpp @@ -0,0 +1,85 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "AnalysisHeader.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/_ThreadLocal.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(analysis) + +struct Analyzer::Internal{ + CL_NS(util)::ThreadLocal >* tokenStreams; +}; +Analyzer::Analyzer(){ + _internal = new Internal; + _internal->tokenStreams = _CLNEW CL_NS(util)::ThreadLocal >; +} +Analyzer::~Analyzer(){ + _CLLDELETE(_internal->tokenStreams); + delete _internal; +} +TokenStream* Analyzer::getPreviousTokenStream() { + return _internal->tokenStreams->get(); +} +void Analyzer::setPreviousTokenStream(TokenStream* obj) { + _internal->tokenStreams->set(obj); +} +TokenStream* Analyzer::reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) { + return tokenStream(fieldName, reader); +} + +template <> +size_t Token::termLength(){ + if ( _termTextLen == -1 ) //it was invalidated by growBuffer + _termTextLen = _tcslen((TCHAR*)_buffer); + return _termTextLen; +}; + +template <> +size_t Token::termLength(){ + if ( _termTextLen == -1 ) //it was invalidated by growBuffer + _termTextLen = strlen((char*)_buffer); + return _termTextLen; +}; + +///Compares the Token for their order +class OrderCompare:LUCENE_BASE, public CL_NS(util)::Compare::_base // +{ +public: + bool operator()( Token* t1, Token* t2 ) const{ + if(t1->startOffset()>t2->startOffset()) + return false; + if(t1->startOffset()startOffset()) + return true; + return true; +} +}; + +TokenFilter::TokenFilter(TokenStream* in, bool deleteTS): + input(in), + deleteTokenStream(deleteTS) +{ +} +TokenFilter::~TokenFilter(){ + if ( deleteTokenStream && input!=NULL ) {input->close();_CLLDELETE( input );} + //close(); -- ISH 04/11/09 +} + +// Close the input TokenStream. +void TokenFilter::close() { + if ( input != NULL ){ + input->close(); + //if ( deleteTokenStream ) _CLDELETE( input ); -- ISH 04/11/09 + } + //input = NULL; -- ISH 04/11/09 +} + +CL_NS_END diff --git a/src/core/CLucene/analysis/AnalysisHeader.h b/src/core/CLucene/analysis/AnalysisHeader.h new file mode 100644 index 00000000000..e3d572a86e6 --- /dev/null +++ b/src/core/CLucene/analysis/AnalysisHeader.h @@ -0,0 +1,362 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_AnalysisHeader_ +#define _lucene_analysis_AnalysisHeader_ + +#include "CLucene/index/Payload.h" +#include "CLucene/util/VoidList.h" +#include "CLucene/LuceneThreads.h" + +CL_CLASS_DEF(util,Reader) +CL_CLASS_DEF(util,IReader) + +CL_NS_DEF(analysis) + +typedef CL_NS(util)::CLSetList CLTCSetList; + +/** A Token is an occurence of a term from the text of a field. It consists of + a term's text, the start and end offset of the term in the text of the field, + and a type string. +

+ The start and end offsets permit applications to re-associate a token with + its source text, e.g., to display highlighted query terms in a document + browser, or to show matching text fragments in a KWIC (KeyWord In Context) + display, etc. +

+ The type is an interned string, assigned by a lexical analyzer + (a.k.a. tokenizer), naming the lexical or syntactic class that the token + belongs to. For example an end of sentence marker token might be implemented + with type "eos". The default token type is "word". +

+ A Token can optionally have metadata (a.k.a. Payload) in the form of a variable + length byte array. Use {@link lucene::index::TermPositions#getPayloadLength()} and + {@link lucene::index::TermPositions#getPayload(byte[], int)} to retrieve the payloads from the index. + +

+

+ WARNING: The status of the Payloads feature is experimental. + The APIs introduced here might change in the future and will not be + supported anymore in such a case. + +

+ +

Tokenizers and filters should try to re-use a Token + instance when possible for best performance, by + implementing the {@link lucene::index::TokenStream#next(Token)} API. + Failing that, to create a new Token you should first use + one of the constructors that starts with null text. Then + you should call either {@link #termBuffer()} or {@link + #resizeTermBuffer(int)} to retrieve the Token's + termBuffer. Fill in the characters of your term into this + buffer, and finally call {@link #setTermLength(int)} to + set the length of the term text. See LUCENE-969 + for details.

+ + @see Payload +*/ +class CLUCENE_EXPORT Token : LUCENE_BASE { +private: + int32_t _startOffset;///< start in source text + int32_t _endOffset; ///< end in source text + const TCHAR *_type; ///< lexical type + int32_t positionIncrement; + size_t bufferTextLen; + void *_buffer; ///< the text of the term + int32_t _termTextLen;///< the length of termText. Internal use only + + CL_NS(index)::Payload *payload; + +public: + static const TCHAR *getDefaultType() { return L"word"; }; + + Token() : _startOffset(0), + _endOffset(0), + _type(getDefaultType()), + positionIncrement(1), + payload(NULL) { + _termTextLen = 0; + _buffer = NULL; + bufferTextLen = 0; + }; + virtual ~Token() { + free(_buffer); + _CLLDELETE(payload); + }; + + /// Constructs a Token with the given text, start and end offsets, & type. + //SToken(const T* text, const int32_t start, const int32_t end, const TCHAR* typ=NULL); + template + void set(const T *text, const int32_t start, const int32_t end, const TCHAR *typ = NULL) { + _startOffset = start; + _endOffset = end; + _type = (typ == NULL ? getDefaultType() : typ); + positionIncrement = 1; + setText(text, end - start); + }; + + size_t bufferLength() const { + return bufferTextLen; + } + template + void growBuffer(size_t size) { + if (bufferTextLen >= size) + return; + if (_buffer == NULL) { + _buffer = (T *) malloc(size * sizeof(T)); + *(T *) _buffer = 0; + } else { + //use realloc. growBuffer is public, therefore could be called + //without a subsequent call to overwriting the memory + _buffer = (T *) realloc(_buffer, size * sizeof(T)); + } + bufferTextLen = size; + } + + template + void *resizeTermBuffer(size_t size) { + if (bufferTextLen < size) + growBuffer(size); + return this->_buffer; + } + void setPositionIncrement(int32_t posIncr) { + if (posIncr < 0) { + _CLTHROWA(CL_ERR_IllegalArgument, "positionIncrement must be >= 0"); + } + positionIncrement = posIncr; + } + int32_t getPositionIncrement() const { return positionIncrement; } + + template + T *termBuffer() const { + return (T *) _buffer; + } + + template + size_t termLength();//< Length of the the termBuffer. See #termBuffer + + void resetTermTextLen() { + _termTextLen = -1; + } + + template + void setText(const T *text, int32_t l) { + if (bufferTextLen < l + 1) + growBuffer(l + 1); + memcpy(_buffer, text, l*sizeof(T)); + _termTextLen = l; + ((T *) _buffer)[_termTextLen] = 0;//make sure null terminated + }; + + int32_t startOffset() const { + return _startOffset; + } + + void setStartOffset(const int32_t val) { + _startOffset = val; + } + + template + void setTermLength(int32_t len) { + if (bufferTextLen < len) + this->growBuffer(len); + this->_termTextLen = len; + } + + int32_t endOffset() const { + return _endOffset; + } + + void setEndOffset(const int32_t val) { + _endOffset = val; + } + + const TCHAR *type() const { return _type; } + void setType(const TCHAR *val) { + _type = val; + } + + CL_NS(index)::Payload *getPayload() { return this->payload; } + void setPayload(CL_NS(index)::Payload *p) { + _CLLDELETE(this->payload); + this->payload = p; + } + + void clear() { + _CLDELETE(payload); + // Leave _buffer to allow re-use + _termTextLen = 0; + positionIncrement = 1; + // startOffset = endOffset = 0; + // type = DEFAULT_TYPE; + } +}; + +class CLUCENE_EXPORT TokenStream { +public: + /** Returns the next token in the stream, or null at EOS. + * When possible, the input Token should be used as the + * returned Token (this gives fastest tokenization + * performance), but this is not required and a new Token + * may be returned (pass NULL for this). + * Callers may re-use a single Token instance for successive + * calls to this method. + *

+ * This implicitly defines a "contract" between + * consumers (callers of this method) and + * producers (implementations of this method + * that are the source for tokens): + *

    + *
  • A consumer must fully consume the previously + * returned Token before calling this method again.
  • + *
  • A producer must call {@link Token#clear()} + * before setting the fields in it & returning it
  • + *
+ * Note that a {@link TokenFilter} is considered a consumer. + * @param result a Token that may or may not be used to return + * @return next token in the stream or null if end-of-stream was hit + */ + virtual Token* next(Token* token) = 0; + + /** Releases resources associated with this stream. */ + virtual void close() = 0; + + /** Resets this stream to the beginning. This is an + * optional operation, so subclasses may or may not + * implement this method. Reset() is not needed for + * the standard indexing process. However, if the Tokens + * of a TokenStream are intended to be consumed more than + * once, it is necessary to implement reset(). + */ + virtual void reset(){}; + + virtual ~TokenStream(){}; +}; + + +class CLUCENE_EXPORT Analyzer{ +public: + Analyzer(); + + /** Creates a TokenStream which tokenizes all the text in the provided + Reader. Default implementation forwards to tokenStream(Reader) for + compatibility with older version. Override to allow Analyzer to choose + strategy based on document and/or field. Must be able to handle null + field name for backward compatibility. */ + virtual TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader)=0; + + /** Creates a TokenStream that is allowed to be re-used + * from the previous time that the same thread called + * this method. Callers that do not need to use more + * than one TokenStream at the same time from this + * analyzer should use this method for better + * performance. + */ + virtual TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); +private: + + DEFINE_MUTEX(THIS_LOCK) + struct Internal; + Internal* _internal; +protected: + + /** Used by Analyzers that implement reusableTokenStream + * to retrieve previously saved TokenStreams for re-use + * by the same thread. */ + TokenStream* getPreviousTokenStream(); + + /** Used by Analyzers that implement reusableTokenStream + * to save a TokenStream for later re-use by the same + * thread. */ + void setPreviousTokenStream(TokenStream* obj); +public: + /** + * Invoked before indexing a Field instance if + * terms have already been added to that field. This allows custom + * analyzers to place an automatic position increment gap between + * Field instances using the same field name. The default value + * position increment gap is 0. With a 0 position increment gap and + * the typical default token position increment of 1, all terms in a field, + * including across Field instances, are in successive positions, allowing + * exact PhraseQuery matches, for instance, across Field instance boundaries. + * + * @param fieldName Field name being indexed. + * @return position increment gap, added to the next token emitted from {@link #tokenStream(TCHAR*, Reader*)} + */ + virtual int32_t getPositionIncrementGap(const TCHAR* fieldName){return 0;} + + virtual ~Analyzer(); +}; + +/** An Analyzer builds TokenStreams, which analyze text. It thus represents a + * policy for extracting index terms from text. + *

+ * Typical implementations first build a Tokenizer, which breaks the stream of + * characters from the Reader into raw Tokens. One or more TokenFilters may + * then be applied to the output of the Tokenizer. + *

+ * WARNING: You must override one of the methods defined by this class in your + * subclass or the Analyzer will enter an infinite loop. + */ + +class CLUCENE_EXPORT Tokenizer:public TokenStream { +protected: + /** The text source for this Tokenizer. */ + CL_NS(util)::Reader* input; + +public: + /** Construct a tokenizer with null input. */ + Tokenizer():input(nullptr){} + /** Construct a token stream processing the given input. */ + explicit Tokenizer(CL_NS(util)::Reader* _input):input(_input){} + + /** By default, closes the input Reader. */ + virtual void close() { + if (input != NULL) { + // ? delete input; + input = NULL; + } + }; + + /** Expert: Reset the tokenizer to a new reader. Typically, an + * analyzer (in its reusableTokenStream method) will use + * this to re-use a previously created tokenizer. */ + virtual void reset(CL_NS(util)::Reader* _input){ + // ? delete input; + this->input = _input; + }; + + virtual ~Tokenizer() { + close(); + }; +}; + +/** A TokenFilter is a TokenStream whose input is another token stream. +

+This is an abstract class. +*/ +class CLUCENE_EXPORT TokenFilter:public TokenStream { +protected: + /** The source of tokens for this filter. */ + TokenStream* input; + /** If true then input will be deleted in the destructor */ + bool deleteTokenStream; + + /** Construct a token stream filtering the given input. + * + * @param in The TokenStream to filter from + * @param deleteTS If true, input will be deleted in the destructor + */ + TokenFilter(TokenStream* in, bool deleteTS=false); + virtual ~TokenFilter(); +public: + /** Close the input TokenStream. */ + void close(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/analysis/Analyzers.cpp b/src/core/CLucene/analysis/Analyzers.cpp new file mode 100644 index 00000000000..2783a100a89 --- /dev/null +++ b/src/core/CLucene/analysis/Analyzers.cpp @@ -0,0 +1,595 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Analyzers.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/Misc.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(analysis) + +template +LetterTokenizer::LetterTokenizer(CL_NS(util)::Reader* in): + CharTokenizer(in) { +} + +template +LetterTokenizer::~LetterTokenizer(){} + +template +bool LetterTokenizer::isTokenChar(const T c) const { + return _istalpha(c)!=0; +} + +template +LowerCaseTokenizer::LowerCaseTokenizer(CL_NS(util)::Reader* in): + LetterTokenizer(in) { +} + +template +LowerCaseTokenizer::~LowerCaseTokenizer(){ +} + +template +T LowerCaseTokenizer::normalize(const T chr) const { + return _totlower(chr); +} + +template class LowerCaseTokenizer; +template class LowerCaseTokenizer; + +template +SimpleTokenizer::SimpleTokenizer(CL_NS(util)::Reader *in) : LowerCaseTokenizer(in) { +} + +template +SimpleTokenizer::~SimpleTokenizer()= default; + +template +bool SimpleTokenizer::isTokenChar(const T c) const { + //return _istalnum(c)!=0; + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); +} + +template class SimpleTokenizer; +template class SimpleTokenizer; + +template +WhitespaceTokenizer::WhitespaceTokenizer(CL_NS(util)::Reader* in):CharTokenizer(in) { +} +template +WhitespaceTokenizer::~WhitespaceTokenizer(){ +} + +template +bool WhitespaceTokenizer::isTokenChar(const T c) const{ + return _istspace(c)==0; //(return true if NOT a space) +} + +template class WhitespaceTokenizer; +template class WhitespaceTokenizer; + +template +WhitespaceAnalyzer::WhitespaceAnalyzer(){ +} +template +WhitespaceAnalyzer::~WhitespaceAnalyzer(){ +} + +template +TokenStream* WhitespaceAnalyzer::tokenStream(const TCHAR* /*fieldName*/, Reader* reader) { + return _CLNEW WhitespaceTokenizer(reader); +} +template +TokenStream* WhitespaceAnalyzer::reusableTokenStream(const TCHAR* /*fieldName*/, CL_NS(util)::Reader* reader) +{ + Tokenizer* tokenizer = static_cast(getPreviousTokenStream()); + if (tokenizer == NULL) { + tokenizer = _CLNEW WhitespaceTokenizer(reader); + setPreviousTokenStream(tokenizer); + } else + tokenizer->reset(reader); + return tokenizer; +} +template class WhitespaceAnalyzer; +template class WhitespaceAnalyzer; + +LowerCaseFilter::LowerCaseFilter(TokenStream* in, bool deleteTokenStream): + TokenFilter(in,deleteTokenStream) { +} +LowerCaseFilter::~LowerCaseFilter(){ +} + +Token* LowerCaseFilter::next(Token* t){ + if (input->next(t) == NULL) + return NULL; + stringCaseFold( t->termBuffer() ); + return t; +} + +bool StopFilter::ENABLE_POSITION_INCREMENTS_DEFAULT = false; + + +/** Constructs a filter which removes words from the input +* TokenStream that are named in the CLSetList. +*/ +StopFilter::StopFilter(TokenStream* in, bool deleteTokenStream, CLTCSetList* stopTable, bool _deleteStopTable): + TokenFilter(in, deleteTokenStream), + stopWords (stopTable), + deleteStopTable(_deleteStopTable), + enablePositionIncrements(ENABLE_POSITION_INCREMENTS_DEFAULT), + ignoreCase(false) +{ +} + +StopFilter::StopFilter(TokenStream* in, bool deleteTokenStream, const TCHAR** _stopWords, const bool _ignoreCase): + TokenFilter(in, deleteTokenStream), + enablePositionIncrements(ENABLE_POSITION_INCREMENTS_DEFAULT), + ignoreCase(_ignoreCase) +{ + deleteStopTable = true; + stopWords = _CLNEW CLTCSetList(true); + fillStopTable( stopWords,_stopWords, _ignoreCase ); +} + +StopFilter::~StopFilter(){ + if (deleteStopTable) + _CLLDELETE(stopWords); +} +//static +bool StopFilter::getEnablePositionIncrementsDefault() { + return ENABLE_POSITION_INCREMENTS_DEFAULT; +} +//static +void StopFilter::setEnablePositionIncrementsDefault(const bool defaultValue) { + ENABLE_POSITION_INCREMENTS_DEFAULT = defaultValue; +} + +bool StopFilter::getEnablePositionIncrements() const { return enablePositionIncrements; } +void StopFilter::setEnablePositionIncrements(const bool enable) { this->enablePositionIncrements = enable; } + +void StopFilter::fillStopTable(CLTCSetList* stopTable, const TCHAR** stopWords, const bool _ignoreCase) +{ + TCHAR* tmp; + if ( _ignoreCase ){ + for (int32_t i = 0; stopWords[i]!=NULL; i++){ + tmp = STRDUP_TtoT(stopWords[i]); + stringCaseFold(tmp); + stopTable->insert( tmp ); + } + }else{ + for (int32_t i = 0; stopWords[i]!=NULL; i++){ + tmp = STRDUP_TtoT(stopWords[i]); + stopTable->insert( tmp ); + } + } +} + +Token* StopFilter::next(Token* token) { + // return the first non-stop word found + int32_t skippedPositions = 0; + while (input->next(token)){ + TCHAR* termText = token->termBuffer(); + if ( ignoreCase ){ + stringCaseFold(termText); + } + if (stopWords->find(termText)==stopWords->end()){ + if (enablePositionIncrements) { + token->setPositionIncrement(token->getPositionIncrement() + skippedPositions); + } + return token; + } + skippedPositions += token->getPositionIncrement(); + } + + // reached EOS -- return nothing + return NULL; +} + +StopAnalyzer::StopAnalyzer(const char* stopwordsFile, const char* enc): + stopTable(_CLNEW CLTCSetList(true)) +{ + if ( enc == NULL ) + enc = "ASCII"; + WordlistLoader::getWordSet(stopwordsFile, enc, stopTable); +} + +StopAnalyzer::StopAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool _bDeleteReader): + stopTable(_CLNEW CLTCSetList(true)) +{ + WordlistLoader::getWordSet(stopwordsReader, stopTable, _bDeleteReader); +} + +StopAnalyzer::StopAnalyzer(): + stopTable(_CLNEW CLTCSetList(true)) +{ + StopFilter::fillStopTable(stopTable,ENGLISH_STOP_WORDS); +} +class StopAnalyzer::SavedStreams : public TokenStream { +public: + Tokenizer* source; + TokenStream* result; + + SavedStreams():source(NULL), result(NULL) {} + + void close(){} + Token* next(Token* token) {return NULL;} +}; +StopAnalyzer::~StopAnalyzer() +{ + SavedStreams* t = reinterpret_cast(this->getPreviousTokenStream()); + if (t) _CLDELETE(t->result); + _CLDELETE(stopTable); +} +StopAnalyzer::StopAnalyzer( const TCHAR** stopWords): + stopTable(_CLNEW CLTCSetList(true)) +{ + StopFilter::fillStopTable(stopTable,stopWords); +} +TokenStream* StopAnalyzer::tokenStream(const TCHAR* /*fieldName*/, Reader* reader) { + return _CLNEW StopFilter(_CLNEW LowerCaseTokenizer(reader),true, stopTable); +} + +/** Filters LowerCaseTokenizer with StopFilter. */ +TokenStream* StopAnalyzer::reusableTokenStream(const TCHAR* fieldName, Reader* reader) { + SavedStreams* streams = reinterpret_cast(getPreviousTokenStream()); + if (streams == NULL) { + streams = _CLNEW SavedStreams(); + streams->source = _CLNEW LowerCaseTokenizer(reader); + streams->result = _CLNEW StopFilter(streams->source, true, stopTable); + setPreviousTokenStream(streams); + } else + streams->source->reset(reader); + return streams->result; +} + +const TCHAR* StopAnalyzer::ENGLISH_STOP_WORDS[] = +{ + _T("a"), _T("an"), _T("and"), _T("are"), _T("as"), _T("at"), _T("be"), _T("but"), _T("by"), + _T("for"), _T("if"), _T("in"), _T("into"), _T("is"), _T("it"), + _T("no"), _T("not"), _T("of"), _T("on"), _T("or"), _T("such"), + _T("that"), _T("the"), _T("their"), _T("then"), _T("there"), _T("these"), + _T("they"), _T("this"), _T("to"), _T("was"), _T("will"), _T("with"), NULL +}; + +PerFieldAnalyzerWrapper::PerFieldAnalyzerWrapper(Analyzer* defaultAnalyzer): + analyzerMap(_CLNEW AnalyzerMapType(true,true)) +{ + this->defaultAnalyzer = defaultAnalyzer; +} +PerFieldAnalyzerWrapper::~PerFieldAnalyzerWrapper(){ + analyzerMap->clear(); + _CLLDELETE(analyzerMap); + _CLLDELETE(defaultAnalyzer); +} + +void PerFieldAnalyzerWrapper::addAnalyzer(const TCHAR* fieldName, Analyzer* analyzer) { + analyzerMap->put(STRDUP_TtoT(fieldName), analyzer); +} + +TokenStream* PerFieldAnalyzerWrapper::tokenStream(const TCHAR* fieldName, Reader* reader) { + Analyzer* analyzer = analyzerMap->get(const_cast(fieldName)); + if (analyzer == NULL) { + analyzer = defaultAnalyzer; + } + + return analyzer->tokenStream(fieldName, reader); +} + +TokenStream* PerFieldAnalyzerWrapper::reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) { + Analyzer* analyzer = analyzerMap->get(const_cast(fieldName)); + if (analyzer == NULL){ + analyzer = defaultAnalyzer; + } + + return analyzer->reusableTokenStream(fieldName, reader); +} + +int32_t PerFieldAnalyzerWrapper::getPositionIncrementGap(const TCHAR* fieldName) { + Analyzer* analyzer = analyzerMap->get(const_cast(fieldName)); + if (analyzer == NULL) + analyzer = defaultAnalyzer; + return analyzer->getPositionIncrementGap(fieldName); +} + + + +ISOLatin1AccentFilter::ISOLatin1AccentFilter(TokenStream* input, bool deleteTs): + TokenFilter(input,deleteTs) +{ +} +ISOLatin1AccentFilter::~ISOLatin1AccentFilter(){ +} +Token* ISOLatin1AccentFilter::next(Token* token){ + if ( input->next(token) != NULL ){ + int32_t l = token->termLength(); + const TCHAR* chars = token->termBuffer(); + bool doProcess = false; + for (int32_t i = 0; i < l; ++i) { + #ifdef _UCS2 + if ( chars[i] >= 0xC0 && chars[i] <= 0x178 ) { + #else + if ( (chars[i] >= 0xC0 && chars[i] <= 0xFF) || chars[i] < 0 ) { + #endif + doProcess = true; + break; + } + + } + if ( !doProcess ) { + return token; + } + + StringBuffer output(l*2); + for (int32_t j = 0; j < l; j++) { + #ifdef _UCS2 + TCHAR c = chars[j]; + #else + unsigned char c = chars[j]; + #endif + switch (c) { + case 0xC0 : // � + case 0xC1 : // � + case 0xC2 : // � + case 0xC3 : // � + case 0xC4 : // � + case 0xC5 : // � + output.appendChar('A'); + break; + case 0xC6 : // � + output.append(_T("AE")); + break; + case 0xC7 : // � + output.appendChar('C'); + break; + case 0xC8 : // � + case 0xC9 : // � + case 0xCA : // � + case 0xCB : // � + output.appendChar('E'); + break; + case 0xCC : // � + case 0xCD : // � + case 0xCE : // � + case 0xCF : // � + output.appendChar('I'); + break; + case 0xD0 : // � + output.appendChar('D'); + break; + case 0xD1 : // � + output.appendChar('N'); + break; + case 0xD2 : // � + case 0xD3 : // � + case 0xD4 : // � + case 0xD5 : // � + case 0xD6 : // � + case 0xD8 : // � + output.appendChar('O'); + break; + case 0xDE : // � + output.append(_T("TH")); + break; + case 0xD9 : // � + case 0xDA : // � + case 0xDB : // � + case 0xDC : // � + output.appendChar('U'); + break; + case 0xDD : // � + output.appendChar('Y'); + break; + case 0xE0 : // � + case 0xE1 : // � + case 0xE2 : // � + case 0xE3 : // � + case 0xE4 : // � + case 0xE5 : // � + output.appendChar('a'); + break; + case 0xE6 : // � + output.append(_T("ae")); + break; + case 0xE7 : // � + output.appendChar('c'); + break; + case 0xE8 : // � + case 0xE9 : // � + case 0xEA : // � + case 0xEB : // � + output.appendChar('e'); + break; + case 0xEC : // � + case 0xED : // � + case 0xEE : // � + case 0xEF : // � + output.appendChar('i'); + break; + case 0xF0 : // � + output.appendChar('d'); + break; + case 0xF1 : // � + output.appendChar('n'); + break; + case 0xF2 : // � + case 0xF3 : // � + case 0xF4 : // � + case 0xF5 : // � + case 0xF6 : // � + case 0xF8 : // � + output.appendChar('o'); + break; + case 0xDF : // � + output.append(_T("ss")); + break; + case 0xFE : // � + output.append(_T("th")); + break; + case 0xF9 : // � + case 0xFA : // � + case 0xFB : // � + case 0xFC : // � + output.appendChar('u'); + break; + case 0xFD : // � + case 0xFF : // � + output.appendChar('y'); + break; + + #ifdef _UCS2 + case 0x152 : // � + output.append(_T("OE")); + break; + case 0x153 : // � + output.append(_T("oe")); + break; + case 0x178 : // � + output.appendChar('Y'); + break; + #endif + default : + output.appendChar(c); + break; + } + } + token->setText(output.getBuffer(), output.length()); + return token; + } + return NULL; +} + + +KeywordAnalyzer::KeywordAnalyzer(){} +KeywordAnalyzer::~KeywordAnalyzer(){} +TokenStream* KeywordAnalyzer::tokenStream(const TCHAR* /*fieldName*/, CL_NS(util)::Reader* reader){ + return _CLNEW KeywordTokenizer(reader); +} +TokenStream* KeywordAnalyzer::reusableTokenStream(const TCHAR* /*fieldName*/, CL_NS(util)::Reader* reader) +{ + Tokenizer* tokenizer = static_cast(getPreviousTokenStream()); + if (tokenizer == NULL) { + tokenizer = _CLNEW KeywordTokenizer(reader); + setPreviousTokenStream(tokenizer); + } else + tokenizer->reset(reader); + return tokenizer; +} + +KeywordTokenizer::KeywordTokenizer(CL_NS(util)::Reader* input, int bufferSize): + Tokenizer(input) +{ + this->done = false; + this->bufferSize = bufferSize; + if ( bufferSize < 1 ) + this->bufferSize = DEFAULT_BUFFER_SIZE; +} +KeywordTokenizer::~KeywordTokenizer(){ +} + +Token* KeywordTokenizer::next(Token* token){ + if (!done) { + done = true; + int32_t upto = 0; + int32_t rd; + + token->clear(); + TCHAR* termBuffer=token->termBuffer(); + const TCHAR* readBuffer=NULL; + + while (true) { + rd = input->read((const void**)&readBuffer, 1, cl_min(bufferSize, token->bufferLength()-upto) ); + if (rd == -1) + break; + if ( upto == token->bufferLength() ){ + termBuffer = (TCHAR*)token->resizeTermBuffer(token->bufferLength() + 8); + } + _tcsncpy(termBuffer + upto, readBuffer, rd); + upto += rd; + } + if ( token->bufferLength() < upto + 1 ){ + termBuffer=(TCHAR *)token->resizeTermBuffer(token->bufferLength() + 8); + } + termBuffer[upto]=0; + token->setTermLength(upto); + return token; + } + return NULL; +} +void KeywordTokenizer::reset(CL_NS(util)::Reader* input) +{ + Tokenizer::reset(input); + this->done = false; +} + + +LengthFilter::LengthFilter(TokenStream* in, const size_t _min, const size_t _max): + TokenFilter(in) +{ + this->_min = _min; + this->_max = _max; +} + +Token* LengthFilter::next(Token* token) +{ + // return the first non-stop word found + while ( input->next(token) ) + { + size_t len = token->termLength(); + if (len >= _min && len <= _max) + return token; + // note: else we ignore it but should we index each part of it? + } + // reached EOS -- return null + return NULL; +} + + +CLTCSetList* WordlistLoader::getWordSet(const char* wordfilePath, const char* enc, CLTCSetList* stopTable) +{ + if ( enc == NULL ) + enc = "ASCII"; + CL_NS(util)::FileReader* reader = NULL; + try { + reader = _CLNEW CL_NS(util)::FileReader(wordfilePath, enc, LUCENE_DEFAULT_TOKEN_BUFFER_SIZE); + stopTable = getWordSet(reader, stopTable); + } + _CLFINALLY ( + if (reader != NULL) { + //reader->close(); + _CLLDELETE(reader); + } + ); + return stopTable; +} + +//static +CLTCSetList* WordlistLoader::getWordSet(CL_NS(util)::Reader* reader, CLTCSetList* stopTable, const bool bDeleteReader) +{ + if (!stopTable) + stopTable = _CLNEW CLTCSetList(true); + + TCHAR* word = NULL; + try { + word = _CL_NEWARRAY(TCHAR, LUCENE_DEFAULT_TOKEN_BUFFER_SIZE); + while (reader->readLine(word, LUCENE_DEFAULT_TOKEN_BUFFER_SIZE) > 0) { + stopTable->insert( STRDUP_TtoT(CL_NS(util)::Misc::wordTrim(word))); + } + } + _CLFINALLY ( + if (bDeleteReader && reader != NULL) { + //reader->close(); + _CLDELETE(reader); + } + _CLDELETE_ARRAY(word); + ); + return stopTable; +} + + +CL_NS_END diff --git a/src/core/CLucene/analysis/Analyzers.h b/src/core/CLucene/analysis/Analyzers.h new file mode 100644 index 00000000000..fc65204b785 --- /dev/null +++ b/src/core/CLucene/analysis/Analyzers.h @@ -0,0 +1,462 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_Analyzers_ +#define _lucene_analysis_Analyzers_ + +#include "CLucene/util/VoidList.h" +#include "CLucene/util/VoidMap.h" +#include "CLucene/util/CLStreams.h" +#include "AnalysisHeader.h" + +CL_NS_DEF(analysis) + +template +class CLUCENE_EXPORT CharTokenizer:public Tokenizer { +private: + int32_t offset, bufferIndex, dataLen; + T buffer[LUCENE_MAX_WORD_LEN+1]; + const T* ioBuffer; +protected: + + /** Returns true iff a character should be included in a token. This + * tokenizer generates as tokens adjacent sequences of characters which + * satisfy this predicate. Characters for which this is false are used to + * define token boundaries and are not included in tokens. */ + virtual bool isTokenChar(const T c) const = 0; + + /** Called on each token character to normalize it before it is added to the + * token. The default implementation does nothing. Subclasses may use this + * to, e.g., lowercase tokens. */ + virtual T normalize(const T c) const{return c;}; + +public: + explicit CharTokenizer(CL_NS(util)::Reader* in):Tokenizer(in), + offset(0), + bufferIndex(0), + dataLen(0), + ioBuffer(NULL) + { + buffer[0]=0; + }; + Token* next(Token* token){ + int32_t length = 0; + int32_t start = offset; + while (true) { + T c; + offset++; + if (bufferIndex >= dataLen) { + dataLen = input->read((const void**)&ioBuffer, 1, LUCENE_IO_BUFFER_SIZE ); + if (dataLen == -1) + dataLen = 0; + bufferIndex = 0; + } + if (dataLen <= 0 ) { + if (length > 0) + break; + else + return NULL; + }else + c = ioBuffer[bufferIndex++]; + if (isTokenChar(c)) { // if it's a token TCHAR + + if (length == 0) // start of token + start = offset-1; + + buffer[length++] = normalize(c); // buffer it, normalized + + if (length == LUCENE_MAX_WORD_LEN) // buffer overflow! + break; + + } else if (length > 0) // at non-Letter w/ chars + break; // return 'em + } + buffer[length]=0; + token->set( buffer, start, start+length); + + return token; + }; + void reset(CL_NS(util)::Reader* input){ + Tokenizer::reset(input); + bufferIndex = 0; + offset = 0; + dataLen = 0; + }; + + virtual ~CharTokenizer(){}; +}; + +/** A LetterTokenizer is a tokenizer that divides text at non-letters. That's +to say, it defines tokens as maximal strings of adjacent letters, as defined +by java.lang.Character.isLetter() predicate. + +Note: this does a decent job for most European languages, but does a terrible +job for some Asian languages, where words are not separated by spaces. */ +template +class CLUCENE_EXPORT LetterTokenizer:public CharTokenizer { +public: + // Construct a new LetterTokenizer. + LetterTokenizer(CL_NS(util)::Reader* in); + virtual ~LetterTokenizer(); +protected: + /** Collects only characters which satisfy _istalpha.*/ + bool isTokenChar(const T c) const; +}; + + + +/** +* LowerCaseTokenizer performs the function of LetterTokenizer +* and LowerCaseFilter together. It divides text at non-letters and converts +* them to lower case. While it is functionally equivalent to the combination +* of LetterTokenizer and LowerCaseFilter, there is a performance advantage +* to doing the two tasks at once, hence this (redundant) implementation. +*

+* Note: this does a decent job for most European languages, but does a terrible +* job for some Asian languages, where words are not separated by spaces. +*/ +template +class CLUCENE_EXPORT LowerCaseTokenizer:public LetterTokenizer { +public: + /** Construct a new LowerCaseTokenizer. */ + LowerCaseTokenizer(CL_NS(util)::Reader* in); + virtual ~LowerCaseTokenizer(); +protected: + /** Collects only characters which satisfy _totlower. */ + T normalize(const T chr) const; +}; + +template +class CLUCENE_EXPORT SimpleTokenizer:public LowerCaseTokenizer { +public: + /** Construct a new SimpleTokenizer. */ + SimpleTokenizer(CL_NS(util)::Reader* in); + virtual ~SimpleTokenizer(); +protected: + /** Collects only characters which satisfy _istalpha.*/ + bool isTokenChar(const T c) const; +}; + +/** A WhitespaceTokenizer is a tokenizer that divides text at whitespace. + * Adjacent sequences of non-Whitespace characters form tokens. */ +template +class CLUCENE_EXPORT WhitespaceTokenizer: public CharTokenizer { +public: + /** Construct a new WhitespaceTokenizer. */ + WhitespaceTokenizer(CL_NS(util)::Reader* in); + virtual ~WhitespaceTokenizer(); +protected: + /** Collects only characters which do not satisfy _istspace.*/ + bool isTokenChar(const T c) const; +}; + + +/** An Analyzer that uses WhitespaceTokenizer. */ +template +class CLUCENE_EXPORT WhitespaceAnalyzer: public Analyzer { +public: + WhitespaceAnalyzer(); + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + virtual ~WhitespaceAnalyzer(); +}; + +/** An Analyzer that filters LetterTokenizer with LowerCaseFilter. */ +template +class CLUCENE_EXPORT SimpleAnalyzer: public Analyzer { +public: + SimpleAnalyzer(){} + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) override{ + return _CLNEW SimpleTokenizer(reader); + } + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) override{ + auto* tokenizer = dynamic_cast(getPreviousTokenStream()); + if (tokenizer == nullptr) { + tokenizer = _CLNEW SimpleTokenizer(reader); + setPreviousTokenStream(tokenizer); + } else + tokenizer->reset(reader); + return tokenizer; + }; + + virtual ~SimpleAnalyzer(){} +}; + +/** +* Normalizes token text to lower case. +*/ +class CLUCENE_EXPORT LowerCaseFilter: public TokenFilter { +public: + LowerCaseFilter(TokenStream* in, bool deleteTokenStream); + virtual ~LowerCaseFilter(); + Token* next(Token* token); +}; + + +/** + * Removes stop words from a token stream. + */ +class CLUCENE_EXPORT StopFilter: public TokenFilter { +private: + //bvk: i found this to work faster with a non-hash table. the number of items + //in the stop table is not like to make it worth having hashing. + //ish: implement a radix/patricia tree for this? + CLTCSetList* stopWords; + bool deleteStopTable; + + bool enablePositionIncrements; + const bool ignoreCase; +public: + static bool ENABLE_POSITION_INCREMENTS_DEFAULT; + + // Constructs a filter which removes words from the input + // TokenStream that are named in the array of words. + StopFilter(TokenStream* in, bool deleteTokenStream, const TCHAR** _stopWords, const bool _ignoreCase = false); + + virtual ~StopFilter(); + + /** Constructs a filter which removes words from the input + * TokenStream that are named in the CLSetList. + */ + StopFilter(TokenStream* in, bool deleteTokenStream, CLTCSetList* stopTable, bool _deleteStopTable=false); + + /** + * Builds a Hashtable from an array of stop words, appropriate for passing + * into the StopFilter constructor. This permits this table construction to + * be cached once when an Analyzer is constructed. + * Note: the stopWords list must be a static list because the strings are not copied + */ + static void fillStopTable(CLTCSetList* stopTable, + const TCHAR** stopWords, const bool _ignoreCase = false); + + /** + * Returns the next input Token whose termText() is not a stop word. + */ + Token* next(Token* token); + + + /** + * @see #setEnablePositionIncrementsDefault(boolean). + */ + static bool getEnablePositionIncrementsDefault(); + + /** + * Set the default position increments behavior of every StopFilter created from now on. + *

+ * Note: behavior of a single StopFilter instance can be modified + * with {@link #setEnablePositionIncrements(boolean)}. + * This static method allows control over behavior of classes using StopFilters internally, + * for example {@link lucene::analysis::standard::StandardAnalyzer StandardAnalyzer}. + *

+ * Default : false. + * @see #setEnablePositionIncrements(boolean). + */ + static void setEnablePositionIncrementsDefault(const bool defaultValue); + + /** + * @see #setEnablePositionIncrements(boolean). + */ + bool getEnablePositionIncrements() const; + + /** + * Set to true to make this StopFilter enable position increments to result tokens. + *

+ * When set, when a token is stopped (omitted), the position increment of + * the following token is incremented. + *

+ * Default: see {@link #setEnablePositionIncrementsDefault(boolean)}. + */ + void setEnablePositionIncrements(const bool enable); + +}; + +/** + * Loader for text files that represent a list of stopwords. + * + */ +class CLUCENE_EXPORT WordlistLoader { +public: + /** + * Loads a text file and adds every line as an entry to a HashSet (omitting + * leading and trailing whitespace). Every line of the file should contain only + * one word. The words need to be in lowercase if you make use of an + * Analyzer which uses LowerCaseFilter (like StandardAnalyzer). + * + * @param wordfile File containing the wordlist + * @return A HashSet with the file's words + */ + static CLTCSetList* getWordSet(const char* wordfilePath, const char* enc = NULL, CLTCSetList* stopTable = NULL); + + /** + * Reads lines from a Reader and adds every line as an entry to a HashSet (omitting + * leading and trailing whitespace). Every line of the Reader should contain only + * one word. The words need to be in lowercase if you make use of an + * Analyzer which uses LowerCaseFilter (like StandardAnalyzer). + * + * @param reader Reader containing the wordlist + * @return A HashSet with the reader's words + */ + static CLTCSetList* getWordSet(CL_NS(util)::Reader* reader, CLTCSetList* stopTable = NULL, const bool bDeleteReader = false); +}; + + +/** Filters LetterTokenizer with LowerCaseFilter and StopFilter. */ +class CLUCENE_EXPORT StopAnalyzer: public Analyzer { + CLTCSetList* stopTable; + class SavedStreams; + +public: + /** Builds an analyzer which removes words in ENGLISH_STOP_WORDS. */ + StopAnalyzer(); + virtual ~StopAnalyzer(); + + /** Builds an analyzer which removes words in the provided array. */ + StopAnalyzer( const TCHAR** stopWords ); + + /** Builds an analyzer with the stop words from the given file. + * @see WordlistLoader#getWordSet(File) + */ + StopAnalyzer(const char* stopwordsFile, const char* enc = NULL); + + /** Builds an analyzer with the stop words from the given reader. + * @see WordlistLoader#getWordSet(Reader) + */ + StopAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool _bDeleteReader = false); + + /** Filters LowerCaseTokenizer with StopFilter. */ + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + /** An array containing some common English words that are not usually useful + for searching. */ + static const TCHAR* ENGLISH_STOP_WORDS[]; +}; + +/** + * This analyzer is used to facilitate scenarios where different + * fields require different analysis techniques. Use {@link #addAnalyzer} + * to add a non-default analyzer on a field name basis. + * + *

Example usage: + * + *

+ *   PerFieldAnalyzerWrapper* aWrapper =
+ *      new PerFieldAnalyzerWrapper(new StandardAnalyzer());
+ *   aWrapper.addAnalyzer("firstname", new KeywordAnalyzer());
+ *   aWrapper.addAnalyzer("lastname", new KeywordAnalyzer());
+ * 
+ * + *

In this example, StandardAnalyzer will be used for all fields except "firstname" + * and "lastname", for which KeywordAnalyzer will be used. + * + *

A PerFieldAnalyzerWrapper can be used like any other analyzer, for both indexing + * and query parsing. + */ +class CLUCENE_EXPORT PerFieldAnalyzerWrapper : public Analyzer { +private: + Analyzer* defaultAnalyzer; + + typedef CL_NS(util)::CLHashMap > AnalyzerMapType; + AnalyzerMapType* analyzerMap; +public: + /** + * Constructs with default analyzer. + * + * @param defaultAnalyzer Any fields not specifically + * defined to use a different analyzer will use the one provided here. + */ + PerFieldAnalyzerWrapper(Analyzer* defaultAnalyzer); + virtual ~PerFieldAnalyzerWrapper(); + + /** + * Defines an analyzer to use for the specified field. + * + * @param fieldName field name requiring a non-default analyzer + * @param analyzer non-default analyzer to use for field + */ + void addAnalyzer(const TCHAR* fieldName, Analyzer* analyzer); + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + /** Return the positionIncrementGap from the analyzer assigned to fieldName */ + int32_t getPositionIncrementGap(const TCHAR* fieldName); +}; + + +/** + * A filter that replaces accented characters in the ISO Latin 1 character set + * (ISO-8859-1) by their unaccented equivalent. The case will not be altered. + *

+ * For instance, 'à' will be replaced by 'a'. + *

+ */ +class CLUCENE_EXPORT ISOLatin1AccentFilter: public TokenFilter { +public: + ISOLatin1AccentFilter(TokenStream* input, bool deleteTs); + + /** + * To replace accented characters in a String by unaccented equivalents. + */ + Token* next(Token* token); + virtual ~ISOLatin1AccentFilter(); +}; + + +/** + * Emits the entire input as a single token. + */ +class CLUCENE_EXPORT KeywordTokenizer: public Tokenizer { +private: + LUCENE_STATIC_CONSTANT(int, DEFAULT_BUFFER_SIZE = 256); + bool done; + int bufferSize; +public: + KeywordTokenizer(CL_NS(util)::Reader* input, int bufferSize=-1); + Token* next(Token* token); + void reset(CL_NS(util)::Reader* input); + + virtual ~KeywordTokenizer(); +}; + +/** + * "Tokenizes" the entire stream as a single token. This is useful + * for data like zip codes, ids, and some product names. + */ +class CLUCENE_EXPORT KeywordAnalyzer: public Analyzer { +public: + KeywordAnalyzer(); + virtual ~KeywordAnalyzer(); + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); +}; + + +/** + * Removes words that are too long and too short from the stream. + * + */ +class CLUCENE_EXPORT LengthFilter: public TokenFilter { +private: + size_t _min; + size_t _max; +public: + /** + * Build a filter that removes words that are too long or too + * short from the text. + */ + LengthFilter(TokenStream* in, const size_t _min, const size_t _max); + + /** + * Returns the next input Token whose termText() is the right len + */ + Token* next(Token* token); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/analysis/CachingTokenFilter.cpp b/src/core/CLucene/analysis/CachingTokenFilter.cpp new file mode 100644 index 00000000000..0591f44a226 --- /dev/null +++ b/src/core/CLucene/analysis/CachingTokenFilter.cpp @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CachingTokenFilter.h" + +CL_NS_DEF(analysis) + +CachingTokenFilter::CachingTokenFilter( TokenStream * input, bool bDeleteTS ) +: TokenFilter( input, bDeleteTS ) +{ + bCacheInitialized = false; +} + +CachingTokenFilter::~CachingTokenFilter() +{ + for( itCache = cache.begin(); itCache != cache.end(); itCache++ ) + delete (*itCache); + + cache.clear(); +} + +Token * CachingTokenFilter::next( Token* t ) +{ + if( ! bCacheInitialized ) + { + fillCache(); + bCacheInitialized = true; + itCache = cache.begin(); + } + + // if the cache is exhausted, return null + if( itCache == cache.end() ) + return NULL; + + t->set( (*itCache)->termBuffer(), (*itCache)->startOffset(), (*itCache)->endOffset(), (*itCache)->type() ); + t->setPositionIncrement( (*itCache)->getPositionIncrement() ); + t->setPayload( (*itCache)->getPayload() ); + itCache++; + + return t; +} + +void CachingTokenFilter::reset() +{ + itCache = cache.begin(); +} + +void CachingTokenFilter::fillCache() +{ + Token token; + Token * pCopy; + + while( input->next( &token ) ) + { + pCopy = new Token( token.termBuffer(), token.startOffset(), token.endOffset(), token.type() ); + pCopy ->setPositionIncrement( token.getPositionIncrement() ); + pCopy ->setPayload( token.getPayload() ); + cache.push_back( pCopy ); + } +} + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/analysis/CachingTokenFilter.h b/src/core/CLucene/analysis/CachingTokenFilter.h new file mode 100644 index 00000000000..a280821aa03 --- /dev/null +++ b/src/core/CLucene/analysis/CachingTokenFilter.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_CachingTokenFilter +#define _lucene_analysis_CachingTokenFilter + +#include +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF(analysis) + +class CLUCENE_EXPORT CachingTokenFilter : public TokenFilter +{ +private: + bool bCacheInitialized; + std::list cache; + std::list::iterator itCache; + +public: + CachingTokenFilter( TokenStream * input, bool bDeleteTS ); + virtual ~CachingTokenFilter(); + + Token * next( Token* t ); + void reset(); + void fillCache(); +}; + +CL_NS_END + +#endif // _lucene_analysis_CachingTokenFilter diff --git a/src/core/CLucene/analysis/standard/StandardAnalyzer.cpp b/src/core/CLucene/analysis/standard/StandardAnalyzer.cpp new file mode 100644 index 00000000000..3275c1b449c --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardAnalyzer.cpp @@ -0,0 +1,106 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "StandardAnalyzer.h" + +////#include "CLucene/util/VoidMap.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/analysis/Analyzers.h" +#include "StandardFilter.h" +#include "StandardTokenizer.h" + +CL_NS_USE(util) +CL_NS_USE(analysis) + +CL_NS_DEF2(analysis,standard) + + StandardAnalyzer::StandardAnalyzer(): + stopSet(_CLNEW CLTCSetList(true)), maxTokenLength(DEFAULT_MAX_TOKEN_LENGTH) + { + StopFilter::fillStopTable( stopSet,CL_NS(analysis)::StopAnalyzer::ENGLISH_STOP_WORDS); + } + + StandardAnalyzer::StandardAnalyzer( const TCHAR** stopWords): + stopSet(_CLNEW CLTCSetList(true)), maxTokenLength(DEFAULT_MAX_TOKEN_LENGTH) + { + StopFilter::fillStopTable( stopSet,stopWords ); + } + + StandardAnalyzer::StandardAnalyzer(const char* stopwordsFile, const char* enc): + stopSet(_CLNEW CLTCSetList(true)), maxTokenLength(DEFAULT_MAX_TOKEN_LENGTH) + { + if ( enc == NULL ) + enc = "ASCII"; + WordlistLoader::getWordSet(stopwordsFile, enc, stopSet); + } + + StandardAnalyzer::StandardAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool _bDeleteReader): + stopSet(_CLNEW CLTCSetList(true)), maxTokenLength(DEFAULT_MAX_TOKEN_LENGTH) + { + WordlistLoader::getWordSet(stopwordsReader, stopSet, _bDeleteReader); + } + + class StandardAnalyzer::SavedStreams : public TokenStream { + public: + StandardTokenizer* tokenStream; + TokenStream* filteredTokenStream; + + SavedStreams():tokenStream(NULL), filteredTokenStream(NULL) + { + } + + void close(){} + Token* next(Token* token) {return NULL;} + }; + + StandardAnalyzer::~StandardAnalyzer(){ + SavedStreams* t = reinterpret_cast(this->getPreviousTokenStream()); + if (t) _CLDELETE(t->filteredTokenStream); + _CLLDELETE(stopSet); + } + + + TokenStream* StandardAnalyzer::tokenStream(const TCHAR* /*fieldName*/, Reader* reader) + { + BufferedReader* bufferedReader = reader->__asBufferedReader(); + TokenStream* ret; + + if ( bufferedReader == NULL ) + ret = _CLNEW StandardTokenizer( _CLNEW FilteredBufferedReader(reader, false), true ); + else + ret = _CLNEW StandardTokenizer(bufferedReader); + //ret->setMaxTokenLength(maxTokenLength); + ret = _CLNEW StandardFilter(ret,true); + ret = _CLNEW LowerCaseFilter(ret,true); + ret = _CLNEW StopFilter(ret,true, stopSet); + return ret; + } + + TokenStream* StandardAnalyzer::reusableTokenStream(const TCHAR* fieldName, Reader* reader){ + SavedStreams* streams = reinterpret_cast(getPreviousTokenStream()); + if (streams == NULL) { + streams = _CLNEW SavedStreams(); + setPreviousTokenStream(streams); + + BufferedReader* bufferedReader = reader->__asBufferedReader(); + if ( bufferedReader == NULL ) + streams->tokenStream = _CLNEW StandardTokenizer( _CLNEW FilteredBufferedReader(reader, false), true); + else + streams->tokenStream = _CLNEW StandardTokenizer(bufferedReader); + + streams->filteredTokenStream = _CLNEW StandardFilter(streams->tokenStream, true); + streams->filteredTokenStream = _CLNEW LowerCaseFilter(streams->filteredTokenStream, true); + streams->filteredTokenStream = _CLNEW StopFilter(streams->filteredTokenStream, true, stopSet); + } else { + streams->tokenStream->reset(reader); + } + //streams->tokenStream->setMaxTokenLength(maxTokenLength); + + return streams->filteredTokenStream; + } +CL_NS_END2 diff --git a/src/core/CLucene/analysis/standard/StandardAnalyzer.h b/src/core/CLucene/analysis/standard/StandardAnalyzer.h new file mode 100644 index 00000000000..85e476b0ddf --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardAnalyzer.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_standard_StandardAnalyzer +#define _lucene_analysis_standard_StandardAnalyzer + +CL_CLASS_DEF(util,BufferedReader) +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF2(analysis,standard) + +/** +* Filters {@link lucene::analysis::standard::StandardTokenizer} with {@link lucene::analysis::standard::StandardFilter}, +* {@link lucene::analysis::LowerCaseFilter} and {@link lucene::analysis::StopFilter}, using a list of English stop words. +* +*/ + class CLUCENE_EXPORT StandardAnalyzer : public Analyzer + { + private: + CLTCSetList* stopSet; + int32_t maxTokenLength; + + class SavedStreams; + public: + /** Default maximum allowed token length */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_TOKEN_LENGTH = 255); + + /** Builds an analyzer.*/ + StandardAnalyzer(); + + /** Builds an analyzer with the given stop words. */ + StandardAnalyzer( const TCHAR** stopWords); + + /** Builds an analyzer with the stop words from the given file. + * @see WordlistLoader#getWordSet(File) + */ + StandardAnalyzer(const char* stopwordsFile, const char* enc = NULL); + + /** Builds an analyzer with the stop words from the given reader. + * @see WordlistLoader#getWordSet(Reader) + */ + StandardAnalyzer(CL_NS(util)::Reader* stopwordsReader, const bool _bDeleteReader = false); + + virtual ~StandardAnalyzer(); + + /** + * Constructs a StandardTokenizer filtered by a + * StandardFilter, a LowerCaseFilter and a StopFilter. + */ + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader); + + /** + * Set maximum allowed token length. If a token is seen + * that exceeds this length then it is discarded. This + * setting only takes effect the next time tokenStream or + * reusableTokenStream is called. + */ + void setMaxTokenLength(const int32_t length) { + maxTokenLength = length; + } + + /** + * @see #setMaxTokenLength + */ + int getMaxTokenLength() const { + return maxTokenLength; + } + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/analysis/standard/StandardFilter.cpp b/src/core/CLucene/analysis/standard/StandardFilter.cpp new file mode 100644 index 00000000000..e2e7a05833e --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardFilter.cpp @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "StandardFilter.h" + +#include "../AnalysisHeader.h" +#include "../Analyzers.h" +#include "StandardTokenizerConstants.h" + +CL_NS_USE(analysis) +CL_NS_USE(util) +CL_NS_DEF2(analysis,standard) + + StandardFilter::StandardFilter(TokenStream* in, bool deleteTokenStream): + TokenFilter(in, deleteTokenStream) + { + } + + StandardFilter::~StandardFilter(){ + } + + Token* StandardFilter::next(Token* t) { + if (input->next(t) == NULL) + return NULL; + + TCHAR* text = t->termBuffer(); + const int32_t textLength = t->termLength(); + const TCHAR* type = t->type(); + + if ( type == tokenImage[APOSTROPHE] && //we can compare the type directy since the type should always come from the tokenImage + ( textLength >= 2 && _tcsicmp(text+textLength-2, _T("'s"))==0 ) ) + { + // remove 's + text[textLength-2]=0; + t->resetTermTextLen(); + + return t; + + } else if ( type == tokenImage[ACRONYM] ) { // remove dots + int32_t j = 0; + for ( int32_t i=0;iresetTermTextLen(); + return t; + + } else { + return t; + } + } + +CL_NS_END2 diff --git a/src/core/CLucene/analysis/standard/StandardFilter.h b/src/core/CLucene/analysis/standard/StandardFilter.h new file mode 100644 index 00000000000..9fcd3dea7f3 --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardFilter.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_standard_StandardFilter +#define _lucene_analysis_standard_StandardFilter + + +#include "CLucene/analysis/AnalysisHeader.h" +//#include "../Analyzers.h" +//#include "StandardTokenizerConstants.h" + +CL_CLASS_DEF(util,StringBuffer) + +CL_NS_DEF2(analysis,standard) + + /** Normalizes tokens extracted with {@link lucene::analysis::standard::StandardTokenizer}. */ + class CLUCENE_EXPORT StandardFilter: public TokenFilter{ + public: + // Construct filtering in. + StandardFilter(TokenStream* in, bool deleteTokenStream); + + virtual ~StandardFilter(); + + + /** Returns the next token in the stream, or NULL at EOS. + *

Removes 's from the end of words. + *

Removes dots from acronyms. + */ + Token* next(Token* token); + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/analysis/standard/StandardTokenizer.cpp b/src/core/CLucene/analysis/standard/StandardTokenizer.cpp new file mode 100644 index 00000000000..98d98283b38 --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardTokenizer.cpp @@ -0,0 +1,465 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "StandardTokenizer.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/_FastCharStream.h" +#include "CLucene/util/CLStreams.h" + + +CL_NS_USE(analysis) +CL_NS_USE(util) +CL_NS_DEF2(analysis,standard) + + const TCHAR* tokenImageArray[] = { + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T("") + }; + const TCHAR** tokenImage = tokenImageArray; + + + /* A bunch of shortcut macros, many of which make assumptions about variable + ** names. These macros enhance readability, not just convenience! */ + #define EOS (ch==-1 || rd->Eos()) + #define SPACE (_istspace((TCHAR)ch) != 0) + #define ALPHA (_istalpha((TCHAR)ch) != 0) + #define ALNUM (_istalnum(ch) != 0) + #define DIGIT (_istdigit(ch) != 0) + #define UNDERSCORE (ch == '_') + + #define _CJK ( (ch>=0x3040 && ch<=0x318f) || \ + (ch>=0x3300 && ch<=0x337f) || \ + (ch>=0x3400 && ch<=0x3d2d) || \ + (ch>=0x4e00 && ch<=0x9fff) || \ + (ch>=0xf900 && ch<=0xfaff) || \ + (ch>=0xac00 && ch<=0xd7af) ) //korean + + + #define DASH (ch == '-') + #define NEGATIVE_SIGN_ DASH + //#define POSITIVE_SIGN_ (ch == '+') + //#define SIGN (NEGATIVE_SIGN_ || POSITIVE_SIGN_) + + #define DOT (ch == '.') + #define DECIMAL DOT + + + //freebsd seems to have a problem with defines over multiple lines, so this has to be one long line + #define _CONSUME_AS_LONG_AS(conditionFails) while (true) { ch = readChar(); if (ch==-1 || (!(conditionFails) || str.len >= LUCENE_MAX_WORD_LEN)) { break; } str.appendChar(ch);} + + #define CONSUME_ALPHAS _CONSUME_AS_LONG_AS(ALPHA) + + #define CONSUME_DIGITS _CONSUME_AS_LONG_AS(DIGIT) + + /* otherMatches is a condition (possibly compound) under which a character + ** that's not an ALNUM or UNDERSCORE can be considered not to break the + ** span. Callers should pass false if only ALNUM/UNDERSCORE are acceptable. */ + #define CONSUME_WORD _CONSUME_AS_LONG_AS(ALNUM || UNDERSCORE) + + /* + ** Consume CJK characters + */ + #define CONSUME_CJK _CONSUME_AS_LONG_AS(_CJK) + + + /* It is considered that "nothing of value" has been read if: + ** a) The "read head" hasn't moved since specialCharPos was established. + ** or + ** b) The "read head" has moved by one character, but that character was + ** either whitespace or not among the characters found in the body of + ** a token (deliberately doesn't include the likes of '@'/'&'). */ + #define CONSUMED_NOTHING_OF_VALUE (rdPos == specialCharPos || (rdPos == specialCharPos+1 && ( SPACE || !(ALNUM || DOT || DASH || UNDERSCORE) ))) + + #define RIGHTMOST(sb) (sb.getBuffer()[sb.len-1]) + #define RIGHTMOST_IS(sb, c) (RIGHTMOST(sb) == c) + /* To discard the last character in a StringBuffer, we decrement the buffer's + ** length indicator and move the terminator back by one character. */ + #define SHAVE_RIGHTMOST(sb) (sb.getBuffer()[--sb.len] = '\0') + + //#define REMOVE_TRAILING_CHARS(sb, charMatchesCondition) { TCHAR* sbBuf = sb.getBuffer(); for (int32_t i = sb.len-1; i >= 0; i--) { TCHAR c = sbBuf[i]; if (charMatchesCondition) { sbBuf[--sb.len] = '\0'; } else {break;}}} + + /* Does StringBuffer sb contain any of the characters in string ofThese? */ + #define CONTAINS_ANY(sb, ofThese) (_tcscspn(sb.getBuffer(), _T(ofThese)) != static_cast(sb.len)) + + + StandardTokenizer::StandardTokenizer(BufferedReader* reader, bool deleteReader): + /* rdPos is zero-based. It starts at -1, and will advance to the first + ** position when readChar() is first called. */ + rdPos(-1), + tokenStart(-1), + rd(_CLNEW FastCharStream(reader)) + { + this->reader = reader; + this->deleteReader = deleteReader; + } + + StandardTokenizer::~StandardTokenizer() { + _CLDELETE(rd); + if ( this->deleteReader ) + _CLDELETE(reader); + } + + int StandardTokenizer::readChar() { + /* Increment by 1 because we're speaking in terms of characters, not + ** necessarily bytes: */ + rdPos++; + return rd->GetNext(); + } + + void StandardTokenizer::unReadChar() { + rd->UnGet(); + rdPos--; + } + + inline Token* StandardTokenizer::setToken(Token* t, StringBuffer* sb, TokenTypes tokenCode) { + t->setStartOffset(tokenStart); + t->setEndOffset(tokenStart+sb->length()); + t->setType(tokenImage[tokenCode]); + sb->getBuffer(); //null terminates the buffer + t->resetTermTextLen(); + return t; + } + + void StandardTokenizer::reset(Reader* _input) { + this->input = _input; + if (rd->input==NULL) rd->input = _input->__asBufferedReader(); + rdPos = -1; + tokenStart = -1; + rd->reset(); + } + + Token* StandardTokenizer::next(Token* t) { + int ch=0; + + while (!EOS) { + ch = readChar(); + + if ( ch == 0 || ch == -1 ){ + continue; + } else if (SPACE) { + continue; + } else if (ALPHA || UNDERSCORE) { + tokenStart = rdPos; + t = ReadAlphaNum(ch,t); + if ( t != NULL) return t; + } else if (DIGIT || NEGATIVE_SIGN_ || DECIMAL) { + tokenStart = rdPos; + /* ReadNumber returns NULL if it fails to extract a valid number; in + ** that case, we just continue. */ + if (ReadNumber(NULL, ch,t)) + return t; + } else if ( _CJK ){ + t = ReadCJK(ch,t); + if ( t != NULL ) return t; + } + } + return NULL; + } + + Token* StandardTokenizer::ReadNumber(const TCHAR* previousNumber, const TCHAR prev,Token* t) { + /* previousNumber is only non-NULL if this function already read a complete + ** number in a previous recursion, yet has been asked to read additional + ** numeric segments. For example, in the HOST "192.168.1.3", "192.168" is + ** a complete number, but this function will recurse to read the "1.3", + ** generating a single HOST token "192.168.1.3". */ + t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word + StringBuffer str(t->termBuffer(),t->bufferLength(),true); //use stringbuffer to read data onto the termText + TokenTypes tokenType; + bool decExhausted; + if (previousNumber != NULL) { + str.prepend(previousNumber); + tokenType = CL_NS2(analysis,standard)::HOST; + decExhausted = false; + } else { + tokenType = CL_NS2(analysis,standard)::NUM; + decExhausted = (prev == '.'); + } + if ( str.len >= LUCENE_MAX_WORD_LEN ){ + //if a number is too long, i would say there is no point + //storing it, because its going to be the wrong number anyway? + //what do people think? + return NULL; + } + str.appendChar(prev); + + const bool signExhausted = (prev == '-'); + int ch = prev; + + CONSUME_DIGITS; + + if (str.len < 2 /* CONSUME_DIGITS didn't find any digits. */ + && ( + (signExhausted && !DECIMAL) + || (decExhausted /* && !DIGIT is implied, since CONSUME_DIGITS stopped on a non-digit. */) + ) + ) + { + /* We have either: + ** a) a negative sign that's not followed by either digit(s) or a decimal + ** b) a decimal that's not followed by digit(s) + ** so this is not a valid number. */ + if (!EOS) { + /* Unread the character that stopped CONSUME_DIGITS: */ + unReadChar(); + } + return NULL; + } + + /* We just read a group of digits. Is it followed by a decimal symbol, + ** implying that there might be another group of digits available? */ + if (!EOS) { + if (DECIMAL) { + if ( str.len >= LUCENE_MAX_WORD_LEN ) + return NULL; //read above for rationale + str.appendChar(ch); + } else { + unReadChar(); + goto SUCCESSFULLY_EXTRACTED_NUMBER; + } + + CONSUME_DIGITS; + if (!DIGIT && !DECIMAL) { + unReadChar(); + } else if (!EOS && DECIMAL && _istdigit(rd->Peek())) { + /* We just read the fractional digit group, but it's also followed by + ** a decimal symbol and at least one more digit, so this must be a + ** HOST rather than a real number. */ + return ReadNumber(str.getBuffer(), '.',t); + } + } + + SUCCESSFULLY_EXTRACTED_NUMBER: + TCHAR rightmost = RIGHTMOST(str); + /* Don't including a trailing decimal point. */ + if (rightmost == '.') { + SHAVE_RIGHTMOST(str); + unReadChar(); + rightmost = RIGHTMOST(str); + } + /* If all we have left is a negative sign, it's not a valid number. */ + if (rightmost == '-') { + CND_PRECONDITION (str.len == 1, "Number is invalid"); + return NULL; + } + + return setToken(t,&str,tokenType); + } + + Token* StandardTokenizer::ReadAlphaNum(const TCHAR prev, Token* t) { + t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word + StringBuffer str(t->termBuffer(),t->bufferLength(),true); //use stringbuffer to read data onto the termText + if ( str.len < LUCENE_MAX_WORD_LEN ){ + str.appendChar(prev); + int ch = prev; + + CONSUME_WORD; + if (!EOS && str.len < LUCENE_MAX_WORD_LEN-1 ) { //still have space for 1 more character? + switch(ch) { /* What follows the first alphanum segment? */ + case '.': + str.appendChar('.'); + return ReadDotted(&str, CL_NS2(analysis,standard)::UNKNOWN,t); + case '\'': + str.appendChar('\''); + return ReadApostrophe(&str,t); + case '@': + str.appendChar('@'); + return ReadAt(&str,t); + case '&': + str.appendChar('&'); + return ReadCompany(&str,t); + /* default: fall through to end of this function. */ + } + } + } + return setToken(t,&str,CL_NS2(analysis,standard)::ALPHANUM); + } + + Token* StandardTokenizer::ReadCJK(const TCHAR prev, Token* t) { + t->growBuffer(LUCENE_MAX_WORD_LEN+1);//make sure token can hold the next word + StringBuffer str(t->termBuffer(),t->bufferLength(),true); //use stringbuffer to read data onto the termText + if ( str.len < LUCENE_MAX_WORD_LEN ){ + str.appendChar(prev); + int ch = prev; + + CONSUME_CJK; + } + return setToken(t,&str,CL_NS2(analysis,standard)::CJK); + } + + + Token* StandardTokenizer::ReadDotted(StringBuffer* _str, TokenTypes forcedType, Token* t) { + const int32_t specialCharPos = rdPos; + StringBuffer& str=*_str; + + /* A segment of a "dotted" is not allowed to begin with another dot or a dash. + ** Even though hosts, e-mail addresses, etc., could have a dotted-segment + ** that begins with a dot or a dash, it's far more common in source text + ** for a pattern like "abc.--def" to be intended as two tokens. */ + int ch = rd->Peek(); + if (!(DOT || DASH)) { + bool prevWasDot; + bool prevWasDash; + if (str.len == 0) { + prevWasDot = false; + prevWasDash = false; + } else { + prevWasDot = RIGHTMOST(str) == '.'; + prevWasDash = RIGHTMOST(str) == '-'; + } + while (!EOS && str.len < LUCENE_MAX_WORD_LEN-1 ) { + ch = readChar(); + const bool dot = ch == '.'; + const bool dash = ch == '-'; + + if (!(ALNUM || UNDERSCORE || dot || dash)) { + break; + } + /* Multiple dots or dashes in succession end the token. + ** Consider the following inputs: + ** "Visit windowsupdate.microsoft.com--update today!" + ** "In the U.S.A.--yes, even there!" */ + if ((dot || dash) && (prevWasDot || prevWasDash)) { + /* We're not going to append the character we just read, in any case. + ** As to the character before it (which is currently RIGHTMOST(str)): + ** Unless RIGHTMOST(str) is a dot, in which we need to save it so the + ** acronym-versus-host detection can work, we want to get rid of it. */ + if (!prevWasDot) { + SHAVE_RIGHTMOST(str); + } + break; + } + + str.appendChar(ch); + + prevWasDot = dot; + prevWasDash = dash; + } + } + + /* There's a potential StringBuffer.append call in the code above, which + ** could cause str to reallocate its internal buffer. We must wait to + ** obtain the optimization-oriented strBuf pointer until after the initial + ** potentially realloc-triggering operations on str. + ** Because there can be other such ops much later in this function, strBuf + ** is guarded within a block to prevent its use during or after the calls + ** that would potentially invalidate it. */ + { /* Begin block-guard of strBuf */ + TCHAR* strBuf = str.getBuffer(); + + bool rightmostIsDot = RIGHTMOST_IS(str, '.'); + if (CONSUMED_NOTHING_OF_VALUE) { + /* No more alphanums available for this token; shave trailing dot, if any. */ + if (rightmostIsDot) { + SHAVE_RIGHTMOST(str); + } + /* If there are no dots remaining, this is a generic ALPHANUM. */ + if (_tcschr(strBuf, '.') == NULL) { + forcedType = CL_NS2(analysis,standard)::ALPHANUM; + } + + /* Check the token to see if it's an acronym. An acronym must have a + ** letter in every even slot and a dot in every odd slot, including the + ** last slot (for example, "U.S.A."). */ + } else if (rightmostIsDot) { + bool isAcronym = true; + const int32_t upperCheckLimit = str.len - 1; /* -1 b/c we already checked the last slot. */ + + for (int32_t i = 0; i < upperCheckLimit; i++) { + const bool even = (i % 2 == 0); + ch = strBuf[i]; + if ( (even && !ALPHA) || (!even && !DOT) ) { + isAcronym = false; + break; + } + } + if (isAcronym) { + forcedType = CL_NS2(analysis,standard)::ACRONYM; + } else { + /* If it's not an acronym, we don't want the trailing dot. */ + SHAVE_RIGHTMOST(str); + /* If there are no dots remaining, this is a generic ALPHANUM. */ + if (_tcschr(strBuf, '.') == NULL) { + forcedType = CL_NS2(analysis,standard)::ALPHANUM; + } + } + } + } /* End block-guard of strBuf */ + + if (!EOS) { + if (ch == '@' && str.len < LUCENE_MAX_WORD_LEN-1) { + str.appendChar('@'); + return ReadAt(&str,t); + } else { + unReadChar(); + } + } + + return setToken(t,&str,CL_NS2(analysis,standard)::UNKNOWN + ? forcedType : CL_NS2(analysis,standard)::HOST); + } + + Token* StandardTokenizer::ReadApostrophe(StringBuffer* _str, Token* t) { + StringBuffer& str=*_str; + + TokenTypes tokenType = CL_NS2(analysis,standard)::APOSTROPHE; + const int32_t specialCharPos = rdPos; + int ch=0; + + CONSUME_ALPHAS; + if (RIGHTMOST_IS(str, '\'') || CONSUMED_NOTHING_OF_VALUE) { + /* After the apostrophe, no more alphanums were available within this + ** token; shave trailing apostrophe and revert to generic ALPHANUM. */ + SHAVE_RIGHTMOST(str); + tokenType = CL_NS2(analysis,standard)::ALPHANUM; + } + if (!EOS) { + unReadChar(); + } + + return setToken(t,&str,tokenType); + } + + Token* StandardTokenizer::ReadAt(StringBuffer* str, Token* t) { + ReadDotted(str, CL_NS2(analysis,standard)::EMAIL,t); + /* JLucene grammar indicates dots/digits not allowed in company name: */ + if (!CONTAINS_ANY((*str), ".0123456789")) { + setToken(t,str,CL_NS2(analysis,standard)::COMPANY); + } + return t; + } + + Token* StandardTokenizer::ReadCompany(StringBuffer* _str, Token* t) { + StringBuffer& str = *_str; + const int32_t specialCharPos = rdPos; + int ch=0; + + CONSUME_WORD; + if (CONSUMED_NOTHING_OF_VALUE) { + /* After the ampersand, no more alphanums were available within this + ** token; shave trailing ampersand and revert to ALPHANUM. */ + CND_PRECONDITION(RIGHTMOST_IS(str, '&'),"ReadCompany failed"); + SHAVE_RIGHTMOST(str); + + + return setToken(t,&str,CL_NS2(analysis,standard)::ALPHANUM); + } + if (!EOS) { + unReadChar(); + } + + return setToken(t,&str,CL_NS2(analysis,standard)::COMPANY); + } + +CL_NS_END2 diff --git a/src/core/CLucene/analysis/standard/StandardTokenizer.h b/src/core/CLucene/analysis/standard/StandardTokenizer.h new file mode 100644 index 00000000000..049a4067595 --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardTokenizer.h @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_standard_StandardTokenizer +#define _lucene_analysis_standard_StandardTokenizer + + +#include "../AnalysisHeader.h" //required for Tokenizer +#include "StandardTokenizerConstants.h" +CL_CLASS_DEF(analysis,Token) +CL_CLASS_DEF(util,BufferedReader) +CL_CLASS_DEF(util,StringBuffer) +CL_CLASS_DEF(util,FastCharStream) + +CL_NS_DEF2(analysis,standard) + +/** A grammar-based tokenizer constructed with JavaCC. + * + *

This should be a good tokenizer for most European-language documents: + * + *

    + *
  • Splits words at punctuation characters, removing punctuation. However, a + * dot that's not followed by whitespace is considered part of a token. + *
  • Splits words at hyphens, unless there's a number in the token, in which case + * the whole token is interpreted as a product number and is not split. + *
  • Recognizes email addresses and internet hostnames as one token. + *
+ * + *

Many applications have specific tokenizer needs. If this tokenizer does + * not suit your application, please consider copying this source code + * directory to your project and maintaining your own grammar-based tokenizer. + */ + class CLUCENE_EXPORT StandardTokenizer: public Tokenizer { + private: + int32_t rdPos; + int32_t tokenStart; + + // Advance by one character, incrementing rdPos and returning the character. + int readChar(); + // Retreat by one character, decrementing rdPos. + void unReadChar(); + + // createToken centralizes token creation for auditing purposes. + //Token* createToken(CL_NS(util)::StringBuffer* sb, TokenTypes tokenCode); + inline Token* setToken(Token* t, CL_NS(util)::StringBuffer* sb, TokenTypes tokenCode); + + Token* ReadDotted(CL_NS(util)::StringBuffer* str, TokenTypes forcedType,Token* t); + + CL_NS(util)::BufferedReader* reader; + bool deleteReader; + CL_NS(util)::FastCharStream* rd; + public: + + // Constructs a tokenizer for this Reader. + StandardTokenizer(CL_NS(util)::BufferedReader* reader, bool deleteReader=false); + + virtual ~StandardTokenizer(); + + /** Returns the next token in the stream, or false at end-of-stream. + * The returned token's type is set to an element of + * StandardTokenizerConstants::tokenImage. */ + Token* next(Token* token); + + // Reads for number like "1"/"1234.567", or IP address like "192.168.1.2". + Token* ReadNumber(const TCHAR* previousNumber, const TCHAR prev, Token* t); + + Token* ReadAlphaNum(const TCHAR prev, Token* t); + + // Reads for apostrophe-containing word. + Token* ReadApostrophe(CL_NS(util)::StringBuffer* str, Token* t); + + // Reads for something@... it may be a COMPANY name or a EMAIL address + Token* ReadAt(CL_NS(util)::StringBuffer* str, Token* t); + + // Reads for COMPANY name like AT&T. + Token* ReadCompany(CL_NS(util)::StringBuffer* str, Token* t); + + // Reads CJK characters + Token* ReadCJK(const TCHAR prev, Token* t); + + virtual void reset(CL_NS(util)::Reader* _input); + }; + +CL_NS_END2 +#endif diff --git a/src/core/CLucene/analysis/standard/StandardTokenizerConstants.h b/src/core/CLucene/analysis/standard/StandardTokenizerConstants.h new file mode 100644 index 00000000000..815dd6f6719 --- /dev/null +++ b/src/core/CLucene/analysis/standard/StandardTokenizerConstants.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_analysis_standard_StandardTokenizerConstants +#define _lucene_analysis_standard_StandardTokenizerConstants + +// TODO: Put these into StandardTokenizer +CL_NS_DEF2(analysis,standard) + enum TokenTypes { + _EOF, + UNKNOWN, + ALPHANUM, + APOSTROPHE, + ACRONYM, + COMPANY, + EMAIL, + HOST, + NUM, + CJK + }; + extern const TCHAR** tokenImage; + +CL_NS_END2 +#endif diff --git a/src/core/CLucene/debug/error.cpp b/src/core/CLucene/debug/error.cpp new file mode 100644 index 00000000000..cee0eca3c61 --- /dev/null +++ b/src/core/CLucene/debug/error.cpp @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_SharedHeader.h" +#include "error.h" +#include "CLucene/util/Misc.h" +CL_NS_USE(util) + + +#ifdef _LUCENE_DISABLE_EXCEPTIONS + #ifdef _LUCENE_PRAGMA_WARNINGS + #pragma message ("==================Lucene exceptions are disabled==================") + #else + #warning "==================Lucene exceptions are disabled==================" + #endif +#else + CLuceneError::CLuceneError():_twhat(NULL),error_number(0){ +#ifndef _ASCII + _awhat = NULL; +#endif + } + CLuceneError::CLuceneError(int num, const char* str, bool ownstr):error_number(num) + { +#ifdef _ASCII + _twhat=STRDUP_AtoA(str); + +#else + _awhat=STRDUP_AtoA(str); + _twhat=NULL; +#endif + if ( ownstr ) + _CLDELETE_LCaARRAY( const_cast(str)); + } + +#ifndef _ASCII + CLuceneError::CLuceneError(int num, const TCHAR* str, bool ownstr) + { + error_number = num; + _awhat=NULL; + _twhat=STRDUP_TtoT(str); + if ( ownstr ) + _CLDELETE_LCARRAY((TCHAR*)str); + } +#endif + + CLuceneError::CLuceneError(const CLuceneError& clone) + { + this->error_number = clone.error_number; +#ifndef _ASCII + this->_awhat = NULL; + if ( clone._awhat != NULL ) + this->_awhat = STRDUP_AtoA(clone._awhat); +#endif + this->_twhat = NULL; + if ( clone._twhat != NULL ) + this->_twhat = STRDUP_TtoT(clone._twhat); + } + CLuceneError::~CLuceneError() throw(){ + _CLDELETE_LCARRAY(_twhat); +#ifndef _ASCII + _CLDELETE_LCaARRAY(_awhat); +#endif + } + const char* CLuceneError::what() const throw() { +#ifdef _ASCII + return _twhat; +#else + if ( _awhat == NULL ) + return STRDUP_TtoA(_twhat); + return _awhat; +#endif + } + TCHAR* CLuceneError::twhat(){ +#ifdef _ASCII + return _twhat; +#else + if ( _twhat == NULL ) + _twhat = STRDUP_AtoT(_awhat); + return _twhat; +#endif + } + +#ifndef _ASCII + void CLuceneError::set(int num, const char* str, bool ownstr){ + _CLDELETE_CARRAY(_twhat); + _CLDELETE_CaARRAY(_awhat); + _awhat=STRDUP_AtoA(str); + error_number = num; + if ( ownstr ) + _CLDELETE_LCaARRAY( const_cast(str)); + } +#endif + + void CLuceneError::set(int num, const TCHAR* str, bool ownstr){ +#ifndef _ASCII + _CLDELETE_CaARRAY(_awhat); +#endif + _CLDELETE_CARRAY(_twhat); + _twhat=STRDUP_TtoT(str); + error_number = num; + if ( ownstr ) + _CLDELETE_LCARRAY(const_cast(str)); + } + +#endif //_LUCENE_DISABLE_EXCEPTIONS diff --git a/src/core/CLucene/debug/error.h b/src/core/CLucene/debug/error.h new file mode 100644 index 00000000000..821d9e13d71 --- /dev/null +++ b/src/core/CLucene/debug/error.h @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_debug_error_ +#define _lucene_debug_error_ + + +#define CL_ERR_UNKNOWN -1 +#define CL_ERR_IO 1 +#define CL_ERR_NullPointer 2 +#define CL_ERR_Runtime 3 +#define CL_ERR_IllegalArgument 4 +#define CL_ERR_Parse 5 +#define CL_ERR_TokenMgr 6 +#define CL_ERR_UnsupportedOperation 7 +#define CL_ERR_InvalidState 8 +#define CL_ERR_IndexOutOfBounds 9 +#define CL_ERR_TooManyClauses 10 +#define CL_ERR_RAMTransaction 11 +#define CL_ERR_InvalidCast 12 +#define CL_ERR_IllegalState 13 // Sub-error: AlreadyClosed +#define CL_ERR_UnknownOperator 14 +#define CL_ERR_ConcurrentModification 15 +#define CL_ERR_CorruptIndex 16 +#define CL_ERR_NumberFormat 17 +#define CL_ERR_AlreadyClosed 18 +#define CL_ERR_StaleReader 19 +#define CL_ERR_LockObtainFailed 20 +#define CL_ERR_Merge 21 //< Exception thrown if there are any problems while executing a merge. +#define CL_ERR_MergeAborted 22 +#define CL_ERR_OutOfMemory 23 +#define CL_ERR_FieldReader 24 + +//////////////////////////////////////////////////////// +//error try/throw/catch definitions +//////////////////////////////////////////////////////// +#ifdef _CL_DISABLE_NATIVE_EXCEPTIONS + #include + + /* + #define try struct pj_exception_state_t pj_x_except__; int pj_x_code__; \ + if(1){ \ + pj_push_exception_handler_(&pj_x_except__); \ + pj_x_code__ = pj_setjmp(pj_x_except__.state); \ + if (pj_x_code__ == 0) + #define _CLCATCHEND pj_pop_exception_handler_(); \ + } else {} + #define _CLCATCH else if (pj_x_code__ == (id)) _CLCATCHEND + #define _CLCATCHANY else _CLCATCHEND + #define _RETHROW pj_throw_exception_(pj_x_code__) + + #define _CLFINALLY(x) else{x _RETHROW}_CLCATCHEND x + #define _CLTHROWA(number) pj_throw_exception_(number) + #define _CLTHROWT(number) pj_throw_exception_(number) + #define _THROWA_DEL(number) _CLDELETE_CaARRAY(str); pj_throw_exception_(number) + #define _THROWT_DEL(number) _CLDELETE_CARRAY(str); pj_throw_exception_(number) + + */ +#else +class CLUCENE_EXPORT CLuceneError : public std::exception +{ +#ifndef _ASCII + char* _awhat; +#endif + TCHAR* _twhat; + int error_number; +public: + CLuceneError(); + CLuceneError(const CLuceneError& clone); +#ifndef _ASCII + CLuceneError(int num, const char* str, bool ownstr); +#endif + CLuceneError(int num, const TCHAR* str, bool ownstr); + int number() const{return error_number;} + virtual const char* what() const throw(); + TCHAR* twhat(); + ~CLuceneError() throw(); + + void set(int num, const TCHAR*, bool ownstr=false); +#ifndef _ASCII + void set(int num, const char*, bool ownstr=false); +#endif +}; + + //#define _THROWS //does nothing + #define _TRY try + #define _CLCATCH_ERR(err_num, cleanup_code, else_code) catch(CLuceneError& err){if (err.number()!=err_num){cleanup_code;throw err;}else {else_code;}} + #define _CLCATCH_ERR_ELSE(err_num, else_code) catch(CLuceneError& err){if (err.number()!=err_num){throw err;}else {else_code;}} + #define _CLCATCH_ERR_CLEANUP(err_num, cleanup_code) catch(CLuceneError& err){if (err.number()!=err_num){cleanup_code;throw err;}} + #define _CLFINALLY(x) catch(...){ x; throw; } x //note: code x is not run if return is called + #define _CLTHROWA(number, str) throw CLuceneError(number, str,false) + #define _CLTHROWT(number, str) throw CLuceneError(number, str,false) + #define _CLTHROWA_DEL(number, str) throw CLuceneError(number, str,true) //throw a string ensures the value is deleted + #define _CLTHROWT_DEL(number, str) throw CLuceneError(number, str,true) //throw a string ensures the value is deleted + #define _CLTHROW_NOT_IMPLEMENT {char buffer[50];sprintf(buffer, "%s not implemented",__func__);_CLTHROWA(CL_ERR_UnsupportedOperation, buffer);} + + +#endif //_LUCENE_DISABLE_EXCEPTIONS +// +//////////////////////////////////////////////////////// + +#endif diff --git a/src/core/CLucene/debug/lucenebase.h b/src/core/CLucene/debug/lucenebase.h new file mode 100644 index 00000000000..c053f110d8e --- /dev/null +++ b/src/core/CLucene/debug/lucenebase.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_debug_lucenebase_ +#define _lucene_debug_lucenebase_ + +#include "CLucene/LuceneThreads.h" + +CL_NS_DEF(debug) + +//Lucenebase is the superclass of all clucene objects. It provides +//memory debugging tracking and/or reference counting +class CLUCENE_EXPORT LuceneBase{ +public: + _LUCENE_ATOMIC_INT __cl_refcount; + LuceneBase(){ + _LUCENE_ATOMIC_INT_SET(__cl_refcount,1); + } + inline int __cl_getref(){ + return _LUCENE_ATOMIC_INT_GET(__cl_refcount); + } + inline int __cl_addref(){ return _LUCENE_ATOMIC_INC(&__cl_refcount); } + inline int __cl_decref(){ return _LUCENE_ATOMIC_DEC(&__cl_refcount); } + virtual ~LuceneBase(){}; +}; + +class CLUCENE_EXPORT LuceneVoidBase{ + public: + virtual ~LuceneVoidBase(){}; +}; + +#if defined(LUCENE_ENABLE_REFCOUNT) + #define LUCENE_BASE public CL_NS(debug)::LuceneBase +#else + #define LUCENE_BASE public CL_NS(debug)::LuceneVoidBase +#endif +#define LUCENE_REFBASE public CL_NS(debug)::LuceneBase //this is the base of classes who *always* need refcounting + + +CL_NS_END +#endif //_lucene_debug_lucenebase_ diff --git a/src/core/CLucene/debug/mem.h b/src/core/CLucene/debug/mem.h new file mode 100644 index 00000000000..98038b58740 --- /dev/null +++ b/src/core/CLucene/debug/mem.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_debug_mem_h +#define _lucene_debug_mem_h + +//todo: this is a hack... +#ifndef CND_PRECONDITION + #include + #define CND_PRECONDITION(x,y) assert(x) +#endif + +//Macro for creating new objects +#if defined(LUCENE_ENABLE_REFCOUNT) + #define _CLNEW new +#else + #define _CLNEW new +#endif +#define _CL_POINTER(x) (x==NULL?NULL:(x->__cl_addref()>=0?x:x)) //return a add-ref'd object +#define _CL_DECREF(x) ((x)==NULL?NULL:((x)->__cl_decref()>=0?(x):(x))) //return a add-ref'd object +#define _CL_LDECREF(x) if ((x)!=NULL) (x)->__cl_decref(); + +//Macro for creating new arrays +#define _CL_NEWARRAY(type,size) (type*)calloc(size, sizeof(type)) +#define _CLDELETE_ARRAY(x) {free(x); x=NULL;} +#define _CLDELETE_LARRAY(x) {free(x);} +#ifndef _CLDELETE_CARRAY + #define _CLDELETE_CARRAY(x) {free(x); x=NULL;} + #define _CLDELETE_LCARRAY(x) {free(x);} +#endif + +//a shortcut for deleting a carray and all its contents +#define _CLDELETE_CARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE_CARRAY(x[xcda]);}_CLDELETE_ARRAY(x)}; +#define _CLDELETE_LCARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE_LCARRAY(x[xcda]);}_CLDELETE_LARRAY(x)}; +#define _CLDELETE_CaARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE_CaARRAY(x[xcda]);}_CLDELETE_ARRAY(x)}; +#define _CLDELETE_ARRAY_ALL(x) {if ( x!=NULL ){ for(int xcda=0;x[xcda]!=NULL;xcda++)_CLDELETE(x[xcda]);}_CLDELETE_ARRAY(x)}; +#ifndef _CLDELETE_CaARRAY + #define _CLDELETE_CaARRAY _CLDELETE_CARRAY + #define _CLDELETE_LCaARRAY _CLDELETE_LCARRAY +#endif + +//Macro for deleting +#ifdef LUCENE_ENABLE_REFCOUNT + #define _CLDELETE(x) if (x!=NULL){ CND_PRECONDITION(_LUCENE_ATOMIC_INT_GET((x)->__cl_refcount)>=0,"__cl_refcount was < 0"); if (_LUCENE_ATOMIC_INT_GET((x)->__cl_decref()) <= 0)delete x; x=NULL; } + #define _CLLDELETE(x) if (x!=NULL){ CND_PRECONDITION(_LUCENE_ATOMIC_INT_GET((x)->__cl_refcount)>=0,"__cl_refcount was < 0"); if ((x)->__cl_decref() <= 0)delete x; } +#else + #define _CLDELETE(x) {delete x;x=NULL;} + #define _CLLDELETE(x) {delete x;} +#endif + +//_CLDECDELETE deletes objects which are *always* refcounted +#define _CLDECDELETE(x) if (x!=NULL){ CND_PRECONDITION(_LUCENE_ATOMIC_INT_GET((x)->__cl_refcount)>=0,"__cl_refcount was < 0"); _LUCENE_ATOMIC_DECDELETE(&(x)->__cl_refcount, x); x=NULL; } +#define _CLLDECDELETE(x) if (x!=NULL){ CND_PRECONDITION(_LUCENE_ATOMIC_INT_GET((x)->__cl_refcount)>=0,"__cl_refcount was < 0"); _LUCENE_ATOMIC_DECDELETE(&(x)->__cl_refcount, x); } +#define _LUCENE_ATOMIC_DECDELETE(theInteger, theObject) { if ( _LUCENE_ATOMIC_DEC(theInteger) == 0) delete theObject;} + +//_VDelete should be used for deleting non-clucene objects. +//when using reference counting, _CLDELETE casts the object +//into a LuceneBase*. +#define _CLVDELETE(x) {delete x;x=NULL;} + +#endif //_lucene_debug_mem_h diff --git a/src/core/CLucene/document/DateField.cpp b/src/core/CLucene/document/DateField.cpp new file mode 100644 index 00000000000..f0c59cf9572 --- /dev/null +++ b/src/core/CLucene/document/DateField.cpp @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "DateField.h" +#include "CLucene/util/Misc.h" + +CL_NS_USE(util) +CL_NS_DEF(document) + +DateField::~DateField(){ +} + +TCHAR* DateField::timeToString(const int64_t time) { + TCHAR* buf = _CL_NEWARRAY(TCHAR,DATEFIELD_DATE_LEN + 1); + timeToString(time,buf); + return buf; +} +void DateField::timeToString(const int64_t time, TCHAR* buf) { + CND_PRECONDITION (buf, "buf == NULL"); + *buf = '\0'; + if (time < 0) + _CLTHROWA (CL_ERR_IllegalArgument,"time too early"); //todo: make richer error + + if (time > DATEFIELD_DATE_MAX) + _CLTHROWA (CL_ERR_IllegalArgument, "time too late (past DATEFIELD_DATE_MAX"); //todo: make richer error + + _i64tot(time, buf, 36); + int32_t bufLen = _tcslen(buf); + + CND_PRECONDITION (bufLen <= DATEFIELD_DATE_LEN, "timeToString length is greater than 9"); + + /* Supply leading zeroes if necessary. */ + if (bufLen < DATEFIELD_DATE_LEN) { + const int32_t nMissingZeroes = DATEFIELD_DATE_LEN - bufLen; + /* Move buffer contents forward to make room for leading zeroes. */ + for (int32_t i = DATEFIELD_DATE_LEN - 1; i >= nMissingZeroes; i--) + buf[i] = buf[i - nMissingZeroes]; + + /* Insert leading zeroes. */ + {// MSVC6 scoping fix + for (int32_t i = 0; i < nMissingZeroes; i++) + buf[i] = '0'; + } + + buf[DATEFIELD_DATE_LEN] = 0; + } + + CND_PRECONDITION (_tcslen(buf) == DATEFIELD_DATE_LEN, "timeToString return is not equal to DATEFIELD_DATE_LEN"); +} + +int64_t DateField::stringToTime(const TCHAR* time) { + TCHAR* end; + return _tcstoi64(time, &end, 36); +} + +CL_NS_END diff --git a/src/core/CLucene/document/DateField.h b/src/core/CLucene/document/DateField.h new file mode 100644 index 00000000000..e309dc3d207 --- /dev/null +++ b/src/core/CLucene/document/DateField.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_document_DateField_ +#define _lucene_document_DateField_ + + +CL_NS_DEF(document) + +//here are some constants used throughout clucene +//make date strings long enough to last a millenium +#define DATEFIELD_DATE_MAX _ILONGLONG(31536000000000) //1000L*365*24*60*60*1000 + +/** +* Provides support for converting dates to strings and vice-versa. +* The strings are structured so that lexicographic sorting orders by date, +* which makes them suitable for use as field values and search terms. +* +*

Note that this class saves dates with millisecond granularity, +* which is bad for {@link lucene::search::RangeQuery} and {@link lucene::search::PrefixQuery}, as those +* queries are expanded to a BooleanQuery with a potentially large number +* of terms when searching. Thus you might want to use +* {@link lucene::document::DateTools} instead. +* +*

+* Note: dates before 1970 cannot be used, and therefore cannot be +* indexed when using this class. See {@link lucene::document::DateTools} for an +* alternative without such a limitation. +* +* @deprecated If you build a new index, use {@link lucene::document::DateTools} instead. +* This class is included for use with existing indices and will be removed in a future release. +*/ +class CLUCENE_EXPORT DateField { +public: + virtual ~DateField(); + + /** + * Converts a millisecond time to a string suitable for indexing. + * @throws RuntimeException if the time specified in the + * method argument is negative, that is, before 1970 + */ + _CL_DEPRECATED( DateTools ) static TCHAR* timeToString(const int64_t time); + + /** + * Converts a millisecond time to a string suitable for indexing. + * @throws CL_ERR_IllegalArgument if the time specified in the + * method argument is negative, that is, before 1970 + * @param str must be a character array DATEFIELD_DATE_LEN+1 or longer + */ + _CL_DEPRECATED( DateTools ) static void timeToString(const int64_t time, TCHAR* str); + + /** Converts a string-encoded date into a millisecond time. */ + _CL_DEPRECATED( DateTools ) static int64_t stringToTime(const TCHAR* s); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/document/DateTools.cpp b/src/core/CLucene/document/DateTools.cpp new file mode 100644 index 00000000000..311d89345e1 --- /dev/null +++ b/src/core/CLucene/document/DateTools.cpp @@ -0,0 +1,292 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "DateTools.h" +#include "CLucene/util/Misc.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(document) + +//asctime(), ctime(), gmtime() localtime() ==> +//asctime_r(), ctime_r(),gmtime_r() localtime_r() +TCHAR* DateTools::timeToString(const int64_t time, Resolution resolution /*= MILLISECOND_FORMAT*/) { + TCHAR* buf = _CL_NEWARRAY(TCHAR, DATETOOLS_BUFFER_SIZE); + timeToString(time, resolution, buf, DATETOOLS_BUFFER_SIZE); + return buf; +} + +void DateTools::timeToString(const int64_t time, Resolution resolution, TCHAR* buf, size_t bufLength) +{ + // Take into account TZ and DST differences which may appear when using gmtime below + const int64_t diff_secs = getDifferenceFromGMT(); + time_t secs = time / 1000 + diff_secs; + tm tm_s; + tm *ptm = &tm_s; + gmtime_r(&secs, ptm); + + char abuf[DATETOOLS_BUFFER_SIZE]; + + if (resolution == MILLISECOND_FORMAT) { + size_t len = strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m%d%H%M%S", ptm); + uint32_t ms = static_cast(time % 1000); + _snprintf(abuf + len, 4, "%03u", ms); + } else if (resolution == SECOND_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m%d%H%M%S", ptm); + } else if (resolution == MINUTE_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m%d%H%M", ptm); + } else if (resolution == YEAR_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y", ptm); + } else if (resolution == MONTH_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m", ptm); + } else if (resolution == DAY_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m%d", ptm); + } else if (resolution == HOUR_FORMAT) { + strftime(abuf, DATETOOLS_BUFFER_SIZE, "%Y%m%d%H", ptm); + } + + STRCPY_AtoT(buf,abuf, bufLength); +} + +tm* DateTools::stringToDate(const TCHAR* dateString){ + const int64_t time = stringToTime(dateString); + time_t secs = time / 1000; + tm *ptm = gmtime(&secs); + return ptm; +} + +int64_t DateTools::stringToTime(const TCHAR* dateString, bool add_local, bool fill_date) { + tm s_time; + memset(&s_time, 0, sizeof (s_time)); + s_time.tm_mday = 1; + int32_t ms = 0; + + switch (_tcslen(dateString)) { + case 4: // YEAR_FORMAT + { + s_time.tm_year = _ttoi(dateString) - 1900; + if (s_time.tm_year == -1900) + _CLTHROWA(CL_ERR_Parse, "Input is not valid date string"); + break; + } + case 6: // MONTH_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + break; + } + case 8: // DAY_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + s_time.tm_mday = _ttoi(&tmpDate[6]); + tmpDate[6] = 0; + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + if(fill_date) + { + s_time.tm_hour = 23; + s_time.tm_min = 59; + s_time.tm_sec = 59; + } + break; + } + case 10: // HOUR_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + s_time.tm_hour = _ttoi(&tmpDate[8]); + tmpDate[8] = 0; + s_time.tm_mday = _ttoi(&tmpDate[6]); + tmpDate[6] = 0; + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + break; + } + case 12: // MINUTE_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + s_time.tm_min = _ttoi(&tmpDate[10]); + tmpDate[10] = 0; + s_time.tm_hour = _ttoi(&tmpDate[8]); + tmpDate[8] = 0; + s_time.tm_mday = _ttoi(&tmpDate[6]); + tmpDate[6] = 0; + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + break; + } + case 14: // SECOND_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + s_time.tm_sec = _ttoi(&tmpDate[12]); + tmpDate[12] = 0; + s_time.tm_min = _ttoi(&tmpDate[10]); + tmpDate[10] = 0; + s_time.tm_hour = _ttoi(&tmpDate[8]); + tmpDate[8] = 0; + s_time.tm_mday = _ttoi(&tmpDate[6]); + tmpDate[6] = 0; + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + break; + } + case 17: // MILLISECOND_FORMAT + { + TCHAR* tmpDate = STRDUP_TtoT(dateString); + ms = _ttoi(&tmpDate[14]); + tmpDate[14] = 0; + s_time.tm_sec = _ttoi(&tmpDate[12]); + tmpDate[12] = 0; + s_time.tm_min = _ttoi(&tmpDate[10]); + tmpDate[10] = 0; + s_time.tm_hour = _ttoi(&tmpDate[8]); + tmpDate[8] = 0; + s_time.tm_mday = _ttoi(&tmpDate[6]); + tmpDate[6] = 0; + s_time.tm_mon = _ttoi(&tmpDate[4]) - 1; + tmpDate[4] = 0; + s_time.tm_year = _ttoi(tmpDate) - 1900; + _CLDELETE_CARRAY(tmpDate); + break; + } + default: + { + _CLTHROWA(CL_ERR_Parse, "Input is not valid date string"); + break; + } + } + + time_t t = mktime(&s_time); + if (t == -1) + _CLTHROWA(CL_ERR_Parse, "Input is not valid date string"); + + // Get TZ difference in seconds, and calc it in + const int64_t diff_secs = add_local ? getDifferenceFromGMT() : 0; + + return (static_cast(t + diff_secs) * 1000) + ms; +} + +int64_t DateTools::getDifferenceFromGMT() +{ + if(SecondsDifferenceFromGMT!=0) + return SecondsDifferenceFromGMT; + + if(SecondsDifferenceFromGMT==0) + { + struct tm tm_s; + struct tm *tptr=&tm_s; + time_t secs, local_secs, gmt_secs; + time(&secs); // Current time in GMT + localtime_r(&secs, tptr); + local_secs = mktime(tptr); + gmtime_r(&secs, tptr); + gmt_secs = mktime(tptr); + SecondsDifferenceFromGMT = int64_t(local_secs - gmt_secs); + } + + return SecondsDifferenceFromGMT; +} + +int64_t DateTools::timeMakeInclusive(const int64_t time) +{ + time_t secs = time / 1000; + tm *ptm = localtime(&secs); // use localtime since mktime below will convert the time to GMT before returning + ptm->tm_hour = 23; + ptm->tm_min = 59; + ptm->tm_sec = 59; + + time_t t = mktime(ptm); + if (t == -1) + _CLTHROWA(CL_ERR_Parse, "Input is not a valid date"); + + return (static_cast(t) * 1000) + 999; +} + +int64_t DateTools::getTime(unsigned short year, uint8_t month, uint8_t mday, uint8_t hours, + uint8_t minutes, uint8_t seconds, unsigned short ms) +{ + struct tm* s_time; + + // get current time, and then change it according to the parameters + time_t rawtime; + time ( &rawtime ); + s_time = localtime ( &rawtime ); // use localtime, since mktime will take into account TZ differences + s_time->tm_isdst = 0; // since we are using gmtime all around, make sure DST is off + + s_time->tm_year = year - 1900; + s_time->tm_mon = month - 1; + s_time->tm_mday = mday; + s_time->tm_hour = hours; + s_time->tm_min = minutes; + s_time->tm_sec = seconds; + + time_t t = mktime(s_time); + if (t == -1) + _CLTHROWA(CL_ERR_Parse, "Input is not a valid date"); + + return (static_cast(t) * 1000) + ms; +} + +TCHAR* DateTools::getISOFormat(const int64_t time){ + const time_t secs = time / 1000; + const int64_t ms = abs((int32_t)((secs * 1000) - time)); + tm *ptm = gmtime(&secs); + return getISOFormat(ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, + ptm->tm_sec, ms); +} + +void DateTools::strCatDate(TCHAR* buf, int zeroes, int value){ + TCHAR str[10]; + _i64tot(value, str, 10); + size_t l = _tcslen(str); + + TCHAR* p = buf; + for ( size_t i=0;i<(zeroes-l);i++ ){ + *p = _T('0'); + p++; + } + _tcscat(p, str); + p+=l; + *p = _T('\0'); +} +TCHAR* DateTools::getISOFormat(unsigned short year, uint8_t month, uint8_t mday, uint8_t hours, + uint8_t minutes, uint8_t seconds, unsigned short ms) +{ + TCHAR* ISOString = _CL_NEWARRAY(TCHAR, 24); + TCHAR* p = ISOString; + strCatDate(p, 4, year); p+=4; + _tcscat(p, _T("-")); p++; + strCatDate(p, 2, month); p+=2; + _tcscat(p, _T("-")); p++; + strCatDate(p, 2, mday); p+=2; + _tcscat(p, _T(" ")); p++; + strCatDate(p, 2, hours); p+=2; + _tcscat(p, _T(":")); p++; + strCatDate(p, 2, minutes); p+=2; + _tcscat(p, _T(":")); p++; + strCatDate(p, 2, seconds); p+=2; + _tcscat(p, _T(":")); p++; + strCatDate(p, 3, ms); p+=3; + + return ISOString; +} + +DateTools::~DateTools(){ +} + +CL_NS_END diff --git a/src/core/CLucene/document/DateTools.h b/src/core/CLucene/document/DateTools.h new file mode 100644 index 00000000000..38070980e68 --- /dev/null +++ b/src/core/CLucene/document/DateTools.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_document_DateTools_ +#define _lucene_document_DateTools_ + +#ifdef _CL_TIME_WITH_SYS_TIME +# include +# include +#else +# if defined(_CL_HAVE_SYS_TIME_H) +# include +# else +# include +# endif +#endif + +#ifdef _CL_HAVE_SYS_TIMEB_H +# include +#endif + +CL_NS_DEF(document) + +class CLUCENE_EXPORT DateTools { +private: + static void strCatDate(TCHAR* buf, int zeroes, int value); +public: + + enum Resolution { + NO_RESOLUTION, + YEAR_FORMAT, // yyyy + MONTH_FORMAT, // yyyyMM + DAY_FORMAT, // yyyyMMdd + HOUR_FORMAT, // yyyyMMddHH + MINUTE_FORMAT, // yyyyMMddHHmm + SECOND_FORMAT, // yyyyMMddHHmmss + MILLISECOND_FORMAT // yyyyMMddHHmmssSSS + }; + + /** + * Converts a millisecond time to a string suitable for indexing. + * + * @param time the date expressed as milliseconds since January 1, 1970, 00:00:00 GMT + * @param resolution the desired resolution, see {@link #Resolution} + * @return a string in format yyyyMMddHHmmssSSS or shorter, + * depeding on resolution; using UTC as timezone + */ + static TCHAR* timeToString(const int64_t time, Resolution resolution = MILLISECOND_FORMAT); + + static void timeToString(const int64_t time, Resolution resolution, TCHAR* buf, size_t bufLength); + + /** + * Converts a string produced by timeToString or + * dateToString back to a time, represented as the + * number of milliseconds since January 1, 1970, 00:00:00 GMT. + * + * @param dateString the date string to be converted + * @add_local when calling stringToTime+timeToString together, set it to false avoid double add + * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT + * @throws ParseException if dateString is not in the + * expected format + */ + static int64_t stringToTime(const TCHAR* dateString, bool add_local=true, bool fill_date=false); + + static tm* stringToDate(const TCHAR* dateString); + + /**** + + * CLucene specific methods + + *****/ + + /** + * Returns a 64bit time value based on the parameters passed + */ + static int64_t getTime(unsigned short year, uint8_t month, uint8_t mday, uint8_t hours = 0, + uint8_t minutes = 0, uint8_t seconds = 0, unsigned short ms = 0); + + /** + * Returns a 64bit time value which is inclusive of the whole last day. + * Only be called when time consisting date (no time) only: + * The user can only specify the date, not the time, so make sure + * the time is set to the latest possible time of that date to really + */ + static int64_t timeMakeInclusive(const int64_t time); + + inline static int64_t getDifferenceFromGMT(); + inline static int64_t SecondsDifferenceFromGMT = 0; + + static TCHAR* getISOFormat(const int64_t time); + static TCHAR* getISOFormat(unsigned short year, uint8_t month, uint8_t mday, uint8_t hours = 0, + uint8_t minutes = 0, uint8_t seconds = 0, unsigned short ms = 0); + + virtual ~DateTools(); + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/document/Document.cpp b/src/core/CLucene/document/Document.cpp new file mode 100644 index 00000000000..69ba2af1201 --- /dev/null +++ b/src/core/CLucene/document/Document.cpp @@ -0,0 +1,183 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Document.h" +#include "Field.h" +#include "CLucene/util/StringBuffer.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(document) + + + struct DocumentFieldEnumeration::Internal { + Document::FieldsType::iterator itr; + Document::FieldsType::iterator end; + }; + DocumentFieldEnumeration::DocumentFieldEnumeration(Document::FieldsType::iterator itr, Document::FieldsType::iterator end){ + this->_internal = new DocumentFieldEnumeration::Internal; + this->_internal->itr = itr; + this->_internal->end = end; + } + + bool DocumentFieldEnumeration::hasMoreElements() const { + return _internal->itr != _internal->end; + } + + Field* DocumentFieldEnumeration::nextElement() { + //Func - Return the next element in the enumeration + //Pre - true + //Post - The next element is returned or NULL + + Field* result = NULL; + if ( _internal->itr != _internal->end ){ + result = *_internal->itr; + _internal->itr++; + } + return result; + } + + DocumentFieldEnumeration::~DocumentFieldEnumeration(){ + //Func - Destructor + //Pre - true + //Post - Instance has been destroyed + delete _internal; + } + DocumentFieldEnumeration* Document::fields() { + return _CLNEW DocumentFieldEnumeration(_fields->begin(), _fields->end()); + } + + /** Constructs a new document with no fields-> */ + Document::Document(): + _fields(_CLNEW FieldsType(true) ) + { + //Func - Constructor + //Pre - true + //Post - Instance has been created + boost = 1.0f; + } + + Document::~Document(){ + //Func - Destructor + //Pre - true + //Post - Instance has been destroyed + boost = 1.0f; + _CLDELETE(_fields); + } + + void Document::clear(){ + _fields->clear(); + } + + void Document::add(Field& field) { + _fields->push_back(&field); + } + + void Document::setBoost(const float_t boost) { + this->boost = boost; + } + + float_t Document::getBoost() const { + return boost; + } + + + Field* Document::getField(const TCHAR* name) const{ + CND_PRECONDITION(name != NULL, "name is NULL"); + for ( FieldsType::const_iterator itr = _fields->begin(); + itr != _fields->end(); itr ++ ){ + if ( _tcscmp( (*itr)->name(),name)==0 ) + return *itr; + } + return NULL; + } + const TCHAR* Document::get(const TCHAR* field) const { + CND_PRECONDITION(field != NULL, "field is NULL"); + Field* f = getField(field); + if (f!=NULL) + return f->stringValue(); //this returns null it is a binary(reader) + else + return NULL; + } + + const Document::FieldsType* Document::getFields() const { + return _fields; + } + + + TCHAR* Document::toString() const { + StringBuffer ret(_T("Document<")); + for (FieldsType::const_iterator itr = _fields->begin(); + itr != _fields->end(); itr++ ) { + TCHAR* tmp = (*itr)->toString(); + if ( ret.len > 0 ) + ret.append(_T(" ")); + ret.append( tmp ); + _CLDELETE_ARRAY( tmp ); + } + ret.append(_T(">")); + return ret.toString(); + } + + + + void Document::removeField(const TCHAR* name) { + CND_PRECONDITION(name != NULL, "name is NULL"); + + for ( FieldsType::iterator itr = _fields->begin(); + itr != _fields->end(); itr++ ){ + + if ( _tcscmp( (*itr)->name(), name) == 0 ){ + _fields->remove(itr); + return; + } + } + } + + void Document::removeFields(const TCHAR* name) { + CND_PRECONDITION(name != NULL, "name is NULL"); + bool flag = true; + //TODO: make this more efficient + while(flag){ + for ( FieldsType::iterator itr = _fields->begin(); + itr != _fields->end(); itr++ ){ + if ( _tcscmp( (*itr)->name(), name) == 0 ){ + _fields->remove(itr); + flag = false; //no modifications allowed on an iterator + break; + } + } + flag = !flag; + } + } + + TCHAR** Document::getValues(const TCHAR* name) { + int count = 0; + for ( FieldsType::iterator itr = _fields->begin(); + itr != _fields->end(); itr++ ){ + if ( _tcscmp( (*itr)->name(),name) == 0 && (*itr)->stringValue() != NULL ) + count++; + } + + //todo: there must be a better way of doing this, we are doing two iterations of the fields + TCHAR** ret = NULL; + if ( count > 0 ){ + ret = _CL_NEWARRAY(TCHAR*,count+1); + int32_t i=0; + for ( FieldsType::iterator itr = _fields->begin(); + itr != _fields->end(); itr++ ){ + + if ( _tcscmp( (*itr)->name(),name) == 0 && (*itr)->stringValue() != NULL ){ + ret[i] = stringDuplicate((*itr)->stringValue()); + i++; + } + } + ret[count]=NULL; + } + return ret; + } +CL_NS_END diff --git a/src/core/CLucene/document/Document.h b/src/core/CLucene/document/Document.h new file mode 100644 index 00000000000..400ec591229 --- /dev/null +++ b/src/core/CLucene/document/Document.h @@ -0,0 +1,178 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_document_Document_ +#define _lucene_document_Document_ + +#include "CLucene/util/VoidList.h" +#include "Field.h" + +///todo: jlucene has change from using DocumentFieldList/Enumeration +///to using a java List... do we want to do this too? +CL_NS_DEF(document) + +class DocumentFieldEnumeration; + +/** Documents are the unit of indexing and search. +* +* A Document is a set of fields. Each field has a name and a textual value. +* A field may be {@link Field#isStored() stored} with the document, in which +* case it is returned with search hits on the document. Thus each document +* should typically contain one or more stored fields which uniquely identify +* it. +* +*

Note that fields which are not {@link Field#isStored() stored} are +* not available in documents retrieved from the index, e.g. with {@link +* Hits#doc(int32_t, Document*)}, {@link Searcher#doc(int32_t, Document*)} or {@link +* IndexReader#document(int32_t, Document*)}. +*/ +class CLUCENE_EXPORT Document:LUCENE_BASE { +public: + typedef CL_NS(util)::CLArrayList > FieldsType; +private: + FieldsType* _fields; + float_t boost; +public: + /** Constructs a new document with no fields. */ + Document(); + + ~Document(); + + /** Sets a boost factor for hits on any field of this document. This value + * will be multiplied into the score of all hits on this document. + * + *

The default value is 1.0. + * + *

Values are multiplied into the value of {@link Field#getBoost()} of + * each field in this document. Thus, this method in effect sets a default + * boost for the fields of this document. + * + * @see Field#setBoost(float_t) + */ + void setBoost(const float_t boost); + + /** Returns, at indexing time, the boost factor as set by {@link #setBoost(float_t)}. + * + *

Note that once a document is indexed this value is no longer available + * from the index. At search time, for retrieved documents, this method always + * returns 1. This however does not mean that the boost value set at indexing + * time was ignored - it was just combined with other indexing time factors and + * stored elsewhere, for better indexing and search performance. (For more + * information see the "norm(t,d)" part of the scoring formula in + * {@link Similarity}.) + * + * @see #setBoost(float_t) + */ + float_t getBoost() const; + + /** + *

Adds a field to a document. Several fields may be added with + * the same name. In this case, if the fields are indexed, their text is + * treated as though appended for the purposes of search.

+ *

Note that add like the removeField(s) methods only makes sense + * prior to adding a document to an index. These methods cannot + * be used to change the content of an existing index! In order to achieve this, + * a document has to be deleted from an index and a new changed version of that + * document has to be added.

+ * + */ + void add(Field& field); + + /** + *

Removes field with the specified name from the document. + * If multiple fields exist with this name, this method removes the first field that has been added. + * If there is no field with the specified name, the document remains unchanged.

+ *

Note that the removeField(s) methods like the add method only make sense + * prior to adding a document to an index. These methods cannot + * be used to change the content of an existing index! In order to achieve this, + * a document has to be deleted from an index and a new changed version of that + * document has to be added.

+ * Note: name is case sensitive + */ + void removeField(const TCHAR* name); + + /** + *

Removes all fields with the given name from the document. + * If there is no field with the specified name, the document remains unchanged.

+ *

Note that the removeField(s) methods like the add method only make sense + * prior to adding a document to an index. These methods cannot + * be used to change the content of an existing index! In order to achieve this, + * a document has to be deleted from an index and a new changed version of that + * document has to be added.

+ * Note: name is case sensitive + */ + void removeFields(const TCHAR* name); + + /** Returns a field with the given name if any exist in this document, or + * null. If multiple fields exists with this name, this method returns the + * first value added. + * Note: name is case sensitive + * Do not use this method with lazy loaded fields. + */ + Field* getField(const TCHAR* name) const; + + /** Returns the string value of the field with the given name if any exist in + * this document, or null. If multiple fields exist with this name, this + * method returns the first value added. If only binary fields with this name + * exist, returns null. + * Note: name is case sensitive + */ + const TCHAR* get(const TCHAR* field) const; + + /** Returns an Enumeration of all the fields in a document. + * @deprecated use {@link #getFields()} instead + */ + _CL_DEPRECATED( getFields() ) DocumentFieldEnumeration* fields(); + + /** Returns a List of all the fields in a document. + *

Note that fields which are not {@link Field#isStored() stored} are + * not available in documents retrieved from the index, e.g. with {@link + * Hits#doc(int)}, {@link Searcher#doc(int)} or {@link IndexReader#document(int)}. + */ + const FieldsType* getFields() const; + + /** + * Returns an array of {@link Field}s with the given name. + * This method can return null. + * + * @param name the name of the field + * @return a Field[] array or null + */ + void getFields(const TCHAR* name, std::vector& ret); + + /** Prints the fields of a document for human consumption. */ + TCHAR* toString() const; + + + /** + * Returns an array of values of the field specified as the method parameter. + * This method can return null. + * Note: name is case sensitive + * + * @param name the name of the field + * @return a TCHAR** of field values or null + */ + TCHAR** getValues(const TCHAR* name); + + /** + * Empties out the document so that it can be reused + */ + void clear(); +}; + + +class CLUCENE_EXPORT DocumentFieldEnumeration :LUCENE_BASE{ +private: + struct Internal; + Internal* _internal; +public: + DocumentFieldEnumeration(Document::FieldsType::iterator itr, Document::FieldsType::iterator end); + ~DocumentFieldEnumeration(); + bool hasMoreElements() const; + Field* nextElement(); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/document/Field.cpp b/src/core/CLucene/document/Field.cpp new file mode 100644 index 00000000000..2190d467e51 --- /dev/null +++ b/src/core/CLucene/document/Field.cpp @@ -0,0 +1,336 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Field.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_USE(util) +CL_NS_DEF(document) + +Field::Field(const TCHAR* Name, Reader* reader, int config): + lazy(false) +{ + CND_PRECONDITION(Name != NULL, "Name cannot be NULL"); + CND_PRECONDITION(reader != NULL, "reader cannot be NULL"); + + _name = Name;//CLStringIntern::intern( Name ); + fieldsData = reader; + valueType = VALUE_READER; + + boost=1.0f; + + setConfig(config); +} + + +Field::Field(const TCHAR* Name, const TCHAR* Value, int _config, const bool duplicateValue): + lazy(false) +{ + CND_PRECONDITION(Name != NULL, "Name cannot be NULL"); + CND_PRECONDITION(Value != NULL, "value cannot be NULL"); + CND_PRECONDITION(_tcslen(Value)>0 || _tcslen(Name)>0, "name and value cannot both be empty"); + + /* + if (_config & INDEX_NO && _config & STORE_NO) + _CLTHROWA(CL_ERR_IllegalArgument,"it doesn't make sense to have a field that is neither indexed nor stored"); + if (_config & INDEX_NO && _config & TERMVECTOR_YES) + _CLTHROWA(CL_ERR_IllegalArgument,"cannot store term vector information for a field that is not indexed"); + */ + + _name = Name;//CLStringIntern::intern( Name ); + if (duplicateValue) + fieldsData = stringDuplicate( Value ); + else + fieldsData = (void*)Value; + valueType = VALUE_STRING; + + boost=1.0f; + + //config = INDEX_TOKENIZED; // default Field is tokenized and indexed + + setConfig(_config); +} + +Field::Field(const TCHAR* Name, ValueArray* Value, int config, bool duplicateValue): + lazy(false) +{ + CND_PRECONDITION(Name != NULL, "Name cannot be NULL"); + CND_PRECONDITION(Value != NULL, "value cannot be NULL"); + + _name = Name;//CLStringIntern::intern( Name ); + + if ( duplicateValue ){ + ValueArray* tmp = _CLNEW ValueArray(Value->length); + memcpy(tmp->values, Value->values, Value->length * sizeof(uint8_t)); + fieldsData = tmp; + }else{ + fieldsData = Value; + } + valueType = VALUE_BINARY; + + boost=1.0f; + + setConfig(config); +} + +Field::Field(const TCHAR* Name, int config): + lazy(false) +{ + CND_PRECONDITION(Name != NULL, "Name cannot be NULL"); + + _name = Name;//CLStringIntern::intern( Name ); + fieldsData = NULL; + valueType = VALUE_NONE; + + boost=1.0f; + + if (config) setConfig(config); +} + +Field::~Field(){ +//Func - Destructor +//Pre - true +//Post - Instance has been destroyed + + //CLStringIntern::unintern(_name); + _resetValue(); +} + + +/*===============FIELDS=======================*/ +const TCHAR* Field::name() const { return _name; } ///(fieldsData) : NULL; } ///* Field::binaryValue() { return (valueType & VALUE_BINARY) ? static_cast*>(fieldsData) : NULL; } ///(fieldsData) : NULL; } ///(fieldsData) : NULL; } +//CL_NS(analysis)::STokenStream* Field::stokenStreamValue() { return (valueType & VALUE_STOKENSTREAM) ? static_cast(fieldsData) : NULL; } + +bool Field::isStored() const { return (config & STORE_YES) != 0; } +bool Field::isIndexed() const { return (config & INDEX_TOKENIZED)!=0 || (config & INDEX_UNTOKENIZED)!=0; } +bool Field::isTokenized() const { return (config & INDEX_TOKENIZED) != 0; } +bool Field::isTokenizedCHS() const { + return (config & INDEX_TOKENIZED) != 0 && (config & INDEX_CHS) != 0; } +bool Field::isCompressed() const { return (config & STORE_COMPRESS) != 0; } +bool Field::isBinary() const { return (valueType & VALUE_BINARY) && fieldsData!=NULL; } + +bool Field::isTermVectorStored() const { return (config & TERMVECTOR_YES) != 0; } +bool Field::isStoreOffsetWithTermVector() const { return (config & TERMVECTOR_YES) != 0 && (config & TERMVECTOR_WITH_OFFSETS) != 0 && ((config & TERMVECTOR_WITH_OFFSETS) != TERMVECTOR_YES); } +bool Field::isStorePositionWithTermVector() const { return (config & TERMVECTOR_YES) != 0 && (config & TERMVECTOR_WITH_POSITIONS) != 0 && ((config & TERMVECTOR_WITH_POSITIONS) != TERMVECTOR_YES); } + +bool Field::getOmitNorms() const { return (config & INDEX_NONORMS) != 0; } +void Field::setOmitNorms(const bool omitNorms) { + if ( omitNorms ) + config |= INDEX_NONORMS; + else + config &= ~INDEX_NONORMS; +} + +bool Field::isLazy() const { return lazy; } + +void Field::setValue(TCHAR* value, const bool duplicateValue) { + _resetValue(); + if (duplicateValue) + fieldsData = stringDuplicate( value ); + else + fieldsData = value; + fieldsDataLength = _tcslen(value); + valueType = VALUE_STRING; +} + +void Field::setValue(char* value, size_t fieldDataLen) { + _resetValue(); + fieldsDataLength = fieldDataLen; + fieldsData = value; + valueType = VALUE_CHAR; +} + +void Field::setValue(Reader* value) { + _resetValue(); + fieldsData = value; + valueType = VALUE_READER; +} +void Field::setValue(ValueArray* value) { + _resetValue(); + fieldsData = value; + valueType = VALUE_BINARY; +} + +/** Expert: change the value of this field. See setValue(String). */ +void Field::setValue(CL_NS(analysis)::TokenStream* value) { + _resetValue(); + fieldsData = value; + valueType = VALUE_TOKENSTREAM; +} + +/*void Field::setValue(CL_NS(analysis)::STokenStream* value) { + _resetValue(); + fieldsData = value; + valueType = VALUE_STOKENSTREAM; +}*/ + +void Field::setBoost(const float_t boost) { this->boost = boost; } +float_t Field::getBoost() const { return boost; } + +void Field::setConfig(const uint32_t x){ + uint32_t newConfig=0; + + //set storage settings + if ( (x & STORE_YES) || (x & STORE_COMPRESS) ){ + newConfig |= STORE_YES; + if ( x & STORE_COMPRESS ) + newConfig |= STORE_COMPRESS; + } else + newConfig |= STORE_NO; + + if ( (x & INDEX_NO)==0 ){ + bool index=false; + + if ( x & INDEX_TOKENIZED && x & INDEX_UNTOKENIZED ) + _CLTHROWA(CL_ERR_IllegalArgument,"it doesn't make sense to have an untokenised and tokenised field"); + + if ( x & INDEX_NONORMS ){ + newConfig |= INDEX_NONORMS; + index = true; + } + if ( x & INDEX_TOKENIZED ){ + newConfig |= INDEX_TOKENIZED; + index = true; + if ( x & INDEX_CHS ) + newConfig |= INDEX_CHS; + } + else if ( x & INDEX_UNTOKENIZED ){ + newConfig |= INDEX_UNTOKENIZED; + index = true; + } + + if ( !index ) + newConfig |= INDEX_NO; + }else + newConfig |= INDEX_NO; + + if ( newConfig & INDEX_NO && newConfig & STORE_NO ) + _CLTHROWA(CL_ERR_IllegalArgument,"it doesn't make sense to have a field that is neither indexed nor stored"); + + //set termvector settings + if ( (x & TERMVECTOR_NO) == 0 ){ + bool termVector=false; + if ( x & TERMVECTOR_YES ){ + termVector=true; + } + if ( (x & TERMVECTOR_WITH_POSITIONS) && ((x & TERMVECTOR_WITH_POSITIONS) != TERMVECTOR_YES) ){ + newConfig |= TERMVECTOR_WITH_POSITIONS; + termVector=true; + } + if ( x & TERMVECTOR_WITH_OFFSETS && ((x & TERMVECTOR_WITH_OFFSETS) != TERMVECTOR_YES) ){ + newConfig |= TERMVECTOR_WITH_OFFSETS; + termVector=true; + } + // TERMVECTOR_WITH_POSITIONS_OFFSETS is being automatically handled here + + if ( termVector ){ + if ( newConfig & INDEX_NO ) + _CLTHROWA(CL_ERR_IllegalArgument,"cannot store a term vector for fields that are not indexed."); + + newConfig |= TERMVECTOR_YES; + }else + newConfig |= TERMVECTOR_NO; + }else + newConfig |= TERMVECTOR_NO; + + config = newConfig; +} + +TCHAR* Field::toString() { + StringBuffer result; + if (isStored()) { + result.append( _T("stored") ); + if (isCompressed()) + result.append( _T("/compressed")); + else + result.append( _T("/uncompressed") ); + } + if (isIndexed()) { + if (result.length() > 0) + result.append( _T(",") ); + result.append( _T("indexed") ); + } + if (isTokenized()) { + if (result.length() > 0) + result.append( _T(",") ); + result.append( _T("tokenized") ); + } + if (isTermVectorStored()) { + if (result.length() > 0) + result.append( _T(",") ); + result.append( _T("termVector") ); + } + if (isStoreOffsetWithTermVector()) { + if (result.length() > 0) + result.appendChar( ',' ); + result.append( _T("termVectorOffsets") ); + } + if (isStorePositionWithTermVector()) { + if (result.length() > 0) + result.appendChar( ',' ); + result.append( _T("termVectorPosition") ); + } + if (isBinary()) { + if (result.length() > 0) + result.appendChar( ',' ); + result.append( _T("binary") ); + } + if (getOmitNorms()) { + result.append( _T(",omitNorms") ); + } + if (isLazy()){ + result.append( _T(",lazy") ); + } + result.appendChar('<'); + result.append(name()); + result.appendChar(':'); + + if (! isLazy() && fieldsData != NULL) { + if (valueType & VALUE_STRING) + result.append(static_cast(fieldsData)); + else if (valueType & VALUE_READER) + result.append( _T("Reader") ); + else if (valueType & VALUE_BINARY) + result.append( _T("Binary") ); + else + result.append( _T("NULL") ); + } + + result.appendChar('>'); + return result.toString(); +} + + +void Field::_resetValue() { + if (valueType & VALUE_STRING) { + TCHAR* t = static_cast(fieldsData); + _CLDELETE_CARRAY(t); + } else if (valueType & VALUE_READER) { + Reader* r = static_cast(fieldsData); + _CLDELETE(r); + } else if (valueType & VALUE_BINARY) { + ValueArray* v = static_cast*>(fieldsData); + _CLDELETE(v); + } + valueType=VALUE_NONE; +} +const char* Field::getObjectName() const{ + return getClassName(); +} +const char* Field::getClassName(){ + return "Field"; +} +CL_NS_END diff --git a/src/core/CLucene/document/Field.h b/src/core/CLucene/document/Field.h new file mode 100644 index 00000000000..f8dd0980e6a --- /dev/null +++ b/src/core/CLucene/document/Field.h @@ -0,0 +1,328 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_document_Field_ +#define _lucene_document_Field_ + +#include "CLucene/util/Array.h" +#include "CLucene/util/Equators.h" +/* +Fieldable reading: +https://issues.apache.org/jira/browse/LUCENE-1219?page=com.atlassian.jira.plugin.system.issuetabpanels:comment- tabpanel&focusedCommentId=12578199#action_12578199 +http://lucene.markmail.org/message/ioi4f6z24cbd5bdm?q=Fieldable#query:Fieldable+page:1+mid:fxmvzb6up7zve7k4+state:results + +TODO: - Solve some inconsistencies between CL and JL - mainly in the constructors area. + - Write some more tests to make sure we conform with JL - mainly in the tokenizing and omitNorms area + - Is there a bug in JL when calling setOmitNorms after a Tokenized field was created? +*/ + +CL_CLASS_DEF(util,Reader) +CL_CLASS_DEF(analysis,TokenStream) +//CL_CLASS_DEF(analysis,STokenStream) + +CL_NS_DEF(document) + +/** +A field is a section of a Document. Each field has two parts, a name and a +value. Values may be free text, provided as a String or as a Reader, or they +may be atomic keywords, which are not further processed. Such keywords may +be used to represent dates, urls, etc. Fields are optionally stored in the +index, so that they may be returned with hits on the document. +*/ +class CLUCENE_EXPORT Field : public CL_NS(util)::NamedObject{ +public: + enum Store{ + /** Store the original field value in the index. This is useful for short texts + * like a document's title which should be displayed with the results. The + * value is stored in its original form, i.e. no analyzer is used before it is + * stored. + */ + STORE_YES=1, + + /** Do not store the field value in the index. */ + STORE_NO=2, + + /** Store the original field value in the index in a compressed form. This is + * useful for long documents and for binary valued fields. + */ + STORE_COMPRESS=4 + }; + + enum Index{ + //for chinese, using: INDEX_CHN | INDEX_TOKENIZED + INDEX_CHS=8, + + /** Do not index the field value. This field can thus not be searched, + * but one can still access its contents provided it is + * {@link Field::Store stored}. */ + INDEX_NO=16, + + /** Index the field's value so it can be searched. An Analyzer will be used + * to tokenize and possibly further normalize the text before its + * terms will be stored in the index. This is useful for common text. + */ + INDEX_TOKENIZED=32, + + /** Index the field's value without using an Analyzer, so it can be searched. + * As no analyzer is used the value will be stored as a single term. This is + * useful for unique Ids like product numbers. + */ + INDEX_UNTOKENIZED=64, + + /** Index the field's value without an Analyzer, and disable + * the storing of norms. No norms means that index-time boosting + * and field length normalization will be disabled. The benefit is + * less memory usage as norms take up one byte per indexed field + * for every document in the index. + * Note that once you index a given field with norms enabled, + * disabling norms will have no effect. In other words, for NO_NORMS + * to have the above described effect on a field, all instances of that + * field must be indexed with NO_NORMS from the beginning. + */ + INDEX_NONORMS=128 + }; + + enum TermVector{ + /** Do not store term vectors. */ + TERMVECTOR_NO=256, + + /** Store the term vectors of each document. A term vector is a list + * of the document's terms and their number of occurences in that document. */ + TERMVECTOR_YES=512, + + /** + * Store the term vector + token position information + * + * @see #YES + */ + TERMVECTOR_WITH_POSITIONS = TERMVECTOR_YES | 1024, + + /** + * Store the term vector + Token offset information + * + * @see #YES + */ + TERMVECTOR_WITH_OFFSETS = TERMVECTOR_YES | 2048, + + /** + * Store the term vector + Token position and offset information + * + * @see #YES + * @see #WITH_POSITIONS + * @see #WITH_OFFSETS + */ + TERMVECTOR_WITH_POSITIONS_OFFSETS = TERMVECTOR_WITH_OFFSETS | TERMVECTOR_WITH_POSITIONS + }; + + bool lazy; + + enum ValueType { + VALUE_NONE = 0, + VALUE_STRING = 1, + VALUE_READER = 2, + VALUE_BINARY = 4, + VALUE_TOKENSTREAM = 8, + VALUE_STOKENSTREAM = 16, + VALUE_CHAR = 32 + }; + + /** + * TCHAR value constructor of Field. + * @memory Set duplicateValue to false to save on memory allocations when possible + */ + Field(const TCHAR* name, const TCHAR* value, int _config, const bool duplicateValue = true); + + /** + * Reader* constructor of Field. + * @memory consumes reader + */ + Field(const TCHAR* name, CL_NS(util)::Reader* reader, int _config); + + /** + * Binary constructor of Field. + * @memory Set duplicateValue to false to save on memory allocations when possible + */ + Field(const TCHAR* name, CL_NS(util)::ValueArray* data, int _config, const bool duplicateValue = true); + + Field(const TCHAR* name, int _config); ///* binaryValue(); + + /** The value of the field as a TokesStream, or null. If null, the Reader value, + * String value, or binary value is used. Exactly one of stringValue(), + * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ + virtual CL_NS(analysis)::TokenStream* tokenStreamValue(); + + //virtual CL_NS(analysis)::STokenStream* stokenStreamValue(); + + // True if the value of the field is to be stored in the index for return + // with search hits. It is an error for this to be true if a field is + // Reader-valued. + bool isStored() const; + + // True if the value of the field is to be indexed, so that it may be + // searched on. + bool isIndexed() const; + + // True if the value of the field should be tokenized as text prior to + // indexing. Un-tokenized fields are indexed as a single word and may not be + // Reader-valued. + bool isTokenized() const; + bool isTokenizedCHS() const; + + /** True if the value of the field is stored and compressed within the index + */ + bool isCompressed() const; + + /** True if the term or terms used to index this field are stored as a term + * vector, available from {@link IndexReader#getTermFreqVector(int32_t,TCHAR*)}. + * These methods do not provide access to the original content of the field, + * only to terms used to index it. If the original content must be + * preserved, use the stored attribute instead. + * + * @see IndexReader#getTermFreqVector(int32_t, String) + */ + bool isTermVectorStored() const; + + /** + * True iff terms are stored as term vector together with their offsets + * (start and end positon in source text). + */ + bool isStoreOffsetWithTermVector() const; + + /** + * True iff terms are stored as term vector together with their token positions. + */ + bool isStorePositionWithTermVector() const; + + /** Returns the boost factor for hits for this field. + * + *

The default value is 1.0. + * + *

Note: this value is not stored directly with the document in the index. + * Documents returned from {@link IndexReader#document(int)} and + * {@link Hits#doc(int)} may thus not have the same value present as when + * this field was indexed. + * + * @see #setBoost(float_t) + */ + float_t getBoost() const; + + /** Sets the boost factor hits on this field. This value will be + * multiplied into the score of all hits on this this field of this + * document. + * + *

The boost is multiplied by {@link Document#getBoost()} of the document + * containing this field. If a document has multiple fields with the same + * name, all such values are multiplied together. This product is then + * multipled by the value {@link Similarity#lengthNorm(String,int)}, and + * rounded by {@link Similarity#encodeNorm(float_t)} before it is stored in the + * index. One should attempt to ensure that this product does not overflow + * the range of that encoding. + * + * @see Document#setBoost(float_t) + * @see Similarity#lengthNorm(String, int) + * @see Similarity#encodeNorm(float_t) + */ + void setBoost(const float_t value); + + /** True if the value of the filed is stored as binary */ + bool isBinary() const; + + /** True if norms are omitted for this indexed field */ + bool getOmitNorms() const; + + /** Expert: + * + * If set, omit normalization factors associated with this indexed field. + * This effectively disables indexing boosts and length normalization for this field. + */ + void setOmitNorms(const bool omitNorms); + + /** + * Indicates whether a Field is Lazy or not. The semantics of Lazy loading are such that if a Field is lazily loaded, retrieving + * it's values via {@link #stringValue()} or {@link #binaryValue()} is only valid as long as the {@link org.apache.lucene.index.IndexReader} that + * retrieved the {@link Document} is still open. + * + * @return true if this field can be loaded lazily + */ + bool isLazy() const; + + /** Prints a Field for human consumption. */ + TCHAR* toString(); + + /**

Expert: change the value of this field. This can + * be used during indexing to re-use a single Field + * instance to improve indexing speed by avoiding GC cost + * of new'ing and reclaiming Field instances. Typically + * a single {@link Document} instance is re-used as + * well. This helps most on small documents.

+ * + *

Note that you should only use this method after the + * Field has been consumed (ie, the {@link Document} + * containing this Field has been added to the index). + * Also, each Field instance should only be used once + * within a single {@link Document} instance. See ImproveIndexingSpeed + * for details.

+ * + * @memory Caller is responsible for releasing value if duplicateValue == false */ + void setValue(TCHAR* value, const bool duplicateValue = true); + void setValue(char* value, size_t fieldDataLen); + + /** Expert: change the value of this field. See setValue(TCHAR*). */ + void setValue(CL_NS(util)::Reader* value); + + /** Expert: change the value of this field. See setValue(TCHAR*). */ + void setValue(CL_NS(util)::ValueArray* value) ; + + /** Expert: change the value of this field. See setValue(TCHAR*). */ + void setValue(CL_NS(analysis)::TokenStream* value); + + //void setValue(CL_NS(analysis)::STokenStream* value); + + virtual const char* getObjectName() const; + static const char* getClassName(); + +protected: + /** + * Set configs using XOR. This resets all the settings + * For example, to use term vectors with positions and offsets do: + * object->setConfig(TERMVECTOR_WITH_POSITIONS | TERMVECTOR_WITH_OFFSETS); + */ + void setConfig(const uint32_t _config); + + void _resetValue(); + + void* fieldsData; + size_t fieldsDataLength; + ValueType valueType; + + const TCHAR* _name; + uint32_t config; + float_t boost; +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/document/FieldSelector.cpp b/src/core/CLucene/document/FieldSelector.cpp new file mode 100644 index 00000000000..346a87e02b3 --- /dev/null +++ b/src/core/CLucene/document/FieldSelector.cpp @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "FieldSelector.h" + +CL_NS_USE(util) +CL_NS_DEF(document) + +FieldSelector::~FieldSelector(){ +} + +LoadFirstFieldSelector::~LoadFirstFieldSelector(){ +} + +FieldSelector::FieldSelectorResult LoadFirstFieldSelector::accept(const TCHAR* /*fieldName*/) const{ + return LOAD_AND_BREAK; +} + +MapFieldSelector::~MapFieldSelector(){ + _CLDELETE(fieldSelections); +} + +MapFieldSelector::MapFieldSelector() : + fieldSelections(_CLNEW FieldSelectionsType(true,false)) +{ +} + +MapFieldSelector::MapFieldSelector(std::vector& fields) : + fieldSelections(_CLNEW FieldSelectionsType(true,false)) +{ + std::vector::iterator itr = fields.begin(); + while ( itr != fields.end() ){ + add(*itr); + itr++; + } +} + +MapFieldSelector::MapFieldSelector(ArrayBase& fields): + fieldSelections(_CLNEW FieldSelectionsType(true,false)) +{ + for ( size_t i=0;ifind((TCHAR*)field); + if ( itr != fieldSelections->end() ){ + return itr->second; + } + return FieldSelector::NO_LOAD; +} + +void MapFieldSelector::add(const TCHAR* field, FieldSelector::FieldSelectorResult action){ + fieldSelections->insert(fieldSelections->end(),std::pair( + STRDUP_TtoT(field), action)); +} + + +CL_NS_END diff --git a/src/core/CLucene/document/FieldSelector.h b/src/core/CLucene/document/FieldSelector.h new file mode 100644 index 00000000000..f66a3003a77 --- /dev/null +++ b/src/core/CLucene/document/FieldSelector.h @@ -0,0 +1,142 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_document_FieldSelector_ +#define _lucene_document_FieldSelector_ + +#include "CLucene/util/Equators.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/VoidMap.h" + +CL_NS_DEF(document) + +/** + * Similar to a {@link java.io.FileFilter}, the FieldSelector allows one to make decisions about + * what Fields get loaded on a {@link Document} by {@link org.apache.lucene.index.IndexReader#document(int,org.apache.lucene.document.FieldSelector)} + * + **/ +class CLUCENE_EXPORT FieldSelector :LUCENE_BASE { +public: + + /** + * Provides information about what should be done with this Field + * + **/ + enum FieldSelectorResult { + /** + * Load this {@link Field} every time the {@link Document} is loaded, reading in the data as it is encounterd. + * {@link Document#getField(String)} and {@link Document#getField(String)} should not return null. + *

+ * {@link Document#add(Field)} should be called by the Reader. + */ + LOAD = 0, + + /** + * Lazily load this {@link Field}. This means the {@link Field} is valid, but it may not actually contain its data until + * invoked. {@link Document#getField(String)} SHOULD NOT BE USED. {@link Document#getField(String)} is safe to use and should + * return a valid instance of a {@link Field}. + *

+ * {@link Document#add(Field)} should be called by the Reader. + */ + LAZY_LOAD = 1, + + /** + * Do not load the {@link Field}. {@link Document#getField(String)} and {@link Document#getField(String)} should return null. + * {@link Document#add(Field)} is not called. + *

+ * {@link Document#add(Field)} should not be called by the Reader. + */ + NO_LOAD = 2, + + /** + * Load this field as in the {@link #LOAD} case, but immediately return from {@link Field} loading for the {@link Document}. Thus, the + * Document may not have its complete set of Fields. {@link Document#getField(String)} and {@link Document#getField(String)} should + * both be valid for this {@link Field} + *

+ * {@link Document#add(Field)} should be called by the Reader. + */ + LOAD_AND_BREAK = 3, + + /** + * Behaves much like {@link #LOAD} but does not uncompress any compressed data. This is used for internal purposes. + * {@link Document#getField(String)} and {@link Document#getField(String)} should not return null. + *

+ * {@link Document#add(Field)} should be called by the Reader. + */ + LOAD_FOR_MERGE = 4, + + /** Expert: Load the size of this {@link Field} rather than its value. + * Size is measured as number of bytes required to store the field == bytes for a binary or any compressed value, and 2*chars for a String value. + * The size is stored as a binary value, represented as an int in a byte[], with the higher order byte first in [0] + */ + SIZE = 5, + + /** Expert: Like {@link #SIZE} but immediately break from the field loading loop, i.e., stop loading further fields, after the size is loaded */ + SIZE_AND_BREAK = 6 + }; + + virtual ~FieldSelector(); + + /** + * + * @param fieldName the field to accept or reject + * @return an instance of {@link FieldSelectorResult} + * if the {@link Field} named fieldName should be loaded. + */ + virtual FieldSelectorResult accept(const TCHAR* fieldName) const = 0; + +}; + +/** + * Load the First field and break. + *

+ * See {@link FieldSelectorResult#LOAD_AND_BREAK} + */ +class CLUCENE_EXPORT LoadFirstFieldSelector :public FieldSelector { +public: + ~LoadFirstFieldSelector(); + + FieldSelectorResult accept(const TCHAR* fieldName) const; +}; + +/** + * A FieldSelector based on a Map of field names to FieldSelectorResults + * + * @author Chuck Williams + */ +class CLUCENE_EXPORT MapFieldSelector: public FieldSelector { +public: + typedef CL_NS(util)::CLHashMap FieldSelectionsType; + FieldSelectionsType* fieldSelections; + + virtual ~MapFieldSelector(); + + MapFieldSelector(std::vector& fieldSelections); + + /** Create a a MapFieldSelector + */ + MapFieldSelector(); + + /** Create a a MapFieldSelector + * @param fields fields to LOAD. All other fields are NO_LOAD. + */ + MapFieldSelector(CL_NS(util)::ArrayBase& fields); + + /** Load field according to its associated value in fieldSelections + * @param field a field name + * @return the fieldSelections value that field maps to or NO_LOAD if none. + */ + FieldSelectorResult accept(const TCHAR* field) const; + + void add(const TCHAR*, FieldSelector::FieldSelectorResult action=FieldSelector::LOAD); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/document/NumberTools.cpp b/src/core/CLucene/document/NumberTools.cpp new file mode 100644 index 00000000000..d41cb0589c4 --- /dev/null +++ b/src/core/CLucene/document/NumberTools.cpp @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "NumberTools.h" +#include "CLucene/util/Misc.h" + +CL_NS_DEF(document) + +const TCHAR* NumberTools::MIN_STRING_VALUE = NEGATIVE_PREFIX _T("0000000000000"); +const TCHAR* NumberTools::MAX_STRING_VALUE = POSITIVE_PREFIX _T("1y2p0ij32e8e7"); + +int NumberTools::float_to_int(float value) +{ + union UnionFloatInt + { + int int_; + float float_; + }; + UnionFloatInt float_int; + float_int.float_ = value; + return float_int.int_; +} + +int64_t NumberTools::double_to_long(double value) +{ + union UnionLongDouble + { + int64_t long_; + double double_; + }; + UnionLongDouble long_double; + long_double.double_ = value; + return long_double.long_; +} + +TCHAR* NumberTools::longToString(int64_t l) +{ + if (l == LUCENE_INT64_MIN_SHOULDBE) { + // special case, because long is not symetric around zero + return stringDuplicate(MIN_STRING_VALUE); + } + + TCHAR* buf = _CL_NEWARRAY(TCHAR, STR_SIZE + 1); + if (l < 0) { + buf[0] = NEGATIVE_PREFIX[0]; + l = LUCENE_INT64_MAX_SHOULDBE + l + 1; + } else { + buf[0] = POSITIVE_PREFIX[0]; + } + + TCHAR tmp[STR_SIZE]; + _i64tot(l, tmp, NUMBERTOOLS_RADIX); + size_t len = _tcslen(tmp); + _tcscpy(buf+(STR_SIZE-len),tmp); + for ( size_t i=1;i + * That is, if l1 is less than l2 for any two longs l1 and l2, then + * NumberTools.longToString(l1) is lexicographically less than + * NumberTools.longToString(l2). (Similarly for "greater than" and "equals".) + * + *

+ * This class handles all long values (unlike + * {@link org.apache.lucene.document.DateField}). + * + * + */ +class CLUCENE_EXPORT NumberTools :LUCENE_BASE { + + #define NUMBERTOOLS_RADIX 36 + + #define NEGATIVE_PREFIX _T("-") + // NB: NEGATIVE_PREFIX must be < POSITIVE_PREFIX + #define POSITIVE_PREFIX _T("0") + +public: + //NB: this must be less than + /** + * Equivalent to longToString(Long.MIN_VALUE); STR_SIZE is depandant on the length of it + */ + static const TCHAR* MIN_STRING_VALUE; + + /** + * Equivalent to longToString(Long.MAX_VALUE) + */ + static const TCHAR* MAX_STRING_VALUE; + + /** + * The length of (all) strings returned by {@link #longToString} + */ + LUCENE_STATIC_CONSTANT (size_t, STR_SIZE = 14); + + /** + * Converts a long to a String suitable for indexing. + * + * @memory Caller should free the returned buffer + */ + static TCHAR* longToString(int64_t l); + + /** + * Converts a String that was returned by {@link #longToString} back to a + * long. + * + * @throws IllegalArgumentException + * if the input is null + * @throws NumberFormatException + * if the input does not parse (it was not a String returned by + * longToString()). + */ + static int64_t stringToLong(const TCHAR* str); + + static int float_to_int(float value); + static int64_t double_to_long(double value); + + ~NumberTools(); + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/CompoundFile.cpp b/src/core/CLucene/index/CompoundFile.cpp new file mode 100644 index 00000000000..52036f37e22 --- /dev/null +++ b/src/core/CLucene/index/CompoundFile.cpp @@ -0,0 +1,456 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Term.h" +#include "_TermInfo.h" +#include "_SkipListWriter.h" +#include "_CompoundFile.h" +#include "CLucene/util/Misc.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + + +class WriterFileEntry:LUCENE_BASE { +public: + WriterFileEntry(){ + directoryOffset=0; + dataOffset=0; + } + ~WriterFileEntry(){ + } + /** source file */ + char file[CL_MAX_PATH]; + + /** temporary holder for the start of directory entry for this file */ + int64_t directoryOffset; + + /** temporary holder for the start of this file's data section */ + int64_t dataOffset; + +}; + + +/** Implementation of an IndexInput that reads from a portion of the + * compound file. The visibility is left as "package" *only* because + * this helps with testing since JUnit test cases in a different class + * can then access package fields of this class. + */ +class CSIndexInput:public CL_NS(store)::BufferedIndexInput { +private: + CL_NS(store)::IndexInput* base; + int64_t fileOffset; + int64_t _length; +protected: + /** Expert: implements buffer refill. Reads uint8_ts from the current + * position in the input. + * @param b the array to read uint8_ts into + * @param length the number of uint8_ts to read + */ + void readInternal(uint8_t* /*b*/, const int32_t /*len*/); + void seekInternal(const int64_t /*pos*/) + { + } + +public: + CSIndexInput(CL_NS(store)::IndexInput* base, const int64_t fileOffset, const int64_t length, const int32_t readBufferSize = CL_NS(store)::BufferedIndexInput::BUFFER_SIZE); + CSIndexInput(const CSIndexInput& clone); + ~CSIndexInput(); + + /** Closes the stream to futher operations. */ + void close(); + CL_NS(store)::IndexInput* clone() const; + + int64_t length() const { return _length; } + + const char* getDirectoryType() const{ return CompoundFileReader::getClassName(); } + const char* getObjectName() const{ return getClassName(); } + static const char* getClassName() { return "CSIndexInput"; } +}; + +class ReaderFileEntry:LUCENE_BASE { +public: + int64_t offset; + int64_t length; + ReaderFileEntry(){ + offset=0; + length=0; + } + ~ReaderFileEntry(){ + } +}; + + +CSIndexInput::CSIndexInput(CL_NS(store)::IndexInput* base, const int64_t fileOffset, const int64_t length, const int32_t _readBufferSize):BufferedIndexInput(_readBufferSize){ + this->base = base; + this->fileOffset = fileOffset; + this->_length = length; +} + +void CSIndexInput::readInternal(uint8_t* b, const int32_t len) +{ + SCOPED_LOCK_MUTEX(base->THIS_LOCK) + + int64_t start = getFilePointer(); + if(start + len > _length) + _CLTHROWA(CL_ERR_IO,"read past EOF"); + base->seek(fileOffset + start); + base->readBytes(b, len, false); +} +CSIndexInput::~CSIndexInput(){ +} +IndexInput* CSIndexInput::clone() const +{ + return _CLNEW CSIndexInput(*this); +} +CSIndexInput::CSIndexInput(const CSIndexInput& clone): BufferedIndexInput(clone){ + this->base = clone.base; //no need to clone this.. + this->fileOffset = clone.fileOffset; + this->_length = clone._length; +} + +void CSIndexInput::close(){ +} + + + +CompoundFileReader::CompoundFileReader(Directory* dir, const char* name, int32_t _readBufferSize): + readBufferSize(_readBufferSize), directory(dir), stream(NULL), entries(_CLNEW EntriesType(true,true)) +{ + fileName = STRDUP_AtoA(name); + + bool success = false; + + try { + stream = dir->openInput(name, readBufferSize); + + // read the directory and init files + int32_t count = stream->readVInt(); + ReaderFileEntry* entry = NULL; + TCHAR tid[CL_MAX_PATH]; + for (int32_t i=0; ireadLong(); + stream->readString(tid,CL_MAX_PATH); + char* aid = STRDUP_TtoA(tid); + + if (entry != NULL) { + // set length of the previous entry + entry->length = offset - entry->offset; + } + + entry = _CLNEW ReaderFileEntry(); + entry->offset = offset; + entries->put(aid, entry); + } + + // set the length of the final entry + if (entry != NULL) { + entry->length = stream->length() - entry->offset; + } + + success = true; + + }_CLFINALLY( + if (! success && (stream != NULL)) { + try { + stream->close(); + _CLDELETE(stream); + } catch (CLuceneError& err){ + if ( err.number() != CL_ERR_IO ) + throw err; + //else ignore + } + } + ) +} + +CompoundFileReader::~CompoundFileReader(){ + close(); + _CLDELETE_CaARRAY(fileName); + _CLDELETE(entries); +} + +Directory* CompoundFileReader::getDirectory(){ + return directory; +} + +const char* CompoundFileReader::getName() const{ + return fileName; +} +const char* CompoundFileReader::getClassName(){ + return "CompoundFileReader"; +} +const char* CompoundFileReader::getObjectName() const{ + return getClassName(); +} + +void CompoundFileReader::close(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (stream != NULL){ + entries->clear(); + stream->close(); + _CLDELETE(stream); + } +} + +bool CompoundFileReader::openInput(const char * id, CL_NS(store)::IndexInput *& ret, CLuceneError& error, int32_t bufferSize){ + SCOPED_LOCK_MUTEX(THIS_LOCK); + + if (stream == NULL){ + error.set(CL_ERR_IO,"Stream closed"); + return false; + } + + const ReaderFileEntry* entry = entries->get((char*)id); + if (entry == NULL){ + char buf[CL_MAX_PATH+26]; + cl_sprintf(buf, CL_MAX_PATH+26, "No sub-file with id %s found", id); + error.set(CL_ERR_IO,buf); + return false; + } + + if (bufferSize < 1) + bufferSize = readBufferSize; + + ret = _CLNEW CSIndexInput(stream, entry->offset, entry->length, bufferSize); + return true; +} + +bool CompoundFileReader::list(vector* names) const{ + for ( EntriesType::const_iterator i=entries->begin();i!=entries->end();i++ ){ + names->push_back(i->first); + ++i; + } + return true; +} + +bool CompoundFileReader::fileExists(const char* name) const{ + return entries->exists((char*)name); +} + +int64_t CompoundFileReader::fileModified(const char* name) const{ + return directory->fileModified(name); +} + +void CompoundFileReader::touchFile(const char* name){ + directory->touchFile(name); +} + +bool CompoundFileReader::doDeleteFile(const char* /*name*/){ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: CompoundFileReader::doDeleteFile"); +} + +void CompoundFileReader::renameFile(const char* /*from*/, const char* /*to*/){ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: CompoundFileReader::renameFile"); +} + +int64_t CompoundFileReader::fileLength(const char* name) const{ + ReaderFileEntry* e = entries->get((char*)name); + if (e == NULL){ + char buf[CL_MAX_PATH + 30]; + strcpy(buf,"File "); + strncat(buf,name,CL_MAX_PATH ); + strcat(buf," does not exist"); + _CLTHROWA(CL_ERR_IO,buf); + } + return e->length; +} +IndexOutput* CompoundFileReader::createOutput(const char* /*name*/){ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: CompoundFileReader::createOutput"); +} +LuceneLock* CompoundFileReader::makeLock(const char* /*name*/){ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: CompoundFileReader::makeLock"); +} + +string CompoundFileReader::toString() const{ + return string("CompoundFileReader@") + fileName; +} + + + +class CompoundFileWriter::Internal{ +public: + CL_NS(store)::Directory* directory; + string fileName; + + CL_NS(util)::CLHashSet ids; + + typedef CL_NS(util)::CLLinkedList > EntriesType; + EntriesType* entries; + + bool merged; + SegmentMerger::CheckAbort* checkAbort; + + Internal(): + ids(true), + entries(_CLNEW EntriesType(true)) + { + + } + ~Internal(){ + _CLDELETE(entries); + } +}; +CompoundFileWriter::CompoundFileWriter(Directory* dir, const char* name, SegmentMerger::CheckAbort* checkAbort){ + _internal = _CLNEW Internal; + if (dir == NULL) + _CLTHROWA(CL_ERR_NullPointer,"directory cannot be null"); + if (name == NULL) + _CLTHROWA(CL_ERR_NullPointer,"name cannot be null"); + _internal->merged = false; + _internal->checkAbort = checkAbort; + _internal->directory = dir; + _internal->fileName = name; +} + +CompoundFileWriter::~CompoundFileWriter(){ + _CLDELETE(_internal); +} + +Directory* CompoundFileWriter::getDirectory(){ + return _internal->directory; +} + +/** Returns the name of the compound file. */ +const char* CompoundFileWriter::getName() const{ + return _internal->fileName.c_str(); +} + +void CompoundFileWriter::addFile(const char* file){ + if (_internal->merged) + _CLTHROWA(CL_ERR_IO,"Can't add extensions after merge has been called"); + + if (file == NULL) + _CLTHROWA(CL_ERR_NullPointer,"file cannot be null"); + + if (_internal->ids.find((char*)file)!=_internal->ids.end()){ + char buf[CL_MAX_PATH + 30]; + strcpy(buf,"File "); + strncat(buf,file,CL_MAX_PATH); + strcat(buf," already added"); + _CLTHROWA(CL_ERR_IO,buf); + } + _internal->ids.insert(STRDUP_AtoA(file)); + + WriterFileEntry* entry = _CLNEW WriterFileEntry(); + STRCPY_AtoA(entry->file,file,CL_MAX_PATH); + _internal->entries->push_back(entry); +} + +void CompoundFileWriter::close(){ + if (_internal->merged) + _CLTHROWA(CL_ERR_IO,"Merge already performed"); + + if (_internal->entries->size()==0) //isEmpty() + _CLTHROWA(CL_ERR_IO,"No entries to merge have been defined"); + + _internal->merged = true; + + // open the compound stream + IndexOutput* os = NULL; + try { + os = _internal->directory->createOutput(_internal->fileName.c_str()); + + // Write the number of entries + os->writeVInt(_internal->entries->size()); + + // Write the directory with all offsets at 0. + // Remember the positions of directory entries so that we can + // adjust the offsets later + { //msvc6 for scope fix + for ( CLLinkedList::iterator i=_internal->entries->begin();i!=_internal->entries->end();i++ ){ + WriterFileEntry* fe = *i; + fe->directoryOffset = os->getFilePointer(); + os->writeLong(0); // for now + os->writeString(fe->file); + } + } + + // Open the files and copy their data into the stream. + // Remember the locations of each file's data section. + { //msvc6 for scope fix + const int32_t bufferLength = 16384; + uint8_t buffer[bufferLength]; + for ( CL_NS(util)::CLLinkedList::iterator i=_internal->entries->begin();i!=_internal->entries->end();i++ ){ + WriterFileEntry* fe = *i; + fe->dataOffset = os->getFilePointer(); + copyFile(fe, os, buffer, bufferLength); + } + } + + { //msvc6 for scope fix + // Write the data offsets into the directory of the compound stream + for ( CLLinkedList::iterator i=_internal->entries->begin(); + i!=_internal->entries->end();i++ ){ + WriterFileEntry* fe = *i; + os->seek(fe->directoryOffset); + os->writeLong(fe->dataOffset); + } + } + + + } _CLFINALLY ( + if (os != NULL) try { os->close(); _CLDELETE(os); } catch (...) { } + ); +} + + +void CompoundFileWriter::copyFile(WriterFileEntry* source, IndexOutput* os, uint8_t* buffer, int32_t bufferLength){ + IndexInput* is = NULL; + try { + int64_t startPtr = os->getFilePointer(); + + is = _internal->directory->openInput(source->file); + int64_t length = is->length(); + int64_t remainder = length; + int32_t chunk = bufferLength; + + while(remainder > 0) { + int32_t len = (int32_t)cl_min((int64_t)chunk, remainder); + is->readBytes(buffer, len); + os->writeBytes(buffer, len); + remainder -= len; + + if (_internal->checkAbort != NULL) + // Roughly every 2 MB we will check if + // it's time to abort + _internal->checkAbort->work(80); + } + + // Verify that remainder is 0 + if (remainder != 0){ + TCHAR buf[CL_MAX_PATH+100]; + _sntprintf(buf,CL_MAX_PATH+100,_T("Non-zero remainder length after copying") + _T(": %d (id: %s, length: %d, buffer size: %d)"), + (int)remainder,source->file,(int)length,(int)chunk ); + _CLTHROWT(CL_ERR_IO,buf); + } + + // Verify that the output length diff is equal to original file + int64_t endPtr = os->getFilePointer(); + int64_t diff = endPtr - startPtr; + if (diff != length){ + TCHAR buf[100]; + _sntprintf(buf,100,_T("Difference in the output file offsets %d ") + _T("does not match the original file length %d"),(int)diff,(int)length); + _CLTHROWT(CL_ERR_IO,buf); + } + } _CLFINALLY ( + if (is != NULL){ + is->close(); + _CLDELETE(is); + } + ); +} + +CL_NS_END diff --git a/src/core/CLucene/index/DirectoryIndexReader.cpp b/src/core/CLucene/index/DirectoryIndexReader.cpp new file mode 100644 index 00000000000..15020eea391 --- /dev/null +++ b/src/core/CLucene/index/DirectoryIndexReader.cpp @@ -0,0 +1,302 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "DirectoryIndexReader.h" +#include "_IndexFileDeleter.h" +#include "IndexDeletionPolicy.h" +#include "_MultiSegmentReader.h" +#include "_SegmentHeader.h" +#include "IndexWriter.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/Lock.h" +#include "_SegmentInfos.h" + +CL_NS_USE(store) +CL_NS_USE(util) + +CL_NS_DEF(index) + + + void DirectoryIndexReader::doClose() { + if(closeDirectory && _directory){ + _directory->close(); + } + _CLDECDELETE(_directory); + } + + void DirectoryIndexReader::doCommit() { + if(hasChanges){ + if (segmentInfos != NULL) { + + // Default deleter (for backwards compatibility) is + // KeepOnlyLastCommitDeleter: + IndexFileDeleter deleter(_directory, + deletionPolicy == NULL ? _CLNEW KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, + segmentInfos, NULL, NULL); + + // Checkpoint the state we are about to change, in + // case we have to roll back: + startCommit(); + + bool success = false; + try { + commitChanges(); + segmentInfos->write(_directory); + success = true; + } _CLFINALLY ( + + if (!success) { + + // Rollback changes that were made to + // SegmentInfos but failed to get [fully] + // committed. This way this reader instance + // remains consistent (matched to what's + // actually in the index): + rollbackCommit(); + + // Recompute deletable files & remove them (so + // partially written .del files, etc, are + // removed): + deleter.refresh(); + } + ) + + // Have the deleter remove any now unreferenced + // files due to this commit: + deleter.checkpoint(segmentInfos, true); + + if (writeLock != NULL) { + writeLock->release(); // release write lock + _CLDELETE(writeLock); + } + } + else + commitChanges(); + } + hasChanges = false; + } + + void DirectoryIndexReader::acquireWriteLock() { + if (segmentInfos != NULL) { + ensureOpen(); + if (stale) + _CLTHROWA(CL_ERR_StaleReader, "IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); + + if (writeLock == NULL) { + LuceneLock* writeLock = _directory->makeLock(IndexWriter::WRITE_LOCK_NAME); + if (!writeLock->obtain(IndexWriter::WRITE_LOCK_TIMEOUT)) { // obtain write lock + string message = string("Index locked for write: ") + writeLock->getObjectName(); + _CLDELETE(writeLock); + _CLTHROWA(CL_ERR_LockObtainFailed, message.c_str()); + } + this->writeLock = writeLock; + + // we have to check whether index has changed since this reader was opened. + // if so, this reader is no longer valid for deletion + if (SegmentInfos::readCurrentVersion(_directory) > segmentInfos->getVersion()) { + stale = true; + this->writeLock->release(); + _CLDELETE(writeLock); + _CLTHROWA(CL_ERR_StaleReader, "IndexReader out of date and no longer valid for delete, undelete, or setNorm operations"); + } + } + } + } + + void DirectoryIndexReader::init(Directory* __directory, SegmentInfos* segmentInfos, bool closeDirectory) { + this->deletionPolicy = NULL; + this->stale = false; + this->writeLock = NULL; + this->rollbackSegmentInfos = NULL; + this->_directory = _CL_POINTER(__directory); + this->segmentInfos = segmentInfos; + this->closeDirectory = closeDirectory; + } + + DirectoryIndexReader::DirectoryIndexReader(): + IndexReader() + { + } + DirectoryIndexReader::~DirectoryIndexReader(){ + try { + if (writeLock != NULL) { + writeLock->release(); // release write lock + writeLock = NULL; + } + }catch(...){ + } + _CLDELETE(segmentInfos); + _CLDELETE(rollbackSegmentInfos); + } + DirectoryIndexReader::DirectoryIndexReader(Directory* __directory, SegmentInfos* segmentInfos, bool closeDirectory): + IndexReader() + { + init(__directory, segmentInfos, closeDirectory); + } + + class DirectoryIndexReader::FindSegmentsFile_Open: public SegmentInfos::FindSegmentsFile{ + bool closeDirectory; + IndexDeletionPolicy* deletionPolicy; + protected: + DirectoryIndexReader* doBody(const char* segmentFileName) { + + SegmentInfos* infos = _CLNEW SegmentInfos; + infos->read(directory, segmentFileName); + + DirectoryIndexReader* reader; + + if (infos->size() == 1) { // index is optimized + reader = SegmentReader::get(infos, infos->info(0), closeDirectory); + } else { + reader = _CLNEW MultiSegmentReader(directory, infos, closeDirectory); + } + reader->setDeletionPolicy(deletionPolicy); + return reader; + } + public: + FindSegmentsFile_Open( bool closeDirectory, IndexDeletionPolicy* deletionPolicy, + CL_NS(store)::Directory* dir ): + SegmentInfos::FindSegmentsFile(dir) + { + this->closeDirectory = closeDirectory; + this->deletionPolicy = deletionPolicy; + } + }; + + DirectoryIndexReader* DirectoryIndexReader::open(Directory* __directory, bool closeDirectory, IndexDeletionPolicy* deletionPolicy) { + DirectoryIndexReader::FindSegmentsFile_Open runner(closeDirectory, deletionPolicy, __directory); + return runner.run(); + } + + + class DirectoryIndexReader::FindSegmentsFile_Reopen: public SegmentInfos::FindSegmentsFile{ + bool closeDirectory; + IndexDeletionPolicy* deletionPolicy; + DirectoryIndexReader* _this; + protected: + DirectoryIndexReader* doBody(const char* segmentFileName) { + SegmentInfos* infos = _CLNEW SegmentInfos(); + infos->read(directory, segmentFileName); + + DirectoryIndexReader* newReader = _this->doReopen(infos); + + if (_this != newReader) { + newReader->init(directory, infos, closeDirectory); + newReader->deletionPolicy = deletionPolicy; + } + + return newReader; + } + public: + FindSegmentsFile_Reopen( bool closeDirectory, IndexDeletionPolicy* deletionPolicy, + CL_NS(store)::Directory* dir, DirectoryIndexReader* _this ): + SegmentInfos::FindSegmentsFile(dir) + { + this->closeDirectory = closeDirectory; + this->deletionPolicy = deletionPolicy; + this->_this = _this; + } + }; + + IndexReader* DirectoryIndexReader::reopen(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + + if (this->hasChanges || this->isCurrent()) { + // the index hasn't changed - nothing to do here + return this; + } + FindSegmentsFile_Reopen runner(closeDirectory, deletionPolicy, _directory, this); + IndexReader* ret = runner.run(); + + //disown this memory... + this->writeLock = NULL; + this->_directory = NULL; + this->deletionPolicy = NULL; + + return ret; + } + + void DirectoryIndexReader::setDeletionPolicy(IndexDeletionPolicy* deletionPolicy) { + this->deletionPolicy = deletionPolicy; + } + + /** Returns the directory this index resides in. + */ + Directory* DirectoryIndexReader::directory() { + ensureOpen(); + return _directory; + } + + /** + * Version number when this IndexReader was opened. + */ + int64_t DirectoryIndexReader::getVersion() { + ensureOpen(); + return segmentInfos->getVersion(); + } + + /** + * Check whether this IndexReader is still using the + * current (i.e., most recently committed) version of the + * index. If a writer has committed any changes to the + * index since this reader was opened, this will return + * false, in which case you must open a _CLNEW + * IndexReader in order to see the changes. See the + * description of the autoCommit + * flag which controls when the {@link IndexWriter} + * actually commits changes to the index. + * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + bool DirectoryIndexReader::isCurrent(){ + ensureOpen(); + return SegmentInfos::readCurrentVersion(_directory) == segmentInfos->getVersion(); + } + + /** + * Checks is the index is optimized (if it has a single segment and no deletions) + * @return true if the index is optimized; false otherwise + */ + bool DirectoryIndexReader::isOptimized() { + ensureOpen(); + return segmentInfos->size() == 1 && hasDeletions() == false; + } + + /** + * Should internally checkpoint state that will change + * during commit so that we can rollback if necessary. + */ + void DirectoryIndexReader::startCommit() { + if (segmentInfos != NULL) { + rollbackSegmentInfos = segmentInfos->clone(); + } + rollbackHasChanges = hasChanges; + } + + /** + * Rolls back state to just before the commit (this is + * called by commit() if there is some exception while + * committing). + */ + void DirectoryIndexReader::rollbackCommit() { + if (segmentInfos != NULL) { + for(int32_t i=0;isize();i++) { + // Rollback each segmentInfo. Because the + // SegmentReader holds a reference to the + // SegmentInfo we can't [easily] just replace + // segmentInfos, so we reset it in place instead: + segmentInfos->info(i)->reset(rollbackSegmentInfos->info(i)); + } + _CLDELETE(rollbackSegmentInfos); + } + + hasChanges = rollbackHasChanges; + } + +CL_NS_END diff --git a/src/core/CLucene/index/DirectoryIndexReader.h b/src/core/CLucene/index/DirectoryIndexReader.h new file mode 100644 index 00000000000..62d315087d4 --- /dev/null +++ b/src/core/CLucene/index/DirectoryIndexReader.h @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_DirectoryIndexReader_ +#define _lucene_index_DirectoryIndexReader_ + +#include "IndexReader.h" + +CL_CLASS_DEF(store,LuceneLock) + +CL_NS_DEF(index) +class IndexDeletionPolicy; + +/** + * IndexReader implementation that has access to a Directory. + * Instances that have a SegmentInfos object (i. e. segmentInfos != null) + * "own" the directory, which means that they try to acquire a write lock + * whenever index modifications are performed. + */ +class CLUCENE_EXPORT DirectoryIndexReader: public IndexReader { +private: + IndexDeletionPolicy* deletionPolicy; + + SegmentInfos* segmentInfos; + CL_NS(store)::LuceneLock* writeLock; + bool stale; + + /** Used by commit() to record pre-commit state in case + * rollback is necessary */ + bool rollbackHasChanges; + SegmentInfos* rollbackSegmentInfos; + + class FindSegmentsFile_Open; + class FindSegmentsFile_Reopen; + friend class FindSegmentsFile_Open; + friend class FindSegmentsFile_Reopen; + +protected: + CL_NS(store)::Directory* _directory; + bool closeDirectory; + DirectoryIndexReader(); + + /** + * Re-opens the index using the passed-in SegmentInfos + */ + virtual DirectoryIndexReader* doReopen(SegmentInfos* infos) = 0; + + + void doClose(); + + /** + * Commit changes resulting from delete, undeleteAll, or + * setNorm operations + * + * If an exception is hit, then either no changes or all + * changes will have been committed to the index + * (transactional semantics). + * @throws IOException if there is a low-level IO error + */ + void doCommit(); + + virtual void commitChanges() = 0; + + /** + * Tries to acquire the WriteLock on this directory-> + * this method is only valid if this IndexReader is directory owner. + * + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if there is a low-level IO error + */ + void acquireWriteLock(); + +public: + virtual ~DirectoryIndexReader(); + void init(CL_NS(store)::Directory* directory, SegmentInfos* segmentInfos, bool closeDirectory); + + CLUCENE_LOCAL_DECL DirectoryIndexReader(CL_NS(store)::Directory* directory, SegmentInfos* segmentInfos, bool closeDirectory); + CLUCENE_LOCAL_DECL static DirectoryIndexReader* open(CL_NS(store)::Directory* directory, bool closeDirectory, IndexDeletionPolicy* deletionPolicy); + + IndexReader* reopen(); + + void setDeletionPolicy(IndexDeletionPolicy* deletionPolicy); + + /** Returns the directory this index resides in. + */ + CL_NS(store)::Directory* directory(); + + /** + * Version number when this IndexReader was opened. + */ + int64_t getVersion(); + + /** + * Check whether this IndexReader is still using the + * current (i.e., most recently committed) version of the + * index. If a writer has committed any changes to the + * index since this reader was opened, this will return + * false, in which case you must open a _CLNEW + * IndexReader in order to see the changes. See the + * description of the autoCommit + * flag which controls when the {@link IndexWriter} + * actually commits changes to the index. + * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + bool isCurrent(); + + /** + * Checks is the index is optimized (if it has a single segment and no deletions) + * @return true if the index is optimized; false otherwise + */ + bool isOptimized(); + + /** + * Should internally checkpoint state that will change + * during commit so that we can rollback if necessary. + */ + CLUCENE_LOCAL_DECL void startCommit(); + + /** + * Rolls back state to just before the commit (this is + * called by commit() if there is some exception while + * committing). + */ + CLUCENE_LOCAL_DECL void rollbackCommit(); + +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/DocumentsWriter.cpp b/src/core/CLucene/index/DocumentsWriter.cpp new file mode 100644 index 00000000000..b8bdead7403 --- /dev/null +++ b/src/core/CLucene/index/DocumentsWriter.cpp @@ -0,0 +1,1683 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/_Arrays.h" +#include "IndexWriter.h" +#include "Term.h" +#include "_Term.h" +#include "_TermInfo.h" +#include "_TermInfosWriter.h" +#include "_TermVector.h" + +#include "_CompoundFile.h" +#include "_DocumentsWriter.h" +#include "_FieldInfos.h" +#include "_FieldsWriter.h" +#include "_IndexFileNames.h" +#include "_SkipListWriter.h" +#include "vp4.h" + +#include +#include +#include + +#if defined(USE_AVX2) && defined(__x86_64__) +#define P4ENC p4nd1enc256v32 +#else +#define P4ENC p4nd1enc128v32 +#endif + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(analysis) +CL_NS_USE(document) +CL_NS_USE(search) +CL_NS_DEF(index) + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +const int32_t DocumentsWriter::MAX_THREAD_STATE = 5; +const uint8_t DocumentsWriter::defaultNorm = Similarity::encodeNorm(1.0f); +const int32_t DocumentsWriter::nextLevelArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; +const int32_t DocumentsWriter::levelSizeArray[10] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; +const int32_t DocumentsWriter::POSTING_NUM_BYTE = OBJECT_HEADER_BYTES + 9 * INT_NUM_BYTE + 5 * POINTER_NUM_BYTE; + +const int32_t DocumentsWriter::BYTE_BLOCK_SHIFT = 15; +const int32_t DocumentsWriter::BYTE_BLOCK_SIZE = (int32_t) pow(2.0, BYTE_BLOCK_SHIFT); +const int32_t DocumentsWriter::BYTE_BLOCK_MASK = BYTE_BLOCK_SIZE - 1; +const int32_t DocumentsWriter::BYTE_BLOCK_NOT_MASK = ~BYTE_BLOCK_MASK; + +const int32_t DocumentsWriter::CHAR_BLOCK_SHIFT = 14; +const int32_t DocumentsWriter::CHAR_BLOCK_SIZE = (int32_t) pow(2.0, CHAR_BLOCK_SHIFT); +const int32_t DocumentsWriter::CHAR_BLOCK_MASK = CHAR_BLOCK_SIZE - 1; + +int32_t DocumentsWriter::OBJECT_HEADER_BYTES = 8; +int32_t DocumentsWriter::OBJECT_POINTER_BYTES = 4;// TODO: should be 8 on 64-bit platform +int32_t DocumentsWriter::BYTES_PER_CHAR = 2; +int32_t DocumentsWriter::BYTES_PER_INT = 4; + +const int32_t DocumentsWriter::POINTER_NUM_BYTE = 4; +const int32_t DocumentsWriter::INT_NUM_BYTE = 4; +const int32_t DocumentsWriter::CHAR_NUM_BYTE = 2;//TODO: adjust for c++... + +const int32_t DocumentsWriter::MAX_TERM_LENGTH = DocumentsWriter::CHAR_BLOCK_SIZE - 1; + + +AbortException::AbortException(CLuceneError &_err, DocumentsWriter *docWriter) : err(_err) { + docWriter->setAborting(); +} + +DocumentsWriter::DocumentsWriter(CL_NS(store)::Directory *directory, IndexWriter *writer) : bufferedDeleteTerms(_CLNEW TermNumMapType(true, true)), + freeCharBlocks(FreeCharBlocksType(true)), + freeByteBlocks(FreeByteBlocksType(true)), + waitingThreadStates(CL_NS(util)::ValueArray(MAX_THREAD_STATE)) { + numBytesAlloc = 0; + numBytesUsed = 0; + this->directory = directory; + this->writer = writer; + this->hasNorms = this->bufferIsFull = false; + fieldInfos = _CLNEW FieldInfos(); + + maxBufferedDeleteTerms = IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS; + ramBufferSize = (int64_t) (IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB * 1024 * 1024); + maxBufferedDocs = IndexWriter::DEFAULT_MAX_BUFFERED_DOCS; + + numBufferedDeleteTerms = 0; + copyByteBuffer = _CL_NEWARRAY(uint8_t, 4096); + *copyByteBuffer = 0; + + this->closed = this->flushPending = false; + _files = NULL; + _abortedFiles = NULL; + skipListWriter = NULL; + infoStream = NULL; + fieldsWriter = NULL; + tvx = tvf = tvd = NULL; + postingsFreeCountDW = postingsAllocCountDW = numWaiting = pauseThreads = abortCount = 0; + docStoreOffset = nextDocID = numDocsInRAM = numDocsInStore = nextWriteDocID = 0; +} +DocumentsWriter::~DocumentsWriter() { + _CLLDELETE(bufferedDeleteTerms); + _CLLDELETE(skipListWriter); + _CLDELETE_LARRAY(copyByteBuffer); + _CLLDELETE(_files); + _CLLDELETE(fieldInfos); + + for (size_t i = 0; i < threadStates.length; i++) { + _CLLDELETE(threadStates.values[i]); + } + + // Make sure unused posting slots aren't attempted delete on + if (this->postingsFreeListDW.values) { + if (this->postingsFreeCountDW < this->postingsFreeListDW.length) { + memset(this->postingsFreeListDW.values + this->postingsFreeCountDW, NULL, sizeof(Posting *)); + } + postingsFreeListDW.deleteUntilNULL(); + } +} + +void DocumentsWriter::setInfoStream(std::ostream *infoStream) { + this->infoStream = infoStream; +} + +void DocumentsWriter::setRAMBufferSizeMB(float_t mb) { + if ((int32_t) mb == IndexWriter::DISABLE_AUTO_FLUSH) { + ramBufferSize = IndexWriter::DISABLE_AUTO_FLUSH; + } else { + ramBufferSize = (int64_t) (mb * 1024 * 1024); + } +} + +float_t DocumentsWriter::getRAMBufferSizeMB() { + if (ramBufferSize == IndexWriter::DISABLE_AUTO_FLUSH) { + return (float_t) ramBufferSize; + } else { + return ramBufferSize / 1024.0 / 1024.0; + } +} + +void DocumentsWriter::setMaxBufferedDocs(int32_t count) { + maxBufferedDocs = count; +} + +int32_t DocumentsWriter::getMaxBufferedDocs() { + return maxBufferedDocs; +} + +std::string DocumentsWriter::getSegment() { + return segment; +} + +int32_t DocumentsWriter::getNumDocsInRAM() { + return numDocsInRAM; +} + +const std::string &DocumentsWriter::getDocStoreSegment() { + return docStoreSegment; +} + +int32_t DocumentsWriter::getDocStoreOffset() { + return docStoreOffset; +} + +std::string DocumentsWriter::closeDocStore() { + + assert(allThreadsIdle()); + + const std::vector &flushedFiles = files(); + + if (infoStream != NULL) + (*infoStream) << string("\ncloseDocStore: ") << Misc::toString((int32_t) flushedFiles.size()) << string(" files to flush to segment ") << docStoreSegment << string(" numDocs=") << Misc::toString(numDocsInStore) << string("\n"); + + if (flushedFiles.size() > 0) { + _CLDELETE(_files); + + if (tvx != NULL) { + // At least one doc in this run had term vectors enabled + assert(!docStoreSegment.empty()); + tvx->close(); + _CLDELETE(tvx); + tvf->close(); + _CLDELETE(tvf); + tvd->close(); + _CLDELETE(tvd); + + assert(4 + numDocsInStore * 8 == directory->fileLength((docStoreSegment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION).c_str()));// "after flush: tvx size mismatch: " + numDocsInStore + " docs vs " + directory->fileLength(docStoreSegment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION) + " length in bytes of " + docStoreSegment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION; + } + + if (fieldsWriter != NULL) { + assert(!docStoreSegment.empty()); + fieldsWriter->close(); + _CLDELETE(fieldsWriter); + + assert(numDocsInStore * 8 == directory->fileLength((docStoreSegment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION).c_str()));// "after flush: fdx size mismatch: " + numDocsInStore + " docs vs " + directory->fileLength(docStoreSegment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION) + " length in bytes of " + docStoreSegment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION; + } + + std::string s = docStoreSegment; + docStoreSegment.clear(); + docStoreOffset = 0; + numDocsInStore = 0; + return s; + } else { + return ""; + } +} + +const std::vector *DocumentsWriter::abortedFiles() { + return _abortedFiles; +} + +const std::vector &DocumentsWriter::files() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (_files != NULL) + return *_files; + + _files = _CLNEW std::vector; + + // Stored fields: + if (fieldsWriter != NULL) { + assert(!docStoreSegment.empty()); + _files->push_back(docStoreSegment + "." + IndexFileNames::FIELDS_EXTENSION); + _files->push_back(docStoreSegment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION); + } + + // Vectors: + if (tvx != NULL) { + assert(!docStoreSegment.empty()); + _files->push_back(docStoreSegment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION); + _files->push_back(docStoreSegment + "." + IndexFileNames::VECTORS_FIELDS_EXTENSION); + _files->push_back(docStoreSegment + "." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION); + } + + return *_files; +} + +void DocumentsWriter::setAborting() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + abortCount++; +} + +void DocumentsWriter::abort(AbortException *ae) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + // Anywhere that throws an AbortException must first + // mark aborting to make sure while the exception is + // unwinding the un-synchronized stack, no thread grabs + // the corrupt ThreadState that hit the aborting + // exception: + assert(ae == NULL || abortCount > 0); + + try { + + if (infoStream != NULL) + (*infoStream) << string("docWriter: now abort\n"); + + // Forcefully remove waiting ThreadStates from line + for (int32_t i = 0; i < numWaiting; i++) + waitingThreadStates[i]->isIdle = true; + numWaiting = 0; + + // Wait for all other threads to finish with DocumentsWriter: + pauseAllThreads(); + + assert(0 == numWaiting); + + try { + bufferedDeleteTerms->clear(); + bufferedDeleteDocIDs.clear(); + numBufferedDeleteTerms = 0; + + try { + const std::vector &__abortedFiles = files(); + _abortedFiles = _CLNEW std::vector; + for (std::vector::const_iterator itr = __abortedFiles.begin(); + itr != __abortedFiles.end(); itr++) { + _abortedFiles->push_back(*itr); + } + } catch (...) { + _CLDELETE(_abortedFiles); + } + + docStoreSegment.clear(); + numDocsInStore = 0; + docStoreOffset = 0; + _CLDELETE(_files); + + // Clear vectors & fields from ThreadStates + for (size_t i = 0; i < threadStates.length; i++) { + ThreadState *state = threadStates[i]; + state->tvfLocal->reset(); + state->fdtLocal->reset(); + if (state->localFieldsWriter != NULL) { + try { + state->localFieldsWriter->close(); + } catch (...) { + } + _CLDELETE(state->localFieldsWriter); + } + } + + // Reset vectors writer + if (tvx != NULL) { + try { + tvx->close(); + } catch (...) { + } + _CLDELETE(tvx); + } + if (tvd != NULL) { + try { + tvd->close(); + } catch (...) { + } + _CLDELETE(tvd); + } + if (tvf != NULL) { + try { + tvf->close(); + } catch (...) { + } + _CLDELETE(tvf); + } + + // Reset fields writer + if (fieldsWriter != NULL) { + try { + fieldsWriter->close(); + } catch (...) { + } + _CLDELETE(fieldsWriter); + } + + // Discard pending norms: + const int32_t numField = fieldInfos->size(); + for (int32_t i = 0; i < numField; i++) { + FieldInfo *fi = fieldInfos->fieldInfo(i); + if (fi->isIndexed && !fi->omitNorms) { + BufferedNorms *n = norms[i]; + if (n != NULL) + try { + n->reset(); + } catch (...) { + } + } + } + + // Reset all postings data + resetPostingsData(); + } + _CLFINALLY( + resumeAllThreads();) + + // If we have a root cause exception, re-throw it now: + if (ae != NULL) { + CLuceneError &t = ae->err; + throw t; + } + } + _CLFINALLY( + if (ae != NULL) + abortCount--; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION)) +} + +void DocumentsWriter::resetPostingsData() { + // All ThreadStates should be idle when we are called + assert(allThreadsIdle()); + threadBindings.clear(); + segment.erase(); + numDocsInRAM = 0; + nextDocID = 0; + nextWriteDocID = 0; + _CLDELETE(_files); + balanceRAM(); + bufferIsFull = false; + flushPending = false; + for (size_t i = 0; i < threadStates.length; i++) { + threadStates[i]->numThreads = 0; + threadStates[i]->resetPostings(); + } + numBytesUsed = 0; +} + +// Returns true if an abort is in progress +bool DocumentsWriter::pauseAllThreads() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + pauseThreads++; + while (!allThreadsIdle()) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } + return abortCount > 0; +} + +void DocumentsWriter::resumeAllThreads() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + pauseThreads--; + assert(pauseThreads >= 0); + if (0 == pauseThreads) { + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + } +} + +bool DocumentsWriter::allThreadsIdle() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + for (size_t i = 0; i < threadStates.length; i++) + if (!threadStates[i]->isIdle) + return false; + return true; +} + +int32_t DocumentsWriter::flush(bool _closeDocStore) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + assert(allThreadsIdle()); + + if (segment.empty()) { + // In case we are asked to flush an empty segment + segment = writer->newSegmentName(); + } + + newFiles.clear(); + + docStoreOffset = numDocsInStore; + + int32_t docCount; + + assert(numDocsInRAM > 0); + + if (infoStream != NULL) + (*infoStream) << string("\nflush postings as segment ") << segment << string(" numDocs=") << Misc::toString(numDocsInRAM) << string("\n"); + + bool success = false; + + try { + + if (_closeDocStore) { + assert(!docStoreSegment.empty()); + assert(docStoreSegment.compare(segment) == 0); + const std::vector &tmp = files(); + for (std::vector::const_iterator itr = tmp.begin(); + itr != tmp.end(); itr++) + newFiles.push_back(*itr); + closeDocStore(); + } + + fieldInfos->write(directory, (segment + ".fnm").c_str()); + + docCount = numDocsInRAM; + + writeSegment(newFiles);//write new files directly... + + success = true; + } + _CLFINALLY( + if (!success) + abort(NULL);) + + return docCount; +} + +void DocumentsWriter::createCompoundFile(const std::string &segment) { + CompoundFileWriter *cfsWriter = _CLNEW CompoundFileWriter(directory, (segment + "." + IndexFileNames::COMPOUND_FILE_EXTENSION).c_str()); + for (std::vector::const_iterator itr = newFiles.begin(); + itr != newFiles.end(); itr++) + cfsWriter->addFile((*itr).c_str()); + + // Perform the merge + cfsWriter->close(); + _CLDELETE(cfsWriter); +} + +bool DocumentsWriter::setFlushPending() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (flushPending) + return false; + else { + flushPending = true; + return true; + } +} + +void DocumentsWriter::clearFlushPending() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + flushPending = false; +} + +void DocumentsWriter::writeNorms(const std::string &segmentName, int32_t totalNumDoc) { + IndexOutput *normsOut = directory->createOutput((segmentName + "." + IndexFileNames::NORMS_EXTENSION).c_str()); + + try { + normsOut->writeBytes(SegmentMerger::NORMS_HEADER, SegmentMerger::NORMS_HEADER_length); + + const int32_t numField = fieldInfos->size(); + + for (int32_t fieldIdx = 0; fieldIdx < numField; fieldIdx++) { + FieldInfo *fi = fieldInfos->fieldInfo(fieldIdx); + if (fi->isIndexed && !fi->omitNorms) { + BufferedNorms *n = norms[fieldIdx]; + int64_t v; + if (n == NULL) + v = 0; + else { + v = n->out.getFilePointer(); + n->out.writeTo(normsOut); + n->reset(); + } + if (v < totalNumDoc) + fillBytes(normsOut, defaultNorm, (int32_t) (totalNumDoc - v)); + } + } + } + _CLFINALLY( + normsOut->close(); + _CLDELETE(normsOut);) +} + +void DocumentsWriter::writeSegment(std::vector &flushedFiles) { + + assert(allThreadsIdle()); + + assert(nextDocID == numDocsInRAM); + + const std::string segmentName = segment; + + TermInfosWriter *termsOut = _CLNEW TermInfosWriter(directory, segmentName.c_str(), fieldInfos, + writer->getTermIndexInterval()); + + IndexOutput *freqOut = directory->createOutput((segmentName + ".frq").c_str()); + // TODO:add options in field index + IndexOutput *proxOut = nullptr; + if (0) { + proxOut = directory->createOutput((segmentName + ".prx").c_str()); + } + + // Gather all FieldData's that have postings, across all + // ThreadStates + std::vector allFields; + assert(allThreadsIdle()); + for (size_t i = 0; i < threadStates.length; i++) { + ThreadState *state = threadStates[i]; + state->trimFields(); + const int32_t numFields = state->numAllFieldData; + for (int32_t j = 0; j < numFields; j++) { + ThreadState::FieldData *fp = state->allFieldDataArray[j]; + if (fp->numPostings > 0) + allFields.push_back(fp); + } + } + + // Sort by field name + std::sort(allFields.begin(), allFields.end(), ThreadState::FieldData::sort); + const int32_t numAllFields = allFields.size(); + + skipListWriter = _CLNEW DefaultSkipListWriter(termsOut->skipInterval, + termsOut->maxSkipLevels, + numDocsInRAM, freqOut, proxOut); + + int32_t start = 0; + while (start < numAllFields) { + + const TCHAR *fieldName = allFields[start]->fieldInfo->name; + + int32_t end = start + 1; + while (end < numAllFields && _tcscmp(allFields[end]->fieldInfo->name, fieldName) == 0) + end++; + + ValueArray fields(end - start); + for (int32_t i = start; i < end; i++) + fields.values[i - start] = allFields[i]; + + // If this field has postings then add them to the + // segment + appendPostings(&fields, termsOut, freqOut, proxOut); + + for (size_t i = 0; i < fields.length; i++) + fields[i]->resetPostingArrays(); + + start = end; + } + + freqOut->close(); + _CLDELETE(freqOut); + if (proxOut != nullptr) { + proxOut->close(); + _CLDELETE(proxOut); + } + termsOut->close(); + _CLDELETE(termsOut); + _CLDELETE(skipListWriter); + + // Record all files we have flushed + flushedFiles.push_back(segmentFileName(IndexFileNames::FIELD_INFOS_EXTENSION)); + flushedFiles.push_back(segmentFileName(IndexFileNames::FREQ_EXTENSION)); + if (0) { + flushedFiles.push_back(segmentFileName(IndexFileNames::PROX_EXTENSION)); + } + flushedFiles.push_back(segmentFileName(IndexFileNames::TERMS_EXTENSION)); + flushedFiles.push_back(segmentFileName(IndexFileNames::TERMS_INDEX_EXTENSION)); + + if (hasNorms) { + writeNorms(segmentName, numDocsInRAM); + flushedFiles.push_back(segmentFileName(IndexFileNames::NORMS_EXTENSION)); + } + + if (infoStream != NULL) { + const int64_t newSegmentSize = segmentSize(segmentName); + + (*infoStream) << string(" oldRAMSize=") << Misc::toString(numBytesUsed) << string(" newFlushedSize=") << Misc::toString(newSegmentSize) << string(" docs/MB=") << Misc::toString((float_t) (numDocsInRAM / (newSegmentSize / 1024.0 / 1024.0))) << string(" new/old=") << Misc::toString((float_t) (100.0 * newSegmentSize / numBytesUsed)) << string("%\n"); + } + + resetPostingsData(); + + nextDocID = 0; + nextWriteDocID = 0; + numDocsInRAM = 0; + _CLDELETE(_files); + + // Maybe downsize this->postingsFreeListDW array + if (this->postingsFreeListDW.length > 1.5 * this->postingsFreeCountDW) { + int32_t newSize = this->postingsFreeListDW.length; + while (newSize > 1.25 * this->postingsFreeCountDW) { + newSize = (int32_t) (newSize * 0.8); + } + this->postingsFreeListDW.resize(newSize); + } +} + +std::string DocumentsWriter::segmentFileName(const char *extension) { + return segmentFileName(string(extension)); +} +std::string DocumentsWriter::segmentFileName(const std::string &extension) { + return segment + "." + extension; +} + +int32_t DocumentsWriter::compareText(const TCHAR *text1, const TCHAR *text2) { + int32_t pos1 = 0; + int32_t pos2 = 0; + while (true) { + const TCHAR c1 = text1[pos1++]; + const TCHAR c2 = text2[pos2++]; + if (c1 < c2) + if (CLUCENE_END_OF_WORD == c2) + return 1; + else + return -1; + else if (c2 < c1) + if (CLUCENE_END_OF_WORD == c1) + return -1; + else + return 1; + else if (CLUCENE_END_OF_WORD == c1) + return 0; + } +} + + +void DocumentsWriter::appendPostings(ArrayBase *fields, + TermInfosWriter *termsOut, + IndexOutput *freqOut, + IndexOutput *proxOut) { + + const int32_t fieldNumber = (*fields)[0]->fieldInfo->number; + int32_t numFields = fields->length; + + ObjectArray mergeStatesData(numFields); + ValueArray mergeStates(numFields); + + for (int32_t i = 0; i < numFields; i++) { + FieldMergeState *fms = mergeStatesData.values[i] = _CLNEW FieldMergeState(); + fms->field = (*fields)[i]; + fms->postings = fms->field->sortPostings(); + + assert(fms->field->fieldInfo == (*fields)[0]->fieldInfo); + + // Should always be true + bool result = fms->nextTerm(); + assert(result); + } + memcpy(mergeStates.values, mergeStatesData.values, sizeof(FieldMergeState *) * numFields); + + const int32_t skipInterval = termsOut->skipInterval; + currentFieldStorePayloads = (*fields)[0]->fieldInfo->storePayloads; + + ValueArray termStates(numFields); + + while (numFields > 0) { + + // Get the next term to merge + termStates.values[0] = mergeStates[0]; + int32_t numToMerge = 1; + + for (int32_t i = 1; i < numFields; i++) { + const TCHAR *text = mergeStates[i]->text; + const int32_t textOffset = mergeStates[i]->textOffset; + const int32_t cmp = compareText(text + textOffset, termStates[0]->text + termStates[0]->textOffset); + + if (cmp < 0) { + termStates.values[0] = mergeStates[i]; + numToMerge = 1; + } else if (cmp == 0) + termStates.values[numToMerge++] = mergeStates[i]; + } + + int32_t df = 0; + int32_t lastPayloadLength = -1; + + int32_t lastDoc = 0; + + const TCHAR *start = termStates[0]->text + termStates[0]->textOffset; + const TCHAR *pos = start; + while (*pos != CLUCENE_END_OF_WORD) + pos++; + + int64_t freqPointer = freqOut->getFilePointer(); + int64_t proxPointer = 0; + if (proxOut != nullptr) { + proxPointer = proxOut->getFilePointer(); + } + + skipListWriter->resetSkip(); + + // Now termStates has numToMerge FieldMergeStates + // which all share the same term. Now we must + // interleave the docID streams. + while (numToMerge > 0) { + + if ((++df % skipInterval) == 0) { + skipListWriter->setSkipData(lastDoc, currentFieldStorePayloads, lastPayloadLength); + skipListWriter->bufferSkip(df); + } + + FieldMergeState *minState = termStates[0]; + for (int32_t i = 1; i < numToMerge; i++) + if (termStates[i]->docID < minState->docID) + minState = termStates[i]; + + const int32_t doc = minState->docID; + const int32_t termDocFreq = minState->termFreq; + + assert(doc < numDocsInRAM); + assert(doc > lastDoc || df == 1); + + const int32_t newDocCode = (doc - lastDoc) << 1; + lastDoc = doc; + + ByteSliceReader &prox = minState->prox; + + // Carefully copy over the prox + payload info, + // changing the format to match Lucene's segment + // format. + if (proxOut != nullptr) { + for (int32_t j = 0; j < termDocFreq; j++) { + const int32_t code = prox.readVInt(); + if (currentFieldStorePayloads) { + int32_t payloadLength; + if ((code & 1) != 0) { + // This position has a payload + payloadLength = prox.readVInt(); + } else + payloadLength = 0; + if (payloadLength != lastPayloadLength) { + proxOut->writeVInt(code | 1); + proxOut->writeVInt(payloadLength); + lastPayloadLength = payloadLength; + } else + proxOut->writeVInt(code & (~1)); + if (payloadLength > 0) + copyBytes(&prox, proxOut, payloadLength); + } else { + assert(0 == (code & 1)); + proxOut->writeVInt(code >> 1); + } + } + } + + docDeltaBuffer.push_back(doc); + + /*if (1 == termDocFreq) { + freqOut->writeVInt(newDocCode | 1); + } else { + freqOut->writeVInt(newDocCode); + freqOut->writeVInt(termDocFreq); + }*/ + if (docDeltaBuffer.size() == PFOR_BLOCK_SIZE) { + std::vector compresseddata(4 * docDeltaBuffer.size() + PFOR_BLOCK_SIZE); + auto size = P4ENC(docDeltaBuffer.data(), docDeltaBuffer.size(), compresseddata.data()); + //auto size = p4nd1enc256v32(docDeltaBuffer.data(), docDeltaBuffer.size(), compresseddata.data()); + freqOut->writeVInt(docDeltaBuffer.size()); + freqOut->writeVInt(size); + freqOut->writeBytes(reinterpret_cast(compresseddata.data()), size); + docDeltaBuffer.resize(0); + } + + + if (!minState->nextDoc()) { + + // Remove from termStates + int32_t upto = 0; + for (int32_t i = 0; i < numToMerge; i++) + if (termStates[i] != minState) + termStates.values[upto++] = termStates[i]; + numToMerge--; + assert(upto == numToMerge); + + // Advance this state to the next term + + if (!minState->nextTerm()) { + // OK, no more terms, so remove from mergeStates + // as well + upto = 0; + for (int32_t i = 0; i < numFields; i++) + if (mergeStates[i] != minState) { + mergeStates.values[upto++] = mergeStates[i]; + } + numFields--; + assert(upto == numFields); + } + } + } + + assert(df > 0); + + // Done merging this term + freqOut->writeVInt(docDeltaBuffer.size()); + uint32_t lDoc = 0; + for (auto &docDelta: docDeltaBuffer) { + freqOut->writeVInt(docDelta - lDoc); + lDoc = docDelta; + } + docDeltaBuffer.resize(0); + int64_t skipPointer = skipListWriter->writeSkip(freqOut); + + // Write term + termInfo.set(df, freqPointer, proxPointer, (int32_t) (skipPointer - freqPointer)); + termsOut->add(fieldNumber, start, pos - start, &termInfo); + } +} + + +void DocumentsWriter::close() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + closed = true; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) +} + +DocumentsWriter::ThreadState *DocumentsWriter::getThreadState(Document *doc, Term *delTerm) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + // First, find a thread state. If this thread already + // has affinity to a specific ThreadState, use that one + // again. + ThreadState *state = NULL; + if (threadBindings.find(_LUCENE_CURRTHREADID) == threadBindings.end()) { + // First time this thread has called us since last flush + ThreadState *minThreadState = NULL; + for (size_t i = 0; i < threadStates.length; i++) { + ThreadState *ts = threadStates[i]; + if (minThreadState == NULL || ts->numThreads < minThreadState->numThreads) + minThreadState = ts; + } + if (minThreadState != NULL && (minThreadState->numThreads == 0 || threadStates.length == MAX_THREAD_STATE)) { + state = minThreadState; + state->numThreads++; + } else { + // Just create a new "private" thread state + threadStates.resize(1 + threadStates.length); + //fill the new position + state = threadStates.values[threadStates.length - 1] = _CLNEW ThreadState(this); + } + threadBindings.put(_LUCENE_CURRTHREADID, state); + } else { + state = threadBindings[_LUCENE_CURRTHREADID]; + } + + // Next, wait until my thread state is idle (in case + // it's shared with other threads) and for threads to + // not be paused nor a flush pending: + while (!closed && (!state->isIdle || pauseThreads != 0 || flushPending || abortCount > 0)) + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + + if (closed) + _CLTHROWA(CL_ERR_AlreadyClosed, "this IndexWriter is closed"); + + if (segment.empty()) + segment = writer->newSegmentName(); + + state->isIdle = false; + + try { + bool success = false; + try { + state->init(doc, nextDocID); + if (delTerm != NULL) { + addDeleteTerm(delTerm, state->docID); + state->doFlushAfter = timeToFlushDeletes(); + } + // Only increment nextDocID & numDocsInRAM on successful init + nextDocID++; + numDocsInRAM++; + + // We must at this point commit to flushing to ensure we + // always get N docs when we flush by doc count, even if + // > 1 thread is adding documents: + if (!flushPending && maxBufferedDocs != IndexWriter::DISABLE_AUTO_FLUSH && numDocsInRAM >= maxBufferedDocs) { + flushPending = true; + state->doFlushAfter = true; + } + + success = true; + } + _CLFINALLY( + if (!success) { + // Forcefully idle this ThreadState: + state->isIdle = true; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + if (state->doFlushAfter) { + state->doFlushAfter = false; + flushPending = false; + } + }) + } catch (AbortException &ae) { + abort(&ae); + } + + return state; +} + +bool DocumentsWriter::addDocument(Document *doc, Analyzer *analyzer) { + return updateDocument(doc, analyzer, NULL); +} + +bool DocumentsWriter::updateDocument(Term *t, Document *doc, Analyzer *analyzer) { + return updateDocument(doc, analyzer, t); +} + +bool DocumentsWriter::updateDocument(Document *doc, Analyzer *analyzer, Term *delTerm) { + + // This call is synchronized but fast + ThreadState *state = getThreadState(doc, delTerm); + try { + bool success = false; + try { + try { + // This call is not synchronized and does all the work + state->processDocument(analyzer); + } + _CLFINALLY( + // This call is synchronized but fast + finishDocument(state);) + success = true; + } + _CLFINALLY( + if (!success) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + // If this thread state had decided to flush, we + // must clear it so another thread can flush + if (state->doFlushAfter) { + state->doFlushAfter = false; + flushPending = false; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + } + + // Immediately mark this document as deleted + // since likely it was partially added. This + // keeps indexing as "all or none" (atomic) when + // adding a document: + addDeleteDocID(state->docID); + }) + } catch (AbortException &ae) { + abort(&ae); + } + + return state->doFlushAfter || timeToFlushDeletes(); +} + +int32_t DocumentsWriter::getNumBufferedDeleteTerms() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return numBufferedDeleteTerms; +} + +const TermNumMapType &DocumentsWriter::getBufferedDeleteTerms() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return *bufferedDeleteTerms; +} + +const std::vector *DocumentsWriter::getBufferedDeleteDocIDs() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return &bufferedDeleteDocIDs; +} + +// Reset buffered deletes. +void DocumentsWriter::clearBufferedDeletes() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + TermNumMapType::iterator term = bufferedDeleteTerms->begin(); + while (term != bufferedDeleteTerms->end()) { + Term *t = term->first; + _CLDELETE(term->second); + bufferedDeleteTerms->erase(term); + _CLDECDELETE(t); + term = bufferedDeleteTerms->begin(); + } + bufferedDeleteDocIDs.clear(); + numBufferedDeleteTerms = 0; + if (numBytesUsed > 0) + resetPostingsData(); +} + +bool DocumentsWriter::bufferDeleteTerms(const ArrayBase *terms) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + while (pauseThreads != 0 || flushPending) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } + for (size_t i = 0; i < terms->length; i++) + addDeleteTerm((*terms)[i], numDocsInRAM); + return timeToFlushDeletes(); +} + +bool DocumentsWriter::bufferDeleteTerm(Term *term) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + while (pauseThreads != 0 || flushPending) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } + addDeleteTerm(term, numDocsInRAM); + return timeToFlushDeletes(); +} + +bool DocumentsWriter::timeToFlushDeletes() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return (bufferIsFull || (maxBufferedDeleteTerms != IndexWriter::DISABLE_AUTO_FLUSH && numBufferedDeleteTerms >= maxBufferedDeleteTerms)) && setFlushPending(); +} + +void DocumentsWriter::setMaxBufferedDeleteTerms(int32_t _maxBufferedDeleteTerms) { + this->maxBufferedDeleteTerms = _maxBufferedDeleteTerms; +} + +int32_t DocumentsWriter::getMaxBufferedDeleteTerms() { + return maxBufferedDeleteTerms; +} + +bool DocumentsWriter::hasDeletes() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return bufferedDeleteTerms->size() > 0 || bufferedDeleteDocIDs.size() > 0; +} + +// Buffer a term in bufferedDeleteTerms, which records the +// current number of documents buffered in ram so that the +// delete term will be applied to those documents as well +// as the disk segments. +void DocumentsWriter::addDeleteTerm(Term *term, int32_t docCount) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + Num *num = bufferedDeleteTerms->get(term); + if (num == NULL) { + bufferedDeleteTerms->put(_CL_POINTER(term), new Num(docCount)); + // This is coarse approximation of actual bytes used: + numBytesUsed += (_tcslen(term->field()) + term->textLength()) * BYTES_PER_CHAR + 4 + 5 * OBJECT_HEADER_BYTES + 5 * OBJECT_POINTER_BYTES; + if (ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && numBytesUsed > ramBufferSize) { + bufferIsFull = true; + } + } else { + num->setNum(docCount); + } + numBufferedDeleteTerms++; +} + +void DocumentsWriter::addDeleteDocID(int32_t docId) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + bufferedDeleteDocIDs.push_back(docId); + numBytesUsed += OBJECT_HEADER_BYTES + BYTES_PER_INT + OBJECT_POINTER_BYTES; +} + +void DocumentsWriter::finishDocument(ThreadState *state) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (abortCount > 0) { + // Forcefully idle this threadstate -- its state will + // be reset by abort() + state->isIdle = true; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + return; + } + + // Now write the indexed document to the real files. + if (nextWriteDocID == state->docID) { + // It's my turn, so write everything now: + nextWriteDocID++; + state->writeDocument(); + state->isIdle = true; + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + + // If any states were waiting on me, sweep through and + // flush those that are enabled by my write. + if (numWaiting > 0) { + bool any = true; + while (any) { + any = false; + for (int32_t i = 0; i < numWaiting;) { + ThreadState *s = waitingThreadStates[i]; + if (s->docID == nextWriteDocID) { + s->writeDocument(); + s->isIdle = true; + nextWriteDocID++; + any = true; + if (numWaiting > i + 1) + // Swap in the last waiting state to fill in + // the hole we just created. It's important + // to do this as-we-go and not at the end of + // the loop, because if we hit an aborting + // exception in one of the s.writeDocument + // calls (above), it leaves this array in an + // inconsistent state: + waitingThreadStates.values[i] = waitingThreadStates[numWaiting - 1]; + numWaiting--; + } else { + assert(!s->isIdle); + i++; + } + } + } + } + } else { + // Another thread got a docID before me, but, it + // hasn't finished its processing. So add myself to + // the line but don't hold up this thread. + waitingThreadStates.values[numWaiting++] = state; + } +} + +int64_t DocumentsWriter::getRAMUsed() { + return numBytesUsed; +} + +void DocumentsWriter::fillBytes(IndexOutput *out, uint8_t b, int32_t numBytes) { + for (int32_t i = 0; i < numBytes; i++) + out->writeByte(b); +} + +void DocumentsWriter::copyBytes(IndexInput *srcIn, IndexOutput *destIn, int64_t numBytes) { + // TODO: we could do this more efficiently (save a copy) + // because it's always from a ByteSliceReader -> + // IndexOutput + while (numBytes > 0) { + int32_t chunk; + if (numBytes > 4096) + chunk = 4096; + else + chunk = (int32_t) numBytes; + srcIn->readBytes(copyByteBuffer, chunk); + destIn->writeBytes(copyByteBuffer, chunk); + numBytes -= chunk; + } +} + + +int64_t DocumentsWriter::segmentSize(const std::string &segmentName) { + assert(infoStream != NULL); + + int64_t size = directory->fileLength((segmentName + ".tii").c_str()) + + directory->fileLength((segmentName + ".tis").c_str()) + + directory->fileLength((segmentName + ".frq").c_str()) + + directory->fileLength((segmentName + ".prx").c_str()); + + const std::string normFileName = segmentName + ".nrm"; + if (directory->fileExists(normFileName.c_str())) + size += directory->fileLength(normFileName.c_str()); + + return size; +} + +void DocumentsWriter::getPostings(ValueArray &postings) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + numBytesUsed += postings.length * POSTING_NUM_BYTE; + int32_t numToCopy; + if (this->postingsFreeCountDW < postings.length) + numToCopy = this->postingsFreeCountDW; + else + numToCopy = postings.length; + + const int32_t start = this->postingsFreeCountDW - numToCopy; + if (numToCopy > 0) { + memcpy(postings.values, this->postingsFreeListDW.values + start, sizeof(Posting *) * numToCopy); + } + this->postingsFreeCountDW -= numToCopy; + + // Directly allocate the remainder if any + if (numToCopy < postings.length) { + const int32_t extra = postings.length - numToCopy; + const int32_t newPostingsAllocCount = this->postingsAllocCountDW + extra; + if (newPostingsAllocCount > this->postingsFreeListDW.length) + this->postingsFreeListDW.resize((int32_t) (1.25 * newPostingsAllocCount)); + + balanceRAM(); + for (size_t i = numToCopy; i < postings.length; i++) { + postings.values[i] = _CLNEW Posting(); + numBytesAlloc += POSTING_NUM_BYTE; + this->postingsAllocCountDW++; + } + } +} + +void DocumentsWriter::recyclePostings(ValueArray &postings, int32_t numPostings) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + // Move all Postings from this ThreadState back to our + // free list. We pre-allocated this array while we were + // creating Postings to make sure it's large enough + assert(this->postingsFreeCountDW + numPostings <= this->postingsFreeListDW.length); + if (numPostings > 0) + memcpy(this->postingsFreeListDW.values + this->postingsFreeCountDW, postings.values, numPostings * sizeof(Posting *)); + this->postingsFreeCountDW += numPostings; +} + +uint8_t *DocumentsWriter::getByteBlock(bool trackAllocations) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + const int32_t size = freeByteBlocks.size(); + uint8_t *b; + if (0 == size) { + numBytesAlloc += BYTE_BLOCK_SIZE; + balanceRAM(); + b = _CL_NEWARRAY(uint8_t, BYTE_BLOCK_SIZE); + memset(b, 0, sizeof(uint8_t) * BYTE_BLOCK_SIZE); + } else { + b = *freeByteBlocks.begin(); + freeByteBlocks.remove(freeByteBlocks.begin(), true); + } + if (trackAllocations) + numBytesUsed += BYTE_BLOCK_SIZE; + return b; +} + +void DocumentsWriter::recycleBlocks(ArrayBase &blocks, int32_t start, int32_t end) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + for (int32_t i = start; i < end; i++) { + freeByteBlocks.push_back(blocks[i]); + blocks[i] = NULL; + } +} + +TCHAR *DocumentsWriter::getCharBlock() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + const int32_t size = freeCharBlocks.size(); + TCHAR *c; + if (0 == size) { + numBytesAlloc += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + balanceRAM(); + c = _CL_NEWARRAY(TCHAR, CHAR_BLOCK_SIZE); + memset(c, 0, sizeof(TCHAR) * CHAR_BLOCK_SIZE); + } else { + c = *freeCharBlocks.begin(); + freeCharBlocks.remove(freeCharBlocks.begin(), true); + } + numBytesUsed += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + return c; +} + +void DocumentsWriter::recycleBlocks(ArrayBase &blocks, int32_t start, int32_t numBlocks) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + for (int32_t i = start; i < numBlocks; i++) { + freeCharBlocks.push_back(blocks[i]); + blocks.values[i] = NULL; + } +} + +std::string DocumentsWriter::toMB(int64_t v) { + char buf[40]; + cl_sprintf(buf, 40, "%0.2f", v / 1024.0 / 1024.0); + return string(buf); +} + +void DocumentsWriter::balanceRAM() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (ramBufferSize == IndexWriter::DISABLE_AUTO_FLUSH || bufferIsFull) + return; + + // We free our allocations if we've allocated 5% over + // our allowed RAM buffer + const int64_t freeTrigger = (int64_t) (1.05 * ramBufferSize); + const int64_t freeLevel = (int64_t) (0.95 * ramBufferSize); + + // We flush when we've used our target usage + const int64_t flushTrigger = (int64_t) ramBufferSize; + + if (numBytesAlloc > freeTrigger) { + if (infoStream != NULL) + (*infoStream) << string(" RAM: now balance allocations: usedMB=") << toMB(numBytesUsed) + string(" vs trigger=") << toMB(flushTrigger) << string(" allocMB=") << toMB(numBytesAlloc) << string(" vs trigger=") << toMB(freeTrigger) << string(" postingsFree=") << toMB(this->postingsFreeCountDW * POSTING_NUM_BYTE) << string(" byteBlockFree=") << toMB(freeByteBlocks.size() * BYTE_BLOCK_SIZE) << string(" charBlockFree=") << toMB(freeCharBlocks.size() * CHAR_BLOCK_SIZE * CHAR_NUM_BYTE) << string("\n"); + + // When we've crossed 100% of our target Postings + // RAM usage, try to free up until we're back down + // to 95% + const int64_t startBytesAlloc = numBytesAlloc; + + const int32_t postingsFreeChunk = (int32_t) (BYTE_BLOCK_SIZE / POSTING_NUM_BYTE); + + int32_t iter = 0; + + // We free equally from each pool in 64 KB + // chunks until we are below our threshold + // (freeLevel) + + while (numBytesAlloc > freeLevel) { + if (0 == freeByteBlocks.size() && 0 == freeCharBlocks.size() && 0 == this->postingsFreeCountDW) { + // Nothing else to free -- must flush now. + bufferIsFull = true; + if (infoStream != NULL) + (*infoStream) << string(" nothing to free; now set bufferIsFull\n"); + break; + } + + if ((0 == iter % 3) && freeByteBlocks.size() > 0) { + freeByteBlocks.remove(freeByteBlocks.size() - 1); + numBytesAlloc -= BYTE_BLOCK_SIZE; + } + + if ((1 == iter % 3) && freeCharBlocks.size() > 0) { + freeCharBlocks.remove(freeCharBlocks.size() - 1); + numBytesAlloc -= CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + } + + if ((2 == iter % 3) && this->postingsFreeCountDW > 0) { + int32_t numToFree; + if (this->postingsFreeCountDW >= postingsFreeChunk) + numToFree = postingsFreeChunk; + else + numToFree = this->postingsFreeCountDW; + for (size_t i = this->postingsFreeCountDW - numToFree; i < this->postingsFreeCountDW; i++) { + _CLDELETE(this->postingsFreeListDW.values[i]); + } + this->postingsFreeCountDW -= numToFree; + this->postingsAllocCountDW -= numToFree; + numBytesAlloc -= numToFree * POSTING_NUM_BYTE; + } + + iter++; + } + + if (infoStream != NULL) { + (*infoStream) << " after free: freedMB=" + Misc::toString((float_t) ((startBytesAlloc - numBytesAlloc) / 1024.0 / 1024.0)) + + " usedMB=" + Misc::toString((float_t) (numBytesUsed / 1024.0 / 1024.0)) + + " allocMB=" + Misc::toString((float_t) (numBytesAlloc / 1024.0 / 1024.0)) + << string("\n"); + } + + } else { + // If we have not crossed the 100% mark, but have + // crossed the 95% mark of RAM we are actually + // using, go ahead and flush. This prevents + // over-allocating and then freeing, with every + // flush. + if (numBytesUsed > flushTrigger) { + if (infoStream != NULL) { + (*infoStream) << string(" RAM: now flush @ usedMB=") << Misc::toString((float_t) (numBytesUsed / 1024.0 / 1024.0)) << string(" allocMB=") << Misc::toString((float_t) (numBytesAlloc / 1024.0 / 1024.0)) << string(" triggerMB=") << Misc::toString((float_t) (flushTrigger / 1024.0 / 1024.0)) << string("\n"); + } + + bufferIsFull = true; + } + } +} + + +DocumentsWriter::BufferedNorms::BufferedNorms() { + this->upto = 0; +} +void DocumentsWriter::BufferedNorms::add(float_t norm) { + uint8_t b = Similarity::encodeNorm(norm); + out.writeByte(b); + upto++; +} +void DocumentsWriter::BufferedNorms::reset() { + out.reset(); + upto = 0; +} +void DocumentsWriter::BufferedNorms::fill(int32_t docID) { + // Must now fill in docs that didn't have this + // field. Note that this is how norms can consume + // tremendous storage when the docs have widely + // varying different fields, because we are not + // storing the norms sparsely (see LUCENE-830) + if (upto < docID) { + fillBytes(&out, defaultNorm, docID - upto); + upto = docID; + } +} + + +DocumentsWriter::FieldMergeState::FieldMergeState() { + field = NULL; + postings = NULL; + p = NULL; + text = NULL; + textOffset = 0; + postingUpto = -1; + docID = 0; + termFreq = 0; +} +DocumentsWriter::FieldMergeState::~FieldMergeState() { +} +bool DocumentsWriter::FieldMergeState::nextTerm() { + postingUpto++; + if (postingUpto == field->numPostings) + return false; + + p = (*postings)[postingUpto]; + docID = 0; + + text = field->threadState->charPool->buffers[p->textStart >> CHAR_BLOCK_SHIFT]; + textOffset = p->textStart & CHAR_BLOCK_MASK; + + if (p->freqUpto > p->freqStart) + freq.init(field->threadState->postingsPool, p->freqStart, p->freqUpto); + else + freq.bufferOffset = freq.upto = freq.endIndex = 0; + + prox.init(field->threadState->postingsPool, p->proxStart, p->proxUpto); + + // Should always be true + bool result = nextDoc(); + assert(result); + + return true; +} + +bool DocumentsWriter::FieldMergeState::nextDoc() { + if (freq.bufferOffset + freq.upto == freq.endIndex) { + if (p->lastDocCode != -1) { + // Return last doc + docID = p->lastDocID; + termFreq = p->docFreq; + p->lastDocCode = -1; + return true; + } else + // EOF + return false; + } + + const uint32_t code = (uint32_t) freq.readVInt(); + docID += code >> 1;//unsigned shift + if ((code & 1) != 0) + termFreq = 1; + else + termFreq = freq.readVInt(); + + return true; +} + + +DocumentsWriter::ByteSliceReader::ByteSliceReader() { + pool = NULL; + bufferUpto = 0; + buffer = 0; + limit = 0; + level = 0; + upto = 0; + bufferOffset = 0; + endIndex = 0; +} +DocumentsWriter::ByteSliceReader::~ByteSliceReader() { +} +const char *DocumentsWriter::ByteSliceReader::getDirectoryType() const { + return ""; +} +const char *DocumentsWriter::ByteSliceReader::getObjectName() const { + return getClassName(); +} +const char *DocumentsWriter::ByteSliceReader::getClassName() { + return "DocumentsWriter::ByteSliceReader"; +} +IndexInput *DocumentsWriter::ByteSliceReader::clone() const { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Not implemented"); +} +void DocumentsWriter::ByteSliceReader::init(ByteBlockPool *_pool, int32_t _startIndex, int32_t _endIndex) { + + assert(_endIndex - _startIndex > 0); + + level = 0; + this->pool = _pool; + this->endIndex = _endIndex; + + bufferUpto = _startIndex / BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * BYTE_BLOCK_SIZE; + buffer = pool->buffers[bufferUpto]; + upto = _startIndex & BYTE_BLOCK_MASK; + + const int32_t firstSize = levelSizeArray[0]; + + if (_startIndex + firstSize >= endIndex) { + // There is only this one slice to read + limit = endIndex & BYTE_BLOCK_MASK; + } else + limit = upto + firstSize - 4; +} + +uint8_t DocumentsWriter::ByteSliceReader::readByte() { + // Assert that we are not @ EOF + assert(upto + bufferOffset < endIndex); + if (upto == limit) + nextSlice(); + return buffer[upto++]; +} + +int64_t DocumentsWriter::ByteSliceReader::writeTo(IndexOutput *out) { + int64_t size = 0; + while (true) { + if (limit + bufferOffset == endIndex) { + assert(endIndex - bufferOffset >= upto); + out->writeBytes(buffer + upto, limit - upto); + size += limit - upto; + break; + } else { + out->writeBytes(buffer + upto, limit - upto); + size += limit - upto; + nextSlice(); + } + } + + return size; +} + +void DocumentsWriter::ByteSliceReader::nextSlice() { + + // Skip to our next slice + const int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + ((buffer[2 + limit] & 0xff) << 8) + (buffer[3 + limit] & 0xff); + level = nextLevelArray[level]; + const int32_t newSize = levelSizeArray[level]; + + bufferUpto = nextIndex / BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * BYTE_BLOCK_SIZE; + + buffer = pool->buffers[bufferUpto]; + upto = nextIndex & BYTE_BLOCK_MASK; + + if (nextIndex + newSize >= endIndex) { + // We are advancing to the const slice + assert(endIndex - nextIndex > 0); + limit = endIndex - bufferOffset; + } else { + // This is not the const slice (subtract 4 for the + // forwarding address at the end of this new slice) + limit = upto + newSize - 4; + } +} + +void DocumentsWriter::ByteSliceReader::readBytes(uint8_t *b, int32_t len) { + readBytes(b, len, 0); +} + +void DocumentsWriter::ByteSliceReader::readBytes(uint8_t *b, int32_t len, int32_t offset) { + while (len > 0) { + const int32_t numLeft = limit - upto; + if (numLeft < len) { + // Read entire slice + memcpy(b + offset, buffer + upto, numLeft * sizeof(uint8_t)); + b += numLeft; + len -= numLeft; + nextSlice(); + } else { + // This slice is the last one + memcpy(b + offset, buffer + upto, len * sizeof(uint8_t)); + upto += len; + break; + } + } +} + +int64_t DocumentsWriter::ByteSliceReader::getFilePointer() const { _CLTHROWA(CL_ERR_Runtime, "not implemented"); } +int64_t DocumentsWriter::ByteSliceReader::length() const { _CLTHROWA(CL_ERR_Runtime, "not implemented"); } +void DocumentsWriter::ByteSliceReader::seek(const int64_t /*pos*/) { _CLTHROWA(CL_ERR_Runtime, "not implemented"); } +void DocumentsWriter::ByteSliceReader::close() { _CLTHROWA(CL_ERR_Runtime, "not implemented"); } + +DocumentsWriter::ByteBlockPool::ByteBlockPool(bool _trackAllocations, DocumentsWriter *_parent) : BlockPool(_parent, BYTE_BLOCK_SIZE, _trackAllocations) { +} +DocumentsWriter::ByteBlockPool::~ByteBlockPool() { + reset(); + //delete the first block + _CLDELETE_ARRAY(buffer); +} +uint8_t *DocumentsWriter::ByteBlockPool::getNewBlock(bool _trackAllocations) { + return parent->getByteBlock(_trackAllocations); +} +int32_t DocumentsWriter::ByteBlockPool::newSlice(const int32_t size) { + if (tUpto > BYTE_BLOCK_SIZE - size) + nextBuffer(); + const int32_t upto = tUpto; + tUpto += size; + buffer[tUpto - 1] = 16; + return upto; +} + +int32_t DocumentsWriter::ByteBlockPool::allocSlice(uint8_t *slice, const int32_t upto) { + const int32_t level = slice[upto] & 15; + assert(level < 10); + const int32_t newLevel = nextLevelArray[level]; + const int32_t newSize = levelSizeArray[newLevel]; + + // Maybe allocate another block + if (tUpto > BYTE_BLOCK_SIZE - newSize) + nextBuffer(); + + const int32_t newUpto = tUpto; + const uint32_t offset = newUpto + tOffset; + tUpto += newSize; + + // Copy forward the past 3 bytes (which we are about + // to overwrite with the forwarding address): + buffer[newUpto] = slice[upto - 3]; + buffer[newUpto + 1] = slice[upto - 2]; + buffer[newUpto + 2] = slice[upto - 1]; + + // Write forwarding address at end of last slice: + slice[upto - 3] = (uint8_t) (offset >> 24);//offset is unsigned... + slice[upto - 2] = (uint8_t) (offset >> 16); + slice[upto - 1] = (uint8_t) (offset >> 8); + slice[upto] = (uint8_t) offset; + + // Write new level: + buffer[tUpto - 1] = (uint8_t) (16 | newLevel); + + return newUpto + 3; +} +void DocumentsWriter::ByteBlockPool::reset() { + if (bufferUpto != -1) { + // We allocated at least one buffer + + for (int i = 0; i < bufferUpto; i++) + // Fully zero fill buffers that we fully used + memset(buffers.values[i], 0, BYTE_BLOCK_SIZE); + + // Partial zero fill the final buffer + memset(buffers.values[bufferUpto], 0, tUpto); + + if (bufferUpto > 0) + // Recycle all but the first buffer + parent->recycleBlocks(buffers, 1, 1 + bufferUpto); + + // Re-use the first buffer + bufferUpto = 0; + tUpto = 0; + tOffset = 0; + buffer = buffers[0]; + } +} +DocumentsWriter::CharBlockPool::CharBlockPool(DocumentsWriter *_parent) : BlockPool(_parent, CHAR_BLOCK_SIZE, false) { +} +DocumentsWriter::CharBlockPool::~CharBlockPool() { +} +TCHAR *DocumentsWriter::CharBlockPool::getNewBlock(bool) { + return parent->getCharBlock(); +} +void DocumentsWriter::CharBlockPool::reset() { + parent->recycleBlocks(buffers, 0, 1 + bufferUpto); + bufferUpto = -1; + tUpto = blockSize; + tOffset = -blockSize; +} + +CL_NS_END diff --git a/src/core/CLucene/index/DocumentsWriterThreadState.cpp b/src/core/CLucene/index/DocumentsWriterThreadState.cpp new file mode 100644 index 00000000000..cd8a7f67fe4 --- /dev/null +++ b/src/core/CLucene/index/DocumentsWriterThreadState.cpp @@ -0,0 +1,1326 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/_Arrays.h" +#include "IndexWriter.h" +#include "Term.h" +#include "_TermInfo.h" + +#include "_CompoundFile.h" +#include "_FieldInfos.h" +#include "_FieldsWriter.h" +#include "_IndexFileNames.h" +#include "_Term.h" +#include "_TermInfosWriter.h" +#include "_TermVector.h" +//#include "CLucene/analysis/mmseg/MMsegAnalyzer.h" +#include "CLucene/search/Similarity.h" +#include "_DocumentsWriter.h" +#include "_FieldsWriter.h" +#include "_TermInfosWriter.h" +#include +#include + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(analysis) +CL_NS_USE(document) +CL_NS_USE(search) +CL_NS_DEF(index) + + +DocumentsWriter::ThreadState::ThreadState(DocumentsWriter *__parent) : postingsFreeListTS(ValueArray(256)), + vectorFieldPointers(ValueArray(10)), + vectorFieldNumbers(ValueArray(10)), + fieldDataArray(ValueArray(8)), + fieldDataHash(ValueArray(16)), + postingsVectors(ObjectArray(1)), + postingsPool(_CLNEW ByteBlockPool(true, __parent)), + vectorsPool(_CLNEW ByteBlockPool(false, __parent)), + charPool(_CLNEW CharBlockPool(__parent)), + allFieldDataArray(ValueArray(10)), + _parent(__parent) { + fieldDataHashMask = 15; + postingsFreeCountTS = 0; + stringReader = _CLNEW ReusableStringReader(_T(""), 0, false); + + isIdle = true; + numThreads = 1; + + tvfLocal = _CLNEW RAMOutputStream();// Term vectors for one doc + fdtLocal = _CLNEW RAMOutputStream();// Stored fields for one doc + + this->docBoost = 0.0; + this->fieldGen = this->posUpto = this->maxPostingsVectors = this->numStoredFields = 0; + this->numAllFieldData = this->docID = 0; + this->numFieldData = numVectorFields = this->proxUpto = this->freqUpto = this->offsetUpto = 0; + this->localFieldsWriter = NULL; + this->maxTermPrefix = NULL; + this->p = NULL; + this->prox = NULL; + this->vector = NULL; + this->offsets = NULL; + this->pos = NULL; + this->freq = NULL; + this->doFlushAfter = false; + + analyzer_chs = _CLNEW lucene::analysis::SimpleAnalyzer(); +} + +DocumentsWriter::ThreadState::~ThreadState() { + _CLDELETE(postingsPool); + _CLDELETE(vectorsPool); + _CLDELETE(charPool); + _CLDELETE(stringReader); + _CLDELETE(tvfLocal); + _CLDELETE(fdtLocal); + + for (size_t i = 0; i < allFieldDataArray.length; i++) + _CLDELETE(allFieldDataArray.values[i]); + + _CLDELETE(analyzer_chs); +} + +void DocumentsWriter::ThreadState::resetPostings() { + fieldGen = 0; + maxPostingsVectors = 0; + doFlushAfter = false; + if (localFieldsWriter != NULL) { + localFieldsWriter->close(); + _CLDELETE(localFieldsWriter); + } + postingsPool->reset(); + charPool->reset(); + _parent->recyclePostings(this->postingsFreeListTS, this->postingsFreeCountTS); + this->postingsFreeCountTS = 0; + for (int32_t i = 0; i < numAllFieldData; i++) { + FieldData *fp = allFieldDataArray[i]; + fp->lastGen = -1; + if (fp->numPostings > 0) + fp->resetPostingArrays(); + } +} + +void DocumentsWriter::ThreadState::writeDocument() { + + // If we hit an exception while appending to the + // stored fields or term vectors files, we have to + // abort all documents since we last flushed because + // it means those files are possibly inconsistent. + try { + _parent->numDocsInStore++; + + // Append stored fields to the real FieldsWriter: + if (0) { + _parent->fieldsWriter->flushDocument(numStoredFields, fdtLocal); + } + fdtLocal->reset(); + + // Append term vectors to the real outputs: + if (_parent->tvx != NULL) { + _parent->tvx->writeLong(_parent->tvd->getFilePointer()); + _parent->tvd->writeVInt(numVectorFields); + if (numVectorFields > 0) { + for (int32_t i = 0; i < numVectorFields; i++) + _parent->tvd->writeVInt(vectorFieldNumbers[i]); + assert(0 == vectorFieldPointers[0]); + _parent->tvd->writeVLong(_parent->tvf->getFilePointer()); + int64_t lastPos = vectorFieldPointers[0]; + for (int32_t i = 1; i < numVectorFields; i++) { + int64_t pos = vectorFieldPointers[i]; + _parent->tvd->writeVLong(pos - lastPos); + lastPos = pos; + } + tvfLocal->writeTo(_parent->tvf); + tvfLocal->reset(); + } + } + + // Append norms for the fields we saw: + for (int32_t i = 0; i < numFieldData; i++) { + FieldData *fp = fieldDataArray[i]; + if (fp->doNorms) { + BufferedNorms *bn = _parent->norms[fp->fieldInfo->number]; + assert(bn != NULL); + assert(bn->upto <= docID); + bn->fill(docID); + float_t norm = fp->boost * _parent->writer->getSimilarity()->lengthNorm(fp->fieldInfo->name, fp->length); + bn->add(norm); + } + } + } catch (CLuceneError &t) { + // Forcefully idle this threadstate -- its state will + // be reset by abort() + isIdle = true; + throw AbortException(t, _parent); + } + + if (_parent->bufferIsFull && !_parent->flushPending) { + _parent->flushPending = true; + doFlushAfter = true; + } +} + +void DocumentsWriter::ThreadState::init(Document *doc, int32_t docID) { + + assert(!isIdle); + assert(_parent->writer->testPoint("DocumentsWriter.ThreadState.init start")); + + this->docID = docID; + docBoost = doc->getBoost(); + numStoredFields = 0; + numFieldData = 0; + numVectorFields = 0; + maxTermPrefix = NULL; + + assert(0 == fdtLocal->length()); + assert(0 == fdtLocal->getFilePointer()); + assert(0 == tvfLocal->length()); + assert(0 == tvfLocal->getFilePointer()); + const int32_t thisFieldGen = fieldGen++; + + const Document::FieldsType &docFields = *doc->getFields(); + const int32_t numDocFields = docFields.size(); + bool docHasVectors = false; + + // Absorb any new fields first seen in this document. + // Also absorb any changes to fields we had already + // seen before (eg suddenly turning on norms or + // vectors, etc.): + + for (int32_t i = 0; i < numDocFields; i++) { + Field *field = docFields[i]; + + FieldInfo *fi = _parent->fieldInfos->add(field->name(), field->isIndexed(), field->isTermVectorStored(), + field->isStorePositionWithTermVector(), field->isStoreOffsetWithTermVector(), + field->getOmitNorms(), false); + if (fi->isIndexed && !fi->omitNorms) { + // Maybe grow our buffered norms + if (_parent->norms.length <= fi->number) { + int32_t newSize = (int32_t) ((1 + fi->number) * 1.25); + _parent->norms.resize(newSize); + } + + if (_parent->norms[fi->number] == NULL) + _parent->norms.values[fi->number] = _CLNEW BufferedNorms(); + + _parent->hasNorms = true; + } + + // Make sure we have a FieldData allocated + int32_t hashPos = Misc::thashCode(fi->name) & fieldDataHashMask;//TODO: put hash in fieldinfo + FieldData *fp = fieldDataHash[hashPos]; + while (fp != NULL && _tcscmp(fp->fieldInfo->name, fi->name) != 0) + fp = fp->next; + + if (fp == NULL) { + fp = _CLNEW FieldData(_parent, this, fi); + fp->next = fieldDataHash[hashPos]; + fieldDataHash.values[hashPos] = fp; + + if (numAllFieldData == allFieldDataArray.length) { + allFieldDataArray.resize((int32_t) (allFieldDataArray.length * 1.5)); + + ValueArray newHashArray(fieldDataHash.length * 2); + + // Rehash + fieldDataHashMask = allFieldDataArray.length - 1; + for (size_t j = 0; j < fieldDataHash.length; j++) { + FieldData *fp0 = fieldDataHash[j]; + while (fp0 != NULL) { + //todo: put hash code into fieldinfo to reduce number of hashes necessary + hashPos = Misc::thashCode(fp0->fieldInfo->name) & fieldDataHashMask; + FieldData *nextFP0 = fp0->next; + fp0->next = newHashArray[hashPos]; + newHashArray.values[hashPos] = fp0; + fp0 = nextFP0; + } + } + fieldDataHash.resize(newHashArray.length); + memcpy(fieldDataHash.values, newHashArray.values, newHashArray.length * sizeof(FieldData *)); + } + allFieldDataArray.values[numAllFieldData++] = fp; + } else { + assert(fp->fieldInfo == fi); + } + + if (thisFieldGen != fp->lastGen) { + + // First time we're seeing this field for this doc + fp->lastGen = thisFieldGen; + fp->fieldCount = 0; + fp->doVectors = fp->doVectorPositions = fp->doVectorOffsets = false; + fp->doNorms = fi->isIndexed && !fi->omitNorms; + + if (numFieldData == fieldDataArray.length) { + fieldDataArray.resize(fieldDataArray.length * 2); + } + fieldDataArray.values[numFieldData++] = fp; + } + + if (field->isTermVectorStored()) { + if (!fp->doVectors && numVectorFields++ == vectorFieldPointers.length) { + const int32_t newSize = (int32_t) (numVectorFields * 1.5); + vectorFieldPointers.resize(newSize); + vectorFieldNumbers.resize(newSize); + } + fp->doVectors = true; + docHasVectors = true; + + fp->doVectorPositions |= field->isStorePositionWithTermVector(); + fp->doVectorOffsets |= field->isStoreOffsetWithTermVector(); + } + + if (fp->fieldCount == fp->docFields.length) { + fp->docFields.resize(fp->docFields.length * 2); + } + + // Lazily allocate arrays for postings: + if (field->isIndexed() && fp->postingsHash.values == NULL) + fp->initPostingArrays(); + + fp->docFields.values[fp->fieldCount++] = field; + } + + // Maybe init the local & global fieldsWriter + if (0) { + if (localFieldsWriter == NULL) { + if (_parent->fieldsWriter == NULL) { + assert(_parent->docStoreSegment.empty()); + assert(!_parent->segment.empty()); + _parent->docStoreSegment = _parent->segment; + // If we hit an exception while init'ing the + // fieldsWriter, we must abort this segment + // because those files will be in an unknown + // state: + try { + _parent->fieldsWriter = _CLNEW FieldsWriter(_parent->directory, _parent->docStoreSegment.c_str(), _parent->fieldInfos); + } catch (CLuceneError &t) { + throw AbortException(t, _parent); + } + _CLDELETE(_parent->_files); + } + localFieldsWriter = _CLNEW FieldsWriter(NULL, fdtLocal, _parent->fieldInfos); + } + } + + // First time we see a doc that has field(s) with + // stored vectors, we init our tvx writer + if (docHasVectors) { + if (_parent->tvx == NULL) { + assert(!_parent->docStoreSegment.empty()); + // If we hit an exception while init'ing the term + // vector output files, we must abort this segment + // because those files will be in an unknown + // state: + try { + _parent->tvx = _parent->directory->createOutput((_parent->docStoreSegment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION).c_str()); + _parent->tvx->writeInt(TermVectorsReader::FORMAT_VERSION); + _parent->tvd = _parent->directory->createOutput((_parent->docStoreSegment + "." + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION).c_str()); + _parent->tvd->writeInt(TermVectorsReader::FORMAT_VERSION); + _parent->tvf = _parent->directory->createOutput((_parent->docStoreSegment + "." + IndexFileNames::VECTORS_FIELDS_EXTENSION).c_str()); + _parent->tvf->writeInt(TermVectorsReader::FORMAT_VERSION); + + // We must "catch up" for all docs before us + // that had no vectors: + for (int32_t i = 0; i < _parent->numDocsInStore; i++) { + _parent->tvx->writeLong(_parent->tvd->getFilePointer()); + _parent->tvd->writeVInt(0); + } + + } catch (CLuceneError &t) { + throw AbortException(t, _parent); + } + _CLDELETE(_parent->_files); + } + + numVectorFields = 0; + } +} + +void DocumentsWriter::ThreadState::doPostingSort(Posting **postings, int32_t numPosting) { + quickSort(postings, 0, numPosting - 1); +} + +void DocumentsWriter::ThreadState::quickSort(Posting **postings, int32_t lo, int32_t hi) { + if (lo >= hi) + return; + + int32_t mid = ((uint32_t) (lo + hi)) >> 1;//unsigned shift... + + if (comparePostings(postings[lo], postings[mid]) > 0) { + Posting *tmp = postings[lo]; + postings[lo] = postings[mid]; + postings[mid] = tmp; + } + + if (comparePostings(postings[mid], postings[hi]) > 0) { + Posting *tmp = postings[mid]; + postings[mid] = postings[hi]; + postings[hi] = tmp; + + if (comparePostings(postings[lo], postings[mid]) > 0) { + Posting *tmp2 = postings[lo]; + postings[lo] = postings[mid]; + postings[mid] = tmp2; + } + } + + int32_t left = lo + 1; + int32_t right = hi - 1; + + if (left >= right) + return; + + Posting *partition = postings[mid]; + + for (;;) { + while (comparePostings(postings[right], partition) > 0) + --right; + + while (left < right && comparePostings(postings[left], partition) <= 0) + ++left; + + if (left < right) { + Posting *tmp = postings[left]; + postings[left] = postings[right]; + postings[right] = tmp; + --right; + } else { + break; + } + } + + quickSort(postings, lo, left); + quickSort(postings, left + 1, hi); +} + +void DocumentsWriter::ThreadState::doVectorSort(ArrayBase &postings, int32_t numPosting) { + quickSort(postings, 0, numPosting - 1); +} + +void DocumentsWriter::ThreadState::quickSort(ArrayBase &postings, int32_t lo, int32_t hi) { + if (lo >= hi) + return; + + int32_t mid = ((uint8_t) (lo + hi)) >> 1;//unsigned shift.. + + if (comparePostings(postings[lo]->p, postings[mid]->p) > 0) { + PostingVector *tmp = postings[lo]; + postings.values[lo] = postings[mid]; + postings.values[mid] = tmp; + } + + if (comparePostings(postings[mid]->p, postings[hi]->p) > 0) { + PostingVector *tmp = postings[mid]; + postings.values[mid] = postings[hi]; + postings.values[hi] = tmp; + + if (comparePostings(postings[lo]->p, postings[mid]->p) > 0) { + PostingVector *tmp2 = postings[lo]; + postings.values[lo] = postings[mid]; + postings.values[mid] = tmp2; + } + } + + int32_t left = lo + 1; + int32_t right = hi - 1; + + if (left >= right) + return; + + PostingVector *partition = postings[mid]; + + for (;;) { + while (comparePostings(postings[right]->p, partition->p) > 0) + --right; + + while (left < right && comparePostings(postings[left]->p, partition->p) <= 0) + ++left; + + if (left < right) { + PostingVector *tmp = postings[left]; + postings.values[left] = postings[right]; + postings.values[right] = tmp; + --right; + } else { + break; + } + } + + quickSort(postings, lo, left); + quickSort(postings, left + 1, hi); +} + +void DocumentsWriter::ThreadState::trimFields() { + + int32_t upto = 0; + for (int32_t i = 0; i < numAllFieldData; i++) { + FieldData *fp = allFieldDataArray[i]; + if (fp->lastGen == -1) { + // This field was not seen since the previous + // flush, so, free up its resources now + + // Unhash + const int32_t hashPos = Misc::thashCode(fp->fieldInfo->name) & fieldDataHashMask; + FieldData *last = NULL; + FieldData *fp0 = fieldDataHash[hashPos]; + while (fp0 != fp) { + last = fp0; + fp0 = fp0->next; + } + assert(fp0 != NULL); + + if (last == NULL) + fieldDataHash.values[hashPos] = fp->next; + else + last->next = fp->next; + + if (_parent->infoStream != NULL) + (*_parent->infoStream) << " remove field=" << fp->fieldInfo->name << "\n"; + + _CLDELETE(fp); + } else { + // Reset + fp->lastGen = -1; + allFieldDataArray.values[upto++] = fp; + + if (fp->numPostings > 0 && ((float_t) fp->numPostings) / fp->postingsHashSize < 0.2) { + int32_t hashSize = fp->postingsHashSize; + + // Reduce hash so it's between 25-50% full + while (fp->numPostings < (hashSize >> 1) && hashSize >= 2) + hashSize >>= 1; + hashSize <<= 1; + + if (hashSize != fp->postingsHash.length) + fp->rehashPostings(hashSize); + } + } + } + //delete everything after up to in allFieldDataArray + for (size_t i = upto; i < allFieldDataArray.length; i++) { + allFieldDataArray[i] = NULL; + } + + // If we didn't see any norms for this field since + // last flush, free it + for (size_t i = 0; i < _parent->norms.length; i++) { + BufferedNorms *n = _parent->norms[i]; + if (n != NULL && n->upto == 0) { + _CLLDELETE(n); + _parent->norms.values[i] = NULL; + } + } + + numAllFieldData = upto; + + // Also pare back PostingsVectors if it's excessively + // large + if (maxPostingsVectors * 1.5 < postingsVectors.length) { + int32_t newSize; + if (0 == maxPostingsVectors) + newSize = 1; + else + newSize = (int32_t) (1.5 * maxPostingsVectors); + postingsVectors.resize(newSize, true); + } +} + +void DocumentsWriter::ThreadState::processDocument(Analyzer *analyzer) { + + const int32_t numFields = numFieldData; + + assert(0 == fdtLocal->length()); + + if (_parent->tvx != NULL) { + // If we are writing vectors then we must visit + // fields in sorted order so they are written in + // sorted order. TODO: we actually only need to + // sort the subset of fields that have vectors + // enabled; we could save [small amount of] CPU + // here. + Arrays::sort(fieldDataArray.values, fieldDataArray.length, 0, numFields); + } + + // We process the document one field at a time + for (int32_t i = 0; i < numFields; i++) + fieldDataArray[i]->processField(analyzer); + + if (maxTermPrefix != NULL && _parent->infoStream != NULL) + (*_parent->infoStream) << "WARNING: document contains at least one immense term (longer than the max length " << MAX_TERM_LENGTH << "), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '" << maxTermPrefix << "...'\n"; + + if (_parent->ramBufferSize != IndexWriter::DISABLE_AUTO_FLUSH && _parent->numBytesUsed > 0.95 * _parent->ramBufferSize) + _parent->balanceRAM(); +} + +// USE ONLY FOR DEBUGGING! +/* + String getPostingText() { + TCHAR* text = charPool->buffers[p->textStart >> CHAR_BLOCK_SHIFT]; + int32_t upto = p->textStart & CHAR_BLOCK_MASK; + while((*text)[upto] != CLUCENE_END_OF_WORD) + upto++; + return new String(text, p->textStart, upto-(p->textStart & BYTE_BLOCK_MASK)); + } +*/ + +bool DocumentsWriter::ThreadState::postingEquals(const TCHAR *tokenText, const int32_t tokenTextLen) { + + const TCHAR *text = charPool->buffers[p->textStart >> CHAR_BLOCK_SHIFT]; + assert(text != NULL); + int32_t pos = p->textStart & CHAR_BLOCK_MASK; + + int32_t tokenPos = 0; + for (; tokenPos < tokenTextLen; pos++, tokenPos++) + if (tokenText[tokenPos] != text[pos]) + return false; + return CLUCENE_END_OF_WORD == text[pos]; +} + +int32_t DocumentsWriter::ThreadState::comparePostings(Posting *p1, Posting *p2) { + const TCHAR *pos1 = charPool->buffers[p1->textStart >> CHAR_BLOCK_SHIFT] + (p1->textStart & CHAR_BLOCK_MASK); + const TCHAR *pos2 = charPool->buffers[p2->textStart >> CHAR_BLOCK_SHIFT] + (p2->textStart & CHAR_BLOCK_MASK); + while (true) { + const TCHAR c1 = *pos1++; + const TCHAR c2 = *pos2++; + if (c1 < c2) + if (CLUCENE_END_OF_WORD == c2) + return 1; + else + return -1; + else if (c2 < c1) + if (CLUCENE_END_OF_WORD == c1) + return -1; + else + return 1; + else if (CLUCENE_END_OF_WORD == c1) + return 0; + } +} + +void DocumentsWriter::ThreadState::writeFreqVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeFreqByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writeFreqByte((uint8_t) i); +} + +void DocumentsWriter::ThreadState::writeProxVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeProxByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writeProxByte((uint8_t) i); +} + +void DocumentsWriter::ThreadState::writeFreqByte(uint8_t b) { + assert(freq != NULL); + if (freq[freqUpto] != 0) { + freqUpto = postingsPool->allocSlice(freq, freqUpto); + freq = postingsPool->buffer; + p->freqUpto = postingsPool->tOffset; + } + freq[freqUpto++] = b; +} + +void DocumentsWriter::ThreadState::writeProxByte(uint8_t b) { + assert(prox != NULL); + if (prox[proxUpto] != 0) { + proxUpto = postingsPool->allocSlice(prox, proxUpto); + prox = postingsPool->buffer; + p->proxUpto = postingsPool->tOffset; + assert(prox != NULL); + } + prox[proxUpto++] = b; + assert(proxUpto != DocumentsWriter::BYTE_BLOCK_SIZE); +} + +void DocumentsWriter::ThreadState::writeProxBytes(uint8_t *b, int32_t offset, int32_t len) { + const int32_t offsetEnd = offset + len; + while (offset < offsetEnd) { + if (prox[proxUpto] != 0) { + // End marker + proxUpto = postingsPool->allocSlice(prox, proxUpto); + prox = postingsPool->buffer; + p->proxUpto = postingsPool->tOffset; + } + + prox[proxUpto++] = b[offset++]; + assert(proxUpto != DocumentsWriter::BYTE_BLOCK_SIZE); + } +} + +void DocumentsWriter::ThreadState::writeOffsetVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeOffsetByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writeOffsetByte((uint8_t) i); +} + +void DocumentsWriter::ThreadState::writeOffsetByte(uint8_t b) { + assert(offsets != NULL); + if (offsets[offsetUpto] != 0) { + offsetUpto = vectorsPool->allocSlice(offsets, offsetUpto); + offsets = vectorsPool->buffer; + vector->offsetUpto = vectorsPool->tOffset; + } + offsets[offsetUpto++] = b; +} + +void DocumentsWriter::ThreadState::writePosVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writePosByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writePosByte((uint8_t) i); +} + +void DocumentsWriter::ThreadState::writePosByte(uint8_t b) { + assert(pos != NULL); + if (pos[posUpto] != 0) { + posUpto = vectorsPool->allocSlice(pos, posUpto); + pos = vectorsPool->buffer; + vector->posUpto = vectorsPool->tOffset; + } + pos[posUpto++] = b; +} + + +DocumentsWriter::ThreadState::FieldData::FieldData(DocumentsWriter *__parent, ThreadState *__threadState, FieldInfo *fieldInfo) : docFields(ValueArray(1)), + _parent(__parent), + localToken(_CLNEW Token), + vectorSliceReader(_CLNEW ByteSliceReader()) { + this->fieldCount = this->postingsHashSize = this->postingsHashHalfSize = this->postingsVectorsUpto = 0; + this->postingsHashMask = this->offsetEnd = 0; + this->offsetStartCode = this->offsetStart = this->numPostings = this->position = this->length = this->offset = 0; + this->boost = 0.0; + this->next = NULL; + this->lastGen = -1; + this->fieldInfo = fieldInfo; + this->threadState = __threadState; + this->postingsCompacted = false; +} +DocumentsWriter::ThreadState::FieldData::~FieldData() { + _CLDELETE(vectorSliceReader); + _CLDELETE(localToken); +} +bool DocumentsWriter::ThreadState::FieldData::sort(FieldData *e1, FieldData *e2) { + return _tcscmp(e1->fieldInfo->name, e2->fieldInfo->name) < 0; +} +void DocumentsWriter::ThreadState::FieldData::resetPostingArrays() { + if (!postingsCompacted) + compactPostings(); + _parent->recyclePostings(this->postingsHash, numPostings); + memset(postingsHash.values, 0, postingsHash.length * sizeof(Posting *)); + postingsCompacted = false; + numPostings = 0; +} + +const char *DocumentsWriter::ThreadState::FieldData::getObjectName() const { + return getClassName(); +} +const char *DocumentsWriter::ThreadState::FieldData::getClassName() { + return "DocumentsWriter::ThreadState"; +} +void DocumentsWriter::ThreadState::FieldData::initPostingArrays() { + // Target hash fill factor of <= 50% + // NOTE: must be a power of two for hash collision + // strategy to work correctly + postingsHashSize = 4; + postingsHashHalfSize = 2; + postingsHashMask = postingsHashSize - 1; + postingsHash.resize(postingsHashSize); +} + +int32_t DocumentsWriter::ThreadState::FieldData::compareTo(NamedObject *o) { + if (o->getObjectName() != FieldData::getClassName()) + return -1; + return _tcscmp(fieldInfo->name, ((FieldData *) o)->fieldInfo->name); +} + +void DocumentsWriter::ThreadState::FieldData::compactPostings() { + int32_t upto = 0; + for (int32_t i = 0; i < postingsHashSize; i++) + if (postingsHash[i] != NULL) + postingsHash.values[upto++] = postingsHash[i]; + + assert(upto == numPostings); + postingsCompacted = true; +} + +CL_NS(util)::ValueArray *DocumentsWriter::ThreadState::FieldData::sortPostings() { + compactPostings(); + threadState->doPostingSort(postingsHash.values, numPostings); + return &postingsHash; +} + + +void DocumentsWriter::ThreadState::FieldData::processField(Analyzer *analyzer) { + length = 0; + position = 0; + offset = 0; + boost = threadState->docBoost; + + const int32_t maxFieldLength = _parent->writer->getMaxFieldLength(); + + const int32_t limit = fieldCount; + const ArrayBase &docFieldsFinal = docFields; + + bool doWriteVectors = true; + + // Walk through all occurrences in this doc for this + // field: + try { + for (int32_t j = 0; j < limit; j++) { + Field *field = docFieldsFinal[j]; + + if (field->isIndexed()) { + //Oney: get the CHN if needed + if (field->isTokenizedCHS()) { + invertField(field, threadState->analyzer_chs, maxFieldLength); + } else { + invertField(field, analyzer, maxFieldLength); + } + } + + if (field->isStored()) { + threadState->numStoredFields++; + bool success = false; + try { + if (0) { + threadState->localFieldsWriter->writeField(fieldInfo, field); + } + success = true; + } + _CLFINALLY( + // If we hit an exception inside + // localFieldsWriter->writeField, the + // contents of fdtLocal can be corrupt, so + // we must discard all stored fields for + // this document: + if (!success) + threadState->fdtLocal->reset();) + } + + docFieldsFinal.values[j] = NULL; + } + } catch (AbortException &ae) { + doWriteVectors = false; + throw ae; + } + _CLFINALLY( + if (postingsVectorsUpto > 0) { + try { + if (doWriteVectors) { + // Add term vectors for this field + bool success = false; + try { + writeVectors(fieldInfo); + success = true; + } + _CLFINALLY( + if (!success) { + // If we hit an exception inside + // writeVectors, the contents of tvfLocal + // can be corrupt, so we must discard all + // term vectors for this document: + threadState->numVectorFields = 0; + threadState->tvfLocal->reset(); + }) + } + } + _CLFINALLY( + if (postingsVectorsUpto > threadState->maxPostingsVectors) + threadState->maxPostingsVectors = postingsVectorsUpto; + postingsVectorsUpto = 0; + threadState->vectorsPool->reset();) + }) +} +void DocumentsWriter::ThreadState::FieldData::invertField(Field *field, Analyzer *analyzer, const int32_t maxFieldLength) { + + if (length > 0) + position += analyzer->getPositionIncrementGap(fieldInfo->name); + + if (!field->isTokenized()) {// un-tokenized field + const TCHAR *stringValue = field->stringValue(); + const size_t valueLength = _tcslen(stringValue); + Token *token = localToken; + token->clear(); + + token->setText(stringValue, valueLength); + token->setStartOffset(offset); + token->setEndOffset(offset + valueLength); + addPosition(token); + offset += valueLength; + length++; + } else {// tokenized field + TokenStream *stream; + TokenStream *streamValue = field->tokenStreamValue(); + + if (streamValue != NULL) + stream = streamValue; + else { + // the field does not have a TokenStream, + // so we have to obtain one from the analyzer + Reader *reader;// find or make Reader + Reader *readerValue = field->readerValue(); + + if (readerValue != NULL) + reader = readerValue; + else { + const TCHAR *stringValue = field->stringValue(); + size_t stringValueLength = _tcslen(stringValue); + if (stringValue == NULL) + _CLTHROWA(CL_ERR_IllegalArgument, "field must have either TokenStream, String or Reader value"); + threadState->stringReader->init(stringValue, stringValueLength); + reader = threadState->stringReader; + } + + // Tokenize field and add to postingTable + stream = analyzer->reusableTokenStream(fieldInfo->name, reader); + } + + // reset the TokenStream to the first token + stream->reset(); + + try { + offsetEnd = offset - 1; + for (;;) { + Token *token = stream->next(localToken); + if (token == NULL) break; + position += (token->getPositionIncrement() - 1); + addPosition(token); + ++length; + + // Apply field truncation policy. + if (maxFieldLength != IndexWriter::FIELD_TRUNC_POLICY__WARN) { + // The client programmer has explicitly authorized us to + // truncate the token stream after maxFieldLength tokens. + if (length >= maxFieldLength) { + if (_parent->infoStream != NULL) + (*_parent->infoStream) << "maxFieldLength " << maxFieldLength << " reached for field " << fieldInfo->name << ", ignoring following tokens\n"; + break; + } + } else if (length > IndexWriter::DEFAULT_MAX_FIELD_LENGTH) { + const TCHAR *errMsgBase = + _T("Indexing a huge number of tokens from a single") + _T(" field (\"%s\", in this case) can cause CLucene") + _T(" to use memory excessively.") + _T(" By default, CLucene will accept only %s tokens") + _T(" tokens from a single field before forcing the") + _T(" client programmer to specify a threshold at") + _T(" which to truncate the token stream.") + _T(" You should set this threshold via") + _T(" IndexReader::maxFieldLength (set to LUCENE_INT32_MAX") + _T(" to disable truncation, or a value to specify maximum number of fields)."); + + TCHAR defaultMaxAsChar[34]; + _i64tot(IndexWriter::DEFAULT_MAX_FIELD_LENGTH, + defaultMaxAsChar, 10); + int32_t errMsgLen = _tcslen(errMsgBase) + _tcslen(fieldInfo->name) + _tcslen(defaultMaxAsChar); + TCHAR *errMsg = _CL_NEWARRAY(TCHAR, errMsgLen + 1); + + _sntprintf(errMsg, errMsgLen, errMsgBase, fieldInfo->name, defaultMaxAsChar); + + _CLTHROWT_DEL(CL_ERR_Runtime, errMsg); + } + } + offset = offsetEnd + 1; + } + _CLFINALLY( + stream->close();//don't delete, this stream is re-used + ) + } + + boost *= field->getBoost(); +} + +DocumentsWriter::PostingVector *DocumentsWriter::ThreadState::FieldData::addNewVector() { + + if (postingsVectorsUpto == threadState->postingsVectors.length) { + int32_t newSize; + if (threadState->postingsVectors.length < 2) + newSize = 2; + else + newSize = (int32_t) (1.5 * threadState->postingsVectors.length); + threadState->postingsVectors.resize(newSize, true); + } + + threadState->p->vector = threadState->postingsVectors[postingsVectorsUpto]; + if (threadState->p->vector == NULL) + threadState->p->vector = threadState->postingsVectors.values[postingsVectorsUpto] = _CLNEW PostingVector(); + + postingsVectorsUpto++; + + PostingVector *v = threadState->p->vector; + v->p = threadState->p; + + const int32_t firstSize = levelSizeArray[0]; + + if (doVectorPositions) { + const int32_t upto = threadState->vectorsPool->newSlice(firstSize); + v->posStart = v->posUpto = threadState->vectorsPool->tOffset + upto; + } + + if (doVectorOffsets) { + const int32_t upto = threadState->vectorsPool->newSlice(firstSize); + v->offsetStart = v->offsetUpto = threadState->vectorsPool->tOffset + upto; + } + + return v; +} + +void DocumentsWriter::ThreadState::FieldData::addPosition(Token *token) { + + const Payload *payload = token->getPayload(); + + // Get the text of this term. Term can either + // provide a String token or offset into a TCHAR* + // array + const TCHAR *tokenText = token->termBuffer(); + const int32_t tokenTextLen = token->termLength(); + + int32_t code = 0; + + // Compute hashcode + int32_t downto = tokenTextLen; + while (downto > 0) + code = (code * 31) + tokenText[--downto]; + /* + std::cout << " addPosition: buffer=" << Misc::toString(tokenText).substr(0,tokenTextLen) << " pos=" << position + << " offsetStart=" << (offset+token->startOffset()) << " offsetEnd=" << (offset + token->endOffset()) + << " docID=" << threadState->docID << " doPos=" << (doVectorPositions?"true":"false") << " doOffset=" << (doVectorOffsets?"true":"false") << "\n"; +*/ + int32_t hashPos = code & postingsHashMask; + + assert(!postingsCompacted); + + // Locate Posting in hash + threadState->p = postingsHash[hashPos]; + + if (threadState->p != NULL && !threadState->postingEquals(tokenText, tokenTextLen)) { + // Conflict: keep searching different locations in + // the hash table. + const int32_t inc = ((code >> 8) + code) | 1; + do { + code += inc; + hashPos = code & postingsHashMask; + threadState->p = postingsHash[hashPos]; + } while (threadState->p != NULL && !threadState->postingEquals(tokenText, tokenTextLen)); + } + + int32_t proxCode; + + // If we hit an exception below, it's possible the + // posting list or term vectors data will be + // partially written and thus inconsistent if + // flushed, so we have to abort all documents + // since the last flush: + + try { + + if (threadState->p != NULL) {// term seen since last flush + + if (threadState->docID != threadState->p->lastDocID) {// term not yet seen in this doc + /* + std::cout << " seen before (new docID=" << threadState->docID << ") freqUpto=" << threadState->p->freqUpto + << " proxUpto=" << threadState->p->proxUpto << "\n"; +*/ + assert(threadState->p->docFreq > 0); + + // Now that we know doc freq for previous doc, + // write it & lastDocCode + threadState->freqUpto = threadState->p->freqUpto & BYTE_BLOCK_MASK; + threadState->freq = threadState->postingsPool->buffers[threadState->p->freqUpto >> BYTE_BLOCK_SHIFT]; + if (1 == threadState->p->docFreq) + threadState->writeFreqVInt(threadState->p->lastDocCode | 1); + else { + threadState->writeFreqVInt(threadState->p->lastDocCode); + threadState->writeFreqVInt(threadState->p->docFreq); + } + threadState->p->freqUpto = threadState->freqUpto + (threadState->p->freqUpto & BYTE_BLOCK_NOT_MASK); + + if (doVectors) { + threadState->vector = addNewVector(); + if (doVectorOffsets) { + offsetStartCode = offsetStart = offset + token->startOffset(); + offsetEnd = offset + token->endOffset(); + } + } + + proxCode = position; + + threadState->p->docFreq = 1; + + // Store code so we can write this after we're + // done with this new doc + threadState->p->lastDocCode = (threadState->docID - threadState->p->lastDocID) << 1; + threadState->p->lastDocID = threadState->docID; + + } else {// term already seen in this doc + //std::cout << " seen before (same docID=" << threadState->docID << ") proxUpto=" << threadState->p->proxUpto << "\n"; + + threadState->p->docFreq++; + + proxCode = position - threadState->p->lastPosition; + + if (doVectors) { + threadState->vector = threadState->p->vector; + if (threadState->vector == NULL) + threadState->vector = addNewVector(); + if (doVectorOffsets) { + offsetStart = offset + token->startOffset(); + offsetEnd = offset + token->endOffset(); + offsetStartCode = offsetStart - threadState->vector->lastOffset; + } + } + } + } else {// term not seen before + //std::cout << " never seen docID=" << threadState->docID << "\n"; + + // Refill? + if (0 == threadState->postingsFreeCountTS) { + _parent->getPostings(threadState->postingsFreeListTS); + threadState->postingsFreeCountTS = threadState->postingsFreeListTS.length; + } + + const int32_t textLen1 = 1 + tokenTextLen; + if (textLen1 + threadState->charPool->tUpto > CHAR_BLOCK_SIZE) { + if (textLen1 > CHAR_BLOCK_SIZE) { + // Just skip this term, to remain as robust as + // possible during indexing. A TokenFilter + // can be inserted into the analyzer chain if + // other behavior is wanted (pruning the term + // to a prefix, throwing an exception, etc). + if (threadState->maxTermPrefix == NULL) { + threadState->maxTermPrefix = _CL_NEWARRAY(TCHAR, 31); + _tcsncpy(threadState->maxTermPrefix, tokenText, 30); + threadState->maxTermPrefix[30] = 0; + } + + // Still increment position: + position++; + return; + } + threadState->charPool->nextBuffer(); + } + TCHAR *text = threadState->charPool->buffer; + TCHAR *textUpto = text + threadState->charPool->tUpto; + + // Pull next free Posting from free list + threadState->p = threadState->postingsFreeListTS[--threadState->postingsFreeCountTS]; + assert(threadState->p != NULL); + threadState->p->textStart = textUpto + threadState->charPool->tOffset - text; + threadState->charPool->tUpto += textLen1; + + _tcsncpy(textUpto, tokenText, tokenTextLen); + textUpto[tokenTextLen] = CLUCENE_END_OF_WORD; + + assert(postingsHash[hashPos] == NULL); + + postingsHash.values[hashPos] = threadState->p; + numPostings++; + + if (numPostings == postingsHashHalfSize) + rehashPostings(2 * postingsHashSize); + + // Init first slice for freq & prox streams + const int32_t firstSize = levelSizeArray[0]; + + const int32_t upto1 = threadState->postingsPool->newSlice(firstSize); + threadState->p->freqStart = threadState->p->freqUpto = threadState->postingsPool->tOffset + upto1; + + const int32_t upto2 = threadState->postingsPool->newSlice(firstSize); + threadState->p->proxStart = threadState->p->proxUpto = threadState->postingsPool->tOffset + upto2; + + threadState->p->lastDocCode = threadState->docID << 1; + threadState->p->lastDocID = threadState->docID; + threadState->p->docFreq = 1; + + if (doVectors) { + threadState->vector = addNewVector(); + if (doVectorOffsets) { + offsetStart = offsetStartCode = offset + token->startOffset(); + offsetEnd = offset + token->endOffset(); + } + } + + proxCode = position; + } + + threadState->proxUpto = threadState->p->proxUpto & BYTE_BLOCK_MASK; + threadState->prox = threadState->postingsPool->buffers[threadState->p->proxUpto >> BYTE_BLOCK_SHIFT]; + assert(threadState->prox != NULL); + + if (payload != NULL && payload->length() > 0) { + threadState->writeProxVInt((proxCode << 1) | 1); + threadState->writeProxVInt(payload->length()); + threadState->writeProxBytes(payload->getData().values, payload->getOffset(), payload->length()); + fieldInfo->storePayloads = true; + } else + threadState->writeProxVInt(proxCode << 1); + + threadState->p->proxUpto = threadState->proxUpto + (threadState->p->proxUpto & BYTE_BLOCK_NOT_MASK); + + threadState->p->lastPosition = position++; + + if (doVectorPositions) { + threadState->posUpto = threadState->vector->posUpto & BYTE_BLOCK_MASK; + threadState->pos = threadState->vectorsPool->buffers[threadState->vector->posUpto >> BYTE_BLOCK_SHIFT]; + threadState->writePosVInt(proxCode); + threadState->vector->posUpto = threadState->posUpto + (threadState->vector->posUpto & BYTE_BLOCK_NOT_MASK); + } + + if (doVectorOffsets) { + threadState->offsetUpto = threadState->vector->offsetUpto & BYTE_BLOCK_MASK; + threadState->offsets = threadState->vectorsPool->buffers[threadState->vector->offsetUpto >> BYTE_BLOCK_SHIFT]; + threadState->writeOffsetVInt(offsetStartCode); + threadState->writeOffsetVInt(offsetEnd - offsetStart); + threadState->vector->lastOffset = offsetEnd; + threadState->vector->offsetUpto = threadState->offsetUpto + (threadState->vector->offsetUpto & BYTE_BLOCK_NOT_MASK); + } + } catch (CLuceneError &t) { + throw AbortException(t, _parent); + } +} + +void DocumentsWriter::ThreadState::FieldData::rehashPostings(const int32_t newSize) { + + const int32_t newMask = newSize - 1; + + ValueArray newHash(newSize); + int32_t hashPos, code; + const TCHAR *pos = NULL; + const TCHAR *start = NULL; + Posting *p0; + + for (int32_t i = 0; i < postingsHashSize; i++) { + p0 = postingsHash[i]; + if (p0 != NULL) { + start = threadState->charPool->buffers[p0->textStart >> CHAR_BLOCK_SHIFT] + (p0->textStart & CHAR_BLOCK_MASK); + pos = start; + while (*pos != CLUCENE_END_OF_WORD) + pos++; + code = 0; + while (pos > start) + code = (code * 31) + *--pos; + + hashPos = code & newMask; + assert(hashPos >= 0); + if (newHash[hashPos] != NULL) { + const int32_t inc = ((code >> 8) + code) | 1; + do { + code += inc; + hashPos = code & newMask; + } while (newHash[hashPos] != NULL); + } + newHash.values[hashPos] = p0; + } + } + + postingsHashMask = newMask; + postingsHash.deleteArray(); + postingsHash.length = newHash.length; + postingsHash.values = newHash.takeArray(); + postingsHashSize = newSize; + postingsHashHalfSize = newSize >> 1; +} + +void DocumentsWriter::ThreadState::FieldData::writeVectors(FieldInfo *fieldInfo) { + assert(fieldInfo->storeTermVector); + + threadState->vectorFieldNumbers.values[threadState->numVectorFields] = fieldInfo->number; + threadState->vectorFieldPointers.values[threadState->numVectorFields] = threadState->tvfLocal->getFilePointer(); + threadState->numVectorFields++; + + const int32_t numPostingsVectors = postingsVectorsUpto; + + threadState->tvfLocal->writeVInt(numPostingsVectors); + uint8_t bits = 0x0; + if (doVectorPositions) + bits |= TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR; + if (doVectorOffsets) + bits |= TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR; + threadState->tvfLocal->writeByte(bits); + + threadState->doVectorSort(threadState->postingsVectors, numPostingsVectors); + + Posting *lastPosting = NULL; + + ByteSliceReader *reader = vectorSliceReader; + + for (int32_t j = 0; j < numPostingsVectors; j++) { + PostingVector *vector = threadState->postingsVectors[j]; + Posting *posting = vector->p; + const int32_t freq = posting->docFreq; + + int32_t prefix = 0; + const TCHAR *text2 = threadState->charPool->buffers[posting->textStart >> CHAR_BLOCK_SHIFT]; + const TCHAR *start2 = text2 + (posting->textStart & CHAR_BLOCK_MASK); + const TCHAR *pos2 = start2; + + // Compute common prefix between last term and + // this term + if (lastPosting == NULL) + prefix = 0; + else { + const TCHAR *text1 = threadState->charPool->buffers[lastPosting->textStart >> CHAR_BLOCK_SHIFT]; + const TCHAR *start1 = text1 + (lastPosting->textStart & CHAR_BLOCK_MASK); + const TCHAR *pos1 = start1; + while (true) { + if (*pos1 != *pos2 || *pos1 == CLUCENE_END_OF_WORD) { + prefix = pos1 - start1; + break; + } + pos1++; + pos2++; + } + } + lastPosting = posting; + + // Compute length + while (*pos2 != CLUCENE_END_OF_WORD) + pos2++; + + const int32_t suffix = pos2 - start2 - prefix; + threadState->tvfLocal->writeVInt(prefix); + threadState->tvfLocal->writeVInt(suffix); + threadState->tvfLocal->writeChars(start2 + prefix, suffix); + threadState->tvfLocal->writeVInt(freq); + + if (doVectorPositions) { + reader->init(threadState->vectorsPool, vector->posStart, vector->posUpto); + reader->writeTo(threadState->tvfLocal); + } + + if (doVectorOffsets) { + reader->init(threadState->vectorsPool, vector->offsetStart, vector->offsetUpto); + reader->writeTo(threadState->tvfLocal); + } + } +} + +CL_NS_END diff --git a/src/core/CLucene/index/FieldInfos.cpp b/src/core/CLucene/index/FieldInfos.cpp new file mode 100644 index 00000000000..2c283d4e2b5 --- /dev/null +++ b/src/core/CLucene/index/FieldInfos.cpp @@ -0,0 +1,236 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FieldInfos.h" + +#include "CLucene/store/Directory.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +////#include "CLucene/util/VoidMap.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" + +CL_NS_USE(store) +CL_NS_USE(document) +CL_NS_USE(util) +CL_NS_DEF(index) + + +FieldInfo::FieldInfo(const TCHAR *_fieldName, + const bool _isIndexed, + const int32_t _fieldNumber, + const bool _storeTermVector, + const bool _storeOffsetWithTermVector, + const bool _storePositionWithTermVector, + const bool _omitNorms, + const bool _storePayloads) : name(CLStringIntern::intern(_fieldName )), + isIndexed(_isIndexed), + number(_fieldNumber), + storeTermVector(_storeTermVector), + storeOffsetWithTermVector(_storeOffsetWithTermVector), + storePositionWithTermVector(_storePositionWithTermVector), + omitNorms(_omitNorms), storePayloads(_storePayloads) { +} + +FieldInfo::~FieldInfo(){ + CL_NS(util)::CLStringIntern::unintern(name); +} + +FieldInfo* FieldInfo::clone() { + return _CLNEW FieldInfo(name, isIndexed, number, storeTermVector, storePositionWithTermVector, + storeOffsetWithTermVector, omitNorms, storePayloads); +} + +FieldInfos::FieldInfos(): + byName(false,false),byNumber(true) { +} + +FieldInfos::~FieldInfos(){ + byName.clear(); + byNumber.clear(); +} + +FieldInfos::FieldInfos(Directory* d, const char* name): + byName(false,false),byNumber(true) +{ + IndexInput* input = d->openInput(name); + try { + read(input); + } _CLFINALLY ( + input->close(); + _CLDELETE(input); + ); +} + +FieldInfos* FieldInfos::clone() +{ + FieldInfos* fis = _CLNEW FieldInfos(); + const size_t numField = byNumber.size(); + for(size_t i=0;iclone(); + fis->byNumber.push_back(fi); + fis->byName.put( fi->name, fi); + } + return fis; +} + +void FieldInfos::add(const Document* doc) { + const Document::FieldsType& fields = *doc->getFields(); + Field* field; + for ( Document::FieldsType::const_iterator itr = fields.begin() ; itr != fields.end() ; itr++ ){ + field = *itr; + add(field->name(), field->isIndexed(), field->isTermVectorStored(), field->isStorePositionWithTermVector(), + field->isStoreOffsetWithTermVector(), field->getOmitNorms()); + } +} + +void FieldInfos::addIndexed(const TCHAR** names, const bool storeTermVectors, const bool storePositionWithTermVector, + const bool storeOffsetWithTermVector) { + size_t i = 0; + while (names[i]) { + add(names[i], true, storeTermVectors, storePositionWithTermVector, storeOffsetWithTermVector); + ++i; + } +} + +void FieldInfos::add(const TCHAR** names,const bool isIndexed, const bool storeTermVectors, + const bool storePositionWithTermVector, const bool storeOffsetWithTermVector, const bool omitNorms, const bool storePayloads) +{ + size_t i=0; + while ( names[i] != NULL ){ + add(names[i], isIndexed, storeTermVectors, storePositionWithTermVector, + storeOffsetWithTermVector, omitNorms, storePayloads); + ++i; + } +} + +FieldInfo* FieldInfos::add( const TCHAR* name, const bool isIndexed, const bool storeTermVector, + const bool storePositionWithTermVector, const bool storeOffsetWithTermVector, const bool omitNorms, + const bool storePayloads) { + FieldInfo* fi = fieldInfo(name); + if (fi == NULL) { + return addInternal(name, isIndexed, storeTermVector, + storePositionWithTermVector, + storeOffsetWithTermVector, omitNorms, storePayloads); + } else { + if (fi->isIndexed != isIndexed) { + fi->isIndexed = true; // once indexed, always index + } + if (fi->storeTermVector != storeTermVector) { + fi->storeTermVector = true; // once vector, always vector + } + if (fi->storePositionWithTermVector != storePositionWithTermVector) { + fi->storePositionWithTermVector = true; // once vector, always vector + } + if (fi->storeOffsetWithTermVector != storeOffsetWithTermVector) { + fi->storeOffsetWithTermVector = true; // once vector, always vector + } + if (fi->omitNorms != omitNorms) { + fi->omitNorms = false; // once norms are stored, always store + } + if (fi->storePayloads != storePayloads) { + fi->storePayloads = true; + } + } + return fi; +} + +FieldInfo* FieldInfos::addInternal( const TCHAR* name, const bool isIndexed, const bool storeTermVector, + const bool storePositionWithTermVector, const bool storeOffsetWithTermVector, + const bool omitNorms, const bool storePayloads) { + + FieldInfo* fi = _CLNEW FieldInfo(name, isIndexed, byNumber.size(), storeTermVector, + storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads); + byNumber.push_back(fi); + byName.put( fi->name, fi); + return fi; +} + +int32_t FieldInfos::fieldNumber(const TCHAR* fieldName)const { + FieldInfo* fi = fieldInfo(fieldName); + return (fi!=NULL) ? fi->number : -1; +} + +FieldInfo* FieldInfos::fieldInfo(const TCHAR* fieldName) const { + FieldInfo* ret = byName.get(fieldName); + return ret; +} + +const TCHAR* FieldInfos::fieldName(const int32_t fieldNumber) const { + FieldInfo* fi = fieldInfo(fieldNumber); + return (fi==NULL)?LUCENE_BLANK_STRING:fi->name; +} + +FieldInfo* FieldInfos::fieldInfo(const int32_t fieldNumber) const { + if ( fieldNumber < 0 || (size_t)fieldNumber >= byNumber.size() ) + return NULL; + return byNumber[fieldNumber]; +} + +size_t FieldInfos::size()const { + return byNumber.size(); +} + +bool FieldInfos::hasVectors() const{ + for (size_t i = 0; i < size(); i++) { + if (fieldInfo(i)->storeTermVector) + return true; + } + return false; +} + +void FieldInfos::write(Directory* d, const char* name) const{ + IndexOutput* output = d->createOutput(name); + try { + write(output); + } _CLFINALLY ( + output->close(); + _CLDELETE(output); + ); +} + +void FieldInfos::write(IndexOutput* output) const{ + output->writeVInt(static_cast(size())); + FieldInfo* fi; + uint8_t bits; + for (size_t i = 0; i < size(); ++i) { + fi = fieldInfo(i); + bits = 0x0; + if (fi->isIndexed) bits |= IS_INDEXED; + if (fi->storeTermVector) bits |= STORE_TERMVECTOR; + if (fi->storePositionWithTermVector) bits |= STORE_POSITIONS_WITH_TERMVECTOR; + if (fi->storeOffsetWithTermVector) bits |= STORE_OFFSET_WITH_TERMVECTOR; + if (fi->omitNorms) bits |= OMIT_NORMS; + if (fi->storePayloads) bits |= STORE_PAYLOADS; + + output->writeString(fi->name,_tcslen(fi->name)); + output->writeByte(bits); + } +} + +void FieldInfos::read(IndexInput* input) { + int32_t size = input->readVInt();//read in the size + uint8_t bits; + bool isIndexed,storeTermVector,storePositionsWithTermVector,storeOffsetWithTermVector,omitNorms,storePayloads; + for (int32_t i = 0; i < size; ++i){ + TCHAR* name = input->readString(); //we could read name into a string buffer, but we can't be sure what the maximum field length will be. + bits = input->readByte(); + isIndexed = (bits & IS_INDEXED) != 0; + storeTermVector = (bits & STORE_TERMVECTOR) != 0; + storePositionsWithTermVector = (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0; + storeOffsetWithTermVector = (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0; + omitNorms = (bits & OMIT_NORMS) != 0; + storePayloads = (bits & STORE_PAYLOADS) != 0; + + addInternal(name, isIndexed, storeTermVector, storePositionsWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads); + _CLDELETE_CARRAY(name); + } +} + +CL_NS_END diff --git a/src/core/CLucene/index/FieldsReader.cpp b/src/core/CLucene/index/FieldsReader.cpp new file mode 100644 index 00000000000..045758716f8 --- /dev/null +++ b/src/core/CLucene/index/FieldsReader.cpp @@ -0,0 +1,565 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include +#include "CLucene/util/Misc.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/FieldSelector.h" +#include "_FieldInfos.h" +#include "_FieldsWriter.h" +#include "_FieldsReader.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include + +CL_NS_USE(store) +CL_NS_USE(document) +CL_NS_USE(util) +CL_NS_DEF(index) + +FieldsReader::FieldsReader(Directory* d, const char* segment, FieldInfos* fn, int32_t _readBufferSize, int32_t _docStoreOffset, int32_t size): + fieldInfos(fn), cloneableFieldsStream(NULL), fieldsStream(NULL), indexStream(NULL), + numTotalDocs(0),_size(0), closed(false),docStoreOffset(0) +{ +//Func - Constructor +//Pre - d contains a valid reference to a Directory +// segment != NULL +// fn contains a valid reference to a FieldInfos +//Post - The instance has been created + + CND_PRECONDITION(segment != NULL, "segment != NULL"); + + bool success = false; + + try { + cloneableFieldsStream = d->openInput( Misc::segmentname(segment,".fdt").c_str(), _readBufferSize ); + fieldsStream = cloneableFieldsStream->clone(); + + indexStream = d->openInput( Misc::segmentname(segment,".fdx").c_str(), _readBufferSize ); + + if (_docStoreOffset != -1) { + // We read only a slice out of this shared fields file + this->docStoreOffset = _docStoreOffset; + this->_size = size; + + // Verify the file is long enough to hold all of our + // docs + CND_CONDITION(((int32_t) (indexStream->length() / 8)) >= size + this->docStoreOffset, + "the file is not long enough to hold all of our docs"); + } else { + this->docStoreOffset = 0; + this->_size = (int32_t) (indexStream->length() >> 3); + } + + //_size = (int32_t)indexStream->length()/8; + + numTotalDocs = (int32_t) (indexStream->length() >> 3); + success = true; + } _CLFINALLY ({ + // With lock-less commits, it's entirely possible (and + // fine) to hit a FileNotFound exception above. In + // this case, we want to explicitly close any subset + // of things that were opened so that we don't have to + // wait for a GC to do so. + if (!success) { + close(); + } + }); +} + +FieldsReader::~FieldsReader(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed + + close(); +} + +void FieldsReader::ensureOpen() { + if (closed) { + _CLTHROWA(CL_ERR_IllegalState, "this FieldsReader is closed"); + } +} + +void FieldsReader::close() { + if (!closed) { + if (fieldsStream){ + fieldsStream->close(); + _CLDELETE(fieldsStream); + } + if (cloneableFieldsStream){ + cloneableFieldsStream->close(); + _CLDELETE(cloneableFieldsStream); + } + if(indexStream){ + indexStream->close(); + _CLDELETE(indexStream); + } + /* + CL_NS(store)::IndexInput* localFieldsStream = fieldsStreamTL.get(); + if (localFieldsStream != NULL) { + localFieldsStream->close(); + fieldsStreamTL->set(NULL); + }*/ + closed = true; + } +} + +int32_t FieldsReader::size() const{ + return _size; +} + +bool FieldsReader::doc(int32_t n, Document& doc, const CL_NS(document)::FieldSelector* fieldSelector) { + if ( (n + docStoreOffset) * 8L > indexStream->length() ) + return false; + indexStream->seek((n + docStoreOffset) * 8L); + int64_t position = indexStream->readLong(); + fieldsStream->seek(position); + + int32_t numFields = fieldsStream->readVInt(); + for (int32_t i = 0; i < numFields; i++) { + const int32_t fieldNumber = fieldsStream->readVInt(); + FieldInfo* fi = fieldInfos->fieldInfo(fieldNumber); + if ( fi == NULL ) _CLTHROWA(CL_ERR_IO, "Field stream is invalid"); + + FieldSelector::FieldSelectorResult acceptField = (fieldSelector == NULL) ? FieldSelector::LOAD : fieldSelector->accept(fi->name); + + uint8_t bits = fieldsStream->readByte(); + CND_CONDITION(bits <= FieldsWriter::FIELD_IS_COMPRESSED + FieldsWriter::FIELD_IS_TOKENIZED + FieldsWriter::FIELD_IS_BINARY, + "invalid field bits"); + + const bool compressed = (bits & FieldsWriter::FIELD_IS_COMPRESSED) != 0; + const bool tokenize = (bits & FieldsWriter::FIELD_IS_TOKENIZED) != 0; + const bool binary = (bits & FieldsWriter::FIELD_IS_BINARY) != 0; + + //TODO: Find an alternative approach here if this list continues to grow beyond the + //list of 5 or 6 currently here. See Lucene 762 for discussion + if (acceptField == FieldSelector::LOAD) { + addField(doc, fi, binary, compressed, tokenize); + } + else if (acceptField == FieldSelector::LOAD_FOR_MERGE) { + addFieldForMerge(doc, fi, binary, compressed, tokenize); + } + else if (acceptField == FieldSelector::LOAD_AND_BREAK){ + addField(doc, fi, binary, compressed, tokenize); + break;//Get out of this loop + } + else if (acceptField == FieldSelector::LAZY_LOAD) { + addFieldLazy(doc, fi, binary, compressed, tokenize); + } + else if (acceptField == FieldSelector::SIZE){ + skipField(binary, compressed, addFieldSize(doc, fi, binary, compressed)); + } + else if (acceptField == FieldSelector::SIZE_AND_BREAK){ + addFieldSize(doc, fi, binary, compressed); + break; + }else { + skipField(binary, compressed); + } + } + return true; +} + +CL_NS(store)::IndexInput* FieldsReader::rawDocs(int32_t* lengths, const int32_t startDocID, const int32_t numDocs) { + indexStream->seek((docStoreOffset+startDocID) * 8L); + int64_t startOffset = indexStream->readLong(); + int64_t lastOffset = startOffset; + int32_t count = 0; + while (count < numDocs) { + int64_t offset; + const int32_t docID = docStoreOffset + startDocID + count + 1; + CND_CONDITION( docID <= numTotalDocs, "invalid docID"); + if (docID < numTotalDocs) + offset = indexStream->readLong(); + else + offset = fieldsStream->length(); + lengths[count++] = static_cast(offset-lastOffset); + lastOffset = offset; + } + + fieldsStream->seek(startOffset); + + return fieldsStream; +} + +void FieldsReader::skipField(const bool binary, const bool compressed) { + skipField(binary, compressed, fieldsStream->readVInt()); +} + +void FieldsReader::skipField(const bool binary, const bool compressed, const int32_t toRead) { + if (binary || compressed) { + int64_t pointer = fieldsStream->getFilePointer(); + fieldsStream->seek(pointer + toRead); + } else { + //We need to skip chars. This will slow us down, but still better + fieldsStream->skipChars(toRead); + } +} + +void FieldsReader::addFieldLazy(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, + const bool compressed, const bool tokenize) { + if (binary) { + int32_t toRead = fieldsStream->readVInt(); + int64_t pointer = fieldsStream->getFilePointer(); + if (compressed) { + doc.add(*_CLNEW LazyField(this, fi->name, Field::STORE_COMPRESS, toRead, pointer)); + } else { + doc.add(*_CLNEW LazyField(this, fi->name, Field::STORE_YES, toRead, pointer)); + } + //Need to move the pointer ahead by toRead positions + fieldsStream->seek(pointer + toRead); + } else { + LazyField* f = NULL; + if (compressed) { + int32_t toRead = fieldsStream->readVInt(); + int64_t pointer = fieldsStream->getFilePointer(); + f = _CLNEW LazyField(this, fi->name, Field::STORE_COMPRESS, toRead, pointer); + //skip over the part that we aren't loading + fieldsStream->seek(pointer + toRead); + f->setOmitNorms(fi->omitNorms); + } else { + int32_t length = fieldsStream->readVInt(); + int64_t pointer = fieldsStream->getFilePointer(); + //Skip ahead of where we are by the length of what is stored + fieldsStream->skipChars(length); + f = _CLNEW LazyField(this, fi->name, Field::STORE_YES | getIndexType(fi, tokenize) | getTermVectorType(fi), length, pointer); + f->setOmitNorms(fi->omitNorms); + } + doc.add(*f); + } +} + +// in merge mode we don't uncompress the data of a compressed field +void FieldsReader::addFieldForMerge(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize) { + void* data; + Field::ValueType v; + + if ( binary || compressed) { + int32_t toRead = fieldsStream->readVInt(); + CL_NS(util)::ValueArray b(toRead); + fieldsStream->readBytes(b.values,toRead); + v = Field::VALUE_BINARY; + data = b.takeArray(); + } else { + data = fieldsStream->readString(); + v = Field::VALUE_STRING; + } + + doc.add(*_CLNEW FieldForMerge(data, v, fi, binary, compressed, tokenize)); +} + +void FieldsReader::addField(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize) { + + //we have a binary stored field, and it may be compressed + if (binary) { + const int32_t toRead = fieldsStream->readVInt(); + ValueArray* b = _CLNEW ValueArray(toRead); + fieldsStream->readBytes(b->values,toRead); + if (compressed) { + // we still do not support compressed fields + ValueArray* data = _CLNEW ValueArray; + try{ + uncompress(*b, *data); + }catch(CLuceneError& err){ + _CLDELETE(data); + _CLDELETE(b); + throw err; + } + _CLDELETE(b); + doc.add(* _CLNEW Field(fi->name, data, Field::STORE_COMPRESS, false)); + }else{ + doc.add(* _CLNEW Field(fi->name, b, Field::STORE_YES, false)); + } + //no need to clean up, Field consumes b + } else { + uint8_t bits = 0; + bits |= getIndexType(fi, tokenize); + bits |= getTermVectorType(fi); + + Field* f = NULL; + if (compressed) { + bits |= Field::STORE_COMPRESS; + const int32_t toRead = fieldsStream->readVInt(); + ValueArray* b = _CLNEW ValueArray(toRead); + fieldsStream->readBytes(b->values,toRead); + ValueArray data; + try{ + uncompress(*b, data); + }_CLFINALLY( _CLDELETE(b) ) + +#ifndef _ASCII + //convert to utf8 + TCHAR* result = _CL_NEWARRAY(TCHAR, data.length); + size_t l = lucene_utf8towcs(result, (const char*)data.values, data.length); + result[l] = 0; + + //if we were a bit too pesimistic with the size, then shrink the memory... + if ( l < data.length/2 ){ + TCHAR* tmp = result; + result = STRDUP_TtoT(result); + _CLDELETE_LCARRAY(tmp); + } + + f = _CLNEW Field(fi->name, // field name + result, // uncompress the value and add as string + bits, false); +#else + f = _CLNEW Field(fi->name, // field name + reinterpret_cast(data.values), // uncompress the value and add as string + bits, false); +#endif + f->setOmitNorms(fi->omitNorms); + } else { + bits |= Field::STORE_YES; + TCHAR* str = fieldsStream->readString(); + f = _CLNEW Field(fi->name, // name + str, // read value + bits, false); + f->setOmitNorms(fi->omitNorms); + } + doc.add(*f); + } +} + +int32_t FieldsReader::addFieldSize(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed) { + const int32_t size = fieldsStream->readVInt(); + const uint32_t bytesize = binary || compressed ? size : 2*size; + ValueArray* sizebytes = _CLNEW ValueArray(4); + sizebytes->values[0] = (uint8_t) (bytesize>>24); + sizebytes->values[1] = (uint8_t) (bytesize>>16); + sizebytes->values[2] = (uint8_t) (bytesize>> 8); + sizebytes->values[3] = (uint8_t) bytesize ; + doc.add(*_CLNEW Field(fi->name, sizebytes, Field::STORE_YES, false)); + return size; +} + +CL_NS(document)::Field::TermVector FieldsReader::getTermVectorType(const FieldInfo* fi) { + if (fi->storeTermVector) { + if (fi->storeOffsetWithTermVector) { + if (fi->storePositionWithTermVector) { + return Field::TERMVECTOR_WITH_POSITIONS_OFFSETS; + } else { + return Field::TERMVECTOR_WITH_OFFSETS; + } + } else if (fi->storePositionWithTermVector) { + return Field::TERMVECTOR_WITH_POSITIONS; + } else { + return Field::TERMVECTOR_YES; + } + } else { + return Field::TERMVECTOR_NO ; + } +} + +CL_NS(document)::Field::Index FieldsReader::getIndexType(const FieldInfo* fi, const bool tokenize) { + if (fi->isIndexed && tokenize) + return Field::INDEX_TOKENIZED; + else if (fi->isIndexed && !tokenize) + return Field::INDEX_UNTOKENIZED; + else + return Field::INDEX_NO; +} + + +FieldsReader::LazyField::LazyField(FieldsReader* _parent, const TCHAR* _name, + int config, const int32_t _toRead, const int64_t _pointer) +: Field(_name, config), parent(_parent) { + // todo: need to allow for auto setting Field::INDEX_NO | Field::TERMVECTOR_NO so only Store is required + this->toRead = _toRead; + this->pointer = _pointer; + lazy = true; +} +FieldsReader::LazyField::~LazyField(){ +} + +CL_NS(store)::IndexInput* FieldsReader::LazyField::getFieldStream(){ + CL_NS(store)::IndexInput* localFieldsStream = parent->fieldsStreamTL.get(); + if (localFieldsStream == NULL) { + localFieldsStream = parent->cloneableFieldsStream->clone(); + parent->fieldsStreamTL.set(localFieldsStream); + } + return localFieldsStream; +} + +const ValueArray* FieldsReader::LazyField::binaryValue(){ + parent->ensureOpen(); + if (fieldsData == NULL) { + ValueArray* b = _CLNEW ValueArray(toRead); + CL_NS(store)::IndexInput* localFieldsStream = getFieldStream(); + + //Throw this IO Exception since IndexREader.document does so anyway, so probably not that big of a change for people + //since they are already handling this exception when getting the document + try { + localFieldsStream->seek(pointer); + localFieldsStream->readBytes(b->values, toRead); + if (isCompressed() == true) { + ValueArray* data = _CLNEW ValueArray; + try{ + uncompress(*b, *data); + }catch (CLuceneError& err){ + _CLDELETE(data); + _CLDELETE(b); + throw err; + } + _CLDELETE(b); + fieldsData = data; + } else { + fieldsData = b; + } + valueType = VALUE_BINARY; + + }catch(CLuceneError& err){ + if ( err.number() != CL_ERR_IO ) throw err; + _CLTHROWA(CL_ERR_FieldReader, err.what()); + } + + } + return static_cast*>(fieldsData); +} + +CL_NS(util)::Reader* FieldsReader::LazyField::readerValue(){ + parent->ensureOpen(); + return (valueType & VALUE_READER) ? static_cast(fieldsData) : NULL; +} + + +CL_NS(analysis)::TokenStream* FieldsReader::LazyField::tokenStreamValue(){ + parent->ensureOpen(); + return (valueType & VALUE_TOKENSTREAM) ? static_cast(fieldsData) : NULL; +} + + +/** The value of the field as a String, or null. If null, the Reader value, +* binary value, or TokenStream value is used. Exactly one of stringValue(), +* readerValue(), binaryValue(), and tokenStreamValue() must be set. */ +const TCHAR* FieldsReader::LazyField::stringValue() { + parent->ensureOpen(); + if (fieldsData == NULL) { + CL_NS(store)::IndexInput* localFieldsStream = getFieldStream(); + localFieldsStream->seek(pointer); + if (isCompressed()) { + ValueArray b(toRead); + ValueArray uncompressed; + localFieldsStream->readBytes(b.values, toRead); + _resetValue(); + uncompress(b, uncompressed); //no need to catch error, memory all in frame + +#ifndef _ASCII + TCHAR* str = _CL_NEWARRAY(TCHAR, uncompressed.length); + size_t l = lucene_utf8towcs(str, (const char*)uncompressed.values, uncompressed.length); + str[l] = 0; + + if ( l < uncompressed.length/2 ){ + //too pesimistic with size... + fieldsData = STRDUP_TtoT(str); + _CLDELETE_LCARRAY(str); + }else{ + fieldsData = str; + } +#else + fieldsData = uncompressed.values; +#endif + } else { + //read in chars b/c we already know the length we need to read + TCHAR* chars = _CL_NEWARRAY(TCHAR, toRead+1); + localFieldsStream->readChars(chars, 0, toRead); + chars[toRead] = _T('\0'); + _resetValue(); + fieldsData = chars; + } + valueType = VALUE_STRING; + } + return static_cast(fieldsData); //instanceof String ? (String) fieldsData : null; +} + +int64_t FieldsReader::LazyField::getPointer() const { + parent->ensureOpen(); + return pointer; +} + +void FieldsReader::LazyField::setPointer(const int64_t _pointer) { + parent->ensureOpen(); + this->pointer = _pointer; +} + +int32_t FieldsReader::LazyField::getToRead() const { + parent->ensureOpen(); + return toRead; +} + +void FieldsReader::LazyField::setToRead(const int32_t _toRead) { + parent->ensureOpen(); + this->toRead = _toRead; +} + +const TCHAR* FieldsReader::FieldForMerge::stringValue() const { + return (valueType & VALUE_STRING) ? static_cast(fieldsData) : NULL; +} + +CL_NS(util)::Reader* FieldsReader::FieldForMerge::readerValue() const { + // not needed for merge + return NULL; +} + +const CL_NS(util)::ValueArray* FieldsReader::FieldForMerge::binaryValue(){ + return (valueType & VALUE_BINARY) ? static_cast*>(fieldsData) : NULL; +} + +CL_NS(analysis)::TokenStream* FieldsReader::FieldForMerge::tokenStreamValue() const { + // not needed for merge + return NULL; +} + +FieldsReader::FieldForMerge::FieldForMerge(void* _value, ValueType _type, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize) : Field(fi->name, 0) { + + uint32_t bits = STORE_YES; + + this->fieldsData = _value; + this->valueType = _type; + + if (tokenize) bits |= INDEX_TOKENIZED; + if (compressed) bits |= STORE_COMPRESS; + + if (fi->isIndexed && !tokenize) bits |= INDEX_UNTOKENIZED; + if (fi->omitNorms) bits |= INDEX_NONORMS; + if (fi->storeOffsetWithTermVector) bits |= TERMVECTOR_WITH_OFFSETS; + if (fi->storePositionWithTermVector) bits |= TERMVECTOR_WITH_POSITIONS; + if (fi->storeTermVector) bits |= TERMVECTOR_YES; + + setConfig(bits); +} +FieldsReader::FieldForMerge::~FieldForMerge(){ +} +const char* FieldsReader::FieldForMerge::getClassName(){ + return "FieldsReader::FieldForMerge"; +} +const char* FieldsReader::FieldForMerge::getObjectName() const{ + return getClassName(); +} + +void FieldsReader::uncompress(const CL_NS(util)::ValueArray& input, CL_NS(util)::ValueArray& output){ + stringstream out; + string err; + if ( ! Misc::deflate(input.values, input.length, out, err) ){ + _CLTHROWA(CL_ERR_IO, err.c_str()); + } + + // get length of file: + out.seekg (0, ios::end); + size_t length = out.tellg(); + out.seekg (0, ios::beg); + + output.resize(length+1); + out.read((char*)output.values,length); + output.values[length] = 0;//null-terminate in case we want to use it as utf8 +} + +CL_NS_END diff --git a/src/core/CLucene/index/FieldsWriter.cpp b/src/core/CLucene/index/FieldsWriter.cpp new file mode 100644 index 00000000000..8a56ce58fc1 --- /dev/null +++ b/src/core/CLucene/index/FieldsWriter.cpp @@ -0,0 +1,269 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FieldsWriter.h" + +//#include "CLucene/util/VoidMap.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Misc.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "_FieldInfos.h" +#include "_FieldsReader.h" +#include + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_USE(document) +CL_NS_DEF(index) + +FieldsWriter::FieldsWriter(Directory* d, const char* segment, FieldInfos* fn): + fieldInfos(fn) +{ +//Func - Constructor +//Pre - d contains a valid reference to a directory +// segment != NULL and contains the name of the segment +//Post - fn contains a valid reference toa a FieldInfos + + CND_PRECONDITION(segment != NULL,"segment is NULL"); + + fieldsStream = d->createOutput ( Misc::segmentname(segment,".fdt").c_str() ); + + CND_CONDITION(fieldsStream != NULL,"fieldsStream is NULL"); + + indexStream = d->createOutput( Misc::segmentname(segment,".fdx").c_str() ); + + CND_CONDITION(indexStream != NULL,"indexStream is NULL"); + + doClose = true; +} + +FieldsWriter::FieldsWriter(CL_NS(store)::IndexOutput* fdx, CL_NS(store)::IndexOutput* fdt, FieldInfos* fn): + fieldInfos(fn) +{ + fieldsStream = fdt; + CND_CONDITION(fieldsStream != NULL,"fieldsStream is NULL"); + indexStream = fdx; + CND_CONDITION(fieldsStream != NULL,"fieldsStream is NULL"); + doClose = false; +} + +FieldsWriter::~FieldsWriter(){ +//Func - Destructor +//Pre - true +//Post - Instance has been destroyed + + close(); +} + +void FieldsWriter::close() { +//Func - Closes all streams and frees all resources +//Pre - true +//Post - All streams have been closed all resources have been freed + + if (! doClose ) + return; + + //Check if fieldsStream is valid + if (fieldsStream){ + //Close fieldsStream + fieldsStream->close(); + _CLDELETE( fieldsStream ); + } + + //Check if indexStream is valid + if (indexStream){ + //Close indexStream + indexStream->close(); + _CLDELETE( indexStream ); + } +} + +void FieldsWriter::addDocument(Document* doc) { +//Func - Adds a document +//Pre - doc contains a valid reference to a Document +// indexStream != NULL +// fieldsStream != NULL +//Post - The document doc has been added + + CND_PRECONDITION(indexStream != NULL,"indexStream is NULL"); + CND_PRECONDITION(fieldsStream != NULL,"fieldsStream is NULL"); + + indexStream->writeLong(fieldsStream->getFilePointer()); + + int32_t storedCount = 0; + { + const Document::FieldsType& fields = *doc->getFields(); + for ( Document::FieldsType::const_iterator itr = fields.begin() ; itr != fields.end() ; itr++ ){ + Field* field = *itr; + if (field->isStored()) + storedCount++; + } + fieldsStream->writeVInt(storedCount); + } + { + const Document::FieldsType& fields = *doc->getFields(); + for ( Document::FieldsType::const_iterator itr = fields.begin() ; itr != fields.end() ; itr++ ){ + Field* field = *itr; + if (field->isStored()) { + writeField(fieldInfos->fieldInfo(field->name()), field); + } + } + } +} + +void FieldsWriter::writeField(FieldInfo* fi, CL_NS(document)::Field* field) +{ + // if the field as an instanceof FieldsReader.FieldForMerge, we're in merge mode + // and field.binaryValue() already returns the compressed value for a field + // with isCompressed()==true, so we disable compression in that case + bool disableCompression = (field->instanceOf(FieldsReader::FieldForMerge::getClassName())); + + fieldsStream->writeVInt(fi->number); + uint8_t bits = 0; + if (field->isTokenized()) + bits |= FieldsWriter::FIELD_IS_TOKENIZED; + if (field->isBinary()) + bits |= FieldsWriter::FIELD_IS_BINARY; + if (field->isCompressed()) + bits |= FieldsWriter::FIELD_IS_COMPRESSED; + + fieldsStream->writeByte(bits); + + if ( field->isCompressed() ){ + // compression is enabled for the current field + CL_NS(util)::ValueArray dataB; + const CL_NS(util)::ValueArray* data = &dataB; + + if (disableCompression) { + // optimized case for merging, the data + // is already compressed + data = field->binaryValue(); + } else { + // check if it is a binary field + if (field->isBinary()) { + compress(*field->binaryValue(), dataB); + }else if ( field->stringValue() == NULL ){ //we must be using readerValue + CND_PRECONDITION(!field->isIndexed(), "Cannot store reader if it is indexed too") + Reader* r = field->readerValue(); + + int32_t sz = r->size(); + if ( sz < 0 ) + sz = 10000000; //todo: we should warn the developer here.... + + //read the entire string + const TCHAR* rv = NULL; + int64_t rl = r->read((const void**)&rv, sz, 1); + if ( rl > LUCENE_INT32_MAX_SHOULDBE ) + _CLTHROWA(CL_ERR_Runtime,"Field length too long"); + else if ( rl < 0 ) + rl = 0; + + string str = lucene_wcstoutf8string(rv, rl); + CL_NS(util)::ValueArray utfstr; + utfstr.length = str.length(); + utfstr.values = (uint8_t*)str.c_str(); + compress(utfstr, dataB); + utfstr.values = NULL; + }else if ( field->stringValue() != NULL ){ + string str = lucene_wcstoutf8string(field->stringValue(), LUCENE_INT32_MAX_SHOULDBE); + CL_NS(util)::ValueArray utfstr; + utfstr.length = str.length(); + utfstr.values = (uint8_t*)str.c_str(); + compress(utfstr, dataB); + utfstr.values = NULL; + } + } + fieldsStream->writeVInt(data->length); + fieldsStream->writeBytes(data->values, data->length); + + }else{ + + //FEATURE: this problem in Java Lucene too, if using Reader, data is not stored. + //todo: this is a logic bug... + //if the field is stored, and indexed, and is using a reader the field wont get indexed + // + //if we could write zero prefixed vints (therefore static length), then we could + //write a reader directly to the field indexoutput and then go back and write the data + //length. however this is not supported in lucene yet... + //if this is ever implemented, then it would make sense to also be able to combine the + //FieldsWriter and DocumentWriter::invertDocument process, and use a streamfilter to + //write the field data while the documentwrite analyses the document! how cool would + //that be! it would cut out all these buffers!!! + + // compression is disabled for the current field + if (field->isBinary()) { + const CL_NS(util)::ValueArray* data = field->binaryValue(); + fieldsStream->writeVInt(data->length); + fieldsStream->writeBytes(data->values, data->length); + + }else if ( field->stringValue() == NULL ){ //we must be using readerValue + CND_PRECONDITION(!field->isIndexed(), "Cannot store reader if it is indexed too") + Reader* r = field->readerValue(); + + int32_t sz = r->size(); + if ( sz < 0 ) + sz = 10000000; //todo: we should warn the developer here.... + + //read the entire string + const TCHAR* rv; + int64_t rl = r->read((const void**)&rv, sz, 1); + if ( rl > LUCENE_INT32_MAX_SHOULDBE ) + _CLTHROWA(CL_ERR_Runtime,"Field length too long"); + else if ( rl < 0 ) + rl = 0; + + fieldsStream->writeString( rv, (int32_t)rl); + }else if ( field->stringValue() != NULL ){ + fieldsStream->writeString(field->stringValue(),_tcslen(field->stringValue())); + }else + _CLTHROWA(CL_ERR_Runtime, "No values are set for the field"); + } +} + +void FieldsWriter::flushDocument(int32_t numStoredFields, CL_NS(store)::RAMOutputStream* buffer) { + indexStream->writeLong(fieldsStream->getFilePointer()); + fieldsStream->writeVInt(numStoredFields); + buffer->writeTo(fieldsStream); +} + +void FieldsWriter::flush() { + indexStream->flush(); + fieldsStream->flush(); +} + +void FieldsWriter::addRawDocuments(CL_NS(store)::IndexInput* stream, const int32_t* lengths, const int32_t numDocs) { + int64_t position = fieldsStream->getFilePointer(); + const int64_t start = position; + for(int32_t i=0;iwriteLong(position); + position += lengths[i]; + } + fieldsStream->copyBytes(stream, position-start); + CND_CONDITION(fieldsStream->getFilePointer() == position,"fieldsStream->getFilePointer() != position"); +} + +void FieldsWriter::compress(const CL_NS(util)::ValueArray& input, CL_NS(util)::ValueArray& output){ + stringstream out; + string err; + if ( ! Misc::inflate(input.values, input.length, out, err) ){ + _CLTHROWA(CL_ERR_IO, err.c_str()); + } + + // get length of file: + out.seekg (0, ios::end); + size_t length = out.tellg(); + out.seekg (0, ios::beg); + + output.resize(length); + out.read((char*)output.values,length); +} + +CL_NS_END diff --git a/src/core/CLucene/index/IndexDeletionPolicy.cpp b/src/core/CLucene/index/IndexDeletionPolicy.cpp new file mode 100644 index 00000000000..49007ee7ecd --- /dev/null +++ b/src/core/CLucene/index/IndexDeletionPolicy.cpp @@ -0,0 +1,140 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexDeletionPolicy.h" + +CL_NS_DEF(index) + +IndexDeletionPolicy::~IndexDeletionPolicy(){ +} +IndexCommitPoint::~IndexCommitPoint(){ +} + + + +KeepOnlyLastCommitDeletionPolicy::~KeepOnlyLastCommitDeletionPolicy(){ +} + +void KeepOnlyLastCommitDeletionPolicy::onInit(std::vector& commits) { + // Note that commits.size() should normally be 1: + onCommit(commits); +} + +void KeepOnlyLastCommitDeletionPolicy::onCommit(std::vector& commits) { + // Note that commits.size() should normally be 2 (if not + // called by onInit above): + size_t size = commits.size(); + for(size_t i=0;ideleteCommitPoint(); + } +} + +const char* KeepOnlyLastCommitDeletionPolicy::getClassName(){ + return "KeepOnlyLastCommitDeletionPolicy"; +} +const char* KeepOnlyLastCommitDeletionPolicy::getObjectName() const{ + return getClassName(); +} + + + +/** A {@link IndexDeletionPolicy} that wraps around any other + * {@link IndexDeletionPolicy} and adds the ability to hold and + * later release a single "snapshot" of an index. While + * the snapshot is held, the {@link IndexWriter} will not + * remove any files associated with it even if the index is + * otherwise being actively, arbitrarily changed. Because + * we wrap another arbitrary {@link IndexDeletionPolicy}, this + * gives you the freedom to continue using whatever {@link + * IndexDeletionPolicy} you would normally want to use with your + * index. + +class SnapshotDeletionPolicy: public IndexDeletionPolicy { +private: + IndexCommitPoint lastCommit; + IndexDeletionPolicy primary; + IndexCommitPoint snapshot; + DEFINE_MUTEX(SnapshotDeletionPolicy_LOCK) + + class MyCommitPoint: public IndexCommitPoint { + IndexCommitPoint cp; + public: + MyCommitPoint(IndexCommitPoint cp) { + this.cp = cp; + } + String getSegmentsFileName() { + return cp.getSegmentsFileName(); + } + Collection getFileNames() throws IOException { + return cp.getFileNames(); + } + void deleteCommitPoint() { + synchronized(SnapshotDeletionPolicy_LOCK) { + // Suppress the delete request if this commit point is + // our current snapshot. + if (snapshot != cp) + cp->deleteCommitPoint(); + } + } + } + + List wrapCommits(List commits) { + final int count = commits.size(); + List myCommits = new ArrayList(count); + for(int i=0;i +#include "CLucene/util/Equators.h" + +CL_NS_DEF(index) + + +class CLUCENE_EXPORT IndexCommitPoint { +public: + virtual ~IndexCommitPoint(); + /** + * Get the segments file (segments_N) associated + * with this commit point. + */ + virtual std::string getSegmentsFileName() = 0; + + /** + * Returns all index files referenced by this commit point. + */ + virtual const std::vector& getFileNames() = 0; + + /** + * Delete this commit point. + *

+ * Upon calling this, the writer is notified that this commit + * point should be deleted. + *

+ * Decision that a commit-point should be deleted is taken by the {@link IndexDeletionPolicy} in effect + * and therefore this should only be called by its {@link IndexDeletionPolicy#onInit onInit()} or + * {@link IndexDeletionPolicy#onCommit onCommit()} methods. + */ + virtual void deleteCommitPoint() = 0; +}; + +/** + *

Expert: policy for deletion of stale {@link IndexCommitPoint index commits}. + * + *

Implement this interface, and pass it to one + * of the {@link IndexWriter} or {@link IndexReader} + * constructors, to customize when older + * {@link IndexCommitPoint point-in-time commits} + * are deleted from the index directory. The default deletion policy + * is {@link KeepOnlyLastCommitDeletionPolicy}, which always + * removes old commits as soon as a new commit is done (this + * matches the behavior before 2.2).

+ * + *

One expected use case for this (and the reason why it + * was first created) is to work around problems with an + * index directory accessed via filesystems like NFS because + * NFS does not provide the "delete on last close" semantics + * that Lucene's "point in time" search normally relies on. + * By implementing a custom deletion policy, such as "a + * commit is only removed once it has been stale for more + * than X minutes", you can give your readers time to + * refresh to the new commit before {@link IndexWriter} + * removes the old commits. Note that doing so will + * increase the storage requirements of the index. See LUCENE-710 + * for details.

+ */ +class CLUCENE_EXPORT IndexDeletionPolicy: public CL_NS(util)::NamedObject{ +public: + virtual ~IndexDeletionPolicy(); + + /** + *

This is called once when a writer is first + * instantiated to give the policy a chance to remove old + * commit points.

+ * + *

The writer locates all index commits present in the + * index directory and calls this method. The policy may + * choose to delete some of the commit points, doing so by + * calling method {@link IndexCommitPoint#delete delete()} + * of {@link IndexCommitPoint}.

+ * + *

Note: the last CommitPoint is the most recent one, + * i.e. the "front index state". Be careful not to delete it, + * unless you know for sure what you are doing, and unless + * you can afford to lose the index content while doing that. + * + * @param commits List of current + * {@link IndexCommitPoint point-in-time commits}, + * sorted by age (the 0th one is the oldest commit). + */ + virtual void onInit(std::vector& commits) = 0; + + /** + *

This is called each time the writer completed a commit. + * This gives the policy a chance to remove old commit points + * with each commit.

+ * + *

The policy may now choose to delete old commit points + * by calling method {@link IndexCommitPoint#delete delete()} + * of {@link IndexCommitPoint}.

+ * + *

If writer has autoCommit = true then + * this method will in general be called many times during + * one instance of {@link IndexWriter}. If + * autoCommit = false then this method is + * only called once when {@link IndexWriter#close} is + * called, or not at all if the {@link IndexWriter#abort} + * is called. + * + *

Note: the last CommitPoint is the most recent one, + * i.e. the "front index state". Be careful not to delete it, + * unless you know for sure what you are doing, and unless + * you can afford to lose the index content while doing that. + * + * @param commits List of {@link IndexCommitPoint}, + * sorted by age (the 0th one is the oldest commit). + */ + virtual void onCommit(std::vector& commits) = 0; +}; + + + + +/** + * This {@link IndexDeletionPolicy} implementation that + * keeps only the most recent commit and immediately removes + * all prior commits after a new commit is done. This is + * the default deletion policy. + */ + +class CLUCENE_EXPORT KeepOnlyLastCommitDeletionPolicy: public IndexDeletionPolicy { +public: + virtual ~KeepOnlyLastCommitDeletionPolicy(); + /** + * Deletes all commits except the most recent one. + */ + void onInit(std::vector& commits); + + /** + * Deletes all commits except the most recent one. + */ + void onCommit(std::vector& commits); + + static const char* getClassName(); + const char* getObjectName() const; +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/IndexFileDeleter.cpp b/src/core/CLucene/index/IndexFileDeleter.cpp new file mode 100644 index 00000000000..2d000a24d71 --- /dev/null +++ b/src/core/CLucene/index/IndexFileDeleter.cpp @@ -0,0 +1,530 @@ +#include "CLucene/_ApiHeader.h" +#include "_IndexFileDeleter.h" +#include "_IndexFileNameFilter.h" +#include "_DocumentsWriter.h" +#include "_SegmentHeader.h" +#include "CLucene/store/Directory.h" +#include "CLucene/LuceneThreads.h" +#include +#include +#include + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + +bool IndexFileDeleter::VERBOSE_REF_COUNTS = false; + +IndexFileDeleter::CommitPoint::CommitPoint(IndexFileDeleter* _this, SegmentInfos* segmentInfos){ + this->_this = _this; + this->deleted = false; + this->gen = 0; + segmentsFileName = segmentInfos->getCurrentSegmentFileName(); + int32_t size = segmentInfos->size(); + files.push_back(segmentsFileName); + gen = segmentInfos->getGeneration(); + for(int32_t i=0;iinfo(i); + if (segmentInfo->dir == _this->directory) { + const vector& ff = segmentInfo->files(); + files.insert(files.end(),ff.begin(), ff.end()); + } + } + +} +IndexFileDeleter::CommitPoint::~CommitPoint(){ +} + +/** +* Get the segments_N file for this commit point32_t. +*/ +std::string IndexFileDeleter::CommitPoint::getSegmentsFileName() { + return segmentsFileName; +} +bool IndexFileDeleter::CommitPoint::sort(IndexCommitPoint* elem1, IndexCommitPoint* elem2){ + if (((CommitPoint*)elem1)->gen < ((CommitPoint*)elem2)->gen) + return true; + return false; +} + +const std::vector& IndexFileDeleter::CommitPoint::getFileNames() { + return files; +} + +/** +* Called only be the deletion policy, to remove this +* commit point32_t from the index. +*/ +void IndexFileDeleter::CommitPoint::deleteCommitPoint() { + if (!deleted) { + deleted = true; + _this->commitsToDelete.push_back(this); + } +} + +const char* IndexFileDeleter::CommitPoint::getClassName(){ + return "IndexFileDeleter::CommitPoint"; +} +const char* IndexFileDeleter::CommitPoint::getObjectName() const{ + return getClassName(); +} +int32_t IndexFileDeleter::CommitPoint::compareTo(NamedObject* obj) { + if ( obj->getObjectName() != CommitPoint::getClassName() ) + return -1; + + CommitPoint* commit = (CommitPoint*) obj; + if (gen < commit->gen) { + return -1; + } else if (gen > commit->gen) { + return 1; + } else { + return 0; + } +} + +void IndexFileDeleter::setInfoStream(std::ostream* infoStream) { + this->infoStream = infoStream; + if (infoStream != NULL){ + string msg = string("setInfoStream deletionPolicy=") + policy->getObjectName(); + message( msg ); + } +} + +void IndexFileDeleter::message(string message) { + (*infoStream) << string("IFD [") << Misc::toString( _LUCENE_CURRTHREADID ) << string("]: ") << message << string("\n"); +} + + +IndexFileDeleter::~IndexFileDeleter(){ + _CLDELETE(policy); + commitsToDelete.clear(); + commits.clear(); + refCounts.clear(); +} +IndexFileDeleter::IndexFileDeleter(Directory* directory, IndexDeletionPolicy* policy, + SegmentInfos* segmentInfos, std::ostream* infoStream, IDocumentsWriter* docWriter): + refCounts( RefCountsType(true,true) ), commits(CommitsType(true)) +{ + this->docWriter = docWriter; + this->infoStream = infoStream; + + if (infoStream != NULL) + message( string("init: current segments file is \"") + segmentInfos->getCurrentSegmentFileName() + "\"; deletionPolicy=" + policy->getObjectName()); + + this->policy = policy; + this->directory = directory; + CommitPoint* currentCommitPoint = NULL; + + // First pass: walk the files and initialize our ref + // counts: + int64_t currentGen = segmentInfos->getGeneration(); + const IndexFileNameFilter* filter = IndexFileNameFilter::getFilter(); + + vector files; + if ( !directory->list(&files) ) + _CLTHROWA(CL_ERR_IO, (string("cannot read directory ") + directory->toString() + ": list() returned NULL").c_str()); + + + for(size_t i=0;iaccept(NULL, fileName.c_str()) && !fileName.compare(IndexFileNames::SEGMENTS_GEN) == 0) { + + // Add this file to refCounts with initial count 0: + getRefCount(fileName.c_str()); + + if ( strncmp(fileName.c_str(), IndexFileNames::SEGMENTS, strlen(IndexFileNames::SEGMENTS)) == 0 ) { + + // This is a commit (segments or segments_N), and + // it's valid (<= the max gen). Load it, then + // incref all files it refers to: + if (SegmentInfos::generationFromSegmentsFileName(fileName.c_str()) <= currentGen) { + if (infoStream != NULL) { + message("init: load commit \"" + fileName + "\""); + } + SegmentInfos sis; + bool failed = false; + try { + sis.read(directory, fileName.c_str()); + } catch (CLuceneError& e) { + if ( e.number() != CL_ERR_IO ){ + throw e; + } + // LUCENE-948: on NFS (and maybe others), if + // you have writers switching back and forth + // between machines, it's very likely that the + // dir listing will be stale and will claim a + // file segments_X exists when in fact it + // doesn't. So, we catch this and handle it + // as if the file does not exist + if (infoStream != NULL) { + message("init: hit FileNotFoundException when loading commit \"" + fileName + "\"; skipping this commit point32_t"); + } + failed = true; + } + if (!failed) { + CommitPoint* commitPoint = _CLNEW CommitPoint(this,&sis); + if (sis.getGeneration() == segmentInfos->getGeneration()) { + currentCommitPoint = commitPoint; + } + commits.push_back(commitPoint); + incRef(&sis, true); + } + } + } + } + } + + if (currentCommitPoint == NULL) { + // We did not in fact see the segments_N file + // corresponding to the segmentInfos that was passed + // in. Yet, it must exist, because our caller holds + // the write lock. This can happen when the directory + // listing was stale (eg when index accessed via NFS + // client with stale directory listing cache). So we + // try now to explicitly open this commit point32_t: + SegmentInfos sis; + try { + sis.read(directory, segmentInfos->getCurrentSegmentFileName().c_str()); + } catch (CLuceneError& e) { + if ( e.number() == CL_ERR_IO ){ + _CLTHROWA(CL_ERR_CorruptIndex, "failed to locate current segments_N file"); + } + } + if (infoStream != NULL) + message("forced open of current segments file " + segmentInfos->getCurrentSegmentFileName()); + currentCommitPoint = _CLNEW CommitPoint(this,&sis); + commits.push_back(currentCommitPoint); + incRef(&sis, true); + } + + // We keep commits list in sorted order (oldest to newest): + std::sort(commits.begin(), commits.end(), CommitPoint::sort); + + // Now delete anything with ref count at 0. These are + // presumably abandoned files eg due to crash of + // IndexWriter. + RefCountsType::iterator it = refCounts.begin(); + while(it != refCounts.end()) { + char* fileName = it->first; + RefCount* rc = it->second; + if (0 == rc->count) { + if (infoStream != NULL) { + message( string("init: removing unreferenced file \"") + fileName + "\""); + } + deleteFile(fileName); + } + it++; + } + + // Finally, give policy a chance to remove things on + // startup: + policy->onInit(commits); + + // It's OK for the onInit to remove the current commit + // point; we just have to checkpoint our in-memory + // SegmentInfos to protect those files that it uses: + if (currentCommitPoint->deleted) { + checkpoint(segmentInfos, false); + } + + deleteCommits(); +} + +/** +* Remove the CommitPoints in the commitsToDelete List by +* DecRef'ing all files from each segmentInfos-> +*/ +void IndexFileDeleter::deleteCommits() { + + int32_t size = commitsToDelete.size(); + + if (size > 0) { + + // First decref all files that had been referred to by + // the now-deleted commits: + for(int32_t i=0;igetSegmentsFileName() + "\""); + } + decRef(commit->files); + } + commitsToDelete.clear(); + + // Now compact commits to remove deleted ones (preserving the sort): + size = commits.size(); + int32_t readFrom = 0; + int32_t writeTo = 0; + while(readFrom < size) { + CommitPoint* commit = (CommitPoint*)commits[readFrom]; + if (!commit->deleted) { + if (writeTo != readFrom) { + commits.remove(readFrom,true); + commits.remove(writeTo,false);//delete this one... + if ( commits.size() == writeTo ) + commits.push_back(commit); + else + commits[writeTo] = commit; + } + writeTo++; + } + readFrom++; + } + + while(size > writeTo) { + commits.remove(size-1); + size--; + } + } +} + +/** +* Writer calls this when it has hit an error and had to +* roll back, to tell us that there may now be +* unreferenced files in the filesystem. So we re-list +* the filesystem and delete such files. If segmentName +* is non-NULL, we will only delete files corresponding to +* that segment. +*/ +void IndexFileDeleter::refresh(const char* segmentName) { + vector files; + if ( !directory->list(files) ) + _CLTHROWA(CL_ERR_IO, (string("cannot read directory ") + directory->toString() + ": list() returned NULL").c_str() ); + const IndexFileNameFilter* filter = IndexFileNameFilter::getFilter(); + string segmentPrefix1; + string segmentPrefix2; + if (segmentName != NULL) { + segmentPrefix1 = string(segmentName) + "."; + segmentPrefix2 = string(segmentName) + "_"; + } + + for(size_t i=0;iaccept(NULL, fileName.c_str()) && + ( (segmentName==NULL || fileName.compare(0,segmentPrefix1.length(),segmentPrefix1) == 0 || fileName.compare(0,segmentPrefix2.length(),segmentPrefix2)==0) + && refCounts.find((char*)fileName.c_str())== refCounts.end() && fileName.compare(IndexFileNames::SEGMENTS_GEN)!=0) ){ + + // Unreferenced file, so remove it + if (infoStream != NULL) { + message( string("refresh [prefix=") + segmentName + "]: removing newly created unreferenced file \"" + fileName + "\""); + } + deleteFile(fileName.c_str()); + } + } +} + +void IndexFileDeleter::refresh() { + refresh(NULL); +} + +void IndexFileDeleter::close() { + deletePendingFiles(); +} + +void IndexFileDeleter::deletePendingFiles() { + if (!deletable.empty()) { + vector oldDeletable; + oldDeletable.insert(oldDeletable.end(),deletable.begin(),deletable.end()); + deletable.clear(); + + int32_t size = oldDeletable.size(); + for(int32_t i=0;igetCurrentSegmentFileName() + "\" [" + + Misc::toString(segmentInfos->size()) + " segments ; isCommit = " + Misc::toString(isCommit) + "]"); + } + + // Try again now to delete any previously un-deletable + // files (because they were in use, on Windows): + deletePendingFiles(); + + // Incref the files: + incRef(segmentInfos, isCommit); + const vector* docWriterFiles = NULL; + if (docWriter != NULL) { + docWriterFiles = &docWriter->files(); + if (!docWriterFiles->empty()) + incRef(*docWriterFiles); + else + docWriterFiles = NULL; + } + + if (isCommit) { + // Append to our commits list: + commits.push_back(_CLNEW CommitPoint(this, segmentInfos)); + + // Tell policy so it can remove commits: + policy->onCommit(commits); + + // Decref files for commits that were deleted by the policy: + deleteCommits(); + } + + // DecRef old files from the last checkpoint, if any: + int32_t size = lastFiles.size(); + if (size > 0) { + for(int32_t i=0;isize(); + for(int32_t i=0;iinfo(i); + if (segmentInfo->dir == directory) { + const vector& files = segmentInfo->files(); + lastFiles.insert(lastFiles.end(), files.begin(), files.end()); + } + } + } + if (docWriterFiles != NULL) + lastFiles.insert(lastFiles.end(), docWriterFiles->begin(),docWriterFiles->end()); +} + +void IndexFileDeleter::incRef(SegmentInfos* segmentInfos, bool isCommit) { + int32_t size = segmentInfos->size(); + for(int32_t i=0;iinfo(i); + if (segmentInfo->dir == directory) { + incRef(segmentInfo->files()); + } + } + + if (isCommit) { + // Since this is a commit point32_t, also incref its + // segments_N file: + getRefCount(segmentInfos->getCurrentSegmentFileName().c_str())->IncRef(); + } +} + +void IndexFileDeleter::incRef(const vector& files) { + int32_t size = files.size(); + for(int32_t i=0;icount)); + } + rc->IncRef(); + } +} + +void IndexFileDeleter::decRef(const vector& files) { + int32_t size = files.size(); + for(int32_t i=0;icount)); + } + if (0 == rc->DecRef()) { + // This file is no int32_t64_ter referenced by any past + // commit point32_ts nor by the in-memory SegmentInfos: + deleteFile(fileName.c_str()); + refCounts.remove((char*)fileName.c_str()); + } +} + +void IndexFileDeleter::decRef(SegmentInfos* segmentInfos) { + int32_t size = segmentInfos->size(); + for(int32_t i=0;iinfo(i); + if (segmentInfo->dir == directory) { + decRef(segmentInfo->files()); + } + } +} + +IndexFileDeleter::RefCount* IndexFileDeleter::getRefCount(const char* fileName) { + RefCount* rc; + RefCountsType::iterator itr = refCounts.find((char*)fileName); + if (itr == refCounts.end()) { + rc = _CLNEW RefCount(); + refCounts.put( STRDUP_AtoA(fileName), rc); + } else { + rc = itr->second; + } + return rc; +} + +void IndexFileDeleter::deleteFiles(vector& files) { + int32_t size = files.size(); + for(int32_t i=0;i& files) { + int32_t size = files.size(); + for(int32_t i=0;ideleteFile(fileName); + } catch (CLuceneError& e) { // if delete fails + if ( e.number() != CL_ERR_IO ){ + throw e; + } + if (directory->fileExists(fileName)) { + + // Some operating systems (e.g. Windows) don't + // permit a file to be deleted while it is opened + // for read (e.g. by another process or thread). So + // we assume that when a delete fails it is because + // the file is open in another process, and queue + // the file for subsequent deletion. + + if (infoStream != NULL) { + message(string("IndexFileDeleter: unable to remove file \"") + fileName + "\": " + e.what() + "; Will re-try later."); + } + deletable.push_back(fileName); // add to deletable + } + } +} + +CL_NS_END diff --git a/src/core/CLucene/index/IndexFileNameFilter.cpp b/src/core/CLucene/index/IndexFileNameFilter.cpp new file mode 100644 index 00000000000..6dec143e3bc --- /dev/null +++ b/src/core/CLucene/index/IndexFileNameFilter.cpp @@ -0,0 +1,84 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_IndexFileNameFilter.h" +#include "_IndexFileNames.h" + +CL_NS_DEF(index) + +FilenameFilter::~FilenameFilter(){ +} + +IndexFileNameFilter* IndexFileNameFilter::_singleton = NULL; +IndexFileNameFilter* IndexFileNameFilter::singleton(){ + if ( _singleton == NULL ) + _singleton = _CLNEW IndexFileNameFilter(); + return _singleton; +} + +void IndexFileNameFilter::_shutdown(){ + _CLDELETE(_singleton); +} + +IndexFileNameFilter::IndexFileNameFilter() { + size_t i; + for ( i = 0; i < IndexFileNames::INDEX_EXTENSIONS().length; ++i) { + extensions.insert(IndexFileNames::INDEX_EXTENSIONS()[i]); + } + for ( i = 0; i < IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE().length; ++i) { + extensionsInCFS.insert(IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE()[i]); + } +} +IndexFileNameFilter::~IndexFileNameFilter(){ +} +bool IndexFileNameFilter::accept(const char* /*dir*/, const char* name) const { + string _name(name); + size_t i = _name.find_last_of('.'); + if (i != string::npos) { + const char* extension = name + 1 + i; + char* tmp; + if (extensions.find(extension) != extensions.end()) { + return true; + } + + size_t l = _name.length(); + if (*extension == 'f' && + strtol(extension+1, &tmp,10)>= 0 && tmp == (extension+l) ) { //check for f001 + return true; + } else if (*extension == 's' && + strtol(extension+1, &tmp,10)>= 0 && tmp == (extension+l)) { + return true; + } + } else { + if ( strcmp(name, IndexFileNames::DELETABLE) == 0 ) return true; + else if ( strncmp(name, IndexFileNames::SEGMENTS, strlen(IndexFileNames::SEGMENTS)) == 0 ) return true; + } + return false; +} + +bool IndexFileNameFilter::isCFSFile(const char* name) const { + string _name(name); + size_t i = _name.find_last_of('.'); + if (i != string::npos) { + const char* extension = name + 1 + i; + char* tmp; + if (extensionsInCFS.find(extension) != extensionsInCFS.end() ) { + return true; + } + size_t l = _name.length(); + if (*extension == 'f' && + strtol(extension+1, &tmp,10)>= 0 && tmp == (extension+l)) { + return true; + } + } + return false; +} + +const IndexFileNameFilter* IndexFileNameFilter::getFilter() { + return singleton(); +} +CL_NS_END diff --git a/src/core/CLucene/index/IndexFileNames.cpp b/src/core/CLucene/index/IndexFileNames.cpp new file mode 100644 index 00000000000..4217240aa5b --- /dev/null +++ b/src/core/CLucene/index/IndexFileNames.cpp @@ -0,0 +1,179 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "_IndexFileNames.h" +#include "_SegmentInfos.h" +#include "CLucene/util/Misc.h" + + +CL_NS_DEF(index) + + const char* IndexFileNames::SEGMENTS = "segments"; + const char* IndexFileNames::SEGMENTS_GEN = "segments.gen"; + const char* IndexFileNames::DELETABLE = "deletable"; + const char* IndexFileNames::NORMS_EXTENSION = "nrm"; + const char* IndexFileNames::FREQ_EXTENSION = "frq"; + const char* IndexFileNames::PROX_EXTENSION = "prx"; + const char* IndexFileNames::TERMS_EXTENSION = "tis"; + const char* IndexFileNames::TERMS_INDEX_EXTENSION = "tii"; + const char* IndexFileNames::FIELDS_INDEX_EXTENSION = "fdx"; + const char* IndexFileNames::FIELDS_EXTENSION = "fdt"; + const char* IndexFileNames::VECTORS_FIELDS_EXTENSION = "tvf"; + const char* IndexFileNames::VECTORS_DOCUMENTS_EXTENSION = "tvd"; + const char* IndexFileNames::VECTORS_INDEX_EXTENSION = "tvx"; + const char* IndexFileNames::COMPOUND_FILE_EXTENSION = "cfs"; + const char* IndexFileNames::COMPOUND_FILE_STORE_EXTENSION = "cfx"; + const char* IndexFileNames::DELETES_EXTENSION = "del"; + const char* IndexFileNames::FIELD_INFOS_EXTENSION = "fnm"; + const char* IndexFileNames::PLAIN_NORMS_EXTENSION = "f"; + const char* IndexFileNames::SEPARATE_NORMS_EXTENSION = "s"; + const char* IndexFileNames::GEN_EXTENSION = "gen"; + + const char* IndexFileNames_INDEX_EXTENSIONS_s[] = + { + IndexFileNames::COMPOUND_FILE_EXTENSION, + IndexFileNames::FIELD_INFOS_EXTENSION, + IndexFileNames::FIELDS_INDEX_EXTENSION, + IndexFileNames::FIELDS_EXTENSION, + IndexFileNames::TERMS_INDEX_EXTENSION, + IndexFileNames::TERMS_EXTENSION, + IndexFileNames::FREQ_EXTENSION, + IndexFileNames::PROX_EXTENSION, + IndexFileNames::DELETES_EXTENSION, + IndexFileNames::VECTORS_INDEX_EXTENSION, + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION, + IndexFileNames::VECTORS_FIELDS_EXTENSION, + IndexFileNames::GEN_EXTENSION, + IndexFileNames::NORMS_EXTENSION, + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION + }; + + CL_NS(util)::ConstValueArray IndexFileNames::_INDEX_EXTENSIONS; + CL_NS(util)::ConstValueArray& IndexFileNames::INDEX_EXTENSIONS(){ + if ( _INDEX_EXTENSIONS.length == 0 ){ + _INDEX_EXTENSIONS.values = IndexFileNames_INDEX_EXTENSIONS_s; + _INDEX_EXTENSIONS.length = 15; + } + return _INDEX_EXTENSIONS; + } + + const char* IndexFileNames_INDEX_EXTENSIONS_IN_COMPOUND_FILE_s[] = { + IndexFileNames::FIELD_INFOS_EXTENSION, + IndexFileNames::FIELDS_INDEX_EXTENSION, + IndexFileNames::FIELDS_EXTENSION, + IndexFileNames::TERMS_INDEX_EXTENSION, + IndexFileNames::TERMS_EXTENSION, + IndexFileNames::FREQ_EXTENSION, + IndexFileNames::PROX_EXTENSION, + IndexFileNames::VECTORS_INDEX_EXTENSION, + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION, + IndexFileNames::VECTORS_FIELDS_EXTENSION, + IndexFileNames::NORMS_EXTENSION + }; + CL_NS(util)::ConstValueArray IndexFileNames::_INDEX_EXTENSIONS_IN_COMPOUND_FILE; + CL_NS(util)::ConstValueArray& IndexFileNames::INDEX_EXTENSIONS_IN_COMPOUND_FILE(){ + if ( _INDEX_EXTENSIONS_IN_COMPOUND_FILE.length == 0 ){ + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.values = IndexFileNames_INDEX_EXTENSIONS_IN_COMPOUND_FILE_s; + _INDEX_EXTENSIONS_IN_COMPOUND_FILE.length = 11; + } + return _INDEX_EXTENSIONS_IN_COMPOUND_FILE; + } + + const char* IndexFileNames_STORE_INDEX_EXTENSIONS_s[] = { + IndexFileNames::VECTORS_INDEX_EXTENSION, + IndexFileNames::VECTORS_FIELDS_EXTENSION, + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION, + IndexFileNames::FIELDS_INDEX_EXTENSION, + IndexFileNames::FIELDS_EXTENSION + }; + CL_NS(util)::ConstValueArray IndexFileNames::_STORE_INDEX_EXTENSIONS; + CL_NS(util)::ConstValueArray& IndexFileNames::STORE_INDEX_EXTENSIONS(){ + if ( _STORE_INDEX_EXTENSIONS.length == 0 ){ + _STORE_INDEX_EXTENSIONS.values = IndexFileNames_STORE_INDEX_EXTENSIONS_s; + _STORE_INDEX_EXTENSIONS.length = 5; + } + return _STORE_INDEX_EXTENSIONS; + } + + const char* IndexFileNames_NON_STORE_INDEX_EXTENSIONS_s[] = { + IndexFileNames::FIELD_INFOS_EXTENSION, + IndexFileNames::FREQ_EXTENSION, + IndexFileNames::PROX_EXTENSION, + IndexFileNames::TERMS_EXTENSION, + IndexFileNames::TERMS_INDEX_EXTENSION, + IndexFileNames::NORMS_EXTENSION + }; + CL_NS(util)::ConstValueArray IndexFileNames::_NON_STORE_INDEX_EXTENSIONS; + CL_NS(util)::ConstValueArray& IndexFileNames::NON_STORE_INDEX_EXTENSIONS(){ + if ( _NON_STORE_INDEX_EXTENSIONS.length == 0 ){ + _NON_STORE_INDEX_EXTENSIONS.values = IndexFileNames_NON_STORE_INDEX_EXTENSIONS_s; + _NON_STORE_INDEX_EXTENSIONS.length = 6; + } + return _NON_STORE_INDEX_EXTENSIONS; + } + + const char* IndexFileNames_COMPOUND_EXTENSIONS_s[] = { + IndexFileNames::FIELD_INFOS_EXTENSION, + IndexFileNames::FREQ_EXTENSION, + IndexFileNames::PROX_EXTENSION, + IndexFileNames::FIELDS_INDEX_EXTENSION, + IndexFileNames::FIELDS_EXTENSION, + IndexFileNames::TERMS_INDEX_EXTENSION, + IndexFileNames::TERMS_EXTENSION + }; + CL_NS(util)::ConstValueArray IndexFileNames::_COMPOUND_EXTENSIONS; + CL_NS(util)::ConstValueArray& IndexFileNames::COMPOUND_EXTENSIONS(){ + if ( _COMPOUND_EXTENSIONS.length == 0 ){ + _COMPOUND_EXTENSIONS.values = IndexFileNames_COMPOUND_EXTENSIONS_s; + _COMPOUND_EXTENSIONS.length = 7; + } + return _COMPOUND_EXTENSIONS; + } + + const char* IndexFileNames_VECTOR_EXTENSIONS_s[] = { + IndexFileNames::VECTORS_INDEX_EXTENSION, + IndexFileNames::VECTORS_DOCUMENTS_EXTENSION, + IndexFileNames::VECTORS_FIELDS_EXTENSION + }; + CL_NS(util)::ConstValueArray IndexFileNames::_VECTOR_EXTENSIONS; + CL_NS(util)::ConstValueArray& IndexFileNames::VECTOR_EXTENSIONS(){ + if ( _VECTOR_EXTENSIONS.length == 0 ){ + _VECTOR_EXTENSIONS.values = IndexFileNames_VECTOR_EXTENSIONS_s; + _VECTOR_EXTENSIONS.length = 3; + } + return _VECTOR_EXTENSIONS; + } + + string IndexFileNames::fileNameFromGeneration( const char* base, const char* extension, int64_t gen ) { + if ( gen == SegmentInfo::NO ) { + return ""; + } else if ( gen == SegmentInfo::WITHOUT_GEN ) { + return string(base) + extension; + } else { + char buf[(sizeof(unsigned long) << 3) + 1]; + CL_NS(util)::Misc::longToBase( gen, 36, buf ); + return string(base) + "_" + buf + extension; + } + } + + bool IndexFileNames::isDocStoreFile( const char* fileName ) { + + const char* p = strchr( fileName, (int)'.' ); + + if ( p != NULL && strcmp( p+1, COMPOUND_FILE_STORE_EXTENSION ) == 0 ) { + return true; + } + for ( int32_t i = 0; i < STORE_INDEX_EXTENSIONS().length; i++ ) { + if ( p != NULL && strcmp( p+1, STORE_INDEX_EXTENSIONS()[i] ) == 0 ) { + return true; + } + } + return false; + } + +CL_NS_END diff --git a/src/core/CLucene/index/IndexModifier.cpp b/src/core/CLucene/index/IndexModifier.cpp new file mode 100644 index 00000000000..83032083414 --- /dev/null +++ b/src/core/CLucene/index/IndexModifier.cpp @@ -0,0 +1,277 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexModifier.h" + +#include "IndexWriter.h" +#include "IndexReader.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/document/Document.h" +#include "MergeScheduler.h" + +CL_NS_DEF(index) +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(analysis) +CL_NS_USE(document) + +IndexModifier::IndexModifier(Directory* directory, Analyzer* analyzer, bool create) { + init(directory, analyzer, create); +} + +IndexModifier::IndexModifier(const char* dirName, Analyzer* analyzer, bool create) { + Directory* dir = FSDirectory::getDirectory(dirName); + init(dir, analyzer, create); +} + +void IndexModifier::init(Directory* directory, Analyzer* analyzer, bool create) { + indexWriter = NULL; + indexReader = NULL; + open = false; + infoStream = NULL; + + useCompoundFile = true; + this->maxBufferedDocs = IndexWriter::DEFAULT_MAX_BUFFERED_DOCS; + this->maxFieldLength = IndexWriter::DEFAULT_MAX_FIELD_LENGTH; + this->mergeFactor = IndexWriter::DEFAULT_MERGE_FACTOR; + + this->directory = _CL_POINTER(directory); + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + this->analyzer = analyzer; + indexWriter = _CLNEW IndexWriter(directory, analyzer, create); + open = true; +} + +IndexModifier::~IndexModifier(){ + if (open) { + close(); + } +} + +void IndexModifier::assureOpen() const{ + if (!open) { + _CLTHROWA(CL_ERR_IllegalState,"Index is closed"); + } +} + +void IndexModifier::createIndexWriter(bool create) { + if (indexWriter == NULL) { + if (indexReader != NULL) { + indexReader->close(); + _CLDELETE(indexReader); + } + + indexWriter = _CLNEW IndexWriter(directory, analyzer, false); + // IndexModifier cannot use ConcurrentMergeScheduler + // because it synchronizes on the directory which can + // cause deadlock + indexWriter->setMergeScheduler(_CLNEW SerialMergeScheduler()); + indexWriter->setInfoStream(infoStream); + indexWriter->setUseCompoundFile(useCompoundFile); + if (maxBufferedDocs != IndexWriter::DISABLE_AUTO_FLUSH) + indexWriter->setMaxBufferedDocs(maxBufferedDocs); + indexWriter->setMaxFieldLength(maxFieldLength); + indexWriter->setMergeFactor(mergeFactor); + } +} + +void IndexModifier::createIndexReader() { + if (indexReader == NULL) { + if (indexWriter != NULL) { + indexWriter->close(); + _CLDELETE(indexWriter); + } + indexReader = IndexReader::open(directory); + } +} + +void IndexModifier::flush() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) { + indexWriter->close(); + _CLDELETE(indexWriter); + createIndexWriter(); + } else { + indexReader->close(); + _CLDELETE(indexReader); + createIndexReader(); + } +} + +void IndexModifier::addDocument(Document* doc, Analyzer* docAnalyzer) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + if (docAnalyzer != NULL) + indexWriter->addDocument(doc, docAnalyzer); + else + indexWriter->addDocument(doc); +} + +int32_t IndexModifier::deleteDocuments(Term* term) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + return indexReader->deleteDocuments(term); +} + +void IndexModifier::deleteDocument(int32_t docNum) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + indexReader->deleteDocument(docNum); +} + +int32_t IndexModifier::docCount() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) + return indexWriter->docCount(); + else + return indexReader->numDocs(); +} + +void IndexModifier::optimize() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + indexWriter->optimize(); +} + +void IndexModifier::setUseCompoundFile(bool useCompoundFile) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) + indexWriter->setUseCompoundFile(useCompoundFile); + this->useCompoundFile = useCompoundFile; +} + +bool IndexModifier::getUseCompoundFile() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + return indexWriter->getUseCompoundFile(); +} + +void IndexModifier::setMaxFieldLength(int32_t maxFieldLength) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) + indexWriter->setMaxFieldLength(maxFieldLength); + this->maxFieldLength = maxFieldLength; +} + +int32_t IndexModifier::getMaxFieldLength() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + return indexWriter->getMaxFieldLength(); +} + +void IndexModifier::setMaxBufferedDocs(int32_t maxBufferedDocs) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) + indexWriter->setMaxBufferedDocs(maxBufferedDocs); + this->maxBufferedDocs = maxBufferedDocs; +} + +int32_t IndexModifier::getMaxBufferedDocs() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + return indexWriter->getMaxBufferedDocs(); +} +void IndexModifier::setMergeFactor(int32_t mergeFactor) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + if (indexWriter != NULL) + indexWriter->setMergeFactor(mergeFactor); + this->mergeFactor = mergeFactor; +} + +int32_t IndexModifier::getMergeFactor() { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexWriter(); + return indexWriter->getMergeFactor(); +} + +void IndexModifier::close() { + if (!open) + _CLTHROWA(CL_ERR_IllegalState, "Index is closed already"); + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + if (indexWriter != NULL) { + indexWriter->close(); + _CLDELETE(indexWriter); + } else if (indexReader != NULL) { + indexReader->close(); + _CLDELETE(indexReader); + } + _CLDECDELETE(directory) + open = false; +} + +string IndexModifier::toString() const{ + return string("Index@") + directory->toString(); +} + + + +int64_t IndexModifier::getCurrentVersion() const{ + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + return IndexReader::getCurrentVersion(directory); +} + +TermDocs* IndexModifier::termDocs(Term* term){ + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + return indexReader->termDocs(term); +} + +TermEnum* IndexModifier::terms(Term* term){ + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + if ( term != NULL ) + return indexReader->terms(term); + else + return indexReader->terms(); +} + + + CL_NS(document)::Document* IndexModifier::document(const int32_t n){ + Document* ret = _CLNEW Document; + if (!document(n, *ret) ) + _CLDELETE(ret); + return ret; + } +bool IndexModifier::document(int32_t n, CL_NS(document)::Document* doc){ + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + return indexReader->document(n, *doc); +} +bool IndexModifier::document(int32_t n, CL_NS(document)::Document& doc){ + SCOPED_LOCK_MUTEX(directory->THIS_LOCK) + assureOpen(); + createIndexReader(); + return indexReader->document(n, doc); +} +CL_NS(store)::Directory* IndexModifier::getDirectory(){ + return directory; +} + +CL_NS_END diff --git a/src/core/CLucene/index/IndexModifier.h b/src/core/CLucene/index/IndexModifier.h new file mode 100644 index 00000000000..d6429bf06b3 --- /dev/null +++ b/src/core/CLucene/index/IndexModifier.h @@ -0,0 +1,332 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_IndexModifier_ +#define _lucene_index_IndexModifier_ + + +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(index, IndexWriter) +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF(index, Term) +CL_CLASS_DEF(index, TermDocs) +CL_CLASS_DEF(index, TermEnum) + +#include "CLucene/analysis/AnalysisHeader.h" + +CL_NS_DEF(index) + +/** +*

[Note that as of 2.1, all but one of the +* methods in this class are available via {@link +* IndexWriter}. The one method that is not available is +* {@link #deleteDocument(int)}.]

+* +* A class to modify an index, i.e. to delete and add documents. This +* class hides {@link IndexReader} and {@link IndexWriter} so that you +* do not need to care about implementation details such as that adding +* documents is done via IndexWriter and deletion is done via IndexReader. +* +*

Note that you cannot create more than one IndexModifier object +* on the same directory at the same time. +* +*

Example usage: +* +*

+* +* +* +* +*
+* +* //note this code will leak memory :) +* Analyzer* analyzer = new StandardAnalyzer();
+* // create an index in /tmp/index, overwriting an existing one:
+* IndexModifier* indexModifier = new IndexModifier("/tmp/index", analyzer, true);
+* Document* doc = new Document*();
+* doc->add(*new Field("id", "1", Field::STORE_YES| Field::INDEX_UNTOKENIZED));
+* doc->add(*new Field("body", "a simple test", Field::STORE_YES, Field::INDEX_TOKENIZED));
+* indexModifier->addDocument(doc);
+* int32_t deleted = indexModifier->deleteDocuments(new Term("id", "1"));
+* printf("Deleted %d document", deleted);
+* indexModifier->flush();
+* printf( "$d docs in index", indexModifier->docCount() );
+* indexModifier->close(); +*
+*
+* +*

Not all methods of IndexReader and IndexWriter are offered by this +* class. If you need access to additional methods, either use those classes +* directly or implement your own class that extends IndexModifier. +* +*

Although an instance of this class can be used from more than one +* thread, you will not get the best performance. You might want to use +* IndexReader and IndexWriter directly for that (but you will need to +* care about synchronization yourself then). +* +*

While you can freely mix calls to add() and delete() using this class, +* you should batch you calls for best performance. For example, if you +* want to update 20 documents, you should first delete all those documents, +* then add all the new documents. +* +* @deprecated Please use {@link IndexWriter} instead. +*/ +class CLUCENE_EXPORT IndexModifier { +protected: + IndexWriter* indexWriter; + IndexReader* indexReader; + + CL_NS(store)::Directory* directory; + CL_NS(analysis)::Analyzer* analyzer; + bool open; + + // Lucene defaults: + std::ostream* infoStream; + bool useCompoundFile; + int32_t maxBufferedDocs; + int32_t maxFieldLength; + int32_t mergeFactor; + +public: + + /** + * Open an index with write access. + * + * @param directory the index directory + * @param analyzer the analyzer to use for adding new documents + * @param create true to create the index or overwrite the existing one; + * false to append to the existing index + */ + IndexModifier(CL_NS(store)::Directory* directory, CL_NS(analysis)::Analyzer* analyzer, bool create); + + /** + * Open an index with write access. + * + * @param dirName the index directory + * @param analyzer the analyzer to use for adding new documents + * @param create true to create the index or overwrite the existing one; + * false to append to the existing index + */ + IndexModifier(const char* dirName, CL_NS(analysis)::Analyzer* analyzer, bool create); + + virtual ~IndexModifier(); + +protected: + + /** + * Initialize an IndexWriter. + * @throws IOException + */ + void init(CL_NS(store)::Directory* directory, CL_NS(analysis)::Analyzer* analyzer, bool create); + + /** + * Throw an IllegalStateException if the index is closed. + * @throws IllegalStateException + */ + void assureOpen() const; + + /** + * Close the IndexReader and open an IndexWriter. + * @throws IOException + */ + void createIndexWriter(bool create = false); + + /** + * Close the IndexWriter and open an IndexReader. + * @throws IOException + */ + void createIndexReader(); + +public: + /** + * Make sure all changes are written to disk. + * @throws IOException + */ + void flush(); + + /** + * Adds a document to this index, using the provided analyzer instead of the + * one specific in the constructor. If the document contains more than + * {@link #setMaxFieldLength(int32_t)} terms for a given field, the remainder are + * discarded. + * @see IndexWriter#addDocument(Document*, Analyzer*) + * @throws IllegalStateException if the index is closed + */ + void addDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* docAnalyzer=NULL); + + + /** + * Deletes all documents containing term. + * This is useful if one uses a document field to hold a unique ID string for + * the document. Then to delete such a document, one merely constructs a + * term with the appropriate field and the unique ID string as its text and + * passes it to this method. Returns the number of documents deleted. + * @return the number of documents deleted + * @see IndexReader#deleteDocuments(Term*) + * @throws IllegalStateException if the index is closed + */ + int32_t deleteDocuments(Term* term); + + /** + * Deletes the document numbered docNum. + * @see IndexReader#deleteDocument(int32_t) + * @throws IllegalStateException if the index is closed + */ + void deleteDocument(int32_t docNum); + + /** + * Returns the number of documents currently in this index. + * @see IndexWriter#docCount() + * @see IndexReader#numDocs() + * @throws IllegalStateException if the index is closed + */ + int32_t docCount(); + + /** + * Merges all segments together into a single segment, optimizing an index + * for search. + * @see IndexWriter#optimize() + * @throws IllegalStateException if the index is closed + */ + void optimize(); + + /** + * Setting to turn on usage of a compound file. When on, multiple files + * for each segment are merged into a single file once the segment creation + * is finished. This is done regardless of what directory is in use. + * @see IndexWriter#setUseCompoundFile(bool) + * @throws IllegalStateException if the index is closed + */ + void setUseCompoundFile(bool useCompoundFile); + + /** + * @throws IOException + * @see IndexModifier#setUseCompoundFile(bool) + */ + bool getUseCompoundFile(); + + /** + * The maximum number of terms that will be indexed for a single field in a + * document. This limits the amount of memory required for indexing, so that + * collections with very large files will not crash the indexing process by + * running out of memory.

+ * Note that this effectively truncates large documents, excluding from the + * index terms that occur further in the document. If you know your source + * documents are large, be sure to set this value high enough to accomodate + * the expected size. If you set it to Integer.MAX_VALUE, then the only limit + * is your memory, but you should anticipate an OutOfMemoryError.

+ * By default, no more than 10,000 terms will be indexed for a field. + * @see IndexWriter#setMaxFieldLength(int32_t) + * @throws IllegalStateException if the index is closed + */ + void setMaxFieldLength(int32_t maxFieldLength); + + /** + * @throws IOException + * @see IndexModifier#setMaxFieldLength(int32_t) + */ + int32_t getMaxFieldLength(); + + /** + * The maximum number of terms that will be indexed for a single field in a + * document. This limits the amount of memory required for indexing, so that + * collections with very large files will not crash the indexing process by + * running out of memory.

+ * Note that this effectively truncates large documents, excluding from the + * index terms that occur further in the document. If you know your source + * documents are large, be sure to set this value high enough to accomodate + * the expected size. If you set it to Integer.MAX_VALUE, then the only limit + * is your memory, but you should anticipate an OutOfMemoryError.

+ * By default, no more than 10,000 terms will be indexed for a field. + * @see IndexWriter#setMaxBufferedDocs(int32_t) + * @throws IllegalStateException if the index is closed + */ + void setMaxBufferedDocs(int32_t maxBufferedDocs); + + /** + * @throws IOException + * @see IndexModifier#setMaxBufferedDocs(int32_t) + */ + int32_t getMaxBufferedDocs(); + + /** + * Determines how often segment indices are merged by addDocument(). With + * smaller values, less RAM is used while indexing, and searches on + * unoptimized indices are faster, but indexing speed is slower. With larger + * values, more RAM is used during indexing, and while searches on unoptimized + * indices are slower, indexing is faster. Thus larger values (> 10) are best + * for batch index creation, and smaller values (< 10) for indices that are + * interactively maintained. + *

This must never be less than 2. The default value is 10. + * + * @see IndexWriter#setMergeFactor(int32_t) + * @throws IllegalStateException if the index is closed + */ + void setMergeFactor(int32_t mergeFactor); + + /** + * @throws IOException + * @see IndexModifier#setMergeFactor(int32_t) + */ + int32_t getMergeFactor(); + + /** + * Close this index, writing all pending changes to disk. + * + * @throws IllegalStateException if the index has been closed before already + */ + void close(); + + std::string toString() const; + + /** + * Gets the version number of the currently open index. + */ + int64_t getCurrentVersion() const; + + /** + * Returns an enumeration of all the documents which contain term. + * + * Warning: This is not threadsafe. Make sure you lock the modifier object + * while using the TermDocs. If the IndexReader that the modifier manages + * is closed, the TermDocs object will fail. + */ + TermDocs* termDocs(Term* term=NULL); + + /** + * Returns an enumeration of all terms after a given term. + * If no term is given, an enumeration of all the terms + * in the index is returned. + * The enumeration is ordered by Term.compareTo(). Each term + * is greater than all that precede it in the enumeration. + * + * Warning: This is not threadsafe. Make sure you lock the modifier object + * while using the TermDocs. If the IndexReader that the modifier manages + * is closed, the Document will be invalid + */ + TermEnum* terms(Term* term=NULL); + + /** + * Returns the stored fields of the n-th Document in this index. + * + * Warning: This is not threadsafe. Make sure you lock the modifier object + * while using the TermDocs. If the IndexReader that the modifier manages + * is closed, the Document will be invalid + */ + bool document(const int32_t n, CL_NS(document)::Document& doc); + _CL_DEPRECATED( document(i, Document&) )bool document(const int32_t n, CL_NS(document)::Document* doc); + _CL_DEPRECATED( document(i, document) ) CL_NS(document)::Document* document(const int32_t n); + + /** + * Returns the directory used by this index. + */ + CL_NS(store)::Directory* getDirectory(); +}; +CL_NS_END +#endif + + diff --git a/src/core/CLucene/index/IndexReader.cpp b/src/core/CLucene/index/IndexReader.cpp new file mode 100644 index 00000000000..91ca18ed0e1 --- /dev/null +++ b/src/core/CLucene/index/IndexReader.cpp @@ -0,0 +1,532 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexReader.h" +#include "IndexWriter.h" + +#include "CLucene/store/Directory.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/store/_Lock.h" +#include "CLucene/document/Document.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/Misc.h" +#include "_SegmentInfos.h" +#include "_SegmentHeader.h" +#include "MultiReader.h" +#include "Terms.h" +#include + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_DEF(index) + + + class IndexReaderFindSegmentsFile: public SegmentInfos::FindSegmentsFile{ + public: + IndexReaderFindSegmentsFile( CL_NS(store)::Directory* dir ): + SegmentInfos::FindSegmentsFile(dir){ + } + IndexReaderFindSegmentsFile( const char* dir ): + SegmentInfos::FindSegmentsFile(dir){ + } + uint64_t doBody(const char* segmentFileName){ + return directory->fileModified(segmentFileName); + } + }; + + class CloseCallbackCompare:public CL_NS(util)::Compare::_base{ + public: + bool operator()( IndexReader::CloseCallback t1, IndexReader::CloseCallback t2 ) const{ + return t1 > t2; + } + static void doDelete(IndexReader::CloseCallback /*dummy*/){ + } + }; + + + class IndexReader::Internal: LUCENE_BASE{ + public: + /** + * @deprecated will be deleted when IndexReader(Directory) is deleted + * @see #directory() + */ + CL_NS(store)::Directory* directory; + + typedef CL_NS(util)::CLSet CloseCallbackMap; + CloseCallbackMap closeCallbacks; + + Internal(Directory* directory, IndexReader* _this) + { + if ( directory != NULL ) + this->directory = _CL_POINTER(directory); + else + this->directory = NULL; + _this->closed = false; + _this->hasChanges = false; + } + ~Internal(){ + } + }; + + IndexReader::IndexReader(Directory* dir){ + //Constructor. + //Func - Creates an instance of IndexReader + //Pre - true + //Post - An instance has been created with writeLock = NULL + _internal = _CLNEW Internal(dir, this); + } + + IndexReader::IndexReader(){ + //Constructor. + //Func - Creates an instance of IndexReader + //Pre - true + //Post - An instance has been created with writeLock = NULL + _internal = _CLNEW Internal(NULL, this); + } + + IndexReader::~IndexReader(){ + //Func - Destructor + // Destroys the instance and releases the writeLock if needed + //Pre - true + //Post - The instance has been destroyed if pre(writeLock) exists is has been released + _CLLDELETE(_internal); + } + + IndexReader* IndexReader::open(const char* path, bool closeDirectoryOnCleanup, IndexDeletionPolicy* deletionPolicy){ + //Func - Static method. + // Returns an IndexReader reading the index in an FSDirectory in the named path. + //Pre - path != NULL and contains the path of the index for which an IndexReader must be + // instantiated + // closeDir indicates if the directory needs to be closed + //Post - An IndexReader has been returned that reads tnhe index located at path + + CND_PRECONDITION(path != NULL, "path is NULL"); + Directory* dir = FSDirectory::getDirectory(path); + IndexReader* reader = open(dir,closeDirectoryOnCleanup,deletionPolicy); + //because fsdirectory will now have a refcount of 1 more than + //if the reader had been opened with a directory object, + //we need to do a refdec + _CLDECDELETE(dir); + return reader; + } + + IndexReader* IndexReader::open( Directory* directory, bool closeDirectory, IndexDeletionPolicy* deletionPolicy){ + //Func - Static method. + // Returns an IndexReader reading the index in an FSDirectory in the named path. + //Pre - directory represents a directory + // closeDir indicates if the directory needs to be closed + //Post - An IndexReader has been returned that reads the index located at directory + + return DirectoryIndexReader::open(directory, closeDirectory, deletionPolicy); + } + + IndexReader* IndexReader::reopen(){ + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support reopen()."); + } + CL_NS(store)::Directory* IndexReader::directory() { + ensureOpen(); + if (NULL != _internal->directory) { + return _internal->directory; + } else { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + } + + void IndexReader::ensureOpen(){ + } + + void IndexReader::acquireWriteLock(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + /* NOOP */ + } + + CL_NS(document)::Document* IndexReader::document(const int32_t n){ + CL_NS(document)::Document* ret = _CLNEW CL_NS(document)::Document; + if (!document(n,*ret) ) + _CLDELETE(ret); + return ret; + } + + uint64_t IndexReader::lastModified(const char* directory2) { + //Func - Static method + // Returns the time the index in the named directory was last modified. + //Pre - directory != NULL and contains the path name of the directory to check + //Post - The last modified time of the index has been returned + + CND_PRECONDITION(directory2 != NULL, "directory is NULL"); + + IndexReaderFindSegmentsFile runner(directory2); + return (uint64_t)runner.run(); + } + + int64_t IndexReader::getCurrentVersion(Directory* directory) { + return SegmentInfos::readCurrentVersion(directory); + } + + + int64_t IndexReader::getCurrentVersion(const char* directory){ + Directory* dir = FSDirectory::getDirectory(directory); + int64_t version = getCurrentVersion(dir); + dir->close(); + _CLDECDELETE(dir); + return version; + } + int64_t IndexReader::getVersion() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + + void IndexReader::setTermInfosIndexDivisor(int32_t /*indexDivisor*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + + int32_t IndexReader::getTermInfosIndexDivisor() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + + bool IndexReader::isCurrent() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + bool IndexReader::isOptimized() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "This reader does not support this method."); + } + + uint64_t IndexReader::lastModified(Directory* directory2) { + //Func - Static method + // Returns the time the index in this directory was last modified. + //Pre - directory contains a valid reference + //Post - The last modified time of the index has been returned + IndexReaderFindSegmentsFile runner(directory2); + return (uint64_t)runner.run(); + } + + void IndexReader::setNorm(int32_t doc, const TCHAR* field, uint8_t value){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + this->ensureOpen(); + this->acquireWriteLock(); + this->hasChanges = true; + this->doSetNorm(doc, field, value); + } + + + void IndexReader::setNorm(int32_t doc, const TCHAR* field, float_t value){ + ensureOpen(); + setNorm(doc, field, CL_NS(search)::Similarity::encodeNorm(value)); + } + + bool IndexReader::indexExists(const char* directory){ + //Func - Static method + // Checks if an index exists in the named directory + //Pre - directory != NULL + //Post - Returns true if an index exists at the specified directory-> + // If the directory does not exist or if there is no index in it. + // false is returned. + std::vector files; + Misc::listFiles(directory, files); + return SegmentInfos::getCurrentSegmentGeneration(files) != -1; + } + + bool IndexReader::indexExists(const Directory* directory){ + //Func - Static method + // Checks if an index exists in the directory + //Pre - directory is a valid reference + //Post - Returns true if an index exists at the specified directory-> + // If the directory does not exist or if there is no index in it. + // false is returned. + + return SegmentInfos::getCurrentSegmentGeneration(directory) != -1; + } + + TermDocs* IndexReader::termDocs(Term* term) { + //Func - Returns an enumeration of all the documents which contain + // term. For each document, the document number, the frequency of + // the term in that document is also provided, for use in search scoring. + // Thus, this method implements the mapping: + // + // Term => * + // The enumeration is ordered by document number. Each document number + // is greater than all that precede it in the enumeration. + //Pre - term != NULL + //Post - A reference to TermDocs containing an enumeration of all found documents + // has been returned + + CND_PRECONDITION(term != NULL, "term is NULL"); + + ensureOpen(); + //Reference an instantiated TermDocs instance + TermDocs* _termDocs = termDocs(); + //Seek all documents containing term + _termDocs->seek(term); + //return the enumaration + return _termDocs; + } + + TermPositions* IndexReader::termPositions(Term* term){ + //Func - Returns an enumeration of all the documents which contain term. For each + // document, in addition to the document number and frequency of the term in + // that document, a list of all of the ordinal positions of the term in the document + // is available. Thus, this method implements the mapping: + // + // Term => >* + // + // This positional information faciliates phrase and proximity searching. + // The enumeration is ordered by document number. Each document number is greater than + // all that precede it in the enumeration. + //Pre - term != NULL + //Post - A reference to TermPositions containing an enumeration of all found documents + // has been returned + + CND_PRECONDITION(term != NULL, "term is NULL"); + + ensureOpen(); + //Reference an instantiated termPositions instance + TermPositions* _termPositions = termPositions(); + //Seek all documents containing term + _termPositions->seek(term); + //return the enumeration + return _termPositions; + } + + bool IndexReader::document(int32_t n, CL_NS(document)::Document* doc){ + return document(n, *doc); + } + bool IndexReader::document(int32_t n, CL_NS(document)::Document& doc){ + ensureOpen(); + return document(n, doc, NULL); + } + + void IndexReader::deleteDoc(const int32_t docNum){ + deleteDocument(docNum); + } + int32_t IndexReader::deleteTerm(Term* term){ + return deleteDocuments(term); + } + + void IndexReader::deleteDocument(const int32_t docNum) { + //Func - Deletes the document numbered docNum. Once a document is deleted it will not appear + // in TermDocs or TermPostitions enumerations. Attempts to read its field with the document + // method will result in an error. The presence of this document may still be reflected in + // the docFreq statistic, though this will be corrected eventually as the index is further modified. + //Pre - docNum >= 0 + //Post - If successful the document identified by docNum has been deleted. If no writelock + // could be obtained an exception has been thrown stating that the index was locked or has no write access + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + CND_PRECONDITION(docNum >= 0, "docNum is negative"); + + ensureOpen(); + acquireWriteLock(); + + //Have the document identified by docNum deleted + hasChanges = true; + doDelete(docNum); + } + + void IndexReader::flush() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + commit(); + } + + void IndexReader::commit(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + if(hasChanges){ + doCommit(); + } + hasChanges = false; + } + + + void IndexReader::undeleteAll(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + acquireWriteLock(); + hasChanges = true; + doUndeleteAll(); + } + + int32_t IndexReader::deleteDocuments(Term* term) { + //Func - Deletes all documents containing term. This is useful if one uses a + // document field to hold a unique ID string for the document. Then to delete such + // a document, one merely constructs a term with the appropriate field and the unique + // ID string as its text and passes it to this method. + //Pre - term != NULL + //Post - All documents containing term have been deleted. The number of deleted documents + // has been returned + + CND_PRECONDITION(term != NULL, "term is NULL"); + ensureOpen(); + + //Search for the documents contain term + TermDocs* docs = termDocs(term); + + //Check if documents have been found + if ( docs == NULL ){ + return 0; + } + + //initialize + int32_t Counter = 0; + try { + //iterate through the found documents + while (docs->next()) { + //Delete the document + deleteDocument(docs->doc()); + ++Counter; + } + }_CLFINALLY( + //Close the enumeration + docs->close(); + ); + + //Delete the enumeration of found documents + _CLDELETE( docs ); + + //Return the number of deleted documents + return Counter; + } + + + void IndexReader::close() { + //Func - Closes files associated with this index and also saves any new deletions to disk. + // No other methods should be called after this has been called. + //Pre - true + //Post - All files associated with this index have been deleted and new deletions have been + // saved to disk + SCOPED_LOCK_MUTEX(THIS_LOCK) + if ( !closed ){ + Internal::CloseCallbackMap::iterator iter = _internal->closeCallbacks.begin(); + for ( ;iter!=_internal->closeCallbacks.end();iter++){ + CloseCallback callback = *iter->first; + callback(this,iter->second); + } + commit(); + doClose(); + } + closed = true; + } + + bool IndexReader::isLocked(Directory* directory) { + //Func - Static method + // Checks if the index in the directory is currently locked. + //Pre - directory is a valid reference to a directory to check for a lock + //Post - Returns true if the index in the named directory is locked otherwise false + + //Check the existence of the file write.lock and return true when it does and false + //when it doesn't + LuceneLock* l = directory->makeLock("write.lock"); + bool ret = l->isLocked(); + _CLDELETE(l); + return ret; + } + + bool IndexReader::isLocked(const char* directory) { + //Func - Static method + // Checks if the index in the named directory is currently locked. + //Pre - directory != NULL and contains the directory to check for a lock + //Post - Returns true if the index in the named directory is locked otherwise false + + CND_PRECONDITION(directory != NULL, "directory is NULL"); + + Directory* dir = FSDirectory::getDirectory(directory); + bool ret = isLocked(dir); + dir->close(); + _CLDECDELETE(dir); + + return ret; + } + +bool IndexReader::hasNorms(const TCHAR* field) { + // backward compatible implementation. + // SegmentReader has an efficient implementation. + ensureOpen(); + return norms(field) != NULL; +} + +void IndexReader::unlock(const char* path){ + FSDirectory* dir = FSDirectory::getDirectory(path); + unlock(dir); + dir->close(); + _CLDECDELETE(dir); +} + void IndexReader::unlock(Directory* directory){ + //Func - Static method + // Forcibly unlocks the index in the named directory-> + // Caution: this should only be used by failure recovery code, + // when it is known that no other process nor thread is in fact + // currently accessing this index. + //Pre - directory is a valid reference to a directory + //Post - The directory has been forcibly unlocked + LuceneLock* lock = directory->makeLock("write.lock"); + lock->release(); + _CLDELETE(lock); + } + +bool IndexReader::isLuceneFile(const char* filename){ + if ( !filename ) + return false; + size_t len = strlen(filename); + if ( len < 6 ) //need at least x.frx + return false; + const char* ext=filename+len; + while(*ext != '.' && ext!=filename) + ext--; + + if ( strcmp(ext, ".cfs") == 0 ) + return true; + else if ( strcmp(ext, ".fnm") == 0 ) + return true; + else if ( strcmp(ext, ".fdx") == 0 ) + return true; + else if ( strcmp(ext, ".fdt") == 0 ) + return true; + else if ( strcmp(ext, ".tii") == 0 ) + return true; + else if ( strcmp(ext, ".tis") == 0 ) + return true; + else if ( strcmp(ext, ".frq") == 0 ) + return true; + else if ( strcmp(ext, ".prx") == 0 ) + return true; + else if ( strcmp(ext, ".del") == 0 ) + return true; + else if ( strcmp(ext, ".tvx") == 0 ) + return true; + else if ( strcmp(ext, ".tvd") == 0 ) + return true; + else if ( strcmp(ext, ".tvf") == 0 ) + return true; + else if ( strcmp(ext, ".tvp") == 0 ) + return true; + + else if ( strcmp(filename, "segments") == 0 ) + return true; + else if ( strcmp(filename, "segments.new") == 0 ) + return true; + else if ( strcmp(filename, "deletable") == 0 ) + return true; + + else if ( strncmp(ext,".f",2)==0 ){ + const char* n = ext+2; + if ( *n && _istdigit(*n) ) + return true; + } + + return false; +} + +CL_NS(store)::Directory* IndexReader::getDirectory() { + return directory(); +} + + void IndexReader::addCloseCallback(CloseCallback callback, void* parameter){ + _internal->closeCallbacks.put(callback, parameter); + } + +CL_NS_END diff --git a/src/core/CLucene/index/IndexReader.h b/src/core/CLucene/index/IndexReader.h new file mode 100644 index 00000000000..9079025a5f3 --- /dev/null +++ b/src/core/CLucene/index/IndexReader.h @@ -0,0 +1,688 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_IndexReader_ +#define _lucene_index_IndexReader_ + + +#include "CLucene/util/Array.h" +#include "CLucene/util/VoidList.h" +#include "CLucene/LuceneThreads.h" + +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(store,LuceneLock) +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(document,FieldSelector) + +CL_NS_DEF(index) +class SegmentInfos; +class TermFreqVector; +class TermEnum; +class Term; +class TermDocs; +class TermPositions; +class IndexDeletionPolicy; +class TermVectorMapper; + +/** IndexReader is an abstract class, providing an interface for accessing an + index. Search of an index is done entirely through this abstract interface, + so that any subclass which implements it is searchable. + +

Concrete subclasses of IndexReader are usually constructed with a call to + one of the static open() methods, e.g. {@link #open(String)}. + +

For efficiency, in this API documents are often referred to via + document numbers, non-negative integers which each name a unique + document in the index. These document numbers are ephemeral--they may change + as documents are added to and deleted from an index. Clients should thus not + rely on a given document having the same number between sessions. + +

An IndexReader can be opened on a directory for which an IndexWriter is + opened already, but it cannot be used to delete documents from the index then. + +

+ NOTE: for backwards API compatibility, several methods are not listed + as abstract, but have no useful implementations in this base class and + instead always throw UnsupportedOperationException. Subclasses are + strongly encouraged to override these methods, but in many cases may not + need to. +

+ +*/ +class CLUCENE_EXPORT IndexReader: public CL_NS(util)::NamedObject{ + bool closed; +protected: + bool hasChanges; + + /** + * Legacy Constructor for backwards compatibility. + * + *

+ * This Constructor should not be used, it exists for backwards + * compatibility only to support legacy subclasses that did not "own" + * a specific directory, but needed to specify something to be returned + * by the directory() method. Future subclasses should delegate to the + * no arg constructor and implement the directory() method as appropriate. + * + * @param directory Directory to be returned by the directory() method + * @see #directory() + * @deprecated - use IndexReader() + */ + IndexReader(CL_NS(store)::Directory* dir); + + IndexReader(); + + /// Implements close. + virtual void doClose() = 0; + + /** Implements setNorm in subclass.*/ + virtual void doSetNorm(int32_t doc, const TCHAR* field, uint8_t value) = 0; + + /** Implements actual undeleteAll() in subclass. */ + virtual void doUndeleteAll() = 0; + + /** Implements deletion of the document numbered docNum. + * Applications should call {@link #deleteDocument(int32_t)} or {@link #deleteDocuments(Term*)}. + */ + virtual void doDelete(const int32_t docNum) = 0; + + /** + * @throws AlreadyClosedException if this IndexReader is closed + */ + virtual void ensureOpen(); + + /** Does nothing by default. Subclasses that require a write lock for + * index modifications must implement this method. */ + virtual void acquireWriteLock(); + +public: + //Callback for classes that need to know if IndexReader is closing. + typedef void (*CloseCallback)(IndexReader*, void*); + + /** Internal use. Implements commit */ + virtual void doCommit() = 0; + /** Internal use. */ + class Internal; + /** Internal use. */ + Internal* _internal; + + + /** + * Constants describing field properties, for example used for + * {@link IndexReader#getFieldNames(FieldOption)}. + */ + enum FieldOption { + /** all fields */ + ALL = 1, + /** all indexed fields */ + INDEXED = 2, + /** all fields which are not indexed */ + UNINDEXED = 4, + /** all fields which are indexed with termvectors enables */ + INDEXED_WITH_TERMVECTOR = 8, + /** all fields which are indexed but don't have termvectors enabled */ + INDEXED_NO_TERMVECTOR = 16, + /** all fields where termvectors are enabled. Please note that only standard termvector fields are returned */ + TERMVECTOR = 32, + /** all field with termvectors wiht positions enabled */ + TERMVECTOR_WITH_POSITION = 64, + /** all fields where termvectors with offset position are set */ + TERMVECTOR_WITH_OFFSET = 128, + /** all fields where termvectors with offset and position values set */ + TERMVECTOR_WITH_POSITION_OFFSET = 256, + /** all fields that store payloads */ + STORES_PAYLOADS = 512 + }; + + /** Returns an IndexReader reading the index in an FSDirectory in the named + path. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * @param path the path to the index directory */ + static IndexReader* open(const char* path, bool closeDirectoryOnCleanup=true, IndexDeletionPolicy* deletionPolicy=NULL); + + /** Expert: returns an IndexReader reading the index in the given + * Directory, with a custom {@link IndexDeletionPolicy}. + * @param directory the index directory + * @param deletionPolicy a custom deletion policy (only used + * if you use this reader to perform deletes or to set + * norms); see {@link IndexWriter} for details. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static IndexReader* open(CL_NS(store)::Directory* directory, bool closeDirectoryOnCleanup=false, IndexDeletionPolicy* deletionPolicy=NULL); + + + /** + * Refreshes an IndexReader if the index has changed since this instance + * was (re)opened. + *

+ * Opening an IndexReader is an expensive operation. This method can be used + * to refresh an existing IndexReader to reduce these costs. This method + * tries to only load segments that have changed or were created after the + * IndexReader was (re)opened. + *

+ * If the index has not changed since this instance was (re)opened, then this + * call is a NOOP and returns this instance. Otherwise, a new instance is + * returned. The old instance is closed (unlink JLucene) and must + * be deleted
+ *

+ * You can determine whether a reader was actually reopened by comparing the + * old instance with the instance returned by this method: + *

+   * IndexReader* reader = ...
+   * ...
+   * IndexReader* newreader = r->reopen();
+   * if (newreader != reader) {
+   *   ...     // reader was reopened
+   *   reader->close();
+   *   _CLDELETE(reader);
+   * }
+   * reader = newreader;
+   * ...
+   * 
+ * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + virtual IndexReader* reopen(); + + /** + * Returns the directory associated with this index. The Default + * implementation returns the directory specified by subclasses when + * delegating to the IndexReader(Directory) constructor, or throws an + * UnsupportedOperationException if one was not specified. + * @throws UnsupportedOperationException if no directory + */ + virtual CL_NS(store)::Directory* directory(); + + DEFINE_MUTEX(THIS_LOCK) + + /** + * + * @throws IOException + */ + virtual void flush(); + + /** + * Commit changes resulting from delete, undeleteAll, or + * setNorm operations + * + * If an exception is hit, then either no changes or all + * changes will have been committed to the index + * (transactional semantics). + * @throws IOException if there is a low-level IO error + */ + CLUCENE_LOCAL_DECL virtual void commit(); + + + /** Undeletes all documents currently marked as deleted in this index. + * + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + virtual void undeleteAll(); + + /** + * Get a list of unique field names that exist in this index and have the specified + * field option information. + * @param fldOption specifies which field option should be available for the returned fields + * @return Collection of Strings indicating the names of the fields. + * @see IndexReader.FieldOption + */ + virtual void getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray) = 0; + + /** Returns the byte-encoded normalization factor for the named field of + * every document. This is used by the search code to score documents. + * + * The number of bytes returned is the size of the IndexReader->maxDoc() + * + * @see Field#setBoost(float_t) + * @memory The values are cached, so don't delete the returned byte array. + */ + virtual uint8_t* norms(const TCHAR* field) = 0; + + + /** Reads the byte-encoded normalization factor for the named field of every + * document. This is used by the search code to score documents. + * + * The size of bytes must be the size of the IndexReader->maxDoc() + * + * @see Field#setBoost(float_t) + */ + virtual void norms(const TCHAR* field, uint8_t* bytes) = 0; + + /** Expert: Resets the normalization factor for the named field of the named + * document. + * + * @see #norms(TCHAR*) + * @see Similarity#decodeNorm(uint8_t) + * + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if there is a low-level IO error + */ + void setNorm(int32_t doc, const TCHAR* field, float_t value); + + /** Expert: Resets the normalization factor for the named field of the named + * document. The norm represents the product of the field's {@link + * Field#setBoost(float_t) boost} and its {@link Similarity#lengthNorm(TCHAR*, + * int32_t) length normalization}. Thus, to preserve the length normalization + * values when resetting this, one should base the new value upon the old. + * + * @see #norms(TCHAR*) + * @see Similarity#decodeNorm(uint8_t) + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if there is a low-level IO error + */ + void setNorm(int32_t doc, const TCHAR* field, uint8_t value); + + /// Release the write lock, if needed. + virtual ~IndexReader(); + + /** + * Returns the time the index in the named directory was last modified. + * Do not use this to check whether the reader is still up-to-date, use + * {@link #isCurrent()} instead. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static uint64_t lastModified(const char* directory); + + /** + * Returns the time the index in the named directory was last modified. + * Do not use this to check whether the reader is still up-to-date, use + * {@link #isCurrent()} instead. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static uint64_t lastModified(CL_NS(store)::Directory* directory); + + + /** + * Reads version number from segments files. The version number is + * initialized with a timestamp and then increased by one for each change of + * the index. + * + * @param directory where the index resides. + * @return version number. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static int64_t getCurrentVersion(CL_NS(store)::Directory* directory); + + /** + * Reads version number from segments files. The version number is + * initialized with a timestamp and then increased by one for each change of + * the index. + * + * @param directory where the index resides. + * @return version number. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static int64_t getCurrentVersion(const char* directory); + + /** + * Version number when this IndexReader was opened. Not implemented in the IndexReader base class. + * @throws UnsupportedOperationException unless overridden in subclass + */ + virtual int64_t getVersion(); + + /**

For IndexReader implementations that use + * TermInfosReader to read terms, this sets the + * indexDivisor to subsample the number of indexed terms + * loaded into memory. This has the same effect as {@link + * IndexWriter#setTermIndexInterval} except that setting + * must be done at indexing time while this setting can be + * set per reader. When set to N, then one in every + * N*termIndexInterval terms in the index is loaded into + * memory. By setting this to a value > 1 you can reduce + * memory usage, at the expense of higher latency when + * loading a TermInfo. The default value is 1.

+ * + * NOTE: you must call this before the term + * index is loaded. If the index is already loaded, + * an IllegalStateException is thrown. + * @throws IllegalStateException if the term index has already been loaded into memory + */ + void setTermInfosIndexDivisor(int32_t indexDivisor); + + /**

For IndexReader implementations that use + * TermInfosReader to read terms, this returns the + * current indexDivisor. + * @see #setTermInfosIndexDivisor */ + int32_t getTermInfosIndexDivisor(); + + /** + * Check whether this IndexReader is still using the + * current (i.e., most recently committed) version of the + * index. If a writer has committed any changes to the + * index since this reader was opened, this will return + * false, in which case you must open a new + * IndexReader in order to see the changes. See the + * description of the autoCommit + * flag which controls when the {@link IndexWriter} + * actually commits changes to the index. + * + *

+ * Not implemented in the IndexReader base class. + *

+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * @throws UnsupportedOperationException unless overridden in subclass + */ + virtual bool isCurrent(); + + /** + * Checks is the index is optimized (if it has a single segment and + * no deletions). Not implemented in the IndexReader base class. + * @return true if the index is optimized; false otherwise + * @throws UnsupportedOperationException unless overridden in subclass + */ + virtual bool isOptimized(); + + /** + * Return an array of term frequency vectors for the specified document. + * The array contains a vector for each vectorized field in the document. + * Each vector contains terms and frequencies for all terms in a given vectorized field. + * If no such fields existed, the method returns null. The term vectors that are + * returned my either be of type TermFreqVector or of type TermPositionsVector if + * positions or offsets have been stored. + * + * @param docNumber document for which term frequency vectors are returned + * @return array of term frequency vectors. May be null if no term vectors have been + * stored for the specified document. + * @throws IOException if index cannot be accessed + * @see org.apache.lucene.document.Field.TermVector + */ + virtual CL_NS(util)::ArrayBase* getTermFreqVectors(int32_t docNumber) = 0; + + /** + * Return a term frequency vector for the specified document and field. The + * returned vector contains terms and frequencies for the terms in + * the specified field of this document, if the field had the storeTermVector + * flag set. If termvectors had been stored with positions or offsets, a + * TermPositionsVector is returned. + * + * @param docNumber document for which the term frequency vector is returned + * @param field field for which the term frequency vector is returned. + * @return term frequency vector May be null if field does not exist in the specified + * document or term vector was not stored. + * @throws IOException if index cannot be accessed + * @see org.apache.lucene.document.Field.TermVector + */ + virtual TermFreqVector* getTermFreqVector(int32_t docNumber, const TCHAR* field=NULL) = 0; + + /** + * Load the Term Vector into a user-defined data structure instead of relying on the parallel arrays of + * the {@link TermFreqVector}. + * @param docNumber The number of the document to load the vector for + * @param field The name of the field to load + * @param mapper The {@link TermVectorMapper} to process the vector. Must not be null + * @throws IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified. + * + */ + virtual void getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper) =0; + + /** + * Map all the term vectors for all fields in a Document + * @param docNumber The number of the document to load the vector for + * @param mapper The {@link TermVectorMapper} to process the vector. Must not be null + * @throws IOException if term vectors cannot be accessed or if they do not exist on the field and doc. specified. + */ + virtual void getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper) =0; + + /** + * Returns true if an index exists at the specified directory. + * If the directory does not exist or if there is no index in it. + * @param directory the directory to check for an index + * @return true if an index exists; false otherwise + */ + static bool indexExists(const char* directory); + + /** + * Returns true if an index exists at the specified directory. + * If the directory does not exist or if there is no index in it. + * @param directory the directory to check for an index + * @return true if an index exists; false otherwise + * @throws IOException if there is a problem with accessing the index + */ + static bool indexExists(const CL_NS(store)::Directory* directory); + + /** Returns the number of documents in this index. */ + virtual int32_t numDocs() = 0; + + /** Returns one greater than the largest possible document number. + * This may be used to, e.g., determine how big to allocate an array which + * will have an element for every document number in an index. + */ + virtual int32_t maxDoc() const = 0; + + /** + * Get the {@link org.apache.lucene.document.Document} at the nth position. The {@link org.apache.lucene.document.FieldSelector} + * may be used to determine what {@link org.apache.lucene.document.Field}s to load and how they should be loaded. + * The fields are not cleared before retrieving the document, so the + * object should be new or just cleared. + * + * NOTE: If this Reader (more specifically, the underlying FieldsReader) is closed before the lazy {@link org.apache.lucene.document.Field} is + * loaded an exception may be thrown. If you want the value of a lazy {@link org.apache.lucene.document.Field} to be available after closing you must + * explicitly load it or fetch the Document again with a new loader. + * + * + * @param n Get the document at the nth position + * @param fieldSelector The {@link org.apache.lucene.document.FieldSelector} to use to determine what Fields should be loaded on the Document. May be null, in which case all Fields will be loaded. + * @return The stored fields of the {@link org.apache.lucene.document.Document} at the nth position + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * + * @see org.apache.lucene.document.Field + * @see org.apache.lucene.document.FieldSelector + * @see org.apache.lucene.document.SetBasedFieldSelector + * @see org.apache.lucene.document.LoadFirstFieldSelector + */ + //When we convert to JDK 1.5 make this Set + virtual bool document(int32_t n, CL_NS(document)::Document& doc, const CL_NS(document)::FieldSelector* fieldSelector) =0; + + /** Gets the stored fields of the nth + * Document in this index. + * The fields are not cleared before retrieving the document, so the + * object should be new or just cleared. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + bool document(int32_t n, CL_NS(document)::Document& doc); + + _CL_DEPRECATED( document(i, Document&) ) bool document(int32_t n, CL_NS(document)::Document*); + + _CL_DEPRECATED( document(i, document) ) CL_NS(document)::Document* document(const int32_t n); + + /** Returns true if document n has been deleted */ + virtual bool isDeleted(const int32_t n) = 0; + + /** Returns true if any documents have been deleted */ + virtual bool hasDeletions() const = 0; + + /** Returns true if there are norms stored for this field. */ + virtual bool hasNorms(const TCHAR* field); + +/** Returns an enumeration of all the terms in the index. The + * enumeration is ordered by Term.compareTo(). Each term is greater + * than all that precede it in the enumeration. Note that after + * calling terms(), {@link TermEnum#next()} must be called + * on the resulting enumeration before calling other methods such as + * {@link TermEnum#term()}. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + virtual TermEnum* terms() = 0; + +/** Returns an enumeration of all terms starting at a given term. If + * the given term does not exist, the enumeration is positioned at the + * first term greater than the supplied therm. The enumeration is + * ordered by Term.compareTo(). Each term is greater than all that + * precede it in the enumeration. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + virtual TermEnum* terms(const Term* t) = 0; + + /** Returns the number of documents containing the term t. + * @throws IOException if there is a low-level IO error + */ + virtual int32_t docFreq(const Term* t) = 0; + + /* Returns an unpositioned TermPositions enumerator. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + virtual TermPositions* termPositions() = 0; + + /** Returns an enumeration of all the documents which contain + * term. For each document, in addition to the document number + * and frequency of the term in that document, a list of all of the ordinal + * positions of the term in the document is available. Thus, this method + * implements the mapping: + * + *

    + * Term    =>    <docNum, freq, + * <pos1, pos2, ... + * posfreq-1> + * >* + *
+ *

This positional information facilitates phrase and proximity searching. + *

The enumeration is ordered by document number. Each document number is + * greater than all that precede it in the enumeration. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + TermPositions* termPositions(Term* term); + + /** Returns an unpositioned {@link TermDocs} enumerator. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + virtual TermDocs* termDocs() = 0; + + /** Returns an enumeration of all the documents which contain + * term. For each document, the document number, the frequency of + * the term in that document is also provided, for use in search scoring. + * Thus, this method implements the mapping: + *

    Term    =>    <docNum, freq>*
+ *

The enumeration is ordered by document number. Each document number + * is greater than all that precede it in the enumeration. + * @throws IOException if there is a low-level IO error + * @memory Caller must clean up + */ + TermDocs* termDocs(Term* term); + + /** Deletes the document numbered docNum. Once a document is + * deleted it will not appear in TermDocs or TermPostitions enumerations. + * Attempts to read its field with the {@link #document} + * method will result in an error. The presence of this document may still be + * reflected in the {@link #docFreq} statistic, though + * this will be corrected eventually as the index is further modified. + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if there is a low-level IO error + */ + void deleteDocument(const int32_t docNum); + + ///@deprecated. Use deleteDocument instead. + _CL_DEPRECATED( deleteDocument ) void deleteDoc(const int32_t docNum); + + /** Deletes all documents that have a given term. + * This is useful if one uses a document field to hold a unique ID string for + * the document. Then to delete such a document, one merely constructs a + * term with the appropriate field and the unique ID string as its text and + * passes it to this method. + * See {@link #deleteDocument(int)} for information about when this deletion will + * become effective. + * @return the number of documents deleted + * @throws StaleReaderException if the index has changed + * since this reader was opened + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if there is a low-level IO error + */ + int32_t deleteDocuments(Term* term); + + ///@deprecated. Use deleteDocuments instead. + _CL_DEPRECATED( deleteDocuments ) int32_t deleteTerm(Term* term); + + /** + * Closes files associated with this index and also saves any new deletions to disk. + * No other methods should be called after this has been called. + * @throws IOException if there is a low-level IO error + */ + void close(); + + /** + * Returns true iff the index in the named directory is + * currently locked. + * @param directory the directory to check for a lock + * @throws IOException if there is a low-level IO error + */ + static bool isLocked(CL_NS(store)::Directory* directory); + + /** + * Returns true iff the index in the named directory is + * currently locked. + * @param directory the directory to check for a lock + * @throws IOException if there is a low-level IO error + */ + static bool isLocked(const char* directory); + + + ///Forcibly unlocks the index in the named directory. + ///Caution: this should only be used by failure recovery code, + ///when it is known that no other process nor thread is in fact + ///currently accessing this index. + static void unlock(CL_NS(store)::Directory* directory); + static void unlock(const char* path); + + /** Returns the directory this index resides in. */ + _CL_DEPRECATED( directory() ) CL_NS(store)::Directory* getDirectory(); + + /** Returns true if the file is a lucene filename (based on extension or filename) */ + static bool isLuceneFile(const char* filename); + + /** + * For classes that need to know when the IndexReader closes (such as caches, etc), + * should pass their callback function to this. + */ + void addCloseCallback(CloseCallback callback, void* parameter); + + friend class SegmentReader; + friend class MultiReader; + friend class IndexWriter; + friend class MultiSegmentReader; +}; + +CL_NS_END +#endif + + diff --git a/src/core/CLucene/index/IndexWriter.cpp b/src/core/CLucene/index/IndexWriter.cpp new file mode 100644 index 00000000000..deab2c3cc5f --- /dev/null +++ b/src/core/CLucene/index/IndexWriter.cpp @@ -0,0 +1,2917 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/document/Document.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/store/Directory.h" +#include "CLucene/util/Misc.h" +#include "IndexReader.h" +#include "IndexWriter.h" + +#include "CLucene/index/MergePolicy.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/store/_Lock.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/PriorityQueue.h" +#include "CLucene/util/croaring/roaring.hh" +#include "MergePolicy.h" +#include "MergeScheduler.h" +#include "SDocumentWriter.h" +#include "_DocumentsWriter.h" +#include "_IndexFileDeleter.h" +#include "_SegmentHeader.h" +#include "_SegmentInfos.h" +#include "_SegmentMerger.h" +#include "_SkipListWriter.h" +#include "_Term.h" +#include "_TermInfo.h" +#include "vp4.h" +#include +#include +#include + +#if defined(USE_AVX2) +#define P4ENC p4nd1enc256v32 +#else +#define P4ENC p4nd1enc128v32 +#endif + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_USE(document) +CL_NS_USE(analysis) +CL_NS_USE(search) +CL_NS_DEF(index) + +int64_t IndexWriter::WRITE_LOCK_TIMEOUT = 1000; +const char *IndexWriter::WRITE_LOCK_NAME = "write.lock"; +std::ostream *IndexWriter::defaultInfoStream = NULL; + +const int32_t IndexWriter::MERGE_READ_BUFFER_SIZE = 4096; +const int32_t IndexWriter::DISABLE_AUTO_FLUSH = -1; +const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DOCS = DISABLE_AUTO_FLUSH; +const float_t IndexWriter::DEFAULT_RAM_BUFFER_SIZE_MB = 16.0; +const int32_t IndexWriter::DEFAULT_MAX_BUFFERED_DELETE_TERMS = DISABLE_AUTO_FLUSH; +const int32_t IndexWriter::DEFAULT_MAX_MERGE_DOCS = LogDocMergePolicy::DEFAULT_MAX_MERGE_DOCS; +const int32_t IndexWriter::DEFAULT_MERGE_FACTOR = LogMergePolicy::DEFAULT_MERGE_FACTOR; + +DEFINE_MUTEX(IndexWriter::MESSAGE_ID_LOCK) +int32_t IndexWriter::MESSAGE_ID = 0; +const int32_t IndexWriter::MAX_TERM_LENGTH = DocumentsWriter::MAX_TERM_LENGTH; + +class IndexWriter::Internal { +public: + IndexWriter *_this; + Internal(IndexWriter *_this) { + this->_this = _this; + } + // Apply buffered delete terms to the segment just flushed from ram + // apply appropriately so that a delete term is only applied to + // the documents buffered before it, not those buffered after it. + void applyDeletesSelectively(const TermNumMapType &deleteTerms, + const std::vector &deleteIds, IndexReader *reader); + + // Apply buffered delete terms to this reader. + void applyDeletes(const TermNumMapType &deleteTerms, IndexReader *reader); +}; + +void IndexWriter::deinit(bool releaseWriteLock) throw() { + if (writeLock != NULL && releaseWriteLock) { + writeLock->release();// release write lock + _CLLDELETE(writeLock); + } + _CLLDELETE(segmentInfos); + _CLLDELETE(mergingSegments); + _CLLDELETE(pendingMerges); + _CLLDELETE(runningMerges); + _CLLDELETE(mergeExceptions); + _CLLDELETE(segmentsToOptimize); + _CLLDELETE(mergeScheduler); + _CLLDELETE(mergePolicy); + _CLLDELETE(deleter); + _CLLDELETE(docWriter); + if (bOwnsDirectory) _CLLDECDELETE(directory); + delete _internal; +} + +IndexWriter::~IndexWriter() { + deinit(); + + _trans_vec.clear(); + readers.clear(); + if (fieldInfos != nullptr) { + _CLDELETE(fieldInfos); + } + freqOutputList.clear(); + proxOutputList.clear(); + termInfosWriterList.clear(); + skipListWriterList.clear(); + docDeltaBuffer.clear(); +} + +void IndexWriter::ensureOpen() { + if (closed) { + _CLTHROWA(CL_ERR_AlreadyClosed, "this IndexWriter is closed"); + } +} + +void IndexWriter::message(string message) { + if (infoStream != NULL) { + (*infoStream) << string("IW ") << Misc::toString(messageID) << string(" [") + << Misc::toString(_LUCENE_CURRTHREADID) << string("]: ") << message << string("\n"); + } +} + +void IndexWriter::setMessageID() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (infoStream != NULL && messageID == -1) { + { + SCOPED_LOCK_MUTEX(MESSAGE_ID_LOCK) + messageID = MESSAGE_ID++; + } + } +} + +LogMergePolicy *IndexWriter::getLogMergePolicy() const { + if (mergePolicy->instanceOf(LogMergePolicy::getClassName())) + return (LogMergePolicy *) mergePolicy; + else + _CLTHROWA(CL_ERR_IllegalArgument, "this method can only be called when the merge policy is the default LogMergePolicy"); +} + +bool IndexWriter::getUseCompoundFile() { + return getLogMergePolicy()->getUseCompoundFile(); +} + + +void IndexWriter::setUseCompoundFile(bool value) { + getLogMergePolicy()->setUseCompoundFile(value); + getLogMergePolicy()->setUseCompoundDocStore(value); +} + +void IndexWriter::setSimilarity(Similarity *similarity) { + ensureOpen(); + this->similarity = similarity; +} + +Similarity *IndexWriter::getSimilarity() { + ensureOpen(); + return this->similarity; +} + + +void IndexWriter::setTermIndexInterval(int32_t interval) { + ensureOpen(); + this->termIndexInterval = interval; +} + +int32_t IndexWriter::getTermIndexInterval() { + ensureOpen(); + return termIndexInterval; +} + +IndexWriter::IndexWriter(const char *path, Analyzer *a, bool create) : bOwnsDirectory(true) { + init(FSDirectory::getDirectory(path, create), a, create, true, (IndexDeletionPolicy *) NULL, true); +} + +IndexWriter::IndexWriter(Directory *d, Analyzer *a, bool create, bool closeDir) : bOwnsDirectory(false) { + init(d, a, create, closeDir, NULL, true); +} + +IndexWriter::IndexWriter(Directory *d, bool autoCommit, Analyzer *a, IndexDeletionPolicy *deletionPolicy, bool closeDirOnShutdown) : bOwnsDirectory(false) { + init(d, a, closeDirOnShutdown, deletionPolicy, autoCommit); +} + +IndexWriter::IndexWriter(Directory *d, bool autoCommit, Analyzer *a, bool create, IndexDeletionPolicy *deletionPolicy, bool closeDirOnShutdown) : bOwnsDirectory(false) { + init(d, a, create, closeDirOnShutdown, deletionPolicy, autoCommit); +} + +void IndexWriter::init(Directory *d, Analyzer *a, bool closeDir, IndexDeletionPolicy *deletionPolicy, bool autoCommit) { + if (IndexReader::indexExists(d)) { + init(d, a, false, closeDir, deletionPolicy, autoCommit); + } else { + init(d, a, true, closeDir, deletionPolicy, autoCommit); + } +} + +void IndexWriter::init(Directory *d, Analyzer *a, const bool create, const bool closeDir, + IndexDeletionPolicy *deletionPolicy, const bool autoCommit) { + this->_internal = new Internal(this); + this->termIndexInterval = IndexWriter::DEFAULT_TERM_INDEX_INTERVAL; + this->mergeScheduler = _CLNEW SerialMergeScheduler();//TODO: implement and use ConcurrentMergeScheduler + this->mergingSegments = _CLNEW MergingSegmentsType; + this->pendingMerges = _CLNEW PendingMergesType; + this->runningMerges = _CLNEW RunningMergesType; + this->mergeExceptions = _CLNEW MergeExceptionsType; + this->segmentsToOptimize = _CLNEW SegmentsToOptimizeType; + this->mergePolicy = _CLNEW LogByteSizeMergePolicy(); + this->localRollbackSegmentInfos = NULL; + this->stopMerges = false; + messageID = -1; + maxFieldLength = FIELD_TRUNC_POLICY__WARN; + infoStream = NULL; + this->mergeFactor = this->minMergeDocs = this->maxMergeDocs = 0; + this->commitLockTimeout = 0; + this->closeDir = closeDir; + this->commitPending = this->closed = this->closing = false; + directory = d; + analyzer = a; + this->infoStream = defaultInfoStream; + setMessageID(); + this->writeLockTimeout = IndexWriter::WRITE_LOCK_TIMEOUT; + this->similarity = Similarity::getDefault(); + this->hitOOM = false; + this->autoCommit = true; + this->segmentInfos = _CLNEW SegmentInfos; + this->mergeGen = 0; + this->rollbackSegmentInfos = NULL; + this->deleter = NULL; + this->docWriter = NULL; + this->writeLock = NULL; + this->fieldInfos = NULL; + + if (create) { + // Clear the write lock in case it's leftover: + directory->clearLock(IndexWriter::WRITE_LOCK_NAME); + } + + bool hasLock = false; + try { + writeLock = directory->makeLock(IndexWriter::WRITE_LOCK_NAME); + hasLock = writeLock->obtain(writeLockTimeout); + if (!hasLock)// obtain write lock + _CLTHROWA(CL_ERR_LockObtainFailed, (string("Index locked for write: ") + writeLock->getObjectName()).c_str()); + } catch (...) { + deinit(hasLock); + throw; + } + + try { + if (create) { + // Try to read first. This is to allow create + // against an index that's currently open for + // searching. In this case we write the next + // segments_N file with no segments: + try { + segmentInfos->read(directory); + segmentInfos->clear(); + } catch (CLuceneError &e) { + if (e.number() != CL_ERR_IO) throw e; + // Likely this means it's a fresh directory + } + segmentInfos->write(directory); + } else { + segmentInfos->read(directory); + } + + this->autoCommit = autoCommit; + if (!autoCommit) { + rollbackSegmentInfos = segmentInfos->clone(); + } else { + rollbackSegmentInfos = NULL; + } + if (analyzer != nullptr) { + if (auto *sa = dynamic_cast *>(analyzer); sa != nullptr) { + docWriter = _CLNEW SDocumentsWriter(directory, this); + } else { + docWriter = _CLNEW DocumentsWriter(directory, this); + } + } else { + docWriter = _CLNEW DocumentsWriter(directory, this); + } + // Default deleter (for backwards compatibility) is + // KeepOnlyLastCommitDeleter: + deleter = _CLNEW IndexFileDeleter(directory, + deletionPolicy == NULL ? _CLNEW KeepOnlyLastCommitDeletionPolicy() : deletionPolicy, + segmentInfos, infoStream, docWriter); + + pushMaxBufferedDocs(); + + if (infoStream != NULL) { + message(string("init: create=") + (create ? "true" : "false")); + messageState(); + } + + } catch (CLuceneError &e) { + deinit(e.number() == CL_ERR_IO); + throw e; + } +} + +void IndexWriter::setMergePolicy(MergePolicy *mp) { + ensureOpen(); + if (mp == NULL) + _CLTHROWA(CL_ERR_NullPointer, "MergePolicy must be non-NULL"); + + if (mergePolicy != mp) { + mergePolicy->close(); + _CLDELETE(mergePolicy); + } + mergePolicy = mp; + pushMaxBufferedDocs(); + if (infoStream != NULL) + message(string("setMergePolicy ") + mp->getObjectName()); +} + +MergePolicy *IndexWriter::getMergePolicy() { + ensureOpen(); + return mergePolicy; +} + +void IndexWriter::setMergeScheduler(MergeScheduler *mergeScheduler) { + ensureOpen(); + if (mergeScheduler == NULL) + _CLTHROWA(CL_ERR_NullPointer, "MergeScheduler must be non-NULL"); + + if (this->mergeScheduler != mergeScheduler) { + finishMerges(true); + this->mergeScheduler->close(); + _CLLDELETE(this->mergeScheduler) + } + this->mergeScheduler = mergeScheduler; + if (infoStream != NULL) + message(string("setMergeScheduler ") + mergeScheduler->getObjectName()); +} + +MergeScheduler *IndexWriter::getMergeScheduler() { + ensureOpen(); + return mergeScheduler; +} + +void IndexWriter::setMaxMergeDocs(int32_t maxMergeDocs) { + getLogMergePolicy()->setMaxMergeDocs(maxMergeDocs); +} + +int32_t IndexWriter::getMaxMergeDocs() const { + return getLogMergePolicy()->getMaxMergeDocs(); +} + +void IndexWriter::setMaxFieldLength(int32_t maxFieldLength) { + ensureOpen(); + this->maxFieldLength = maxFieldLength; + if (infoStream != NULL) + message("setMaxFieldLength " + Misc::toString(maxFieldLength)); +} + +int32_t IndexWriter::getMaxFieldLength() { + ensureOpen(); + return maxFieldLength; +} + +void IndexWriter::setMaxBufferedDocs(int32_t maxBufferedDocs) { + ensureOpen(); + if (maxBufferedDocs != DISABLE_AUTO_FLUSH && maxBufferedDocs < 2) + _CLTHROWA(CL_ERR_IllegalArgument, + "maxBufferedDocs must at least be 2 when enabled"); + if (maxBufferedDocs == DISABLE_AUTO_FLUSH && (int32_t) getRAMBufferSizeMB() == DISABLE_AUTO_FLUSH) + _CLTHROWA(CL_ERR_IllegalArgument, + "at least one of ramBufferSize and maxBufferedDocs must be enabled"); + docWriter->setMaxBufferedDocs(maxBufferedDocs); + pushMaxBufferedDocs(); + if (infoStream != NULL) + message("setMaxBufferedDocs " + Misc::toString(maxBufferedDocs)); +} + +void IndexWriter::pushMaxBufferedDocs() { + if (docWriter->getMaxBufferedDocs() != DISABLE_AUTO_FLUSH) { + const MergePolicy *mp = mergePolicy; + if (mp->instanceOf(LogDocMergePolicy::getClassName())) { + LogDocMergePolicy *lmp = (LogDocMergePolicy *) mp; + const int32_t maxBufferedDocs = docWriter->getMaxBufferedDocs(); + if (lmp->getMinMergeDocs() != maxBufferedDocs) { + if (infoStream != NULL) { + message(string("now push maxBufferedDocs ") + Misc::toString(maxBufferedDocs) + " to LogDocMergePolicy"); + } + lmp->setMinMergeDocs(maxBufferedDocs); + } + } + } +} + +int32_t IndexWriter::getMaxBufferedDocs() { + ensureOpen(); + return docWriter->getMaxBufferedDocs(); +} + +void IndexWriter::setRAMBufferSizeMB(float_t mb) { + if ((int32_t) mb != DISABLE_AUTO_FLUSH && mb <= 0.0) + _CLTHROWA(CL_ERR_IllegalArgument, + "ramBufferSize should be > 0.0 MB when enabled"); + if (mb == DISABLE_AUTO_FLUSH && getMaxBufferedDocs() == DISABLE_AUTO_FLUSH) + _CLTHROWA(CL_ERR_IllegalArgument, + "at least one of ramBufferSize and maxBufferedDocs must be enabled"); + docWriter->setRAMBufferSizeMB(mb); + if (infoStream != NULL) { + message(string("setRAMBufferSizeMB ") + Misc::toString(mb)); + } +} + +float_t IndexWriter::getRAMBufferSizeMB() { + return docWriter->getRAMBufferSizeMB(); +} + +void IndexWriter::setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms) { + ensureOpen(); + if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH && maxBufferedDeleteTerms < 1) + _CLTHROWA(CL_ERR_IllegalArgument, + "maxBufferedDeleteTerms must at least be 1 when enabled"); + docWriter->setMaxBufferedDeleteTerms(maxBufferedDeleteTerms); + if (infoStream != NULL) + message("setMaxBufferedDeleteTerms " + Misc::toString(maxBufferedDeleteTerms)); +} + +int32_t IndexWriter::getMaxBufferedDeleteTerms() { + ensureOpen(); + return docWriter->getMaxBufferedDeleteTerms(); +} + +void IndexWriter::setMergeFactor(int32_t mergeFactor) { + getLogMergePolicy()->setMergeFactor(mergeFactor); +} + +int32_t IndexWriter::getMergeFactor() const { + return getLogMergePolicy()->getMergeFactor(); +} + +void IndexWriter::setDefaultInfoStream(std::ostream *infoStream) { + IndexWriter::defaultInfoStream = infoStream; +} + +std::ostream *IndexWriter::getDefaultInfoStream() { + return IndexWriter::defaultInfoStream; +} + +//TODO: infoStream - unicode +void IndexWriter::setInfoStream(std::ostream *infoStream) { + ensureOpen(); + this->infoStream = infoStream; + setMessageID(); + docWriter->setInfoStream(infoStream); + deleter->setInfoStream(infoStream); + if (infoStream != NULL) + messageState(); +} + +void IndexWriter::messageState() { + message(string("setInfoStream: dir=") + directory->toString() + + " autoCommit=" + (autoCommit ? "true" : "false" + string(" mergePolicy=") + mergePolicy->getObjectName() + " mergeScheduler=" + mergeScheduler->getObjectName() + " ramBufferSizeMB=" + Misc::toString(docWriter->getRAMBufferSizeMB()) + " maxBuffereDocs=" + Misc::toString(docWriter->getMaxBufferedDocs())) + + " maxBuffereDeleteTerms=" + Misc::toString(docWriter->getMaxBufferedDeleteTerms()) + + " maxFieldLength=" + Misc::toString(maxFieldLength) + + " index=" + segString()); +} + +std::ostream *IndexWriter::getInfoStream() { + ensureOpen(); + return infoStream; +} + +void IndexWriter::setWriteLockTimeout(int64_t writeLockTimeout) { + ensureOpen(); + this->writeLockTimeout = writeLockTimeout; +} + +int64_t IndexWriter::getWriteLockTimeout() { + ensureOpen(); + return writeLockTimeout; +} + +void IndexWriter::setDefaultWriteLockTimeout(int64_t writeLockTimeout) { + IndexWriter::WRITE_LOCK_TIMEOUT = writeLockTimeout; +} + +int64_t IndexWriter::getDefaultWriteLockTimeout() { + return IndexWriter::WRITE_LOCK_TIMEOUT; +} + +void IndexWriter::close(bool waitForMerges) { + bool doClose; + + // If any methods have hit OutOfMemoryError, then abort + // on close, in case the internal state of IndexWriter + // or DocumentsWriter is corrupt + if (hitOOM) + abort(); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + // Ensure that only one thread actually gets to do the closing: + if (!closing) { + doClose = true; + closing = true; + } else + doClose = false; + } + if (doClose) + closeInternal(waitForMerges); + else + // Another thread beat us to it (is actually doing the + // close), so we will block until that other thread + // has finished closing + waitForClose(); +} + +void IndexWriter::waitForClose() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + while (!closed && closing) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } +} + +void IndexWriter::closeInternal(bool waitForMerges) { + try { + if (infoStream != NULL) + message(string("now flush at close")); + + docWriter->close(); + + // Only allow a _CLNEW merge to be triggered if we are + // going to wait for merges: + flush(waitForMerges, true); + + if (waitForMerges) + // Give merge scheduler last chance to run, in case + // any pending merges are waiting: + mergeScheduler->merge(this); + + mergePolicy->close(); + + finishMerges(waitForMerges); + + mergeScheduler->close(); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + if (commitPending) { + bool success = false; + try { + segmentInfos->write(directory);// now commit changes + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception committing segments file during close")); + deletePartialSegmentsFile(); + }) + if (infoStream != NULL) + message("close: wrote segments file \"" + segmentInfos->getCurrentSegmentFileName() + "\""); + + deleter->checkpoint(segmentInfos, true); + + commitPending = false; + // _CLDELETE(rollbackSegmentInfos); + } + _CLDELETE(rollbackSegmentInfos); + + + if (infoStream != NULL) + message("at close: " + segString()); + + _CLDELETE(docWriter); + deleter->close(); + } + + if (closeDir) + directory->close(); + + if (writeLock != NULL) { + writeLock->release();// release write lock + _CLDELETE(writeLock); + } + closed = true; + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } catch (CLuceneError &e) { + throw e; + } + _CLFINALLY( + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + if (!closed) { + closing = false; + if (infoStream != NULL) + message(string("hit exception while closing")); + } + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION) + }) +} + +bool IndexWriter::flushDocStores() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + const std::vector &files = docWriter->files(); + + bool useCompoundDocStore = false; + + if (files.size() > 0) { + string docStoreSegment; + + bool success = false; + try { + docStoreSegment = docWriter->closeDocStore(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception closing doc store segment")); + docWriter->abort(NULL); + }) + + useCompoundDocStore = mergePolicy->useCompoundDocStore(segmentInfos); + + if (useCompoundDocStore && !docStoreSegment.empty()) { + // Now build compound doc store file + + success = false; + + const int32_t numSegments = segmentInfos->size(); + const string compoundFileName = docStoreSegment + "." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION; + + try { + CompoundFileWriter cfsWriter(directory, compoundFileName.c_str()); + const size_t size = files.size(); + for (size_t i = 0; i < size; ++i) + cfsWriter.addFile(files[i].c_str()); + + // Perform the merge + cfsWriter.close(); + + for (int32_t i = 0; i < numSegments; i++) { + SegmentInfo *si = segmentInfos->info(i); + if (si->getDocStoreOffset() != -1 && + si->getDocStoreSegment().compare(docStoreSegment) == 0) + si->setDocStoreIsCompoundFile(true); + } + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message("hit exception building compound file doc store for segment " + docStoreSegment); + + // Rollback to no compound file + for (int32_t i = 0; i < numSegments; i++) { + SegmentInfo *si = segmentInfos->info(i); + if (si->getDocStoreOffset() != -1 && + si->getDocStoreSegment().compare(docStoreSegment) == 0) + si->setDocStoreIsCompoundFile(false); + } + deleter->deleteFile(compoundFileName.c_str()); + deletePartialSegmentsFile(); + }) + + deleter->checkpoint(segmentInfos, false); + } + } + + return useCompoundDocStore; +} + +Directory *IndexWriter::getDirectory() { + ensureOpen(); + return directory; +} + +Analyzer *IndexWriter::getAnalyzer() { + ensureOpen(); + return analyzer; +} + +int32_t IndexWriter::docCount() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + int32_t count = docWriter->getNumDocsInRAM(); + for (int32_t i = 0; i < segmentInfos->size(); i++) { + SegmentInfo *si = segmentInfos->info(i); + count += si->docCount; + } + return count; +} + +void IndexWriter::addDocument(Document *doc, Analyzer *an) { + if (an == NULL) an = this->analyzer; + ensureOpen(); + bool doFlush = false; + bool success = false; + try { + try { + doFlush = docWriter->addDocument(doc, an); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception adding document")); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + // If docWriter has some aborted files that were + // never incref'd, then we clean them up here + if (docWriter != NULL) { + const std::vector *files = docWriter->abortedFiles(); + if (files != NULL) + deleter->deleteNewFiles(*files); + } + } + }) + if (doFlush) + flush(true, false); + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } +} + +void IndexWriter::deleteDocuments(Term *term) { + ensureOpen(); + try { + bool doFlush = docWriter->bufferDeleteTerm(term); + if (doFlush) + flush(true, false); + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } +} + +void IndexWriter::deleteDocuments(const ArrayBase *terms) { + ensureOpen(); + try { + bool doFlush = docWriter->bufferDeleteTerms(terms); + if (doFlush) + flush(true, false); + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } +} + +void IndexWriter::updateDocument(Term *term, Document *doc) { + ensureOpen(); + updateDocument(term, doc, getAnalyzer()); +} + +void IndexWriter::updateDocument(Term *term, Document *doc, Analyzer *analyzer) { + ensureOpen(); + try { + bool doFlush = false; + bool success = false; + try { + doFlush = docWriter->updateDocument(term, doc, analyzer); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception updating document")); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + // If docWriter has some aborted files that were + // never incref'd, then we clean them up here + const std::vector *files = docWriter->abortedFiles(); + if (files != NULL) + deleter->deleteNewFiles(*files); + } + }) + if (doFlush) + flush(true, false); + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } +} + +// for test purpose +int32_t IndexWriter::getSegmentCount() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return segmentInfos->size(); +} + +// for test purpose +int32_t IndexWriter::getNumBufferedDocuments() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return docWriter->getNumDocsInRAM(); +} + +// for test purpose +int32_t IndexWriter::getDocCount(int32_t i) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (i >= 0 && i < segmentInfos->size()) { + return segmentInfos->info(i)->docCount; + } else { + return -1; + } +} + +string IndexWriter::newSegmentName() { + // Cannot synchronize on IndexWriter because that causes + // deadlock + { + SCOPED_LOCK_MUTEX(segmentInfos->THIS_LOCK) + // Important to set commitPending so that the + // segmentInfos is written on close. Otherwise we + // could close, re-open and re-return the same segment + // name that was previously returned which can cause + // problems at least with ConcurrentMergeScheduler. + commitPending = true; + + char buf[10]; + Misc::longToBase(segmentInfos->counter++, 36, buf); + return string("_") + buf; + } +} + +void IndexWriter::optimize(bool doWait) { + optimize(1, doWait); +} + +void IndexWriter::optimize(int32_t maxNumSegments, bool doWait) { + ensureOpen(); + + if (maxNumSegments < 1) + _CLTHROWA(CL_ERR_IllegalArgument, "maxNumSegments must be >= 1; got " + maxNumSegments); + + if (infoStream != NULL) + message("optimize: index now " + segString()); + + flush(); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + resetMergeExceptions(); + segmentsToOptimize->clear(); + const int32_t numSegments = segmentInfos->size(); + for (int32_t i = 0; i < numSegments; i++) + segmentsToOptimize->push_back(segmentInfos->info(i)); + + // Now mark all pending & running merges as optimize + // merge: + PendingMergesType::iterator it = pendingMerges->begin(); + while (it != pendingMerges->end()) { + MergePolicy::OneMerge *_merge = *it; + _merge->optimize = true; + _merge->maxNumSegmentsOptimize = maxNumSegments; + + it++; + } + + RunningMergesType::iterator it2 = runningMerges->begin(); + while (it2 != runningMerges->end()) { + MergePolicy::OneMerge *_merge = *it2; + _merge->optimize = true; + _merge->maxNumSegmentsOptimize = maxNumSegments; + + it2++; + } + } + + maybeMerge(maxNumSegments, true); + + if (doWait) { + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + while (optimizeMergesPending()) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION); + + if (mergeExceptions->size() > 0) { + // Forward any exceptions in background merge + // threads to the current thread: + const int32_t size = mergeExceptions->size(); + for (int32_t i = 0; i < size; i++) { + MergePolicy::OneMerge *_merge = (*mergeExceptions)[0]; + if (_merge->optimize) { + CLuceneError tmp(_merge->getException()); + CLuceneError err(tmp.number(), + (string("background merge hit exception: ") + _merge->segString(directory) + ":" + tmp.what()).c_str(), false); + throw err; + } + } + } + } + } + } + + // NOTE: in the ConcurrentMergeScheduler case, when + // doWait is false, we can return immediately while + // background threads accomplish the optimization +} + +bool IndexWriter::optimizeMergesPending() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + for (PendingMergesType::iterator it = pendingMerges->begin(); + it != pendingMerges->end(); it++) { + if ((*it)->optimize) + return true; + + it++; + } + + for (RunningMergesType::iterator it = runningMerges->begin(); + it != runningMerges->end(); it++) { + if ((*it)->optimize) + return true; + + it++; + } + + return false; +} + +void IndexWriter::maybeMerge() { + maybeMerge(false); +} + +void IndexWriter::maybeMerge(bool optimize) { + maybeMerge(1, optimize); +} + +void IndexWriter::maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize) { + updatePendingMerges(maxNumSegmentsOptimize, optimize); + mergeScheduler->merge(this); +} + +void IndexWriter::updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + assert(!optimize || maxNumSegmentsOptimize > 0); + + if (stopMerges) + return; + + MergePolicy::MergeSpecification *spec; + if (optimize) { + spec = mergePolicy->findMergesForOptimize(segmentInfos, this, maxNumSegmentsOptimize, *segmentsToOptimize); + + if (spec != NULL) { + const int32_t numMerges = spec->merges->size(); + for (int32_t i = 0; i < numMerges; i++) { + MergePolicy::OneMerge *_merge = (*spec->merges)[i]; + _merge->optimize = true; + _merge->maxNumSegmentsOptimize = maxNumSegmentsOptimize; + } + } + + } else + spec = mergePolicy->findMerges(segmentInfos, this); + + if (spec != NULL) { + const int32_t numMerges = spec->merges->size(); + for (int32_t i = 0; i < numMerges; i++) + registerMerge((*spec->merges)[i]); + } + _CLDELETE(spec); +} + +MergePolicy::OneMerge *IndexWriter::getNextMerge() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (pendingMerges->size() == 0) + return NULL; + else { + // Advance the merge from pending to running + MergePolicy::OneMerge *_merge = *pendingMerges->begin(); + pendingMerges->pop_front(); + runningMerges->insert(_merge); + return _merge; + } +} + + +void IndexWriter::startTransaction() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (infoStream != NULL) + message(string("now start transaction")); + + CND_PRECONDITION(docWriter->getNumBufferedDeleteTerms() == 0, + "calling startTransaction with buffered delete terms not supported"); + CND_PRECONDITION(docWriter->getNumDocsInRAM() == 0, + "calling startTransaction with buffered documents not supported"); + + localRollbackSegmentInfos = segmentInfos->clone(); + localAutoCommit = autoCommit; + + if (localAutoCommit) { + + if (infoStream != NULL) + message(string("flush at startTransaction")); + + flush(); + // Turn off auto-commit during our local transaction: + autoCommit = false; + } else + // We must "protect" our files at this point from + // deletion in case we need to rollback: + deleter->incRef(segmentInfos, false); +} + +void IndexWriter::rollbackTransaction() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (infoStream != NULL) + message(string("now rollback transaction")); + + // First restore autoCommit in case we hit an exception below: + autoCommit = localAutoCommit; + + // Keep the same segmentInfos instance but replace all + // of its SegmentInfo instances. This is so the next + // attempt to commit using this instance of IndexWriter + // will always write to a _CLNEW generation ("write once"). + segmentInfos->clear(); + segmentInfos->insert(localRollbackSegmentInfos, true); + _CLDELETE(localRollbackSegmentInfos); + + // Ask deleter to locate unreferenced files we had + // created & remove them: + deleter->checkpoint(segmentInfos, false); + + if (!autoCommit) + // Remove the incRef we did in startTransaction: + deleter->decRef(segmentInfos); + + deleter->refresh(); + finishMerges(false); + stopMerges = false; +} + +void IndexWriter::commitTransaction() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (infoStream != NULL) + message(string("now commit transaction")); + + // First restore autoCommit in case we hit an exception below: + autoCommit = localAutoCommit; + + bool success = false; + try { + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception committing transaction")); + + rollbackTransaction(); + }) + + if (!autoCommit) + // Remove the incRef we did in startTransaction. + deleter->decRef(localRollbackSegmentInfos); + + _CLDELETE(localRollbackSegmentInfos); + + // Give deleter a chance to remove files now: + deleter->checkpoint(segmentInfos, autoCommit); +} + +void IndexWriter::abort() { + ensureOpen(); + if (autoCommit) + _CLTHROWA(CL_ERR_IllegalState, "abort() can only be called when IndexWriter was opened with autoCommit=false"); + + bool doClose; + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + // Ensure that only one thread actually gets to do the closing: + if (!closing) { + doClose = true; + closing = true; + } else + doClose = false; + } + + if (doClose) { + + finishMerges(false); + + // Must pre-close these two, in case they set + // commitPending=true, so that we can then set it to + // false before calling closeInternal + mergePolicy->close(); + mergeScheduler->close(); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + // Keep the same segmentInfos instance but replace all + // of its SegmentInfo instances. This is so the next + // attempt to commit using this instance of IndexWriter + // will always write to a _CLNEW generation ("write + // once"). + segmentInfos->clear(); + segmentInfos->insert(rollbackSegmentInfos, false); + + docWriter->abort(NULL); + + // Ask deleter to locate unreferenced files & remove + // them: + deleter->checkpoint(segmentInfos, false); + deleter->refresh(); + } + + commitPending = false; + closeInternal(false); + } else + waitForClose(); +} + +void IndexWriter::finishMerges(bool waitForMerges) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (!waitForMerges) { + + stopMerges = true; + + // Abort all pending & running merges: + for (PendingMergesType::iterator it = pendingMerges->begin(); + it != pendingMerges->end(); it++) { + MergePolicy::OneMerge *_merge = *it; + if (infoStream != NULL) + message("now abort pending merge " + _merge->segString(directory)); + _merge->abort(); + mergeFinish(_merge); + + it++; + } + pendingMerges->clear(); + + for (RunningMergesType::iterator it = runningMerges->begin(); + it != runningMerges->end(); it++) { + MergePolicy::OneMerge *_merge = *it; + if (infoStream != NULL) + message("now abort running merge " + _merge->segString(directory)); + _merge->abort(); + + it++; + } + + // These merges periodically check whether they have + // been aborted, and stop if so. We wait here to make + // sure they all stop. It should not take very int64_t + // because the merge threads periodically check if + // they are aborted. + while (runningMerges->size() > 0) { + if (infoStream != NULL) + message(string("now wait for ") + Misc::toString((int32_t) runningMerges->size()) + " running merge to abort"); + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } + + assert(0 == mergingSegments->size()); + + if (infoStream != NULL) + message(string("all running merges have aborted")); + + } else { + while (pendingMerges->size() > 0 || runningMerges->size() > 0) { + CONDITION_WAIT(THIS_LOCK, THIS_WAIT_CONDITION) + } + assert(0 == mergingSegments->size()); + } +} + +void IndexWriter::checkpoint() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (autoCommit) { + segmentInfos->write(directory); + commitPending = false; + if (infoStream != NULL) + message("checkpoint: wrote segments file \"" + segmentInfos->getCurrentSegmentFileName() + "\""); + } else { + commitPending = true; + } +} + +void IndexWriter::addIndexes(CL_NS(util)::ArrayBase &dirs) { + + ensureOpen(); + + // Do not allow add docs or deletes while we are running: + docWriter->pauseAllThreads(); + + try { + + if (infoStream != NULL) + message(string("flush at addIndexes")); + flush(); + + bool success = false; + + startTransaction(); + + try { + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + for (int32_t i = 0; i < dirs.length; i++) { + SegmentInfos sis;// read infos from dir + sis.read(dirs[i]); + segmentInfos->insert(&sis, true);// add each info + } + } + + optimize(); + + success = true; + } + _CLFINALLY( + if (success) { + commitTransaction(); + } else { + rollbackTransaction(); + }) + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } + _CLFINALLY( + docWriter->resumeAllThreads();) +} + +void IndexWriter::resetMergeExceptions() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + mergeExceptions->clear(); + mergeGen++; +} + +void IndexWriter::indexCompaction(std::vector &src_dirs, + std::vector dest_dirs, + std::vector>> trans_vec, + std::vector dest_index_docs) { + CND_CONDITION(src_dirs.size() > 0, "Source directory not found."); + CND_CONDITION(dest_dirs.size() > 0, "Destination directory not found."); + this->_trans_vec = trans_vec; + + // order mapping: dir -> segment info -> segment reader + addIndexesSegments(src_dirs); + + // create segment readers + int32_t totDocCount = 0; + int numSegments = segmentInfos->size(); + assert(numSegments > 0); + + //Set of IndexReaders + if (infoStream != NULL) { + message(string("src index dir size: ") + Misc::toString(numSegments)); + } + for (int32_t i = 0; i < numSegments; i++) { + SegmentInfo *si = segmentInfos->info(i); + IndexReader *reader = SegmentReader::get(si, MERGE_READ_BUFFER_SIZE, false /* mergeDocStores */); + readers.push_back(reader); + totDocCount += reader->numDocs(); + if (infoStream != NULL) { + message(src_dirs[i]->toString()); + } + } + if (infoStream != NULL) { + message(string("index compaction total doc count: ") + Misc::toString(totDocCount)); + } + + numDestIndexes = dest_dirs.size(); + + // print dest index files + if (infoStream != NULL) { + message(string("dest index size: ") + Misc::toString(numDestIndexes)); + for (auto dest: dest_dirs) { + message(dest->toString()); + } + } + + // init new segment infos + std::vector newSegmentInfos; + SegmentInfo *newSegment = nullptr; + std::string docStoreSegment; + docStoreSegment.clear(); + + std::vector destIndexWriterList; + try { + /// merge fields + mergeFields(); + + /// write fields and create files writers + for (int j = 0; j < numDestIndexes; j++) { + auto dest_dir = dest_dirs[j]; + /// create dest index writers + auto index_writer = _CLNEW IndexWriter(dest_dir, analyzer, true, true); + destIndexWriterList.push_back(index_writer); + + std::string segment = index_writer->newSegmentName(); + // create segment info + newSegment = _CLNEW SegmentInfo(segment.c_str(), + (int) dest_index_docs[j], + dest_dir, false, true, + 0, docStoreSegment.c_str(), + false); + newSegmentInfos.push_back(newSegment); + + /// write fields + writeFields(dest_dir, segment); + + /// create file writers + // Open an IndexOutput to the new Frequency File + IndexOutput *freqOut = dest_dir->createOutput((Misc::segmentname(segment.c_str(), ".frq").c_str())); + freqOutputList.push_back(freqOut); + // Open an IndexOutput to the new Prox File + IndexOutput *proxOut = nullptr; + if (0) { + proxOut = dest_dir->createOutput(Misc::segmentname(segment.c_str(), ".prx").c_str()); + } + proxOutputList.push_back(proxOut); + // Instantiate a new termInfosWriter which will write in directory + // for the segment name segment using the new merged fieldInfos + TermInfosWriter *termInfosWriter = _CLNEW TermInfosWriter(dest_dir, segment.c_str(), fieldInfos, termIndexInterval); + termInfosWriterList.push_back(termInfosWriter); + // skipList writer + skipInterval = termInfosWriter->skipInterval; + maxSkipLevels = termInfosWriter->maxSkipLevels; + skipListWriterList.push_back(_CLNEW DefaultSkipListWriter(skipInterval, maxSkipLevels, (int) dest_index_docs[j], freqOutputList[j], proxOutputList[j])); + } + + /// merge terms + mergeTerms(); + } catch (CLuceneError &e) { + throw e; + } + _CLFINALLY( + for (auto freqOutput + : freqOutputList) { + if (freqOutput != NULL) { + freqOutput->close(); + _CLDELETE(freqOutput); + } + } freqOutputList.clear(); + for (auto proxOutput + : proxOutputList) { + if (proxOutput != NULL) { + proxOutput->close(); + _CLDELETE(proxOutput); + } + } proxOutputList.clear(); + for (auto termInfosWriter + : termInfosWriterList) { + if (termInfosWriter != NULL) { + termInfosWriter->close(); + _CLDELETE(termInfosWriter); + } + } termInfosWriterList.clear(); + for (auto skipListWriter + : skipListWriterList) { + if (skipListWriter != NULL) { + _CLDELETE(skipListWriter); + } + } skipListWriterList.clear(); + for (auto r + : readers) { + if (r != NULL) { + r->close(); + _CLDELETE(r); + } + } readers.clear();); + + // update segment infos of dest index_writer in memory + // close dest index writer + for (int i = 0; i < numDestIndexes; i++) { + auto index_writer = destIndexWriterList[i]; + index_writer->getSegmentInfos()->setElementAt(newSegmentInfos[i], 0); + // close + index_writer->close(); + _CLDELETE(index_writer); + } + destIndexWriterList.clear(); + + // delete segment infos + newSegmentInfos.clear(); +} + +bool IndexWriter::compareIndexes(lucene::store::Directory *other) { + /// compare merged segments + // index compaction segments + // term -> + std::map> merged_map; + if (segmentInfos->size() == 0) { + // reload segment infos from directory + segmentInfos->read(directory); + } + + std::vector index_readers; + int32_t totDocCount = 0; + for (int32_t i = 0; i < segmentInfos->size(); i++) { + SegmentInfo *si = segmentInfos->info(i); + IndexReader *reader = SegmentReader::get(si, MERGE_READ_BUFFER_SIZE, false /* mergeDocStores */); + index_readers.push_back(reader); + totDocCount += reader->numDocs(); + } + + lucene::index::IndexReader *merged_reader = index_readers[0]; + lucene::index::TermEnum *m_term_enum = merged_reader->terms(); + while (m_term_enum->next()) { + lucene::index::Term *t = m_term_enum->term(); + lucene::index::TermPositions *postings = merged_reader->termPositions(); + postings->seek(t); + std::pair p; + while (postings->next()) { + int doc = postings->doc(); + int freq = postings->freq(); + p.first = doc; + p.second = freq; + } + merged_map.emplace(t, p); + } + + // new write segments + std::map> new_map; + lucene::index::SegmentInfos *new_sis; + new_sis->read(other); + + std::vector new_index_readers; + int32_t newTotCount = 0; + for (int32_t i = 0; i < new_sis->size(); i++) { + SegmentInfo *si = new_sis->info(i); + IndexReader *reader = SegmentReader::get(si, MERGE_READ_BUFFER_SIZE, false /* mergeDocStores */); + new_index_readers.push_back(reader); + newTotCount += reader->numDocs(); + } + + if (totDocCount != newTotCount) { + _CLTHROWA(CL_ERR_CorruptIndex, (string("docs count is not equal totCount(") + Misc::toString(totDocCount) + + "), newTotCount(" + Misc::toString(newTotCount) + " )") + .c_str()); + } + + lucene::index::IndexReader *new_reader = new_index_readers[0]; + lucene::index::TermEnum *n_term_enum = new_reader->terms(); + while (n_term_enum->next()) { + lucene::index::Term *t = n_term_enum->term(); + lucene::index::TermPositions *postings = new_reader->termPositions(); + postings->seek(t); + std::pair p; + while (postings->next()) { + int doc = postings->doc(); + int freq = postings->freq(); + p.first = doc; + p.second = freq; + } + new_map.emplace(t, p); + } + + // compare + for (auto m: merged_map) { + lucene::index::Term *t = m.first; + int doc = m.second.first; + int freq = m.second.second; + auto it = new_map.find(t); + if (it != new_map.end()) { + auto new_t = it->first; + auto new_doc = it->second.first; + auto new_freq = it->second.second; + if (t->compareTo(new_t) != 0) { + _CLTHROWA(CL_ERR_CorruptIndex, (string("term is not same, term(") + Misc::toString(t->toString()) + + "), new_term(" + Misc::toString(new_t->toString()) + " )") + .c_str()); + } + if (doc != new_doc) { + _CLTHROWA(CL_ERR_CorruptIndex, (string("doc is not equal, term(") + Misc::toString(t->toString()) + + "), doc(" + Misc::toString(doc) + "); new_term(" + Misc::toString(new_t->toString()) + " ), new_doc(" + Misc::toString(new_doc) + ")") + .c_str()); + } + if (freq != new_freq) { + _CLTHROWA(CL_ERR_CorruptIndex, (string("freq is not equal, term(") + Misc::toString(t->toString()) + + "), freq(" + Misc::toString(freq) + "); new_term(" + Misc::toString(new_t->toString()) + " ), new_freq(" + Misc::toString(new_freq) + ")") + .c_str()); + } + } else { + _CLTHROWA(CL_ERR_CorruptIndex, (string("not found term(") + Misc::toString(t->toString())).c_str()); + } + } +} + +void IndexWriter::addIndexesSegments(std::vector &dirs) { + ensureOpen(); + try { + if (infoStream != NULL) + message(string("add indexes segments")); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + for (auto dir: dirs) { + SegmentInfos sis;// read infos from dir + sis.read(dir); + segmentInfos->insert(&sis, true); + } + } + } catch (CLuceneError &e) { + throw e; + } +} + +void IndexWriter::mergeFields() { + //Create a new FieldInfos + fieldInfos = _CLNEW FieldInfos(); + //Condition check to see if fieldInfos points to a valid instance + CND_CONDITION(fieldInfos != NULL, "Memory allocation for fieldInfos failed"); + + //Condition check to see if reader points to a valid instanceL + CND_CONDITION(readers.size() == 0, "No IndexReader found"); + // fields of all readers are the same, so we pick the first one. + IndexReader *reader = readers[0]; + + if (reader->instanceOf(SegmentReader::getClassName())) { + SegmentReader *segmentReader = (SegmentReader *) reader; + for (size_t j = 0; j < segmentReader->getFieldInfos()->size(); j++) { + FieldInfo *fi = segmentReader->getFieldInfos()->fieldInfo(j); + fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, + fi->storePositionWithTermVector, fi->storeOffsetWithTermVector, + !reader->hasNorms(fi->name), fi->storePayloads); + } + } +} + +void IndexWriter::writeFields(lucene::store::Directory *d, std::string segment) { + //Write the new FieldInfos file to the directory + fieldInfos->write(d, Misc::segmentname(segment.c_str(), ".fnm").c_str()); +} + +void IndexWriter::mergeTerms() { + auto numSrcIndexes = readers.size(); + // get termEnum of all readers + std::vector termEnumList(numSrcIndexes); + // get termPositions of all readers + std::vector postingsList(numSrcIndexes); + for (int i = 0; i < numSrcIndexes; ++i) { + auto reader = readers[i]; + TermEnum *te = reader->terms(); + // move the pointer to the first term in enum. + te->next(); + termEnumList[i] = te; + postingsList[i] = reader->termPositions(); + } + + while (true) { + // smallest term + Term *smallestTerm = nullptr; + Term *currTerm = nullptr; + // 1. find the smallest term + for (int i = 0; i < numSrcIndexes; ++i) { + TermEnum *termEnum = termEnumList[i]; + currTerm = termEnum->term(); + // iterate to the enum end + if (currTerm == nullptr) { + continue; + } + if (infoStream != NULL) { + auto ts = currTerm->toString(); + message(string("current term: ") + Misc::toString(ts)); + _CLDELETE(ts); + } + if (smallestTerm == nullptr) { + smallestTerm = currTerm; + } else { + if (currTerm->compareTo(smallestTerm) < 0) { + _CLDECDELETE(smallestTerm); + smallestTerm = currTerm; + } else { + _CLDECDELETE(currTerm); + } + } + } + + // stop loop when there is no term left + if (smallestTerm == nullptr) { + break; + } + + // smallest term's field can not be blank string, but value can be empty. + assert(smallestTerm->field() != LUCENE_BLANK_STRING); + + if (infoStream != NULL) { + auto ts = smallestTerm->toString(); + message(string("smallest term: ") + Misc::toString(ts)); + _CLDELETE(ts); + } + + // 2. construct dest_idx_bitmap + // dest_idx -> docId + std::vector dest_idx_bitmap(numDestIndexes); + + for (int i = 0; i < numSrcIndexes; ++i) { + // check whether current term is equal to smallest term + TermEnum *termEnum = termEnumList[i]; + Term *cTerm = termEnum->term(); + if (cTerm == nullptr) { + continue; + } + if (!cTerm->equals(smallestTerm)) { + _CLDECDELETE(cTerm); + continue; + } + _CLDECDELETE(cTerm); + + // advance termEnum + termEnum->next(); + + // get an unpositioned TermPositions enumerator. + TermPositions *postings = postingsList[i]; + // Sets this to the data for a term. + postings->seek(smallestTerm); + + while (postings->next()) { + // get src doc id number + int srcDoc = postings->doc(); + std::pair p = _trans_vec[i][srcDoc]; + uint32_t destIdx = p.first; + uint32_t destDocId = p.second; + + // add to bitmap + dest_idx_bitmap[destIdx].add(destDocId); + } + } + + if (infoStream != NULL) { + message(string("bitmap list size: ") + Misc::toString(dest_idx_bitmap.size())); + } + + // 3. append term data + for (int i = 0; i < numDestIndexes; ++i) { + DefaultSkipListWriter *skipListWriter = skipListWriterList[i]; + CL_NS(store)::IndexOutput *freqOutput = freqOutputList[i]; + CL_NS(store)::IndexOutput *proxOutput = proxOutputList[i]; + TermInfosWriter *termInfosWriter = termInfosWriterList[i]; + + Roaring destBitmap = dest_idx_bitmap[i]; + + int32_t docNums = destBitmap.cardinality(); + if (docNums <= 0) { + continue; + } + + if (infoStream != NULL) { + message(string("the [") + Misc::toString(i) + string("] bitmap doc number: ") + Misc::toString(docNums)); + } + + // Get the file pointer of the IndexOutput to the Frequency File + int64_t freqPointer = freqOutput->getFilePointer(); + // Get the file pointer of the IndexOutput to the Prox File + int64_t proxPointer = 0; + if (proxOutput != nullptr) { + proxPointer = proxOutput->getFilePointer(); + } + + // append postings + int32_t lastDoc = 0; + int32_t df = 0;//docNums;// document frequency + + skipListWriter->resetSkip(); + + bool storePayloads = fieldInfos->fieldInfo(smallestTerm->field())->storePayloads; + int32_t lastPayloadLength = -1;// ensures that we write the first length + + // go through the bitmap + for (auto it = destBitmap.begin(); it != destBitmap.end(); ++it) { + // dest doc id + int32_t doc = *it; + + //Condition check to see doc is eaqual to or bigger than lastDoc + if (doc < 0 || (df > 0 && doc > 0 && doc <= lastDoc)) { + _CLTHROWA(CL_ERR_CorruptIndex, (string("docs out of order (") + Misc::toString(doc) + + " <= " + Misc::toString(lastDoc) + " )") + .c_str()); + } + + if ((++df % skipInterval) == 0) { + skipListWriter->setSkipData(lastDoc, storePayloads, lastPayloadLength); + skipListWriter->bufferSkip(df); + } + + //Calculate a new docCode + //use low bit to flag freq=1 + int32_t docCode = (doc - lastDoc) << 1; + lastDoc = doc; + + docDeltaBuffer.push_back(doc); + + if (docDeltaBuffer.size() == PFOR_BLOCK_SIZE) { + std::vector compresseddata(4 * docDeltaBuffer.size() + PFOR_BLOCK_SIZE); + auto size = P4ENC(docDeltaBuffer.data(), docDeltaBuffer.size(), compresseddata.data()); + freqOutput->writeVInt(docDeltaBuffer.size()); + freqOutput->writeVInt(size); + freqOutput->writeBytes(reinterpret_cast(compresseddata.data()), size); + docDeltaBuffer.resize(0); + } + + /// write positions + /** See {@link DocumentWriter#writePostings(Posting[], String)} for + * documentation about the encoding of positions and payloads + */ + // TODO(luen): fix this when write position file + if (false) { + // int32_t lastPosition = 0; + // // write position deltas + // for (int32_t k = 0; k < freq; k++) { + // //Get the next position + // int32_t position = postings->nextPosition(); + // int32_t delta = position - lastPosition; + // if (storePayloads) { + // size_t payloadLength = postings->getPayloadLength(); + // if (payloadLength == lastPayloadLength) { + // proxOutput->writeVInt(delta * 2); + // } else { + // proxOutput->writeVInt(delta * 2 + 1); + // proxOutput->writeVInt(payloadLength); + // lastPayloadLength = payloadLength; + // } + // if (payloadLength > 0) { + // if ( payloadBuffer.length < payloadLength ){ + // payloadBuffer.resize(payloadLength); + // } + // postings->getPayload(payloadBuffer.values); + // proxOutput->writeBytes(payloadBuffer.values, payloadLength); + // } + // } else { + // proxOutput->writeVInt(delta); + // } + // lastPosition = position; + // } + } + } + + assert(df > 0); + // Done merging this term + freqOutput->writeVInt(docDeltaBuffer.size()); + uint32_t lDoc = 0; + for (auto &docDelta: docDeltaBuffer) { + freqOutput->writeVInt(docDelta - lDoc); + lDoc = docDelta; + } + docDeltaBuffer.resize(0); + int64_t skipPointer = skipListWriter->writeSkip(freqOutput); + + // write terms + TermInfo termInfo; + termInfo.set(df, freqPointer, proxPointer, (int32_t) (skipPointer - freqPointer)); + // Write a new TermInfo + termInfosWriter->add(smallestTerm, &termInfo); + } + // decrement term refcount + _CLDECDELETE(smallestTerm); + } + + // delete term enum list + for (auto te: termEnumList) { + te->close(); + _CLDELETE(te); + } + termEnumList.clear(); + + // delete term position list + for (auto tp: postingsList) { + tp->close(); + _CLDELETE(tp); + } +} + +void IndexWriter::addIndexesNoOptimize(CL_NS(util)::ArrayBase &dirs) { + ensureOpen(); + + // Do not allow add docs or deletes while we are running: + docWriter->pauseAllThreads(); + + try { + if (infoStream != NULL) + message(string("flush at addIndexesNoOptimize")); + flush(); + + bool success = false; + + startTransaction(); + + try { + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + for (int32_t i = 0; i < dirs.length; i++) { + if (directory == dirs[i]) { + // cannot add this index: segments may be deleted in merge before added + _CLTHROWA(CL_ERR_IllegalArgument, "Cannot add this index to itself"); + } + + SegmentInfos sis;// read infos from dir + sis.read(dirs[i]); + segmentInfos->insert(&sis, true); + } + } + + maybeMerge(); + + // If after merging there remain segments in the index + // that are in a different directory, just copy these + // over into our index. This is necessary (before + // finishing the transaction) to avoid leaving the + // index in an unusable (inconsistent) state. + copyExternalSegments(); + + success = true; + } + _CLFINALLY( + if (success) { + commitTransaction(); + } else { + rollbackTransaction(); + }) + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } + _CLFINALLY( + docWriter->resumeAllThreads();) +} + +void IndexWriter::copyExternalSegments() { + + bool any = false; + + while (true) { + SegmentInfo *info = NULL; + MergePolicy::OneMerge *_merge = NULL; + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + const int32_t numSegments = segmentInfos->size(); + for (int32_t i = 0; i < numSegments; i++) { + info = segmentInfos->info(i); + if (info->dir != directory) { + SegmentInfos *range = _CLNEW SegmentInfos; + segmentInfos->range(i, 1 + i, *range); + _merge = _CLNEW MergePolicy::OneMerge(range, info->getUseCompoundFile()); + break; + } + } + } + + if (_merge != NULL) { + if (registerMerge(_merge)) { + PendingMergesType::iterator p = std::find(pendingMerges->begin(), pendingMerges->end(), _merge); + pendingMerges->remove(p, true); + runningMerges->insert(_merge); + any = true; + merge(_merge); + } else + // This means there is a bug in the + // MergeScheduler. MergeSchedulers in general are + // not allowed to run a merge involving segments + // external to this IndexWriter's directory in the + // background because this would put the index + // into an inconsistent state (where segmentInfos + // has been written with such external segments + // that an IndexReader would fail to load). + _CLTHROWA(CL_ERR_Merge, (string("segment \"") + info->name + " exists in external directory yet the MergeScheduler executed the merge in a separate thread").c_str()); + } else + // No more external segments + break; + } + + if (any) + // Sometimes, on copying an external segment over, + // more merges may become necessary: + mergeScheduler->merge(this); +} + +void IndexWriter::doAfterFlush() { +} + +void IndexWriter::flush() { + flush(true, false); +} + +void IndexWriter::flush(bool triggerMerge, bool _flushDocStores) { + ensureOpen(); + + if (doFlush(_flushDocStores) && triggerMerge) + maybeMerge(); +} + +bool IndexWriter::doFlush(bool _flushDocStores) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + // Make sure no threads are actively adding a document + + // Returns true if docWriter is currently aborting, in + // which case we skip flushing this segment + /*if (docWriter->pauseAllThreads()) { + docWriter->resumeAllThreads(); + return false; + }*/ + + bool ret = false; + try { + + SegmentInfo *newSegment = NULL; + + const int32_t numDocs = docWriter->getNumDocsInRAM(); + //const int32_t numDocs = sdocWriter->getNumDocsInRAM(); + + + // Always flush docs if there are any + bool flushDocs = numDocs > 0; + + // With autoCommit=true we always must flush the doc + // stores when we flush + _flushDocStores |= autoCommit; + //string docStoreSegment = sdocWriter->getDocStoreSegment(); + string docStoreSegment = docWriter->getDocStoreSegment(); + if (docStoreSegment.empty()) + _flushDocStores = false; + + // Always flush deletes if there are any delete terms. + // TODO: when autoCommit=false we don't have to flush + // deletes with every flushed segment; we can save + // CPU/IO by buffering longer & flushing deletes only + // when they are full or writer is being closed. We + // have to fix the "applyDeletesSelectively" logic to + // apply to more than just the last flushed segment + //bool flushDeletes = sdocWriter->hasDeletes(); + bool flushDeletes = docWriter->hasDeletes(); + + if (infoStream != NULL) { + message(" flush: segment=" + docWriter->getSegment() + + " docStoreSegment=" + docWriter->getDocStoreSegment() + + " docStoreOffset=" + Misc::toString(docWriter->getDocStoreOffset()) + + " flushDocs=" + Misc::toString(flushDocs) + + " flushDeletes=" + Misc::toString(flushDeletes) + + " flushDocStores=" + Misc::toString(_flushDocStores) + + " numDocs=" + Misc::toString(numDocs) + + " numBufDelTerms=" + Misc::toString(docWriter->getNumBufferedDeleteTerms())); + message(" index before flush " + segString()); + } + + //int32_t docStoreOffset = sdocWriter->getDocStoreOffset(); + int32_t docStoreOffset = docWriter->getDocStoreOffset(); + + // docStoreOffset should only be non-zero when + // autoCommit == false + assert(!autoCommit || 0 == docStoreOffset); + + bool docStoreIsCompoundFile = false; + + // Check if the doc stores must be separately flushed + // because other segments, besides the one we are about + // to flush, reference it + //if (_flushDocStores && (!flushDocs || !sdocWriter->getSegment().compare(sdocWriter->getDocStoreSegment())==0 )) { + if (_flushDocStores && (!flushDocs || !docWriter->getSegment().compare(docWriter->getDocStoreSegment()) == 0)) { + // We must separately flush the doc store + if (infoStream != NULL) + message(" flush shared docStore segment " + docStoreSegment); + + docStoreIsCompoundFile = flushDocStores(); + _flushDocStores = false; + } + + //string segment = sdocWriter->getSegment(); + string segment = docWriter->getSegment(); + + // If we are flushing docs, segment must not be NULL: + assert(!segment.empty() || !flushDocs); + + if (flushDocs || flushDeletes) { + + SegmentInfos *rollback = NULL; + + if (flushDeletes) + rollback = segmentInfos->clone(); + + bool success = false; + + try { + if (flushDocs) { + + if (0 == docStoreOffset && _flushDocStores) { + // This means we are flushing doc stores + // with this segment, so it will not be shared + // with other segments + assert(!docStoreSegment.empty()); + assert(docStoreSegment.compare(segment) == 0); + docStoreOffset = -1; + docStoreIsCompoundFile = false; + docStoreSegment.clear(); + } + //int32_t flushedDocCount = sdocWriter->flush(_flushDocStores); + int32_t flushedDocCount = docWriter->flush(_flushDocStores); + + newSegment = _CLNEW SegmentInfo(segment.c_str(), + flushedDocCount, + directory, false, true, + docStoreOffset, docStoreSegment.c_str(), + docStoreIsCompoundFile); + segmentInfos->insert(newSegment); + } + + if (flushDeletes) + // we should be able to change this so we can + // buffer deletes longer and then flush them to + // multiple flushed segments, when + // autoCommit=false + applyDeletes(flushDocs); + + doAfterFlush(); + + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message("hit exception flushing segment " + segment); + + if (flushDeletes) { + + // Carefully check if any partial .del files + // should be removed: + const int32_t size = rollback->size(); + for (int32_t i = 0; i < size; i++) { + const string newDelFileName = segmentInfos->info(i)->getDelFileName(); + const string delFileName = rollback->info(i)->getDelFileName(); + if (!newDelFileName.empty() && newDelFileName.compare(delFileName) != 0) + deleter->deleteFile(newDelFileName.c_str()); + } + + // Fully replace the segmentInfos since flushed + // deletes could have changed any of the + // SegmentInfo instances: + segmentInfos->clear(); + assert(false);//test me.. + segmentInfos->insert(rollback, false); + + } else { + // Remove segment we added, if any: + if (newSegment != NULL && + segmentInfos->size() > 0 && + segmentInfos->info(segmentInfos->size() - 1) == newSegment) + segmentInfos->remove(segmentInfos->size() - 1); + } + if (flushDocs) {} + //sdocWriter->abort(NULL); + deletePartialSegmentsFile(); + deleter->checkpoint(segmentInfos, false); + + if (!segment.empty()) + deleter->refresh(segment.c_str()); + } else if (flushDeletes) + _CLDELETE(rollback);) + + deleter->checkpoint(segmentInfos, autoCommit); + + if (flushDocs && mergePolicy->useCompoundFile(segmentInfos, + newSegment)) { + success = false; + try { + docWriter->createCompoundFile(segment); + newSegment->setUseCompoundFile(true); + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message("hit exception creating compound file for newly flushed segment " + segment); + newSegment->setUseCompoundFile(false); + deleter->deleteFile((segment + "." + IndexFileNames::COMPOUND_FILE_EXTENSION).c_str()); + deletePartialSegmentsFile(); + }) + + deleter->checkpoint(segmentInfos, autoCommit); + } + + ret = true; + } + + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } + _CLFINALLY( + //docWriter->clearFlushPending(); + //docWriter->resumeAllThreads(); + ) + return ret; +} + +int64_t IndexWriter::ramSizeInBytes() { + ensureOpen(); + return docWriter->getRAMUsed(); +} + +int32_t IndexWriter::numRamDocs() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + return docWriter->getNumDocsInRAM(); +} + +int32_t IndexWriter::ensureContiguousMerge(MergePolicy::OneMerge *_merge) { + + int32_t first = segmentInfos->indexOf(_merge->segments->info(0)); + if (first == -1) + _CLTHROWA(CL_ERR_Merge, (string("could not find segment ") + _merge->segments->info(0)->name + " in current segments").c_str()); + + const int32_t numSegments = segmentInfos->size(); + + const int32_t numSegmentsToMerge = _merge->segments->size(); + for (int32_t i = 0; i < numSegmentsToMerge; i++) { + const SegmentInfo *info = _merge->segments->info(i); + + if (first + i >= numSegments || !segmentInfos->info(first + i)->equals(info)) { + if (segmentInfos->indexOf(info) == -1) + _CLTHROWA(CL_ERR_Merge, (string("MergePolicy selected a segment (") + info->name + ") that is not in the index").c_str()); + else + _CLTHROWA(CL_ERR_Merge, (string("MergePolicy selected non-contiguous segments to merge (") + _merge->getObjectName() + " vs " + segString() + "), which IndexWriter (currently) cannot handle").c_str()); + } + } + + return first; +} + +bool IndexWriter::commitMerge(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + assert(_merge->registerDone); + + if (hitOOM) + return false; + + if (infoStream != NULL) + message("commitMerge: " + _merge->segString(directory)); + + // If merge was explicitly aborted, or, if abort() or + // rollbackTransaction() had been called since our merge + // started (which results in an unqualified + // deleter->refresh() call that will remove any index + // file that current segments does not reference), we + // abort this merge + if (_merge->isAborted()) { + if (infoStream != NULL) + message("commitMerge: skipping merge " + _merge->segString(directory) + ": it was aborted"); + + assert(_merge->increfDone); + decrefMergeSegments(_merge); + deleter->refresh(_merge->info->name.c_str()); + return false; + } + + bool success = false; + + int32_t start; + + try { + SegmentInfos *sourceSegmentsClone = _merge->segmentsClone; + const SegmentInfos *sourceSegments = _merge->segments; + + start = ensureContiguousMerge(_merge); + if (infoStream != NULL) + message("commitMerge " + _merge->segString(directory)); + + // Carefully merge deletes that occurred after we + // started merging: + + BitVector *deletes = NULL; + int32_t docUpto = 0; + + const int32_t numSegmentsToMerge = sourceSegments->size(); + for (int32_t i = 0; i < numSegmentsToMerge; i++) { + const SegmentInfo *previousInfo = sourceSegmentsClone->info(i); + const SegmentInfo *currentInfo = sourceSegments->info(i); + + assert(currentInfo->docCount == previousInfo->docCount); + + const int32_t docCount = currentInfo->docCount; + + if (previousInfo->hasDeletions()) { + + // There were deletes on this segment when the merge + // started. The merge has collapsed away those + // deletes, but, if _CLNEW deletes were flushed since + // the merge started, we must now carefully keep any + // newly flushed deletes but mapping them to the _CLNEW + // docIDs. + + assert(currentInfo->hasDeletions()); + + // Load deletes present @ start of merge, for this segment: + BitVector previousDeletes(previousInfo->dir, previousInfo->getDelFileName().c_str()); + + if (!currentInfo->getDelFileName().compare(previousInfo->getDelFileName()) == 0) { + // This means this segment has had new deletes + // committed since we started the merge, so we + // must merge them: + if (deletes == NULL) + deletes = _CLNEW BitVector(_merge->info->docCount); + + BitVector currentDeletes(currentInfo->dir, currentInfo->getDelFileName().c_str()); + for (int32_t j = 0; j < docCount; j++) { + if (previousDeletes.get(j)) + assert(currentDeletes.get(j)); + else { + if (currentDeletes.get(j)) + deletes->set(docUpto); + docUpto++; + } + } + } else + docUpto += docCount - previousDeletes.count(); + + } else if (currentInfo->hasDeletions()) { + // This segment had no deletes before but now it + // does: + if (deletes == NULL) + deletes = _CLNEW BitVector(_merge->info->docCount); + BitVector currentDeletes(directory, currentInfo->getDelFileName().c_str()); + + for (int32_t j = 0; j < docCount; j++) { + if (currentDeletes.get(j)) + deletes->set(docUpto); + docUpto++; + } + + } else + // No deletes before or after + docUpto += currentInfo->docCount; + + _merge->checkAborted(directory); + } + + if (deletes != NULL) { + _merge->info->advanceDelGen(); + deletes->write(directory, _merge->info->getDelFileName().c_str()); + _CLDELETE(deletes); + } + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception creating merged deletes file")); + deleter->refresh(_merge->info->name.c_str()); + }) + + // Simple optimization: if the doc store we are using + // has been closed and is in now compound format (but + // wasn't when we started), then we will switch to the + // compound format as well: + const string mergeDocStoreSegment = _merge->info->getDocStoreSegment(); + if (!mergeDocStoreSegment.empty() && !_merge->info->getDocStoreIsCompoundFile()) { + const int32_t size = segmentInfos->size(); + for (int32_t i = 0; i < size; i++) { + const SegmentInfo *info = segmentInfos->info(i); + const string docStoreSegment = info->getDocStoreSegment(); + if (!docStoreSegment.empty() && + docStoreSegment.compare(mergeDocStoreSegment) == 0 && + info->getDocStoreIsCompoundFile()) { + _merge->info->setDocStoreIsCompoundFile(true); + break; + } + } + } + + success = false; + SegmentInfos *rollback = NULL; + try { + rollback = segmentInfos->clone(); + int32_t segmentssize = _merge->segments->size(); + for (int32_t i = 0; i < segmentssize; i++) { + segmentInfos->remove(start); + } + segmentInfos->add(_merge->info, start); + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success && rollback != NULL) { + if (infoStream != NULL) + message(string("hit exception when checkpointing after merge")); + segmentInfos->clear(); + segmentInfos->insert(rollback, true); + deletePartialSegmentsFile(); + deleter->refresh(_merge->info->name.c_str()); + } _CLDELETE(rollback);) + + if (_merge->optimize) + segmentsToOptimize->push_back(_merge->info); + + // Must checkpoint before decrefing so any newly + // referenced files in the _CLNEW merge->info are incref'd + // first: + deleter->checkpoint(segmentInfos, autoCommit); + + decrefMergeSegments(_merge); + + return true; +} + + +void IndexWriter::decrefMergeSegments(MergePolicy::OneMerge *_merge) { + const SegmentInfos *sourceSegmentsClone = _merge->segmentsClone; + const int32_t numSegmentsToMerge = sourceSegmentsClone->size(); + assert(_merge->increfDone); + _merge->increfDone = false; + for (int32_t i = 0; i < numSegmentsToMerge; i++) { + SegmentInfo *previousInfo = sourceSegmentsClone->info(i); + // Decref all files for this SegmentInfo (this + // matches the incref in mergeInit): + if (previousInfo->dir == directory) + deleter->decRef(previousInfo->files()); + } +} + +void IndexWriter::merge(MergePolicy::OneMerge *_merge) { + + assert(_merge->registerDone); + assert(!_merge->optimize || _merge->maxNumSegmentsOptimize > 0); + + bool success = false; + + try { + try { + try { + mergeInit(_merge); + + if (infoStream != NULL) + message("now merge\n merge=" + _merge->segString(directory) + "\n index=" + segString()); + + mergeMiddle(_merge); + success = true; + } catch (CLuceneError &e) { + if (e.number() != CL_ERR_MergeAborted) throw e; + _merge->setException(e); + addMergeException(_merge); + // We can ignore this exception, unless the merge + // involves segments from external directories, in + // which case we must throw it so, for example, the + // rollbackTransaction code in addIndexes* is + // executed. + if (_merge->isExternal) + throw e; + } + } + _CLFINALLY( + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + try { + + mergeFinish(_merge); + + if (!success) { + if (infoStream != NULL) + message(string("hit exception during merge")); + addMergeException(_merge); + if (_merge->info != NULL && segmentInfos->indexOf(_merge->info) == -1) + deleter->refresh(_merge->info->name.c_str()); + } + + // This merge (and, generally, any change to the + // segments) may now enable new merges, so we call + // merge policy & update pending merges. + if (success && !_merge->isAborted() && !closed && !closing) + updatePendingMerges(_merge->maxNumSegmentsOptimize, _merge->optimize); + } + _CLFINALLY( + RunningMergesType::iterator itr = runningMerges->find(_merge); + if (itr != runningMerges->end()) runningMerges->remove(itr); + // Optimize may be waiting on the final optimize + // merge to finish; and finishMerges() may be + // waiting for all merges to finish: + CONDITION_NOTIFYALL(THIS_WAIT_CONDITION)) + }) + } catch (std::bad_alloc &) { + hitOOM = true; + _CLTHROWA(CL_ERR_OutOfMemory, "Out of memory"); + } +} + +bool IndexWriter::registerMerge(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (_merge->registerDone) + return true; + + const int32_t count = _merge->segments->size(); + bool isExternal = false; + for (int32_t i = 0; i < count; i++) { + SegmentInfo *info = _merge->segments->info(i); + if (mergingSegments->find(info) != mergingSegments->end()) + return false; + if (segmentInfos->indexOf(info) == -1) + return false; + if (info->dir != directory) + isExternal = true; + } + + pendingMerges->push_back(_merge); + + if (infoStream != NULL) + message(string("add merge to pendingMerges: ") + _merge->segString(directory) + " [total " + Misc::toString((int32_t) pendingMerges->size()) + " pending]"); + + _merge->mergeGen = mergeGen; + _merge->isExternal = isExternal; + + // OK it does not conflict; now record that this merge + // is running (while synchronized) to avoid race + // condition where two conflicting merges from different + // threads, start + for (int32_t i = 0; i < count; i++) + mergingSegments->insert(mergingSegments->end(), _merge->segments->info(i)); + + // Merge is now registered + _merge->registerDone = true; + return true; +} + +void IndexWriter::mergeInit(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + bool success = false; + try { + _mergeInit(_merge); + success = true; + } + _CLFINALLY( + if (!success) { + mergeFinish(_merge); + RunningMergesType::iterator itr = runningMerges->find(_merge); + if (itr != runningMerges->end()) runningMerges->remove(itr); + }) +} + +void IndexWriter::_mergeInit(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + assert(testPoint("startMergeInit")); + + assert(_merge->registerDone); + + if (_merge->info != NULL) + // mergeInit already done + return; + + if (_merge->isAborted()) + return; + + const SegmentInfos *sourceSegments = _merge->segments; + const int32_t end = sourceSegments->size(); + + ensureContiguousMerge(_merge); + + // Check whether this merge will allow us to skip + // merging the doc stores (stored field & vectors). + // This is a very substantial optimization (saves tons + // of IO) that can only be applied with + // autoCommit=false. + + Directory *lastDir = directory; + string lastDocStoreSegment; + int32_t next = -1; + + bool mergeDocStores = false; + bool doFlushDocStore = false; + const string currentDocStoreSegment = docWriter->getDocStoreSegment(); + + // Test each segment to be merged: check if we need to + // flush/merge doc stores + for (int32_t i = 0; i < end; i++) { + SegmentInfo *si = sourceSegments->info(i); + + // If it has deletions we must merge the doc stores + if (si->hasDeletions()) + mergeDocStores = true; + + // If it has its own (private) doc stores we must + // merge the doc stores + if (-1 == si->getDocStoreOffset()) + mergeDocStores = true; + + // If it has a different doc store segment than + // previous segments, we must merge the doc stores + string docStoreSegment = si->getDocStoreSegment(); + if (docStoreSegment.empty()) + mergeDocStores = true; + else if (lastDocStoreSegment.empty()) + lastDocStoreSegment = docStoreSegment; + else if (!lastDocStoreSegment.compare(docStoreSegment) == 0) + mergeDocStores = true; + + // Segments' docScoreOffsets must be in-order, + // contiguous. For the default merge policy now + // this will always be the case but for an arbitrary + // merge policy this may not be the case + if (-1 == next) + next = si->getDocStoreOffset() + si->docCount; + else if (next != si->getDocStoreOffset()) + mergeDocStores = true; + else + next = si->getDocStoreOffset() + si->docCount; + + // If the segment comes from a different directory + // we must merge + if (lastDir != si->dir) + mergeDocStores = true; + + // If the segment is referencing the current "live" + // doc store outputs then we must merge + if (si->getDocStoreOffset() != -1 && !currentDocStoreSegment.empty() && si->getDocStoreSegment().compare(currentDocStoreSegment) == 0) + doFlushDocStore = true; + } + + int32_t docStoreOffset; + string docStoreSegment; + bool docStoreIsCompoundFile; + + if (mergeDocStores) { + docStoreOffset = -1; + docStoreSegment.clear(); + docStoreIsCompoundFile = false; + } else { + SegmentInfo *si = sourceSegments->info(0); + docStoreOffset = si->getDocStoreOffset(); + docStoreSegment = si->getDocStoreSegment(); + docStoreIsCompoundFile = si->getDocStoreIsCompoundFile(); + } + + if (mergeDocStores && doFlushDocStore) { + // SegmentMerger intends to merge the doc stores + // (stored fields, vectors), and at least one of the + // segments to be merged refers to the currently + // live doc stores. + + // TODO: if we know we are about to merge away these + // newly flushed doc store files then we should not + // make compound file out of them... + if (infoStream != NULL) + message(string("flush at merge")); + flush(false, true); + } + + // We must take a full copy at this point so that we can + // properly merge deletes in commitMerge() + _merge->segmentsClone = _merge->segments->clone(); + + for (int32_t i = 0; i < end; i++) { + SegmentInfo *si = _merge->segmentsClone->info(i); + + // IncRef all files for this segment info to make sure + // they are not removed while we are trying to merge-> + if (si->dir == directory) + deleter->incRef(si->files()); + } + + _merge->increfDone = true; + + _merge->mergeDocStores = mergeDocStores; + + // Bind a _CLNEW segment name here so even with + // ConcurrentMergePolicy we keep deterministic segment + // names. + _merge->info = _CLNEW SegmentInfo(newSegmentName().c_str(), 0, + directory, false, true, + docStoreOffset, + docStoreSegment.c_str(), + docStoreIsCompoundFile); + // Also enroll the merged segment into mergingSegments; + // this prevents it from getting selected for a merge + // after our merge is done but while we are building the + // CFS: + mergingSegments->insert(_merge->info); +} + +void IndexWriter::mergeFinish(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (_merge->increfDone) + decrefMergeSegments(_merge); + + assert(_merge->registerDone); + + const SegmentInfos *sourceSegments = _merge->segments; + const int32_t end = sourceSegments->size(); + for (int32_t i = 0; i < end; i++) {//todo: use iterator + MergingSegmentsType::iterator itr = mergingSegments->find(sourceSegments->info(i)); + if (itr != mergingSegments->end()) mergingSegments->remove(itr); + } + MergingSegmentsType::iterator itr = mergingSegments->find(_merge->info); + if (itr != mergingSegments->end()) mergingSegments->remove(itr); + _merge->registerDone = false; +} + +int32_t IndexWriter::mergeMiddle(MergePolicy::OneMerge *_merge) { + + _merge->checkAborted(directory); + + const string mergedName = _merge->info->name; + + int32_t mergedDocCount = 0; + + const SegmentInfos *sourceSegments = _merge->segments; + SegmentInfos *sourceSegmentsClone = _merge->segmentsClone; + const int32_t numSegments = sourceSegments->size(); + + if (infoStream != NULL) + message("merging " + _merge->segString(directory)); + + SegmentMerger merger(this, mergedName.c_str(), _merge); + + // This is try/finally to make sure merger's readers are + // closed: + + bool success = false; + + try { + int32_t totDocCount = 0; + + for (int32_t i = 0; i < numSegments; i++) { + SegmentInfo *si = sourceSegmentsClone->info(i); + IndexReader *reader = SegmentReader::get(si, MERGE_READ_BUFFER_SIZE, _merge->mergeDocStores);// no need to set deleter (yet) + merger.add(reader); + totDocCount += reader->numDocs(); + } + if (infoStream != NULL) { + message(string("merge: total ") + Misc::toString(totDocCount) + " docs"); + } + + _merge->checkAborted(directory); + + mergedDocCount = _merge->info->docCount = merger.merge(_merge->mergeDocStores); + + assert(mergedDocCount == totDocCount); + + success = true; + } + _CLFINALLY( + // close readers before we attempt to delete + // now-obsolete segments + merger.closeReaders(); + if (!success) { + if (infoStream != NULL) + message("hit exception during merge; now refresh deleter on segment " + mergedName); + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + addMergeException(_merge); + deleter->refresh(mergedName.c_str()); + } + }) + + if (!commitMerge(_merge)) + // commitMerge will return false if this merge was aborted + return 0; + + if (_merge->useCompoundFile) { + + success = false; + bool skip = false; + const string compoundFileName = mergedName + "." + IndexFileNames::COMPOUND_FILE_EXTENSION; + + try { + try { + merger.createCompoundFile(compoundFileName.c_str()); + success = true; + } catch (CLuceneError &ioe) { + if (ioe.number() != CL_ERR_IO) throw ioe; + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + if (segmentInfos->indexOf(_merge->info) == -1) { + // If another merge kicked in and merged our + // _CLNEW segment away while we were trying to + // build the compound file, we can hit a + // FileNotFoundException and possibly + // IOException over NFS. We can tell this has + // happened because our SegmentInfo is no + // longer in the segments; if this has + // happened it is safe to ignore the exception + // & skip finishing/committing our compound + // file creating. + if (infoStream != NULL) + message("hit exception creating compound file; ignoring it because our info (segment " + _merge->info->name + ") has been merged away"); + skip = true; + } else + throw ioe; + } + } + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception creating compound file during merge: skip=") + Misc::toString(skip)); + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + if (!skip) + addMergeException(_merge); + deleter->deleteFile(compoundFileName.c_str()); + } + }) + + if (!skip) { + + { + SCOPED_LOCK_MUTEX(this->THIS_LOCK) + if (skip || segmentInfos->indexOf(_merge->info) == -1 || _merge->isAborted()) { + // Our segment (committed in non-compound + // format) got merged away while we were + // building the compound format. + deleter->deleteFile(compoundFileName.c_str()); + } else { + success = false; + try { + _merge->info->setUseCompoundFile(true); + checkpoint(); + success = true; + } + _CLFINALLY( + if (!success) { + if (infoStream != NULL) + message(string("hit exception checkpointing compound file during merge")); + + // Must rollback: + addMergeException(_merge); + _merge->info->setUseCompoundFile(false); + deletePartialSegmentsFile(); + deleter->deleteFile(compoundFileName.c_str()); + }) + + // Give deleter a chance to remove files now. + deleter->checkpoint(segmentInfos, autoCommit); + } + } + } + } + + return mergedDocCount; +} + +void IndexWriter::addMergeException(MergePolicy::OneMerge *_merge) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (mergeGen == _merge->mergeGen) { + MergeExceptionsType::iterator itr = mergeExceptions->begin(); + while (itr != mergeExceptions->end()) { + MergePolicy::OneMerge *x = *itr; + if (x == _merge) { + return; + } + } + } + mergeExceptions->push_back(_merge); +} + +void IndexWriter::deletePartialSegmentsFile() { + if (segmentInfos->getLastGeneration() != segmentInfos->getGeneration()) { + string segmentFileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS, + "", + segmentInfos->getGeneration()); + if (infoStream != NULL) + message("now delete partial segments file \"" + segmentFileName + "\""); + + deleter->deleteFile(segmentFileName.c_str()); + } +} + + +void IndexWriter::applyDeletes(bool flushedNewSegment) { + const TermNumMapType &bufferedDeleteTerms = docWriter->getBufferedDeleteTerms(); + const vector *bufferedDeleteDocIDs = docWriter->getBufferedDeleteDocIDs(); + + if (infoStream != NULL) + message(string("flush ") + Misc::toString(docWriter->getNumBufferedDeleteTerms()) + + " buffered deleted terms and " + Misc::toString((int32_t) bufferedDeleteDocIDs->size()) + + " deleted docIDs on " + Misc::toString((int32_t) segmentInfos->size()) + " segments."); + + if (flushedNewSegment) { + IndexReader *reader = NULL; + try { + // Open readers w/o opening the stored fields / + // vectors because these files may still be held + // open for writing by docWriter + reader = SegmentReader::get(segmentInfos->info(segmentInfos->size() - 1), false); + + // Apply delete terms to the segment just flushed from ram + // apply appropriately so that a delete term is only applied to + // the documents buffered before it, not those buffered after it. + _internal->applyDeletesSelectively(bufferedDeleteTerms, *bufferedDeleteDocIDs, reader); + } + _CLFINALLY( + if (reader != NULL) { + try { + reader->doCommit(); + } + _CLFINALLY( + reader->doClose(); + _CLLDELETE(reader);) + }) + } + + int32_t infosEnd = segmentInfos->size(); + if (flushedNewSegment) { + infosEnd--; + } + + for (int32_t i = 0; i < infosEnd; i++) { + IndexReader *reader = NULL; + try { + reader = SegmentReader::get(segmentInfos->info(i), false); + + // Apply delete terms to disk segments + // except the one just flushed from ram. + _internal->applyDeletes(bufferedDeleteTerms, reader); + } + _CLFINALLY( + if (reader != NULL) { + try { + reader->doCommit(); + } + _CLFINALLY( + reader->doClose();) + }) + } + + // Clean up bufferedDeleteTerms. + docWriter->clearBufferedDeletes(); +} + + +int32_t IndexWriter::getBufferedDeleteTermsSize() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return docWriter->getBufferedDeleteTerms().size(); +} + +int32_t IndexWriter::getNumBufferedDeleteTerms() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return docWriter->getNumBufferedDeleteTerms(); +} + +void IndexWriter::Internal::applyDeletesSelectively(const TermNumMapType &deleteTerms, + const vector &deleteIds, IndexReader *reader) { + TermNumMapType::const_iterator iter = deleteTerms.begin(); + while (iter != deleteTerms.end()) { + Term *term = iter->first; + TermDocs *docs = reader->termDocs(term); + if (docs != NULL) { + int32_t num = iter->second->getNum(); + try { + while (docs->next()) { + int32_t doc = docs->doc(); + if (doc >= num) { + break; + } + reader->deleteDocument(doc); + } + } + _CLFINALLY( + docs->close(); + _CLDELETE(docs);) + } + + iter++; + } + + if (deleteIds.size() > 0) { + vector::const_iterator iter2 = deleteIds.begin(); + while (iter2 != deleteIds.end()) { + reader->deleteDocument(*iter2); + ++iter2; + } + } +} + +void IndexWriter::Internal::applyDeletes(const TermNumMapType &deleteTerms, IndexReader *reader) { + TermNumMapType::const_iterator iter = deleteTerms.begin(); + while (iter != deleteTerms.end()) { + reader->deleteDocuments(iter->first); + iter++; + } +} + +SegmentInfo *IndexWriter::newestSegment() { + return segmentInfos->info(segmentInfos->size() - 1); +} + +string IndexWriter::segString() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + std::string buffer; + for (int32_t i = 0; i < segmentInfos->size(); i++) { + if (i > 0) { + buffer += " "; + } + buffer += segmentInfos->info(i)->segString(directory); + } + + return buffer; +} + +bool IndexWriter::testPoint(const char *name) { + return true; +} + +CL_NS_END diff --git a/src/core/CLucene/index/IndexWriter.h b/src/core/CLucene/index/IndexWriter.h new file mode 100644 index 00000000000..8cd24f04d06 --- /dev/null +++ b/src/core/CLucene/index/IndexWriter.h @@ -0,0 +1,1370 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_IndexWriter_ +#define _lucene_index_IndexWriter_ + +#include "CLucene/util/VoidList.h" +#include "CLucene/util/Array.h" + +CL_CLASS_DEF(search,Similarity) +CL_CLASS_DEF(store,Lock) +CL_CLASS_DEF(analysis,Analyzer) +CL_CLASS_DEF(analysis,SAnalyzer) +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(store,LuceneLock) +CL_CLASS_DEF(document,Document) + +#include "MergePolicy.h" +#include "CLucene/LuceneThreads.h" +#include "CLucene/store/IndexOutput.h" + +CL_NS_DEF(index) +class SegmentInfo; +class SegmentInfos; +class MergePolicy; +class IndexReader; +class SegmentReader; +class MergeScheduler; +class IDocumentsWriter; +template +class SDocumentsWriter; +class IndexFileDeleter; +class LogMergePolicy; +class IndexDeletionPolicy; +class Term; +class FieldInfos; +class TermInfosWriter; +class DefaultSkipListWriter; +class TermInfo; + +/** + An IndexWriter creates and maintains an index. + +

The create argument to the + constructor + determines whether a new index is created, or whether an existing index is + opened. Note that you + can open an index with create=true even while readers are + using the index. The old readers will continue to search + the "point in time" snapshot they had opened, and won't + see the newly created index until they re-open. There are + also constructors + with no create argument which + will create a new index if there is not already an index at the + provided path and otherwise open the existing index.

+ +

In either case, documents are added with addDocument + and removed with deleteDocuments. + A document can be updated with updateDocument + (which just deletes and then adds the entire document). + When finished adding, deleting and updating documents, close should be called.

+ +

These changes are buffered in memory and periodically + flushed to the {@link Directory} (during the above method + calls). A flush is triggered when there are enough + buffered deletes (see {@link #setMaxBufferedDeleteTerms}) + or enough added documents since the last flush, whichever + is sooner. For the added documents, flushing is triggered + either by RAM usage of the documents (see {@link + #setRAMBufferSizeMB}) or the number of added documents. + The default is to flush when RAM usage hits 16 MB. For + best indexing speed you should flush by RAM usage with a + large RAM buffer. You can also force a flush by calling + {@link #flush}. When a flush occurs, both pending deletes + and added documents are flushed to the index. A flush may + also trigger one or more segment merges which by default + run with a background thread so as not to block the + addDocument calls (see below + for changing the {@link MergeScheduler}).

+ + +

The optional autoCommit argument to the + constructors + controls visibility of the changes to {@link IndexReader} instances reading the same index. + When this is false, changes are not + visible until {@link #close()} is called. + Note that changes will still be flushed to the + {@link org.apache.lucene.store.Directory} as new files, + but are not committed (no new segments_N file + is written referencing the new files) until {@link #close} is + called. If something goes terribly wrong (for example the + JVM crashes) before {@link #close()}, then + the index will reflect none of the changes made (it will + remain in its starting state). + You can also call {@link #abort()}, which closes the writer without committing any + changes, and removes any index + files that had been flushed but are now unreferenced. + This mode is useful for preventing readers from refreshing + at a bad time (for example after you've done all your + deletes but before you've done your adds). + It can also be used to implement simple single-writer + transactional semantics ("all or none").

+ +

When autoCommit is true then + every flush is also a commit ({@link IndexReader} + instances will see each flush as changes to the index). + This is the default, to match the behavior before 2.2. + When running in this mode, be careful not to refresh your + readers while optimize or segment merges are taking place + as this can tie up substantial disk space.

+ +

Regardless of autoCommit, an {@link + IndexReader} or {@link org.apache.lucene.search.IndexSearcher} will only see the + index as of the "point in time" that it was opened. Any + changes committed to the index after the reader was opened + are not visible until the reader is re-opened.

+ +

If an index will not have more documents added for a while and optimal search + performance is desired, then the optimize + method should be called before the index is closed.

+ +

Opening an IndexWriter creates a lock file for the directory in use. Trying to open + another IndexWriter on the same directory will lead to a + {@link LockObtainFailedException}. The {@link LockObtainFailedException} + is also thrown if an IndexReader on the same directory is used to delete documents + from the index.

+ + +

Expert: IndexWriter allows an optional + {@link IndexDeletionPolicy} implementation to be + specified. You can use this to control when prior commits + are deleted from the index. The default policy is {@link + KeepOnlyLastCommitDeletionPolicy} which removes all prior + commits as soon as a new commit is done (this matches + behavior before 2.2). Creating your own policy can allow + you to explicitly keep previous "point in time" commits + alive in the index for some time, to allow readers to + refresh to the new commit without having the old commit + deleted out from under them. This is necessary on + filesystems like NFS that do not support "delete on last + close" semantics, which Lucene's "point in time" search + normally relies on.

+ +

Expert: + IndexWriter allows you to separately change + the {@link MergePolicy} and the {@link MergeScheduler}. + The {@link MergePolicy} is invoked whenever there are + changes to the segments in the index. Its role is to + select which merges to do, if any, and return a {@link + MergePolicy.MergeSpecification} describing the merges. It + also selects merges to do for optimize(). (The default is + {@link LogByteSizeMergePolicy}. Then, the {@link + MergeScheduler} is invoked with the requested merges and + it decides when and how to run the merges. The default is + {@link ConcurrentMergeScheduler}.

+ */ +/* + * Clarification: Check Points (and commits) + * Being able to set autoCommit=false allows IndexWriter to flush and + * write new index files to the directory without writing a new segments_N + * file which references these new files. It also means that the state of + * the in memory SegmentInfos object is different than the most recent + * segments_N file written to the directory. + * + * Each time the SegmentInfos is changed, and matches the (possibly + * modified) directory files, we have a new "check point". + * If the modified/new SegmentInfos is written to disk - as a new + * (generation of) segments_N file - this check point is also an + * IndexCommitPoint. + * + * With autoCommit=true, every checkPoint is also a CommitPoint. + * With autoCommit=false, some checkPoints may not be commits. + * + * A new checkpoint always replaces the previous checkpoint and + * becomes the new "front" of the index. This allows the IndexFileDeleter + * to delete files that are referenced only by stale checkpoints. + * (files that were created since the last commit, but are no longer + * referenced by the "front" of the index). For this, IndexFileDeleter + * keeps track of the last non commit checkpoint. + */ +class CLUCENE_EXPORT IndexWriter:LUCENE_BASE { + bool isOpen; //indicates if the writers is open - this way close can be called multiple times + + // how to analyze text + CL_NS(analysis)::Analyzer* analyzer; + //CL_NS(analysis)::SAnalyzer* sanalyzer; + + CL_NS(search)::Similarity* similarity; // how to normalize + + bool closeDir; + bool closed; + bool closing; + + // Holds all SegmentInfo instances currently involved in + // merges + typedef CL_NS(util)::CLHashSet > MergingSegmentsType; + MergingSegmentsType* mergingSegments; + MergePolicy* mergePolicy; + MergeScheduler* mergeScheduler; + + typedef CL_NS(util)::CLLinkedList > PendingMergesType; + PendingMergesType* pendingMerges; + + typedef CL_NS(util)::CLHashSet, + CL_NS(util)::Deletor::Object > RunningMergesType; + RunningMergesType* runningMerges; + + typedef CL_NS(util)::CLArrayList MergeExceptionsType; + MergeExceptionsType* mergeExceptions; + int64_t mergeGen; + bool stopMerges; + + + /** If non-null, information about merges will be printed to this. + */ + std::ostream* infoStream; + static std::ostream* defaultInfoStream; + + + + bool commitPending; // true if segmentInfos has changes not yet committed + SegmentInfos* rollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails + + SegmentInfos* localRollbackSegmentInfos; // segmentInfos we will fallback to if the commit fails + bool localAutoCommit; // saved autoCommit during local transaction + bool autoCommit; // false if we should commit only on close + + IDocumentsWriter* docWriter; + //typedef SDocumentsWriter SDocumentsWriterType; + //SDocumentsWriterType *sdocWriter; + //lucene::index::SDocumentsWriter* sdocWriter; + IndexFileDeleter* deleter; + + typedef std::vector SegmentsToOptimizeType; + SegmentsToOptimizeType* segmentsToOptimize; // used by optimize to note those needing optimization + + + CL_NS(store)::LuceneLock* writeLock; + + void init(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, bool closeDir, IndexDeletionPolicy* deletionPolicy, bool autoCommit); + void init(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, bool create, bool closeDir, IndexDeletionPolicy* deletionPolicy, bool autoCommit); + void deinit(bool releaseWriteLock = true) throw(); + + // where this index resides + CL_NS(store)::Directory* directory; + bool bOwnsDirectory; + + + int32_t getSegmentsCounter(); + int32_t maxFieldLength; + int32_t mergeFactor; + int32_t minMergeDocs; + int32_t maxMergeDocs; + int32_t termIndexInterval; + + int64_t writeLockTimeout; + int64_t commitLockTimeout; + + // The normal read buffer size defaults to 1024, but + // increasing this during merging seems to yield + // performance gains. However we don't want to increase + // it too much because there are quite a few + // BufferedIndexInputs created during merging. See + // LUCENE-888 for details. + static const int32_t MERGE_READ_BUFFER_SIZE; + + // Used for printing messages + STATIC_DEFINE_MUTEX(MESSAGE_ID_LOCK) + static int32_t MESSAGE_ID; + int32_t messageID; + mutable bool hitOOM; + + // index compaction params + std::vector>> _trans_vec; + // dest indexes numbers + int32_t numDestIndexes; + std::vector readers; + //Field Infos for the FieldInfo instances of all fields + FieldInfos* fieldInfos; + // IndexOutput to the new Frequency File + std::vector freqOutputList; + // IndexOutput to the new Prox File + std::vector proxOutputList; + std::vector termInfosWriterList; + int32_t skipInterval; + int32_t maxSkipLevels; + std::vector skipListWriterList; + std::vector docDeltaBuffer; + +public: + DEFINE_MUTEX(THIS_LOCK) + DEFINE_CONDITION(THIS_WAIT_CONDITION) + + /** + * Compact src indices to dest indices, depend on doc id translation vector + * @param src_dirs source indices directories to read data + * @param dest_dirs destination indices directories to write new indices + * @param trans_vec translation vector + * the first level vector: + * index indicates index of source index, which is same order of src_dirs + * the second level vector: + * index indicates doc id of source index + * the pair: + * pair.first indicates index of destination index, which is same order of dest_dirs + * pair.second indicates doc id of destination index + * @param dest_index_docs destination indices doc count list + */ + void indexCompaction(std::vector& src_dirs, + std::vector dest_dirs, + std::vector>> trans_vec, + std::vector dest_index_docs); + + /** + * Merges all segments from an array of indexes into this index, just merging segment infos. + * Simplified from addIndexesNoOptimize(CL_NS(util)::ArrayBase& dirs) + * @param dirs + */ + void addIndexesSegments(std::vector& dirs); + + // create new fields info + void mergeFields(); + // write fields info file + void writeFields(lucene::store::Directory* d, std::string segment); + // merge terms and write files + void mergeTerms(); + + // Compare current index with the other + bool compareIndexes(lucene::store::Directory* other); + + // Release the write lock, if needed. + SegmentInfos* segmentInfos; + + // Release the write lock, if needed. + virtual ~IndexWriter(); + + void setDocumentWriter(IDocumentsWriter* doc_writer) { + docWriter = doc_writer; + } + + /** + * The Java implementation of Lucene silently truncates any tokenized + * field if the number of tokens exceeds a certain threshold. Although + * that threshold is adjustable, it is easy for the client programmer + * to be unaware that such a threshold exists, and to become its + * unwitting victim. + * CLucene implements a less insidious truncation policy. Up to + * DEFAULT_MAX_FIELD_LENGTH tokens, CLucene behaves just as JLucene + * does. If the number of tokens exceeds that threshold without any + * indication of a truncation preference by the client programmer, + * CLucene raises an exception, prompting the client programmer to + * explicitly set a truncation policy by adjusting maxFieldLength. + */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MAX_FIELD_LENGTH = 10000); + LUCENE_STATIC_CONSTANT(int32_t, FIELD_TRUNC_POLICY__WARN = -1); + + /** + * Returns the maximum number of terms that will be + * indexed for a single field in a document. + * @see #setMaxFieldLength + */ + int32_t getMaxFieldLength(); + /** + * The maximum number of terms that will be indexed for a single field in a + * document. This limits the amount of memory required for indexing, so that + * collections with very large files will not crash the indexing process by + * running out of memory. This setting refers to the number of running terms, + * not to the number of different terms.

+ * Note: see {@link DEFAULT_MAX_FIELD_LENGTH} for an important + * note regarding field lengths. + * @see #DEFAULT_MAX_FIELD_LENGTH + */ + void setMaxFieldLength(int32_t val); + + /** Determines the minimal number of documents required before the buffered + * in-memory documents are merging and a new Segment is created. + * Since Documents are merged in a {@link RAMDirectory}, + * large value gives faster indexing. At the same time, mergeFactor limits + * the number of files open in a FSDirectory. + * + *

The default value is DEFAULT_MAX_BUFFERED_DOCS.*/ + void setMaxBufferedDocs(int32_t val); + /** + * @see #setMaxBufferedDocs + */ + int32_t getMaxBufferedDocs(); + + /** + * Default value for the write lock timeout (1,000). + * @see #setDefaultWriteLockTimeout + */ + static int64_t WRITE_LOCK_TIMEOUT; + /** + * Sets the maximum time to wait for a write lock (in milliseconds). + */ + void setWriteLockTimeout(int64_t writeLockTimeout); + /** + * @see #setWriteLockTimeout + */ + int64_t getWriteLockTimeout(); + + /** + * Sets the maximum time to wait for a commit lock (in milliseconds). + */ + void setCommitLockTimeout(int64_t commitLockTimeout); + /** + * @see #setCommitLockTimeout + */ + int64_t getCommitLockTimeout(); + + /** + * Name of the write lock in the index. + */ + static const char* WRITE_LOCK_NAME; //"write.lock"; + + /** + * @deprecated + * @see LogMergePolicy#DEFAULT_MERGE_FACTOR + */ + static const int32_t DEFAULT_MERGE_FACTOR ; + + /** + * Value to denote a flush trigger is disabled + */ + static const int32_t DISABLE_AUTO_FLUSH; + + /** + * Disabled by default (because IndexWriter flushes by RAM usage + * by default). Change using {@link #setMaxBufferedDocs(int)}. + */ + static const int32_t DEFAULT_MAX_BUFFERED_DOCS; + + /** + * Default value is 16 MB (which means flush when buffered + * docs consume 16 MB RAM). Change using {@link #setRAMBufferSizeMB}. + */ + static const float_t DEFAULT_RAM_BUFFER_SIZE_MB; + + /** + * Disabled by default (because IndexWriter flushes by RAM usage + * by default). Change using {@link #setMaxBufferedDeleteTerms(int)}. + */ + static const int32_t DEFAULT_MAX_BUFFERED_DELETE_TERMS; + + /** + * @deprecated + * @see LogDocMergePolicy#DEFAULT_MAX_MERGE_DOCS + */ + static const int32_t DEFAULT_MAX_MERGE_DOCS; + + /** + * Absolute hard maximum length for a term. If a term + * arrives from the analyzer longer than this length, it + * is skipped and a message is printed to infoStream, if + * set (see {@link #setInfoStream}). + */ + static const int32_t MAX_TERM_LENGTH; + + + /* Determines how often segment indices are merged by addDocument(). With + * smaller values, less RAM is used while indexing, and searches on + * unoptimized indices are faster, but indexing speed is slower. With larger + * values more RAM is used while indexing and searches on unoptimized indices + * are slower, but indexing is faster. Thus larger values (> 10) are best + * for batched index creation, and smaller values (< 10) for indices that are + * interactively maintained. + * + *

This must never be less than 2. The default value is 10. + */ + int32_t getMergeFactor() const; + void setMergeFactor(int32_t val); + + + /** Expert: The fraction of terms in the "dictionary" which should be stored + * in RAM. Smaller values use more memory, but make searching slightly + * faster, while larger values use less memory and make searching slightly + * slower. Searching is typically not dominated by dictionary lookup, so + * tweaking this is rarely useful. + */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_TERM_INDEX_INTERVAL = 128); + /** Expert: Set the interval between indexed terms. Large values cause less + * memory to be used by IndexReader, but slow random-access to terms. Small + * values cause more memory to be used by an IndexReader, and speed + * random-access to terms. + * + * This parameter determines the amount of computation required per query + * term, regardless of the number of documents that contain that term. In + * particular, it is the maximum number of other terms that must be + * scanned before a term is located and its frequency and position information + * may be processed. In a large index with user-entered query terms, query + * processing time is likely to be dominated not by term lookup but rather + * by the processing of frequency and positional data. In a small index + * or when many uncommon query terms are generated (e.g., by wildcard + * queries) term lookup may become a dominant cost. + * + * In particular, numUniqueTerms/interval terms are read into + * memory by an IndexReader, and, on average, interval/2 terms + * must be scanned for each random term access. + * + * @see #DEFAULT_TERM_INDEX_INTERVAL + */ + void setTermIndexInterval(int32_t interval); + /** Expert: Return the interval between indexed terms. + * + * @see #setTermIndexInterval(int) + */ + int32_t getTermIndexInterval(); + + /**Determines the largest number of documents ever merged by addDocument(). + * Small values (e.g., less than 10,000) are best for interactive indexing, + * as this limits the length of pauses while indexing to a few seconds. + * Larger values are best for batched indexing and speedier searches. + * + *

The default value is {@link Integer#MAX_VALUE}. + */ + int32_t getMaxMergeDocs() const; + void setMaxMergeDocs(int32_t val); + + /** + * Constructs an IndexWriter for the index in path. + * Text will be analyzed with a. If create + * is true, then a new, empty index will be created in + * path, replacing the index already there, if any. + * + * @param path the path to the index directory + * @param a the analyzer to use + * @param create true to create the index or overwrite + * the existing one; false to append to the existing + * index + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if the directory cannot be read/written to, or + * if it does not exist and create is + * false or if there is any other low-level + * IO error + */ + explicit IndexWriter(const char* path, CL_NS(analysis)::Analyzer* a, const bool create); + + /** + * Constructs an IndexWriter for the index in d. + * Text will be analyzed with a. If create + * is true, then a new, empty index will be created in + * d, replacing the index already there, if any. + * + * @param d the index directory + * @param a the analyzer to use + * @param create true to create the index or overwrite + * the existing one; false to append to the existing + * index + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if the directory cannot be read/written to, or + * if it does not exist and create is + * false or if there is any other low-level + * IO error + */ + explicit IndexWriter(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, const bool create, const bool closeDirOnShutdown=false); + + /** + * Expert: constructs an IndexWriter with a custom {@link + * IndexDeletionPolicy}, for the index in d, + * first creating it if it does not already exist. Text + * will be analyzed with a. + * + * @param d the index directory + * @param autoCommit see above + * @param a the analyzer to use + * @param deletionPolicy see above + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if the directory cannot be + * read/written to or if there is any other low-level + * IO error + */ + explicit IndexWriter(CL_NS(store)::Directory* d, const bool autoCommit, CL_NS(analysis)::Analyzer* a, IndexDeletionPolicy* deletionPolicy = NULL, const bool closeDirOnShutdown=false); + + /** + * Expert: constructs an IndexWriter with a custom {@link + * IndexDeletionPolicy}, for the index in d. + * Text will be analyzed with a. If + * create is true, then a new, empty index + * will be created in d, replacing the index + * already there, if any. + * + * @param d the index directory + * @param autoCommit see above + * @param a the analyzer to use + * @param create true to create the index or overwrite + * the existing one; false to append to the existing + * index + * @param deletionPolicy see above + * @throws CorruptIndexException if the index is corrupt + * @throws LockObtainFailedException if another writer + * has this index open (write.lock could not + * be obtained) + * @throws IOException if the directory cannot be read/written to, or + * if it does not exist and create is + * false or if there is any other low-level + * IO error + */ + explicit IndexWriter(CL_NS(store)::Directory* d, const bool autoCommit, CL_NS(analysis)::Analyzer* a, const bool create, IndexDeletionPolicy* deletionPolicy = NULL, const bool closeDirOnShutdown=false); + + /**Returns the number of documents currently in this index. + * synchronized + */ + int32_t docCount(); + + + /** Returns the directory this index resides in. */ + CL_NS(store)::Directory* getDirectory(); + + /** Get the current setting of whether to use the compound file format. + * Note that this just returns the value you set with setUseCompoundFile(boolean) + * or the default. You cannot use this to query the status of an existing index. + * @see #setUseCompoundFile(boolean) + */ + bool getUseCompoundFile(); + + /** Setting to turn on usage of a compound file. When on, multiple files + * for each segment are merged into a single file once the segment creation + * is finished. This is done regardless of what directory is in use. + */ + void setUseCompoundFile(bool value); + + + /** Expert: Set the Similarity implementation used by this IndexWriter. + * + * @see Similarity#setDefault(Similarity) + */ + void setSimilarity(CL_NS(search)::Similarity* similarity); + + /** Expert: Return the Similarity implementation used by this IndexWriter. + * + *

This defaults to the current value of {@link Similarity#getDefault()}. + */ + CL_NS(search)::Similarity* getSimilarity(); + + /** Returns the analyzer used by this index. */ + CL_NS(analysis)::Analyzer* getAnalyzer(); + + // synchronized + std::string newSegmentName(); + + /** + * Prints a message to the infoStream (if non-null), + * prefixed with the identifying information for this + * writer and the thread that's calling it. + */ + void message(std::string message); + + /** + * Returns the current default infoStream for newly + * instantiated IndexWriters. + * @see #setDefaultInfoStream + */ + static std::ostream* getDefaultInfoStream(); + + /** + * Returns the current infoStream in use by this writer. + * @see #setInfoStream + */ + std::ostream* getInfoStream(); + + /** + * Returns the number of buffered deleted terms that will + * trigger a flush if enabled. + * @see #setMaxBufferedDeleteTerms + */ + int32_t getMaxBufferedDeleteTerms(); + + /** + * Expert: returns the current MergePolicy in use by this writer. + * @see #setMergePolicy + */ + MergePolicy* getMergePolicy(); + + /** + * Expert: returns the current MergePolicy in use by this + * writer. + * @see #setMergePolicy + */ + MergeScheduler* getMergeScheduler(); + + /** + * Returns the value set by {@link #setRAMBufferSizeMB} if enabled. + */ + float_t getRAMBufferSizeMB(); + + /** If non-null, this will be the default infoStream used + * by a newly instantiated IndexWriter. + * @see #setInfoStream + */ + static void setDefaultInfoStream(std::ostream* infoStream);\ + + /** If non-null, information about merges, deletes and a + * message when maxFieldLength is reached will be printed + * to this. + */ + void setInfoStream(std::ostream* infoStream); + + /** + *

Determines the minimal number of delete terms required before the buffered + * in-memory delete terms are applied and flushed. If there are documents + * buffered in memory at the time, they are merged and a new segment is + * created.

+ + *

Disabled by default (writer flushes by RAM usage).

+ * + * @throws IllegalArgumentException if maxBufferedDeleteTerms + * is enabled but smaller than 1 + * @see #setRAMBufferSizeMB + */ + void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); + + /** + * Expert: set the merge policy used by this writer. + */ + void setMergePolicy(MergePolicy* mp); + + /** + * Expert: set the merge scheduler used by this writer. + */ + void setMergeScheduler(MergeScheduler* mergeScheduler); + + /** Determines the amount of RAM that may be used for + * buffering added documents before they are flushed as a + * new Segment. Generally for faster indexing performance + * it's best to flush by RAM usage instead of document + * count and use as large a RAM buffer as you can. + * + *

When this is set, the writer will flush whenever + * buffered documents use this much RAM. Pass in {@link + * #DISABLE_AUTO_FLUSH} to prevent triggering a flush due + * to RAM usage. Note that if flushing by document count + * is also enabled, then the flush will be triggered by + * whichever comes first.

+ * + *

The default value is {@link #DEFAULT_RAM_BUFFER_SIZE_MB}.

+ * + * @throws IllegalArgumentException if ramBufferSize is + * enabled but non-positive, or it disables ramBufferSize + * when maxBufferedDocs is already disabled + */ + void setRAMBufferSizeMB(float_t mb); + + + /** Expert: the {@link MergeScheduler} calls this method + * to retrieve the next merge requested by the + * MergePolicy */ + MergePolicy::OneMerge* getNextMerge(); + + /** + * Merges the indicated segments, replacing them in the stack with a + * single segment. + */ + void merge(MergePolicy::OneMerge* merge); + + /** + * Deletes the document(s) containing term. + * @param term the term to identify the documents to be deleted + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void deleteDocuments(Term* term); + + /** + * Deletes the document(s) containing any of the + * terms. All deletes are flushed at the same time. + * @param terms array of terms to identify the documents + * to be deleted + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void deleteDocuments(const CL_NS(util)::ArrayBase* terms); + + /** + * Updates a document by first deleting the document(s) + * containing term and then adding the new + * document. The delete and then add are atomic as seen + * by a reader on the same index (flush may happen only after + * the add). + * @param term the term to identify the document(s) to be + * deleted + * @param doc the document to be added + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void updateDocument(Term* term, CL_NS(document)::Document* doc); + + /** + * Updates a document by first deleting the document(s) + * containing term and then adding the new + * document. The delete and then add are atomic as seen + * by a reader on the same index (flush may happen only after + * the add). + * @param term the term to identify the document(s) to be + * deleted + * @param doc the document to be added + * @param analyzer the analyzer to use when analyzing the document + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void updateDocument(Term* term, CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer); + + /** + * Returns default write lock timeout for newly + * instantiated IndexWriters. + * @see #setDefaultWriteLockTimeout + */ + int64_t getDefaultWriteLockTimeout(); + + /** + * Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock (in + * milliseconds). + */ + void setDefaultWriteLockTimeout(int64_t writeLockTimeout); + + std::string segString(); + + /** + * Closes the index with or without waiting for currently + * running merges to finish. This is only meaningful when + * using a MergeScheduler that runs merges in background + * threads. + * @param waitForMerges if true, this call will block + * until all merges complete; else, it will ask all + * running merges to abort, wait until those merges have + * finished (which should be at most a few seconds), and + * then return. + * + *

If an Exception is hit during close, eg due to disk + * full or some other reason, then both the on-disk index + * and the internal state of the IndexWriter instance will + * be consistent. However, the close will not be complete + * even though part of it (flushing buffered documents) + * may have succeeded, so the write lock will still be + * held.

+ * + *

If you can correct the underlying cause (eg free up + * some disk space) then you can call close() again. + * Failing that, if you want to force the write lock to be + * released (dangerous, because you may then lose buffered + * docs in the IndexWriter instance) then you can do + * something like this:

+ * + *
+   * try {
+   *   writer.close();
+   * } finally {
+   *   if (IndexReader.isLocked(directory)) {
+   *     IndexReader.unlock(directory);
+   *   }
+   * }
+   * 
+ * + * after which, you must be certain not to use the writer + * instance anymore.

+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void close(bool waitForMerges=true); + + /** + * Requests an "optimize" operation on an index, priming the index + * for the fastest available search. Traditionally this has meant + * merging all segments into a single segment as is done in the + * default merge policy, but individaul merge policies may implement + * optimize in different ways. + * + * @see LogMergePolicy#findMergesForOptimize + * + *

It is recommended that this method be called upon completion of indexing. In + * environments with frequent updates, optimize is best done during low volume times, if at all. + * + *

+ *

See http://www.gossamer-threads.com/lists/lucene/java-dev/47895 for more discussion.

+ * + *

Note that this can require substantial temporary free + * space in the Directory (see LUCENE-764 + * for details):

+ * + *
    + *
  • + * + *

    If no readers/searchers are open against the index, + * then free space required is up to 1X the total size of + * the starting index. For example, if the starting + * index is 10 GB, then you must have up to 10 GB of free + * space before calling optimize.

    + * + *
  • + * + *

    If readers/searchers are using the index, then free + * space required is up to 2X the size of the starting + * index. This is because in addition to the 1X used by + * optimize, the original 1X of the starting index is + * still consuming space in the Directory as the readers + * are holding the segments files open. Even on Unix, + * where it will appear as if the files are gone ("ls" + * won't list them), they still consume storage due to + * "delete on last close" semantics.

    + * + *

    Furthermore, if some but not all readers re-open + * while the optimize is underway, this will cause > 2X + * temporary space to be consumed as those new readers + * will then hold open the partially optimized segments at + * that time. It is best not to re-open readers while + * optimize is running.

    + * + *
+ * + *

The actual temporary usage could be much less than + * these figures (it depends on many factors).

+ * + *

In general, once the optimize completes, the total size of the + * index will be less than the size of the starting index. + * It could be quite a bit smaller (if there were many + * pending deletes) or just slightly smaller.

+ * + *

If an Exception is hit during optimize(), for example + * due to disk full, the index will not be corrupt and no + * documents will have been lost. However, it may have + * been partially optimized (some segments were merged but + * not all), and it's possible that one of the segments in + * the index will be in non-compound format even when + * using compound file format. This will occur when the + * Exception is hit during conversion of the segment into + * compound format.

+ * + *

This call will optimize those segments present in + * the index when the call started. If other threads are + * still adding documents and flushing segments, those + * newly created segments will not be optimized unless you + * call optimize again.

+ * + * @param doWait Specifies whether the call should block + * until the optimize completes. This is only meaningful + * with a {@link MergeScheduler} that is able to run merges + * in background threads. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void optimize(bool doWait=true); + + /** + * Optimize the index down to <= maxNumSegments. If + * maxNumSegments==1 then this is the same as {@link + * #optimize()}. + * @param maxNumSegments maximum number of segments left + * in the index after optimization finishes + * @param doWait Specifies whether the call should block + * until the optimize completes. This is only meaningful + * with a {@link MergeScheduler} that is able to run merges + * in background threads. + */ + void optimize(int32_t maxNumSegments, bool doWait=true); + + /** + * Flush all in-memory buffered updates (adds and deletes) + * to the Directory. + *

Note: if autoCommit=false, flushed data would still + * not be visible to readers, until {@link #close} is called. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void flush(); + + /** + * Adds a document to this index. If the document contains more than + * {@link #setMaxFieldLength(int)} terms for a given field, the remainder are + * discarded (depending on the policy, see #FIELD_TRUNC_POLICY__WARN) + * + *

Note that if an Exception is hit (for example disk full) + * then the index will be consistent, but this document + * may not have been added. Furthermore, it's possible + * the index will have one segment in non-compound format + * even when using compound files (when a merge has + * partially succeeded).

+ * + *

This method periodically flushes pending documents + * to the Directory (every {@link #setMaxBufferedDocs}), + * and also periodically merges segments in the index + * (every {@link #setMergeFactor} flushes). When this + * occurs, the method will take more time to run (possibly + * a long time if the index is large), and will require + * free temporary space in the Directory to do the + * merging.

+ * + *

The amount of free space required when a merge is triggered is + * up to 1X the size of all segments being merged, when no + * readers/searchers are open against the index, and up to 2X the + * size of all segments being merged when readers/searchers are open + * against the index (see {@link #optimize()} for details). The + * sequence of primitive merge operations performed is governed by + * the merge policy. + * + *

Note that each term in the document can be no longer + * than 16383 characters, otherwise an + * IllegalArgumentException will be thrown.

+ * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * @param analyzer use the provided analyzer instead of the + * value of {@link #getAnalyzer()} + */ + void addDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer=NULL); + //void addDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::SAnalyzer* sanalyzer); + + + /** + * Expert: asks the mergePolicy whether any merges are + * necessary now and if so, runs the requested merges and + * then iterate (test again if merges are needed) until no + * more merges are returned by the mergePolicy. + * + * Explicit calls to maybeMerge() are usually not + * necessary. The most common case is when merge policy + * parameters have changed. + */ + void maybeMerge(); + + /** + * Close the IndexWriter without committing + * any of the changes that have occurred since it was + * opened. This removes any temporary files that had been + * created, after which the state of the index will be the + * same as it was when this writer was first opened. This + * can only be called when this IndexWriter was opened + * with autoCommit=false. + * @throws IllegalStateException if this is called when + * the writer was opened with autoCommit=true. + * @throws IOException if there is a low-level IO error + */ + void abort(); + + + /** + * Merges all segments from an array of indexes into this index. + *

+ * This is similar to addIndexes(Directory[]). However, no optimize() + * is called either at the beginning or at the end. Instead, merges + * are carried out as necessary. + * + *

NOTE: the index in each Directory must not be + * changed (opened by a writer) while this method is + * running. This method does not acquire a write lock in + * each input Directory, so it is up to the caller to + * enforce this. + * + *

NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * + *

+ * This requires this index not be among those to be added, and the + * upper bound* of those segment doc counts not exceed maxMergeDocs. + * + *

See {@link #addIndexes(Directory[])} for + * details on transactional semantics, temporary free + * space required in the Directory, and non-CFS segments + * on an Exception.

+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void addIndexesNoOptimize(CL_NS(util)::ArrayBase& dirs); + + /** Merges the provided indexes into this index. + *

After this completes, the index is optimized.

+ *

The provided IndexReaders are not closed.

+ + *

NOTE: the index in each Directory must not be + * changed (opened by a writer) while this method is + * running. This method does not acquire a write lock in + * each input Directory, so it is up to the caller to + * enforce this. + * + *

NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * + *

See {@link #addIndexes(Directory[])} for + * details on transactional semantics, temporary free + * space required in the Directory, and non-CFS segments + * on an Exception.

+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + //NOT IMPLEMENTED YET: void addIndexes(CL_NS(util)::ArrayBase& readers); + + /** Merges all segments from an array of indexes into this index. + * + *

This may be used to parallelize batch indexing. A large document + * collection can be broken into sub-collections. Each sub-collection can be + * indexed in parallel, on a different thread, process or machine. The + * complete index can then be created by merging sub-collection indexes + * with this method. + * + *

NOTE: the index in each Directory must not be + * changed (opened by a writer) while this method is + * running. This method does not acquire a write lock in + * each input Directory, so it is up to the caller to + * enforce this. + * + *

NOTE: while this is running, any attempts to + * add or delete documents (with another thread) will be + * paused until this method completes. + * + *

After this completes, the index is optimized. + * + *

This method is transactional in how Exceptions are + * handled: it does not commit a new segments_N file until + * all indexes are added. This means if an Exception + * occurs (for example disk full), then either no indexes + * will have been added or they all will have been.

+ * + *

If an Exception is hit, it's still possible that all + * indexes were successfully added. This happens when the + * Exception is hit when trying to build a CFS file. In + * this case, one segment in the index will be in non-CFS + * format, even when using compound file format.

+ * + *

Also note that on an Exception, the index may still + * have been partially or fully optimized even though none + * of the input indexes were added.

+ * + *

Note that this requires temporary free space in the + * Directory up to 2X the sum of all input indexes + * (including the starting index). If readers/searchers + * are open against the starting index, then temporary + * free space required will be higher by the size of the + * starting index (see {@link #optimize()} for details). + *

+ * + *

Once this completes, the final size of the index + * will be less than the sum of all input index sizes + * (including the starting index). It could be quite a + * bit smaller (if there were many pending deletes) or + * just slightly smaller.

+ * + *

See LUCENE-702 + * for details.

+ * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void addIndexes(CL_NS(util)::ArrayBase& dirs); + + /** Expert: Return the total size of all index files currently cached in memory. + * Useful for size management with flushRamDocs() + */ + int64_t ramSizeInBytes(); + + /** Expert: Return the number of documents whose segments are currently cached in memory. + * Useful when calling flush() + */ + int32_t numRamDocs(); + + /** for testing only */ + virtual bool testPoint(const char* name); +private: + class LockWith2; + class LockWithCFS; + friend class LockWith2; + friend class LockWithCFS; + friend class DocumentsWriter; + + /** Merges all RAM-resident segments. */ + void flushRamSegments(); + + /** Incremental segment merger. */ + void maybeMergeSegments(); + + /** Pops segments off of segmentInfos stack down to minSegment, merges them, + * and pushes the merged index onto the top of the segmentInfos stack. + */ + void mergeSegments(const uint32_t minSegment); + + /** Merges the named range of segments, replacing them in the stack with a + * single segment. */ + void mergeSegments(const uint32_t minSegment, const uint32_t end); + + void deleteFiles(std::vector& files); + void readDeleteableFiles(std::vector& files); + void writeDeleteableFiles(std::vector& files); + + /* + * Some operating systems (e.g. Windows) don't permit a file to be deleted + * while it is opened for read (e.g. by another process or thread). So we + * assume that when a delete fails it is because the file is open in another + * process, and queue the file for subsequent deletion. + */ + void deleteSegments(CL_NS(util)::CLVector* segments); + void deleteFiles(std::vector& files, CL_NS(store)::Directory* directory); + void deleteFiles(std::vector& files, std::vector& deletable); + + /** + * Casts current mergePolicy to LogMergePolicy, and throws + * an exception if the mergePolicy is not a LogMergePolicy. + */ + LogMergePolicy* getLogMergePolicy() const; + + void setMessageID(); + + void closeInternal(bool waitForMerges); + void messageState(); + + /** + * If we are flushing by doc count (not by RAM usage), and + * using LogDocMergePolicy then push maxBufferedDocs down + * as its minMergeDocs, to keep backwards compatibility. + */ + void pushMaxBufferedDocs(); + + void finishMerges(bool waitForMerges); + + /** Tells the docWriter to close its currently open shared + * doc stores (stored fields & vectors files). + * Return value specifices whether new doc store files are compound or not. + */ + bool flushDocStores(); + + //for test purposes +protected: + int32_t getDocCount(int32_t i); + int32_t getNumBufferedDocuments(); + int32_t getSegmentCount(); + SegmentInfos* getSegmentInfos() { return segmentInfos; } + int32_t getBufferedDeleteTermsSize(); + int32_t getNumBufferedDeleteTerms(); + virtual SegmentInfo* newestSegment(); + +private: + void waitForClose(); + void deletePartialSegmentsFile(); + + /** Returns true if any merges in pendingMerges or + * runningMerges are optimization merges. */ + bool optimizeMergesPending(); + + void resetMergeExceptions(); + + void updatePendingMerges(int32_t maxNumSegmentsOptimize, bool optimize); + + /* + * Begin a transaction. During a transaction, any segment + * merges that happen (or ram segments flushed) will not + * write a new segments file and will not remove any files + * that were present at the start of the transaction. You + * must make a matched (try/finally) call to + * commitTransaction() or rollbackTransaction() to finish + * the transaction. + * + * Note that buffered documents and delete terms are not handled + * within the transactions, so they must be flushed before the + * transaction is started. + */ + void startTransaction(); + + /* + * Rolls back the transaction and restores state to where + * we were at the start. + */ + void rollbackTransaction(); + + /* + * Commits the transaction. This will write the new + * segments file and remove and pending deletions we have + * accumulated during the transaction + */ + void commitTransaction(); + + + void maybeMerge(bool optimize); + void maybeMerge(int32_t maxNumSegmentsOptimize, bool optimize); + /** Does initial setup for a merge, which is fast but holds + * the synchronized lock on IndexWriter instance. */ + void mergeInit(MergePolicy::OneMerge* _merge); + void _mergeInit(MergePolicy::OneMerge* _merge); + + /* If any of our segments are using a directory != ours + * then copy them over. Currently this is only used by + * addIndexesNoOptimize(). */ + void copyExternalSegments(); + + + /* + * Called whenever the SegmentInfos has been updated and + * the index files referenced exist (correctly) in the + * index directory-> If we are in autoCommit mode, we + * commit the change immediately. Else, we mark + * commitPending. + */ + void checkpoint(); + + bool doFlush(bool flushDocStores); + + /* FIXME if we want to support non-contiguous segment merges */ + bool commitMerge(MergePolicy::OneMerge* merge); + + int32_t ensureContiguousMerge(MergePolicy::OneMerge* merge); + + void decrefMergeSegments(MergePolicy::OneMerge* _merge); + + /** Does fininishing for a merge, which is fast but holds + * the synchronized lock on IndexWriter instance. */ + void mergeFinish(MergePolicy::OneMerge* _merge); + + /** Does the actual (time-consuming) work of the merge, + * but without holding synchronized lock on IndexWriter + * instance */ + int32_t mergeMiddle(MergePolicy::OneMerge* _merge); + + void addMergeException(MergePolicy::OneMerge* _merge); + + /** Checks whether this merge involves any segments + * already participating in a merge. If not, this merge + * is "registered", meaning we record that its segments + * are now participating in a merge, and true is + * returned. Else (the merge conflicts) false is + * returned. */ + bool registerMerge(MergePolicy::OneMerge* _merge); + + // Called during flush to apply any buffered deletes. If + // flushedNewSegment is true then a new segment was just + // created and flushed from the ram segments, so we will + // selectively apply the deletes to that new segment. + void applyDeletes(bool flushedNewSegment); + + class Internal; + Internal* _internal; +protected: + // This is called after pending added and deleted + // documents have been flushed to the Directory but before + // the change is committed (_CLNEW segments_N file written). + virtual void doAfterFlush(); + + /** + * Used internally to throw an {@link + * AlreadyClosedException} if this IndexWriter has been + * closed. + * @throws AlreadyClosedException if this IndexWriter is + */ + void ensureOpen(); + + /** + * Flush all in-memory buffered udpates (adds and deletes) + * to the Directory. + * @param triggerMerge if true, we may merge segments (if + * deletes or docs were flushed) if necessary + * @param flushDocStores if false we are allowed to keep + * doc stores open to share with the next segment + */ + void flush(bool triggerMerge, bool flushDocStores); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/MergePolicy.cpp b/src/core/CLucene/index/MergePolicy.cpp new file mode 100644 index 00000000000..1ee1e0a15f6 --- /dev/null +++ b/src/core/CLucene/index/MergePolicy.cpp @@ -0,0 +1,521 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MergePolicy.h" +#include "_SegmentInfos.h" +#include "IndexWriter.h" +#include "CLucene/store/Directory.h" +#include + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_DEF(index) + +#define MESSAGE(msg) if ( writer != NULL && writer->getInfoStream() != NULL ) message(msg) + +const int32_t LogMergePolicy::DEFAULT_MAX_MERGE_DOCS = LUCENE_INT32_MAX_SHOULDBE; + +MergePolicy::OneMerge::OneMerge(SegmentInfos* segments, bool _useCompoundFile): + useCompoundFile(_useCompoundFile) +{ + if (0 == segments->size()) + _CLTHROWA(CL_ERR_Runtime,"segments must include at least one segment"); + this->segments = segments; + this->info = NULL; + this->segmentsClone = NULL; + this->mergeGen = 0; + this->maxNumSegmentsOptimize = 0; + aborted = mergeDocStores = optimize = increfDone = registerDone = isExternal = false; +} +MergePolicy::OneMerge::~OneMerge(){ + _CLDELETE(this->segmentsClone); + + while ( this->segments->size() > 0 ){ + this->segments->remove(0,true);//don't delete... + } + _CLDELETE(this->segments);//and finally delete the segments object itself +} + +const char* MergePolicy::OneMerge::getClassName(){ + return "MergePolicy::OneMerge"; +} +const char* MergePolicy::OneMerge::getObjectName() const{ + return getClassName(); +} +void MergePolicy::OneMerge::setException(CLuceneError& error) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + this->error.set(error.number(),error.what()); +} + +const CLuceneError& MergePolicy::OneMerge::getException(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + return error; +} + +void MergePolicy::OneMerge::abort() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + aborted = true; +} + +bool MergePolicy::OneMerge::isAborted() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + return aborted; +} + +void MergePolicy::OneMerge::checkAborted(CL_NS(store)::Directory* dir){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (aborted) + _CLTHROWA(CL_ERR_MergeAborted, (string("merge is aborted: ") + segString(dir)).c_str() ); +} + +std::string MergePolicy::OneMerge::segString(CL_NS(store)::Directory* dir) const{ + std::string b; + const int32_t numSegments = segments->size(); + for(int32_t i=0;i 0) b.append(" "); + b.append(segments->info(i)->segString(dir)); + } + if (info != NULL) + b.append(" into ").append(info->name); + if (optimize) + b.append(" [optimize]"); + return b; +} + + +MergePolicy::MergeSpecification::MergeSpecification(){ + merges = _CLNEW CLArrayList; +} +MergePolicy::MergeSpecification::~MergeSpecification(){ + _CLDELETE(merges); +} +void MergePolicy::MergeSpecification::add(OneMerge* merge) { + merges->push_back(merge); +} + +std::string MergePolicy::MergeSpecification::segString(CL_NS(store)::Directory* dir) { + std::string b = "MergeSpec:\n"; + int32_t count = merges->size(); + for(int32_t i=0;isegString(dir)); + } + return b; +} + + + +const float_t LogMergePolicy::LEVEL_LOG_SPAN = 0.75; + +void LogMergePolicy::message(const string& message) { + if (writer != NULL){ + string msg = "LMP: " + message; + writer->message( msg ); + } +} +int32_t LogMergePolicy::getMergeFactor(){ + return mergeFactor; +} +bool LogMergePolicy::isOptimized(SegmentInfos* infos, IndexWriter* writer, int32_t maxNumSegments, std::vector& segmentsToOptimize){ + const int32_t numSegments = infos->size(); + int32_t numToOptimize = 0; + SegmentInfo* optimizeInfo = NULL; + for(int32_t i=0;iinfo(i); + vector::iterator itr = segmentsToOptimize.begin(); + while ( itr != segmentsToOptimize.end() ){ + if ( *itr == info ) { + numToOptimize++; + optimizeInfo = info; + } + itr++; + } + } + + return numToOptimize <= maxNumSegments && + (numToOptimize != 1 || isOptimized(writer, optimizeInfo)); +} + +bool LogMergePolicy::isOptimized(IndexWriter* writer, SegmentInfo* info){ + return !info->hasDeletions() && + !info->hasSeparateNorms() && + info->dir == writer->getDirectory() && + info->getUseCompoundFile() == _useCompoundFile; +} + +LogMergePolicy::LogMergePolicy(){ + this->maxMergeDocs = DEFAULT_MAX_MERGE_DOCS; + this->mergeFactor = DEFAULT_MERGE_FACTOR; + this->_useCompoundFile = true; + this->_useCompoundDocStore = true; + this->writer = NULL; + this->minMergeSize = this->maxMergeSize = 0; +} + +void LogMergePolicy::setMergeFactor(int32_t mergeFactor) { + if (mergeFactor < 2) + _CLTHROWA(CL_ERR_IllegalArgument, "mergeFactor cannot be less than 2"); + this->mergeFactor = mergeFactor; +} + +bool LogMergePolicy::useCompoundFile(SegmentInfos* /*infos*/, SegmentInfo* /*info*/) { + return _useCompoundFile; +} + +void LogMergePolicy::setUseCompoundFile(bool useCompoundFile) { + this->_useCompoundFile = useCompoundFile; +} + +bool LogMergePolicy::getUseCompoundFile() { + return _useCompoundFile; +} + +bool LogMergePolicy::useCompoundDocStore(SegmentInfos* /*infos*/) { + return _useCompoundDocStore; +} + +void LogMergePolicy::setUseCompoundDocStore(bool useCompoundDocStore) { + this->_useCompoundDocStore = useCompoundDocStore; +} + +bool LogMergePolicy::getUseCompoundDocStore() { + return _useCompoundDocStore; +} + +void LogMergePolicy::close() {} + + +MergePolicy::MergeSpecification* LogMergePolicy::findMergesForOptimize(SegmentInfos* infos, IndexWriter* writer, int32_t maxNumSegments, vector& segmentsToOptimize) { + MergeSpecification* spec = NULL; + + assert (maxNumSegments > 0); + + if (!isOptimized(infos, writer, maxNumSegments, segmentsToOptimize)) { + + // Find the newest (rightmost) segment that needs to + // be optimized (other segments may have been flushed + // since optimize started): + int32_t last = infos->size(); + while(last > 0) { + const SegmentInfo* info = infos->info(--last); + + vector::iterator itr = segmentsToOptimize.begin(); + bool containsInfo = false; + while (itr != segmentsToOptimize.end() ){ + if ( *itr == info ){ + containsInfo = true; + break; + } + itr++; + } + if (containsInfo) { + last++; + break; + } + } + + if (last > 0) { + spec = _CLNEW MergeSpecification(); + + // First, enroll all "full" merges (size + // mergeFactor) to potentially be run concurrently: + while (last - maxNumSegments + 1 >= mergeFactor) { + SegmentInfos* range = _CLNEW SegmentInfos; + infos->range(last-mergeFactor, last, *range); + spec->add(_CLNEW OneMerge(range, _useCompoundFile)); + last -= mergeFactor; + } + + // Only if there are no full merges pending do we + // add a final partial (< mergeFactor segments) merge: + if (0 == spec->merges->size()) { + if (maxNumSegments == 1) { + + // Since we must optimize down to 1 segment, the + // choice is simple: + if (last > 1 || !isOptimized(writer, infos->info(0))){ + SegmentInfos* range = _CLNEW SegmentInfos; + infos->range(0, last, *range); + spec->add(_CLNEW OneMerge(range, _useCompoundFile)); + } + } else if (last > maxNumSegments) { + + // Take care to pick a partial merge that is + // least cost, but does not make the index too + // lopsided. If we always just picked the + // partial tail then we could produce a highly + // lopsided index over time: + + // We must merge this many segments to leave + // maxNumSegments in the index (from when + // optimize was first kicked off): + const int32_t finalMergeSize = last - maxNumSegments + 1; + + // Consider all possible starting points: + int64_t bestSize = 0; + int32_t bestStart = 0; + + for(int32_t i=0;iinfo(j+i)); + if (i == 0 || (sumSize < 2*size(infos->info(i-1)) && sumSize < bestSize)) { + bestStart = i; + bestSize = sumSize; + } + } + + SegmentInfos* range = _CLNEW SegmentInfos; + infos->range(bestStart, bestStart+finalMergeSize, *range); + spec->add(_CLNEW OneMerge(range, _useCompoundFile)); + } + } + + } else + _CLDELETE(spec); + } else + _CLDELETE(spec); + + return spec; +} + +MergePolicy::MergeSpecification* LogMergePolicy::findMerges(SegmentInfos* infos, IndexWriter* writer){ + + const int32_t numSegments = infos->size(); + this->writer = writer; + MESSAGE( string("findMerges: ") + Misc::toString(numSegments) + " segments"); + + // Compute levels, which is just log (base mergeFactor) + // of the size of each segment + ValueArray levels(numSegments); + const float_t norm = log((float_t)mergeFactor); + + for(int32_t i=0;iinfo(i); + int64_t _size = size(info); + + // Floor tiny segments + if (_size < 1) + _size = 1; + levels[i] = log((float_t)_size)/norm; + } + + float_t levelFloor; + if (minMergeSize <= 0) + levelFloor = 0.0; + else + levelFloor = log((float_t)minMergeSize)/norm; + + // Now, we quantize the log values into levels. The + // first level is any segment whose log size is within + // LEVEL_LOG_SPAN of the max size, or, who has such as + // segment "to the right". Then, we find the max of all + // other segments and use that to define the next level + // segment, etc. + + MergeSpecification* spec = NULL; + + int32_t start = 0; + while(start < numSegments) { + + // Find max level of all segments not already + // quantized. + float_t maxLevel = levels[start]; + for(int32_t i=1+start;i maxLevel) + maxLevel = level; + } + + // Now search backwards for the rightmost segment that + // falls into this level: + float_t levelBottom; + if (maxLevel < levelFloor) + // All remaining segments fall into the min level + levelBottom = -1.0F; + else { + levelBottom = maxLevel - LEVEL_LOG_SPAN; + + // Force a boundary at the level floor + if (levelBottom < levelFloor && maxLevel >= levelFloor) + levelBottom = levelFloor; + } + + int32_t upto = numSegments-1; + while(upto >= start) { + if (levels[upto] >= levelBottom) { + break; + } + upto--; + } + MESSAGE(string(" level ") + Misc::toString(levelBottom) + " to " + Misc::toString(maxLevel) + ": " + Misc::toString(1+upto-start) + " segments"); + + // Finally, record all merges that are viable at this level: + int32_t end = start + mergeFactor; + while(end <= 1+upto) { + bool anyTooLarge = false; + for(int32_t i=start;iinfo(i); + anyTooLarge |= (size(info) >= maxMergeSize || info->docCount >= maxMergeDocs); + } + + if (!anyTooLarge) { + if (spec == NULL) + spec = _CLNEW MergeSpecification(); + MESSAGE( string(" ") + Misc::toString(start) + " to " + Misc::toString(end) + ": add this merge"); + SegmentInfos* range = _CLNEW SegmentInfos; + infos->range(start, end, *range); + spec->add(_CLNEW OneMerge(range, _useCompoundFile)); + } else + MESSAGE( string(" ") + Misc::toString(start) + " to " + Misc::toString(end) + ": contains segment over maxMergeSize or maxMergeDocs; skipping"); + + start = end; + end = start + mergeFactor; + } + + start = 1+upto; + } + + return spec; +} + +void LogMergePolicy::setMaxMergeDocs(int32_t maxMergeDocs) { + this->maxMergeDocs = maxMergeDocs; +} + +int32_t LogMergePolicy::getMaxMergeDocs() { + return maxMergeDocs; +} + +const char* LogMergePolicy::getClassName(){ + return "LogMergePolicy"; +} +const char* LogMergePolicy::getObjectName() const{ + return getClassName(); +} +bool LogMergePolicy::instanceOf(const char* other) const{ + const char* t = this->getObjectName(); + if ( t==other || strcmp( t, other )==0 ){ + return true; + } + t = getClassName(); + if ( t==other || strcmp( t, other )==0 ){ + return true; + } + return false; +} + + + + +LogDocMergePolicy::LogDocMergePolicy() { + minMergeSize = DEFAULT_MIN_MERGE_DOCS; + + // maxMergeSize is never used by LogDocMergePolicy; set + // it to Long.MAX_VALUE to disable it + maxMergeSize = LUCENE_INT64_MAX_SHOULDBE; +} + +void LogDocMergePolicy::setMinMergeDocs(int32_t minMergeDocs) { + minMergeSize = minMergeDocs; +} + +int32_t LogDocMergePolicy::getMinMergeDocs() { + return (int32_t)minMergeSize; +} + +int64_t LogDocMergePolicy::size(SegmentInfo* info) { + return info->docCount; +} + +const char* LogDocMergePolicy::getClassName(){ + return "LogDocMergePolicy"; +} +const char* LogDocMergePolicy::getObjectName() const{ + return getClassName(); +} + + + + +int64_t LogByteSizeMergePolicy::size(SegmentInfo* info) { + return info->sizeInBytes(); +} + +/** Default minimum segment size. @see setMinMergeMB */ +const float_t LogByteSizeMergePolicy::DEFAULT_MIN_MERGE_MB = 1.6; + +/** Default maximum segment size. A segment of this size + * or larger will never be merged. @see setMaxMergeMB */ +const float_t LogByteSizeMergePolicy::DEFAULT_MAX_MERGE_MB = (float_t)LUCENE_INT64_MAX_SHOULDBE; + +LogByteSizeMergePolicy::LogByteSizeMergePolicy() { + minMergeSize = (int64_t) (DEFAULT_MIN_MERGE_MB*1024*1024); + maxMergeSize = (uint64_t) (DEFAULT_MAX_MERGE_MB); //*1024*1024 +} + +/**

Determines the largest segment (measured by total + * byte size of the segment's files, in MB) that may be + * merged with other segments. Small values (e.g., less + * than 50 MB) are best for interactive indexing, as this + * limits the length of pauses while indexing to a few + * seconds. Larger values are best for batched indexing + * and speedier searches.

+ * + *

Note that {@link #setMaxMergeDocs} is also + * used to check whether a segment is too large for + * merging (it's either or).

*/ +void LogByteSizeMergePolicy::setMaxMergeMB(float_t mb) { + maxMergeSize = (uint64_t) (mb*1024*1024); +} + +/** Returns the largest segment (meaured by total byte + * size of the segment's files, in MB) that may be merged + * with other segments. + * @see #setMaxMergeMB */ +float_t LogByteSizeMergePolicy::getMaxMergeMB() { + return ((float_t) maxMergeSize)/1024/1024; +} + +/** Sets the minimum size for the lowest level segments. + * Any segments below this size are considered to be on + * the same level (even if they vary drastically in size) + * and will be merged whenever there are mergeFactor of + * them. This effectively truncates the "long tail" of + * small segments that would otherwise be created into a + * single level. If you set this too large, it could + * greatly increase the merging cost during indexing (if + * you flush many small segments). */ +void LogByteSizeMergePolicy::setMinMergeMB(float_t mb) { + minMergeSize = (int64_t) (mb*1024*1024); +} + +/** Get the minimum size for a segment to remain + * un-merged. + * @see #setMinMergeMB **/ +float_t LogByteSizeMergePolicy::getMinMergeMB() { + return ((float_t) minMergeSize)/1024/1024; +} + +const char* LogByteSizeMergePolicy::getClassName(){ + return "LogByteSizeMergePolicy"; +} +const char* LogByteSizeMergePolicy::getObjectName() const{ + return getClassName(); +} + + +CL_NS_END diff --git a/src/core/CLucene/index/MergePolicy.h b/src/core/CLucene/index/MergePolicy.h new file mode 100644 index 00000000000..79caf40726c --- /dev/null +++ b/src/core/CLucene/index/MergePolicy.h @@ -0,0 +1,438 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_MergePolicy_ +#define _lucene_index_MergePolicy_ + +#include "CLucene/util/VoidList.h" +CL_CLASS_DEF(store,Directory) +CL_NS_DEF(index) + +class SegmentInfo; +class SegmentInfos; +class IndexWriter; + +/** + *

Expert: a MergePolicy determines the sequence of + * primitive merge operations to be used for overall merge + * and optimize operations.

+ * + *

Whenever the segments in an index have been altered by + * {@link IndexWriter}, either the addition of a newly + * flushed segment, addition of many segments from + * addIndexes* calls, or a previous merge that may now need + * to cascade, {@link IndexWriter} invokes {@link + * #findMerges} to give the MergePolicy a chance to pick + * merges that are now required. This method returns a + * {@link MergeSpecification} instance describing the set of + * merges that should be done, or null if no merges are + * necessary. When IndexWriter.optimize is called, it calls + * {@link #findMergesForOptimize} and the MergePolicy should + * then return the necessary merges.

+ * + *

Note that the policy can return more than one merge at + * a time. In this case, if the writer is using {@link + * SerialMergeScheduler}, the merges will be run + * sequentially but if it is using {@link + * ConcurrentMergeScheduler} they will be run concurrently.

+ * + *

The default MergePolicy is {@link + * LogByteSizeMergePolicy}.

+ *

NOTE: This API is new and still experimental + * (subject to change suddenly in the next release)

+ */ +class CLUCENE_EXPORT MergePolicy: public CL_NS(util)::NamedObject { +public: + /** OneMerge provides the information necessary to perform + * an individual primitive merge operation, resulting in + * a single new segment. The merge spec includes the + * subset of segments to be merged as well as whether the + * new segment should use the compound file format. */ + class CLUCENE_EXPORT OneMerge: public CL_NS(util)::NamedObject { + public: + DEFINE_MUTEX(THIS_LOCK) + SegmentInfo* info; // used by IndexWriter + bool mergeDocStores; // used by IndexWriter + bool optimize; // used by IndexWriter + SegmentInfos* segmentsClone; // used by IndexWriter + bool increfDone; // used by IndexWriter + bool registerDone; // used by IndexWriter + int64_t mergeGen; // used by IndexWriter + bool isExternal; // used by IndexWriter + int32_t maxNumSegmentsOptimize; // used by IndexWriter + + SegmentInfos* segments; + const bool useCompoundFile; + bool aborted; + CLuceneError error; + + /** + * Constructor + * @memory, segments object is consumed. The SegmentInfo objects within are referenced + */ + OneMerge(SegmentInfos* segments, bool _useCompoundFile); + ~OneMerge(); + + /** Record that an exception occurred while executing + * this merge */ + void setException(CLuceneError& error); + + /** Retrieve previous exception set by {@link + * #setException}. */ + const CLuceneError& getException(); + + /** Mark this merge as aborted. If this is called + * before the merge is committed then the merge will + * not be committed. */ + void abort(); + + /** Returns true if this merge was aborted. */ + bool isAborted(); + + void checkAborted(CL_NS(store)::Directory* dir); + + std::string segString(CL_NS(store)::Directory* dir) const; + + static const char* getClassName(); + virtual const char* getObjectName() const; + }; + + /** + * A MergeSpecification instance provides the information + * necessary to perform multiple merges. It simply + * contains a list of {@link OneMerge} instances. + */ + + class CLUCENE_EXPORT MergeSpecification { + public: + MergeSpecification(); + ~MergeSpecification(); + + /** + * The subset of segments to be included in the primitive merge. + */ + CL_NS(util)::CLArrayList* merges; + + void add(OneMerge* merge); + + std::string segString(CL_NS(store)::Directory* dir); + }; + + + /** + * Determine what set of merge operations are now + * necessary on the index. The IndexWriter calls this + * whenever there is a change to the segments. This call + * is always synchronized on the IndexWriter instance so + * only one thread at a time will call this method. + * + * @param segmentInfos the total set of segments in the index + * @param writer IndexWriter instance + */ + virtual MergeSpecification* findMerges(SegmentInfos* segmentInfos, + IndexWriter* writer) = 0; + + /** + * Determine what set of merge operations are necessary in + * order to optimize the index. The IndexWriter calls + * this when its optimize() method is called. This call + * is always synchronized on the IndexWriter instance so + * only one thread at a time will call this method. + * + * @param segmentInfos the total set of segments in the index + * @param writer IndexWriter instance + * @param maxSegmentCount requested maximum number of + * segments in the index (currently this is always 1) + * @param segmentsToOptimize contains the specific + * SegmentInfo instances that must be merged away. This + * may be a subset of all SegmentInfos. + */ + virtual MergeSpecification* findMergesForOptimize(SegmentInfos* segmentInfos, + IndexWriter* writer, + int32_t maxSegmentCount, + std::vector& segmentsToOptimize) = 0; + + /** + * Release all resources for the policy. + */ + virtual void close() = 0; + + /** + * Returns true if a newly flushed (not from merge) + * segment should use the compound file format. + */ + virtual bool useCompoundFile(SegmentInfos* segments, SegmentInfo* newSegment) = 0; + + /** + * Returns true if the doc store files should use the + * compound file format. + */ + virtual bool useCompoundDocStore(SegmentInfos* segments) = 0; +}; + + + + + + + + + + + + + +/**

This class implements a {@link MergePolicy} that tries + * to merge segments into levels of exponentially + * increasing size, where each level has < mergeFactor + * segments in it. Whenever a given levle has mergeFactor + * segments or more in it, they will be merged.

+ * + *

This class is abstract and requires a subclass to + * define the {@link #size} method which specifies how a + * segment's size is determined. {@link LogDocMergePolicy} + * is one subclass that measures size by document count in + * the segment. {@link LogByteSizeMergePolicy} is another + * subclass that measures size as the total byte size of the + * file(s) for the segment.

+ */ +class CLUCENE_EXPORT LogMergePolicy: public MergePolicy { + + int32_t mergeFactor; + + int32_t maxMergeDocs; + + bool _useCompoundFile; + bool _useCompoundDocStore; + IndexWriter* writer; + + void message(const std::string& message); + + bool isOptimized(SegmentInfos* infos, IndexWriter* writer, int32_t maxNumSegments, std::vector& segmentsToOptimize); + + /** Returns true if this single nfo is optimized (has no + * pending norms or deletes, is in the same dir as the + * writer, and matches the current compound file setting */ + bool isOptimized(IndexWriter* writer, SegmentInfo* info); + + +protected: + virtual int64_t size(SegmentInfo* info) = 0; + int64_t minMergeSize; + uint64_t maxMergeSize; + +public: + LogMergePolicy(); + + /** Defines the allowed range of log(size) for each + * level. A level is computed by taking the max segment + * log size, minuse LEVEL_LOG_SPAN, and finding all + * segments falling within that range. */ + static const float_t LEVEL_LOG_SPAN; + + /** Default merge factor, which is how many segments are + * merged at a time */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MERGE_FACTOR = 10); + + /** Default maximum segment size. A segment of this size + * or larger will never be merged. @see setMaxMergeDocs */ + static const int32_t DEFAULT_MAX_MERGE_DOCS; + + /**

Returns the number of segments that are merged at + * once and also controls the total number of segments + * allowed to accumulate in the index.

*/ + int32_t getMergeFactor(); + + /** Determines how often segment indices are merged by + * addDocument(). With smaller values, less RAM is used + * while indexing, and searches on unoptimized indices are + * faster, but indexing speed is slower. With larger + * values, more RAM is used during indexing, and while + * searches on unoptimized indices are slower, indexing is + * faster. Thus larger values (> 10) are best for batch + * index creation, and smaller values (< 10) for indices + * that are interactively maintained. */ + void setMergeFactor(int32_t mergeFactor); + + // Javadoc inherited + bool useCompoundFile(SegmentInfos* infos, SegmentInfo* info); + + /** Sets whether compound file format should be used for + * newly flushed and newly merged segments. */ + void setUseCompoundFile(bool useCompoundFile); + + /** Returns true if newly flushed and newly merge segments + * are written in compound file format. @see + * #setUseCompoundFile */ + bool getUseCompoundFile(); + + // Javadoc inherited + bool useCompoundDocStore(SegmentInfos* infos); + + /** Sets whether compound file format should be used for + * newly flushed and newly merged doc store + * segment files (term vectors and stored fields). */ + void setUseCompoundDocStore(bool useCompoundDocStore); + + /** Returns true if newly flushed and newly merge doc + * store segment files (term vectors and stored fields) + * are written in compound file format. @see + * #setUseCompoundDocStore */ + bool getUseCompoundDocStore(); + + void close(); + + + /** Returns the merges necessary to optimize the index. + * This merge policy defines "optimized" to mean only one + * segment in the index, where that segment has no + * deletions pending nor separate norms, and it is in + * compound file format if the current useCompoundFile + * setting is true. This method returns multiple merges + * (mergeFactor at a time) so the {@link MergeScheduler} + * in use may make use of concurrency. */ + MergeSpecification* findMergesForOptimize(SegmentInfos* segmentInfos, + IndexWriter* writer, + int32_t maxSegmentCount, + std::vector& segmentsToOptimize); + + /** Checks if any merges are now necessary and returns a + * {@link MergePolicy.MergeSpecification} if so. A merge + * is necessary when there are more than {@link + * #setMergeFactor} segments at a given level. When + * multiple levels have too many segments, this method + * will return multiple merges, allowing the {@link + * MergeScheduler} to use concurrency. */ + MergeSpecification* findMerges(SegmentInfos* infos, IndexWriter* writer); + + /**

Determines the largest segment (measured by + * document count) that may be merged with other segments. + * Small values (e.g., less than 10,000) are best for + * interactive indexing, as this limits the length of + * pauses while indexing to a few seconds. Larger values + * are best for batched indexing and speedier + * searches.

+ * + *

The default value is {@link Integer#MAX_VALUE}.

+ * + *

The default merge policy ({@link + * LogByteSizeMergePolicy}) also allows you to set this + * limit by net size (in MB) of the segment, using {@link + * LogByteSizeMergePolicy#setMaxMergeMB}.

+ */ + void setMaxMergeDocs(int32_t maxMergeDocs); + + /** Returns the largest segment (measured by document + * count) that may be merged with other segments. + * @see #setMaxMergeDocs */ + int32_t getMaxMergeDocs(); + + + virtual bool instanceOf(const char* otherobject) const; + static const char* getClassName(); + virtual const char* getObjectName() const; +}; + + + + + + +/** This is a {@link LogMergePolicy} that measures size of a + * segment as the number of documents (not taking deletions + * into account). */ +class CLUCENE_EXPORT LogDocMergePolicy: public LogMergePolicy { +public: + + /** Default minimum segment size. @see setMinMergeDocs */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MIN_MERGE_DOCS = 1000); + + LogDocMergePolicy(); + + /** Sets the minimum size for the lowest level segments. + * Any segments below this size are considered to be on + * the same level (even if they vary drastically in size) + * and will be merged whenever there are mergeFactor of + * them. This effectively truncates the "int64_t tail" of + * small segments that would otherwise be created into a + * single level. If you set this too large, it could + * greatly increase the merging cost during indexing (if + * you flush many small segments). */ + void setMinMergeDocs(int32_t minMergeDocs); + + /** Get the minimum size for a segment to remain + * un-merged. + * @see #setMinMergeDocs **/ + int32_t getMinMergeDocs(); + + + static const char* getClassName(); + virtual const char* getObjectName() const; +protected: + int64_t size(SegmentInfo* info); +}; + + +/** This is a {@link LogMergePolicy} that measures size of a + * segment as the total byte size of the segment's files. */ +class CLUCENE_EXPORT LogByteSizeMergePolicy: public LogMergePolicy { +protected: + int64_t size(SegmentInfo* info); + +public: + /** Default minimum segment size. @see setMinMergeMB */ + static const float_t DEFAULT_MIN_MERGE_MB; + + /** Default maximum segment size. A segment of this size + * or larger will never be merged. @see setMaxMergeMB */ + static const float_t DEFAULT_MAX_MERGE_MB; + + LogByteSizeMergePolicy(); + + /**

Determines the largest segment (measured by total + * byte size of the segment's files, in MB) that may be + * merged with other segments. Small values (e.g., less + * than 50 MB) are best for interactive indexing, as this + * limits the length of pauses while indexing to a few + * seconds. Larger values are best for batched indexing + * and speedier searches.

+ * + *

Note that {@link #setMaxMergeDocs} is also + * used to check whether a segment is too large for + * merging (it's either or).

*/ + void setMaxMergeMB(float_t mb); + + /** Returns the largest segment (meaured by total byte + * size of the segment's files, in MB) that may be merged + * with other segments. + * @see #setMaxMergeMB */ + float_t getMaxMergeMB(); + + /** Sets the minimum size for the lowest level segments. + * Any segments below this size are considered to be on + * the same level (even if they vary drastically in size) + * and will be merged whenever there are mergeFactor of + * them. This effectively truncates the "long tail" of + * small segments that would otherwise be created into a + * single level. If you set this too large, it could + * greatly increase the merging cost during indexing (if + * you flush many small segments). */ + void setMinMergeMB(float_t mb); + + /** Get the minimum size for a segment to remain + * un-merged. + * @see #setMinMergeMB **/ + float_t getMinMergeMB(); + + static const char* getClassName(); + virtual const char* getObjectName() const; +}; + + + +CL_NS_END +#endif + diff --git a/src/core/CLucene/index/MergeScheduler.cpp b/src/core/CLucene/index/MergeScheduler.cpp new file mode 100644 index 00000000000..9de63b35030 --- /dev/null +++ b/src/core/CLucene/index/MergeScheduler.cpp @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MergeScheduler.h" +#include "IndexWriter.h" + + +CL_NS_DEF(index) + + +const char* SerialMergeScheduler::getObjectName() const{ + return getClassName(); +} +const char* SerialMergeScheduler::getClassName(){ + return "SerialMergeScheduler"; +} + +void SerialMergeScheduler::merge(IndexWriter* writer){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + while(true) { + MergePolicy::OneMerge* merge = writer->getNextMerge(); + if (merge == NULL) + break; + writer->merge(merge); + } +} + +void SerialMergeScheduler::close() {} + +CL_NS_END diff --git a/src/core/CLucene/index/MergeScheduler.h b/src/core/CLucene/index/MergeScheduler.h new file mode 100644 index 00000000000..97cb8b36a28 --- /dev/null +++ b/src/core/CLucene/index/MergeScheduler.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_MergeScheduler_ +#define _lucene_index_MergeScheduler_ + +#include "CLucene/util/Equators.h" +#include "CLucene/LuceneThreads.h" +CL_NS_DEF(index) + +class IndexWriter; + +/** Expert: {@link IndexWriter} uses an instance + * implementing this interface to execute the merges + * selected by a {@link MergePolicy}. The default + * MergeScheduler is {@link ConcurrentMergeScheduler}. + *

NOTE: This API is new and still experimental + * (subject to change suddenly in the next release)

+*/ +class CLUCENE_EXPORT MergeScheduler: public CL_NS(util)::NamedObject { +public: + /** Run the merges provided by {@link IndexWriter#getNextMerge()}. */ + virtual void merge(IndexWriter* writer) = 0; + + /** Close this MergeScheduler. */ + virtual void close() = 0; +}; + +/** A {@link MergeScheduler} that simply does each merge + * sequentially, using the current thread. */ +class CLUCENE_EXPORT SerialMergeScheduler: public MergeScheduler { +public: + DEFINE_MUTEX(THIS_LOCK) + + /** Just do the merges in sequence. We do this + * "synchronized" so that even if the application is using + * multiple threads, only one merge may run at a time. */ + void merge(IndexWriter* writer); + void close(); + + const char* getObjectName() const; + static const char* getClassName(); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/MultiReader.cpp b/src/core/CLucene/index/MultiReader.cpp new file mode 100644 index 00000000000..0a94c5f399b --- /dev/null +++ b/src/core/CLucene/index/MultiReader.cpp @@ -0,0 +1,363 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultiReader.h" +#include "_MultiSegmentReader.h" + +#include "IndexReader.h" +#include "CLucene/document/Document.h" +#include "Term.h" +#include "Terms.h" +#include "CLucene/util/PriorityQueue.h" +#include "_SegmentHeader.h" +#include "_SegmentMergeInfo.h" +#include "_SegmentMergeQueue.h" + +CL_NS_USE(store) +CL_NS_USE(document) +CL_NS_USE(util) +CL_NS_DEF(index) + + + +class MultiReader::Internal: LUCENE_BASE{ +public: + MultiSegmentReader::NormsCacheType normsCache; + + bool* closeOnClose; //remember which subreaders to close on close + bool _hasDeletions; + uint8_t* ones; + int32_t _maxDoc; + int32_t _numDocs; + + Internal(): + normsCache(true, true) + { + _maxDoc = 0; + _numDocs = -1; + ones = NULL; + _hasDeletions = false; + closeOnClose = NULL; + } + ~Internal(){ + _CLDELETE_ARRAY(ones); + _CLDELETE_ARRAY(closeOnClose); + } +}; + +MultiReader::MultiReader(const CL_NS(util)::ArrayBase* subReaders, bool closeSubReaders) +{ + this->_internal = _CLNEW Internal(); + this->init(subReaders, closeSubReaders); +} + +void MultiReader::init(const CL_NS(util)::ArrayBase* _subReaders, bool closeSubReaders){ + this->subReaders = _CLNEW CL_NS(util)::ValueArray(_subReaders->length); + starts = _CL_NEWARRAY(int32_t, subReaders->length + 1); // build starts array + _internal->closeOnClose = _CL_NEWARRAY(bool, subReaders->length); + + for (size_t i = 0; i < subReaders->length; i++) { + this->subReaders->values[i] = _subReaders->values[i]; + starts[i] = _internal->_maxDoc; + + // compute maxDocs + _internal->_maxDoc += (*subReaders)[i]->maxDoc(); + _internal->closeOnClose[i] = closeSubReaders; + if ((*subReaders)[i]->hasDeletions()) + _internal->_hasDeletions = true; + } + starts[subReaders->length] = _internal->_maxDoc; +} + +MultiReader::~MultiReader() { +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed all IndexReader instances +// this instance managed have been destroyed to + + close(); + _CLDELETE(_internal); + _CLDELETE_ARRAY(starts); + _CLDELETE(subReaders); +} + + +IndexReader* MultiReader::reopen() { + ensureOpen(); + + bool reopened = false; + ValueArray newSubReaders(subReaders->length); + ValueArray newCloseOnClose(subReaders->length); + + bool success = false; + IndexReader* ret = NULL; + try { + for (size_t i = 0; i < subReaders->length; i++) { + newSubReaders[i] = (*subReaders)[i]->reopen(); + + // if at least one of the subreaders was updated we remember that + // and return a new MultiReader + if (newSubReaders[i] != (*subReaders)[i]) { + reopened = true; + // this is a new subreader instance, so on close() we don't close it + newCloseOnClose[i] = true; + } + } + + if (reopened) { + MultiReader* mr = _CLNEW MultiReader(&newSubReaders); + + for (size_t i = 0; i < subReaders->length; i++) { + if (newSubReaders[i] == (*subReaders)[i]) { + // 'give' the memory to the new object + mr->_internal->closeOnClose[i] = this->_internal->closeOnClose[i]; + this->subReaders->values[i] = NULL; + } + } + success = true; + ret = mr; + } else { + success = true; + ret = this; + } + } _CLFINALLY ( + if (!success && reopened) { + for (size_t i = 0; i < newSubReaders.length; i++) { + if (newSubReaders[i] != NULL) { + try { + if (newCloseOnClose[i]) { + newSubReaders.values[i]->close(); + _CLDELETE(newSubReaders.values[i]); + } + } catch (CLuceneError& ignore) { + if ( ignore.number() != CL_ERR_IO ) throw ignore; + // keep going - we want to clean up as much as possible + } + } + } + } + ) + return ret; +} + +ArrayBase* MultiReader::getTermFreqVectors(int32_t n){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->getTermFreqVectors(n - starts[i]); // dispatch to segment +} + +TermFreqVector* MultiReader::getTermFreqVector(int32_t n, const TCHAR* field){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->getTermFreqVector(n - starts[i], field); +} + +void MultiReader::getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + (*subReaders)[i]->getTermFreqVector(docNumber - starts[i], field, mapper); +} + +void MultiReader::getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper) { + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + (*subReaders)[i]->getTermFreqVector(docNumber - starts[i], mapper); +} + +bool MultiReader::isOptimized() { + return false; +} + + +int32_t MultiReader::numDocs() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + // Don't call ensureOpen() here (it could affect performance) + if (_internal->_numDocs == -1) { // check cache + int32_t n = 0; // cache miss--recompute + for (size_t i = 0; i < subReaders->length; i++){ + n += (*subReaders)[i]->numDocs(); // sum from readers + } + _internal->_numDocs = n; + } + return _internal->_numDocs; +} + +int32_t MultiReader::maxDoc() const { + // Don't call ensureOpen() here (it could affect performance) + return _internal->_maxDoc; +} + +bool MultiReader::document(int32_t n, CL_NS(document)::Document& doc, const FieldSelector* fieldSelector){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->document(n - starts[i],doc, fieldSelector); // dispatch to segment reader +} + +bool MultiReader::isDeleted(const int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->isDeleted(n - starts[i]); // dispatch to segment reader +} + +bool MultiReader::hasDeletions() const{ + // Don't call ensureOpen() here (it could affect performance) + return _internal->_hasDeletions; +} + +const ArrayBase* MultiReader::getSubReaders() const{ + return subReaders; +} + +uint8_t* MultiReader::norms(const TCHAR* field){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + uint8_t* bytes; + bytes = _internal->normsCache.get((TCHAR*)field); + if (bytes != NULL){ + return bytes; // cache hit + } + + if ( !hasNorms(field) ) + return fakeNorms(); + + bytes = _CL_NEWARRAY(uint8_t,maxDoc()); + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->norms(field, bytes + starts[i]); + + //Unfortunately the data in the normCache can get corrupted, since it's being loaded with string + //keys that may be deleted while still in use by the map. To prevent this field is duplicated + //and then stored in the normCache + TCHAR* key = STRDUP_TtoT(field); + //update cache + _internal->normsCache.put(key, bytes); + + return bytes; +} + +void MultiReader::norms(const TCHAR* field, uint8_t* result) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + uint8_t* bytes = norms(field); + if (bytes != NULL){ // return + memcpy(result,bytes, maxDoc() * sizeof(int32_t)); + } +} + + +void MultiReader::doSetNorm(int32_t n, const TCHAR* field, uint8_t value){ + _internal->normsCache.removeitr( _internal->normsCache.find((TCHAR*)field) ); // clear cache + int32_t i = readerIndex(n); // find segment num + (*subReaders)[i]->setNorm(n-starts[i], field, value); // dispatch +} + +TermEnum* MultiReader::terms() { + ensureOpen(); + return _CLNEW MultiTermEnum(subReaders, starts, NULL); +} + +TermEnum* MultiReader::terms(const Term* term) { + ensureOpen(); + return _CLNEW MultiTermEnum(subReaders, starts, term); +} + +int32_t MultiReader::docFreq(const Term* t) { + ensureOpen(); + int32_t total = 0; // sum freqs in Multi + for (size_t i = 0; i < subReaders->length; i++) + total += (*subReaders)[i]->docFreq(t); + return total; +} + +TermDocs* MultiReader::termDocs() { + ensureOpen(); + TermDocs* ret = _CLNEW MultiTermDocs(subReaders, starts); + return ret; +} + +TermPositions* MultiReader::termPositions() { + ensureOpen(); + TermPositions* ret = (TermPositions*)_CLNEW MultiTermPositions(subReaders, starts); + return ret; +} + +void MultiReader::doDelete(const int32_t n) { + _internal->_numDocs = -1; // invalidate cache + int32_t i = readerIndex(n); // find segment num + (*subReaders)[i]->deleteDocument(n - starts[i]); // dispatch to segment reader + _internal->_hasDeletions = true; +} + +int32_t MultiReader::readerIndex(const int32_t n) const { // find reader for doc n: + return MultiSegmentReader::readerIndex(n, this->starts, this->subReaders->length); +} + +bool MultiReader::hasNorms(const TCHAR* field) { + ensureOpen(); + for (size_t i = 0; i < subReaders->length; i++) { + if ((*subReaders)[i]->hasNorms(field)) + return true; + } + return false; +} +uint8_t* MultiReader::fakeNorms() { + if (_internal->ones==NULL) + _internal->ones=SegmentReader::createFakeNorms(maxDoc()); + return _internal->ones; +} + +void MultiReader::doUndeleteAll(){ + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->undeleteAll(); + _internal->_hasDeletions = false; + _internal->_numDocs = -1; +} +void MultiReader::doCommit() { + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->commit(); +} + +void MultiReader::doClose() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + for (size_t i = 0; i < subReaders->length; i++){ + if ( (*subReaders)[i] == NULL ) continue; //reopen may take some memory... + if (_internal->closeOnClose[i]) { + subReaders->values[i]->close(); + _CLDELETE(subReaders->values[i]); + } + } +} + + +void MultiReader::getFieldNames(FieldOption fieldNames, StringArrayWithDeletor& retarray){ + ensureOpen(); + return MultiSegmentReader::getFieldNames(fieldNames, retarray, this->subReaders); +} + +bool MultiReader::isCurrent(){ + for (size_t i = 0; i < subReaders->length; i++) { + if (!(*subReaders)[i]->isCurrent()) { + return false; + } + } + + // all subreaders are up to date + return true; +} + +/** Not implemented. + * @throws UnsupportedOperationException + */ +int64_t MultiReader::getVersion() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "MultiReader does not support this method."); +} + +const char* MultiReader::getClassName(){ + return "MultiReader"; +} +const char* MultiReader::getObjectName() const{ + return getClassName(); +} +CL_NS_END diff --git a/src/core/CLucene/index/MultiReader.h b/src/core/CLucene/index/MultiReader.h new file mode 100644 index 00000000000..64d1cca44cc --- /dev/null +++ b/src/core/CLucene/index/MultiReader.h @@ -0,0 +1,129 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_MultiReader +#define _lucene_index_MultiReader + + +//#include "SegmentHeader.h" +#include "IndexReader.h" +CL_CLASS_DEF(document,Document) +//#include "Terms.h" +//#include "SegmentMergeQueue.h" + +CL_NS_DEF(index) + +/** An IndexReader which reads multiple indexes, appending their content. +*/ +class CLUCENE_EXPORT MultiReader:public IndexReader{ +private: + class Internal; + Internal* _internal; + int32_t readerIndex(const int32_t n) const; + bool hasNorms(const TCHAR* field); + uint8_t* fakeNorms(); + + void init(const CL_NS(util)::ArrayBase* subReaders, bool closeSubReaders); +protected: + CL_NS(util)::ArrayBase* subReaders; + int32_t* starts; // 1st docno for each segment + + void doSetNorm(int32_t n, const TCHAR* field, uint8_t value); + void doUndeleteAll(); + void doCommit(); + void doClose(); + void doDelete(const int32_t n); +public: + /** + *

Construct a MultiReader aggregating the named set of (sub)readers. + * Directory locking for delete, undeleteAll, and setNorm operations is + * left to the subreaders.

+ * @param subReaders set of (sub)readers + * @param closeSubReaders The subReaders (IndexReader instances) are deleted if true + * @throws IOException + * @memory The subReaders array itself belongs to the caller + */ + MultiReader(const CL_NS(util)::ArrayBase* subReaders, bool closeSubReaders=true); + + ~MultiReader(); + + + /** + * Tries to reopen the subreaders. + *
+ * If one or more subreaders could be re-opened (i. e. subReader.reopen() + * returned a new instance != subReader), then a new MultiReader instance + * is returned, otherwise this instance is returned. + *

+ * A re-opened instance might share one or more subreaders with the old + * instance. Index modification operations result in undefined behavior + * when performed before the old instance is closed. + * (see {@link IndexReader#reopen()}). + *

+ * If subreaders are shared, then the reference count of those + * readers is increased to ensure that the subreaders remain open + * until the last referring reader is closed. + * + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + IndexReader* reopen(); + + TermFreqVector* getTermFreqVector(int32_t n, const TCHAR* field=NULL); + + void getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper); + void getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper); + + /** Return an array of term frequency vectors for the specified document. + * The array contains a vector for each vectorized field in the document. + * Each vector vector contains term numbers and frequencies for all terms + * in a given vectorized field. + * If no such fields existed, the method returns null. + */ + CL_NS(util)::ArrayBase* getTermFreqVectors(int32_t n); + + bool isOptimized(); + + int32_t numDocs(); + int32_t maxDoc() const; + bool document(int32_t n, CL_NS(document)::Document& doc, const CL_NS(document)::FieldSelector* fieldSelector); + bool isDeleted(const int32_t n); + bool hasDeletions() const; + uint8_t* norms(const TCHAR* field); + void norms(const TCHAR* field, uint8_t* result); + TermEnum* terms(); + TermEnum* terms(const Term* term); + + //Returns the document frequency of the current term in the set + int32_t docFreq(const Term* t=NULL); + TermDocs* termDocs(); + TermPositions* termPositions(); + + /** + * @see IndexReader#getFieldNames(IndexReader.FieldOption fldOption) + */ + void getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray); + + + /** + * Checks recursively if all subreaders are up to date. + */ + bool isCurrent(); + + /** Not implemented. + * @throws UnsupportedOperationException + */ + int64_t getVersion(); + + const CL_NS(util)::ArrayBase* getSubReaders() const; + + static const char* getClassName(); + const char* getObjectName() const; +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/MultiSegmentReader.cpp b/src/core/CLucene/index/MultiSegmentReader.cpp new file mode 100644 index 00000000000..3e143ad75c0 --- /dev/null +++ b/src/core/CLucene/index/MultiSegmentReader.cpp @@ -0,0 +1,904 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "IndexReader.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/FieldSelector.h" +#include "Term.h" +#include "Terms.h" +#include "CLucene/util/PriorityQueue.h" +#include "_SegmentHeader.h" +#include "_SegmentMergeInfo.h" +#include "_SegmentMergeQueue.h" +#include "MultiReader.h" +#include "_MultiSegmentReader.h" + +CL_NS_USE(document) +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + +void MultiSegmentReader::initialize(CL_NS(util)::ArrayBase* _subReaders){ + this->subReaders = _subReaders; + + _maxDoc = 0; + _numDocs = -1; + ones = NULL; + _hasDeletions = false; + + starts = _CL_NEWARRAY(int32_t, subReaders->length + 1); // build starts array + for (size_t i = 0; i < subReaders->length; i++) { + starts[i] = _maxDoc; + + // compute maxDocs + _maxDoc += (*subReaders)[i]->maxDoc(); + if ((*subReaders)[i]->hasDeletions()) + _hasDeletions = true; + } + starts[subReaders->length] = _maxDoc; +} + +MultiSegmentReader::MultiSegmentReader(CL_NS(store)::Directory* directory, SegmentInfos* sis, bool closeDirectory): + DirectoryIndexReader(directory,sis,closeDirectory), + normsCache(NormsCacheType(true,true)) +{ + // To reduce the chance of hitting FileNotFound + // (and having to retry), we open segments in + // reverse because IndexWriter merges & deletes + // the newest segments first. + + ArrayBase* readers = _CLNEW ObjectArray(sis->size()); + for (int32_t i = (int32_t)sis->size()-1; i >= 0; i--) { + try { + readers->values[i] = SegmentReader::get(sis->info(i)); + } catch(CLuceneError& err) { + if ( err.number() != CL_ERR_IO ) throw err; + + // Close all readers we had opened: + for(i++;isize();i++) { + try { + (*readers)[i]->close(); + } catch (CLuceneError& err2) { + if ( err.number() != CL_ERR_IO ) throw err2; + // keep going - we want to clean up as much as possible + } + } + throw err; + } catch(...) { + // Close all readers we had opened: + for(i++;isize();i++) { + (*readers)[i]->close(); + } + throw; + } + } + initialize(readers); +} + +/** This contructor is only used for {@link #reopen()} */ +MultiSegmentReader::MultiSegmentReader( + CL_NS(store)::Directory* directory, + SegmentInfos* infos, + bool closeDirectory, + CL_NS(util)::ArrayBase* oldReaders, + int32_t* oldStarts, + NormsCacheType* oldNormsCache): + DirectoryIndexReader(directory, infos, closeDirectory), + normsCache(NormsCacheType(true,true)) +{ + // we put the old SegmentReaders in a map, that allows us + // to lookup a reader using its segment name + map segmentReaders; + if (oldReaders != NULL) { + // create a Map SegmentName->SegmentReader + for (size_t i = 0; i < oldReaders->length; i++) { + segmentReaders[((SegmentReader*)(*oldReaders)[i])->getSegmentName()] = i; + } + } + + ArrayBase* newReaders = _CLNEW ObjectArray(infos->size()); + + for (int32_t i = infos->size() - 1; i>=0; i--) { + // find SegmentReader for this segment + map::iterator oldReaderIndex = segmentReaders.find(infos->info(i)->name); + if ( oldReaderIndex == segmentReaders.end()) { + // this is a new segment, no old SegmentReader can be reused + newReaders->values[i] = NULL; + } else { + // there is an old reader for this segment - we'll try to reopen it + newReaders->values[i] = (*oldReaders)[oldReaderIndex->second]; + } + + bool success = false; + try { + SegmentReader* newReader; + if ((*newReaders)[i] == NULL || infos->info(i)->getUseCompoundFile() != ((SegmentReader*)(*newReaders)[i])->getSegmentInfo()->getUseCompoundFile()) { + // this is a new reader; in case we hit an exception we can close it safely + newReader = SegmentReader::get(infos->info(i)); + } else { + newReader = ((SegmentReader*)(*newReaders)[i])->reopenSegment(infos->info(i)); + } + if (newReader == (*newReaders)[i]) { + // this reader is being re-used, so we take ownership of it... + oldReaders->values[i] = NULL; + } + + newReaders->values[i] = newReader; + success = true; + } _CLFINALLY ( + if (!success) { + for (i++; i < infos->size(); i++) { + if (newReaders->values[i] != NULL) { + try { + (*newReaders)[i]->close(); + _CLDELETE(newReaders->values[i]); + }catch(CLuceneError& ignore){ + if ( ignore.number() != CL_ERR_IO ) throw ignore; + // keep going - we want to clean up as much as possible + } + } + } + } + ) + } + + // initialize the readers to calculate maxDoc before we try to reuse the old normsCache + initialize(newReaders); + + // try to copy unchanged norms from the old normsCache to the new one + if (oldNormsCache != NULL) { + NormsCacheType::iterator it = oldNormsCache->begin(); + while (it != oldNormsCache->end()) { + TCHAR* field = it->first; + if (!hasNorms(field)) { + continue; + } + uint8_t* oldBytes = it->second; + uint8_t* bytes = _CL_NEWARRAY(uint8_t,maxDoc()); + + + for (size_t i = 0; i < subReaders->length; i++) { + map::iterator oldReaderIndex = segmentReaders.find(((SegmentReader*)(*subReaders)[i])->getSegmentName()); + + // this SegmentReader was not re-opened, we can copy all of its norms + if (oldReaderIndex != segmentReaders.end() && + ((*oldReaders)[oldReaderIndex->second] == (*subReaders)[i] + || ((SegmentReader*)(*oldReaders)[oldReaderIndex->second])->_norms.get(field) == ((SegmentReader*)(*subReaders)[i])->_norms.get(field))) { + // we don't have to synchronize here: either this constructor is called from a SegmentReader, + // in which case no old norms cache is present, or it is called from MultiReader.reopen(), + // which is synchronized + memcpy(bytes + starts[i], oldBytes + oldStarts[oldReaderIndex->second], starts[i+1] - starts[i]); + } else { + (*subReaders)[i]->norms(field, bytes+starts[i]); + } + } + + normsCache.put(field, bytes); // update cache + + it++; + } + } +} + + + +MultiSegmentReader::~MultiSegmentReader() { +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed all IndexReader instances +// this instance managed have been destroyed to + + _CLDELETE_ARRAY(ones); + _CLDELETE_ARRAY(starts); + + //Iterate through the subReaders and destroy each reader + _CLDELETE(subReaders); +} + +const char* MultiTermEnum::getObjectName() const{ return getClassName(); } +const char* MultiTermEnum::getClassName(){ return "MultiTermEnum"; } + + DirectoryIndexReader* MultiSegmentReader::doReopen(SegmentInfos* infos){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (infos->size() == 1) { + // The index has only one segment now, so we can't refresh the MultiSegmentReader. + // Return a new SegmentReader instead + return SegmentReader::get(infos, infos->info(0), false); + } else { + return _CLNEW MultiSegmentReader(_directory, infos, closeDirectory, subReaders, starts, &normsCache); + } + } + + +ArrayBase* MultiSegmentReader::getTermFreqVectors(int32_t n){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->getTermFreqVectors(n - starts[i]); // dispatch to segment +} + +TermFreqVector* MultiSegmentReader::getTermFreqVector(int32_t n, const TCHAR* field){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->getTermFreqVector(n - starts[i], field); +} +void MultiSegmentReader::getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper){ + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + (*subReaders)[i]->getTermFreqVector(docNumber - starts[i], field, mapper); +} + +void MultiSegmentReader::getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper){ + ensureOpen(); + int32_t i = readerIndex(docNumber); // find segment num + (*subReaders)[i]->getTermFreqVector(docNumber - starts[i], mapper); +} + + +bool MultiSegmentReader::isOptimized() { + return false; +} + +int32_t MultiSegmentReader::numDocs() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + // Don't call ensureOpen() here (it could affect performance) + if (_numDocs == -1) { // check cache + int32_t n = 0; // cache miss--recompute + for (size_t i = 0; i < subReaders->length; i++) + n += (*subReaders)[i]->numDocs(); // sum from readers + _numDocs = n; + } + return _numDocs; +} + +int32_t MultiSegmentReader::maxDoc() const { + // Don't call ensureOpen() here (it could affect performance) + return _maxDoc; +} + +const ArrayBase* MultiSegmentReader::getSubReaders() const{ + return subReaders; +} + +bool MultiSegmentReader::document(int32_t n, CL_NS(document)::Document& doc, const FieldSelector* fieldSelector){ + ensureOpen(); + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->document(n - starts[i],doc, fieldSelector); // dispatch to segment reader +} + +bool MultiSegmentReader::isDeleted(const int32_t n) { + // Don't call ensureOpen() here (it could affect performance) + int32_t i = readerIndex(n); // find segment num + return (*subReaders)[i]->isDeleted(n - starts[i]); // dispatch to segment reader +} + +bool MultiSegmentReader::hasDeletions() const{ + // Don't call ensureOpen() here (it could affect performance) + return _hasDeletions; +} + +uint8_t* MultiSegmentReader::norms(const TCHAR* field){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + uint8_t* bytes; + bytes = normsCache.get((TCHAR*)field); + if (bytes != NULL){ + return bytes; // cache hit + } + + if ( !hasNorms(field) ) + return fakeNorms(); + + bytes = _CL_NEWARRAY(uint8_t,maxDoc()); + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->norms(field, bytes + starts[i]); + + //Unfortunately the data in the normCache can get corrupted, since it's being loaded with string + //keys that may be deleted while still in use by the map. To prevent this field is duplicated + //and then stored in the normCache + TCHAR* key = STRDUP_TtoT(field); + //update cache + normsCache.put(key, bytes); + + return bytes; +} + +void MultiSegmentReader::norms(const TCHAR* field, uint8_t* result) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + ensureOpen(); + uint8_t* bytes = normsCache.get((TCHAR*)field); + if (bytes==NULL && !hasNorms(field)) + bytes=fakeNorms(); + + if (bytes != NULL){ // cache hit + int32_t len = maxDoc(); + memcpy(result,bytes,len * sizeof(int32_t)); + } + + for (size_t i = 0; i < subReaders->length; i++) // read from segments + (*subReaders)[i]->norms(field, result + starts[i]); +} + + +void MultiSegmentReader::doSetNorm(int32_t n, const TCHAR* field, uint8_t value){ + normsCache.removeitr( normsCache.find((TCHAR*)field) ); // clear cache + int32_t i = readerIndex(n); // find segment num + (*subReaders)[i]->setNorm(n-starts[i], field, value); // dispatch +} + +TermEnum* MultiSegmentReader::terms() { + ensureOpen(); + return _CLNEW MultiTermEnum(subReaders, starts, NULL); +} + +TermEnum* MultiSegmentReader::terms(const Term* term) { + ensureOpen(); + return _CLNEW MultiTermEnum(subReaders, starts, term); +} + +int32_t MultiSegmentReader::docFreq(const Term* t) { + ensureOpen(); + int32_t total = 0; // sum freqs in Multi + for (size_t i = 0; i < subReaders->length; i++) + total += (*subReaders)[i]->docFreq(t); + return total; +} + +TermDocs* MultiSegmentReader::termDocs() { + ensureOpen(); + TermDocs* ret = _CLNEW MultiTermDocs(subReaders, starts); + return ret; +} + +TermPositions* MultiSegmentReader::termPositions() { + ensureOpen(); + TermPositions* ret = static_cast(_CLNEW MultiTermPositions(subReaders, starts)); + return ret; +} + +void MultiSegmentReader::setTermInfosIndexDivisor(int32_t indexDivisor) { + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->setTermInfosIndexDivisor(indexDivisor); +} + +int32_t MultiSegmentReader::getTermInfosIndexDivisor() { + if (subReaders->length > 0) + return (*subReaders)[0]->getTermInfosIndexDivisor(); + else + _CLTHROWA(CL_ERR_IllegalState,"no readers"); +} + +void MultiSegmentReader::doDelete(const int32_t n) { + _numDocs = -1; // invalidate cache + int32_t i = readerIndex(n); // find segment num + (*subReaders)[i]->deleteDocument(n - starts[i]); // dispatch to segment reader + _hasDeletions = true; +} + +int32_t MultiSegmentReader::readerIndex(int32_t n) const{ // find reader for doc n: + return readerIndex(n, this->starts, this->subReaders->length); +} + + +int32_t MultiSegmentReader::readerIndex(const int32_t n, int32_t* starts, int32_t numSubReaders) { // find reader for doc n: + int32_t lo = 0; // search starts array + int32_t hi = numSubReaders - 1; // for first element less + // than n, return its index + while (hi >= lo) { + int32_t mid = (lo + hi) >> 1; + int32_t midValue = starts[mid]; + if (n < midValue) + hi = mid - 1; + else if (n > midValue) + lo = mid + 1; + else{ // found a match + while (mid+1 < numSubReaders && starts[mid+1] == midValue) { + mid++; // scan to last match + } + return mid; + } + } + return hi; +} + +bool MultiSegmentReader::hasNorms(const TCHAR* field) { + ensureOpen(); + for (size_t i = 0; i < subReaders->length; i++) { + if ((*subReaders)[i]->hasNorms(field)) + return true; + } + return false; +} +uint8_t* MultiSegmentReader::fakeNorms() { + if (ones==NULL) + ones=SegmentReader::createFakeNorms(maxDoc()); + return ones; +} + +void MultiSegmentReader::doUndeleteAll(){ + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->undeleteAll(); + _hasDeletions = false; + _numDocs = -1; +} +void MultiSegmentReader::commitChanges() { + for (size_t i = 0; i < subReaders->length; i++) + (*subReaders)[i]->commit(); +} + +void MultiSegmentReader::doClose() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + for (size_t i = 0; i < subReaders->length; i++){ + if ( (*subReaders)[i] != NULL ){ + (*subReaders)[i]->close(); + _CLDELETE(subReaders->values[i]); + } + } + // maybe close directory + DirectoryIndexReader::doClose(); +} + +void MultiSegmentReader::getFieldNames(FieldOption fieldNames, StringArrayWithDeletor& retarray, CL_NS(util)::ArrayBase* subReaders) { + // maintain a unique set of field names + for (size_t i = 0; i < subReaders->length; i++) { + IndexReader* reader = (*subReaders)[i]; + StringArrayWithDeletor subFields(false); + reader->getFieldNames(fieldNames, subFields); + retarray.insert(retarray.end(),subFields.begin(),subFields.end()); + subFields.clear(); + } +} + + +void MultiSegmentReader::getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray){ + StringArrayWithDeletor temp; + CLHashList hashList; + for (size_t i = 0; i < subReaders->length; i++) { + IndexReader* reader = (*subReaders)[i]; + reader->getFieldNames(fldOption, temp); + + //create a unique list of names. + StringArrayWithDeletor::iterator itr = temp.begin(); + while ( itr != temp.end() ){ + if ( hashList.find(*itr) == hashList.end() ) + hashList.insert(STRDUP_TtoT(*itr)); + itr++; + } + } + //move the items into the return + CLHashList::iterator itr = hashList.begin(); + while ( itr != hashList.end() ){ + retarray.push_back(*itr);//no need to copy, already done! + itr++; + } +} +const char* MultiSegmentReader::getClassName(){ + return "MultiSegmentReader"; +} +const char* MultiSegmentReader::getObjectName() const{ + return getClassName(); +} + + + + + + + + + + +void MultiTermDocs::init(ArrayBase* r, const int32_t* s){ + subReaders = r; + starts = s; + base = 0; + pointer = 0; + current = NULL; + term = NULL; + readerTermDocs = NULL; + + //Check if there are subReaders + if(subReaders != NULL && subReaders->length > 0){ + readerTermDocs = _CLNEW ValueArray(subReaders->length); + } +} +MultiTermDocs::MultiTermDocs(){ +//Func - Default constructor +// Initialises an empty MultiTermDocs. +// This constructor is needed to allow the constructor of MultiTermPositions +// initialise the instance by itself +//Pre - true +//Post - An empty + + init(NULL,NULL); +} + +MultiTermDocs::MultiTermDocs(ArrayBase* r, const int32_t* s){ +//Func - Constructor +//Pre - if r is NULL then rLen must be 0 else if r != NULL then rLen > 0 +// s != NULL +//Post - The instance has been created + init(r,s); +} + +MultiTermDocs::~MultiTermDocs(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed + + close(); +} + + +TermPositions* MultiTermDocs::__asTermPositions(){ + return NULL; +} + +int32_t MultiTermDocs::doc() const { + CND_PRECONDITION(current!=NULL,"current==NULL, check that next() was called"); + return base + current->doc(); +} +int32_t MultiTermDocs::freq() const { + CND_PRECONDITION(current!=NULL,"current==NULL, check that next() was called"); + return current->freq(); +} + +void MultiTermDocs::seek(TermEnum* termEnum){ + seek(termEnum->term(false)); +} + +void MultiTermDocs::seek( Term* tterm) { +//Func - Resets the instance for a new search +//Pre - tterm != NULL +//Post - The instance has been reset for a new search + + CND_PRECONDITION(tterm != NULL, "tterm is NULL"); + + //Assigning tterm is done as below for a reason + //The construction ensures that if seek is called from within + //MultiTermDocs with as argument this->term (seek(this->term)) that the assignment + //will succeed and all referencecounters represent the correct situation + + //Get a pointer from tterm and increase its reference counter + Term *TempTerm = _CL_POINTER(tterm); +//xx + //Finialize term to ensure we decrease the reference counter of the instance which term points to + _CLDECDELETE(term); + + //Assign TempTerm to term + term = TempTerm; + + base = 0; + pointer = 0; + current = NULL; +} + +bool MultiTermDocs::next() { + for(;;) { + if (current != NULL && current->next()) { + return true; + } else if (pointer < subReaders->length) { + base = starts[pointer]; + current = termDocs(pointer++); + } else { + return false; + } + } +} + +int32_t MultiTermDocs::read(int32_t* docs, int32_t* freqs, int32_t length) { + while (true) { + while (current == NULL) { + if (pointer < subReaders->length) { // try next segment + base = starts[pointer]; + current = termDocs(pointer++); + } else { + return 0; + } + } + int32_t end = current->read(docs, freqs,length); + if (end == 0) { // none left in segment + current = NULL; + } else { // got some + int32_t b = base; // adjust doc numbers + for (int32_t i = 0; i < end; i++) + docs[i] += b; + return end; + } + } +} + +bool MultiTermDocs::skipTo(const int32_t target) { +// do { +// if (!next()) +// return false; +// } while (target > doc()); +// return true; + for(;;) { + if ( current != NULL && current->skipTo(target - base)) { + return true; + } else if ( pointer < subReaders->length ) { + base = starts[pointer]; + current = termDocs(pointer++); + } else { + return false; + } + } +} + +void MultiTermDocs::close() { +//Func - Closes all MultiTermDocs managed by this instance +//Pre - true +//Post - All the MultiTermDocs have been closed + + + //Check if readerTermDocs is valid + if (readerTermDocs){ + TermDocs* curTD = NULL; + //iterate through the readerTermDocs array + for (size_t i = 0; i < subReaders->length; i++) { + //Retrieve the i-th TermDocs instance + curTD = (*readerTermDocs)[i]; + + //Check if it is a valid pointer + if (curTD != NULL) { + //Close it + curTD->close(); + _CLDELETE(curTD); + } + } + + _CLDELETE(readerTermDocs); + } + + //current previously pointed to a member of readerTermDocs; ensure that + //it doesn't now point to invalid memory. + current = NULL; + base = 0; + pointer = 0; + + _CLDECDELETE(term); +} + +TermDocs* MultiTermDocs::termDocs(IndexReader* reader) { + return reader->termDocs(); +} + +TermDocs* MultiTermDocs::termDocs(const int32_t i) { + if (term == NULL) + return NULL; + TermDocs* result = (*readerTermDocs)[i]; + if (result == NULL){ + _CLLDELETE(readerTermDocs->values[i]); + readerTermDocs->values[i] = termDocs((*subReaders)[i]); + result = (*readerTermDocs)[i]; + } + result->seek(term); + + return result; +} + + +MultiTermEnum::MultiTermEnum(ArrayBase* subReaders, const int32_t *starts, const Term* t){ +//Func - Constructor +// Opens all enumerations of all readers +//Pre - readers != NULL and contains an array of IndexReader instances each responsible for +// reading a single segment +// subReaders->length >= 0 and represents the number of readers in the readers array +// starts is an array of +//Post - An instance of has been created + +//Pre - if readers is NULL then subReaders->length must be 0 else if readers != NULL then subReaders->length > 0 +// s != NULL +//Post - The instance has been created + + CND_PRECONDITION(starts != NULL,"starts is NULL"); + + //Temporary variables + IndexReader* reader = NULL; + TermEnum* termEnum = NULL; + SegmentMergeInfo* smi = NULL; + _docFreq = 0; + _term = NULL; + queue = _CLNEW SegmentMergeQueue(subReaders->length); + + CND_CONDITION (queue != NULL, "Could not allocate memory for queue"); + + //iterate through all the readers + for ( size_t i=0;ilength;i++ ) { + //Get the i-th reader + reader = (*subReaders)[i]; + + //Check if the enumeration must start from term t + if (t != NULL) { + //termEnum is an enumeration of terms starting at or after the named term t + termEnum = reader->terms(t); + }else{ + //termEnum is an enumeration of all the Terms and TermInfos in the set. + termEnum = reader->terms(); + } + + //Instantiate an new SegmentMerginfo + smi = _CLNEW SegmentMergeInfo(starts[i], termEnum, reader); + + // Note that in the call termEnum->getTerm(false) below false is required because + // otherwise a reference is leaked. By passing false getTerm is + // ordered to return an unowned reference instead. (Credits for DSR) + if (t == NULL ? smi->next() : termEnum->term(false) != NULL){ + // initialize queue + queue->put(smi); + } else{ + //Close the SegmentMergeInfo + smi->close(); + //And have it deleted + _CLDELETE(smi); + } + } + + //Check if the queue has elements + if (t != NULL && queue->size() > 0) { + next(); + } +} + +MultiTermEnum::~MultiTermEnum(){ +//Func - Destructor +//Pre - true +//Post - All the resource have been freed and the instance has been deleted + + //Close the enumeration + close(); + + //Delete the queue + _CLDELETE(queue); +} + +bool MultiTermEnum::next(){ +//Func - Move the current term to the next in the set of enumerations +//Pre - true +//Post - Returns true if term has been moved to the next in the set of enumerations +// Returns false if this was not possible + + SegmentMergeInfo* top = queue->top(); + if (top == NULL) { + _CLDECDELETE(_term); + _term = NULL; + return false; + } + + //The getTerm method requires the client programmer to indicate whether he + // owns the returned reference, so we can discard ours + // right away. + _CLDECDELETE(_term); + + //Assign term the term of top and make sure the reference counter is increased + _term = _CL_POINTER(top->term); + _docFreq = 0; + + //Find the next term + while (top != NULL && _term->compareTo(top->term) == 0) { + //don't delete, this is the top + queue->pop(); + // increment freq + _docFreq += top->termEnum->docFreq(); + if (top->next()){ + // restore queue + queue->put(top); + }else{ + // done with a segment + top->close(); + _CLDELETE(top); + } + top = queue->top(); + } + + return true; +} + + +Term* MultiTermEnum::term(bool pointer) { + if ( pointer ) + return _CL_POINTER(_term); + else + return _term; +} + +int32_t MultiTermEnum::docFreq() const { +//Func - Returns the document frequency of the current term in the set +//Pre - termInfo != NULL +// next() must have been called once +//Post - The document frequency of the current enumerated term has been returned + + return _docFreq; +} + + +void MultiTermEnum::close() { +//Func - Closes the set of enumerations in the queue +//Pre - queue holds a valid reference to a SegmentMergeQueue +//Post - The queue has been closed all SegmentMergeInfo instance have been deleted by +// the closing of the queue +// term has been finalized and reset to NULL + + // Needed when this enumeration hasn't actually been exhausted yet + _CLDECDELETE(_term); + + //Close the queue This will destroy all SegmentMergeInfo instances! + queue->close(); + +} + + + + + +MultiTermPositions::MultiTermPositions(ArrayBase* r, const int32_t* s){ +//Func - Constructor +//Pre - if r is NULL then rLen must be 0 else if r != NULL then rLen > 0 +// s != NULL +//Post - The instance has been created + init(r,s); +} + + +TermDocs* MultiTermPositions::__asTermDocs(){ + return (TermDocs*) this; +} +TermPositions* MultiTermPositions::__asTermPositions(){ + return (TermPositions*) this; +} + + +TermDocs* MultiTermPositions::termDocs(IndexReader* reader) { +// Here in the MultiTermPositions class, we want this->current to always +// be a SegmentTermPositions rather than merely a SegmentTermDocs. +// To that end, we override the termDocs(IndexReader&) method to produce +// a SegmentTermPositions via the underlying reader's termPositions method +// rather merely producing a SegmentTermDocs via the reader's termDocs +// method. + + TermPositions* tp = reader->termPositions(); + TermDocs* ret = tp->__asTermDocs(); + + CND_CONDITION(ret != NULL, + "Dynamic downcast in MultiTermPositions::termDocs from" + " TermPositions to TermDocs failed." + ); + return ret; + } + +int32_t MultiTermPositions::nextPosition() { + //Func - + //Pre - current != NULL + //Post - + CND_PRECONDITION(current != NULL,"current is NULL"); + + TermPositions* curAsTP = current->__asTermPositions(); + + CND_CONDITION(curAsTP != NULL, + "Dynamic downcast in MultiTermPositions::nextPosition from" + " SegmentTermDocs to TermPositions failed." + ) + return curAsTP->nextPosition(); +} + +int32_t MultiTermPositions::getPayloadLength() const{ + TermPositions* curAsTP = current->__asTermPositions(); + return curAsTP->getPayloadLength(); +} + +uint8_t* MultiTermPositions::getPayload(uint8_t* data){ + TermPositions* curAsTP = current->__asTermPositions(); + return curAsTP->getPayload(data); +} + +bool MultiTermPositions::isPayloadAvailable() const{ + TermPositions* curAsTP = current->__asTermPositions(); + return curAsTP->isPayloadAvailable(); +} + +CL_NS_END diff --git a/src/core/CLucene/index/MultipleTermPositions.cpp b/src/core/CLucene/index/MultipleTermPositions.cpp new file mode 100644 index 00000000000..a4dcf2cd8c4 --- /dev/null +++ b/src/core/CLucene/index/MultipleTermPositions.cpp @@ -0,0 +1,199 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultipleTermPositions.h" +#include "IndexReader.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/PriorityQueue.h" + +CL_NS_USE(util) + +CL_NS_DEF(index) + +void MultipleTermPositions::seek(Term*) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation: MultipleTermPositions::seek"); +} + +void MultipleTermPositions::seek(TermEnum*) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation: MultipleTermPositions::seek"); +} + +int32_t MultipleTermPositions::read(int32_t*, int32_t*,int32_t) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation: MultipleTermPositions::read"); +} + +int32_t MultipleTermPositions::getPayloadLength() const { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation: MultipleTermPositions::getPayloadLength"); +} + +uint8_t* MultipleTermPositions::getPayload(uint8_t*) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation: MultipleTermPositions::getPayload"); +} + +bool MultipleTermPositions::isPayloadAvailable() const{ + return false; +} + +TermDocs* MultipleTermPositions::__asTermDocs(){ + return (TermDocs*)this; +} +TermPositions* MultipleTermPositions::__asTermPositions(){ + return (TermPositions*)this; +} + + +class MultipleTermPositions::TermPositionsQueue : public CL_NS(util)::PriorityQueue > { +public: + TermPositionsQueue(TermPositions** termPositions, size_t termPositionsSize) { + initialize(termPositionsSize, false); + + size_t i=0; + while (termPositions[i]!=NULL) { + if (termPositions[i]->next()) + put(termPositions[i]); + else + _CLDELETE( termPositions[ i ] ); + + ++i; + } + } + virtual ~TermPositionsQueue(){ + } + + TermPositions* peek() { + return top(); + } + + bool lessThan(TermPositions* a, TermPositions* b) { + return a->doc() < b->doc(); + } +}; + +int IntQueue_sort(const void* a, const void* b){ + return ( *(int*)a - *(int*)b ); +} +class MultipleTermPositions::IntQueue { +private: + ValueArray* _array; + int32_t _index; + int32_t _lastIndex; + +public: + IntQueue():_array(_CLNEW ValueArray(16)), _index(0), _lastIndex(0){ + } + virtual ~IntQueue(){ + _CLLDELETE(_array); + } + + void add(const int32_t i) { + if (_lastIndex == _array->length) + _array->resize(_array->length*2); + + _array->values[_lastIndex++] = i; + } + + int32_t next() { + return _array->values[_index++]; + } + + void sort() { + int len = _lastIndex - _index; + qsort(_array->values+_index, len, sizeof(int32_t), IntQueue_sort); + } + + void clear() { + _index = 0; + _lastIndex = 0; + } + + int32_t size() { + return (_lastIndex - _index); + } +}; + +MultipleTermPositions::MultipleTermPositions(IndexReader* indexReader, const CL_NS(util)::ArrayBase* terms) : _posList(_CLNEW IntQueue()){ + CLLinkedList termPositions; + for ( size_t i=0;ilength;i++){ + termPositions.push_back( indexReader->termPositions(terms->values[i])); + } + + TermPositions** tps = _CL_NEWARRAY(TermPositions*, terms->length+1); // i == tpsSize + termPositions.toArray_nullTerminated(tps); + + _termPositionsQueue = _CLNEW TermPositionsQueue(tps,terms->length); + _CLDELETE_LARRAY(tps); +} + +MultipleTermPositions::~MultipleTermPositions() { + _CLLDELETE(_termPositionsQueue); + _CLLDELETE(_posList); +} + +bool MultipleTermPositions::next() { + if (_termPositionsQueue->size() == 0) + return false; + + _posList->clear(); + _doc = _termPositionsQueue->peek()->doc(); + + TermPositions* tp; + do { + tp = _termPositionsQueue->peek(); + + for (int32_t i = 0; i < tp->freq(); i++) + _posList->add(tp->nextPosition()); + + if (tp->next()) + _termPositionsQueue->adjustTop(); + else { + _termPositionsQueue->pop(); + tp->close(); + _CLLDELETE(tp); + } + } while (_termPositionsQueue->size() > 0 && _termPositionsQueue->peek()->doc() == _doc); + + _posList->sort(); + _freq = _posList->size(); + + return true; +} + +int32_t MultipleTermPositions::nextPosition() { + return _posList->next(); +} + +bool MultipleTermPositions::skipTo(int32_t target) { + while (_termPositionsQueue->peek() != NULL && target > _termPositionsQueue->peek()->doc()) { + TermPositions* tp = _termPositionsQueue->pop(); + if (tp->skipTo(target)) + _termPositionsQueue->put(tp); + else { + tp->close(); + _CLLDELETE(tp); + } + } + return next(); +} + +int32_t MultipleTermPositions::doc() const { + return _doc; +} + +int32_t MultipleTermPositions::freq() const { + return _freq; +} + +void MultipleTermPositions::close() { + while (_termPositionsQueue->size() > 0) { + TermPositions* tp = _termPositionsQueue->pop(); + tp->close(); + _CLLDELETE(tp); + } +} + +CL_NS_END diff --git a/src/core/CLucene/index/MultipleTermPositions.h b/src/core/CLucene/index/MultipleTermPositions.h new file mode 100644 index 00000000000..012f197b358 --- /dev/null +++ b/src/core/CLucene/index/MultipleTermPositions.h @@ -0,0 +1,92 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_MultipleTermPositions_ +#define _lucene_index_MultipleTermPositions_ + +#include "Terms.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +class Term; +class IndexReader; + +class CLUCENE_EXPORT MultipleTermPositions : public TermPositions { +private: + class TermPositionsQueue; + class IntQueue; + + int32_t _doc; + int32_t _freq; + TermPositionsQueue* _termPositionsQueue; + IntQueue* _posList; + +public: + /** + * Creates a new MultipleTermPositions instance. + * + * @exception IOException + */ + MultipleTermPositions(IndexReader* indexReader, const CL_NS(util)::ArrayBase* terms); + virtual ~MultipleTermPositions(); + + bool next(); + + int32_t nextPosition(); + + bool skipTo(const int32_t target); + + int32_t doc() const; + + int32_t freq() const; + + void close(); + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + void seek(Term*); + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + void seek(TermEnum*); + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + int32_t read(int32_t*, int32_t*,int32_t); + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + int32_t getPayloadLength() const; + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + uint8_t* getPayload(uint8_t*); + + /** + * + * @return false + */ + // Java-TODO: Remove warning after API has been finalized + bool isPayloadAvailable() const; + + TermDocs* __asTermDocs(); + TermPositions* __asTermPositions(); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/Payload.cpp b/src/core/CLucene/index/Payload.cpp new file mode 100644 index 00000000000..1cf4839f230 --- /dev/null +++ b/src/core/CLucene/index/Payload.cpp @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Payload.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(index) + +Payload::Payload() : + data( * _CLNEW CL_NS(util)::ValueArray(0)) +{ + // nothing to do + this->deleteData = true; + this->deleteArray = true; +} +Payload::Payload(CL_NS(util)::ValueArray& _data, const int32_t offset, const int32_t length, bool deleteData): + data(_data) +{ + this->deleteData = false; + this->deleteArray = false; + this->setData(data,offset,length,deleteData); +} +Payload::Payload(uint8_t* data, const int32_t length, bool deleteData): + data(*_CLNEW CL_NS(util)::ValueArray) +{ + this->deleteData = false; + this->deleteArray = false; + this->setData(data,length,deleteData); +} + +Payload::~Payload() { + if ( deleteData ) this->data.deleteValues(); + if ( deleteArray ) _CLLDELETE(&this->data); +} + +void Payload::setData(uint8_t* data, const int32_t length, bool deleteData) { + if ( this->deleteData ) this->data.deleteValues(); + if ( this->deleteArray ) { + _CLLDELETE(&this->data); + this->data = *_CLNEW CL_NS(util)::ValueArray; + } + if (length < 0 ) { + _CLTHROWA(CL_ERR_IllegalArgument,"length < 0"); + } + this->data.length = offset+length; + this->data.values = data; + this->deleteData = deleteData; + this->deleteArray = true; + this->_length = length; + this->offset = 0; + //assert(false); +} + +void Payload::setData(CL_NS(util)::ValueArray& data, const int32_t offset, const int32_t length, bool deleteData) { + if ( this->deleteData ) this->data.deleteValues(); + if ( this->deleteArray ) { + _CLLDELETE(&this->data); + } + + if (offset < 0 || offset + length > data.length) { + _CLTHROWA(CL_ERR_IllegalArgument,"offset < 0 || offset + length > data.length"); + } + this->data = data; + this->_length = ( length < 0 ? data.length-offset : length ); + this->offset = offset; + this->deleteData = this->deleteArray = deleteData; + //assert(false); +} + +const CL_NS(util)::ValueArray& Payload::getData() const{ + return data; +} + +int32_t Payload::getOffset() const { return offset; } + +int32_t Payload::length() const { return _length; } + +uint8_t Payload::byteAt(int index) const { + if (0 <= index && index < this->_length) { + return this->data[this->offset + index]; + } + _CLTHROWA(CL_ERR_IndexOutOfBounds,"Array index out of bounds at Payload::byteAt"); +} + +CL_NS(util)::ValueArray* Payload::toByteArray() const{ + CL_NS(util)::ValueArray* ret = _CLNEW CL_NS(util)::ValueArray(this->_length); + memcpy(ret->values, this->data.values + this->offset, this->_length * sizeof(uint8_t)); + return ret; +} + +void Payload::copyTo(uint8_t* target, const int32_t targetLen) const { + if (this->_length > targetLen) { + _CLTHROWA(CL_ERR_IndexOutOfBounds,"Array index out of bounds at Payload::byteAt"); + } + memcpy(target, this->data.values + this->offset, this->_length * sizeof(uint8_t)); +} + +Payload* Payload::clone() const{ + Payload* clone = _CLNEW Payload(*this->toByteArray(), 0, -1, true); + return clone; +} + +CL_NS_END diff --git a/src/core/CLucene/index/Payload.h b/src/core/CLucene/index/Payload.h new file mode 100644 index 00000000000..5a490dc7adb --- /dev/null +++ b/src/core/CLucene/index/Payload.h @@ -0,0 +1,128 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_Payload_ +#define _lucene_index_Payload_ + +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +/** +* A Payload is metadata that can be stored together with each occurrence +* of a term. This metadata is stored inline in the posting list of the +* specific term. +*

+* To store payloads in the index a {@link TokenStream} has to be used that +* produces {@link Token}s containing payload data. +*

+* Use {@link TermPositions#getPayloadLength()} and {@link TermPositions#getPayload(byte[], int)} +* to retrieve the payloads from the index.
+* +*/ +class CLUCENE_EXPORT Payload:LUCENE_REFBASE { +protected: + CL_NS(util)::ValueArray& data; + + /** the offset within the byte array */ + int32_t offset; + + /** the length of the payload data */ + int32_t _length; + + bool deleteData; + bool deleteArray; +public: + + /** Creates an empty payload and does not allocate a byte array. */ + Payload(); + + /** + * Creates a new payload with the the given array as data. + * A reference to the passed-in array is held, i. e. no + * copy is made. + * + * @param data the data of this payload + * @param length the length of the data + * @param deleteData delete data when payload is deleted + */ + Payload(uint8_t* data, const int32_t length, bool deleteData=false); + + /** + * Creates a new payload with the the given array as data. + * A reference to the passed-in array is held, i. e. no + * copy is made. + * + * @param data the data of this payload + * @param deleteData delete data when payload is deleted + */ + Payload(CL_NS(util)::ValueArray& data, const int32_t offset=0, const int32_t length=-1, bool deleteData=false); + + /* Desctructor - auto-delete the data container */ + ~Payload(); + + /** + * Sets this payloads data. + * A reference to the passed-in array is held, i. e. no + * copy is made. + * @param deleteData delete data when payload is deleted + */ + void setData(uint8_t* data, const int32_t length, bool deleteData=false); + + /** + * Sets this payloads data. + * A reference to the passed-in array is held, i. e. no + * copy is made. + * @param deleteData delete data when payload is deleted + */ + void setData(CL_NS(util)::ValueArray& data, const int32_t offset=0, const int32_t length=-1, bool deleteData=false); + + /** + * Returns a reference to the underlying byte array + * that holds this payloads data. + */ + const CL_NS(util)::ValueArray& getData() const; + + /** + * Returns the length of the payload data. + */ + int32_t length() const; + + /** + * Returns the offset in the underlying byte array + */ + int32_t getOffset() const; + + /** + * Returns the byte at the given index. + */ + uint8_t byteAt(int index) const; + + /** + * Allocates a new byte array, copies the payload data into it and returns it. Caller is responsible + * for deleting it later. + * @memory caller is responsible for deleting the returned array + */ + CL_NS(util)::ValueArray* toByteArray() const; + + /** + * Copies the payload data to a byte array. + * + * @param target the target byte array + * @param targetOffset the offset in the target byte array + */ + void copyTo(uint8_t* target, const int32_t targetLen) const; + + /** + * Clones this payload by creating a copy of the underlying + * byte array. + */ + Payload* clone() const; + +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/SDocumentWriter.cpp b/src/core/CLucene/index/SDocumentWriter.cpp new file mode 100644 index 00000000000..e90f92f9e26 --- /dev/null +++ b/src/core/CLucene/index/SDocumentWriter.cpp @@ -0,0 +1,1342 @@ +// +// Created by 姜凯 on 2022/9/16. +// + +#include "SDocumentWriter.h" +#include "IndexWriter.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/document/Document.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/stringUtil.h" + +#include "_FieldsWriter.h" +#include "_TermInfosWriter.h" +#include "_SkipListWriter.h" +#include "_IndexFileNames.h" +#include "_SegmentMerger.h" +#include "vp4.h" + +#include +#include + +#if defined(USE_AVX2) && defined(__x86_64__) +#define P4ENC p4nd1enc256v32 +#else +#define P4ENC p4nd1enc128v32 +#endif + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(analysis) +CL_NS_USE(document) +CL_NS_DEF(index) + +template +const uint8_t SDocumentsWriter::defaultNorm = search::Similarity::encodeNorm(1.0f); + +template +const int32_t SDocumentsWriter::BYTE_BLOCK_SHIFT = 15; +template +const int32_t SDocumentsWriter::BYTE_BLOCK_SIZE = (int32_t) pow(2.0, BYTE_BLOCK_SHIFT); +template +const int32_t SDocumentsWriter::BYTE_BLOCK_MASK = BYTE_BLOCK_SIZE - 1; +template +const int32_t SDocumentsWriter::BYTE_BLOCK_NOT_MASK = ~BYTE_BLOCK_MASK; +template +const int32_t SDocumentsWriter::CHAR_BLOCK_SHIFT = 14; +template +const int32_t SDocumentsWriter::CHAR_BLOCK_SIZE = (int32_t) pow(2.0, CHAR_BLOCK_SHIFT); +template +const int32_t SDocumentsWriter::CHAR_BLOCK_MASK = CHAR_BLOCK_SIZE - 1; +template +const int32_t SDocumentsWriter::nextLevelArray[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 9}; +template +const int32_t SDocumentsWriter::levelSizeArray[10] = {5, 14, 20, 30, 40, 40, 80, 80, 120, 200}; +template +const int32_t SDocumentsWriter::POINTER_NUM_BYTE = 4; +template +const int32_t SDocumentsWriter::INT_NUM_BYTE = 4; +template +const int32_t SDocumentsWriter::CHAR_NUM_BYTE = 2;//TODO: adjust for c++... +template +const int32_t SDocumentsWriter::SCHAR_NUM_BYTE = 1;//TODO: adjust for c++... +template +int32_t SDocumentsWriter::OBJECT_HEADER_BYTES = 8; +template +const int32_t SDocumentsWriter::POSTING_NUM_BYTE = OBJECT_HEADER_BYTES + 9 * INT_NUM_BYTE + 5 * POINTER_NUM_BYTE; + +template +SDocumentsWriter::ThreadState::ThreadState(SDocumentsWriter *p) : postingsFreeListTS(ValueArray(256)), + vectorFieldPointers(ValueArray(10)), + vectorFieldNumbers(ValueArray(10)), + fieldDataArray(ValueArray(8)), + fieldDataHash(ValueArray(16)), + postingsPool(_CLNEW ByteBlockPool(true, p)), + scharPool(_CLNEW SCharBlockPool(p)), + allFieldDataArray(ValueArray(10)), + _parent(p) { + fieldDataHashMask = 15; + postingsFreeCountTS = 0; + stringReader = _CLNEW ReusableStringReader(_T(""), 0, false); + + numThreads = 1; + this->docBoost = 0.0; + this->fieldGen = this->posUpto = this->numStoredFields = 0; + this->numAllFieldData = this->docID = 0; + this->numFieldData = numVectorFields = this->proxUpto = this->freqUpto = this->offsetUpto = 0; + this->maxTermPrefix = nullptr; + this->p = nullptr; + this->prox = nullptr; + this->offsets = nullptr; + this->pos = nullptr; + this->freq = nullptr; + this->doFlushAfter = false; +} + +template +SDocumentsWriter::~SDocumentsWriter() { + if (skipListWriter!=nullptr) { + _CLDELETE(skipListWriter); + } + if (fieldInfos != nullptr) { + _CLDELETE(fieldInfos); + } + if (threadState != nullptr) { + _CLDELETE(threadState); + } + + // Make sure unused posting slots aren't attempted delete on + if (this->postingsFreeListDW.values) { + if (this->postingsFreeCountDW < this->postingsFreeListDW.length) { + memset(this->postingsFreeListDW.values + this->postingsFreeCountDW, 0, sizeof(Posting *)); + } + postingsFreeListDW.deleteUntilNULL(); + } +} + +template +SDocumentsWriter::ThreadState::~ThreadState() { + _CLDELETE(postingsPool); + _CLDELETE(scharPool); + _CLDELETE(stringReader); + + for (size_t i = 0; i < allFieldDataArray.length; i++) + _CLDELETE(allFieldDataArray.values[i]); +} + +template +typename SDocumentsWriter::ThreadState *SDocumentsWriter::getThreadState(Document *doc) { + if (threadState == nullptr) { + threadState = _CLNEW ThreadState(this); + } + + ThreadState *state = threadState; + if (segment.empty()) + segment = writer->newSegmentName(); + state->init(doc, nextDocID); + // Only increment nextDocID & numDocsInRAM on successful init + nextDocID++; + numDocsInRAM++; + + return state; +} + +template +void SDocumentsWriter::ThreadState::init(Document *doc, int32_t doc_id) { + this->docID = doc_id; + docBoost = doc->getBoost(); + numStoredFields = 0; + numFieldData = 0; + numVectorFields = 0; + maxTermPrefix = nullptr; + + const int32_t thisFieldGen = fieldGen++; + + const Document::FieldsType &docFields = *doc->getFields(); + const int32_t numDocFields = docFields.size(); + + for (int32_t i = 0; i < numDocFields; i++) { + Field *field = docFields[i]; + + FieldInfo *fi = _parent->fieldInfos->add(field->name(), field->isIndexed(), field->isTermVectorStored(), + field->isStorePositionWithTermVector(), field->isStoreOffsetWithTermVector(), + field->getOmitNorms(), false); + if (fi->isIndexed && !fi->omitNorms) { + // Maybe grow our buffered norms + if (_parent->norms.length <= fi->number) { + auto newSize = (int32_t) ((1 + fi->number) * 1.25); + _parent->norms.resize(newSize); + } + + if (_parent->norms[fi->number] == NULL) + _parent->norms.values[fi->number] = _CLNEW BufferedNorms(); + + _parent->hasNorms = true; + } + + // Make sure we have a FieldData allocated + int32_t hashPos = Misc::thashCode(fi->name) & fieldDataHashMask;//TODO: put hash in fieldinfo + FieldData *fp = fieldDataHash[hashPos]; + while (fp != nullptr && _tcscmp(fp->fieldInfo->name, fi->name) != 0) + fp = fp->next; + + if (fp == nullptr) { + fp = _CLNEW FieldData(_parent, this, fi); + fp->next = fieldDataHash[hashPos]; + fieldDataHash.values[hashPos] = fp; + + if (numAllFieldData == allFieldDataArray.length) { + allFieldDataArray.resize((int32_t) (allFieldDataArray.length * 1.5)); + + ValueArray newHashArray(fieldDataHash.length * 2); + + // Rehash + fieldDataHashMask = allFieldDataArray.length - 1; + for (size_t j = 0; j < fieldDataHash.length; j++) { + FieldData *fp0 = fieldDataHash[j]; + while (fp0 != nullptr) { + //todo: put hash code into fieldinfo to reduce number of hashes necessary + hashPos = Misc::thashCode(fp0->fieldInfo->name) & fieldDataHashMask; + FieldData *nextFP0 = fp0->next; + fp0->next = newHashArray[hashPos]; + newHashArray.values[hashPos] = fp0; + fp0 = nextFP0; + } + } + fieldDataHash.resize(newHashArray.length); + memcpy(fieldDataHash.values, newHashArray.values, newHashArray.length * sizeof(FieldData *)); + } + allFieldDataArray.values[numAllFieldData++] = fp; + } else { + assert(fp->fieldInfo == fi); + } + + if (thisFieldGen != fp->lastGen) { + + // First time we're seeing this field for this doc + fp->lastGen = thisFieldGen; + fp->fieldCount = 0; + fp->doNorms = fi->isIndexed && !fi->omitNorms; + + if (numFieldData == fieldDataArray.length) { + fieldDataArray.resize(fieldDataArray.length * 2); + } + fieldDataArray.values[numFieldData++] = fp; + } + + if (fp->fieldCount == fp->docFields.length) { + fp->docFields.resize(fp->docFields.length * 2); + } + + // Lazily allocate arrays for postings: + if (field->isIndexed() && fp->postingsHash.values == nullptr) + fp->initPostingArrays(); + + fp->docFields.values[fp->fieldCount++] = field; + } +} + +template +void SDocumentsWriter::ThreadState::writeDocument() { + + // If we hit an exception while appending to the + // stored fields or term vectors files, we have to + // abort all documents since we last flushed because + // it means those files are possibly inconsistent. + try { + _parent->numDocsInStore++; + + // Append norms for the fields we saw: + for (int32_t i = 0; i < numFieldData; i++) { + FieldData *fp = fieldDataArray[i]; + if (fp->doNorms) { + BufferedNorms *bn = _parent->norms[fp->fieldInfo->number]; + assert(bn != nullptr); + assert(bn->upto <= docID); + bn->fill(docID); + float_t norm = fp->boost * _parent->writer->getSimilarity()->lengthNorm(fp->fieldInfo->name, fp->length); + bn->add(norm); + } + } + } catch (CLuceneError &t) { + throw; + } + + if (_parent->bufferIsFull && !_parent->flushPending) { + _parent->flushPending = true; + doFlushAfter = true; + } +} + +template +void SDocumentsWriter::ThreadState::FieldData::initPostingArrays() { + // Target hash fill factor of <= 50% + // NOTE: must be a power of two for hash collision + // strategy to work correctly + postingsHashSize = 4; + postingsHashHalfSize = 2; + postingsHashMask = postingsHashSize - 1; + postingsHash.resize(postingsHashSize); +} + +template +void SDocumentsWriter::ThreadState::FieldData::processField(Analyzer *sanalyzer) { + length = 0; + position = 0; + offset = 0; + boost = threadState->docBoost; + + const int32_t maxFieldLength = _parent->writer->getMaxFieldLength(); + + const int32_t limit = fieldCount; + const ArrayBase &docFieldsFinal = docFields; + + try { + for (int32_t j = 0; j < limit; j++) { + Field *field = docFieldsFinal[j]; + + if (field->isIndexed()) { + invertField(field, sanalyzer, maxFieldLength); + } + + if (field->isStored()) { + threadState->numStoredFields++; + } + + docFieldsFinal.values[j] = NULL; + } + } catch (exception &ae) { + throw ae; + } +} + +template +void SDocumentsWriter::ThreadState::FieldData::rehashPostings(const int32_t newSize) { + const int32_t newMask = newSize - 1; + + ValueArray newHash(newSize); + int32_t hashPos, code; + const T *_pos = nullptr; + const T *start = nullptr; + Posting *p0; + + for (int32_t i = 0; i < postingsHashSize; i++) { + p0 = postingsHash[i]; + if (p0 != nullptr) { + start = threadState->scharPool->buffers[p0->textStart >> CHAR_BLOCK_SHIFT] + (p0->textStart & CHAR_BLOCK_MASK); + _pos = start; + while (*_pos != CLUCENE_END_OF_WORD) + _pos++; + code = 0; + while (_pos > start) + code = (code * 31) + *start++; + //code = (code * 31) + *--_pos; + + hashPos = code & newMask; + assert(hashPos >= 0); + if (newHash[hashPos] != NULL) { + const int32_t inc = ((code >> 8) + code) | 1; + do { + code += inc; + hashPos = code & newMask; + } while (newHash[hashPos] != NULL); + } + newHash.values[hashPos] = p0; + } + } + + postingsHashMask = newMask; + postingsHash.deleteArray(); + postingsHash.length = newHash.length; + postingsHash.values = newHash.takeArray(); + postingsHashSize = newSize; + postingsHashHalfSize = newSize >> 1; +} + +template +bool SDocumentsWriter::ThreadState::postingEquals(const T *tokenText, const int32_t tokenTextLen) { + if (p->textLen != tokenTextLen) { + return false; + } + const T *text = scharPool->buffers[p->textStart >> CHAR_BLOCK_SHIFT]; + assert(text != nullptr); + int32_t position = p->textStart & CHAR_BLOCK_MASK; + + int32_t tokenPos = 0; + for (; tokenPos < tokenTextLen; position++, tokenPos++) { + if (tokenText[tokenPos] != text[position]) + return false; + } + return CLUCENE_END_OF_WORD == text[position]; +} + +template +void SDocumentsWriter::ThreadState::writeFreqVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeFreqByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writeFreqByte((uint8_t) i); +} + +template +void SDocumentsWriter::ThreadState::writeProxVInt(int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeProxByte((uint8_t) ((i & 0x7f) | 0x80)); + i >>= 7;//unsigned shift... + } + writeProxByte((uint8_t) i); +} + +template +void SDocumentsWriter::ThreadState::writeFreqByte(uint8_t b) { + assert(freq != nullptr); + if (freq[freqUpto] != 0) { + freqUpto = postingsPool->allocSlice(freq, freqUpto); + freq = postingsPool->buffer; + p->freqUpto = postingsPool->tOffset; + } + freq[freqUpto++] = b; +} + +template +void SDocumentsWriter::ThreadState::writeProxByte(uint8_t b) { + assert(prox != nullptr); + if (prox[proxUpto] != 0) { + proxUpto = postingsPool->allocSlice(prox, proxUpto); + prox = postingsPool->buffer; + //p->proxUpto = postingsPool->tOffset; + assert(prox != nullptr); + } + prox[proxUpto++] = b; + assert(proxUpto != SDocumentsWriter::BYTE_BLOCK_SIZE); +} + +template +void SDocumentsWriter::ThreadState::writeProxBytes(const uint8_t *b, int32_t offset, int32_t len) { + const int32_t offsetEnd = offset + len; + while (offset < offsetEnd) { + if (prox[proxUpto] != 0) { + // End marker + proxUpto = postingsPool->allocSlice(prox, proxUpto); + prox = postingsPool->buffer; + //p->proxUpto = postingsPool->tOffset; + } + + prox[proxUpto++] = b[offset++]; + assert(proxUpto != SDocumentsWriter::BYTE_BLOCK_SIZE); + } +} + +template +void SDocumentsWriter::ThreadState::FieldData::addPosition(Token *token) { + const T *tokenText = token->termBuffer(); + const int32_t tokenTextLen = token->termLength(); + uint32_t code = 0; + + // Compute hashcode + //int32_t downto = tokenTextLen; + int32_t upto = 0; + //while (downto > 0) + while (upto < tokenTextLen) + code = (code * 31) + tokenText[upto++]; + uint32_t hashPos = code & postingsHashMask; + + assert(!postingsCompacted); + + // Locate Posting in hash + threadState->p = postingsHash[hashPos]; + + if (threadState->p != nullptr && !threadState->postingEquals(tokenText, tokenTextLen)) { + // Conflict: keep searching different locations in + // the hash table. + const uint32_t inc = ((code >> 8) + code) | 1; + do { + postingsHashConflicts++; + code += inc; + hashPos = code & postingsHashMask; + threadState->p = postingsHash[hashPos]; + } while (threadState->p != nullptr && !threadState->postingEquals(tokenText, tokenTextLen)); + } + + //int32_t proxCode; + try { + if (threadState->p != nullptr) { // term seen since last flush + if (threadState->docID != threadState->p->lastDocID) {// term not yet seen in this doc + // Now that we know doc freq for previous doc, + // write it & lastDocCode + threadState->freqUpto = threadState->p->freqUpto & BYTE_BLOCK_MASK; + threadState->freq = threadState->postingsPool->buffers[threadState->p->freqUpto >> BYTE_BLOCK_SHIFT]; + //if (1 == threadState->p->docFreq) + threadState->writeFreqVInt(threadState->p->lastDocCode | 1); + //else { + // threadState->writeFreqVInt(threadState->p->lastDocCode); + // threadState->writeFreqVInt(threadState->p->docFreq); + // } + threadState->p->freqUpto = threadState->freqUpto + (threadState->p->freqUpto & BYTE_BLOCK_NOT_MASK); + + //proxCode = position; + + //threadState->p->docFreq = 1; + + // Store code so we can write this after we're + // done with this new doc + threadState->p->lastDocCode = (threadState->docID - threadState->p->lastDocID) << 1; + threadState->p->lastDocID = threadState->docID; + + } else {// term already seen in this doc + //threadState->p->docFreq++; + + //proxCode = position - threadState->p->lastPosition; + } + } else {// term not seen before + if (0 == threadState->postingsFreeCountTS) { + _parent->getPostings(threadState->postingsFreeListTS); + threadState->postingsFreeCountTS = threadState->postingsFreeListTS.length; + } + + const int32_t textLen1 = 1 + tokenTextLen; + if (textLen1 + threadState->scharPool->tUpto > CHAR_BLOCK_SIZE) { + threadState->scharPool->nextBuffer(); + } + T *text = threadState->scharPool->buffer; + T *textUpto = text + threadState->scharPool->tUpto; + + // Pull next free Posting from free list + threadState->p = threadState->postingsFreeListTS[--threadState->postingsFreeCountTS]; + assert(threadState->p != nullptr); + threadState->p->textStart = textUpto + threadState->scharPool->tOffset - text; + threadState->p->textLen = tokenTextLen; + threadState->scharPool->tUpto += textLen1; + + memcpy(textUpto, tokenText, tokenTextLen * sizeof(T)); + textUpto[tokenTextLen] = CLUCENE_END_OF_WORD; + + assert(postingsHash[hashPos] == NULL); + + postingsHash.values[hashPos] = threadState->p; + numPostings++; + + if (numPostings == postingsHashHalfSize) + rehashPostings(2 * postingsHashSize); + + // Init first slice for freq & prox streams + const int32_t firstSize = levelSizeArray[0]; + + const int32_t upto1 = threadState->postingsPool->newSlice(firstSize); + threadState->p->freqStart = threadState->p->freqUpto = threadState->postingsPool->tOffset + upto1; + + //const int32_t upto2 = threadState->postingsPool->newSlice(firstSize); + //threadState->p->proxStart = threadState->p->proxUpto = threadState->postingsPool->tOffset + upto2; + + threadState->p->lastDocCode = threadState->docID << 1; + threadState->p->lastDocID = threadState->docID; + //threadState->p->docFreq = 1; + //proxCode = position; + } + + //threadState->proxUpto = threadState->p->proxUpto & BYTE_BLOCK_MASK; + //threadState->prox = threadState->postingsPool->buffers[threadState->p->proxUpto >> BYTE_BLOCK_SHIFT]; + //assert(threadState->prox != nullptr); + + //threadState->writeProxVInt(proxCode << 1); + + //threadState->p->proxUpto = threadState->proxUpto + (threadState->p->proxUpto & BYTE_BLOCK_NOT_MASK); + + threadState->p->lastPosition = position++; + } catch (CLuceneError &t) { + throw; + } +} + +template +void SDocumentsWriter::ThreadState::FieldData::invertField(Field *field, Analyzer *sanalyzer, const int32_t maxFieldLength) { + + if (length > 0) + position += sanalyzer->getPositionIncrementGap(fieldInfo->name); + + if (!field->isTokenized()) {// un-tokenized field + const T *stringValue = (T *) field->rawStringValue(); + const size_t valueLength = field->getFieldDataLength(); + Token *token = localSToken; + token->clear(); + + token->setText(stringValue, valueLength); + token->setStartOffset(offset); + token->setEndOffset(offset + valueLength); + addPosition(token); + offset += valueLength; + length++; + } else {// tokenized field + TokenStream *stream; + TokenStream *streamValue = field->tokenStreamValue(); + + if (streamValue != nullptr) + stream = streamValue; + else { + // not support by now + _CLTHROWA(CL_ERR_IllegalArgument, "field must have only STokenStream"); + } + + // reset the TokenStream to the first token + stream->reset(); + + try { + offsetEnd = offset - 1; + for (;;) { + Token *token = stream->next(localSToken); + if (token == nullptr) break; + position += (token->getPositionIncrement() - 1); + addPosition(token); + ++length; + } + offset = offsetEnd + 1; + } + _CLFINALLY( + stream->close();//don't delete, this stream is re-used + ) + } + + boost *= field->getBoost(); +} + +template +void SDocumentsWriter::ThreadState::processDocument(Analyzer *sanalyzer) { + + const int32_t numFields = numFieldData; + + // We process the document one field at a time + for (int32_t i = 0; i < numFields; i++) + fieldDataArray[i]->processField(sanalyzer); +} + +template +void SDocumentsWriter::ThreadState::trimFields() { + int32_t upto = 0; + for (int32_t i = 0; i < numAllFieldData; i++) { + FieldData *fp = allFieldDataArray[i]; + if (fp->lastGen == -1) { + // This field was not seen since the previous + // flush, so, free up its resources now + + // Unhash + const int32_t hashPos = Misc::thashCode(fp->fieldInfo->name) & fieldDataHashMask; + FieldData *last = nullptr; + FieldData *fp0 = fieldDataHash[hashPos]; + while (fp0 != fp) { + last = fp0; + fp0 = fp0->next; + } + assert(fp0 != nullptr); + + if (last == nullptr) + fieldDataHash.values[hashPos] = fp->next; + else + last->next = fp->next; + + _CLDELETE(fp); + } else { + // Reset + fp->lastGen = -1; + allFieldDataArray.values[upto++] = fp; + + if (fp->numPostings > 0 && ((float_t) fp->numPostings) / fp->postingsHashSize < 0.2) { + int32_t hashSize = fp->postingsHashSize; + + // Reduce hash so it's between 25-50% full + while (fp->numPostings < (hashSize >> 1) && hashSize >= 2) + hashSize >>= 1; + hashSize <<= 1; + + if (hashSize != fp->postingsHash.length) + fp->rehashPostings(hashSize); + } + } + } + //delete everything after up to in allFieldDataArray + for (size_t i = upto; i < allFieldDataArray.length; i++) { + allFieldDataArray[i] = NULL; + } + + // If we didn't see any norms for this field since + // last flush, free it + for (size_t i = 0; i < _parent->norms.length; i++) { + BufferedNorms *n = _parent->norms[i]; + if (n != nullptr && n->upto == 0) { + _CLLDELETE(n); + _parent->norms.values[i] = NULL; + } + } + + numAllFieldData = upto; +} + +template +void SDocumentsWriter::ThreadState::resetPostings() { + fieldGen = 0; + doFlushAfter = false; + postingsPool->reset(); + scharPool->reset(); + _parent->recyclePostings(this->postingsFreeListTS, this->postingsFreeCountTS); + this->postingsFreeCountTS = 0; + for (int32_t i = 0; i < numAllFieldData; i++) { + FieldData *fp = allFieldDataArray[i]; + fp->lastGen = -1; + if (fp->numPostings > 0) + fp->resetPostingArrays(); + } +} + +template +int32_t SDocumentsWriter::ThreadState::comparePostings(Posting *p1, Posting *p2) { + const T *pos1 = scharPool->buffers[p1->textStart >> CHAR_BLOCK_SHIFT] + (p1->textStart & CHAR_BLOCK_MASK); + const T *pos2 = scharPool->buffers[p2->textStart >> CHAR_BLOCK_SHIFT] + (p2->textStart & CHAR_BLOCK_MASK); + while (true) { + const T c1 = *pos1++; + const T c2 = *pos2++; + if (c1 < c2) + if (CLUCENE_END_OF_WORD == c2) + return 1; + else + return -1; + else if (c2 < c1) + if (CLUCENE_END_OF_WORD == c1) + return -1; + else + return 1; + else if (CLUCENE_END_OF_WORD == c1) + return 0; + } +} + +template +void SDocumentsWriter::ThreadState::quickSort(Posting **postings, int32_t lo, int32_t hi) { + if (lo >= hi) + return; + + int32_t mid = ((uint32_t) (lo + hi)) >> 1;//unsigned shift... + + if (comparePostings(postings[lo], postings[mid]) > 0) { + Posting *tmp = postings[lo]; + postings[lo] = postings[mid]; + postings[mid] = tmp; + } + + if (comparePostings(postings[mid], postings[hi]) > 0) { + Posting *tmp = postings[mid]; + postings[mid] = postings[hi]; + postings[hi] = tmp; + + if (comparePostings(postings[lo], postings[mid]) > 0) { + Posting *tmp2 = postings[lo]; + postings[lo] = postings[mid]; + postings[mid] = tmp2; + } + } + + int32_t left = lo + 1; + int32_t right = hi - 1; + + if (left >= right) + return; + + Posting *partition = postings[mid]; + + for (;;) { + while (comparePostings(postings[right], partition) > 0) + --right; + + while (left < right && comparePostings(postings[left], partition) <= 0) + ++left; + + if (left < right) { + Posting *tmp = postings[left]; + postings[left] = postings[right]; + postings[right] = tmp; + --right; + } else { + break; + } + } + + quickSort(postings, lo, left); + quickSort(postings, left + 1, hi); +} + +template +void SDocumentsWriter::finishDocument(ThreadState *state) { + // Now write the indexed document to the real files. + if (nextWriteDocID == state->docID) { + // It's my turn, so write everything now: + nextWriteDocID++; + state->writeDocument(); + } else { + // No other choices. + } +} + +template +bool SDocumentsWriter::updateDocument(Document *doc, Analyzer *sanalyzer) { + ThreadState *state = getThreadState(doc); + try { + bool success = false; + try { + try { + state->processDocument(sanalyzer); + } + _CLFINALLY( + finishDocument(state);) + success = true; + } + _CLFINALLY( + if (!success) { + // If this thread state had decided to flush, we + // must clear it so another thread can flush + if (state->doFlushAfter) { + state->doFlushAfter = false; + flushPending = false; + } + }) + } catch (exception &ae) { + abort(nullptr); + } + + return state->doFlushAfter; +} + +template<> +TCHAR *SDocumentsWriter::getSCharBlock() { + const size_t size = freeSCharBlocks.size(); + TCHAR *c; + if (0 == size) { + numBytesAlloc += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + c = _CL_NEWARRAY(TCHAR, CHAR_NUM_BYTE); + memset(c, 0, sizeof(TCHAR) * CHAR_BLOCK_SIZE); + } else { + c = *freeSCharBlocks.begin(); + freeSCharBlocks.remove(freeSCharBlocks.begin(), true); + } + numBytesUsed += CHAR_BLOCK_SIZE * CHAR_NUM_BYTE; + return c; +} + +template<> +char *SDocumentsWriter::getSCharBlock() { + const size_t size = freeSCharBlocks.size(); + char *c; + if (0 == size) { + numBytesAlloc += CHAR_BLOCK_SIZE * SCHAR_NUM_BYTE; + c = _CL_NEWARRAY(char, CHAR_BLOCK_SIZE); + memset(c, 0, sizeof(char) * CHAR_BLOCK_SIZE); + } else { + c = *freeSCharBlocks.begin(); + freeSCharBlocks.remove(freeSCharBlocks.begin(), true); + } + numBytesUsed += CHAR_BLOCK_SIZE * SCHAR_NUM_BYTE; + return c; +} + +template +void SDocumentsWriter::recycleSCharBlocks(ArrayBase &blocks, int32_t start, int32_t numBlocks) { + for (int32_t i = start; i < numBlocks; i++) { + freeSCharBlocks.push_back(blocks[i]); + blocks.values[i] = NULL; + } +} + +template +void SDocumentsWriter::getPostings(ValueArray &postings) { + numBytesUsed += postings.length * POSTING_NUM_BYTE; + int32_t numToCopy; + if (this->postingsFreeCountDW < postings.length) + numToCopy = this->postingsFreeCountDW; + else + numToCopy = postings.length; + + const int32_t start = this->postingsFreeCountDW - numToCopy; + if (numToCopy > 0) { + memcpy(postings.values, this->postingsFreeListDW.values + start, sizeof(Posting *) * numToCopy); + } + this->postingsFreeCountDW -= numToCopy; + + // Directly allocate the remainder if any + if (numToCopy < postings.length) { + const int32_t extra = postings.length - numToCopy; + const int32_t newPostingsAllocCount = this->postingsAllocCountDW + extra; + if (newPostingsAllocCount > this->postingsFreeListDW.length) + this->postingsFreeListDW.resize((int32_t) (1.25 * newPostingsAllocCount)); + + for (size_t i = numToCopy; i < postings.length; i++) { + postings.values[i] = _CLNEW Posting(); + numBytesAlloc += POSTING_NUM_BYTE; + this->postingsAllocCountDW++; + } + } +} + + +template +void SDocumentsWriter::writeNorms(const std::string &segmentName, int32_t totalNumDoc) { + IndexOutput *normsOut = directory->createOutput((segmentName + "." + IndexFileNames::NORMS_EXTENSION).c_str()); + + try { + normsOut->writeBytes(SegmentMerger::NORMS_HEADER, SegmentMerger::NORMS_HEADER_length); + + const int32_t numField = fieldInfos->size(); + + for (int32_t fieldIdx = 0; fieldIdx < numField; fieldIdx++) { + FieldInfo *fi = fieldInfos->fieldInfo(fieldIdx); + if (fi->isIndexed && !fi->omitNorms) { + BufferedNorms *n = norms[fieldIdx]; + int64_t v; + if (n == nullptr) + v = 0; + else { + v = n->out.getFilePointer(); + n->out.writeTo(normsOut); + n->reset(); + } + if (v < totalNumDoc) + fillBytes(normsOut, defaultNorm, (int32_t) (totalNumDoc - v)); + } + } + } + _CLFINALLY( + normsOut->close(); + _CLDELETE(normsOut);) +} + +template +void SDocumentsWriter::writeSegment(std::vector &flushedFiles) { + assert(nextDocID == numDocsInRAM); + + const std::string segmentName = segment; + + auto *termsOut = _CLNEW STermInfosWriter(directory, segmentName.c_str(), fieldInfos, + writer->getTermIndexInterval()); + + IndexOutput *freqOut = directory->createOutput((segmentName + ".frq").c_str()); + // TODO:add options in field index + IndexOutput *proxOut = nullptr; + if (0) { + proxOut = directory->createOutput((segmentName + ".prx").c_str()); + } + + // Gather all FieldData's that have postings, across all + // ThreadStates + std::vector allFields; + ThreadState *state = threadState; + state->trimFields(); + const int32_t numFields = state->numAllFieldData; + for (int32_t j = 0; j < numFields; j++) { + typename SDocumentsWriter::ThreadState::FieldData *fp = state->allFieldDataArray[j]; + if (fp->numPostings > 0) + allFields.push_back(fp); + } + + // Sort by field name + std::sort(allFields.begin(), allFields.end(), ThreadState::FieldData::sort); + const int32_t numAllFields = allFields.size(); + + skipListWriter = _CLNEW DefaultSkipListWriter(termsOut->skipInterval, + termsOut->maxSkipLevels, + numDocsInRAM, freqOut, proxOut); + + int32_t start = 0; + while (start < numAllFields) { + + const TCHAR *fieldName = allFields[start]->fieldInfo->name; + + int32_t end = start + 1; + while (end < numAllFields && _tcscmp(allFields[end]->fieldInfo->name, fieldName) == 0) + end++; + + ValueArray fields(end - start); + for (int32_t i = start; i < end; i++) + fields.values[i - start] = allFields[i]; + + // If this field has postings then add them to the + // segment + appendPostings(&fields, termsOut, freqOut, proxOut); + + for (size_t i = 0; i < fields.length; i++) + fields[i]->resetPostingArrays(); + + start = end; + } + + freqOut->close(); + _CLDELETE(freqOut); + if (proxOut != nullptr) { + proxOut->close(); + _CLDELETE(proxOut); + } + termsOut->close(); + _CLDELETE(termsOut); + _CLDELETE(skipListWriter); + + // Record all files we have flushed + flushedFiles.push_back(segmentFileName(IndexFileNames::FIELD_INFOS_EXTENSION)); + flushedFiles.push_back(segmentFileName(IndexFileNames::FREQ_EXTENSION)); + if (0) { + flushedFiles.push_back(segmentFileName(IndexFileNames::PROX_EXTENSION)); + } + flushedFiles.push_back(segmentFileName(IndexFileNames::TERMS_EXTENSION)); + flushedFiles.push_back(segmentFileName(IndexFileNames::TERMS_INDEX_EXTENSION)); + + if (hasNorms) { + writeNorms(segmentName, numDocsInRAM); + flushedFiles.push_back(segmentFileName(IndexFileNames::NORMS_EXTENSION)); + } + + resetPostingsData(); + + nextDocID = 0; + nextWriteDocID = 0; + numDocsInRAM = 0; + + // Maybe downsize this->postingsFreeListDW array + if (this->postingsFreeListDW.length > 1.5 * this->postingsFreeCountDW) { + int32_t newSize = this->postingsFreeListDW.length; + while (newSize > 1.25 * this->postingsFreeCountDW) { + newSize = (int32_t) (newSize * 0.8); + } + this->postingsFreeListDW.resize(newSize); + } +} + +template +void SDocumentsWriter::recyclePostings(ValueArray &postings, int32_t numPostings) { + // Move all Postings from this ThreadState back to our + // free list. We pre-allocated this array while we were + // creating Postings to make sure it's large enough + assert(this->postingsFreeCountDW + numPostings <= this->postingsFreeListDW.length); + if (numPostings > 0) + memcpy(this->postingsFreeListDW.values + this->postingsFreeCountDW, postings.values, numPostings * sizeof(Posting *)); + this->postingsFreeCountDW += numPostings; +} + +template +int32_t SDocumentsWriter::compareText(const T *text1, const T *text2) { + int32_t pos1 = 0; + int32_t pos2 = 0; + while (true) { + const T c1 = text1[pos1++]; + const T c2 = text2[pos2++]; + if (c1 < c2) + if (CLUCENE_END_OF_WORD == c2) + return 1; + else + return -1; + else if (c2 < c1) + if (CLUCENE_END_OF_WORD == c1) + return -1; + else + return 1; + else if (CLUCENE_END_OF_WORD == c1) + return 0; + } +} + +template +void SDocumentsWriter::appendPostings(ArrayBase *fields, + STermInfosWriter *termsOut, + IndexOutput *freqOut, + IndexOutput *proxOut) { + + const int32_t fieldNumber = (*fields)[0]->fieldInfo->number; + int32_t numFields = fields->length; + // In Doris, field number is always 1 by now. + assert(numFields == 1); + + ObjectArray mergeStatesData(numFields); + ValueArray mergeStates(numFields); + + for (int32_t i = 0; i < numFields; i++) { + FieldMergeState *fms = mergeStatesData.values[i] = _CLNEW FieldMergeState(); + fms->field = (*fields)[i]; + fms->postings = fms->field->sortPostings(); + + assert(fms->field->fieldInfo == (*fields)[0]->fieldInfo); + + // Should always be true + bool result = fms->nextTerm(); + assert(result); + } + memcpy(mergeStates.values, mergeStatesData.values, sizeof(FieldMergeState *) * numFields); + + const int32_t skipInterval = termsOut->skipInterval; + auto currentFieldStorePayloads = false; + + ValueArray termStates(numFields); + + while (numFields > 0) { + + // Get the next term to merge + termStates.values[0] = mergeStates[0]; + int32_t numToMerge = 1; + + for (int32_t i = 1; i < numFields; i++) { + const T *text = mergeStates[i]->text; + const int32_t textOffset = mergeStates[i]->textOffset; + const int32_t cmp = compareText(text + textOffset, termStates[0]->text + termStates[0]->textOffset); + + if (cmp < 0) { + termStates.values[0] = mergeStates[i]; + numToMerge = 1; + } else if (cmp == 0) + termStates.values[numToMerge++] = mergeStates[i]; + } + + int32_t df = 0; + int32_t lastPayloadLength = -1; + + int32_t lastDoc = 0; + + const T *start = termStates[0]->text + termStates[0]->textOffset; + const T *pos = start; + while (*pos != CLUCENE_END_OF_WORD) + pos++; + + int64_t freqPointer = freqOut->getFilePointer(); + int64_t proxPointer = 0; + if (proxOut != nullptr) { + proxPointer = proxOut->getFilePointer(); + } + + skipListWriter->resetSkip(); + + // Now termStates has numToMerge FieldMergeStates + // which all share the same term. Now we must + // interleave the docID streams. + while (numToMerge > 0) { + + if ((++df % skipInterval) == 0) { + skipListWriter->setSkipData(lastDoc, currentFieldStorePayloads, lastPayloadLength); + skipListWriter->bufferSkip(df); + } + + FieldMergeState *minState = termStates[0]; + for (int32_t i = 1; i < numToMerge; i++) + if (termStates[i]->docID < minState->docID) + minState = termStates[i]; + + const int32_t doc = minState->docID; + const int32_t termDocFreq = minState->termFreq; + + assert(doc < numDocsInRAM); + assert(doc > lastDoc || df == 1); + + const int32_t newDocCode = (doc - lastDoc) << 1; + lastDoc = doc; + + ByteSliceReader &prox = minState->prox; + + // Carefully copy over the prox + payload info, + // changing the format to match Lucene's segment + // format. + if (proxOut != nullptr) { + for (int32_t j = 0; j < termDocFreq; j++) { + const int32_t code = prox.readVInt(); + assert(0 == (code & 1)); + proxOut->writeVInt(code >> 1); + } + } + + docDeltaBuffer.push_back(doc); + + if (docDeltaBuffer.size() == PFOR_BLOCK_SIZE) { + std::vector compresseddata(4 * docDeltaBuffer.size() + PFOR_BLOCK_SIZE); + auto size = P4ENC(docDeltaBuffer.data(), docDeltaBuffer.size(), compresseddata.data()); + //auto size = p4nd1enc256v32(docDeltaBuffer.data(), docDeltaBuffer.size(), compresseddata.data()); + freqOut->writeVInt(docDeltaBuffer.size()); + freqOut->writeVInt(size); + freqOut->writeBytes(reinterpret_cast(compresseddata.data()), size); + docDeltaBuffer.resize(0); + } + + + if (!minState->nextDoc()) { + + // Remove from termStates + int32_t upto = 0; + for (int32_t i = 0; i < numToMerge; i++) + if (termStates[i] != minState) + termStates.values[upto++] = termStates[i]; + numToMerge--; + assert(upto == numToMerge); + + // Advance this state to the next term + + if (!minState->nextTerm()) { + // OK, no more terms, so remove from mergeStates + // as well + upto = 0; + for (int32_t i = 0; i < numFields; i++) + if (mergeStates[i] != minState) { + mergeStates.values[upto++] = mergeStates[i]; + } + numFields--; + assert(upto == numFields); + } + } + } + + assert(df > 0); + + // Done merging this term + freqOut->writeVInt(docDeltaBuffer.size()); + uint32_t lDoc = 0; + for (auto &docDelta: docDeltaBuffer) { + freqOut->writeVInt(docDelta - lDoc); + lDoc = docDelta; + } + docDeltaBuffer.resize(0); + int64_t skipPointer = skipListWriter->writeSkip(freqOut); + + // Write term + termInfo.set(df, freqPointer, proxPointer, (int32_t) (skipPointer - freqPointer)); + termsOut->add(fieldNumber, start, pos - start, &termInfo); + } +} + +template +int32_t SDocumentsWriter::flush(bool _closeDocStore) { + + if (segment.empty()) { + // In case we are asked to flush an empty segment + segment = writer->newSegmentName(); + } + + newFiles.clear(); + + docStoreOffset = numDocsInStore; + + int32_t docCount; + + assert(numDocsInRAM > 0); + + bool success = false; + + try { + fieldInfos->write(directory, (segment + ".fnm").c_str()); + + docCount = numDocsInRAM; + + writeSegment(newFiles);//write new files directly... + + success = true; + } + _CLFINALLY( + if (!success) + abort(nullptr);) + + return docCount; +} + +template +uint8_t *SDocumentsWriter::getByteBlock(bool trackAllocations) { + const int32_t size = freeByteBlocks.size(); + uint8_t *b; + if (0 == size) { + numBytesAlloc += BYTE_BLOCK_SIZE; + b = _CL_NEWARRAY(uint8_t, BYTE_BLOCK_SIZE); + memset(b, 0, sizeof(uint8_t) * BYTE_BLOCK_SIZE); + } else { + b = *freeByteBlocks.begin(); + freeByteBlocks.remove(freeByteBlocks.begin(), true); + } + if (trackAllocations) + numBytesUsed += BYTE_BLOCK_SIZE; + return b; +} + +template +void SDocumentsWriter::recycleBlocks(ArrayBase &blocks, int32_t start, int32_t end) { + for (int32_t i = start; i < end; i++) { + freeByteBlocks.push_back(blocks[i]); + blocks[i] = NULL; + } +} + +template +void SDocumentsWriter::fillBytes(IndexOutput *out, uint8_t b, int32_t numBytes) { + for (int32_t i = 0; i < numBytes; i++) + out->writeByte(b); +} + +template +T *SDocumentsWriter::SCharBlockPool::getNewBlock(bool) { + return BlockPool::parent->getSCharBlock(); +} + +template +void SDocumentsWriter::SCharBlockPool::reset() { + BlockPool::parent->recycleSCharBlocks(BlockPool::buffers, 0, 1 + BlockPool::bufferUpto); + BlockPool::bufferUpto = -1; + BlockPool::tUpto = BlockPool::blockSize; + BlockPool::tOffset = -BlockPool::blockSize; +} + +template +SDocumentsWriter::ThreadState::FieldData::FieldData(SDocumentsWriter *p, ThreadState *t, FieldInfo *fieldInfo) : docFields(ValueArray(1)), + _parent(p), + localSToken(_CLNEW Token) { + this->fieldCount = this->postingsHashSize = this->postingsHashHalfSize = this->postingsVectorsUpto = 0; + this->postingsHashMask = this->offsetEnd = 0; + this->offsetStartCode = this->offsetStart = this->numPostings = this->position = this->length = this->offset = 0; + this->boost = 0.0; + this->next = nullptr; + this->lastGen = -1; + this->fieldInfo = fieldInfo; + this->threadState = t; + this->postingsCompacted = false; +} + +template +SDocumentsWriter::ThreadState::FieldData::~FieldData() { + _CLDELETE(localSToken); +} + +template +int32_t SDocumentsWriter::ThreadState::FieldData::compareTo(NamedObject *o) { + if (o->getObjectName() != FieldData::getClassName()) + return -1; + return _tcscmp(fieldInfo->name, ((FieldData *) o)->fieldInfo->name); +} + +template +SDocumentsWriter::BufferedNorms::BufferedNorms() { + this->upto = 0; +} +template +void SDocumentsWriter::BufferedNorms::add(float_t norm) { + uint8_t b = search::Similarity::encodeNorm(norm); + out.writeByte(b); + upto++; +} +template +void SDocumentsWriter::BufferedNorms::reset() { + out.reset(); + upto = 0; +} +template +void SDocumentsWriter::BufferedNorms::fill(int32_t docID) { + // Must now fill in docs that didn't have this + // field. Note that this is how norms can consume + // tremendous storage when the docs have widely + // varying different fields, because we are not + // storing the norms sparsely (see LUCENE-830) + if (upto < docID) { + fillBytes(&out, defaultNorm, docID - upto); + upto = docID; + } +} +template class SDocumentsWriter; +template class SDocumentsWriter; +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/index/SDocumentWriter.h b/src/core/CLucene/index/SDocumentWriter.h new file mode 100644 index 00000000000..d89a42aa754 --- /dev/null +++ b/src/core/CLucene/index/SDocumentWriter.h @@ -0,0 +1,786 @@ +// +// Created by 姜凯 on 2022/9/16. +// + +#ifndef _lucene_index_SDocumentsWriter_ +#define _lucene_index_SDocumentsWriter_ + +#include "CLucene/_ApiHeader.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/util/Array.h" +#include "_DocumentsWriter.h" +#include "_FieldInfos.h" +#include "_TermInfo.h" +#include "_TermInfosWriter.h" + +CL_CLASS_DEF(analysis, Analyzer) +CL_CLASS_DEF(analysis, Token) +CL_CLASS_DEF(analysis, TokenStream) +CL_CLASS_DEF(document, Document) +CL_CLASS_DEF(document, Field) +CL_CLASS_DEF(util, StringReader) + +CL_NS_DEF(index) +class IndexWriter; +class FieldInfo; +class FieldInfos; +class TermInfo; +class TermInfosWriter; +class ByteBlockPool; +class SCharBlockPool; +class DefaultSkipListWriter; + +typedef CL_NS(util)::StringReader ReusableStringReader; + +template +class SDocumentsWriter : public IDocumentsWriter { +public: +private: + IndexWriter *writer{}; + CL_NS(store)::Directory *directory{}; + FieldInfos *fieldInfos;// All fields we've seen + int32_t nextDocID; // Next docID to be added + int32_t numDocsInRAM; // # docs buffered in RAM + int32_t numDocsInStore;// # docs written to doc stores + int32_t nextWriteDocID;// Next docID to be written + bool flushPending{}; // True when a thread has decided to flush + bool bufferIsFull{}; // True when it's time to write segment + bool hasNorms{}; + bool closed{}; + std::string segment;// Current segment we are working on + std::vector docDeltaBuffer; + +public: + class FieldMergeState; + + struct Posting { + int32_t textStart; // Address into char[] blocks where our text is stored + int32_t textLen; // our text length + //int32_t docFreq; // # times this term occurs in the current doc + int32_t freqStart; // Address of first uint8_t[] slice for freq + int32_t freqUpto; // Next write address for freq + //int32_t proxStart; // Address of first uint8_t[] slice + //int32_t proxUpto; // Next write address for prox + int32_t lastDocID; // Last docID where this term occurred + int32_t lastDocCode; // Code for prior doc + int32_t lastPosition;// Last position where this term occurred + }; + + /* Stores norms, buffered in RAM, until they are flushed + * to a partial segment. */ + class BufferedNorms { + public: + CL_NS(store)::RAMOutputStream out; + int32_t upto{}; + + BufferedNorms(); + void add(float_t norm); + void reset(); + void fill(int32_t docID); + }; + template + class BlockPool { + protected: + bool trackAllocations{}; + + int32_t numBuffer; + + int32_t bufferUpto;// Which buffer we are upto + int32_t blockSize{}; + + SDocumentsWriter *parent; + + public: + CL_NS(util)::ValueArray buffers; + int32_t tOffset;// Current head offset + int32_t tUpto; // Where we are in head buffer + T2 *buffer; // Current head buffer + + virtual T2 *getNewBlock(bool trackAllocations) = 0; + + BlockPool(SDocumentsWriter *_parent, int32_t _blockSize, bool trackAllocations) : buffers(CL_NS(util)::ValueArray(10)) { + this->blockSize = _blockSize; + this->parent = _parent; + bufferUpto = -1; + tUpto = blockSize; + tOffset = -blockSize; + buffer = nullptr; + numBuffer = 0; + this->trackAllocations = trackAllocations; + buffer = nullptr; + } + virtual ~BlockPool() { + buffers.deleteValues(); + } + + virtual void reset() = 0; + + void nextBuffer() { + if (1 + bufferUpto == buffers.length) { + //expand the number of buffers + buffers.resize((int32_t) (buffers.length * 1.5)); + } + buffer = buffers.values[1 + bufferUpto] = getNewBlock(trackAllocations); + bufferUpto++; + + tUpto = 0; + tOffset += blockSize; + } + }; + class SCharBlockPool : public BlockPool { + public: + explicit SCharBlockPool(SDocumentsWriter *_parent) : BlockPool(_parent, CHAR_BLOCK_SIZE, false) {} + virtual ~SCharBlockPool() = default; + T *getNewBlock(bool trackAllocations) override; + void reset() override; + }; + class ByteBlockPool : public BlockPool { + public: + ByteBlockPool(bool _trackAllocations, SDocumentsWriter *_parent) : BlockPool(_parent, BYTE_BLOCK_SIZE, _trackAllocations) {} + ~ByteBlockPool() override { + reset(); + //delete the first block + _CLDELETE_ARRAY(BlockPool::buffer); + } + uint8_t *getNewBlock(bool trackAllocations) override { + return BlockPool::parent->getByteBlock(trackAllocations); + } + int32_t newSlice(const int32_t size) { + if (BlockPool::tUpto > BYTE_BLOCK_SIZE - size) + BlockPool::nextBuffer(); + const int32_t upto = BlockPool::tUpto; + BlockPool::tUpto += size; + BlockPool::buffer[BlockPool::tUpto - 1] = 16; + return upto; + } + int32_t allocSlice(uint8_t *slice, const int32_t upto) { + const int32_t level = slice[upto] & 15; + assert(level < 10); + const int32_t newLevel = nextLevelArray[level]; + const int32_t newSize = levelSizeArray[newLevel]; + + // Maybe allocate another block + if (BlockPool::tUpto > BYTE_BLOCK_SIZE - newSize) + BlockPool::nextBuffer(); + + const int32_t newUpto = BlockPool::tUpto; + const uint32_t offset = newUpto + BlockPool::tOffset; + BlockPool::tUpto += newSize; + + // Copy forward the past 3 bytes (which we are about + // to overwrite with the forwarding address): + BlockPool::buffer[newUpto] = slice[upto - 3]; + BlockPool::buffer[newUpto + 1] = slice[upto - 2]; + BlockPool::buffer[newUpto + 2] = slice[upto - 1]; + + // Write forwarding address at end of last slice: + slice[upto - 3] = (uint8_t) (offset >> 24);//offset is unsigned... + slice[upto - 2] = (uint8_t) (offset >> 16); + slice[upto - 1] = (uint8_t) (offset >> 8); + slice[upto] = (uint8_t) offset; + + // Write new level: + BlockPool::buffer[BlockPool::tUpto - 1] = (uint8_t) (16 | newLevel); + + return newUpto + 3; + } + void reset() override { + if (BlockPool::bufferUpto != -1) { + // We allocated at least one buffer + + for (int i = 0; i < BlockPool::bufferUpto; i++) + // Fully zero fill buffers that we fully used + memset(BlockPool::buffers.values[i], 0, BYTE_BLOCK_SIZE); + + // Partial zero fill the final buffer + memset(BlockPool::buffers.values[BlockPool::bufferUpto], 0, BlockPool::tUpto); + + if (BlockPool::bufferUpto > 0) + // Recycle all but the first buffer + BlockPool::parent->recycleBlocks(BlockPool::buffers, 1, 1 + BlockPool::bufferUpto); + + // Re-use the first buffer + BlockPool::bufferUpto = 0; + BlockPool::tUpto = 0; + BlockPool::tOffset = 0; + BlockPool::buffer = BlockPool::buffers[0]; + } + } + }; + class ThreadState { + public: + class FieldData : public CL_NS(util)::Comparable { + private: + ThreadState *threadState; + + int32_t fieldCount; + CL_NS(util)::ValueArray docFields; + + FieldData *next; + + bool postingsCompacted; + + CL_NS(util)::ValueArray postingsHash; + int32_t postingsHashSize; + int32_t postingsHashHalfSize; + int32_t postingsHashMask; + int32_t postingsHashConflicts{}; + + int32_t postingsVectorsUpto; + SDocumentsWriter *_parent; + + int32_t offsetEnd; + CL_NS(analysis)::Token *localSToken; + + int32_t offsetStartCode; + int32_t offsetStart; + + void initPostingArrays(); + void addPosition(CL_NS(analysis)::Token *token); + void rehashPostings(int32_t newSize); + void compactPostings() { + int32_t upto = 0; + for (int32_t i = 0; i < postingsHashSize; i++) + if (postingsHash[i] != NULL) + postingsHash.values[upto++] = postingsHash[i]; + + assert(upto == numPostings); + postingsCompacted = true; + } + + public: + int32_t numPostings; + FieldInfo *fieldInfo; + int32_t lastGen; + int32_t position; + int32_t length; + int32_t offset; + float_t boost; + bool doNorms; + void resetPostingArrays() { + if (!postingsCompacted) + compactPostings(); + _parent->recyclePostings(this->postingsHash, numPostings); + memset(postingsHash.values, 0, postingsHash.length * sizeof(Posting *)); + postingsCompacted = false; + numPostings = 0; + } + + FieldData(SDocumentsWriter *_parent, ThreadState *__threadState, FieldInfo *fieldInfo); + ~FieldData(); + /** So Arrays.sort can sort us. */ + //int32_t compareTo(const void* o); + + /** Collapse the hash table & sort in-place. */ + CL_NS(util)::ValueArray *sortPostings() { + compactPostings(); + threadState->doPostingSort(postingsHash.values, numPostings); + return &postingsHash; + } + + void processField(CL_NS(analysis)::Analyzer *sanalyzer); + + void invertField(CL_NS(document)::Field *field, CL_NS(analysis)::Analyzer *sanalyzer, int32_t maxFieldLength); + + static bool sort(FieldData *e1, FieldData *e2) { + return _tcscmp(e1->fieldInfo->name, e2->fieldInfo->name) < 0; + } + + const char *getObjectName() const override { + return getClassName(); + } + static const char *getClassName() { + return "SDocumentsWriter::ThreadState"; + } + int32_t compareTo(lucene::util::NamedObject *) override; + friend class ThreadState; + friend class FieldMergeState; + }; + + private: + CL_NS(util)::ValueArray postingsFreeListTS;// Free Posting instances + int32_t postingsFreeCountTS; + + CL_NS(util)::ValueArray vectorFieldPointers; + CL_NS(util)::ValueArray vectorFieldNumbers; + + int32_t numStoredFields{};// How many stored fields in current doc + float_t docBoost{}; // Boost for current doc + + CL_NS(util)::ValueArray fieldDataArray;// Fields touched by current doc + int32_t numFieldData{}; // How many fields in current doc + int32_t numVectorFields; // How many vector fields in current doc + + CL_NS(util)::ValueArray fieldDataHash;// Hash FieldData instances by field name + int32_t fieldDataHashMask; + TCHAR *maxTermPrefix{};// Non-null prefix of a too-large term if this + // doc has one + char *maxStermPrefix{}; + + int32_t fieldGen{}; + + // Used to read a string value for a field + ReusableStringReader *stringReader; + + + ByteBlockPool *postingsPool; + SCharBlockPool *scharPool; + + // Current posting we are working on + Posting *p; + + //writeFreqByte... + uint8_t *freq{}; + int32_t freqUpto{}; + + //writeProxByte... + uint8_t *prox{}; + int32_t proxUpto{}; + + //writeOffsetByte... + uint8_t *offsets{}; + int32_t offsetUpto{}; + + //writePosByte... + uint8_t *pos{}; + int32_t posUpto{}; + + + /** Do in-place sort of Posting array */ + void doPostingSort(Posting **postings, int32_t numPosting) { + quickSort(postings, 0, numPosting - 1); + } + + void quickSort(Posting **postings, int32_t lo, int32_t hi); + + bool postingEquals(const T *tokenText, int32_t tokenTextLen); + + /** Compares term text for two Posting instance and + * returns -1 if p1 < p2; 1 if p1 > p2; else 0. + */ + int32_t comparePostings(Posting *p1, Posting *p2); + + + public: + int32_t numThreads;// Number of threads that use this instance + int32_t numAllFieldData{}; + CL_NS(util)::ValueArray allFieldDataArray;// All FieldData instances + bool doFlushAfter{}; + int32_t docID{};// docID we are now working on + + SDocumentsWriter *_parent; + + ThreadState(SDocumentsWriter *_parent); + virtual ~ThreadState(); + + /** Initializes shared state for this new document */ + void init(CL_NS(document)::Document *doc, int32_t docID); + + /** Tokenizes the fields of a document into Postings */ + void processDocument(CL_NS(analysis)::Analyzer *sanalyzer); + + /** If there are fields we've seen but did not see again + * in the last run, then free them up. Also reduce + * postings hash size. */ + void trimFields(); + + /** Clear the postings hash and return objects back to + * shared pool */ + void resetPostings(); + + /** Move all per-document state that was accumulated in + * the ThreadState into the "real" stores. */ + void writeDocument(); + + /** Write vInt into freq stream of current Posting */ + void writeFreqVInt(int32_t i); + + /** Write vInt into prox stream of current Posting */ + void writeProxVInt(int32_t i); + + /** Write uint8_t into freq stream of current Posting */ + void writeFreqByte(uint8_t b); + + /** Write uint8_t into prox stream of current Posting */ + void writeProxByte(uint8_t b); + + /** Currently only used to copy a payload into the prox + * stream. */ + void writeProxBytes(const uint8_t *b, int32_t offset, int32_t len); + + /** Write uint8_t into offsets stream of current + * PostingVector */ + //void writeOffsetByte(uint8_t b); + + /** Write uint8_t into pos stream of current + * PostingVector */ + //void writePosByte(uint8_t b); + friend class FieldMergeState; + }; + + class ByteSliceReader : public CL_NS(store)::IndexInput { + ByteBlockPool *pool; + int32_t bufferUpto; + const uint8_t *buffer; + int32_t limit; + int32_t level; + + int32_t upto; + int32_t bufferOffset; + int32_t endIndex; + + public: + ByteSliceReader() { + pool = NULL; + bufferUpto = 0; + buffer = 0; + limit = 0; + level = 0; + upto = 0; + bufferOffset = 0; + endIndex = 0; + } + virtual ~ByteSliceReader(){}; + void init(ByteBlockPool *_pool, int32_t _startIndex, int32_t _endIndex) { + assert(_endIndex - _startIndex > 0); + + level = 0; + this->pool = _pool; + this->endIndex = _endIndex; + + bufferUpto = _startIndex / BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * BYTE_BLOCK_SIZE; + buffer = pool->buffers[bufferUpto]; + upto = _startIndex & BYTE_BLOCK_MASK; + + const int32_t firstSize = levelSizeArray[0]; + + if (_startIndex + firstSize >= endIndex) { + // There is only this one slice to read + limit = endIndex & BYTE_BLOCK_MASK; + } else + limit = upto + firstSize - 4; + } + + uint8_t readByte() override { + // Assert that we are not @ EOF + assert(upto + bufferOffset < endIndex); + if (upto == limit) + nextSlice(); + return buffer[upto++]; + } + + int64_t writeTo(CL_NS(store)::IndexOutput *out) { + int64_t size = 0; + while (true) { + if (limit + bufferOffset == endIndex) { + assert(endIndex - bufferOffset >= upto); + out->writeBytes(buffer + upto, limit - upto); + size += limit - upto; + break; + } else { + out->writeBytes(buffer + upto, limit - upto); + size += limit - upto; + nextSlice(); + } + } + + return size; + } + void nextSlice() { + + // Skip to our next slice + const int32_t nextIndex = ((buffer[limit] & 0xff) << 24) + ((buffer[1 + limit] & 0xff) << 16) + ((buffer[2 + limit] & 0xff) << 8) + (buffer[3 + limit] & 0xff); + level = nextLevelArray[level]; + const int32_t newSize = levelSizeArray[level]; + + bufferUpto = nextIndex / BYTE_BLOCK_SIZE; + bufferOffset = bufferUpto * BYTE_BLOCK_SIZE; + + buffer = pool->buffers[bufferUpto]; + upto = nextIndex & BYTE_BLOCK_MASK; + + if (nextIndex + newSize >= endIndex) { + // We are advancing to the const slice + assert(endIndex - nextIndex > 0); + limit = endIndex - bufferOffset; + } else { + // This is not the const slice (subtract 4 for the + // forwarding address at the end of this new slice) + limit = upto + newSize - 4; + } + } + void readBytes(uint8_t *b, const int32_t len) override { + readBytes(b, len, 0); + } + void readBytes(uint8_t *b, int32_t len, int32_t offset) override { + while (len > 0) { + const int32_t numLeft = limit - upto; + if (numLeft < len) { + // Read entire slice + memcpy(b + offset, buffer + upto, numLeft * sizeof(uint8_t)); + b += numLeft; + len -= numLeft; + nextSlice(); + } else { + // This slice is the last one + memcpy(b + offset, buffer + upto, len * sizeof(uint8_t)); + upto += len; + break; + } + } + } + int64_t getFilePointer() const override { _CLTHROW_NOT_IMPLEMENT } + int64_t length() const override { _CLTHROW_NOT_IMPLEMENT } + void seek(const int64_t pos) override { _CLTHROW_NOT_IMPLEMENT } + void close() override {} + + IndexInput *clone() const override { _CLTHROW_NOT_IMPLEMENT } + const char *getDirectoryType() const override { + return ""; + } + const char *getObjectName() const override { + return getClassName(); + } + static const char *getClassName() { + return "DocumentsWriter::ByteSliceReader"; + } + + friend class FieldMergeState; + }; + + + class FieldMergeState { + private: + typename ThreadState::FieldData *field; + CL_NS(util)::ValueArray *postings; + + Posting *p; + T *text; + int32_t textOffset; + + int32_t postingUpto; + + ByteSliceReader freq; + ByteSliceReader prox; + + int32_t docID; + int32_t termFreq; + + public: + FieldMergeState() { + field = NULL; + postings = NULL; + p = NULL; + text = NULL; + textOffset = 0; + postingUpto = -1; + docID = 0; + termFreq = 0; + } + ~FieldMergeState() = default; + bool nextTerm() { + postingUpto++; + if (postingUpto == field->numPostings) + return false; + + p = (*postings)[postingUpto]; + docID = 0; + + text = field->threadState->scharPool->buffers[p->textStart >> CHAR_BLOCK_SHIFT]; + textOffset = p->textStart & CHAR_BLOCK_MASK; + + if (p->freqUpto > p->freqStart) + freq.init(field->threadState->postingsPool, p->freqStart, p->freqUpto); + else + freq.bufferOffset = freq.upto = freq.endIndex = 0; + + //prox.init(field->threadState->postingsPool, p->proxStart, p->proxUpto); + + // Should always be true + bool result = nextDoc(); + assert(result); + + return true; + } + + bool nextDoc() { + if (freq.bufferOffset + freq.upto == freq.endIndex) { + if (p->lastDocCode != -1) { + // Return last doc + docID = p->lastDocID; + termFreq = 1;//p->docFreq; + p->lastDocCode = -1; + return true; + } else + // EOF + return false; + } + + const auto code = (uint32_t) freq.readVInt(); + docID += code >> 1;//unsigned shift + if ((code & 1) != 0) + termFreq = 1; + else + termFreq = freq.readVInt(); + + return true; + } + + friend class SDocumentsWriter; + }; + + +public: + // Holds free pool of Posting instances + CL_NS(util)::ObjectArray postingsFreeListDW; + int32_t postingsFreeCountDW; + int32_t postingsAllocCountDW; + typedef CL_NS(util)::CLArrayList> FreeSCharBlocksType; + FreeSCharBlocksType freeSCharBlocks; + typedef CL_NS(util)::CLArrayList> FreeByteBlocksType; + FreeByteBlocksType freeByteBlocks; + int64_t numBytesAlloc; + int64_t numBytesUsed; + std::vector newFiles; + std::string docStoreSegment;// Current doc-store segment we are writing + int32_t docStoreOffset; // Current starting doc-store offset of current segment + +public: + SDocumentsWriter(CL_NS(store)::Directory *directory, IndexWriter *writer) : freeSCharBlocks(FreeSCharBlocksType(true)), + freeByteBlocks(FreeByteBlocksType(true)) { + numBytesAlloc = 0; + numBytesUsed = 0; + this->directory = directory; + this->writer = writer; + this->hasNorms = this->bufferIsFull = false; + + this->closed = this->flushPending = false; + this->threadState = nullptr; + fieldInfos = _CLNEW FieldInfos(); + + + this->closed = this->flushPending = false; + postingsFreeCountDW = postingsAllocCountDW = 0; + docStoreOffset = nextDocID = numDocsInRAM = numDocsInStore = nextWriteDocID = 0; + } + virtual ~SDocumentsWriter(); + int32_t flush(bool closeDocStore) override ; + bool addDocument(CL_NS(document)::Document *doc, CL_NS(analysis)::Analyzer *sanalyzer) override { + return updateDocument(doc, sanalyzer); + } + bool updateDocument(CL_NS(document)::Document *doc, CL_NS(analysis)::Analyzer *sanalyzer); + ThreadState *getThreadState(CL_NS(document)::Document *doc); + T *getSCharBlock(); + void recycleSCharBlocks(CL_NS(util)::ArrayBase &blocks, int32_t start, int32_t numBlocks); + uint8_t *getByteBlock(bool trackAllocations); + void recycleBlocks(CL_NS(util)::ArrayBase &blocks, int32_t start, int32_t end); + void finishDocument(ThreadState *state); + void getPostings(CL_NS(util)::ValueArray &postings); + static void fillBytes(CL_NS(store)::IndexOutput *out, uint8_t b, int32_t numBytes); + void appendPostings(CL_NS(util)::ArrayBase *fields, + STermInfosWriter *termsOut, + CL_NS(store)::IndexOutput *freqOut, + CL_NS(store)::IndexOutput *proxOut); + + void writeSegment(std::vector &flushedFiles); + + void recyclePostings(CL_NS(util)::ValueArray &postings, int32_t numPostings); + void writeNorms(const std::string &segmentName, int32_t totalNumDoc); + int32_t compareText(const T *text1, const T *text2); + void resetPostingsData() { + // All ThreadStates should be idle when we are called + segment.erase(); + numDocsInRAM = 0; + nextDocID = 0; + nextWriteDocID = 0; + bufferIsFull = false; + flushPending = false; + threadState->numThreads = 0; + threadState->resetPostings(); + numBytesUsed = 0; + } + + + std::string segmentFileName(const std::string &extension) { + return segment + "." + extension; + } + std::string segmentFileName(const char *extension) { + return segmentFileName(string(extension)); + } + int32_t getMaxBufferedDocs() override { + return 0; + } + float_t getRAMBufferSizeMB() override { + return 0.0f; + } + int32_t getNumDocsInRAM() override { + return numDocsInRAM; + } + const std::string &getDocStoreSegment() override { return docStoreSegment; } + bool hasDeletes() override { return false; } + std::string getSegment() override { + return segment; + } + int32_t getDocStoreOffset() override { + return docStoreOffset; + } + int32_t getNumBufferedDeleteTerms() override { + return 0; + } + void abort(AbortException *ae) override {} + void setMaxBufferedDocs(int32_t count) override {} + void setInfoStream(std::ostream *infoStream) override {} + void setRAMBufferSizeMB(float_t mb) override {} + void close() override {} + const std::vector &files() override { + auto EMPTY = _CLNEW std::vector; + return *EMPTY; + } + void setMaxBufferedDeleteTerms(int32_t _maxBufferedDeleteTerms) override {_CLTHROW_NOT_IMPLEMENT} + int32_t getMaxBufferedDeleteTerms() override {_CLTHROW_NOT_IMPLEMENT} + std::string closeDocStore() override {_CLTHROW_NOT_IMPLEMENT} + const std::vector *abortedFiles() override {_CLTHROW_NOT_IMPLEMENT} + bool bufferDeleteTerm(Term *term) override {_CLTHROW_NOT_IMPLEMENT} + bool pauseAllThreads() override {_CLTHROW_NOT_IMPLEMENT} + void resumeAllThreads() override {_CLTHROW_NOT_IMPLEMENT} + void createCompoundFile(const std::string &s) override {_CLTHROW_NOT_IMPLEMENT} + void clearBufferedDeletes() override {_CLTHROW_NOT_IMPLEMENT} + const TermNumMapType &getBufferedDeleteTerms() override {_CLTHROW_NOT_IMPLEMENT} + bool updateDocument(Term *t, CL_NS(document)::Document *doc, CL_NS(analysis)::Analyzer *analyzer) override {_CLTHROW_NOT_IMPLEMENT} + bool bufferDeleteTerms(const CL_NS(util)::ArrayBase *terms) override {_CLTHROW_NOT_IMPLEMENT} + int64_t getRAMUsed() override {_CLTHROW_NOT_IMPLEMENT} + const std::vector *getBufferedDeleteDocIDs() override {_CLTHROW_NOT_IMPLEMENT} + +public: + ThreadState *threadState; + CL_NS(util)::ObjectArray norms;// Holds norms until we flush + DefaultSkipListWriter *skipListWriter{}; + TermInfo termInfo;// minimize consing + + static const int32_t nextLevelArray[10]; + static const int32_t levelSizeArray[10]; + static const int32_t BYTE_BLOCK_SHIFT; + static const int32_t BYTE_BLOCK_SIZE; + static const int32_t BYTE_BLOCK_MASK; + static const int32_t BYTE_BLOCK_NOT_MASK; + + static const int32_t CHAR_BLOCK_SHIFT; + static const int32_t CHAR_BLOCK_SIZE; + static const int32_t CHAR_BLOCK_MASK; + + static const int32_t POINTER_NUM_BYTE; + static const int32_t INT_NUM_BYTE; + static const int32_t CHAR_NUM_BYTE; + static const int32_t SCHAR_NUM_BYTE; + + static const int32_t POSTING_NUM_BYTE;/// = OBJECT_HEADER_BYTES + 9*INT_NUM_BYTE + 5*POINTER_NUM_BYTE; + static int32_t OBJECT_HEADER_BYTES; + + static const uint8_t defaultNorm;///=Similarity::encodeNorm(1.0f) +}; +#define CLUCENE_END_OF_WORD 0x0 + +CL_NS_END +#endif \ No newline at end of file diff --git a/src/core/CLucene/index/SegmentInfos.cpp b/src/core/CLucene/index/SegmentInfos.cpp new file mode 100644 index 00000000000..00ae6284bdf --- /dev/null +++ b/src/core/CLucene/index/SegmentInfos.cpp @@ -0,0 +1,1133 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "_SegmentInfos.h" +#include "_IndexFileNames.h" +#include "_SegmentHeader.h" +#include "MultiReader.h" +#include +#include + +#include "CLucene/store/Directory.h" +#include "CLucene/util/Misc.h" + +CL_NS_USE(store) +CL_NS_USE(util) + +CL_NS_DEF(index) + +SegmentInfo::SegmentInfo(const char* _name, const int32_t _docCount, CL_NS(store)::Directory* _dir, + bool _isCompoundFile, bool _hasSingleNormFile, + int32_t _docStoreOffset, const char* _docStoreSegment, bool _docStoreIsCompoundFile) + : + docCount(_docCount), + preLockless(false), + delGen(SegmentInfo::NO), + isCompoundFile(_isCompoundFile ? SegmentInfo::YES : SegmentInfo::NO), + hasSingleNormFile(_hasSingleNormFile), + _sizeInBytes(-1), + docStoreOffset(_docStoreOffset), + docStoreSegment( _docStoreSegment == NULL ? "" : _docStoreSegment ), + docStoreIsCompoundFile(_docStoreIsCompoundFile) +{ + CND_PRECONDITION(docStoreOffset == -1 || !docStoreSegment.empty(), "failed testing for (docStoreOffset == -1 || docStoreSegment != NULL)"); + + this->name = _name; + this->dir = _dir; +} + +string SegmentInfo::segString(Directory* dir) { + string cfs; + try { + if (getUseCompoundFile()) + cfs = "c"; + else + cfs = "C"; + } catch (CLuceneError& ioe) { + if ( ioe.number() != CL_ERR_IO ) throw ioe; + cfs = "?"; + } + + string docStore; + + if (docStoreOffset != -1) + docStore = string("->") + docStoreSegment; + else + docStore = ""; + + return string(name) + ":" + + cfs + + string(this->dir == dir ? "" : "x") + + Misc::toString(docCount) + docStore; +} + SegmentInfo::SegmentInfo(CL_NS(store)::Directory* _dir, int32_t format, CL_NS(store)::IndexInput* input): + _sizeInBytes(-1) + { + this->dir = _dir; + + { + char aname[CL_MAX_PATH]; + input->readString(aname, CL_MAX_PATH); + this->name = aname; + } + + docCount = input->readInt(); + if (format <= SegmentInfos::FORMAT_LOCKLESS) { + delGen = input->readLong(); + if (format <= SegmentInfos::FORMAT_SHARED_DOC_STORE) { + docStoreOffset = input->readInt(); + if (docStoreOffset != -1) { + char aname[CL_MAX_PATH]; + input->readString(aname, CL_MAX_PATH); + docStoreSegment = aname; + docStoreIsCompoundFile = (1 == input->readByte()); + } else { + docStoreSegment = name; + docStoreIsCompoundFile = false; + } + } else { + docStoreOffset = -1; + docStoreSegment = name; + docStoreIsCompoundFile = false; + } + if (format <= SegmentInfos::FORMAT_SINGLE_NORM_FILE) { + hasSingleNormFile = (1 == input->readByte()); + } else { + hasSingleNormFile = false; + } + int32_t numNormGen = input->readInt(); + normGen.deleteValues(); + if (numNormGen == NO) { + // normGen is already NULL, we'll just set normGenLen to 0 + } else { + normGen.values = _CL_NEWARRAY(int64_t, numNormGen); + normGen.length = numNormGen; + for(int32_t j=0;jreadLong(); + } + } + isCompoundFile = input->readByte(); + preLockless = (isCompoundFile == CHECK_DIR); + } else { + delGen = CHECK_DIR; + //normGen=NULL; normGenLen=0; + isCompoundFile = CHECK_DIR; + preLockless = true; + hasSingleNormFile = false; + docStoreOffset = -1; + docStoreIsCompoundFile = false; + } + } + + void SegmentInfo::reset(const SegmentInfo* src) { + clearFiles(); + this->name = src->name; + docCount = src->docCount; + dir = src->dir; + preLockless = src->preLockless; + delGen = src->delGen; + docStoreOffset = src->docStoreOffset; + docStoreIsCompoundFile = src->docStoreIsCompoundFile; + if (src->normGen.values == NULL) { + this->normGen.deleteValues(); + }else{ + // optimized case to allocate new array only if current memory buffer is too small + if (this->normGen.length < src->normGen.length) { + normGen.resize(src->normGen.length); + }else{ + this->normGen.length = src->normGen.length; + } + memcpy(this->normGen.values, src->normGen.values, sizeof(int64_t) * this->normGen.length); + } + isCompoundFile = src->isCompoundFile; + hasSingleNormFile = src->hasSingleNormFile; + } + + SegmentInfo::~SegmentInfo(){ + normGen.deleteValues(); + } + + void SegmentInfo::setNumFields(const int32_t numFields) { + if (normGen.values == NULL) { + // normGen is null if we loaded a pre-2.1 segment + // file, or, if this segments file hasn't had any + // norms set against it yet: + normGen.resize(numFields); + + if (preLockless) { + // Do nothing: thus leaving normGen[k]==CHECK_DIR (==0), so that later we know + // we have to check filesystem for norm files, because this is prelockless. + + } else { + // This is a FORMAT_LOCKLESS segment, which means + // there are no separate norms: + for(int32_t i=0;i& __files = files(); + size_t size = __files.size(); + _sizeInBytes = 0; + for(size_t i=0;ifileLength(fileName); + } + } + return _sizeInBytes; + } + + void SegmentInfo::addIfExists(std::vector& files, const std::string& fileName){ + if (dir->fileExists(fileName.c_str())) + files.push_back(fileName); + } + + const vector& SegmentInfo::files(){ + if (!_files.empty()) { + // Already cached: + return _files; + } + + bool useCompoundFile = getUseCompoundFile(); + + if (useCompoundFile) { + _files.push_back( string(name) + "." + IndexFileNames::COMPOUND_FILE_EXTENSION); + } else { + ConstValueArray& exts = IndexFileNames::NON_STORE_INDEX_EXTENSIONS(); + for(size_t i=0;i &exts = IndexFileNames::STORE_INDEX_EXTENSIONS(); + for (size_t i = 0; i < exts.length; i++) + addIfExists(_files, docStoreSegment + "." + exts[i]); + } + } else if (!useCompoundFile) { + // We are not sharing, and, these files were not + // included in the compound file + ConstValueArray &exts = IndexFileNames::STORE_INDEX_EXTENSIONS(); + for (size_t i = 0; i < exts.length; i++) + addIfExists(_files, name + "." + exts[i]); + } + } + + string delFileName = IndexFileNames::fileNameFromGeneration(name.c_str(), (string(".") + IndexFileNames::DELETES_EXTENSION).c_str(), delGen); + if ( !delFileName.empty() && (delGen >= YES || dir->fileExists(delFileName.c_str()))) { + _files.push_back(delFileName); + } + + // Careful logic for norms files + if (normGen.values != NULL) { + for(size_t i=0;i= YES) { + // Definitely a separate norm file, with generation: + string gens = string(".") + IndexFileNames::SEPARATE_NORMS_EXTENSION; + gens += Misc::toString((int64_t)i); + _files.push_back(IndexFileNames::fileNameFromGeneration(name.c_str(), gens.c_str(), gen)); + } else if (NO == gen) { + // No separate norms but maybe plain norms + // in the non compound file case: + if (!hasSingleNormFile && !useCompoundFile) { + string fileName = name + "." + IndexFileNames::PLAIN_NORMS_EXTENSION; + fileName += i; + if (dir->fileExists(fileName.c_str())) { + _files.push_back(fileName); + } + } + } else if (CHECK_DIR == gen) { + // Pre-2.1: we have to check file existence + string fileName; + if (useCompoundFile) { + fileName = name + "." + IndexFileNames::SEPARATE_NORMS_EXTENSION; + fileName += Misc::toString((int64_t)i); + } else if (!hasSingleNormFile) { + fileName = name + "." + IndexFileNames::PLAIN_NORMS_EXTENSION; + fileName += Misc::toString((int64_t)i); + } + if ( !fileName.empty() && dir->fileExists(fileName.c_str())) { + _files.push_back(fileName); + } + } + } + } else if (preLockless || (!hasSingleNormFile && !useCompoundFile)) { + // Pre-2.1: we have to scan the dir to find all + // matching _X.sN/_X.fN files for our segment: + string prefix; + if (useCompoundFile) + prefix = name + "." + IndexFileNames::SEPARATE_NORMS_EXTENSION; + else + prefix = name + "." + IndexFileNames::PLAIN_NORMS_EXTENSION; + size_t prefixLength = prefix.length(); + vector allFiles; + if (dir->list(allFiles) == false ){ + string err = "cannot read directory "; + err += dir->toString(); + err += ": list() returned null"; + _CLTHROWA(CL_ERR_IO, err.c_str()); + } + for(size_t i=0;i prefixLength && _istdigit(fileName[prefixLength]) && fileName.compare(0,prefix.length(),prefix)==0 ) { + _files.push_back(fileName); + } + } + } + return _files; + } + + + + bool SegmentInfo::hasDeletions() const { + // Cases: + // + // delGen == NO: this means this segment was written + // by the LOCKLESS code and for certain does not have + // deletions yet + // + // delGen == CHECK_DIR: this means this segment was written by + // pre-LOCKLESS code which means we must check + // directory to see if .del file exists + // + // delGen >= YES: this means this segment was written by + // the LOCKLESS code and for certain has + // deletions + // + if (delGen == NO) { + return false; + } else if (delGen >= YES) { + return true; + } else { + return dir->fileExists(getDelFileName().c_str()); + } + } + + void SegmentInfo::advanceDelGen() { + // delGen 0 is reserved for pre-LOCKLESS format + if (delGen == NO) { + delGen = YES; + } else { + delGen++; + } + clearFiles(); + } + + void SegmentInfo::clearDelGen() { + delGen = NO; + clearFiles(); + } + + SegmentInfo* SegmentInfo::clone () { + SegmentInfo* si = _CLNEW SegmentInfo(name.c_str(), docCount, dir); + si->isCompoundFile = isCompoundFile; + si->delGen = delGen; + si->preLockless = preLockless; + si->hasSingleNormFile = hasSingleNormFile; + if (this->normGen.values != NULL) { + si->normGen.resize(this->normGen.length); + memcpy(si->normGen.values, this->normGen.values, sizeof(int64_t) * this->normGen.length); + } + si->docStoreOffset = docStoreOffset; + si->docStoreSegment = docStoreSegment; + si->docStoreIsCompoundFile = docStoreIsCompoundFile; + + return si; + } + + string SegmentInfo::getDelFileName() const { + if (delGen == NO) { + // In this case we know there is no deletion filename + // against this segment + return NULL; + } else { + // If delGen is CHECK_DIR, it's the pre-lockless-commit file format + return IndexFileNames::fileNameFromGeneration(name.c_str(), (string(".") + IndexFileNames::DELETES_EXTENSION).c_str(), delGen); + } + } + + bool SegmentInfo::hasSeparateNorms(const int32_t fieldNumber) const { + if ((normGen.values == NULL && preLockless) || (normGen.values != NULL && normGen[fieldNumber] == CHECK_DIR)) { + // Must fallback to directory file exists check: + return dir->fileExists( (name + string(".s") + Misc::toString(fieldNumber)).c_str() ); + } else if (normGen.values == NULL || normGen[fieldNumber] == NO) { + return false; + } else { + return true; + } + } + + bool SegmentInfo::hasSeparateNorms() const { + if (normGen.values == NULL) { + if (!preLockless) { + // This means we were created w/ LOCKLESS code and no + // norms are written yet: + return false; + } else { + // This means this segment was saved with pre-LOCKLESS + // code. So we must fallback to the original + // directory list check: + vector result; + if ( !dir->list(result) ) { + _CLTHROWA(CL_ERR_IO, (string("cannot read directory: ") + dir->toString() + string(" list() returned NULL")).c_str() ); + } + + string pattern = name + string(".s"); + for ( vector::iterator itr = result.begin(); + itr != result.end() ; itr ++ ){ + if(strncmp(itr->c_str(), pattern.c_str(), pattern.length() ) == 0 && + isdigit( (*itr)[pattern.length()])) { + return true; + } + } + return false; + } + } else { + // This means this segment was saved with LOCKLESS + // code so we first check whether any normGen's are >= 1 + // (meaning they definitely have separate norms): + for(size_t i=0;i= YES) { + return true; + } + } + // Next we look for any == 0. These cases were + // pre-LOCKLESS and must be checked in directory: + for(size_t j=0;jisCompoundFile = YES; + } else { + this->isCompoundFile = NO; + } + clearFiles(); + } + + bool SegmentInfo::getUseCompoundFile() const { + if (isCompoundFile == NO) { + return false; + } else if (isCompoundFile == YES) { + return true; + } else { + return dir->fileExists( ((string)name + "." + IndexFileNames::COMPOUND_FILE_EXTENSION).c_str() ); + } + } + + int32_t SegmentInfo::getDocStoreOffset() const { return docStoreOffset; } + + bool SegmentInfo::getDocStoreIsCompoundFile() const { return docStoreIsCompoundFile; } + + void SegmentInfo::setDocStoreIsCompoundFile(const bool v) { + docStoreIsCompoundFile = v; + clearFiles(); + } + + const string& SegmentInfo::getDocStoreSegment() const { + return docStoreSegment; + } + + void SegmentInfo::setDocStoreOffset(const int32_t offset) { + docStoreOffset = offset; + clearFiles(); + } + + void SegmentInfo::write(CL_NS(store)::IndexOutput* output) { + output->writeString(name); + output->writeInt(docCount); + output->writeLong(delGen); + output->writeInt(docStoreOffset); + if (docStoreOffset != -1) { + output->writeString(docStoreSegment); + output->writeByte(static_cast(docStoreIsCompoundFile ? 1:0)); + } + + output->writeByte(static_cast(hasSingleNormFile ? 1:0)); + if (normGen.values == NULL) { + output->writeInt(NO); + } else { + output->writeInt(normGen.length); + for(size_t j = 0; j < normGen.length; j++) { + output->writeLong(normGen[j]); + } + } + output->writeByte(isCompoundFile); + } + + void SegmentInfo::clearFiles() { + _files.clear(); + _sizeInBytes = -1; + } + + /** We consider another SegmentInfo instance equal if it + * has the same dir and same name. */ + bool SegmentInfo::equals(const SegmentInfo* obj) { + return (obj->dir == this->dir && obj->name.compare(this->name) == 0 ); + } + + + + + + std::ostream* SegmentInfos::infoStream = NULL; + + /** If non-null, information about retries when loading + * the segments file will be printed to this. + */ + void SegmentInfos::setInfoStream(std::ostream* infoStream) { + SegmentInfos::infoStream = infoStream; + } + + /** + * @see #setInfoStream + */ + std::ostream* SegmentInfos::getInfoStream() { + return infoStream; + } + + SegmentInfos::SegmentInfos(bool deleteMembers, int32_t reserveCount) : + generation(0),lastGeneration(0), infos(deleteMembers) { + //Func - Constructor + //Pre - deleteMembers indicates if the instance to be created must delete + // all SegmentInfo instances it manages when the instance is destroyed or not + // true -> must delete, false may not delete + //Post - An instance of SegmentInfos has been created. + + //initialize counter to 0 + counter = 0; + version = Misc::currentTimeMillis(); + if (reserveCount > 1) + infos.reserve(reserveCount); + } + + SegmentInfos::~SegmentInfos(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed. Depending on the constructor used + // the SegmentInfo instances that this instance managed have been deleted or not. + + //Clear the list of SegmentInfo instances - make sure everything is deleted + infos.clear(); + } + + SegmentInfo* SegmentInfos::info(int32_t i) const { + //Func - Returns a reference to the i-th SegmentInfo in the list. + //Pre - i >= 0 + //Post - A reference to the i-th SegmentInfo instance has been returned + + CND_PRECONDITION(i >= 0 && i < infos.size(), "i is out of bounds"); + + //Get the i-th SegmentInfo instance + SegmentInfo *ret = infos[i]; + + //Condition check to see if the i-th SegmentInfo has been retrieved + CND_CONDITION(ret != NULL,"No SegmentInfo instance found"); + + return ret; + } + + int64_t SegmentInfos::getCurrentSegmentGeneration( std::vector& files ) { + if ( files.size() == 0 ) { + return -1; + } + + int64_t max = -1; + + vector::iterator itr = files.begin(); + const char* file; + size_t seglen = strlen(IndexFileNames::SEGMENTS); + while ( itr != files.end() ) { + file = itr->c_str(); + if ( strncmp( file, IndexFileNames::SEGMENTS, seglen ) == 0 && strcmp( file, IndexFileNames::SEGMENTS_GEN ) != 0 ) { + int64_t gen = generationFromSegmentsFileName( file ); + if ( gen > max ) { + max = gen; + } + } + + itr++; + } + + return max; + } + + int64_t SegmentInfos::getCurrentSegmentGeneration( const CL_NS(store)::Directory* directory ) { + vector files; + if ( !directory->list(&files) ){ + _CLTHROWA(CL_ERR_IO, (string("cannot read directory ") + directory->toString() + string(": list() returned NULL")).c_str() ); + } + int64_t gen = getCurrentSegmentGeneration( files ); + return gen; + } + + string SegmentInfos::getCurrentSegmentFileName( vector& files ) { + return IndexFileNames::fileNameFromGeneration( IndexFileNames::SEGMENTS, "", getCurrentSegmentGeneration( files )); + } + + std::string SegmentInfos::getCurrentSegmentFileName( CL_NS(store)::Directory* directory ) { + return IndexFileNames::fileNameFromGeneration( IndexFileNames::SEGMENTS, "", getCurrentSegmentGeneration( directory )); + } + + std::string SegmentInfos::getCurrentSegmentFileName() { + return IndexFileNames::fileNameFromGeneration( IndexFileNames::SEGMENTS, "", lastGeneration ); + } + + int64_t SegmentInfos::generationFromSegmentsFileName( const char* fileName ) { + if ( strcmp( fileName, IndexFileNames::SEGMENTS ) == 0 ) { + return 0; + } else if ( strncmp( fileName, IndexFileNames::SEGMENTS, strlen(IndexFileNames::SEGMENTS) ) == 0 ) { + return CL_NS(util)::Misc::base36ToLong( fileName + strlen( IndexFileNames::SEGMENTS )+1 ); + } else { + TCHAR err[CL_MAX_PATH + 35]; + _sntprintf(err,CL_MAX_PATH + 35,_T("fileName \"%s\" is not a segments file"), fileName); + _CLTHROWA(CL_ERR_IllegalArgument, err); + return 0; + } + } + + std::string SegmentInfos::getNextSegmentFileName() { + int64_t nextGeneration; + + if ( generation == -1 ) { + nextGeneration = 1; + } else { + nextGeneration = generation+1; + } + + return IndexFileNames::fileNameFromGeneration( IndexFileNames::SEGMENTS, "", nextGeneration ); + } + + void SegmentInfos::clearto(size_t from, size_t end){ + size_t range = end - from; + if ( (infos.size() - from) >= range) { // Make sure we actually need to remove + segmentInfosType::iterator itr,bitr=infos.begin()+from,eitr=infos.end(); + size_t count = 0; + for(itr=bitr;itr!=eitr && count < range;++itr, count++) { + _CLLDELETE((*itr)); + } + infos.erase(bitr,bitr + count); + } + } + void SegmentInfos::add(SegmentInfo* info, int32_t pos){ + if ( pos == -1 ){ + infos.push_back(info); + }else{ + if ( pos < 0 || pos >= (int32_t)infos.size()+1 ) _CLTHROWA(CL_ERR_IllegalArgument, "pos is out of range"); + infos.insert( infos.begin()+pos, info ); + } + } + int32_t SegmentInfos::size() const{ + return infos.size(); + } + SegmentInfo* SegmentInfos::elementAt(int32_t pos) { + return infos.at(pos); + } + void SegmentInfos::setElementAt(SegmentInfo* si, int32_t pos) { + infos.set(pos, si); + } + void SegmentInfos::clear() { infos.clear(); } + + + void SegmentInfos::insert(SegmentInfos* _infos, bool takeMemory){ + infos.insert(infos.end(),_infos->infos.begin(),_infos->infos.end()); + if ( takeMemory ){ + while (_infos->infos.size() > 0 ) + _infos->infos.remove(_infos->infos.begin(), true ); + } + } + void SegmentInfos::insert(SegmentInfo* info){ + infos.push_back(info); + } + int32_t SegmentInfos::indexOf(const SegmentInfo* info) const{ + segmentInfosType::const_iterator itr = infos.begin(); + int32_t c=-1; + while ( itr != infos.end()){ + c++; + if ( *itr == info ){ + return c; + } + itr++; + } + return -1; + } + void SegmentInfos::range(size_t from, size_t to, SegmentInfos& ret) const{ + segmentInfosType::const_iterator itr = infos.begin(); + itr+= from; + for (size_t i=from;iopenInput(segmentFileName); + CND_CONDITION(input != NULL,"input == NULL"); + + generation = generationFromSegmentsFileName( segmentFileName ); + lastGeneration = generation; + + try { + int32_t format = input->readInt(); + if(format < 0){ // file contains explicit format info + // check that it is a format we can understand + if (format < CURRENT_FORMAT){ + char err[30]; + cl_sprintf(err,30,"Unknown format version: %d", format); + _CLTHROWA(CL_ERR_CorruptIndex, err); + } + version = input->readLong(); // read version + counter = input->readInt(); // read counter + } + else{ // file is in old format without explicit format info + counter = format; + } + + for (int32_t i = input->readInt(); i > 0; i--) { // read segmentInfos + infos.push_back( _CLNEW SegmentInfo(directory, format, input) ); + } + + if(format >= 0){ // in old format the version number may be at the end of the file + if (input->getFilePointer() >= input->length()) + version = CL_NS(util)::Misc::currentTimeMillis(); // old file format without version number + else + version = input->readLong(); // read version + } + success = true; + } _CLFINALLY({ + input->close(); + _CLDELETE(input); + if (!success) { + // Clear any segment infos we had loaded so we + // have a clean slate on retry: + clear(); + } + }); + } + + void SegmentInfos::read(Directory* directory) { + generation = lastGeneration = -1; + + FindSegmentsRead find(directory, this); + + find.run(); + } + + + void SegmentInfos::write(Directory* directory){ + //Func - Writes a new segments file based upon the SegmentInfo instances it manages + //Pre - directory is a valid reference to a Directory + //Post - The new segment has been written to disk + + string segmentFileName = getNextSegmentFileName(); + + // Always advance the generation on write: + if (generation == -1) { + generation = 1; + } else { + generation++; + } + + IndexOutput* output = directory->createOutput(segmentFileName.c_str()); + + bool success = false; + + try { + output->writeInt(CURRENT_FORMAT); // write FORMAT + output->writeLong(++version); // every write changes + // the index + output->writeInt(counter); // write counter + output->writeInt(size()); // write infos + for (int32_t i = 0; i < size(); i++) { + info(i)->write(output); + } + }_CLFINALLY ( + try { + output->close(); + _CLDELETE(output); + success = true; + } _CLFINALLY ( + if (!success) { + // Try not to leave a truncated segments_N file in + // the index: + directory->deleteFile(segmentFileName.c_str()); + } + ) + ) + + try { + output = directory->createOutput(IndexFileNames::SEGMENTS_GEN); + try { + output->writeInt(FORMAT_LOCKLESS); + output->writeLong(generation); + output->writeLong(generation); + } _CLFINALLY( + output->close(); + _CLDELETE(output); + ) + } catch (CLuceneError& e) { + if ( e.number() != CL_ERR_IO ) throw e; + // It's OK if we fail to write this file since it's + // used only as one of the retry fallbacks. + } + + lastGeneration = generation; + } + + SegmentInfos* SegmentInfos::clone() const{ + SegmentInfos* sis = _CLNEW SegmentInfos(true, infos.size()); + for(size_t i=0;isetElementAt(infos[i]->clone(), i); + } + return sis; + } + + int64_t SegmentInfos::getVersion() const { return version; } + int64_t SegmentInfos::getGeneration() const { return generation; } + int64_t SegmentInfos::getLastGeneration() const { return lastGeneration; } + + int64_t SegmentInfos::readCurrentVersion(Directory* directory){ + FindSegmentsVersion find(directory); + return find.run(); + } + + //void SegmentInfos::setDefaultGenFileRetryCount(const int32_t count) { defaultGenFileRetryCount = count; } + int32_t SegmentInfos::getDefaultGenFileRetryCount() { return defaultGenFileRetryCount; } + + //void SegmentInfos::setDefaultGenFileRetryPauseMsec(const int32_t msec) { defaultGenFileRetryPauseMsec = msec; } + int32_t SegmentInfos::getDefaultGenFileRetryPauseMsec() { return defaultGenFileRetryPauseMsec; } + + //void SegmentInfos::setDefaultGenLookaheadCount(const int32_t count) { defaultGenLookaheadCount = count;} + int32_t SegmentInfos::getDefaultGenLookahedCount() { return defaultGenLookaheadCount; } + + void SegmentInfos::_FindSegmentsFile::doRun(){ + string segmentFileName; + int64_t lastGen = -1; + int64_t gen = 0; + int32_t genLookaheadCount = 0; + bool retry = false; + CLuceneError exc; //saved exception + + int32_t method = 0; + + // Loop until we succeed in calling doBody() without + // hitting an IOException. An IOException most likely + // means a commit was in process and has finished, in + // the time it took us to load the now-old infos files + // (and segments files). It's also possible it's a + // true error (corrupt index). To distinguish these, + // on each retry we must see "forward progress" on + // which generation we are trying to load. If we + // don't, then the original error is real and we throw + // it. + + // We have three methods for determining the current + // generation. We try the first two in parallel, and + // fall back to the third when necessary. + + while( true ) { + + if ( 0 == method ) { + // Method 1: list the directory and use the highest + // segments_N file. This method works well as long + // as there is no stale caching on the directory + // contents (NOTE: NFS clients often have such stale + // caching): + vector files; + + int64_t genA = -1; + + if (directory != NULL){ + if (directory->list(&files)) { + genA = getCurrentSegmentGeneration( files ); + files.clear(); + } + } + + + if ( infoStream ){ + (*infoStream) << "[SIS]: directory listing genA=" << genA << "\n"; + } + + // Method 2: open segments.gen and read its + // contents. Then we take the larger of the two + // gen's. This way, if either approach is hitting + // a stale cache (NFS) we have a better chance of + // getting the right generation. + int64_t genB = -1; + if (directory != NULL) { + CLuceneError e; + for(int32_t i=0;iopenInput(IndexFileNames::SEGMENTS_GEN, genInput, e) ){ + if (e.number() == CL_ERR_IO ) { + if ( infoStream ){ + (*infoStream) << "[SIS]: segments.gen open: IOException " << e.what() << "\n"; + } + break; + } else { + genInput->close(); + _CLLDELETE(genInput); + throw e; + } + } + + if (genInput != NULL) { + try { + int32_t version = genInput->readInt(); + if (version == FORMAT_LOCKLESS) { + int64_t gen0 = genInput->readLong(); + int64_t gen1 = genInput->readLong(); + //CL_TRACE("fallback check: %d; %d", gen0, gen1); + if (gen0 == gen1) { + // The file is consistent. + genB = gen0; + genInput->close(); + _CLDELETE(genInput); + break; + } + } + } catch (CLuceneError &err2) { + if (err2.number() != CL_ERR_IO) { + genInput->close(); + _CLLDELETE(genInput); + throw err2; // retry only for IOException + } + } _CLFINALLY({ + genInput->close(); + _CLDELETE(genInput); + }); + } + + _LUCENE_SLEEP(defaultGenFileRetryPauseMsec); + /* + //todo: Wrap the LUCENE_SLEEP call above with the following try/catch block if + // InterruptedException is implemented + try { + } catch (CLuceneError &e) { + //if (err2.number != CL_ERR_Interrupted) // retry only for InterruptedException + // todo: see if CL_ERR_Interrupted needs to be added... + throw e; + }*/ + + } + } + + //CL_TRACE("%s check: genB=%d", IndexFileNames::SEGMENTS_GEN, genB); + + // Pick the larger of the two gen's: + if (genA > genB) + gen = genA; + else + gen = genB; + + if (gen == -1) { + // Neither approach found a generation + _CLTHROWA(CL_ERR_IO, (string("No segments* file found in ") + directory->toString()).c_str()); + } + } + + // Third method (fallback if first & second methods + // are not reliable): since both directory cache and + // file contents cache seem to be stale, just + // advance the generation. + if ( 1 == method || ( 0 == method && lastGen == gen && retry )) { + + method = 1; + + if (genLookaheadCount < defaultGenLookaheadCount) { + gen++; + genLookaheadCount++; + //CL_TRACE("look ahead increment gen to %d", gen); + } + } + + if (lastGen == gen) { + + // This means we're about to try the same + // segments_N last tried. This is allowed, + // exactly once, because writer could have been in + // the process of writing segments_N last time. + + if (retry) { + // OK, we've tried the same segments_N file + // twice in a row, so this must be a real + // error. We throw the original exception we + // got. + throw exc; + } else { + retry = true; + } + + } else { + // Segment file has advanced since our last loop, so + // reset retry: + retry = false; + } + + lastGen = gen; + + segmentFileName = IndexFileNames::fileNameFromGeneration(IndexFileNames::SEGMENTS, "", gen); + + CLuceneError saved_error; + if ( tryDoBody(segmentFileName.c_str(), saved_error) ){ + return; + } + + // Save the original root cause: + if (exc.number() == 0) { + CND_CONDITION( saved_error.number() > 0, "Unsupported error code"); + exc.set(saved_error.number(),saved_error.what()); + } + + //CL_TRACE("primary Exception on '" + segmentFileName + "': " + err + "'; will retry: retry=" + retry + "; gen = " + gen); + + if (!retry && gen > 1) { + + // This is our first time trying this segments + // file (because retry is false), and, there is + // possibly a segments_(N-1) (because gen > 1). + // So, check if the segments_(N-1) exists and + // try it if so: + string prevSegmentFileName = IndexFileNames::fileNameFromGeneration( IndexFileNames::SEGMENTS, "", gen-1 ); + + bool prevExists=false; + if (directory != NULL) + prevExists = directory->fileExists(prevSegmentFileName.c_str()); + else + prevExists = Misc::dir_Exists( (string(fileDirectory) + prevSegmentFileName).c_str() ); + + if (prevExists) { + //CL_TRACE("fallback to prior segment file '%s'", prevSegmentFileName); + CLuceneError saved_error; + if ( tryDoBody(prevSegmentFileName.c_str(), saved_error) ){ + return; + } + //CL_TRACE("secondary Exception on '" + prevSegmentFileName + "': " + err2 + "'; will retry"); + } + } + } + } + SegmentInfos::FindSegmentsRead::FindSegmentsRead( CL_NS(store)::Directory* dir, SegmentInfos* _this ) : + SegmentInfos::FindSegmentsFile(dir) { + this->_this = _this; + } + bool SegmentInfos::FindSegmentsRead::doBody( const char* segmentFileName ) { + //Have SegmentInfos read the segments file in directory + _this->read(directory, segmentFileName); + return true; + } + + SegmentInfos::FindSegmentsVersion::FindSegmentsVersion( CL_NS(store)::Directory* dir ) : + SegmentInfos::FindSegmentsFile(dir) { + } + + int64_t SegmentInfos::FindSegmentsVersion::doBody( const char* segmentFileName ) { + + IndexInput* input = directory->openInput( segmentFileName ); + + int32_t format = 0; + int64_t version=0; + try { + format = input->readInt(); + if(format < 0){ + if(format < CURRENT_FORMAT){ + char err[30]; + cl_sprintf(err,30,"Unknown format version: %d",format); + _CLTHROWA(CL_ERR_CorruptIndex,err); + } + version = input->readLong(); // read version + } + } + _CLFINALLY( input->close(); _CLDELETE(input); ); + + if(format < 0) + return version; + + // We cannot be sure about the format of the file. + // Therefore we have to read the whole file and cannot simply seek to the version entry. + SegmentInfos* sis = _CLNEW SegmentInfos(); + sis->read(directory, segmentFileName); + version = sis->getVersion(); + _CLDELETE(sis); + + return version; + + } + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentMergeInfo.cpp b/src/core/CLucene/index/SegmentMergeInfo.cpp new file mode 100644 index 00000000000..035cdd2d8ae --- /dev/null +++ b/src/core/CLucene/index/SegmentMergeInfo.cpp @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SegmentHeader.h" +#include "_SegmentMergeInfo.h" +#include "_SegmentTermEnum.h" + +CL_NS_DEF(index) + +SegmentMergeInfo::SegmentMergeInfo(const int32_t b, TermEnum* te, IndexReader* r): + docMap(NULL), + termEnum(te), + base(b), + reader(r) +{ +//Func - Constructor +//Pre - b >= 0 +// te contains a valid reference to a SegmentTermEnum instance +// r contains a valid reference to a SegmentReader instance +//Post - The instance has been created + + CND_PRECONDITION(b >= 0, "b is a negative number"); + + postings=NULL; + term = te->term(); +} + +SegmentMergeInfo::~SegmentMergeInfo(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed + + close(); +} + +int32_t* SegmentMergeInfo::getDocMap(){ + if ( docMap == NULL ){ + // build array which maps document numbers around deletions + if (reader->hasDeletions()) { + //Get the total number of documents managed by the reader including the deleted ones + int32_t maxDoc = reader->maxDoc(); + //Create a map for all documents + docMap = _CL_NEWARRAY(int32_t,maxDoc); + int32_t j = 0; + //Iterate through all the document numbers + for (int32_t i = 0; i < maxDoc; i++) { + //Check if document i is marked deleted + if (reader->isDeleted(i)){ + //Document i has not been marked deleted so assign -1 + docMap[i] = -1; + }else{ + docMap[i] = j++; + } + } + } + } + return docMap; +} + +TermPositions* SegmentMergeInfo::getPositions() { + if (postings == NULL) { + postings = reader->termPositions(); + } + return postings; +} + + +bool SegmentMergeInfo::next() { +//Func - Moves the current term of the enumeration termEnum to the next and term +// points to this new current term +//Pre - true +//Post - Returns true if the term has been moved to the next otherwise false + if (termEnum->next()) { + _CLDECDELETE(term); + term = termEnum->term(); + return true; + } else { + _CLDECDELETE(term); //TODO: test HighFreqTerms errors with this + term = NULL; + return false; + } +} + +void SegmentMergeInfo::close() { +//Func - Closes the the resources +//Pre - true +//Post - The resources have been closed + + //First make sure posting has been closed + if ( postings != NULL ){ + postings->close(); + _CLVDELETE(postings); //todo: not a clucene object... should be + } + + if ( termEnum != NULL ){ + termEnum->close(); + _CLDELETE(termEnum); + } + _CLDECDELETE(term); + _CLDELETE_ARRAY(docMap); +} + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentMergeQueue.cpp b/src/core/CLucene/index/SegmentMergeQueue.cpp new file mode 100644 index 00000000000..ba349371359 --- /dev/null +++ b/src/core/CLucene/index/SegmentMergeQueue.cpp @@ -0,0 +1,76 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/PriorityQueue.h" +#include "_SegmentHeader.h" +#include "_SegmentMergeInfo.h" +#include "_SegmentMergeQueue.h" + +CL_NS_DEF(index) + + + SegmentMergeQueue::SegmentMergeQueue(const int32_t size) { + //Func - Constructor + // Creates a queue of length size + //Pre - size >= 0 + //Post - The queue has been created of length size + + //BVK: bug. changed condition from size > 0 to size >= 0 + //if size is 0, as it is when retrieving a TermEnum + //from an empty index this should this should not fail. + CND_PRECONDITION(size >= 0, "size is too small"); + + //Call the initialize method of its superclass. The boolean value passed here + //indicates that the superclass PriorityQueue takes the responsibility to have its elements deleted + //The destructor of SegmentMergInfo will make sure that each intstance it will be closed properly + //before it is deleted + initialize(size,true); + } + + SegmentMergeQueue::~SegmentMergeQueue(){ + //Func - Destructor + // Does nothing as its parent class will clean up everything + //Pre - true + //Post - true + close(); + } + + void SegmentMergeQueue::close() { + //Func - Closes and destroyes all SegmentMergeInfo Instances in the queue + //Pre - true + //post - All SegmentMergeInfo Instances in the queue have been closed and deleted + // The queue is now empty but can still be used + + //call the clear method of the parent class PriorityQueue + clear(); + } + + bool SegmentMergeQueue::lessThan(SegmentMergeInfo* stiA, SegmentMergeInfo* stiB) { + //Func - Overloaded method that implements the lessThan operator for the parent class + // This method is used by the parent class Priority queue to reorder its internal + // data structures. This implementation check if stiA is less than the current term of stiB. + //Pre - stiA != NULL + // stiB != NULL + //Post - true is returned if stiA < stiB otherwise false + + CND_PRECONDITION(stiA != NULL, "stiA is NULL"); + CND_PRECONDITION(stiB != NULL, "stiB is NULL"); + + //Compare the two terms + int32_t comparison = stiA->term->compareTo(stiB->term); + //Check if they match + if (comparison == 0){ //todo: can we do an optimized compare here? compare using equals, then compare properly? + //If the match check if the base of stiA is smaller than the base of stiB + //Note that different bases means that the terms of stiA an stiB ly in different segments + return stiA->base < stiB->base; + }else{ + //Terms didn't match so return the difference in positions + return comparison < 0; + } + } + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentMerger.cpp b/src/core/CLucene/index/SegmentMerger.cpp new file mode 100644 index 00000000000..284ee2694e5 --- /dev/null +++ b/src/core/CLucene/index/SegmentMerger.cpp @@ -0,0 +1,813 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SegmentHeader.h" +#include "CLucene/util/PriorityQueue.h" +#include "CLucene/util/Misc.h" +#include "IndexReader.h" +#include "IndexWriter.h" +#include "_SegmentMerger.h" +#include "_FieldsWriter.h" +#include "CLucene/document/Document.h" +#include +#include "CLucene/index/_IndexFileNames.h" +#include "_CompoundFile.h" +#include "_SkipListWriter.h" +#include "CLucene/document/FieldSelector.h" + +CL_NS_USE(util) +CL_NS_USE(document) +CL_NS_USE(store) +CL_NS_DEF(index) + +const uint8_t SegmentMerger::NORMS_HEADER[] = {'N','R','M', (uint8_t)-1}; +const int SegmentMerger::NORMS_HEADER_length = 4; +int32_t SegmentMerger::MAX_RAW_MERGE_DOCS = 4192; + +void SegmentMerger::init(){ + skipListWriter = NULL; + freqOutput = NULL; + proxOutput = NULL; + termInfosWriter = NULL; + queue = NULL; + fieldInfos = NULL; + checkAbort = NULL; + skipInterval = 0; +} + +SegmentMerger::SegmentMerger(IndexWriter* writer, const char* name, MergePolicy::OneMerge* merge){ +//Func - Constructor +//Pre - dir holds a valid reference to a Directory +// name != NULL +//Post - Instance has been created + + CND_PRECONDITION(name != NULL, "name is NULL"); + + this->init(); + this->directory = writer->getDirectory(); + this->segment = name; + if (merge != NULL) + this->checkAbort = _CLNEW CheckAbort(merge, directory); + this->termIndexInterval= writer->getTermIndexInterval(); + this->mergedDocs = 0; + this->maxSkipLevels = 0; +} + +SegmentMerger::~SegmentMerger(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed + + //Clear the readers set + readers.clear(); + + //Delete field Infos + _CLDELETE(fieldInfos); + //Close and destroy the IndexOutput to the Frequency File + if (freqOutput != NULL){ + freqOutput->close(); + _CLDELETE(freqOutput); + } + //Close and destroy the IndexOutput to the Prox File + if (proxOutput != NULL){ + proxOutput->close(); + _CLDELETE(proxOutput); + } + //Close and destroy the termInfosWriter + if (termInfosWriter != NULL){ + termInfosWriter->close(); + _CLDELETE(termInfosWriter); + } + //Close and destroy the queue + if (queue != NULL){ + queue->close(); + _CLDELETE(queue); + } + + _CLDELETE(checkAbort); + _CLDELETE(skipListWriter); + +} + +void SegmentMerger::add(IndexReader* reader) { +//Func - Adds a IndexReader to the set of readers +//Pre - reader contains a valid reference to a IndexReader +//Post - The SegementReader reader has been added to the set of readers + + readers.push_back(reader); +} + +IndexReader* SegmentMerger::segmentReader(const int32_t i) { +//Func - Returns a reference to the i-th IndexReader +//Pre - 0 <= i < readers.size() +//Post - A reference to the i-th IndexReader has been returned + + CND_PRECONDITION(i >= 0, "i is a negative number"); + CND_PRECONDITION((size_t)i < readers.size(), "i is bigger than the number of IndexReader instances"); + + //Retrieve the i-th IndexReader + IndexReader* ret = readers[i]; + CND_CONDITION(ret != NULL,"No IndexReader found"); + + return ret; +} + +int32_t SegmentMerger::merge(bool mergeDocStores) { + this->mergeDocStores = mergeDocStores; + + // NOTE: it's important to add calls to + // checkAbort.work(...) if you make any changes to this + // method that will spend alot of time. The frequency + // of this check impacts how long + // IndexWriter.close(false) takes to actually stop the + // threads. + + mergedDocs = mergeFields(); + + mergeTerms(); + mergeNorms(); + + if (mergeDocStores && fieldInfos->hasVectors()) + mergeVectors(); + + return mergedDocs; +} + +void SegmentMerger::closeReaders(){ + for (uint32_t i = 0; i < readers.size(); i++) { // close readers + IndexReader* reader = readers[i]; + reader->close(); + } +} + +void SegmentMerger::createCompoundFile(const char* filename, std::vector* files){ + CompoundFileWriter* cfsWriter = _CLNEW CompoundFileWriter(directory, filename, checkAbort); + + bool ownFiles = false; + if ( files == NULL ){ + files = new vector; + files->reserve(IndexFileNames::COMPOUND_EXTENSIONS().length + 1); + ownFiles = true; + } + + // Basic files + for (int32_t i = 0; i < IndexFileNames::COMPOUND_EXTENSIONS().length; i++) { + const char* ext = IndexFileNames::COMPOUND_EXTENSIONS()[i]; + if (mergeDocStores || (strcmp(ext,IndexFileNames::FIELDS_EXTENSION) != 0 && + strcmp(ext,IndexFileNames::FIELDS_INDEX_EXTENSION) != 0 ) ){ + files->push_back ( string(segment) + "." + ext ); + } + } + + // Field norm files + for (size_t i = 0; i < fieldInfos->size(); i++) { + FieldInfo* fi = fieldInfos->fieldInfo(i); + if (fi->isIndexed && !fi->omitNorms) { + files->push_back ( segment + "." + IndexFileNames::NORMS_EXTENSION ); + break; + } + } + + // Vector files + if ( mergeDocStores && fieldInfos->hasVectors()) { + for (int32_t i = 0; i < IndexFileNames::VECTOR_EXTENSIONS().length; i++) { + files->push_back ( segment + "." + IndexFileNames::VECTOR_EXTENSIONS()[i] ); + } + } + + // Now merge all added files + for ( size_t i=0;isize();i++ ){ + cfsWriter->addFile( (*files)[i].c_str()); + } + + // Perform the merge + cfsWriter->close(); + _CLDELETE(cfsWriter); + if ( ownFiles ) delete files; +} + +void SegmentMerger::addIndexed(IndexReader* reader, FieldInfos* fieldInfos, StringArrayWithDeletor& names, + bool storeTermVectors, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool storePayloads){ + + StringArrayWithDeletor::const_iterator itr = names.begin(); + while ( itr != names.end() ){ + fieldInfos->add(*itr, true, + storeTermVectors, storePositionWithTermVector, + storeOffsetWithTermVector, !reader->hasNorms(*itr), storePayloads); + + ++itr; + } +} + + +// for merging we don't want to compress/uncompress the data, so to tell the FieldsReader that we're +// in merge mode, we use this FieldSelector +class FieldSelectorMerge: public FieldSelector{ +public: + FieldSelectorResult accept(const TCHAR* /*fieldName*/) const{ + return FieldSelector::LOAD_FOR_MERGE; + } +}; + + +int32_t SegmentMerger::mergeFields() { +//Func - Merge the fields of all segments +//Pre - true +//Post - The field infos and field values of all segments have been merged. + + if (!mergeDocStores) { + // When we are not merging by doc stores, that means + // all segments were written as part of a single + // autoCommit=false IndexWriter session, so their field + // name -> number mapping are the same. So, we start + // with the fieldInfos of the last segment in this + // case, to keep that numbering. + assert(readers[readers.size()-1]->instanceOf(SegmentReader::getClassName())); + assert(false);//check last...and remove if correct... + SegmentReader* sr = (SegmentReader*)readers[readers.size()-1]; + fieldInfos = sr->fieldInfos()->clone(); + } else { + //Create a new FieldInfos + fieldInfos = _CLNEW FieldInfos(); // merge field names + } + //Condition check to see if fieldInfos points to a valid instance + CND_CONDITION(fieldInfos != NULL,"Memory allocation for fieldInfos failed"); + + IndexReader* reader = NULL; + + //Iterate through all readers + for (uint32_t i = 0; i < readers.size(); i++){ + //get the i-th reader + reader = readers[i]; + //Condition check to see if reader points to a valid instance + CND_CONDITION(reader != NULL,"No IndexReader found"); + + if (reader->instanceOf(SegmentReader::getClassName())) { + SegmentReader* segmentReader = (SegmentReader*) reader; + for (size_t j = 0; j < segmentReader->getFieldInfos()->size(); j++) { + FieldInfo* fi = segmentReader->getFieldInfos()->fieldInfo(j); + fieldInfos->add(fi->name, fi->isIndexed, fi->storeTermVector, + fi->storePositionWithTermVector, fi->storeOffsetWithTermVector, + !reader->hasNorms(fi->name), fi->storePayloads); + } + } else { + StringArrayWithDeletor tmp; + + tmp.clear(); reader->getFieldNames(IndexReader::TERMVECTOR_WITH_POSITION_OFFSET, tmp); + addIndexed(reader, fieldInfos, tmp, true, true, true, false); + + tmp.clear(); reader->getFieldNames(IndexReader::TERMVECTOR_WITH_POSITION, tmp); + addIndexed(reader, fieldInfos, tmp, true, true, false, false); + + tmp.clear(); reader->getFieldNames(IndexReader::TERMVECTOR_WITH_OFFSET, tmp); + addIndexed(reader, fieldInfos, tmp, true, false, true, false); + + tmp.clear(); reader->getFieldNames(IndexReader::TERMVECTOR, tmp); + addIndexed(reader, fieldInfos, tmp, true, false, false, false); + + tmp.clear(); reader->getFieldNames(IndexReader::STORES_PAYLOADS, tmp); + addIndexed(reader, fieldInfos, tmp, false, false, false, true); + + tmp.clear(); reader->getFieldNames(IndexReader::INDEXED, tmp); + addIndexed(reader, fieldInfos, tmp, false, false, false, false); + + tmp.clear(); reader->getFieldNames(IndexReader::UNINDEXED, tmp); + if ( tmp.size() > 0 ){ + TCHAR** arr = _CL_NEWARRAY(TCHAR*,tmp.size()+1); + tmp.toArray_nullTerminated(arr); + fieldInfos->add((const TCHAR**)arr, false); + _CLDELETE_ARRAY(arr); //no need to delete the contents, since tmp is responsible for it + } + } + } + + //Write the new FieldInfos file to the directory + fieldInfos->write(directory, Misc::segmentname(segment.c_str(),".fnm").c_str() ); + + int32_t docCount = 0; + + if (mergeDocStores) { + + // If the i'th reader is a SegmentReader and has + // identical fieldName -> number mapping, then this + // array will be non-NULL at position i: + ValueArray matchingSegmentReaders(readers.size()); + + // If this reader is a SegmentReader, and all of its + // field name -> number mappings match the "merged" + // FieldInfos, then we can do a bulk copy of the + // stored fields: + for (size_t i = 0; i < readers.size(); i++) { + IndexReader* reader = readers[i]; + if (reader->instanceOf(SegmentReader::getClassName())) { + SegmentReader* segmentReader = (SegmentReader*) reader; + bool same = true; + FieldInfos* segmentFieldInfos = segmentReader->getFieldInfos(); + for (size_t j = 0; same && j < segmentFieldInfos->size(); j++) + same = _tcscmp(fieldInfos->fieldName(j), segmentFieldInfos->fieldName(j)) == 0; + if (same) { + matchingSegmentReaders.values[i] = segmentReader; + } + } + } + + // Used for bulk-reading raw bytes for stored fields + ValueArray rawDocLengths(MAX_RAW_MERGE_DOCS); + + // merge field values + FieldsWriter fieldsWriter(directory, segment.c_str(), fieldInfos); + + try { + for (size_t i = 0; i < readers.size(); i++) { + IndexReader* reader = readers[i]; + SegmentReader* matchingSegmentReader = matchingSegmentReaders[i]; + FieldsReader* matchingFieldsReader; + if (matchingSegmentReader != NULL) + matchingFieldsReader = matchingSegmentReader->getFieldsReader(); + else + matchingFieldsReader = NULL; + const int32_t maxDoc = reader->maxDoc(); + Document doc; + FieldSelectorMerge fieldSelectorMerge; + for (int32_t j = 0; j < maxDoc;) { + if (!reader->isDeleted(j)) { // skip deleted docs + if (matchingSegmentReader != NULL) { + // We can optimize this case (doing a bulk + // byte copy) since the field numbers are + // identical + int32_t start = j; + int32_t numDocs = 0; + do { + j++; + numDocs++; + } while(j < maxDoc && !matchingSegmentReader->isDeleted(j) && numDocs < MAX_RAW_MERGE_DOCS); + + IndexInput* stream = matchingFieldsReader->rawDocs(rawDocLengths.values, start, numDocs); + fieldsWriter.addRawDocuments(stream, rawDocLengths.values, numDocs); + docCount += numDocs; + if (checkAbort != NULL) + checkAbort->work(300*numDocs); + } else { + doc.clear(); + reader->document(j, doc, &fieldSelectorMerge); + fieldsWriter.addDocument(&doc); + j++; + docCount++; + if (checkAbort != NULL) + checkAbort->work(300); + } + } else + j++; + } + } + } _CLFINALLY ( + fieldsWriter.close(); + ) + + CND_PRECONDITION (docCount*8 == directory->fileLength( (segment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION).c_str() ), + (string("after mergeFields: fdx size mismatch: ") + Misc::toString(docCount) + " docs vs " + Misc::toString(directory->fileLength( (segment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION).c_str() )) + " length in bytes of " + segment + "." + IndexFileNames::FIELDS_INDEX_EXTENSION).c_str() ); + + } else{ + // If we are skipping the doc stores, that means there + // are no deletions in any of these segments, so we + // just sum numDocs() of each segment to get total docCount + for (size_t i = 0; i < readers.size(); i++) + docCount += readers[i]->numDocs(); + } + return docCount; +} + + +void SegmentMerger::mergeVectors(){ + TermVectorsWriter* termVectorsWriter = + _CLNEW TermVectorsWriter(directory, segment.c_str(), fieldInfos); + + try { + for (uint32_t r = 0; r < readers.size(); r++) { + IndexReader* reader = readers[r]; + int32_t maxDoc = reader->maxDoc(); + for (int32_t docNum = 0; docNum < maxDoc; docNum++) { + // skip deleted docs + if (reader->isDeleted(docNum)) + continue; + + ArrayBase* tmp = reader->getTermFreqVectors(docNum); +// if ( tmp != NULL ){ + termVectorsWriter->addAllDocVectors(tmp); + _CLLDELETE(tmp); +// } + if (checkAbort != NULL) + checkAbort->work(300); + } + } + }_CLFINALLY( + if ( termVectorsWriter != NULL ){ + termVectorsWriter->close(); + _CLDELETE(termVectorsWriter); + } + ); + + CND_PRECONDITION(4+mergedDocs*8 == directory->fileLength( (segment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION).c_str() ), + (string("after mergeVectors: tvx size mismatch: ") + Misc::toString(mergedDocs) + " docs vs " + Misc::toString(directory->fileLength( (segment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION).c_str() )) + " length in bytes of " + segment + "." + IndexFileNames::VECTORS_INDEX_EXTENSION).c_str() ) + +} + + +void SegmentMerger::mergeTerms() { +//Func - Merge the terms of all segments +//Pre - fieldInfos != NULL +//Post - The terms of all segments have been merged + + CND_PRECONDITION(fieldInfos != NULL, "fieldInfos is NULL"); + + try{ + //Open an IndexOutput to the new Frequency File + freqOutput = directory->createOutput( Misc::segmentname(segment.c_str(),".frq").c_str() ); + + //Open an IndexOutput to the new Prox File + proxOutput = directory->createOutput( Misc::segmentname(segment.c_str(),".prx").c_str() ); + + //Instantiate a new termInfosWriter which will write in directory + //for the segment name segment using the new merged fieldInfos + termInfosWriter = _CLNEW TermInfosWriter(directory, segment.c_str(), fieldInfos, termIndexInterval); + + //Condition check to see if termInfosWriter points to a valid instance + CND_CONDITION(termInfosWriter != NULL,"Memory allocation for termInfosWriter failed") ; + + skipInterval = termInfosWriter->skipInterval; + maxSkipLevels = termInfosWriter->maxSkipLevels; + skipListWriter = _CLNEW DefaultSkipListWriter(skipInterval, maxSkipLevels, mergedDocs, freqOutput, proxOutput); + queue = _CLNEW SegmentMergeQueue(readers.size()); + + //And merge the Term Infos + mergeTermInfos(); + }_CLFINALLY( + if ( freqOutput != NULL ){ + freqOutput->close(); + _CLDELETE(freqOutput); + } + if ( proxOutput != NULL ){ + proxOutput->close(); + _CLDELETE(proxOutput); + } + if ( termInfosWriter != NULL ){ + termInfosWriter->close(); + _CLDELETE(termInfosWriter); + } + if ( queue != NULL ){ + queue->close(); + _CLDELETE(queue); + } + ); +} + +void SegmentMerger::mergeTermInfos(){ +//Func - Merges all TermInfos into a single segment +//Pre - true +//Post - All TermInfos have been merged into a single segment + + //Condition check to see if queue points to a valid instance + CND_CONDITION(queue != NULL, "Memory allocation for queue failed") ; + + //base is the id of the first document in a segment + int32_t base = 0; + + IndexReader* reader = NULL; + SegmentMergeInfo* smi = NULL; + + //iterate through all the readers + for (uint32_t i = 0; i < readers.size(); i++) { + //Get the i-th reader + reader = readers[i]; + + //Condition check to see if reader points to a valid instance + CND_CONDITION(reader != NULL, "No IndexReader found"); + + //Get the term enumeration of the reader + TermEnum* termEnum = reader->terms(); + //Instantiate a new SegmentMerginfo for the current reader and enumeration + smi = _CLNEW SegmentMergeInfo(base, termEnum, reader); + + //Condition check to see if smi points to a valid instance + CND_CONDITION(smi != NULL, "Memory allocation for smi failed") ; + + //Increase the base by the number of documents that have not been marked deleted + //so base will contain a new value for the first document of the next iteration + base += reader->numDocs(); + //Get the next current term + if (smi->next()){ + //Store the SegmentMergeInfo smi with the initialized SegmentTermEnum TermEnum + //into the queue + queue->put(smi); + }else{ + //Apparently the end of the TermEnum of the SegmentTerm has been reached so + //close the SegmentMergeInfo smi + smi->close(); + //And destroy the instance and set smi to NULL (It will be used later in this method) + _CLDELETE(smi); + } + } + + //Instantiate an array of SegmentMergeInfo instances called match + SegmentMergeInfo** match = _CL_NEWARRAY(SegmentMergeInfo*,readers.size()); + + //Condition check to see if match points to a valid instance + CND_CONDITION(match != NULL, "Memory allocation for match failed") ; + + SegmentMergeInfo* top = NULL; + + //As long as there are SegmentMergeInfo instances stored in the queue + while (queue->size() > 0) { + int32_t matchSize = 0; + + // pop matching terms + + //Pop the first SegmentMergeInfo from the queue + match[matchSize++] = queue->pop(); + //Get the Term of match[0] + Term* term = match[0]->term; + + //Condition check to see if term points to a valid instance + CND_CONDITION(term != NULL,"term is NULL") ; + + //Get the current top of the queue + top = queue->top(); + + //For each SegmentMergInfo still in the queue + //Check if term matches the term of the SegmentMergeInfo instances in the queue + while (top != NULL && term->equals(top->term) ){ + //A match has been found so add the matching SegmentMergeInfo to the match array + match[matchSize++] = queue->pop(); + //Get the next SegmentMergeInfo + top = queue->top(); + } + int32_t df = mergeTermInfo(match, matchSize); // add new TermInfo + if (checkAbort != NULL) + checkAbort->work(df/3.0); + + //Restore the SegmentTermInfo instances in the match array back into the queue + while (matchSize > 0){ + smi = match[--matchSize]; + + //Condition check to see if smi points to a valid instance + CND_CONDITION(smi != NULL,"smi is NULL") ; + + //Move to the next term in the enumeration of SegmentMergeInfo smi + if (smi->next()){ + //There still are some terms so restore smi in the queue + queue->put(smi); + + }else{ + //Done with a segment + //No terms anymore so close this SegmentMergeInfo instance + smi->close(); + _CLDELETE( smi ); + } + } + } + _CLDELETE_ARRAY(match); +} + +int32_t SegmentMerger::mergeTermInfo( SegmentMergeInfo** smis, int32_t n){ +//Func - Merge the TermInfo of a term found in one or more segments. +//Pre - smis != NULL and it contains segments that are positioned at the same term. +// n is equal to the number of SegmentMergeInfo instances in smis +// freqOutput != NULL +// proxOutput != NULL +//Post - The TermInfo of a term has been merged + + CND_PRECONDITION(smis != NULL, "smis is NULL"); + CND_PRECONDITION(freqOutput != NULL, "freqOutput is NULL"); + CND_PRECONDITION(proxOutput != NULL, "proxOutput is NULL"); + + //Get the file pointer of the IndexOutput to the Frequency File + int64_t freqPointer = freqOutput->getFilePointer(); + //Get the file pointer of the IndexOutput to the Prox File + int64_t proxPointer = proxOutput->getFilePointer(); + + //Process postings from multiple segments all positioned on the same term. + int32_t df = appendPostings(smis, n); + + int64_t skipPointer = skipListWriter->writeSkip(freqOutput); + + //df contains the number of documents across all segments where this term was found + if (df > 0) { + //add an entry to the dictionary with pointers to prox and freq files + termInfo.set(df, freqPointer, proxPointer, (int32_t)(skipPointer - freqPointer)); + //Precondition check for to be sure that the reference to + //smis[0]->term will be valid + CND_PRECONDITION(smis[0]->term != NULL, "smis[0]->term is NULL"); + //Write a new TermInfo + termInfosWriter->add(smis[0]->term, &termInfo); + } + return df; +} + + +int32_t SegmentMerger::appendPostings(SegmentMergeInfo** smis, int32_t n){ +//Func - Process postings from multiple segments all positioned on the +// same term. Writes out merged entries into freqOutput and +// the proxOutput streams. +//Pre - smis != NULL and it contains segments that are positioned at the same term. +// n is equal to the number of SegmentMergeInfo instances in smis +// freqOutput != NULL +// proxOutput != NULL +//Post - Returns number of documents across all segments where this term was found + + CND_PRECONDITION(smis != NULL, "smis is NULL"); + CND_PRECONDITION(freqOutput != NULL, "freqOutput is NULL"); + CND_PRECONDITION(proxOutput != NULL, "proxOutput is NULL"); + + int32_t lastDoc = 0; + int32_t df = 0; //Document Counter + + skipListWriter->resetSkip(); + bool storePayloads = fieldInfos->fieldInfo(smis[0]->term->field())->storePayloads; + int32_t lastPayloadLength = -1; // ensures that we write the first length + + SegmentMergeInfo* smi = NULL; + + //Iterate through all SegmentMergeInfo instances in smis + for ( int32_t i=0;igetPositions(); + assert(postings != NULL); + //Get the base of this segment + int32_t base = smi->base; + //Get the docMap so we can see which documents have been deleted + int32_t* docMap = smi->getDocMap(); + //Seek the termpost + postings->seek(smi->termEnum); + while (postings->next()) { + int32_t doc = postings->doc(); + //Check if there are deletions + if (docMap != NULL) + doc = docMap[doc]; // map around deletions + doc += base; // convert to merged space + + //Condition check to see doc is eaqual to or bigger than lastDoc + if (doc < 0 || (df > 0 && doc <= lastDoc)) + _CLTHROWA(CL_ERR_CorruptIndex, (string("docs out of order (") + Misc::toString(doc) + + " <= " + Misc::toString(lastDoc) + " )").c_str()); + + //Increase the total frequency over all segments + df++; + + if ((df % skipInterval) == 0) { + skipListWriter->setSkipData(lastDoc, storePayloads, lastPayloadLength); + skipListWriter->bufferSkip(df); + } + + //Calculate a new docCode + //use low bit to flag freq=1 + int32_t docCode = (doc - lastDoc) << 1; + lastDoc = doc; + + //Get the frequency of the Term + int32_t freq = postings->freq(); + if (freq == 1){ + //write doc & freq=1 + freqOutput->writeVInt(docCode | 1); + }else{ + //write doc + freqOutput->writeVInt(docCode); + //write frequency in doc + freqOutput->writeVInt(freq); + } + + /** See {@link DocumentWriter#writePostings(Posting[], String)} for + * documentation about the encoding of positions and payloads + */ + int32_t lastPosition = 0; + // write position deltas + for (int32_t j = 0; j < freq; j++) { + //Get the next position + int32_t position = postings->nextPosition(); + int32_t delta = position - lastPosition; + if (storePayloads) { + size_t payloadLength = postings->getPayloadLength(); + if (payloadLength == lastPayloadLength) { + proxOutput->writeVInt(delta * 2); + } else { + proxOutput->writeVInt(delta * 2 + 1); + proxOutput->writeVInt(payloadLength); + lastPayloadLength = payloadLength; + } + if (payloadLength > 0) { + if ( payloadBuffer.length < payloadLength ){ + payloadBuffer.resize(payloadLength); + } + postings->getPayload(payloadBuffer.values); + proxOutput->writeBytes(payloadBuffer.values, payloadLength); + } + } else { + proxOutput->writeVInt(delta); + } + lastPosition = position; + } + } + } + + //Return total number of documents across all segments where term was found + return df; +} + +void SegmentMerger::mergeNorms() { +//Func - Merges the norms for all fields +//Pre - fieldInfos != NULL +//Post - The norms for all fields have been merged + ValueArray normBuffer; + IndexOutput* output = NULL; + try { + + CND_PRECONDITION(fieldInfos != NULL, "fieldInfos is NULL"); + + IndexReader* reader = NULL; + + //iterate through all the Field Infos instances + for (size_t i = 0; i < fieldInfos->size(); i++) { + //Get the i-th FieldInfo + FieldInfo* fi = fieldInfos->fieldInfo(i); + //Is this Field indexed? + if (fi->isIndexed && !fi->omitNorms){ + //Instantiate an IndexOutput to that norm file + if (output == NULL) { + output = directory->createOutput( (segment + "." + IndexFileNames::NORMS_EXTENSION).c_str() ); + output->writeBytes(NORMS_HEADER,NORMS_HEADER_length); + } + + //Condition check to see if output points to a valid instance + CND_CONDITION(output != NULL, "No Outputstream retrieved"); + + //Iterate through all IndexReaders + for (uint32_t j = 0; j < readers.size(); j++) { + //Get the i-th IndexReader + reader = readers[j]; + + //Condition check to see if reader points to a valid instance + CND_CONDITION(reader != NULL, "No reader found"); + + //Get the total number of documents including the documents that have been marked deleted + size_t maxDoc = reader->maxDoc(); + + //Get an IndexInput to the norm file for this field in this segment + if ( normBuffer.length < maxDoc ){ + normBuffer.resize(maxDoc); + memset(normBuffer.values,0,sizeof(uint8_t) * maxDoc); + } + reader->norms(fi->name, normBuffer.values); + + if (!reader->hasDeletions()) { + //optimized case for segments without deleted docs + output->writeBytes(normBuffer.values, maxDoc); + } else { + // this segment has deleted docs, so we have to + // check for every doc if it is deleted or not + + for(size_t k = 0; k < maxDoc; k++) { + //Check if document k is deleted + if (!reader->isDeleted(k)){ + //write the new norm + output->writeByte(normBuffer[k]); + } + } + } + if (checkAbort != NULL) + checkAbort->work(maxDoc); + } + } + } + }_CLFINALLY( + if ( output != NULL ){ + output->close(); + _CLDELETE(output); + } + ); +} + + +SegmentMerger::CheckAbort::CheckAbort(MergePolicy::OneMerge* merge, Directory* dir) { + this->merge = merge; + this->dir = dir; + this->workCount = 0; +} + +void SegmentMerger::CheckAbort::work(float_t units){ + workCount += units; + if (workCount >= 10000.0) { + merge->checkAborted(dir); + workCount = 0; + } +} +CL_NS_END diff --git a/src/core/CLucene/index/SegmentReader.cpp b/src/core/CLucene/index/SegmentReader.cpp new file mode 100644 index 00000000000..d914de88de3 --- /dev/null +++ b/src/core/CLucene/index/SegmentReader.cpp @@ -0,0 +1,1126 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/PriorityQueue.h" +#include "IndexReader.h" +#include "Terms.h" +#include "_FieldInfos.h" +#include "_FieldsReader.h" +#include "_MultiSegmentReader.h" +#include "_SegmentHeader.h" +#include "_SegmentMerger.h" +#include "_TermInfosReader.h" +#include + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(document) +CL_NS_USE(search) +CL_NS_DEF(index) + +SegmentReader::Norm::Norm(IndexInput *instrm, bool _useSingleNormStream, int32_t n, int64_t ns, SegmentReader *r, const char *seg) : number(n), + normSeek(ns), + _this(r), + segment(seg), + useSingleNormStream(_useSingleNormStream), + in(instrm), + bytes(NULL), + dirty(false) { + //Func - Constructor + //Pre - instrm is a valid reference to an IndexInput + //Post - A Norm instance has been created with an empty bytes array + + refCount = 1; + bytes = NULL; + dirty = false; +} + +SegmentReader::Norm::~Norm() { + //Func - Destructor + //Pre - true + //Post - The IndexInput in has been deleted (and closed by its destructor) + // and the array too. + + //Close and destroy the inputstream in-> The inputstream will be closed + // by its destructor. Note that the IndexInput 'in' actually is a pointer!!!!! + if (in != _this->singleNormStream) + _CLDELETE(in); + + //Delete the bytes array + _CLDELETE_ARRAY(bytes); +} +void SegmentReader::Norm::doDelete(Norm *norm) { + if (norm->refCount == 0) { + _CLLDELETE(norm); + } +} + +void SegmentReader::Norm::close() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (in != NULL && !useSingleNormStream) { + in->close(); + _CLDELETE(in); + } + in = NULL; +} + +void SegmentReader::Norm::incRef() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + assert(refCount > 0); + refCount++; +} + +void SegmentReader::Norm::decRef() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + assert(refCount > 0); + if (refCount == 1) { + close(); + } + refCount--; +} +void SegmentReader::Norm::reWrite(SegmentInfo *si) { + // NOTE: norms are re-written in regular directory, not cfs + si->advanceNormGen(this->number); + IndexOutput *out = _this->directory()->createOutput(si->getNormFileName(this->number).c_str()); + try { + out->writeBytes(bytes, _this->maxDoc()); + } + _CLFINALLY( + out->close(); + _CLDELETE(out)); + this->dirty = false; +} + +void SegmentReader::initialize(SegmentInfo *si, int32_t readBufferSize, bool doOpenStores, bool doingReopen) { + //Pre - si-> is a valid reference to SegmentInfo instance + // identified by si-> + //Post - All files of the segment have been read + + this->deletedDocs = NULL; + this->ones = NULL; + //There are no documents yet marked as deleted + this->deletedDocsDirty = false; + + this->normsDirty = false; + this->undeleteAll = false; + + this->rollbackDeletedDocsDirty = false; + this->rollbackNormsDirty = false; + this->rollbackUndeleteAll = false; + + //Duplicate the name of the segment from SegmentInfo to segment + this->segment = si->name; + + // make sure that all index files have been read or are kept open + // so that if an index update removes them we'll still have them + this->freqStream = NULL; + this->proxStream = NULL; + this->singleNormStream = NULL; + this->termVectorsReaderOrig = NULL; + this->_fieldInfos = NULL; + this->tis = NULL; + this->fieldsReader = NULL; + this->cfsReader = NULL; + this->storeCFSReader = NULL; + + this->segment = si->name; + this->si = si; + this->readBufferSize = readBufferSize; + + if (doingReopen) return;// the rest is done in the reopen code... + + bool success = false; + + try { + // Use compound file directory for some files, if it exists + Directory *cfsDir = directory(); + if (si->getUseCompoundFile()) { + cfsReader = _CLNEW CompoundFileReader(directory(), (segment + "." + IndexFileNames::COMPOUND_FILE_EXTENSION).c_str(), readBufferSize); + cfsDir = cfsReader; + } + + Directory *storeDir; + + if (doOpenStores) { + if (si->getDocStoreOffset() != -1) { + if (si->getDocStoreIsCompoundFile()) { + storeCFSReader = _CLNEW CompoundFileReader(directory(), (si->getDocStoreSegment() + "." + IndexFileNames::COMPOUND_FILE_STORE_EXTENSION).c_str(), readBufferSize); + storeDir = storeCFSReader; + } else { + storeDir = directory(); + } + } else { + storeDir = cfsDir; + } + } else + storeDir = NULL; + + // No compound file exists - use the multi-file format + _fieldInfos = _CLNEW FieldInfos(cfsDir, (segment + ".fnm").c_str()); + + string fieldsSegment; + + if (si->getDocStoreOffset() != -1) + fieldsSegment = si->getDocStoreSegment(); + else + fieldsSegment = segment; + + if (doOpenStores) { + fieldsReader = _CLNEW FieldsReader(storeDir, fieldsSegment.c_str(), _fieldInfos, readBufferSize, + si->getDocStoreOffset(), si->docCount); + + // Verify two sources of "maxDoc" agree: + if (si->getDocStoreOffset() == -1 && fieldsReader->size() != si->docCount) { + string err = "doc counts differ for segment "; + err += si->name; + err += ": fieldsReader shows "; + err += fieldsReader->size(); + err += " but segmentInfo shows "; + err += si->docCount; + _CLTHROWA(CL_ERR_CorruptIndex, err.c_str()); + } + } + + tis = _CLNEW TermInfosReader(cfsDir, segment.c_str(), _fieldInfos, readBufferSize); + + loadDeletedDocs(); + + // make sure that all index files have been read or are kept open + // so that if an index update removes them we'll still have them + freqStream = cfsDir->openInput((segment + ".frq").c_str(), readBufferSize); + // TODO: should be true when we could set writing terms positions in field conf flag. + if (0) { + proxStream = cfsDir->openInput((segment + ".prx").c_str(), readBufferSize); + } + // we do not need norms, so we don't read it at all. + //openNorms(cfsDir, readBufferSize); + + if (doOpenStores && _fieldInfos->hasVectors()) {// open term vector files only as needed + string vectorsSegment; + if (si->getDocStoreOffset() != -1) + vectorsSegment = si->getDocStoreSegment(); + else + vectorsSegment = segment; + termVectorsReaderOrig = _CLNEW TermVectorsReader(storeDir, vectorsSegment.c_str(), _fieldInfos, readBufferSize, si->getDocStoreOffset(), si->docCount); + } + success = true; + } catch (CLuceneError& e) { + throw e; + } + _CLFINALLY( + + // With lock-less commits, it's entirely possible (and + // fine) to hit a FileNotFound exception above. In + // this case, we want to explicitly close any subset + // of things that were opened so that we don't have to + // wait for a GC to do so. + if (!success) { + doClose(); + }) +} + +SegmentReader *SegmentReader::get(SegmentInfo *si, bool doOpenStores) { + // set doOpenStores false force + return get(si->dir, si, NULL, false, false, BufferedIndexInput::BUFFER_SIZE, false); +} + +SegmentReader *SegmentReader::get(SegmentInfo *si, int32_t readBufferSize, bool doOpenStores) { + // set doOpenStores false force + return get(si->dir, si, NULL, false, false, readBufferSize, false); +} +SegmentReader *SegmentReader::get(SegmentInfos *sis, SegmentInfo *si, + bool closeDir) { + return get(si->dir, si, sis, closeDir, true, BufferedIndexInput::BUFFER_SIZE, false); +} +/** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ +SegmentReader *SegmentReader::get(Directory *dir, SegmentInfo *si, + SegmentInfos *sis, + bool closeDir, bool ownDir, + int32_t readBufferSize, + bool doOpenStores) { + SegmentReader *instance = _CLNEW SegmentReader();//todo: make this configurable... + instance->init(dir, sis, closeDir); + // TODO: make this configurable... + bool fieldsReaderExist = false; + instance->initialize(si, readBufferSize == -1 ? BufferedIndexInput::BUFFER_SIZE : readBufferSize, doOpenStores, fieldsReaderExist); + return instance; +} + +SegmentReader::SegmentReader() : DirectoryIndexReader(), + _norms(false, true) { +} +SegmentReader::~SegmentReader() { + //Func - Destructor. + //Pre - doClose has been invoked! + //Post - the instance has been destroyed + + doClose();//this means that index reader doesn't need to be closed manually + + _CLDELETE(_fieldInfos); + _CLDELETE(fieldsReader); + _CLDELETE(tis); + _CLDELETE(freqStream); + if (proxStream != nullptr) { + _CLDELETE(proxStream); + } + _CLDELETE(deletedDocs); + _CLDELETE_ARRAY(ones); + _CLDELETE(termVectorsReaderOrig) + _CLDECDELETE(cfsReader); + //termVectorsLocal->unregister(this); +} + +void SegmentReader::commitChanges() { + if (deletedDocsDirty) {// re-write deleted + si->advanceDelGen(); + + // We can write directly to the actual name (vs to a + // .tmp & renaming it) because the file is not live + // until segments file is written: + deletedDocs->write(directory(), si->getDelFileName().c_str()); + } + if (undeleteAll && si->hasDeletions()) { + si->clearDelGen(); + } + if (normsDirty) {// re-write norms + si->setNumFields(_fieldInfos->size()); + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + Norm *norm = it->second; + if (norm->dirty) { + norm->reWrite(si); + } + it++; + } + } + deletedDocsDirty = false; + normsDirty = false; + undeleteAll = false; +} + +void SegmentReader::doClose() { + //Func - Closes all streams to the files of a single segment + //Pre - fieldsReader != NULL + // tis != NULL + //Post - All streams to files have been closed + + _CLDELETE(deletedDocs); + + // close the single norms stream + if (singleNormStream != NULL) { + // we can close this stream, even if the norms + // are shared, because every reader has it's own + // singleNormStream + singleNormStream->close(); + _CLDELETE(singleNormStream); + } + + // re-opened SegmentReaders have their own instance of FieldsReader + if (fieldsReader != NULL) { + fieldsReader->close(); + _CLDELETE(fieldsReader); + } + + if (tis != NULL) { + tis->close(); + _CLDELETE(tis); + } + + //Close the frequency stream + if (freqStream != NULL) { + freqStream->close(); + _CLDELETE(freqStream); + } + //Close the prox stream + if (proxStream != NULL) { + proxStream->close(); + _CLDELETE(proxStream); + } + + if (termVectorsReaderOrig != NULL) { + termVectorsReaderOrig->close(); + _CLDELETE(termVectorsReaderOrig); + } + + if (cfsReader != NULL) { + cfsReader->close(); + _CLDECDELETE(cfsReader); + } + + if (storeCFSReader != NULL) { + storeCFSReader->close(); + _CLDELETE(storeCFSReader); + } + + this->decRefNorms(); + _norms.clear(); + + // maybe close directory + DirectoryIndexReader::doClose(); +} + +bool SegmentReader::hasDeletions() const { + // Don't call ensureOpen() here (it could affect performance) + return deletedDocs != NULL; +} + +//static +bool SegmentReader::usesCompoundFile(SegmentInfo *si) { + return si->getUseCompoundFile(); +} + +//static +bool SegmentReader::hasSeparateNorms(SegmentInfo *si) { + return si->hasSeparateNorms(); +} + +bool SegmentReader::hasDeletions(const SegmentInfo *si) { + //Func - Static method + // Checks if a segment managed by SegmentInfo si-> has deletions + //Pre - si-> holds a valid reference to an SegmentInfo instance + //Post - if the segement contains deleteions true is returned otherwise flas + + // Don't call ensureOpen() here (it could affect performance) + return si->hasDeletions(); +} + +//synchronized +void SegmentReader::doDelete(const int32_t docNum) { + //Func - Marks document docNum as deleted + //Pre - docNum >=0 and DocNum < maxDoc() + // docNum contains the number of the document that must be + // marked deleted + //Post - The document identified by docNum has been marked deleted + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + CND_PRECONDITION(docNum >= 0, "docNum is a negative number"); + CND_PRECONDITION(docNum < maxDoc(), "docNum is bigger than the total number of documents"); + + //Check if deletedDocs exists + if (deletedDocs == NULL) { + deletedDocs = _CLNEW BitSet(maxDoc()); + + //Condition check to see if deletedDocs points to a valid instance + CND_CONDITION(deletedDocs != NULL, "No memory could be allocated for deletedDocs"); + } + //Flag that there are documents marked deleted + deletedDocsDirty = true; + undeleteAll = false; + //Mark document identified by docNum as deleted + deletedDocs->set(docNum); +} + +void SegmentReader::doUndeleteAll() { + _CLDELETE(deletedDocs); + deletedDocsDirty = false; + undeleteAll = true; +} + +void SegmentReader::files(vector &retarray) { + //Func - Returns all file names managed by this SegmentReader + //Pre - segment != NULL + //Post - All filenames managed by this SegmentRead have been returned + vector tmp = si->files(); + retarray.insert(retarray.end(), tmp.begin(), tmp.end()); +} + +TermEnum *SegmentReader::terms() { + //Func - Returns an enumeration of all the Terms and TermInfos in the set. + //Pre - tis != NULL + //Post - An enumeration of all the Terms and TermInfos in the set has been returned + + CND_PRECONDITION(tis != NULL, "tis is NULL"); + + ensureOpen(); + return tis->terms(); +} + +TermEnum *SegmentReader::terms(const Term *t) { + //Func - Returns an enumeration of terms starting at or after the named term t + //Pre - t != NULL + // tis != NULL + //Post - An enumeration of terms starting at or after the named term t + + CND_PRECONDITION(t != NULL, "t is NULL"); + CND_PRECONDITION(tis != NULL, "tis is NULL"); + + ensureOpen(); + return tis->terms(t); +} + +bool SegmentReader::document(int32_t n, Document &doc, const FieldSelector *fieldSelector) { + //Func - writes the fields of document n into doc + //Pre - n >=0 and identifies the document n + //Post - if the document has been deleted then an exception has been thrown + // otherwise a reference to the found document has been returned + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + ensureOpen(); + + CND_PRECONDITION(n >= 0, "n is a negative number"); + + //Check if the n-th document has been marked deleted + if (isDeleted(n)) { + _CLTHROWA(CL_ERR_InvalidState, "attempt to access a deleted document"); + } + + //Retrieve the n-th document + return fieldsReader->doc(n, doc, fieldSelector); +} + + +bool SegmentReader::isDeleted(const int32_t n) { + //Func - Checks if the n-th document has been marked deleted + //Pre - n >=0 and identifies the document n + //Post - true has been returned if document n has been deleted otherwise fralse + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + CND_PRECONDITION(n >= 0, "n is a negative number"); + + //Is document n deleted + bool ret = (deletedDocs != NULL && deletedDocs->get(n)); + + return ret; +} + +TermDocs *SegmentReader::termDocs() { + //Func - Returns an unpositioned TermDocs enumerator. + //Pre - true + //Post - An unpositioned TermDocs enumerator has been returned + + ensureOpen(); + return _CLNEW SegmentTermDocs(this); +} + +TermPositions *SegmentReader::termPositions() { + //Func - Returns an unpositioned TermPositions enumerator. + //Pre - true + //Post - An unpositioned TermPositions enumerator has been returned + + ensureOpen(); + return _CLNEW SegmentTermPositions(this); +} + +int32_t SegmentReader::docFreq(const Term *t) { + //Func - Returns the number of documents which contain the term t + //Pre - t holds a valid reference to a Term + //Post - The number of documents which contain term t has been returned + + ensureOpen(); + + //Get the TermInfo ti for Term t in the set + TermInfo *ti = tis->get(t); + //Check if an TermInfo has been returned + if (ti) { + //Get the frequency of the term + int32_t ret = ti->docFreq; + //TermInfo ti is not needed anymore so delete it + _CLDELETE(ti); + //return the number of documents which containt term t + return ret; + } else + //No TermInfo returned so return 0 + return 0; +} + +int32_t SegmentReader::numDocs() { + //Func - Returns the actual number of documents in the segment + //Pre - true + //Post - The actual number of documents in the segments + + ensureOpen(); + + //Get the number of all the documents in the segment including the ones that have + //been marked deleted + int32_t n = maxDoc(); + + //Check if there any deleted docs + if (deletedDocs != NULL) + //Substract the number of deleted docs from the number returned by maxDoc + n -= deletedDocs->count(); + + //return the actual number of documents in the segment + return n; +} + +int32_t SegmentReader::maxDoc() const { + //Func - Returns the number of all the documents in the segment including + // the ones that have been marked deleted + //Pre - true + //Post - The total number of documents in the segment has been returned + + // Don't call ensureOpen() here (it could affect performance) + + return si->docCount; +} + + +void SegmentReader::setTermInfosIndexDivisor(int32_t indexDivisor) { + tis->setIndexDivisor(indexDivisor); +} + +int32_t SegmentReader::getTermInfosIndexDivisor() { + return tis->getIndexDivisor(); +} + + +void SegmentReader::getFieldNames(FieldOption fldOption, StringArrayWithDeletor &retarray) { + ensureOpen(); + + size_t len = _fieldInfos->size(); + for (size_t i = 0; i < len; i++) { + FieldInfo *fi = _fieldInfos->fieldInfo(i); + bool v = false; + if (fldOption & IndexReader::ALL) { + v = true; + } else { + if (!fi->isIndexed && (fldOption & IndexReader::UNINDEXED)) + v = true; + else if (fi->isIndexed && (fldOption & IndexReader::INDEXED)) + v = true; + else if (fi->storePayloads && (fldOption & IndexReader::STORES_PAYLOADS)) + v = true; + else if (fi->isIndexed && fi->storeTermVector == false && (fldOption & IndexReader::INDEXED_NO_TERMVECTOR)) + v = true; + else if ((fldOption & IndexReader::TERMVECTOR) && + fi->storeTermVector == true && + fi->storePositionWithTermVector == false && + fi->storeOffsetWithTermVector == false) + v = true; + else if (fi->isIndexed && fi->storeTermVector && (fldOption & IndexReader::INDEXED_WITH_TERMVECTOR)) + v = true; + else if (fi->storePositionWithTermVector && fi->storeOffsetWithTermVector == false && + (fldOption & IndexReader::TERMVECTOR_WITH_POSITION)) + v = true; + else if (fi->storeOffsetWithTermVector && fi->storePositionWithTermVector == false && + (fldOption & IndexReader::TERMVECTOR_WITH_OFFSET)) + v = true; + else if ((fi->storeOffsetWithTermVector && fi->storePositionWithTermVector) && + (fldOption & IndexReader::TERMVECTOR_WITH_POSITION_OFFSET)) + v = true; + } + if (v) + retarray.push_back(STRDUP_TtoT(fi->name)); + } +} + +bool SegmentReader::hasNorms(const TCHAR *field) { + ensureOpen(); + return _norms.find(field) != _norms.end(); +} + + +void SegmentReader::norms(const TCHAR *field, uint8_t *bytes) { + //Func - Reads the Norms for field from disk starting at offset in the inputstream + //Pre - field != NULL + // bytes != NULL is an array of bytes which is to be used to read the norms into. + // it is advisable to have bytes initalized by zeroes! + //Post - The if an inputstream to the norm file could be retrieved the bytes have been read + // You are never sure whether or not the norms have been read into bytes properly!!!!!!!!!!!!!!!!! + + CND_PRECONDITION(field != NULL, "field is NULL"); + CND_PRECONDITION(bytes != NULL, "field is NULL"); + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + ensureOpen(); + Norm *norm = _norms.get(field); + if (norm == NULL) { + memcpy(bytes, fakeNorms(), maxDoc()); + return; + } + + + { + SCOPED_LOCK_MUTEX(norm->THIS_LOCK) + if (norm->bytes != NULL) {// can copy from cache + memcpy(bytes, norm->bytes, maxDoc()); + return; + } + + // Read from disk. norm.in may be shared across multiple norms and + // should only be used in a synchronized context. + IndexInput *normStream; + if (norm->useSingleNormStream) { + normStream = singleNormStream; + } else { + normStream = norm->in; + } + normStream->seek(norm->normSeek); + normStream->readBytes(bytes, maxDoc()); + } +} + +uint8_t *SegmentReader::createFakeNorms(int32_t size) { + uint8_t *ones = _CL_NEWARRAY(uint8_t, size); + if (size > 0) + memset(ones, DefaultSimilarity::encodeNorm(1.0f), size); + return ones; +} + +uint8_t *SegmentReader::fakeNorms() { + if (ones == NULL) + // ones = createFakeNorms(maxDoc()); + ones = createFakeNorms(1); + return ones; +} +// can return NULL if norms aren't stored +uint8_t *SegmentReader::getNorms(const TCHAR *field) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + Norm *norm = _norms.get(field); + if (norm == NULL) return NULL;// not indexed, or norms not stored + + { + SCOPED_LOCK_MUTEX(norm->THIS_LOCK) + if (norm->bytes == NULL) {// value not yet read + uint8_t *bytes = _CL_NEWARRAY(uint8_t, maxDoc()); + norms(field, bytes); + norm->bytes = bytes;// cache it + // it's OK to close the underlying IndexInput as we have cached the + // norms and will never read them again. + norm->close(); + } + return norm->bytes; + } +} + +void SegmentReader::decRefNorms() { + SCOPED_LOCK_MUTEX(THIS_LOCK) + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + Norm *norm = it->second; + norm->decRef(); + it++; + } +} + +DirectoryIndexReader *SegmentReader::doReopen(SegmentInfos *infos) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + DirectoryIndexReader *newReader; + + if (infos->size() == 1) { + SegmentInfo *si = infos->info(0); + if (segment.compare(si->name) == 0 && si->getUseCompoundFile() == this->si->getUseCompoundFile()) { + newReader = reopenSegment(si); + } else { + // segment not referenced anymore, reopen not possible + // or segment format changed + newReader = SegmentReader::get(infos, infos->info(0), false); + } + } else { + ValueArray readers(1); + readers.values[0] = this; + return _CLNEW MultiSegmentReader(_directory, infos, closeDirectory, &readers, NULL, NULL); + } + + return newReader; +} + + +uint8_t *SegmentReader::norms(const TCHAR *field) { + //Func - Returns the bytes array that holds the norms of a named field + //Pre - field != NULL and contains the name of the field for which the norms + // must be retrieved + //Post - If there was norm for the named field then a bytes array has been allocated + // and returned containing the norms for that field. If the named field is unknown NULL is returned. + + CND_PRECONDITION(field != NULL, "field is NULL"); + // SCOPED_LOCK_MUTEX(THIS_LOCK) + // ensureOpen(); + // uint8_t *bytes = getNorms(field); + // if (bytes == NULL) + // bytes = fakeNorms(); + uint8_t *bytes = fakeNorms(); + return bytes; +} + +void SegmentReader::doSetNorm(int32_t doc, const TCHAR *field, uint8_t value) { + Norm *norm = _norms.get(field); + if (norm == NULL)// not an indexed field + return; + norm->dirty = true;// mark it dirty + normsDirty = true; + + uint8_t *bits = norms(field); + bits[doc] = value;// set the value +} + + +string SegmentReader::SegmentName(const char *ext, const int32_t x) { + //Func - Returns an allocated buffer in which it creates a filename by + // concatenating segment with ext and x + //Pre ext != NULL and holds the extension + // x contains a number + //Post - A buffer has been instantiated an when x = -1 buffer contains the concatenation of + // segment and ext otherwise buffer contains the contentation of segment, ext and x + + CND_PRECONDITION(ext != NULL, "ext is NULL"); + + return Misc::segmentname(segment.c_str(), ext, x); +} + +void SegmentReader::openNorms(Directory *cfsDir, int32_t readBufferSize) { + //Func - Open all norms files for all fields + // Creates for each field a norm Instance with an open inputstream to + // a corresponding norm file ready to be read + //Pre - true + //Post - For each field a norm instance has been created with an open inputstream to + // a corresponding norm file ready to be read + int64_t nextNormSeek = SegmentMerger::NORMS_HEADER_length;//skip header (header unused for now) + int32_t _maxDoc = maxDoc(); + for (size_t i = 0; i < _fieldInfos->size(); i++) { + FieldInfo *fi = _fieldInfos->fieldInfo(i); + if (_norms.find(fi->name) != _norms.end()) { + // in case this SegmentReader is being re-opened, we might be able to + // reuse some norm instances and skip loading them here + continue; + } + if (fi->isIndexed && !fi->omitNorms) { + Directory *d = directory(); + string fileName = si->getNormFileName(fi->number); + if (!si->hasSeparateNorms(fi->number)) { + d = cfsDir; + } + + // singleNormFile means multiple norms share this file + string ext = string(".") + IndexFileNames::NORMS_EXTENSION; + bool singleNormFile = fileName.compare(fileName.length() - ext.length(), ext.length(), ext) == 0; + IndexInput *normInput = NULL; + int64_t normSeek; + + if (singleNormFile) { + normSeek = nextNormSeek; + if (singleNormStream == NULL) { + singleNormStream = d->openInput(fileName.c_str(), readBufferSize); + } + // All norms in the .nrm file can share a single IndexInput since + // they are only used in a synchronized context. + // If this were to change in the future, a clone could be done here. + normInput = singleNormStream; + } else { + normSeek = 0; + normInput = d->openInput(fileName.c_str()); + } + + _norms[fi->name] = _CLNEW Norm(normInput, singleNormFile, fi->number, normSeek, this, segment.c_str()); + nextNormSeek += _maxDoc;// increment also if some norms are separate + } + } +} + + +TermVectorsReader *SegmentReader::getTermVectorsReader() { + TermVectorsReader *tvReader = termVectorsLocal.get(); + if (tvReader == NULL) { + tvReader = termVectorsReaderOrig->clone(); + termVectorsLocal.set(tvReader); + } + return tvReader; +} + +FieldsReader *SegmentReader::getFieldsReader() { + return fieldsReader; +} + +FieldInfos *SegmentReader::getFieldInfos() { + return _fieldInfos; +} + +TermFreqVector *SegmentReader::getTermFreqVector(int32_t docNumber, const TCHAR *field) { + ensureOpen(); + if (field != NULL) { + // Check if this field is invalid or has no stored term vector + FieldInfo *fi = _fieldInfos->fieldInfo(field); + if (fi == NULL || !fi->storeTermVector || termVectorsReaderOrig == NULL) + return NULL; + } + TermVectorsReader *termVectorsReader = getTermVectorsReader(); + if (termVectorsReader == NULL) + return NULL; + return termVectorsReader->get(docNumber, field); +} + +ArrayBase *SegmentReader::getTermFreqVectors(int32_t docNumber) { + ensureOpen(); + if (termVectorsReaderOrig == NULL) + return NULL; + + TermVectorsReader *termVectorsReader = getTermVectorsReader(); + if (termVectorsReader == NULL) + return NULL; + + return termVectorsReader->get(docNumber); +} + + +void SegmentReader::getTermFreqVector(int32_t docNumber, const TCHAR *field, TermVectorMapper *mapper) { + ensureOpen(); + FieldInfo *fi = _fieldInfos->fieldInfo(field); + if (fi == NULL || !fi->storeTermVector || termVectorsReaderOrig == NULL) + return; + + TermVectorsReader *termVectorsReader = getTermVectorsReader(); + if (termVectorsReader == NULL) { + return; + } + + + termVectorsReader->get(docNumber, field, mapper); +} + + +void SegmentReader::getTermFreqVector(int32_t docNumber, TermVectorMapper *mapper) { + ensureOpen(); + if (termVectorsReaderOrig == NULL) + return; + + TermVectorsReader *termVectorsReader = getTermVectorsReader(); + if (termVectorsReader == NULL) + return; + + termVectorsReader->get(docNumber, mapper); +} + + +void SegmentReader::loadDeletedDocs() { + // NOTE: the bitvector is stored using the regular directory, not cfs + if (hasDeletions(si)) { + deletedDocs = _CLNEW BitVector(directory(), si->getDelFileName().c_str()); + + // Verify # deletes does not exceed maxDoc for this segment: + if (deletedDocs->count() > maxDoc()) { + string err = "number of deletes ("; + err += deletedDocs->count(); + err += ") exceeds max doc ("; + err += maxDoc(); + err += ") for segment "; + err += si->name; + _CLTHROWA(CL_ERR_CorruptIndex, err.c_str()); + } + } +} + +SegmentReader *SegmentReader::reopenSegment(SegmentInfo *si) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + bool deletionsUpToDate = (this->si->hasDeletions() == si->hasDeletions()) && (!si->hasDeletions() || this->si->getDelFileName().compare(si->getDelFileName()) == 0); + bool normsUpToDate = true; + + + ValueArray fieldNormsChanged(_fieldInfos->size()); + if (normsUpToDate) { + for (size_t i = 0; i < _fieldInfos->size(); i++) { + if (this->si->getNormFileName(i).compare(si->getNormFileName(i)) != 0) { + normsUpToDate = false; + fieldNormsChanged.values[i] = true; + } + } + } + + if (normsUpToDate && deletionsUpToDate) { + this->si = si;//force the result to use the new segment info (the old one is going to go away!) + return this; + } + + + // clone reader + SegmentReader *clone = NULL; + bool success = false; + try { + clone = _CLNEW SegmentReader(); + clone->init(_directory, NULL, false); + clone->initialize(si, readBufferSize, false, true); + clone->cfsReader = cfsReader; + clone->storeCFSReader = storeCFSReader; + clone->_fieldInfos = _fieldInfos; + clone->tis = tis; + clone->freqStream = freqStream; + clone->proxStream = proxStream; + clone->termVectorsReaderOrig = termVectorsReaderOrig; + + // we have to open a new FieldsReader, because it is not thread-safe + // and can thus not be shared among multiple SegmentReaders + // TODO: Change this in case FieldsReader becomes thread-safe in the future + string fieldsSegment; + + Directory *storeDir = directory(); + + if (si->getDocStoreOffset() != -1) { + fieldsSegment = si->getDocStoreSegment(); + if (storeCFSReader != NULL) { + storeDir = storeCFSReader; + } + } else { + fieldsSegment = segment; + if (cfsReader != NULL) { + storeDir = cfsReader; + } + } + + if (fieldsReader != NULL) { + clone->fieldsReader = _CLNEW FieldsReader(storeDir, fieldsSegment.c_str(), _fieldInfos, readBufferSize, + si->getDocStoreOffset(), si->docCount); + } + + + if (!deletionsUpToDate) { + // load deleted docs + clone->deletedDocs = NULL; + clone->loadDeletedDocs(); + } else { + clone->deletedDocs = this->deletedDocs; + } + + if (!normsUpToDate) { + // load norms + for (size_t i = 0; i < fieldNormsChanged.length; i++) { + // copy unchanged norms to the cloned reader and incRef those norms + if (!fieldNormsChanged[i]) { + const TCHAR *curField = _fieldInfos->fieldInfo(i)->name; + Norm *norm = this->_norms.get(curField); + norm->incRef(); + norm->_this = clone;//give the norm to the clone + clone->_norms.put(curField, norm); + } + } + + clone->openNorms(si->getUseCompoundFile() ? cfsReader : directory(), readBufferSize); + } else { + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + const TCHAR *field = it->first; + Norm *norm = _norms[field]; + norm->incRef(); + norm->_this = clone;//give the norm to the clone + clone->_norms.put(field, norm); + it++; + } + } + + if (clone->singleNormStream == NULL) { + for (size_t i = 0; i < _fieldInfos->size(); i++) { + FieldInfo *fi = _fieldInfos->fieldInfo(i); + if (fi->isIndexed && !fi->omitNorms) { + Directory *d = si->getUseCompoundFile() ? cfsReader : directory(); + string fileName = si->getNormFileName(fi->number); + if (si->hasSeparateNorms(fi->number)) { + continue; + } + + string ext = string(".") + IndexFileNames::NORMS_EXTENSION; + if (fileName.compare(fileName.length() - ext.length(), ext.length(), ext) == 0) { + clone->singleNormStream = d->openInput(fileName.c_str(), readBufferSize); + break; + } + } + } + } + + success = true; + } + _CLFINALLY( + if (!success) { + // An exception occured during reopen, we have to decRef the norms + // that we incRef'ed already and close singleNormsStream and FieldsReader + clone->decRefNorms(); + }) + + //disown this memory + this->freqStream = NULL; + this->_fieldInfos = NULL; + this->tis = NULL; + this->deletedDocs = NULL; + this->ones = NULL; + this->termVectorsReaderOrig = NULL; + this->cfsReader = NULL; + this->freqStream = NULL; + this->proxStream = NULL; + this->termVectorsReaderOrig = NULL; + this->cfsReader = NULL; + this->storeCFSReader = NULL; + this->singleNormStream = NULL; + + return clone; +} + + +/** Returns the field infos of this segment */ +FieldInfos *SegmentReader::fieldInfos() { + return _fieldInfos; +} + +/** + * Return the name of the segment this reader is reading. + */ +const char *SegmentReader::getSegmentName() { + return segment.c_str(); +} + +/** + * Return the SegmentInfo of the segment this reader is reading. + */ +SegmentInfo *SegmentReader::getSegmentInfo() { + return si; +} + +void SegmentReader::setSegmentInfo(SegmentInfo *info) { + si = info; +} + +void SegmentReader::startCommit() { + DirectoryIndexReader::startCommit(); + rollbackDeletedDocsDirty = deletedDocsDirty; + rollbackNormsDirty = normsDirty; + rollbackUndeleteAll = undeleteAll; + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + Norm *norm = it->second; + norm->rollbackDirty = norm->dirty; + } +} + +void SegmentReader::rollbackCommit() { + DirectoryIndexReader::rollbackCommit(); + deletedDocsDirty = rollbackDeletedDocsDirty; + normsDirty = rollbackNormsDirty; + undeleteAll = rollbackUndeleteAll; + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + Norm *norm = it->second; + norm->dirty = norm->rollbackDirty; + } +} + +const char *SegmentReader::getClassName() { + return "SegmentReader"; +} +const char *SegmentReader::getObjectName() const { + return getClassName(); +} + +bool SegmentReader::normsClosed() { + if (singleNormStream != NULL) { + return false; + } + NormsType::iterator it = _norms.begin(); + while (it != _norms.end()) { + Norm *norm = it->second; + if (norm->refCount > 0) { + return false; + } + } + return true; +} +CL_NS_END diff --git a/src/core/CLucene/index/SegmentTermDocs.cpp b/src/core/CLucene/index/SegmentTermDocs.cpp new file mode 100644 index 00000000000..ae4994a2b4e --- /dev/null +++ b/src/core/CLucene/index/SegmentTermDocs.cpp @@ -0,0 +1,210 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SegmentHeader.h" + +#include "CLucene/store/IndexInput.h" +#include "Term.h" +#include "vp4.h" + +#include +#include + +#if defined(USE_AVX2) && defined(__x86_64__) +#define P4DEC p4nd1dec256v32 +#else +#define P4DEC p4nd1dec128v32 +#endif + +CL_NS_DEF(index) + +SegmentTermDocs::SegmentTermDocs(const SegmentReader *_parent) : parent(_parent), freqStream(_parent->freqStream->clone()), + count(0), df(0), deletedDocs(_parent->deletedDocs), _doc(0), _freq(0), skipInterval(_parent->tis->getSkipInterval()), + maxSkipLevels(_parent->tis->getMaxSkipLevels()), skipListReader(NULL), freqBasePointer(0), proxBasePointer(0), + skipPointer(0), haveSkipped(false), pointer(0), pointerMax(0) { + CND_CONDITION(_parent != NULL, "Parent is NULL"); + memset(docs,0,PFOR_BLOCK_SIZE*sizeof(int32_t)); + memset(freqs,0,PFOR_BLOCK_SIZE*sizeof(int32_t)); +} + +SegmentTermDocs::~SegmentTermDocs() { + close(); +} + +TermPositions *SegmentTermDocs::__asTermPositions() { + return NULL; +} + +void SegmentTermDocs::seek(Term *term) { + TermInfo *ti = parent->tis->get(term); + seek(ti, term); + _CLDELETE(ti); +} + +void SegmentTermDocs::seek(TermEnum *termEnum) { + TermInfo *ti = NULL; + Term *term = NULL; + + // use comparison of fieldinfos to verify that termEnum belongs to the same segment as this SegmentTermDocs + if (termEnum->getObjectName() == SegmentTermEnum::getClassName() && + ((SegmentTermEnum *) termEnum)->fieldInfos == parent->_fieldInfos) { + SegmentTermEnum *segmentTermEnum = (SegmentTermEnum *) termEnum; + term = segmentTermEnum->term(false); + ti = segmentTermEnum->getTermInfo(); + } else { + term = termEnum->term(false); + ti = parent->tis->get(term); + } + + seek(ti, term); + _CLDELETE(ti); +} +void SegmentTermDocs::seek(const TermInfo *ti, Term *term) { + count = 0; + FieldInfo *fi = parent->_fieldInfos->fieldInfo(term->field()); + currentFieldStoresPayloads = (fi != NULL) ? fi->storePayloads : false; + if (ti == NULL) { + df = 0; + } else {// punt case + df = ti->docFreq; + _doc = 0; + freqBasePointer = ti->freqPointer; + proxBasePointer = ti->proxPointer; + skipPointer = freqBasePointer + ti->skipOffset; + freqStream->seek(freqBasePointer); + haveSkipped = false; + } +} + +void SegmentTermDocs::close() { + _CLDELETE(freqStream); + _CLDELETE(skipListReader); +} + +int32_t SegmentTermDocs::doc() const { + return _doc; +} +int32_t SegmentTermDocs::freq() const { + return _freq; +} + +bool SegmentTermDocs::next() { + pointer++; + if (pointer >= pointerMax) { + pointerMax = SegmentTermDocs::read(docs, freqs, PFOR_BLOCK_SIZE); // refill buffer + if (pointerMax != 0) { + pointer = 0; + } else { + // NOTE: do not close here, try to close by upper caller or destruct. + //SegmentTermDocs::close(); // close stream + _doc = LUCENE_INT32_MAX_SHOULDBE; // set to sentinel value + return false; + } + } + _doc = docs[pointer]; + _freq = freqs[pointer]; + return true; +} + +/*bool SegmentTermDocs::next() { + while (true) { + if (count == df) + return false; + + uint32_t docCode = freqStream->readVInt(); + _doc += docCode >> 1; //unsigned shift + if ((docCode & 1) != 0)// if low bit is set + _freq = 1; // _freq is one + else + _freq = freqStream->readVInt();// else read _freq + count++; + + if ((deletedDocs == NULL) || (_doc >= 0 && deletedDocs->get(_doc) == false)) + break; + skippingDoc(); + } + return true; +}*/ + +int32_t SegmentTermDocs::read(int32_t *docs, int32_t *freqs, int32_t length) { + int32_t i = 0; + //todo: one optimization would be to get the pointer buffer for ram or mmap dirs + //and iterate over them instead of using readByte() intensive functions. + if (i < length && count < df) { + uint32_t arraySize = freqStream->readVInt(); + if (arraySize < PFOR_BLOCK_SIZE) { + int32_t _docDelta{0}; + while (i < length && count < df && i < arraySize) { + // manually inlined call to next() for speed + uint32_t docCode = freqStream->readVInt(); + _docDelta += docCode; + _doc = _docDelta; + _freq = 1; // _freq is one + count++; + + if (deletedDocs == NULL || (_doc >= 0 && !deletedDocs->get(_doc))) { + docs[i] = _doc; + freqs[i] = _freq; + i++; + } + } + } else { + // need one more space for decode, otherwise will buffer overflow when decoding + std::vector arr(arraySize + 1); + uint32_t serializedSize = freqStream->readVInt(); + // need more space for decode, otherwise will buffer overflow when decoding + std::vector buf(serializedSize + PFOR_BLOCK_SIZE); + freqStream->readBytes(buf.data(), serializedSize); + P4DEC(buf.data(), arraySize, arr.data()); + + while (i < length && count < df && i < arraySize) { + _doc = arr[i]; + _freq = 1;// _freq is one + if (deletedDocs == NULL || (_doc >= 0 && !deletedDocs->get(_doc))) { + docs[i] = _doc; + freqs[i] = _freq; + i++; + } + count++; + } + } + } + return i; +} + +bool SegmentTermDocs::skipTo(const int32_t target) { + assert(count <= df); + + if (df >= skipInterval) {// optimized case + if (skipListReader == NULL) + skipListReader = _CLNEW DefaultSkipListReader(freqStream->clone(), maxSkipLevels, skipInterval);// lazily clone + + if (!haveSkipped) {// lazily initialize skip stream + skipListReader->init(skipPointer, freqBasePointer, proxBasePointer, df, currentFieldStoresPayloads); + haveSkipped = true; + } + + int32_t newCount = skipListReader->skipTo(target); + if (newCount > count) { + freqStream->seek(skipListReader->getFreqPointer()); + skipProx(skipListReader->getProxPointer(), skipListReader->getPayloadLength()); + + _doc = skipListReader->getDoc(); + count = newCount; + } + } + + // done skipping, now just scan + do { + if (!next()) + return false; + } while (target > _doc); + return true; +} + + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentTermEnum.cpp b/src/core/CLucene/index/SegmentTermEnum.cpp new file mode 100644 index 00000000000..1383451c458 --- /dev/null +++ b/src/core/CLucene/index/SegmentTermEnum.cpp @@ -0,0 +1,395 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SegmentHeader.h" +#include "_SegmentTermEnum.h" + +#include "Terms.h" +#include "_FieldInfos.h" +#include "Term.h" +#include "_TermInfo.h" +#include "_TermInfosWriter.h" + +CL_NS_USE(store) +CL_NS_DEF(index) + + SegmentTermEnum::SegmentTermEnum(IndexInput* i, FieldInfos* fis, const bool isi): + fieldInfos(fis){ + //Func - Constructor + //Pre - i holds a reference to an instance of IndexInput + // fis holds a reference to an instance of FieldInfos + // isi + //Post - An instance of SegmentTermEnum has been created + input = i; + position = -1; + //Instantiate a Term with empty field, empty text and which is interned (see term.h what interned means) + _term = _CLNEW Term; + isIndex = isi; + termInfo = _CLNEW TermInfo(); + indexPointer = 0; + buffer = NULL; + bufferLength = 0; + prev = NULL; + formatM1SkipInterval = 0; + maxSkipLevels = 1; + + //Set isClone to false as the instance is not clone of another instance + isClone = false; + + + int32_t firstInt = input->readInt(); + if (firstInt >= 0) { + // original-format file, without explicit format version number + format = 0; + size = firstInt; + + // back-compatible settings + indexInterval = 128; + skipInterval = LUCENE_INT32_MAX_SHOULDBE; // switch off skipTo optimization + + } else { + // we have a format version number + format = firstInt; + + // check that it is a format we can understand + if (format < TermInfosWriter::FORMAT){ + TCHAR err[30]; + _sntprintf(err,30,_T("Unknown format version: %d"), format); + _CLTHROWT(CL_ERR_CorruptIndex,err); + } + + size = input->readLong(); // read the size + if (size < 0) { // read the size at file footer, if size < 0 + auto pos = input->getFilePointer(); + input->seek(input->length() - 8); + size = input->readLong(); + input->seek(pos); + } + + if(format == -1){ + if (!isIndex) { + indexInterval = input->readInt(); + formatM1SkipInterval = input->readInt(); + } + // switch off skipTo optimization for file format prior to 1.4rc2 in order to avoid a bug in + // skipTo implementation of these versions + skipInterval = LUCENE_INT32_MAX_SHOULDBE; + }else{ + indexInterval = input->readInt(); + skipInterval = input->readInt(); + if ( format == -3 ) { + // this new format introduces multi-level skipping + maxSkipLevels = input->readInt(); + } + } + } + } + + SegmentTermEnum::SegmentTermEnum(const SegmentTermEnum& clone): + fieldInfos(clone.fieldInfos) + { + //Func - Constructor + // The instance is created by cloning all properties of clone + //Pre - clone holds a valid reference to SegmentTermEnum + //Post - An instance of SegmentTermEnum with the same properties as clone + + input = clone.input->clone(); + //Copy the postion from the clone + position = clone.position; + + if ( clone._term != NULL ){ + _term = _CLNEW Term; + _term->set(clone._term,clone._term->text()); + }else + _term = NULL; + isIndex = clone.isIndex; + termInfo = _CLNEW TermInfo(clone.termInfo); + indexPointer = clone.indexPointer; + buffer = clone.buffer==NULL?NULL:(TCHAR*)malloc(sizeof(TCHAR) * (clone.bufferLength+1)); + bufferLength = clone.bufferLength; + prev = clone.prev==NULL?NULL:_CLNEW Term(clone.prev->field(),clone.prev->text(),false); + size = clone.size; + + format = clone.format; + indexInterval= clone.indexInterval; + skipInterval = clone.skipInterval; + formatM1SkipInterval = clone.formatM1SkipInterval; + maxSkipLevels = clone.maxSkipLevels; + + //Set isClone to true as this instance is a clone of another instance + isClone = true; + + //Copy the contents of buffer of clone to the buffer of this instance + if ( clone.buffer != NULL ) + memcpy(buffer,clone.buffer,bufferLength * sizeof(TCHAR)); + } + + SegmentTermEnum::~SegmentTermEnum(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed. If this instance was a clone + // then the inputstream is closed and deleted too. + + //todo: revisit this... close() should clean up most of everything. + + //Finalize prev + _CLDECDELETE(prev ); + //Finalize term + _CLDECDELETE( _term ); + + + //Delete the buffer if necessary + if ( buffer != NULL ) free(buffer); + //Delete termInfo if necessary + _CLDELETE(termInfo); + + //Check if this instance is a clone + if ( isClone ){ + //Close the inputstream + input->close(); + //delete the inputstream + _CLDELETE(input); + } + } + + const char* SegmentTermEnum::getObjectName() const{ return getClassName(); } + const char* SegmentTermEnum::getClassName(){ return "SegmentTermEnum"; } + + bool SegmentTermEnum::next(){ + //Func - Moves the current of the set to the next in the set + //Pre - true + //Post - If the end has been reached NULL is returned otherwise the term has + // become the next Term in the enumeration + + //Increase position by and and check if the end has been reached + if (position++ >= size-1) { + //delete term + _CLDECDELETE(_term); + return false; + } + + //delete the previous enumerated term + Term* tmp=NULL; + if ( prev != NULL ){ + if ( _LUCENE_ATOMIC_INT_GET(prev->__cl_refcount) > 1 ){ + _CLDECDELETE(prev); //todo: tune other places try and delete its term + }else + tmp = prev; //we are going to re-use this term + } + //prev becomes the current enumerated term + prev = _term; + //term becomes the next term read from inputStream input + _term = readTerm(tmp); + + //Read docFreq, the number of documents which contain the term. + termInfo->docFreq = input->readVInt(); + //Read freqPointer, a pointer into the TermFreqs file (.frq) + termInfo->freqPointer += input->readVLong(); + + //Read proxPointer, a pointer into the TermPosition file (.prx). + termInfo->proxPointer += input->readVLong(); + + if(format == -1){ + // just read skipOffset in order to increment file pointer; + // value is never used since skipTo is switched off + if (!isIndex) { + if (termInfo->docFreq > formatM1SkipInterval) { + termInfo->skipOffset = input->readVInt(); + } + } + }else{ + if (termInfo->docFreq >= skipInterval) + termInfo->skipOffset = input->readVInt(); + } + + //Check if the enumeration is an index + if (isIndex) + //read index pointer + indexPointer += input->readVLong(); + + return true; + } + + Term* SegmentTermEnum::term(bool pointer) { + if ( pointer ) + return _CL_POINTER(_term); + else + return _term; + } + + void SegmentTermEnum::scanTo(const Term *term){ + //Func - Scan for Term without allocating new Terms + //Pre - term != NULL + //Post - The iterator term has been moved to the position where Term is expected to be + // in the enumeration + while ( term->compareTo(this->_term) > 0 && next()) + { + } + } + + void SegmentTermEnum::close() { + //Func - Closes the enumeration to further activity, freeing resources. + //Pre - true + //Post - The inputStream input has been closed + + input->close(); + } + + int32_t SegmentTermEnum::docFreq() const { + //Func - Returns the document frequency of the current term in the set + //Pre - termInfo != NULL + // next() must have been called once + //Post - The document frequency of the current enumerated term has been returned + + return termInfo->docFreq; + } + + void SegmentTermEnum::seek(const int64_t pointer, const int32_t p, Term* t, TermInfo* ti) { + //Func - Repositions term and termInfo within the enumeration + //Pre - pointer >= 0 + // p >= 0 and contains the new position within the enumeration + // t is a valid reference to a Term and is the new current term in the enumeration + // ti is a valid reference to a TermInfo and is corresponding TermInfo form the new + // current Term + //Post - term and terminfo have been repositioned within the enumeration + + //Reset the IndexInput input to pointer + input->seek(pointer); + //Assign the new position + position = p; + + //finalize the current term + if ( _term == NULL || _LUCENE_ATOMIC_INT_GET(_term->__cl_refcount) > 1 ){ + _CLDECDELETE(_term); + //Get a pointer from t and increase the reference counter of t + _term = _CLNEW Term; //cannot use reference, because TermInfosReader uses non ref-counted array + } + _term->set(t,t->text()); + + //finalize prev + _CLDECDELETE(prev); + + //Change the current termInfo so it matches the new current term + termInfo->set(ti); + + //Have the buffer grown if needed + if ( bufferLength <= _term->textLength() ) + growBuffer(_term->textLength(), true ); // copy term text into buffer + else + _tcsncpy(buffer,_term->text(),bufferLength); //just copy the buffer + } + + TermInfo* SegmentTermEnum::getTermInfo()const { + //Func - Returns a clone of the current termInfo + //Pre - termInfo != NULL + // next() must have been called once + //Post - A clone of the current termInfo has been returned + + return _CLNEW TermInfo(*termInfo); //clone + } + + void SegmentTermEnum::getTermInfo(TermInfo* ti)const { + //Func - Retrieves a clone of termInfo through the reference ti + //Pre - ti contains a valid reference to TermInfo + // termInfo != NULL + // next() must have been called once + //Post - ti contains a clone of termInfo + + ti->set(termInfo); + } + + int64_t SegmentTermEnum::freqPointer()const { + //Func - Returns the freqpointer of the current termInfo + //Pre - termInfo != NULL + // next() must have been called once + //Post - The freqpointer of the current termInfo has been returned + + return termInfo->freqPointer; + } + + int64_t SegmentTermEnum::proxPointer()const { + //Func - Returns the proxPointer of the current termInfo + //Pre - termInfo != NULL + // next() must have been called once + //Post - the proxPointer of the current termInfo has been returned + + return termInfo->proxPointer; + } + + SegmentTermEnum* SegmentTermEnum::clone() const { + //Func - Returns a clone of this instance + //Pre - true + //Post - An clone of this instance has been returned + + return _CLNEW SegmentTermEnum(*this); + } + + Term* SegmentTermEnum::readTerm(Term* reuse) { + //Func - Reads the next term in the enumeration + //Pre - true + //Post - The next Term in the enumeration has been read and returned + + //Read the start position from the inputStream input + int32_t start = input->readVInt(); + //Read the length of term in the inputStream input + int32_t length = input->readVInt(); + + //Calculated the total lenght of bytes that buffer must be to contain the current + //chars in buffer and the new ones yet to be read + uint32_t totalLength = start + length; + + if (static_cast(bufferLength) < totalLength+1) + growBuffer(totalLength, false); //dont copy the buffer over. + + //Read a length number of characters into the buffer from position start in the inputStream input + input->readChars(buffer, start, length); + //Null terminate the string + buffer[totalLength] = 0; + + //Return a new Term + int32_t field = input->readVInt(); + const TCHAR* fieldname = fieldInfos->fieldName(field); + if ( reuse == NULL ) + reuse = _CLNEW Term; + + reuse->set(fieldname, buffer, false); + return reuse; + } + + void SegmentTermEnum::growBuffer(const uint32_t length, bool force_copy) { + //Func - Instantiate a buffer of length length+1 + //Pre - length > 0 + //Post - pre(buffer) has been deleted with its contents. A new buffer + // has been allocated of length length+1 and the text of term has been copied + // to buffer + //todo: we could guess that we will need to re-grow this + //buffer a few times...so start off with a reasonable grow + //value... + if ( bufferLength > length ) + return; + + //Store the new bufferLength + if ( length - bufferLength < 8 ) + bufferLength = length+8; + else + bufferLength = length+1; + + bool copy = buffer==NULL; + + //Instantiate the new buffer + 1 is needed for terminator '\0' + if ( buffer == NULL ) + buffer = (TCHAR*)malloc(sizeof(TCHAR) * (bufferLength+1)); + else + buffer = (TCHAR*)realloc(buffer, sizeof(TCHAR) * (bufferLength+1)); + + if ( copy || force_copy){ + //Copy the text of term into buffer + _tcsncpy(buffer,_term->text(),bufferLength); + } + } + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentTermPositions.cpp b/src/core/CLucene/index/SegmentTermPositions.cpp new file mode 100644 index 00000000000..5fe1e787db9 --- /dev/null +++ b/src/core/CLucene/index/SegmentTermPositions.cpp @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SegmentHeader.h" + +#include "Terms.h" + +CL_NS_USE(util) +CL_NS_DEF(index) + +SegmentTermPositions::SegmentTermPositions(const SegmentReader* _parent): + SegmentTermDocs(_parent), proxStream(NULL)// the proxStream will be cloned lazily when nextPosition() is called for the first time + ,lazySkipPointer(-1), lazySkipProxCount(0) +{ + CND_CONDITION(_parent != NULL, "Parent is NULL"); +} + +SegmentTermPositions::~SegmentTermPositions() { + close(); +} + +TermDocs* SegmentTermPositions::__asTermDocs(){ + return (TermDocs*) this; +} +TermPositions* SegmentTermPositions::__asTermPositions(){ + return (TermPositions*) this; +} + +void SegmentTermPositions::seek(const TermInfo* ti, Term* term) { + SegmentTermDocs::seek(ti, term); + if (ti != NULL) + lazySkipPointer = ti->proxPointer; + + lazySkipProxCount = 0; + proxCount = 0; + payloadLength = 0; + needToLoadPayload = false; +} + +void SegmentTermPositions::close() { + SegmentTermDocs::close(); + //Check if proxStream still exists + if(proxStream){ + proxStream->close(); + _CLDELETE( proxStream ); + } +} + +int32_t SegmentTermPositions::nextPosition() { + // TODO:need to do like this: if (indexOptions != IndexOptions.DOCS_AND_FREQS_AND_POSITIONS) + if (parent->proxStream== NULL){ + return 0; + } + // perform lazy skips if neccessary + lazySkip(); + proxCount--; + return position += readDeltaPosition(); +} + +int32_t SegmentTermPositions::readDeltaPosition() { + int32_t delta = proxStream->readVInt(); + if (currentFieldStoresPayloads) { + // if the current field stores payloads then + // the position delta is shifted one bit to the left. + // if the LSB is set, then we have to read the current + // payload length + if ((delta & 1) != 0) { + payloadLength = proxStream->readVInt(); + } + delta = (int32_t)((uint32_t)delta >> (uint32_t)1); + needToLoadPayload = true; + } + return delta; +} + +void SegmentTermPositions::skippingDoc() { + lazySkipProxCount += _freq; +} + +bool SegmentTermPositions::next() { + // we remember to skip the remaining positions of the current + // document lazily + lazySkipProxCount += proxCount; + + if (SegmentTermDocs::next()) { // run super + proxCount = _freq; // note frequency + position = 0; // reset position + return true; + } + return false; +} + +int32_t SegmentTermPositions::read(int32_t* /*docs*/, int32_t* /*freqs*/, int32_t /*length*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation,"TermPositions does not support processing multiple documents in one call. Use TermDocs instead."); +} + +void SegmentTermPositions::skipProx(const int64_t proxPointer, const int32_t _payloadLength){ + // we save the pointer, we might have to skip there lazily + lazySkipPointer = proxPointer; + lazySkipProxCount = 0; + proxCount = 0; + this->payloadLength = _payloadLength; + needToLoadPayload = false; +} + +void SegmentTermPositions::skipPositions(const int32_t n) { + for ( int32_t f = n; f > 0; f-- ) { // skip unread positions + readDeltaPosition(); + skipPayload(); + } +} + +void SegmentTermPositions::skipPayload() { + if (needToLoadPayload && payloadLength > 0) { + proxStream->seek(proxStream->getFilePointer() + payloadLength); + } + needToLoadPayload = false; +} + +void SegmentTermPositions::lazySkip() { + if (proxStream == NULL) { + // clone lazily + proxStream = parent->proxStream->clone(); + } + + // we might have to skip the current payload + // if it was not read yet + skipPayload(); + + if (lazySkipPointer != -1) { + proxStream->seek(lazySkipPointer); + lazySkipPointer = -1; + } + + if (lazySkipProxCount != 0) { + skipPositions(lazySkipProxCount); + lazySkipProxCount = 0; + } +} + +int32_t SegmentTermPositions::getPayloadLength() const { return payloadLength; } + +uint8_t* SegmentTermPositions::getPayload(uint8_t* data) { + if (!needToLoadPayload) { + _CLTHROWA(CL_ERR_IO, "Payload cannot be loaded more than once for the same term position."); + } + + // read payloads lazily + uint8_t* retArray; + // TODO: Complete length logic ( possibly using ValueArray ? ) + if (data == NULL /*|| data.length - offset < payloadLength*/) { + // the array is too small to store the payload data, + // so we allocate a new one + _CLDELETE_ARRAY(data); + retArray = _CL_NEWARRAY(uint8_t, payloadLength); + } else { + retArray = data; + } + proxStream->readBytes(retArray, payloadLength); + needToLoadPayload = false; + return retArray; +} +bool SegmentTermPositions::isPayloadAvailable() const { return needToLoadPayload && (payloadLength > 0); } + +CL_NS_END diff --git a/src/core/CLucene/index/SegmentTermVector.cpp b/src/core/CLucene/index/SegmentTermVector.cpp new file mode 100644 index 00000000000..049cb6c563f --- /dev/null +++ b/src/core/CLucene/index/SegmentTermVector.cpp @@ -0,0 +1,156 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FieldInfos.h" +#include "_TermVector.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/Array.h" + +CL_NS_USE(util) +CL_NS_DEF(index) + +ValueArray SegmentTermPositionVector::EMPTY_TERM_POS; + +SegmentTermVector::SegmentTermVector(const TCHAR* _field, + ArrayBase* _terms, ArrayBase* _termFreqs) { + this->field = STRDUP_TtoT(_field); // TODO: Try and avoid this dup (using intern'ing perhaps?) + this->terms = _terms; + this->termFreqs = _termFreqs; +} + +SegmentTermVector::~SegmentTermVector(){ + _CLDELETE_LCARRAY(field); + _CLDELETE(terms); + _CLDELETE(termFreqs); +} +TermPositionVector* SegmentTermVector::__asTermPositionVector(){ + return NULL; +} + +const TCHAR* SegmentTermVector::getField() { + return field; +} + +TCHAR* SegmentTermVector::toString() const{ + StringBuffer sb; + sb.appendChar('{'); + sb.append(field); + sb.append(_T(": ")); + + int32_t i=0; + while ( terms && terms->values[i] != NULL ){ + if (i>0) + sb.append(_T(", ")); + sb.append(terms->values[i]); + sb.appendChar('/'); + + sb.appendInt((*termFreqs)[i]); + } + sb.appendChar('}'); + return sb.toString(); +} + +int32_t SegmentTermVector::size() { + if ( terms == NULL ) + return 0; + + return terms->length; +} + +const CL_NS(util)::ArrayBase* SegmentTermVector::getTerms() { + return (CL_NS(util)::ArrayBase*)terms; +} + +const ArrayBase* SegmentTermVector::getTermFrequencies() { + return termFreqs; +} + +int32_t SegmentTermVector::binarySearch(const ArrayBase& a, const TCHAR* key) const +{ + int32_t low = 0; + int32_t hi = a.length - 1; + int32_t mid = 0; + while (low <= hi) + { + mid = (low + hi) >> 1; + + int32_t c = _tcscmp(a[mid],key); + if (c==0) + return mid; + else if (c > 0) + hi = mid - 1; + else // This gets the insertion point right on the last loop. + low = ++mid; + } + return -mid - 1; +} + +int32_t SegmentTermVector::indexOf(const TCHAR* termText) { + if(terms == NULL) + return -1; + int32_t res = binarySearch(*terms, termText); + return res >= 0 ? res : -1; +} + +ArrayBase* SegmentTermVector::indexesOf(const CL_NS(util)::ArrayBase& termNumbers, const int32_t start, const int32_t len) { + // TODO: there must be a more efficient way of doing this. + // At least, we could advance the lower bound of the terms array + // as we find valid indexes. Also, it might be possible to leverage + // this even more by starting in the middle of the termNumbers array + // and thus dividing the terms array maybe in half with each found index. + ArrayBase* ret = _CLNEW ValueArray(len); + for (int32_t i=0; ivalues[i] = indexOf(termNumbers[start+ i]); + } + return ret; +} + + +SegmentTermPositionVector::SegmentTermPositionVector(const TCHAR* field, + ArrayBase* terms, ArrayBase* termFreqs, + ArrayBase< ArrayBase* >* _positions, + ArrayBase< ArrayBase* >* _offsets) + : SegmentTermVector(field,terms,termFreqs), + positions(_positions), + offsets(_offsets) +{ +} +SegmentTermPositionVector::~SegmentTermPositionVector(){ + _CLLDELETE(offsets); + _CLLDELETE(positions); +} + +ArrayBase* SegmentTermPositionVector::indexesOf(const ArrayBase& termNumbers, const int32_t start, const int32_t len) +{ + return SegmentTermVector::indexesOf(termNumbers, start, len); +} + +TermPositionVector* SegmentTermPositionVector::__asTermPositionVector(){ + return this; +} + +const ArrayBase* SegmentTermPositionVector::getOffsets(const size_t index) { + if(offsets == NULL) + return NULL; + if (index < offsets->length) + return offsets->values[index]; + else + return TermVectorOffsetInfo_EMPTY_OFFSET_INFO; +} + +const ArrayBase* SegmentTermPositionVector::getTermPositions(const size_t index) { + if(positions == NULL) + return NULL; + + if (index < positions->length) + return positions->values[index]; + else + return &EMPTY_TERM_POS; +} + +CL_NS_END + diff --git a/src/core/CLucene/index/SkipListReader.cpp b/src/core/CLucene/index/SkipListReader.cpp new file mode 100644 index 00000000000..7b356b9c717 --- /dev/null +++ b/src/core/CLucene/index/SkipListReader.cpp @@ -0,0 +1,357 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_SkipListReader.h" + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_USE(store) +CL_NS_DEF(index) + +MultiLevelSkipListReader::MultiLevelSkipListReader(IndexInput* _skipStream, const int32_t maxSkipLevels, + const int32_t _skipInterval): + maxNumberOfSkipLevels(maxSkipLevels),numberOfLevelsToBuffer(1), + skipStream(CL_NS(util)::ObjectArray(maxSkipLevels)), + skipPointer(_CL_NEWARRAY(int64_t,maxSkipLevels)), + skipInterval(_CL_NEWARRAY(int32_t,maxSkipLevels)), + numSkipped(_CL_NEWARRAY(int32_t,maxSkipLevels)), + skipDoc(_CL_NEWARRAY(int32_t,maxSkipLevels)), + childPointer(_CL_NEWARRAY(int64_t,maxSkipLevels)) +{ + memset(this->skipPointer,0,sizeof(int64_t) * maxSkipLevels); + memset(this->skipInterval,0,sizeof(int32_t) * maxSkipLevels); + memset(this->numSkipped,0,sizeof(int32_t) * maxSkipLevels); + memset(this->skipDoc,0,sizeof(int32_t) * maxSkipLevels); + memset(this->childPointer,0,sizeof(int32_t) * maxSkipLevels); + + this->numberOfLevelsToBuffer = 0; + this->numberOfSkipLevels = 0; + this->docCount = 0; + this->lastDoc = 0; + this->lastChildPointer = 0; + this->haveSkipped = false; + this->skipStream[0] = _skipStream; + this->inputIsBuffered = _skipStream->instanceOf(BufferedIndexInput::getClassName()); + this->skipInterval[0] = _skipInterval; + for (int32_t i = 1; i < maxSkipLevels; i++) { + // cache skip intervals + this->skipInterval[i] = this->skipInterval[i - 1] * _skipInterval; + } +} +MultiLevelSkipListReader::~MultiLevelSkipListReader(){ + close(); + _CLDELETE_LARRAY(skipPointer); + _CLDELETE_LARRAY(childPointer); + _CLDELETE_LARRAY(numSkipped); + _CLDELETE_LARRAY(skipInterval); + _CLDELETE_LARRAY(skipDoc); +} + +int32_t MultiLevelSkipListReader::getDoc() const { + return lastDoc; +} + +int32_t MultiLevelSkipListReader::skipTo(const int32_t target) { + if (!haveSkipped) { + // first time, load skip levels + loadSkipLevels(); + haveSkipped = true; + } + + // walk up the levels until highest level is found that has a skip + // for this target + int32_t level = 0; + while (level < numberOfSkipLevels - 1 && target > skipDoc[level + 1]) { + level++; + } + + while (level >= 0) { + if (target > skipDoc[level]) { + if (!loadNextSkip(level)) { + continue; + } + } else { + // no more skips on this level, go down one level + if (level > 0 && lastChildPointer > skipStream[level - 1]->getFilePointer()) { + seekChild(level - 1); + } + level--; + } + } + + return numSkipped[0] - skipInterval[0] - 1; +} + +bool MultiLevelSkipListReader::loadNextSkip(const int32_t level) { + // we have to skip, the target document is greater than the current + // skip list entry + setLastSkipData(level); + + numSkipped[level] += skipInterval[level]; + + if (numSkipped[level] > docCount) { + // this skip list is exhausted + skipDoc[level] = LUCENE_INT32_MAX_SHOULDBE; + if (numberOfSkipLevels > level) numberOfSkipLevels = level; + return false; + } + + // read next skip entry + skipDoc[level] += readSkipData(level, skipStream[level]); + + if (level != 0) { + // read the child pointer if we are not on the leaf level + childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; + } + return true; +} + +void MultiLevelSkipListReader::seekChild(const int32_t level) { + skipStream[level]->seek(lastChildPointer); + numSkipped[level] = numSkipped[level + 1] - skipInterval[level + 1]; + skipDoc[level] = lastDoc; + if (level > 0) { + childPointer[level] = skipStream[level]->readVLong() + skipPointer[level - 1]; + } +} + +void MultiLevelSkipListReader::close() { + for (int32_t i = 1; i < maxNumberOfSkipLevels; i++) { + if (skipStream[i] != NULL) { + //skipStream[i]->close(); + _CLDELETE(skipStream[i]); // ISH: We actually do need to nullify pointer here + } + } +} + +void MultiLevelSkipListReader::init(const int64_t _skipPointer, const int32_t df) { + this->skipPointer[0] = _skipPointer; + this->docCount = df; + memset(skipDoc,0,sizeof(int32_t) * maxNumberOfSkipLevels); + memset(numSkipped,0,sizeof(int32_t) * maxNumberOfSkipLevels); + memset(childPointer,0,sizeof(int64_t) * maxNumberOfSkipLevels); + if ( numberOfSkipLevels > 1 ) + { + for (int i=1;i maxNumberOfSkipLevels) { + numberOfSkipLevels = maxNumberOfSkipLevels; + } + + skipStream[0]->seek(skipPointer[0]); + + int32_t toBuffer = numberOfLevelsToBuffer; + + for (int32_t i = numberOfSkipLevels - 1; i > 0; i--) { + // the length of the current level + int64_t length = skipStream[0]->readVLong(); + + // the start pointer of the current level + skipPointer[i] = skipStream[0]->getFilePointer(); + if (toBuffer > 0) { + // buffer this level + skipStream[i] = _CLNEW SkipBuffer(skipStream[0], (int32_t) length); + toBuffer--; + } else { + // clone this stream, it is already at the start of the current level + skipStream[i] = skipStream[0]->clone(); + if (inputIsBuffered && length < BufferedIndexInput::BUFFER_SIZE) { + ((BufferedIndexInput*) skipStream[i])->setBufferSize((int32_t) length); + } + + // move base stream beyond the current level + skipStream[0]->seek(skipStream[0]->getFilePointer() + length); + } + } + + // use base stream for the lowest level + skipPointer[0] = skipStream[0]->getFilePointer(); +} + +void MultiLevelSkipListReader::setLastSkipData(const int32_t level) { + lastDoc = skipDoc[level]; + lastChildPointer = childPointer[level]; +} + +MultiLevelSkipListReader::SkipBuffer::SkipBuffer(IndexInput* input, const int32_t _length):pos(0) +{ + data = _CL_NEWARRAY(uint8_t,_length); + this->_datalength = _length; + pointer = input->getFilePointer(); + input->readBytes(data, _length); +} +MultiLevelSkipListReader::SkipBuffer::~SkipBuffer() +{ + _CLLDELETE(data); +} + +void MultiLevelSkipListReader::SkipBuffer::close() { + _CLDELETE(data); + _datalength=0; +} + +int64_t MultiLevelSkipListReader::SkipBuffer::getFilePointer() const { + return pointer + pos; +} + +int64_t MultiLevelSkipListReader::SkipBuffer::length() const { + return _datalength; +} + +uint8_t MultiLevelSkipListReader::SkipBuffer::readByte() { + return data[pos++]; +} + +void MultiLevelSkipListReader::SkipBuffer::readBytes(uint8_t* b, const int32_t len) { + readBytes(b, len, 0); +} + +void MultiLevelSkipListReader::SkipBuffer::readBytes(uint8_t* b, const int32_t len, int32_t offset) { + memcpy(b+offset,data+pos,len*sizeof(uint8_t)); + pos += len; +} + +void MultiLevelSkipListReader::SkipBuffer::seek(const int64_t _pos) { + this->pos = static_cast(_pos - pointer); +} + +const char* MultiLevelSkipListReader::SkipBuffer::getObjectName() const{ return getClassName(); } +const char* MultiLevelSkipListReader::SkipBuffer::getClassName(){ return "MultiLevelSkipListReader::SkipBuffer"; } + +const char* MultiLevelSkipListReader::SkipBuffer::getDirectoryType() const{ return "SKIP"; } +MultiLevelSkipListReader::SkipBuffer::SkipBuffer(const SkipBuffer& other): + IndexInput(other) +{ + data = _CL_NEWARRAY(uint8_t,other._datalength); + memcpy(data,other.data,other._datalength * sizeof(uint8_t)); + this->_datalength = other._datalength; + this->pointer = other.pointer; + this->pos = other.pos; +} +IndexInput* MultiLevelSkipListReader::SkipBuffer::clone() const{ + return _CLNEW SkipBuffer(*this); +} + + + + + + + +DefaultSkipListReader::DefaultSkipListReader(CL_NS(store)::IndexInput* _skipStream, const int32_t maxSkipLevels, const int32_t _skipInterval) + : MultiLevelSkipListReader(_skipStream, maxSkipLevels, _skipInterval) +{ + freqPointer = _CL_NEWARRAY(int64_t,maxSkipLevels); + if (0) { + proxPointer = _CL_NEWARRAY(int64_t, maxSkipLevels); + } + payloadLength = _CL_NEWARRAY(int32_t,maxSkipLevels); + memset(freqPointer,0, sizeof(int64_t) * maxSkipLevels); + if (0) { + memset(proxPointer, 0, sizeof(int64_t) * maxSkipLevels); + } + memset(payloadLength,0, sizeof(int32_t) * maxSkipLevels); + this->lastFreqPointer = 0; + if (0) { + this->lastProxPointer = 0; + } + this->lastPayloadLength = 0; + this->currentFieldStoresPayloads = false; +} + +DefaultSkipListReader::~DefaultSkipListReader(){ + _CLDELETE_LARRAY(freqPointer); + if (0) { + _CLDELETE_LARRAY(proxPointer); + } + _CLDELETE_LARRAY(payloadLength); +} + +void DefaultSkipListReader::init(const int64_t _skipPointer, const int64_t freqBasePointer, const int64_t proxBasePointer, const int32_t df, const bool storesPayloads) { + MultiLevelSkipListReader::init(_skipPointer, df); + this->currentFieldStoresPayloads = storesPayloads; + lastFreqPointer = freqBasePointer; + if (0) { + lastProxPointer = proxBasePointer; + } + + for (int32_t j=0; jreadVInt(); + if ((delta & 1) != 0) { + payloadLength[level] = _skipStream->readVInt(); + } + delta = (int32_t)(((uint32_t)delta) >> (uint32_t)1); + } else { + delta = _skipStream->readVInt(); + } + freqPointer[level] += _skipStream->readVInt(); + if (0) { + proxPointer[level] += _skipStream->readVInt(); + } + + return delta; +} + +CL_NS_END diff --git a/src/core/CLucene/index/SkipListWriter.cpp b/src/core/CLucene/index/SkipListWriter.cpp new file mode 100644 index 00000000000..bc54b53656b --- /dev/null +++ b/src/core/CLucene/index/SkipListWriter.cpp @@ -0,0 +1,187 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/_Arrays.h" +#include "_SkipListWriter.h" + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + +void MultiLevelSkipListWriter::bufferSkip(int32_t df) { + int32_t numLevels; + + // determine max level + for (numLevels = 0; (df % skipInterval) == 0 && numLevels < numberOfSkipLevels; df /= skipInterval) { + numLevels++; + } + + int64_t childPointer = 0; + + for (int32_t level = 0; level < numLevels; level++) { + writeSkipData(level, (*skipBuffer)[level]); + + int64_t newChildPointer = (*skipBuffer)[level]->getFilePointer(); + + if (level != 0) { + // store child pointers for all levels except the lowest + (*skipBuffer)[level]->writeVLong(childPointer); + } + + //remember the childPointer for the next level + childPointer = newChildPointer; + } +} + +int64_t MultiLevelSkipListWriter::writeSkip(IndexOutput *output) { + int64_t skipPointer = output->getFilePointer(); + if (skipBuffer == NULL || skipBuffer->length == 0) return skipPointer; + + for (int32_t level = numberOfSkipLevels - 1; level > 0; level--) { + int64_t length = (*skipBuffer)[level]->getFilePointer(); + if (length > 0) { + output->writeVLong(length); + (*skipBuffer)[level]->writeTo(output); + } + } + (*skipBuffer)[0]->writeTo(output); + + return skipPointer; +} + +MultiLevelSkipListWriter::MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df) { + this->skipBuffer = NULL; + this->skipInterval = skipInterval; + + // calculate the maximum number of skip levels for this document frequency + numberOfSkipLevels = df == 0 ? 0 : (int32_t) floor(log((float_t) df) / log((float_t) skipInterval)); + + // make sure it does not exceed maxSkipLevels + if (numberOfSkipLevels > maxSkipLevels) { + numberOfSkipLevels = maxSkipLevels; + } +} +MultiLevelSkipListWriter::~MultiLevelSkipListWriter() { + _CLDELETE(skipBuffer); +} + +void MultiLevelSkipListWriter::init() { + skipBuffer = _CLNEW CL_NS(util)::ObjectArray(numberOfSkipLevels); + for (int32_t i = 0; i < numberOfSkipLevels; i++) { + skipBuffer->values[i] = _CLNEW RAMOutputStream; + } +} + +void MultiLevelSkipListWriter::resetSkip() { + // creates new buffers or empties the existing ones + if (skipBuffer == NULL) { + init(); + } else { + for (size_t i = 0; i < skipBuffer->length; i++) { + (*skipBuffer)[i]->reset(); + } + } +} + + +void DefaultSkipListWriter::setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength) { + this->curDoc = doc; + this->curStorePayloads = storePayloads; + this->curPayloadLength = payloadLength; + this->curFreqPointer = freqOutput->getFilePointer(); + if (proxOutput != nullptr) { + this->curProxPointer = proxOutput->getFilePointer(); + } +} + +void DefaultSkipListWriter::resetSkip() { + MultiLevelSkipListWriter::resetSkip(); + memset(lastSkipDoc, 0, numberOfSkipLevels * sizeof(int32_t)); + Arrays::fill(lastSkipPayloadLength, numberOfSkipLevels, -1);// we don't have to write the first length in the skip list + if (proxOutput != nullptr) { + Arrays::fill(lastSkipProxPointer, numberOfSkipLevels, proxOutput->getFilePointer()); + } + Arrays::fill(lastSkipFreqPointer, numberOfSkipLevels, freqOutput->getFilePointer()); +} + +void DefaultSkipListWriter::writeSkipData(int32_t level, IndexOutput *skipBuffer) { + // To efficiently store payloads in the posting lists we do not store the length of + // every payload. Instead we omit the length for a payload if the previous payload had + // the same length. + // However, in order to support skipping the payload length at every skip point must be known. + // So we use the same length encoding that we use for the posting lists for the skip data as well: + // Case 1: current field does not store payloads + // SkipDatum --> DocSkip, FreqSkip, ProxSkip + // DocSkip,FreqSkip,ProxSkip --> VInt + // DocSkip records the document number before every SkipInterval th document in TermFreqs. + // Document numbers are represented as differences from the previous value in the sequence. + // Case 2: current field stores payloads + // SkipDatum --> DocSkip, PayloadLength?, FreqSkip,ProxSkip + // DocSkip,FreqSkip,ProxSkip --> VInt + // PayloadLength --> VInt + // In this case DocSkip/2 is the difference between + // the current and the previous value. If DocSkip + // is odd, then a PayloadLength encoded as VInt follows, + // if DocSkip is even, then it is assumed that the + // current payload length equals the length at the previous + // skip point + if (curStorePayloads) { + int32_t delta = curDoc - lastSkipDoc[level]; + if (curPayloadLength == lastSkipPayloadLength[level]) { + // the current payload length equals the length at the previous skip point, + // so we don't store the length again + skipBuffer->writeVInt(delta * 2); + } else { + // the payload length is different from the previous one. We shift the DocSkip, + // set the lowest bit and store the current payload length as VInt. + skipBuffer->writeVInt(delta * 2 + 1); + skipBuffer->writeVInt(curPayloadLength); + lastSkipPayloadLength[level] = curPayloadLength; + } + } else { + // current field does not store payloads + skipBuffer->writeVInt(curDoc - lastSkipDoc[level]); + } + skipBuffer->writeVInt((int32_t) (curFreqPointer - lastSkipFreqPointer[level])); + if (curProxPointer != -1) { + skipBuffer->writeVInt((int32_t) (curProxPointer - lastSkipProxPointer[level])); + } + + lastSkipDoc[level] = curDoc; + //System.out.println("write doc at level " + level + ": " + curDoc); + + lastSkipFreqPointer[level] = curFreqPointer; + if (curProxPointer != -1) { + lastSkipProxPointer[level] = curProxPointer; + } +} + +DefaultSkipListWriter::DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, IndexOutput *freqOutput, IndexOutput *proxOutput) : MultiLevelSkipListWriter(skipInterval, numberOfSkipLevels, docCount) { + this->freqOutput = freqOutput; + this->proxOutput = proxOutput; + this->curDoc = this->curPayloadLength = 0; + this->curFreqPointer = 0; + + lastSkipDoc = _CL_NEWARRAY(int32_t, numberOfSkipLevels); + lastSkipPayloadLength = _CL_NEWARRAY(int32_t, numberOfSkipLevels); + lastSkipFreqPointer = _CL_NEWARRAY(int64_t, numberOfSkipLevels); + lastSkipProxPointer = _CL_NEWARRAY(int64_t, numberOfSkipLevels); +} +DefaultSkipListWriter::~DefaultSkipListWriter() { + _CLDELETE_ARRAY(lastSkipDoc); + _CLDELETE_ARRAY(lastSkipPayloadLength); + _CLDELETE_ARRAY(lastSkipFreqPointer); + _CLDELETE_ARRAY(lastSkipProxPointer); +} +CL_NS_END diff --git a/src/core/CLucene/index/Term.cpp b/src/core/CLucene/index/Term.cpp new file mode 100644 index 00000000000..0bf87f8dc38 --- /dev/null +++ b/src/core/CLucene/index/Term.cpp @@ -0,0 +1,450 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Term.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/stringUtil.h" + +CL_NS_USE(util) +CL_NS_DEF(index) + +template +STerm::STerm(){ + //Intern fld and assign it to field + _field = LUCENE_BLANK_STRING; + internF = false; + cachedHashCode = 0; + textLen = 0; + + _text = strDuplicate(LUCENE_BLANK_SSTRING()); + textLenBuf = 0; + textLen = 0; +} + +template +STerm::STerm(const TCHAR* fld, const T* txt, bool internField){ + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + _text = strDuplicate(LUCENE_BLANK_SSTRING()); + textLenBuf = 0; + + set(fld,txt,internField); +} + +template +STerm::STerm(const STerm* fieldTerm, const T* txt){ + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + _text = strDuplicate(LUCENE_BLANK_SSTRING()); + textLenBuf = 0; + + set(fieldTerm,txt); +} + +template +STerm::STerm(const TCHAR* fld, const T* txt){ + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + _text = strDuplicate(LUCENE_BLANK_SSTRING()); + textLenBuf = 0; + + set(fld,txt); +} + +template +STerm::~STerm(){ + if ( internF ) + CLStringIntern::unintern(_field); + _field = NULL; + //Deletetext if it is the owner + _CLDELETE_CARRAY( _text ); +} + +template +const TCHAR* STerm::field() const { + return _field; +} + +template +const T* STerm::text() const { + return _text; +} + +template +void STerm::set(const STerm* term, const T* txt){ + set(term->field(),txt,false); +} + +template +void STerm::set(const TCHAR* fld, const T* txt,const bool internField){ + CND_PRECONDITION(fld != NULL, "fld contains NULL"); + CND_PRECONDITION(txt != NULL, "txt contains NULL"); + + //save field for unintern later + const TCHAR* oldField = _field; + //bool oldInternF = internF; //Not used + cachedHashCode = 0; + + textLen = lenOfString(txt); + //if the term text buffer is bigger than what we have + if ( _text && textLen > textLenBuf){ + _CLDELETE_ARRAY( _text ); + textLenBuf = 0; + } + + if ( _text==NULL ){ + _text = strDuplicate(txt); + textLenBuf = textLen; + }else{ + //re-use the buffer + strCopy(_text, txt); + } + + //Set Term Field + if ( internField ) + _field = CLStringIntern::intern(fld); + else + _field = fld; + + //unintern old field after interning new one, + if ( internF ) + CLStringIntern::unintern(oldField); + internF = internField; + + CND_PRECONDITION(_tcscmp(fld, _field)==0,"field not equal"); +} + +template +bool STerm::equals(const STerm* other) const{ + if (other == this) + return true; + if (other == NULL) + return false; + + if ( cachedHashCode != 0 && other->cachedHashCode != 0 && other->cachedHashCode != cachedHashCode ) + return false; + + if (_field == other->_field) {// fields are interned + if (textLen == other->textLen) { + return (strCompare(_text, other->_text) == 0); + } + } else { + int32_t ret = strCompare(_field, other->_field); + if (ret == 0) { + if (textLen == other->textLen) { + return strCompare(_text, other->_text) == 0; + } + } + } + return false; +} + +template +size_t STerm::hashCode(){ + if ( cachedHashCode == 0 ) + cachedHashCode = Misc::thashCode(_field) + Misc::swhashCode(_text,textLen); + return cachedHashCode; +} + +template +size_t STerm::textLength() const { return textLen; } + +template +int32_t STerm::compareTo(const STerm* other) const { + if ( _field == other->_field ){ // fields are interned + //Compare text with text of other and return the result + return strCompare(_text,other->_text); + }else{ + int32_t ret = _tcscmp(_field,other->_field); + if ( ret == 0 ){ + return strCompare(_text,other->_text); + }else{ + return ret; + } + } +} + +template +int32_t STerm::hashedCompareTo(STerm* other) { + size_t hc1 = this->hashCode(); + size_t hc2 = other->hashCode(); + + if ( hc1 == hc2 ) + return compareTo(other); + else if ( hc1 > hc2 ) + return -1; + else + return 1; +} + +template <> +char* STerm::toString() const{ + return CL_NS(util)::Misc::ajoin( CL_NS(util)::Misc::_wideToChar(_field), ":", _text); +} + +template <> +TCHAR* STerm::toString() const{ + return CL_NS(util)::Misc::join( _field, _T(":"), _text); +} + +template class STerm; +template class STerm; + +Term::Term(){ + //Intern fld and assign it to field + _field = LUCENE_BLANK_STRING; + internF = false; + cachedHashCode = 0; + textLen = 0; + + //Duplicate txt and assign it to text + #ifdef LUCENE_TERM_TEXT_LENGTH + _text[0]=0; + #else + _text = STRDUP_TtoT(LUCENE_BLANK_STRING); + textLenBuf = 0; + #endif + textLen = 0; +} + +Term::Term(const TCHAR* fld, const TCHAR* txt, bool internField){ +//Func - Constructor. +// Constructs a Term with the given field and text. Field and text are not copied +// Field and text are deleted in destructor only if intern is false. +//Pre - fld != NULL and contains the name of the field +// txt != NULL and contains the value of the field +// internF is true or false and indicates if term Field is interned or not +// internT is true or false and indicates if term Text is interned or not +// canDelete defaults to true but can be false and indicates to the IGarbageCollector that the Term can be deleted when finalized +//Post - An instance of Term has been created.Field and txt have not been copied but assigned + + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + #ifdef LUCENE_TERM_TEXT_LENGTH + _text[0]=0; + #else + _text = STRDUP_TtoT(LUCENE_BLANK_STRING); + textLenBuf = 0; + #endif + + set(fld,txt,internField); +} + + +Term::Term(const Term* fieldTerm, const TCHAR* txt){ + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + #ifdef LUCENE_TERM_TEXT_LENGTH + _text[0]=0; + #else + _text = STRDUP_TtoT(LUCENE_BLANK_STRING); + textLenBuf = 0; + #endif + + set(fieldTerm,txt); +} + +Term::Term(const TCHAR* fld, const TCHAR* txt){ + _field = LUCENE_BLANK_STRING; + internF = false; + textLen = 0; + #ifdef LUCENE_TERM_TEXT_LENGTH + _text[0]=0; + #else + _text = STRDUP_TtoT(LUCENE_BLANK_STRING); + textLenBuf = 0; + #endif + + set(fld,txt); +} + +Term::~Term(){ +//Func - Destructor. +//Pre - true +//Post - The instance has been destroyed. field and text have been deleted if pre(intrn) is false + + //Unintern field + if ( internF ) + CLStringIntern::unintern(_field); + _field = NULL; + +#ifndef LUCENE_TERM_TEXT_LENGTH + //Deletetext if it is the owner + _CLDELETE_CARRAY( _text ); +#endif +} + +const TCHAR* Term::field() const { +//Func - Returns the field of this term, an interned string. The field indicates +// the part of a document which this term came from. +//Pre - true +//Post - field has been returned + + return _field; +} + +const TCHAR* Term::text() const { +//Func - Returns the text of this term. In the case of words, this is simply the +// text of the word. In the case of dates and other types, this is an +// encoding of the object as a string. +//Pre - true +//Post - text has been returned + + return _text; +} + + +void Term::set(const Term* term, const TCHAR* txt){ + set(term->field(),txt,false); +} + +void Term::set(const TCHAR* fld, const TCHAR* txt,const bool internField){ +//Func - Resets the field and text of a Term. +//Pre - fld != NULL and contains the name of the field +// txt != NULL and contains the value of the field +// internF is true or false +// internT is true or false +//Post - field and text of Term have been reset + + CND_PRECONDITION(fld != NULL, "fld contains NULL"); + CND_PRECONDITION(txt != NULL, "txt contains NULL"); + + //save field for unintern later + const TCHAR* oldField = _field; + //bool oldInternF = internF; //Not used + cachedHashCode = 0; + + textLen = _tcslen(txt); + + //Delete text if it is the owner +#ifdef LUCENE_TERM_TEXT_LENGTH + if ( textLen > LUCENE_TERM_TEXT_LENGTH ) + textLen = LUCENE_TERM_TEXT_LENGTH; + _tcsncpy(_text,txt,textLen+1); + _text[textLen]=0; +#else + + //if the term text buffer is bigger than what we have + if ( _text && textLen > textLenBuf){ + _CLDELETE_ARRAY( _text ); + textLenBuf = 0; + } + + if ( _text==NULL ){ + //duplicate the text + _text = stringDuplicate(txt); + textLenBuf = textLen; + }else{ + //re-use the buffer + _tcscpy(_text,txt); + } + +#endif + + //Set Term Field + if ( internField ) + _field = CLStringIntern::intern(fld); + else + _field = fld; + + //unintern old field after interning new one, + if ( internF ) + CLStringIntern::unintern(oldField); + internF = internField; + + CND_PRECONDITION(_tcscmp(fld, _field)==0,"field not equal"); +} + +/** Compares two terms, returning true iff they have the same + field and text. */ +bool Term::equals(const Term* other) const{ + if (other == this) + return true; + if (other == NULL) + return false; + + if ( cachedHashCode != 0 && other->cachedHashCode != 0 && other->cachedHashCode != cachedHashCode ) + return false; + + if (_field == other->_field) {// fields are interned + if (textLen == other->textLen) { + return (_tcscmp(_text, other->_text) == 0); + } + } else { + int32_t ret = _tcscmp(_field, other->_field); + if (ret == 0) { + if (textLen == other->textLen) { + return _tcscmp(_text, other->_text) == 0; + } + } + } + return false; +} + +size_t Term::hashCode(){ + if ( cachedHashCode == 0 ) + cachedHashCode = Misc::thashCode(_field) + Misc::thashCode(_text,textLen); + return cachedHashCode; +} + +size_t Term::textLength() const { return textLen; } + +int32_t Term::compareTo(const Term* other) const { +//Func - Compares two terms, to see if this term belongs before,is equal to or after +// after the argument term. +//Pre - other is a reference to another term +//Post - A negative integer is returned if this term belongs before the argument, +// zero is returned if this term is equal to the argument, and a positive integer +// if this term belongs after the argument. + + //Check ret to see if text needs to be compared + if ( _field == other->_field ){ // fields are interned + //Compare text with text of other and return the result + return _tcscmp(_text,other->_text); + }else{ + int32_t ret = _tcscmp(_field,other->_field); + if ( ret == 0 ){ + return _tcscmp(_text,other->_text); + }else{ + return ret; + } + } +} + +int32_t Term::hashedCompareTo(Term* other) { + size_t hc1 = this->hashCode(); + size_t hc2 = other->hashCode(); + + if ( hc1 == hc2 ) + return compareTo(other); + else if ( hc1 > hc2 ) + return -1; + else + return 1; +} + +TCHAR* Term::toString() const{ +//Func - Forms the contents of Field and term in some kind of tuple notation +// +//Pre - true +//Post - a string formatted as is returned if pre(field) is NULL and +// text is NULL the returned string will be formatted as <:> + + // Note: Should this representation ever change, make sure to update Query and Filter classes + // that may be using this format without calling toString (to save on memory allocations) + // For example: PrefixFilter::toString() + + return CL_NS(util)::Misc::join( _field, _T(":"), _text); +} + +CL_NS_END diff --git a/src/core/CLucene/index/Term.h b/src/core/CLucene/index/Term.h new file mode 100644 index 00000000000..7b0d0eca456 --- /dev/null +++ b/src/core/CLucene/index/Term.h @@ -0,0 +1,177 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_Term_ +#define _lucene_index_Term_ + +CL_NS_DEF(index) + +/** +A Term represents a word from text. This is the unit of search. It is +composed of two elements, the text of the word, as a string, and the name of +the field that the text occured in, an interned string. + +Note that terms may represent more than words from text fields, but also +things like dates, email addresses, urls, etc. + +IMPORTANT NOTE: +Term inherits from the template class LUCENE_REFBASE which tries to do +some garbage collection by counting the references an instance has. As a result +of this construction you MUST use _CLDECDELETE(obj) when you want to delete an +of Term! + +ABOUT intrn + +intrn indicates if field and text are interned or not. Interning of Strings is the process of +converting duplicated strings to shared ones. + +*/ +template +class CLUCENE_EXPORT STerm:LUCENE_REFBASE { +private: + size_t cachedHashCode; + const TCHAR* _field; + T* _text; + size_t textLenBuf; //a cache of text len, this allows for a preliminary comparison of text lengths + size_t textLen; //a cache of text len, this allows for a preliminary comparison of text lengths + bool internF; //Indicates if Term Field is interned(and therefore must be uninternd). +public: + STerm(const STerm* fieldTerm, const T* txt); + STerm(); + STerm(const TCHAR* fld, const T* txt, bool internField); + STerm(const TCHAR* fld, const T* txt); + ~STerm(); + + const TCHAR* field() const; ///Note that a null field or null text value results in undefined + * behavior for most Lucene APIs that accept a Term parameter. + */ + Term(const Term* fieldTerm, const TCHAR* txt); + + /** Constructs a blank term */ + Term(); + + /** Constructs a Term with the given field and text. + *

Note that a null field or null text value results in undefined + * behavior for most Lucene APIs that accept a Term parameter. + */ + Term(const TCHAR* fld, const TCHAR* txt, bool internField); + + /** + * Constructor. Constructs a Term with the given field and text. Field and text are not copied + * Field and text are deleted in destructor only if intern is false. + *

Note that a null field or null text value results in undefined + * behavior for most Lucene APIs that accept a Term parameter. + */ + Term(const TCHAR* fld, const TCHAR* txt); + + ///Destructor. + ~Term(); + + ///Returns the field of this term, an interned string. The field indicates + ///the part of a document which this term came from. + const TCHAR* field() const; /// + TCHAR* toString() const; + + size_t hashCode(); +}; + +class Term_UnorderedCompare:LUCENE_BASE, public CL_NS(util)::Compare::_base // +{ +public: + bool operator()( Term* t1, Term* t2 ) const{ + return ( t1->hashedCompareTo(t2) < 0 ); + } + size_t operator()( Term* t ) const{ + return t->hashCode(); + } +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/TermInfo.cpp b/src/core/CLucene/index/TermInfo.cpp new file mode 100644 index 00000000000..4eea2f63787 --- /dev/null +++ b/src/core/CLucene/index/TermInfo.cpp @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_TermInfo.h" + + +CL_NS_DEF(index) + +TermInfo::TermInfo(){ +//Func - Constructor +//Pre - true +//Post - Instance has been created + + docFreq = 0; + freqPointer = 0; + proxPointer = 0; + skipOffset = 0; +} + +TermInfo::~TermInfo(){ +//Func - Destructor. +//Pre - true +//Post - Instance has been destroyed +} + +TermInfo::TermInfo(const int32_t df, const int64_t fp, const int64_t pp){ +//Func - Constructor. +//Pre - df >= 0, fp >= 0 pp >= 0 +//Post - An instance has been created with FreqPointer = fp, proxPointer=pp and docFreq= df + + CND_PRECONDITION(df >= 0, "df contains negative number"); + CND_PRECONDITION(fp >= 0, "fp contains negative number"); + CND_PRECONDITION(pp >= 0, "pp contains negative number"); + + freqPointer = fp; + proxPointer = pp; + docFreq = df; + skipOffset = 0; +} + +TermInfo::TermInfo(const TermInfo* ti) { +//Func - Constructor. +// Initialises this instance by copying the values of another TermInfo ti +//Pre - ti is a reference to another TermInfo +// ti->docFreq >= 0 +// ti->freqPointer >= 0 +// ti->proxPointer >= 0 +//Post - Values of ti have been copied to the values of this Instance. + + CND_PRECONDITION(ti->docFreq >= 0, "ti->docFreq contains negative number"); + CND_PRECONDITION(ti->freqPointer >= 0, "ti->freqPointer contains negative number"); + CND_PRECONDITION(ti->proxPointer >= 0, "ti->proxPointer contains negative number"); + + docFreq = ti->docFreq; + freqPointer = ti->freqPointer; + proxPointer = ti->proxPointer; + skipOffset = ti->skipOffset; +} + +void TermInfo::set(const int32_t df, const int64_t fp, const int64_t pp, int32_t so) { +//Func - Sets a new document frequency, a new freqPointer and a new proxPointer +//Pre - df >= 0, fp >= 0 pp >= 0 +//Post - The new document frequency, a new freqPointer and a new proxPointer +// have been set + + CND_PRECONDITION(df >= 0, "df contains negative number"); + CND_PRECONDITION(fp >= 0, "fp contains negative number"); + CND_PRECONDITION(pp >= 0, "pp contains negative number"); + + docFreq = df; + freqPointer = fp; + proxPointer = pp; + skipOffset = so; +} + +void TermInfo::set(const TermInfo* ti) { +//Func - Sets a new document frequency, a new freqPointer and a new proxPointer +// by copying these values from another instance of TermInfo +//Pre - ti is a reference to another TermInfo +// ti->docFreq >= 0 +// ti->freqPointer >= 0 +// ti->proxPointer >= 0 +//Post - Values of ti have been copied to the values of this Instance. + + CND_PRECONDITION(ti->docFreq >= 0, "ti->docFreq contains negative number"); + CND_PRECONDITION(ti->freqPointer >= 0, "ti->freqPointer contains negative number"); + CND_PRECONDITION(ti->proxPointer >= 0, "ti->proxPointer contains negative number"); + + docFreq = ti->docFreq; + freqPointer = ti->freqPointer; + proxPointer = ti->proxPointer; + skipOffset = ti->skipOffset; +} +CL_NS_END diff --git a/src/core/CLucene/index/TermInfosReader.cpp b/src/core/CLucene/index/TermInfosReader.cpp new file mode 100644 index 00000000000..b28bb7eec94 --- /dev/null +++ b/src/core/CLucene/index/TermInfosReader.cpp @@ -0,0 +1,477 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "Term.h" +#include "Terms.h" +#include "CLucene/util/Misc.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" + +#include "_TermInfo.h" +#include "_FieldInfos.h" +#include "_SegmentTermEnum.h" +#include "_FieldInfos.h" +#include "_TermInfo.h" +#include "_TermInfosWriter.h" +#include "_TermInfosReader.h" + +CL_NS_USE(store) +CL_NS_USE(util) +CL_NS_DEF(index) + + + TermInfosReader::TermInfosReader(Directory* dir, const char* seg, FieldInfos* fis, const int32_t readBufferSize): + directory (dir),fieldInfos (fis), indexTerms(NULL), indexInfos(NULL), indexPointers(NULL), indexDivisor(1) + { + //Func - Constructor. + // Reads the TermInfos file (.tis) and eventually the Term Info Index file (.tii) + //Pre - dir is a reference to a valid Directory + // Fis contains a valid reference to an FieldInfos instance + // seg != NULL and contains the name of the segment + //Post - An instance has been created and the index named seg has been read. (Remember + // a segment is nothing more then an independently readable index) + + CND_PRECONDITION(seg != NULL, "seg is NULL"); + + //Initialize the name of the segment + segment = seg; + + //Create a filname fo a Term Info File + string tisFile = Misc::segmentname(segment,".tis"); + string tiiFile = Misc::segmentname(segment,".tii"); + bool success = false; + origEnum = indexEnum = NULL; + _size = indexTermsLength = totalIndexInterval = 0; + indexIsRead = false; + + try { + //Create an SegmentTermEnum for storing all the terms read of the segment + origEnum = _CLNEW SegmentTermEnum( directory->openInput( tisFile.c_str(), readBufferSize ), fieldInfos, false); + _size = origEnum->size; + totalIndexInterval = origEnum->indexInterval; + indexEnum = _CLNEW SegmentTermEnum( directory->openInput( tiiFile.c_str(), readBufferSize ), fieldInfos, true); + + //Check if enumerator points to a valid instance + CND_CONDITION(origEnum != NULL, "No memory could be allocated for orig enumerator"); + CND_CONDITION(indexEnum != NULL, "No memory could be allocated for index enumerator"); + + //call ensureIndexIsRead to load data to memory right now + ensureIndexIsRead(); + + success = true; + } _CLFINALLY({ + // With lock-less commits, it's entirely possible (and + // fine) to hit a FileNotFound exception above. In + // this case, we want to explicitly close any subset + // of things that were opened so that we don't have to + // wait for a GC to do so. + if (!success) { + close(); + } + }); + + } + + TermInfosReader::~TermInfosReader(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + //Close the TermInfosReader to be absolutly sure that enumerator has been closed + //and the arrays indexTerms, indexPointers and indexInfos and their elements + //have been destroyed + close(); + } + int32_t TermInfosReader::getSkipInterval() const { + return origEnum->skipInterval; + } + + int32_t TermInfosReader::getMaxSkipLevels() const { + return origEnum->maxSkipLevels; + } + + void TermInfosReader::setIndexDivisor(const int32_t _indexDivisor) { + if (indexDivisor < 1) + _CLTHROWA(CL_ERR_IllegalArgument, "indexDivisor must be > 0"); + + if (indexTerms != NULL) + _CLTHROWA(CL_ERR_IllegalArgument, "index terms are already loaded"); + + this->indexDivisor = _indexDivisor; + totalIndexInterval = origEnum->indexInterval * _indexDivisor; + } + + int32_t TermInfosReader::getIndexDivisor() const { return indexDivisor; } + void TermInfosReader::close() { + + //Check if indexTerms and indexInfos exist + if (indexTerms && indexInfos){ + //Iterate through arrays indexTerms and indexPointer to + //destroy their elements +#ifdef _DEBUG + for ( int32_t i=0; iclose(); + + //Get a pointer to IndexInput used by the enumeration but + //instantiated in the constructor by directory.open( tisFile ) + IndexInput *is = origEnum->input; + + //Delete the enumuration enumerator + _CLDELETE(origEnum); + + //Delete the IndexInput + _CLDELETE(is); + } + + if (indexEnum != NULL){ + indexEnum->close(); + + //Get a pointer to IndexInput used by the enumeration but + //instantiated in the constructor by directory.open( tiiFile ) + IndexInput *is = indexEnum->input; + + //Delete the enumuration enumerator + _CLDELETE(indexEnum); + indexEnum = NULL; + + //Delete the IndexInput + _CLDELETE(is); + } + enumerators.setNull(); + } + + int64_t TermInfosReader::size() const{ + //Func - Return the size of the enumeration of TermInfos + //Pre - true + //Post - size has been returened + + return _size; + } + + + Term* TermInfosReader::get(const int32_t position) { + //Func - Returns the nth term in the set + //Pre - position > = 0 + //Post - The n-th term in the set has been returned + + //Check if the size is 0 because then there are no terms + if (_size == 0) + return NULL; + + SegmentTermEnum* enumerator = getEnum(); + + if ( + enumerator != NULL //an enumeration exists + && enumerator->term(false) != NULL // term is at or past current + && position >= enumerator->position + && position < (enumerator->position + totalIndexInterval) + ) + { + return scanEnum(position); // can avoid seek + } + + //random-access: must seek + seekEnum(position / totalIndexInterval); + + //Get the Term at position + return scanEnum(position); + } + + SegmentTermEnum* TermInfosReader::getEnum(){ + SegmentTermEnum* termEnum = enumerators.get(); + if (termEnum == NULL){ + termEnum = terms(); + enumerators.set(termEnum); + } + return termEnum; + } + + TermInfo* TermInfosReader::get(const Term* term){ + //Func - Returns a TermInfo for a term + //Pre - term holds a valid reference to term + //Post - if term can be found its TermInfo has been returned otherwise NULL + + //If the size of the enumeration is 0 then no Terms have been read + if (_size == 0) + return NULL; + + ensureIndexIsRead(); + + // optimize sequential access: first try scanning cached enum w/o seeking + SegmentTermEnum* enumerator = getEnum(); + + // optimize sequential access: first try scanning cached enumerator w/o seeking + if ( + //the current term of the enumeration enumerator is not at the end AND + enumerator->term(false) != NULL && + ( + //there exists a previous current called prev and term is positioned after this prev OR + ( enumerator->prev != NULL && term->compareTo(enumerator->prev) > 0) || + //term is positioned at the same position as the current of enumerator or at a higher position + term->compareTo(enumerator->term(false)) >= 0 ) + ) + { + + //Calculate the offset for the position + int32_t _enumOffset = (int32_t)(enumerator->position/totalIndexInterval)+1; + + // but before end of block + if ( + //the length of indexTerms (the number of terms in enumerator) equals + //_enum_offset OR + indexTermsLength == _enumOffset || + //term is positioned in front of term found at _enumOffset in indexTerms + term->compareTo(&indexTerms[_enumOffset]) < 0){ + + //no need to seek, retrieve the TermInfo for term + return scanEnum(term); + } + } + + //Reposition current term in the enumeration + seekEnum(getIndexOffset(term)); + //Return the TermInfo for term + return scanEnum(term); + } + + + int64_t TermInfosReader::getPosition(const Term* term) { + //Func - Returns the position of a Term in the set + //Pre - term holds a valid reference to a Term + // enumerator != NULL + //Post - If term was found then its position is returned otherwise -1 + + //if the enumeration is empty then return -1 + if (_size == 0) + return -1; + + ensureIndexIsRead(); + + //Retrieve the indexOffset for term + int32_t indexOffset = getIndexOffset(term); + seekEnum(indexOffset); + + SegmentTermEnum* enumerator = getEnum(); + + while(term->compareTo(enumerator->term(false)) > 0 && enumerator->next()) {} + + if ( term->equals(enumerator->term(false)) ){ + return enumerator->position; + }else + return -1; + } + + SegmentTermEnum* TermInfosReader::terms(const Term* term) { + //Func - Returns an enumeration of terms starting at or after the named term. + // If term is null then enumerator is set to the beginning + //Pre - term holds a valid reference to a Term + // enumerator != NULL + //Post - An enumeration of terms starting at or after the named term has been returned + + SegmentTermEnum* enumerator = NULL; + if ( term != NULL ){ + //Seek enumerator to term; delete the new TermInfo that's returned. + TermInfo* ti = get(term); + _CLLDELETE(ti); + enumerator = getEnum(); + }else + enumerator = origEnum; + + //Clone the entire enumeration + SegmentTermEnum* cln = enumerator->clone(); + + //Check if cln points to a valid instance + CND_CONDITION(cln != NULL,"cln is NULL"); + + return cln; + } + + + void TermInfosReader::ensureIndexIsRead() { + //Func - Reads the term info index file or .tti file. + // This file contains every IndexInterval-th entry from the .tis file, + // along with its location in the "tis" file. This is designed to be read entirely + // into memory and used to provide random access to the "tis" file. + //Pre - indexTerms = NULL + // indexInfos = NULL + // indexPointers = NULL + //Post - The term info index file has been read into memory + + SCOPED_LOCK_MUTEX(THIS_LOCK) + + if (indexIsRead) + return; + + //https://jira.qianxin-inc.cn/browse/XHBUG-2921 + //https://jira.qianxin-inc.cn/browse/XHBUG-3053 + if (indexEnum == NULL) + _CLTHROWA(CL_ERR_NullPointer, "indexEnum is NULL"); + + try { + indexTermsLength = (size_t)indexEnum->size; + + //Instantiate an block of Term's,so that each one doesn't have to be new'd + indexTerms = new Term[indexTermsLength]; + CND_CONDITION(indexTerms != NULL,"No memory could be allocated for indexTerms");//Check if is indexTerms is a valid array + + //Instantiate an big block of TermInfo's, so that each one doesn't have to be new'd + indexInfos = _CL_NEWARRAY(TermInfo,indexTermsLength); + CND_CONDITION(indexInfos != NULL,"No memory could be allocated for indexInfos"); //Check if is indexInfos is a valid array + + //Instantiate an array indexPointers that contains pointers to the term info index file + indexPointers = _CL_NEWARRAY(int64_t,indexTermsLength); + CND_CONDITION(indexPointers != NULL,"No memory could be allocated for indexPointers");//Check if is indexPointers is a valid array + + //Iterate through the terms of indexEnum + for (int32_t i = 0; indexEnum->next(); ++i){ + indexTerms[i].set(indexEnum->term(false),indexEnum->term(false)->text()); + indexEnum->getTermInfo(&indexInfos[i]); + indexPointers[i] = indexEnum->indexPointer; + + for (int32_t j = 1; j < indexDivisor; j++) + if (!indexEnum->next()) + break; + } + indexIsRead = true; + }_CLFINALLY( + indexEnum->close(); + //Close and delete the IndexInput is. The close is done by the destructor. + _CLDELETE( indexEnum->input ); + _CLDELETE( indexEnum ); + indexEnum = NULL; + ); + } + + + int32_t TermInfosReader::getIndexOffset(const Term* term){ + //Func - Returns the offset of the greatest index entry which is less than or equal to term. + //Pre - term holds a reference to a valid term + // indexTerms != NULL + //Post - The new offset has been returned + + //Check if is indexTerms is a valid array + CND_PRECONDITION(indexTerms != NULL,"indexTerms is NULL"); + + int32_t lo = 0; + int32_t hi = indexTermsLength - 1; + int32_t mid; + int32_t delta; + + while (hi >= lo) { + //Start in the middle betwee hi and lo + mid = (lo + hi) >> 1; + + //Check if is indexTerms[mid] is a valid instance of Term + CND_PRECONDITION(&indexTerms[mid] != NULL,"indexTerms[mid] is NULL"); + CND_PRECONDITION(mid < indexTermsLength,"mid >= indexTermsLength"); + + //Determine if term is before mid or after mid + delta = term->compareTo(&indexTerms[mid]); + if (delta < 0){ + //Calculate the new hi + hi = mid - 1; + }else if (delta > 0){ + //Calculate the new lo + lo = mid + 1; + }else{ + //term has been found so return its position + return mid; + } + } + // the new starting offset + return hi; + } + + void TermInfosReader::seekEnum(const int32_t indexOffset) { + //Func - Reposition the current Term and TermInfo to indexOffset + //Pre - indexOffset >= 0 + // indexTerms != NULL + // indexInfos != NULL + // indexPointers != NULL + //Post - The current Term and Terminfo have been repositioned to indexOffset + + CND_PRECONDITION(indexOffset >= 0, "indexOffset contains a negative number"); + CND_PRECONDITION(indexTerms != NULL, "indexTerms is NULL"); + CND_PRECONDITION(indexInfos != NULL, "indexInfos is NULL"); + CND_PRECONDITION(indexPointers != NULL, "indexPointers is NULL"); + + SegmentTermEnum* enumerator = getEnum(); + enumerator->seek( + indexPointers[indexOffset], + (indexOffset * totalIndexInterval) - 1, + &indexTerms[indexOffset], + &indexInfos[indexOffset] + ); + } + + + TermInfo* TermInfosReader::scanEnum(const Term* term) { + //Func - Scans the Enumeration of terms for term and returns the corresponding TermInfo instance if found. + // The search is started from the current term. + //Pre - term contains a valid reference to a Term + // enumerator != NULL + //Post - if term has been found the corresponding TermInfo has been returned otherwise NULL + // has been returned + + SegmentTermEnum* enumerator = getEnum(); + enumerator->scanTo(term); + + //Check if the at the position the Term term can be found + if (enumerator->term(false) != NULL && term->equals(enumerator->term(false)) ){ + //Return the TermInfo instance about term + return enumerator->getTermInfo(); + }else{ + //term was not found so no TermInfo can be returned + return NULL; + } + } + + Term* TermInfosReader::scanEnum(const int32_t position) { + //Func - Scans the enumeration to the requested position and returns the + // Term located at that position + //Pre - position > = 0 + // enumerator != NULL + //Post - The Term at the requested position has been returned + + SegmentTermEnum* enumerator = getEnum(); + + //As long the position of the enumeration enumerator is smaller than the requested one + while(enumerator->position < position){ + //Move the current of enumerator to the next + if (!enumerator->next()){ + //If there is no next it means that the requested position was to big + return NULL; + } + } + + //Return the Term a the requested position + return enumerator->term(); + } + +CL_NS_END diff --git a/src/core/CLucene/index/TermInfosWriter.cpp b/src/core/CLucene/index/TermInfosWriter.cpp new file mode 100644 index 00000000000..6b9060ecfed --- /dev/null +++ b/src/core/CLucene/index/TermInfosWriter.cpp @@ -0,0 +1,418 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/stringUtil.h" +#include "Term.h" +#include "_TermInfo.h" +#include "IndexWriter.h" +#include "_FieldInfos.h" +#include "_TermInfosWriter.h" +#include + +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_DEF(index) + +template +STermInfosWriter::STermInfosWriter(Directory *directory, const char *segment, FieldInfos *fis, int32_t interval) : fieldInfos(fis) { + CND_PRECONDITION(segment != NULL, "segment is NULL"); + //Initialize instance + initialise(directory, segment, interval, false); + + other = _CLNEW STermInfosWriter(directory, segment, fieldInfos, interval, true); + + CND_CONDITION(other != NULL, "other is NULL"); + + other->other = this; +} + +template +STermInfosWriter::STermInfosWriter(Directory *directory, const char *segment, FieldInfos *fis, int32_t interval, bool isIndex) : fieldInfos(fis) { + CND_PRECONDITION(segment != NULL, "segment is NULL"); + initialise(directory, segment, interval, isIndex); +} + +template +void STermInfosWriter::initialise(Directory *directory, const char *segment, int32_t interval, bool IsIndex) { + maxSkipLevels = 10; + lastTermTextLength = 0; + lastFieldNumber = -1; + + lastTi = _CLNEW TermInfo(); + + CND_CONDITION(lastTi != NULL, "Could not allocate memory for lastTi"); + + lastIndexPointer = 0; + size = 0; + isIndex = IsIndex; + indexInterval = interval; + skipInterval = TermInfosWriter::DEFAULT_TERMDOCS_SKIP_INTERVAL; + + output = directory->createOutput(Misc::segmentname(segment, (isIndex ? ".tii" : ".tis")).c_str()); + + output->writeInt(FORMAT); // write format + output->writeLong(-1); // leave space for size, to compatible with former version. + output->writeInt(indexInterval);// write indexInterval + output->writeInt(skipInterval); // write skipInterval + + output->writeInt(maxSkipLevels);// write maxSkipLevels + + //Set other to NULL by Default + other = NULL; +} + +template +STermInfosWriter::~STermInfosWriter() { + close(); +} + +template +void STermInfosWriter::add(STerm *term, TermInfo *ti) { + const size_t length = term->textLength(); + if (termTextBuffer.values == NULL || termTextBuffer.length < length) { + termTextBuffer.resize((int32_t) (length * 1.25)); + } + strnCopy(termTextBuffer.values, term->text(), length); + + add(fieldInfos->fieldNumber(term->field()), termTextBuffer.values, length, ti); +} + +template +int32_t STermInfosWriter::compareToLastTerm(int32_t fieldNumber, const T *termText, int32_t length) { + int32_t pos = 0; + + if (lastFieldNumber != fieldNumber) { + const int32_t cmp = _tcscmp(fieldInfos->fieldName(lastFieldNumber), fieldInfos->fieldName(fieldNumber)); + if (cmp != 0 || lastFieldNumber != -1) + return cmp; + } + + while (pos < length && pos < lastTermTextLength) { + const T c1 = lastTermText[pos]; + const T c2 = termText[pos]; + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + pos++; + } + + if (pos < lastTermTextLength) + // Last term was longer + return 1; + else if (pos < length) + // Last term was shorter + return -1; + else + return 0; +} + +template +void STermInfosWriter::add(int32_t fieldNumber, const T *termText, int32_t termTextLength, const TermInfo *ti) { + + CND_PRECONDITION(ti->freqPointer >= lastTi->freqPointer, ("freqPointer out of order (" + Misc::toString(ti->freqPointer) + " < " + Misc::toString(lastTi->freqPointer) + ")").c_str()); + CND_PRECONDITION(ti->proxPointer >= lastTi->proxPointer, ("proxPointer out of order (" + Misc::toString(ti->proxPointer) + " < " + Misc::toString(lastTi->proxPointer) + ")").c_str()); + + if (!isIndex && size % indexInterval == 0) { + //add an index term + other->add(lastFieldNumber, lastTermText.values, lastTermTextLength, lastTi);// add an index term + } + + //write term + writeTerm(fieldNumber, termText, termTextLength); + // write doc freq + output->writeVInt(ti->docFreq); + //write pointers + output->writeVLong(ti->freqPointer - lastTi->freqPointer); + output->writeVLong(ti->proxPointer - lastTi->proxPointer); + if (ti->docFreq >= skipInterval) { + output->writeVInt(ti->skipOffset); + } + + if (isIndex) { + output->writeVLong(other->output->getFilePointer() - lastIndexPointer); + lastIndexPointer = other->output->getFilePointer();// write pointer + } + if (lastTermText.length < termTextLength || lastTermText.length == 0) { + lastTermText.resize((int32_t) cl_max(10.0, termTextLength * 1.25)); + } + if (termText != nullptr) + strnCopy(lastTermText.values, termText, termTextLength); + else + lastTermText.values[0] = 0; + + lastTermTextLength = termTextLength; + lastFieldNumber = fieldNumber; + + lastTi->set(ti); + size++; +} + +template +void STermInfosWriter::close() { + if (output) { + //write size at start + //output->seek(4); // write size after format + output->writeLong(size);// do not seek now, directly write size at file footer + output->close(); + _CLDELETE(output); + + if (!isIndex) { + if (other) { + other->close(); + _CLDELETE(other); + } + } + _CLDELETE(lastTi); + } +} + +template +void STermInfosWriter::writeTerm(int32_t fieldNumber, const T *termText, int32_t termTextLength) { + int32_t start = 0; + const int32_t limit = termTextLength < lastTermTextLength ? termTextLength : lastTermTextLength; + while (start < limit) { + if (termText[start] != lastTermText.values[start]) + break; + start++; + } + + int32_t length = termTextLength - start; + + output->writeVInt(start); // write shared prefix length + output->writeVInt(length); // write delta length + output->writeSChars(termText + start, length);// write delta chars + output->writeVInt(fieldNumber); // write field num +} + +template class STermInfosWriter; +template class STermInfosWriter; + +TermInfosWriter::TermInfosWriter(Directory *directory, const char *segment, FieldInfos *fis, int32_t interval) : fieldInfos(fis) { + //Func - Constructor + //Pre - directory contains a valid reference to a Directory + // segment != NULL + // fis contains a valid reference to a reference FieldInfos + //Post - The instance has been created + + CND_PRECONDITION(segment != NULL, "segment is NULL"); + //Initialize instance + initialise(directory, segment, interval, false); + + other = _CLNEW TermInfosWriter(directory, segment, fieldInfos, interval, true); + + CND_CONDITION(other != NULL, "other is NULL"); + + other->other = this; +} + +TermInfosWriter::TermInfosWriter(Directory *directory, const char *segment, FieldInfos *fis, int32_t interval, bool isIndex) : fieldInfos(fis) { + //Func - Constructor + //Pre - directory contains a valid reference to a Directory + // segment != NULL + // fis contains a valid reference to a reference FieldInfos + // isIndex is true or false + //Post - The instance has been created + + CND_PRECONDITION(segment != NULL, "segment is NULL"); + initialise(directory, segment, interval, isIndex); +} + +void TermInfosWriter::initialise(Directory *directory, const char *segment, int32_t interval, bool IsIndex) { + //Func - Helps constructors to initialize Instance + //Pre - directory contains a valid reference to a Directory + // segment != NULL + // fis contains a valid reference to a reference FieldInfos + //Post - The instance has been initialized + + + maxSkipLevels = 10; + lastTermTextLength = 0; + lastFieldNumber = -1; + + lastTi = _CLNEW TermInfo(); + + CND_CONDITION(lastTi != NULL, "Could not allocate memory for lastTi"); + + lastIndexPointer = 0; + size = 0; + isIndex = IsIndex; + indexInterval = interval; + skipInterval = TermInfosWriter::DEFAULT_TERMDOCS_SKIP_INTERVAL; + + output = directory->createOutput(Misc::segmentname(segment, (isIndex ? ".tii" : ".tis")).c_str()); + + output->writeInt(FORMAT); // write format + output->writeLong(-1); // leave space for size, to compatible with former version. + output->writeInt(indexInterval);// write indexInterval + output->writeInt(skipInterval); // write skipInterval + + output->writeInt(maxSkipLevels);// write maxSkipLevels + + //Set other to NULL by Default + other = NULL; +} + +TermInfosWriter::~TermInfosWriter() { + //Func - Destructor + //Pre - true + //Post - de instance has been destroyed + + close(); +} + +void TermInfosWriter::add(Term *term, TermInfo *ti) { + const size_t length = term->textLength(); + if (termTextBuffer.values == NULL || termTextBuffer.length < length) { + termTextBuffer.resize((int32_t) (length * 1.25)); + } + _tcsncpy(termTextBuffer.values, term->text(), length); + + add(fieldInfos->fieldNumber(term->field()), termTextBuffer.values, length, ti); +} + +// Currently used only by assert statement +int32_t TermInfosWriter::compareToLastTerm(int32_t fieldNumber, const TCHAR *termText, int32_t length) { + int32_t pos = 0; + + if (lastFieldNumber != fieldNumber) { + const int32_t cmp = _tcscmp(fieldInfos->fieldName(lastFieldNumber), fieldInfos->fieldName(fieldNumber)); + // If there is a field named "" (empty string) then we + // will get 0 on this comparison, yet, it's "OK". But + // it's not OK if two different field numbers map to + // the same name. + if (cmp != 0 || lastFieldNumber != -1) + return cmp; + } + + //TODO: is this just a _tcsncmp??? + while (pos < length && pos < lastTermTextLength) { + const TCHAR c1 = lastTermText[pos]; + const TCHAR c2 = termText[pos]; + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + pos++; + } + + if (pos < lastTermTextLength) + // Last term was longer + return 1; + else if (pos < length) + // Last term was shorter + return -1; + else + return 0; +} + +void TermInfosWriter::add(int32_t fieldNumber, const TCHAR *termText, int32_t termTextLength, const TermInfo *ti) { + //Func - Writes a Term and TermInfo to the outputstream + //Pre - Term must be lexicographically greater than all previous Terms added. + // Pointers of TermInfo ti (freqPointer and proxPointer) must be positive and greater than all previous. + +// TODO: This is a hack. If _ASCII is defined, Misc::toString(const TCHAR*, int) will cause linking errors, +// at least on VS. Needs a prettier fix no doubt... ISH 2009-11-08 +#ifdef _ASCII + assert(compareToLastTerm(fieldNumber, termText, termTextLength) < 0 || + (isIndex && termTextLength == 0 && lastTermTextLength == 0)); +#else + CND_PRECONDITION(compareToLastTerm(fieldNumber, termText, termTextLength) < 0 || + (isIndex && termTextLength == 0 && lastTermTextLength == 0), + (string("Terms are out of order: field=") + Misc::toString(fieldInfos->fieldName(fieldNumber)) + + " (number " + Misc::toString(fieldNumber) + ")" + + " lastField=" + Misc::toString(fieldInfos->fieldName(lastFieldNumber)) + + " (number " + Misc::toString(lastFieldNumber) + ")" + + " text=" + Misc::toString(termText, termTextLength) + + " lastText=" + Misc::toString(lastTermText.values, lastTermTextLength)) + .c_str()); +#endif + + CND_PRECONDITION(ti->freqPointer >= lastTi->freqPointer, ("freqPointer out of order (" + Misc::toString(ti->freqPointer) + " < " + Misc::toString(lastTi->freqPointer) + ")").c_str()); + CND_PRECONDITION(ti->proxPointer >= lastTi->proxPointer, ("proxPointer out of order (" + Misc::toString(ti->proxPointer) + " < " + Misc::toString(lastTi->proxPointer) + ")").c_str()); + + if (!isIndex && size % indexInterval == 0) { + //add an index term + other->add(lastFieldNumber, lastTermText.values, lastTermTextLength, lastTi);// add an index term + } + + //write term + writeTerm(fieldNumber, termText, termTextLength); + // write doc freq + output->writeVInt(ti->docFreq); + //write pointers + output->writeVLong(ti->freqPointer - lastTi->freqPointer); + output->writeVLong(ti->proxPointer - lastTi->proxPointer); + if (ti->docFreq >= skipInterval) { + output->writeVInt(ti->skipOffset); + } + + if (isIndex) { + output->writeVLong(other->output->getFilePointer() - lastIndexPointer); + lastIndexPointer = other->output->getFilePointer();// write pointer + } + if (lastTermText.length < termTextLength || lastTermText.length == 0) { + lastTermText.resize((int32_t) cl_max(10.0, termTextLength * 1.25)); + } + if (termText != NULL) + _tcsncpy(lastTermText.values, termText, termTextLength); + else + lastTermText.values[0] = 0; + + lastTermTextLength = termTextLength; + lastFieldNumber = fieldNumber; + + lastTi->set(ti); + size++; +} + +void TermInfosWriter::close() { + //Func - Closes the TermInfosWriter + //Pre - true + //Post - The TermInfosWriter has been closed + + if (output) { + //write size at start + //output->seek(4); // write size after format + output->writeLong(size);// do not seek now, directly write size at file footer + output->close(); + _CLDELETE(output); + + if (!isIndex) { + if (other) { + other->close(); + _CLDELETE(other); + } + } + _CLDELETE(lastTi); + } +} + +void TermInfosWriter::writeTerm(int32_t fieldNumber, const TCHAR *termText, int32_t termTextLength) { + + // Compute prefix in common with last term: + int32_t start = 0; + const int32_t limit = termTextLength < lastTermTextLength ? termTextLength : lastTermTextLength; + while (start < limit) { + if (termText[start] != lastTermText.values[start]) + break; + start++; + } + + int32_t length = termTextLength - start; + + output->writeVInt(start); // write shared prefix length + output->writeVInt(length); // write delta length + output->writeChars(termText + start, length);// write delta chars + output->writeVInt(fieldNumber); // write field num +} + + +CL_NS_END diff --git a/src/core/CLucene/index/TermVector.h b/src/core/CLucene/index/TermVector.h new file mode 100644 index 00000000000..9b843c310a8 --- /dev/null +++ b/src/core/CLucene/index/TermVector.h @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_termvector_h +#define _lucene_index_termvector_h + + +//#include "FieldInfos.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +class TermPositionVector; + + +/** Provides access to stored term vector of + * a document field. The vector consists of the name of the field, an array of the terms tha occur in the field of the + * {@link org.apache.lucene.document.Document} and a parallel array of frequencies. Thus, getTermFrequencies()[5] corresponds with the + * frequency of getTerms()[5], assuming there are at least 5 terms in the Document. + */ +class CLUCENE_EXPORT TermFreqVector:LUCENE_BASE { +public: + virtual ~TermFreqVector(){ + } + + /** + * The Field name. + * @return The name of the field this vector is associated with. + * + */ + virtual const TCHAR* getField() = 0; + + /** + * @return The number of terms in the term vector. + */ + virtual int32_t size() = 0; + + /** + * @return An Array of term texts in ascending order. + */ + virtual const CL_NS(util)::ArrayBase* getTerms() = 0; + + + /** Array of term frequencies. Locations of the array correspond one to one + * to the terms in the array obtained from getTerms + * method. Each location in the array contains the number of times this + * term occurs in the document or the document field. + * + * The size of the returned array is size() + * @memory Returning a pointer to internal data. Do not delete. + */ + virtual const CL_NS(util)::ArrayBase* getTermFrequencies() = 0; + + + /** Return an index in the term numbers array returned from + * getTerms at which the term with the specified + * term appears. If this term does not appear in the array, + * return -1. + */ + virtual int32_t indexOf(const TCHAR* term) = 0; + + /** Just like indexOf(int32_t) but searches for a number of terms + * at the same time. Returns an array that has the same size as the number + * of terms searched for, each slot containing the result of searching for + * that term number. + * + * @param terms array containing terms to look for + * @param start index in the array where the list of terms starts + * @param len the number of terms in the list + */ + virtual CL_NS(util)::ArrayBase* indexesOf(const CL_NS(util)::ArrayBase& terms, const int32_t start, const int32_t len) = 0; + + /** Solve the diamond inheritence problem by providing a reinterpret function. + * No dynamic casting is required and no RTTI data is needed to do this + */ + virtual TermPositionVector* __asTermPositionVector()=0; +}; + + +/** +* The TermVectorOffsetInfo class holds information pertaining to a Term in a {@link TermPositionVector}'s +* offset information. This offset information is the character offset as set during the Analysis phase (and thus may not be the actual offset in the +* original content). +*/ +struct CLUCENE_EXPORT TermVectorOffsetInfo { +private: + int32_t startOffset; + int32_t endOffset; +public: // TODO: Remove after TermVectorWriter has been ported; + TermVectorOffsetInfo(); + ~TermVectorOffsetInfo(); + TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset); + + /** + * The accessor for the ending offset for the term + * @return The offset + */ + int32_t getEndOffset() const; + void setEndOffset(const int32_t _endOffset); + + /** + * The accessor for the starting offset of the term. + * + * @return The offset + */ + int32_t getStartOffset() const; + void setStartOffset(const int32_t _startOffset); + + /** + * Two TermVectorOffsetInfos are equals if both the start and end offsets are the same + * @param o The comparison Object + * @return true if both {@link #getStartOffset()} and {@link #getEndOffset()} are the same for both objects. + */ + bool equals(TermVectorOffsetInfo* o); + size_t hashCode() const; +}; + + +/** +* Convenience declaration when creating a {@link org.apache.lucene.index.TermPositionVector} that stores only position information. +*/ +extern CL_NS(util)::ObjectArray* TermVectorOffsetInfo_EMPTY_OFFSET_INFO; + +/** Extends TermFreqVector to provide additional information about + * positions in which each of the terms is found. A TermPositionVector not necessarily + * contains both positions and offsets, but at least one of these arrays exists. + */ +class CLUCENE_EXPORT TermPositionVector: public virtual TermFreqVector { +public: + + /** Returns an array of positions in which the term is found. + * Terms are identified by the index at which its number appears in the + * term String array obtained from the indexOf method. + * May return null if positions have not been stored. + */ + virtual const CL_NS(util)::ArrayBase* getTermPositions(const size_t index) = 0; + + /** + * Returns an array of TermVectorOffsetInfo in which the term is found. + * May return null if offsets have not been stored. + * + * @see org.apache.lucene.analysis.Token + * + * @param index The position in the array to get the offsets from + * @return An array of TermVectorOffsetInfo objects or the empty list + */ + virtual const CL_NS(util)::ArrayBase* getOffsets(const size_t index) = 0; + + virtual ~TermPositionVector(){ + } +}; + + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/TermVectorReader.cpp b/src/core/CLucene/index/TermVectorReader.cpp new file mode 100644 index 00000000000..dcaaddfcbdb --- /dev/null +++ b/src/core/CLucene/index/TermVectorReader.cpp @@ -0,0 +1,551 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_TermVector.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" +#include "_IndexFileNames.h" + +CL_NS_USE(util) +CL_NS_DEF(index) + +TermVectorsReader::TermVectorsReader(CL_NS(store)::Directory* d, const char* segment, FieldInfos* fieldInfos, + int32_t readBufferSize, int32_t docStoreOffset, int32_t size): + fieldInfos(NULL), tvx(NULL), tvd(NULL), tvf(NULL), _size(0), docStoreOffset(0) + { + + bool success = false; + + char fbuf[CL_MAX_NAME]; + strcpy(fbuf,segment); + strcat(fbuf,"."); + char* fpbuf=fbuf+strlen(fbuf); + + strcpy(fpbuf,IndexFileNames::VECTORS_INDEX_EXTENSION); + try { + if (d->fileExists(fbuf)) { + tvx = d->openInput(fbuf, readBufferSize); + checkValidFormat(tvx); + + strcpy(fpbuf,IndexFileNames::VECTORS_DOCUMENTS_EXTENSION); + tvd = d->openInput(fbuf, readBufferSize); + tvdFormat = checkValidFormat(tvd); + + strcpy(fpbuf,IndexFileNames::VECTORS_FIELDS_EXTENSION); + tvf = d->openInput(fbuf, readBufferSize); + tvfFormat = checkValidFormat(tvf); + if (-1 == docStoreOffset) { + this->docStoreOffset = 0; + this->_size = static_cast(tvx->length() >> 3); + } else { + this->docStoreOffset = docStoreOffset; + this->_size = size; + // Verify the file is long enough to hold all of our + // docs + CND_CONDITION( ((int64_t) (tvx->length() / 8)) >= size + docStoreOffset , "file is not long enough to hold all of our docs"); + } + } + + this->fieldInfos = fieldInfos; + success = true; + } _CLFINALLY ({ + // With lock-less commits, it's entirely possible (and + // fine) to hit a FileNotFound exception above. In + // this case, we want to explicitly close any subset + // of things that were opened so that we don't have to + // wait for a GC to do so. + if (!success) { + close(); + } + }); +} + +TermVectorsReader::TermVectorsReader(const TermVectorsReader& copy) +{ + tvx = copy.tvx->clone(); + tvd = copy.tvd->clone(); + tvf = copy.tvf->clone(); + + tvdFormat = copy.tvdFormat; + tvfFormat = copy.tvfFormat; + _size = copy._size; + fieldInfos = copy.fieldInfos; + docStoreOffset = copy.docStoreOffset; +} +TermVectorsReader* TermVectorsReader::clone() const{ + if (tvx == NULL || tvd == NULL || tvf == NULL) + return NULL; + return _CLNEW TermVectorsReader(*this); +} + +TermVectorsReader::~TermVectorsReader(){ + close(); +} + +int32_t TermVectorsReader::checkValidFormat(CL_NS(store)::IndexInput* in){ + int32_t format = in->readInt(); + if (format > TermVectorsReader::FORMAT_VERSION) + { + CL_NS(util)::StringBuffer err; + err.append(_T("Incompatible format version: ")); + err.appendInt(format); + err.append(_T(" expected ")); + err.appendInt(TermVectorsReader::FORMAT_VERSION); + err.append(_T(" or less")); + _CLTHROWT(CL_ERR_CorruptIndex,err.getBuffer()); + } + return format; +} + +void TermVectorsReader::close(){ + // make all effort to close up. Keep the first exception + // and throw it as a new one. + // todo: why don't we trap the exception and at least make sure that + // all streams that we can close are closed? + CLuceneError keep; + bool thrown = false; + + if (tvx != NULL){ + try{tvx->close();} + catch(CLuceneError& err){ + if ( err.number() == CL_ERR_IO ){ + keep = err; + thrown = true; + }else + throw err; + } + _CLDELETE(tvx);//delete even if error thrown + } + if (tvd != NULL){ + try{tvd->close();} + catch(CLuceneError& err){ + if ( err.number() == CL_ERR_IO ){ + keep = err; + thrown = true; + }else + throw err; + } + _CLDELETE(tvd); + } + if (tvf != NULL){ + try{tvf->close();} + catch(CLuceneError& err){ + if ( err.number() == CL_ERR_IO ){ + keep = err; + thrown = true; + }else + throw err; + } + _CLDELETE(tvf); + } + + if ( thrown ) + throw keep; +} + +int64_t TermVectorsReader::size() const{ + return _size; +} + +void TermVectorsReader::get(const int32_t docNum, const TCHAR* field, TermVectorMapper* mapper){ + if (tvx != NULL) { + int32_t fieldNumber = fieldInfos->fieldNumber(field); + //We need to account for the FORMAT_SIZE at when seeking in the tvx + //We don't need to do this in other seeks because we already have the + // file pointer + //that was written in another file + tvx->seek(((docNum + docStoreOffset) * 8L) + FORMAT_SIZE); + int64_t position = tvx->readLong(); + + tvd->seek(position); + int32_t fieldCount = tvd->readVInt(); + // There are only a few fields per document. We opt for a full scan + // rather then requiring that they be ordered. We need to read through + // all of the fields anyway to get to the tvf pointers. + int32_t number = 0; + int32_t found = -1; + for (int32_t i = 0; i < fieldCount; ++i) { + if(tvdFormat == FORMAT_VERSION) + number = tvd->readVInt(); + else + number += tvd->readVInt(); + + if (number == fieldNumber) + found = i; + } + + // This field, although valid in the segment, was not found in this + // document + if (found != -1) { + // Compute position in the tvf file + position = 0; + for (int32_t i = 0; i <= found; i++) // TODO: Was ++i, make sure its still good + position += tvd->readVLong(); + + mapper->setDocumentNumber(docNum); + readTermVector(field, position, mapper); + } else { + // "Field not found" + } + } else { + // "No tvx file" + } +} + +TermFreqVector* TermVectorsReader::get(const int32_t docNum, const TCHAR* field){ + // Check if no term vectors are available for this segment at all + ParallelArrayTermVectorMapper* mapper = _CLNEW ParallelArrayTermVectorMapper(); + get(docNum, field, (TermVectorMapper*)mapper); + + TermFreqVector* ret = mapper->materializeVector(); + _CLLDELETE(mapper); + return ret; +} + + +ArrayBase* TermVectorsReader::get(const int32_t docNum){ + ObjectArray* result = NULL; + // Check if no term vectors are available for this segment at all + if (tvx != NULL) { + //We need to offset by + tvx->seek(((docNum + docStoreOffset) * 8L) + FORMAT_SIZE); + int64_t position = tvx->readLong(); + + tvd->seek(position); + int32_t fieldCount = tvd->readVInt(); + + // No fields are vectorized for this document + if (fieldCount != 0) { + int32_t number = 0; + const TCHAR** fields = _CL_NEWARRAY(const TCHAR*,fieldCount+1); + + { //msvc6 scope fix + for (int32_t i = 0; i < fieldCount; ++i) { + if(tvdFormat == FORMAT_VERSION) + number = tvd->readVInt(); + else + number += tvd->readVInt(); + fields[i] = fieldInfos->fieldName(number); + } + } + fields[fieldCount]=NULL; + + // Compute position in the tvf file + position = 0; + int64_t* tvfPointers = _CL_NEWARRAY(int64_t,fieldCount); + { //msvc6 scope fix + for (int32_t i = 0; i < fieldCount; ++i) { + position += tvd->readVLong(); + tvfPointers[i] = position; + } + } + + result = (ObjectArray*)readTermVectors(docNum, fields, tvfPointers, fieldCount); + + _CLDELETE_ARRAY(tvfPointers); + _CLDELETE_ARRAY(fields); + } + } else { + // "No tvx file" + } + return result; +} + +void TermVectorsReader::get(const int32_t docNumber, TermVectorMapper* mapper) { + // Check if no term vectors are available for this segment at all + if (tvx != NULL) { + //We need to offset by + tvx->seek((docNumber * 8L) + FORMAT_SIZE); + int64_t position = tvx->readLong(); + + tvd->seek(position); + int32_t fieldCount = tvd->readVInt(); + + // No fields are vectorized for this document + if (fieldCount != 0) { + int32_t number = 0; + const TCHAR** fields = _CL_NEWARRAY(const TCHAR*, fieldCount+1); + + { //msvc6 scope fix + for (int32_t i = 0; i < fieldCount; i++) { + if(tvdFormat == FORMAT_VERSION) + number = tvd->readVInt(); + else + number += tvd->readVInt(); + + fields[i] = fieldInfos->fieldName(number); + } + } + fields[fieldCount]=NULL; + + // Compute position in the tvf file + position = 0; + int64_t* tvfPointers = _CL_NEWARRAY(int64_t,fieldCount); + { //msvc6 scope fix + for (int32_t i = 0; i < fieldCount; i++) { + position += tvd->readVLong(); + tvfPointers[i] = position; + } + } + + mapper->setDocumentNumber(docNumber); + readTermVectors(fields, tvfPointers, fieldCount, mapper); + + _CLDELETE_ARRAY(tvfPointers); + _CLDELETE_ARRAY(fields); + } + } else { + // "No tvx file" + } + } + +ObjectArray* TermVectorsReader::readTermVectors(const int32_t docNum, + const TCHAR** fields, const int64_t* tvfPointers, const int32_t len){ + ObjectArray* res = _CLNEW CL_NS(util)::ObjectArray(len); + ParallelArrayTermVectorMapper* mapper = _CLNEW ParallelArrayTermVectorMapper(); + for (int32_t i = 0; i < len; i++) { + mapper->setDocumentNumber(docNum); + readTermVector(fields[i], tvfPointers[i], mapper); + res->values[i] = static_cast(mapper->materializeVector()); + mapper->reset(); + } + _CLLDELETE(mapper); + return res; +} + +void TermVectorsReader::readTermVectors(const TCHAR** fields, const int64_t* tvfPointers, + const int32_t len, TermVectorMapper* mapper){ + for (int32_t i = 0; i < len; i++) { + readTermVector(fields[i], tvfPointers[i], mapper); + } +} + +void TermVectorsReader::readTermVector(const TCHAR* field, const int64_t tvfPointer, TermVectorMapper* mapper){ + //Now read the data from specified position + //We don't need to offset by the FORMAT here since the pointer already includes the offset + tvf->seek(tvfPointer); + + int32_t numTerms = tvf->readVInt(); + // If no terms - return a constant empty termvector. However, this should never occur! + if (numTerms == 0) + return; + + bool storePositions; + bool storeOffsets; + + if(tvfFormat == FORMAT_VERSION){ + uint8_t bits = tvf->readByte(); + storePositions = (bits & STORE_POSITIONS_WITH_TERMVECTOR) != 0; + storeOffsets = (bits & STORE_OFFSET_WITH_TERMVECTOR) != 0; + } + else{ + tvf->readVInt(); + storePositions = false; + storeOffsets = false; + } + mapper->setExpectations(field, numTerms, storeOffsets, storePositions); + + int32_t start = 0; + int32_t deltaLength = 0; + int32_t totalLength = 0; + ValueArray buffer(10); // init the buffer with a length of 10 character + + for (int32_t i = 0; i < numTerms; ++i) { + start = tvf->readVInt(); + deltaLength = tvf->readVInt(); + totalLength = start + deltaLength; + if (buffer.length < totalLength + 1) // increase buffer + { + buffer.resize(totalLength+1); + } + + //read the term + tvf->readChars(buffer.values, start, deltaLength); + buffer.values[totalLength] = '\0'; //null terminate term + + //read the frequency + int32_t freq = tvf->readVInt(); + ValueArray* positions = NULL; + + if (storePositions) { //read in the positions + //does the mapper even care about positions? + if (mapper->isIgnoringPositions() == false) { + positions = _CLNEW ValueArray(freq); + int32_t prevPosition = 0; + for (int32_t j = 0; j < freq; j++) + { + positions->values[j] = prevPosition + tvf->readVInt(); + prevPosition = positions->values[j]; + } + } else { + //we need to skip over the positions. Since these are VInts, I don't believe there is anyway to know for sure how far to skip + // + for (int32_t j = 0; j < freq; j++) + { + tvf->readVInt(); + } + } + } + + ArrayBase* offsets = NULL; + if (storeOffsets) { + //does the mapper even care about offsets? + if (mapper->isIgnoringOffsets() == false) { + offsets = _CLNEW ObjectArray(freq); + int32_t prevOffset = 0; + for (int32_t j = 0; j < freq; j++) { + int32_t startOffset = prevOffset + tvf->readVInt(); + int32_t endOffset = startOffset + tvf->readVInt(); + offsets->values[j] = _CLNEW TermVectorOffsetInfo(startOffset, endOffset); + prevOffset = endOffset; + } + } else { + for (int32_t j = 0; j < freq; j++){ + tvf->readVInt(); + tvf->readVInt(); + } + } + } + mapper->map(buffer.values, totalLength, freq, offsets, positions); + } +} + +ObjectArray* TermVectorOffsetInfo_EMPTY_OFFSET_INFO = _CLNEW ObjectArray; + +TermVectorOffsetInfo::TermVectorOffsetInfo() { + startOffset = 0; + endOffset=0; +} +TermVectorOffsetInfo::~TermVectorOffsetInfo() { +} + +TermVectorOffsetInfo::TermVectorOffsetInfo(int32_t startOffset, int32_t endOffset) { + this->endOffset = endOffset; + this->startOffset = startOffset; +} + +int32_t TermVectorOffsetInfo::getEndOffset() const{ + return endOffset; +} + +void TermVectorOffsetInfo::setEndOffset(const int32_t _endOffset) { + this->endOffset = _endOffset; +} + +int32_t TermVectorOffsetInfo::getStartOffset() const{ + return startOffset; +} + +void TermVectorOffsetInfo::setStartOffset(const int32_t _startOffset) { + this->startOffset = _startOffset; +} + +bool TermVectorOffsetInfo::equals(TermVectorOffsetInfo* termVectorOffsetInfo) { + if (this == termVectorOffsetInfo) + return true; + + if (endOffset != termVectorOffsetInfo->endOffset) return false; + if (startOffset != termVectorOffsetInfo->startOffset) return false; + + return true; +} + +size_t TermVectorOffsetInfo::hashCode() const{ + size_t result; + result = startOffset; + result = 29 * result + endOffset; + return result; +} + +TermVectorMapper::TermVectorMapper(){ + this->ignoringPositions = false; + this->ignoringOffsets = false; +} + +TermVectorMapper::TermVectorMapper(const bool _ignoringPositions, const bool _ignoringOffsets){ + this->ignoringPositions = _ignoringPositions; + this->ignoringOffsets = _ignoringOffsets; +} + +bool TermVectorMapper::isIgnoringPositions() const +{ + return ignoringPositions; +} + +bool TermVectorMapper::isIgnoringOffsets() const +{ + return ignoringOffsets; +} + +void TermVectorMapper::setDocumentNumber(const int32_t /*documentNumber*/) +{ + //default implementation does nothing... +} + +ParallelArrayTermVectorMapper::ParallelArrayTermVectorMapper(): + terms(NULL), + termFreqs(NULL), + positions(NULL), + offsets(NULL), + currentPosition(0), + field(NULL) +{ +} +ParallelArrayTermVectorMapper::~ParallelArrayTermVectorMapper(){ + _CLDELETE_LCARRAY(field); +} + +void ParallelArrayTermVectorMapper::setExpectations(const TCHAR* _field, const int32_t numTerms, + const bool storeOffsets, const bool storePositions) { + _CLDELETE_LCARRAY(field); + this->field = STRDUP_TtoT(_field); + + terms = _CLNEW CL_NS(util)::TCharArray(numTerms); + termFreqs = _CLNEW ValueArray(numTerms); + + this->storingOffsets = storeOffsets; + this->storingPositions = storePositions; + if(storePositions){ + positions = (ArrayBase< ArrayBase* >*)_CLNEW ObjectArray< ValueArray >(numTerms); + } + if(storeOffsets){ + offsets = _CLNEW ObjectArray< ArrayBase >(numTerms); + } +} + +void ParallelArrayTermVectorMapper::map(const TCHAR* term, int32_t termLen, const int32_t frequency, + ArrayBase* _offsets, + ArrayBase* _positions) { + terms->values[currentPosition] = STRDUP_TtoT(term); + + termFreqs->values[currentPosition] = frequency; + + if (storingOffsets) + { + this->offsets->values[currentPosition] = _offsets; + } + if (storingPositions) + { + this->positions->values[currentPosition] = _positions; + } + currentPosition++; +} + +TermFreqVector* ParallelArrayTermVectorMapper::materializeVector() { + SegmentTermVector* tv = NULL; + if (field != NULL && terms != NULL) { + if (storingPositions || storingOffsets) { + tv = _CLNEW SegmentTermPositionVector(field, terms, termFreqs, positions, offsets); + } else { + tv = _CLNEW SegmentTermVector(field, terms, termFreqs); + } + } + return tv; +} + +CL_NS_END diff --git a/src/core/CLucene/index/TermVectorWriter.cpp b/src/core/CLucene/index/TermVectorWriter.cpp new file mode 100644 index 00000000000..a37b69e679d --- /dev/null +++ b/src/core/CLucene/index/TermVectorWriter.cpp @@ -0,0 +1,230 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_TermVector.h" +#include "_IndexFileNames.h" +#include "CLucene/util/Misc.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(index) + + TermVectorsWriter::TermVectorsWriter(CL_NS(store)::Directory* directory, + const char* segment,FieldInfos* fieldInfos) + { + // Open files for TermVector storage + char fbuf[CL_MAX_NAME]; + strcpy(fbuf,segment); + strcat(fbuf,"."); + char* fpbuf=fbuf+strlen(fbuf); + + strcpy(fpbuf,IndexFileNames::VECTORS_INDEX_EXTENSION); + tvx = directory->createOutput(fbuf); + tvx->writeInt(TermVectorsReader::FORMAT_VERSION); + + strcpy(fpbuf,IndexFileNames::VECTORS_DOCUMENTS_EXTENSION); + tvd = directory->createOutput(fbuf); + tvd->writeInt(TermVectorsReader::FORMAT_VERSION); + + strcpy(fpbuf,IndexFileNames::VECTORS_FIELDS_EXTENSION); + tvf = directory->createOutput(fbuf); + tvf->writeInt(TermVectorsReader::FORMAT_VERSION); + + this->fieldInfos = fieldInfos; + } + + void TermVectorsWriter::close(CLuceneError* err){ + CLuceneError keep; + bool bError = false; + + if ( tvx != NULL ){ + try{ + tvx->close(); + }catch(CLuceneError& ioerr){ + if ( ioerr.number() != CL_ERR_IO ) + { + _CLDELETE(tvx); + _CLDELETE(tvd); + _CLDELETE(tvf); + throw ioerr; + } + if (!bError) + { + bError = true; + keep.set(ioerr.number(), ioerr.what()); + } + } + _CLDELETE(tvx); + } + + if ( tvd != NULL ){ + try{ + tvd->close(); + }catch(CLuceneError& ioerr){ + if ( ioerr.number() != CL_ERR_IO ) + { + _CLDELETE(tvd); + _CLDELETE(tvf); + throw ioerr; + } + if (!bError) + { + bError = true; + keep.set(ioerr.number(), ioerr.what()); + } + } + _CLDELETE(tvd); + } + + if ( tvf != NULL ){ + try{ + tvf->close(); + }catch(CLuceneError& ioerr){ + if ( ioerr.number() != CL_ERR_IO ) + { + _CLDELETE(tvf); + throw ioerr; + } + if (!bError) + { + bError = true; + keep.set(ioerr.number(), ioerr.what()); + } + } + _CLDELETE(tvf); + } + + if (bError) + { + if ( err != NULL ) + err->set(keep.number(), keep.what()); + else + throw keep; + } + } + + TermVectorsWriter::~TermVectorsWriter(){ + CLuceneError err; + close(&err); + } + + + void TermVectorsWriter::addAllDocVectors(ArrayBase* _vectors){ + + tvx->writeLong(tvd->getFilePointer()); + + if (_vectors != NULL) { + ArrayBase& vectors = *_vectors; + + const int32_t numFields = vectors.length; + tvd->writeVInt(numFields); + + ValueArray fieldPointers(numFields); + + for (int32_t i=0; igetFilePointer(); + + const int32_t fieldNumber = fieldInfos->fieldNumber(vectors[i]->getField()); + + // 1st pass: write field numbers to tvd + tvd->writeVInt(fieldNumber); + + const int32_t numTerms = vectors[i]->size(); + tvf->writeVInt(numTerms); + + TermPositionVector* tpVector = NULL; + + uint8_t bits = 0; + bool storePositions = false; + bool storeOffsets = false; + + if ( vectors[i]->__asTermPositionVector() != NULL ) { + // May have positions & offsets + tpVector = vectors[i]->__asTermPositionVector(); + storePositions = tpVector->size() > 0 && tpVector->getTermPositions(0) != NULL; + storeOffsets = tpVector->size() > 0 && tpVector->getOffsets(0) != NULL; + bits = ((storePositions ? TermVectorsReader::STORE_POSITIONS_WITH_TERMVECTOR : 0) + + (storeOffsets ? TermVectorsReader::STORE_OFFSET_WITH_TERMVECTOR : 0)); + } else { + tpVector = NULL; + bits = 0; + storePositions = false; + storeOffsets = false; + } + + tvf->writeVInt(bits); + + const ArrayBase& terms = *vectors[i]->getTerms(); + const ArrayBase& freqs = *vectors[i]->getTermFrequencies(); + + const TCHAR* lastTermText = LUCENE_BLANK_STRING; + size_t lastTermTextLen = 0; + + for (int32_t j=0; jwriteVInt(start); // write shared prefix length + tvf->writeVInt(length); // write delta length + tvf->writeChars(termText + start, length); // write delta chars + lastTermText = termText; + + const int32_t termFreq = freqs[j]; + + tvf->writeVInt(termFreq); + + if (storePositions) { + const ArrayBase* _positions = tpVector->getTermPositions(j); + if (_positions == NULL) + _CLTHROWA(CL_ERR_IllegalState, "Trying to write positions that are NULL!"); + const ArrayBase& positions = *_positions; + assert (positions.length == termFreq); + + // use delta encoding for positions + int32_t lastPosition = 0; + for(int32_t k=0;kwriteVInt(position-lastPosition); + lastPosition = position; + } + } + + if (storeOffsets) { + const ArrayBase* _offsets = tpVector->getOffsets(j); + if (_offsets == NULL) + _CLTHROWA(CL_ERR_IllegalState, "Trying to write offsets that are NULL!"); + const ArrayBase& offsets = *_offsets; + assert (offsets.length == termFreq); + + // use delta encoding for offsets + int32_t lastEndOffset = 0; + for(int k=0;kgetStartOffset(); + const int32_t endOffset = offsets[k]->getEndOffset(); + tvf->writeVInt(startOffset-lastEndOffset); + tvf->writeVInt(endOffset-startOffset); + lastEndOffset = endOffset; + } + } + } + } + + // 2nd pass: write field pointers to tvd + int64_t lastFieldPointer = 0; + for (int32_t i=0; iwriteVLong(fieldPointer-lastFieldPointer); + lastFieldPointer = fieldPointer; + } + } else + tvd->writeVInt(0); + } + +CL_NS_END diff --git a/src/core/CLucene/index/Terms.cpp b/src/core/CLucene/index/Terms.cpp new file mode 100644 index 00000000000..7899f814d41 --- /dev/null +++ b/src/core/CLucene/index/Terms.cpp @@ -0,0 +1,30 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Terms.h" +#include "Term.h" + +CL_NS_DEF(index) + +TermDocs::~TermDocs(){ +} + +TermEnum::~TermEnum(){ +} + +bool TermEnum::skipTo(Term* target){ + do { + if (!next()) + return false; + } while (target->compareTo(term(false)) > 0); + return true; +} + +TermPositions::~TermPositions(){ +} + +CL_NS_END diff --git a/src/core/CLucene/index/Terms.h b/src/core/CLucene/index/Terms.h new file mode 100644 index 00000000000..1744fa44479 --- /dev/null +++ b/src/core/CLucene/index/Terms.h @@ -0,0 +1,189 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_Terms_ +#define _lucene_index_Terms_ + +#include "CLucene/util/Equators.h" +CL_NS_DEF(index) + +//predefine +class Term; +class TermEnum; +class TermPositions; + +/** TermDocs provides an interface for enumerating <document, frequency> + pairs for a term.

The document portion names each document containing + the term. Documents are indicated by number. The frequency portion gives + the number of times the term occurred in each document.

The pairs are + ordered by document number. + + @see IndexReader#termDocs() + */ +class CLUCENE_EXPORT TermDocs { +public: + virtual ~TermDocs(); + + // Sets this to the data for a term. + // The enumeration is reset to the start of the data for this term. + virtual void seek(Term* term)=0; + + /** Sets this to the data for the current term in a {@link TermEnum}. + * This may be optimized in some implementations. + */ + virtual void seek(TermEnum* termEnum)=0; + + // Returns the current document number.

This is invalid until {@link + // #next()} is called for the first time. + virtual int32_t doc() const=0; + + // Returns the frequency of the term within the current document.

This + // is invalid until {@link #next()} is called for the first time. + virtual int32_t freq() const=0; + + // Moves to the next pair in the enumeration.

Returns true iff there is + // such a next pair in the enumeration. + virtual bool next() =0; + + // Attempts to read multiple entries from the enumeration, up to length of + // docs. Document numbers are stored in docs, and term + // frequencies are stored in freqs. The freqs array must be as + // int64_t as the docs array. + // + //

Returns the number of entries read. Zero is only returned when the + // stream has been exhausted. + virtual int32_t read(int32_t* docs, int32_t* freqs, int32_t length)=0; + + // Skips entries to the first beyond the current whose document number is + // greater than or equal to target.

Returns true iff there is such + // an entry.

Behaves as if written:

+	//   bool skipTo(int32_t target) {
+	//     do {
+	//       if (!next())
+	// 	     return false;
+	//     } while (target > doc());
+	//     return true;
+	//   }
+	// 
+ // Some implementations are considerably more efficient than that. + virtual bool skipTo(const int32_t target)=0; + + // Frees associated resources. + virtual void close() = 0; + + + /** Solve the diamond inheritence problem by providing a reinterpret function. + * No dynamic casting is required and no RTTI data is needed to do this + */ + virtual TermPositions* __asTermPositions()=0; +}; + + +/** Abstract class for enumerating terms. + +

Term enumerations are always ordered by Term.compareTo(). Each term in + the enumeration is greater than all that precede it. +*/ +class CLUCENE_EXPORT TermEnum: LUCENE_BASE, public CL_NS(util)::NamedObject { +public: + /** Increments the enumeration to the next element. True if one exists.*/ + virtual bool next()=0; + + /** + * Returns the current Term in the enumeration. + * @param pointer if true, then increment the reference count before returning + */ + virtual Term* term(bool pointer=true)=0; + + /** Returns the docFreq of the current Term in the enumeration.*/ + virtual int32_t docFreq() const=0; + + /** Closes the enumeration to further activity, freeing resources. */ + virtual void close() =0; + + virtual ~TermEnum(); + + // Term Vector support + /** Skips terms to the first beyond the current whose value is + * greater or equal to target.

Returns true iff there is such + * an entry.

Behaves as if written:

+	*   public boolean skipTo(Term target) {
+	*     do {
+	*       if (!next())
+	* 	     return false;
+	*     } while (target > term());
+	*     return true;
+	*   }
+	* 
+ * Some implementations are considerably more efficient than that. + */ + virtual bool skipTo(Term* target); +}; + + + +/** + * TermPositions provides an interface for enumerating the <document, + * frequency, <position>* > tuples for a term.

The document and + * frequency are the same as for a TermDocs. The positions portion lists the ordinal + * positions of each occurrence of a term in a document. + * + * @see IndexReader#termPositions() + */ +class CLUCENE_EXPORT TermPositions: public virtual TermDocs { +public: + /** Returns next position in the current document. It is an error to call + this more than {@link #freq()} times + without calling {@link #next()}

This is + invalid until {@link #next()} is called for + the first time. + */ + virtual int32_t nextPosition() = 0; + + virtual ~TermPositions(); + + /** + * Returns the length of the payload at the current term position. + * This is invalid until {@link #nextPosition()} is called for + * the first time.
+ * @return length of the current payload in number of bytes + */ + virtual int32_t getPayloadLength() const = 0; + + /** + * Returns the payload data at the current term position. + * This is invalid until {@link #nextPosition()} is called for + * the first time. + * This method must not be called more than once after each call + * of {@link #nextPosition()}. However, payloads are loaded lazily, + * so if the payload data for the current position is not needed, + * this method may not be called at all for performance reasons.
+ * + * @param data the array into which the data of this payload is to be + * stored, if it is big enough; otherwise, a new byte[] array + * is allocated for this purpose. + * @return a byte[] array containing the data of this payload + */ + virtual uint8_t* getPayload(uint8_t* data) = 0; + + /** + * Checks if a payload can be loaded at this position. + *

+ * Payloads can only be loaded once per call to + * {@link #nextPosition()}. + * + * @return true if there is a payload available at this position that can be loaded + */ + virtual bool isPayloadAvailable() const = 0; + + /** Solve the diamond inheritence problem by providing a reinterpret function. + * No dynamic casting is required and no RTTI data is needed to do this + */ + virtual TermDocs* __asTermDocs()=0; + virtual TermPositions* __asTermPositions()=0; +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_CompoundFile.h b/src/core/CLucene/index/_CompoundFile.h new file mode 100644 index 00000000000..5577610db76 --- /dev/null +++ b/src/core/CLucene/index/_CompoundFile.h @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_compoundfile_h +#define _lucene_index_compoundfile_h + + +CL_CLASS_DEF(store,Lock) +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" +#include "_SegmentMerger.h" + +CL_NS_DEF(index) + +class WriterFileEntry; +class ReaderFileEntry; + +/** + * Class for accessing a compound stream. + * This class implements a directory, but is limited to only read operations. + * Directory methods that would normally modify data throw an exception. + * + */ +class CompoundFileReader: public CL_NS(store)::Directory { +private: + int32_t readBufferSize; + + // Base info + CL_NS(store)::Directory* directory; + char* fileName; + + CL_NS(store)::IndexInput* stream; + + typedef CL_NS(util)::CLHashMap > EntriesType; + EntriesType* entries; +protected: + /** Removes an existing file in the directory-> */ + bool doDeleteFile(const char* name); + +public: + CompoundFileReader(CL_NS(store)::Directory* dir, const char* name, int32_t _readBufferSize=CL_NS(store)::BufferedIndexInput::BUFFER_SIZE); + virtual ~CompoundFileReader(); + CL_NS(store)::Directory* getDirectory(); + const char* getName() const; + + void close(); + bool openInput(const char * name, CL_NS(store)::IndexInput *& ret, CLuceneError& error, int32_t bufferSize=0); + + /** Returns an array of strings, one for each file in the directory-> */ + bool list(std::vector* names) const; + /** Returns true iff a file with the given name exists. */ + bool fileExists(const char* name) const; + /** Returns the time the named file was last modified. */ + int64_t fileModified(const char* name) const; + /** Set the modified time of an existing file to now. */ + void touchFile(const char* name); + /** Renames an existing file in the directory-> + If a file already exists with the new name, then it is replaced. + This replacement should be atomic. */ + void renameFile(const char* from, const char* to); + /** Returns the length of a file in the directory. + * @throws IOException if the file does not exist */ + int64_t fileLength(const char* name) const; + /** Not implemented + * @throws UnsupportedOperationException */ + CL_NS(store)::IndexOutput* createOutput(const char* name); + /** Not implemented + * @throws UnsupportedOperationException */ + CL_NS(store)::LuceneLock* makeLock(const char* name); + + std::string toString() const; + + static const char* getClassName(); + const char* getObjectName() const; +}; + + +/** + * Combines multiple files into a single compound file. + * The file format:
+ *

    + *
  • VInt fileCount
  • + *
  • {Directory} + * fileCount entries with the following structure:
  • + *
      + *
    • int64_t dataOffset
    • + *
    • UTFString extension
    • + *
    + *
  • {File Data} + * fileCount entries with the raw data of the corresponding file
  • + *
+ * + * The fileCount integer indicates how many files are contained in this compound + * file. The {directory} that follows has that many entries. Each directory entry + * contains an encoding identifier, an int64_t pointer to the start of this file's + * data section, and a UTF String with that file's extension. + * + */ +class CompoundFileWriter:LUCENE_BASE { + class Internal; + Internal* _internal; + + /** Copy the contents of the file with specified extension into the + * provided output stream. Use the provided buffer for moving data + * to reduce memory allocation. + */ + void copyFile(WriterFileEntry* source, CL_NS(store)::IndexOutput* os, uint8_t* buffer, int32_t bufferLength); +public: + /** Create the compound stream in the specified file. The file name is the + * entire name (no extensions are added). + */ + CompoundFileWriter(CL_NS(store)::Directory* dir, const char* name, SegmentMerger::CheckAbort* checkAbort = NULL); + ~CompoundFileWriter(); + /** Returns the directory of the compound file. */ + CL_NS(store)::Directory* getDirectory(); + const char* getName() const ; + /** Add a source stream. file is the string by which the + * sub-stream will be known in the compound stream. + * + * @throws IllegalStateException if this writer is closed + * @throws NullPointerException if file is null + * @throws IllegalArgumentException if a file with the same name + * has been added already + */ + void addFile(const char* file); + /** Merge files with the extensions added up to now. + * All files with these extensions are combined sequentially into the + * compound stream. After successful merge, the source files + * @throws IllegalStateException if close() had been called before or + * if no file has been added to this object + * are deleted. + */ + void close(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_DocumentsWriter.h b/src/core/CLucene/index/_DocumentsWriter.h new file mode 100644 index 00000000000..9d359c245c3 --- /dev/null +++ b/src/core/CLucene/index/_DocumentsWriter.h @@ -0,0 +1,1005 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_DocumentsWriter_ +#define _lucene_index_DocumentsWriter_ + +#include "CLucene/store/IndexInput.h" +#include "CLucene/config/_threads.h" +#include "CLucene/util/Array.h" +#include "CLucene/store/_RAMDirectory.h" +#include "_TermInfo.h" + +CL_CLASS_DEF(analysis,Analyzer) +CL_CLASS_DEF(analysis,Token) +CL_CLASS_DEF(analysis,TokenStream) +CL_CLASS_DEF(document,Field) +CL_CLASS_DEF(store,IndexOutput) +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(util,StringReader) + +CL_NS_DEF(index) + +class DocumentsWriter; +class DefaultSkipListWriter; +class FieldInfos; +class FieldsWriter; +class FieldInfos; +class IndexWriter; +class TermInfo; +class TermInfosWriter; +class Term; +class FieldInfo; +class Term_Compare; +class Term_Equals; + +/** Used only internally to DW to call abort "up the stack" */ +class AbortException{ +public: + CLuceneError err; + AbortException(CLuceneError& _err, DocumentsWriter* docWriter); +}; + +// Number of documents a delete term applies to. +class Num { +private: + int32_t num; +public: + Num(int32_t num) { + this->num = num; + } + int32_t getNum() { + return num; + } + void setNum(int32_t num) { + // Only record the new number if it's greater than the + // current one. This is important because if multiple + // threads are replacing the same doc at nearly the + // same time, it's possible that one thread that got a + // higher docID is scheduled before the other + // threads. + if (num > this->num) + this->num = num; + } +}; +typedef CL_NS(util)::CLHashMap, CL_NS(util)::Deletor::Object > TermNumMapType; + +class IDocumentsWriter { +public: + virtual std::string getSegment() = 0; + virtual int32_t getDocStoreOffset() = 0; + virtual int32_t getNumBufferedDeleteTerms() = 0; + virtual void setMaxBufferedDocs(int32_t count) = 0; + virtual void setInfoStream(std::ostream *infoStream) = 0; + virtual void setRAMBufferSizeMB(float_t mb) = 0; + virtual void setMaxBufferedDeleteTerms(int32_t _maxBufferedDeleteTerms) = 0; + virtual int32_t getMaxBufferedDeleteTerms() = 0; + virtual bool hasDeletes() = 0; + virtual void close() = 0; + virtual const std::vector &files() = 0; + virtual std::string closeDocStore() = 0; + virtual void abort(AbortException *ae) = 0; + virtual bool addDocument(document::Document *doc, analysis::Analyzer *analyzer) = 0; + virtual bool updateDocument(Term* t, CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer) = 0; + virtual const std::vector *abortedFiles() = 0; + virtual bool bufferDeleteTerm(Term *term) = 0; + virtual bool pauseAllThreads() = 0; + virtual void resumeAllThreads() = 0; + virtual int32_t getNumDocsInRAM() = 0; + virtual int32_t flush(bool _closeDocStore) = 0; + virtual void createCompoundFile(const std::string &segment) = 0; + virtual void clearBufferedDeletes() = 0; + virtual const TermNumMapType& getBufferedDeleteTerms() = 0; + virtual int32_t getMaxBufferedDocs() = 0; + virtual float_t getRAMBufferSizeMB() = 0; + virtual bool bufferDeleteTerms(const CL_NS(util)::ArrayBase* terms) = 0; + virtual const std::string& getDocStoreSegment() = 0; + virtual int64_t getRAMUsed() = 0; + virtual const std::vector* getBufferedDeleteDocIDs() = 0; + virtual ~IDocumentsWriter() {} +}; + +/** + * This class accepts multiple added documents and directly + * writes a single segment file. It does this more + * efficiently than creating a single segment per document + * (with DocumentWriter) and doing standard merges on those + * segments. + * + * When a document is added, its stored fields (if any) and + * term vectors (if any) are immediately written to the + * Directory (ie these do not consume RAM). The freq/prox + * postings are accumulated into a Postings hash table keyed + * by term. Each entry in this hash table holds a separate + * uint8_t stream (allocated as incrementally growing slices + * into large shared uint8_t[] arrays) for freq and prox, that + * contains the postings data for multiple documents. If + * vectors are enabled, each unique term for each document + * also allocates a PostingVector instance to similarly + * track the offsets & positions uint8_t stream. + * + * Once the Postings hash is full (ie is consuming the + * allowed RAM) or the number of added docs is large enough + * (in the case we are flushing by doc count instead of RAM + * usage), we create a real segment and flush it to disk and + * reset the Postings hash. + * + * In adding a document we first organize all of its fields + * by field name. We then process field by field, and + * record the Posting hash per-field. After each field we + * flush its term vectors. When it's time to flush the full + * segment we first sort the fields by name, and then go + * field by field and sorts its postings. + * + * + * Threads: + * + * Multiple threads are allowed into addDocument at once. + * There is an initial synchronized call to getThreadState + * which allocates a ThreadState for this thread. The same + * thread will get the same ThreadState over time (thread + * affinity) so that if there are consistent patterns (for + * example each thread is indexing a different content + * source) then we make better use of RAM. Then + * processDocument is called on that ThreadState without + * synchronization (most of the "heavy lifting" is in this + * call). Finally the synchronized "finishDocument" is + * called to flush changes to the directory. + * + * Each ThreadState instance has its own Posting hash. Once + * we're using too much RAM, we flush all Posting hashes to + * a segment by merging the docIDs in the posting lists for + * the same term across multiple thread states (see + * writeSegment and appendPostings). + * + * When flush is called by IndexWriter, or, we flush + * internally when autoCommit=false, we forcefully idle all + * threads and flush only once they are all idle. This + * means you can call flush with a given thread even while + * other threads are actively adding/deleting documents. + * + * + * Exceptions: + * + * Because this class directly updates in-memory posting + * lists, and flushes stored fields and term vectors + * directly to files in the directory, there are certain + * limited times when an exception can corrupt this state. + * For example, a disk full while flushing stored fields + * leaves this file in a corrupt state. Or, an OOM + * exception while appending to the in-memory posting lists + * can corrupt that posting list. We call such exceptions + * "aborting exceptions". In these cases we must call + * abort() to discard all docs added since the last flush. + * + * All other exceptions ("non-aborting exceptions") can + * still partially update the index structures. These + * updates are consistent, but, they represent only a part + * of the document seen up until the exception was hit. + * When this happens, we immediately mark the document as + * deleted so that the document is always atomically ("all + * or none") added to the index. + */ +class DocumentsWriter : public IDocumentsWriter { +private: + IndexWriter* writer; + CL_NS(store)::Directory* directory; + DEFINE_MUTEX(THIS_LOCK) + DEFINE_CONDITION(THIS_WAIT_CONDITION) + + FieldInfos* fieldInfos; // All fields we've seen + CL_NS(store)::IndexOutput *tvx, *tvf, *tvd; // To write term vectors + FieldsWriter* fieldsWriter; // To write stored fields + + std::string segment; // Current segment we are working on + std::string docStoreSegment; // Current doc-store segment we are writing + int32_t docStoreOffset; // Current starting doc-store offset of current segment + + int32_t nextDocID; // Next docID to be added + int32_t numDocsInRAM; // # docs buffered in RAM + int32_t numDocsInStore; // # docs written to doc stores + int32_t nextWriteDocID; // Next docID to be written + + std::ostream* infoStream; + + // Currently used only for deleting a doc on hitting an non-aborting exception + std::vector bufferedDeleteDocIDs; + std::vector docDeltaBuffer; + + // The max number of delete terms that can be buffered before + // they must be flushed to disk. + int32_t maxBufferedDeleteTerms; + + // How much RAM we can use before flushing. This is 0 if + // we are flushing by doc count instead. + int64_t ramBufferSize; + + // Flush @ this number of docs. If rarmBufferSize is + // non-zero we will flush by RAM usage instead. + int32_t maxBufferedDocs; + + bool closed; + + // Coarse estimates used to measure RAM usage of buffered deletes + static int32_t OBJECT_HEADER_BYTES; + static int32_t OBJECT_POINTER_BYTES; // TODO: should be 8 on 64-bit platform + static int32_t BYTES_PER_CHAR; + static int32_t BYTES_PER_INT; + + + // This Hashmap buffers delete terms in ram before they + // are applied. The key is delete term; the value is + // number of buffered documents the term applies to. + TermNumMapType* bufferedDeleteTerms; + int32_t numBufferedDeleteTerms; + + + /* Simple StringReader that can be reset to a new string; + * we use this when tokenizing the string value from a + * Field. */ + typedef CL_NS(util)::StringReader ReusableStringReader; + + class ByteBlockPool; + class CharBlockPool; + class FieldMergeState; + + /* IndexInput that knows how to read the byte slices written + * by Posting and PostingVector. We read the bytes in + * each slice until we hit the end of that slice at which + * point we read the forwarding address of the next slice + * and then jump to it.*/ + class ByteSliceReader: public CL_NS(store)::IndexInput { + ByteBlockPool* pool; + int32_t bufferUpto; + const uint8_t* buffer; + int32_t limit; + int32_t level; + + int32_t upto; + int32_t bufferOffset; + int32_t endIndex; + public: + ByteSliceReader(); + virtual ~ByteSliceReader(); + void init(ByteBlockPool* pool, int32_t startIndex, int32_t endIndex); + + uint8_t readByte(); + int64_t writeTo(CL_NS(store)::IndexOutput* out); + void nextSlice(); + void readBytes(uint8_t* b, const int32_t len); + void readBytes(uint8_t* b, const int32_t len, int32_t offset); + int64_t getFilePointer() const; + int64_t length() const; + void seek(const int64_t pos); + void close(); + + IndexInput* clone() const; + const char* getDirectoryType() const; + const char* getObjectName() const; + static const char* getClassName(); + + friend class FieldMergeState; + }; + + + struct PostingVector; //predefine... + + /* Used to track postings for a single term. One of these + * exists per unique term seen since the last flush. */ + struct Posting { + int32_t textStart; // Address into char[] blocks where our text is stored + int32_t docFreq; // # times this term occurs in the current doc + int32_t freqStart; // Address of first uint8_t[] slice for freq + int32_t freqUpto; // Next write address for freq + int32_t proxStart; // Address of first uint8_t[] slice + int32_t proxUpto; // Next write address for prox + int32_t lastDocID; // Last docID where this term occurred + int32_t lastDocCode; // Code for prior doc + int32_t lastPosition; // Last position where this term occurred + PostingVector* vector; // Corresponding PostingVector instance + }; + + /* Used to track data for term vectors. One of these + * exists per unique term seen in each field in the + * document. */ + struct PostingVector { + Posting* p; // Corresponding Posting instance for this term + int32_t lastOffset; // Last offset we saw + int32_t offsetStart; // Address of first slice for offsets + int32_t offsetUpto; // Next write address for offsets + int32_t posStart; // Address of first slice for positions + int32_t posUpto; // Next write address for positions + }; + + + /* Stores norms, buffered in RAM, until they are flushed + * to a partial segment. */ + class BufferedNorms { + public: + CL_NS(store)::RAMOutputStream out; + int32_t upto; + + BufferedNorms(); + void add(float_t norm); + void reset(); + void fill(int32_t docID); + }; + + + // Used only when infoStream != null + int64_t segmentSize(const std::string& segmentName); + + static const int32_t POINTER_NUM_BYTE; + static const int32_t INT_NUM_BYTE; + static const int32_t CHAR_NUM_BYTE; + + // Holds free pool of Posting instances + CL_NS(util)::ObjectArray postingsFreeListDW; + int32_t postingsFreeCountDW; + int32_t postingsAllocCountDW; + + typedef CL_NS(util)::CLArrayList FreeCharBlocksType; + FreeCharBlocksType freeCharBlocks; + + /* We have three pools of RAM: Postings, uint8_t blocks + * (holds freq/prox posting data) and char blocks (holds + * characters in the term). Different docs require + * varying amount of storage from these three classes. + * For example, docs with many unique single-occurrence + * short terms will use up the Postings RAM and hardly any + * of the other two. Whereas docs with very large terms + * will use alot of char blocks RAM and relatively less of + * the other two. This method just frees allocations from + * the pools once we are over-budget, which balances the + * pools to match the current docs. */ + void balanceRAM(); + + std::vector* _files; // Cached list of files we've created + std::vector* _abortedFiles; // List of files that were written before last abort() + + bool allThreadsIdle(); + + bool hasNorms; // Whether any norms were seen since last flush + + DefaultSkipListWriter* skipListWriter; + + bool currentFieldStorePayloads{}; + + /** Creates a segment from all Postings in the Postings + * hashes across all ThreadStates & FieldDatas. */ + void writeSegment(std::vector& flushedFiles); + + /** Returns the name of the file with this extension, on + * the current segment we are working on. */ + std::string segmentFileName(const std::string& extension); + std::string segmentFileName(const char* extension); + + TermInfo termInfo; // minimize consing + + + /** Reset after a flush */ + void resetPostingsData(); + + static const uint8_t defaultNorm; ///=Similarity::encodeNorm(1.0f) + + bool timeToFlushDeletes(); + + // Buffer a term in bufferedDeleteTerms, which records the + // current number of documents buffered in ram so that the + // delete term will be applied to those documents as well + // as the disk segments. + void addDeleteTerm(Term* term, int32_t docCount); + + // Buffer a specific docID for deletion. Currently only + // used when we hit a exception when adding a document + void addDeleteDocID(int32_t docId); + + typedef CL_NS(util)::CLArrayList > FreeByteBlocksType; + FreeByteBlocksType freeByteBlocks; + + + /** Per-thread state. We keep a separate Posting hash and + * other state for each thread and then merge postings * + * hashes from all threads when writing the segment. */ + class ThreadState { + public: + /** Holds data associated with a single field, including + * the Postings hash. A document may have many * + * occurrences for a given field name; we gather all * + * such occurrences here (in docFields) so that we can + * * process the entire field at once. */ + class FieldData: public CL_NS(util)::Comparable { + private: + ThreadState* threadState; + + int32_t fieldCount; + CL_NS(util)::ValueArray docFields; + + FieldData* next; + + bool postingsCompacted; + + CL_NS(util)::ValueArray postingsHash; + int32_t postingsHashSize; + int32_t postingsHashHalfSize; + int32_t postingsHashMask; + + int32_t postingsVectorsUpto; + DocumentsWriter* _parent; + + int32_t offsetEnd; + CL_NS(analysis)::Token* localToken; + + int32_t offsetStartCode; + int32_t offsetStart; + + ByteSliceReader* vectorSliceReader; + + void initPostingArrays(); + + /** Only called when term vectors are enabled. This + * is called the first time we see a given term for + * each * document, to allocate a PostingVector + * instance that * is used to record data needed to + * write the posting * vectors. */ + PostingVector* addNewVector(); + + /** This is the hotspot of indexing: it's called once + * for every term of every document. Its job is to * + * update the postings uint8_t stream (Postings hash) * + * based on the occurence of a single term. */ + void addPosition(CL_NS(analysis)::Token* token); + + /** Called when postings hash is too small (> 50% + * occupied) or too large (< 20% occupied). */ + void rehashPostings(int32_t newSize); + + /** Called once per field per document if term vectors + * are enabled, to write the vectors to * + * RAMOutputStream, which is then quickly flushed to + * the real term vectors files in the Directory. */ + void writeVectors(FieldInfo* fieldInfo); + + void compactPostings(); + + public: + int32_t numPostings; + FieldInfo* fieldInfo; + int32_t lastGen; + int32_t position; + int32_t length; + int32_t offset; + float_t boost; + bool doNorms; + bool doVectors; + bool doVectorPositions; + bool doVectorOffsets; + void resetPostingArrays(); + + FieldData(DocumentsWriter* _parent, ThreadState* __threadState, FieldInfo* fieldInfo); + ~FieldData(); + + /** So Arrays.sort can sort us. */ + int32_t compareTo(const void* o); + + /** Collapse the hash table & sort in-place. */ + CL_NS(util)::ValueArray* sortPostings(); + + /** Process all occurrences of one field in the document. */ + void processField(CL_NS(analysis)::Analyzer* analyzer); + + /* Invert one occurrence of one field in the document */ + void invertField(CL_NS(document)::Field* field, CL_NS(analysis)::Analyzer* analyzer, int32_t maxFieldLength); + + static bool sort(FieldData*, FieldData*); + + const char* getObjectName() const; + static const char* getClassName(); + int32_t compareTo(lucene::util::NamedObject *); + friend class ThreadState; + friend class FieldMergeState; + }; + + private: + CL_NS(util)::ValueArray postingsFreeListTS; // Free Posting instances + int32_t postingsFreeCountTS; + + CL_NS(util)::ValueArray vectorFieldPointers; + CL_NS(util)::ValueArray vectorFieldNumbers; + + int32_t numStoredFields; // How many stored fields in current doc + float_t docBoost; // Boost for current doc + + CL_NS(util)::ValueArray fieldDataArray; // Fields touched by current doc + int32_t numFieldData; // How many fields in current doc + int32_t numVectorFields; // How many vector fields in current doc + + CL_NS(util)::ValueArray fieldDataHash; // Hash FieldData instances by field name + int32_t fieldDataHashMask; + TCHAR* maxTermPrefix; // Non-null prefix of a too-large term if this + // doc has one + + int32_t fieldGen; + + CL_NS(util)::ObjectArray postingsVectors; + int32_t maxPostingsVectors; + + // Used to read a string value for a field + ReusableStringReader* stringReader; + + + ByteBlockPool* postingsPool; + ByteBlockPool* vectorsPool; + CharBlockPool* charPool; + + // Current posting we are working on + Posting* p; + PostingVector* vector; + + //writeFreqByte... + uint8_t* freq; + int32_t freqUpto; + + //writeProxByte... + uint8_t* prox; + int32_t proxUpto; + + //writeOffsetByte... + uint8_t* offsets; + int32_t offsetUpto; + + //writePosByte... + uint8_t* pos; + int32_t posUpto; + + + /** Do in-place sort of Posting array */ + void doPostingSort(Posting** postings, int32_t numPosting); + + void quickSort(Posting** postings, int32_t lo, int32_t hi); + + /** Do in-place sort of PostingVector array */ + void doVectorSort(CL_NS(util)::ArrayBase& postings, int32_t numPosting); + + void quickSort(CL_NS(util)::ArrayBase& postings, int32_t lo, int32_t hi); + + // USE ONLY FOR DEBUGGING! + /* + public String getPostingText() { + char[] text = charPool.buffers[p.textStart >> CHAR_BLOCK_SHIFT]; + int32_t upto = p.textStart & CHAR_BLOCK_MASK; + while(text[upto] != CLUCENE_END_OF_WORD) + upto++; + return new String(text, p.textStart, upto-(p.textStart & BYTE_BLOCK_MASK)); + } + */ + + /** Test whether the text for current Posting p equals + * current tokenText. */ + bool postingEquals(const TCHAR* tokenText, int32_t tokenTextLen); + + /** Compares term text for two Posting instance and + * returns -1 if p1 < p2; 1 if p1 > p2; else 0. + */ + int32_t comparePostings(Posting* p1, Posting* p2); + + + public: + bool isIdle; // Whether we are in use + CL_NS(store)::RAMOutputStream* tvfLocal; // Term vectors for one doc + CL_NS(store)::RAMOutputStream* fdtLocal; // Stored fields for one doc + FieldsWriter* localFieldsWriter; // Fields for one doc + int32_t numThreads; // Number of threads that use this instance + int32_t numAllFieldData; + CL_NS(util)::ValueArray allFieldDataArray; // All FieldData instances + bool doFlushAfter; + int32_t docID; // docID we are now working on + + DocumentsWriter* _parent; + + CL_NS(analysis)::Analyzer* analyzer_chs; + + ThreadState(DocumentsWriter* _parent); + virtual ~ThreadState(); + + /** Initializes shared state for this new document */ + void init(CL_NS(document)::Document* doc, int32_t docID); + + /** Tokenizes the fields of a document into Postings */ + void processDocument(CL_NS(analysis)::Analyzer* analyzer); + + /** If there are fields we've seen but did not see again + * in the last run, then free them up. Also reduce + * postings hash size. */ + void trimFields(); + + /** Clear the postings hash and return objects back to + * shared pool */ + void resetPostings(); + + /** Move all per-document state that was accumulated in + * the ThreadState into the "real" stores. */ + void writeDocument(); + + /** Write vInt into freq stream of current Posting */ + void writeFreqVInt(int32_t i); + + /** Write vInt into prox stream of current Posting */ + void writeProxVInt(int32_t i); + + /** Write uint8_t into freq stream of current Posting */ + void writeFreqByte(uint8_t b); + + /** Write uint8_t into prox stream of current Posting */ + void writeProxByte(uint8_t b); + + /** Currently only used to copy a payload into the prox + * stream. */ + void writeProxBytes(uint8_t* b, int32_t offset, int32_t len); + + /** Write vInt into offsets stream of current + * PostingVector */ + void writeOffsetVInt(int32_t i); + + /** Write uint8_t into offsets stream of current + * PostingVector */ + void writeOffsetByte(uint8_t b); + + /** Write vInt into pos stream of current + * PostingVector */ + void writePosVInt(int32_t i); + + /** Write uint8_t into pos stream of current + * PostingVector */ + void writePosByte(uint8_t b); + + friend class FieldMergeState; + }; + + /* Class that Posting and PostingVector use to write uint8_t + * streams into shared fixed-size uint8_t[] arrays. The idea + * is to allocate slices of increasing lengths For + * example, the first slice is 5 bytes, the next slice is + * 14, etc. We start by writing our bytes into the first + * 5 bytes. When we hit the end of the slice, we allocate + * the next slice and then write the address of the new + * slice into the last 4 bytes of the previous slice (the + * "forwarding address"). + * + * Each slice is filled with 0's initially, and we mark + * the end with a non-zero uint8_t. This way the methods + * that are writing into the slice don't need to record + * its length and instead allocate a new slice once they + * hit a non-zero uint8_t. */ + template + class BlockPool { + protected: + bool trackAllocations; + + int32_t numBuffer; + + int32_t bufferUpto; // Which buffer we are upto + int32_t blockSize; + + DocumentsWriter* parent; + public: + CL_NS(util)::ValueArray< T* > buffers; + int32_t tOffset; // Current head offset + int32_t tUpto; // Where we are in head buffer + T* buffer; // Current head buffer + + virtual T* getNewBlock(bool trackAllocations) = 0; + + BlockPool(DocumentsWriter* _parent, int32_t _blockSize, bool trackAllocations): + buffers(CL_NS(util)::ValueArray(10)) + { + this->blockSize = _blockSize; + this->parent = _parent; + bufferUpto = -1; + tUpto = blockSize; + tOffset = -blockSize; + buffer = NULL; + numBuffer = 0; + this->trackAllocations = trackAllocations; + buffer = NULL; + } + virtual ~BlockPool(){ + buffers.deleteValues(); + } + + virtual void reset() = 0; + + void nextBuffer() { + if (1+bufferUpto == buffers.length) { + //expand the number of buffers + buffers.resize( (int32_t)(buffers.length * 1.5)); + } + buffer = buffers.values[1+bufferUpto] = getNewBlock(trackAllocations); + bufferUpto++; + + tUpto = 0; + tOffset += blockSize; + } + + friend class DocumentsWriter; + friend class DocumentsWriter::ThreadState; + friend class DocumentsWriter::ThreadState::FieldData; + friend class DocumentsWriter::FieldMergeState; + friend class DocumentsWriter::ByteSliceReader; + }; + + class CharBlockPool: public BlockPool{ + public: + CharBlockPool(DocumentsWriter* _parent); + virtual ~CharBlockPool(); + TCHAR* getNewBlock(bool trackAllocations); + void reset(); + friend class DocumentsWriter::FieldMergeState; + }; + class ByteBlockPool: public BlockPool{ + public: + ByteBlockPool( bool _trackAllocations, DocumentsWriter* _parent); + virtual ~ByteBlockPool(); + uint8_t* getNewBlock(bool trackAllocations); + int32_t newSlice(const int32_t size); + int32_t allocSlice(uint8_t* slice, const int32_t upto); + void reset(); + + friend class DocumentsWriter::ThreadState; + }; + + + + // Max # ThreadState instances; if there are more threads + // than this they share ThreadStates + static const int32_t MAX_THREAD_STATE; + CL_NS(util)::ValueArray threadStates; + CL_NS(util)::CLHashMap<_LUCENE_THREADID_TYPE, ThreadState*, + CL_NS (util)::CLuceneThreadIdCompare,CL_NS (util)::CLuceneThreadIdCompare, + CL_NS (util)::Deletor::ConstNullVal<_LUCENE_THREADID_TYPE>, + CL_NS (util)::Deletor::Object > threadBindings; + int32_t numWaiting; + CL_NS(util)::ValueArray waitingThreadStates; + int32_t pauseThreads; // Non-zero when we need all threads to + // pause (eg to flush) + bool flushPending; // True when a thread has decided to flush + bool bufferIsFull; // True when it's time to write segment + int32_t abortCount; // Non-zero while abort is pending or running + + CL_NS(util)::ObjectArray norms; // Holds norms until we flush + + /** Does the synchronized work to finish/flush the + * inverted document. */ + void finishDocument(ThreadState* state); + + + /** Used to merge the postings from multiple ThreadStates + * when creating a segment */ + class FieldMergeState { + private: + ThreadState::FieldData* field; + CL_NS(util)::ValueArray* postings; + + Posting* p; + TCHAR* text; + int32_t textOffset; + + int32_t postingUpto; + + ByteSliceReader freq; + ByteSliceReader prox; + + int32_t docID; + int32_t termFreq; + public: + FieldMergeState(); + ~FieldMergeState(); + bool nextTerm(); + bool nextDoc(); + + friend class DocumentsWriter; + }; + + +public: + DocumentsWriter(CL_NS(store)::Directory* directory, IndexWriter* writer); + ~DocumentsWriter(); + + /** If non-null, various details of indexing are printed + * here. */ + void setInfoStream(std::ostream* infoStream); + + /** Set how much RAM we can use before flushing. */ + void setRAMBufferSizeMB(float_t mb); + + float_t getRAMBufferSizeMB(); + + /** Set max buffered docs, which means we will flush by + * doc count instead of by RAM usage. */ + void setMaxBufferedDocs(int32_t count); + + int32_t getMaxBufferedDocs(); + + /** Get current segment name we are writing. */ + std::string getSegment(); + + /** Returns how many docs are currently buffered in RAM. */ + int32_t getNumDocsInRAM(); + + /** Returns the current doc store segment we are writing + * to. This will be the same as segment when autoCommit + * * is true. */ + const std::string& getDocStoreSegment(); + + /** Returns the doc offset into the shared doc store for + * the current buffered docs. */ + int32_t getDocStoreOffset(); + + /** Closes the current open doc stores an returns the doc + * store segment name. This returns a blank string if there are + * no buffered documents. */ + std::string closeDocStore(); + + const std::vector* abortedFiles(); + + /* Returns list of files in use by this instance, + * including any flushed segments. */ + const std::vector& files(); + + void setAborting(); + + /** Called if we hit an exception when adding docs, + * flushing, etc. This resets our state, discarding any + * docs added since last flush. If ae is non-null, it + * contains the root cause exception (which we re-throw + * after we are done aborting). */ + void abort(AbortException* ae); + + // Returns true if an abort is in progress + bool pauseAllThreads(); + + void resumeAllThreads(); + + std::vector newFiles; + + /** Flush all pending docs to a new segment */ + int32_t flush(bool closeDocStore); + + /** Build compound file for the segment we just flushed */ + void createCompoundFile(const std::string& segment); + + /** Set flushPending if it is not already set and returns + * whether it was set. This is used by IndexWriter to * + * trigger a single flush even when multiple threads are + * * trying to do so. */ + bool setFlushPending(); + + void clearFlushPending(); + + /** Write norms in the "true" segment format. This is + * called only during commit, to create the .nrm file. */ + void writeNorms(const std::string& segmentName, int32_t totalNumDoc); + + int32_t compareText(const TCHAR* text1, const TCHAR* text2); + + /* Walk through all unique text tokens (Posting + * instances) found in this field and serialize them + * into a single RAM segment. */ + void appendPostings(CL_NS(util)::ArrayBase* fields, + TermInfosWriter* termsOut, + CL_NS(store)::IndexOutput* freqOut, + CL_NS(store)::IndexOutput* proxOut); + + void close(); + + /** Returns a free (idle) ThreadState that may be used for + * indexing this one document. This call also pauses if a + * flush is pending. If delTerm is non-null then we + * buffer this deleted term after the thread state has + * been acquired. */ + ThreadState* getThreadState(CL_NS(document)::Document* doc, Term* delTerm); + + /** Returns true if the caller (IndexWriter) should now + * flush. */ + bool addDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer); + + bool updateDocument(Term* t, CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer); + + bool updateDocument(CL_NS(document)::Document* doc, CL_NS(analysis)::Analyzer* analyzer, Term* delTerm); + + int32_t getNumBufferedDeleteTerms(); + + const TermNumMapType& getBufferedDeleteTerms(); + + const std::vector* getBufferedDeleteDocIDs(); + + // Reset buffered deletes. + void clearBufferedDeletes(); + + bool bufferDeleteTerms(const CL_NS(util)::ArrayBase* terms); + + bool bufferDeleteTerm(Term* term); + + void setMaxBufferedDeleteTerms(int32_t maxBufferedDeleteTerms); + + int32_t getMaxBufferedDeleteTerms(); + + bool hasDeletes(); + + int64_t getRAMUsed(); + + int64_t numBytesAlloc; + int64_t numBytesUsed; + + /* Used only when writing norms to fill in default norm + * value into the holes in docID stream for those docs + * that didn't have this field. */ + static void fillBytes(CL_NS(store)::IndexOutput* out, uint8_t b, int32_t numBytes); + + uint8_t* copyByteBuffer; + + /** Copy numBytes from srcIn to destIn */ + void copyBytes(CL_NS(store)::IndexInput* srcIn, CL_NS(store)::IndexOutput* destIn, int64_t numBytes); + + + // Size of each slice. These arrays should be at most 16 + // elements. First array is just a compact way to encode + // X+1 with a max. Second array is the length of each + // slice, ie first slice is 5 bytes, next slice is 14 + // bytes, etc. + static const int32_t nextLevelArray[10]; + static const int32_t levelSizeArray[10]; + + // Why + 5*POINTER_NUM_BYTE below? + // 1: Posting has "vector" field which is a pointer + // 2: Posting is referenced by postingsFreeList array + // 3,4,5: Posting is referenced by postings hash, which + // targets 25-50% fill factor; approximate this + // as 3X # pointers + //TODO: estimate this accurately for C++! + static const int32_t POSTING_NUM_BYTE; /// = OBJECT_HEADER_BYTES + 9*INT_NUM_BYTE + 5*POINTER_NUM_BYTE; + + /* Allocate more Postings from shared pool */ + void getPostings(CL_NS(util)::ValueArray& postings); + void recyclePostings(CL_NS(util)::ValueArray& postings, int32_t numPostings); + + /* Initial chunks size of the shared uint8_t[] blocks used to + store postings data */ + static const int32_t BYTE_BLOCK_SHIFT; + static const int32_t BYTE_BLOCK_SIZE; + static const int32_t BYTE_BLOCK_MASK; + static const int32_t BYTE_BLOCK_NOT_MASK; + + /* Allocate another uint8_t[] from the shared pool */ + uint8_t* getByteBlock(bool trackAllocations); + + /* Return a uint8_t[] to the pool */ + void recycleBlocks(CL_NS(util)::ArrayBase& blocks, int32_t start, int32_t end); + + /* Initial chunk size of the shared char[] blocks used to + store term text */ + static const int32_t CHAR_BLOCK_SHIFT; + static const int32_t CHAR_BLOCK_SIZE; + static const int32_t CHAR_BLOCK_MASK; + + static const int32_t MAX_TERM_LENGTH; + + /* Allocate another char[] from the shared pool */ + TCHAR* getCharBlock(); + + /* Return a char[] to the pool */ + void recycleBlocks(CL_NS(util)::ArrayBase& blocks, int32_t start, int32_t numBlocks); + + std::string toMB(int64_t v); + + +}; + +#define CLUCENE_END_OF_WORD 0x0 + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_FieldInfo.h b/src/core/CLucene/index/_FieldInfo.h new file mode 100644 index 00000000000..506499fbd00 --- /dev/null +++ b/src/core/CLucene/index/_FieldInfo.h @@ -0,0 +1,13 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_FieldInfo_ +#define _lucene_index_FieldInfo_ + + +#error "This header is deprecated, use _FieldInfos.h instead" + +#endif diff --git a/src/core/CLucene/index/_FieldInfos.h b/src/core/CLucene/index/_FieldInfos.h new file mode 100644 index 00000000000..99f0c6f399a --- /dev/null +++ b/src/core/CLucene/index/_FieldInfos.h @@ -0,0 +1,199 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_FieldInfos_ +#define _lucene_index_FieldInfos_ + +#include "CLucene/store/Directory.h" + +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(document,Field) + +CL_NS_DEF(index) + +class FieldInfo :LUCENE_BASE{ + public: + //name of the field + const TCHAR* name; + + //Is field indexed? true = yes false = no + bool isIndexed; + bool duplicateName; + + //field number + const int32_t number; + + // true if term vector for this field should be stored + bool storeTermVector; + bool storeOffsetWithTermVector; + bool storePositionWithTermVector; + + bool omitNorms; // omit norms associated with indexed fields + + bool storePayloads; // whether this field stores payloads together with term positions + + //Func - Constructor + // Initialises FieldInfo. + // na holds the name of the field + // tk indicates whether this field is indexed or not + // nu indicates its number + //Pre - na != NULL and holds the name of the field + // tk is true or false + // number >= 0 + //Post - The FieldInfo instance has been created and initialized. + // name holds the duplicated string of na + // isIndexed = tk + // number = nu + FieldInfo(const TCHAR* fieldName, + const bool isIndexed, + const int32_t fieldNumber, + const bool storeTermVector, + const bool storeOffsetWithTermVector, + const bool storePositionWithTermVector, + const bool omitNorms, + const bool storePayloads); + + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + ~FieldInfo(); + + /* Clones this + * @memory - caller is responsible for deleting the returned object + */ + FieldInfo* clone(); +}; + +/** Access to the Field Info file that describes document fields and whether or + * not they are indexed. Each segment has a separate Field Info file. Objects + * of this class are thread-safe for multiple readers, but only one thread can + * be adding documents at a time, with no other reader or writer threads + * accessing this object. + */ +class CLUCENE_EXPORT FieldInfos :LUCENE_BASE{ + //we now use internd field names, so we can use the voidCompare + //to directly compare the strings + typedef CL_NS(util)::CLHashMap defByName; + defByName byName; + + CL_NS(util)::CLArrayList > byNumber; +public: + enum{ + IS_INDEXED = 0x1, + STORE_TERMVECTOR = 0x2, + STORE_POSITIONS_WITH_TERMVECTOR = 0x4, + STORE_OFFSET_WITH_TERMVECTOR = 0x8, + OMIT_NORMS = 0x10, + STORE_PAYLOADS = 0x20 + }; + + FieldInfos(); + ~FieldInfos(); + + /** + * Construct a FieldInfos object using the directory and the name of the file + * IndexInput + * @param d The directory to open the IndexInput from + * @param name The name of the file to open the IndexInput from in the Directory + * @throws IOException + */ + FieldInfos(CL_NS(store)::Directory* d, const char* name); + + /** + * Returns a deep clone of this FieldInfos instance. + * @memory caller is responisble for deleting returned object + */ + FieldInfos* clone(); + + /** Adds field info for a Document. */ + void add(const CL_NS(document)::Document* doc); + + /** + * Add fields that are indexed. Whether they have termvectors has to be specified. + * + * @param names The names of the fields. An array of TCHARs, last item has to be NULL + * @param storeTermVectors Whether the fields store term vectors or not + * @param storePositionWithTermVector treu if positions should be stored. + * @param storeOffsetWithTermVector true if offsets should be stored + */ + void addIndexed(const TCHAR** names, const bool storeTermVectors, const bool storePositionWithTermVector, const bool storeOffsetWithTermVector); + + /** + * Assumes the fields are not storing term vectors. + * + * @param names The names of the fields + * @param isIndexed Whether the fields are indexed or not + * + * @see #add(TCHAR*, bool) + */ + void add(const TCHAR** names, const bool isIndexed, const bool storeTermVector=false, + const bool storePositionWithTermVector=false, const bool storeOffsetWithTermVector=false, + const bool omitNorms=false, const bool storePayloads=false); + + // Merges in information from another FieldInfos. + void add(FieldInfos* other); + + /** If the field is not yet known, adds it. If it is known, checks to make + * sure that the isIndexed flag is the same as was given previously for this + * field. If not - marks it as being indexed. Same goes for the TermVector + * parameters. + * + * @param name The name of the field + * @param isIndexed true if the field is indexed + * @param storeTermVector true if the term vector should be stored + * @param storePositionWithTermVector true if the term vector with positions should be stored + * @param storeOffsetWithTermVector true if the term vector with offsets should be stored + * @param omitNorms true if the norms for the indexed field should be omitted + * @param storePayloads true if payloads should be stored for this field + */ + FieldInfo* add(const TCHAR* name, const bool isIndexed, const bool storeTermVector=false, + const bool storePositionWithTermVector=false, const bool storeOffsetWithTermVector=false, const bool omitNorms=false, const bool storePayloads=false); + + // was void + FieldInfo* addInternal( const TCHAR* name,const bool isIndexed, const bool storeTermVector, + const bool storePositionWithTermVector, const bool storeOffsetWithTermVector, const bool omitNorms, const bool storePayloads); + + int32_t fieldNumber(const TCHAR* fieldName)const; + + /** + * Return the fieldinfo object referenced by the fieldNumber. + * @param fieldNumber + * @return the FieldInfo object or null when the given fieldNumber + * doesn't exist. + */ + FieldInfo* fieldInfo(const TCHAR* fieldName) const; + + /** + * Return the fieldName identified by its number. + * + * @param fieldNumber + * @return the fieldName or an empty string when the field + * with the given number doesn't exist. + */ + const TCHAR* fieldName(const int32_t fieldNumber)const; + + /** + * Return the fieldinfo object referenced by the fieldNumber. + * @param fieldNumber + * @return the FieldInfo object or null when the given fieldNumber + * doesn't exist. + */ + FieldInfo* fieldInfo(const int32_t fieldNumber) const; + + size_t size()const; + bool hasVectors() const; + + + void write(CL_NS(store)::Directory* d, const char* name) const; + void write(CL_NS(store)::IndexOutput* output) const; + +private: + void read(CL_NS(store)::IndexInput* input); + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_FieldsReader.h b/src/core/CLucene/index/_FieldsReader.h new file mode 100644 index 00000000000..33aec75acc2 --- /dev/null +++ b/src/core/CLucene/index/_FieldsReader.h @@ -0,0 +1,169 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_FieldsReader_ +#define _lucene_index_FieldsReader_ + +#include "CLucene/util/_ThreadLocal.h" +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(document,Document) +#include "CLucene/document/Field.h" +CL_CLASS_DEF(document,FieldSelector) +CL_CLASS_DEF(index, FieldInfo) +CL_CLASS_DEF(index, FieldInfos) +CL_CLASS_DEF(store,IndexInput) + +CL_NS_DEF(index) + + /** + * Class responsible for access to stored document fields. + *

+ * It uses <segment>.fdt and <segment>.fdx; files. + */ + class FieldsReader :LUCENE_BASE{ + private: + const FieldInfos* fieldInfos; + + // The main fieldStream, used only for cloning. + CL_NS(store)::IndexInput* cloneableFieldsStream; + + // This is a clone of cloneableFieldsStream used for reading documents. + // It should not be cloned outside of a synchronized context. + CL_NS(store)::IndexInput* fieldsStream; + + CL_NS(store)::IndexInput* indexStream; + int32_t numTotalDocs; + int32_t _size; + bool closed; + + // The docID offset where our docs begin in the index + // file. This will be 0 if we have our own private file. + int32_t docStoreOffset; + + DEFINE_MUTEX(THIS_LOCK) + CL_NS(util)::ThreadLocal > fieldsStreamTL; + static void uncompress(const CL_NS(util)::ValueArray& input, CL_NS(util)::ValueArray& output); + public: + FieldsReader(CL_NS(store)::Directory* d, const char* segment, FieldInfos* fn, + int32_t readBufferSize = CL_NS(store)::BufferedIndexInput::BUFFER_SIZE, int32_t docStoreOffset = -1, int32_t size = 0); + virtual ~FieldsReader(); + + //protected: + /** + * @throws an exception (CL_ERR_IllegalState) if this FieldsReader is closed + */ + void ensureOpen(); + + /** + * Closes the underlying {@link org.apache.lucene.store.IndexInput} streams, including any ones associated with a + * lazy implementation of a Field. This means that the Fields values will not be accessible. + * + * @throws IOException + */ + void close(); + + int32_t size() const; + + /** Loads the fields from n'th document into doc. returns true on success. */ + bool doc(int32_t n, CL_NS(document)::Document& doc, const CL_NS(document)::FieldSelector* fieldSelector = NULL); + + protected: + /** Returns the length in bytes of each raw document in a + * contiguous range of length numDocs starting with + * startDocID. Returns the IndexInput (the fieldStream), + * already seeked to the starting point for startDocID.*/ + CL_NS(store)::IndexInput* rawDocs(int32_t* lengths, const int32_t startDocID, const int32_t numDocs); + + private: + /** + * Skip the field. We still have to read some of the information about the field, but can skip past the actual content. + * This will have the most payoff on large fields. + */ + void skipField(const bool binary, const bool compressed); + void skipField(const bool binary, const bool compressed, const int32_t toRead); + + void addFieldLazy(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize); + + /** Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes) + * Read just the size -- caller must skip the field content to continue reading fields + * Return the size in bytes or chars, depending on field type + */ + int32_t addFieldSize(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed); + + // in merge mode we don't uncompress the data of a compressed field + void addFieldForMerge(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize); + + void addField(CL_NS(document)::Document& doc, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize); + + CL_NS(document)::Field::TermVector getTermVectorType(const FieldInfo* fi); + CL_NS(document)::Field::Index getIndexType(const FieldInfo* fi, const bool tokenize); + + private: + /** + * A Lazy implementation of Field that differs loading of fields until asked for, instead of when the Document is + * loaded. + */ + class LazyField : public CL_NS(document)::Field { + private: + int32_t toRead; + int64_t pointer; + FieldsReader* parent; + + public: + LazyField(FieldsReader* _parent, const TCHAR* _name, int config, const int32_t _toRead, const int64_t _pointer); + virtual ~LazyField(); + private: + CL_NS(store)::IndexInput* getFieldStream(); + + public: + /** The value of the field in Binary, or null. If null, the Reader value, + * String value, or TokenStream value is used. Exactly one of stringValue(), + * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ + virtual const CL_NS(util)::ValueArray* binaryValue(); + + /** The value of the field as a Reader, or null. If null, the String value, + * binary value, or TokenStream value is used. Exactly one of stringValue(), + * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ + virtual CL_NS(util)::Reader* readerValue(); + + /** The value of the field as a String, or null. If null, the Reader value, + * binary value, or TokenStream value is used. Exactly one of stringValue(), + * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ + virtual const TCHAR* stringValue(); + + /** The value of the field as a TokesStream, or null. If null, the Reader value, + * String value, or binary value is used. Exactly one of stringValue(), + * readerValue(), binaryValue(), and tokenStreamValue() must be set. */ + virtual CL_NS(analysis)::TokenStream* tokenStreamValue(); + + int64_t getPointer() const; + void setPointer(const int64_t _pointer); + + int32_t getToRead() const; + void setToRead(const int32_t _toRead); + }; + friend class LazyField; + friend class SegmentMerger; + friend class FieldsWriter; + + // Instances of this class hold field properties and data + // for merge + class FieldForMerge : public CL_NS(document)::Field { + public: + const TCHAR* stringValue() const; + CL_NS(util)::Reader* readerValue() const; + const CL_NS(util)::ValueArray* binaryValue(); + CL_NS(analysis)::TokenStream* tokenStreamValue() const; + + FieldForMerge(void* _value, ValueType _type, const FieldInfo* fi, const bool binary, const bool compressed, const bool tokenize); + virtual ~FieldForMerge(); + + virtual const char* getObjectName() const; + static const char* getClassName(); + }; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_FieldsWriter.h b/src/core/CLucene/index/_FieldsWriter.h new file mode 100644 index 00000000000..d0622aa9782 --- /dev/null +++ b/src/core/CLucene/index/_FieldsWriter.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_FieldsWriter_ +#define _lucene_index_FieldsWriter_ + +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(store,IndexOutput) +CL_CLASS_DEF(store,IndexInput) +CL_CLASS_DEF(index,FieldInfo) +CL_CLASS_DEF(store,RAMOutputStream) +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(document,Field) +CL_CLASS_DEF(index,FieldInfos) +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) +class FieldsWriter :LUCENE_BASE{ +private: + FieldInfos* fieldInfos; + + CL_NS(store)::IndexOutput* fieldsStream; + CL_NS(store)::IndexOutput* indexStream; + + bool doClose; + + static void compress(const CL_NS(util)::ValueArray& input, CL_NS(util)::ValueArray& output); + +public: + LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_TOKENIZED = 0x1); + LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_BINARY = 0x2); + LUCENE_STATIC_CONSTANT(uint8_t, FIELD_IS_COMPRESSED = 0x4); + + FieldsWriter(CL_NS(store)::Directory* d, const char* segment, FieldInfos* fn); + FieldsWriter(CL_NS(store)::IndexOutput* fdx, CL_NS(store)::IndexOutput* fdt, FieldInfos* fn); + ~FieldsWriter(); + + // Writes the contents of buffer into the fields stream + // and adds a new entry for this document into the index + // stream. This assumes the buffer was already written + // in the correct fields format. + void flushDocument(int32_t numStoredFields, CL_NS(store)::RAMOutputStream* buffer); + + void flush(); + + void writeField(FieldInfo* fi, CL_NS(document)::Field* field); + + void close(); + + /** Bulk write a contiguous series of documents. The + * lengths array is the length (in bytes) of each raw + * document. The stream IndexInput is the + * fieldsStream from which we should bulk-copy all + * bytes. */ + void addRawDocuments(CL_NS(store)::IndexInput* stream, const int32_t* lengths, const int32_t numDocs); + void addDocument(CL_NS(document)::Document* doc); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_IndexFileDeleter.h b/src/core/CLucene/index/_IndexFileDeleter.h new file mode 100644 index 00000000000..c47fb4d090e --- /dev/null +++ b/src/core/CLucene/index/_IndexFileDeleter.h @@ -0,0 +1,224 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_IndexFileDeleter_ +#define _lucene_index_IndexFileDeleter_ + +#include "CLucene/util/Equators.h" +#include "IndexDeletionPolicy.h" + +CL_CLASS_DEF(store,Directory) +CL_NS_DEF(index) +class SegmentInfos; +class IDocumentsWriter; +class IndexDeletionPolicy; + +/* + * This class keeps track of each SegmentInfos instance that + * is still "live", either because it corresponds to a + * segments_N file in the Directory (a "commit", i.e. a + * committed SegmentInfos) or because it's the in-memory SegmentInfos + * that a writer is actively updating but has not yet committed + * (currently this only applies when autoCommit=false in IndexWriter). + * This class uses simple reference counting to map the live + * SegmentInfos instances to individual files in the Directory. + * + * The same directory file may be referenced by more than + * one IndexCommitPoints, i.e. more than one SegmentInfos. + * Therefore we count how many commits reference each file. + * When all the commits referencing a certain file have been + * deleted, the refcount for that file becomes zero, and the + * file is deleted. + * + * A separate deletion policy interface + * (IndexDeletionPolicy) is consulted on creation (onInit) + * and once per commit (onCommit), to decide when a commit + * should be removed. + * + * It is the business of the IndexDeletionPolicy to choose + * when to delete commit points. The actual mechanics of + * file deletion, retrying, etc, derived from the deletion + * of commit points is the business of the IndexFileDeleter. + * + * The current default deletion policy is {@link + * KeepOnlyLastCommitDeletionPolicy}, which removes all + * prior commits when a new commit has completed. This + * matches the behavior before 2.2. + * + * Note that you must hold the write.lock before + * instantiating this class. It opens segments_N file(s) + * directly with no retry logic. + */ +class IndexFileDeleter { +private: + /** + * Tracks the reference count for a single index file: + */ + class RefCount { + public: + int count; + int IncRef() { + return ++count; + } + int DecRef() { + return --count; + } + }; + + /** + * Holds details for each commit point. This class is + * also passed to the deletion policy. Note: this class + * has a natural ordering that is inconsistent with + * equals. + */ + class CommitPoint: public IndexCommitPoint, public CL_NS(util)::Comparable { + int64_t gen; + std::string segmentsFileName; + IndexFileDeleter* _this; + public: + std::vector files; + bool deleted; + + CommitPoint(IndexFileDeleter* _this, SegmentInfos* segmentInfos); + virtual ~CommitPoint(); + + /** + * Get the segments_N file for this commit point. + */ + std::string getSegmentsFileName(); + + const std::vector& getFileNames(); + + /** + * Called only be the deletion policy, to remove this + * commit point from the index. + */ + void deleteCommitPoint(); + + int32_t compareTo(NamedObject* obj); + + static const char* getClassName(); + const char* getObjectName() const; + static bool sort(IndexCommitPoint* elem1, IndexCommitPoint* elem2); + }; + +private: + /* Files that we tried to delete but failed (likely + * because they are open and we are running on Windows), + * so we will retry them again later: */ + std::vector deletable; + + typedef CL_NS(util)::CLHashMap > RefCountsType; + /* Reference count for all files in the index. + * Counts how many existing commits reference a file. + * Maps String to RefCount (class below) instances: */ + RefCountsType refCounts; + + typedef CL_NS(util)::CLVector > CommitsType; + /* Holds all commits (segments_N) currently in the index. + * This will have just 1 commit if you are using the + * default delete policy (KeepOnlyLastCommitDeletionPolicy). + * Other policies may leave commit points live for longer + * in which case this list would be longer than 1: */ + CommitsType commits; + + /* Holds files we had incref'd from the previous + * non-commit checkpoint: */ + std::vector lastFiles; + + /* Commits that the IndexDeletionPolicy have decided to delete: */ + CL_NS(util)::CLArrayList commitsToDelete; + + std::ostream* infoStream; + CL_NS(store)::Directory* directory; + IndexDeletionPolicy* policy; + IDocumentsWriter* docWriter; + + +public: + void deletePendingFiles(); + + void setInfoStream(std::ostream* infoStream); + void message(std::string message); + void decRef(const std::string& fileName); + RefCount* getRefCount(const char* fileName); + + /** + * Remove the CommitPoints in the commitsToDelete List by + * DecRef'ing all files from each SegmentInfos. + */ + void deleteCommits(); + + /** Change to true to see details of reference counts when + * infoStream != null */ + static bool VERBOSE_REF_COUNTS; + + /** + * Initialize the deleter: find all previous commits in + * the Directory, incref the files they reference, call + * the policy to let it delete commits. The incoming + * segmentInfos must have been loaded from a commit point + * and not yet modified. This will remove any files not + * referenced by any of the commits. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + IndexFileDeleter(CL_NS(store)::Directory* directory, IndexDeletionPolicy* policy, SegmentInfos* segmentInfos, std::ostream* infoStream, IDocumentsWriter* docWriter); + ~IndexFileDeleter(); + + /** + * Writer calls this when it has hit an error and had to + * roll back, to tell us that there may now be + * unreferenced files in the filesystem. So we re-list + * the filesystem and delete such files. If segmentName + * is non-null, we will only delete files corresponding to + * that segment. + */ + void refresh(const char* segmentName); + void refresh(); + void close(); + + /** + * For definition of "check point" see IndexWriter comments: + * "Clarification: Check Points (and commits)". + * + * Writer calls this when it has made a "consistent + * change" to the index, meaning new files are written to + * the index and the in-memory SegmentInfos have been + * modified to point to those files. + * + * This may or may not be a commit (segments_N may or may + * not have been written). + * + * We simply incref the files referenced by the new + * SegmentInfos and decref the files we had previously + * seen (if any). + * + * If this is a commit, we also call the policy to give it + * a chance to remove other commits. If any commits are + * removed, we decref their files as well. + */ + void checkpoint(SegmentInfos* segmentInfos, bool isCommit); + + + void CLUCENE_LOCAL_DECL incRef(SegmentInfos* segmentInfos, bool isCommit); + void CLUCENE_LOCAL_DECL incRef(const std::vector& files); + void CLUCENE_LOCAL_DECL decRef(const std::vector& files) ; + void CLUCENE_LOCAL_DECL decRef(SegmentInfos* segmentInfos); + void CLUCENE_LOCAL_DECL deleteFiles(std::vector& files); + + /** Delets the specified files, but only if they are new + * (have not yet been incref'd). */ + void CLUCENE_LOCAL_DECL deleteNewFiles(const std::vector& files); + void CLUCENE_LOCAL_DECL deleteFile(const char* fileName); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_IndexFileNameFilter.h b/src/core/CLucene/index/_IndexFileNameFilter.h new file mode 100644 index 00000000000..c825e6a4918 --- /dev/null +++ b/src/core/CLucene/index/_IndexFileNameFilter.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_IndexFileNameFilter_ +#define _lucene_index_IndexFileNameFilter_ + +#include "CLucene/util/Equators.h" +#include "CLucene/util/VoidList.h" + +CL_NS_DEF(index) +class FilenameFilter{ +public: + virtual bool accept(const char* dir, const char* name) const = 0; + virtual ~FilenameFilter(); +}; + +/** + * Filename filter that accept filenames and extensions only created by Lucene. + * + * @author Daniel Naber / Bernhard Messer + * @version $rcs = ' $Id: Exp $ ' ; + */ +class IndexFileNameFilter: public FilenameFilter { + static IndexFileNameFilter* _singleton; + static IndexFileNameFilter* singleton(); + CL_NS(util)::CLHashSet extensions; + CL_NS(util)::CLHashSet extensionsInCFS; +public: + IndexFileNameFilter(); + virtual ~IndexFileNameFilter(); + + /* (non-Javadoc) + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) + */ + bool accept(const char* dir, const char* name) const; + + /** + * Returns true if this is a file that would be contained + * in a CFS file. This function should only be called on + * files that pass the above "accept" (ie, are already + * known to be a Lucene index file). + */ + bool isCFSFile(const char* name) const; + static const IndexFileNameFilter* getFilter(); + + static void _shutdown(); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_IndexFileNames.h b/src/core/CLucene/index/_IndexFileNames.h new file mode 100644 index 00000000000..e93687e0de2 --- /dev/null +++ b/src/core/CLucene/index/_IndexFileNames.h @@ -0,0 +1,55 @@ + +#ifndef _lucene_index_IndexFileNames_ +#define _lucene_index_IndexFileNames_ + +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +class CLUCENE_EXPORT IndexFileNames { + static CL_NS(util)::ConstValueArray _INDEX_EXTENSIONS; + static CL_NS(util)::ConstValueArray _INDEX_EXTENSIONS_IN_COMPOUND_FILE; + static CL_NS(util)::ConstValueArray _STORE_INDEX_EXTENSIONS; + static CL_NS(util)::ConstValueArray _NON_STORE_INDEX_EXTENSIONS; + static CL_NS(util)::ConstValueArray _COMPOUND_EXTENSIONS; + static CL_NS(util)::ConstValueArray _VECTOR_EXTENSIONS; +public: + static const char* SEGMENTS; + static const char* SEGMENTS_GEN; + static const char* DELETABLE; + static const char* NORMS_EXTENSION; + static const char* FREQ_EXTENSION; + static const char* PROX_EXTENSION; + static const char* TERMS_EXTENSION; + static const char* TERMS_INDEX_EXTENSION; + static const char* FIELDS_INDEX_EXTENSION; + static const char* FIELDS_EXTENSION; + static const char* VECTORS_FIELDS_EXTENSION; + static const char* VECTORS_DOCUMENTS_EXTENSION; + static const char* VECTORS_INDEX_EXTENSION; + static const char* COMPOUND_FILE_EXTENSION; + static const char* COMPOUND_FILE_STORE_EXTENSION; + static const char* DELETES_EXTENSION; + static const char* FIELD_INFOS_EXTENSION; + static const char* PLAIN_NORMS_EXTENSION; + static const char* SEPARATE_NORMS_EXTENSION; + static const char* GEN_EXTENSION; + + LUCENE_STATIC_CONSTANT(int32_t,COMPOUND_EXTENSIONS_LENGTH=7); + LUCENE_STATIC_CONSTANT(int32_t,VECTOR_EXTENSIONS_LENGTH=3); + LUCENE_STATIC_CONSTANT(int32_t,STORE_INDEX_EXTENSIONS_LENGTH=5); + + static CL_NS(util)::ConstValueArray& INDEX_EXTENSIONS(); + static CL_NS(util)::ConstValueArray& INDEX_EXTENSIONS_IN_COMPOUND_FILE(); + static CL_NS(util)::ConstValueArray& STORE_INDEX_EXTENSIONS(); + static CL_NS(util)::ConstValueArray& NON_STORE_INDEX_EXTENSIONS(); + static CL_NS(util)::ConstValueArray& COMPOUND_EXTENSIONS(); + static CL_NS(util)::ConstValueArray& VECTOR_EXTENSIONS(); + + static std::string fileNameFromGeneration( const char* base, const char* extension, int64_t gen ); + static bool isDocStoreFile( const char* fileName ); + +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_MultiSegmentReader.h b/src/core/CLucene/index/_MultiSegmentReader.h new file mode 100644 index 00000000000..1ad94a85ffa --- /dev/null +++ b/src/core/CLucene/index/_MultiSegmentReader.h @@ -0,0 +1,232 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_MultiSegmentReader +#define _lucene_index_MultiSegmentReader + + +#include "DirectoryIndexReader.h" +#include "IndexReader.h" +CL_CLASS_DEF(document,Document) +//#include "Terms.h" +#include "_SegmentHeader.h" + +CL_NS_DEF(index) +class SegmentMergeQueue; + +class MultiSegmentReader:public DirectoryIndexReader{ + static int32_t readerIndex(const int32_t n, int32_t* starts, int32_t numSubReaders); +public: + typedef CL_NS(util)::CLHashtable > NormsCacheType; +private: + int32_t readerIndex(int32_t n) const; + bool hasNorms(const TCHAR* field); + uint8_t* fakeNorms(); + + void startCommit(); + void rollbackCommit(); + + bool _hasDeletions; + uint8_t* ones; + NormsCacheType normsCache; + int32_t _maxDoc; + int32_t _numDocs; + +protected: + CL_NS(util)::ArrayBase* subReaders; + int32_t* starts; // 1st docno for each segment + + void doSetNorm(int32_t n, const TCHAR* field, uint8_t value); + void doUndeleteAll(); + void commitChanges(); + // synchronized + void doClose(); + + // synchronized + void doDelete(const int32_t n); + DirectoryIndexReader* doReopen(SegmentInfos* infos); + + void initialize( CL_NS(util)::ArrayBase* subReaders); + +public: + + /** Construct reading the named set of readers. */ + MultiSegmentReader(CL_NS(store)::Directory* directory, SegmentInfos* sis, bool closeDirectory); + + /** This contructor is only used for {@link #reopen()} */ + CLUCENE_LOCAL_DECL MultiSegmentReader( + CL_NS(store)::Directory* directory, + SegmentInfos* sis, + bool closeDirectory, + CL_NS(util)::ArrayBase* oldReaders, + int32_t* oldStarts, + NormsCacheType* oldNormsCache); + + virtual ~MultiSegmentReader(); + + /** Return an array of term frequency vectors for the specified document. + * The array contains a vector for each vectorized field in the document. + * Each vector vector contains term numbers and frequencies for all terms + * in a given vectorized field. + * If no such fields existed, the method returns null. + */ + TermFreqVector* getTermFreqVector(int32_t docNumber, const TCHAR* field=NULL); + CL_NS(util)::ArrayBase* getTermFreqVectors(int32_t docNumber); + void getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper); + void getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper); + bool isOptimized(); + + // synchronized + int32_t numDocs(); + + int32_t maxDoc() const; + + bool document(int32_t n, CL_NS(document)::Document& doc, const CL_NS(document)::FieldSelector* fieldSelector); + + bool isDeleted(const int32_t n); + bool hasDeletions() const; + + // synchronized + uint8_t* norms(const TCHAR* field); + void norms(const TCHAR* field, uint8_t* result); + + TermEnum* terms(); + TermEnum* terms(const Term* term); + + //Returns the document frequency of the current term in the set + int32_t docFreq(const Term* t=NULL); + TermDocs* termDocs(); + TermPositions* termPositions(); + + void getFieldNames (FieldOption fldOption, StringArrayWithDeletor& retarray); + static void getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray, CL_NS(util)::ArrayBase* subReaders); + + void setTermInfosIndexDivisor(int32_t indexDivisor); + int32_t getTermInfosIndexDivisor(); + + const CL_NS(util)::ArrayBase* getSubReaders() const; + + friend class MultiReader; + friend class SegmentReader; + friend class DirectoryIndexReader; + + static const char* getClassName(); + const char* getObjectName() const; +}; + + +class MultiTermDocs:public virtual TermDocs { +protected: + CL_NS(util)::ArrayBase* readerTermDocs; + + CL_NS(util)::ArrayBase* subReaders; + const int32_t* starts; + Term* term; + + int32_t base; + size_t pointer; + + TermDocs* current; // == segTermDocs[pointer] + TermDocs* termDocs(const int32_t i); //< internal use only + virtual TermDocs* termDocs(IndexReader* reader); + void init(CL_NS(util)::ArrayBase* subReaders, const int32_t* starts); +public: + MultiTermDocs(); + MultiTermDocs(CL_NS(util)::ArrayBase* subReaders, const int32_t* s); + virtual ~MultiTermDocs(); + + int32_t doc() const; + int32_t freq() const; + + void seek(TermEnum* termEnum); + void seek(Term* tterm); + bool next(); + + /** Optimized implementation. */ + int32_t read(int32_t* docs, int32_t* freqs, int32_t length); + + /* A Possible future optimization could skip entire segments */ + bool skipTo(const int32_t target); + + void close(); + + virtual TermPositions* __asTermPositions(); +}; + + +//MultiTermEnum represents the enumeration of all terms of all readers +class MultiTermEnum:public TermEnum { +private: + SegmentMergeQueue* queue; + + Term* _term; + int32_t _docFreq; +public: + //Constructor + //Opens all enumerations of all readers + MultiTermEnum(CL_NS(util)::ArrayBase* subReaders, const int32_t* starts, const Term* t); + + //Destructor + ~MultiTermEnum(); + + //Move the current term to the next in the set of enumerations + bool next(); + + //Returns a pointer to the current term of the set of enumerations + Term* term(bool pointer=true); + + //Returns the document frequency of the current term in the set + int32_t docFreq() const; + + //Closes the set of enumerations in the queue + void close(); + + + const char* getObjectName() const; + static const char* getClassName(); +}; + + +#ifdef _MSC_VER + #pragma warning(disable : 4250) +#endif +class MultiTermPositions:public MultiTermDocs,public TermPositions { +protected: + TermDocs* termDocs(IndexReader* reader); +public: + MultiTermPositions(CL_NS(util)::ArrayBase* subReaders, const int32_t* s); + virtual ~MultiTermPositions() {}; + int32_t nextPosition(); + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + int32_t getPayloadLength() const; + + /** + * Not implemented. + * @throws UnsupportedOperationException + */ + uint8_t* getPayload(uint8_t* data); + + /** + * + * @return false + */ + // TODO: Remove warning after API has been finalized + bool isPayloadAvailable() const; + + virtual TermDocs* __asTermDocs(); + virtual TermPositions* __asTermPositions(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SegmentHeader.h b/src/core/CLucene/index/_SegmentHeader.h new file mode 100644 index 00000000000..7eaece9faa1 --- /dev/null +++ b/src/core/CLucene/index/_SegmentHeader.h @@ -0,0 +1,451 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentHeader_ +#define _lucene_index_SegmentHeader_ + +#include "_SegmentInfos.h" +#include "CLucene/util/BitSet.h" +//#include "CLucene/util/VoidMap.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/index/IndexReader.h" +#include "Term.h" +#include "Terms.h" +#include "_TermInfo.h" +//#include "FieldInfos.h" +#include "_FieldsReader.h" +#include "_TermVector.h" +//#include "IndexReader.h" +#include "_TermInfosReader.h" +#include "_CompoundFile.h" +#include "DirectoryIndexReader.h" +#include "_SkipListReader.h" +#include "CLucene/util/_ThreadLocal.h" + +CL_NS_DEF(index) +class SegmentReader; + +class SegmentTermDocs:public virtual TermDocs { +protected: + const SegmentReader* parent; + CL_NS(store)::IndexInput* freqStream; + int32_t count; + int32_t df; + CL_NS(util)::BitSet* deletedDocs; + int32_t _doc; + int32_t _freq; + int32_t docs[PFOR_BLOCK_SIZE]; // buffered doc numbers + int32_t freqs[PFOR_BLOCK_SIZE]; // buffered term freqs + int32_t pointer; + int32_t pointerMax; + +private: + int32_t skipInterval; + int32_t maxSkipLevels; + DefaultSkipListReader* skipListReader; + + int64_t freqBasePointer; + int64_t proxBasePointer; + + int64_t skipPointer; + bool haveSkipped; + +protected: + bool currentFieldStoresPayloads; + +public: + ///\param Parent must be a segment reader + SegmentTermDocs( const SegmentReader* Parent); + virtual ~SegmentTermDocs(); + + virtual void seek(Term* term); + virtual void seek(TermEnum* termEnum); + virtual void seek(const TermInfo* ti,Term* term); + + virtual void close(); + virtual int32_t doc()const; + virtual int32_t freq()const; + + virtual bool next(); + + /** Optimized implementation. */ + virtual int32_t read(int32_t* docs, int32_t* freqs, int32_t length); + + /** Optimized implementation. */ + virtual bool skipTo(const int32_t target); + + virtual TermPositions* __asTermPositions(); + +protected: + virtual void skippingDoc(){} + virtual void skipProx(const int64_t /*proxPointer*/, const int32_t /*payloadLength*/){} +}; + + +class SegmentTermPositions: public SegmentTermDocs, public TermPositions { +private: + CL_NS(store)::IndexInput* proxStream; + int32_t proxCount; + int32_t position; + + // the current payload length + int32_t payloadLength; + // indicates whether the payload of the currend position has + // been read from the proxStream yet + bool needToLoadPayload; + + // these variables are being used to remember information + // for a lazy skip + int64_t lazySkipPointer; + int32_t lazySkipProxCount; + +public: + ///\param Parent must be a segment reader + SegmentTermPositions(const SegmentReader* Parent); + virtual ~SegmentTermPositions(); + +private: + void seek(const TermInfo* ti, Term* term); + +public: + void close(); + + int32_t nextPosition(); +private: + int32_t readDeltaPosition(); + +protected: + void skippingDoc(); + +public: + bool next(); + int32_t read(int32_t* docs, int32_t* freqs, int32_t length); + +protected: + /** Called by super.skipTo(). */ + void skipProx(const int64_t proxPointer, const int32_t _payloadLength); + +private: + void skipPositions( int32_t n ); + void skipPayload(); + + // It is not always neccessary to move the prox pointer + // to a new document after the freq pointer has been moved. + // Consider for example a phrase query with two terms: + // the freq pointer for term 1 has to move to document x + // to answer the question if the term occurs in that document. But + // only if term 2 also matches document x, the positions have to be + // read to figure out if term 1 and term 2 appear next + // to each other in document x and thus satisfy the query. + // So we move the prox pointer lazily to the document + // as soon as positions are requested. + void lazySkip(); + +public: + int32_t getPayloadLength() const; + + uint8_t* getPayload(uint8_t* data); + + bool isPayloadAvailable() const; + +private: + virtual TermDocs* __asTermDocs(); + virtual TermPositions* __asTermPositions(); + + //resolve SegmentTermDocs/TermPositions ambiguity + void seek(Term* term){ SegmentTermDocs::seek(term); } + void seek(TermEnum* termEnum){ SegmentTermDocs::seek(termEnum); } + int32_t doc() const{ return SegmentTermDocs::doc(); } + int32_t freq() const{ return SegmentTermDocs::freq(); } + bool skipTo(const int32_t target){ return SegmentTermDocs::skipTo(target); } +}; + + + + +/** + * An IndexReader responsible for reading 1 segment of an index + */ +class SegmentReader: public DirectoryIndexReader { + /** + * The class Norm represents the normalizations for a field. + * These normalizations are read from an IndexInput in into an array of bytes called bytes + */ + class Norm :LUCENE_BASE{ + int32_t number; + int64_t normSeek; + SegmentReader* _this; + const char* segment; ///< pointer to segment name + volatile int32_t refCount; + bool useSingleNormStream; + bool rollbackDirty; + + + /** Closes the underlying IndexInput for this norm. + * It is still valid to access all other norm properties after close is called. + * @throws IOException + */ + void close(); + public: + DEFINE_MUTEX(THIS_LOCK) + + CL_NS(store)::IndexInput* in; + uint8_t* bytes; + bool dirty; + //Constructor + Norm(CL_NS(store)::IndexInput* instrm, bool useSingleNormStream, int32_t number, int64_t normSeek, SegmentReader* reader, const char* segment); + //Destructor + ~Norm(); + + void reWrite(SegmentInfo* si); + + void incRef(); + void decRef(); + friend class SegmentReader; + + static void doDelete(Norm* norm); + }; + friend class SegmentReader::Norm; + + //Holds the name of the segment that is being read + std::string segment; + SegmentInfo* si; + int32_t readBufferSize; + + //Indicates if there are documents marked as deleted + bool deletedDocsDirty; + bool normsDirty; + bool undeleteAll; + + bool rollbackDeletedDocsDirty; + bool rollbackNormsDirty; + bool rollbackUndeleteAll; + + + //Holds all norms for all fields in the segment + typedef CL_NS(util)::CLHashtable NormsType; + NormsType _norms; + + uint8_t* ones; + uint8_t* fakeNorms(); + + // optionally used for the .nrm file shared by multiple norms + CL_NS(store)::IndexInput* singleNormStream; + + // Compound File Reader when based on a compound file segment + CompoundFileReader* cfsReader; + CompoundFileReader* storeCFSReader; + + ///Reads the Field Info file + FieldsReader* fieldsReader; + TermVectorsReader* termVectorsReaderOrig; + CL_NS(util)::ThreadLocal >termVectorsLocal; + + void initialize(SegmentInfo* si, int32_t readBufferSize, bool doOpenStores, bool doingReopen); + + /** + * Create a clone from the initial TermVectorsReader and store it in the ThreadLocal. + * @return TermVectorsReader + */ + TermVectorsReader* getTermVectorsReader(); + + FieldsReader* getFieldsReader(); + FieldInfos* getFieldInfos(); + +protected: + ///Marks document docNum as deleted + void doDelete(const int32_t docNum); + void doUndeleteAll(); + void commitChanges(); + void doSetNorm(int32_t doc, const TCHAR* field, uint8_t value); + + // can return null if norms aren't stored + uint8_t* getNorms(const TCHAR* field); + + /** + * Decrements the RC of the norms this reader is using + */ + void decRefNorms(); + + + DirectoryIndexReader* doReopen(SegmentInfos* infos); + +public: + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static SegmentReader* get(SegmentInfo* si, bool doOpenStores=true); + + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static SegmentReader* get(SegmentInfo* si, int32_t readBufferSize, bool doOpenStores=true); + + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static SegmentReader* get(SegmentInfos* sis, SegmentInfo* si, bool closeDir); + + /** + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * @param readBufferSize defaults to BufferedIndexInput::BUFFER_SIZE + */ + static SegmentReader* get(CL_NS(store)::Directory* dir, SegmentInfo* si, + SegmentInfos* sis, + bool closeDir, bool ownDir, + int32_t readBufferSize=-1, + bool doOpenStores=true); + + + + SegmentReader(); + ///Destructor. + virtual ~SegmentReader(); + + ///Closes all streams to the files of a single segment + void doClose(); + + ///Checks if a segment managed by SegmentInfo si has deletions + static bool hasDeletions(const SegmentInfo* si); + bool hasDeletions() const; + bool hasNorms(const TCHAR* field); + + ///Returns all file names managed by this SegmentReader + void files(std::vector& retarray); + ///Returns an enumeration of all the Terms and TermInfos in the set. + TermEnum* terms(); + ///Returns an enumeration of terms starting at or after the named term t + TermEnum* terms(const Term* t); + + ///Gets the document identified by n + bool document(int32_t n, CL_NS(document)::Document& doc, const CL_NS(document)::FieldSelector* fieldSelector); + + ///Checks if the n-th document has been marked deleted + bool isDeleted(const int32_t n); + + ///Returns an unpositioned TermDocs enumerator. + TermDocs* termDocs(); + ///Returns an unpositioned TermPositions enumerator. + TermPositions* termPositions(); + + ///Returns the number of documents which contain the term t + int32_t docFreq(const Term* t); + + ///Returns the actual number of documents in the segment + int32_t numDocs(); + ///Returns the number of all the documents in the segment including the ones that have + ///been marked deleted + int32_t maxDoc() const; + + + void setTermInfosIndexDivisor(int32_t indexDivisor); + + int32_t getTermInfosIndexDivisor(); + + ///Returns the bytes array that holds the norms of a named field. + ///Returns fake norms if norms aren't available + uint8_t* norms(const TCHAR* field); + + ///Reads the Norms for field from disk + void norms(const TCHAR* field, uint8_t* bytes); + + ///concatenating segment with ext and x + std::string SegmentName(const char* ext, const int32_t x=-1); + ///Creates a filename in buffer by concatenating segment with ext and x + void SegmentName(char* buffer,int32_t bufferLen,const char* ext, const int32_t x=-1 ); + + /** + * @see IndexReader#getFieldNames(IndexReader.FieldOption fldOption) + */ + void getFieldNames(FieldOption fldOption, StringArrayWithDeletor& retarray); + + static bool usesCompoundFile(SegmentInfo* si); + + /** Return a term frequency vector for the specified document and field. The + * vector returned contains term numbers and frequencies for all terms in + * the specified field of this document, if the field had storeTermVector + * flag set. If the flag was not set, the method returns null. + * @throws IOException + */ + TermFreqVector* getTermFreqVector(int32_t docNumber, const TCHAR* field=NULL); + + void getTermFreqVector(int32_t docNumber, const TCHAR* field, TermVectorMapper* mapper); + void getTermFreqVector(int32_t docNumber, TermVectorMapper* mapper); + + /** Return an array of term frequency vectors for the specified document. + * The array contains a vector for each vectorized field in the document. + * Each vector vector contains term numbers and frequencies for all terms + * in a given vectorized field. + * If no such fields existed, the method returns null. + * @throws IOException + */ + CL_NS(util)::ArrayBase* getTermFreqVectors(int32_t docNumber); + + static const char* getClassName(); + const char* getObjectName() const; + + // for testing only + bool normsClosed(); + +private: + //Open all norms files for all fields + void openNorms(CL_NS(store)::Directory* cfsDir, int32_t readBufferSize); + + ///a bitVector that manages which documents have been deleted + CL_NS(util)::BitSet* deletedDocs; + ///an IndexInput to the frequency file + CL_NS(store)::IndexInput* freqStream; + ///For reading the fieldInfos file + FieldInfos* _fieldInfos; + ///For reading the Term Dictionary .tis file + TermInfosReader* tis; + ///an IndexInput to the prox file + CL_NS(store)::IndexInput* proxStream; + + static bool hasSeparateNorms(SegmentInfo* si); + static uint8_t* createFakeNorms(int32_t size); + + void loadDeletedDocs(); + SegmentReader* reopenSegment(SegmentInfo* si); + + /** Returns the field infos of this segment */ + FieldInfos* fieldInfos(); + + /** + * Return the name of the segment this reader is reading. + */ + const char* getSegmentName(); + + /** + * Return the SegmentInfo of the segment this reader is reading. + */ + SegmentInfo* getSegmentInfo(); + void setSegmentInfo(SegmentInfo* info); + void startCommit(); + void rollbackCommit(); + + //allow various classes to access the internals of this. this allows us to have + //a more tight idea of the package + friend class IndexReader; + friend class IndexWriter; + friend class SegmentTermDocs; + friend class SegmentTermPositions; + friend class MultiReader; + friend class MultiSegmentReader; + friend class SegmentMerger; +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SegmentInfos.h b/src/core/CLucene/index/_SegmentInfos.h new file mode 100644 index 00000000000..e79d9e54ae4 --- /dev/null +++ b/src/core/CLucene/index/_SegmentInfos.h @@ -0,0 +1,532 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentInfos_ +#define _lucene_index_SegmentInfos_ + + +//#include "IndexReader.h" +#include "CLucene/util/Misc.h" +#include "_IndexFileNames.h" +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(store,IndexInput) +CL_CLASS_DEF(store,IndexOutput) + +CL_NS_DEF(index) + + class SegmentInfo :LUCENE_BASE{ + public: + + LUCENE_STATIC_CONSTANT(int32_t, NO = -1); // e.g. no norms; no deletes; + LUCENE_STATIC_CONSTANT(int32_t, YES = 1); // e.g. have norms; have deletes; + LUCENE_STATIC_CONSTANT(int32_t, CHECK_DIR = 0); // e.g. must check dir to see if there are norms/deletions + LUCENE_STATIC_CONSTANT(int32_t, WITHOUT_GEN = 0); // a file name that has no GEN in it. + + std::string name; // unique name in dir + int32_t docCount; // number of docs in seg + CL_NS(store)::Directory* dir; // where segment resides + + private: + bool preLockless; // true if this is a segments file written before + // lock-less commits (2.1) + + int64_t delGen; // current generation of del file; NO if there + // are no deletes; CHECK_DIR if it's a pre-2.1 segment + // (and we must check filesystem); YES or higher if + // there are deletes at generation N + + CL_NS(util)::ValueArray normGen; // current generation of each field's norm file. + // If this array is null, for lockLess this means no + // separate norms. For preLockLess this means we must + // check filesystem. If this array is not null, its + // values mean: NO says this field has no separate + // norms; CHECK_DIR says it is a preLockLess segment and + // filesystem must be checked; >= YES says this field + // has separate norms with the specified generation + + int8_t isCompoundFile; // NO if it is not; YES if it is; CHECK_DIR if it's + // pre-2.1 (ie, must check file system to see + // if .cfs and .nrm exist) + + bool hasSingleNormFile; // true if this segment maintains norms in a single file; + // false otherwise + // this is currently false for segments populated by DocumentWriter + // and true for newly created merged segments (both + // compound and non compound). + + private: + + std::vector _files; // cached list of files that this segment uses + // in the Directory + + int64_t _sizeInBytes; // total byte size of all of our files (computed on demand) + + int32_t docStoreOffset; // if this segment shares stored fields & vectors, this + // offset is where in that file this segment's docs begin + std::string docStoreSegment; // name used to derive fields/vectors file we share with + // other segments + // This string is being interned. There might be a way around this, + // and if found, this would greatly improve perfomance. + + bool docStoreIsCompoundFile; // whether doc store files are stored in compound file (*.cfx) + + /* Called whenever any change is made that affects which + * files this segment has. */ + void clearFiles(); + + void addIfExists(std::vector& files, const std::string& fileName); + + public: + SegmentInfo(const char* _name, const int32_t _docCount, CL_NS(store)::Directory* _dir, + bool _isCompoundFile=SegmentInfo::CHECK_DIR, + bool _hasSingleNormFile=false, + int32_t _docStoreOffset = -1, + const char* _docStoreSegment = NULL, + bool _docStoreIsCompoundFile = false); + + /** + * Construct a new SegmentInfo instance by reading a + * previously saved SegmentInfo from input. + * + * @param dir directory to load from + * @param format format of the segments info file + * @param input input handle to read segment info from + */ + SegmentInfo(CL_NS(store)::Directory* dir, int32_t format, CL_NS(store)::IndexInput* input); + + ~SegmentInfo(); + + void setNumFields(const int32_t numFields); + int64_t sizeInBytes(); + bool hasDeletions() const; + + void advanceDelGen(); + void clearDelGen(); + + SegmentInfo* clone (); + + std::string getDelFileName() const; + + /** + * Returns true if this field for this segment has saved a separate norms file (__N.sX). + * + * @param fieldNumber the field index to check + */ + bool hasSeparateNorms(const int32_t fieldNumber) const; + + /** + * Returns true if any fields in this segment have separate norms. + */ + bool hasSeparateNorms() const; + + /** + * Get the file name for the norms file for this field. + * + * @param number field index + */ + std::string getNormFileName(const int32_t number) const; + + /** + * Increment the generation count for the norms file for + * this field. + * + * @param fieldIndex field whose norm file will be rewritten + */ + void advanceNormGen(const int32_t fieldIndex); + + /** + * Mark whether this segment is stored as a compound file. + * + * @param isCompoundFile true if this is a compound file; + * else, false + */ + void setUseCompoundFile(const bool isCompoundFile); + + /** + * Returns true if this segment is stored as a compound + * file; else, false. + */ + bool getUseCompoundFile() const; + + /* + * Return all files referenced by this SegmentInfo. The + * returns List is a locally cached List so you should not + * modify it. + */ + const std::vector& files(); + + /** + * Copy everything from src SegmentInfo into our instance. + */ + void reset(const SegmentInfo* src); + + /** + * Save this segment's info. + */ + void write(CL_NS(store)::IndexOutput* output); + + int32_t getDocStoreOffset() const; + + bool getDocStoreIsCompoundFile() const; + + void setDocStoreIsCompoundFile(const bool v); + + /** + * Returns a reference to docStoreSegment + */ + const std::string& getDocStoreSegment() const; + + void setDocStoreOffset(const int32_t offset); + + /** We consider another SegmentInfo instance equal if it + * has the same dir and same name. */ + bool equals(const SegmentInfo* obj); + + ///Gets the Directory where the segment resides + CL_NS(store)::Directory* getDir() const{ return dir; } //todo: since dir is public, consider removing this function + + friend class SegmentReader; + + /** Used for debugging */ + std::string segString(CL_NS(store)::Directory* dir); + }; + + typedef CL_NS(util)::CLVector > segmentInfosType; + //SegmentInfos manages a list of SegmentInfo instances + //Each SegmentInfo contains information about a segment in a directory. + // + //The active segments in the index are stored in the segment info file. + //An index only has a single file in this format, and it is named "segments". + //This lists each segment by name, and also contains the size of each segment. + //The format of the file segments is defined as follows: + // + // SegCount + //Segments --> SegCount, + // + //SegCount, SegSize --> UInt32 + // + //SegName --> String + // + //SegName is the name of the segment, and is used as the file name prefix + //for all of the files that compose the segment's index. + // + //SegSize is the number of documents contained in the segment index. + // + //Note: + //At http://jakarta.apache.org/lucene/docs/fileformats.html the definition + //of all file formats can be found. Note that java lucene currently + //defines Segments as follows: + // + //Segments --> Format, Version, SegCount, SegCount + // + //Format, SegCount, SegSize --> UInt32 + // + //Format and Version have not been implemented yet + + class IndexReader; + + class SegmentInfos: LUCENE_BASE { + public: + DEFINE_MUTEX(THIS_LOCK) + + /** The file format version, a negative number. */ + /* Works since counter, the old 1st entry, is always >= 0 */ + LUCENE_STATIC_CONSTANT(int32_t,FORMAT=-1); + + /** This format adds details used for lockless commits. It differs + * slightly from the previous format in that file names + * are never re-used (write once). Instead, each file is + * written to the next generation. For example, + * segments_1, segments_2, etc. This allows us to not use + * a commit lock. See file + * formats for details. + */ + LUCENE_STATIC_CONSTANT(int32_t,FORMAT_LOCKLESS=-2); + + /** This format adds a "hasSingleNormFile" flag into each segment info. + * See LUCENE-756 + * for details. + */ + LUCENE_STATIC_CONSTANT(int32_t,FORMAT_SINGLE_NORM_FILE=-3); + + /** This format allows multiple segments to share a single + * vectors and stored fields file. */ + LUCENE_STATIC_CONSTANT(int32_t,FORMAT_SHARED_DOC_STORE=-4); + + private: + /* This must always point to the most recent file format. */ + LUCENE_STATIC_CONSTANT(int32_t,CURRENT_FORMAT=FORMAT_SHARED_DOC_STORE); + + public: + int32_t counter; // used to name new segments + + /** + * counts how often the index has been changed by adding or deleting docs. + * starting with the current time in milliseconds forces to create unique version numbers. + */ + int64_t version; + + private: + int64_t generation; // generation of the "segments_N" for the next commit + int64_t lastGeneration; // generation of the "segments_N" file we last successfully read + // or wrote; this is normally the same as generation except if + // there was an IOException that had interrupted a commit + + /** + * If non-null, information about loading segments_N files + * will be printed here. @see #setInfoStream. + */ + static std::ostream* infoStream; + + LUCENE_STATIC_CONSTANT(int32_t,defaultGenFileRetryCount=10); + LUCENE_STATIC_CONSTANT(int32_t,defaultGenFileRetryPauseMsec=50); + LUCENE_STATIC_CONSTANT(int32_t,defaultGenLookaheadCount=10); + + segmentInfosType infos; + + friend class IndexWriter; //allow IndexWriter to use counter + + static void message(const char* _message, ...); + + public: + SegmentInfos(bool deleteMembers=true, int32_t reserveCount=0); + ~SegmentInfos(); + + //Returns a reference to the i-th SegmentInfo in the list. + SegmentInfo* info(int32_t i) const; + + /** + * Get the generation (N) of the current segments_N file + * from a list of files. + * + * @param files -- array of file names to check + */ + static int64_t getCurrentSegmentGeneration( std::vector& files ); + + /** + * Get the generation (N) of the current segments_N file + * in the directory. + * + * @param directory -- directory to search for the latest segments_N file + */ + static int64_t getCurrentSegmentGeneration( const CL_NS(store)::Directory* directory ); + + /** + * Get the filename of the current segments_N file + * from a list of files. + * + * @param files -- array of file names to check + */ + static std::string getCurrentSegmentFileName( std::vector& files ); + + /** + * Get the filename of the current segments_N file + * in the directory. + * + * @param directory -- directory to search for the latest segments_N file + */ + static std::string getCurrentSegmentFileName( CL_NS(store)::Directory* directory ); + + /** + * Get the segments_N filename in use by this segment infos. + */ + std::string getCurrentSegmentFileName(); + + /** + * Parse the generation off the segments file name and + * return it. + */ + static int64_t generationFromSegmentsFileName( const char* fileName ); + + /** + * Get the next segments_N filename that will be written. + */ + std::string getNextSegmentFileName(); + + /* public vector-like operations */ + //delete and clears objects 'from' from to 'to' + void clearto(size_t to, size_t end); + //count of segment infos + int32_t size() const; + /** add a segment info + * @param pos position to add the info at. -1 for last position + */ + void add(SegmentInfo* info, int32_t pos=-1); + SegmentInfo* elementAt(int32_t pos); + void setElementAt(SegmentInfo* si, int32_t pos); + void clear(); + + void insert(SegmentInfos* infos, bool takeMemory); + void insert(SegmentInfo* info); + int32_t indexOf(const SegmentInfo* info) const; + void range(size_t from, size_t to, SegmentInfos& ret) const; + void remove(size_t index, bool dontDelete=false); + + /** + * Read a particular segmentFileName. Note that this may + * throw an IOException if a commit is in process. + * + * @param directory -- directory containing the segments file + * @param segmentFileName -- segment file to load + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void read(CL_NS(store)::Directory* directory, const char* segmentFileName); + + /** + * This version of read uses the retry logic (for lock-less + * commits) to find the right segments file to load. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + void read(CL_NS(store)::Directory* directory); + + //Writes a new segments file based upon the SegmentInfo instances it manages + //note: still does not support lock-less writes (still pre-2.1 format) + void write(CL_NS(store)::Directory* directory); + + /** + * Returns a copy of this instance, also copying each + * SegmentInfo. + */ + SegmentInfos* clone() const; + + /** + * version number when this SegmentInfos was generated. + */ + int64_t getVersion() const; + int64_t getGeneration() const; + int64_t getLastGeneration() const; + + /** + * Current version number from segments file. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + static int64_t readCurrentVersion(CL_NS(store)::Directory* directory); + + + /** If non-null, information about retries when loading + * the segments file will be printed to this. + */ + static void setInfoStream(std::ostream* infoStream); + + /** + * @see #setInfoStream + */ + static std::ostream* getInfoStream(); + + /** + * Advanced: set how many times to try loading the + * segments.gen file contents to determine current segment + * generation. This file is only referenced when the + * primary method (listing the directory) fails. + */ + //static void setDefaultGenFileRetryCount(const int32_t count); + /** + * @see #setDefaultGenFileRetryCount + */ + static int32_t getDefaultGenFileRetryCount(); + + /** + * Advanced: set how many milliseconds to pause in between + * attempts to load the segments.gen file. + */ + //static void setDefaultGenFileRetryPauseMsec(const int32_t msec); + /** + * @see #setDefaultGenFileRetryPauseMsec + */ + static int32_t getDefaultGenFileRetryPauseMsec(); + + /** + * Advanced: set how many times to try incrementing the + * gen when loading the segments file. This only runs if + * the primary (listing directory) and secondary (opening + * segments.gen file) methods fail to find the segments + * file. + */ + //static void setDefaultGenLookaheadCount(const int32_t count); + /** + * @see #setDefaultGenLookaheadCount + */ + static int32_t getDefaultGenLookahedCount(); + + class _FindSegmentsFile: LUCENE_BASE{ + protected: + const char* fileDirectory; + CL_NS(store)::Directory* directory; + + void doRun(); + virtual bool tryDoBody(const char* segmentFileName, CLuceneError& ret_err) = 0; + }; + + /** + * Utility class for executing code that needs to do + * something with the current segments file. This is + * necessary with lock-less commits because from the time + * you locate the current segments file name, until you + * actually open it, read its contents, or check modified + * time, etc., it could have been deleted due to a writer + * commit finishing. + */ + template + class FindSegmentsFile: public _FindSegmentsFile{ + protected: + virtual RET doBody(const char* segmentFileName) = 0; + RET result; + + //catch only IO errors, return true on success... + bool tryDoBody(const char* segmentFileName, CLuceneError& ret_err){ + try{ + result = doBody(segmentFileName); + return true; + } catch (CLuceneError& err) { + result = 0; + ret_err.set(err.number(),err.what()); + } + return false; + } + public: + FindSegmentsFile( CL_NS(store)::Directory* dir ){ + this->directory = dir; + this->fileDirectory = NULL; + this->result = 0; + } + FindSegmentsFile( const char* dir ){ + this->directory = NULL; + this->fileDirectory = dir; + this->result = 0; + } + ~FindSegmentsFile(){ + } + + RET run(){ + doRun(); + return result; + }; + }; + //friend class SegmentInfos::FindSegmentsFile; + + class FindSegmentsVersion: public FindSegmentsFile { + public: + FindSegmentsVersion( CL_NS(store)::Directory* dir ); + FindSegmentsVersion( const char* dir ); + int64_t doBody( const char* segmentFileName ); + }; + friend class SegmentInfos::FindSegmentsVersion; + + class FindSegmentsRead: public FindSegmentsFile { + SegmentInfos* _this; + public: + FindSegmentsRead( CL_NS(store)::Directory* dir, SegmentInfos* _this ); + FindSegmentsRead( const char* dir, SegmentInfos* _this ); + bool doBody( const char* segmentFileName ); + }; + friend class SegmentInfos::FindSegmentsRead; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SegmentMergeInfo.h b/src/core/CLucene/index/_SegmentMergeInfo.h new file mode 100644 index 00000000000..87b05cb9d8d --- /dev/null +++ b/src/core/CLucene/index/_SegmentMergeInfo.h @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentMergeInfo_ +#define _lucene_index_SegmentMergeInfo_ + + +//#include "SegmentTermEnum.h" +//#include "SegmentHeader.h" +#include "Terms.h" + +CL_NS_DEF(index) +class IndexReader; + +class SegmentMergeInfo:LUCENE_BASE { +private: + int32_t* docMap; // maps around deleted docs + TermPositions* postings; +public: + TermEnum* termEnum; + Term* term; + int32_t base; + IndexReader* reader; + + //Constructor + SegmentMergeInfo(const int32_t b, TermEnum* te, IndexReader* r); + + //Destructor + ~SegmentMergeInfo(); + + //Moves the current term of the enumeration termEnum to the next and term + //points to this new current term + bool next(); + + //Closes the the resources + void close(); + + // maps around deleted docs + int32_t* getDocMap(); + + TermPositions* getPositions(); +}; +CL_NS_END +#endif + diff --git a/src/core/CLucene/index/_SegmentMergeQueue.h b/src/core/CLucene/index/_SegmentMergeQueue.h new file mode 100644 index 00000000000..a95a001b6b3 --- /dev/null +++ b/src/core/CLucene/index/_SegmentMergeQueue.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentMergeQueue_ +#define _lucene_index_SegmentMergeQueue_ + +#include "CLucene/util/PriorityQueue.h" +//#include "SegmentMergeInfo.h" + +CL_NS_DEF(index) + class SegmentMergeQueue :public CL_NS(util)::PriorityQueue > { + public: + //Constructor + //Creates a queue of length size + SegmentMergeQueue(const int32_t size); + + //Destructor + //Does nothing as its parent class will clean up everything + ~SegmentMergeQueue(); + + //Closes and destroyes all SegmentMergeInfo Instances in the queue + void close(); + protected: + //Overloaded method that implements the lessThan operator for the parent class + //This method is used by the parent class Priority queue to reorder its internal + //data structures. This implementation check if stiA is less than the current term of stiB. + bool lessThan(SegmentMergeInfo* stiA, SegmentMergeInfo* stiB); + + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SegmentMerger.h b/src/core/CLucene/index/_SegmentMerger.h new file mode 100644 index 00000000000..da24e1dda4e --- /dev/null +++ b/src/core/CLucene/index/_SegmentMerger.h @@ -0,0 +1,198 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentMerger_ +#define _lucene_index_SegmentMerger_ + + +CL_CLASS_DEF(store,Directory) +#include "CLucene/store/_RAMDirectory.h" +#include "_SegmentMergeInfo.h" +#include "_SegmentMergeQueue.h" +#include "IndexReader.h" +#include "_TermInfosWriter.h" +#include "Terms.h" +#include "MergePolicy.h" + +CL_NS_DEF(index) +class DefaultSkipListWriter; +/** +* The SegmentMerger class combines two or more Segments, represented by an IndexReader ({@link #add}, +* into a single Segment. After adding the appropriate readers, call the merge method to combine the +* segments. +*

+* If the compoundFile flag is set, then the segments will be merged into a compound file. +* +* +* @see #merge +* @see #add +*/ +class SegmentMerger:LUCENE_BASE { + CL_NS(util)::ValueArray payloadBuffer; + + //Directory of the segment + CL_NS(store)::Directory* directory; + //name of the new segment + std::string segment; + //Set of IndexReaders + CL_NS(util)::CLVector > readers; + //Field Infos for t he FieldInfo instances of all fields + FieldInfos* fieldInfos; + + int32_t mergedDocs; + + // Whether we should merge doc stores (stored fields and + // vectors files). When all segments we are merging + // already share the same doc store files, we don't need + // to merge the doc stores. + bool mergeDocStores; + + /** Maximum number of contiguous documents to bulk-copy + when merging stored fields */ + static int32_t MAX_RAW_MERGE_DOCS; + + //The queue that holds SegmentMergeInfo instances + SegmentMergeQueue* queue; + //IndexOutput to the new Frequency File + CL_NS(store)::IndexOutput* freqOutput; + //IndexOutput to the new Prox File + CL_NS(store)::IndexOutput* proxOutput; + //Writes Terminfos that have been merged + TermInfosWriter* termInfosWriter; + TermInfo termInfo; //(new) minimize consing + + int32_t termIndexInterval; + int32_t skipInterval; + int32_t maxSkipLevels; + DefaultSkipListWriter* skipListWriter; + +public: + static const uint8_t NORMS_HEADER[]; + static const int NORMS_HEADER_length; + + /** + * + * @param dir The Directory to merge the other segments into + * @param name The name of the new segment + * @param compoundFile true if the new segment should use a compoundFile + */ + SegmentMerger( IndexWriter* writer, const char* name, MergePolicy::OneMerge* merge ); + + SegmentMerger(IndexWriter* writer, std::string name, MergePolicy::OneMerge* merge); + + void init(); + + //Destructor + ~SegmentMerger(); + + /** + * Add an IndexReader to the collection of readers that are to be merged + * @param reader + */ + void add(IndexReader* reader); + + /** + * + * @param i The index of the reader to return + * @return The ith reader to be merged + */ + IndexReader* segmentReader(const int32_t i); + + /** + * Merges the readers specified by the {@link #add} method + * into the directory passed to the constructor. + * @param mergeDocStores if false, we will not merge the + * stored fields nor vectors files + * @return The number of documents that were merged + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + int32_t merge(bool mergeDocStores); + /** + * close all IndexReaders that have been added. + * Should not be called before merge(). + * @throws IOException + */ + void closeReaders(); + + + class CheckAbort { + private: + float_t workCount; + MergePolicy::OneMerge* merge; + CL_NS(store)::Directory* dir; + public: + CheckAbort(MergePolicy::OneMerge* merge, CL_NS(store)::Directory* dir); + + /** + * Records the fact that roughly units amount of work + * have been done since this method was last called. + * When adding time-consuming code into SegmentMerger, + * you should test different values for units to ensure + * that the time in between calls to merge.checkAborted + * is up to ~ 1 second. + */ + void work(float_t units); + }; + +private: + CheckAbort* checkAbort; + + void addIndexed(IndexReader* reader, FieldInfos* fieldInfos, StringArrayWithDeletor& names, + bool storeTermVectors, bool storePositionWithTermVector, + bool storeOffsetWithTermVector, bool storePayloads); + + /** + * Merge the fields of all segments + * @return The number of documents in all of the readers + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + int32_t mergeFields(); + + /** + * Merge the TermVectors from each of the segments into the new one. + * @throws IOException + */ + void mergeVectors(); + + /** Merge the terms of all segments */ + void mergeTerms(); + + /** Merges all TermInfos into a single segment */ + void mergeTermInfos(); + + /** Merge one term found in one or more segments. The array smis + * contains segments that are positioned at the same term. N + * is the number of cells in the array actually occupied. + * + * @param smis array of segments + * @param n number of cells in the array actually occupied + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + int32_t mergeTermInfo( SegmentMergeInfo** smis, int32_t n); + + /** Process postings from multiple segments all positioned on the + * same term. Writes out merged entries into freqOutput and + * the proxOutput streams. + * + * @param smis array of segments + * @param n number of cells in the array actually occupied + * @return number of documents across all segments where this term was found + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + int32_t appendPostings(SegmentMergeInfo** smis, int32_t n); + + //Merges the norms for all fields + void mergeNorms(); + + void createCompoundFile(const char* filename, std::vector* files=NULL); + friend class IndexWriter; //allow IndexWriter to use createCompoundFile +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SegmentTermEnum.h b/src/core/CLucene/index/_SegmentTermEnum.h new file mode 100644 index 00000000000..a2559082b14 --- /dev/null +++ b/src/core/CLucene/index/_SegmentTermEnum.h @@ -0,0 +1,133 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SegmentTermEnum_ +#define _lucene_index_SegmentTermEnum_ + + +//#include "Terms.h" +//#include "FieldInfos.h" +//#include "TermInfo.h" + +CL_NS_DEF(index) + +/** + * SegmentTermEnum is an enumeration of all Terms and TermInfos + */ +class SegmentTermEnum:public TermEnum{ +private: + Term* _term; ///points to the current Term in the enumeration + TermInfo* termInfo; ///points to the TermInfo matching the current Term in the enumeration + + bool isIndex; ///Indicates if the Segment is a an index + bool isClone; ///Indicates if SegmentTermEnum is an orignal instance or + ///a clone of another SegmentTermEnum + + TCHAR* buffer; ///The buffer that contains the data read from the Term Infos File + uint32_t bufferLength; ///Length of the buffer + + int32_t format; + int32_t formatM1SkipInterval; + + CL_NS(store)::IndexInput* input; ///The IndexInput that reads from the Term Infos File + FieldInfos* fieldInfos; ///contains the Field Infos for the segment + int64_t size; ///The size of the enumeration + int64_t position; ///The position of the current (term) in the enumeration + int64_t indexPointer; + Term* prev; ///The previous current + int32_t indexInterval; + int32_t skipInterval; + int32_t maxSkipLevels; + + friend class TermInfosReader; + friend class SegmentTermDocs; +protected: + + /** + * Constructor. + * The instance is created by cloning all properties of clone + */ + SegmentTermEnum( const SegmentTermEnum& clone); + +public: + ///Constructor + SegmentTermEnum(CL_NS(store)::IndexInput* i, FieldInfos* fis, const bool isi ); + + ///Destructor + ~SegmentTermEnum(); + + /** + * Moves the current of the set to the next in the set + */ + bool next(); + + /** + * Returns the current term. + */ + Term* term(bool pointer=true); + + /** + * Scan for Term term without allocating new Terms + */ + void scanTo(const Term *term); + + /** + * Closes the enumeration to further activity, freeing resources. + */ + void close(); + + /** + * Returns the document frequency of the current term in the set + */ + int32_t docFreq() const; + + /** + * Repositions term and termInfo within the enumeration + */ + void seek(const int64_t pointer, const int32_t p, Term* t, TermInfo* ti); + + /** + * Returns a clone of the current termInfo + */ + TermInfo* getTermInfo()const; + + /** + * Retrieves a clone of termInfo through the reference ti + */ + void getTermInfo(TermInfo* ti)const; + + /** + * Returns the freqPointer from the current TermInfo in the enumeration. + */ + int64_t freqPointer() const; + + /** + * Returns the proxPointer from the current TermInfo in the enumeration. + */ + int64_t proxPointer() const; + + /** + * Returns a clone of this instance + */ + SegmentTermEnum* clone() const; + + const char* getObjectName() const; + static const char* getClassName(); + +private: + /** + * Reads the next term in the enumeration + */ + Term* readTerm(Term* reuse); + /** + * Instantiate a buffer of length length+1 + * TODO: deprecate this... + */ + void growBuffer(const uint32_t length, bool force_copy); + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SkipListReader.h b/src/core/CLucene/index/_SkipListReader.h new file mode 100644 index 00000000000..05e0e284411 --- /dev/null +++ b/src/core/CLucene/index/_SkipListReader.h @@ -0,0 +1,183 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SkipListReader_ +#define _lucene_index_SkipListReader_ + +#include "CLucene/store/IndexInput.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +/** + * This abstract class reads skip lists with multiple levels. + * + * See {@link MultiLevelSkipListWriter} for the information about the encoding + * of the multi level skip lists. + * + * Subclasses must implement the abstract method {@link #readSkipData(int, IndexInput)} + * which defines the actual format of the skip data. + */ +class MultiLevelSkipListReader : LUCENE_BASE { +protected: + // number of levels in this skip list + int32_t numberOfSkipLevels; + + // the maximum number of skip levels possible for this index + int32_t maxNumberOfSkipLevels; +private: + // Expert: defines the number of top skip levels to buffer in memory. + // Reducing this number results in less memory usage, but possibly + // slower performance due to more random I/Os. + // Please notice that the space each level occupies is limited by + // the skipInterval. The top level can not contain more than + // skipLevel entries, the second top level can not contain more + // than skipLevel^2 entries and so forth. + int32_t numberOfLevelsToBuffer; + + int32_t docCount; + bool haveSkipped; + + CL_NS(util)::ObjectArray skipStream; // skipStream for each level + int64_t* skipPointer; // the start pointer of each skip level + int32_t* skipInterval; // skipInterval of each level + int32_t* numSkipped; // number of docs skipped per level + + int32_t* skipDoc; // doc id of current skip entry per level + int32_t lastDoc; // doc id of last read skip entry with docId <= target + int64_t* childPointer; // child pointer of current skip entry per level + int64_t lastChildPointer; // childPointer of last read skip entry with docId <= target + + bool inputIsBuffered; + +public: + /** + * @memory consumes _skipStream + */ + MultiLevelSkipListReader(CL_NS(store)::IndexInput* _skipStream, const int32_t maxSkipLevels, const int32_t _skipInterval); + virtual ~MultiLevelSkipListReader(); + + /** Returns the id of the doc to which the last call of {@link #skipTo(int)} + * has skipped. */ + int32_t getDoc() const; + + /** Skips entries to the first beyond the current whose document number is + * greater than or equal to target. Returns the current doc count. + */ + int32_t skipTo(const int32_t target); + +private: + bool loadNextSkip(const int32_t level); + +protected: + /** Seeks the skip entry on the given level */ + virtual void seekChild(const int32_t level); + + void close(); + + /** initializes the reader */ + void init(const int64_t _skipPointer, const int32_t df); + +private: + /** Loads the skip levels */ + void loadSkipLevels(); + +protected: + /** + * Subclasses must implement the actual skip data encoding in this method. + * + * @param level the level skip data shall be read from + * @param skipStream the skip stream to read from + */ + virtual int32_t readSkipData(const int32_t level, CL_NS(store)::IndexInput* skipStream) = 0; + + /** Copies the values of the last read skip entry on this level */ + virtual void setLastSkipData(const int32_t level); + +protected: + /** used to buffer the top skip levels */ + class SkipBuffer : public CL_NS(store)::IndexInput { + private: + uint8_t* data; + int64_t pointer; + int32_t pos; + size_t _datalength; + + public: + SkipBuffer(CL_NS(store)::IndexInput* input, const int32_t length); + virtual ~SkipBuffer(); + + private: + void close(); + + int64_t getFilePointer() const; + + int64_t length() const; + + uint8_t readByte(); + + /* Make sure b is passed after the offset has been calculated into it, if necessary! */ + void readBytes(uint8_t* b, const int32_t len); + void readBytes(uint8_t* b, const int32_t len, int32_t offset); + + + void seek(const int64_t _pos); + + SkipBuffer(const SkipBuffer& other); + CL_NS(store)::IndexInput* clone() const; + + const char* getDirectoryType() const; + const char* getObjectName() const; + static const char* getClassName(); + }; +}; + + +/** + * Implements the skip list reader for the default posting list format + * that stores positions and payloads. + * + */ +class DefaultSkipListReader: public MultiLevelSkipListReader { +private: + bool currentFieldStoresPayloads; + int64_t* freqPointer{nullptr}; + int64_t* proxPointer{nullptr}; + int32_t* payloadLength; + + int64_t lastFreqPointer{0}; + int64_t lastProxPointer{0}; + int32_t lastPayloadLength; + +public: + DefaultSkipListReader(CL_NS(store)::IndexInput* _skipStream, const int32_t maxSkipLevels, const int32_t _skipInterval); + virtual ~DefaultSkipListReader(); + + void init(const int64_t _skipPointer, const int64_t freqBasePointer, const int64_t proxBasePointer, const int32_t df, const bool storesPayloads); + + /** Returns the freq pointer of the doc to which the last call of + * {@link MultiLevelSkipListReader#skipTo(int)} has skipped. */ + int64_t getFreqPointer() const; + + /** Returns the prox pointer of the doc to which the last call of + * {@link MultiLevelSkipListReader#skipTo(int)} has skipped. */ + int64_t getProxPointer() const; + + /** Returns the payload length of the payload stored just before + * the doc to which the last call of {@link MultiLevelSkipListReader#skipTo(int)} + * has skipped. */ + int32_t getPayloadLength() const; + +protected: + void seekChild(const int32_t level); + + void setLastSkipData(const int32_t level); + + int32_t readSkipData(const int32_t level, CL_NS(store)::IndexInput* _skipStream); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_SkipListWriter.h b/src/core/CLucene/index/_SkipListWriter.h new file mode 100644 index 00000000000..a22a37a874e --- /dev/null +++ b/src/core/CLucene/index/_SkipListWriter.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_SkipListWriter_ +#define _lucene_index_SkipListWriter_ + +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/_RAMDirectory.h" +#include "CLucene/util/Array.h" + +CL_NS_DEF(index) + +/** + * This abstract class writes skip lists with multiple levels. + * + * Example for skipInterval = 3: + * c (skip level 2) + * c c c (skip level 1) + * x x x x x x x x x x (skip level 0) + * d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d d (posting list) + * 3 6 9 12 15 18 21 24 27 30 (df) + * + * d - document + * x - skip data + * c - skip data with child pointer + * + * Skip level i contains every skipInterval-th entry from skip level i-1. + * Therefore the number of entries on level i is: floor(df / ((skipInterval ^ (i + 1))). + * + * Each skip entry on a level i>0 contains a pointer to the corresponding skip entry in list i-1. + * This guarantess a logarithmic amount of skips to find the target document. + * + * While this class takes care of writing the different skip levels, + * subclasses must define the actual format of the skip data. + * + */ +class MultiLevelSkipListWriter { +private: + // the skip interval in the list with level = 0 + int32_t skipInterval; + + // for every skip level a different buffer is used + CL_NS(util)::ArrayBase* skipBuffer; + +protected: + // number of levels in this skip list + int32_t numberOfSkipLevels; + + MultiLevelSkipListWriter(int32_t skipInterval, int32_t maxSkipLevels, int32_t df); + virtual ~MultiLevelSkipListWriter(); + void init(); + + void resetSkip(); + + /** + * Subclasses must implement the actual skip data encoding in this method. + * + * @param level the level skip data shall be writting for + * @param skipBuffer the skip buffer to write to + */ + virtual void writeSkipData(int32_t level, CL_NS(store)::IndexOutput* skipBuffer) = 0; + + friend class SegmentMerger; + friend class DocumentsWriter; + +public: + /** + * Writes the current skip data to the buffers. The current document frequency determines + * the max level is skip data is to be written to. + * + * @param df the current document frequency + * @throws IOException + */ + void bufferSkip(int32_t df); + + /** + * Writes the buffered skip lists to the given output. + * + * @param output the IndexOutput the skip lists shall be written to + * @return the pointer the skip list starts + */ + int64_t writeSkip(CL_NS(store)::IndexOutput* output); +}; + +/** + * Implements the skip list writer for the default posting list format + * that stores positions and payloads. + * + */ +class DefaultSkipListWriter: public MultiLevelSkipListWriter { +private: + int32_t* lastSkipDoc; + int32_t* lastSkipPayloadLength; + int64_t* lastSkipFreqPointer; + int64_t* lastSkipProxPointer; + + CL_NS(store)::IndexOutput* freqOutput; + CL_NS(store)::IndexOutput* proxOutput{nullptr}; + + int32_t curDoc; + bool curStorePayloads; + int32_t curPayloadLength; + int64_t curFreqPointer; + int64_t curProxPointer{-1}; + +protected: + + void writeSkipData(int32_t level, CL_NS(store)::IndexOutput* skipBuffer); + +public: + + DefaultSkipListWriter(int32_t skipInterval, int32_t numberOfSkipLevels, int32_t docCount, + CL_NS(store)::IndexOutput* freqOutput, CL_NS(store)::IndexOutput* proxOutput); + ~DefaultSkipListWriter(); + + friend class SegmentMerger; + friend class DocumentsWriter; + /** + * Sets the values for the current skip data. + */ + void setSkipData(int32_t doc, bool storePayloads, int32_t payloadLength); + void resetSkip(); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_Term.h b/src/core/CLucene/index/_Term.h new file mode 100644 index 00000000000..28baf1342bb --- /dev/null +++ b/src/core/CLucene/index/_Term.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_internal_Term_ +#define _lucene_index_internal_Term_ + +#include "Term.h" +#include + +CL_NS_DEF(index) + + +class Term_Equals:public CL_NS_STD(binary_function) +{ +public: + bool operator()( const Term* val1, const Term* val2 ) const{ + return val1->equals(val2); + } +}; + +class Term_Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base // +{ +public: + bool operator()( Term* t1, Term* t2 ) const{ + return ( t1->compareTo(t2) < 0 ); + } + size_t operator()( Term* t ) const{ + return t->hashCode(); + } +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_TermInfo.h b/src/core/CLucene/index/_TermInfo.h new file mode 100644 index 00000000000..7404117c3df --- /dev/null +++ b/src/core/CLucene/index/_TermInfo.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_TermInfo +#define _lucene_index_TermInfo + + +CL_NS_DEF(index) + +// A TermInfo is the record of information stored for a term. +class TermInfo: LUCENE_BASE{ +public: + // The number of documents which contain the term. + int32_t docFreq; + + //A pointer into the TermFreqs file (.frq) + //The .frq file contains the lists of documents which contain each term, + //along with the frequency of the term in that document. + int64_t freqPointer; + + //A pointer into the TermPosition file (.prx). + //The .prx file contains the lists of positions that each term + //occurs at within documents. + int64_t proxPointer; + + int32_t skipOffset; + + //Constructor + TermInfo(); + + //Constructor + TermInfo(const int32_t df, const int64_t fp, const int64_t pp); + + //Constructor + //Initialises this instance by copying the values of another TermInfo ti + TermInfo(const TermInfo* ti); + + //Destructor + ~TermInfo(); + + //Sets a new document frequency, a new freqPointer and a new proxPointer + void set(const int32_t docFreq, const int64_t freqPointer, const int64_t proxPointer, int32_t skipOffset); + + //Sets a new document frequency, a new freqPointer and a new proxPointer + //by copying these values from another instance of TermInfo + void set(const TermInfo* ti); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_TermInfosReader.h b/src/core/CLucene/index/_TermInfosReader.h new file mode 100644 index 00000000000..c2b41aca6ce --- /dev/null +++ b/src/core/CLucene/index/_TermInfosReader.h @@ -0,0 +1,131 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_TermInfosReader_ +#define _lucene_index_TermInfosReader_ + + +//#include "Terms.h" +#include "_SegmentTermEnum.h" +CL_CLASS_DEF(store,Directory) +//CL_CLASS_DEF(store,IndexInput) +#include "CLucene/util/_ThreadLocal.h" +//#include "FieldInfos.h" +//#include "TermInfo.h" +//#include "TermInfosWriter.h" + +CL_NS_DEF(index) +/** This stores a monotonically increasing set of pairs in a +* Directory. Pairs are accessed either by Term or by ordinal position the +* set. +* +* PORT STATUS: 365707 (jlucene 1.9) -- started port to JLucene 2.3.2 +*/ + class TermInfosReader :LUCENE_BASE{ + private: + CL_NS(store)::Directory* directory; + const char* segment; + FieldInfos* fieldInfos; + + CL_NS(util)::ThreadLocal > enumerators; + + SegmentTermEnum* getEnum(); + SegmentTermEnum* origEnum; + SegmentTermEnum* indexEnum; + int64_t _size; + + Term* indexTerms; //note: this is a list of objects, not arrays! + int32_t indexTermsLength; + TermInfo* indexInfos; + int64_t* indexPointers; + bool indexIsRead = false; + + int32_t indexDivisor; + int32_t totalIndexInterval; + + DEFINE_MUTEX(THIS_LOCK) + + public: + /** + * Constructor. + * Reads the TermInfos file (.tis) and eventually the Term Info Index file (.tii) + */ + TermInfosReader(CL_NS(store)::Directory* dir, const char* segment, FieldInfos* fis, + const int32_t readBufferSize = CL_NS(store)::BufferedIndexInput::BUFFER_SIZE); + ~TermInfosReader(); + + int32_t getSkipInterval() const; + int32_t getMaxSkipLevels() const; + + /** + *

Sets the indexDivisor, which subsamples the number + * of indexed terms loaded into memory. This has a + * similar effect as {@link + * IndexWriter#setTermIndexInterval} except that setting + * must be done at indexing time while this setting can be + * set per reader. When set to N, then one in every + * N*termIndexInterval terms in the index is loaded into + * memory. By setting this to a value > 1 you can reduce + * memory usage, at the expense of higher latency when + * loading a TermInfo. The default value is 1.

+ * + * NOTE: you must call this before the term + * index is loaded. If the index is already loaded, + * an IllegalStateException is thrown. + * + * @throws IllegalStateException if the term index has + * already been loaded into memory. + */ + void setIndexDivisor(const int32_t _indexDivisor); + + /** Returns the indexDivisor. + * @see #setIndexDivisor + */ + int32_t getIndexDivisor() const; + + /** Close the enumeration of TermInfos */ + void close(); + + /** Returns the number of term/value pairs in the set. */ + int64_t size() const; + + /** + * Returns an enumeration of terms starting at or after the named term. + * If no term is specified, an enumeration of all the Terms + * and TermInfos in the set is returned. + */ + SegmentTermEnum* terms(const Term* term=NULL); + + /** Returns the TermInfo for a Term in the set, or null. */ + TermInfo* get(const Term* term); + private: + /** Reads the term info index file or .tti file. */ + void ensureIndexIsRead(); + + /** Returns the offset of the greatest index entry which is less than or equal to term.*/ + int32_t getIndexOffset(const Term* term); + + /** Reposition the current Term and TermInfo to indexOffset */ + void seekEnum(const int32_t indexOffset); + + /** Scans the Enumeration of terms for term and returns the corresponding TermInfo instance if found. + * The search is started from the current term. + */ + TermInfo* scanEnum(const Term* term); + + /** Scans the enumeration to the requested position and returns the Term located at that position */ + Term* scanEnum(const int32_t position); + + /** Returns the position of a Term in the set or -1. */ + int64_t getPosition(const Term* term); + + /** Returns the nth term in the set. synchronized */ + Term* get(const int32_t position); + + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_TermInfosWriter.h b/src/core/CLucene/index/_TermInfosWriter.h new file mode 100644 index 00000000000..c2f72e707ae --- /dev/null +++ b/src/core/CLucene/index/_TermInfosWriter.h @@ -0,0 +1,148 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_TermInfosWriter_ +#define _lucene_index_TermInfosWriter_ + +#include "CLucene/util/Array.h" + +CL_CLASS_DEF(store, Directory) +//#include "FieldInfos.h" +//#include "TermInfo.h" +#include "Term.h" + +CL_NS_DEF(index) +class FieldInfos; +class TermInfo; + +template +class STermInfosWriter : LUCENE_BASE { +private: + FieldInfos *fieldInfos; + CL_NS(store)::IndexOutput *output; + TermInfo *lastTi; + int64_t size; + + int64_t lastIndexPointer; + bool isIndex; + CL_NS(util)::ValueArray lastTermText; + int32_t lastTermTextLength; + int32_t lastFieldNumber; + + CL_NS(util)::ValueArray termTextBuffer; + + STermInfosWriter *other; + + //inititalize + STermInfosWriter(CL_NS(store)::Directory *directory, const char *segment, FieldInfos *fis, int32_t interval, bool isIndex); + + int32_t compareToLastTerm(int32_t fieldNumber, const T *termText, int32_t length); + +public: + int32_t maxSkipLevels; + + LUCENE_STATIC_CONSTANT(int32_t, FORMAT = -3); + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_TERMDOCS_SKIP_INTERVAL = 16); + + int32_t indexInterval;// = 128 + int32_t skipInterval;// = 16 + + STermInfosWriter(CL_NS(store)::Directory *directory, const char *segment, FieldInfos *fis, int32_t interval); + + ~STermInfosWriter() override; + + void add(STerm *term, TermInfo *ti); + + void add(int32_t fieldNumber, const T *termText, int32_t termTextLength, const TermInfo *ti); + + void close(); + +private: + void initialise(CL_NS(store)::Directory *directory, const char *segment, int32_t interval, bool IsIndex); + void writeTerm(int32_t fieldNumber, const T *termText, int32_t termTextLength); +}; + +// This stores a monotonically increasing set of pairs in a +// Directory. A TermInfos can be written once, in order. +class TermInfosWriter : LUCENE_BASE { +private: + FieldInfos *fieldInfos; + CL_NS(store)::IndexOutput *output; + TermInfo *lastTi; + int64_t size; + + int64_t lastIndexPointer; + bool isIndex; + CL_NS(util)::ValueArray lastTermText; + int32_t lastTermTextLength; + int32_t lastFieldNumber; + + CL_NS(util)::ValueArray termTextBuffer; + + TermInfosWriter *other; + + //inititalize + TermInfosWriter(CL_NS(store)::Directory *directory, const char *segment, FieldInfos *fis, int32_t interval, bool isIndex); + + int32_t compareToLastTerm(int32_t fieldNumber, const TCHAR *termText, int32_t length); + +public: + /** Expert: The maximum number of skip levels. Smaller values result in + * slightly smaller indexes, but slower skipping in big posting lists. + */ + int32_t maxSkipLevels; + + /** The file format version, a negative number. */ + LUCENE_STATIC_CONSTANT(int32_t, FORMAT = -3); + + //Expert: The fraction of {@link TermDocs} entries stored in skip tables, + //used to accellerate {@link TermDocs#skipTo(int)}. Larger values result in + //smaller indices, greater acceleration, but fewer accelerable cases, while + //smaller values result in bigger indices, less acceleration and more + //accelerable cases. More detailed experiments would be useful here. */ + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_TERMDOCS_SKIP_INTERVAL = 16); + + + /** + * Expert: The fraction of terms in the "dictionary" which should be stored + * in RAM. Smaller values use more memory, but make searching slightly + * faster, while larger values use less memory and make searching slightly + * slower. Searching is typically not dominated by dictionary lookup, so + * tweaking this is rarely useful. + */ + int32_t indexInterval;// = 128 + + /** + * Expert: The fraction of {@link TermDocs} entries stored in skip tables, + * used to accellerate {@link TermDocs#SkipTo(int32_t)}. Larger values result in + * smaller indexes, greater acceleration, but fewer accelerable cases, while + * smaller values result in bigger indexes, less acceleration and more + * accelerable cases. More detailed experiments would be useful here. + */ + int32_t skipInterval;// = 16 + + TermInfosWriter(CL_NS(store)::Directory *directory, const char *segment, FieldInfos *fis, int32_t interval); + + ~TermInfosWriter(); + + + void add(Term *term, TermInfo *ti); + + /** Adds a new <, TermInfo> pair to the set. + Term must be lexicographically greater than all previous Terms added. + TermInfo pointers must be positive and greater than all previous.*/ + void add(int32_t fieldNumber, const TCHAR *termText, int32_t termTextLength, const TermInfo *ti); + + /** Called to complete TermInfos creation. */ + void close(); + +private: + /** Helps constructors to initialize instances */ + void initialise(CL_NS(store)::Directory *directory, const char *segment, int32_t interval, bool IsIndex); + void writeTerm(int32_t fieldNumber, const TCHAR *termText, int32_t termTextLength); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/index/_TermVector.h b/src/core/CLucene/index/_TermVector.h new file mode 100644 index 00000000000..faf165d7410 --- /dev/null +++ b/src/core/CLucene/index/_TermVector.h @@ -0,0 +1,330 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_index_internal_termvector_h +#define _lucene_index_internal_termvector_h + +#include "CLucene/util/Array.h" +#include "_FieldInfos.h" +#include "TermVector.h" +//#include "FieldInfos.h" + +CL_NS_DEF(index) + +class TermVectorsWriter:LUCENE_BASE { +private: + CL_NS(store)::IndexOutput* tvx, *tvd, *tvf; + FieldInfos* fieldInfos; + +public: + TermVectorsWriter(CL_NS(store)::Directory* directory, const char* segment, + FieldInfos* fieldInfos); + ~TermVectorsWriter(); + + /** + * Add a complete document specified by all its term vectors. If document has no + * term vectors, add value for tvx. + * + * @param vectors + * @throws IOException + */ + void addAllDocVectors(CL_NS(util)::ArrayBase* vectors); + + /** Close all streams. + * to suppress exceptions from being thrown, pass an error object to be filled in + */ + void close(CLuceneError* err = NULL); +}; + +/** + */ +class SegmentTermVector: public /*virtual*/ TermFreqVector { +private: + TCHAR* field; + CL_NS(util)::ArrayBase* terms; + CL_NS(util)::ArrayBase* termFreqs; + + int32_t binarySearch(const CL_NS(util)::ArrayBase& array, const TCHAR* key) const; +public: + //note: termFreqs must be the same length as terms + SegmentTermVector(const TCHAR* field, CL_NS(util)::ArrayBase* terms, + CL_NS(util)::ArrayBase* termFreqs); + virtual ~SegmentTermVector(); + + /** + * + * @return The number of the field this vector is associated with + */ + const TCHAR* getField(); + TCHAR* toString() const; + int32_t size(); + const CL_NS(util)::ArrayBase* getTerms(); + const CL_NS(util)::ArrayBase* getTermFrequencies(); + int32_t indexOf(const TCHAR* termText); + CL_NS(util)::ArrayBase* indexesOf(const CL_NS(util)::ArrayBase& termNumbers, const int32_t start, const int32_t len); + + virtual TermPositionVector* __asTermPositionVector(); +}; + + + +/** +* @version $Id: +*/ +class TermVectorMapper; // Forward declaration + +class CLUCENE_EXPORT TermVectorsReader:LUCENE_BASE { +public: + LUCENE_STATIC_CONSTANT(int32_t, FORMAT_VERSION = 2); + LUCENE_STATIC_CONSTANT(uint8_t, STORE_POSITIONS_WITH_TERMVECTOR = 0x1); + LUCENE_STATIC_CONSTANT(uint8_t, STORE_OFFSET_WITH_TERMVECTOR = 0x2); +private: + + //The size in bytes that the FORMAT_VERSION will take up at the beginning of each file + LUCENE_STATIC_CONSTANT(int32_t, FORMAT_SIZE = 4); + + FieldInfos* fieldInfos; + + CL_NS(store)::IndexInput* tvx; + CL_NS(store)::IndexInput* tvd; + CL_NS(store)::IndexInput* tvf; + int64_t _size; // TODO: size_t ? + + // The docID offset where our docs begin in the index + // file. This will be 0 if we have our own private file. + int32_t docStoreOffset; + + int32_t tvdFormat; + int32_t tvfFormat; + +public: + TermVectorsReader(CL_NS(store)::Directory* d, const char* segment, FieldInfos* fieldInfos, + int32_t readBufferSize=LUCENE_STREAM_BUFFER_SIZE, int32_t docStoreOffset=-1, int32_t size=0); + ~TermVectorsReader(); + +private: + int32_t checkValidFormat(CL_NS(store)::IndexInput* in); + +public: + void close(); + + /** + * + * @return The number of documents in the reader + */ + int64_t size() const; + +public: + void get(const int32_t docNum, const TCHAR* field, TermVectorMapper* mapper); + + /** + * Retrieve the term vector for the given document and field + * @param docNum The document number to retrieve the vector for + * @param field The field within the document to retrieve + * @return The TermFreqVector for the document and field or null if there is no termVector for this field. + * @throws IOException if there is an error reading the term vector files + */ + TermFreqVector* get(const int32_t docNum, const TCHAR* field); + + /** + * Return all term vectors stored for this document or null if the could not be read in. + * + * @param docNum The document number to retrieve the vector for + * @return All term frequency vectors + * @throws IOException if there is an error reading the term vector files + */ + CL_NS(util)::ArrayBase* get(const int32_t docNum); + //bool get(int32_t docNum, CL_NS(util)::ObjectArray& result); + + void get(const int32_t docNumber, TermVectorMapper* mapper); + +private: + CL_NS(util)::ObjectArray* readTermVectors(const int32_t docNum, + const TCHAR** fields, const int64_t* tvfPointers, const int32_t len); + + void readTermVectors(const TCHAR** fields, const int64_t* tvfPointers, + const int32_t len, TermVectorMapper* mapper); + + /** + * + * @param field The field to read in + * @param tvfPointer The pointer within the tvf file where we should start reading + * @param mapper The mapper used to map the TermVector + * @return The TermVector located at that position + * @throws IOException + */ + void readTermVector(const TCHAR* field, const int64_t tvfPointer, TermVectorMapper* mapper); + + + DEFINE_MUTEX(THIS_LOCK) + TermVectorsReader(const TermVectorsReader& copy); + +public: + TermVectorsReader* clone() const; +}; + + +class SegmentTermPositionVector: public SegmentTermVector, public TermPositionVector { +protected: + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* positions; + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* offsets; + static CL_NS(util)::ValueArray EMPTY_TERM_POS; +public: + SegmentTermPositionVector(const TCHAR* field, + CL_NS(util)::ArrayBase* terms, + CL_NS(util)::ArrayBase* termFreqs, + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* _positions, + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* _offsets); + ~SegmentTermPositionVector(); + + /** + * Returns an array of TermVectorOffsetInfo in which the term is found. + * + * @param index The position in the array to get the offsets from + * @return An array of TermVectorOffsetInfo objects or the empty list + * @see org.apache.lucene.analysis.Token + */ + const CL_NS(util)::ArrayBase* getOffsets(const size_t index); + + /** + * Returns an array of positions in which the term is found. + * Terms are identified by the index at which its number appears in the + * term String array obtained from the indexOf method. + */ + const CL_NS(util)::ArrayBase* getTermPositions(const size_t index); + + // disambiguation + const TCHAR* getField(){ return SegmentTermVector::getField(); } + TCHAR* toString() const{ return SegmentTermVector::toString(); } + int32_t size(){ return SegmentTermVector::size(); } + const CL_NS(util)::ArrayBase* getTerms(){ return SegmentTermVector::getTerms(); } + const CL_NS(util)::ArrayBase* getTermFrequencies(){ return SegmentTermVector::getTermFrequencies(); } + int32_t indexOf(const TCHAR* termText){ return SegmentTermVector::indexOf(termText); } + CL_NS(util)::ArrayBase* indexesOf(const CL_NS(util)::ArrayBase& termNumbers, const int32_t start, const int32_t len); + + virtual TermPositionVector* __asTermPositionVector(); +}; + +/** + * The TermVectorMapper can be used to map Term Vectors into your own + * structure instead of the parallel array structure used by + * {@link org.apache.lucene.index.IndexReader#getTermFreqVector(int,String)}. + *

+ * It is up to the implementation to make sure it is thread-safe. + * + * + **/ +class CLUCENE_EXPORT TermVectorMapper : LUCENE_BASE{ +private: + bool ignoringPositions; + bool ignoringOffsets; + +protected: + TermVectorMapper(); + virtual ~TermVectorMapper(){}; + + /** + * + * @param ignoringPositions true if this mapper should tell Lucene to ignore positions even if they are stored + * @param ignoringOffsets similar to ignoringPositions + */ + TermVectorMapper(const bool _ignoringPositions, const bool _ignoringOffsets); + +public: + /** + * Tell the mapper what to expect in regards to field, number of terms, offset and position storage. + * This method will be called once before retrieving the vector for a field. + * + * This method will be called before {@link #map(String,int,TermVectorOffsetInfo[],int[])}. + * @param field The field the vector is for + * @param numTerms The number of terms that need to be mapped + * @param storeOffsets true if the mapper should expect offset information + * @param storePositions true if the mapper should expect positions info + */ + virtual void setExpectations(const TCHAR* _field, const int32_t numTerms, const bool storeOffsets, + const bool storePositions) = 0; + + /** + * Map the Term Vector information into your own structure + * @param term The term to add to the vector + * @param frequency The frequency of the term in the document + * @param offsets null if the offset is not specified, otherwise the offset into the field of the term + * @param positions null if the position is not specified, otherwise the position in the field of the term + * @memory offset and position objects must be cleaned up by implementing class + */ + virtual void map(const TCHAR* term, const int32_t termLen, const int32_t frequency, + CL_NS(util)::ArrayBase* _offsets, + CL_NS(util)::ArrayBase* _positions) = 0; + + /** + * Indicate to Lucene that even if there are positions stored, this mapper is not interested in them and they + * can be skipped over. Derived classes should set this to true if they want to ignore positions. The default + * is false, meaning positions will be loaded if they are stored. + * @return false + */ + bool isIgnoringPositions() const; + + /** + * + * @see #isIgnoringPositions() Same principal as {@link #isIgnoringPositions()}, but applied to offsets. false by default. + * @return false + */ + bool isIgnoringOffsets() const; + + /** + * Passes down the index of the document whose term vector is currently being mapped, + * once for each top level call to a term vector reader. + *

+ * Default implementation IGNORES the document number. Override if your implementation needs the document number. + *

+ * NOTE: Document numbers are internal to Lucene and subject to change depending on indexing operations. + * + * @param documentNumber index of document currently being mapped + */ + virtual void setDocumentNumber(const int32_t documentNumber); +}; + +/** + * Models the existing parallel array structure + */ +class ParallelArrayTermVectorMapper : public TermVectorMapper +{ +private: + CL_NS(util)::ArrayBase* terms; + CL_NS(util)::ArrayBase* termFreqs; + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* positions; + CL_NS(util)::ArrayBase< CL_NS(util)::ArrayBase* >* offsets; + int32_t currentPosition; + bool storingOffsets; + bool storingPositions; + TCHAR* field; + +public: + ParallelArrayTermVectorMapper(); + virtual ~ParallelArrayTermVectorMapper(); + + void setExpectations(const TCHAR* _field, const int32_t numTerms, + const bool storeOffsets, const bool storePositions); + + void map(const TCHAR* term, const int32_t termLen, const int32_t frequency, + CL_NS(util)::ArrayBase* _offsets, + CL_NS(util)::ArrayBase* _positions); + + /** + * Construct the vector + * @return The {@link TermFreqVector} based on the mappings. + * @memory Caller is responsible for freeing up the returned object + */ + TermFreqVector* materializeVector(); + + void reset() + { + currentPosition = 0; + } +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/index/bpacking.cpp b/src/core/CLucene/index/bpacking.cpp new file mode 100644 index 00000000000..bead69a1bed --- /dev/null +++ b/src/core/CLucene/index/bpacking.cpp @@ -0,0 +1,13859 @@ +/** +* +* This code is released under the +* Apache License Version 2.0 http://www.apache.org/licenses/. +* (c) Daniel Lemire 2013 +*/ + +#include "bpacking.h" + + + + +uint32_t * pack1_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack2_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack3_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack4_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack5_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack6_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack7_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack8_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack9_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack10_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack11_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack12_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack13_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack14_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack15_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack16_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack17_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack18_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack19_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack20_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack21_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack22_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack23_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack24_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack25_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack26_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack27_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 24 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack28_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack29_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 8 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack30_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack31_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 30 ); + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 29 ); + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 27 ); + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 24 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack32_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + + return out; +} + + + + +uint32_t * unpack1_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 1 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 2 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 3 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 4 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 5 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 6 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 7 ) & 1 ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack2_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 2 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack3_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 3 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack4_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack5_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 5 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 5 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack6_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 6 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 6 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack7_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 7 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 7 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack8_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack9_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 9 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 9 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack10_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 10 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 10 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 10 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack11_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 11 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 11 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 11 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack12_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack13_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 13 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 13 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 13 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack14_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 14 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 14 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 14 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 14 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack15_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 15 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 15 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 15 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 15 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack16_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack17_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 17 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 17 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 17 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 17 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack18_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 18 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 18 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 18 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 18 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack19_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 19 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 19 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 19 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 19 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 19 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack20_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack21_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 21 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 21 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 21 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 21 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 21 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack22_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 22 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 22 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 22 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 22 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 22 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack23_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 23 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 23 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 23 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 23 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 23 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 23 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack24_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack25_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 25 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 25 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 25 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 25 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 25 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 25 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack26_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 26 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 26 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 26 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 26 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 26 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 26 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack27_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 27 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 27 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 27 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 27 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 27 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 27 - 24 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack28_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack29_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 29 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 29 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 29 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 29 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 29 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 29 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 29 - 8 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack30_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 30 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 30 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 30 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 30 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 30 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 30 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 30 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 30 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack31_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 31 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 30 ))<<( 31 - 30 ); + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 29 ))<<( 31 - 29 ); + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 31 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 27 ))<<( 31 - 27 ); + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 31 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 31 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 31 - 24 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack32_8( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + +uint32_t * pack1_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack2_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack3_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 3 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack4_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack5_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack6_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack7_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack8_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack9_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack10_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack11_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack12_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack13_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack14_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack15_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + + return out + 1; +} + + + +uint32_t * pack16_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack17_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack18_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack19_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack20_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack21_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack22_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack23_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack24_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack25_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack26_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack27_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack28_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack29_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack30_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack31_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 30 ); + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 29 ); + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 27 ); + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 16 ); + ++in; + + return out + 1; +} + + + +uint32_t * pack32_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + + return out; +} + + + + +uint32_t * unpack1_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 1 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 2 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 3 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 4 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 5 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 6 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 7 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 8 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 9 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 10 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 11 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 12 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 13 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 14 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 15 ) & 1 ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack2_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack3_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 3 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 3 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack4_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack5_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 5 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 5 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 5 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack6_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 6 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 6 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack7_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 7 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 7 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 7 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 7 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack8_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack9_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 9 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 9 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 9 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 9 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 9 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack10_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 10 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 10 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 10 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 10 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack11_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 11 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 11 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 11 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 11 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 11 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 11 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack12_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack13_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 13 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 13 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 13 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 13 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 13 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 13 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 13 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack14_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 14 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 14 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 14 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 14 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 14 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 14 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack15_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 15 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 15 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 15 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 15 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 15 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 15 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 15 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 15 ) ; + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack16_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack17_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 17 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 17 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 17 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 17 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 17 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 17 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 17 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 17 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack18_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 18 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 18 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 18 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 18 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 18 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 18 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 18 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 18 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack19_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 19 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 19 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 19 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 19 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 19 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 19 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 19 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 19 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 19 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack20_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack21_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 21 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 21 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 21 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 21 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 21 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 21 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 21 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 21 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 21 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 21 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack22_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 22 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 22 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 22 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 22 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 22 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 22 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 22 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 22 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 22 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 22 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack23_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 23 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 23 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 23 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 23 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 23 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 23 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 23 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 23 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 23 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 23 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 23 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack24_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack25_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 25 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 25 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 25 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 25 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 25 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 25 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 25 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 25 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 25 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 25 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 25 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 25 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack26_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 26 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 26 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 26 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 26 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 26 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 26 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 26 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 26 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 26 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 26 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 26 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 26 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack27_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 27 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 27 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 27 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 27 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 27 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 27 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 27 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 27 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 27 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 27 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 27 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 27 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 27 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack28_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack29_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 29 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 29 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 29 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 29 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 29 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 29 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 29 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 29 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 29 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 29 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 29 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 29 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 29 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 29 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack30_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 30 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 30 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 30 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 30 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 30 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 30 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 30 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 30 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 30 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 30 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 30 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 30 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 30 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 30 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 30 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack31_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 31 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 30 ))<<( 31 - 30 ); + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 29 ))<<( 31 - 29 ); + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 31 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 27 ))<<( 31 - 27 ); + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 31 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 31 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 31 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 31 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 31 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 31 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 31 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 31 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 31 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 31 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 31 - 16 ); + *out += base; + out++; + + return in + 1; +} + + + + +uint32_t * unpack32_16( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + +uint32_t * pack1_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack2_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack3_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 3 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 3 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack4_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack5_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 5 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack6_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 6 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack7_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 7 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack8_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack9_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 9 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack10_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 10 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack11_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 11 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack12_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 12 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack13_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 13 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack14_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 14 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack15_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 15 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack16_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack17_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 17 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack18_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 18 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack19_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 19 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack20_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 20 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack21_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 21 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack22_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 22 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack23_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 23 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack24_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 24 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack25_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 25 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack26_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 26 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack27_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 27 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack28_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 28 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack29_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 27 ); + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 29 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack30_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 30 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack31_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++in; + *out |= static_cast( (*in) - base ) << 31 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 30 ); + ++in; + *out |= static_cast( (*in) - base ) << 30 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 29 ); + ++in; + *out |= static_cast( (*in) - base ) << 29 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 28 ); + ++in; + *out |= static_cast( (*in) - base ) << 28 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 27 ); + ++in; + *out |= static_cast( (*in) - base ) << 27 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 26 ); + ++in; + *out |= static_cast( (*in) - base ) << 26 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 25 ); + ++in; + *out |= static_cast( (*in) - base ) << 25 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 24 ); + ++in; + *out |= static_cast( (*in) - base ) << 24 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 23 ); + ++in; + *out |= static_cast( (*in) - base ) << 23 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 22 ); + ++in; + *out |= static_cast( (*in) - base ) << 22 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 21 ); + ++in; + *out |= static_cast( (*in) - base ) << 21 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 20 ); + ++in; + *out |= static_cast( (*in) - base ) << 20 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 19 ); + ++in; + *out |= static_cast( (*in) - base ) << 19 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 18 ); + ++in; + *out |= static_cast( (*in) - base ) << 18 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 17 ); + ++in; + *out |= static_cast( (*in) - base ) << 17 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 16 ); + ++in; + *out |= static_cast( (*in) - base ) << 16 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 15 ); + ++in; + *out |= static_cast( (*in) - base ) << 15 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 14 ); + ++in; + *out |= static_cast( (*in) - base ) << 14 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 13 ); + ++in; + *out |= static_cast( (*in) - base ) << 13 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 12 ); + ++in; + *out |= static_cast( (*in) - base ) << 12 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 11 ); + ++in; + *out |= static_cast( (*in) - base ) << 11 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 10 ); + ++in; + *out |= static_cast( (*in) - base ) << 10 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 9 ); + ++in; + *out |= static_cast( (*in) - base ) << 9 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 8 ); + ++in; + *out |= static_cast( (*in) - base ) << 8 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 7 ); + ++in; + *out |= static_cast( (*in) - base ) << 7 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 6 ); + ++in; + *out |= static_cast( (*in) - base ) << 6 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 5 ); + ++in; + *out |= static_cast( (*in) - base ) << 5 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 4 ); + ++in; + *out |= static_cast( (*in) - base ) << 4 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 3 ); + ++in; + *out |= static_cast( (*in) - base ) << 3 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 2 ); + ++in; + *out |= static_cast( (*in) - base ) << 2 ; + ++out; + *out = static_cast( (*in) - base ) >> ( 31 - 1 ); + ++in; + *out |= static_cast( (*in) - base ) << 1 ; + ++out; + ++in; + + return out; +} + + + +uint32_t * pack32_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + *out = static_cast((*in) -base) ; + ++out; + ++in; + + return out; +} + + + + +uint32_t * unpack1_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 1 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 2 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 3 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 4 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 5 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 6 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 7 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 8 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 9 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 10 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 11 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 12 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 13 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 14 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 15 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 16 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 17 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 18 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 19 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 20 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 21 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 22 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 23 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 24 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 25 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 26 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 27 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 28 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 29 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 30 ) & 1 ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack2_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) % (1U << 2 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack3_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 3 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 3 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) % (1U << 3 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack4_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 4 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack5_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 5 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 5 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 5 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 5 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 5 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack6_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 6 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 6 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 6 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 6 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 6 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack7_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 7 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 7 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 7 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 7 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 7 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 7 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 7 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack8_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 8 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack9_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 9 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 9 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 9 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 9 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 9 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 9 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 9 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 9 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 9 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack10_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 10 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 10 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 10 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 10 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 10 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 10 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 10 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 10 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 10 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack11_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 11 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 11 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 11 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 11 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 11 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 11 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 11 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 11 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 11 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 11 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 11 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack12_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 12 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 12 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 12 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack13_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 13 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 13 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 13 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 13 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 13 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 13 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 13 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 13 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 13 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 13 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 13 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 13 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 13 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack14_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 14 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 14 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 14 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 14 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 14 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 14 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 14 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 14 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 14 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 14 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 14 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 14 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 14 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack15_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 15 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 15 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 15 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 15 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 15 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 15 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 15 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 15 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 15 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 15 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 15 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 15 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 15 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 15 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 15 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 15 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack16_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 16 ) ; + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack17_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 17 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 17 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 17 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 17 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 17 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 17 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 17 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 17 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 17 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 17 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 17 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 17 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 17 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 17 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 17 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) % (1U << 17 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 17 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack18_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 18 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 18 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 18 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 18 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 18 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 18 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 18 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 18 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 18 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 18 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 18 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 18 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 18 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 18 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 18 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 18 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 18 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack19_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 19 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 19 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 19 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 19 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 19 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 19 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 19 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 19 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 19 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 19 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 19 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 19 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 19 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 19 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 19 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 19 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 19 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 19 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 19 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack20_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 20 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 20 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 20 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 20 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 20 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack21_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 21 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 21 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 21 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 21 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 21 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 21 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 21 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 21 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 21 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 21 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 21 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 21 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 21 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 21 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 21 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 21 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 21 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 21 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 21 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 21 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 21 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack22_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 22 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 22 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 22 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 22 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 22 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 22 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 22 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 22 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 22 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 22 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 22 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 22 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 22 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 22 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 22 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 22 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 22 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 22 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 22 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 22 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 22 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack23_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 23 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 23 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 23 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 23 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 23 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 23 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 23 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 23 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 23 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 23 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 23 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 23 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 23 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 23 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 23 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 23 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 23 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 23 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 23 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 23 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 23 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 23 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 23 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack24_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 24 ) ; + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 24 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 24 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack25_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 25 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 25 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 25 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 25 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 25 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 25 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 25 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 25 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 25 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 25 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 25 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 25 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 25 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 25 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 25 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 25 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 25 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 25 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 25 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 25 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 25 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 25 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 25 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 25 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 25 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack26_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 26 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 26 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 26 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 26 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 26 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 26 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 26 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 26 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 26 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 26 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 26 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 26 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 26 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 26 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 26 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 26 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 26 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 26 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 26 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 26 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 26 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 26 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 26 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 26 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 26 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack27_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 27 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 27 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 27 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 27 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 27 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 27 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 27 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 27 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 27 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 27 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 27 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 27 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 27 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 27 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 27 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 27 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 27 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 27 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 27 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 27 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 27 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) % (1U << 27 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 27 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 27 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 27 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 27 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 27 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack28_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 28 ) ; + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 28 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 28 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 28 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 28 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 28 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 28 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack29_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 29 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 29 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 29 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 29 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 29 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 29 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 29 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 29 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 29 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 29 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 29 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 29 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 29 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 29 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 29 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 29 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 29 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 29 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 29 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) % (1U << 29 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 27 ))<<( 29 - 27 ); + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 29 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 29 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 29 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 29 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 29 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 29 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 29 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 29 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack30_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 30 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 30 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 30 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 30 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 30 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 30 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 30 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 30 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 30 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 30 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 30 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 30 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 30 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 30 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 30 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) % (1U << 30 ) ; + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 30 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 30 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 30 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 30 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 30 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 30 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 30 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 30 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 30 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 30 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 30 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 30 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 30 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 30 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack31_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) % (1U << 31 ) ; + *out += base; + out++; + *out = ( (*in) >> 31 ) ; + ++in; + *out |= ((*in) % (1U<< 30 ))<<( 31 - 30 ); + *out += base; + out++; + *out = ( (*in) >> 30 ) ; + ++in; + *out |= ((*in) % (1U<< 29 ))<<( 31 - 29 ); + *out += base; + out++; + *out = ( (*in) >> 29 ) ; + ++in; + *out |= ((*in) % (1U<< 28 ))<<( 31 - 28 ); + *out += base; + out++; + *out = ( (*in) >> 28 ) ; + ++in; + *out |= ((*in) % (1U<< 27 ))<<( 31 - 27 ); + *out += base; + out++; + *out = ( (*in) >> 27 ) ; + ++in; + *out |= ((*in) % (1U<< 26 ))<<( 31 - 26 ); + *out += base; + out++; + *out = ( (*in) >> 26 ) ; + ++in; + *out |= ((*in) % (1U<< 25 ))<<( 31 - 25 ); + *out += base; + out++; + *out = ( (*in) >> 25 ) ; + ++in; + *out |= ((*in) % (1U<< 24 ))<<( 31 - 24 ); + *out += base; + out++; + *out = ( (*in) >> 24 ) ; + ++in; + *out |= ((*in) % (1U<< 23 ))<<( 31 - 23 ); + *out += base; + out++; + *out = ( (*in) >> 23 ) ; + ++in; + *out |= ((*in) % (1U<< 22 ))<<( 31 - 22 ); + *out += base; + out++; + *out = ( (*in) >> 22 ) ; + ++in; + *out |= ((*in) % (1U<< 21 ))<<( 31 - 21 ); + *out += base; + out++; + *out = ( (*in) >> 21 ) ; + ++in; + *out |= ((*in) % (1U<< 20 ))<<( 31 - 20 ); + *out += base; + out++; + *out = ( (*in) >> 20 ) ; + ++in; + *out |= ((*in) % (1U<< 19 ))<<( 31 - 19 ); + *out += base; + out++; + *out = ( (*in) >> 19 ) ; + ++in; + *out |= ((*in) % (1U<< 18 ))<<( 31 - 18 ); + *out += base; + out++; + *out = ( (*in) >> 18 ) ; + ++in; + *out |= ((*in) % (1U<< 17 ))<<( 31 - 17 ); + *out += base; + out++; + *out = ( (*in) >> 17 ) ; + ++in; + *out |= ((*in) % (1U<< 16 ))<<( 31 - 16 ); + *out += base; + out++; + *out = ( (*in) >> 16 ) ; + ++in; + *out |= ((*in) % (1U<< 15 ))<<( 31 - 15 ); + *out += base; + out++; + *out = ( (*in) >> 15 ) ; + ++in; + *out |= ((*in) % (1U<< 14 ))<<( 31 - 14 ); + *out += base; + out++; + *out = ( (*in) >> 14 ) ; + ++in; + *out |= ((*in) % (1U<< 13 ))<<( 31 - 13 ); + *out += base; + out++; + *out = ( (*in) >> 13 ) ; + ++in; + *out |= ((*in) % (1U<< 12 ))<<( 31 - 12 ); + *out += base; + out++; + *out = ( (*in) >> 12 ) ; + ++in; + *out |= ((*in) % (1U<< 11 ))<<( 31 - 11 ); + *out += base; + out++; + *out = ( (*in) >> 11 ) ; + ++in; + *out |= ((*in) % (1U<< 10 ))<<( 31 - 10 ); + *out += base; + out++; + *out = ( (*in) >> 10 ) ; + ++in; + *out |= ((*in) % (1U<< 9 ))<<( 31 - 9 ); + *out += base; + out++; + *out = ( (*in) >> 9 ) ; + ++in; + *out |= ((*in) % (1U<< 8 ))<<( 31 - 8 ); + *out += base; + out++; + *out = ( (*in) >> 8 ) ; + ++in; + *out |= ((*in) % (1U<< 7 ))<<( 31 - 7 ); + *out += base; + out++; + *out = ( (*in) >> 7 ) ; + ++in; + *out |= ((*in) % (1U<< 6 ))<<( 31 - 6 ); + *out += base; + out++; + *out = ( (*in) >> 6 ) ; + ++in; + *out |= ((*in) % (1U<< 5 ))<<( 31 - 5 ); + *out += base; + out++; + *out = ( (*in) >> 5 ) ; + ++in; + *out |= ((*in) % (1U<< 4 ))<<( 31 - 4 ); + *out += base; + out++; + *out = ( (*in) >> 4 ) ; + ++in; + *out |= ((*in) % (1U<< 3 ))<<( 31 - 3 ); + *out += base; + out++; + *out = ( (*in) >> 3 ) ; + ++in; + *out |= ((*in) % (1U<< 2 ))<<( 31 - 2 ); + *out += base; + out++; + *out = ( (*in) >> 2 ) ; + ++in; + *out |= ((*in) % (1U<< 1 ))<<( 31 - 1 ); + *out += base; + out++; + *out = ( (*in) >> 1 ) ; + ++in; + *out += base; + out++; + + return in; +} + + + + +uint32_t * unpack32_32( uint32_t base, uint32_t * in, uint32_t * out) { + + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + *out = ( (*in) >> 0 ) ; + ++in; + *out += base; + out++; + + return in; +} + + diff --git a/src/core/CLucene/index/bpacking.h b/src/core/CLucene/index/bpacking.h new file mode 100644 index 00000000000..0f3c797967c --- /dev/null +++ b/src/core/CLucene/index/bpacking.h @@ -0,0 +1,726 @@ +/** +* +* This code is released under the +* Apache License Version 2.0 http://www.apache.org/licenses/. +* (c) Daniel Lemire 2013 +*/ +#ifndef BPACKING +#define BPACKING + +#include "common.h" +uint32_t * pack1_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack2_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack3_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack4_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack5_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack6_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack7_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack8_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack9_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack10_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack11_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack12_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack13_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack14_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack15_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack16_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack17_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack18_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack19_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack20_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack21_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack22_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack23_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack24_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack25_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack26_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack27_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack28_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack29_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack30_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack31_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack32_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack1_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack2_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack3_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack4_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack5_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack6_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack7_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack8_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack9_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack10_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack11_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack12_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack13_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack14_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack15_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack16_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack17_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack18_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack19_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack20_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack21_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack22_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack23_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack24_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack25_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack26_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack27_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack28_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack29_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack30_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack31_8( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack32_8( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack1_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack2_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack3_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack4_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack5_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack6_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack7_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack8_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack9_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack10_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack11_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack12_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack13_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack14_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack15_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack16_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack17_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack18_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack19_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack20_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack21_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack22_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack23_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack24_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack25_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack26_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack27_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack28_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack29_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack30_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack31_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack32_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack1_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack2_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack3_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack4_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack5_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack6_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack7_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack8_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack9_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack10_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack11_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack12_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack13_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack14_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack15_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack16_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack17_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack18_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack19_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack20_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack21_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack22_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack23_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack24_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack25_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack26_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack27_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack28_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack29_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack30_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack31_16( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack32_16( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack1_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack2_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack3_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack4_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack5_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack6_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack7_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack8_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack9_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack10_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack11_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack12_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack13_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack14_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack15_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack16_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack17_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack18_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack19_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack20_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack21_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack22_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack23_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack24_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack25_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack26_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack27_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack28_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack29_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack30_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack31_32( uint32_t base, uint32_t * in, uint32_t * out); + +uint32_t * pack32_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack1_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack2_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack3_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack4_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack5_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack6_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack7_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack8_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack9_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack10_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack11_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack12_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack13_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack14_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack15_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack16_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack17_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack18_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack19_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack20_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack21_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack22_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack23_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack24_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack25_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack26_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack27_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack28_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack29_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack30_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack31_32( uint32_t base, uint32_t * in, uint32_t * out); + + +uint32_t * unpack32_32( uint32_t base, uint32_t * in, uint32_t * out); + + +typedef uint32_t * (*packfnc)( uint32_t, uint32_t * , uint32_t * ); + +static uint32_t * nullpacker( uint32_t, uint32_t * , uint32_t * out) { + return out; +} + +static uint32_t * nullunpacker8( uint32_t base, uint32_t * in , uint32_t * out) { + for(int k = 0; k < 8; ++k) { + out[k] = base; + } + return in; +} + +static uint32_t * nullunpacker16( uint32_t base, uint32_t * in , uint32_t * out) { + for(int k = 0; k < 8; ++k) { + out[k] = base; + } + return in; +} + +static uint32_t * nullunpacker32( uint32_t base, uint32_t * in , uint32_t * out) { + for(int k = 0; k < 8; ++k) { + out[k] = base; + } + return in; +} + + + +const static packfnc unpack8[33]= {nullunpacker8,unpack1_8, + unpack2_8, + unpack3_8, + unpack4_8, + unpack5_8, + unpack6_8, + unpack7_8, + unpack8_8, + unpack9_8, + unpack10_8, + unpack11_8, + unpack12_8, + unpack13_8, + unpack14_8, + unpack15_8, + unpack16_8, + unpack17_8, + unpack18_8, + unpack19_8, + unpack20_8, + unpack21_8, + unpack22_8, + unpack23_8, + unpack24_8, + unpack25_8, + unpack26_8, + unpack27_8, + unpack28_8, + unpack29_8, + unpack30_8, + unpack31_8, + unpack32_8 + }; + +const static packfnc pack8[33]= {nullpacker,pack1_8, + pack2_8, + pack3_8, + pack4_8, + pack5_8, + pack6_8, + pack7_8, + pack8_8, + pack9_8, + pack10_8, + pack11_8, + pack12_8, + pack13_8, + pack14_8, + pack15_8, + pack16_8, + pack17_8, + pack18_8, + pack19_8, + pack20_8, + pack21_8, + pack22_8, + pack23_8, + pack24_8, + pack25_8, + pack26_8, + pack27_8, + pack28_8, + pack29_8, + pack30_8, + pack31_8, + pack32_8 + }; + + +const static packfnc unpack16[33]= {nullunpacker16,unpack1_16, + unpack2_16, + unpack3_16, + unpack4_16, + unpack5_16, + unpack6_16, + unpack7_16, + unpack8_16, + unpack9_16, + unpack10_16, + unpack11_16, + unpack12_16, + unpack13_16, + unpack14_16, + unpack15_16, + unpack16_16, + unpack17_16, + unpack18_16, + unpack19_16, + unpack20_16, + unpack21_16, + unpack22_16, + unpack23_16, + unpack24_16, + unpack25_16, + unpack26_16, + unpack27_16, + unpack28_16, + unpack29_16, + unpack30_16, + unpack31_16, + unpack32_16 + }; + + +const static packfnc pack16[33]= {nullpacker,pack1_16, + pack2_16, + pack3_16, + pack4_16, + pack5_16, + pack6_16, + pack7_16, + pack8_16, + pack9_16, + pack10_16, + pack11_16, + pack12_16, + pack13_16, + pack14_16, + pack15_16, + pack16_16, + pack17_16, + pack18_16, + pack19_16, + pack20_16, + pack21_16, + pack22_16, + pack23_16, + pack24_16, + pack25_16, + pack26_16, + pack27_16, + pack28_16, + pack29_16, + pack30_16, + pack31_16, + pack32_16 + }; + +const static packfnc unpack32[33]= {nullunpacker32,unpack1_32, + unpack2_32, + unpack3_32, + unpack4_32, + unpack5_32, + unpack6_32, + unpack7_32, + unpack8_32, + unpack9_32, + unpack10_32, + unpack11_32, + unpack12_32, + unpack13_32, + unpack14_32, + unpack15_32, + unpack16_32, + unpack17_32, + unpack18_32, + unpack19_32, + unpack20_32, + unpack21_32, + unpack22_32, + unpack23_32, + unpack24_32, + unpack25_32, + unpack26_32, + unpack27_32, + unpack28_32, + unpack29_32, + unpack30_32, + unpack31_32, + unpack32_32 + }; + +const static packfnc pack32[33]= {nullpacker,pack1_32, + pack2_32, + pack3_32, + pack4_32, + pack5_32, + pack6_32, + pack7_32, + pack8_32, + pack9_32, + pack10_32, + pack11_32, + pack12_32, + pack13_32, + pack14_32, + pack15_32, + pack16_32, + pack17_32, + pack18_32, + pack19_32, + pack20_32, + pack21_32, + pack22_32, + pack23_32, + pack24_32, + pack25_32, + pack26_32, + pack27_32, + pack28_32, + pack29_32, + pack30_32, + pack31_32, + pack32_32 + }; +#endif diff --git a/src/core/CLucene/index/common.h b/src/core/CLucene/index/common.h new file mode 100644 index 00000000000..9fd5b9d8ff1 --- /dev/null +++ b/src/core/CLucene/index/common.h @@ -0,0 +1,26 @@ +/** +* +* This code is released under the +* Apache License Version 2.0 http://www.apache.org/licenses/. +* (c) Daniel Lemire 2013 +*/ + +#ifndef COMMON_H_ +#define COMMON_H_ + + +#include +#include +#include // mostly for Microsoft compilers +#include +#include // part of Visual Studio 2010 and better + +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* COMMON_H_ */ diff --git a/src/core/CLucene/index/compression.h b/src/core/CLucene/index/compression.h new file mode 100644 index 00000000000..016189d1deb --- /dev/null +++ b/src/core/CLucene/index/compression.h @@ -0,0 +1,88 @@ +/* + * compression.h + * + * Created on: Oct 28, 2013 + * Author: lemire + */ + +#ifndef COMPRESSION_H_ +#define COMPRESSION_H_ + +#include "bpacking.h" +#include "util.h" + +/** +* Compresses "length" values from "in" to "out" and return a pointer to the end of the compressed stream. +* The format is "number of values, minimal value, maximal value, followed by packed data". +*/ +inline uint32_t * compress(uint32_t * in, uint32_t length, uint32_t * out) { + out[0] = length; + ++out; + if(length == 0) return out; + uint32_t m = in[0]; + uint32_t M = in[0]; + for(uint32_t i = 1; i < length; ++i) { + if(in[i]>M) M=in[i]; + if(in[i](M-m)); + out[0] = m; + ++out; + out[0] = M; + ++out; + uint32_t k = 0; + for(; k+32<=length; k+=32,in+=32) { + out = pack32[b](m,in,out); + } + for(; k+16<=length; k+=16,in+=16) { + out = pack16[b](m,in,out); + } + for(; k+8<=length; k+=8,in+=8) { + out = pack8[b](m,in,out); + } + // we could pack the rest, but we don't bother + for(; k(M-m)); +#ifdef _OPENMP + #pragma omp parallel for +#endif + for(uint32_t k = 0; k M) + M = in[i]; + if (in[i] < m) + m = in[i]; + } + int b = bits(static_cast(M - m)); + memcpy(out, &m, sizeof(m)); + out += sizeof(m); + memcpy(out, &M, sizeof(M)); + out += sizeof(M); + uint32_t k = 0; + for (; k + 32 <= length; k += 32) { + funcForPackArr[b](m, &in, &out); + } + // we could pack the rest, but we don't bother + memcpy(out, in, (length - k) * sizeof(uint32_t)); + out += (length - k) * sizeof(uint32_t); + return out; +} + +/* +* uncompress FOR data found in "in". +* The format is "number of values, minimal value, maximal value, followed by +* packed data". +* The 'nvalue' variable receives the number of decoded values (initial value is +* ignored) +* The values are stored in "out". +* We return a pointer to the end of the compressed input stream. +*/ +inline const uint8_t *turbouncompress(const uint8_t *in, uint32_t *out, + uint32_t &nvalue) { + memcpy(&nvalue, in, sizeof(nvalue)); + in += sizeof(nvalue); + if (nvalue == 0) + return in; + uint32_t m, M; + memcpy(&m, in, sizeof(m)); + in += sizeof(m); + memcpy(&M, in, sizeof(M)); + in += sizeof(M); + int b = bits(static_cast(M - m)); +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (uint32_t k = 0; k < nvalue / 32; ++k) { + // could code as funcForUnpackArr[b](m,&in,&out); but it hurts + // parallelization + const uint8_t *input = in + 32 * b * k / 8; + uint32_t *output = out + k * 32; + funcForUnpackArr[b](m, &input, &output); + } + in = in + (32 * b / 8) * (nvalue / 32); + out = out + 32 * (nvalue / 32); + + // we could pack the rest, but we don't bother + uint32_t leftover = nvalue - nvalue / 32 * 32; + memcpy(out, in, leftover * sizeof(uint32_t)); + in += leftover * sizeof(uint32_t); + return in; +} + + + +/** +* Compresses "length" values from "in" to "out" and return a pointer to the end +* of the compressed stream. +* The format is "number of values, minimal value, maximal value, followed by +* packed data". +* +* Currently the implementation assumes that the integer arrays to be compressed +* are in multiples of 32, remaining integers are not compressed. Thus using this +* code on arrays smaller than 32 is wasteful. (This limitation will be removed +* in the future.) +*/ +inline uint8_t *turbocompress64(const uint64_t *in, uint32_t length, + uint8_t *out) { + memcpy(out, &length, sizeof(length)); + out += sizeof(length); + if (length == 0) + return out; + uint64_t m = in[0]; + uint64_t M = in[0]; + for (uint32_t i = 1; i < length; ++i) { + if (in[i] > M) + M = in[i]; + if (in[i] < m) + m = in[i]; + } + int b = bits64(static_cast(M - m)); + memcpy(out, &m, sizeof(m)); + out += sizeof(m); + memcpy(out, &M, sizeof(M)); + out += sizeof(M); + + uint32_t k = 0; + for (; k + 32 <= length; k += 32) { + funcForPackArr64[b](m, &in, &out); + } + // we could pack the rest, but we don't bother + memcpy(out, in, (length - k) * sizeof(uint64_t)); + out += (length - k) * sizeof(uint64_t); + return out; +} + +/* +* uncompress FOR data found in "in". +* The format is "number of values, minimal value, maximal value, followed by +* packed data". +* The 'nvalue' variable receives the number of decoded values (initial value is +* ignored) +* The values are stored in "out". +* We return a pointer to the end of the compressed input stream. +*/ +inline const uint8_t *turbouncompress64(const uint8_t *in, uint64_t *out, + uint32_t &nvalue) { + memcpy(&nvalue, in, sizeof(nvalue)); + in += sizeof(nvalue); + if (nvalue == 0) + return in; + uint64_t m, M; + memcpy(&m, in, sizeof(m)); + in += sizeof(m); + memcpy(&M, in, sizeof(M)); + in += sizeof(M); + int b = bits64(static_cast(M - m)); +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (uint32_t k = 0; k < nvalue / 32; ++k) { + // could code as funcForUnpackArr[b](m,&in,&out); but it hurts + // parallelization + const uint8_t *input = in + 32 * b * k / 8; + uint64_t *output = out + k * 32; + funcForUnpackArr64[b](m, &input, &output); + } + in = in + (32 * b / 8) * (nvalue / 32); + out = out + 32 * (nvalue / 32); + + // we could pack the rest, but we don't bother + uint32_t leftover = nvalue - nvalue / 32 * 32; + memcpy(out, in, leftover * sizeof(uint64_t)); + in += leftover * sizeof(uint64_t); + return in; +} + + +#endif /* COMPRESSION_H_ */ diff --git a/src/core/CLucene/index/turbopacking32.h b/src/core/CLucene/index/turbopacking32.h new file mode 100644 index 00000000000..7946ef1018b --- /dev/null +++ b/src/core/CLucene/index/turbopacking32.h @@ -0,0 +1,3836 @@ + +#ifndef INCLUDE_TURBOPACKING32_H +#define INCLUDE_TURBOPACKING32_H +#include // mostly for Microsoft compilers +#include // part of Visual Studio 2010 and better +#ifndef UINT64_C +#define UINT64_C(c) (c ## ULL) +#endif + +/** +* (c) Daniel Lemire +* Apache License 2.0 +*/ +/** turbopacking32 starts here **/ +/** +* this code mimics the way TurboPFor packs short arrays of integers. +* We pack and unpack always at least a full 64-bit word, plus whatever +* is necessary to get to an even number of bytes. +*/ +typedef void (*packforblockfnc)(const uint32_t base, const uint32_t **pin, + uint8_t **pw); +typedef void (*unpackforblockfnc)(const uint32_t base, const uint8_t **pw, + uint32_t **pout); + +static void packforblock0(const uint32_t, const uint32_t **pin, uint8_t **pw) { + (void)pw; + *pin += 32; /* we consumed 32 32-bit integers */ +} + +/* we are going to pack 32 1-bit values, touching 1 64-bit words, using 4 bytes + */ +static void packforblock1(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 1 64-bit word */ + uint64_t w0; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 1; + w0 |= (uint64_t)(in[2] - base) << 2; + w0 |= (uint64_t)(in[3] - base) << 3; + w0 |= (uint64_t)(in[4] - base) << 4; + w0 |= (uint64_t)(in[5] - base) << 5; + w0 |= (uint64_t)(in[6] - base) << 6; + w0 |= (uint64_t)(in[7] - base) << 7; + w0 |= (uint64_t)(in[8] - base) << 8; + w0 |= (uint64_t)(in[9] - base) << 9; + w0 |= (uint64_t)(in[10] - base) << 10; + w0 |= (uint64_t)(in[11] - base) << 11; + w0 |= (uint64_t)(in[12] - base) << 12; + w0 |= (uint64_t)(in[13] - base) << 13; + w0 |= (uint64_t)(in[14] - base) << 14; + w0 |= (uint64_t)(in[15] - base) << 15; + w0 |= (uint64_t)(in[16] - base) << 16; + w0 |= (uint64_t)(in[17] - base) << 17; + w0 |= (uint64_t)(in[18] - base) << 18; + w0 |= (uint64_t)(in[19] - base) << 19; + w0 |= (uint64_t)(in[20] - base) << 20; + w0 |= (uint64_t)(in[21] - base) << 21; + w0 |= (uint64_t)(in[22] - base) << 22; + w0 |= (uint64_t)(in[23] - base) << 23; + w0 |= (uint64_t)(in[24] - base) << 24; + w0 |= (uint64_t)(in[25] - base) << 25; + w0 |= (uint64_t)(in[26] - base) << 26; + w0 |= (uint64_t)(in[27] - base) << 27; + w0 |= (uint64_t)(in[28] - base) << 28; + w0 |= (uint64_t)(in[29] - base) << 29; + w0 |= (uint64_t)(in[30] - base) << 30; + w0 |= (uint64_t)(in[31] - base) << 31; + pw64[0] = w0; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 4; /* we used up 4 output bytes */ +} + +/* we are going to pack 32 2-bit values, touching 1 64-bit words, using 8 bytes + */ +static void packforblock2(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 1 64-bit word */ + uint64_t w0; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 2; + w0 |= (uint64_t)(in[2] - base) << 4; + w0 |= (uint64_t)(in[3] - base) << 6; + w0 |= (uint64_t)(in[4] - base) << 8; + w0 |= (uint64_t)(in[5] - base) << 10; + w0 |= (uint64_t)(in[6] - base) << 12; + w0 |= (uint64_t)(in[7] - base) << 14; + w0 |= (uint64_t)(in[8] - base) << 16; + w0 |= (uint64_t)(in[9] - base) << 18; + w0 |= (uint64_t)(in[10] - base) << 20; + w0 |= (uint64_t)(in[11] - base) << 22; + w0 |= (uint64_t)(in[12] - base) << 24; + w0 |= (uint64_t)(in[13] - base) << 26; + w0 |= (uint64_t)(in[14] - base) << 28; + w0 |= (uint64_t)(in[15] - base) << 30; + w0 |= (uint64_t)(in[16] - base) << 32; + w0 |= (uint64_t)(in[17] - base) << 34; + w0 |= (uint64_t)(in[18] - base) << 36; + w0 |= (uint64_t)(in[19] - base) << 38; + w0 |= (uint64_t)(in[20] - base) << 40; + w0 |= (uint64_t)(in[21] - base) << 42; + w0 |= (uint64_t)(in[22] - base) << 44; + w0 |= (uint64_t)(in[23] - base) << 46; + w0 |= (uint64_t)(in[24] - base) << 48; + w0 |= (uint64_t)(in[25] - base) << 50; + w0 |= (uint64_t)(in[26] - base) << 52; + w0 |= (uint64_t)(in[27] - base) << 54; + w0 |= (uint64_t)(in[28] - base) << 56; + w0 |= (uint64_t)(in[29] - base) << 58; + w0 |= (uint64_t)(in[30] - base) << 60; + w0 |= (uint64_t)(in[31] - base) << 62; + pw64[0] = w0; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 8; /* we used up 8 output bytes */ +} + +/* we are going to pack 32 3-bit values, touching 2 64-bit words, using 12 bytes + */ +static void packforblock3(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 2 64-bit words */ + uint64_t w0; + uint64_t w1; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 3; + w0 |= (uint64_t)(in[2] - base) << 6; + w0 |= (uint64_t)(in[3] - base) << 9; + w0 |= (uint64_t)(in[4] - base) << 12; + w0 |= (uint64_t)(in[5] - base) << 15; + w0 |= (uint64_t)(in[6] - base) << 18; + w0 |= (uint64_t)(in[7] - base) << 21; + w0 |= (uint64_t)(in[8] - base) << 24; + w0 |= (uint64_t)(in[9] - base) << 27; + w0 |= (uint64_t)(in[10] - base) << 30; + w0 |= (uint64_t)(in[11] - base) << 33; + w0 |= (uint64_t)(in[12] - base) << 36; + w0 |= (uint64_t)(in[13] - base) << 39; + w0 |= (uint64_t)(in[14] - base) << 42; + w0 |= (uint64_t)(in[15] - base) << 45; + w0 |= (uint64_t)(in[16] - base) << 48; + w0 |= (uint64_t)(in[17] - base) << 51; + w0 |= (uint64_t)(in[18] - base) << 54; + w0 |= (uint64_t)(in[19] - base) << 57; + w0 |= (uint64_t)(in[20] - base) << 60; + w0 |= (uint64_t)(in[21] - base) << 63; + w1 = (uint64_t)(in[21] - base) >> 1; + w1 |= (uint64_t)(in[22] - base) << 2; + w1 |= (uint64_t)(in[23] - base) << 5; + w1 |= (uint64_t)(in[24] - base) << 8; + w1 |= (uint64_t)(in[25] - base) << 11; + w1 |= (uint64_t)(in[26] - base) << 14; + w1 |= (uint64_t)(in[27] - base) << 17; + w1 |= (uint64_t)(in[28] - base) << 20; + w1 |= (uint64_t)(in[29] - base) << 23; + w1 |= (uint64_t)(in[30] - base) << 26; + w1 |= (uint64_t)(in[31] - base) << 29; + pw64[0] = w0; + pw64[1] = w1; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 12; /* we used up 12 output bytes */ +} + +/* we are going to pack 32 4-bit values, touching 2 64-bit words, using 16 bytes + */ +static void packforblock4(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 2 64-bit words */ + uint64_t w0; + uint64_t w1; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 4; + w0 |= (uint64_t)(in[2] - base) << 8; + w0 |= (uint64_t)(in[3] - base) << 12; + w0 |= (uint64_t)(in[4] - base) << 16; + w0 |= (uint64_t)(in[5] - base) << 20; + w0 |= (uint64_t)(in[6] - base) << 24; + w0 |= (uint64_t)(in[7] - base) << 28; + w0 |= (uint64_t)(in[8] - base) << 32; + w0 |= (uint64_t)(in[9] - base) << 36; + w0 |= (uint64_t)(in[10] - base) << 40; + w0 |= (uint64_t)(in[11] - base) << 44; + w0 |= (uint64_t)(in[12] - base) << 48; + w0 |= (uint64_t)(in[13] - base) << 52; + w0 |= (uint64_t)(in[14] - base) << 56; + w0 |= (uint64_t)(in[15] - base) << 60; + w1 = (uint64_t)(in[16] - base); + w1 |= (uint64_t)(in[17] - base) << 4; + w1 |= (uint64_t)(in[18] - base) << 8; + w1 |= (uint64_t)(in[19] - base) << 12; + w1 |= (uint64_t)(in[20] - base) << 16; + w1 |= (uint64_t)(in[21] - base) << 20; + w1 |= (uint64_t)(in[22] - base) << 24; + w1 |= (uint64_t)(in[23] - base) << 28; + w1 |= (uint64_t)(in[24] - base) << 32; + w1 |= (uint64_t)(in[25] - base) << 36; + w1 |= (uint64_t)(in[26] - base) << 40; + w1 |= (uint64_t)(in[27] - base) << 44; + w1 |= (uint64_t)(in[28] - base) << 48; + w1 |= (uint64_t)(in[29] - base) << 52; + w1 |= (uint64_t)(in[30] - base) << 56; + w1 |= (uint64_t)(in[31] - base) << 60; + pw64[0] = w0; + pw64[1] = w1; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 16; /* we used up 16 output bytes */ +} + +/* we are going to pack 32 5-bit values, touching 3 64-bit words, using 20 bytes + */ +static void packforblock5(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 3 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 5; + w0 |= (uint64_t)(in[2] - base) << 10; + w0 |= (uint64_t)(in[3] - base) << 15; + w0 |= (uint64_t)(in[4] - base) << 20; + w0 |= (uint64_t)(in[5] - base) << 25; + w0 |= (uint64_t)(in[6] - base) << 30; + w0 |= (uint64_t)(in[7] - base) << 35; + w0 |= (uint64_t)(in[8] - base) << 40; + w0 |= (uint64_t)(in[9] - base) << 45; + w0 |= (uint64_t)(in[10] - base) << 50; + w0 |= (uint64_t)(in[11] - base) << 55; + w0 |= (uint64_t)(in[12] - base) << 60; + w1 = (uint64_t)(in[12] - base) >> 4; + w1 |= (uint64_t)(in[13] - base) << 1; + w1 |= (uint64_t)(in[14] - base) << 6; + w1 |= (uint64_t)(in[15] - base) << 11; + w1 |= (uint64_t)(in[16] - base) << 16; + w1 |= (uint64_t)(in[17] - base) << 21; + w1 |= (uint64_t)(in[18] - base) << 26; + w1 |= (uint64_t)(in[19] - base) << 31; + w1 |= (uint64_t)(in[20] - base) << 36; + w1 |= (uint64_t)(in[21] - base) << 41; + w1 |= (uint64_t)(in[22] - base) << 46; + w1 |= (uint64_t)(in[23] - base) << 51; + w1 |= (uint64_t)(in[24] - base) << 56; + w1 |= (uint64_t)(in[25] - base) << 61; + w2 = (uint64_t)(in[25] - base) >> 3; + w2 |= (uint64_t)(in[26] - base) << 2; + w2 |= (uint64_t)(in[27] - base) << 7; + w2 |= (uint64_t)(in[28] - base) << 12; + w2 |= (uint64_t)(in[29] - base) << 17; + w2 |= (uint64_t)(in[30] - base) << 22; + w2 |= (uint64_t)(in[31] - base) << 27; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 20; /* we used up 20 output bytes */ +} + +/* we are going to pack 32 6-bit values, touching 3 64-bit words, using 24 bytes + */ +static void packforblock6(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 3 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 6; + w0 |= (uint64_t)(in[2] - base) << 12; + w0 |= (uint64_t)(in[3] - base) << 18; + w0 |= (uint64_t)(in[4] - base) << 24; + w0 |= (uint64_t)(in[5] - base) << 30; + w0 |= (uint64_t)(in[6] - base) << 36; + w0 |= (uint64_t)(in[7] - base) << 42; + w0 |= (uint64_t)(in[8] - base) << 48; + w0 |= (uint64_t)(in[9] - base) << 54; + w0 |= (uint64_t)(in[10] - base) << 60; + w1 = (uint64_t)(in[10] - base) >> 4; + w1 |= (uint64_t)(in[11] - base) << 2; + w1 |= (uint64_t)(in[12] - base) << 8; + w1 |= (uint64_t)(in[13] - base) << 14; + w1 |= (uint64_t)(in[14] - base) << 20; + w1 |= (uint64_t)(in[15] - base) << 26; + w1 |= (uint64_t)(in[16] - base) << 32; + w1 |= (uint64_t)(in[17] - base) << 38; + w1 |= (uint64_t)(in[18] - base) << 44; + w1 |= (uint64_t)(in[19] - base) << 50; + w1 |= (uint64_t)(in[20] - base) << 56; + w1 |= (uint64_t)(in[21] - base) << 62; + w2 = (uint64_t)(in[21] - base) >> 2; + w2 |= (uint64_t)(in[22] - base) << 4; + w2 |= (uint64_t)(in[23] - base) << 10; + w2 |= (uint64_t)(in[24] - base) << 16; + w2 |= (uint64_t)(in[25] - base) << 22; + w2 |= (uint64_t)(in[26] - base) << 28; + w2 |= (uint64_t)(in[27] - base) << 34; + w2 |= (uint64_t)(in[28] - base) << 40; + w2 |= (uint64_t)(in[29] - base) << 46; + w2 |= (uint64_t)(in[30] - base) << 52; + w2 |= (uint64_t)(in[31] - base) << 58; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 24; /* we used up 24 output bytes */ +} + +/* we are going to pack 32 7-bit values, touching 4 64-bit words, using 28 bytes + */ +static void packforblock7(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 4 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 7; + w0 |= (uint64_t)(in[2] - base) << 14; + w0 |= (uint64_t)(in[3] - base) << 21; + w0 |= (uint64_t)(in[4] - base) << 28; + w0 |= (uint64_t)(in[5] - base) << 35; + w0 |= (uint64_t)(in[6] - base) << 42; + w0 |= (uint64_t)(in[7] - base) << 49; + w0 |= (uint64_t)(in[8] - base) << 56; + w0 |= (uint64_t)(in[9] - base) << 63; + w1 = (uint64_t)(in[9] - base) >> 1; + w1 |= (uint64_t)(in[10] - base) << 6; + w1 |= (uint64_t)(in[11] - base) << 13; + w1 |= (uint64_t)(in[12] - base) << 20; + w1 |= (uint64_t)(in[13] - base) << 27; + w1 |= (uint64_t)(in[14] - base) << 34; + w1 |= (uint64_t)(in[15] - base) << 41; + w1 |= (uint64_t)(in[16] - base) << 48; + w1 |= (uint64_t)(in[17] - base) << 55; + w1 |= (uint64_t)(in[18] - base) << 62; + w2 = (uint64_t)(in[18] - base) >> 2; + w2 |= (uint64_t)(in[19] - base) << 5; + w2 |= (uint64_t)(in[20] - base) << 12; + w2 |= (uint64_t)(in[21] - base) << 19; + w2 |= (uint64_t)(in[22] - base) << 26; + w2 |= (uint64_t)(in[23] - base) << 33; + w2 |= (uint64_t)(in[24] - base) << 40; + w2 |= (uint64_t)(in[25] - base) << 47; + w2 |= (uint64_t)(in[26] - base) << 54; + w2 |= (uint64_t)(in[27] - base) << 61; + w3 = (uint64_t)(in[27] - base) >> 3; + w3 |= (uint64_t)(in[28] - base) << 4; + w3 |= (uint64_t)(in[29] - base) << 11; + w3 |= (uint64_t)(in[30] - base) << 18; + w3 |= (uint64_t)(in[31] - base) << 25; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 28; /* we used up 28 output bytes */ +} + +/* we are going to pack 32 8-bit values, touching 4 64-bit words, using 32 bytes + */ +static void packforblock8(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 4 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 8; + w0 |= (uint64_t)(in[2] - base) << 16; + w0 |= (uint64_t)(in[3] - base) << 24; + w0 |= (uint64_t)(in[4] - base) << 32; + w0 |= (uint64_t)(in[5] - base) << 40; + w0 |= (uint64_t)(in[6] - base) << 48; + w0 |= (uint64_t)(in[7] - base) << 56; + w1 = (uint64_t)(in[8] - base); + w1 |= (uint64_t)(in[9] - base) << 8; + w1 |= (uint64_t)(in[10] - base) << 16; + w1 |= (uint64_t)(in[11] - base) << 24; + w1 |= (uint64_t)(in[12] - base) << 32; + w1 |= (uint64_t)(in[13] - base) << 40; + w1 |= (uint64_t)(in[14] - base) << 48; + w1 |= (uint64_t)(in[15] - base) << 56; + w2 = (uint64_t)(in[16] - base); + w2 |= (uint64_t)(in[17] - base) << 8; + w2 |= (uint64_t)(in[18] - base) << 16; + w2 |= (uint64_t)(in[19] - base) << 24; + w2 |= (uint64_t)(in[20] - base) << 32; + w2 |= (uint64_t)(in[21] - base) << 40; + w2 |= (uint64_t)(in[22] - base) << 48; + w2 |= (uint64_t)(in[23] - base) << 56; + w3 = (uint64_t)(in[24] - base); + w3 |= (uint64_t)(in[25] - base) << 8; + w3 |= (uint64_t)(in[26] - base) << 16; + w3 |= (uint64_t)(in[27] - base) << 24; + w3 |= (uint64_t)(in[28] - base) << 32; + w3 |= (uint64_t)(in[29] - base) << 40; + w3 |= (uint64_t)(in[30] - base) << 48; + w3 |= (uint64_t)(in[31] - base) << 56; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 32; /* we used up 32 output bytes */ +} + +/* we are going to pack 32 9-bit values, touching 5 64-bit words, using 36 bytes + */ +static void packforblock9(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 5 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 9; + w0 |= (uint64_t)(in[2] - base) << 18; + w0 |= (uint64_t)(in[3] - base) << 27; + w0 |= (uint64_t)(in[4] - base) << 36; + w0 |= (uint64_t)(in[5] - base) << 45; + w0 |= (uint64_t)(in[6] - base) << 54; + w0 |= (uint64_t)(in[7] - base) << 63; + w1 = (uint64_t)(in[7] - base) >> 1; + w1 |= (uint64_t)(in[8] - base) << 8; + w1 |= (uint64_t)(in[9] - base) << 17; + w1 |= (uint64_t)(in[10] - base) << 26; + w1 |= (uint64_t)(in[11] - base) << 35; + w1 |= (uint64_t)(in[12] - base) << 44; + w1 |= (uint64_t)(in[13] - base) << 53; + w1 |= (uint64_t)(in[14] - base) << 62; + w2 = (uint64_t)(in[14] - base) >> 2; + w2 |= (uint64_t)(in[15] - base) << 7; + w2 |= (uint64_t)(in[16] - base) << 16; + w2 |= (uint64_t)(in[17] - base) << 25; + w2 |= (uint64_t)(in[18] - base) << 34; + w2 |= (uint64_t)(in[19] - base) << 43; + w2 |= (uint64_t)(in[20] - base) << 52; + w2 |= (uint64_t)(in[21] - base) << 61; + w3 = (uint64_t)(in[21] - base) >> 3; + w3 |= (uint64_t)(in[22] - base) << 6; + w3 |= (uint64_t)(in[23] - base) << 15; + w3 |= (uint64_t)(in[24] - base) << 24; + w3 |= (uint64_t)(in[25] - base) << 33; + w3 |= (uint64_t)(in[26] - base) << 42; + w3 |= (uint64_t)(in[27] - base) << 51; + w3 |= (uint64_t)(in[28] - base) << 60; + w4 = (uint64_t)(in[28] - base) >> 4; + w4 |= (uint64_t)(in[29] - base) << 5; + w4 |= (uint64_t)(in[30] - base) << 14; + w4 |= (uint64_t)(in[31] - base) << 23; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 36; /* we used up 36 output bytes */ +} + +/* we are going to pack 32 10-bit values, touching 5 64-bit words, using 40 + * bytes */ +static void packforblock10(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 5 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 10; + w0 |= (uint64_t)(in[2] - base) << 20; + w0 |= (uint64_t)(in[3] - base) << 30; + w0 |= (uint64_t)(in[4] - base) << 40; + w0 |= (uint64_t)(in[5] - base) << 50; + w0 |= (uint64_t)(in[6] - base) << 60; + w1 = (uint64_t)(in[6] - base) >> 4; + w1 |= (uint64_t)(in[7] - base) << 6; + w1 |= (uint64_t)(in[8] - base) << 16; + w1 |= (uint64_t)(in[9] - base) << 26; + w1 |= (uint64_t)(in[10] - base) << 36; + w1 |= (uint64_t)(in[11] - base) << 46; + w1 |= (uint64_t)(in[12] - base) << 56; + w2 = (uint64_t)(in[12] - base) >> 8; + w2 |= (uint64_t)(in[13] - base) << 2; + w2 |= (uint64_t)(in[14] - base) << 12; + w2 |= (uint64_t)(in[15] - base) << 22; + w2 |= (uint64_t)(in[16] - base) << 32; + w2 |= (uint64_t)(in[17] - base) << 42; + w2 |= (uint64_t)(in[18] - base) << 52; + w2 |= (uint64_t)(in[19] - base) << 62; + w3 = (uint64_t)(in[19] - base) >> 2; + w3 |= (uint64_t)(in[20] - base) << 8; + w3 |= (uint64_t)(in[21] - base) << 18; + w3 |= (uint64_t)(in[22] - base) << 28; + w3 |= (uint64_t)(in[23] - base) << 38; + w3 |= (uint64_t)(in[24] - base) << 48; + w3 |= (uint64_t)(in[25] - base) << 58; + w4 = (uint64_t)(in[25] - base) >> 6; + w4 |= (uint64_t)(in[26] - base) << 4; + w4 |= (uint64_t)(in[27] - base) << 14; + w4 |= (uint64_t)(in[28] - base) << 24; + w4 |= (uint64_t)(in[29] - base) << 34; + w4 |= (uint64_t)(in[30] - base) << 44; + w4 |= (uint64_t)(in[31] - base) << 54; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 40; /* we used up 40 output bytes */ +} + +/* we are going to pack 32 11-bit values, touching 6 64-bit words, using 44 + * bytes */ +static void packforblock11(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 6 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 11; + w0 |= (uint64_t)(in[2] - base) << 22; + w0 |= (uint64_t)(in[3] - base) << 33; + w0 |= (uint64_t)(in[4] - base) << 44; + w0 |= (uint64_t)(in[5] - base) << 55; + w1 = (uint64_t)(in[5] - base) >> 9; + w1 |= (uint64_t)(in[6] - base) << 2; + w1 |= (uint64_t)(in[7] - base) << 13; + w1 |= (uint64_t)(in[8] - base) << 24; + w1 |= (uint64_t)(in[9] - base) << 35; + w1 |= (uint64_t)(in[10] - base) << 46; + w1 |= (uint64_t)(in[11] - base) << 57; + w2 = (uint64_t)(in[11] - base) >> 7; + w2 |= (uint64_t)(in[12] - base) << 4; + w2 |= (uint64_t)(in[13] - base) << 15; + w2 |= (uint64_t)(in[14] - base) << 26; + w2 |= (uint64_t)(in[15] - base) << 37; + w2 |= (uint64_t)(in[16] - base) << 48; + w2 |= (uint64_t)(in[17] - base) << 59; + w3 = (uint64_t)(in[17] - base) >> 5; + w3 |= (uint64_t)(in[18] - base) << 6; + w3 |= (uint64_t)(in[19] - base) << 17; + w3 |= (uint64_t)(in[20] - base) << 28; + w3 |= (uint64_t)(in[21] - base) << 39; + w3 |= (uint64_t)(in[22] - base) << 50; + w3 |= (uint64_t)(in[23] - base) << 61; + w4 = (uint64_t)(in[23] - base) >> 3; + w4 |= (uint64_t)(in[24] - base) << 8; + w4 |= (uint64_t)(in[25] - base) << 19; + w4 |= (uint64_t)(in[26] - base) << 30; + w4 |= (uint64_t)(in[27] - base) << 41; + w4 |= (uint64_t)(in[28] - base) << 52; + w4 |= (uint64_t)(in[29] - base) << 63; + w5 = (uint64_t)(in[29] - base) >> 1; + w5 |= (uint64_t)(in[30] - base) << 10; + w5 |= (uint64_t)(in[31] - base) << 21; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 44; /* we used up 44 output bytes */ +} + +/* we are going to pack 32 12-bit values, touching 6 64-bit words, using 48 + * bytes */ +static void packforblock12(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 6 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 12; + w0 |= (uint64_t)(in[2] - base) << 24; + w0 |= (uint64_t)(in[3] - base) << 36; + w0 |= (uint64_t)(in[4] - base) << 48; + w0 |= (uint64_t)(in[5] - base) << 60; + w1 = (uint64_t)(in[5] - base) >> 4; + w1 |= (uint64_t)(in[6] - base) << 8; + w1 |= (uint64_t)(in[7] - base) << 20; + w1 |= (uint64_t)(in[8] - base) << 32; + w1 |= (uint64_t)(in[9] - base) << 44; + w1 |= (uint64_t)(in[10] - base) << 56; + w2 = (uint64_t)(in[10] - base) >> 8; + w2 |= (uint64_t)(in[11] - base) << 4; + w2 |= (uint64_t)(in[12] - base) << 16; + w2 |= (uint64_t)(in[13] - base) << 28; + w2 |= (uint64_t)(in[14] - base) << 40; + w2 |= (uint64_t)(in[15] - base) << 52; + w3 = (uint64_t)(in[16] - base); + w3 |= (uint64_t)(in[17] - base) << 12; + w3 |= (uint64_t)(in[18] - base) << 24; + w3 |= (uint64_t)(in[19] - base) << 36; + w3 |= (uint64_t)(in[20] - base) << 48; + w3 |= (uint64_t)(in[21] - base) << 60; + w4 = (uint64_t)(in[21] - base) >> 4; + w4 |= (uint64_t)(in[22] - base) << 8; + w4 |= (uint64_t)(in[23] - base) << 20; + w4 |= (uint64_t)(in[24] - base) << 32; + w4 |= (uint64_t)(in[25] - base) << 44; + w4 |= (uint64_t)(in[26] - base) << 56; + w5 = (uint64_t)(in[26] - base) >> 8; + w5 |= (uint64_t)(in[27] - base) << 4; + w5 |= (uint64_t)(in[28] - base) << 16; + w5 |= (uint64_t)(in[29] - base) << 28; + w5 |= (uint64_t)(in[30] - base) << 40; + w5 |= (uint64_t)(in[31] - base) << 52; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 48; /* we used up 48 output bytes */ +} + +/* we are going to pack 32 13-bit values, touching 7 64-bit words, using 52 + * bytes */ +static void packforblock13(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 7 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 13; + w0 |= (uint64_t)(in[2] - base) << 26; + w0 |= (uint64_t)(in[3] - base) << 39; + w0 |= (uint64_t)(in[4] - base) << 52; + w1 = (uint64_t)(in[4] - base) >> 12; + w1 |= (uint64_t)(in[5] - base) << 1; + w1 |= (uint64_t)(in[6] - base) << 14; + w1 |= (uint64_t)(in[7] - base) << 27; + w1 |= (uint64_t)(in[8] - base) << 40; + w1 |= (uint64_t)(in[9] - base) << 53; + w2 = (uint64_t)(in[9] - base) >> 11; + w2 |= (uint64_t)(in[10] - base) << 2; + w2 |= (uint64_t)(in[11] - base) << 15; + w2 |= (uint64_t)(in[12] - base) << 28; + w2 |= (uint64_t)(in[13] - base) << 41; + w2 |= (uint64_t)(in[14] - base) << 54; + w3 = (uint64_t)(in[14] - base) >> 10; + w3 |= (uint64_t)(in[15] - base) << 3; + w3 |= (uint64_t)(in[16] - base) << 16; + w3 |= (uint64_t)(in[17] - base) << 29; + w3 |= (uint64_t)(in[18] - base) << 42; + w3 |= (uint64_t)(in[19] - base) << 55; + w4 = (uint64_t)(in[19] - base) >> 9; + w4 |= (uint64_t)(in[20] - base) << 4; + w4 |= (uint64_t)(in[21] - base) << 17; + w4 |= (uint64_t)(in[22] - base) << 30; + w4 |= (uint64_t)(in[23] - base) << 43; + w4 |= (uint64_t)(in[24] - base) << 56; + w5 = (uint64_t)(in[24] - base) >> 8; + w5 |= (uint64_t)(in[25] - base) << 5; + w5 |= (uint64_t)(in[26] - base) << 18; + w5 |= (uint64_t)(in[27] - base) << 31; + w5 |= (uint64_t)(in[28] - base) << 44; + w5 |= (uint64_t)(in[29] - base) << 57; + w6 = (uint64_t)(in[29] - base) >> 7; + w6 |= (uint64_t)(in[30] - base) << 6; + w6 |= (uint64_t)(in[31] - base) << 19; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 52; /* we used up 52 output bytes */ +} + +/* we are going to pack 32 14-bit values, touching 7 64-bit words, using 56 + * bytes */ +static void packforblock14(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 7 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 14; + w0 |= (uint64_t)(in[2] - base) << 28; + w0 |= (uint64_t)(in[3] - base) << 42; + w0 |= (uint64_t)(in[4] - base) << 56; + w1 = (uint64_t)(in[4] - base) >> 8; + w1 |= (uint64_t)(in[5] - base) << 6; + w1 |= (uint64_t)(in[6] - base) << 20; + w1 |= (uint64_t)(in[7] - base) << 34; + w1 |= (uint64_t)(in[8] - base) << 48; + w1 |= (uint64_t)(in[9] - base) << 62; + w2 = (uint64_t)(in[9] - base) >> 2; + w2 |= (uint64_t)(in[10] - base) << 12; + w2 |= (uint64_t)(in[11] - base) << 26; + w2 |= (uint64_t)(in[12] - base) << 40; + w2 |= (uint64_t)(in[13] - base) << 54; + w3 = (uint64_t)(in[13] - base) >> 10; + w3 |= (uint64_t)(in[14] - base) << 4; + w3 |= (uint64_t)(in[15] - base) << 18; + w3 |= (uint64_t)(in[16] - base) << 32; + w3 |= (uint64_t)(in[17] - base) << 46; + w3 |= (uint64_t)(in[18] - base) << 60; + w4 = (uint64_t)(in[18] - base) >> 4; + w4 |= (uint64_t)(in[19] - base) << 10; + w4 |= (uint64_t)(in[20] - base) << 24; + w4 |= (uint64_t)(in[21] - base) << 38; + w4 |= (uint64_t)(in[22] - base) << 52; + w5 = (uint64_t)(in[22] - base) >> 12; + w5 |= (uint64_t)(in[23] - base) << 2; + w5 |= (uint64_t)(in[24] - base) << 16; + w5 |= (uint64_t)(in[25] - base) << 30; + w5 |= (uint64_t)(in[26] - base) << 44; + w5 |= (uint64_t)(in[27] - base) << 58; + w6 = (uint64_t)(in[27] - base) >> 6; + w6 |= (uint64_t)(in[28] - base) << 8; + w6 |= (uint64_t)(in[29] - base) << 22; + w6 |= (uint64_t)(in[30] - base) << 36; + w6 |= (uint64_t)(in[31] - base) << 50; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 56; /* we used up 56 output bytes */ +} + +/* we are going to pack 32 15-bit values, touching 8 64-bit words, using 60 + * bytes */ +static void packforblock15(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 8 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 15; + w0 |= (uint64_t)(in[2] - base) << 30; + w0 |= (uint64_t)(in[3] - base) << 45; + w0 |= (uint64_t)(in[4] - base) << 60; + w1 = (uint64_t)(in[4] - base) >> 4; + w1 |= (uint64_t)(in[5] - base) << 11; + w1 |= (uint64_t)(in[6] - base) << 26; + w1 |= (uint64_t)(in[7] - base) << 41; + w1 |= (uint64_t)(in[8] - base) << 56; + w2 = (uint64_t)(in[8] - base) >> 8; + w2 |= (uint64_t)(in[9] - base) << 7; + w2 |= (uint64_t)(in[10] - base) << 22; + w2 |= (uint64_t)(in[11] - base) << 37; + w2 |= (uint64_t)(in[12] - base) << 52; + w3 = (uint64_t)(in[12] - base) >> 12; + w3 |= (uint64_t)(in[13] - base) << 3; + w3 |= (uint64_t)(in[14] - base) << 18; + w3 |= (uint64_t)(in[15] - base) << 33; + w3 |= (uint64_t)(in[16] - base) << 48; + w3 |= (uint64_t)(in[17] - base) << 63; + w4 = (uint64_t)(in[17] - base) >> 1; + w4 |= (uint64_t)(in[18] - base) << 14; + w4 |= (uint64_t)(in[19] - base) << 29; + w4 |= (uint64_t)(in[20] - base) << 44; + w4 |= (uint64_t)(in[21] - base) << 59; + w5 = (uint64_t)(in[21] - base) >> 5; + w5 |= (uint64_t)(in[22] - base) << 10; + w5 |= (uint64_t)(in[23] - base) << 25; + w5 |= (uint64_t)(in[24] - base) << 40; + w5 |= (uint64_t)(in[25] - base) << 55; + w6 = (uint64_t)(in[25] - base) >> 9; + w6 |= (uint64_t)(in[26] - base) << 6; + w6 |= (uint64_t)(in[27] - base) << 21; + w6 |= (uint64_t)(in[28] - base) << 36; + w6 |= (uint64_t)(in[29] - base) << 51; + w7 = (uint64_t)(in[29] - base) >> 13; + w7 |= (uint64_t)(in[30] - base) << 2; + w7 |= (uint64_t)(in[31] - base) << 17; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 60; /* we used up 60 output bytes */ +} + +/* we are going to pack 32 16-bit values, touching 8 64-bit words, using 64 + * bytes */ +static void packforblock16(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 8 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 16; + w0 |= (uint64_t)(in[2] - base) << 32; + w0 |= (uint64_t)(in[3] - base) << 48; + w1 = (uint64_t)(in[4] - base); + w1 |= (uint64_t)(in[5] - base) << 16; + w1 |= (uint64_t)(in[6] - base) << 32; + w1 |= (uint64_t)(in[7] - base) << 48; + w2 = (uint64_t)(in[8] - base); + w2 |= (uint64_t)(in[9] - base) << 16; + w2 |= (uint64_t)(in[10] - base) << 32; + w2 |= (uint64_t)(in[11] - base) << 48; + w3 = (uint64_t)(in[12] - base); + w3 |= (uint64_t)(in[13] - base) << 16; + w3 |= (uint64_t)(in[14] - base) << 32; + w3 |= (uint64_t)(in[15] - base) << 48; + w4 = (uint64_t)(in[16] - base); + w4 |= (uint64_t)(in[17] - base) << 16; + w4 |= (uint64_t)(in[18] - base) << 32; + w4 |= (uint64_t)(in[19] - base) << 48; + w5 = (uint64_t)(in[20] - base); + w5 |= (uint64_t)(in[21] - base) << 16; + w5 |= (uint64_t)(in[22] - base) << 32; + w5 |= (uint64_t)(in[23] - base) << 48; + w6 = (uint64_t)(in[24] - base); + w6 |= (uint64_t)(in[25] - base) << 16; + w6 |= (uint64_t)(in[26] - base) << 32; + w6 |= (uint64_t)(in[27] - base) << 48; + w7 = (uint64_t)(in[28] - base); + w7 |= (uint64_t)(in[29] - base) << 16; + w7 |= (uint64_t)(in[30] - base) << 32; + w7 |= (uint64_t)(in[31] - base) << 48; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 64; /* we used up 64 output bytes */ +} + +/* we are going to pack 32 17-bit values, touching 9 64-bit words, using 68 + * bytes */ +static void packforblock17(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 9 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 17; + w0 |= (uint64_t)(in[2] - base) << 34; + w0 |= (uint64_t)(in[3] - base) << 51; + w1 = (uint64_t)(in[3] - base) >> 13; + w1 |= (uint64_t)(in[4] - base) << 4; + w1 |= (uint64_t)(in[5] - base) << 21; + w1 |= (uint64_t)(in[6] - base) << 38; + w1 |= (uint64_t)(in[7] - base) << 55; + w2 = (uint64_t)(in[7] - base) >> 9; + w2 |= (uint64_t)(in[8] - base) << 8; + w2 |= (uint64_t)(in[9] - base) << 25; + w2 |= (uint64_t)(in[10] - base) << 42; + w2 |= (uint64_t)(in[11] - base) << 59; + w3 = (uint64_t)(in[11] - base) >> 5; + w3 |= (uint64_t)(in[12] - base) << 12; + w3 |= (uint64_t)(in[13] - base) << 29; + w3 |= (uint64_t)(in[14] - base) << 46; + w3 |= (uint64_t)(in[15] - base) << 63; + w4 = (uint64_t)(in[15] - base) >> 1; + w4 |= (uint64_t)(in[16] - base) << 16; + w4 |= (uint64_t)(in[17] - base) << 33; + w4 |= (uint64_t)(in[18] - base) << 50; + w5 = (uint64_t)(in[18] - base) >> 14; + w5 |= (uint64_t)(in[19] - base) << 3; + w5 |= (uint64_t)(in[20] - base) << 20; + w5 |= (uint64_t)(in[21] - base) << 37; + w5 |= (uint64_t)(in[22] - base) << 54; + w6 = (uint64_t)(in[22] - base) >> 10; + w6 |= (uint64_t)(in[23] - base) << 7; + w6 |= (uint64_t)(in[24] - base) << 24; + w6 |= (uint64_t)(in[25] - base) << 41; + w6 |= (uint64_t)(in[26] - base) << 58; + w7 = (uint64_t)(in[26] - base) >> 6; + w7 |= (uint64_t)(in[27] - base) << 11; + w7 |= (uint64_t)(in[28] - base) << 28; + w7 |= (uint64_t)(in[29] - base) << 45; + w7 |= (uint64_t)(in[30] - base) << 62; + w8 = (uint64_t)(in[30] - base) >> 2; + w8 |= (uint64_t)(in[31] - base) << 15; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 68; /* we used up 68 output bytes */ +} + +/* we are going to pack 32 18-bit values, touching 9 64-bit words, using 72 + * bytes */ +static void packforblock18(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 9 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 18; + w0 |= (uint64_t)(in[2] - base) << 36; + w0 |= (uint64_t)(in[3] - base) << 54; + w1 = (uint64_t)(in[3] - base) >> 10; + w1 |= (uint64_t)(in[4] - base) << 8; + w1 |= (uint64_t)(in[5] - base) << 26; + w1 |= (uint64_t)(in[6] - base) << 44; + w1 |= (uint64_t)(in[7] - base) << 62; + w2 = (uint64_t)(in[7] - base) >> 2; + w2 |= (uint64_t)(in[8] - base) << 16; + w2 |= (uint64_t)(in[9] - base) << 34; + w2 |= (uint64_t)(in[10] - base) << 52; + w3 = (uint64_t)(in[10] - base) >> 12; + w3 |= (uint64_t)(in[11] - base) << 6; + w3 |= (uint64_t)(in[12] - base) << 24; + w3 |= (uint64_t)(in[13] - base) << 42; + w3 |= (uint64_t)(in[14] - base) << 60; + w4 = (uint64_t)(in[14] - base) >> 4; + w4 |= (uint64_t)(in[15] - base) << 14; + w4 |= (uint64_t)(in[16] - base) << 32; + w4 |= (uint64_t)(in[17] - base) << 50; + w5 = (uint64_t)(in[17] - base) >> 14; + w5 |= (uint64_t)(in[18] - base) << 4; + w5 |= (uint64_t)(in[19] - base) << 22; + w5 |= (uint64_t)(in[20] - base) << 40; + w5 |= (uint64_t)(in[21] - base) << 58; + w6 = (uint64_t)(in[21] - base) >> 6; + w6 |= (uint64_t)(in[22] - base) << 12; + w6 |= (uint64_t)(in[23] - base) << 30; + w6 |= (uint64_t)(in[24] - base) << 48; + w7 = (uint64_t)(in[24] - base) >> 16; + w7 |= (uint64_t)(in[25] - base) << 2; + w7 |= (uint64_t)(in[26] - base) << 20; + w7 |= (uint64_t)(in[27] - base) << 38; + w7 |= (uint64_t)(in[28] - base) << 56; + w8 = (uint64_t)(in[28] - base) >> 8; + w8 |= (uint64_t)(in[29] - base) << 10; + w8 |= (uint64_t)(in[30] - base) << 28; + w8 |= (uint64_t)(in[31] - base) << 46; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 72; /* we used up 72 output bytes */ +} + +/* we are going to pack 32 19-bit values, touching 10 64-bit words, using 76 + * bytes */ +static void packforblock19(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 10 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 19; + w0 |= (uint64_t)(in[2] - base) << 38; + w0 |= (uint64_t)(in[3] - base) << 57; + w1 = (uint64_t)(in[3] - base) >> 7; + w1 |= (uint64_t)(in[4] - base) << 12; + w1 |= (uint64_t)(in[5] - base) << 31; + w1 |= (uint64_t)(in[6] - base) << 50; + w2 = (uint64_t)(in[6] - base) >> 14; + w2 |= (uint64_t)(in[7] - base) << 5; + w2 |= (uint64_t)(in[8] - base) << 24; + w2 |= (uint64_t)(in[9] - base) << 43; + w2 |= (uint64_t)(in[10] - base) << 62; + w3 = (uint64_t)(in[10] - base) >> 2; + w3 |= (uint64_t)(in[11] - base) << 17; + w3 |= (uint64_t)(in[12] - base) << 36; + w3 |= (uint64_t)(in[13] - base) << 55; + w4 = (uint64_t)(in[13] - base) >> 9; + w4 |= (uint64_t)(in[14] - base) << 10; + w4 |= (uint64_t)(in[15] - base) << 29; + w4 |= (uint64_t)(in[16] - base) << 48; + w5 = (uint64_t)(in[16] - base) >> 16; + w5 |= (uint64_t)(in[17] - base) << 3; + w5 |= (uint64_t)(in[18] - base) << 22; + w5 |= (uint64_t)(in[19] - base) << 41; + w5 |= (uint64_t)(in[20] - base) << 60; + w6 = (uint64_t)(in[20] - base) >> 4; + w6 |= (uint64_t)(in[21] - base) << 15; + w6 |= (uint64_t)(in[22] - base) << 34; + w6 |= (uint64_t)(in[23] - base) << 53; + w7 = (uint64_t)(in[23] - base) >> 11; + w7 |= (uint64_t)(in[24] - base) << 8; + w7 |= (uint64_t)(in[25] - base) << 27; + w7 |= (uint64_t)(in[26] - base) << 46; + w8 = (uint64_t)(in[26] - base) >> 18; + w8 |= (uint64_t)(in[27] - base) << 1; + w8 |= (uint64_t)(in[28] - base) << 20; + w8 |= (uint64_t)(in[29] - base) << 39; + w8 |= (uint64_t)(in[30] - base) << 58; + w9 = (uint64_t)(in[30] - base) >> 6; + w9 |= (uint64_t)(in[31] - base) << 13; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 76; /* we used up 76 output bytes */ +} + +/* we are going to pack 32 20-bit values, touching 10 64-bit words, using 80 + * bytes */ +static void packforblock20(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 10 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 20; + w0 |= (uint64_t)(in[2] - base) << 40; + w0 |= (uint64_t)(in[3] - base) << 60; + w1 = (uint64_t)(in[3] - base) >> 4; + w1 |= (uint64_t)(in[4] - base) << 16; + w1 |= (uint64_t)(in[5] - base) << 36; + w1 |= (uint64_t)(in[6] - base) << 56; + w2 = (uint64_t)(in[6] - base) >> 8; + w2 |= (uint64_t)(in[7] - base) << 12; + w2 |= (uint64_t)(in[8] - base) << 32; + w2 |= (uint64_t)(in[9] - base) << 52; + w3 = (uint64_t)(in[9] - base) >> 12; + w3 |= (uint64_t)(in[10] - base) << 8; + w3 |= (uint64_t)(in[11] - base) << 28; + w3 |= (uint64_t)(in[12] - base) << 48; + w4 = (uint64_t)(in[12] - base) >> 16; + w4 |= (uint64_t)(in[13] - base) << 4; + w4 |= (uint64_t)(in[14] - base) << 24; + w4 |= (uint64_t)(in[15] - base) << 44; + w5 = (uint64_t)(in[16] - base); + w5 |= (uint64_t)(in[17] - base) << 20; + w5 |= (uint64_t)(in[18] - base) << 40; + w5 |= (uint64_t)(in[19] - base) << 60; + w6 = (uint64_t)(in[19] - base) >> 4; + w6 |= (uint64_t)(in[20] - base) << 16; + w6 |= (uint64_t)(in[21] - base) << 36; + w6 |= (uint64_t)(in[22] - base) << 56; + w7 = (uint64_t)(in[22] - base) >> 8; + w7 |= (uint64_t)(in[23] - base) << 12; + w7 |= (uint64_t)(in[24] - base) << 32; + w7 |= (uint64_t)(in[25] - base) << 52; + w8 = (uint64_t)(in[25] - base) >> 12; + w8 |= (uint64_t)(in[26] - base) << 8; + w8 |= (uint64_t)(in[27] - base) << 28; + w8 |= (uint64_t)(in[28] - base) << 48; + w9 = (uint64_t)(in[28] - base) >> 16; + w9 |= (uint64_t)(in[29] - base) << 4; + w9 |= (uint64_t)(in[30] - base) << 24; + w9 |= (uint64_t)(in[31] - base) << 44; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 80; /* we used up 80 output bytes */ +} + +/* we are going to pack 32 21-bit values, touching 11 64-bit words, using 84 + * bytes */ +static void packforblock21(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 11 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 21; + w0 |= (uint64_t)(in[2] - base) << 42; + w0 |= (uint64_t)(in[3] - base) << 63; + w1 = (uint64_t)(in[3] - base) >> 1; + w1 |= (uint64_t)(in[4] - base) << 20; + w1 |= (uint64_t)(in[5] - base) << 41; + w1 |= (uint64_t)(in[6] - base) << 62; + w2 = (uint64_t)(in[6] - base) >> 2; + w2 |= (uint64_t)(in[7] - base) << 19; + w2 |= (uint64_t)(in[8] - base) << 40; + w2 |= (uint64_t)(in[9] - base) << 61; + w3 = (uint64_t)(in[9] - base) >> 3; + w3 |= (uint64_t)(in[10] - base) << 18; + w3 |= (uint64_t)(in[11] - base) << 39; + w3 |= (uint64_t)(in[12] - base) << 60; + w4 = (uint64_t)(in[12] - base) >> 4; + w4 |= (uint64_t)(in[13] - base) << 17; + w4 |= (uint64_t)(in[14] - base) << 38; + w4 |= (uint64_t)(in[15] - base) << 59; + w5 = (uint64_t)(in[15] - base) >> 5; + w5 |= (uint64_t)(in[16] - base) << 16; + w5 |= (uint64_t)(in[17] - base) << 37; + w5 |= (uint64_t)(in[18] - base) << 58; + w6 = (uint64_t)(in[18] - base) >> 6; + w6 |= (uint64_t)(in[19] - base) << 15; + w6 |= (uint64_t)(in[20] - base) << 36; + w6 |= (uint64_t)(in[21] - base) << 57; + w7 = (uint64_t)(in[21] - base) >> 7; + w7 |= (uint64_t)(in[22] - base) << 14; + w7 |= (uint64_t)(in[23] - base) << 35; + w7 |= (uint64_t)(in[24] - base) << 56; + w8 = (uint64_t)(in[24] - base) >> 8; + w8 |= (uint64_t)(in[25] - base) << 13; + w8 |= (uint64_t)(in[26] - base) << 34; + w8 |= (uint64_t)(in[27] - base) << 55; + w9 = (uint64_t)(in[27] - base) >> 9; + w9 |= (uint64_t)(in[28] - base) << 12; + w9 |= (uint64_t)(in[29] - base) << 33; + w9 |= (uint64_t)(in[30] - base) << 54; + w10 = (uint64_t)(in[30] - base) >> 10; + w10 |= (uint64_t)(in[31] - base) << 11; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 84; /* we used up 84 output bytes */ +} + +/* we are going to pack 32 22-bit values, touching 11 64-bit words, using 88 + * bytes */ +static void packforblock22(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 11 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 22; + w0 |= (uint64_t)(in[2] - base) << 44; + w1 = (uint64_t)(in[2] - base) >> 20; + w1 |= (uint64_t)(in[3] - base) << 2; + w1 |= (uint64_t)(in[4] - base) << 24; + w1 |= (uint64_t)(in[5] - base) << 46; + w2 = (uint64_t)(in[5] - base) >> 18; + w2 |= (uint64_t)(in[6] - base) << 4; + w2 |= (uint64_t)(in[7] - base) << 26; + w2 |= (uint64_t)(in[8] - base) << 48; + w3 = (uint64_t)(in[8] - base) >> 16; + w3 |= (uint64_t)(in[9] - base) << 6; + w3 |= (uint64_t)(in[10] - base) << 28; + w3 |= (uint64_t)(in[11] - base) << 50; + w4 = (uint64_t)(in[11] - base) >> 14; + w4 |= (uint64_t)(in[12] - base) << 8; + w4 |= (uint64_t)(in[13] - base) << 30; + w4 |= (uint64_t)(in[14] - base) << 52; + w5 = (uint64_t)(in[14] - base) >> 12; + w5 |= (uint64_t)(in[15] - base) << 10; + w5 |= (uint64_t)(in[16] - base) << 32; + w5 |= (uint64_t)(in[17] - base) << 54; + w6 = (uint64_t)(in[17] - base) >> 10; + w6 |= (uint64_t)(in[18] - base) << 12; + w6 |= (uint64_t)(in[19] - base) << 34; + w6 |= (uint64_t)(in[20] - base) << 56; + w7 = (uint64_t)(in[20] - base) >> 8; + w7 |= (uint64_t)(in[21] - base) << 14; + w7 |= (uint64_t)(in[22] - base) << 36; + w7 |= (uint64_t)(in[23] - base) << 58; + w8 = (uint64_t)(in[23] - base) >> 6; + w8 |= (uint64_t)(in[24] - base) << 16; + w8 |= (uint64_t)(in[25] - base) << 38; + w8 |= (uint64_t)(in[26] - base) << 60; + w9 = (uint64_t)(in[26] - base) >> 4; + w9 |= (uint64_t)(in[27] - base) << 18; + w9 |= (uint64_t)(in[28] - base) << 40; + w9 |= (uint64_t)(in[29] - base) << 62; + w10 = (uint64_t)(in[29] - base) >> 2; + w10 |= (uint64_t)(in[30] - base) << 20; + w10 |= (uint64_t)(in[31] - base) << 42; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 88; /* we used up 88 output bytes */ +} + +/* we are going to pack 32 23-bit values, touching 12 64-bit words, using 92 + * bytes */ +static void packforblock23(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 12 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 23; + w0 |= (uint64_t)(in[2] - base) << 46; + w1 = (uint64_t)(in[2] - base) >> 18; + w1 |= (uint64_t)(in[3] - base) << 5; + w1 |= (uint64_t)(in[4] - base) << 28; + w1 |= (uint64_t)(in[5] - base) << 51; + w2 = (uint64_t)(in[5] - base) >> 13; + w2 |= (uint64_t)(in[6] - base) << 10; + w2 |= (uint64_t)(in[7] - base) << 33; + w2 |= (uint64_t)(in[8] - base) << 56; + w3 = (uint64_t)(in[8] - base) >> 8; + w3 |= (uint64_t)(in[9] - base) << 15; + w3 |= (uint64_t)(in[10] - base) << 38; + w3 |= (uint64_t)(in[11] - base) << 61; + w4 = (uint64_t)(in[11] - base) >> 3; + w4 |= (uint64_t)(in[12] - base) << 20; + w4 |= (uint64_t)(in[13] - base) << 43; + w5 = (uint64_t)(in[13] - base) >> 21; + w5 |= (uint64_t)(in[14] - base) << 2; + w5 |= (uint64_t)(in[15] - base) << 25; + w5 |= (uint64_t)(in[16] - base) << 48; + w6 = (uint64_t)(in[16] - base) >> 16; + w6 |= (uint64_t)(in[17] - base) << 7; + w6 |= (uint64_t)(in[18] - base) << 30; + w6 |= (uint64_t)(in[19] - base) << 53; + w7 = (uint64_t)(in[19] - base) >> 11; + w7 |= (uint64_t)(in[20] - base) << 12; + w7 |= (uint64_t)(in[21] - base) << 35; + w7 |= (uint64_t)(in[22] - base) << 58; + w8 = (uint64_t)(in[22] - base) >> 6; + w8 |= (uint64_t)(in[23] - base) << 17; + w8 |= (uint64_t)(in[24] - base) << 40; + w8 |= (uint64_t)(in[25] - base) << 63; + w9 = (uint64_t)(in[25] - base) >> 1; + w9 |= (uint64_t)(in[26] - base) << 22; + w9 |= (uint64_t)(in[27] - base) << 45; + w10 = (uint64_t)(in[27] - base) >> 19; + w10 |= (uint64_t)(in[28] - base) << 4; + w10 |= (uint64_t)(in[29] - base) << 27; + w10 |= (uint64_t)(in[30] - base) << 50; + w11 = (uint64_t)(in[30] - base) >> 14; + w11 |= (uint64_t)(in[31] - base) << 9; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 92; /* we used up 92 output bytes */ +} + +/* we are going to pack 32 24-bit values, touching 12 64-bit words, using 96 + * bytes */ +static void packforblock24(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 12 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 24; + w0 |= (uint64_t)(in[2] - base) << 48; + w1 = (uint64_t)(in[2] - base) >> 16; + w1 |= (uint64_t)(in[3] - base) << 8; + w1 |= (uint64_t)(in[4] - base) << 32; + w1 |= (uint64_t)(in[5] - base) << 56; + w2 = (uint64_t)(in[5] - base) >> 8; + w2 |= (uint64_t)(in[6] - base) << 16; + w2 |= (uint64_t)(in[7] - base) << 40; + w3 = (uint64_t)(in[8] - base); + w3 |= (uint64_t)(in[9] - base) << 24; + w3 |= (uint64_t)(in[10] - base) << 48; + w4 = (uint64_t)(in[10] - base) >> 16; + w4 |= (uint64_t)(in[11] - base) << 8; + w4 |= (uint64_t)(in[12] - base) << 32; + w4 |= (uint64_t)(in[13] - base) << 56; + w5 = (uint64_t)(in[13] - base) >> 8; + w5 |= (uint64_t)(in[14] - base) << 16; + w5 |= (uint64_t)(in[15] - base) << 40; + w6 = (uint64_t)(in[16] - base); + w6 |= (uint64_t)(in[17] - base) << 24; + w6 |= (uint64_t)(in[18] - base) << 48; + w7 = (uint64_t)(in[18] - base) >> 16; + w7 |= (uint64_t)(in[19] - base) << 8; + w7 |= (uint64_t)(in[20] - base) << 32; + w7 |= (uint64_t)(in[21] - base) << 56; + w8 = (uint64_t)(in[21] - base) >> 8; + w8 |= (uint64_t)(in[22] - base) << 16; + w8 |= (uint64_t)(in[23] - base) << 40; + w9 = (uint64_t)(in[24] - base); + w9 |= (uint64_t)(in[25] - base) << 24; + w9 |= (uint64_t)(in[26] - base) << 48; + w10 = (uint64_t)(in[26] - base) >> 16; + w10 |= (uint64_t)(in[27] - base) << 8; + w10 |= (uint64_t)(in[28] - base) << 32; + w10 |= (uint64_t)(in[29] - base) << 56; + w11 = (uint64_t)(in[29] - base) >> 8; + w11 |= (uint64_t)(in[30] - base) << 16; + w11 |= (uint64_t)(in[31] - base) << 40; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 96; /* we used up 96 output bytes */ +} + +/* we are going to pack 32 25-bit values, touching 13 64-bit words, using 100 + * bytes */ +static void packforblock25(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 13 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 25; + w0 |= (uint64_t)(in[2] - base) << 50; + w1 = (uint64_t)(in[2] - base) >> 14; + w1 |= (uint64_t)(in[3] - base) << 11; + w1 |= (uint64_t)(in[4] - base) << 36; + w1 |= (uint64_t)(in[5] - base) << 61; + w2 = (uint64_t)(in[5] - base) >> 3; + w2 |= (uint64_t)(in[6] - base) << 22; + w2 |= (uint64_t)(in[7] - base) << 47; + w3 = (uint64_t)(in[7] - base) >> 17; + w3 |= (uint64_t)(in[8] - base) << 8; + w3 |= (uint64_t)(in[9] - base) << 33; + w3 |= (uint64_t)(in[10] - base) << 58; + w4 = (uint64_t)(in[10] - base) >> 6; + w4 |= (uint64_t)(in[11] - base) << 19; + w4 |= (uint64_t)(in[12] - base) << 44; + w5 = (uint64_t)(in[12] - base) >> 20; + w5 |= (uint64_t)(in[13] - base) << 5; + w5 |= (uint64_t)(in[14] - base) << 30; + w5 |= (uint64_t)(in[15] - base) << 55; + w6 = (uint64_t)(in[15] - base) >> 9; + w6 |= (uint64_t)(in[16] - base) << 16; + w6 |= (uint64_t)(in[17] - base) << 41; + w7 = (uint64_t)(in[17] - base) >> 23; + w7 |= (uint64_t)(in[18] - base) << 2; + w7 |= (uint64_t)(in[19] - base) << 27; + w7 |= (uint64_t)(in[20] - base) << 52; + w8 = (uint64_t)(in[20] - base) >> 12; + w8 |= (uint64_t)(in[21] - base) << 13; + w8 |= (uint64_t)(in[22] - base) << 38; + w8 |= (uint64_t)(in[23] - base) << 63; + w9 = (uint64_t)(in[23] - base) >> 1; + w9 |= (uint64_t)(in[24] - base) << 24; + w9 |= (uint64_t)(in[25] - base) << 49; + w10 = (uint64_t)(in[25] - base) >> 15; + w10 |= (uint64_t)(in[26] - base) << 10; + w10 |= (uint64_t)(in[27] - base) << 35; + w10 |= (uint64_t)(in[28] - base) << 60; + w11 = (uint64_t)(in[28] - base) >> 4; + w11 |= (uint64_t)(in[29] - base) << 21; + w11 |= (uint64_t)(in[30] - base) << 46; + w12 = (uint64_t)(in[30] - base) >> 18; + w12 |= (uint64_t)(in[31] - base) << 7; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 100; /* we used up 100 output bytes */ +} + +/* we are going to pack 32 26-bit values, touching 13 64-bit words, using 104 + * bytes */ +static void packforblock26(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 13 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 26; + w0 |= (uint64_t)(in[2] - base) << 52; + w1 = (uint64_t)(in[2] - base) >> 12; + w1 |= (uint64_t)(in[3] - base) << 14; + w1 |= (uint64_t)(in[4] - base) << 40; + w2 = (uint64_t)(in[4] - base) >> 24; + w2 |= (uint64_t)(in[5] - base) << 2; + w2 |= (uint64_t)(in[6] - base) << 28; + w2 |= (uint64_t)(in[7] - base) << 54; + w3 = (uint64_t)(in[7] - base) >> 10; + w3 |= (uint64_t)(in[8] - base) << 16; + w3 |= (uint64_t)(in[9] - base) << 42; + w4 = (uint64_t)(in[9] - base) >> 22; + w4 |= (uint64_t)(in[10] - base) << 4; + w4 |= (uint64_t)(in[11] - base) << 30; + w4 |= (uint64_t)(in[12] - base) << 56; + w5 = (uint64_t)(in[12] - base) >> 8; + w5 |= (uint64_t)(in[13] - base) << 18; + w5 |= (uint64_t)(in[14] - base) << 44; + w6 = (uint64_t)(in[14] - base) >> 20; + w6 |= (uint64_t)(in[15] - base) << 6; + w6 |= (uint64_t)(in[16] - base) << 32; + w6 |= (uint64_t)(in[17] - base) << 58; + w7 = (uint64_t)(in[17] - base) >> 6; + w7 |= (uint64_t)(in[18] - base) << 20; + w7 |= (uint64_t)(in[19] - base) << 46; + w8 = (uint64_t)(in[19] - base) >> 18; + w8 |= (uint64_t)(in[20] - base) << 8; + w8 |= (uint64_t)(in[21] - base) << 34; + w8 |= (uint64_t)(in[22] - base) << 60; + w9 = (uint64_t)(in[22] - base) >> 4; + w9 |= (uint64_t)(in[23] - base) << 22; + w9 |= (uint64_t)(in[24] - base) << 48; + w10 = (uint64_t)(in[24] - base) >> 16; + w10 |= (uint64_t)(in[25] - base) << 10; + w10 |= (uint64_t)(in[26] - base) << 36; + w10 |= (uint64_t)(in[27] - base) << 62; + w11 = (uint64_t)(in[27] - base) >> 2; + w11 |= (uint64_t)(in[28] - base) << 24; + w11 |= (uint64_t)(in[29] - base) << 50; + w12 = (uint64_t)(in[29] - base) >> 14; + w12 |= (uint64_t)(in[30] - base) << 12; + w12 |= (uint64_t)(in[31] - base) << 38; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 104; /* we used up 104 output bytes */ +} + +/* we are going to pack 32 27-bit values, touching 14 64-bit words, using 108 + * bytes */ +static void packforblock27(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 14 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 27; + w0 |= (uint64_t)(in[2] - base) << 54; + w1 = (uint64_t)(in[2] - base) >> 10; + w1 |= (uint64_t)(in[3] - base) << 17; + w1 |= (uint64_t)(in[4] - base) << 44; + w2 = (uint64_t)(in[4] - base) >> 20; + w2 |= (uint64_t)(in[5] - base) << 7; + w2 |= (uint64_t)(in[6] - base) << 34; + w2 |= (uint64_t)(in[7] - base) << 61; + w3 = (uint64_t)(in[7] - base) >> 3; + w3 |= (uint64_t)(in[8] - base) << 24; + w3 |= (uint64_t)(in[9] - base) << 51; + w4 = (uint64_t)(in[9] - base) >> 13; + w4 |= (uint64_t)(in[10] - base) << 14; + w4 |= (uint64_t)(in[11] - base) << 41; + w5 = (uint64_t)(in[11] - base) >> 23; + w5 |= (uint64_t)(in[12] - base) << 4; + w5 |= (uint64_t)(in[13] - base) << 31; + w5 |= (uint64_t)(in[14] - base) << 58; + w6 = (uint64_t)(in[14] - base) >> 6; + w6 |= (uint64_t)(in[15] - base) << 21; + w6 |= (uint64_t)(in[16] - base) << 48; + w7 = (uint64_t)(in[16] - base) >> 16; + w7 |= (uint64_t)(in[17] - base) << 11; + w7 |= (uint64_t)(in[18] - base) << 38; + w8 = (uint64_t)(in[18] - base) >> 26; + w8 |= (uint64_t)(in[19] - base) << 1; + w8 |= (uint64_t)(in[20] - base) << 28; + w8 |= (uint64_t)(in[21] - base) << 55; + w9 = (uint64_t)(in[21] - base) >> 9; + w9 |= (uint64_t)(in[22] - base) << 18; + w9 |= (uint64_t)(in[23] - base) << 45; + w10 = (uint64_t)(in[23] - base) >> 19; + w10 |= (uint64_t)(in[24] - base) << 8; + w10 |= (uint64_t)(in[25] - base) << 35; + w10 |= (uint64_t)(in[26] - base) << 62; + w11 = (uint64_t)(in[26] - base) >> 2; + w11 |= (uint64_t)(in[27] - base) << 25; + w11 |= (uint64_t)(in[28] - base) << 52; + w12 = (uint64_t)(in[28] - base) >> 12; + w12 |= (uint64_t)(in[29] - base) << 15; + w12 |= (uint64_t)(in[30] - base) << 42; + w13 = (uint64_t)(in[30] - base) >> 22; + w13 |= (uint64_t)(in[31] - base) << 5; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 108; /* we used up 108 output bytes */ +} + +/* we are going to pack 32 28-bit values, touching 14 64-bit words, using 112 + * bytes */ +static void packforblock28(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 14 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 28; + w0 |= (uint64_t)(in[2] - base) << 56; + w1 = (uint64_t)(in[2] - base) >> 8; + w1 |= (uint64_t)(in[3] - base) << 20; + w1 |= (uint64_t)(in[4] - base) << 48; + w2 = (uint64_t)(in[4] - base) >> 16; + w2 |= (uint64_t)(in[5] - base) << 12; + w2 |= (uint64_t)(in[6] - base) << 40; + w3 = (uint64_t)(in[6] - base) >> 24; + w3 |= (uint64_t)(in[7] - base) << 4; + w3 |= (uint64_t)(in[8] - base) << 32; + w3 |= (uint64_t)(in[9] - base) << 60; + w4 = (uint64_t)(in[9] - base) >> 4; + w4 |= (uint64_t)(in[10] - base) << 24; + w4 |= (uint64_t)(in[11] - base) << 52; + w5 = (uint64_t)(in[11] - base) >> 12; + w5 |= (uint64_t)(in[12] - base) << 16; + w5 |= (uint64_t)(in[13] - base) << 44; + w6 = (uint64_t)(in[13] - base) >> 20; + w6 |= (uint64_t)(in[14] - base) << 8; + w6 |= (uint64_t)(in[15] - base) << 36; + w7 = (uint64_t)(in[16] - base); + w7 |= (uint64_t)(in[17] - base) << 28; + w7 |= (uint64_t)(in[18] - base) << 56; + w8 = (uint64_t)(in[18] - base) >> 8; + w8 |= (uint64_t)(in[19] - base) << 20; + w8 |= (uint64_t)(in[20] - base) << 48; + w9 = (uint64_t)(in[20] - base) >> 16; + w9 |= (uint64_t)(in[21] - base) << 12; + w9 |= (uint64_t)(in[22] - base) << 40; + w10 = (uint64_t)(in[22] - base) >> 24; + w10 |= (uint64_t)(in[23] - base) << 4; + w10 |= (uint64_t)(in[24] - base) << 32; + w10 |= (uint64_t)(in[25] - base) << 60; + w11 = (uint64_t)(in[25] - base) >> 4; + w11 |= (uint64_t)(in[26] - base) << 24; + w11 |= (uint64_t)(in[27] - base) << 52; + w12 = (uint64_t)(in[27] - base) >> 12; + w12 |= (uint64_t)(in[28] - base) << 16; + w12 |= (uint64_t)(in[29] - base) << 44; + w13 = (uint64_t)(in[29] - base) >> 20; + w13 |= (uint64_t)(in[30] - base) << 8; + w13 |= (uint64_t)(in[31] - base) << 36; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 112; /* we used up 112 output bytes */ +} + +/* we are going to pack 32 29-bit values, touching 15 64-bit words, using 116 + * bytes */ +static void packforblock29(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 15 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 29; + w0 |= (uint64_t)(in[2] - base) << 58; + w1 = (uint64_t)(in[2] - base) >> 6; + w1 |= (uint64_t)(in[3] - base) << 23; + w1 |= (uint64_t)(in[4] - base) << 52; + w2 = (uint64_t)(in[4] - base) >> 12; + w2 |= (uint64_t)(in[5] - base) << 17; + w2 |= (uint64_t)(in[6] - base) << 46; + w3 = (uint64_t)(in[6] - base) >> 18; + w3 |= (uint64_t)(in[7] - base) << 11; + w3 |= (uint64_t)(in[8] - base) << 40; + w4 = (uint64_t)(in[8] - base) >> 24; + w4 |= (uint64_t)(in[9] - base) << 5; + w4 |= (uint64_t)(in[10] - base) << 34; + w4 |= (uint64_t)(in[11] - base) << 63; + w5 = (uint64_t)(in[11] - base) >> 1; + w5 |= (uint64_t)(in[12] - base) << 28; + w5 |= (uint64_t)(in[13] - base) << 57; + w6 = (uint64_t)(in[13] - base) >> 7; + w6 |= (uint64_t)(in[14] - base) << 22; + w6 |= (uint64_t)(in[15] - base) << 51; + w7 = (uint64_t)(in[15] - base) >> 13; + w7 |= (uint64_t)(in[16] - base) << 16; + w7 |= (uint64_t)(in[17] - base) << 45; + w8 = (uint64_t)(in[17] - base) >> 19; + w8 |= (uint64_t)(in[18] - base) << 10; + w8 |= (uint64_t)(in[19] - base) << 39; + w9 = (uint64_t)(in[19] - base) >> 25; + w9 |= (uint64_t)(in[20] - base) << 4; + w9 |= (uint64_t)(in[21] - base) << 33; + w9 |= (uint64_t)(in[22] - base) << 62; + w10 = (uint64_t)(in[22] - base) >> 2; + w10 |= (uint64_t)(in[23] - base) << 27; + w10 |= (uint64_t)(in[24] - base) << 56; + w11 = (uint64_t)(in[24] - base) >> 8; + w11 |= (uint64_t)(in[25] - base) << 21; + w11 |= (uint64_t)(in[26] - base) << 50; + w12 = (uint64_t)(in[26] - base) >> 14; + w12 |= (uint64_t)(in[27] - base) << 15; + w12 |= (uint64_t)(in[28] - base) << 44; + w13 = (uint64_t)(in[28] - base) >> 20; + w13 |= (uint64_t)(in[29] - base) << 9; + w13 |= (uint64_t)(in[30] - base) << 38; + w14 = (uint64_t)(in[30] - base) >> 26; + w14 |= (uint64_t)(in[31] - base) << 3; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 116; /* we used up 116 output bytes */ +} + +/* we are going to pack 32 30-bit values, touching 15 64-bit words, using 120 + * bytes */ +static void packforblock30(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 15 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 30; + w0 |= (uint64_t)(in[2] - base) << 60; + w1 = (uint64_t)(in[2] - base) >> 4; + w1 |= (uint64_t)(in[3] - base) << 26; + w1 |= (uint64_t)(in[4] - base) << 56; + w2 = (uint64_t)(in[4] - base) >> 8; + w2 |= (uint64_t)(in[5] - base) << 22; + w2 |= (uint64_t)(in[6] - base) << 52; + w3 = (uint64_t)(in[6] - base) >> 12; + w3 |= (uint64_t)(in[7] - base) << 18; + w3 |= (uint64_t)(in[8] - base) << 48; + w4 = (uint64_t)(in[8] - base) >> 16; + w4 |= (uint64_t)(in[9] - base) << 14; + w4 |= (uint64_t)(in[10] - base) << 44; + w5 = (uint64_t)(in[10] - base) >> 20; + w5 |= (uint64_t)(in[11] - base) << 10; + w5 |= (uint64_t)(in[12] - base) << 40; + w6 = (uint64_t)(in[12] - base) >> 24; + w6 |= (uint64_t)(in[13] - base) << 6; + w6 |= (uint64_t)(in[14] - base) << 36; + w7 = (uint64_t)(in[14] - base) >> 28; + w7 |= (uint64_t)(in[15] - base) << 2; + w7 |= (uint64_t)(in[16] - base) << 32; + w7 |= (uint64_t)(in[17] - base) << 62; + w8 = (uint64_t)(in[17] - base) >> 2; + w8 |= (uint64_t)(in[18] - base) << 28; + w8 |= (uint64_t)(in[19] - base) << 58; + w9 = (uint64_t)(in[19] - base) >> 6; + w9 |= (uint64_t)(in[20] - base) << 24; + w9 |= (uint64_t)(in[21] - base) << 54; + w10 = (uint64_t)(in[21] - base) >> 10; + w10 |= (uint64_t)(in[22] - base) << 20; + w10 |= (uint64_t)(in[23] - base) << 50; + w11 = (uint64_t)(in[23] - base) >> 14; + w11 |= (uint64_t)(in[24] - base) << 16; + w11 |= (uint64_t)(in[25] - base) << 46; + w12 = (uint64_t)(in[25] - base) >> 18; + w12 |= (uint64_t)(in[26] - base) << 12; + w12 |= (uint64_t)(in[27] - base) << 42; + w13 = (uint64_t)(in[27] - base) >> 22; + w13 |= (uint64_t)(in[28] - base) << 8; + w13 |= (uint64_t)(in[29] - base) << 38; + w14 = (uint64_t)(in[29] - base) >> 26; + w14 |= (uint64_t)(in[30] - base) << 4; + w14 |= (uint64_t)(in[31] - base) << 34; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 120; /* we used up 120 output bytes */ +} + +/* we are going to pack 32 31-bit values, touching 16 64-bit words, using 124 + * bytes */ +static void packforblock31(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 16 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 31; + w0 |= (uint64_t)(in[2] - base) << 62; + w1 = (uint64_t)(in[2] - base) >> 2; + w1 |= (uint64_t)(in[3] - base) << 29; + w1 |= (uint64_t)(in[4] - base) << 60; + w2 = (uint64_t)(in[4] - base) >> 4; + w2 |= (uint64_t)(in[5] - base) << 27; + w2 |= (uint64_t)(in[6] - base) << 58; + w3 = (uint64_t)(in[6] - base) >> 6; + w3 |= (uint64_t)(in[7] - base) << 25; + w3 |= (uint64_t)(in[8] - base) << 56; + w4 = (uint64_t)(in[8] - base) >> 8; + w4 |= (uint64_t)(in[9] - base) << 23; + w4 |= (uint64_t)(in[10] - base) << 54; + w5 = (uint64_t)(in[10] - base) >> 10; + w5 |= (uint64_t)(in[11] - base) << 21; + w5 |= (uint64_t)(in[12] - base) << 52; + w6 = (uint64_t)(in[12] - base) >> 12; + w6 |= (uint64_t)(in[13] - base) << 19; + w6 |= (uint64_t)(in[14] - base) << 50; + w7 = (uint64_t)(in[14] - base) >> 14; + w7 |= (uint64_t)(in[15] - base) << 17; + w7 |= (uint64_t)(in[16] - base) << 48; + w8 = (uint64_t)(in[16] - base) >> 16; + w8 |= (uint64_t)(in[17] - base) << 15; + w8 |= (uint64_t)(in[18] - base) << 46; + w9 = (uint64_t)(in[18] - base) >> 18; + w9 |= (uint64_t)(in[19] - base) << 13; + w9 |= (uint64_t)(in[20] - base) << 44; + w10 = (uint64_t)(in[20] - base) >> 20; + w10 |= (uint64_t)(in[21] - base) << 11; + w10 |= (uint64_t)(in[22] - base) << 42; + w11 = (uint64_t)(in[22] - base) >> 22; + w11 |= (uint64_t)(in[23] - base) << 9; + w11 |= (uint64_t)(in[24] - base) << 40; + w12 = (uint64_t)(in[24] - base) >> 24; + w12 |= (uint64_t)(in[25] - base) << 7; + w12 |= (uint64_t)(in[26] - base) << 38; + w13 = (uint64_t)(in[26] - base) >> 26; + w13 |= (uint64_t)(in[27] - base) << 5; + w13 |= (uint64_t)(in[28] - base) << 36; + w14 = (uint64_t)(in[28] - base) >> 28; + w14 |= (uint64_t)(in[29] - base) << 3; + w14 |= (uint64_t)(in[30] - base) << 34; + w15 = (uint64_t)(in[30] - base) >> 30; + w15 |= (uint64_t)(in[31] - base) << 1; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 124; /* we used up 124 output bytes */ +} + +/* we are going to pack 32 32-bit values, touching 16 64-bit words, using 128 + * bytes */ +static void packforblock32(const uint32_t base, const uint32_t **pin, + uint8_t **pw) { + uint64_t *pw64 = *(uint64_t **)pw; + const uint32_t *in = *pin; + /* we are going to touch 16 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + w0 = (uint64_t)(in[0] - base); + w0 |= (uint64_t)(in[1] - base) << 32; + w1 = (uint64_t)(in[2] - base); + w1 |= (uint64_t)(in[3] - base) << 32; + w2 = (uint64_t)(in[4] - base); + w2 |= (uint64_t)(in[5] - base) << 32; + w3 = (uint64_t)(in[6] - base); + w3 |= (uint64_t)(in[7] - base) << 32; + w4 = (uint64_t)(in[8] - base); + w4 |= (uint64_t)(in[9] - base) << 32; + w5 = (uint64_t)(in[10] - base); + w5 |= (uint64_t)(in[11] - base) << 32; + w6 = (uint64_t)(in[12] - base); + w6 |= (uint64_t)(in[13] - base) << 32; + w7 = (uint64_t)(in[14] - base); + w7 |= (uint64_t)(in[15] - base) << 32; + w8 = (uint64_t)(in[16] - base); + w8 |= (uint64_t)(in[17] - base) << 32; + w9 = (uint64_t)(in[18] - base); + w9 |= (uint64_t)(in[19] - base) << 32; + w10 = (uint64_t)(in[20] - base); + w10 |= (uint64_t)(in[21] - base) << 32; + w11 = (uint64_t)(in[22] - base); + w11 |= (uint64_t)(in[23] - base) << 32; + w12 = (uint64_t)(in[24] - base); + w12 |= (uint64_t)(in[25] - base) << 32; + w13 = (uint64_t)(in[26] - base); + w13 |= (uint64_t)(in[27] - base) << 32; + w14 = (uint64_t)(in[28] - base); + w14 |= (uint64_t)(in[29] - base) << 32; + w15 = (uint64_t)(in[30] - base); + w15 |= (uint64_t)(in[31] - base) << 32; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + *pin += 32; /* we consumed 32 32-bit integers */ + *pw += 128; /* we used up 128 output bytes */ +} + +static void unpackforblock0(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + (void)pw; + for (int k = 0; k < 32; k += 1) { + (*pout)[k] = base; + } + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 1-bit values, touching 1 64-bit words, using 4 bytes */ +static void unpackforblock1(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(1); + /* we are going to access 1 64-bit word */ + uint64_t w0 = pw64[0]; + *pw += 4; /* we used up 4 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 1) & mask); + out[2] = base + (uint32_t)((w0 >> 2) & mask); + out[3] = base + (uint32_t)((w0 >> 3) & mask); + out[4] = base + (uint32_t)((w0 >> 4) & mask); + out[5] = base + (uint32_t)((w0 >> 5) & mask); + out[6] = base + (uint32_t)((w0 >> 6) & mask); + out[7] = base + (uint32_t)((w0 >> 7) & mask); + out[8] = base + (uint32_t)((w0 >> 8) & mask); + out[9] = base + (uint32_t)((w0 >> 9) & mask); + out[10] = base + (uint32_t)((w0 >> 10) & mask); + out[11] = base + (uint32_t)((w0 >> 11) & mask); + out[12] = base + (uint32_t)((w0 >> 12) & mask); + out[13] = base + (uint32_t)((w0 >> 13) & mask); + out[14] = base + (uint32_t)((w0 >> 14) & mask); + out[15] = base + (uint32_t)((w0 >> 15) & mask); + out[16] = base + (uint32_t)((w0 >> 16) & mask); + out[17] = base + (uint32_t)((w0 >> 17) & mask); + out[18] = base + (uint32_t)((w0 >> 18) & mask); + out[19] = base + (uint32_t)((w0 >> 19) & mask); + out[20] = base + (uint32_t)((w0 >> 20) & mask); + out[21] = base + (uint32_t)((w0 >> 21) & mask); + out[22] = base + (uint32_t)((w0 >> 22) & mask); + out[23] = base + (uint32_t)((w0 >> 23) & mask); + out[24] = base + (uint32_t)((w0 >> 24) & mask); + out[25] = base + (uint32_t)((w0 >> 25) & mask); + out[26] = base + (uint32_t)((w0 >> 26) & mask); + out[27] = base + (uint32_t)((w0 >> 27) & mask); + out[28] = base + (uint32_t)((w0 >> 28) & mask); + out[29] = base + (uint32_t)((w0 >> 29) & mask); + out[30] = base + (uint32_t)((w0 >> 30) & mask); + out[31] = base + (uint32_t)((w0 >> 31) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 2-bit values, touching 1 64-bit words, using 8 bytes */ +static void unpackforblock2(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(3); + /* we are going to access 1 64-bit word */ + uint64_t w0 = pw64[0]; + *pw += 8; /* we used up 8 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 2) & mask); + out[2] = base + (uint32_t)((w0 >> 4) & mask); + out[3] = base + (uint32_t)((w0 >> 6) & mask); + out[4] = base + (uint32_t)((w0 >> 8) & mask); + out[5] = base + (uint32_t)((w0 >> 10) & mask); + out[6] = base + (uint32_t)((w0 >> 12) & mask); + out[7] = base + (uint32_t)((w0 >> 14) & mask); + out[8] = base + (uint32_t)((w0 >> 16) & mask); + out[9] = base + (uint32_t)((w0 >> 18) & mask); + out[10] = base + (uint32_t)((w0 >> 20) & mask); + out[11] = base + (uint32_t)((w0 >> 22) & mask); + out[12] = base + (uint32_t)((w0 >> 24) & mask); + out[13] = base + (uint32_t)((w0 >> 26) & mask); + out[14] = base + (uint32_t)((w0 >> 28) & mask); + out[15] = base + (uint32_t)((w0 >> 30) & mask); + out[16] = base + (uint32_t)((w0 >> 32) & mask); + out[17] = base + (uint32_t)((w0 >> 34) & mask); + out[18] = base + (uint32_t)((w0 >> 36) & mask); + out[19] = base + (uint32_t)((w0 >> 38) & mask); + out[20] = base + (uint32_t)((w0 >> 40) & mask); + out[21] = base + (uint32_t)((w0 >> 42) & mask); + out[22] = base + (uint32_t)((w0 >> 44) & mask); + out[23] = base + (uint32_t)((w0 >> 46) & mask); + out[24] = base + (uint32_t)((w0 >> 48) & mask); + out[25] = base + (uint32_t)((w0 >> 50) & mask); + out[26] = base + (uint32_t)((w0 >> 52) & mask); + out[27] = base + (uint32_t)((w0 >> 54) & mask); + out[28] = base + (uint32_t)((w0 >> 56) & mask); + out[29] = base + (uint32_t)((w0 >> 58) & mask); + out[30] = base + (uint32_t)((w0 >> 60) & mask); + out[31] = base + (uint32_t)(w0 >> 62); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 3-bit values, touching 2 64-bit words, using 12 bytes */ +static void unpackforblock3(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(7); + /* we are going to access 2 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + *pw += 12; /* we used up 12 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 3) & mask); + out[2] = base + (uint32_t)((w0 >> 6) & mask); + out[3] = base + (uint32_t)((w0 >> 9) & mask); + out[4] = base + (uint32_t)((w0 >> 12) & mask); + out[5] = base + (uint32_t)((w0 >> 15) & mask); + out[6] = base + (uint32_t)((w0 >> 18) & mask); + out[7] = base + (uint32_t)((w0 >> 21) & mask); + out[8] = base + (uint32_t)((w0 >> 24) & mask); + out[9] = base + (uint32_t)((w0 >> 27) & mask); + out[10] = base + (uint32_t)((w0 >> 30) & mask); + out[11] = base + (uint32_t)((w0 >> 33) & mask); + out[12] = base + (uint32_t)((w0 >> 36) & mask); + out[13] = base + (uint32_t)((w0 >> 39) & mask); + out[14] = base + (uint32_t)((w0 >> 42) & mask); + out[15] = base + (uint32_t)((w0 >> 45) & mask); + out[16] = base + (uint32_t)((w0 >> 48) & mask); + out[17] = base + (uint32_t)((w0 >> 51) & mask); + out[18] = base + (uint32_t)((w0 >> 54) & mask); + out[19] = base + (uint32_t)((w0 >> 57) & mask); + out[20] = base + (uint32_t)((w0 >> 60) & mask); + out[21] = base + (uint32_t)(((w0 >> 63) | (w1 << 1)) & mask); + out[22] = base + (uint32_t)((w1 >> 2) & mask); + out[23] = base + (uint32_t)((w1 >> 5) & mask); + out[24] = base + (uint32_t)((w1 >> 8) & mask); + out[25] = base + (uint32_t)((w1 >> 11) & mask); + out[26] = base + (uint32_t)((w1 >> 14) & mask); + out[27] = base + (uint32_t)((w1 >> 17) & mask); + out[28] = base + (uint32_t)((w1 >> 20) & mask); + out[29] = base + (uint32_t)((w1 >> 23) & mask); + out[30] = base + (uint32_t)((w1 >> 26) & mask); + out[31] = base + (uint32_t)((w1 >> 29) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 4-bit values, touching 2 64-bit words, using 16 bytes */ +static void unpackforblock4(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(15); + /* we are going to access 2 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + *pw += 16; /* we used up 16 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 4) & mask); + out[2] = base + (uint32_t)((w0 >> 8) & mask); + out[3] = base + (uint32_t)((w0 >> 12) & mask); + out[4] = base + (uint32_t)((w0 >> 16) & mask); + out[5] = base + (uint32_t)((w0 >> 20) & mask); + out[6] = base + (uint32_t)((w0 >> 24) & mask); + out[7] = base + (uint32_t)((w0 >> 28) & mask); + out[8] = base + (uint32_t)((w0 >> 32) & mask); + out[9] = base + (uint32_t)((w0 >> 36) & mask); + out[10] = base + (uint32_t)((w0 >> 40) & mask); + out[11] = base + (uint32_t)((w0 >> 44) & mask); + out[12] = base + (uint32_t)((w0 >> 48) & mask); + out[13] = base + (uint32_t)((w0 >> 52) & mask); + out[14] = base + (uint32_t)((w0 >> 56) & mask); + out[15] = base + (uint32_t)(w0 >> 60); + out[16] = base + (uint32_t)((w1)&mask); + out[17] = base + (uint32_t)((w1 >> 4) & mask); + out[18] = base + (uint32_t)((w1 >> 8) & mask); + out[19] = base + (uint32_t)((w1 >> 12) & mask); + out[20] = base + (uint32_t)((w1 >> 16) & mask); + out[21] = base + (uint32_t)((w1 >> 20) & mask); + out[22] = base + (uint32_t)((w1 >> 24) & mask); + out[23] = base + (uint32_t)((w1 >> 28) & mask); + out[24] = base + (uint32_t)((w1 >> 32) & mask); + out[25] = base + (uint32_t)((w1 >> 36) & mask); + out[26] = base + (uint32_t)((w1 >> 40) & mask); + out[27] = base + (uint32_t)((w1 >> 44) & mask); + out[28] = base + (uint32_t)((w1 >> 48) & mask); + out[29] = base + (uint32_t)((w1 >> 52) & mask); + out[30] = base + (uint32_t)((w1 >> 56) & mask); + out[31] = base + (uint32_t)(w1 >> 60); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 5-bit values, touching 3 64-bit words, using 20 bytes */ +static void unpackforblock5(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(31); + /* we are going to access 3 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + *pw += 20; /* we used up 20 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 5) & mask); + out[2] = base + (uint32_t)((w0 >> 10) & mask); + out[3] = base + (uint32_t)((w0 >> 15) & mask); + out[4] = base + (uint32_t)((w0 >> 20) & mask); + out[5] = base + (uint32_t)((w0 >> 25) & mask); + out[6] = base + (uint32_t)((w0 >> 30) & mask); + out[7] = base + (uint32_t)((w0 >> 35) & mask); + out[8] = base + (uint32_t)((w0 >> 40) & mask); + out[9] = base + (uint32_t)((w0 >> 45) & mask); + out[10] = base + (uint32_t)((w0 >> 50) & mask); + out[11] = base + (uint32_t)((w0 >> 55) & mask); + out[12] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[13] = base + (uint32_t)((w1 >> 1) & mask); + out[14] = base + (uint32_t)((w1 >> 6) & mask); + out[15] = base + (uint32_t)((w1 >> 11) & mask); + out[16] = base + (uint32_t)((w1 >> 16) & mask); + out[17] = base + (uint32_t)((w1 >> 21) & mask); + out[18] = base + (uint32_t)((w1 >> 26) & mask); + out[19] = base + (uint32_t)((w1 >> 31) & mask); + out[20] = base + (uint32_t)((w1 >> 36) & mask); + out[21] = base + (uint32_t)((w1 >> 41) & mask); + out[22] = base + (uint32_t)((w1 >> 46) & mask); + out[23] = base + (uint32_t)((w1 >> 51) & mask); + out[24] = base + (uint32_t)((w1 >> 56) & mask); + out[25] = base + (uint32_t)(((w1 >> 61) | (w2 << 3)) & mask); + out[26] = base + (uint32_t)((w2 >> 2) & mask); + out[27] = base + (uint32_t)((w2 >> 7) & mask); + out[28] = base + (uint32_t)((w2 >> 12) & mask); + out[29] = base + (uint32_t)((w2 >> 17) & mask); + out[30] = base + (uint32_t)((w2 >> 22) & mask); + out[31] = base + (uint32_t)((w2 >> 27) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 6-bit values, touching 3 64-bit words, using 24 bytes */ +static void unpackforblock6(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(63); + /* we are going to access 3 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + *pw += 24; /* we used up 24 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 6) & mask); + out[2] = base + (uint32_t)((w0 >> 12) & mask); + out[3] = base + (uint32_t)((w0 >> 18) & mask); + out[4] = base + (uint32_t)((w0 >> 24) & mask); + out[5] = base + (uint32_t)((w0 >> 30) & mask); + out[6] = base + (uint32_t)((w0 >> 36) & mask); + out[7] = base + (uint32_t)((w0 >> 42) & mask); + out[8] = base + (uint32_t)((w0 >> 48) & mask); + out[9] = base + (uint32_t)((w0 >> 54) & mask); + out[10] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[11] = base + (uint32_t)((w1 >> 2) & mask); + out[12] = base + (uint32_t)((w1 >> 8) & mask); + out[13] = base + (uint32_t)((w1 >> 14) & mask); + out[14] = base + (uint32_t)((w1 >> 20) & mask); + out[15] = base + (uint32_t)((w1 >> 26) & mask); + out[16] = base + (uint32_t)((w1 >> 32) & mask); + out[17] = base + (uint32_t)((w1 >> 38) & mask); + out[18] = base + (uint32_t)((w1 >> 44) & mask); + out[19] = base + (uint32_t)((w1 >> 50) & mask); + out[20] = base + (uint32_t)((w1 >> 56) & mask); + out[21] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[22] = base + (uint32_t)((w2 >> 4) & mask); + out[23] = base + (uint32_t)((w2 >> 10) & mask); + out[24] = base + (uint32_t)((w2 >> 16) & mask); + out[25] = base + (uint32_t)((w2 >> 22) & mask); + out[26] = base + (uint32_t)((w2 >> 28) & mask); + out[27] = base + (uint32_t)((w2 >> 34) & mask); + out[28] = base + (uint32_t)((w2 >> 40) & mask); + out[29] = base + (uint32_t)((w2 >> 46) & mask); + out[30] = base + (uint32_t)((w2 >> 52) & mask); + out[31] = base + (uint32_t)(w2 >> 58); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 7-bit values, touching 4 64-bit words, using 28 bytes */ +static void unpackforblock7(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(127); + /* we are going to access 4 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + *pw += 28; /* we used up 28 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 7) & mask); + out[2] = base + (uint32_t)((w0 >> 14) & mask); + out[3] = base + (uint32_t)((w0 >> 21) & mask); + out[4] = base + (uint32_t)((w0 >> 28) & mask); + out[5] = base + (uint32_t)((w0 >> 35) & mask); + out[6] = base + (uint32_t)((w0 >> 42) & mask); + out[7] = base + (uint32_t)((w0 >> 49) & mask); + out[8] = base + (uint32_t)((w0 >> 56) & mask); + out[9] = base + (uint32_t)(((w0 >> 63) | (w1 << 1)) & mask); + out[10] = base + (uint32_t)((w1 >> 6) & mask); + out[11] = base + (uint32_t)((w1 >> 13) & mask); + out[12] = base + (uint32_t)((w1 >> 20) & mask); + out[13] = base + (uint32_t)((w1 >> 27) & mask); + out[14] = base + (uint32_t)((w1 >> 34) & mask); + out[15] = base + (uint32_t)((w1 >> 41) & mask); + out[16] = base + (uint32_t)((w1 >> 48) & mask); + out[17] = base + (uint32_t)((w1 >> 55) & mask); + out[18] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[19] = base + (uint32_t)((w2 >> 5) & mask); + out[20] = base + (uint32_t)((w2 >> 12) & mask); + out[21] = base + (uint32_t)((w2 >> 19) & mask); + out[22] = base + (uint32_t)((w2 >> 26) & mask); + out[23] = base + (uint32_t)((w2 >> 33) & mask); + out[24] = base + (uint32_t)((w2 >> 40) & mask); + out[25] = base + (uint32_t)((w2 >> 47) & mask); + out[26] = base + (uint32_t)((w2 >> 54) & mask); + out[27] = base + (uint32_t)(((w2 >> 61) | (w3 << 3)) & mask); + out[28] = base + (uint32_t)((w3 >> 4) & mask); + out[29] = base + (uint32_t)((w3 >> 11) & mask); + out[30] = base + (uint32_t)((w3 >> 18) & mask); + out[31] = base + (uint32_t)((w3 >> 25) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 8-bit values, touching 4 64-bit words, using 32 bytes */ +static void unpackforblock8(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(255); + /* we are going to access 4 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + *pw += 32; /* we used up 32 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 8) & mask); + out[2] = base + (uint32_t)((w0 >> 16) & mask); + out[3] = base + (uint32_t)((w0 >> 24) & mask); + out[4] = base + (uint32_t)((w0 >> 32) & mask); + out[5] = base + (uint32_t)((w0 >> 40) & mask); + out[6] = base + (uint32_t)((w0 >> 48) & mask); + out[7] = base + (uint32_t)(w0 >> 56); + out[8] = base + (uint32_t)((w1)&mask); + out[9] = base + (uint32_t)((w1 >> 8) & mask); + out[10] = base + (uint32_t)((w1 >> 16) & mask); + out[11] = base + (uint32_t)((w1 >> 24) & mask); + out[12] = base + (uint32_t)((w1 >> 32) & mask); + out[13] = base + (uint32_t)((w1 >> 40) & mask); + out[14] = base + (uint32_t)((w1 >> 48) & mask); + out[15] = base + (uint32_t)(w1 >> 56); + out[16] = base + (uint32_t)((w2)&mask); + out[17] = base + (uint32_t)((w2 >> 8) & mask); + out[18] = base + (uint32_t)((w2 >> 16) & mask); + out[19] = base + (uint32_t)((w2 >> 24) & mask); + out[20] = base + (uint32_t)((w2 >> 32) & mask); + out[21] = base + (uint32_t)((w2 >> 40) & mask); + out[22] = base + (uint32_t)((w2 >> 48) & mask); + out[23] = base + (uint32_t)(w2 >> 56); + out[24] = base + (uint32_t)((w3)&mask); + out[25] = base + (uint32_t)((w3 >> 8) & mask); + out[26] = base + (uint32_t)((w3 >> 16) & mask); + out[27] = base + (uint32_t)((w3 >> 24) & mask); + out[28] = base + (uint32_t)((w3 >> 32) & mask); + out[29] = base + (uint32_t)((w3 >> 40) & mask); + out[30] = base + (uint32_t)((w3 >> 48) & mask); + out[31] = base + (uint32_t)(w3 >> 56); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 9-bit values, touching 5 64-bit words, using 36 bytes */ +static void unpackforblock9(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(511); + /* we are going to access 5 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + *pw += 36; /* we used up 36 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 9) & mask); + out[2] = base + (uint32_t)((w0 >> 18) & mask); + out[3] = base + (uint32_t)((w0 >> 27) & mask); + out[4] = base + (uint32_t)((w0 >> 36) & mask); + out[5] = base + (uint32_t)((w0 >> 45) & mask); + out[6] = base + (uint32_t)((w0 >> 54) & mask); + out[7] = base + (uint32_t)(((w0 >> 63) | (w1 << 1)) & mask); + out[8] = base + (uint32_t)((w1 >> 8) & mask); + out[9] = base + (uint32_t)((w1 >> 17) & mask); + out[10] = base + (uint32_t)((w1 >> 26) & mask); + out[11] = base + (uint32_t)((w1 >> 35) & mask); + out[12] = base + (uint32_t)((w1 >> 44) & mask); + out[13] = base + (uint32_t)((w1 >> 53) & mask); + out[14] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[15] = base + (uint32_t)((w2 >> 7) & mask); + out[16] = base + (uint32_t)((w2 >> 16) & mask); + out[17] = base + (uint32_t)((w2 >> 25) & mask); + out[18] = base + (uint32_t)((w2 >> 34) & mask); + out[19] = base + (uint32_t)((w2 >> 43) & mask); + out[20] = base + (uint32_t)((w2 >> 52) & mask); + out[21] = base + (uint32_t)(((w2 >> 61) | (w3 << 3)) & mask); + out[22] = base + (uint32_t)((w3 >> 6) & mask); + out[23] = base + (uint32_t)((w3 >> 15) & mask); + out[24] = base + (uint32_t)((w3 >> 24) & mask); + out[25] = base + (uint32_t)((w3 >> 33) & mask); + out[26] = base + (uint32_t)((w3 >> 42) & mask); + out[27] = base + (uint32_t)((w3 >> 51) & mask); + out[28] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[29] = base + (uint32_t)((w4 >> 5) & mask); + out[30] = base + (uint32_t)((w4 >> 14) & mask); + out[31] = base + (uint32_t)((w4 >> 23) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 10-bit values, touching 5 64-bit words, using 40 bytes */ +static void unpackforblock10(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(1023); + /* we are going to access 5 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + *pw += 40; /* we used up 40 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 10) & mask); + out[2] = base + (uint32_t)((w0 >> 20) & mask); + out[3] = base + (uint32_t)((w0 >> 30) & mask); + out[4] = base + (uint32_t)((w0 >> 40) & mask); + out[5] = base + (uint32_t)((w0 >> 50) & mask); + out[6] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[7] = base + (uint32_t)((w1 >> 6) & mask); + out[8] = base + (uint32_t)((w1 >> 16) & mask); + out[9] = base + (uint32_t)((w1 >> 26) & mask); + out[10] = base + (uint32_t)((w1 >> 36) & mask); + out[11] = base + (uint32_t)((w1 >> 46) & mask); + out[12] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[13] = base + (uint32_t)((w2 >> 2) & mask); + out[14] = base + (uint32_t)((w2 >> 12) & mask); + out[15] = base + (uint32_t)((w2 >> 22) & mask); + out[16] = base + (uint32_t)((w2 >> 32) & mask); + out[17] = base + (uint32_t)((w2 >> 42) & mask); + out[18] = base + (uint32_t)((w2 >> 52) & mask); + out[19] = base + (uint32_t)(((w2 >> 62) | (w3 << 2)) & mask); + out[20] = base + (uint32_t)((w3 >> 8) & mask); + out[21] = base + (uint32_t)((w3 >> 18) & mask); + out[22] = base + (uint32_t)((w3 >> 28) & mask); + out[23] = base + (uint32_t)((w3 >> 38) & mask); + out[24] = base + (uint32_t)((w3 >> 48) & mask); + out[25] = base + (uint32_t)(((w3 >> 58) | (w4 << 6)) & mask); + out[26] = base + (uint32_t)((w4 >> 4) & mask); + out[27] = base + (uint32_t)((w4 >> 14) & mask); + out[28] = base + (uint32_t)((w4 >> 24) & mask); + out[29] = base + (uint32_t)((w4 >> 34) & mask); + out[30] = base + (uint32_t)((w4 >> 44) & mask); + out[31] = base + (uint32_t)(w4 >> 54); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 11-bit values, touching 6 64-bit words, using 44 bytes */ +static void unpackforblock11(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(2047); + /* we are going to access 6 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + *pw += 44; /* we used up 44 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 11) & mask); + out[2] = base + (uint32_t)((w0 >> 22) & mask); + out[3] = base + (uint32_t)((w0 >> 33) & mask); + out[4] = base + (uint32_t)((w0 >> 44) & mask); + out[5] = base + (uint32_t)(((w0 >> 55) | (w1 << 9)) & mask); + out[6] = base + (uint32_t)((w1 >> 2) & mask); + out[7] = base + (uint32_t)((w1 >> 13) & mask); + out[8] = base + (uint32_t)((w1 >> 24) & mask); + out[9] = base + (uint32_t)((w1 >> 35) & mask); + out[10] = base + (uint32_t)((w1 >> 46) & mask); + out[11] = base + (uint32_t)(((w1 >> 57) | (w2 << 7)) & mask); + out[12] = base + (uint32_t)((w2 >> 4) & mask); + out[13] = base + (uint32_t)((w2 >> 15) & mask); + out[14] = base + (uint32_t)((w2 >> 26) & mask); + out[15] = base + (uint32_t)((w2 >> 37) & mask); + out[16] = base + (uint32_t)((w2 >> 48) & mask); + out[17] = base + (uint32_t)(((w2 >> 59) | (w3 << 5)) & mask); + out[18] = base + (uint32_t)((w3 >> 6) & mask); + out[19] = base + (uint32_t)((w3 >> 17) & mask); + out[20] = base + (uint32_t)((w3 >> 28) & mask); + out[21] = base + (uint32_t)((w3 >> 39) & mask); + out[22] = base + (uint32_t)((w3 >> 50) & mask); + out[23] = base + (uint32_t)(((w3 >> 61) | (w4 << 3)) & mask); + out[24] = base + (uint32_t)((w4 >> 8) & mask); + out[25] = base + (uint32_t)((w4 >> 19) & mask); + out[26] = base + (uint32_t)((w4 >> 30) & mask); + out[27] = base + (uint32_t)((w4 >> 41) & mask); + out[28] = base + (uint32_t)((w4 >> 52) & mask); + out[29] = base + (uint32_t)(((w4 >> 63) | (w5 << 1)) & mask); + out[30] = base + (uint32_t)((w5 >> 10) & mask); + out[31] = base + (uint32_t)((w5 >> 21) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 12-bit values, touching 6 64-bit words, using 48 bytes */ +static void unpackforblock12(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(4095); + /* we are going to access 6 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + *pw += 48; /* we used up 48 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 12) & mask); + out[2] = base + (uint32_t)((w0 >> 24) & mask); + out[3] = base + (uint32_t)((w0 >> 36) & mask); + out[4] = base + (uint32_t)((w0 >> 48) & mask); + out[5] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[6] = base + (uint32_t)((w1 >> 8) & mask); + out[7] = base + (uint32_t)((w1 >> 20) & mask); + out[8] = base + (uint32_t)((w1 >> 32) & mask); + out[9] = base + (uint32_t)((w1 >> 44) & mask); + out[10] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[11] = base + (uint32_t)((w2 >> 4) & mask); + out[12] = base + (uint32_t)((w2 >> 16) & mask); + out[13] = base + (uint32_t)((w2 >> 28) & mask); + out[14] = base + (uint32_t)((w2 >> 40) & mask); + out[15] = base + (uint32_t)(w2 >> 52); + out[16] = base + (uint32_t)((w3)&mask); + out[17] = base + (uint32_t)((w3 >> 12) & mask); + out[18] = base + (uint32_t)((w3 >> 24) & mask); + out[19] = base + (uint32_t)((w3 >> 36) & mask); + out[20] = base + (uint32_t)((w3 >> 48) & mask); + out[21] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[22] = base + (uint32_t)((w4 >> 8) & mask); + out[23] = base + (uint32_t)((w4 >> 20) & mask); + out[24] = base + (uint32_t)((w4 >> 32) & mask); + out[25] = base + (uint32_t)((w4 >> 44) & mask); + out[26] = base + (uint32_t)(((w4 >> 56) | (w5 << 8)) & mask); + out[27] = base + (uint32_t)((w5 >> 4) & mask); + out[28] = base + (uint32_t)((w5 >> 16) & mask); + out[29] = base + (uint32_t)((w5 >> 28) & mask); + out[30] = base + (uint32_t)((w5 >> 40) & mask); + out[31] = base + (uint32_t)(w5 >> 52); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 13-bit values, touching 7 64-bit words, using 52 bytes */ +static void unpackforblock13(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(8191); + /* we are going to access 7 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + *pw += 52; /* we used up 52 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 13) & mask); + out[2] = base + (uint32_t)((w0 >> 26) & mask); + out[3] = base + (uint32_t)((w0 >> 39) & mask); + out[4] = base + (uint32_t)(((w0 >> 52) | (w1 << 12)) & mask); + out[5] = base + (uint32_t)((w1 >> 1) & mask); + out[6] = base + (uint32_t)((w1 >> 14) & mask); + out[7] = base + (uint32_t)((w1 >> 27) & mask); + out[8] = base + (uint32_t)((w1 >> 40) & mask); + out[9] = base + (uint32_t)(((w1 >> 53) | (w2 << 11)) & mask); + out[10] = base + (uint32_t)((w2 >> 2) & mask); + out[11] = base + (uint32_t)((w2 >> 15) & mask); + out[12] = base + (uint32_t)((w2 >> 28) & mask); + out[13] = base + (uint32_t)((w2 >> 41) & mask); + out[14] = base + (uint32_t)(((w2 >> 54) | (w3 << 10)) & mask); + out[15] = base + (uint32_t)((w3 >> 3) & mask); + out[16] = base + (uint32_t)((w3 >> 16) & mask); + out[17] = base + (uint32_t)((w3 >> 29) & mask); + out[18] = base + (uint32_t)((w3 >> 42) & mask); + out[19] = base + (uint32_t)(((w3 >> 55) | (w4 << 9)) & mask); + out[20] = base + (uint32_t)((w4 >> 4) & mask); + out[21] = base + (uint32_t)((w4 >> 17) & mask); + out[22] = base + (uint32_t)((w4 >> 30) & mask); + out[23] = base + (uint32_t)((w4 >> 43) & mask); + out[24] = base + (uint32_t)(((w4 >> 56) | (w5 << 8)) & mask); + out[25] = base + (uint32_t)((w5 >> 5) & mask); + out[26] = base + (uint32_t)((w5 >> 18) & mask); + out[27] = base + (uint32_t)((w5 >> 31) & mask); + out[28] = base + (uint32_t)((w5 >> 44) & mask); + out[29] = base + (uint32_t)(((w5 >> 57) | (w6 << 7)) & mask); + out[30] = base + (uint32_t)((w6 >> 6) & mask); + out[31] = base + (uint32_t)((w6 >> 19) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 14-bit values, touching 7 64-bit words, using 56 bytes */ +static void unpackforblock14(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(16383); + /* we are going to access 7 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + *pw += 56; /* we used up 56 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 14) & mask); + out[2] = base + (uint32_t)((w0 >> 28) & mask); + out[3] = base + (uint32_t)((w0 >> 42) & mask); + out[4] = base + (uint32_t)(((w0 >> 56) | (w1 << 8)) & mask); + out[5] = base + (uint32_t)((w1 >> 6) & mask); + out[6] = base + (uint32_t)((w1 >> 20) & mask); + out[7] = base + (uint32_t)((w1 >> 34) & mask); + out[8] = base + (uint32_t)((w1 >> 48) & mask); + out[9] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[10] = base + (uint32_t)((w2 >> 12) & mask); + out[11] = base + (uint32_t)((w2 >> 26) & mask); + out[12] = base + (uint32_t)((w2 >> 40) & mask); + out[13] = base + (uint32_t)(((w2 >> 54) | (w3 << 10)) & mask); + out[14] = base + (uint32_t)((w3 >> 4) & mask); + out[15] = base + (uint32_t)((w3 >> 18) & mask); + out[16] = base + (uint32_t)((w3 >> 32) & mask); + out[17] = base + (uint32_t)((w3 >> 46) & mask); + out[18] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[19] = base + (uint32_t)((w4 >> 10) & mask); + out[20] = base + (uint32_t)((w4 >> 24) & mask); + out[21] = base + (uint32_t)((w4 >> 38) & mask); + out[22] = base + (uint32_t)(((w4 >> 52) | (w5 << 12)) & mask); + out[23] = base + (uint32_t)((w5 >> 2) & mask); + out[24] = base + (uint32_t)((w5 >> 16) & mask); + out[25] = base + (uint32_t)((w5 >> 30) & mask); + out[26] = base + (uint32_t)((w5 >> 44) & mask); + out[27] = base + (uint32_t)(((w5 >> 58) | (w6 << 6)) & mask); + out[28] = base + (uint32_t)((w6 >> 8) & mask); + out[29] = base + (uint32_t)((w6 >> 22) & mask); + out[30] = base + (uint32_t)((w6 >> 36) & mask); + out[31] = base + (uint32_t)(w6 >> 50); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 15-bit values, touching 8 64-bit words, using 60 bytes */ +static void unpackforblock15(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(32767); + /* we are going to access 8 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + *pw += 60; /* we used up 60 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 15) & mask); + out[2] = base + (uint32_t)((w0 >> 30) & mask); + out[3] = base + (uint32_t)((w0 >> 45) & mask); + out[4] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[5] = base + (uint32_t)((w1 >> 11) & mask); + out[6] = base + (uint32_t)((w1 >> 26) & mask); + out[7] = base + (uint32_t)((w1 >> 41) & mask); + out[8] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[9] = base + (uint32_t)((w2 >> 7) & mask); + out[10] = base + (uint32_t)((w2 >> 22) & mask); + out[11] = base + (uint32_t)((w2 >> 37) & mask); + out[12] = base + (uint32_t)(((w2 >> 52) | (w3 << 12)) & mask); + out[13] = base + (uint32_t)((w3 >> 3) & mask); + out[14] = base + (uint32_t)((w3 >> 18) & mask); + out[15] = base + (uint32_t)((w3 >> 33) & mask); + out[16] = base + (uint32_t)((w3 >> 48) & mask); + out[17] = base + (uint32_t)(((w3 >> 63) | (w4 << 1)) & mask); + out[18] = base + (uint32_t)((w4 >> 14) & mask); + out[19] = base + (uint32_t)((w4 >> 29) & mask); + out[20] = base + (uint32_t)((w4 >> 44) & mask); + out[21] = base + (uint32_t)(((w4 >> 59) | (w5 << 5)) & mask); + out[22] = base + (uint32_t)((w5 >> 10) & mask); + out[23] = base + (uint32_t)((w5 >> 25) & mask); + out[24] = base + (uint32_t)((w5 >> 40) & mask); + out[25] = base + (uint32_t)(((w5 >> 55) | (w6 << 9)) & mask); + out[26] = base + (uint32_t)((w6 >> 6) & mask); + out[27] = base + (uint32_t)((w6 >> 21) & mask); + out[28] = base + (uint32_t)((w6 >> 36) & mask); + out[29] = base + (uint32_t)(((w6 >> 51) | (w7 << 13)) & mask); + out[30] = base + (uint32_t)((w7 >> 2) & mask); + out[31] = base + (uint32_t)((w7 >> 17) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 16-bit values, touching 8 64-bit words, using 64 bytes */ +static void unpackforblock16(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(65535); + /* we are going to access 8 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + *pw += 64; /* we used up 64 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 16) & mask); + out[2] = base + (uint32_t)((w0 >> 32) & mask); + out[3] = base + (uint32_t)(w0 >> 48); + out[4] = base + (uint32_t)((w1)&mask); + out[5] = base + (uint32_t)((w1 >> 16) & mask); + out[6] = base + (uint32_t)((w1 >> 32) & mask); + out[7] = base + (uint32_t)(w1 >> 48); + out[8] = base + (uint32_t)((w2)&mask); + out[9] = base + (uint32_t)((w2 >> 16) & mask); + out[10] = base + (uint32_t)((w2 >> 32) & mask); + out[11] = base + (uint32_t)(w2 >> 48); + out[12] = base + (uint32_t)((w3)&mask); + out[13] = base + (uint32_t)((w3 >> 16) & mask); + out[14] = base + (uint32_t)((w3 >> 32) & mask); + out[15] = base + (uint32_t)(w3 >> 48); + out[16] = base + (uint32_t)((w4)&mask); + out[17] = base + (uint32_t)((w4 >> 16) & mask); + out[18] = base + (uint32_t)((w4 >> 32) & mask); + out[19] = base + (uint32_t)(w4 >> 48); + out[20] = base + (uint32_t)((w5)&mask); + out[21] = base + (uint32_t)((w5 >> 16) & mask); + out[22] = base + (uint32_t)((w5 >> 32) & mask); + out[23] = base + (uint32_t)(w5 >> 48); + out[24] = base + (uint32_t)((w6)&mask); + out[25] = base + (uint32_t)((w6 >> 16) & mask); + out[26] = base + (uint32_t)((w6 >> 32) & mask); + out[27] = base + (uint32_t)(w6 >> 48); + out[28] = base + (uint32_t)((w7)&mask); + out[29] = base + (uint32_t)((w7 >> 16) & mask); + out[30] = base + (uint32_t)((w7 >> 32) & mask); + out[31] = base + (uint32_t)(w7 >> 48); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 17-bit values, touching 9 64-bit words, using 68 bytes */ +static void unpackforblock17(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(131071); + /* we are going to access 9 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + *pw += 68; /* we used up 68 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 17) & mask); + out[2] = base + (uint32_t)((w0 >> 34) & mask); + out[3] = base + (uint32_t)(((w0 >> 51) | (w1 << 13)) & mask); + out[4] = base + (uint32_t)((w1 >> 4) & mask); + out[5] = base + (uint32_t)((w1 >> 21) & mask); + out[6] = base + (uint32_t)((w1 >> 38) & mask); + out[7] = base + (uint32_t)(((w1 >> 55) | (w2 << 9)) & mask); + out[8] = base + (uint32_t)((w2 >> 8) & mask); + out[9] = base + (uint32_t)((w2 >> 25) & mask); + out[10] = base + (uint32_t)((w2 >> 42) & mask); + out[11] = base + (uint32_t)(((w2 >> 59) | (w3 << 5)) & mask); + out[12] = base + (uint32_t)((w3 >> 12) & mask); + out[13] = base + (uint32_t)((w3 >> 29) & mask); + out[14] = base + (uint32_t)((w3 >> 46) & mask); + out[15] = base + (uint32_t)(((w3 >> 63) | (w4 << 1)) & mask); + out[16] = base + (uint32_t)((w4 >> 16) & mask); + out[17] = base + (uint32_t)((w4 >> 33) & mask); + out[18] = base + (uint32_t)(((w4 >> 50) | (w5 << 14)) & mask); + out[19] = base + (uint32_t)((w5 >> 3) & mask); + out[20] = base + (uint32_t)((w5 >> 20) & mask); + out[21] = base + (uint32_t)((w5 >> 37) & mask); + out[22] = base + (uint32_t)(((w5 >> 54) | (w6 << 10)) & mask); + out[23] = base + (uint32_t)((w6 >> 7) & mask); + out[24] = base + (uint32_t)((w6 >> 24) & mask); + out[25] = base + (uint32_t)((w6 >> 41) & mask); + out[26] = base + (uint32_t)(((w6 >> 58) | (w7 << 6)) & mask); + out[27] = base + (uint32_t)((w7 >> 11) & mask); + out[28] = base + (uint32_t)((w7 >> 28) & mask); + out[29] = base + (uint32_t)((w7 >> 45) & mask); + out[30] = base + (uint32_t)(((w7 >> 62) | (w8 << 2)) & mask); + out[31] = base + (uint32_t)((w8 >> 15) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 18-bit values, touching 9 64-bit words, using 72 bytes */ +static void unpackforblock18(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(262143); + /* we are going to access 9 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + *pw += 72; /* we used up 72 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 18) & mask); + out[2] = base + (uint32_t)((w0 >> 36) & mask); + out[3] = base + (uint32_t)(((w0 >> 54) | (w1 << 10)) & mask); + out[4] = base + (uint32_t)((w1 >> 8) & mask); + out[5] = base + (uint32_t)((w1 >> 26) & mask); + out[6] = base + (uint32_t)((w1 >> 44) & mask); + out[7] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[8] = base + (uint32_t)((w2 >> 16) & mask); + out[9] = base + (uint32_t)((w2 >> 34) & mask); + out[10] = base + (uint32_t)(((w2 >> 52) | (w3 << 12)) & mask); + out[11] = base + (uint32_t)((w3 >> 6) & mask); + out[12] = base + (uint32_t)((w3 >> 24) & mask); + out[13] = base + (uint32_t)((w3 >> 42) & mask); + out[14] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[15] = base + (uint32_t)((w4 >> 14) & mask); + out[16] = base + (uint32_t)((w4 >> 32) & mask); + out[17] = base + (uint32_t)(((w4 >> 50) | (w5 << 14)) & mask); + out[18] = base + (uint32_t)((w5 >> 4) & mask); + out[19] = base + (uint32_t)((w5 >> 22) & mask); + out[20] = base + (uint32_t)((w5 >> 40) & mask); + out[21] = base + (uint32_t)(((w5 >> 58) | (w6 << 6)) & mask); + out[22] = base + (uint32_t)((w6 >> 12) & mask); + out[23] = base + (uint32_t)((w6 >> 30) & mask); + out[24] = base + (uint32_t)(((w6 >> 48) | (w7 << 16)) & mask); + out[25] = base + (uint32_t)((w7 >> 2) & mask); + out[26] = base + (uint32_t)((w7 >> 20) & mask); + out[27] = base + (uint32_t)((w7 >> 38) & mask); + out[28] = base + (uint32_t)(((w7 >> 56) | (w8 << 8)) & mask); + out[29] = base + (uint32_t)((w8 >> 10) & mask); + out[30] = base + (uint32_t)((w8 >> 28) & mask); + out[31] = base + (uint32_t)(w8 >> 46); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 19-bit values, touching 10 64-bit words, using 76 bytes */ +static void unpackforblock19(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(524287); + /* we are going to access 10 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + *pw += 76; /* we used up 76 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 19) & mask); + out[2] = base + (uint32_t)((w0 >> 38) & mask); + out[3] = base + (uint32_t)(((w0 >> 57) | (w1 << 7)) & mask); + out[4] = base + (uint32_t)((w1 >> 12) & mask); + out[5] = base + (uint32_t)((w1 >> 31) & mask); + out[6] = base + (uint32_t)(((w1 >> 50) | (w2 << 14)) & mask); + out[7] = base + (uint32_t)((w2 >> 5) & mask); + out[8] = base + (uint32_t)((w2 >> 24) & mask); + out[9] = base + (uint32_t)((w2 >> 43) & mask); + out[10] = base + (uint32_t)(((w2 >> 62) | (w3 << 2)) & mask); + out[11] = base + (uint32_t)((w3 >> 17) & mask); + out[12] = base + (uint32_t)((w3 >> 36) & mask); + out[13] = base + (uint32_t)(((w3 >> 55) | (w4 << 9)) & mask); + out[14] = base + (uint32_t)((w4 >> 10) & mask); + out[15] = base + (uint32_t)((w4 >> 29) & mask); + out[16] = base + (uint32_t)(((w4 >> 48) | (w5 << 16)) & mask); + out[17] = base + (uint32_t)((w5 >> 3) & mask); + out[18] = base + (uint32_t)((w5 >> 22) & mask); + out[19] = base + (uint32_t)((w5 >> 41) & mask); + out[20] = base + (uint32_t)(((w5 >> 60) | (w6 << 4)) & mask); + out[21] = base + (uint32_t)((w6 >> 15) & mask); + out[22] = base + (uint32_t)((w6 >> 34) & mask); + out[23] = base + (uint32_t)(((w6 >> 53) | (w7 << 11)) & mask); + out[24] = base + (uint32_t)((w7 >> 8) & mask); + out[25] = base + (uint32_t)((w7 >> 27) & mask); + out[26] = base + (uint32_t)(((w7 >> 46) | (w8 << 18)) & mask); + out[27] = base + (uint32_t)((w8 >> 1) & mask); + out[28] = base + (uint32_t)((w8 >> 20) & mask); + out[29] = base + (uint32_t)((w8 >> 39) & mask); + out[30] = base + (uint32_t)(((w8 >> 58) | (w9 << 6)) & mask); + out[31] = base + (uint32_t)((w9 >> 13) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 20-bit values, touching 10 64-bit words, using 80 bytes */ +static void unpackforblock20(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(1048575); + /* we are going to access 10 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + *pw += 80; /* we used up 80 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 20) & mask); + out[2] = base + (uint32_t)((w0 >> 40) & mask); + out[3] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[4] = base + (uint32_t)((w1 >> 16) & mask); + out[5] = base + (uint32_t)((w1 >> 36) & mask); + out[6] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[7] = base + (uint32_t)((w2 >> 12) & mask); + out[8] = base + (uint32_t)((w2 >> 32) & mask); + out[9] = base + (uint32_t)(((w2 >> 52) | (w3 << 12)) & mask); + out[10] = base + (uint32_t)((w3 >> 8) & mask); + out[11] = base + (uint32_t)((w3 >> 28) & mask); + out[12] = base + (uint32_t)(((w3 >> 48) | (w4 << 16)) & mask); + out[13] = base + (uint32_t)((w4 >> 4) & mask); + out[14] = base + (uint32_t)((w4 >> 24) & mask); + out[15] = base + (uint32_t)(w4 >> 44); + out[16] = base + (uint32_t)((w5)&mask); + out[17] = base + (uint32_t)((w5 >> 20) & mask); + out[18] = base + (uint32_t)((w5 >> 40) & mask); + out[19] = base + (uint32_t)(((w5 >> 60) | (w6 << 4)) & mask); + out[20] = base + (uint32_t)((w6 >> 16) & mask); + out[21] = base + (uint32_t)((w6 >> 36) & mask); + out[22] = base + (uint32_t)(((w6 >> 56) | (w7 << 8)) & mask); + out[23] = base + (uint32_t)((w7 >> 12) & mask); + out[24] = base + (uint32_t)((w7 >> 32) & mask); + out[25] = base + (uint32_t)(((w7 >> 52) | (w8 << 12)) & mask); + out[26] = base + (uint32_t)((w8 >> 8) & mask); + out[27] = base + (uint32_t)((w8 >> 28) & mask); + out[28] = base + (uint32_t)(((w8 >> 48) | (w9 << 16)) & mask); + out[29] = base + (uint32_t)((w9 >> 4) & mask); + out[30] = base + (uint32_t)((w9 >> 24) & mask); + out[31] = base + (uint32_t)(w9 >> 44); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 21-bit values, touching 11 64-bit words, using 84 bytes */ +static void unpackforblock21(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(2097151); + /* we are going to access 11 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + *pw += 84; /* we used up 84 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 21) & mask); + out[2] = base + (uint32_t)((w0 >> 42) & mask); + out[3] = base + (uint32_t)(((w0 >> 63) | (w1 << 1)) & mask); + out[4] = base + (uint32_t)((w1 >> 20) & mask); + out[5] = base + (uint32_t)((w1 >> 41) & mask); + out[6] = base + (uint32_t)(((w1 >> 62) | (w2 << 2)) & mask); + out[7] = base + (uint32_t)((w2 >> 19) & mask); + out[8] = base + (uint32_t)((w2 >> 40) & mask); + out[9] = base + (uint32_t)(((w2 >> 61) | (w3 << 3)) & mask); + out[10] = base + (uint32_t)((w3 >> 18) & mask); + out[11] = base + (uint32_t)((w3 >> 39) & mask); + out[12] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[13] = base + (uint32_t)((w4 >> 17) & mask); + out[14] = base + (uint32_t)((w4 >> 38) & mask); + out[15] = base + (uint32_t)(((w4 >> 59) | (w5 << 5)) & mask); + out[16] = base + (uint32_t)((w5 >> 16) & mask); + out[17] = base + (uint32_t)((w5 >> 37) & mask); + out[18] = base + (uint32_t)(((w5 >> 58) | (w6 << 6)) & mask); + out[19] = base + (uint32_t)((w6 >> 15) & mask); + out[20] = base + (uint32_t)((w6 >> 36) & mask); + out[21] = base + (uint32_t)(((w6 >> 57) | (w7 << 7)) & mask); + out[22] = base + (uint32_t)((w7 >> 14) & mask); + out[23] = base + (uint32_t)((w7 >> 35) & mask); + out[24] = base + (uint32_t)(((w7 >> 56) | (w8 << 8)) & mask); + out[25] = base + (uint32_t)((w8 >> 13) & mask); + out[26] = base + (uint32_t)((w8 >> 34) & mask); + out[27] = base + (uint32_t)(((w8 >> 55) | (w9 << 9)) & mask); + out[28] = base + (uint32_t)((w9 >> 12) & mask); + out[29] = base + (uint32_t)((w9 >> 33) & mask); + out[30] = base + (uint32_t)(((w9 >> 54) | (w10 << 10)) & mask); + out[31] = base + (uint32_t)((w10 >> 11) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 22-bit values, touching 11 64-bit words, using 88 bytes */ +static void unpackforblock22(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(4194303); + /* we are going to access 11 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + *pw += 88; /* we used up 88 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 22) & mask); + out[2] = base + (uint32_t)(((w0 >> 44) | (w1 << 20)) & mask); + out[3] = base + (uint32_t)((w1 >> 2) & mask); + out[4] = base + (uint32_t)((w1 >> 24) & mask); + out[5] = base + (uint32_t)(((w1 >> 46) | (w2 << 18)) & mask); + out[6] = base + (uint32_t)((w2 >> 4) & mask); + out[7] = base + (uint32_t)((w2 >> 26) & mask); + out[8] = base + (uint32_t)(((w2 >> 48) | (w3 << 16)) & mask); + out[9] = base + (uint32_t)((w3 >> 6) & mask); + out[10] = base + (uint32_t)((w3 >> 28) & mask); + out[11] = base + (uint32_t)(((w3 >> 50) | (w4 << 14)) & mask); + out[12] = base + (uint32_t)((w4 >> 8) & mask); + out[13] = base + (uint32_t)((w4 >> 30) & mask); + out[14] = base + (uint32_t)(((w4 >> 52) | (w5 << 12)) & mask); + out[15] = base + (uint32_t)((w5 >> 10) & mask); + out[16] = base + (uint32_t)((w5 >> 32) & mask); + out[17] = base + (uint32_t)(((w5 >> 54) | (w6 << 10)) & mask); + out[18] = base + (uint32_t)((w6 >> 12) & mask); + out[19] = base + (uint32_t)((w6 >> 34) & mask); + out[20] = base + (uint32_t)(((w6 >> 56) | (w7 << 8)) & mask); + out[21] = base + (uint32_t)((w7 >> 14) & mask); + out[22] = base + (uint32_t)((w7 >> 36) & mask); + out[23] = base + (uint32_t)(((w7 >> 58) | (w8 << 6)) & mask); + out[24] = base + (uint32_t)((w8 >> 16) & mask); + out[25] = base + (uint32_t)((w8 >> 38) & mask); + out[26] = base + (uint32_t)(((w8 >> 60) | (w9 << 4)) & mask); + out[27] = base + (uint32_t)((w9 >> 18) & mask); + out[28] = base + (uint32_t)((w9 >> 40) & mask); + out[29] = base + (uint32_t)(((w9 >> 62) | (w10 << 2)) & mask); + out[30] = base + (uint32_t)((w10 >> 20) & mask); + out[31] = base + (uint32_t)(w10 >> 42); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 23-bit values, touching 12 64-bit words, using 92 bytes */ +static void unpackforblock23(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(8388607); + /* we are going to access 12 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + *pw += 92; /* we used up 92 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 23) & mask); + out[2] = base + (uint32_t)(((w0 >> 46) | (w1 << 18)) & mask); + out[3] = base + (uint32_t)((w1 >> 5) & mask); + out[4] = base + (uint32_t)((w1 >> 28) & mask); + out[5] = base + (uint32_t)(((w1 >> 51) | (w2 << 13)) & mask); + out[6] = base + (uint32_t)((w2 >> 10) & mask); + out[7] = base + (uint32_t)((w2 >> 33) & mask); + out[8] = base + (uint32_t)(((w2 >> 56) | (w3 << 8)) & mask); + out[9] = base + (uint32_t)((w3 >> 15) & mask); + out[10] = base + (uint32_t)((w3 >> 38) & mask); + out[11] = base + (uint32_t)(((w3 >> 61) | (w4 << 3)) & mask); + out[12] = base + (uint32_t)((w4 >> 20) & mask); + out[13] = base + (uint32_t)(((w4 >> 43) | (w5 << 21)) & mask); + out[14] = base + (uint32_t)((w5 >> 2) & mask); + out[15] = base + (uint32_t)((w5 >> 25) & mask); + out[16] = base + (uint32_t)(((w5 >> 48) | (w6 << 16)) & mask); + out[17] = base + (uint32_t)((w6 >> 7) & mask); + out[18] = base + (uint32_t)((w6 >> 30) & mask); + out[19] = base + (uint32_t)(((w6 >> 53) | (w7 << 11)) & mask); + out[20] = base + (uint32_t)((w7 >> 12) & mask); + out[21] = base + (uint32_t)((w7 >> 35) & mask); + out[22] = base + (uint32_t)(((w7 >> 58) | (w8 << 6)) & mask); + out[23] = base + (uint32_t)((w8 >> 17) & mask); + out[24] = base + (uint32_t)((w8 >> 40) & mask); + out[25] = base + (uint32_t)(((w8 >> 63) | (w9 << 1)) & mask); + out[26] = base + (uint32_t)((w9 >> 22) & mask); + out[27] = base + (uint32_t)(((w9 >> 45) | (w10 << 19)) & mask); + out[28] = base + (uint32_t)((w10 >> 4) & mask); + out[29] = base + (uint32_t)((w10 >> 27) & mask); + out[30] = base + (uint32_t)(((w10 >> 50) | (w11 << 14)) & mask); + out[31] = base + (uint32_t)((w11 >> 9) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 24-bit values, touching 12 64-bit words, using 96 bytes */ +static void unpackforblock24(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(16777215); + /* we are going to access 12 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + *pw += 96; /* we used up 96 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 24) & mask); + out[2] = base + (uint32_t)(((w0 >> 48) | (w1 << 16)) & mask); + out[3] = base + (uint32_t)((w1 >> 8) & mask); + out[4] = base + (uint32_t)((w1 >> 32) & mask); + out[5] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[6] = base + (uint32_t)((w2 >> 16) & mask); + out[7] = base + (uint32_t)(w2 >> 40); + out[8] = base + (uint32_t)((w3)&mask); + out[9] = base + (uint32_t)((w3 >> 24) & mask); + out[10] = base + (uint32_t)(((w3 >> 48) | (w4 << 16)) & mask); + out[11] = base + (uint32_t)((w4 >> 8) & mask); + out[12] = base + (uint32_t)((w4 >> 32) & mask); + out[13] = base + (uint32_t)(((w4 >> 56) | (w5 << 8)) & mask); + out[14] = base + (uint32_t)((w5 >> 16) & mask); + out[15] = base + (uint32_t)(w5 >> 40); + out[16] = base + (uint32_t)((w6)&mask); + out[17] = base + (uint32_t)((w6 >> 24) & mask); + out[18] = base + (uint32_t)(((w6 >> 48) | (w7 << 16)) & mask); + out[19] = base + (uint32_t)((w7 >> 8) & mask); + out[20] = base + (uint32_t)((w7 >> 32) & mask); + out[21] = base + (uint32_t)(((w7 >> 56) | (w8 << 8)) & mask); + out[22] = base + (uint32_t)((w8 >> 16) & mask); + out[23] = base + (uint32_t)(w8 >> 40); + out[24] = base + (uint32_t)((w9)&mask); + out[25] = base + (uint32_t)((w9 >> 24) & mask); + out[26] = base + (uint32_t)(((w9 >> 48) | (w10 << 16)) & mask); + out[27] = base + (uint32_t)((w10 >> 8) & mask); + out[28] = base + (uint32_t)((w10 >> 32) & mask); + out[29] = base + (uint32_t)(((w10 >> 56) | (w11 << 8)) & mask); + out[30] = base + (uint32_t)((w11 >> 16) & mask); + out[31] = base + (uint32_t)(w11 >> 40); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 25-bit values, touching 13 64-bit words, using 100 bytes */ +static void unpackforblock25(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(33554431); + /* we are going to access 13 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + *pw += 100; /* we used up 100 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 25) & mask); + out[2] = base + (uint32_t)(((w0 >> 50) | (w1 << 14)) & mask); + out[3] = base + (uint32_t)((w1 >> 11) & mask); + out[4] = base + (uint32_t)((w1 >> 36) & mask); + out[5] = base + (uint32_t)(((w1 >> 61) | (w2 << 3)) & mask); + out[6] = base + (uint32_t)((w2 >> 22) & mask); + out[7] = base + (uint32_t)(((w2 >> 47) | (w3 << 17)) & mask); + out[8] = base + (uint32_t)((w3 >> 8) & mask); + out[9] = base + (uint32_t)((w3 >> 33) & mask); + out[10] = base + (uint32_t)(((w3 >> 58) | (w4 << 6)) & mask); + out[11] = base + (uint32_t)((w4 >> 19) & mask); + out[12] = base + (uint32_t)(((w4 >> 44) | (w5 << 20)) & mask); + out[13] = base + (uint32_t)((w5 >> 5) & mask); + out[14] = base + (uint32_t)((w5 >> 30) & mask); + out[15] = base + (uint32_t)(((w5 >> 55) | (w6 << 9)) & mask); + out[16] = base + (uint32_t)((w6 >> 16) & mask); + out[17] = base + (uint32_t)(((w6 >> 41) | (w7 << 23)) & mask); + out[18] = base + (uint32_t)((w7 >> 2) & mask); + out[19] = base + (uint32_t)((w7 >> 27) & mask); + out[20] = base + (uint32_t)(((w7 >> 52) | (w8 << 12)) & mask); + out[21] = base + (uint32_t)((w8 >> 13) & mask); + out[22] = base + (uint32_t)((w8 >> 38) & mask); + out[23] = base + (uint32_t)(((w8 >> 63) | (w9 << 1)) & mask); + out[24] = base + (uint32_t)((w9 >> 24) & mask); + out[25] = base + (uint32_t)(((w9 >> 49) | (w10 << 15)) & mask); + out[26] = base + (uint32_t)((w10 >> 10) & mask); + out[27] = base + (uint32_t)((w10 >> 35) & mask); + out[28] = base + (uint32_t)(((w10 >> 60) | (w11 << 4)) & mask); + out[29] = base + (uint32_t)((w11 >> 21) & mask); + out[30] = base + (uint32_t)(((w11 >> 46) | (w12 << 18)) & mask); + out[31] = base + (uint32_t)((w12 >> 7) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 26-bit values, touching 13 64-bit words, using 104 bytes */ +static void unpackforblock26(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(67108863); + /* we are going to access 13 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + *pw += 104; /* we used up 104 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 26) & mask); + out[2] = base + (uint32_t)(((w0 >> 52) | (w1 << 12)) & mask); + out[3] = base + (uint32_t)((w1 >> 14) & mask); + out[4] = base + (uint32_t)(((w1 >> 40) | (w2 << 24)) & mask); + out[5] = base + (uint32_t)((w2 >> 2) & mask); + out[6] = base + (uint32_t)((w2 >> 28) & mask); + out[7] = base + (uint32_t)(((w2 >> 54) | (w3 << 10)) & mask); + out[8] = base + (uint32_t)((w3 >> 16) & mask); + out[9] = base + (uint32_t)(((w3 >> 42) | (w4 << 22)) & mask); + out[10] = base + (uint32_t)((w4 >> 4) & mask); + out[11] = base + (uint32_t)((w4 >> 30) & mask); + out[12] = base + (uint32_t)(((w4 >> 56) | (w5 << 8)) & mask); + out[13] = base + (uint32_t)((w5 >> 18) & mask); + out[14] = base + (uint32_t)(((w5 >> 44) | (w6 << 20)) & mask); + out[15] = base + (uint32_t)((w6 >> 6) & mask); + out[16] = base + (uint32_t)((w6 >> 32) & mask); + out[17] = base + (uint32_t)(((w6 >> 58) | (w7 << 6)) & mask); + out[18] = base + (uint32_t)((w7 >> 20) & mask); + out[19] = base + (uint32_t)(((w7 >> 46) | (w8 << 18)) & mask); + out[20] = base + (uint32_t)((w8 >> 8) & mask); + out[21] = base + (uint32_t)((w8 >> 34) & mask); + out[22] = base + (uint32_t)(((w8 >> 60) | (w9 << 4)) & mask); + out[23] = base + (uint32_t)((w9 >> 22) & mask); + out[24] = base + (uint32_t)(((w9 >> 48) | (w10 << 16)) & mask); + out[25] = base + (uint32_t)((w10 >> 10) & mask); + out[26] = base + (uint32_t)((w10 >> 36) & mask); + out[27] = base + (uint32_t)(((w10 >> 62) | (w11 << 2)) & mask); + out[28] = base + (uint32_t)((w11 >> 24) & mask); + out[29] = base + (uint32_t)(((w11 >> 50) | (w12 << 14)) & mask); + out[30] = base + (uint32_t)((w12 >> 12) & mask); + out[31] = base + (uint32_t)(w12 >> 38); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 27-bit values, touching 14 64-bit words, using 108 bytes */ +static void unpackforblock27(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(134217727); + /* we are going to access 14 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + *pw += 108; /* we used up 108 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 27) & mask); + out[2] = base + (uint32_t)(((w0 >> 54) | (w1 << 10)) & mask); + out[3] = base + (uint32_t)((w1 >> 17) & mask); + out[4] = base + (uint32_t)(((w1 >> 44) | (w2 << 20)) & mask); + out[5] = base + (uint32_t)((w2 >> 7) & mask); + out[6] = base + (uint32_t)((w2 >> 34) & mask); + out[7] = base + (uint32_t)(((w2 >> 61) | (w3 << 3)) & mask); + out[8] = base + (uint32_t)((w3 >> 24) & mask); + out[9] = base + (uint32_t)(((w3 >> 51) | (w4 << 13)) & mask); + out[10] = base + (uint32_t)((w4 >> 14) & mask); + out[11] = base + (uint32_t)(((w4 >> 41) | (w5 << 23)) & mask); + out[12] = base + (uint32_t)((w5 >> 4) & mask); + out[13] = base + (uint32_t)((w5 >> 31) & mask); + out[14] = base + (uint32_t)(((w5 >> 58) | (w6 << 6)) & mask); + out[15] = base + (uint32_t)((w6 >> 21) & mask); + out[16] = base + (uint32_t)(((w6 >> 48) | (w7 << 16)) & mask); + out[17] = base + (uint32_t)((w7 >> 11) & mask); + out[18] = base + (uint32_t)(((w7 >> 38) | (w8 << 26)) & mask); + out[19] = base + (uint32_t)((w8 >> 1) & mask); + out[20] = base + (uint32_t)((w8 >> 28) & mask); + out[21] = base + (uint32_t)(((w8 >> 55) | (w9 << 9)) & mask); + out[22] = base + (uint32_t)((w9 >> 18) & mask); + out[23] = base + (uint32_t)(((w9 >> 45) | (w10 << 19)) & mask); + out[24] = base + (uint32_t)((w10 >> 8) & mask); + out[25] = base + (uint32_t)((w10 >> 35) & mask); + out[26] = base + (uint32_t)(((w10 >> 62) | (w11 << 2)) & mask); + out[27] = base + (uint32_t)((w11 >> 25) & mask); + out[28] = base + (uint32_t)(((w11 >> 52) | (w12 << 12)) & mask); + out[29] = base + (uint32_t)((w12 >> 15) & mask); + out[30] = base + (uint32_t)(((w12 >> 42) | (w13 << 22)) & mask); + out[31] = base + (uint32_t)((w13 >> 5) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 28-bit values, touching 14 64-bit words, using 112 bytes */ +static void unpackforblock28(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(268435455); + /* we are going to access 14 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + *pw += 112; /* we used up 112 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 28) & mask); + out[2] = base + (uint32_t)(((w0 >> 56) | (w1 << 8)) & mask); + out[3] = base + (uint32_t)((w1 >> 20) & mask); + out[4] = base + (uint32_t)(((w1 >> 48) | (w2 << 16)) & mask); + out[5] = base + (uint32_t)((w2 >> 12) & mask); + out[6] = base + (uint32_t)(((w2 >> 40) | (w3 << 24)) & mask); + out[7] = base + (uint32_t)((w3 >> 4) & mask); + out[8] = base + (uint32_t)((w3 >> 32) & mask); + out[9] = base + (uint32_t)(((w3 >> 60) | (w4 << 4)) & mask); + out[10] = base + (uint32_t)((w4 >> 24) & mask); + out[11] = base + (uint32_t)(((w4 >> 52) | (w5 << 12)) & mask); + out[12] = base + (uint32_t)((w5 >> 16) & mask); + out[13] = base + (uint32_t)(((w5 >> 44) | (w6 << 20)) & mask); + out[14] = base + (uint32_t)((w6 >> 8) & mask); + out[15] = base + (uint32_t)(w6 >> 36); + out[16] = base + (uint32_t)((w7)&mask); + out[17] = base + (uint32_t)((w7 >> 28) & mask); + out[18] = base + (uint32_t)(((w7 >> 56) | (w8 << 8)) & mask); + out[19] = base + (uint32_t)((w8 >> 20) & mask); + out[20] = base + (uint32_t)(((w8 >> 48) | (w9 << 16)) & mask); + out[21] = base + (uint32_t)((w9 >> 12) & mask); + out[22] = base + (uint32_t)(((w9 >> 40) | (w10 << 24)) & mask); + out[23] = base + (uint32_t)((w10 >> 4) & mask); + out[24] = base + (uint32_t)((w10 >> 32) & mask); + out[25] = base + (uint32_t)(((w10 >> 60) | (w11 << 4)) & mask); + out[26] = base + (uint32_t)((w11 >> 24) & mask); + out[27] = base + (uint32_t)(((w11 >> 52) | (w12 << 12)) & mask); + out[28] = base + (uint32_t)((w12 >> 16) & mask); + out[29] = base + (uint32_t)(((w12 >> 44) | (w13 << 20)) & mask); + out[30] = base + (uint32_t)((w13 >> 8) & mask); + out[31] = base + (uint32_t)(w13 >> 36); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 29-bit values, touching 15 64-bit words, using 116 bytes */ +static void unpackforblock29(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(536870911); + /* we are going to access 15 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + *pw += 116; /* we used up 116 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 29) & mask); + out[2] = base + (uint32_t)(((w0 >> 58) | (w1 << 6)) & mask); + out[3] = base + (uint32_t)((w1 >> 23) & mask); + out[4] = base + (uint32_t)(((w1 >> 52) | (w2 << 12)) & mask); + out[5] = base + (uint32_t)((w2 >> 17) & mask); + out[6] = base + (uint32_t)(((w2 >> 46) | (w3 << 18)) & mask); + out[7] = base + (uint32_t)((w3 >> 11) & mask); + out[8] = base + (uint32_t)(((w3 >> 40) | (w4 << 24)) & mask); + out[9] = base + (uint32_t)((w4 >> 5) & mask); + out[10] = base + (uint32_t)((w4 >> 34) & mask); + out[11] = base + (uint32_t)(((w4 >> 63) | (w5 << 1)) & mask); + out[12] = base + (uint32_t)((w5 >> 28) & mask); + out[13] = base + (uint32_t)(((w5 >> 57) | (w6 << 7)) & mask); + out[14] = base + (uint32_t)((w6 >> 22) & mask); + out[15] = base + (uint32_t)(((w6 >> 51) | (w7 << 13)) & mask); + out[16] = base + (uint32_t)((w7 >> 16) & mask); + out[17] = base + (uint32_t)(((w7 >> 45) | (w8 << 19)) & mask); + out[18] = base + (uint32_t)((w8 >> 10) & mask); + out[19] = base + (uint32_t)(((w8 >> 39) | (w9 << 25)) & mask); + out[20] = base + (uint32_t)((w9 >> 4) & mask); + out[21] = base + (uint32_t)((w9 >> 33) & mask); + out[22] = base + (uint32_t)(((w9 >> 62) | (w10 << 2)) & mask); + out[23] = base + (uint32_t)((w10 >> 27) & mask); + out[24] = base + (uint32_t)(((w10 >> 56) | (w11 << 8)) & mask); + out[25] = base + (uint32_t)((w11 >> 21) & mask); + out[26] = base + (uint32_t)(((w11 >> 50) | (w12 << 14)) & mask); + out[27] = base + (uint32_t)((w12 >> 15) & mask); + out[28] = base + (uint32_t)(((w12 >> 44) | (w13 << 20)) & mask); + out[29] = base + (uint32_t)((w13 >> 9) & mask); + out[30] = base + (uint32_t)(((w13 >> 38) | (w14 << 26)) & mask); + out[31] = base + (uint32_t)((w14 >> 3) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 30-bit values, touching 15 64-bit words, using 120 bytes */ +static void unpackforblock30(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(1073741823); + /* we are going to access 15 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + *pw += 120; /* we used up 120 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 30) & mask); + out[2] = base + (uint32_t)(((w0 >> 60) | (w1 << 4)) & mask); + out[3] = base + (uint32_t)((w1 >> 26) & mask); + out[4] = base + (uint32_t)(((w1 >> 56) | (w2 << 8)) & mask); + out[5] = base + (uint32_t)((w2 >> 22) & mask); + out[6] = base + (uint32_t)(((w2 >> 52) | (w3 << 12)) & mask); + out[7] = base + (uint32_t)((w3 >> 18) & mask); + out[8] = base + (uint32_t)(((w3 >> 48) | (w4 << 16)) & mask); + out[9] = base + (uint32_t)((w4 >> 14) & mask); + out[10] = base + (uint32_t)(((w4 >> 44) | (w5 << 20)) & mask); + out[11] = base + (uint32_t)((w5 >> 10) & mask); + out[12] = base + (uint32_t)(((w5 >> 40) | (w6 << 24)) & mask); + out[13] = base + (uint32_t)((w6 >> 6) & mask); + out[14] = base + (uint32_t)(((w6 >> 36) | (w7 << 28)) & mask); + out[15] = base + (uint32_t)((w7 >> 2) & mask); + out[16] = base + (uint32_t)((w7 >> 32) & mask); + out[17] = base + (uint32_t)(((w7 >> 62) | (w8 << 2)) & mask); + out[18] = base + (uint32_t)((w8 >> 28) & mask); + out[19] = base + (uint32_t)(((w8 >> 58) | (w9 << 6)) & mask); + out[20] = base + (uint32_t)((w9 >> 24) & mask); + out[21] = base + (uint32_t)(((w9 >> 54) | (w10 << 10)) & mask); + out[22] = base + (uint32_t)((w10 >> 20) & mask); + out[23] = base + (uint32_t)(((w10 >> 50) | (w11 << 14)) & mask); + out[24] = base + (uint32_t)((w11 >> 16) & mask); + out[25] = base + (uint32_t)(((w11 >> 46) | (w12 << 18)) & mask); + out[26] = base + (uint32_t)((w12 >> 12) & mask); + out[27] = base + (uint32_t)(((w12 >> 42) | (w13 << 22)) & mask); + out[28] = base + (uint32_t)((w13 >> 8) & mask); + out[29] = base + (uint32_t)(((w13 >> 38) | (w14 << 26)) & mask); + out[30] = base + (uint32_t)((w14 >> 4) & mask); + out[31] = base + (uint32_t)(w14 >> 34); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 31-bit values, touching 16 64-bit words, using 124 bytes */ +static void unpackforblock31(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + const uint64_t mask = UINT64_C(2147483647); + /* we are going to access 16 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + *pw += 124; /* we used up 124 input bytes */ + out[0] = base + (uint32_t)((w0)&mask); + out[1] = base + (uint32_t)((w0 >> 31) & mask); + out[2] = base + (uint32_t)(((w0 >> 62) | (w1 << 2)) & mask); + out[3] = base + (uint32_t)((w1 >> 29) & mask); + out[4] = base + (uint32_t)(((w1 >> 60) | (w2 << 4)) & mask); + out[5] = base + (uint32_t)((w2 >> 27) & mask); + out[6] = base + (uint32_t)(((w2 >> 58) | (w3 << 6)) & mask); + out[7] = base + (uint32_t)((w3 >> 25) & mask); + out[8] = base + (uint32_t)(((w3 >> 56) | (w4 << 8)) & mask); + out[9] = base + (uint32_t)((w4 >> 23) & mask); + out[10] = base + (uint32_t)(((w4 >> 54) | (w5 << 10)) & mask); + out[11] = base + (uint32_t)((w5 >> 21) & mask); + out[12] = base + (uint32_t)(((w5 >> 52) | (w6 << 12)) & mask); + out[13] = base + (uint32_t)((w6 >> 19) & mask); + out[14] = base + (uint32_t)(((w6 >> 50) | (w7 << 14)) & mask); + out[15] = base + (uint32_t)((w7 >> 17) & mask); + out[16] = base + (uint32_t)(((w7 >> 48) | (w8 << 16)) & mask); + out[17] = base + (uint32_t)((w8 >> 15) & mask); + out[18] = base + (uint32_t)(((w8 >> 46) | (w9 << 18)) & mask); + out[19] = base + (uint32_t)((w9 >> 13) & mask); + out[20] = base + (uint32_t)(((w9 >> 44) | (w10 << 20)) & mask); + out[21] = base + (uint32_t)((w10 >> 11) & mask); + out[22] = base + (uint32_t)(((w10 >> 42) | (w11 << 22)) & mask); + out[23] = base + (uint32_t)((w11 >> 9) & mask); + out[24] = base + (uint32_t)(((w11 >> 40) | (w12 << 24)) & mask); + out[25] = base + (uint32_t)((w12 >> 7) & mask); + out[26] = base + (uint32_t)(((w12 >> 38) | (w13 << 26)) & mask); + out[27] = base + (uint32_t)((w13 >> 5) & mask); + out[28] = base + (uint32_t)(((w13 >> 36) | (w14 << 28)) & mask); + out[29] = base + (uint32_t)((w14 >> 3) & mask); + out[30] = base + (uint32_t)(((w14 >> 34) | (w15 << 30)) & mask); + out[31] = base + (uint32_t)((w15 >> 1) & mask); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +/* we packed 32 32-bit values, touching 16 64-bit words, using 128 bytes */ +static void unpackforblock32(const uint32_t base, const uint8_t **pw, + uint32_t **pout) { + const uint64_t *pw64 = *(const uint64_t **)pw; + uint32_t *out = *pout; + /* we are going to access 16 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + *pw += 128; /* we used up 128 input bytes */ + out[0] = base + (uint32_t)((w0)); + out[1] = base + (uint32_t)(w0 >> 32); + out[2] = base + (uint32_t)((w1)); + out[3] = base + (uint32_t)(w1 >> 32); + out[4] = base + (uint32_t)((w2)); + out[5] = base + (uint32_t)(w2 >> 32); + out[6] = base + (uint32_t)((w3)); + out[7] = base + (uint32_t)(w3 >> 32); + out[8] = base + (uint32_t)((w4)); + out[9] = base + (uint32_t)(w4 >> 32); + out[10] = base + (uint32_t)((w5)); + out[11] = base + (uint32_t)(w5 >> 32); + out[12] = base + (uint32_t)((w6)); + out[13] = base + (uint32_t)(w6 >> 32); + out[14] = base + (uint32_t)((w7)); + out[15] = base + (uint32_t)(w7 >> 32); + out[16] = base + (uint32_t)((w8)); + out[17] = base + (uint32_t)(w8 >> 32); + out[18] = base + (uint32_t)((w9)); + out[19] = base + (uint32_t)(w9 >> 32); + out[20] = base + (uint32_t)((w10)); + out[21] = base + (uint32_t)(w10 >> 32); + out[22] = base + (uint32_t)((w11)); + out[23] = base + (uint32_t)(w11 >> 32); + out[24] = base + (uint32_t)((w12)); + out[25] = base + (uint32_t)(w12 >> 32); + out[26] = base + (uint32_t)((w13)); + out[27] = base + (uint32_t)(w13 >> 32); + out[28] = base + (uint32_t)((w14)); + out[29] = base + (uint32_t)(w14 >> 32); + out[30] = base + (uint32_t)((w15)); + out[31] = base + (uint32_t)(w15 >> 32); + *pout += 32; /* we wrote 32 32-bit integers */ +} + +static packforblockfnc funcForPackArr[] = { + &packforblock0, &packforblock1, &packforblock2, &packforblock3, + &packforblock4, &packforblock5, &packforblock6, &packforblock7, + &packforblock8, &packforblock9, &packforblock10, &packforblock11, + &packforblock12, &packforblock13, &packforblock14, &packforblock15, + &packforblock16, &packforblock17, &packforblock18, &packforblock19, + &packforblock20, &packforblock21, &packforblock22, &packforblock23, + &packforblock24, &packforblock25, &packforblock26, &packforblock27, + &packforblock28, &packforblock29, &packforblock30, &packforblock31, + &packforblock32}; +static unpackforblockfnc funcForUnpackArr[] = { + &unpackforblock0, &unpackforblock1, &unpackforblock2, &unpackforblock3, + &unpackforblock4, &unpackforblock5, &unpackforblock6, &unpackforblock7, + &unpackforblock8, &unpackforblock9, &unpackforblock10, &unpackforblock11, + &unpackforblock12, &unpackforblock13, &unpackforblock14, &unpackforblock15, + &unpackforblock16, &unpackforblock17, &unpackforblock18, &unpackforblock19, + &unpackforblock20, &unpackforblock21, &unpackforblock22, &unpackforblock23, + &unpackforblock24, &unpackforblock25, &unpackforblock26, &unpackforblock27, + &unpackforblock28, &unpackforblock29, &unpackforblock30, &unpackforblock31, + &unpackforblock32}; +/** turbopacking32.py ends here **/ + +#endif // INCLUDE_TURBOPACKING32_H diff --git a/src/core/CLucene/index/turbopacking64.h b/src/core/CLucene/index/turbopacking64.h new file mode 100644 index 00000000000..e47c6f367ac --- /dev/null +++ b/src/core/CLucene/index/turbopacking64.h @@ -0,0 +1,9695 @@ + +#ifndef INCLUDE_TURBOPACKING64_H +#define INCLUDE_TURBOPACKING64_H +#include // mostly for Microsoft compilers +#include // part of Visual Studio 2010 and better + + +#ifndef UINT64_C +#define UINT64_C(c) (c ## ULL) +#endif + + +/** +* (c) Daniel Lemire +* Apache License 2.0 +*/ +/** turbopacking64 starts here **/ +/** +* this code mimics the way TurboPFor packs short arrays of integers. +* We pack and unpack always at least a full 64-bit word, plus whatever +* is necessary to get to an even number of bytes. +*/ +typedef void (*packforblockfnc_64)(const uint64_t base, const uint64_t ** pin, uint8_t ** pw); +typedef void (*unpackforblockfnc_64)(const uint64_t base, const uint8_t ** pw, uint64_t ** pout); + +static void packforblock0_64(const uint64_t , const uint64_t ** pin, uint8_t ** pw) { + (void)pw; + *pin += 32; /* we consumed 32 64-bit integers */ +} + + +/* we are going to pack 32 1-bit values, touching 1 64-bit words, using 4 bytes */ +static void packforblock1_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 1 64-bit word */ + uint64_t w0; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 1; + w0 |= (in[2] - base) << 2; + w0 |= (in[3] - base) << 3; + w0 |= (in[4] - base) << 4; + w0 |= (in[5] - base) << 5; + w0 |= (in[6] - base) << 6; + w0 |= (in[7] - base) << 7; + w0 |= (in[8] - base) << 8; + w0 |= (in[9] - base) << 9; + w0 |= (in[10] - base) << 10; + w0 |= (in[11] - base) << 11; + w0 |= (in[12] - base) << 12; + w0 |= (in[13] - base) << 13; + w0 |= (in[14] - base) << 14; + w0 |= (in[15] - base) << 15; + w0 |= (in[16] - base) << 16; + w0 |= (in[17] - base) << 17; + w0 |= (in[18] - base) << 18; + w0 |= (in[19] - base) << 19; + w0 |= (in[20] - base) << 20; + w0 |= (in[21] - base) << 21; + w0 |= (in[22] - base) << 22; + w0 |= (in[23] - base) << 23; + w0 |= (in[24] - base) << 24; + w0 |= (in[25] - base) << 25; + w0 |= (in[26] - base) << 26; + w0 |= (in[27] - base) << 27; + w0 |= (in[28] - base) << 28; + w0 |= (in[29] - base) << 29; + w0 |= (in[30] - base) << 30; + w0 |= (in[31] - base) << 31; + pw64[0] = w0; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 4; /* we used up 4 output bytes */ +} + + +/* we are going to pack 32 2-bit values, touching 1 64-bit words, using 8 bytes */ +static void packforblock2_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 1 64-bit word */ + uint64_t w0; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 2; + w0 |= (in[2] - base) << 4; + w0 |= (in[3] - base) << 6; + w0 |= (in[4] - base) << 8; + w0 |= (in[5] - base) << 10; + w0 |= (in[6] - base) << 12; + w0 |= (in[7] - base) << 14; + w0 |= (in[8] - base) << 16; + w0 |= (in[9] - base) << 18; + w0 |= (in[10] - base) << 20; + w0 |= (in[11] - base) << 22; + w0 |= (in[12] - base) << 24; + w0 |= (in[13] - base) << 26; + w0 |= (in[14] - base) << 28; + w0 |= (in[15] - base) << 30; + w0 |= (in[16] - base) << 32; + w0 |= (in[17] - base) << 34; + w0 |= (in[18] - base) << 36; + w0 |= (in[19] - base) << 38; + w0 |= (in[20] - base) << 40; + w0 |= (in[21] - base) << 42; + w0 |= (in[22] - base) << 44; + w0 |= (in[23] - base) << 46; + w0 |= (in[24] - base) << 48; + w0 |= (in[25] - base) << 50; + w0 |= (in[26] - base) << 52; + w0 |= (in[27] - base) << 54; + w0 |= (in[28] - base) << 56; + w0 |= (in[29] - base) << 58; + w0 |= (in[30] - base) << 60; + w0 |= (in[31] - base) << 62; + pw64[0] = w0; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 8; /* we used up 8 output bytes */ +} + + +/* we are going to pack 32 3-bit values, touching 2 64-bit words, using 12 bytes */ +static void packforblock3_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 2 64-bit words */ + uint64_t w0; + uint64_t w1; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 3; + w0 |= (in[2] - base) << 6; + w0 |= (in[3] - base) << 9; + w0 |= (in[4] - base) << 12; + w0 |= (in[5] - base) << 15; + w0 |= (in[6] - base) << 18; + w0 |= (in[7] - base) << 21; + w0 |= (in[8] - base) << 24; + w0 |= (in[9] - base) << 27; + w0 |= (in[10] - base) << 30; + w0 |= (in[11] - base) << 33; + w0 |= (in[12] - base) << 36; + w0 |= (in[13] - base) << 39; + w0 |= (in[14] - base) << 42; + w0 |= (in[15] - base) << 45; + w0 |= (in[16] - base) << 48; + w0 |= (in[17] - base) << 51; + w0 |= (in[18] - base) << 54; + w0 |= (in[19] - base) << 57; + w0 |= (in[20] - base) << 60; + w0 |= (in[21] - base) << 63; + w1 = (in[21] - base) >> 1; + w1 |= (in[22] - base) << 2; + w1 |= (in[23] - base) << 5; + w1 |= (in[24] - base) << 8; + w1 |= (in[25] - base) << 11; + w1 |= (in[26] - base) << 14; + w1 |= (in[27] - base) << 17; + w1 |= (in[28] - base) << 20; + w1 |= (in[29] - base) << 23; + w1 |= (in[30] - base) << 26; + w1 |= (in[31] - base) << 29; + pw64[0] = w0; + pw64[1] = w1; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 12; /* we used up 12 output bytes */ +} + + +/* we are going to pack 32 4-bit values, touching 2 64-bit words, using 16 bytes */ +static void packforblock4_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 2 64-bit words */ + uint64_t w0; + uint64_t w1; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 4; + w0 |= (in[2] - base) << 8; + w0 |= (in[3] - base) << 12; + w0 |= (in[4] - base) << 16; + w0 |= (in[5] - base) << 20; + w0 |= (in[6] - base) << 24; + w0 |= (in[7] - base) << 28; + w0 |= (in[8] - base) << 32; + w0 |= (in[9] - base) << 36; + w0 |= (in[10] - base) << 40; + w0 |= (in[11] - base) << 44; + w0 |= (in[12] - base) << 48; + w0 |= (in[13] - base) << 52; + w0 |= (in[14] - base) << 56; + w0 |= (in[15] - base) << 60; + w1 = (in[16] - base); + w1 |= (in[17] - base) << 4; + w1 |= (in[18] - base) << 8; + w1 |= (in[19] - base) << 12; + w1 |= (in[20] - base) << 16; + w1 |= (in[21] - base) << 20; + w1 |= (in[22] - base) << 24; + w1 |= (in[23] - base) << 28; + w1 |= (in[24] - base) << 32; + w1 |= (in[25] - base) << 36; + w1 |= (in[26] - base) << 40; + w1 |= (in[27] - base) << 44; + w1 |= (in[28] - base) << 48; + w1 |= (in[29] - base) << 52; + w1 |= (in[30] - base) << 56; + w1 |= (in[31] - base) << 60; + pw64[0] = w0; + pw64[1] = w1; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 16; /* we used up 16 output bytes */ +} + + +/* we are going to pack 32 5-bit values, touching 3 64-bit words, using 20 bytes */ +static void packforblock5_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 3 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 5; + w0 |= (in[2] - base) << 10; + w0 |= (in[3] - base) << 15; + w0 |= (in[4] - base) << 20; + w0 |= (in[5] - base) << 25; + w0 |= (in[6] - base) << 30; + w0 |= (in[7] - base) << 35; + w0 |= (in[8] - base) << 40; + w0 |= (in[9] - base) << 45; + w0 |= (in[10] - base) << 50; + w0 |= (in[11] - base) << 55; + w0 |= (in[12] - base) << 60; + w1 = (in[12] - base) >> 4; + w1 |= (in[13] - base) << 1; + w1 |= (in[14] - base) << 6; + w1 |= (in[15] - base) << 11; + w1 |= (in[16] - base) << 16; + w1 |= (in[17] - base) << 21; + w1 |= (in[18] - base) << 26; + w1 |= (in[19] - base) << 31; + w1 |= (in[20] - base) << 36; + w1 |= (in[21] - base) << 41; + w1 |= (in[22] - base) << 46; + w1 |= (in[23] - base) << 51; + w1 |= (in[24] - base) << 56; + w1 |= (in[25] - base) << 61; + w2 = (in[25] - base) >> 3; + w2 |= (in[26] - base) << 2; + w2 |= (in[27] - base) << 7; + w2 |= (in[28] - base) << 12; + w2 |= (in[29] - base) << 17; + w2 |= (in[30] - base) << 22; + w2 |= (in[31] - base) << 27; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 20; /* we used up 20 output bytes */ +} + + +/* we are going to pack 32 6-bit values, touching 3 64-bit words, using 24 bytes */ +static void packforblock6_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 3 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 6; + w0 |= (in[2] - base) << 12; + w0 |= (in[3] - base) << 18; + w0 |= (in[4] - base) << 24; + w0 |= (in[5] - base) << 30; + w0 |= (in[6] - base) << 36; + w0 |= (in[7] - base) << 42; + w0 |= (in[8] - base) << 48; + w0 |= (in[9] - base) << 54; + w0 |= (in[10] - base) << 60; + w1 = (in[10] - base) >> 4; + w1 |= (in[11] - base) << 2; + w1 |= (in[12] - base) << 8; + w1 |= (in[13] - base) << 14; + w1 |= (in[14] - base) << 20; + w1 |= (in[15] - base) << 26; + w1 |= (in[16] - base) << 32; + w1 |= (in[17] - base) << 38; + w1 |= (in[18] - base) << 44; + w1 |= (in[19] - base) << 50; + w1 |= (in[20] - base) << 56; + w1 |= (in[21] - base) << 62; + w2 = (in[21] - base) >> 2; + w2 |= (in[22] - base) << 4; + w2 |= (in[23] - base) << 10; + w2 |= (in[24] - base) << 16; + w2 |= (in[25] - base) << 22; + w2 |= (in[26] - base) << 28; + w2 |= (in[27] - base) << 34; + w2 |= (in[28] - base) << 40; + w2 |= (in[29] - base) << 46; + w2 |= (in[30] - base) << 52; + w2 |= (in[31] - base) << 58; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 24; /* we used up 24 output bytes */ +} + + +/* we are going to pack 32 7-bit values, touching 4 64-bit words, using 28 bytes */ +static void packforblock7_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 4 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 7; + w0 |= (in[2] - base) << 14; + w0 |= (in[3] - base) << 21; + w0 |= (in[4] - base) << 28; + w0 |= (in[5] - base) << 35; + w0 |= (in[6] - base) << 42; + w0 |= (in[7] - base) << 49; + w0 |= (in[8] - base) << 56; + w0 |= (in[9] - base) << 63; + w1 = (in[9] - base) >> 1; + w1 |= (in[10] - base) << 6; + w1 |= (in[11] - base) << 13; + w1 |= (in[12] - base) << 20; + w1 |= (in[13] - base) << 27; + w1 |= (in[14] - base) << 34; + w1 |= (in[15] - base) << 41; + w1 |= (in[16] - base) << 48; + w1 |= (in[17] - base) << 55; + w1 |= (in[18] - base) << 62; + w2 = (in[18] - base) >> 2; + w2 |= (in[19] - base) << 5; + w2 |= (in[20] - base) << 12; + w2 |= (in[21] - base) << 19; + w2 |= (in[22] - base) << 26; + w2 |= (in[23] - base) << 33; + w2 |= (in[24] - base) << 40; + w2 |= (in[25] - base) << 47; + w2 |= (in[26] - base) << 54; + w2 |= (in[27] - base) << 61; + w3 = (in[27] - base) >> 3; + w3 |= (in[28] - base) << 4; + w3 |= (in[29] - base) << 11; + w3 |= (in[30] - base) << 18; + w3 |= (in[31] - base) << 25; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 28; /* we used up 28 output bytes */ +} + + +/* we are going to pack 32 8-bit values, touching 4 64-bit words, using 32 bytes */ +static void packforblock8_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 4 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 8; + w0 |= (in[2] - base) << 16; + w0 |= (in[3] - base) << 24; + w0 |= (in[4] - base) << 32; + w0 |= (in[5] - base) << 40; + w0 |= (in[6] - base) << 48; + w0 |= (in[7] - base) << 56; + w1 = (in[8] - base); + w1 |= (in[9] - base) << 8; + w1 |= (in[10] - base) << 16; + w1 |= (in[11] - base) << 24; + w1 |= (in[12] - base) << 32; + w1 |= (in[13] - base) << 40; + w1 |= (in[14] - base) << 48; + w1 |= (in[15] - base) << 56; + w2 = (in[16] - base); + w2 |= (in[17] - base) << 8; + w2 |= (in[18] - base) << 16; + w2 |= (in[19] - base) << 24; + w2 |= (in[20] - base) << 32; + w2 |= (in[21] - base) << 40; + w2 |= (in[22] - base) << 48; + w2 |= (in[23] - base) << 56; + w3 = (in[24] - base); + w3 |= (in[25] - base) << 8; + w3 |= (in[26] - base) << 16; + w3 |= (in[27] - base) << 24; + w3 |= (in[28] - base) << 32; + w3 |= (in[29] - base) << 40; + w3 |= (in[30] - base) << 48; + w3 |= (in[31] - base) << 56; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 32; /* we used up 32 output bytes */ +} + + +/* we are going to pack 32 9-bit values, touching 5 64-bit words, using 36 bytes */ +static void packforblock9_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 5 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 9; + w0 |= (in[2] - base) << 18; + w0 |= (in[3] - base) << 27; + w0 |= (in[4] - base) << 36; + w0 |= (in[5] - base) << 45; + w0 |= (in[6] - base) << 54; + w0 |= (in[7] - base) << 63; + w1 = (in[7] - base) >> 1; + w1 |= (in[8] - base) << 8; + w1 |= (in[9] - base) << 17; + w1 |= (in[10] - base) << 26; + w1 |= (in[11] - base) << 35; + w1 |= (in[12] - base) << 44; + w1 |= (in[13] - base) << 53; + w1 |= (in[14] - base) << 62; + w2 = (in[14] - base) >> 2; + w2 |= (in[15] - base) << 7; + w2 |= (in[16] - base) << 16; + w2 |= (in[17] - base) << 25; + w2 |= (in[18] - base) << 34; + w2 |= (in[19] - base) << 43; + w2 |= (in[20] - base) << 52; + w2 |= (in[21] - base) << 61; + w3 = (in[21] - base) >> 3; + w3 |= (in[22] - base) << 6; + w3 |= (in[23] - base) << 15; + w3 |= (in[24] - base) << 24; + w3 |= (in[25] - base) << 33; + w3 |= (in[26] - base) << 42; + w3 |= (in[27] - base) << 51; + w3 |= (in[28] - base) << 60; + w4 = (in[28] - base) >> 4; + w4 |= (in[29] - base) << 5; + w4 |= (in[30] - base) << 14; + w4 |= (in[31] - base) << 23; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 36; /* we used up 36 output bytes */ +} + + +/* we are going to pack 32 10-bit values, touching 5 64-bit words, using 40 bytes */ +static void packforblock10_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 5 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 10; + w0 |= (in[2] - base) << 20; + w0 |= (in[3] - base) << 30; + w0 |= (in[4] - base) << 40; + w0 |= (in[5] - base) << 50; + w0 |= (in[6] - base) << 60; + w1 = (in[6] - base) >> 4; + w1 |= (in[7] - base) << 6; + w1 |= (in[8] - base) << 16; + w1 |= (in[9] - base) << 26; + w1 |= (in[10] - base) << 36; + w1 |= (in[11] - base) << 46; + w1 |= (in[12] - base) << 56; + w2 = (in[12] - base) >> 8; + w2 |= (in[13] - base) << 2; + w2 |= (in[14] - base) << 12; + w2 |= (in[15] - base) << 22; + w2 |= (in[16] - base) << 32; + w2 |= (in[17] - base) << 42; + w2 |= (in[18] - base) << 52; + w2 |= (in[19] - base) << 62; + w3 = (in[19] - base) >> 2; + w3 |= (in[20] - base) << 8; + w3 |= (in[21] - base) << 18; + w3 |= (in[22] - base) << 28; + w3 |= (in[23] - base) << 38; + w3 |= (in[24] - base) << 48; + w3 |= (in[25] - base) << 58; + w4 = (in[25] - base) >> 6; + w4 |= (in[26] - base) << 4; + w4 |= (in[27] - base) << 14; + w4 |= (in[28] - base) << 24; + w4 |= (in[29] - base) << 34; + w4 |= (in[30] - base) << 44; + w4 |= (in[31] - base) << 54; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 40; /* we used up 40 output bytes */ +} + + +/* we are going to pack 32 11-bit values, touching 6 64-bit words, using 44 bytes */ +static void packforblock11_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 6 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 11; + w0 |= (in[2] - base) << 22; + w0 |= (in[3] - base) << 33; + w0 |= (in[4] - base) << 44; + w0 |= (in[5] - base) << 55; + w1 = (in[5] - base) >> 9; + w1 |= (in[6] - base) << 2; + w1 |= (in[7] - base) << 13; + w1 |= (in[8] - base) << 24; + w1 |= (in[9] - base) << 35; + w1 |= (in[10] - base) << 46; + w1 |= (in[11] - base) << 57; + w2 = (in[11] - base) >> 7; + w2 |= (in[12] - base) << 4; + w2 |= (in[13] - base) << 15; + w2 |= (in[14] - base) << 26; + w2 |= (in[15] - base) << 37; + w2 |= (in[16] - base) << 48; + w2 |= (in[17] - base) << 59; + w3 = (in[17] - base) >> 5; + w3 |= (in[18] - base) << 6; + w3 |= (in[19] - base) << 17; + w3 |= (in[20] - base) << 28; + w3 |= (in[21] - base) << 39; + w3 |= (in[22] - base) << 50; + w3 |= (in[23] - base) << 61; + w4 = (in[23] - base) >> 3; + w4 |= (in[24] - base) << 8; + w4 |= (in[25] - base) << 19; + w4 |= (in[26] - base) << 30; + w4 |= (in[27] - base) << 41; + w4 |= (in[28] - base) << 52; + w4 |= (in[29] - base) << 63; + w5 = (in[29] - base) >> 1; + w5 |= (in[30] - base) << 10; + w5 |= (in[31] - base) << 21; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 44; /* we used up 44 output bytes */ +} + + +/* we are going to pack 32 12-bit values, touching 6 64-bit words, using 48 bytes */ +static void packforblock12_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 6 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 12; + w0 |= (in[2] - base) << 24; + w0 |= (in[3] - base) << 36; + w0 |= (in[4] - base) << 48; + w0 |= (in[5] - base) << 60; + w1 = (in[5] - base) >> 4; + w1 |= (in[6] - base) << 8; + w1 |= (in[7] - base) << 20; + w1 |= (in[8] - base) << 32; + w1 |= (in[9] - base) << 44; + w1 |= (in[10] - base) << 56; + w2 = (in[10] - base) >> 8; + w2 |= (in[11] - base) << 4; + w2 |= (in[12] - base) << 16; + w2 |= (in[13] - base) << 28; + w2 |= (in[14] - base) << 40; + w2 |= (in[15] - base) << 52; + w3 = (in[16] - base); + w3 |= (in[17] - base) << 12; + w3 |= (in[18] - base) << 24; + w3 |= (in[19] - base) << 36; + w3 |= (in[20] - base) << 48; + w3 |= (in[21] - base) << 60; + w4 = (in[21] - base) >> 4; + w4 |= (in[22] - base) << 8; + w4 |= (in[23] - base) << 20; + w4 |= (in[24] - base) << 32; + w4 |= (in[25] - base) << 44; + w4 |= (in[26] - base) << 56; + w5 = (in[26] - base) >> 8; + w5 |= (in[27] - base) << 4; + w5 |= (in[28] - base) << 16; + w5 |= (in[29] - base) << 28; + w5 |= (in[30] - base) << 40; + w5 |= (in[31] - base) << 52; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 48; /* we used up 48 output bytes */ +} + + +/* we are going to pack 32 13-bit values, touching 7 64-bit words, using 52 bytes */ +static void packforblock13_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 7 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 13; + w0 |= (in[2] - base) << 26; + w0 |= (in[3] - base) << 39; + w0 |= (in[4] - base) << 52; + w1 = (in[4] - base) >> 12; + w1 |= (in[5] - base) << 1; + w1 |= (in[6] - base) << 14; + w1 |= (in[7] - base) << 27; + w1 |= (in[8] - base) << 40; + w1 |= (in[9] - base) << 53; + w2 = (in[9] - base) >> 11; + w2 |= (in[10] - base) << 2; + w2 |= (in[11] - base) << 15; + w2 |= (in[12] - base) << 28; + w2 |= (in[13] - base) << 41; + w2 |= (in[14] - base) << 54; + w3 = (in[14] - base) >> 10; + w3 |= (in[15] - base) << 3; + w3 |= (in[16] - base) << 16; + w3 |= (in[17] - base) << 29; + w3 |= (in[18] - base) << 42; + w3 |= (in[19] - base) << 55; + w4 = (in[19] - base) >> 9; + w4 |= (in[20] - base) << 4; + w4 |= (in[21] - base) << 17; + w4 |= (in[22] - base) << 30; + w4 |= (in[23] - base) << 43; + w4 |= (in[24] - base) << 56; + w5 = (in[24] - base) >> 8; + w5 |= (in[25] - base) << 5; + w5 |= (in[26] - base) << 18; + w5 |= (in[27] - base) << 31; + w5 |= (in[28] - base) << 44; + w5 |= (in[29] - base) << 57; + w6 = (in[29] - base) >> 7; + w6 |= (in[30] - base) << 6; + w6 |= (in[31] - base) << 19; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 52; /* we used up 52 output bytes */ +} + + +/* we are going to pack 32 14-bit values, touching 7 64-bit words, using 56 bytes */ +static void packforblock14_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 7 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 14; + w0 |= (in[2] - base) << 28; + w0 |= (in[3] - base) << 42; + w0 |= (in[4] - base) << 56; + w1 = (in[4] - base) >> 8; + w1 |= (in[5] - base) << 6; + w1 |= (in[6] - base) << 20; + w1 |= (in[7] - base) << 34; + w1 |= (in[8] - base) << 48; + w1 |= (in[9] - base) << 62; + w2 = (in[9] - base) >> 2; + w2 |= (in[10] - base) << 12; + w2 |= (in[11] - base) << 26; + w2 |= (in[12] - base) << 40; + w2 |= (in[13] - base) << 54; + w3 = (in[13] - base) >> 10; + w3 |= (in[14] - base) << 4; + w3 |= (in[15] - base) << 18; + w3 |= (in[16] - base) << 32; + w3 |= (in[17] - base) << 46; + w3 |= (in[18] - base) << 60; + w4 = (in[18] - base) >> 4; + w4 |= (in[19] - base) << 10; + w4 |= (in[20] - base) << 24; + w4 |= (in[21] - base) << 38; + w4 |= (in[22] - base) << 52; + w5 = (in[22] - base) >> 12; + w5 |= (in[23] - base) << 2; + w5 |= (in[24] - base) << 16; + w5 |= (in[25] - base) << 30; + w5 |= (in[26] - base) << 44; + w5 |= (in[27] - base) << 58; + w6 = (in[27] - base) >> 6; + w6 |= (in[28] - base) << 8; + w6 |= (in[29] - base) << 22; + w6 |= (in[30] - base) << 36; + w6 |= (in[31] - base) << 50; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 56; /* we used up 56 output bytes */ +} + + +/* we are going to pack 32 15-bit values, touching 8 64-bit words, using 60 bytes */ +static void packforblock15_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 8 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 15; + w0 |= (in[2] - base) << 30; + w0 |= (in[3] - base) << 45; + w0 |= (in[4] - base) << 60; + w1 = (in[4] - base) >> 4; + w1 |= (in[5] - base) << 11; + w1 |= (in[6] - base) << 26; + w1 |= (in[7] - base) << 41; + w1 |= (in[8] - base) << 56; + w2 = (in[8] - base) >> 8; + w2 |= (in[9] - base) << 7; + w2 |= (in[10] - base) << 22; + w2 |= (in[11] - base) << 37; + w2 |= (in[12] - base) << 52; + w3 = (in[12] - base) >> 12; + w3 |= (in[13] - base) << 3; + w3 |= (in[14] - base) << 18; + w3 |= (in[15] - base) << 33; + w3 |= (in[16] - base) << 48; + w3 |= (in[17] - base) << 63; + w4 = (in[17] - base) >> 1; + w4 |= (in[18] - base) << 14; + w4 |= (in[19] - base) << 29; + w4 |= (in[20] - base) << 44; + w4 |= (in[21] - base) << 59; + w5 = (in[21] - base) >> 5; + w5 |= (in[22] - base) << 10; + w5 |= (in[23] - base) << 25; + w5 |= (in[24] - base) << 40; + w5 |= (in[25] - base) << 55; + w6 = (in[25] - base) >> 9; + w6 |= (in[26] - base) << 6; + w6 |= (in[27] - base) << 21; + w6 |= (in[28] - base) << 36; + w6 |= (in[29] - base) << 51; + w7 = (in[29] - base) >> 13; + w7 |= (in[30] - base) << 2; + w7 |= (in[31] - base) << 17; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 60; /* we used up 60 output bytes */ +} + + +/* we are going to pack 32 16-bit values, touching 8 64-bit words, using 64 bytes */ +static void packforblock16_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 8 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 16; + w0 |= (in[2] - base) << 32; + w0 |= (in[3] - base) << 48; + w1 = (in[4] - base); + w1 |= (in[5] - base) << 16; + w1 |= (in[6] - base) << 32; + w1 |= (in[7] - base) << 48; + w2 = (in[8] - base); + w2 |= (in[9] - base) << 16; + w2 |= (in[10] - base) << 32; + w2 |= (in[11] - base) << 48; + w3 = (in[12] - base); + w3 |= (in[13] - base) << 16; + w3 |= (in[14] - base) << 32; + w3 |= (in[15] - base) << 48; + w4 = (in[16] - base); + w4 |= (in[17] - base) << 16; + w4 |= (in[18] - base) << 32; + w4 |= (in[19] - base) << 48; + w5 = (in[20] - base); + w5 |= (in[21] - base) << 16; + w5 |= (in[22] - base) << 32; + w5 |= (in[23] - base) << 48; + w6 = (in[24] - base); + w6 |= (in[25] - base) << 16; + w6 |= (in[26] - base) << 32; + w6 |= (in[27] - base) << 48; + w7 = (in[28] - base); + w7 |= (in[29] - base) << 16; + w7 |= (in[30] - base) << 32; + w7 |= (in[31] - base) << 48; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 64; /* we used up 64 output bytes */ +} + + +/* we are going to pack 32 17-bit values, touching 9 64-bit words, using 68 bytes */ +static void packforblock17_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 9 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 17; + w0 |= (in[2] - base) << 34; + w0 |= (in[3] - base) << 51; + w1 = (in[3] - base) >> 13; + w1 |= (in[4] - base) << 4; + w1 |= (in[5] - base) << 21; + w1 |= (in[6] - base) << 38; + w1 |= (in[7] - base) << 55; + w2 = (in[7] - base) >> 9; + w2 |= (in[8] - base) << 8; + w2 |= (in[9] - base) << 25; + w2 |= (in[10] - base) << 42; + w2 |= (in[11] - base) << 59; + w3 = (in[11] - base) >> 5; + w3 |= (in[12] - base) << 12; + w3 |= (in[13] - base) << 29; + w3 |= (in[14] - base) << 46; + w3 |= (in[15] - base) << 63; + w4 = (in[15] - base) >> 1; + w4 |= (in[16] - base) << 16; + w4 |= (in[17] - base) << 33; + w4 |= (in[18] - base) << 50; + w5 = (in[18] - base) >> 14; + w5 |= (in[19] - base) << 3; + w5 |= (in[20] - base) << 20; + w5 |= (in[21] - base) << 37; + w5 |= (in[22] - base) << 54; + w6 = (in[22] - base) >> 10; + w6 |= (in[23] - base) << 7; + w6 |= (in[24] - base) << 24; + w6 |= (in[25] - base) << 41; + w6 |= (in[26] - base) << 58; + w7 = (in[26] - base) >> 6; + w7 |= (in[27] - base) << 11; + w7 |= (in[28] - base) << 28; + w7 |= (in[29] - base) << 45; + w7 |= (in[30] - base) << 62; + w8 = (in[30] - base) >> 2; + w8 |= (in[31] - base) << 15; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 68; /* we used up 68 output bytes */ +} + + +/* we are going to pack 32 18-bit values, touching 9 64-bit words, using 72 bytes */ +static void packforblock18_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 9 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 18; + w0 |= (in[2] - base) << 36; + w0 |= (in[3] - base) << 54; + w1 = (in[3] - base) >> 10; + w1 |= (in[4] - base) << 8; + w1 |= (in[5] - base) << 26; + w1 |= (in[6] - base) << 44; + w1 |= (in[7] - base) << 62; + w2 = (in[7] - base) >> 2; + w2 |= (in[8] - base) << 16; + w2 |= (in[9] - base) << 34; + w2 |= (in[10] - base) << 52; + w3 = (in[10] - base) >> 12; + w3 |= (in[11] - base) << 6; + w3 |= (in[12] - base) << 24; + w3 |= (in[13] - base) << 42; + w3 |= (in[14] - base) << 60; + w4 = (in[14] - base) >> 4; + w4 |= (in[15] - base) << 14; + w4 |= (in[16] - base) << 32; + w4 |= (in[17] - base) << 50; + w5 = (in[17] - base) >> 14; + w5 |= (in[18] - base) << 4; + w5 |= (in[19] - base) << 22; + w5 |= (in[20] - base) << 40; + w5 |= (in[21] - base) << 58; + w6 = (in[21] - base) >> 6; + w6 |= (in[22] - base) << 12; + w6 |= (in[23] - base) << 30; + w6 |= (in[24] - base) << 48; + w7 = (in[24] - base) >> 16; + w7 |= (in[25] - base) << 2; + w7 |= (in[26] - base) << 20; + w7 |= (in[27] - base) << 38; + w7 |= (in[28] - base) << 56; + w8 = (in[28] - base) >> 8; + w8 |= (in[29] - base) << 10; + w8 |= (in[30] - base) << 28; + w8 |= (in[31] - base) << 46; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 72; /* we used up 72 output bytes */ +} + + +/* we are going to pack 32 19-bit values, touching 10 64-bit words, using 76 bytes */ +static void packforblock19_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 10 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 19; + w0 |= (in[2] - base) << 38; + w0 |= (in[3] - base) << 57; + w1 = (in[3] - base) >> 7; + w1 |= (in[4] - base) << 12; + w1 |= (in[5] - base) << 31; + w1 |= (in[6] - base) << 50; + w2 = (in[6] - base) >> 14; + w2 |= (in[7] - base) << 5; + w2 |= (in[8] - base) << 24; + w2 |= (in[9] - base) << 43; + w2 |= (in[10] - base) << 62; + w3 = (in[10] - base) >> 2; + w3 |= (in[11] - base) << 17; + w3 |= (in[12] - base) << 36; + w3 |= (in[13] - base) << 55; + w4 = (in[13] - base) >> 9; + w4 |= (in[14] - base) << 10; + w4 |= (in[15] - base) << 29; + w4 |= (in[16] - base) << 48; + w5 = (in[16] - base) >> 16; + w5 |= (in[17] - base) << 3; + w5 |= (in[18] - base) << 22; + w5 |= (in[19] - base) << 41; + w5 |= (in[20] - base) << 60; + w6 = (in[20] - base) >> 4; + w6 |= (in[21] - base) << 15; + w6 |= (in[22] - base) << 34; + w6 |= (in[23] - base) << 53; + w7 = (in[23] - base) >> 11; + w7 |= (in[24] - base) << 8; + w7 |= (in[25] - base) << 27; + w7 |= (in[26] - base) << 46; + w8 = (in[26] - base) >> 18; + w8 |= (in[27] - base) << 1; + w8 |= (in[28] - base) << 20; + w8 |= (in[29] - base) << 39; + w8 |= (in[30] - base) << 58; + w9 = (in[30] - base) >> 6; + w9 |= (in[31] - base) << 13; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 76; /* we used up 76 output bytes */ +} + + +/* we are going to pack 32 20-bit values, touching 10 64-bit words, using 80 bytes */ +static void packforblock20_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 10 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 20; + w0 |= (in[2] - base) << 40; + w0 |= (in[3] - base) << 60; + w1 = (in[3] - base) >> 4; + w1 |= (in[4] - base) << 16; + w1 |= (in[5] - base) << 36; + w1 |= (in[6] - base) << 56; + w2 = (in[6] - base) >> 8; + w2 |= (in[7] - base) << 12; + w2 |= (in[8] - base) << 32; + w2 |= (in[9] - base) << 52; + w3 = (in[9] - base) >> 12; + w3 |= (in[10] - base) << 8; + w3 |= (in[11] - base) << 28; + w3 |= (in[12] - base) << 48; + w4 = (in[12] - base) >> 16; + w4 |= (in[13] - base) << 4; + w4 |= (in[14] - base) << 24; + w4 |= (in[15] - base) << 44; + w5 = (in[16] - base); + w5 |= (in[17] - base) << 20; + w5 |= (in[18] - base) << 40; + w5 |= (in[19] - base) << 60; + w6 = (in[19] - base) >> 4; + w6 |= (in[20] - base) << 16; + w6 |= (in[21] - base) << 36; + w6 |= (in[22] - base) << 56; + w7 = (in[22] - base) >> 8; + w7 |= (in[23] - base) << 12; + w7 |= (in[24] - base) << 32; + w7 |= (in[25] - base) << 52; + w8 = (in[25] - base) >> 12; + w8 |= (in[26] - base) << 8; + w8 |= (in[27] - base) << 28; + w8 |= (in[28] - base) << 48; + w9 = (in[28] - base) >> 16; + w9 |= (in[29] - base) << 4; + w9 |= (in[30] - base) << 24; + w9 |= (in[31] - base) << 44; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 80; /* we used up 80 output bytes */ +} + + +/* we are going to pack 32 21-bit values, touching 11 64-bit words, using 84 bytes */ +static void packforblock21_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 11 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 21; + w0 |= (in[2] - base) << 42; + w0 |= (in[3] - base) << 63; + w1 = (in[3] - base) >> 1; + w1 |= (in[4] - base) << 20; + w1 |= (in[5] - base) << 41; + w1 |= (in[6] - base) << 62; + w2 = (in[6] - base) >> 2; + w2 |= (in[7] - base) << 19; + w2 |= (in[8] - base) << 40; + w2 |= (in[9] - base) << 61; + w3 = (in[9] - base) >> 3; + w3 |= (in[10] - base) << 18; + w3 |= (in[11] - base) << 39; + w3 |= (in[12] - base) << 60; + w4 = (in[12] - base) >> 4; + w4 |= (in[13] - base) << 17; + w4 |= (in[14] - base) << 38; + w4 |= (in[15] - base) << 59; + w5 = (in[15] - base) >> 5; + w5 |= (in[16] - base) << 16; + w5 |= (in[17] - base) << 37; + w5 |= (in[18] - base) << 58; + w6 = (in[18] - base) >> 6; + w6 |= (in[19] - base) << 15; + w6 |= (in[20] - base) << 36; + w6 |= (in[21] - base) << 57; + w7 = (in[21] - base) >> 7; + w7 |= (in[22] - base) << 14; + w7 |= (in[23] - base) << 35; + w7 |= (in[24] - base) << 56; + w8 = (in[24] - base) >> 8; + w8 |= (in[25] - base) << 13; + w8 |= (in[26] - base) << 34; + w8 |= (in[27] - base) << 55; + w9 = (in[27] - base) >> 9; + w9 |= (in[28] - base) << 12; + w9 |= (in[29] - base) << 33; + w9 |= (in[30] - base) << 54; + w10 = (in[30] - base) >> 10; + w10 |= (in[31] - base) << 11; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 84; /* we used up 84 output bytes */ +} + + +/* we are going to pack 32 22-bit values, touching 11 64-bit words, using 88 bytes */ +static void packforblock22_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 11 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 22; + w0 |= (in[2] - base) << 44; + w1 = (in[2] - base) >> 20; + w1 |= (in[3] - base) << 2; + w1 |= (in[4] - base) << 24; + w1 |= (in[5] - base) << 46; + w2 = (in[5] - base) >> 18; + w2 |= (in[6] - base) << 4; + w2 |= (in[7] - base) << 26; + w2 |= (in[8] - base) << 48; + w3 = (in[8] - base) >> 16; + w3 |= (in[9] - base) << 6; + w3 |= (in[10] - base) << 28; + w3 |= (in[11] - base) << 50; + w4 = (in[11] - base) >> 14; + w4 |= (in[12] - base) << 8; + w4 |= (in[13] - base) << 30; + w4 |= (in[14] - base) << 52; + w5 = (in[14] - base) >> 12; + w5 |= (in[15] - base) << 10; + w5 |= (in[16] - base) << 32; + w5 |= (in[17] - base) << 54; + w6 = (in[17] - base) >> 10; + w6 |= (in[18] - base) << 12; + w6 |= (in[19] - base) << 34; + w6 |= (in[20] - base) << 56; + w7 = (in[20] - base) >> 8; + w7 |= (in[21] - base) << 14; + w7 |= (in[22] - base) << 36; + w7 |= (in[23] - base) << 58; + w8 = (in[23] - base) >> 6; + w8 |= (in[24] - base) << 16; + w8 |= (in[25] - base) << 38; + w8 |= (in[26] - base) << 60; + w9 = (in[26] - base) >> 4; + w9 |= (in[27] - base) << 18; + w9 |= (in[28] - base) << 40; + w9 |= (in[29] - base) << 62; + w10 = (in[29] - base) >> 2; + w10 |= (in[30] - base) << 20; + w10 |= (in[31] - base) << 42; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 88; /* we used up 88 output bytes */ +} + + +/* we are going to pack 32 23-bit values, touching 12 64-bit words, using 92 bytes */ +static void packforblock23_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 12 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 23; + w0 |= (in[2] - base) << 46; + w1 = (in[2] - base) >> 18; + w1 |= (in[3] - base) << 5; + w1 |= (in[4] - base) << 28; + w1 |= (in[5] - base) << 51; + w2 = (in[5] - base) >> 13; + w2 |= (in[6] - base) << 10; + w2 |= (in[7] - base) << 33; + w2 |= (in[8] - base) << 56; + w3 = (in[8] - base) >> 8; + w3 |= (in[9] - base) << 15; + w3 |= (in[10] - base) << 38; + w3 |= (in[11] - base) << 61; + w4 = (in[11] - base) >> 3; + w4 |= (in[12] - base) << 20; + w4 |= (in[13] - base) << 43; + w5 = (in[13] - base) >> 21; + w5 |= (in[14] - base) << 2; + w5 |= (in[15] - base) << 25; + w5 |= (in[16] - base) << 48; + w6 = (in[16] - base) >> 16; + w6 |= (in[17] - base) << 7; + w6 |= (in[18] - base) << 30; + w6 |= (in[19] - base) << 53; + w7 = (in[19] - base) >> 11; + w7 |= (in[20] - base) << 12; + w7 |= (in[21] - base) << 35; + w7 |= (in[22] - base) << 58; + w8 = (in[22] - base) >> 6; + w8 |= (in[23] - base) << 17; + w8 |= (in[24] - base) << 40; + w8 |= (in[25] - base) << 63; + w9 = (in[25] - base) >> 1; + w9 |= (in[26] - base) << 22; + w9 |= (in[27] - base) << 45; + w10 = (in[27] - base) >> 19; + w10 |= (in[28] - base) << 4; + w10 |= (in[29] - base) << 27; + w10 |= (in[30] - base) << 50; + w11 = (in[30] - base) >> 14; + w11 |= (in[31] - base) << 9; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 92; /* we used up 92 output bytes */ +} + + +/* we are going to pack 32 24-bit values, touching 12 64-bit words, using 96 bytes */ +static void packforblock24_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 12 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 24; + w0 |= (in[2] - base) << 48; + w1 = (in[2] - base) >> 16; + w1 |= (in[3] - base) << 8; + w1 |= (in[4] - base) << 32; + w1 |= (in[5] - base) << 56; + w2 = (in[5] - base) >> 8; + w2 |= (in[6] - base) << 16; + w2 |= (in[7] - base) << 40; + w3 = (in[8] - base); + w3 |= (in[9] - base) << 24; + w3 |= (in[10] - base) << 48; + w4 = (in[10] - base) >> 16; + w4 |= (in[11] - base) << 8; + w4 |= (in[12] - base) << 32; + w4 |= (in[13] - base) << 56; + w5 = (in[13] - base) >> 8; + w5 |= (in[14] - base) << 16; + w5 |= (in[15] - base) << 40; + w6 = (in[16] - base); + w6 |= (in[17] - base) << 24; + w6 |= (in[18] - base) << 48; + w7 = (in[18] - base) >> 16; + w7 |= (in[19] - base) << 8; + w7 |= (in[20] - base) << 32; + w7 |= (in[21] - base) << 56; + w8 = (in[21] - base) >> 8; + w8 |= (in[22] - base) << 16; + w8 |= (in[23] - base) << 40; + w9 = (in[24] - base); + w9 |= (in[25] - base) << 24; + w9 |= (in[26] - base) << 48; + w10 = (in[26] - base) >> 16; + w10 |= (in[27] - base) << 8; + w10 |= (in[28] - base) << 32; + w10 |= (in[29] - base) << 56; + w11 = (in[29] - base) >> 8; + w11 |= (in[30] - base) << 16; + w11 |= (in[31] - base) << 40; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 96; /* we used up 96 output bytes */ +} + + +/* we are going to pack 32 25-bit values, touching 13 64-bit words, using 100 bytes */ +static void packforblock25_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 13 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 25; + w0 |= (in[2] - base) << 50; + w1 = (in[2] - base) >> 14; + w1 |= (in[3] - base) << 11; + w1 |= (in[4] - base) << 36; + w1 |= (in[5] - base) << 61; + w2 = (in[5] - base) >> 3; + w2 |= (in[6] - base) << 22; + w2 |= (in[7] - base) << 47; + w3 = (in[7] - base) >> 17; + w3 |= (in[8] - base) << 8; + w3 |= (in[9] - base) << 33; + w3 |= (in[10] - base) << 58; + w4 = (in[10] - base) >> 6; + w4 |= (in[11] - base) << 19; + w4 |= (in[12] - base) << 44; + w5 = (in[12] - base) >> 20; + w5 |= (in[13] - base) << 5; + w5 |= (in[14] - base) << 30; + w5 |= (in[15] - base) << 55; + w6 = (in[15] - base) >> 9; + w6 |= (in[16] - base) << 16; + w6 |= (in[17] - base) << 41; + w7 = (in[17] - base) >> 23; + w7 |= (in[18] - base) << 2; + w7 |= (in[19] - base) << 27; + w7 |= (in[20] - base) << 52; + w8 = (in[20] - base) >> 12; + w8 |= (in[21] - base) << 13; + w8 |= (in[22] - base) << 38; + w8 |= (in[23] - base) << 63; + w9 = (in[23] - base) >> 1; + w9 |= (in[24] - base) << 24; + w9 |= (in[25] - base) << 49; + w10 = (in[25] - base) >> 15; + w10 |= (in[26] - base) << 10; + w10 |= (in[27] - base) << 35; + w10 |= (in[28] - base) << 60; + w11 = (in[28] - base) >> 4; + w11 |= (in[29] - base) << 21; + w11 |= (in[30] - base) << 46; + w12 = (in[30] - base) >> 18; + w12 |= (in[31] - base) << 7; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 100; /* we used up 100 output bytes */ +} + + +/* we are going to pack 32 26-bit values, touching 13 64-bit words, using 104 bytes */ +static void packforblock26_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 13 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 26; + w0 |= (in[2] - base) << 52; + w1 = (in[2] - base) >> 12; + w1 |= (in[3] - base) << 14; + w1 |= (in[4] - base) << 40; + w2 = (in[4] - base) >> 24; + w2 |= (in[5] - base) << 2; + w2 |= (in[6] - base) << 28; + w2 |= (in[7] - base) << 54; + w3 = (in[7] - base) >> 10; + w3 |= (in[8] - base) << 16; + w3 |= (in[9] - base) << 42; + w4 = (in[9] - base) >> 22; + w4 |= (in[10] - base) << 4; + w4 |= (in[11] - base) << 30; + w4 |= (in[12] - base) << 56; + w5 = (in[12] - base) >> 8; + w5 |= (in[13] - base) << 18; + w5 |= (in[14] - base) << 44; + w6 = (in[14] - base) >> 20; + w6 |= (in[15] - base) << 6; + w6 |= (in[16] - base) << 32; + w6 |= (in[17] - base) << 58; + w7 = (in[17] - base) >> 6; + w7 |= (in[18] - base) << 20; + w7 |= (in[19] - base) << 46; + w8 = (in[19] - base) >> 18; + w8 |= (in[20] - base) << 8; + w8 |= (in[21] - base) << 34; + w8 |= (in[22] - base) << 60; + w9 = (in[22] - base) >> 4; + w9 |= (in[23] - base) << 22; + w9 |= (in[24] - base) << 48; + w10 = (in[24] - base) >> 16; + w10 |= (in[25] - base) << 10; + w10 |= (in[26] - base) << 36; + w10 |= (in[27] - base) << 62; + w11 = (in[27] - base) >> 2; + w11 |= (in[28] - base) << 24; + w11 |= (in[29] - base) << 50; + w12 = (in[29] - base) >> 14; + w12 |= (in[30] - base) << 12; + w12 |= (in[31] - base) << 38; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 104; /* we used up 104 output bytes */ +} + + +/* we are going to pack 32 27-bit values, touching 14 64-bit words, using 108 bytes */ +static void packforblock27_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 14 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 27; + w0 |= (in[2] - base) << 54; + w1 = (in[2] - base) >> 10; + w1 |= (in[3] - base) << 17; + w1 |= (in[4] - base) << 44; + w2 = (in[4] - base) >> 20; + w2 |= (in[5] - base) << 7; + w2 |= (in[6] - base) << 34; + w2 |= (in[7] - base) << 61; + w3 = (in[7] - base) >> 3; + w3 |= (in[8] - base) << 24; + w3 |= (in[9] - base) << 51; + w4 = (in[9] - base) >> 13; + w4 |= (in[10] - base) << 14; + w4 |= (in[11] - base) << 41; + w5 = (in[11] - base) >> 23; + w5 |= (in[12] - base) << 4; + w5 |= (in[13] - base) << 31; + w5 |= (in[14] - base) << 58; + w6 = (in[14] - base) >> 6; + w6 |= (in[15] - base) << 21; + w6 |= (in[16] - base) << 48; + w7 = (in[16] - base) >> 16; + w7 |= (in[17] - base) << 11; + w7 |= (in[18] - base) << 38; + w8 = (in[18] - base) >> 26; + w8 |= (in[19] - base) << 1; + w8 |= (in[20] - base) << 28; + w8 |= (in[21] - base) << 55; + w9 = (in[21] - base) >> 9; + w9 |= (in[22] - base) << 18; + w9 |= (in[23] - base) << 45; + w10 = (in[23] - base) >> 19; + w10 |= (in[24] - base) << 8; + w10 |= (in[25] - base) << 35; + w10 |= (in[26] - base) << 62; + w11 = (in[26] - base) >> 2; + w11 |= (in[27] - base) << 25; + w11 |= (in[28] - base) << 52; + w12 = (in[28] - base) >> 12; + w12 |= (in[29] - base) << 15; + w12 |= (in[30] - base) << 42; + w13 = (in[30] - base) >> 22; + w13 |= (in[31] - base) << 5; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 108; /* we used up 108 output bytes */ +} + + +/* we are going to pack 32 28-bit values, touching 14 64-bit words, using 112 bytes */ +static void packforblock28_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 14 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 28; + w0 |= (in[2] - base) << 56; + w1 = (in[2] - base) >> 8; + w1 |= (in[3] - base) << 20; + w1 |= (in[4] - base) << 48; + w2 = (in[4] - base) >> 16; + w2 |= (in[5] - base) << 12; + w2 |= (in[6] - base) << 40; + w3 = (in[6] - base) >> 24; + w3 |= (in[7] - base) << 4; + w3 |= (in[8] - base) << 32; + w3 |= (in[9] - base) << 60; + w4 = (in[9] - base) >> 4; + w4 |= (in[10] - base) << 24; + w4 |= (in[11] - base) << 52; + w5 = (in[11] - base) >> 12; + w5 |= (in[12] - base) << 16; + w5 |= (in[13] - base) << 44; + w6 = (in[13] - base) >> 20; + w6 |= (in[14] - base) << 8; + w6 |= (in[15] - base) << 36; + w7 = (in[16] - base); + w7 |= (in[17] - base) << 28; + w7 |= (in[18] - base) << 56; + w8 = (in[18] - base) >> 8; + w8 |= (in[19] - base) << 20; + w8 |= (in[20] - base) << 48; + w9 = (in[20] - base) >> 16; + w9 |= (in[21] - base) << 12; + w9 |= (in[22] - base) << 40; + w10 = (in[22] - base) >> 24; + w10 |= (in[23] - base) << 4; + w10 |= (in[24] - base) << 32; + w10 |= (in[25] - base) << 60; + w11 = (in[25] - base) >> 4; + w11 |= (in[26] - base) << 24; + w11 |= (in[27] - base) << 52; + w12 = (in[27] - base) >> 12; + w12 |= (in[28] - base) << 16; + w12 |= (in[29] - base) << 44; + w13 = (in[29] - base) >> 20; + w13 |= (in[30] - base) << 8; + w13 |= (in[31] - base) << 36; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 112; /* we used up 112 output bytes */ +} + + +/* we are going to pack 32 29-bit values, touching 15 64-bit words, using 116 bytes */ +static void packforblock29_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 15 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 29; + w0 |= (in[2] - base) << 58; + w1 = (in[2] - base) >> 6; + w1 |= (in[3] - base) << 23; + w1 |= (in[4] - base) << 52; + w2 = (in[4] - base) >> 12; + w2 |= (in[5] - base) << 17; + w2 |= (in[6] - base) << 46; + w3 = (in[6] - base) >> 18; + w3 |= (in[7] - base) << 11; + w3 |= (in[8] - base) << 40; + w4 = (in[8] - base) >> 24; + w4 |= (in[9] - base) << 5; + w4 |= (in[10] - base) << 34; + w4 |= (in[11] - base) << 63; + w5 = (in[11] - base) >> 1; + w5 |= (in[12] - base) << 28; + w5 |= (in[13] - base) << 57; + w6 = (in[13] - base) >> 7; + w6 |= (in[14] - base) << 22; + w6 |= (in[15] - base) << 51; + w7 = (in[15] - base) >> 13; + w7 |= (in[16] - base) << 16; + w7 |= (in[17] - base) << 45; + w8 = (in[17] - base) >> 19; + w8 |= (in[18] - base) << 10; + w8 |= (in[19] - base) << 39; + w9 = (in[19] - base) >> 25; + w9 |= (in[20] - base) << 4; + w9 |= (in[21] - base) << 33; + w9 |= (in[22] - base) << 62; + w10 = (in[22] - base) >> 2; + w10 |= (in[23] - base) << 27; + w10 |= (in[24] - base) << 56; + w11 = (in[24] - base) >> 8; + w11 |= (in[25] - base) << 21; + w11 |= (in[26] - base) << 50; + w12 = (in[26] - base) >> 14; + w12 |= (in[27] - base) << 15; + w12 |= (in[28] - base) << 44; + w13 = (in[28] - base) >> 20; + w13 |= (in[29] - base) << 9; + w13 |= (in[30] - base) << 38; + w14 = (in[30] - base) >> 26; + w14 |= (in[31] - base) << 3; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 116; /* we used up 116 output bytes */ +} + + +/* we are going to pack 32 30-bit values, touching 15 64-bit words, using 120 bytes */ +static void packforblock30_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 15 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 30; + w0 |= (in[2] - base) << 60; + w1 = (in[2] - base) >> 4; + w1 |= (in[3] - base) << 26; + w1 |= (in[4] - base) << 56; + w2 = (in[4] - base) >> 8; + w2 |= (in[5] - base) << 22; + w2 |= (in[6] - base) << 52; + w3 = (in[6] - base) >> 12; + w3 |= (in[7] - base) << 18; + w3 |= (in[8] - base) << 48; + w4 = (in[8] - base) >> 16; + w4 |= (in[9] - base) << 14; + w4 |= (in[10] - base) << 44; + w5 = (in[10] - base) >> 20; + w5 |= (in[11] - base) << 10; + w5 |= (in[12] - base) << 40; + w6 = (in[12] - base) >> 24; + w6 |= (in[13] - base) << 6; + w6 |= (in[14] - base) << 36; + w7 = (in[14] - base) >> 28; + w7 |= (in[15] - base) << 2; + w7 |= (in[16] - base) << 32; + w7 |= (in[17] - base) << 62; + w8 = (in[17] - base) >> 2; + w8 |= (in[18] - base) << 28; + w8 |= (in[19] - base) << 58; + w9 = (in[19] - base) >> 6; + w9 |= (in[20] - base) << 24; + w9 |= (in[21] - base) << 54; + w10 = (in[21] - base) >> 10; + w10 |= (in[22] - base) << 20; + w10 |= (in[23] - base) << 50; + w11 = (in[23] - base) >> 14; + w11 |= (in[24] - base) << 16; + w11 |= (in[25] - base) << 46; + w12 = (in[25] - base) >> 18; + w12 |= (in[26] - base) << 12; + w12 |= (in[27] - base) << 42; + w13 = (in[27] - base) >> 22; + w13 |= (in[28] - base) << 8; + w13 |= (in[29] - base) << 38; + w14 = (in[29] - base) >> 26; + w14 |= (in[30] - base) << 4; + w14 |= (in[31] - base) << 34; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 120; /* we used up 120 output bytes */ +} + + +/* we are going to pack 32 31-bit values, touching 16 64-bit words, using 124 bytes */ +static void packforblock31_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 16 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 31; + w0 |= (in[2] - base) << 62; + w1 = (in[2] - base) >> 2; + w1 |= (in[3] - base) << 29; + w1 |= (in[4] - base) << 60; + w2 = (in[4] - base) >> 4; + w2 |= (in[5] - base) << 27; + w2 |= (in[6] - base) << 58; + w3 = (in[6] - base) >> 6; + w3 |= (in[7] - base) << 25; + w3 |= (in[8] - base) << 56; + w4 = (in[8] - base) >> 8; + w4 |= (in[9] - base) << 23; + w4 |= (in[10] - base) << 54; + w5 = (in[10] - base) >> 10; + w5 |= (in[11] - base) << 21; + w5 |= (in[12] - base) << 52; + w6 = (in[12] - base) >> 12; + w6 |= (in[13] - base) << 19; + w6 |= (in[14] - base) << 50; + w7 = (in[14] - base) >> 14; + w7 |= (in[15] - base) << 17; + w7 |= (in[16] - base) << 48; + w8 = (in[16] - base) >> 16; + w8 |= (in[17] - base) << 15; + w8 |= (in[18] - base) << 46; + w9 = (in[18] - base) >> 18; + w9 |= (in[19] - base) << 13; + w9 |= (in[20] - base) << 44; + w10 = (in[20] - base) >> 20; + w10 |= (in[21] - base) << 11; + w10 |= (in[22] - base) << 42; + w11 = (in[22] - base) >> 22; + w11 |= (in[23] - base) << 9; + w11 |= (in[24] - base) << 40; + w12 = (in[24] - base) >> 24; + w12 |= (in[25] - base) << 7; + w12 |= (in[26] - base) << 38; + w13 = (in[26] - base) >> 26; + w13 |= (in[27] - base) << 5; + w13 |= (in[28] - base) << 36; + w14 = (in[28] - base) >> 28; + w14 |= (in[29] - base) << 3; + w14 |= (in[30] - base) << 34; + w15 = (in[30] - base) >> 30; + w15 |= (in[31] - base) << 1; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 124; /* we used up 124 output bytes */ +} + + +/* we are going to pack 32 32-bit values, touching 16 64-bit words, using 128 bytes */ +static void packforblock32_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 16 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 32; + w1 = (in[2] - base); + w1 |= (in[3] - base) << 32; + w2 = (in[4] - base); + w2 |= (in[5] - base) << 32; + w3 = (in[6] - base); + w3 |= (in[7] - base) << 32; + w4 = (in[8] - base); + w4 |= (in[9] - base) << 32; + w5 = (in[10] - base); + w5 |= (in[11] - base) << 32; + w6 = (in[12] - base); + w6 |= (in[13] - base) << 32; + w7 = (in[14] - base); + w7 |= (in[15] - base) << 32; + w8 = (in[16] - base); + w8 |= (in[17] - base) << 32; + w9 = (in[18] - base); + w9 |= (in[19] - base) << 32; + w10 = (in[20] - base); + w10 |= (in[21] - base) << 32; + w11 = (in[22] - base); + w11 |= (in[23] - base) << 32; + w12 = (in[24] - base); + w12 |= (in[25] - base) << 32; + w13 = (in[26] - base); + w13 |= (in[27] - base) << 32; + w14 = (in[28] - base); + w14 |= (in[29] - base) << 32; + w15 = (in[30] - base); + w15 |= (in[31] - base) << 32; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 128; /* we used up 128 output bytes */ +} + + +/* we are going to pack 32 33-bit values, touching 17 64-bit words, using 132 bytes */ +static void packforblock33_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 17 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 33; + w1 = (in[1] - base) >> 31; + w1 |= (in[2] - base) << 2; + w1 |= (in[3] - base) << 35; + w2 = (in[3] - base) >> 29; + w2 |= (in[4] - base) << 4; + w2 |= (in[5] - base) << 37; + w3 = (in[5] - base) >> 27; + w3 |= (in[6] - base) << 6; + w3 |= (in[7] - base) << 39; + w4 = (in[7] - base) >> 25; + w4 |= (in[8] - base) << 8; + w4 |= (in[9] - base) << 41; + w5 = (in[9] - base) >> 23; + w5 |= (in[10] - base) << 10; + w5 |= (in[11] - base) << 43; + w6 = (in[11] - base) >> 21; + w6 |= (in[12] - base) << 12; + w6 |= (in[13] - base) << 45; + w7 = (in[13] - base) >> 19; + w7 |= (in[14] - base) << 14; + w7 |= (in[15] - base) << 47; + w8 = (in[15] - base) >> 17; + w8 |= (in[16] - base) << 16; + w8 |= (in[17] - base) << 49; + w9 = (in[17] - base) >> 15; + w9 |= (in[18] - base) << 18; + w9 |= (in[19] - base) << 51; + w10 = (in[19] - base) >> 13; + w10 |= (in[20] - base) << 20; + w10 |= (in[21] - base) << 53; + w11 = (in[21] - base) >> 11; + w11 |= (in[22] - base) << 22; + w11 |= (in[23] - base) << 55; + w12 = (in[23] - base) >> 9; + w12 |= (in[24] - base) << 24; + w12 |= (in[25] - base) << 57; + w13 = (in[25] - base) >> 7; + w13 |= (in[26] - base) << 26; + w13 |= (in[27] - base) << 59; + w14 = (in[27] - base) >> 5; + w14 |= (in[28] - base) << 28; + w14 |= (in[29] - base) << 61; + w15 = (in[29] - base) >> 3; + w15 |= (in[30] - base) << 30; + w15 |= (in[31] - base) << 63; + w16 = (in[31] - base) >> 1; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 132; /* we used up 132 output bytes */ +} + + +/* we are going to pack 32 34-bit values, touching 17 64-bit words, using 136 bytes */ +static void packforblock34_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 17 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 34; + w1 = (in[1] - base) >> 30; + w1 |= (in[2] - base) << 4; + w1 |= (in[3] - base) << 38; + w2 = (in[3] - base) >> 26; + w2 |= (in[4] - base) << 8; + w2 |= (in[5] - base) << 42; + w3 = (in[5] - base) >> 22; + w3 |= (in[6] - base) << 12; + w3 |= (in[7] - base) << 46; + w4 = (in[7] - base) >> 18; + w4 |= (in[8] - base) << 16; + w4 |= (in[9] - base) << 50; + w5 = (in[9] - base) >> 14; + w5 |= (in[10] - base) << 20; + w5 |= (in[11] - base) << 54; + w6 = (in[11] - base) >> 10; + w6 |= (in[12] - base) << 24; + w6 |= (in[13] - base) << 58; + w7 = (in[13] - base) >> 6; + w7 |= (in[14] - base) << 28; + w7 |= (in[15] - base) << 62; + w8 = (in[15] - base) >> 2; + w8 |= (in[16] - base) << 32; + w9 = (in[16] - base) >> 32; + w9 |= (in[17] - base) << 2; + w9 |= (in[18] - base) << 36; + w10 = (in[18] - base) >> 28; + w10 |= (in[19] - base) << 6; + w10 |= (in[20] - base) << 40; + w11 = (in[20] - base) >> 24; + w11 |= (in[21] - base) << 10; + w11 |= (in[22] - base) << 44; + w12 = (in[22] - base) >> 20; + w12 |= (in[23] - base) << 14; + w12 |= (in[24] - base) << 48; + w13 = (in[24] - base) >> 16; + w13 |= (in[25] - base) << 18; + w13 |= (in[26] - base) << 52; + w14 = (in[26] - base) >> 12; + w14 |= (in[27] - base) << 22; + w14 |= (in[28] - base) << 56; + w15 = (in[28] - base) >> 8; + w15 |= (in[29] - base) << 26; + w15 |= (in[30] - base) << 60; + w16 = (in[30] - base) >> 4; + w16 |= (in[31] - base) << 30; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 136; /* we used up 136 output bytes */ +} + + +/* we are going to pack 32 35-bit values, touching 18 64-bit words, using 140 bytes */ +static void packforblock35_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 18 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 35; + w1 = (in[1] - base) >> 29; + w1 |= (in[2] - base) << 6; + w1 |= (in[3] - base) << 41; + w2 = (in[3] - base) >> 23; + w2 |= (in[4] - base) << 12; + w2 |= (in[5] - base) << 47; + w3 = (in[5] - base) >> 17; + w3 |= (in[6] - base) << 18; + w3 |= (in[7] - base) << 53; + w4 = (in[7] - base) >> 11; + w4 |= (in[8] - base) << 24; + w4 |= (in[9] - base) << 59; + w5 = (in[9] - base) >> 5; + w5 |= (in[10] - base) << 30; + w6 = (in[10] - base) >> 34; + w6 |= (in[11] - base) << 1; + w6 |= (in[12] - base) << 36; + w7 = (in[12] - base) >> 28; + w7 |= (in[13] - base) << 7; + w7 |= (in[14] - base) << 42; + w8 = (in[14] - base) >> 22; + w8 |= (in[15] - base) << 13; + w8 |= (in[16] - base) << 48; + w9 = (in[16] - base) >> 16; + w9 |= (in[17] - base) << 19; + w9 |= (in[18] - base) << 54; + w10 = (in[18] - base) >> 10; + w10 |= (in[19] - base) << 25; + w10 |= (in[20] - base) << 60; + w11 = (in[20] - base) >> 4; + w11 |= (in[21] - base) << 31; + w12 = (in[21] - base) >> 33; + w12 |= (in[22] - base) << 2; + w12 |= (in[23] - base) << 37; + w13 = (in[23] - base) >> 27; + w13 |= (in[24] - base) << 8; + w13 |= (in[25] - base) << 43; + w14 = (in[25] - base) >> 21; + w14 |= (in[26] - base) << 14; + w14 |= (in[27] - base) << 49; + w15 = (in[27] - base) >> 15; + w15 |= (in[28] - base) << 20; + w15 |= (in[29] - base) << 55; + w16 = (in[29] - base) >> 9; + w16 |= (in[30] - base) << 26; + w16 |= (in[31] - base) << 61; + w17 = (in[31] - base) >> 3; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 140; /* we used up 140 output bytes */ +} + + +/* we are going to pack 32 36-bit values, touching 18 64-bit words, using 144 bytes */ +static void packforblock36_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 18 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 36; + w1 = (in[1] - base) >> 28; + w1 |= (in[2] - base) << 8; + w1 |= (in[3] - base) << 44; + w2 = (in[3] - base) >> 20; + w2 |= (in[4] - base) << 16; + w2 |= (in[5] - base) << 52; + w3 = (in[5] - base) >> 12; + w3 |= (in[6] - base) << 24; + w3 |= (in[7] - base) << 60; + w4 = (in[7] - base) >> 4; + w4 |= (in[8] - base) << 32; + w5 = (in[8] - base) >> 32; + w5 |= (in[9] - base) << 4; + w5 |= (in[10] - base) << 40; + w6 = (in[10] - base) >> 24; + w6 |= (in[11] - base) << 12; + w6 |= (in[12] - base) << 48; + w7 = (in[12] - base) >> 16; + w7 |= (in[13] - base) << 20; + w7 |= (in[14] - base) << 56; + w8 = (in[14] - base) >> 8; + w8 |= (in[15] - base) << 28; + w9 = (in[16] - base); + w9 |= (in[17] - base) << 36; + w10 = (in[17] - base) >> 28; + w10 |= (in[18] - base) << 8; + w10 |= (in[19] - base) << 44; + w11 = (in[19] - base) >> 20; + w11 |= (in[20] - base) << 16; + w11 |= (in[21] - base) << 52; + w12 = (in[21] - base) >> 12; + w12 |= (in[22] - base) << 24; + w12 |= (in[23] - base) << 60; + w13 = (in[23] - base) >> 4; + w13 |= (in[24] - base) << 32; + w14 = (in[24] - base) >> 32; + w14 |= (in[25] - base) << 4; + w14 |= (in[26] - base) << 40; + w15 = (in[26] - base) >> 24; + w15 |= (in[27] - base) << 12; + w15 |= (in[28] - base) << 48; + w16 = (in[28] - base) >> 16; + w16 |= (in[29] - base) << 20; + w16 |= (in[30] - base) << 56; + w17 = (in[30] - base) >> 8; + w17 |= (in[31] - base) << 28; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 144; /* we used up 144 output bytes */ +} + + +/* we are going to pack 32 37-bit values, touching 19 64-bit words, using 148 bytes */ +static void packforblock37_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 19 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 37; + w1 = (in[1] - base) >> 27; + w1 |= (in[2] - base) << 10; + w1 |= (in[3] - base) << 47; + w2 = (in[3] - base) >> 17; + w2 |= (in[4] - base) << 20; + w2 |= (in[5] - base) << 57; + w3 = (in[5] - base) >> 7; + w3 |= (in[6] - base) << 30; + w4 = (in[6] - base) >> 34; + w4 |= (in[7] - base) << 3; + w4 |= (in[8] - base) << 40; + w5 = (in[8] - base) >> 24; + w5 |= (in[9] - base) << 13; + w5 |= (in[10] - base) << 50; + w6 = (in[10] - base) >> 14; + w6 |= (in[11] - base) << 23; + w6 |= (in[12] - base) << 60; + w7 = (in[12] - base) >> 4; + w7 |= (in[13] - base) << 33; + w8 = (in[13] - base) >> 31; + w8 |= (in[14] - base) << 6; + w8 |= (in[15] - base) << 43; + w9 = (in[15] - base) >> 21; + w9 |= (in[16] - base) << 16; + w9 |= (in[17] - base) << 53; + w10 = (in[17] - base) >> 11; + w10 |= (in[18] - base) << 26; + w10 |= (in[19] - base) << 63; + w11 = (in[19] - base) >> 1; + w11 |= (in[20] - base) << 36; + w12 = (in[20] - base) >> 28; + w12 |= (in[21] - base) << 9; + w12 |= (in[22] - base) << 46; + w13 = (in[22] - base) >> 18; + w13 |= (in[23] - base) << 19; + w13 |= (in[24] - base) << 56; + w14 = (in[24] - base) >> 8; + w14 |= (in[25] - base) << 29; + w15 = (in[25] - base) >> 35; + w15 |= (in[26] - base) << 2; + w15 |= (in[27] - base) << 39; + w16 = (in[27] - base) >> 25; + w16 |= (in[28] - base) << 12; + w16 |= (in[29] - base) << 49; + w17 = (in[29] - base) >> 15; + w17 |= (in[30] - base) << 22; + w17 |= (in[31] - base) << 59; + w18 = (in[31] - base) >> 5; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 148; /* we used up 148 output bytes */ +} + + +/* we are going to pack 32 38-bit values, touching 19 64-bit words, using 152 bytes */ +static void packforblock38_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 19 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 38; + w1 = (in[1] - base) >> 26; + w1 |= (in[2] - base) << 12; + w1 |= (in[3] - base) << 50; + w2 = (in[3] - base) >> 14; + w2 |= (in[4] - base) << 24; + w2 |= (in[5] - base) << 62; + w3 = (in[5] - base) >> 2; + w3 |= (in[6] - base) << 36; + w4 = (in[6] - base) >> 28; + w4 |= (in[7] - base) << 10; + w4 |= (in[8] - base) << 48; + w5 = (in[8] - base) >> 16; + w5 |= (in[9] - base) << 22; + w5 |= (in[10] - base) << 60; + w6 = (in[10] - base) >> 4; + w6 |= (in[11] - base) << 34; + w7 = (in[11] - base) >> 30; + w7 |= (in[12] - base) << 8; + w7 |= (in[13] - base) << 46; + w8 = (in[13] - base) >> 18; + w8 |= (in[14] - base) << 20; + w8 |= (in[15] - base) << 58; + w9 = (in[15] - base) >> 6; + w9 |= (in[16] - base) << 32; + w10 = (in[16] - base) >> 32; + w10 |= (in[17] - base) << 6; + w10 |= (in[18] - base) << 44; + w11 = (in[18] - base) >> 20; + w11 |= (in[19] - base) << 18; + w11 |= (in[20] - base) << 56; + w12 = (in[20] - base) >> 8; + w12 |= (in[21] - base) << 30; + w13 = (in[21] - base) >> 34; + w13 |= (in[22] - base) << 4; + w13 |= (in[23] - base) << 42; + w14 = (in[23] - base) >> 22; + w14 |= (in[24] - base) << 16; + w14 |= (in[25] - base) << 54; + w15 = (in[25] - base) >> 10; + w15 |= (in[26] - base) << 28; + w16 = (in[26] - base) >> 36; + w16 |= (in[27] - base) << 2; + w16 |= (in[28] - base) << 40; + w17 = (in[28] - base) >> 24; + w17 |= (in[29] - base) << 14; + w17 |= (in[30] - base) << 52; + w18 = (in[30] - base) >> 12; + w18 |= (in[31] - base) << 26; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 152; /* we used up 152 output bytes */ +} + + +/* we are going to pack 32 39-bit values, touching 20 64-bit words, using 156 bytes */ +static void packforblock39_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 20 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 39; + w1 = (in[1] - base) >> 25; + w1 |= (in[2] - base) << 14; + w1 |= (in[3] - base) << 53; + w2 = (in[3] - base) >> 11; + w2 |= (in[4] - base) << 28; + w3 = (in[4] - base) >> 36; + w3 |= (in[5] - base) << 3; + w3 |= (in[6] - base) << 42; + w4 = (in[6] - base) >> 22; + w4 |= (in[7] - base) << 17; + w4 |= (in[8] - base) << 56; + w5 = (in[8] - base) >> 8; + w5 |= (in[9] - base) << 31; + w6 = (in[9] - base) >> 33; + w6 |= (in[10] - base) << 6; + w6 |= (in[11] - base) << 45; + w7 = (in[11] - base) >> 19; + w7 |= (in[12] - base) << 20; + w7 |= (in[13] - base) << 59; + w8 = (in[13] - base) >> 5; + w8 |= (in[14] - base) << 34; + w9 = (in[14] - base) >> 30; + w9 |= (in[15] - base) << 9; + w9 |= (in[16] - base) << 48; + w10 = (in[16] - base) >> 16; + w10 |= (in[17] - base) << 23; + w10 |= (in[18] - base) << 62; + w11 = (in[18] - base) >> 2; + w11 |= (in[19] - base) << 37; + w12 = (in[19] - base) >> 27; + w12 |= (in[20] - base) << 12; + w12 |= (in[21] - base) << 51; + w13 = (in[21] - base) >> 13; + w13 |= (in[22] - base) << 26; + w14 = (in[22] - base) >> 38; + w14 |= (in[23] - base) << 1; + w14 |= (in[24] - base) << 40; + w15 = (in[24] - base) >> 24; + w15 |= (in[25] - base) << 15; + w15 |= (in[26] - base) << 54; + w16 = (in[26] - base) >> 10; + w16 |= (in[27] - base) << 29; + w17 = (in[27] - base) >> 35; + w17 |= (in[28] - base) << 4; + w17 |= (in[29] - base) << 43; + w18 = (in[29] - base) >> 21; + w18 |= (in[30] - base) << 18; + w18 |= (in[31] - base) << 57; + w19 = (in[31] - base) >> 7; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 156; /* we used up 156 output bytes */ +} + + +/* we are going to pack 32 40-bit values, touching 20 64-bit words, using 160 bytes */ +static void packforblock40_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 20 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 40; + w1 = (in[1] - base) >> 24; + w1 |= (in[2] - base) << 16; + w1 |= (in[3] - base) << 56; + w2 = (in[3] - base) >> 8; + w2 |= (in[4] - base) << 32; + w3 = (in[4] - base) >> 32; + w3 |= (in[5] - base) << 8; + w3 |= (in[6] - base) << 48; + w4 = (in[6] - base) >> 16; + w4 |= (in[7] - base) << 24; + w5 = (in[8] - base); + w5 |= (in[9] - base) << 40; + w6 = (in[9] - base) >> 24; + w6 |= (in[10] - base) << 16; + w6 |= (in[11] - base) << 56; + w7 = (in[11] - base) >> 8; + w7 |= (in[12] - base) << 32; + w8 = (in[12] - base) >> 32; + w8 |= (in[13] - base) << 8; + w8 |= (in[14] - base) << 48; + w9 = (in[14] - base) >> 16; + w9 |= (in[15] - base) << 24; + w10 = (in[16] - base); + w10 |= (in[17] - base) << 40; + w11 = (in[17] - base) >> 24; + w11 |= (in[18] - base) << 16; + w11 |= (in[19] - base) << 56; + w12 = (in[19] - base) >> 8; + w12 |= (in[20] - base) << 32; + w13 = (in[20] - base) >> 32; + w13 |= (in[21] - base) << 8; + w13 |= (in[22] - base) << 48; + w14 = (in[22] - base) >> 16; + w14 |= (in[23] - base) << 24; + w15 = (in[24] - base); + w15 |= (in[25] - base) << 40; + w16 = (in[25] - base) >> 24; + w16 |= (in[26] - base) << 16; + w16 |= (in[27] - base) << 56; + w17 = (in[27] - base) >> 8; + w17 |= (in[28] - base) << 32; + w18 = (in[28] - base) >> 32; + w18 |= (in[29] - base) << 8; + w18 |= (in[30] - base) << 48; + w19 = (in[30] - base) >> 16; + w19 |= (in[31] - base) << 24; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 160; /* we used up 160 output bytes */ +} + + +/* we are going to pack 32 41-bit values, touching 21 64-bit words, using 164 bytes */ +static void packforblock41_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 21 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 41; + w1 = (in[1] - base) >> 23; + w1 |= (in[2] - base) << 18; + w1 |= (in[3] - base) << 59; + w2 = (in[3] - base) >> 5; + w2 |= (in[4] - base) << 36; + w3 = (in[4] - base) >> 28; + w3 |= (in[5] - base) << 13; + w3 |= (in[6] - base) << 54; + w4 = (in[6] - base) >> 10; + w4 |= (in[7] - base) << 31; + w5 = (in[7] - base) >> 33; + w5 |= (in[8] - base) << 8; + w5 |= (in[9] - base) << 49; + w6 = (in[9] - base) >> 15; + w6 |= (in[10] - base) << 26; + w7 = (in[10] - base) >> 38; + w7 |= (in[11] - base) << 3; + w7 |= (in[12] - base) << 44; + w8 = (in[12] - base) >> 20; + w8 |= (in[13] - base) << 21; + w8 |= (in[14] - base) << 62; + w9 = (in[14] - base) >> 2; + w9 |= (in[15] - base) << 39; + w10 = (in[15] - base) >> 25; + w10 |= (in[16] - base) << 16; + w10 |= (in[17] - base) << 57; + w11 = (in[17] - base) >> 7; + w11 |= (in[18] - base) << 34; + w12 = (in[18] - base) >> 30; + w12 |= (in[19] - base) << 11; + w12 |= (in[20] - base) << 52; + w13 = (in[20] - base) >> 12; + w13 |= (in[21] - base) << 29; + w14 = (in[21] - base) >> 35; + w14 |= (in[22] - base) << 6; + w14 |= (in[23] - base) << 47; + w15 = (in[23] - base) >> 17; + w15 |= (in[24] - base) << 24; + w16 = (in[24] - base) >> 40; + w16 |= (in[25] - base) << 1; + w16 |= (in[26] - base) << 42; + w17 = (in[26] - base) >> 22; + w17 |= (in[27] - base) << 19; + w17 |= (in[28] - base) << 60; + w18 = (in[28] - base) >> 4; + w18 |= (in[29] - base) << 37; + w19 = (in[29] - base) >> 27; + w19 |= (in[30] - base) << 14; + w19 |= (in[31] - base) << 55; + w20 = (in[31] - base) >> 9; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 164; /* we used up 164 output bytes */ +} + + +/* we are going to pack 32 42-bit values, touching 21 64-bit words, using 168 bytes */ +static void packforblock42_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 21 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 42; + w1 = (in[1] - base) >> 22; + w1 |= (in[2] - base) << 20; + w1 |= (in[3] - base) << 62; + w2 = (in[3] - base) >> 2; + w2 |= (in[4] - base) << 40; + w3 = (in[4] - base) >> 24; + w3 |= (in[5] - base) << 18; + w3 |= (in[6] - base) << 60; + w4 = (in[6] - base) >> 4; + w4 |= (in[7] - base) << 38; + w5 = (in[7] - base) >> 26; + w5 |= (in[8] - base) << 16; + w5 |= (in[9] - base) << 58; + w6 = (in[9] - base) >> 6; + w6 |= (in[10] - base) << 36; + w7 = (in[10] - base) >> 28; + w7 |= (in[11] - base) << 14; + w7 |= (in[12] - base) << 56; + w8 = (in[12] - base) >> 8; + w8 |= (in[13] - base) << 34; + w9 = (in[13] - base) >> 30; + w9 |= (in[14] - base) << 12; + w9 |= (in[15] - base) << 54; + w10 = (in[15] - base) >> 10; + w10 |= (in[16] - base) << 32; + w11 = (in[16] - base) >> 32; + w11 |= (in[17] - base) << 10; + w11 |= (in[18] - base) << 52; + w12 = (in[18] - base) >> 12; + w12 |= (in[19] - base) << 30; + w13 = (in[19] - base) >> 34; + w13 |= (in[20] - base) << 8; + w13 |= (in[21] - base) << 50; + w14 = (in[21] - base) >> 14; + w14 |= (in[22] - base) << 28; + w15 = (in[22] - base) >> 36; + w15 |= (in[23] - base) << 6; + w15 |= (in[24] - base) << 48; + w16 = (in[24] - base) >> 16; + w16 |= (in[25] - base) << 26; + w17 = (in[25] - base) >> 38; + w17 |= (in[26] - base) << 4; + w17 |= (in[27] - base) << 46; + w18 = (in[27] - base) >> 18; + w18 |= (in[28] - base) << 24; + w19 = (in[28] - base) >> 40; + w19 |= (in[29] - base) << 2; + w19 |= (in[30] - base) << 44; + w20 = (in[30] - base) >> 20; + w20 |= (in[31] - base) << 22; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 168; /* we used up 168 output bytes */ +} + + +/* we are going to pack 32 43-bit values, touching 22 64-bit words, using 172 bytes */ +static void packforblock43_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 22 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 43; + w1 = (in[1] - base) >> 21; + w1 |= (in[2] - base) << 22; + w2 = (in[2] - base) >> 42; + w2 |= (in[3] - base) << 1; + w2 |= (in[4] - base) << 44; + w3 = (in[4] - base) >> 20; + w3 |= (in[5] - base) << 23; + w4 = (in[5] - base) >> 41; + w4 |= (in[6] - base) << 2; + w4 |= (in[7] - base) << 45; + w5 = (in[7] - base) >> 19; + w5 |= (in[8] - base) << 24; + w6 = (in[8] - base) >> 40; + w6 |= (in[9] - base) << 3; + w6 |= (in[10] - base) << 46; + w7 = (in[10] - base) >> 18; + w7 |= (in[11] - base) << 25; + w8 = (in[11] - base) >> 39; + w8 |= (in[12] - base) << 4; + w8 |= (in[13] - base) << 47; + w9 = (in[13] - base) >> 17; + w9 |= (in[14] - base) << 26; + w10 = (in[14] - base) >> 38; + w10 |= (in[15] - base) << 5; + w10 |= (in[16] - base) << 48; + w11 = (in[16] - base) >> 16; + w11 |= (in[17] - base) << 27; + w12 = (in[17] - base) >> 37; + w12 |= (in[18] - base) << 6; + w12 |= (in[19] - base) << 49; + w13 = (in[19] - base) >> 15; + w13 |= (in[20] - base) << 28; + w14 = (in[20] - base) >> 36; + w14 |= (in[21] - base) << 7; + w14 |= (in[22] - base) << 50; + w15 = (in[22] - base) >> 14; + w15 |= (in[23] - base) << 29; + w16 = (in[23] - base) >> 35; + w16 |= (in[24] - base) << 8; + w16 |= (in[25] - base) << 51; + w17 = (in[25] - base) >> 13; + w17 |= (in[26] - base) << 30; + w18 = (in[26] - base) >> 34; + w18 |= (in[27] - base) << 9; + w18 |= (in[28] - base) << 52; + w19 = (in[28] - base) >> 12; + w19 |= (in[29] - base) << 31; + w20 = (in[29] - base) >> 33; + w20 |= (in[30] - base) << 10; + w20 |= (in[31] - base) << 53; + w21 = (in[31] - base) >> 11; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 172; /* we used up 172 output bytes */ +} + + +/* we are going to pack 32 44-bit values, touching 22 64-bit words, using 176 bytes */ +static void packforblock44_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 22 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 44; + w1 = (in[1] - base) >> 20; + w1 |= (in[2] - base) << 24; + w2 = (in[2] - base) >> 40; + w2 |= (in[3] - base) << 4; + w2 |= (in[4] - base) << 48; + w3 = (in[4] - base) >> 16; + w3 |= (in[5] - base) << 28; + w4 = (in[5] - base) >> 36; + w4 |= (in[6] - base) << 8; + w4 |= (in[7] - base) << 52; + w5 = (in[7] - base) >> 12; + w5 |= (in[8] - base) << 32; + w6 = (in[8] - base) >> 32; + w6 |= (in[9] - base) << 12; + w6 |= (in[10] - base) << 56; + w7 = (in[10] - base) >> 8; + w7 |= (in[11] - base) << 36; + w8 = (in[11] - base) >> 28; + w8 |= (in[12] - base) << 16; + w8 |= (in[13] - base) << 60; + w9 = (in[13] - base) >> 4; + w9 |= (in[14] - base) << 40; + w10 = (in[14] - base) >> 24; + w10 |= (in[15] - base) << 20; + w11 = (in[16] - base); + w11 |= (in[17] - base) << 44; + w12 = (in[17] - base) >> 20; + w12 |= (in[18] - base) << 24; + w13 = (in[18] - base) >> 40; + w13 |= (in[19] - base) << 4; + w13 |= (in[20] - base) << 48; + w14 = (in[20] - base) >> 16; + w14 |= (in[21] - base) << 28; + w15 = (in[21] - base) >> 36; + w15 |= (in[22] - base) << 8; + w15 |= (in[23] - base) << 52; + w16 = (in[23] - base) >> 12; + w16 |= (in[24] - base) << 32; + w17 = (in[24] - base) >> 32; + w17 |= (in[25] - base) << 12; + w17 |= (in[26] - base) << 56; + w18 = (in[26] - base) >> 8; + w18 |= (in[27] - base) << 36; + w19 = (in[27] - base) >> 28; + w19 |= (in[28] - base) << 16; + w19 |= (in[29] - base) << 60; + w20 = (in[29] - base) >> 4; + w20 |= (in[30] - base) << 40; + w21 = (in[30] - base) >> 24; + w21 |= (in[31] - base) << 20; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 176; /* we used up 176 output bytes */ +} + + +/* we are going to pack 32 45-bit values, touching 23 64-bit words, using 180 bytes */ +static void packforblock45_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 23 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 45; + w1 = (in[1] - base) >> 19; + w1 |= (in[2] - base) << 26; + w2 = (in[2] - base) >> 38; + w2 |= (in[3] - base) << 7; + w2 |= (in[4] - base) << 52; + w3 = (in[4] - base) >> 12; + w3 |= (in[5] - base) << 33; + w4 = (in[5] - base) >> 31; + w4 |= (in[6] - base) << 14; + w4 |= (in[7] - base) << 59; + w5 = (in[7] - base) >> 5; + w5 |= (in[8] - base) << 40; + w6 = (in[8] - base) >> 24; + w6 |= (in[9] - base) << 21; + w7 = (in[9] - base) >> 43; + w7 |= (in[10] - base) << 2; + w7 |= (in[11] - base) << 47; + w8 = (in[11] - base) >> 17; + w8 |= (in[12] - base) << 28; + w9 = (in[12] - base) >> 36; + w9 |= (in[13] - base) << 9; + w9 |= (in[14] - base) << 54; + w10 = (in[14] - base) >> 10; + w10 |= (in[15] - base) << 35; + w11 = (in[15] - base) >> 29; + w11 |= (in[16] - base) << 16; + w11 |= (in[17] - base) << 61; + w12 = (in[17] - base) >> 3; + w12 |= (in[18] - base) << 42; + w13 = (in[18] - base) >> 22; + w13 |= (in[19] - base) << 23; + w14 = (in[19] - base) >> 41; + w14 |= (in[20] - base) << 4; + w14 |= (in[21] - base) << 49; + w15 = (in[21] - base) >> 15; + w15 |= (in[22] - base) << 30; + w16 = (in[22] - base) >> 34; + w16 |= (in[23] - base) << 11; + w16 |= (in[24] - base) << 56; + w17 = (in[24] - base) >> 8; + w17 |= (in[25] - base) << 37; + w18 = (in[25] - base) >> 27; + w18 |= (in[26] - base) << 18; + w18 |= (in[27] - base) << 63; + w19 = (in[27] - base) >> 1; + w19 |= (in[28] - base) << 44; + w20 = (in[28] - base) >> 20; + w20 |= (in[29] - base) << 25; + w21 = (in[29] - base) >> 39; + w21 |= (in[30] - base) << 6; + w21 |= (in[31] - base) << 51; + w22 = (in[31] - base) >> 13; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 180; /* we used up 180 output bytes */ +} + + +/* we are going to pack 32 46-bit values, touching 23 64-bit words, using 184 bytes */ +static void packforblock46_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 23 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 46; + w1 = (in[1] - base) >> 18; + w1 |= (in[2] - base) << 28; + w2 = (in[2] - base) >> 36; + w2 |= (in[3] - base) << 10; + w2 |= (in[4] - base) << 56; + w3 = (in[4] - base) >> 8; + w3 |= (in[5] - base) << 38; + w4 = (in[5] - base) >> 26; + w4 |= (in[6] - base) << 20; + w5 = (in[6] - base) >> 44; + w5 |= (in[7] - base) << 2; + w5 |= (in[8] - base) << 48; + w6 = (in[8] - base) >> 16; + w6 |= (in[9] - base) << 30; + w7 = (in[9] - base) >> 34; + w7 |= (in[10] - base) << 12; + w7 |= (in[11] - base) << 58; + w8 = (in[11] - base) >> 6; + w8 |= (in[12] - base) << 40; + w9 = (in[12] - base) >> 24; + w9 |= (in[13] - base) << 22; + w10 = (in[13] - base) >> 42; + w10 |= (in[14] - base) << 4; + w10 |= (in[15] - base) << 50; + w11 = (in[15] - base) >> 14; + w11 |= (in[16] - base) << 32; + w12 = (in[16] - base) >> 32; + w12 |= (in[17] - base) << 14; + w12 |= (in[18] - base) << 60; + w13 = (in[18] - base) >> 4; + w13 |= (in[19] - base) << 42; + w14 = (in[19] - base) >> 22; + w14 |= (in[20] - base) << 24; + w15 = (in[20] - base) >> 40; + w15 |= (in[21] - base) << 6; + w15 |= (in[22] - base) << 52; + w16 = (in[22] - base) >> 12; + w16 |= (in[23] - base) << 34; + w17 = (in[23] - base) >> 30; + w17 |= (in[24] - base) << 16; + w17 |= (in[25] - base) << 62; + w18 = (in[25] - base) >> 2; + w18 |= (in[26] - base) << 44; + w19 = (in[26] - base) >> 20; + w19 |= (in[27] - base) << 26; + w20 = (in[27] - base) >> 38; + w20 |= (in[28] - base) << 8; + w20 |= (in[29] - base) << 54; + w21 = (in[29] - base) >> 10; + w21 |= (in[30] - base) << 36; + w22 = (in[30] - base) >> 28; + w22 |= (in[31] - base) << 18; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 184; /* we used up 184 output bytes */ +} + + +/* we are going to pack 32 47-bit values, touching 24 64-bit words, using 188 bytes */ +static void packforblock47_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 24 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 47; + w1 = (in[1] - base) >> 17; + w1 |= (in[2] - base) << 30; + w2 = (in[2] - base) >> 34; + w2 |= (in[3] - base) << 13; + w2 |= (in[4] - base) << 60; + w3 = (in[4] - base) >> 4; + w3 |= (in[5] - base) << 43; + w4 = (in[5] - base) >> 21; + w4 |= (in[6] - base) << 26; + w5 = (in[6] - base) >> 38; + w5 |= (in[7] - base) << 9; + w5 |= (in[8] - base) << 56; + w6 = (in[8] - base) >> 8; + w6 |= (in[9] - base) << 39; + w7 = (in[9] - base) >> 25; + w7 |= (in[10] - base) << 22; + w8 = (in[10] - base) >> 42; + w8 |= (in[11] - base) << 5; + w8 |= (in[12] - base) << 52; + w9 = (in[12] - base) >> 12; + w9 |= (in[13] - base) << 35; + w10 = (in[13] - base) >> 29; + w10 |= (in[14] - base) << 18; + w11 = (in[14] - base) >> 46; + w11 |= (in[15] - base) << 1; + w11 |= (in[16] - base) << 48; + w12 = (in[16] - base) >> 16; + w12 |= (in[17] - base) << 31; + w13 = (in[17] - base) >> 33; + w13 |= (in[18] - base) << 14; + w13 |= (in[19] - base) << 61; + w14 = (in[19] - base) >> 3; + w14 |= (in[20] - base) << 44; + w15 = (in[20] - base) >> 20; + w15 |= (in[21] - base) << 27; + w16 = (in[21] - base) >> 37; + w16 |= (in[22] - base) << 10; + w16 |= (in[23] - base) << 57; + w17 = (in[23] - base) >> 7; + w17 |= (in[24] - base) << 40; + w18 = (in[24] - base) >> 24; + w18 |= (in[25] - base) << 23; + w19 = (in[25] - base) >> 41; + w19 |= (in[26] - base) << 6; + w19 |= (in[27] - base) << 53; + w20 = (in[27] - base) >> 11; + w20 |= (in[28] - base) << 36; + w21 = (in[28] - base) >> 28; + w21 |= (in[29] - base) << 19; + w22 = (in[29] - base) >> 45; + w22 |= (in[30] - base) << 2; + w22 |= (in[31] - base) << 49; + w23 = (in[31] - base) >> 15; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 188; /* we used up 188 output bytes */ +} + + +/* we are going to pack 32 48-bit values, touching 24 64-bit words, using 192 bytes */ +static void packforblock48_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 24 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 48; + w1 = (in[1] - base) >> 16; + w1 |= (in[2] - base) << 32; + w2 = (in[2] - base) >> 32; + w2 |= (in[3] - base) << 16; + w3 = (in[4] - base); + w3 |= (in[5] - base) << 48; + w4 = (in[5] - base) >> 16; + w4 |= (in[6] - base) << 32; + w5 = (in[6] - base) >> 32; + w5 |= (in[7] - base) << 16; + w6 = (in[8] - base); + w6 |= (in[9] - base) << 48; + w7 = (in[9] - base) >> 16; + w7 |= (in[10] - base) << 32; + w8 = (in[10] - base) >> 32; + w8 |= (in[11] - base) << 16; + w9 = (in[12] - base); + w9 |= (in[13] - base) << 48; + w10 = (in[13] - base) >> 16; + w10 |= (in[14] - base) << 32; + w11 = (in[14] - base) >> 32; + w11 |= (in[15] - base) << 16; + w12 = (in[16] - base); + w12 |= (in[17] - base) << 48; + w13 = (in[17] - base) >> 16; + w13 |= (in[18] - base) << 32; + w14 = (in[18] - base) >> 32; + w14 |= (in[19] - base) << 16; + w15 = (in[20] - base); + w15 |= (in[21] - base) << 48; + w16 = (in[21] - base) >> 16; + w16 |= (in[22] - base) << 32; + w17 = (in[22] - base) >> 32; + w17 |= (in[23] - base) << 16; + w18 = (in[24] - base); + w18 |= (in[25] - base) << 48; + w19 = (in[25] - base) >> 16; + w19 |= (in[26] - base) << 32; + w20 = (in[26] - base) >> 32; + w20 |= (in[27] - base) << 16; + w21 = (in[28] - base); + w21 |= (in[29] - base) << 48; + w22 = (in[29] - base) >> 16; + w22 |= (in[30] - base) << 32; + w23 = (in[30] - base) >> 32; + w23 |= (in[31] - base) << 16; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 192; /* we used up 192 output bytes */ +} + + +/* we are going to pack 32 49-bit values, touching 25 64-bit words, using 196 bytes */ +static void packforblock49_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 25 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 49; + w1 = (in[1] - base) >> 15; + w1 |= (in[2] - base) << 34; + w2 = (in[2] - base) >> 30; + w2 |= (in[3] - base) << 19; + w3 = (in[3] - base) >> 45; + w3 |= (in[4] - base) << 4; + w3 |= (in[5] - base) << 53; + w4 = (in[5] - base) >> 11; + w4 |= (in[6] - base) << 38; + w5 = (in[6] - base) >> 26; + w5 |= (in[7] - base) << 23; + w6 = (in[7] - base) >> 41; + w6 |= (in[8] - base) << 8; + w6 |= (in[9] - base) << 57; + w7 = (in[9] - base) >> 7; + w7 |= (in[10] - base) << 42; + w8 = (in[10] - base) >> 22; + w8 |= (in[11] - base) << 27; + w9 = (in[11] - base) >> 37; + w9 |= (in[12] - base) << 12; + w9 |= (in[13] - base) << 61; + w10 = (in[13] - base) >> 3; + w10 |= (in[14] - base) << 46; + w11 = (in[14] - base) >> 18; + w11 |= (in[15] - base) << 31; + w12 = (in[15] - base) >> 33; + w12 |= (in[16] - base) << 16; + w13 = (in[16] - base) >> 48; + w13 |= (in[17] - base) << 1; + w13 |= (in[18] - base) << 50; + w14 = (in[18] - base) >> 14; + w14 |= (in[19] - base) << 35; + w15 = (in[19] - base) >> 29; + w15 |= (in[20] - base) << 20; + w16 = (in[20] - base) >> 44; + w16 |= (in[21] - base) << 5; + w16 |= (in[22] - base) << 54; + w17 = (in[22] - base) >> 10; + w17 |= (in[23] - base) << 39; + w18 = (in[23] - base) >> 25; + w18 |= (in[24] - base) << 24; + w19 = (in[24] - base) >> 40; + w19 |= (in[25] - base) << 9; + w19 |= (in[26] - base) << 58; + w20 = (in[26] - base) >> 6; + w20 |= (in[27] - base) << 43; + w21 = (in[27] - base) >> 21; + w21 |= (in[28] - base) << 28; + w22 = (in[28] - base) >> 36; + w22 |= (in[29] - base) << 13; + w22 |= (in[30] - base) << 62; + w23 = (in[30] - base) >> 2; + w23 |= (in[31] - base) << 47; + w24 = (in[31] - base) >> 17; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 196; /* we used up 196 output bytes */ +} + + +/* we are going to pack 32 50-bit values, touching 25 64-bit words, using 200 bytes */ +static void packforblock50_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 25 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 50; + w1 = (in[1] - base) >> 14; + w1 |= (in[2] - base) << 36; + w2 = (in[2] - base) >> 28; + w2 |= (in[3] - base) << 22; + w3 = (in[3] - base) >> 42; + w3 |= (in[4] - base) << 8; + w3 |= (in[5] - base) << 58; + w4 = (in[5] - base) >> 6; + w4 |= (in[6] - base) << 44; + w5 = (in[6] - base) >> 20; + w5 |= (in[7] - base) << 30; + w6 = (in[7] - base) >> 34; + w6 |= (in[8] - base) << 16; + w7 = (in[8] - base) >> 48; + w7 |= (in[9] - base) << 2; + w7 |= (in[10] - base) << 52; + w8 = (in[10] - base) >> 12; + w8 |= (in[11] - base) << 38; + w9 = (in[11] - base) >> 26; + w9 |= (in[12] - base) << 24; + w10 = (in[12] - base) >> 40; + w10 |= (in[13] - base) << 10; + w10 |= (in[14] - base) << 60; + w11 = (in[14] - base) >> 4; + w11 |= (in[15] - base) << 46; + w12 = (in[15] - base) >> 18; + w12 |= (in[16] - base) << 32; + w13 = (in[16] - base) >> 32; + w13 |= (in[17] - base) << 18; + w14 = (in[17] - base) >> 46; + w14 |= (in[18] - base) << 4; + w14 |= (in[19] - base) << 54; + w15 = (in[19] - base) >> 10; + w15 |= (in[20] - base) << 40; + w16 = (in[20] - base) >> 24; + w16 |= (in[21] - base) << 26; + w17 = (in[21] - base) >> 38; + w17 |= (in[22] - base) << 12; + w17 |= (in[23] - base) << 62; + w18 = (in[23] - base) >> 2; + w18 |= (in[24] - base) << 48; + w19 = (in[24] - base) >> 16; + w19 |= (in[25] - base) << 34; + w20 = (in[25] - base) >> 30; + w20 |= (in[26] - base) << 20; + w21 = (in[26] - base) >> 44; + w21 |= (in[27] - base) << 6; + w21 |= (in[28] - base) << 56; + w22 = (in[28] - base) >> 8; + w22 |= (in[29] - base) << 42; + w23 = (in[29] - base) >> 22; + w23 |= (in[30] - base) << 28; + w24 = (in[30] - base) >> 36; + w24 |= (in[31] - base) << 14; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 200; /* we used up 200 output bytes */ +} + + +/* we are going to pack 32 51-bit values, touching 26 64-bit words, using 204 bytes */ +static void packforblock51_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 26 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 51; + w1 = (in[1] - base) >> 13; + w1 |= (in[2] - base) << 38; + w2 = (in[2] - base) >> 26; + w2 |= (in[3] - base) << 25; + w3 = (in[3] - base) >> 39; + w3 |= (in[4] - base) << 12; + w3 |= (in[5] - base) << 63; + w4 = (in[5] - base) >> 1; + w4 |= (in[6] - base) << 50; + w5 = (in[6] - base) >> 14; + w5 |= (in[7] - base) << 37; + w6 = (in[7] - base) >> 27; + w6 |= (in[8] - base) << 24; + w7 = (in[8] - base) >> 40; + w7 |= (in[9] - base) << 11; + w7 |= (in[10] - base) << 62; + w8 = (in[10] - base) >> 2; + w8 |= (in[11] - base) << 49; + w9 = (in[11] - base) >> 15; + w9 |= (in[12] - base) << 36; + w10 = (in[12] - base) >> 28; + w10 |= (in[13] - base) << 23; + w11 = (in[13] - base) >> 41; + w11 |= (in[14] - base) << 10; + w11 |= (in[15] - base) << 61; + w12 = (in[15] - base) >> 3; + w12 |= (in[16] - base) << 48; + w13 = (in[16] - base) >> 16; + w13 |= (in[17] - base) << 35; + w14 = (in[17] - base) >> 29; + w14 |= (in[18] - base) << 22; + w15 = (in[18] - base) >> 42; + w15 |= (in[19] - base) << 9; + w15 |= (in[20] - base) << 60; + w16 = (in[20] - base) >> 4; + w16 |= (in[21] - base) << 47; + w17 = (in[21] - base) >> 17; + w17 |= (in[22] - base) << 34; + w18 = (in[22] - base) >> 30; + w18 |= (in[23] - base) << 21; + w19 = (in[23] - base) >> 43; + w19 |= (in[24] - base) << 8; + w19 |= (in[25] - base) << 59; + w20 = (in[25] - base) >> 5; + w20 |= (in[26] - base) << 46; + w21 = (in[26] - base) >> 18; + w21 |= (in[27] - base) << 33; + w22 = (in[27] - base) >> 31; + w22 |= (in[28] - base) << 20; + w23 = (in[28] - base) >> 44; + w23 |= (in[29] - base) << 7; + w23 |= (in[30] - base) << 58; + w24 = (in[30] - base) >> 6; + w24 |= (in[31] - base) << 45; + w25 = (in[31] - base) >> 19; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 204; /* we used up 204 output bytes */ +} + + +/* we are going to pack 32 52-bit values, touching 26 64-bit words, using 208 bytes */ +static void packforblock52_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 26 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 52; + w1 = (in[1] - base) >> 12; + w1 |= (in[2] - base) << 40; + w2 = (in[2] - base) >> 24; + w2 |= (in[3] - base) << 28; + w3 = (in[3] - base) >> 36; + w3 |= (in[4] - base) << 16; + w4 = (in[4] - base) >> 48; + w4 |= (in[5] - base) << 4; + w4 |= (in[6] - base) << 56; + w5 = (in[6] - base) >> 8; + w5 |= (in[7] - base) << 44; + w6 = (in[7] - base) >> 20; + w6 |= (in[8] - base) << 32; + w7 = (in[8] - base) >> 32; + w7 |= (in[9] - base) << 20; + w8 = (in[9] - base) >> 44; + w8 |= (in[10] - base) << 8; + w8 |= (in[11] - base) << 60; + w9 = (in[11] - base) >> 4; + w9 |= (in[12] - base) << 48; + w10 = (in[12] - base) >> 16; + w10 |= (in[13] - base) << 36; + w11 = (in[13] - base) >> 28; + w11 |= (in[14] - base) << 24; + w12 = (in[14] - base) >> 40; + w12 |= (in[15] - base) << 12; + w13 = (in[16] - base); + w13 |= (in[17] - base) << 52; + w14 = (in[17] - base) >> 12; + w14 |= (in[18] - base) << 40; + w15 = (in[18] - base) >> 24; + w15 |= (in[19] - base) << 28; + w16 = (in[19] - base) >> 36; + w16 |= (in[20] - base) << 16; + w17 = (in[20] - base) >> 48; + w17 |= (in[21] - base) << 4; + w17 |= (in[22] - base) << 56; + w18 = (in[22] - base) >> 8; + w18 |= (in[23] - base) << 44; + w19 = (in[23] - base) >> 20; + w19 |= (in[24] - base) << 32; + w20 = (in[24] - base) >> 32; + w20 |= (in[25] - base) << 20; + w21 = (in[25] - base) >> 44; + w21 |= (in[26] - base) << 8; + w21 |= (in[27] - base) << 60; + w22 = (in[27] - base) >> 4; + w22 |= (in[28] - base) << 48; + w23 = (in[28] - base) >> 16; + w23 |= (in[29] - base) << 36; + w24 = (in[29] - base) >> 28; + w24 |= (in[30] - base) << 24; + w25 = (in[30] - base) >> 40; + w25 |= (in[31] - base) << 12; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 208; /* we used up 208 output bytes */ +} + + +/* we are going to pack 32 53-bit values, touching 27 64-bit words, using 212 bytes */ +static void packforblock53_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 27 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 53; + w1 = (in[1] - base) >> 11; + w1 |= (in[2] - base) << 42; + w2 = (in[2] - base) >> 22; + w2 |= (in[3] - base) << 31; + w3 = (in[3] - base) >> 33; + w3 |= (in[4] - base) << 20; + w4 = (in[4] - base) >> 44; + w4 |= (in[5] - base) << 9; + w4 |= (in[6] - base) << 62; + w5 = (in[6] - base) >> 2; + w5 |= (in[7] - base) << 51; + w6 = (in[7] - base) >> 13; + w6 |= (in[8] - base) << 40; + w7 = (in[8] - base) >> 24; + w7 |= (in[9] - base) << 29; + w8 = (in[9] - base) >> 35; + w8 |= (in[10] - base) << 18; + w9 = (in[10] - base) >> 46; + w9 |= (in[11] - base) << 7; + w9 |= (in[12] - base) << 60; + w10 = (in[12] - base) >> 4; + w10 |= (in[13] - base) << 49; + w11 = (in[13] - base) >> 15; + w11 |= (in[14] - base) << 38; + w12 = (in[14] - base) >> 26; + w12 |= (in[15] - base) << 27; + w13 = (in[15] - base) >> 37; + w13 |= (in[16] - base) << 16; + w14 = (in[16] - base) >> 48; + w14 |= (in[17] - base) << 5; + w14 |= (in[18] - base) << 58; + w15 = (in[18] - base) >> 6; + w15 |= (in[19] - base) << 47; + w16 = (in[19] - base) >> 17; + w16 |= (in[20] - base) << 36; + w17 = (in[20] - base) >> 28; + w17 |= (in[21] - base) << 25; + w18 = (in[21] - base) >> 39; + w18 |= (in[22] - base) << 14; + w19 = (in[22] - base) >> 50; + w19 |= (in[23] - base) << 3; + w19 |= (in[24] - base) << 56; + w20 = (in[24] - base) >> 8; + w20 |= (in[25] - base) << 45; + w21 = (in[25] - base) >> 19; + w21 |= (in[26] - base) << 34; + w22 = (in[26] - base) >> 30; + w22 |= (in[27] - base) << 23; + w23 = (in[27] - base) >> 41; + w23 |= (in[28] - base) << 12; + w24 = (in[28] - base) >> 52; + w24 |= (in[29] - base) << 1; + w24 |= (in[30] - base) << 54; + w25 = (in[30] - base) >> 10; + w25 |= (in[31] - base) << 43; + w26 = (in[31] - base) >> 21; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 212; /* we used up 212 output bytes */ +} + + +/* we are going to pack 32 54-bit values, touching 27 64-bit words, using 216 bytes */ +static void packforblock54_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 27 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 54; + w1 = (in[1] - base) >> 10; + w1 |= (in[2] - base) << 44; + w2 = (in[2] - base) >> 20; + w2 |= (in[3] - base) << 34; + w3 = (in[3] - base) >> 30; + w3 |= (in[4] - base) << 24; + w4 = (in[4] - base) >> 40; + w4 |= (in[5] - base) << 14; + w5 = (in[5] - base) >> 50; + w5 |= (in[6] - base) << 4; + w5 |= (in[7] - base) << 58; + w6 = (in[7] - base) >> 6; + w6 |= (in[8] - base) << 48; + w7 = (in[8] - base) >> 16; + w7 |= (in[9] - base) << 38; + w8 = (in[9] - base) >> 26; + w8 |= (in[10] - base) << 28; + w9 = (in[10] - base) >> 36; + w9 |= (in[11] - base) << 18; + w10 = (in[11] - base) >> 46; + w10 |= (in[12] - base) << 8; + w10 |= (in[13] - base) << 62; + w11 = (in[13] - base) >> 2; + w11 |= (in[14] - base) << 52; + w12 = (in[14] - base) >> 12; + w12 |= (in[15] - base) << 42; + w13 = (in[15] - base) >> 22; + w13 |= (in[16] - base) << 32; + w14 = (in[16] - base) >> 32; + w14 |= (in[17] - base) << 22; + w15 = (in[17] - base) >> 42; + w15 |= (in[18] - base) << 12; + w16 = (in[18] - base) >> 52; + w16 |= (in[19] - base) << 2; + w16 |= (in[20] - base) << 56; + w17 = (in[20] - base) >> 8; + w17 |= (in[21] - base) << 46; + w18 = (in[21] - base) >> 18; + w18 |= (in[22] - base) << 36; + w19 = (in[22] - base) >> 28; + w19 |= (in[23] - base) << 26; + w20 = (in[23] - base) >> 38; + w20 |= (in[24] - base) << 16; + w21 = (in[24] - base) >> 48; + w21 |= (in[25] - base) << 6; + w21 |= (in[26] - base) << 60; + w22 = (in[26] - base) >> 4; + w22 |= (in[27] - base) << 50; + w23 = (in[27] - base) >> 14; + w23 |= (in[28] - base) << 40; + w24 = (in[28] - base) >> 24; + w24 |= (in[29] - base) << 30; + w25 = (in[29] - base) >> 34; + w25 |= (in[30] - base) << 20; + w26 = (in[30] - base) >> 44; + w26 |= (in[31] - base) << 10; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 216; /* we used up 216 output bytes */ +} + + +/* we are going to pack 32 55-bit values, touching 28 64-bit words, using 220 bytes */ +static void packforblock55_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 28 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 55; + w1 = (in[1] - base) >> 9; + w1 |= (in[2] - base) << 46; + w2 = (in[2] - base) >> 18; + w2 |= (in[3] - base) << 37; + w3 = (in[3] - base) >> 27; + w3 |= (in[4] - base) << 28; + w4 = (in[4] - base) >> 36; + w4 |= (in[5] - base) << 19; + w5 = (in[5] - base) >> 45; + w5 |= (in[6] - base) << 10; + w6 = (in[6] - base) >> 54; + w6 |= (in[7] - base) << 1; + w6 |= (in[8] - base) << 56; + w7 = (in[8] - base) >> 8; + w7 |= (in[9] - base) << 47; + w8 = (in[9] - base) >> 17; + w8 |= (in[10] - base) << 38; + w9 = (in[10] - base) >> 26; + w9 |= (in[11] - base) << 29; + w10 = (in[11] - base) >> 35; + w10 |= (in[12] - base) << 20; + w11 = (in[12] - base) >> 44; + w11 |= (in[13] - base) << 11; + w12 = (in[13] - base) >> 53; + w12 |= (in[14] - base) << 2; + w12 |= (in[15] - base) << 57; + w13 = (in[15] - base) >> 7; + w13 |= (in[16] - base) << 48; + w14 = (in[16] - base) >> 16; + w14 |= (in[17] - base) << 39; + w15 = (in[17] - base) >> 25; + w15 |= (in[18] - base) << 30; + w16 = (in[18] - base) >> 34; + w16 |= (in[19] - base) << 21; + w17 = (in[19] - base) >> 43; + w17 |= (in[20] - base) << 12; + w18 = (in[20] - base) >> 52; + w18 |= (in[21] - base) << 3; + w18 |= (in[22] - base) << 58; + w19 = (in[22] - base) >> 6; + w19 |= (in[23] - base) << 49; + w20 = (in[23] - base) >> 15; + w20 |= (in[24] - base) << 40; + w21 = (in[24] - base) >> 24; + w21 |= (in[25] - base) << 31; + w22 = (in[25] - base) >> 33; + w22 |= (in[26] - base) << 22; + w23 = (in[26] - base) >> 42; + w23 |= (in[27] - base) << 13; + w24 = (in[27] - base) >> 51; + w24 |= (in[28] - base) << 4; + w24 |= (in[29] - base) << 59; + w25 = (in[29] - base) >> 5; + w25 |= (in[30] - base) << 50; + w26 = (in[30] - base) >> 14; + w26 |= (in[31] - base) << 41; + w27 = (in[31] - base) >> 23; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 220; /* we used up 220 output bytes */ +} + + +/* we are going to pack 32 56-bit values, touching 28 64-bit words, using 224 bytes */ +static void packforblock56_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 28 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 56; + w1 = (in[1] - base) >> 8; + w1 |= (in[2] - base) << 48; + w2 = (in[2] - base) >> 16; + w2 |= (in[3] - base) << 40; + w3 = (in[3] - base) >> 24; + w3 |= (in[4] - base) << 32; + w4 = (in[4] - base) >> 32; + w4 |= (in[5] - base) << 24; + w5 = (in[5] - base) >> 40; + w5 |= (in[6] - base) << 16; + w6 = (in[6] - base) >> 48; + w6 |= (in[7] - base) << 8; + w7 = (in[8] - base); + w7 |= (in[9] - base) << 56; + w8 = (in[9] - base) >> 8; + w8 |= (in[10] - base) << 48; + w9 = (in[10] - base) >> 16; + w9 |= (in[11] - base) << 40; + w10 = (in[11] - base) >> 24; + w10 |= (in[12] - base) << 32; + w11 = (in[12] - base) >> 32; + w11 |= (in[13] - base) << 24; + w12 = (in[13] - base) >> 40; + w12 |= (in[14] - base) << 16; + w13 = (in[14] - base) >> 48; + w13 |= (in[15] - base) << 8; + w14 = (in[16] - base); + w14 |= (in[17] - base) << 56; + w15 = (in[17] - base) >> 8; + w15 |= (in[18] - base) << 48; + w16 = (in[18] - base) >> 16; + w16 |= (in[19] - base) << 40; + w17 = (in[19] - base) >> 24; + w17 |= (in[20] - base) << 32; + w18 = (in[20] - base) >> 32; + w18 |= (in[21] - base) << 24; + w19 = (in[21] - base) >> 40; + w19 |= (in[22] - base) << 16; + w20 = (in[22] - base) >> 48; + w20 |= (in[23] - base) << 8; + w21 = (in[24] - base); + w21 |= (in[25] - base) << 56; + w22 = (in[25] - base) >> 8; + w22 |= (in[26] - base) << 48; + w23 = (in[26] - base) >> 16; + w23 |= (in[27] - base) << 40; + w24 = (in[27] - base) >> 24; + w24 |= (in[28] - base) << 32; + w25 = (in[28] - base) >> 32; + w25 |= (in[29] - base) << 24; + w26 = (in[29] - base) >> 40; + w26 |= (in[30] - base) << 16; + w27 = (in[30] - base) >> 48; + w27 |= (in[31] - base) << 8; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 224; /* we used up 224 output bytes */ +} + + +/* we are going to pack 32 57-bit values, touching 29 64-bit words, using 228 bytes */ +static void packforblock57_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 29 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 57; + w1 = (in[1] - base) >> 7; + w1 |= (in[2] - base) << 50; + w2 = (in[2] - base) >> 14; + w2 |= (in[3] - base) << 43; + w3 = (in[3] - base) >> 21; + w3 |= (in[4] - base) << 36; + w4 = (in[4] - base) >> 28; + w4 |= (in[5] - base) << 29; + w5 = (in[5] - base) >> 35; + w5 |= (in[6] - base) << 22; + w6 = (in[6] - base) >> 42; + w6 |= (in[7] - base) << 15; + w7 = (in[7] - base) >> 49; + w7 |= (in[8] - base) << 8; + w8 = (in[8] - base) >> 56; + w8 |= (in[9] - base) << 1; + w8 |= (in[10] - base) << 58; + w9 = (in[10] - base) >> 6; + w9 |= (in[11] - base) << 51; + w10 = (in[11] - base) >> 13; + w10 |= (in[12] - base) << 44; + w11 = (in[12] - base) >> 20; + w11 |= (in[13] - base) << 37; + w12 = (in[13] - base) >> 27; + w12 |= (in[14] - base) << 30; + w13 = (in[14] - base) >> 34; + w13 |= (in[15] - base) << 23; + w14 = (in[15] - base) >> 41; + w14 |= (in[16] - base) << 16; + w15 = (in[16] - base) >> 48; + w15 |= (in[17] - base) << 9; + w16 = (in[17] - base) >> 55; + w16 |= (in[18] - base) << 2; + w16 |= (in[19] - base) << 59; + w17 = (in[19] - base) >> 5; + w17 |= (in[20] - base) << 52; + w18 = (in[20] - base) >> 12; + w18 |= (in[21] - base) << 45; + w19 = (in[21] - base) >> 19; + w19 |= (in[22] - base) << 38; + w20 = (in[22] - base) >> 26; + w20 |= (in[23] - base) << 31; + w21 = (in[23] - base) >> 33; + w21 |= (in[24] - base) << 24; + w22 = (in[24] - base) >> 40; + w22 |= (in[25] - base) << 17; + w23 = (in[25] - base) >> 47; + w23 |= (in[26] - base) << 10; + w24 = (in[26] - base) >> 54; + w24 |= (in[27] - base) << 3; + w24 |= (in[28] - base) << 60; + w25 = (in[28] - base) >> 4; + w25 |= (in[29] - base) << 53; + w26 = (in[29] - base) >> 11; + w26 |= (in[30] - base) << 46; + w27 = (in[30] - base) >> 18; + w27 |= (in[31] - base) << 39; + w28 = (in[31] - base) >> 25; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 228; /* we used up 228 output bytes */ +} + + +/* we are going to pack 32 58-bit values, touching 29 64-bit words, using 232 bytes */ +static void packforblock58_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 29 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 58; + w1 = (in[1] - base) >> 6; + w1 |= (in[2] - base) << 52; + w2 = (in[2] - base) >> 12; + w2 |= (in[3] - base) << 46; + w3 = (in[3] - base) >> 18; + w3 |= (in[4] - base) << 40; + w4 = (in[4] - base) >> 24; + w4 |= (in[5] - base) << 34; + w5 = (in[5] - base) >> 30; + w5 |= (in[6] - base) << 28; + w6 = (in[6] - base) >> 36; + w6 |= (in[7] - base) << 22; + w7 = (in[7] - base) >> 42; + w7 |= (in[8] - base) << 16; + w8 = (in[8] - base) >> 48; + w8 |= (in[9] - base) << 10; + w9 = (in[9] - base) >> 54; + w9 |= (in[10] - base) << 4; + w9 |= (in[11] - base) << 62; + w10 = (in[11] - base) >> 2; + w10 |= (in[12] - base) << 56; + w11 = (in[12] - base) >> 8; + w11 |= (in[13] - base) << 50; + w12 = (in[13] - base) >> 14; + w12 |= (in[14] - base) << 44; + w13 = (in[14] - base) >> 20; + w13 |= (in[15] - base) << 38; + w14 = (in[15] - base) >> 26; + w14 |= (in[16] - base) << 32; + w15 = (in[16] - base) >> 32; + w15 |= (in[17] - base) << 26; + w16 = (in[17] - base) >> 38; + w16 |= (in[18] - base) << 20; + w17 = (in[18] - base) >> 44; + w17 |= (in[19] - base) << 14; + w18 = (in[19] - base) >> 50; + w18 |= (in[20] - base) << 8; + w19 = (in[20] - base) >> 56; + w19 |= (in[21] - base) << 2; + w19 |= (in[22] - base) << 60; + w20 = (in[22] - base) >> 4; + w20 |= (in[23] - base) << 54; + w21 = (in[23] - base) >> 10; + w21 |= (in[24] - base) << 48; + w22 = (in[24] - base) >> 16; + w22 |= (in[25] - base) << 42; + w23 = (in[25] - base) >> 22; + w23 |= (in[26] - base) << 36; + w24 = (in[26] - base) >> 28; + w24 |= (in[27] - base) << 30; + w25 = (in[27] - base) >> 34; + w25 |= (in[28] - base) << 24; + w26 = (in[28] - base) >> 40; + w26 |= (in[29] - base) << 18; + w27 = (in[29] - base) >> 46; + w27 |= (in[30] - base) << 12; + w28 = (in[30] - base) >> 52; + w28 |= (in[31] - base) << 6; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 232; /* we used up 232 output bytes */ +} + + +/* we are going to pack 32 59-bit values, touching 30 64-bit words, using 236 bytes */ +static void packforblock59_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 30 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 59; + w1 = (in[1] - base) >> 5; + w1 |= (in[2] - base) << 54; + w2 = (in[2] - base) >> 10; + w2 |= (in[3] - base) << 49; + w3 = (in[3] - base) >> 15; + w3 |= (in[4] - base) << 44; + w4 = (in[4] - base) >> 20; + w4 |= (in[5] - base) << 39; + w5 = (in[5] - base) >> 25; + w5 |= (in[6] - base) << 34; + w6 = (in[6] - base) >> 30; + w6 |= (in[7] - base) << 29; + w7 = (in[7] - base) >> 35; + w7 |= (in[8] - base) << 24; + w8 = (in[8] - base) >> 40; + w8 |= (in[9] - base) << 19; + w9 = (in[9] - base) >> 45; + w9 |= (in[10] - base) << 14; + w10 = (in[10] - base) >> 50; + w10 |= (in[11] - base) << 9; + w11 = (in[11] - base) >> 55; + w11 |= (in[12] - base) << 4; + w11 |= (in[13] - base) << 63; + w12 = (in[13] - base) >> 1; + w12 |= (in[14] - base) << 58; + w13 = (in[14] - base) >> 6; + w13 |= (in[15] - base) << 53; + w14 = (in[15] - base) >> 11; + w14 |= (in[16] - base) << 48; + w15 = (in[16] - base) >> 16; + w15 |= (in[17] - base) << 43; + w16 = (in[17] - base) >> 21; + w16 |= (in[18] - base) << 38; + w17 = (in[18] - base) >> 26; + w17 |= (in[19] - base) << 33; + w18 = (in[19] - base) >> 31; + w18 |= (in[20] - base) << 28; + w19 = (in[20] - base) >> 36; + w19 |= (in[21] - base) << 23; + w20 = (in[21] - base) >> 41; + w20 |= (in[22] - base) << 18; + w21 = (in[22] - base) >> 46; + w21 |= (in[23] - base) << 13; + w22 = (in[23] - base) >> 51; + w22 |= (in[24] - base) << 8; + w23 = (in[24] - base) >> 56; + w23 |= (in[25] - base) << 3; + w23 |= (in[26] - base) << 62; + w24 = (in[26] - base) >> 2; + w24 |= (in[27] - base) << 57; + w25 = (in[27] - base) >> 7; + w25 |= (in[28] - base) << 52; + w26 = (in[28] - base) >> 12; + w26 |= (in[29] - base) << 47; + w27 = (in[29] - base) >> 17; + w27 |= (in[30] - base) << 42; + w28 = (in[30] - base) >> 22; + w28 |= (in[31] - base) << 37; + w29 = (in[31] - base) >> 27; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 236; /* we used up 236 output bytes */ +} + + +/* we are going to pack 32 60-bit values, touching 30 64-bit words, using 240 bytes */ +static void packforblock60_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 30 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 60; + w1 = (in[1] - base) >> 4; + w1 |= (in[2] - base) << 56; + w2 = (in[2] - base) >> 8; + w2 |= (in[3] - base) << 52; + w3 = (in[3] - base) >> 12; + w3 |= (in[4] - base) << 48; + w4 = (in[4] - base) >> 16; + w4 |= (in[5] - base) << 44; + w5 = (in[5] - base) >> 20; + w5 |= (in[6] - base) << 40; + w6 = (in[6] - base) >> 24; + w6 |= (in[7] - base) << 36; + w7 = (in[7] - base) >> 28; + w7 |= (in[8] - base) << 32; + w8 = (in[8] - base) >> 32; + w8 |= (in[9] - base) << 28; + w9 = (in[9] - base) >> 36; + w9 |= (in[10] - base) << 24; + w10 = (in[10] - base) >> 40; + w10 |= (in[11] - base) << 20; + w11 = (in[11] - base) >> 44; + w11 |= (in[12] - base) << 16; + w12 = (in[12] - base) >> 48; + w12 |= (in[13] - base) << 12; + w13 = (in[13] - base) >> 52; + w13 |= (in[14] - base) << 8; + w14 = (in[14] - base) >> 56; + w14 |= (in[15] - base) << 4; + w15 = (in[16] - base); + w15 |= (in[17] - base) << 60; + w16 = (in[17] - base) >> 4; + w16 |= (in[18] - base) << 56; + w17 = (in[18] - base) >> 8; + w17 |= (in[19] - base) << 52; + w18 = (in[19] - base) >> 12; + w18 |= (in[20] - base) << 48; + w19 = (in[20] - base) >> 16; + w19 |= (in[21] - base) << 44; + w20 = (in[21] - base) >> 20; + w20 |= (in[22] - base) << 40; + w21 = (in[22] - base) >> 24; + w21 |= (in[23] - base) << 36; + w22 = (in[23] - base) >> 28; + w22 |= (in[24] - base) << 32; + w23 = (in[24] - base) >> 32; + w23 |= (in[25] - base) << 28; + w24 = (in[25] - base) >> 36; + w24 |= (in[26] - base) << 24; + w25 = (in[26] - base) >> 40; + w25 |= (in[27] - base) << 20; + w26 = (in[27] - base) >> 44; + w26 |= (in[28] - base) << 16; + w27 = (in[28] - base) >> 48; + w27 |= (in[29] - base) << 12; + w28 = (in[29] - base) >> 52; + w28 |= (in[30] - base) << 8; + w29 = (in[30] - base) >> 56; + w29 |= (in[31] - base) << 4; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 240; /* we used up 240 output bytes */ +} + + +/* we are going to pack 32 61-bit values, touching 31 64-bit words, using 244 bytes */ +static void packforblock61_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 31 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + uint64_t w30; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 61; + w1 = (in[1] - base) >> 3; + w1 |= (in[2] - base) << 58; + w2 = (in[2] - base) >> 6; + w2 |= (in[3] - base) << 55; + w3 = (in[3] - base) >> 9; + w3 |= (in[4] - base) << 52; + w4 = (in[4] - base) >> 12; + w4 |= (in[5] - base) << 49; + w5 = (in[5] - base) >> 15; + w5 |= (in[6] - base) << 46; + w6 = (in[6] - base) >> 18; + w6 |= (in[7] - base) << 43; + w7 = (in[7] - base) >> 21; + w7 |= (in[8] - base) << 40; + w8 = (in[8] - base) >> 24; + w8 |= (in[9] - base) << 37; + w9 = (in[9] - base) >> 27; + w9 |= (in[10] - base) << 34; + w10 = (in[10] - base) >> 30; + w10 |= (in[11] - base) << 31; + w11 = (in[11] - base) >> 33; + w11 |= (in[12] - base) << 28; + w12 = (in[12] - base) >> 36; + w12 |= (in[13] - base) << 25; + w13 = (in[13] - base) >> 39; + w13 |= (in[14] - base) << 22; + w14 = (in[14] - base) >> 42; + w14 |= (in[15] - base) << 19; + w15 = (in[15] - base) >> 45; + w15 |= (in[16] - base) << 16; + w16 = (in[16] - base) >> 48; + w16 |= (in[17] - base) << 13; + w17 = (in[17] - base) >> 51; + w17 |= (in[18] - base) << 10; + w18 = (in[18] - base) >> 54; + w18 |= (in[19] - base) << 7; + w19 = (in[19] - base) >> 57; + w19 |= (in[20] - base) << 4; + w20 = (in[20] - base) >> 60; + w20 |= (in[21] - base) << 1; + w20 |= (in[22] - base) << 62; + w21 = (in[22] - base) >> 2; + w21 |= (in[23] - base) << 59; + w22 = (in[23] - base) >> 5; + w22 |= (in[24] - base) << 56; + w23 = (in[24] - base) >> 8; + w23 |= (in[25] - base) << 53; + w24 = (in[25] - base) >> 11; + w24 |= (in[26] - base) << 50; + w25 = (in[26] - base) >> 14; + w25 |= (in[27] - base) << 47; + w26 = (in[27] - base) >> 17; + w26 |= (in[28] - base) << 44; + w27 = (in[28] - base) >> 20; + w27 |= (in[29] - base) << 41; + w28 = (in[29] - base) >> 23; + w28 |= (in[30] - base) << 38; + w29 = (in[30] - base) >> 26; + w29 |= (in[31] - base) << 35; + w30 = (in[31] - base) >> 29; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + pw64[30] = w30; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 244; /* we used up 244 output bytes */ +} + + +/* we are going to pack 32 62-bit values, touching 31 64-bit words, using 248 bytes */ +static void packforblock62_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 31 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + uint64_t w30; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 62; + w1 = (in[1] - base) >> 2; + w1 |= (in[2] - base) << 60; + w2 = (in[2] - base) >> 4; + w2 |= (in[3] - base) << 58; + w3 = (in[3] - base) >> 6; + w3 |= (in[4] - base) << 56; + w4 = (in[4] - base) >> 8; + w4 |= (in[5] - base) << 54; + w5 = (in[5] - base) >> 10; + w5 |= (in[6] - base) << 52; + w6 = (in[6] - base) >> 12; + w6 |= (in[7] - base) << 50; + w7 = (in[7] - base) >> 14; + w7 |= (in[8] - base) << 48; + w8 = (in[8] - base) >> 16; + w8 |= (in[9] - base) << 46; + w9 = (in[9] - base) >> 18; + w9 |= (in[10] - base) << 44; + w10 = (in[10] - base) >> 20; + w10 |= (in[11] - base) << 42; + w11 = (in[11] - base) >> 22; + w11 |= (in[12] - base) << 40; + w12 = (in[12] - base) >> 24; + w12 |= (in[13] - base) << 38; + w13 = (in[13] - base) >> 26; + w13 |= (in[14] - base) << 36; + w14 = (in[14] - base) >> 28; + w14 |= (in[15] - base) << 34; + w15 = (in[15] - base) >> 30; + w15 |= (in[16] - base) << 32; + w16 = (in[16] - base) >> 32; + w16 |= (in[17] - base) << 30; + w17 = (in[17] - base) >> 34; + w17 |= (in[18] - base) << 28; + w18 = (in[18] - base) >> 36; + w18 |= (in[19] - base) << 26; + w19 = (in[19] - base) >> 38; + w19 |= (in[20] - base) << 24; + w20 = (in[20] - base) >> 40; + w20 |= (in[21] - base) << 22; + w21 = (in[21] - base) >> 42; + w21 |= (in[22] - base) << 20; + w22 = (in[22] - base) >> 44; + w22 |= (in[23] - base) << 18; + w23 = (in[23] - base) >> 46; + w23 |= (in[24] - base) << 16; + w24 = (in[24] - base) >> 48; + w24 |= (in[25] - base) << 14; + w25 = (in[25] - base) >> 50; + w25 |= (in[26] - base) << 12; + w26 = (in[26] - base) >> 52; + w26 |= (in[27] - base) << 10; + w27 = (in[27] - base) >> 54; + w27 |= (in[28] - base) << 8; + w28 = (in[28] - base) >> 56; + w28 |= (in[29] - base) << 6; + w29 = (in[29] - base) >> 58; + w29 |= (in[30] - base) << 4; + w30 = (in[30] - base) >> 60; + w30 |= (in[31] - base) << 2; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + pw64[30] = w30; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 248; /* we used up 248 output bytes */ +} + + +/* we are going to pack 32 63-bit values, touching 32 64-bit words, using 252 bytes */ +static void packforblock63_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 32 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + uint64_t w30; + uint64_t w31; + w0 = (in[0] - base); + w0 |= (in[1] - base) << 63; + w1 = (in[1] - base) >> 1; + w1 |= (in[2] - base) << 62; + w2 = (in[2] - base) >> 2; + w2 |= (in[3] - base) << 61; + w3 = (in[3] - base) >> 3; + w3 |= (in[4] - base) << 60; + w4 = (in[4] - base) >> 4; + w4 |= (in[5] - base) << 59; + w5 = (in[5] - base) >> 5; + w5 |= (in[6] - base) << 58; + w6 = (in[6] - base) >> 6; + w6 |= (in[7] - base) << 57; + w7 = (in[7] - base) >> 7; + w7 |= (in[8] - base) << 56; + w8 = (in[8] - base) >> 8; + w8 |= (in[9] - base) << 55; + w9 = (in[9] - base) >> 9; + w9 |= (in[10] - base) << 54; + w10 = (in[10] - base) >> 10; + w10 |= (in[11] - base) << 53; + w11 = (in[11] - base) >> 11; + w11 |= (in[12] - base) << 52; + w12 = (in[12] - base) >> 12; + w12 |= (in[13] - base) << 51; + w13 = (in[13] - base) >> 13; + w13 |= (in[14] - base) << 50; + w14 = (in[14] - base) >> 14; + w14 |= (in[15] - base) << 49; + w15 = (in[15] - base) >> 15; + w15 |= (in[16] - base) << 48; + w16 = (in[16] - base) >> 16; + w16 |= (in[17] - base) << 47; + w17 = (in[17] - base) >> 17; + w17 |= (in[18] - base) << 46; + w18 = (in[18] - base) >> 18; + w18 |= (in[19] - base) << 45; + w19 = (in[19] - base) >> 19; + w19 |= (in[20] - base) << 44; + w20 = (in[20] - base) >> 20; + w20 |= (in[21] - base) << 43; + w21 = (in[21] - base) >> 21; + w21 |= (in[22] - base) << 42; + w22 = (in[22] - base) >> 22; + w22 |= (in[23] - base) << 41; + w23 = (in[23] - base) >> 23; + w23 |= (in[24] - base) << 40; + w24 = (in[24] - base) >> 24; + w24 |= (in[25] - base) << 39; + w25 = (in[25] - base) >> 25; + w25 |= (in[26] - base) << 38; + w26 = (in[26] - base) >> 26; + w26 |= (in[27] - base) << 37; + w27 = (in[27] - base) >> 27; + w27 |= (in[28] - base) << 36; + w28 = (in[28] - base) >> 28; + w28 |= (in[29] - base) << 35; + w29 = (in[29] - base) >> 29; + w29 |= (in[30] - base) << 34; + w30 = (in[30] - base) >> 30; + w30 |= (in[31] - base) << 33; + w31 = (in[31] - base) >> 31; + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + pw64[30] = w30; + pw64[31] = w31; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 252; /* we used up 252 output bytes */ +} + + +/* we are going to pack 32 64-bit values, touching 32 64-bit words, using 256 bytes */ +static void packforblock64_64(const uint64_t base, const uint64_t ** pin, uint8_t ** pw) { + uint64_t * pw64 = *(uint64_t **) pw; + const uint64_t * in = *pin; + /* we are going to touch 32 64-bit words */ + uint64_t w0; + uint64_t w1; + uint64_t w2; + uint64_t w3; + uint64_t w4; + uint64_t w5; + uint64_t w6; + uint64_t w7; + uint64_t w8; + uint64_t w9; + uint64_t w10; + uint64_t w11; + uint64_t w12; + uint64_t w13; + uint64_t w14; + uint64_t w15; + uint64_t w16; + uint64_t w17; + uint64_t w18; + uint64_t w19; + uint64_t w20; + uint64_t w21; + uint64_t w22; + uint64_t w23; + uint64_t w24; + uint64_t w25; + uint64_t w26; + uint64_t w27; + uint64_t w28; + uint64_t w29; + uint64_t w30; + uint64_t w31; + w0 = (in[0] - base); + w1 = (in[1] - base); + w2 = (in[2] - base); + w3 = (in[3] - base); + w4 = (in[4] - base); + w5 = (in[5] - base); + w6 = (in[6] - base); + w7 = (in[7] - base); + w8 = (in[8] - base); + w9 = (in[9] - base); + w10 = (in[10] - base); + w11 = (in[11] - base); + w12 = (in[12] - base); + w13 = (in[13] - base); + w14 = (in[14] - base); + w15 = (in[15] - base); + w16 = (in[16] - base); + w17 = (in[17] - base); + w18 = (in[18] - base); + w19 = (in[19] - base); + w20 = (in[20] - base); + w21 = (in[21] - base); + w22 = (in[22] - base); + w23 = (in[23] - base); + w24 = (in[24] - base); + w25 = (in[25] - base); + w26 = (in[26] - base); + w27 = (in[27] - base); + w28 = (in[28] - base); + w29 = (in[29] - base); + w30 = (in[30] - base); + w31 = (in[31] - base); + pw64[0] = w0; + pw64[1] = w1; + pw64[2] = w2; + pw64[3] = w3; + pw64[4] = w4; + pw64[5] = w5; + pw64[6] = w6; + pw64[7] = w7; + pw64[8] = w8; + pw64[9] = w9; + pw64[10] = w10; + pw64[11] = w11; + pw64[12] = w12; + pw64[13] = w13; + pw64[14] = w14; + pw64[15] = w15; + pw64[16] = w16; + pw64[17] = w17; + pw64[18] = w18; + pw64[19] = w19; + pw64[20] = w20; + pw64[21] = w21; + pw64[22] = w22; + pw64[23] = w23; + pw64[24] = w24; + pw64[25] = w25; + pw64[26] = w26; + pw64[27] = w27; + pw64[28] = w28; + pw64[29] = w29; + pw64[30] = w30; + pw64[31] = w31; + *pin += 32; /* we consumed 32 64-bit integers */ + *pw += 256; /* we used up 256 output bytes */ +} + +static void unpackforblock0_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + (void) pw; + for(int k = 0; k < 32 ; k+= 1) { + (*pout) [k] = base; + } + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 1-bit values, touching 1 64-bit words, using 4 bytes */ +static void unpackforblock1_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1); + /* we are going to access 1 64-bit word */ + uint64_t w0 = pw64[0]; + *pw += 4; /* we used up 4 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 1 ) & mask ); + out[2] = base + ( ( w0 >> 2 ) & mask ); + out[3] = base + ( ( w0 >> 3 ) & mask ); + out[4] = base + ( ( w0 >> 4 ) & mask ); + out[5] = base + ( ( w0 >> 5 ) & mask ); + out[6] = base + ( ( w0 >> 6 ) & mask ); + out[7] = base + ( ( w0 >> 7 ) & mask ); + out[8] = base + ( ( w0 >> 8 ) & mask ); + out[9] = base + ( ( w0 >> 9 ) & mask ); + out[10] = base + ( ( w0 >> 10 ) & mask ); + out[11] = base + ( ( w0 >> 11 ) & mask ); + out[12] = base + ( ( w0 >> 12 ) & mask ); + out[13] = base + ( ( w0 >> 13 ) & mask ); + out[14] = base + ( ( w0 >> 14 ) & mask ); + out[15] = base + ( ( w0 >> 15 ) & mask ); + out[16] = base + ( ( w0 >> 16 ) & mask ); + out[17] = base + ( ( w0 >> 17 ) & mask ); + out[18] = base + ( ( w0 >> 18 ) & mask ); + out[19] = base + ( ( w0 >> 19 ) & mask ); + out[20] = base + ( ( w0 >> 20 ) & mask ); + out[21] = base + ( ( w0 >> 21 ) & mask ); + out[22] = base + ( ( w0 >> 22 ) & mask ); + out[23] = base + ( ( w0 >> 23 ) & mask ); + out[24] = base + ( ( w0 >> 24 ) & mask ); + out[25] = base + ( ( w0 >> 25 ) & mask ); + out[26] = base + ( ( w0 >> 26 ) & mask ); + out[27] = base + ( ( w0 >> 27 ) & mask ); + out[28] = base + ( ( w0 >> 28 ) & mask ); + out[29] = base + ( ( w0 >> 29 ) & mask ); + out[30] = base + ( ( w0 >> 30 ) & mask ); + out[31] = base + ( ( w0 >> 31 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 2-bit values, touching 1 64-bit words, using 8 bytes */ +static void unpackforblock2_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(3); + /* we are going to access 1 64-bit word */ + uint64_t w0 = pw64[0]; + *pw += 8; /* we used up 8 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 2 ) & mask ); + out[2] = base + ( ( w0 >> 4 ) & mask ); + out[3] = base + ( ( w0 >> 6 ) & mask ); + out[4] = base + ( ( w0 >> 8 ) & mask ); + out[5] = base + ( ( w0 >> 10 ) & mask ); + out[6] = base + ( ( w0 >> 12 ) & mask ); + out[7] = base + ( ( w0 >> 14 ) & mask ); + out[8] = base + ( ( w0 >> 16 ) & mask ); + out[9] = base + ( ( w0 >> 18 ) & mask ); + out[10] = base + ( ( w0 >> 20 ) & mask ); + out[11] = base + ( ( w0 >> 22 ) & mask ); + out[12] = base + ( ( w0 >> 24 ) & mask ); + out[13] = base + ( ( w0 >> 26 ) & mask ); + out[14] = base + ( ( w0 >> 28 ) & mask ); + out[15] = base + ( ( w0 >> 30 ) & mask ); + out[16] = base + ( ( w0 >> 32 ) & mask ); + out[17] = base + ( ( w0 >> 34 ) & mask ); + out[18] = base + ( ( w0 >> 36 ) & mask ); + out[19] = base + ( ( w0 >> 38 ) & mask ); + out[20] = base + ( ( w0 >> 40 ) & mask ); + out[21] = base + ( ( w0 >> 42 ) & mask ); + out[22] = base + ( ( w0 >> 44 ) & mask ); + out[23] = base + ( ( w0 >> 46 ) & mask ); + out[24] = base + ( ( w0 >> 48 ) & mask ); + out[25] = base + ( ( w0 >> 50 ) & mask ); + out[26] = base + ( ( w0 >> 52 ) & mask ); + out[27] = base + ( ( w0 >> 54 ) & mask ); + out[28] = base + ( ( w0 >> 56 ) & mask ); + out[29] = base + ( ( w0 >> 58 ) & mask ); + out[30] = base + ( ( w0 >> 60 ) & mask ); + out[31] = base + ( w0 >> 62 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 3-bit values, touching 2 64-bit words, using 12 bytes */ +static void unpackforblock3_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(7); + /* we are going to access 2 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + *pw += 12; /* we used up 12 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 3 ) & mask ); + out[2] = base + ( ( w0 >> 6 ) & mask ); + out[3] = base + ( ( w0 >> 9 ) & mask ); + out[4] = base + ( ( w0 >> 12 ) & mask ); + out[5] = base + ( ( w0 >> 15 ) & mask ); + out[6] = base + ( ( w0 >> 18 ) & mask ); + out[7] = base + ( ( w0 >> 21 ) & mask ); + out[8] = base + ( ( w0 >> 24 ) & mask ); + out[9] = base + ( ( w0 >> 27 ) & mask ); + out[10] = base + ( ( w0 >> 30 ) & mask ); + out[11] = base + ( ( w0 >> 33 ) & mask ); + out[12] = base + ( ( w0 >> 36 ) & mask ); + out[13] = base + ( ( w0 >> 39 ) & mask ); + out[14] = base + ( ( w0 >> 42 ) & mask ); + out[15] = base + ( ( w0 >> 45 ) & mask ); + out[16] = base + ( ( w0 >> 48 ) & mask ); + out[17] = base + ( ( w0 >> 51 ) & mask ); + out[18] = base + ( ( w0 >> 54 ) & mask ); + out[19] = base + ( ( w0 >> 57 ) & mask ); + out[20] = base + ( ( w0 >> 60 ) & mask ); + out[21] = base + ( ( ( w0 >> 63 ) | ( w1 << 1 ) ) & mask ); + out[22] = base + ( ( w1 >> 2 ) & mask ); + out[23] = base + ( ( w1 >> 5 ) & mask ); + out[24] = base + ( ( w1 >> 8 ) & mask ); + out[25] = base + ( ( w1 >> 11 ) & mask ); + out[26] = base + ( ( w1 >> 14 ) & mask ); + out[27] = base + ( ( w1 >> 17 ) & mask ); + out[28] = base + ( ( w1 >> 20 ) & mask ); + out[29] = base + ( ( w1 >> 23 ) & mask ); + out[30] = base + ( ( w1 >> 26 ) & mask ); + out[31] = base + ( ( w1 >> 29 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 4-bit values, touching 2 64-bit words, using 16 bytes */ +static void unpackforblock4_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(15); + /* we are going to access 2 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + *pw += 16; /* we used up 16 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 4 ) & mask ); + out[2] = base + ( ( w0 >> 8 ) & mask ); + out[3] = base + ( ( w0 >> 12 ) & mask ); + out[4] = base + ( ( w0 >> 16 ) & mask ); + out[5] = base + ( ( w0 >> 20 ) & mask ); + out[6] = base + ( ( w0 >> 24 ) & mask ); + out[7] = base + ( ( w0 >> 28 ) & mask ); + out[8] = base + ( ( w0 >> 32 ) & mask ); + out[9] = base + ( ( w0 >> 36 ) & mask ); + out[10] = base + ( ( w0 >> 40 ) & mask ); + out[11] = base + ( ( w0 >> 44 ) & mask ); + out[12] = base + ( ( w0 >> 48 ) & mask ); + out[13] = base + ( ( w0 >> 52 ) & mask ); + out[14] = base + ( ( w0 >> 56 ) & mask ); + out[15] = base + ( w0 >> 60 ); + out[16] = base + ( ( w1 ) & mask ); + out[17] = base + ( ( w1 >> 4 ) & mask ); + out[18] = base + ( ( w1 >> 8 ) & mask ); + out[19] = base + ( ( w1 >> 12 ) & mask ); + out[20] = base + ( ( w1 >> 16 ) & mask ); + out[21] = base + ( ( w1 >> 20 ) & mask ); + out[22] = base + ( ( w1 >> 24 ) & mask ); + out[23] = base + ( ( w1 >> 28 ) & mask ); + out[24] = base + ( ( w1 >> 32 ) & mask ); + out[25] = base + ( ( w1 >> 36 ) & mask ); + out[26] = base + ( ( w1 >> 40 ) & mask ); + out[27] = base + ( ( w1 >> 44 ) & mask ); + out[28] = base + ( ( w1 >> 48 ) & mask ); + out[29] = base + ( ( w1 >> 52 ) & mask ); + out[30] = base + ( ( w1 >> 56 ) & mask ); + out[31] = base + ( w1 >> 60 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 5-bit values, touching 3 64-bit words, using 20 bytes */ +static void unpackforblock5_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(31); + /* we are going to access 3 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + *pw += 20; /* we used up 20 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 5 ) & mask ); + out[2] = base + ( ( w0 >> 10 ) & mask ); + out[3] = base + ( ( w0 >> 15 ) & mask ); + out[4] = base + ( ( w0 >> 20 ) & mask ); + out[5] = base + ( ( w0 >> 25 ) & mask ); + out[6] = base + ( ( w0 >> 30 ) & mask ); + out[7] = base + ( ( w0 >> 35 ) & mask ); + out[8] = base + ( ( w0 >> 40 ) & mask ); + out[9] = base + ( ( w0 >> 45 ) & mask ); + out[10] = base + ( ( w0 >> 50 ) & mask ); + out[11] = base + ( ( w0 >> 55 ) & mask ); + out[12] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[13] = base + ( ( w1 >> 1 ) & mask ); + out[14] = base + ( ( w1 >> 6 ) & mask ); + out[15] = base + ( ( w1 >> 11 ) & mask ); + out[16] = base + ( ( w1 >> 16 ) & mask ); + out[17] = base + ( ( w1 >> 21 ) & mask ); + out[18] = base + ( ( w1 >> 26 ) & mask ); + out[19] = base + ( ( w1 >> 31 ) & mask ); + out[20] = base + ( ( w1 >> 36 ) & mask ); + out[21] = base + ( ( w1 >> 41 ) & mask ); + out[22] = base + ( ( w1 >> 46 ) & mask ); + out[23] = base + ( ( w1 >> 51 ) & mask ); + out[24] = base + ( ( w1 >> 56 ) & mask ); + out[25] = base + ( ( ( w1 >> 61 ) | ( w2 << 3 ) ) & mask ); + out[26] = base + ( ( w2 >> 2 ) & mask ); + out[27] = base + ( ( w2 >> 7 ) & mask ); + out[28] = base + ( ( w2 >> 12 ) & mask ); + out[29] = base + ( ( w2 >> 17 ) & mask ); + out[30] = base + ( ( w2 >> 22 ) & mask ); + out[31] = base + ( ( w2 >> 27 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 6-bit values, touching 3 64-bit words, using 24 bytes */ +static void unpackforblock6_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(63); + /* we are going to access 3 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + *pw += 24; /* we used up 24 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 6 ) & mask ); + out[2] = base + ( ( w0 >> 12 ) & mask ); + out[3] = base + ( ( w0 >> 18 ) & mask ); + out[4] = base + ( ( w0 >> 24 ) & mask ); + out[5] = base + ( ( w0 >> 30 ) & mask ); + out[6] = base + ( ( w0 >> 36 ) & mask ); + out[7] = base + ( ( w0 >> 42 ) & mask ); + out[8] = base + ( ( w0 >> 48 ) & mask ); + out[9] = base + ( ( w0 >> 54 ) & mask ); + out[10] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[11] = base + ( ( w1 >> 2 ) & mask ); + out[12] = base + ( ( w1 >> 8 ) & mask ); + out[13] = base + ( ( w1 >> 14 ) & mask ); + out[14] = base + ( ( w1 >> 20 ) & mask ); + out[15] = base + ( ( w1 >> 26 ) & mask ); + out[16] = base + ( ( w1 >> 32 ) & mask ); + out[17] = base + ( ( w1 >> 38 ) & mask ); + out[18] = base + ( ( w1 >> 44 ) & mask ); + out[19] = base + ( ( w1 >> 50 ) & mask ); + out[20] = base + ( ( w1 >> 56 ) & mask ); + out[21] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[22] = base + ( ( w2 >> 4 ) & mask ); + out[23] = base + ( ( w2 >> 10 ) & mask ); + out[24] = base + ( ( w2 >> 16 ) & mask ); + out[25] = base + ( ( w2 >> 22 ) & mask ); + out[26] = base + ( ( w2 >> 28 ) & mask ); + out[27] = base + ( ( w2 >> 34 ) & mask ); + out[28] = base + ( ( w2 >> 40 ) & mask ); + out[29] = base + ( ( w2 >> 46 ) & mask ); + out[30] = base + ( ( w2 >> 52 ) & mask ); + out[31] = base + ( w2 >> 58 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 7-bit values, touching 4 64-bit words, using 28 bytes */ +static void unpackforblock7_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(127); + /* we are going to access 4 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + *pw += 28; /* we used up 28 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 7 ) & mask ); + out[2] = base + ( ( w0 >> 14 ) & mask ); + out[3] = base + ( ( w0 >> 21 ) & mask ); + out[4] = base + ( ( w0 >> 28 ) & mask ); + out[5] = base + ( ( w0 >> 35 ) & mask ); + out[6] = base + ( ( w0 >> 42 ) & mask ); + out[7] = base + ( ( w0 >> 49 ) & mask ); + out[8] = base + ( ( w0 >> 56 ) & mask ); + out[9] = base + ( ( ( w0 >> 63 ) | ( w1 << 1 ) ) & mask ); + out[10] = base + ( ( w1 >> 6 ) & mask ); + out[11] = base + ( ( w1 >> 13 ) & mask ); + out[12] = base + ( ( w1 >> 20 ) & mask ); + out[13] = base + ( ( w1 >> 27 ) & mask ); + out[14] = base + ( ( w1 >> 34 ) & mask ); + out[15] = base + ( ( w1 >> 41 ) & mask ); + out[16] = base + ( ( w1 >> 48 ) & mask ); + out[17] = base + ( ( w1 >> 55 ) & mask ); + out[18] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[19] = base + ( ( w2 >> 5 ) & mask ); + out[20] = base + ( ( w2 >> 12 ) & mask ); + out[21] = base + ( ( w2 >> 19 ) & mask ); + out[22] = base + ( ( w2 >> 26 ) & mask ); + out[23] = base + ( ( w2 >> 33 ) & mask ); + out[24] = base + ( ( w2 >> 40 ) & mask ); + out[25] = base + ( ( w2 >> 47 ) & mask ); + out[26] = base + ( ( w2 >> 54 ) & mask ); + out[27] = base + ( ( ( w2 >> 61 ) | ( w3 << 3 ) ) & mask ); + out[28] = base + ( ( w3 >> 4 ) & mask ); + out[29] = base + ( ( w3 >> 11 ) & mask ); + out[30] = base + ( ( w3 >> 18 ) & mask ); + out[31] = base + ( ( w3 >> 25 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 8-bit values, touching 4 64-bit words, using 32 bytes */ +static void unpackforblock8_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(255); + /* we are going to access 4 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + *pw += 32; /* we used up 32 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 8 ) & mask ); + out[2] = base + ( ( w0 >> 16 ) & mask ); + out[3] = base + ( ( w0 >> 24 ) & mask ); + out[4] = base + ( ( w0 >> 32 ) & mask ); + out[5] = base + ( ( w0 >> 40 ) & mask ); + out[6] = base + ( ( w0 >> 48 ) & mask ); + out[7] = base + ( w0 >> 56 ); + out[8] = base + ( ( w1 ) & mask ); + out[9] = base + ( ( w1 >> 8 ) & mask ); + out[10] = base + ( ( w1 >> 16 ) & mask ); + out[11] = base + ( ( w1 >> 24 ) & mask ); + out[12] = base + ( ( w1 >> 32 ) & mask ); + out[13] = base + ( ( w1 >> 40 ) & mask ); + out[14] = base + ( ( w1 >> 48 ) & mask ); + out[15] = base + ( w1 >> 56 ); + out[16] = base + ( ( w2 ) & mask ); + out[17] = base + ( ( w2 >> 8 ) & mask ); + out[18] = base + ( ( w2 >> 16 ) & mask ); + out[19] = base + ( ( w2 >> 24 ) & mask ); + out[20] = base + ( ( w2 >> 32 ) & mask ); + out[21] = base + ( ( w2 >> 40 ) & mask ); + out[22] = base + ( ( w2 >> 48 ) & mask ); + out[23] = base + ( w2 >> 56 ); + out[24] = base + ( ( w3 ) & mask ); + out[25] = base + ( ( w3 >> 8 ) & mask ); + out[26] = base + ( ( w3 >> 16 ) & mask ); + out[27] = base + ( ( w3 >> 24 ) & mask ); + out[28] = base + ( ( w3 >> 32 ) & mask ); + out[29] = base + ( ( w3 >> 40 ) & mask ); + out[30] = base + ( ( w3 >> 48 ) & mask ); + out[31] = base + ( w3 >> 56 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 9-bit values, touching 5 64-bit words, using 36 bytes */ +static void unpackforblock9_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(511); + /* we are going to access 5 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + *pw += 36; /* we used up 36 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 9 ) & mask ); + out[2] = base + ( ( w0 >> 18 ) & mask ); + out[3] = base + ( ( w0 >> 27 ) & mask ); + out[4] = base + ( ( w0 >> 36 ) & mask ); + out[5] = base + ( ( w0 >> 45 ) & mask ); + out[6] = base + ( ( w0 >> 54 ) & mask ); + out[7] = base + ( ( ( w0 >> 63 ) | ( w1 << 1 ) ) & mask ); + out[8] = base + ( ( w1 >> 8 ) & mask ); + out[9] = base + ( ( w1 >> 17 ) & mask ); + out[10] = base + ( ( w1 >> 26 ) & mask ); + out[11] = base + ( ( w1 >> 35 ) & mask ); + out[12] = base + ( ( w1 >> 44 ) & mask ); + out[13] = base + ( ( w1 >> 53 ) & mask ); + out[14] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[15] = base + ( ( w2 >> 7 ) & mask ); + out[16] = base + ( ( w2 >> 16 ) & mask ); + out[17] = base + ( ( w2 >> 25 ) & mask ); + out[18] = base + ( ( w2 >> 34 ) & mask ); + out[19] = base + ( ( w2 >> 43 ) & mask ); + out[20] = base + ( ( w2 >> 52 ) & mask ); + out[21] = base + ( ( ( w2 >> 61 ) | ( w3 << 3 ) ) & mask ); + out[22] = base + ( ( w3 >> 6 ) & mask ); + out[23] = base + ( ( w3 >> 15 ) & mask ); + out[24] = base + ( ( w3 >> 24 ) & mask ); + out[25] = base + ( ( w3 >> 33 ) & mask ); + out[26] = base + ( ( w3 >> 42 ) & mask ); + out[27] = base + ( ( w3 >> 51 ) & mask ); + out[28] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[29] = base + ( ( w4 >> 5 ) & mask ); + out[30] = base + ( ( w4 >> 14 ) & mask ); + out[31] = base + ( ( w4 >> 23 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 10-bit values, touching 5 64-bit words, using 40 bytes */ +static void unpackforblock10_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1023); + /* we are going to access 5 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + *pw += 40; /* we used up 40 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 10 ) & mask ); + out[2] = base + ( ( w0 >> 20 ) & mask ); + out[3] = base + ( ( w0 >> 30 ) & mask ); + out[4] = base + ( ( w0 >> 40 ) & mask ); + out[5] = base + ( ( w0 >> 50 ) & mask ); + out[6] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[7] = base + ( ( w1 >> 6 ) & mask ); + out[8] = base + ( ( w1 >> 16 ) & mask ); + out[9] = base + ( ( w1 >> 26 ) & mask ); + out[10] = base + ( ( w1 >> 36 ) & mask ); + out[11] = base + ( ( w1 >> 46 ) & mask ); + out[12] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[13] = base + ( ( w2 >> 2 ) & mask ); + out[14] = base + ( ( w2 >> 12 ) & mask ); + out[15] = base + ( ( w2 >> 22 ) & mask ); + out[16] = base + ( ( w2 >> 32 ) & mask ); + out[17] = base + ( ( w2 >> 42 ) & mask ); + out[18] = base + ( ( w2 >> 52 ) & mask ); + out[19] = base + ( ( ( w2 >> 62 ) | ( w3 << 2 ) ) & mask ); + out[20] = base + ( ( w3 >> 8 ) & mask ); + out[21] = base + ( ( w3 >> 18 ) & mask ); + out[22] = base + ( ( w3 >> 28 ) & mask ); + out[23] = base + ( ( w3 >> 38 ) & mask ); + out[24] = base + ( ( w3 >> 48 ) & mask ); + out[25] = base + ( ( ( w3 >> 58 ) | ( w4 << 6 ) ) & mask ); + out[26] = base + ( ( w4 >> 4 ) & mask ); + out[27] = base + ( ( w4 >> 14 ) & mask ); + out[28] = base + ( ( w4 >> 24 ) & mask ); + out[29] = base + ( ( w4 >> 34 ) & mask ); + out[30] = base + ( ( w4 >> 44 ) & mask ); + out[31] = base + ( w4 >> 54 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 11-bit values, touching 6 64-bit words, using 44 bytes */ +static void unpackforblock11_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2047); + /* we are going to access 6 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + *pw += 44; /* we used up 44 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 11 ) & mask ); + out[2] = base + ( ( w0 >> 22 ) & mask ); + out[3] = base + ( ( w0 >> 33 ) & mask ); + out[4] = base + ( ( w0 >> 44 ) & mask ); + out[5] = base + ( ( ( w0 >> 55 ) | ( w1 << 9 ) ) & mask ); + out[6] = base + ( ( w1 >> 2 ) & mask ); + out[7] = base + ( ( w1 >> 13 ) & mask ); + out[8] = base + ( ( w1 >> 24 ) & mask ); + out[9] = base + ( ( w1 >> 35 ) & mask ); + out[10] = base + ( ( w1 >> 46 ) & mask ); + out[11] = base + ( ( ( w1 >> 57 ) | ( w2 << 7 ) ) & mask ); + out[12] = base + ( ( w2 >> 4 ) & mask ); + out[13] = base + ( ( w2 >> 15 ) & mask ); + out[14] = base + ( ( w2 >> 26 ) & mask ); + out[15] = base + ( ( w2 >> 37 ) & mask ); + out[16] = base + ( ( w2 >> 48 ) & mask ); + out[17] = base + ( ( ( w2 >> 59 ) | ( w3 << 5 ) ) & mask ); + out[18] = base + ( ( w3 >> 6 ) & mask ); + out[19] = base + ( ( w3 >> 17 ) & mask ); + out[20] = base + ( ( w3 >> 28 ) & mask ); + out[21] = base + ( ( w3 >> 39 ) & mask ); + out[22] = base + ( ( w3 >> 50 ) & mask ); + out[23] = base + ( ( ( w3 >> 61 ) | ( w4 << 3 ) ) & mask ); + out[24] = base + ( ( w4 >> 8 ) & mask ); + out[25] = base + ( ( w4 >> 19 ) & mask ); + out[26] = base + ( ( w4 >> 30 ) & mask ); + out[27] = base + ( ( w4 >> 41 ) & mask ); + out[28] = base + ( ( w4 >> 52 ) & mask ); + out[29] = base + ( ( ( w4 >> 63 ) | ( w5 << 1 ) ) & mask ); + out[30] = base + ( ( w5 >> 10 ) & mask ); + out[31] = base + ( ( w5 >> 21 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 12-bit values, touching 6 64-bit words, using 48 bytes */ +static void unpackforblock12_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4095); + /* we are going to access 6 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + *pw += 48; /* we used up 48 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 12 ) & mask ); + out[2] = base + ( ( w0 >> 24 ) & mask ); + out[3] = base + ( ( w0 >> 36 ) & mask ); + out[4] = base + ( ( w0 >> 48 ) & mask ); + out[5] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[6] = base + ( ( w1 >> 8 ) & mask ); + out[7] = base + ( ( w1 >> 20 ) & mask ); + out[8] = base + ( ( w1 >> 32 ) & mask ); + out[9] = base + ( ( w1 >> 44 ) & mask ); + out[10] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[11] = base + ( ( w2 >> 4 ) & mask ); + out[12] = base + ( ( w2 >> 16 ) & mask ); + out[13] = base + ( ( w2 >> 28 ) & mask ); + out[14] = base + ( ( w2 >> 40 ) & mask ); + out[15] = base + ( w2 >> 52 ); + out[16] = base + ( ( w3 ) & mask ); + out[17] = base + ( ( w3 >> 12 ) & mask ); + out[18] = base + ( ( w3 >> 24 ) & mask ); + out[19] = base + ( ( w3 >> 36 ) & mask ); + out[20] = base + ( ( w3 >> 48 ) & mask ); + out[21] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[22] = base + ( ( w4 >> 8 ) & mask ); + out[23] = base + ( ( w4 >> 20 ) & mask ); + out[24] = base + ( ( w4 >> 32 ) & mask ); + out[25] = base + ( ( w4 >> 44 ) & mask ); + out[26] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[27] = base + ( ( w5 >> 4 ) & mask ); + out[28] = base + ( ( w5 >> 16 ) & mask ); + out[29] = base + ( ( w5 >> 28 ) & mask ); + out[30] = base + ( ( w5 >> 40 ) & mask ); + out[31] = base + ( w5 >> 52 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 13-bit values, touching 7 64-bit words, using 52 bytes */ +static void unpackforblock13_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(8191); + /* we are going to access 7 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + *pw += 52; /* we used up 52 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 13 ) & mask ); + out[2] = base + ( ( w0 >> 26 ) & mask ); + out[3] = base + ( ( w0 >> 39 ) & mask ); + out[4] = base + ( ( ( w0 >> 52 ) | ( w1 << 12 ) ) & mask ); + out[5] = base + ( ( w1 >> 1 ) & mask ); + out[6] = base + ( ( w1 >> 14 ) & mask ); + out[7] = base + ( ( w1 >> 27 ) & mask ); + out[8] = base + ( ( w1 >> 40 ) & mask ); + out[9] = base + ( ( ( w1 >> 53 ) | ( w2 << 11 ) ) & mask ); + out[10] = base + ( ( w2 >> 2 ) & mask ); + out[11] = base + ( ( w2 >> 15 ) & mask ); + out[12] = base + ( ( w2 >> 28 ) & mask ); + out[13] = base + ( ( w2 >> 41 ) & mask ); + out[14] = base + ( ( ( w2 >> 54 ) | ( w3 << 10 ) ) & mask ); + out[15] = base + ( ( w3 >> 3 ) & mask ); + out[16] = base + ( ( w3 >> 16 ) & mask ); + out[17] = base + ( ( w3 >> 29 ) & mask ); + out[18] = base + ( ( w3 >> 42 ) & mask ); + out[19] = base + ( ( ( w3 >> 55 ) | ( w4 << 9 ) ) & mask ); + out[20] = base + ( ( w4 >> 4 ) & mask ); + out[21] = base + ( ( w4 >> 17 ) & mask ); + out[22] = base + ( ( w4 >> 30 ) & mask ); + out[23] = base + ( ( w4 >> 43 ) & mask ); + out[24] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[25] = base + ( ( w5 >> 5 ) & mask ); + out[26] = base + ( ( w5 >> 18 ) & mask ); + out[27] = base + ( ( w5 >> 31 ) & mask ); + out[28] = base + ( ( w5 >> 44 ) & mask ); + out[29] = base + ( ( ( w5 >> 57 ) | ( w6 << 7 ) ) & mask ); + out[30] = base + ( ( w6 >> 6 ) & mask ); + out[31] = base + ( ( w6 >> 19 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 14-bit values, touching 7 64-bit words, using 56 bytes */ +static void unpackforblock14_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(16383); + /* we are going to access 7 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + *pw += 56; /* we used up 56 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 14 ) & mask ); + out[2] = base + ( ( w0 >> 28 ) & mask ); + out[3] = base + ( ( w0 >> 42 ) & mask ); + out[4] = base + ( ( ( w0 >> 56 ) | ( w1 << 8 ) ) & mask ); + out[5] = base + ( ( w1 >> 6 ) & mask ); + out[6] = base + ( ( w1 >> 20 ) & mask ); + out[7] = base + ( ( w1 >> 34 ) & mask ); + out[8] = base + ( ( w1 >> 48 ) & mask ); + out[9] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[10] = base + ( ( w2 >> 12 ) & mask ); + out[11] = base + ( ( w2 >> 26 ) & mask ); + out[12] = base + ( ( w2 >> 40 ) & mask ); + out[13] = base + ( ( ( w2 >> 54 ) | ( w3 << 10 ) ) & mask ); + out[14] = base + ( ( w3 >> 4 ) & mask ); + out[15] = base + ( ( w3 >> 18 ) & mask ); + out[16] = base + ( ( w3 >> 32 ) & mask ); + out[17] = base + ( ( w3 >> 46 ) & mask ); + out[18] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[19] = base + ( ( w4 >> 10 ) & mask ); + out[20] = base + ( ( w4 >> 24 ) & mask ); + out[21] = base + ( ( w4 >> 38 ) & mask ); + out[22] = base + ( ( ( w4 >> 52 ) | ( w5 << 12 ) ) & mask ); + out[23] = base + ( ( w5 >> 2 ) & mask ); + out[24] = base + ( ( w5 >> 16 ) & mask ); + out[25] = base + ( ( w5 >> 30 ) & mask ); + out[26] = base + ( ( w5 >> 44 ) & mask ); + out[27] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[28] = base + ( ( w6 >> 8 ) & mask ); + out[29] = base + ( ( w6 >> 22 ) & mask ); + out[30] = base + ( ( w6 >> 36 ) & mask ); + out[31] = base + ( w6 >> 50 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 15-bit values, touching 8 64-bit words, using 60 bytes */ +static void unpackforblock15_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(32767); + /* we are going to access 8 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + *pw += 60; /* we used up 60 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 15 ) & mask ); + out[2] = base + ( ( w0 >> 30 ) & mask ); + out[3] = base + ( ( w0 >> 45 ) & mask ); + out[4] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[5] = base + ( ( w1 >> 11 ) & mask ); + out[6] = base + ( ( w1 >> 26 ) & mask ); + out[7] = base + ( ( w1 >> 41 ) & mask ); + out[8] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[9] = base + ( ( w2 >> 7 ) & mask ); + out[10] = base + ( ( w2 >> 22 ) & mask ); + out[11] = base + ( ( w2 >> 37 ) & mask ); + out[12] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[13] = base + ( ( w3 >> 3 ) & mask ); + out[14] = base + ( ( w3 >> 18 ) & mask ); + out[15] = base + ( ( w3 >> 33 ) & mask ); + out[16] = base + ( ( w3 >> 48 ) & mask ); + out[17] = base + ( ( ( w3 >> 63 ) | ( w4 << 1 ) ) & mask ); + out[18] = base + ( ( w4 >> 14 ) & mask ); + out[19] = base + ( ( w4 >> 29 ) & mask ); + out[20] = base + ( ( w4 >> 44 ) & mask ); + out[21] = base + ( ( ( w4 >> 59 ) | ( w5 << 5 ) ) & mask ); + out[22] = base + ( ( w5 >> 10 ) & mask ); + out[23] = base + ( ( w5 >> 25 ) & mask ); + out[24] = base + ( ( w5 >> 40 ) & mask ); + out[25] = base + ( ( ( w5 >> 55 ) | ( w6 << 9 ) ) & mask ); + out[26] = base + ( ( w6 >> 6 ) & mask ); + out[27] = base + ( ( w6 >> 21 ) & mask ); + out[28] = base + ( ( w6 >> 36 ) & mask ); + out[29] = base + ( ( ( w6 >> 51 ) | ( w7 << 13 ) ) & mask ); + out[30] = base + ( ( w7 >> 2 ) & mask ); + out[31] = base + ( ( w7 >> 17 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 16-bit values, touching 8 64-bit words, using 64 bytes */ +static void unpackforblock16_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(65535); + /* we are going to access 8 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + *pw += 64; /* we used up 64 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 16 ) & mask ); + out[2] = base + ( ( w0 >> 32 ) & mask ); + out[3] = base + ( w0 >> 48 ); + out[4] = base + ( ( w1 ) & mask ); + out[5] = base + ( ( w1 >> 16 ) & mask ); + out[6] = base + ( ( w1 >> 32 ) & mask ); + out[7] = base + ( w1 >> 48 ); + out[8] = base + ( ( w2 ) & mask ); + out[9] = base + ( ( w2 >> 16 ) & mask ); + out[10] = base + ( ( w2 >> 32 ) & mask ); + out[11] = base + ( w2 >> 48 ); + out[12] = base + ( ( w3 ) & mask ); + out[13] = base + ( ( w3 >> 16 ) & mask ); + out[14] = base + ( ( w3 >> 32 ) & mask ); + out[15] = base + ( w3 >> 48 ); + out[16] = base + ( ( w4 ) & mask ); + out[17] = base + ( ( w4 >> 16 ) & mask ); + out[18] = base + ( ( w4 >> 32 ) & mask ); + out[19] = base + ( w4 >> 48 ); + out[20] = base + ( ( w5 ) & mask ); + out[21] = base + ( ( w5 >> 16 ) & mask ); + out[22] = base + ( ( w5 >> 32 ) & mask ); + out[23] = base + ( w5 >> 48 ); + out[24] = base + ( ( w6 ) & mask ); + out[25] = base + ( ( w6 >> 16 ) & mask ); + out[26] = base + ( ( w6 >> 32 ) & mask ); + out[27] = base + ( w6 >> 48 ); + out[28] = base + ( ( w7 ) & mask ); + out[29] = base + ( ( w7 >> 16 ) & mask ); + out[30] = base + ( ( w7 >> 32 ) & mask ); + out[31] = base + ( w7 >> 48 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 17-bit values, touching 9 64-bit words, using 68 bytes */ +static void unpackforblock17_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(131071); + /* we are going to access 9 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + *pw += 68; /* we used up 68 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 17 ) & mask ); + out[2] = base + ( ( w0 >> 34 ) & mask ); + out[3] = base + ( ( ( w0 >> 51 ) | ( w1 << 13 ) ) & mask ); + out[4] = base + ( ( w1 >> 4 ) & mask ); + out[5] = base + ( ( w1 >> 21 ) & mask ); + out[6] = base + ( ( w1 >> 38 ) & mask ); + out[7] = base + ( ( ( w1 >> 55 ) | ( w2 << 9 ) ) & mask ); + out[8] = base + ( ( w2 >> 8 ) & mask ); + out[9] = base + ( ( w2 >> 25 ) & mask ); + out[10] = base + ( ( w2 >> 42 ) & mask ); + out[11] = base + ( ( ( w2 >> 59 ) | ( w3 << 5 ) ) & mask ); + out[12] = base + ( ( w3 >> 12 ) & mask ); + out[13] = base + ( ( w3 >> 29 ) & mask ); + out[14] = base + ( ( w3 >> 46 ) & mask ); + out[15] = base + ( ( ( w3 >> 63 ) | ( w4 << 1 ) ) & mask ); + out[16] = base + ( ( w4 >> 16 ) & mask ); + out[17] = base + ( ( w4 >> 33 ) & mask ); + out[18] = base + ( ( ( w4 >> 50 ) | ( w5 << 14 ) ) & mask ); + out[19] = base + ( ( w5 >> 3 ) & mask ); + out[20] = base + ( ( w5 >> 20 ) & mask ); + out[21] = base + ( ( w5 >> 37 ) & mask ); + out[22] = base + ( ( ( w5 >> 54 ) | ( w6 << 10 ) ) & mask ); + out[23] = base + ( ( w6 >> 7 ) & mask ); + out[24] = base + ( ( w6 >> 24 ) & mask ); + out[25] = base + ( ( w6 >> 41 ) & mask ); + out[26] = base + ( ( ( w6 >> 58 ) | ( w7 << 6 ) ) & mask ); + out[27] = base + ( ( w7 >> 11 ) & mask ); + out[28] = base + ( ( w7 >> 28 ) & mask ); + out[29] = base + ( ( w7 >> 45 ) & mask ); + out[30] = base + ( ( ( w7 >> 62 ) | ( w8 << 2 ) ) & mask ); + out[31] = base + ( ( w8 >> 15 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 18-bit values, touching 9 64-bit words, using 72 bytes */ +static void unpackforblock18_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(262143); + /* we are going to access 9 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + *pw += 72; /* we used up 72 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 18 ) & mask ); + out[2] = base + ( ( w0 >> 36 ) & mask ); + out[3] = base + ( ( ( w0 >> 54 ) | ( w1 << 10 ) ) & mask ); + out[4] = base + ( ( w1 >> 8 ) & mask ); + out[5] = base + ( ( w1 >> 26 ) & mask ); + out[6] = base + ( ( w1 >> 44 ) & mask ); + out[7] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[8] = base + ( ( w2 >> 16 ) & mask ); + out[9] = base + ( ( w2 >> 34 ) & mask ); + out[10] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[11] = base + ( ( w3 >> 6 ) & mask ); + out[12] = base + ( ( w3 >> 24 ) & mask ); + out[13] = base + ( ( w3 >> 42 ) & mask ); + out[14] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[15] = base + ( ( w4 >> 14 ) & mask ); + out[16] = base + ( ( w4 >> 32 ) & mask ); + out[17] = base + ( ( ( w4 >> 50 ) | ( w5 << 14 ) ) & mask ); + out[18] = base + ( ( w5 >> 4 ) & mask ); + out[19] = base + ( ( w5 >> 22 ) & mask ); + out[20] = base + ( ( w5 >> 40 ) & mask ); + out[21] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[22] = base + ( ( w6 >> 12 ) & mask ); + out[23] = base + ( ( w6 >> 30 ) & mask ); + out[24] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[25] = base + ( ( w7 >> 2 ) & mask ); + out[26] = base + ( ( w7 >> 20 ) & mask ); + out[27] = base + ( ( w7 >> 38 ) & mask ); + out[28] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[29] = base + ( ( w8 >> 10 ) & mask ); + out[30] = base + ( ( w8 >> 28 ) & mask ); + out[31] = base + ( w8 >> 46 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 19-bit values, touching 10 64-bit words, using 76 bytes */ +static void unpackforblock19_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(524287); + /* we are going to access 10 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + *pw += 76; /* we used up 76 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 19 ) & mask ); + out[2] = base + ( ( w0 >> 38 ) & mask ); + out[3] = base + ( ( ( w0 >> 57 ) | ( w1 << 7 ) ) & mask ); + out[4] = base + ( ( w1 >> 12 ) & mask ); + out[5] = base + ( ( w1 >> 31 ) & mask ); + out[6] = base + ( ( ( w1 >> 50 ) | ( w2 << 14 ) ) & mask ); + out[7] = base + ( ( w2 >> 5 ) & mask ); + out[8] = base + ( ( w2 >> 24 ) & mask ); + out[9] = base + ( ( w2 >> 43 ) & mask ); + out[10] = base + ( ( ( w2 >> 62 ) | ( w3 << 2 ) ) & mask ); + out[11] = base + ( ( w3 >> 17 ) & mask ); + out[12] = base + ( ( w3 >> 36 ) & mask ); + out[13] = base + ( ( ( w3 >> 55 ) | ( w4 << 9 ) ) & mask ); + out[14] = base + ( ( w4 >> 10 ) & mask ); + out[15] = base + ( ( w4 >> 29 ) & mask ); + out[16] = base + ( ( ( w4 >> 48 ) | ( w5 << 16 ) ) & mask ); + out[17] = base + ( ( w5 >> 3 ) & mask ); + out[18] = base + ( ( w5 >> 22 ) & mask ); + out[19] = base + ( ( w5 >> 41 ) & mask ); + out[20] = base + ( ( ( w5 >> 60 ) | ( w6 << 4 ) ) & mask ); + out[21] = base + ( ( w6 >> 15 ) & mask ); + out[22] = base + ( ( w6 >> 34 ) & mask ); + out[23] = base + ( ( ( w6 >> 53 ) | ( w7 << 11 ) ) & mask ); + out[24] = base + ( ( w7 >> 8 ) & mask ); + out[25] = base + ( ( w7 >> 27 ) & mask ); + out[26] = base + ( ( ( w7 >> 46 ) | ( w8 << 18 ) ) & mask ); + out[27] = base + ( ( w8 >> 1 ) & mask ); + out[28] = base + ( ( w8 >> 20 ) & mask ); + out[29] = base + ( ( w8 >> 39 ) & mask ); + out[30] = base + ( ( ( w8 >> 58 ) | ( w9 << 6 ) ) & mask ); + out[31] = base + ( ( w9 >> 13 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 20-bit values, touching 10 64-bit words, using 80 bytes */ +static void unpackforblock20_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1048575); + /* we are going to access 10 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + *pw += 80; /* we used up 80 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 20 ) & mask ); + out[2] = base + ( ( w0 >> 40 ) & mask ); + out[3] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[4] = base + ( ( w1 >> 16 ) & mask ); + out[5] = base + ( ( w1 >> 36 ) & mask ); + out[6] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[7] = base + ( ( w2 >> 12 ) & mask ); + out[8] = base + ( ( w2 >> 32 ) & mask ); + out[9] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[10] = base + ( ( w3 >> 8 ) & mask ); + out[11] = base + ( ( w3 >> 28 ) & mask ); + out[12] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[13] = base + ( ( w4 >> 4 ) & mask ); + out[14] = base + ( ( w4 >> 24 ) & mask ); + out[15] = base + ( w4 >> 44 ); + out[16] = base + ( ( w5 ) & mask ); + out[17] = base + ( ( w5 >> 20 ) & mask ); + out[18] = base + ( ( w5 >> 40 ) & mask ); + out[19] = base + ( ( ( w5 >> 60 ) | ( w6 << 4 ) ) & mask ); + out[20] = base + ( ( w6 >> 16 ) & mask ); + out[21] = base + ( ( w6 >> 36 ) & mask ); + out[22] = base + ( ( ( w6 >> 56 ) | ( w7 << 8 ) ) & mask ); + out[23] = base + ( ( w7 >> 12 ) & mask ); + out[24] = base + ( ( w7 >> 32 ) & mask ); + out[25] = base + ( ( ( w7 >> 52 ) | ( w8 << 12 ) ) & mask ); + out[26] = base + ( ( w8 >> 8 ) & mask ); + out[27] = base + ( ( w8 >> 28 ) & mask ); + out[28] = base + ( ( ( w8 >> 48 ) | ( w9 << 16 ) ) & mask ); + out[29] = base + ( ( w9 >> 4 ) & mask ); + out[30] = base + ( ( w9 >> 24 ) & mask ); + out[31] = base + ( w9 >> 44 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 21-bit values, touching 11 64-bit words, using 84 bytes */ +static void unpackforblock21_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2097151); + /* we are going to access 11 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + *pw += 84; /* we used up 84 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 21 ) & mask ); + out[2] = base + ( ( w0 >> 42 ) & mask ); + out[3] = base + ( ( ( w0 >> 63 ) | ( w1 << 1 ) ) & mask ); + out[4] = base + ( ( w1 >> 20 ) & mask ); + out[5] = base + ( ( w1 >> 41 ) & mask ); + out[6] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[7] = base + ( ( w2 >> 19 ) & mask ); + out[8] = base + ( ( w2 >> 40 ) & mask ); + out[9] = base + ( ( ( w2 >> 61 ) | ( w3 << 3 ) ) & mask ); + out[10] = base + ( ( w3 >> 18 ) & mask ); + out[11] = base + ( ( w3 >> 39 ) & mask ); + out[12] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[13] = base + ( ( w4 >> 17 ) & mask ); + out[14] = base + ( ( w4 >> 38 ) & mask ); + out[15] = base + ( ( ( w4 >> 59 ) | ( w5 << 5 ) ) & mask ); + out[16] = base + ( ( w5 >> 16 ) & mask ); + out[17] = base + ( ( w5 >> 37 ) & mask ); + out[18] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[19] = base + ( ( w6 >> 15 ) & mask ); + out[20] = base + ( ( w6 >> 36 ) & mask ); + out[21] = base + ( ( ( w6 >> 57 ) | ( w7 << 7 ) ) & mask ); + out[22] = base + ( ( w7 >> 14 ) & mask ); + out[23] = base + ( ( w7 >> 35 ) & mask ); + out[24] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[25] = base + ( ( w8 >> 13 ) & mask ); + out[26] = base + ( ( w8 >> 34 ) & mask ); + out[27] = base + ( ( ( w8 >> 55 ) | ( w9 << 9 ) ) & mask ); + out[28] = base + ( ( w9 >> 12 ) & mask ); + out[29] = base + ( ( w9 >> 33 ) & mask ); + out[30] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[31] = base + ( ( w10 >> 11 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 22-bit values, touching 11 64-bit words, using 88 bytes */ +static void unpackforblock22_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4194303); + /* we are going to access 11 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + *pw += 88; /* we used up 88 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 22 ) & mask ); + out[2] = base + ( ( ( w0 >> 44 ) | ( w1 << 20 ) ) & mask ); + out[3] = base + ( ( w1 >> 2 ) & mask ); + out[4] = base + ( ( w1 >> 24 ) & mask ); + out[5] = base + ( ( ( w1 >> 46 ) | ( w2 << 18 ) ) & mask ); + out[6] = base + ( ( w2 >> 4 ) & mask ); + out[7] = base + ( ( w2 >> 26 ) & mask ); + out[8] = base + ( ( ( w2 >> 48 ) | ( w3 << 16 ) ) & mask ); + out[9] = base + ( ( w3 >> 6 ) & mask ); + out[10] = base + ( ( w3 >> 28 ) & mask ); + out[11] = base + ( ( ( w3 >> 50 ) | ( w4 << 14 ) ) & mask ); + out[12] = base + ( ( w4 >> 8 ) & mask ); + out[13] = base + ( ( w4 >> 30 ) & mask ); + out[14] = base + ( ( ( w4 >> 52 ) | ( w5 << 12 ) ) & mask ); + out[15] = base + ( ( w5 >> 10 ) & mask ); + out[16] = base + ( ( w5 >> 32 ) & mask ); + out[17] = base + ( ( ( w5 >> 54 ) | ( w6 << 10 ) ) & mask ); + out[18] = base + ( ( w6 >> 12 ) & mask ); + out[19] = base + ( ( w6 >> 34 ) & mask ); + out[20] = base + ( ( ( w6 >> 56 ) | ( w7 << 8 ) ) & mask ); + out[21] = base + ( ( w7 >> 14 ) & mask ); + out[22] = base + ( ( w7 >> 36 ) & mask ); + out[23] = base + ( ( ( w7 >> 58 ) | ( w8 << 6 ) ) & mask ); + out[24] = base + ( ( w8 >> 16 ) & mask ); + out[25] = base + ( ( w8 >> 38 ) & mask ); + out[26] = base + ( ( ( w8 >> 60 ) | ( w9 << 4 ) ) & mask ); + out[27] = base + ( ( w9 >> 18 ) & mask ); + out[28] = base + ( ( w9 >> 40 ) & mask ); + out[29] = base + ( ( ( w9 >> 62 ) | ( w10 << 2 ) ) & mask ); + out[30] = base + ( ( w10 >> 20 ) & mask ); + out[31] = base + ( w10 >> 42 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 23-bit values, touching 12 64-bit words, using 92 bytes */ +static void unpackforblock23_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(8388607); + /* we are going to access 12 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + *pw += 92; /* we used up 92 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 23 ) & mask ); + out[2] = base + ( ( ( w0 >> 46 ) | ( w1 << 18 ) ) & mask ); + out[3] = base + ( ( w1 >> 5 ) & mask ); + out[4] = base + ( ( w1 >> 28 ) & mask ); + out[5] = base + ( ( ( w1 >> 51 ) | ( w2 << 13 ) ) & mask ); + out[6] = base + ( ( w2 >> 10 ) & mask ); + out[7] = base + ( ( w2 >> 33 ) & mask ); + out[8] = base + ( ( ( w2 >> 56 ) | ( w3 << 8 ) ) & mask ); + out[9] = base + ( ( w3 >> 15 ) & mask ); + out[10] = base + ( ( w3 >> 38 ) & mask ); + out[11] = base + ( ( ( w3 >> 61 ) | ( w4 << 3 ) ) & mask ); + out[12] = base + ( ( w4 >> 20 ) & mask ); + out[13] = base + ( ( ( w4 >> 43 ) | ( w5 << 21 ) ) & mask ); + out[14] = base + ( ( w5 >> 2 ) & mask ); + out[15] = base + ( ( w5 >> 25 ) & mask ); + out[16] = base + ( ( ( w5 >> 48 ) | ( w6 << 16 ) ) & mask ); + out[17] = base + ( ( w6 >> 7 ) & mask ); + out[18] = base + ( ( w6 >> 30 ) & mask ); + out[19] = base + ( ( ( w6 >> 53 ) | ( w7 << 11 ) ) & mask ); + out[20] = base + ( ( w7 >> 12 ) & mask ); + out[21] = base + ( ( w7 >> 35 ) & mask ); + out[22] = base + ( ( ( w7 >> 58 ) | ( w8 << 6 ) ) & mask ); + out[23] = base + ( ( w8 >> 17 ) & mask ); + out[24] = base + ( ( w8 >> 40 ) & mask ); + out[25] = base + ( ( ( w8 >> 63 ) | ( w9 << 1 ) ) & mask ); + out[26] = base + ( ( w9 >> 22 ) & mask ); + out[27] = base + ( ( ( w9 >> 45 ) | ( w10 << 19 ) ) & mask ); + out[28] = base + ( ( w10 >> 4 ) & mask ); + out[29] = base + ( ( w10 >> 27 ) & mask ); + out[30] = base + ( ( ( w10 >> 50 ) | ( w11 << 14 ) ) & mask ); + out[31] = base + ( ( w11 >> 9 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 24-bit values, touching 12 64-bit words, using 96 bytes */ +static void unpackforblock24_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(16777215); + /* we are going to access 12 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + *pw += 96; /* we used up 96 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 24 ) & mask ); + out[2] = base + ( ( ( w0 >> 48 ) | ( w1 << 16 ) ) & mask ); + out[3] = base + ( ( w1 >> 8 ) & mask ); + out[4] = base + ( ( w1 >> 32 ) & mask ); + out[5] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[6] = base + ( ( w2 >> 16 ) & mask ); + out[7] = base + ( w2 >> 40 ); + out[8] = base + ( ( w3 ) & mask ); + out[9] = base + ( ( w3 >> 24 ) & mask ); + out[10] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[11] = base + ( ( w4 >> 8 ) & mask ); + out[12] = base + ( ( w4 >> 32 ) & mask ); + out[13] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[14] = base + ( ( w5 >> 16 ) & mask ); + out[15] = base + ( w5 >> 40 ); + out[16] = base + ( ( w6 ) & mask ); + out[17] = base + ( ( w6 >> 24 ) & mask ); + out[18] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[19] = base + ( ( w7 >> 8 ) & mask ); + out[20] = base + ( ( w7 >> 32 ) & mask ); + out[21] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[22] = base + ( ( w8 >> 16 ) & mask ); + out[23] = base + ( w8 >> 40 ); + out[24] = base + ( ( w9 ) & mask ); + out[25] = base + ( ( w9 >> 24 ) & mask ); + out[26] = base + ( ( ( w9 >> 48 ) | ( w10 << 16 ) ) & mask ); + out[27] = base + ( ( w10 >> 8 ) & mask ); + out[28] = base + ( ( w10 >> 32 ) & mask ); + out[29] = base + ( ( ( w10 >> 56 ) | ( w11 << 8 ) ) & mask ); + out[30] = base + ( ( w11 >> 16 ) & mask ); + out[31] = base + ( w11 >> 40 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 25-bit values, touching 13 64-bit words, using 100 bytes */ +static void unpackforblock25_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(33554431); + /* we are going to access 13 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + *pw += 100; /* we used up 100 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 25 ) & mask ); + out[2] = base + ( ( ( w0 >> 50 ) | ( w1 << 14 ) ) & mask ); + out[3] = base + ( ( w1 >> 11 ) & mask ); + out[4] = base + ( ( w1 >> 36 ) & mask ); + out[5] = base + ( ( ( w1 >> 61 ) | ( w2 << 3 ) ) & mask ); + out[6] = base + ( ( w2 >> 22 ) & mask ); + out[7] = base + ( ( ( w2 >> 47 ) | ( w3 << 17 ) ) & mask ); + out[8] = base + ( ( w3 >> 8 ) & mask ); + out[9] = base + ( ( w3 >> 33 ) & mask ); + out[10] = base + ( ( ( w3 >> 58 ) | ( w4 << 6 ) ) & mask ); + out[11] = base + ( ( w4 >> 19 ) & mask ); + out[12] = base + ( ( ( w4 >> 44 ) | ( w5 << 20 ) ) & mask ); + out[13] = base + ( ( w5 >> 5 ) & mask ); + out[14] = base + ( ( w5 >> 30 ) & mask ); + out[15] = base + ( ( ( w5 >> 55 ) | ( w6 << 9 ) ) & mask ); + out[16] = base + ( ( w6 >> 16 ) & mask ); + out[17] = base + ( ( ( w6 >> 41 ) | ( w7 << 23 ) ) & mask ); + out[18] = base + ( ( w7 >> 2 ) & mask ); + out[19] = base + ( ( w7 >> 27 ) & mask ); + out[20] = base + ( ( ( w7 >> 52 ) | ( w8 << 12 ) ) & mask ); + out[21] = base + ( ( w8 >> 13 ) & mask ); + out[22] = base + ( ( w8 >> 38 ) & mask ); + out[23] = base + ( ( ( w8 >> 63 ) | ( w9 << 1 ) ) & mask ); + out[24] = base + ( ( w9 >> 24 ) & mask ); + out[25] = base + ( ( ( w9 >> 49 ) | ( w10 << 15 ) ) & mask ); + out[26] = base + ( ( w10 >> 10 ) & mask ); + out[27] = base + ( ( w10 >> 35 ) & mask ); + out[28] = base + ( ( ( w10 >> 60 ) | ( w11 << 4 ) ) & mask ); + out[29] = base + ( ( w11 >> 21 ) & mask ); + out[30] = base + ( ( ( w11 >> 46 ) | ( w12 << 18 ) ) & mask ); + out[31] = base + ( ( w12 >> 7 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 26-bit values, touching 13 64-bit words, using 104 bytes */ +static void unpackforblock26_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(67108863); + /* we are going to access 13 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + *pw += 104; /* we used up 104 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 26 ) & mask ); + out[2] = base + ( ( ( w0 >> 52 ) | ( w1 << 12 ) ) & mask ); + out[3] = base + ( ( w1 >> 14 ) & mask ); + out[4] = base + ( ( ( w1 >> 40 ) | ( w2 << 24 ) ) & mask ); + out[5] = base + ( ( w2 >> 2 ) & mask ); + out[6] = base + ( ( w2 >> 28 ) & mask ); + out[7] = base + ( ( ( w2 >> 54 ) | ( w3 << 10 ) ) & mask ); + out[8] = base + ( ( w3 >> 16 ) & mask ); + out[9] = base + ( ( ( w3 >> 42 ) | ( w4 << 22 ) ) & mask ); + out[10] = base + ( ( w4 >> 4 ) & mask ); + out[11] = base + ( ( w4 >> 30 ) & mask ); + out[12] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[13] = base + ( ( w5 >> 18 ) & mask ); + out[14] = base + ( ( ( w5 >> 44 ) | ( w6 << 20 ) ) & mask ); + out[15] = base + ( ( w6 >> 6 ) & mask ); + out[16] = base + ( ( w6 >> 32 ) & mask ); + out[17] = base + ( ( ( w6 >> 58 ) | ( w7 << 6 ) ) & mask ); + out[18] = base + ( ( w7 >> 20 ) & mask ); + out[19] = base + ( ( ( w7 >> 46 ) | ( w8 << 18 ) ) & mask ); + out[20] = base + ( ( w8 >> 8 ) & mask ); + out[21] = base + ( ( w8 >> 34 ) & mask ); + out[22] = base + ( ( ( w8 >> 60 ) | ( w9 << 4 ) ) & mask ); + out[23] = base + ( ( w9 >> 22 ) & mask ); + out[24] = base + ( ( ( w9 >> 48 ) | ( w10 << 16 ) ) & mask ); + out[25] = base + ( ( w10 >> 10 ) & mask ); + out[26] = base + ( ( w10 >> 36 ) & mask ); + out[27] = base + ( ( ( w10 >> 62 ) | ( w11 << 2 ) ) & mask ); + out[28] = base + ( ( w11 >> 24 ) & mask ); + out[29] = base + ( ( ( w11 >> 50 ) | ( w12 << 14 ) ) & mask ); + out[30] = base + ( ( w12 >> 12 ) & mask ); + out[31] = base + ( w12 >> 38 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 27-bit values, touching 14 64-bit words, using 108 bytes */ +static void unpackforblock27_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(134217727); + /* we are going to access 14 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + *pw += 108; /* we used up 108 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 27 ) & mask ); + out[2] = base + ( ( ( w0 >> 54 ) | ( w1 << 10 ) ) & mask ); + out[3] = base + ( ( w1 >> 17 ) & mask ); + out[4] = base + ( ( ( w1 >> 44 ) | ( w2 << 20 ) ) & mask ); + out[5] = base + ( ( w2 >> 7 ) & mask ); + out[6] = base + ( ( w2 >> 34 ) & mask ); + out[7] = base + ( ( ( w2 >> 61 ) | ( w3 << 3 ) ) & mask ); + out[8] = base + ( ( w3 >> 24 ) & mask ); + out[9] = base + ( ( ( w3 >> 51 ) | ( w4 << 13 ) ) & mask ); + out[10] = base + ( ( w4 >> 14 ) & mask ); + out[11] = base + ( ( ( w4 >> 41 ) | ( w5 << 23 ) ) & mask ); + out[12] = base + ( ( w5 >> 4 ) & mask ); + out[13] = base + ( ( w5 >> 31 ) & mask ); + out[14] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[15] = base + ( ( w6 >> 21 ) & mask ); + out[16] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[17] = base + ( ( w7 >> 11 ) & mask ); + out[18] = base + ( ( ( w7 >> 38 ) | ( w8 << 26 ) ) & mask ); + out[19] = base + ( ( w8 >> 1 ) & mask ); + out[20] = base + ( ( w8 >> 28 ) & mask ); + out[21] = base + ( ( ( w8 >> 55 ) | ( w9 << 9 ) ) & mask ); + out[22] = base + ( ( w9 >> 18 ) & mask ); + out[23] = base + ( ( ( w9 >> 45 ) | ( w10 << 19 ) ) & mask ); + out[24] = base + ( ( w10 >> 8 ) & mask ); + out[25] = base + ( ( w10 >> 35 ) & mask ); + out[26] = base + ( ( ( w10 >> 62 ) | ( w11 << 2 ) ) & mask ); + out[27] = base + ( ( w11 >> 25 ) & mask ); + out[28] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[29] = base + ( ( w12 >> 15 ) & mask ); + out[30] = base + ( ( ( w12 >> 42 ) | ( w13 << 22 ) ) & mask ); + out[31] = base + ( ( w13 >> 5 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 28-bit values, touching 14 64-bit words, using 112 bytes */ +static void unpackforblock28_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(268435455); + /* we are going to access 14 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + *pw += 112; /* we used up 112 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 28 ) & mask ); + out[2] = base + ( ( ( w0 >> 56 ) | ( w1 << 8 ) ) & mask ); + out[3] = base + ( ( w1 >> 20 ) & mask ); + out[4] = base + ( ( ( w1 >> 48 ) | ( w2 << 16 ) ) & mask ); + out[5] = base + ( ( w2 >> 12 ) & mask ); + out[6] = base + ( ( ( w2 >> 40 ) | ( w3 << 24 ) ) & mask ); + out[7] = base + ( ( w3 >> 4 ) & mask ); + out[8] = base + ( ( w3 >> 32 ) & mask ); + out[9] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[10] = base + ( ( w4 >> 24 ) & mask ); + out[11] = base + ( ( ( w4 >> 52 ) | ( w5 << 12 ) ) & mask ); + out[12] = base + ( ( w5 >> 16 ) & mask ); + out[13] = base + ( ( ( w5 >> 44 ) | ( w6 << 20 ) ) & mask ); + out[14] = base + ( ( w6 >> 8 ) & mask ); + out[15] = base + ( w6 >> 36 ); + out[16] = base + ( ( w7 ) & mask ); + out[17] = base + ( ( w7 >> 28 ) & mask ); + out[18] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[19] = base + ( ( w8 >> 20 ) & mask ); + out[20] = base + ( ( ( w8 >> 48 ) | ( w9 << 16 ) ) & mask ); + out[21] = base + ( ( w9 >> 12 ) & mask ); + out[22] = base + ( ( ( w9 >> 40 ) | ( w10 << 24 ) ) & mask ); + out[23] = base + ( ( w10 >> 4 ) & mask ); + out[24] = base + ( ( w10 >> 32 ) & mask ); + out[25] = base + ( ( ( w10 >> 60 ) | ( w11 << 4 ) ) & mask ); + out[26] = base + ( ( w11 >> 24 ) & mask ); + out[27] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[28] = base + ( ( w12 >> 16 ) & mask ); + out[29] = base + ( ( ( w12 >> 44 ) | ( w13 << 20 ) ) & mask ); + out[30] = base + ( ( w13 >> 8 ) & mask ); + out[31] = base + ( w13 >> 36 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 29-bit values, touching 15 64-bit words, using 116 bytes */ +static void unpackforblock29_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(536870911); + /* we are going to access 15 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + *pw += 116; /* we used up 116 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 29 ) & mask ); + out[2] = base + ( ( ( w0 >> 58 ) | ( w1 << 6 ) ) & mask ); + out[3] = base + ( ( w1 >> 23 ) & mask ); + out[4] = base + ( ( ( w1 >> 52 ) | ( w2 << 12 ) ) & mask ); + out[5] = base + ( ( w2 >> 17 ) & mask ); + out[6] = base + ( ( ( w2 >> 46 ) | ( w3 << 18 ) ) & mask ); + out[7] = base + ( ( w3 >> 11 ) & mask ); + out[8] = base + ( ( ( w3 >> 40 ) | ( w4 << 24 ) ) & mask ); + out[9] = base + ( ( w4 >> 5 ) & mask ); + out[10] = base + ( ( w4 >> 34 ) & mask ); + out[11] = base + ( ( ( w4 >> 63 ) | ( w5 << 1 ) ) & mask ); + out[12] = base + ( ( w5 >> 28 ) & mask ); + out[13] = base + ( ( ( w5 >> 57 ) | ( w6 << 7 ) ) & mask ); + out[14] = base + ( ( w6 >> 22 ) & mask ); + out[15] = base + ( ( ( w6 >> 51 ) | ( w7 << 13 ) ) & mask ); + out[16] = base + ( ( w7 >> 16 ) & mask ); + out[17] = base + ( ( ( w7 >> 45 ) | ( w8 << 19 ) ) & mask ); + out[18] = base + ( ( w8 >> 10 ) & mask ); + out[19] = base + ( ( ( w8 >> 39 ) | ( w9 << 25 ) ) & mask ); + out[20] = base + ( ( w9 >> 4 ) & mask ); + out[21] = base + ( ( w9 >> 33 ) & mask ); + out[22] = base + ( ( ( w9 >> 62 ) | ( w10 << 2 ) ) & mask ); + out[23] = base + ( ( w10 >> 27 ) & mask ); + out[24] = base + ( ( ( w10 >> 56 ) | ( w11 << 8 ) ) & mask ); + out[25] = base + ( ( w11 >> 21 ) & mask ); + out[26] = base + ( ( ( w11 >> 50 ) | ( w12 << 14 ) ) & mask ); + out[27] = base + ( ( w12 >> 15 ) & mask ); + out[28] = base + ( ( ( w12 >> 44 ) | ( w13 << 20 ) ) & mask ); + out[29] = base + ( ( w13 >> 9 ) & mask ); + out[30] = base + ( ( ( w13 >> 38 ) | ( w14 << 26 ) ) & mask ); + out[31] = base + ( ( w14 >> 3 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 30-bit values, touching 15 64-bit words, using 120 bytes */ +static void unpackforblock30_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1073741823); + /* we are going to access 15 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + *pw += 120; /* we used up 120 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 30 ) & mask ); + out[2] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[3] = base + ( ( w1 >> 26 ) & mask ); + out[4] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[5] = base + ( ( w2 >> 22 ) & mask ); + out[6] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[7] = base + ( ( w3 >> 18 ) & mask ); + out[8] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[9] = base + ( ( w4 >> 14 ) & mask ); + out[10] = base + ( ( ( w4 >> 44 ) | ( w5 << 20 ) ) & mask ); + out[11] = base + ( ( w5 >> 10 ) & mask ); + out[12] = base + ( ( ( w5 >> 40 ) | ( w6 << 24 ) ) & mask ); + out[13] = base + ( ( w6 >> 6 ) & mask ); + out[14] = base + ( ( ( w6 >> 36 ) | ( w7 << 28 ) ) & mask ); + out[15] = base + ( ( w7 >> 2 ) & mask ); + out[16] = base + ( ( w7 >> 32 ) & mask ); + out[17] = base + ( ( ( w7 >> 62 ) | ( w8 << 2 ) ) & mask ); + out[18] = base + ( ( w8 >> 28 ) & mask ); + out[19] = base + ( ( ( w8 >> 58 ) | ( w9 << 6 ) ) & mask ); + out[20] = base + ( ( w9 >> 24 ) & mask ); + out[21] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[22] = base + ( ( w10 >> 20 ) & mask ); + out[23] = base + ( ( ( w10 >> 50 ) | ( w11 << 14 ) ) & mask ); + out[24] = base + ( ( w11 >> 16 ) & mask ); + out[25] = base + ( ( ( w11 >> 46 ) | ( w12 << 18 ) ) & mask ); + out[26] = base + ( ( w12 >> 12 ) & mask ); + out[27] = base + ( ( ( w12 >> 42 ) | ( w13 << 22 ) ) & mask ); + out[28] = base + ( ( w13 >> 8 ) & mask ); + out[29] = base + ( ( ( w13 >> 38 ) | ( w14 << 26 ) ) & mask ); + out[30] = base + ( ( w14 >> 4 ) & mask ); + out[31] = base + ( w14 >> 34 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 31-bit values, touching 16 64-bit words, using 124 bytes */ +static void unpackforblock31_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2147483647); + /* we are going to access 16 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + *pw += 124; /* we used up 124 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( w0 >> 31 ) & mask ); + out[2] = base + ( ( ( w0 >> 62 ) | ( w1 << 2 ) ) & mask ); + out[3] = base + ( ( w1 >> 29 ) & mask ); + out[4] = base + ( ( ( w1 >> 60 ) | ( w2 << 4 ) ) & mask ); + out[5] = base + ( ( w2 >> 27 ) & mask ); + out[6] = base + ( ( ( w2 >> 58 ) | ( w3 << 6 ) ) & mask ); + out[7] = base + ( ( w3 >> 25 ) & mask ); + out[8] = base + ( ( ( w3 >> 56 ) | ( w4 << 8 ) ) & mask ); + out[9] = base + ( ( w4 >> 23 ) & mask ); + out[10] = base + ( ( ( w4 >> 54 ) | ( w5 << 10 ) ) & mask ); + out[11] = base + ( ( w5 >> 21 ) & mask ); + out[12] = base + ( ( ( w5 >> 52 ) | ( w6 << 12 ) ) & mask ); + out[13] = base + ( ( w6 >> 19 ) & mask ); + out[14] = base + ( ( ( w6 >> 50 ) | ( w7 << 14 ) ) & mask ); + out[15] = base + ( ( w7 >> 17 ) & mask ); + out[16] = base + ( ( ( w7 >> 48 ) | ( w8 << 16 ) ) & mask ); + out[17] = base + ( ( w8 >> 15 ) & mask ); + out[18] = base + ( ( ( w8 >> 46 ) | ( w9 << 18 ) ) & mask ); + out[19] = base + ( ( w9 >> 13 ) & mask ); + out[20] = base + ( ( ( w9 >> 44 ) | ( w10 << 20 ) ) & mask ); + out[21] = base + ( ( w10 >> 11 ) & mask ); + out[22] = base + ( ( ( w10 >> 42 ) | ( w11 << 22 ) ) & mask ); + out[23] = base + ( ( w11 >> 9 ) & mask ); + out[24] = base + ( ( ( w11 >> 40 ) | ( w12 << 24 ) ) & mask ); + out[25] = base + ( ( w12 >> 7 ) & mask ); + out[26] = base + ( ( ( w12 >> 38 ) | ( w13 << 26 ) ) & mask ); + out[27] = base + ( ( w13 >> 5 ) & mask ); + out[28] = base + ( ( ( w13 >> 36 ) | ( w14 << 28 ) ) & mask ); + out[29] = base + ( ( w14 >> 3 ) & mask ); + out[30] = base + ( ( ( w14 >> 34 ) | ( w15 << 30 ) ) & mask ); + out[31] = base + ( ( w15 >> 1 ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 32-bit values, touching 16 64-bit words, using 128 bytes */ +static void unpackforblock32_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4294967295); + /* we are going to access 16 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + *pw += 128; /* we used up 128 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( w0 >> 32 ); + out[2] = base + ( ( w1 ) & mask ); + out[3] = base + ( w1 >> 32 ); + out[4] = base + ( ( w2 ) & mask ); + out[5] = base + ( w2 >> 32 ); + out[6] = base + ( ( w3 ) & mask ); + out[7] = base + ( w3 >> 32 ); + out[8] = base + ( ( w4 ) & mask ); + out[9] = base + ( w4 >> 32 ); + out[10] = base + ( ( w5 ) & mask ); + out[11] = base + ( w5 >> 32 ); + out[12] = base + ( ( w6 ) & mask ); + out[13] = base + ( w6 >> 32 ); + out[14] = base + ( ( w7 ) & mask ); + out[15] = base + ( w7 >> 32 ); + out[16] = base + ( ( w8 ) & mask ); + out[17] = base + ( w8 >> 32 ); + out[18] = base + ( ( w9 ) & mask ); + out[19] = base + ( w9 >> 32 ); + out[20] = base + ( ( w10 ) & mask ); + out[21] = base + ( w10 >> 32 ); + out[22] = base + ( ( w11 ) & mask ); + out[23] = base + ( w11 >> 32 ); + out[24] = base + ( ( w12 ) & mask ); + out[25] = base + ( w12 >> 32 ); + out[26] = base + ( ( w13 ) & mask ); + out[27] = base + ( w13 >> 32 ); + out[28] = base + ( ( w14 ) & mask ); + out[29] = base + ( w14 >> 32 ); + out[30] = base + ( ( w15 ) & mask ); + out[31] = base + ( w15 >> 32 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 33-bit values, touching 17 64-bit words, using 132 bytes */ +static void unpackforblock33_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(8589934591); + /* we are going to access 17 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + *pw += 132; /* we used up 132 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 33 ) | ( w1 << 31 ) ) & mask ); + out[2] = base + ( ( w1 >> 2 ) & mask ); + out[3] = base + ( ( ( w1 >> 35 ) | ( w2 << 29 ) ) & mask ); + out[4] = base + ( ( w2 >> 4 ) & mask ); + out[5] = base + ( ( ( w2 >> 37 ) | ( w3 << 27 ) ) & mask ); + out[6] = base + ( ( w3 >> 6 ) & mask ); + out[7] = base + ( ( ( w3 >> 39 ) | ( w4 << 25 ) ) & mask ); + out[8] = base + ( ( w4 >> 8 ) & mask ); + out[9] = base + ( ( ( w4 >> 41 ) | ( w5 << 23 ) ) & mask ); + out[10] = base + ( ( w5 >> 10 ) & mask ); + out[11] = base + ( ( ( w5 >> 43 ) | ( w6 << 21 ) ) & mask ); + out[12] = base + ( ( w6 >> 12 ) & mask ); + out[13] = base + ( ( ( w6 >> 45 ) | ( w7 << 19 ) ) & mask ); + out[14] = base + ( ( w7 >> 14 ) & mask ); + out[15] = base + ( ( ( w7 >> 47 ) | ( w8 << 17 ) ) & mask ); + out[16] = base + ( ( w8 >> 16 ) & mask ); + out[17] = base + ( ( ( w8 >> 49 ) | ( w9 << 15 ) ) & mask ); + out[18] = base + ( ( w9 >> 18 ) & mask ); + out[19] = base + ( ( ( w9 >> 51 ) | ( w10 << 13 ) ) & mask ); + out[20] = base + ( ( w10 >> 20 ) & mask ); + out[21] = base + ( ( ( w10 >> 53 ) | ( w11 << 11 ) ) & mask ); + out[22] = base + ( ( w11 >> 22 ) & mask ); + out[23] = base + ( ( ( w11 >> 55 ) | ( w12 << 9 ) ) & mask ); + out[24] = base + ( ( w12 >> 24 ) & mask ); + out[25] = base + ( ( ( w12 >> 57 ) | ( w13 << 7 ) ) & mask ); + out[26] = base + ( ( w13 >> 26 ) & mask ); + out[27] = base + ( ( ( w13 >> 59 ) | ( w14 << 5 ) ) & mask ); + out[28] = base + ( ( w14 >> 28 ) & mask ); + out[29] = base + ( ( ( w14 >> 61 ) | ( w15 << 3 ) ) & mask ); + out[30] = base + ( ( w15 >> 30 ) & mask ); + out[31] = base + ( ( ( w15 >> 63 ) | ( w16 << 1 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 34-bit values, touching 17 64-bit words, using 136 bytes */ +static void unpackforblock34_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(17179869183); + /* we are going to access 17 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + *pw += 136; /* we used up 136 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 34 ) | ( w1 << 30 ) ) & mask ); + out[2] = base + ( ( w1 >> 4 ) & mask ); + out[3] = base + ( ( ( w1 >> 38 ) | ( w2 << 26 ) ) & mask ); + out[4] = base + ( ( w2 >> 8 ) & mask ); + out[5] = base + ( ( ( w2 >> 42 ) | ( w3 << 22 ) ) & mask ); + out[6] = base + ( ( w3 >> 12 ) & mask ); + out[7] = base + ( ( ( w3 >> 46 ) | ( w4 << 18 ) ) & mask ); + out[8] = base + ( ( w4 >> 16 ) & mask ); + out[9] = base + ( ( ( w4 >> 50 ) | ( w5 << 14 ) ) & mask ); + out[10] = base + ( ( w5 >> 20 ) & mask ); + out[11] = base + ( ( ( w5 >> 54 ) | ( w6 << 10 ) ) & mask ); + out[12] = base + ( ( w6 >> 24 ) & mask ); + out[13] = base + ( ( ( w6 >> 58 ) | ( w7 << 6 ) ) & mask ); + out[14] = base + ( ( w7 >> 28 ) & mask ); + out[15] = base + ( ( ( w7 >> 62 ) | ( w8 << 2 ) ) & mask ); + out[16] = base + ( ( ( w8 >> 32 ) | ( w9 << 32 ) ) & mask ); + out[17] = base + ( ( w9 >> 2 ) & mask ); + out[18] = base + ( ( ( w9 >> 36 ) | ( w10 << 28 ) ) & mask ); + out[19] = base + ( ( w10 >> 6 ) & mask ); + out[20] = base + ( ( ( w10 >> 40 ) | ( w11 << 24 ) ) & mask ); + out[21] = base + ( ( w11 >> 10 ) & mask ); + out[22] = base + ( ( ( w11 >> 44 ) | ( w12 << 20 ) ) & mask ); + out[23] = base + ( ( w12 >> 14 ) & mask ); + out[24] = base + ( ( ( w12 >> 48 ) | ( w13 << 16 ) ) & mask ); + out[25] = base + ( ( w13 >> 18 ) & mask ); + out[26] = base + ( ( ( w13 >> 52 ) | ( w14 << 12 ) ) & mask ); + out[27] = base + ( ( w14 >> 22 ) & mask ); + out[28] = base + ( ( ( w14 >> 56 ) | ( w15 << 8 ) ) & mask ); + out[29] = base + ( ( w15 >> 26 ) & mask ); + out[30] = base + ( ( ( w15 >> 60 ) | ( w16 << 4 ) ) & mask ); + out[31] = base + ( w16 >> 30 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 35-bit values, touching 18 64-bit words, using 140 bytes */ +static void unpackforblock35_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(34359738367); + /* we are going to access 18 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + *pw += 140; /* we used up 140 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 35 ) | ( w1 << 29 ) ) & mask ); + out[2] = base + ( ( w1 >> 6 ) & mask ); + out[3] = base + ( ( ( w1 >> 41 ) | ( w2 << 23 ) ) & mask ); + out[4] = base + ( ( w2 >> 12 ) & mask ); + out[5] = base + ( ( ( w2 >> 47 ) | ( w3 << 17 ) ) & mask ); + out[6] = base + ( ( w3 >> 18 ) & mask ); + out[7] = base + ( ( ( w3 >> 53 ) | ( w4 << 11 ) ) & mask ); + out[8] = base + ( ( w4 >> 24 ) & mask ); + out[9] = base + ( ( ( w4 >> 59 ) | ( w5 << 5 ) ) & mask ); + out[10] = base + ( ( ( w5 >> 30 ) | ( w6 << 34 ) ) & mask ); + out[11] = base + ( ( w6 >> 1 ) & mask ); + out[12] = base + ( ( ( w6 >> 36 ) | ( w7 << 28 ) ) & mask ); + out[13] = base + ( ( w7 >> 7 ) & mask ); + out[14] = base + ( ( ( w7 >> 42 ) | ( w8 << 22 ) ) & mask ); + out[15] = base + ( ( w8 >> 13 ) & mask ); + out[16] = base + ( ( ( w8 >> 48 ) | ( w9 << 16 ) ) & mask ); + out[17] = base + ( ( w9 >> 19 ) & mask ); + out[18] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[19] = base + ( ( w10 >> 25 ) & mask ); + out[20] = base + ( ( ( w10 >> 60 ) | ( w11 << 4 ) ) & mask ); + out[21] = base + ( ( ( w11 >> 31 ) | ( w12 << 33 ) ) & mask ); + out[22] = base + ( ( w12 >> 2 ) & mask ); + out[23] = base + ( ( ( w12 >> 37 ) | ( w13 << 27 ) ) & mask ); + out[24] = base + ( ( w13 >> 8 ) & mask ); + out[25] = base + ( ( ( w13 >> 43 ) | ( w14 << 21 ) ) & mask ); + out[26] = base + ( ( w14 >> 14 ) & mask ); + out[27] = base + ( ( ( w14 >> 49 ) | ( w15 << 15 ) ) & mask ); + out[28] = base + ( ( w15 >> 20 ) & mask ); + out[29] = base + ( ( ( w15 >> 55 ) | ( w16 << 9 ) ) & mask ); + out[30] = base + ( ( w16 >> 26 ) & mask ); + out[31] = base + ( ( ( w16 >> 61 ) | ( w17 << 3 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 36-bit values, touching 18 64-bit words, using 144 bytes */ +static void unpackforblock36_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(68719476735); + /* we are going to access 18 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + *pw += 144; /* we used up 144 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 36 ) | ( w1 << 28 ) ) & mask ); + out[2] = base + ( ( w1 >> 8 ) & mask ); + out[3] = base + ( ( ( w1 >> 44 ) | ( w2 << 20 ) ) & mask ); + out[4] = base + ( ( w2 >> 16 ) & mask ); + out[5] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[6] = base + ( ( w3 >> 24 ) & mask ); + out[7] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[8] = base + ( ( ( w4 >> 32 ) | ( w5 << 32 ) ) & mask ); + out[9] = base + ( ( w5 >> 4 ) & mask ); + out[10] = base + ( ( ( w5 >> 40 ) | ( w6 << 24 ) ) & mask ); + out[11] = base + ( ( w6 >> 12 ) & mask ); + out[12] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[13] = base + ( ( w7 >> 20 ) & mask ); + out[14] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[15] = base + ( w8 >> 28 ); + out[16] = base + ( ( w9 ) & mask ); + out[17] = base + ( ( ( w9 >> 36 ) | ( w10 << 28 ) ) & mask ); + out[18] = base + ( ( w10 >> 8 ) & mask ); + out[19] = base + ( ( ( w10 >> 44 ) | ( w11 << 20 ) ) & mask ); + out[20] = base + ( ( w11 >> 16 ) & mask ); + out[21] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[22] = base + ( ( w12 >> 24 ) & mask ); + out[23] = base + ( ( ( w12 >> 60 ) | ( w13 << 4 ) ) & mask ); + out[24] = base + ( ( ( w13 >> 32 ) | ( w14 << 32 ) ) & mask ); + out[25] = base + ( ( w14 >> 4 ) & mask ); + out[26] = base + ( ( ( w14 >> 40 ) | ( w15 << 24 ) ) & mask ); + out[27] = base + ( ( w15 >> 12 ) & mask ); + out[28] = base + ( ( ( w15 >> 48 ) | ( w16 << 16 ) ) & mask ); + out[29] = base + ( ( w16 >> 20 ) & mask ); + out[30] = base + ( ( ( w16 >> 56 ) | ( w17 << 8 ) ) & mask ); + out[31] = base + ( w17 >> 28 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 37-bit values, touching 19 64-bit words, using 148 bytes */ +static void unpackforblock37_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(137438953471); + /* we are going to access 19 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + *pw += 148; /* we used up 148 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 37 ) | ( w1 << 27 ) ) & mask ); + out[2] = base + ( ( w1 >> 10 ) & mask ); + out[3] = base + ( ( ( w1 >> 47 ) | ( w2 << 17 ) ) & mask ); + out[4] = base + ( ( w2 >> 20 ) & mask ); + out[5] = base + ( ( ( w2 >> 57 ) | ( w3 << 7 ) ) & mask ); + out[6] = base + ( ( ( w3 >> 30 ) | ( w4 << 34 ) ) & mask ); + out[7] = base + ( ( w4 >> 3 ) & mask ); + out[8] = base + ( ( ( w4 >> 40 ) | ( w5 << 24 ) ) & mask ); + out[9] = base + ( ( w5 >> 13 ) & mask ); + out[10] = base + ( ( ( w5 >> 50 ) | ( w6 << 14 ) ) & mask ); + out[11] = base + ( ( w6 >> 23 ) & mask ); + out[12] = base + ( ( ( w6 >> 60 ) | ( w7 << 4 ) ) & mask ); + out[13] = base + ( ( ( w7 >> 33 ) | ( w8 << 31 ) ) & mask ); + out[14] = base + ( ( w8 >> 6 ) & mask ); + out[15] = base + ( ( ( w8 >> 43 ) | ( w9 << 21 ) ) & mask ); + out[16] = base + ( ( w9 >> 16 ) & mask ); + out[17] = base + ( ( ( w9 >> 53 ) | ( w10 << 11 ) ) & mask ); + out[18] = base + ( ( w10 >> 26 ) & mask ); + out[19] = base + ( ( ( w10 >> 63 ) | ( w11 << 1 ) ) & mask ); + out[20] = base + ( ( ( w11 >> 36 ) | ( w12 << 28 ) ) & mask ); + out[21] = base + ( ( w12 >> 9 ) & mask ); + out[22] = base + ( ( ( w12 >> 46 ) | ( w13 << 18 ) ) & mask ); + out[23] = base + ( ( w13 >> 19 ) & mask ); + out[24] = base + ( ( ( w13 >> 56 ) | ( w14 << 8 ) ) & mask ); + out[25] = base + ( ( ( w14 >> 29 ) | ( w15 << 35 ) ) & mask ); + out[26] = base + ( ( w15 >> 2 ) & mask ); + out[27] = base + ( ( ( w15 >> 39 ) | ( w16 << 25 ) ) & mask ); + out[28] = base + ( ( w16 >> 12 ) & mask ); + out[29] = base + ( ( ( w16 >> 49 ) | ( w17 << 15 ) ) & mask ); + out[30] = base + ( ( w17 >> 22 ) & mask ); + out[31] = base + ( ( ( w17 >> 59 ) | ( w18 << 5 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 38-bit values, touching 19 64-bit words, using 152 bytes */ +static void unpackforblock38_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(274877906943); + /* we are going to access 19 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + *pw += 152; /* we used up 152 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 38 ) | ( w1 << 26 ) ) & mask ); + out[2] = base + ( ( w1 >> 12 ) & mask ); + out[3] = base + ( ( ( w1 >> 50 ) | ( w2 << 14 ) ) & mask ); + out[4] = base + ( ( w2 >> 24 ) & mask ); + out[5] = base + ( ( ( w2 >> 62 ) | ( w3 << 2 ) ) & mask ); + out[6] = base + ( ( ( w3 >> 36 ) | ( w4 << 28 ) ) & mask ); + out[7] = base + ( ( w4 >> 10 ) & mask ); + out[8] = base + ( ( ( w4 >> 48 ) | ( w5 << 16 ) ) & mask ); + out[9] = base + ( ( w5 >> 22 ) & mask ); + out[10] = base + ( ( ( w5 >> 60 ) | ( w6 << 4 ) ) & mask ); + out[11] = base + ( ( ( w6 >> 34 ) | ( w7 << 30 ) ) & mask ); + out[12] = base + ( ( w7 >> 8 ) & mask ); + out[13] = base + ( ( ( w7 >> 46 ) | ( w8 << 18 ) ) & mask ); + out[14] = base + ( ( w8 >> 20 ) & mask ); + out[15] = base + ( ( ( w8 >> 58 ) | ( w9 << 6 ) ) & mask ); + out[16] = base + ( ( ( w9 >> 32 ) | ( w10 << 32 ) ) & mask ); + out[17] = base + ( ( w10 >> 6 ) & mask ); + out[18] = base + ( ( ( w10 >> 44 ) | ( w11 << 20 ) ) & mask ); + out[19] = base + ( ( w11 >> 18 ) & mask ); + out[20] = base + ( ( ( w11 >> 56 ) | ( w12 << 8 ) ) & mask ); + out[21] = base + ( ( ( w12 >> 30 ) | ( w13 << 34 ) ) & mask ); + out[22] = base + ( ( w13 >> 4 ) & mask ); + out[23] = base + ( ( ( w13 >> 42 ) | ( w14 << 22 ) ) & mask ); + out[24] = base + ( ( w14 >> 16 ) & mask ); + out[25] = base + ( ( ( w14 >> 54 ) | ( w15 << 10 ) ) & mask ); + out[26] = base + ( ( ( w15 >> 28 ) | ( w16 << 36 ) ) & mask ); + out[27] = base + ( ( w16 >> 2 ) & mask ); + out[28] = base + ( ( ( w16 >> 40 ) | ( w17 << 24 ) ) & mask ); + out[29] = base + ( ( w17 >> 14 ) & mask ); + out[30] = base + ( ( ( w17 >> 52 ) | ( w18 << 12 ) ) & mask ); + out[31] = base + ( w18 >> 26 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 39-bit values, touching 20 64-bit words, using 156 bytes */ +static void unpackforblock39_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(549755813887); + /* we are going to access 20 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + *pw += 156; /* we used up 156 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 39 ) | ( w1 << 25 ) ) & mask ); + out[2] = base + ( ( w1 >> 14 ) & mask ); + out[3] = base + ( ( ( w1 >> 53 ) | ( w2 << 11 ) ) & mask ); + out[4] = base + ( ( ( w2 >> 28 ) | ( w3 << 36 ) ) & mask ); + out[5] = base + ( ( w3 >> 3 ) & mask ); + out[6] = base + ( ( ( w3 >> 42 ) | ( w4 << 22 ) ) & mask ); + out[7] = base + ( ( w4 >> 17 ) & mask ); + out[8] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[9] = base + ( ( ( w5 >> 31 ) | ( w6 << 33 ) ) & mask ); + out[10] = base + ( ( w6 >> 6 ) & mask ); + out[11] = base + ( ( ( w6 >> 45 ) | ( w7 << 19 ) ) & mask ); + out[12] = base + ( ( w7 >> 20 ) & mask ); + out[13] = base + ( ( ( w7 >> 59 ) | ( w8 << 5 ) ) & mask ); + out[14] = base + ( ( ( w8 >> 34 ) | ( w9 << 30 ) ) & mask ); + out[15] = base + ( ( w9 >> 9 ) & mask ); + out[16] = base + ( ( ( w9 >> 48 ) | ( w10 << 16 ) ) & mask ); + out[17] = base + ( ( w10 >> 23 ) & mask ); + out[18] = base + ( ( ( w10 >> 62 ) | ( w11 << 2 ) ) & mask ); + out[19] = base + ( ( ( w11 >> 37 ) | ( w12 << 27 ) ) & mask ); + out[20] = base + ( ( w12 >> 12 ) & mask ); + out[21] = base + ( ( ( w12 >> 51 ) | ( w13 << 13 ) ) & mask ); + out[22] = base + ( ( ( w13 >> 26 ) | ( w14 << 38 ) ) & mask ); + out[23] = base + ( ( w14 >> 1 ) & mask ); + out[24] = base + ( ( ( w14 >> 40 ) | ( w15 << 24 ) ) & mask ); + out[25] = base + ( ( w15 >> 15 ) & mask ); + out[26] = base + ( ( ( w15 >> 54 ) | ( w16 << 10 ) ) & mask ); + out[27] = base + ( ( ( w16 >> 29 ) | ( w17 << 35 ) ) & mask ); + out[28] = base + ( ( w17 >> 4 ) & mask ); + out[29] = base + ( ( ( w17 >> 43 ) | ( w18 << 21 ) ) & mask ); + out[30] = base + ( ( w18 >> 18 ) & mask ); + out[31] = base + ( ( ( w18 >> 57 ) | ( w19 << 7 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 40-bit values, touching 20 64-bit words, using 160 bytes */ +static void unpackforblock40_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1099511627775); + /* we are going to access 20 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + *pw += 160; /* we used up 160 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 40 ) | ( w1 << 24 ) ) & mask ); + out[2] = base + ( ( w1 >> 16 ) & mask ); + out[3] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[4] = base + ( ( ( w2 >> 32 ) | ( w3 << 32 ) ) & mask ); + out[5] = base + ( ( w3 >> 8 ) & mask ); + out[6] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[7] = base + ( w4 >> 24 ); + out[8] = base + ( ( w5 ) & mask ); + out[9] = base + ( ( ( w5 >> 40 ) | ( w6 << 24 ) ) & mask ); + out[10] = base + ( ( w6 >> 16 ) & mask ); + out[11] = base + ( ( ( w6 >> 56 ) | ( w7 << 8 ) ) & mask ); + out[12] = base + ( ( ( w7 >> 32 ) | ( w8 << 32 ) ) & mask ); + out[13] = base + ( ( w8 >> 8 ) & mask ); + out[14] = base + ( ( ( w8 >> 48 ) | ( w9 << 16 ) ) & mask ); + out[15] = base + ( w9 >> 24 ); + out[16] = base + ( ( w10 ) & mask ); + out[17] = base + ( ( ( w10 >> 40 ) | ( w11 << 24 ) ) & mask ); + out[18] = base + ( ( w11 >> 16 ) & mask ); + out[19] = base + ( ( ( w11 >> 56 ) | ( w12 << 8 ) ) & mask ); + out[20] = base + ( ( ( w12 >> 32 ) | ( w13 << 32 ) ) & mask ); + out[21] = base + ( ( w13 >> 8 ) & mask ); + out[22] = base + ( ( ( w13 >> 48 ) | ( w14 << 16 ) ) & mask ); + out[23] = base + ( w14 >> 24 ); + out[24] = base + ( ( w15 ) & mask ); + out[25] = base + ( ( ( w15 >> 40 ) | ( w16 << 24 ) ) & mask ); + out[26] = base + ( ( w16 >> 16 ) & mask ); + out[27] = base + ( ( ( w16 >> 56 ) | ( w17 << 8 ) ) & mask ); + out[28] = base + ( ( ( w17 >> 32 ) | ( w18 << 32 ) ) & mask ); + out[29] = base + ( ( w18 >> 8 ) & mask ); + out[30] = base + ( ( ( w18 >> 48 ) | ( w19 << 16 ) ) & mask ); + out[31] = base + ( w19 >> 24 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 41-bit values, touching 21 64-bit words, using 164 bytes */ +static void unpackforblock41_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2199023255551); + /* we are going to access 21 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + *pw += 164; /* we used up 164 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 41 ) | ( w1 << 23 ) ) & mask ); + out[2] = base + ( ( w1 >> 18 ) & mask ); + out[3] = base + ( ( ( w1 >> 59 ) | ( w2 << 5 ) ) & mask ); + out[4] = base + ( ( ( w2 >> 36 ) | ( w3 << 28 ) ) & mask ); + out[5] = base + ( ( w3 >> 13 ) & mask ); + out[6] = base + ( ( ( w3 >> 54 ) | ( w4 << 10 ) ) & mask ); + out[7] = base + ( ( ( w4 >> 31 ) | ( w5 << 33 ) ) & mask ); + out[8] = base + ( ( w5 >> 8 ) & mask ); + out[9] = base + ( ( ( w5 >> 49 ) | ( w6 << 15 ) ) & mask ); + out[10] = base + ( ( ( w6 >> 26 ) | ( w7 << 38 ) ) & mask ); + out[11] = base + ( ( w7 >> 3 ) & mask ); + out[12] = base + ( ( ( w7 >> 44 ) | ( w8 << 20 ) ) & mask ); + out[13] = base + ( ( w8 >> 21 ) & mask ); + out[14] = base + ( ( ( w8 >> 62 ) | ( w9 << 2 ) ) & mask ); + out[15] = base + ( ( ( w9 >> 39 ) | ( w10 << 25 ) ) & mask ); + out[16] = base + ( ( w10 >> 16 ) & mask ); + out[17] = base + ( ( ( w10 >> 57 ) | ( w11 << 7 ) ) & mask ); + out[18] = base + ( ( ( w11 >> 34 ) | ( w12 << 30 ) ) & mask ); + out[19] = base + ( ( w12 >> 11 ) & mask ); + out[20] = base + ( ( ( w12 >> 52 ) | ( w13 << 12 ) ) & mask ); + out[21] = base + ( ( ( w13 >> 29 ) | ( w14 << 35 ) ) & mask ); + out[22] = base + ( ( w14 >> 6 ) & mask ); + out[23] = base + ( ( ( w14 >> 47 ) | ( w15 << 17 ) ) & mask ); + out[24] = base + ( ( ( w15 >> 24 ) | ( w16 << 40 ) ) & mask ); + out[25] = base + ( ( w16 >> 1 ) & mask ); + out[26] = base + ( ( ( w16 >> 42 ) | ( w17 << 22 ) ) & mask ); + out[27] = base + ( ( w17 >> 19 ) & mask ); + out[28] = base + ( ( ( w17 >> 60 ) | ( w18 << 4 ) ) & mask ); + out[29] = base + ( ( ( w18 >> 37 ) | ( w19 << 27 ) ) & mask ); + out[30] = base + ( ( w19 >> 14 ) & mask ); + out[31] = base + ( ( ( w19 >> 55 ) | ( w20 << 9 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 42-bit values, touching 21 64-bit words, using 168 bytes */ +static void unpackforblock42_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4398046511103); + /* we are going to access 21 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + *pw += 168; /* we used up 168 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 42 ) | ( w1 << 22 ) ) & mask ); + out[2] = base + ( ( w1 >> 20 ) & mask ); + out[3] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[4] = base + ( ( ( w2 >> 40 ) | ( w3 << 24 ) ) & mask ); + out[5] = base + ( ( w3 >> 18 ) & mask ); + out[6] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[7] = base + ( ( ( w4 >> 38 ) | ( w5 << 26 ) ) & mask ); + out[8] = base + ( ( w5 >> 16 ) & mask ); + out[9] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[10] = base + ( ( ( w6 >> 36 ) | ( w7 << 28 ) ) & mask ); + out[11] = base + ( ( w7 >> 14 ) & mask ); + out[12] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[13] = base + ( ( ( w8 >> 34 ) | ( w9 << 30 ) ) & mask ); + out[14] = base + ( ( w9 >> 12 ) & mask ); + out[15] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[16] = base + ( ( ( w10 >> 32 ) | ( w11 << 32 ) ) & mask ); + out[17] = base + ( ( w11 >> 10 ) & mask ); + out[18] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[19] = base + ( ( ( w12 >> 30 ) | ( w13 << 34 ) ) & mask ); + out[20] = base + ( ( w13 >> 8 ) & mask ); + out[21] = base + ( ( ( w13 >> 50 ) | ( w14 << 14 ) ) & mask ); + out[22] = base + ( ( ( w14 >> 28 ) | ( w15 << 36 ) ) & mask ); + out[23] = base + ( ( w15 >> 6 ) & mask ); + out[24] = base + ( ( ( w15 >> 48 ) | ( w16 << 16 ) ) & mask ); + out[25] = base + ( ( ( w16 >> 26 ) | ( w17 << 38 ) ) & mask ); + out[26] = base + ( ( w17 >> 4 ) & mask ); + out[27] = base + ( ( ( w17 >> 46 ) | ( w18 << 18 ) ) & mask ); + out[28] = base + ( ( ( w18 >> 24 ) | ( w19 << 40 ) ) & mask ); + out[29] = base + ( ( w19 >> 2 ) & mask ); + out[30] = base + ( ( ( w19 >> 44 ) | ( w20 << 20 ) ) & mask ); + out[31] = base + ( w20 >> 22 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 43-bit values, touching 22 64-bit words, using 172 bytes */ +static void unpackforblock43_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(8796093022207); + /* we are going to access 22 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + *pw += 172; /* we used up 172 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 43 ) | ( w1 << 21 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 22 ) | ( w2 << 42 ) ) & mask ); + out[3] = base + ( ( w2 >> 1 ) & mask ); + out[4] = base + ( ( ( w2 >> 44 ) | ( w3 << 20 ) ) & mask ); + out[5] = base + ( ( ( w3 >> 23 ) | ( w4 << 41 ) ) & mask ); + out[6] = base + ( ( w4 >> 2 ) & mask ); + out[7] = base + ( ( ( w4 >> 45 ) | ( w5 << 19 ) ) & mask ); + out[8] = base + ( ( ( w5 >> 24 ) | ( w6 << 40 ) ) & mask ); + out[9] = base + ( ( w6 >> 3 ) & mask ); + out[10] = base + ( ( ( w6 >> 46 ) | ( w7 << 18 ) ) & mask ); + out[11] = base + ( ( ( w7 >> 25 ) | ( w8 << 39 ) ) & mask ); + out[12] = base + ( ( w8 >> 4 ) & mask ); + out[13] = base + ( ( ( w8 >> 47 ) | ( w9 << 17 ) ) & mask ); + out[14] = base + ( ( ( w9 >> 26 ) | ( w10 << 38 ) ) & mask ); + out[15] = base + ( ( w10 >> 5 ) & mask ); + out[16] = base + ( ( ( w10 >> 48 ) | ( w11 << 16 ) ) & mask ); + out[17] = base + ( ( ( w11 >> 27 ) | ( w12 << 37 ) ) & mask ); + out[18] = base + ( ( w12 >> 6 ) & mask ); + out[19] = base + ( ( ( w12 >> 49 ) | ( w13 << 15 ) ) & mask ); + out[20] = base + ( ( ( w13 >> 28 ) | ( w14 << 36 ) ) & mask ); + out[21] = base + ( ( w14 >> 7 ) & mask ); + out[22] = base + ( ( ( w14 >> 50 ) | ( w15 << 14 ) ) & mask ); + out[23] = base + ( ( ( w15 >> 29 ) | ( w16 << 35 ) ) & mask ); + out[24] = base + ( ( w16 >> 8 ) & mask ); + out[25] = base + ( ( ( w16 >> 51 ) | ( w17 << 13 ) ) & mask ); + out[26] = base + ( ( ( w17 >> 30 ) | ( w18 << 34 ) ) & mask ); + out[27] = base + ( ( w18 >> 9 ) & mask ); + out[28] = base + ( ( ( w18 >> 52 ) | ( w19 << 12 ) ) & mask ); + out[29] = base + ( ( ( w19 >> 31 ) | ( w20 << 33 ) ) & mask ); + out[30] = base + ( ( w20 >> 10 ) & mask ); + out[31] = base + ( ( ( w20 >> 53 ) | ( w21 << 11 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 44-bit values, touching 22 64-bit words, using 176 bytes */ +static void unpackforblock44_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(17592186044415); + /* we are going to access 22 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + *pw += 176; /* we used up 176 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 44 ) | ( w1 << 20 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 24 ) | ( w2 << 40 ) ) & mask ); + out[3] = base + ( ( w2 >> 4 ) & mask ); + out[4] = base + ( ( ( w2 >> 48 ) | ( w3 << 16 ) ) & mask ); + out[5] = base + ( ( ( w3 >> 28 ) | ( w4 << 36 ) ) & mask ); + out[6] = base + ( ( w4 >> 8 ) & mask ); + out[7] = base + ( ( ( w4 >> 52 ) | ( w5 << 12 ) ) & mask ); + out[8] = base + ( ( ( w5 >> 32 ) | ( w6 << 32 ) ) & mask ); + out[9] = base + ( ( w6 >> 12 ) & mask ); + out[10] = base + ( ( ( w6 >> 56 ) | ( w7 << 8 ) ) & mask ); + out[11] = base + ( ( ( w7 >> 36 ) | ( w8 << 28 ) ) & mask ); + out[12] = base + ( ( w8 >> 16 ) & mask ); + out[13] = base + ( ( ( w8 >> 60 ) | ( w9 << 4 ) ) & mask ); + out[14] = base + ( ( ( w9 >> 40 ) | ( w10 << 24 ) ) & mask ); + out[15] = base + ( w10 >> 20 ); + out[16] = base + ( ( w11 ) & mask ); + out[17] = base + ( ( ( w11 >> 44 ) | ( w12 << 20 ) ) & mask ); + out[18] = base + ( ( ( w12 >> 24 ) | ( w13 << 40 ) ) & mask ); + out[19] = base + ( ( w13 >> 4 ) & mask ); + out[20] = base + ( ( ( w13 >> 48 ) | ( w14 << 16 ) ) & mask ); + out[21] = base + ( ( ( w14 >> 28 ) | ( w15 << 36 ) ) & mask ); + out[22] = base + ( ( w15 >> 8 ) & mask ); + out[23] = base + ( ( ( w15 >> 52 ) | ( w16 << 12 ) ) & mask ); + out[24] = base + ( ( ( w16 >> 32 ) | ( w17 << 32 ) ) & mask ); + out[25] = base + ( ( w17 >> 12 ) & mask ); + out[26] = base + ( ( ( w17 >> 56 ) | ( w18 << 8 ) ) & mask ); + out[27] = base + ( ( ( w18 >> 36 ) | ( w19 << 28 ) ) & mask ); + out[28] = base + ( ( w19 >> 16 ) & mask ); + out[29] = base + ( ( ( w19 >> 60 ) | ( w20 << 4 ) ) & mask ); + out[30] = base + ( ( ( w20 >> 40 ) | ( w21 << 24 ) ) & mask ); + out[31] = base + ( w21 >> 20 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 45-bit values, touching 23 64-bit words, using 180 bytes */ +static void unpackforblock45_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(35184372088831); + /* we are going to access 23 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + *pw += 180; /* we used up 180 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 45 ) | ( w1 << 19 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 26 ) | ( w2 << 38 ) ) & mask ); + out[3] = base + ( ( w2 >> 7 ) & mask ); + out[4] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[5] = base + ( ( ( w3 >> 33 ) | ( w4 << 31 ) ) & mask ); + out[6] = base + ( ( w4 >> 14 ) & mask ); + out[7] = base + ( ( ( w4 >> 59 ) | ( w5 << 5 ) ) & mask ); + out[8] = base + ( ( ( w5 >> 40 ) | ( w6 << 24 ) ) & mask ); + out[9] = base + ( ( ( w6 >> 21 ) | ( w7 << 43 ) ) & mask ); + out[10] = base + ( ( w7 >> 2 ) & mask ); + out[11] = base + ( ( ( w7 >> 47 ) | ( w8 << 17 ) ) & mask ); + out[12] = base + ( ( ( w8 >> 28 ) | ( w9 << 36 ) ) & mask ); + out[13] = base + ( ( w9 >> 9 ) & mask ); + out[14] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[15] = base + ( ( ( w10 >> 35 ) | ( w11 << 29 ) ) & mask ); + out[16] = base + ( ( w11 >> 16 ) & mask ); + out[17] = base + ( ( ( w11 >> 61 ) | ( w12 << 3 ) ) & mask ); + out[18] = base + ( ( ( w12 >> 42 ) | ( w13 << 22 ) ) & mask ); + out[19] = base + ( ( ( w13 >> 23 ) | ( w14 << 41 ) ) & mask ); + out[20] = base + ( ( w14 >> 4 ) & mask ); + out[21] = base + ( ( ( w14 >> 49 ) | ( w15 << 15 ) ) & mask ); + out[22] = base + ( ( ( w15 >> 30 ) | ( w16 << 34 ) ) & mask ); + out[23] = base + ( ( w16 >> 11 ) & mask ); + out[24] = base + ( ( ( w16 >> 56 ) | ( w17 << 8 ) ) & mask ); + out[25] = base + ( ( ( w17 >> 37 ) | ( w18 << 27 ) ) & mask ); + out[26] = base + ( ( w18 >> 18 ) & mask ); + out[27] = base + ( ( ( w18 >> 63 ) | ( w19 << 1 ) ) & mask ); + out[28] = base + ( ( ( w19 >> 44 ) | ( w20 << 20 ) ) & mask ); + out[29] = base + ( ( ( w20 >> 25 ) | ( w21 << 39 ) ) & mask ); + out[30] = base + ( ( w21 >> 6 ) & mask ); + out[31] = base + ( ( ( w21 >> 51 ) | ( w22 << 13 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 46-bit values, touching 23 64-bit words, using 184 bytes */ +static void unpackforblock46_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(70368744177663); + /* we are going to access 23 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + *pw += 184; /* we used up 184 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 46 ) | ( w1 << 18 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 28 ) | ( w2 << 36 ) ) & mask ); + out[3] = base + ( ( w2 >> 10 ) & mask ); + out[4] = base + ( ( ( w2 >> 56 ) | ( w3 << 8 ) ) & mask ); + out[5] = base + ( ( ( w3 >> 38 ) | ( w4 << 26 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 20 ) | ( w5 << 44 ) ) & mask ); + out[7] = base + ( ( w5 >> 2 ) & mask ); + out[8] = base + ( ( ( w5 >> 48 ) | ( w6 << 16 ) ) & mask ); + out[9] = base + ( ( ( w6 >> 30 ) | ( w7 << 34 ) ) & mask ); + out[10] = base + ( ( w7 >> 12 ) & mask ); + out[11] = base + ( ( ( w7 >> 58 ) | ( w8 << 6 ) ) & mask ); + out[12] = base + ( ( ( w8 >> 40 ) | ( w9 << 24 ) ) & mask ); + out[13] = base + ( ( ( w9 >> 22 ) | ( w10 << 42 ) ) & mask ); + out[14] = base + ( ( w10 >> 4 ) & mask ); + out[15] = base + ( ( ( w10 >> 50 ) | ( w11 << 14 ) ) & mask ); + out[16] = base + ( ( ( w11 >> 32 ) | ( w12 << 32 ) ) & mask ); + out[17] = base + ( ( w12 >> 14 ) & mask ); + out[18] = base + ( ( ( w12 >> 60 ) | ( w13 << 4 ) ) & mask ); + out[19] = base + ( ( ( w13 >> 42 ) | ( w14 << 22 ) ) & mask ); + out[20] = base + ( ( ( w14 >> 24 ) | ( w15 << 40 ) ) & mask ); + out[21] = base + ( ( w15 >> 6 ) & mask ); + out[22] = base + ( ( ( w15 >> 52 ) | ( w16 << 12 ) ) & mask ); + out[23] = base + ( ( ( w16 >> 34 ) | ( w17 << 30 ) ) & mask ); + out[24] = base + ( ( w17 >> 16 ) & mask ); + out[25] = base + ( ( ( w17 >> 62 ) | ( w18 << 2 ) ) & mask ); + out[26] = base + ( ( ( w18 >> 44 ) | ( w19 << 20 ) ) & mask ); + out[27] = base + ( ( ( w19 >> 26 ) | ( w20 << 38 ) ) & mask ); + out[28] = base + ( ( w20 >> 8 ) & mask ); + out[29] = base + ( ( ( w20 >> 54 ) | ( w21 << 10 ) ) & mask ); + out[30] = base + ( ( ( w21 >> 36 ) | ( w22 << 28 ) ) & mask ); + out[31] = base + ( w22 >> 18 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 47-bit values, touching 24 64-bit words, using 188 bytes */ +static void unpackforblock47_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(140737488355327); + /* we are going to access 24 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + *pw += 188; /* we used up 188 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 47 ) | ( w1 << 17 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 30 ) | ( w2 << 34 ) ) & mask ); + out[3] = base + ( ( w2 >> 13 ) & mask ); + out[4] = base + ( ( ( w2 >> 60 ) | ( w3 << 4 ) ) & mask ); + out[5] = base + ( ( ( w3 >> 43 ) | ( w4 << 21 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 26 ) | ( w5 << 38 ) ) & mask ); + out[7] = base + ( ( w5 >> 9 ) & mask ); + out[8] = base + ( ( ( w5 >> 56 ) | ( w6 << 8 ) ) & mask ); + out[9] = base + ( ( ( w6 >> 39 ) | ( w7 << 25 ) ) & mask ); + out[10] = base + ( ( ( w7 >> 22 ) | ( w8 << 42 ) ) & mask ); + out[11] = base + ( ( w8 >> 5 ) & mask ); + out[12] = base + ( ( ( w8 >> 52 ) | ( w9 << 12 ) ) & mask ); + out[13] = base + ( ( ( w9 >> 35 ) | ( w10 << 29 ) ) & mask ); + out[14] = base + ( ( ( w10 >> 18 ) | ( w11 << 46 ) ) & mask ); + out[15] = base + ( ( w11 >> 1 ) & mask ); + out[16] = base + ( ( ( w11 >> 48 ) | ( w12 << 16 ) ) & mask ); + out[17] = base + ( ( ( w12 >> 31 ) | ( w13 << 33 ) ) & mask ); + out[18] = base + ( ( w13 >> 14 ) & mask ); + out[19] = base + ( ( ( w13 >> 61 ) | ( w14 << 3 ) ) & mask ); + out[20] = base + ( ( ( w14 >> 44 ) | ( w15 << 20 ) ) & mask ); + out[21] = base + ( ( ( w15 >> 27 ) | ( w16 << 37 ) ) & mask ); + out[22] = base + ( ( w16 >> 10 ) & mask ); + out[23] = base + ( ( ( w16 >> 57 ) | ( w17 << 7 ) ) & mask ); + out[24] = base + ( ( ( w17 >> 40 ) | ( w18 << 24 ) ) & mask ); + out[25] = base + ( ( ( w18 >> 23 ) | ( w19 << 41 ) ) & mask ); + out[26] = base + ( ( w19 >> 6 ) & mask ); + out[27] = base + ( ( ( w19 >> 53 ) | ( w20 << 11 ) ) & mask ); + out[28] = base + ( ( ( w20 >> 36 ) | ( w21 << 28 ) ) & mask ); + out[29] = base + ( ( ( w21 >> 19 ) | ( w22 << 45 ) ) & mask ); + out[30] = base + ( ( w22 >> 2 ) & mask ); + out[31] = base + ( ( ( w22 >> 49 ) | ( w23 << 15 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 48-bit values, touching 24 64-bit words, using 192 bytes */ +static void unpackforblock48_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(281474976710655); + /* we are going to access 24 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + *pw += 192; /* we used up 192 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 48 ) | ( w1 << 16 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 32 ) | ( w2 << 32 ) ) & mask ); + out[3] = base + ( w2 >> 16 ); + out[4] = base + ( ( w3 ) & mask ); + out[5] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 32 ) | ( w5 << 32 ) ) & mask ); + out[7] = base + ( w5 >> 16 ); + out[8] = base + ( ( w6 ) & mask ); + out[9] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[10] = base + ( ( ( w7 >> 32 ) | ( w8 << 32 ) ) & mask ); + out[11] = base + ( w8 >> 16 ); + out[12] = base + ( ( w9 ) & mask ); + out[13] = base + ( ( ( w9 >> 48 ) | ( w10 << 16 ) ) & mask ); + out[14] = base + ( ( ( w10 >> 32 ) | ( w11 << 32 ) ) & mask ); + out[15] = base + ( w11 >> 16 ); + out[16] = base + ( ( w12 ) & mask ); + out[17] = base + ( ( ( w12 >> 48 ) | ( w13 << 16 ) ) & mask ); + out[18] = base + ( ( ( w13 >> 32 ) | ( w14 << 32 ) ) & mask ); + out[19] = base + ( w14 >> 16 ); + out[20] = base + ( ( w15 ) & mask ); + out[21] = base + ( ( ( w15 >> 48 ) | ( w16 << 16 ) ) & mask ); + out[22] = base + ( ( ( w16 >> 32 ) | ( w17 << 32 ) ) & mask ); + out[23] = base + ( w17 >> 16 ); + out[24] = base + ( ( w18 ) & mask ); + out[25] = base + ( ( ( w18 >> 48 ) | ( w19 << 16 ) ) & mask ); + out[26] = base + ( ( ( w19 >> 32 ) | ( w20 << 32 ) ) & mask ); + out[27] = base + ( w20 >> 16 ); + out[28] = base + ( ( w21 ) & mask ); + out[29] = base + ( ( ( w21 >> 48 ) | ( w22 << 16 ) ) & mask ); + out[30] = base + ( ( ( w22 >> 32 ) | ( w23 << 32 ) ) & mask ); + out[31] = base + ( w23 >> 16 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 49-bit values, touching 25 64-bit words, using 196 bytes */ +static void unpackforblock49_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(562949953421311); + /* we are going to access 25 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + *pw += 196; /* we used up 196 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 49 ) | ( w1 << 15 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 34 ) | ( w2 << 30 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 19 ) | ( w3 << 45 ) ) & mask ); + out[4] = base + ( ( w3 >> 4 ) & mask ); + out[5] = base + ( ( ( w3 >> 53 ) | ( w4 << 11 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 38 ) | ( w5 << 26 ) ) & mask ); + out[7] = base + ( ( ( w5 >> 23 ) | ( w6 << 41 ) ) & mask ); + out[8] = base + ( ( w6 >> 8 ) & mask ); + out[9] = base + ( ( ( w6 >> 57 ) | ( w7 << 7 ) ) & mask ); + out[10] = base + ( ( ( w7 >> 42 ) | ( w8 << 22 ) ) & mask ); + out[11] = base + ( ( ( w8 >> 27 ) | ( w9 << 37 ) ) & mask ); + out[12] = base + ( ( w9 >> 12 ) & mask ); + out[13] = base + ( ( ( w9 >> 61 ) | ( w10 << 3 ) ) & mask ); + out[14] = base + ( ( ( w10 >> 46 ) | ( w11 << 18 ) ) & mask ); + out[15] = base + ( ( ( w11 >> 31 ) | ( w12 << 33 ) ) & mask ); + out[16] = base + ( ( ( w12 >> 16 ) | ( w13 << 48 ) ) & mask ); + out[17] = base + ( ( w13 >> 1 ) & mask ); + out[18] = base + ( ( ( w13 >> 50 ) | ( w14 << 14 ) ) & mask ); + out[19] = base + ( ( ( w14 >> 35 ) | ( w15 << 29 ) ) & mask ); + out[20] = base + ( ( ( w15 >> 20 ) | ( w16 << 44 ) ) & mask ); + out[21] = base + ( ( w16 >> 5 ) & mask ); + out[22] = base + ( ( ( w16 >> 54 ) | ( w17 << 10 ) ) & mask ); + out[23] = base + ( ( ( w17 >> 39 ) | ( w18 << 25 ) ) & mask ); + out[24] = base + ( ( ( w18 >> 24 ) | ( w19 << 40 ) ) & mask ); + out[25] = base + ( ( w19 >> 9 ) & mask ); + out[26] = base + ( ( ( w19 >> 58 ) | ( w20 << 6 ) ) & mask ); + out[27] = base + ( ( ( w20 >> 43 ) | ( w21 << 21 ) ) & mask ); + out[28] = base + ( ( ( w21 >> 28 ) | ( w22 << 36 ) ) & mask ); + out[29] = base + ( ( w22 >> 13 ) & mask ); + out[30] = base + ( ( ( w22 >> 62 ) | ( w23 << 2 ) ) & mask ); + out[31] = base + ( ( ( w23 >> 47 ) | ( w24 << 17 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 50-bit values, touching 25 64-bit words, using 200 bytes */ +static void unpackforblock50_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1125899906842623); + /* we are going to access 25 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + *pw += 200; /* we used up 200 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 50 ) | ( w1 << 14 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 36 ) | ( w2 << 28 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 22 ) | ( w3 << 42 ) ) & mask ); + out[4] = base + ( ( w3 >> 8 ) & mask ); + out[5] = base + ( ( ( w3 >> 58 ) | ( w4 << 6 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 44 ) | ( w5 << 20 ) ) & mask ); + out[7] = base + ( ( ( w5 >> 30 ) | ( w6 << 34 ) ) & mask ); + out[8] = base + ( ( ( w6 >> 16 ) | ( w7 << 48 ) ) & mask ); + out[9] = base + ( ( w7 >> 2 ) & mask ); + out[10] = base + ( ( ( w7 >> 52 ) | ( w8 << 12 ) ) & mask ); + out[11] = base + ( ( ( w8 >> 38 ) | ( w9 << 26 ) ) & mask ); + out[12] = base + ( ( ( w9 >> 24 ) | ( w10 << 40 ) ) & mask ); + out[13] = base + ( ( w10 >> 10 ) & mask ); + out[14] = base + ( ( ( w10 >> 60 ) | ( w11 << 4 ) ) & mask ); + out[15] = base + ( ( ( w11 >> 46 ) | ( w12 << 18 ) ) & mask ); + out[16] = base + ( ( ( w12 >> 32 ) | ( w13 << 32 ) ) & mask ); + out[17] = base + ( ( ( w13 >> 18 ) | ( w14 << 46 ) ) & mask ); + out[18] = base + ( ( w14 >> 4 ) & mask ); + out[19] = base + ( ( ( w14 >> 54 ) | ( w15 << 10 ) ) & mask ); + out[20] = base + ( ( ( w15 >> 40 ) | ( w16 << 24 ) ) & mask ); + out[21] = base + ( ( ( w16 >> 26 ) | ( w17 << 38 ) ) & mask ); + out[22] = base + ( ( w17 >> 12 ) & mask ); + out[23] = base + ( ( ( w17 >> 62 ) | ( w18 << 2 ) ) & mask ); + out[24] = base + ( ( ( w18 >> 48 ) | ( w19 << 16 ) ) & mask ); + out[25] = base + ( ( ( w19 >> 34 ) | ( w20 << 30 ) ) & mask ); + out[26] = base + ( ( ( w20 >> 20 ) | ( w21 << 44 ) ) & mask ); + out[27] = base + ( ( w21 >> 6 ) & mask ); + out[28] = base + ( ( ( w21 >> 56 ) | ( w22 << 8 ) ) & mask ); + out[29] = base + ( ( ( w22 >> 42 ) | ( w23 << 22 ) ) & mask ); + out[30] = base + ( ( ( w23 >> 28 ) | ( w24 << 36 ) ) & mask ); + out[31] = base + ( w24 >> 14 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 51-bit values, touching 26 64-bit words, using 204 bytes */ +static void unpackforblock51_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2251799813685247); + /* we are going to access 26 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + *pw += 204; /* we used up 204 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 51 ) | ( w1 << 13 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 38 ) | ( w2 << 26 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 25 ) | ( w3 << 39 ) ) & mask ); + out[4] = base + ( ( w3 >> 12 ) & mask ); + out[5] = base + ( ( ( w3 >> 63 ) | ( w4 << 1 ) ) & mask ); + out[6] = base + ( ( ( w4 >> 50 ) | ( w5 << 14 ) ) & mask ); + out[7] = base + ( ( ( w5 >> 37 ) | ( w6 << 27 ) ) & mask ); + out[8] = base + ( ( ( w6 >> 24 ) | ( w7 << 40 ) ) & mask ); + out[9] = base + ( ( w7 >> 11 ) & mask ); + out[10] = base + ( ( ( w7 >> 62 ) | ( w8 << 2 ) ) & mask ); + out[11] = base + ( ( ( w8 >> 49 ) | ( w9 << 15 ) ) & mask ); + out[12] = base + ( ( ( w9 >> 36 ) | ( w10 << 28 ) ) & mask ); + out[13] = base + ( ( ( w10 >> 23 ) | ( w11 << 41 ) ) & mask ); + out[14] = base + ( ( w11 >> 10 ) & mask ); + out[15] = base + ( ( ( w11 >> 61 ) | ( w12 << 3 ) ) & mask ); + out[16] = base + ( ( ( w12 >> 48 ) | ( w13 << 16 ) ) & mask ); + out[17] = base + ( ( ( w13 >> 35 ) | ( w14 << 29 ) ) & mask ); + out[18] = base + ( ( ( w14 >> 22 ) | ( w15 << 42 ) ) & mask ); + out[19] = base + ( ( w15 >> 9 ) & mask ); + out[20] = base + ( ( ( w15 >> 60 ) | ( w16 << 4 ) ) & mask ); + out[21] = base + ( ( ( w16 >> 47 ) | ( w17 << 17 ) ) & mask ); + out[22] = base + ( ( ( w17 >> 34 ) | ( w18 << 30 ) ) & mask ); + out[23] = base + ( ( ( w18 >> 21 ) | ( w19 << 43 ) ) & mask ); + out[24] = base + ( ( w19 >> 8 ) & mask ); + out[25] = base + ( ( ( w19 >> 59 ) | ( w20 << 5 ) ) & mask ); + out[26] = base + ( ( ( w20 >> 46 ) | ( w21 << 18 ) ) & mask ); + out[27] = base + ( ( ( w21 >> 33 ) | ( w22 << 31 ) ) & mask ); + out[28] = base + ( ( ( w22 >> 20 ) | ( w23 << 44 ) ) & mask ); + out[29] = base + ( ( w23 >> 7 ) & mask ); + out[30] = base + ( ( ( w23 >> 58 ) | ( w24 << 6 ) ) & mask ); + out[31] = base + ( ( ( w24 >> 45 ) | ( w25 << 19 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 52-bit values, touching 26 64-bit words, using 208 bytes */ +static void unpackforblock52_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4503599627370495); + /* we are going to access 26 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + *pw += 208; /* we used up 208 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 52 ) | ( w1 << 12 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 40 ) | ( w2 << 24 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 28 ) | ( w3 << 36 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 16 ) | ( w4 << 48 ) ) & mask ); + out[5] = base + ( ( w4 >> 4 ) & mask ); + out[6] = base + ( ( ( w4 >> 56 ) | ( w5 << 8 ) ) & mask ); + out[7] = base + ( ( ( w5 >> 44 ) | ( w6 << 20 ) ) & mask ); + out[8] = base + ( ( ( w6 >> 32 ) | ( w7 << 32 ) ) & mask ); + out[9] = base + ( ( ( w7 >> 20 ) | ( w8 << 44 ) ) & mask ); + out[10] = base + ( ( w8 >> 8 ) & mask ); + out[11] = base + ( ( ( w8 >> 60 ) | ( w9 << 4 ) ) & mask ); + out[12] = base + ( ( ( w9 >> 48 ) | ( w10 << 16 ) ) & mask ); + out[13] = base + ( ( ( w10 >> 36 ) | ( w11 << 28 ) ) & mask ); + out[14] = base + ( ( ( w11 >> 24 ) | ( w12 << 40 ) ) & mask ); + out[15] = base + ( w12 >> 12 ); + out[16] = base + ( ( w13 ) & mask ); + out[17] = base + ( ( ( w13 >> 52 ) | ( w14 << 12 ) ) & mask ); + out[18] = base + ( ( ( w14 >> 40 ) | ( w15 << 24 ) ) & mask ); + out[19] = base + ( ( ( w15 >> 28 ) | ( w16 << 36 ) ) & mask ); + out[20] = base + ( ( ( w16 >> 16 ) | ( w17 << 48 ) ) & mask ); + out[21] = base + ( ( w17 >> 4 ) & mask ); + out[22] = base + ( ( ( w17 >> 56 ) | ( w18 << 8 ) ) & mask ); + out[23] = base + ( ( ( w18 >> 44 ) | ( w19 << 20 ) ) & mask ); + out[24] = base + ( ( ( w19 >> 32 ) | ( w20 << 32 ) ) & mask ); + out[25] = base + ( ( ( w20 >> 20 ) | ( w21 << 44 ) ) & mask ); + out[26] = base + ( ( w21 >> 8 ) & mask ); + out[27] = base + ( ( ( w21 >> 60 ) | ( w22 << 4 ) ) & mask ); + out[28] = base + ( ( ( w22 >> 48 ) | ( w23 << 16 ) ) & mask ); + out[29] = base + ( ( ( w23 >> 36 ) | ( w24 << 28 ) ) & mask ); + out[30] = base + ( ( ( w24 >> 24 ) | ( w25 << 40 ) ) & mask ); + out[31] = base + ( w25 >> 12 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 53-bit values, touching 27 64-bit words, using 212 bytes */ +static void unpackforblock53_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(9007199254740991); + /* we are going to access 27 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + *pw += 212; /* we used up 212 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 53 ) | ( w1 << 11 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 42 ) | ( w2 << 22 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 31 ) | ( w3 << 33 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 20 ) | ( w4 << 44 ) ) & mask ); + out[5] = base + ( ( w4 >> 9 ) & mask ); + out[6] = base + ( ( ( w4 >> 62 ) | ( w5 << 2 ) ) & mask ); + out[7] = base + ( ( ( w5 >> 51 ) | ( w6 << 13 ) ) & mask ); + out[8] = base + ( ( ( w6 >> 40 ) | ( w7 << 24 ) ) & mask ); + out[9] = base + ( ( ( w7 >> 29 ) | ( w8 << 35 ) ) & mask ); + out[10] = base + ( ( ( w8 >> 18 ) | ( w9 << 46 ) ) & mask ); + out[11] = base + ( ( w9 >> 7 ) & mask ); + out[12] = base + ( ( ( w9 >> 60 ) | ( w10 << 4 ) ) & mask ); + out[13] = base + ( ( ( w10 >> 49 ) | ( w11 << 15 ) ) & mask ); + out[14] = base + ( ( ( w11 >> 38 ) | ( w12 << 26 ) ) & mask ); + out[15] = base + ( ( ( w12 >> 27 ) | ( w13 << 37 ) ) & mask ); + out[16] = base + ( ( ( w13 >> 16 ) | ( w14 << 48 ) ) & mask ); + out[17] = base + ( ( w14 >> 5 ) & mask ); + out[18] = base + ( ( ( w14 >> 58 ) | ( w15 << 6 ) ) & mask ); + out[19] = base + ( ( ( w15 >> 47 ) | ( w16 << 17 ) ) & mask ); + out[20] = base + ( ( ( w16 >> 36 ) | ( w17 << 28 ) ) & mask ); + out[21] = base + ( ( ( w17 >> 25 ) | ( w18 << 39 ) ) & mask ); + out[22] = base + ( ( ( w18 >> 14 ) | ( w19 << 50 ) ) & mask ); + out[23] = base + ( ( w19 >> 3 ) & mask ); + out[24] = base + ( ( ( w19 >> 56 ) | ( w20 << 8 ) ) & mask ); + out[25] = base + ( ( ( w20 >> 45 ) | ( w21 << 19 ) ) & mask ); + out[26] = base + ( ( ( w21 >> 34 ) | ( w22 << 30 ) ) & mask ); + out[27] = base + ( ( ( w22 >> 23 ) | ( w23 << 41 ) ) & mask ); + out[28] = base + ( ( ( w23 >> 12 ) | ( w24 << 52 ) ) & mask ); + out[29] = base + ( ( w24 >> 1 ) & mask ); + out[30] = base + ( ( ( w24 >> 54 ) | ( w25 << 10 ) ) & mask ); + out[31] = base + ( ( ( w25 >> 43 ) | ( w26 << 21 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 54-bit values, touching 27 64-bit words, using 216 bytes */ +static void unpackforblock54_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(18014398509481983); + /* we are going to access 27 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + *pw += 216; /* we used up 216 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 54 ) | ( w1 << 10 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 44 ) | ( w2 << 20 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 34 ) | ( w3 << 30 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 24 ) | ( w4 << 40 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 14 ) | ( w5 << 50 ) ) & mask ); + out[6] = base + ( ( w5 >> 4 ) & mask ); + out[7] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[8] = base + ( ( ( w6 >> 48 ) | ( w7 << 16 ) ) & mask ); + out[9] = base + ( ( ( w7 >> 38 ) | ( w8 << 26 ) ) & mask ); + out[10] = base + ( ( ( w8 >> 28 ) | ( w9 << 36 ) ) & mask ); + out[11] = base + ( ( ( w9 >> 18 ) | ( w10 << 46 ) ) & mask ); + out[12] = base + ( ( w10 >> 8 ) & mask ); + out[13] = base + ( ( ( w10 >> 62 ) | ( w11 << 2 ) ) & mask ); + out[14] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[15] = base + ( ( ( w12 >> 42 ) | ( w13 << 22 ) ) & mask ); + out[16] = base + ( ( ( w13 >> 32 ) | ( w14 << 32 ) ) & mask ); + out[17] = base + ( ( ( w14 >> 22 ) | ( w15 << 42 ) ) & mask ); + out[18] = base + ( ( ( w15 >> 12 ) | ( w16 << 52 ) ) & mask ); + out[19] = base + ( ( w16 >> 2 ) & mask ); + out[20] = base + ( ( ( w16 >> 56 ) | ( w17 << 8 ) ) & mask ); + out[21] = base + ( ( ( w17 >> 46 ) | ( w18 << 18 ) ) & mask ); + out[22] = base + ( ( ( w18 >> 36 ) | ( w19 << 28 ) ) & mask ); + out[23] = base + ( ( ( w19 >> 26 ) | ( w20 << 38 ) ) & mask ); + out[24] = base + ( ( ( w20 >> 16 ) | ( w21 << 48 ) ) & mask ); + out[25] = base + ( ( w21 >> 6 ) & mask ); + out[26] = base + ( ( ( w21 >> 60 ) | ( w22 << 4 ) ) & mask ); + out[27] = base + ( ( ( w22 >> 50 ) | ( w23 << 14 ) ) & mask ); + out[28] = base + ( ( ( w23 >> 40 ) | ( w24 << 24 ) ) & mask ); + out[29] = base + ( ( ( w24 >> 30 ) | ( w25 << 34 ) ) & mask ); + out[30] = base + ( ( ( w25 >> 20 ) | ( w26 << 44 ) ) & mask ); + out[31] = base + ( w26 >> 10 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 55-bit values, touching 28 64-bit words, using 220 bytes */ +static void unpackforblock55_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(36028797018963967); + /* we are going to access 28 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + *pw += 220; /* we used up 220 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 55 ) | ( w1 << 9 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 46 ) | ( w2 << 18 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 37 ) | ( w3 << 27 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 28 ) | ( w4 << 36 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 19 ) | ( w5 << 45 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 10 ) | ( w6 << 54 ) ) & mask ); + out[7] = base + ( ( w6 >> 1 ) & mask ); + out[8] = base + ( ( ( w6 >> 56 ) | ( w7 << 8 ) ) & mask ); + out[9] = base + ( ( ( w7 >> 47 ) | ( w8 << 17 ) ) & mask ); + out[10] = base + ( ( ( w8 >> 38 ) | ( w9 << 26 ) ) & mask ); + out[11] = base + ( ( ( w9 >> 29 ) | ( w10 << 35 ) ) & mask ); + out[12] = base + ( ( ( w10 >> 20 ) | ( w11 << 44 ) ) & mask ); + out[13] = base + ( ( ( w11 >> 11 ) | ( w12 << 53 ) ) & mask ); + out[14] = base + ( ( w12 >> 2 ) & mask ); + out[15] = base + ( ( ( w12 >> 57 ) | ( w13 << 7 ) ) & mask ); + out[16] = base + ( ( ( w13 >> 48 ) | ( w14 << 16 ) ) & mask ); + out[17] = base + ( ( ( w14 >> 39 ) | ( w15 << 25 ) ) & mask ); + out[18] = base + ( ( ( w15 >> 30 ) | ( w16 << 34 ) ) & mask ); + out[19] = base + ( ( ( w16 >> 21 ) | ( w17 << 43 ) ) & mask ); + out[20] = base + ( ( ( w17 >> 12 ) | ( w18 << 52 ) ) & mask ); + out[21] = base + ( ( w18 >> 3 ) & mask ); + out[22] = base + ( ( ( w18 >> 58 ) | ( w19 << 6 ) ) & mask ); + out[23] = base + ( ( ( w19 >> 49 ) | ( w20 << 15 ) ) & mask ); + out[24] = base + ( ( ( w20 >> 40 ) | ( w21 << 24 ) ) & mask ); + out[25] = base + ( ( ( w21 >> 31 ) | ( w22 << 33 ) ) & mask ); + out[26] = base + ( ( ( w22 >> 22 ) | ( w23 << 42 ) ) & mask ); + out[27] = base + ( ( ( w23 >> 13 ) | ( w24 << 51 ) ) & mask ); + out[28] = base + ( ( w24 >> 4 ) & mask ); + out[29] = base + ( ( ( w24 >> 59 ) | ( w25 << 5 ) ) & mask ); + out[30] = base + ( ( ( w25 >> 50 ) | ( w26 << 14 ) ) & mask ); + out[31] = base + ( ( ( w26 >> 41 ) | ( w27 << 23 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 56-bit values, touching 28 64-bit words, using 224 bytes */ +static void unpackforblock56_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(72057594037927935); + /* we are going to access 28 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + *pw += 224; /* we used up 224 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 56 ) | ( w1 << 8 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 48 ) | ( w2 << 16 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 40 ) | ( w3 << 24 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 32 ) | ( w4 << 32 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 24 ) | ( w5 << 40 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 16 ) | ( w6 << 48 ) ) & mask ); + out[7] = base + ( w6 >> 8 ); + out[8] = base + ( ( w7 ) & mask ); + out[9] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[10] = base + ( ( ( w8 >> 48 ) | ( w9 << 16 ) ) & mask ); + out[11] = base + ( ( ( w9 >> 40 ) | ( w10 << 24 ) ) & mask ); + out[12] = base + ( ( ( w10 >> 32 ) | ( w11 << 32 ) ) & mask ); + out[13] = base + ( ( ( w11 >> 24 ) | ( w12 << 40 ) ) & mask ); + out[14] = base + ( ( ( w12 >> 16 ) | ( w13 << 48 ) ) & mask ); + out[15] = base + ( w13 >> 8 ); + out[16] = base + ( ( w14 ) & mask ); + out[17] = base + ( ( ( w14 >> 56 ) | ( w15 << 8 ) ) & mask ); + out[18] = base + ( ( ( w15 >> 48 ) | ( w16 << 16 ) ) & mask ); + out[19] = base + ( ( ( w16 >> 40 ) | ( w17 << 24 ) ) & mask ); + out[20] = base + ( ( ( w17 >> 32 ) | ( w18 << 32 ) ) & mask ); + out[21] = base + ( ( ( w18 >> 24 ) | ( w19 << 40 ) ) & mask ); + out[22] = base + ( ( ( w19 >> 16 ) | ( w20 << 48 ) ) & mask ); + out[23] = base + ( w20 >> 8 ); + out[24] = base + ( ( w21 ) & mask ); + out[25] = base + ( ( ( w21 >> 56 ) | ( w22 << 8 ) ) & mask ); + out[26] = base + ( ( ( w22 >> 48 ) | ( w23 << 16 ) ) & mask ); + out[27] = base + ( ( ( w23 >> 40 ) | ( w24 << 24 ) ) & mask ); + out[28] = base + ( ( ( w24 >> 32 ) | ( w25 << 32 ) ) & mask ); + out[29] = base + ( ( ( w25 >> 24 ) | ( w26 << 40 ) ) & mask ); + out[30] = base + ( ( ( w26 >> 16 ) | ( w27 << 48 ) ) & mask ); + out[31] = base + ( w27 >> 8 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 57-bit values, touching 29 64-bit words, using 228 bytes */ +static void unpackforblock57_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(144115188075855871); + /* we are going to access 29 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + *pw += 228; /* we used up 228 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 57 ) | ( w1 << 7 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 50 ) | ( w2 << 14 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 43 ) | ( w3 << 21 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 36 ) | ( w4 << 28 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 29 ) | ( w5 << 35 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 22 ) | ( w6 << 42 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 15 ) | ( w7 << 49 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 8 ) | ( w8 << 56 ) ) & mask ); + out[9] = base + ( ( w8 >> 1 ) & mask ); + out[10] = base + ( ( ( w8 >> 58 ) | ( w9 << 6 ) ) & mask ); + out[11] = base + ( ( ( w9 >> 51 ) | ( w10 << 13 ) ) & mask ); + out[12] = base + ( ( ( w10 >> 44 ) | ( w11 << 20 ) ) & mask ); + out[13] = base + ( ( ( w11 >> 37 ) | ( w12 << 27 ) ) & mask ); + out[14] = base + ( ( ( w12 >> 30 ) | ( w13 << 34 ) ) & mask ); + out[15] = base + ( ( ( w13 >> 23 ) | ( w14 << 41 ) ) & mask ); + out[16] = base + ( ( ( w14 >> 16 ) | ( w15 << 48 ) ) & mask ); + out[17] = base + ( ( ( w15 >> 9 ) | ( w16 << 55 ) ) & mask ); + out[18] = base + ( ( w16 >> 2 ) & mask ); + out[19] = base + ( ( ( w16 >> 59 ) | ( w17 << 5 ) ) & mask ); + out[20] = base + ( ( ( w17 >> 52 ) | ( w18 << 12 ) ) & mask ); + out[21] = base + ( ( ( w18 >> 45 ) | ( w19 << 19 ) ) & mask ); + out[22] = base + ( ( ( w19 >> 38 ) | ( w20 << 26 ) ) & mask ); + out[23] = base + ( ( ( w20 >> 31 ) | ( w21 << 33 ) ) & mask ); + out[24] = base + ( ( ( w21 >> 24 ) | ( w22 << 40 ) ) & mask ); + out[25] = base + ( ( ( w22 >> 17 ) | ( w23 << 47 ) ) & mask ); + out[26] = base + ( ( ( w23 >> 10 ) | ( w24 << 54 ) ) & mask ); + out[27] = base + ( ( w24 >> 3 ) & mask ); + out[28] = base + ( ( ( w24 >> 60 ) | ( w25 << 4 ) ) & mask ); + out[29] = base + ( ( ( w25 >> 53 ) | ( w26 << 11 ) ) & mask ); + out[30] = base + ( ( ( w26 >> 46 ) | ( w27 << 18 ) ) & mask ); + out[31] = base + ( ( ( w27 >> 39 ) | ( w28 << 25 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 58-bit values, touching 29 64-bit words, using 232 bytes */ +static void unpackforblock58_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(288230376151711743); + /* we are going to access 29 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + *pw += 232; /* we used up 232 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 58 ) | ( w1 << 6 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 52 ) | ( w2 << 12 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 46 ) | ( w3 << 18 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 40 ) | ( w4 << 24 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 34 ) | ( w5 << 30 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 28 ) | ( w6 << 36 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 22 ) | ( w7 << 42 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 16 ) | ( w8 << 48 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 10 ) | ( w9 << 54 ) ) & mask ); + out[10] = base + ( ( w9 >> 4 ) & mask ); + out[11] = base + ( ( ( w9 >> 62 ) | ( w10 << 2 ) ) & mask ); + out[12] = base + ( ( ( w10 >> 56 ) | ( w11 << 8 ) ) & mask ); + out[13] = base + ( ( ( w11 >> 50 ) | ( w12 << 14 ) ) & mask ); + out[14] = base + ( ( ( w12 >> 44 ) | ( w13 << 20 ) ) & mask ); + out[15] = base + ( ( ( w13 >> 38 ) | ( w14 << 26 ) ) & mask ); + out[16] = base + ( ( ( w14 >> 32 ) | ( w15 << 32 ) ) & mask ); + out[17] = base + ( ( ( w15 >> 26 ) | ( w16 << 38 ) ) & mask ); + out[18] = base + ( ( ( w16 >> 20 ) | ( w17 << 44 ) ) & mask ); + out[19] = base + ( ( ( w17 >> 14 ) | ( w18 << 50 ) ) & mask ); + out[20] = base + ( ( ( w18 >> 8 ) | ( w19 << 56 ) ) & mask ); + out[21] = base + ( ( w19 >> 2 ) & mask ); + out[22] = base + ( ( ( w19 >> 60 ) | ( w20 << 4 ) ) & mask ); + out[23] = base + ( ( ( w20 >> 54 ) | ( w21 << 10 ) ) & mask ); + out[24] = base + ( ( ( w21 >> 48 ) | ( w22 << 16 ) ) & mask ); + out[25] = base + ( ( ( w22 >> 42 ) | ( w23 << 22 ) ) & mask ); + out[26] = base + ( ( ( w23 >> 36 ) | ( w24 << 28 ) ) & mask ); + out[27] = base + ( ( ( w24 >> 30 ) | ( w25 << 34 ) ) & mask ); + out[28] = base + ( ( ( w25 >> 24 ) | ( w26 << 40 ) ) & mask ); + out[29] = base + ( ( ( w26 >> 18 ) | ( w27 << 46 ) ) & mask ); + out[30] = base + ( ( ( w27 >> 12 ) | ( w28 << 52 ) ) & mask ); + out[31] = base + ( w28 >> 6 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 59-bit values, touching 30 64-bit words, using 236 bytes */ +static void unpackforblock59_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(576460752303423487); + /* we are going to access 30 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + *pw += 236; /* we used up 236 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 59 ) | ( w1 << 5 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 54 ) | ( w2 << 10 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 49 ) | ( w3 << 15 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 44 ) | ( w4 << 20 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 39 ) | ( w5 << 25 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 34 ) | ( w6 << 30 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 29 ) | ( w7 << 35 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 24 ) | ( w8 << 40 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 19 ) | ( w9 << 45 ) ) & mask ); + out[10] = base + ( ( ( w9 >> 14 ) | ( w10 << 50 ) ) & mask ); + out[11] = base + ( ( ( w10 >> 9 ) | ( w11 << 55 ) ) & mask ); + out[12] = base + ( ( w11 >> 4 ) & mask ); + out[13] = base + ( ( ( w11 >> 63 ) | ( w12 << 1 ) ) & mask ); + out[14] = base + ( ( ( w12 >> 58 ) | ( w13 << 6 ) ) & mask ); + out[15] = base + ( ( ( w13 >> 53 ) | ( w14 << 11 ) ) & mask ); + out[16] = base + ( ( ( w14 >> 48 ) | ( w15 << 16 ) ) & mask ); + out[17] = base + ( ( ( w15 >> 43 ) | ( w16 << 21 ) ) & mask ); + out[18] = base + ( ( ( w16 >> 38 ) | ( w17 << 26 ) ) & mask ); + out[19] = base + ( ( ( w17 >> 33 ) | ( w18 << 31 ) ) & mask ); + out[20] = base + ( ( ( w18 >> 28 ) | ( w19 << 36 ) ) & mask ); + out[21] = base + ( ( ( w19 >> 23 ) | ( w20 << 41 ) ) & mask ); + out[22] = base + ( ( ( w20 >> 18 ) | ( w21 << 46 ) ) & mask ); + out[23] = base + ( ( ( w21 >> 13 ) | ( w22 << 51 ) ) & mask ); + out[24] = base + ( ( ( w22 >> 8 ) | ( w23 << 56 ) ) & mask ); + out[25] = base + ( ( w23 >> 3 ) & mask ); + out[26] = base + ( ( ( w23 >> 62 ) | ( w24 << 2 ) ) & mask ); + out[27] = base + ( ( ( w24 >> 57 ) | ( w25 << 7 ) ) & mask ); + out[28] = base + ( ( ( w25 >> 52 ) | ( w26 << 12 ) ) & mask ); + out[29] = base + ( ( ( w26 >> 47 ) | ( w27 << 17 ) ) & mask ); + out[30] = base + ( ( ( w27 >> 42 ) | ( w28 << 22 ) ) & mask ); + out[31] = base + ( ( ( w28 >> 37 ) | ( w29 << 27 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 60-bit values, touching 30 64-bit words, using 240 bytes */ +static void unpackforblock60_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(1152921504606846975); + /* we are going to access 30 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + *pw += 240; /* we used up 240 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 60 ) | ( w1 << 4 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 56 ) | ( w2 << 8 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 52 ) | ( w3 << 12 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 48 ) | ( w4 << 16 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 44 ) | ( w5 << 20 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 40 ) | ( w6 << 24 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 36 ) | ( w7 << 28 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 32 ) | ( w8 << 32 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 28 ) | ( w9 << 36 ) ) & mask ); + out[10] = base + ( ( ( w9 >> 24 ) | ( w10 << 40 ) ) & mask ); + out[11] = base + ( ( ( w10 >> 20 ) | ( w11 << 44 ) ) & mask ); + out[12] = base + ( ( ( w11 >> 16 ) | ( w12 << 48 ) ) & mask ); + out[13] = base + ( ( ( w12 >> 12 ) | ( w13 << 52 ) ) & mask ); + out[14] = base + ( ( ( w13 >> 8 ) | ( w14 << 56 ) ) & mask ); + out[15] = base + ( w14 >> 4 ); + out[16] = base + ( ( w15 ) & mask ); + out[17] = base + ( ( ( w15 >> 60 ) | ( w16 << 4 ) ) & mask ); + out[18] = base + ( ( ( w16 >> 56 ) | ( w17 << 8 ) ) & mask ); + out[19] = base + ( ( ( w17 >> 52 ) | ( w18 << 12 ) ) & mask ); + out[20] = base + ( ( ( w18 >> 48 ) | ( w19 << 16 ) ) & mask ); + out[21] = base + ( ( ( w19 >> 44 ) | ( w20 << 20 ) ) & mask ); + out[22] = base + ( ( ( w20 >> 40 ) | ( w21 << 24 ) ) & mask ); + out[23] = base + ( ( ( w21 >> 36 ) | ( w22 << 28 ) ) & mask ); + out[24] = base + ( ( ( w22 >> 32 ) | ( w23 << 32 ) ) & mask ); + out[25] = base + ( ( ( w23 >> 28 ) | ( w24 << 36 ) ) & mask ); + out[26] = base + ( ( ( w24 >> 24 ) | ( w25 << 40 ) ) & mask ); + out[27] = base + ( ( ( w25 >> 20 ) | ( w26 << 44 ) ) & mask ); + out[28] = base + ( ( ( w26 >> 16 ) | ( w27 << 48 ) ) & mask ); + out[29] = base + ( ( ( w27 >> 12 ) | ( w28 << 52 ) ) & mask ); + out[30] = base + ( ( ( w28 >> 8 ) | ( w29 << 56 ) ) & mask ); + out[31] = base + ( w29 >> 4 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 61-bit values, touching 31 64-bit words, using 244 bytes */ +static void unpackforblock61_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(2305843009213693951); + /* we are going to access 31 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + uint64_t w30 = pw64[30]; + *pw += 244; /* we used up 244 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 61 ) | ( w1 << 3 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 58 ) | ( w2 << 6 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 55 ) | ( w3 << 9 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 52 ) | ( w4 << 12 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 49 ) | ( w5 << 15 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 46 ) | ( w6 << 18 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 43 ) | ( w7 << 21 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 40 ) | ( w8 << 24 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 37 ) | ( w9 << 27 ) ) & mask ); + out[10] = base + ( ( ( w9 >> 34 ) | ( w10 << 30 ) ) & mask ); + out[11] = base + ( ( ( w10 >> 31 ) | ( w11 << 33 ) ) & mask ); + out[12] = base + ( ( ( w11 >> 28 ) | ( w12 << 36 ) ) & mask ); + out[13] = base + ( ( ( w12 >> 25 ) | ( w13 << 39 ) ) & mask ); + out[14] = base + ( ( ( w13 >> 22 ) | ( w14 << 42 ) ) & mask ); + out[15] = base + ( ( ( w14 >> 19 ) | ( w15 << 45 ) ) & mask ); + out[16] = base + ( ( ( w15 >> 16 ) | ( w16 << 48 ) ) & mask ); + out[17] = base + ( ( ( w16 >> 13 ) | ( w17 << 51 ) ) & mask ); + out[18] = base + ( ( ( w17 >> 10 ) | ( w18 << 54 ) ) & mask ); + out[19] = base + ( ( ( w18 >> 7 ) | ( w19 << 57 ) ) & mask ); + out[20] = base + ( ( ( w19 >> 4 ) | ( w20 << 60 ) ) & mask ); + out[21] = base + ( ( w20 >> 1 ) & mask ); + out[22] = base + ( ( ( w20 >> 62 ) | ( w21 << 2 ) ) & mask ); + out[23] = base + ( ( ( w21 >> 59 ) | ( w22 << 5 ) ) & mask ); + out[24] = base + ( ( ( w22 >> 56 ) | ( w23 << 8 ) ) & mask ); + out[25] = base + ( ( ( w23 >> 53 ) | ( w24 << 11 ) ) & mask ); + out[26] = base + ( ( ( w24 >> 50 ) | ( w25 << 14 ) ) & mask ); + out[27] = base + ( ( ( w25 >> 47 ) | ( w26 << 17 ) ) & mask ); + out[28] = base + ( ( ( w26 >> 44 ) | ( w27 << 20 ) ) & mask ); + out[29] = base + ( ( ( w27 >> 41 ) | ( w28 << 23 ) ) & mask ); + out[30] = base + ( ( ( w28 >> 38 ) | ( w29 << 26 ) ) & mask ); + out[31] = base + ( ( ( w29 >> 35 ) | ( w30 << 29 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 62-bit values, touching 31 64-bit words, using 248 bytes */ +static void unpackforblock62_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(4611686018427387903); + /* we are going to access 31 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + uint64_t w30 = pw64[30]; + *pw += 248; /* we used up 248 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 62 ) | ( w1 << 2 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 60 ) | ( w2 << 4 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 58 ) | ( w3 << 6 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 56 ) | ( w4 << 8 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 54 ) | ( w5 << 10 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 52 ) | ( w6 << 12 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 50 ) | ( w7 << 14 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 48 ) | ( w8 << 16 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 46 ) | ( w9 << 18 ) ) & mask ); + out[10] = base + ( ( ( w9 >> 44 ) | ( w10 << 20 ) ) & mask ); + out[11] = base + ( ( ( w10 >> 42 ) | ( w11 << 22 ) ) & mask ); + out[12] = base + ( ( ( w11 >> 40 ) | ( w12 << 24 ) ) & mask ); + out[13] = base + ( ( ( w12 >> 38 ) | ( w13 << 26 ) ) & mask ); + out[14] = base + ( ( ( w13 >> 36 ) | ( w14 << 28 ) ) & mask ); + out[15] = base + ( ( ( w14 >> 34 ) | ( w15 << 30 ) ) & mask ); + out[16] = base + ( ( ( w15 >> 32 ) | ( w16 << 32 ) ) & mask ); + out[17] = base + ( ( ( w16 >> 30 ) | ( w17 << 34 ) ) & mask ); + out[18] = base + ( ( ( w17 >> 28 ) | ( w18 << 36 ) ) & mask ); + out[19] = base + ( ( ( w18 >> 26 ) | ( w19 << 38 ) ) & mask ); + out[20] = base + ( ( ( w19 >> 24 ) | ( w20 << 40 ) ) & mask ); + out[21] = base + ( ( ( w20 >> 22 ) | ( w21 << 42 ) ) & mask ); + out[22] = base + ( ( ( w21 >> 20 ) | ( w22 << 44 ) ) & mask ); + out[23] = base + ( ( ( w22 >> 18 ) | ( w23 << 46 ) ) & mask ); + out[24] = base + ( ( ( w23 >> 16 ) | ( w24 << 48 ) ) & mask ); + out[25] = base + ( ( ( w24 >> 14 ) | ( w25 << 50 ) ) & mask ); + out[26] = base + ( ( ( w25 >> 12 ) | ( w26 << 52 ) ) & mask ); + out[27] = base + ( ( ( w26 >> 10 ) | ( w27 << 54 ) ) & mask ); + out[28] = base + ( ( ( w27 >> 8 ) | ( w28 << 56 ) ) & mask ); + out[29] = base + ( ( ( w28 >> 6 ) | ( w29 << 58 ) ) & mask ); + out[30] = base + ( ( ( w29 >> 4 ) | ( w30 << 60 ) ) & mask ); + out[31] = base + ( w30 >> 2 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 63-bit values, touching 32 64-bit words, using 252 bytes */ +static void unpackforblock63_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + const uint64_t mask = UINT64_C(9223372036854775807); + /* we are going to access 32 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + uint64_t w30 = pw64[30]; + uint64_t w31 = pw64[31]; + *pw += 252; /* we used up 252 input bytes */ + out[0] = base + ( ( w0 ) & mask ); + out[1] = base + ( ( ( w0 >> 63 ) | ( w1 << 1 ) ) & mask ); + out[2] = base + ( ( ( w1 >> 62 ) | ( w2 << 2 ) ) & mask ); + out[3] = base + ( ( ( w2 >> 61 ) | ( w3 << 3 ) ) & mask ); + out[4] = base + ( ( ( w3 >> 60 ) | ( w4 << 4 ) ) & mask ); + out[5] = base + ( ( ( w4 >> 59 ) | ( w5 << 5 ) ) & mask ); + out[6] = base + ( ( ( w5 >> 58 ) | ( w6 << 6 ) ) & mask ); + out[7] = base + ( ( ( w6 >> 57 ) | ( w7 << 7 ) ) & mask ); + out[8] = base + ( ( ( w7 >> 56 ) | ( w8 << 8 ) ) & mask ); + out[9] = base + ( ( ( w8 >> 55 ) | ( w9 << 9 ) ) & mask ); + out[10] = base + ( ( ( w9 >> 54 ) | ( w10 << 10 ) ) & mask ); + out[11] = base + ( ( ( w10 >> 53 ) | ( w11 << 11 ) ) & mask ); + out[12] = base + ( ( ( w11 >> 52 ) | ( w12 << 12 ) ) & mask ); + out[13] = base + ( ( ( w12 >> 51 ) | ( w13 << 13 ) ) & mask ); + out[14] = base + ( ( ( w13 >> 50 ) | ( w14 << 14 ) ) & mask ); + out[15] = base + ( ( ( w14 >> 49 ) | ( w15 << 15 ) ) & mask ); + out[16] = base + ( ( ( w15 >> 48 ) | ( w16 << 16 ) ) & mask ); + out[17] = base + ( ( ( w16 >> 47 ) | ( w17 << 17 ) ) & mask ); + out[18] = base + ( ( ( w17 >> 46 ) | ( w18 << 18 ) ) & mask ); + out[19] = base + ( ( ( w18 >> 45 ) | ( w19 << 19 ) ) & mask ); + out[20] = base + ( ( ( w19 >> 44 ) | ( w20 << 20 ) ) & mask ); + out[21] = base + ( ( ( w20 >> 43 ) | ( w21 << 21 ) ) & mask ); + out[22] = base + ( ( ( w21 >> 42 ) | ( w22 << 22 ) ) & mask ); + out[23] = base + ( ( ( w22 >> 41 ) | ( w23 << 23 ) ) & mask ); + out[24] = base + ( ( ( w23 >> 40 ) | ( w24 << 24 ) ) & mask ); + out[25] = base + ( ( ( w24 >> 39 ) | ( w25 << 25 ) ) & mask ); + out[26] = base + ( ( ( w25 >> 38 ) | ( w26 << 26 ) ) & mask ); + out[27] = base + ( ( ( w26 >> 37 ) | ( w27 << 27 ) ) & mask ); + out[28] = base + ( ( ( w27 >> 36 ) | ( w28 << 28 ) ) & mask ); + out[29] = base + ( ( ( w28 >> 35 ) | ( w29 << 29 ) ) & mask ); + out[30] = base + ( ( ( w29 >> 34 ) | ( w30 << 30 ) ) & mask ); + out[31] = base + ( ( ( w30 >> 33 ) | ( w31 << 31 ) ) & mask ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + + +/* we packed 32 64-bit values, touching 32 64-bit words, using 256 bytes */ +static void unpackforblock64_64(const uint64_t base, const uint8_t ** pw, uint64_t ** pout) { + const uint64_t * pw64 = *(const uint64_t **) pw; + uint64_t * out = *pout; + /* we are going to access 32 64-bit words */ + uint64_t w0 = pw64[0]; + uint64_t w1 = pw64[1]; + uint64_t w2 = pw64[2]; + uint64_t w3 = pw64[3]; + uint64_t w4 = pw64[4]; + uint64_t w5 = pw64[5]; + uint64_t w6 = pw64[6]; + uint64_t w7 = pw64[7]; + uint64_t w8 = pw64[8]; + uint64_t w9 = pw64[9]; + uint64_t w10 = pw64[10]; + uint64_t w11 = pw64[11]; + uint64_t w12 = pw64[12]; + uint64_t w13 = pw64[13]; + uint64_t w14 = pw64[14]; + uint64_t w15 = pw64[15]; + uint64_t w16 = pw64[16]; + uint64_t w17 = pw64[17]; + uint64_t w18 = pw64[18]; + uint64_t w19 = pw64[19]; + uint64_t w20 = pw64[20]; + uint64_t w21 = pw64[21]; + uint64_t w22 = pw64[22]; + uint64_t w23 = pw64[23]; + uint64_t w24 = pw64[24]; + uint64_t w25 = pw64[25]; + uint64_t w26 = pw64[26]; + uint64_t w27 = pw64[27]; + uint64_t w28 = pw64[28]; + uint64_t w29 = pw64[29]; + uint64_t w30 = pw64[30]; + uint64_t w31 = pw64[31]; + *pw += 256; /* we used up 256 input bytes */ + out[0] = base + ( w0 ); + out[1] = base + ( w1 ); + out[2] = base + ( w2 ); + out[3] = base + ( w3 ); + out[4] = base + ( w4 ); + out[5] = base + ( w5 ); + out[6] = base + ( w6 ); + out[7] = base + ( w7 ); + out[8] = base + ( w8 ); + out[9] = base + ( w9 ); + out[10] = base + ( w10 ); + out[11] = base + ( w11 ); + out[12] = base + ( w12 ); + out[13] = base + ( w13 ); + out[14] = base + ( w14 ); + out[15] = base + ( w15 ); + out[16] = base + ( w16 ); + out[17] = base + ( w17 ); + out[18] = base + ( w18 ); + out[19] = base + ( w19 ); + out[20] = base + ( w20 ); + out[21] = base + ( w21 ); + out[22] = base + ( w22 ); + out[23] = base + ( w23 ); + out[24] = base + ( w24 ); + out[25] = base + ( w25 ); + out[26] = base + ( w26 ); + out[27] = base + ( w27 ); + out[28] = base + ( w28 ); + out[29] = base + ( w29 ); + out[30] = base + ( w30 ); + out[31] = base + ( w31 ); + *pout += 32; /* we wrote 32 64-bit integers */ +} + +static packforblockfnc_64 funcForPackArr64[] = { +&packforblock0_64, +&packforblock1_64, +&packforblock2_64, +&packforblock3_64, +&packforblock4_64, +&packforblock5_64, +&packforblock6_64, +&packforblock7_64, +&packforblock8_64, +&packforblock9_64, +&packforblock10_64, +&packforblock11_64, +&packforblock12_64, +&packforblock13_64, +&packforblock14_64, +&packforblock15_64, +&packforblock16_64, +&packforblock17_64, +&packforblock18_64, +&packforblock19_64, +&packforblock20_64, +&packforblock21_64, +&packforblock22_64, +&packforblock23_64, +&packforblock24_64, +&packforblock25_64, +&packforblock26_64, +&packforblock27_64, +&packforblock28_64, +&packforblock29_64, +&packforblock30_64, +&packforblock31_64, +&packforblock32_64, +&packforblock33_64, +&packforblock34_64, +&packforblock35_64, +&packforblock36_64, +&packforblock37_64, +&packforblock38_64, +&packforblock39_64, +&packforblock40_64, +&packforblock41_64, +&packforblock42_64, +&packforblock43_64, +&packforblock44_64, +&packforblock45_64, +&packforblock46_64, +&packforblock47_64, +&packforblock48_64, +&packforblock49_64, +&packforblock50_64, +&packforblock51_64, +&packforblock52_64, +&packforblock53_64, +&packforblock54_64, +&packforblock55_64, +&packforblock56_64, +&packforblock57_64, +&packforblock58_64, +&packforblock59_64, +&packforblock60_64, +&packforblock61_64, +&packforblock62_64, +&packforblock63_64, +&packforblock64_64 +}; +static unpackforblockfnc_64 funcForUnpackArr64[] = { +&unpackforblock0_64, +&unpackforblock1_64, +&unpackforblock2_64, +&unpackforblock3_64, +&unpackforblock4_64, +&unpackforblock5_64, +&unpackforblock6_64, +&unpackforblock7_64, +&unpackforblock8_64, +&unpackforblock9_64, +&unpackforblock10_64, +&unpackforblock11_64, +&unpackforblock12_64, +&unpackforblock13_64, +&unpackforblock14_64, +&unpackforblock15_64, +&unpackforblock16_64, +&unpackforblock17_64, +&unpackforblock18_64, +&unpackforblock19_64, +&unpackforblock20_64, +&unpackforblock21_64, +&unpackforblock22_64, +&unpackforblock23_64, +&unpackforblock24_64, +&unpackforblock25_64, +&unpackforblock26_64, +&unpackforblock27_64, +&unpackforblock28_64, +&unpackforblock29_64, +&unpackforblock30_64, +&unpackforblock31_64, +&unpackforblock32_64, +&unpackforblock33_64, +&unpackforblock34_64, +&unpackforblock35_64, +&unpackforblock36_64, +&unpackforblock37_64, +&unpackforblock38_64, +&unpackforblock39_64, +&unpackforblock40_64, +&unpackforblock41_64, +&unpackforblock42_64, +&unpackforblock43_64, +&unpackforblock44_64, +&unpackforblock45_64, +&unpackforblock46_64, +&unpackforblock47_64, +&unpackforblock48_64, +&unpackforblock49_64, +&unpackforblock50_64, +&unpackforblock51_64, +&unpackforblock52_64, +&unpackforblock53_64, +&unpackforblock54_64, +&unpackforblock55_64, +&unpackforblock56_64, +&unpackforblock57_64, +&unpackforblock58_64, +&unpackforblock59_64, +&unpackforblock60_64, +&unpackforblock61_64, +&unpackforblock62_64, +&unpackforblock63_64, +&unpackforblock64_64 +}; +/** turbopacking64.py ends here **/ + +#endif //INCLUDE_TURBOPACKING64_H + diff --git a/src/core/CLucene/index/util.h b/src/core/CLucene/index/util.h new file mode 100644 index 00000000000..d0756abd534 --- /dev/null +++ b/src/core/CLucene/index/util.h @@ -0,0 +1,83 @@ +#ifndef FRAMEOFREFERENCE_INCLUDE_UTIL_H +#define FRAMEOFREFERENCE_INCLUDE_UTIL_H +#include // mostly for Microsoft +#ifdef _MSC_VER +/* Microsoft C/C++-compatible compiler */ +#include + +#ifndef __clang__ // if one compiles with MSVC *with* clang, then these intrinsics are defined!!! +// sadly there is no way to check whether we are missing these intrinsics specifically. + +/* wrappers for Visual Studio built-ins that look like gcc built-ins */ +/* result might be undefined when input_num is zero */ +static inline int __builtin_ctzll(unsigned long long input_num) { + unsigned long index; +#ifdef _WIN64 // highly recommended!!! + _BitScanForward64(&index, input_num); +#else // if we must support 32-bit Windows + if ((uint32_t)input_num != 0) { + _BitScanForward(&index, (uint32_t)input_num); + } + else { + _BitScanForward(&index, (uint32_t)(input_num >> 32)); + index += 32; + } +#endif + return index; +} + +/* result might be undefined when input_num is zero */ +static inline int __builtin_clzll(unsigned long long input_num) { + unsigned long index; +#ifdef _WIN64 // highly recommended!!! + _BitScanReverse64(&index, input_num); +#else // if we must support 32-bit Windows + if (input_num > 0xFFFFFFF) { + _BitScanReverse(&index, (uint32_t)(input_num >> 32)); + } + else { + _BitScanReverse(&index, (uint32_t)(input_num)); + index += 32; + } +#endif + return 63 - index; +} + +/* result might be undefined when input_num is zero */ +static inline int __builtin_clz(int input_num) { + unsigned long index; + _BitScanReverse(&index, input_num); + return 31 - index; +} + +/* result might be undefined when input_num is zero */ +static inline int __builtin_popcountll(unsigned long long input_num) { +#ifdef _WIN64 // highly recommended!!! + return (int)__popcnt64(input_num); +#else // if we must support 32-bit Windows + return (int)(__popcnt((uint32_t)input_num) + __popcnt((uint32_t)(input_num >> 32))); +#endif +} + +static inline void __builtin_unreachable() { + __assume(0); +} +#endif +#endif + + +#include // part of Visual Studio 2010 and better + +// integer logarithm function +static inline uint32_t bits(const uint32_t v) { + return v == 0 ? 0 : 32 - __builtin_clz(v); // todo: make portable (Visual studio) +} + + + +// integer logarithm function +static inline uint32_t bits64(const uint64_t v) { + return v == 0 ? 0 : 64 - __builtin_clzll(v); // todo: make portable (Visual studio) +} + +#endif // FRAMEOFREFERENCE_INCLUDE_UTIL_H diff --git a/src/core/CLucene/queryParser/FastCharStream.cpp b/src/core/CLucene/queryParser/FastCharStream.cpp new file mode 100644 index 00000000000..e17c788b2c5 --- /dev/null +++ b/src/core/CLucene/queryParser/FastCharStream.cpp @@ -0,0 +1,121 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_CharStream.h" +#include "_FastCharStream.h" +#include "CLucene/util/CLStreams.h" + +CL_NS_DEF(queryParser) + +FastCharStream::FastCharStream(CL_NS(util)::Reader* r, bool ownsReader) : + buffer(NULL), + _bufferSize(0), + bufferLength(0), + bufferPosition(0), + tokenStart(0), + bufferStart(0), + input(r), + _ownsReader(ownsReader) +{ +} + +FastCharStream::~FastCharStream() +{ + if (_ownsReader ){ + _CLLDELETE(input); + } + _CLDELETE_LCARRAY(buffer); +} + +TCHAR FastCharStream::readChar() { + if (bufferPosition >= bufferLength) + refill(); + return buffer[bufferPosition++]; +} + +void FastCharStream::refill() { + int32_t newPosition = bufferLength - tokenStart; + + if (tokenStart == 0) { // token won't fit in buffer + if (buffer == NULL) { // first time: alloc buffer + buffer = _CL_NEWARRAY(TCHAR, 2048); + _bufferSize = 2048; + } else if (bufferLength == _bufferSize) { // grow buffer + _bufferSize *= 2; + TCHAR* newBuffer = _CL_NEWARRAY(TCHAR, _bufferSize); + _tcsncpy(newBuffer, buffer, bufferLength); + _CLDELETE_LCARRAY(buffer); + buffer = newBuffer; + } + } else { // shift token to front + _tcsncpy(buffer, buffer+tokenStart,newPosition); + } + + bufferLength = newPosition; // update state + bufferPosition = newPosition; + bufferStart += tokenStart; + tokenStart = 0; + + const TCHAR* charBuf = NULL; + int32_t charsRead = // fill space in buffer + input->read((const void**)&charBuf, newPosition, _bufferSize-newPosition); + if (charsRead == -1){ + _CLTHROWA(CL_ERR_IO, "read past eof"); + } + else { + memcpy(buffer, charBuf, charsRead * sizeof(TCHAR)); // TODO: Can we use the reader buffer instead of copying to our own? + bufferLength += charsRead; + } +} + +void FastCharStream::backup(const int32_t amount) { + bufferPosition -= amount; +} + +TCHAR* FastCharStream::GetImage() { + size_t len = bufferPosition - tokenStart; + TCHAR* ret = _CL_NEWARRAY(TCHAR, len + 1); + _tcsncpy(ret, buffer+tokenStart, len); + ret[len] = 0; // NULL terminated string + return ret; +} + +TCHAR* FastCharStream::GetSuffix(const int32_t len) { + TCHAR* value = _CL_NEWARRAY(TCHAR, len + 1); + _tcsncpy(value, buffer+(bufferPosition - len), len); + value[len] = 0; // NULL terminated string + return value; +} + +void FastCharStream::Done() { +} + +TCHAR FastCharStream::BeginToken() { + tokenStart = bufferPosition; + return readChar(); +} + +int32_t FastCharStream::getColumn() const { + return bufferStart + bufferPosition; +} +int32_t FastCharStream::getLine() const { + return 1; +} +int32_t FastCharStream::getEndColumn() const { + return bufferStart + bufferPosition; +} +int32_t FastCharStream::getEndLine() const { + return 1; +} +int32_t FastCharStream::getBeginColumn() const { + return bufferStart + tokenStart; +} +int32_t FastCharStream::getBeginLine() const { + return 1; +} + +CL_NS_END diff --git a/src/core/CLucene/queryParser/MultiFieldQueryParser.cpp b/src/core/CLucene/queryParser/MultiFieldQueryParser.cpp new file mode 100644 index 00000000000..6566fa21380 --- /dev/null +++ b/src/core/CLucene/queryParser/MultiFieldQueryParser.cpp @@ -0,0 +1,181 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultiFieldQueryParser.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/search/BooleanQuery.h" +#include "CLucene/search/BooleanClause.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/search/MultiPhraseQuery.h" +#include "CLucene/search/SearchHeader.h" +#include "QueryParser.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(search) +CL_NS_USE(analysis) + +CL_NS_DEF(queryParser) + + +MultiFieldQueryParser::MultiFieldQueryParser(const TCHAR** _fields, CL_NS(analysis)::Analyzer* a, BoostMap* _boosts): + QueryParser(NULL,a), fields(_fields), boosts(_boosts) +{ +} +MultiFieldQueryParser::~MultiFieldQueryParser(){ +} + +Query* MultiFieldQueryParser::getFieldQuery(const TCHAR* field, TCHAR* queryText, const int32_t slop){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::getFieldQuery(fields[i], queryText); + if (q != NULL) { + //If the user passes a map of boosts + if (boosts != NULL) { + //Get the boost from the map and apply them + BoostMap::const_iterator itr = boosts->find((TCHAR*)fields[i]); + if (itr != boosts->end()) { + q->setBoost(itr->second); + } + } + if (q->instanceOf(PhraseQuery::getClassName())) { + ((PhraseQuery*)q)->setSlop(slop); + } + if (q->instanceOf(MultiPhraseQuery::getClassName())) { + ((MultiPhraseQuery*) q)->setSlop(slop); + } + clauses.push_back(_CLNEW BooleanClause(q, true, BooleanClause::SHOULD)); + } + } + if (clauses.size() == 0) // happens for stopwords + return NULL; + return QueryParser::getBooleanQuery(clauses, true); + }else{ + return QueryParser::getFieldQuery(field, queryText); + } +} + +Query* MultiFieldQueryParser::getFuzzyQuery(const TCHAR* field, TCHAR* termStr, const float_t minSimilarity){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::getFuzzyQuery(fields[i], termStr, minSimilarity); + if (q) clauses.push_back(_CLNEW BooleanClause(q,true, BooleanClause::SHOULD) ); + } + return QueryParser::getBooleanQuery(clauses, true); + } + return QueryParser::getFuzzyQuery(field, termStr, minSimilarity); +} + +Query* MultiFieldQueryParser::getPrefixQuery(const TCHAR* field, TCHAR* termStr){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::getPrefixQuery(fields[i], termStr); + if (q) clauses.push_back(_CLNEW BooleanClause(q,true,BooleanClause::SHOULD)); + } + return QueryParser::getBooleanQuery(clauses, true); + } + return QueryParser::getPrefixQuery(field, termStr); +} + +Query* MultiFieldQueryParser::getWildcardQuery(const TCHAR* field, TCHAR* termStr){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::getWildcardQuery(fields[i], termStr); + if (q) clauses.push_back(_CLNEW BooleanClause(q,true,BooleanClause::SHOULD)); + } + return QueryParser::getBooleanQuery(clauses, true); + } + return QueryParser::getWildcardQuery(field, termStr); +} + + +Query* MultiFieldQueryParser::getRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, const bool inclusive){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::getRangeQuery(fields[i], part1, part2, inclusive); + if (q) clauses.push_back(_CLNEW BooleanClause(q,true,BooleanClause::SHOULD)); + } + return QueryParser::getBooleanQuery(clauses, true); + }else{ + return QueryParser::getRangeQuery(field, part1, part2, inclusive); + } +} + +//static +Query* MultiFieldQueryParser::parse(const TCHAR** _queries, const TCHAR** _fields, Analyzer* analyzer) +{ + BooleanQuery* bQuery = _CLNEW BooleanQuery(); + for (size_t i = 0; _fields[i]!=NULL; i++) + { + if (_queries[i] == NULL) { + _CLLDELETE(bQuery); + _CLTHROWA(CL_ERR_IllegalArgument, "_queries.length != _fields.length"); + } + // TODO: Reuse qp instead of creating it over and over again + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); + Query* q = qp->parse(_queries[i]); + if (q!=NULL && // q never null, just being defensive + (!(q->instanceOf(BooleanQuery::getClassName()) || ((BooleanQuery*)q)->getClauseCount() > 0))) { + bQuery->add(q, true, BooleanClause::SHOULD); + } else + _CLLDELETE(q); + _CLLDELETE(qp); + } + return bQuery; +} + +// static +Query* MultiFieldQueryParser::parse(const TCHAR* query, const TCHAR** _fields, const uint8_t* flags, Analyzer* analyzer) { + BooleanQuery* bQuery = _CLNEW BooleanQuery(); + for (size_t i = 0; _fields[i]!=NULL; i++) { + //TODO: this is really confusing... why not refactor _fields and flags to use a array object. + //flags can be NULL since NULL == 0... + /*if (flags[i] == NULL) { + _CLLDELETE(bQuery); + _CLTHROWA(CL_ERR_IllegalArgument, "_fields.length != flags.length"); + }*/ + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); + Query* q = qp->parse(query); + if (q!=NULL && // q never null, just being defensive + (!(q->instanceOf(BooleanQuery::getClassName())) || ((BooleanQuery*)q)->getClauseCount()>0)) { + bQuery->add(q, true, (BooleanClause::Occur)flags[i]); + } else + _CLLDELETE(q); + _CLLDELETE(qp); + } + return bQuery; +} + +//static +Query* MultiFieldQueryParser::parse(const TCHAR** _queries, const TCHAR** _fields, const uint8_t* flags, Analyzer* analyzer){ + BooleanQuery* bQuery = _CLNEW BooleanQuery(); + for (size_t i = 0; _fields[i]!=NULL; i++) + { + //TODO: this is really confusing... why not refactor _fields and flags to use a array object. + //flags can be NULL since NULL == 0... + if (_queries[i] == NULL ) { //|| flags[i] == NULL + _CLLDELETE(bQuery); + _CLTHROWA(CL_ERR_IllegalArgument, "_queries, _fields, and flags array have have different length"); + } + QueryParser* qp = _CLNEW QueryParser(_fields[i], analyzer); + Query* q = qp->parse(_queries[i]); + if (q!=NULL && // q never null, just being defensive + (!(q->instanceOf(BooleanQuery::getClassName())) || ((BooleanQuery*)q)->getClauseCount()>0)) { + bQuery->add(q, true, (BooleanClause::Occur)flags[i]); + } else + _CLLDELETE(q); + _CLLDELETE(qp); + } + return bQuery; +} + +CL_NS_END diff --git a/src/core/CLucene/queryParser/MultiFieldQueryParser.h b/src/core/CLucene/queryParser/MultiFieldQueryParser.h new file mode 100644 index 00000000000..a10168bdeff --- /dev/null +++ b/src/core/CLucene/queryParser/MultiFieldQueryParser.h @@ -0,0 +1,163 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_MultiFieldQueryParser_ +#define _lucene_queryParser_MultiFieldQueryParser_ + +#include "QueryParser.h" +#include "CLucene/util/VoidMap.h" + + +CL_NS_DEF(queryParser) + +typedef CL_NS(util)::CLHashMap BoostMap; + +/** +* A QueryParser which constructs queries to search multiple fields. +* +*/ +class CLUCENE_EXPORT MultiFieldQueryParser: public QueryParser +{ +protected: + const TCHAR** fields; + BoostMap* boosts; +public: + /** + * Creates a MultiFieldQueryParser. + * Allows passing of a map with term to Boost, and the boost to apply to each term. + * + *

It will, when parse(String query) + * is called, construct a query like this (assuming the query consists of + * two terms and you specify the two fields title and body):

+ * + * + * (title:term1 body:term1) (title:term2 body:term2) + * + * + *

When setDefaultOperator(AND_OPERATOR) is set, the result will be:

+ * + * + * +(title:term1 body:term1) +(title:term2 body:term2) + * + * + *

When you pass a boost (title=>5 body=>10) you can get

+ * + * + * +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0) + * + * + *

In other words, all the query's terms must appear, but it doesn't matter in + * what fields they appear.

+ */ + MultiFieldQueryParser(const TCHAR** _fields, CL_NS(analysis)::Analyzer* a, BoostMap* _boosts = NULL); + virtual ~MultiFieldQueryParser(); + + +protected: + CL_NS(search)::Query* getFieldQuery(const TCHAR* field, TCHAR* queryText, const int32_t slop); + CL_NS(search)::Query* getFieldQuery(const TCHAR* field, TCHAR* queryText) { return getFieldQuery(field,queryText,0); } + CL_NS(search)::Query* getFuzzyQuery(const TCHAR* field, TCHAR* termStr, const float_t minSimilarity); + CL_NS(search)::Query* getPrefixQuery(const TCHAR* field, TCHAR* termStr); + CL_NS(search)::Query* getWildcardQuery(const TCHAR* field, TCHAR* termStr); + CL_NS(search)::Query* getRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, const bool inclusive); + +public: + /** + * Parses a query which searches on the fields specified. + *

+ * If x fields are specified, this effectively constructs: + *

+  * 
+  * (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
+  * 
+  * 
+ * @param queries Queries strings to parse + * @param fields Fields to search on + * @param analyzer Analyzer to use + * @throws ParseException if query parsing fails + * @throws IllegalArgumentException if the length of the queries array differs + * from the length of the fields array + */ + static CL_NS(search)::Query* parse(const TCHAR** _queries, const TCHAR** _fields, + CL_NS(analysis)::Analyzer* analyzer); + + /** + * Parses a query, searching on the fields specified. + * Use this if you need to specify certain fields as required, + * and others as prohibited. + *

+  * Usage:
+  * 
+  * String[] fields = {"filename", "contents", "description"};
+  * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+  *                BooleanClause.Occur.MUST,
+  *                BooleanClause.Occur.MUST_NOT};
+  * MultiFieldQueryParser.parse("query", fields, flags, analyzer);
+  * 
+  * 
+ *

+ * The code above would construct a query: + *

+  * 
+  * (filename:query) +(contents:query) -(description:query)
+  * 
+  * 
+ * + * @param query Query string to parse + * @param fields Fields to search on + * @param flags Flags describing the fields + * @param analyzer Analyzer to use + * @throws ParseException if query parsing fails + * @throws IllegalArgumentException if the length of the fields array differs + * from the length of the flags array + */ + static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR** _fields, + const uint8_t* flags, CL_NS(analysis)::Analyzer* analyzer); + + /** + * Parses a query, searching on the fields specified. + * Use this if you need to specify certain fields as required, + * and others as prohibited. + *

+  * Usage:
+  * 
+  * String[] query = {"query1", "query2", "query3"};
+  * String[] fields = {"filename", "contents", "description"};
+  * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+  *                BooleanClause.Occur.MUST,
+  *                BooleanClause.Occur.MUST_NOT};
+  * MultiFieldQueryParser.parse(query, fields, flags, analyzer);
+  * 
+  * 
+ *

+ * The code above would construct a query: + *

+  * 
+  * (filename:query1) +(contents:query2) -(description:query3)
+  * 
+  * 
+ * + * @param queries Queries string to parse + * @param fields Fields to search on + * @param flags Flags describing the fields + * @param analyzer Analyzer to use + * @throws ParseException if query parsing fails + * @throws IllegalArgumentException if the length of the queries, fields, + * and flags array differ + */ + static CL_NS(search)::Query* parse(const TCHAR** _queries, const TCHAR** _fields, const uint8_t* flags, + CL_NS(analysis)::Analyzer* analyzer); + + CL_NS(search)::Query* parse(const TCHAR* _query){return QueryParser::parse(_query);} +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/QueryParser.cpp b/src/core/CLucene/queryParser/QueryParser.cpp new file mode 100644 index 00000000000..37047e57431 --- /dev/null +++ b/src/core/CLucene/queryParser/QueryParser.cpp @@ -0,0 +1,1504 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_CharStream.h" +#include "_FastCharStream.h" +#include "QueryParserConstants.h" +#include "QueryParserTokenManager.h" +#include "QueryParser.h" + +#include "CLucene/analysis/AnalysisHeader.h" + +#include "CLucene/search/SearchHeader.h" + +#include "CLucene/search/Query.h" +#include "CLucene/search/TermQuery.h" +#include "CLucene/search/BooleanQuery.h" +#include "CLucene/search/FuzzyQuery.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/search/WildcardQuery.h" +#include "CLucene/search/PrefixQuery.h" +#include "CLucene/search/RangeQuery.h" +#include "CLucene/search/MatchAllDocsQuery.h" +#include "CLucene/search/MultiPhraseQuery.h" +#include "CLucene/search/ConstantScoreQuery.h" + +#include "CLucene/document/DateField.h" +#include "CLucene/document/DateTools.h" + +#include "CLucene/index/Term.h" +#include "QueryToken.h" + +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/StringBuffer.h" + +#include + +CL_NS_USE(util) +CL_NS_USE(index) +CL_NS_USE(analysis) +CL_NS_USE(search) + +CL_NS_DEF(queryParser) + +const TCHAR* QueryParserConstants::tokenImage[] = { + _T(""), + _T("<_NUM_CHAR>"), + _T("<_ESCAPED_CHAR>"), + _T("<_TERM_START_CHAR>"), + _T("<_TERM_CHAR>"), + _T("<_WHITESPACE>"), + _T(""), + _T(""), + _T(""), + _T(""), + _T("\"+\""), + _T("\"-\""), + _T("\"(\""), + _T("\")\""), + _T("\":\""), + _T("\"*\""), + _T("\"^\""), + _T(""), + _T(""), + _T(""), + _T(""), + _T(""), + _T("\"[\""), + _T("\"{\""), + _T(""), + _T("\"TO\""), + _T("\"]\""), + _T(""), + _T(""), + _T("\"TO\""), + _T("\"}\""), + _T(""), + _T("") +}; + +const int32_t QueryParser::jj_la1_0[] = {0x180,0x180,0xe00,0xe00,0x1f69f80,0x48000,0x10000,0x1f69000,0x1348000,0x80000,0x80000,0x10000,0x18000000,0x2000000,0x18000000,0x10000,0x80000000,0x20000000,0x80000000,0x10000,0x80000,0x10000,0x1f68000}; +const int32_t QueryParser::jj_la1_1[] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0}; + +struct QueryParser::JJCalls { +public: + int32_t gen; + QueryToken* first; + int32_t arg; + JJCalls* next; + + JJCalls(); + ~JJCalls(); +}; + +QueryParser::QueryParser(const TCHAR* f, Analyzer* a) : _operator(OR_OPERATOR), + lowercaseExpandedTerms(true),useOldRangeQuery(false),allowLeadingWildcard(false),enablePositionIncrements(false), + analyzer(a),field(NULL),phraseSlop(0),fuzzyMinSim(FuzzyQuery::defaultMinSimilarity), + fuzzyPrefixLength(FuzzyQuery::defaultPrefixLength),/*locale(NULL),*/ + dateResolution(CL_NS(document)::DateTools::NO_RESOLUTION),fieldToDateResolution(NULL), + token_source(NULL),token(NULL),jj_nt(NULL),_firstToken(NULL),jj_ntk(-1),jj_scanpos(NULL),jj_lastpos(NULL),jj_la(0), + lookingAhead(false),jj_gen(0),jj_2_rtns(NULL),jj_rescan(false),jj_gc(0),jj_expentries(NULL),jj_expentry(NULL), + jj_kind(-1),jj_endpos(0) +{ + StringReader* rdr = _CLNEW StringReader(_T("")); + _init(_CLNEW FastCharStream(rdr, true)); + + if ( f ) + field = STRDUP_TtoT(f); +} + +void QueryParser::_deleteTokens(){ + QueryToken* t = _firstToken; + while (true){ + if (_firstToken == NULL) break; + t = _firstToken->next; + _CLLDELETE(_firstToken); + _firstToken = t; + } +} + +QueryParser::~QueryParser(){ + _CLLDELETE(fieldToDateResolution); + _CLLDELETE(token_source); + + _deleteTokens(); + + _CLLDELETE(jj_expentries); + _CLLDELETE(jj_expentry); + _CLLDELETE(jj_2_rtns); + + _CLDELETE_CARRAY(field); +} + +CL_NS(search)::Query* QueryParser::parse(const TCHAR* q, const TCHAR* f, CL_NS(analysis)::Analyzer* a){ + QueryParser* qp = _CLNEW QueryParser(f, a); + CL_NS(search)::Query* qry = qp->parse(q); + _CLDELETE(qp); + return qry; +} + +Query* QueryParser::parse(const TCHAR* _query) +{ + StringReader* rdr = _CLNEW StringReader(_query); + ReInit(_CLNEW FastCharStream(rdr, true)); + try { + // TopLevelQuery is a Query followed by the end-of-input (EOF) + Query* res = TopLevelQuery(field); + return (res!=NULL) ? res : _CLNEW BooleanQuery(); + } + catch (CLuceneError& e) { + // rethrow to include the original query: + if (e.number()==CL_ERR_Parse || e.number()==CL_ERR_TokenMgr) { + TCHAR* _twhat = e.twhat(); + const size_t errLen = _tcslen(_twhat) + _tcslen(_query) + 20; // make sure we have enough room for our error message + TCHAR *err = _CL_NEWARRAY(TCHAR,errLen); + cl_stprintf(err, errLen, _T("Cannot parse '%s': %s"), _query,_twhat); + _CLTHROWT_DEL(CL_ERR_Parse, err); + } else if (e.number()==CL_ERR_TooManyClauses) { + const size_t errLen = _tcslen(_query) + 25; // make sure we have enough room for our error message + TCHAR *err = _CL_NEWARRAY(TCHAR,errLen); + cl_stprintf(err, errLen, _T("Cannot parse '%s': too many boolean clauses"), _query); + _CLTHROWT_DEL(CL_ERR_Parse, err); + } else + throw e; + } +} + +Analyzer* QueryParser::getAnalyzer() const { + return analyzer; +} + +const TCHAR* QueryParser::getField() const { + return field; +} + +float_t QueryParser::getFuzzyMinSim() const { + return fuzzyMinSim; +} + +void QueryParser::setFuzzyMinSim(const float_t _fuzzyMinSim) { + fuzzyMinSim = _fuzzyMinSim; +} + +int32_t QueryParser::getFuzzyPrefixLength() const { + return fuzzyPrefixLength; +} + +void QueryParser::setFuzzyPrefixLength(const int32_t _fuzzyPrefixLength) { + fuzzyPrefixLength = _fuzzyPrefixLength; +} + +void QueryParser::setPhraseSlop(const int32_t _phraseSlop) { + phraseSlop = _phraseSlop; +} +int32_t QueryParser::getPhraseSlop() const { + return phraseSlop; +} +void QueryParser::setAllowLeadingWildcard(const bool _allowLeadingWildcard) { + allowLeadingWildcard = _allowLeadingWildcard; +} +bool QueryParser::getAllowLeadingWildcard() const { + return allowLeadingWildcard; +} +void QueryParser::setEnablePositionIncrements(const bool _enable) { + enablePositionIncrements = _enable; +} +bool QueryParser::getEnablePositionIncrements() const { + return enablePositionIncrements; +} +void QueryParser::setDefaultOperator(Operator _op) { + _operator = _op; +} +QueryParser::Operator QueryParser::getDefaultOperator() const { + return _operator; +} +void QueryParser::setLowercaseExpandedTerms(const bool _lowercaseExpandedTerms) { + lowercaseExpandedTerms = _lowercaseExpandedTerms; +} +bool QueryParser::getLowercaseExpandedTerms() const { + return lowercaseExpandedTerms; +} +void QueryParser::setUseOldRangeQuery(const bool _useOldRangeQuery) { + useOldRangeQuery = _useOldRangeQuery; +} +bool QueryParser::getUseOldRangeQuery() const { + return useOldRangeQuery; +} +void QueryParser::setDateResolution(const CL_NS(document)::DateTools::Resolution _dateResolution) { + dateResolution = _dateResolution; +} +void QueryParser::setDateResolution(const TCHAR* fieldName, const CL_NS(document)::DateTools::Resolution _dateResolution) { + if (fieldName == NULL) + _CLTHROWA(CL_ERR_IllegalArgument, "Field cannot be null."); + + if (fieldToDateResolution == NULL) { + // lazily initialize HashMap + fieldToDateResolution = _CLNEW FieldToDateResolutionType(); + } + + fieldToDateResolution->put(fieldName, _dateResolution); +} +CL_NS(document)::DateTools::Resolution QueryParser::getDateResolution(const TCHAR* fieldName) const { + if (fieldName == NULL) + _CLTHROWA(CL_ERR_IllegalArgument,"Field cannot be null."); + + if (fieldToDateResolution == NULL) { + // no field specific date resolutions set; return default date resolution instead + return dateResolution; + } + + CL_NS(document)::DateTools::Resolution resolution = fieldToDateResolution->get(fieldName); + if (resolution == CL_NS(document)::DateTools::NO_RESOLUTION) { + // no date resolutions set for the given field; return default date resolution instead + resolution = dateResolution; + } + + return resolution; +} + +void QueryParser::addClause(std::vector& clauses, int32_t conj, int32_t mods, Query* q){ + bool required, prohibited; + + // If this term is introduced by AND, make the preceding term required, + // unless it's already prohibited + const uint32_t nPreviousClauses = clauses.size(); + if (nPreviousClauses > 0 && conj == CONJ_AND) { + BooleanClause* c = clauses[nPreviousClauses-1]; + if (!c->isProhibited()) + c->setOccur(BooleanClause::MUST); + } + + if (nPreviousClauses > 0 && _operator == AND_OPERATOR && conj == CONJ_OR) { + // If this term is introduced by OR, make the preceding term optional, + // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b) + // notice if the input is a OR b, first term is parsed as required; without + // this modification a OR b would parsed as +a OR b + BooleanClause* c = clauses[nPreviousClauses-1]; + if (!c->isProhibited()) + c->setOccur(BooleanClause::SHOULD); + } + + // We might have been passed a null query; the term might have been + // filtered away by the analyzer. + if (q == NULL) + return; + + if (_operator == OR_OPERATOR) { + // We set REQUIRED if we're introduced by AND or +; PROHIBITED if + // introduced by NOT or -; make sure not to set both. + prohibited = (mods == MOD_NOT); + required = (mods == MOD_REQ); + if (conj == CONJ_AND && !prohibited) { + required = true; + } + } else { + // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED + // if not PROHIBITED and not introduced by OR + prohibited = (mods == MOD_NOT); + required = (!prohibited && conj != CONJ_OR); + } + if (required && !prohibited) + clauses.push_back(_CLNEW BooleanClause(q,true, BooleanClause::MUST)); + else if (!required && !prohibited) + clauses.push_back(_CLNEW BooleanClause(q,true, BooleanClause::SHOULD)); + else if (!required && prohibited) + clauses.push_back(_CLNEW BooleanClause(q,true, BooleanClause::MUST_NOT)); + else { + _CLTHROWA(CL_ERR_Runtime, "Clause cannot be both required and prohibited"); + } +} + +Query* QueryParser::getFieldQuery(const TCHAR* _field, TCHAR* queryText) { + // Use the analyzer to get all the tokens, and then build a TermQuery, + // PhraseQuery, or nothing based on the term count + + StringReader reader(queryText); + TokenStream* source = analyzer->tokenStream(_field, &reader); + + CLVector > v; + CL_NS(analysis)::Token* t = NULL; + int32_t positionCount = 0; + bool severalTokensAtSamePosition = false; + + while (true) { + t = _CLNEW Token(); + try { + Token* _t = source->next(t); + if (_t == NULL) _CLDELETE(t); + }_CLCATCH_ERR(CL_ERR_IO, _CLLDELETE(source);_CLLDELETE(t);_CLDELETE_LCARRAY(queryText);,{ + t = NULL; + }); + if (t == NULL) + break; + v.push_back(t); + if (t->getPositionIncrement() != 0) + positionCount += t->getPositionIncrement(); + else + severalTokensAtSamePosition = true; + } + try { + source->close(); + } + _CLCATCH_ERR_CLEANUP(CL_ERR_IO, {_CLLDELETE(source);_CLLDELETE(t);_CLDELETE_LCARRAY(queryText);} ); /* cleanup */ + _CLLDELETE(source); + + if (v.size() == 0) + return NULL; + else if (v.size() == 1) { + Term* tm = _CLNEW Term(_field, v.at(0)->termBuffer()); + Query* ret = _CLNEW TermQuery( tm ); + _CLDECDELETE(tm); + return ret; + } else { + if (severalTokensAtSamePosition) { + if (positionCount == 1) { + // no phrase query: + BooleanQuery* q = _CLNEW BooleanQuery(true); + for(size_t i=0; itermBuffer()); + q->add(_CLNEW TermQuery(tm), true, BooleanClause::SHOULD); + _CLDECDELETE(tm); + } + return q; + }else { + MultiPhraseQuery* mpq = _CLNEW MultiPhraseQuery(); + mpq->setSlop(phraseSlop); + CLArrayList multiTerms; + int32_t position = -1; + for (size_t i = 0; i < v.size(); i++) { + t = v.at(i); + if (t->getPositionIncrement() > 0 && multiTerms.size() > 0) { + ValueArray termsArray(multiTerms.size()); + multiTerms.toArray(termsArray.values); + if (enablePositionIncrements) { + mpq->add(&termsArray,position); + } else { + mpq->add(&termsArray); + } + multiTerms.clear(); + } + position += t->getPositionIncrement(); + multiTerms.push_back(_CLNEW Term(field, t->termBuffer())); + } + ValueArray termsArray(multiTerms.size()); + multiTerms.toArray(termsArray.values); + if (enablePositionIncrements) { + mpq->add(&termsArray,position); + } else { + mpq->add(&termsArray); + } + return mpq; + } + }else { + PhraseQuery* pq = _CLNEW PhraseQuery(); + pq->setSlop(phraseSlop); + int32_t position = -1; + + for (size_t i = 0; i < v.size(); i++) { + t = v.at(i); + Term* tm = _CLNEW Term(_field, t->termBuffer()); + if (enablePositionIncrements) { + position += t->getPositionIncrement(); + pq->add(tm,position); + } else { + pq->add(tm); + } + _CLDECDELETE(tm); + } + return pq; + } + } +} + +Query* QueryParser::getFieldQuery(const TCHAR* _field, TCHAR* queryText, const int32_t slop) { + Query* query = getFieldQuery(_field, queryText); + + if (query) { + if ( query->instanceOf(PhraseQuery::getClassName()) ) { + static_cast(query)->setSlop(slop); + } else if ( query->instanceOf(MultiPhraseQuery::getClassName()) ) { + static_cast(query)->setSlop(slop); + } + } + return query; +} + +Query* QueryParser::getRangeQuery(const TCHAR* _field, TCHAR* part1, TCHAR* part2, const bool inclusive) +{ + if (lowercaseExpandedTerms) { + _tcslwr(part1); + _tcslwr(part2); + } + + TCHAR* _part1 = part1, *_part2 = part2; // just in case anything go wrong... + try { + /*DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); // SHORT means completely numeric + df.setLenient(true); + Date d1 = df.parse(part1); + Date d2 = df.parse(part2); + */ + const int64_t d1 = CL_NS(document)::DateTools::stringToTime(part1); + int64_t d2 = CL_NS(document)::DateTools::stringToTime(part2); + if (inclusive) { + // The user can only specify the date, not the time, so make sure + // the time is set to the latest possible time of that date to really + // include all documents: + d2 = CL_NS(document)::DateTools::timeMakeInclusive(d2); + } + + CL_NS(document)::DateTools::Resolution resolution = getDateResolution(_field); + if (resolution == CL_NS(document)::DateTools::NO_RESOLUTION) { + // no default or field specific date resolution has been set, + // use deprecated DateField to maintain compatibilty with + // pre-1.9 Lucene versions. + _part1 = CL_NS(document)::DateField::timeToString(d1); + _part2 = CL_NS(document)::DateField::timeToString(d2); + } else { + _part1 = CL_NS(document)::DateTools::timeToString(d1, resolution); + _part2 = CL_NS(document)::DateTools::timeToString(d2, resolution); + } + } + catch (...) { } + + if(useOldRangeQuery) + { + Term* t1 = _CLNEW Term(_field,part1); + Term* t2 = _CLNEW Term(_field,part2); + Query* ret = _CLNEW RangeQuery(t1, t2, inclusive); + _CLDECDELETE(t1); + _CLDECDELETE(t2); + + // Make sure to delete the date strings we allocated only if we indeed allocated them + if (part1 != _part1) _CLDELETE_LCARRAY(_part1); + if (part2 != _part2) _CLDELETE_LCARRAY(_part2); + + return ret; + } + else + { + Query* q = _CLNEW ConstantScoreRangeQuery(_field,part1,part2,inclusive,inclusive); + + // Make sure to delete the date strings we allocated only if we indeed allocated them + if (part1 != _part1) _CLDELETE_LCARRAY(_part1); + if (part2 != _part2) _CLDELETE_LCARRAY(_part2); + + return q; + } +} + +Query* QueryParser::getBooleanQuery(std::vector& clauses, bool disableCoord) +{ + if (clauses.size()==0) { + return NULL; // all clause words were filtered away by the analyzer. + } + BooleanQuery* query = _CLNEW BooleanQuery(disableCoord); + + for (size_t i = 0; i < clauses.size(); i++) { + query->add(clauses[i]); + } + return query; +} + +Query* QueryParser::getWildcardQuery(const TCHAR* _field, TCHAR* termStr) +{ + if (_tcscmp(_T("*"), _field) == 0) { + if (_tcscmp(_T("*"), termStr) == 0) + return _CLNEW MatchAllDocsQuery(); + } + if (!allowLeadingWildcard && (termStr[0]==_T('*') || termStr[0]==_T('?'))){ + _CLDELETE_LCARRAY(termStr); + _CLTHROWT(CL_ERR_Parse,_T("'*' or '?' not allowed as first character in WildcardQuery")); + } + if (lowercaseExpandedTerms) { + _tcslwr(termStr); + } + + Term* t = _CLNEW Term(_field, termStr); + Query* q = _CLNEW WildcardQuery(t); + _CLDECDELETE(t); + + return q; +} + +Query* QueryParser::getPrefixQuery(const TCHAR* _field, TCHAR* _termStr) +{ + if (!allowLeadingWildcard && _termStr[0] == _T('*')){ + _CLDELETE_LCARRAY(_termStr); + _CLTHROWT(CL_ERR_Parse,_T("'*' not allowed as first character in PrefixQuery")); + } + if (lowercaseExpandedTerms) { + _tcslwr(_termStr); + } + Term* t = _CLNEW Term(_field, _termStr); + Query *q = _CLNEW PrefixQuery(t); + _CLDECDELETE(t); + return q; +} + +Query* QueryParser::getFuzzyQuery(const TCHAR* _field, TCHAR* termStr, const float_t minSimilarity) +{ + if (lowercaseExpandedTerms) { + _tcslwr(termStr); + } + + Term* t = _CLNEW Term(_field, termStr); + Query *q = _CLNEW FuzzyQuery(t, minSimilarity, fuzzyPrefixLength); + _CLDECDELETE(t); + return q; +} + +TCHAR* QueryParser::discardEscapeChar(TCHAR* input, TCHAR* output) { + // Create char array to hold unescaped char sequence + const size_t inputLen = _tcslen(input); + bool outputOwned=false; + if (output == NULL){ + // TODO: Perhaps we can re-use an inner buffer instead of creating new char arrays here and in several other places + output = _CL_NEWARRAY(TCHAR, inputLen + 1); + outputOwned=true; + } + + // The length of the output can be less than the input + // due to discarded escape chars. This variable holds + // the actual length of the output + int32_t length = 0; + + // We remember whether the last processed character was + // an escape character + bool lastCharWasEscapeChar = false; + + // The multiplier the current unicode digit must be multiplied with. + // E. g. the first digit must be multiplied with 16^3, the second with 16^2... + uint32_t codePointMultiplier = 0; + + // Used to calculate the codepoint of the escaped unicode character + int32_t codePoint = 0; + + for (size_t i = 0; i < inputLen; i++) { + TCHAR curChar = input[i]; + if (codePointMultiplier > 0) { + try { + codePoint += hexToInt(curChar) * codePointMultiplier; + } catch (CLuceneError& e) { + if (outputOwned)_CLDELETE_LCARRAY(output); + throw e; + } + codePointMultiplier = codePointMultiplier >> 4; + if (codePointMultiplier == 0) { + output[length++] = (TCHAR)codePoint; + codePoint = 0; + } + } else if (lastCharWasEscapeChar) { + if (curChar == _T('u')) { + // found an escaped unicode character + codePointMultiplier = 16 * 16 * 16; + } else { + // this character was escaped + output[length] = curChar; + length++; + } + lastCharWasEscapeChar = false; + } else { + if (curChar == _T('\\')) { + lastCharWasEscapeChar = true; + } else { + output[length] = curChar; + length++; + } + } + } + + if (codePointMultiplier > 0) { + if (outputOwned)_CLDELETE_LCARRAY(output); + _CLTHROWT(CL_ERR_Parse, _T("Truncated unicode escape sequence.")); + } + + if (lastCharWasEscapeChar) { + if (outputOwned)_CLDELETE_LCARRAY(output); + _CLTHROWT(CL_ERR_Parse,_T("Term can not end with escape character.")); + } + + output[length]=0; + return output; +} + +//static +int32_t QueryParser::hexToInt(TCHAR c) { + if (_T('0') <= c && c <= _T('9')) { + return c - _T('0'); + } else if (_T('a') <= c && c <= _T('f')){ + return c - _T('a') + 10; + } else if (_T('A') <= c && c <= _T('F')) { + return c - _T('A') + 10; + } else { + TCHAR err[50]; + cl_stprintf(err,50, _T("Non-hex character in unicode escape sequence: %c"), c); + _CLTHROWT(CL_ERR_Parse,err); + } +} + +//static +TCHAR* QueryParser::escape(const TCHAR* s) { + size_t len = _tcslen(s); + // Create a StringBuffer object a bit longer from the length of the query (to prevent some reallocations), + // and declare we are the owners of the buffer (to save on a copy) + // TODO: 1. Test to see what is the optimal initial length + // 2. Allow re-using the provided string buffer (argument s) instead of creating another one? + StringBuffer sb(len+5); + for (size_t i = 0; i < len; i++) { + const TCHAR c = s[i]; + // These characters are part of the query syntax and must be escaped + if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' + || c == '^' || c == '[' || c == ']' || c == '"' || c == '{' || c == '}' || c == '~' + || c == '*' || c == '?' || c == '|' || c == '&') { + sb.appendChar(_T('\\')); + } + sb.appendChar(c); + } + return sb.giveBuffer(); +} + +int32_t QueryParser::Conjunction() { + int32_t ret = CONJ_NONE; + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case AND: + case OR: + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case AND: + jj_consume_token(AND); + ret = CONJ_AND; + break; + case OR: + jj_consume_token(OR); + ret = CONJ_OR; + break; + default: + jj_la1[0] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + break; + default: + jj_la1[1] = jj_gen; + } + return ret; +} + +int32_t QueryParser::Modifiers() { + int32_t ret = MOD_NONE; + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case NOT: + case PLUS: + case MINUS: + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case PLUS: + jj_consume_token(PLUS); + ret = MOD_REQ; + break; + case MINUS: + jj_consume_token(MINUS); + ret = MOD_NOT; + break; + case NOT: + jj_consume_token(NOT); + ret = MOD_NOT; + break; + default: + jj_la1[2] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + break; + default: + jj_la1[3] = jj_gen; + } + return ret; +} + +Query* QueryParser::TopLevelQuery(TCHAR* _field) { + Query* q = NULL;; + try { + q = fQuery(_field); + jj_consume_token(0); + } catch (CLuceneError& e) { + _CLLDELETE(q); + throw e; + } + return q; +} + +Query* QueryParser::fQuery(TCHAR* _field) { + CLVector > clauses; + Query *q, *firstQuery=NULL; + int32_t conj, mods; + mods = Modifiers(); + q = fClause(_field); + addClause(clauses, CONJ_NONE, mods, q); + if (mods == MOD_NONE) + firstQuery=q; + while (true) { + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case AND: + case OR: + case NOT: + case PLUS: + case MINUS: + case LPAREN: + case STAR: + case QUOTED: + case TERM: + case PREFIXTERM: + case WILDTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + break; + default: + jj_la1[4] = jj_gen; + goto label_1_brk; + } + + conj = Conjunction(); + mods = Modifiers(); + q = fClause(_field); + addClause(clauses, conj, mods, q); + } + +label_1_brk: + if (clauses.size() == 1 && firstQuery != NULL){ + clauses[0]->deleteQuery = false; + return firstQuery; + }else{ + clauses.setDoDelete(false); + return getBooleanQuery(clauses); + } +} + +Query* QueryParser::fClause(TCHAR* _field) { + Query* q=NULL; + QueryToken *fieldToken=NULL, *boost=NULL; + TCHAR* tmpField=NULL; + if (jj_2_1(2)) { + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case TERM: + { + fieldToken = jj_consume_token(TERM); + jj_consume_token(COLON); + // make sure to delete _field only if it's not contained already by the QP + tmpField=discardEscapeChar(fieldToken->image); + break; + } + case STAR: + jj_consume_token(STAR); + jj_consume_token(COLON); + tmpField=_CL_NEWARRAY(TCHAR,2); + tmpField[0]=_T('*'); + tmpField[1]=0; + break; + default: + jj_la1[5] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + } + + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case STAR: + case QUOTED: + case TERM: + case PREFIXTERM: + case WILDTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + { + q = fTerm( tmpField==NULL ? _field : tmpField ); + break; + } + case LPAREN: + { + jj_consume_token(LPAREN); + q = fQuery( tmpField==NULL ? _field : tmpField ); + jj_consume_token(RPAREN); + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == CARAT) + { + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + } + else + jj_la1[6] = jj_gen; + break; + } + default: + { + jj_la1[7] = jj_gen; + jj_consume_token(-1); + _CLDELETE_LCARRAY(tmpField); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + } + _CLDELETE_LCARRAY(tmpField); + if (q && boost != NULL) { + float_t f = 1.0; + try { + f = _tcstod(boost->image, NULL); + q->setBoost(f); + } catch (...) { /* ignore errors */ } + } + return q; +} + +Query* QueryParser::fTerm(const TCHAR* _field) { + QueryToken *term, *boost=NULL, *fuzzySlop=NULL, *goop1, *goop2; + bool prefix = false; + bool wildcard = false; + bool fuzzy = false; + //bool rangein = false; + Query* q = NULL; + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case STAR: + case TERM: + case PREFIXTERM: + case WILDTERM: + case NUMBER: + { + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case TERM: + term = jj_consume_token(TERM); + break; + case STAR: + term = jj_consume_token(STAR); + wildcard=true; + break; + case PREFIXTERM: + term = jj_consume_token(PREFIXTERM); + prefix=true; + break; + case WILDTERM: + term = jj_consume_token(WILDTERM); + wildcard=true; + break; + case NUMBER: + term = jj_consume_token(NUMBER); + break; + default: + jj_la1[8] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == FUZZY_SLOP) + { + fuzzySlop = jj_consume_token(FUZZY_SLOP); + fuzzy=true; + } + else + jj_la1[9] = jj_gen; + + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == CARAT) + { + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == FUZZY_SLOP) + { + fuzzySlop = jj_consume_token(FUZZY_SLOP); + fuzzy=true; + } + else + jj_la1[10] = jj_gen; + } + else + jj_la1[11] = jj_gen; + + TCHAR* termImage=NULL; + if (wildcard) { + termImage=discardEscapeChar(term->image); + q = getWildcardQuery(_field, termImage); + } else if (prefix) { + termImage = STRDUP_TtoT(term->image); + size_t tiLen = _tcslen(termImage); + termImage[tiLen-1]=0; + q = getPrefixQuery(_field,discardEscapeChar(termImage, termImage)); + } else if (fuzzy) { + float_t fms = fuzzyMinSim; + try { + if (fuzzySlop->image[1] != 0) + fms = _tcstod(fuzzySlop->image + 1, NULL); + } catch (...) { /* ignore exceptions */ } + if(fms < 0.0f || fms > 1.0f){ + _CLTHROWT(CL_ERR_Parse, _T("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !")); + } + termImage=discardEscapeChar(term->image); + q = getFuzzyQuery(_field, termImage,fms); + } else { + termImage=discardEscapeChar(term->image); + q = getFieldQuery(_field, termImage); + } + _CLDELETE_LCARRAY(termImage); + break; + } + case RANGEIN_START: + { + jj_consume_token(RANGEIN_START); + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case RANGEIN_GOOP: + goop1 = jj_consume_token(RANGEIN_GOOP); + break; + case RANGEIN_QUOTED: + goop1 = jj_consume_token(RANGEIN_QUOTED); + break; + default: + jj_la1[12] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == RANGEIN_TO) + jj_consume_token(RANGEIN_TO); + else + jj_la1[13] = jj_gen; + + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case RANGEIN_GOOP: + goop2 = jj_consume_token(RANGEIN_GOOP); + break; + case RANGEIN_QUOTED: + goop2 = jj_consume_token(RANGEIN_QUOTED); + break; + default: + jj_la1[14] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + jj_consume_token(RANGEIN_END); + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == CARAT) + { + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + } + else + jj_la1[15] = jj_gen; + + // TODO: Allow analysis::Term to accept ownership on a TCHAR* and save on extra dup's + if (goop1->kind == RANGEIN_QUOTED) { + _tcscpy(goop1->image, goop1->image+1); + goop1->image[_tcslen(goop1->image)-1]='\0'; + } + if (goop2->kind == RANGEIN_QUOTED) { + _tcscpy(goop2->image, goop2->image+1); + goop2->image[_tcslen(goop2->image)-1]='\0'; + } + TCHAR* t1 = discardEscapeChar(goop1->image); + TCHAR* t2 = discardEscapeChar(goop2->image); + q = getRangeQuery(_field, t1, t2, true); + _CLDELETE_LCARRAY(t1); + _CLDELETE_LCARRAY(t2); + break; + } + case RANGEEX_START: + { + jj_consume_token(RANGEEX_START); + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case RANGEEX_GOOP: + goop1 = jj_consume_token(RANGEEX_GOOP); + break; + case RANGEEX_QUOTED: + goop1 = jj_consume_token(RANGEEX_QUOTED); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == RANGEEX_TO) + jj_consume_token(RANGEEX_TO); + else + jj_la1[17] = jj_gen; + + switch ((jj_ntk==-1)?f_jj_ntk():jj_ntk) + { + case RANGEEX_GOOP: + goop2 = jj_consume_token(RANGEEX_GOOP); + break; + case RANGEEX_QUOTED: + goop2 = jj_consume_token(RANGEEX_QUOTED); + break; + default: + jj_la1[18] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + jj_consume_token(RANGEEX_END); + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == CARAT) + { + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + } + else + jj_la1[19] = jj_gen; + + if (goop1->kind == RANGEEX_QUOTED) + goop1->image = goop1->image + 1; + + if (goop2->kind == RANGEEX_QUOTED) + goop2->image = goop2->image + 1; + + TCHAR* t1 = discardEscapeChar(goop1->image); + TCHAR* t2 = discardEscapeChar(goop2->image); + q = getRangeQuery(_field, t1, t2, false); + _CLDELETE_LCARRAY(t1); + _CLDELETE_LCARRAY(t2); + break; + } + case QUOTED: + { + term = jj_consume_token(QUOTED); + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == FUZZY_SLOP) + fuzzySlop = jj_consume_token(FUZZY_SLOP); + else + jj_la1[20] = jj_gen; + + if (((jj_ntk==-1)?f_jj_ntk():jj_ntk) == CARAT) + { + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + } + else + jj_la1[21] = jj_gen; + + int32_t s = phraseSlop; + + if (fuzzySlop != NULL) { + try { + s = _ttoi(fuzzySlop->image + 1); + } + catch (...) { /* ignore exceptions */ } + } + // TODO: Make sure this hack, save an extra dup, is legal and not harmful + const size_t st = _tcslen(term->image); + term->image[st-1]='\0'; + TCHAR* tmp = discardEscapeChar(term->image+1); + q = getFieldQuery(_field, tmp, s); + _CLDELETE_LCARRAY(tmp); + break; + } + default: + { + jj_la1[22] = jj_gen; + jj_consume_token(-1); + _CLTHROWT(CL_ERR_Parse,_T("")); + } + } + if (boost != NULL) { + float_t f = 1.0; + try { + f = _tcstod(boost->image, NULL); + } + catch (...) { + /* Should this be handled somehow? (defaults to "no boost", if + * boost number is invalid) + */ + } + + // avoid boosting null queries, such as those caused by stop words + if (q != NULL) { + q->setBoost(f); + } + } + return q; +} + +bool QueryParser::jj_2_1(const int32_t xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_1(); } + catch(CLuceneError& e) { + // TODO: Improve this handling + if (e.number()==CL_ERR_Parse && _tcscmp(e.twhat(),_T("LookaheadSuccess"))==0) + return true; + else + throw e; + } + _CLFINALLY( jj_save(0, xla); ); +} + +bool QueryParser::jj_3R_2() { + if (jj_scan_token(TERM)) return true; + if (jj_scan_token(COLON)) return true; + return false; +} + +bool QueryParser::jj_3_1() { + QueryToken* xsp = jj_scanpos; + if (jj_3R_2()) { + jj_scanpos = xsp; + if (jj_3R_3()) return true; + } + return false; +} + +bool QueryParser::jj_3R_3() { + if (jj_scan_token(STAR)) return true; + if (jj_scan_token(COLON)) return true; + return false; +} + +QueryParser::QueryParser(CharStream* stream):_operator(OR_OPERATOR), + lowercaseExpandedTerms(true),useOldRangeQuery(false),allowLeadingWildcard(false),enablePositionIncrements(false), + analyzer(NULL),field(NULL),phraseSlop(0),fuzzyMinSim(FuzzyQuery::defaultMinSimilarity), + fuzzyPrefixLength(FuzzyQuery::defaultPrefixLength),/*locale(NULL),*/ + dateResolution(CL_NS(document)::DateTools::NO_RESOLUTION),fieldToDateResolution(NULL), + token_source(NULL),token(NULL),jj_nt(NULL),_firstToken(NULL),jj_ntk(-1),jj_scanpos(NULL),jj_lastpos(NULL),jj_la(0), + lookingAhead(false),jj_gen(0),jj_2_rtns(NULL),jj_rescan(false),jj_gc(0),jj_expentries(NULL),jj_expentry(NULL), + jj_kind(-1),jj_endpos(0) +{ + _init(stream); +} + +void QueryParser::_init(CharStream* stream){ + if (token_source == NULL) + token_source = _CLNEW QueryParserTokenManager(stream); + _firstToken = token = _CLNEW QueryToken(); + jj_ntk = -1; + jj_gen = 0; + for (int32_t i = 0; i < 23; i++) jj_la1[i] = -1; + jj_2_rtns = new JJCalls(); +} + +QueryToken* QueryParser::jj_consume_token(const int32_t kind) +{ + QueryToken* oldToken = token; + if (token->next != NULL) + token = token->next; + else + token = token->next = token_source->getNextToken(); + jj_ntk = -1; + if (token->kind == kind) { + jj_gen++; + if (++jj_gc > 100) { + jj_gc = 0; + JJCalls* c = jj_2_rtns; + while (c != NULL) { + if (c->gen < jj_gen) c->first = NULL; + c = c->next; + } + } + return token; + } + token = oldToken; + jj_kind = kind; + generateParseException(); + return NULL; +} + +bool QueryParser::jj_scan_token(const int32_t kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos->next == NULL) { + jj_lastpos = jj_scanpos = jj_scanpos->next = token_source->getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos->next; + } + } else { + jj_scanpos = jj_scanpos->next; + } + if (jj_rescan) { + int32_t i = 0; QueryToken* tok = token; + while (tok != NULL && tok != jj_scanpos) { i++; tok = tok->next; } + if (tok != NULL) jj_add_error_token(kind, i); + } + if (jj_scanpos->kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) _CLTHROWT(CL_ERR_Parse, _T("LookaheadSuccess")); + return false; +} + +void QueryParser::ReInit(CharStream* stream) { + token_source->ReInit(stream); + delete jj_2_rtns; + _deleteTokens(); + _init(NULL); +} + +QueryParser::QueryParser(QueryParserTokenManager* tm):_operator(OR_OPERATOR), + lowercaseExpandedTerms(true),useOldRangeQuery(false),allowLeadingWildcard(false),enablePositionIncrements(false), + analyzer(NULL),field(NULL),phraseSlop(0),fuzzyMinSim(FuzzyQuery::defaultMinSimilarity), + fuzzyPrefixLength(FuzzyQuery::defaultPrefixLength),/*locale(NULL),*/ + dateResolution(CL_NS(document)::DateTools::NO_RESOLUTION),fieldToDateResolution(NULL), + token_source(NULL),token(NULL),jj_nt(NULL),_firstToken(NULL),jj_ntk(-1),jj_scanpos(NULL),jj_lastpos(NULL),jj_la(0), + lookingAhead(false),jj_gen(0),jj_2_rtns(NULL),jj_rescan(false),jj_gc(0),jj_expentries(NULL),jj_expentry(NULL), + jj_kind(-1),jj_endpos(0) +{ + ReInit(tm); +} + +void QueryParser::ReInit(QueryParserTokenManager* tm){ + _CLLDELETE(token_source); + token_source = tm; + _deleteTokens(); + _firstToken = token = _CLNEW QueryToken(); + jj_ntk = -1; + jj_gen = 0; + for (int32_t i = 0; i < 23; i++) jj_la1[i] = -1; + delete jj_2_rtns; + jj_2_rtns = new JJCalls(); +} + +QueryToken* QueryParser::getNextToken() { + if (token->next != NULL) token = token->next; + else token = token->next = token_source->getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; +} + +QueryToken* QueryParser::getToken(int32_t index) { + QueryToken* t = lookingAhead ? jj_scanpos : token; + for (int32_t i = 0; i < index; i++) { + if (t->next != NULL) t = t->next; + else t = t->next = token_source->getNextToken(); + } + return t; +} + +int32_t QueryParser::f_jj_ntk() { + if ((jj_nt=token->next) == NULL){ + token->next=token_source->getNextToken(); + jj_ntk = token->next->kind; + return jj_ntk; + } + else{ + jj_ntk = jj_nt->kind; + return jj_ntk; + } +} + +QueryParser::JJCalls::JJCalls():gen(0),first(NULL),arg(0),next(NULL) +{ +} +QueryParser::JJCalls::~JJCalls(){ + _CLLDELETE(first); + delete next; +} + +void QueryParser::jj_add_error_token(const int32_t kind, int32_t pos) { + if (pos >= 100) return; + if (pos == jj_endpos + 1) { + jj_lasttokens[jj_endpos++] = kind; + } else if (jj_endpos != 0) { + _CLLDELETE(jj_expentry); + jj_expentry = _CLNEW ValueArray(jj_endpos); + for (int32_t i = 0; i < jj_endpos; i++) { + jj_expentry->values[i] = jj_lasttokens[i]; + } + bool exists = false; + if (!jj_expentries) jj_expentries = _CLNEW CL_NS(util)::CLVector*, CL_NS(util)::Deletor::Object< CL_NS(util)::ValueArray > >(); + for (size_t i=0;isize();i++){ + const ValueArray* oldentry = jj_expentries->at(i); + if (oldentry->length == jj_expentry->length) { + exists = true; + for (size_t i = 0; i < jj_expentry->length; i++) { + if (oldentry->values[i] != jj_expentry->values[i]) { + exists = false; + break; + } + } + if (exists) break; + } + } + if (!exists) {jj_expentries->push_back(jj_expentry); jj_expentry=NULL;} + if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind; + } +} + +void QueryParser::generateParseException() { + // lazily create the vectors required for this operation + if (!jj_expentries) + jj_expentries = _CLNEW CL_NS(util)::CLVector*, CL_NS(util)::Deletor::Object< CL_NS(util)::ValueArray > >(); + else + jj_expentries->clear(); + bool la1tokens[33]; + for (int32_t i = 0; i < 33; i++) { + la1tokens[i] = false; + } + if (jj_kind >= 0) { + la1tokens[jj_kind] = true; + jj_kind = -1; + } + for (int32_t i = 0; i < 23; i++) { + if (jj_la1[i] == jj_gen) { + for (int32_t j = 0; j < 32; j++) { + if ((jj_la1_0[i] & (1<(1); + jj_expentry->values[0] = i; + jj_expentries->push_back(jj_expentry); + jj_expentry=NULL; + } + } + jj_endpos = 0; + jj_rescan_token(); + jj_add_error_token(0, 0); + + TCHAR* err = getParseExceptionMessage(token, jj_expentries, tokenImage); + _CLTHROWT_DEL(CL_ERR_Parse, err); +} + +void QueryParser::jj_rescan_token() { + jj_rescan = true; + JJCalls* p = jj_2_rtns; + do { + if (p->gen > jj_gen) { + jj_la = p->arg; jj_lastpos = jj_scanpos = p->first; + jj_3_1(); + } + p = p->next; + } while (p != NULL); + jj_rescan = false; +} + +void QueryParser::jj_save(const int32_t /*index*/, int32_t xla) { + JJCalls* p = jj_2_rtns; + while (p->gen > jj_gen) { + if (p->next == NULL) { p = p->next = new JJCalls(); break; } + p = p->next; + } + p->gen = jj_gen + xla - jj_la; + p->first = token; + p->arg = xla; +} + +TCHAR* QueryParserConstants::addEscapes(TCHAR* str) { + const size_t len = _tcslen(str); + StringBuffer retval(len * 2); + TCHAR ch; + for (size_t i = 0; i < len; i++) { + switch (str[i]) + { + case 0 : + continue; + case _T('\b'): + retval.append(_T("\\b")); + continue; + case _T('\t'): + retval.append(_T("\\t")); + continue; + case _T('\n'): + retval.append(_T("\\n")); + continue; + case _T('\f'): + retval.append(_T("\\f")); + continue; + case _T('\r'): + retval.append(_T("\\r")); + continue; + case _T('"'): + retval.append(_T("\\\"")); + continue; + case _T('\''): + retval.append(_T("\\'")); + continue; + case _T('\\'): + retval.append(_T("\\\\")); + continue; + default: + if ((ch = str[i]) < 0x20 || ch > 0x7e) { + TCHAR buf[4]; + _sntprintf(buf, 4, _T("%012X"), static_cast(ch)); + retval.append(_T("\\u")); + retval.append(buf); + } else { + retval.appendChar(ch); + } + continue; + } + } + return retval.giveBuffer(); +} + +TCHAR* QueryParser::getParseExceptionMessage(QueryToken* currentToken, + CL_NS(util)::CLVector< CL_NS(util)::ValueArray*, CL_NS(util)::Deletor::Object< CL_NS(util)::ValueArray > >* expectedTokenSequences, + const TCHAR* tokenImage[]) +{ + // TODO: Check to see what's a realistic initial value for the buffers here + // TODO: Make eol configurable (will be useful for PrintStream implementation as well later)? + const TCHAR* eol = _T("\n"); + + StringBuffer expected(CL_MAX_PATH); + size_t maxSize = 0; + for (size_t i = 0; i < expectedTokenSequences->size(); i++) { + if (maxSize < expectedTokenSequences->at(i)->length) { + maxSize = expectedTokenSequences->at(i)->length; + } + for (size_t j = 0; j < expectedTokenSequences->at(i)->length; j++) { + expected.append(tokenImage[expectedTokenSequences->at(i)->values[j]]); + expected.appendChar(_T(' ')); + } + if (expectedTokenSequences->at(i)->values[expectedTokenSequences->at(i)->length - 1] != 0) { + expected.append(_T("...")); + } + expected.append(eol); + expected.append(_T(" ")); + } + + StringBuffer retval(CL_MAX_PATH); + retval.append(_T("Encountered \"")); + QueryToken* tok = currentToken->next; + for (size_t i = 0; i < maxSize; i++) { + if (i != 0) retval.appendChar(' '); + if (tok->kind == 0) { + retval.append(tokenImage[0]); + break; + } + if (tok->image){ + TCHAR* buf = addEscapes(tok->image); + retval.append(buf); + _CLDELETE_CARRAY(buf); + } + tok = tok->next; + } + retval.append(_T("\" at line ")); + retval.appendInt(currentToken->next->beginLine); + retval.append(_T(", column ")); + retval.appendInt(currentToken->next->beginColumn); + retval.appendChar(_T('.')); + retval.append(eol); + if (expectedTokenSequences->size() == 1) { + retval.append(_T("Was expecting:")); + retval.append(eol); + retval.append(_T(" ")); + } else { + retval.append(_T("Was expecting one of:")); + retval.append(eol); + retval.append(_T(" ")); + } + retval.append(expected.getBuffer()); + + return retval.giveBuffer(); +} + +CL_NS_END diff --git a/src/core/CLucene/queryParser/QueryParser.h b/src/core/CLucene/queryParser/QueryParser.h new file mode 100644 index 00000000000..3ca5c55162a --- /dev/null +++ b/src/core/CLucene/queryParser/QueryParser.h @@ -0,0 +1,530 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_QueryParser_ +#define _lucene_queryParser_QueryParser_ + +#include "CLucene/util/Array.h" +#include "QueryParserTokenManager.h" +#include "CLucene/document/DateTools.h" +#include "CLucene/util/VoidMap.h" +#include "CLucene/util/VoidList.h" + +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(analysis,Analyzer) +CL_CLASS_DEF(search,Query) +CL_CLASS_DEF(search,BooleanClause) + +CL_NS_DEF(queryParser) + +class QueryParserConstants; + +/** + * This class is generated by JavaCC. The most important method is + * {@link #parse(String)}. + * + * The syntax for query strings is as follows: + * A Query is a series of clauses. + * A clause may be prefixed by: + *
    + *
  • a plus (+) or a minus (-) sign, indicating + * that the clause is required or prohibited respectively; or + *
  • a term followed by a colon, indicating the field to be searched. + * This enables one to construct queries which search multiple fields. + *
+ * + * A clause may be either: + *
    + *
  • a term, indicating all the documents that contain this term; or + *
  • a nested query, enclosed in parentheses. Note that this may be used + * with a +/- prefix to require any of a set of + * terms. + *
+ * + * Thus, in BNF, the query grammar is: + *
+ *   Query  ::= ( Clause )*
+ *   Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
+ * 
+ * + *

+ * Examples of appropriately formatted queries can be found in the query syntax + * documentation. + *

+ * + *

+ * In {@link RangeQuery}s, QueryParser tries to detect date values, e.g. + * date:[6/1/2005 TO 6/4/2005] produces a range query that searches + * for "date" fields between 2005-06-01 and 2005-06-04. Note that the format + * of the accepted input depends on {@link #setLocale(Locale) the locale}. + * By default a date is converted into a search term using the deprecated + * {@link DateField} for compatibility reasons. + * To use the new {@link DateTools} to convert dates, a + * {@link org.apache.lucene.document.DateTools.Resolution} has to be set. + *

+ *

+ * The date resolution that shall be used for RangeQueries can be set + * using {@link #setDateResolution(DateTools.Resolution)} + * or {@link #setDateResolution(String, DateTools.Resolution)}. The former + * sets the default date resolution for all fields, whereas the latter can + * be used to set field specific date resolutions. Field specific date + * resolutions take, if set, precedence over the default date resolution. + *

+ *

+ * If you use neither {@link DateField} nor {@link DateTools} in your + * index, you can create your own + * query parser that inherits QueryParser and overwrites + * {@link #getRangeQuery(String, String, String, boolean)} to + * use a different method for date conversion. + *

+ * + *

Note that QueryParser is not thread-safe.

+ * + * @author Brian Goetz + * @author Peter Halacsy + * @author Tatu Saloranta + */ +class CLUCENE_EXPORT QueryParser : public virtual QueryParserConstants +{ +private: + LUCENE_STATIC_CONSTANT(int32_t, CONJ_NONE=0); + LUCENE_STATIC_CONSTANT(int32_t, CONJ_AND=1); + LUCENE_STATIC_CONSTANT(int32_t, CONJ_OR=2); + + LUCENE_STATIC_CONSTANT(int32_t, MOD_NONE=0); + LUCENE_STATIC_CONSTANT(int32_t, MOD_NOT=10); + LUCENE_STATIC_CONSTANT(int32_t, MOD_REQ=11); + +public: + /** The default operator for parsing queries. + * Use {@link QueryParser#setDefaultOperator} to change it. + */ + enum Operator { + OR_OPERATOR, + AND_OPERATOR + }; + +private: + /** The actual operator that parser uses to combine query terms */ + Operator _operator; + + bool lowercaseExpandedTerms; + bool useOldRangeQuery; + bool allowLeadingWildcard; + bool enablePositionIncrements; + + CL_NS(analysis)::Analyzer* analyzer; + TCHAR* field; + int32_t phraseSlop; + float_t fuzzyMinSim; + int32_t fuzzyPrefixLength; + //TODO: Locale locale = Locale.getDefault(); + + // the default date resolution + CL_NS(document)::DateTools::Resolution dateResolution; + // maps field names to date resolutions + typedef CL_NS(util)::CLHashMap FieldToDateResolutionType; + FieldToDateResolutionType* fieldToDateResolution; + +public: + /** Constructs a query parser. + * @param f the default field for query terms. + * @param a used to find terms in the query text. + */ + QueryParser(const TCHAR* f, CL_NS(analysis)::Analyzer* a); + virtual ~QueryParser(); + void _deleteTokens(); + + /** For backward compatibility */ + static CL_NS(search)::Query* parse(const TCHAR* q, const TCHAR* f, CL_NS(analysis)::Analyzer* a); + + /** Parses a query string, returning a {@link org.apache.lucene.search.Query}. + * @param query the query string to be parsed. + * @throws ParseException if the parsing fails + */ + CL_NS(search)::Query* parse(const TCHAR* _query); + + /** + * @return Returns the analyzer. + */ + CL_NS(analysis)::Analyzer* getAnalyzer() const; + + /** + * @return Returns the field. + */ + const TCHAR* getField() const; + + /** + * Get the minimal similarity for fuzzy queries. + */ + float_t getFuzzyMinSim() const; + + /** + * Set the minimum similarity for fuzzy queries. + * Default is 0.5f. + */ + void setFuzzyMinSim(const float_t _fuzzyMinSim); + + /** + * Get the prefix length for fuzzy queries. + * @return Returns the fuzzyPrefixLength. + */ + int32_t getFuzzyPrefixLength() const; + + /** + * Set the prefix length for fuzzy queries. Default is 0. + * @param fuzzyPrefixLength The fuzzyPrefixLength to set. + */ + void setFuzzyPrefixLength(const int32_t _fuzzyPrefixLength); + + /** + * Sets the default slop for phrases. If zero, then exact phrase matches + * are required. Default value is zero. + */ + void setPhraseSlop(const int32_t _phraseSlop); + + /** + * Gets the default slop for phrases. + */ + int32_t getPhraseSlop() const; + + /** + * Set to true to allow leading wildcard characters. + *

+ * When set, * or ? are allowed as + * the first character of a PrefixQuery and WildcardQuery. + * Note that this can produce very slow + * queries on big indexes. + *

+ * Default: false. + */ + void setAllowLeadingWildcard(const bool _allowLeadingWildcard); + + /** + * @see #setAllowLeadingWildcard(boolean) + */ + bool getAllowLeadingWildcard() const; + + /** + * Set to true to enable position increments in result query. + *

+ * When set, result phrase and multi-phrase queries will + * be aware of position increments. + * Useful when e.g. a StopFilter increases the position increment of + * the token that follows an omitted token. + *

+ * Default: false. + */ + void setEnablePositionIncrements(const bool _enable); + + /** + * @see #setEnablePositionIncrements(boolean) + */ + bool getEnablePositionIncrements() const; + + /** + * Sets the boolean operator of the QueryParser. + * In default mode (OR_OPERATOR) terms without any modifiers + * are considered optional: for example capital of Hungary is equal to + * capital OR of OR Hungary.
+ * In AND_OPERATOR mode terms are considered to be in conjuction: the + * above mentioned query is parsed as capital AND of AND Hungary + */ + void setDefaultOperator(Operator _op); + + /** + * Gets implicit operator setting, which will be either AND_OPERATOR + * or OR_OPERATOR. + */ + Operator getDefaultOperator() const; + + /** + * Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically + * lower-cased or not. Default is true. + */ + void setLowercaseExpandedTerms(const bool _lowercaseExpandedTerms); + + /** + * @see #setLowercaseExpandedTerms(boolean) + */ + bool getLowercaseExpandedTerms() const; + + /** + * By default QueryParser uses new ConstantScoreRangeQuery in preference to RangeQuery + * for range queries. This implementation is generally preferable because it + * a) Runs faster b) Does not have the scarcity of range terms unduly influence score + * c) avoids any "TooManyBooleanClauses" exception. + * However, if your application really needs to use the old-fashioned RangeQuery and the above + * points are not required then set this option to true + * Default is false. + */ + void setUseOldRangeQuery(const bool _useOldRangeQuery); + + /** + * @see #setUseOldRangeQuery(boolean) + */ + bool getUseOldRangeQuery() const; + + /** + * Set locale used by date range parsing. + * + void setLocale(const Locale _locale) { + locale = _locale; + } + + + * Returns current locale, allowing access by subclasses. + * + Locale getLocale() const { + return locale; + } + */ + + /** + * Sets the default date resolution used by RangeQueries for fields for which no + * specific date resolutions has been set. Field specific resolutions can be set + * with {@link #setDateResolution(String, DateTools.Resolution)}. + * + * @param dateResolution the default date resolution to set + */ + void setDateResolution(const CL_NS(document)::DateTools::Resolution _dateResolution); + + /** + * Sets the date resolution used by RangeQueries for a specific field. + * + * @param fieldName field for which the date resolution is to be set + * @param dateResolution date resolution to set + */ + void setDateResolution(const TCHAR* fieldName, const CL_NS(document)::DateTools::Resolution _dateResolution); + + /** + * Returns the date resolution that is used by RangeQueries for the given field. + * Returns null (NO_RESOLUTION), if no default or field specific date resolution has been set + * for the given field. + * + */ + CL_NS(document)::DateTools::Resolution getDateResolution(const TCHAR* fieldName) const; + +protected: + void addClause(std::vector& clauses, int32_t conj, int32_t mods, CL_NS(search)::Query* q); + + /** + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getFieldQuery(const TCHAR* _field, TCHAR* queryText); + + /** + * Base implementation delegates to {@link #getFieldQuery(String,String)}. + * This method may be overridden, for example, to return + * a SpanNearQuery instead of a PhraseQuery. + * + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getFieldQuery(const TCHAR* _field, TCHAR* queryText, const int32_t slop); + + /** + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, const bool inclusive); + + /** + * Factory method for generating query, given a set of clauses. + * By default creates a boolean query composed of clauses passed in. + * + * Can be overridden by extending classes, to modify query being + * returned. + * + * @param clauses Vector that contains {@link BooleanClause} instances + * to join. + * @param disableCoord true if coord scoring should be disabled. + * + * @return Resulting {@link Query} object. + * @exception ParseException throw in overridden method to disallow + */ + CL_NS(search)::Query* getBooleanQuery(std::vector& clauses, bool disableCoord = false); + + /** + * Factory method for generating a query. Called when parser + * parses an input term token that contains one or more wildcard + * characters (? and *), but is not a prefix term token (one + * that has just a single * character at the end) + *

+ * Depending on settings, prefix term may be lower-cased + * automatically. It will not go through the default Analyzer, + * however, since normal Analyzers are unlikely to work properly + * with wildcard templates. + *

+ * Can be overridden by extending classes, to provide custom handling for + * wildcard queries, which may be necessary due to missing analyzer calls. + * + * @param field Name of the field query will use. + * @param termStr Term token that contains one or more wild card + * characters (? or *), but is not simple prefix term + * + * @return Resulting {@link Query} built for the term + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getWildcardQuery(const TCHAR* _field, TCHAR* termStr); + + /** + * Factory method for generating a query (similar to + * {@link #getWildcardQuery}). Called when parser parses an input term + * token that uses prefix notation; that is, contains a single '*' wildcard + * character as its last character. Since this is a special case + * of generic wildcard term, and such a query can be optimized easily, + * this usually results in a different query object. + *

+ * Depending on settings, a prefix term may be lower-cased + * automatically. It will not go through the default Analyzer, + * however, since normal Analyzers are unlikely to work properly + * with wildcard templates. + *

+ * Can be overridden by extending classes, to provide custom handling for + * wild card queries, which may be necessary due to missing analyzer calls. + * + * @param field Name of the field query will use. + * @param termStr Term token to use for building term for the query + * (without trailing '*' character!) + * + * @return Resulting {@link Query} built for the term + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getPrefixQuery(const TCHAR* _field, TCHAR* _termStr); + + /** + * Factory method for generating a query (similar to + * {@link #getWildcardQuery}). Called when parser parses + * an input term token that has the fuzzy suffix (~) appended. + * + * @param field Name of the field query will use. + * @param termStr Term token to use for building term for the query + * + * @return Resulting {@link Query} built for the term + * @exception ParseException throw in overridden method to disallow + */ + virtual CL_NS(search)::Query* getFuzzyQuery(const TCHAR* _field, TCHAR* termStr, const float_t minSimilarity); + +private: + /** + * Returns a String where the escape char has been + * removed, or kept only once if there was a double escape. + * + * Supports escaped unicode characters, e. g. translates + * A to A. + * + * @memory caller is responsible to free the returned string + * + */ + TCHAR* discardEscapeChar(TCHAR* input, TCHAR* output=NULL); + + /** Returns the numeric value of the hexadecimal character */ + static int32_t hexToInt(TCHAR c); + + struct JJCalls; + +public: + /** + * Returns a String where those characters that QueryParser + * expects to be escaped are escaped by a preceding \. + * + * @memory caller is responsible to free the returned string + */ + static TCHAR* escape(const TCHAR* s); + + // * Query ::= ( Clause )* + // * Clause ::= ["+", "-"] [ ":"] ( | "(" Query ")" ) + int32_t Conjunction(); + + int32_t Modifiers(); + + // This makes sure that there is no garbage after the query string + CL_NS(search)::Query* TopLevelQuery(TCHAR* _field); + + CL_NS(search)::Query* fQuery(TCHAR* _field); + + CL_NS(search)::Query* fClause(TCHAR* _field); + +public: + CL_NS(search)::Query* fTerm(const TCHAR* _field); + +private: + bool jj_2_1(const int32_t xla); + bool jj_3R_2(); + bool jj_3_1(); + bool jj_3R_3(); + +public: + QueryParserTokenManager* token_source; + QueryToken *token, *jj_nt; +private: + QueryToken *_firstToken; + int32_t jj_ntk; + QueryToken *jj_scanpos, *jj_lastpos; + int32_t jj_la; +public: + bool lookingAhead; +private: + bool jj_semLA; + int32_t jj_gen; + int32_t jj_la1[23]; + static const int32_t jj_la1_0[]; + static const int32_t jj_la1_1[]; + JJCalls* jj_2_rtns; + bool jj_rescan; + int32_t jj_gc; + +public: + QueryParser(CharStream* stream); + void ReInit(CharStream* stream); + QueryParser(QueryParserTokenManager* tm); + void ReInit(QueryParserTokenManager* tm); + +private: + void _init(CharStream* stream); + QueryToken* jj_consume_token(const int32_t kind); + bool jj_scan_token(const int32_t kind); + +public: + QueryToken* getNextToken(); + QueryToken* getToken(int32_t index); + +private: + int32_t f_jj_ntk(); + + CL_NS(util)::CLVector< CL_NS(util)::ValueArray*, + CL_NS(util)::Deletor::Object< CL_NS(util)::ValueArray > + >* jj_expentries; + CL_NS(util)::ValueArray* jj_expentry; + int32_t jj_kind; + int32_t jj_lasttokens[100]; + int32_t jj_endpos; + + void jj_add_error_token(const int32_t kind, int32_t pos); + +public: + void generateParseException(); + + //void enable_tracing() {} + //void disable_tracing() {} + +private: + void jj_rescan_token(); + void jj_save(const int32_t index, int32_t xla); + + TCHAR* getParseExceptionMessage(QueryToken* currentToken, + CL_NS(util)::CLVector< CL_NS(util)::ValueArray*, + CL_NS(util)::Deletor::Object< CL_NS(util)::ValueArray > >* expectedTokenSequences, + const TCHAR* tokenImage[]); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/QueryParserConstants.h b/src/core/CLucene/queryParser/QueryParserConstants.h new file mode 100644 index 00000000000..96accb4631e --- /dev/null +++ b/src/core/CLucene/queryParser/QueryParserConstants.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_QueryParserConstants_ +#define _lucene_queryParser_QueryParserConstants_ + +CL_NS_DEF(queryParser) + +class CLUCENE_EXPORT QueryParserConstants { +public: + enum Types { + _EOF = 0, + _NUM_CHAR = 1, + _ESCAPED_CHAR = 2, + _TERM_START_CHAR = 3, + _TERM_CHAR = 4, + _WHITESPACE = 5, + AND = 7, + OR = 8, + NOT = 9, + PLUS = 10, + MINUS = 11, + LPAREN = 12, + RPAREN = 13, + COLON = 14, + STAR = 15, + CARAT = 16, + QUOTED = 17, + TERM = 18, + FUZZY_SLOP = 19, + PREFIXTERM = 20, + WILDTERM = 21, + RANGEIN_START = 22, + RANGEEX_START = 23, + NUMBER = 24, + RANGEIN_TO = 25, + RANGEIN_END = 26, + RANGEIN_QUOTED = 27, + RANGEIN_GOOP = 28, + RANGEEX_TO = 29, + RANGEEX_END = 30, + RANGEEX_QUOTED = 31, + RANGEEX_GOOP = 32 + }; + + enum LexStates { + Boost = 0, + RangeEx = 1, + RangeIn = 2, + DEFAULT = 3 + }; + + static const TCHAR* tokenImage[]; + +protected: + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal, while formatting an error message. + * Called internally only by error reporting tools. + */ + static TCHAR* addEscapes(TCHAR* str); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/QueryParserTokenManager.cpp b/src/core/CLucene/queryParser/QueryParserTokenManager.cpp new file mode 100644 index 00000000000..14de0cf1889 --- /dev/null +++ b/src/core/CLucene/queryParser/QueryParserTokenManager.cpp @@ -0,0 +1,1265 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_ApiHeader.h" +#include "QueryParserTokenManager.h" +#include "_CharStream.h" +#include "_FastCharStream.h" +#include "QueryToken.h" + +#include "CLucene/util/StringBuffer.h" + +CL_NS_DEF(queryParser) + +const int64_t QueryParserTokenManager::jjbitVec2[]={0x0L, 0x0L, _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff)}; +const int64_t QueryParserTokenManager::jjbitVec0[] = { + _ILONGLONG(0xfffffffffffffffe), _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff), _ILONGLONG(0xffffffffffffffff) +}; +const int32_t QueryParserTokenManager::jjnextStates[]={ + 15, 17, 18, 29, 32, 23, 33, 30, 20, 21, 32, 23, 33, 31, 34, 27, + 2, 4, 5, 0, 1 +}; +const TCHAR* QueryParserTokenManager::jjstrLiteralImages[]={ + _T(""), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, _T("\53"), _T("\55)"), _T("\50)"), + _T("\51"), _T("\72"), _T("\52"), _T("\136"), NULL, NULL, NULL, NULL, NULL, _T("\133"), _T("\173"), NULL, + _T("\124\117"), _T("\135"), NULL, NULL, _T("\124\117"), _T("\175"), NULL, NULL +}; +const TCHAR* QueryParserTokenManager::lexStateNames [] = { + _T("Boost"), + _T("RangeEx"), + _T("RangeIn"), + _T("DEFAULT") +}; +const int32_t QueryParserTokenManager::jjnewLexState [] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 2, 1, 3, + -1, 3, -1, -1, -1, 3, -1, -1 +}; +const int64_t QueryParserTokenManager::jjtoToken [] = { + _ILONGLONG(0x1ffffff81) +}; +const int64_t QueryParserTokenManager::jjtoSkip [] = { + _ILONGLONG(0x40) +}; + +QueryParserTokenManager::QueryParserTokenManager(CharStream* stream, const int32_t lexState) : + input_stream(stream), curChar(0), curLexState(3), defaultLexState(3),jjnewStateCnt(0),jjround(0), + jjmatchedPos(0),jjmatchedKind(0) +{ + if (lexState > -1) + SwitchTo(lexState); +} +QueryParserTokenManager::~QueryParserTokenManager() +{ + _CLLDELETE(input_stream); +} + +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_3(const int32_t /*pos*/, int64_t /*active0*/) +{ + return -1; +} + +int32_t QueryParserTokenManager::jjStartNfa_3(int32_t pos, int64_t active0) +{ + return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); +} + +int32_t QueryParserTokenManager::jjStopAtPos(const int32_t pos, const int32_t kind) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; +} + +int32_t QueryParserTokenManager::jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return pos + 1; + } + return jjMoveNfa_3(state, pos + 1); +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_3() +{ + switch(curChar) + { + case 40: + return jjStopAtPos(0, 12); + case 41: + return jjStopAtPos(0, 13); + case 42: + return jjStartNfaWithStates_3(0, 15, 36); + case 43: + return jjStopAtPos(0, 10); + case 45: + return jjStopAtPos(0, 11); + case 58: + return jjStopAtPos(0, 14); + case 91: + return jjStopAtPos(0, 22); + case 94: + return jjStopAtPos(0, 16); + case 123: + return jjStopAtPos(0, 23); + default : + return jjMoveNfa_3(0, 0); + } +} + +void QueryParserTokenManager::jjCheckNAdd(const int32_t state) +{ + if (jjrounds[state] != jjround) + { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } +} + +void QueryParserTokenManager::jjAddStates(int32_t start, const int32_t end) +{ + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); +} + +void QueryParserTokenManager::jjCheckNAddTwoStates(const int32_t state1, const int32_t state2) +{ + jjCheckNAdd(state1); + jjCheckNAdd(state2); +} + +void QueryParserTokenManager::jjCheckNAddStates(int32_t start, const int32_t end) +{ + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); +} + +void QueryParserTokenManager::jjCheckNAddStates(const int32_t start) +{ + jjCheckNAdd(jjnextStates[start]); + jjCheckNAdd(jjnextStates[start + 1]); +} + +int32_t QueryParserTokenManager::jjMoveNfa_3(const int32_t startState, int32_t curPos) +{ + int32_t startsAt = 0; + jjnewStateCnt = 36; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + uint64_t l = (uint64_t) (((uint64_t)1L) << ((int32_t)curChar)); + do + { + switch(jjstateSet[--i]) + { + case 36: + case 25: + if (( _ILONGLONG(0xfbfffcf8ffffd9ff) & l) == 0L) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 0: + if (( _ILONGLONG(0xfbffd4f8ffffd9ff) & l) != 0L) + { + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + } + else if ((_ILONGLONG(0x100002600) & l) != 0L) + { + if (kind > 6) + kind = 6; + } + else if (curChar == 34) + jjCheckNAddStates(0, 2); + else if (curChar == 33) + { + if (kind > 9) + kind = 9; + } + if ((_ILONGLONG(0x7bffd0f8ffffd9ff) & l) != 0L) + { + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + } + else if (curChar == 42) + { + if (kind > 20) + kind = 20; + } + if (curChar == 38) + jjstateSet[jjnewStateCnt++] = 4; + break; + case 4: + if (curChar == 38 && kind > 7) + kind = 7; + break; + case 5: + if (curChar == 38) + jjstateSet[jjnewStateCnt++] = 4; + break; + case 13: + if (curChar == 33 && kind > 9) + kind = 9; + break; + case 14: + case 16: + if (curChar == 34) + jjCheckNAddStates(0, 2); + break; + case 15: + if ((_ILONGLONG(0xfffffffbffffffff) & l) != 0L) + jjCheckNAddStates(0, 2); + break; + case 18: + if (curChar == 34 && kind > 17) + kind = 17; + break; + case 20: + if ((_ILONGLONG(0x3ff000000000000) & l) == 0L) + break; + if (kind > 19) + kind = 19; + jjAddStates(8, 9); + break; + case 21: + if (curChar == 46) + jjCheckNAdd(22); + break; + case 22: + if ((_ILONGLONG(0x3ff000000000000) & l) == 0L) + break; + if (kind > 19) + kind = 19; + jjCheckNAdd(22); + break; + case 23: + if (curChar == 42 && kind > 20) + kind = 20; + break; + case 24: + if ((_ILONGLONG(0xfbffd4f8ffffd9ff) & l) == 0L) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 27: + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if ((_ILONGLONG(0x7bffd0f8ffffd9ff) & l) == 0L) + break; + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + break; + case 29: + if ((_ILONGLONG(0x7bfff8f8ffffd9ff) & l) == 0L) + break; + if (kind > 18) + kind = 18; + jjCheckNAddTwoStates(29, 30); + break; + case 31: + if (kind > 18) + kind = 18; + jjCheckNAddTwoStates(29, 30); + break; + case 32: + if ((_ILONGLONG(0x7bfff8f8ffffd9ff) & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 34: + jjCheckNAddStates(10, 12); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + uint64_t l = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 36: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) != 0L) + { + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + } + else if (curChar == 92) + jjCheckNAddTwoStates(27, 27); + break; + case 0: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) != 0L) + { + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + } + else if (curChar == 92) + jjCheckNAddStates(13, 15); + else if (curChar == 126) + { + if (kind > 19) + kind = 19; + jjstateSet[jjnewStateCnt++] = 20; + } + if ((_ILONGLONG(0x97ffffff87ffffff) & l) != 0L) + { + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + } + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 11; + else if (curChar == 124) + jjstateSet[jjnewStateCnt++] = 8; + else if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 6; + else if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 2; + break; + case 1: + if (curChar == 68 && kind > 7) + kind = 7; + break; + case 2: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 1; + break; + case 3: + if (curChar == 65) + jjstateSet[jjnewStateCnt++] = 2; + break; + case 6: + if (curChar == 82 && kind > 8) + kind = 8; + break; + case 7: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 6; + break; + case 8: + if (curChar == 124 && kind > 8) + kind = 8; + break; + case 9: + if (curChar == 124) + jjstateSet[jjnewStateCnt++] = 8; + break; + case 10: + if (curChar == 84 && kind > 9) + kind = 9; + break; + case 11: + if (curChar == 79) + jjstateSet[jjnewStateCnt++] = 10; + break; + case 12: + if (curChar == 78) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 15: + jjAddStates(0, 2); + break; + case 17: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 16; + break; + case 19: + if (curChar != 126) + break; + if (kind > 19) + kind = 19; + jjstateSet[jjnewStateCnt++] = 20; + break; + case 24: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) == 0L) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 25: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) == 0L) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 26: + if (curChar == 92) + jjCheckNAddTwoStates(27, 27); + break; + case 27: + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) == 0L) + break; + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + break; + case 29: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) == 0L) + break; + if (kind > 18) + kind = 18; + jjCheckNAddTwoStates(29, 30); + break; + case 30: + if (curChar == 92) + jjCheckNAddTwoStates(31, 31); + break; + case 31: + if (kind > 18) + kind = 18; + jjCheckNAddTwoStates(29, 30); + break; + case 32: + if ((_ILONGLONG(0x97ffffff87ffffff) & l) != 0L) + jjCheckNAddStates(10, 12); + break; + case 33: + if (curChar == 92) + jjCheckNAddTwoStates(34, 34); + break; + case 34: + jjCheckNAddStates(10, 12); + break; + case 35: + if (curChar == 92) + jjCheckNAddStates(13, 15); + break; + default : break; + } + } while(i != startsAt); + } + else + { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + uint64_t l1 = ((uint64_t)1L) << (hiByte & 63); + int32_t i2 = (curChar & 0xff) >> 6; + uint64_t l2 = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 36: + case 25: + case 27: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 0: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + { + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + } + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + { + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + } + break; + case 15: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjAddStates(0, 2); + break; + case 24: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 21) + kind = 21; + jjCheckNAddTwoStates(25, 26); + break; + case 28: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 18) + kind = 18; + jjCheckNAddStates(3, 7); + break; + case 29: + case 31: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 18) + kind = 18; + jjCheckNAddTwoStates(29, 30); + break; + case 32: + case 34: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjCheckNAddStates(10, 12); + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 36 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return curPos; + } + } +} + +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_1(const int32_t pos, const int64_t active0) +{ + switch (pos) + { + case 0: + if ((active0 & 0x20000000L) != 0L) + { + jjmatchedKind = 32; + return 6; + } + return -1; + default : + return -1; + } +} + +int32_t QueryParserTokenManager::jjStartNfa_1(int32_t pos, int64_t active0) +{ + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); +} + +int32_t QueryParserTokenManager::jjStartNfaWithStates_1(const int32_t pos, const int32_t kind, const int32_t state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return pos + 1; + } + return jjMoveNfa_1(state, pos + 1); +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_1() +{ + switch(curChar) + { + case 84: + return jjMoveStringLiteralDfa1_1(0x20000000L); + case 125: + return jjStopAtPos(0, 30); + default : + return jjMoveNfa_1(0, 0); + } +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_1(int64_t active0) +{ + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else { + jjStopStringLiteralDfa_1(0, active0); + return 1; + } + } + switch(curChar) + { + case 79: + if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_1(1, 29, 6); + break; + default : + break; + } + return jjStartNfa_1(0, active0); +} + +int32_t QueryParserTokenManager::jjMoveNfa_1(const int32_t startState, int32_t curPos) +{ + int32_t startsAt = 0; + jjnewStateCnt = 7; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + uint64_t l = ((uint64_t)1L) << curChar; + + do + { + switch(jjstateSet[--i]) + { + case 0: + if ((_ILONGLONG(0xfffffffeffffffff) & l) != 0L) + { + if (kind > 32) + kind = 32; + jjCheckNAdd(6); + } + if ((_ILONGLONG(0x100002600) & l) != 0L) + { + if (kind > 6) + kind = 6; + } + else if (curChar == 34) + jjCheckNAddTwoStates(2, 4); + break; + case 1: + if (curChar == 34) + jjCheckNAddTwoStates(2, 4); + break; + case 2: + if ((_ILONGLONG(0xfffffffbffffffff) & l) != 0L) + jjCheckNAddStates(16, 18); + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(16, 18); + break; + case 5: + if (curChar == 34 && kind > 31) + kind = 31; + break; + case 6: + if ((_ILONGLONG(0xfffffffeffffffff) & l) == 0L) + break; + if (kind > 32) + kind = 32; + jjCheckNAdd(6); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + uint64_t l = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 0: + case 6: + if ((_ILONGLONG(0xdfffffffffffffff) & l) == 0L) + break; + if (kind > 32) + kind = 32; + jjCheckNAdd(6); + break; + case 2: + jjAddStates(16, 18); + break; + case 4: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 3; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + uint64_t l1 = ((uint64_t)1L) << (hiByte & 63); + int32_t i2 = (curChar & 0xff) >> 6; + uint64_t l2 = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 0: + case 6: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 32) + kind = 32; + jjCheckNAdd(6); + break; + case 2: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjAddStates(16, 18); + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return curPos; + } + } +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_0() +{ + return jjMoveNfa_0(0, 0); +} + +int32_t QueryParserTokenManager::jjMoveNfa_0(const int32_t startState, int32_t curPos) +{ + int32_t startsAt = 0; + jjnewStateCnt = 3; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + uint64_t l = ((uint64_t)1L) << curChar; + + do + { + switch(jjstateSet[--i]) + { + case 0: + if ((_ILONGLONG(0x3ff000000000000) & l) == 0L) + break; + if (kind > 24) + kind = 24; + jjAddStates(19, 20); + break; + case 1: + if (curChar == 46) + jjCheckNAdd(2); + break; + case 2: + if ((_ILONGLONG(0x3ff000000000000) & l) == 0L) + break; + if (kind > 24) + kind = 24; + jjCheckNAdd(2); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + /* + uint64_t l = ((uint64_t)1L) << (curChar & 63); + do + { + switch(jjstateSet[--i]) + { + default : break; + } + } while(i != startsAt);*/ + i = startsAt; + } + else + { + /* + int32_t hiByte = (int)(curChar >> 8); + int32_t i1 = hiByte >> 6; + uint64_t l1 = ((uint64_t)1L) << (hiByte & 63); + int32_t i2 = (curChar & 0xff) >> 6; + uint64_t l2 = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + default : break; + } + } while(i != startsAt);*/ + i = startsAt; + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return curPos; + } + } +} + +int32_t QueryParserTokenManager::jjStopStringLiteralDfa_2(const int32_t pos, const int64_t active0) +{ + switch (pos) + { + case 0: + if ((active0 & 0x2000000L) != 0L) + { + jjmatchedKind = 28; + return 6; + } + return -1; + default : + return -1; + } +} + +int32_t QueryParserTokenManager::jjStartNfa_2(int32_t pos, int64_t active0) +{ + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); +} + +int32_t QueryParserTokenManager::jjStartNfaWithStates_2(const int32_t pos, const int32_t kind, const int32_t state) +{ + jjmatchedKind = kind; + jjmatchedPos = pos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return pos+1; + } + return jjMoveNfa_2(state, pos + 1); +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa0_2() +{ + switch(curChar) + { + case 84: + return jjMoveStringLiteralDfa1_2(0x2000000L); + case 93: + return jjStopAtPos(0, 26); + default : + return jjMoveNfa_2(0, 0); + } +} + +int32_t QueryParserTokenManager::jjMoveStringLiteralDfa1_2(const int64_t active0) +{ + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else { + jjStopStringLiteralDfa_2(0, active0); + return 1; + } + } + switch(curChar) + { + case 79: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_2(1, 25, 6); + break; + default : + break; + } + return jjStartNfa_2(0, active0); +} + +int32_t QueryParserTokenManager::jjMoveNfa_2(const int32_t startState, int32_t curPos) +{ + int32_t startsAt = 0; + jjnewStateCnt = 7; + int32_t i = 1; + jjstateSet[0] = startState; + int32_t kind = 0x7fffffff; + for (;;) + { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) + { + uint64_t l = ((uint64_t)1L) << curChar; + + do + { + switch(jjstateSet[--i]) + { + case 0: + if ((_ILONGLONG(0xfffffffeffffffff) & l) != 0L) + { + if (kind > 28) + kind = 28; + jjCheckNAdd(6); + } + if ((_ILONGLONG(0x100002600) & l) != 0L) + { + if (kind > 6) + kind = 6; + } + else if (curChar == 34) + jjCheckNAddTwoStates(2, 4); + break; + case 1: + if (curChar == 34) + jjCheckNAddTwoStates(2, 4); + break; + case 2: + if ((_ILONGLONG(0xfffffffbffffffff) & l) != 0L) + jjCheckNAddStates(16, 18); + break; + case 3: + if (curChar == 34) + jjCheckNAddStates(16, 18); + break; + case 5: + if (curChar == 34 && kind > 27) + kind = 27; + break; + case 6: + if ((_ILONGLONG(0xfffffffeffffffff) & l) == 0L) + break; + if (kind > 28) + kind = 28; + jjCheckNAdd(6); + break; + default : break; + } + } while(i != startsAt); + } + else if (curChar < 128) + { + uint64_t l = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 0: + case 6: + if ((_ILONGLONG(0xffffffffdfffffff) & l) == 0L) + break; + if (kind > 28) + kind = 28; + jjCheckNAdd(6); + break; + case 2: + jjAddStates(16, 18); + break; + case 4: + if (curChar == 92) + jjstateSet[jjnewStateCnt++] = 3; + break; + default : break; + } + } while(i != startsAt); + } + else + { + int32_t hiByte = (int32_t)(curChar >> 8); + int32_t i1 = hiByte >> 6; + uint64_t l1 = ((uint64_t)1L) << (hiByte & 63); + int32_t i2 = (curChar & 0xff) >> 6; + uint64_t l2 = ((uint64_t)1L) << (curChar & 63); + + do + { + switch(jjstateSet[--i]) + { + case 0: + case 6: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 28) + kind = 28; + jjCheckNAdd(6); + break; + case 2: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjAddStates(16, 18); + break; + default : break; + } + } while(i != startsAt); + } + if (kind != 0x7fffffff) + { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) + return curPos; + try { curChar = input_stream->readChar(); } + catch(CLuceneError& e) { + if (e.number() != CL_ERR_IO) + { + throw e; + } + else + return curPos; + } + } +} + +/*static*/ +bool QueryParserTokenManager::jjCanMove_0(const int32_t hiByte, const int32_t i1, const int32_t i2, const int64_t l1, const int64_t l2) +{ + switch(hiByte) + { + case 0: + return ((jjbitVec2[i2] & l2) != 0L); + default : + if ((jjbitVec0[i1] & l1) != 0L) + return true; + return false; + } +} + +void QueryParserTokenManager::ReInit(CharStream* stream) +{ + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + _CLLDELETE(input_stream); + input_stream = stream; + ReInitRounds(); +} + +void QueryParserTokenManager::ReInitRounds() +{ + jjround = 0x80000001; + for (int32_t i = 36; i-- > 0;) + jjrounds[i] = 0x80000000; +} + +void QueryParserTokenManager::ReInit(CharStream* stream, const int32_t lexState) +{ + ReInit(stream); + SwitchTo(lexState); +} + +void QueryParserTokenManager::SwitchTo(const int32_t lexState) +{ + if (lexState >= 4 || lexState < 0) { + TCHAR err[CL_MAX_PATH]; + // TODO: use TokenMgrError::INVALID_LEXICAL_STATE? + _sntprintf(err,CL_MAX_PATH,_T("Error: Ignoring invalid lexical state : %d. State unchanged."), lexState); + _CLTHROWA(CL_ERR_TokenMgr,err); + } + else + curLexState = lexState; +} + +QueryToken* QueryParserTokenManager::jjFillToken(){ + QueryToken* t = QueryToken::newToken(jjmatchedKind); + t->kind = jjmatchedKind; + const TCHAR* im = jjstrLiteralImages[jjmatchedKind]; + t->image = (im == NULL) ? input_stream->GetImage() : stringDuplicate(im); + t->beginLine = input_stream->getBeginLine(); + t->beginColumn = input_stream->getBeginColumn(); + t->endLine = input_stream->getEndLine(); + t->endColumn = input_stream->getEndColumn(); + return t; +} + +QueryToken* QueryParserTokenManager::getNextToken() { + QueryToken* matchedToken = NULL; + int32_t curPos = 0; + + for (;;) { + try + { + curChar = input_stream->BeginToken(); + } + _CLCATCH_ERR_ELSE(CL_ERR_IO, { /*else*/ + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + }); + + switch(curLexState){ + case 0: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + break; + case 1: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_1(); + break; + case 2: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_2(); + break; + case 3: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_3(); + break; + } + if (jjmatchedKind != 0x7fffffff){ + if (jjmatchedPos + 1 < curPos) + input_stream->backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & ((uint64_t)(1L << (jjmatchedKind & 63)))) != (uint64_t)0L) + { + matchedToken = jjFillToken(); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + return matchedToken; + } + else + { + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + continue; + } + } + int32_t error_line = input_stream->getEndLine(); + int32_t error_column = input_stream->getEndColumn(); + TCHAR* error_after = NULL; + bool EOFSeen = false; + try { input_stream->readChar(); input_stream->backup(1); } + _CLCATCH_ERR_ELSE(CL_ERR_IO, { /*else*/ + EOFSeen = true; + if (curPos <= 1) { + error_after = _CL_NEWARRAY(TCHAR,2); + error_after[0] = _T(' '); + error_after[1] = 0; + } else { + error_after = input_stream->GetImage(); + } + if (curChar == _T('\n') || curChar == _T('\r')) { + error_line++; + error_column = 0; + } + else + error_column++; + }); + if (!EOFSeen) { + input_stream->backup(1); + if (curPos <= 1) { + error_after = _CL_NEWARRAY(TCHAR,2); + error_after[0] = _T(' '); + error_after[1] = 0; + } else { + error_after = input_stream->GetImage(); + } + } + // TODO: TokenMgrError.LEXICAL_ERROR ? + TCHAR* err = getLexicalError(EOFSeen, curLexState, error_line, error_column, error_after, curChar); + _CLDELETE_LCARRAY(error_after); + _CLTHROWT_DEL(CL_ERR_TokenMgr,err); + } +} + +TCHAR* QueryParserTokenManager::getLexicalError(bool EOFSeen, int32_t /*lexState*/, int32_t errorLine, + int32_t errorColumn, TCHAR* errorAfter, TCHAR curChar) +{ + TCHAR* tmp = NULL; + CL_NS(util)::StringBuffer sb(100); + sb.append(_T("Lexical error at line ")); + sb.appendInt(errorLine); + sb.append(_T(", column ")); + sb.appendInt(errorColumn); + sb.append(_T(". Encountered: ")); + if (EOFSeen){ + sb.append(_T(" ")); + }else{ + sb.appendChar(_T('"')); + sb.appendChar(curChar); // TODO: addEscapes ? + sb.appendChar(_T('"')); + sb.append(_T(" (")); + sb.appendInt((int32_t)curChar); + sb.append(_T("), ")); + } + sb.append(_T("after : \"")); + + tmp = addEscapes(errorAfter); + sb.append(tmp); + _CLDELETE_LCARRAY(tmp); + + sb.appendChar(_T('"')); + return sb.giveBuffer(); +} + +CL_NS_END // QueryParserTokenManager diff --git a/src/core/CLucene/queryParser/QueryParserTokenManager.h b/src/core/CLucene/queryParser/QueryParserTokenManager.h new file mode 100644 index 00000000000..834c324711f --- /dev/null +++ b/src/core/CLucene/queryParser/QueryParserTokenManager.h @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_QueryParserTokenManager_ +#define _lucene_queryParser_QueryParserTokenManager_ + +#include "QueryParserConstants.h" + +CL_NS_DEF(queryParser) + +class CharStream; +class QueryToken; + +class CLUCENE_EXPORT QueryParserTokenManager: public virtual QueryParserConstants +{ +public: + // TODO: PrintStream debugStream = System.out; + // TODO: setDebugStream(PrintStream ds) { debugStream = ds; } + +private: + int32_t jjStopStringLiteralDfa_3(const int32_t pos, int64_t active0); + int32_t jjStartNfa_3(int32_t pos, int64_t active0); + int32_t jjStopAtPos(const int32_t pos, const int32_t kind); + + int32_t jjStartNfaWithStates_3(int32_t pos, int32_t kind, int32_t state); + + int32_t jjMoveStringLiteralDfa0_3(); + + void jjCheckNAdd(const int32_t state); + void jjAddStates(int32_t start, const int32_t end); + void jjCheckNAddTwoStates(const int32_t state1, const int32_t state2); + void jjCheckNAddStates(int32_t start, const int32_t end); + void jjCheckNAddStates(const int32_t start); + + static const int64_t jjbitVec0[]; + static const int64_t jjbitVec2[]; + + int32_t jjMoveNfa_3(const int32_t startState, int32_t curPos); + + int32_t jjStopStringLiteralDfa_1(const int32_t pos, const int64_t active0); + + int32_t jjStartNfa_1(int32_t pos, int64_t active0); + + int32_t jjStartNfaWithStates_1(const int32_t pos, const int32_t kind, const int32_t state); + + int32_t jjMoveStringLiteralDfa0_1(); + int32_t jjMoveStringLiteralDfa1_1(int64_t active0); + int32_t jjMoveNfa_1(const int32_t startState, int32_t curPos); + int32_t jjMoveStringLiteralDfa0_0(); + + int32_t jjMoveNfa_0(const int32_t startState, int32_t curPos); + int32_t jjStopStringLiteralDfa_2(const int32_t pos, const int64_t active0); + int32_t jjStartNfa_2(int32_t pos, int64_t active0); + + int32_t jjStartNfaWithStates_2(const int32_t pos, const int32_t kind, const int32_t state); + + int32_t jjMoveStringLiteralDfa0_2(); + int32_t jjMoveStringLiteralDfa1_2(const int64_t active0); + + int32_t jjMoveNfa_2(const int32_t startState, int32_t curPos); + + static const int32_t jjnextStates[]; + + static bool jjCanMove_0(const int32_t hiByte, const int32_t i1, const int32_t i2, const int64_t l1, + const int64_t l2); + +public: + static const TCHAR* jjstrLiteralImages []; + static const TCHAR* lexStateNames []; + static const int32_t jjnewLexState []; + static const int64_t jjtoToken []; + static const int64_t jjtoSkip []; +protected: + CharStream* input_stream; +private: + int32_t jjrounds[36]; + int32_t jjstateSet[72]; +protected: + TCHAR curChar; +public: + QueryParserTokenManager(CharStream* stream, const int32_t lexState = -1); + virtual ~QueryParserTokenManager(); + + void ReInit(CharStream* stream); +private: + void ReInitRounds(); +public: + void ReInit(CharStream* stream, const int32_t lexState); + void SwitchTo(const int32_t lexState); + +protected: + QueryToken* jjFillToken(); + + int32_t curLexState; + int32_t defaultLexState; + int32_t jjnewStateCnt; + uint32_t jjround; + int32_t jjmatchedPos; + int32_t jjmatchedKind; + +public: + QueryToken* getNextToken(); + +private: + static TCHAR* getLexicalError(bool EOFSeen, int32_t lexState, int32_t errorLine, int32_t errorColumn, + TCHAR* errorAfter, TCHAR curChar); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/QueryToken.cpp b/src/core/CLucene/queryParser/QueryToken.cpp new file mode 100644 index 00000000000..d16f1cd3b2f --- /dev/null +++ b/src/core/CLucene/queryParser/QueryToken.cpp @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryToken.h" + +CL_NS_DEF(queryParser) + + +QueryToken::QueryToken() : + kind(0), + beginLine(0), + beginColumn(0), + endLine(0), + endColumn(0), + image(NULL), + next(NULL), + specialToken(NULL) +{ +} + +QueryToken::~QueryToken() +{ +#ifndef LUCENE_TOKEN_WORD_LENGTH + _CLDELETE_LCARRAY( image ); +#endif +} + +TCHAR* QueryToken::toString() const +{ +#ifndef LUCENE_TOKEN_WORD_LENGTH + return image; +#else + return STRDUP_TtoT(image); +#endif +} + +/*static*/ +QueryToken* QueryToken::newToken(const int32_t /*ofKind*/) +{ + //switch(ofKind) + //{ + //default : return _CLNEW Token(); + //} + return _CLNEW QueryToken(); +} + +CL_NS_END diff --git a/src/core/CLucene/queryParser/QueryToken.h b/src/core/CLucene/queryParser/QueryToken.h new file mode 100644 index 00000000000..5e3c91ee876 --- /dev/null +++ b/src/core/CLucene/queryParser/QueryToken.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_Token_ +#define _lucene_queryParser_Token_ + +CL_NS_DEF(queryParser) + +/** + * Describes the input token stream. + */ +class CLUCENE_EXPORT QueryToken{ +public: + QueryToken(); + ~QueryToken(); + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + int32_t kind; + + /** + * beginLine and beginColumn describe the position of the first character + * of this token; endLine and endColumn describe the position of the + * last character of this token. + */ + int32_t beginLine, beginColumn, endLine, endColumn; + + /** + * The string image of the token. + */ + TCHAR* image; + + /* + TODO: If LUCENE_TOKEN_WORD_LENGTH is still necessary, use the #defines below + #ifdef LUCENE_TOKEN_WORD_LENGTH + TCHAR image[LUCENE_TOKEN_WORD_LENGTH+1]; + #else + TCHAR* image; + #endif + */ + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + QueryToken* next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + QueryToken* specialToken; + + /** + * Returns the image. + */ + TCHAR* toString() const; + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simlpy add something like : + * + * case MyParserConstants.ID : return new IDToken(); + * + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use it in your lexical actions. + */ + static QueryToken* newToken(const int32_t ofKind); + +}; +CL_NS_END +#endif + diff --git a/src/core/CLucene/queryParser/_CharStream.h b/src/core/CLucene/queryParser/_CharStream.h new file mode 100644 index 00000000000..74bfbba13fd --- /dev/null +++ b/src/core/CLucene/queryParser/_CharStream.h @@ -0,0 +1,121 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_CharStream_ +#define _lucene_queryParser_CharStream_ + +CL_NS_DEF(queryParser) + +/** + * This interface describes a character stream that maintains line and + * column number positions of the characters. It also has the capability + * to backup the stream to some extent. An implementation of this + * interface is used in the TokenManager implementation generated by + * JavaCCParser. + * + * All the methods except backup can be implemented in any fashion. backup + * needs to be implemented correctly for the correct operation of the lexer. + * Rest of the methods are all used to get information like line number, + * column number and the String that constitutes a token and are not used + * by the lexer. Hence their implementation won't affect the generated lexer's + * operation. + */ +class CharStream :LUCENE_BASE { +public: + /** + * Returns the next character from the selected input. The method + * of selecting the input is the responsibility of the class + * implementing this interface. Can throw any java.io.IOException. + */ + virtual TCHAR readChar() = 0; + + /** + * Returns the column position of the character last read. + * @deprecated + * @see #getEndColumn + */ + virtual int32_t getColumn() const = 0; + + /** + * Returns the line number of the character last read. + * @deprecated + * @see #getEndLine + */ + virtual int32_t getLine() const = 0; + + /** + * Returns the column number of the last character for current token (being + * matched after the last call to BeginTOken). + */ + virtual int32_t getEndColumn() const = 0; + + /** + * Returns the line number of the last character for current token (being + * matched after the last call to BeginTOken). + */ + virtual int32_t getEndLine() const = 0; + + /** + * Returns the column number of the first character for current token (being + * matched after the last call to BeginTOken). + */ + virtual int32_t getBeginColumn() const = 0; + + /** + * Returns the line number of the first character for current token (being + * matched after the last call to BeginTOken). + */ + virtual int32_t getBeginLine() const = 0; + + /** + * Backs up the input stream by amount steps. Lexer calls this method if it + * had already read some characters, but could not use them to match a + * (longer) token. So, they will be used again as the prefix of the next + * token and it is the implemetation's responsibility to do this right. + */ + virtual void backup(const int32_t amount) = 0; + + /** + * Returns the next character that marks the beginning of the next token. + * All characters must remain in the buffer between two successive calls + * to this method to implement backup correctly. + */ + virtual TCHAR BeginToken() = 0; + + /** + * Returns a string made up of characters from the marked token beginning + * to the current buffer position. Implementations have the choice of returning + * anything that they want to. For example, for efficiency, one might decide + * to just return null, which is a valid implementation. + */ + virtual TCHAR* GetImage() = 0; + + /** + * Returns an array of characters that make up the suffix of length 'len' for + * the currently matched token. This is used to build up the matched string + * for use in actions in the case of MORE. A simple and inefficient + * implementation of this is as follows : + * + * { + * String t = GetImage(); + * return t.substring(t.length() - len, t.length()).toCharArray(); + * } + */ + virtual TCHAR* GetSuffix(const int32_t len) = 0; + + /** + * The lexer calls this function to indicate that it is done with the stream + * and hence implementations can free any resources held by this class. + * Again, the body of this function can be just empty and it will not + * affect the lexer's operation. + */ + virtual void Done() = 0; + + //CharStream(){}; + //virtual ~CharStream(){}; +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/_FastCharStream.h b/src/core/CLucene/queryParser/_FastCharStream.h new file mode 100644 index 00000000000..40d9fdc6408 --- /dev/null +++ b/src/core/CLucene/queryParser/_FastCharStream.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_FastCharStream_ +#define _lucene_queryParser_FastCharStream_ + +CL_CLASS_DEF(util,Reader) + +CL_NS_DEF(queryParser) + +class CharStream; + +/** An efficient implementation of JavaCC's CharStream interface.

Note that + * this does not do line-number counting, but instead keeps track of the + * character position of the token in the input, as required by Lucene's {@link + * org.apache.lucene.analysis.Token} API. */ +class FastCharStream : public CharStream { +protected: + TCHAR* buffer; + size_t _bufferSize; // To keep track of the buffer size in memory + + int32_t bufferLength; // end of valid chars + int32_t bufferPosition; // next char to read + + int32_t tokenStart; // offset in buffer + int32_t bufferStart; // position in file of buffer + + CL_NS(util)::Reader* input; // source of chars + bool _ownsReader; // Should we delete the reader once done with it, or in destructor? + + +public: + /** Constructs from a Reader. */ + FastCharStream(CL_NS(util)::Reader* r, bool ownsReader = false); + virtual ~FastCharStream(); + + TCHAR readChar(); + +private: + void refill(); + +public: + void backup(const int32_t amount); + + /*@memory Caller is responsible for deleting the returned string */ + TCHAR* GetImage(); + + /*@memory Caller is responsible for deleting the returned string */ + TCHAR* GetSuffix(const int32_t len); + + void Done(); + + TCHAR BeginToken(); + + int32_t getColumn() const; + int32_t getLine() const; + int32_t getEndColumn() const; + int32_t getEndLine() const; + int32_t getBeginColumn() const; + int32_t getBeginLine() const; +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/queryParser/legacy/Lexer.cpp b/src/core/CLucene/queryParser/legacy/Lexer.cpp new file mode 100644 index 00000000000..3c8dceca336 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/Lexer.cpp @@ -0,0 +1,371 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryParser.h" +#include "_TokenList.h" +#include "QueryToken.h" +#include "_Lexer.h" + +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/_FastCharStream.h" + +CL_NS_USE(util) + +CL_NS_DEF2(queryParser,legacy) +Lexer::Lexer(QueryParserBase* queryparser, const TCHAR* query) { + //Func - Constructor + //Pre - query != NULL and contains the query string + //Post - An instance of Lexer has been created + + this->queryparser = queryparser; + + CND_PRECONDITION(query != NULL, "query is NULL"); + + //The InputStream of Reader must be destroyed in the destructor + delSR = true; + + StringReader *r = _CLNEW StringReader(query); + + //Check to see if r has been created properly + CND_CONDITION(r != NULL, "Could not allocate memory for StringReader r"); + + //Instantie a FastCharStream instance using r and assign it to reader + reader = _CLNEW FastCharStream(r); + + //Check to see if reader has been created properly + CND_CONDITION(reader != NULL, "Could not allocate memory for FastCharStream reader"); + + //The InputStream of Reader must be destroyed in the destructor + delSR = true; + +} + + +Lexer::Lexer(QueryParserBase* queryparser, BufferedReader* source) { + //Func - Constructor + // Initializes a new instance of the Lexer class with the specified + // TextReader to lex. + //Pre - Source contains a valid reference to a Reader + //Post - An instance of Lexer has been created using source as the reader + + this->queryparser = queryparser; + + //Instantie a FastCharStream instance using r and assign it to reader + reader = _CLNEW FastCharStream(source); + + //Check to see if reader has been created properly + CND_CONDITION(reader != NULL, "Could not allocate memory for FastCharStream reader"); + + //The InputStream of Reader must not be destroyed in the destructor + delSR = false; +} + + +Lexer::~Lexer() { + //Func - Destructor + //Pre - true + //Post - if delSR was true the InputStream input of reader has been deleted + // The instance of Lexer has been destroyed + + if (delSR) { + _CLDELETE(reader->input); + } + + _CLDELETE(reader); +} + + +void Lexer::Lex(TokenList *tokenList) { + //Func - Breaks the input stream onto the tokens list tokens + //Pre - tokens != NULL and contains a TokenList in which the tokens can be stored + //Post - The tokens have been added to the TokenList tokens + + CND_PRECONDITION(tokenList != NULL, "tokens is NULL"); + + //Get all the tokens + while(true) { + //Add the token to the tokens list + + //Get the next token + QueryToken* token = _CLNEW QueryToken; + if ( !GetNextToken(token) ){ + _CLDELETE(token); + break; + } + tokenList->add(token); + } + + //The end has been reached so create an EOF_ token + //Add the final token to the TokenList _tokens + tokenList->add(_CLNEW QueryToken( QueryToken::EOF_)); +} + + +bool Lexer::GetNextToken(QueryToken* token) { + while(!reader->Eos()) { + int ch = reader->GetNext(); + + if ( ch == -1 ) + break; + + // skipping whitespaces + if( _istspace(ch)!=0 ) { + continue; + } + TCHAR buf[2] = {ch,'\0'}; + switch(ch) { + case '+': + token->set(buf, QueryToken::PLUS); + return true; + case '-': + token->set(buf, QueryToken::MINUS); + return true; + case '(': + token->set(buf, QueryToken::LPAREN); + return true; + case ')': + token->set(buf, QueryToken::RPAREN); + return true; + case ':': + token->set(buf, QueryToken::COLON); + return true; + case '!': + token->set(buf, QueryToken::NOT); + return true; + case '^': + token->set(buf, QueryToken::CARAT); + return true; + case '~': + if( _istdigit( reader->Peek() )!=0 ) { + TCHAR number[LUCENE_MAX_FIELD_LEN]; + ReadIntegerNumber(ch, number,LUCENE_MAX_FIELD_LEN); + token->set(number, QueryToken::SLOP); + return true; + }else{ + token->set(buf, QueryToken::FUZZY); + return true; + } + break; + case '"': + return ReadQuoted(ch, token); + case '[': + return ReadInclusiveRange(ch, token); + case '{': + return ReadExclusiveRange(ch, token); + case ']': + case '}': + case '*': + queryparser->throwParserException( _T("Unrecognized char %d at %d::%d."), + ch, reader->Column(), reader->Line() ); + return false; + default: + return ReadTerm(ch, token); + + // end of swith + } + + } + return false; +} + + +void Lexer::ReadIntegerNumber(const TCHAR ch, TCHAR* buf, int buflen) { + int bp=0; + buf[bp++] = ch; + + int c = reader->Peek(); + while( c!=-1 && _istdigit(c)!=0 && bpGetNext(); + c = reader->Peek(); + } + buf[bp++] = 0; +} + + +bool Lexer::ReadInclusiveRange(const TCHAR prev, QueryToken* token) { + int ch = prev; + StringBuffer range; + range.appendChar(ch); + + while(!reader->Eos()) { + ch = reader->GetNext(); + if ( ch == -1 ) + break; + range.appendChar(ch); + + if(ch == ']'){ + token->set(range.getBuffer(), QueryToken::RANGEIN); + return true; + } + } + queryparser->throwParserException(_T("Unterminated inclusive range! %d %d::%d"),' ', + reader->Column(),reader->Column()); + return false; +} + + +bool Lexer::ReadExclusiveRange(const TCHAR prev, QueryToken* token) { + int ch = prev; + StringBuffer range; + range.appendChar(ch); + + while(!reader->Eos()) { + ch = reader->GetNext(); + + if (ch==-1) + break; + range.appendChar(ch); + + if(ch == '}'){ + token->set(range.getBuffer(), QueryToken::RANGEEX); + return true; + } + } + queryparser->throwParserException(_T("Unterminated exclusive range! %d %d::%d"),' ', + reader->Column(),reader->Column() ); + return false; +} + +bool Lexer::ReadQuoted(const TCHAR prev, QueryToken* token) { + int ch = prev; + StringBuffer quoted; + quoted.appendChar(ch); + + while(!reader->Eos()) { + ch = reader->GetNext(); + + if (ch==-1) + break; + + quoted.appendChar(ch); + + if(ch == '"'){ + token->set(quoted.getBuffer(), QueryToken::QUOTED); + return true; + } + } + queryparser->throwParserException(_T("Unterminated string! %d %d::%d"),' ', + reader->Column(),reader->Column()); + return false; +} + + +bool Lexer::ReadTerm(const TCHAR prev, QueryToken* token) { + int ch = prev; + bool completed = false; + int32_t asteriskCount = 0; + bool hasQuestion = false; + + StringBuffer val; + TCHAR buf[3]; //used for readescaped + + while(true) { + switch(ch) { + case -1: + break; + case '\\': + { + if ( ReadEscape(ch, buf) ) + val.append( buf ); + else + return false; + } + break; + + case LUCENE_WILDCARDTERMENUM_WILDCARD_STRING: + asteriskCount++; + val.appendChar(ch); + break; + case LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR: + hasQuestion = true; + val.appendChar(ch); + break; + case '\n': + case '\t': + case ' ': + case '+': + case '-': + case '!': + case '(': + case ')': + case ':': + case '^': + case '[': + case ']': + case '{': + case '}': + case '~': + case '"': + // create new QueryToken + reader->UnGet(); + completed = true; + break; + default: + val.appendChar(ch); + break; + // end of switch + } + + if(completed || ch==-1 || reader->Eos() ) + break; + else + ch = reader->GetNext(); + } + + // create new QueryToken + if(hasQuestion) + token->set(val.getBuffer(), QueryToken::WILDTERM); + else if(asteriskCount == 1 && val.getBuffer()[val.length() - 1] == '*') + token->set(val.getBuffer(), QueryToken::PREFIXTERM); + else if(asteriskCount > 0) + token->set(val.getBuffer(), QueryToken::WILDTERM); + else if( _tcsicmp(val.getBuffer(), _T("AND"))==0 || _tcscmp(val.getBuffer(), _T("&&"))==0 ) + token->set(val.getBuffer(), QueryToken::AND_); + else if( _tcsicmp(val.getBuffer(), _T("OR"))==0 || _tcscmp(val.getBuffer(), _T("||"))==0) + token->set(val.getBuffer(), QueryToken::OR); + else if( _tcsicmp(val.getBuffer(), _T("NOT"))==0 ) + token->set(val.getBuffer(), QueryToken::NOT); + else { + bool isnum = true; + int32_t nlen=val.length(); + for (int32_t i=0;iset(val.getBuffer(), QueryToken::NUMBER); + else + token->set(val.getBuffer(), QueryToken::TERM); + } + return true; +} + + +bool Lexer::ReadEscape(TCHAR prev, TCHAR* buf) { + TCHAR ch = prev; + int bp=0; + buf[bp++] = ch; + + ch = reader->GetNext(); + int32_t idx = _tcscspn( buf, _T("\\+-!():^[]{}\"~*") ); + if(idx == 0) { + buf[bp++] = ch; + buf[bp++]=0; + return true; + } + queryparser->throwParserException(_T("Unrecognized escape sequence at %d %d::%d"), ' ', + reader->Column(),reader->Line()); + return false; +} + + +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.cpp b/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.cpp new file mode 100644 index 00000000000..fd8478784e9 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.cpp @@ -0,0 +1,216 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultiFieldQueryParser.h" +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/search/BooleanQuery.h" +#include "CLucene/search/BooleanClause.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/search/SearchHeader.h" +#include "QueryParser.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(search) +CL_NS_USE(analysis) + +CL_NS_DEF2(queryParser,legacy) + +MultiFieldQueryParser::MultiFieldQueryParser(const TCHAR** fields, CL_NS(analysis)::Analyzer* a, BoostMap* boosts): + QueryParser(NULL,a) +{ + this->fields = fields; + this->boosts = boosts; +} +MultiFieldQueryParser::~MultiFieldQueryParser(){ +} + +//static +Query* MultiFieldQueryParser::parse(const TCHAR* query, const TCHAR** fields, Analyzer* analyzer) +{ + BooleanQuery* bQuery = _CLNEW BooleanQuery( true ); + int32_t i = 0; + while ( fields[i] != NULL ){ + Query* q = QueryParser::parse(query, fields[i], analyzer); + if (q && ( !q->instanceOf(BooleanQuery::getClassName()) || ((BooleanQuery*)q)->getClauseCount() > 0)) { + //todo: Move to using BooleanClause::Occur + bQuery->add(q, true, false, false); + } else { + _CLDELETE(q); + } + + i++; + } + return bQuery; +} + +//static +Query* MultiFieldQueryParser::parse(const TCHAR* query, const TCHAR** fields, const uint8_t* flags, Analyzer* analyzer) +{ + BooleanQuery* bQuery = _CLNEW BooleanQuery( true ); + int32_t i = 0; + while ( fields[i] != NULL ) + { + Query* q = QueryParser::parse(query, fields[i], analyzer); + if (q && ( !q->instanceOf(BooleanQuery::getClassName()) || ((BooleanQuery*)q)->getClauseCount() > 0)) { + uint8_t flag = flags[i]; + switch (flag) + { + //todo: Move to using BooleanClause::Occur + case MultiFieldQueryParser::REQUIRED_FIELD: + bQuery->add(q, true, true, false); + break; + case MultiFieldQueryParser::PROHIBITED_FIELD: + bQuery->add(q, true, false, true); + break; + default: + bQuery->add(q, true, false, false); + break; + } + } else { + _CLDELETE(q); + } + + i++; + } + return bQuery; +} + +//not static +CL_NS(search)::Query* MultiFieldQueryParser::parse(const TCHAR* query) { + return parse(query, this->fields, this->analyzer); +} + +Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::GetFieldQuery(fields[i], queryText); + if (q != NULL) { + //If the user passes a map of boosts + if (boosts != NULL) { + //Get the boost from the map and apply them + BoostMap::iterator itr = boosts->find( fields[i]); + if (itr != boosts->end()) { + q->setBoost(itr->second); + } + } + if (q->instanceOf(PhraseQuery::getClassName()) ) { + ((PhraseQuery*)q)->setSlop(slop); + } + //if (q instanceof MultiPhraseQuery) { + // ((MultiPhraseQuery) q).setSlop(slop); + //} + q = QueryAddedCallback(fields[i], q); + if ( q ) + clauses.push_back(_CLNEW BooleanClause(q, true, false,false)); + } + } + if (clauses.size() == 0) // happens for stopwords + return NULL; + Query* q = QueryParser::GetBooleanQuery(clauses); + return q; + }else{ + Query* q = QueryParser::GetFieldQuery(field, queryText); + if ( q ) + q = QueryAddedCallback(field,q); + return q; + } +} + + +Query* MultiFieldQueryParser::GetFieldQuery(const TCHAR* field, TCHAR* queryText){ + return GetFieldQuery(field, queryText, 0); +} + + +CL_NS(search)::Query* MultiFieldQueryParser::GetFuzzyQuery(const TCHAR* field, TCHAR* termStr){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::GetFuzzyQuery(fields[i], termStr); //todo: , minSimilarity + if ( q ){ + q = QueryAddedCallback(fields[i], q); + if ( q ){ + clauses.push_back(_CLNEW BooleanClause(q,true,false,false) ); + } + } + } + return QueryParser::GetBooleanQuery(clauses); + }else{ + Query* q = QueryParser::GetFuzzyQuery(field, termStr);//todo: , minSimilarity + if ( q ) + q = QueryAddedCallback(field,q); + return q; + } +} + +Query* MultiFieldQueryParser::GetPrefixQuery(const TCHAR* field, TCHAR* termStr){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::GetPrefixQuery(fields[i], termStr); + if ( q ){ + q = QueryAddedCallback(fields[i],q); + if ( q ){ + clauses.push_back(_CLNEW BooleanClause(q,true,false,false)); + } + } + } + return QueryParser::GetBooleanQuery(clauses); + }else{ + Query* q = QueryParser::GetPrefixQuery(field, termStr); + if ( q ) + q = QueryAddedCallback(field,q); + return q; + } +} + +Query* MultiFieldQueryParser::GetWildcardQuery(const TCHAR* field, TCHAR* termStr){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::GetWildcardQuery(fields[i], termStr); + if ( q ){ + q = QueryAddedCallback(fields[i],q); + if ( q ){ + clauses.push_back(_CLNEW BooleanClause(q,true,false,false)); + } + } + } + return QueryParser::GetBooleanQuery(clauses); + }else{ + Query* q = QueryParser::GetWildcardQuery(field, termStr); + if ( q ) + q = QueryAddedCallback(field,q); + return q; + } +} + + +Query* MultiFieldQueryParser::GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive){ + if (field == NULL) { + vector clauses; + for (int i = 0; fields[i]!=NULL; ++i) { + Query* q = QueryParser::GetRangeQuery(fields[i], part1, part2, inclusive); + if ( q ){ + q = QueryAddedCallback(fields[i],q); + if ( q ){ + clauses.push_back(_CLNEW BooleanClause(q,true,false,false)); + } + } + } + return QueryParser::GetBooleanQuery(clauses); + }else{ + Query* q = QueryParser::GetRangeQuery(field, part1, part2, inclusive); + if ( q ) + q = QueryAddedCallback(field,q); + return q; + } +} + +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.h b/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.h new file mode 100644 index 00000000000..304c6f7a1f4 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/MultiFieldQueryParser.h @@ -0,0 +1,131 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_legacy_MultiFieldQueryParser +#define _lucene_queryParser_legacy_MultiFieldQueryParser + +#include "QueryParser.h" +#include "CLucene/util/VoidMap.h" + +CL_NS_DEF2(queryParser,legacy) + + typedef CL_NS(util)::CLHashMap BoostMap; + + /** + * A QueryParser which constructs queries to search multiple fields. + * + */ + class CLUCENE_EXPORT MultiFieldQueryParser: public QueryParser + { + protected: + const TCHAR** fields; + BoostMap* boosts; + public: + LUCENE_STATIC_CONSTANT(uint8_t, NORMAL_FIELD=0); + LUCENE_STATIC_CONSTANT(uint8_t, REQUIRED_FIELD=1); + LUCENE_STATIC_CONSTANT(uint8_t, PROHIBITED_FIELD=2); + + /** + * Creates a MultiFieldQueryParser. + * + *

It will, when parse(String query) + * is called, construct a query like this (assuming the query consists of + * two terms and you specify the two fields title and body):

+ * + * + * (title:term1 body:term1) (title:term2 body:term2) + * + * + *

When setDefaultOperator(AND_OPERATOR) is set, the result will be:

+ * + * + * +(title:term1 body:term1) +(title:term2 body:term2) + * + * + *

In other words, all the query's terms must appear, but it doesn't matter in + * what fields they appear.

+ */ + MultiFieldQueryParser(const TCHAR** fields, CL_NS(analysis)::Analyzer* a, BoostMap* boosts = NULL); + virtual ~MultiFieldQueryParser(); + + /** + *

+ * Parses a query which searches on the fields specified. + *

+ * If x fields are specified, this effectively constructs: + *

+     * 
+     * (field1:query) (field2:query) (field3:query)...(fieldx:query)
+     * 
+     * 
+ * + * @param query Query string to parse + * @param fields Fields to search on + * @param analyzer Analyzer to use + * @throws ParserException if query parsing fails + * @throws TokenMgrError if query parsing fails + */ + static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR** fields, CL_NS(analysis)::Analyzer* analyzer); + + /** + *

+ * Parses a query, searching on the fields specified. + * Use this if you need to specify certain fields as required, + * and others as prohibited. + *

+     * Usage:
+     * 
+     * TCHAR** fields = {"filename", "contents", "description"};
+     * int8_t* flags = {MultiFieldQueryParser::NORMAL FIELD,
+     *                MultiFieldQueryParser::REQUIRED FIELD,
+     *                MultiFieldQueryParser::PROHIBITED FIELD};
+     * parse(query, fields, flags, analyzer);
+     * 
+     * 
+ *

+ * The code above would construct a query: + *

+     * 
+     * (filename:query) +(contents:query) -(description:query)
+     * 
+     * 
+ * + * @param query Query string to parse + * @param fields Fields to search on + * @param flags Flags describing the fields + * @param analyzer Analyzer to use + * @throws ParserException if query parsing fails + * @throws TokenMgrError if query parsing fails + */ + static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR** fields, const uint8_t* flags, CL_NS(analysis)::Analyzer* analyzer); + + // non-static version of the above + CL_NS(search)::Query* parse(const TCHAR* query); + + protected: + CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText); + CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop); + CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field, TCHAR* termStr); + CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive); + CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field, TCHAR* termStr); + CL_NS(search)::Query* GetWildcardQuery(const TCHAR* field, TCHAR* termStr); + + /** + * A special virtual function for the MultiFieldQueryParser which can be used + * to clean up queries. Once the field name is known and the query has been + * created, its passed to this function. + * An example of this usage is to set boosts. + */ + virtual CL_NS(search)::Query* QueryAddedCallback(const TCHAR* field, CL_NS(search)::Query* query){ return query; } + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/queryParser/legacy/QueryParser.cpp b/src/core/CLucene/queryParser/legacy/QueryParser.cpp new file mode 100644 index 00000000000..263e58e7dad --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/QueryParser.cpp @@ -0,0 +1,507 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryParser.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/BooleanClause.h" +#include "CLucene/search/Query.h" +#include "CLucene/index/Term.h" +#include "QueryToken.h" + +#include "_TokenList.h" +#include "_Lexer.h" + +CL_NS_USE(util) +CL_NS_USE(index) +CL_NS_USE(analysis) +CL_NS_USE(search) + +CL_NS_DEF2(queryParser,legacy) + + QueryParser::QueryParser(const TCHAR* _field, Analyzer* _analyzer) : QueryParserBase(_analyzer){ + //Func - Constructor. + // Instantiates a QueryParser for the named field _field + //Pre - _field != NULL + //Post - An instance has been created + + if ( _field ) + field = STRDUP_TtoT(_field); + else + field = NULL; + tokens = NULL; + lowercaseExpandedTerms = true; + } + + QueryParser::~QueryParser() { + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLDELETE_CARRAY(field); + } + + //static + Query* QueryParser::parse(const TCHAR* query, const TCHAR* field, Analyzer* analyzer){ + //Func - Returns a new instance of the Query class with a specified query, field and + // analyzer values. + //Pre - query != NULL and holds the query to parse + // field != NULL and holds the default field for query terms + // analyzer holds a valid reference to an Analyzer and is used to + // find terms in the query text + //Post - query has been parsed and an instance of Query has been returned + + CND_PRECONDITION(query != NULL, "query is NULL"); + CND_PRECONDITION(field != NULL, "field is NULL"); + + QueryParser parser(field, analyzer); + return parser.parse(query); + } + + Query* QueryParser::parse(const TCHAR* query){ + //Func - Returns a parsed Query instance + //Pre - query != NULL and contains the query value to be parsed + //Post - Returns a parsed Query Instance + + CND_PRECONDITION(query != NULL, "query is NULL"); + + //Instantie a Stringer that can read the query string + BufferedReader* r = _CLNEW StringReader(query); + + //Check to see if r has been created properly + CND_CONDITION(r != NULL, "Could not allocate memory for StringReader r"); + + //Pointer for the return value + Query* ret = NULL; + + try{ + //Parse the query managed by the StringReader R and return a parsed Query instance + //into ret + ret = parse(r); + }_CLFINALLY ( + _CLDELETE(r); + ); + + return ret; + } + + Query* QueryParser::parse(BufferedReader* reader){ + //Func - Returns a parsed Query instance + //Pre - reader contains a valid reference to a Reader and manages the query string + //Post - A parsed Query instance has been returned or + + //instantiate the TokenList tokens + TokenList _tokens; + this->tokens = &_tokens; + + //Instantiate a lexer + Lexer lexer(this, reader); + + //tokens = lexer.Lex(); + //Lex the tokens + lexer.Lex(tokens); + + //Peek to the first token and check if is an EOF + if (tokens->peek()->Type == QueryToken::EOF_){ + // The query string failed to yield any tokens. We discard the + // TokenList tokens and raise an exceptioin. + QueryToken* token = this->tokens->extract(); + _CLDELETE(token); + _CLTHROWA(CL_ERR_Parse, "No query given."); + } + + //Return the parsed Query instance + Query* ret = MatchQuery(field); + this->tokens = NULL; + return ret; + } + + int32_t QueryParser::MatchConjunction(){ + //Func - matches for CONJUNCTION + // CONJUNCTION ::= | + //Pre - tokens != NULL + //Post - if the first token is an AND or an OR then + // the token is extracted and deleted and CONJ_AND or CONJ_OR is returned + // otherwise CONJ_NONE is returned + + CND_PRECONDITION(tokens != NULL, "tokens is NULL"); + + switch(tokens->peek()->Type){ + case QueryToken::AND_ : + //Delete the first token of tokenlist + ExtractAndDeleteToken(); + return CONJ_AND; + case QueryToken::OR : + //Delete the first token of tokenlist + ExtractAndDeleteToken(); + return CONJ_OR; + default : + return CONJ_NONE; + } + } + + int32_t QueryParser::MatchModifier(){ + //Func - matches for MODIFIER + // MODIFIER ::= | | + //Pre - tokens != NULL + //Post - if the first token is a PLUS the token is extracted and deleted and MOD_REQ is returned + // if the first token is a MINUS or NOT the token is extracted and deleted and MOD_NOT is returned + // otherwise MOD_NONE is returned + CND_PRECONDITION(tokens != NULL, "tokens is NULL"); + + switch(tokens->peek()->Type){ + case QueryToken::PLUS : + //Delete the first token of tokenlist + ExtractAndDeleteToken(); + return MOD_REQ; + case QueryToken::MINUS : + case QueryToken::NOT : + //Delete the first token of tokenlist + ExtractAndDeleteToken(); + return MOD_NOT; + default : + return MOD_NONE; + } + } + + Query* QueryParser::MatchQuery(const TCHAR* field){ + //Func - matches for QUERY + // QUERY ::= [MODIFIER] QueryParser::CLAUSE ( [MODIFIER] CLAUSE)* + //Pre - field != NULL + //Post - + + CND_PRECONDITION(tokens != NULL, "tokens is NULL"); + + vector clauses; + + Query* q = NULL; + + int32_t mods = MOD_NONE; + int32_t conj = CONJ_NONE; + + //match for MODIFIER + mods = MatchModifier(); + + //match for CLAUSE + q = MatchClause(field); + AddClause(clauses, CONJ_NONE, mods, q); + + // match for CLAUSE* + while(true){ + QueryToken* p = tokens->peek(); + if(p->Type == QueryToken::EOF_){ + QueryToken* qt = MatchQueryToken(QueryToken::EOF_); + _CLDELETE(qt); + break; + } + + if(p->Type == QueryToken::RPAREN){ + //MatchQueryToken(QueryToken::RPAREN); + break; + } + + //match for a conjuction (AND OR NOT) + conj = MatchConjunction(); + //match for a modifier + mods = MatchModifier(); + + q = MatchClause(field); + if ( q != NULL ) + AddClause(clauses, conj, mods, q); + } + + // finalize query + if(clauses.size() == 1){ //bvk: removed this && firstQuery != NULL + BooleanClause* c = clauses[0]; + Query* q = c->getQuery(); + + //Condition check to be sure clauses[0] is valid + CND_CONDITION(c != NULL, "c is NULL"); + + //Tell the boolean clause not to delete its query + c->deleteQuery=false; + //Clear the clauses list + clauses.clear(); + _CLDELETE(c); + + return q; + }else{ + return GetBooleanQuery(clauses); + } + } + + Query* QueryParser::MatchClause(const TCHAR* field){ + //Func - matches for CLAUSE + // CLAUSE ::= [TERM ] ( TERM | ( QUERY )) + //Pre - field != NULL + //Post - + + Query* q = NULL; + const TCHAR* sfield = field; + TCHAR* tmp = NULL; + + QueryToken *DelToken = NULL; + + //match for [TERM ] + QueryToken* term = tokens->extract(); + if(term->Type == QueryToken::TERM && tokens->peek()->Type == QueryToken::COLON){ + DelToken = MatchQueryToken(QueryToken::COLON); + + CND_CONDITION(DelToken != NULL,"DelToken is NULL"); + _CLDELETE(DelToken); + + tmp = STRDUP_TtoT(term->Value); + discardEscapeChar(tmp); + sfield = tmp; + _CLDELETE(term); + }else{ + tokens->push(term); + term = NULL; + } + + // match for + // TERM | ( QUERY ) + if(tokens->peek()->Type == QueryToken::LPAREN){ + DelToken = MatchQueryToken(QueryToken::LPAREN); + + CND_CONDITION(DelToken != NULL,"DelToken is NULL"); + _CLDELETE(DelToken); + + q = MatchQuery(sfield); + //DSR:2004.11.01: + //If exception is thrown while trying to match trailing parenthesis, + //need to prevent q from leaking. + + try{ + DelToken = MatchQueryToken(QueryToken::RPAREN); + + CND_CONDITION(DelToken != NULL,"DelToken is NULL"); + _CLDELETE(DelToken); + + }catch(...) { + _CLDELETE(q); + throw; + } + }else{ + q = MatchTerm(sfield); + } + + _CLDELETE_CARRAY(tmp); + return q; + } + + + Query* QueryParser::MatchTerm(const TCHAR* field){ + //Func - matches for TERM + // TERM ::= TERM | PREFIXTERM | WILDTERM | NUMBER + // [ ] [ []] + // | ( | ) [ ] + // | [SLOP] [ ] + //Pre - field != NULL + //Post - + + QueryToken* term = NULL; + QueryToken* slop = NULL; + QueryToken* boost = NULL; + + bool prefix = false; + bool wildcard = false; + bool fuzzy = false; + bool rangein = false; + Query* q = NULL; + + term = tokens->extract(); + QueryToken* DelToken = NULL; //Token that is about to be deleted + + switch(term->Type){ + case QueryToken::TERM: + case QueryToken::NUMBER: + case QueryToken::PREFIXTERM: + case QueryToken::WILDTERM: + { //start case + //Check if type of QueryToken term is a prefix term + if(term->Type == QueryToken::PREFIXTERM){ + prefix = true; + } + //Check if type of QueryToken term is a wildcard term + if(term->Type == QueryToken::WILDTERM){ + wildcard = true; + } + //Peek to see if the type of the next token is fuzzy term + if(tokens->peek()->Type == QueryToken::FUZZY){ + DelToken = MatchQueryToken(QueryToken::FUZZY); + + CND_CONDITION(DelToken !=NULL, "DelToken is NULL"); + _CLDELETE(DelToken); + + fuzzy = true; + } + if(tokens->peek()->Type == QueryToken::CARAT){ + DelToken = MatchQueryToken(QueryToken::CARAT); + + CND_CONDITION(DelToken !=NULL, "DelToken is NULL"); + _CLDELETE(DelToken); + + boost = MatchQueryToken(QueryToken::NUMBER); + + if(tokens->peek()->Type == QueryToken::FUZZY){ + DelToken = MatchQueryToken(QueryToken::FUZZY); + + CND_CONDITION(DelToken !=NULL, "DelToken is NULL"); + _CLDELETE(DelToken); + + fuzzy = true; + } + } //end if type==CARAT + + discardEscapeChar(term->Value); //clean up + if(wildcard){ + q = GetWildcardQuery(field,term->Value); + break; + }else if(prefix){ + //Create a PrefixQuery + term->Value[_tcslen(term->Value)-1] = 0; //discard the * + q = GetPrefixQuery(field,term->Value); + break; + }else if(fuzzy){ + //Create a FuzzyQuery + + //Check if the last char is a ~ + if(term->Value[_tcslen(term->Value)-1] == '~'){ + //remove the ~ + term->Value[_tcslen(term->Value)-1] = '\0'; + } + + q = GetFuzzyQuery(field,term->Value); + break; + }else{ + q = GetFieldQuery(field, term->Value); + break; + } + } + + + case QueryToken::RANGEIN: + case QueryToken::RANGEEX:{ + if(term->Type == QueryToken::RANGEIN){ + rangein = true; + } + + if(tokens->peek()->Type == QueryToken::CARAT){ + DelToken = MatchQueryToken(QueryToken::CARAT); + + CND_CONDITION(DelToken !=NULL, "DelToken is NULL"); + _CLDELETE(DelToken); + + boost = MatchQueryToken(QueryToken::NUMBER); + } + + TCHAR* noBrackets = term->Value + 1; + noBrackets[_tcslen(noBrackets)-1] = 0; + q = ParseRangeQuery(field, noBrackets, rangein); + break; + } + + + case QueryToken::QUOTED:{ + if(tokens->peek()->Type == QueryToken::SLOP){ + slop = MatchQueryToken(QueryToken::SLOP); + } + + if(tokens->peek()->Type == QueryToken::CARAT){ + DelToken = MatchQueryToken(QueryToken::CARAT); + + CND_CONDITION(DelToken !=NULL, "DelToken is NULL"); + _CLDELETE(DelToken); + + boost = MatchQueryToken(QueryToken::NUMBER); + } + + //remove the quotes + TCHAR* quotedValue = term->Value+1; + quotedValue[_tcslen(quotedValue)-1] = '\0'; + + int32_t islop = phraseSlop; + if(slop != NULL ){ + try { + islop = _ttoi(slop->Value+1); + }catch(...){ + //ignored + } + } + + q = GetFieldQuery(field, quotedValue, islop); + _CLDELETE(slop); + } + + default: + break; + } // end of switch + + _CLDELETE(term); + + + if( q!=NULL && boost != NULL ){ + float_t f = 1.0F; + try { + f = _tcstod(boost->Value, NULL); + }catch(...){ + //ignored + } + _CLDELETE(boost); + + q->setBoost( f); + } + + return q; + } + + QueryToken* QueryParser::MatchQueryToken(QueryToken::Types expectedType){ + //Func - matches for QueryToken of the specified type and returns it + // otherwise Exception throws + //Pre - tokens != NULL + //Post - + + CND_PRECONDITION(tokens != NULL,"tokens is NULL"); + + if(tokens->count() == 0){ + throwParserException(_T("Error: Unexpected end of program"),' ',0,0); + } + + //Extract a token form the TokenList tokens + QueryToken* t = tokens->extract(); + //Check if the type of the token t matches the expectedType + if (expectedType != t->Type){ + TCHAR buf[200]; + _sntprintf(buf,200,_T("Error: Unexpected QueryToken: %d, expected: %d"),t->Type,expectedType); + _CLDELETE(t); + throwParserException(buf,' ',0,0); + } + + //Return the matched token + return t; + } + + void QueryParser::ExtractAndDeleteToken(void){ + //Func - Extracts the first token from the Tokenlist tokenlist + // and destroys it + //Pre - true + //Post - The first token has been extracted and destroyed + + CND_PRECONDITION(tokens != NULL, "tokens is NULL"); + + //Extract the token from the TokenList tokens + QueryToken* t = tokens->extract(); + //Condition Check Token may not be NULL + CND_CONDITION(t != NULL, "Token is NULL"); + //Delete Token + _CLDELETE(t); + } + +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/QueryParser.h b/src/core/CLucene/queryParser/legacy/QueryParser.h new file mode 100644 index 00000000000..f1f50ab6696 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/QueryParser.h @@ -0,0 +1,336 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_legacy_QueryParser_ +#define _lucene_queryParser_legacy_QueryParser_ + + +//#include "CLucene/analysis/AnalysisHeader.h" +CL_CLASS_DEF(util,BufferedReader) +//#include "CLucene/search/SearchHeader.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(analysis,Analyzer) +CL_CLASS_DEF(search,Query) +CL_CLASS_DEF(search,BooleanClause) +CL_CLASS_DEF2(queryParser,legacy,TokenList) + +#include + +//#include "TokenList.h" +#include "QueryToken.h" +//#include "QueryParserBase.h" +//#include "Lexer.h" + +CL_NS_DEF2(queryParser,legacy) + + +/** +* Contains default implementations used by QueryParser. +* You can override any of these to provide a customised QueryParser. +*/ +class CLUCENE_EXPORT QueryParserBase:LUCENE_BASE +{ +protected: + /* The actual operator the parser uses to combine query terms */ + int defaultOperator; + int32_t phraseSlop; + + bool lowercaseExpandedTerms; + + LUCENE_STATIC_CONSTANT(int, CONJ_NONE=0); + LUCENE_STATIC_CONSTANT(int, CONJ_AND=1); + LUCENE_STATIC_CONSTANT(int, CONJ_OR=2); + + LUCENE_STATIC_CONSTANT(int, MOD_NONE=0); + LUCENE_STATIC_CONSTANT(int, MOD_NOT=10); + LUCENE_STATIC_CONSTANT(int, MOD_REQ=11); + + CL_NS(analysis)::Analyzer* analyzer; + +public: + QueryParserBase(CL_NS(analysis)::Analyzer* analyzer); + virtual ~QueryParserBase(); + + /** + * Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically + * lower-cased or not. Default is true. + */ + void setLowercaseExpandedTerms(bool lowercaseExpandedTerms); + + /** + * @see #setLowercaseExpandedTerms(boolean) + */ + bool getLowercaseExpandedTerms() const; + + //values used for setOperator + LUCENE_STATIC_CONSTANT(int, OR_OPERATOR=0); + LUCENE_STATIC_CONSTANT(int, AND_OPERATOR=1); + + /** + * Sets the boolean operator of the QueryParser. + * In default mode (OR_OPERATOR) terms without any modifiers + * are considered optional: for example capital of Hungary is equal to + * capital OR of OR Hungary.
+ * In AND_OPERATOR mode terms are considered to be in conjuction: the + * above mentioned query is parsed as capital AND of AND Hungary + */ + void setDefaultOperator(int oper); + /** + * Gets implicit operator setting, which will be either AND_OPERATOR + * or OR_OPERATOR. + */ + int getDefaultOperator() const; + + //public so that the lexer can call this + virtual void throwParserException(const TCHAR* message, TCHAR ch, int32_t col, int32_t line ); + + /** + * Sets the default slop for phrases. If zero, then exact phrase matches + * are required. Default value is zero. + */ + void setPhraseSlop(int phraseSlop) { this->phraseSlop = phraseSlop; } + + /** + * Gets the default slop for phrases. + */ + int getPhraseSlop() { return phraseSlop; } + +protected: + + /** + * Removes the escaped characters + */ + void discardEscapeChar(TCHAR* token) const; + + //Analyzes the expanded term termStr with the StandardFilter and the LowerCaseFilter. + TCHAR* AnalyzeExpandedTerm(const TCHAR* field, TCHAR* termStr); + + // Adds the next parsed clause. + virtual void AddClause(std::vector& clauses, int32_t conj, int32_t mods, CL_NS(search)::Query* q); + + /** + * Returns a termquery, phrasequery for the specified field. + * Note: this is only a partial implementation, since MultiPhraseQuery is not implemented yet + * return NULL to disallow + */ + virtual CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText); + + /** + * Delegates to GetFieldQuery(string, string), and adds slop onto phrasequery. + * Can be used to remove slop functionality + */ + virtual CL_NS(search)::Query* GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop); + + /** + * Factory method for generating a query (similar to + * {@link #GetWildcardQuery}). Called when parser parses an input term + * token that uses prefix notation; that is, contains a single '*' wildcard + * character as its last character. Since this is a special case + * of generic wildcard term, and such a query can be optimized easily, + * this usually results in a different query object. + *

+ * Depending on settings, a prefix term may be lower-cased + * automatically. It will not go through the default Analyzer, + * however, since normal Analyzers are unlikely to work properly + * with wildcard templates. + *

+ * Can be overridden by extending classes, to provide custom handling for + * wild card queries, which may be necessary due to missing analyzer calls. + * + * @param field Name of the field query will use. + * @param termStr Term token to use for building term for the query + * (without trailing '*' character!) + * + * @return Resulting {@link Query} built for the term + * return NULL to disallow + */ + virtual CL_NS(search)::Query* GetPrefixQuery(const TCHAR* field, TCHAR* termStr); + + /** + * Factory method for generating a query. Called when parser + * parses an input term token that contains one or more wildcard + * characters (? and *), but is not a prefix term token (one + * that has just a single * character at the end) + *

+ * Depending on settings, prefix term may be lower-cased + * automatically. It will not go through the default Analyzer, + * however, since normal Analyzers are unlikely to work properly + * with wildcard templates. + *

+ * Can be overridden by extending classes, to provide custom handling for + * wildcard queries, which may be necessary due to missing analyzer calls. + * + * @param field Name of the field query will use. + * @param termStr Term token that contains one or more wild card + * characters (? or *), but is not simple prefix term + * + * @return Resulting {@link Query} built for the term + * return NULL to disallow + */ + virtual CL_NS(search)::Query* GetWildcardQuery(const TCHAR* field, TCHAR* termStr); + + /** + * Factory method for generating a query (similar to + * {@link #GetWildcardQuery}). Called when parser parses + * an input term token that has the fuzzy suffix (~) appended. + * + * @param field Name of the field query will use. + * @param termStr Term token to use for building term for the query + * + * @return Resulting {@link Query} built for the term + * return NULL to disallow + */ + virtual CL_NS(search)::Query* GetFuzzyQuery(const TCHAR* field, TCHAR* termStr); + + /** + * Factory method for generating query, given a set of clauses. + * By default creates a boolean query composed of clauses passed in. + * + * Can be overridden by extending classes, to modify query being + * returned. + * + * @param clauses Vector that contains {@link BooleanClause} instances + * to join. + * + * @return Resulting {@link Query} object. + * return NULL to disallow + * + * @memory clauses must all be cleaned up by this function. + */ + virtual CL_NS(search)::Query* GetBooleanQuery(std::vector& clauses); + virtual CL_NS(search)::Query* GetBooleanQuery(std::vector& clauses, bool disableCoord ); + + /** + * return NULL to disallow + */ + virtual CL_NS(search)::Query* GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive); + virtual CL_NS(search)::Query* ParseRangeQuery(const TCHAR* field, TCHAR* str, bool inclusive); +}; + +/** +* @brief CLucene's default query parser. +* +*

It's a query parser. +* The only method that clients should need to call is Parse(). +* The syntax for query const TCHAR*s is as follows: +* A Query is a series of clauses. A clause may be prefixed by:

+*
    +*
  • a plus (+) or a minus (-) sign, indicating that the +* clause is required or prohibited respectively; or
  • +*
  • a term followed by a colon, indicating the field to be searched. +* This enables one to construct queries which search multiple fields.
  • +*
+*

+* A clause may be either:

+*
    +*
  • a term, indicating all the documents that contain this term; or
  • +*
  • a nested query, enclosed in parentheses. Note that this may be +* used with a +/- prefix to require any of a set of terms.
  • +*
+*

+* Thus, in BNF, the query grammar is:

+* +* Query ::= ( Clause )* +* Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" ) +* +*

+* Examples of appropriately formatted queries can be found in the test cases. +*

+*/ +class CLUCENE_EXPORT QueryParser : public QueryParserBase +{ +private: + TCHAR* field; + TokenList* tokens; +public: + /** + * Initializes a new instance of the QueryParser class with a specified field and + * analyzer values. + */ + QueryParser(const TCHAR* field, CL_NS(analysis)::Analyzer* analyzer); + ~QueryParser(); + + /** + * Returns a parsed Query instance. + * Note: this call is not threadsafe, either use a seperate QueryParser for each thread, or use a thread lock + * The query value to be parsed. + * A parsed Query instance. + */ + virtual CL_NS(search)::Query* parse(const TCHAR* query); + + /** + * Returns a parsed Query instance. + * Note: this call is not threadsafe, either use a seperate QueryParser for each thread, or use a thread lock + * The TextReader value to be parsed. + * A parsed Query instance. + */ + virtual CL_NS(search)::Query* parse(CL_NS(util)::BufferedReader* reader); + + /** + * Returns a new instance of the Query class with a specified query, field and + * analyzer values. + */ + static CL_NS(search)::Query* parse(const TCHAR* query, const TCHAR* field, CL_NS(analysis)::Analyzer* analyzer); + + CL_NS(analysis)::Analyzer* getAnalyzer() { return analyzer; } + + /** + * @return Returns the field. + */ + const TCHAR* getField(); + + //deprecated functions + _CL_DEPRECATED( setLowercaseExpandedTerms ) void setLowercaseWildcardTerms(bool lowercaseWildcardTerms); + _CL_DEPRECATED( getLowercaseExpandedTerms ) bool getLowercaseWildcardTerms() const; +private: + /** + * matches for CONJUNCTION + * CONJUNCTION ::= | + */ + int32_t MatchConjunction(); + + /** + * matches for MODIFIER + * MODIFIER ::= | | + */ + int32_t MatchModifier(); + + /** + * matches for QUERY + * QUERY ::= [MODIFIER] CLAUSE ( [MODIFIER] CLAUSE)* + */ + CL_NS(search)::Query* MatchQuery(const TCHAR* field); + + /** + * matches for CLAUSE + * CLAUSE ::= [TERM ] ( TERM | ( QUERY )) + */ + CL_NS(search)::Query* MatchClause(const TCHAR* field); + + /** + * matches for TERM + * TERM ::= TERM | PREFIXTERM | WILDTERM | NUMBER + * [ ] [ []] + * + * | ( | ) [ ] + * | [SLOP] [ ] + */ + CL_NS(search)::Query* MatchTerm(const TCHAR* field); + + /** + * matches for QueryToken of the specified type and returns it + * otherwise Exception throws + */ + QueryToken* MatchQueryToken(QueryToken::Types expectedType); + + /** + * Extracts the first token from the Tokenlist tokenlist + * and destroys it + */ + void ExtractAndDeleteToken(void); +}; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/queryParser/legacy/QueryParserBase.cpp b/src/core/CLucene/queryParser/legacy/QueryParserBase.cpp new file mode 100644 index 00000000000..5d34b7dc423 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/QueryParserBase.cpp @@ -0,0 +1,384 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryParser.h" + +#include "CLucene/search/TermQuery.h" +#include "CLucene/search/PhraseQuery.h" +#include "CLucene/search/RangeQuery.h" +#include "CLucene/search/FuzzyQuery.h" +#include "CLucene/search/WildcardQuery.h" +#include "CLucene/search/PrefixQuery.h" +#include "CLucene/search/BooleanQuery.h" + +#include "CLucene/analysis/AnalysisHeader.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/BooleanClause.h" +#include "CLucene/search/Query.h" +#include "CLucene/index/Term.h" +#include "QueryToken.h" + +#include "_TokenList.h" +#include "_Lexer.h" + +CL_NS_USE(search) +CL_NS_USE(util) +CL_NS_USE(analysis) +CL_NS_USE(index) + +CL_NS_DEF2(queryParser,legacy) + +QueryParserBase::QueryParserBase(Analyzer* analyzer){ +//Func - Constructor +//Pre - true +//Post - instance has been created with PhraseSlop = 0 + this->analyzer = analyzer; + this->defaultOperator = OR_OPERATOR; + this->phraseSlop = 0; + this->lowercaseExpandedTerms = true; +} + +QueryParserBase::~QueryParserBase(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed +} + + +void QueryParserBase::discardEscapeChar(TCHAR* source) const{ + int len = _tcslen(source); + for (int i = 0; i < len; i++) { + if (source[i] == '\\' && source[i+1] != '\0' ) { + _tcscpy(source+i,source+i+1); + len--; + } + } +} + +void QueryParserBase::AddClause(std::vector& clauses, int32_t conj, int32_t mods, Query* q){ +//Func - Adds the next parsed clause. +//Pre - +//Post - + + bool required, prohibited; + + // If this term is introduced by AND, make the preceding term required, + // unless it's already prohibited. + const uint32_t nPreviousClauses = clauses.size(); + if (nPreviousClauses > 0 && conj == CONJ_AND) { + BooleanClause* c = clauses[nPreviousClauses-1]; + if (!c->prohibited) + c->required = true; + } + + if (nPreviousClauses > 0 && defaultOperator == AND_OPERATOR && conj == CONJ_OR) { + // If this term is introduced by OR, make the preceding term optional, + // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b) + // notice if the input is a OR b, first term is parsed as required; without + // this modification a OR b would parse as +a OR b + BooleanClause* c = clauses[nPreviousClauses-1]; + if (!c->prohibited){ + c->required = false; + c->prohibited = false; + } + } + + // We might have been passed a NULL query; the term might have been + // filtered away by the analyzer. + if (q == NULL) + return; + + if (defaultOperator == OR_OPERATOR) { + // We set REQUIRED if we're introduced by AND or +; PROHIBITED if + // introduced by NOT or -; make sure not to set both. + prohibited = (mods == MOD_NOT); + required = (mods == MOD_REQ); + if (conj == CONJ_AND && !prohibited) { + required = true; + } + } else { + // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED + // if not PROHIBITED and not introduced by OR + prohibited = (mods == MOD_NOT); + required = (!prohibited && conj != CONJ_OR); + } + + if ( required && prohibited ) + throwParserException( _T("Clause cannot be both required and prohibited"), ' ',0,0); + clauses.push_back(_CLNEW BooleanClause(q,true, required, prohibited)); +} + +void QueryParserBase::throwParserException(const TCHAR* message, TCHAR ch, int32_t col, int32_t line ) +{ + TCHAR msg[1024]; + _sntprintf(msg,1024,message,ch,col,line); + _CLTHROWT (CL_ERR_Parse, msg ); +} + + +Query* QueryParserBase::GetFieldQuery(const TCHAR* field, TCHAR* queryText, int32_t slop){ + Query* ret = GetFieldQuery(field,queryText); + if ( ret && ret->instanceOf(PhraseQuery::getClassName()) ) + ((PhraseQuery*)ret)->setSlop(slop); + + return ret; +} + +Query* QueryParserBase::GetFieldQuery(const TCHAR* field, TCHAR* queryText){ +//Func - Returns a query for the specified field. +// Use the analyzer to get all the tokens, and then build a TermQuery, +// PhraseQuery, or nothing based on the term count +//Pre - field != NULL +// analyzer contains a valid reference to an Analyzer +// queryText != NULL and contains the query +//Post - A query instance has been returned for the specified field + + CND_PRECONDITION(field != NULL, "field is NULL"); + CND_PRECONDITION(queryText != NULL, "queryText is NULL"); + + //Instantiate a stringReader for queryText + StringReader reader(queryText); + TokenStream* source = analyzer->tokenStream(field, &reader); + CND_CONDITION(source != NULL,"source is NULL"); + + StringArrayWithDeletor v; + + Token t; + int positionCount = 0; + bool severalTokensAtSamePosition = false; + + //Get the tokens from the source + try{ + while (source->next(&t)){ + v.push_back(STRDUP_TtoT(t.termBuffer())); + + if (t.getPositionIncrement() != 0) + positionCount += t.getPositionIncrement(); + else + severalTokensAtSamePosition = true; + } + }catch(CLuceneError& err){ + if ( err.number() != CL_ERR_IO ) { + _CLLDELETE(source); + throw err; + } + } + _CLDELETE(source); + + //Check if there are any tokens retrieved + if (v.size() == 0){ + return NULL; + }else{ + if (v.size() == 1){ + Term* t = _CLNEW Term(field, v[0]); + Query* ret = _CLNEW TermQuery( t ); + _CLDECDELETE(t); + return ret; + }else{ + if (severalTokensAtSamePosition) { + if (positionCount == 1) { + // no phrase query: + BooleanQuery* q = _CLNEW BooleanQuery( true ); //todo: disableCoord=true here, but not implemented in BooleanQuery + CLuceneStringArray::iterator itr = v.begin(); + while ( itr != v.end() ){ + Term* t = _CLNEW Term(field, *itr); + q->add(_CLNEW TermQuery(t),true, false,false);//should occur... + _CLDECDELETE(t); + ++itr; + } + return q; + }else { + _CLTHROWA(CL_ERR_UnsupportedOperation, "MultiPhraseQuery NOT Implemented"); + } + }else{ + PhraseQuery* q = _CLNEW PhraseQuery; + q->setSlop(phraseSlop); + + StringArrayWithDeletor::iterator itr = v.begin(); + while ( itr != v.end() ){ + const TCHAR* data = *itr; + Term* t = _CLNEW Term(field, data); + q->add(t); + _CLDECDELETE(t); + ++itr; + } + return q; + } + } + } +} + +void QueryParserBase::setLowercaseExpandedTerms(bool lowercaseExpandedTerms){ + this->lowercaseExpandedTerms = lowercaseExpandedTerms; +} +bool QueryParserBase::getLowercaseExpandedTerms() const { + return lowercaseExpandedTerms; +} +void QueryParserBase::setDefaultOperator(int oper){ + this->defaultOperator=oper; +} +int QueryParserBase::getDefaultOperator() const{ + return defaultOperator; +} + + +Query* QueryParserBase::ParseRangeQuery(const TCHAR* field, TCHAR* queryText, bool inclusive) +{ + //todo: this must be fixed, [-1--5] (-1 to -5) should yield a result, but won't parse properly + //because it uses an analyser, should split it up differently... + + // Use the analyzer to get all the tokens. There should be 1 or 2. + StringReader reader(queryText); + TokenStream* source = analyzer->tokenStream(field, &reader); + + TCHAR* terms[2]; + terms[0]=NULL;terms[1]=NULL; + Token t; + bool tret=false; + bool from=true; + do + { + try{ + tret = (source->next(&t) != NULL); + }catch (CLuceneError& err){ + if ( err.number() == CL_ERR_IO ) + tret=false; + else + throw err; + } + if (tret) + { + if ( !from && _tcscmp(t.termBuffer(),_T("TO"))==0 ) + continue; + + + TCHAR* tmp = STRDUP_TtoT(t.termBuffer()); + discardEscapeChar(tmp); + terms[from? 0 : 1] = tmp; + + if (from) + from = false; + else + break; + } + }while(tret); + if ((terms[0] == NULL) || (terms[1] == NULL)) { + _CLTHROWA(CL_ERR_Parse, "No range given."); + } + Query* ret = GetRangeQuery(field, terms[0], terms[1],inclusive); + _CLDELETE_CARRAY(terms[0]); + _CLDELETE_CARRAY(terms[1]); + _CLDELETE(source); + + return ret; +} + +Query* QueryParserBase::GetPrefixQuery(const TCHAR* field, TCHAR* termStr){ +//Pre - field != NULL and field contains the name of the field that the query will use +// termStr != NULL and is the token to use for building term for the query +// (WITH or WITHOUT a trailing '*' character!) +//Post - A PrefixQuery instance has been returned + + CND_PRECONDITION(field != NULL,"field is NULL"); + CND_PRECONDITION(termStr != NULL,"termStr is NULL"); + + if ( lowercaseExpandedTerms ) + _tcslwr(termStr); + + Term* t = _CLNEW Term(field, termStr); + CND_CONDITION(t != NULL,"Could not allocate memory for term t"); + + Query *q = _CLNEW PrefixQuery(t); + CND_CONDITION(q != NULL,"Could not allocate memory for PrefixQuery q"); + + _CLDECDELETE(t); + return q; +} + +Query* QueryParserBase::GetFuzzyQuery(const TCHAR* field, TCHAR* termStr){ +//Func - Factory method for generating a query (similar to getPrefixQuery}). Called when parser parses +// an input term token that has the fuzzy suffix (~) appended. +//Pre - field != NULL and field contains the name of the field that the query will use +// termStr != NULL and is the token to use for building term for the query +// (WITH or WITHOUT a trailing '*' character!) +//Post - A FuzzyQuery instance has been returned + + CND_PRECONDITION(field != NULL,"field is NULL"); + CND_PRECONDITION(termStr != NULL,"termStr is NULL"); + + if ( lowercaseExpandedTerms ) + _tcslwr(termStr); + + Term* t = _CLNEW Term(field, termStr); + CND_CONDITION(t != NULL,"Could not allocate memory for term t"); + + Query *q = _CLNEW FuzzyQuery(t); + CND_CONDITION(q != NULL,"Could not allocate memory for FuzzyQuery q"); + + _CLDECDELETE(t); + return q; +} + + +Query* QueryParserBase::GetWildcardQuery(const TCHAR* field, TCHAR* termStr){ + CND_PRECONDITION(field != NULL,"field is NULL"); + CND_PRECONDITION(termStr != NULL,"termStr is NULL"); + + if ( lowercaseExpandedTerms ) + _tcslwr(termStr); + + Term* t = _CLNEW Term(field, termStr); + CND_CONDITION(t != NULL,"Could not allocate memory for term t"); + Query* q = _CLNEW WildcardQuery(t); + _CLDECDELETE(t); + + return q; +} + +Query* QueryParserBase::GetBooleanQuery(std::vector& clauses ) { + return GetBooleanQuery( clauses, false ); +} + +Query* QueryParserBase::GetBooleanQuery(std::vector& clauses, bool disableCoord){ + if ( clauses.size() == 0 ) + return NULL; + + BooleanQuery* query = _CLNEW BooleanQuery( disableCoord ); + //Condition check to see if query has been allocated properly + CND_CONDITION(query != NULL, "No memory could be allocated for query"); + + //iterate through all the clauses + for( uint32_t i=0;iadd(clauses[i]); + } + return query; +} + + +CL_NS(search)::Query* QueryParserBase::GetRangeQuery(const TCHAR* field, TCHAR* part1, TCHAR* part2, bool inclusive){ + //todo: does jlucene handle rangequeries differntly? if we are using + //a certain type of analyser, the terms may be filtered out, which + //is not necessarily what we want. + if (lowercaseExpandedTerms) { + _tcslwr(part1); + _tcslwr(part2); + } + //todo: should see if we can parse the strings as dates... currently we leave that up to the end-developer... + Term* t1 = _CLNEW Term(field,part1); + Term* t2 = _CLNEW Term(field,part2); + Query* ret = _CLNEW RangeQuery(t1, t2, inclusive); + _CLDECDELETE(t1); + _CLDECDELETE(t2); + + return ret; +} + +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/QueryToken.cpp b/src/core/CLucene/queryParser/legacy/QueryToken.cpp new file mode 100644 index 00000000000..7dc74ebde8a --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/QueryToken.cpp @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryToken.h" + +CL_NS_DEF2(queryParser,legacy) + +QueryToken::QueryToken(): + Value(NULL) +{ + set(UNKNOWN_); +} +QueryToken::QueryToken(const TCHAR* value, const int32_t start, const int32_t end, const QueryToken::Types type): + Value(NULL) +{ + set(value,start,end,type); +} + +QueryToken::~QueryToken(){ +//Func - Destructor +//Pre - true +//Post - Instance has been destroyed + + #ifndef LUCENE_TOKEN_WORD_LENGTH + _CLDELETE_CARRAY( Value ); + #endif +} + +// Initializes a new instance of the Token class LUCENE_EXPORT. +// +QueryToken::QueryToken(const TCHAR* value, const QueryToken::Types type): + Value(NULL) +{ + set(value,type); +} + +// Initializes a new instance of the Token class LUCENE_EXPORT. +// +QueryToken::QueryToken(QueryToken::Types type): + Value(NULL) +{ + set(type); +} + + +void QueryToken::set(const TCHAR* value, const Types type){ + set(value,0,-1,type); +} +void QueryToken::set(const TCHAR* value, const int32_t start, const int32_t end, const Types type){ + #ifndef LUCENE_TOKEN_WORD_LENGTH + _CLDELETE_CARRAY(Value); + Value = STRDUP_TtoT(value); + #else + _tcsncpy(Value,value,LUCENE_TOKEN_WORD_LENGTH); + Value[LUCENE_TOKEN_WORD_LENGTH]; + #endif + this->Start = start; + this->End = end; + this->Type = type; + + if ( this->End < 0 ) + this->End = _tcslen(Value); +} +void QueryToken::set(Types type){ + set(LUCENE_BLANK_STRING,0,0,type); +} + +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/QueryToken.h b/src/core/CLucene/queryParser/legacy/QueryToken.h new file mode 100644 index 00000000000..e53c99ce2a7 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/QueryToken.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_legacy_QueryToken_ +#define _lucene_queryParser_legacy_QueryToken_ + +CL_NS_DEF2(queryParser,legacy) + + // Token class that used by QueryParser. + class CLUCENE_EXPORT QueryToken:LUCENE_BASE + { + public: + enum Types + { + AND_, + OR, + NOT, + PLUS, + MINUS, + LPAREN, + RPAREN, + COLON, + CARAT, + QUOTED, + TERM, + SLOP, + FUZZY, + PREFIXTERM, + WILDTERM, + RANGEIN, + RANGEEX, + NUMBER, + EOF_, + UNKNOWN_ + }; + + + #ifdef LUCENE_TOKEN_WORD_LENGTH + TCHAR Value[LUCENE_TOKEN_WORD_LENGTH+1]; + #else + TCHAR* Value; + #endif + + int32_t Start; + int32_t End; + QueryToken::Types Type; + + // Initializes a new instance of the Token class. + QueryToken(const TCHAR* value, const int32_t start, const int32_t end, const Types type); + + // Initializes a new instance of the Token class. + QueryToken(const TCHAR* value, const Types type); + + // Initializes a new instance of the Token class. + QueryToken(Types type); + + // Initializes an empty instance of the Token class. + QueryToken(); + + ~QueryToken(); + + void set(const TCHAR* value, const int32_t start, const int32_t end, const Types type); + void set(const TCHAR* value, const Types type); + void set(Types type); + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/queryParser/legacy/TokenList.cpp b/src/core/CLucene/queryParser/legacy/TokenList.cpp new file mode 100644 index 00000000000..1d675c5ecbb --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/TokenList.cpp @@ -0,0 +1,79 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_TokenList.h" + +//#include "CLucene/util/VoidMap.h" +#include "CLucene/util/VoidList.h" +#include "QueryToken.h" + +CL_NS_DEF2(queryParser,legacy) + + TokenList::TokenList(){ + //Func - Constructor + //Pre - true + //Post - Instance has been created + } + + TokenList::~TokenList(){ + //Func - Destructor + //Pre - true + //Post - The tokenlist has been destroyed + + tokens.clear(); + } + + void TokenList::add(QueryToken* token){ + //Func - Adds a QueryToken token to the TokenList + //Pre - token != NULL + //Post - token has been added to the token list + + CND_PRECONDITION(token != NULL, "token != NULL"); + + tokens.insert(tokens.begin(),token); + } + + void TokenList::push(QueryToken* token){ + //Func - + //Pre - token != NULL + //Post - + + CND_PRECONDITION(token != NULL, "token is NULL"); + + tokens.push_back(token); + } + + QueryToken* TokenList::peek() { + /* DSR:2004.11.01: Reverted my previous (circa April 2004) fix (which + ** raised an exception if Peek was called when there were no tokens) in + ** favor of returning the EOF token. This solution is much better + ** integrated with the rest of the code in the queryParser subsystem. */ + size_t nTokens = tokens.size(); + if (nTokens == 0) { + push(_CLNEW QueryToken(QueryToken::EOF_)); + nTokens++; + } + return tokens[nTokens-1]; + } + + QueryToken* TokenList::extract(){ + //Func - Extract token from the TokenList + //Pre - true + //Post - Retracted token has been returned + + QueryToken* token = peek(); + //Retract the current peeked token + tokens.delete_back(); + + return token; + } + + int32_t TokenList::count() const + { + return tokens.size(); + } +CL_NS_END2 diff --git a/src/core/CLucene/queryParser/legacy/_Lexer.h b/src/core/CLucene/queryParser/legacy/_Lexer.h new file mode 100644 index 00000000000..44592336634 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/_Lexer.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_legacy_Lexer_ +#define _lucene_queryParser_legacy_Lexer_ + + +CL_CLASS_DEF(util,FastCharStream) +CL_CLASS_DEF(util,BufferedReader) +CL_CLASS_DEF(util,StringBuffer) + +//#include "TokenList.h" +class QueryToken; +class TokenList; +class QueryParserBase; + +CL_NS_DEF2(queryParser,legacy) + + // A simple Lexer that is used by QueryParser. + class Lexer:LUCENE_BASE + { + private: + CL_NS(util)::FastCharStream* reader; + QueryParserBase* queryparser; //holds the queryparser so that we can do callbacks + bool delSR; //Indicates if the reader must be deleted or not + + public: + // Initializes a new instance of the Lexer class with the specified + // query to lex. + Lexer(QueryParserBase* queryparser, const TCHAR* query); + + // Initializes a new instance of the Lexer class with the specified + // TextReader to lex. + Lexer(QueryParserBase* queryparser, CL_NS(util)::BufferedReader* source); + + //Breaks the input stream onto the tokens list tokens + void Lex(TokenList *tokens); + + ~Lexer(); + + private: + bool GetNextToken(QueryToken* token); + + // Reads an integer number. buf should quite large, probably as large as a field should ever be + void ReadIntegerNumber(const TCHAR ch, TCHAR* buf, int buflen); + + // Reads an inclusive range like [some words] + bool ReadInclusiveRange(const TCHAR prev, QueryToken* token); + + // Reads an exclusive range like {some words} + bool ReadExclusiveRange(const TCHAR prev, QueryToken* token); + + // Reads quoted string like "something else" + bool ReadQuoted(const TCHAR prev, QueryToken* token); + + bool ReadTerm(const TCHAR prev, QueryToken* token); + + //reads an escaped character into the buf. Buf requires at least 3 characters + bool ReadEscape(const TCHAR prev, TCHAR* buf); + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/queryParser/legacy/_TokenList.h b/src/core/CLucene/queryParser/legacy/_TokenList.h new file mode 100644 index 00000000000..7c482aca687 --- /dev/null +++ b/src/core/CLucene/queryParser/legacy/_TokenList.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_queryParser_legacy_TokenList_ +#define _lucene_queryParser_legacy_TokenList_ + + +//#include "QueryToken.h" +CL_NS_DEF2(queryParser,legacy) + +class QueryToken; + + // Represents a list of the tokens. + class TokenList:LUCENE_BASE + { + private: + CL_NS(util)::CLVector tokens; //todo:,CL_NS(util)::Deletor::Object + public: + TokenList(); + ~TokenList(); + + void add(QueryToken* token); + + void push(QueryToken* token); + + QueryToken* peek(); + + QueryToken* extract(); + + int32_t count() const; + }; +CL_NS_END2 +#endif diff --git a/src/core/CLucene/search/BooleanClause.h b/src/core/CLucene/search/BooleanClause.h new file mode 100644 index 00000000000..32fe8080ce3 --- /dev/null +++ b/src/core/CLucene/search/BooleanClause.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_BooleanClause_ +#define _lucene_search_BooleanClause_ + +CL_CLASS_DEF(util,StringBuffer) +CL_CLASS_DEF(search,Query) + +CL_NS_DEF(search) + +// A clause in a BooleanQuery. +class CLUCENE_EXPORT BooleanClause:LUCENE_BASE{ +public: + /** Specifies how clauses are to occur in matching documents. */ + enum Occur { + /** Use this operator for clauses that must appear in the matching documents. */ + MUST=1, + + /** Use this operator for clauses that should appear in the + * matching documents. For a BooleanQuery with no MUST + * clauses one or more SHOULD clauses must match a document + * for the BooleanQuery to match. + * @see BooleanQuery#setMinimumNumberShouldMatch + */ + SHOULD=2, + + /** Use this operator for clauses that must not appear in the matching documents. + * Note that it is not possible to search for queries that only consist + * of a MUST_NOT clause. */ + MUST_NOT=4 + }; +private: + /** The query whose matching documents are combined by the boolean query. + * @deprecated use {@link #setQuery(Query)} instead */ + Query* query; + + Occur occur; + + /* Middle layer for the Occur enum; will be removed soon enough. */ + void setFields(Occur occur); +public: + bool deleteQuery; + + + int32_t getClauseCount(); + + + /** Constructs a BooleanClause with query q, required + * r and prohibited p. + * @deprecated use BooleanClause(Query, Occur) instead + *
    + *
  • For BooleanClause(query, true, false) use BooleanClause(query, BooleanClause.Occur.MUST) + *
  • For BooleanClause(query, false, false) use BooleanClause(query, BooleanClause.Occur.SHOULD) + *
  • For BooleanClause(query, false, true) use BooleanClause(query, BooleanClause.Occur.MUST_NOT) + *
+ */ + BooleanClause(Query* q, const bool DeleteQuery,const bool req, const bool p); + + BooleanClause(const BooleanClause& clone); + + /** Constructs a BooleanClause. + */ + BooleanClause(Query* q, const bool DeleteQuery, Occur o); + + + BooleanClause* clone() const; + + ~BooleanClause(); + + + /** Returns true if o is equal to this. */ + bool equals(const BooleanClause* other) const; + + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + Occur getOccur() const; + void setOccur(Occur o); + + Query* getQuery() const; + void setQuery(Query* q); + + bool isProhibited() const; + bool isRequired() const; + + TCHAR* toString() const; + +public: // TODO: Make private and remove for CLucene 2.3.2 + /** If true, documents documents which do not + match this sub-query will not match the boolean query. + @deprecated use {@link #setOccur(BooleanClause.Occur)} instead */ + bool required; + + /** If true, documents documents which do + match this sub-query will not match the boolean query. + @deprecated use {@link #setOccur(BooleanClause.Occur)} instead */ + bool prohibited; +}; + + +CL_NS_END +#endif + diff --git a/src/core/CLucene/search/BooleanQuery.cpp b/src/core/CLucene/search/BooleanQuery.cpp new file mode 100644 index 00000000000..e77c4031073 --- /dev/null +++ b/src/core/CLucene/search/BooleanQuery.cpp @@ -0,0 +1,581 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "BooleanQuery.h" + +#include "BooleanClause.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/_Arrays.h" +#include "SearchHeader.h" +#include "_BooleanScorer.h" +#include "_ConjunctionScorer.h" +#include "Similarity.h" +#include "Explanation.h" +#include "_BooleanScorer2.h" +#include "Scorer.h" + +#include + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + class BooleanClause_Compare:public CL_NS_STD(binary_function) + { + public: + bool operator()( const BooleanClause* val1, const BooleanClause* val2 ) const { + return val1->equals(val2); + } + }; + + + class BooleanWeight: public Weight { + protected: + Searcher* searcher; + Similarity* similarity; + CL_NS(util)::CLVector > weights; + BooleanQuery::ClausesType* clauses; + BooleanQuery* parentQuery; + public: + BooleanWeight(Searcher* searcher, + CL_NS(util)::CLVector >* clauses, + BooleanQuery* parentQuery); + virtual ~BooleanWeight(); + Query* getQuery(); + float_t getValue(); + float_t sumOfSquaredWeights(); + void normalize(float_t norm); + Scorer* scorer(CL_NS(index)::IndexReader* reader); + Explanation* explain(CL_NS(index)::IndexReader* reader, int32_t doc); + };// BooleanWeight + + + BooleanQuery::BooleanQuery( bool disableCoord ): + clauses(_CLNEW BooleanQuery::ClausesType(true)) + { + this->minNrShouldMatch = 0; + this->disableCoord = disableCoord; + } + + BooleanQuery::BooleanQuery(int32_t minimumNumberShouldMatch, const std::vector& clauses): + clauses(_CLNEW ClausesType(true)) + { + minNrShouldMatch = minimumNumberShouldMatch; + for ( uint32_t i=0;ideleteQuery=true; + add(clauses[i]); + } + + // todo: ComputeHashCode() and RewriteNoScoring() need this sets! +// clause_sets_[BooleanClause::Occur::SHOULD] = std::make_shared>(); +// clause_sets_[BooleanClause::Occur::MUST] = std::make_shared>(); +// clause_sets_[BooleanClause::Occur::FILTER] = std::make_shared>(); +// clause_sets_[BooleanClause::Occur::MUST_NOT] = std::make_shared>(); + } + + Weight* BooleanQuery::_createWeight(Searcher* searcher) { + return _CLNEW BooleanWeight(searcher, clauses,this); + } + + BooleanQuery::BooleanQuery(const BooleanQuery& clone): + Query(clone), + clauses(_CLNEW ClausesType(true)), + disableCoord(clone.disableCoord) + { + minNrShouldMatch = clone.minNrShouldMatch; + for ( uint32_t i=0;isize();i++ ){ + BooleanClause* clause = (*clone.clauses)[i]->clone(); + clause->deleteQuery=true; + add(clause); + } + } + + BooleanQuery::~BooleanQuery(){ + clauses->clear(); + _CLDELETE(clauses); + } + + size_t BooleanQuery::hashCode() const { + //todo: do cachedHashCode, and invalidate on add/remove clause + size_t ret = 0; + for (uint32_t i = 0 ; i < clauses->size(); i++) { + BooleanClause* c = (*clauses)[i]; + ret = 31 * ret + c->hashCode(); + } + ret = ret ^ Similarity::floatToByte(getBoost()); + return ret; + } + + const char* BooleanQuery::getObjectName() const{ + return getClassName(); + } + const char* BooleanQuery::getClassName(){ + return "BooleanQuery"; + } + + /** + * Default value is 1024. Use org.apache.lucene.maxClauseCount + * system property to override. + */ + size_t BooleanQuery::maxClauseCount = LUCENE_BOOLEANQUERY_MAXCLAUSECOUNT; + size_t BooleanQuery::getMaxClauseCount(){ + return maxClauseCount; + } + + void BooleanQuery::setMaxClauseCount(const size_t maxClauseCount){ + if (maxClauseCount < 1) + _CLTHROWA(CL_ERR_IllegalArgument, "maxClauseCount must be >= 1"); + BooleanQuery::maxClauseCount = maxClauseCount; + } + + Similarity* BooleanQuery::getSimilarity( Searcher* searcher ) { + + Similarity* result = Query::getSimilarity( searcher ); + return result; + + } + + void BooleanQuery::add(Query* query, const bool deleteQuery, const bool required, const bool prohibited) { + BooleanClause* bc = _CLNEW BooleanClause(query,deleteQuery,required, prohibited); + try{ + add(bc); + }catch(...){ + _CLDELETE(bc); + throw; + } + } + + void BooleanQuery::add(Query* query, const bool deleteQuery, BooleanClause::Occur occur) { + BooleanClause* bc = _CLNEW BooleanClause(query,deleteQuery,occur); + try{ + add(bc); + }catch(...){ + _CLDELETE(bc); + throw; + } + } + + void BooleanQuery::add(BooleanClause* clause) { + if (clauses->size() >= getMaxClauseCount()) + _CLTHROWA(CL_ERR_TooManyClauses,"Too Many Clauses, please change your wildcard condition and try again"); + + clauses->push_back(clause); + } + + int32_t BooleanQuery::getMinNrShouldMatch(){ + return minNrShouldMatch; + } + bool BooleanQuery::getUseScorer14() { + return getAllowDocsOutOfOrder(); + } + + bool BooleanQuery::allowDocsOutOfOrder = false; + + void BooleanQuery::setUseScorer14( bool use14 ) { + setAllowDocsOutOfOrder(use14); + } + + void BooleanQuery::setAllowDocsOutOfOrder(bool allow) { + allowDocsOutOfOrder = allow; + } + + bool BooleanQuery::getAllowDocsOutOfOrder() { + return allowDocsOutOfOrder; + } + + + size_t BooleanQuery::getClauseCount() const { + return (int32_t) clauses->size(); + } + + TCHAR* BooleanQuery::toString(const TCHAR* field) const{ + StringBuffer buffer; + bool needParens=(getBoost() != 1.0) /* TODO: || (getMinimumNumberShouldMatch()>0)*/ ; + if (needParens) { + buffer.append(_T("(")); + } + + for (uint32_t i = 0 ; i < clauses->size(); i++) { + BooleanClause* c = (*clauses)[i]; + if (c->prohibited) + buffer.append(_T("-")); + else if (c->required) + buffer.append(_T("+")); + + if ( c->getQuery()->instanceOf(BooleanQuery::getClassName()) ) { // wrap sub-bools in parens + buffer.append(_T("(")); + + TCHAR* buf = c->getQuery()->toString(field); + buffer.append(buf); + _CLDELETE_CARRAY( buf ); + + buffer.append(_T(")")); + } else { + TCHAR* buf = c->getQuery()->toString(field); + buffer.append(buf); + _CLDELETE_CARRAY( buf ); + } + if (i != clauses->size()-1) + buffer.append(_T(" ")); + } + + if (needParens) { + buffer.append(_T(")")); + } + + if (getBoost() != 1.0) { + buffer.appendChar(_T('^')); + buffer.appendFloat(getBoost(),1); + } + return buffer.toString(); + } + + bool BooleanQuery::isCoordDisabled() { return disableCoord; } + void BooleanQuery::setCoordDisabled( bool disableCoord ) { this->disableCoord = disableCoord; } + + BooleanClause** BooleanQuery::getClauses() const + { + CND_MESSAGE(false, "Warning: BooleanQuery::getClauses() is deprecated") + BooleanClause** ret = _CL_NEWARRAY(BooleanClause*, clauses->size()+1); + getClauses(ret); + return ret; + } + + void BooleanQuery::getClauses(BooleanClause** ret) const + { + size_t size=clauses->size(); + for ( uint32_t i=0;isize() == 1) { // optimize 1-clause queries + BooleanClause* c = (*clauses)[0]; + if (!c->prohibited) { // just return clause + Query* query = c->getQuery()->rewrite(reader); // rewrite first + + //if the query doesn't actually get re-written, + //then return a clone (because the BooleanQuery + //will register different to the returned query. + if ( query == c->getQuery() ) + query = query->clone(); + + if (getBoost() != 1.0f) { // incorporate boost + query->setBoost(getBoost() * query->getBoost()); + } + + return query; + } + } + + BooleanQuery* clone = NULL; // recursively rewrite + for (uint32_t i = 0 ; i < clauses->size(); i++) { + BooleanClause* c = (*clauses)[i]; + Query* query = c->getQuery()->rewrite(reader); + if (query != c->getQuery()) { // clause rewrote: must clone + if (clone == NULL) + clone = (BooleanQuery*)this->clone(); + clone->clauses->set (i, _CLNEW BooleanClause(query, true, c->getOccur())); + } + } + if (clone != NULL) { + return clone; // some clauses rewrote + } else + return this; // no clauses rewrote + } + + void BooleanQuery::extractTerms( TermSet * termset ) const + { + for (size_t i = 0 ; i < clauses->size(); i++) + { + BooleanClause* clause = (*clauses)[i]; + clause->getQuery()->extractTerms( termset ); + } + } + + Query* BooleanQuery::clone() const{ + BooleanQuery* clone = _CLNEW BooleanQuery(*this); + return clone; + } + + /** Returns true iff o is equal to this. */ + bool BooleanQuery::equals(Query* o)const { + if (!(o->instanceOf(BooleanQuery::getClassName()))) + return false; + const BooleanQuery* other = (BooleanQuery*)o; + + bool ret = (this->getBoost() == other->getBoost()); + if ( ret ){ + CLListEquals comp; + ret = comp.equals(this->clauses,other->clauses); + } + return ret; + } + + + float_t BooleanWeight::getValue() { return parentQuery->getBoost(); } + Query* BooleanWeight::getQuery() { return (Query*)parentQuery; } + + BooleanWeight::BooleanWeight(Searcher* searcher, + CLVector >* clauses, BooleanQuery* parentQuery) + { + this->searcher = searcher; + this->similarity = parentQuery->getSimilarity( searcher ); + this->parentQuery = parentQuery; + this->clauses = clauses; + for (uint32_t i = 0 ; i < clauses->size(); i++) { + weights.push_back((*clauses)[i]->getQuery()->_createWeight(searcher)); + } + } + BooleanWeight::~BooleanWeight(){ + this->weights.clear(); + } + + float_t BooleanWeight::sumOfSquaredWeights() { + float_t sum = 0.0f; + for (uint32_t i = 0 ; i < weights.size(); i++) { + BooleanClause* c = (*clauses)[i]; + Weight* w = weights[i]; + float_t s = w->sumOfSquaredWeights(); // sum sub weights + if (!c->isProhibited()) + // only add to sum for non-prohibited clauses + sum += s; + } + sum *= parentQuery->getBoost() * parentQuery->getBoost(); // boost each sub-weight + return sum ; + } + + void BooleanWeight::normalize(float_t norm) { + norm *= parentQuery->getBoost(); // incorporate boost + for (uint32_t i = 0 ; i < weights.size(); i++) { + Weight* w = weights[i]; + // normalize all clauses, (even if prohibited in case of side affects) + w->normalize(norm); + } + } + + Scorer* BooleanWeight::scorer(IndexReader* reader){ + BooleanScorer2* result = _CLNEW BooleanScorer2(similarity, + parentQuery->minNrShouldMatch, + parentQuery->allowDocsOutOfOrder); + + for (size_t i = 0 ; i < weights.size(); i++) { + BooleanClause* c = (*clauses)[i]; + Weight* w = weights[i]; + Scorer* subScorer = w->scorer(reader); + if (subScorer != NULL) + result->add(subScorer, c->isRequired(), c->isProhibited()); + else if (c->isRequired()){ + _CLDELETE(result); + return NULL; + } + } + + return result; + + } + + Explanation* BooleanWeight::explain(IndexReader* reader, int32_t doc){ + const int32_t minShouldMatch = parentQuery->getMinNrShouldMatch(); + ComplexExplanation* sumExpl = _CLNEW ComplexExplanation(); + sumExpl->setDescription(_T("sum of:")); + int32_t coord = 0; + int32_t maxCoord = 0; + float_t sum = 0.0f; + bool fail = false; + int32_t shouldMatchCount = 0; + for (size_t i = 0 ; i < weights.size(); i++) { + BooleanClause* c = (*clauses)[i]; + Weight* w = weights[i]; + Explanation* e = w->explain(reader, doc); + if (!c->isProhibited()) maxCoord++; + if (e->isMatch()){ + if (!c->isProhibited()) { + sumExpl->addDetail(e); + sum += e->getValue(); + coord++; + } else { + StringBuffer buf(100); + buf.append(_T("match on prohibited clause (")); + TCHAR* tmp = c->getQuery()->toString(); + buf.append(tmp); + _CLDELETE_LCARRAY(tmp); + buf.appendChar(_T(')')); + + Explanation* r = _CLNEW Explanation(0.0f, buf.getBuffer()); + r->addDetail(e); + sumExpl->addDetail(r); + fail = true; + } + if (c->getOccur() == BooleanClause::SHOULD) + shouldMatchCount++; + } else if (c->isRequired()) { + StringBuffer buf(100); + buf.append(_T("no match on required clause (")); + TCHAR* tmp = c->getQuery()->toString(); + buf.append(tmp); + _CLDELETE_LCARRAY(tmp); + buf.appendChar(_T(')')); + + Explanation* r = _CLNEW Explanation(0.0f, buf.getBuffer()); + r->addDetail(e); + sumExpl->addDetail(r); + fail = true; + } else { + _CLLDELETE(e); + } + } + if (fail) { + sumExpl->setMatch(false); + sumExpl->setValue(0.0f); + sumExpl->setDescription(_T("Failure to meet condition(s) of required/prohibited clause(s)")); + return sumExpl; + } else if (shouldMatchCount < minShouldMatch) { + sumExpl->setMatch(false); + sumExpl->setValue(0.0f); + + StringBuffer buf(60); + buf.append(_T("Failure to match minimum number of optional clauses: ")); + buf.appendInt(minShouldMatch); + sumExpl->setDescription(buf.getBuffer()); + return sumExpl; + } + + sumExpl->setMatch(0 < coord ? true : false); + sumExpl->setValue(sum); + + float_t coordFactor = similarity->coord(coord, maxCoord); + if (coordFactor == 1.0f) // coord is no-op + return sumExpl; // eliminate wrapper + else { + ComplexExplanation* result = _CLNEW ComplexExplanation(sumExpl->isMatch(), + sum*coordFactor, + _T("product of:")); + result->addDetail(sumExpl); + + StringBuffer buf(30); + buf.append(_T("coord(")); + buf.appendInt(coord); + buf.appendChar(_T('/')); + buf.appendInt(maxCoord); + buf.appendChar(_T(')')); + result->addDetail(_CLNEW Explanation(coordFactor,buf.getBuffer())); + return result; + } + } + + BooleanClause::BooleanClause(Query* q, const bool DeleteQuery,const bool req, const bool p): + query(q), + occur(SHOULD), + deleteQuery(DeleteQuery), + required(req), + prohibited(p) + { + if (required) { + if (prohibited) { + // prohibited && required doesn't make sense, but we want the old behaviour: + occur = MUST_NOT; + } else { + occur = MUST; + } + } else { + if (prohibited) { + occur = MUST_NOT; + } else { + occur = SHOULD; + } + } + } + + BooleanClause::BooleanClause(const BooleanClause& clone): + query(clone.query->clone()), + occur(clone.occur), + deleteQuery(true), + required(clone.required), + prohibited(clone.prohibited) + { + } + + BooleanClause::BooleanClause(Query* q, const bool DeleteQuery, Occur o): + query(q), + occur(o), + deleteQuery(DeleteQuery) + { + setFields(occur); + } + + + BooleanClause* BooleanClause::clone() const { + BooleanClause* ret = _CLNEW BooleanClause(*this); + return ret; + } + + BooleanClause::~BooleanClause(){ + if ( deleteQuery ) + _CLDELETE( query ); + } + + + /** Returns true if o is equal to this. */ + bool BooleanClause::equals(const BooleanClause* other) const { + return this->query->equals(other->query) + && (this->required == other->required) + && (this->prohibited == other->prohibited) // TODO: Remove these + && (this->occur == other->getOccur() ); + } + + /** Returns a hash code value for this object.*/ + size_t BooleanClause::hashCode() const { + return query->hashCode() ^ ( (occur == MUST) ?1:0) ^ ( (occur == MUST_NOT)?2:0); + } + + BooleanClause::Occur BooleanClause::getOccur() const { return occur; } + void BooleanClause::setOccur(Occur o) { + occur = o; + setFields(o); + } + + Query* BooleanClause::getQuery() const { return query; } + void BooleanClause::setQuery(Query* q) { + if ( deleteQuery ) + _CLDELETE( query ); + query = q; + } + + bool BooleanClause::isProhibited() const { + return prohibited; /* TODO: return (occur == MUST_NOT); */ + } + + bool BooleanClause::isRequired() const { return required; /* TODO: return (occur == MUST); */ } + + TCHAR* BooleanClause::toString() const { + CL_NS(util)::StringBuffer buffer; + if (occur == MUST) + buffer.append(_T("+")); + else if (occur == MUST_NOT) + buffer.append(_T("-")); + buffer.append( query->toString() ); + return buffer.toString(); + } + + void BooleanClause::setFields(Occur occur) { + if (occur == MUST) { + required = true; + prohibited = false; + } else if (occur == SHOULD) { + required = false; + prohibited = false; + } else if (occur == MUST_NOT) { + required = false; + prohibited = true; + } else { + _CLTHROWT (CL_ERR_UnknownOperator, _T("Unknown operator")); + } + } + +CL_NS_END diff --git a/src/core/CLucene/search/BooleanQuery.h b/src/core/CLucene/search/BooleanQuery.h new file mode 100644 index 00000000000..47bd48f8eee --- /dev/null +++ b/src/core/CLucene/search/BooleanQuery.h @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_BooleanQuery_ +#define _lucene_search_BooleanQuery_ + +CL_CLASS_DEF(util,StringBuffer) +CL_CLASS_DEF(search,Weight) +#include "Query.h" +#include "BooleanClause.h" +#include "CLucene/util/VoidList.h" + +CL_NS_DEF(search) + + + // A Query that matches documents matching boolean combinations of other + // queries, typically {@link TermQuery}s or {@link PhraseQuery}s. + class CLUCENE_EXPORT BooleanQuery:public Query { + public: + typedef CL_NS(util)::CLVector > ClausesType; + private: + ClausesType* clauses; + static size_t maxClauseCount; + + /** Whether hit docs may be collected out of docid order. */ + static bool allowDocsOutOfOrder; + + bool disableCoord; + protected: + int32_t minNrShouldMatch; + Weight* _createWeight(Searcher* searcher); + BooleanQuery(const BooleanQuery& clone); + + public: + /** Constructs an empty boolean query. */ + BooleanQuery( bool disableCoord = false ); + + BooleanQuery(int32_t maxClauseCount, const std::vector& clauses); + + ~BooleanQuery(); + const char* getObjectName() const; + static const char* getClassName(); + + /** Return the maximum number of clauses permitted, 1024 by default. + * Attempts to add more than the permitted number of clauses cause {@link + * TooManyClauses} to be thrown.*/ + static size_t getMaxClauseCount(); + + /** Set the maximum number of clauses permitted. */ + static void setMaxClauseCount(const size_t maxClauseCount); + + /** Adds a clause to a boolean query. Clauses may be: + *
    + *
  • required which means that documents which do not + * match this sub-query will not match the boolean query; + *
  • prohibited which means that documents which do + * match this sub-query will not match the boolean query; or + *
  • neither, in which case matched documents are neither prohibited from + * nor required to match the sub-query. However, a document must match at + * least 1 sub-query to match the boolean query. + *
+ * It is an error to specify a clause as both required and + * prohibited. + * + * @deprecated use {@link #add(Query, BooleanClause.Occur)} instead: + *
    + *
  • For add(query, true, false) use add(query, BooleanClause.Occur.MUST) + *
  • For add(query, false, false) use add(query, BooleanClause.Occur.SHOULD) + *
  • For add(query, false, true) use add(query, BooleanClause.Occur.MUST_NOT) + *
+ */ + void add(Query* query, const bool required, const bool prohibited){ + add(query,false,required,prohibited); + } + void add(Query* query, const bool deleteQuery, const bool required, const bool prohibited); + + void add(Query* query, const bool deleteQuery, BooleanClause::Occur occur); + void add(Query* query, BooleanClause::Occur occur) { add(query,false,occur); }; + + /** Copies the clauses of this query into the array. + * The array must be at least as long as getClauseCount() + * If you want to use the clauses, make sure you null terminate it. + */ + void getClauses(BooleanClause** clauses) const; + + ///@deprecated + _CL_DEPRECATED( getClauses(clauses) ) BooleanClause** getClauses() const; + + /** + * Give client code access to clauses.size() so we know how + * large the array returned by getClauses is. + */ + size_t getClauseCount() const; + + /** Adds a clause to a boolean query. + * @see #getMaxClauseCount() + */ + void add(BooleanClause* clause); + + Query* rewrite(CL_NS(index)::IndexReader* reader); + Query* clone() const; + + /** Expert: adds all terms occurring in this query to the termset set. */ + void extractTerms( TermSet * termset ) const; + + bool equals(Query* o) const; + Similarity* getSimilarity( Searcher* searcher ); + + bool isCoordDisabled(); + void setCoordDisabled( bool disableCoord ); + + static bool getUseScorer14(); + static void setUseScorer14( bool use14 ); + + /** + * Expert: Indicates whether hit docs may be collected out of docid + * order. + * + *

+ * Background: although the contract of the Scorer class requires that + * documents be iterated in order of doc id, this was not true in early + * versions of Lucene. Many pieces of functionality in the current + * Lucene code base have undefined behavior if this contract is not + * upheld, but in some specific simple cases may be faster. (For + * example: disjunction queries with less than 32 prohibited clauses; + * This setting has no effect for other queries.) + *

+ * + *

+ * Specifics: By setting this option to true, calls to + * {@link HitCollector#collect(int,float)} might be + * invoked first for docid N and only later for docid N-1. + * Being static, this setting is system wide. + *

+ */ + static void setAllowDocsOutOfOrder(bool allow); + + /** + * Whether hit docs may be collected out of docid order. + * @see #setAllowDocsOutOfOrder(boolean) + */ + static bool getAllowDocsOutOfOrder(); + + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + //internal + int32_t getMinNrShouldMatch(); + friend class BooleanWeight; + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/BooleanScorer.cpp b/src/core/CLucene/search/BooleanScorer.cpp new file mode 100644 index 00000000000..a6d0cecd0bb --- /dev/null +++ b/src/core/CLucene/search/BooleanScorer.cpp @@ -0,0 +1,299 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "SearchHeader.h" +#include "_BooleanScorer.h" + +#include "Scorer.h" +#include "Similarity.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_USE(util) +CL_NS_DEF(search) + + BooleanScorer::BooleanScorer(Similarity* similarity, int32_t minNrShouldMatch ): + Scorer(similarity), + scorers(NULL), + maxCoord(1), + nextMask(1), + end(0), + current(NULL), + minNrShouldMatch(minNrShouldMatch), + requiredMask(0), + prohibitedMask(0), + coordFactors(NULL) + { + bucketTable = _CLNEW BucketTable(this); + } + + BooleanScorer::~BooleanScorer(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLDELETE(bucketTable); + _CLDELETE_ARRAY(coordFactors); + _CLDELETE(scorers); + } + + + bool BooleanScorer::next() { + bool more; + do { + while (bucketTable->first != NULL) { // more queued + current = bucketTable->first; + bucketTable->first = current->next; // pop the queue + + // check prohibited & required + if ((current->bits & prohibitedMask) == 0 && + (current->bits & requiredMask) == requiredMask) { + return true; + } + } + + // refill the queue + more = false; + end += BooleanScorer::BucketTable_SIZE; + for (SubScorer* sub = scorers; sub != NULL; sub = sub->next) { + Scorer* scorer = sub->scorer; + int32_t doc; + while (!sub->done && (doc=scorer->doc()) < end) { + sub->collector->collect(doc, scorer->score()); + sub->done = !scorer->next(); + } + if (!sub->done) { + more = true; + } + } + } while (bucketTable->first != NULL || more); + + return false; + } + + float_t BooleanScorer::score(){ + if (coordFactors == NULL) + computeCoordFactors(); + return current->score * coordFactors[current->coord]; + } + + void BooleanScorer::score( HitCollector* results ) { + next(); + score( results, LUCENE_INT32_MAX_SHOULDBE ); + } + + bool BooleanScorer::skipTo(int32_t /*target*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: BooleanScorer::skipTo"); + } + + Explanation* BooleanScorer::explain(int32_t /*doc*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: BooleanScorer::explain"); + } + + TCHAR* BooleanScorer::toString() { + CL_NS(util)::StringBuffer buffer; + buffer.append(_T("boolean(")); + for (SubScorer* sub = scorers; sub != NULL; sub = sub->next) { + TCHAR* tmp = sub->scorer->toString(); + buffer.append(tmp); + _CLDELETE_LCARRAY(tmp); + buffer.appendChar(_T(' ')); + } + buffer.appendChar(_T(')')); + return buffer.toString(); + } + + void BooleanScorer::add(Scorer* scorer, const bool required, const bool prohibited) { + int32_t mask = 0; + if (required || prohibited) { + if (nextMask == 0) + _CLTHROWA(CL_ERR_IndexOutOfBounds, "More than 32 required/prohibited clauses in query."); + mask = nextMask; + nextMask = ( nextMask << 1 ); + } else + mask = 0; + + if (!prohibited) + maxCoord++; + + if (prohibited) + prohibitedMask |= mask; // update prohibited mask + else if (required) + requiredMask |= mask; // update required mask + + //scorer, HitCollector, and scorers is delete in the SubScorer + scorers = _CLNEW SubScorer(scorer, required, prohibited, + bucketTable->newCollector(mask), scorers); + } + + void BooleanScorer::computeCoordFactors(){ + coordFactors = _CL_NEWARRAY(float_t,maxCoord); + for (int32_t i = 0; i < maxCoord; i++) + coordFactors[i] = getSimilarity()->coord(i, maxCoord-1); + } + + bool BooleanScorer::score( HitCollector* results, const int32_t maxDoc ) { + if ( coordFactors == NULL ) { + computeCoordFactors(); + } + + bool more; + Bucket* tmp; + + do { + bucketTable->first = NULL; + while ( current != NULL ) { + + if (( current->bits & prohibitedMask ) == 0 && + ( current->bits & requiredMask ) == requiredMask ) { + + if ( current->doc >= maxDoc ) { + tmp = current; + current = current->next; + tmp->next = bucketTable->first; + bucketTable->first = tmp; + continue; + } + + if ( current->coord >= minNrShouldMatch ) { + results->collect( current->doc, current->score * coordFactors[current->coord] ); + } + } + + current = current->next; + } + + if ( bucketTable->first != NULL ) { + current = bucketTable->first; + bucketTable->first = current->next; + return true; + } + + more = false; + end += BucketTable_SIZE; + + for ( SubScorer* sub = scorers; sub != NULL; sub = sub->next ) { + if ( !sub->done ) { + sub->done = !sub->scorer->score( sub->collector, end ); + if ( !sub->done ) + more = true; + } + } + current = bucketTable->first; + + } while ( current != NULL || more ); + + return false; + } + + + + BooleanScorer::SubScorer::SubScorer(Scorer* scr, const bool r, const bool p, HitCollector* c, SubScorer* nxt): + scorer(scr), + required(r), + prohibited(p), + collector(c), + next(nxt) + { + //Func - Constructor + //Pre - scr != NULL, + // c != NULL + // nxt may or may not be NULL + //Post - The instance has been created + + CND_PRECONDITION(scr != NULL,"scr is NULL"); + CND_PRECONDITION(c != NULL,"c is NULL"); + + done = !scorer->next(); + } + + BooleanScorer::SubScorer::~SubScorer(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + for (SubScorer * ptr = next; ptr; ){ + SubScorer* next = ptr->next; + ptr->next = NULL; + _CLDELETE(ptr); + ptr = next; + } + _CLDELETE(scorer); + _CLDELETE(collector); + } + + BooleanScorer::Bucket::Bucket(): + doc(-1), + score(0.0), + bits(0), + coord(0), + next(NULL) + { + } + BooleanScorer::Bucket::~Bucket(){ + } + + + + + BooleanScorer::BucketTable::BucketTable(BooleanScorer* scr): + scorer(scr), + first(NULL) + { + buckets = new Bucket[BucketTable_SIZE]; + } + BooleanScorer::BucketTable::~BucketTable(){ + clear(); + delete [] buckets; + } + + void BooleanScorer::BucketTable::clear(){ + //delete first; + first = NULL; + } + int32_t BooleanScorer::BucketTable::size() const { return BooleanScorer::BucketTable_SIZE; } + + HitCollector* BooleanScorer::BucketTable::newCollector(const int32_t mask) { + return _CLNEW Collector(mask, this); + } + + + + + + + + + + BooleanScorer::Collector::Collector(const int32_t msk, BucketTable* bucketTbl): + bucketTable(bucketTbl), + mask(msk) + { + } + + void BooleanScorer::Collector::collect(const int32_t doc, const float_t score){ + BucketTable* table = bucketTable; + int32_t i = doc & (BooleanScorer::BucketTable_SIZE-1); + Bucket* bucket = &table->buckets[i]; + + if (bucket->doc != doc) { // invalid bucket + bucket->doc = doc; // set doc + bucket->score = score; // initialize score + bucket->bits = mask; // initialize mask + bucket->coord = 1; // initialize coord + + bucket->next = table->first; // push onto valid list + table->first = bucket; + } else { // valid bucket + bucket->score += score; // increment score + bucket->bits |= mask; // add bits in mask + bucket->coord++; // increment coord + } + } + + + +CL_NS_END diff --git a/src/core/CLucene/search/BooleanScorer2.cpp b/src/core/CLucene/search/BooleanScorer2.cpp new file mode 100644 index 00000000000..a562193fb83 --- /dev/null +++ b/src/core/CLucene/search/BooleanScorer2.cpp @@ -0,0 +1,688 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_BooleanScorer2.h" + +#include "Scorer.h" +#include "SearchHeader.h" +#include "Similarity.h" +#include "ScorerDocQueue.h" +#include "Explanation.h" + +#include "_BooleanScorer.h" +#include "_BooleanScorer.h" +#include "_ConjunctionScorer.h" +#include "_DisjunctionSumScorer.h" + +CL_NS_USE(util) +CL_NS_DEF(search) + + +class BooleanScorer2::Coordinator { +public: + int32_t maxCoord; + int32_t nrMatchers; // to be increased by score() of match counting scorers. + float_t* coordFactors; + Scorer* parentScorer; + + Coordinator( Scorer* parent ): + maxCoord(0), + nrMatchers(0), + coordFactors(NULL), + parentScorer(parent) + { + } + + virtual ~Coordinator() + { + _CLDELETE_ARRAY(coordFactors); + } + + void init() + { + coordFactors = _CL_NEWARRAY( float_t, maxCoord+1 ); + Similarity* sim = parentScorer->getSimilarity(); + for ( int32_t i = 0; i <= maxCoord; i++ ) { + coordFactors[i] = sim->coord(i, maxCoord); + } + } + + + void initDoc() { + nrMatchers = 0; + } + + float_t coordFactor() { + return coordFactors[nrMatchers]; + } +}; + +class BooleanScorer2::SingleMatchScorer: public Scorer { +public: + Scorer* scorer; + Coordinator* coordinator; + int32_t lastScoredDoc; + + SingleMatchScorer( Scorer* _scorer, Coordinator* _coordinator ) : + Scorer( _scorer->getSimilarity() ), scorer(_scorer), coordinator(_coordinator), lastScoredDoc(-1) + { + } + + virtual ~SingleMatchScorer() + { + _CLDELETE( scorer ); + } + + float_t score() + { + if ( doc() >= lastScoredDoc ) { + lastScoredDoc = this->doc(); + coordinator->nrMatchers++; + } + return scorer->score(); + } + + int32_t doc() const { + return scorer->doc(); + } + + bool next() { + return scorer->next(); + } + + bool skipTo( int32_t docNr ) { + return scorer->skipTo( docNr ); + } + + virtual TCHAR* toString() { + return scorer->toString(); + } + + Explanation* explain(int32_t doc) { + return scorer->explain( doc ); + } + +}; + +/** A scorer that matches no document at all. */ +class BooleanScorer2::NonMatchingScorer: public Scorer { +public: + + NonMatchingScorer() : + Scorer( NULL ) + { + } + virtual ~NonMatchingScorer() {}; + + int32_t doc() const { + _CLTHROWA(CL_ERR_UnsupportedOperation, "UnsupportedOperationException: BooleanScorer2::NonMatchingScorer::doc"); + return 0; + } + bool next() { return false; } + float_t score() { + _CLTHROWA(CL_ERR_UnsupportedOperation, "UnsupportedOperationException: BooleanScorer2::NonMatchingScorer::score"); + return 0.0; + } + bool skipTo( int32_t /*target*/ ) { return false; } + virtual TCHAR* toString() { return stringDuplicate(_T("NonMatchingScorer")); } + + Explanation* explain( int32_t /*doc*/ ) { + Explanation* e = _CLNEW Explanation(); + e->setDescription(_T("No document matches.")); + return e; + } + +}; + +/** A Scorer for queries with a required part and an optional part. + * Delays skipTo() on the optional part until a score() is needed. + *
+ * This Scorer implements {@link Scorer#skipTo(int)}. + */ +class BooleanScorer2::ReqOptSumScorer: public Scorer { +private: + /** The scorers passed from the constructor. + * These are set to null as soon as their next() or skipTo() returns false. + */ + Scorer* reqScorer; + Scorer* optScorer; + bool firstTimeOptScorer; + +public: + /** Construct a ReqOptScorer. + * @param reqScorer The required scorer. This must match. + * @param optScorer The optional scorer. This is used for scoring only. + */ + ReqOptSumScorer( Scorer* _reqScorer, Scorer* _optScorer ) : + Scorer( NULL ), reqScorer(_reqScorer), optScorer(_optScorer), firstTimeOptScorer(true) + { + } + + virtual ~ReqOptSumScorer() + { + _CLDELETE( reqScorer ); + _CLDELETE( optScorer ); + } + + /** Returns the score of the current document matching the query. + * Initially invalid, until {@link #next()} is called the first time. + * @return The score of the required scorer, eventually increased by the score + * of the optional scorer when it also matches the current document. + */ + float_t score() + { + int32_t curDoc = reqScorer->doc(); + float_t reqScore = reqScorer->score(); + + if ( firstTimeOptScorer ) { + firstTimeOptScorer = false; + if ( !optScorer->skipTo( curDoc ) ) { + _CLDELETE(optScorer); + return reqScore; + } + } else if ( optScorer == NULL ) { + return reqScore; + } else if (( optScorer->doc() < curDoc ) && ( !optScorer->skipTo( curDoc ))) { + _CLDELETE(optScorer); + return reqScore; + } + + return ( optScorer->doc() == curDoc ) + ? reqScore + optScorer->score() + : reqScore; + } + + int32_t doc() const { + return reqScorer->doc(); + } + + bool next() { + return reqScorer->next(); + } + + bool skipTo( int32_t target ) { + return reqScorer->skipTo( target ); + } + + virtual TCHAR* toString() { + return stringDuplicate(_T("ReqOptSumScorer")); + } + + /** Explain the score of a document. + * @todo Also show the total score. + * See BooleanScorer.explain() on how to do this. + */ + Explanation* explain( int32_t doc ) { + Explanation* res = _CLNEW Explanation(); + res->setDescription(_T("required, optional")); + res->addDetail(reqScorer->explain(doc)); + res->addDetail(optScorer->explain(doc)); + return res; + } +}; + + +/** A Scorer for queries with a required subscorer and an excluding (prohibited) subscorer. +*
+* This Scorer implements {@link Scorer#skipTo(int)}, +* and it uses the skipTo() on the given scorers. +*/ +class BooleanScorer2::ReqExclScorer: public Scorer { +private: + Scorer* reqScorer; + Scorer* exclScorer; + bool firstTime; + +public: + /** Construct a ReqExclScorer. + * @param reqScorer The scorer that must match, except where + * @param exclScorer indicates exclusion. + */ + ReqExclScorer( Scorer* _reqScorer, Scorer* _exclScorer ) : + Scorer( NULL ), reqScorer(_reqScorer), exclScorer(_exclScorer), firstTime(true) + { + } + + virtual ~ReqExclScorer() + { + _CLDELETE( reqScorer ); + _CLDELETE( exclScorer ); + } + + int32_t doc() const { + return reqScorer->doc(); + } + + /** Returns the score of the current document matching the query. + * Initially invalid, until {@link #next()} is called the first time. + * @return The score of the required scorer. + */ + float_t score() { + return reqScorer->score(); + } + + virtual TCHAR* toString() { + return stringDuplicate(_T("ReqExclScorer")); + } + + Explanation* explain( int32_t doc ) { + Explanation* res = _CLNEW Explanation(); + if (exclScorer->skipTo(doc) && (exclScorer->doc() == doc)) { + res->setDescription(_T("excluded")); + } else { + res->setDescription(_T("not excluded")); + res->addDetail(reqScorer->explain(doc)); + } + return res; + } + + + bool next() + { + if ( firstTime ) { + if ( !exclScorer->next() ) { + _CLDELETE( exclScorer ); + } + firstTime = false; + } + if ( reqScorer == NULL ) { + return false; + } + if ( !reqScorer->next() ) { + _CLDELETE( reqScorer ); // exhausted, nothing left + return false; + } + if ( exclScorer == NULL ) { + return true;// reqScorer.next() already returned true + } + return toNonExcluded(); + } + + + /** Skips to the first match beyond the current whose document number is + * greater than or equal to a given target. + *
When this method is used the {@link #explain(int)} method should not be used. + * @param target The target document number. + * @return true iff there is such a match. + */ + bool skipTo( int32_t target ) + { + if ( firstTime ) { + firstTime = false; + if ( !exclScorer->skipTo( target )) { + _CLDELETE( exclScorer ); // exhausted + } + } + if ( reqScorer == NULL ) { + return false; + } + if ( exclScorer == NULL ) { + return reqScorer->skipTo( target ); + } + if ( !reqScorer->skipTo( target )) { + _CLDELETE( reqScorer ); + return false; + } + return toNonExcluded(); + } + + +private: + /** Advance to non excluded doc. + *
On entry: + *
    + *
  • reqScorer != null, + *
  • exclScorer != null, + *
  • reqScorer was advanced once via next() or skipTo() + * and reqScorer.doc() may still be excluded. + *
+ * Advances reqScorer a non excluded required doc, if any. + * @return true iff there is a non excluded required doc. + */ + bool toNonExcluded() + { + int32_t exclDoc = exclScorer->doc(); + + do { + int32_t reqDoc = reqScorer->doc(); + if ( reqDoc < exclDoc ) { + return true; // reqScorer advanced to before exclScorer, ie. not excluded + } else if ( reqDoc > exclDoc ) { + if (! exclScorer->skipTo(reqDoc)) { + _CLDELETE( exclScorer ); // exhausted, no more exclusions + return true; + } + exclDoc = exclScorer->doc(); + if ( exclDoc > reqDoc ) { + return true; // not excluded + } + } + } while ( reqScorer->next() ); + + _CLDELETE( reqScorer ); // exhausted, nothing left + return false; + } + +}; + +class BooleanScorer2::BSConjunctionScorer: public CL_NS(search)::ConjunctionScorer { +private: + CL_NS(search)::BooleanScorer2::Coordinator* coordinator; + int32_t lastScoredDoc; + int32_t requiredNrMatchers; + typedef CL_NS(util)::CLVector > ScorersType; +public: + BSConjunctionScorer( CL_NS(search)::BooleanScorer2::Coordinator* _coordinator, ScorersType* _requiredScorers, int32_t _requiredNrMatchers ): + ConjunctionScorer( Similarity::getDefault(), _requiredScorers ), + coordinator(_coordinator), + lastScoredDoc(-1), + requiredNrMatchers(_requiredNrMatchers) + { + } + + virtual ~BSConjunctionScorer(){ + } + float_t score() + { + if ( this->doc() >= lastScoredDoc ) { + lastScoredDoc = this->doc(); + coordinator->nrMatchers += requiredNrMatchers; + } + return ConjunctionScorer::score(); + } + virtual TCHAR* toString() {return stringDuplicate(_T("BSConjunctionScorer"));} +}; + +class BooleanScorer2::BSDisjunctionSumScorer: public CL_NS(search)::DisjunctionSumScorer { +private: + CL_NS(search)::BooleanScorer2::Coordinator* coordinator; + int32_t lastScoredDoc; + typedef CL_NS(util)::CLVector > ScorersType; +public: + BSDisjunctionSumScorer( + CL_NS(search)::BooleanScorer2::Coordinator* _coordinator, + ScorersType* subScorers, + int32_t minimumNrMatchers ): + DisjunctionSumScorer( subScorers, minimumNrMatchers ), + coordinator(_coordinator), + lastScoredDoc(-1) + { + } + + float_t score() { + if ( this->doc() >= lastScoredDoc ) { + lastScoredDoc = this->doc(); + coordinator->nrMatchers += _nrMatchers; + } + return DisjunctionSumScorer::score(); + } + + virtual ~BSDisjunctionSumScorer(){ + } + virtual TCHAR* toString() {return stringDuplicate(_T("BSDisjunctionSumScorer"));} +}; + +class BooleanScorer2::Internal{ +public: + typedef CL_NS(util)::CLVector > ScorersType; + + ScorersType requiredScorers; + ScorersType optionalScorers; + ScorersType prohibitedScorers; + + BooleanScorer2::Coordinator *coordinator; + Scorer* countingSumScorer; + + size_t minNrShouldMatch; + bool allowDocsOutOfOrder; + + + void initCountingSumScorer() + { + coordinator->init(); + countingSumScorer = makeCountingSumScorer(); + } + + Scorer* countingDisjunctionSumScorer( ScorersType* scorers, int32_t minNrShouldMatch ) + { + return _CLNEW BSDisjunctionSumScorer( coordinator, scorers, minNrShouldMatch ); + } + + Scorer* countingConjunctionSumScorer( ScorersType* requiredScorers ) + { + return _CLNEW BSConjunctionScorer( coordinator, requiredScorers, requiredScorers->size() ); + } + + Scorer* dualConjunctionSumScorer( Scorer* req1, Scorer* req2 ) + { + ValueArray scorers(2); + scorers[0] = req1; + scorers[1] = req2; + return _CLNEW CL_NS(search)::ConjunctionScorer( Similarity::getDefault(), &scorers ); + + } + + Scorer* makeCountingSumScorer() + { + return ( requiredScorers.size() == 0 ) ? + makeCountingSumScorerNoReq() : + makeCountingSumScorerSomeReq(); + } + + Scorer* makeCountingSumScorerNoReq() + { + if ( optionalScorers.size() == 0 ) { + optionalScorers.setDoDelete(true); + return _CLNEW NonMatchingScorer(); + } else { + size_t nrOptRequired = ( minNrShouldMatch < 1 ) ? 1 : minNrShouldMatch; + if ( optionalScorers.size() < nrOptRequired ) { + optionalScorers.setDoDelete(true); + return _CLNEW NonMatchingScorer(); + } else { + Scorer* requiredCountingSumScorer = + ( optionalScorers.size() > nrOptRequired ) + ? countingDisjunctionSumScorer( &optionalScorers, nrOptRequired ) + : + ( optionalScorers.size() == 1 ) + ? _CLNEW SingleMatchScorer((Scorer*) optionalScorers[0], coordinator) + : countingConjunctionSumScorer( &optionalScorers ); + return addProhibitedScorers( requiredCountingSumScorer ); + } + } + } + + Scorer* makeCountingSumScorerSomeReq() + { + if ( optionalScorers.size() < minNrShouldMatch ) { + requiredScorers.setDoDelete(true); + optionalScorers.setDoDelete(true); + return _CLNEW NonMatchingScorer(); + } else if ( optionalScorers.size() == minNrShouldMatch ) { + Internal::ScorersType allReq( false ); + for ( Internal::ScorersType::iterator it = requiredScorers.begin(); it != requiredScorers.end(); it++ ) { + allReq.push_back( *it ); + } + for ( Internal::ScorersType::iterator it2 = optionalScorers.begin(); it2 != optionalScorers.end(); it2++ ) { + allReq.push_back( *it2 ); + } + return addProhibitedScorers( countingConjunctionSumScorer( &allReq )); + } else { + Scorer* requiredCountingSumScorer = + ( requiredScorers.size() == 1 ) + ? _CLNEW SingleMatchScorer( (Scorer*)requiredScorers[0], coordinator ) + : countingConjunctionSumScorer( &requiredScorers ); + if ( minNrShouldMatch > 0 ) { + return addProhibitedScorers( + dualConjunctionSumScorer( + requiredCountingSumScorer, + countingDisjunctionSumScorer( + &optionalScorers, + minNrShouldMatch ))); + } else { + return _CLNEW ReqOptSumScorer( + addProhibitedScorers( requiredCountingSumScorer ), + (( optionalScorers.size() == 1 ) + ? _CLNEW SingleMatchScorer( (Scorer*)optionalScorers[0], coordinator ) + : countingDisjunctionSumScorer( &optionalScorers, 1 ))); + } + } + } + + Scorer* addProhibitedScorers( Scorer* requiredCountingSumScorer ) + { + return ( prohibitedScorers.size() == 0 ) + ? requiredCountingSumScorer + : _CLNEW ReqExclScorer( requiredCountingSumScorer, + (( prohibitedScorers.size() == 1 ) + ? (Scorer*)prohibitedScorers[0] + : _CLNEW CL_NS(search)::DisjunctionSumScorer( &prohibitedScorers ))); + } + + + Internal( BooleanScorer2* parent, int32_t _minNrShouldMatch, bool _allowDocsOutOfOrder ): + requiredScorers(false), + optionalScorers(false), + prohibitedScorers(false), + countingSumScorer(NULL), + minNrShouldMatch(_minNrShouldMatch), + allowDocsOutOfOrder(_allowDocsOutOfOrder) + { + if ( _minNrShouldMatch < 0 ) { + _CLTHROWA(CL_ERR_IllegalArgument, "Minimum number of optional scorers should not be negative"); + } + + this->coordinator = _CLNEW Coordinator( parent ); + + } + ~Internal(){ + _CLDELETE( coordinator ); + _CLDELETE( countingSumScorer ); + /* TODO: these leak memory... haven't figure out how it should be fixed though... + requiredScorers.clear(); + optionalScorers.clear(); + prohibitedScorers.clear(); + */ + } + +}; + + + + + +BooleanScorer2::BooleanScorer2( Similarity* similarity, int32_t minNrShouldMatch, bool allowDocsOutOfOrder ): + Scorer( similarity ) +{ + _internal = new Internal(this, minNrShouldMatch, allowDocsOutOfOrder); +} + +BooleanScorer2::~BooleanScorer2() +{ + delete _internal; +} + +void BooleanScorer2::add( Scorer* scorer, bool required, bool prohibited ) +{ + if ( !prohibited ) { + _internal->coordinator->maxCoord++; + } + + if ( required ) { + if ( prohibited ) { + _CLTHROWA(CL_ERR_IllegalArgument, "scorer cannot be required and prohibited"); + } + _internal->requiredScorers.push_back( scorer ); + } else if ( prohibited ) { + _internal->prohibitedScorers.push_back( scorer ); + } else { + _internal->optionalScorers.push_back( scorer ); + } + +} + +void BooleanScorer2::score( HitCollector* hc ) +{ + if ( _internal->allowDocsOutOfOrder && _internal->requiredScorers.size() == 0 && _internal->prohibitedScorers.size() < 32 ) { + + BooleanScorer* bs = _CLNEW BooleanScorer( getSimilarity(), _internal->minNrShouldMatch ); + Internal::ScorersType::iterator si = _internal->optionalScorers.begin(); + while ( si != _internal->optionalScorers.end() ) { + bs->add( (*si), false /* required */, false /* prohibited */ ); + si++; + } + si = _internal->prohibitedScorers.begin(); + while ( si != _internal->prohibitedScorers.end() ) { + bs->add( (*si), false /* required */, true /* prohibited */ ); + si++; + } + bs->score( hc ); + } else { + if ( _internal->countingSumScorer == NULL ) { + _internal->initCountingSumScorer(); + } + while ( _internal->countingSumScorer->next() ) { + hc->collect( _internal->countingSumScorer->doc(), score() ); + } + } +} + +int32_t BooleanScorer2::doc() const +{ + return _internal->countingSumScorer->doc(); +} + +bool BooleanScorer2::next() +{ + if ( _internal->countingSumScorer == NULL ) { + _internal->initCountingSumScorer(); + } + return _internal->countingSumScorer->next(); +} + +float_t BooleanScorer2::score() +{ + _internal->coordinator->initDoc(); + float_t sum = _internal->countingSumScorer->score(); + return sum * _internal->coordinator->coordFactor(); +} + +bool BooleanScorer2::skipTo( int32_t target ) +{ + if ( _internal->countingSumScorer == NULL ) { + _internal->initCountingSumScorer(); + } + return _internal->countingSumScorer->skipTo( target ); +} + +TCHAR* BooleanScorer2::toString() +{ + return stringDuplicate(_T("BooleanScorer2")); +} + +Explanation* BooleanScorer2::explain( int32_t /*doc*/ ) +{ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: BooleanScorer2::explain"); + /* How to explain the coordination factor? + initCountingSumScorer(); + return countingSumScorer.explain(doc); // misses coord factor. + */ +} + +bool BooleanScorer2::score( HitCollector* hc, int32_t max ) +{ + int32_t docNr = _internal->countingSumScorer->doc(); + while ( docNr < max ) { + hc->collect( docNr, score() ); + if ( !_internal->countingSumScorer->next() ) { + return false; + } + docNr = _internal->countingSumScorer->doc(); + } + return true; +} +CL_NS_END diff --git a/src/core/CLucene/search/CachingSpanFilter.cpp b/src/core/CLucene/search/CachingSpanFilter.cpp new file mode 100644 index 00000000000..98300770e57 --- /dev/null +++ b/src/core/CLucene/search/CachingSpanFilter.cpp @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CachingSpanFilter.h" +#include "CLucene/index/IndexReader.h" + + +CL_NS_DEF(search) + +/** + * Result wrapper for the cache + */ +class ResultHolder : LUCENE_BASE +{ + bool deleteResult; +public: + SpanFilterResult * result; + + ResultHolder(SpanFilterResult * result, bool deleteResult ) + { + this->result = result; + this->deleteResult = deleteResult; + } + ~ResultHolder() + { + if ( deleteResult ) + _CLDELETE( result ); + } +}; + +struct CachingSpanFilter::Internal +{ + typedef CL_NS(util)::CLHashMap< + CL_NS(index)::IndexReader *, + ResultHolder *, + CL_NS(util)::Compare::Void, + CL_NS(util)::Equals::Void, + CL_NS(util)::Deletor::Object, + CL_NS(util)::Deletor::Object + > ResultCacheType; + + ResultCacheType cache; + DEFINE_MUTEX(cache_LOCK) + + Internal() : cache(false,true) + {} +}; + +CachingSpanFilter::CachingSpanFilter( SpanFilter * filter, bool deleteFilter ) +{ + _internal = _CLNEW Internal(); + this->filter = filter; + this->deleteFilter = deleteFilter; +} + +CachingSpanFilter::CachingSpanFilter( const CachingSpanFilter& copy ) +{ + _internal = _CLNEW Internal(); + this->filter = (SpanFilter*)copy.filter->clone(); + this->deleteFilter = true; +} + +CachingSpanFilter::~CachingSpanFilter() +{ + _CLDELETE( _internal ); + if( deleteFilter ) + { + _CLDELETE( filter ); + } + else + filter = NULL; +} + +Filter* CachingSpanFilter::clone() const +{ + return _CLNEW CachingSpanFilter( *this ); +} + +CL_NS(util)::BitSet* CachingSpanFilter::bits( CL_NS(index)::IndexReader * reader ) +{ + SpanFilterResult * result = getCachedResult( reader ); + return result != NULL ? result->getBits() : NULL; +} + +SpanFilterResult * CachingSpanFilter::getCachedResult( CL_NS(index)::IndexReader * reader ) +{ + SCOPED_LOCK_MUTEX( _internal->cache_LOCK ) + + ResultHolder * resultHolder = _internal->cache.get( reader ); + if( ! resultHolder ) + { + SpanFilterResult * result = filter->bitSpans( reader ); + resultHolder = _CLNEW ResultHolder( result, true ); + _internal->cache.put( reader, resultHolder ); + } + + return resultHolder->result; +} + +SpanFilterResult * CachingSpanFilter::bitSpans( CL_NS(index)::IndexReader * reader ) +{ + return getCachedResult( reader ); +} + +TCHAR* CachingSpanFilter::toString() +{ + TCHAR* ft = filter->toString(); + size_t len = _tcslen( ft ) + 20; + TCHAR* ret = _CL_NEWARRAY( TCHAR, len ); + ret[0] = 0; + _sntprintf( ret, len, _T( "CachingSpanFilter(%s)" ), ft ); + _CLDELETE_CARRAY( ft ); + return ret; +} + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/search/CachingSpanFilter.h b/src/core/CLucene/search/CachingSpanFilter.h new file mode 100644 index 00000000000..abe32bb1a6b --- /dev/null +++ b/src/core/CLucene/search/CachingSpanFilter.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_CachingSpanFilter_ +#define _lucene_search_CachingSpanFilter_ + +#include "SpanFilter.h" + +CL_NS_DEF(search) + +/** + * Wraps another SpanFilter's result and caches it. The purpose is to allow + * filters to simply filter, and then wrap with this class to add caching. + */ +class CachingSpanFilter : public SpanFilter +{ + struct Internal; + Internal* _internal; + +protected: + SpanFilter * filter; + bool deleteFilter; + +protected: + CachingSpanFilter( const CachingSpanFilter& copy ); + +public: + /** + * @param filter Filter to cache results of + */ + CachingSpanFilter( SpanFilter * filter, bool deleteFilter=true ); + + virtual ~CachingSpanFilter(); + + virtual Filter* clone() const; + + virtual CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader * reader ); + + virtual SpanFilterResult * bitSpans( CL_NS(index)::IndexReader * reader ); + + virtual TCHAR* toString(); + +private: + SpanFilterResult * getCachedResult( CL_NS(index)::IndexReader * reader ); + +// public boolean equals(Object o) { +// if (!(o instanceof CachingSpanFilter)) return false; +// return this.filter.equals(((CachingSpanFilter)o).filter); +// } +// +// public int hashCode() { +// return filter.hashCode() ^ 0x1117BF25; +// } +}; + +CL_NS_END +#endif // _lucene_search_CachingSpanFilter_ diff --git a/src/core/CLucene/search/CachingWrapperFilter.cpp b/src/core/CLucene/search/CachingWrapperFilter.cpp new file mode 100644 index 00000000000..0fd5ff1534b --- /dev/null +++ b/src/core/CLucene/search/CachingWrapperFilter.cpp @@ -0,0 +1,114 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CachingWrapperFilter.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/index/IndexReader.h" + +CL_NS_DEF(search) +CL_NS_USE(index) +CL_NS_USE(util) + + +class BitSetHolder: LUCENE_BASE{ + bool deleteBs; +public: + CL_NS(util)::BitSet* bits; + + BitSetHolder(CL_NS(util)::BitSet* bits, bool deleteBs){ + this->bits = bits; + this->deleteBs = deleteBs; + } + ~BitSetHolder(){ + if ( deleteBs ) + _CLDELETE(bits); + } +}; + +struct AbstractCachingFilter::Internal{ + typedef CL_NS(util)::CLHashMap, + CL_NS(util)::Equals::Void, + CL_NS(util)::Deletor::Object, + CL_NS(util)::Deletor::Object > CacheType; + + CacheType cache; + DEFINE_MUTEX(cache_LOCK) + Internal(): + cache(false,true) + { + } +}; + +AbstractCachingFilter::AbstractCachingFilter(): + _internal(new Internal) +{ +} +AbstractCachingFilter::AbstractCachingFilter(const AbstractCachingFilter& /*copy*/): + _internal(new Internal) +{ +} +AbstractCachingFilter::~AbstractCachingFilter(){ + delete _internal; +} + +BitSet* AbstractCachingFilter::bits(IndexReader* reader){ + SCOPED_LOCK_MUTEX(_internal->cache_LOCK) + BitSetHolder* cached = _internal->cache.get(reader); + if ( cached != NULL ) + return cached->bits; + BitSet* bs = doBits(reader); + BitSetHolder* bsh = _CLNEW BitSetHolder(bs, doShouldDeleteBitSet(bs)); + _internal->cache.put(reader,bsh); + return bs; +} +void AbstractCachingFilter::closeCallback(CL_NS(index)::IndexReader* reader, void*){ + SCOPED_LOCK_MUTEX(_internal->cache_LOCK) + _internal->cache.remove(reader); +} + + + + +CachingWrapperFilter::CachingWrapperFilter(Filter* filter, bool deleteFilter): + AbstractCachingFilter() +{ + this->filter = filter; + this->deleteFilter = deleteFilter; +} +CachingWrapperFilter::CachingWrapperFilter(const CachingWrapperFilter& copy): + AbstractCachingFilter(copy) +{ + this->filter = copy.filter->clone(); + this->deleteFilter = true; +} +Filter* CachingWrapperFilter::clone() const{ + return _CLNEW CachingWrapperFilter(*this); +} +TCHAR* CachingWrapperFilter::toString(){ + TCHAR* fs = filter->toString(); + int len = _tcslen(fs)+23; + TCHAR* ret = _CL_NEWARRAY(TCHAR,len); + _sntprintf(ret,len,_T("CachingWrapperFilter(%s)"),fs); + _CLDELETE_CARRAY(fs); + return ret; +} +BitSet* CachingWrapperFilter::doBits(IndexReader* reader){ + return filter->bits(reader); +} +bool CachingWrapperFilter::doShouldDeleteBitSet( CL_NS(util)::BitSet* bits ){ + return filter->shouldDeleteBitSet(bits); +} +CachingWrapperFilter::~CachingWrapperFilter(){ + if ( deleteFilter ){ + _CLDELETE(filter); + }else + filter=NULL; +} + +CL_NS_END diff --git a/src/core/CLucene/search/CachingWrapperFilter.h b/src/core/CLucene/search/CachingWrapperFilter.h new file mode 100644 index 00000000000..9647c96adec --- /dev/null +++ b/src/core/CLucene/search/CachingWrapperFilter.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_CachingWrapperFilter_ +#define _lucene_search_CachingWrapperFilter_ + +//#include "CLucene/util/BitSet.h" +//#include "CLucene/index/IndexReader.h" +#include "Filter.h" + +CL_NS_DEF(search) +/** + * Wraps another filter's result and caches it. The purpose is to allow + * filters to implement this and allow itself to be cached. Alternatively, + * use the CachingWrapperFilter to cache the filter. + */ +class CLUCENE_EXPORT AbstractCachingFilter: public Filter +{ + struct Internal; + Internal* _internal; + void closeCallback(CL_NS(index)::IndexReader* reader, void* param); +protected: + AbstractCachingFilter( const AbstractCachingFilter& copy ); + virtual CL_NS(util)::BitSet* doBits( CL_NS(index)::IndexReader* reader ) = 0; + virtual bool doShouldDeleteBitSet( CL_NS(util)::BitSet* /*bits*/ ){ return false; } + AbstractCachingFilter(); +public: + virtual ~AbstractCachingFilter(); + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + virtual Filter *clone() const = 0; + virtual TCHAR *toString() = 0; + + bool shouldDeleteBitSet( const CL_NS(util)::BitSet* /*bits*/ ) const{ return false; } +}; + +/** + * Wraps another filter's result and caches it. The purpose is to allow + * filters to simply filter, and then wrap with this class to add + * caching, keeping the two concerns decoupled yet composable. + */ +class CLUCENE_EXPORT CachingWrapperFilter: public AbstractCachingFilter +{ +private: + Filter* filter; + bool deleteFilter; +protected: + CachingWrapperFilter( const CachingWrapperFilter& copy ); + CL_NS(util)::BitSet* doBits( CL_NS(index)::IndexReader* reader ); + bool doShouldDeleteBitSet( CL_NS(util)::BitSet* bits ); +public: + CachingWrapperFilter( Filter* filter, bool deleteFilter=true ); + ~CachingWrapperFilter(); + + Filter *clone() const; + TCHAR *toString(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/ChainedFilter.cpp b/src/core/CLucene/search/ChainedFilter.cpp new file mode 100644 index 00000000000..872147379c7 --- /dev/null +++ b/src/core/CLucene/search/ChainedFilter.cpp @@ -0,0 +1,219 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_ApiHeader.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/index/IndexReader.h" +#include "ChainedFilter.h" + +CL_NS_DEF(search) +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) + + +ChainedFilter::ChainedFilter( Filter ** _filters, int _op ): + Filter(), + filters(_filters), + logicArray(NULL), + logic(_op) +{ +} +ChainedFilter::ChainedFilter( Filter** _filters, int* _array ): + Filter(), + filters(_filters), + logicArray(_array), + logic(-1) +{ +} +ChainedFilter::ChainedFilter( const ChainedFilter& copy ) : + Filter(copy), + logicArray( copy.logicArray ), + logic( copy.logic ) +{ + filters = copy.filters; +} +ChainedFilter::~ChainedFilter(void) +{ + +} + +Filter* ChainedFilter::clone() const { + return _CLNEW ChainedFilter(*this ); +} + +const TCHAR* ChainedFilter::getLogicString(int logic){ + if ( logic == ChainedFilter::OR ) + return _T("OR"); + else if ( logic == ChainedFilter::AND ) + return _T("AND"); + else if ( logic == ChainedFilter::ANDNOT ) + return _T("ANDNOT"); + else if ( logic == ChainedFilter::XOR ) + return _T("XOR"); + else if ( logic >= ChainedFilter::USER ){ + return _T("USER"); + } + return _T(""); +} + +TCHAR* ChainedFilter::toString() +{ + + Filter** filter = filters; + + StringBuffer buf(_T("ChainedFilter: [")); + int* la = logicArray; + while(*filter ) + { + if ( filter != filters ) + buf.appendChar(' '); + buf.append(getLogicString(logic==-1?*la:logic)); + buf.appendChar(' '); + + TCHAR* filterstr = (*filter)->toString(); + buf.append(filterstr); + _CLDELETE_ARRAY( filterstr ); + + filter++; + if ( logic == -1 ) + la++; + } + + buf.appendChar(']'); + + return buf.toString(); +} + + +/** Returns a BitSet with true for documents which should be permitted in +search results, and false for those that should not. */ +BitSet* ChainedFilter::bits( IndexReader* reader ) +{ + if( logic != -1 ) + return bits( reader, logic ); + else if( logicArray != NULL ) + return bits( reader, logicArray ); + else + return bits( reader, DEFAULT ); +} + + +BitSet* ChainedFilter::bits( IndexReader* reader, int logic ) +{ + BitSet* bts = NULL; + + Filter** filter = filters; + + // see discussion at top of file + if( *filter ) { + BitSet* tmp = (*filter)->bits( reader ); + if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then + bts = tmp; //we can safely call it our own + else if ( tmp == NULL ){ + int32_t len = reader->maxDoc(); + bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_ + for (int32_t i=0;iset(i); + }else{ + bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it. + } + filter++; + } + else + bts = _CLNEW BitSet( reader->maxDoc() ); + + while( *filter ) { + doChain( bts, reader, logic, *filter ); + filter++; + } + + return bts; +} + + +BitSet* ChainedFilter::bits( IndexReader* reader, int* _logicArray ) +{ + BitSet* bts = NULL; + + Filter** filter = filters; + int* logic = _logicArray; + + // see discussion at top of file + if( *filter ) { + BitSet* tmp = (*filter)->bits( reader ); + if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then + bts = tmp; //we can safely call it our own + else if ( tmp == NULL ){ + int32_t len = reader->maxDoc(); + bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_ + for (int32_t i=0;iset(i); //todo: this could mean that we can skip certain types of filters + } + else + { + bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it. + } + filter++; + logic++; + } + else + bts = _CLNEW BitSet( reader->maxDoc() ); + + while( *filter ) { + doChain( bts, reader, *logic, *filter ); + filter++; + logic++; + } + + return bts; +} + +void ChainedFilter::doUserChain( CL_NS(util)::BitSet* /*chain*/, CL_NS(util)::BitSet* /*filter*/, int /*logic*/ ){ + _CLTHROWA(CL_ERR_Runtime,"User chain logic not implemented by superclass"); +} + +BitSet* ChainedFilter::doChain( BitSet* resultset, IndexReader* reader, int logic, Filter* filter ) +{ + BitSet* filterbits = filter->bits( reader ); + int32_t maxDoc = reader->maxDoc(); + int32_t i=0; + if ( logic >= ChainedFilter::USER ){ + doUserChain(resultset,filterbits,logic); + }else{ + switch( logic ) + { + case OR: + for( i=0; i < maxDoc; i++ ) + resultset->set( i, (resultset->get(i) || (filterbits==NULL || filterbits->get(i) ))?1:0 ); + break; + case AND: + for( i=0; i < maxDoc; i++ ) + resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i) ))?1:0 ); + break; + case ANDNOT: + for( i=0; i < maxDoc; i++ ) + resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i)))?0:1 ); + break; + case XOR: + for( i=0; i < maxDoc; i++ ) + resultset->set( i, resultset->get(i) ^ ((filterbits==NULL || filterbits->get(i) )?1:0) ); + break; + default: + doChain( resultset, reader, DEFAULT, filter ); + } + } + + if ( filter->shouldDeleteBitSet(filterbits) ) + _CLDELETE( filterbits ); + + return resultset; +} + +CL_NS_END diff --git a/src/core/CLucene/search/ChainedFilter.h b/src/core/CLucene/search/ChainedFilter.h new file mode 100644 index 00000000000..e7047cdb1f6 --- /dev/null +++ b/src/core/CLucene/search/ChainedFilter.h @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_ChainedFilter_ +#define _lucene_search_ChainedFilter_ + +//#include "CLucene/index/IndexReader.h" +//#include "CLucene/util/BitSet.h" +#include "Filter.h" + +CL_NS_DEF(search) + +/* +Discussion - brian@unixpoet.com + +From ChainedFilter.java: + +... + +// First AND operation takes place against a completely false +// bitset and will always return zero results. Thanks to +// Daniel Armbrust for pointing this out and suggesting workaround. + +if (logic[0] == AND) +{ + result = (BitSet) chain[i].bits(reader).clone(); + ++i; +} + +... + +The observation is correct and it was buggy. The problem is that the same +issue remains for the ANDNOT logic op but with the inverse result: all bits +set to 1. The result of the other ops, i.e. OR, AND, XOR for the first filter +ends up just copying the bitset of the first filter (explicitly in the case of the AND). + +Why not do the same for the NAND? This will have the side effect of rendering the first op +in the logic array superflous - not a big problem. + +The only "problem" is that we will return different results then the Java +Lucene code - though I prefer CLucene to be a correct implementation and only maintain +API compat rather than full 100% compat with Lucene. +*/ +class CLUCENE_EXPORT ChainedFilter: public Filter +{ +public: + LUCENE_STATIC_CONSTANT(int, OR = 0); //set current bit if the chain is set OR if the filter bit is set + LUCENE_STATIC_CONSTANT(int, AND = 1); //set current bit if the chain is set AND the filter bit is set + LUCENE_STATIC_CONSTANT(int, ANDNOT = 2); //set current bit if the chain is not set AND the filter bit is not set + LUCENE_STATIC_CONSTANT(int, XOR = 3); //set current bit if the chain is set OR the filter bit is set BUT not both is set + + LUCENE_STATIC_CONSTANT(int, USER = 5); //add this value to user defined value, then override doUserChain + + LUCENE_STATIC_CONSTANT(int, DEFAULT = OR); + +protected: + Filter **filters; + int *logicArray; + int logic; + + ChainedFilter( const ChainedFilter& copy ); + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader, int logic ); + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader, int* logicArray ); + CL_NS(util)::BitSet* doChain( CL_NS(util)::BitSet* result, CL_NS(index)::IndexReader* reader, int logic, Filter* filter ); + + virtual void doUserChain( CL_NS(util)::BitSet* chain, CL_NS(util)::BitSet* filter, int logic ); + virtual const TCHAR* getLogicString(int logic); +public: + ChainedFilter( Filter** filters, int op = DEFAULT ); + ChainedFilter( Filter** filters, int* _array ); + virtual ~ChainedFilter(); + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + virtual Filter* clone() const; + + TCHAR* toString(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Compare.cpp b/src/core/CLucene/search/Compare.cpp new file mode 100644 index 00000000000..bb85951989b --- /dev/null +++ b/src/core/CLucene/search/Compare.cpp @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Compare.h" +#include "SearchHeader.h" + +CL_NS_DEF(search) + +ScoreDocComparators::ScoreDocComparators(){} +ScoreDocComparators::~ScoreDocComparators(){ +} + +int32_t ScoreDocComparators::Relevance::compare (struct ScoreDoc* i, struct ScoreDoc* j) { + if (i->score > j->score) return -1; + if (i->score < j->score) return 1; + return 0; +} +CL_NS(util)::Comparable* ScoreDocComparators::Relevance::sortValue (struct ScoreDoc* i) { + return _CLNEW CL_NS(util)::Compare::Float (i->score); +} +int32_t ScoreDocComparators::Relevance::sortType() { + return SortField::DOCSCORE; +} + + + +ScoreDocComparators::IndexOrder::IndexOrder(): + ScoreDocComparator() +{ + +} +int32_t ScoreDocComparators::IndexOrder::compare (struct ScoreDoc* i, struct ScoreDoc* j) { + if (i->doc < j->doc) return -1; + if (i->doc > j->doc) return 1; + return 0; +} +CL_NS(util)::Comparable* ScoreDocComparators::IndexOrder::sortValue (struct ScoreDoc* i) { + return _CLNEW CL_NS(util)::Compare::Int32(i->doc); +} +int32_t ScoreDocComparators::IndexOrder::sortType() { + return SortField::DOC; +} + + + +ScoreDocComparators::String::String(FieldCache::StringIndex* index, int32_t len) +{ + this->length = len; + this->index = index; +} + +int32_t ScoreDocComparators::String::compare (struct ScoreDoc* i, struct ScoreDoc* j) { + CND_PRECONDITION(i->docdoc>=length") + CND_PRECONDITION(j->docdoc>=length") + if (index->order[i->doc] < index->order[j->doc]) return -1; + if (index->order[i->doc] > index->order[j->doc]) return 1; + return 0; +} + +CL_NS(util)::Comparable* ScoreDocComparators::String::sortValue (struct ScoreDoc* i) { + return _CLNEW CL_NS(util)::Compare::TChar(index->lookup[index->order[i->doc]]); +} + +int32_t ScoreDocComparators::String::sortType() { + return SortField::STRING; +} + + +ScoreDocComparators::Int32::Int32(int32_t* fieldOrder, int32_t len) +{ + this->fieldOrder = fieldOrder; + this->length = len; +} + + +int32_t ScoreDocComparators::Int32::compare (struct ScoreDoc* i, struct ScoreDoc* j) { + CND_PRECONDITION(i->docdoc>=length") + CND_PRECONDITION(j->docdoc>=length") + if (fieldOrder[i->doc] < fieldOrder[j->doc]) return -1; + if (fieldOrder[i->doc] > fieldOrder[j->doc]) return 1; + return 0; +} + +CL_NS(util)::Comparable* ScoreDocComparators::Int32::sortValue (struct ScoreDoc* i) { + CND_PRECONDITION(i->docdoc>=length") + return _CLNEW CL_NS(util)::Compare::Int32(fieldOrder[i->doc]); +} + +int32_t ScoreDocComparators::Int32::sortType() { + return SortField::INT; +} + +ScoreDocComparators::Float::Float(float_t* fieldOrder, int32_t len) +{ + this->fieldOrder = fieldOrder; + this->length = len; +} + +int32_t ScoreDocComparators::Float::compare (struct ScoreDoc* i, struct ScoreDoc* j) { + CND_PRECONDITION(i->docdoc>=length") + CND_PRECONDITION(j->docdoc>=length") + if (fieldOrder[i->doc] < fieldOrder[j->doc]) return -1; + if (fieldOrder[i->doc] > fieldOrder[j->doc]) return 1; + return 0; +} + +CL_NS(util)::Comparable* ScoreDocComparators::Float::sortValue (struct ScoreDoc* i) { + CND_PRECONDITION(i->docdoc>=length") + return _CLNEW CL_NS(util)::Compare::Float(fieldOrder[i->doc]); +} + +int32_t ScoreDocComparators::Float::sortType() { + return SortField::FLOAT; +} + +CL_NS_END diff --git a/src/core/CLucene/search/Compare.h b/src/core/CLucene/search/Compare.h new file mode 100644 index 00000000000..e3122a53078 --- /dev/null +++ b/src/core/CLucene/search/Compare.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Compare_ +#define _lucene_search_Compare_ + + +//#include "FieldSortedHitQueue.h" +#include "Sort.h" +#include "FieldCache.h" + +CL_NS_DEF(search) + + +class CLUCENE_EXPORT ScoreDocComparators:LUCENE_BASE { +protected: + ScoreDocComparators(); +public: + ~ScoreDocComparators(); + + class CLUCENE_EXPORT Relevance:public ScoreDocComparator { + public: + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j); + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i); + int32_t sortType(); + }; + + class CLUCENE_EXPORT IndexOrder:public ScoreDocComparator{ + public: + IndexOrder(); + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j); + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i); + int32_t sortType(); + }; + + + class CLUCENE_EXPORT String: public ScoreDocComparator { + FieldCache::StringIndex* index; + int32_t length; + public: + String(FieldCache::StringIndex* index, int32_t len); + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j); + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i); + + int32_t sortType(); + }; + + class CLUCENE_EXPORT Int32:public ScoreDocComparator{ + int32_t* fieldOrder; + int32_t length; + public: + Int32(int32_t* fieldOrder, int32_t len); + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j); + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i); + int32_t sortType(); + }; + + class CLUCENE_EXPORT Float:public ScoreDocComparator { + float_t* fieldOrder; + int32_t length; + public: + Float(float_t* fieldOrder, int32_t len); + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j); + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i); + int32_t sortType(); + }; +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/ConjunctionScorer.cpp b/src/core/CLucene/search/ConjunctionScorer.cpp new file mode 100644 index 00000000000..317faaa00b1 --- /dev/null +++ b/src/core/CLucene/search/ConjunctionScorer.cpp @@ -0,0 +1,133 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_ConjunctionScorer.h" +#include "Similarity.h" +#include "CLucene/util/_Arrays.h" +#include +#include + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + ConjunctionScorer::ConjunctionScorer(Similarity* similarity, ScorersType* _scorers): + Scorer(similarity), + firstTime(true), + more(false), + coord(0.0), + lastDoc(-1) + { + this->scorers = _CLNEW CL_NS(util)::ObjectArray(_scorers->size()); + _scorers->toArray(this->scorers->values); + coord = getSimilarity()->coord(this->scorers->length, this->scorers->length); + } + ConjunctionScorer::ConjunctionScorer(Similarity* similarity, const CL_NS(util)::ArrayBase* _scorers): + Scorer(similarity), + firstTime(true), + more(false), + coord(0.0), + lastDoc(-1) + { + this->scorers = _CLNEW CL_NS(util)::ObjectArray(_scorers->length); + memcpy(this->scorers->values, _scorers->values, _scorers->length * sizeof(Scorer*)); + coord = getSimilarity()->coord(this->scorers->length, this->scorers->length); + } + ConjunctionScorer::~ConjunctionScorer(){ + _CLLDELETE(scorers); + } + + TCHAR* ConjunctionScorer::toString(){ + return stringDuplicate(_T("ConjunctionScorer")); + } + + int32_t ConjunctionScorer::doc() const{ + return lastDoc; + } + + bool ConjunctionScorer::next() { + if (firstTime) { + init(0); + } else if (more) { + more = scorers->values[(scorers->length-1)]->next(); + } + return doNext(); + } + + bool ConjunctionScorer::doNext() { + int32_t first=0; + Scorer* lastScorer = scorers->values[scorers->length-1]; + Scorer* firstScorer; + while (more && (firstScorer=scorers->values[first])->doc() < (lastDoc=lastScorer->doc())) { + more = firstScorer->skipTo(lastDoc); + lastScorer = firstScorer; + first = (first == (scorers->length-1)) ? 0 : first+1; + } + return more; + } + + bool ConjunctionScorer::skipTo(int32_t target) { + if (firstTime) + return init(target); + else if (more) + more = scorers->values[(scorers->length-1)]->skipTo(target); + return doNext(); + } + int ConjunctionScorer_sort(const void* _elem1, const void* _elem2){ + const Scorer* elem1 = *(const Scorer**)_elem1; + const Scorer* elem2 = *(const Scorer**)_elem2; + return elem1->doc() - elem2->doc(); + } + + bool ConjunctionScorer::init(int32_t target) { + firstTime = false; + more = scorers->length>1; + + + for (size_t i=0; ilength; i++) { + more = target==0 ? scorers->values[i]->next() : scorers->values[i]->skipTo(target); + if (!more) + return false; + } + + // Sort the array the first time... + // We don't need to sort the array in any future calls because we know + // it will already start off sorted (all scorers on same doc). + + // note that this comparator is not consistent with equals! + qsort(scorers->values,scorers->length, sizeof(Scorer*), ConjunctionScorer_sort); + + doNext(); + + // If first-time skip distance is any predictor of + // scorer sparseness, then we should always try to skip first on + // those scorers. + // Keep last scorer in it's last place (it will be the first + // to be skipped on), but reverse all of the others so that + // they will be skipped on in order of original high skip. + int32_t end=(scorers->length-1)-1; + for (int32_t i=0; i<(end>>1); i++) { + Scorer* tmp = scorers->values[i]; + scorers->values[i] = scorers->values[end-i]; + scorers->values[end-i] = tmp; + } + return more; + } + + float_t ConjunctionScorer::score(){ + float_t sum = 0.0f; + for (size_t i = 0; i < scorers->length; i++) { + sum += scorers->values[i]->score(); + } + return sum * coord; + } + Explanation* ConjunctionScorer::explain(int32_t /*doc*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: ConjunctionScorer::explain"); + } + + +CL_NS_END diff --git a/src/core/CLucene/search/ConstantScoreQuery.cpp b/src/core/CLucene/search/ConstantScoreQuery.cpp new file mode 100644 index 00000000000..c47b3a441d3 --- /dev/null +++ b/src/core/CLucene/search/ConstantScoreQuery.cpp @@ -0,0 +1,313 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "ConstantScoreQuery.h" + +#include "SearchHeader.h" +#include "Scorer.h" +#include "RangeFilter.h" +#include "Similarity.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/Misc.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + +class ConstantScorer : public Scorer { + BitSet* bits; + const float_t theScore; + int32_t _doc; + +public: + ConstantScorer(Similarity* similarity, IndexReader* reader, Weight* w, Filter* filter) : Scorer(similarity), + bits(filter->bits(reader)), theScore(w->getValue()), _doc(-1) + { + } + virtual ~ConstantScorer() { + _CLLDELETE(bits); + } + + bool next() { + _doc = bits->nextSetBit(_doc+1); + return _doc >= 0; + } + + int32_t doc() const { + return _doc; + } + + float_t score() { + return theScore; + } + + bool skipTo(int32_t target) { + _doc = bits->nextSetBit(target); + return _doc >= 0; + } + + Explanation* explain(int32_t /*doc*/) { + _CLTHROWA(CL_ERR_UnsupportedOperation, "Unsupported operation at ConstantScoreQuery::explain"); + } + + TCHAR* toString(){ + return STRDUP_TtoT(_T("ConstantScorer")); + } + + friend class ConstantWeight; +}; + +class ConstantWeight : public Weight { +private: + Similarity* similarity; + float_t queryNorm; + float_t queryWeight; + const ConstantScoreQuery* parentQuery; + +public: + ConstantWeight(ConstantScoreQuery* enclosingInstance, Searcher* searcher) : + similarity(enclosingInstance->getSimilarity(searcher)), + queryNorm(0), queryWeight(0), + parentQuery(enclosingInstance) + { + } + virtual ~ConstantWeight(){} + + Query* getQuery() { + return (Query*)parentQuery; + } + + float_t getValue() { + return queryWeight; + } + + float_t sumOfSquaredWeights() { + queryWeight = parentQuery->getBoost(); + return queryWeight * queryWeight; + } + + void normalize(float_t norm) { + this->queryNorm = norm; + queryWeight *= this->queryNorm; + } + + Scorer* scorer(IndexReader* reader) { + return _CLNEW ConstantScorer(similarity, reader, this, parentQuery->filter); + } + + Explanation* explain(IndexReader* reader, int32_t doc) { + ConstantScorer* cs = (ConstantScorer*)scorer(reader); + bool exists = cs->bits->get(doc); + _CLDELETE(cs); + + ComplexExplanation* result = _CLNEW ComplexExplanation(); + + if (exists) { + StringBuffer buf(100); + buf.append(_T("ConstantScoreQuery(")); + + TCHAR* tmp = parentQuery->filter->toString(); + buf.append(tmp); + _CLDELETE_LCARRAY(tmp); + + buf.append(_T("), product of:")); + + result->setDescription(buf.getBuffer()); + result->setValue(queryWeight); + result->setMatch(true); + result->addDetail(_CLNEW Explanation(parentQuery->getBoost(), _T("boost"))); + result->addDetail(_CLNEW Explanation(queryNorm, _T("queryNorm"))); + } else { + StringBuffer buf(100); + buf.append(_T("ConstantScoreQuery(")); + + TCHAR* tmp = parentQuery->filter->toString(); + buf.append(tmp); + _CLDELETE_LCARRAY(tmp); + + buf.append(_T(") doesn't match id ")); + buf.appendInt(doc); + + result->setDescription(buf.getBuffer()); + result->setValue(0); + result->setMatch(true); + } + + _CLLDELETE(cs); + return result; + } +}; + +ConstantScoreQuery::ConstantScoreQuery(Filter* _filter) : filter(_filter) { +} + +ConstantScoreQuery::~ConstantScoreQuery() { + _CLLDELETE(filter); +} + +Filter* ConstantScoreQuery::getFilter() const { + return filter; +} + +Query* ConstantScoreQuery::rewrite(IndexReader* reader) { + return this; +} + +void ConstantScoreQuery::extractTerms( TermSet * termset ) const +{ + // OK to not add any terms when used for MultiSearcher, + // but may not be OK for highlighting +} + +Weight* ConstantScoreQuery::_createWeight(Searcher* searcher) { + return _CLNEW /*ConstantScoreQuery::*/ConstantWeight(this, searcher); +} + +TCHAR* ConstantScoreQuery::toString(const TCHAR* /*field*/) const +{ + StringBuffer buf; + buf.append(_T("ConstantScore(")); + TCHAR* tmp = filter->toString(); + buf.append(tmp); + _CLLDELETE(tmp); + buf.appendBoost(getBoost()); + buf.appendChar(_T(')')); + return buf.giveBuffer(); +} + +// TODO: Filter is missing an equals() function, hence this equals() is incomplete +bool ConstantScoreQuery::equals(Query* o) const { + if (this == o) return true; + if (!(o->instanceOf("ConstantScoreQuery"))) return false; + ConstantScoreQuery* other = (ConstantScoreQuery*)o; + return this->getBoost()==other->getBoost() + /*&& filter->equals(other->filter)*/; +} + +// TODO: Filter is missing hashCode() +size_t ConstantScoreQuery::hashCode() const { + // Simple add is OK since no existing filter hashcode has a float component. + //return filter->hashCode() + FloatToIntBits(getBoost()); + return 0; +} + +ConstantScoreQuery::ConstantScoreQuery( const ConstantScoreQuery& copy ) : filter(copy.getFilter()->clone()) +{ +} + +const char* ConstantScoreQuery::getObjectName() const { return "ConstantScoreQuery"; } +Query* ConstantScoreQuery::clone() const{ + return _CLNEW ConstantScoreQuery(*this); +} + +ConstantScoreRangeQuery::ConstantScoreRangeQuery( const ConstantScoreRangeQuery& copy ): + fieldName(const_cast(CLStringIntern::intern(copy.fieldName))), + lowerVal(copy.lowerVal == nullptr ? nullptr : STRDUP_TtoT(copy.lowerVal)), + upperVal(copy.upperVal == nullptr ? nullptr : STRDUP_TtoT(copy.upperVal)), + includeLower(copy.includeLower),includeUpper(copy.includeUpper) +{ +} + +ConstantScoreRangeQuery::ConstantScoreRangeQuery(const TCHAR* _fieldName, const TCHAR* _lowerVal, const TCHAR* _upperVal, + bool _includeLower, bool _includeUpper) : fieldName(NULL), lowerVal(NULL), upperVal(NULL) +{ + // do a little bit of normalization... + // open ended range queries should always be inclusive. + if (_lowerVal==NULL) { + _includeLower=true; + } else if (_includeLower && _tcscmp(_lowerVal, _T(""))==0) { + _lowerVal=NULL; + } + if (_upperVal==NULL) { + _includeUpper=true; + } + + this->fieldName = const_cast(CLStringIntern::intern(_fieldName)); // intern it, just like terms... + if (_lowerVal != NULL) + this->lowerVal = STRDUP_TtoT(_lowerVal); + if (_upperVal != NULL) + this->upperVal = STRDUP_TtoT(_upperVal); + this->includeLower = _includeLower; + this->includeUpper = _includeUpper; +} +ConstantScoreRangeQuery::~ConstantScoreRangeQuery(){ + _CLDELETE_LCARRAY(lowerVal); + _CLDELETE_LCARRAY(upperVal); + CLStringIntern::unintern(this->fieldName); +} + +Query* ConstantScoreRangeQuery::rewrite(CL_NS(index)::IndexReader* reader) { + // Map to RangeFilter semantics which are slightly different... + const TCHAR* lowerSafe = lowerVal!=NULL?lowerVal:_T(""); + RangeFilter* rangeFilt = _CLNEW RangeFilter(fieldName, + lowerSafe, + upperVal, + (_tcscmp(lowerSafe, _T(""))==0)?false:includeLower, + upperVal==NULL?false:includeUpper); + Query* q = _CLNEW ConstantScoreQuery(rangeFilt); + q->setBoost(getBoost()); + return q; +} + +TCHAR* ConstantScoreRangeQuery::toString(const TCHAR* field) const +{ + StringBuffer buffer(30); + if (_tcscmp(getField(), field) != 0) + { + buffer.append(getField()); + buffer.appendChar(_T(':')); + } + buffer.appendChar(includeLower ? _T('[') : _T('{')); + buffer.append(lowerVal != NULL ? lowerVal : _T("*")); + buffer.append(_T(" TO ")); + buffer.append(upperVal != NULL ? upperVal : _T("*")); + buffer.appendChar(includeUpper ? _T(']') : _T('}')); + buffer.appendBoost(getBoost()); + return buffer.giveBuffer(); +} + +bool ConstantScoreRangeQuery::equals(Query* o) const { + if (this == o) return true; + if (!(o->instanceOf("ConstantScoreRangeQuery"))) return false; + ConstantScoreRangeQuery* other = (ConstantScoreRangeQuery*) o; + + if (this->fieldName != other->fieldName // interned comparison + || this->includeLower != other->includeLower + || this->includeUpper != other->includeUpper + ) { return false; } + if (this->lowerVal != NULL ? _tcscmp(this->lowerVal, other->lowerVal) != 0 : other->lowerVal != NULL) return false; + if (this->upperVal != NULL ? _tcscmp(this->upperVal, other->upperVal) != 0 : other->upperVal != NULL) return false; + return this->getBoost() == other->getBoost(); +} + +// TODO: Complete this +size_t ConstantScoreRangeQuery::hashCode() const +{ + int32_t h = Similarity::floatToByte( getBoost() ) ^ Misc::thashCode( fieldName ); + // hashCode of "" is 0, so don't use that for null... + + h ^= ( lowerVal != NULL ) ? Misc::thashCode( lowerVal ) : 0x965a965a; + // don't just XOR upperVal with out mixing either it or h, as it will cancel + // out lowerVal if they are equal. + + h ^= (h << 17) | (h >> 16); // a reversible (one to one) 32 bit mapping mix + h ^= (upperVal != NULL) ? Misc::thashCode( upperVal ) : 0x5a695a69; + h ^= (includeLower ? 0x665599aa : 0) ^ (includeUpper ? 0x99aa5566 : 0); + + return h; +} + +const char* ConstantScoreRangeQuery::getObjectName() const { return "ConstantScoreRangeQuery"; } +Query* ConstantScoreRangeQuery::clone() const{ + return _CLNEW ConstantScoreRangeQuery(*this); +} + +CL_NS_END + diff --git a/src/core/CLucene/search/ConstantScoreQuery.h b/src/core/CLucene/search/ConstantScoreQuery.h new file mode 100644 index 00000000000..e6278db280f --- /dev/null +++ b/src/core/CLucene/search/ConstantScoreQuery.h @@ -0,0 +1,125 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_ConstantScoreQuery_ +#define _lucene_search_ConstantScoreQuery_ + +CL_CLASS_DEF(index,IndexReader) + +#include "Query.h" +#include "Filter.h" +#include "Explanation.h" + +CL_NS_DEF(search) + +/** + * A query that wraps a filter and simply returns a constant score equal to the + * query boost for every document in the filter. + * + */ +class CLUCENE_EXPORT ConstantScoreQuery : public Query { +protected: + Filter* filter; + +public: + /** + * Constructs a new ConstantScoreQuery, and takes ownership of the filter object + * + * @memory this object consumes _filter + */ + ConstantScoreQuery(Filter* _filter); + virtual ~ConstantScoreQuery(); + + /** Returns the encapsulated filter */ + Filter* getFilter() const; + + Query* rewrite(CL_NS(index)::IndexReader* reader); + + /** Constant score query does not return any terms */ + void extractTerms( TermSet * termset ) const; + +protected: + Weight* _createWeight(Searcher* searcher); + +public: + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + + /** Returns true if o is equal to this. */ + bool equals(Query* o) const; + + /** Returns a hash code value for this object. */ + size_t hashCode() const; + + const char* getObjectName() const; + static const char* getClassName(){ return "ConstantScoreQuery"; } + Query* clone() const; + + friend class ConstantWeight; + +protected: + ConstantScoreQuery( const ConstantScoreQuery& copy ); +}; + + +/** + * A range query that returns a constant score equal to its boost for + * all documents in the range. + *

+ * It does not have an upper bound on the number of clauses covered in the range. + *

+ * If an endpoint is null, it is said to be "open". + * Either or both endpoints may be open. Open endpoints may not be exclusive + * (you can't select all but the first or last term without explicitly specifying the term to exclude.) + * + */ +class CLUCENE_EXPORT ConstantScoreRangeQuery : public Query +{ +private: + TCHAR* fieldName; + TCHAR* lowerVal; + TCHAR* upperVal; + bool includeLower; + bool includeUpper; + +public: + ConstantScoreRangeQuery(const TCHAR* _fieldName, const TCHAR* _lowerVal, const TCHAR* _upperVal, + bool _includeLower, bool _includeUpper); + virtual ~ConstantScoreRangeQuery(); + + /** Returns the field name for this query */ + TCHAR* getField() const { return fieldName; } + /** Returns the value of the lower endpoint of this range query, null if open ended */ + TCHAR* getLowerVal() const { return lowerVal; } + /** Returns the value of the upper endpoint of this range query, null if open ended */ + TCHAR* getUpperVal() const { return upperVal; } + /** Returns true if the lower endpoint is inclusive */ + bool includesLower() const { return includeLower; } + /** Returns true if the upper endpoint is inclusive */ + bool includesUpper() const { return includeUpper; } + + Query* rewrite(CL_NS(index)::IndexReader* reader); + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + + /** Returns true if o is equal to this. */ + bool equals(Query* o) const; + + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + const char* getObjectName() const; + static const char* getClassName(){ return "ConstantScoreRangeQuery"; } + Query* clone() const; +protected: + ConstantScoreRangeQuery( const ConstantScoreRangeQuery& copy ); +}; + +CL_NS_END + +#endif + diff --git a/src/core/CLucene/search/DateFilter.cpp b/src/core/CLucene/search/DateFilter.cpp new file mode 100644 index 00000000000..a8a2825429c --- /dev/null +++ b/src/core/CLucene/search/DateFilter.cpp @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "DateFilter.h" +#include "CLucene/document/DateField.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/Terms.h" +#include "CLucene/util/BitSet.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) +CL_NS_DEF(search) + + DateFilter::~DateFilter(){ + _CLDECDELETE( start ); + _CLDECDELETE( end ); + } + + DateFilter::DateFilter(const DateFilter& copy): + start( _CL_POINTER(copy.start) ), + end ( _CL_POINTER(copy.end) ) + { + } + + /** Constructs a filter for field f matching times between + from and to. */ + DateFilter::DateFilter(const TCHAR* f, int64_t from, int64_t to) + { + TCHAR* tmp = DateField::timeToString(from); + start = _CLNEW Term(f, tmp); + _CLDELETE_CARRAY(tmp); + + tmp = DateField::timeToString(to); + end = _CLNEW Term(start, tmp); + _CLDELETE_CARRAY(tmp); + } + + /** Constructs a filter for field f matching times before + time. */ + DateFilter* DateFilter::Before(const TCHAR* field, int64_t time) { + return _CLNEW DateFilter(field, 0,time); + } + + /** Constructs a filter for field f matching times after + time. */ + DateFilter* DateFilter::After(const TCHAR* field, int64_t time) { + return _CLNEW DateFilter(field,time, DATEFIELD_DATE_MAX ); + } + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + BitSet* DateFilter::bits(IndexReader* reader) { + BitSet* bts = _CLNEW BitSet(reader->maxDoc()); + + TermEnum* enumerator = reader->terms(start); + if (enumerator->term(false) == NULL){ + _CLDELETE(enumerator); + return bts; + } + TermDocs* termDocs = reader->termDocs(); + + try { + while (enumerator->term(false)->compareTo(end) <= 0) { + termDocs->seek(enumerator->term(false)); + while (termDocs->next()) { + bts->set(termDocs->doc()); + } + if (!enumerator->next()) { + break; + } + } + } _CLFINALLY ( + termDocs->close(); + _CLDELETE(termDocs); + enumerator->close(); + _CLDELETE(enumerator); + ); + return bts; + } + + Filter* DateFilter::clone() const{ + return _CLNEW DateFilter(*this); + } + + TCHAR* DateFilter::toString(){ + size_t len = _tcslen(start->field()) + start->textLength() + end->textLength() + 8; + TCHAR* ret = _CL_NEWARRAY(TCHAR,len); + ret[0]=0; + _sntprintf(ret,len,_T("%s: [%s-%s]"), start->field(),start->text(),end->text()); + return ret; + } +CL_NS_END diff --git a/src/core/CLucene/search/DateFilter.h b/src/core/CLucene/search/DateFilter.h new file mode 100644 index 00000000000..91b3da8d1b5 --- /dev/null +++ b/src/core/CLucene/search/DateFilter.h @@ -0,0 +1,61 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_DateFilter_ +#define _lucene_search_DateFilter_ + + +//#include "CLucene/document/DateField.h" +CL_CLASS_DEF(index,Term) +//#include "CLucene/index/Terms.h" +//#include "CLucene/index/IndexReader.h" +//#include "CLucene/util/BitSet.h" +#include "Filter.h" + +CL_NS_DEF(search) + + +// Deprecated. Instead, use RangeFilter combined with DateTools. + + + /** + * A Filter that restricts search results to a range of time. + * + *

For this to work, documents must have been indexed with a + * {@link DateField}. + */ + class CLUCENE_EXPORT DateFilter: public Filter { + private: + CL_NS(index)::Term* start; + CL_NS(index)::Term* end; + + protected: + DateFilter(const DateFilter& copy); + public: + ~DateFilter(); + + /** Constructs a filter for field f matching times between + from and to. */ + DateFilter(const TCHAR* f, int64_t from, int64_t to); + + /** Constructs a filter for field f matching times before + time. */ + static DateFilter* Before(const TCHAR* field, int64_t time) ; + + /** Constructs a filter for field f matching times after + time. */ + static DateFilter* After(const TCHAR* field, int64_t time) ; + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + CL_NS(util)::BitSet* bits(CL_NS(index)::IndexReader* reader) ; + + Filter* clone() const; + + TCHAR* toString(); + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/DisjunctionSumScorer.cpp b/src/core/CLucene/search/DisjunctionSumScorer.cpp new file mode 100644 index 00000000000..6e45658a64b --- /dev/null +++ b/src/core/CLucene/search/DisjunctionSumScorer.cpp @@ -0,0 +1,201 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_ApiHeader.h" +#include "Scorer.h" +#include "ScorerDocQueue.h" +#include "SearchHeader.h" +#include "Explanation.h" + +#include "CLucene/util/StringBuffer.h" + +#include "_DisjunctionSumScorer.h" + + +CL_NS_DEF(search) + +DisjunctionSumScorer::DisjunctionSumScorer( DisjunctionSumScorer::ScorersType* _subScorers, const int32_t _minimumNrMatchers ) : + Scorer( NULL ), + minimumNrMatchers(_minimumNrMatchers), + scorerDocQueue(NULL), + queueSize(-1), + currentDoc(-1), + currentScore(-1.0f), + nrScorers(0), + _nrMatchers(-1) +{ + if ( minimumNrMatchers <= 0 ) { + _CLTHROWA(CL_ERR_IllegalArgument,"Minimum nr of matchers must be positive"); + } + + nrScorers = _subScorers->size(); + + if ( nrScorers <= 1 ) { + _CLTHROWA(CL_ERR_IllegalArgument,"There must be at least 2 subScorers"); + } + + for ( DisjunctionSumScorer::ScorersType::iterator itr = _subScorers->begin(); itr != _subScorers->end(); itr++ ) { + subScorers.push_back( *itr ); + } +} + +DisjunctionSumScorer::~DisjunctionSumScorer() +{ + _CLLDELETE( scorerDocQueue ); +} + +void DisjunctionSumScorer::score( HitCollector* hc ) +{ + while( next() ) { + hc->collect( currentDoc, currentScore ); + } +} + +bool DisjunctionSumScorer::next() +{ + if ( scorerDocQueue == NULL ) { + initScorerDocQueue(); + } + return ( scorerDocQueue->size() >= minimumNrMatchers ) && advanceAfterCurrent(); +} + +float_t DisjunctionSumScorer::score() +{ + return currentScore; +} +int32_t DisjunctionSumScorer::doc() const +{ + return currentDoc; +} + +int32_t DisjunctionSumScorer::nrMatchers() const +{ + return _nrMatchers; +} + +bool DisjunctionSumScorer::skipTo( int32_t target ) +{ + if ( scorerDocQueue == NULL ) { + initScorerDocQueue(); + } + if ( queueSize < minimumNrMatchers ) { + return false; + } + if ( target <= currentDoc ) { + return true; + } + do { + if ( scorerDocQueue->topDoc() >= target ) { + return advanceAfterCurrent(); + } else if ( !scorerDocQueue->topSkipToAndAdjustElsePop( target )) { + if ( --queueSize < minimumNrMatchers ) { + return false; + } + } + } while ( true ); +} + +TCHAR* DisjunctionSumScorer::toString() +{ + return stringDuplicate(_T("DisjunctionSumScorer")); +} + +Explanation* DisjunctionSumScorer::explain( int32_t doc ){ + Explanation* res = _CLNEW Explanation(); + float_t sumScore = 0.0f; + int32_t nrMatches = 0; + ScorersType::iterator ssi = subScorers.begin(); + while (ssi != subScorers.end()) { + Explanation* es = reinterpret_cast(*ssi)->explain(doc); + if (es->getValue() > 0.0f) { // indicates match + sumScore += es->getValue(); + nrMatches++; + } + res->addDetail(es); + ++ssi; + } + + CL_NS(util)::StringBuffer buf(50); + if (_nrMatchers >= minimumNrMatchers) { + buf.append(_T("sum over at least ")); + buf.appendInt(minimumNrMatchers); + buf.append(_T(" of ")); + buf.appendInt(subScorers.size()); + buf.appendChar(_T(':')); + + res->setValue(sumScore); + res->setDescription(buf.getBuffer()); + } else { + buf.appendInt(nrMatches); + buf.append(_T(" match(es) but at least ")); + buf.appendInt(minimumNrMatchers); + buf.append(_T(" of ")); + buf.appendInt(subScorers.size()); + buf.append(_T(" needed")); + + res->setValue(0.0f); + res->setDescription(buf.getBuffer()); + } + return res; +} + +bool DisjunctionSumScorer::score( HitCollector* hc, const int32_t max ) +{ + while ( currentDoc < max ) { + hc->collect( currentDoc, currentScore ); + if ( !next() ) { + return false; + } + } + return true; +} + +bool DisjunctionSumScorer::advanceAfterCurrent() +{ + do { // repeat until minimum nr of matchers + currentDoc = scorerDocQueue->topDoc(); + currentScore = scorerDocQueue->topScore(); + + _nrMatchers = 1; + do { // Until all subscorers are after currentDoc + if ( !scorerDocQueue->topNextAndAdjustElsePop() ) { + if ( --queueSize == 0 ) { + break; // nothing more to advance, check for last match. + } + } + if ( scorerDocQueue->topDoc() != currentDoc ) { + break; // All remaining subscorers are after currentDoc. + } + currentScore += scorerDocQueue->topScore(); + _nrMatchers++; + } while( true ); + + if ( _nrMatchers >= minimumNrMatchers ) { + return true; + } else if ( queueSize < minimumNrMatchers ) { + return false; + } + } while( true ); +} + +void DisjunctionSumScorer::initScorerDocQueue() +{ + // No need to _CLLDELETE here since this function since this function is only called if scorerDocQueue==NULL + scorerDocQueue = _CLNEW ScorerDocQueue( nrScorers ); + queueSize = 0; + + for ( ScorersType::iterator it = subScorers.begin(); it != subScorers.end(); ++it ) { + Scorer* scorer = (Scorer*)(*it); + if ( scorer->next() ) { // doc() method will be used in scorerDocQueue. + if ( scorerDocQueue->insert( scorer )) { + queueSize++; + } + } + } +} + +CL_NS_END diff --git a/src/core/CLucene/search/ExactPhraseScorer.cpp b/src/core/CLucene/search/ExactPhraseScorer.cpp new file mode 100644 index 00000000000..6856784d995 --- /dev/null +++ b/src/core/CLucene/search/ExactPhraseScorer.cpp @@ -0,0 +1,91 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/Terms.h" +#include "SearchHeader.h" +#include "SearchHeader.h" +#include "Scorer.h" +#include "_ExactPhraseScorer.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + + ExactPhraseScorer::ExactPhraseScorer(Weight* weight, TermPositions** tps, + int32_t* offsets, Similarity* similarity, uint8_t* norms): + PhraseScorer(weight, tps, offsets, similarity, norms){ + //Func - Constructor + //Pre - tps != NULL + // tpsLength >= 0 + // n != NULL + //Post - Instance has been created + + CND_PRECONDITION(tps != NULL,"tps is NULL"); + CND_PRECONDITION(tps[0] != NULL,"tps is NULL"); + //CND_PRECONDITION(n != NULL,"n is NULL") =this is checked already in PhraseScorer + + } + + ExactPhraseScorer::~ExactPhraseScorer(){} + + float_t ExactPhraseScorer::phraseFreq(){ + //Func - Returns the freqency of the phrase + //Pre - first != NULL + // last != NULL + // pq != NULL + // size of the PhraseQueue pq is 0 + //Post - The frequency of the phrase has been returned + + CND_PRECONDITION(first != NULL,"first is NULL"); + CND_PRECONDITION(last != NULL,"last is NULL"); + CND_PRECONDITION(pq != NULL,"pq is NULL"); + CND_PRECONDITION(pq->size()==0,"pq is not empty"); + + // sort list with pq + pq->clear(); + + //Add the nodes of the list of PhrasePositions and store them + //into the PhraseQueue pq so it can used to build + //a list of sorted nodes + for (PhrasePositions* pp = first; pp != NULL; pp = pp->_next) { + //Read the first TermPosition of the current PhrasePositions pp + pp->firstPosition(); + //Store the current PhrasePositions pp into the PhraseQueue pq + pq->put(pp); + } + //pqToList requires that first and last be NULL when it's called. + //This is done at the beginning of pqToList() + //In this case, the nodes of the linked list are referenced by pq (see + //above loop), so we can clear our pointers to the head and tail of the + //linked list without fear of leaking the nodes. + + //rebuild list from pq + pqToList(); + + // for counting how many times the exact phrase is found in current document, + // just count how many times all PhrasePosition's have exactly the same position. + int32_t freq = 0; + do { //find position with all terms + while (first->position < last->position){ //scan forward in first + do{ + if (!first->nextPosition()){ + return (float_t)freq; + } + } while (first->position < last->position); + //Make the current first node the last node in the list + firstToLast(); + } + //all equal: a match has been found + freq++; + } while (last->nextPosition()); + + return (float_t)freq; + } + + TCHAR* ExactPhraseScorer::toString(){ + return stringDuplicate(_T("ExactPhraseScorer")); + } +CL_NS_END diff --git a/src/core/CLucene/search/Explanation.cpp b/src/core/CLucene/search/Explanation.cpp new file mode 100644 index 00000000000..57a77ba0fb5 --- /dev/null +++ b/src/core/CLucene/search/Explanation.cpp @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Explanation.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_USE(util) +CL_NS_DEF(search) + + +Explanation::Explanation(float_t _value, const TCHAR* _description):value(_value),details(NULL) +{ + _tcsncpy(this->description,_description,LUCENE_SEARCH_EXPLANATION_DESC_LEN); +} + +Explanation::Explanation():value(0), details(NULL) +{ + this->description[0]=0; +} + +Explanation::Explanation(const Explanation& copy):details(NULL) +{ + set(copy); +} +void Explanation::set(const Explanation& copy){ + this->value = copy.value; + _tcsncpy(description,copy.description,LUCENE_SEARCH_EXPLANATION_DESC_LEN); + + _CLDELETE(this->details); + + if (copy.details != NULL) { + this->details = _CLNEW CL_NS(util)::CLArrayList >(true); + CL_NS(util)::CLArrayList >::const_iterator itr; + itr = copy.details->begin(); + while ( itr != copy.details->end() ){ + details->push_back( (*itr)->clone() ); + ++itr; + } + } +} +Explanation* Explanation::clone() const{ + return _CLNEW Explanation(*this); +} + +Explanation::~Explanation(){ + _CLLDELETE(this->details); +} + +bool Explanation::isMatch() const { + return (0.0f < getValue()); +} + +float_t Explanation::getValue() const{ + return value; +} +void Explanation::setValue(const float_t value) { + this->value = value; +} + +const TCHAR* Explanation::getDescription() const { + return description; +} +void Explanation::setDescription(const TCHAR* description) { + _tcsncpy(this->description,description,LUCENE_SEARCH_EXPLANATION_DESC_LEN); +} + +TCHAR* Explanation::getSummary() { + StringBuffer buf(210); + buf.appendFloat(getValue(), 2); + buf.append(_T(" = ")); + buf.append(getDescription()); + return buf.giveBuffer(); +} + +size_t Explanation::getDetailsLength() const {return (details==NULL)?0:details->size();} +void Explanation::getDetails(Explanation** ret) { + if (details==NULL){ + ret[0]=NULL; + return; + } + size_t size = details->size(); + for ( size_t i=0;iclone(); + } + ret[size] = NULL; +} +Explanation* Explanation::getDetail(const size_t i){return (*details)[i];} + +void Explanation::addDetail(Explanation* detail) { + if (details==NULL) details = _CLNEW CL_NS(util)::CLArrayList >(true); + details->push_back(detail); +} + +TCHAR* Explanation::toString() { + return toString(0); +} + +TCHAR* Explanation::toString(int32_t depth) { + StringBuffer buffer; + for (int32_t i = 0; i < depth; i++) { + buffer.append(_T(" ")); + } + TCHAR* tSum = getSummary(); + buffer.append(tSum); + _CLDELETE_LCARRAY(tSum); + buffer.appendChar(_T('\n')); + + if (details != NULL){ + for ( size_t j=0;jsize();j++ ){ + TCHAR* tmp = (*details)[j]->toString(depth+1); + buffer.append(tmp); + _CLDELETE_LCARRAY(tmp); + } + } + return buffer.toString(); +} + +TCHAR* Explanation::toHtml() { + StringBuffer buffer; + TCHAR* tmp; + buffer.append(_T("

    \n")); + + buffer.append(_T("
  • ")); + TCHAR* tSum = getSummary(); + buffer.append(tSum); + _CLDELETE_LCARRAY(tSum); + buffer.append(_T("
    \n")); + + if (details != NULL){ + for ( size_t i=0;isize();i++ ){ + tmp = (*details)[i]->toHtml(); + buffer.append(tmp); + _CLDELETE_LCARRAY(tmp); + } + } + buffer.append(_T("
  • \n")); + buffer.append(_T("
\n")); + + return buffer.toString(); +} + +ComplexExplanation::ComplexExplanation():Explanation(){} +ComplexExplanation::ComplexExplanation(const ComplexExplanation& copy): + Explanation(copy) +{ + this->match = copy.match; +} +ComplexExplanation::ComplexExplanation(const bool _match, const float_t _value, const TCHAR* _description): + Explanation(_value, _description), match(_match) +{ +} +ComplexExplanation::~ComplexExplanation(){ +} + +bool ComplexExplanation::getMatch() const { return match; } +void ComplexExplanation::setMatch(const bool _match) { this->match = _match; } +bool ComplexExplanation::isMatch() const {return getMatch();} + +TCHAR* ComplexExplanation::getSummary() { + StringBuffer buf(220); + buf.appendFloat(getValue(),2); + buf.append(_T(" = ")); + buf.append(isMatch() ? _T("(MATCH) ") : _T("(NON-MATCH) ")); + buf.append(getDescription()); + return buf.giveBuffer(); +} + +Explanation* ComplexExplanation::clone() const{ + return _CLNEW ComplexExplanation(*this); +} + +CL_NS_END diff --git a/src/core/CLucene/search/Explanation.h b/src/core/CLucene/search/Explanation.h new file mode 100644 index 00000000000..a99ba8e11e2 --- /dev/null +++ b/src/core/CLucene/search/Explanation.h @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Explanation +#define _lucene_search_Explanation + +#include "CLucene/util/VoidList.h" + +CL_NS_DEF(search) + +#define LUCENE_SEARCH_EXPLANATION_DESC_LEN 200 + +/** Expert: Describes the score computation for document and query. */ +class CLUCENE_EXPORT Explanation { +private: + float_t value; // the value of this node + TCHAR description[LUCENE_SEARCH_EXPLANATION_DESC_LEN]; // what it represents + CL_NS(util)::CLArrayList >* details; // sub-explanations + +public: + Explanation(); + Explanation(float_t _value, const TCHAR* _description); + virtual ~Explanation(); + + /** + * Indicates whether or not this Explanation models a good match. + * + *

+ * By default, an Explanation represents a "match" if the value is positive. + *

+ * @see #getValue + */ + virtual bool isMatch() const; + + /** The value assigned to this explanation node. */ + float_t getValue() const; + /** Sets the value assigned to this explanation node. */ + void setValue(const float_t value); + + /** A description of this explanation node. */ + const TCHAR* getDescription() const; /// + * If the match statis is explicitly set (ie: not null) this method + * uses it; otherwise it defers to the superclass. + *

+ * @see #getMatch + */ + bool isMatch() const; + + Explanation* clone() const; + +protected: + TCHAR* getSummary(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/FieldCache.cpp b/src/core/CLucene/search/FieldCache.cpp new file mode 100644 index 00000000000..f2f3a2896fb --- /dev/null +++ b/src/core/CLucene/search/FieldCache.cpp @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "FieldCache.h" +#include "_FieldCacheImpl.h" +#include "Sort.h" + +CL_NS_DEF(search) + +FieldCache* FieldCache_DEFAULT = NULL; +int32_t FieldCache::STRING_INDEX = -1; + +FieldCache* FieldCache::DEFAULT(){ + if ( FieldCache_DEFAULT == NULL ) + FieldCache_DEFAULT = _CLNEW FieldCacheImpl(); + return FieldCache_DEFAULT; +} +void FieldCache::_shutdown(){ + _CLDELETE(FieldCache_DEFAULT); +} + +FieldCacheAuto::FieldCacheAuto(int32_t len, int32_t type){ + contentType = type; + contentLen = len; + ownContents = false; + + intArray=NULL; + floatArray=NULL; + stringIndex=NULL; + stringArray=NULL; + comparableArray=NULL; + sortComparator=NULL; + scoreDocComparator=NULL; +} +FieldCacheAuto::~FieldCacheAuto(){ + if ( contentType == FieldCacheAuto::INT_ARRAY ){ + _CLDELETE_ARRAY(intArray); + }else if ( contentType == FieldCacheAuto::FLOAT_ARRAY ){ + _CLDELETE_ARRAY(floatArray); + }else if ( contentType == FieldCacheAuto::STRING_INDEX ){ + _CLDELETE(stringIndex); + }else if ( contentType == FieldCacheAuto::STRING_ARRAY ){ + if ( ownContents ){ + for ( int32_t i=0;ifield as integers and returns an array + * of size reader.maxDoc() of the value each document + * has in the given field. + * @param reader Used to get field values. + * @param field Which field contains the integers. + * @return The values in the given field for each document. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getInts (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0; + + /** Checks the internal cache for an appropriate entry, and if + * none is found, reads the terms in field as floats and returns an array + * of size reader.maxDoc() of the value each document + * has in the given field. + * @param reader Used to get field values. + * @param field Which field contains the floats. + * @return The values in the given field for each document. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getFloats (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0; + + /** Checks the internal cache for an appropriate entry, and if none + * is found, reads the term values in field and returns an array + * of size reader.maxDoc() containing the value each document + * has in the given field. + * @param reader Used to get field values. + * @param field Which field contains the strings. + * @return The values in the given field for each document. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getStrings (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0; + + /** Checks the internal cache for an appropriate entry, and if none + * is found reads the term values in field and returns + * an array of them in natural order, along with an array telling + * which element in the term array each document uses. + * @param reader Used to get field values. + * @param field Which field contains the strings. + * @return Array of terms and index into the array for each document. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getStringIndex (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0; + + /** Checks the internal cache for an appropriate entry, and if + * none is found reads field to see if it contains integers, floats + * or strings, and then calls one of the other methods in this class to get the + * values. For string values, a FieldCache::StringIndex is returned. After + * calling this method, there is an entry in the cache for both + * type AUTO and the actual found type. + * @param reader Used to get field values. + * @param field Which field contains the values. + * @return int32_t[], float_t[] or FieldCache::StringIndex. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getAuto (CL_NS(index)::IndexReader* reader, const TCHAR* field) = 0; + + /** Checks the internal cache for an appropriate entry, and if none + * is found reads the terms out of field and calls the given SortComparator + * to get the sort values. A hit in the cache will happen if reader, + * field, and comparator are the same (using equals()) + * as a previous call to this method. + * @param reader Used to get field values. + * @param field Which field contains the values. + * @param comparator Used to convert terms into something to sort by. + * @return Array of sort objects, one for each document. + * @throws IOException If any error occurs. + */ + virtual FieldCacheAuto* getCustom (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparator* comparator) = 0; + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); +}; + +/** A class holding an AUTO field. In java lucene an Object + is used, but we use this. + contentType: + 1 - integer array + 2 - float array + 3 - FieldCache::StringIndex object + This class is also used when returning getInt, getFloat, etc + because we have no way of returning the size of the array and + this class can be used to determine the array size +*/ +class CLUCENE_EXPORT FieldCacheAuto:LUCENE_BASE{ +public: + enum{ + INT_ARRAY=1, + FLOAT_ARRAY=2, + STRING_INDEX=3, + STRING_ARRAY=4, + COMPARABLE_ARRAY=5, + SORT_COMPARATOR=6, + SCOREDOC_COMPARATOR=7 + }; + + FieldCacheAuto(int32_t len, int32_t type); + ~FieldCacheAuto(); + ///if contents should be deleted too, depending on type + bool ownContents; + int32_t contentLen; //number of items in the list + uint8_t contentType; + int32_t* intArray; //item 1 + float_t* floatArray; //item 2 + FieldCache::StringIndex* stringIndex; //item 3 + TCHAR** stringArray; //item 4 + CL_NS(util)::Comparable** comparableArray; //item 5 + SortComparator* sortComparator; //item 6 + ScoreDocComparator* scoreDocComparator; //item 7 + +}; + + +CL_NS_END + +#endif diff --git a/src/core/CLucene/search/FieldCacheImpl.cpp b/src/core/CLucene/search/FieldCacheImpl.cpp new file mode 100644 index 00000000000..bc3a29c6a87 --- /dev/null +++ b/src/core/CLucene/search/FieldCacheImpl.cpp @@ -0,0 +1,577 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FieldCacheImpl.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/Misc.h" +#include "Sort.h" + +CL_NS_USE(util) +CL_NS_USE(index) +CL_NS_DEF(search) + +///the type that is stored in the field cache. can't use a typedef because +///the decorated name would become too long +class fieldcacheCacheReaderType: public CL_NS(util)::CLHashMap, + CL_NS(util)::Deletor::Object >{ +public: + fieldcacheCacheReaderType(){ + setDeleteKey(false); + setDeleteValue(false); + } + ~fieldcacheCacheReaderType(){ + iterator itr = begin(); + while ( itr != end() ){ + FieldCacheImpl::FileEntry* f = itr->first; + if ( f->getType() != SortField::AUTO ) + _CLDELETE( itr->second ); + _CLDELETE( f ); + ++itr; + } + clear(); + } +}; + +//note: typename gets too long if using cacheReaderType as a typename +class fieldcacheCacheType: public CL_NS(util)::CLHashMap< + CL_NS(index)::IndexReader*, + fieldcacheCacheReaderType*, + CL_NS(util)::Compare::Void, + CL_NS(util)::Equals::Void, + CL_NS(util)::Deletor::Object, + CL_NS(util)::Deletor::Object >{ +public: + fieldcacheCacheType ( const bool deleteKey, const bool deleteValue) + { + setDeleteKey(deleteKey); + setDeleteValue(deleteValue); + } + virtual ~fieldcacheCacheType(){ + + } +}; + +FieldCache::StringIndex::StringIndex (int32_t* values, TCHAR** lookup, int count) { + this->count = count; + this->order = values; + this->lookup = lookup; +} + +FieldCache::StringIndex::~StringIndex(){ + _CLDELETE_ARRAY(order); + + for ( int i=0;iclear(); + _CLDELETE(cache); +} + +FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, int32_t type) { + this->field = CLStringIntern::intern(field); + this->type = type; + this->custom = NULL; + this->_hashCode = 0; + } + + /** Creates one of these objects for a custom comparator. */ + FieldCacheImpl::FileEntry::FileEntry (const TCHAR* field, SortComparatorSource* custom) { + this->field = CLStringIntern::intern(field); + this->type = SortField::CUSTOM; + this->custom = custom; + this->_hashCode = 0; + } + FieldCacheImpl::FileEntry::~FileEntry(){ + CLStringIntern::unintern(field); + } + + size_t FieldCacheImpl::FileEntry::hashCode(){ + if ( _hashCode == 0 ){ + //todo: cache hashcode? + size_t ret = Misc::thashCode(field); + if ( custom != NULL ) + ret = ret ^ custom->hashCode(); + ret = ret ^ (type*7); //type with a seed + _hashCode = ret; + } + return _hashCode; + } + int32_t FieldCacheImpl::FileEntry::compareTo(const FieldCacheImpl::FileEntry* other) const{ + if ( other->field == this->field ){ + if ( other->type == this->type ){ + if ( other->custom == NULL ){ + if ( this->custom == NULL ) + return 0; //both null + else + return 1; + }else if ( this->custom == NULL ) + return -1; + else if ( other->custom < this->custom ) + return -1; + else if ( other->custom > this->custom ) + return 1; + else + return 0; + }else if ( other->type > this->type ) + return 1; + else + return -1; + + }else + return _tcscmp(other->field,this->field); + } + + /** Two of these are equal iff they reference the same field and type. */ + /*bool FieldCacheImpl::FileEntry::equals (FileEntry* other) { + if (other->field == field && other->type == type) { + if (other->custom == NULL) { + if (custom == NULL) + return true; + } else if (other->custom->equals (custom)) { + return true; + } + } + }*/ + + /** Composes a hashcode based on the field and type. */ + /*size_t FieldCacheImpl::FileEntry::hashCode() { + return field->hashCode() ^ type ^ (custom==NULL ? 0 : custom->hashCode()); + }*/ + + + + + + /** See if an object is in the cache. */ + FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, int32_t type) { + FieldCacheAuto* ret = NULL; + FileEntry* entry = _CLNEW FileEntry (field, type); + { + SCOPED_LOCK_MUTEX(THIS_LOCK) + fieldcacheCacheReaderType* readerCache = cache->get(reader); + if (readerCache != NULL) + ret = readerCache->get (entry); + _CLDELETE(entry); + } + return ret; + } + + + /** See if a custom object is in the cache. */ + FieldCacheAuto* FieldCacheImpl::lookup (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer) { + FieldCacheAuto* ret = NULL; + FileEntry* entry = _CLNEW FileEntry (field, comparer); + { + SCOPED_LOCK_MUTEX(THIS_LOCK) + fieldcacheCacheReaderType* readerCache = cache->get(reader); + if (readerCache != NULL) + ret = readerCache->get (entry); + _CLDELETE(entry); +} + return ret; + } + + void FieldCacheImpl::closeCallback(CL_NS(index)::IndexReader* reader, void* fieldCacheImpl){ + FieldCacheImpl* fci = (FieldCacheImpl*)fieldCacheImpl; + SCOPED_LOCK_MUTEX(fci->THIS_LOCK) + fci->cache->remove(reader); + } + + /** Put an object into the cache. */ + void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, int32_t type, FieldCacheAuto* value) { + FileEntry* entry = _CLNEW FileEntry (field, type); + { + SCOPED_LOCK_MUTEX(THIS_LOCK) + fieldcacheCacheReaderType* readerCache = cache->get(reader); + if (readerCache == NULL) { + readerCache = _CLNEW fieldcacheCacheReaderType; + cache->put(reader,readerCache); + reader->addCloseCallback(closeCallback, this); + } + readerCache->put (entry, value); + //this is supposed to return the previous value, but it needs to be deleted!!! + } + } + + /** Put a custom object into the cache. */ + void FieldCacheImpl::store (IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer, FieldCacheAuto* value) { + FileEntry* entry = _CLNEW FileEntry (field, comparer); + { + SCOPED_LOCK_MUTEX(THIS_LOCK) + fieldcacheCacheReaderType* readerCache = cache->get(reader); + if (readerCache == NULL) { + readerCache = _CLNEW fieldcacheCacheReaderType; + cache->put(reader, readerCache); + reader->addCloseCallback(FieldCacheImpl::closeCallback, this); + } + readerCache->put(entry, value); + //this is supposed to return the previous value, but it needs to be deleted!!! + } + } + + + + + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getInts (IndexReader* reader, const TCHAR* field) { + field = CLStringIntern::intern(field); + FieldCacheAuto* ret = lookup (reader, field, SortField::INT); + if (ret == NULL) { + int32_t retLen = reader->maxDoc(); + int32_t* retArray = _CL_NEWARRAY(int32_t,retLen); + memset(retArray,0,sizeof(int32_t)*retLen); + if (retLen > 0) { + TermDocs* termDocs = reader->termDocs(); + + Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false); + TermEnum* termEnum = reader->terms (term); + _CLDECDELETE(term); + try { + if (termEnum->term(false) == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field"); //todo: add detailed error: + field); + } + do { + Term* term = termEnum->term(false); + if (term->field() != field) + break; + + int32_t termval = _ttoi(term->text()); + termDocs->seek (termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; + } + } while (termEnum->next()); + } _CLFINALLY( + termDocs->close(); + _CLDELETE(termDocs); + termEnum->close(); + _CLDELETE(termEnum); + ) + } + + FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::INT_ARRAY); + fa->intArray = retArray; + + store (reader, field, SortField::INT, fa); + CLStringIntern::unintern(field); + return fa; + } + CLStringIntern::unintern(field); + return ret; + } + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getFloats (IndexReader* reader, const TCHAR* field){ + field = CLStringIntern::intern(field); + FieldCacheAuto* ret = lookup (reader, field, SortField::FLOAT); + if (ret == NULL) { + int32_t retLen = reader->maxDoc(); + float_t* retArray = _CL_NEWARRAY(float_t,retLen); + memset(retArray,0,sizeof(float_t)*retLen); + if (retLen > 0) { + TermDocs* termDocs = reader->termDocs(); + + Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false); + TermEnum* termEnum = reader->terms (term); + _CLDECDELETE(term); + + try { + if (termEnum->term(false) == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: make richer error + field); + } + do { + Term* term = termEnum->term(false); + if (term->field() != field) + break; + + float_t termval = _tcstod(term->text(),NULL); + termDocs->seek (termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; + } + } while (termEnum->next()); + } _CLFINALLY( + termDocs->close(); + _CLDELETE(termDocs); + termEnum->close(); + _CLDELETE(termEnum); + ) + } + + FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::FLOAT_ARRAY); + fa->floatArray = retArray; + + store (reader, field, SortField::FLOAT, fa); + CLStringIntern::unintern(field); + return fa; + } + CLStringIntern::unintern(field); + return ret; + } + + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getStrings (IndexReader* reader, const TCHAR* field){ + //todo: this is not really used, i think? + field = CLStringIntern::intern(field); + FieldCacheAuto* ret = lookup (reader, field, SortField::STRING); + if (ret == NULL) { + int32_t retLen = reader->maxDoc(); + TCHAR** retArray = _CL_NEWARRAY(TCHAR*,retLen+1); + memset(retArray,0,sizeof(TCHAR*)*(retLen+1)); + if (retLen > 0) { + TermDocs* termDocs = reader->termDocs(); + + Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false); + TermEnum* termEnum = reader->terms (term); + _CLDECDELETE(term); + + try { + if (termEnum->term(false) == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: extend to + field); + } + do { + Term* term = termEnum->term(false); + if (term->field() != field) + break; + const TCHAR* termval = term->text(); + termDocs->seek (termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = STRDUP_TtoT(termval); //todo: any better way of doing this??? + } + } while (termEnum->next()); + } _CLFINALLY( + retArray[retLen]=NULL; + termDocs->close(); + _CLDELETE(termDocs); + termEnum->close(); + _CLDELETE(termEnum); + ) + } + FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::STRING_ARRAY); + fa->stringArray = retArray; + fa->ownContents=true; + store (reader, field, SortField::STRING, fa); + CLStringIntern::unintern(field); + return fa; + } + CLStringIntern::unintern(field); + return ret; + } + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getStringIndex (IndexReader* reader, const TCHAR* field){ + field = CLStringIntern::intern(field); + FieldCacheAuto* ret = lookup (reader, field, STRING_INDEX); + int32_t t = 0; // current term number + if (ret == NULL) { + int32_t retLen = reader->maxDoc(); + int32_t* retArray = _CL_NEWARRAY(int32_t,retLen); + memset(retArray,0,sizeof(int32_t)*retLen); + + TCHAR** mterms = _CL_NEWARRAY(TCHAR*,retLen+2); + mterms[0]=NULL; + if ( retLen > 0 ) { + TermDocs* termDocs = reader->termDocs(); + + Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false); + TermEnum* termEnum = reader->terms (term); + _CLDECDELETE(term); + + + CND_PRECONDITION(t+1 <= retLen, "t out of bounds"); + + // an entry for documents that have no terms in this field + // should a document with no terms be at top or bottom? + // this puts them at the top - if it is changed, FieldDocSortedHitQueue + // needs to change as well. + mterms[t++] = NULL; + + try { + if (termEnum->term(false) == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field"); //todo: make rich message " + field); + } + do { + Term* term = termEnum->term(false); + if (term->field() != field) + break; + + // store term text + // we expect that there is at most one term per document + if (t >= retLen+1) + _CLTHROWA(CL_ERR_Runtime,"there are more terms than documents in field"); //todo: rich error \"" + field + "\""); + mterms[t] = STRDUP_TtoT(term->text()); + + termDocs->seek (termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = t; + } + + t++; + } while (termEnum->next()); + CND_PRECONDITION(tclose(); + _CLDELETE(termDocs); + termEnum->close(); + _CLDELETE(termEnum); + ); + + if (t == 0) { + // if there are no terms, make the term array + // have a single NULL entry + _CLDELETE_ARRAY(mterms); + mterms = _CL_NEWARRAY(TCHAR*,1); //todo: delete old mterms? + mterms[0]=NULL; + } else if (t < retLen) { //todo: check, was mterms.length + // if there are less terms than documents, + // trim off the dead array space + //const TCHAR** terms = _CL_NEWARRAY(TCHAR,t); + //System.arraycopy (mterms, 0, terms, 0, t); + //mterms = terms; + + //we simply shorten the length of the array... + + } + } + FieldCache::StringIndex* value = _CLNEW FieldCache::StringIndex (retArray, mterms,t); + + FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::STRING_INDEX); + fa->stringIndex = value; + fa->ownContents=true; + store (reader, field, STRING_INDEX, fa); + CLStringIntern::unintern(field); + return fa; + } + CLStringIntern::unintern(field); + return ret; + } + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getAuto (IndexReader* reader, const TCHAR* field) { + field = CLStringIntern::intern(field); + FieldCacheAuto* ret = lookup (reader, field, SortField::AUTO); + if (ret == NULL) { + Term* term = _CLNEW Term (field, LUCENE_BLANK_STRING, false); + TermEnum* enumerator = reader->terms (term); + _CLDECDELETE(term); + + try { + Term* term = enumerator->term(false); + if (term == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field - cannot determine sort type"); //todo: make rich error: " + field + " + } + if (term->field() == field) { + const TCHAR* termtext = term->text(); + size_t termTextLen = term->textLength(); + + bool isint=true; + for ( size_t i=0;iclose(); _CLDELETE(enumerator) ); + + } + CLStringIntern::unintern(field); + return ret; + } + + + // inherit javadocs + FieldCacheAuto* FieldCacheImpl::getCustom (IndexReader* reader, const TCHAR* field, SortComparator* comparator){ + field = CLStringIntern::intern(field); + + FieldCacheAuto* ret = lookup (reader, field, comparator); + if (ret == NULL) { + int32_t retLen = reader->maxDoc(); + Comparable** retArray = _CL_NEWARRAY(Comparable*,retLen); + memset(retArray,0,sizeof(Comparable*)*retLen); + if (retLen > 0) { + TermDocs* termDocs = reader->termDocs(); + TermEnum* termEnum = reader->terms (); + + try { + if (termEnum->term(false) == NULL) { + _CLTHROWA(CL_ERR_Runtime,"no terms in field "); //todo: make rich error + field); + } + do { + Term* term = termEnum->term(false); + if (term->field() != field) + break; + Comparable* termval = comparator->getComparable (term->text()); + termDocs->seek (termEnum); + while (termDocs->next()) { + retArray[termDocs->doc()] = termval; + } + } while (termEnum->next()); + } _CLFINALLY ( + termDocs->close(); + _CLDELETE(termDocs); + termEnum->close(); + _CLDELETE(termEnum); + ); + } + + FieldCacheAuto* fa = _CLNEW FieldCacheAuto(retLen,FieldCacheAuto::COMPARABLE_ARRAY); + fa->comparableArray = retArray; + fa->ownContents=true; + store (reader, field, SortField::CUSTOM, fa); + CLStringIntern::unintern(field); + return fa; + } + CLStringIntern::unintern(field); + return ret; + } + + +CL_NS_END diff --git a/src/core/CLucene/search/FieldDoc.h b/src/core/CLucene/search/FieldDoc.h new file mode 100644 index 00000000000..07835c926a0 --- /dev/null +++ b/src/core/CLucene/search/FieldDoc.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FieldDoc_ +#define _lucene_search_FieldDoc_ + +#include "SearchHeader.h" + +CL_NS_DEF(search) + +/** + * Expert: A ScoreDoc which also contains information about + * how to sort the referenced document. In addition to the + * document number and score, this object contains an array + * of values for the document from the field(s) used to sort. + * For example, if the sort criteria was to sort by fields + * "a", "b" then "c", the fields object array + * will have three elements, corresponding respectively to + * the term values for the document in fields "a", "b" and "c". + * The class of each element in the array will be either + * Integer, Float or String depending on the type of values + * in the terms of each field. + * + * @see ScoreDoc + * @see TopFieldDocs + */ +class CLUCENE_EXPORT FieldDoc: LUCENE_BASE { +public: + //FieldDoc did inherit from ScoreDoc, but now we make the scoredoc a member + struct ScoreDoc scoreDoc; + + /** Expert: The values which are used to sort the referenced document. + * The order of these will match the original sort criteria given by a + * Sort object. Each Object will be either an Integer, Float or String, + * depending on the type of values in the terms of the original field. + * @see Sort + * @see Searchable#search(Query,Filter,int32_t,Sort) + */ + CL_NS(util)::Comparable** fields; + + /** Expert: Creates one of these objects with empty sort information. */ + FieldDoc (int32_t doc, float_t score); + /** Expert: Creates one of these objects with the given sort information. */ + FieldDoc (int32_t doc, float_t score, CL_NS(util)::Comparable** fields); + ~FieldDoc(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/FieldDocSortedHitQueue.cpp b/src/core/CLucene/search/FieldDocSortedHitQueue.cpp new file mode 100644 index 00000000000..67e4939c19f --- /dev/null +++ b/src/core/CLucene/search/FieldDocSortedHitQueue.cpp @@ -0,0 +1,171 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FieldDocSortedHitQueue.h" + + +CL_NS_USE(util) +CL_NS_DEF(search) + + +FieldDoc::FieldDoc (int32_t doc, float_t score) +{ + this->scoreDoc.doc = doc; + this->scoreDoc.score = score; + fields=NULL; +} + +FieldDoc::FieldDoc (int32_t doc, float_t score, CL_NS(util)::Comparable** fields) +{ + this->scoreDoc.doc = doc; + this->scoreDoc.score = score; + this->fields = fields; +} + +FieldDoc::~FieldDoc(){ + if ( fields != NULL ){ + for ( int i=0;fields[i]!=NULL;i++ ) + _CLDELETE(fields[i]); + _CLDELETE_ARRAY(fields); + } +} + + + +FieldDocSortedHitQueue::FieldDocSortedHitQueue (SortField** fields, int32_t size) { + this->fields = fields; + _countsize(); + //this->collators = hasCollators (fields); + initialize (size,true); +} + +bool FieldDocSortedHitQueue::lessThan (FieldDoc* docA, FieldDoc* docB) { + const int32_t n = fieldsLen; + int32_t c = 0; + float_t f1,f2,r1,r2; + int32_t i1,i2; + const TCHAR *s1, *s2; + + for (int32_t i=0; igetType(); + if (fields[i]->getReverse()) { + switch (type) { + case SortField::DOCSCORE: + r1 = reinterpret_cast(docA->fields[i])->getValue(); + r2 = reinterpret_cast(docB->fields[i])->getValue(); + if (r1 < r2) c = -1; + if (r1 > r2) c = 1; + break; + case SortField::DOC: + case SortField::INT: + i1 = reinterpret_cast(docA->fields[i])->getValue(); + i2 = reinterpret_cast(docB->fields[i])->getValue(); + if (i1 > i2) c = -1; + if (i1 < i2) c = 1; + break; + case SortField::STRING: + s1 = reinterpret_cast(docA->fields[i])->getValue(); + s2 = reinterpret_cast(docB->fields[i])->getValue(); + if (s2 == NULL) c = -1; // could be NULL if there are + else if (s1 == NULL) c = 1; // no terms in the given field + else c = _tcscmp(s2,s1); //else if (fields[i].getLocale() == NULL) { + + /*todo: collators not impl + } else { + c = collators[i].compare (s2, s1); + }*/ + break; + case SortField::FLOAT: + f1 = reinterpret_cast(docA->fields[i])->getValue(); + f2 = reinterpret_cast(docB->fields[i])->getValue(); + if (f1 > f2) c = -1; + if (f1 < f2) c = 1; + break; + case SortField::CUSTOM: + c = docB->fields[i]->compareTo (docA->fields[i]); + break; + case SortField::AUTO: + // we cannot handle this - even if we determine the type of object (float_t or + // Integer), we don't necessarily know how to compare them (both SCORE and + // float_t both contain floats, but are sorted opposite of each other). Before + // we get here, each AUTO should have been replaced with its actual value. + _CLTHROWA (CL_ERR_Runtime,"FieldDocSortedHitQueue cannot use an AUTO SortField"); + default: + _CLTHROWA (CL_ERR_Runtime, "invalid SortField type"); //todo: rich error... : "+type); + } + } else { + switch (type) { + case SortField::DOCSCORE: + r1 = reinterpret_cast(docA->fields[i])->getValue(); + r2 = reinterpret_cast(docB->fields[i])->getValue(); + if (r1 > r2) c = -1; + if (r1 < r2) c = 1; + break; + case SortField::DOC: + case SortField::INT: + i1 = reinterpret_cast(docA->fields[i])->getValue(); + i2 = reinterpret_cast(docB->fields[i])->getValue(); + if (i1 < i2) c = -1; + if (i1 > i2) c = 1; + break; + case SortField::STRING: + s1 = reinterpret_cast(docA->fields[i])->getValue(); + s2 = reinterpret_cast(docB->fields[i])->getValue(); + // NULL values need to be sorted first, because of how FieldCache.getStringIndex() + // works - in that routine, any documents without a value in the given field are + // put first. + if (s1 == NULL) c = -1; // could be NULL if there are + else if (s2 == NULL) c = 1; // no terms in the given field + else c = _tcscmp(s1,s2); //else if (fields[i].getLocale() == NULL) { + + /* todo: collators not implemented } else { + c = collators[i].compare (s1, s2); + }*/ + break; + case SortField::FLOAT: + f1 = reinterpret_cast(docA->fields[i])->getValue(); + f2 = reinterpret_cast(docB->fields[i])->getValue(); + if (f1 < f2) c = -1; + if (f1 > f2) c = 1; + break; + case SortField::CUSTOM: + c = docA->fields[i]->compareTo (docB->fields[i]); + break; + case SortField::AUTO: + // we cannot handle this - even if we determine the type of object (float_t or + // Integer), we don't necessarily know how to compare them (both SCORE and + // float_t both contain floats, but are sorted opposite of each other). Before + // we get here, each AUTO should have been replaced with its actual value. + _CLTHROWA (CL_ERR_Runtime,"FieldDocSortedHitQueue cannot use an AUTO SortField"); + default: + _CLTHROWA (CL_ERR_Runtime,"invalid SortField type"); //todo: rich error... : "+type); + } + } + } + return c > 0; +} + +void FieldDocSortedHitQueue::setFields (SortField** fields) { + SCOPED_LOCK_MUTEX(THIS_LOCK) + if (this->fields == NULL) { + this->fields = fields; + _countsize(); + //this->collators = hasCollators (fields); + }else if ( fields == NULL ) + this->fields = NULL; +} + +FieldDocSortedHitQueue::~FieldDocSortedHitQueue(){ + if ( fields != NULL ){ + for ( int i=0;fields[i]!=NULL;i++ ) + _CLDELETE(fields[i]); + _CLDELETE_ARRAY(fields); + } +} + +CL_NS_END + diff --git a/src/core/CLucene/search/FieldSortedHitQueue.cpp b/src/core/CLucene/search/FieldSortedHitQueue.cpp new file mode 100644 index 00000000000..ef6100c77da --- /dev/null +++ b/src/core/CLucene/search/FieldSortedHitQueue.cpp @@ -0,0 +1,258 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "FieldSortedHitQueue.h" +#include "_FieldDocSortedHitQueue.h" +#include "_FieldCacheImpl.h" +#include "Compare.h" +#include "CLucene/index/IndexReader.h" + +CL_NS_USE(util) +CL_NS_USE(index) +CL_NS_DEF(search) + + +//note: typename gets too long if using cacheReaderType as a typename +class hitqueueCacheType: public CL_NS(util)::CLHashMap, + CL_NS(util)::Equals::Void, + CL_NS(util)::Deletor::Object, + CL_NS(util)::Deletor::Object >{ +public: + hitqueueCacheType(bool deleteKey, bool deleteValue){ + setDeleteKey(deleteKey); + setDeleteValue(deleteValue); + } + ~hitqueueCacheType(){ + clear(); + } +}; + + +///the type that is stored in the field cache. can't use a typedef because +///the decorated name would become too long +class hitqueueCacheReaderType: public CL_NS(util)::CLHashMap, + CL_NS(util)::Deletor::Object >{ + +public: + hitqueueCacheReaderType(bool deleteValue){ + setDeleteKey(true); + setDeleteValue(deleteValue); + } + ~hitqueueCacheReaderType(){ + clear(); + } +}; + +hitqueueCacheType* FieldSortedHitQueue::Comparators = _CLNEW hitqueueCacheType(false,true); +DEFINE_MUTEX(FieldSortedHitQueue::Comparators_LOCK) + +void FieldSortedHitQueue::_shutdown(){ + Comparators->clear(); + _CLDELETE(Comparators); +} + +FieldSortedHitQueue::FieldSortedHitQueue (IndexReader* reader, SortField** _fields, int32_t size): + fieldsLen(0), + maxscore(1.0f) +{ + while ( _fields[fieldsLen] != 0 ) + fieldsLen++; + + comparators = _CL_NEWARRAY(ScoreDocComparator*,fieldsLen+1); + SortField** tmp = _CL_NEWARRAY(SortField*,fieldsLen+1); + for (int32_t i=0; igetField(); + //todo: fields[i].getLocale(), not implemented + comparators[i] = getCachedComparator (reader, fieldname, _fields[i]->getType(), _fields[i]->getFactory()); + tmp[i] = _CLNEW SortField (fieldname, comparators[i]->sortType(), _fields[i]->getReverse()); + } + comparatorsLen = fieldsLen; + comparators[fieldsLen]=NULL; + tmp[fieldsLen] = NULL; + this->fields = tmp; + + initialize(size,true); +} + + +bool FieldSortedHitQueue::lessThan (FieldDoc* docA, FieldDoc* docB) { + // keep track of maximum score + if (docA->scoreDoc.score > maxscore) maxscore = docA->scoreDoc.score; + if (docB->scoreDoc.score > maxscore) maxscore = docB->scoreDoc.score; + + // run comparators + int32_t c = 0; + for ( int32_t i=0; c==0 && igetReverse()) ? comparators[i]->compare (&docB->scoreDoc, &docA->scoreDoc) : + comparators[i]->compare (&docA->scoreDoc, &docB->scoreDoc); + } + // avoid random sort order that could lead to duplicates (bug #31241): + if (c == 0) + return docA->scoreDoc.doc > docB->scoreDoc.doc; + return c > 0; +} + + +//static +ScoreDocComparator* FieldSortedHitQueue::comparatorString (IndexReader* reader, const TCHAR* field) { + //const TCHAR* field = CLStringIntern::intern(fieldname); + FieldCacheAuto* fa = FieldCache::DEFAULT()->getStringIndex (reader, field); + //CLStringIntern::unintern(field); + + CND_PRECONDITION(fa->contentType==FieldCacheAuto::STRING_INDEX,"Content type is incorrect"); + fa->ownContents = false; + return _CLNEW ScoreDocComparators::String(fa->stringIndex, fa->contentLen); +} + +//static +ScoreDocComparator* FieldSortedHitQueue::comparatorInt (IndexReader* reader, const TCHAR* field){ + //const TCHAR* field = CLStringIntern::intern(fieldname); + FieldCacheAuto* fa = FieldCache::DEFAULT()->getInts (reader, field); + //CLStringIntern::unintern(field); + + CND_PRECONDITION(fa->contentType==FieldCacheAuto::INT_ARRAY,"Content type is incorrect"); + return _CLNEW ScoreDocComparators::Int32(fa->intArray, fa->contentLen); + } + +//static + ScoreDocComparator* FieldSortedHitQueue::comparatorFloat (IndexReader* reader, const TCHAR* field) { + //const TCHAR* field = CLStringIntern::intern(fieldname); + FieldCacheAuto* fa = FieldCache::DEFAULT()->getFloats (reader, field); + //CLStringIntern::unintern(field); + + CND_PRECONDITION(fa->contentType==FieldCacheAuto::FLOAT_ARRAY,"Content type is incorrect"); + return _CLNEW ScoreDocComparators::Float (fa->floatArray, fa->contentLen); + } +//static + ScoreDocComparator* FieldSortedHitQueue::comparatorAuto (IndexReader* reader, const TCHAR* field){ + //const TCHAR* field = CLStringIntern::intern(fieldname); + FieldCacheAuto* fa = FieldCache::DEFAULT()->getAuto (reader, field); + //CLStringIntern::unintern(field); + + if (fa->contentType == FieldCacheAuto::STRING_INDEX ) { + return comparatorString (reader, field); + } else if (fa->contentType == FieldCacheAuto::INT_ARRAY) { + return comparatorInt (reader, field); + } else if (fa->contentType == FieldCacheAuto::FLOAT_ARRAY) { + return comparatorFloat (reader, field); + } else if (fa->contentType == FieldCacheAuto::STRING_ARRAY) { + return comparatorString (reader, field); + } else { + _CLTHROWA(CL_ERR_Runtime, "unknown data type in field"); //todo: rich error information: '"+field+"'"); + } + } + + + //todo: Locale locale, not implemented yet + ScoreDocComparator* FieldSortedHitQueue::getCachedComparator (IndexReader* reader, const TCHAR* fieldname, int32_t type, SortComparatorSource* factory){ + if (type == SortField::DOC) + return ScoreDocComparator::INDEXORDER(); + if (type == SortField::DOCSCORE) + return ScoreDocComparator::RELEVANCE(); + ScoreDocComparator* comparator = lookup (reader, fieldname, type, factory); + if (comparator == NULL) { + switch (type) { + case SortField::AUTO: + comparator = comparatorAuto (reader, fieldname); + break; + case SortField::INT: + comparator = comparatorInt (reader, fieldname); + break; + case SortField::FLOAT: + comparator = comparatorFloat (reader, fieldname); + break; + case SortField::STRING: + //if (locale != NULL) + // comparator = comparatorStringLocale (reader, fieldname, locale); + //else + comparator = comparatorString (reader, fieldname); + break; + case SortField::CUSTOM: + comparator = factory->newComparator (reader, fieldname); + break; + default: + _CLTHROWA(CL_ERR_Runtime,"unknown field type"); + //todo: extend error + //throw _CLNEW RuntimeException ("unknown field type: "+type); + } + store (reader, fieldname, type, factory, comparator); + } + return comparator; + } + + + FieldDoc* FieldSortedHitQueue::fillFields (FieldDoc* doc) const{ + int32_t n = comparatorsLen; + Comparable** fields = _CL_NEWARRAY(Comparable*,n+1); + for (int32_t i=0; isortValue(&doc->scoreDoc); + fields[n]=NULL; + doc->fields = fields; + if (maxscore > 1.0f) + doc->scoreDoc.score /= maxscore; // normalize scores + return doc; + } + + ScoreDocComparator* FieldSortedHitQueue::lookup (IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory) { + ScoreDocComparator* sdc = NULL; + FieldCacheImpl::FileEntry* entry = (factory != NULL) + ? _CLNEW FieldCacheImpl::FileEntry (field, factory) + : _CLNEW FieldCacheImpl::FileEntry (field, type); + + { + SCOPED_LOCK_MUTEX(Comparators_LOCK) + hitqueueCacheReaderType* readerCache = Comparators->get(reader); + if (readerCache == NULL){ + _CLDELETE(entry); + return NULL; + } + + sdc = readerCache->get (entry); + _CLDELETE(entry); + } + return sdc; + } + + void FieldSortedHitQueue::closeCallback(CL_NS(index)::IndexReader* reader, void*){ + SCOPED_LOCK_MUTEX(Comparators_LOCK) + Comparators->remove(reader); + } + + //static + void FieldSortedHitQueue::store (IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory, ScoreDocComparator* value) { + FieldCacheImpl::FileEntry* entry = (factory != NULL) + ? _CLNEW FieldCacheImpl::FileEntry (field, factory) + : _CLNEW FieldCacheImpl::FileEntry (field, type); + + { + SCOPED_LOCK_MUTEX(Comparators_LOCK) + hitqueueCacheReaderType* readerCache = Comparators->get(reader); + if (readerCache == NULL) { + readerCache = _CLNEW hitqueueCacheReaderType(true); + Comparators->put(reader,readerCache); + reader->addCloseCallback(FieldSortedHitQueue::closeCallback,NULL); + } + readerCache->put (entry, value); + //return NULL; //supposed to return previous value... + } + } + +FieldSortedHitQueue::~FieldSortedHitQueue(){ + _CLDELETE_ARRAY(comparators); + if ( fields != NULL ){ + for ( int i=0;fields[i]!=NULL;i++ ) + _CLDELETE(fields[i]); + _CLDELETE_ARRAY(fields); + } +} +CL_NS_END diff --git a/src/core/CLucene/search/FieldSortedHitQueue.h b/src/core/CLucene/search/FieldSortedHitQueue.h new file mode 100644 index 00000000000..4a82762cbc1 --- /dev/null +++ b/src/core/CLucene/search/FieldSortedHitQueue.h @@ -0,0 +1,196 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FieldSortedHitQueue_ +#define _lucene_search_FieldSortedHitQueue_ + + +CL_CLASS_DEF(search,FieldDoc) +CL_CLASS_DEF(search,SortComparatorSource) +CL_CLASS_DEF(search,SortField) +#include "FieldDoc.h" //required to expose destructor +#include "CLucene/util/PriorityQueue.h" +#include "CLucene/util/Equators.h" +#include "CLucene/LuceneThreads.h" + +CL_CLASS_DEF(index,IndexReader) + +CL_NS_DEF(search) + +class hitqueueCacheReaderType; +class hitqueueCacheType; +class ScoreDocComparator; + +/** + * Expert: A hit queue for sorting by hits by terms in more than one field. + * Uses FieldCache.DEFAULT for maintaining internal term lookup tables. + * + * @see Searchable#search(Query,Filter,int32_t,Sort) + * @see FieldCache + */ +class CLUCENE_EXPORT FieldSortedHitQueue: public CL_NS(util)::PriorityQueue > { + +public: //todo: remove this and below after close callback is implemented + + /** Internal cache of comparators. Similar to FieldCache, only + * caches comparators instead of term values. + */ + static hitqueueCacheType* Comparators; + STATIC_DEFINE_MUTEX(Comparators_LOCK) + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); +private: + + /** Returns a comparator if it is in the cache.*/ + static ScoreDocComparator* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory); + + /** Stores a comparator into the cache. + returns the valid ScoreDocComparator. + */ + static void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, SortComparatorSource* factory, ScoreDocComparator* value); + + + //todo: Locale locale, not implemented yet + static ScoreDocComparator* getCachedComparator (CL_NS(index)::IndexReader* reader, + const TCHAR* fieldname, int32_t type, SortComparatorSource* factory); + + + /** + * Returns a comparator for sorting hits according to a field containing integers. + * @param reader Index to use. + * @param fieldname Field containg integer values. + * @return Comparator for sorting hits. + * @throws IOException If an error occurs reading the index. + */ + static ScoreDocComparator* comparatorInt (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname); + + /** + * Returns a comparator for sorting hits according to a field containing floats. + * @param reader Index to use. + * @param fieldname Field containg float values. + * @return Comparator for sorting hits. + * @throws IOException If an error occurs reading the index. + */ + static ScoreDocComparator* comparatorFloat (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname); + + /** + * Returns a comparator for sorting hits according to a field containing strings. + * @param reader Index to use. + * @param fieldname Field containg string values. + * @return Comparator for sorting hits. + * @throws IOException If an error occurs reading the index. + */ + static ScoreDocComparator* comparatorString (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname); + + + //todo: + /** + * Returns a comparator for sorting hits according to a field containing strings. + * @param reader Index to use. + * @param fieldname Field containg string values. + * @return Comparator for sorting hits. + * @throws IOException If an error occurs reading the index. + + static ScoreDocComparator* comparatorStringLocale (IndexReader* reader, TCHAR* fieldname, Locale locale){ + Collator collator = Collator.getInstance (locale); + TCHAR* field = fieldname.intern(); + TCHAR** index = FieldCache.DEFAULT.getStrings (reader, field); + return _CLNEW ScoreDocComparator() { + + public int32_t compare (ScoreDoc i, ScoreDoc j) { + return collator.compare (index[i.doc], index[j.doc]); + } + + public Comparable sortValue (ScoreDoc i) { + return index[i.doc]; + } + + public int32_t sortType() { + return SortField.STRING; + } + }; + }*/ + + /** + * Returns a comparator for sorting hits according to values in the given field. + * The terms in the field are looked at to determine whether they contain integers, + * floats or strings. Once the type is determined, one of the other static methods + * in this class is called to get the comparator. + * @param reader Index to use. + * @param fieldname Field containg values. + * @return Comparator for sorting hits. + * @throws IOException If an error occurs reading the index. + */ + static ScoreDocComparator* comparatorAuto (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname); + + +protected: + /** Stores a comparator corresponding to each field being sorted by */ + ScoreDocComparator** comparators; + int32_t comparatorsLen; + + /** Stores the sort criteria being used. */ + SortField** fields; + int32_t fieldsLen; + + /** Stores the maximum score value encountered, for normalizing. + * we only care about scores greater than 1.0 - if all the scores + * are less than 1.0, we don't have to normalize. */ + float_t maxscore; + + /** + * Returns whether a is less relevant than b. + * @param a ScoreDoc + * @param b ScoreDoc + * @return true if document a should be sorted after document b. + */ + bool lessThan (FieldDoc* docA, FieldDoc* docB); +public: + + /** + * Creates a hit queue sorted by the given list of fields. + * @param reader Index to use. + * @param fields Field names, in priority order (highest priority first). Cannot be null or empty. + * @param size The number of hits to retain. Must be greater than zero. + * @throws IOException + */ + FieldSortedHitQueue (CL_NS(index)::IndexReader* reader, SortField** fields, int32_t size); + + ~FieldSortedHitQueue(); + + /** + * Callback for when IndexReader closes. This causes + * any Comparators to be removed for the specified reader. + */ + static void closeCallback(CL_NS(index)::IndexReader* reader, void* param); + + /** + * Given a FieldDoc object, stores the values used + * to sort the given document. These values are not the raw + * values out of the index, but the internal representation + * of them. This is so the given search hit can be collated + * by a MultiSearcher with other search hits. + * @param doc The FieldDoc to store sort values into. + * @return The same FieldDoc passed in. + * @see Searchable#search(Query,Filter,int32_t,Sort) + */ + FieldDoc* fillFields (FieldDoc* doc) const; + + void setFields (SortField** fields){ + this->fields = fields; + } + + /** Returns the SortFields being used by this hit queue. */ + SortField** getFields() { + return fields; + } +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Filter.h b/src/core/CLucene/search/Filter.h new file mode 100644 index 00000000000..a2c35fc7256 --- /dev/null +++ b/src/core/CLucene/search/Filter.h @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Filter_ +#define _lucene_search_Filter_ + +CL_CLASS_DEF(util,BitSet) +CL_CLASS_DEF(index,IndexReader) + +CL_NS_DEF(search) + // Abstract base class providing a mechanism to restrict searches to a subset + // of an index. + class CLUCENE_EXPORT Filter: LUCENE_BASE { + public: + virtual ~Filter(){ + } + + virtual Filter* clone() const = 0; + + /** + * Returns a BitSet with true for documents which should be permitted in + * search results, and false for those that should not. + * @memory see {@link #shouldDeleteBitSet} + */ + virtual CL_NS(util)::BitSet* bits(CL_NS(index)::IndexReader* reader)=0; + + /** + * Because of the problem of cached bitsets with the CachingWrapperFilter, + * CLucene has no way of knowing whether to delete the bitset returned from bits(). + * To properly clean memory from bits(), pass the bitset to this function. The + * Filter should be deleted if this function returns true. + */ + virtual bool shouldDeleteBitSet(const CL_NS(util)::BitSet*) const{ return true; } + + //Creates a user-readable version of this query and returns it as as string + virtual TCHAR* toString()=0; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/FilterResultCache.cpp b/src/core/CLucene/search/FilterResultCache.cpp new file mode 100644 index 00000000000..b382088811e --- /dev/null +++ b/src/core/CLucene/search/FilterResultCache.cpp @@ -0,0 +1,48 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CachingWrapperFilter.h" +#include "CLucene/index/IndexReader.h" + +CL_NS_DEF(search) +CL_NS_USE(index) +CL_NS_USE(util) + + +template +FilterResultCache::FilterResultCache( bool bDeleteResults ) +{ + this->bDeleteResults = bDeleteResults; +} + +template +FilterResultCache::~FilterResultCache() +{ +} + +template +T* FilterResultCache::getResult( CL_NS(index)::IndexReader* reader ) +{ + SCOPED_LOCK_MUTEX( cache_LOCK ) + ResultHolder * cached = cache.get( reader ); + if( cached != NULL ) + return cached->result; + + T * result = fiter->( reader ); + ResultHolder * holder = _CLNEW ResultHolder( result, bDeleteResults ); + cache.put( reader, holder ); + return result; +} + +template +void FilterResultCache::closeCallback( CL_NS(index)::IndexReader* reader, void* ) +{ + SCOPED_LOCK_MUTEX( cache_LOCK ) + cache.remove( reader ); +} + +CL_NS_END diff --git a/src/core/CLucene/search/FilterResultCache.h b/src/core/CLucene/search/FilterResultCache.h new file mode 100644 index 00000000000..d937c016ae8 --- /dev/null +++ b/src/core/CLucene/search/FilterResultCache.h @@ -0,0 +1,68 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FilterResultCache_ +#define _lucene_search_FilterResultCache_ + +CL_CLASS_DEF(index,IndexReader) + +CL_NS_DEF(search) + +/** + * Holds one cached result + */ +template +class ResultHolder : LUCENE_BASE +{ + bool deleteRes; +public: + T* result; + + ResultHolder( T * result, bool deleteRes ) + { + this->result = result; + this->deleteRes = deleteRes; + } + ~ResultHolder(){ + if ( deleteRes ) + _CLDELETE( result ); + } +}; + +/** + * Wraps another filter's result and caches it. The purpose is to allow + * filters to implement this and allow itself to be cached. Alternatively, + * use the CachingWrapperFilter to cache the filter. + */ +template +class FilterResultCache +{ + typedef CL_NS(util)::CLHashMap< + CL_NS(index)::IndexReader*, + BitSetHolder*, + CL_NS(util)::Compare::Void, + CL_NS(util)::Equals::Void, + CL_NS(util)::Deletor::Object, + CL_NS(util)::Deletor::Object > + > CacheType; + + CacheType cache; + bool bDeleteResults; + DEFINE_MUTEX( cache_LOCK ) + + +public: + FilterResultCache( bool bDeleteResults ); + virtual ~FilterResultCache(); + + T* getResult( CL_NS(index)::IndexReader* reader ); + +protected: + void closeCallback( CL_NS(index)::IndexReader* reader, void* param ); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/FilteredTermEnum.cpp b/src/core/CLucene/search/FilteredTermEnum.cpp new file mode 100644 index 00000000000..9ac7f314dc2 --- /dev/null +++ b/src/core/CLucene/search/FilteredTermEnum.cpp @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "FilteredTermEnum.h" +#include "CLucene/index/Term.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + + +FilteredTermEnum::FilteredTermEnum():currentTerm(NULL),actualEnum(NULL){ +} + + FilteredTermEnum::~FilteredTermEnum() { + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + close(); + } + + int32_t FilteredTermEnum::docFreq() const { + //Func - Returns the docFreq of the current Term in the enumeration. + //Pre - next() must have been called at least once + //Post - if actualEnum is NULL result is -1 otherwise the frequencey is returned + + if (actualEnum == NULL){ + return -1; + } + return actualEnum->docFreq(); + } + + bool FilteredTermEnum::next() { + //Func - Increments the enumeration to the next element. + //Pre - true + //Post - Returns True if the enumeration has been moved to the next element otherwise false + + //The actual enumerator is not initialized! + if (actualEnum == NULL){ + return false; + } + + //Finalize the currentTerm and reset it to NULL + _CLDECDELETE( currentTerm ); + + //Iterate through the enumeration + while (currentTerm == NULL) { + if (endEnum()) + return false; + if (actualEnum->next()) { + //Order term not to return reference ownership here. */ + Term* term = actualEnum->term(false); + //Compare the retrieved term + if (termCompare(term)){ + //Matched so finalize the current + _CLDECDELETE(currentTerm); + //Get a reference to the matched term + currentTerm = _CL_POINTER(term); + return true; + } + }else + return false; + } + _CLDECDELETE(currentTerm); + currentTerm = NULL; + + return false; + } + + Term* FilteredTermEnum::term(bool pointer) { + if ( pointer ) + return _CL_POINTER(currentTerm); + else + return currentTerm; + } + + void FilteredTermEnum::close(){ + //Func - Closes the enumeration to further activity, freeing resources. + //Pre - true + //Post - The Enumeration has been closed + + //Check if actualEnum is valid + if (actualEnum){ + //Close the enumeration + actualEnum->close(); + //Destroy the enumeration + _CLDELETE(actualEnum); + } + + //Destroy currentTerm + _CLDECDELETE(currentTerm); + } + + void FilteredTermEnum::setEnum(TermEnum* actualEnum) { + //Func - Sets the actual Enumeration + //Pre - actualEnum != NULL + //Post - The instance has been created + + CND_PRECONDITION(actualEnum != NULL,"actualEnum is NULL"); + + _CLLDELETE(this->actualEnum); + this->actualEnum = actualEnum; + + // Find the first term that matches + //Ordered term not to return reference ownership here. + Term* term = actualEnum->term(false); + if (term != NULL && termCompare(term)){ + _CLDECDELETE(currentTerm); + currentTerm = _CL_POINTER(term); + }else{ + next(); + } + } + +CL_NS_END diff --git a/src/core/CLucene/search/FilteredTermEnum.h b/src/core/CLucene/search/FilteredTermEnum.h new file mode 100644 index 00000000000..39385df3a3d --- /dev/null +++ b/src/core/CLucene/search/FilteredTermEnum.h @@ -0,0 +1,58 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FilteredTermEnum_ +#define _lucene_search_FilteredTermEnum_ + + +CL_CLASS_DEF(index,Term) +#include "CLucene/index/Terms.h" + +CL_NS_DEF(search) +/** Abstract class for enumerating a subset of all terms. + +

Term enumerations are always ordered by Term.compareTo(). Each term in +the enumeration is greater than all that precede it. */ +class CLUCENE_EXPORT FilteredTermEnum: public CL_NS(index)::TermEnum { +public: + FilteredTermEnum(); + virtual ~FilteredTermEnum(); + + /** Equality measure on the term */ + virtual float_t difference() = 0; + + /** + * Returns the docFreq of the current Term in the enumeration. + * Returns -1 if no Term matches or all terms have been enumerated. + */ + int32_t docFreq() const; + + /** Increments the enumeration to the next element. True if one exists. */ + bool next() ; + + /** Returns the current Term in the enumeration. + * Returns null if no Term matches or all terms have been enumerated. */ + CL_NS(index)::Term* term(bool pointer=true); + + /** Closes the enumeration to further activity, freeing resources. */ + void close(); + +protected: + /** Equality compare on the term */ + virtual bool termCompare(CL_NS(index)::Term* term) = 0; + + /** Indicates the end of the enumeration has been reached */ + virtual bool endEnum() = 0; + + void setEnum(CL_NS(index)::TermEnum* actualEnum) ; + +private: + CL_NS(index)::Term* currentTerm; + CL_NS(index)::TermEnum* actualEnum; + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/FuzzyQuery.cpp b/src/core/CLucene/search/FuzzyQuery.cpp new file mode 100644 index 00000000000..16071a01fff --- /dev/null +++ b/src/core/CLucene/search/FuzzyQuery.cpp @@ -0,0 +1,425 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/IndexReader.h" +#include "Similarity.h" +#include "FuzzyQuery.h" +#include "BooleanQuery.h" +#include "BooleanClause.h" +#include "TermQuery.h" + +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/PriorityQueue.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + +/** Finds and returns the smallest of three integers + * precondition: Must define int32_t __t for temporary storage and result + */ +#define min3(a, b, c) __t = (a < b) ? a : b; __t = (__t < c) ? __t : c; + + + FuzzyTermEnum::FuzzyTermEnum(IndexReader* reader, Term* term, float_t minSimilarity, size_t _prefixLength): + FilteredTermEnum(),d(NULL),dLen(0),_similarity(0),_endEnum(false),searchTerm(_CL_POINTER(term)), + text(NULL),textLen(0),prefix(NULL)/* ISH: was STRDUP_TtoT(LUCENE_BLANK_STRING)*/,prefixLength(0), + minimumSimilarity(minSimilarity) + { + CND_PRECONDITION(term != NULL,"term is NULL"); + + if (minSimilarity >= 1.0f) + _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity cannot be greater than or equal to 1"); + else if (minSimilarity < 0.0f) + _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity cannot be less than 0"); + + scale_factor = 1.0f / (1.0f - minimumSimilarity); // only now we are safe from a division by zero + //TODO: this.field = searchTerm.field(); + + //The prefix could be longer than the word. + //It's kind of silly though. It means we must match the entire word. + const size_t fullSearchTermLength = searchTerm->textLength(); + const size_t realPrefixLength = _prefixLength > fullSearchTermLength ? fullSearchTermLength : _prefixLength; + + text = STRDUP_TtoT(searchTerm->text() + realPrefixLength); + textLen = fullSearchTermLength - realPrefixLength; + + prefix = _CL_NEWARRAY(TCHAR,realPrefixLength+1); + _tcsncpy(prefix, searchTerm->text(), realPrefixLength); + prefix[realPrefixLength]='\0'; + prefixLength = realPrefixLength; + + initializeMaxDistances(); + + Term* trm = _CLNEW Term(searchTerm->field(), prefix); // _CLNEW Term(term, prefix); -- not intern'd? + setEnum(reader->terms(trm)); + _CLLDECDELETE(trm); + + + /* LEGACY: + //Initialize e to NULL + e = NULL; + eWidth = 0; + eHeight = 0; + + if(prefixLength > 0 && prefixLength < textLen){ + this->prefixLength = prefixLength; + + prefix = _CL_NEWARRAY(TCHAR,prefixLength+1); + _tcsncpy(prefix,text,prefixLength); + prefix[prefixLength]='\0'; + + textLen = prefixLength; + text[textLen]='\0'; + } + */ + } + + FuzzyTermEnum::~FuzzyTermEnum(){ + close(); + } + + const char* FuzzyTermEnum::getObjectName() const{ return getClassName(); } + const char* FuzzyTermEnum::getClassName(){ return "FuzzyTermEnum"; } + + bool FuzzyTermEnum::endEnum() { + return _endEnum; + } + + void FuzzyTermEnum::close(){ + + FilteredTermEnum::close(); + + //Finalize the searchTerm + _CLDECDELETE(searchTerm); + + free(d); + d=NULL; + + _CLDELETE_CARRAY(text); + + _CLDELETE_CARRAY(prefix); + } + + bool FuzzyTermEnum::termCompare(Term* term) { + //Func - Compares term with the searchTerm using the Levenshtein distance. + //Pre - term is NULL or term points to a Term + //Post - if pre(term) is NULL then false is returned otherwise + // if the distance of the current term in the enumeration is bigger than the FUZZY_THRESHOLD + // then true is returned + + if (term == NULL){ + return false; //Note that endEnum is not set to true! + } + + const TCHAR* termText = term->text(); + const size_t termTextLen = term->textLength(); + + //Check if the field name of searchTerm of term match + //(we can use == because fields are interned) + if ( searchTerm->field() == term->field() && + (prefixLength==0 || _tcsncmp(termText,prefix,prefixLength)==0 )) { + + const TCHAR* target = termText+prefixLength; + const size_t targetLen = termTextLen-prefixLength; + _similarity = similarity(target, targetLen); + return (_similarity > minimumSimilarity); + } + _endEnum = true; + return false; + } + + float_t FuzzyTermEnum::difference() { + return (float_t)((_similarity - minimumSimilarity) * scale_factor ); + } + + // TODO: had synchronized in definition + float_t FuzzyTermEnum::similarity(const TCHAR* target, const size_t m) { + const size_t n = textLen; // TODO: remove after replacing n with textLen + if (n == 0) { + //we don't have anything to compare. That means if we just add + //the letters for m we get the new word + return prefixLength == 0 ? 0.0f : 1.0f - ((float_t) m / prefixLength); + } + if (m == 0) { + return prefixLength == 0 ? 0.0f : 1.0f - ((float_t) n / prefixLength); + } + + const uint32_t maxDistance = getMaxDistance(m); + + if ( maxDistance < (uint32_t)(abs((int32_t)(m-n))) ) { + //just adding the characters of m to n or vice-versa results in + //too many edits + //for example "pre" length is 3 and "prefixes" length is 8. We can see that + //given this optimal circumstance, the edit distance cannot be less than 5. + //which is 8-3 or more precisesly Math.abs(3-8). + //if our maximum edit distance is 4, then we can discard this word + //without looking at it. + return 0.0f; + } + + //let's make sure we have enough room in our array to do the distance calculations. + //Check if the array must be reallocated because it is too small or does not exist + size_t dWidth = n+1; + size_t dHeight = m+1; + if (d == NULL){ + dLen = dWidth*dHeight; + d = (int32_t*)(malloc(sizeof(int32_t)*dLen)); + } else if (dLen < dWidth*dHeight) { + dLen = dWidth*dHeight; + d = (int32_t*)(realloc(d, sizeof(int32_t)*dLen)); + } + memset(d,0,dLen); + + size_t i; // iterates through the source string + size_t j; // iterates through the target string + + // init matrix d + for (i = 0; i <= n; i++){ + d[i + (0*dWidth)] = i; + } + for (j = 0; j <= m; j++){ + d[0 + (j*dWidth)] = j; + } + + int32_t __t; //temporary variable for min3 + + // start computing edit distance + TCHAR s_i; // ith character of s + for (i = 1; i <= n; i++) { + size_t bestPossibleEditDistance = m; + s_i = text[i - 1]; + for (j = 1; j <= m; j++) { + if (s_i != target[j-1]) { + min3(d[i-1 + (j*dWidth)], d[i + ((j-1)*dWidth)], d[i-1 + ((j-1)*dWidth)]); + d[i + (j*dWidth)] = __t+1; + } + else { + min3(d[i-1 + (j*dWidth)]+1, d[i + ((j-1)*dWidth)]+1, d[i-1 + ((j-1)*dWidth)]); + d[i + (j*dWidth)] = __t; + } + bestPossibleEditDistance = cl_min(bestPossibleEditDistance, d[i + (j*dWidth)]); + } + + //After calculating row i, the best possible edit distance + //can be found by finding the smallest value in a given column. + //If the bestPossibleEditDistance is greater than the max distance, abort. + + if (i > maxDistance && bestPossibleEditDistance > maxDistance) { //equal is okay, but not greater + //the closest the target can be to the text is just too far away. + //this target is leaving the party early. + return 0.0f; + } + } + + // this will return less than 0.0 when the edit distance is + // greater than the number of characters in the shorter word. + // but this was the formula that was previously used in FuzzyTermEnum, + // so it has not been changed (even though minimumSimilarity must be + // greater than 0.0) + return 1.0f - ((float_t)d[n + m*dWidth] / (float_t) (prefixLength + cl_min(n, m))); + } + + int32_t FuzzyTermEnum::getMaxDistance(const size_t m) { + return (m < LUCENE_TYPICAL_LONGEST_WORD_IN_INDEX) ? maxDistances[m] : calculateMaxDistance(m); + } + + void FuzzyTermEnum::initializeMaxDistances() { + for (int32_t i = 0; i < LUCENE_TYPICAL_LONGEST_WORD_IN_INDEX; i++) { + maxDistances[i] = calculateMaxDistance(i); + } + } + + int32_t FuzzyTermEnum::calculateMaxDistance(const size_t m) const { + return (int32_t) ((1-minimumSimilarity) * (cl_min(textLen, m) + prefixLength)); + } + + // TODO: Make ScoreTerm and ScoreTermQueue reside under FuzzyQuery + class ScoreTerm { + public: + Term* term; + float_t score; + + ScoreTerm(Term* _term, float_t _score):term(_term),score(_score){ + } + virtual ~ScoreTerm(){ + _CLLDECDELETE(term); + } + }; + + class ScoreTermQueue : public PriorityQueue > { + public: + ScoreTermQueue(int32_t size){ + initialize(size, true); + } + virtual ~ScoreTermQueue(){ + } + + protected: + bool lessThan(ScoreTerm* termA, ScoreTerm* termB) { + if (termA->score == termB->score) + return termA->term->compareTo(termB->term) > 0; + else + return termA->score < termB->score; + } + }; + + + FuzzyQuery::FuzzyQuery(Term* term, float_t _minimumSimilarity, size_t _prefixLength): + MultiTermQuery(term), + minimumSimilarity(_minimumSimilarity), + prefixLength(_prefixLength) + { + if ( minimumSimilarity < 0 ) + minimumSimilarity = defaultMinSimilarity; + + CND_PRECONDITION(term != NULL,"term is NULL"); + + if (minimumSimilarity >= 1.0f) + _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity >= 1"); + else if (minimumSimilarity < 0.0f) + _CLTHROWA(CL_ERR_IllegalArgument,"minimumSimilarity < 0"); + } + + float_t FuzzyQuery::defaultMinSimilarity = 0.5f; + int32_t FuzzyQuery::defaultPrefixLength = 0; + + FuzzyQuery::~FuzzyQuery(){ + } + + float_t FuzzyQuery::getMinSimilarity() const { + return minimumSimilarity; + } + + size_t FuzzyQuery::getPrefixLength() const { + return prefixLength; + } + + TCHAR* FuzzyQuery::toString(const TCHAR* field) const{ + StringBuffer buffer(100); // TODO: Have a better estimation for the initial buffer length + Term* term = getTerm(false); // no need to increase ref count + if ( field==NULL || _tcscmp(term->field(),field)!=0 ) { + buffer.append(term->field()); + buffer.appendChar( _T(':')); + } + buffer.append(term->text()); + buffer.appendChar( _T('~') ); + buffer.appendFloat(minimumSimilarity,1); + buffer.appendBoost(getBoost()); + return buffer.giveBuffer(); + } + + const char* FuzzyQuery::getObjectName() const{ + //Func - Returns the name of the query + //Pre - true + //post - The string FuzzyQuery has been returned + + return getClassName(); + } + const char* FuzzyQuery::getClassName(){ + //Func - Returns the name of the query + //Pre - true + //post - The string FuzzyQuery has been returned + + return "FuzzyQuery"; + } + + FuzzyQuery::FuzzyQuery(const FuzzyQuery& clone): + MultiTermQuery(clone) + { + this->minimumSimilarity = clone.getMinSimilarity(); + this->prefixLength = clone.getPrefixLength(); + + //if(prefixLength < 0) + // _CLTHROWA(CL_ERR_IllegalArgument,"prefixLength < 0"); + //else + if(prefixLength >= clone.getTerm()->textLength()) + _CLTHROWA(CL_ERR_IllegalArgument,"prefixLength >= term.textLength()"); + + } + + Query* FuzzyQuery::clone() const{ + return _CLNEW FuzzyQuery(*this); + } + size_t FuzzyQuery::hashCode() const{ + //todo: we should give the query a seeding value... but + //need to do it for all hascode functions + // TODO: does not conform with JL + size_t val = Similarity::floatToByte(getBoost()) ^ getTerm()->hashCode(); + val ^= Similarity::floatToByte(this->getMinSimilarity()); + val ^= this->getPrefixLength(); + return val; + } + bool FuzzyQuery::equals(Query* other) const{ + if (this == other) return true; + if (!(other->instanceOf(FuzzyQuery::getClassName()))) + return false; + + FuzzyQuery* fq = static_cast(other); + return (this->getBoost() == fq->getBoost()) + && this->minimumSimilarity == fq->getMinSimilarity() + && this->prefixLength == fq->getPrefixLength() + && getTerm()->equals(fq->getTerm()); + } + + FilteredTermEnum* FuzzyQuery::getEnum(IndexReader* reader){ + Term* term = getTerm(false); + FuzzyTermEnum* ret = _CLNEW FuzzyTermEnum(reader, term, minimumSimilarity, prefixLength); + return ret; + } + + Query* FuzzyQuery::rewrite(IndexReader* reader) { + FilteredTermEnum* enumerator = getEnum(reader); + const size_t maxClauseCount = BooleanQuery::getMaxClauseCount(); + ScoreTermQueue* stQueue = _CLNEW ScoreTermQueue(maxClauseCount); + ScoreTerm* reusableST = NULL; + + try { + do { + float_t score = 0.0f; + Term* t = enumerator->term(); + if (t != NULL) { + score = enumerator->difference(); + if (reusableST == NULL) { + reusableST = _CLNEW ScoreTerm(t, score); + } else if (score >= reusableST->score) { + // reusableST holds the last "rejected" entry, so, if + // this new score is not better than that, there's no + // need to try inserting it + reusableST->score = score; + reusableST->term = t; + } else { + continue; + } + + reusableST = stQueue->insertWithOverflow(reusableST); + } + } while (enumerator->next()); + } _CLFINALLY({ + enumerator->close(); + _CLLDELETE(enumerator); + //_CLLDELETE(reusableST); + }); + + BooleanQuery* query = _CLNEW BooleanQuery(true); + const size_t size = stQueue->size(); + for(size_t i = 0; i < size; i++){ + ScoreTerm* st = stQueue->pop(); + TermQuery* tq = _CLNEW TermQuery(st->term); // found a match + tq->setBoost(getBoost() * st->score); // set the boost + query->add(tq, true, BooleanClause::SHOULD); // add to query + _CLLDELETE(st); + } + _CLLDELETE(stQueue); + + return query; + } + + +CL_NS_END diff --git a/src/core/CLucene/search/FuzzyQuery.h b/src/core/CLucene/search/FuzzyQuery.h new file mode 100644 index 00000000000..9c8a58ae68f --- /dev/null +++ b/src/core/CLucene/search/FuzzyQuery.h @@ -0,0 +1,204 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FuzzyQuery_ +#define _lucene_search_FuzzyQuery_ + +#include "MultiTermQuery.h" +#include "FilteredTermEnum.h" + +CL_CLASS_DEF(index,Term) + +CL_NS_DEF(search) + +/** Implements the fuzzy search query. The similiarity measurement +* is based on the Levenshtein (edit distance) algorithm. +*/ +class CLUCENE_EXPORT FuzzyQuery : public MultiTermQuery { +private: + float_t minimumSimilarity; + size_t prefixLength; +protected: + FuzzyQuery(const FuzzyQuery& clone); +public: + static float_t defaultMinSimilarity; + static int32_t defaultPrefixLength; + + /** + * Create a new FuzzyQuery that will match terms with a similarity + * of at least minimumSimilarity to term. + * If a prefixLength > 0 is specified, a common prefix + * of that length is also required. + * + * @param term the term to search for + * @param minimumSimilarity a value between 0 and 1 to set the required similarity + * between the query term and the matching terms. For example, for a + * minimumSimilarity of 0.5 a term of the same length + * as the query term is considered similar to the query term if the edit distance + * between both terms is less than length(term)*0.5 + * @param prefixLength length of common (non-fuzzy) prefix + * @throws IllegalArgumentException if minimumSimilarity is > 1 or < 0 + * or if prefixLength < 0 or > term.text().length(). + */ + FuzzyQuery(CL_NS(index)::Term* term, float_t minimumSimilarity=-1, size_t prefixLength=0); + virtual ~FuzzyQuery(); + + /** + * Returns the minimum similarity that is required for this query to match. + * @return float value between 0.0 and 1.0 + */ + float_t getMinSimilarity() const; + + /** + * Returns the prefix length, i.e. the number of characters at the start + * of a term that must be identical (not fuzzy) to the query term if the query + * is to match that term. + */ + size_t getPrefixLength() const; + + Query* rewrite(CL_NS(index)::IndexReader* reader); + + TCHAR* toString(const TCHAR* field) const; + + //Returns the name "FuzzyQuery" + static const char* getClassName(); + const char* getObjectName() const; + + Query* clone() const; + bool equals(Query * other) const; + size_t hashCode() const; + +protected: + FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader); +}; + +/** Subclass of FilteredTermEnum for enumerating all terms that are similiar +* to the specified filter term. +* +*

Term enumerations are always ordered by Term.compareTo(). Each term in +* the enumeration is greater than all that precede it. +*/ +class CLUCENE_EXPORT FuzzyTermEnum: public FilteredTermEnum { +private: + /* Allows us save time required to create a new array + * everytime similarity is called. + */ + int32_t* d; + size_t dLen; + + //float_t distance; + float_t _similarity; + bool _endEnum; + + CL_NS(index)::Term* searchTerm; + //String field; + TCHAR* text; + size_t textLen; + TCHAR* prefix; + size_t prefixLength; + + float_t minimumSimilarity; + double scale_factor; + int32_t maxDistances[LUCENE_TYPICAL_LONGEST_WORD_IN_INDEX]; + + /****************************** + * Compute Levenshtein distance + ******************************/ + + /** + *

Similarity returns a number that is 1.0f or less (including negative numbers) + * based on how similar the Term is compared to a target term. It returns + * exactly 0.0f when + *

+	*    editDistance < maximumEditDistance
+ * Otherwise it returns: + *
+	*    1 - (editDistance / length)
+ * where length is the length of the shortest term (text or target) including a + * prefix that are identical and editDistance is the Levenshtein distance for + * the two words.

+ * + *

Embedded within this algorithm is a fail-fast Levenshtein distance + * algorithm. The fail-fast algorithm differs from the standard Levenshtein + * distance algorithm in that it is aborted if it is discovered that the + * mimimum distance between the words is greater than some threshold. + * + *

To calculate the maximum distance threshold we use the following formula: + *

+	*     (1 - minimumSimilarity) * length
+ * where length is the shortest term including any prefix that is not part of the + * similarity comparision. This formula was derived by solving for what maximum value + * of distance returns false for the following statements: + *
+	*   similarity = 1 - ((float)distance / (float) (prefixLength + Math.min(textlen, targetlen)));
+	*   return (similarity > minimumSimilarity);
+ * where distance is the Levenshtein distance for the two words. + *

+ *

Levenshtein distance (also known as edit distance) is a measure of similiarity + * between two strings where the distance is measured as the number of character + * deletions, insertions or substitutions required to transform one string to + * the other string. + * @param target the target word or phrase + * @return the similarity, 0.0 or less indicates that it matches less than the required + * threshold and 1.0 indicates that the text and target are identical + */ + float_t similarity(const TCHAR* target, const size_t targetLen); + + /** + * The max Distance is the maximum Levenshtein distance for the text + * compared to some other value that results in score that is + * better than the minimum similarity. + * @param m the length of the "other value" + * @return the maximum levenshtein distance that we care about + */ + int32_t getMaxDistance(const size_t m); + + void initializeMaxDistances(); + + int32_t calculateMaxDistance(const size_t m) const; + +protected: + /** + * The termCompare method in FuzzyTermEnum uses Levenshtein distance to + * calculate the distance between the given term and the comparing term. + */ + bool termCompare(CL_NS(index)::Term* term) ; + + /** Returns the fact if the current term in the enumeration has reached the end */ + bool endEnum(); +public: + + /** + * Constructor for enumeration of all terms from specified reader which share a prefix of + * length prefixLength with term and which have a fuzzy similarity > + * minSimilarity. + *

+ * After calling the constructor the enumeration is already pointing to the first + * valid term if such a term exists. + * + * @param reader Delivers terms. + * @param term Pattern term. + * @param minSimilarity Minimum required similarity for terms from the reader. Default value is 0.5f. + * @param prefixLength Length of required common prefix. Default value is 0. + * @throws IOException + */ + FuzzyTermEnum(CL_NS(index)::IndexReader* reader, CL_NS(index)::Term* term, float_t minSimilarity=FuzzyQuery::defaultMinSimilarity, size_t prefixLength=0); + virtual ~FuzzyTermEnum(); + + /** Close the enumeration */ + void close(); + + /** Returns the difference between the distance and the fuzzy threshold + * multiplied by the scale factor + */ + float_t difference(); + + const char* getObjectName() const; + static const char* getClassName(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/HitQueue.cpp b/src/core/CLucene/search/HitQueue.cpp new file mode 100644 index 00000000000..0d4191b2042 --- /dev/null +++ b/src/core/CLucene/search/HitQueue.cpp @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "SearchHeader.h" +#include "_HitQueue.h" + +CL_NS_DEF(search) + +void HitQueue::upHeap(){ + size_t i = _size; + ScoreDoc node = heap[i]; // save bottom node (WAS object) + int32_t j = ((uint32_t)i) >> 1; + while (j > 0 && lessThan(node,heap[j])) { + heap[i] = heap[j]; // shift parents down + i = j; + j = ((uint32_t)j) >> 1; + } + heap[i] = node; // install saved node +} +void HitQueue::downHeap(){ + size_t i = 1; + ScoreDoc node = heap[i]; // save top node + size_t j = i << 1; // find smaller child + size_t k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { + j = k; + } + while (j <= _size && lessThan(heap[j],node)) { + heap[i] = heap[j]; // shift up child + i = j; + j = i << 1; + k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { + j = k; + } + } + heap[i] = node; // install saved node +} + +void HitQueue::adjustTop(){ + downHeap(); +} +size_t HitQueue::size(){ + return _size; +} + +struct ScoreDoc& HitQueue::top(){ + if ( _size == 0 ) + _CLTHROWA(CL_ERR_IndexOutOfBounds, "Attempted to access empty hitqueue::top"); + return heap[1]; +} + +void HitQueue::put(struct ScoreDoc& element){ + if ( _size>=maxSize ) + _CLTHROWA(CL_ERR_IndexOutOfBounds,"add is out of bounds"); + + _size++; + heap[_size] = element; + upHeap(); +} + +ScoreDoc HitQueue::pop(){ + if (_size > 0) { + ScoreDoc result = heap[1]; // save first value + heap[1] = heap[_size]; // move last to first + + _size--; + downHeap(); // adjust heap + return result; + } else + _CLTHROWA(CL_ERR_IndexOutOfBounds, "Attempted to access empty hitqueue::top"); +} + +bool HitQueue::insert(struct ScoreDoc& element){ + if(_size < maxSize){ + put(element); + return true; + }else if(_size > 0 && !lessThan(element, heap[1])){ + heap[1] = element; + adjustTop(); + return true; + }else + return false; +} + +HitQueue::HitQueue(const int32_t maxSize){ + _size = 0; + this->maxSize = maxSize; + int32_t heapSize = maxSize + 1; + heap = new ScoreDoc[heapSize]; +} +HitQueue::~HitQueue(){ + delete [] heap; +} + +bool HitQueue::lessThan(struct ScoreDoc& hitA, struct ScoreDoc& hitB){ + if (hitA.score == hitB.score) + return hitA.doc > hitB.doc; + else + return hitA.score < hitB.score; +} + + +CL_NS_END diff --git a/src/core/CLucene/search/Hits.cpp b/src/core/CLucene/search/Hits.cpp new file mode 100644 index 00000000000..5dee7354916 --- /dev/null +++ b/src/core/CLucene/search/Hits.cpp @@ -0,0 +1,232 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Hits.h" +#include "SearchHeader.h" +#include "CLucene/document/Document.h" +#include "CLucene/index/IndexReader.h" +#include "Filter.h" +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/IndexSearcher.h" + +CL_NS_USE(document) +CL_NS_USE(util) +CL_NS_USE(index) + +CL_NS_DEF(search) + +const size_t DEFAULT_ONE_TIME_MORE_DOCS = 1000000; +const size_t DEFAULT_MAX_DOCS_CACHE = DEFAULT_ONE_TIME_MORE_DOCS*6; + + HitDoc::HitDoc(const float_t s, const int32_t i) + { + //Func - Constructor + //Pre - true + //Post - The instance has been created + + next = NULL; + prev = NULL; + doc = NULL; + score = s; + id = i; + } + + HitDoc::~HitDoc(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLLDELETE(doc); + } + + + Hits::Hits(Searcher* s, Query* q, Filter* f, const Sort* _sort, size_t nlimit): + query(q), searcher(s), filter(f), sort(_sort) , _length(0), first(NULL), last(NULL), + numDocs(0), maxDocs(DEFAULT_MAX_DOCS_CACHE), nDeletedHits(0), debugCheckedForDeletions(false), + nLimit(nlimit) + { + //Func - Constructor + //Pre - s contains a valid reference to a searcher s + // q contains a valid reference to a Query + // f is NULL or contains a pointer to a filter + //Post - The instance has been created + + hitDocs = _CLNEW CL_NS(util)::CLVector >; + nDeletions = countDeletions(s); + + size_t initial_read_docs = DEFAULT_ONE_TIME_MORE_DOCS; + if (nLimit) + { + auto maxSize = std::min(nLimit, DEFAULT_ONE_TIME_MORE_DOCS); + maxDocs = maxSize * 2; + initial_read_docs = maxSize; + } + //retrieve "n" initially + getMoreDocs(initial_read_docs); + + _lengthAtStart = _length; + } + + Hits::~Hits(){ + _CLLDELETE(hitDocs); + } + + // count # deletions, return -1 if unknown. + int32_t Hits::countDeletions(CL_NS(search)::Searcher* s) { + int32_t cnt = -1; + if ( s->getObjectName() == IndexSearcher::getClassName() ) { + cnt = s->maxDoc() - static_cast(s)->getReader()->numDocs(); + } + return cnt; + } + + size_t Hits::length() const { + return _length; + } + + Document& Hits::doc(const int32_t n){ + HitDoc* hitDoc = getHitDoc(n); + + // Update LRU cache of documents + remove(hitDoc); // remove from list, if there + addToFront(hitDoc); // add to front of list + if (numDocs > maxDocs) { // if cache is full + HitDoc* oldLast = last; + remove(last); // flush last + + _CLLDELETE( oldLast->doc ); + oldLast->doc = NULL; + } + + if (hitDoc->doc == NULL){ + hitDoc->doc = _CLNEW Document; + searcher->doc(hitDoc->id, hitDoc->doc); // cache miss: read document + } + + return *hitDoc->doc; + } + + int32_t Hits::id (const int32_t n){ + return getHitDoc(n)->id; + } + + float_t Hits::score(const int32_t n){ + return getHitDoc(n)->score; + } + + void Hits::getMoreDocs(const size_t m){ + auto get_min = [needs = m](const size_t hits) + { + size_t _min = needs; + if(hits > _min) + _min = hits; + + // double # retrieved + return _min+_min; + }; + + size_t n = nLimit ? nLimit : get_min(hitDocs->size()); + TopDocs* topDocs = NULL; + if ( sort==NULL ) + topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n); + else + topDocs = (TopDocs*)((Searchable*)searcher)->_search(query, filter, n, sort); + _length = topDocs->totalHits; + ScoreDoc* scoreDocs = topDocs->scoreDocs; + size_t scoreDocsLength = topDocs->scoreDocsLength; + + float_t scoreNorm = 1.0f; + + //Check that scoreDocs is a valid pointer before using it + if (scoreDocs != NULL){ + if (_length > 0 && scoreDocs[0].score > 1.0f){ + scoreNorm = 1.0f / scoreDocs[0].score; + } + + int32_t start = hitDocs->size() - nDeletedHits; + + // any new deletions? + int32_t nDels2 = countDeletions(searcher); + debugCheckedForDeletions = false; + if (nDeletions < 0 || nDels2 > nDeletions) { + // either we cannot count deletions, or some "previously valid hits" might have been deleted, so find exact start point + nDeletedHits = 0; + debugCheckedForDeletions = true; + size_t i2 = 0; + for (size_t i1=0; i1size() && i2 < scoreDocsLength; i1++) { + int32_t id1 = ((*hitDocs)[i1])->id; + int32_t id2 = scoreDocs[i2].doc; + if (id1 == id2) { + i2++; + } else { + nDeletedHits++; + } + } + start = i2; + } + + size_t end = scoreDocsLength < _length ? scoreDocsLength : _length; + _length += nDeletedHits; + for (size_t i = start; i < end; i++) { + hitDocs->push_back(_CLNEW HitDoc(scoreDocs[i].score * scoreNorm, scoreDocs[i].doc)); + } + + nDeletions = nDels2; + } + + _CLDELETE(topDocs); + } + + HitDoc* Hits::getHitDoc(const size_t n){ + if (n >= _lengthAtStart){ + TCHAR buf[100]; + _sntprintf(buf, 100,_T("Not a valid hit number: %d"), (int)n); + _CLTHROWT(CL_ERR_IndexOutOfBounds, buf ); + } + if (n >= hitDocs->size()) + getMoreDocs(n); + + if (n >= _length) { + TCHAR buf[100]; + _sntprintf(buf, 100,_T("Not a valid hit number: %d"), (int)n); + _CLTHROWT(CL_ERR_ConcurrentModification, buf ); + } + + return (*hitDocs)[n]; + } + + void Hits::addToFront(HitDoc* hitDoc) { // insert at front of cache + if (first == NULL) + last = hitDoc; + else + first->prev = hitDoc; + + hitDoc->next = first; + first = hitDoc; + hitDoc->prev = NULL; + + numDocs++; + } + + void Hits::remove(const HitDoc* hitDoc) { // remove from cache + if (hitDoc->doc == NULL) // it's not in the list + return; // abort + + if (hitDoc->next == NULL) + last = hitDoc->prev; + else + hitDoc->next->prev = hitDoc->prev; + + if (hitDoc->prev == NULL) + first = hitDoc->next; + else + hitDoc->prev->next = hitDoc->next; + + numDocs--; + } + +CL_NS_END diff --git a/src/core/CLucene/search/Hits.h b/src/core/CLucene/search/Hits.h new file mode 100644 index 00000000000..38b60045ba2 --- /dev/null +++ b/src/core/CLucene/search/Hits.h @@ -0,0 +1,102 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Hits_h +#define _lucene_search_Hits_h + +#include "CLucene/util/VoidList.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(document,Document) + +CL_NS_DEF(search) + + class Query; + class Searcher; + class Filter; + class HitDoc; + class Sort; + + /** A ranked list of documents, used to hold search results. + *

+ * Caution: Iterate only over the hits needed. Iterating over all + * hits is generally not desirable and may be the source of + * performance issues. If you need to iterate over many or all hits, consider + * using the search method that takes a {@link HitCollector}. + *

+ *

Note: Deleting matching documents concurrently with traversing + * the hits, might, when deleting hits that were not yet retrieved, decrease + * {@link #length()}. In such case, + * {@link java.util.ConcurrentModificationException ConcurrentModificationException} + * is thrown when accessing hit n ≥ current_{@link #length()} + * (but n < {@link #length()}_at_start). + */ + class CLUCENE_EXPORT Hits { + private: + Query* query; + Searcher* searcher; + Filter* filter; + const Sort* sort; + + size_t _length; // the total number of hits + CL_NS(util)::CLVector >* hitDocs; // cache of hits retrieved + + HitDoc* first; // head of LRU cache + HitDoc* last; // tail of LRU cache + int32_t numDocs; // number cached + int32_t maxDocs; // max to cache + + int32_t nDeletions; // # deleted docs in the index. + size_t _lengthAtStart; // this is the number apps usually count on (although deletions can bring it down). + int32_t nDeletedHits; // # of already collected hits that were meanwhile deleted. + + bool debugCheckedForDeletions; // for test purposes. + size_t nLimit; + + /** + * Tries to add new documents to hitDocs. + * Ensures that the hit numbered _min has been retrieved. + */ + void getMoreDocs(const size_t _min); + + /** Returns the score for the nth document in this set. */ + HitDoc* getHitDoc(const size_t n); + + void addToFront(HitDoc* hitDoc); + + void remove(const HitDoc* hitDoc); + + public: + Hits(Searcher* s, Query* q, Filter* f, const Sort* sort=NULL, size_t nlimit=0); + virtual ~Hits(); + + /** Returns the total number of hits available in this set. */ + size_t length() const; + + /** Returns the stored fields of the nth document in this set. + *

Documents are cached, so that repeated requests for the same element may + * return the same Document object. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + * + * @memory Memory belongs to the hits object. Don't delete the return value. + */ + CL_NS(document)::Document& doc(const int32_t n); + + /** Returns the id for the nth document in this set. + * Note that ids may change when the index changes, so you cannot + * rely on the id to be stable. + */ + int32_t id (const int32_t n); + + /** Returns the score for the nth document in this set. */ + float_t score(const int32_t n); + + /** count # deletions, return -1 if unknown. */ + int32_t countDeletions(CL_NS(search)::Searcher* s); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/IndexSearcher.cpp b/src/core/CLucene/search/IndexSearcher.cpp new file mode 100644 index 00000000000..1461ea77c10 --- /dev/null +++ b/src/core/CLucene/search/IndexSearcher.cpp @@ -0,0 +1,441 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexSearcher.h" + +#include "SearchHeader.h" +#include "Scorer.h" +#include "_HitQueue.h" +#include "Query.h" +#include "Filter.h" +#include "_FieldDocSortedHitQueue.h" +#include "CLucene/store/Directory.h" +#include "CLucene/document/Document.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/Term.h" +#include "CLucene/util/BitSet.h" +#include "FieldSortedHitQueue.h" +#include "Explanation.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) + +CL_NS_DEF(search) + + class SimpleTopDocsCollector:public HitCollector{ + private: + float_t minScore; + const CL_NS(util)::BitSet* bits; + HitQueue* hq; + size_t nDocs; + int32_t* totalHits; + public: + SimpleTopDocsCollector(const CL_NS(util)::BitSet* bs, HitQueue* hitQueue, int32_t* totalhits, size_t ndocs, const float_t ms=-1.0f): + minScore(ms), + bits(bs), + hq(hitQueue), + nDocs(ndocs), + totalHits(totalhits) + { + } + ~SimpleTopDocsCollector(){} + void collect(const int32_t doc, const float_t score){ + if (score > 0.0f && // ignore zeroed buckets + (bits==NULL || bits->get(doc))) { // skip docs not in bits + ++totalHits[0]; + + if (hq->size() < nDocs || (minScore==-1.0f || score >= minScore)) { + ScoreDoc sd = {doc, score}; + hq->insert(sd); // update hit queue + if ( minScore != -1.0f ) + minScore = hq->top().score; // maintain minScore + } + } + } + }; + + class AllTopDocsCollector:public HitCollector { + public: + AllTopDocsCollector(const Functor& cb) : cb_(cb) {} + void collect(const int32_t doc, const float_t score) { + cb_(doc, score); + } + + private: + Functor cb_; + }; + + class SortedTopDocsCollector:public HitCollector{ + private: + const CL_NS(util)::BitSet* bits; + FieldSortedHitQueue* hq; + size_t nDocs; + int32_t* totalHits; + public: + SortedTopDocsCollector(const CL_NS(util)::BitSet* bs, FieldSortedHitQueue* hitQueue, int32_t* totalhits, size_t _nDocs): + bits(bs), + hq(hitQueue), + nDocs(_nDocs), + totalHits(totalhits) + { + } + ~SortedTopDocsCollector(){ + } + void collect(const int32_t doc, const float_t score){ + if (score > 0.0f && // ignore zeroed buckets + (bits==NULL || bits->get(doc))) { // skip docs not in bits + ++totalHits[0]; + FieldDoc* fd = _CLNEW FieldDoc(doc, score); //todo: see jlucene way... with fields def??? + if ( !hq->insert(fd) ) // update hit queue + _CLDELETE(fd); + } + } + }; + + class SimpleFilteredCollector: public HitCollector{ + private: + CL_NS(util)::BitSet* bits; + HitCollector* results; + public: + SimpleFilteredCollector(CL_NS(util)::BitSet* bs, HitCollector* collector): + bits(bs), + results(collector) + { + } + ~SimpleFilteredCollector(){ + } + protected: + void collect(const int32_t doc, const float_t score){ + if (bits->get(doc)) { // skip docs not in bits + results->collect(doc, score); + } + } + }; + + + IndexSearcher::IndexSearcher(const char* path){ + //Func - Constructor + // Creates a searcher searching the index in the named directory. */ + //Pre - path != NULL + //Post - The instance has been created + + CND_PRECONDITION(path != NULL, "path is NULL"); + + reader = IndexReader::open(path); + readerOwner = true; + } + + IndexSearcher::IndexSearcher(CL_NS(store)::Directory* directory, bool closeDirectory){ + //Func - Constructor + // Creates a searcher searching the index in the specified directory. */ + //Pre - path != NULL + //Post - The instance has been created + + CND_PRECONDITION(directory != NULL, "directory is NULL"); + + reader = IndexReader::open(directory, closeDirectory); + readerOwner = true; + } + + IndexSearcher::IndexSearcher(CL_NS(store)::Directory* directory){ + //Func - Constructor + // Creates a searcher searching the index in the specified directory. */ + //Pre - path != NULL + //Post - The instance has been created + + CND_PRECONDITION(directory != NULL, "directory is NULL"); + + reader = IndexReader::open(directory); + readerOwner = true; + } + + IndexSearcher::IndexSearcher(IndexReader* r){ + //Func - Constructor + // Creates a searcher searching the index with the provide IndexReader + //Pre - path != NULL + //Post - The instance has been created + + reader = r; + readerOwner = false; + } + + IndexSearcher::~IndexSearcher(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + close(); + } + + void IndexSearcher::close(){ + //Func - Frees resources associated with this Searcher. + //Pre - true + //Post - The resources associated have been freed + if (readerOwner && reader){ + reader->close(); + _CLDELETE(reader); + } + } + + // inherit javadoc + int32_t IndexSearcher::docFreq(const Term* term) const{ + //Func - + //Pre - reader != NULL + //Post - + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + + return reader->docFreq(term); + } + + _CL_DEPRECATED( doc(i, document) ) CL_NS(document)::Document* IndexSearcher::doc(int32_t i){ + CL_NS(document)::Document* ret = _CLNEW CL_NS(document)::Document; + if (!doc(i,ret) ) + _CLDELETE(ret); + return ret; + } + + // inherit javadoc + bool IndexSearcher::doc(int32_t i, CL_NS(document)::Document& d) { + //Func - Retrieves i-th document found + // For use by HitCollector implementations. + //Pre - reader != NULL + //Post - The i-th document has been returned + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + + return reader->document(i,d); + } + bool IndexSearcher::doc(int32_t i, CL_NS(document)::Document* d) { + //Func - Retrieves i-th document found + // For use by HitCollector implementations. + //Pre - reader != NULL + //Post - The i-th document has been returned + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + + return reader->document(i,*d); + } + + // inherit javadoc + int32_t IndexSearcher::maxDoc() const { + //Func - Return total number of documents including the ones marked deleted + //Pre - reader != NULL + //Post - The total number of documents including the ones marked deleted + // has been returned + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + + return reader->maxDoc(); + } + + //todo: find out why we are passing Query* and not Weight*, as Weight is being extracted anyway from Query* + TopDocs* IndexSearcher::_search(Query* query, Filter* filter, const int32_t nDocs){ + //Func - + //Pre - reader != NULL + //Post - + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + CND_PRECONDITION(query != NULL, "query is NULL"); + + Weight* weight = query->weight(this); + Scorer* scorer = weight->scorer(reader); + if (scorer == NULL) { + Query* wq = weight->getQuery(); + if (wq != query) + _CLLDELETE(wq); + _CLLDELETE(weight); + return _CLNEW TopDocs(0, NULL, 0); + } + + BitSet* bits = filter != NULL ? filter->bits(reader) : NULL; + HitQueue* hq = _CLNEW HitQueue(nDocs); + + //Check hq has been allocated properly + CND_CONDITION(hq != NULL, "Could not allocate memory for HitQueue hq"); + + int32_t* totalHits = _CL_NEWARRAY(int32_t,1); + totalHits[0] = 0; + + SimpleTopDocsCollector hitCol(bits,hq,totalHits,nDocs,0.0f); + scorer->score( &hitCol ); + _CLDELETE(scorer); + + int32_t scoreDocsLength = hq->size(); + + ScoreDoc* scoreDocs = new ScoreDoc[scoreDocsLength]; + + for (int32_t i = scoreDocsLength-1; i >= 0; --i) // put docs in array + scoreDocs[i] = hq->pop(); + + int32_t totalHitsInt = totalHits[0]; + + _CLDELETE(hq); + if ( bits != NULL && filter->shouldDeleteBitSet(bits) ) + _CLDELETE(bits); + _CLDELETE_ARRAY(totalHits); + Query* wq = weight->getQuery(); + if ( query != wq ) //query was re-written + _CLLDELETE(wq); + _CLDELETE(weight); + + return _CLNEW TopDocs(totalHitsInt, scoreDocs, scoreDocsLength); + } + + // inherit javadoc + TopFieldDocs* IndexSearcher::_search(Query* query, Filter* filter, const int32_t nDocs, + const Sort* sort) { + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + CND_PRECONDITION(query != NULL, "query is NULL"); + + Weight* weight = query->weight(this); + Scorer* scorer = weight->scorer(reader); + if (scorer == NULL){ + return _CLNEW TopFieldDocs(0, NULL, 0, NULL ); + } + + BitSet* bits = filter != NULL ? filter->bits(reader) : NULL; + FieldSortedHitQueue hq(reader, sort->getSort(), nDocs); + int32_t* totalHits = _CL_NEWARRAY(int32_t,1); + totalHits[0]=0; + + SortedTopDocsCollector hitCol(bits,&hq,totalHits,nDocs); + scorer->score(&hitCol); + _CLLDELETE(scorer); + + int32_t hqLen = hq.size(); + FieldDoc** fieldDocs = _CL_NEWARRAY(FieldDoc*,hqLen); + for (int32_t i = hqLen-1; i >= 0; --i){ // put docs in array + fieldDocs[i] = hq.fillFields (hq.pop()); + } + + Query* wq = weight->getQuery(); + if ( query != wq ) //query was re-written + _CLLDELETE(wq); + _CLLDELETE(weight); + + SortField** hqFields = hq.getFields(); + hq.setFields(NULL); //move ownership of memory over to TopFieldDocs + int32_t totalHits0 = totalHits[0]; + if ( bits != NULL && filter->shouldDeleteBitSet(bits) ) + _CLLDELETE(bits); + _CLDELETE_LARRAY(totalHits); + return _CLNEW TopFieldDocs(totalHits0, fieldDocs, hqLen, hqFields ); + } + + void IndexSearcher::_search(Query* query, Filter* filter, HitCollector* results){ + //Func - _search an index and fetch the results + // Applications should only use this if they need all of the + // matching documents. The high-level search API (search(Query)) is usually more efficient, + // as it skips non-high-scoring hits. + //Pre - query is a valid reference to a query + // filter may or may not be NULL + // results is a valid reference to a HitCollector and used to store the results + //Post - filter if non-NULL, a bitset used to eliminate some documents + + CND_PRECONDITION(reader != NULL, "reader is NULL"); + CND_PRECONDITION(query != NULL, "query is NULL"); + + BitSet* bits = NULL; + SimpleFilteredCollector* fc = NULL; + + if (filter != NULL){ + bits = filter->bits(reader); + fc = _CLNEW SimpleFilteredCollector(bits, results); + } + + Weight* weight = query->weight(this); + Scorer* scorer = weight->scorer(reader); + if (scorer != NULL) { + if (fc == NULL){ + scorer->score(results); + }else{ + scorer->score((HitCollector*)fc); + } + _CLDELETE(scorer); + } + + _CLLDELETE(fc); + Query* wq = weight->getQuery(); + if (wq != query) // query was rewritten + _CLLDELETE(wq); + _CLLDELETE(weight); + if ( bits != NULL && filter->shouldDeleteBitSet(bits) ) + _CLLDELETE(bits); + } + + void IndexSearcher::_search(Query* query, const Functor& cb) { + CND_PRECONDITION(reader != NULL, "reader is NULL"); + CND_PRECONDITION(query != NULL, "query is NULL"); + + Weight* weight = NULL; + Scorer* scorer = NULL; + try + { + Weight* weight = query->weight(this); + Scorer* scorer = weight->scorer(reader); + if (scorer == NULL) { + Query* wq = weight->getQuery(); + if (wq != query) // query was rewritten + _CLLDELETE(wq); + _CLLDELETE(weight); + return; + } + + AllTopDocsCollector hitCol(cb); + scorer->score( &hitCol ); + } _CLFINALLY({ + _CLDELETE(scorer); + if (weight != NULL) + { + Query* wq = weight->getQuery(); + if (wq != query) // query was rewritten + _CLLDELETE(wq); + } + _CLLDELETE(weight); + }); + } + + Query* IndexSearcher::rewrite(Query* original) { + Query* query = original; + Query* last = original; + for (Query* rewrittenQuery = query->rewrite(reader); + rewrittenQuery != query; + rewrittenQuery = query->rewrite(reader)) { + query = rewrittenQuery; + if ( query != last && last != original ){ + _CLLDELETE(last); + } + last = query; + } + return query; + } + + void IndexSearcher::explain(Query* query, int32_t doc, Explanation* ret){ + Weight* weight = query->weight(this); + ret->addDetail(weight->explain(reader, doc)); // TODO: A hack until this function will return Explanation* as well + + Query* wq = weight->getQuery(); + if ( query != wq ) //query was re-written + _CLLDELETE(wq); + _CLDELETE(weight); + } + + CL_NS(index)::IndexReader* IndexSearcher::getReader(){ + return reader; + } + + const char* IndexSearcher::getClassName(){ + return "IndexSearcher"; + } + const char* IndexSearcher::getObjectName() const{ + return IndexSearcher::getClassName(); + } + +CL_NS_END diff --git a/src/core/CLucene/search/IndexSearcher.h b/src/core/CLucene/search/IndexSearcher.h new file mode 100644 index 00000000000..960d17e7427 --- /dev/null +++ b/src/core/CLucene/search/IndexSearcher.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_IndexSearcher_ +#define _lucene_search_IndexSearcher_ + + +#include + + +#include "Searchable.h" +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(search,TopDocs) +CL_CLASS_DEF(search,TopFieldDocs) +CL_CLASS_DEF(search,Query) +CL_CLASS_DEF(search,Filter) +CL_CLASS_DEF(search,Sort) +CL_CLASS_DEF(search,HitCollector) +CL_CLASS_DEF(search,Explanation) +CL_CLASS_DEF(index,IndexReader) +//#include "CLucene/index/IndexReader.h" +//#include "CLucene/util/BitSet.h" +//#include "HitQueue.h" +//#include "FieldSortedHitQueue.h" + +CL_NS_DEF(search) +/** Implements search over a single IndexReader. +* +*

Applications usually need only call the inherited {@link search(Query*)} +* or {@link search(Query*,Filter*)} methods. +*/ + +typedef std::function Functor; + +class CLUCENE_EXPORT IndexSearcher:public Searcher{ + CL_NS(index)::IndexReader* reader; + bool readerOwner; +public: + /** Creates a searcher searching the index in the named directory. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + IndexSearcher(const char* path); + + /** Creates a searcher searching the index in the provided directory. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + IndexSearcher(CL_NS(store)::Directory* directory); + + /** Creates a searcher searching the index in the provided directory. + * and manages the lifetime of the directory. + * @throws CorruptIndexException if the index is corrupt + * @throws IOException if there is a low-level IO error + */ + IndexSearcher(CL_NS(store)::Directory* directory, bool closeDirector); + + /** Creates a searcher searching the provided index. */ + IndexSearcher(CL_NS(index)::IndexReader* r); + + ~IndexSearcher(); + + /** + * Note that the underlying IndexReader is not closed, if + * IndexSearcher was constructed with IndexSearcher(IndexReader r). + * If the IndexReader was supplied implicitly by specifying a directory, then + * the IndexReader gets closed. + */ + void close(); + + int32_t docFreq(const CL_NS(index)::Term* term) const; + + bool doc(int32_t i, CL_NS(document)::Document& document); + bool doc(int32_t i, CL_NS(document)::Document* document); + _CL_DEPRECATED( doc(i, document) ) CL_NS(document)::Document* doc(int32_t i); + + int32_t maxDoc() const; + + TopDocs* _search(Query* query, Filter* filter, const int32_t nDocs); + TopFieldDocs* _search(Query* query, Filter* filter, const int32_t nDocs, const Sort* sort); + + void _search(Query* query, Filter* filter, HitCollector* results); + + void _search(Query* query, const Functor& cb); + + CL_NS(index)::IndexReader* getReader(); + + Query* rewrite(Query* original); + void explain(Query* query, int32_t doc, Explanation* ret); + + virtual const char* getObjectName() const; + static const char* getClassName(); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/MatchAllDocsQuery.cpp b/src/core/CLucene/search/MatchAllDocsQuery.cpp new file mode 100644 index 00000000000..79f194ac7da --- /dev/null +++ b/src/core/CLucene/search/MatchAllDocsQuery.cpp @@ -0,0 +1,201 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Query.h" +#include "MatchAllDocsQuery.h" +#include "Explanation.h" +#include "SearchHeader.h" +#include "Searchable.h" + +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_DEF(search) + +class MatchAllDocsQuery::MatchAllDocsWeight : public Weight { +private: + Similarity* similarity; + float_t queryWeight; + float_t queryNorm; + MatchAllDocsQuery* parentQuery; + +public: + MatchAllDocsWeight(MatchAllDocsQuery* enclosingInstance, Searcher* searcher); + virtual ~MatchAllDocsWeight(){} + + virtual TCHAR* toString(); + + Query* getQuery(); + + float_t getValue(); + + float_t sumOfSquaredWeights(); + + void normalize(float_t _queryNorm); + + Scorer* scorer(CL_NS(index)::IndexReader* reader); + + Explanation* explain(CL_NS(index)::IndexReader* reader, int32_t doc); +}; + +class MatchAllDocsQuery::MatchAllScorer : public Scorer { + CL_NS(index)::IndexReader* reader; + int32_t id; + int32_t maxId; + float_t _score; + +public: + MatchAllScorer(CL_NS(index)::IndexReader* _reader, Similarity* similarity, Weight* w); + virtual ~MatchAllScorer(){} + + Explanation* explain(int32_t doc); + + int32_t doc() const; + + bool next(); + + float_t score(); + + bool skipTo(int32_t target); + + virtual TCHAR* toString(); +}; + +MatchAllDocsQuery::MatchAllScorer::MatchAllScorer(CL_NS(index)::IndexReader* _reader, Similarity* similarity, Weight* w) + :Scorer(similarity),reader(_reader),id(-1) +{ + maxId = reader->maxDoc() - 1; + _score = w->getValue(); +} + +Explanation* MatchAllDocsQuery::MatchAllScorer::explain(int32_t doc) { + // not called... see MatchAllDocsWeight::explain() + return NULL; +} + +int32_t MatchAllDocsQuery::MatchAllScorer::doc() const { + return id; +} + +bool MatchAllDocsQuery::MatchAllScorer::next() { + while (id < maxId) { + id++; + if (!reader->isDeleted(id)) { + return true; + } + } + return false; +} + +float_t MatchAllDocsQuery::MatchAllScorer::score() { + return _score; +} + +bool MatchAllDocsQuery::MatchAllScorer::skipTo(int32_t target) { + id = target - 1; + return next(); +} + +TCHAR* MatchAllDocsQuery::MatchAllScorer::toString(){ + return stringDuplicate(_T("MatchAllScorer")); +} + +MatchAllDocsQuery::MatchAllDocsWeight::MatchAllDocsWeight(MatchAllDocsQuery* enclosingInstance, Searcher* searcher): + parentQuery(enclosingInstance){ + this->similarity = searcher->getSimilarity(); +} + +TCHAR* MatchAllDocsQuery::MatchAllDocsWeight::toString() { + CL_NS(util)::StringBuffer buf(50); + buf.append(_T("weight(")); + + TCHAR* t = parentQuery->toString(); + buf.append(t); + _CLDELETE_LCARRAY(t); + + buf.appendChar(_T(')')); + return buf.giveBuffer(); +} + +Query* MatchAllDocsQuery::MatchAllDocsWeight::getQuery() { + return parentQuery; +} + +float_t MatchAllDocsQuery::MatchAllDocsWeight::getValue() { + return queryWeight; +} + +float_t MatchAllDocsQuery::MatchAllDocsWeight::sumOfSquaredWeights() { + queryWeight = parentQuery->getBoost(); + return queryWeight * queryWeight; +} + +void MatchAllDocsQuery::MatchAllDocsWeight::normalize(float_t _queryNorm) { + this->queryNorm = _queryNorm; + queryWeight *= this->queryNorm; +} + +Scorer* MatchAllDocsQuery::MatchAllDocsWeight::scorer(CL_NS(index)::IndexReader* reader) { + return _CLNEW MatchAllScorer(reader, similarity, this); +} + +Explanation* MatchAllDocsQuery::MatchAllDocsWeight::explain(CL_NS(index)::IndexReader* reader, int32_t doc) { + // explain query weight + Explanation* queryExpl = _CLNEW ComplexExplanation(true, getValue(), _T("MatchAllDocsQuery, product of:")); + if (parentQuery->getBoost() != 1.0f) { + queryExpl->addDetail(_CLNEW Explanation(parentQuery->getBoost(),_T("boost"))); + } + queryExpl->addDetail(_CLNEW Explanation(queryNorm,_T("queryNorm"))); + return queryExpl; +} + +MatchAllDocsQuery::MatchAllDocsQuery(){} +MatchAllDocsQuery::~MatchAllDocsQuery(){} + +Weight* MatchAllDocsQuery::_createWeight(Searcher* searcher){ + return _CLNEW MatchAllDocsWeight(this, searcher); +} + +const char* MatchAllDocsQuery::getClassName() { + return "MatchAllDocsQuery"; +} +const char* MatchAllDocsQuery::getObjectName() const{ + return getClassName(); +} + +TCHAR* MatchAllDocsQuery::toString(const TCHAR* /*field*/) const{ + CL_NS(util)::StringBuffer buffer(25); + buffer.append(_T("MatchAllDocsQuery")); + buffer.appendBoost(getBoost()); + return buffer.giveBuffer(); +} + +MatchAllDocsQuery::MatchAllDocsQuery(const MatchAllDocsQuery& clone): + Query(clone) +{ +} + +Query* MatchAllDocsQuery::clone() const{ + return _CLNEW MatchAllDocsQuery(*this); +} + +void MatchAllDocsQuery::extractTerms( TermSet * termset ) const +{ +} + +bool MatchAllDocsQuery::equals(Query* o) const{ + if (!(o->instanceOf(MatchAllDocsQuery::getClassName()))) + return false; + MatchAllDocsQuery* other = static_cast(o); + return this->getBoost() == other->getBoost(); +} + +size_t MatchAllDocsQuery::hashCode() const{ + return (static_cast(getBoost())) ^ 0x1AA71190; +} + +CL_NS_END diff --git a/src/core/CLucene/search/MatchAllDocsQuery.h b/src/core/CLucene/search/MatchAllDocsQuery.h new file mode 100644 index 00000000000..febe6f76e8f --- /dev/null +++ b/src/core/CLucene/search/MatchAllDocsQuery.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_MatchAllDocsQuery_h +#define _lucene_search_MatchAllDocsQuery_h + +#include "Scorer.h" +#include "SearchHeader.h" +#include "Query.h" + +CL_CLASS_DEF(search,Explanation) +CL_CLASS_DEF(search,Similarity) +CL_CLASS_DEF(index,IndexReader) + +CL_NS_DEF(search) + class Weight; + + /** + * A query that matches all documents. + * + */ + class CLUCENE_EXPORT MatchAllDocsQuery : public Query { + protected: + MatchAllDocsQuery(const MatchAllDocsQuery& clone); + public: + MatchAllDocsQuery(); + virtual ~MatchAllDocsQuery(); + + class MatchAllScorer; + class MatchAllDocsWeight; + + /** Prints a query to a string, with field assumed to be the + * default field and omitted. + *

The representation used is one that is supposed to be readable + * by {@link org.apache.lucene.queryParser.QueryParser QueryParser}. However, + * there are the following limitations: + *

    + *
  • If the query was created by the parser, the printed + * representation may not be exactly what was parsed. For example, + * characters that need to be escaped will be represented without + * the required backslash.
  • + *
  • Some of the more complicated queries (e.g. span queries) + * don't have a representation that can be parsed by QueryParser.
  • + *
+ */ + virtual TCHAR* toString(const TCHAR* field = NULL) const; + + protected: + /** Expert: Constructs an appropriate Weight implementation for this query. + * + *

Only implemented by primitive queries, which re-write to themselves. + * This is an Internal function + */ + virtual Weight* _createWeight(Searcher* searcher); + + public: + /** Returns a clone of this query. */ + virtual Query* clone() const; + + /** Expert: MatchAllDocsQuery provides no terms at all. */ + void extractTerms( TermSet * termset ) const; + + virtual bool equals(Query* o) const; + virtual size_t hashCode() const; + + static const char* getClassName(); + const char* getObjectName() const; + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/MultiPhraseQuery.cpp b/src/core/CLucene/search/MultiPhraseQuery.cpp new file mode 100644 index 00000000000..3c506763a9a --- /dev/null +++ b/src/core/CLucene/search/MultiPhraseQuery.cpp @@ -0,0 +1,441 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultiPhraseQuery.h" +#include "SearchHeader.h" + +#include "BooleanClause.h" +#include "BooleanQuery.h" +#include "TermQuery.h" +#include "Explanation.h" +#include "Similarity.h" + +#include "CLucene/index/_Term.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/MultipleTermPositions.h" + +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/VoidList.h" +#include "CLucene/util/_Arrays.h" + +#include "_ExactPhraseScorer.h" +#include "_SloppyPhraseScorer.h" + +CL_NS_USE(index) +CL_NS_USE(util) + +CL_NS_DEF(search) + +class MultiPhraseWeight : public Weight { +private: + Similarity* similarity; + float_t value; + float_t idf; + float_t queryNorm; + float_t queryWeight; + + MultiPhraseQuery* parentQuery; + +public: + MultiPhraseWeight(Searcher* searcher, MultiPhraseQuery* _parentQuery) : similarity(_parentQuery->getSimilarity(searcher)), + value(0), idf(0), queryNorm(0), queryWeight(0), parentQuery(_parentQuery) { + + // compute idf + for (size_t i = 0; i < parentQuery->termArrays->size(); i++){ + ArrayBase* terms = parentQuery->termArrays->at(i); + for ( size_t j=0;jlength;j++ ){ + idf += parentQuery->getSimilarity(searcher)->idf(terms->values[j], searcher); + } + } + } + virtual ~MultiPhraseWeight(){}; + + Query* getQuery() { return parentQuery; } + float_t getValue() { return value; } + + float_t sumOfSquaredWeights() { + queryWeight = idf * parentQuery->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it + } + + void normalize(float_t _queryNorm) { + this->queryNorm = _queryNorm; + queryWeight *= _queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document + } + + Scorer* scorer(IndexReader* reader) { + const size_t termArraysSize = parentQuery->termArrays->size(); + if (termArraysSize == 0) // optimize zero-term case + return NULL; + + TermPositions** tps = _CL_NEWARRAY(TermPositions*,termArraysSize+1); + for (size_t i=0; i* terms = parentQuery->termArrays->at(i); + + TermPositions* p; + if (terms->length > 1 ) + p = _CLNEW MultipleTermPositions(reader, terms); + else + p = reader->termPositions((*terms)[0]); + + if (p == NULL) + return NULL; + + tps[i] = p; + } + tps[termArraysSize] = NULL; + + Scorer* ret = NULL; + + ValueArray positions; + parentQuery->getPositions(positions); + const int32_t slop = parentQuery->getSlop(); + if (slop == 0) + ret = _CLNEW ExactPhraseScorer(this, tps, positions.values, similarity, + reader->norms(parentQuery->field)); + else + ret = _CLNEW SloppyPhraseScorer(this, tps, positions.values, similarity, + slop, reader->norms(parentQuery->field)); + + positions.deleteArray(); + + //tps can be deleted safely. SloppyPhraseScorer or ExactPhraseScorer will take care + //of its values + _CLDELETE_LARRAY(tps); + + return ret; + } + + Explanation* explain(IndexReader* reader, int32_t doc){ + ComplexExplanation* result = _CLNEW ComplexExplanation(); + + StringBuffer buf(100); + buf.append(_T("weight(")); + TCHAR* queryString = getQuery()->toString(); + buf.append(queryString); + buf.append(_T(" in ")); + buf.appendInt(doc); + buf.append(_T("), product of:")); + result->setDescription(buf.getBuffer()); + buf.clear(); + + buf.append(_T("idf(")); + buf.append(queryString); + buf.appendChar(_T(')')); + Explanation* idfExpl = _CLNEW Explanation(idf, buf.getBuffer()); + buf.clear(); + + // explain query weight + Explanation* queryExpl = _CLNEW Explanation(); + buf.append(_T("queryWeight(")); + buf.append(queryString); + buf.append(_T("), product of:")); + queryExpl->setDescription(buf.getBuffer()); + buf.clear(); + + Explanation* boostExpl = _CLNEW Explanation(parentQuery->getBoost(), _T("boost")); + if (parentQuery->getBoost() != 1.0f) + queryExpl->addDetail(boostExpl); + + queryExpl->addDetail(idfExpl); + + Explanation* queryNormExpl = _CLNEW Explanation(queryNorm,_T("queryNorm")); + queryExpl->addDetail(queryNormExpl); + + queryExpl->setValue(boostExpl->getValue() * + idfExpl->getValue() * + queryNormExpl->getValue()); + + result->addDetail(queryExpl); + + // explain field weight + ComplexExplanation* fieldExpl = _CLNEW ComplexExplanation(); + buf.append(_T("fieldWeight(")); + buf.append(queryString); + buf.append(_T(" in ")); + buf.appendInt(doc); + buf.append(_T("), product of:")); + fieldExpl->setDescription(buf.getBuffer()); + buf.clear(); + _CLDELETE_LCARRAY(queryString); + + Explanation* tfExpl = scorer(reader)->explain(doc); + fieldExpl->addDetail(tfExpl); + fieldExpl->addDetail(idfExpl); + + Explanation* fieldNormExpl = _CLNEW Explanation(); + uint8_t* fieldNorms = reader->norms(parentQuery->field); + float_t fieldNorm = + fieldNorms!=NULL ? Similarity::decodeNorm(fieldNorms[doc]) : 0.0f; + fieldNormExpl->setValue(fieldNorm); + + buf.append(_T("fieldNorm(field=")); + buf.append(parentQuery->field); + buf.append(_T(", doc=")); + buf.appendInt(doc); + buf.appendChar(_T(')')); + fieldNormExpl->setDescription(buf.getBuffer()); + buf.clear(); + + fieldExpl->addDetail(fieldNormExpl); + + fieldExpl->setMatch(tfExpl->isMatch()); + fieldExpl->setValue(tfExpl->getValue() * + idfExpl->getValue() * + fieldNormExpl->getValue()); + + if (queryExpl->getValue() == 1.0f){ + _CLLDELETE(result); + return fieldExpl; + } + + result->addDetail(fieldExpl); + result->setMatch(fieldExpl->getMatch()); + + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + + return result; + } +}; + +Query* MultiPhraseQuery::rewrite(IndexReader* /*reader*/) { + if (termArrays->size() == 1) { // optimize one-term case + ArrayBase* terms = termArrays->at(0); + BooleanQuery* boq = _CLNEW BooleanQuery(true); + for ( size_t i=0;ilength;i++ ){ + boq->add(_CLNEW TermQuery((*terms)[i]), BooleanClause::SHOULD); + } + boq->setBoost(getBoost()); + return boq; + } else { + return this; + } +} + +void MultiPhraseQuery::extractTerms( TermSet * termset ) const +{ + for( size_t i = 0; i < termArrays->size(); i++ ) + { + ArrayBase * terms = termArrays->at( i ); + for( size_t j=0; j < terms->length; j++ ) + { + Term * pTerm = terms->values[ j ]; + if( pTerm && termset->end() == termset->find( pTerm )) + termset->insert( _CL_POINTER( pTerm )); + } + } +} + +MultiPhraseQuery::MultiPhraseQuery(): + field(NULL), + termArrays(_CLNEW CL_NS(util)::CLArrayList*>), + positions(_CLNEW CL_NS(util)::CLVector), + slop(0) +{ +} + +MultiPhraseQuery::MultiPhraseQuery( const MultiPhraseQuery& clone ): + Query(clone) +{ + this->field = clone.field ? STRDUP_TtoT( clone.field ) : NULL; + this->slop = clone.slop; + + this->termArrays = _CLNEW CL_NS(util)::CLArrayList*>(); + this->positions = _CLNEW CL_NS(util)::CLVector(); + + size_t size = clone.positions->size(); + for( size_t i = 0; i < size; i++ ) + { + int32_t n = (*clone.positions)[i]; + this->positions->push_back( n ); + } + + size = clone.termArrays->size(); + for( size_t j = 0; j < size; j++ ) + { + CL_NS(util)::ArrayBase* termsToClone = (*clone.termArrays)[ j ]; + CL_NS(util)::ArrayBase* terms = _CLNEW CL_NS(util)::ValueArray( termsToClone->length ); + for( size_t t = 0; t < termsToClone->length; t++ ) + terms->values[ t ] = _CL_POINTER( termsToClone->values[ t ] ); + + this->termArrays->push_back( terms ); + } +} + +MultiPhraseQuery::~MultiPhraseQuery(){ + for (size_t i = 0; i < termArrays->size(); i++){ + for ( size_t j=0;jat(i)->length;j++ ) { + _CLLDECDELETE(termArrays->at(i)->values[j]); + } + _CLLDELETE(termArrays->at(i)); + } + _CLLDELETE(termArrays); + _CLLDELETE(positions); + _CLDELETE_LCARRAY(field); +} + +Query * MultiPhraseQuery::clone() const +{ + return _CLNEW MultiPhraseQuery( *this ); +} + +void MultiPhraseQuery::setSlop(const int32_t s) { slop = s; } + +int32_t MultiPhraseQuery::getSlop() const { return slop; } + +void MultiPhraseQuery::add(CL_NS(index)::Term* term) { + ValueArray _terms(1); + _terms[0] = term; + add(&_terms); +} + +void MultiPhraseQuery::add(const CL_NS(util)::ArrayBase* terms) { + int32_t position = 0; + if (positions->size() > 0) + position = (*positions)[positions->size()-1] + 1; + + add(terms, position); +} + +void MultiPhraseQuery::add(const CL_NS(util)::ArrayBase* _terms, const int32_t position) { + if (termArrays->size() == 0) + field = STRDUP_TtoT((*_terms)[0]->field()); + + CL_NS(util)::ArrayBase* terms = _CLNEW CL_NS(util)::ValueArray(_terms->length); + for ( size_t i=0;i<_terms->length;i++ ){ + if ( _tcscmp(_terms->values[i]->field(), field) != 0) { + TCHAR buf[250]; + _sntprintf(buf,250,_T("All phrase terms must be in the same field (%s): %s"),field, (*terms)[i]->field()); + _CLTHROWT(CL_ERR_IllegalArgument,buf); + } + terms->values[i] = _CL_POINTER(_terms->values[i]); + } + termArrays->push_back(terms); + positions->push_back(position); +} +const CL_NS(util)::CLArrayList*>* MultiPhraseQuery::getTermArrays() { + return termArrays; +} + +void MultiPhraseQuery::getPositions(ValueArray& result) const { + result.length = positions->size(); + result.values = _CL_NEWARRAY(int32_t,result.length); + for (size_t i = 0; i < result.length; i++) + result.values[i] = (*positions)[i]; +} + +Weight* MultiPhraseQuery::_createWeight(Searcher* searcher) { + return _CLNEW MultiPhraseWeight(searcher, this); +} + +TCHAR* MultiPhraseQuery::toString(const TCHAR* f) const { + StringBuffer buffer(100); + if (_tcscmp(f, field)!=0) { + buffer.append(field); + buffer.appendChar(_T(':')); + } + + buffer.appendChar(_T('"')); + + CL_NS(util)::CLArrayList*>::iterator i; + i = termArrays->begin(); + while (i != termArrays->end()){ + CL_NS(util)::ArrayBase& terms = *(*i); + if (terms.length > 1) { + buffer.appendChar(_T('(')); + for (size_t j = 0; j < terms.length; j++) { + buffer.append(terms[j]->text()); + if (j < terms.length-1) + buffer.appendChar(_T(' ')); + } + buffer.appendChar(_T(')')); + } else { + buffer.append(terms[0]->text()); + } + if (i+1 != termArrays->end() ) + buffer.appendChar(_T(' ')); + + i++; + } + buffer.appendChar(_T('"')); + + if (slop != 0) { + buffer.appendChar(_T('~')); + buffer.appendInt(slop); + } + + buffer.appendBoost(getBoost()); + + return buffer.giveBuffer(); +} + +class TermArray_Equals:public CL_NS_STD(binary_function) +{ +public: + bool operator()( CL_NS(util)::ArrayBase* val1, CL_NS(util)::ArrayBase* val2 ) const{ + if ( val1->length != val2->length ) + return false; + for ( size_t i=0;ilength;i++ ){ + if (!val1->values[i]->equals(val2->values[i])) return false; + } + return true; + } +}; + +bool MultiPhraseQuery::equals(Query* o) const { + if (!(o->instanceOf(MultiPhraseQuery::getObjectName()))) return false; + MultiPhraseQuery* other = static_cast(o); + bool ret = (this->getBoost() == other->getBoost()) && (this->slop == other->slop); + + if (ret){ + CLListEquals, + const CL_NS(util)::CLVector > comp; + ret = comp.equals(this->positions,other->positions); + } + + if (ret){ + if (this->termArrays->size() != other->termArrays->size()) + return false; + + for (size_t i=0; itermArrays->size();i++){ + CLListEquals*>, + const CL_NS(util)::CLVector*> > comp; + ret = comp.equals(this->termArrays,other->termArrays); + } + } + return ret; +} + +// TODO: Test hashed value if conforms with JL +size_t MultiPhraseQuery::hashCode() const { + size_t ret = Similarity::floatToByte(getBoost()) ^ slop; + + { //msvc6 scope fix + for( size_t i = 0; i < termArrays->size(); i++ ) + { + for( size_t j = 0; j < termArrays->at( i )->length; j++ ) + { + ret = 31 * ret + termArrays->at(i)->values[j]->hashCode(); + } + } + } + { //msvc6 scope fix + for ( size_t i=0;isize();i++ ) + ret = 31 * ret + (*positions)[i]; + } + ret ^= 0x4AC65113; + + return ret; +} + +CL_NS_END diff --git a/src/core/CLucene/search/MultiPhraseQuery.h b/src/core/CLucene/search/MultiPhraseQuery.h new file mode 100644 index 00000000000..86419e5b753 --- /dev/null +++ b/src/core/CLucene/search/MultiPhraseQuery.h @@ -0,0 +1,116 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_MultiPhraseQuery_ +#define _lucene_search_MultiPhraseQuery_ + +#include "Query.h" +#include "CLucene/util/Array.h" +#include "CLucene/util/VoidList.h" + +CL_CLASS_DEF(index,Term) + +CL_NS_DEF(search) + +class MultiPhraseWeight; + +/** +* MultiPhraseQuery is a generalized version of PhraseQuery, with an added +* method {@link #add(Term[])}. +* To use this class, to search for the phrase "Microsoft app*" first use +* add(Term) on the term "Microsoft", then find all terms that have "app" as +* prefix using IndexReader.terms(Term), and use MultiPhraseQuery.add(Term[] +* terms) to add them to the query. +* +* @author Anders Nielsen +* @version 1.0 +*/ +class CLUCENE_EXPORT MultiPhraseQuery : public Query { +private: + TCHAR* field; + CL_NS(util)::CLArrayList*>* termArrays; + CL_NS(util)::CLVector* positions; + + int32_t slop; + +protected: + MultiPhraseQuery( const MultiPhraseQuery& clone ); + +public: + MultiPhraseQuery(); + virtual ~MultiPhraseQuery(); + friend class MultiPhraseWeight; + + /** Sets the phrase slop for this query. + * @see PhraseQuery#setSlop(int) + */ + void setSlop(const int32_t s); + + /** Sets the phrase slop for this query. + * @see PhraseQuery#getSlop() + */ + int32_t getSlop() const; + + /** Add a single term at the next position in the phrase. + * @see PhraseQuery#add(Term) + * @memory A pointer is taken to term + */ + void add(CL_NS(index)::Term* term); + + /** Add multiple terms at the next position in the phrase. Any of the terms + * may match. + * @memory A pointer is taken of each term, the array memory must be cleaned up by calle + * @see PhraseQuery#add(Term) + */ + void add(const CL_NS(util)::ArrayBase* terms); + + /** + * Allows to specify the relative position of terms within the phrase. + * + * @see PhraseQuery#add(Term, int) + * @param terms + * @param position + * @memory A pointer is taken of each term, the array memory must be cleaned up by calle + */ + void add(const CL_NS(util)::ArrayBase* terms, const int32_t position); + + /** + * Returns a ArrayBase of the terms in the multiphrase. + * Do not modify the List or its contents. + */ + const CL_NS(util)::CLArrayList*>* getTermArrays(); + + + /** + * Returns the relative positions of terms in this phrase. + */ + void getPositions(CL_NS(util)::ValueArray& result) const; + + Query* rewrite(CL_NS(index)::IndexReader* reader); + + /** Expert: adds all terms occurring in this query to the terms set. */ + void extractTerms( TermSet * termset ) const; + +protected: + Weight* _createWeight(Searcher* searcher); + +public: + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* f) const; + + /** Returns true if o is equal to this. */ + bool equals(Query* o) const; + + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + Query* clone() const; + + const char* getObjectName() const { return getClassName(); } + static const char* getClassName(){ return "MultiPhraseQuery"; } +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/MultiSearcher.cpp b/src/core/CLucene/search/MultiSearcher.cpp new file mode 100644 index 00000000000..0f2a6862706 --- /dev/null +++ b/src/core/CLucene/search/MultiSearcher.cpp @@ -0,0 +1,244 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "MultiSearcher.h" +#include "SearchHeader.h" +#include "Query.h" +#include "_HitQueue.h" +#include "CLucene/document/Document.h" +#include "CLucene/index/Term.h" +#include "_FieldDocSortedHitQueue.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) + +CL_NS_DEF(search) + + class MultiHitCollector: public HitCollector{ + private: + HitCollector* results; + int32_t start; + public: + MultiHitCollector(HitCollector* _results, int32_t _start); + void collect(const int32_t doc, const float_t score) ; + }; + + + /** Creates a searcher which searches searchers. */ + MultiSearcher::MultiSearcher(Searchable** _searchables): + _maxDoc(0) { + searchablesLen = 0; + while ( _searchables[searchablesLen] != NULL ) + ++searchablesLen; + + searchables=_CL_NEWARRAY(Searchable*,searchablesLen+1); + starts = _CL_NEWARRAY(int32_t,searchablesLen + 1); // build starts array + for (int32_t i = 0; i < searchablesLen; ++i) { + searchables[i]=_searchables[i]; + starts[i] = _maxDoc; + _maxDoc += searchables[i]->maxDoc(); // compute maxDocs + } + starts[searchablesLen] = _maxDoc; + } + + MultiSearcher::~MultiSearcher() { + _CLDELETE_ARRAY(searchables); + _CLDELETE_ARRAY(starts); + } + + int32_t* MultiSearcher::getStarts() { + return starts; + } + int32_t MultiSearcher::getLength() { + return searchablesLen; + } + + // inherit javadoc + void MultiSearcher::close() { + for (int32_t i = 0; i < searchablesLen; ++i){ + searchables[i]->close(); + searchables[i]=NULL; + } + } + + int32_t MultiSearcher::docFreq(const Term* term) const { + int32_t docFreq = 0; + for (int32_t i = 0; i < searchablesLen; ++i) + docFreq += searchables[i]->docFreq(term); + return docFreq; + } + + /** For use by {@link HitCollector} implementations. */ + bool MultiSearcher::doc(int32_t n, Document* d) { + int32_t i = subSearcher(n); // find searcher index + return searchables[i]->doc(n - starts[i], d); // dispatch to searcher + } + + int32_t MultiSearcher::searcherIndex(int32_t n) const{ + return subSearcher(n); + } + + /** Returns index of the searcher for document n in the array + * used to construct this searcher. */ + int32_t MultiSearcher::subSearcher(int32_t n) const{ + // replace w/ call to Arrays.binarySearch in Java 1.2 + int32_t lo = 0; // search starts array + int32_t hi = searchablesLen - 1; // for first element less + // than n, return its index + int32_t mid,midValue; + while (hi >= lo) { + mid = (lo + hi) >> 1; + midValue = starts[mid]; + if (n < midValue) + hi = mid - 1; + else if (n > midValue) + lo = mid + 1; + else{ // found a match + while (mid+1 < searchablesLen && starts[mid+1] == midValue) { + ++mid; // scan to last match + } + return mid; + } + } + return hi; + } + + /** Returns the document number of document n within its + * sub-index. */ + int32_t MultiSearcher::subDoc(int32_t n) const{ + return n - starts[subSearcher(n)]; + } + + int32_t MultiSearcher::maxDoc() const{ + return _maxDoc; + } + + TopDocs* MultiSearcher::_search(Query* query, Filter* filter, const int32_t nDocs) { + HitQueue* hq = _CLNEW HitQueue(nDocs); + int32_t totalHits = 0; + TopDocs* docs; + int32_t j; + ScoreDoc* scoreDocs; + for (int32_t i = 0; i < searchablesLen; i++) { // search each searcher + docs = searchables[i]->_search(query, filter, nDocs); + totalHits += docs->totalHits; // update totalHits + scoreDocs = docs->scoreDocs; + for ( j = 0; j scoreDocsLength; ++j) { // merge scoreDocs int_to hq + scoreDocs[j].doc += starts[i]; // convert doc + if ( !hq->insert(scoreDocs[j])) + break; // no more scores > minScore + } + + _CLDELETE(docs); + } + + int32_t scoreDocsLen = hq->size(); + scoreDocs = new ScoreDoc[scoreDocsLen]; + {//MSVC 6 scope fix + for (int32_t i = scoreDocsLen-1; i >= 0; --i) // put docs in array + scoreDocs[i] = hq->pop(); + } + + //cleanup + _CLDELETE(hq); + + return _CLNEW TopDocs(totalHits, scoreDocs, scoreDocsLen); + } + + /** Lower-level search API. + * + *

{@link HitCollector#collect(int32_t,float_t)} is called for every non-zero + * scoring document. + * + *

Applications should only use this if they need all of the + * matching documents. The high-level search API ({@link + * Searcher#search(Query)}) is usually more efficient, as it skips + * non-high-scoring hits. + * + * @param query to match documents + * @param filter if non-null, a bitset used to eliminate some documents + * @param results to receive hits + */ + void MultiSearcher::_search(Query* query, Filter* filter, HitCollector* results){ + for (int32_t i = 0; i < searchablesLen; ++i) { + /* DSR:CL_BUG: Old implementation leaked and was misconceived. We need + ** to have the original HitCollector ($results) collect *all* hits; + ** the MultiHitCollector instantiated below serves only to adjust + ** (forward by starts[i]) the docNo passed to $results. + ** Old implementation instead created a sort of linked list of + ** MultiHitCollectors that applied the adjustments in $starts + ** cumulatively (and was never deleted). */ + HitCollector *docNoAdjuster = _CLNEW MultiHitCollector(results, starts[i]); + searchables[i]->_search(query, filter, docNoAdjuster); + _CLDELETE(docNoAdjuster); + } + } + + TopFieldDocs* MultiSearcher::_search (Query* query, Filter* filter, const int32_t n, const Sort* sort){ + FieldDocSortedHitQueue* hq = NULL; + int32_t totalHits = 0; + TopFieldDocs* docs; + int32_t j; + FieldDoc** fieldDocs; + + for (int32_t i = 0; i < searchablesLen; ++i) { // search each searcher + docs = searchables[i]->_search (query, filter, n, sort); + if (hq == NULL){ + hq = _CLNEW FieldDocSortedHitQueue (docs->fields, n); + docs->fields = NULL; //hit queue takes fields memory + } + + totalHits += docs->totalHits; // update totalHits + fieldDocs = docs->fieldDocs; + for(j = 0;jscoreDocsLength;++j){ // merge scoreDocs into hq + fieldDocs[j]->scoreDoc.doc += starts[i]; // convert doc + if (!hq->insert (fieldDocs[j]) ) + break; // no more scores > minScore + } + for ( int32_t x=0;xsize(); + fieldDocs = _CL_NEWARRAY(FieldDoc*,hqlen); + for (j = hqlen - 1; j >= 0; j--) // put docs in array + fieldDocs[j] = hq->pop(); + + SortField** hqFields = hq->getFields(); + hq->setFields(NULL); //move ownership of memory over to TopFieldDocs + _CLDELETE(hq); + + return _CLNEW TopFieldDocs (totalHits, fieldDocs, hqlen, hqFields); + } + + Query* MultiSearcher::rewrite(Query* query) { + // this is a bit of a hack. We know that a query which + // creates a Weight based on this Dummy-Searcher is + // always already rewritten (see preparedWeight()). + // Therefore we just return the unmodified query here + return query; + } + + void MultiSearcher::explain(Query* query, int32_t doc, Explanation* ret) { + int32_t i = subSearcher(doc); // find searcher index + searchables[i]->explain(query,doc-starts[i], ret); // dispatch to searcher + } + + MultiHitCollector::MultiHitCollector(HitCollector* _results, int32_t _start): + results(_results), + start(_start) { + } + + void MultiHitCollector::collect(const int32_t doc, const float_t score) { + results->collect(doc + start, score); + } + +CL_NS_END diff --git a/src/core/CLucene/search/MultiSearcher.h b/src/core/CLucene/search/MultiSearcher.h new file mode 100644 index 00000000000..17adba01e8d --- /dev/null +++ b/src/core/CLucene/search/MultiSearcher.h @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_multisearcher +#define _lucene_search_multisearcher + + +//#include "SearchHeader.h" +#include "Searchable.h" +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(index,Term) + +CL_NS_DEF(search) + + /** Implements search over a set of Searchables. + * + *

Applications usually need only call the inherited {@link #search(Query)} + * or {@link #search(Query,Filter)} methods. + */ + class CLUCENE_EXPORT MultiSearcher: public Searcher { + private: + Searchable** searchables; + int32_t searchablesLen; + int32_t* starts; + int32_t _maxDoc; + protected: + int32_t* getStarts(); + int32_t getLength(); + public: + /** Creates a searcher which searches Searchables. */ + MultiSearcher(Searchable** searchables); + + ~MultiSearcher(); + + /** Frees resources associated with this Searcher. */ + void close() ; + + int32_t docFreq(const CL_NS(index)::Term* term) const ; + + /** For use by {@link HitCollector} implementations. */ + bool doc(int32_t n, CL_NS(document)::Document* document); + + /** For use by {@link HitCollector} implementations to identify the + * index of the sub-searcher that a particular hit came from. */ + int32_t searcherIndex(int32_t n) const; + + int32_t subSearcher(int32_t n) const; + + int32_t subDoc(int32_t n) const; + + int32_t maxDoc() const; + + TopDocs* _search(Query* query, Filter* filter, const int32_t nDocs) ; + + TopFieldDocs* _search (Query* query, Filter* filter, const int32_t n, const Sort* sort); + + /** Lower-level search API. + * + *

{@link HitCollector#collect(int32_t,float_t)} is called for every non-zero + * scoring document. + * + *

Applications should only use this if they need all of the + * matching documents. The high-level search API ({@link + * Searcher#search(Query)}) is usually more efficient, as it skips + * non-high-scoring hits. + * + * @param query to match documents + * @param filter if non-null, a bitset used to eliminate some documents + * @param results to receive hits + */ + void _search(Query* query, Filter* filter, HitCollector* results); + + Query* rewrite(Query* original); + void explain(Query* query, int32_t doc, Explanation* ret); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/MultiTermQuery.cpp b/src/core/CLucene/search/MultiTermQuery.cpp new file mode 100644 index 00000000000..c781c40845c --- /dev/null +++ b/src/core/CLucene/search/MultiTermQuery.cpp @@ -0,0 +1,104 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "MultiTermQuery.h" +#include "BooleanQuery.h" +#include "FilteredTermEnum.h" +#include "TermQuery.h" +#include "CLucene/index/Term.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + +/** Constructs a query for terms matching term. */ + + MultiTermQuery::MultiTermQuery(Term* t){ + //Func - Constructor + //Pre - t != NULL + //Post - The instance has been created + + CND_PRECONDITION(t != NULL, "t is NULL"); + + term = _CL_POINTER(t); + + } + MultiTermQuery::MultiTermQuery(const MultiTermQuery& clone): + Query(clone) + { + term = _CLNEW Term(clone.getTerm(false),clone.getTerm(false)->text()); + } + + MultiTermQuery::~MultiTermQuery(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLDECDELETE(term); + } + + Term* MultiTermQuery::getTerm(bool pointer) const{ + if ( pointer ) + return _CL_POINTER(term); + else + return term; + } + + Query* MultiTermQuery::rewrite(IndexReader* reader) { + FilteredTermEnum* enumerator = getEnum(reader); + BooleanQuery* query = _CLNEW BooleanQuery( true ); + try { + do { + Term* t = enumerator->term(false); + if (t != NULL) { + TermQuery* tq = _CLNEW TermQuery(t); // found a match + tq->setBoost(getBoost() * enumerator->difference()); // set the boost + query->add(tq,true, false, false); // add to q + } + } while (enumerator->next()); + } _CLFINALLY ( enumerator->close(); _CLDELETE(enumerator) ); + + //if we only added one clause and the clause is not prohibited then + //we can just return the query + if (query->getClauseCount() == 1) { // optimize 1-clause queries + BooleanClause* c=0; + query->getClauses(&c); + + if (!c->prohibited) { // just return clause + c->deleteQuery=false; + Query* ret = c->getQuery(); + + _CLDELETE(query); + return ret; + } + } + return query; + } + + Query* MultiTermQuery::combine(CL_NS(util)::ArrayBase* queries) { + return Query::mergeBooleanQueries(queries); + } + + /** Prints a user-readable version of this query. */ + TCHAR* MultiTermQuery::toString(const TCHAR* field) const{ + StringBuffer buffer; + + if ( field==NULL || _tcscmp(term->field(),field)!=0 ) { + buffer.append(term->field()); + buffer.append( _T(":")); + } + buffer.append(term->text()); + // todo: use ToStringUtils.boost() + if (getBoost() != 1.0f) { + buffer.appendChar ( '^' ); + buffer.appendFloat( getBoost(),1); + } + return buffer.toString(); + } + +CL_NS_END diff --git a/src/core/CLucene/search/MultiTermQuery.h b/src/core/CLucene/search/MultiTermQuery.h new file mode 100644 index 00000000000..d35c9d25e1f --- /dev/null +++ b/src/core/CLucene/search/MultiTermQuery.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_MultiTermQuery_ +#define _lucene_search_MultiTermQuery_ + + +CL_CLASS_DEF(util,StringBuffer) +//#include "CLucene/index/IndexReader.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(search,FilteredTermEnum) +CL_CLASS_DEF(index,IndexReader) +//#include "CLucene/index/Terms.h" +//#include "FilteredTermEnum.h" +//#include "SearchHeader.h" +//#include "BooleanQuery.h" +//#include "TermQuery.h" +#include "Query.h" + +CL_NS_DEF(search) + + /** + * A {@link lucene::search::Query} that matches documents containing a subset of terms provided + * by a {@link lucene::search::FilteredTermEnum} enumeration. + *

+ * MultiTermQuery is not designed to be used by itself. + *
+ * The reason being that it is not intialized with a {@link FilteredTermEnum} + * enumeration. A {@link FilteredTermEnum} enumeration needs to be provided. + *

+ * For example, {@link WildcardQuery} and {@link FuzzyQuery} extend + * MultiTermQuery to provide {@link WildcardTermEnum} and + * {@link FuzzyTermEnum}, respectively. + */ + class CLUCENE_EXPORT MultiTermQuery: public Query { + private: + CL_NS(index)::Term* term; + protected: + MultiTermQuery(const MultiTermQuery& clone); + + /** Construct the enumeration to be used, expanding the pattern term. */ + virtual FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader) = 0; + public: + /** Constructs a query for terms matching term. */ + MultiTermQuery(CL_NS(index)::Term* t); + + virtual ~MultiTermQuery(); + + /** Returns the pattern term. */ + CL_NS(index)::Term* getTerm(bool pointer=true) const; + + Query* combine(CL_NS(util)::ArrayBase* queries); + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + + virtual Query* rewrite(CL_NS(index)::IndexReader* reader); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/PhrasePositions.cpp b/src/core/CLucene/search/PhrasePositions.cpp new file mode 100644 index 00000000000..b8d1773d058 --- /dev/null +++ b/src/core/CLucene/search/PhrasePositions.cpp @@ -0,0 +1,114 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_PhrasePositions.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + +PhrasePositions::PhrasePositions(TermPositions* t, const int32_t OffSet) { + //Func - Constructor + //Pre - t != NULL + // OffSet != NULL + //Post - The instance has been created + + CND_PRECONDITION(t != NULL,"Tp is NULL"); + CND_PRECONDITION(OffSet >= 0 ,"OffSet is a negative number"); + + tp = t; + offset = OffSet; + position = 0; + count = 0; + doc = 0; + + _next = NULL; + } + + PhrasePositions::~PhrasePositions(){ + //Func - Destructor + //Pre - true + //Post - The instance has been deleted + + //delete next Phrase position and by doing that + //all PhrasePositions in the list + _CLDELETE(_next); + + //Check if tp is valid + if ( tp != NULL ){ + //Close TermPositions tp + tp->close(); + _CLDELETE(tp); + } + } + + bool PhrasePositions::next(){ + //Func - Increments to next doc + //Pre - tp != NULL + //Post - if there was no next then doc = INT_MAX otherwise + // doc contains the current document number + + CND_PRECONDITION(tp != NULL,"tp is NULL"); + + //Move to the next in TermPositions tp + if (!tp->next()) { + //There is no next so close the stream + tp->close(); + //delete tp and reset tp to NULL + _CLVDELETE(tp); //todo: not a clucene object... should be + //Assign Doc sentinel value + doc = LUCENE_INT32_MAX_SHOULDBE; + return false; + }else{ + doc = tp->doc(); + position = 0; + return true; + } + } + bool PhrasePositions::skipTo(int32_t target){ + if (!tp->skipTo(target)) { + tp->close(); // close stream + doc = LUCENE_INT32_MAX_SHOULDBE; // sentinel value + return false; + } + doc = tp->doc(); + position = 0; + return true; + } + void PhrasePositions::firstPosition(){ + //Func - Read the first TermPosition + //Pre - tp != NULL + //Post - + + CND_PRECONDITION(tp != NULL,"tp is NULL"); + + //read first pos + count = tp->freq(); + //Move to the next TermPosition + nextPosition(); + } + + bool PhrasePositions::nextPosition(){ + //Func - Move to the next position + //Pre - tp != NULL + //Post - + + CND_PRECONDITION(tp != NULL,"tp is NULL"); + + if (count-- > 0) { + //read subsequent pos's + position = tp->nextPosition() - offset; + + //Check position always bigger than or equal to 0 + //bvk: todo, bug??? position < 0 occurs, cant figure out why, + //old version does it too and will fail the "SearchTest" test + //CND_CONDITION(position >= 0, "position has become a negative number"); + return true; + }else{ + return false; + } + } +CL_NS_END diff --git a/src/core/CLucene/search/PhraseQuery.cpp b/src/core/CLucene/search/PhraseQuery.cpp new file mode 100644 index 00000000000..2942d0df2f0 --- /dev/null +++ b/src/core/CLucene/search/PhraseQuery.cpp @@ -0,0 +1,485 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "PhraseQuery.h" + +#include "SearchHeader.h" +#include "Scorer.h" +#include "BooleanQuery.h" +#include "TermQuery.h" +#include "Similarity.h" +#include "Searchable.h" +#include "Explanation.h" + +#include "CLucene/index/_Term.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/index/IndexReader.h" + +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/VoidList.h" +#include "CLucene/util/_Arrays.h" + +#include "_ExactPhraseScorer.h" +#include "_SloppyPhraseScorer.h" + +#include + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + + + class PhraseWeight: public Weight { + private: + Searcher* searcher; + float_t value; + float_t idf; + float_t queryNorm; + float_t queryWeight; + + PhraseQuery* parentQuery; + public: + PhraseWeight(Searcher* searcher, PhraseQuery* parentQuery); + virtual ~PhraseWeight(); + TCHAR* toString(); + + Query* getQuery(); + float_t getValue(); + + float_t sumOfSquaredWeights(); + void normalize(float_t queryNorm); + Scorer* scorer(CL_NS(index)::IndexReader* reader); + Explanation* explain(CL_NS(index)::IndexReader* reader, int32_t doc); + TCHAR* toString(TCHAR* f); + bool equals(PhraseWeight* o); + }; + + PhraseQuery::PhraseQuery(): + field(NULL), terms(_CLNEW CL_NS(util)::CLVector(false) ), + positions(_CLNEW CL_NS(util)::CLVector), slop(0) + { + } + + PhraseQuery::PhraseQuery(const PhraseQuery& clone): + Query(clone), + terms(_CLNEW CL_NS(util)::CLVector(false) ), + positions(_CLNEW CL_NS(util)::CLVector) + { + slop = clone.slop; + field = clone.field; + int32_t size=clone.positions->size(); + { //msvc6 scope fix + for ( int32_t i=0;ipositions->push_back( n ); + } + } + size=clone.terms->size(); + { //msvc6 scope fix + for ( int32_t i=0;iterms->push_back( _CL_POINTER((*clone.terms)[i])); + } + } + } + Query* PhraseQuery::clone() const{ + return _CLNEW PhraseQuery(*this); + } + + const TCHAR* PhraseQuery::getFieldName() const{ return field; } + + void PhraseQuery::setSlop(const int32_t s) { slop = s; } + int32_t PhraseQuery::getSlop() const { return slop; } + + bool PhraseQuery::equals(CL_NS(search)::Query *other) const{ + if (!(other->instanceOf(PhraseQuery::getClassName()))) + return false; + + PhraseQuery* pq = (PhraseQuery*)other; + bool ret = (this->getBoost() == pq->getBoost()) && (this->slop == pq->slop); + + if ( ret ){ + CLListEquals, + const CL_NS(util)::CLVector > comp; + ret = comp.equals(this->terms,pq->terms); + } + + if ( ret ){ + CLListEquals, + const CL_NS(util)::CLVector > comp; + ret = comp.equals(this->positions,pq->positions); + } + return ret; + } + + + PhraseQuery::~PhraseQuery(){ + //Func - Destructor + //Pre - true + //Post 0 The instance has been destroyed + + //Iterate through all the terms + for (size_t i = 0; i < terms->size(); i++){ + _CLLDECDELETE((*terms)[i]); + } + _CLLDELETE(terms); + _CLLDELETE(positions); + } + + size_t PhraseQuery::hashCode() const { + //todo: do cachedHashCode, and invalidate on add/remove clause + size_t ret = Similarity::floatToByte(getBoost()) ^ Similarity::floatToByte(slop); + + { //msvc6 scope fix + for ( size_t i=0;isize();i++ ) + ret = 31 * ret + (*terms)[i]->hashCode(); + } + { //msvc6 scope fix + for ( size_t i=0;isize();i++ ) + ret = 31 * ret + (*positions)[i]; + } + return ret; + } + + const char* PhraseQuery::getClassName(){ + return "PhraseQuery"; + } + const char* PhraseQuery::getObjectName() const{ + //Func - Returns the string "PhraseQuery" + //Pre - true + //Post - The string "PhraseQuery" has been returned + return getClassName(); + } + + void PhraseQuery::add(Term* term) { + CND_PRECONDITION(term != NULL,"term is NULL"); + + int32_t position = 0; + + if(positions->size() > 0) + position = ((*positions)[positions->size()-1]) + 1; + + add(term, position); + } + + void PhraseQuery::add(Term* term, int32_t position) { + + CND_PRECONDITION(term != NULL,"term is NULL"); + + if (terms->size() == 0) + field = term->field(); + else{ + //Check if the field of the _CLNEW term matches the field of the PhraseQuery + //can use != because fields are interned + if ( term->field() != field){ + TCHAR buf[200]; + _sntprintf(buf,200,_T("All phrase terms must be in the same field: %s"),term->field()); + _CLTHROWT(CL_ERR_IllegalArgument,buf); + } + } + + //Store the _CLNEW term + terms->push_back(_CL_POINTER(term)); + positions->push_back(position); + } + + void PhraseQuery::getPositions(ValueArray& result) const{ + result.length = positions->size(); + result.values = _CL_NEWARRAY(int32_t,result.length); + for(size_t i = 0; i < result.length; i++){ + result.values[i] = (*positions)[i]; + } + } + + Weight* PhraseQuery::_createWeight(Searcher* searcher) { + if (terms->size() == 1) { // optimize one-term case + Term* term = (*terms)[0]; + Query* termQuery = _CLNEW TermQuery(term); + termQuery->setBoost(getBoost()); + Weight* ret = termQuery->_createWeight(searcher); + _CLLDELETE(termQuery); + return ret; + } + return _CLNEW PhraseWeight(searcher,this); + } + + + Term** PhraseQuery::getTerms() const{ + //Func - added by search highlighter + + //Let size contain the number of terms + int32_t size = terms->size(); + Term** ret = _CL_NEWARRAY(Term*,size+1); + + CND_CONDITION(ret != NULL,"Could not allocated memory for ret"); + + //Iterate through terms and copy each pointer to ret + for ( int32_t i=0;isize()== 0 ) + return NULL; + + StringBuffer buffer(32); + if ( f==NULL || _tcscmp(field,f)!=0) { + buffer.append(field); + buffer.appendChar(_T(':')); + } + + buffer.appendChar( _T('"') ); + + Term *T = NULL; + + //iterate through all terms + for (size_t i = 0; i < terms->size(); i++) { + //Get the i-th term + T = (*terms)[i]; + + buffer.append( T->text() ); + //Check if i is at the end of terms + if (i != terms->size()-1){ + buffer.appendChar(_T(' ')); + } + } + buffer.appendChar( _T('"') ); + + if (slop != 0) { + buffer.appendChar(_T('~')); + buffer.appendFloat(slop, 0); + } + + buffer.appendBoost(getBoost()); + + return buffer.giveBuffer(); + } + +void PhraseQuery::extractTerms( TermSet * termset ) const +{ + for( size_t i = 0; i < terms->size(); i++ ) + { + Term * pTerm = (*terms)[i]; + if( pTerm && termset->end() == termset->find( pTerm )) + termset->insert( _CL_POINTER( pTerm )); + } +} + + + PhraseWeight::PhraseWeight(Searcher* searcher, PhraseQuery* _parentQuery) { + this->parentQuery=_parentQuery; + this->value = 0; + this->idf = 0; + this->queryNorm = 0; + this->queryWeight = 0; + this->searcher = searcher; + } + + TCHAR* PhraseWeight::toString() { + return STRDUP_TtoT(_T("weight(PhraseQuery)")); + } + PhraseWeight::~PhraseWeight(){ + } + + + Query* PhraseWeight::getQuery() { return parentQuery; } + float_t PhraseWeight::getValue() { return value; } + + float_t PhraseWeight::sumOfSquaredWeights(){ + idf = parentQuery->getSimilarity(searcher)->idf(parentQuery->terms, searcher); + queryWeight = idf * parentQuery->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it + } + + void PhraseWeight::normalize(float_t queryNorm) { + this->queryNorm = queryNorm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document + } + + Scorer* PhraseWeight::scorer(IndexReader* reader) { + //Func - + //Pre - + //Post - + + //Get the length of terms + const int32_t tpsLength = (const int32_t)parentQuery->terms->size(); + + //optimize zero-term case + if (tpsLength == 0) + return NULL; + + TermPositions** tps = _CL_NEWARRAY(TermPositions*,tpsLength+1); + + //Check if tps has been allocated properly + CND_CONDITION(tps != NULL,"Could not allocate memory for tps"); + + TermPositions* p = NULL; + + //Iterate through all terms + for (int32_t i = 0; i < tpsLength; i++) { + //Get the termPostitions for the i-th term + p = reader->termPositions((*parentQuery->terms)[i]); + + //Check if p is valid + if (p == NULL) { + //Delete previous retrieved termPositions + while (--i >= 0){ + _CLVDELETE(tps[i]); //todo: not a clucene object... should be + } + _CLDELETE_ARRAY(tps); + return NULL; + } + + //Store p at i in tps + tps[i] = p; + } + tps[tpsLength] = NULL; + + Scorer* ret = NULL; + + ValueArray positions; + parentQuery->getPositions(positions); + int32_t slop = parentQuery->getSlop(); + if ( slop != 0) + // optimize exact case + //todo: need to pass these: this, tps, + ret = _CLNEW SloppyPhraseScorer(this,tps,positions.values, + parentQuery->getSimilarity(searcher), + slop, reader->norms(parentQuery->field)); + else + ret = _CLNEW ExactPhraseScorer(this, tps, positions.values, + parentQuery->getSimilarity(searcher), + reader->norms(parentQuery->field)); + positions.deleteArray(); + + CND_CONDITION(ret != NULL,"Could not allocate memory for ret"); + + //tps can be deleted safely. SloppyPhraseScorer or ExactPhraseScorer will take care + //of its values + + _CLDELETE_LARRAY(tps); + return ret; + } + + Explanation* PhraseWeight::explain(IndexReader* reader, int32_t doc){ + Explanation* result = _CLNEW Explanation(); + TCHAR descbuf[LUCENE_SEARCH_EXPLANATION_DESC_LEN+1]; + TCHAR* tmp; + + tmp = getQuery()->toString(); + _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,_T("weight(%s in %d), product of:"), + tmp,doc); + _CLDELETE_LCARRAY(tmp); + result->setDescription(descbuf); + + StringBuffer docFreqs; + StringBuffer query; + query.appendChar('"'); + for (size_t i = 0; i < parentQuery->terms->size(); i++) { + if (i != 0) { + docFreqs.appendChar(' '); + query.appendChar(' '); + } + + Term* term = (*parentQuery->terms)[i]; + + docFreqs.append(term->text()); + docFreqs.appendChar('='); + docFreqs.appendInt(searcher->docFreq(term)); + + query.append(term->text()); + } + query.appendChar('\"'); + + _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("idf(%s: %s)"),parentQuery->field,docFreqs.getBuffer()); + Explanation* idfExpl = _CLNEW Explanation(idf, descbuf); + + // explain query weight + Explanation* queryExpl = _CLNEW Explanation(); + tmp = getQuery()->toString(); + _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("queryWeight(%s), product of:"),tmp); + _CLDELETE_LCARRAY(tmp); + queryExpl->setDescription(descbuf); + + Explanation* boostExpl = _CLNEW Explanation(parentQuery->getBoost(), _T("boost")); + bool deleteBoostExpl = false; + if (parentQuery->getBoost() != 1.0f) + queryExpl->addDetail(boostExpl); + else + deleteBoostExpl = true; + queryExpl->addDetail(idfExpl); + + Explanation* queryNormExpl = _CLNEW Explanation(queryNorm,_T("queryNorm")); + queryExpl->addDetail(queryNormExpl); + + queryExpl->setValue(boostExpl->getValue() * + idfExpl->getValue() * + queryNormExpl->getValue()); + + if (deleteBoostExpl) + _CLLDELETE(boostExpl); + + result->addDetail(queryExpl); + + // explain field weight + Explanation* fieldExpl = _CLNEW Explanation(); + _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("fieldWeight(%s:%s in %d), product of:"), + parentQuery->field,query.getBuffer(),doc); + fieldExpl->setDescription(descbuf); + + + Scorer* sc = scorer(reader); + Explanation* tfExpl = sc->explain(doc); + _CLLDELETE(sc); + fieldExpl->addDetail(tfExpl); + fieldExpl->addDetail( _CLNEW Explanation(idfExpl->getValue(), idfExpl->getDescription()) ); + + Explanation* fieldNormExpl = _CLNEW Explanation(); + uint8_t* fieldNorms = reader->norms(parentQuery->field); + float_t fieldNorm = + fieldNorms!=NULL ? Similarity::decodeNorm(fieldNorms[doc]) : 0.0f; + fieldNormExpl->setValue(fieldNorm); + + + _sntprintf(descbuf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("fieldNorm(field=%s, doc=%d)"),parentQuery->field,doc); + fieldNormExpl->setDescription(descbuf); + fieldExpl->addDetail(fieldNormExpl); + + fieldExpl->setValue(tfExpl->getValue() * + idfExpl->getValue() * + fieldNormExpl->getValue()); + + if (queryExpl->getValue() == 1.0f){ + _CLLDELETE(result); + return fieldExpl; + } + + result->addDetail(fieldExpl); + + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + + return result; + } + + +CL_NS_END diff --git a/src/core/CLucene/search/PhraseQuery.h b/src/core/CLucene/search/PhraseQuery.h new file mode 100644 index 00000000000..33c7a8b08d0 --- /dev/null +++ b/src/core/CLucene/search/PhraseQuery.h @@ -0,0 +1,107 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_PhraseQuery_ +#define _lucene_search_PhraseQuery_ + +#include "Query.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(search,Scorer) +#include "CLucene/util/Array.h" +#include "CLucene/util/VoidList.h" + +CL_NS_DEF(search) + /** A Query that matches documents containing a particular sequence of terms. + * A PhraseQuery is built by QueryParser for input like "new york". + * + *

This query may be combined with other terms or queries with a {@link BooleanQuery}. + */ + class CLUCENE_EXPORT PhraseQuery: public Query { + private: + const TCHAR* field; + CL_NS(util)::CLVector* terms; + CL_NS(util)::CLVector* positions; + int32_t slop; + + friend class PhraseWeight; + protected: + Weight* _createWeight(Searcher* searcher); + PhraseQuery(const PhraseQuery& clone); + public: + /** Constructs an empty phrase query. */ + PhraseQuery(); + virtual ~PhraseQuery(); + + /** Sets the number of other words permitted between words in query phrase. + If zero, then this is an exact phrase search. For larger values this works + like a WITHIN or NEAR operator. + +

The slop is in fact an edit-distance, where the units correspond to + moves of terms in the query phrase out of position. For example, to switch + the order of two words requires two moves (the first move places the words + atop one another), so to permit re-orderings of phrases, the slop must be + at least two. + +

More exact matches are scored higher than sloppier matches, thus search + results are sorted by exactness. + +

The slop is zero by default, requiring exact matches.*/ + void setSlop(const int32_t s); + + /** Returns the slop. See setSlop(). */ + int32_t getSlop() const; + + /** + * Adds a term to the end of the query phrase. + * The relative position of the term is the one immediately after the last term added. + */ + void add(CL_NS(index)::Term* term); + + /** + * Adds a term to the end of the query phrase. + * The relative position of the term within the phrase is specified explicitly. + * This allows e.g. phrases with more than one term at the same position + * or phrases with gaps (e.g. in connection with stopwords). + * + * @param term + * @param position + */ + void add(CL_NS(index)::Term* term, int32_t position); + + /** Returns the set of terms in this phrase. */ + CL_NS(index)::Term** getTerms() const; + + /** + * Returns the relative positions of terms in this phrase. + */ + void getPositions(CL_NS(util)::ValueArray& result) const; + + //Returns the sum of squared weights + float_t sumOfSquaredWeights(Searcher* searcher); + + //Normalizes the Weight + void normalize(const float_t norm); + + Scorer* scorer(CL_NS(index)::IndexReader* reader); + + const TCHAR* getFieldName() const; + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* f) const; + + Query* clone() const; + bool equals(Query *) const; + + size_t hashCode() const; + + const char* getObjectName() const; + static const char* getClassName(); + + /** Expert: adds all terms occurring in this query to the terms set. */ + void extractTerms( TermSet * termset ) const; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/PhraseScorer.cpp b/src/core/CLucene/search/PhraseScorer.cpp new file mode 100644 index 00000000000..06d883635e0 --- /dev/null +++ b/src/core/CLucene/search/PhraseScorer.cpp @@ -0,0 +1,223 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Scorer.h" +#include "Explanation.h" +#include "Similarity.h" +#include "SearchHeader.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/index/Terms.h" +#include "_PhraseQueue.h" +#include "_PhraseScorer.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + + PhraseScorer::PhraseScorer(Weight* _weight, TermPositions** tps, + int32_t* offsets, Similarity* similarity, uint8_t* _norms): + Scorer(similarity), weight(_weight), norms(_norms), value(_weight->getValue()), firstTime(true), more(true), freq(0.0f), + first(NULL), last(NULL) + { + //Func - Constructor + //Pre - tps != NULL and is an array of TermPositions + // tpsLength >= 0 + // n != NULL + //Post - The instance has been created + + CND_PRECONDITION(tps != NULL,"tps is NULL"); + + // convert tps to a list of phrase positions. + // note: phrase-position differs from term-position in that its position + // reflects the phrase offset: pp.pos = tp.pos - offset. + // this allows to easily identify a matching (exact) phrase + // when all PhrasePositions have exactly the same position. + int32_t i = 0; + while(tps[i] != NULL){ + PhrasePositions *pp = _CLNEW PhrasePositions(tps[i], offsets[i]); + CND_CONDITION(pp != NULL,"Could not allocate memory for pp"); + + //Store PhrasePos into the PhrasePos pq + if (last != NULL) { // add next to end of list + last->_next = pp; + } else + first = pp; + last = pp; + + i++; + } + + pq = _CLNEW PhraseQueue(i); //i==tps.length + CND_CONDITION(pq != NULL,"Could not allocate memory for pq"); + } + + PhraseScorer::~PhraseScorer() { + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + //The PhraseQueue pq (which is a PriorityQueue) pq is actually empty at present, the elements + //having been transferred by pqToList() to the linked list starting with + //first. The nodes of that linked list are deleted by the destructor of + //first, rather than the destructor of pq. + _CLLDELETE(first); + _CLLDELETE(pq); + } + + bool PhraseScorer::next(){ + if (firstTime) { + init(); + firstTime = false; + } else if (more) { + more = last->next(); // trigger further scanning + } + return doNext(); + } + + // next without initial increment + bool PhraseScorer::doNext() { + while (more) { + while (more && first->doc < last->doc) { // find doc w/ all the terms + more = first->skipTo(last->doc); // skip first upto last + firstToLast(); // and move it to the end + } + + if (more) { + // found a doc with all of the terms + freq = phraseFreq(); // check for phrase + if (freq == 0.0f) // no match + more = last->next(); // trigger further scanning + else + return true; // found a match + } + } + return false; // no more matches + } + + float_t PhraseScorer::score(){ + //System.out.println("scoring " + first.doc); + float_t raw = getSimilarity()->tf(freq) * value; // raw score + return raw * Similarity::decodeNorm(norms[first->doc]); // normalize + } + + bool PhraseScorer::skipTo(int32_t target) { + firstTime = false; + for (PhrasePositions* pp = first; more && pp != NULL; pp = pp->_next) { + more = pp->skipTo(target); + } + if (more) + sort(); // re-sort + return doNext(); + } + + void PhraseScorer::init() { + for (PhrasePositions* pp = first; more && pp != NULL; pp = pp->_next) + more = pp->next(); + if(more) + sort(); + } + + void PhraseScorer::sort() { + pq->clear(); + for (PhrasePositions* pp = first; pp != NULL; pp = pp->_next) + pq->put(pp); + pqToList(); + } + + void PhraseScorer::pqToList(){ + //Func - Transfers the PhrasePositions from the PhraseQueue pq to + // the PhrasePositions list with first as its first element + //Pre - pq != NULL + // first = NULL + // last = NULL + //Post - All PhrasePositions have been transfered to the list + // of PhrasePositions of which the first element is pointed to by first + // and the last element is pointed to by last + + CND_PRECONDITION(pq != NULL,"pq is NULL"); + + last = first = NULL; + + PhrasePositions* PhrasePos = NULL; + + //As long pq is not empty + while (pq->top() != NULL){ + //Pop a PhrasePositions instance + PhrasePos = pq->pop(); + + // add next to end of list + if (last != NULL) { + last->_next = PhrasePos; + } else { + first = PhrasePos; + } + + //Let last point to the new last PhrasePositions instance just added + last = PhrasePos; + //Reset the next of last to NULL + last->_next = NULL; + } + + //Check to see that pq is empty now + CND_CONDITION(pq->size()==0, "pq is not empty while it should be"); + } + + void PhraseScorer::firstToLast(){ + //Func - Moves first to the end of the list + //Pre - first is NULL or points to an PhrasePositions Instance + // last is NULL or points to an PhrasePositions Instance + // first and last both are NULL or both are not NULL + //Post - The first element has become the last element in the list + + CND_PRECONDITION(((first==NULL && last==NULL) ||(first !=NULL && last != NULL)), + "Either first or last is NULL but not both"); + + //Check if first and last are valid pointers + if(first && last){ + last->_next = first; + last = first; + first = first->_next; + last->_next = NULL; + } + } + + + Explanation* PhraseScorer::explain(int32_t _doc) { + Explanation* tfExplanation = _CLNEW Explanation(); + + while (next() && doc() < _doc){ + } + + float_t phraseFreq = (doc() == _doc) ? freq : 0.0f; + tfExplanation->setValue(getSimilarity()->tf(phraseFreq)); + + StringBuffer buf; + buf.append(_T("tf(phraseFreq=")); + buf.appendFloat(phraseFreq,2); + buf.append(_T(")")); + tfExplanation->setDescription(buf.getBuffer()); + + return tfExplanation; + } + + TCHAR* PhraseScorer::toString() { + StringBuffer buf; + buf.append(_T("scorer(")); + + TCHAR* tmp = weight->toString(); + buf.append(tmp); + _CLDELETE_CARRAY(tmp); + + buf.append(_T(")")); + + return buf.toString(); + } + + int32_t PhraseScorer::doc() const { return first->doc; } + +CL_NS_END diff --git a/src/core/CLucene/search/PrefixQuery.cpp b/src/core/CLucene/search/PrefixQuery.cpp new file mode 100644 index 00000000000..7dc9afb7ff8 --- /dev/null +++ b/src/core/CLucene/search/PrefixQuery.cpp @@ -0,0 +1,311 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/index/IndexReader.h" +#include "Similarity.h" +#include "PrefixQuery.h" +#include "BooleanClause.h" +#include "BooleanQuery.h" +#include "TermQuery.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_USE(util) +CL_NS_USE(index) +CL_NS_DEF(search) + + PrefixQuery::PrefixQuery(Term* Prefix){ + //Func - Constructor. + // Constructs a query for terms starting with prefix + //Pre - Prefix != NULL + //Post - The instance has been created + + //Get a pointer to Prefix + prefix = _CL_POINTER(Prefix); + } + + PrefixQuery::PrefixQuery(const PrefixQuery& clone):Query(clone){ + prefix = _CL_POINTER(clone.prefix); + } + Query* PrefixQuery::clone() const{ + return _CLNEW PrefixQuery(*this); + } + + Term* PrefixQuery::getPrefix(bool pointer){ + if ( pointer ) + return _CL_POINTER(prefix); + else + return prefix; + } + + PrefixQuery::~PrefixQuery(){ + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed. + + //Delete prefix by finalizing it + _CLDECDELETE(prefix); + } + + + /** Returns a hash code value for this object.*/ + size_t PrefixQuery::hashCode() const { + return Similarity::floatToByte(getBoost()) ^ prefix->hashCode(); + } + + const char* PrefixQuery::getObjectName()const{ + //Func - Returns the name "PrefixQuery" + //Pre - true + //Post - The string "PrefixQuery" has been returned + + return getClassName(); + } + const char* PrefixQuery::getClassName(){ + //Func - Returns the name "PrefixQuery" + //Pre - true + //Post - The string "PrefixQuery" has been returned + + return "PrefixQuery"; + } + + bool PrefixQuery::equals(Query * other) const{ + if (!(other->instanceOf(PrefixQuery::getClassName()))) + return false; + + PrefixQuery* rq = (PrefixQuery*)other; + bool ret = (this->getBoost() == rq->getBoost()) + && (this->prefix->equals(rq->prefix)); + + return ret; + } + + Query* PrefixQuery::rewrite(IndexReader* reader){ + BooleanQuery* query = _CLNEW BooleanQuery( true ); + TermEnum* enumerator = reader->terms(prefix); + Term* lastTerm = NULL; + try { + const TCHAR* prefixText = prefix->text(); + const TCHAR* prefixField = prefix->field(); + const TCHAR* tmp; + size_t i; + size_t prefixLen = prefix->textLength(); + do { + lastTerm = enumerator->term(); + if (lastTerm != NULL && + lastTerm->field() == prefixField ) // interned comparison + { + + //now see if term->text() starts with prefixText + size_t termLen = lastTerm->textLength(); + if ( prefixLen>termLen ) + break; //the prefix is longer than the term, can't be matched + + tmp = lastTerm->text(); + + //check for prefix match in reverse, since most change will be at the end + for ( i=prefixLen-1;i!=-1;--i ){ + if ( tmp[i] != prefixText[i] ){ + tmp=NULL;//signals inequality + break; + } + } + if ( tmp == NULL ) + break; + + TermQuery* tq = _CLNEW TermQuery(lastTerm); // found a match + tq->setBoost(getBoost()); // set the boost + query->add(tq,true,false, false); // add to query + } else + break; + _CLDECDELETE(lastTerm); + } while (enumerator->next()); + }_CLFINALLY( + enumerator->close(); + _CLDELETE(enumerator); + _CLDECDELETE(lastTerm); + ); + _CLDECDELETE(lastTerm); + + + //if we only added one clause and the clause is not prohibited then + //we can just return the query + if (query->getClauseCount() == 1) { // optimize 1-clause queries + BooleanClause* c=0; + query->getClauses(&c); + + if (!c->prohibited) { // just return clause + c->deleteQuery=false; + Query* ret = c->getQuery(); + + _CLDELETE(query); + return ret; + } + } + + return query; + } + + Query* PrefixQuery::combine(CL_NS(util)::ArrayBase* queries) { + return Query::mergeBooleanQueries(queries); + } + + TCHAR* PrefixQuery::toString(const TCHAR* field) const{ + //Func - Creates a user-readable version of this query and returns it as as string + //Pre - field != NULL + //Post - a user-readable version of this query has been returned as as string + + //Instantiate a stringbuffer buffer to store the readable version temporarily + CL_NS(util)::StringBuffer buffer; + //check if field equal to the field of prefix + if( field==NULL || + _tcscmp(prefix->field(),field) != 0 ) { + //Append the field of prefix to the buffer + buffer.append(prefix->field()); + //Append a colon + buffer.append(_T(":") ); + } + //Append the text of the prefix + buffer.append(prefix->text()); + //Append a wildchar character + buffer.append(_T("*")); + //if the boost factor is not eaqual to 1 + if (getBoost() != 1.0f) { + //Append ^ + buffer.append(_T("^")); + //Append the boost factor + buffer.appendFloat( getBoost(),1); + } + //Convert StringBuffer buffer to TCHAR block and return it + return buffer.toString(); + } + + + + + +//todo: this needs to be exposed, but java is still a bit confused about how... +class PrefixFilter::PrefixGenerator{ + const Term* prefix; +public: + PrefixGenerator(const Term* prefix){ + this->prefix = prefix; + } + virtual ~PrefixGenerator(){ + } + + virtual void handleDoc(int doc) = 0; + + void generate(IndexReader* reader) { + TermEnum* enumerator = reader->terms(prefix); + TermDocs* termDocs = reader->termDocs(); + const TCHAR* prefixText = prefix->text(); + const TCHAR* prefixField = prefix->field(); + const TCHAR* tmp; + size_t i; + size_t prefixLen = prefix->textLength(); + Term* term = NULL; + + try{ + do{ + term = enumerator->term(false); + if (term != NULL && + term->field() == prefixField // interned comparison + ){ + //now see if term->text() starts with prefixText + size_t termLen = term->textLength(); + if ( prefixLen>termLen ) + break; //the prefix is longer than the term, can't be matched + + tmp = term->text(); + + //check for prefix match in reverse, since most change will be at the end + for ( i=prefixLen-1;i!=-1;--i ){ + if ( tmp[i] != prefixText[i] ){ + tmp=NULL;//signals inequality + break; + } + } + if ( tmp == NULL ) + break; + + termDocs->seek(enumerator); + while (termDocs->next()) { + handleDoc(termDocs->doc()); + } + } + }while(enumerator->next()); + } _CLFINALLY( + termDocs->close(); + _CLDELETE(termDocs); + enumerator->close(); + _CLDELETE(enumerator); + ) + } +}; + +class DefaultPrefixGenerator: public PrefixFilter::PrefixGenerator{ +public: + BitSet* bts; + DefaultPrefixGenerator(BitSet* bts, const Term* prefix): + PrefixGenerator(prefix) + { + this->bts = bts; + } + virtual ~DefaultPrefixGenerator(){ + } + void handleDoc(int doc) { + bts->set(doc); + } +}; + +PrefixFilter::PrefixFilter( Term* prefix ) +{ + this->prefix = _CL_POINTER(prefix); +} + +PrefixFilter::~PrefixFilter() +{ + _CLDECDELETE(prefix); +} + +PrefixFilter::PrefixFilter( const PrefixFilter& copy ) : + Filter(), + prefix( _CL_POINTER(copy.prefix) ) +{ +} + +Filter* PrefixFilter::clone() const { + return _CLNEW PrefixFilter(*this ); +} + +TCHAR* PrefixFilter::toString() +{ + //Instantiate a stringbuffer buffer to store the readable version temporarily + CL_NS(util)::StringBuffer buffer; + buffer.append(_T("PrefixFilter(")); + buffer.append(prefix->field()); + buffer.append(_T(")")); + + //Convert StringBuffer buffer to TCHAR block and return it + return buffer.toString(); +} + +/** Returns a BitSet with true for documents which should be permitted in +search results, and false for those that should not. */ +BitSet* PrefixFilter::bits( IndexReader* reader ) +{ + BitSet* bts = _CLNEW BitSet( reader->maxDoc() ); + DefaultPrefixGenerator gen(bts, prefix); + gen.generate(reader); + return bts; +} + +CL_NS(index)::Term* PrefixFilter::getPrefix() const { return prefix; } + +CL_NS_END diff --git a/src/core/CLucene/search/PrefixQuery.h b/src/core/CLucene/search/PrefixQuery.h new file mode 100644 index 00000000000..c5d5767e2cc --- /dev/null +++ b/src/core/CLucene/search/PrefixQuery.h @@ -0,0 +1,80 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_PrefixQuery +#define _lucene_search_PrefixQuery + +CL_CLASS_DEF(index,Term) +//#include "CLucene/index/Terms.h" +//#include "CLucene/index/IndexReader.h" +//#include "SearchHeader.h" +//#include "BooleanQuery.h" +//#include "TermQuery.h" +#include "Query.h" +#include "Filter.h" +CL_CLASS_DEF(util,StringBuffer) + +CL_NS_DEF(search) +/** A Query that matches documents containing terms with a specified prefix. A PrefixQuery +* is built by QueryParser for input like app*. */ + class CLUCENE_EXPORT PrefixQuery: public Query { + private: + CL_NS(index)::Term* prefix; + protected: + PrefixQuery(const PrefixQuery& clone); + public: + + //Constructor. Constructs a query for terms starting with prefix + PrefixQuery(CL_NS(index)::Term* Prefix); + + //Destructor + ~PrefixQuery(); + + //Returns the name "PrefixQuery" + const char* getObjectName() const; + static const char* getClassName(); + + /** Returns the prefix of this query. */ + CL_NS(index)::Term* getPrefix(bool pointer=true); + + Query* combine(CL_NS(util)::ArrayBase* queries); + Query* rewrite(CL_NS(index)::IndexReader* reader); + Query* clone() const; + bool equals(Query * other) const; + + //Creates a user-readable version of this query and returns it as as string + TCHAR* toString(const TCHAR* field) const; + + size_t hashCode() const; + }; + + + class CLUCENE_EXPORT PrefixFilter: public Filter + { + private: + CL_NS(index)::Term* prefix; + protected: + PrefixFilter( const PrefixFilter& copy ); + public: + class PrefixGenerator; + + PrefixFilter(CL_NS(index)::Term* prefix); + ~PrefixFilter(); + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + Filter* clone() const; + + /** Prints a user-readable version of this query. */ + TCHAR* toString(); + + // Returns a reference of internal prefix + CL_NS(index)::Term* getPrefix() const; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Query.h b/src/core/CLucene/search/Query.h new file mode 100644 index 00000000000..b5800b9cb53 --- /dev/null +++ b/src/core/CLucene/search/Query.h @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Query_h +#define _lucene_search_Query_h + + +#include "CLucene/util/Array.h" +#include "CLucene/index/Term.h" +#include "CLucene/util/Equators.h" + +CL_CLASS_DEF(index,IndexReader) + + +CL_NS_DEF(search) + class Weight; + class Similarity; + class Searcher; + + typedef std::set TermSet; + + /** The abstract base class for queries. +

Instantiable subclasses are: +

    +
  • {@link TermQuery} +
  • {@link MultiTermQuery} +
  • {@link BooleanQuery} +
  • {@link WildcardQuery} +
  • {@link PhraseQuery} +
  • {@link PrefixQuery} +
  • {@link PhrasePrefixQuery} +
  • {@link FuzzyQuery} +
  • {@link RangeQuery} +
  • {@link spans.SpanQuery} +
+

A parser for queries is contained in: +

    +
  • {@link queryParser.QueryParser QueryParser} +
+ */ +class CLUCENE_EXPORT Query : public CL_NS(util)::NamedObject{ + private: + // query boost factor + float_t boost; + protected: + Query(); + Query(const Query& clone); + public: + virtual ~Query(); + + /** Sets the boost for this query clause to b. Documents + * matching this clause will (in addition to the normal weightings) have + * their score multiplied by b. + */ + void setBoost(float_t b); + + /** Gets the boost for this clause. Documents matching + * this clause will (in addition to the normal weightings) have their score + * multiplied by b. The boost is 1.0 by default. + */ + float_t getBoost() const; + + /** Expert: Constructs an initializes a Weight for a top-level query. */ + Weight* weight(Searcher* searcher); + + /** Expert: called to re-write queries into primitive queries. + * + * @memory: + * The caller has to clean up. When rewrite() returns a pointer which + * differs from the pointer to the initial query, the pointer points + * to a newly allocated object and has also to be cleaned up. */ + virtual Query* rewrite(CL_NS(index)::IndexReader* reader); + + /** Expert: called when re-writing queries under MultiSearcher. + * + * Create a single query suitable for use by all subsearchers (in 1-1 + * correspondence with queries). This is an optimization of the OR of + * all queries. We handle the common optimization cases of equal + * queries and overlapping clauses of boolean OR queries (as generated + * by MultiTermQuery.rewrite() and RangeQuery.rewrite()). + * Be careful overriding this method as queries[0] determines which + * method will be called and is not necessarily of the same type as + * the other queries. + */ + virtual Query* combine(CL_NS(util)::ArrayBase* queries); + + /** Expert: adds all terms occurring in this query to the terms set. Only + * works if this query is in its {@link #rewrite rewritten} form. + * + * @memory: + * CLucene specific - all terms in the list have their reference counter + * increased by one. + * + * @throws CLuceneError with CL_ERR_UnsupportedOperation + */ + virtual void extractTerms( TermSet * termset ) const; + + /** Expert: merges the clauses of a set of BooleanQuery's into a single + * BooleanQuery. + * + *

A utility for use by {@link #combine(Query[])} implementations. + */ + static Query* mergeBooleanQueries(CL_NS(util)::ArrayBase* queries); + + /** Expert: Returns the Similarity implementation to be used for this query. + * Subclasses may override this method to specify their own Similarity + * implementation, perhaps one that delegates through that of the Searcher. + * By default the Searcher's Similarity implementation is returned.*/ + Similarity* getSimilarity(Searcher* searcher); + + /** Returns a clone of this query. */ + virtual Query* clone() const = 0; + _CL_DEPRECATED(getObjectName) const char* getQueryName() const; + + /** Prints a query to a string, with field assumed to be the + * default field and omitted. + *

The representation used is one that is supposed to be readable + * by {@link org.apache.lucene.queryParser.QueryParser QueryParser}. However, + * there are the following limitations: + *

    + *
  • If the query was created by the parser, the printed + * representation may not be exactly what was parsed. For example, + * characters that need to be escaped will be represented without + * the required backslash.
  • + *
  • Some of the more complicated queries (e.g. span queries) + * don't have a representation that can be parsed by QueryParser.
  • + *
+ * + * @memory always returns a newly allocated string, which the caller is + * responsible for deleting + * + */ + virtual TCHAR* toString(const TCHAR* field) const = 0; + + virtual bool equals(Query* other) const = 0; + virtual size_t hashCode() const = 0; + + /** Prints a query to a string. */ + TCHAR* toString() const; + + + /** Expert: Constructs an appropriate Weight implementation for this query. + * + *

Only implemented by primitive queries, which re-write to themselves. + * This is an Internal function + */ + virtual Weight* _createWeight(Searcher* searcher); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/QueryFilter.cpp b/src/core/CLucene/search/QueryFilter.cpp new file mode 100644 index 00000000000..7da64f12acc --- /dev/null +++ b/src/core/CLucene/search/QueryFilter.cpp @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "QueryFilter.h" +#include "IndexSearcher.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/BitSet.h" +#include "SearchHeader.h" +#include "Query.h" + +CL_NS_DEF(search) +CL_NS_USE(util) +CL_NS_USE(index) + + +class QFHitCollector: public HitCollector{ + CL_NS(util)::BitSet* bits; +public: + QFHitCollector(CL_NS(util)::BitSet* bits){ + this->bits = bits; + } + void collect(const int32_t doc, const float_t /*score*/){ + bits->set(doc); // set bit for hit + } +}; + + +QueryFilter::QueryFilter( const Query* query ) +{ + this->query = query->clone(); + bDeleteQuery = true; +} + +QueryFilter::QueryFilter( Query* query, bool bDeleteQuery ) +{ + this->query = query; + this->bDeleteQuery = bDeleteQuery; +} + +QueryFilter::~QueryFilter() +{ + if( bDeleteQuery ) + _CLDELETE( query ); +} + + +QueryFilter::QueryFilter( const QueryFilter& copy ) +{ + this->query = copy.query->clone(); + bDeleteQuery = true; +} + + +Filter* QueryFilter::clone() const { + return _CLNEW QueryFilter(*this ); +} + + +TCHAR* QueryFilter::toString() +{ + TCHAR* qt = query->toString(); + size_t len = _tcslen(qt) + 14; + TCHAR* ret = _CL_NEWARRAY( TCHAR, len ); + ret[0] = 0; + _sntprintf( ret, len, _T("QueryFilter(%s)"), qt ); + _CLDELETE_CARRAY(qt); + return ret; +} + + +/** Returns a BitSet with true for documents which should be permitted in +search results, and false for those that should not. */ +BitSet* QueryFilter::bits( IndexReader* reader ) +{ + BitSet* bits = _CLNEW BitSet(reader->maxDoc()); + + IndexSearcher s(reader); + QFHitCollector hc(bits); + s._search(query, NULL, &hc); + return bits; +} + + +CL_NS_END diff --git a/src/core/CLucene/search/QueryFilter.h b/src/core/CLucene/search/QueryFilter.h new file mode 100644 index 00000000000..452dd4e7843 --- /dev/null +++ b/src/core/CLucene/search/QueryFilter.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_QueryFilter_ +#define _lucene_search_QueryFilter_ + +//#include "CLucene/util/BitSet.h" +//#include "CLucene/index/IndexReader.h" +//#include "SearchHeader.h" +#include "Filter.h" +CL_CLASS_DEF(search,Query) +//#include "CachingWrapperFilter.h" + +CL_NS_DEF(search) + +class CLUCENE_EXPORT QueryFilter: public Filter +{ +private: + Query* query; + bool bDeleteQuery; +protected: + QueryFilter( const QueryFilter& copy ); +public: + QueryFilter( const Query* query ); + QueryFilter( Query* query, bool bDeleteQuery ); + + ~QueryFilter(); + + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + Filter *clone() const; + + TCHAR *toString(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/RangeFilter.cpp b/src/core/CLucene/search/RangeFilter.cpp new file mode 100644 index 00000000000..f802ea9d0cd --- /dev/null +++ b/src/core/CLucene/search/RangeFilter.cpp @@ -0,0 +1,148 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/BitSet.h" +#include "RangeFilter.h" + +CL_NS_DEF(search) +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) + + +RangeFilter::RangeFilter( const TCHAR* _fieldName, const TCHAR* _lowerTerm, const TCHAR* _upperTerm, + bool _includeLower, bool _includeUpper ) + : fieldName(NULL), lowerTerm(NULL), upperTerm(NULL) + , includeLower(_includeLower), includeUpper(_includeUpper) +{ + if (NULL == _lowerTerm && NULL == _upperTerm) { + _CLTHROWT(CL_ERR_IllegalArgument, _T("At least one value must be non-null")); + } + if (_includeLower && NULL == _lowerTerm) { + _CLTHROWT(CL_ERR_IllegalArgument, _T("The lower bound must be non-null to be inclusive")); + } + if (_includeUpper && NULL == _upperTerm) { + _CLTHROWT(CL_ERR_IllegalArgument, _T("The upper bound must be non-null to be inclusive")); + } + + this->fieldName = STRDUP_TtoT(_fieldName); + if ( _lowerTerm != NULL ) + this->lowerTerm = STRDUP_TtoT(_lowerTerm); + if ( _upperTerm != NULL ) + this->upperTerm = STRDUP_TtoT(_upperTerm); +} + +RangeFilter::RangeFilter( const RangeFilter& copy ) : + fieldName( STRDUP_TtoT(copy.fieldName) ), + lowerTerm( STRDUP_TtoT(copy.lowerTerm) ), + upperTerm( STRDUP_TtoT(copy.upperTerm) ), + includeLower( copy.includeLower ), + includeUpper( copy.includeUpper ) +{ +} + +RangeFilter::~RangeFilter() +{ + _CLDELETE_LCARRAY( fieldName ); + _CLDELETE_LCARRAY( lowerTerm ); + _CLDELETE_LCARRAY( upperTerm ); +} + +RangeFilter* RangeFilter::Less( const TCHAR* _fieldName, const TCHAR* _upperTerm ) { + return _CLNEW RangeFilter( _fieldName, NULL, _upperTerm, false, true ); +} + +RangeFilter* RangeFilter::More( const TCHAR* _fieldName, const TCHAR* _lowerTerm ) { + return _CLNEW RangeFilter( _fieldName, _lowerTerm, NULL, true, false ); +} + +BitSet* RangeFilter::bits( IndexReader* reader ) +{ + BitSet* bts = _CLNEW BitSet( reader->maxDoc() ); + Term* term = NULL; + + Term* t = _CLNEW Term( fieldName, (lowerTerm ? lowerTerm : _T("")), false ); + TermEnum* enumerator = reader->terms( t ); // get enumeration of all terms after lowerValue + _CLDECDELETE( t ); + + if( enumerator->term(false) == NULL ) { + _CLLDELETE( enumerator ); + return bts; + } + + bool checkLower = false; + if( !includeLower ) // make adjustments to set to exclusive + checkLower = true; + + TermDocs* termDocs = reader->termDocs(); + + #define CLEANUP \ + _CLLDECDELETE( term ); \ + termDocs->close(); \ + _CLLDELETE( termDocs ); \ + enumerator->close(); \ + _CLLDELETE( enumerator ) + + try + { + do + { + term = enumerator->term(); + + if( term == NULL || _tcscmp(term->field(), fieldName) ) + break; + + if( !checkLower || lowerTerm == NULL || _tcscmp(term->text(), lowerTerm) > 0 ) + { + checkLower = false; + if( upperTerm != NULL ) + { + int compare = _tcscmp( upperTerm, term->text() ); + + /* if beyond the upper term, or is exclusive and + * this is equal to the upper term, break out */ + if( (compare < 0) || (!includeUpper && compare == 0) ) + break; + } + + termDocs->seek( enumerator->term(false) ); + while( termDocs->next() ) { + bts->set( termDocs->doc() ); + } + } + + _CLDECDELETE( term ); + } + while( enumerator->next() ); + }catch(CLuceneError& err){ + _CLDELETE(bts); + CLEANUP; + throw err; + } + CLEANUP; + + return bts; +} + +TCHAR* RangeFilter::toString() +{ + size_t len = (fieldName ? _tcslen(fieldName) : 0) + (lowerTerm ? _tcslen(lowerTerm) : 0) + (upperTerm ? _tcslen(upperTerm) : 0) + 8; + TCHAR* ret = _CL_NEWARRAY( TCHAR, len ); + ret[0] = 0; + _sntprintf( ret, len, _T("%s: [%s-%s]"), fieldName, (lowerTerm?lowerTerm:_T("")), (upperTerm?upperTerm:_T("")) ); + + return ret; +} + +Filter* RangeFilter::clone() const { + return _CLNEW RangeFilter(*this ); +} + +CL_NS_END diff --git a/src/core/CLucene/search/RangeFilter.h b/src/core/CLucene/search/RangeFilter.h new file mode 100644 index 00000000000..e30925e42a8 --- /dev/null +++ b/src/core/CLucene/search/RangeFilter.h @@ -0,0 +1,75 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_search_RangeFilter_ +#define _lucene_search_RangeFilter_ + +#include "Filter.h" + +CL_CLASS_DEF(index,Term) + +CL_NS_DEF(search) + +/** + * A Filter that restricts search results to a range of values in a given + * field. + * + *

+ * This code borrows heavily from {@link RangeQuery}, but is implemented as a Filter + * + *

+ */ +class CLUCENE_EXPORT RangeFilter: public Filter +{ +private: + TCHAR* fieldName; + TCHAR* lowerTerm; + TCHAR* upperTerm; + bool includeLower; + bool includeUpper; + +public: + /** + * @param fieldName The field this range applies to + * @param lowerTerm The lower bound on this range + * @param upperTerm The upper bound on this range + * @param includeLower Does this range include the lower bound? + * @param includeUpper Does this range include the upper bound? + */ + RangeFilter( const TCHAR* fieldName, const TCHAR* lowerTerm, const TCHAR* upperTerm, + bool includeLower, bool includeUpper ); + virtual ~RangeFilter(); + + /** + * Constructs a filter for field fieldName matching + * less than or equal to upperTerm. + */ + static RangeFilter* Less( const TCHAR* fieldName, const TCHAR* upperTerm ); + + /** + * Constructs a filter for field fieldName matching + * more than or equal to lowerTerm. + */ + static RangeFilter* More( const TCHAR* fieldName, const TCHAR* lowerTerm ); + + /** + * Returns a BitSet with true for documents which should be + * permitted in search results, and false for those that should + * not. + */ + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + Filter* clone() const; + + TCHAR* toString(); + +protected: + RangeFilter( const RangeFilter& copy ); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/RangeQuery.cpp b/src/core/CLucene/search/RangeQuery.cpp new file mode 100644 index 00000000000..8fe56437431 --- /dev/null +++ b/src/core/CLucene/search/RangeQuery.cpp @@ -0,0 +1,194 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "RangeQuery.h" + +#include "SearchHeader.h" +#include "Scorer.h" +#include "BooleanQuery.h" +#include "TermQuery.h" +#include "Similarity.h" + +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" + + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + RangeQuery::RangeQuery(Term* lowerTerm, Term* upperTerm, const bool Inclusive){ + //Func - Constructor + //Pre - (LowerTerm != NULL OR UpperTerm != NULL) AND + // if LowerTerm and UpperTerm are valid pointer then the fieldnames must be the same + //Post - The instance has been created + + if (lowerTerm == NULL && upperTerm == NULL) + { + _CLTHROWA(CL_ERR_IllegalArgument,"At least one term must be non-null"); + } + if (lowerTerm != NULL && upperTerm != NULL && lowerTerm->field() != upperTerm->field()) + { + _CLTHROWA(CL_ERR_IllegalArgument,"Both terms must be for the same field"); + } + + // if we have a lowerTerm, start there. otherwise, start at beginning + if (lowerTerm != NULL) { + this->lowerTerm = _CL_POINTER(lowerTerm); + } + else { + this->lowerTerm = _CLNEW Term(upperTerm, LUCENE_BLANK_STRING); + } + this->upperTerm = (upperTerm != NULL ? _CL_POINTER(upperTerm) : NULL); + this->inclusive = Inclusive; + } + RangeQuery::RangeQuery(const RangeQuery& clone): + Query(clone){ + this->inclusive = clone.inclusive; + this->upperTerm = (clone.upperTerm != NULL ? _CL_POINTER(clone.upperTerm) : NULL ); + this->lowerTerm = (clone.lowerTerm != NULL ? _CL_POINTER(clone.lowerTerm) : NULL ); + } + Query* RangeQuery::clone() const{ + return _CLNEW RangeQuery(*this); + } + + RangeQuery::~RangeQuery() { + //Func - Destructor + //Pre - true + //Post - The instance has been destroyed + + _CLDECDELETE(lowerTerm); + _CLDECDELETE(upperTerm); + } + + /** Returns a hash code value for this object.*/ + size_t RangeQuery::hashCode() const { + return Similarity::floatToByte(getBoost()) ^ + (lowerTerm != NULL ? lowerTerm->hashCode() : 0) ^ + (upperTerm != NULL ? upperTerm->hashCode() : 0) ^ + (this->inclusive ? 1 : 0); + } + + const char* RangeQuery::getObjectName() const{ + return getClassName(); + } + const char* RangeQuery::getClassName(){ + return "RangeQuery"; + } + + Query* RangeQuery::combine(CL_NS(util)::ArrayBase* queries) { + return Query::mergeBooleanQueries(queries); + } + + bool RangeQuery::equals(Query * other) const{ + if (!(other->instanceOf(RangeQuery::getClassName()))) + return false; + + RangeQuery* rq = (RangeQuery*)other; + bool ret = (this->getBoost() == rq->getBoost()) + && (this->isInclusive() == rq->isInclusive()) + && (this->getLowerTerm()->equals(rq->getLowerTerm())) + && (this->getUpperTerm()->equals(rq->getUpperTerm())); + + return ret; + } + + + Query* RangeQuery::rewrite(IndexReader* reader){ + + BooleanQuery* query = _CLNEW BooleanQuery( true ); + TermEnum* enumerator = reader->terms(lowerTerm); + Term* lastTerm = NULL; + try { + bool checkLower = false; + if (!inclusive) // make adjustments to set to exclusive + checkLower = true; + + const TCHAR* testField = getField(); + do { + lastTerm = enumerator->term(); + if (lastTerm != NULL && lastTerm->field() == testField ) { + if (!checkLower || _tcscmp(lastTerm->text(),lowerTerm->text()) > 0) { + checkLower = false; + if (upperTerm != NULL) { + int compare = _tcscmp(upperTerm->text(),lastTerm->text()); + /* if beyond the upper term, or is exclusive and + * this is equal to the upper term, break out */ + if ((compare < 0) || (!inclusive && compare == 0)) + break; + } + TermQuery* tq = _CLNEW TermQuery(lastTerm); // found a match + tq->setBoost(getBoost()); // set the boost + query->add(tq, true, false, false); // add to query + } + }else { + break; + } + _CLDECDELETE(lastTerm); + } + while (enumerator->next()); + }catch(...){ + _CLDECDELETE(lastTerm); //always need to delete this + _CLDELETE(query); //in case of error, delete the query + enumerator->close(); + _CLDELETE(enumerator); + throw; //rethrow + } + _CLDECDELETE(lastTerm); //always need to delete this + enumerator->close(); + _CLDELETE(enumerator); + + return query; + } + + TCHAR* RangeQuery::toString(const TCHAR* field) const + { + StringBuffer buffer; + if ( field==NULL || _tcscmp(getField(),field)!=0 ) + { + buffer.append( getField() ); + buffer.append( _T(":")); + } + buffer.append(inclusive ? _T("[") : _T("{")); + buffer.append(lowerTerm != NULL ? lowerTerm->text() : _T("NULL")); + buffer.append(_T(" TO ")); + buffer.append(upperTerm != NULL ? upperTerm->text() : _T("NULL")); + buffer.append(inclusive ? _T("]") : _T("}")); + if (getBoost() != 1.0f) + { + buffer.append( _T("^")); + buffer.appendFloat( getBoost(),1 ); + } + return buffer.toString(); + } + + + const TCHAR* RangeQuery::getField() const + { + return (lowerTerm != NULL ? lowerTerm->field() : upperTerm->field()); + } + + Term* RangeQuery::getLowerTerm(bool pointer) const { + if ( pointer ) + return _CL_POINTER(lowerTerm); + else + return lowerTerm; + } + + Term* RangeQuery::getUpperTerm(bool pointer) const { + if ( pointer ) + return _CL_POINTER(upperTerm); + else + return upperTerm; + } + + bool RangeQuery::isInclusive() const { return inclusive; } + + +CL_NS_END diff --git a/src/core/CLucene/search/RangeQuery.h b/src/core/CLucene/search/RangeQuery.h new file mode 100644 index 00000000000..841ff25616e --- /dev/null +++ b/src/core/CLucene/search/RangeQuery.h @@ -0,0 +1,92 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_RangeQuery_ +#define _lucene_search_RangeQuery_ + +//#include "SearchHeader.h" +//#include "Scorer.h" +//#include "TermQuery.h" +#include "Query.h" + +CL_CLASS_DEF(index,Term) +//#include "CLucene/index/Terms.h" + +CL_CLASS_DEF(util,StringBuffer) + + +CL_NS_DEF(search) + +/** + * A Query that matches documents within an exclusive range. A RangeQuery + * is built by QueryParser for input like [010 TO 120] but only if the QueryParser has + * the useOldRangeQuery property set to true. The QueryParser default behaviour is to use + * the newer ConstantScoreRangeQuery class. This is generally preferable because: + *
    + *
  • It is faster than RangeQuery
  • + *
  • Unlike RangeQuery, it does not cause a BooleanQuery.TooManyClauses exception if the range of values is large
  • + *
  • Unlike RangeQuery it does not influence scoring based on the scarcity of individual terms that may match
  • + *
+ * + * + * @see ConstantScoreRangeQuery + * + * + * @version $Id: RangeQuery.java 520891 2007-03-21 13:58:47Z yonik $ + */ +class CLUCENE_EXPORT RangeQuery: public Query +{ +private: + CL_NS(index)::Term* lowerTerm; + CL_NS(index)::Term* upperTerm; + bool inclusive; +protected: + RangeQuery(const RangeQuery& clone); + +public: + /** Constructs a query selecting all terms greater than + * lowerTerm but less than upperTerm. + * There must be at least one term and either term may be null, + * in which case there is no bound on that side, but if there are + * two terms, both terms must be for the same field. + */ + RangeQuery(CL_NS(index)::Term* LowerTerm, CL_NS(index)::Term* UpperTerm, const bool Inclusive); + ~RangeQuery(); + + const char* getObjectName() const; + static const char* getClassName(); + + /** + * FIXME: Describe rewrite method here. + * + * @param reader an IndexReader value + * @return a Query value + * @exception IOException if an error occurs + */ + Query* rewrite(CL_NS(index)::IndexReader* reader); + + Query* combine(CL_NS(util)::ArrayBase* queries); + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + + Query* clone() const; + + bool equals(Query * other) const; + + /** Returns the lower term of this range query */ + CL_NS(index)::Term* getLowerTerm(bool pointer=true) const; + /** Returns the upper term of this range query */ + CL_NS(index)::Term* getUpperTerm(bool pointer=true) const; + bool isInclusive() const; + /** Returns true if the range query is inclusive */ + const TCHAR* getField() const; + + size_t hashCode() const; +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Scorer.cpp b/src/core/CLucene/search/Scorer.cpp new file mode 100644 index 00000000000..9aa20fdf60e --- /dev/null +++ b/src/core/CLucene/search/Scorer.cpp @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Scorer.h" +#include "SearchHeader.h" + +CL_NS_DEF(search) + +Scorer::Scorer(Similarity* _similarity) : similarity(_similarity){ +} + +Scorer::~Scorer(){ +} + +Similarity* Scorer::getSimilarity() const{ + return this->similarity; +} + +void Scorer::score(HitCollector* hc) { + while (next()) { + hc->collect(doc(), score()); + } +} + +bool Scorer::score( HitCollector* results, const int32_t maxDoc ) { + while( doc() < maxDoc ) { + results->collect( doc(), score() ); + if ( !next() ) + return false; + } + return true; +} +bool Scorer::sort(const Scorer* elem1, const Scorer* elem2){ + return elem1->doc() < elem2->doc(); +} + +CL_NS_END diff --git a/src/core/CLucene/search/Scorer.h b/src/core/CLucene/search/Scorer.h new file mode 100644 index 00000000000..dab85fb231e --- /dev/null +++ b/src/core/CLucene/search/Scorer.h @@ -0,0 +1,134 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Scorer_ +#define _lucene_search_Scorer_ + +CL_CLASS_DEF(search,Similarity) +CL_CLASS_DEF(search,HitCollector) +CL_CLASS_DEF(search,Explanation) + +CL_NS_DEF(search) + +/** +* Expert: Common scoring functionality for different types of queries. +* +*

+* A Scorer either iterates over documents matching a +* query in increasing order of doc Id, or provides an explanation of +* the score for a query for a given document. +*

+*

+* Document scores are computed using a given Similarity +* implementation. +*

+* @see BooleanQuery#setAllowDocsOutOfOrder +*/ +class CLUCENE_EXPORT Scorer { +private: + Similarity* similarity; +protected: + /** Constructs a Scorer. + * @param similarity The Similarity implementation used by this scorer. + */ + Scorer(Similarity* _similarity); + +public: + virtual ~Scorer(); + + /** Returns the Similarity implementation used by this scorer. */ + Similarity* getSimilarity() const; + + /** Scores and collects all matching documents. + * @param hc The collector to which all matching documents are passed through + * {@link HitCollector#collect(int, float)}. + *
When this method is used the {@link #explain(int)} method should not be used. + */ + virtual void score(HitCollector* hc) ; + + /** Expert: Collects matching documents in a range. Hook for optimization. + * Note that {@link #next()} must be called once before this method is called + * for the first time. + * @param hc The collector to which all matching documents are passed through + * {@link HitCollector#collect(int, float)}. + * @param max Do not score documents past this. + * @return true if more matching documents may remain. + */ + virtual bool score( HitCollector* results, const int32_t maxDoc ); + + /** + * Advances to the document matching this Scorer with the lowest doc Id + * greater than the current value of {@link #doc()} (or to the matching + * document with the lowest doc Id if next has never been called on + * this Scorer). + * + *

+ * When this method is used the {@link #explain(int)} method should not + * be used. + *

+ * + * @return true iff there is another document matching the query. + * @see BooleanQuery#setAllowDocsOutOfOrder + */ + virtual bool next() = 0; + + /** Returns the current document number matching the query. + * Initially invalid, until {@link #next()} is called the first time. + */ + virtual int32_t doc() const = 0; + + /** Returns the score of the current document matching the query. + * Initially invalid, until {@link #next()} or {@link #skipTo(int)} + * is called the first time. + */ + virtual float_t score() = 0; + + /** + * Skips to the document matching this Scorer with the lowest doc Id + * greater than or equal to a given target. + * + *

+ * The behavior of this method is undefined if the target specified is + * less than or equal to the current value of {@link #doc()}. + *

+ * Behaves as if written: + *

+	*   boolean skipTo(int target) {
+	*     do {
+	*       if (!next())
+	* 	     return false;
+	*     } while (target > doc());
+	*     return true;
+	*   }
+	* 
+ * Most implementations are considerably more efficient than that. + *

+ * + *

+ * When this method is used the {@link #explain(int)} method should not + * be used. + *

+ * + * @param target The target document number. + * @return true iff there is such a match. + * @see BooleanQuery#setAllowDocsOutOfOrder + */ + virtual bool skipTo(int32_t target) = 0; + + /** Returns an explanation of the score for a document. + *
When this method is used, the {@link #next()}, {@link #skipTo(int)} and + * {@link #score(HitCollector)} methods should not be used. + * @param doc The document number for the explanation. + */ + virtual Explanation* explain(int32_t doc) = 0; + + /** Returns a string which explains the object */ + virtual TCHAR* toString() = 0; + + static bool sort(const Scorer* elem1, const Scorer* elem2); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/ScorerDocQueue.cpp b/src/core/CLucene/search/ScorerDocQueue.cpp new file mode 100644 index 00000000000..514d1afa88f --- /dev/null +++ b/src/core/CLucene/search/ScorerDocQueue.cpp @@ -0,0 +1,191 @@ +#include "CLucene/_ApiHeader.h" +#include "ScorerDocQueue.h" +#include "Scorer.h" + +CL_NS_DEF(util) + +class ScorerDocQueue::HeapedScorerDoc:LUCENE_BASE { +public: + Scorer* _scorer; + int32_t _doc; + + HeapedScorerDoc( Scorer* s ); + HeapedScorerDoc( Scorer* s, int32_t doc ); + ~HeapedScorerDoc(); + + void adjust(); +}; + +ScorerDocQueue::HeapedScorerDoc::HeapedScorerDoc( Scorer* scorer ) : _scorer(scorer), _doc(scorer->doc()) +{ +} + +ScorerDocQueue::HeapedScorerDoc::HeapedScorerDoc( Scorer* scorer, int32_t doc ) : _scorer(scorer), _doc(doc) +{ +} + +ScorerDocQueue::HeapedScorerDoc::~HeapedScorerDoc() +{ +} + +void ScorerDocQueue::HeapedScorerDoc::adjust() +{ + this->_doc = _scorer->doc(); +} + +ScorerDocQueue::ScorerDocQueue( int32_t maxSize ) : maxSize(maxSize), _size(0) +{ + int heapSize = maxSize + 1; + heap = _CL_NEWARRAY( HeapedScorerDoc*, heapSize ); + for ( int32_t i = 0; i < heapSize; i++ ) { + heap[i] = NULL; + } + topHsd = heap[1]; +} + +ScorerDocQueue::~ScorerDocQueue() +{ + clear(); + _CLDELETE_ARRAY( heap ); +} + +void ScorerDocQueue::put( Scorer* scorer ) +{ + _size++; + heap[ _size ] = _CLNEW HeapedScorerDoc( scorer ); + upHeap(); +} + +bool ScorerDocQueue::insert( Scorer* scorer ) +{ + if ( _size < maxSize ) { + put( scorer ); + return true; + } else { + int32_t docNr = scorer->doc(); + if (( _size > 0 ) && ( !( docNr < topHsd->_doc ))) { + _CLDELETE( heap[1] ); + heap[1] = _CLNEW HeapedScorerDoc( scorer, docNr ); + downHeap(); + return true; + } else { + return false; + } + } +} + +Scorer* ScorerDocQueue::pop() +{ + Scorer* result = topHsd->_scorer; + popNoResult(); + return result; +} + +void ScorerDocQueue::adjustTop() +{ + topHsd->adjust(); + downHeap(); +} + +int32_t ScorerDocQueue::size() +{ + return _size; +} + +void ScorerDocQueue::clear() +{ + for ( int32_t i = 0; i <= _size; i++ ) { + _CLDELETE( heap[i] ); + } + _size = 0; +} + +Scorer* ScorerDocQueue::top() +{ + return topHsd->_scorer; +} + +int32_t ScorerDocQueue::topDoc() +{ + return topHsd->_doc; +} + +float_t ScorerDocQueue::topScore() +{ + return topHsd->_scorer->score(); +} + +bool ScorerDocQueue::topNextAndAdjustElsePop() +{ + return checkAdjustElsePop( topHsd->_scorer->next() ); +} + +bool ScorerDocQueue::topSkipToAndAdjustElsePop( int32_t target ) +{ + return checkAdjustElsePop( topHsd->_scorer->skipTo( target )); +} + +bool ScorerDocQueue::checkAdjustElsePop( bool cond ) +{ + if ( cond ) { + topHsd->_doc = topHsd->_scorer->doc(); + } else { + _CLLDELETE( heap[1] ); + heap[1] = heap[_size]; + heap[_size] = NULL; + _size--; + } + downHeap(); + return cond; +} + +void ScorerDocQueue::popNoResult() +{ + _CLLDELETE( heap[1] ); + heap[1] = heap[_size]; + heap[_size] = NULL; + _size--; + downHeap(); +} + +void ScorerDocQueue::upHeap() +{ + int32_t i = _size; + HeapedScorerDoc* node = heap[i]; + int32_t j = i >> 1; + while (( j > 0 ) && ( node->_doc < heap[j]->_doc )) { + heap[i] = heap[j]; + i = j; + j = j >> 1; + } + heap[i] = node; + topHsd = heap[1]; +} + +void ScorerDocQueue::downHeap() +{ + int32_t i = 1; + HeapedScorerDoc* node = heap[i]; + int32_t j = i << 1; + int32_t k = j + 1; + + if (( k <= _size ) && ( heap[k]->_doc < heap[j]->_doc )) { + j = k; + } + + while (( j <= _size ) && ( heap[j]->_doc < node->_doc )) { + heap[i] = heap[j]; + i = j; + j = i << 1; + k = j + 1; + if (( k <= _size ) && ( heap[k]->_doc < heap[j]->_doc )) { + j = k; + } + } + + heap[i] = node; + topHsd = heap[1]; +} + +CL_NS_END + diff --git a/src/core/CLucene/search/ScorerDocQueue.h b/src/core/CLucene/search/ScorerDocQueue.h new file mode 100644 index 00000000000..34e8c810792 --- /dev/null +++ b/src/core/CLucene/search/ScorerDocQueue.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_ScorerDocQueue_ +#define _lucene_util_ScorerDocQueue_ + + +CL_CLASS_DEF(search,Scorer) + +CL_NS_USE(search) +CL_NS_DEF(util) + +class CLUCENE_EXPORT ScorerDocQueue:LUCENE_BASE { +private: + class HeapedScorerDoc; + + HeapedScorerDoc** heap; + HeapedScorerDoc* topHsd; + + int32_t maxSize; + int32_t _size; + +public: + + ScorerDocQueue( int32_t maxSize ); + virtual ~ScorerDocQueue(); + + void put( Scorer* scorer ); + bool insert( Scorer* scorer ); + Scorer* pop(); + void adjustTop(); + int32_t size(); + void clear(); + + Scorer* top(); + int32_t topDoc(); + float_t topScore(); + bool topNextAndAdjustElsePop(); + bool topSkipToAndAdjustElsePop( int32_t target ); + +private: + + bool checkAdjustElsePop( bool cond ); + void popNoResult(); + void upHeap(); + void downHeap(); + +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/SearchHeader.cpp b/src/core/CLucene/search/SearchHeader.cpp new file mode 100644 index 00000000000..cae4a10850e --- /dev/null +++ b/src/core/CLucene/search/SearchHeader.cpp @@ -0,0 +1,232 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "SearchHeader.h" +#include "CLucene/document/Document.h" +#include "Similarity.h" +#include "BooleanQuery.h" +#include "Searchable.h" +#include "Hits.h" +#include "_FieldDocSortedHitQueue.h" +#include + +CL_NS_USE(index) +CL_NS_DEF(search) + +CL_NS(document)::Document* Searchable::doc(const int32_t i){ + CL_NS(document)::Document* ret = _CLNEW CL_NS(document)::Document; + if (!doc(i,ret) ) + _CLDELETE(ret); + return ret; +} + +//static +Query* Query::mergeBooleanQueries(CL_NS(util)::ArrayBase* queries) { + std::vector allClauses; + + CL_NS(util)::ValueArray clauses; + for (size_t i = 0; i < queries->length; i++) { + assert(BooleanQuery::getClassName() == queries->values[i]->getObjectName()); + BooleanQuery* booleanQuery = (BooleanQuery*)queries->values[i]; + clauses.resize((booleanQuery->getClauseCount())); + booleanQuery->getClauses(clauses.values); + for (size_t j = 0; j < clauses.length; j++) { + allClauses.push_back(clauses.values[j]->clone()); + } + } + + bool coordDisabled = ( queries->length == 0 ) ? false : ((BooleanQuery*)queries->values[0])->isCoordDisabled(); + BooleanQuery* result = _CLNEW BooleanQuery(coordDisabled); + std::vector::iterator i = allClauses.begin(); + while ( i != allClauses.end() ){ + result->add(*i); + i++; + } + return result; +} + +Query::Query(const Query& clone):boost(clone.boost){ +} +Weight* Query::_createWeight(Searcher* /*searcher*/){ + _CLTHROWA(CL_ERR_UnsupportedOperation,"UnsupportedOperationException: Query::_createWeight"); +} + +Query::Query(): + boost(1.0f) +{ +} +Query::~Query(){ +} + +const char* Query::getQueryName() const{ return getObjectName(); } +/** Expert: called to re-write queries into primitive queries. */ +Query* Query::rewrite(CL_NS(index)::IndexReader* /*reader*/){ + return this; +} + +Query* Query::combine(CL_NS(util)::ArrayBase* queries){ + std::vector uniques; + for (size_t i = 0; i < queries->length; i++) { + Query* query = queries->values[i]; + CL_NS(util)::ValueArray clauses; + // check if we can split the query into clauses + bool splittable = query->instanceOf(BooleanQuery::getClassName()); + if(splittable){ + BooleanQuery* bq = (BooleanQuery*) query; + splittable = bq->isCoordDisabled(); + clauses.resize(bq->getClauseCount()); + bq->getClauses(clauses.values); + for (size_t j = 0; splittable && j < clauses.length; j++) { + splittable = (clauses[j]->getOccur() == BooleanClause::SHOULD); + } + } + if(splittable){ + for (size_t j = 0; j < clauses.length; j++) { + uniques.push_back(clauses[j]->getQuery()); + } + } else { + uniques.push_back(query); + } + } + // optimization: if we have just one query, just return it + if(uniques.size() == 1){ + return *uniques.begin(); + } + std::vector::iterator it = uniques.begin(); + BooleanQuery* result = _CLNEW BooleanQuery(true); + while (it != uniques.end() ){ + result->add(*it, BooleanClause::SHOULD); + + it++; + } + return result; +} +Similarity* Query::getSimilarity(Searcher* searcher) { + return searcher->getSimilarity(); +} +TCHAR* Query::toString() const{ + return toString(LUCENE_BLANK_STRING); +} + +void Query::setBoost(float_t b) { boost = b; } + +float_t Query::getBoost() const { return boost; } + +Weight* Query::weight(Searcher* searcher){ + Query* query = searcher->rewrite(this); + Weight* weight = query->_createWeight(searcher); + // float_t sum = weight->sumOfSquaredWeights(); + // float_t norm = getSimilarity(searcher)->queryNorm(sum); + // weight->normalize(norm); + return weight; +} + +void Query::extractTerms( TermSet * termset ) const +{ + _CLTHROWA( CL_ERR_UnsupportedOperation,"UnsupportedOperationException: Query::extractTerms" ); +} + +TopFieldDocs::TopFieldDocs (int32_t totalHits, FieldDoc** fieldDocs, int32_t scoreDocsLen, SortField** fields): + TopDocs (totalHits, NULL, scoreDocsLen) +{ + this->fields = fields; + this->fieldDocs = fieldDocs; + this->scoreDocs = new ScoreDoc[scoreDocsLen]; + for (int32_t i=0;iscoreDocs[i] = this->fieldDocs[i]->scoreDoc; +} +TopFieldDocs::~TopFieldDocs(){ + if ( fieldDocs ){ + for (int32_t i=0;i= 0 +//Post - The instance has been created + +} + +TopDocs::~TopDocs(){ +//Func - Destructor +//Pre - true +//Post - The instance has been destroyed + + delete[] scoreDocs; +} + + + +Searcher::Searcher(){ + similarity = Similarity::getDefault(); +} +Searcher::~Searcher(){ +} + +Hits* Searcher::search(Query* query, size_t n) { + return _CLNEW Hits(this, query, (Filter*)NULL, (Sort*)NULL, n); +} + +Hits* Searcher::search(Query* query, Filter* filter) { + return _CLNEW Hits(this, query, filter); +} + +Hits* Searcher::search(Query* query, const Sort* sort, size_t n){ + return _CLNEW Hits(this, query, NULL, sort, n); +} + +Hits* Searcher::search(Query* query, Filter* filter, const Sort* sort){ + return _CLNEW Hits(this, query, filter, sort); +} + +void Searcher::_search(Query* query, HitCollector* results) { + _search(query, NULL, results); +} + +void Searcher::setSimilarity(Similarity* similarity) { + this->similarity = similarity; +} + +Similarity* Searcher::getSimilarity(){ + return this->similarity; +} + +const char* Searcher::getClassName(){ + return "Searcher"; +} + +const char* Searcher::getObjectName() const{ + return Searcher::getClassName(); +} + + +Weight::~Weight(){ +} + +TCHAR* Weight::toString(){ + return STRDUP_TtoT(_T("Weight")); +} + + +Searchable::~Searchable(){ +} + + +CL_NS_END diff --git a/src/core/CLucene/search/SearchHeader.h b/src/core/CLucene/search/SearchHeader.h new file mode 100644 index 00000000000..c7aa941ff66 --- /dev/null +++ b/src/core/CLucene/search/SearchHeader.h @@ -0,0 +1,152 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_SearchHeader_ +#define _lucene_search_SearchHeader_ + + +//#include "CLucene/index/IndexReader.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(index,IndexReader) +//#include "Filter.h" +CL_CLASS_DEF(document,Document) +CL_CLASS_DEF(util,Comparable) +//#include "Sort.h" +//#include "CLucene/util/VoidList.h" +//#include "Explanation.h" +//#include "Similarity.h" + +CL_NS_DEF(search) + + class Query; + class Scorer; + class Explanation; + class Hits; + class Sort; + class FieldDoc; + class TopFieldDocs; + + /** Expert: Returned by low-level search implementations. + * @see TopDocs */ + struct CLUCENE_EXPORT ScoreDoc { + /** Expert: A hit document's number. + * @see Searcher#doc(int32_t) + */ + int32_t doc; + + /** Expert: The score of this document for the query. */ + float_t score; + }; + + /** Expert: Returned by low-level search implementations. + * @see Searcher#search(Query,Filter,int32_t) */ + class CLUCENE_EXPORT TopDocs:LUCENE_BASE { + public: + /** Expert: The total number of hits for the query. + * @see Hits#length() + */ + int32_t totalHits; + + /** Expert: The top hits for the query. */ + ScoreDoc* scoreDocs; + int32_t scoreDocsLength; + + /** Expert: Constructs a TopDocs. TopDocs takes ownership of the ScoreDoc array*/ + TopDocs(const int32_t th, ScoreDoc* sds, int32_t scoreDocsLength); + virtual ~TopDocs(); + + private: + /** Expert: Stores the maximum score value encountered, needed for normalizing. */ + //float_t maxScore; + }; + + /** Lower-level search API. + *
HitCollectors are primarily meant to be used to implement queries, + * sorting and filtering. + * @see Searcher#search(Query,HitCollector) + */ + class CLUCENE_EXPORT HitCollector: LUCENE_BASE { + public: + /** Called once for every non-zero scoring document, with the document number + * and its score. + * + *

If, for example, an application wished to collect all of the hits for a + * query in a BitSet, then it might:

+      *   Searcher searcher = new IndexSearcher(indexReader);
+      *   final BitSet bits = new BitSet(indexReader.maxDoc());
+      *   searcher.search(query, new HitCollector() {
+      *       public void collect(int32_t doc, float score) {
+      *         bits.set(doc);
+      *       }
+      *     });
+      * 
+ * + *

Note: This is called in an inner search loop. For good search + * performance, implementations of this method should not call + * {@link Searcher#doc(int32_t)} or + * {@link IndexReader#document(int32_t)} on every + * document number encountered. Doing so can slow searches by an order + * of magnitude or more. + *

Note: The score passed to this method is a raw score. + * In other words, the score will not necessarily be a float whose value is + * between 0 and 1. + */ + virtual void collect(const int32_t doc, const float_t score) = 0; + virtual ~HitCollector(){} + }; + + /** Expert: Calculate query weights and build query scorers. + * + *

A Weight is constructed by a query, given a Searcher ({@link + * Query#_createWeight(Searcher)}). The {@link #sumOfSquaredWeights()} method + * is then called on the top-level query to compute the query normalization + * factor (@link Similarity#queryNorm(float_t)}). This factor is then passed to + * {@link #normalize(float_t)}. At this point the weighting is complete and a + * scorer may be constructed by calling {@link #scorer(IndexReader)}. + */ + class CLUCENE_EXPORT Weight + { + public: + virtual ~Weight(); + + /** The query that this concerns. */ + virtual Query* getQuery() = 0; + + /** The weight for this query. */ + virtual float_t getValue() = 0; + + /** The sum of squared weights of contained query clauses. */ + virtual float_t sumOfSquaredWeights() = 0; + + /** Assigns the query normalization factor to this. */ + virtual void normalize(float_t norm) = 0; + + /** Constructs a scorer for this. */ + virtual Scorer* scorer(CL_NS(index)::IndexReader* reader) = 0; + + /** An explanation of the score computation for the named document. */ + virtual Explanation* explain(CL_NS(index)::IndexReader* reader, int32_t doc) = 0; + + virtual TCHAR* toString(); + }; + + class CLUCENE_EXPORT HitDoc + { + public: + float_t score; + int32_t id; + CL_NS(document)::Document* doc; + + HitDoc* next; // in doubly-linked cache + HitDoc* prev; // in doubly-linked cache + + HitDoc(const float_t s, const int32_t i); + virtual ~HitDoc(); + }; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Searchable.h b/src/core/CLucene/search/Searchable.h new file mode 100644 index 00000000000..13905747070 --- /dev/null +++ b/src/core/CLucene/search/Searchable.h @@ -0,0 +1,182 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Searcher_ +#define _lucene_search_Searcher_ + + +//#include "CLucene/index/IndexReader.h" +CL_CLASS_DEF(index,Term) +//#include "Filter.h" +CL_CLASS_DEF(document,Document) +//#include "Sort.h" +//#include "CLucene/util/VoidList.h" +//#include "Explanation.h" +//#include "Similarity.h" + +CL_NS_DEF(search) + + //predefine classes + class Query; + class Filter; + class HitCollector; + class TopDocs; + class Explanation; + class Hits; + class Similarity; + class TopFieldDocs; + class Sort; + + + /** The interface for search implementations. + * + *

Implementations provide search over a single index, over multiple + * indices, and over indices on remote servers. + */ + class CLUCENE_EXPORT Searchable: LUCENE_BASE { + public: + virtual ~Searchable(); + + /** Lower-level search API. + * + *

{@link HitCollector#collect(int32_t,float_t)} is called for every non-zero + * scoring document. + * + *

Applications should only use this if they need all of the + * matching documents. The high-level search API ({@link + * Searcher#search(Query*)}) is usually more efficient, as it skips + * non-high-scoring hits. + * + * @param query to match documents + * @param filter if non-null, a bitset used to eliminate some documents + * @param results to receive hits + */ + virtual void _search(Query* query, Filter* filter, HitCollector* results) = 0; + + /** Frees resources associated with this Searcher. + * Be careful not to call this method while you are still using objects + * like {@link Hits}. + */ + virtual void close() = 0; + + /** Expert: Returns the number of documents containing term. + * Called by search code to compute term weights. + * @see IndexReader#docFreq(Term). + */ + virtual int32_t docFreq(const CL_NS(index)::Term* term) const = 0; + + /** Expert: Returns one greater than the largest possible document number. + * Called by search code to compute term weights. + * @see IndexReader#maxDoc(). + */ + virtual int32_t maxDoc() const = 0; + + /** Expert: Low-level search implementation. Finds the top n + * hits for query, applying filter if non-null. + * + *

Called by {@link Hits}. + * + *

Applications should usually call {@link Searcher#search(Query*)} or + * {@link Searcher#search(Query*,Filter*)} instead. + */ + virtual TopDocs* _search(Query* query, Filter* filter, const int32_t n) = 0; + + /** Expert: Returns the stored fields of document i. + * Called by {@link HitCollector} implementations. + * @see IndexReader#document(int32_t). + */ + virtual bool doc(int32_t i, CL_NS(document)::Document* d) = 0; + _CL_DEPRECATED( doc(i, document) ) CL_NS(document)::Document* doc(const int32_t i); + + /** Expert: called to re-write queries into primitive queries. */ + virtual Query* rewrite(Query* query) = 0; + + /** Returns an Explanation that describes how doc scored against + * query. + * + *

This is intended to be used in developing Similarity implementations, + * and, for good performance, should not be displayed with every hit. + * Computing an explanation is as expensive as executing the query over the + * entire index. + */ + virtual void explain(Query* query, int32_t doc, Explanation* ret) = 0; + + /** Expert: Low-level search implementation with arbitrary sorting. Finds + * the top n hits for query, applying + * filter if non-null, and sorting the hits by the criteria in + * sort. + * + *

Applications should usually call {@link + * Searcher#search(Query,Filter,Sort)} instead. + */ + virtual TopFieldDocs* _search(Query* query, Filter* filter, const int32_t n, const Sort* sort) = 0; + }; + + + + /** An abstract base class for search implementations. + * Implements some common utility methods. + */ + class CLUCENE_EXPORT Searcher:public Searchable { + private: + /** The Similarity implementation used by this searcher. */ + Similarity* similarity; + public: + Searcher(); + virtual ~Searcher(); + + // Returns the documents matching query. + Hits* search(Query* query, size_t n=0); + + // Returns the documents matching query and + // filter. + Hits* search(Query* query, Filter* filter); + + /** Returns documents matching query sorted by + * sort. + */ + Hits* search(Query* query, const Sort* sort, size_t n=0); + + /** Returns documents matching query and filter, + * sorted by sort. + */ + Hits* search(Query* query, Filter* filter, const Sort* sort); + + /** Lower-level search API. + * + *

{@link HitCollector#collect(int32_t ,float_t)} is called for every non-zero + * scoring document. + * + *

Applications should only use this if they need all of the + * matching documents. The high-level search API ({@link + * Searcher#search(Query*)}) is usually more efficient, as it skips + * non-high-scoring hits. + *

Note: The score passed to this method is a raw score. + * In other words, the score will not necessarily be a float whose value is + * between 0 and 1. + */ + void _search(Query* query, HitCollector* results); + + /** Expert: Set the Similarity implementation used by this Searcher. + * + * @see Similarity#setDefault(Similarity) + */ + void setSimilarity(Similarity* similarity); + + /** Expert: Return the Similarity implementation used by this Searcher. + * + *

This defaults to the current value of {@link Similarity#getDefault()}. + */ + Similarity* getSimilarity(); + + virtual const char* getObjectName() const; + static const char* getClassName(); + + virtual void _search(Query* query, Filter* filter, HitCollector* results) = 0; + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/Similarity.cpp b/src/core/CLucene/search/Similarity.cpp new file mode 100644 index 00000000000..69b402c4a33 --- /dev/null +++ b/src/core/CLucene/search/Similarity.cpp @@ -0,0 +1,243 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Similarity.h" + +#include "CLucene/index/Term.h" +#include "SearchHeader.h" +#include "Searchable.h" + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_USE(index) +CL_NS_DEF(search) + +#ifdef _CL_HAVE_NO_FLOAT_BYTE + #if defined(_LUCENE_PRAGMA_WARNINGS) + #pragma message ("==================Using fallback float<->byte encodings!!!==================") + #else + #warning "==================Using fallback float<->byte encodings!!!==================" + #endif + + //if the autoconf figured out that we can't do the conversions properly, then + //we fall back on the old, inaccurate way of doing things. + float_t NORM_TABLE[] = { + 0.0,5.820766E-10,6.9849193E-10,8.1490725E-10,9.313226E-10,1.1641532E-9,1.3969839E-9, + 1.6298145E-9,1.8626451E-9,2.3283064E-9,2.7939677E-9,3.259629E-9,3.7252903E-9, + 4.656613E-9,5.5879354E-9,6.519258E-9,7.4505806E-9,9.313226E-9,1.1175871E-8,1.3038516E-8, + 1.4901161E-8,1.8626451E-8,2.2351742E-8,2.6077032E-8,2.9802322E-8,3.7252903E-8,4.4703484E-8, + 5.2154064E-8,5.9604645E-8,7.4505806E-8,8.940697E-8,1.0430813E-7,1.1920929E-7,1.4901161E-7, + 1.7881393E-7,2.0861626E-7,2.3841858E-7,2.9802322E-7,3.5762787E-7,4.172325E-7,4.7683716E-7, + 5.9604645E-7,7.1525574E-7,8.34465E-7,9.536743E-7,1.1920929E-6,1.4305115E-6,1.66893E-6, + 1.9073486E-6,2.3841858E-6,2.861023E-6,3.33786E-6,3.8146973E-6,4.7683716E-6,5.722046E-6, + 6.67572E-6,7.6293945E-6,9.536743E-6,1.1444092E-5,1.335144E-5,1.5258789E-5,1.9073486E-5, + 2.2888184E-5,2.670288E-5,3.0517578E-5,3.8146973E-5,4.5776367E-5,5.340576E-5,6.1035156E-5, + 7.6293945E-5,9.1552734E-5,1.0681152E-4,1.2207031E-4,1.5258789E-4,1.8310547E-4,2.1362305E-4, + 2.4414062E-4,3.0517578E-4,3.6621094E-4,4.272461E-4,4.8828125E-4,6.1035156E-4,7.324219E-4, + 8.544922E-4,9.765625E-4,0.0012207031,0.0014648438,0.0017089844,0.001953125,0.0024414062, + 0.0029296875,0.0034179688,0.00390625,0.0048828125,0.005859375,0.0068359375, + 0.0078125,0.009765625,0.01171875,0.013671875,0.015625,0.01953125,0.0234375, + 0.02734375,0.03125,0.0390625,0.046875,0.0546875,0.0625,0.078125,0.09375,0.109375, + 0.125,0.15625,0.1875,0.21875,0.25,0.3125,0.375,0.4375,0.5,0.625,0.75, + 0.875,1.0,1.25,1.5,1.75,2,2.5,3,3.5,4.0,5.0,6.0,7.0,8.0,10.0,12.0,14.0,16.0,20.0,24.0,28.0,32.0,40.0,48.0,56.0, + 64.0,80.0,96.0,112.0,128.0,160.0,192.0,224.0,256.0,320.0,384.0,448.0,512.0,640.0,768.0,896.0,1024.0,1280.0,1536.0,1792.0, + 2048.0,2560.0,3072.0,3584.0,4096.0,5120.0,6144.0,7168.0,8192.0,10240.0,12288.0,14336.0,16384.0,20480.0,24576.0, + 28672.0,32768.0,40960.0,49152.0,57344.0,65536.0,81920.0,98304.0,114688.0,131072.0,163840.0,196608.0, + 229376.0,262144.0,327680.0,393216.0,458752.0,524288.0,655360.0,786432.0,917504.0,1048576.0,1310720.0, + 1572864.0,1835008.0,2097152.0,2621440.0,3145728.0,3670016.0,4194304.0,5242880.0,6291456.0,7340032.0, + 8388608.0,10485760.0,12582912.0,14680064.0,16777216.0,20971520.0,25165824.0,29360128.0,33554432.0, + 41943040.0,50331648.0,58720256.0,67108864.0,83886080.0,100663296.0,117440512.0,134217728.0, + 167772160.0,201326592.0,234881024.0,268435456.0,335544320.0,402653184.0,469762048.0,536870912.0, + 671088640.0,805306368.0,939524096.0,1073741824.0,1342177280.0,1610612736.0,1879048192.0, + 2147483648.0,2684354560.0,3221225472.0,3758096384.0,4294967296.0,5368709120.0,6442450944.0,7516192768.0 + }; + + float_t Similarity::byteToFloat(uint8_t b) { + return NORM_TABLE[b]; + } + + uint8_t Similarity::floatToByte(float_t f) { + return Similarity::encodeNorm(f); + } + +#else + + /** Cache of decoded bytes. */ + float_t NORM_TABLE[256]; + bool NORM_TABLE_initd=false; + + //float to bits conversion utilities... + union clvalue { + int32_t i; + float f; //must use a float type, else types dont match up + }; + + int32_t floatToIntBits(float_t value) + { + clvalue u; + int32_t e, f; + u.f = (float)value; + e = u.i & 0x7f800000; + f = u.i & 0x007fffff; + + if (e == 0x7f800000 && f != 0) + u.i = 0x7fc00000; + + return u.i; + } + + float_t intBitsToFloat(int32_t bits) + { + clvalue u; + u.i = bits; + return u.f; + } + + + float_t Similarity::byteToFloat(uint8_t b) { + if (b == 0) // zero is a special case + return 0.0f; + int32_t mantissa = b & 7; + int32_t exponent = (b >> 3) & 31; + int32_t bits = ((exponent+(63-15)) << 24) | (mantissa << 21); + return intBitsToFloat(bits); + } + + uint8_t Similarity::floatToByte(float_t f) { + if (f < 0.0f) // round negatives up to zero + f = 0.0f; + + if (f == 0.0f) // zero is a special case + return 0; + + int32_t bits = floatToIntBits(f); // parse float_t into parts + int32_t mantissa = (bits & 0xffffff) >> 21; + int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15; + + if (exponent > 31) { // overflow: use max value + exponent = 31; + mantissa = 7; + } + + if (exponent < 0) { // underflow: use min value + exponent = 0; + mantissa = 1; + } + + return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t + } +#endif + + /** The Similarity implementation used by default. */ + Similarity* Similarity_defaultImpl=NULL; + + void Similarity::setDefault(Similarity* similarity) { + _CLDELETE(Similarity_defaultImpl); + Similarity_defaultImpl = similarity; + } + + Similarity* Similarity::getDefault() { + if ( Similarity_defaultImpl == NULL ){ + Similarity_defaultImpl = _CLNEW DefaultSimilarity(); + } + return Similarity_defaultImpl; + } + void Similarity::_shutdown(){ + _CLDELETE(Similarity_defaultImpl); + } + + float_t Similarity::decodeNorm(uint8_t b) { +#ifndef _CL_HAVE_NO_FLOAT_BYTE + if ( !NORM_TABLE_initd ){ + for (int i = 0; i < 256; i++) + NORM_TABLE[i] = byteToFloat(i); + NORM_TABLE_initd=true; + } +#endif + return NORM_TABLE[b]; + } + + uint8_t Similarity::encodeNorm(float_t f) { +#ifdef _CL_HAVE_NO_FLOAT_BYTE + int32_t i=0; + if ( f <= 0 ) + return 0; + + while ( i<256 && f > NORM_TABLE[i] ){ + i++; + } + if ( i == 0 ) + return 0; + else if ( i == 255 && f>NORM_TABLE[255] ) + return 255; + else + return i; +#else + return floatToByte(f); +#endif + } + + + float_t Similarity::idf(Term* term, Searcher* searcher) { + return idf(searcher->docFreq(term), searcher->maxDoc()); + } + + + float_t Similarity::idf(CL_NS(util)::CLVector* terms, Searcher* searcher) { + float_t _idf = 0.0f; + for (CL_NS(util)::CLVector::iterator i = terms->begin(); i != terms->end(); i++ ) { + _idf += idf((Term*)*i, searcher); + } + return _idf; + } + + Similarity::~Similarity(){ + } + + + + + DefaultSimilarity::DefaultSimilarity(){ + } + DefaultSimilarity::~DefaultSimilarity(){ + } + + float_t DefaultSimilarity::lengthNorm(const TCHAR* /*fieldName*/, int32_t numTerms) { + if ( numTerms == 0 ) //prevent div by zero + return 0; + return (1.0 / sqrt((float_t)numTerms)); + } + + float_t DefaultSimilarity::queryNorm(float_t sumOfSquaredWeights) { + if ( sumOfSquaredWeights == 0 ) //prevent div by zero + return 0.0f; + return (float_t)(1.0 / sqrt(sumOfSquaredWeights)); + } + + float_t DefaultSimilarity::tf(float_t freq) { + return sqrt(freq); + } + + float_t DefaultSimilarity::sloppyFreq(int32_t distance) { + return 1.0f / (distance + 1); + } + + float_t DefaultSimilarity::idf(int32_t docFreq, int32_t numDocs) { + return (float_t)(log(numDocs/(float_t)(docFreq+1)) + 1.0); + } + + float_t DefaultSimilarity::coord(int32_t overlap, int32_t maxOverlap) { + if ( maxOverlap == 0 ) + return 0.0f; + return overlap / (float_t)maxOverlap; + } +CL_NS_END diff --git a/src/core/CLucene/search/Similarity.h b/src/core/CLucene/search/Similarity.h new file mode 100644 index 00000000000..388898aba23 --- /dev/null +++ b/src/core/CLucene/search/Similarity.h @@ -0,0 +1,279 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Similarity_ +#define _lucene_search_Similarity_ + +#include "CLucene/util/VoidList.h" +CL_CLASS_DEF(index,Term) + +CL_NS_DEF(search) + +class Searcher; +class DefaultSimilarity; + +/** Expert: Scoring API. +*

Subclasses implement search scoring. +* +*

The score of query q for document d is defined +* in terms of these methods as follows: +* +* +* +* +* +* +* +* +* +* +* +*
score(q,d) =
+* Σ +* {@link #tf(int32_t) tf}(t in d) * +* {@link #idf(Term,Searcher) idf}(t) * +* {@link Field#getBoost getBoost}(t.field in d) * +* {@link #lengthNorm(TCHAR*,int32_t) lengthNorm}(t.field in d) +*  * +* {@link #coord(int32_t,int32_t) coord}(q,d) * +* {@link #queryNorm(float_t) queryNorm}(q) +*
+* t in q +*
+* +* @see #setDefault(Similarity) +* @see IndexWriter#setSimilarity(Similarity) +* @see Searcher#setSimilarity(Similarity) +*/ +class CLUCENE_EXPORT Similarity:LUCENE_BASE { +public: + virtual ~Similarity(); + + /** Set the default Similarity implementation used by indexing and search + * code. + * + * @see Searcher#setSimilarity(Similarity) + * @see IndexWriter#setSimilarity(Similarity) + */ + static void setDefault(Similarity* similarity); + + /** Return the default Similarity implementation used by indexing and search + * code. + * + *

This is initially an instance of {@link DefaultSimilarity}. + * + * @see Searcher#setSimilarity(Similarity) + * @see IndexWriter#setSimilarity(Similarity) + */ + static Similarity* getDefault(); + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); + + /** Encodes a normalization factor for storage in an index. + * + *

The encoding uses a five-bit exponent and three-bit mantissa, thus + * representing values from around 7x10^9 to 2x10^-9 with about one + * significant decimal digit of accuracy. Zero is also represented. + * Negative numbers are rounded up to zero. Values too large to represent + * are rounded down to the largest representable value. Positive values too + * small to represent are rounded up to the smallest positive representable + * value. + * + * @see Field#setBoost(float_t) + */ + static uint8_t encodeNorm(float_t f); + + /** Decodes a normalization factor stored in an index. + * @see #encodeNorm(float_t) + */ + static float_t decodeNorm(uint8_t b); + + static uint8_t floatToByte(float_t f); + static float_t byteToFloat(uint8_t b); + + /** Computes a score factor for a phrase. + * + *

The default implementation sums the {@link #idf(Term,Searcher)} factor + * for each term in the phrase. + * + * @param terms the terms in the phrase + * @param searcher the document collection being searched + * @return a score factor for the phrase + */ + float_t idf(CL_NS(util)::CLVector* terms, Searcher* searcher); + + template + float_t idf( TermIterator first, TermIterator last, Searcher* searcher ) + { + float_t _idf = 0.0f; + for( ; first != last; first++ ) { + _idf += idf(*first, searcher); + } + return _idf; + } + + //float_t idf(Term** terms, Searcher* searcher); + + + /** Computes a score factor for a simple term. + * + *

The default implementation is:

+   *   return idf(searcher.docFreq(term), searcher.maxDoc());
+   * 
+ * + * Note that {@link Searcher#maxDoc()} is used instead of + * {@link IndexReader#numDocs()} because it is proportional to + * {@link Searcher#docFreq(Term)} , i.e., when one is inaccurate, + * so is the other, and in the same direction. + * + * @param term the term in question + * @param searcher the document collection being searched + * @return a score factor for the term + */ + float_t idf(CL_NS(index)::Term* term, Searcher* searcher); + + + /** Computes a score factor based on a term or phrase's frequency in a + * document. This value is multiplied by the {@link #idf(Term, Searcher)} + * factor for each term in the query and these products are then summed to + * form the initial score for a document. + * + *

Terms and phrases repeated in a document indicate the topic of the + * document, so implementations of this method usually return larger values + * when freq is large, and smaller values when freq + * is small. + * + *

The default implementation calls {@link #tf(float_t)}. + * + * @param freq the frequency of a term within a document + * @return a score factor based on a term's within-document frequency + */ + inline float_t tf(int32_t freq){ return tf((float_t)freq); } + + /** Computes the normalization value for a field given the total number of + * terms contained in a field. These values, together with field boosts, are + * stored in an index and multipled into scores for hits on each field by the + * search code. + * + *

Matches in longer fields are less precise, so implemenations of this + * method usually return smaller values when numTokens is large, + * and larger values when numTokens is small. + * + *

That these values are computed under {@link + * IndexWriter#addDocument(Document)} and stored then using + * {#encodeNorm(float_t)}. Thus they have limited precision, and documents + * must be re-indexed if this method is altered. + * + * @param fieldName the name of the field + * @param numTokens the total number of tokens contained in fields named + * fieldName of doc. + * @return a normalization factor for hits on this field of this document + * + * @see Field#setBoost(float_t) + */ + virtual float_t lengthNorm(const TCHAR* fieldName, int32_t numTokens) = 0; + + /** Computes the normalization value for a query given the sum of the squared + * weights of each of the query terms. This value is then multipled into the + * weight of each query term. + * + *

This does not affect ranking, but rather just attempts to make scores + * from different queries comparable. + * + * @param sumOfSquaredWeights the sum of the squares of query term weights + * @return a normalization factor for query weights + */ + virtual float_t queryNorm(float_t sumOfSquaredWeights) = 0; + + /** Computes the amount of a sloppy phrase match, based on an edit distance. + * This value is summed for each sloppy phrase match in a document to form + * the frequency that is passed to {@link #tf(float_t)}. + * + *

A phrase match with a small edit distance to a document passage more + * closely matches the document, so implementations of this method usually + * return larger values when the edit distance is small and smaller values + * when it is large. + * + * @see PhraseQuery#setSlop(int32_t) + * @param distance the edit distance of this sloppy phrase match + * @return the frequency increment for this match + */ + virtual float_t sloppyFreq(int32_t distance) = 0; + + /** Computes a score factor based on a term or phrase's frequency in a + * document. This value is multiplied by the {@link #idf(Term, Searcher)} + * factor for each term in the query and these products are then summed to + * form the initial score for a document. + * + *

Terms and phrases repeated in a document indicate the topic of the + * document, so implemenations of this method usually return larger values + * when freq is large, and smaller values when freq + * is small. + * + * @param freq the frequency of a term within a document + * @return a score factor based on a term's within-document frequency + */ + virtual float_t tf(float_t freq) = 0; + + /** Computes a score factor based on a term's document frequency (the number + * of documents which contain the term). This value is multiplied by the + * {@link #tf(int32_t)} factor for each term in the query and these products are + * then summed to form the initial score for a document. + * + *

Terms that occur in fewer documents are better indicators of topic, so + * implemenations of this method usually return larger values for rare terms, + * and smaller values for common terms. + * + * @param docFreq the number of documents which contain the term + * @param numDocs the total number of documents in the collection + * @return a score factor based on the term's document frequency + */ + virtual float_t idf(int32_t docFreq, int32_t numDocs) = 0; + + /** Computes a score factor based on the fraction of all query terms that a + * document contains. This value is multiplied into scores. + * + *

The presence of a large portion of the query terms indicates a better + * match with the query, so implemenations of this method usually return + * larger values when the ratio between these parameters is large and smaller + * values when the ratio between them is small. + * + * @param overlap the number of query terms matched in the document + * @param maxOverlap the total number of terms in the query + * @return a score factor based on term overlap with the query + */ + virtual float_t coord(int32_t overlap, int32_t maxOverlap) = 0; +}; + + +/** Expert: Default scoring implementation. */ +class CLUCENE_EXPORT DefaultSimilarity: public Similarity { +public: + DefaultSimilarity(); + ~DefaultSimilarity(); + + /** Implemented as 1/sqrt(numTerms). */ + float_t lengthNorm(const TCHAR* fieldName, int32_t numTerms); + + /** Implemented as 1/sqrt(sumOfSquaredWeights). */ + float_t queryNorm(float_t sumOfSquaredWeights); + + /** Implemented as sqrt(freq). */ + inline float_t tf(float_t freq); + + /** Implemented as 1 / (distance + 1). */ + float_t sloppyFreq(int32_t distance); + + /** Implemented as log(numDocs/(docFreq+1)) + 1. */ + float_t idf(int32_t docFreq, int32_t numDocs); + + /** Implemented as overlap / maxOverlap. */ + float_t coord(int32_t overlap, int32_t maxOverlap); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/SloppyPhraseScorer.cpp b/src/core/CLucene/search/SloppyPhraseScorer.cpp new file mode 100644 index 00000000000..be9d38c011e --- /dev/null +++ b/src/core/CLucene/search/SloppyPhraseScorer.cpp @@ -0,0 +1,175 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Scorer.h" +#include "CLucene/index/Terms.h" +#include "SearchHeader.h" +#include "_PhrasePositions.h" +#include "_SloppyPhraseScorer.h" +#include "Similarity.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + + SloppyPhraseScorer::SloppyPhraseScorer(Weight* _weight, TermPositions** tps, int32_t* offsets, + Similarity* similarity, int32_t _slop, uint8_t* norms): + PhraseScorer(_weight,tps,offsets,similarity,norms),slop(_slop),repeats(NULL),repeatsLen(0){ + //Func - Constructor + //Pre - tps != NULL + // tpsLength >= 0 + // n != NULL + //Post - Instance has been created + + CND_PRECONDITION(tps != NULL, "tps is NULL"); + } + + SloppyPhraseScorer::~SloppyPhraseScorer(){ + _CLDELETE_LARRAY(repeats); + } + + float_t SloppyPhraseScorer::phraseFreq() { + + CND_PRECONDITION(first != NULL,"first is NULL"); + CND_PRECONDITION(last != NULL,"last is NULL"); + CND_PRECONDITION(pq != NULL,"pq is NULL"); + + int32_t end = initPhrasePositions(); + float_t freq = 0.0f; + bool done = (end<0); + + while (!done) { + PhrasePositions* pp = pq->pop(); + int32_t start = pp->position; + int32_t next = pq->top()->position; + + bool tpsDiffer = true; + for (int32_t pos = start; pos <= next || !tpsDiffer; pos = pp->position) { + if (pos<=next && tpsDiffer) + start = pos; // advance pp to min window + if (!pp->nextPosition()) { + done = true; // ran out of a term -- done + break; + } + tpsDiffer = !pp->repeats || termPositionsDiffer(pp); + } + + const int32_t matchLength = end - start; + if (matchLength <= slop) + freq += getSimilarity()->sloppyFreq(matchLength); // score match + + if (pp->position > end) + end = pp->position; + pq->put(pp); // restore pq + + } + return freq; + } + + int32_t SloppyPhraseScorer::initPhrasePositions() { + int32_t end = 0; + PhrasePositions* pp = NULL; // used in order to solve msvc6 scope issues + + // no repeats at all (most common case is also the simplest one) + if (checkedRepeats && repeats==NULL) { + // build queue from list + pq->clear(); + for (pp = first; pp != NULL; pp = pp->_next) { + pp->firstPosition(); + if (pp->position > end) + end = pp->position; + pq->put(pp); // build pq from list + } + return end; + } + + // position the pp's + for (pp = first; pp != NULL; pp = pp->_next) + pp->firstPosition(); + + // one time initializatin for this scorer + if (!checkedRepeats) { + checkedRepeats = true; + // check for repeats + // TODO: is this correct, filtering clones using CLHashMap??? + PhrasePositionsMap* m = NULL; + for (pp = first; pp != NULL; pp = pp->_next) { + int32_t tpPos = pp->position + pp->offset; + for (PhrasePositions* pp2 = pp->_next; pp2 != NULL; pp2 = pp2->_next) { + int32_t tpPos2 = pp2->position + pp2->offset; + if (tpPos2 == tpPos) { + if (m == NULL) + m = new PhrasePositionsMap(false,false); + pp->repeats = true; + pp2->repeats = true; + m->put(pp,NULL); + m->put(pp2,NULL); + } + } + } + if (m!=NULL) { + repeatsLen = m->size(); + repeats = _CL_NEWARRAY(PhrasePositions*, repeatsLen + 1); + PhrasePositionsMap::iterator itr = m->begin(); + size_t pos = 0; + while ( itr!=m->end() ){ + repeats[pos] = itr->first; + ++itr; + ++pos; + } + repeats[repeatsLen + 1] = NULL; // NULL terminate the array + } + delete m; + } + + // with repeats must advance some repeating pp's so they all start with differing tp's + if (repeats!=NULL) { + // must propagate higher offsets first (otherwise might miss matches). + qsort(repeats, repeatsLen, sizeof(PhrasePositions*), comparePhrasePositions); + // now advance them + for (size_t i = 0; i < repeatsLen; i++) { + PhrasePositions* pp = repeats[i]; + while (!termPositionsDiffer(pp)) { + if (!pp->nextPosition()) + return -1; // ran out of a term -- done + } + } + } + + // build queue from list + pq->clear(); + for (pp = first; pp != NULL; pp = pp->_next) { + if (pp->position > end) + end = pp->position; + pq->put(pp); // build pq from list + } + + return end; + } + + // disalow two pp's to have the same tp position, so that same word twice + // in query would go elswhere in the matched doc + bool SloppyPhraseScorer::termPositionsDiffer(PhrasePositions* pp) { + // efficiency note: a more efficient implemention could keep a map between repeating + // pp's, so that if pp1a, pp1b, pp1c are repeats term1, and pp2a, pp2b are repeats + // of term2, pp2a would only be checked against pp2b but not against pp1a, pp1b, pp1c. + // However this would complicate code, for a rather rare case, so choice is to compromise here. + const int32_t tpPos = pp->position + pp->offset; + for (size_t i = 0; i < repeatsLen; i++) { + PhrasePositions* pp2 = repeats[i]; + if (pp2 == pp) + continue; + const int32_t tpPos2 = pp2->position + pp2->offset; + if (tpPos2 == tpPos) + return false; + } + return true; + } + + TCHAR* SloppyPhraseScorer::toString(){ + return stringDuplicate(_T("SloppyPhraseScorer")); + } +CL_NS_END diff --git a/src/core/CLucene/search/Sort.cpp b/src/core/CLucene/search/Sort.cpp new file mode 100644 index 00000000000..03e0af56d6d --- /dev/null +++ b/src/core/CLucene/search/Sort.cpp @@ -0,0 +1,340 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Sort.h" +#include "Compare.h" +#include "SearchHeader.h" +#include "CLucene/util/_StringIntern.h" +#include "CLucene/util/StringBuffer.h" + +CL_NS_USE(util) +CL_NS_DEF(search) + + + SortField* SortField_FIELD_SCORE = NULL; + SortField* SortField_FIELD_DOC = NULL; + SortField* SortField::FIELD_SCORE(){ + if ( SortField_FIELD_SCORE == NULL ) + SortField_FIELD_SCORE = _CLNEW SortField (NULL, DOCSCORE,false); + return SortField_FIELD_SCORE; + } + SortField* SortField::FIELD_DOC(){ + if ( SortField_FIELD_DOC == NULL ) + SortField_FIELD_DOC = _CLNEW SortField (NULL, DOC,false); + return SortField_FIELD_DOC; + } + void SortField::_shutdown(){ + _CLDELETE(SortField_FIELD_SCORE); + _CLDELETE(SortField_FIELD_DOC); + } + + Sort* Sort_RELEVANCE = NULL; + Sort* Sort_INDEXORDER = NULL; + Sort* Sort::RELEVANCE(){ + if ( Sort_RELEVANCE == NULL ) + Sort_RELEVANCE = _CLNEW Sort(); + return Sort_RELEVANCE; + } + Sort* Sort::INDEXORDER(){ + if ( Sort_INDEXORDER == NULL ) + Sort_INDEXORDER = _CLNEW Sort (SortField::FIELD_DOC()); + return Sort_INDEXORDER; + } + void Sort::_shutdown(){ + _CLDELETE(Sort_RELEVANCE); + _CLDELETE(Sort_INDEXORDER); + } + + ScoreDocComparator* ScoreDocComparator_INDEXORDER = NULL; + ScoreDocComparator* ScoreDocComparator_RELEVANCE = NULL; + ScoreDocComparator* ScoreDocComparator::INDEXORDER(){ + if ( ScoreDocComparator_INDEXORDER == NULL ) + ScoreDocComparator_INDEXORDER = _CLNEW ScoreDocComparators::IndexOrder; + return ScoreDocComparator_INDEXORDER; + } + ScoreDocComparator* ScoreDocComparator::RELEVANCE(){ + if ( ScoreDocComparator_RELEVANCE == NULL ) + ScoreDocComparator_RELEVANCE = _CLNEW ScoreDocComparators::Relevance; + return ScoreDocComparator_RELEVANCE; + } + void ScoreDocComparator::_shutdown(){ + _CLDELETE(ScoreDocComparator_INDEXORDER); + _CLDELETE(ScoreDocComparator_RELEVANCE); + } + + + + SortField::SortField (const TCHAR* field) { + this->type = AUTO; + this->reverse = false; + this->field = CLStringIntern::intern(field); + this->factory = NULL; + } + + SortField::SortField (const TCHAR* field, int32_t type, bool reverse) { + this->field = (field != NULL) ? CLStringIntern::intern(field) : field; + this->type = type; + this->reverse = reverse; + this->factory = NULL; + } + + SortField::SortField(const SortField& clone){ + this->field = (clone.field != NULL) ? CLStringIntern::intern(clone.field) : clone.field; + this->type = clone.type; + this->reverse = clone.reverse; + this->factory = clone.factory; + } + SortField* SortField::clone() const{ + return _CLNEW SortField(*this); + } + + const TCHAR* SortField::getField() const { + return field; + } + int32_t SortField::getType() const { + return type; + } + bool SortField::getReverse() const { + return reverse; + } + SortComparatorSource* SortField::getFactory() const { + return factory; + } + + /** Creates a sort by terms in the given field sorted + * according to the given locale. + * @param field Name of field to sort by, cannot be null. + * @param locale Locale of values in the field. + */ + /*SortField::SortField (TCHAR* field, Locale* locale) { + this->field = (field != NULL) ? CLStringIntern::intern(field): field; + this->type = STRING; + this->locale = locale; + }*/ + + /** Creates a sort, possibly in reverse, by terms in the given field sorted + * according to the given locale. + * @param field Name of field to sort by, cannot be null. + * @param locale Locale of values in the field. + */ + /*SortField::SortField (TCHAR* field, Locale* locale, bool reverse) { + this->field = (field != NULL) ? CLStringIntern::intern(field): field; + this->type = STRING; + this->locale = locale; + this->reverse = reverse; + }*/ + + + SortField::SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse) { + this->field = (field != NULL) ? CLStringIntern::intern(field): field; + this->type = CUSTOM; + this->reverse = reverse; + this->factory = comparator; + } + + SortField::~SortField(){ + CLStringIntern::unintern(field); + } + + TCHAR* SortField::toString() const { + CL_NS(util)::StringBuffer buffer; + switch (type) { + case DOCSCORE: + buffer.append(_T("")); + break; + + case DOC: + buffer.append(_T("")); + break; + + case CUSTOM: + buffer.append (_T("getName()); + buffer.append(_T(">")); + break; + + default: + buffer.append( _T("\"")); + buffer.append( field ); + buffer.append( _T("\"") ); + break; + } + + //if (locale != null) buffer.append ("("+locale+")"); todo: + if (reverse) buffer.appendChar('!'); + + return buffer.toString(); + } + + + + + + + + + + + + + Sort::Sort() { + fields=NULL; + SortField** fields=_CL_NEWARRAY(SortField*,3); + fields[0]=SortField::FIELD_SCORE(); + fields[1]=SortField::FIELD_DOC(); + fields[2]=NULL; + setSort (fields); + _CLDELETE_ARRAY(fields); + } + + Sort::~Sort(){ + clear(); + } + void Sort::clear(){ + if ( fields != NULL ){ + int32_t i=0; + while ( fields[i] != NULL ){ + if ( fields[i] != SortField::FIELD_SCORE() && + fields[i] != SortField::FIELD_DOC() ){ + _CLDELETE(fields[i]); + } + i++; + } + _CLDELETE_ARRAY(fields); + } + } + + Sort::Sort (const TCHAR* field, bool reverse) { + this->fields=NULL; + setSort (field, reverse); + } + + Sort::Sort (const TCHAR** fields) { + this->fields=NULL; + setSort (fields); + } + Sort::Sort (SortField* field) { + this->fields=NULL; + setSort (field); + } + + Sort::Sort (SortField** fields) { + this->fields=NULL; + setSort (fields); + } + + void Sort::setSort (const TCHAR* field, bool reverse) { + clear(); + fields = _CL_NEWARRAY(SortField*,3); + fields[0] = _CLNEW SortField (field, SortField::AUTO, reverse); + fields[1] = SortField::FIELD_DOC(); + fields[2] = NULL; + } + + void Sort::setSort (const TCHAR** fieldnames) { + clear(); + + int32_t n = 0; + while ( fieldnames[n] != NULL ) + n++; + + fields = _CL_NEWARRAY(SortField*,n+1); + for (int32_t i = 0; i < n; ++i) { + fields[i] = _CLNEW SortField (fieldnames[i], SortField::AUTO,false); + } + fields[n]=NULL; + } + + + void Sort::setSort (SortField* field) { + clear(); + + this->fields = _CL_NEWARRAY(SortField*,2); + this->fields[0] = field; + this->fields[1] = NULL; + } + + void Sort::setSort (SortField** fields) { + clear(); + + int n=0; + while ( fields[n] != NULL ) + n++; + this->fields = _CL_NEWARRAY(SortField*,n+1); + for (int i=0;ifields[i]=fields[i]; + } + + TCHAR* Sort::toString() const { + CL_NS(util)::StringBuffer buffer; + + int32_t i = 0; + while ( fields[i] != NULL ){ + if (i>0) + buffer.appendChar(','); + + TCHAR* p = fields[i]->toString(); + buffer.append(p); + _CLDELETE_CARRAY(p); + + i++; + } + + return buffer.toString(); + } + + + + + + + ScoreDocComparator::~ScoreDocComparator(){ + } + + +class ScoreDocComparatorImpl: public ScoreDocComparator{ + Comparable** cachedValues; + FieldCacheAuto* fca; + int32_t cachedValuesLen; +public: + ScoreDocComparatorImpl(FieldCacheAuto* fca){ + this->fca = fca; + if ( fca->contentType != FieldCacheAuto::COMPARABLE_ARRAY ) + _CLTHROWA(CL_ERR_InvalidCast,"Invalid field cache auto type"); + this->cachedValues = fca->comparableArray; + this->cachedValuesLen = fca->contentLen; + } + ~ScoreDocComparatorImpl(){ + } + int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j){ + CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range") + CND_PRECONDITION(j->doc >= 0 && j->doc < cachedValuesLen, "j->doc out of range") + return cachedValues[i->doc]->compareTo (cachedValues[j->doc]); + } + + CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i){ + CND_PRECONDITION(i->doc >= 0 && i->doc < cachedValuesLen, "i->doc out of range") + return cachedValues[i->doc]; + } + + int32_t sortType(){ + return SortField::CUSTOM; + } +}; + +ScoreDocComparator* SortComparator::newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname){ + return _CLNEW ScoreDocComparatorImpl(FieldCache::DEFAULT()->getCustom (reader, fieldname, this)); +} +SortComparator::SortComparator(){ +} +SortComparator::~SortComparator(){ +} + + +CL_NS_END diff --git a/src/core/CLucene/search/Sort.h b/src/core/CLucene/search/Sort.h new file mode 100644 index 00000000000..e917293bf4c --- /dev/null +++ b/src/core/CLucene/search/Sort.h @@ -0,0 +1,426 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_Sort_ +#define _lucene_search_Sort_ + + +//#include "CLucene/index/IndexReader.h" +//#include "SearchHeader.h" +//#include "CLucene/util/Equator.h" +CL_CLASS_DEF(index,IndexReader) +CL_CLASS_DEF(util,Comparable) + +CL_NS_DEF(search) + +//predefine + class SortField; + class Sort; + +/** + * Expert: Compares two ScoreDoc objects for sorting. + * + */ + class CLUCENE_EXPORT ScoreDocComparator { + protected: + ScoreDocComparator(){} + public: + virtual ~ScoreDocComparator(); + + /** + * Compares two ScoreDoc objects and returns a result indicating their + * sort order. + * @param i First ScoreDoc + * @param j Second ScoreDoc + * @return a negative integer if i should come before j
+ * a positive integer if i should come after j
+ * 0 if they are equal + * @see java.util.Comparator + */ + virtual int32_t compare (struct ScoreDoc* i, struct ScoreDoc* j) = 0; + + /** + * Returns the value used to sort the given document. The + * object returned must implement the java.io.Serializable + * interface. This is used by multisearchers to determine how + * to collate results from their searchers. + * @see FieldDoc + * @param i Document + * @return Serializable object + */ + virtual CL_NS(util)::Comparable* sortValue (struct ScoreDoc* i) = 0; + + + /** + * Returns the type of sort. Should return SortField.SCORE, + * SortField.DOC, SortField.STRING, + * SortField.INTEGER, SortField.FLOAT or + * SortField.CUSTOM. It is not valid to return + * SortField.AUTO. + * This is used by multisearchers to determine how to collate results + * from their searchers. + * @return One of the constants in SortField. + * @see SortField + */ + virtual int32_t sortType() = 0; + + /** Special comparator for sorting hits according to computed relevance (document score). */ + static ScoreDocComparator* RELEVANCE(); + + /** Special comparator for sorting hits according to index order (document number). */ + static ScoreDocComparator* INDEXORDER(); + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); + }; + +/** + * Expert: returns a comparator for sorting ScoreDocs. + * + */ +class CLUCENE_EXPORT SortComparatorSource:LUCENE_BASE { +public: + virtual ~SortComparatorSource(){ + } + + /** + * return a reference to a string describing the name of the comparator + * this is used in the explanation + */ + virtual TCHAR* getName() = 0; + + virtual size_t hashCode() = 0; + + /** + * Creates a comparator for the field in the given index. + * @param reader Index to create comparator for. + * @param fieldname Name of the field to create comparator for. + * @return Comparator of ScoreDoc objects. + * @throws IOException If an error occurs reading the index. + */ + virtual ScoreDocComparator* newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname) = 0; +}; + + +/** + * Abstract base class for sorting hits returned by a Query. + * + *

This class should only be used if the other SortField + * types (SCORE, DOC, STRING, INT, FLOAT) do not provide an + * adequate sorting. It maintains an internal cache of values which + * could be quite large. The cache is an array of Comparable, + * one for each document in the index. There is a distinct + * Comparable for each unique term in the field - if + * some documents have the same term in the field, the cache + * array will have entries which reference the same Comparable. + * + */ +class CLUCENE_EXPORT SortComparator: public SortComparatorSource { +public: + virtual ScoreDocComparator* newComparator (CL_NS(index)::IndexReader* reader, const TCHAR* fieldname); + + SortComparator(); + virtual ~SortComparator(); + + /** + * Returns an object which, when sorted according to natural order, + * will order the Term values in the correct order. + *

For example, if the Terms contained integer values, this method + * would return new Integer(termtext). Note that this + * might not always be the most efficient implementation - for this + * particular example, a better implementation might be to make a + * ScoreDocLookupComparator that uses an internal lookup table of int. + * @param termtext The textual value of the term. + * @return An object representing termtext that sorts + * according to the natural order of termtext. + * @see Comparable + * @see ScoreDocComparator + */ + virtual CL_NS(util)::Comparable* getComparable (const TCHAR* termtext) = 0; + +}; + + +/** + * Stores information about how to sort documents by terms in an individual + * field. Fields must be indexed in order to sort by them. + * + */ +class CLUCENE_EXPORT SortField:LUCENE_BASE { +private: + const TCHAR* field; + int32_t type; // defaults to determining type dynamically + //Locale* locale; // defaults to "natural order" (no Locale) + bool reverse; // defaults to natural order + SortComparatorSource* factory; + +protected: + SortField (const SortField& clone); +public: + virtual ~SortField(); + + /** Sort by document score (relevancy). Sort values are Float and higher + * values are at the front. + * PORTING: this is the same as SCORE in java, it had to be renamed because + * SCORE is a system macro on some platforms (AIX). + */ + LUCENE_STATIC_CONSTANT(int32_t, DOCSCORE=0); + + /** Sort by document number (index order). Sort values are Integer and lower + * values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, DOC=1); + + /** Guess type of sort based on field contents. A regular expression is used + * to look at the first term indexed for the field and determine if it + * represents an integer number, a floating point number, or just arbitrary + * string characters. */ + LUCENE_STATIC_CONSTANT(int32_t, AUTO=2); + + /** Sort using term values as Strings. Sort values are String and lower + * values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, STRING=3); + + /** Sort using term values as encoded Integers. Sort values are Integer and + * lower values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, INT=4); + + /** Sort using term values as encoded Floats. Sort values are Float and + * lower values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, FLOAT=5); + + /** Sort using term values as encoded Longs. Sort values are Long and + * lower values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, LONG=6); + + /** Sort using term values as encoded Doubles. Sort values are Double and + * lower values are at the front. */ + LUCENE_STATIC_CONSTANT(int32_t, DOUBLE=7); + + + /** Sort using a custom Comparator. Sort values are any Comparable and + * sorting is done according to natural order. */ + LUCENE_STATIC_CONSTANT(int32_t, CUSTOM=9); + + // IMPLEMENTATION NOTE: the FieldCache.STRING_INDEX is in the same "namespace" + // as the above static int values. Any new values must not have the same value + // as FieldCache.STRING_INDEX. + + /** Represents sorting by document score (relevancy). */ + static SortField* FIELD_SCORE(); + + /** Represents sorting by document number (index order). */ + static SortField* FIELD_DOC(); + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); + + /** Creates a sort by terms in the given field where the type of term value + * is determined dynamically ({@link #AUTO AUTO}). + * @param field Name of field to sort by, cannot be null. + */ + SortField (const TCHAR* field); + //SortField (const TCHAR* field, bool reverse); + //todo: we cannot make reverse use default field of =false. + //because bool and int are the same type in c, overloading is not possible + + /** Creates a sort, possibly in reverse, by terms in the given field with the + * type of term values explicitly given. + * @param field Name of field to sort by. Can be null if + * type is SCORE or DOC. + * @param type Type of values in the terms. + * @param reverse True if natural order should be reversed (default=false). + */ + SortField (const TCHAR* field, int32_t type, bool reverse); + + /* + SortField (TCHAR* field, Locale* locale) { + SortField (TCHAR* field, Locale* locale, bool reverse);*/ + + /** Creates a sort, possibly in reverse, with a custom comparison function. + * @param field Name of field to sort by; cannot be null. + * @param comparator Returns a comparator for sorting hits. + * @param reverse True if natural order should be reversed (default=false). + */ + SortField (const TCHAR* field, SortComparatorSource* comparator, bool reverse=false); + + /** Returns the name of the field. Could return null + * if the sort is by SCORE or DOC. + * @return Name of field, possibly null. + */ + const TCHAR* getField() const; + + SortField* clone() const; + + /** Returns the type of contents in the field. + * @return One of the constants SCORE, DOC, AUTO, STRING, INT or FLOAT. + */ + int32_t getType() const; + + /** Returns the Locale by which term values are interpreted. + * May return null if no Locale was specified. + * @return Locale, or null. + */ + /*Locale getLocale() { + return locale; + }*/ + + /** Returns whether the sort should be reversed. + * @return True if natural order should be reversed. + */ + bool getReverse() const; + + SortComparatorSource* getFactory() const; + + TCHAR* toString() const; +}; + + + +/** + * Encapsulates sort criteria for returned hits. + * + *

The fields used to determine sort order must be carefully chosen. + * Documents must contain a single term in such a field, + * and the value of the term should indicate the document's relative position in + * a given sort order. The field must be indexed, but should not be tokenized, + * and does not need to be stored (unless you happen to want it back with the + * rest of your document data). In other words: + * + *

document.add (new Field ("byNumber", Integer.toString(x), false, true, false)); + *
+ * + *

Valid Types of Values

+ * + *

There are three possible kinds of term values which may be put into + * sorting fields: Integers, Floats, or Strings. Unless + * {@link SortField SortField} objects are specified, the type of value + * in the field is determined by parsing the first term in the field. + * + *

Integer term values should contain only digits and an optional + * preceeding negative sign. Values must be base 10 and in the range + * Integer.MIN_VALUE and Integer.MAX_VALUE inclusive. + * Documents which should appear first in the sort + * should have low value integers, later documents high values + * (i.e. the documents should be numbered 1..n where + * 1 is the first and n the last). + * + *

Float term values should conform to values accepted by + * {@link Float Float.valueOf(String)} (except that NaN + * and Infinity are not supported). + * Documents which should appear first in the sort + * should have low values, later documents high values. + * + *

String term values can contain any valid String, but should + * not be tokenized. The values are sorted according to their + * {@link Comparable natural order}. Note that using this type + * of term value has higher memory requirements than the other + * two types. + * + *

Object Reuse

+ * + *

One of these objects can be + * used multiple times and the sort order changed between usages. + * + *

This class is thread safe. + * + *

Memory Usage

+ * + *

Sorting uses of caches of term values maintained by the + * internal HitQueue(s). The cache is static and contains an integer + * or float array of length IndexReader.maxDoc() for each field + * name for which a sort is performed. In other words, the size of the + * cache in bytes is: + * + *

4 * IndexReader.maxDoc() * (# of different fields actually used to sort) + * + *

For String fields, the cache is larger: in addition to the + * above array, the value of every term in the field is kept in memory. + * If there are many unique terms in the field, this could + * be quite large. + * + *

Note that the size of the cache is not affected by how many + * fields are in the index and might be used to sort - only by + * the ones actually used to sort a result set. + * + *

The cache is cleared each time a new IndexReader is + * passed in, or if the value returned by maxDoc() + * changes for the current IndexReader. This class is not set up to + * be able to efficiently sort hits from more than one index + * simultaneously. + * + */ +class CLUCENE_EXPORT Sort:LUCENE_BASE { + // internal representation of the sort criteria + SortField** fields; + void clear(); +public: + ~Sort(); + + /** Represents sorting by computed relevance. Using this sort criteria + * returns the same results as calling {@link Searcher#search(Query) Searcher#search()} + * without a sort criteria, only with slightly more overhead. */ + static Sort* RELEVANCE(); + + /** Represents sorting by index order. */ + static Sort* INDEXORDER(); + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); + + + /** Sorts by computed relevance. This is the same sort criteria as + * calling {@link Searcher#search(Query) Searcher#search()} without a sort criteria, only with + * slightly more overhead. */ + Sort(); + + /** Sorts possibly in reverse by the terms in field then by + * index order (document number). The type of value in field is determined + * automatically. + * @see SortField#AUTO + */ + Sort (const TCHAR* field, bool reverse=false); + + /** Sorts in succession by the terms in each field. + * The type of value in field is determined + * automatically. + * @see SortField#AUTO + */ + Sort (const TCHAR** fields); + + /** Sorts by the criteria in the given SortField. */ + Sort (SortField* field); + + /** Sorts in succession by the criteria in each SortField. */ + Sort (SortField** fields); + + /** Sets the sort to the terms in field possibly in reverse, + * then by index order (document number). */ + void setSort (const TCHAR* field, bool reverse=false); + + /** Sets the sort to the terms in each field in succession. */ + void setSort (const TCHAR** fieldnames); + + /** Sets the sort to the given criteria. */ + void setSort (SortField* field); + + /** Sets the sort to the given criteria in succession. */ + void setSort (SortField** fields); + + TCHAR* toString() const; + + /** + * Representation of the sort criteria. + * @return a pointer to the of SortField array used in this sort criteria + */ + SortField** getSort() const{ return fields; } +}; + + + + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/SpanFilter.h b/src/core/CLucene/search/SpanFilter.h new file mode 100644 index 00000000000..88721cf7755 --- /dev/null +++ b/src/core/CLucene/search/SpanFilter.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_SpanFilter_ +#define _lucene_search_SpanFilter_ + +#include "Filter.h" +#include "SpanFilterResult.h" + +CL_NS_DEF(search) + +/** Abstract base class providing a mechanism to restrict searches to a subset + of an index and also maintains and returns position information. + + This is useful if you want to compare the positions from a SpanQuery with the positions of items in + a filter. For instance, if you had a SpanFilter that marked all the occurrences of the word "foo" in documents, + and then you entered a new SpanQuery containing bar, you could not only filter by the word foo, but you could + then compare position information for post processing. + */ +class CLUCENE_EXPORT SpanFilter : public Filter +{ +public: + virtual ~SpanFilter() {} + + /** Returns a SpanFilterResult with true for documents which should be permitted in + * search results, and false for those that should not and Spans for where the true docs match. + * @param reader The {@link org.apache.lucene.index.IndexReader} to load position and bitset information from + * @return A {@link SpanFilterResult} + * @throws CLuceneError if there was an issue accessing the necessary information + */ + virtual SpanFilterResult * bitSpans( CL_NS(index)::IndexReader * reader ) = 0; + +}; + +CL_NS_END +#endif // _lucene_search_SpanFilter_ diff --git a/src/core/CLucene/search/SpanFilterResult.h b/src/core/CLucene/search/SpanFilterResult.h new file mode 100644 index 00000000000..c2622823c36 --- /dev/null +++ b/src/core/CLucene/search/SpanFilterResult.h @@ -0,0 +1,130 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_SpanFilterResult_ +#define _lucene_search_SpanFilterResult_ + +#include "CLucene/util/BitSet.h" +#include "CLucene/util/VoidList.h" + +CL_NS_DEF(search) + +/** + * The results of a SpanQueryFilter. + * Wraps the BitSet and the position information from the SpanQuery + * + * NOTE: This API is still experimental and subject to change. + **/ +class CLUCENE_EXPORT SpanFilterResult +{ +public: + class StartEnd + { + private: + int32_t start; + int32_t end; + + public: + StartEnd( int32_t _start, int32_t _end ) : start(_start), end(_end) + {} + + virtual ~StartEnd() + {} + + /** + * @return The end position of this match + */ + int32_t getEnd() + { + return end; + } + + /** + * The Start position + * @return The start position of this match + */ + int32_t getStart() + { + return start; + } + }; + + + class PositionInfo + { + private: + int32_t doc; + CL_NS(util)::CLList* positions; + + public: + PositionInfo( int32_t _doc ) : doc(_doc) + { + positions = _CLNEW CL_NS(util)::CLList(); + } + + virtual ~PositionInfo() + { + _CLLDELETE( positions ); + } + + void addPosition( int32_t start, int32_t end ) + { + positions->push_back( _CLNEW StartEnd( start, end )); + } + + int32_t getDoc() + { + return doc; + } + + /** + * @return A List of {@link org.apache.lucene.search.SpanFilterResult.StartEnd} objects + */ + CL_NS(util)::CLList* getPositions() + { + return positions; + } + }; + + +private: + CL_NS(util)::BitSet * bits; + CL_NS(util)::CLList * positions; //Spans spans; + +public: + /** + * Constructor + * @param bits The bits for the Filter + * @param positions A List of {@link org.apache.lucene.search.SpanFilterResult.PositionInfo} objects + */ + SpanFilterResult( CL_NS(util)::BitSet * _bits, CL_NS(util)::CLList * _positions ) : + bits( _bits ), positions( _positions ) + {} + + virtual ~SpanFilterResult() + {} + + /** + * The first entry in the array corresponds to the first "on" bit. + * Entries are increasing by document order + * @return A List of PositionInfo objects + */ + CL_NS(util)::CLList * getPositions() + { + return positions; + } + + CL_NS(util)::BitSet * getBits() + { + return bits; + } +}; + +CL_NS_END +#endif // _lucene_search_SpanFilterResult_ + + + diff --git a/src/core/CLucene/search/SpanQueryFilter.cpp b/src/core/CLucene/search/SpanQueryFilter.cpp new file mode 100644 index 00000000000..2d55f42861f --- /dev/null +++ b/src/core/CLucene/search/SpanQueryFilter.cpp @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "SpanQueryFilter.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/search/spans/Spans.h" + + +CL_NS_DEF(search) + +SpanQueryFilter::SpanQueryFilter() : query( NULL ) +{} + +SpanQueryFilter::SpanQueryFilter( const CL_NS2(search,spans)::SpanQuery * query ) +{ + this->query = (CL_NS2(search,spans)::SpanQuery *) query->clone(); + bDeleteQuery = true; +} + +SpanQueryFilter::SpanQueryFilter( CL_NS2(search,spans)::SpanQuery * query, bool bDeleteQuery ) +{ + this->query = query; + this->bDeleteQuery = bDeleteQuery; +} + +SpanQueryFilter::SpanQueryFilter( const SpanQueryFilter& copy ) +{ + this->query = (CL_NS2(search,spans)::SpanQuery *) copy.query->clone(); + bDeleteQuery = true; +} + +SpanQueryFilter::~SpanQueryFilter() +{ + if( bDeleteQuery ) + _CLDELETE( query ); +} + +Filter* SpanQueryFilter::clone() const +{ + return _CLNEW SpanQueryFilter( *this ); +} + +CL_NS(util)::BitSet * SpanQueryFilter::bits( CL_NS(index)::IndexReader * reader ) +{ + SpanFilterResult * result = bitSpans( reader ); + CL_NS(util)::BitSet * bits = result->getBits(); + _CLLDELETE( result ); + return bits; +} + +SpanFilterResult * SpanQueryFilter::bitSpans( CL_NS(index)::IndexReader * reader ) +{ + CL_NS(util)::BitSet * bits = _CLNEW CL_NS(util)::BitSet( reader->maxDoc() ); + CL_NS2(search,spans)::Spans * spans = query->getSpans( reader ); + CL_NS(util)::CLList * tmp = new CL_NS(util)::CLList(); + int32_t currentDoc = -1; + SpanFilterResult::PositionInfo * currentInfo = NULL; + + while( spans->next() ) + { + int32_t doc = spans->doc(); + bits->set( doc ); + if( currentDoc != doc ) + { + currentInfo = _CLNEW SpanFilterResult::PositionInfo( doc ); + tmp->push_back( currentInfo ); + currentDoc = doc; + } + currentInfo->addPosition( spans->start(), spans->end() ); + } + return _CLNEW SpanFilterResult( bits, tmp ); +} + +TCHAR* SpanQueryFilter::toString() +{ + TCHAR* qt = query->toString(); + size_t len = _tcslen( qt ) + 21; + TCHAR* ret = _CL_NEWARRAY( TCHAR, len ); + ret[0] = 0; + _sntprintf( ret, len, _T( "QueryWrapperFilter(%s)" ), qt ); + _CLDELETE_CARRAY( qt ); + return ret; +} + +CL_NS_END diff --git a/src/core/CLucene/search/SpanQueryFilter.h b/src/core/CLucene/search/SpanQueryFilter.h new file mode 100644 index 00000000000..33cbbac141f --- /dev/null +++ b/src/core/CLucene/search/SpanQueryFilter.h @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_SpanQueryFilter_ +#define _lucene_search_SpanQueryFilter_ + +#include "SpanFilter.h" +#include "spans/SpanQuery.h" + +CL_NS_DEF(search) + +/** + * Constrains search results to only match those which also match a provided + * query. Also provides position information about where each document matches + * at the cost of extra space compared with the QueryWrapperFilter. + * There is an added cost to this above what is stored in a {@link QueryWrapperFilter}. Namely, + * the position information for each matching document is stored. + *

+ * This filter does not cache. See the {@link org.apache.lucene.search.CachingSpanFilter} for a wrapper that + * caches. + * + * @version $Id:$ + */ +class CLUCENE_EXPORT SpanQueryFilter : public SpanFilter +{ +protected: + CL_NS2(search,spans)::SpanQuery * query; + bool bDeleteQuery; + +protected: + SpanQueryFilter(); + SpanQueryFilter( const SpanQueryFilter& copy ); + +public: + /** Constructs a filter which only matches documents matching + * query. + * @param query The {@link org.apache.lucene.search.spans.SpanQuery} to use as the basis for the Filter. + */ + SpanQueryFilter( const CL_NS2(search,spans)::SpanQuery * query ); + + SpanQueryFilter( CL_NS2(search,spans)::SpanQuery * query, bool bDeleteQuery ); + + virtual ~SpanQueryFilter(); + + virtual Filter* clone() const; + + virtual CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader * reader ); + + virtual SpanFilterResult * bitSpans( CL_NS(index)::IndexReader * reader ); + + CL_NS2(search,spans)::SpanQuery * getQuery(); + + virtual TCHAR* toString(); + + +// public boolean equals( Object o ) { +// return o instanceof SpanQueryFilter && this.query.equals(((SpanQueryFilter) o).query); +// } +// +// public int hashCode() { +// return query.hashCode() ^ 0x923F64B9; +// } +}; + +inline CL_NS2(search,spans)::SpanQuery * SpanQueryFilter::getQuery() +{ + return query; +} + +CL_NS_END +#endif // _lucene_search_SpanQueryFilter_ diff --git a/src/core/CLucene/search/TermQuery.cpp b/src/core/CLucene/search/TermQuery.cpp new file mode 100644 index 00000000000..79b4fd54165 --- /dev/null +++ b/src/core/CLucene/search/TermQuery.cpp @@ -0,0 +1,251 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "TermQuery.h" + +#include "SearchHeader.h" +#include "Scorer.h" +#include "CLucene/index/Term.h" +#include "Explanation.h" +#include "Similarity.h" +#include "Searchable.h" +#include "_TermScorer.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/index/Terms.h" + +#include + +CL_NS_USE(index) +CL_NS_DEF(search) + + + + class TermWeight: public Weight { + private: + Similarity* similarity; // ISH: was Searcher*, for no apparent reason + float_t value; + float_t idf; + float_t queryNorm; + float_t queryWeight; + + TermQuery* parentQuery; // CLucene specific + CL_NS(index)::Term* _term; + + public: + TermWeight(Searcher* searcher, TermQuery* parentQuery, CL_NS(index)::Term* _term); + virtual ~TermWeight(); + + // return a *new* string describing this object + TCHAR* toString(); + Query* getQuery() { return (Query*)parentQuery; } + float_t getValue() { return value; } + + float_t sumOfSquaredWeights(); + void normalize(float_t queryNorm); + Scorer* scorer(CL_NS(index)::IndexReader* reader); + Explanation* explain(CL_NS(index)::IndexReader* reader, int32_t doc); + }; + + + /** Constructs a query for the term t. */ + TermQuery::TermQuery(Term* t): + term( _CL_POINTER(t) ) + { + } + TermQuery::TermQuery(const TermQuery& clone): + Query(clone){ + this->term=_CL_POINTER(clone.term); + } + TermQuery::~TermQuery(){ + _CLLDECDELETE(term); + } + + Query* TermQuery::clone() const{ + return _CLNEW TermQuery(*this); + } + + const char* TermQuery::getClassName(){ + return "TermQuery"; + } + const char* TermQuery::getObjectName() const{ + return getClassName(); + } + size_t TermQuery::hashCode() const { + return Similarity::floatToByte(getBoost()) ^ term->hashCode(); + } + + //added by search highlighter + Term* TermQuery::getTerm(bool pointer) const + { + if ( pointer ) + return _CL_POINTER(term); + else + return term; + } + + TCHAR* TermQuery::toString(const TCHAR* field) const{ + CL_NS(util)::StringBuffer buffer; + if ( field==NULL || _tcscmp(term->field(),field)!= 0 ) { + buffer.append(term->field()); + buffer.append(_T(":")); + } + buffer.append(term->text()); + if (getBoost() != 1.0f) { + buffer.append(_T("^")); + buffer.appendFloat( getBoost(),1 ); + } + return buffer.toString(); + } + + bool TermQuery::equals(Query* other) const { + if (!(other->instanceOf(TermQuery::getClassName()))) + return false; + + TermQuery* tq = (TermQuery*)other; + return (this->getBoost() == tq->getBoost()) + && this->term->equals(tq->term); + } + + TermWeight::TermWeight(Searcher* _searcher, TermQuery* _parentQuery, Term* term):similarity(_searcher->getSimilarity()), + value(0), queryNorm(0),queryWeight(0), parentQuery(_parentQuery),_term(term) + { + idf = similarity->idf(term, _searcher); // compute idf + } + + TermWeight::~TermWeight(){ + } + + // + TCHAR* TermWeight::toString() { + int32_t size=strlen(parentQuery->getObjectName()) + 10; + TCHAR* tmp = _CL_NEWARRAY(TCHAR, size); + _sntprintf(tmp,size,_T("weight(%S)"),parentQuery->getObjectName()); + return tmp; + } + + float_t TermWeight::sumOfSquaredWeights() { + // legacy // idf = parentQuery->getSimilarity(searcher)->idf(_term, searcher); // compute idf + queryWeight = idf * parentQuery->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it + } + + void TermWeight::normalize(float_t _queryNorm) { + this->queryNorm = _queryNorm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document + } + + Scorer* TermWeight::scorer(IndexReader* reader) { + TermDocs* termDocs = reader->termDocs(_term); + + if (termDocs == NULL) + return NULL; + + return _CLNEW TermScorer(this, termDocs, similarity, + reader->norms(_term->field())); + } + + Explanation* TermWeight::explain(IndexReader* reader, int32_t doc){ + ComplexExplanation* result = _CLNEW ComplexExplanation(); + + TCHAR buf[LUCENE_SEARCH_EXPLANATION_DESC_LEN]; + TCHAR* tmp; + + tmp = getQuery()->toString(); + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("weight(%s in %d), product of:"),tmp,doc); + _CLDELETE_LCARRAY(tmp); + result->setDescription(buf); + + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("idf(docFreq=%d, numDocs=%d)"), reader->docFreq(_term), reader->numDocs() ); + Explanation* idfExpl = _CLNEW Explanation(idf, buf); + + // explain query weight + Explanation* queryExpl = _CLNEW Explanation(); + tmp = getQuery()->toString(); + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("queryWeight(%s), product of:"), tmp); + _CLDELETE_LCARRAY(tmp); + queryExpl->setDescription(buf); + + Explanation* boostExpl = _CLNEW Explanation(parentQuery->getBoost(), _T("boost")); + if (parentQuery->getBoost() != 1.0f) + queryExpl->addDetail(boostExpl); + else + _CLDELETE(boostExpl); + + queryExpl->addDetail(idfExpl->clone()); + + Explanation* queryNormExpl = _CLNEW Explanation(queryNorm,_T("queryNorm")); + queryExpl->addDetail(queryNormExpl); + + queryExpl->setValue(parentQuery->getBoost()* // always 1.0 | TODO: original Java code is boostExpl.getValue() + idfExpl->getValue() * + queryNormExpl->getValue()); + result->addDetail(queryExpl); + + // explain field weight + const TCHAR* field = _term->field(); + ComplexExplanation* fieldExpl = _CLNEW ComplexExplanation(); + + tmp = _term->toString(); + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("fieldWeight(%s in %d), product of:"),tmp,doc); + _CLDELETE_LCARRAY(tmp); + fieldExpl->setDescription(buf); + + Scorer* sc = scorer(reader); + Explanation* tfExpl = sc->explain(doc); + _CLLDELETE(sc); + fieldExpl->addDetail(tfExpl); + fieldExpl->addDetail(idfExpl); + + Explanation* fieldNormExpl = _CLNEW Explanation(); + uint8_t* fieldNorms = reader->norms(field); + float_t fieldNorm = + fieldNorms!=NULL ? Similarity::decodeNorm(fieldNorms[doc]) : 0.0f; + fieldNormExpl->setValue(fieldNorm); + + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN, + _T("fieldNorm(field=%s, doc=%d)"),field,doc); + fieldNormExpl->setDescription(buf); + fieldExpl->addDetail(fieldNormExpl); + + fieldExpl->setMatch(tfExpl->isMatch()); + fieldExpl->setValue(tfExpl->getValue() * + idfExpl->getValue() * + fieldNormExpl->getValue()); + + if (queryExpl->getValue() == 1.0f){ + _CLLDELETE(result); + return fieldExpl; + } + + // combine them + result->setValue(queryExpl->getValue() * fieldExpl->getValue()); + + result->addDetail(fieldExpl); + result->setMatch(fieldExpl->getMatch()); + + return result; + } + + Weight* TermQuery::_createWeight(Searcher* _searcher) { + return _CLNEW TermWeight(_searcher,this,term); + } + + void TermQuery::extractTerms( TermSet * termset ) const + { + if( term && termset->end() == termset->find( term )) + termset->insert( _CL_POINTER( term )); + } + + +CL_NS_END + diff --git a/src/core/CLucene/search/TermQuery.h b/src/core/CLucene/search/TermQuery.h new file mode 100644 index 00000000000..da4170d66ff --- /dev/null +++ b/src/core/CLucene/search/TermQuery.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_TermQuery_ +#define _lucene_search_TermQuery_ + +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(util,StringBuffer) + +#include "Query.h" + +CL_NS_DEF(search) + /** A Query that matches documents containing a term. + This may be combined with other terms with a {@link BooleanQuery}. + */ + class CLUCENE_EXPORT TermQuery: public Query { + private: + CL_NS(index)::Term* term; + protected: + Weight* _createWeight(Searcher* searcher); + TermQuery(const TermQuery& clone); + public: + // Constructs a query for the term t. + TermQuery(CL_NS(index)::Term* t); + virtual ~TermQuery(); + + static const char* getClassName(); + const char* getObjectName() const; + + /** Returns the term of this query. */ + CL_NS(index)::Term* getTerm(bool pointer=true) const; + + /** Prints a user-readable version of this query. */ + TCHAR* toString(const TCHAR* field) const; + + /** Returns true if o is equal to this. */ + bool equals(Query* other) const; + Query* clone() const; + + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + /** Expert: adds all terms occurring in this query to the termset set. */ + void extractTerms( TermSet * termset ) const; + + }; +CL_NS_END +#endif + diff --git a/src/core/CLucene/search/TermScorer.cpp b/src/core/CLucene/search/TermScorer.cpp new file mode 100644 index 00000000000..81555a4dc9c --- /dev/null +++ b/src/core/CLucene/search/TermScorer.cpp @@ -0,0 +1,129 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_TermScorer.h" +#include "SearchHeader.h" +#include "Explanation.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/Terms.h" +#include "TermQuery.h" +#include "Similarity.h" +#include "Explanation.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + + TermScorer::TermScorer(Weight* w, CL_NS(index)::TermDocs* td, + Similarity* similarity,uint8_t* _norms): + Scorer(similarity), + termDocs(td), + norms(_norms), + weight(w), + weightValue(w->getValue()), + _doc(0), + pointer(0), + pointerMax(0) + { + memset(docs,0,PFOR_BLOCK_SIZE*sizeof(int32_t)); + memset(freqs,0,PFOR_BLOCK_SIZE*sizeof(int32_t)); + + for (int32_t i = 0; i < LUCENE_SCORE_CACHE_SIZE; i++) + scoreCache[i] = 1;//getSimilarity()->tf(i) * weightValue; + } + + TermScorer::~TermScorer(){ + _CLLDELETE(termDocs); + } + bool TermScorer::next(){ + pointer++; + if (pointer >= pointerMax) { + pointerMax = termDocs->read(docs, freqs, PFOR_BLOCK_SIZE); // refill buffer + if (pointerMax != 0) { + pointer = 0; + } else { + termDocs->close(); // close stream + _doc = LUCENE_INT32_MAX_SHOULDBE; // set to sentinel value + return false; + } + } + _doc = docs[pointer]; + return true; + } + + bool TermScorer::skipTo(int32_t target) { + // first scan in cache + for (pointer++; pointer < pointerMax; pointer++) { + if (docs[pointer] >= target) { + _doc = docs[pointer]; + return true; + } + } + + // not found in cache, seek underlying stream + bool result = termDocs->skipTo(target); + if (result) { + pointerMax = 1; + pointer = 0; + docs[pointer] = _doc = termDocs->doc(); + freqs[pointer] = termDocs->freq(); + } else { + _doc = LUCENE_INT32_MAX_SHOULDBE; + } + return result; + } + + Explanation* TermScorer::explain(int32_t doc) { + TermQuery* query = (TermQuery*)weight->getQuery(); + Explanation* tfExplanation = _CLNEW Explanation(); + int32_t tf = 0; + while (pointer < pointerMax) { + if (docs[pointer] == doc) + tf = freqs[pointer]; + pointer++; + } + if (tf == 0) { + if (termDocs->skipTo(doc)) { + if (termDocs->doc() == doc) { + tf = termDocs->freq(); + } + } + } + termDocs->close(); + tfExplanation->setValue(getSimilarity()->tf(tf)); + + TCHAR buf[LUCENE_SEARCH_EXPLANATION_DESC_LEN+1]; + TCHAR* termToString = query->getTerm(false)->toString(); + _sntprintf(buf,LUCENE_SEARCH_EXPLANATION_DESC_LEN,_T("tf(termFreq(%s)=%d)"), termToString, tf); + _CLDELETE_LCARRAY(termToString); + tfExplanation->setDescription(buf); + return tfExplanation; + } + + TCHAR* TermScorer::toString() { + TCHAR* wb = weight->toString(); + int32_t rl = _tcslen(wb) + 9; //9=_tcslen("scorer(" ")") + 1 + TCHAR* ret = _CL_NEWARRAY(TCHAR,rl); + _sntprintf(ret,rl,_T("scorer(%s)"), wb); + _CLDELETE_LCARRAY(wb); + return ret; + } + + float_t TermScorer::score(){ + return 1.0; + /*int32_t f = freqs[pointer]; + float_t raw = // compute tf(f)*weight + f < LUCENE_SCORE_CACHE_SIZE // check cache + ? scoreCache[f] // cache hit + : getSimilarity()->tf(f) * weightValue; // cache miss + + // return raw * Similarity::decodeNorm(norms[_doc]); // normalize for field + return raw; // no need use norms*/ + } + + int32_t TermScorer::doc() const { return _doc; } + +CL_NS_END diff --git a/src/core/CLucene/search/WildcardQuery.cpp b/src/core/CLucene/search/WildcardQuery.cpp new file mode 100644 index 00000000000..fd9c8c92ee5 --- /dev/null +++ b/src/core/CLucene/search/WildcardQuery.cpp @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "WildcardQuery.h" +#include "TermQuery.h" +#include "WildcardTermEnum.h" +#include "Similarity.h" +#include "CLucene/index/Term.h" +#include "CLucene/util/BitSet.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/index/IndexReader.h" + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_DEF(search) + + +WildcardQuery::WildcardQuery(Term* term): +MultiTermQuery( term ){ + //Func - Constructor + //Pre - term != NULL + //Post - Instance has been created + termContainsWildcard = (_tcschr(term->text(), _T('*')) != NULL || _tcschr(term->text(), _T('?')) != NULL); +} + +WildcardQuery::~WildcardQuery(){ + //Func - Destructor + //Pre - true + //Post - true + +} + +const char* WildcardQuery::getObjectName() const{ + //Func - Returns the string "WildcardQuery" + //Pre - true + //Post - The string "WildcardQuery" has been returned + return getClassName(); +} + +const char* WildcardQuery::getClassName(){ + return "WildcardQuery"; +} + + +FilteredTermEnum* WildcardQuery::getEnum(IndexReader* reader) { + return _CLNEW WildcardTermEnum(reader, getTerm(false)); +} + +WildcardQuery::WildcardQuery(const WildcardQuery& clone): +MultiTermQuery(clone) +{ +} + +Query* WildcardQuery::clone() const{ + return _CLNEW WildcardQuery(*this); +} +size_t WildcardQuery::hashCode() const{ + //todo: we should give the query a seeding value... but + //need to do it for all hascode functions + return Similarity::floatToByte(getBoost()) ^ getTerm()->hashCode(); +} +bool WildcardQuery::equals(Query* other) const{ + if (!(other->instanceOf(WildcardQuery::getClassName()))) + return false; + + WildcardQuery* tq = (WildcardQuery*)other; + return (this->getBoost() == tq->getBoost()) + && getTerm()->equals(tq->getTerm()); +} + + +Query* WildcardQuery::rewrite(CL_NS(index)::IndexReader* reader) { + if (termContainsWildcard) + return MultiTermQuery::rewrite(reader); + + return _CLNEW TermQuery( getTerm(false) ); +} + + +WildcardFilter::WildcardFilter( Term* term ) +{ + this->term = _CL_POINTER(term); +} + +WildcardFilter::~WildcardFilter() +{ + _CLDECDELETE(term); +} + +WildcardFilter::WildcardFilter( const WildcardFilter& copy ) : +term( _CL_POINTER(copy.term) ) +{ +} + +Filter* WildcardFilter::clone() const { + return _CLNEW WildcardFilter(*this ); +} + + +TCHAR* WildcardFilter::toString() +{ + //Instantiate a stringbuffer buffer to store the readable version temporarily + CL_NS(util)::StringBuffer buffer; + //check if field equal to the field of prefix + if( term->field() != NULL ) { + //Append the field of prefix to the buffer + buffer.append(term->field()); + //Append a colon + buffer.append(_T(":") ); + } + //Append the text of the prefix + buffer.append(term->text()); + + //Convert StringBuffer buffer to TCHAR block and return it + return buffer.toString(); +} + + +/** Returns a BitSet with true for documents which should be permitted in +search results, and false for those that should not. */ +BitSet* WildcardFilter::bits( IndexReader* reader ) +{ + BitSet* bts = _CLNEW BitSet( reader->maxDoc() ); + + WildcardTermEnum termEnum (reader, term); + if (termEnum.term(false) == NULL) + return bts; + + TermDocs* termDocs = reader->termDocs(); + try{ + do{ + termDocs->seek(&termEnum); + + while (termDocs->next()) { + bts->set(termDocs->doc()); + } + }while(termEnum.next()); + } _CLFINALLY( + termDocs->close(); + _CLDELETE(termDocs); + termEnum.close(); + ) + + return bts; +} + +CL_NS_END diff --git a/src/core/CLucene/search/WildcardQuery.h b/src/core/CLucene/search/WildcardQuery.h new file mode 100644 index 00000000000..38ff2267be8 --- /dev/null +++ b/src/core/CLucene/search/WildcardQuery.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_WildcardQuery_ +#define _lucene_search_WildcardQuery_ + +//#include "CLucene/index/IndexReader.h" +CL_CLASS_DEF(index,Term) +#include "MultiTermQuery.h" +#include "Filter.h" +//#include "WildcardTermEnum.h" + +CL_NS_DEF(search) + +/** Implements the wildcard search query. Supported wildcards are *, which + * matches any character sequence (including the empty one), and ?, + * which matches any single character. Note this query can be slow, as it + * needs to iterate over all terms. In order to prevent extremely slow WildcardQueries, + * a Wildcard term must not start with one of the wildcards * or + * ?. + * + * @see WildcardTermEnum + */ +class CLUCENE_EXPORT WildcardQuery: public MultiTermQuery { +protected: + FilteredTermEnum* getEnum(CL_NS(index)::IndexReader* reader); + WildcardQuery(const WildcardQuery& clone); +public: + WildcardQuery(CL_NS(index)::Term* term); + ~WildcardQuery(); + + const char* getObjectName() const; + static const char* getClassName(); + + size_t hashCode() const; + bool equals(Query* other) const; + Query* clone() const; + + Query* rewrite(CL_NS(index)::IndexReader* reader); +private: + bool termContainsWildcard; +}; + + + +class CLUCENE_EXPORT WildcardFilter: public Filter +{ +private: + CL_NS(index)::Term* term; +protected: + WildcardFilter( const WildcardFilter& copy ); + +public: + WildcardFilter(CL_NS(index)::Term* term); + ~WildcardFilter(); + + /** Returns a BitSet with true for documents which should be permitted in + search results, and false for those that should not. */ + CL_NS(util)::BitSet* bits( CL_NS(index)::IndexReader* reader ); + + Filter* clone() const; + TCHAR* toString(); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/WildcardTermEnum.cpp b/src/core/CLucene/search/WildcardTermEnum.cpp new file mode 100644 index 00000000000..6d90057b9d8 --- /dev/null +++ b/src/core/CLucene/search/WildcardTermEnum.cpp @@ -0,0 +1,182 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "WildcardTermEnum.h" +#include "CLucene/index/Term.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/config/repl_wchar.h" + +CL_NS_USE(index) +CL_NS_DEF(search) + + bool WildcardTermEnum::termCompare(Term* term) { + if ( term!=NULL && __term->field() == term->field() ) { + const TCHAR* searchText = term->text(); + const TCHAR* patternText = __term->text(); + if ( _tcsncmp( searchText, pre, preLen ) == 0 ){ + return wildcardEquals(patternText+preLen, __term->textLength()-preLen, 0, searchText, term->textLength(), preLen); + } + } + _endEnum = true; + return false; + } + + /** Creates new WildcardTermEnum */ + WildcardTermEnum::WildcardTermEnum(IndexReader* reader, Term* term): + FilteredTermEnum(), + __term(_CL_POINTER(term)), + fieldMatch(false), + _endEnum(false) + { + + pre = stringDuplicate(term->text()); + + const TCHAR* sidx = _tcschr( pre, LUCENE_WILDCARDTERMENUM_WILDCARD_STRING ); + const TCHAR* cidx = _tcschr( pre, LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR ); + const TCHAR* tidx = sidx; + if (tidx == NULL) + tidx = cidx; + else if ( cidx && cidx > pre) + tidx = cl_min(sidx, cidx); + CND_PRECONDITION(tidx != NULL, "tidx==NULL"); + int32_t idx = (int32_t)(tidx - pre); + preLen = idx; + CND_PRECONDITION(preLentextLength(), "preLen >= term->textLength()"); + pre[preLen]=0; //trim end + + Term* t = _CLNEW Term(__term, pre); + setEnum( reader->terms(t) ); + _CLDECDELETE(t); + } + + void WildcardTermEnum::close() + { + if ( __term != NULL ){ + FilteredTermEnum::close(); + + _CLDECDELETE(__term); + __term = NULL; + + _CLDELETE_CARRAY( pre ); + } + } + WildcardTermEnum::~WildcardTermEnum() { + close(); + } + + float_t WildcardTermEnum::difference() { + return 1.0f; + } + + bool WildcardTermEnum::endEnum() { + return _endEnum; + } + const char* WildcardTermEnum::getObjectName() const{ return getClassName(); } + const char* WildcardTermEnum::getClassName(){ return "WildcardTermEnum"; } + + bool WildcardTermEnum::wildcardEquals(const TCHAR* pattern, int32_t patternLen, int32_t patternIdx, const TCHAR* str, int32_t strLen, int32_t stringIdx) + { + for (int32_t p = patternIdx; ; ++p) + { + for (int32_t s = stringIdx; ; ) + { + // End of str yet? + bool sEnd = (s >= strLen); + // End of pattern yet? + bool pEnd = (p >= patternLen); + + // If we're looking at the end of the str... + if (sEnd) + { + // Assume the only thing left on the pattern is/are wildcards + bool justWildcardsLeft = true; + + // Current wildcard position + int32_t wildcardSearchPos = p; + // While we haven't found the end of the pattern, + // and haven't encountered any non-wildcard characters + while (wildcardSearchPos < patternLen && justWildcardsLeft) + { + // Check the character at the current position + TCHAR wildchar = pattern[wildcardSearchPos]; + // If it's not a wildcard character, then there is more + // pattern information after this/these wildcards. + + if (wildchar != LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR && + wildchar != LUCENE_WILDCARDTERMENUM_WILDCARD_STRING){ + justWildcardsLeft = false; + }else{ + // to prevent "cat" matches "ca??" + if (wildchar == LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR) + return false; + + wildcardSearchPos++; // Look at the next character + } + } + + // This was a prefix wildcard search, and we've matched, so + // return true. + if (justWildcardsLeft) + return true; + } + + // If we've gone past the end of the str, or the pattern, + // return false. + if (sEnd || pEnd) + break; + + // Match a single character, so continue. + if (pattern[p] == LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR) + { + p += lucene_utf8charlen(pattern[p]); + s += lucene_utf8charlen(str[s]); + continue; + } + + if (pattern[p] == LUCENE_WILDCARDTERMENUM_WILDCARD_STRING) + { + // Look at the character beyond the '*'. + ++p; + // Examine the str, starting at the last character. + for (int32_t i = strLen; i >= s; --i) + { + if (wildcardEquals(pattern, patternLen, p, str, strLen, i)) + return true; + } + break; + } + + if (pattern[p] != str[s]) + break; + + // if utf-8, compare the whole + auto len_p = lucene_utf8charlen(pattern[p]); + auto len_s = lucene_utf8charlen(str[s]); + + if (len_p != len_s || p+len_p > patternLen || s+len_s > strLen) + break; + bool is_match = true; + for(size_t i_utf8 =1; i_utf8 < len_p; ++i_utf8) + { + if (pattern[p + i_utf8] != str[s + i_utf8]) + { + is_match = false; + break; + } + } + if(!is_match) + break; + + p += len_p; + s += len_s; + } + return false; + } + } + + +CL_NS_END diff --git a/src/core/CLucene/search/WildcardTermEnum.h b/src/core/CLucene/search/WildcardTermEnum.h new file mode 100644 index 00000000000..370d9ce669b --- /dev/null +++ b/src/core/CLucene/search/WildcardTermEnum.h @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_WildcardTermEnum_ +#define _lucene_search_WildcardTermEnum_ + +//#include "CLucene/index/IndexReader.h" +CL_CLASS_DEF(index,Term) +CL_CLASS_DEF(index,IndexReader) +//#include "CLucene/index/Terms.h" +#include "FilteredTermEnum.h" + +CL_NS_DEF(search) + /** + * Subclass of FilteredTermEnum for enumerating all terms that match the + * specified wildcard filter term-> + *

+ * Term enumerations are always ordered by term->compareTo(). Each term in + * the enumeration is greater than all that precede it. + */ + class CLUCENE_EXPORT WildcardTermEnum: public FilteredTermEnum { + private: + CL_NS(index)::Term* __term; + TCHAR* pre; + int32_t preLen; + bool fieldMatch; + bool _endEnum; + + /******************************************** + * const TCHAR* equality with support for wildcards + ********************************************/ + + protected: + bool termCompare(CL_NS(index)::Term* term) ; + + public: + + /** + * Creates a new WildcardTermEnum. Passing in a + * {@link Term Term} that does not contain a + * LUCENE_WILDCARDTERMENUM_WILDCARD_STRING or + * LUCENE_WILDCARDTERMENUM_WILDCARD_CHAR will cause an exception to be thrown. + */ + WildcardTermEnum(CL_NS(index)::IndexReader* reader, CL_NS(index)::Term* term); + ~WildcardTermEnum(); + + float_t difference() ; + + bool endEnum() ; + + /** + * Determines if a word matches a wildcard pattern. + */ + static bool wildcardEquals(const TCHAR* pattern, int32_t patternLen, int32_t patternIdx, const TCHAR* str, int32_t strLen, int32_t stringIdx); + + void close(); + + const char* getObjectName() const; + static const char* getClassName(); + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_BooleanScorer.h b/src/core/CLucene/search/_BooleanScorer.h new file mode 100644 index 00000000000..fbc599a47df --- /dev/null +++ b/src/core/CLucene/search/_BooleanScorer.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_BooleanScorer_ +#define _lucene_search_BooleanScorer_ + + +#include "Scorer.h" + +CL_NS_DEF(search) + + class BooleanScorer: public Scorer { + private: + + class Bucket { + public: + int32_t doc; // tells if bucket is valid + float_t score; // incremental score + int32_t bits; // used for bool constraints + int32_t coord; // count of terms in score + Bucket* next; // next valid bucket + + Bucket(); + virtual ~Bucket(); + }; + + class SubScorer { + public: + bool done; + Scorer* scorer; + bool required; + bool prohibited; + HitCollector* collector; + SubScorer* next; + SubScorer(Scorer* scr, const bool r, const bool p, HitCollector* c, SubScorer* nxt); + virtual ~SubScorer(); + }; + + class BucketTable { + private: + BooleanScorer* scorer; + public: + Bucket* buckets; + Bucket* first; // head of valid list + + BucketTable(BooleanScorer* scr); + int32_t size() const; + HitCollector* newCollector(const int32_t mask); + void clear(); + virtual ~BucketTable(); + }; + + class Collector: public HitCollector { + private: + BucketTable* bucketTable; + int32_t mask; + public: + Collector(const int32_t mask, BucketTable* bucketTable); + + void collect(const int32_t doc, const float_t score); + }; + + SubScorer* scorers; + BucketTable* bucketTable; + + int32_t maxCoord; + int32_t nextMask; + + int32_t end; + Bucket* current; + + int32_t minNrShouldMatch; + + public: + LUCENE_STATIC_CONSTANT(int32_t,BucketTable_SIZE=1024); + int32_t requiredMask; + int32_t prohibitedMask; + float_t* coordFactors; + + BooleanScorer( Similarity* similarity, int32_t minNrShouldMatch = 1 ); + virtual ~BooleanScorer(); + void add(Scorer* scorer, const bool required, const bool prohibited); + int32_t doc() const { return current->doc; } + bool next(); + float_t score(); + void score( HitCollector* hc ); + bool skipTo(int32_t target); + Explanation* explain(int32_t doc); + virtual TCHAR* toString(); + void computeCoordFactors(); + + protected: + bool score( HitCollector* hc, const int32_t max ); + + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_BooleanScorer2.h b/src/core/CLucene/search/_BooleanScorer2.h new file mode 100644 index 00000000000..ce0b2582463 --- /dev/null +++ b/src/core/CLucene/search/_BooleanScorer2.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_search_BooleanScorer2_ +#define _lucene_search_BooleanScorer2_ + +#include "Scorer.h" + +CL_NS_DEF(search) + + class CLUCENE_EXPORT BooleanScorer2: public Scorer { + private: + class Internal; + friend class Internal; + Internal* _internal; + + class Coordinator; + class SingleMatchScorer; + class NonMatchingScorer; + class ReqOptSumScorer; + class ReqExclScorer; + class BSConjunctionScorer; + class BSDisjunctionSumScorer; + protected: + bool score( HitCollector* hc, const int32_t max ); + public: + + BooleanScorer2( Similarity* similarity, int32_t minNrShouldMatch = 0, bool allowDocsOutOfOrder = false ); + virtual ~BooleanScorer2(); + + void add( Scorer* scorer, bool required, bool prohibited ); + void score( HitCollector* hc ); + int32_t doc() const; + bool next(); + float_t score(); + bool skipTo( int32_t target ); + Explanation* explain( int32_t doc ); + virtual TCHAR* toString(); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_ConjunctionScorer.h b/src/core/CLucene/search/_ConjunctionScorer.h new file mode 100644 index 00000000000..e02bec7cd7d --- /dev/null +++ b/src/core/CLucene/search/_ConjunctionScorer.h @@ -0,0 +1,41 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_ConjunctionScorer_ +#define _lucene_search_ConjunctionScorer_ + +#include "Scorer.h" +#include "CLucene/util/Array.h" +CL_NS_DEF(search) + +/** Scorer for conjunctions, sets of queries, all of which are required. */ +class ConjunctionScorer: public Scorer { +private: + CL_NS(util)::ArrayBase* scorers; + typedef CL_NS(util)::CLVector > ScorersType; + bool firstTime; + bool more; + float_t coord; + int32_t lastDoc; + + Scorer* last(); + bool doNext(); + + bool init(int32_t target); +public: + ConjunctionScorer(Similarity* similarity, ScorersType* scorers); + ConjunctionScorer(Similarity* similarity, const CL_NS(util)::ArrayBase* scorers); + virtual ~ConjunctionScorer(); + virtual TCHAR* toString(); + int32_t doc() const; + bool next(); + bool skipTo(int32_t target); + virtual float_t score(); + virtual Explanation* explain(int32_t doc); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_DisjunctionSumScorer.h b/src/core/CLucene/search/_DisjunctionSumScorer.h new file mode 100644 index 00000000000..5f25d3bd06f --- /dev/null +++ b/src/core/CLucene/search/_DisjunctionSumScorer.h @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_DisjunctionSumScorer_ +#define _lucene_search_DisjunctionSumScorer_ + +CL_NS_USE(util) +CL_NS_DEF(search) + +/** A Scorer for OR like queries, counterpart of ConjunctionScorer. +* This Scorer implements {@link Scorer#skipTo(int)} and uses skipTo() on the given Scorers. +* @java-todo Implement score(HitCollector, int). +*/ +class DisjunctionSumScorer : public Scorer { +public: + typedef CL_NS(util)::CLVector > ScorersType; +private: + /** The minimum number of scorers that should match. */ + int32_t minimumNrMatchers; + + /** The scorerDocQueue contains all subscorers ordered by their current doc(), + * with the minimum at the top. + *
The scorerDocQueue is initialized the first time next() or skipTo() is called. + *
An exhausted scorer is immediately removed from the scorerDocQueue. + *
If less than the minimumNrMatchers scorers + * remain in the scorerDocQueue next() and skipTo() return false. + *

+ * After each to call to next() or skipTo() + * currentSumScore is the total score of the current matching doc, + * nrMatchers is the number of matching scorers, + * and all scorers are after the matching doc, or are exhausted. + */ + ScorerDocQueue* scorerDocQueue; + int32_t queueSize; // used to avoid size() method calls on scorerDocQueue + + /** The document number of the current match. */ + int32_t currentDoc; + float_t currentScore; + + /** Called the first time next() or skipTo() is called to + * initialize scorerDocQueue. + */ + void initScorerDocQueue(); + +protected: + /** The number of subscorers. */ + int32_t nrScorers; + + /** The subscorers. */ + DisjunctionSumScorer::ScorersType subScorers; + + /** The number of subscorers that provide the current match. */ + int32_t _nrMatchers; + + /** Expert: Collects matching documents in a range. Hook for optimization. + * Note that {@link #next()} must be called once before this method is called + * for the first time. + * @param hc The collector to which all matching documents are passed through + * {@link HitCollector#collect(int, float)}. + * @param max Do not score documents past this. + * @return true if more matching documents may remain. + */ + bool score( HitCollector* hc, const int32_t max ); + + /** Advance all subscorers after the current document determined by the + * top of the scorerDocQueue. + * Repeat until at least the minimum number of subscorers match on the same + * document and all subscorers are after that document or are exhausted. + *
On entry the scorerDocQueue has at least minimumNrMatchers + * available. At least the scorer with the minimum document number will be advanced. + * @return true iff there is a match. + *
In case there is a match, currentDoc, currentSumScore, + * and nrMatchers describe the match. + * + * @todo Investigate whether it is possible to use skipTo() when + * the minimum number of matchers is bigger than one, ie. try and use the + * character of ConjunctionScorer for the minimum number of matchers. + * Also delay calling score() on the sub scorers until the minimum number of + * matchers is reached. + *
For this, a Scorer array with minimumNrMatchers elements might + * hold Scorers at currentDoc that are temporarily popped from scorerQueue. + */ + bool advanceAfterCurrent(); + +public: + /** Construct a DisjunctionScorer, using one as the minimum number + * of matching subscorers. + * @param subScorers A collection of at least two subscorers. + * @param minimumNrMatchers The positive minimum number of subscorers that should + * match to match this query. + *
When minimumNrMatchers is bigger than + * the number of subScorers, + * no matches will be produced. + *
When minimumNrMatchers equals the number of subScorers, + * it more efficient to use ConjunctionScorer. + */ + DisjunctionSumScorer( DisjunctionSumScorer::ScorersType* _subScorers, const int32_t _minimumNrMatchers = 1); + virtual ~DisjunctionSumScorer(); + + /** Scores and collects all matching documents. + * @param hc The collector to which all matching documents are passed through + * {@link HitCollector#collect(int, float)}. + *
When this method is used the {@link #explain(int)} method should not be used. + */ + void score( HitCollector* hc ); + bool next(); + + /** Returns the score of the current document matching the query. + * Initially invalid, until {@link #next()} is called the first time. + */ + virtual float_t score(); + + int32_t doc() const; + + /** Returns the number of subscorers matching the current document. + * Initially invalid, until {@link #next()} is called the first time. + */ + int32_t nrMatchers() const; + + /** Skips to the first match beyond the current whose document number is + * greater than or equal to a given target. + *
When this method is used the {@link #explain(int)} method should not be used. + *
The implementation uses the skipTo() method on the subscorers. + * @param target The target document number. + * @return true iff there is such a match. + */ + bool skipTo( int32_t target ); + + virtual TCHAR* toString(); + + /** @return An explanation for the score of a given document. */ + Explanation* explain( int32_t doc ); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_ExactPhraseScorer.h b/src/core/CLucene/search/_ExactPhraseScorer.h new file mode 100644 index 00000000000..c88dcaa385c --- /dev/null +++ b/src/core/CLucene/search/_ExactPhraseScorer.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_ExactPhraseScorer_ +#define _lucene_search_ExactPhraseScorer_ + +#include "_PhraseScorer.h" + +CL_NS_DEF(search) + + class ExactPhraseScorer: public PhraseScorer { + public: + ExactPhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps, int32_t* offsets, + Similarity* similarity, uint8_t* norms ); + + virtual ~ExactPhraseScorer(); + + virtual TCHAR* toString(); + + protected: + //Returns the exact freqency of the phrase + float_t phraseFreq(); + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_FieldCacheImpl.h b/src/core/CLucene/search/_FieldCacheImpl.h new file mode 100644 index 00000000000..98bbcdd41c2 --- /dev/null +++ b/src/core/CLucene/search/_FieldCacheImpl.h @@ -0,0 +1,119 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FieldCacheImpl_ +#define _lucene_search_FieldCacheImpl_ + +CL_CLASS_DEF(index,IndexReader) +CL_CLASS_DEF(search,SortComparator) +CL_CLASS_DEF(search,SortComparatorSource) +#include "FieldCache.h" +#include "CLucene/LuceneThreads.h" +CL_NS_DEF(search) + +class fieldcacheCacheType; + +/** + * Expert: The default cache implementation, storing all values in memory. + * + */ +class FieldCacheImpl: public FieldCache { +public: + DEFINE_MUTEX(THIS_LOCK) + + /** Expert: Every key in the internal cache is of this type. */ + class FileEntry:LUCENE_BASE { + const TCHAR* field; // which Field + int32_t type; // which SortField type + SortComparatorSource* custom; // which custom comparator + size_t _hashCode; + public: + /** Creates one of these objects. */ + FileEntry (const TCHAR* field, int32_t type); + + /** Creates one of these objects for a custom comparator. */ + FileEntry (const TCHAR* field, SortComparatorSource* custom); + ~FileEntry(); + + int32_t getType() const{ return type; } + + /** Two of these are equal iff they reference the same field and type. */ + bool equals (FileEntry* other) const; + + /** Composes a hashcode based on the field and type. */ + size_t hashCode(); + + int32_t compareTo(const FileEntry* other) const; + + class Compare:LUCENE_BASE, public CL_NS(util)::Compare::_base // + { + public: + bool operator()( FileEntry* f1, FileEntry* f2 ) const{ + return ( f1->compareTo(f2) < 0 ); + } + size_t operator()( FileEntry* t ) const{ + return t->hashCode(); + } + }; + class Equals:LUCENE_BASE, public CL_NS(util)::Compare::_base // + { + public: + bool operator()( FileEntry* f1, FileEntry* f2 ) const{ + return ( f1->compareTo(f2) == 0 ); + } + }; + }; + + FieldCacheImpl(); + virtual ~FieldCacheImpl(); +private: + /** The internal cache. Maps FileEntry to array of interpreted term values. **/ + //todo: make indexreader remove itself from here when the reader is shut + fieldcacheCacheType* cache; + + /** See if an object is in the cache. */ + FieldCacheAuto* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type) ; + + /** See if a custom object is in the cache. */ + FieldCacheAuto* lookup (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer); + + /** Put an object into the cache. */ + void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, int32_t type, FieldCacheAuto* value); + + /** Put a custom object into the cache. */ + void store (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparatorSource* comparer, FieldCacheAuto* value); + +public: + + // inherit javadocs + FieldCacheAuto* getInts (CL_NS(index)::IndexReader* reader, const TCHAR* field); + + // inherit javadocs + FieldCacheAuto* getFloats (CL_NS(index)::IndexReader* reader, const TCHAR* field); + + // inherit javadocs + FieldCacheAuto* getStrings (CL_NS(index)::IndexReader* reader, const TCHAR* field); + + // inherit javadocs + FieldCacheAuto* getStringIndex (CL_NS(index)::IndexReader* reader, const TCHAR* field); + + // inherit javadocs + FieldCacheAuto* getAuto (CL_NS(index)::IndexReader* reader, const TCHAR* field); + + // inherit javadocs + FieldCacheAuto* getCustom (CL_NS(index)::IndexReader* reader, const TCHAR* field, SortComparator* comparator); + + + /** + * Callback for when IndexReader closes. This causes + * any cache to be removed for the specified reader. + */ + static void closeCallback(CL_NS(index)::IndexReader* reader, void* fieldCacheImpl); +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_FieldDocSortedHitQueue.h b/src/core/CLucene/search/_FieldDocSortedHitQueue.h new file mode 100644 index 00000000000..a4dae1b209e --- /dev/null +++ b/src/core/CLucene/search/_FieldDocSortedHitQueue.h @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_FieldDocSortedHitQueue_ +#define _lucene_search_FieldDocSortedHitQueue_ + + +#include "Sort.h" +#include "FieldDoc.h" +#include "CLucene/util/PriorityQueue.h" + +CL_NS_DEF(search) + +/** + * Expert: Collects sorted results from Searchable's and collates them. + * The elements put into this queue must be of type FieldDoc. + */ +class FieldDocSortedHitQueue: + public CL_NS(util)::PriorityQueue > +{ +private: + DEFINE_MUTEX(THIS_LOCK) + + // this cannot contain AUTO fields - any AUTO fields should + // have been resolved by the time this class is used. + SortField** fields; + int32_t fieldsLen; + + void _countsize(){ + fieldsLen=0; + while(fields[fieldsLen]!=NULL) + fieldsLen++; + } + + // used in the case where the fields are sorted by locale + // based strings + //todo: not implemented in clucene because locales has not been implemented + //Collator[] collators; //volatile + +public: + /** + * Creates a hit queue sorted by the given list of fields. + * @param fields Field names, in priority order (highest priority first). + * @param size The number of hits to retain. Must be greater than zero. + */ + FieldDocSortedHitQueue (SortField** fields, int32_t size); + ~FieldDocSortedHitQueue(); + + + /** + * Allows redefinition of sort fields if they are NULL. + * This is to handle the case using ParallelMultiSearcher where the + * original list contains AUTO and we don't know the actual sort + * type until the values come back. The fields can only be set once. + * This method is thread safe. + * @param fields + */ + void setFields (SortField** fields); + + /** Returns the fields being used to sort. */ + SortField** getFields() { + return fields; + } + + /** Returns an array of collators, possibly NULL. The collators + * correspond to any SortFields which were given a specific locale. + * @param fields Array of sort fields. + * @return Array, possibly NULL. + + private Collator[] hasCollators (SortField[] fields) { + if (fields == NULL) return NULL; + Collator[] ret = new Collator[fields.length]; + for (int32_t i=0; ia is less relevant than b. + * @param a FieldDoc + * @param b FieldDoc + * @return true if document a should be sorted after document b. + */ + bool lessThan (FieldDoc* docA, FieldDoc* docB); +}; + + +/** +* Expert: Returned by low-level sorted search implementations. +* +* @see Searchable#search(Query,Filter,int32_t,Sort) +*/ +class TopFieldDocs: public TopDocs { +public: + /// The fields which were used to sort results by. + SortField** fields; + + FieldDoc** fieldDocs; + + /** Creates one of these objects. + * @param totalHits Total number of hits for the query. + * @param fieldDocs The top hits for the query. + * @param scoreDocs The top hits for the query. + * @param scoreDocsLen Length of fieldDocs and scoreDocs + * @param fields The sort criteria used to find the top hits. + */ + TopFieldDocs (int32_t totalHits, FieldDoc** fieldDocs, int32_t scoreDocsLen, SortField** fields); + ~TopFieldDocs(); +}; + +CL_NS_END +#endif + diff --git a/src/core/CLucene/search/_HitQueue.h b/src/core/CLucene/search/_HitQueue.h new file mode 100644 index 00000000000..fb46469c238 --- /dev/null +++ b/src/core/CLucene/search/_HitQueue.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_HitQueue_ +#define _lucene_search_HitQueue_ + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_DEF(search) +struct ScoreDoc; + +/** +* An optimised PriorityQueue which takes ScoreDoc structs. Some by-ref passing +* and memory related optimisations have been done. +*/ +class HitQueue: LUCENE_BASE { +private: + ScoreDoc* heap; + size_t _size; + size_t maxSize; + + void upHeap(); + void downHeap(); + +protected: + bool lessThan(struct ScoreDoc& hitA, struct ScoreDoc& hitB); + +public: + void adjustTop(); + struct ScoreDoc& top(); + void put(struct ScoreDoc& element); + ScoreDoc pop(); + /** + * Adds element to the PriorityQueue in log(size) time if either + * the PriorityQueue is not full, or not lessThan(element, top()). + * @param element + * @return true if element is added, false otherwise. + */ + bool insert(struct ScoreDoc& element); + /** + * Returns the number of elements currently stored in the PriorityQueue. + */ + size_t size(); + HitQueue(const int32_t maxSize); + ~HitQueue(); + +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_PhrasePositions.h b/src/core/CLucene/search/_PhrasePositions.h new file mode 100644 index 00000000000..db1f517ce86 --- /dev/null +++ b/src/core/CLucene/search/_PhrasePositions.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_PhrasePositions_ +#define _lucene_search_PhrasePositions_ + +#include "CLucene/index/Terms.h" + +CL_NS_DEF(search) + +/** + * Position of a term in a document that takes into account the term offset within the phrase. + */ +class PhrasePositions:LUCENE_BASE { +public: + int32_t doc; // current doc + int32_t position; // position in doc + int32_t count; // remaining pos in this doc + int32_t offset; // position in phrase + CL_NS(index)::TermPositions* tp; // stream of positions + PhrasePositions* _next; // used to make lists + bool repeats; // there's other pp for same term (e.g. query="1st word 2nd word"~1) + + PhrasePositions(CL_NS(index)::TermPositions* Tp, const int32_t o); + ~PhrasePositions(); + + bool next(); + bool skipTo(int32_t target); + + void firstPosition(); + + /** + * Go to next location of this term current document, and set + * position as location - offset, so that a + * matching exact phrase is easily identified when all PhrasePositions + * have exactly the same position. + */ + bool nextPosition(); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_PhraseQueue.h b/src/core/CLucene/search/_PhraseQueue.h new file mode 100644 index 00000000000..3f7ea3d422c --- /dev/null +++ b/src/core/CLucene/search/_PhraseQueue.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_PhraseQueue_ +#define _lucene_search_PhraseQueue_ + + +#include "CLucene/util/PriorityQueue.h" +#include "_PhrasePositions.h" + +CL_NS_DEF(search) + class PhraseQueue: public CL_NS(util)::PriorityQueue > { + public: + PhraseQueue(const int32_t size) { + initialize(size,false); + } + virtual ~PhraseQueue(){ + } + + protected: + bool lessThan(PhrasePositions* pp1, PhrasePositions* pp2) { + if (pp1->doc == pp2->doc){ + if (pp1->position == pp2->position) + // same doc and pp.position, so decide by actual term positions. + // rely on: pp.position == tp.position - offset. + return pp1->offset < pp2->offset; + else + return pp1->position < pp2->position; + }else + return pp1->doc < pp2->doc; + } + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_PhraseScorer.h b/src/core/CLucene/search/_PhraseScorer.h new file mode 100644 index 00000000000..1760596fef7 --- /dev/null +++ b/src/core/CLucene/search/_PhraseScorer.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_PhraseScorer_ +#define _lucene_search_PhraseScorer_ + +#include "_PhraseQueue.h" +#include "Scorer.h" + +CL_NS_DEF(search) + +class Explanation; +/** Expert: Scoring functionality for phrase queries. +*
A document is considered matching if it contains the phrase-query terms +* at "valid" positons. What "valid positions" are +* depends on the type of the phrase query: for an exact phrase query terms are required +* to appear in adjacent locations, while for a sloppy phrase query some distance between +* the terms is allowed. The abstract method {@link #phraseFreq()} of extending classes +* is invoked for each document containing all the phrase query terms, in order to +* compute the frequency of the phrase query in that document. A non zero frequency +* means a match. +*/ +class PhraseScorer: public Scorer { +private: + Weight* weight; +protected: + uint8_t* norms; + float_t value; +private: + bool firstTime; + bool more; +protected: + float_t freq; //phrase frequency in current doc as computed by phraseFreq(). + + PhraseQueue* pq; //is used to order the list point to by first and last + PhrasePositions* first; //Points to the first in the list of PhrasePositions + PhrasePositions* last; //Points to the last in the list of PhrasePositions + +public: + //Constructor + PhraseScorer(Weight* _weight, CL_NS(index)::TermPositions** tps, + int32_t* offsets, Similarity* similarity, uint8_t* _norms); + virtual ~PhraseScorer(); + + int32_t doc() const; + bool next(); + float_t score(); + bool skipTo(int32_t target); + + + Explanation* explain(int32_t doc); + virtual TCHAR* toString(); +protected: + /** + * For a document containing all the phrase query terms, compute the + * frequency of the phrase in that document. + * A non zero frequency means a match. + *
Note, that containing all phrase terms does not guarantee a match - they have to be found in matching locations. + * @return frequency of the phrase in current doc, 0 if not found. + */ + virtual float_t phraseFreq() =0; + + //Transfers the PhrasePositions from the PhraseQueue pq to + //the PhrasePositions list with first as its first element + void pqToList(); + + //Moves first to the end of the list + void firstToLast(); +private: + bool doNext(); + void init(); + void sort(); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/_SloppyPhraseScorer.h b/src/core/CLucene/search/_SloppyPhraseScorer.h new file mode 100644 index 00000000000..6498475ad81 --- /dev/null +++ b/src/core/CLucene/search/_SloppyPhraseScorer.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_SloppyPhraseScorer_ +#define _lucene_search_SloppyPhraseScorer_ + +#include "_PhraseScorer.h" + +CL_NS_DEF(search) + class SloppyPhraseScorer: public PhraseScorer { + private: + int32_t slop; + PhrasePositions** repeats; + size_t repeatsLen; + bool checkedRepeats; + public: + SloppyPhraseScorer(Weight* weight, CL_NS(index)::TermPositions** tps, + int32_t* offsets, Similarity* similarity, + int32_t _slop, uint8_t* norms); + virtual ~SloppyPhraseScorer(); + protected: + /** + * Score a candidate doc for all slop-valid position-combinations (matches) + * encountered while traversing/hopping the PhrasePositions. + *
The score contribution of a match depends on the distance: + *
- highest score for distance=0 (exact match). + *
- score gets lower as distance gets higher. + *
Example: for query "a b"~2, a document "x a b a y" can be scored twice: + * once for "a b" (distance=0), and once for "b a" (distance=2). + *
Pssibly not all valid combinations are encountered, because for efficiency + * we always propagate the least PhrasePosition. This allows to base on + * PriorityQueue and move forward faster. + * As result, for example, document "a b c b a" + * would score differently for queries "a b c"~4 and "c b a"~4, although + * they really are equivalent. + * Similarly, for doc "a b c b a f g", query "c b"~2 + * would get same score as "g f"~2, although "c b"~2 could be matched twice. + * We may want to fix this in the future (currently not, for performance reasons). + */ + float_t phraseFreq(); + private: + typedef CL_NS(util)::CLHashMap, + CL_NS(util)::Equals::Void > + PhrasePositionsMap; + static int comparePhrasePositions(const void* x, const void* y){ + return static_cast(y)->offset - static_cast(x)->offset; + } + + /** + * Init PhrasePositions in place. + * There is a one time initializatin for this scorer: + *
- Put in repeats[] each pp that has another pp with same position in the doc. + *
- Also mark each such pp by pp.repeats = true. + *
Later can consult with repeats[] in termPositionsDiffer(pp), making that check efficient. + * In particular, this allows to score queries with no repetiotions with no overhead due to this computation. + *
- Example 1 - query with no repetitions: "ho my"~2 + *
- Example 2 - query with repetitions: "ho my my"~2 + *
- Example 3 - query with repetitions: "my ho my"~2 + *
Init per doc w/repeats in query, includes propagating some repeating pp's to avoid false phrase detection. + * @return end (max position), or -1 if any term ran out (i.e. done) + * @throws IOException + */ + int32_t initPhrasePositions(); + + // disalow two pp's to have the same tp position, so that same word twice + // in query would go elswhere in the matched doc + bool termPositionsDiffer(PhrasePositions* pp); + + public: + virtual TCHAR* toString(); + }; +CL_NS_END +#endif + diff --git a/src/core/CLucene/search/_TermScorer.h b/src/core/CLucene/search/_TermScorer.h new file mode 100644 index 00000000000..68133b115b9 --- /dev/null +++ b/src/core/CLucene/search/_TermScorer.h @@ -0,0 +1,82 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_TermScorer_ +#define _lucene_search_TermScorer_ + + +#include "Scorer.h" +#include "CLucene/index/Terms.h" +CL_CLASS_DEF(search,Similarity) +#include "SearchHeader.h" + +CL_NS_DEF(search) + +/** Expert: A Scorer for documents matching a Term. +*/ +class TermScorer: public Scorer { +private: + CL_NS(index)::TermDocs* termDocs; + uint8_t* norms; + Weight* weight; + const float_t weightValue; + int32_t _doc; + + int32_t docs[PFOR_BLOCK_SIZE]; // buffered doc numbers + int32_t freqs[PFOR_BLOCK_SIZE]; // buffered term freqs + int32_t pointer; + int32_t pointerMax; + + float_t scoreCache[LUCENE_SCORE_CACHE_SIZE]; +public: + + /** Construct a TermScorer. + * @param weight The weight of the Term in the query. + * @param td An iterator over the documents matching the Term. + * @param similarity The Similarity implementation to be used for score computations. + * @param norms The field norms of the document fields for the Term. + * + * @memory TermScorer takes TermDocs and deletes it when TermScorer is cleaned up */ + TermScorer(Weight* weight, CL_NS(index)::TermDocs* td, + Similarity* similarity, uint8_t* _norms); + + virtual ~TermScorer(); + + /** Returns the current document number matching the query. + * Initially invalid, until {@link #next()} is called the first time. + */ + int32_t doc() const; + + + /** Advances to the next document matching the query. + *
The iterator over the matching documents is buffered using + * {@link TermDocs#read(int[],int[])}. + * @return true iff there is another document matching the query. + */ + bool next(); + + float_t score(); + + /** Skips to the first match beyond the current whose document number is + * greater than or equal to a given target. + *
The implementation uses {@link TermDocs#skipTo(int)}. + * @param target The target document number. + * @return true iff there is such a match. + */ + bool skipTo(int32_t target); + + /** Returns an explanation of the score for a document. + *
When this method is used, the {@link #next()} method + * and the {@link #score(HitCollector)} method should not be used. + * @param doc The document number for the explanation. + */ + Explanation* explain(int32_t doc); + + /** Returns a string representation of this TermScorer. */ + virtual TCHAR* toString(); +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/search/spans/NearSpansOrdered.cpp b/src/core/CLucene/search/spans/NearSpansOrdered.cpp new file mode 100644 index 00000000000..a745ec2afed --- /dev/null +++ b/src/core/CLucene/search/spans/NearSpansOrdered.cpp @@ -0,0 +1,285 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" + +#include +#include + +#include "_NearSpansOrdered.h" +#include "SpanNearQuery.h" + + +CL_NS_DEF2( search, spans ) + +bool spanDocCompare( Spans * s1, Spans * s2 ) +{ + return s1->doc() < s2->doc(); +} + +NearSpansOrdered::NearSpansOrdered( SpanNearQuery * spanNearQuery, CL_NS(index)::IndexReader * reader ) +{ + firstTime = true; + more = false; + + inSameDoc = false; + + matchDoc = -1; + matchStart = -1; + matchEnd = -1; + + if( spanNearQuery->getClausesCount() < 2 ) + { + TCHAR * tszQry = spanNearQuery->toString(); + size_t bBufLen = _tcslen( tszQry ) + 25; + TCHAR * tszMsg = _CL_NEWARRAY( TCHAR, bBufLen ); + _sntprintf( tszMsg, bBufLen, _T( "Less than 2 clauses: %s" ), tszQry ); + _CLDELETE_LCARRAY( tszQry ); + _CLTHROWT_DEL( CL_ERR_IllegalArgument, tszMsg ); + } + + allowedSlop = spanNearQuery->getSlop(); + + subSpansCount = spanNearQuery->getClausesCount(); + subSpans = _CL_NEWARRAY( Spans *, subSpansCount ); + subSpansByDoc = _CL_NEWARRAY( Spans *, subSpansCount ); + + SpanQuery ** clauses = spanNearQuery->getClauses(); + for( size_t i = 0; i < subSpansCount; i++ ) + { + subSpans[ i ] = clauses[ i ]->getSpans( reader ); + subSpansByDoc[ i ] = subSpans[ i ]; // used in toSameDoc() + } + clauses = NULL; + + query = spanNearQuery; // kept for toString() only. +} + +NearSpansOrdered::~NearSpansOrdered() +{ + for( size_t i = 0; i < subSpansCount; i++ ) + _CLLDELETE( subSpans[ i ] ); + + _CLDELETE_LARRAY( subSpans ); + _CLDELETE_LARRAY( subSpansByDoc ); +} + +bool NearSpansOrdered::next() +{ + if( firstTime ) + { + firstTime = false; + for( size_t i = 0; i < subSpansCount; i++ ) + { + if( ! subSpans[ i ]->next() ) + { + more = false; + return false; + } + } + more = true; + } + return advanceAfterOrdered(); +} + +bool NearSpansOrdered::skipTo( int32_t target ) +{ + if( firstTime ) + { + firstTime = false; + for( size_t i = 0; i < subSpansCount; i++ ) + { + if( ! subSpans[ i ]->skipTo( target )) + { + more = false; + return false; + } + } + more = true; + } + else if( more && ( subSpans[ 0 ]->doc() < target )) + { + if( subSpans[ 0 ]->skipTo( target )) + { + inSameDoc = false; + } + else + { + more = false; + return false; + } + } + return advanceAfterOrdered(); +} + +bool NearSpansOrdered::advanceAfterOrdered() +{ + while( more && ( inSameDoc || toSameDoc() )) + { + if( stretchToOrder() && shrinkToAfterShortestMatch() ) + return true; + } + return false; // no more matches +} + +bool NearSpansOrdered::toSameDoc() +{ + sort( subSpansByDoc, subSpansByDoc + subSpansCount, spanDocCompare ); + size_t firstIndex = 0; + int32_t maxDoc = subSpansByDoc[ subSpansCount-1 ]->doc(); + while( subSpansByDoc[ firstIndex ]->doc() != maxDoc ) + { + if( ! subSpansByDoc[ firstIndex ]->skipTo( maxDoc )) + { + more = false; + inSameDoc = false; + return false; + } + maxDoc = subSpansByDoc[ firstIndex ]->doc(); + if( ++firstIndex == subSpansCount ) + firstIndex = 0; + } + +#ifdef _DEBUG + for( size_t i = 0; i < subSpansCount; i++ ) + { + assert( subSpansByDoc[ i ]->doc() == maxDoc ); +// : " NearSpansOrdered.toSameDoc() spans " + subSpansByDoc[0] +// + "\n at doc " + subSpansByDoc[i].doc() +// + ", but should be at " + maxDoc; + } +#endif //_DEBUG + + inSameDoc = true; + return true; +} + +bool NearSpansOrdered::docSpansOrdered( Spans * spans1, Spans * spans2 ) +{ + assert( spans1->doc() == spans2->doc() ); // "doc1 " + spans1.doc() + " != doc2 " + spans2.doc(); + int32_t start1 = spans1->start(); + int32_t start2 = spans2->start(); + + /* Do not call docSpansOrdered(int,int,int,int) to avoid invoking .end() : */ // CLucene - why? + return ( start1 == start2 ) ? ( spans1->end() < spans2->end() ) : ( start1 < start2 ); +} + +bool NearSpansOrdered::docSpansOrdered(int start1, int end1, int start2, int end2) +{ + return ( start1 == start2 ) ? ( end1 < end2 ) : ( start1 < start2 ); +} + +bool NearSpansOrdered::stretchToOrder() +{ + matchDoc = subSpans[ 0 ]->doc(); + for( size_t i = 1; inSameDoc && ( i < subSpansCount ); i++ ) + { + while( ! docSpansOrdered( subSpans[ i-1 ], subSpans[ i ] )) + { + if( ! subSpans[ i ]->next() ) + { + inSameDoc = false; + more = false; + break; + } + else if( matchDoc != subSpans[ i ]->doc() ) + { + inSameDoc = false; + break; + } + } + } + return inSameDoc; +} + +bool NearSpansOrdered::shrinkToAfterShortestMatch() +{ + matchStart = subSpans[ subSpansCount - 1 ]->start(); + matchEnd = subSpans[ subSpansCount - 1]->end(); + + int32_t matchSlop = 0; + int32_t lastStart = matchStart; + int32_t lastEnd = matchEnd; + + for( int32_t i = (int32_t)subSpansCount - 2; i >= 0; i-- ) + { + Spans * prevSpans = subSpans[ i ]; + int32_t prevStart = prevSpans->start(); + int32_t prevEnd = prevSpans->end(); + + while( true ) // Advance prevSpans until after (lastStart, lastEnd) + { + if( ! prevSpans->next() ) + { + inSameDoc = false; + more = false; + break; // Check remaining subSpans for final match. + } + else if( matchDoc != prevSpans->doc() ) + { + inSameDoc = false; // The last subSpans is not advanced here. + break; // Check remaining subSpans for last match in this document. + } + else + { + int32_t ppStart = prevSpans->start(); + int32_t ppEnd = prevSpans->end(); // Cannot avoid invoking .end() + if( ! docSpansOrdered( ppStart, ppEnd, lastStart, lastEnd )) + { + break; // Check remaining subSpans. + } + else + { // prevSpans still before (lastStart, lastEnd) + prevStart = ppStart; + prevEnd = ppEnd; + } + } + } + + assert( prevStart <= matchStart ); + if( matchStart > prevEnd ) // Only non overlapping spans add to slop. + matchSlop += ( matchStart - prevEnd ); + + /* Do not break on (matchSlop > allowedSlop) here to make sure + * that subSpans[0] is advanced after the match, if any. + */ + matchStart = prevStart; + lastStart = prevStart; + lastEnd = prevEnd; + } + + return matchSlop <= allowedSlop; // ordered and allowed slop +} + +TCHAR* NearSpansOrdered::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszQuery = query->toString(); + + buffer.append( _T( "NearSpansOrdered(" )); + buffer.append( tszQuery ); + buffer.append( _T( ")@" )); + if( firstTime ) + buffer.append( _T( "START" )); + else if( more ) + { + buffer.appendInt( doc() ); + buffer.append( _T( ":" )); + buffer.appendInt( start() ); + buffer.append( _T( "-" )); + buffer.appendInt( end() ); + } + else + buffer.append( _T( "END" )); + + _CLDELETE_ARRAY( tszQuery ); + + return buffer.toString(); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/NearSpansUnordered.cpp b/src/core/CLucene/search/spans/NearSpansUnordered.cpp new file mode 100644 index 00000000000..1fb473383eb --- /dev/null +++ b/src/core/CLucene/search/spans/NearSpansUnordered.cpp @@ -0,0 +1,271 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/util/StringBuffer.h" + +#include "_NearSpansUnordered.h" +#include "_NearSpansOrdered.h" +#include "SpanNearQuery.h" + +CL_NS_DEF2( search, spans ) + + +///////////////////////////////////////////////////////////////////////////// +NearSpansUnordered::SpansCell::SpansCell( NearSpansUnordered * parentSpans, Spans * spans, int32_t index ) +{ + this->parentSpans = parentSpans; + this->spans = spans; + this->index = index; + this->length = -1; +} + +NearSpansUnordered::SpansCell::~SpansCell() +{ + _CLLDELETE( spans ); +} + +bool NearSpansUnordered::SpansCell::adjust( bool condition ) +{ + if( length != -1 ) + parentSpans->totalLength -= length; // subtract old length + + if( condition ) + { + length = end() - start(); + parentSpans->totalLength += length; // add new length + + if( ! parentSpans->max + || doc() > parentSpans->max->doc() + || ( doc() == parentSpans->max->doc() && end() > parentSpans->max->end())) + { + parentSpans->max = this; + } + } + parentSpans->more = condition; + return condition; +} + +TCHAR* NearSpansUnordered::SpansCell::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszSpans = spans->toString(); + + buffer.append( tszSpans ); + buffer.append( _T( "#" )); + buffer.appendInt( index ); + + _CLDELETE_LARRAY( tszSpans ); + return buffer.toString(); +} + + +///////////////////////////////////////////////////////////////////////////// +bool NearSpansUnordered::CellQueue::lessThan(SpansCell * spans1, SpansCell* spans2 ) +{ + if( spans1->doc() == spans2->doc() ) + return NearSpansOrdered::docSpansOrdered( spans1, spans2 ); + else + return spans1->doc() < spans2->doc(); +} + + +///////////////////////////////////////////////////////////////////////////// +NearSpansUnordered::NearSpansUnordered( SpanNearQuery * query, CL_NS(index)::IndexReader * reader ) +{ + // this->ordered = new ArrayList(); + this->more = true; + this->firstTime = true; + + this->max = NULL; // CLucene specific, SpansCell::adjust tests this member to NULL + this->first = NULL; // CLucene specific + this->last = NULL; // CLucene specific, addToList test this member to NULL + this->totalLength = 0; // CLucene specific + + this->query = query; + this->slop = query->getSlop(); + + SpanQuery ** clauses = query->getClauses(); + this->queue = _CLNEW CellQueue( query->getClausesCount() ); + for( size_t i = 0; i < query->getClausesCount(); i++ ) + { + SpansCell * cell = _CLNEW SpansCell( this, clauses[ i ]->getSpans( reader ), i ); + ordered.push_back( cell ); + } + clauses = NULL; +} + +NearSpansUnordered::~NearSpansUnordered() +{ + for( list::iterator iCell = ordered.begin(); iCell != ordered.end(); iCell++ ) + _CLLDELETE( *iCell ); + + _CLLDELETE( queue ); +} + +bool NearSpansUnordered::next() +{ + if( firstTime ) + { + initList( true ); + listToQueue(); // initialize queue + firstTime = false; + } + else if( more ) + { + if( min()->next() ) // trigger further scanning + queue->adjustTop(); // maintain queue + else + more = false; + } + + while( more ) + { + bool queueStale = false; + if( min()->doc() != max->doc() ) // maintain list + { + queueToList(); + queueStale = true; + } + + // skip to doc w/ all clauses + while( more && first->doc() < last->doc() ) + { + more = first->skipTo( last->doc() );// skip first upto last + firstToLast(); // and move it to the end + queueStale = true; + } + + if( ! more ) + return false; + + // found doc w/ all clauses + if( queueStale ) // maintain the queue + { + listToQueue(); + queueStale = false; + } + + if( atMatch() ) + return true; + + more = min()->next(); + if( more ) + queue->adjustTop(); // maintain queue + } + + return false; // no more matches +} + +bool NearSpansUnordered::skipTo( int32_t target ) +{ + if( firstTime ) // initialize + { + initList( false ); + for( SpansCell * cell = first; more && cell; cell = cell->nextCell ) + { + more = cell->skipTo( target ); // skip all + } + + if( more ) + listToQueue(); + + firstTime = false; + } + else + { // normal case + while( more && min()->doc() < target ) // skip as needed + { + if( min()->skipTo( target )) + queue->adjustTop(); + else + more = false; + } + } + + return more && ( atMatch() || next() ); +} + +TCHAR* NearSpansUnordered::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszQuery = query->toString(); + + buffer.append( _T( "NearSpansUnordered(" )); + buffer.append( tszQuery ); + buffer.append( _T( ")@" )); + if( firstTime ) + buffer.append( _T( "START" )); + else if( more ) + { + buffer.appendInt( doc() ); + buffer.append( _T( ":" )); + buffer.appendInt( start() ); + buffer.append( _T( "-" )); + buffer.appendInt( end() ); + } + else + buffer.append( _T( "END" )); + + _CLDELETE_ARRAY( tszQuery ); + + return buffer.toString(); +} + +void NearSpansUnordered::initList( bool next ) +{ + for( list::iterator iCell = ordered.begin(); more && iCell != ordered.end(); iCell++ ) + { + if( next ) + more = (*iCell)->next(); // move to first entry + + if( more ) + addToList( *iCell ); // add to list + } +} + +void NearSpansUnordered::addToList( SpansCell * cell ) +{ + if( last ) // add next to end of list + last->nextCell = cell; + else + first = cell; + + last = cell; + cell->nextCell = NULL; +} + +void NearSpansUnordered::firstToLast() +{ + last->nextCell = first; // move first to end of list + last = first; + first = first->nextCell; + last->nextCell = NULL; +} + +void NearSpansUnordered::queueToList() +{ + last = NULL; + first = NULL; + while( queue->top() ) + addToList( queue->pop() ); +} + +void NearSpansUnordered::listToQueue() +{ + queue->clear(); // rebuild queue + for( SpansCell * cell = first; cell; cell = cell->nextCell ) + queue->put( cell ); // add to queue from list +} + +bool NearSpansUnordered::atMatch() +{ + return ( min()->doc() == max->doc() ) + && (( max->end() - min()->start() - totalLength ) <= slop ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanFirstQuery.cpp b/src/core/CLucene/search/spans/SpanFirstQuery.cpp new file mode 100644 index 00000000000..6921b4b1313 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanFirstQuery.cpp @@ -0,0 +1,205 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanFirstQuery.h" +#include "Spans.h" + +CL_NS_DEF2( search, spans ) + + +///////////////////////////////////////////////////////////////////////////// +class SpanFirstQuery::SpanFirstQuerySpans : public Spans +{ +private: + Spans * spans; + int32_t end_; + SpanFirstQuery * parentQuery; + +public: + SpanFirstQuerySpans( SpanFirstQuery * parentQuery, CL_NS(index)::IndexReader * reader ); + virtual ~SpanFirstQuerySpans(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return spans->doc(); } + int32_t start() const { return spans->start(); } + int32_t end() const { return spans->end(); } + + TCHAR* toString() const; +}; + +SpanFirstQuery::SpanFirstQuerySpans::SpanFirstQuerySpans( SpanFirstQuery * parentQuery, CL_NS(index)::IndexReader * reader ) +{ + this->parentQuery = parentQuery; + this->end_ = parentQuery->end; + this->spans = parentQuery->match->getSpans( reader ); +} + +SpanFirstQuery::SpanFirstQuerySpans::~SpanFirstQuerySpans() +{ + _CLLDELETE( spans ); +} + +bool SpanFirstQuery::SpanFirstQuerySpans::next() +{ + while( spans->next() ) // scan to next match + { + if( spans->end() <= end_ ) + return true; + } + return false; +} + +bool SpanFirstQuery::SpanFirstQuerySpans::skipTo( int32_t target ) +{ + if( ! spans->skipTo( target )) + return false; + + if( spans->end() <= end_ ) // there is a match + return true; + + return next(); // scan to next match +} + +TCHAR* SpanFirstQuery::SpanFirstQuerySpans::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszQry = parentQuery->toString(); + + buffer.append( _T( "spans(" )); + buffer.append( tszQry ); + buffer.append( _T( ")" )); + + _CLDELETE_LARRAY( tszQry ); + return buffer.toString(); +} + + +///////////////////////////////////////////////////////////////////////////// +SpanFirstQuery::SpanFirstQuery( SpanQuery * match, int32_t end, bool bDeleteQuery ) +{ + this->match = match; + this->end = end; + this->bDeleteQuery = bDeleteQuery; +} + +SpanFirstQuery::SpanFirstQuery( const SpanFirstQuery& clone ) : + SpanQuery( clone ) +{ + this->match = (SpanQuery *) clone.match->clone(); + this->end = clone.end; + this->bDeleteQuery = true; +} + +SpanFirstQuery::~SpanFirstQuery() +{ + if( bDeleteQuery ) + { + _CLLDELETE( match ); + } +} + +CL_NS(search)::Query * SpanFirstQuery::clone() const +{ + return _CLNEW SpanFirstQuery( *this ); +} + +const char * SpanFirstQuery::getClassName() +{ + return "SpanFirstQuery"; +} + +const char * SpanFirstQuery::getObjectName() const +{ + return getClassName(); +} + +SpanQuery * SpanFirstQuery::getMatch() const +{ + return match; +} + +int32_t SpanFirstQuery::getEnd() const +{ + return end; +} + +const TCHAR * SpanFirstQuery::getField() const +{ + return match->getField(); +} + +void SpanFirstQuery::extractTerms( CL_NS(search)::TermSet * terms ) const +{ + match->extractTerms( terms ); +} + +CL_NS(search)::Query * SpanFirstQuery::rewrite( CL_NS(index)::IndexReader * reader ) +{ + SpanFirstQuery * clone = NULL; + + SpanQuery * rewritten = (SpanQuery *) match->rewrite( reader ); + if( rewritten != match ) + { + clone = (SpanFirstQuery *) this->clone(); + _CLLDELETE( clone->match ); + clone->match = rewritten; + } + + if( clone ) + return clone; // some clauses rewrote + else + return this; // no clauses rewrote +} + +TCHAR* SpanFirstQuery::toString( const TCHAR* field ) const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszMatch = match->toString( field ); + + buffer.append( _T( "spanFirst(" )); + buffer.append( tszMatch ); + buffer.append( _T( ", " )); + buffer.appendInt( end ); + buffer.append( _T( ")" )); + buffer.appendBoost( getBoost() ); + _CLDELETE_LARRAY( tszMatch ); + + return buffer.toString(); +} + +bool SpanFirstQuery::equals( Query * other ) const +{ + if( this == other ) return true; + if( other == NULL || !( other->instanceOf( SpanFirstQuery::getClassName() ))) + return false; + + SpanFirstQuery * that = (SpanFirstQuery *) other; + return end == that->end + && getBoost() == that->getBoost() + && match->equals( that->match ); +} + +size_t SpanFirstQuery::hashCode() const +{ + size_t h = match->hashCode(); + h ^= (h << 8) | (h >> 25); // reversible + h ^= Similarity::floatToByte( getBoost() ) ^ end; + return h; +} + +Spans * SpanFirstQuery::getSpans( CL_NS(index)::IndexReader * reader ) +{ + return _CLNEW SpanFirstQuerySpans( this, reader ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanFirstQuery.h b/src/core/CLucene/search/spans/SpanFirstQuery.h new file mode 100644 index 00000000000..4b62b9ec048 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanFirstQuery.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_FirstSpanQuery_ +#define _lucene_search_spans_FirstSpanQuery_ + +CL_CLASS_DEF(index, IndexReader); +#include "SpanQuery.h" + +CL_NS_DEF2( search, spans ) + +/** Matches spans near the beginning of a field. */ +class CLUCENE_EXPORT SpanFirstQuery : public SpanQuery +{ +private: + class SpanFirstQuerySpans; + +private: + SpanQuery * match; + bool bDeleteQuery; + int32_t end; + +protected: + SpanFirstQuery( const SpanFirstQuery& clone ); + +public: + /** Construct a SpanFirstQuery matching spans in match whose end + * position is less than or equal to end. */ + SpanFirstQuery( SpanQuery * match, int32_t end, bool bDeleteQuery ); + virtual ~SpanFirstQuery(); + + CL_NS(search)::Query * clone() const; + + static const char * getClassName(); + const char * getObjectName() const; + + /** Return the SpanQuery whose matches are filtered. */ + SpanQuery * getMatch() const; + + /** Return the maximum end position permitted in a match. */ + int32_t getEnd() const; + + const TCHAR * getField() const; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see #extractTerms(Set) + */ +// public Collection getTerms() { return match.getTerms(); } + void extractTerms( CL_NS(search)::TermSet * terms ) const; + + CL_NS(search)::Query * rewrite( CL_NS(index)::IndexReader * reader ); + + using Query::toString; + TCHAR* toString( const TCHAR* field ) const; + bool equals( Query* other ) const; + size_t hashCode() const; + + Spans * getSpans( CL_NS(index)::IndexReader * reader ); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_FirstSpanQuery_ diff --git a/src/core/CLucene/search/spans/SpanNearQuery.cpp b/src/core/CLucene/search/spans/SpanNearQuery.cpp new file mode 100644 index 00000000000..ae676581eb6 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanNearQuery.cpp @@ -0,0 +1,204 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanNearQuery.h" +#include "_EmptySpans.h" +#include "_NearSpansOrdered.h" +#include "_NearSpansUnordered.h" + +CL_NS_DEF2( search, spans ) + +SpanNearQuery::SpanNearQuery( const SpanNearQuery& clone ) : + SpanQuery( clone ) +{ + this->clauses = _CL_NEWARRAY( SpanQuery *, clone.clausesCount ); + for( size_t i = 0; i < clone.clausesCount; i++ ) + this->clauses[ i ] = (SpanQuery *) clone.clauses[ i ]->clone(); + + this->clausesCount = clone.clausesCount; + this->bDeleteClauses = true; + + this->slop = clone.slop; + this->inOrder = clone.inOrder; + + this->field = NULL; + setField( clone.field ); +} + +SpanNearQuery::~SpanNearQuery() +{ + if( bDeleteClauses ) + { + for( size_t i = 0; i < clausesCount; i++ ) + _CLLDELETE( clauses[ i ] ); + } + + clausesCount = 0; + _CLDELETE_LARRAY( clauses ); + _CLDELETE_LARRAY( field ); +} + +CL_NS(search)::Query * SpanNearQuery::clone() const +{ + return _CLNEW SpanNearQuery( *this ); +} + +const char * SpanNearQuery::getClassName() +{ + return "SpanNearQuery"; +} + +const char * SpanNearQuery::getObjectName() const +{ + return getClassName(); +} + +SpanQuery ** SpanNearQuery::getClauses() const +{ + return clauses; +} + +size_t SpanNearQuery::getClausesCount() const +{ + return clausesCount; +} + +void SpanNearQuery::setField( const TCHAR * field ) +{ + _CLDELETE_LARRAY( this->field ); + this->field = STRDUP_TtoT( field ); +} + +const TCHAR * SpanNearQuery::getField() const +{ + return field; +} + +int32_t SpanNearQuery::getSlop() const +{ + return slop; +} + +bool SpanNearQuery::isInOrder() const +{ + return inOrder; +} + +void SpanNearQuery::extractTerms( CL_NS(search)::TermSet * terms ) const +{ + for( size_t i = 0; i < clausesCount; i++ ) + clauses[ i ]->extractTerms( terms ); +} + +CL_NS(search)::Query * SpanNearQuery::rewrite( CL_NS(index)::IndexReader * reader ) +{ + SpanNearQuery * clone = NULL; + + for( size_t i = 0; i < clausesCount; i++ ) + { + SpanQuery * c = clauses[ i ]; + SpanQuery * query = (SpanQuery *) c->rewrite( reader ); + if( query != c ) + { // clause rewrote: must clone + if( clone == NULL ) + clone = (SpanNearQuery *) this->clone(); + + _CLLDELETE( clone->clauses[ i ] ); + clone->clauses[ i ] = query; + } + } + if( clone ) + return clone; // some clauses rewrote + else + return this; // no clauses rewrote +} + +TCHAR* SpanNearQuery::toString( const TCHAR* field ) const +{ + CL_NS(util)::StringBuffer buffer; + + buffer.append( _T( "spanNear([" )); + for( size_t i = 0; i < clausesCount; i++ ) + { + if( i != 0 ) + buffer.append( _T( ", " )); + + TCHAR * tszClause = clauses[ i ]->toString( field ); + buffer.append( tszClause ); + _CLDELETE_ARRAY( tszClause ); + } + + buffer.append( _T( "], " )); + buffer.appendInt( slop ); + buffer.append( _T( ", " )); + buffer.appendBool( inOrder ); + buffer.append( _T( ")" )); + buffer.appendBoost( getBoost() ); + + return buffer.toString(); +} + +bool SpanNearQuery::equals( Query* other ) const +{ + if( this == other ) return true; + if( other == NULL || !( other->instanceOf( SpanNearQuery::getClassName() ))) + return false; + + SpanNearQuery * that = (SpanNearQuery *) other; + if( inOrder != that->inOrder + || slop != that->slop + || getBoost() != that->getBoost() + || 0 != _tcscmp( field, that->field ) ) // CLucene: java version does not compare field names + { + return false; + } + + if( clausesCount != that->clausesCount ) + return false; + for( size_t i = 0; i < clausesCount; i++ ) + { + if( ! clauses[ i ]->equals( that->clauses[ i ] )) + return false; + } + + return true; +} + +size_t SpanNearQuery::hashCode() const +{ + size_t result = 1; + for( size_t i = 0; i < clausesCount; i++ ) + result = 31*result + clauses[ i ]->hashCode(); + + // Mix bits before folding in things like boost, since it could cancel the + // last element of clauses. This particular mix also serves to + // differentiate SpanNearQuery hash codes from others. + result ^= (result << 14) | (result >> 19); // reversible + result += Similarity::floatToByte( getBoost() ); + result += slop; + result ^= ( inOrder ? 0x99AFD3BD : 0 ); + + return result; +} + +Spans * SpanNearQuery::getSpans( CL_NS(index)::IndexReader * reader ) +{ + if( clausesCount == 0 ) + return _CLNEW EmptySpans(); // CLucene: 0-clause case - different to java version, because java creates SpanOrQuery to call its function to create empty spans + + if( clausesCount == 1 ) // optimize 1-clause case + return clauses[ 0 ]->getSpans( reader ); + + return inOrder + ? (Spans *) _CLNEW NearSpansOrdered( this, reader ) + : (Spans *) _CLNEW NearSpansUnordered( this, reader ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanNearQuery.h b/src/core/CLucene/search/spans/SpanNearQuery.h new file mode 100644 index 00000000000..c88b5f7c1a5 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanNearQuery.h @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanNearQuery_ +#define _lucene_search_spans_SpanNearQuery_ + +CL_CLASS_DEF(index, IndexReader); +#include "SpanQuery.h" + +CL_NS_DEF2( search, spans ) + +/** Matches spans which are near one another. One can specify slop, the + * maximum number of intervening unmatched positions, as well as whether + * matches are required to be in-order. */ +class CLUCENE_EXPORT SpanNearQuery : public SpanQuery +{ +private: + SpanQuery ** clauses; + size_t clausesCount; + bool bDeleteClauses; + + int32_t slop; + bool inOrder; + + TCHAR * field; + +protected: + SpanNearQuery( const SpanNearQuery& clone ); + +public: + /** Construct a SpanNearQuery. Matches spans matching a span from each + * clause, with up to slop total unmatched positions between + * them. * When inOrder is true, the spans from each clause + * must be * ordered as in clauses. */ + template + SpanNearQuery( ClauseIterator first, ClauseIterator last, int32_t slop, bool inOrder, bool bDeleteClauses ) + { + // CLucene specific: at least one clause must be here + if( first == last ) + _CLTHROWA( CL_ERR_IllegalArgument, "Missing query clauses." ); + + this->bDeleteClauses = bDeleteClauses; + this->clausesCount = last - first; + this->clauses = _CL_NEWARRAY( SpanQuery *, clausesCount ); + this->field = NULL; + + // copy clauses array into an array and check fields + for( size_t i = 0; first != last; first++, i++ ) + { + SpanQuery * clause = *first; + if( i == 0 ) + { + setField( clause->getField() ); + } + else if( 0 != _tcscmp( clause->getField(), field )) + { + _CLTHROWA( CL_ERR_IllegalArgument, "Clauses must have same field." ); + } + this->clauses[ i ] = clause; + } + + this->slop = slop; + this->inOrder = inOrder; + } + + virtual ~SpanNearQuery(); + + CL_NS(search)::Query * clone() const; + + static const char * getClassName(); + const char * getObjectName() const; + + /** Return the clauses whose spans are matched. + * CLucene: pointer to the internal array + */ + SpanQuery ** getClauses() const; + size_t getClausesCount() const; + + /** Return the maximum number of intervening unmatched positions permitted.*/ + int32_t getSlop() const; + + /** Return true if matches are required to be in-order.*/ + bool isInOrder() const; + + const TCHAR * getField() const; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see #extractTerms(Set) + */ +// public Collection getTerms() + + void extractTerms( CL_NS(search)::TermSet * terms ) const; + + CL_NS(search)::Query * rewrite( CL_NS(index)::IndexReader * reader ); + + using Query::toString; + TCHAR* toString( const TCHAR* field ) const; + bool equals( Query* other ) const; + size_t hashCode() const; + + Spans * getSpans( CL_NS(index)::IndexReader * reader ); + +protected: + void setField( const TCHAR * field ); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanNearQuery_ diff --git a/src/core/CLucene/search/spans/SpanNotQuery.cpp b/src/core/CLucene/search/spans/SpanNotQuery.cpp new file mode 100644 index 00000000000..d751258bb9c --- /dev/null +++ b/src/core/CLucene/search/spans/SpanNotQuery.cpp @@ -0,0 +1,274 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanNotQuery.h" +#include "Spans.h" + +CL_NS_DEF2( search, spans ) + + +///////////////////////////////////////////////////////////////////////////// +class SpanNotQuery::SpanNotQuerySpans : public Spans +{ +private: + SpanNotQuery * parentQuery; + Spans * includeSpans; + bool moreInclude; + + Spans * excludeSpans; + bool moreExclude; + +public: + SpanNotQuerySpans( SpanNotQuery * parentQuery, CL_NS(index)::IndexReader * reader ); + virtual ~SpanNotQuerySpans(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return includeSpans->doc(); } + int32_t start() const { return includeSpans->start(); } + int32_t end() const { return includeSpans->end(); } + + TCHAR* toString() const; +}; + +SpanNotQuery::SpanNotQuerySpans::SpanNotQuerySpans( SpanNotQuery * parentQuery, CL_NS(index)::IndexReader * reader ) +{ + this->parentQuery = parentQuery; + + includeSpans = parentQuery->include->getSpans( reader ); + moreInclude = true; + + excludeSpans = parentQuery->exclude->getSpans( reader ); + moreExclude = excludeSpans->next(); +} + +SpanNotQuery::SpanNotQuerySpans::~SpanNotQuerySpans() +{ + _CLLDELETE( includeSpans ); + _CLLDELETE( excludeSpans ); +} + +bool SpanNotQuery::SpanNotQuerySpans::next() +{ + if( moreInclude ) // move to next include + moreInclude = includeSpans->next(); + + while( moreInclude && moreExclude ) + { + if( includeSpans->doc() > excludeSpans->doc() ) // skip exclude + moreExclude = excludeSpans->skipTo( includeSpans->doc() ); + + while( moreExclude // while exclude is before + && includeSpans->doc() == excludeSpans->doc() + && excludeSpans->end() <= includeSpans->start()) + { + moreExclude = excludeSpans->next(); // increment exclude + } + + if( ! moreExclude // if no intersection + || includeSpans->doc() != excludeSpans->doc() + || includeSpans->end() <= excludeSpans->start()) + break; // we found a match + + moreInclude = includeSpans->next(); // intersected: keep scanning + } + + return moreInclude; +} + + +bool SpanNotQuery::SpanNotQuerySpans::skipTo( int32_t target ) +{ + if( moreInclude ) // skip include + moreInclude = includeSpans->skipTo( target ); + + if( ! moreInclude ) + return false; + + if( moreExclude // skip exclude + && includeSpans->doc() > excludeSpans->doc()) + { + moreExclude = excludeSpans->skipTo( includeSpans->doc() ); + } + + while( moreExclude // while exclude is before + && includeSpans->doc() == excludeSpans->doc() + && excludeSpans->end() <= includeSpans->start()) + { + moreExclude = excludeSpans->next(); // increment exclude + } + + if( ! moreExclude // if no intersection + || includeSpans->doc() != excludeSpans->doc() + || includeSpans->end() <= excludeSpans->start()) + { + return true; // we found a match + } + + return next(); // scan to next match +} + +TCHAR* SpanNotQuery::SpanNotQuerySpans::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszQry = parentQuery->toString(); + + buffer.append( _T( "spans(" )); + buffer.append( tszQry ); + buffer.append( _T( ")" )); + + _CLDELETE_LARRAY( tszQry ); + return buffer.toString(); +} + + +///////////////////////////////////////////////////////////////////////////// +SpanNotQuery::SpanNotQuery( SpanQuery * include, SpanQuery * exclude, bool bDeleteQueries ) +{ + this->include = include; + this->exclude = exclude; + this->bDeleteQueries = bDeleteQueries; + + if( 0 != _tcscmp( include->getField(), exclude->getField())) + _CLTHROWA( CL_ERR_IllegalArgument, "Clauses must have same field." ); +} + +SpanNotQuery::SpanNotQuery( const SpanNotQuery& clone ) : + SpanQuery( clone ) +{ + include = (SpanQuery *) clone.include->clone(); + exclude = (SpanQuery *) clone.exclude->clone(); + bDeleteQueries = true; +} + +SpanNotQuery::~SpanNotQuery() +{ + if( bDeleteQueries ) + { + _CLLDELETE( include ); + _CLLDELETE( exclude ); + } +} + +CL_NS(search)::Query * SpanNotQuery::clone() const +{ + return _CLNEW SpanNotQuery( *this ); +} + +const char * SpanNotQuery::getClassName() +{ + return "SpanNotQuery"; +} + +const char * SpanNotQuery::getObjectName() const +{ + return getClassName(); +} + +SpanQuery * SpanNotQuery::getInclude() const +{ + return include; +} + +SpanQuery * SpanNotQuery::getExclude() const +{ + return exclude; +} + +const TCHAR * SpanNotQuery::getField() const +{ + return include->getField(); +} + +void SpanNotQuery::extractTerms( CL_NS(search)::TermSet * terms ) const +{ + include->extractTerms( terms ); +} + +TCHAR* SpanNotQuery::toString( const TCHAR* field ) const +{ + CL_NS(util)::StringBuffer buffer; + + TCHAR * tmp; + + buffer.append( _T( "spanNot(" )); + tmp = include->toString( field ); + buffer.append( tmp ); + _CLDELETE_ARRAY( tmp ); + + buffer.append( _T( ", " )); + tmp = exclude->toString( field ); + buffer.append( tmp ); + _CLDELETE_ARRAY( tmp ); + + buffer.append( _T( ")" )); + buffer.appendFloat( getBoost(), 1 ); + + return buffer.toString(); +} + +CL_NS(search)::Query * SpanNotQuery::rewrite( CL_NS(index)::IndexReader * reader ) +{ + SpanNotQuery * clone = NULL; + + SpanQuery * rewrittenInclude = (SpanQuery *) include->rewrite( reader ); + if( rewrittenInclude != include ) + { + clone = (SpanNotQuery *) this->clone(); + _CLLDELETE( clone->include ); + clone->include = rewrittenInclude; + } + + SpanQuery * rewrittenExclude = (SpanQuery *) exclude->rewrite( reader ); + if( rewrittenExclude != exclude ) + { + if( ! clone ) + clone = (SpanNotQuery *) this->clone(); + _CLLDELETE( clone->exclude ); + clone->exclude = rewrittenExclude; + } + + if( clone ) + return clone; // some clauses rewrote + else + return this; // no clauses rewrote +} + +bool SpanNotQuery::equals( Query* other ) const +{ + if( this == other ) return true; + if( other == NULL || !( other->instanceOf( SpanNotQuery::getClassName() ))) + return false; + + SpanNotQuery * that = (SpanNotQuery *) other; + return include->equals( that->include ) + && exclude->equals( that->exclude ) + && getBoost() == that->getBoost(); +} + +size_t SpanNotQuery::hashCode() const +{ + size_t h = include->hashCode(); + h = (h << 1) | (h >> 31); // rotate left + h ^= exclude->hashCode(); + h = (h << 1) | (h >> 31); // rotate left + h ^= Similarity::floatToByte( getBoost() ); + + return h; +} + +Spans * SpanNotQuery::getSpans( CL_NS(index)::IndexReader * reader ) +{ + return _CLNEW SpanNotQuerySpans( this, reader ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanNotQuery.h b/src/core/CLucene/search/spans/SpanNotQuery.h new file mode 100644 index 00000000000..22541055e76 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanNotQuery.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanNotQuery_ +#define _lucene_search_spans_SpanNotQuery_ + +CL_CLASS_DEF(index, IndexReader); +#include "SpanQuery.h" + +CL_NS_DEF2( search, spans ) + +/** Removes matches which overlap with another SpanQuery. */ +class CLUCENE_EXPORT SpanNotQuery : public SpanQuery +{ +private: + class SpanNotQuerySpans; + +private: + SpanQuery * include; + SpanQuery * exclude; + bool bDeleteQueries; + +protected: + SpanNotQuery( const SpanNotQuery& clone ); + +public: + /** Construct a SpanNotQuery matching spans from include which + * have no overlap with spans from exclude.*/ + SpanNotQuery( SpanQuery * include, SpanQuery * exclude, bool bDeleteQueries ); + virtual ~SpanNotQuery(); + + CL_NS(search)::Query * clone() const; + + static const char * getClassName(); + const char * getObjectName() const; + + /** Return the SpanQuery whose matches are filtered. */ + SpanQuery * getInclude() const; + + /** Return the SpanQuery whose matches must not overlap those returned. */ + SpanQuery * getExclude() const; + + const TCHAR * getField() const; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see #extractTerms(Set) + */ +// public Collection getTerms() { return include.getTerms(); } + + void extractTerms( CL_NS(search)::TermSet * terms ) const; + + CL_NS(search)::Query * rewrite( CL_NS(index)::IndexReader * reader ); + + using Query::toString; + TCHAR* toString( const TCHAR* field ) const; + bool equals( Query* other ) const; + size_t hashCode() const; + + Spans * getSpans( CL_NS(index)::IndexReader * reader ); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanNotQuery_ diff --git a/src/core/CLucene/search/spans/SpanOrQuery.cpp b/src/core/CLucene/search/spans/SpanOrQuery.cpp new file mode 100644 index 00000000000..05209d53dd6 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanOrQuery.cpp @@ -0,0 +1,304 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/PriorityQueue.h" + +#include "SpanOrQuery.h" +#include "_EmptySpans.h" + + +CL_NS_DEF2( search, spans ) + + +///////////////////////////////////////////////////////////////////////////// +class SpanOrQuery::SpanQueue : public CL_NS(util)::PriorityQueue > +{ +public: + SpanQueue( int32_t size ) { initialize( size, true ); } + virtual ~SpanQueue() {} + +protected: + bool lessThan(Spans* spans1, Spans* spans2 ) + { + if( spans1->doc() == spans2->doc() ) + { + if( spans1->start() == spans2->start()) + return spans1->end() < spans2->end(); + else + return spans1->start() < spans2->start(); + } + else + return spans1->doc() < spans2->doc(); + } +}; + + +///////////////////////////////////////////////////////////////////////////// +class SpanOrQuery::SpanOrQuerySpans : public Spans +{ +private: + SpanQueue * queue; + SpanOrQuery * parentQuery; + CL_NS(index)::IndexReader * reader; + +public: + SpanOrQuerySpans( SpanOrQuery * parentQuery, CL_NS(index)::IndexReader * reader ); + virtual ~SpanOrQuerySpans(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return top()->doc(); } + int32_t start() const { return top()->start(); } + int32_t end() const { return top()->end(); } + + TCHAR* toString() const; + +private: + Spans * top() const { return queue->top(); } + bool initSpanQueue( int32_t target ); +}; + + +SpanOrQuery::SpanOrQuerySpans::SpanOrQuerySpans( SpanOrQuery * parentQuery, CL_NS(index)::IndexReader * reader ) +{ + this->parentQuery = parentQuery; + this->reader = reader; + this->queue = NULL; +} + +SpanOrQuery::SpanOrQuerySpans::~SpanOrQuerySpans() +{ + _CLLDELETE( queue ); +} + +bool SpanOrQuery::SpanOrQuerySpans::next() +{ + if( ! queue ) + return initSpanQueue( -1 ); + + if( queue->size() == 0 ) // all done + return false; + + if( top()->next() ) // move to next + { + queue->adjustTop(); + return true; + } + + _CLLDELETE( queue->pop() ); // exhausted a clause + return queue->size() != 0; +} + +bool SpanOrQuery::SpanOrQuerySpans::skipTo( int32_t target ) +{ + if( ! queue ) + return initSpanQueue( target ); + + while( queue->size() != 0 && top()->doc() < target ) + { + if( top()->skipTo( target )) + queue->adjustTop(); + else + _CLLDELETE( queue->pop() ); + } + + return queue->size() != 0; +} + +TCHAR* SpanOrQuery::SpanOrQuerySpans::toString() const +{ + CL_NS(util)::StringBuffer buffer; + TCHAR * tszQry = parentQuery->toString(); + + buffer.append( _T( "spans(" )); + buffer.append( tszQry ); + buffer.append( _T( ")" )); + + _CLDELETE_LARRAY( tszQry ); + return buffer.toString(); +} + +bool SpanOrQuery::SpanOrQuerySpans::initSpanQueue( int32_t target ) +{ + queue = _CLNEW SpanQueue( parentQuery->clausesCount ); + + for( size_t i = 0; i < parentQuery->clausesCount; i++ ) + { + Spans * spans = parentQuery->clauses[ i ]->getSpans( reader ); + if(( target == -1 && spans->next()) || ( target != -1 && spans->skipTo( target ))) + queue->put( spans ); + else + _CLLDELETE( spans ); + } + return ( queue->size() != 0 ); +} + + +///////////////////////////////////////////////////////////////////////////// +SpanOrQuery::SpanOrQuery( const SpanOrQuery& clone ) : + SpanQuery( clone ) +{ + this->clauses = _CL_NEWARRAY( SpanQuery *, clone.clausesCount ); + for( size_t i = 0; i < clone.clausesCount; i++ ) + this->clauses[ i ] = (SpanQuery *) clone.clauses[ i ]->clone(); + + this->clausesCount = clone.clausesCount; + this->bDeleteClauses = true; + + this->field = NULL; + setField( clone.field ); +} + +SpanOrQuery::~SpanOrQuery() +{ + if( bDeleteClauses ) + { + for( size_t i = 0; i < clausesCount; i++ ) + _CLLDELETE( clauses[ i ] ); + } + + clausesCount = 0; + _CLDELETE_LARRAY( clauses ); + _CLDELETE_LARRAY( field ); +} + +CL_NS(search)::Query * SpanOrQuery::clone() const +{ + return _CLNEW SpanOrQuery( *this ); +} + +const char * SpanOrQuery::getClassName() +{ + return "SpanOrQuery"; +} + +const char * SpanOrQuery::getObjectName() const +{ + return getClassName(); +} + +SpanQuery ** SpanOrQuery::getClauses() const +{ + return clauses; +} + +size_t SpanOrQuery::getClausesCount() const +{ + return clausesCount; +} + +void SpanOrQuery::setField( const TCHAR * field ) +{ + _CLDELETE_LARRAY( this->field ); + this->field = STRDUP_TtoT( field ); +} + +const TCHAR * SpanOrQuery::getField() const +{ + return field; +} + +void SpanOrQuery::extractTerms( CL_NS(search)::TermSet * terms ) const +{ + for( size_t i = 0; i < clausesCount; i++ ) + clauses[ i ]->extractTerms( terms ); +} + +CL_NS(search)::Query * SpanOrQuery::rewrite( CL_NS(index)::IndexReader * reader ) +{ + SpanOrQuery * clone = NULL; + for( size_t i = 0; i < clausesCount; i++ ) + { + SpanQuery * c = clauses[ i ]; + SpanQuery * query = (SpanQuery *) c->rewrite( reader ); + if( query != c ) + { // clause rewrote: must clone + if( clone == NULL ) + clone = (SpanOrQuery *) this->clone(); + + _CLLDELETE( clone->clauses[ i ] ); + clone->clauses[ i ] = query; + } + } + if( clone ) + return clone; // some clauses rewrote + else + return this; // no clauses rewrote +} + +TCHAR* SpanOrQuery::toString( const TCHAR* field ) const +{ + CL_NS(util)::StringBuffer buffer; + + buffer.append( _T( "spanOr([" )); + for( size_t i = 0; i < clausesCount; i++ ) + { + if( i != 0 ) + buffer.append( _T( ", " )); + + TCHAR * tszClause = clauses[ i ]->toString( field ); + buffer.append( tszClause ); + _CLDELETE_ARRAY( tszClause ); + } + + buffer.append( _T( "])" )); + buffer.appendBoost( getBoost() ); + + return buffer.toString(); +} + +bool SpanOrQuery::equals( Query* other ) const +{ + if( this == other ) return true; + if( other == NULL || !( other->instanceOf( SpanOrQuery::getClassName() ))) + return false; + + SpanOrQuery * that = (SpanOrQuery *) other; + if( 0 != _tcscmp( field, that->field ) + || getBoost() != that->getBoost()) + { + return false; + } + + if( clausesCount != that->clausesCount ) + return false; + for( size_t i = 0; i < clausesCount; i++ ) + { + if( ! clauses[ i ]->equals( that->clauses[ i ] )) + return false; + } + + return true; +} + +size_t SpanOrQuery::hashCode() const +{ + size_t h = 1; + for( size_t i = 0; i < clausesCount; i++ ) + h = 31*h + clauses[ i ]->hashCode(); + + h ^= (h << 10) | (h >> 23); + h ^= Similarity::floatToByte( getBoost() ); + + return h; +} + +Spans * SpanOrQuery::getSpans( CL_NS(index)::IndexReader * reader ) +{ + if( clausesCount == 0 ) + return _CLNEW EmptySpans(); // CLucene: 0-clause case + + if( clausesCount == 1 ) // optimize 1-clause case + return clauses[ 0 ]->getSpans( reader ); + + return _CLNEW SpanOrQuerySpans( this, reader ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanOrQuery.h b/src/core/CLucene/search/spans/SpanOrQuery.h new file mode 100644 index 00000000000..ade7a5d5e88 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanOrQuery.h @@ -0,0 +1,104 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanOrQuery_ +#define _lucene_search_spans_SpanOrQuery_ + +CL_CLASS_DEF(index, IndexReader); +#include "SpanQuery.h" + +CL_NS_DEF2( search, spans ) + +/** + * Matches the union of its clauses. + */ +class CLUCENE_EXPORT SpanOrQuery : public SpanQuery +{ +private: + class SpanQueue; + class SpanOrQuerySpans; + +private: + SpanQuery ** clauses; + size_t clausesCount; + bool bDeleteClauses; + + TCHAR * field; + +protected: + SpanOrQuery( const SpanOrQuery& clone ); + +public: + /** Construct a SpanOrQuery merging the provided clauses. */ + template + SpanOrQuery( ClauseIterator first, ClauseIterator last, bool bDeleteClauses ) + { + // CLucene specific: at least one clause must be here + if( first == last ) + _CLTHROWA( CL_ERR_IllegalArgument, "Missing query clauses." ); + + this->bDeleteClauses = bDeleteClauses; + this->clausesCount = last - first; + this->clauses = _CL_NEWARRAY( SpanQuery *, clausesCount ); + this->field = NULL; + + // copy clauses array into an array and check fields + for( size_t i = 0; first != last; first++, i++ ) + { + SpanQuery * clause = *first; + if( i == 0 ) + { + setField( clause->getField() ); + } + else if( 0 != _tcscmp( clause->getField(), field )) + { + _CLTHROWA( CL_ERR_IllegalArgument, "Clauses must have same field." ); + } + this->clauses[ i ] = clause; + } + } + + virtual ~SpanOrQuery(); + + CL_NS(search)::Query * clone() const; + + static const char * getClassName(); + const char * getObjectName() const; + + /** Return the clauses whose spans are matched. + * CLucene: pointer to the internal array + */ + SpanQuery ** getClauses() const; + size_t getClausesCount() const; + + const TCHAR * getField() const; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see #extractTerms(Set) + */ +// public Collection getTerms() + + void extractTerms( CL_NS(search)::TermSet * terms ) const; + + CL_NS(search)::Query * rewrite( CL_NS(index)::IndexReader * reader ); + + using Query::toString; + TCHAR* toString( const TCHAR* field ) const; + bool equals( Query* other ) const; + size_t hashCode() const; + + /** This returns some kind of lazy spans. The set will be evaluated with the first call + * and this query and the given reader must exists at this time + */ + Spans * getSpans( CL_NS(index)::IndexReader * reader ); + +protected: + void setField( const TCHAR * field ); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanOrQuery_ diff --git a/src/core/CLucene/search/spans/SpanQuery.h b/src/core/CLucene/search/spans/SpanQuery.h new file mode 100644 index 00000000000..cb7f20b7f64 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanQuery.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanQuery_ +#define _lucene_search_spans_SpanQuery_ + +#include "CLucene/search/Query.h" +#include "CLucene/search/spans/SpanWeight.h" +CL_CLASS_DEF2( search, spans, Spans ) + +CL_NS_DEF2( search, spans ) + +/** Base class for span-based queries. */ +class CLUCENE_EXPORT SpanQuery : public CL_NS(search)::Query +{ +public: + /** Expert: Returns the matches for this query in an index. Used internally + * to search for spans. */ + virtual Spans * getSpans( CL_NS(index)::IndexReader * reader ) = 0; + + /** Returns the name of the field matched by this query.*/ + virtual const TCHAR* getField() const = 0; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see Query#extractTerms(Set) + */ +// public abstract Collection getTerms(); + + Weight * _createWeight( CL_NS(search)::Searcher * searcher ) + { + return _CLNEW SpanWeight( this, searcher ); + } +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanQuery_ diff --git a/src/core/CLucene/search/spans/SpanScorer.cpp b/src/core/CLucene/search/spans/SpanScorer.cpp new file mode 100644 index 00000000000..feee5663b8d --- /dev/null +++ b/src/core/CLucene/search/spans/SpanScorer.cpp @@ -0,0 +1,122 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/search/Explanation.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanScorer.h" +#include "Spans.h" + +CL_NS_DEF2(search, spans) + +SpanScorer::SpanScorer( Spans * spans, Weight * weight, Similarity * similarity, uint8_t* norms ) : +Scorer( similarity ), firstTime( true ), more( true ) +{ + this->spans = spans; + this->norms = norms; + this->weight = weight; + this->value = weight->getValue(); + doc_ = -1; +} + +SpanScorer::~SpanScorer() +{ + _CLLDELETE( spans ); +} + +bool SpanScorer::next() +{ + if( firstTime ) + { + more = spans->next(); + firstTime = false; + } + return setFreqCurrentDoc(); +} + +bool SpanScorer::skipTo( int32_t target ) +{ + if( firstTime ) + { + more = spans->skipTo( target ); + firstTime = false; + } + + if( ! more ) + return false; + + if( spans->doc() < target ) + { + // setFreqCurrentDoc() leaves spans.doc() ahead + more = spans->skipTo( target ); + } + + return setFreqCurrentDoc(); +} + +bool SpanScorer::setFreqCurrentDoc() +{ + if( ! more ) + return false; + + doc_ = spans->doc(); + freq = 0.0f; + while( more && doc_ == spans->doc() ) + { + int32_t matchLength = spans->end() - spans->start(); + freq += getSimilarity()->sloppyFreq( matchLength ); + more = spans->next(); + } + + return more || ( freq != 0 ); +} + +int32_t SpanScorer::doc() const +{ + return doc_; +} + +float_t SpanScorer::score() +{ + float_t raw = getSimilarity()->tf( freq ) * value; // raw score + return raw * Similarity::decodeNorm( norms[ doc_ ]); // normalize +} + +CL_NS(search)::Explanation * SpanScorer::explain( int32_t docIn ) +{ + Explanation * tfExplanation = _CLNEW Explanation(); + + skipTo( docIn ); + float_t phraseFreq = (doc() == docIn ) ? freq : 0.0f; + tfExplanation->setValue( getSimilarity()->tf( phraseFreq )); + + CL_NS(util)::StringBuffer strBuf( 50 ); + strBuf.append( _T( "tf(phraseFreq=" )); + strBuf.appendFloat( phraseFreq, 2 ); + strBuf.append( _T( ")" )); + tfExplanation->setDescription( strBuf.getBuffer() ); + + return tfExplanation; +} + +TCHAR* SpanScorer::toString() +{ + CL_NS(util)::StringBuffer buf; + buf.append( _T( "SpanScorer(" )); + + TCHAR* tmp = weight->toString(); + buf.append( tmp ); + _CLDELETE_CARRAY( tmp ); + + buf.append( _T( ")" )); + + return buf.toString(); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanScorer.h b/src/core/CLucene/search/spans/SpanScorer.h new file mode 100644 index 00000000000..bd775f6f45c --- /dev/null +++ b/src/core/CLucene/search/spans/SpanScorer.h @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanScorer_ +#define _lucene_search_spans_SpanScorer_ + +#include "CLucene/search/Scorer.h" +CL_CLASS_DEF2(search,spans,Spans) +CL_CLASS_DEF(search,Explanation) +CL_CLASS_DEF(search,Weight) + +CL_NS_DEF2(search, spans) + +/** + * Public for extension only. + */ +class CLUCENE_EXPORT SpanScorer : public CL_NS(search)::Scorer +{ +protected: + Spans * spans; + CL_NS(search)::Weight * weight; + uint8_t* norms; + float_t value; + + bool firstTime; + bool more; + + int32_t doc_; + float_t freq; + + +public: + SpanScorer( Spans * spans, Weight * weight, Similarity * similarity, uint8_t* norms ); + virtual ~SpanScorer(); + + bool next(); + bool skipTo( int32_t target ); + int32_t doc() const; + float_t score(); + CL_NS(search)::Explanation* explain( int32_t docIn ); + TCHAR* toString(); + +protected: + bool setFreqCurrentDoc(); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanScorer_ diff --git a/src/core/CLucene/search/spans/SpanTermQuery.cpp b/src/core/CLucene/search/spans/SpanTermQuery.cpp new file mode 100644 index 00000000000..e7dcc32c5f9 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanTermQuery.cpp @@ -0,0 +1,104 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/Term.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanTermQuery.h" +#include "_TermSpans.h" + +CL_NS_DEF2( search, spans ) + +SpanTermQuery::SpanTermQuery( CL_NS(index)::Term * term ) +{ + this->term = _CL_POINTER( term ); +} + +SpanTermQuery::SpanTermQuery( const SpanTermQuery& clone ) : + SpanQuery( clone ) +{ + this->term = _CL_POINTER( clone.term ); +} + +SpanTermQuery::~SpanTermQuery() +{ + _CLLDECDELETE( term ); +} + +CL_NS(search)::Query * SpanTermQuery::clone() const +{ + return _CLNEW SpanTermQuery( *this ); +} + +const char* SpanTermQuery::getClassName() +{ + return "SpanTermQuery"; +} + +const char* SpanTermQuery::getObjectName() const +{ + return getClassName(); +} + +size_t SpanTermQuery::hashCode() const +{ + return Similarity::floatToByte(getBoost()) ^ term->hashCode() ^ 0xD23FE494; +} + +CL_NS(index)::Term * SpanTermQuery::getTerm( bool pointer ) const +{ + if ( pointer ) + return _CL_POINTER( term ); + else + return term; +} + +const TCHAR * SpanTermQuery::getField() const +{ + return term->field(); +} + +void SpanTermQuery::extractTerms( CL_NS(search)::TermSet * terms ) const +{ + if( term && terms->end() == terms->find( term )) + terms->insert( _CL_POINTER( term )); +} + +Spans * SpanTermQuery::getSpans( CL_NS(index)::IndexReader * reader ) +{ + return _CLNEW TermSpans( reader->termPositions( term ), term ); +} + +TCHAR* SpanTermQuery::toString( const TCHAR* field ) const +{ + CL_NS(util)::StringBuffer buffer; + + if( field && 0 == _tcscmp( term->field(), field )) + buffer.append( term->text() ); + else + { + TCHAR * tszTerm = term->toString(); + buffer.append( tszTerm ); + buffer.appendBoost( getBoost() ); + _CLDELETE_CARRAY( tszTerm ); + } + return buffer.toString(); +} + +bool SpanTermQuery::equals( Query* other ) const +{ + if( !( other->instanceOf( SpanTermQuery::getClassName() ))) + return false; + + SpanTermQuery * that = (SpanTermQuery *) other; + return ( this->getBoost() == that->getBoost() ) + && this->term->equals( that->term ); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanTermQuery.h b/src/core/CLucene/search/spans/SpanTermQuery.h new file mode 100644 index 00000000000..6adf27bc886 --- /dev/null +++ b/src/core/CLucene/search/spans/SpanTermQuery.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanTermQuery_ +#define _lucene_search_spans_SpanTermQuery_ + +CL_CLASS_DEF(index, Term); +CL_CLASS_DEF(index, IndexReader); +#include "SpanQuery.h" + +CL_NS_DEF2( search, spans ) + +/** Matches spans containing a term. */ +class CLUCENE_EXPORT SpanTermQuery : public SpanQuery +{ +protected: + CL_NS(index)::Term * term; + +protected: + SpanTermQuery( const SpanTermQuery& clone ); + +public: + /** Construct a SpanTermQuery matching the named term's spans. */ + SpanTermQuery( CL_NS(index)::Term * term ); + virtual ~SpanTermQuery(); + + static const char * getClassName(); + const char * getObjectName() const; + + /** Return the term whose spans are matched. */ + CL_NS(index)::Term * getTerm( bool pointer=true ) const; + + const TCHAR * getField() const; + + /** Returns a collection of all terms matched by this query. + * @deprecated use extractTerms instead + * @see #extractTerms(Set) + */ +// public Collection getTerms() + + void extractTerms( CL_NS(search)::TermSet * terms ) const; + Spans * getSpans( CL_NS(index)::IndexReader * reader ); + + CL_NS(search)::Query * clone() const; + + /** Returns true iff o is equal to this. */ + bool equals( Query* other ) const; + + /** Returns a hash code value for this object.*/ + size_t hashCode() const; + + TCHAR* toString( const TCHAR* field ) const; +}; + +CL_NS_END2 +#endif //_lucene_search_spans_SpanTermQuery_ diff --git a/src/core/CLucene/search/spans/SpanWeight.cpp b/src/core/CLucene/search/spans/SpanWeight.cpp new file mode 100644 index 00000000000..767721f27ad --- /dev/null +++ b/src/core/CLucene/search/spans/SpanWeight.cpp @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/search/Similarity.h" +#include "CLucene/search/Explanation.h" +#include "CLucene/search/Scorer.h" +#include "CLucene/util/StringBuffer.h" + +#include "SpanWeight.h" +#include "SpanQuery.h" +#include "SpanScorer.h" + +CL_NS_USE(util) +CL_NS_DEF2(search, spans) + +SpanWeight::SpanWeight( SpanQuery * query, CL_NS(search)::Searcher * searcher ) +{ + this->similarity = query->getSimilarity( searcher ); + this->query = query; + + terms = _CLNEW TermSet(); + query->extractTerms( terms ); + idf = similarity->idf( terms->begin(), terms->end(), searcher ); +} + +SpanWeight::~SpanWeight() +{ + for( TermSet::iterator iTerm = terms->begin(); iTerm != terms->end(); iTerm++ ) + _CLLDECDELETE( *iTerm ); + + _CLDELETE( terms ); +} + +CL_NS(search)::Query * SpanWeight::getQuery() +{ + return query; +} + +float_t SpanWeight::getValue() +{ + return value; +} + +float_t SpanWeight::sumOfSquaredWeights() +{ + queryWeight = idf * query->getBoost(); // compute query weight + return queryWeight * queryWeight; // square it +} + +void SpanWeight::normalize( float_t norm ) +{ + queryNorm = norm; + queryWeight *= queryNorm; // normalize query weight + value = queryWeight * idf; // idf for document +} + +CL_NS(search)::Scorer * SpanWeight::scorer( CL_NS(index)::IndexReader* reader ) +{ + return _CLNEW SpanScorer( query->getSpans( reader ), + this, + similarity, + reader->norms( query->getField() )); +} + +CL_NS(search)::Explanation * SpanWeight::explain( CL_NS(index)::IndexReader* reader, int32_t doc ) +{ + ComplexExplanation * result = _CLNEW ComplexExplanation(); + StringBuffer strBuf(100); + + const TCHAR * field = ((SpanQuery *)getQuery())->getField(); + TCHAR * tQry = getQuery()->toString(); + TCHAR * tQryF = getQuery()->toString( field ); + + strBuf.append( _T( "weight(" )); + strBuf.append( tQry ); + strBuf.append( _T( " in " )); + strBuf.appendInt( doc ); + strBuf.append( _T( "), product of:" )); + result->setDescription( strBuf.getBuffer() ); + + CL_NS(util)::StringBuffer docFreqs; + for( TermSet::iterator itTerms = terms->begin(); itTerms != terms->end(); itTerms++ ) + { + CL_NS(index)::Term * term = (*itTerms); + docFreqs.append( term->text()); + docFreqs.append( _T( "=" )); + docFreqs.appendInt( reader->docFreq( term )); + if( itTerms != terms->end() ) + docFreqs.append( _T( " " )); + } + + strBuf.clear(); + strBuf.append( _T( "idf(" )); + strBuf.append( field ); + strBuf.append( _T( ": " )); + strBuf.append( docFreqs.getBuffer()); + strBuf.append( _T( ")" )); + Explanation * idfExpl = _CLNEW Explanation( idf, strBuf.getBuffer() ); + + // explain query weight + Explanation * queryExpl = _CLNEW Explanation(); + strBuf.clear(); + strBuf.append( _T( "queryWeight(" )); + strBuf.append( tQry ); + strBuf.append( _T( "), product of:" )); + queryExpl->setDescription( strBuf.getBuffer() ); + + if( getQuery()->getBoost() != 1.0f ) + queryExpl->addDetail( _CLNEW Explanation( getQuery()->getBoost(), _T( "boost" ))); + + queryExpl->addDetail( idfExpl ); + + Explanation * queryNormExpl = _CLNEW Explanation( queryNorm, _T( "queryNorm" )); + queryExpl->addDetail( queryNormExpl ); + queryExpl->setValue( getQuery()->getBoost() * + idfExpl->getValue() * + queryNormExpl->getValue()); + result->addDetail( queryExpl ); + + // explain field weight + ComplexExplanation * fieldExpl = _CLNEW ComplexExplanation(); + strBuf.clear(); + strBuf.append( _T( "fieldWeight(" )); + strBuf.append( field ); + strBuf.append( _T( ":" )); + strBuf.append( tQryF ); + strBuf.append( _T( " in " )); + strBuf.appendInt( doc ); + strBuf.append( _T( "), product of:" )); + fieldExpl->setDescription( strBuf.getBuffer() ); + + Scorer * pScorer = scorer( reader ); + Explanation * tfExpl = pScorer->explain( doc ); + fieldExpl->addDetail( tfExpl ); + fieldExpl->addDetail( idfExpl->clone() ); + + Explanation * fieldNormExpl = _CLNEW Explanation(); + uint8_t * fieldNorms = reader->norms( field ); + float_t fieldNorm = fieldNorms != NULL ? Similarity::decodeNorm( fieldNorms[ doc ] ) : 0.0f; + fieldNormExpl->setValue( fieldNorm ); + strBuf.clear(); + strBuf.append( _T( "fieldNorm(field=" )); + strBuf.append( field ); + strBuf.append( _T( ", doc=" )); + strBuf.appendInt( doc ); + strBuf.append( _T( ")" )); + fieldNormExpl->setDescription( strBuf.getBuffer()); + fieldExpl->addDetail( fieldNormExpl ); + + fieldExpl->setMatch( tfExpl->isMatch() ); + fieldExpl->setValue( tfExpl->getValue() * + idfExpl->getValue() * + fieldNormExpl->getValue() ); + + _CLLDELETE( pScorer ); + _CLDELETE_LCARRAY( tQry ); + _CLDELETE_LCARRAY( tQryF ); + + if( queryExpl->getValue() == 1.0f ) + { + _CLLDELETE( result ); + return fieldExpl; + } + else + { + result->addDetail( fieldExpl ); + result->setMatch( fieldExpl->getMatch() ); + + // combine them + result->setValue( queryExpl->getValue() * fieldExpl->getValue() ); + return result; + } +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/SpanWeight.h b/src/core/CLucene/search/spans/SpanWeight.h new file mode 100644 index 00000000000..dddd56a642e --- /dev/null +++ b/src/core/CLucene/search/spans/SpanWeight.h @@ -0,0 +1,46 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_SpanWeight_ +#define _lucene_search_spans_SpanWeight_ + +#include "CLucene/search/SearchHeader.h" +#include "CLucene/search/Query.h" +CL_CLASS_DEF2(search,spans,SpanQuery) +CL_CLASS_DEF(search,Similarity) +CL_CLASS_DEF(search,Searcher) + +CL_NS_DEF2(search, spans) + +/** + * Expert-only. Public for use by other weight implementations + */ +class CLUCENE_EXPORT SpanWeight : public CL_NS(search)::Weight +{ +protected: + CL_NS(search)::Similarity * similarity; + float_t value; + float_t idf; + float_t queryNorm; + float_t queryWeight; + + CL_NS(search)::TermSet * terms; + SpanQuery * query; + +public: + SpanWeight( SpanQuery * query, CL_NS(search)::Searcher * searcher ); + virtual ~SpanWeight(); + + CL_NS(search)::Scorer * scorer( CL_NS(index)::IndexReader* reader ); + CL_NS(search)::Explanation * explain( CL_NS(index)::IndexReader* reader, int32_t doc ); + CL_NS(search)::Query * getQuery(); + float_t getValue(); + float_t sumOfSquaredWeights(); + void normalize( float_t norm ); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_SpanWeight_ diff --git a/src/core/CLucene/search/spans/Spans.h b/src/core/CLucene/search/spans/Spans.h new file mode 100644 index 00000000000..f552fc21d07 --- /dev/null +++ b/src/core/CLucene/search/spans/Spans.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_Spans_ +#define _lucene_search_spans_Spans_ + +CL_NS_DEF2( search, spans ) + +/** Expert: an enumeration of span matches. Used to implement span searching. + * Each span represents a range of term positions within a document. Matches + * are enumerated in order, by increasing document number, within that by + * increasing start position and finally by increasing end position. */ +class CLUCENE_EXPORT Spans +{ +public: + /** Empty base destructor */ + virtual ~Spans() {}; + + /** Move to the next match, returning true iff any such exists. */ + virtual bool next() = 0; + + /** Skips to the first match beyond the current, whose document number is + * greater than or equal to target.

Returns true iff there is such + * a match.

Behaves as if written:

+     *   boolean skipTo(int target) {
+     *     do {
+     *       if (!next())
+     * 	     return false;
+     *     } while (target > doc());
+     *     return true;
+     *   }
+     * 
+ * Most implementations are considerably more efficient than that. + */ + virtual bool skipTo( int32_t target ) = 0; + + /** Returns the document number of the current match. Initially invalid. */ + virtual int32_t doc() const = 0; + + /** Returns the start position of the current match. Initially invalid. */ + virtual int32_t start() const = 0; + + /** Returns the end position of the current match. Initially invalid. */ + virtual int32_t end() const = 0; + + /** Returns the string representation of the spans */ + virtual TCHAR* toString() const = 0; +}; + +CL_NS_END2 +#endif // _lucene_search_spans_Spans_ diff --git a/src/core/CLucene/search/spans/TermSpans.cpp b/src/core/CLucene/search/spans/TermSpans.cpp new file mode 100644 index 00000000000..969207b9731 --- /dev/null +++ b/src/core/CLucene/search/spans/TermSpans.cpp @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#include +#include "CLucene/_ApiHeader.h" + +#include + +#include "CLucene/index/Terms.h" +#include "CLucene/index/Term.h" +#include "CLucene/util/StringBuffer.h" + +#include "_TermSpans.h" + +CL_NS_DEF2(search, spans) + +TermSpans::TermSpans( CL_NS(index)::TermPositions * positions, CL_NS(index)::Term * term ) +{ + this->positions = positions; + this->term = _CL_POINTER( term ); + doc_ = -1; + freq = 0; + count = 0; + position = 0; +} + +TermSpans::~TermSpans() +{ + _CLLDELETE( positions ); + _CLLDECDELETE( term ); +} + +bool TermSpans::next() +{ + if( count == freq ) + { + if( ! positions->next()) + { + doc_ = INT_MAX; + return false; + } + doc_ = positions->doc(); + freq = positions->freq(); + count = 0; + } + position = positions->nextPosition(); + count++; + return true; +} + +bool TermSpans::skipTo( int32_t target ) +{ + // are we already at the correct position? + if( doc_ >= target ) + return true; + + if( !positions->skipTo( target )) + { + doc_ = INT_MAX; + return false; + } + + doc_ = positions->doc(); + freq = positions->freq(); + count = 0; + + position = positions->nextPosition(); + count++; + + return true; +} + +TCHAR* TermSpans::toString() const +{ + CL_NS(util)::StringBuffer strBuf( 50 ); + + TCHAR * tszTerm = term->toString(); + strBuf.append( _T( "spans(" )); + strBuf.append( tszTerm ); + strBuf.append( _T( ")@" )); + if( doc_ == -1 ) + strBuf.append( _T( "START" )); + else if( doc_ == INT_MAX ) + strBuf.append( _T( "END" )); + else + { + strBuf.appendInt( doc_ ); + strBuf.append( _T( "-" )); + strBuf.appendInt( position ); + } + _CLDELETE_CARRAY( tszTerm ); + + return strBuf.toString(); +} + +CL_NS_END2 diff --git a/src/core/CLucene/search/spans/_EmptySpans.h b/src/core/CLucene/search/spans/_EmptySpans.h new file mode 100644 index 00000000000..65b0e013084 --- /dev/null +++ b/src/core/CLucene/search/spans/_EmptySpans.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_EmptySpans_ +#define _lucene_search_spans_EmptySpans_ + +#include "Spans.h" +#include + +CL_NS_DEF2( search, spans ) + +/** CLucene specific: Empty span enumeration, used for optimized cases + * when there are no clauses in SpanNearQuery or SpanOrQuery + */ +class EmptySpans : public Spans +{ +public: + EmptySpans() {} + virtual ~ EmptySpans() {} + + bool next() { return false; } + bool skipTo( int32_t target ) { return false; } + + int32_t doc() const { assert( false ); return -1; } + int32_t start() const { assert( false ); return 0; } + int32_t end() const { assert( false ); return 1; } + + TCHAR* toString() const { return STRDUP_TtoT( _T( "spans()" )); } +}; + +CL_NS_END2 +#endif // _lucene_search_spans_EmptySpans_ diff --git a/src/core/CLucene/search/spans/_NearSpansOrdered.h b/src/core/CLucene/search/spans/_NearSpansOrdered.h new file mode 100644 index 00000000000..092b5074168 --- /dev/null +++ b/src/core/CLucene/search/spans/_NearSpansOrdered.h @@ -0,0 +1,106 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_NearSpansOrdered_ +#define _lucene_search_spans_NearSpansOrdered_ + +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF2(search, spans, SpanNearQuery) +#include "Spans.h" + +CL_NS_DEF2( search, spans ) + +/** A Spans that is formed from the ordered subspans of a SpanNearQuery + * where the subspans do not overlap and have a maximum slop between them. + *

+ * The formed spans only contains minimum slop matches.
+ * The matching slop is computed from the distance(s) between + * the non overlapping matching Spans.
+ * Successive matches are always formed from the successive Spans + * of the SpanNearQuery. + *

+ * The formed spans may contain overlaps when the slop is at least 1. + * For example, when querying using + *

t1 t2 t3
+ * with slop at least 1, the fragment: + *
t1 t2 t1 t3 t2 t3
+ * matches twice: + *
t1 t2 .. t3      
+ *
      t1 .. t2 t3
+ */ +class NearSpansOrdered : public Spans +{ +private: + int32_t allowedSlop; + bool firstTime; + bool more; + + /** The spans in the same order as the SpanNearQuery */ + Spans ** subSpans; + size_t subSpansCount; + + /** Indicates that all subSpans have same doc() */ + bool inSameDoc; + + int32_t matchDoc; + int32_t matchStart; + int32_t matchEnd; + + Spans ** subSpansByDoc; + + SpanNearQuery * query; + +public: + NearSpansOrdered( SpanNearQuery * spanNearQuery, CL_NS(index)::IndexReader * reader ); + virtual ~NearSpansOrdered(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return matchDoc; } + int32_t start() const { return matchStart; } + int32_t end() const { return matchEnd; } + + TCHAR* toString() const; + + /** Check whether two Spans in the same document are ordered. + * @param spans1 + * @param spans2 + * @return true iff spans1 starts before spans2 + * or the spans start at the same position, + * and spans1 ends before spans2. + */ + static bool docSpansOrdered( Spans * spans1, Spans * spans2 ); + +private: + /** Advances the subSpans to just after an ordered match with a minimum slop + * that is smaller than the slop allowed by the SpanNearQuery. + * @return true iff there is such a match. + */ + bool advanceAfterOrdered(); + + /** Advance the subSpans to the same document */ + bool toSameDoc(); + + /** Like {@link #docSpansOrdered(Spans,Spans)}, but use the spans + * starts and ends as parameters. + */ + static bool docSpansOrdered( int32_t start1, int32_t end1, int32_t start2, int32_t end2 ); + + /** Order the subSpans within the same document by advancing all later spans + * after the previous one. + */ + bool stretchToOrder(); + + /** The subSpans are ordered in the same doc, so there is a possible match. + * Compute the slop while making the match as short as possible by advancing + * all subSpans except the last one in reverse order. + */ + bool shrinkToAfterShortestMatch(); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_NearSpansOrdered_ diff --git a/src/core/CLucene/search/spans/_NearSpansUnordered.h b/src/core/CLucene/search/spans/_NearSpansUnordered.h new file mode 100644 index 00000000000..a9912f1ec9e --- /dev/null +++ b/src/core/CLucene/search/spans/_NearSpansUnordered.h @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_NearSpansUnordered_ +#define _lucene_search_spans_NearSpansUnordered_ + +CL_CLASS_DEF(index, IndexReader) +CL_CLASS_DEF2(search, spans, SpanNearQuery) +#include "CLucene/util/PriorityQueue.h" +#include "Spans.h" + +CL_NS_DEF2( search, spans ) + +class NearSpansUnordered : public Spans +{ +private: + ///////////////////////////////////////////////////////////////////////////// + class SpansCell : public Spans + { + private: + NearSpansUnordered * parentSpans; + Spans * spans; + int32_t length; + int32_t index; + + public: + SpansCell * nextCell; + + public: + SpansCell( NearSpansUnordered * parentSpans, Spans * spans, int32_t index ); + virtual ~SpansCell(); + + bool next() { return adjust( spans->next() ); } + bool skipTo( int32_t target ) { return adjust( spans->skipTo( target )); } + + int32_t doc() const { return spans->doc(); } + int32_t start() const { return spans->start(); } + int32_t end() const { return spans->end(); } + + TCHAR* toString() const; + + private: + bool adjust( bool condition ); + + }; + + ///////////////////////////////////////////////////////////////////////////// + class CellQueue : public CL_NS(util)::PriorityQueue > + { + public: + CellQueue( int32_t size ) { initialize( size, false ); } // All the span cells will be freed in ~NearSpansUnordered() while frein ordered member + virtual ~CellQueue() {} + + protected: + bool lessThan( SpansCell * spans1, SpansCell* spans2 ); + }; + +private: + SpanNearQuery * query; + + list ordered; // spans in query order + int32_t slop; // from query + + SpansCell * first; // linked list of spans + SpansCell * last; // sorted by doc only + + int32_t totalLength; // sum of current lengths + + CellQueue * queue; // sorted queue of spans + SpansCell * max; // max element in queue + + bool more; // true iff not done + bool firstTime; // true before first next() + +public: + NearSpansUnordered( SpanNearQuery * query, CL_NS(index)::IndexReader * reader ); + virtual ~NearSpansUnordered(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return min()->doc(); } + int32_t start() const { return min()->start(); } + int32_t end() const { return max->end(); } + + TCHAR* toString() const; + +private: + SpansCell * min() const { return queue->top(); } + + void initList( bool next ); + void addToList( SpansCell * cell ); + void firstToLast(); + void queueToList(); + void listToQueue(); + bool atMatch(); +}; + +CL_NS_END2 +#endif // _lucene_search_spans_NearSpansUnordered_ diff --git a/src/core/CLucene/search/spans/_TermSpans.h b/src/core/CLucene/search/spans/_TermSpans.h new file mode 100644 index 00000000000..5a7356a228b --- /dev/null +++ b/src/core/CLucene/search/spans/_TermSpans.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. + ------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TermSpans_ +#define _lucene_search_spans_TermSpans_ + +#include "CLucene/search/spans/Spans.h" +CL_CLASS_DEF(index, TermPositions) +CL_CLASS_DEF(index, Term) + +CL_NS_DEF2(search, spans) + +/** + * Expert: + * Public for extension only + */ +class TermSpans : public Spans +{ +protected: + CL_NS(index)::TermPositions * positions; + CL_NS(index)::Term * term; + int32_t doc_; + int32_t freq; + int32_t count; + int32_t position; + +public: + TermSpans( CL_NS(index)::TermPositions * positions, CL_NS(index)::Term * term ); + virtual ~TermSpans(); + + bool next(); + bool skipTo( int32_t target ); + + int32_t doc() const { return doc_; } + int32_t start() const { return position; } + int32_t end() const { return position + 1; } + + TCHAR* toString() const; + + CL_NS(index)::TermPositions * getPositions() { return positions; } +}; + +CL_NS_END2 +#endif // _lucene_search_spans_TermSpans_ diff --git a/src/core/CLucene/store/ByteArrayDataInput.cpp b/src/core/CLucene/store/ByteArrayDataInput.cpp new file mode 100644 index 00000000000..197bd40e75b --- /dev/null +++ b/src/core/CLucene/store/ByteArrayDataInput.cpp @@ -0,0 +1,148 @@ +#include "ByteArrayDataInput.h" +#include "CLucene/debug/error.h" +#include "CLucene/util/BytesRef.h" + +CL_NS_DEF(store) + +using BytesRef = util::BytesRef; + +ByteArrayDataInput::ByteArrayDataInput(std::vector &b) { + reset(b); +} + +ByteArrayDataInput::ByteArrayDataInput(std::vector &bytes, int offset, + int len) { + reset(bytes, offset, len); +} + +ByteArrayDataInput::ByteArrayDataInput() { reset(BytesRef::EMPTY_BYTES); } + +void ByteArrayDataInput::reset(std::vector& b) { + reset(b, 0, b.size()); +} + +void ByteArrayDataInput::rewind() { pos = 0; } + +int ByteArrayDataInput::getPosition() { return pos; } + +void ByteArrayDataInput::setPosition(int p) { pos = p; } + +void ByteArrayDataInput::reset(std::vector &b, int offset, int len) { + bytes = b; + pos = offset; + limit = offset + len; +} + +int ByteArrayDataInput::length() { return limit; } + +bool ByteArrayDataInput::eof() { return pos == limit; } + +void ByteArrayDataInput::skipBytes(int64_t count) { pos += count; } + +short ByteArrayDataInput::readShort() { + return static_cast(((bytes.at(pos++) & 0xFF) << 8) | + (bytes.at(pos++) & 0xFF)); +} + +int ByteArrayDataInput::readInt() { + return ((bytes.at(pos++) & 0xFF) << 24) | ((bytes.at(pos++) & 0xFF) << 16) | + ((bytes.at(pos++) & 0xFF) << 8) | (bytes.at(pos++) & 0xFF); +} + +int64_t ByteArrayDataInput::readLong() { + int i1 = ((bytes.at(pos++) & 0xff) << 24) | + ((bytes.at(pos++) & 0xff) << 16) | + ((bytes.at(pos++) & 0xff) << 8) | (bytes.at(pos++) & 0xff); + int i2 = ((bytes.at(pos++) & 0xff) << 24) | + ((bytes.at(pos++) & 0xff) << 16) | + ((bytes.at(pos++) & 0xff) << 8) | (bytes.at(pos++) & 0xff); + return ((static_cast(i1)) << 32) | (i2 & 0xFFFFFFFFLL); +} + +int ByteArrayDataInput::readVInt() { + uint8_t b = bytes.at(pos++); + if (b >= 0) { + return b; + } + int i = b & 0x7F; + b = bytes.at(pos++); + i |= (b & 0x7F) << 7; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7F) << 14; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7F) << 21; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + // Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors: + i |= (b & 0x0F) << 28; + if ((b & 0xF0) == 0) { + return i; + } + _CLTHROWA(CL_ERR_Runtime, "Invalid vInt detected (too many bits)"); +} + +int64_t ByteArrayDataInput::readVLong() { + uint8_t b = bytes.at(pos++); + if (b >= 0) { + return b; + } + int64_t i = b & 0x7FLL; + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 7; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 14; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 21; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 28; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 35; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 42; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 49; + if (b >= 0) { + return i; + } + b = bytes.at(pos++); + i |= (b & 0x7FLL) << 56; + if (b >= 0) { + return i; + } + _CLTHROWA(CL_ERR_Runtime, "Invalid vLong detected (negative values disallowed)"); +} + +uint8_t ByteArrayDataInput::readByte() { return bytes.at(pos++); } + +void ByteArrayDataInput::readBytes(std::vector &b, int len, int offset) { + std::copy(bytes.begin() + pos, bytes.begin() + pos + len, b.begin() + offset); + pos += len; +} + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/store/ByteArrayDataInput.h b/src/core/CLucene/store/ByteArrayDataInput.h new file mode 100644 index 00000000000..9c43d6cbbbc --- /dev/null +++ b/src/core/CLucene/store/ByteArrayDataInput.h @@ -0,0 +1,68 @@ +#ifndef _lucene_store_ByteArrayDataInput_ +#define _lucene_store_ByteArrayDataInput_ + +#include "CLucene/SharedHeader.h" + +#include +#include +#include + +CL_NS_DEF(store) +/** + * DataInput backed by a byte array. + * WARNING: This class omits all low-level checks. + * @lucene.experimental + */ +class ByteArrayDataInput { + +private: + std::vector bytes; + + int pos = 0; + int limit = 0; + +public: + explicit ByteArrayDataInput(std::vector &bytes); + + ByteArrayDataInput(std::vector &bytes, int offset, int len); + + ByteArrayDataInput(); + + void reset(std::vector &bytes); + + + // NOTE: sets pos to 0, which is not right if you had + // called reset w/ non-zero offset!! + void rewind(); + + int getPosition(); + + void setPosition(int pos); + + void reset(std::vector &bytes, int offset, int len); + + int length(); + + bool eof(); + + void skipBytes(int64_t count); + + short readShort(); + + int readInt(); + + int64_t readLong(); + + int readVInt(); + + int64_t readVLong(); + + // NOTE: AIOOBE not EOF if you read too much + uint8_t readByte(); + + // NOTE: AIOOBE not EOF if you read too much + void readBytes(std::vector &b, int len, int offset); +}; + +CL_NS_END +#endif \ No newline at end of file diff --git a/src/core/CLucene/store/Directory.cpp b/src/core/CLucene/store/Directory.cpp new file mode 100644 index 00000000000..7fbf4955610 --- /dev/null +++ b/src/core/CLucene/store/Directory.cpp @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "Directory.h" +#include "LockFactory.h" +#include "CLucene/util/Misc.h" + +CL_NS_DEF(store) + + +Directory::Directory(){ + this->lockFactory = NULL; +} +Directory::~Directory(){ + if (lockFactory != NULL) + _CLDELETE(lockFactory); +} + +LuceneLock* Directory::makeLock(const char* name) { + return lockFactory->makeLock( name ); +} + +void Directory::setLockFactory( LockFactory* lockFactory ) { + this->lockFactory = lockFactory; + lockFactory->setLockPrefix( getLockID().c_str() ); +} + +LockFactory* Directory::getLockFactory() { + return lockFactory; +} + +string Directory::getLockID() { + return toString(); +} + +void Directory::clearLock(const char* name) { + if ( lockFactory != NULL ) { + lockFactory->clearLock( name ); + } +} + +bool Directory::deleteFile(const char* name, const bool throwError){ + bool ret = doDeleteFile(name); + if ( !ret && throwError ){ + char buffer[200]; + _snprintf(buffer,200,"couldn't delete %s",name); + _CLTHROWA(CL_ERR_IO, buffer ); + } + return ret; +} +IndexInput* Directory::openInput(const char* name, int32_t bufferSize){ + IndexInput* ret; + CLuceneError err; + if ( ! openInput(name, ret, err, bufferSize) ) + throw err; + return ret; +} +char** Directory::list() const{ + vector names; + + list(&names); + + size_t size = names.size(); + char** ret = _CL_NEWARRAY(char*,size+1); + for ( size_t i=0;i& names) const{ + return list(&names); +} +CL_NS_END diff --git a/src/core/CLucene/store/Directory.h b/src/core/CLucene/store/Directory.h new file mode 100644 index 00000000000..a13cc9119ad --- /dev/null +++ b/src/core/CLucene/store/Directory.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_Directory +#define _lucene_store_Directory + +#include "CLucene/util/Equators.h" +#include "CLucene/LuceneThreads.h" +#include +#include + +CL_CLASS_DEF(store,Lock) +CL_CLASS_DEF(store,IndexInput) +CL_CLASS_DEF(store,IndexOutput) +CL_CLASS_DEF(store,LockFactory) +CL_CLASS_DEF(store,LuceneLock) + +CL_NS_DEF(store) + + /** A Directory is a flat list of files. Files may be written once, when they + * are created. Once a file is created it may only be opened for read, or + * deleted. Random access is permitted both when reading and writing. + * + *

Direct i/o is not used directly, but rather all i/o is + * through this API. This permits things such as:

    + *
  • implementation of RAM-based indices; + *
  • implementation indices stored in a database, via a database; + *
  • implementation of an index as a single file; + *
+ * + */ +class CLUCENE_EXPORT Directory: LUCENE_REFBASE, public CL_NS(util)::NamedObject { + protected: + LockFactory* lockFactory; + + Directory(); + // Removes an existing file in the directory. + virtual bool doDeleteFile(const char* name) = 0; + public: + DEFINE_MUTEX(THIS_LOCK) + + virtual ~Directory(); + + // Returns an null terminated array of strings, one for each file in the directory. + char** list() const; + virtual bool list(std::vector* names) const = 0; //todo: deprecate this... + bool list(std::vector& names) const; + + // Returns true iff a file with the given name exists. + virtual bool fileExists(const char* name) const = 0; + + // Returns the time the named file was last modified. + virtual int64_t fileModified(const char* name) const = 0; + + // Returns the length of a file in the directory. + virtual int64_t fileLength(const char* name) const = 0; + + // An advanced overload to avoid throwing an error. if result is false, error is filled with the reason + virtual bool openInput(const char* name, IndexInput*& ret, CLuceneError& error, int32_t bufferSize = -1) = 0; + + // Returns a stream reading an existing file. + IndexInput* openInput(const char* name, int32_t bufferSize=-1); + + /// Set the modified time of an existing file to now. */ + virtual void touchFile(const char* name) = 0; + + // Removes an existing file in the directory. + virtual bool deleteFile(const char* name, const bool throwError=true); + + // Renames an existing file in the directory. + // If a file already exists with the new name, then it is replaced. + // This replacement should be atomic. + virtual void renameFile(const char* from, const char* to) = 0; + + // Creates a new, empty file in the directory with the given name. + // Returns a stream writing this file. + virtual IndexOutput* createOutput(const char* name) = 0; + + // Construct a {@link Lock}. + // @param name the name of the lock file + virtual LuceneLock* makeLock(const char* name); + + virtual void clearLock(const char* name); + + // Closes the store. + virtual void close() = 0; + + virtual std::string toString() const = 0; + + void setLockFactory( LockFactory* lockFactory ); + + LockFactory* getLockFactory(); + + virtual std::string getLockID(); + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/store/FSDirectory.cpp b/src/core/CLucene/store/FSDirectory.cpp new file mode 100644 index 00000000000..4b520c9809a --- /dev/null +++ b/src/core/CLucene/store/FSDirectory.cpp @@ -0,0 +1,693 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include +#ifdef _CL_HAVE_IO_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#include + +#include + +#include "FSDirectory.h" +#include "LockFactory.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/IndexWriter.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/_MD5Digester.h" + +#ifdef LUCENE_FS_MMAP + #include "_MMapIndexInput.h" +#endif + +CL_NS_DEF(store) +CL_NS_USE(util) + + /** This cache of directories ensures that there is a unique Directory + * instance per path, so that synchronization on the Directory can be used to + * synchronize access between readers and writers. + */ + static CL_NS(util)::CLHashMap DIRECTORIES(false,false); + STATIC_DEFINE_MUTEX(DIRECTORIES_LOCK) + + bool FSDirectory::disableLocks=false; + + class FSDirectory::FSIndexInput:public BufferedIndexInput { + /** + * We used a shared handle between all the fsindexinput clones. + * This reduces number of file handles we need, and it means + * we dont have to use file tell (which is slow) before doing + * a read. + * TODO: get rid of this and dup/fctnl or something like that... + */ + class SharedHandle: LUCENE_REFBASE{ + public: + int32_t fhandle; + int64_t _length; + int64_t _fpos; + DEFINE_MUTEX(*SHARED_LOCK) + char path[CL_MAX_DIR]; //todo: this is only used for cloning, better to get information from the fhandle + SharedHandle(const char* path); + ~SharedHandle(); + }; + SharedHandle* handle; + int64_t _pos; + FSIndexInput(SharedHandle* handle, int32_t __bufferSize): + BufferedIndexInput(__bufferSize) + { + this->_pos = 0; + this->handle = handle; + }; + protected: + FSIndexInput(const FSIndexInput& clone); + public: + static bool open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t bufferSize=-1); + ~FSIndexInput(); + + IndexInput* clone() const; + void close(); + int64_t length() const { return handle->_length; } + + const char* getDirectoryType() const{ return FSDirectory::getClassName(); } + const char* getObjectName() const{ return getClassName(); } + static const char* getClassName() { return "FSIndexInput"; } + protected: + // Random-access methods + void seekInternal(const int64_t position); + // IndexInput methods + void readInternal(uint8_t* b, const int32_t len); + }; + + class FSDirectory::FSIndexOutput: public BufferedIndexOutput { + private: + int32_t fhandle; + protected: + // output methods: + void flushBuffer(const uint8_t* b, const int32_t size); + public: + FSIndexOutput(const char* path, int filemode); + ~FSIndexOutput(); + + // output methods: + void close(); + + // Random-access methods + void seek(const int64_t pos); + int64_t length() const; + }; + + bool FSDirectory::FSIndexInput::open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize ) { + //Func - Constructor. + // Opens the file named path + //Pre - path != NULL + //Post - if the file could not be opened an exception is thrown. + + CND_PRECONDITION(path != NULL, "path is NULL"); + + if ( __bufferSize == -1 ) + __bufferSize = CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE; + SharedHandle* handle = _CLNEW SharedHandle(path); + + //Open the file + handle->fhandle = ::_cl_open(path, _O_BINARY | O_RDONLY | _O_RANDOM, _S_IREAD ); + + //Check if a valid handle was retrieved + if (handle->fhandle >= 0){ + //Store the file length + handle->_length = fileSize(handle->fhandle); + if ( handle->_length == -1 ) + error.set( CL_ERR_IO,"fileStat error" ); + else{ + handle->_fpos = 0; + ret = _CLNEW FSIndexInput(handle, __bufferSize); + return true; + } + }else{ + int err = errno; + if ( err == ENOENT ) + error.set(CL_ERR_IO, "File does not exist"); + else if ( err == EACCES ) + error.set(CL_ERR_IO, "File Access denied"); + else if ( err == EMFILE ) + error.set(CL_ERR_IO, "Too many open files"); + else + error.set(CL_ERR_IO, "Could not open file"); + } +#ifndef _CL_DISABLE_MULTITHREADING + delete handle->SHARED_LOCK; +#endif + _CLDECDELETE(handle); + return false; + } + + FSDirectory::FSIndexInput::FSIndexInput(const FSIndexInput& other): BufferedIndexInput(other){ + //Func - Constructor + // Uses clone for its initialization + //Pre - clone is a valide instance of FSIndexInput + //Post - The instance has been created and initialized by clone + if ( other.handle == NULL ) + _CLTHROWA(CL_ERR_NullPointer, "other handle is null"); + + SCOPED_LOCK_MUTEX(*other.handle->SHARED_LOCK) + handle = _CL_POINTER(other.handle); + _pos = other.handle->_fpos; //note where we are currently... + } + + FSDirectory::FSIndexInput::SharedHandle::SharedHandle(const char* path){ + fhandle = 0; + _length = 0; + _fpos = 0; + strcpy(this->path,path); + +#ifndef _CL_DISABLE_MULTITHREADING + SHARED_LOCK = new _LUCENE_THREADMUTEX; +#endif + } + FSDirectory::FSIndexInput::SharedHandle::~SharedHandle() { + if ( fhandle >= 0 ){ + if ( ::_close(fhandle) != 0 ) + _CLTHROWA(CL_ERR_IO, "File IO Close error"); + else + fhandle = -1; + } + } + + FSDirectory::FSIndexInput::~FSIndexInput(){ + //Func - Destructor + //Pre - True + //Post - The file for which this instance is responsible has been closed. + // The instance has been destroyed + + FSIndexInput::close(); + } + + IndexInput* FSDirectory::FSIndexInput::clone() const + { + return _CLNEW FSDirectory::FSIndexInput(*this); + } + void FSDirectory::FSIndexInput::close() { + BufferedIndexInput::close(); +#ifndef _CL_DISABLE_MULTITHREADING + if ( handle != NULL ){ + //here we have a bit of a problem... we need to lock the handle to ensure that we can + //safely delete the handle... but if we delete the handle, then the scoped unlock, + //won't be able to unlock the mutex... + + //take a reference of the lock object... + _LUCENE_THREADMUTEX* mutex = handle->SHARED_LOCK; + //lock the mutex + mutex->lock(); + + //determine if we are about to delete the handle... + bool dounlock = ( _LUCENE_ATOMIC_INT_GET(handle->__cl_refcount) > 1 ); + + //decdelete (deletes if refcount is down to 0 + _CLDECDELETE(handle); + + //printf("handle=%d\n", handle->__cl_refcount); + if ( dounlock ){ + mutex->unlock(); + }else{ + delete mutex; + } + } +#else + _CLDECDELETE(handle); +#endif + } + + void FSDirectory::FSIndexInput::seekInternal(const int64_t position) { + CND_PRECONDITION(position>=0 &&position_length,"Seeking out of range") + _pos = position; + } + +/** IndexInput methods */ +void FSDirectory::FSIndexInput::readInternal(uint8_t* b, const int32_t len) { + CND_PRECONDITION(handle!=NULL,"shared file handle has closed"); + CND_PRECONDITION(handle->fhandle>=0,"file is not open"); + SCOPED_LOCK_MUTEX(*handle->SHARED_LOCK) + + if ( handle->_fpos != _pos ){ + if ( fileSeek(handle->fhandle,_pos,SEEK_SET) != _pos ){ + _CLTHROWA( CL_ERR_IO, "File IO Seek error"); + } + handle->_fpos = _pos; + } + + bufferLength = _read(handle->fhandle,b,len); // 2004.10.31:SF 1037836 + if (bufferLength == 0){ + _CLTHROWA(CL_ERR_IO, "read past EOF"); + } + if (bufferLength == -1){ + //if (EINTR == errno) we could do something else... but we have + //to guarantee some return, or throw EOF + + _CLTHROWA(CL_ERR_IO, "read error"); + } + _pos+=bufferLength; + handle->_fpos=_pos; +} + + FSDirectory::FSIndexOutput::FSIndexOutput(const char* path, int filemode){ + //O_BINARY - Opens file in binary (untranslated) mode + //O_CREAT - Creates and opens new file for writing. Has no effect if file specified by filename exists + //O_RANDOM - Specifies that caching is optimized for, but not restricted to, random access from disk. + //O_WRONLY - Opens file for writing only; + if ( filemode <= 0 ){ + filemode = 0644; + } + if ( Misc::dir_Exists(path) ) + fhandle = _cl_open( path, _O_BINARY | O_RDWR | _O_RANDOM | O_TRUNC, filemode); + else // added by JBP + fhandle = _cl_open( path, _O_BINARY | O_RDWR | _O_RANDOM | O_CREAT, filemode); + + if ( fhandle < 0 ){ + int err = errno; + if ( err == ENOENT ) + _CLTHROWA(CL_ERR_IO, "File does not exist"); + else if ( err == EACCES ) + _CLTHROWA(CL_ERR_IO, "File Access denied"); + else if ( err == EMFILE ) + _CLTHROWA(CL_ERR_IO, "Too many open files"); + } + } + FSDirectory::FSIndexOutput::~FSIndexOutput(){ + if ( fhandle >= 0 ){ + try { + FSIndexOutput::close(); + }catch(CLuceneError& err){ + //ignore IO errors... + if ( err.number() != CL_ERR_IO ) + throw; + } + } + } + + /** output methods: */ + void FSDirectory::FSIndexOutput::flushBuffer(const uint8_t* b, const int32_t size) { + CND_PRECONDITION(fhandle>=0,"file is not open"); + if ( size > 0 && _write(fhandle,b,size) != size ) + _CLTHROWA(CL_ERR_IO, "File IO Write error"); + } + void FSDirectory::FSIndexOutput::close() { + try{ + BufferedIndexOutput::close(); + }catch(CLuceneError& err){ + //ignore IO errors... + if ( err.number() != CL_ERR_IO ) + throw; + } + + if ( ::_close(fhandle) != 0 ) + _CLTHROWA(CL_ERR_IO, "File IO Close error"); + else + fhandle = -1; //-1 now indicates closed + } + + void FSDirectory::FSIndexOutput::seek(const int64_t pos) { + CND_PRECONDITION(fhandle>=0,"file is not open"); + BufferedIndexOutput::seek(pos); + int64_t ret = fileSeek(fhandle,pos,SEEK_SET); + if ( ret != pos ){ + _CLTHROWA(CL_ERR_IO, "File IO Seek error"); + } + } + int64_t FSDirectory::FSIndexOutput::length() const { + CND_PRECONDITION(fhandle>=0,"file is not open"); + return fileSize(fhandle); + } + + + const char* FSDirectory::LOCK_DIR=NULL; + const char* FSDirectory::getLockDir(){ + #ifdef LUCENE_LOCK_DIR + LOCK_DIR = LUCENE_LOCK_DIR; + #else + #ifdef LUCENE_LOCK_DIR_ENV_1 + if ( LOCK_DIR == NULL ) + LOCK_DIR = getenv(LUCENE_LOCK_DIR_ENV_1); + #endif + #ifdef LUCENE_LOCK_DIR_ENV_2 + if ( LOCK_DIR == NULL ) + LOCK_DIR = getenv(LUCENE_LOCK_DIR_ENV_2); + #endif + #ifdef LUCENE_LOCK_DIR_ENV_FALLBACK + if ( LOCK_DIR == NULL ) + LOCK_DIR=LUCENE_LOCK_DIR_ENV_FALLBACK; + #endif + if ( LOCK_DIR == NULL ) + _CLTHROWA(CL_ERR_IO, "Couldn't get determine lock dir"); + #endif + + return LOCK_DIR; + } + + FSDirectory::FSDirectory(): + Directory(), + refCount(0), + useMMap(LUCENE_USE_MMAP) + { + filemode = 0644; + this->lockFactory = NULL; + } + + void FSDirectory::init(const char* _path, LockFactory* lockFactory) + { + directory = _path; + bool doClearLockID = false; + + if ( lockFactory == NULL ) { + if ( disableLocks ) { + lockFactory = NoLockFactory::getNoLockFactory(); + } else { + lockFactory = _CLNEW FSLockFactory( directory.c_str(), this->filemode ); + doClearLockID = true; + } + } + + setLockFactory( lockFactory ); + + if ( doClearLockID ) { + lockFactory->setLockPrefix(NULL); + } + + if (!Misc::dir_Exists(directory.c_str())){ + char* err = _CL_NEWARRAY(char,19+directory.length()+1); //19: len of " is not a directory" + strcpy(err,directory.c_str()); + strcat(err," is not a directory"); + _CLTHROWA_DEL(CL_ERR_IO, err ); + } + } + + + void FSDirectory::create(){ + SCOPED_LOCK_MUTEX(THIS_LOCK) + + //clear old files + vector files; + Misc::listFiles(directory.c_str(), files, false); + vector::iterator itr = files.begin(); + while ( itr != files.end() ){ + if ( CL_NS(index)::IndexReader::isLuceneFile(itr->c_str()) ){ + if ( _unlink( (directory + PATH_DELIMITERA + *itr).c_str() ) == -1 ) { + _CLTHROWA(CL_ERR_IO, "Couldn't delete file "); //todo: make richer error + } + } + itr++; + } + lockFactory->clearLock( CL_NS(index)::IndexWriter::WRITE_LOCK_NAME ); + + } + + void FSDirectory::priv_getFN(char* buffer, const char* name) const{ + buffer[0] = 0; + strcpy(buffer,directory.c_str()); + strcat(buffer, PATH_DELIMITERA ); + strcat(buffer,name); + } + + FSDirectory::~FSDirectory(){ + } + + void FSDirectory::setFileMode(int mode){ + this->filemode = mode; + } + int FSDirectory::getFileMode(){ + return this->filemode; + } + void FSDirectory::setUseMMap(bool value){ useMMap = value; } + bool FSDirectory::getUseMMap() const{ return useMMap; } + const char* FSDirectory::getClassName(){ + return "FSDirectory"; + } + const char* FSDirectory::getObjectName() const{ + return getClassName(); + } + + void FSDirectory::setDisableLocks(bool doDisableLocks) { disableLocks = doDisableLocks; } + bool FSDirectory::getDisableLocks() { return disableLocks; } + + + bool FSDirectory::list(vector* names) const{ //todo: fix this, ugly!!! + CND_PRECONDITION(!directory.empty(),"directory is not open"); + return Misc::listFiles(directory.c_str(), *names, false); + } + + bool FSDirectory::fileExists(const char* name) const { + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + char fl[CL_MAX_DIR]; + priv_getFN(fl, name); + return Misc::dir_Exists( fl ); + } + + const char* FSDirectory::getDirName() const{ + return directory.c_str(); + } + + FSDirectory* FSDirectory::getDirectory(const char* file, bool create, LockFactory* lockFactory){ + FSDirectory* dir = getDirectory(file, (LockFactory*)NULL); + + // This is now deprecated (creation should only be done + // by IndexWriter): + if (create) { + dir->create(); + } + + return dir; + } + //static + FSDirectory* FSDirectory::getDirectory(const char* _file, LockFactory* lockFactory){ + FSDirectory* dir = NULL; + { + if ( !_file || !*_file ) + _CLTHROWA(CL_ERR_IO,"Invalid directory"); + + char buf[CL_MAX_PATH]; + char* file = _realpath(_file,buf);//set a realpath so that if we change directory, we can still function + if ( !file || !*file ){ + strncpy(buf, _file, CL_MAX_PATH); + file = buf; + } + + struct cl_stat_t fstat; + if ( fileStat(file,&fstat) == 0 && !(fstat.st_mode & S_IFDIR) ){ + char tmp[1024]; + _snprintf(tmp,1024,"%s not a directory", file); + _CLTHROWA(CL_ERR_IO,tmp); + } + + if ( fileStat(file,&fstat) != 0 ) { + //todo: should construct directory using _mkdirs... have to write replacement + if ( _mkdir(file) == -1 ){ + string err = "Couldn't create directory: "; + err += string(file); + _CLTHROWA(CL_ERR_IO, err.c_str() ); + } + } + + + SCOPED_LOCK_MUTEX(DIRECTORIES_LOCK) + dir = DIRECTORIES.get(file); + if ( dir == NULL ){ + dir = _CLNEW FSDirectory(); + dir->init(file,lockFactory); + DIRECTORIES.put( dir->directory.c_str(), dir); + } else { + if ( lockFactory != NULL && lockFactory != dir->getLockFactory() ) { + _CLTHROWA(CL_ERR_IO,"Directory was previously created with a different LockFactory instance, please pass NULL as the lockFactory instance and use setLockFactory to change it"); + } + } + + { + SCOPED_LOCK_MUTEX(dir->THIS_LOCK) + dir->refCount++; + } + } + + return _CL_POINTER(dir); // TODO: Isn't this a double ref increment? + } + + int64_t FSDirectory::fileModified(const char* name) const { + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + struct cl_stat_t buf; + char buffer[CL_MAX_DIR]; + priv_getFN(buffer,name); + if (fileStat( buffer, &buf ) == -1 ) + return 0; + else + return buf.st_mtime; + } + + //static + int64_t FSDirectory::fileModified(const char* dir, const char* name){ + struct cl_stat_t buf; + char buffer[CL_MAX_DIR]; + _snprintf(buffer,CL_MAX_DIR,"%s%s%s",dir,PATH_DELIMITERA,name); + fileStat( buffer, &buf ); + return buf.st_mtime; + } + + void FSDirectory::touchFile(const char* name){ + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + char buffer[CL_MAX_DIR]; + _snprintf(buffer,CL_MAX_DIR,"%s%s%s",directory.c_str(),PATH_DELIMITERA,name); + + int32_t r = _cl_open(buffer, O_RDWR, this->filemode); + if ( r < 0 ) + _CLTHROWA(CL_ERR_IO,"IO Error while touching file"); + ::_close(r); + } + + int64_t FSDirectory::fileLength(const char* name) const { + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + struct cl_stat_t buf; + char buffer[CL_MAX_DIR]; + priv_getFN(buffer,name); + if ( fileStat( buffer, &buf ) == -1 ) + return 0; + else + return buf.st_size; + } + + bool FSDirectory::openInput(const char * name, IndexInput *& ret, CLuceneError& error, int32_t bufferSize) + { + CND_PRECONDITION(directory[0]!=0,"directory is not open") + char fl[CL_MAX_DIR]; + priv_getFN(fl, name); +#ifdef LUCENE_FS_MMAP + //todo: do some tests here... like if the file + //is >2gb, then some system cannot mmap the file + //also some file systems mmap will fail?? could detect here too + if ( useMMap && Misc::file_Size(fl) < LUCENE_INT32_MAX_SHOULDBE ) //todo: would this be bigger on 64bit systems?. i suppose it would be...test first + return MMapIndexInput::open( fl, ret, error, bufferSize ); + else +#endif + return FSIndexInput::open( fl, ret, error, bufferSize ); + } + + void FSDirectory::close(){ + SCOPED_LOCK_MUTEX(DIRECTORIES_LOCK) + { + THIS_LOCK.lock(); + + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + + if (--refCount <= 0 ) {//refcount starts at 1 + Directory* dir = DIRECTORIES.get(getDirName()); + if(dir){ + DIRECTORIES.remove( getDirName() ); //this will be removed in ~FSDirectory + _CLDECDELETE(dir); + //NOTE: Don't unlock the mutex, since it has been destroyed now... + return; + } + } + THIS_LOCK.unlock(); + } + } + + /** + * So we can do some byte-to-hexchar conversion below + */ + char HEX_DIGITS[] = + {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + + char* FSDirectory::getLockPrefix() const{ + char dirName[CL_MAX_PATH]; // name to be hashed + if ( _realpath(directory.c_str(),dirName) == NULL ){ + _CLTHROWA(CL_ERR_Runtime,"Invalid directory path"); + } + + //to make a compatible name with jlucene, we need to make some changes... + if ( dirName[1] == ':' ) + dirName[0] = (char)_totupper((char)dirName[0]); + + char* smd5 = MD5String(dirName); + + char* ret=_CL_NEWARRAY(char,32+7+1); //32=2*16, 7=strlen("lucene-") + strcpy(ret,"lucene-"); + strcat(ret,smd5); + + _CLDELETE_CaARRAY(smd5); + + return ret; + } + + bool FSDirectory::doDeleteFile(const char* name) { + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + char fl[CL_MAX_DIR]; + priv_getFN(fl, name); + return _unlink(fl) != -1; + } + + void FSDirectory::renameFile(const char* from, const char* to){ + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + SCOPED_LOCK_MUTEX(THIS_LOCK) + char old[CL_MAX_DIR]; + priv_getFN(old, from); + + char nu[CL_MAX_DIR]; + priv_getFN(nu, to); + + /* This is not atomic. If the program crashes between the call to + delete() and the call to renameTo() then we're screwed, but I've + been unable to figure out how else to do this... */ + + if ( Misc::dir_Exists(nu) ){ + //we run this sequence of unlinking an arbitary 100 times + //on some platforms (namely windows), there can be a + //delay between unlink and dir_exists==false + if( Misc::file_Unlink( nu ) == -1 ) { + char* err = _CL_NEWARRAY(char,16+strlen(to)+1); //16: len of "couldn't delete " + strcpy(err,"couldn't delete "); + strcat(err,to); + _CLTHROWA_DEL(CL_ERR_IO, err ); + } + } + if ( _rename(old,nu) != 0 ){ + //todo: jlucene has some extra rename code - if the rename fails, it copies + //the whole file to the new file... might want to implement that if renaming + //fails on some platforms + char buffer[20+CL_MAX_PATH+CL_MAX_PATH]; + strcpy(buffer,"couldn't rename "); + strcat(buffer,from); + strcat(buffer," to "); + strcat(buffer,nu); + _CLTHROWA(CL_ERR_IO, buffer ); + } + } + + IndexOutput* FSDirectory::createOutput(const char* name) { + CND_PRECONDITION(directory[0]!=0,"directory is not open"); + char fl[CL_MAX_DIR]; + priv_getFN(fl, name); + if ( Misc::dir_Exists(fl) ){ + if ( Misc::file_Unlink( fl, 1 ) == -1 ) { + char tmp[1024]; + strcpy(tmp, "Cannot overwrite: "); + strcat(tmp, name); + _CLTHROWA(CL_ERR_IO, tmp); + } + assert( ! Misc::dir_Exists(fl) ); + } + return _CLNEW FSIndexOutput( fl, this->filemode ); + } + + string FSDirectory::toString() const{ + return string("FSDirectory@") + this->directory; + } + +CL_NS_END diff --git a/src/core/CLucene/store/FSDirectory.h b/src/core/CLucene/store/FSDirectory.h new file mode 100644 index 00000000000..13b5f784ab2 --- /dev/null +++ b/src/core/CLucene/store/FSDirectory.h @@ -0,0 +1,168 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_FSDirectory_ +#define _lucene_store_FSDirectory_ + +#include "Directory.h" +#include "IndexInput.h" +#include "IndexOutput.h" +#include +#include + +CL_CLASS_DEF(util,StringBuffer) + + CL_NS_DEF(store) + + /** + * Straightforward implementation of {@link lucene::store::Directory} as a directory of files. + *

If the system property 'disableLuceneLocks' has the String value of + * "true", lock creation will be disabled. + * + * @see Directory + */ + class CLUCENE_EXPORT FSDirectory:public Directory{ + private: + class FSIndexOutput; + class FSIndexInput; + friend class FSDirectory::FSIndexOutput; + friend class FSDirectory::FSIndexInput; + + int filemode; + protected: + FSDirectory(); + virtual void init(const char* path, LockFactory* lockFactory = NULL); + void priv_getFN(char* buffer, const char* name) const; + private: + std::string directory; + int refCount; + void create(); + + static const char* LOCK_DIR; + static const char* getLockDir(); + char* getLockPrefix() const; + static bool disableLocks; + + bool useMMap; + + protected: + /// Removes an existing file in the directory. + bool doDeleteFile(const char* name); + + public: + ///Destructor - only call this if you are sure the directory + ///is not being used anymore. Otherwise use the ref-counting + ///facilities of _CLDECDELETE + virtual ~FSDirectory(); + + /// Get a list of strings, one for each file in the directory. + bool list(std::vector* names) const; + + /// Returns true iff a file with the given name exists. + bool fileExists(const char* name) const; + + /// Returns the text name of the directory + const char* getDirName() const; ///Directories are cached, so that, for a given canonical path, the same + FSDirectory instance will always be returned. This permits + synchronization on directories. + + @param file the path to the directory. + @param create if true, create, or erase any existing contents. + @return the FSDirectory for the named file. + */ + static FSDirectory* getDirectory(const char* file, LockFactory* lockFactory=NULL); + + /// Returns the time the named file was last modified. + int64_t fileModified(const char* name) const; + + //static + /// Returns the time the named file was last modified. + static int64_t fileModified(const char* dir, const char* name); + + //static + /// Returns the length in bytes of a file in the directory. + int64_t fileLength(const char* name) const; + + /// Returns a stream reading an existing file. + virtual bool openInput(const char* name, IndexInput*& ret, CLuceneError& err, int32_t bufferSize = -1); + + /// Renames an existing file in the directory. + void renameFile(const char* from, const char* to); + + /** Set the modified time of an existing file to now. */ + void touchFile(const char* name); + + /// Creates a new, empty file in the directory with the given name. + /// Returns a stream writing this file. + virtual IndexOutput* createOutput(const char* name); + + ///Decrease the ref-count to the directory by one. If + ///the object is no longer needed, then the object is + ///removed from the directory pool. + void close(); + + /** + * If MMap is available, this can disable use of + * mmap reading. + */ + void setUseMMap(bool value); + /** + * Gets whether the directory is using MMap for inputstreams. + */ + bool getUseMMap() const; + + std::string toString() const; + + static const char* getClassName(); + const char* getObjectName() const; + + /** + * Set whether Lucene's use of lock files is disabled. By default, + * lock files are enabled. They should only be disabled if the index + * is on a read-only medium like a CD-ROM. + */ + static void setDisableLocks(bool doDisableLocks); + + /** + * Returns whether Lucene's use of lock files is disabled. + * @return true if locks are disabled, false if locks are enabled. + */ + static bool getDisableLocks(); + + /** + * Sets the file mode for new files. This is passed to new output streams + * and to the lock factory. The mode should be a valid octal file mode for + * the 3rd parameter of the file open function (such as 0644) + * + * Tip: _tcstoi64(_T("644"), NULL, 8) is also a valid way of + * creating a file mode + */ + void setFileMode(int mode); + + /** + * Gets the file mode for new files + */ + int getFileMode(); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/store/IndexInput.cpp b/src/core/CLucene/store/IndexInput.cpp new file mode 100644 index 00000000000..eebd8387a0f --- /dev/null +++ b/src/core/CLucene/store/IndexInput.cpp @@ -0,0 +1,323 @@ + /*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexInput.h" +#include "IndexOutput.h" +#include "CLucene/util/Misc.h" + +CL_NS_DEF(store) +CL_NS_USE(util) + + IndexInput::IndexInput(): + NamedObject() + { + } + IndexInput::~IndexInput() + { + } + IndexInput::IndexInput(const IndexInput& /*other*/) + { + } + + int32_t IndexInput::readInt() { + int32_t b = (readByte() << 24); + b |= (readByte() << 16); + b |= (readByte() << 8); + return (b | readByte()); + } + + short IndexInput::readShort() + { + return static_cast(((readByte() & 0xFF) << 8) | (readByte() & 0xFF)); + } + + int32_t IndexInput::readVInt() { + uint8_t b = readByte(); + int32_t i = b & 0x7F; + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { + b = readByte(); + i |= (b & 0x7F) << shift; + } + return i; + } + + int64_t IndexInput::readLong() { + int64_t i = ((int64_t)readInt() << 32); + return (i | ((int64_t)readInt() & 0xFFFFFFFFL)); + } + + int64_t IndexInput::readVLong() { + uint8_t b = readByte(); + int64_t i = b & 0x7F; + for (int32_t shift = 7; (b & 0x80) != 0; shift += 7) { + b = readByte(); + i |= (((int64_t)b) & 0x7FL) << shift; + } + return i; + } + + void IndexInput::skipChars( const int32_t count) { + for (int32_t i = 0; i < count; i++) { + TCHAR b = readByte(); + if ((b & 0x80) == 0) { + // Do Nothing. + } else if ((b & 0xE0) != 0xE0) { + readByte(); + } else { + readByte(); + readByte(); + } + } +} + + #ifdef _UCS2 + int32_t IndexInput::readString(char* buffer, const int32_t maxLength){ + TCHAR* buf = _CL_NEWARRAY(TCHAR,maxLength); + int32_t ret = -1; + try{ + ret = readString(buf,maxLength); + STRCPY_TtoA(buffer,buf,ret+1); + }_CLFINALLY ( _CLDELETE_CARRAY(buf); ) + return ret; + } + #endif + + int32_t IndexInput::readString(TCHAR* buffer, const int32_t maxLength){ + int32_t len = readVInt(); + int32_t ml=maxLength-1; + if ( len >= ml ){ + readChars(buffer, 0, ml); + buffer[ml] = 0; + //we have to finish reading all the data for this string! + if ( len-ml > 0 ){ + //seek(getFilePointer()+(len-ml)); <- that was the wrong way to "finish reading" + skipChars(len-ml); + } + return ml; + }else{ + readChars(buffer, 0, len); + buffer[len] = 0; + return len; + } + } + + TCHAR* IndexInput::readString(){ + int32_t len = readVInt(); + + if ( len == 0){ + return stringDuplicate(LUCENE_BLANK_STRING); + } + + TCHAR* ret = _CL_NEWARRAY(TCHAR,len+1); + readChars(ret, 0, len); + ret[len] = 0; + + return ret; + } + + void IndexInput::readBytes( uint8_t* b, const int32_t len, bool /*useBuffer*/) { + // Default to ignoring useBuffer entirely + readBytes(b, len); + } + + void IndexInput::readBytes( uint8_t* b, const int32_t len, int32_t offset, bool /*useBuffer*/) { + // Default to ignoring useBuffer entirely + readBytes(b, len, offset); + } + + void IndexInput::readChars( TCHAR* buffer, const int32_t start, const int32_t len) { + const int32_t end = start + len; + TCHAR b; + for (int32_t i = start; i < end; ++i) { + b = readByte(); + if ((b & 0x80) == 0) { + b = (b & 0x7F); + } else if ((b & 0xE0) != 0xE0) { + b = (((b & 0x1F) << 6) + | (readByte() & 0x3F)); + } else { + b = ((b & 0x0F) << 12) | ((readByte() & 0x3F) << 6); + b |= (readByte() & 0x3F); + } + buffer[i] = b; + } + } + + + + + + +BufferedIndexInput::BufferedIndexInput(int32_t _bufferSize): + buffer(NULL), + bufferSize(_bufferSize>=0?_bufferSize:CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE), + bufferStart(0), + bufferLength(0), + bufferPosition(0) + { + } + + BufferedIndexInput::BufferedIndexInput(const BufferedIndexInput& other): + IndexInput(other), + buffer(NULL), + bufferSize(other.bufferSize), + bufferStart(other.bufferStart), + bufferLength(other.bufferLength), + bufferPosition(other.bufferPosition) + { + /* DSR: Does the fact that sometime clone.buffer is not NULL even when + ** clone.bufferLength is zero indicate memory corruption/leakage? + ** if ( clone.buffer != NULL) { */ + if (other.bufferLength != 0 && other.buffer != NULL) { + //buffer = _CL_NEWARRAY(uint8_t,bufferLength); + buffer = _CL_NEWARRAY(uint8_t,bufferSize); + memcpy(buffer,other.buffer,bufferLength * sizeof(uint8_t)); + } + } + + const char* BufferedIndexInput::getObjectName(){ return getClassName(); } + const char* BufferedIndexInput::getClassName(){ return "BufferedIndexInput"; } + + void BufferedIndexInput::readBytes(uint8_t* b, const int32_t len){ + readBytes(b, len, 0, true); + } + void BufferedIndexInput::readBytes(uint8_t* b, const int32_t len, int32_t offset){ + readBytes(b, len, offset, true); + } + void BufferedIndexInput::readBytes(uint8_t* _b, const int32_t _len, bool useBuffer) { + readBytes(_b, _len, 0, useBuffer); + } + void BufferedIndexInput::readBytes(uint8_t* _b, const int32_t _len, int32_t offset, bool useBuffer){ + int32_t len = _len; + uint8_t* b = _b; + + if(len <= (bufferLength-bufferPosition)){ + // the buffer contains enough data to satisfy this request + if(len>0) // to allow b to be null if len is 0... + memcpy(b + offset, buffer + bufferPosition, len); + bufferPosition+=len; + } else { + // the buffer does not have enough data. First serve all we've got. + int32_t available = bufferLength - bufferPosition; + if(available > 0){ + memcpy(b + offset, buffer + bufferPosition, available); + b += available; + len -= available; + bufferPosition += available; + } + // and now, read the remaining 'len' bytes: + if (useBuffer && len length()) + _CLTHROWA(CL_ERR_IO, "read past EOF"); + readInternal(b + offset, len); + bufferStart = after; + bufferPosition = 0; + bufferLength = 0; // trigger refill() on read + } + } + } + + int64_t BufferedIndexInput::getFilePointer() const{ + return bufferStart + bufferPosition; + } + + void BufferedIndexInput::seek(const int64_t pos) { + if ( pos < 0 ) + _CLTHROWA(CL_ERR_IO, "IO Argument Error. Value must be a positive value."); + if (pos >= bufferStart && pos < (bufferStart + bufferLength)) + bufferPosition = (int32_t)(pos - bufferStart); // seek within buffer + else { + bufferStart = pos; + bufferPosition = 0; + bufferLength = 0; // trigger refill() on read() + seekInternal(pos); + } + } + void BufferedIndexInput::close(){ + _CLDELETE_ARRAY(buffer); + bufferLength = 0; + bufferPosition = 0; + bufferStart = 0; + } + + + BufferedIndexInput::~BufferedIndexInput(){ + BufferedIndexInput::close(); + } + + void BufferedIndexInput::refill() { + int64_t start = bufferStart + bufferPosition; + int64_t end = start + bufferSize; + if (end > length()) // don't read past EOF + end = length(); + bufferLength = (int32_t)(end - start); + if (bufferLength <= 0) + _CLTHROWA(CL_ERR_IO, "IndexInput read past EOF"); + + if (buffer == NULL){ + buffer = _CL_NEWARRAY(uint8_t,bufferSize); // allocate buffer lazily + } + readInternal(buffer, bufferLength); + + + bufferStart = start; + bufferPosition = 0; + } + + void BufferedIndexInput::setBufferSize( int32_t newSize ) { + + if ( newSize != bufferSize ) { + bufferSize = newSize; + if ( buffer != NULL ) { + + uint8_t* newBuffer = _CL_NEWARRAY( uint8_t, newSize ); + int32_t leftInBuffer = bufferLength - bufferPosition; + int32_t numToCopy; + + if ( leftInBuffer > newSize ) { + numToCopy = newSize; + } else { + numToCopy = leftInBuffer; + } + + memcpy( (void*)newBuffer, (void*)(buffer + bufferPosition), numToCopy ); + + bufferStart += bufferPosition; + bufferPosition = 0; + bufferLength = numToCopy; + + _CLDELETE_ARRAY( buffer ); + buffer = newBuffer; + + } + } + + } + +CL_NS_END + diff --git a/src/core/CLucene/store/IndexInput.h b/src/core/CLucene/store/IndexInput.h new file mode 100644 index 00000000000..3a12ae934e3 --- /dev/null +++ b/src/core/CLucene/store/IndexInput.h @@ -0,0 +1,202 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_IndexInput_ +#define _lucene_store_IndexInput_ + +#include "CLucene/LuceneThreads.h" +#include "CLucene/util/Equators.h" + +CL_NS_DEF(store) + + /** Abstract base class for input from a file in a {@link lucene::store::Directory}. A + * random-access input stream. Used for all Lucene index input operations. + * @see Directory + * @see IndexOutput + */ + class CLUCENE_EXPORT IndexInput: LUCENE_BASE, public CL_NS(util)::NamedObject { + protected: + IndexInput(); + IndexInput(const IndexInput& clone); + public: + virtual ~IndexInput(); + virtual IndexInput* clone() const =0; + + DEFINE_MUTEX(THIS_LOCK) + + /** Reads and returns a single byte. + * @see IndexOutput#writeByte(byte) + */ + virtual uint8_t readByte() =0; + + + /** Reads a specified number of bytes into an array at the specified offset. + * @param b the array to read bytes into + * @param offset the offset in the array to start storing bytes + * @param len the number of bytes to read + * @see IndexOutput#writeBytes(byte[],int) + */ + virtual void readBytes(uint8_t* b, const int32_t len, int32_t offset) = 0; + + virtual void readBytes(uint8_t* b, const int32_t len) = 0; + + /** Reads a specified number of bytes into an array at the + * specified offset with control over whether the read + * should be buffered (callers who have their own buffer + * should pass in "false" for useBuffer). Currently only + * {@link BufferedIndexInput} respects this parameter. + * @param b the array to read bytes into + * @param offset the offset in the array to start storing bytes + * @param len the number of bytes to read + * @param useBuffer set to false if the caller will handle + * buffering. + * @see IndexOutput#writeBytes(byte[],int32_t) + */ + virtual void readBytes(uint8_t* b, const int32_t len, bool useBuffer); + virtual void readBytes(uint8_t* b, const int32_t len, int32_t offset, bool useBuffer); + + /** Reads four bytes and returns an int. + * @see IndexOutput#writeInt(int32_t) + */ + int32_t readInt(); + + /** Reads an int stored in variable-length format. Reads between one and + * five bytes. Smaller values take fewer bytes. Negative numbers are not + * supported. + * @see IndexOutput#writeVInt(int32_t) + */ + virtual int32_t readVInt(); + + /** Reads eight bytes and returns a long. + * @see IndexOutput#writeLong(long) + */ + int64_t readLong(); + + /** Reads a long stored in variable-length format. Reads between one and + * nine bytes. Smaller values take fewer bytes. Negative numbers are not + * supported. */ + int64_t readVLong(); + + /** Reads a string + * @see IndexOutput#writeString(String) + * maxLength is the amount read into the buffer, the whole string is still read from the stream + * returns the amount read + */ + int32_t readString(TCHAR* buffer, const int32_t maxlength); + + #ifdef _UCS2 + /** Reads a string and converts to ascii. + * @see IndexOutput#writeString(String) + * maxLength is the amount read into the buffer, the whole string is still read from the stream + * returns the amount read + */ + int32_t readString(char* buffer, const int32_t maxlength); + #endif + + /** Reads a string. + * @see IndexOutput#writeString(String) + */ + TCHAR* readString(); + + /** Reads UTF-8 encoded characters into an array. + * @param buffer the array to read characters into + * @param start the offset in the array to start storing characters + * @param length the number of characters to read + * @see IndexOutput#writeChars(String,int32_t,int32_t) + */ + void readChars( TCHAR* buffer, const int32_t start, const int32_t len); + + void skipChars( const int32_t count); + + /** Closes the stream to futher operations. */ + virtual void close() =0; + + /** Returns the current position in this file, where the next read will + * occur. + * @see #seek(int64_t) + */ + virtual int64_t getFilePointer() const =0; + + /** Sets current position in this file, where the next read will occur. + * @see #getFilePointer() + */ + virtual void seek(const int64_t pos) =0; + + /** The number of bytes in the file. */ + virtual int64_t length() const = 0; + + virtual const char* getDirectoryType() const = 0; + virtual const char* getObjectName() const = 0; + short readShort(); + }; + + /** Abstract base class for input from a file in a {@link Directory}. A + * random-access input stream. Used for all Lucene index input operations. + * @see Directory + * @see IndexOutput + */ + class CLUCENE_EXPORT BufferedIndexInput: public IndexInput{ + private: + uint8_t* buffer; //array of bytes + void refill(); + protected: + int32_t bufferSize; //size of the buffer + int64_t bufferStart; // position in file of buffer + int32_t bufferLength; // end of valid l_byte_ts + int32_t bufferPosition; // next uint8_t to read + + /** Returns a clone of this stream. + * + *

Clones of a stream access the same data, and are positioned at the same + * point as the stream they were cloned from. + * + *

Expert: Subclasses must ensure that clones may be positioned at + * different points in the input from each other and from the stream they + * were cloned from. + */ + BufferedIndexInput(const BufferedIndexInput& clone); + BufferedIndexInput(int32_t bufferSize = -1); + public: + LUCENE_STATIC_CONSTANT(int32_t, BUFFER_SIZE=LUCENE_STREAM_BUFFER_SIZE); + + virtual ~BufferedIndexInput(); + virtual IndexInput* clone() const = 0; + void close(); + inline uint8_t readByte(){ + if (bufferPosition >= bufferLength) + refill(); + + return buffer[bufferPosition++]; + } + void readBytes(uint8_t* b, const int32_t len); + void readBytes(uint8_t* b, const int32_t len, bool useBuffer); + void readBytes(uint8_t* b, const int32_t len, int32_t offset); + void readBytes(uint8_t* b, const int32_t len, int32_t offset, bool useBuffer); + int64_t getFilePointer() const; + void seek(const int64_t pos); + + void setBufferSize( int32_t newSize ); + + const char* getObjectName(); + static const char* getClassName(); + + protected: + /** Expert: implements buffer refill. Reads bytes from the current position + * in the input. + * @param b the array to read bytes into + * @param offset the offset in the array to start storing bytes + * @param length the number of bytes to read + */ + virtual void readInternal(uint8_t* b, const int32_t len) = 0; + + /** Expert: implements seek. Sets current position in this file, where the + * next {@link #readInternal(byte[],int32_t,int32_t)} will occur. + * @see #readInternal(byte[],int32_t,int32_t) + */ + virtual void seekInternal(const int64_t pos) = 0; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/store/IndexOutput.cpp b/src/core/CLucene/store/IndexOutput.cpp new file mode 100644 index 00000000000..92fd4d9c66f --- /dev/null +++ b/src/core/CLucene/store/IndexOutput.cpp @@ -0,0 +1,240 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "IndexOutput.h" +#include "IndexInput.h" +#include "CLucene/util/Misc.h" + +CL_NS_USE(util) +CL_NS_DEF(store) + + + IndexOutput::IndexOutput() + { + copyBuffer = NULL; + } + + IndexOutput::~IndexOutput(){ + _CLDELETE_LARRAY(copyBuffer); + } + + BufferedIndexOutput::BufferedIndexOutput() + { + buffer = _CL_NEWARRAY(uint8_t, BUFFER_SIZE ); + bufferStart = 0; + bufferPosition = 0; + } + + BufferedIndexOutput::~BufferedIndexOutput(){ + if ( buffer != NULL ) + close(); + } + + void BufferedIndexOutput::close(){ + flush(); + _CLDELETE_ARRAY( buffer ); + + bufferStart = 0; + bufferPosition = 0; + } + + void BufferedIndexOutput::writeByte(const uint8_t b) { + CND_PRECONDITION(buffer!=NULL,"IndexOutput is closed") + if (bufferPosition >= BUFFER_SIZE) + flush(); + buffer[bufferPosition++] = b; + } + + void BufferedIndexOutput::writeBytes(const uint8_t* b, const int32_t length) { + writeBytes(b,length,0); + } + + void BufferedIndexOutput::writeBytes(const uint8_t* b, const int32_t length, const int32_t offset) { + if ( length < 0 ) + _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); + int32_t bytesLeft = BUFFER_SIZE - bufferPosition; + // is there enough space in the buffer? + if (bytesLeft >= length) { + // we add the data to the end of the buffer + memcpy(buffer + bufferPosition, b + offset, length); + bufferPosition += length; + // if the buffer is full, flush it + if (BUFFER_SIZE - bufferPosition == 0) + flush(); + } else { + // is data larger then buffer? + if (length > BUFFER_SIZE) { + // we flush the buffer + if (bufferPosition > 0) + flush(); + // and write data at once + flushBuffer(b, length); + bufferStart += length; + } else { + // we fill/flush the buffer (until the input is written) + int64_t pos = 0; // position in the input data + int32_t pieceLength; + while (pos < length) { + if ( length - pos < bytesLeft ) + pieceLength = (int32_t)(length - pos); + else + pieceLength = bytesLeft; + memcpy(buffer + bufferPosition, b + offset + pos, pieceLength); + pos += pieceLength; + bufferPosition += pieceLength; + // if the buffer is full, flush it + bytesLeft = BUFFER_SIZE - bufferPosition; + if (bytesLeft == 0) { + flush(); + bytesLeft = BUFFER_SIZE; + } + } + } + } + } + + void IndexOutput::writeInt(const int32_t i) { + writeByte((uint8_t)(i >> 24)); + writeByte((uint8_t)(i >> 16)); + writeByte((uint8_t)(i >> 8)); + writeByte((uint8_t) i); + } + + void IndexOutput::writeShort(short i) + { + writeByte(static_cast(i >> 8)); + writeByte(static_cast(i)); + } + + void IndexOutput::writeVInt(const int32_t vi) { + uint32_t i = vi; + while ((i & ~0x7F) != 0) { + writeByte((uint8_t)((i & 0x7f) | 0x80)); + i >>= 7; //doing unsigned shift + } + writeByte( (uint8_t)i ); + } + + void IndexOutput::writeLong(const int64_t i) { + writeInt((int32_t) (i >> 32)); + writeInt((int32_t) i); + } + + void IndexOutput::writeVLong(const int64_t vi) { + uint64_t i = vi; + while ((i & ~0x7F) != 0) { + writeByte((uint8_t)((i & 0x7f) | 0x80)); + i >>= 7; //doing unsigned shift + } + writeByte((uint8_t)i); + } + + void IndexOutput::writeString(const std::string& s ) { + writeString(s.c_str(),s.length()); + } + + void IndexOutput::writeString(const std::wstring& s ) { + writeString(s.c_str(),s.length()); + } + +#ifdef _UCS2 + void IndexOutput::writeString(const char* s, const int32_t length ) { + TCHAR* buf = _CL_NEWARRAY(TCHAR,length+1); + STRCPY_AtoT(buf,s,length); + try{ + writeString(buf,length); + }_CLFINALLY ( _CLDELETE_CARRAY(buf); ) + } +#endif + + void IndexOutput::writeString(const TCHAR* s, const int32_t length ) { + writeVInt(length); + writeChars(s, length); + } + + template <> + void IndexOutput::writeSChars(const TCHAR* s, const int32_t length){ + if ( length < 0 ) + _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); + + const int32_t end = length; + for (int32_t i = 0; i < end; ++i) { + const int32_t code = (int32_t)s[i]; + if (code >= 0x01 && code <= 0x7F) + writeByte((uint8_t)code); + else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) { + writeByte((uint8_t)(0xC0 | (code >> 6))); + writeByte((uint8_t)(0x80 | (code & 0x3F))); + } else { + writeByte((uint8_t)(0xE0 | (((uint32_t)code) >> 12))); //unsigned shift + writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3F))); + writeByte((uint8_t)(0x80 | (code & 0x3F))); + } + } + } + + template <> + void IndexOutput::writeSChars(const char* s, const int32_t length){ + if ( length < 0 ) + _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); + + writeBytes((const uint8_t*)s, length); + } + + void IndexOutput::writeChars(const TCHAR* s, const int32_t length){ + if ( length < 0 ) + _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); + + const int32_t end = length; + for (int32_t i = 0; i < end; ++i) { + const int32_t code = (int32_t)s[i]; + if (code >= 0x01 && code <= 0x7F) + writeByte((uint8_t)code); + else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) { + writeByte((uint8_t)(0xC0 | (code >> 6))); + writeByte((uint8_t)(0x80 | (code & 0x3F))); + } else { + writeByte((uint8_t)(0xE0 | (((uint32_t)code) >> 12))); //unsigned shift + writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3F))); + writeByte((uint8_t)(0x80 | (code & 0x3F))); + } + } + } + + + int64_t BufferedIndexOutput::getFilePointer() const{ + return bufferStart + bufferPosition; + } + void IndexOutput::copyBytes(CL_NS(store)::IndexInput* input, int64_t numBytes) + { + int64_t left = numBytes; + if (copyBuffer == NULL) + copyBuffer = _CL_NEWARRAY(uint8_t, COPY_BUFFER_SIZE); + while(left > 0) { + int32_t toCopy; + if (left > COPY_BUFFER_SIZE) + toCopy = COPY_BUFFER_SIZE; + else + toCopy = (int32_t) left; + input->readBytes(copyBuffer, toCopy); + writeBytes(copyBuffer, toCopy); + left -= toCopy; + } + } + + void BufferedIndexOutput::seek(const int64_t pos) { + flush(); + bufferStart = pos; + } + + void BufferedIndexOutput::flush() { + flushBuffer(buffer, bufferPosition); + bufferStart += bufferPosition; + bufferPosition = 0; + } + +CL_NS_END diff --git a/src/core/CLucene/store/IndexOutput.h b/src/core/CLucene/store/IndexOutput.h new file mode 100644 index 00000000000..4b36371fe79 --- /dev/null +++ b/src/core/CLucene/store/IndexOutput.h @@ -0,0 +1,175 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_IndexOutput_ +#define _lucene_store_IndexOutput_ + +CL_NS_DEF(store) + +class IndexInput; + +/** Abstract class for output to a file in a Directory. A random-access output +* stream. Used for all Lucene index output operations. +* @see Directory +* @see IndexInput +*/ +class CLUCENE_EXPORT IndexOutput:LUCENE_BASE{ + bool isclosed; +public: + IndexOutput(); + virtual ~IndexOutput(); + + /** Writes a single byte. + * @see IndexInput#readByte() + */ + virtual void writeByte(const uint8_t b) = 0; + + /** Writes an array of bytes. + * @param b the bytes to write + * @param length the number of bytes to write + * @see IndexInput#readBytes(uint8_t*,int32_t) + */ + virtual void writeBytes(const uint8_t* b, const int32_t length) = 0; + virtual void writeBytes(const uint8_t* b, const int32_t length, const int32_t offset) = 0; + + /** Writes an int as four bytes. + * @see IndexInput#readInt() + */ + void writeInt(const int32_t i); + + /** Writes an int in a variable-length format. Writes between one and + * five bytes. Smaller values take fewer bytes. Negative numbers are not + * supported. + * @see IndexInput#readVInt() + */ + void writeVInt(const int32_t vi); + + /** Writes a long as eight bytes. + * @see IndexInput#readLong() + */ + void writeLong(const int64_t i); + + /** Writes an long in a variable-length format. Writes between one and five + * bytes. Smaller values take fewer bytes. Negative numbers are not + * supported. + * @see IndexInput#readVLong() + */ + void writeVLong(const int64_t vi); + + /** Writes a string. + * @see IndexInput#readString() + */ + void writeString(const TCHAR* s, const int32_t length); + void writeString(const std::wstring& s); + void writeString(const std::string& s); + + + #ifdef _UCS2 + /** Writes an ascii string. converts to TCHAR* before writing + * @see IndexInput#readString() + */ + void writeString(const char* s, const int32_t length); + #endif + + /** Writes a sequence of UTF-8 encoded characters from a string. + * @param s the source of the characters + * @param start the first character in the sequence + * @param length the number of characters in the sequence + * @see IndexInput#readChars(char[],int32_t,int32_t) + */ + void writeChars(const TCHAR* s, const int32_t length); + template + void writeSChars(const T* s, int32_t length); + + /** Closes this stream to further operations. */ + virtual void close() = 0; + + /** Returns the current position in this file, where the next write will + * occur. + * @see #seek(long) + */ + virtual int64_t getFilePointer() const = 0; + + /** Sets current position in this file, where the next write will occur. + * @see #getFilePointer() + */ + virtual void seek(const int64_t pos) = 0; + + /** The number of bytes in the file. */ + virtual int64_t length() const = 0; + + /** Forces any buffered output to be written. */ + virtual void flush() = 0; + +private: + LUCENE_STATIC_CONSTANT(int32_t, COPY_BUFFER_SIZE = 16384); + uint8_t* copyBuffer; + +public: + /** Copy numBytes bytes from input to ourself. */ + void copyBytes(CL_NS(store)::IndexInput* input, int64_t numBytes); + void writeShort(short i); +}; + +/** Base implementation class for buffered {@link IndexOutput}. */ +class CLUCENE_EXPORT BufferedIndexOutput : public IndexOutput{ +public: + LUCENE_STATIC_CONSTANT(int32_t, BUFFER_SIZE=16384); +private: + uint8_t* buffer; + int64_t bufferStart; // position in file of buffer + int32_t bufferPosition; // position in buffer + +public: + BufferedIndexOutput(); + virtual ~BufferedIndexOutput(); + + /** Writes a single byte. + * @see IndexInput#readByte() + */ + void writeByte(const uint8_t b) override; + + /** Writes an array of bytes. + * @param b the bytes to write + * @param length the number of bytes to write + * @see IndexInput#readBytes(byte[],int32_t,int32_t) + */ + void writeBytes(const uint8_t* b, const int32_t length) override; + + void writeBytes(const uint8_t* b, const int32_t length, const int32_t offset) override; + + + /** Closes this stream to further operations. */ + void close() override; + + /** Returns the current position in this file, where the next write will + * occur. + * @see #seek(long) + */ + int64_t getFilePointer() const; + + /** Sets current position in this file, where the next write will occur. + * @see #getFilePointer() + */ + virtual void seek(const int64_t pos); + + /** The number of bytes in the file. */ + virtual int64_t length() const = 0; + + /** Forces any buffered output to be written. */ + void flush(); + +protected: + /** Expert: implements buffer write. Writes bytes at the current position in + * the output. + * @param b the bytes to write + * @param len the number of bytes to write + */ + virtual void flushBuffer(const uint8_t* b, const int32_t len) = 0; +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/store/Lock.cpp b/src/core/CLucene/store/Lock.cpp new file mode 100644 index 00000000000..ae7c25b42ef --- /dev/null +++ b/src/core/CLucene/store/Lock.cpp @@ -0,0 +1,174 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Lock.h" +#include "_Lock.h" +#include "CLucene/util/Misc.h" + +#ifdef _CL_HAVE_IO_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#include + + +CL_NS_USE(util) +CL_NS_DEF(store) + + LuceneLock::~LuceneLock() + { + } + bool LuceneLock::obtain(int64_t lockWaitTimeout) { + bool locked = obtain(); + if ( lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER ) { + _CLTHROWA(CL_ERR_IllegalArgument,"lockWaitTimeout should be LOCK_OBTAIN_WAIT_FOREVER or a non-negative number"); + } + + int64_t maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL; + int64_t sleepCount = 0; + + while (!locked) { + if ( lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ == maxSleepCount ) { + _CLTHROWA(CL_ERR_IO,"Lock obtain timed out"); + } + _LUCENE_SLEEP(LOCK_POLL_INTERVAL); + locked = obtain(); + } + + return locked; + } + std::string NoLock::toString() + { + return "NoLock"; + } + bool NoLock::obtain() { return true; } + void NoLock::release() {} + bool NoLock::isLocked() { return false; } + + const char* NoLock::getClassName(){ + return "NoLock"; + } + const char* NoLock::getObjectName() const{ + return getClassName(); + } + + + + SingleInstanceLock::SingleInstanceLock( LocksType* locks, _LUCENE_THREADMUTEX* locks_LOCK, const char* lockName ) + { + this->locks = locks; +#ifndef _CL_DISABLE_MULTITHREADING + this->locks_LOCK = locks_LOCK; +#endif + this->lockName = lockName; + } + SingleInstanceLock::~SingleInstanceLock(){ + } + const char* SingleInstanceLock::getClassName(){ + return "SingleInstanceLock"; + } + const char* SingleInstanceLock::getObjectName() const{ + return getClassName(); + } + + bool SingleInstanceLock::obtain() + { + SCOPED_LOCK_MUTEX(*locks_LOCK); + return locks->insert( lockName ).second; + } + + void SingleInstanceLock::release() + { + SCOPED_LOCK_MUTEX(*locks_LOCK); + LocksType::iterator itr = locks->find( lockName ); + if ( itr != locks->end() ) { + locks->remove(itr, true); + } + } + + bool SingleInstanceLock::isLocked() + { + SCOPED_LOCK_MUTEX(*locks_LOCK); + return locks->find( lockName ) == locks->end(); + } + + string SingleInstanceLock::toString() + { + return string("SingleInstanceLock:") + lockName; + } + + + FSLock::FSLock( const char* _lockDir, const char* name, int filemode ) + { + if ( filemode <= 0 ) + this->filemode = 0644; //must do this or file will be created Read only + else + this->filemode = filemode; + + this->lockFile = _CL_NEWARRAY(char,CL_MAX_PATH); + this->lockDir = STRDUP_AtoA(_lockDir); + strcpy(lockFile,_lockDir); + strcat(lockFile,PATH_DELIMITERA); + strcat(lockFile,name); + } + + FSLock::~FSLock() + { + _CLDELETE_ARRAY( lockFile ); + _CLDELETE_LCaARRAY( lockDir ); + } + + const char* FSLock::getClassName(){ + return "FSLock"; + } + const char* FSLock::getObjectName() const{ + return getClassName(); + } + + bool FSLock::obtain() + { + if ( !Misc::dir_Exists(lockDir) ){ + if ( _mkdir(lockDir) == -1 ){ + char* err = _CL_NEWARRAY(char,34+strlen(lockDir)+1); //34: len of "Couldn't create lock directory: " + strcpy(err,"Couldn't create lock directory: "); + strcat(err,lockDir); + _CLTHROWA_DEL(CL_ERR_IO, err ); + } + } + int32_t r = _cl_open(lockFile, O_RDWR | O_CREAT | _O_RANDOM | O_EXCL, this->filemode); + if ( r < 0 ) { + return false; + } else { + _close(r); + return true; + } + } + + void FSLock::release() + { + _unlink( lockFile ); + } + + bool FSLock::isLocked() + { + return Misc::dir_Exists(lockFile); + } + + string FSLock::toString() + { + return string("SimpleFSLock@") + lockFile; + } + +CL_NS_END diff --git a/src/core/CLucene/store/Lock.h b/src/core/CLucene/store/Lock.h new file mode 100644 index 00000000000..069672d2b64 --- /dev/null +++ b/src/core/CLucene/store/Lock.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_Lock_ +#define _lucene_store_Lock_ + +#include +#include "CLucene/util/Equators.h" + +CL_NS_DEF(store) + class LocksType; + + class CLUCENE_EXPORT LuceneLock: public CL_NS(util)::NamedObject{ + public: + LUCENE_STATIC_CONSTANT(int64_t, LOCK_POLL_INTERVAL = 1000); + LUCENE_STATIC_CONSTANT(int64_t, LOCK_OBTAIN_WAIT_FOREVER = -1); + + /** Attempts to obtain exclusive access and immediately return + * upon success or failure. + * @return true iff exclusive access is obtained + */ + virtual bool obtain() = 0; + + /** Attempts to obtain an exclusive lock within amount + * of time given. Currently polls once per second until + * lockWaitTimeout is passed. + * @param lockWaitTimeout length of time to wait in ms + * @return true if lock was obtained + * @throws IOException if lock wait times out or obtain() throws an IOException + */ + bool obtain(int64_t lockWaitTimeout); + + // Release exclusive access. + virtual void release() = 0; + + /** Returns true if the resource is currently locked. Note that one must + * still call {@link #obtain()} before using the resource. */ + virtual bool isLocked() = 0; + + virtual ~LuceneLock(); + + virtual std::string toString() = 0; + }; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/store/LockFactory.cpp b/src/core/CLucene/store/LockFactory.cpp new file mode 100644 index 00000000000..6b2cfe23634 --- /dev/null +++ b/src/core/CLucene/store/LockFactory.cpp @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_ApiHeader.h" +#include "LockFactory.h" +#include "_Lock.h" +#include "CLucene/util/Misc.h" + +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif + +CL_NS_USE(util) +CL_NS_DEF(store) + + +LockFactory::LockFactory() +{ +} + +LockFactory::~LockFactory() +{ +} + +void LockFactory::setLockPrefix( const char* lockPrefix ) +{ + if ( lockPrefix != NULL ) + this->lockPrefix = lockPrefix; + else + this->lockPrefix.clear(); +} + +const char* LockFactory::getLockPrefix() +{ + return lockPrefix.c_str(); +} + +SingleInstanceLockFactory::SingleInstanceLockFactory() +{ + locks = _CLNEW LocksType(); +} + +SingleInstanceLockFactory::~SingleInstanceLockFactory() +{ + _CLDELETE( locks ); +} + +LuceneLock* SingleInstanceLockFactory::makeLock( const char* lockName ) +{ +#ifdef _CL_DISABLE_MULTITHREADING + return _CLNEW SingleInstanceLock( locks, NULL, lockName ); +#else + return _CLNEW SingleInstanceLock( locks, &locks_LOCK, lockName ); +#endif +} + +void SingleInstanceLockFactory::clearLock( const char* lockName ) +{ + SCOPED_LOCK_MUTEX(locks_LOCK); + LocksType::iterator itr = locks->find( lockName ); + if ( itr != locks->end() ) { + locks->remove( itr ); + } +} + + +NoLockFactory* NoLockFactory::singleton = NULL; +NoLock* NoLockFactory::singletonLock = NULL; + +void NoLockFactory::_shutdown(){ + _CLDELETE(NoLockFactory::singleton); + _CLDELETE(NoLockFactory::singletonLock); +} + +NoLockFactory* NoLockFactory::getNoLockFactory() +{ + if ( singleton == NULL ) { + singleton = _CLNEW NoLockFactory(); + } + return singleton; +} + +LuceneLock* NoLockFactory::makeLock( const char* /*lockName*/ ) +{ + if ( singletonLock == NULL ) { + singletonLock = _CLNEW NoLock(); + } + return singletonLock; +} + +void NoLockFactory::clearLock( const char* /*lockName*/ ) +{ +} + + +FSLockFactory::FSLockFactory( const char* lockDir, int filemode ) +{ + setLockDir( lockDir ); + if ( filemode > 0 ) + this->filemode = filemode; + else + this->filemode = 0644; +} + +FSLockFactory::~FSLockFactory() +{ +} + +void FSLockFactory::setLockDir( const char* lockDir ) +{ + this->lockDir = lockDir; +} + +LuceneLock* FSLockFactory::makeLock( const char* lockName ) +{ + char name[CL_MAX_DIR]; + + if ( !lockPrefix.empty() ) { + cl_sprintf(name, CL_MAX_DIR, "%s-%s", lockPrefix.c_str(), lockName); + } else { + cl_strcpy(name,lockName,CL_MAX_DIR); + } + + return _CLNEW FSLock( lockDir.c_str(), name, this->filemode ); +} + +void FSLockFactory::clearLock( const char* lockName ) +{ + if ( Misc::dir_Exists( lockDir.c_str() )) { + char name[CL_MAX_DIR]; + char path[CL_MAX_DIR]; + struct cl_stat_t buf; + + if ( !lockPrefix.empty() ) { + STRCPY_AtoA(name,lockPrefix.c_str(),lockPrefix.length()+1); + strcat(name,"-"); + strcat(name,lockName); + } else { + strcpy(name,lockName); + } + + _snprintf(path,CL_MAX_DIR,"%s/%s",lockDir.c_str(),name); + + int32_t ret = fileStat(path,&buf); + if ( ret==0 && !(buf.st_mode & S_IFDIR) && _unlink( path ) == -1 ) { + _CLTHROWA(CL_ERR_IO, "Couldn't delete file" ); // TODO: make richer error + } + } +} + + +CL_NS_END diff --git a/src/core/CLucene/store/LockFactory.h b/src/core/CLucene/store/LockFactory.h new file mode 100644 index 00000000000..95ab3c96419 --- /dev/null +++ b/src/core/CLucene/store/LockFactory.h @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_LockFactory_ +#define _lucene_store_LockFactory_ + +#include "CLucene/LuceneThreads.h" + +CL_CLASS_DEF(store,LuceneLock) +CL_CLASS_DEF(store,NoLock) + +CL_NS_DEF(store) +class LocksType; + +class CLUCENE_EXPORT LockFactory: LUCENE_BASE { +protected: + std::string lockPrefix; +public: + + LockFactory(); + virtual ~LockFactory(); + + void setLockPrefix( const char* lockPrefix ); + const char* getLockPrefix(); + + virtual LuceneLock* makeLock( const char* lockName )=0; + virtual void clearLock( const char* lockName )=0; +}; + +class CLUCENE_EXPORT SingleInstanceLockFactory: public LockFactory { +private: + LocksType* locks; + DEFINE_MUTEX(locks_LOCK) +public: + SingleInstanceLockFactory(); + ~SingleInstanceLockFactory(); + + LuceneLock* makeLock( const char* lockName ); + void clearLock( const char* lockName ); +}; + +class CLUCENE_EXPORT NoLockFactory: public LockFactory { +public: + static NoLockFactory* singleton; + static NoLock* singletonLock; + + static NoLockFactory* getNoLockFactory(); + LuceneLock* makeLock( const char* lockName ); + void clearLock( const char* lockName ); + + /** called when lucene_shutdown is called */ + static CLUCENE_LOCAL void _shutdown(); +}; + +class CLUCENE_EXPORT FSLockFactory: public LockFactory { +private: + std::string lockDir; + int filemode; +public: + /** Constructs a FS Lock factory. The default file mode is user writable */ + FSLockFactory( const char* lockDir=NULL, int filemode=-1 ); + ~FSLockFactory(); + + void setLockDir( const char* lockDir ); + + LuceneLock* makeLock( const char* lockName ); + void clearLock( const char* lockName ); + + static const char* getClassName(); + const char* getObjectName(); +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/store/MMapInput.cpp b/src/core/CLucene/store/MMapInput.cpp new file mode 100644 index 00000000000..331c7cef506 --- /dev/null +++ b/src/core/CLucene/store/MMapInput.cpp @@ -0,0 +1,301 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "FSDirectory.h" +#include "_MMapIndexInput.h" +#include "CLucene/util/Misc.h" + +#include +#ifdef _CL_HAVE_IO_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#ifdef _CL_HAVE_SYS_MMAN_H + #include +#endif +#ifdef _CL_HAVE_WINERROR_H + #include +#endif +#include + +#if defined(_CL_HAVE_FUNCTION_MAPVIEWOFFILE) + typedef int HANDLE; + + #define GENERIC_READ (0x80000000L) + #define FILE_SHARE_READ 0x00000001 + #define OPEN_EXISTING 3 + #define PAGE_READONLY 0x02 + #define SECTION_MAP_READ 0x0004 + #define FILE_MAP_READ SECTION_MAP_READ + + typedef struct _SECURITY_ATTRIBUTES + { + _cl_dword_t nLength; + void* lpSecurityDescriptor; + bool bInheritHandle; + } SECURITY_ATTRIBUTES; + + extern "C" __declspec(dllimport) _cl_dword_t __stdcall GetFileSize( HANDLE hFile, _cl_dword_t* lpFileSizeHigh ); + + extern "C" __declspec(dllimport) bool __stdcall UnmapViewOfFile( void* lpBaseAddress ); + + extern "C" __declspec(dllimport) bool __stdcall CloseHandle( HANDLE hObject ); + extern "C" __declspec(dllimport) HANDLE __stdcall CreateFileA( + const char* lpFileName, + _cl_dword_t dwDesiredAccess, + _cl_dword_t dwShareMode, + SECURITY_ATTRIBUTES* lpSecurityAttributes, + _cl_dword_t dwCreationDisposition, + _cl_dword_t dwFlagsAndAttributes, + HANDLE hTemplateFile + ); + extern "C" __declspec(dllimport) HANDLE __stdcall CreateFileMappingA( + HANDLE hFile, + SECURITY_ATTRIBUTES* lpFileMappingAttributes, + _cl_dword_t flProtect, + _cl_dword_t dwMaximumSizeHigh, + _cl_dword_t dwMaximumSizeLow, + const char* lpName + ); + extern "C" __declspec(dllimport) void* __stdcall MapViewOfFile( + HANDLE hFileMappingObject, + _cl_dword_t dwDesiredAccess, + _cl_dword_t dwFileOffsetHigh, + _cl_dword_t dwFileOffsetLow, + _cl_dword_t dwNumberOfBytesToMap + ); + extern "C" __declspec(dllimport) _cl_dword_t __stdcall GetLastError(); +#endif + + +CL_NS_DEF(store) +CL_NS_USE(util) + + class MMapIndexInput::Internal: LUCENE_BASE{ + public: + uint8_t* data; + int64_t pos; +#if defined(_CL_HAVE_FUNCTION_MAPVIEWOFFILE) + HANDLE mmaphandle; + HANDLE fhandle; +#elif defined(_CL_HAVE_FUNCTION_MMAP) + int fhandle; +#else + #error no mmap implementation set +#endif + bool isClone; + int64_t _length; + + Internal(): + data(NULL), + pos(0), + isClone(false), + _length(0) + { + } + ~Internal(){ + } + }; + + MMapIndexInput::MMapIndexInput(Internal* __internal): + _internal(__internal) + { + } + + bool MMapIndexInput::open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize ) { + + //Func - Constructor. + // Opens the file named path + //Pre - path != NULL + //Post - if the file could not be opened an exception is thrown. + + CND_PRECONDITION(path != NULL, "path is NULL"); + + Internal* _internal = _CLNEW Internal; + +#if defined(_CL_HAVE_FUNCTION_MAPVIEWOFFILE) + _internal->mmaphandle = NULL; + _internal->fhandle = CreateFileA(path,GENERIC_READ,FILE_SHARE_READ, 0,OPEN_EXISTING,0,0); + + //Check if a valid fhandle was retrieved + if (_internal->fhandle < 0){ + _cl_dword_t err = GetLastError(); + if ( err == ERROR_FILE_NOT_FOUND ) + error.set(CL_ERR_IO, "File does not exist"); + else if ( err == ERROR_ACCESS_DENIED ) + error.set(CL_ERR_IO, "File Access denied"); + else if ( err == ERROR_TOO_MANY_OPEN_FILES ) + error.set(CL_ERR_IO, "Too many open files"); + else + error.set(CL_ERR_IO, "Could not open file"); + } + + _cl_dword_t dummy=0; + _internal->_length = GetFileSize(_internal->fhandle, &dummy); + + if ( _internal->_length > 0 ){ + _internal->mmaphandle = CreateFileMappingA(_internal->fhandle,NULL,PAGE_READONLY,0,0,NULL); + if ( _internal->mmaphandle != NULL ){ + void* address = MapViewOfFile(_internal->mmaphandle,FILE_MAP_READ,0,0,0); + if ( address != NULL ){ + _internal->data = (uint8_t*)address; + ret = _CLNEW MMapIndexInput(_internal); + return true; + } + } + + //failure: + int errnum = GetLastError(); + + CloseHandle(_internal->mmaphandle); + + char* lpMsgBuf=strerror(errnum); + size_t len = strlen(lpMsgBuf)+80; + char* errstr = _CL_NEWARRAY(char, len); + cl_sprintf(errstr, len, "MMapIndexInput::MMapIndexInput failed with error %d: %s", errnum, lpMsgBuf); + + error.set(CL_ERR_IO, errstr); + _CLDELETE_CaARRAY(errstr); + } + +#else //_CL_HAVE_FUNCTION_MAPVIEWOFFILE + _internal->fhandle = ::_cl_open (path, _O_BINARY | O_RDONLY | _O_RANDOM, _S_IREAD); + if (_internal->fhandle < 0){ + error.set(CL_ERR_IO, strerror(errno)); + }else{ + // stat it + struct stat sb; + if (::fstat (_internal->fhandle, &sb)){ + error.set(CL_ERR_IO, strerror(errno)); + }else{ + // get length from stat + _internal->_length = sb.st_size; + + // mmap the file + void* address = ::mmap(0, _internal->_length, PROT_READ, MAP_SHARED, _internal->fhandle, 0); + if (address == MAP_FAILED){ + error.set(CL_ERR_IO, strerror(errno)); + }else{ + _internal->data = (uint8_t*)address; + ret = _CLNEW MMapIndexInput(_internal); + return true; + } + } + } +#endif + + _CLDELETE(_internal); + return false; + } + + MMapIndexInput::MMapIndexInput(const MMapIndexInput& clone): IndexInput(clone){ + //Func - Constructor + // Uses clone for its initialization + //Pre - clone is a valide instance of FSIndexInput + //Post - The instance has been created and initialized by clone + _internal = _CLNEW Internal; + +#if defined(_CL_HAVE_FUNCTION_MAPVIEWOFFILE) + _internal->mmaphandle = NULL; + _internal->fhandle = NULL; +#endif + + _internal->data = clone._internal->data; + _internal->pos = clone._internal->pos; + + //clone the file length + _internal->_length = clone._internal->_length; + //Keep in mind that this instance is a clone + _internal->isClone = true; + } + + uint8_t MMapIndexInput::readByte(){ + return *(_internal->data+(_internal->pos++)); + } + + void MMapIndexInput::readBytes(uint8_t* b, const int32_t len) { + readBytes(b,len,0); + } + void MMapIndexInput::readBytes(uint8_t* b, const int32_t len, int32_t offset){ + memcpy(b + offset, _internal->data+_internal->pos, len); + _internal->pos+=len; + } + int32_t MMapIndexInput::readVInt(){ + uint8_t b = *(_internal->data+(_internal->pos++)); + int32_t i = b & 0x7F; + for (int shift = 7; (b & 0x80) != 0; shift += 7) { + b = *(_internal->data+(_internal->pos++)); + i |= (b & 0x7F) << shift; + } + return i; + } + int64_t MMapIndexInput::getFilePointer() const{ + return _internal->pos; + } + void MMapIndexInput::seek(const int64_t pos){ + this->_internal->pos=pos; + } + int64_t MMapIndexInput::length() const{ return _internal->_length; } + + MMapIndexInput::~MMapIndexInput(){ + //Func - Destructor + //Pre - True + //Post - The file for which this instance is responsible has been closed. + // The instance has been destroyed + + close(); + _CLDELETE(_internal); + } + + IndexInput* MMapIndexInput::clone() const + { + return _CLNEW MMapIndexInput(*this); + } + void MMapIndexInput::close() { + if ( !_internal->isClone ){ +#if defined(_CL_HAVE_FUNCTION_MAPVIEWOFFILE) + if ( _internal->data != NULL ){ + if ( ! UnmapViewOfFile(_internal->data) ){ + CND_PRECONDITION( false, "UnmapViewOfFile(data) failed"); //todo: change to rich error + } + } + + if ( _internal->mmaphandle != NULL ){ + if ( ! CloseHandle(_internal->mmaphandle) ){ + CND_PRECONDITION( false, "CloseHandle(mmaphandle) failed"); + } + } + if ( _internal->fhandle != NULL ){ + if ( !CloseHandle(_internal->fhandle) ){ + CND_PRECONDITION( false, "CloseHandle(fhandle) failed"); + } + } + _internal->mmaphandle = NULL; + _internal->fhandle = NULL; +#else + if ( _internal->data != NULL ) + ::munmap(_internal->data, _internal->_length); + if ( _internal->fhandle > 0 ) + ::close(_internal->fhandle); + _internal->fhandle = 0; +#endif + } + _internal->data = NULL; + _internal->pos = 0; + } + + +CL_NS_END diff --git a/src/core/CLucene/store/RAMDirectory.cpp b/src/core/CLucene/store/RAMDirectory.cpp new file mode 100644 index 00000000000..768b2f4d478 --- /dev/null +++ b/src/core/CLucene/store/RAMDirectory.cpp @@ -0,0 +1,579 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#include "RAMDirectory.h" +#include "CLucene/index/IndexReader.h" +#include "Directory.h" +#include "FSDirectory.h" +#include "Lock.h" +#include "LockFactory.h" +#include "_RAMDirectory.h" +//#include "CLucene/util/VoidMap.h" +#include "CLucene/util/Misc.h" +#include + +CL_NS_USE(util) +CL_NS_DEF(store) + + +// ***** +// Lock acquisition sequence: RAMDirectory, then RAMFile +// ***** + +class RAMLock : public LuceneLock { +private: + RAMDirectory *directory; + char *fname; + +public: + RAMLock(const char *name, RAMDirectory *dir); + virtual ~RAMLock(); + bool obtain(); + void release(); + bool isLocked(); + virtual std::string toString(); +}; + + +RAMFile::RAMFile(RAMDirectory *_directory) { + length = 0; + lastModified = Misc::currentTimeMillis(); + this->directory = _directory; + sizeInBytes = 0; +} + +RAMFile::~RAMFile() { +} + +int64_t RAMFile::getLength() { + SCOPED_LOCK_MUTEX(THIS_LOCK); + return length; +} + +void RAMFile::setLength(int64_t length) { + SCOPED_LOCK_MUTEX(THIS_LOCK); + this->length = length; +} + +uint64_t RAMFile::getLastModified() { + SCOPED_LOCK_MUTEX(THIS_LOCK); + return lastModified; +} + +void RAMFile::setLastModified(const uint64_t lastModified) { + SCOPED_LOCK_MUTEX(THIS_LOCK); + this->lastModified = lastModified; +} + +uint8_t *RAMFile::addBuffer(const int32_t size) { + SCOPED_LOCK_MUTEX(THIS_LOCK); + uint8_t *buffer = newBuffer(size); + RAMFileBuffer *rfb = _CLNEW RAMFileBuffer(buffer, size); + if (directory != NULL) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK); + buffers.push_back(rfb); + directory->sizeInBytes += size; + sizeInBytes += size; + } else { + buffers.push_back(rfb); + } + return buffer; +} + +uint8_t *RAMFile::getBuffer(const int32_t index) { + SCOPED_LOCK_MUTEX(THIS_LOCK); + return buffers[index]->_buffer; +} + +int32_t RAMFile::numBuffers() const { + return buffers.size(); +} + +uint8_t *RAMFile::newBuffer(const int32_t size) { + return _CL_NEWARRAY(uint8_t, size); +} + +int64_t RAMFile::getSizeInBytes() const { + if (directory != NULL) { + SCOPED_LOCK_MUTEX(directory->THIS_LOCK); + return sizeInBytes; + } + return 0; +} + + +RAMOutputStream::~RAMOutputStream() { + if (deleteFile) { + _CLDELETE(file); + } else { + file = NULL; + } +} +RAMOutputStream::RAMOutputStream(RAMFile *f) : file(f), + deleteFile(false), + currentBuffer(NULL), + currentBufferIndex(-1), + bufferPosition(0), + bufferStart(0), + bufferLength(0) { +} + +RAMOutputStream::RAMOutputStream() : file(_CLNEW RAMFile), + deleteFile(true), + currentBuffer(NULL), + currentBufferIndex(-1), + bufferPosition(0), + bufferStart(0), + bufferLength(0) { +} + +void RAMOutputStream::writeTo(std::vector &bytes, + int offset) { + flush(); + const int64_t end = file->getLength(); + int64_t pos = 0; + int buffer = 0; + int bytesUpto = offset; + while (pos < end) { + int length = BUFFER_SIZE; + int64_t nextPos = pos + length; + if (nextPos > end) {// at the last buffer + length = static_cast(end - pos); + } + memcpy(bytes.data()+ bytesUpto, file->getBuffer(buffer++), length); + bytesUpto += length; + pos = nextPos; + } +} + +void RAMOutputStream::writeTo(IndexOutput *out) { + flush(); + const int64_t end = file->getLength(); + int64_t pos = 0; + int32_t p = 0; + while (pos < end) { + int32_t length = BUFFER_SIZE; + int64_t nextPos = pos + length; + if (nextPos > end) {// at the last buffer + length = (int32_t) (end - pos); + } + out->writeBytes(file->getBuffer(p++), length); + pos = nextPos; + } +} + +void RAMOutputStream::reset() { + seek((int64_t) 0); + file->setLength((int64_t) 0); +} + +void RAMOutputStream::close() { + flush(); +} + +/** Random-at methods */ +void RAMOutputStream::seek(const int64_t pos) { + // set the file length in case we seek back + // and flush() has not been called yet + setFileLength(); + if (pos < bufferStart || pos >= bufferStart + bufferLength) { + currentBufferIndex = (int32_t) (pos / BUFFER_SIZE); + switchCurrentBuffer(); + } + + bufferPosition = (int32_t) (pos % BUFFER_SIZE); +} + +int64_t RAMOutputStream::length() const { + return file->getLength(); +} + +void RAMOutputStream::writeByte(const uint8_t b) { + if (bufferPosition == bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + currentBuffer[bufferPosition++] = b; +} + +void RAMOutputStream::writeBytes(const uint8_t *b, const int32_t len) { + writeBytes(b, len, 0); +} + +void RAMOutputStream::writeBytes(const uint8_t *b, int32_t len, int32_t offset) { + int32_t srcOffset = offset; + + while (len > 0) { + if (bufferPosition == bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + + int remainInBuffer = bufferLength - bufferPosition; + int bytesToCopy = len < remainInBuffer ? len : remainInBuffer; + memcpy( currentBuffer+bufferPosition, b+offset, bytesToCopy * sizeof(uint8_t) ); + offset += bytesToCopy; + len -= bytesToCopy; + bufferPosition += bytesToCopy; + } + /*while ( srcOffset != len ) { + if ( bufferPosition == bufferLength ) { + currentBufferIndex++; + switchCurrentBuffer(); + } + + int32_t remainInSrcBuffer = len - srcOffset; + int32_t bytesInBuffer = bufferLength - bufferPosition; + int32_t bytesToCopy = bytesInBuffer >= remainInSrcBuffer ? remainInSrcBuffer : bytesInBuffer; + + memcpy( currentBuffer+bufferPosition, b+srcOffset, bytesToCopy * sizeof(uint8_t) ); + + srcOffset += bytesToCopy; + bufferPosition += bytesToCopy; + }*/ +} + +void RAMOutputStream::switchCurrentBuffer() { + + if (currentBufferIndex == file->numBuffers()) { + currentBuffer = file->addBuffer(BUFFER_SIZE); + bufferLength = BUFFER_SIZE; + } else { + currentBuffer = file->getBuffer(currentBufferIndex); + bufferLength = file->getBufferLen(currentBufferIndex); + } + assert(bufferLength >= 0);// + + bufferPosition = 0; + bufferStart = (int64_t) BUFFER_SIZE * (int64_t) currentBufferIndex; +} + + +void RAMOutputStream::setFileLength() { + int64_t pointer = bufferStart + bufferPosition; + if (pointer > file->getLength()) { + file->setLength(pointer); + } +} + +void RAMOutputStream::flush() { + file->setLastModified(Misc::currentTimeMillis()); + setFileLength(); +} + +int64_t RAMOutputStream::getFilePointer() const { + return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; +} + + +RAMInputStream::RAMInputStream(RAMFile *f) : file(f), + currentBuffer(NULL), + currentBufferIndex(-1), + bufferPosition(0), + bufferStart(0), + bufferLength(0) { + _length = f->getLength(); + + if (_length / BUFFER_SIZE >= 0x7FFFFFFFL) { + // TODO: throw exception + } +} + +RAMInputStream::RAMInputStream(const RAMInputStream &other) : IndexInput(other) { + file = other.file; + _length = other._length; + currentBufferIndex = other.currentBufferIndex; + currentBuffer = other.currentBuffer; + bufferPosition = other.bufferPosition; + bufferStart = other.bufferStart; + bufferLength = other.bufferLength; +} + +RAMInputStream::~RAMInputStream() { + RAMInputStream::close(); +} + +IndexInput *RAMInputStream::clone() const { + return _CLNEW RAMInputStream(*this); +} + +int64_t RAMInputStream::length() const { + return _length; +} + +const char *RAMInputStream::getDirectoryType() const { + return RAMDirectory::getClassName(); +} +const char *RAMIndexInput::getObjectName() const { return getClassName(); } +const char *RAMIndexInput::getClassName() { return "RAMIndexInput"; } + +uint8_t RAMInputStream::readByte() { + if (bufferPosition >= bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + return currentBuffer[bufferPosition++]; +} + +void RAMInputStream::readBytes(uint8_t *_dest, const int32_t _len) { + readBytes(_dest, _len, 0); +} +void RAMInputStream::readBytes(uint8_t *_dest, const int32_t _len, int32_t offset) { + + uint8_t *dest = _dest; + int32_t len = _len; + + while (len > 0) { + if (bufferPosition >= bufferLength) { + currentBufferIndex++; + switchCurrentBuffer(); + } + + int32_t remainInBuffer = bufferLength - bufferPosition; + int32_t bytesToCopy = len < remainInBuffer ? len : remainInBuffer; + memcpy(dest + offset, currentBuffer + bufferPosition, bytesToCopy * sizeof(uint8_t)); + + dest += bytesToCopy; + len -= bytesToCopy; + bufferPosition += bytesToCopy; + } +} + +int64_t RAMInputStream::getFilePointer() const { + return currentBufferIndex < 0 ? 0 : bufferStart + bufferPosition; +} + +void RAMInputStream::seek(const int64_t pos) { + if (currentBuffer == NULL || pos < bufferStart || pos >= bufferStart + BUFFER_SIZE) { + currentBufferIndex = (int32_t) (pos / BUFFER_SIZE); + switchCurrentBuffer(); + } + bufferPosition = (int32_t) (pos % BUFFER_SIZE); +} + +void RAMInputStream::close() { +} + +void RAMInputStream::switchCurrentBuffer() { + if (currentBufferIndex >= file->numBuffers()) { + // end of file reached, no more buffers left + _CLTHROWA(CL_ERR_IO, "Read past EOF"); + } else { + currentBuffer = file->getBuffer(currentBufferIndex); + bufferPosition = 0; + bufferStart = (int64_t) BUFFER_SIZE * (int64_t) currentBufferIndex; + int64_t bufLen = _length - bufferStart; + bufferLength = bufLen > BUFFER_SIZE ? BUFFER_SIZE : static_cast(bufLen); + } + assert(bufferLength >= 0); +} + + +bool RAMDirectory::list(vector *names) const { + SCOPED_LOCK_MUTEX(files_mutex); + + FileMap::const_iterator itr = files->begin(); + while (itr != files->end()) { + names->push_back(string(itr->first)); + ++itr; + } + return true; +} + +RAMDirectory::RAMDirectory() : Directory(), files(_CLNEW FileMap(true, true)) { + this->sizeInBytes = 0; + setLockFactory(_CLNEW SingleInstanceLockFactory()); +} + +RAMDirectory::~RAMDirectory() { + //todo: should call close directory? + _CLDELETE(lockFactory); + _CLDELETE(files); +} + +void RAMDirectory::_copyFromDir(Directory *dir, bool closeDir) { + vector names; + dir->list(&names); + uint8_t buf[CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE]; + + for (size_t i = 0; i < names.size(); ++i) { + // make place on ram disk + IndexOutput *os = createOutput(names[i].c_str()); + // read current file + IndexInput *is = dir->openInput(names[i].c_str()); + // and copy to ram disk + //todo: this could be a problem when copying from big indexes... + int64_t len = is->length(); + int64_t readCount = 0; + while (readCount < len) { + int32_t toRead = (int32_t) (readCount + CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE > len ? len - readCount : CL_NS(store)::BufferedIndexOutput::BUFFER_SIZE); + is->readBytes(buf, toRead); + os->writeBytes(buf, toRead); + readCount += toRead; + } + + // graceful cleanup + is->close(); + _CLDELETE(is); + os->close(); + _CLDELETE(os); + } + if (closeDir) + dir->close(); +} +RAMDirectory::RAMDirectory(Directory *dir) : Directory(), files(_CLNEW FileMap(true, true)) { + this->sizeInBytes = 0; + setLockFactory(_CLNEW SingleInstanceLockFactory()); + _copyFromDir(dir, false); +} + +RAMDirectory::RAMDirectory(const char *dir) : Directory(), files(_CLNEW FileMap(true, true)) { + this->sizeInBytes = 0; + setLockFactory(_CLNEW SingleInstanceLockFactory()); + Directory *fsdir = FSDirectory::getDirectory(dir); + try { + _copyFromDir(fsdir, false); + } + _CLFINALLY( + fsdir->close(); + _CLDECDELETE(fsdir);); +} + +bool RAMDirectory::fileExists(const char *name) const { + SCOPED_LOCK_MUTEX(files_mutex); + return files->exists((char *) name); +} + +int64_t RAMDirectory::fileModified(const char *name) const { + SCOPED_LOCK_MUTEX(files_mutex); + RAMFile *f = files->get((char *) name); + return f->getLastModified(); +} + +int64_t RAMDirectory::fileLength(const char *name) const { + SCOPED_LOCK_MUTEX(files_mutex); + RAMFile *f = files->get((char *) name); + return f->getLength(); +} + + +bool RAMDirectory::openInput(const char *name, IndexInput *&ret, CLuceneError &error, int32_t /*bufferSize*/) { + SCOPED_LOCK_MUTEX(files_mutex); + RAMFile *file = files->get((char *) name); + if (file == NULL) { + error.set(CL_ERR_IO, "[RAMDirectory::open] The requested file does not exist."); + return false; + } + ret = _CLNEW RAMInputStream(file); + return true; +} + +void RAMDirectory::close() { + SCOPED_LOCK_MUTEX(files_mutex); + files->clear(); + _CLDELETE(files); +} + +bool RAMDirectory::doDeleteFile(const char *name) { + SCOPED_LOCK_MUTEX(files_mutex); + FileMap::iterator itr = files->find((char *) name); + if (itr != files->end()) { + SCOPED_LOCK_MUTEX(this->THIS_LOCK); + sizeInBytes -= itr->second->sizeInBytes; + files->removeitr(itr); + return true; + } else { + return false; + } +} + +void RAMDirectory::renameFile(const char *from, const char *to) { + SCOPED_LOCK_MUTEX(files_mutex); + FileMap::iterator itr = files->find((char *) from); + + /* DSR:CL_BUG_LEAK: + ** If a file named $to already existed, its old value was leaked. + ** My inclination would be to prevent this implicit deletion with an + ** exception, but it happens routinely in CLucene's internals (e.g., during + ** IndexWriter.addIndexes with the file named 'segments'). */ + if (files->exists((char *) to)) { + FileMap::iterator itr1 = files->find((char *) to); + SCOPED_LOCK_MUTEX(this->THIS_LOCK); + sizeInBytes -= itr1->second->sizeInBytes; + files->removeitr(itr1); + } + if (itr == files->end()) { + char tmp[1024]; + _snprintf(tmp, 1024, "cannot rename %s, file does not exist", from); + _CLTHROWT(CL_ERR_IO, tmp); + } + CND_PRECONDITION(itr != files->end(), "itr==files->end()") + RAMFile *file = itr->second; + files->removeitr(itr, false, true); + files->put(STRDUP_AtoA(to), file); +} + + +void RAMDirectory::touchFile(const char *name) { + RAMFile *file = NULL; + { + SCOPED_LOCK_MUTEX(files_mutex); + file = files->get((char *) name); + } + const uint64_t ts1 = file->getLastModified(); + uint64_t ts2 = Misc::currentTimeMillis(); + + //make sure that the time has actually changed + while (ts1 == ts2) { + _LUCENE_SLEEP(1); + ts2 = Misc::currentTimeMillis(); + }; + + file->setLastModified(ts2); +} + +IndexOutput *RAMDirectory::createOutput(const char *name) { + /* Check the $files VoidMap to see if there was a previous file named + ** $name. If so, delete the old RAMFile object, but reuse the existing + ** char buffer ($n) that holds the filename. If not, duplicate the + ** supplied filename buffer ($name) and pass ownership of that memory ($n) + ** to $files. */ + + SCOPED_LOCK_MUTEX(files_mutex); + + // get the actual pointer to the output name + char *n = NULL; + FileMap::const_iterator itr = files->find(const_cast(name)); + if (itr != files->end()) { + n = itr->first; + RAMFile *rf = itr->second; + SCOPED_LOCK_MUTEX(this->THIS_LOCK); + sizeInBytes -= rf->sizeInBytes; + _CLDELETE(rf); + } else { + n = STRDUP_AtoA(name); + } + + RAMFile *file = _CLNEW RAMFile(); + (*files)[n] = file; + + return _CLNEW RAMOutputStream(file); +} + +std::string RAMDirectory::toString() const { + return "RAMDirectory"; +} + +const char *RAMDirectory::getClassName() { + return "RAMDirectory"; +} +const char *RAMDirectory::getObjectName() const { + return getClassName(); +} + +CL_NS_END diff --git a/src/core/CLucene/store/RAMDirectory.h b/src/core/CLucene/store/RAMDirectory.h new file mode 100644 index 00000000000..ba01a49732f --- /dev/null +++ b/src/core/CLucene/store/RAMDirectory.h @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_RAMDirectory_ +#define _lucene_store_RAMDirectory_ + + +#include "CLucene/util/VoidMap.h" +#include "Directory.h" +CL_CLASS_DEF(store,RAMFile) + +CL_NS_DEF(store) + + /** + * A memory-resident {@link Directory} implementation. Locking + * implementation is by default the {@link SingleInstanceLockFactory} + * but can be changed with {@link #setLockFactory}. + * + */ + class CLUCENE_EXPORT RAMDirectory:public Directory{ + protected: + typedef CL_NS(util)::CLHashMap > FileMap; + /// Removes an existing file in the directory. + virtual bool doDeleteFile(const char* name); + + /** + * Creates a new RAMDirectory instance from a different + * Directory implementation. This can be used to load + * a disk-based index into memory. + *

+ * This should be used only with indices that can fit into memory. + * + * @param dir a Directory value + * @exception IOException if an error occurs + */ + void _copyFromDir(Directory* dir, bool closeDir); + FileMap* files; // unlike the java Hashtable, FileMap is not synchronized, and all access must be protected by a lock + public: + int64_t sizeInBytes; //todo + + DEFINE_MUTABLE_MUTEX(files_mutex) // mutable: const methods must also be able to synchronize properly + + /// Returns a null terminated array of strings, one for each file in the directory. + bool list(std::vector* names) const; + + /** Constructs an empty {@link Directory}. */ + RAMDirectory(); + + ///Destructor - only call this if you are sure the directory + ///is not being used anymore. Otherwise use the ref-counting + ///facilities of dir->close + virtual ~RAMDirectory(); + + RAMDirectory(Directory* dir); + + /** + * Creates a new RAMDirectory instance from the {@link FSDirectory}. + * + * @param dir a String specifying the full index directory path + */ + RAMDirectory(const char* dir); + + /// Returns true iff the named file exists in this directory. + bool fileExists(const char* name) const; + + /// Returns the time the named file was last modified. + int64_t fileModified(const char* name) const; + + /// Returns the length in bytes of a file in the directory. + int64_t fileLength(const char* name) const; + + /// Removes an existing file in the directory. + virtual void renameFile(const char* from, const char* to); + + /** Set the modified time of an existing file to now. */ + void touchFile(const char* name); + + /// Creates a new, empty file in the directory with the given name. + /// Returns a stream writing this file. + virtual IndexOutput* createOutput(const char* name); + + /// Returns a stream reading an existing file. + bool openInput(const char* name, IndexInput*& ret, CLuceneError& error, int32_t bufferSize = -1); + + virtual void close(); + + std::string toString() const; + + static const char* getClassName(); + const char* getObjectName() const; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/store/_Lock.h b/src/core/CLucene/store/_Lock.h new file mode 100644 index 00000000000..b44d05d8151 --- /dev/null +++ b/src/core/CLucene/store/_Lock.h @@ -0,0 +1,134 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_intlLock_ +#define _lucene_store_intlLock_ + +#include "Lock.h" +#include + +CL_NS_DEF(store) + + +class LocksType: public CL_NS(util)::CLHashSet +{ +public: + LocksType() + { + setDoDelete(false); + } + virtual ~LocksType(){ + } +}; + + class SingleInstanceLock: public LuceneLock { + private: + const char* lockName; + LocksType* locks; + DEFINE_MUTEX(*locks_LOCK) + + public: + SingleInstanceLock( LocksType* locks, _LUCENE_THREADMUTEX* locks_LOCK, const char* lockName ); + virtual ~SingleInstanceLock(); + bool obtain(); + void release(); + bool isLocked(); + std::string toString(); + + static const char* getClassName(); + const char* getObjectName() const; + }; + + + + class NoLock: public LuceneLock { + public: + bool obtain(); + void release(); + bool isLocked(); + std::string toString(); + + static const char* getClassName(); + const char* getObjectName() const; + }; + + class FSLock: public LuceneLock { + private: + char* lockFile; + char* lockDir; + int filemode; + public: + FSLock( const char* _lockDir, const char* name, int filemode = -1 ); + ~FSLock(); + + bool obtain(); + void release(); + bool isLocked(); + std::string toString(); + + static const char* getClassName(); + const char* getObjectName() const; + }; + + // Utility class for executing code with exclusive access. + template + class LuceneLockWith { + private: + LuceneLock* lock; + int64_t lockWaitTimeout; + + protected: + // Code to execute with exclusive access. + virtual T doBody() = 0; + + // Constructs an executor that will grab the named lock. + public: + /** Constructs an executor that will grab the named lock. + * Defaults lockWaitTimeout to LUCENE_COMMIT_LOCK_TIMEOUT. + * @deprecated Kept only to avoid breaking existing code. + */ + LuceneLockWith(LuceneLock* lock, int64_t lockWaitTimeout) { + this->lock = lock; + this->lockWaitTimeout = lockWaitTimeout; + } + virtual ~LuceneLockWith(){ + } + + /** Calls {@link #doBody} while lock is obtained. Blocks if lock + * cannot be obtained immediately. Retries to obtain lock once per second + * until it is obtained, or until it has tried ten times. Lock is released when + * {@link #doBody} exits. */ + T runAndReturn() { + bool locked = false; + T ret = NULL; + try { + locked = lock->obtain(lockWaitTimeout); + ret = doBody(); + }_CLFINALLY( + if (locked) + lock->release(); + ); + return ret; + } + + /** @see runAndReturn + * Same as runAndReturn, except doesn't return any value. + * The only difference is that no void values are used + */ + void run() { + bool locked = false; + try { + locked = lock->obtain(lockWaitTimeout); + doBody(); + }_CLFINALLY( + if (locked) + lock->release(); + ); + } + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/store/_MMapIndexInput.h b/src/core/CLucene/store/_MMapIndexInput.h new file mode 100644 index 00000000000..fc31a0d2f5d --- /dev/null +++ b/src/core/CLucene/store/_MMapIndexInput.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_MMap_ +#define _lucene_store_MMap_ + +#include "IndexInput.h" + +CL_NS_DEF(store) + +class MMapIndexInput : public IndexInput { + class Internal; + Internal* _internal; + + MMapIndexInput(const MMapIndexInput& clone); + MMapIndexInput(Internal* _internal); +public: + static bool open(const char* path, IndexInput*& ret, CLuceneError& error, int32_t __bufferSize); + + ~MMapIndexInput(); + IndexInput* clone() const; + + inline uint8_t readByte(); + int32_t readVInt(); + void readBytes(uint8_t* b, const int32_t len); + void readBytes(uint8_t* b, const int32_t len, int32_t offset); + void close(); + int64_t getFilePointer() const; + void seek(const int64_t pos); + int64_t length() const; + + const char* getObjectName() const{ return MMapIndexInput::getClassName(); } + static const char* getClassName(){ return "MMapIndexInput"; } + const char* getDirectoryType() const{ return "MMapDirectory"; } +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/store/_RAMDirectory.h b/src/core/CLucene/store/_RAMDirectory.h new file mode 100644 index 00000000000..232b7efd83a --- /dev/null +++ b/src/core/CLucene/store/_RAMDirectory.h @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_store_intl_RAMDirectory_ +#define _lucene_store_intl_RAMDirectory_ + +#include "RAMDirectory.h" + +#include "IndexInput.h" +#include "IndexOutput.h" +//#include "Lock.h" +//#include "Directory.h" +//#include "CLucene/util/VoidMap.h" +//#include "CLucene/util/Arrays.h" + +CL_NS_DEF(store) + +class CLUCENE_EXPORT RAMFile : LUCENE_BASE { +private: + struct RAMFileBuffer : LUCENE_BASE { + uint8_t *_buffer; + size_t _len; + RAMFileBuffer(uint8_t *buf = NULL, size_t len = 0) : _buffer(buf), _len(len){}; + virtual ~RAMFileBuffer() { _CLDELETE_LARRAY(_buffer); }; + }; + + + CL_NS(util)::CLVector> buffers; + + + int64_t length; + int64_t sizeInBytes;// Only maintained if in a directory; updates synchronized on directory + + // This is publicly modifiable via Directory::touchFile(), so direct access not supported + uint64_t lastModified; + +protected: + RAMDirectory *directory; + +public: + DEFINE_MUTEX(THIS_LOCK) + + // File used as buffer, in no RAMDirectory + RAMFile(RAMDirectory *directory = NULL); + virtual ~RAMFile(); + + // For non-stream access from thread that might be concurrent with writing + int64_t getLength(); + void setLength(const int64_t _length); + + // For non-stream access from thread that might be concurrent with writing + uint64_t getLastModified(); + void setLastModified(const uint64_t lastModified); + + uint8_t *addBuffer(const int32_t size); + uint8_t *getBuffer(const int32_t index); + size_t getBufferLen(const int32_t index) const { return buffers[index]->_len; } + int32_t numBuffers() const; + uint8_t *newBuffer(const int32_t size); + + int64_t getSizeInBytes() const; + + friend class RAMDirectory; +}; + +class CLUCENE_EXPORT RAMOutputStream : public IndexOutput { +protected: + RAMFile *file; + bool deleteFile; + + uint8_t *currentBuffer; + int32_t currentBufferIndex; + + int32_t bufferPosition; + int64_t bufferStart; + int32_t bufferLength; + + void switchCurrentBuffer(); + void setFileLength(); + +public: + LUCENE_STATIC_CONSTANT(int32_t, BUFFER_SIZE = 1024); + + RAMOutputStream(RAMFile *f); + RAMOutputStream(); + /** Construct an empty output buffer. */ + virtual ~RAMOutputStream(); + + virtual void close(); + + int64_t length() const; + /** Resets this to an empty buffer. */ + void reset(); + /** Copy the current contents of this buffer to the named output. */ + void writeTo(IndexOutput *output); + void writeTo(std::vector &bytes, int offset); + + void writeByte(uint8_t b) override; + void writeBytes(const uint8_t *b, int32_t len) override; + void writeBytes(const uint8_t *b, int32_t len, int32_t offset) override; + + void seek(const int64_t pos); + + void flush(); + + int64_t getFilePointer() const; + + const char *getObjectName(); + static const char *getClassName(); +}; +typedef RAMOutputStream RAMIndexOutput;//deprecated + +class CLUCENE_EXPORT RAMInputStream : public IndexInput { +private: + RAMFile *file; + int64_t _length; + + uint8_t *currentBuffer; + int32_t currentBufferIndex; + + int32_t bufferPosition; + int64_t bufferStart; + int32_t bufferLength; + + void switchCurrentBuffer(); + +protected: + /** IndexInput methods */ + RAMInputStream(const RAMInputStream &clone); + +public: + LUCENE_STATIC_CONSTANT(int32_t, BUFFER_SIZE = RAMOutputStream::BUFFER_SIZE); + + RAMInputStream(RAMFile *f); + virtual ~RAMInputStream(); + IndexInput *clone() const; + + void close(); + int64_t length() const; + + uint8_t readByte(); + void readBytes(uint8_t *dest, const int32_t len); + void readBytes(uint8_t *dest, const int32_t len, int32_t offset); + + + int64_t getFilePointer() const; + + void seek(const int64_t pos); + const char *getDirectoryType() const; + const char *getObjectName() const; + static const char *getClassName(); +}; +typedef RAMInputStream RAMIndexInput;//deprecated + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/Array.h b/src/core/CLucene/util/Array.h new file mode 100644 index 00000000000..c1bd844adc0 --- /dev/null +++ b/src/core/CLucene/util/Array.h @@ -0,0 +1,340 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_Array_ +#define _lucene_util_Array_ + +#include +#include + +CL_NS_DEF(util) + +template +class CLUCENE_INLINE_EXPORT ArrayBase: LUCENE_BASE{ +public: + T* values; + size_t length; + + /** + * Delete's the values in the array. + * This won't do anything if deleteArray or takeArray is called first. + * This is overridden in various implementations to provide the appropriate deletor function. + */ + virtual void deleteValues(){ + if ( this->values == NULL ) + return; + for (size_t i=0;ilength;i++){ + deleteValue(this->values[i]); + } + } + /** + * Delete's a single value. Used when resizing... + */ + virtual void deleteValue(T) = 0; + + /** + * Delete's the values in the array and then calls deleteArray(). + * This won't do anything if deleteArray or takeArray is called first. + * This is overridden in various implementations to provide the appropriate deletor function. + */ + void deleteAll(){ + this->deleteValues(); + this->deleteArray(); + } + + /** + * Deletes the array holding the values. Do this if you want to take + * ownership of the array's values, but not the array containing the values. + */ + void deleteArray(){ + free(this->values); + this->values = NULL; + } + /** + * Empties the array. Do this if you want to take ownership of the array + * and the array's values. + */ + T* takeArray(){ + T* ret = values; + values = NULL; + return ret; + } + + ArrayBase(const size_t initialLength = 0) + : values(NULL), length(initialLength) + { + if (initialLength > 0) + { + this->values = (T*)malloc(sizeof(T)*length); + memset(this->values,0,sizeof(T)*length); + } + } + ArrayBase(T* _values, const size_t _length) + : values(_values), length(_length) + { + } + virtual ~ArrayBase(){ + } + + const T& operator[](const size_t _Pos) const + { + if (length <= _Pos){ + _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range"); + } + return (*(values + _Pos)); + } + T& operator[](const size_t _Pos) + { + if (length <= _Pos){ + _CLTHROWA(CL_ERR_IllegalArgument,"vector subscript out of range"); + } + return (*(values + _Pos)); + } + + /** + * Resize the array + * @param deleteValues if shrinking, delete the values that are lost. + */ + void resize(const size_t newSize, const bool deleteValues=false){ + if ( length == newSize ) return; + + if ( values == NULL ) + { + values = (T*)malloc(sizeof(T)*newSize); + memset(values,0,sizeof(T) * newSize); + length = newSize; + return; + } + + if (length < newSize) + { + values = (T*)realloc(values, sizeof(T) * newSize); + memset(values + length,0,sizeof(T) * (newSize-length)); + } + else // length > newSize, including newSize == 0 + { + if ( deleteValues ){ + for ( size_t i=newSize;i +class CLUCENE_INLINE_EXPORT ObjectArray: public ArrayBase{ +public: + ObjectArray():ArrayBase(){} + ObjectArray(T** values, size_t length):ArrayBase(values,length){} + ObjectArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + for (size_t i=0;ilength;++i){ + _CLLDELETE(this->values[i]); + } + this->deleteArray(); + } + void deleteUntilNULL(){ + if ( this->values == NULL ) + return; + for (size_t i=0;ilength && this->values[i] != NULL;++i){ + _CLLDELETE(this->values[i]); + } + this->deleteArray(); + } + void deleteValue(T* v){ + _CLLDELETE(v); + } + virtual ~ObjectArray(){ + deleteValues(); + } + + /* Initializes all cells in the array with a NULL value */ + void initArray(){ + for (size_t i=0;ilength;i++){ + this->values[i]=NULL; + } + } +}; + +/** +* Legacy code... don't use, remove all instances of this! +*/ +template +class CLUCENE_INLINE_EXPORT Array: public ArrayBase{ +public: + _CL_DEPRECATED(ObjectArray or ValueArray) Array():ArrayBase(){} + _CL_DEPRECATED(ObjectArray or ValueArray) Array(T* values, size_t length):ArrayBase(values,length){} + _CL_DEPRECATED(ObjectArray or ValueArray) Array(size_t length):ArrayBase(length){} + void deleteValues(){ + if ( this->values == NULL ) + return; + this->deleteArray(); + } + void deleteValue(T v){} //nothing to do... + virtual ~Array(){ + } +}; + +/** +* An array where the values do not need to be deleted +*/ +template +class CLUCENE_INLINE_EXPORT ValueArray: public ArrayBase{ +public: + ValueArray():ArrayBase(){} + ValueArray(T* values, size_t length):ArrayBase(values,length){} + ValueArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + this->deleteArray(); + } + void deleteValue(T /*v*/){} //nothing to do... + virtual ~ValueArray(){ + deleteValues(); + } +}; + +/** A value array for const values (never deleted) */ +template +class CLUCENE_INLINE_EXPORT ConstValueArray: public ArrayBase{ +public: + ConstValueArray():ArrayBase(){} + ConstValueArray(T* values, size_t length):ArrayBase(values,length){} + ConstValueArray(size_t length):ArrayBase(length){} + + void deleteValues(){} + void deleteValue(T /*v*/){} //nothing to do... + virtual ~ConstValueArray(){} +}; + + +/** +* An array of TCHAR strings +*/ +class CLUCENE_INLINE_EXPORT TCharArray: public ArrayBase{ +public: + TCharArray():ArrayBase(){} + TCharArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + for (size_t i=0;ilength;i++) + _CLDELETE_CARRAY(this->values[i]); + this->deleteArray(); + } + void deleteValue(TCHAR* v){ + _CLDELETE_LCARRAY(v); + } + virtual ~TCharArray(){ + deleteValues(); + } +}; + +/** +* An array of char strings +*/ +class CLUCENE_INLINE_EXPORT CharArray: public ArrayBase{ +public: + CharArray():ArrayBase(){} + CharArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + for (size_t i=0;ilength;i++) + _CLDELETE_CaARRAY(this->values[i]); + this->deleteArray(); + } + virtual ~CharArray(){ + deleteValues(); + } +}; + +/** +* An array of const TCHAR strings +*/ +class CLUCENE_INLINE_EXPORT TCharConstArray: public ArrayBase{ +public: + TCharConstArray():ArrayBase(){} + TCharConstArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + { + return; + } + this->deleteArray(); + } + virtual ~TCharConstArray(){ + deleteValues(); + } +}; + +/** +* An array of const char strings +*/ +class CLUCENE_INLINE_EXPORT CharConstArray: public ArrayBase{ +public: + CharConstArray():ArrayBase(){} + CharConstArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + this->deleteArray(); + } + virtual ~CharConstArray(){ + deleteValues(); + } +}; + +/** An array that uses _CLDECDELETE for deletion */ +template +class CLUCENE_INLINE_EXPORT RefCountArray: public ArrayBase{ +public: + RefCountArray():ArrayBase(){} + RefCountArray(T* values, size_t length):ArrayBase(values,length){} + RefCountArray(size_t length):ArrayBase(length){} + + void deleteValues(){ + if ( this->values == NULL ) + return; + ArrayBase::deleteValues(); + this->deleteArray(); + } + void deleteValue(T v){ + _CLDECDELETE(v); + } //nothing to do... + virtual ~RefCountArray(){ + deleteValues(); + } +}; + + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/BitSet.cpp b/src/core/CLucene/util/BitSet.cpp new file mode 100644 index 00000000000..c4efe352f9f --- /dev/null +++ b/src/core/CLucene/util/BitSet.cpp @@ -0,0 +1,198 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "BitSet.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" + +CL_NS_USE(store) +CL_NS_DEF(util) + + +const uint8_t BitSet::BYTE_COUNTS[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; + +BitSet::BitSet( const BitSet& copy ) : + _size( copy._size ), + _count(-1) +{ + int32_t len = (_size >> 3) + 1; + bits = _CL_NEWARRAY(uint8_t, len); + memcpy( bits, copy.bits, len ); +} + +BitSet::BitSet ( int32_t size ): + _size(size), + _count(-1) +{ + int32_t len = (_size >> 3) + 1; + bits = _CL_NEWARRAY(uint8_t, len); + memset(bits,0,len); +} + +BitSet::BitSet(CL_NS(store)::Directory* d, const char* name) +{ + _count=-1; + CL_NS(store)::IndexInput* input = d->openInput( name ); + try { + _size = input->readInt(); // read size + if (_size == -1) { + readDgaps(input); + } else { + readBits(input); + } + } _CLFINALLY ( + input->close(); + _CLDELETE(input ); + ); +} + +void BitSet::write(CL_NS(store)::Directory* d, const char* name) { + CL_NS(store)::IndexOutput* output = d->createOutput(name); + try { + if (isSparse()) { + writeDgaps(output); // sparse bit-set more efficiently saved as d-gaps. + } else { + writeBits(output); + } + } _CLFINALLY ( + output->close(); + _CLDELETE(output); + ); +} +BitSet::~BitSet(){ + _CLDELETE_ARRAY(bits); +} + + +void BitSet::set(const int32_t bit, bool val){ + if (bit >= _size) { + _CLTHROWA(CL_ERR_IndexOutOfBounds, "bit out of range"); + } + + _count = -1; + + if (val) + bits[bit >> 3] |= 1 << (bit & 7); + else + bits[bit >> 3] &= ~(1 << (bit & 7)); +} + +int32_t BitSet::size() const { + return _size; +} +int32_t BitSet::count(){ + // if the BitSet has been modified + if (_count == -1) { + + int32_t c = 0; + int32_t end = (_size >> 3) + 1; + for (int32_t i = 0; i < end; i++) + c += BYTE_COUNTS[bits[i]]; // sum bits per uint8_t + _count = c; + } + return _count; +} +BitSet* BitSet::clone() const { + return _CLNEW BitSet( *this ); +} + + /** Read as a bit set */ + void BitSet::readBits(IndexInput* input) { + _count = input->readInt(); // read count + bits = _CL_NEWARRAY(uint8_t,(_size >> 3) + 1); // allocate bits + input->readBytes(bits, (_size >> 3) + 1); // read bits + } + + /** read as a d-gaps list */ + void BitSet::readDgaps(IndexInput* input) { + _size = input->readInt(); // (re)read size + _count = input->readInt(); // read count + bits = _CL_NEWARRAY(uint8_t,(_size >> 3) + 1); // allocate bits + int32_t last=0; + int32_t n = count(); + while (n>0) { + last += input->readVInt(); + bits[last] = input->readByte(); + n -= BYTE_COUNTS[bits[last] & 0xFF]; + } + } + + /** Write as a bit set */ + void BitSet::writeBits(IndexOutput* output) { + output->writeInt(size()); // write size + output->writeInt(count()); // write count + output->writeBytes(bits, (_size >> 3) + 1); // write bits + } + + /** Write as a d-gaps list */ + void BitSet::writeDgaps(IndexOutput* output) { + output->writeInt(-1); // mark using d-gaps + output->writeInt(size()); // write size + output->writeInt(count()); // write count + int32_t last=0; + int32_t n = count(); + int32_t m = (_size >> 3) + 1; + for (int32_t i=0; i0; i++) { + if (bits[i]!=0) { + output->writeVInt(i-last); + output->writeByte(bits[i]); + last = i; + n -= BYTE_COUNTS[bits[i] & 0xFF]; + } + } + } + + /** Indicates if the bit vector is sparse and should be saved as a d-gaps list, or dense, and should be saved as a bit set. */ + bool BitSet::isSparse() { + // note: order of comparisons below set to favor smaller values (no binary range search.) + // note: adding 4 because we start with ((int) -1) to indicate d-gaps format. + // note: we write the d-gap for the byte number, and the byte (bits[i]) itself, therefore + // multiplying count by (8+8) or (8+16) or (8+24) etc.: + // - first 8 for writing bits[i] (1 byte vs. 1 bit), and + // - second part for writing the byte-number d-gap as vint. + // note: factor is for read/write of byte-arrays being faster than vints. + int32_t factor = 10; + if ((_size >> 3) < (1<< 7)) return factor * (4 + (8+ 8)*count()) < size(); + if ((_size >> 3) < (1<<14)) return factor * (4 + (8+16)*count()) < size(); + if ((_size >> 3) < (1<<21)) return factor * (4 + (8+24)*count()) < size(); + if ((_size >> 3) < (1<<28)) return factor * (4 + (8+32)*count()) < size(); + return factor * (4 + (8+40)*count()) < size(); + } + + int32_t BitSet::nextSetBit(int32_t fromIndex) const { + if (fromIndex < 0) + _CLTHROWT(CL_ERR_IndexOutOfBounds, _T("fromIndex < 0")); + + if (fromIndex >= _size) + return -1; + + while (true) { + if ((bits[fromIndex >> 3] & (1 << (fromIndex & 7))) != 0) + return fromIndex; + if (++fromIndex == _size) + return -1; + } + } + +CL_NS_END diff --git a/src/core/CLucene/util/BitSet.h b/src/core/CLucene/util/BitSet.h new file mode 100644 index 00000000000..296e18662d1 --- /dev/null +++ b/src/core/CLucene/util/BitSet.h @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_BitSet_ +#define _lucene_util_BitSet_ + + +CL_CLASS_DEF(store,Directory) +CL_CLASS_DEF(store,IndexInput) +CL_CLASS_DEF(store,IndexOutput) + +CL_NS_DEF(util) + + +/** Optimized implementation of a vector of bits. This is more-or-less like + java.util.BitSet, but also includes the following: +

    +
  • a count() method, which efficiently computes the number of one bits;
  • +
  • optimized read from and write to disk;
  • +
  • inlinable get() method;
  • +
  • store and load, as bit set or d-gaps, depending on sparseness;
  • +
+ */ +class CLUCENE_EXPORT BitSet:LUCENE_BASE { + int32_t _size; + int32_t _count; + uint8_t *bits; + + void readBits(CL_NS(store)::IndexInput* input); + /** read as a d-gaps list */ + void readDgaps(CL_NS(store)::IndexInput* input); + /** Write as a bit set */ + void writeBits(CL_NS(store)::IndexOutput* output); + /** Write as a d-gaps list */ + void writeDgaps(CL_NS(store)::IndexOutput* output); + /** Indicates if the bit vector is sparse and should be saved as a d-gaps list, or dense, and should be saved as a bit set. */ + bool isSparse(); + static const uint8_t BYTE_COUNTS[256]; +protected: + BitSet( const BitSet& copy ); + +public: + ///Create a bitset with the specified size + BitSet ( int32_t size ); + BitSet(CL_NS(store)::Directory* d, const char* name); + void write(CL_NS(store)::Directory* d, const char* name); + + ///Destructor for the bit set + ~BitSet(); + + ///get the value of the specified bit + ///get the value of the specified bit + inline bool get(const int32_t bit) const{ + if (bit >= _size) { + _CLTHROWA(CL_ERR_IndexOutOfBounds, "bit out of range"); + } + return (bits[bit >> 3] & (1 << (bit & 7))) != 0; + } + + /** + * Returns the index of the first bit that is set to {@code true} + * that occurs on or after the specified starting index. If no such + * bit exists then {@code -1} is returned. + * + *

To iterate over the {@code true} bits in a {@code BitSet}, + * use the following loop: + * + *

 {@code
+    * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+    *     // operate on index i here
+    * }}
+ * + * @param fromIndex the index to start checking from (inclusive) + * @return the index of the next set bit, or {@code -1} if there + * is no such bit + * @throws IndexOutOfBounds if the specified index is negative + * + */ + int32_t nextSetBit(int32_t fromIndex) const; + + ///set the value of the specified bit + void set(const int32_t bit, bool val=true); + + ///returns the size of the bitset + int32_t size() const; + + /// Returns the total number of one bits in this BitSet. This is efficiently + /// computed and cached, so that, if the BitSet is not changed, no + /// recomputation is done for repeated calls. + int32_t count(); + BitSet *clone() const; +}; +typedef BitSet BitVector; //Lucene now calls the BitSet a BitVector... + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/BitUtil.cpp b/src/core/CLucene/util/BitUtil.cpp new file mode 100644 index 00000000000..ba6f079b64f --- /dev/null +++ b/src/core/CLucene/util/BitUtil.cpp @@ -0,0 +1,24 @@ +#include "BitUtil.h" + +#include +CL_NS_DEF(util) + +std::vector const BitUtil::MAGIC = { + 0x5555555555555555LL, 0x3333333333333333LL, 0x0F0F0F0F0F0F0F0FLL, + 0x00FF00FF00FF00FFLL, 0x0000FFFF0000FFFFLL, 0x00000000FFFFFFFFLL, + 0xAAAAAAAAAAAAAAAALL}; +std::vector const BitUtil::SHIFT = {1, 2, 4, 8, 16}; + +BitUtil::BitUtil() = default; // no instance + +int64_t BitUtil::pop_array(std::vector &arr, int wordOffset, + int numWords) +{ + int64_t popCount = 0; + for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { + std::bitset<64> bit_count{arr[i]}; + popCount += bit_count.count(); + } + return popCount; +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/BitUtil.h b/src/core/CLucene/util/BitUtil.h new file mode 100644 index 00000000000..df2fa5ed7fd --- /dev/null +++ b/src/core/CLucene/util/BitUtil.h @@ -0,0 +1,28 @@ +#pragma once +#include "CLucene/SharedHeader.h" + +#include + +CL_NS_DEF(util) + class BitUtil + { + + // magic numbers for bit interleaving + private: + static std::vector const MAGIC; + // shift values for bit interleaving + static std::vector const SHIFT; + + BitUtil(); + + // The pop methods used to rely on bit-manipulation tricks for speed but it + // turns out that it is faster to use the Long.bitCount method (which is an + // intrinsic since Java 6u18) in a naive loop, see LUCENE-2221 + + /** Returns the number of set bits in an array of longs. */ + public: + static int64_t pop_array(std::vector &arr, int wordOffset, + int numWords); + }; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/BytesRef.cpp b/src/core/CLucene/util/BytesRef.cpp new file mode 100644 index 00000000000..08cd61d1fcf --- /dev/null +++ b/src/core/CLucene/util/BytesRef.cpp @@ -0,0 +1,73 @@ +#include "BytesRef.h" +#include "FutureArrays.h" + +#include + +CL_NS_DEF(util) + +std::vector BytesRef::EMPTY_BYTES = std::vector(0); + +BytesRef::BytesRef() : BytesRef((EMPTY_BYTES)) {} + +BytesRef::BytesRef(std::vector &bytes, int offset, int length) { + this->bytes = bytes; + this->offset = offset; + this->length = length; + //assert(isValid()); +} + +BytesRef::BytesRef(std::vector &bytes) : BytesRef(bytes, 0, bytes.size()) { +} + +BytesRef::BytesRef(int capacity) { this->bytes = std::vector(capacity); } + +bool BytesRef::BytesEquals(BytesRef &other) { + return FutureArrays::Equals(bytes, offset, offset + length, + other.bytes, other.offset, other.offset + other.length); +} + +std::shared_ptr BytesRef::clone() { + return std::make_shared(bytes, offset, length); +} + +std::shared_ptr BytesRef::deepCopyOf(const std::shared_ptr& other) { + std::shared_ptr copy = std::make_shared(); + std::copy(other->bytes.begin(), + other->bytes.begin() + other->offset + other->length, + copy->bytes.begin()); + copy->offset = 0; + copy->length = other->length; + return copy; +} + +int BytesRef::CompareTo(BytesRef &other) { + return FutureArrays::CompareUnsigned( + bytes, offset, offset + length, other.bytes, + other.offset, other.offset + other.length); +} + +bool BytesRef::isValid() { + if (bytes.empty()) { + return false; + } + if (length < 0) { + return false; + } + if (length > bytes.size()) { + return false; + } + if (offset < 0) { + return false; + } + if (offset > bytes.size()) { + return false; + } + if (offset + length < 0) { + return false; + } + if (offset + length > bytes.size()) { + return false; + } + return true; +} +CL_NS_END diff --git a/src/core/CLucene/util/BytesRef.h b/src/core/CLucene/util/BytesRef.h new file mode 100644 index 00000000000..cbb619a67e8 --- /dev/null +++ b/src/core/CLucene/util/BytesRef.h @@ -0,0 +1,95 @@ +#pragma once +#include "CLucene/SharedHeader.h" + +#include +#include +#include +#include + +CL_NS_DEF(util) + +/** Represents byte[], as a slice (offset + length) into an + * existing byte[]. The {@link #bytes} member should never be null; + * use {@link #EMPTY_BYTES} if necessary. + * + *

Important note: Unless otherwise noted, Lucene uses this class to + * represent terms that are encoded as UTF8 bytes in the index. To + * convert them to a Java {@link std::wstring} (which is UTF16), use {@link + * #utf8ToString}. Using code like {@code new std::wstring(bytes, offset, length)} to + * do this is wrong, as it does not respect the correct character set and + * may return wrong results (depending on the platform's defaults)! + * + *

{@code BytesRef} implements {@link Comparable}. The underlying byte arrays + * are sorted lexicographically, numerically treating elements as unsigned. + * This is identical to Unicode codepoint order. + */ +class BytesRef final : public std::enable_shared_from_this { + /** An empty byte array for convenience */ +public: + static std::vector EMPTY_BYTES; + + /** The contents of the BytesRef. Should never be {@code null}. */ + std::vector bytes; + + /** Offset of first valid byte. */ + int offset = 0; + + /** Length of used bytes. */ + int length = 0; + + /** Create a BytesRef with {@link #EMPTY_BYTES} */ + BytesRef(); + + /** This instance will directly reference bytes w/o making a copy. + * bytes should not be null. + */ + BytesRef(std::vector &bytes, int offset, int length); + + /** This instance will directly reference bytes w/o making a copy. + * bytes should not be null */ + explicit BytesRef(std::vector &bytes); + + /** + * Create a BytesRef pointing to a new array of size capacity. + * Offset and length will both be zero. + */ + explicit BytesRef(int capacity); + + /** + * Expert: compares the bytes against another BytesRef, + * returning true if the bytes are equal. + * + * @param other Another BytesRef, should not be null. + * @lucene.internal + */ + bool BytesEquals(BytesRef &other); + + /** + * Returns a shallow clone of this instance (the underlying bytes are + * not copied and will be shared by both the returned object and this + * object. + * + * @see #deepCopyOf + */ + std::shared_ptr clone(); + static std::shared_ptr deepCopyOf(const std::shared_ptr& other); + + /** Unsigned byte order comparison */ + int CompareTo(BytesRef& other); + + /** + * Creates a new BytesRef that points to a copy of the bytes from + * other + *

+ * The returned BytesRef will have a length of other.length + * and an offset of zero. + */ + //static std::shared_ptr deepCopyOf(std::shared_ptr other); + + /** + * Performs internal consistency checks. + * Always returns true (or throws IllegalStateException) + */ + bool isValid(); +}; +CL_NS_END diff --git a/src/core/CLucene/util/BytesRefBuilder.cpp b/src/core/CLucene/util/BytesRefBuilder.cpp new file mode 100644 index 00000000000..c72b80d8c8e --- /dev/null +++ b/src/core/CLucene/util/BytesRefBuilder.cpp @@ -0,0 +1,50 @@ +#include "BytesRefBuilder.h" + +CL_NS_DEF(util) + + +BytesRefBuilder::BytesRefBuilder() : ref_(std::make_shared()) {} + +std::vector BytesRefBuilder::bytes() { return ref_->bytes; } + +int BytesRefBuilder::length() { return ref_->length; } + +void BytesRefBuilder::setLength(int length) { ref_->length = length; } + +uint8_t BytesRefBuilder::byteAt(int offset) { return ref_->bytes.at(offset); } + +void BytesRefBuilder::setByteAt(int offset, uint8_t b) { ref_->bytes.at(offset) = b; } + +void BytesRefBuilder::grow(int capacity) { + ref_->bytes.resize(capacity); +} + +void BytesRefBuilder::append(uint8_t b) { + grow(ref_->length + 1); + ref_->bytes.at(ref_->length++) = b; +} + +void BytesRefBuilder::append(std::vector &b, int off, int len) { + grow(ref_->length + len); + //std::copy(b, off, ref_->bytes, ref_->length, len); + //TODO:need to check overflow here + std::copy(b.begin()+off, b.begin()+off+len, ref_->bytes.begin()+ref_->length); + ref_->length += len; +} + +void BytesRefBuilder::append(const std::shared_ptr& ref) { + append(ref->bytes, ref->offset, ref->length); +} + +void BytesRefBuilder::append(const std::shared_ptr& builder) { + append(builder->get()); +} + +void BytesRefBuilder::clear() { setLength(0); } + +std::shared_ptr BytesRefBuilder::get() { + assert((ref_->offset == 0, + L"Modifying the offset of the returned ref is illegal")); + return ref_; +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/BytesRefBuilder.h b/src/core/CLucene/util/BytesRefBuilder.h new file mode 100644 index 00000000000..95d74464752 --- /dev/null +++ b/src/core/CLucene/util/BytesRefBuilder.h @@ -0,0 +1,78 @@ +#pragma once +#include "CLucene/SharedHeader.h" +#include "CLucene/util/BytesRef.h" + +#include + +CL_NS_DEF(util) + +/** + * A builder for {@link BytesRef} instances. + * @lucene.internal + */ +class BytesRefBuilder : public std::enable_shared_from_this +{ + +private: + const std::shared_ptr ref_; + + /** Sole constructor. */ +public: + BytesRefBuilder(); + + /** Return a reference to the bytes of this builder. */ + virtual std::vector bytes(); + + /** Return the number of bytes in this buffer. */ + virtual int length(); + + /** Set the length. */ + virtual void setLength(int length); + + /** Return the byte at the given offset. */ + virtual uint8_t byteAt(int offset); + + /** Set a byte. */ + virtual void setByteAt(int offset, uint8_t b); + + /** + * Ensure that this builder can hold at least capacity bytes + * without resizing. + */ + virtual void grow(int capacity); + + /** + * Append a single byte to this builder. + */ + virtual void append(uint8_t b); + + /** + * Append the provided bytes to this builder. + */ + virtual void append(std::vector &b, int off, int len); + + /** + * Append the provided bytes to this builder. + */ + virtual void append(const std::shared_ptr& ref); + + /** + * Append the provided bytes to this builder. + */ + virtual void append(const std::shared_ptr& builder); + + /** + * Reset this builder to the empty state. + */ + virtual void clear(); + + /** + * Return a {@link BytesRef} that points to the internal content of this + * builder. Any update to the content of this builder might invalidate + * the provided ref and vice-versa. + */ + virtual std::shared_ptr get(); + +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/CLStreams.h b/src/core/CLucene/util/CLStreams.h new file mode 100644 index 00000000000..b7d89855058 --- /dev/null +++ b/src/core/CLucene/util/CLStreams.h @@ -0,0 +1,379 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_CLStreams_ +#define _lucene_util_CLStreams_ + +CL_NS_DEF(util) + +class IReader { +public: + virtual int32_t read(const void **start, int32_t min, int32_t max) = 0; + virtual int64_t skip(int64_t ntoskip) = 0; + virtual int64_t position() = 0; + virtual size_t size() = 0; +}; + +template +class CLUCENE_EXPORT CLStream: public IReader{ +public: + virtual ~CLStream(){} + + inline int read(){ + const T* buffer; + const int32_t nread = read((const void**)&buffer,1, 1); + if ( nread < 0 ) + return -1; + else + return buffer[0]; + } + + /** Read one line, return the length of the line read. + * If the string is longer than len, only len of that line will be copied + */ + inline int32_t readLine(T* buffer, size_t len){ + size_t i = 0; + while (true && i 0) + break; + else + continue; + } + buffer[i++] = b; + } + buffer[i] = 0; + return i; + } + + /** + * @brief Reads items from the stream and sets @p start to point to + * the first item that was read. + * + * Note: unless stated otherwise in the documentation for that method, + * this pointer will no longer be valid after calling another method of + * this class. The pointer will also no longer be valid after the class + * is destroyed. + * + * At least @p min items will be read from the stream, unless an error occurs + * or the end of the stream is reached. Under no circumstances will more than + * @p max items be read. + * + * If the end of the stream is reached before @p min items are read, the + * read is still considered successful and the number of items read will + * be returned. + * + * @param start pointer passed by reference that will be set to point to + * the retrieved array of items. If the end of the stream + * is encountered or an error occurs, the value of @p start + * is undefined + * @param min the minimal number of items to read from the stream. This + * value should be larger than 0. If it is 0 or smaller, the + * result is undefined + * @param max the maximal number of items to read from the stream. + * If this value is smaller than @p min, there is no limit on + * the number of items that can be read + * @return the number of items that were read. @c -1 is returned if + * end of the stream has already been reached. An error is thrown + * if an error occurs. + **/ + virtual int32_t read(const void ** start, int32_t min, int32_t max) = 0; + /** + * @brief Skip @p ntoskip items. + * + * If an error occurs, or the end of the stream is encountered, fewer + * than @p ntoskip items may be skipped. This can be checked by comparing + * the return value to @p ntoskip. + * + * Calling this function invalidates the data pointer that was obtained from + * StreamBase::read. + * + * @param ntoskip the number of items that should be skipped + * @return the number of items skipped + **/ + virtual int64_t skip(int64_t ntoskip) = 0; + /** + * @brief Get the current position in the stream. + * The value obtained from this function can be used to reset the stream. + **/ + virtual int64_t position() = 0; + int64_t getPosition(){ return this->position(); } + + virtual size_t size() = 0; +}; + +template +class CLUCENE_EXPORT BufferedStream{ +public: + virtual ~BufferedStream(){} + /** + * @brief Repositions this stream to a given position. + * + * A call to reset is only guaranteed to be successful when + * the requested position lies within the segment of a stream + * corresponding to a valid pointer obtained from read. + * In this case, the pointer will not be invalidated. + * + * Calling this function invalidates the data pointer that was obtained from + * StreamBase::read unless the conditions outlined above apply. + * + * To read n items, leaving the stream at the same position as before, you + * can do the following: + * @code + * int64_t start = stream.position(); + * if ( stream.read(data, min, max) > 0 ) { + * stream.reset(start); + * // The data pointer is still valid here + * } + * @endcode + * + * @param pos the position in the stream you want to go to, relative to + * the start of the stream + * @return the new position in the stream + **/ + virtual int64_t reset(int64_t) = 0; + /** + * @brief Sets the minimum size of the buffer + */ + virtual void setMinBufSize(int32_t s) = 0; +}; + +class BufferedReader; +class CLUCENE_EXPORT Reader: public CLStream{ +public: + ~Reader(){} + virtual BufferedReader* __asBufferedReader(){ return NULL; } +}; +class CLUCENE_EXPORT BufferedReader: public Reader, public BufferedStream{ +public: + _CL_DEPRECATED( setMinBufSize ) int64_t mark(int32_t readAheadlimit){ + this->setMinBufSize(readAheadlimit); + return this->position(); + } + ~BufferedReader(){} + BufferedReader* __asBufferedReader(){ return this; } +}; +typedef CLStream InputStream; +class CLUCENE_EXPORT BufferedInputStream: public InputStream, public BufferedStream{ +public: + virtual ~BufferedInputStream(){} +}; + +template +class CLUCENE_EXPORT SStringReader : public Reader { +protected: + const T *value; + bool ownValue{}; + int64_t pos{}; + size_t m_size{}; + size_t buffer_size{}; + +public: + SStringReader(): value(NULL), ownValue(false),pos(0),m_size(0),buffer_size(0){}; + SStringReader(const T *_value, const int32_t _length, bool copyData=true) { + this->m_size = 0; + this->value = NULL; + this->ownValue = true; + this->buffer_size = 0; + this->init(_value, _length, copyData); + } + void init(const T *_value, int32_t _length, bool copyData = true){ + const size_t length = _length; + this->pos = 0; + if (copyData) { + T *tmp = (T *) this->value; + if (tmp == NULL || !this->ownValue) { + tmp = _CL_NEWARRAY(T, length + 1); + this->buffer_size = length; + } else if (length > this->buffer_size || length < (this->buffer_size / 2)) {//expand, or shrink + tmp = (T *) realloc(tmp, sizeof(T) * (length + 1)); + this->buffer_size = length; + } + memcpy(tmp, _value, length + 1); + this->value = tmp; + } else { + if (ownValue && this->value != NULL) { + _CLDELETE_LARRAY((T *) this->value); + } + this->value = _value; + this->buffer_size = 0; + } + this->m_size = length; + this->ownValue = copyData; + }; + virtual ~SStringReader() { + if (ownValue && this->value != NULL) { + auto *v = (T *) this->value; + _CLDELETE_LARRAY(v); + this->value = NULL; + } + } + + int32_t read(const void **start, int32_t min, int32_t max) override { + if (m_size == pos) + return -1; + *(const T**)start = this->value + pos; + auto tmp = std::max(min, max); + int32_t r = (int32_t) std::min((size_t) tmp, m_size - pos); + pos += r; + return r; + } + int64_t position() override { + return pos; + } + int64_t reset(int64_t){ + if ( pos >= 0 && pos < this->m_size ) + this->pos = pos; + return this->pos; + } + int64_t skip(int64_t ntoskip) override{ + int64_t s = std::min(ntoskip, (int64_t)m_size-pos); + this->pos += s; + return s; + } + size_t size() override { + return m_size; + } +}; + +class CLUCENE_EXPORT FilteredBufferedReader: public BufferedReader{ + class Internal; + Internal* _internal; +public: + FilteredBufferedReader(Reader* reader, bool deleteReader); + virtual ~FilteredBufferedReader(); + + int32_t read(const void** start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + size_t size(); + void setMinBufSize(int32_t minbufsize); +}; + +class CLUCENE_EXPORT FilteredBufferedInputStream: public BufferedInputStream{ + class Internal; + Internal* _internal; +public: + FilteredBufferedInputStream(InputStream* input, bool deleteInput); + virtual ~FilteredBufferedInputStream(); + + int32_t read(const signed char*& start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + size_t size(); + void setMinBufSize(int32_t minbufsize); +}; + + +class CLUCENE_EXPORT StringReader: public BufferedReader{ +protected: + const TCHAR* value; + bool ownValue; + int64_t pos; + size_t m_size; + size_t buffer_size; +public: + StringReader ( const TCHAR* value, const int32_t length = -1, bool copyData = true ); + void init ( const TCHAR* value, const int32_t length, bool copyData = true ); + virtual ~StringReader(); + + int32_t read(const void** start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + void setMinBufSize(int32_t s); + size_t size(); +}; +class CLUCENE_EXPORT AStringReader: public BufferedInputStream{ + signed char* value; + bool ownValue; + int64_t pos; +protected: + size_t m_size; +public: + AStringReader ( const char* value, const int32_t length = -1 ); + AStringReader ( char* value, const int32_t length, bool copyData = true ); + virtual ~AStringReader(); + + int32_t read(const signed char*& start, int32_t min, int32_t max); + int32_t read(const unsigned char*& start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + void setMinBufSize(int32_t s); + size_t size(); +}; + +/** +* A helper class which constructs a FileReader with a specified +* simple encodings, or a given inputstreamreader +*/ +class CLUCENE_EXPORT FileInputStream: public BufferedInputStream { + class Internal; + Internal* _internal; +protected: + void init(InputStream *i, int encoding); +public: + LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_BUFFER_SIZE=4096); + FileInputStream ( const char* path, int32_t buflen = -1 ); + virtual ~FileInputStream (); + + int32_t read(const void** start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + size_t size(); + void setMinBufSize(int32_t minbufsize); +}; + +class CLUCENE_EXPORT SimpleInputStreamReader: public BufferedReader{ + class Internal; + Internal* _internal; +protected: + void init(InputStream *i, int encoding); +public: + enum{ + ASCII=1, + UTF8=2, + UCS2_LE=3 + }; + + SimpleInputStreamReader(); + SimpleInputStreamReader(InputStream *i, int encoding); + virtual ~SimpleInputStreamReader(); + + int32_t read(const void** start, int32_t min, int32_t max); + int64_t position(); + int64_t reset(int64_t); + int64_t skip(int64_t ntoskip); + void setMinBufSize(int32_t s); + size_t size(); +}; + +/** +* A helper class which constructs a FileReader with a specified +* simple encodings, or a given inputstreamreader. +* It is recommended that you use the contribs package for proper +* decoding using iconv. This class is provided only as a dependency-less +* replacement. +*/ +class CLUCENE_EXPORT FileReader: public SimpleInputStreamReader{ +public: + FileReader(const char* path, int encoding, int32_t buflen = -1); + FileReader(const char* path, const char* encoding, int32_t buflen = -1); + virtual ~FileReader(); +}; + +CL_NS_END + +#define jstreams CL_NS(util) + +#endif diff --git a/src/core/CLucene/util/CodecUtil.cpp b/src/core/CLucene/util/CodecUtil.cpp new file mode 100644 index 00000000000..bf282ae1957 --- /dev/null +++ b/src/core/CLucene/util/CodecUtil.cpp @@ -0,0 +1,53 @@ +#include "CodecUtil.h" +#include "BytesRef.h" +#include "CLucene/debug/error.h" + +CL_NS_DEF(util) + +CodecUtil::CodecUtil() = default;// no instance + +void CodecUtil::writeHeader(store::IndexOutput *out, const std::wstring &codec, + int version) { + std::vector codecVector(codec.begin(), codec.end()); + std::shared_ptr bytes = std::make_shared(codecVector); + if (bytes->length != codec.size() || bytes->length >= 128) { + _CLTHROWA(CL_ERR_IllegalArgument, "codec must be simple ASCII, less than 128 characters in length"); + } + out->writeInt(CODEC_MAGIC); + out->writeString(codec); + out->writeInt(version); +} + +int CodecUtil::checkHeader(store::IndexInput *in_, + const std::wstring &codec, + int minVersion, int maxVersion) { + // Safety to guard against reading a bogus string: + int actualHeader = in_->readInt(); + if (actualHeader != CODEC_MAGIC) { + _CLTHROWA(CL_ERR_CorruptIndex, "codec header mismatch"); + } + return checkHeaderNoMagic(in_, codec, minVersion, maxVersion); +} + +int CodecUtil::checkHeaderNoMagic(store::IndexInput *in_, + const std::wstring &codec, int minVersion, + int maxVersion) { + auto name = in_->readString(); + const std::wstring actualCodec(name); + _CLDELETE_CARRAY(name); + if (actualCodec != codec) { + _CLTHROWA(CL_ERR_CorruptIndex, "codec mismatch"); + } + + int actualVersion = in_->readInt(); + if (actualVersion < minVersion) { + _CLTHROWA(CL_ERR_NumberFormat, "codec version too old"); + } + if (actualVersion > maxVersion) { + _CLTHROWA(CL_ERR_NumberFormat, "codec version too new"); + } + + return actualVersion; +} + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/CodecUtil.h b/src/core/CLucene/util/CodecUtil.h new file mode 100644 index 00000000000..7d91704e1c4 --- /dev/null +++ b/src/core/CLucene/util/CodecUtil.h @@ -0,0 +1,36 @@ +#pragma once +#include "CLucene/_ApiHeader.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" + +#include +#include + +CL_NS_DEF(util) + +class CodecUtil final : public std::enable_shared_from_this { +private: + CodecUtil(); + + /** + * Constant to identify the start of a codec header. + */ +public: + static constexpr int CODEC_MAGIC = 0x3fd76c17; + /** + * Constant to identify the start of a codec footer. + */ + static const int FOOTER_MAGIC = ~CODEC_MAGIC; + + static void writeHeader(store::IndexOutput* out, + const std::wstring &codec, + int version); + static int checkHeader(store::IndexInput* in_, + const std::wstring &codec, int minVersion, + int maxVersion); + static int checkHeaderNoMagic(store::IndexInput* in_, + const std::wstring &codec, int minVersion, + int maxVersion); +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/Equators.cpp b/src/core/CLucene/util/Equators.cpp new file mode 100644 index 00000000000..9d113e268e8 --- /dev/null +++ b/src/core/CLucene/util/Equators.cpp @@ -0,0 +1,172 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Equators.h" +#include "CLucene/util/Misc.h" + +CL_NS_DEF(util) + +bool Equals::Int32::operator()( const int32_t val1, const int32_t val2 ) const{ + return (val1)==(val2); +} + +bool Equals::Char::operator()( const char* val1, const char* val2 ) const{ + if ( val1 == val2 ) + return true; + return (strcmp( val1,val2 ) == 0); +} + +#ifdef _UCS2 +bool Equals::WChar::operator()( const wchar_t* val1, const wchar_t* val2 ) const{ + if ( val1 == val2 ) + return true; + return (_tcscmp( val1,val2 ) == 0); +} +#endif + +AbstractDeletor::~AbstractDeletor(){ +} + +//////////////////////////////////////////////////////////////////////////////// +// Comparors +//////////////////////////////////////////////////////////////////////////////// +int32_t compare(Comparable* o1, Comparable* o2){ + if ( o1 == NULL && o2 == NULL ) + return 0; + else if ( o1 == NULL ) + return 1; + else if ( o2 == NULL ) + return -1; + else + return o1->compareTo(o2); +} +NamedObject::~NamedObject(){ +} +bool NamedObject::instanceOf(const char* other) const{ + const char* t = this->getObjectName(); + if ( t==other || strcmp( t, other )==0 ) + return true; + else + return false; +} + +int32_t Compare::Int32::getValue() const{ return value; } +Compare::Int32::Int32(int32_t val){ + value = val; +} +Compare::Int32::Int32(){ + value = 0; +} +const char* Compare::Int32::getClassName(){ + return "Compare::Int32::getClassName"; +} +const char* Compare::Int32::getObjectName() const{ + return getClassName(); +} +int32_t Compare::Int32::compareTo(NamedObject* o){ + if ( o->getObjectName() != Int32::getClassName() ) return -1; + + Int32* other = (Int32*)o; + if (value == other->value) + return 0; + // Returns just -1 or 1 on inequality; doing math might overflow. + return value > other->value ? 1 : -1; +} + +bool Compare::Int32::operator()( int32_t t1, int32_t t2 ) const{ + return t1 > t2 ? true : false; +} +size_t Compare::Int32::operator()( int32_t t ) const{ + return t; +} + + +float_t Compare::Float::getValue() const{ + return value; +} +Compare::Float::Float(float_t val){ + value = val; +} +const char* Compare::Float::getClassName(){ + return "Compare::Float::getClassName"; +} +const char* Compare::Float::getObjectName() const{ + return getClassName(); +} +int32_t Compare::Float::compareTo(NamedObject* o){ + if ( o->getObjectName() != Float::getClassName() ) return -1; + Float* other = (Float*)o; + if (value == other->value) + return 0; + // Returns just -1 or 1 on inequality; doing math might overflow. + return value > other->value ? 1 : -1; +} + + +bool Compare::Char::operator()( const char* val1, const char* val2 ) const{ + if ( val1==val2) + return false; + return (strcmp( val1,val2 ) < 0); +} +size_t Compare::Char::operator()( const char* val1) const{ + return CL_NS(util)::Misc::ahashCode(val1); +} +const char* Compare::Char::getValue() const{ return s; } + +Compare::Char::Char(){ + s=NULL; +} + Compare::Char::Char(const char* str){ + this->s = str; +} +const char* Compare::Char::getClassName(){ + return "Compare::Char::getClassName"; +} +const char* Compare::Char::getObjectName() const{ + return getClassName(); +} +int32_t Compare::Char::compareTo(NamedObject* o){ + if ( o->getObjectName() != Char::getClassName() ) return -1; + Char* os = (Char*)o; + return strcmp(s,os->s); +} + +#ifdef _UCS2 +bool Compare::WChar::operator()( const wchar_t* val1, const wchar_t* val2 ) const{ + if ( val1==val2) + return false; + bool ret = (_tcscmp( val1,val2 ) < 0); + return ret; +} +size_t Compare::WChar::operator()( const wchar_t* val1) const{ + return CL_NS(util)::Misc::whashCode(val1); +} + +const wchar_t* Compare::WChar::getValue() const{ return s; } + +Compare::WChar::WChar(){ + s=NULL; +} + Compare::WChar::WChar(const wchar_t* str){ + this->s = str; +} +const char* Compare::WChar::getClassName(){ + return "Compare::WChar::getClassName"; +} +const char* Compare::WChar::getObjectName() const{ + return getClassName(); +} +int32_t Compare::WChar::compareTo(NamedObject* o){ + if ( o->getObjectName() != WChar::getClassName() ) return -1; + TChar* os = (TChar*)o; + return _tcscmp(s,os->s); +} + +#endif + + +CL_NS_END diff --git a/src/core/CLucene/util/Equators.h b/src/core/CLucene/util/Equators.h new file mode 100644 index 00000000000..8cc85db5101 --- /dev/null +++ b/src/core/CLucene/util/Equators.h @@ -0,0 +1,283 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_Equators_ +#define _lucene_util_Equators_ + +#include +#include +#include +#include +#include +//#include "CLucene/LuceneThreads.h" + +CL_NS_DEF(util) + +//////////////////////////////////////////////////////////////////////////////// +// Equators +//////////////////////////////////////////////////////////////////////////////// +/** @internal */ +class CLUCENE_INLINE_EXPORT Equals{ +public: + class CLUCENE_INLINE_EXPORT Int32:public CL_NS_STD(binary_function) + { + public: + bool operator()( const int32_t val1, const int32_t val2 ) const; + }; + + class CLUCENE_INLINE_EXPORT Char:public CL_NS_STD(binary_function) + { + public: + bool operator()( const char* val1, const char* val2 ) const; + }; +#ifdef _UCS2 + class CLUCENE_INLINE_EXPORT WChar: public CL_NS_STD(binary_function) + { + public: + bool operator()( const wchar_t* val1, const wchar_t* val2 ) const; + }; + class CLUCENE_INLINE_EXPORT TChar: public WChar{ + }; +#else + class CLUCENE_INLINE_EXPORT TChar: public Char{ + }; +#endif + + + template + class CLUCENE_INLINE_EXPORT Void:public CL_NS_STD(binary_function) + { + public: + bool operator()( _cl* val1, _cl* val2 ) const{ + return val1==val2; + } + }; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// Comparors +//////////////////////////////////////////////////////////////////////////////// +class CLUCENE_EXPORT NamedObject{ +public: + virtual ~NamedObject(); + virtual const char* getObjectName() const = 0; + virtual bool instanceOf(const char* otherobject) const; +}; +class CLUCENE_EXPORT Comparable:public NamedObject{ +public: + virtual ~Comparable(){ + } + + virtual int32_t compareTo(NamedObject* o) = 0; +}; + +/** @internal */ +class CLUCENE_INLINE_EXPORT Compare{ +public: + class CLUCENE_EXPORT _base + { // traits class for hash containers + public: + enum + { // parameters for hash table + bucket_size = 4, // 0 < bucket_size + min_buckets = 8 + }; // min_buckets = 2 ^^ N, 0 < N + + _base() + { + } + }; + + class CLUCENE_INLINE_EXPORT Int32:public _base, public Comparable{ + int32_t value; + public: + int32_t getValue() const; + Int32(int32_t val); + Int32(); + int32_t compareTo(NamedObject* o); + bool operator()( int32_t t1, int32_t t2 ) const; + size_t operator()( int32_t t ) const; + static const char* getClassName(); + const char* getObjectName() const; + }; + + + class CLUCENE_INLINE_EXPORT Float:public Comparable{ + float_t value; + public: + float_t getValue() const; + Float(float_t val); + int32_t compareTo(NamedObject* o); + static const char* getClassName(); + const char* getObjectName() const; + }; + + + class CLUCENE_EXPORT Char: public _base, public Comparable // + { + const char* s; + public: + const char* getValue() const; + Char(); + Char(const char* str); + int32_t compareTo(NamedObject* o); + + bool operator()( const char* val1, const char* val2 ) const; + size_t operator()( const char* val1) const; + static const char* getClassName(); + const char* getObjectName() const; + }; + +#ifdef _UCS2 + class CLUCENE_EXPORT WChar: public _base, public Comparable // + { + const wchar_t* s; + public: + const wchar_t* getValue() const; + WChar(); + WChar(const wchar_t* str); + int32_t compareTo(NamedObject* o); + + bool operator()( const wchar_t* val1, const wchar_t* val2 ) const; + size_t operator()( const wchar_t* val1) const; + static const char* getClassName(); + const char* getObjectName() const; + }; + typedef WChar TChar; +#else + typedef Char TChar; +#endif + + template + class CLUCENE_INLINE_EXPORT Void:public _base // + { + public: + int32_t compareTo(_cl* o){ + if ( this == o ) + return o; + else + return this > o ? 1 : -1; + } + bool operator()( _cl* t1, _cl* t2 ) const{ + return t1 > t2 ? true : false; + } + size_t operator()( _cl* t ) const{ + return (size_t)t; + } + }; +}; + + + + +int32_t compare(Comparable* o1, Comparable* o2); + +//////////////////////////////////////////////////////////////////////////////// +// allocators +//////////////////////////////////////////////////////////////////////////////// +/** @internal */ +class CLUCENE_INLINE_EXPORT AbstractDeletor{ +public: + virtual void Delete(void*) = 0; + virtual ~AbstractDeletor(); +}; +class CLUCENE_INLINE_EXPORT Deletor{ +public: + class CLUCENE_INLINE_EXPORT tcArray: public AbstractDeletor{ + public: + void Delete(void* _arr){ + doDelete((TCHAR*)_arr); + } + static void doDelete(TCHAR* arr){ + _CLDELETE_CARRAY(arr); + } + }; + + template + class CLUCENE_INLINE_EXPORT vArray: public AbstractDeletor{ + public: + void Delete(void* arr){ + doDelete((_kt*)arr); + } + static void doDelete(_kt* arr){ + _CLDELETE_LARRAY(arr); + } + }; + class CLUCENE_INLINE_EXPORT acArray: public AbstractDeletor{ + public: + void Delete(void* arr){ + doDelete((char*)arr); + } + static void doDelete(char* arr){ + _CLDELETE_CaARRAY(arr); + } + }; + + template + class CLUCENE_INLINE_EXPORT Object: public AbstractDeletor{ + public: + void Delete(void* obj){ + doDelete((_kt*)obj); + } + static void doDelete(_kt* obj){ + _CLDELETE(obj); + } + }; + template + class CLUCENE_INLINE_EXPORT Void: public AbstractDeletor{ + public: + void Delete(void* obj){ + doDelete((_kt*)obj); + } + static void doDelete(_kt* obj){ + _CLVDELETE(obj); + } + }; + class CLUCENE_INLINE_EXPORT Dummy: public AbstractDeletor{ + public: + void Delete(void*){} + static void doDelete(const void*){ + //todo: remove all occurances where it hits this point + //CND_WARNING(false,"Deletor::Dummy::doDelete run, set deleteKey or deleteValue to false"); + } + }; + class CLUCENE_INLINE_EXPORT DummyInt32: public AbstractDeletor{ + public: + void Delete(void*){} + static void doDelete(const int32_t){ + } + }; + class CLUCENE_INLINE_EXPORT DummyFloat: public AbstractDeletor{ + public: + void Delete(void*){} + static void doDelete(const float_t){ + } + }; + template + class CLUCENE_INLINE_EXPORT ConstNullVal: public AbstractDeletor{ + public: + void Delete(void*){} + static void doDelete(const _type){ + //todo: remove all occurances where it hits this point + //CND_WARNING(false,"Deletor::Dummy::doDelete run, set deleteKey or deleteValue to false"); + } + }; + + template + class CLUCENE_INLINE_EXPORT NullVal: public AbstractDeletor{ + public: + void Delete(void*){} + static void doDelete(_type){ + //todo: remove all occurances where it hits this point + //CND_WARNING(false,"Deletor::Dummy::doDelete run, set deleteKey or deleteValue to false"); + } + }; +}; +//////////////////////////////////////////////////////////////////////////////// + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/FastCharStream.cpp b/src/core/CLucene/util/FastCharStream.cpp new file mode 100644 index 00000000000..590a3bd76e7 --- /dev/null +++ b/src/core/CLucene/util/FastCharStream.cpp @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_FastCharStream.h" + +#include "CLucene/util/CLStreams.h" + +CL_NS_DEF(util) + +const int32_t FastCharStream::maxRewindSize = LUCENE_MAX_WORD_LEN*2; + + FastCharStream::FastCharStream(BufferedReader* reader): + pos(0), + rewindPos(0), + resetPos(0), + col(1), + line(1), + input(reader) + { + input->setMinBufSize(maxRewindSize); + } + FastCharStream::~FastCharStream(){ + } + + void FastCharStream::reset() + { + pos = 0; + rewindPos = 0; + resetPos = 0; + col = 1; + line = 1; + input->setMinBufSize(maxRewindSize); + } + + void FastCharStream::readChar(TCHAR &c) { + try{ + int32_t r = input->read(); + if ( r == -1 ) + input = NULL; + c = r; + }catch(CLuceneError& err){ + if ( err.number() == CL_ERR_IO ) + input = 0; + throw err; + } + } + int FastCharStream::GetNext() + { + if (input == 0 ) // end of file + { + _CLTHROWA(CL_ERR_IO,"warning : FileReader.GetNext : Read TCHAR over EOS."); + } + // this is rather inefficient + // implementing the functions from the java version of + // charstream will be much more efficient. + ++pos; + TCHAR ch; + readChar(ch); + + if (input == NULL) { // eof + return -1; + } + if (rewindPos == 0) { + col += 1; + if(ch == '\n') { + line++; + col = 1; + } + } else { + rewindPos--; + } + return ch; + } + + void FastCharStream::UnGet(){ +// printf("UnGet \n"); + if (input == 0) + return; + if ( pos == 0 ) { + _CLTHROWA(CL_ERR_IO,"error : No character can be UnGet"); + } + rewindPos++; + + input->reset(pos-1); + pos--; + } + + int FastCharStream::Peek() { + int c = GetNext(); + UnGet(); + return c; + } + + bool FastCharStream::Eos() const { + return input==NULL; + } + + int32_t FastCharStream::Column() const { + return col; + } + + int32_t FastCharStream::Line() const { + return line; + } +CL_NS_END diff --git a/src/core/CLucene/util/FixedBitSet.cpp b/src/core/CLucene/util/FixedBitSet.cpp new file mode 100644 index 00000000000..b87b182af8b --- /dev/null +++ b/src/core/CLucene/util/FixedBitSet.cpp @@ -0,0 +1,37 @@ +#include "FixedBitSet.h" +#include "BitUtil.h" + +CL_NS_DEF(util) +FixedBitSet::FixedBitSet(int nb) + : numBits(nb),bits(std::vector(bits2words(nb))), + numWords(bits.size()) { +} + +int FixedBitSet::bits2words(int numBits) { + return ((numBits - 1) >> 6) + 1;// I.e.: get the word-offset of the last bit and add one (make sure + // to use >> so 0 returns 0!) +} + +int FixedBitSet::Cardinality() +{ + // Depends on the ghost bits being clear! + return static_cast(BitUtil::pop_array(bits, 0, numWords)); +} + +bool FixedBitSet::Get(int index) +{ + int i = index >> 6; // div 64 + // signed shift will keep a negative index and force an + // array-index-out-of-bounds-exception, removing the need for an explicit + // check. + int64_t bitmask = 1LL << index; + return (bits[i] & bitmask) != 0; +} + +void FixedBitSet::Set(int index) +{ + int wordNum = index >> 6; // div 64 + int64_t bitmask = 1LL << index; + bits[wordNum] |= bitmask; +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/FixedBitSet.h b/src/core/CLucene/util/FixedBitSet.h new file mode 100644 index 00000000000..e8dd6f2e2d7 --- /dev/null +++ b/src/core/CLucene/util/FixedBitSet.h @@ -0,0 +1,24 @@ +#pragma once + +#include "CLucene/SharedHeader.h" + +#include + +CL_NS_DEF(util) +class FixedBitSet { +public: + explicit FixedBitSet(int numBits); + +private: + std::vector bits;// Array of longs holding the bits + const int numBits; // The number of bits in use + const int numWords; // The exact number of longs needed to hold numBits (<= + // bits.length) +public: + void Set(int index); + bool Get(int index); + int Cardinality(); + static int bits2words(int numBits); +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/FutureArrays.cpp b/src/core/CLucene/util/FutureArrays.cpp new file mode 100644 index 00000000000..2d7e1b97384 --- /dev/null +++ b/src/core/CLucene/util/FutureArrays.cpp @@ -0,0 +1,246 @@ +#include "FutureArrays.h" + +CL_NS_DEF(util) + +FutureArrays::FutureArrays() {}// no instance + +void FutureArrays::CheckFromToIndex(int fromIndex, int toIndex, int length) { + if (fromIndex > toIndex) { + _CLTHROWA(CL_ERR_IllegalArgument, (L"fromIndex " + std::to_wstring(fromIndex) + + L" > toIndex " + std::to_wstring(toIndex)) + .c_str()); + } + if (fromIndex < 0 || toIndex > length) { + _CLTHROWA(CL_ERR_IndexOutOfBounds, (L"Range [" + std::to_wstring(fromIndex) + L", " + + std::to_wstring(toIndex) + L") out-of-bounds for length " + + std::to_wstring(length)) + .c_str()); + } +} + +int FutureArrays::Mismatch(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return i; + } + } + return aLen == bLen ? -1 : len; +} + +int FutureArrays::CompareUnsigned(const uint8_t *a, int aFromIndex, + int aToIndex, const uint8_t *b, + int bFromIndex, int bToIndex) { + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + int aByte = a[i + aFromIndex] & 0xFF; + int bByte = b[i + bFromIndex] & 0xFF; + int diff = aByte - bByte; + if (diff != 0) { + return diff; + } + } + + // One is a prefix of the other, or, they are equal: + return aLen - bLen; +} + +int FutureArrays::CompareNumeric(const uint8_t *a, + int aLen, + const uint8_t *b, + int bLen) { + if (aLen != bLen) { return aLen - bLen; } + int len = std::min(aLen, bLen); + for (int i = len - 1; i >= 0; i--) { + int aByte = a[i] & 0xFF; + int bByte = b[i] & 0xFF; + int diff = aByte - bByte; + if (diff != 0) { + return diff; + } + } + + // One is a prefix of the other, or, they are equal: + return 0; +} +int FutureArrays::CompareUnsigned(std::vector &a, int aFromIndex, + int aToIndex, std::vector &b, + int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + int aByte = a[i + aFromIndex] & 0xFF; + int bByte = b[i + bFromIndex] & 0xFF; + int diff = aByte - bByte; + if (diff != 0) { + return diff; + } + } + + // One is a prefix of the other, or, they are equal: + return aLen - bLen; +} + +bool FutureArrays::Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + // lengths differ: cannot be equal + if (aLen != bLen) { + return false; + } + for (int i = 0; i < aLen; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return false; + } + } + return true; +} + +int FutureArrays::Mismatch(std::vector &a, int aFromIndex, + int aToIndex, std::vector &b, + int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return i; + } + } + return aLen == bLen ? -1 : len; +} + +int FutureArrays::Compare(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + int aInt = a[i + aFromIndex]; + int bInt = b[i + bFromIndex]; + if (aInt > bInt) { + return 1; + } else if (aInt < bInt) { + return -1; + } + } + + // One is a prefix of the other, or, they are equal: + return aLen - bLen; +} + +bool FutureArrays::Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + // lengths differ: cannot be equal + if (aLen != bLen) { + return false; + } + for (int i = 0; i < aLen; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return false; + } + } + return true; +} + +int FutureArrays::Compare(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + int aInt = a[i + aFromIndex]; + int bInt = b[i + bFromIndex]; + if (aInt > bInt) { + return 1; + } else if (aInt < bInt) { + return -1; + } + } + + // One is a prefix of the other, or, they are equal: + return aLen - bLen; +} + +bool FutureArrays::Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + // lengths differ: cannot be equal + if (aLen != bLen) { + return false; + } + for (int i = 0; i < aLen; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return false; + } + } + return true; +} + +int FutureArrays::Compare(std::vector &a, int aFromIndex, + int aToIndex, std::vector &b, + int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + int len = std::min(aLen, bLen); + for (int i = 0; i < len; i++) { + int64_t aInt = a[i + aFromIndex]; + int64_t bInt = b[i + bFromIndex]; + if (aInt > bInt) { + return 1; + } else if (aInt < bInt) { + return -1; + } + } + + // One is a prefix of the other, or, they are equal: + return aLen - bLen; +} + +bool FutureArrays::Equals(std::vector &a, int aFromIndex, + int aToIndex, std::vector &b, + int bFromIndex, int bToIndex) { + CheckFromToIndex(aFromIndex, aToIndex, a.size()); + CheckFromToIndex(bFromIndex, bToIndex, b.size()); + int aLen = aToIndex - aFromIndex; + int bLen = bToIndex - bFromIndex; + // lengths differ: cannot be equal + if (aLen != bLen) { + return false; + } + for (int i = 0; i < aLen; i++) { + if (a[i + aFromIndex] != b[i + bFromIndex]) { + return false; + } + } + return true; +} +CL_NS_END diff --git a/src/core/CLucene/util/FutureArrays.h b/src/core/CLucene/util/FutureArrays.h new file mode 100644 index 00000000000..e621c377994 --- /dev/null +++ b/src/core/CLucene/util/FutureArrays.h @@ -0,0 +1,134 @@ +#pragma once +#include "CLucene/StdHeader.h" + +#include +#include +#include + +CL_NS_DEF(util) + + +/** + * Additional methods from Java 9's + * {@code java.util.Arrays}. + *

+ * This class will be removed when Java 9 is minimum requirement. + * Currently any bytecode is patched to use the Java 9 native + * classes through MR-JAR (Multi-Release JAR) mechanism. + * In Java 8 it will use THIS implementation. + * Because of patching, inside the Java source files we always + * refer to the Lucene implementations, but the final Lucene + * JAR files will use the native Java 9 class names when executed + * with Java 9. + * @lucene.internal + */ +class FutureArrays final : public std::enable_shared_from_this { +private: + FutureArrays(); + + // methods in Arrays are defined stupid: they cannot use + // Objects.checkFromToIndex they throw IAE (vs IOOBE) in the case of fromIndex + // > toIndex. so this method works just like checkFromToIndex, but with that + // stupidity added. + static void CheckFromToIndex(int fromIndex, int toIndex, int length); + + // byte[] + + /** + * Behaves like Java 9's Arrays.Mismatch + * @see Arrays.Mismatch + */ +public: + static int Mismatch(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + /** + * Behaves like Java 9's Arrays.compareUnsigned + * @see Arrays.compareUnsigned + */ + static int CompareUnsigned(const uint8_t *a, int aFromIndex, + int aToIndex, const uint8_t *b, + int bFromIndex, int bToIndex); + static int CompareUnsigned(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, + int bToIndex); + + static int CompareNumeric(const uint8_t *a, + int aLen, + const uint8_t *b, + int bLen); + + /** + * Behaves like Java 9's Arrays.equals + * @see Arrays.equals + */ + static bool Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + // uint8_t[] + + /** + * Behaves like Java 9's Arrays.Mismatch + * @see Arrays.Mismatch + */ + static int Mismatch(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + /** + * Behaves like Java 9's Arrays.compare + * @see Arrays.compare + */ + static int Compare(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + /** + * Behaves like Java 9's Arrays.equals + * @see Arrays.equals + */ + static bool Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + // int[] + + /** + * Behaves like Java 9's Arrays.compare + * @see Arrays.compare + */ + static int Compare(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + /** + * Behaves like Java 9's Arrays.equals + * @see Arrays.equals + */ + static bool Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + // long[] + + /** + * Behaves like Java 9's Arrays.compare + * @see Arrays.compare + */ + static int Compare(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); + + /** + * Behaves like Java 9's Arrays.equals + * @see Arrays.equals + */ + static bool Equals(std::vector &a, int aFromIndex, int aToIndex, + std::vector &b, int bFromIndex, int bToIndex); +}; +CL_NS_END diff --git a/src/core/CLucene/util/IntroSorter.cpp b/src/core/CLucene/util/IntroSorter.cpp new file mode 100644 index 00000000000..819fd07819e --- /dev/null +++ b/src/core/CLucene/util/IntroSorter.cpp @@ -0,0 +1,66 @@ +#include "IntroSorter.h" + +#include + +CL_NS_DEF(util) + +IntroSorter::IntroSorter() {} + +void IntroSorter::sort(int from, int to) { + checkRange(from, to); + quicksort(from, to, 2 * log2(to - from)); +} + +void IntroSorter::quicksort(int from, int to, int maxDepth) { + if (to - from < BINARY_SORT_THRESHOLD) { + binarySort(from, to); + return; + } else if (--maxDepth < 0) { + heapSort(from, to); + return; + } + + int mid = + static_cast(static_cast((from + to)) >> 1); + + if (compare(from, mid) > 0) { + swap(from, mid); + } + + if (compare(mid, to - 1) > 0) { + swap(mid, to - 1); + if (compare(from, mid) > 0) { + swap(from, mid); + } + } + + int left = from + 1; + int right = to - 2; + + setPivot(mid); + for (;;) { + while (comparePivot(right) < 0) { + --right; + } + + while (left < right && comparePivot(left) >= 0) { + ++left; + } + + if (left < right) { + swap(left, right); + --right; + } else { + break; + } + } + + quicksort(from, left + 1, maxDepth); + quicksort(left + 1, to, maxDepth); +} + +int IntroSorter::compare(int i, int j) { + setPivot(i); + return comparePivot(j); +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/IntroSorter.h b/src/core/CLucene/util/IntroSorter.h new file mode 100644 index 00000000000..33030419e0a --- /dev/null +++ b/src/core/CLucene/util/IntroSorter.h @@ -0,0 +1,45 @@ +#pragma once +#include "CLucene/SharedHeader.h" +#include "CLucene/util/Sorter.h" + +#include + +CL_NS_DEF(util) + +/** + * {@link Sorter} implementation based on a variant of the quicksort algorithm + * called introsort: when + * the recursion level exceeds the log of the length of the array to sort, it + * falls back to heapsort. This prevents quicksort from running into its + * worst-case quadratic runtime. Small arrays are sorted with + * insertion sort. + * @lucene.internal + */ +class IntroSorter : public Sorter +{ + /** Create a new {@link IntroSorter}. */ +public: + IntroSorter(); + + void sort(int from, int to) override final; + + virtual void quicksort(int from, int to, int maxDepth); + + // Don't rely on the slow default impl of setPivot/comparePivot since + // quicksort relies on these methods to be fast for good performance + +protected: + void setPivot(int i) = 0; + + int comparePivot(int j) = 0; + + int compare(int i, int j) override; + +protected: + std::shared_ptr shared_from_this() + { + return std::static_pointer_cast(Sorter::shared_from_this()); + } +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/LongBitSet.cpp b/src/core/CLucene/util/LongBitSet.cpp new file mode 100644 index 00000000000..0eec2ab4fc1 --- /dev/null +++ b/src/core/CLucene/util/LongBitSet.cpp @@ -0,0 +1,41 @@ +#include "LongBitSet.h" +#include "BitUtil.h" + +CL_NS_DEF(util) +LongBitSet::LongBitSet(int64_t nb) + : bits(std::vector(bits2words(nb))), numBits(nb), + numWords(bits.size()) { +} + +int LongBitSet::bits2words(int64_t numBits) { + return static_cast((numBits - 1) >> 6) + 1; +} + +void LongBitSet::Clear(int64_t index) +{ + int wordNum = static_cast(index >> 6); + int64_t bitmask = 1LL << index; + bits[wordNum] &= ~bitmask; +} + +int64_t LongBitSet::Cardinality() { + return BitUtil::pop_array(bits, 0, numWords); +} + +bool LongBitSet::Get(int64_t index) { + int i = static_cast(index >> 6);// div 64 + + // signed shift will keep a negative index and force an + // array-index-out-of-bounds-exception, removing the need for an explicit + // check. + + int64_t bitmask = 1LL << index; + return (bits[i] & bitmask) != 0; +} + +void LongBitSet::Set(int64_t index) { + int wordNum = static_cast(index >> 6);// div 64 + int64_t bitmask = 1LL << index; + bits[wordNum] |= bitmask; +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/LongBitSet.h b/src/core/CLucene/util/LongBitSet.h new file mode 100644 index 00000000000..82e661e9435 --- /dev/null +++ b/src/core/CLucene/util/LongBitSet.h @@ -0,0 +1,25 @@ +#pragma once + +#include "CLucene/SharedHeader.h" + +#include + +CL_NS_DEF(util) +class LongBitSet { +public: + explicit LongBitSet(int64_t numBits); + +private: + std::vector bits;// Array of longs holding the bits + const int64_t numBits; // The number of bits in use + const int numWords; // The exact number of longs needed to hold numBits (<= + // bits.length) +public: + void Set(int64_t index); + bool Get(int64_t index); + int64_t Cardinality(); + void Clear(int64_t index); + static int bits2words(int64_t numBits); +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/MD5Digester.cpp b/src/core/CLucene/util/MD5Digester.cpp new file mode 100644 index 00000000000..15c16e48c87 --- /dev/null +++ b/src/core/CLucene/util/MD5Digester.cpp @@ -0,0 +1,337 @@ +///////////////////////////////////////////////////////////////////////// +// MD5.cpp +// Implementation file for MD5 class +// +// This C++ Class implementation of the original RSA Data Security, Inc. +// MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle. +// All rights reserved. This software is a derivative of the "RSA Data +// Security, Inc. MD5 Message-Digest Algorithm" +// +// You may use this software free of any charge, but without any +// warranty or implied warranty, provided that you follow the terms +// of the original RSA copyright, listed below. +// +// Original RSA Data Security, Inc. Copyright notice +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +// rights reserved. +// +// License to copy and use this software is granted provided that it +// is identified as the "RSA Data Security, Inc. MD5 Message-Digest +// Algorithm" in all material mentioning or referencing this software +// or this function. +// License is also granted to make and use derivative works provided +// that such works are identified as "derived from the RSA Data +// Security, Inc. MD5 Message-Digest Algorithm" in all material +// mentioning or referencing the derived work. +// RSA Data Security, Inc. makes no representations concerning either +// the merchantability of this software or the suitability of this +// software for any particular purpose. It is provided "as is" +// without express or implied warranty of any kind. +// These notices must be retained in any copies of any part of this +// documentation and/or software. +///////////////////////////////////////////////////////////////////////// + +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_ApiHeader.h" +#include "_MD5Digester.h" +CL_NS_DEF(util) + +static unsigned char PADDING[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +// PrintMD5: Converts a completed md5 digest into a char* string. +char* PrintMD5(uint8_t md5Digest[16]) +{ + char chBuffer[256]; + char chEach[10]; + int nCount; + + memset(chBuffer,0,256); + memset(chEach, 0, 10); + + for (nCount = 0; nCount < 16; nCount++) + { + cl_sprintf(chEach, 10, "%02x", md5Digest[nCount]); + strncat(chBuffer, chEach, sizeof(chEach)); + } + + return STRDUP_AtoA(chBuffer); +} + +// MD5String: Performs the MD5 algorithm on a char* string, returning +// the results as a char*. +char* MD5String(char* szString) +{ + int nLen = strlen(szString); + md5 alg; + + alg.Update((unsigned char*)szString, (unsigned int)nLen); + alg.Finalize(); + + return PrintMD5(alg.Digest()); + +} + +// MD5File: Performs the MD5 algorithm on a file (binar or text), +// returning the results as a char*. Returns NULL if it fails. +char* MD5File(char* szFilename) +{ + FILE* file; + md5 alg; + int nLen; + unsigned char chBuffer[1024]; + + try + { + memset(chBuffer, 0, 1024); + + if ((file = fopen (szFilename, "rb")) != NULL) + { + while ((nLen = fread (chBuffer, 1, 1024, file))) + alg.Update(chBuffer, nLen); + + alg.Finalize(); + + fclose (file); + + return PrintMD5(alg.Digest()); + } + } + catch(...) //todo: only catch IO Err??? + { + + } + + return NULL; // failed +} + + +// md5::Init +// Initializes a new context. +void md5::Init() +{ + memset(m_Count, 0, 2 * sizeof(uint32_t)); + + m_State[0] = 0x67452301; + m_State[1] = 0xefcdab89; + m_State[2] = 0x98badcfe; + m_State[3] = 0x10325476; +} + +// md5::Update +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block, and updating the +// context. +void md5::Update(uint8_t* chInput, uint32_t nInputLen) +{ + uint32_t i, index, partLen; + + // Compute number of bytes mod 64 + index = (unsigned int)((m_Count[0] >> 3) & 0x3F); + + // Update number of bits + if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3)) + m_Count[1]++; + + m_Count[1] += (nInputLen >> 29); + + partLen = 64 - index; + + // Transform as many times as possible. + if (nInputLen >= partLen) + { + memcpy( &m_Buffer[index], chInput, partLen ); + Transform(m_Buffer); + + for (i = partLen; i + 63 < nInputLen; i += 64) + Transform(&chInput[i]); + + index = 0; + } + else + i = 0; + + // Buffer remaining input + memcpy( &m_Buffer[index], &chInput[i], nInputLen-i ); +} + +// md5::Finalize +// MD5 finalization. Ends an MD5 message-digest operation, writing +// the message digest and zeroizing the context. +void md5::Finalize() +{ + uint8_t bits[8]; + uint32_t index, padLen; + + // Save number of bits + Encode (bits, m_Count, 8); + + // Pad out to 56 mod 64 + index = (unsigned int)((m_Count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + Update(PADDING, padLen); + + // Append length (before padding) + Update (bits, 8); + + // Store state in digest + Encode (m_Digest, m_State, 16); + + memset(m_Count, 0, 2 * sizeof(uint32_t)); + memset(m_State, 0, 4 * sizeof(uint32_t)); + memset(m_Buffer,0, 64 * sizeof(uint8_t)); +} + +// md5::Transform +// MD5 basic transformation. Transforms state based on block. +void md5::Transform (uint8_t* block) +{ + uint32_t a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16]; + + Decode (x, block, 64); + + // Round 1 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); + FF (c, d, a, b, x[ 2], S13, 0x242070db); + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); + FF (c, d, a, b, x[ 6], S13, 0xa8304613); + FF (b, c, d, a, x[ 7], S14, 0xfd469501); + FF (a, b, c, d, x[ 8], S11, 0x698098d8); + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); + FF (c, d, a, b, x[10], S13, 0xffff5bb1); + FF (b, c, d, a, x[11], S14, 0x895cd7be); + FF (a, b, c, d, x[12], S11, 0x6b901122); + FF (d, a, b, c, x[13], S12, 0xfd987193); + FF (c, d, a, b, x[14], S13, 0xa679438e); + FF (b, c, d, a, x[15], S14, 0x49b40821); + + // Round 2 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); + GG (d, a, b, c, x[ 6], S22, 0xc040b340); + GG (c, d, a, b, x[11], S23, 0x265e5a51); + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); + GG (d, a, b, c, x[10], S22, 0x2441453); + GG (c, d, a, b, x[15], S23, 0xd8a1e681); + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); + GG (d, a, b, c, x[14], S22, 0xc33707d6); + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); + GG (a, b, c, d, x[13], S21, 0xa9e3e905); + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); + + // Round 3 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); + HH (d, a, b, c, x[ 8], S32, 0x8771f681); + HH (c, d, a, b, x[11], S33, 0x6d9d6122); + HH (b, c, d, a, x[14], S34, 0xfde5380c); + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); + HH (b, c, d, a, x[10], S34, 0xbebfbc70); + HH (a, b, c, d, x[13], S31, 0x289b7ec6); + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); + HH (b, c, d, a, x[ 6], S34, 0x4881d05); + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); + HH (d, a, b, c, x[12], S32, 0xe6db99e5); + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); + + // Round 4 + II (a, b, c, d, x[ 0], S41, 0xf4292244); + II (d, a, b, c, x[ 7], S42, 0x432aff97); + II (c, d, a, b, x[14], S43, 0xab9423a7); + II (b, c, d, a, x[ 5], S44, 0xfc93a039); + II (a, b, c, d, x[12], S41, 0x655b59c3); + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); + II (c, d, a, b, x[10], S43, 0xffeff47d); + II (b, c, d, a, x[ 1], S44, 0x85845dd1); + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); + II (c, d, a, b, x[ 6], S43, 0xa3014314); + II (b, c, d, a, x[13], S44, 0x4e0811a1); + II (a, b, c, d, x[ 4], S41, 0xf7537e82); + II (d, a, b, c, x[11], S42, 0xbd3af235); + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); + II (b, c, d, a, x[ 9], S44, 0xeb86d391); + + m_State[0] += a; + m_State[1] += b; + m_State[2] += c; + m_State[3] += d; + + memset(x, 0, sizeof(x)); +} + +// md5::Encode +// Encodes input (uint32_t) into output (uint8_t). Assumes nLength is +// a multiple of 4. +void md5::Encode(uint8_t* dest, uint32_t* src, uint32_t nLength) +{ + uint32_t i, j; + + CND_PRECONDITION(nLength % 4 == 0,"nLength % 4 != 0") + + for (i = 0, j = 0; j < nLength; i++, j += 4) + { + dest[j] = (uint8_t)(src[i] & 0xff); + dest[j+1] = (uint8_t)((src[i] >> 8) & 0xff); + dest[j+2] = (uint8_t)((src[i] >> 16) & 0xff); + dest[j+3] = (uint8_t)((src[i] >> 24) & 0xff); + } +} + +// md5::Decode +// Decodes input (uint8_t) into output (uint32_t). Assumes nLength is +// a multiple of 4. +void md5::Decode(uint32_t* dest, uint8_t* src, uint32_t nLength) +{ + uint32_t i, j; + + CND_PRECONDITION(nLength % 4 == 0, "nLength % 4 != 0"); + + for (i = 0, j = 0; j < nLength; i++, j += 4) + { + dest[i] = ((uint32_t)src[j]) | (((uint32_t)src[j+1])<<8) | + (((uint32_t)src[j+2])<<16) | (((uint32_t)src[j+3])<<24); + } +} + +CL_NS_END diff --git a/src/core/CLucene/util/MSBRadixSorter.cpp b/src/core/CLucene/util/MSBRadixSorter.cpp new file mode 100644 index 00000000000..dcc9df7da54 --- /dev/null +++ b/src/core/CLucene/util/MSBRadixSorter.cpp @@ -0,0 +1,207 @@ +#include "MSBRadixSorter.h" + +#include +CL_NS_DEF(util) + +MSBRadixSorter::MSBRadixSorter(int maxLength) + : commonPrefix(std::vector(min(24, maxLength))), maxLength(maxLength) { +} + +MSBRadixSorter::IntroSorterAnonymousInnerClass::IntroSorterAnonymousInnerClass( + shared_ptr&& outerInstance, int k) { + this->outerInstance = outerInstance; + this->k = k; + pivot = std::make_shared(); +} + +void MSBRadixSorter::IntroSorterAnonymousInnerClass::swap(int i, int j) { + outerInstance->swap(i, j); +} + +int MSBRadixSorter::IntroSorterAnonymousInnerClass::compare(int i, int j) { + for (int o = k; o < outerInstance->maxLength; ++o) { + int b1 = outerInstance->byteAt(i, o); + int b2 = outerInstance->byteAt(j, o); + if (b1 != b2) { + return b1 - b2; + } else if (b1 == -1) { + break; + } + } + return 0; +} + +void MSBRadixSorter::IntroSorterAnonymousInnerClass::setPivot(int i) { + pivot->setLength(0); + for (int o = k; o < outerInstance->maxLength; ++o) { + int b = outerInstance->byteAt(i, o); + if (b == -1) { + break; + } + pivot->append(static_cast(b)); + } +} + +int MSBRadixSorter::IntroSorterAnonymousInnerClass::comparePivot(int j) { + for (int o = 0; o < pivot->length(); ++o) { + int b1 = pivot->byteAt(o) & 0xff; + int b2 = outerInstance->byteAt(j, k + o); + if (b1 != b2) { + return b1 - b2; + } + } + if (k + pivot->length() == outerInstance->maxLength) { + return 0; + } + return -1 - outerInstance->byteAt(j, k + pivot->length()); +} + +int MSBRadixSorter::compare(int i, int j) { + _CLTHROWA(CL_ERR_InvalidState, "unused: not a comparison-based sort"); +} + +void MSBRadixSorter::sort(int from, int to) { + checkRange(from, to); + sort(from, to, 0, 0); +} + +void MSBRadixSorter::sort(int from, int to, int k, int l) { + if (to - from <= LENGTH_THRESHOLD || l >= LEVEL_THRESHOLD) { + introSort(from, to, k); + } else { + radixSort(from, to, k, l); + } +} + +void MSBRadixSorter::introSort(int from, int to, int k) { + std::make_shared(shared_from_this(), k)->sort(from, to); +} + +void MSBRadixSorter::radixSort(int from, int to, int k, int l) { + std::vector histogram = histograms[l]; + if (histogram.empty()) { + histogram = histograms[l] = std::vector(HISTOGRAM_SIZE); + } else { + std::fill(histogram.begin(), histogram.end(), 0); + } + + int commonPrefixLength = + computeCommonPrefixLengthAndBuildHistogram(from, to, k, histogram); + if (commonPrefixLength > 0) { + // if there are no more chars to compare or if all entries fell into the + // first bucket (which means strings are shorter than k) then we are done + // otherwise recurse + if (k + commonPrefixLength < maxLength && histogram[0] < to - from) { + radixSort(from, to, k + commonPrefixLength, l); + } + return; + } + assert((assertHistogram(commonPrefixLength, histogram))); + + sumHistogram(histogram, endOffsets); + reorder(from, to, histogram, endOffsets, k); + + if (k + 1 < maxLength) { + // recurse on all but the first bucket since all keys are equals in this + // bucket (we already compared all bytes) + for (int prev = histogram[0], i = 1; i < HISTOGRAM_SIZE; ++i) { + int h = histogram[i]; + int bucketLen = h - prev; + if (bucketLen > 1) { + sort(from + prev, from + h, k + 1, l + 1); + } + prev = h; + } + } +} + +bool MSBRadixSorter::assertHistogram(int commonPrefixLength, + std::vector &histogram) { + int numberOfUniqueBytes = 0; + for (auto freq: histogram) { + if (freq > 0) { + numberOfUniqueBytes++; + } + } + if (numberOfUniqueBytes == 1) { + assert(commonPrefixLength >= 1); + } else { + assert(commonPrefixLength == 0); + } + return true; +} + +int MSBRadixSorter::getBucket(int i, int k) { return byteAt(i, k) + 1; } + +int MSBRadixSorter::computeCommonPrefixLengthAndBuildHistogram( + int from, int to, int k, std::vector &histogram) { + int commonPrefixLength = min(int(commonPrefix.size()), maxLength - k); + for (int j = 0; j < commonPrefixLength; ++j) { + int b = byteAt(from, k + j); + commonPrefix[j] = b; + if (b == -1) { + commonPrefixLength = j + 1; + break; + } + } + + int i; + for (i = from + 1; i < to; ++i) { + for (int j = 0; j < commonPrefixLength; ++j) { + int b = byteAt(i, k + j); + if (b != commonPrefix[j]) { + commonPrefixLength = j; + if (commonPrefixLength == 0) {// we have no common prefix + histogram[commonPrefix[0] + 1] = i - from; + histogram[b + 1] = 1; + goto outerBreak; + } + break; + } + } + } +outerBreak: + + if (i < to) { + // the loop got broken because there is no common prefix + assert(commonPrefixLength == 0); + buildHistogram(i + 1, to, k, histogram); + } else { + assert(commonPrefixLength > 0); + histogram[commonPrefix[0] + 1] = to - from; + } + + return commonPrefixLength; +} + +void MSBRadixSorter::buildHistogram(int from, int to, int k, + std::vector &histogram) { + for (int i = from; i < to; ++i) { + histogram[getBucket(i, k)]++; + } +} + +void MSBRadixSorter::sumHistogram(std::vector &histogram, + std::vector &endOffsets) { + int accum = 0; + for (int i = 0; i < HISTOGRAM_SIZE; ++i) { + int count = histogram[i]; + histogram[i] = accum; + accum += count; + endOffsets[i] = accum; + } +} + +void MSBRadixSorter::reorder(int from, int to, std::vector &start, + std::vector &end, int k) { + // reorder in place, like the dutch flag problem + for (int i = 0; i < HISTOGRAM_SIZE; ++i) { + const int limit = end[i]; + for (int h1 = start[i]; h1 < limit; h1 = start[i]) { + const int b = getBucket(from + h1, k); + const int h2 = start[b]++; + swap(from + h1, from + h2); + } + } +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/MSBRadixSorter.h b/src/core/CLucene/util/MSBRadixSorter.h new file mode 100644 index 00000000000..10c3ea028d6 --- /dev/null +++ b/src/core/CLucene/util/MSBRadixSorter.h @@ -0,0 +1,134 @@ +#pragma once +#include "BytesRefBuilder.h" +#include "CLucene/SharedHeader.h" +#include "CLucene/util/Sorter.h" +#include "IntroSorter.h" + +#include + +CL_NS_DEF(util) + +/** Radix sorter for variable-length strings. This class sorts based on the most + * significant byte first and falls back to {@link IntroSorter} when the size + * of the buckets to sort becomes small. It is NOT stable. + * Worst-case memory usage is about {@code 2.3 KB}. + * @lucene.internal */ +class MSBRadixSorter : public Sorter{ + // after that many levels of recursion we fall back to introsort anyway + // this is used as a protection against the fact that radix sort performs + // worse when there are long common prefixes (probably because of cache + // locality) +private: + static constexpr int LEVEL_THRESHOLD = 8; + // size of histograms: 256 + 1 to indicate that the string is finished + static constexpr int HISTOGRAM_SIZE = 257; + // buckets below this size will be sorted with introsort + static constexpr int LENGTH_THRESHOLD = 100; + + // we store one histogram per recursion level + std::vector> histograms = + std::vector>(LEVEL_THRESHOLD); + std::vector endOffsets = std::vector(HISTOGRAM_SIZE); + std::vector commonPrefix; + + const int maxLength; + + /** + * Sole constructor. + * @param maxLength the maximum length of keys, pass {@link Integer#MAX_VALUE} + * if unknown. + */ +protected: + explicit MSBRadixSorter(int maxLength); + + /** Return the k-th byte of the entry at index {@code i}, or {@code -1} if + * its length is less than or equal to {@code k}. This may only be called + * with a value of {@code i} between {@code 0} included and + * {@code maxLength} excluded. */ + virtual int byteAt(int i, int k) = 0; + +private: + class IntroSorterAnonymousInnerClass : public IntroSorter { + private: + std::shared_ptr outerInstance; + + int k = 0; + + public: + IntroSorterAnonymousInnerClass( + shared_ptr&& outerInstance, int k); + + protected: + void swap(int i, int j) override; + + int compare(int i, int j) override; + + void setPivot(int i) override; + + int comparePivot(int j) override; + + private: + std::shared_ptr pivot; + + protected: + std::shared_ptr shared_from_this() { + return std::static_pointer_cast( + IntroSorter::shared_from_this()); + } + }; + +protected: + int compare(int i, int j) final; + +public: + void sort(int from, int to) override; + +private: + void sort(int from, int to, int k, int l); + + void introSort(int from, int to, int k); + + /** + * @param k the character number to compare + * @param l the level of recursion + */ + void radixSort(int from, int to, int k, int l); + + // only used from assert + static bool assertHistogram(int commonPrefixLength, std::vector &histogram); + + /** Return a number for the k-th character between 0 and {@link + * #HISTOGRAM_SIZE}. */ + int getBucket(int i, int k); + + /** Build a histogram of the number of values per {@link #getBucket(int, int) + * bucket} and return a common prefix length for all visited values. + * @see #buildHistogram */ + int computeCommonPrefixLengthAndBuildHistogram(int from, int to, int k, + std::vector &histogram); + + /** Build an histogram of the k-th characters of values occurring between + * offsets {@code from} and {@code to}, using {@link #getBucket}. */ + void buildHistogram(int from, int to, int k, std::vector &histogram); + + /** Accumulate values of the histogram so that it does not store counts but + * start offsets. {@code endOffsets} will store the end offsets. */ + static void sumHistogram(std::vector &histogram, + std::vector &endOffsets); + + /** + * Reorder based on start/end offsets for each bucket. When this method + * returns, startOffsets and endOffsets are equal. + * @param startOffsets start offsets per bucket + * @param endOffsets end offsets per bucket + */ + void reorder(int from, int to, std::vector &start, + std::vector &end, int k); + +protected: + std::shared_ptr shared_from_this() { + return std::static_pointer_cast(Sorter::shared_from_this()); + } +}; + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/NumericUtils.cpp b/src/core/CLucene/util/NumericUtils.cpp new file mode 100644 index 00000000000..aeda477fc5f --- /dev/null +++ b/src/core/CLucene/util/NumericUtils.cpp @@ -0,0 +1,124 @@ +#include "NumericUtils.h" +#include "CLucene/debug/error.h" + +CL_NS_DEF(util) + + +NumericUtils::NumericUtils() = default;// no instance! + +int NumericUtils::floatToInt(float value) { + union UnionFloatInt { + int int_; + float float_; + }; + UnionFloatInt float_int{}; + float_int.float_ = value; + return float_int.int_; +} + +int64_t NumericUtils::doubleToLong(double value) { + union UnionLongDouble { + int64_t long_; + double double_; + }; + UnionLongDouble long_double{}; + long_double.double_ = value; + return long_double.long_; +} + +int64_t NumericUtils::sortableDoubleBits(int64_t bits) +{ + return bits ^ (bits >> 63) & 0x7fffffffffffffffLL; +} + +int NumericUtils::sortableFloatBits(int bits) +{ + return bits ^ (bits >> 31) & 0x7fffffff; +} + +void NumericUtils::doubleToSortableBytes(double value, std::vector &result, int offset) { + auto v = sortableDoubleBits(doubleToLong(value)); + longToSortableBytes(v, result, offset); +} + + +void NumericUtils::floatToSortableBytes(float value, std::vector &result, int offset) { + auto v = sortableFloatBits(floatToInt(value)); + intToSortableBytes(v, result, offset); +} + +void NumericUtils::int16ToSortableBytes(int value, std::vector &result, + int offset) { + // Flip the sign bit, so negative ints sort before positive ints correctly: + value ^= 0x8000; + result[offset] = static_cast(value >> 8); + result[offset + 1] = static_cast(value); +} + +void NumericUtils::intToSortableBytes(int value, std::vector &result, + int offset) { + // Flip the sign bit, so negative ints sort before positive ints correctly: + value ^= 0x80000000; + result[offset] = static_cast(value >> 24); + result[offset + 1] = static_cast(value >> 16); + result[offset + 2] = static_cast(value >> 8); + result[offset + 3] = static_cast(value); +} + +int NumericUtils::sortableBytesToInt(std::vector &encoded, int offset) { + int x = ((encoded[offset] & 0xFF) << 24) | + ((encoded[offset + 1] & 0xFF) << 16) | + ((encoded[offset + 2] & 0xFF) << 8) | (encoded[offset + 3] & 0xFF); + // Re-flip the sign bit to restore the original value: + return x ^ 0x80000000; +} + +void NumericUtils::longToSortableBytes(int64_t value, + std::vector &result, int offset) { + // Flip the sign bit so negative longs sort before positive longs: + value ^= 0x8000000000000000LL; + result[offset] = static_cast(value >> 56); + result[offset + 1] = static_cast(value >> 48); + result[offset + 2] = static_cast(value >> 40); + result[offset + 3] = static_cast(value >> 32); + result[offset + 4] = static_cast(value >> 24); + result[offset + 5] = static_cast(value >> 16); + result[offset + 6] = static_cast(value >> 8); + result[offset + 7] = static_cast(value); +} + +int64_t NumericUtils::sortableBytesToLong(std::vector &encoded, + int offset) { + int64_t v = ((encoded[offset] & 0xFFLL) << 56) | + ((encoded[offset + 1] & 0xFFLL) << 48) | + ((encoded[offset + 2] & 0xFFLL) << 40) | + ((encoded[offset + 3] & 0xFFLL) << 32) | + ((encoded[offset + 4] & 0xFFLL) << 24) | + ((encoded[offset + 5] & 0xFFLL) << 16) | + ((encoded[offset + 6] & 0xFFLL) << 8) | + (encoded[offset + 7] & 0xFFLL); + // Flip the sign bit back + v ^= 0x8000000000000000LL; + return v; +} + +void NumericUtils::subtract(int bytesPerDim, int dim, std::vector &a, + std::vector &b, std::vector &result) { + int start = dim * bytesPerDim; + int end = start + bytesPerDim; + int borrow = 0; + for (int i = end - 1; i >= start; i--) { + int diff = (a[i] & 0xff) - (b[i] & 0xff) - borrow; + if (diff < 0) { + diff += 256; + borrow = 1; + } else { + borrow = 0; + } + result[i - start] = static_cast(diff); + } + if (borrow != 0) { + _CLTHROWA(CL_ERR_IllegalArgument, "a < b"); + } +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/NumericUtils.h b/src/core/CLucene/util/NumericUtils.h new file mode 100644 index 00000000000..91deab647d6 --- /dev/null +++ b/src/core/CLucene/util/NumericUtils.h @@ -0,0 +1,60 @@ +#pragma once + +#include "CLucene/StdHeader.h" + +#include +#include +#include + +CL_NS_DEF(util) +class NumericUtils final : public std::enable_shared_from_this { +private: + NumericUtils(); + + /** + * Converts a double value to a sortable signed + * long. The value is converted by getting their IEEE 754 + * floating-point "double format" bit layout and then some bits are + * swapped, to be able to compare the result as long. By this the precision is + * not reduced, but the value can easily used as a long. The sort order + * (including {@link Double#NaN}) is defined by + * {@link Double#compareTo}; {@code NaN} is greater than positive infinity. + * @see #sortableLongToDouble + */ +public: + static void intToSortableBytes(int value, std::vector &result, + int offset); + static void int16ToSortableBytes(int value, std::vector &result, + int offset); + /** + * Decodes an integer value previously written with {@link + * #intToSortableBytes} + * @see #intToSortableBytes(int, byte[], int) + */ + static int sortableBytesToInt(std::vector &encoded, int offset); + + /** + * Encodes an long {@code value} such that unsigned byte order comparison + * is consistent with {@link Long#compare(long, long)} + * @see #sortableBytesToLong(byte[], int) + */ + static void longToSortableBytes(int64_t value, std::vector &result, + int offset); + + /** + * Decodes a long value previously written with {@link #longToSortableBytes} + * @see #longToSortableBytes(long, byte[], int) + */ + static int64_t sortableBytesToLong(std::vector &encoded, int offset); + + static void subtract(int bytesPerDim, int dim, std::vector &a, + std::vector &b, std::vector &result); + static int floatToInt(float value); + static int64_t doubleToLong(double value); + static void floatToSortableBytes(float value, std::vector &result, int offset); + static void doubleToSortableBytes(double value, std::vector &result, int offset); + static int64_t sortableDoubleBits(int64_t bits); + static int sortableFloatBits(int bits); +}; + +CL_NS_END diff --git a/src/core/CLucene/util/OfflineSorter.h b/src/core/CLucene/util/OfflineSorter.h new file mode 100644 index 00000000000..42de8c3b36f --- /dev/null +++ b/src/core/CLucene/util/OfflineSorter.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include +#include +#include + +CL_NS_DEF(util) + +class OfflineSorter : public std::enable_shared_from_this { + /** Convenience constant for megabytes */ +public: + static constexpr int64_t MB = 1024 * 1024; + /** Convenience constant for gigabytes */ + static const int64_t GB = MB * 1024; + + /** + * Minimum recommended buffer size for sorting. + */ + static constexpr int64_t MIN_BUFFER_SIZE_MB = 32; + + /** + * Absolute minimum required buffer size for sorting. + */ + static const int64_t ABSOLUTE_MIN_SORT_BUFFER_SIZE = MB / 2; + +private: + static const std::wstring MIN_BUFFER_SIZE_MSG; + + /** + * Maximum number of temporary files before doing an intermediate merge. + */ +public: + static constexpr int MAX_TEMPFILES = 10; + +public: + class BufferSize final : public std::enable_shared_from_this { + public: + const int bytes; + + explicit BufferSize(int64_t bytes) : bytes(static_cast(bytes)){}; + + /** + * Creates a {@link BufferSize} in MB. The given + * values must be > 0 and < 2048. + */ + public: + static std::shared_ptr MegaBytes(int64_t mb) { + return std::make_shared(mb * MB); + } + }; +}; +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/PriorityQueue.h b/src/core/CLucene/util/PriorityQueue.h new file mode 100644 index 00000000000..b66689c9d72 --- /dev/null +++ b/src/core/CLucene/util/PriorityQueue.h @@ -0,0 +1,206 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_PriorityQueue_ +#define _lucene_util_PriorityQueue_ + +#include + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_DEF(util) + +/** A PriorityQueue maintains a partial ordering of its elements such that the + least element can always be found in constant time. Put()'s and pop()'s + require log(size) time. */ +template +class CLUCENE_INLINE_EXPORT PriorityQueue { + private: + size_t _size; + bool dk; + size_t maxSize; + protected: + _type* heap; //(was object[]) + + private: + void upHeap(){ + size_t i = _size; + _type node = heap[i]; // save bottom node (WAS object) + int32_t j = ((uint32_t)i) >> 1; + while (j > 0 && lessThan(node,heap[j])) { + heap[i] = heap[j]; // shift parents down + i = j; + j = ((uint32_t)j) >> 1; + } + heap[i] = node; // install saved node + } + void downHeap(){ + size_t i = 1; + _type node = heap[i]; // save top node + size_t j = i << 1; // find smaller child + size_t k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { + j = k; + } + while (j <= _size && lessThan(heap[j],node)) { + heap[i] = heap[j]; // shift up child + i = j; + j = i << 1; + k = j + 1; + if (k <= _size && lessThan(heap[k], heap[j])) { + j = k; + } + } + heap[i] = node; // install saved node + } + + protected: + PriorityQueue():_size(0),dk(false),maxSize(0),heap(NULL){ + } + + // Determines the ordering of objects in this priority queue. Subclasses + // must define this one method. + virtual bool lessThan(_type a, _type b)=0; + + // Subclass constructors must call this. + void initialize(const int32_t maxSize, bool deleteOnClear){ + _size = 0; + dk = deleteOnClear; + int32_t heapSize; + if (0 == maxSize) + // We allocate 1 extra to avoid if statement in top() + heapSize = 2; + else + heapSize = maxSize + 1; + heap = _CL_NEWARRAY(_type,heapSize); + this->maxSize = maxSize; + } + + public: + virtual ~PriorityQueue(){ + clear(); + _CLDELETE_LARRAY(heap); + } + + /** + * Adds an Object to a PriorityQueue in log(size) time. + * If one tries to add more objects than maxSize from initialize + * a RuntimeException (ArrayIndexOutOfBound) is thrown. + */ + void put(_type element){ + if ( _size>=maxSize ) + _CLTHROWA(CL_ERR_IndexOutOfBounds,"add is out of bounds"); + + ++_size; + heap[_size] = element; + upHeap(); + } + + /** + * Adds element to the PriorityQueue in log(size) time if either + * the PriorityQueue is not full, or not lessThan(element, top()). + * @param element + * @return true if element is added, false otherwise. + */ + bool insert(_type element){ + _type t = insertWithOverflow(element); + if (t != element) { + if (t) _valueDeletor::doDelete(t); + return true; + } + return false; + } + + /** + * insertWithOverflow() is the same as insert() except its + * return value: it returns the object (if any) that was + * dropped off the heap because it was full. This can be + * the given parameter (in case it is smaller than the + * full heap's minimum, and couldn't be added), or another + * object that was previously the smallest value in the + * heap and now has been replaced by a larger one, or null + * if the queue wasn't yet full with maxSize elements. + * NOTE: value is not being deleted - its the user responsibilty + * to dispose the returned _type (only if != NULL && != element). + */ + _type insertWithOverflow(_type element) { + if(_size < maxSize){ + put(element); + return NULL; + }else if(_size > 0 && !lessThan(element, heap[1])){ + _type ret = heap[1]; + heap[1] = element; + adjustTop(); + return ret; + }else + return element; + } + + /** + * Returns the least element of the PriorityQueue in constant time. + */ + _type top(){ + // We don't need to check size here: if maxSize is 0, + // then heap is length 2 array with both entries null. + // If size is 0 then heap[1] is already null. + return heap[1]; + } + + /** Removes and returns the least element of the PriorityQueue in log(size) + * time. + */ + _type pop(){ + if (_size > 0) { + _type result = heap[1]; // save first value + heap[1] = heap[_size]; // move last to first + + heap[_size] = (_type)0; // permit GC of objects + --_size; + downHeap(); // adjust heap + return result; + } else + return (_type)NULL; + } + + /**Should be called when the object at top changes values. Still log(n) + worst case, but it's at least twice as fast to

+		    { pq.top().change(); pq.adjustTop(); }
+		   
instead of
+		    { o = pq.pop(); o.change(); pq.push(o); }
+		   
+ */ + void adjustTop(){ + downHeap(); + } + + + /** + * Returns the number of elements currently stored in the PriorityQueue. + */ + size_t size(){ + return _size; + } + + /** + * Removes all entries from the PriorityQueue. + */ + void clear(){ + for (size_t i = 1; i <= _size; ++i){ + if ( dk ){ + _valueDeletor::doDelete(heap[i]); + } + } + _size = 0; + } + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/Reader.cpp b/src/core/CLucene/util/Reader.cpp new file mode 100644 index 00000000000..c33695e00b4 --- /dev/null +++ b/src/core/CLucene/util/Reader.cpp @@ -0,0 +1,577 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "CLStreams.h" +#include "CLucene/util/Misc.h" + +#include +#ifdef _CL_HAVE_IO_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#include + +#include "_bufferedstream.h" + +CL_NS_DEF(util) + +/*template +void SStringReader::init(const T *_value, int32_t _length, bool copyData) { + const size_t length = _length; + this->pos = 0; + if (copyData) { + T *tmp = (T *) this->value; + if (tmp == NULL || !this->ownValue) { + tmp = _CL_NEWARRAY(T, length + 1); + this->buffer_size = length; + } else if (length > this->buffer_size || length < (this->buffer_size / 2)) {//expand, or shrink + tmp = (T *) realloc(tmp, sizeof(T) * (length + 1)); + this->buffer_size = length; + } + _tcsncpy(tmp, _value, length + 1); + this->value = tmp; + } else { + if (ownValue && this->value != NULL) { + _CLDELETE_LARRAY((T *) this->value); + } + this->value = _value; + this->buffer_size = 0; + } + this->m_size = length; + this->ownValue = copyData; +} +*/ +StringReader::StringReader ( const TCHAR* _value, const int32_t _length, bool copyData ) +{ + this->m_size = 0; + this->value = NULL; + this->ownValue = true; + this->buffer_size = 0; + this->init(_value,_length,copyData); +} + +void StringReader::init(const TCHAR *_value, const int32_t _length, bool copyData) { + const size_t length = (_length < 0 ? _tcslen(_value) : _length); + this->pos = 0; + if (copyData) { + TCHAR *tmp = (TCHAR *) this->value; + if (tmp == NULL || !this->ownValue) { + tmp = _CL_NEWARRAY(TCHAR, length + 1); + this->buffer_size = length; + } else if (length > this->buffer_size || length < (this->buffer_size / 2)) {//expand, or shrink + tmp = (TCHAR *) realloc(tmp, sizeof(TCHAR) * (length + 1)); + this->buffer_size = length; + } + _tcsncpy(tmp, _value, length + 1); + this->value = tmp; + } else { + if (ownValue && this->value != NULL) { + _CLDELETE_LARRAY((TCHAR *) this->value); + } + this->value = _value; + this->buffer_size = 0; + } + this->m_size = length; + this->ownValue = copyData; +} + +StringReader::~StringReader(){ + if ( ownValue && this->value != NULL){ + TCHAR* value = (TCHAR*) this->value; + _CLDELETE_LARRAY(value); + this->value = NULL; + } +} + +size_t StringReader::size(){ + return m_size; +} +int32_t StringReader::read(const void** start, int32_t min, int32_t max){ + if ( m_size == pos ) + return -1; + *(const TCHAR**)start = this->value + pos; + int32_t r = (int32_t)cl_min(cl_max(min,max),m_size-pos); + pos += r; + return r; +} +int64_t StringReader::position(){ + return pos; +} +void StringReader::setMinBufSize(int32_t /*s*/){ +} +int64_t StringReader::reset(int64_t pos){ + if ( pos >= 0 && pos < this->m_size ) + this->pos = pos; + return this->pos; +} +int64_t StringReader::skip(int64_t ntoskip){ + int64_t s = cl_min(ntoskip, m_size-pos); + this->pos += s; + return s; +} + + + + +AStringReader::AStringReader ( char* value, const int32_t length, bool copyData ) +{ + this->m_size = length; + this->pos = 0; + if ( copyData ){ + this->value = _CL_NEWARRAY(signed char, this->m_size); + strncpy((char*)this->value, value, this->m_size); + }else{ + this->value = (signed char*)value; + } + this->ownValue = copyData; +} + +AStringReader::AStringReader ( const char* value, const int32_t length ){ + if ( length >= 0 ) + this->m_size = length; + else + this->m_size = strlen(value); + this->pos = 0; + this->value = _CL_NEWARRAY(signed char, this->m_size); + strncpy((char*)this->value, value, this->m_size); + this->ownValue = true; +} +AStringReader::~AStringReader(){ + if ( ownValue ) + _CLDELETE_ARRAY(this->value); +} + +size_t AStringReader::size(){ + return m_size; +} +int32_t AStringReader::read(const signed char*& start, int32_t min, int32_t max){ + if ( m_size == pos ) + return -1; + start = this->value + pos; + int32_t r = (int32_t)cl_min(cl_max(min,max),m_size-pos); + pos += r; + return r; +} +int32_t AStringReader::read(const unsigned char*& start, int32_t min, int32_t max){ + if ( m_size == pos ) + return -1; + start = (unsigned char*)(this->value + pos); + int32_t r = (int32_t)cl_min(cl_max(min,max),m_size-pos); + pos += r; + return r; +} +int64_t AStringReader::position(){ + return pos; +} +void AStringReader::setMinBufSize(int32_t /*s*/){ +} +int64_t AStringReader::reset(int64_t pos){ + if ( pos >= 0 && pos < this->m_size ) + this->pos = pos; + return this->pos; +} +int64_t AStringReader::skip(int64_t ntoskip){ + int64_t s = cl_min(ntoskip, m_size-pos); + this->pos += s; + return s; +} + +class FileInputStream::Internal{ +public: + class JStreamsBuffer: public BufferedInputStreamImpl{ + int32_t fhandle; + protected: + int32_t fillBuffer(signed char* start, int32_t space){ + if (fhandle == 0) return -1; + // read into the buffer + int32_t nwritten = ::_read(fhandle, start, space); + + // check the file stream status + if (nwritten == -1 ) { + m_error = "Could not read from file"; + m_status = CL_NS(util)::Error; + if ( fhandle > 0 ){ + ::_close(fhandle); + fhandle = 0; + } + return -1; + }else if ( nwritten == 0 ) { + ::_close(fhandle); + fhandle = 0; + } + return nwritten; + } + public: + int encoding; + + JStreamsBuffer(int32_t fhandle, int32_t buffersize){ + this->fhandle = fhandle; + + m_size = fileSize(fhandle); // no need to know the file length... + + // allocate memory in the buffer + int32_t bufsize = (int32_t)((m_size <= buffersize) ?m_size+1 :buffersize); + setMinBufSize(bufsize); + } + void _setMinBufSize(int32_t bufsize){ + this->setMinBufSize(bufsize); + } + + ~JStreamsBuffer(){ + if ( fhandle > 0 ){ + if ( ::_close(fhandle) != 0 ) + _CLTHROWA(CL_ERR_IO, "File IO Close error"); + } + } + }; + + JStreamsBuffer* jsbuffer; + + Internal(const char* path, int32_t buffersize){ + int32_t fhandle = _cl_open(path, _O_BINARY | O_RDONLY | _O_RANDOM, _S_IREAD ); + + //Check if a valid handle was retrieved + if (fhandle < 0){ + int err = errno; + if ( err == ENOENT ) + _CLTHROWA(CL_ERR_IO, "File does not exist"); + else if ( err == EACCES ) + _CLTHROWA(CL_ERR_IO, "File Access denied"); + else if ( err == EMFILE ) + _CLTHROWA(CL_ERR_IO, "Too many open files"); + else + _CLTHROWA(CL_ERR_IO, "Could not open file"); + } + jsbuffer = new JStreamsBuffer(fhandle, buffersize); + + } + ~Internal(){ + delete jsbuffer; + } +}; + + +FileInputStream::FileInputStream ( const char* path, int32_t buflen ) +{ + if ( buflen == -1 ) + buflen = DEFAULT_BUFFER_SIZE; + _internal = new Internal(path, buflen); +} + +size_t FileInputStream::size(){ + return (size_t)_internal->jsbuffer->size(); +} + +FileInputStream::~FileInputStream () +{ + delete _internal; +} + +int32_t FileInputStream::read(const void** start, int32_t min, int32_t max){ + return _internal->jsbuffer->read((const signed char*&)*start,min,max); +} +int64_t FileInputStream::position(){ + return _internal->jsbuffer->position(); +} +int64_t FileInputStream::reset(int64_t to){ + return _internal->jsbuffer->reset(to); +} +int64_t FileInputStream::skip(int64_t ntoskip){ + return _internal->jsbuffer->skip(ntoskip); +} +void FileInputStream::setMinBufSize(int32_t minbufsize){ + _internal->jsbuffer->_setMinBufSize(minbufsize); +} + + +FileReader::FileReader(const char *path, const char *enc, int32_t buflen) +{ + int encoding; + if ( strcmp(enc,"ASCII")==0 ) + encoding = ASCII; +#ifdef _UCS2 + else if ( strcmp(enc,"UTF-8")==0 ) + encoding = UTF8; + else if ( strcmp(enc,"UCS-2LE")==0 ) + encoding = UCS2_LE; +#endif + else + _CLTHROWA(CL_ERR_IllegalArgument,"Unsupported encoding, use jstreams iconv based instead"); + init( _CLNEW FileInputStream(path, buflen), encoding); +} +FileReader::FileReader(const char *path, int encoding, int32_t buflen) +{ + init(_CLNEW FileInputStream(path, buflen), encoding); +} +FileReader::~FileReader(){ +} + +class SimpleInputStreamReader::Internal{ +public: + + class JStreamsBuffer: public BufferedReaderImpl{ + InputStream* input; + char utf8buf[6]; //< buffer used for converting utf8 characters + protected: + int readChar(){ + const signed char* buf; + if ( encoding == ASCII ){ + int32_t ret = this->input->read((const void**)&buf, 1, 1) ; + if ( ret == 1 ){ + return buf[0]; + }else + return -1; + + }else if ( encoding == UCS2_LE ){ + int32_t ret = this->input->read((const void**)&buf, 2, 2); + if ( ret < 0 ) + return -1; + else if ( ret == 1 ){ + return buf[0]; + }else{ + uint8_t c1 = *buf; + uint8_t c2 = *(buf+1); + return c1 | (c2<<8); + } + }else if ( encoding == UTF8 ){ + int32_t ret = this->input->read((const void**)&buf, 1, 1); + + if ( ret == 1 ){ + int len = lucene_utf8charlen(buf[0]); + if ( len > 1 ){ + *utf8buf = buf[0]; + ret = this->input->read((const void**)&buf, len-1, len-1); + }else + return buf[0]; + + if ( ret >= 0 ){ + if ( ret == len-1 ){ + memcpy(utf8buf+1,buf,ret); + wchar_t wcbuf=0; + lucene_utf8towc(wcbuf, utf8buf); + return wcbuf; + } + } + }else if ( ret == -1 ) + return -1; + this->m_error = "Invalid multibyte sequence."; + this->m_status = CL_NS(util)::Error; + }else{ + this->m_error = "Unexpected encoding"; + this->m_status = CL_NS(util)::Error; + } + return -1; + } + int32_t fillBuffer(TCHAR* start, int32_t space){ + if ( input == NULL ) return -1; + + int c; + int32_t i; + for(i=0;im_status == CL_NS(util)::Ok ){ + if ( i == 0 ) + return -1; + break; + } + return -1; + } + start[i] = c; + } + return i; + } + public: + int encoding; + + JStreamsBuffer(InputStream* input, int encoding){ + this->input = input; + this->encoding = encoding; + setMinBufSize(1024); + } + virtual ~JStreamsBuffer(){ + _CLDELETE(input); + } + void _setMinBufSize(int32_t min){ + this->setMinBufSize(min); + } + }; + + JStreamsBuffer* jsbuffer; + + Internal(InputStream* input, int encoding){ + jsbuffer = new JStreamsBuffer(input, encoding); + } + ~Internal(){ + delete jsbuffer; + } +}; + +SimpleInputStreamReader::SimpleInputStreamReader(){ + _internal = NULL; +} +SimpleInputStreamReader::SimpleInputStreamReader(InputStream *i, int encoding){ + _internal = new Internal(i, encoding); +} +void SimpleInputStreamReader::init(InputStream *i, int encoding){ + _internal = new Internal(i, encoding); +} +SimpleInputStreamReader::~SimpleInputStreamReader(){ + delete _internal; +} + +int32_t SimpleInputStreamReader::read(const void** start, int32_t min, int32_t max){ + return _internal->jsbuffer->read((const TCHAR*&) *start, min, max); +} +int64_t SimpleInputStreamReader::position(){ + return _internal->jsbuffer->position(); +} +int64_t SimpleInputStreamReader::reset(int64_t to){ + return _internal->jsbuffer->reset(to); +} +int64_t SimpleInputStreamReader::skip(int64_t ntoskip){ + return _internal->jsbuffer->skip(ntoskip); +} +size_t SimpleInputStreamReader::size(){ + return (size_t)_internal->jsbuffer->size(); +} +void SimpleInputStreamReader::setMinBufSize(int32_t minbufsize){ + _internal->jsbuffer->_setMinBufSize(minbufsize); +} + +class FilteredBufferedReader::Internal{ +public: + class JStreamsFilteredBuffer: public BufferedReaderImpl{ + Reader* input; + bool deleteInput; + protected: + int32_t fillBuffer(TCHAR* start, int32_t space){ + const TCHAR* buffer; + int32_t r = input->read((const void**)&buffer, 1, space); + if ( r > 0 ) + _tcsncpy(start, buffer, r); + return r; + } + public: + JStreamsFilteredBuffer(Reader* input, bool deleteInput){ + this->input = input; + this->deleteInput = deleteInput; + } + ~JStreamsFilteredBuffer(){ + if ( deleteInput ) + _CLDELETE(input); + } + void _setMinBufSize(int32_t min){ + this->setMinBufSize(min); + } + }; + JStreamsFilteredBuffer* jsbuffer; + + Internal(Reader* reader, bool deleteReader){ + this->jsbuffer = new JStreamsFilteredBuffer(reader, deleteReader); + } + ~Internal(){ + delete jsbuffer; + } +}; +FilteredBufferedReader::FilteredBufferedReader(Reader* reader, bool deleteReader){ + _internal = new Internal(reader, deleteReader); +} +FilteredBufferedReader::~FilteredBufferedReader(){ + delete _internal; +} +int32_t FilteredBufferedReader::read(const void** start, int32_t min, int32_t max){ + return _internal->jsbuffer->read((const TCHAR*&)*start,min,max); +} +int64_t FilteredBufferedReader::position(){ + return _internal->jsbuffer->position(); +} +int64_t FilteredBufferedReader::reset(int64_t p){ + return _internal->jsbuffer->reset(p); +} +int64_t FilteredBufferedReader::skip(int64_t ntoskip){ + return _internal->jsbuffer->skip(ntoskip); +} +size_t FilteredBufferedReader::size(){ + return (size_t)_internal->jsbuffer->size(); +} +void FilteredBufferedReader::setMinBufSize(int32_t minbufsize){ + return _internal->jsbuffer->_setMinBufSize(minbufsize); +} + + + + +class FilteredBufferedInputStream::Internal{ +public: + class JStreamsFilteredBuffer: public BufferedInputStreamImpl{ + InputStream* input; + bool deleteInput; + protected: + int32_t fillBuffer(signed char* start, int32_t space){ + const signed char* buffer; + int32_t r = input->read((const void**)&buffer, 1, space); + if ( r > 0 ) + memcpy(start, buffer, r); + return r; + } + public: + JStreamsFilteredBuffer(InputStream* input, bool deleteInput){ + this->input = input; + this->deleteInput = deleteInput; + } + ~JStreamsFilteredBuffer(){ + if ( deleteInput ) + _CLDELETE(input); + } + void _setMinBufSize(int32_t min){ + this->setMinBufSize(min); + } + }; + JStreamsFilteredBuffer* jsbuffer; + + Internal(InputStream* input, bool deleteInput){ + this->jsbuffer = new JStreamsFilteredBuffer(input, deleteInput); + } + ~Internal(){ + delete jsbuffer; + } +}; +FilteredBufferedInputStream::FilteredBufferedInputStream(InputStream* input, bool deleteInput){ + _internal = new Internal(input, deleteInput); +} +FilteredBufferedInputStream::~FilteredBufferedInputStream(){ + delete _internal; +} +int32_t FilteredBufferedInputStream::read(const signed char*& start, int32_t min, int32_t max){ + return _internal->jsbuffer->read(start,min,max); +} +int64_t FilteredBufferedInputStream::position(){ + return _internal->jsbuffer->position(); +} +int64_t FilteredBufferedInputStream::reset(int64_t p){ + return _internal->jsbuffer->reset(p); +} +int64_t FilteredBufferedInputStream::skip(int64_t ntoskip){ + return _internal->jsbuffer->skip(ntoskip); +} +size_t FilteredBufferedInputStream::size(){ + return (size_t)_internal->jsbuffer->size(); +} +void FilteredBufferedInputStream::setMinBufSize(int32_t minbufsize){ + return _internal->jsbuffer->_setMinBufSize(minbufsize); +} + +CL_NS_END diff --git a/src/core/CLucene/util/Reader.h b/src/core/CLucene/util/Reader.h new file mode 100644 index 00000000000..a523d337fc4 --- /dev/null +++ b/src/core/CLucene/util/Reader.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_Reader_ +#define _lucene_util_Reader_ + +#include "CLucene/util/CLStreams.h" +CL_NS_DEF(util) + +#error Reader has been refactored. It is recommended that you use strigi streams +#error for all input into CLucene. If, however, you dont want to use that dependency, +#error then you'll have to refactor your current code. The jstreams namespace +#error was completely removed + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/Sorter.cpp b/src/core/CLucene/util/Sorter.cpp new file mode 100644 index 00000000000..83bd1c5b1bf --- /dev/null +++ b/src/core/CLucene/util/Sorter.cpp @@ -0,0 +1,200 @@ +#include "Sorter.h" + +CL_NS_DEF(util) + +Sorter::Sorter() {} + +void Sorter::setPivot(int i) { pivotIndex = i; } + +int Sorter::comparePivot(int j) { return compare(pivotIndex, j); } + +void Sorter::checkRange(int from, int to) { + if (to < from) { + _CLTHROWA(CL_ERR_IllegalArgument, ("'to' must be >= 'from', got from=" + to_string(from) + " and to=" + to_string(to)).c_str()); + } +} + +void Sorter::mergeInPlace(int from, int mid, int to) { + if (from == mid || mid == to || compare(mid - 1, mid) <= 0) { + return; + } else if (to - from == 2) { + swap(mid - 1, mid); + return; + } + while (compare(from, mid) <= 0) { + ++from; + } + while (compare(mid - 1, to - 1) <= 0) { + --to; + } + int first_cut, second_cut; + int len11, len22; + if (mid - from > to - mid) { + len11 = static_cast(static_cast((mid - from)) >> 1); + first_cut = from + len11; + second_cut = lower(mid, to, first_cut); + len22 = second_cut - mid; + } else { + len22 = static_cast(static_cast((to - mid)) >> 1); + second_cut = mid + len22; + first_cut = upper(from, mid, second_cut); + len11 = first_cut - from; + } + rotate(first_cut, mid, second_cut); + int new_mid = first_cut + len22; + mergeInPlace(from, first_cut, new_mid); + mergeInPlace(new_mid, second_cut, to); +} + +int Sorter::lower(int from, int to, int val) { + int len = to - from; + while (len > 0) { + int half = static_cast(static_cast(len) >> 1); + int mid = from + half; + if (compare(mid, val) < 0) { + from = mid + 1; + len = len - half - 1; + } else { + len = half; + } + } + return from; +} + +int Sorter::upper(int from, int to, int val) { + int len = to - from; + while (len > 0) { + int half = static_cast(static_cast(len) >> 1); + int mid = from + half; + if (compare(val, mid) < 0) { + len = half; + } else { + from = mid + 1; + len = len - half - 1; + } + } + return from; +} + +int Sorter::lower2(int from, int to, int val) { + int f = to - 1, t = to; + while (f > from) { + if (compare(f, val) < 0) { + return lower(f, t, val); + } + int delta = t - f; + t = f; + f -= delta << 1; + } + return lower(from, t, val); +} + +int Sorter::upper2(int from, int to, int val) { + int f = from, t = f + 1; + while (t < to) { + if (compare(t, val) > 0) { + return upper(f, t, val); + } + int delta = t - f; + f = t; + t += delta << 1; + } + return upper(f, to, val); +} + +void Sorter::reverse(int from, int to) { + for (--to; from < to; ++from, --to) { + swap(from, to); + } +} + +void Sorter::rotate(int lo, int mid, int hi) { + assert(lo <= mid && mid <= hi); + if (lo == mid || mid == hi) { + return; + } + doRotate(lo, mid, hi); +} + +void Sorter::doRotate(int lo, int mid, int hi) { + if (mid - lo == hi - mid) { + // happens rarely but saves n/2 swaps + while (mid < hi) { + swap(lo++, mid++); + } + } else { + reverse(lo, mid); + reverse(mid, hi); + reverse(lo, hi); + } +} + +void Sorter::binarySort(int from, int to) { binarySort(from, to, from + 1); } + +void Sorter::binarySort(int from, int to, int i) { + for (; i < to; ++i) { + setPivot(i); + int l = from; + int h = i - 1; + while (l <= h) { + int mid = + static_cast(static_cast((l + h)) >> 1); + int cmp = comparePivot(mid); + if (cmp < 0) { + h = mid - 1; + } else { + l = mid + 1; + } + } + for (int j = i; j > l; --j) { + swap(j - 1, j); + } + } +} + +void Sorter::heapSort(int from, int to) { + if (to - from <= 1) { + return; + } + heapify(from, to); + for (int end = to - 1; end > from; --end) { + swap(from, end); + siftDown(from, from, end); + } +} + +void Sorter::heapify(int from, int to) { + for (int i = heapParent(from, to - 1); i >= from; --i) { + siftDown(i, from, to); + } +} + +void Sorter::siftDown(int i, int from, int to) { + for (int leftChild = heapChild(from, i); leftChild < to; + leftChild = heapChild(from, i)) { + int rightChild = leftChild + 1; + if (compare(i, leftChild) < 0) { + if (rightChild < to && compare(leftChild, rightChild) < 0) { + swap(i, rightChild); + i = rightChild; + } else { + swap(i, leftChild); + i = leftChild; + } + } else if (rightChild < to && compare(i, rightChild) < 0) { + swap(i, rightChild); + i = rightChild; + } else { + break; + } + } +} + +int Sorter::heapParent(int from, int i) { + return (static_cast(static_cast((i - 1 - from)) >> 1)) + + from; +} + +int Sorter::heapChild(int from, int i) { return ((i - from) << 1) + 1 + from; } + +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/Sorter.h b/src/core/CLucene/util/Sorter.h new file mode 100644 index 00000000000..2778fe3c27d --- /dev/null +++ b/src/core/CLucene/util/Sorter.h @@ -0,0 +1,89 @@ +#pragma once +#include "CLucene/_ApiHeader.h" +#include + +#include + +CL_NS_DEF(util) + +/** Base class for sorting algorithms implementations. + * @lucene.internal */ +class Sorter : public std::enable_shared_from_this { +public: + static constexpr int BINARY_SORT_THRESHOLD = 20; + + /** Sole constructor, used for inheritance. */ +protected: + Sorter(); + + /** Compare entries found in slots i and j. + * The contract for the returned value is the same as + * {@link Comparator#compare(Object, Object)}. */ + virtual int compare(int i, int j) = 0; + + /** Swap values at slots i and j. */ + virtual void swap(int i, int j) = 0; + +private: + int pivotIndex = 0; + + /** Save the value at slot i so that it can later be used as a + * pivot, see {@link #comparePivot(int)}. */ +protected: + virtual void setPivot(int i); + + /** Compare the pivot with the slot at j, similarly to + * {@link #compare(int, int) compare(i, j)}. */ + virtual int comparePivot(int j); + + /** Sort the slice which starts at from (inclusive) and ends at + * to (exclusive). */ +public: + virtual void sort(int from, int to) = 0; + + virtual void checkRange(int from, int to); + + virtual void mergeInPlace(int from, int mid, int to); + + virtual int lower(int from, int to, int val); + + virtual int upper(int from, int to, int val); + + // faster than lower when val is at the end of [from:to[ + virtual int lower2(int from, int to, int val); + + // faster than upper when val is at the beginning of [from:to[ + virtual int upper2(int from, int to, int val); + + void reverse(int from, int to); + + void rotate(int lo, int mid, int hi); + + virtual void doRotate(int lo, int mid, int hi); + + /** + * A binary sort implementation. This performs {@code O(n*log(n))} comparisons + * and {@code O(n^2)} swaps. It is typically used by more sophisticated + * implementations as a fall-back when the numbers of items to sort has become + * less than {@value #BINARY_SORT_THRESHOLD}. + */ + virtual void binarySort(int from, int to); + + virtual void binarySort(int from, int to, int i); + + /** + * Use heap sort to sort items between {@code from} inclusive and {@code to} + * exclusive. This runs in {@code O(n*log(n))} and is used as a fall-back by + * {@link IntroSorter}. + */ + virtual void heapSort(int from, int to); + + virtual void heapify(int from, int to); + + virtual void siftDown(int i, int from, int to); + + static int heapParent(int from, int i); + + static int heapChild(int from, int i); +}; +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/StringIntern.cpp b/src/core/CLucene/util/StringIntern.cpp new file mode 100644 index 00000000000..69199e63230 --- /dev/null +++ b/src/core/CLucene/util/StringIntern.cpp @@ -0,0 +1,122 @@ + /*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "_StringIntern.h" +CL_NS_DEF(util) + +typedef CL_NS(util)::CLHashMap __wcsintrntype; +typedef CL_NS(util)::CLHashMap __strintrntype; +__wcsintrntype StringIntern_stringPool(true); +__strintrntype StringIntern_stringaPool(true); + +bool StringIntern_blanksinitd=false; +__wcsintrntype::iterator StringIntern_wblank; + +//STATIC_DEFINE_MUTEX(StringIntern_THIS_LOCK); +DEFINE_MUTEX(StringIntern_THIS_LOCK) + + + void CLStringIntern::_shutdown(){ + #ifdef _DEBUG + SCOPED_LOCK_MUTEX(StringIntern_THIS_LOCK) + if ( StringIntern_stringaPool.size() > 0 ){ + printf("WARNING: stringaPool still contains intern'd strings (refcounts):\n"); + __strintrntype::iterator itr = StringIntern_stringaPool.begin(); + while ( itr != StringIntern_stringaPool.end() ){ + printf(" %s (%d)\n",(itr->first), (itr->second)); + ++itr; + } + } + + if ( StringIntern_stringPool.size() > 0 ){ + printf("WARNING: stringPool still contains intern'd strings (refcounts):\n"); + __wcsintrntype::iterator itr = StringIntern_stringPool.begin(); + while ( itr != StringIntern_stringPool.end() ){ + _tprintf(_T(" %s (%d)\n"),(itr->first), (itr->second)); + ++itr; + } + } + #endif + } + + const TCHAR* CLStringIntern::intern(const TCHAR* str){ + if ( str == NULL ) + return NULL; + if ( str[0] == 0 ) + return LUCENE_BLANK_STRING; + + SCOPED_LOCK_MUTEX(StringIntern_THIS_LOCK) + + __wcsintrntype::iterator itr = StringIntern_stringPool.find((TCHAR*)str); + if ( itr==StringIntern_stringPool.end() ){ + TCHAR* ret = STRDUP_TtoT(str); + StringIntern_stringPool[ret]= 1; + return ret; + }else{ + (itr->second)++; + return itr->first; + } + } + + bool CLStringIntern::unintern(const TCHAR* str){ + if ( str == NULL ) + return false; + if ( str[0] == 0 ) + return false; // warning: a possible memory leak, since str may be never freed! + + SCOPED_LOCK_MUTEX(StringIntern_THIS_LOCK) + + __wcsintrntype::iterator itr = StringIntern_stringPool.find((TCHAR*)str); + if ( itr != StringIntern_stringPool.end() ){ + if ( (itr->second) == 1 ){ + StringIntern_stringPool.removeitr(itr); + return true; + }else + (itr->second)--; + } + return false; + } + + const char* CLStringIntern::internA(const char* str, const int8_t count, const bool use_provided){ + if ( str == NULL ) + return NULL; + if ( str[0] == 0 ) + return _LUCENE_BLANK_ASTRING; + + SCOPED_LOCK_MUTEX(StringIntern_THIS_LOCK) + + __strintrntype::iterator itr = StringIntern_stringaPool.find((char*)str); + if ( itr==StringIntern_stringaPool.end() ){ + char* ret = (use_provided) ? const_cast(str) : STRDUP_AtoA(str); + StringIntern_stringaPool[ret] = count; + return ret; + }else{ + if (use_provided) _CLDELETE_LCaARRAY((char*)str); // delete the provided string if already exists + (itr->second) = (itr->second) + count; + return itr->first; + } + } + + bool CLStringIntern::uninternA(const char* str, const int8_t count){ + if ( str == NULL ) + return false; + if ( str[0] == 0 ) + return false; // warning: a possible memory leak, since str may be never freed! + + SCOPED_LOCK_MUTEX(StringIntern_THIS_LOCK) + + __strintrntype::iterator itr = StringIntern_stringaPool.find((char*)str); + if ( itr!=StringIntern_stringaPool.end() ){ + if ( (itr->second) == count ){ + StringIntern_stringaPool.removeitr(itr); + return true; + }else + (itr->second) = (itr->second) - count; + } + return false; + } +CL_NS_END diff --git a/src/core/CLucene/util/ThreadLocal.cpp b/src/core/CLucene/util/ThreadLocal.cpp new file mode 100644 index 00000000000..ed1b0ebde84 --- /dev/null +++ b/src/core/CLucene/util/ThreadLocal.cpp @@ -0,0 +1,266 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include + +#include "CLucene/_ApiHeader.h" +#include "CLucene/LuceneThreads.h" +#include "_ThreadLocal.h" +#include "CLucene/config/_threads.h" +#include + +CL_NS_DEF ( util ) + +/* +* The concept of ThreadLocal is that a ThreadLocal class stores specific values for each unique thread. +* Several thread-end detection techniques are used to delete the thread data if the thread dies before the ThreadLocal class is shut. +* +* The class->thread data mapping is stored in the _ThreadLocal class. +* The thread->datas mapping is in ThreadData. +*/ + + +//predefine for the shared code... +#if defined(_CL_HAVE_WIN32_THREADS) + #define INIT_THREAD(ret) ret=true + extern "C"{ + + //todo: move this to StdHeader and make it usable by other functions... + bool __stdcall DllMain( unsigned short hinstDLL, // DLL module handle + _cl_dword_t fdwReason, // reason called + void*) // reserved + { + if ( fdwReason == 3 ) + _ThreadLocal::UnregisterCurrentThread(); + + return true; + } + } +#elif defined(_CL_HAVE_PTHREAD) + pthread_key_t pthread_threadlocal_key; + pthread_once_t pthread_threadlocal_key_once = PTHREAD_ONCE_INIT; + #define INIT_THREAD(ret) \ + pthread_once(&pthread_threadlocal_key_once, pthread_threadlocal_make_key); \ + if (pthread_getspecific(pthread_threadlocal_key) == NULL) { pthread_setspecific(pthread_threadlocal_key, (void*)1); } \ + ret = true; + + //the function that is called when the thread shutsdown + void pthread_threadlocal_destructor(void* /*_holder*/){ + _ThreadLocal::UnregisterCurrentThread(); + } + //the key initialiser function + void pthread_threadlocal_make_key() + { + (void) pthread_key_create(&pthread_threadlocal_key, &pthread_threadlocal_destructor); + } +#endif + +class _ThreadLocal; + +/** +* List that holds the list of ThreadLocals that this thread has data in. +*/ +class ThreadLocals : private std::set<_ThreadLocal*> +{ +public: + void UnregisterThread(); + void add(_ThreadLocal* thread); + void remove(_ThreadLocal* thread); +}; + +//map of thread<>ThreadLocals +typedef CL_NS ( util ) ::CLMultiMap<_LUCENE_THREADID_TYPE, ThreadLocals*, + CL_NS ( util ) ::CLuceneThreadIdCompare, + CL_NS ( util ) ::Deletor::ConstNullVal<_LUCENE_THREADID_TYPE>, + CL_NS ( util ) ::Deletor::Object > ThreadDataType; +static ThreadDataType* threadData = NULL; + +#ifndef _CL_DISABLE_MULTITHREADING + //the lock for locking ThreadData + //we don't use STATIC_DEFINE_MUTEX, because then the initialization order will be undefined. + static _LUCENE_THREADMUTEX *threadData_LOCK = NULL; +#endif + + +class _ThreadLocal::Internal +{ + public: + typedef CL_NS ( util ) ::CLSet<_LUCENE_THREADID_TYPE, void*, + CL_NS ( util ) ::CLuceneThreadIdCompare, + CL_NS ( util ) ::Deletor::ConstNullVal<_LUCENE_THREADID_TYPE>, + CL_NS ( util ) ::Deletor::ConstNullVal > LocalsType; + LocalsType locals; + DEFINE_MUTEX ( locals_LOCK ) + AbstractDeletor* _deletor; + + Internal ( AbstractDeletor* _deletor ) : + locals ( false,false ) + { + this->_deletor = _deletor; + } + ~Internal() + { + //remove all the thread local data for this object + LocalsType::iterator itr = locals.begin(); + while ( itr != locals.end() ) + { + void* val = itr->second; + locals.removeitr ( itr ); + _deletor->Delete ( val ); + itr = locals.begin(); + } + + delete _deletor; + } +}; + +_ThreadLocal::_ThreadLocal ( CL_NS ( util ) ::AbstractDeletor* _deletor ) : + _internal ( _CLNEW Internal ( _deletor ) ) +{ + +} + +_ThreadLocal::~_ThreadLocal() +{ + setNull(); + UnregisterCurrentThread(); + RemoveThreadLocal( this ); + delete _internal; +} + + +void* _ThreadLocal::get() +{ + SCOPED_LOCK_MUTEX(_internal->locals_LOCK) + return _internal->locals.get ( _LUCENE_CURRTHREADID ); +} + +void _ThreadLocal::setNull() +{ + //just delete this thread from the locals list + _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID; + SCOPED_LOCK_MUTEX(_internal->locals_LOCK) + Internal::LocalsType::iterator itr = _internal->locals.find ( id ); + if ( itr != _internal->locals.end() ) + { + void* val = itr->second; + _internal->locals.removeitr ( itr ); + _internal->_deletor->Delete ( val ); + } +} + +void _ThreadLocal::set ( void* t ) +{ + if ( t == NULL ){ + setNull(); + return; + } + //make sure we have a threadlocal context (for cleanup) + bool ret; + INIT_THREAD(ret); + assert(ret); + + _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID; + + //drop a reference to this ThreadLocal in ThreadData + { +#ifndef _CL_DISABLE_MULTITHREADING + //slightly un-usual way of initialising mutex, + //because otherwise our initialisation order would be undefined + if ( threadData_LOCK == NULL ) + threadData_LOCK = _CLNEW _LUCENE_THREADMUTEX; + SCOPED_LOCK_MUTEX ( *threadData_LOCK ); +#endif + + if ( threadData == NULL ) + threadData = _CLNEW ThreadDataType ( false, true ); + + ThreadLocals* threadLocals = threadData->get(id); + if ( threadLocals == NULL ){ + threadLocals = _CLNEW ThreadLocals; + threadData->insert( std::pair(id,threadLocals)); + } + threadLocals->add(this); + } + + { + SCOPED_LOCK_MUTEX(_internal->locals_LOCK) + Internal::LocalsType::iterator itr = _internal->locals.find ( id ); + if ( itr != _internal->locals.end() ) + { + void* val = itr->second; + _internal->locals.removeitr ( itr ); + _internal->_deletor->Delete ( val ); + } + + if ( t != NULL ) + _internal->locals.put ( id, t ); + } + +} + +void _ThreadLocal::UnregisterCurrentThread() +{ + if ( threadData == NULL ) + return; + _LUCENE_THREADID_TYPE id = _LUCENE_CURRTHREADID; + SCOPED_LOCK_MUTEX ( *threadData_LOCK ); + + ThreadDataType::iterator itr = threadData->find(id); + if ( itr != threadData->end() ){ + ThreadLocals* threadLocals = itr->second; + threadLocals->UnregisterThread(); + threadData->removeitr(itr); + } +} + +void _ThreadLocal::RemoveThreadLocal( _ThreadLocal * tl ) +{ + if ( threadData == NULL ) + return; + + SCOPED_LOCK_MUTEX ( *threadData_LOCK ); + + ThreadDataType::iterator itr = threadData->begin(); + for( ThreadDataType::iterator itr = threadData->begin(); itr != threadData->end(); itr++ ) + { + ThreadLocals* threadLocals = itr->second; + threadLocals->remove( tl ); + // Remove empty threadLocals + } +} + +void _ThreadLocal::_shutdown() +{ +#ifndef _CL_DISABLE_MULTITHREADING + _CLDELETE(threadData_LOCK); +#endif + _CLDELETE(threadData); +} + + + +void ThreadLocals::UnregisterThread() +{ + //this should only be accessed from its own thread... if this changes, then this access has to be locked. + for( ThreadLocals::iterator iTLocal = begin(); iTLocal != end(); iTLocal++ ) + (*iTLocal)->setNull(); + clear(); +} +void ThreadLocals::add(_ThreadLocal* thread) +{ + //this should only be accessed from its own thread... if this changes, then this access has to be locked. + if( end() == find( thread ) ) + insert( thread ); +} +void ThreadLocals::remove(_ThreadLocal* thread) +{ + ThreadLocals::iterator iTLocal = find( thread ); + if( iTLocal != end() ) + erase( iTLocal ); +} + +CL_NS_END diff --git a/src/core/CLucene/util/Time.h b/src/core/CLucene/util/Time.h new file mode 100644 index 00000000000..9bb17686ac3 --- /dev/null +++ b/src/core/CLucene/util/Time.h @@ -0,0 +1,20 @@ +#include +#include + +CL_NS_DEF(util) + +#define NANOS_PER_SEC 1000000000ll +#define NANOS_PER_MILLIS 1000000ll +#define NANOS_PER_MICRO 1000ll +#define MICROS_PER_SEC 1000000ll +#define MICROS_PER_MILLI 1000ll +#define MILLIS_PER_SEC 1000ll +inline int64_t GetCurrentTimeMicros() { + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_sec * MICROS_PER_SEC + ts.tv_nsec / NANOS_PER_MICRO; +} +inline int64_t UnixMillis() { + return GetCurrentTimeMicros() / MICROS_PER_MILLI; +} +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/VoidList.h b/src/core/CLucene/util/VoidList.h new file mode 100644 index 00000000000..5abdd4523a4 --- /dev/null +++ b/src/core/CLucene/util/VoidList.h @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_VoidList_ +#define _lucene_util_VoidList_ + +#include "Equators.h" +#include "CLucene/LuceneThreads.h" + +CL_NS_DEF(util) + +/** +* A template to encapsulate various list type classes +* @internal +*/ +template +class CLUCENE_INLINE_EXPORT __CLList:public _base,LUCENE_BASE { +private: + bool dv; +protected: + typedef _base base; +public: + typedef typename _base::const_iterator const_iterator; + typedef typename _base::iterator iterator; + + virtual ~__CLList(){ + clear(); + } + + __CLList ( const bool deleteValue ): + dv(deleteValue) + { + } + + void setDoDelete(bool val){ dv=val; } + + //sets array to the contents of this array. + //array must be size + void toArray(_kt* into) const{ + int i=0; + for ( const_iterator itr=base::begin();itr!=base::end();itr++ ){ + into[i] = *itr; + i++; + } + } + + //sets array to the contents of this array, terminating with a NULL pointer + //array must be size+1 + void toArray_nullTerminated(_kt* into) const{ + int i=0; + for ( const_iterator itr=base::begin();itr!=base::end();itr++ ){ + into[i] = *itr; + i++; + } + into[i] = NULL; + } + + void set(size_t i, _kt val) { + if ( dv && i < base::size() ) + _valueDeletor::doDelete((*this)[i]); + if ( i+1 > base::size() ) base::resize(i+1); + (*this)[i] = val; + } + + //todo: check this + void delete_back(){ + if ( base::size() > 0 ){ + iterator itr = base::end(); + if ( itr != base::begin()) + itr --; + _kt key = *itr; + base::erase(itr); + if ( dv ) + _valueDeletor::doDelete(key); + } + } + + void delete_front(){ + if ( base::size() > 0 ){ + iterator itr = base::begin(); + _kt key = *itr; + base::erase(itr); + if ( dv ) + _valueDeletor::doDelete(key); + } + } + + void clear(){ + if ( dv ){ + iterator itr = base::begin(); + while ( itr != base::end() ){ + _valueDeletor::doDelete(*itr); + ++itr; + } + } + base::clear(); + } + + void remove(size_t i, bool dontDelete=false){ + if ( i < base::size() ){ + iterator itr=base::begin(); + itr+=i; + _kt key = *itr; + base::erase( itr ); + if ( dv && !dontDelete ) + _valueDeletor::doDelete(key); + } + } + void remove(iterator itr, bool dontDelete=false){ + _kt key = *itr; + base::erase( itr ); + if ( dv && !dontDelete ) + _valueDeletor::doDelete(key); + } +}; + + + +//growable arrays of Objects (like a collection or list) +//a list, so can contain duplicates +//it grows in chunks... todo: check jlucene for initial size of array, and growfactors +template +class CLUCENE_INLINE_EXPORT CLVector:public __CLList<_kt, CL_NS_STD(vector)<_kt> , _valueDeletor> +{ +public: + CLVector ( const bool deleteValue=true ): + __CLList<_kt, CL_NS_STD(vector)<_kt> , _valueDeletor>(deleteValue) + { + } +}; + +//An array-backed implementation of the List interface +//a list, so can contain duplicates +//*** a very simple list - use +//(This class is roughly equivalent to Vector, except that it is unsynchronized.) +#define CLArrayList CLVector +#define CLHashSet CLHashList +#define CLList CLVector + +//implementation of the List interface, provides access to the first and last list elements in O(1) +//no comparator is required... and so can contain duplicates +//a simple list with no comparator +//*** a very simple list - use +#ifdef LUCENE_DISABLE_HASHING + #define CLHashList CLSetList +#else + +template +class CLUCENE_INLINE_EXPORT CLHashList:public __CLList<_kt, CL_NS_HASHING(_CL_HASH_SET)<_kt,_Comparator> , _valueDeletor> +{ +public: + CLHashList ( const bool deleteValue=true ): + __CLList<_kt, CL_NS_HASHING(_CL_HASH_SET)<_kt,_Comparator> , _valueDeletor>(deleteValue) + { + } +}; +#endif + +template +class CLUCENE_INLINE_EXPORT CLLinkedList:public __CLList<_kt, CL_NS_STD(list)<_kt> , _valueDeletor> +{ +public: + CLLinkedList ( const bool deleteValue=true ): + __CLList<_kt, CL_NS_STD(list)<_kt> , _valueDeletor>(deleteValue) + { + } +}; +template +class CLUCENE_INLINE_EXPORT CLSetList:public __CLList<_kt, CL_NS_STD(set)<_kt,_Comparator> , _valueDeletor> +{ +public: + CLSetList ( const bool deleteValue=true ): + __CLList<_kt, CL_NS_STD(set)<_kt,_Comparator> , _valueDeletor>(deleteValue) + { + } +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/VoidMap.h b/src/core/CLucene/util/VoidMap.h new file mode 100644 index 00000000000..1037a9b8da3 --- /dev/null +++ b/src/core/CLucene/util/VoidMap.h @@ -0,0 +1,327 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_VoidMap_ +#define _lucene_util_VoidMap_ + +#include "Equators.h" +#include "CLucene/LuceneThreads.h" + +#if defined(_CL_HAVE_TR1_UNORDERED_MAP) && defined(_CL_HAVE_TR1_UNORDERED_SET) + #include + #include +#elif defined(_CL_HAVE_HASH_MAP) && defined(_CL_HAVE_HASH_SET) + //hashing is all or nothing! + #include + #include +#elif defined(_CL_HAVE_EXT_HASH_MAP) && defined(_CL_HAVE_EXT_HASH_SET) + #include + #include +#elif !defined(LUCENE_DISABLE_HASHING) + #define LUCENE_DISABLE_HASHING +#endif + +CL_NS_DEF(util) + +/** +* A template to encapsulate various map type classes +* @internal +*/ +template +class CLUCENE_INLINE_EXPORT __CLMap:public _base,LUCENE_BASE { +protected: + bool dk; + bool dv; + typedef _base base; +public: + typedef typename _base::iterator iterator; + typedef typename _base::const_iterator const_iterator; + typedef CL_NS_STD(pair)<_kt, _vt> _pair; + + ///Default constructor for the __CLMap + __CLMap (): + dk(true), + dv(true) + { + } + + ///Deconstructor for the __CLMap + ~__CLMap (){ + clear(); + } + + void setDeleteKey(bool val){ dk = val; } + void setDeleteValue(bool val){ dv = val; } + + ///Construct the VoidMap and set the deleteTypes to the specified values + ///\param deleteKey if true then the key variable is deleted when an object is deleted + ///\param keyDelType delete the key variable using the specified type + ///\param deleteValue if true then the value variable is deleted when an object is deleted + ///\param valueDelType delete the value variable using the specified type + /*__CLMap ( const bool deleteKey, const bool deleteValue ): + dk(deleteKey), + dv(deleteValue) + { + }*/ + + ///checks to see if the specified key exists + ///\param k the key to check for + ///\returns true if the key exists + bool exists(_kt k)const{ + const_iterator itr = base::find(k); + bool ret = itr!=base::end(); + return ret; + } + + ///using a non-const key, get a non-const value + _vt get( _kt k) const { + const_iterator itr = base::find(k); + if ( itr==base::end() ) + return (_vt)NULL; + else + return itr->second; + } + /* + ///using a non-const key, get the actual key + _kt getKey( _kt k) const { + const_iterator itr = base::find(k); + if ( itr==base::end() ) + return NULL; + else + return itr->first; + }*/ + + void removeitr (iterator itr, const bool dontDeleteKey = false, const bool dontDeleteValue = false){ + if ( itr == base::end() ) return; + + //delete key&val first. This prevents potential loops (deleting object removes itself) + _kt key = itr->first; + _vt val = itr->second; + base::erase(itr); + + //keys & vals need to be deleted after erase, because the hashvalue is still needed + if ( dk && !dontDeleteKey ) + _KeyDeletor::doDelete(key); + if ( dv && !dontDeleteValue ) + _ValueDeletor::doDelete(val); + } + ///delete and optionally delete the specified key and associated value + void remove(_kt key, const bool dontDeleteKey = false, const bool dontDeleteValue = false){ + iterator itr = base::find(key); + if ( itr!=base::end() ) + removeitr(itr,dontDeleteKey,dontDeleteValue); + } + + ///clear all keys and values in the map + void clear(){ + if ( dk || dv ){ + iterator itr = base::begin(); + while ( itr!=base::end() ){ + #ifdef _CL_HAVE_EXT_HASH_MAP + removeitr(itr); + itr = base::begin(); + + #else + if ( dk ) + _KeyDeletor::doDelete(itr->first); + if ( dv ) + _ValueDeletor::doDelete(itr->second); + ++itr; + + #endif + } + } + base::clear(); + } +}; + +// makes no guarantees as to the order of the map +// cannot contain duplicate keys; each key can map to at most one value +#define CLHashtable CLHashMap + +#if defined(LUCENE_DISABLE_HASHING) + + //a CLSet with CLHashMap traits +template +class CLUCENE_INLINE_EXPORT CLHashMap:public __CLMap<_kt,_vt, + CL_NS_STD(map)<_kt,_vt, _Compare>, + _KeyDeletor,_ValueDeletor> +{ + typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base; + typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>, + _KeyDeletor,_ValueDeletor> _this; +public: + CLHashMap ( const bool deleteKey=false, const bool deleteValue=false ) + { + _this::setDeleteKey(deleteKey); + _this::setDeleteValue(deleteValue); + } + + ///put the specified pair into the map. remove any old items first + ///\param k the key + ///\param v the value + virtual void put(_kt k,_vt v){ + //todo: check if this is always right! + //must should look through code, for + //cases where map is not unique!!! + if ( _this::dk || _this::dv ) + _this::remove(k); + + (*this)[k] = v;; + } + +}; +#elif defined(_CL_HAVE_EXT_HASH_MAP) + //ext/hash_map syntax +//HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized +template +class CLUCENE_INLINE_EXPORT CLHashMap:public __CLMap<_kt,_vt, + CL_NS_HASHING(_CL_HASH_MAP)<_kt,_vt, _Hasher,_Equals>, + _KeyDeletor,_ValueDeletor> +{ + typedef __CLMap<_kt,_vt, CL_NS_HASHING(_CL_HASH_MAP)<_kt,_vt, _Hasher,_Equals>, + _KeyDeletor,_ValueDeletor> _this; +public: + CLHashMap ( const bool deleteKey=false, const bool deleteValue=false ) + { + _this::setDeleteKey(deleteKey); + _this::setDeleteValue(deleteValue); + } + ///put the specified pair into the map. remove any old items first + ///\param k the key + ///\param v the value + virtual void put(_kt k,_vt v){ + //todo: check if this is always right! + //must should look through code, for + //cases where map is not unique!!! + if ( _this::dk || _this::dv ) + _this::remove(k); + + (*this)[k] = v;; + } + +}; + +#elif defined(_CL_HAVE_HASH_MAP) + +//HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized +template +class CLUCENE_INLINE_EXPORT CLHashMap:public __CLMap<_kt,_vt, + CL_NS_HASHING(_CL_HASH_MAP)<_kt,_vt, _Hasher>, + _KeyDeletor,_ValueDeletor> +{ + typedef __CLMap<_kt,_vt, CL_NS_HASHING(_CL_HASH_MAP)<_kt,_vt, _Hasher>, + _KeyDeletor,_ValueDeletor> _this; +public: + CLHashMap ( const bool deleteKey=false, const bool deleteValue=false ) + { + _this::setDeleteKey(deleteKey); + _this::setDeleteValue(deleteValue); + } + ///put the specified pair into the map. remove any old items first + ///\param k the key + ///\param v the value + virtual void put(_kt k,_vt v){ + //todo: check if this is always right! + //must should look through code, for + //cases where map is not unique!!! + if ( _this::dk || _this::dv ) + _this::remove(k); + + (*this)[k] = v;; + } + +}; +#endif + +//A collection that contains no duplicates +//does not guarantee that the order will remain constant over time +template +class CLUCENE_INLINE_EXPORT CLSet:public __CLMap<_kt,_vt, + CL_NS_STD(map)<_kt,_vt, _Compare>, + _KeyDeletor,_ValueDeletor> +{ + typedef typename CL_NS_STD(map)<_kt,_vt,_Compare> _base; + typedef __CLMap<_kt, _vt, CL_NS_STD(map)<_kt,_vt, _Compare>, + _KeyDeletor,_ValueDeletor> _this; +public: + CLSet ( const bool deleteKey=false, const bool deleteValue=false ) + { + _this::setDeleteKey(deleteKey); + _this::setDeleteValue(deleteValue); + } + ///put the specified pair into the map. remove any old items first + ///\param k the key + ///\param v the value + virtual void put(_kt k,_vt v){ + //todo: check if this is always right! + //must should look through code, for + //cases where map is not unique!!! + if ( _this::dk || _this::dv ) + _this::remove(k); + + (*this)[k] = v;; + } + +}; + + +//A collection that can contains duplicates +template +class CLUCENE_INLINE_EXPORT CLMultiMap:public __CLMap<_kt,_vt, + CL_NS_STD(multimap)<_kt,_vt>, + _KeyDeletor,_ValueDeletor> +{ + typedef typename CL_NS_STD(multimap)<_kt,_vt> _base; + typedef __CLMap<_kt, _vt, CL_NS_STD(multimap)<_kt,_vt>, + _KeyDeletor,_ValueDeletor> _this; +public: + CLMultiMap ( const bool deleteKey=false, const bool deleteValue=false ) + { + _this::setDeleteKey(deleteKey); + _this::setDeleteValue(deleteValue); + } + + ///put the specified pair into the map. remove any old items first + ///\param k the key + ///\param v the value + void put(_kt k,_vt v){ + //todo: check if this is always right! + //must should look through code, for + //cases where map is not unique!!! + if ( _this::dk || _this::dv ) + _this::remove(k); + + } +}; + + +//*** need to create a class that allows duplicates - use +//#define CLSet __CLMap +CL_NS_END + +#endif diff --git a/src/core/CLucene/util/_Arrays.h b/src/core/CLucene/util/_Arrays.h new file mode 100644 index 00000000000..cd446bffaab --- /dev/null +++ b/src/core/CLucene/util/_Arrays.h @@ -0,0 +1,155 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_Arrays_ +#define _lucene_util_Arrays_ + + +CL_NS_DEF(util) + template + class Arrays{ + Arrays(){} + public: + static void fill( _type* a, int32_t alen, _type value ) { + for ( int32_t i = 0; i < alen; i++ ) { + a[i] = value; + } + } + static void sort(_type* a, int32_t alen, int32_t fromIndex, int32_t toIndex){ + CND_PRECONDITION(fromIndex < toIndex,"fromIndex >= toIndex"); + CND_PRECONDITION(fromIndex >= 0,"fromIndex < 0"); + + // First presort the array in chunks of length 6 with insertion + // sort. A mergesort would give too much overhead for this length. + for (int32_t chunk = fromIndex; chunk < toIndex; chunk += 6) + { + int32_t end = cl_min(chunk + 6, toIndex); + for (int32_t i = chunk + 1; i < end; i++) + { + if (compare(a[i - 1], a[i]) > 0) + { + // not already sorted + int32_t j = i; + _type elem = a[j]; + do + { + a[j] = a[j - 1]; + j--; + } + while (j > chunk && compare(a[j - 1], elem) > 0); + a[j] = elem; + } + } + } + + int32_t len = toIndex - fromIndex; + // If length is smaller or equal 6 we are done. + if (len <= 6) + return; + + _type* src = a; + _type* dest = _CL_NEWARRAY(_type,alen); + _type* t = NULL; // t is used for swapping src and dest + + // The difference of the fromIndex of the src and dest array. + int32_t srcDestDiff = -fromIndex; + + // The merges are done in this loop + for (int32_t size = 6; size < len; size <<= 1) + { + for (int32_t start = fromIndex; start < toIndex; start += size << 1) + { + // mid is the start of the second sublist; + // end the start of the next sublist (or end of array). + int32_t mid = start + size; + int32_t end = cl_min(toIndex, mid + size); + + // The second list is empty or the elements are already in + // order - no need to merge + if (mid >= end || compare(src[mid - 1], src[mid]) <= 0) + { + memcpy(dest + start + srcDestDiff, src+start, (end-start)*sizeof(_type)); + }// The two halves just need swapping - no need to merge + else if (compare(src[start], src[end - 1]) > 0) + { + memcpy(dest+end-size+srcDestDiff, src+start, size * sizeof(_type)); + memcpy(dest+start+srcDestDiff, src+mid, (end-mid) * sizeof(_type)); + + }else{ + // Declare a lot of variables to save repeating + // calculations. Hopefully a decent JIT will put these + // in registers and make this fast + int32_t p1 = start; + int32_t p2 = mid; + int32_t i = start + srcDestDiff; + + // The main merge loop; terminates as soon as either + // half is ended + while (p1 < mid && p2 < end) + { + dest[i++] = src[(compare(src[p1], src[p2]) <= 0 + ? p1++ : p2++)]; + } + + // Finish up by copying the remainder of whichever half + // wasn't finished. + if (p1 < mid) + memcpy(dest+i,src+p1, (mid-p1) * sizeof(_type)); + else + memcpy(dest+i,src+p2, (end-p2) * sizeof(_type)); + } + } + // swap src and dest ready for the next merge + t = src; + src = dest; + dest = t; + fromIndex += srcDestDiff; + toIndex += srcDestDiff; + srcDestDiff = -srcDestDiff; + } + + // make sure the result ends up back in the right place. Note + // that src and dest may have been swapped above, so src + // contains the sorted array. + if (src != a) + { + // Note that fromIndex == 0. + memcpy(a+srcDestDiff,src,toIndex * sizeof(_type)); + } + } + }; + + template + class CLListEquals: + public CL_NS_STD(binary_function) + { + typedef typename class1::const_iterator _itr1; + typedef typename class2::const_iterator _itr2; + public: + CLListEquals(){ + } + bool equals( class1* val1, class2* val2 ) const{ + static _comparator comp; + if ( val1 == val2 ) + return true; + int32_t size = (int32_t)val1->size(); + if ( size != (int32_t)val2->size() ) + return false; + + _itr1 itr1 = val1->begin(); + _itr2 itr2 = val2->begin(); + while ( --size >= 0 ){ + if ( !comp(*itr1,*itr2) ) + return false; + itr1++; + itr2++; + } + return true; + } + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/util/_FastCharStream.h b/src/core/CLucene/util/_FastCharStream.h new file mode 100644 index 00000000000..ddb2b82aaf1 --- /dev/null +++ b/src/core/CLucene/util/_FastCharStream.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_FastCharStream_ +#define _lucene_util_FastCharStream_ + + +CL_CLASS_DEF(util,BufferedReader) + +CL_NS_DEF(util) + + /** Ported implementation of the FastCharStream class. */ + class FastCharStream + { + static const int32_t maxRewindSize; + int32_t pos; + int32_t rewindPos; + int64_t resetPos; + int32_t col; + int32_t line; + // read character from stream throws an exception on error + void readChar(TCHAR &); + public: + BufferedReader* input; + + /// Initializes a new instance of the FastCharStream class LUCENE_EXPORT. + FastCharStream(BufferedReader* reader); + virtual ~FastCharStream(); + + void reset(); + + /// Returns the next TCHAR from the stream. + int GetNext(); + + void UnGet(); + + /// Returns the current top TCHAR from the input stream without removing it. + int Peek(); + + + /// Returns True if the end of stream was reached. + bool Eos() const; + + /// Gets the current column. + int32_t Column() const; + + /// Gets the current line. + int32_t Line() const; + }; +CL_NS_END +#endif diff --git a/src/core/CLucene/util/_MD5Digester.h b/src/core/CLucene/util/_MD5Digester.h new file mode 100644 index 00000000000..aff913ac7c8 --- /dev/null +++ b/src/core/CLucene/util/_MD5Digester.h @@ -0,0 +1,110 @@ +///////////////////////////////////////////////////////////////////////// +// MD5.cpp +// Implementation file for MD5 class +// +// This C++ Class implementation of the original RSA Data Security, Inc. +// MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle. +// All rights reserved. This software is a derivative of the "RSA Data +// Security, Inc. MD5 Message-Digest Algorithm" +// +// You may use this software free of any charge, but without any +// warranty or implied warranty, provided that you follow the terms +// of the original RSA copyright, listed below. +// +// Original RSA Data Security, Inc. Copyright notice +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +// rights reserved. +// +// License to copy and use this software is granted provided that it +// is identified as the "RSA Data Security, Inc. MD5 Message-Digest +// Algorithm" in all material mentioning or referencing this software +// or this function. +// License is also granted to make and use derivative works provided +// that such works are identified as "derived from the RSA Data +// Security, Inc. MD5 Message-Digest Algorithm" in all material +// mentioning or referencing the derived work. +// RSA Data Security, Inc. makes no representations concerning either +// the merchantability of this software or the suitability of this +// software for any particular purpose. It is provided "as is" +// without express or implied warranty of any kind. +// These notices must be retained in any copies of any part of this +// documentation and/or software. +///////////////////////////////////////////////////////////////////////// + +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_util_MD5Digester_H +#define _lucene_util_MD5Digester_H + + +CL_NS_DEF(util) + +typedef unsigned short int uint2; + +char* PrintMD5(uint8_t md5Digest[16]); +char* MD5String(char* szString); +char* MD5File(char* szFilename); + +class md5 +{ +// Methods +public: + md5() { Init(); } + void Init(); + void Update(uint8_t* chInput, uint32_t nInputLen); + void Finalize(); + uint8_t* Digest() { return m_Digest; } + +private: + + void Transform(uint8_t* block); + void Encode(uint8_t* dest, uint32_t* src, uint32_t nLength); + void Decode(uint32_t* dest, uint8_t* src, uint32_t nLength); + + + inline uint32_t rotate_left(uint32_t x, uint32_t n) + { return ((x << n) | (x >> (32-n))); } + + inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) + { return ((x & y) | (~x & z)); } + + inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) + { return ((x & z) | (y & ~z)); } + + inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) + { return (x ^ y ^ z); } + + inline uint32_t I(uint32_t x, uint32_t y, uint32_t z) + { return (y ^ (x | ~z)); } + + inline void FF(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) + { a += F(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } + + inline void GG(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) + { a += G(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } + + inline void HH(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) + { a += H(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } + + inline void II(uint32_t& a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac) + { a += I(b, c, d) + x + ac; a = rotate_left(a, s); a += b; } + +// Data +private: + uint32_t m_State[4]; + uint32_t m_Count[2]; + uint8_t m_Buffer[64]; + uint8_t m_Digest[16]; + uint8_t m_Finalized; + +}; + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/_StringIntern.h b/src/core/CLucene/util/_StringIntern.h new file mode 100644 index 00000000000..6e4c66ca932 --- /dev/null +++ b/src/core/CLucene/util/_StringIntern.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_StringIntern_H +#define _lucene_util_StringIntern_H + +//#include "Equators.h" +//#include "_VoidMap.h" + +CL_NS_DEF(util) + /** Functions for intern'ing strings. This + * is a process of pooling strings thus using less memory, + * and furthermore allows intern'd strings to be directly + * compared: + * string1==string2, rather than _tcscmp(string1,string2) + */ + class CLStringIntern{ + public: + + /** + * Internalise the specified string. + * \return Returns a pointer to the internalised string + */ + static const char* internA(const char* str, const int8_t count=1, const bool use_provided=false); + + /** + * Uninternalise the specified string. Decreases + * the reference count and frees the string if + * reference count is zero + * \returns true if string was destroyed, otherwise false + */ + static bool uninternA(const char* str, const int8_t count=1); + + /** + * Internalise the specified string. + * \return Returns a pointer to the internalised string + */ + static const TCHAR* intern(const TCHAR* str); + + /** + * Uninternalise the specified string. Decreases + * the reference count and frees the string if + * reference count is zero + * \returns true if string was destroyed, otherwise false + */ + static bool unintern(const TCHAR* str); + + /** Cleanup static data */ + static CLUCENE_LOCAL void _shutdown(); + }; + +CL_NS_END +#endif diff --git a/src/core/CLucene/util/_ThreadLocal.h b/src/core/CLucene/util/_ThreadLocal.h new file mode 100644 index 00000000000..cd07757115c --- /dev/null +++ b/src/core/CLucene/util/_ThreadLocal.h @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_ThreadLocal_H +#define _lucene_util_ThreadLocal_H + +CL_NS_DEF ( util ) + + +/** +* A class which holds thread specific data. Calls to get() or set() or to the data kept in the _ThreadLocal +* is invalid after _ThreadLocal has been destroyed. +*/ +class _ThreadLocal +{ + private: + class Internal; + Internal* _internal; + public: + _ThreadLocal ( CL_NS ( util ) ::AbstractDeletor* _deletor ); + void* get(); + + /** + * Call this function to clear the local thread data for this + * ThreadLocal. Calling set(NULL) does the same thing, except + * this function is virtual and can be called without knowing + * the template. + */ + void setNull(); + void set ( void* t ); + virtual ~_ThreadLocal(); + + /** + * For early cleanup of thread data, call this function. It will clear out any + * thread specific data. Useful if you have a long running thread that doesn't + * need to access clucene anymore. + * The thread local code tries to call this automatically when a thread ends. + * Some implementations may be impossible (or not implemented) to detect thread + * endings... then you would have to run this function yourself. + */ + static void UnregisterCurrentThread(); + + static void RemoveThreadLocal( _ThreadLocal * tl ); + + + /** + * Call this function to shutdown CLucene + */ + static CLUCENE_LOCAL void _shutdown(); + + /** + * A hook called when CLucene is starting or shutting down, + * this can be used for setting up and tearing down static + * variables + */ + typedef void ShutdownHook ( bool startup ); +}; + + +/** +* A templated class of _ThreadLocal +* @see _ThreadLocal +*/ +template +class ThreadLocal: public _ThreadLocal +{ + public: + ThreadLocal() : + _ThreadLocal ( _CLNEW _deletor ) + { + + } + virtual ~ThreadLocal() + { + } + T get() + { + return ( T ) _ThreadLocal::get(); + } + void set ( T t ) + { + _ThreadLocal::set ( ( T ) t ); + } +}; +CL_NS_END +#endif diff --git a/src/core/CLucene/util/_VoidList.h b/src/core/CLucene/util/_VoidList.h new file mode 100644 index 00000000000..00db3739095 --- /dev/null +++ b/src/core/CLucene/util/_VoidList.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_VoidsList_ +#define _lucene_util_VoidsList_ + + /*#if defined(_LUCENE_PRAGMA_WARNINGS) + #pragma message ("==================Deprecated!!!==================") + #else + //#warning "==================Deprecated!!!==================" + #endif + + #include "VoidMapSetDefinitions.h"*/ + + #include "VoidList.h" +#endif diff --git a/src/core/CLucene/util/_VoidMap.h b/src/core/CLucene/util/_VoidMap.h new file mode 100644 index 00000000000..e3860b9f5da --- /dev/null +++ b/src/core/CLucene/util/_VoidMap.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_VoidsMap_ +#define _lucene_util_VoidsMap_ + + /*#if defined(_LUCENE_PRAGMA_WARNINGS) + #pragma message ("==================Deprecated!!!==================") + #else + //#warning "==================Deprecated!!!==================" + #endif + + #include "VoidMapSetDefinitions.h"*/ + + #include "VoidMap.h" +#endif diff --git a/src/core/CLucene/util/_bufferedstream.h b/src/core/CLucene/util/_bufferedstream.h new file mode 100644 index 00000000000..8cb82435ee7 --- /dev/null +++ b/src/core/CLucene/util/_bufferedstream.h @@ -0,0 +1,185 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef JSTREAMS_BUFFEREDSTREAM_H +#define JSTREAMS_BUFFEREDSTREAM_H + +#include "_streambase.h" +#include "_streambuffer.h" +#include + +CL_NS_DEF(util) + +/** + * @brief Abstract implementation class providing a buffered input stream. + * + * You can inherit this class to provide buffered access to a + * resource. You just need to implement fillBuffer, and + * BufferedStream will do the rest. + */ +template +class BufferedStreamImpl : public StreamBase { +private: + StreamBuffer buffer; + bool finishedWritingToBuffer; + + void writeToBuffer(int32_t minsize, int32_t maxsize); +protected: + /** + * @brief Fill the buffer with the provided data + * + * This function should be implemented by subclasses. + * It should write up to @p space characters from the + * stream to the buffer position pointed to by @p start. + * + * If the end of the stream is encountered, -1 should be + * returned. + * + * If an error occurs, the status should be set to Error, + * an error message should be set and -1 should be returned. + * + * You should @em not call this function yourself. + * + * @param start where the data should be written to + * @param space the maximum amount of data to write + * @return Number of characters written, or -1 on error + **/ + virtual int32_t fillBuffer(T* start, int32_t space) = 0; + /** + * @brief Resets the buffer, allowing it to be used again + * + * This function resets the buffer, allowing it to be re-used. + */ + void resetBuffer() { + StreamBase::m_size = -1; + StreamBase::m_position = 0; + StreamBase::m_error.assign(""); + StreamBase::m_status = Ok; + buffer.readPos = buffer.start; + buffer.avail = 0; + finishedWritingToBuffer = false; + } + /** + * @brief Sets the minimum size of the buffer + */ + void setMinBufSize(int32_t s) { + buffer.makeSpace(s); + } + BufferedStreamImpl(); +public: + int32_t read(const T*& start, int32_t min, int32_t max); + int64_t reset(int64_t pos); + virtual int64_t skip(int64_t ntoskip); +}; + + +/** Abstract class for a buffered stream of bytes */ +typedef BufferedStreamImpl BufferedInputStreamImpl; + +/** Abstract class for a buffered stream of Unicode characters */ +typedef BufferedStreamImpl BufferedReaderImpl; + + +template +BufferedStreamImpl::BufferedStreamImpl() { + finishedWritingToBuffer = false; +} + +template +void +BufferedStreamImpl::writeToBuffer(int32_t ntoread, int32_t maxread) { + int32_t missing = ntoread - buffer.avail; + int32_t nwritten = 0; + while (missing > 0 && nwritten >= 0) { + int32_t space; + space = buffer.makeSpace(missing); + if (maxread >= ntoread && space > maxread) { + space = maxread; + } + T* start = buffer.readPos + buffer.avail; + nwritten = fillBuffer(start, space); + assert(StreamBase::m_status != Eof); + if (nwritten > 0) { + buffer.avail += nwritten; + missing = ntoread - buffer.avail; + } + } + if (nwritten < 0) { + finishedWritingToBuffer = true; + } +} +template +int32_t +BufferedStreamImpl::read(const T*& start, int32_t min, int32_t max) { + if (StreamBase::m_status == Error) return -2; + if (StreamBase::m_status == Eof) return -1; + + // do we need to read data into the buffer? + if (min > max) max = 0; + if (!finishedWritingToBuffer && min > buffer.avail) { + // do we have enough space in the buffer? + writeToBuffer(min, max); + if (StreamBase::m_status == Error) return -2; + } + + int32_t nread = buffer.read(start, max); + + StreamBase::m_position += nread; + if (StreamBase::m_position > StreamBase::m_size + && StreamBase::m_size > 0) { + // error: we read more than was specified in size + // this is an error because all dependent code might have been labouring + // under a misapprehension + StreamBase::m_status = Error; + StreamBase::m_error = "Stream is longer than specified."; + nread = -2; + } else if (StreamBase::m_status == Ok && buffer.avail == 0 + && finishedWritingToBuffer) { + StreamBase::m_status = Eof; + if (StreamBase::m_size == -1) { + StreamBase::m_size = StreamBase::m_position; + } + // save one call to read() by already returning -1 if no data is there + if (nread == 0) nread = -1; + } + return nread; +} +template +int64_t +BufferedStreamImpl::reset(int64_t newpos) { + assert(newpos >= 0); + if (StreamBase::m_status == Error) return -2; + // check to see if we have this position + int64_t d = StreamBase::m_position - newpos; + if (buffer.readPos - d >= buffer.start && -d < buffer.avail) { + StreamBase::m_position -= d; + buffer.avail += (int32_t)d; + buffer.readPos -= d; + StreamBase::m_status = Ok; + } + return StreamBase::m_position; +} +template +int64_t +BufferedStreamImpl::skip(int64_t ntoskip) { + const T *begin; + int32_t nread; + int64_t skipped = 0; + while (ntoskip) { + int32_t step = (int32_t)((ntoskip > buffer.size) ?buffer.size :ntoskip); + nread = read(begin, 1, step); + if (nread <= 0) { + return skipped; + } + ntoskip -= nread; + skipped += nread; + } + return skipped; +} + +CL_NS_END + +#endif diff --git a/src/core/CLucene/util/_streambase.h b/src/core/CLucene/util/_streambase.h new file mode 100644 index 00000000000..fba1a734155 --- /dev/null +++ b/src/core/CLucene/util/_streambase.h @@ -0,0 +1,210 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef JSTREAMS_STREAMBASE_H +#define JSTREAMS_STREAMBASE_H + +#include +#include + +#define INT32MAX 0x7FFFFFFFL + +CL_NS_DEF(util) + +/** Used to indicate the current status of a Stream */ +enum StreamStatus { + Ok /**< Stream is capable of being read from */, + Eof /**< The end of the Stream has been reached */, + Error /**< An error occurred. Use error() to find out more information */ +}; + +// java mapping: long=int64, int=int32, byte=uint8_t +/** + * The base of all Streams. Do not inherit directly from this class, + * but from (an instance of) StreamBase + * + * This class contains all the non-virtual StreamBase methods + * that don't depend on a specific Stream type + * + * Developer comment: This is needed because of win32 compilation. + * When we want to access a function outside a lib, we have to export them, + * but we can't export the template class because this would be somewhat + * stupid / does not work by design :) + * Because of this I've introduced this StreamBaseBase class + */ +class StreamBaseBase { //krazy:exclude=dpointer +protected: + /** The size of the stream (-1 if unknown) */ + int64_t m_size; + /** The position of the stream */ + int64_t m_position; + /** + * @brief String representation of the last error, or + * an empty string otherwise + */ + std::string m_error; + /** The status of the stream - see StreamStatus */ + StreamStatus m_status; +public: + /** + * @brief Constructor: initialises everything to sane defaults + **/ + StreamBaseBase() :m_size(-1), m_position(0), m_status(Ok) {} + /** + * @brief Destructor + **/ + virtual ~StreamBaseBase() {} + /** + * @brief Return a string representation of the last error. + * If no error has occurred, an empty string is returned. + **/ + const char* error() const { return m_error.c_str(); } + /** + * @brief Return the status of the stream. + **/ + StreamStatus status() const { return m_status; } + /** + * @brief Get the current position in the stream. + * The value obtained from this function can be used to reset the stream. + **/ + int64_t position() const { return m_position; } + /** + * @brief Return the size of the stream. + * + * The size of the stream is always known if the end of the stream + * has been reached. In all other cases, this may return -1 to + * indicate the size of the stream is unknown. + * + * @return the size of the stream, if it is known, or -1 if the size + * of the stream is unknown + **/ + int64_t size() const { return m_size; } +}; + +/** + * @brief Base class for stream read access to a data source. + * + * This class is based on the interface java.io.InputStream. It provides + * a uniform interface for accessing streamed resources. + * + * The main difference with the Java equivalent is a performance improvement. + * When reading data, data is not copied into a buffer provided by the caller, + * but a pointer to the read data is provided. This makes this interface + * especially useful for deriving from it and implementing filters or + * transformers. + */ +template +class StreamBase : public StreamBaseBase { +public: + StreamBase() { } + virtual ~StreamBase(){} + /** + * @brief Reads items from the stream and sets @p start to point to + * the first item that was read. + * + * Note: unless stated otherwise in the documentation for that method, + * this pointer will no longer be valid after calling another method of + * this class. The pointer will also no longer be valid after the class + * is destroyed. + * + * The functions inherited from StreamBaseBase do not invalidate the pointer. + * + * At least @p min items will be read from the stream, unless an error occurs + * or the end of the stream is reached. Under no circumstances will more than + * @p max items be read. + * + * If the end of the stream is reached before @p min items are read, the + * read is still considered successful and the number of items read will + * be returned. + * + * @param start pointer passed by reference that will be set to point to + * the retrieved array of items. If the end of the stream + * is encountered or an error occurs, the value of @p start + * is undefined + * @param min the minimal number of items to read from the stream. This + * value should be larger than 0. If it is 0 or smaller, the + * result is undefined + * @param max the maximal number of items to read from the stream. + * If this value is smaller than @p min, there is no limit on + * the number of items that can be read + * @return the number of items that were read. @c -1 is returned if + * end of the stream has already been reached. @c -2 is returned + * if an error has occurred + **/ + virtual int32_t read(const T*& start, int32_t min, int32_t max) = 0; + /** + * @brief Skip @p ntoskip items. + * + * If an error occurs, or the end of the stream is encountered, fewer + * than @p ntoskip items may be skipped. This can be checked by comparing + * the return value to @p ntoskip. + * + * Calling this function invalidates the data pointer that was obtained from + * StreamBase::read. + * + * @param ntoskip the number of items that should be skipped + * @return the number of items skipped + **/ + virtual int64_t skip(int64_t ntoskip); + /** + * @brief Repositions this stream to a given position. + * + * A call to StreamBase::reset is only guaranteed to be successful when + * the requested position lies within the segment of a stream + * corresponding to a valid pointer obtained from StreamBase::read. + * In this case, the pointer will not be invalidated. + * + * Calling this function invalidates the data pointer that was obtained from + * StreamBase::read unless the conditions outlined above apply. + * + * To read n items, leaving the stream at the same position as before, you + * can do the following: + * @code + * int64_t start = stream.position(); + * if ( stream.read(data, min, max) > 0 ) { + * stream.reset(start); + * // The data pointer is still valid here + * } + * @endcode + * + * @param pos the position in the stream you want to go to, relative to + * the start of the stream + * @return the new position in the stream + **/ + virtual int64_t reset(int64_t pos) = 0; +}; + + +template +int64_t +StreamBase::skip(int64_t ntoskip) { + const T* begin; + int32_t nread; + int64_t skipped = 0; + while (ntoskip > 0) { + // make sure we do not overflow uint32_t + int32_t maxstep = (int32_t)((ntoskip > 10000000) + ?10000000 :ntoskip); + // the default implementation is to simply read the data that we want + // to skip + nread = read(begin, 1, maxstep); + if (nread < -1 ) { + // an error occurred + return nread; + } else if (nread < 1) { + // the end of the stream was encountered + ntoskip = 0; + } else { + skipped += nread; + ntoskip -= nread; + } + } + return skipped; +} + +CL_NS_END + +#endif diff --git a/src/core/CLucene/util/_streambuffer.h b/src/core/CLucene/util/_streambuffer.h new file mode 100644 index 00000000000..3967cc300ca --- /dev/null +++ b/src/core/CLucene/util/_streambuffer.h @@ -0,0 +1,167 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jos van den Oever +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef JSTREAM_STREAMBUFFER_H +#define JSTREAM_STREAMBUFFER_H + +#include +#include + +CL_NS_DEF(util) + +/** + * @internal + * @brief Provides a buffer for the use of BufferedStream + */ +template +class StreamBuffer { +private: +public: + /** + * @internal + * @brief Pointer to the start of the buffer. + */ + T* start; + /** + * @internal + * @brief Size of the buffer. + * + * Size of the memory pointed to by @p start, + * in multiples of sizeof(T) + */ + int32_t size; + /** + * @internal + * @brief Pointer to the current position the buffer. + */ + T* readPos; + /** + * @internal + * @brief The amount of data available in the buffer. + * + * The size of the used memory in the buffer, starting + * from @p readPos. @p readPos + @p avail must be + * greater than @p start + @p size. + */ + int32_t avail; + + /** + * @internal + * @brief Constructor: initialises members to sane defaults. + */ + StreamBuffer(); + /** + * @internal + * @brief Destructor: frees the memory used by the buffer. + */ + ~StreamBuffer(); + /** + * @internal + * @brief Sets the size of the buffer, allocating the necessary memory + * + * @param size the size that the buffer should be, in multiples + * of sizeof(T) + */ + void setSize(int32_t size); + /** + * @internal + * @brief Read data from the buffer + * + * Sets @p start to point to the data, starting + * at the item of data following the last item + * of data read. + * + * @param start pointer passed by reference. It will + * be set to point to the data read from the buffer + * @param max the maximum amount of data to read from + * the buffer + * @return the size of the data pointed to by @p start + * (always less than or equal to @p max) + */ + int32_t read(const T*& start, int32_t max=0); + + /** + * @internal + * @brief Prepares the buffer for a new write. + * + * This function invalidates any pointers + * previously obtained from read. + * + * @return the number of available places + **/ + int32_t makeSpace(int32_t needed); +}; + +template +StreamBuffer::StreamBuffer() { + readPos = start = 0; + size = avail = 0; +} +template +StreamBuffer::~StreamBuffer() { + std::free(start); +} +template +void +StreamBuffer::setSize(int32_t size) { + // store pointer information + int32_t offset = readPos - start; + + // allocate memory in the buffer + start = (T*)std::realloc(start, size*sizeof(T)); + this->size = size; + + // restore pointer information + readPos = start + offset; +} +template +int32_t +StreamBuffer::makeSpace(int32_t needed) { + // determine how much space is available for writing + int32_t space = size - (readPos - start) - avail; + if (space >= needed) { + // there's enough space + return space; + } + + if (avail) { + if (readPos != start) { +// printf("moving\n"); + // move data to the start of the buffer + std::memmove(start, readPos, avail*sizeof(T)); + space += readPos - start; + readPos = start; + } + } else { + // we may start writing at the start of the buffer + readPos = start; + space = size; + } + if (space >= needed) { + // there's enough space now + return space; + } + + // still not enough space, we have to allocate more +// printf("resize %i %i %i %i %i\n", avail, needed, space, size + needed - space, size); + setSize(size + needed - space); + return needed; +} +template +int32_t +StreamBuffer::read(const T*& start, int32_t max) { + start = readPos; + if (max <= 0 || max > avail) { + max = avail; + } + readPos += max; + avail -= max; + return max; +} + +CL_NS_END + +#endif diff --git a/src/core/CLucene/util/bkd/bkd_docid_iterator.h b/src/core/CLucene/util/bkd/bkd_docid_iterator.h new file mode 100644 index 00000000000..c3dcd673233 --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_docid_iterator.h @@ -0,0 +1,112 @@ +#pragma once + +#include "CLucene/StdHeader.h" +#include "CLucene/util/croaring/roaring.hh" + +#include +#include +#include + +CL_NS_DEF2(util, bkd) + +class bkd_docID_set{ +public: + static const int NO_MORE_DOCS = std::numeric_limits::max(); + + explicit bkd_docID_set(int32_t size) { + docIDs.resize(size); + } + int32_t length() const { + return _length; + } + int32_t nextDoc() { + if (_idx == _length) { + _docID = NO_MORE_DOCS; + } else { + _docID = docIDs[_offset + _idx]; + _idx++; + } + return _docID; + } + void reset(int offset, int length) { + _offset = offset; + _length = length; + assert(offset + length <= docIDs.size()); + _docID = -1; + _idx = 0; + } + std::vector docIDs; + +private: + int32_t _idx{}; + int32_t _length{}; + int32_t _offset{}; + int32_t _docID{}; +}; + +class bkd_docID_bitmap_set{ +public: + explicit bkd_docID_bitmap_set(int32_t size) { + //docIDs.resize(size); + } + ~bkd_docID_bitmap_set() = default; + void add(std::vector&& r, int pos) { + docIDs[pos] = r; + _offset++; + } + void add(std::vector&& r) { + docIDs.emplace_back(r); + _offset++; + } + void add(std::vector& r) { + docIDs.emplace_back(std::move(r)); + _offset++; + } + int32_t length() const { + return _length; + } + std::vector& nextDoc() { + if (_idx == _length) { + _docID = std::vector(0); + } else { + _docID = docIDs[_offset + _idx]; + _idx++; + } + return _docID; + } + + void reset(int length) { + _length = length; + assert(_offset + length <= docIDs.size()); + _docID = std::vector(0); + _idx = 0; + } + + void reset(int offset, int length) { + _offset = offset; + _length = length; + assert(offset + length <= docIDs.size()); + _docID = std::vector(0); + _idx = 0; + } + std::vector> docIDs; + +private: + int32_t _idx{}; + int32_t _length{}; + int32_t _offset{}; + std::vector _docID{}; +}; + +class bkd_docID_set_iterator { +public: + explicit bkd_docID_set_iterator(int32_t size) { + bitmap_set = std::make_unique(size); + docID_set = std::make_unique(size); + } + std::unique_ptr bitmap_set; + std::unique_ptr docID_set; + bool is_bitmap_set; +}; + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.cpp b/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.cpp new file mode 100644 index 00000000000..e3ba3758233 --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.cpp @@ -0,0 +1,119 @@ +#include "bkd_msb_radix_sorter.h" + +#include + +CL_NS_DEF2(util, bkd) +bkd_msb_radix_sorter::bkd_msb_radix_sorter( + //std::shared_ptr&& writer, + bkd_writer * writer, + //std::shared_ptr& heapWriter, + heap_point_writer * heapWriter, + int dim, int32_t bytes) : MSBRadixSorter(bytes), dim(dim), writer(writer), heapWriter(heapWriter) { +} + +int bkd_msb_radix_sorter::byteAt(int i, int k) { + assert(k >= 0); + if (k < writer->bytes_per_dim_) { + // dim bytes + int block = i / heapWriter->values_per_block_; + int index = i % heapWriter->values_per_block_; + return heapWriter->blocks_[block][index * writer->packed_bytes_length_ + + dim * writer->bytes_per_dim_ + k] & + 0xff; + } else { + // doc id + int s = 3 - (k - writer->bytes_per_dim_); + return (static_cast(static_cast(heapWriter->doc_IDs_[i]) >> + (s * 8))) & + 0xff; + } + if (k < writer->bytes_per_dim_) { + int32_t block = i / heapWriter->values_per_block_; + int32_t index = i % heapWriter->values_per_block_; + return heapWriter->blocks_[block][index * writer->packed_bytes_length_ + dim * writer->bytes_per_dim_ + k] & 0xff; + } else { + //TODO:try to figure out what is doing here. + int32_t s = 3 - (k - writer->bytes_per_dim_); + //return (MiscUtils::UnsignedShift(writer->doc_IDs_[i], s * 8)) & 0xff; + return (static_cast(static_cast(heapWriter->doc_IDs_[i]) >> (s * 8))) & 0xff; + } +} + +void bkd_msb_radix_sorter::swap(int i, int j) { + int32_t doc_id = heapWriter->doc_IDs_[i]; + heapWriter->doc_IDs_[i] = heapWriter->doc_IDs_[j]; + heapWriter->doc_IDs_[j] = doc_id; + + if (!writer->single_value_per_doc_) { + if (writer->long_ords_) { + int64_t ord = heapWriter->ords_long_[j]; + heapWriter->ords_long_[i] = heapWriter->ords_long_[j]; + heapWriter->ords_long_[j] = ord; + } else { + int32_t ord = heapWriter->ords_[i]; + heapWriter->ords_[i] = heapWriter->ords_[j]; + heapWriter->ords_[j] = ord; + } + } + + //shared_ptr>& blockI = heapWriter->blocks_[i / heapWriter->values_per_block_]; + int indexI = (i % heapWriter->values_per_block_) * writer->packed_bytes_length_; + //shared_ptr>& blockJ = heapWriter->blocks_[j / heapWriter->values_per_block_]; + int indexJ = (j % heapWriter->values_per_block_) * writer->packed_bytes_length_; + + if (writer->packed_bytes_length_ == 4) { + auto *value1 = reinterpret_cast(heapWriter->blocks_[i / heapWriter->values_per_block_].data() + indexI); + auto *value2 = reinterpret_cast(heapWriter->blocks_[j / heapWriter->values_per_block_].data() + indexJ); + uint32_t tmp = *value1; + *value1 = *value2; + *value2 = tmp; + } else { + // scratch1 = values[i] + auto& blockI = heapWriter->blocks_[i / heapWriter->values_per_block_]; + auto& blockJ = heapWriter->blocks_[j / heapWriter->values_per_block_]; + std::copy(blockI.begin() + indexI, + blockI.begin() + indexI + writer->packed_bytes_length_, + writer->scratch1_.begin()); + // values[i] = values[j] + std::copy(blockJ.begin() + indexJ, + blockJ.begin() + indexJ + writer->packed_bytes_length_, + blockI.begin() + indexI); + // values[j] = scratch1 + std::copy(writer->scratch1_.begin(), + writer->scratch1_.begin() + writer->packed_bytes_length_, + blockJ.begin() + indexJ); + } + + /*int32_t doc_id = heapWriter->doc_IDs_[i]; + heapWriter->doc_IDs_[i] = heapWriter->doc_IDs_[j]; + heapWriter->doc_IDs_[j] = doc_id; + if (!writer->single_value_per_doc_) { + if (writer->long_ords_) { + int64_t ord = heapWriter->ords_long_.at(j); + heapWriter->ords_long_.at(i) = heapWriter->ords_long_.at(j); + heapWriter->ords_long_.at(j) = ord; + } else { + int32_t ord = heapWriter->ords_.at(i); + heapWriter->ords_.at(i) = heapWriter->ords_.at(j); + heapWriter->ords_.at(j) = ord; + } + } + std::vector &block_i = heapWriter->blocks_.at(i / heapWriter->values_per_block_); + int32_t index_i = (i % heapWriter->values_per_block_) * writer->packed_bytes_length_; + std::vector &block_j = heapWriter->blocks_.at(j / heapWriter->values_per_block_); + int32_t index_j = (j % heapWriter->values_per_block_) * writer->packed_bytes_length_; + //scratch1 = values[i] + std::copy(block_i.begin() + index_i, + block_i.begin() + index_i + writer->packed_bytes_length_, + writer->scratch1_->begin()); + // values[i] = values[j] + std::copy(block_j.begin() + index_j, + block_j.begin() + index_j + writer->packed_bytes_length_, + block_i.begin() + index_i); + // values[j] = scratch1 + std::copy(writer->scratch1_->begin(), + writer->scratch1_->begin() + writer->packed_bytes_length_, + block_j.begin() + index_j);*/ +} + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.h b/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.h new file mode 100644 index 00000000000..eee15e745d1 --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_msb_radix_sorter.h @@ -0,0 +1,37 @@ +#pragma once + +#include "CLucene/SharedHeader.h" +#include "CLucene/util/MSBRadixSorter.h" +#include "bkd_writer.h" +#include "heap_point_writer.h" + +#include + +CL_NS_DEF2(util,bkd) + +class bkd_msb_radix_sorter : public MSBRadixSorter +{ +private: + bkd_writer * writer; + heap_point_writer * heapWriter; + //std::shared_ptr writer; + //std::shared_ptr heapWriter; + int dim = 0; + +public: + bkd_msb_radix_sorter( + //std::shared_ptr&& writer, + bkd_writer * writer, + //std::shared_ptr& heapWriter, + heap_point_writer * heapWriter, + int dim, int32_t bytes); + +protected: + int byteAt(int i, int k) override; + void swap(int i, int j) override; +protected: + /*std::shared_ptr shared_from_this() { + return std::static_pointer_cast(MSBRadixSorter::shared_from_this()); + }*/ +}; +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/bkd_reader.cpp b/src/core/CLucene/util/bkd/bkd_reader.cpp new file mode 100644 index 00000000000..a37f9ee60be --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_reader.cpp @@ -0,0 +1,588 @@ +#include "CLucene/_ApiHeader.h" + +#include "CLucene/util/CodecUtil.h" +#include "CLucene/util/FutureArrays.h" +#include "CLucene/util/Time.h" +#include "bkd_reader.h" +#include "bkd_writer.h" +#include "docIds_writer.h" +#include "legacy_index_tree.h" +#include "packed_index_tree.h" + +#include + +CL_NS_DEF2(util, bkd) + +bkd_reader::bkd_reader(store::IndexInput *in) { + in_ = std::unique_ptr(in); +} + +int bkd_reader::read_meta(store::IndexInput* meta_in) { + // Meta is written in the tail of index file. + //in_->seek(in_->length() - sizeof(int32_t) - sizeof(int64_t)); + type = meta_in->readInt(); + indexFP = meta_in->readLong(); + // NOTE:if indexFP is 0, it means index file is empty. + if (0 == indexFP) { + return 0; + } else { + return 1; + } +} + +void bkd_reader::read_index(store::IndexInput* index_in) { + //in_->seek(indexFP); + version_ = CodecUtil::checkHeader(index_in, + bkd_writer::CODEC_NAME, + bkd_writer::VERSION_START, + bkd_writer::VERSION_CURRENT); + num_data_dims_ = index_in->readVInt(); + if (version_ >= bkd_writer::VERSION_SELECTIVE_INDEXING) { + num_index_dims_ = index_in->readVInt(); + } else { + num_index_dims_ = num_data_dims_; + } + max_points_in_leaf_node_ = index_in->readVInt(); + bytes_per_dim_ = index_in->readVInt(); + bytes_per_index_entry_ = (num_data_dims_ == 1) && version_ >= bkd_writer::VERSION_IMPLICIT_SPLIT_DIM_1D ? bytes_per_dim_ : bytes_per_dim_ + 1; + packed_bytes_length_ = num_data_dims_ * bytes_per_dim_; + packed_index_bytes_length_ = num_index_dims_ * bytes_per_dim_; + + // Read index: + num_leaves_ = index_in->readVInt(); + assert(num_leaves_ > 0); + leaf_node_offset_ = num_leaves_; + + min_packed_value_ = std::vector(packed_index_bytes_length_); + max_packed_value_ = std::vector(packed_index_bytes_length_); + + index_in->readBytes(min_packed_value_.data(), packed_index_bytes_length_); + index_in->readBytes(max_packed_value_.data(), packed_index_bytes_length_); + + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + if (FutureArrays::CompareUnsigned(min_packed_value_, dim * bytes_per_dim_, + dim * bytes_per_dim_ + bytes_per_dim_, + max_packed_value_, + dim * bytes_per_dim_, + dim * bytes_per_dim_ + bytes_per_dim_) > 0) { + _CLTHROWA(CL_ERR_CorruptIndex, ("minPackedValue > maxPackedValue for dim=" + std::to_string(dim)).c_str()); + } + } + + point_count_ = index_in->readVLong(); + + doc_count_ = index_in->readVInt(); + + if (version_ >= bkd_writer::VERSION_PACKED_INDEX) { + int32_t numBytes = index_in->readVInt(); + metaOffset = index_in->getFilePointer(); + + clone_index_input = std::shared_ptr(index_in->clone()); + packed_index_ = std::make_shared>(numBytes); + index_in->readBytes(packed_index_->data(), numBytes); + /*printf("read packed index start\n"); + for(auto i = packed_index_->begin();i != packed_index_->end();i++) { + printf("%0x ",*i); + } + printf("\nread packed index stop\n");*/ + leaf_block_fps_.clear(); + split_packed_values_.clear(); + } else { + split_packed_values_ = std::vector(bytes_per_index_entry_ * num_leaves_); + + index_in->readBytes(split_packed_values_.data(), split_packed_values_.size()); + + std::vector leafBlockFPs(num_leaves_); + int64_t lastFP = 0; + for (int32_t i = 0; i < num_leaves_; i++) { + int64_t delta = index_in->readVLong(); + leafBlockFPs[i] = lastFP + delta; + lastFP += delta; + } + + if (num_data_dims_ == 1 && num_leaves_ > 1) { + int32_t levelCount = 2; + while (true) { + if (num_leaves_ >= levelCount && num_leaves_ <= 2 * levelCount) { + int32_t lastLevel = 2 * (num_leaves_ - levelCount); + assert(lastLevel >= 0); + if (lastLevel != 0) { + std::vector newLeafBlockFPs(num_leaves_); + std::copy(leafBlockFPs.begin() + lastLevel, + leafBlockFPs.begin() + lastLevel + (leafBlockFPs.size() - lastLevel), + newLeafBlockFPs.begin()); + std::copy(leafBlockFPs.begin(), + leafBlockFPs.begin() + lastLevel, + newLeafBlockFPs.begin() + (leafBlockFPs.size() - lastLevel)); + leafBlockFPs = newLeafBlockFPs; + } + break; + } + + levelCount *= 2; + } + } + + leaf_block_fps_ = leafBlockFPs; + packed_index_->clear(); + } +} + +bkd_reader::intersect_state::intersect_state(store::IndexInput *in, + int32_t numDims, + int32_t packedBytesLength, + int32_t packedIndexBytesLength, + int32_t maxPointsInLeafNode, + bkd_reader::intersect_visitor *visitor, + const std::shared_ptr &indexVisitor) { + in_ = std::shared_ptr(in); + visitor_ = visitor; + common_prefix_lengths_ = std::vector(numDims); + docID_set_iterator = std::make_unique(maxPointsInLeafNode); + scratch_doc_ids_ = std::vector(maxPointsInLeafNode); + scratch_data_packed_value_ = std::vector(packedBytesLength); + scratch_min_index_packed_value_ = std::vector(packedIndexBytesLength); + scratch_max_index_packed_value_ = std::vector(packedIndexBytesLength); + index_ = indexVisitor; +} + +std::shared_ptr bkd_reader::get_intersect_state(bkd_reader::intersect_visitor *visitor) { + // because we will reuse BKDReader, we need to seek to packed tree index offset every time. + clone_index_input->seek(metaOffset); + std::shared_ptr index; + if (!packed_index_->empty()) { + index = std::make_shared(shared_from_this()); + } else { + index = std::make_shared(shared_from_this()); + } + return std::make_shared(in_->clone(), + num_data_dims_, + packed_bytes_length_, + packed_index_bytes_length_, + max_points_in_leaf_node_, + visitor, + index); +} + +void bkd_reader::intersect(bkd_reader::intersect_visitor *visitor) + +{ + intersect(get_intersect_state(visitor), min_packed_value_, max_packed_value_); +} + +int64_t bkd_reader::estimate_point_count(bkd_reader::intersect_visitor *visitor) { + return estimate_point_count(get_intersect_state(visitor), min_packed_value_, max_packed_value_); +} + +int64_t bkd_reader::estimate_point_count(const std::shared_ptr &s, std::vector &cellMinPacked, std::vector &cellMaxPacked) +{ + relation r = s->visitor_->compare(cellMinPacked, cellMaxPacked); + + if (r == relation::CELL_OUTSIDE_QUERY) { + // This cell is fully outside of the query shape: stop recursing + return 0LL; + } else if (r == relation::CELL_INSIDE_QUERY) { + return static_cast(max_points_in_leaf_node_) * s->index_->get_num_leaves(); + } else if (s->index_->is_leaf_node()) { + // Assume half the points matched + return (max_points_in_leaf_node_ + 1) / 2; + } else { + int32_t splitDim = s->index_->get_split_dim(); + assert(splitDim >= 0); + assert(splitDim < num_index_dims_); + + std::vector &splitPackedValue = s->index_->get_split_packed_value(); + std::shared_ptr splitDimValue = s->index_->get_split_dim_value(); + assert(splitDimValue->length == bytes_per_dim_); + assert(FutureArrays::CompareUnsigned(cellMinPacked, + splitDim * bytes_per_dim_, + splitDim * bytes_per_dim_ + bytes_per_dim_, + (splitDimValue->bytes), + splitDimValue->offset, + splitDimValue->offset + bytes_per_dim_) <= 0); + assert(FutureArrays::CompareUnsigned(cellMaxPacked, + splitDim * bytes_per_dim_, + splitDim * bytes_per_dim_ + bytes_per_dim_, + (splitDimValue->bytes), + splitDimValue->offset, + splitDimValue->offset + bytes_per_dim_) >= 0); + + std::copy(cellMaxPacked.begin(), + cellMaxPacked.begin() + packed_index_bytes_length_, + splitPackedValue.begin()); + std::copy(splitDimValue->bytes.begin() + splitDimValue->offset, + splitDimValue->bytes.begin() + splitDimValue->offset + bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_); + s->index_->push_left(); + int64_t leftCost = + estimate_point_count(s, cellMinPacked, splitPackedValue); + s->index_->pop(); + + std::copy(splitPackedValue.begin() + splitDim * bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_ + bytes_per_dim_, + splitDimValue->bytes.begin() + splitDimValue->offset); + + std::copy(cellMinPacked.begin(), + cellMinPacked.begin() + packed_index_bytes_length_, + splitPackedValue.begin()); + std::copy(splitDimValue->bytes.begin() + splitDimValue->offset, + splitDimValue->bytes.begin() + splitDimValue->offset + bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_); + s->index_->push_right(); + int64_t rightCost = + estimate_point_count(s, splitPackedValue, cellMaxPacked); + s->index_->pop(); + return leftCost + rightCost; + } +} + +void bkd_reader::visit_doc_ids(store::IndexInput *in, int64_t blockFP, bkd_reader::intersect_visitor *visitor) const { + in->seek(blockFP); + + int32_t count = in->readVInt(); + // avoid read_ints + if (visitor->only_hits()) { + visitor->inc_hits(count); + return; + } + if (version_ < bkd_writer::VERSION_COMPRESSED_DOC_IDS) { + docIds_writer::read_ints32(in, count, visitor); + } else { + docIds_writer::read_ints(in, count, visitor); + } +} + +void bkd_reader::add_all(const std::shared_ptr &state, bool grown) { + if (!grown) { + int64_t maxPointCount = static_cast(max_points_in_leaf_node_) * state->index_->get_num_leaves(); + if (maxPointCount <= std::numeric_limits::max()) { + state->visitor_->grow(static_cast(maxPointCount)); + grown = true; + } + } + + if (state->index_->is_leaf_node()) { + assert(grown); + if (state->index_->node_exists()) { + auto start = UnixMillis(); + visit_doc_ids(state->in_.get(), state->index_->get_leaf_blockFP(), state->visitor_); + stats.add_doc_id_visit_time_duration(UnixMillis() - start); + } + } else { + state->index_->push_left(); + add_all(state, grown); + state->index_->pop(); + + state->index_->push_right(); + add_all(state, grown); + state->index_->pop(); + } +} + +int32_t bkd_reader::read_doc_ids(store::IndexInput *in, int64_t blockFP, bkd_docID_set_iterator *iter) const { + in->seek(blockFP); + + int32_t count = in->readVInt(); + //docIds_writer::read_bitmap_ints(in, count, docIDs); + + if (version_ < bkd_writer::VERSION_COMPRESSED_DOC_IDS) { + iter->docID_set->reset(0, count); + docIds_writer::read_ints32(in, count, iter->docID_set->docIDs); + } else { + docIds_writer::read_ints(in, count, iter); + } + + return count; +} + +void bkd_reader::read_common_prefixes(std::vector &commonPrefixLengths, std::vector &scratchPackedValue, store::IndexInput *in) const { + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + int32_t prefix = in->readVInt(); + commonPrefixLengths[dim] = prefix; + if (prefix > 0) { + in->readBytes(scratchPackedValue.data(), prefix, dim * bytes_per_dim_); + } + } +} + +void bkd_reader::read_min_max(const std::vector &commonPrefixLengths, + std::vector &minPackedValue, + std::vector &maxPackedValue, + store::IndexInput *in) const { + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + int32_t prefix = commonPrefixLengths[dim]; + in->readBytes(minPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + in->readBytes(maxPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + } +} + +void bkd_reader::visit_compressed_doc_values(std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor, + int32_t compressedDim) const { + int32_t compressedByteOffset = compressedDim * bytes_per_dim_ + commonPrefixLengths[compressedDim]; + commonPrefixLengths[compressedDim]++; + int32_t i; + for (i = 0; i < count;) { + scratchPackedValue[compressedByteOffset] = in->readByte(); + int32_t runLen = static_cast(in->readByte()) & 0xFF; + for (int32_t j = 0; j < runLen; ++j) { + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + int32_t prefix = commonPrefixLengths[dim]; + in->readBytes(scratchPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + } + visitor->visit(iter->docID_set->docIDs[i + j], scratchPackedValue); + } + i += runLen; + } + if (i != count) { + _CLTHROWA(CL_ERR_CorruptIndex, ("Sub blocks do not add up to the expected count: " + std::to_string(count) + " != " + std::to_string(i)).c_str()); + } +} + +int32_t bkd_reader::read_compressed_dim(store::IndexInput *in) const { + auto compressedDim = static_cast(in->readByte()); + auto compressed_dim = static_cast((compressedDim)); + if (compressed_dim < -2 || compressed_dim >= num_data_dims_) { + _CLTHROWA(CL_ERR_CorruptIndex, ("Got compressedDim=" + std::to_string(compressed_dim)).c_str()); + } + return compressed_dim; +} + +void bkd_reader::visit_unique_raw_doc_values(std::vector &scratchPackedValue, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const { + //iter->docIDs_bitmap = std::move(iter->docIDs_bitmap_vector[0]); + auto bitmap = iter->bitmap_set->nextDoc(); + while(!bitmap.empty()) { + visitor->visit(bitmap, scratchPackedValue); + bitmap = iter->bitmap_set->nextDoc(); + } + //visitor->visit(iter, scratchPackedValue); +} + +void bkd_reader::visit_sparse_raw_doc_values(const std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const { + int i = 0; + int cardinality = 0; + if (iter->is_bitmap_set) { + for (i = 0; i < count;) { + int length = in->readVInt(); + for (int dim = 0; dim < num_data_dims_; dim++) { + int prefix = commonPrefixLengths[dim]; + in->readBytes(scratchPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + } + auto bitmap = iter->bitmap_set->nextDoc(); + if (!bitmap.empty()) { + visitor->visit(bitmap, scratchPackedValue); + //bitmap = iter->bitmap_set->nextDoc(); + } + i += length; + cardinality++; + } + } else { + if (!iter->docID_set->docIDs.empty()) { + for (i = 0; i < count;) { + int length = in->readVInt(); + for (int dim = 0; dim < num_data_dims_; dim++) { + int prefix = commonPrefixLengths[dim]; + in->readBytes(scratchPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + } + iter->docID_set->reset(i, length); + visitor->visit(iter, scratchPackedValue); + i += length; + cardinality++; + } + } + } + if (i != count) { + _CLTHROWA(CL_ERR_CorruptIndex, "Sub blocks do not add up to the expected count"); + } +} + +void bkd_reader::visit_raw_doc_values(const std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const { + for (int32_t i = 0; i < count; ++i) { + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + int32_t prefix = commonPrefixLengths[dim]; + in->readBytes(scratchPackedValue.data(), bytes_per_dim_ - prefix, dim * bytes_per_dim_ + prefix); + } + visitor->visit(iter->docID_set->docIDs[i], scratchPackedValue); + } +} + +void bkd_reader::visit_doc_values(std::vector &commonPrefixLengths, + std::vector &scratchDataPackedValue, + const std::vector &scratchMinIndexPackedValue, + const std::vector &scratchMaxIndexPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) { + auto start = UnixMillis(); + read_common_prefixes(commonPrefixLengths, scratchDataPackedValue, in); + + if (num_index_dims_ != 1 && version_ >= bkd_writer::VERSION_LEAF_STORES_BOUNDS) { + std::vector minPackedValue = scratchMinIndexPackedValue; + std::copy(scratchDataPackedValue.begin(), + scratchDataPackedValue.begin() + packed_index_bytes_length_, + minPackedValue.begin()); + + std::vector maxPackedValue = scratchMaxIndexPackedValue; + std::copy(minPackedValue.begin(), + minPackedValue.begin() + packed_index_bytes_length_, + maxPackedValue.begin()); + + read_min_max(commonPrefixLengths, minPackedValue, maxPackedValue, in); + + auto start_time = UnixMillis(); + relation r = visitor->compare(minPackedValue, maxPackedValue); + stats.add_visit_compare_time_duration(UnixMillis() - start_time); + if (r == relation::CELL_OUTSIDE_QUERY) { + return; + } + visitor->grow(count); + + if (r == relation::CELL_INSIDE_QUERY) { + for (int32_t i = 0; i < count; ++i) { + visitor->visit(iter->docID_set->docIDs[i]); + } + return; + } + } else { + visitor->grow(count); + } + + int32_t compressedDim = version_ < bkd_writer::VERSION_COMPRESSED_VALUES ? -1 : read_compressed_dim(in); + + //auto start = UnixMillis(); + if (compressedDim == -1) { + assert(iter->bitmap_set!= nullptr); + assert(iter->bitmap_set->docIDs.size() == 1); + auto uniq_start = UnixMillis(); + visit_unique_raw_doc_values(scratchDataPackedValue, iter, count, visitor); + stats.add_uniq_doc_value_visit_time_duration(UnixMillis() - uniq_start); + } else { + if (compressedDim == -2) { + auto sparse_start = UnixMillis(); + // low cardinality values + visit_sparse_raw_doc_values(commonPrefixLengths, + scratchDataPackedValue, + in, + iter, + count, + visitor); + stats.add_sparse_doc_value_visit_time_duration(UnixMillis() - sparse_start); + } else { + // high cardinality + auto compress_start = UnixMillis(); + visit_compressed_doc_values(commonPrefixLengths, + scratchDataPackedValue, + in, + iter, + count, + visitor, + compressedDim); + stats.add_compress_doc_value_visit_time_duration(UnixMillis() - compress_start); + } + } + stats.add_doc_value_visit_time_duration(UnixMillis() - start); +} + +void bkd_reader::intersect(const std::shared_ptr &s, std::vector &cellMinPacked, std::vector &cellMaxPacked) { + auto start_time = UnixMillis(); + relation r = s->visitor_->compare(cellMinPacked, cellMaxPacked); + stats.add_visit_compare_time_duration(UnixMillis() - start_time); + + if (r == relation::CELL_OUTSIDE_QUERY) { + } else if (r == relation::CELL_INSIDE_QUERY) { + add_all(s, false); + } else if (s->index_->is_leaf_node()) { + if (s->index_->node_exists()) { + auto start = UnixMillis(); + int32_t count = read_doc_ids(s->in_.get(), s->index_->get_leaf_blockFP(), s->docID_set_iterator.get()); + stats.add_read_doc_id_time_duration(UnixMillis() - start); + + visit_doc_values(s->common_prefix_lengths_, + s->scratch_data_packed_value_, + s->scratch_min_index_packed_value_, + s->scratch_max_index_packed_value_, + s->in_.get(), + s->docID_set_iterator.get(), + count, + s->visitor_); + } + } else { + int32_t splitDim = s->index_->get_split_dim(); + assert(splitDim >= 0); + assert(splitDim < num_index_dims_); + + std::vector &splitPackedValue = s->index_->get_split_packed_value(); + std::shared_ptr splitDimValue = s->index_->get_split_dim_value(); + assert(splitDimValue->length == bytes_per_dim_); + assert(FutureArrays::CompareUnsigned(cellMinPacked, + splitDim * bytes_per_dim_, + splitDim * bytes_per_dim_ + bytes_per_dim_, + (splitDimValue->bytes), + splitDimValue->offset, + splitDimValue->offset + bytes_per_dim_) <= 0); + assert(FutureArrays::CompareUnsigned(cellMaxPacked, + splitDim * bytes_per_dim_, + splitDim * bytes_per_dim_ + bytes_per_dim_, + (splitDimValue->bytes), + splitDimValue->offset, + splitDimValue->offset + bytes_per_dim_) >= 0); + + std::copy(cellMaxPacked.begin(), + cellMaxPacked.begin() + packed_index_bytes_length_, + splitPackedValue.begin()); + std::copy(splitDimValue->bytes.begin() + splitDimValue->offset, + splitDimValue->bytes.begin() + splitDimValue->offset + bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_); + s->index_->push_left(); + intersect(s, cellMinPacked, splitPackedValue); + s->index_->pop(); + + std::copy(splitPackedValue.begin() + splitDim * bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_ + bytes_per_dim_, + splitDimValue->bytes.begin() + splitDimValue->offset); + + std::copy(cellMinPacked.begin(), + cellMinPacked.begin() + packed_index_bytes_length_, + splitPackedValue.begin()); + std::copy(splitDimValue->bytes.begin() + splitDimValue->offset, + splitDimValue->bytes.begin() + splitDimValue->offset + bytes_per_dim_, + splitPackedValue.begin() + splitDim * bytes_per_dim_); + s->index_->push_right(); + intersect(s, splitPackedValue, cellMaxPacked); + s->index_->pop(); + } +} + +int32_t bkd_reader::get_tree_depth() const { + return floor(log2(num_leaves_)) + 2; +} + +int64_t bkd_reader::ram_bytes_used() { + if (!packed_index_->empty()) { + return packed_index_->capacity();// std::shared_ptr> packed_index_; 元素1字节 + } else { + // std::vector split_packed_values_ // 元素1字节 + // std::vector leaf_block_fps_; + return split_packed_values_.capacity() + leaf_block_fps_.capacity() * sizeof(int64_t); + } +} + +CL_NS_END2 diff --git a/src/core/CLucene/util/bkd/bkd_reader.h b/src/core/CLucene/util/bkd/bkd_reader.h new file mode 100644 index 00000000000..8ee1156e5f2 --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_reader.h @@ -0,0 +1,215 @@ +#pragma once + +#include "CLucene/StdHeader.h" + +#include "CLucene/store/IndexInput.h" +#include "CLucene/util/croaring/roaring.hh" +#include "bkd_docid_iterator.h" +#include "index_tree.h" + +#include +#include + +CL_NS_DEF2(util, bkd) + +enum class relation { + /** Return this if the cell is fully contained by the query */ + CELL_INSIDE_QUERY, + /** Return this if the cell and query do not overlap */ + CELL_OUTSIDE_QUERY, + /** Return this if the cell partially overlaps the query */ + CELL_CROSSES_QUERY +}; + + +class bkd_reader : public std::enable_shared_from_this { + +public: + int32_t leaf_node_offset_{}; + int32_t num_data_dims_{}; + int32_t num_index_dims_{}; + int32_t bytes_per_dim_{}; + int32_t num_leaves_{}; + std::unique_ptr in_; + int32_t max_points_in_leaf_node_{}; + std::vector min_packed_value_; + std::vector max_packed_value_; + int64_t point_count_{}; + int32_t doc_count_{}; + int32_t version_{}; + std::shared_ptr> packed_index_; + std::shared_ptr clone_index_input; + int32_t bytes_per_index_entry_{}; + std::vector leaf_block_fps_; + + int32_t packed_bytes_length_{}; + int32_t packed_index_bytes_length_{}; + std::vector split_packed_values_; + int32_t type{}; + int64_t metaOffset{}; + int64_t indexFP{}; + +public: + class intersect_visitor { + public: + virtual void visit(int docID) = 0; + + /** Called for all documents in a leaf cell that crosses the query. The + * consumer should scrutinize the packedValue to decide whether to accept + * it. In the 1D case, values are visited in increasing order, and in the + * case of ties, in increasing docID order. + */ + virtual void visit(int docID, std::vector &packedValue) = 0; + virtual void visit(Roaring &docID) = 0; + virtual void visit(Roaring &&docID) = 0; + virtual void visit(bkd_docID_set_iterator *iter, std::vector &packedValue) = 0; + virtual void visit(Roaring *docID, std::vector &packedValue) = 0; + virtual void visit(std::vector& docID, std::vector &packedValue) = 0; + + /** Called for non-leaf cells to test how the cell relates to the query, to + * determine how to further recurse down the tree. */ + virtual relation compare(std::vector &minPackedValue, + std::vector &maxPackedValue) = 0; + void grow(int count){}; + + virtual void inc_hits(int count) {} + + virtual bool only_hits() { return false; } + }; + class intersect_state final { + public: + intersect_state(store::IndexInput *in, + int32_t numDims, + int32_t packedBytesLength, + int32_t packedIndexBytesLength, + int32_t maxPointsInLeafNode, + bkd_reader::intersect_visitor *visitor, + const std::shared_ptr &indexVisitor); + + public: + std::shared_ptr in_; + std::unique_ptr docID_set_iterator; + std::vector scratch_doc_ids_; + std::vector scratch_data_packed_value_; + std::vector scratch_min_index_packed_value_; + std::vector scratch_max_index_packed_value_; + std::vector common_prefix_lengths_; + + bkd_reader::intersect_visitor *visitor_; + std::shared_ptr index_; + }; + +public: + int32_t get_tree_depth() const; + void add_all(const std::shared_ptr &state, bool grown); + void visit_doc_ids(store::IndexInput *in, int64_t blockFP, bkd_reader::intersect_visitor *visitor) const; + int32_t read_doc_ids(store::IndexInput *in, int64_t blockFP, bkd_docID_set_iterator *iter) const; + //int32_t VisitDocValues(const std::shared_ptr& in, int64_t blockFP, std::vector& docIDs); + void visit_doc_values(std::vector &commonPrefixLengths, + std::vector &scratchDataPackedValue, + const std::vector &scratchMinIndexPackedValue, + const std::vector &scratchMaxIndexPackedValue, + store::IndexInput *in, bkd_docID_set_iterator *iter, + int32_t count, bkd_reader::intersect_visitor *visitor); + void read_common_prefixes(std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, store::IndexInput *in) const; + + void read_min_max(const std::vector &commonPrefixLengths, std::vector &minPackedValue, + std::vector &maxPackedValue, store::IndexInput *in) const; + int32_t read_compressed_dim(store::IndexInput *in) const; + void visit_compressed_doc_values(std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor, + int32_t compressedDim) const; + void visit_raw_doc_values(const std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const; + void visit_unique_raw_doc_values(std::vector &scratchPackedValue, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const; + void visit_sparse_raw_doc_values(const std::vector &commonPrefixLengths, + std::vector &scratchPackedValue, + store::IndexInput *in, + bkd_docID_set_iterator *iter, + int32_t count, + bkd_reader::intersect_visitor *visitor) const; + +public: + bkd_reader() = default; + void read_index(store::IndexInput* index_in); + int read_meta(store::IndexInput* meta_in); + explicit bkd_reader(store::IndexInput *in); + int64_t estimate_point_count(bkd_reader::intersect_visitor *visitor); + int64_t estimate_point_count(const std::shared_ptr &s, + std::vector &cellMinPacked, + std::vector &cellMaxPacked); + void intersect(bkd_reader::intersect_visitor *visitor); + void intersect(const std::shared_ptr &s, + std::vector &cellMinPacked, + std::vector &cellMaxPacked); + std::shared_ptr get_intersect_state(bkd_reader::intersect_visitor *visitor); + +private: + int64_t ram_bytes_used(); + +public: + struct reader_stats { + private: + uint64_t visit_doc_values_time_duration_ms{0}; + uint64_t visit_uniq_doc_values_time_duration_ms{0}; + uint64_t visit_sparse_doc_values_time_duration_ms{0}; + uint64_t visit_compress_doc_values_time_duration_ms{0}; + uint64_t visit_doc_id_time_duration_ms{0}; + uint64_t read_doc_id_time_duration_ms{0}; + uint64_t visit_compare_time_duration_ms{0}; + + public: + void set_doc_value_visit_time_duration(uint64_t time_duration) { visit_doc_values_time_duration_ms = time_duration; } + void add_doc_value_visit_time_duration(uint64_t time_duration) { visit_doc_values_time_duration_ms += time_duration; } + uint64_t get_doc_value_visit_time_duration() const { return visit_doc_values_time_duration_ms; } + + void set_uniq_doc_value_visit_time_duration(uint64_t time_duration) { visit_uniq_doc_values_time_duration_ms = time_duration; } + void add_uniq_doc_value_visit_time_duration(uint64_t time_duration) { visit_uniq_doc_values_time_duration_ms += time_duration; } + uint64_t get_uniq_doc_value_visit_time_duration() const { return visit_uniq_doc_values_time_duration_ms; } + + void set_sparse_doc_value_visit_time_duration(uint64_t time_duration) { visit_sparse_doc_values_time_duration_ms = time_duration; } + void add_sparse_doc_value_visit_time_duration(uint64_t time_duration) { visit_sparse_doc_values_time_duration_ms += time_duration; } + uint64_t get_sparse_doc_value_visit_time_duration() const { return visit_sparse_doc_values_time_duration_ms; } + + void set_compress_doc_value_visit_time_duration(uint64_t time_duration) { visit_compress_doc_values_time_duration_ms = time_duration; } + void add_compress_doc_value_visit_time_duration(uint64_t time_duration) { visit_compress_doc_values_time_duration_ms += time_duration; } + uint64_t get_compress_doc_value_visit_time_duration() const { return visit_compress_doc_values_time_duration_ms; } + + void set_doc_id_visit_time_duration(uint64_t time_duration) { visit_doc_id_time_duration_ms = time_duration; } + void add_doc_id_visit_time_duration(uint64_t time_duration) { visit_doc_id_time_duration_ms += time_duration; } + uint64_t get_doc_id_visit_time_duration() const { return visit_doc_id_time_duration_ms; } + + void set_read_doc_id_time_duration(uint64_t time_duration) { read_doc_id_time_duration_ms = time_duration; } + void add_read_doc_id_time_duration(uint64_t time_duration) { read_doc_id_time_duration_ms += time_duration; } + uint64_t get_read_doc_id_time_duration() const { return read_doc_id_time_duration_ms; } + + void set_visit_compare_time_duration(uint64_t time_duration) { visit_compare_time_duration_ms = time_duration; } + void add_visit_compare_time_duration(uint64_t time_duration) { visit_compare_time_duration_ms += time_duration; } + uint64_t get_visit_compare_time_duration() const { return visit_compare_time_duration_ms; } + + std::string to_string() const { + return "| visit compare time: " + std::to_string(visit_compare_time_duration_ms) + "ms " + + "| read doc id time: " + std::to_string(read_doc_id_time_duration_ms) + "ms " + + "| visit doc id time: " + std::to_string(visit_doc_id_time_duration_ms) + "ms " + + "| visit doc value time: " + std::to_string(visit_doc_values_time_duration_ms) + "ms " + + "| visit unique doc value time: " + std::to_string(visit_uniq_doc_values_time_duration_ms) + "ms " + + "| visit sparse doc value time: " + std::to_string(visit_sparse_doc_values_time_duration_ms) + "ms " + + "| visit compress doc value time: " + std::to_string(visit_compress_doc_values_time_duration_ms) + "ms " + ; + } + }; + reader_stats stats; +}; +CL_NS_END2 diff --git a/src/core/CLucene/util/bkd/bkd_writer.cpp b/src/core/CLucene/util/bkd/bkd_writer.cpp new file mode 100644 index 00000000000..4e05d431371 --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_writer.cpp @@ -0,0 +1,984 @@ +#include "CLucene/util/CodecUtil.h" +#include "CLucene/util/FixedBitSet.h" +#include "CLucene/util/FutureArrays.h" +#include "CLucene/util/NumericUtils.h" +#include "CLucene/store/_RAMDirectory.h" + +#include "bkd_msb_radix_sorter.h" +#include "bkd_writer.h" +#include "docIds_writer.h" + +#include +#include +#include +#include +CL_NS_DEF(util) + +namespace bkd { + const std::wstring bkd_writer::CODEC_NAME = L"BKD"; + bkd_writer::bkd_writer(int32_t maxDoc, int32_t numDataDims, + int32_t num_index_dims, int32_t bytes_per_dim, int32_t maxPointsInLeafNode, double maxMBSortInHeap, + int64_t totalPointCount, bool singleValuePerDoc, int32_t maxDepth) : bkd_writer(maxDoc, numDataDims,num_index_dims, bytes_per_dim, maxPointsInLeafNode, maxMBSortInHeap, totalPointCount, singleValuePerDoc, + totalPointCount > std::numeric_limits::max(), maxDepth) { + } + + bkd_writer::bkd_writer(int32_t maxDoc, int32_t numDataDims, + int32_t num_index_dims, int32_t bytes_per_dim, int32_t maxPointsInLeafNode, double maxMBSortInHeap, + int64_t totalPointCount, bool singleValuePerDoc, bool longOrds, int32_t maxDepth) { + verify_params(numDataDims, num_index_dims, maxPointsInLeafNode, maxMBSortInHeap, totalPointCount); + // We use tracking dir to deal with removing files on exception, so each place that + // creates temp files doesn't need crazy try/finally/sucess logic: + max_depth_ = maxDepth; + max_points_in_leaf_node_ = maxPointsInLeafNode; + num_data_dims_ = numDataDims; + num_index_dims_ = num_index_dims; + bytes_per_dim_ = bytes_per_dim; + total_point_count_ = totalPointCount; + max_doc_ = maxDoc; + max_depth_ = maxDepth; + //docs_seen_ = std::make_unique(maxDoc); + packed_bytes_length_ = numDataDims * bytes_per_dim; + packed_index_bytes_length_ = num_index_dims_ * bytes_per_dim; + + + // If we may have more than 1+Integer.MAX_VALUE values, then we must encode ords with int64_t (8 bytes), else we can use int32_t (4 bytes). + long_ords_ = longOrds; + single_value_per_doc_ = singleValuePerDoc; + + // dimensional values (numDims * bytes_per_dim_) + ord (int32_t or int64_t) + docID (int32_t) + if (singleValuePerDoc) { + // Lucene only supports up to 2.1 docs, so we better not need longOrds in this case: + assert(longOrds == false); + bytes_per_doc_ = packed_bytes_length_ + 4; + } else if (longOrds) { + bytes_per_doc_ = packed_bytes_length_ + 8 + 4; + } else { + bytes_per_doc_ = packed_bytes_length_ + 4 + 4; + } + + // As we recurse, we compute temporary partitions of the data, halving the + // number of points at each recursion. Once there are few enough points, + // we can switch to sorting in heap instead of offline (on disk). At any + // time in the recursion, we hold the number of points at that level, plus + // all recursive halves (i.e. 16 + 8 + 4 + 2) so the memory usage is 2X + // what that level would consume, so we multiply by 0.5 to convert from + // bytes to points here. Each dimension has its own sorted partition, so + // we must divide by numDims as wel. + + max_points_sort_in_heap_ = (int32_t) (0.5 * (maxMBSortInHeap * 1024 * 1024) / (bytes_per_doc_ * numDataDims)); + + // Finally, we must be able to hold at least the leaf node in heap during build: + if (max_points_sort_in_heap_ < maxPointsInLeafNode) { + auto msg = "maxMBSortInHeap=" + std::to_string(maxMBSortInHeap) + " only allows for maxPointsSortInHeap=" + std::to_string(max_points_sort_in_heap_) + ", but this is less than maxPointsInLeafNode=" + std::to_string(maxPointsInLeafNode) + "; either increase maxMBSortInHeap or decrease maxPointsInLeafNode"; + _CLTHROWA(CL_ERR_IllegalArgument, msg.c_str()); + } + // max_points_sort_in_heap_ = 100 * 1024 * 1024; + // We write first maxPointsSortInHeap in heap, then cutover to offline for additional points: + heap_point_writer_ = std::make_shared(16, max_points_sort_in_heap_, packed_bytes_length_, longOrds, singleValuePerDoc); + max_mb_sort_in_heap_ = maxMBSortInHeap; + + max_packed_value_.resize(packed_bytes_length_); + min_packed_value_.resize(packed_bytes_length_); + + common_prefix_lengths_.resize(num_data_dims_); + scratch1_.resize(packed_bytes_length_); + scratch_diff_.resize(bytes_per_dim_); + scratch2_.resize(packed_bytes_length_); + } + + void bkd_writer::verify_params(int32_t numDataDims, int32_t numIndexDims, int32_t maxPointsInLeafNode, + double maxMBSortInHeap, int64_t totalPointCount) { + std::string msg; + // We encode dim in a single byte in the splitPackedValues, but we only expose 4 bits for it now, in case we want to use + // remaining 4 bits for another purpose later + if (numDataDims < 1 || numDataDims > MAX_DIMS) { + msg = "numDataDims must be 1 .. " + std::to_string(MAX_DIMS) + " (got: " + std::to_string(numDataDims) + ")"; + } + if (numIndexDims < 1 || numIndexDims > numDataDims) { + msg = "num_index_dims_ must be 1 .. " + std::to_string(numDataDims) + " (got: " + std::to_string(numIndexDims) + ")"; + } + if (maxPointsInLeafNode <= 0) { + msg = "maxPointsInLeafNode must be > 0; got " + std::to_string(maxPointsInLeafNode); + } + if (maxPointsInLeafNode > MAX_ARRAY_LENGTH) { + msg = "maxPointsInLeafNode must be <= MAX_ARRAY_LENGTH (= " + std::to_string(MAX_ARRAY_LENGTH) + "); got " + std::to_string(maxPointsInLeafNode); + } + if (maxMBSortInHeap < 0.0) { + msg = "maxMBSortInHeap must be >= 0.0 (got: " + std::to_string(maxMBSortInHeap) + ")"; + } + if (totalPointCount < 0) { + msg = "totalPointCount must be >=0 (got: " + std::to_string(totalPointCount) + ")"; + } + if (!msg.empty()) { + _CLTHROWA(CL_ERR_IllegalArgument, msg.c_str()); + } + } + + void bkd_writer::check_max_leaf_node_count(int32_t num_leaves) const { + if ((1 + bytes_per_dim_) * (int64_t) num_leaves > MAX_ARRAY_LENGTH) { + _CLTHROWA(CL_ERR_IllegalArgument, "too many nodes; increase max_points_in_leaf_node"); + } + } + + void bkd_writer::add(const uint8_t *packed_value, uint32_t value_len, int32_t doc_id) { + if (value_len != (size_t) packed_bytes_length_) { + _CLTHROWA(CL_ERR_IllegalArgument, ("packedValue should be length=" + std::to_string(packed_bytes_length_) + ", got " + std::to_string(value_len)).c_str()); + } + heap_point_writer_->append(packed_value, value_len, std::min(point_count_, (int64_t) max_points_sort_in_heap_), doc_id); + if (point_count_ == 0) { + memcpy(min_packed_value_.data(), packed_value, packed_index_bytes_length_); + memcpy(max_packed_value_.data(), packed_value, packed_index_bytes_length_); + } else { + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + int32_t offset = dim * bytes_per_dim_; + if (FutureArrays::CompareUnsigned(packed_value, offset, offset + bytes_per_dim_, min_packed_value_.data(), offset, offset + bytes_per_dim_) < 0) { + memcpy(min_packed_value_.data() + offset, packed_value + offset, bytes_per_dim_); + } + if (FutureArrays::CompareUnsigned(packed_value, offset, offset + bytes_per_dim_, max_packed_value_.data(), offset, offset + bytes_per_dim_) > 0) { + memcpy(max_packed_value_.data() + offset, packed_value + offset, bytes_per_dim_); + } + } + } + + point_count_++; + if (point_count_ > total_point_count_) + _CLTHROWA(CL_ERR_IllegalArgument, ("total_point_count_=" + std::to_string(total_point_count_) + " was passed when we were created, but we just hit " + std::to_string(point_count_) + " values").c_str()); + //docs_seen_.insert(doc_id); + } + + void bkd_writer::add(std::vector &packedValue, int32_t docID) { + if (packedValue.size() != (size_t) packed_bytes_length_) { + _CLTHROWA(CL_ERR_IllegalArgument, ("packedValue should be length=" + std::to_string(packed_bytes_length_) + ", got " + std::to_string(packedValue.size())).c_str()); + } + heap_point_writer_->append(packedValue, std::min(point_count_, (int64_t) max_points_sort_in_heap_), docID); + + if (point_count_ == 0) { + std::copy(packedValue.begin(), + packedValue.begin() + packed_index_bytes_length_, + min_packed_value_.begin()); + std::copy(packedValue.begin(), + packedValue.begin() + packed_index_bytes_length_, + max_packed_value_.begin()); + } else { + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + int32_t offset = dim * bytes_per_dim_; + if (FutureArrays::CompareUnsigned(packedValue, offset, offset + bytes_per_dim_, min_packed_value_, offset, offset + bytes_per_dim_) < 0) { + std::copy(packedValue.begin() + offset, + packedValue.begin() + offset + bytes_per_dim_, + min_packed_value_.begin() + offset); + } + if (FutureArrays::CompareUnsigned(packedValue, offset, offset + bytes_per_dim_, max_packed_value_, offset, offset + bytes_per_dim_) > 0) { + std::copy(packedValue.begin() + offset, + packedValue.begin() + offset + bytes_per_dim_, + max_packed_value_.begin() + offset); + } + } + } + + point_count_++; + if (point_count_ > total_point_count_) + _CLTHROWA(CL_ERR_IllegalArgument, ("total_point_count_=" + std::to_string(total_point_count_) + " was passed when we were created, but we just hit " + std::to_string(point_count_) + " values").c_str()); + //docs_seen_->Set(docID); + //docs_seen_.insert(docID); + } + + void bkd_writer::meta_finish(store::IndexOutput *out, int64_t fPointer, int32_t type) { + out->writeInt(type); + out->writeLong(fPointer); + } + + int64_t bkd_writer::finish(store::IndexOutput *out, store::IndexOutput *index_out) { + if (point_count_ == 0) { + return 0; + //_CLTHROWA(CL_ERR_IllegalArgument, "must index at least one point"); + } + std::shared_ptr ord_bit_set = nullptr; + if (num_index_dims_ > 1) { + if (single_value_per_doc_) + ord_bit_set = std::make_shared(max_doc_); + else + ord_bit_set = std::make_shared(point_count_); + } + + auto max_points_in_leaf_node = point_count_ / (1LL << max_depth_); + if (max_points_in_leaf_node > 0) { + max_points_in_leaf_node_ = max_points_in_leaf_node; + } + + int64_t count_per_leaf = point_count_; + int64_t inner_node_count = 1; + while (count_per_leaf > max_points_in_leaf_node_) { + count_per_leaf = (count_per_leaf + 1) / 2; + inner_node_count *= 2; + } + auto num_leaves = (int32_t) inner_node_count; + check_max_leaf_node_count(num_leaves); + // Indexed by node_id, but first (root) node_id is 1. We do 1+ because the lead byte at each recursion says which dim we split on. + std::vector split_packed_values(num_leaves * (1 + bytes_per_dim_)); + std::vector leaf_block_fps(num_leaves); + //assert(point_count_ / num_leaves <= max_points_in_leaf_node_); + std::vector> sorted_point_writers(num_index_dims_); + std::vector> to_close_heroically; + bool success = false; + std::vector parent_splits(num_index_dims_); + build(1, num_leaves, sorted_point_writers, + ord_bit_set, out, + min_packed_value_, max_packed_value_, + parent_splits, + split_packed_values, + leaf_block_fps, + to_close_heroically); + //assert(temp_dir_->GetCreatedFiles().size() == 0); + success = true; + if (!success) { + //TODO IOUtilas need to be implemented + } + int64_t index_fp = out->getFilePointer(); + write_index(index_out, count_per_leaf, leaf_block_fps, split_packed_values); + return index_fp; + } + + /** Pull a partition back into heap once the point count is low enough while recursing. */ + PathSlicePtr bkd_writer::switch_to_heap(const PathSlicePtr &source, const std::vector> &toCloseHeroically) { + auto count = (int32_t) (source->count_); + // Not inside the try because we don't want to close it here: + std::shared_ptr reader = source->writer_->get_shared_reader(source->start_, source->count_, toCloseHeroically); + std::shared_ptr writer = std::make_shared(count, count, packed_bytes_length_, long_ords_, single_value_per_doc_); + if (writer != nullptr) { + for (int32_t i = 0; i < count; i++) { + bool has_next = reader->next(); + assert(has_next); + //assert(reader->Next()); + writer->append(reader->packed_value_raw(), packed_bytes_length_, reader->ord(), reader->docId()); + } + } + return std::make_shared(writer, 0, count); + } + + void bkd_writer::write_leaf_block_docs(store::IndexOutput *out, std::vector &docIDs, int32_t start, int32_t count) { + assert(count > 0); + out->writeVInt(count); + docIds_writer::write_doc_ids(docIDs, start, count, out); + } + void bkd_writer::write_leaf_block_docs_bitmap(store::IndexOutput *out, std::vector &docIDs, int32_t start, int32_t count) { + assert(count > 0); + out->writeVInt(count); + out->writeByte((uint8_t) 1); + docIds_writer::write_doc_ids_bitmap(docIDs, start, count, out); + } + void bkd_writer::write_common_prefixes(store::IndexOutput *out, std::vector &commonPrefixes, std::vector &packedValue) const { + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + out->writeVInt(commonPrefixes[dim]); + out->writeBytes(packedValue.data(), commonPrefixes[dim], dim * bytes_per_dim_); + } + } + + void bkd_writer::write_common_prefixes(store::IndexOutput *out, std::vector &commonPrefixes, std::vector &packedValue, int offset) const { + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + out->writeVInt(commonPrefixes[dim]); + out->writeBytes(packedValue.data(), commonPrefixes[dim], dim * bytes_per_dim_ + offset); + } + } + + int32_t bkd_writer::append_block(const std::shared_ptr &writeBuffer, ByteArrayList &blocks) { + //TODO:efficiency need to check here + int32_t pos = writeBuffer->getFilePointer(); + std::vector bytes = std::vector(pos); + writeBuffer->writeTo(bytes, 0); + writeBuffer->reset(); + blocks.emplace_back(bytes); + return pos; + } + + int64_t bkd_writer::get_left_most_leaf_blockFP(std::vector &leafBlockFPs, int32_t nodeID) { + while (nodeID < (int32_t) leafBlockFPs.size()) + nodeID *= 2; + int32_t leaf_id = nodeID - leafBlockFPs.size(); + int64_t result = leafBlockFPs.at(leaf_id); + if (result < 0) + _CLTHROWA(CL_ERR_IllegalArgument, "file pointer less than 0."); + return result; + } + + //lastSplitValues is per-dimension split value previously seen; we use this to prefix-code the split byte[] on each inner node + int32_t bkd_writer::recurse_pack_index(const std::shared_ptr &writeBuffer, std::vector &leafBlockFPs, + std::vector &splitPackedValues, int64_t minBlockFP, + ByteArrayList &blocks, int32_t nodeID, std::vector &lastSplitValues, + std::vector &negativeDeltas, bool isLeft) const { + if (nodeID >= (int32_t) leafBlockFPs.size()) { + int32_t leaf_id = nodeID - leafBlockFPs.size(); + // in the unbalanced case it's possible the left most node noly has one child + if (leaf_id < (int32_t) leafBlockFPs.size()) { + int64_t delta = leafBlockFPs.at(leaf_id) - minBlockFP; + if (isLeft) { + assert(delta == 0); + return 0; + } else { + assert(nodeID == 1 || delta > 0); + writeBuffer->writeVLong(delta); + return append_block(writeBuffer, blocks); + } + } else { + return 0; + } + } else { + int64_t left_block_fp; + if (!isLeft) { + left_block_fp = get_left_most_leaf_blockFP(leafBlockFPs, nodeID); + int64_t delta = left_block_fp - minBlockFP; + assert(nodeID == 1 || delta > 0); + writeBuffer->writeVLong(delta); + } else { + left_block_fp = minBlockFP; + } + + + int32_t address = nodeID * (1 + bytes_per_dim_); + int32_t split_dim = splitPackedValues[address++] & 0xff; + + //find common prefix with last split value in this dimension + int32_t prefix = FutureArrays::Mismatch(splitPackedValues, address, address + bytes_per_dim_, + lastSplitValues, split_dim * bytes_per_dim_, split_dim * bytes_per_dim_ + bytes_per_dim_); + if (prefix == -1) + prefix = bytes_per_dim_; + + int32_t first_diff_byte_delta; + //std::string message = "["; + if (prefix < bytes_per_dim_) { + first_diff_byte_delta = (splitPackedValues[address + prefix] & 0xff) - + (lastSplitValues[split_dim * bytes_per_dim_ + prefix] & 0xff); + if (negativeDeltas[split_dim]) + first_diff_byte_delta = -first_diff_byte_delta; + //message += std::to_string(first_diff_byte_delta); + assert(first_diff_byte_delta > 0); + + } else { + first_diff_byte_delta = 0; + //message += std::to_string(first_diff_byte_delta); + } + //message += "]"; + //pack the prefix, split_dim and delta fist diff byte into a single vInt: + int32_t code = (first_diff_byte_delta * (1 + bytes_per_dim_) + prefix) * num_index_dims_ + split_dim; + //printf("write first_diff_byte_delta %d\n",code); + writeBuffer->writeVInt(code); + //write the split value, prefix coded as. out parent's split value: + int32_t suffix = bytes_per_dim_ - prefix; + std::vector save_split_value(suffix); + if (suffix > 1) + writeBuffer->writeBytes(splitPackedValues.data(), suffix - 1, address + prefix + 1); + + std::vector cmp = lastSplitValues; + + std::copy(lastSplitValues.begin() + split_dim * bytes_per_dim_ + prefix, + lastSplitValues.begin() + split_dim * bytes_per_dim_ + prefix + suffix, + save_split_value.begin()); + + // copy our split value into lastSplitValues for our children to prefix-code against + std::copy(splitPackedValues.begin() + address + prefix, + splitPackedValues.begin() + address + prefix + suffix, + lastSplitValues.begin() + split_dim * bytes_per_dim_ + prefix); + int32_t num_bytes = append_block(writeBuffer, blocks); + + // placeholder for left-tree numBytes; we need this so that at search time if we only need to recurse into the right sub-tree we can + // quickly seek to its starting point + int32_t idx_save = blocks.size(); + //blocks.push_back(nullptr); + blocks.emplace_back(std::vector(0)); + //blocks.push_back(std::vector()); + bool save_negative_delta = negativeDeltas[split_dim]; + negativeDeltas[split_dim] = true; + int32_t left_num_bytes = recurse_pack_index(writeBuffer, leafBlockFPs, splitPackedValues, left_block_fp, blocks, + 2 * nodeID, lastSplitValues, negativeDeltas, true); + if (nodeID * 2 < (int32_t) leafBlockFPs.size()) + writeBuffer->writeVInt(left_num_bytes); + else + assert(left_num_bytes == 0); + int32_t num_bytes2 = writeBuffer->getFilePointer(); + std::vector bytes2(num_bytes2); + writeBuffer->writeTo(bytes2, 0); + writeBuffer->reset(); + // replace out placeholder + // std::fill(blocks[idx_save]->begin(), blocks[idx_save]->begin() + num_bytes2, bytes2.begin()); + // bytes2.insert(bytes2.begin(), blocks[idx_save]->begin(), blocks[idx_save]->begin() + num_bytes2); + //TODO:copy is inefficient,need to improve performance here. + blocks[idx_save] = std::move(bytes2); + + negativeDeltas[split_dim] = false; + int32_t right_num_bytes = recurse_pack_index(writeBuffer, leafBlockFPs, splitPackedValues, left_block_fp, blocks, + 2 * nodeID + 1, lastSplitValues, negativeDeltas, false); + negativeDeltas[split_dim] = save_negative_delta; + // restore last split values to what caller originally passed us: + std::copy(save_split_value.begin(), + save_split_value.begin() + suffix, + lastSplitValues.begin() + split_dim * bytes_per_dim_ + prefix); + + assert(std::equal(lastSplitValues.begin(), lastSplitValues.end(), cmp.begin())); + return num_bytes + num_bytes2 + left_num_bytes + right_num_bytes; + } + } + + std::shared_ptr> bkd_writer::pack_index(std::vector &leaf_block_fps, + std::vector &split_packed_values) const { + int32_t num_leaves = leaf_block_fps.size(); + if (num_index_dims_ == 1 && num_leaves > 1) { + int32_t level_count = 2; + while (true) { + if (num_leaves >= level_count && num_leaves <= 2 * level_count) { + int32_t last_level = 2 * (num_leaves - level_count); + assert(last_level >= 0); + if (last_level != 0) { + std::vector new_leaf_block_fps(num_leaves); + std::copy(leaf_block_fps.begin() + last_level, + leaf_block_fps.begin() + last_level + (leaf_block_fps.size() - last_level), + new_leaf_block_fps.begin()); + std::copy(leaf_block_fps.begin(), + leaf_block_fps.begin() + last_level, + new_leaf_block_fps.begin() + (leaf_block_fps.size() - last_level)); + leaf_block_fps.swap(new_leaf_block_fps); + } + break; + } + level_count *= 2; + } + } + std::shared_ptr write_buffer = std::make_shared(); + //This is the "file" we append the byte[] to: + ByteArrayList blocks; + std::vector last_split_values(bytes_per_dim_ * num_index_dims_); + std::vector bools(num_index_dims_); + int32_t total_size = recurse_pack_index(write_buffer, leaf_block_fps, split_packed_values, (int64_t) 0, blocks, 1, last_split_values, bools, false); + std::shared_ptr> index = std::make_shared>(total_size); + int32_t upto = 0; + for (auto &block: blocks) { + std::copy(block.begin(), block.begin() + block.size(), index->begin() + upto); + upto += block.size(); + } + assert(upto == total_size); + return index; + } + + void bkd_writer::write_index(store::IndexOutput *out, int32_t countPerLeaf, std::vector &leafBlockFPs, + std::vector &splitPackedValues) { + std::shared_ptr> packed_index = pack_index(leafBlockFPs, splitPackedValues); + write_index(out, countPerLeaf, leafBlockFPs.size(), *packed_index); + } + + void bkd_writer::write_index(store::IndexOutput *out, int32_t countPerLeaf, int32_t numLeaves, std::vector &packedIndex) { + CodecUtil::writeHeader(out, CODEC_NAME, VERSION_CURRENT); + out->writeVInt(num_data_dims_); + out->writeVInt(num_index_dims_); + out->writeVInt(countPerLeaf); + out->writeVInt(bytes_per_dim_); + + assert(numLeaves > 0); + out->writeVInt(numLeaves); + out->writeBytes(min_packed_value_.data(), packed_index_bytes_length_); + out->writeBytes(max_packed_value_.data(), packed_index_bytes_length_); + + out->writeVLong(point_count_); + out->writeVInt(docs_seen_); + out->writeVInt(packedIndex.size()); + + out->writeBytes(packedIndex.data(), packedIndex.size()); + } + + int32_t bkd_writer::run_len(const IntFunction &packedValues, int32_t start, int32_t end, int32_t byteOffset) { + BytesRef *first = packedValues(start); + uint8_t b = first->bytes.at(first->offset + byteOffset); + for (int32_t i = start + 1; i < end; ++i) { + BytesRef *ref = packedValues(i); + uint8_t b2 = ref->bytes.at(ref->offset + byteOffset); + if (b != b2) + return i - start; + } + return end - start; + } + + void bkd_writer::write_leaf_block_packed_values_range(store::IndexOutput *out, std::vector &commonPrefixLengths, + int32_t start, int32_t end, const IntFunction &packedValues) const { + for (int32_t i = start; i < end; i++) { + BytesRef *ref = packedValues(i); + assert(ref->length == packed_bytes_length_); + for (int32_t dim = 0; dim < num_data_dims_; dim++) { + int32_t prefix = commonPrefixLengths[dim]; + out->writeBytes(ref->bytes.data(), bytes_per_dim_ - prefix, ref->offset + dim * bytes_per_dim_ + prefix); + } + } + } + + void bkd_writer::write_low_cardinality_leaf_block_packed_values(store::IndexOutput *out, std::vector &common_prefix_lengths, + int32_t count, const IntFunction &packed_values) { + BytesRef *value = packed_values(0); + std::copy(value->bytes.begin() + value->offset, value->bytes.begin() + value->offset + num_data_dims_ * bytes_per_dim_, scratch1_.begin()); + int cardinality = 1; + for (int i = 1; i < count; i++) { + value = packed_values(i); + for (int dim = 0; dim < num_data_dims_; dim++) { + int start = dim * bytes_per_dim_ + common_prefix_lengths[dim]; + int end = dim * bytes_per_dim_ + bytes_per_dim_; + if (FutureArrays::Mismatch(value->bytes, value->offset + start, value->offset + end, scratch1_, start, end) != -1) { + out->writeVInt(cardinality); + for (int j = 0; j < num_data_dims_; j++) { + out->writeBytes(scratch1_.data(), bytes_per_dim_ - common_prefix_lengths[j], j * bytes_per_dim_ + common_prefix_lengths[j]); + } + std::copy(value->bytes.begin() + value->offset, value->bytes.begin() + value->offset + num_data_dims_ * bytes_per_dim_, scratch1_.begin()); + cardinality = 1; + break; + } else if (dim == num_data_dims_ - 1) { + cardinality++; + } + } + } + out->writeVInt(cardinality); + for (int i = 0; i < num_data_dims_; i++) { + out->writeBytes(scratch1_.data(), bytes_per_dim_ - common_prefix_lengths[i], i * bytes_per_dim_ + common_prefix_lengths[i]); + } + } + + void bkd_writer::write_high_cardinality_leaf_block_packed_values(store::IndexOutput *out, std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, const IntFunction &packed_values, + int32_t compressed_byte_offset) const { + common_prefix_lengths[sorted_dim]++; + for (int32_t i = 0; i < count;) { + int32_t run_length = run_len(packed_values, i, std::min(i + 0xff, count), compressed_byte_offset); + assert(run_length <= 0xff); + BytesRef *first = packed_values(i); + uint8_t prefix_byte = first->bytes.at(first->offset + compressed_byte_offset); + out->writeByte(prefix_byte); + out->writeByte((uint8_t) run_length); + write_leaf_block_packed_values_range(out, common_prefix_lengths, i, i + run_length, packed_values); + i += run_length; + assert(i <= count); + } + } + + void bkd_writer::write_leaf_block_packed_values(store::IndexOutput *out, + std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, + const IntFunction &packed_values, + int32_t prefix_len_sum, + bool low_cardinality) { + //int32_t prefix_len_sum = std::accumulate(common_prefix_lengths.begin(), common_prefix_lengths.end(), 0); + if (prefix_len_sum == packed_bytes_length_) { + // all values in this block are equal + out->writeByte(int8_t(-1)); + } else { + int32_t compressed_byte_offset = sorted_dim * bytes_per_dim_ + common_prefix_lengths[sorted_dim]; + if (low_cardinality) { + out->writeByte(int8_t(-2)); + write_low_cardinality_leaf_block_packed_values(out, common_prefix_lengths, count, packed_values); + } else { + out->writeByte((uint8_t) sorted_dim); + write_high_cardinality_leaf_block_packed_values(out, common_prefix_lengths, count, sorted_dim, packed_values, compressed_byte_offset); + } + } + } + + /**Pick the next dimension to split.*/ + int32_t bkd_writer::split(std::vector &min_packed_value, std::vector &max_packed_value, std::vector &parent_splits) { + // First look at whether there is a dimension that has split less than 2x less than + // the dim that has most splits, and return it if there is such a dimension and it + // does not only have equals values. This helps ensure all dimensions are indexed. + int32_t max_num_splits = 0; + max_num_splits = *(std::max_element(parent_splits.begin(), parent_splits.end())); + for (int32_t dim = 0; dim < num_index_dims_; ++dim) { + int32_t offset = dim * bytes_per_dim_; + if (parent_splits[dim] < max_num_splits / 2 && FutureArrays::CompareUnsigned(min_packed_value, offset, offset + bytes_per_dim_, max_packed_value, offset, offset + bytes_per_dim_) != 0) + return dim; + } + // Find which dim has the largest span so we can split on it: + int32_t split_dim = -1; + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + NumericUtils::subtract(bytes_per_dim_, dim, max_packed_value, min_packed_value, scratch_diff_); + if (split_dim == -1 || FutureArrays::CompareUnsigned(scratch_diff_, 0, bytes_per_dim_, scratch1_, 0, bytes_per_dim_) > 0) { + std::copy(scratch_diff_.begin(), scratch_diff_.begin() + bytes_per_dim_, scratch1_.begin()); + split_dim = dim; + } + } + return split_dim; + } + + /** Marks bits for the ords (points) that belong in the right sub tree (those docs that have values >= the splitValue). */ + const uint8_t *bkd_writer::mark_right_tree(int64_t rightCount, int32_t splitDim, std::shared_ptr &source, const std::shared_ptr &ordBitSet) const { + // Now we mark ords that fall into the right half, so we can partition on all other dims that are not the split dim: + // Read the split value, then mark all ords in the right tree (larger than the split value): + std::shared_ptr reader = source->writer_->get_reader(source->start_ + source->count_ - rightCount, rightCount); + bool result = reader->next(); + assert(result); + //assert(reader->Next()); + if (reader != nullptr) { + /*std::copy(reader->packed_value().begin() + splitDim * bytes_per_dim_, + reader->packed_value().begin() + splitDim * bytes_per_dim_ + bytes_per_dim_, + scratch1_.begin());*/ + if (num_index_dims_ > 1 && ordBitSet != nullptr) { + assert(ordBitSet->Get(reader->ord()) == false); + ordBitSet->Set(reader->ord()); + reader->mark_ords(rightCount - 1, ordBitSet); + } + return reader->packed_value_raw() + splitDim * bytes_per_dim_; + } + return nullptr; + } + + std::shared_ptr bkd_writer::get_point_writer(int64_t count, std::string &desc) { + return std::make_shared(std::min(count, int64_t(max_points_sort_in_heap_)), std::min(count, int64_t(max_points_sort_in_heap_)), packed_bytes_length_, long_ords_, single_value_per_doc_); + } + + bool bkd_writer::leaf_node_is_low_cardinality(std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, + const IntFunction &packed_values, + const std::vector &leaf_cardinality, + int32_t prefix_len_sum) const { + int32_t compressed_byte_offset = sorted_dim * bytes_per_dim_ + common_prefix_lengths[sorted_dim]; + int highCardinalityCost; + int lowCardinalityCost; + if (count == leaf_cardinality.size()) { + // all values in this block are different + highCardinalityCost = 0; + lowCardinalityCost = 1; + } else { + // compute cost of runLen compression + int numRunLens = 0; + for (int i = 0; i < count;) { + // do run-length compression on the byte at compressedByteOffset + int32_t run_length = run_len(packed_values, i, std::min(i + 0xff, count), compressed_byte_offset); + assert(run_length <= 0xff); + numRunLens++; + i += run_length; + } + // Add cost of runLen compression + highCardinalityCost = count * (num_data_dims_ * bytes_per_dim_ - prefix_len_sum - 1) + 2 * numRunLens; + // +1 is the byte needed for storing the cardinality + lowCardinalityCost = leaf_cardinality.size() * (num_data_dims_ * bytes_per_dim_ - prefix_len_sum + 1); + } + return (lowCardinalityCost <= highCardinalityCost); + } + + void bkd_writer::build(int32_t nodeID, int32_t leafNodeOffset, + std::vector> &slices, + const std::shared_ptr &ordBitSet, + store::IndexOutput *out, + std::vector &minPackedValue, + std::vector &maxPackedValue, + std::vector &parentSplits, + std::vector &splitPackedValues, + std::vector &leafBlockFPs, + const std::vector> &toCloseHeroically) { + if (nodeID >= leafNodeOffset) { + + // Leaf node: write block + // We can write the block in any order so by default we write it sorted by the dimension that has the + // least number of unique bytes at commonPrefixLengths[dim], which makes compression more efficient + int32_t sorted_dim = 0; + int32_t sorted_dim_cardinality = std::numeric_limits::max(); + + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + //create a slice if it does not exist + bool created = false; + if (slices[dim] == nullptr) { + create_path_slice(slices, dim); + created = true; + } + if (std::dynamic_pointer_cast(slices[dim]->writer_) == nullptr) { + // Adversarial cases can cause this, e.g. very lopsided data, all equal points, such that we started + // offline, but then kept splitting only in one dimension, and so never had to rewrite into heap writer + PathSlicePtr slice = slices[dim]; + slices[dim] = switch_to_heap(slices[dim], toCloseHeroically); + if (created) { + slice->writer_->destroy(); + } + } + + PathSlicePtr source = slices[dim]; + + std::shared_ptr heap_source = std::dynamic_pointer_cast(source->writer_); + + // Find common prefix by comparing first and last values, already sorted in this dimension: + heap_source->read_packed_value(source->start_, scratch1_); + heap_source->read_packed_value(source->start_ + source->count_ - 1, scratch2_); + int32_t offset = dim * bytes_per_dim_; + common_prefix_lengths_[dim] = FutureArrays::Mismatch(scratch1_, offset, offset + bytes_per_dim_, scratch2_, offset, offset + bytes_per_dim_); + + if (common_prefix_lengths_[dim] == -1) + common_prefix_lengths_[dim] = bytes_per_dim_; + sorted_dim = dim; + /*int32_t prefix = common_prefix_lengths_[dim]; + if (prefix < bytes_per_dim_) { + int32_t cardinality = 1; + uint8_t previous = scratch1_[offset + prefix]; + for (int64_t i = 1; i < source->count_; ++i) { + heap_source->read_packed_value((source->start_ + i), scratch2_); + uint8_t b = scratch2_[offset + prefix]; + if (b != previous) { + cardinality++; + previous = b; + } + } + assert(cardinality <= 256); + if (cardinality < sorted_dim_cardinality) { + sorted_dim = dim; + sorted_dim_cardinality = cardinality; + } + }*/ + } + + PathSlicePtr data_dim_path_slice = nullptr; + + if (num_data_dims_ != num_index_dims_) { + std::shared_ptr heap_source = std::dynamic_pointer_cast(slices[0]->writer_); + auto from = (int32_t) slices[0]->start_; + int32_t to = from + (int32_t) slices[0]->count_; + std::fill(common_prefix_lengths_.begin() + num_index_dims_, + common_prefix_lengths_.begin() + num_index_dims_ + num_data_dims_, + bytes_per_dim_); + heap_source->read_packed_value(from, scratch1_); + for (int32_t i = from + 1; i < to; ++i) { + heap_source->read_packed_value(i, scratch2_); + for (int32_t dim = num_index_dims_; dim < num_data_dims_; dim++) { + int32_t offset = dim * bytes_per_dim_; + int32_t dimension_prefix_length = common_prefix_lengths_[dim]; + common_prefix_lengths_[dim] = FutureArrays::Mismatch(scratch1_, offset, offset + dimension_prefix_length, + scratch2_, offset, offset + dimension_prefix_length); + if (common_prefix_lengths_[dim] == -1) { + common_prefix_lengths_[dim] = dimension_prefix_length; + } + } + } + //handle case when all index dimensions contain the same value but not the data dimensions + if (common_prefix_lengths_[sorted_dim] == bytes_per_dim_) { + for (int32_t dim = num_index_dims_; dim < num_data_dims_; ++dim) { + if (common_prefix_lengths_[dim] != bytes_per_dim_) { + sorted_dim = dim; + //create a new slice in memory + data_dim_path_slice = switch_to_heap(slices[0], toCloseHeroically); + std::shared_ptr heap_writer = std::dynamic_pointer_cast(data_dim_path_slice->writer_); + sort_heap_point_writer(heap_writer, (int32_t) data_dim_path_slice->count_, sorted_dim); + break; + } + } + } + } + + PathSlicePtr source = (data_dim_path_slice != nullptr) ? data_dim_path_slice : slices[sorted_dim]; + + // We ensured that maxPointsSortInHeap was >= maxPointsInLeafNode, so we better be in heap at this point: + std::shared_ptr heap_source = std::dynamic_pointer_cast(source->writer_); + auto from = (int32_t) slices[0]->start_; + int32_t to = from + (int32_t) slices[0]->count_; + auto leaf_cardinality = heap_source->compute_cardinality(from, to, num_data_dims_, bytes_per_dim_, common_prefix_lengths_); + + // Save the block file pointer: + leafBlockFPs[nodeID - leafNodeOffset] = out->getFilePointer(); + //System.out.println(" write leaf block @ fp=" + out.getFilePointer()); + + // Write docIDs first, as their own chunk, so that at intersect time we can add all docIDs w/o + // loading the values: + int32_t count = source->count_; + // Write the full values: + scratch_bytes_ref2.length = packed_bytes_length_; + std::function packed_values = [&](int32_t i) -> BytesRef * { + heap_source->get_packed_value_slice((source->start_ + i), scratch_bytes_ref2); + return &scratch_bytes_ref2; + }; + assert(count > 0); + int32_t prefix_len_sum = std::accumulate(common_prefix_lengths_.begin(), common_prefix_lengths_.end(), 0); + bool low_cardinal = false; + if (prefix_len_sum == packed_bytes_length_) { + write_leaf_block_docs_bitmap(out, heap_source->doc_IDs_, source->start_, count); + } else { + low_cardinal = leaf_node_is_low_cardinality(common_prefix_lengths_, count, sorted_dim, packed_values, leaf_cardinality, prefix_len_sum); + // NOTE: just write runlen compressed docID, instead of bitmap chunks + // because we found that much faster. + write_leaf_block_docs(out, heap_source->doc_IDs_, source->start_, count); + } + + // TODO: minor opto: we don't really have to write the actual common prefixes, because BKDReader on recursing can regenerate it for us + // from the index, much like how terms dict does so from the FST: + + // Write the common prefixes: + write_common_prefixes(out, common_prefix_lengths_, scratch1_); + + write_leaf_block_packed_values(out, common_prefix_lengths_, count, sorted_dim, packed_values, prefix_len_sum, low_cardinal); + } else { + // Inner node: partition/recurse + int32_t split_dim; + if (num_index_dims_ > 1) { + //TODO:recomment here when we support multiple dimension + //split_dim = Split(min_packed_value, max_packed_value, parent_splits); + } else { + split_dim = 0; + } + + //We delete the created path slices at the same level + bool delete_split_dim = false; + if (slices[split_dim] == nullptr) { + create_path_slice(slices, split_dim); + delete_split_dim = true; + } + PathSlicePtr source = slices[split_dim]; + + assert(nodeID < (int32_t) splitPackedValues.size()); + + // How many points will be in the left tree: + int64_t right_count = source->count_ / 2; + int64_t left_count = source->count_ - right_count; + + // When we are on this dim, below, we clear the ordBitSet: + int32_t dim_to_clear = num_index_dims_ - 1; + while (dim_to_clear >= 0) { + if (slices[dim_to_clear] != nullptr && split_dim != dim_to_clear) { + break; + } + dim_to_clear--; + } + + auto split_value = (dim_to_clear == -1) ? mark_right_tree(right_count, split_dim, source, nullptr) : mark_right_tree(right_count, split_dim, source, ordBitSet); + if (split_value == nullptr) { + _CLTHROWA(CL_ERR_NullPointer, "split value pointer is null."); + } + int32_t address = nodeID * (1 + bytes_per_dim_); + splitPackedValues[address] = (uint8_t) split_dim; + std::copy(split_value, split_value + bytes_per_dim_, splitPackedValues.begin() + address + 1); + + // Partition all PathSlice that are not the split dim into sorted left and right sets, so we can recurse: + std::vector left_slices(num_index_dims_); + std::vector right_slices(num_index_dims_); + + std::vector min_split_packed_value(packed_index_bytes_length_); + std::copy(minPackedValue.begin(), minPackedValue.begin() + packed_index_bytes_length_, min_split_packed_value.begin()); + + std::vector max_split_packed_value(packed_index_bytes_length_); + std::copy(maxPackedValue.begin(), maxPackedValue.begin() + packed_index_bytes_length_, max_split_packed_value.begin()); + + + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + if (slices[dim] == nullptr) { + continue; + } + if (dim == split_dim) { + // No need to partition on this dim since it's a simple slice of the incoming already sorted slice, and we + // will re-use its shared reader when visiting it as we recurse: + left_slices[dim] = std::make_shared(source->writer_, source->start_, left_count); + right_slices[dim] = std::make_shared(source->writer_, source->start_ + left_count, right_count); + std::copy(split_value, split_value + bytes_per_dim_, min_split_packed_value.begin() + dim * bytes_per_dim_); + std::copy(split_value, split_value + bytes_per_dim_, max_split_packed_value.begin() + dim * bytes_per_dim_); + continue; + } + + // Not inside the try because we don't want to close this one now, so that after recursion is done, + // we will have done a singel full sweep of the file: + std::shared_ptr reader = slices[dim]->writer_->get_shared_reader(slices[dim]->start_, slices[dim]->count_, toCloseHeroically); + std::string desc = "left" + std::to_string(dim); + std::shared_ptr left_point_writer = get_point_writer(left_count, desc); + if (left_point_writer != nullptr) { + desc = "right" + std::to_string(dim); + std::shared_ptr right_point_writer = get_point_writer(source->count_ - left_count, desc); + + int64_t next_right_count = reader->split(source->count_, ordBitSet, left_point_writer, right_point_writer, dim == dim_to_clear); + if (right_count != next_right_count) + _CLTHROWA(CL_ERR_IllegalState, ("wrong number of points in split: expected=" + std::to_string(right_count) + " but actual=" + std::to_string(next_right_count)).c_str()); + + left_slices[dim] = std::make_shared(left_point_writer, 0, left_count); + right_slices[dim] = std::make_shared(right_point_writer, 0, right_count); + left_point_writer->close(); + right_point_writer->close(); + } + } + + parentSplits[split_dim]++; + // Recurse on left tree: + build(2 * nodeID, leafNodeOffset, left_slices, + ordBitSet, out, + minPackedValue, max_split_packed_value, parentSplits, + splitPackedValues, leafBlockFPs, toCloseHeroically); + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + // Don't destroy the dim we split on because we just re-used what our caller above gave us for that dim: + if (dim != split_dim && slices[dim] != nullptr) { + left_slices[dim]->writer_->destroy(); + } + } + + // TODO: we could "tail recurse" here? have our parent discard its refs as we recurse right? + // Recurse on right tree: + build(2 * nodeID + 1, leafNodeOffset, right_slices, + ordBitSet, out, + min_split_packed_value, maxPackedValue, parentSplits, + splitPackedValues, leafBlockFPs, toCloseHeroically); + for (int32_t dim = 0; dim < num_index_dims_; dim++) { + // Don't destroy the dim we split on because we just re-used what our caller above gave us for that dim: + if (dim != split_dim && slices[dim] != nullptr) { + right_slices[dim]->writer_->destroy(); + } + } + parentSplits[split_dim]--; + if (delete_split_dim) { + slices[split_dim]->writer_->destroy(); + } + } + } + void bkd_writer::create_path_slice(std::vector> &slices, int32_t dim) { + assert(slices[dim] == nullptr); + std::shared_ptr current = nullptr; + for (const std::shared_ptr &slice: slices) { + if (slice != nullptr) { + current = slice; + break; + } + } + if (current == nullptr) { + slices[dim] = std::make_shared(sort(dim), 0, point_count_); + } else { + slices[dim] = std::make_shared(sort(dim, current->writer_, current->start_, current->count_), 0, current->count_); + } + } + + std::shared_ptr bkd_writer::create_heap_point_writer_copy(const std::shared_ptr &writer, int64_t start, int64_t count) { + int32_t size = count; + std::shared_ptr point_writer = std::make_shared(size, size, packed_bytes_length_, long_ords_, single_value_per_doc_); + std::shared_ptr reader = writer->get_reader(start, count); + if (point_writer != nullptr && reader != nullptr) { + for (int64_t i = 0; i < count; i++) { + reader->next(); + point_writer->append(reader->packed_value_raw(), packed_bytes_length_, reader->ord(), reader->docId()); + } + return point_writer; + } + _CLTHROWA(CL_ERR_CorruptIndex, "point index corrupt."); + } + + + std::shared_ptr bkd_writer::sort(int32_t dim, const std::shared_ptr &writer, int64_t start, int64_t point_count) { + assert(dim >= 0 && dim < num_data_dims_); + auto w = std::dynamic_pointer_cast(writer); + if (w != nullptr) { + //TODO:check efficiency here + std::shared_ptr heap_point_writer = create_heap_point_writer_copy(w, start, point_count); + sort_heap_point_writer(heap_point_writer, point_count, dim); + // LOG_SF_INFO << "HeapPointWriter"; + return heap_point_writer; + } + return nullptr; + } + + // radix sort by value + std::shared_ptr bkd_writer::sort(int32_t dim) { + assert(dim >= 0 && dim < num_data_dims_); + if (heap_point_writer_ != nullptr) { + // TODO: try to use move to save some atomic reference increment and decrement. + std::shared_ptr sorted = std::move(heap_point_writer_); + sort_heap_point_writer(sorted, point_count_, dim); + sorted->close(); + heap_point_writer_ = nullptr; + // LOG_SF_INFO << "HeapPointWriter"; + return std::dynamic_pointer_cast(sorted); + } + return nullptr; + } + + void bkd_writer::sort_heap_point_writer(std::shared_ptr &writer, int32_t pointCount, int32_t dim) { + auto sorter = std::make_shared(shared_from_this().get(), writer.get(), dim, bytes_per_dim_ + 4); + sorter->sort(0, pointCount); + } + +}// namespace bkd +CL_NS_END diff --git a/src/core/CLucene/util/bkd/bkd_writer.h b/src/core/CLucene/util/bkd/bkd_writer.h new file mode 100644 index 00000000000..5a91a26668e --- /dev/null +++ b/src/core/CLucene/util/bkd/bkd_writer.h @@ -0,0 +1,180 @@ +#pragma once + +#include "CLucene/StdHeader.h" + +#include "CLucene/store/IndexInput.h" +#include "CLucene/store/IndexOutput.h" +#include "CLucene/util/FixedBitSet.h" +#include "CLucene/util/LongBitSet.h" +#include "CLucene/util/OfflineSorter.h" + +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexOutput.h" + +#include "heap_point_writer.h" + +#include +#include +#include +#include +#include +#include + +//namespace lucene { namespace store{ class RAMOutputStream; } } +CL_CLASS_DEF(store, RAMOutputStream) +CL_NS_DEF(util) + +namespace bkd { + //typedef std::vector>> ByteArrayList; + + template + using IntFunction = std::function; + + class bkd_writer : public std::enable_shared_from_this { + public: + static const int MAX_ARRAY_LENGTH = std::numeric_limits::max() - 1024; + static const int MAX_DIMS = 8; + static const std::wstring CODEC_NAME; + static const int VERSION_START = 0; + static const int VERSION_COMPRESSED_DOC_IDS = 1; + static const int VERSION_COMPRESSED_VALUES = 2; + static const int VERSION_IMPLICIT_SPLIT_DIM_1D = 3; + static const int VERSION_PACKED_INDEX = 4; + static const int VERSION_LEAF_STORES_BOUNDS = 5; + static const int VERSION_SELECTIVE_INDEXING = 6; + static const int VERSION_CURRENT = VERSION_SELECTIVE_INDEXING; + + public: + int32_t bytes_per_doc_; + int32_t num_data_dims_; + /** How many dimensions we are indexing in the internal nodes */ + int32_t num_index_dims_; + /** How many bytes each value in each dimension takes. */ + int32_t bytes_per_dim_; + /** numDataDims * bytesPerDim */ + int32_t packed_bytes_length_; + /** numIndexDims * bytesPerDim */ + int32_t packed_index_bytes_length_; + std::unique_ptr temp_dir_; + double max_mb_sort_in_heap_; + int32_t max_depth_; + int32_t max_points_in_leaf_node_; + int32_t max_points_sort_in_heap_; + /** Minimum per-dim values, packed */ + std::vector min_packed_value_; + /** Maximum per-dim values, packed */ + std::vector max_packed_value_; + int64_t point_count_ = 0; + /** true if we have so many values that we must write ords using long (8 bytes) instead of int (4 bytes) */ + bool long_ords_; + /** An upper bound on how many points the caller will add (includes deletions) */ + int64_t total_point_count_; + /** True if every document has at most one value. We specialize this case by not bothering to store the ord since it's redundant with docID. */ + bool single_value_per_doc_; + int32_t max_doc_; + std::vector scratch_diff_; + std::vector scratch1_; + std::vector scratch2_; + BytesRef scratch_bytes_ref2 = BytesRef(); + std::vector common_prefix_lengths_; + uint32_t docs_seen_; + std::shared_ptr heap_point_writer_; + + public: + class path_slice; + + public: + bkd_writer(int32_t maxDoc, int32_t numDataDims, + int32_t numIndexDims, int32_t bytesPerDim, int32_t maxPointsInLeafNode, double maxMBSortInHeap, + int64_t totalPointCount, bool singleValuePerDoc, int32_t maxDepth=8); + bkd_writer(int32_t maxDoc, int32_t numDataDims, + int32_t numIndexDims, int32_t bytesPerDim, int32_t maxPointsInLeafNode, double maxMBSortInHeap, + int64_t totalPointCount, bool singleValuePerDoc, bool longOrds, int32_t maxDepth=8); + + + static void verify_params(int32_t numDataDims, int32_t numIndexDims, int32_t maxPointsInLeafNode, + double maxMBSortInHeap, int64_t totalPointCount); + void check_max_leaf_node_count(int32_t num_leaves) const; + void add(std::vector &packedValue, int32_t docID); + void add(const uint8_t *packed_value, uint32_t value_len, int32_t doc_id); + int64_t finish(store::IndexOutput *out, store::IndexOutput *index_out); + /*void Build(int32_t nodeID, int32_t leafNodeOffset, + MutablePointValuesPtr reader, int32_t from, int32_t to, + std::shared_ptr& out, + std::vector &minPackedValue, std::vector &maxPackedValue, + std::vector &parentSplits, + std::vector &splitPackedValues, + std::vector &leafBlockFPs, + std::vector &spareDocIds);*/ + void build(int32_t nodeID, int32_t leafNodeOffset, + std::vector> &slices, + const std::shared_ptr &ordBitSet, + store::IndexOutput *out, + std::vector &minPackedValue, std::vector &maxPackedValue, + std::vector &parentSplits, + std::vector &splitPackedValues, + std::vector &leafBlockFPs, + const std::vector> &toCloseHeroically); + void create_path_slice(std::vector> &slices, int32_t dim); + std::shared_ptr sort(int32_t dim); + std::shared_ptr sort(int32_t dim, const std::shared_ptr &writer, int64_t start, int64_t point_count); + void sort_heap_point_writer(std::shared_ptr &writer, int32_t pointCount, int32_t dim); + std::shared_ptr create_heap_point_writer_copy(const std::shared_ptr &writer, int64_t start, int64_t count); + std::shared_ptr switch_to_heap(const std::shared_ptr &source, const std::vector> &toCloseHeroically); + static void write_leaf_block_docs(store::IndexOutput *out, std::vector &docIDs, int32_t start, int32_t count); + static void write_leaf_block_docs_bitmap(store::IndexOutput *out, std::vector &docIDs, int32_t start, int32_t count); + void write_common_prefixes(store::IndexOutput *out, std::vector &commonPrefixes, std::vector &packedValue) const; + void write_common_prefixes(store::IndexOutput *out, std::vector &commonPrefixes, std::vector &packedValue, int offset) const; + void write_index(store::IndexOutput *out, int32_t countPerLeaf, std::vector &leafBlockFPs, + std::vector &splitPackedValues); + void write_index(store::IndexOutput *out, int32_t countPerLeaf, int32_t numLeaves, std::vector &packedIndex); + int32_t recurse_pack_index(const std::shared_ptr &writeBuffer, std::vector &leafBlockFPs, + std::vector &splitPackedValues, int64_t minBlockFP, + ByteArrayList &blocks, int32_t nodeID, std::vector &lastSplitValues, + std::vector &negativeDeltas, bool isLeft) const; + std::shared_ptr> pack_index(std::vector &leaf_block_fps, + std::vector &split_packed_values) const; + static int32_t append_block(const std::shared_ptr &writeBuffer, ByteArrayList &blocks); + static int64_t get_left_most_leaf_blockFP(std::vector &leafBlockFPs, int32_t nodeID); + /*void write_leaf_block_packed_values(store::IndexOutput *out, std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, const IntFunction &packed_values, + const std::vector &leaf_cardinality);*/ + void write_leaf_block_packed_values(store::IndexOutput *out, + std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, + const IntFunction &packed_values, + int32_t prefix_len_sum, + bool low_cardinality); + void write_high_cardinality_leaf_block_packed_values(store::IndexOutput *out, std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, const IntFunction &packed_values, + int32_t compressed_byte_offset) const; + void write_low_cardinality_leaf_block_packed_values(store::IndexOutput *out, std::vector &common_prefix_lengths, + int32_t count, const IntFunction &packed_values); + static int32_t run_len(const IntFunction &packedValues, int32_t start, int32_t end, int32_t byteOffset); + void write_leaf_block_packed_values_range(store::IndexOutput *out, std::vector &commonPrefixLengths, + int32_t start, int32_t end, const IntFunction &packedValues) const; + int32_t split(std::vector &min_packed_value, std::vector &max_packed_value, std::vector &parent_splits); + const uint8_t *mark_right_tree(int64_t rightCount, int32_t splitDim, std::shared_ptr &source, const std::shared_ptr &ordBitSet) const; + std::shared_ptr get_point_writer(int64_t count, std::string &desc); + static void meta_finish(store::IndexOutput *out, int64_t fPointer, int32_t type); + bool leaf_node_is_low_cardinality(std::vector &common_prefix_lengths, + int32_t count, int32_t sorted_dim, + const IntFunction &packed_values, + const std::vector &leaf_cardinality, + int32_t prefix_len_sum) const; + }; + + class bkd_writer::path_slice { + public: + path_slice(std::shared_ptr writer, int64_t start, int64_t count) : writer_(std::move(writer)), + start_(start), + count_(count) {} + + public: + std::shared_ptr writer_; + int64_t start_; + int64_t count_; + }; + using PathSlicePtr = std::shared_ptr; +}// namespace bkd +CL_NS_END diff --git a/src/core/CLucene/util/bkd/docIds_writer.cpp b/src/core/CLucene/util/bkd/docIds_writer.cpp new file mode 100644 index 00000000000..e24f4c5154a --- /dev/null +++ b/src/core/CLucene/util/bkd/docIds_writer.cpp @@ -0,0 +1,247 @@ +#include "docIds_writer.h" + +#include "CLucene/debug/error.h" + +CL_NS_DEF2(util, bkd) + +void docIds_writer::write_doc_ids_bitmap(std::vector &docIds, int32_t start, int32_t count, store::IndexOutput *out){ + Roaring r; + for (int32_t i = 0; i < count; ++i) { + int32_t doc = docIds[start + i]; + r.add(doc); + } + r.runOptimize(); + auto bitmap_size = r.getSizeInBytes(false); + out->writeVInt(bitmap_size); + char *bitmap = new char[bitmap_size]; + r.write(bitmap, false); + out->writeBytes((const uint8_t*)bitmap, bitmap_size); + delete[] bitmap; +} + +void docIds_writer::write_doc_ids(std::vector &docIds, int32_t start, int32_t count, store::IndexOutput *out) { + bool sorted = true; + for (int32_t i = 1; i < count; ++i) { + if (docIds[start + i - 1] > docIds[start + i]) { + sorted = false; + break; + } + } + + if (sorted) { + out->writeByte((uint8_t) 0); + int32_t previous = 0; + for (int32_t i = 0; i < count; ++i) { + int32_t doc = docIds[start + i]; + out->writeVInt(doc - previous); + previous = doc; + } + } else { + int64_t max = 0; + for (int32_t i = 0; i < count; ++i) { + max |= (static_cast(docIds[start + i])); + } + + if (max <= 0xffffff) { + out->writeByte((uint8_t) 24); + for (int32_t i = 0; i < count; ++i) { + out->writeShort((short) (docIds[start + i] >> 8)); + out->writeByte((uint8_t) (docIds[start + i])); + } + } else { + out->writeByte((uint8_t) 32); + for (int32_t i = 0; i < count; ++i) { + out->writeInt(docIds[start + i]); + } + } + } +} + +void docIds_writer::read_bitmap_ints(store::IndexInput *in, int32_t count, std::vector &docIDs) { + auto size = in->readVInt(); + char buf[size]; + in->readBytes((uint8_t *) buf, size); + Roaring result = Roaring::read(buf, false); + int c = 0; + for (auto i: result) { + if (c <= count) { + docIDs[c] = i; + } + c++; + } +} + +void docIds_writer::read_bitmap(store::IndexInput *in, Roaring &r) { + auto size = in->readVInt(); + char buf[size]; + in->readBytes((uint8_t *) buf, size); + r = Roaring::read(buf, false); +} + +void docIds_writer::read_bitmap(store::IndexInput *in, bkd_reader::intersect_visitor *visitor){ + auto size = in->readVInt(); + char buf[size]; + in->readBytes((uint8_t *) buf, size); + visitor->visit(Roaring::read(buf, false)); +} + +void docIds_writer::read_low_cardinal_bitmap(store::IndexInput *in, bkd_reader::intersect_visitor *visitor){ + auto cardinality = in->readVInt(); + std::vector buf; + for(int i = 0; i < cardinality; ++i) { + auto size = in->readVInt(); + buf.resize(size); + in->readBytes((uint8_t *) buf.data(), size); + visitor->visit(Roaring::read(buf.data(), false)); + } +} + +void docIds_writer::read_low_cardinal_bitmap(store::IndexInput *in, bkd_docID_set_iterator* iter){ + auto cardinality = in->readVInt(); + //std::vector buf; + auto offset = iter->bitmap_set->docIDs.size(); + iter->bitmap_set->docIDs.resize(cardinality); + + for(int i = 0; i < cardinality; ++i) { + auto size = in->readVInt(); + std::vector buf(size); + //buf.resize(size); + //buf.resize(size); + in->readBytes((uint8_t *) buf.data(), size); + iter->bitmap_set->add(std::move(buf), i); + } + iter->bitmap_set->reset(0, cardinality); +} + +void docIds_writer::read_ints(store::IndexInput *in, int32_t count, bkd_docID_set_iterator* iter) { + int32_t bpv = in->readByte(); + switch (bpv) { + case 0: + iter->is_bitmap_set = false; + iter->docID_set->reset(0, count); + read_delta_vints(in, count, iter->docID_set->docIDs); + break; + case 1: { + iter->is_bitmap_set = true; + auto size = in->readVInt(); + std::vector buf(size); + in->readBytes((uint8_t *) buf.data(), size); + auto offset = 0;//iter->bitmap_set->docIDs.size(); + iter->bitmap_set->docIDs.resize(1); + + iter->bitmap_set->add(std::move(buf), 0); + iter->bitmap_set->reset(offset, 1); + break; + } + case 2: + iter->is_bitmap_set = true; + read_low_cardinal_bitmap(in, iter); + break; + case 32: + iter->is_bitmap_set = false; + iter->docID_set->reset(0, count); + read_ints32(in, count, iter->docID_set->docIDs); + break; + case 24: + iter->is_bitmap_set = false; + iter->docID_set->reset(0, count); + read_ints24(in, count, iter->docID_set->docIDs); + break; + default: + _CLTHROWA(CL_ERR_IO, ("Unsupported number of bits per value: " + std::to_string(bpv)).c_str()); + } +} + +void docIds_writer::read_ints32(store::IndexInput *in, int32_t count, std::vector &docIDs) { + for (int32_t i = 0; i < count; i++) { + docIDs[i] = in->readInt(); + } +} + +void docIds_writer::read_delta_vints(store::IndexInput *in, int32_t count, std::vector &docIDs) { + int32_t doc = 0; + for (int32_t i = 0; i < count; i++) { + doc += in->readVInt(); + docIDs[i] = doc; + } +} + +void docIds_writer::read_ints24(store::IndexInput *in, int32_t count, std::vector &docIDs) { + int32_t i = 0; + for (i = 0; i < count - 7; i += 8) { + int64_t l1 = in->readLong(); + int64_t l2 = in->readLong(); + int64_t l3 = in->readLong(); + docIDs[i] = (int) (static_cast(l1) >> 40); + docIDs[i + 1] = (int) (static_cast(l1) >> 16) & 0xffffff; + docIDs[i + 2] = (int) (((static_cast(l1) & 0xffff) << 8) | (static_cast(l2) >> 56)); + docIDs[i + 3] = (int) (static_cast(l2) >> 32) & 0xffffff; + docIDs[i + 4] = (int) (static_cast(l2) >> 8) & 0xffffff; + docIDs[i + 5] = (int) (((l2 & 0xff) << 16) | (static_cast(l3) >> 48)); + docIDs[i + 6] = (int) (static_cast(l3) >> 24) & 0xffffff; + docIDs[i + 7] = (int) l3 & 0xffffff; + } + for (; i < count; ++i) { + docIDs[i] = ((static_cast(in->readShort()) & 0xffff) << 8) | static_cast(in->readByte()); + } +} + +void docIds_writer::read_ints(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor) { + int32_t bpv = in->readByte(); + switch (bpv) { + case 0: + read_delta_vints(in, count, visitor); + break; + case 1: + read_bitmap(in, visitor); + break; + case 2: + read_low_cardinal_bitmap(in, visitor); + break; + case 32: + read_ints32(in, count, visitor); + break; + case 24: + read_ints24(in, count, visitor); + break; + default: + _CLTHROWA(CL_ERR_IO, ("Unsupported number of bits per value: " + std::to_string(bpv)).c_str()); + } +} + +void docIds_writer::read_ints32(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor) { + for (int32_t i = 0; i < count; i++) { + visitor->visit(in->readInt()); + } +} + +void docIds_writer::read_ints24(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor) { + int32_t i = 0; + for (i = 0; i < count - 7; i += 8) { + auto l1 = static_cast(in->readLong()); + auto l2 = static_cast(in->readLong()); + auto l3 = static_cast(in->readLong()); + visitor->visit((int) (l1 >> 40)); + visitor->visit((int) (l1 >> 16) & 0xffffff); + visitor->visit((int) (((l1 & 0xffff) << 8) | (l2 >> 56))); + visitor->visit((int) (l2 >> 32) & 0xffffff); + visitor->visit((int) (l2 >> 8) & 0xffffff); + visitor->visit((int) (((l2 & 0xff) << 16) | (l3 >> 48))); + visitor->visit((int) (l3 >> 24) & 0xffffff); + visitor->visit((int) l3 & 0xffffff); + } + + for (; i < count; ++i) { + visitor->visit(((in->readShort() & 0xffff) << 8) | (in->readByte() & 0xff)); + } +} + +void docIds_writer::read_delta_vints(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor) { + int32_t doc = 0; + for (int32_t i = 0; i < count; i++) { + doc += in->readVInt(); + visitor->visit(doc); + } +} + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/docIds_writer.h b/src/core/CLucene/util/bkd/docIds_writer.h new file mode 100644 index 00000000000..c17826a071c --- /dev/null +++ b/src/core/CLucene/util/bkd/docIds_writer.h @@ -0,0 +1,41 @@ +#pragma once +#include + +#include +#include + +//#include "CLucene/SharedHeader.h" +#include "CLucene.h" +#include "bkd_reader.h" +#include "CLucene/util/croaring/roaring.hh" + +//#include "CLucene/store/IndexInput.h" +//#include "CLucene/store/IndexOutput.h" + + +CL_NS_DEF2(util, bkd) +class docIds_writer { +private: + /* data */ +public: + docIds_writer() = default; + ~docIds_writer() = default; + static void read_bitmap(store::IndexInput *in, Roaring &r); + static void read_bitmap(store::IndexInput *in, bkd_reader::intersect_visitor *visitor); + static void read_low_cardinal_bitmap(store::IndexInput *in, bkd_docID_set_iterator* iter); + static void read_low_cardinal_bitmap(store::IndexInput *in, bkd_reader::intersect_visitor *visitor); + static void read_bitmap_ints(store::IndexInput *in, int32_t count, std::vector &docIDs); + static void write_doc_ids_bitmap(std::vector &docIds, int32_t start, int32_t count, store::IndexOutput *out); + static void write_doc_ids(std::vector &docIds, int32_t start, int32_t count, store::IndexOutput *out); + static void read_ints(store::IndexInput *in, int32_t count, bkd_docID_set_iterator* iter); + static void read_ints32(store::IndexInput *in, int32_t count, std::vector &docIDs); + static void read_ints(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor); + static void read_ints32(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor); + static void read_ints24(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor); + +private: + static void read_delta_vints(store::IndexInput *in, int32_t count, std::vector &docIDs); + static void read_ints24(store::IndexInput *in, int32_t count, std::vector &docIDs); + static void read_delta_vints(store::IndexInput *in, int32_t count, bkd_reader::intersect_visitor *visitor); +}; +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/heap_point_reader.cpp b/src/core/CLucene/util/bkd/heap_point_reader.cpp new file mode 100644 index 00000000000..9185eddc045 --- /dev/null +++ b/src/core/CLucene/util/bkd/heap_point_reader.cpp @@ -0,0 +1,79 @@ +#include "heap_point_reader.h" + +CL_NS_DEF(util) +namespace bkd { + + heap_point_reader::heap_point_reader(ByteArrayList* blocks, + int32_t valuesPerBlock, + int32_t packedBytesLength, + const std::vector &ords, + const std::vector &ordsLong, + std::vector *docIDs, + int32_t start, + int32_t end, + bool singleValuePerDoc) { + blocks_ = blocks; + values_per_block_ = valuesPerBlock; + single_value_per_doc_ = singleValuePerDoc; + ords_ = ords; + ords_long_ = ordsLong; + doc_ids_ = docIDs; + cur_read_ = start - 1; + end_ = end; + packed_bytes_length_ = packedBytesLength; + scratch_ = std::vector(packedBytesLength); + } + + /*void heap_point_reader::write_packed_value(int32_t index, const std::vector &bytes) { + int32_t block = index / values_per_block_; + int32_t blockIndex = index % values_per_block_; + while (blocks_->size() <= (uint32_t) block) { + //auto p_vec = std::make_shared>(values_per_block_ * packed_bytes_length_); + auto p_vec = std::vector(values_per_block_ * packed_bytes_length_); + blocks_->emplace_back(p_vec); + } + std::copy(bytes.begin(), + bytes.begin() + packed_bytes_length_, + blocks_[blockIndex].begin() + blockIndex * packed_bytes_length_); + }*/ + + void heap_point_reader::read_packed_value(int32_t index, std::vector &bytes) { + int32_t block = index / values_per_block_; + int32_t blockIndex = index % values_per_block_; + std::copy((*blocks_)[block].begin() + blockIndex * packed_bytes_length_, + (*blocks_)[block].begin() + blockIndex * packed_bytes_length_ + packed_bytes_length_, + bytes.begin()); + } + + bool heap_point_reader::next() { + cur_read_++; + return cur_read_ < end_; + } + + const std::vector &heap_point_reader::packed_value() { + read_packed_value(cur_read_, scratch_); + return scratch_; + } + + uint8_t* heap_point_reader::packed_value_raw() { + int32_t block = cur_read_ / values_per_block_; + int32_t blockIndex = cur_read_ % values_per_block_; + return (*blocks_)[block].data() + blockIndex * packed_bytes_length_; + } + + int32_t heap_point_reader::docId() { + return (*doc_ids_)[cur_read_]; + } + + int64_t heap_point_reader::ord() { + if (single_value_per_doc_) { + return (*doc_ids_)[cur_read_]; + } else if (ords_long_.size() > 0) { + return ords_long_[cur_read_]; + } else { + return ords_[cur_read_]; + } + } + +}// namespace bkd +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/heap_point_reader.h b/src/core/CLucene/util/bkd/heap_point_reader.h new file mode 100644 index 00000000000..5f0a9ea1748 --- /dev/null +++ b/src/core/CLucene/util/bkd/heap_point_reader.h @@ -0,0 +1,51 @@ +#pragma once + +#include "point_reader.h" +#include +#include + +CL_NS_DEF(util) + +namespace bkd { + //TODO:make vectorptr to unique_ptr + //typedef std::vector>> ByteArrayList; + typedef std::vector> ByteArrayList; + //using vectorptr = std::shared_ptr>; + + class heap_point_reader final : public point_reader { + public: + heap_point_reader(ByteArrayList *blocks, + int32_t valuesPerBlock, + int32_t packedBytesLength, + const std::vector &ords, + const std::vector &ordsLong, + std::vector *docIDs, + int32_t start, + int32_t end, + bool singleValuePerDoc); + + //void write_packed_value(int32_t index, const std::vector &bytes); + void read_packed_value(int32_t index, std::vector &bytes); + bool next() override; + const std::vector &packed_value() override; + uint8_t* packed_value_raw() override; + int32_t docId() override; + int64_t ord() override; + + public: + bool single_value_per_doc_; + int32_t values_per_block_; + int32_t packed_bytes_length_; + int32_t end_; + ByteArrayList* blocks_{}; + std::vector ords_long_; + std::vector ords_; + std::vector *doc_ids_; + std::vector scratch_; + + private: + int32_t cur_read_ = 0; + }; + +}// namespace bkd +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/heap_point_writer.cpp b/src/core/CLucene/util/bkd/heap_point_writer.cpp new file mode 100644 index 00000000000..0e7d09e1fbf --- /dev/null +++ b/src/core/CLucene/util/bkd/heap_point_writer.cpp @@ -0,0 +1,259 @@ +#include "heap_point_writer.h" +#include "CLucene/util/FutureArrays.h" +#include + +CL_NS_DEF(util) + +namespace bkd { + + heap_point_writer::heap_point_writer(int32_t initSize, int32_t maxSize, + uint32_t packedBytesLength, + bool longOrds, bool singleValuePerDoc) + : doc_IDs_(initSize, 0), next_write_(0), + closed_(false), max_size_(maxSize), packed_bytes_length_(packedBytesLength), + values_per_block_(std::max(1u, 4096 / packedBytesLength)), single_value_per_doc_(singleValuePerDoc) { + if (!singleValuePerDoc) { + if (longOrds) { + ords_long_ = std::vector(initSize, 0); + } else { + ords_ = std::vector(initSize, 0); + } + } + // 4k per page, unless each value is > 4k + cache_ = std::make_unique(); + cache1_ = std::make_unique(); + } + + void heap_point_writer::copy_from(heap_point_writer &other) { + if (doc_IDs_.size() < other.next_write_) { + //throw CLuceneError(CL_ERR_InvalidState, ("docIDs.length=" + std::to_string(doc_IDs_.size()) + " other.nextWrite=" + std::to_string(other.next_write_)).c_str()); + } + + std::copy(other.doc_IDs_.begin(), other.doc_IDs_.begin() + other.next_write_, doc_IDs_.begin()); + if (!single_value_per_doc_) { + if (other.ords_.size() != 0) { + assert(ords_.size() != 0); + std::copy(other.ords_.begin(), other.ords_.begin() + other.next_write_, ords_.begin()); + // System.arraycopy(other.ords, 0, ords, 0, other.nextWrite); + } else { + assert(ords_long_.size() != 0); + std::copy(other.ords_long_.begin(), other.ords_long_.begin() + other.next_write_, ords_long_.begin()); + // System.arraycopy(other.ordsLong, 0, ordsLong, 0, other.nextWrite); + } + } + + for (auto const &block: other.blocks_) { + blocks_.push_back(block);// (block.clone()); // 这里是浅拷贝,直接利用vector的赋值拷贝就行 + } + next_write_ = other.next_write_; + } + + std::vector heap_point_writer::compute_cardinality(int from, int to, int num_dims, int bytes_per_dim, std::vector &common_prefix_lengths) { + std::vector leafCardinality(1,1); + for (int i = from + 1; i < to; i++) { + for (int dim = 0; dim < num_dims; dim++) { + int start = dim * bytes_per_dim + common_prefix_lengths[dim]; + int end = dim * bytes_per_dim + bytes_per_dim; + int32_t block1 = i / values_per_block_; + int32_t blockIndex1 = i % values_per_block_; + int32_t block2 = (i - 1) / values_per_block_; + int32_t blockIndex2 = (i - 1) % values_per_block_; + if (FutureArrays::Mismatch(blocks_[block1], blockIndex1 * packed_bytes_length_ + start, blockIndex1 * packed_bytes_length_ + end, + blocks_[block2], blockIndex2 * packed_bytes_length_ + start, blockIndex2 * packed_bytes_length_ + end) != -1) { + leafCardinality.push_back(1); + break; + } else { + leafCardinality[leafCardinality.size() - 1]++; + } + } + } + return leafCardinality; + } + + void heap_point_writer::read_packed_value(int32_t index, std::vector &bytes) { + assert(bytes.size() == packed_bytes_length_); + int32_t block = index / values_per_block_; + int32_t blockIndex = index % values_per_block_; + auto start = blocks_.at(block).begin() + blockIndex * packed_bytes_length_; + std::copy(start, start + packed_bytes_length_, bytes.begin()); + //System.arraycopy(blocks.get(block), blockIndex * packedBytesLength, bytes, 0, packedBytesLength); + } + + std::shared_ptr heap_point_writer::read_packed_value2(int32_t index) { + int32_t block = index / values_per_block_; + int32_t blockIndex = index % values_per_block_; + cache1_->bytes = blocks_[block]; + cache1_->offset = blockIndex * packed_bytes_length_; + cache1_->length = packed_bytes_length_; + return cache1_; + } + +#if 1 + std::shared_ptr heap_point_writer::read_packed_value(int32_t index) { + int32_t block = index / values_per_block_; + int32_t blockIndex = index % values_per_block_; + cache_->bytes = blocks_[block]; + cache_->offset = blockIndex * packed_bytes_length_; + cache_->length = packed_bytes_length_; + return cache_; + } +#endif + + void heap_point_writer::get_packed_value_slice(int32_t index, BytesRef &result) { + uint32_t block = index / values_per_block_; + int blockIndex = index % values_per_block_; + //TODO: double free waring, need to figure it out. + result.bytes = blocks_.at(block); + result.offset = blockIndex * packed_bytes_length_; + assert(result.length == static_cast(packed_bytes_length_)); + } + + void heap_point_writer::write_packed_value(int32_t index, const uint8_t *bytes, uint32_t length) { + assert(length == packed_bytes_length_); + auto block = static_cast(index / values_per_block_); + int blockIndex = index % values_per_block_; + //System.out.println("writePackedValue: index=" + index + " bytes.length=" + bytes.length + " block=" + block + " blockIndex=" + blockIndex + " valuesPerBlock=" + valuesPerBlock); + while (blocks_.size() <= block) { + // If this is the last block, only allocate as large as necessary for maxSize: + int valuesInBlock = std::min(values_per_block_, (max_size_ - (static_cast(blocks_.size()) * values_per_block_))); + //blocks_.emplace_back(valuesInBlock * packed_bytes_length_); + blocks_.emplace_back(std::vector(valuesInBlock * packed_bytes_length_)); + //blocks_.emplace_back(std::vector(valuesInBlock * packed_bytes_length_)); + } + memcpy(blocks_.at(block).data() + blockIndex * packed_bytes_length_, bytes, packed_bytes_length_); + } + + + void heap_point_writer::write_packed_value(int32_t index, const std::vector &bytes) { + assert(bytes.size() == packed_bytes_length_); + uint32_t block = static_cast(index / values_per_block_); + int blockIndex = index % values_per_block_; + //System.out.println("writePackedValue: index=" + index + " bytes.length=" + bytes.length + " block=" + block + " blockIndex=" + blockIndex + " valuesPerBlock=" + valuesPerBlock); + while (blocks_.size() <= block) { + // If this is the last block, only allocate as large as necessary for maxSize: + int valuesInBlock = std::min(values_per_block_, (max_size_ - (static_cast(blocks_.size()) * values_per_block_))); + //blocks_.emplace_back(valuesInBlock * packed_bytes_length_); + blocks_.emplace_back(std::vector(valuesInBlock * packed_bytes_length_)); + //blocks_.emplace_back(std::vector(valuesInBlock * packed_bytes_length_)); + } + std::copy(bytes.begin(), + bytes.begin() + packed_bytes_length_, + blocks_.at(block).begin() + blockIndex * packed_bytes_length_); + //System.arraycopy(bytes, 0, blocks.get(block), blockIndex * packedBytesLength, packedBytesLength); + } + + void heap_point_writer::append(const std::vector &packedValue, int64_t ord, int32_t docID) { + assert(closed_ == false); + assert(packedValue.size() == packed_bytes_length_); + // TODO:it's inefficient to do vector clear here. + while (doc_IDs_.size() < (next_write_ + 1)) { + doc_IDs_.push_back(0); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_.push_back(0L); + } else { + ords_.push_back(0); + } + } + } + + write_packed_value(next_write_, packedValue); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_[next_write_] = ord; + } else { + assert(ord <= 0x7fffffff); + ords_[next_write_] = (int) ord; + } + } + doc_IDs_[next_write_] = docID; + next_write_++; + } + + void heap_point_writer::append(const uint8_t *packedValue, uint32_t value_length, int64_t ord, int32_t docID) { + assert(closed_ == false); + assert(value_length == packed_bytes_length_); + while (doc_IDs_.size() < (next_write_ + 1)) { + doc_IDs_.push_back(0); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_.push_back(0l); + } else { + ords_.push_back(0); + } + } + } + + write_packed_value(next_write_, packedValue, value_length); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_[next_write_] = ord; + } else { + assert(ord <= 0x7fffffff); + ords_[next_write_] = (int) ord; + } + } + doc_IDs_[next_write_] = docID; + next_write_++; + } + + void heap_point_writer::append(std::shared_ptr> &packedValue, int64_t ord, int32_t docID) { + assert(closed_ == false); + assert(packedValue->size() == packed_bytes_length_); + while (doc_IDs_.size() < (next_write_ + 1)) { + doc_IDs_.push_back(0); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_.push_back(0l); + } else { + ords_.push_back(0); + } + } + } + + write_packed_value(next_write_, packedValue); + if (!single_value_per_doc_) { + if (ords_long_.size() != 0) { + ords_long_[next_write_] = ord; + } else { + assert(ord <= 0x7fffffff); + ords_[next_write_] = (int) ord; + } + } + doc_IDs_[next_write_] = docID; + next_write_++; + } + + std::shared_ptr heap_point_writer::get_reader(int64_t start, int64_t length) { + assert((start + length) <= static_cast(doc_IDs_.size()));//: "start=" + start + " length=" + length + " docIDs.length=" + docIDs.length; + assert((start + length) <= next_write_); //: "start=" + start + " length=" + length + " nextWrite=" + nextWrite; + return std::make_shared(&blocks_, values_per_block_, packed_bytes_length_, + ords_, ords_long_, &doc_IDs_, (int32_t) start, + static_cast(start + length), single_value_per_doc_); + } + + std::shared_ptr heap_point_writer::get_shared_reader(int64_t start, int64_t length, + const std::vector> &toCloseHeroically) { + return std::make_shared(&blocks_, values_per_block_, packed_bytes_length_, ords_, ords_long_, &doc_IDs_, + (int32_t) start, next_write_, single_value_per_doc_); + } + + void heap_point_writer::close() { + closed_ = true; + } + + void heap_point_writer::destroy() { + } + + std::string heap_point_writer::to_string() { + return "HeapPointWriter(count=" + std::to_string(next_write_) + " alloc=" + std::to_string(doc_IDs_.size()) + ")"; + } + + + heap_point_writer::~heap_point_writer() { + close(); + } + +};// namespace bkd + +CL_NS_END diff --git a/src/core/CLucene/util/bkd/heap_point_writer.h b/src/core/CLucene/util/bkd/heap_point_writer.h new file mode 100644 index 00000000000..c6b75b92aeb --- /dev/null +++ b/src/core/CLucene/util/bkd/heap_point_writer.h @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include +#include + +#include "CLucene/util/BytesRef.h" + +#include "heap_point_reader.h" +#include "point_writer.h" + +CL_NS_DEF(util) + +namespace bkd +{ + //typedef std::vector>> ByteArrayList; + /** Utility class to write new points into in-heap arrays.**/ + class heap_point_writer : public point_writer { + + public: + std::vector doc_IDs_; + // std::shared_ptr> ords_long_; + // std::shared_ptr> ords_; + + std::vector ords_long_; + std::vector ords_; + uint32_t next_write_; + bool closed_; + int32_t max_size_; + + uint32_t packed_bytes_length_; + const int32_t values_per_block_; // std::max(1, 4096/packedBytesLength) + + const bool single_value_per_doc_; + // TODO: use shared_ptr to avoid vector copy + //using vectorptr = std::shared_ptr>; + //std::vector blocks_; // vector> + ByteArrayList blocks_; + std::shared_ptr cache_; + std::shared_ptr cache1_; + public: + heap_point_writer(int32_t initSize, int32_t maxSize, uint32_t packedBytesLength, + bool longOrds, bool singleValuePerDoc); + void copy_from(heap_point_writer &other); + inline void copy_from(std::shared_ptr &other){ copy_from(*other);}; + void read_packed_value(int32_t index, std::vector &bytes); + std::shared_ptr read_packed_value(int32_t index); + std::shared_ptr read_packed_value2(int32_t index); + void get_packed_value_slice(int32_t index, BytesRef& result); + void write_packed_value(int32_t index, std::shared_ptr> &bytes){ write_packed_value(index, *bytes);}; + void write_packed_value(int32_t index, const std::vector &bytes); + void write_packed_value(int32_t index, const uint8_t* bytes, uint32_t length); + std::vector compute_cardinality(int from, int to, int num_dims, int bytes_per_dim, std::vector &common_prefix_lengths); + void append(std::shared_ptr> &packedValue, int64_t ord, int32_t docID); + void append(const uint8_t* packedValue, uint32_t value_length, int64_t ord, int32_t docID); + void append(const std::vector &packedValue, int64_t ord, int32_t docID) override; + std::shared_ptr get_reader(int64_t start, int64_t length) override; + std::shared_ptr get_shared_reader(int64_t start, int64_t length, const std::vector> &toCloseHeroically) override; + void close() override; + void destroy() override; + std::string to_string(); + + ~heap_point_writer(); + }; +} // namespace bkd +CL_NS_END \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/index_tree.cpp b/src/core/CLucene/util/bkd/index_tree.cpp new file mode 100644 index 00000000000..201cc8d3f13 --- /dev/null +++ b/src/core/CLucene/util/bkd/index_tree.cpp @@ -0,0 +1,91 @@ +#include "bkd_reader.h" +#include "index_tree.h" + +CL_NS_DEF2(util,bkd) + +index_tree::index_tree(std::shared_ptr& reader) + : reader(reader) { + int32_t treeDepth = reader->get_tree_depth(); + split_packed_value_stack_ = std::vector>(treeDepth + 1); + node_id_ = 1; + level_ = 1; + split_packed_value_stack_[level_] = std::vector(reader->packed_index_bytes_length_); +} + +void index_tree::push_left() { + node_id_ *= 2; + level_++; + if (split_packed_value_stack_[level_].empty()) { + split_packed_value_stack_[level_] = std::vector(reader->packed_index_bytes_length_); + } +} + +void index_tree::push_right() { + node_id_ = node_id_ * 2 + 1; + level_++; + if (split_packed_value_stack_[level_].empty()) { + split_packed_value_stack_[level_] = std::vector(reader->packed_index_bytes_length_); + } +} + +void index_tree::pop() { + node_id_ /= 2; + level_--; + split_dim_ = -1; +} + +bool index_tree::is_leaf_node() { + return node_id_ >= reader->leaf_node_offset_; +} + +bool index_tree::node_exists() { + return node_id_ - reader->leaf_node_offset_ < reader->leaf_node_offset_; +} + +int32_t index_tree::get_node_id() { + return node_id_; +} + +std::vector&index_tree::get_split_packed_value() { + assert(is_leaf_node() == false); + assert(!split_packed_value_stack_[level_].empty()); + return split_packed_value_stack_[level_]; +} + +int32_t index_tree::get_split_dim() { + assert(is_leaf_node() == false); + return split_dim_; +} + +int32_t index_tree::get_num_leaves() { + int32_t leftMostLeafNode = node_id_; + while (leftMostLeafNode < reader->leaf_node_offset_) { + leftMostLeafNode = leftMostLeafNode * 2; + } + int32_t rightMostLeafNode = node_id_; + while (rightMostLeafNode < reader->leaf_node_offset_) { + rightMostLeafNode = rightMostLeafNode * 2 + 1; + } + int32_t numLeaves; + if (rightMostLeafNode >= leftMostLeafNode) { + numLeaves = rightMostLeafNode - leftMostLeafNode + 1; + } else { + numLeaves = rightMostLeafNode - leftMostLeafNode + 1 + reader->leaf_node_offset_; + } + assert(numLeaves == GetNumLeavesSlow(node_id_)); + return numLeaves; +} + +int32_t index_tree::GetNumLeavesSlow(int32_t node) { + if (node >= 2 * reader->leaf_node_offset_) { + return 0; + } else if (node >= reader->leaf_node_offset_) { + return 1; + } else { + int32_t leftCount = GetNumLeavesSlow(node * 2); + int32_t rightCount = GetNumLeavesSlow(node * 2 + 1); + return leftCount + rightCount; + } +} + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/index_tree.h b/src/core/CLucene/util/bkd/index_tree.h new file mode 100644 index 00000000000..d6342806135 --- /dev/null +++ b/src/core/CLucene/util/bkd/index_tree.h @@ -0,0 +1,41 @@ +#pragma once + +#include "CLucene/util/BytesRef.h" + +#include +#include + +CL_NS_DEF2(util,bkd) +class bkd_reader; +class index_tree { +protected: + explicit index_tree(std::shared_ptr& reader); + +public: + virtual void push_left(); + virtual void push_right(); + virtual void pop(); + virtual bool is_leaf_node(); + virtual bool node_exists(); + virtual int32_t get_node_id(); + virtual std::vector&get_split_packed_value(); + virtual int32_t get_split_dim(); + virtual int32_t get_num_leaves(); + virtual std::shared_ptr clone() = 0; + virtual std::shared_ptr get_split_dim_value() = 0; + virtual int64_t get_leaf_blockFP() = 0; + +private: + int32_t GetNumLeavesSlow(int32_t node); + +protected: + int32_t node_id_ = 0; + int32_t level_ = 0; + int32_t split_dim_ = 0; + std::vector> split_packed_value_stack_; + +protected: + std::shared_ptr reader; +}; + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/legacy_index_tree.cpp b/src/core/CLucene/util/bkd/legacy_index_tree.cpp new file mode 100644 index 00000000000..08471ace4de --- /dev/null +++ b/src/core/CLucene/util/bkd/legacy_index_tree.cpp @@ -0,0 +1,76 @@ +#include "bkd_reader.h" +#include "bkd_writer.h" +#include "legacy_index_tree.h" + +CL_NS_DEF2(util,bkd) +legacy_index_tree::legacy_index_tree(std::shared_ptr&& reader) + : index_tree(reader) { + split_dim_value_ = std::make_shared>(reader->bytes_per_dim_); + scratch_ = std::make_shared(); + set_node_data(); + //TODO: double free warning, need to figure it out. + scratch_->bytes = *split_dim_value_; + scratch_->length = reader->bytes_per_dim_; +} + +std::shared_ptr legacy_index_tree::clone() { + //TODO:std move reader make reader not available anymore. + auto index = std::make_shared(std::move(reader)); + index->node_id_ = node_id_; + index->level_ = level_; + index->split_dim_ = split_dim_; + index->leaf_block_fp_ = leaf_block_fp_; + index->split_packed_value_stack_[index->level_] = split_packed_value_stack_[index->level_]; + + return index; +} + +void legacy_index_tree::push_left() { + index_tree::push_left(); + set_node_data(); +} + +void legacy_index_tree::push_right() { + index_tree::push_right(); + set_node_data(); +} + +int64_t legacy_index_tree::get_leaf_blockFP() { + assert(is_leaf_node()); + return leaf_block_fp_; +} + +std::shared_ptr legacy_index_tree::get_split_dim_value() { + assert(is_leaf_node() == false); + return scratch_; +} + +void legacy_index_tree::pop() { + index_tree::pop(); + leaf_block_fp_ = -1; +} + +void legacy_index_tree::set_node_data() { + if (is_leaf_node()) { + leaf_block_fp_ = reader->leaf_block_fps_[node_id_ - reader->leaf_node_offset_]; + split_dim_ = -1; + } else { + leaf_block_fp_ = -1; + int32_t address = node_id_ * reader->bytes_per_index_entry_; + if (reader->num_index_dims_ == 1) { + split_dim_ = 0; + if (reader->version_ < bkd_writer::VERSION_IMPLICIT_SPLIT_DIM_1D) { + assert(reader->split_packed_values_[address] == 0); + address++; + } + } else { + split_dim_ = reader->split_packed_values_[address++] & 0xff; + } + std::copy(reader->split_packed_values_.begin() + address, + reader->split_packed_values_.begin() + address + reader->bytes_per_dim_, + split_dim_value_->begin()); + } +} + + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/legacy_index_tree.h b/src/core/CLucene/util/bkd/legacy_index_tree.h new file mode 100644 index 00000000000..c90ef9c72a4 --- /dev/null +++ b/src/core/CLucene/util/bkd/legacy_index_tree.h @@ -0,0 +1,29 @@ +#pragma once + +#include "index_tree.h" + +#include +#include + +CL_NS_DEF2(util,bkd) +class legacy_index_tree : public index_tree { +public: + explicit legacy_index_tree(std::shared_ptr&& reader); + + std::shared_ptr clone() override; + void push_left() override; + void push_right() override; + void pop() override; + int64_t get_leaf_blockFP() override; + std::shared_ptr get_split_dim_value() override; + +private: + void set_node_data(); + +private: + int64_t leaf_block_fp_ = 0; + std::shared_ptr> split_dim_value_; + std::shared_ptr scratch_{}; +}; + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/packed_index_tree.cpp b/src/core/CLucene/util/bkd/packed_index_tree.cpp new file mode 100644 index 00000000000..2b8c9ec6b9a --- /dev/null +++ b/src/core/CLucene/util/bkd/packed_index_tree.cpp @@ -0,0 +1,136 @@ +#include "bkd_reader.h" +#include "packed_index_tree.h" + +CL_NS_DEF2(util,bkd) + +packed_index_tree::packed_index_tree(std::shared_ptr&& reader) + : index_tree(reader) { + int32_t treeDepth = reader->get_tree_depth(); + leaf_block_fp_stack_ = std::vector(treeDepth + 1); + left_node_positions_ = std::vector(treeDepth + 1); + right_node_positions_ = std::vector(treeDepth + 1); + split_values_stack_ = std::vector>>(treeDepth + 1); + split_dims_ = std::vector(treeDepth + 1); + negative_deltas_ = std::vector(reader->num_index_dims_ * (treeDepth + 1)); + + //in_ = std::make_shared(reader->packed_index_); + //in_ = std::move(reader->clone_index_input); + in_ = reader->clone_index_input; + split_values_stack_[0] = std::make_shared>(reader->packed_index_bytes_length_); + read_node_data(false); + scratch_ = std::make_shared(); + scratch_->length = reader->bytes_per_dim_; +} + +std::shared_ptr packed_index_tree::clone() { + std::shared_ptr index = std::make_shared(std::move(reader)); + index->node_id_ = node_id_; + index->level_ = level_; + index->split_dim_ = split_dim_; + index->leaf_block_fp_stack_[level_] = leaf_block_fp_stack_[level_]; + index->left_node_positions_[level_] = left_node_positions_[level_]; + index->right_node_positions_[level_] = right_node_positions_[level_]; + index->split_values_stack_[index->level_] = split_values_stack_[index->level_]; + std::copy(negative_deltas_.begin() + level_ * reader->num_index_dims_, + negative_deltas_.begin() + level_ * reader->num_index_dims_ + reader->num_index_dims_, + index->negative_deltas_.begin() + level_ * reader->num_index_dims_); + index->split_dims_[level_] = split_dims_[level_]; + return index; +} + +void packed_index_tree::push_left() { + int32_t nodePosition = left_node_positions_[level_]; + index_tree::push_left(); + std::copy(negative_deltas_.begin() + (level_ - 1) * reader->num_index_dims_, + negative_deltas_.begin() + (level_ - 1) * reader->num_index_dims_ + reader->num_index_dims_, + negative_deltas_.begin() + level_ * reader->num_index_dims_); + assert(split_dim_ != -1); + negative_deltas_[level_ * reader->num_index_dims_ + split_dim_] = true; + //in_->setPosition(nodePosition); + in_->seek(nodePosition); + read_node_data(true); +} + +void packed_index_tree::push_right() { + int32_t nodePosition = right_node_positions_[level_]; + index_tree::push_right(); + std::copy(negative_deltas_.begin() + (level_ - 1) * reader->num_index_dims_, + negative_deltas_.begin() + (level_ - 1) * reader->num_index_dims_ + reader->num_index_dims_, + negative_deltas_.begin() + level_ * reader->num_index_dims_); + assert(split_dim_ != -1); + negative_deltas_[level_ * reader->num_index_dims_ + split_dim_] = false; + //in_->setPosition(nodePosition); + in_->seek(nodePosition); + read_node_data(false); +} + +void packed_index_tree::pop() { + index_tree::pop(); + split_dim_ = split_dims_[level_]; +} + +int64_t packed_index_tree::get_leaf_blockFP() { + assert(is_leaf_node()); + return leaf_block_fp_stack_[level_]; +} + +std::shared_ptr packed_index_tree::get_split_dim_value() { + assert(is_leaf_node() == false); + // TODO: double free warning here, need too figure it out. + scratch_->bytes = *split_values_stack_[level_]; + scratch_->offset = split_dim_ * reader->bytes_per_dim_; + return scratch_; +} + +void packed_index_tree::read_node_data(bool isLeft) { + leaf_block_fp_stack_[level_] = leaf_block_fp_stack_[level_ - 1]; + + if (!isLeft) { + leaf_block_fp_stack_[level_] += in_->readVLong(); + } + + if (is_leaf_node()) { + split_dim_ = -1; + } else { + int32_t code = in_->readVInt(); + split_dim_ = code % reader->num_index_dims_; + split_dims_[level_] = split_dim_; + code /= reader->num_index_dims_; + int32_t prefix = code % (1 + reader->bytes_per_dim_); + int32_t suffix = reader->bytes_per_dim_ - prefix; + + if (split_values_stack_[level_]==nullptr) { + split_values_stack_[level_] = std::make_shared>(reader->packed_index_bytes_length_); + } + std::copy(split_values_stack_[level_ - 1]->begin(), + split_values_stack_[level_ - 1]->begin() + reader->packed_index_bytes_length_, + split_values_stack_[level_]->begin()); + if (suffix > 0) { + int32_t firstDiffByteDelta = code / (1 + reader->bytes_per_dim_); + if (negative_deltas_[level_ * reader->num_index_dims_ + split_dim_]) { + firstDiffByteDelta = -firstDiffByteDelta; + } + int32_t oldByte = (*split_values_stack_[level_])[split_dim_ * reader->bytes_per_dim_ + prefix] & 0xFF; + (*split_values_stack_[level_])[split_dim_ * reader->bytes_per_dim_ + prefix] = static_cast(oldByte + firstDiffByteDelta); + in_->readBytes((split_values_stack_[level_])->data(), + suffix - 1, + split_dim_ * reader->bytes_per_dim_ + prefix + 1); + } else { + // our split value is == last split value in this dim, which can happen when there are many duplicate values + } + + int32_t leftNumBytes; + if (node_id_ * 2 < reader->leaf_node_offset_) { + leftNumBytes = in_->readVInt(); + } else { + leftNumBytes = 0; + } + + //left_node_positions_[level_] = in_->getPosition(); + left_node_positions_[level_] = in_->getFilePointer(); + + right_node_positions_[level_] = left_node_positions_[level_] + leftNumBytes; + } +} + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/packed_index_tree.h b/src/core/CLucene/util/bkd/packed_index_tree.h new file mode 100644 index 00000000000..439f4d32d7d --- /dev/null +++ b/src/core/CLucene/util/bkd/packed_index_tree.h @@ -0,0 +1,38 @@ +#pragma once +#include "CLucene/_ApiHeader.h" + +#include "index_tree.h" +//#include "CLucene/store/ByteArrayDataInput.h" +#include "CLucene/store/IndexInput.h" + +#include +#include + +CL_NS_DEF2(util,bkd) +class packed_index_tree : public index_tree { +public: + explicit packed_index_tree(std::shared_ptr&& reader); + + std::shared_ptr clone() override; + void push_left() override; + void push_right() override; + void pop() override; + int64_t get_leaf_blockFP() override; + std::shared_ptr get_split_dim_value() override; + +private: + void read_node_data(bool isLeft); + +private: + //std::shared_ptr in_; + std::shared_ptr in_; + std::vector leaf_block_fp_stack_; + std::vector left_node_positions_; + std::vector right_node_positions_; + std::vector split_dims_; + std::vector negative_deltas_; + std::vector>> split_values_stack_; + std::shared_ptr scratch_; +}; + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/point_reader.cpp b/src/core/CLucene/util/bkd/point_reader.cpp new file mode 100644 index 00000000000..462e4346360 --- /dev/null +++ b/src/core/CLucene/util/bkd/point_reader.cpp @@ -0,0 +1,46 @@ +#include "point_reader.h" + +#include "CLucene/debug/error.h" + +#include + +CL_NS_DEF2(util, bkd) +void point_reader::mark_ords(int64_t count, const std::shared_ptr &ordBitSet) { + for (int32_t i = 0; i < count; i++) { + bool result = next(); + if (!result) { + _CLTHROWA(CL_ERR_InvalidState, "did not see enough points from reader"); + } + assert(ordBitSet->Get(ord()) == false); + ordBitSet->Set(ord()); + } +} + +int64_t point_reader::split(int64_t count, + const std::shared_ptr &rightTree, + const std::shared_ptr &left, + const std::shared_ptr &right, + bool doClearBits) { + int64_t rightCount = 0; + for (int64_t i = 0; i < count; i++) { + bool result = next(); + assert(result); + //assert(Next()); + const std::vector &packedValue = packed_value(); + int64_t ordinal = ord(); + int32_t docID = docId(); + if (rightTree->Get(ordinal)) { + right->append(packedValue, ordinal, docID); + rightCount++; + if (doClearBits) { + rightTree->Clear(ordinal); + } + } else { + left->append(packedValue, ordinal, docID); + } + } + + return rightCount; +} + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/bkd/point_reader.h b/src/core/CLucene/util/bkd/point_reader.h new file mode 100644 index 00000000000..408652544d3 --- /dev/null +++ b/src/core/CLucene/util/bkd/point_reader.h @@ -0,0 +1,25 @@ +#pragma once + +#include "CLucene/StdHeader.h" +#include "CLucene/util/LongBitSet.h" +#include "point_writer.h" +#include +#include + + +CL_NS_DEF2(util, bkd) +class point_reader { +public: + virtual bool next() = 0; + virtual const std::vector &packed_value() = 0; + virtual uint8_t* packed_value_raw() = 0; + virtual int64_t ord() = 0; + virtual void mark_ords(int64_t count, const std::shared_ptr &ordBitSet); + virtual int docId() = 0; + virtual int64_t split(int64_t count, + const std::shared_ptr &rightTree, + const std::shared_ptr &left, + const std::shared_ptr &right, + bool doClearBits); +}; +CL_NS_END2 diff --git a/src/core/CLucene/util/bkd/point_writer.h b/src/core/CLucene/util/bkd/point_writer.h new file mode 100644 index 00000000000..0b28ce5edd4 --- /dev/null +++ b/src/core/CLucene/util/bkd/point_writer.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +CL_NS_DEF2(util,bkd) +class point_reader; + + class point_writer { + public: + point_writer(/* args */)= default;; + ~point_writer() { close(); }; + + /** add a new point */ + virtual void append(const std::vector &packed_value, int64_t ord, int32_t doc_id) = 0; + virtual void append(const uint8_t* packedValue, uint32_t value_length, int64_t ord, int32_t docID) = 0; + /** Returns a {@link PointReader} iterator to step through all previously added points */ + virtual std::shared_ptr get_reader(int64_t start_point, int64_t length) = 0; + /** Returns the single shared reader, used at multiple times during the recursion, to read previously added points */ + virtual std::shared_ptr get_shared_reader(int64_t start_point, int64_t length, const std::vector> &to_close_heroically) = 0; + /** Removes any temp files behind this writer */ + virtual void destroy() = 0; + virtual void close(){}; + }; + +CL_NS_END2 \ No newline at end of file diff --git a/src/core/CLucene/util/croaring/LICENSE b/src/core/CLucene/util/croaring/LICENSE new file mode 100644 index 00000000000..998d14b8f0b --- /dev/null +++ b/src/core/CLucene/util/croaring/LICENSE @@ -0,0 +1,235 @@ + The CRoaring project is under a dual license (Apache/MIT). +Users of the library may choose one or the other license. + +------------------ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016-2022 The CRoaring authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------------------------------- + +MIT License + +Copyright 2016-2022 The CRoaring authors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER diff --git a/src/core/CLucene/util/croaring/README.md b/src/core/CLucene/util/croaring/README.md new file mode 100644 index 00000000000..1d0c57ce589 --- /dev/null +++ b/src/core/CLucene/util/croaring/README.md @@ -0,0 +1,44 @@ +# CRoaringUnityBuild +Dumps of CRoaring unity builds (for convenience) + +This code is automatically generated from https://github.com/RoaringBitmap/CRoaring + +version: https://github.com/lemire/CRoaringUnityBuild/releases/tag/v0.6.0 + +## Building + +```bash + echo -e "#include \n int main(){Roaring x;}" > test.cpp && cc -c roaring.c -I. -std=c11 && c++ -o test test.cpp roaring.o -I. -std=c++11 +``` + +You need to compile and link `roaring.c` with your project: this is not a header-only build. + +## Usage (C) + +```C +#include +#include "roaring.c" +int main() { + roaring_bitmap_t *r1 = roaring_bitmap_create(); + for (uint32_t i = 100; i < 1000; i++) roaring_bitmap_add(r1, i); + printf("cardinality = %d\n", (int) roaring_bitmap_get_cardinality(r1)); + roaring_bitmap_free(r1); + return 0; +} +``` +## Usage (C++) + + +```C++ +#include +#include "roaring.hh" +#include "roaring.c" +int main() { + Roaring r1; + for (uint32_t i = 100; i < 1000; i++) { + r1.add(i); + } + std::cout << "cardinality = " << r1.cardinality() << std::endl; +  return 0; +} +``` diff --git a/src/core/CLucene/util/croaring/roaring.c b/src/core/CLucene/util/croaring/roaring.c new file mode 100644 index 00000000000..0dd2af56c37 --- /dev/null +++ b/src/core/CLucene/util/croaring/roaring.c @@ -0,0 +1,19542 @@ +// !!! DO NOT EDIT - THIS IS AN AUTO-GENERATED FILE !!! +// Created by amalgamation.sh on Wed 20 Jul 2022 16:25:25 EDT + +/* + * The CRoaring project is under a dual license (Apache/MIT). + * Users of the library may choose one or the other license. + */ +/* + * Copyright 2016-2022 The CRoaring authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * MIT License + * + * Copyright 2016-2022 The CRoaring authors + * + * Permission is hereby granted, free of charge, to any + * person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the + * Software without restriction, including without + * limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE + * + * SPDX-License-Identifier: MIT + */ + +#include "roaring.h" + +/* used for http://dmalloc.com/ Dmalloc - Debug Malloc Library */ +#ifdef DMALLOC +#include "dmalloc.h" +#endif + +#include "roaring.h" /* include public API definitions */ +/* begin file include/roaring/isadetection.h */ +/* From +https://github.com/endorno/pytorch/blob/master/torch/lib/TH/generic/simd/simd.h +Highly modified. + +Copyright (c) 2016- Facebook, Inc (Adam Paszke) +Copyright (c) 2014- Facebook, Inc (Soumith Chintala) +Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) +Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) +Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) +Copyright (c) 2011-2013 NYU (Clement Farabet) +Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, +Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute +(Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, +Samy Bengio, Johnny Mariethoz) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the names of Facebook, Deepmind Technologies, NYU, NEC Laboratories +America and IDIAP Research Institute nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ROARING_ISADETECTION_H +#define ROARING_ISADETECTION_H + +#include +#include +#include +#if defined(_MSC_VER) +#include +#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) +#include +#endif // defined(_MSC_VER) + + +enum croaring_instruction_set { + CROARING_DEFAULT = 0x0, + CROARING_NEON = 0x1, + CROARING_AVX2 = 0x4, + CROARING_SSE42 = 0x8, + CROARING_PCLMULQDQ = 0x10, + CROARING_BMI1 = 0x20, + CROARING_BMI2 = 0x40, + CROARING_ALTIVEC = 0x80, + CROARING_UNINITIALIZED = 0x8000 +}; + +#if defined(__PPC64__) + +static inline uint32_t dynamic_croaring_detect_supported_architectures() { + return CROARING_ALTIVEC; +} + +#elif defined(__arm__) || defined(__aarch64__) // incl. armel, armhf, arm64 + +#if defined(__ARM_NEON) + +static inline uint32_t dynamic_croaring_detect_supported_architectures() { + return CROARING_NEON; +} + +#else // ARM without NEON + +static inline uint32_t dynamic_croaring_detect_supported_architectures() { + return CROARING_DEFAULT; +} + +#endif + +#elif defined(__x86_64__) || defined(_M_AMD64) // x64 + + + + +static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, + uint32_t *edx) { + +#if defined(_MSC_VER) + int cpu_info[4]; + __cpuid(cpu_info, *eax); + *eax = cpu_info[0]; + *ebx = cpu_info[1]; + *ecx = cpu_info[2]; + *edx = cpu_info[3]; +#elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) + uint32_t level = *eax; + __get_cpuid(level, eax, ebx, ecx, edx); +#else + uint32_t a = *eax, b, c = *ecx, d; + __asm__("cpuid\n\t" : "+a"(a), "=b"(b), "+c"(c), "=d"(d)); + *eax = a; + *ebx = b; + *ecx = c; + *edx = d; +#endif +} + +static inline uint32_t dynamic_croaring_detect_supported_architectures() { + uint32_t eax, ebx, ecx, edx; + uint32_t host_isa = 0x0; + // Can be found on Intel ISA Reference for CPUID + static uint32_t cpuid_avx2_bit = 1 << 5; ///< @private Bit 5 of EBX for EAX=0x7 + static uint32_t cpuid_bmi1_bit = 1 << 3; ///< @private bit 3 of EBX for EAX=0x7 + static uint32_t cpuid_bmi2_bit = 1 << 8; ///< @private bit 8 of EBX for EAX=0x7 + static uint32_t cpuid_sse42_bit = 1 << 20; ///< @private bit 20 of ECX for EAX=0x1 + static uint32_t cpuid_pclmulqdq_bit = 1 << 1; ///< @private bit 1 of ECX for EAX=0x1 + // ECX for EAX=0x7 + eax = 0x7; + ecx = 0x0; + cpuid(&eax, &ebx, &ecx, &edx); + if (ebx & cpuid_avx2_bit) { + host_isa |= CROARING_AVX2; + } + if (ebx & cpuid_bmi1_bit) { + host_isa |= CROARING_BMI1; + } + + if (ebx & cpuid_bmi2_bit) { + host_isa |= CROARING_BMI2; + } + + // EBX for EAX=0x1 + eax = 0x1; + cpuid(&eax, &ebx, &ecx, &edx); + + if (ecx & cpuid_sse42_bit) { + host_isa |= CROARING_SSE42; + } + + if (ecx & cpuid_pclmulqdq_bit) { + host_isa |= CROARING_PCLMULQDQ; + } + + return host_isa; +} +#else // fallback + + +static inline uint32_t dynamic_croaring_detect_supported_architectures() { + return CROARING_DEFAULT; +} + + +#endif // end SIMD extension detection code + + +#if defined(__x86_64__) || defined(_M_AMD64) // x64 + +#if defined(__cplusplus) +#include +static inline uint32_t croaring_detect_supported_architectures() { + static std::atomic buffer{CROARING_UNINITIALIZED}; + if(buffer == CROARING_UNINITIALIZED) { + buffer = dynamic_croaring_detect_supported_architectures(); + } + return buffer; +} +#elif defined(_MSC_VER) && !defined(__clang__) +// Visual Studio does not support C11 atomics. +static inline uint32_t croaring_detect_supported_architectures() { + static int buffer = CROARING_UNINITIALIZED; + if(buffer == CROARING_UNINITIALIZED) { + buffer = dynamic_croaring_detect_supported_architectures(); + } + return buffer; +} +#else // defined(__cplusplus) and defined(_MSC_VER) && !defined(__clang__) +#include +static inline uint32_t croaring_detect_supported_architectures() { + static _Atomic int buffer = CROARING_UNINITIALIZED; + if(buffer == CROARING_UNINITIALIZED) { + buffer = dynamic_croaring_detect_supported_architectures(); + } + return buffer; +} +#endif // defined(_MSC_VER) && !defined(__clang__) + +#ifdef ROARING_DISABLE_AVX +static inline bool croaring_avx2() { + return false; +} +#elif defined(__AVX2__) +static inline bool croaring_avx2() { + return true; +} +#else +static inline bool croaring_avx2() { + return (croaring_detect_supported_architectures() & CROARING_AVX2) == CROARING_AVX2; +} +#endif + + +#else // defined(__x86_64__) || defined(_M_AMD64) // x64 + +static inline bool croaring_avx2() { + return false; +} + +static inline uint32_t croaring_detect_supported_architectures() { + // no runtime dispatch + return dynamic_croaring_detect_supported_architectures(); +} +#endif // defined(__x86_64__) || defined(_M_AMD64) // x64 + +#endif // ROARING_ISADETECTION_H +/* end file include/roaring/isadetection.h */ +/* begin file include/roaring/portability.h */ +/* + * portability.h + * + */ + +#ifndef INCLUDE_PORTABILITY_H_ +#define INCLUDE_PORTABILITY_H_ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif // _GNU_SOURCE +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS 1 +#endif // __STDC_FORMAT_MACROS + +#if !(defined(_POSIX_C_SOURCE)) || (_POSIX_C_SOURCE < 200809L) +#define _POSIX_C_SOURCE 200809L +#endif // !(defined(_POSIX_C_SOURCE)) || (_POSIX_C_SOURCE < 200809L) +#if !(defined(_XOPEN_SOURCE)) || (_XOPEN_SOURCE < 700) +#define _XOPEN_SOURCE 700 +#endif // !(defined(_XOPEN_SOURCE)) || (_XOPEN_SOURCE < 700) + +#include +#include +#include // will provide posix_memalign with _POSIX_C_SOURCE as defined above +#if !(defined(__APPLE__)) && !(defined(__FreeBSD__)) +#include // this should never be needed but there are some reports that it is needed. +#endif + +#ifdef __cplusplus +extern "C" { // portability definitions are in global scope, not a namespace +#endif + +#if defined(_MSC_VER) && !defined(__clang__) && !defined(_WIN64) && !defined(ROARING_ACK_32BIT) +#pragma message( \ + "You appear to be attempting a 32-bit build under Visual Studio. We recommend a 64-bit build instead.") +#endif + +#if defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ != 8 +#error This code assumes 64-bit long longs (by use of the GCC intrinsics). Your system is not currently supported. +#endif + +#if defined(_MSC_VER) +#define __restrict__ __restrict +#endif // defined(_MSC_VER + + + +#if defined(__x86_64__) || defined(_M_X64) +// we have an x64 processor +#define CROARING_IS_X64 + +#if defined(_MSC_VER) && (_MSC_VER < 1910) +// Old visual studio systems won't support AVX2 well. +#undef CROARING_IS_X64 +#endif + +#if defined(__clang_major__) && (__clang_major__<= 8) && !defined(__AVX2__) +// Older versions of clang have a bug affecting us +// https://stackoverflow.com/questions/57228537/how-does-one-use-pragma-clang-attribute-push-with-c-namespaces +#undef CROARING_IS_X64 +#endif + +#ifdef ROARING_DISABLE_X64 +#undef CROARING_IS_X64 +#endif +// we include the intrinsic header +#ifndef _MSC_VER +/* Non-Microsoft C/C++-compatible compiler */ +#include // on some recent GCC, this will declare posix_memalign +#endif // _MSC_VER +#endif // defined(__x86_64__) || defined(_M_X64) + +#if !defined(USENEON) && !defined(DISABLENEON) && defined(__ARM_NEON) +# define USENEON +#endif +#if defined(USENEON) +# include +#endif + +#ifndef _MSC_VER +/* Non-Microsoft C/C++-compatible compiler, assumes that it supports inline + * assembly */ +#define ROARING_INLINE_ASM +#endif // _MSC_VER + + +#ifdef _MSC_VER +/* Microsoft C/C++-compatible compiler */ +#include + +#ifndef __clang__ // if one compiles with MSVC *with* clang, then these + // intrinsics are defined!!! +// sadly there is no way to check whether we are missing these intrinsics +// specifically. + +/* wrappers for Visual Studio built-ins that look like gcc built-ins */ +/* result might be undefined when input_num is zero */ +inline int __builtin_ctzll(unsigned long long input_num) { + unsigned long index; +#ifdef _WIN64 // highly recommended!!! + _BitScanForward64(&index, input_num); +#else // if we must support 32-bit Windows + if ((uint32_t)input_num != 0) { + _BitScanForward(&index, (uint32_t)input_num); + } else { + _BitScanForward(&index, (uint32_t)(input_num >> 32)); + index += 32; + } +#endif + return index; +} + +/* result might be undefined when input_num is zero */ +inline int __builtin_clzll(unsigned long long input_num) { + unsigned long index; +#ifdef _WIN64 // highly recommended!!! + _BitScanReverse64(&index, input_num); +#else // if we must support 32-bit Windows + if (input_num > 0xFFFFFFFF) { + _BitScanReverse(&index, (uint32_t)(input_num >> 32)); + index += 32; + } else { + _BitScanReverse(&index, (uint32_t)(input_num)); + } +#endif + return 63 - index; +} + + +/* software implementation avoids POPCNT */ +/*static inline int __builtin_popcountll(unsigned long long input_num) { + const uint64_t m1 = 0x5555555555555555; //binary: 0101... + const uint64_t m2 = 0x3333333333333333; //binary: 00110011.. + const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ... + const uint64_t h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3... + + input_num -= (input_num >> 1) & m1; + input_num = (input_num & m2) + ((input_num >> 2) & m2); + input_num = (input_num + (input_num >> 4)) & m4; + return (input_num * h01) >> 56; +}*/ + +/* Use #define so this is effective even under /Ob0 (no inline) */ +#define __builtin_unreachable() __assume(0) +#endif + +#endif + +#if defined(_MSC_VER) +#define ALIGNED(x) __declspec(align(x)) +#else +#if defined(__GNUC__) +#define ALIGNED(x) __attribute__((aligned(x))) +#endif +#endif + +#ifdef __GNUC__ +#define WARN_UNUSED __attribute__((warn_unused_result)) +#else +#define WARN_UNUSED +#endif + +#define IS_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100) + +static inline int hammingbackup(uint64_t x) { + uint64_t c1 = UINT64_C(0x5555555555555555); + uint64_t c2 = UINT64_C(0x3333333333333333); + uint64_t c4 = UINT64_C(0x0F0F0F0F0F0F0F0F); + x -= (x >> 1) & c1; + x = (( x >> 2) & c2) + (x & c2); x=(x +(x>>4))&c4; + x *= UINT64_C(0x0101010101010101); + return x >> 56; +} + +static inline int hamming(uint64_t x) { +#if defined(_WIN64) && defined(_MSC_VER) && !defined(__clang__) +#ifdef _M_ARM64 + return hammingbackup(x); + // (int) _CountOneBits64(x); is unavailable +#else // _M_ARM64 + return (int) __popcnt64(x); +#endif // _M_ARM64 +#elif defined(_WIN32) && defined(_MSC_VER) && !defined(__clang__) +#ifdef _M_ARM + return hammingbackup(x); + // _CountOneBits is unavailable +#else // _M_ARM + return (int) __popcnt(( unsigned int)x) + (int) __popcnt(( unsigned int)(x>>32)); +#endif // _M_ARM +#else + return __builtin_popcountll(x); +#endif +} + +#ifndef UINT64_C +#define UINT64_C(c) (c##ULL) +#endif // UINT64_C + +#ifndef UINT32_C +#define UINT32_C(c) (c##UL) +#endif // UINT32_C + +#ifdef __cplusplus +} // extern "C" { +#endif // __cplusplus + + +// this is almost standard? +#undef STRINGIFY_IMPLEMENTATION_ +#undef STRINGIFY +#define STRINGIFY_IMPLEMENTATION_(a) #a +#define STRINGIFY(a) STRINGIFY_IMPLEMENTATION_(a) + +// Our fast kernels require 64-bit systems. +// +// On 32-bit x86, we lack 64-bit popcnt, lzcnt, blsr instructions. +// Furthermore, the number of SIMD registers is reduced. +// +// On 32-bit ARM, we would have smaller registers. +// +// The library should still have the fallback kernel. It is +// slower, but it should run everywhere. + +// +// Enable valid runtime implementations, and select CROARING_BUILTIN_IMPLEMENTATION +// + +// We are going to use runtime dispatch. +#ifdef CROARING_IS_X64 +#ifdef __clang__ +// clang does not have GCC push pop +// warning: clang attribute push can't be used within a namespace in clang up +// til 8.0 so CROARING_TARGET_REGION and CROARING_UNTARGET_REGION must be *outside* of a +// namespace. +#define CROARING_TARGET_REGION(T) \ + _Pragma(STRINGIFY( \ + clang attribute push(__attribute__((target(T))), apply_to = function))) +#define CROARING_UNTARGET_REGION _Pragma("clang attribute pop") +#elif defined(__GNUC__) +// GCC is easier +#define CROARING_TARGET_REGION(T) \ + _Pragma("GCC push_options") _Pragma(STRINGIFY(GCC target(T))) +#define CROARING_UNTARGET_REGION _Pragma("GCC pop_options") +#endif // clang then gcc + +#endif // CROARING_IS_X64 + +// Default target region macros don't do anything. +#ifndef CROARING_TARGET_REGION +#define CROARING_TARGET_REGION(T) +#define CROARING_UNTARGET_REGION +#endif + +#define CROARING_TARGET_AVX2 CROARING_TARGET_REGION("avx2,bmi,pclmul,lzcnt") + +#ifdef __AVX2__ +// No need for runtime dispatching. +// It is unnecessary and harmful to old clang to tag regions. +#undef CROARING_TARGET_AVX2 +#define CROARING_TARGET_AVX2 +#undef CROARING_UNTARGET_REGION +#define CROARING_UNTARGET_REGION +#endif + +#endif /* INCLUDE_PORTABILITY_H_ */ +/* end file include/roaring/portability.h */ +/* begin file include/roaring/containers/perfparameters.h */ +#ifndef PERFPARAMETERS_H_ +#define PERFPARAMETERS_H_ + +#include + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/** +During lazy computations, we can transform array containers into bitset +containers as +long as we can expect them to have ARRAY_LAZY_LOWERBOUND values. +*/ +enum { ARRAY_LAZY_LOWERBOUND = 1024 }; + +/* default initial size of a run container + setting it to zero delays the malloc.*/ +enum { RUN_DEFAULT_INIT_SIZE = 0 }; + +/* default initial size of an array container + setting it to zero delays the malloc */ +enum { ARRAY_DEFAULT_INIT_SIZE = 0 }; + +/* automatic bitset conversion during lazy or */ +#ifndef LAZY_OR_BITSET_CONVERSION +#define LAZY_OR_BITSET_CONVERSION true +#endif + +/* automatically attempt to convert a bitset to a full run during lazy + * evaluation */ +#ifndef LAZY_OR_BITSET_CONVERSION_TO_FULL +#define LAZY_OR_BITSET_CONVERSION_TO_FULL true +#endif + +/* automatically attempt to convert a bitset to a full run */ +#ifndef OR_BITSET_CONVERSION_TO_FULL +#define OR_BITSET_CONVERSION_TO_FULL true +#endif + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif +/* end file include/roaring/containers/perfparameters.h */ +/* begin file include/roaring/containers/container_defs.h */ +/* + * container_defs.h + * + * Unlike containers.h (which is a file aggregating all the container includes, + * like array.h, bitset.h, and run.h) this is a file included BY those headers + * to do things like define the container base class `container_t`. + */ + +#ifndef INCLUDE_CONTAINERS_CONTAINER_DEFS_H_ +#define INCLUDE_CONTAINERS_CONTAINER_DEFS_H_ + +#ifdef __cplusplus + #include // used by casting helper for compile-time check +#endif + +// The preferences are a separate file to separate out tweakable parameters + +#ifdef __cplusplus +namespace roaring { namespace internal { // No extern "C" (contains template) +#endif + + +/* + * Since roaring_array_t's definition is not opaque, the container type is + * part of the API. If it's not going to be `void*` then it needs a name, and + * expectations are to prefix C library-exported names with `roaring_` etc. + * + * Rather than force the whole codebase to use the name `roaring_container_t`, + * the few API appearances use the macro ROARING_CONTAINER_T. Those includes + * are prior to containers.h, so make a short private alias of `container_t`. + * Then undefine the awkward macro so it's not used any more than it has to be. + */ +typedef ROARING_CONTAINER_T container_t; +#undef ROARING_CONTAINER_T + + +/* + * See ROARING_CONTAINER_T for notes on using container_t as a base class. + * This macro helps make the following pattern look nicer: + * + * #ifdef __cplusplus + * struct roaring_array_s : public container_t { + * #else + * struct roaring_array_s { + * #endif + * int32_t cardinality; + * int32_t capacity; + * uint16_t *array; + * } + */ +#if defined(__cplusplus) + #define STRUCT_CONTAINER(name) \ + struct name : public container_t /* { ... } */ +#else + #define STRUCT_CONTAINER(name) \ + struct name /* { ... } */ +#endif + + +/** + * Since container_t* is not void* in C++, "dangerous" casts are not needed to + * downcast; only a static_cast<> is needed. Define a macro for static casting + * which helps make casts more visible, and catches problems at compile-time + * when building the C sources in C++ mode: + * + * void some_func(container_t **c, ...) { // double pointer, not single + * array_container_t *ac1 = (array_container_t *)(c); // uncaught!! + * + * array_container_t *ac2 = CAST(array_container_t *, c) // C++ errors + * array_container_t *ac3 = CAST_array(c); // shorthand for #2, errors + * } + * + * Trickier to do is a cast from `container**` to `array_container_t**`. This + * needs a reinterpret_cast<>, which sacrifices safety...so a template is used + * leveraging to make sure it's legal in the C++ build. + */ +#ifdef __cplusplus + #define CAST(type,value) static_cast(value) + #define movable_CAST(type,value) movable_CAST_HELPER(value) + + template + PPDerived movable_CAST_HELPER(Base **ptr_to_ptr) { + typedef typename std::remove_pointer::type PDerived; + typedef typename std::remove_pointer::type Derived; + static_assert( + std::is_base_of::value, + "use movable_CAST() for container_t** => xxx_container_t**" + ); + return reinterpret_cast(ptr_to_ptr); + } +#else + #define CAST(type,value) ((type)value) + #define movable_CAST(type, value) ((type)value) +#endif + +// Use for converting e.g. an `array_container_t**` to a `container_t**` +// +#define movable_CAST_base(c) movable_CAST(container_t **, c) + + +#ifdef __cplusplus +} } // namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_CONTAINER_DEFS_H_ */ +/* end file include/roaring/containers/container_defs.h */ +/* begin file include/roaring/array_util.h */ +#ifndef ARRAY_UTIL_H +#define ARRAY_UTIL_H + +#include // for size_t +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* + * Good old binary search. + * Assumes that array is sorted, has logarithmic complexity. + * if the result is x, then: + * if ( x>0 ) you have array[x] = ikey + * if ( x<0 ) then inserting ikey at position -x-1 in array (insuring that array[-x-1]=ikey) + * keys the array sorted. + */ +inline int32_t binarySearch(const uint16_t *array, int32_t lenarray, + uint16_t ikey) { + int32_t low = 0; + int32_t high = lenarray - 1; + while (low <= high) { + int32_t middleIndex = (low + high) >> 1; + uint16_t middleValue = array[middleIndex]; + if (middleValue < ikey) { + low = middleIndex + 1; + } else if (middleValue > ikey) { + high = middleIndex - 1; + } else { + return middleIndex; + } + } + return -(low + 1); +} + +/** + * Galloping search + * Assumes that array is sorted, has logarithmic complexity. + * if the result is x, then if x = length, you have that all values in array between pos and length + * are smaller than min. + * otherwise returns the first index x such that array[x] >= min. + */ +static inline int32_t advanceUntil(const uint16_t *array, int32_t pos, + int32_t length, uint16_t min) { + int32_t lower = pos + 1; + + if ((lower >= length) || (array[lower] >= min)) { + return lower; + } + + int32_t spansize = 1; + + while ((lower + spansize < length) && (array[lower + spansize] < min)) { + spansize <<= 1; + } + int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1; + + if (array[upper] == min) { + return upper; + } + if (array[upper] < min) { + // means + // array + // has no + // item + // >= min + // pos = array.length; + return length; + } + + // we know that the next-smallest span was too small + lower += (spansize >> 1); + + int32_t mid = 0; + while (lower + 1 != upper) { + mid = (lower + upper) >> 1; + if (array[mid] == min) { + return mid; + } else if (array[mid] < min) { + lower = mid; + } else { + upper = mid; + } + } + return upper; +} + +/** + * Returns number of elements which are less then $ikey. + * Array elements must be unique and sorted. + */ +static inline int32_t count_less(const uint16_t *array, int32_t lenarray, + uint16_t ikey) { + if (lenarray == 0) return 0; + int32_t pos = binarySearch(array, lenarray, ikey); + return pos >= 0 ? pos : -(pos+1); +} + +/** + * Returns number of elements which are greater then $ikey. + * Array elements must be unique and sorted. + */ +static inline int32_t count_greater(const uint16_t *array, int32_t lenarray, + uint16_t ikey) { + if (lenarray == 0) return 0; + int32_t pos = binarySearch(array, lenarray, ikey); + if (pos >= 0) { + return lenarray - (pos+1); + } else { + return lenarray - (-pos-1); + } +} + +/** + * From Schlegel et al., Fast Sorted-Set Intersection using SIMD Instructions + * Optimized by D. Lemire on May 3rd 2013 + * + * C should have capacity greater than the minimum of s_1 and s_b + 8 + * where 8 is sizeof(__m128i)/sizeof(uint16_t). + */ +int32_t intersect_vector16(const uint16_t *__restrict__ A, size_t s_a, + const uint16_t *__restrict__ B, size_t s_b, + uint16_t *C); + +/** + * Compute the cardinality of the intersection using SSE4 instructions + */ +int32_t intersect_vector16_cardinality(const uint16_t *__restrict__ A, + size_t s_a, + const uint16_t *__restrict__ B, + size_t s_b); + +/* Computes the intersection between one small and one large set of uint16_t. + * Stores the result into buffer and return the number of elements. */ +int32_t intersect_skewed_uint16(const uint16_t *smallarray, size_t size_s, + const uint16_t *largearray, size_t size_l, + uint16_t *buffer); + +/* Computes the size of the intersection between one small and one large set of + * uint16_t. */ +int32_t intersect_skewed_uint16_cardinality(const uint16_t *smallarray, + size_t size_s, + const uint16_t *largearray, + size_t size_l); + + +/* Check whether the size of the intersection between one small and one large set of uint16_t is non-zero. */ +bool intersect_skewed_uint16_nonempty(const uint16_t *smallarray, size_t size_s, + const uint16_t *largearray, size_t size_l); +/** + * Generic intersection function. + */ +int32_t intersect_uint16(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB, uint16_t *out); +/** + * Compute the size of the intersection (generic). + */ +int32_t intersect_uint16_cardinality(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB); + +/** + * Checking whether the size of the intersection is non-zero. + */ +bool intersect_uint16_nonempty(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB); +/** + * Generic union function. + */ +size_t union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, + size_t size_2, uint16_t *buffer); + +/** + * Generic XOR function. + */ +int32_t xor_uint16(const uint16_t *array_1, int32_t card_1, + const uint16_t *array_2, int32_t card_2, uint16_t *out); + +/** + * Generic difference function (ANDNOT). + */ +int difference_uint16(const uint16_t *a1, int length1, const uint16_t *a2, + int length2, uint16_t *a_out); + +/** + * Generic intersection function. + */ +size_t intersection_uint32(const uint32_t *A, const size_t lenA, + const uint32_t *B, const size_t lenB, uint32_t *out); + +/** + * Generic intersection function, returns just the cardinality. + */ +size_t intersection_uint32_card(const uint32_t *A, const size_t lenA, + const uint32_t *B, const size_t lenB); + +/** + * Generic union function. + */ +size_t union_uint32(const uint32_t *set_1, size_t size_1, const uint32_t *set_2, + size_t size_2, uint32_t *buffer); + +/** + * A fast SSE-based union function. + */ +uint32_t union_vector16(const uint16_t *__restrict__ set_1, uint32_t size_1, + const uint16_t *__restrict__ set_2, uint32_t size_2, + uint16_t *__restrict__ buffer); +/** + * A fast SSE-based XOR function. + */ +uint32_t xor_vector16(const uint16_t *__restrict__ array1, uint32_t length1, + const uint16_t *__restrict__ array2, uint32_t length2, + uint16_t *__restrict__ output); + +/** + * A fast SSE-based difference function. + */ +int32_t difference_vector16(const uint16_t *__restrict__ A, size_t s_a, + const uint16_t *__restrict__ B, size_t s_b, + uint16_t *C); + +/** + * Generic union function, returns just the cardinality. + */ +size_t union_uint32_card(const uint32_t *set_1, size_t size_1, + const uint32_t *set_2, size_t size_2); + +/** +* combines union_uint16 and union_vector16 optimally +*/ +size_t fast_union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, + size_t size_2, uint16_t *buffer); + + +bool memequals(const void *s1, const void *s2, size_t n); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif +/* end file include/roaring/array_util.h */ +/* begin file include/roaring/utilasm.h */ +/* + * utilasm.h + * + */ + +#ifndef INCLUDE_UTILASM_H_ +#define INCLUDE_UTILASM_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { +#endif + +#if defined(ROARING_INLINE_ASM) +#define CROARING_ASMBITMANIPOPTIMIZATION // optimization flag + +#define ASM_SHIFT_RIGHT(srcReg, bitsReg, destReg) \ + __asm volatile("shrx %1, %2, %0" \ + : "=r"(destReg) \ + : /* write */ \ + "r"(bitsReg), /* read only */ \ + "r"(srcReg) /* read only */ \ + ) + +#define ASM_INPLACESHIFT_RIGHT(srcReg, bitsReg) \ + __asm volatile("shrx %1, %0, %0" \ + : "+r"(srcReg) \ + : /* read/write */ \ + "r"(bitsReg) /* read only */ \ + ) + +#define ASM_SHIFT_LEFT(srcReg, bitsReg, destReg) \ + __asm volatile("shlx %1, %2, %0" \ + : "=r"(destReg) \ + : /* write */ \ + "r"(bitsReg), /* read only */ \ + "r"(srcReg) /* read only */ \ + ) +// set bit at position testBit within testByte to 1 and +// copy cmovDst to cmovSrc if that bit was previously clear +#define ASM_SET_BIT_INC_WAS_CLEAR(testByte, testBit, count) \ + __asm volatile( \ + "bts %2, %0\n" \ + "sbb $-1, %1\n" \ + : "+r"(testByte), /* read/write */ \ + "+r"(count) \ + : /* read/write */ \ + "r"(testBit) /* read only */ \ + ) + +#define ASM_CLEAR_BIT_DEC_WAS_SET(testByte, testBit, count) \ + __asm volatile( \ + "btr %2, %0\n" \ + "sbb $0, %1\n" \ + : "+r"(testByte), /* read/write */ \ + "+r"(count) \ + : /* read/write */ \ + "r"(testBit) /* read only */ \ + ) + +#define ASM_BT64(testByte, testBit, count) \ + __asm volatile( \ + "bt %2,%1\n" \ + "sbb %0,%0" /*could use setb */ \ + : "=r"(count) \ + : /* write */ \ + "r"(testByte), /* read only */ \ + "r"(testBit) /* read only */ \ + ) + +#endif + +#ifdef __cplusplus +} } // extern "C" { namespace roaring { +#endif + +#endif /* INCLUDE_UTILASM_H_ */ +/* end file include/roaring/utilasm.h */ +/* begin file include/roaring/bitset_util.h */ +#ifndef BITSET_UTIL_H +#define BITSET_UTIL_H + +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* + * Set all bits in indexes [begin,end) to true. + */ +static inline void bitset_set_range(uint64_t *words, uint32_t start, + uint32_t end) { + if (start == end) return; + uint32_t firstword = start / 64; + uint32_t endword = (end - 1) / 64; + if (firstword == endword) { + words[firstword] |= ((~UINT64_C(0)) << (start % 64)) & + ((~UINT64_C(0)) >> ((~end + 1) % 64)); + return; + } + words[firstword] |= (~UINT64_C(0)) << (start % 64); + for (uint32_t i = firstword + 1; i < endword; i++) { + words[i] = ~UINT64_C(0); + } + words[endword] |= (~UINT64_C(0)) >> ((~end + 1) % 64); +} + + +/* + * Find the cardinality of the bitset in [begin,begin+lenminusone] + */ +static inline int bitset_lenrange_cardinality(const uint64_t *words, + uint32_t start, + uint32_t lenminusone) { + uint32_t firstword = start / 64; + uint32_t endword = (start + lenminusone) / 64; + if (firstword == endword) { + return hamming(words[firstword] & + ((~UINT64_C(0)) >> ((63 - lenminusone) % 64)) + << (start % 64)); + } + int answer = hamming(words[firstword] & ((~UINT64_C(0)) << (start % 64))); + for (uint32_t i = firstword + 1; i < endword; i++) { + answer += hamming(words[i]); + } + answer += + hamming(words[endword] & + (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64)); + return answer; +} + +/* + * Check whether the cardinality of the bitset in [begin,begin+lenminusone] is 0 + */ +static inline bool bitset_lenrange_empty(const uint64_t *words, uint32_t start, + uint32_t lenminusone) { + uint32_t firstword = start / 64; + uint32_t endword = (start + lenminusone) / 64; + if (firstword == endword) { + return (words[firstword] & ((~UINT64_C(0)) >> ((63 - lenminusone) % 64)) + << (start % 64)) == 0; + } + if (((words[firstword] & ((~UINT64_C(0)) << (start%64)))) != 0) { + return false; + } + for (uint32_t i = firstword + 1; i < endword; i++) { + if (words[i] != 0) { + return false; + } + } + if ((words[endword] & (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64)) != 0) { + return false; + } + return true; +} + + +/* + * Set all bits in indexes [begin,begin+lenminusone] to true. + */ +static inline void bitset_set_lenrange(uint64_t *words, uint32_t start, + uint32_t lenminusone) { + uint32_t firstword = start / 64; + uint32_t endword = (start + lenminusone) / 64; + if (firstword == endword) { + words[firstword] |= ((~UINT64_C(0)) >> ((63 - lenminusone) % 64)) + << (start % 64); + return; + } + uint64_t temp = words[endword]; + words[firstword] |= (~UINT64_C(0)) << (start % 64); + for (uint32_t i = firstword + 1; i < endword; i += 2) + words[i] = words[i + 1] = ~UINT64_C(0); + words[endword] = + temp | (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64); +} + +/* + * Flip all the bits in indexes [begin,end). + */ +static inline void bitset_flip_range(uint64_t *words, uint32_t start, + uint32_t end) { + if (start == end) return; + uint32_t firstword = start / 64; + uint32_t endword = (end - 1) / 64; + words[firstword] ^= ~((~UINT64_C(0)) << (start % 64)); + for (uint32_t i = firstword; i < endword; i++) { + words[i] = ~words[i]; + } + words[endword] ^= ((~UINT64_C(0)) >> ((~end + 1) % 64)); +} + +/* + * Set all bits in indexes [begin,end) to false. + */ +static inline void bitset_reset_range(uint64_t *words, uint32_t start, + uint32_t end) { + if (start == end) return; + uint32_t firstword = start / 64; + uint32_t endword = (end - 1) / 64; + if (firstword == endword) { + words[firstword] &= ~(((~UINT64_C(0)) << (start % 64)) & + ((~UINT64_C(0)) >> ((~end + 1) % 64))); + return; + } + words[firstword] &= ~((~UINT64_C(0)) << (start % 64)); + for (uint32_t i = firstword + 1; i < endword; i++) { + words[i] = UINT64_C(0); + } + words[endword] &= ~((~UINT64_C(0)) >> ((~end + 1) % 64)); +} + +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out", values start at "base". + * + * The "out" pointer should be sufficient to store the actual number of bits + * set. + * + * Returns how many values were actually decoded. + * + * This function should only be expected to be faster than + * bitset_extract_setbits + * when the density of the bitset is high. + * + * This function uses AVX2 decoding. + */ +size_t bitset_extract_setbits_avx2(const uint64_t *words, size_t length, + uint32_t *out, size_t outcapacity, + uint32_t base); + +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out", values start at "base". + * + * The "out" pointer should be sufficient to store the actual number of bits + *set. + * + * Returns how many values were actually decoded. + */ +size_t bitset_extract_setbits(const uint64_t *words, size_t length, + uint32_t *out, uint32_t base); + +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out" as 16-bit integers, values start at "base" (can + *be set to zero) + * + * The "out" pointer should be sufficient to store the actual number of bits + *set. + * + * Returns how many values were actually decoded. + * + * This function should only be expected to be faster than + *bitset_extract_setbits_uint16 + * when the density of the bitset is high. + * + * This function uses SSE decoding. + */ +size_t bitset_extract_setbits_sse_uint16(const uint64_t *words, size_t length, + uint16_t *out, size_t outcapacity, + uint16_t base); + +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out", values start at "base" + * (can be set to zero) + * + * The "out" pointer should be sufficient to store the actual number of bits + *set. + * + * Returns how many values were actually decoded. + */ +size_t bitset_extract_setbits_uint16(const uint64_t *words, size_t length, + uint16_t *out, uint16_t base); + +/* + * Given two bitsets containing "length" 64-bit words, write out the position + * of all the common set bits to "out", values start at "base" + * (can be set to zero) + * + * The "out" pointer should be sufficient to store the actual number of bits + * set. + * + * Returns how many values were actually decoded. + */ +size_t bitset_extract_intersection_setbits_uint16(const uint64_t * __restrict__ words1, + const uint64_t * __restrict__ words2, + size_t length, uint16_t *out, + uint16_t base); + +/* + * Given a bitset having cardinality card, set all bit values in the list (there + * are length of them) + * and return the updated cardinality. This evidently assumes that the bitset + * already contained data. + */ +uint64_t bitset_set_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length); +/* + * Given a bitset, set all bit values in the list (there + * are length of them). + */ +void bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length); + +/* + * Given a bitset having cardinality card, unset all bit values in the list + * (there are length of them) + * and return the updated cardinality. This evidently assumes that the bitset + * already contained data. + */ +uint64_t bitset_clear_list(uint64_t *words, uint64_t card, const uint16_t *list, + uint64_t length); + +/* + * Given a bitset having cardinality card, toggle all bit values in the list + * (there are length of them) + * and return the updated cardinality. This evidently assumes that the bitset + * already contained data. + */ + +uint64_t bitset_flip_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length); + +void bitset_flip_list(uint64_t *words, const uint16_t *list, uint64_t length); + +#ifdef CROARING_IS_X64 +/*** + * BEGIN Harley-Seal popcount functions. + */ +CROARING_TARGET_AVX2 +/** + * Compute the population count of a 256-bit word + * This is not especially fast, but it is convenient as part of other functions. + */ +static inline __m256i popcount256(__m256i v) { + const __m256i lookuppos = _mm256_setr_epi8( + /* 0 */ 4 + 0, /* 1 */ 4 + 1, /* 2 */ 4 + 1, /* 3 */ 4 + 2, + /* 4 */ 4 + 1, /* 5 */ 4 + 2, /* 6 */ 4 + 2, /* 7 */ 4 + 3, + /* 8 */ 4 + 1, /* 9 */ 4 + 2, /* a */ 4 + 2, /* b */ 4 + 3, + /* c */ 4 + 2, /* d */ 4 + 3, /* e */ 4 + 3, /* f */ 4 + 4, + + /* 0 */ 4 + 0, /* 1 */ 4 + 1, /* 2 */ 4 + 1, /* 3 */ 4 + 2, + /* 4 */ 4 + 1, /* 5 */ 4 + 2, /* 6 */ 4 + 2, /* 7 */ 4 + 3, + /* 8 */ 4 + 1, /* 9 */ 4 + 2, /* a */ 4 + 2, /* b */ 4 + 3, + /* c */ 4 + 2, /* d */ 4 + 3, /* e */ 4 + 3, /* f */ 4 + 4); + const __m256i lookupneg = _mm256_setr_epi8( + /* 0 */ 4 - 0, /* 1 */ 4 - 1, /* 2 */ 4 - 1, /* 3 */ 4 - 2, + /* 4 */ 4 - 1, /* 5 */ 4 - 2, /* 6 */ 4 - 2, /* 7 */ 4 - 3, + /* 8 */ 4 - 1, /* 9 */ 4 - 2, /* a */ 4 - 2, /* b */ 4 - 3, + /* c */ 4 - 2, /* d */ 4 - 3, /* e */ 4 - 3, /* f */ 4 - 4, + + /* 0 */ 4 - 0, /* 1 */ 4 - 1, /* 2 */ 4 - 1, /* 3 */ 4 - 2, + /* 4 */ 4 - 1, /* 5 */ 4 - 2, /* 6 */ 4 - 2, /* 7 */ 4 - 3, + /* 8 */ 4 - 1, /* 9 */ 4 - 2, /* a */ 4 - 2, /* b */ 4 - 3, + /* c */ 4 - 2, /* d */ 4 - 3, /* e */ 4 - 3, /* f */ 4 - 4); + const __m256i low_mask = _mm256_set1_epi8(0x0f); + + const __m256i lo = _mm256_and_si256(v, low_mask); + const __m256i hi = _mm256_and_si256(_mm256_srli_epi16(v, 4), low_mask); + const __m256i popcnt1 = _mm256_shuffle_epi8(lookuppos, lo); + const __m256i popcnt2 = _mm256_shuffle_epi8(lookupneg, hi); + return _mm256_sad_epu8(popcnt1, popcnt2); +} +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +/** + * Simple CSA over 256 bits + */ +static inline void CSA(__m256i *h, __m256i *l, __m256i a, __m256i b, + __m256i c) { + const __m256i u = _mm256_xor_si256(a, b); + *h = _mm256_or_si256(_mm256_and_si256(a, b), _mm256_and_si256(u, c)); + *l = _mm256_xor_si256(u, c); +} +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +/** + * Fast Harley-Seal AVX population count function + */ +inline static uint64_t avx2_harley_seal_popcount256(const __m256i *data, + const uint64_t size) { + __m256i total = _mm256_setzero_si256(); + __m256i ones = _mm256_setzero_si256(); + __m256i twos = _mm256_setzero_si256(); + __m256i fours = _mm256_setzero_si256(); + __m256i eights = _mm256_setzero_si256(); + __m256i sixteens = _mm256_setzero_si256(); + __m256i twosA, twosB, foursA, foursB, eightsA, eightsB; + + const uint64_t limit = size - size % 16; + uint64_t i = 0; + + for (; i < limit; i += 16) { + CSA(&twosA, &ones, ones, _mm256_lddqu_si256(data + i), + _mm256_lddqu_si256(data + i + 1)); + CSA(&twosB, &ones, ones, _mm256_lddqu_si256(data + i + 2), + _mm256_lddqu_si256(data + i + 3)); + CSA(&foursA, &twos, twos, twosA, twosB); + CSA(&twosA, &ones, ones, _mm256_lddqu_si256(data + i + 4), + _mm256_lddqu_si256(data + i + 5)); + CSA(&twosB, &ones, ones, _mm256_lddqu_si256(data + i + 6), + _mm256_lddqu_si256(data + i + 7)); + CSA(&foursB, &twos, twos, twosA, twosB); + CSA(&eightsA, &fours, fours, foursA, foursB); + CSA(&twosA, &ones, ones, _mm256_lddqu_si256(data + i + 8), + _mm256_lddqu_si256(data + i + 9)); + CSA(&twosB, &ones, ones, _mm256_lddqu_si256(data + i + 10), + _mm256_lddqu_si256(data + i + 11)); + CSA(&foursA, &twos, twos, twosA, twosB); + CSA(&twosA, &ones, ones, _mm256_lddqu_si256(data + i + 12), + _mm256_lddqu_si256(data + i + 13)); + CSA(&twosB, &ones, ones, _mm256_lddqu_si256(data + i + 14), + _mm256_lddqu_si256(data + i + 15)); + CSA(&foursB, &twos, twos, twosA, twosB); + CSA(&eightsB, &fours, fours, foursA, foursB); + CSA(&sixteens, &eights, eights, eightsA, eightsB); + + total = _mm256_add_epi64(total, popcount256(sixteens)); + } + + total = _mm256_slli_epi64(total, 4); // * 16 + total = _mm256_add_epi64( + total, _mm256_slli_epi64(popcount256(eights), 3)); // += 8 * ... + total = _mm256_add_epi64( + total, _mm256_slli_epi64(popcount256(fours), 2)); // += 4 * ... + total = _mm256_add_epi64( + total, _mm256_slli_epi64(popcount256(twos), 1)); // += 2 * ... + total = _mm256_add_epi64(total, popcount256(ones)); + for (; i < size; i++) + total = + _mm256_add_epi64(total, popcount256(_mm256_lddqu_si256(data + i))); + + return (uint64_t)(_mm256_extract_epi64(total, 0)) + + (uint64_t)(_mm256_extract_epi64(total, 1)) + + (uint64_t)(_mm256_extract_epi64(total, 2)) + + (uint64_t)(_mm256_extract_epi64(total, 3)); +} +CROARING_UNTARGET_REGION + +#define AVXPOPCNTFNC(opname, avx_intrinsic) \ + static inline uint64_t avx2_harley_seal_popcount256_##opname( \ + const __m256i *data1, const __m256i *data2, const uint64_t size) { \ + __m256i total = _mm256_setzero_si256(); \ + __m256i ones = _mm256_setzero_si256(); \ + __m256i twos = _mm256_setzero_si256(); \ + __m256i fours = _mm256_setzero_si256(); \ + __m256i eights = _mm256_setzero_si256(); \ + __m256i sixteens = _mm256_setzero_si256(); \ + __m256i twosA, twosB, foursA, foursB, eightsA, eightsB; \ + __m256i A1, A2; \ + const uint64_t limit = size - size % 16; \ + uint64_t i = 0; \ + for (; i < limit; i += 16) { \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i), \ + _mm256_lddqu_si256(data2 + i)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 1), \ + _mm256_lddqu_si256(data2 + i + 1)); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 2), \ + _mm256_lddqu_si256(data2 + i + 2)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 3), \ + _mm256_lddqu_si256(data2 + i + 3)); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursA, &twos, twos, twosA, twosB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 4), \ + _mm256_lddqu_si256(data2 + i + 4)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 5), \ + _mm256_lddqu_si256(data2 + i + 5)); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 6), \ + _mm256_lddqu_si256(data2 + i + 6)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 7), \ + _mm256_lddqu_si256(data2 + i + 7)); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursB, &twos, twos, twosA, twosB); \ + CSA(&eightsA, &fours, fours, foursA, foursB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 8), \ + _mm256_lddqu_si256(data2 + i + 8)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 9), \ + _mm256_lddqu_si256(data2 + i + 9)); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 10), \ + _mm256_lddqu_si256(data2 + i + 10)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 11), \ + _mm256_lddqu_si256(data2 + i + 11)); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursA, &twos, twos, twosA, twosB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 12), \ + _mm256_lddqu_si256(data2 + i + 12)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 13), \ + _mm256_lddqu_si256(data2 + i + 13)); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 14), \ + _mm256_lddqu_si256(data2 + i + 14)); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 15), \ + _mm256_lddqu_si256(data2 + i + 15)); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursB, &twos, twos, twosA, twosB); \ + CSA(&eightsB, &fours, fours, foursA, foursB); \ + CSA(&sixteens, &eights, eights, eightsA, eightsB); \ + total = _mm256_add_epi64(total, popcount256(sixteens)); \ + } \ + total = _mm256_slli_epi64(total, 4); \ + total = _mm256_add_epi64(total, \ + _mm256_slli_epi64(popcount256(eights), 3)); \ + total = \ + _mm256_add_epi64(total, _mm256_slli_epi64(popcount256(fours), 2)); \ + total = \ + _mm256_add_epi64(total, _mm256_slli_epi64(popcount256(twos), 1)); \ + total = _mm256_add_epi64(total, popcount256(ones)); \ + for (; i < size; i++) { \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i), \ + _mm256_lddqu_si256(data2 + i)); \ + total = _mm256_add_epi64(total, popcount256(A1)); \ + } \ + return (uint64_t)(_mm256_extract_epi64(total, 0)) + \ + (uint64_t)(_mm256_extract_epi64(total, 1)) + \ + (uint64_t)(_mm256_extract_epi64(total, 2)) + \ + (uint64_t)(_mm256_extract_epi64(total, 3)); \ + } \ + static inline uint64_t avx2_harley_seal_popcount256andstore_##opname( \ + const __m256i *__restrict__ data1, const __m256i *__restrict__ data2, \ + __m256i *__restrict__ out, const uint64_t size) { \ + __m256i total = _mm256_setzero_si256(); \ + __m256i ones = _mm256_setzero_si256(); \ + __m256i twos = _mm256_setzero_si256(); \ + __m256i fours = _mm256_setzero_si256(); \ + __m256i eights = _mm256_setzero_si256(); \ + __m256i sixteens = _mm256_setzero_si256(); \ + __m256i twosA, twosB, foursA, foursB, eightsA, eightsB; \ + __m256i A1, A2; \ + const uint64_t limit = size - size % 16; \ + uint64_t i = 0; \ + for (; i < limit; i += 16) { \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i), \ + _mm256_lddqu_si256(data2 + i)); \ + _mm256_storeu_si256(out + i, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 1), \ + _mm256_lddqu_si256(data2 + i + 1)); \ + _mm256_storeu_si256(out + i + 1, A2); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 2), \ + _mm256_lddqu_si256(data2 + i + 2)); \ + _mm256_storeu_si256(out + i + 2, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 3), \ + _mm256_lddqu_si256(data2 + i + 3)); \ + _mm256_storeu_si256(out + i + 3, A2); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursA, &twos, twos, twosA, twosB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 4), \ + _mm256_lddqu_si256(data2 + i + 4)); \ + _mm256_storeu_si256(out + i + 4, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 5), \ + _mm256_lddqu_si256(data2 + i + 5)); \ + _mm256_storeu_si256(out + i + 5, A2); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 6), \ + _mm256_lddqu_si256(data2 + i + 6)); \ + _mm256_storeu_si256(out + i + 6, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 7), \ + _mm256_lddqu_si256(data2 + i + 7)); \ + _mm256_storeu_si256(out + i + 7, A2); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursB, &twos, twos, twosA, twosB); \ + CSA(&eightsA, &fours, fours, foursA, foursB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 8), \ + _mm256_lddqu_si256(data2 + i + 8)); \ + _mm256_storeu_si256(out + i + 8, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 9), \ + _mm256_lddqu_si256(data2 + i + 9)); \ + _mm256_storeu_si256(out + i + 9, A2); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 10), \ + _mm256_lddqu_si256(data2 + i + 10)); \ + _mm256_storeu_si256(out + i + 10, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 11), \ + _mm256_lddqu_si256(data2 + i + 11)); \ + _mm256_storeu_si256(out + i + 11, A2); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursA, &twos, twos, twosA, twosB); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 12), \ + _mm256_lddqu_si256(data2 + i + 12)); \ + _mm256_storeu_si256(out + i + 12, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 13), \ + _mm256_lddqu_si256(data2 + i + 13)); \ + _mm256_storeu_si256(out + i + 13, A2); \ + CSA(&twosA, &ones, ones, A1, A2); \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 14), \ + _mm256_lddqu_si256(data2 + i + 14)); \ + _mm256_storeu_si256(out + i + 14, A1); \ + A2 = avx_intrinsic(_mm256_lddqu_si256(data1 + i + 15), \ + _mm256_lddqu_si256(data2 + i + 15)); \ + _mm256_storeu_si256(out + i + 15, A2); \ + CSA(&twosB, &ones, ones, A1, A2); \ + CSA(&foursB, &twos, twos, twosA, twosB); \ + CSA(&eightsB, &fours, fours, foursA, foursB); \ + CSA(&sixteens, &eights, eights, eightsA, eightsB); \ + total = _mm256_add_epi64(total, popcount256(sixteens)); \ + } \ + total = _mm256_slli_epi64(total, 4); \ + total = _mm256_add_epi64(total, \ + _mm256_slli_epi64(popcount256(eights), 3)); \ + total = \ + _mm256_add_epi64(total, _mm256_slli_epi64(popcount256(fours), 2)); \ + total = \ + _mm256_add_epi64(total, _mm256_slli_epi64(popcount256(twos), 1)); \ + total = _mm256_add_epi64(total, popcount256(ones)); \ + for (; i < size; i++) { \ + A1 = avx_intrinsic(_mm256_lddqu_si256(data1 + i), \ + _mm256_lddqu_si256(data2 + i)); \ + _mm256_storeu_si256(out + i, A1); \ + total = _mm256_add_epi64(total, popcount256(A1)); \ + } \ + return (uint64_t)(_mm256_extract_epi64(total, 0)) + \ + (uint64_t)(_mm256_extract_epi64(total, 1)) + \ + (uint64_t)(_mm256_extract_epi64(total, 2)) + \ + (uint64_t)(_mm256_extract_epi64(total, 3)); \ + } + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC(or, _mm256_or_si256) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC(union, _mm256_or_si256) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC(and, _mm256_and_si256) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC(intersection, _mm256_and_si256) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC (xor, _mm256_xor_si256) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVXPOPCNTFNC(andnot, _mm256_andnot_si256) +CROARING_UNTARGET_REGION + +/*** + * END Harley-Seal popcount functions. + */ + +#endif // CROARING_IS_X64 + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal +#endif + +#endif +/* end file include/roaring/bitset_util.h */ +/* begin file include/roaring/containers/array.h */ +/* + * array.h + * + */ + +#ifndef INCLUDE_CONTAINERS_ARRAY_H_ +#define INCLUDE_CONTAINERS_ARRAY_H_ + +#include + + + +#ifdef __cplusplus +extern "C" { namespace roaring { + +// Note: in pure C++ code, you should avoid putting `using` in header files +using api::roaring_iterator; +using api::roaring_iterator64; + +namespace internal { +#endif + +/* Containers with DEFAULT_MAX_SIZE or less integers should be arrays */ +enum { DEFAULT_MAX_SIZE = 4096 }; + +/* struct array_container - sparse representation of a bitmap + * + * @cardinality: number of indices in `array` (and the bitmap) + * @capacity: allocated size of `array` + * @array: sorted list of integers + */ +STRUCT_CONTAINER(array_container_s) { + int32_t cardinality; + int32_t capacity; + uint16_t *array; +}; + +typedef struct array_container_s array_container_t; + +#define CAST_array(c) CAST(array_container_t *, c) // safer downcast +#define const_CAST_array(c) CAST(const array_container_t *, c) +#define movable_CAST_array(c) movable_CAST(array_container_t **, c) + +/* Create a new array with default. Return NULL in case of failure. See also + * array_container_create_given_capacity. */ +array_container_t *array_container_create(void); + +/* Create a new array with a specified capacity size. Return NULL in case of + * failure. */ +array_container_t *array_container_create_given_capacity(int32_t size); + +/* Create a new array containing all values in [min,max). */ +array_container_t * array_container_create_range(uint32_t min, uint32_t max); + +/* + * Shrink the capacity to the actual size, return the number of bytes saved. + */ +int array_container_shrink_to_fit(array_container_t *src); + +/* Free memory owned by `array'. */ +void array_container_free(array_container_t *array); + +/* Duplicate container */ +array_container_t *array_container_clone(const array_container_t *src); + +/* Get the cardinality of `array'. */ +static inline int array_container_cardinality(const array_container_t *array) { + return array->cardinality; +} + +static inline bool array_container_nonzero_cardinality( + const array_container_t *array) { + return array->cardinality > 0; +} + +/* Copy one container into another. We assume that they are distinct. */ +void array_container_copy(const array_container_t *src, array_container_t *dst); + +/* Add all the values in [min,max) (included) at a distance k*step from min. + The container must have a size less or equal to DEFAULT_MAX_SIZE after this + addition. */ +void array_container_add_from_range(array_container_t *arr, uint32_t min, + uint32_t max, uint16_t step); + +/* Set the cardinality to zero (does not release memory). */ +static inline void array_container_clear(array_container_t *array) { + array->cardinality = 0; +} + +static inline bool array_container_empty(const array_container_t *array) { + return array->cardinality == 0; +} + +/* check whether the cardinality is equal to the capacity (this does not mean +* that it contains 1<<16 elements) */ +static inline bool array_container_full(const array_container_t *array) { + return array->cardinality == array->capacity; +} + + +/* Compute the union of `src_1' and `src_2' and write the result to `dst' + * It is assumed that `dst' is distinct from both `src_1' and `src_2'. */ +void array_container_union(const array_container_t *src_1, + const array_container_t *src_2, + array_container_t *dst); + +/* symmetric difference, see array_container_union */ +void array_container_xor(const array_container_t *array_1, + const array_container_t *array_2, + array_container_t *out); + +/* Computes the intersection of src_1 and src_2 and write the result to + * dst. It is assumed that dst is distinct from both src_1 and src_2. */ +void array_container_intersection(const array_container_t *src_1, + const array_container_t *src_2, + array_container_t *dst); + +/* Check whether src_1 and src_2 intersect. */ +bool array_container_intersect(const array_container_t *src_1, + const array_container_t *src_2); + + +/* computers the size of the intersection between two arrays. + */ +int array_container_intersection_cardinality(const array_container_t *src_1, + const array_container_t *src_2); + +/* computes the intersection of array1 and array2 and write the result to + * array1. + * */ +void array_container_intersection_inplace(array_container_t *src_1, + const array_container_t *src_2); + +/* + * Write out the 16-bit integers contained in this container as a list of 32-bit + * integers using base + * as the starting value (it might be expected that base has zeros in its 16 + * least significant bits). + * The function returns the number of values written. + * The caller is responsible for allocating enough memory in out. + */ +int array_container_to_uint32_array(void *vout, const array_container_t *cont, + uint32_t base); + +/* Compute the number of runs */ +int32_t array_container_number_of_runs(const array_container_t *ac); + +/* + * Print this container using printf (useful for debugging). + */ +void array_container_printf(const array_container_t *v); + +/* + * Print this container using printf as a comma-separated list of 32-bit + * integers starting at base. + */ +void array_container_printf_as_uint32_array(const array_container_t *v, + uint32_t base); + +/** + * Return the serialized size in bytes of a container having cardinality "card". + */ +static inline int32_t array_container_serialized_size_in_bytes(int32_t card) { + return card * 2 + 2; +} + +/** + * Increase capacity to at least min. + * Whether the existing data needs to be copied over depends on the "preserve" + * parameter. If preserve is false, then the new content will be uninitialized, + * otherwise the old content is copied. + */ +void array_container_grow(array_container_t *container, int32_t min, + bool preserve); + +bool array_container_iterate(const array_container_t *cont, uint32_t base, + roaring_iterator iterator, void *ptr); +bool array_container_iterate64(const array_container_t *cont, uint32_t base, + roaring_iterator64 iterator, uint64_t high_bits, + void *ptr); + +/** + * Writes the underlying array to buf, outputs how many bytes were written. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes written should be + * array_container_size_in_bytes(container). + * + */ +int32_t array_container_write(const array_container_t *container, char *buf); +/** + * Reads the instance from buf, outputs how many bytes were read. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes read should be array_container_size_in_bytes(container). + * You need to provide the (known) cardinality. + */ +int32_t array_container_read(int32_t cardinality, array_container_t *container, + const char *buf); + +/** + * Return the serialized size in bytes of a container (see + * bitset_container_write) + * This is meant to be compatible with the Java and Go versions of Roaring and + * assumes + * that the cardinality of the container is already known. + * + */ +static inline int32_t array_container_size_in_bytes( + const array_container_t *container) { + return container->cardinality * sizeof(uint16_t); +} + +/** + * Return true if the two arrays have the same content. + */ +static inline bool array_container_equals( + const array_container_t *container1, + const array_container_t *container2) { + + if (container1->cardinality != container2->cardinality) { + return false; + } + return memequals(container1->array, container2->array, container1->cardinality*2); +} + +/** + * Return true if container1 is a subset of container2. + */ +bool array_container_is_subset(const array_container_t *container1, + const array_container_t *container2); + +/** + * If the element of given rank is in this container, supposing that the first + * element has rank start_rank, then the function returns true and sets element + * accordingly. + * Otherwise, it returns false and update start_rank. + */ +static inline bool array_container_select(const array_container_t *container, + uint32_t *start_rank, uint32_t rank, + uint32_t *element) { + int card = array_container_cardinality(container); + if (*start_rank + card <= rank) { + *start_rank += card; + return false; + } else { + *element = container->array[rank - *start_rank]; + return true; + } +} + +/* Computes the difference of array1 and array2 and write the result + * to array out. + * Array out does not need to be distinct from array_1 + */ +void array_container_andnot(const array_container_t *array_1, + const array_container_t *array_2, + array_container_t *out); + +/* Append x to the set. Assumes that the value is larger than any preceding + * values. */ +static inline void array_container_append(array_container_t *arr, + uint16_t pos) { + const int32_t capacity = arr->capacity; + + if (array_container_full(arr)) { + array_container_grow(arr, capacity + 1, true); + } + + arr->array[arr->cardinality++] = pos; +} + +/** + * Add value to the set if final cardinality doesn't exceed max_cardinality. + * Return code: + * 1 -- value was added + * 0 -- value was already present + * -1 -- value was not added because cardinality would exceed max_cardinality + */ +static inline int array_container_try_add(array_container_t *arr, uint16_t value, + int32_t max_cardinality) { + const int32_t cardinality = arr->cardinality; + + // best case, we can append. + if ((array_container_empty(arr) || arr->array[cardinality - 1] < value) && + cardinality < max_cardinality) { + array_container_append(arr, value); + return 1; + } + + const int32_t loc = binarySearch(arr->array, cardinality, value); + + if (loc >= 0) { + return 0; + } else if (cardinality < max_cardinality) { + if (array_container_full(arr)) { + array_container_grow(arr, arr->capacity + 1, true); + } + const int32_t insert_idx = -loc - 1; + memmove(arr->array + insert_idx + 1, arr->array + insert_idx, + (cardinality - insert_idx) * sizeof(uint16_t)); + arr->array[insert_idx] = value; + arr->cardinality++; + return 1; + } else { + return -1; + } +} + +/* Add value to the set. Returns true if x was not already present. */ +static inline bool array_container_add(array_container_t *arr, uint16_t value) { + return array_container_try_add(arr, value, INT32_MAX) == 1; +} + +/* Remove x from the set. Returns true if x was present. */ +static inline bool array_container_remove(array_container_t *arr, + uint16_t pos) { + const int32_t idx = binarySearch(arr->array, arr->cardinality, pos); + const bool is_present = idx >= 0; + if (is_present) { + memmove(arr->array + idx, arr->array + idx + 1, + (arr->cardinality - idx - 1) * sizeof(uint16_t)); + arr->cardinality--; + } + + return is_present; +} + +/* Check whether x is present. */ +inline bool array_container_contains(const array_container_t *arr, + uint16_t pos) { + // return binarySearch(arr->array, arr->cardinality, pos) >= 0; + // binary search with fallback to linear search for short ranges + int32_t low = 0; + const uint16_t * carr = (const uint16_t *) arr->array; + int32_t high = arr->cardinality - 1; + // while (high - low >= 0) { + while(high >= low + 16) { + int32_t middleIndex = (low + high)>>1; + uint16_t middleValue = carr[middleIndex]; + if (middleValue < pos) { + low = middleIndex + 1; + } else if (middleValue > pos) { + high = middleIndex - 1; + } else { + return true; + } + } + + for (int i=low; i <= high; i++) { + uint16_t v = carr[i]; + if (v == pos) { + return true; + } + if ( v > pos ) return false; + } + return false; + +} + +void array_container_offset(const array_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset); + +//* Check whether a range of values from range_start (included) to range_end (excluded) is present. */ +static inline bool array_container_contains_range(const array_container_t *arr, + uint32_t range_start, uint32_t range_end) { + + const uint16_t rs_included = range_start; + const uint16_t re_included = range_end - 1; + + const uint16_t *carr = (const uint16_t *) arr->array; + + const int32_t start = advanceUntil(carr, -1, arr->cardinality, rs_included); + const int32_t end = advanceUntil(carr, start - 1, arr->cardinality, re_included); + + return (start < arr->cardinality) && (end < arr->cardinality) + && (((uint16_t)(end - start)) == re_included - rs_included) + && (carr[start] == rs_included) && (carr[end] == re_included); +} + +/* Returns the smallest value (assumes not empty) */ +inline uint16_t array_container_minimum(const array_container_t *arr) { + if (arr->cardinality == 0) return 0; + return arr->array[0]; +} + +/* Returns the largest value (assumes not empty) */ +inline uint16_t array_container_maximum(const array_container_t *arr) { + if (arr->cardinality == 0) return 0; + return arr->array[arr->cardinality - 1]; +} + +/* Returns the number of values equal or smaller than x */ +inline int array_container_rank(const array_container_t *arr, uint16_t x) { + const int32_t idx = binarySearch(arr->array, arr->cardinality, x); + const bool is_present = idx >= 0; + if (is_present) { + return idx + 1; + } else { + return -idx - 1; + } +} + +/* Returns the index of the first value equal or smaller than x, or -1 */ +inline int array_container_index_equalorlarger(const array_container_t *arr, uint16_t x) { + const int32_t idx = binarySearch(arr->array, arr->cardinality, x); + const bool is_present = idx >= 0; + if (is_present) { + return idx; + } else { + int32_t candidate = - idx - 1; + if(candidate < arr->cardinality) return candidate; + return -1; + } +} + +/* + * Adds all values in range [min,max] using hint: + * nvals_less is the number of array values less than $min + * nvals_greater is the number of array values greater than $max + */ +static inline void array_container_add_range_nvals(array_container_t *array, + uint32_t min, uint32_t max, + int32_t nvals_less, + int32_t nvals_greater) { + int32_t union_cardinality = nvals_less + (max - min + 1) + nvals_greater; + if (union_cardinality > array->capacity) { + array_container_grow(array, union_cardinality, true); + } + memmove(&(array->array[union_cardinality - nvals_greater]), + &(array->array[array->cardinality - nvals_greater]), + nvals_greater * sizeof(uint16_t)); + for (uint32_t i = 0; i <= max - min; i++) { + array->array[nvals_less + i] = min + i; + } + array->cardinality = union_cardinality; +} + +/** + * Adds all values in range [min,max]. + */ +static inline void array_container_add_range(array_container_t *array, + uint32_t min, uint32_t max) { + int32_t nvals_greater = count_greater(array->array, array->cardinality, max); + int32_t nvals_less = count_less(array->array, array->cardinality - nvals_greater, min); + array_container_add_range_nvals(array, min, max, nvals_less, nvals_greater); +} + +/* + * Removes all elements array[pos] .. array[pos+count-1] + */ +static inline void array_container_remove_range(array_container_t *array, + uint32_t pos, uint32_t count) { + if (count != 0) { + memmove(&(array->array[pos]), &(array->array[pos+count]), + (array->cardinality - pos - count) * sizeof(uint16_t)); + array->cardinality -= count; + } +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_ARRAY_H_ */ +/* end file include/roaring/containers/array.h */ +/* begin file include/roaring/containers/bitset.h */ +/* + * bitset.h + * + */ + +#ifndef INCLUDE_CONTAINERS_BITSET_H_ +#define INCLUDE_CONTAINERS_BITSET_H_ + +#include +#include + + + +#ifdef __cplusplus +extern "C" { namespace roaring { + +// Note: in pure C++ code, you should avoid putting `using` in header files +using api::roaring_iterator; +using api::roaring_iterator64; + +namespace internal { +#endif + + + +enum { + BITSET_CONTAINER_SIZE_IN_WORDS = (1 << 16) / 64, + BITSET_UNKNOWN_CARDINALITY = -1 +}; + +STRUCT_CONTAINER(bitset_container_s) { + int32_t cardinality; + uint64_t *words; +}; + +typedef struct bitset_container_s bitset_container_t; + +#define CAST_bitset(c) CAST(bitset_container_t *, c) // safer downcast +#define const_CAST_bitset(c) CAST(const bitset_container_t *, c) +#define movable_CAST_bitset(c) movable_CAST(bitset_container_t **, c) + +/* Create a new bitset. Return NULL in case of failure. */ +bitset_container_t *bitset_container_create(void); + +/* Free memory. */ +void bitset_container_free(bitset_container_t *bitset); + +/* Clear bitset (sets bits to 0). */ +void bitset_container_clear(bitset_container_t *bitset); + +/* Set all bits to 1. */ +void bitset_container_set_all(bitset_container_t *bitset); + +/* Duplicate bitset */ +bitset_container_t *bitset_container_clone(const bitset_container_t *src); + +/* Set the bit in [begin,end). WARNING: as of April 2016, this method is slow + * and + * should not be used in performance-sensitive code. Ever. */ +void bitset_container_set_range(bitset_container_t *bitset, uint32_t begin, + uint32_t end); + +#if defined(CROARING_ASMBITMANIPOPTIMIZATION) && defined(__AVX2__) +/* Set the ith bit. */ +static inline void bitset_container_set(bitset_container_t *bitset, + uint16_t pos) { + uint64_t shift = 6; + uint64_t offset; + uint64_t p = pos; + ASM_SHIFT_RIGHT(p, shift, offset); + uint64_t load = bitset->words[offset]; + ASM_SET_BIT_INC_WAS_CLEAR(load, p, bitset->cardinality); + bitset->words[offset] = load; +} + +/* Unset the ith bit. */ +static inline void bitset_container_unset(bitset_container_t *bitset, + uint16_t pos) { + uint64_t shift = 6; + uint64_t offset; + uint64_t p = pos; + ASM_SHIFT_RIGHT(p, shift, offset); + uint64_t load = bitset->words[offset]; + ASM_CLEAR_BIT_DEC_WAS_SET(load, p, bitset->cardinality); + bitset->words[offset] = load; +} + +/* Add `pos' to `bitset'. Returns true if `pos' was not present. Might be slower + * than bitset_container_set. */ +static inline bool bitset_container_add(bitset_container_t *bitset, + uint16_t pos) { + uint64_t shift = 6; + uint64_t offset; + uint64_t p = pos; + ASM_SHIFT_RIGHT(p, shift, offset); + uint64_t load = bitset->words[offset]; + // could be possibly slightly further optimized + const int32_t oldcard = bitset->cardinality; + ASM_SET_BIT_INC_WAS_CLEAR(load, p, bitset->cardinality); + bitset->words[offset] = load; + return bitset->cardinality - oldcard; +} + +/* Remove `pos' from `bitset'. Returns true if `pos' was present. Might be + * slower than bitset_container_unset. */ +static inline bool bitset_container_remove(bitset_container_t *bitset, + uint16_t pos) { + uint64_t shift = 6; + uint64_t offset; + uint64_t p = pos; + ASM_SHIFT_RIGHT(p, shift, offset); + uint64_t load = bitset->words[offset]; + // could be possibly slightly further optimized + const int32_t oldcard = bitset->cardinality; + ASM_CLEAR_BIT_DEC_WAS_SET(load, p, bitset->cardinality); + bitset->words[offset] = load; + return oldcard - bitset->cardinality; +} + +/* Get the value of the ith bit. */ +inline bool bitset_container_get(const bitset_container_t *bitset, + uint16_t pos) { + uint64_t word = bitset->words[pos >> 6]; + const uint64_t p = pos; + ASM_INPLACESHIFT_RIGHT(word, p); + return word & 1; +} + +#else + +/* Set the ith bit. */ +static inline void bitset_container_set(bitset_container_t *bitset, + uint16_t pos) { + const uint64_t old_word = bitset->words[pos >> 6]; + const int index = pos & 63; + const uint64_t new_word = old_word | (UINT64_C(1) << index); + bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index); + bitset->words[pos >> 6] = new_word; +} + +/* Unset the ith bit. */ +static inline void bitset_container_unset(bitset_container_t *bitset, + uint16_t pos) { + const uint64_t old_word = bitset->words[pos >> 6]; + const int index = pos & 63; + const uint64_t new_word = old_word & (~(UINT64_C(1) << index)); + bitset->cardinality -= (uint32_t)((old_word ^ new_word) >> index); + bitset->words[pos >> 6] = new_word; +} + +/* Add `pos' to `bitset'. Returns true if `pos' was not present. Might be slower + * than bitset_container_set. */ +static inline bool bitset_container_add(bitset_container_t *bitset, + uint16_t pos) { + const uint64_t old_word = bitset->words[pos >> 6]; + const int index = pos & 63; + const uint64_t new_word = old_word | (UINT64_C(1) << index); + const uint64_t increment = (old_word ^ new_word) >> index; + bitset->cardinality += (uint32_t)increment; + bitset->words[pos >> 6] = new_word; + return increment > 0; +} + +/* Remove `pos' from `bitset'. Returns true if `pos' was present. Might be + * slower than bitset_container_unset. */ +static inline bool bitset_container_remove(bitset_container_t *bitset, + uint16_t pos) { + const uint64_t old_word = bitset->words[pos >> 6]; + const int index = pos & 63; + const uint64_t new_word = old_word & (~(UINT64_C(1) << index)); + const uint64_t increment = (old_word ^ new_word) >> index; + bitset->cardinality -= (uint32_t)increment; + bitset->words[pos >> 6] = new_word; + return increment > 0; +} + +/* Get the value of the ith bit. */ +inline bool bitset_container_get(const bitset_container_t *bitset, + uint16_t pos) { + const uint64_t word = bitset->words[pos >> 6]; + return (word >> (pos & 63)) & 1; +} + +#endif + +/* +* Check if all bits are set in a range of positions from pos_start (included) to +* pos_end (excluded). +*/ +static inline bool bitset_container_get_range(const bitset_container_t *bitset, + uint32_t pos_start, uint32_t pos_end) { + + const uint32_t start = pos_start >> 6; + const uint32_t end = pos_end >> 6; + + const uint64_t first = ~((1ULL << (pos_start & 0x3F)) - 1); + const uint64_t last = (1ULL << (pos_end & 0x3F)) - 1; + + if (start == end) return ((bitset->words[end] & first & last) == (first & last)); + if ((bitset->words[start] & first) != first) return false; + + if ((end < BITSET_CONTAINER_SIZE_IN_WORDS) && ((bitset->words[end] & last) != last)){ + + return false; + } + + for (uint16_t i = start + 1; (i < BITSET_CONTAINER_SIZE_IN_WORDS) && (i < end); ++i){ + + if (bitset->words[i] != UINT64_C(0xFFFFFFFFFFFFFFFF)) return false; + } + + return true; +} + +/* Check whether `bitset' is present in `array'. Calls bitset_container_get. */ +inline bool bitset_container_contains(const bitset_container_t *bitset, + uint16_t pos) { + return bitset_container_get(bitset, pos); +} + +/* +* Check whether a range of bits from position `pos_start' (included) to `pos_end' (excluded) +* is present in `bitset'. Calls bitset_container_get_all. +*/ +static inline bool bitset_container_contains_range(const bitset_container_t *bitset, + uint32_t pos_start, uint32_t pos_end) { + return bitset_container_get_range(bitset, pos_start, pos_end); +} + +/* Get the number of bits set */ +static inline int bitset_container_cardinality( + const bitset_container_t *bitset) { + return bitset->cardinality; +} + + + + +/* Copy one container into another. We assume that they are distinct. */ +void bitset_container_copy(const bitset_container_t *source, + bitset_container_t *dest); + +/* Add all the values [min,max) at a distance k*step from min: min, + * min+step,.... */ +void bitset_container_add_from_range(bitset_container_t *bitset, uint32_t min, + uint32_t max, uint16_t step); + +/* Get the number of bits set (force computation). This does not modify bitset. + * To update the cardinality, you should do + * bitset->cardinality = bitset_container_compute_cardinality(bitset).*/ +int bitset_container_compute_cardinality(const bitset_container_t *bitset); + +/* Get whether there is at least one bit set (see bitset_container_empty for the reverse), + when the cardinality is unknown, it is computed and stored in the struct */ +static inline bool bitset_container_nonzero_cardinality( + bitset_container_t *bitset) { + // account for laziness + if (bitset->cardinality == BITSET_UNKNOWN_CARDINALITY) { + // could bail early instead with a nonzero result + bitset->cardinality = bitset_container_compute_cardinality(bitset); + } + return bitset->cardinality > 0; +} + +/* Check whether this bitset is empty (see bitset_container_nonzero_cardinality for the reverse), + * it never modifies the bitset struct. */ +static inline bool bitset_container_empty( + const bitset_container_t *bitset) { + if (bitset->cardinality == BITSET_UNKNOWN_CARDINALITY) { + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i ++) { + if((bitset->words[i]) != 0) return false; + } + return true; + } + return bitset->cardinality == 0; +} + + +/* Get whether there is at least one bit set (see bitset_container_empty for the reverse), + the bitset is never modified */ +static inline bool bitset_container_const_nonzero_cardinality( + const bitset_container_t *bitset) { + return !bitset_container_empty(bitset); +} + +/* + * Check whether the two bitsets intersect + */ +bool bitset_container_intersect(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the union of bitsets `src_1' and `src_2' into `dst' and return the + * cardinality. */ +int bitset_container_or(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the union of bitsets `src_1' and `src_2' and return the cardinality. + */ +int bitset_container_or_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the union of bitsets `src_1' and `src_2' into `dst' and return the + * cardinality. Same as bitset_container_or. */ +int bitset_container_union(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the union of bitsets `src_1' and `src_2' and return the + * cardinality. Same as bitset_container_or_justcard. */ +int bitset_container_union_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the union of bitsets `src_1' and `src_2' into `dst', but does not + * update the cardinality. Provided to optimize chained operations. */ +int bitset_container_or_nocard(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the intersection of bitsets `src_1' and `src_2' into `dst' and + * return the cardinality. */ +int bitset_container_and(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the intersection of bitsets `src_1' and `src_2' and return the + * cardinality. */ +int bitset_container_and_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the intersection of bitsets `src_1' and `src_2' into `dst' and + * return the cardinality. Same as bitset_container_and. */ +int bitset_container_intersection(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the intersection of bitsets `src_1' and `src_2' and return the + * cardinality. Same as bitset_container_and_justcard. */ +int bitset_container_intersection_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the intersection of bitsets `src_1' and `src_2' into `dst', but does + * not update the cardinality. Provided to optimize chained operations. */ +int bitset_container_and_nocard(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the exclusive or of bitsets `src_1' and `src_2' into `dst' and + * return the cardinality. */ +int bitset_container_xor(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the exclusive or of bitsets `src_1' and `src_2' and return the + * cardinality. */ +int bitset_container_xor_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the exclusive or of bitsets `src_1' and `src_2' into `dst', but does + * not update the cardinality. Provided to optimize chained operations. */ +int bitset_container_xor_nocard(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the and not of bitsets `src_1' and `src_2' into `dst' and return the + * cardinality. */ +int bitset_container_andnot(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Computes the and not of bitsets `src_1' and `src_2' and return the + * cardinality. */ +int bitset_container_andnot_justcard(const bitset_container_t *src_1, + const bitset_container_t *src_2); + +/* Computes the and not or of bitsets `src_1' and `src_2' into `dst', but does + * not update the cardinality. Provided to optimize chained operations. */ +int bitset_container_andnot_nocard(const bitset_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +void bitset_container_offset(const bitset_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset); +/* + * Write out the 16-bit integers contained in this container as a list of 32-bit + * integers using base + * as the starting value (it might be expected that base has zeros in its 16 + * least significant bits). + * The function returns the number of values written. + * The caller is responsible for allocating enough memory in out. + * The out pointer should point to enough memory (the cardinality times 32 + * bits). + */ +int bitset_container_to_uint32_array(uint32_t *out, + const bitset_container_t *bc, + uint32_t base); + +/* + * Print this container using printf (useful for debugging). + */ +void bitset_container_printf(const bitset_container_t *v); + +/* + * Print this container using printf as a comma-separated list of 32-bit + * integers starting at base. + */ +void bitset_container_printf_as_uint32_array(const bitset_container_t *v, + uint32_t base); + +/** + * Return the serialized size in bytes of a container. + */ +static inline int32_t bitset_container_serialized_size_in_bytes(void) { + return BITSET_CONTAINER_SIZE_IN_WORDS * 8; +} + +/** + * Return the the number of runs. + */ +int bitset_container_number_of_runs(bitset_container_t *bc); + +bool bitset_container_iterate(const bitset_container_t *cont, uint32_t base, + roaring_iterator iterator, void *ptr); +bool bitset_container_iterate64(const bitset_container_t *cont, uint32_t base, + roaring_iterator64 iterator, uint64_t high_bits, + void *ptr); + +/** + * Writes the underlying array to buf, outputs how many bytes were written. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes written should be + * bitset_container_size_in_bytes(container). + */ +int32_t bitset_container_write(const bitset_container_t *container, char *buf); + +/** + * Reads the instance from buf, outputs how many bytes were read. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes read should be bitset_container_size_in_bytes(container). + * You need to provide the (known) cardinality. + */ +int32_t bitset_container_read(int32_t cardinality, + bitset_container_t *container, const char *buf); +/** + * Return the serialized size in bytes of a container (see + * bitset_container_write). + * This is meant to be compatible with the Java and Go versions of Roaring and + * assumes + * that the cardinality of the container is already known or can be computed. + */ +static inline int32_t bitset_container_size_in_bytes( + const bitset_container_t *container) { + (void)container; + return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); +} + +/** + * Return true if the two containers have the same content. + */ +bool bitset_container_equals(const bitset_container_t *container1, + const bitset_container_t *container2); + +/** +* Return true if container1 is a subset of container2. +*/ +bool bitset_container_is_subset(const bitset_container_t *container1, + const bitset_container_t *container2); + +/** + * If the element of given rank is in this container, supposing that the first + * element has rank start_rank, then the function returns true and sets element + * accordingly. + * Otherwise, it returns false and update start_rank. + */ +bool bitset_container_select(const bitset_container_t *container, + uint32_t *start_rank, uint32_t rank, + uint32_t *element); + +/* Returns the smallest value (assumes not empty) */ +uint16_t bitset_container_minimum(const bitset_container_t *container); + +/* Returns the largest value (assumes not empty) */ +uint16_t bitset_container_maximum(const bitset_container_t *container); + +/* Returns the number of values equal or smaller than x */ +int bitset_container_rank(const bitset_container_t *container, uint16_t x); + +/* Returns the index of the first value equal or larger than x, or -1 */ +int bitset_container_index_equalorlarger(const bitset_container_t *container, uint16_t x); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_BITSET_H_ */ +/* end file include/roaring/containers/bitset.h */ +/* begin file include/roaring/containers/run.h */ +/* + * run.h + * + */ + +#ifndef INCLUDE_CONTAINERS_RUN_H_ +#define INCLUDE_CONTAINERS_RUN_H_ + +#include +#include +#include +#include + + + +#ifdef __cplusplus +extern "C" { namespace roaring { + +// Note: in pure C++ code, you should avoid putting `using` in header files +using api::roaring_iterator; +using api::roaring_iterator64; + +namespace internal { +#endif + +/* struct rle16_s - run length pair + * + * @value: start position of the run + * @length: length of the run is `length + 1` + * + * An RLE pair {v, l} would represent the integers between the interval + * [v, v+l+1], e.g. {3, 2} = [3, 4, 5]. + */ +struct rle16_s { + uint16_t value; + uint16_t length; +}; + +typedef struct rle16_s rle16_t; + +#ifdef __cplusplus + #define MAKE_RLE16(val,len) \ + {(uint16_t)(val), (uint16_t)(len)} // no tagged structs until c++20 +#else + #define MAKE_RLE16(val,len) \ + (rle16_t){.value = (uint16_t)(val), .length = (uint16_t)(len)} +#endif + +/* struct run_container_s - run container bitmap + * + * @n_runs: number of rle_t pairs in `runs`. + * @capacity: capacity in rle_t pairs `runs` can hold. + * @runs: pairs of rle_t. + */ +STRUCT_CONTAINER(run_container_s) { + int32_t n_runs; + int32_t capacity; + rle16_t *runs; +}; + +typedef struct run_container_s run_container_t; + +#define CAST_run(c) CAST(run_container_t *, c) // safer downcast +#define const_CAST_run(c) CAST(const run_container_t *, c) +#define movable_CAST_run(c) movable_CAST(run_container_t **, c) + +/* Create a new run container. Return NULL in case of failure. */ +run_container_t *run_container_create(void); + +/* Create a new run container with given capacity. Return NULL in case of + * failure. */ +run_container_t *run_container_create_given_capacity(int32_t size); + +/* + * Shrink the capacity to the actual size, return the number of bytes saved. + */ +int run_container_shrink_to_fit(run_container_t *src); + +/* Free memory owned by `run'. */ +void run_container_free(run_container_t *run); + +/* Duplicate container */ +run_container_t *run_container_clone(const run_container_t *src); + +/* + * Effectively deletes the value at index index, repacking data. + */ +static inline void recoverRoomAtIndex(run_container_t *run, uint16_t index) { + memmove(run->runs + index, run->runs + (1 + index), + (run->n_runs - index - 1) * sizeof(rle16_t)); + run->n_runs--; +} + +/** + * Good old binary search through rle data + */ +inline int32_t interleavedBinarySearch(const rle16_t *array, int32_t lenarray, + uint16_t ikey) { + int32_t low = 0; + int32_t high = lenarray - 1; + while (low <= high) { + int32_t middleIndex = (low + high) >> 1; + uint16_t middleValue = array[middleIndex].value; + if (middleValue < ikey) { + low = middleIndex + 1; + } else if (middleValue > ikey) { + high = middleIndex - 1; + } else { + return middleIndex; + } + } + return -(low + 1); +} + +/* + * Returns index of the run which contains $ikey + */ +static inline int32_t rle16_find_run(const rle16_t *array, int32_t lenarray, + uint16_t ikey) { + int32_t low = 0; + int32_t high = lenarray - 1; + while (low <= high) { + int32_t middleIndex = (low + high) >> 1; + uint16_t min = array[middleIndex].value; + uint16_t max = array[middleIndex].value + array[middleIndex].length; + if (ikey > max) { + low = middleIndex + 1; + } else if (ikey < min) { + high = middleIndex - 1; + } else { + return middleIndex; + } + } + return -(low + 1); +} + + +/** + * Returns number of runs which can'be be merged with the key because they + * are less than the key. + * Note that [5,6,7,8] can be merged with the key 9 and won't be counted. + */ +static inline int32_t rle16_count_less(const rle16_t* array, int32_t lenarray, + uint16_t key) { + if (lenarray == 0) return 0; + int32_t low = 0; + int32_t high = lenarray - 1; + while (low <= high) { + int32_t middleIndex = (low + high) >> 1; + uint16_t min_value = array[middleIndex].value; + uint16_t max_value = array[middleIndex].value + array[middleIndex].length; + if (max_value + UINT32_C(1) < key) { // uint32 arithmetic + low = middleIndex + 1; + } else if (key < min_value) { + high = middleIndex - 1; + } else { + return middleIndex; + } + } + return low; +} + +static inline int32_t rle16_count_greater(const rle16_t* array, int32_t lenarray, + uint16_t key) { + if (lenarray == 0) return 0; + int32_t low = 0; + int32_t high = lenarray - 1; + while (low <= high) { + int32_t middleIndex = (low + high) >> 1; + uint16_t min_value = array[middleIndex].value; + uint16_t max_value = array[middleIndex].value + array[middleIndex].length; + if (max_value < key) { + low = middleIndex + 1; + } else if (key + UINT32_C(1) < min_value) { // uint32 arithmetic + high = middleIndex - 1; + } else { + return lenarray - (middleIndex + 1); + } + } + return lenarray - low; +} + +/** + * increase capacity to at least min. Whether the + * existing data needs to be copied over depends on copy. If "copy" is false, + * then the new content will be uninitialized, otherwise a copy is made. + */ +void run_container_grow(run_container_t *run, int32_t min, bool copy); + +/** + * Moves the data so that we can write data at index + */ +static inline void makeRoomAtIndex(run_container_t *run, uint16_t index) { + /* This function calls realloc + memmove sequentially to move by one index. + * Potentially copying twice the array. + */ + if (run->n_runs + 1 > run->capacity) + run_container_grow(run, run->n_runs + 1, true); + memmove(run->runs + 1 + index, run->runs + index, + (run->n_runs - index) * sizeof(rle16_t)); + run->n_runs++; +} + +/* Add `pos' to `run'. Returns true if `pos' was not present. */ +bool run_container_add(run_container_t *run, uint16_t pos); + +/* Remove `pos' from `run'. Returns true if `pos' was present. */ +static inline bool run_container_remove(run_container_t *run, uint16_t pos) { + int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos); + if (index >= 0) { + int32_t le = run->runs[index].length; + if (le == 0) { + recoverRoomAtIndex(run, (uint16_t)index); + } else { + run->runs[index].value++; + run->runs[index].length--; + } + return true; + } + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match + int32_t offset = pos - run->runs[index].value; + int32_t le = run->runs[index].length; + if (offset < le) { + // need to break in two + run->runs[index].length = (uint16_t)(offset - 1); + // need to insert + uint16_t newvalue = pos + 1; + int32_t newlength = le - offset - 1; + makeRoomAtIndex(run, (uint16_t)(index + 1)); + run->runs[index + 1].value = newvalue; + run->runs[index + 1].length = (uint16_t)newlength; + return true; + + } else if (offset == le) { + run->runs[index].length--; + return true; + } + } + // no match + return false; +} + +/* Check whether `pos' is present in `run'. */ +inline bool run_container_contains(const run_container_t *run, uint16_t pos) { + int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos); + if (index >= 0) return true; + index = -index - 2; // points to preceding value, possibly -1 + if (index != -1) { // possible match + int32_t offset = pos - run->runs[index].value; + int32_t le = run->runs[index].length; + if (offset <= le) return true; + } + return false; +} + +/* +* Check whether all positions in a range of positions from pos_start (included) +* to pos_end (excluded) is present in `run'. +*/ +static inline bool run_container_contains_range(const run_container_t *run, + uint32_t pos_start, uint32_t pos_end) { + uint32_t count = 0; + int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos_start); + if (index < 0) { + index = -index - 2; + if ((index == -1) || ((pos_start - run->runs[index].value) > run->runs[index].length)){ + return false; + } + } + for (int32_t i = index; i < run->n_runs; ++i) { + const uint32_t stop = run->runs[i].value + run->runs[i].length; + if (run->runs[i].value >= pos_end) break; + if (stop >= pos_end) { + count += (((pos_end - run->runs[i].value) > 0) ? (pos_end - run->runs[i].value) : 0); + break; + } + const uint32_t min = (stop - pos_start) > 0 ? (stop - pos_start) : 0; + count += (min < run->runs[i].length) ? min : run->runs[i].length; + } + return count >= (pos_end - pos_start - 1); +} + +/* Get the cardinality of `run'. Requires an actual computation. */ +int run_container_cardinality(const run_container_t *run); + +/* Card > 0?, see run_container_empty for the reverse */ +static inline bool run_container_nonzero_cardinality( + const run_container_t *run) { + return run->n_runs > 0; // runs never empty +} + +/* Card == 0?, see run_container_nonzero_cardinality for the reverse */ +static inline bool run_container_empty( + const run_container_t *run) { + return run->n_runs == 0; // runs never empty +} + + + +/* Copy one container into another. We assume that they are distinct. */ +void run_container_copy(const run_container_t *src, run_container_t *dst); + +/* Set the cardinality to zero (does not release memory). */ +static inline void run_container_clear(run_container_t *run) { + run->n_runs = 0; +} + +/** + * Append run described by vl to the run container, possibly merging. + * It is assumed that the run would be inserted at the end of the container, no + * check is made. + * It is assumed that the run container has the necessary capacity: caller is + * responsible for checking memory capacity. + * + * + * This is not a safe function, it is meant for performance: use with care. + */ +static inline void run_container_append(run_container_t *run, rle16_t vl, + rle16_t *previousrl) { + const uint32_t previousend = previousrl->value + previousrl->length; + if (vl.value > previousend + 1) { // we add a new one + run->runs[run->n_runs] = vl; + run->n_runs++; + *previousrl = vl; + } else { + uint32_t newend = vl.value + vl.length + UINT32_C(1); + if (newend > previousend) { // we merge + previousrl->length = (uint16_t)(newend - 1 - previousrl->value); + run->runs[run->n_runs - 1] = *previousrl; + } + } +} + +/** + * Like run_container_append but it is assumed that the content of run is empty. + */ +static inline rle16_t run_container_append_first(run_container_t *run, + rle16_t vl) { + run->runs[run->n_runs] = vl; + run->n_runs++; + return vl; +} + +/** + * append a single value given by val to the run container, possibly merging. + * It is assumed that the value would be inserted at the end of the container, + * no check is made. + * It is assumed that the run container has the necessary capacity: caller is + * responsible for checking memory capacity. + * + * This is not a safe function, it is meant for performance: use with care. + */ +static inline void run_container_append_value(run_container_t *run, + uint16_t val, + rle16_t *previousrl) { + const uint32_t previousend = previousrl->value + previousrl->length; + if (val > previousend + 1) { // we add a new one + *previousrl = MAKE_RLE16(val, 0); + run->runs[run->n_runs] = *previousrl; + run->n_runs++; + } else if (val == previousend + 1) { // we merge + previousrl->length++; + run->runs[run->n_runs - 1] = *previousrl; + } +} + +/** + * Like run_container_append_value but it is assumed that the content of run is + * empty. + */ +static inline rle16_t run_container_append_value_first(run_container_t *run, + uint16_t val) { + rle16_t newrle = MAKE_RLE16(val, 0); + run->runs[run->n_runs] = newrle; + run->n_runs++; + return newrle; +} + +/* Check whether the container spans the whole chunk (cardinality = 1<<16). + * This check can be done in constant time (inexpensive). */ +static inline bool run_container_is_full(const run_container_t *run) { + rle16_t vl = run->runs[0]; + return (run->n_runs == 1) && (vl.value == 0) && (vl.length == 0xFFFF); +} + +/* Compute the union of `src_1' and `src_2' and write the result to `dst' + * It is assumed that `dst' is distinct from both `src_1' and `src_2'. */ +void run_container_union(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst); + +/* Compute the union of `src_1' and `src_2' and write the result to `src_1' */ +void run_container_union_inplace(run_container_t *src_1, + const run_container_t *src_2); + +/* Compute the intersection of src_1 and src_2 and write the result to + * dst. It is assumed that dst is distinct from both src_1 and src_2. */ +void run_container_intersection(const run_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst); + +/* Compute the size of the intersection of src_1 and src_2 . */ +int run_container_intersection_cardinality(const run_container_t *src_1, + const run_container_t *src_2); + +/* Check whether src_1 and src_2 intersect. */ +bool run_container_intersect(const run_container_t *src_1, + const run_container_t *src_2); + +/* Compute the symmetric difference of `src_1' and `src_2' and write the result + * to `dst' + * It is assumed that `dst' is distinct from both `src_1' and `src_2'. */ +void run_container_xor(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst); + +/* + * Write out the 16-bit integers contained in this container as a list of 32-bit + * integers using base + * as the starting value (it might be expected that base has zeros in its 16 + * least significant bits). + * The function returns the number of values written. + * The caller is responsible for allocating enough memory in out. + */ +int run_container_to_uint32_array(void *vout, const run_container_t *cont, + uint32_t base); + +/* + * Print this container using printf (useful for debugging). + */ +void run_container_printf(const run_container_t *v); + +/* + * Print this container using printf as a comma-separated list of 32-bit + * integers starting at base. + */ +void run_container_printf_as_uint32_array(const run_container_t *v, + uint32_t base); + +/** + * Return the serialized size in bytes of a container having "num_runs" runs. + */ +static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) { + return sizeof(uint16_t) + + sizeof(rle16_t) * num_runs; // each run requires 2 2-byte entries. +} + +bool run_container_iterate(const run_container_t *cont, uint32_t base, + roaring_iterator iterator, void *ptr); +bool run_container_iterate64(const run_container_t *cont, uint32_t base, + roaring_iterator64 iterator, uint64_t high_bits, + void *ptr); + +/** + * Writes the underlying array to buf, outputs how many bytes were written. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes written should be run_container_size_in_bytes(container). + */ +int32_t run_container_write(const run_container_t *container, char *buf); + +/** + * Reads the instance from buf, outputs how many bytes were read. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes read should be bitset_container_size_in_bytes(container). + * The cardinality parameter is provided for consistency with other containers, + * but + * it might be effectively ignored.. + */ +int32_t run_container_read(int32_t cardinality, run_container_t *container, + const char *buf); + +/** + * Return the serialized size in bytes of a container (see run_container_write). + * This is meant to be compatible with the Java and Go versions of Roaring. + */ +static inline int32_t run_container_size_in_bytes( + const run_container_t *container) { + return run_container_serialized_size_in_bytes(container->n_runs); +} + +/** + * Return true if the two containers have the same content. + */ +static inline bool run_container_equals(const run_container_t *container1, + const run_container_t *container2) { + if (container1->n_runs != container2->n_runs) { + return false; + } + return memequals(container1->runs, container2->runs, + container1->n_runs * sizeof(rle16_t)); +} + +/** +* Return true if container1 is a subset of container2. +*/ +bool run_container_is_subset(const run_container_t *container1, + const run_container_t *container2); + +/** + * Used in a start-finish scan that appends segments, for XOR and NOT + */ + +void run_container_smart_append_exclusive(run_container_t *src, + const uint16_t start, + const uint16_t length); + +/** +* The new container consists of a single run [start,stop). +* It is required that stop>start, the caller is responsability for this check. +* It is required that stop <= (1<<16), the caller is responsability for this check. +* The cardinality of the created container is stop - start. +* Returns NULL on failure +*/ +static inline run_container_t *run_container_create_range(uint32_t start, + uint32_t stop) { + run_container_t *rc = run_container_create_given_capacity(1); + if (rc) { + rle16_t r; + r.value = (uint16_t)start; + r.length = (uint16_t)(stop - start - 1); + run_container_append_first(rc, r); + } + return rc; +} + +/** + * If the element of given rank is in this container, supposing that the first + * element has rank start_rank, then the function returns true and sets element + * accordingly. + * Otherwise, it returns false and update start_rank. + */ +bool run_container_select(const run_container_t *container, + uint32_t *start_rank, uint32_t rank, + uint32_t *element); + +/* Compute the difference of src_1 and src_2 and write the result to + * dst. It is assumed that dst is distinct from both src_1 and src_2. */ + +void run_container_andnot(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst); + +void run_container_offset(const run_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset); + +/* Returns the smallest value (assumes not empty) */ +inline uint16_t run_container_minimum(const run_container_t *run) { + if (run->n_runs == 0) return 0; + return run->runs[0].value; +} + +/* Returns the largest value (assumes not empty) */ +inline uint16_t run_container_maximum(const run_container_t *run) { + if (run->n_runs == 0) return 0; + return run->runs[run->n_runs - 1].value + run->runs[run->n_runs - 1].length; +} + +/* Returns the number of values equal or smaller than x */ +int run_container_rank(const run_container_t *arr, uint16_t x); + +/* Returns the index of the first run containing a value at least as large as x, or -1 */ +inline int run_container_index_equalorlarger(const run_container_t *arr, uint16_t x) { + int32_t index = interleavedBinarySearch(arr->runs, arr->n_runs, x); + if (index >= 0) return index; + index = -index - 2; // points to preceding run, possibly -1 + if (index != -1) { // possible match + int32_t offset = x - arr->runs[index].value; + int32_t le = arr->runs[index].length; + if (offset <= le) return index; + } + index += 1; + if(index < arr->n_runs) { + return index; + } + return -1; +} + +/* + * Add all values in range [min, max] using hint. + */ +static inline void run_container_add_range_nruns(run_container_t* run, + uint32_t min, uint32_t max, + int32_t nruns_less, + int32_t nruns_greater) { + int32_t nruns_common = run->n_runs - nruns_less - nruns_greater; + if (nruns_common == 0) { + makeRoomAtIndex(run, nruns_less); + run->runs[nruns_less].value = min; + run->runs[nruns_less].length = max - min; + } else { + uint32_t common_min = run->runs[nruns_less].value; + uint32_t common_max = run->runs[nruns_less + nruns_common - 1].value + + run->runs[nruns_less + nruns_common - 1].length; + uint32_t result_min = (common_min < min) ? common_min : min; + uint32_t result_max = (common_max > max) ? common_max : max; + + run->runs[nruns_less].value = result_min; + run->runs[nruns_less].length = result_max - result_min; + + memmove(&(run->runs[nruns_less + 1]), + &(run->runs[run->n_runs - nruns_greater]), + nruns_greater*sizeof(rle16_t)); + run->n_runs = nruns_less + 1 + nruns_greater; + } +} + +/** + * Add all values in range [min, max] + */ +static inline void run_container_add_range(run_container_t* run, + uint32_t min, uint32_t max) { + int32_t nruns_greater = rle16_count_greater(run->runs, run->n_runs, max); + int32_t nruns_less = rle16_count_less(run->runs, run->n_runs - nruns_greater, min); + run_container_add_range_nruns(run, min, max, nruns_less, nruns_greater); +} + +/** + * Shifts last $count elements either left (distance < 0) or right (distance > 0) + */ +static inline void run_container_shift_tail(run_container_t* run, + int32_t count, int32_t distance) { + if (distance > 0) { + if (run->capacity < count+distance) { + run_container_grow(run, count+distance, true); + } + } + int32_t srcpos = run->n_runs - count; + int32_t dstpos = srcpos + distance; + memmove(&(run->runs[dstpos]), &(run->runs[srcpos]), sizeof(rle16_t) * count); + run->n_runs += distance; +} + +/** + * Remove all elements in range [min, max] + */ +static inline void run_container_remove_range(run_container_t *run, uint32_t min, uint32_t max) { + int32_t first = rle16_find_run(run->runs, run->n_runs, min); + int32_t last = rle16_find_run(run->runs, run->n_runs, max); + + if (first >= 0 && min > run->runs[first].value && + max < ((uint32_t)run->runs[first].value + (uint32_t)run->runs[first].length)) { + // split this run into two adjacent runs + + // right subinterval + makeRoomAtIndex(run, first+1); + run->runs[first+1].value = max + 1; + run->runs[first+1].length = (run->runs[first].value + run->runs[first].length) - (max + 1); + + // left subinterval + run->runs[first].length = (min - 1) - run->runs[first].value; + + return; + } + + // update left-most partial run + if (first >= 0) { + if (min > run->runs[first].value) { + run->runs[first].length = (min - 1) - run->runs[first].value; + first++; + } + } else { + first = -first-1; + } + + // update right-most run + if (last >= 0) { + uint16_t run_max = run->runs[last].value + run->runs[last].length; + if (run_max > max) { + run->runs[last].value = max + 1; + run->runs[last].length = run_max - (max + 1); + last--; + } + } else { + last = (-last-1) - 1; + } + + // remove intermediate runs + if (first <= last) { + run_container_shift_tail(run, run->n_runs - (last+1), -(last-first+1)); + } +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_RUN_H_ */ +/* end file include/roaring/containers/run.h */ +/* begin file include/roaring/containers/convert.h */ +/* + * convert.h + * + */ + +#ifndef INCLUDE_CONTAINERS_CONVERT_H_ +#define INCLUDE_CONTAINERS_CONVERT_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Convert an array into a bitset. The input container is not freed or modified. + */ +bitset_container_t *bitset_container_from_array(const array_container_t *arr); + +/* Convert a run into a bitset. The input container is not freed or modified. */ +bitset_container_t *bitset_container_from_run(const run_container_t *arr); + +/* Convert a run into an array. The input container is not freed or modified. */ +array_container_t *array_container_from_run(const run_container_t *arr); + +/* Convert a bitset into an array. The input container is not freed or modified. + */ +array_container_t *array_container_from_bitset(const bitset_container_t *bits); + +/* Convert an array into a run. The input container is not freed or modified. + */ +run_container_t *run_container_from_array(const array_container_t *c); + +/* convert a run into either an array or a bitset + * might free the container. This does not free the input run container. */ +container_t *convert_to_bitset_or_array_container( + run_container_t *rc, int32_t card, + uint8_t *resulttype); + +/* convert containers to and from runcontainers, as is most space efficient. + * The container might be freed. */ +container_t *convert_run_optimize( + container_t *c, uint8_t typecode_original, + uint8_t *typecode_after); + +/* converts a run container to either an array or a bitset, IF it saves space. + */ +/* If a conversion occurs, the caller is responsible to free the original + * container and + * he becomes reponsible to free the new one. */ +container_t *convert_run_to_efficient_container( + run_container_t *c, uint8_t *typecode_after); + +// like convert_run_to_efficient_container but frees the old result if needed +container_t *convert_run_to_efficient_container_and_free( + run_container_t *c, uint8_t *typecode_after); + +/** + * Create new container which is a union of run container and + * range [min, max]. Caller is responsible for freeing run container. + */ +container_t *container_from_run_range( + const run_container_t *run, + uint32_t min, uint32_t max, + uint8_t *typecode_after); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_CONVERT_H_ */ +/* end file include/roaring/containers/convert.h */ +/* begin file include/roaring/containers/mixed_equal.h */ +/* + * mixed_equal.h + * + */ + +#ifndef CONTAINERS_MIXED_EQUAL_H_ +#define CONTAINERS_MIXED_EQUAL_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/** + * Return true if the two containers have the same content. + */ +bool array_container_equal_bitset(const array_container_t* container1, + const bitset_container_t* container2); + +/** + * Return true if the two containers have the same content. + */ +bool run_container_equals_array(const run_container_t* container1, + const array_container_t* container2); +/** + * Return true if the two containers have the same content. + */ +bool run_container_equals_bitset(const run_container_t* container1, + const bitset_container_t* container2); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* CONTAINERS_MIXED_EQUAL_H_ */ +/* end file include/roaring/containers/mixed_equal.h */ +/* begin file include/roaring/containers/mixed_subset.h */ +/* + * mixed_subset.h + * + */ + +#ifndef CONTAINERS_MIXED_SUBSET_H_ +#define CONTAINERS_MIXED_SUBSET_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/** + * Return true if container1 is a subset of container2. + */ +bool array_container_is_subset_bitset(const array_container_t* container1, + const bitset_container_t* container2); + +/** +* Return true if container1 is a subset of container2. + */ +bool run_container_is_subset_array(const run_container_t* container1, + const array_container_t* container2); + +/** +* Return true if container1 is a subset of container2. + */ +bool array_container_is_subset_run(const array_container_t* container1, + const run_container_t* container2); + +/** +* Return true if container1 is a subset of container2. + */ +bool run_container_is_subset_bitset(const run_container_t* container1, + const bitset_container_t* container2); + +/** +* Return true if container1 is a subset of container2. +*/ +bool bitset_container_is_subset_run(const bitset_container_t* container1, + const run_container_t* container2); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* CONTAINERS_MIXED_SUBSET_H_ */ +/* end file include/roaring/containers/mixed_subset.h */ +/* begin file include/roaring/containers/mixed_andnot.h */ +/* + * mixed_andnot.h + */ +#ifndef INCLUDE_CONTAINERS_MIXED_ANDNOT_H_ +#define INCLUDE_CONTAINERS_MIXED_ANDNOT_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst, a valid array container that could be the same as dst.*/ +void array_bitset_container_andnot(const array_container_t *src_1, + const bitset_container_t *src_2, + array_container_t *dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * src_1 */ + +void array_bitset_container_iandnot(array_container_t *src_1, + const bitset_container_t *src_2); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst, which does not initially have a valid container. + * Return true for a bitset result; false for array + */ + +bool bitset_array_container_andnot( + const bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_array_container_iandnot( + bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_andnot( + const run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_iandnot( + run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool bitset_run_container_andnot( + const bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_run_container_iandnot( + bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* dst does not indicate a valid container initially. Eventually it + * can become any type of container. + */ + +int run_array_container_andnot( + const run_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +int run_array_container_iandnot( + run_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* dst must be a valid array container, allowed to be src_1 */ + +void array_run_container_andnot(const array_container_t *src_1, + const run_container_t *src_2, + array_container_t *dst); + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +void array_run_container_iandnot(array_container_t *src_1, + const run_container_t *src_2); + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int run_run_container_andnot( + const run_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +int run_run_container_iandnot( + run_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* + * dst is a valid array container and may be the same as src_1 + */ + +void array_array_container_andnot(const array_container_t *src_1, + const array_container_t *src_2, + array_container_t *dst); + +/* inplace array-array andnot will always be able to reuse the space of + * src_1 */ +void array_array_container_iandnot(array_container_t *src_1, + const array_container_t *src_2); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). Return value is + * "dst is a bitset" + */ + +bool bitset_bitset_container_andnot( + const bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_bitset_container_iandnot( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif +/* end file include/roaring/containers/mixed_andnot.h */ +/* begin file include/roaring/containers/mixed_intersection.h */ +/* + * mixed_intersection.h + * + */ + +#ifndef INCLUDE_CONTAINERS_MIXED_INTERSECTION_H_ +#define INCLUDE_CONTAINERS_MIXED_INTERSECTION_H_ + +/* These functions appear to exclude cases where the + * inputs have the same type and the output is guaranteed + * to have the same type as the inputs. Eg, array intersection + */ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the intersection of src_1 and src_2 and write the result to + * dst. It is allowed for dst to be equal to src_1. We assume that dst is a + * valid container. */ +void array_bitset_container_intersection(const array_container_t *src_1, + const bitset_container_t *src_2, + array_container_t *dst); + +/* Compute the size of the intersection of src_1 and src_2. */ +int array_bitset_container_intersection_cardinality( + const array_container_t *src_1, const bitset_container_t *src_2); + + + +/* Checking whether src_1 and src_2 intersect. */ +bool array_bitset_container_intersect(const array_container_t *src_1, + const bitset_container_t *src_2); + +/* + * Compute the intersection between src_1 and src_2 and write the result + * to *dst. If the return function is true, the result is a bitset_container_t + * otherwise is a array_container_t. We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool bitset_bitset_container_intersection(const bitset_container_t *src_1, + const bitset_container_t *src_2, + container_t **dst); + +/* Compute the intersection between src_1 and src_2 and write the result to + * dst. It is allowed for dst to be equal to src_1. We assume that dst is a + * valid container. */ +void array_run_container_intersection(const array_container_t *src_1, + const run_container_t *src_2, + array_container_t *dst); + +/* Compute the intersection between src_1 and src_2 and write the result to + * *dst. If the result is true then the result is a bitset_container_t + * otherwise is a array_container_t. + * If *dst == src_2, then an in-place intersection is attempted + **/ +bool run_bitset_container_intersection(const run_container_t *src_1, + const bitset_container_t *src_2, + container_t **dst); + +/* Compute the size of the intersection between src_1 and src_2 . */ +int array_run_container_intersection_cardinality(const array_container_t *src_1, + const run_container_t *src_2); + +/* Compute the size of the intersection between src_1 and src_2 + **/ +int run_bitset_container_intersection_cardinality(const run_container_t *src_1, + const bitset_container_t *src_2); + + +/* Check that src_1 and src_2 intersect. */ +bool array_run_container_intersect(const array_container_t *src_1, + const run_container_t *src_2); + +/* Check that src_1 and src_2 intersect. + **/ +bool run_bitset_container_intersect(const run_container_t *src_1, + const bitset_container_t *src_2); + +/* + * Same as bitset_bitset_container_intersection except that if the output is to + * be a + * bitset_container_t, then src_1 is modified and no allocation is made. + * If the output is to be an array_container_t, then caller is responsible + * to free the container. + * In all cases, the result is in *dst. + */ +bool bitset_bitset_container_intersection_inplace( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_MIXED_INTERSECTION_H_ */ +/* end file include/roaring/containers/mixed_intersection.h */ +/* begin file include/roaring/containers/mixed_negation.h */ +/* + * mixed_negation.h + * + */ + +#ifndef INCLUDE_CONTAINERS_MIXED_NEGATION_H_ +#define INCLUDE_CONTAINERS_MIXED_NEGATION_H_ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Negation across the entire range of the container. + * Compute the negation of src and write the result + * to *dst. The complement of a + * sufficiently sparse set will always be dense and a hence a bitmap + * We assume that dst is pre-allocated and a valid bitset container + * There can be no in-place version. + */ +void array_container_negation(const array_container_t *src, + bitset_container_t *dst); + +/* Negation across the entire range of the container + * Compute the negation of src and write the result + * to *dst. A true return value indicates a bitset result, + * otherwise the result is an array container. + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool bitset_container_negation( + const bitset_container_t *src, + container_t **dst); + +/* inplace version */ +/* + * Same as bitset_container_negation except that if the output is to + * be a + * bitset_container_t, then src is modified and no allocation is made. + * If the output is to be an array_container_t, then caller is responsible + * to free the container. + * In all cases, the result is in *dst. + */ +bool bitset_container_negation_inplace( + bitset_container_t *src, + container_t **dst); + +/* Negation across the entire range of container + * Compute the negation of src and write the result + * to *dst. + * Return values are the *_TYPECODES as defined * in containers.h + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +int run_container_negation(const run_container_t *src, container_t **dst); + +/* + * Same as run_container_negation except that if the output is to + * be a + * run_container_t, and has the capacity to hold the result, + * then src is modified and no allocation is made. + * In all cases, the result is in *dst. + */ +int run_container_negation_inplace(run_container_t *src, container_t **dst); + +/* Negation across a range of the container. + * Compute the negation of src and write the result + * to *dst. Returns true if the result is a bitset container + * and false for an array container. *dst is not preallocated. + */ +bool array_container_negation_range( + const array_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +/* Even when the result would fit, it is unclear how to make an + * inplace version without inefficient copying. Thus this routine + * may be a wrapper for the non-in-place version + */ +bool array_container_negation_range_inplace( + array_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +/* Negation across a range of the container + * Compute the negation of src and write the result + * to *dst. A true return value indicates a bitset result, + * otherwise the result is an array container. + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool bitset_container_negation_range( + const bitset_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +/* inplace version */ +/* + * Same as bitset_container_negation except that if the output is to + * be a + * bitset_container_t, then src is modified and no allocation is made. + * If the output is to be an array_container_t, then caller is responsible + * to free the container. + * In all cases, the result is in *dst. + */ +bool bitset_container_negation_range_inplace( + bitset_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +/* Negation across a range of container + * Compute the negation of src and write the result + * to *dst. Return values are the *_TYPECODES as defined * in containers.h + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +int run_container_negation_range( + const run_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +/* + * Same as run_container_negation except that if the output is to + * be a + * run_container_t, and has the capacity to hold the result, + * then src is modified and no allocation is made. + * In all cases, the result is in *dst. + */ +int run_container_negation_range_inplace( + run_container_t *src, + const int range_start, const int range_end, + container_t **dst); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_MIXED_NEGATION_H_ */ +/* end file include/roaring/containers/mixed_negation.h */ +/* begin file include/roaring/containers/mixed_union.h */ +/* + * mixed_intersection.h + * + */ + +#ifndef INCLUDE_CONTAINERS_MIXED_UNION_H_ +#define INCLUDE_CONTAINERS_MIXED_UNION_H_ + +/* These functions appear to exclude cases where the + * inputs have the same type and the output is guaranteed + * to have the same type as the inputs. Eg, bitset unions + */ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the union of src_1 and src_2 and write the result to + * dst. It is allowed for src_2 to be dst. */ +void array_bitset_container_union(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Compute the union of src_1 and src_2 and write the result to + * dst. It is allowed for src_2 to be dst. This version does not + * update the cardinality of dst (it is set to BITSET_UNKNOWN_CARDINALITY). */ +void array_bitset_container_lazy_union(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* + * Compute the union between src_1 and src_2 and write the result + * to *dst. If the return function is true, the result is a bitset_container_t + * otherwise is a array_container_t. We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool array_array_container_union( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* + * Compute the union between src_1 and src_2 and write the result + * to *dst if it cannot be written to src_1. If the return function is true, + * the result is a bitset_container_t + * otherwise is a array_container_t. When the result is an array_container_t, it + * it either written to src_1 (if *dst is null) or to *dst. + * If the result is a bitset_container_t and *dst is null, then there was a failure. + */ +bool array_array_container_inplace_union( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* + * Same as array_array_container_union except that it will more eagerly produce + * a bitset. + */ +bool array_array_container_lazy_union( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* + * Same as array_array_container_inplace_union except that it will more eagerly produce + * a bitset. + */ +bool array_array_container_lazy_inplace_union( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* Compute the union of src_1 and src_2 and write the result to + * dst. We assume that dst is a + * valid container. The result might need to be further converted to array or + * bitset container, + * the caller is responsible for the eventual conversion. */ +void array_run_container_union(const array_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst); + +/* Compute the union of src_1 and src_2 and write the result to + * src2. The result might need to be further converted to array or + * bitset container, + * the caller is responsible for the eventual conversion. */ +void array_run_container_inplace_union(const array_container_t *src_1, + run_container_t *src_2); + +/* Compute the union of src_1 and src_2 and write the result to + * dst. It is allowed for dst to be src_2. + * If run_container_is_full(src_1) is true, you must not be calling this + *function. + **/ +void run_bitset_container_union(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* Compute the union of src_1 and src_2 and write the result to + * dst. It is allowed for dst to be src_2. This version does not + * update the cardinality of dst (it is set to BITSET_UNKNOWN_CARDINALITY). + * If run_container_is_full(src_1) is true, you must not be calling this + * function. + * */ +void run_bitset_container_lazy_union(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif /* INCLUDE_CONTAINERS_MIXED_UNION_H_ */ +/* end file include/roaring/containers/mixed_union.h */ +/* begin file include/roaring/containers/mixed_xor.h */ +/* + * mixed_xor.h + * + */ + +#ifndef INCLUDE_CONTAINERS_MIXED_XOR_H_ +#define INCLUDE_CONTAINERS_MIXED_XOR_H_ + +/* These functions appear to exclude cases where the + * inputs have the same type and the output is guaranteed + * to have the same type as the inputs. Eg, bitset unions + */ + +/* + * Java implementation (as of May 2016) for array_run, run_run + * and bitset_run don't do anything different for inplace. + * (They are not truly in place.) + */ + + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). + * Result is true iff dst is a bitset */ +bool array_bitset_container_xor( + const array_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. It is allowed for src_2 to be dst. This version does not + * update the cardinality of dst (it is set to BITSET_UNKNOWN_CARDINALITY). + */ + +void array_bitset_container_lazy_xor(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). Return value is + * "dst is a bitset" + */ + +bool bitset_bitset_container_xor( + const bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_xor( + const run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* lazy xor. Dst is initialized and may be equal to src_2. + * Result is left as a bitset container, even if actual + * cardinality would dictate an array container. + */ + +void run_bitset_container_lazy_xor(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst); + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int array_run_container_xor( + const array_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* dst does not initially have a valid container. Creates either + * an array or a bitset container, indicated by return code + */ + +bool array_array_container_xor( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* dst does not initially have a valid container. Creates either + * an array or a bitset container, indicated by return code. + * A bitset container will not have a valid cardinality and the + * container type might not be correct for the actual cardinality + */ + +bool array_array_container_lazy_xor( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +/* Dst is a valid run container. (Can it be src_2? Let's say not.) + * Leaves result as run container, even if other options are + * smaller. + */ + +void array_run_container_lazy_xor(const array_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst); + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int run_run_container_xor( + const run_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* INPLACE versions (initial implementation may not exploit all inplace + * opportunities (if any...) + */ + +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_array_container_ixor( + bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +bool bitset_bitset_container_ixor( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +bool array_bitset_container_ixor( + array_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_ixor( + run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst); + +bool bitset_run_container_ixor( + bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int array_run_container_ixor( + array_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +int run_array_container_ixor( + run_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +bool array_array_container_ixor( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst); + +int run_run_container_ixor( + run_container_t *src_1, const run_container_t *src_2, + container_t **dst); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif +/* end file include/roaring/containers/mixed_xor.h */ +/* begin file include/roaring/containers/containers.h */ +#ifndef CONTAINERS_CONTAINERS_H +#define CONTAINERS_CONTAINERS_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +// would enum be possible or better? + +/** + * The switch case statements follow + * BITSET_CONTAINER_TYPE -- ARRAY_CONTAINER_TYPE -- RUN_CONTAINER_TYPE + * so it makes more sense to number them 1, 2, 3 (in the vague hope that the + * compiler might exploit this ordering). + */ + +#define BITSET_CONTAINER_TYPE 1 +#define ARRAY_CONTAINER_TYPE 2 +#define RUN_CONTAINER_TYPE 3 +#define SHARED_CONTAINER_TYPE 4 + +/** + * Macros for pairing container type codes, suitable for switch statements. + * Use PAIR_CONTAINER_TYPES() for the switch, CONTAINER_PAIR() for the cases: + * + * switch (PAIR_CONTAINER_TYPES(type1, type2)) { + * case CONTAINER_PAIR(BITSET,ARRAY): + * ... + * } + */ +#define PAIR_CONTAINER_TYPES(type1,type2) \ + (4 * (type1) + (type2)) + +#define CONTAINER_PAIR(name1,name2) \ + (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE)) + +/** + * A shared container is a wrapper around a container + * with reference counting. + */ + +STRUCT_CONTAINER(shared_container_s) { + container_t *container; + uint8_t typecode; + uint32_t counter; // to be managed atomically +}; + +typedef struct shared_container_s shared_container_t; + +#define CAST_shared(c) CAST(shared_container_t *, c) // safer downcast +#define const_CAST_shared(c) CAST(const shared_container_t *, c) +#define movable_CAST_shared(c) movable_CAST(shared_container_t **, c) + +/* + * With copy_on_write = true + * Create a new shared container if the typecode is not SHARED_CONTAINER_TYPE, + * otherwise, increase the count + * If copy_on_write = false, then clone. + * Return NULL in case of failure. + **/ +container_t *get_copy_of_container(container_t *container, uint8_t *typecode, + bool copy_on_write); + +/* Frees a shared container (actually decrement its counter and only frees when + * the counter falls to zero). */ +void shared_container_free(shared_container_t *container); + +/* extract a copy from the shared container, freeing the shared container if +there is just one instance left, +clone instances when the counter is higher than one +*/ +container_t *shared_container_extract_copy(shared_container_t *container, + uint8_t *typecode); + +/* access to container underneath */ +static inline const container_t *container_unwrap_shared( + const container_t *candidate_shared_container, uint8_t *type +){ + if (*type == SHARED_CONTAINER_TYPE) { + *type = const_CAST_shared(candidate_shared_container)->typecode; + assert(*type != SHARED_CONTAINER_TYPE); + return const_CAST_shared(candidate_shared_container)->container; + } else { + return candidate_shared_container; + } +} + + +/* access to container underneath */ +static inline container_t *container_mutable_unwrap_shared( + container_t *c, uint8_t *type +) { + if (*type == SHARED_CONTAINER_TYPE) { // the passed in container is shared + *type = CAST_shared(c)->typecode; + assert(*type != SHARED_CONTAINER_TYPE); + return CAST_shared(c)->container; // return the enclosed container + } else { + return c; // wasn't shared, so return as-is + } +} + +/* access to container underneath and queries its type */ +static inline uint8_t get_container_type( + const container_t *c, uint8_t type +){ + if (type == SHARED_CONTAINER_TYPE) { + return const_CAST_shared(c)->typecode; + } else { + return type; + } +} + +/** + * Copies a container, requires a typecode. This allocates new memory, caller + * is responsible for deallocation. If the container is not shared, then it is + * physically cloned. Sharable containers are not cloneable. + */ +container_t *container_clone(const container_t *container, uint8_t typecode); + +/* access to container underneath, cloning it if needed */ +static inline container_t *get_writable_copy_if_shared( + container_t *c, uint8_t *type +){ + if (*type == SHARED_CONTAINER_TYPE) { // shared, return enclosed container + return shared_container_extract_copy(CAST_shared(c), type); + } else { + return c; // not shared, so return as-is + } +} + +/** + * End of shared container code + */ + +static const char *container_names[] = {"bitset", "array", "run", "shared"}; +static const char *shared_container_names[] = { + "bitset (shared)", "array (shared)", "run (shared)"}; + +// no matter what the initial container was, convert it to a bitset +// if a new container is produced, caller responsible for freeing the previous +// one +// container should not be a shared container +static inline bitset_container_t *container_to_bitset( + container_t *c, uint8_t typecode +){ + bitset_container_t *result = NULL; + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return CAST_bitset(c); // nothing to do + case ARRAY_CONTAINER_TYPE: + result = bitset_container_from_array(CAST_array(c)); + return result; + case RUN_CONTAINER_TYPE: + result = bitset_container_from_run(CAST_run(c)); + return result; + case SHARED_CONTAINER_TYPE: + assert(false); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * Get the container name from the typecode + * (unused at time of writing) + */ +static inline const char *get_container_name(uint8_t typecode) { + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return container_names[0]; + case ARRAY_CONTAINER_TYPE: + return container_names[1]; + case RUN_CONTAINER_TYPE: + return container_names[2]; + case SHARED_CONTAINER_TYPE: + return container_names[3]; + default: + assert(false); + __builtin_unreachable(); + return "unknown"; + } +} + +static inline const char *get_full_container_name( + const container_t *c, uint8_t typecode +){ + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return container_names[0]; + case ARRAY_CONTAINER_TYPE: + return container_names[1]; + case RUN_CONTAINER_TYPE: + return container_names[2]; + case SHARED_CONTAINER_TYPE: + switch (const_CAST_shared(c)->typecode) { + case BITSET_CONTAINER_TYPE: + return shared_container_names[0]; + case ARRAY_CONTAINER_TYPE: + return shared_container_names[1]; + case RUN_CONTAINER_TYPE: + return shared_container_names[2]; + default: + assert(false); + __builtin_unreachable(); + return "unknown"; + } + break; + default: + assert(false); + __builtin_unreachable(); + return "unknown"; + } + __builtin_unreachable(); + return NULL; +} + +/** + * Get the container cardinality (number of elements), requires a typecode + */ +static inline int container_get_cardinality( + const container_t *c, uint8_t typecode +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_cardinality(const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_cardinality(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_cardinality(const_CAST_run(c)); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + + + +// returns true if a container is known to be full. Note that a lazy bitset +// container +// might be full without us knowing +static inline bool container_is_full(const container_t *c, uint8_t typecode) { + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_cardinality( + const_CAST_bitset(c)) == (1 << 16); + case ARRAY_CONTAINER_TYPE: + return array_container_cardinality( + const_CAST_array(c)) == (1 << 16); + case RUN_CONTAINER_TYPE: + return run_container_is_full(const_CAST_run(c)); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +static inline int container_shrink_to_fit( + container_t *c, uint8_t type +){ + c = container_mutable_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return 0; // no shrinking possible + case ARRAY_CONTAINER_TYPE: + return array_container_shrink_to_fit(CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_shrink_to_fit(CAST_run(c)); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + + +/** + * make a container with a run of ones + */ +/* initially always use a run container, even if an array might be + * marginally + * smaller */ +static inline container_t *container_range_of_ones( + uint32_t range_start, uint32_t range_end, + uint8_t *result_type +){ + assert(range_end >= range_start); + uint64_t cardinality = range_end - range_start + 1; + if(cardinality <= 2) { + *result_type = ARRAY_CONTAINER_TYPE; + return array_container_create_range(range_start, range_end); + } else { + *result_type = RUN_CONTAINER_TYPE; + return run_container_create_range(range_start, range_end); + } +} + + +/* Create a container with all the values between in [min,max) at a + distance k*step from min. */ +static inline container_t *container_from_range( + uint8_t *type, uint32_t min, + uint32_t max, uint16_t step +){ + if (step == 0) return NULL; // being paranoid + if (step == 1) { + return container_range_of_ones(min,max,type); + // Note: the result is not always a run (need to check the cardinality) + //*type = RUN_CONTAINER_TYPE; + //return run_container_create_range(min, max); + } + int size = (max - min + step - 1) / step; + if (size <= DEFAULT_MAX_SIZE) { // array container + *type = ARRAY_CONTAINER_TYPE; + array_container_t *array = array_container_create_given_capacity(size); + array_container_add_from_range(array, min, max, step); + assert(array->cardinality == size); + return array; + } else { // bitset container + *type = BITSET_CONTAINER_TYPE; + bitset_container_t *bitset = bitset_container_create(); + bitset_container_add_from_range(bitset, min, max, step); + assert(bitset->cardinality == size); + return bitset; + } +} + +/** + * "repair" the container after lazy operations. + */ +static inline container_t *container_repair_after_lazy( + container_t *c, uint8_t *type +){ + c = get_writable_copy_if_shared(c, type); // !!! unnecessary cloning + container_t *result = NULL; + switch (*type) { + case BITSET_CONTAINER_TYPE: { + bitset_container_t *bc = CAST_bitset(c); + bc->cardinality = bitset_container_compute_cardinality(bc); + if (bc->cardinality <= DEFAULT_MAX_SIZE) { + result = array_container_from_bitset(bc); + bitset_container_free(bc); + *type = ARRAY_CONTAINER_TYPE; + return result; + } + return c; } + case ARRAY_CONTAINER_TYPE: + return c; // nothing to do + case RUN_CONTAINER_TYPE: + return convert_run_to_efficient_container_and_free( + CAST_run(c), type); + case SHARED_CONTAINER_TYPE: + assert(false); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * Writes the underlying array to buf, outputs how many bytes were written. + * This is meant to be byte-by-byte compatible with the Java and Go versions of + * Roaring. + * The number of bytes written should be + * container_write(container, buf). + * + */ +static inline int32_t container_write( + const container_t *c, uint8_t typecode, + char *buf +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_write(const_CAST_bitset(c), buf); + case ARRAY_CONTAINER_TYPE: + return array_container_write(const_CAST_array(c), buf); + case RUN_CONTAINER_TYPE: + return run_container_write(const_CAST_run(c), buf); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * Get the container size in bytes under portable serialization (see + * container_write), requires a + * typecode + */ +static inline int32_t container_size_in_bytes( + const container_t *c, uint8_t typecode +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_size_in_bytes(const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_size_in_bytes(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_size_in_bytes(const_CAST_run(c)); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * print the container (useful for debugging), requires a typecode + */ +void container_printf(const container_t *container, uint8_t typecode); + +/** + * print the content of the container as a comma-separated list of 32-bit values + * starting at base, requires a typecode + */ +void container_printf_as_uint32_array(const container_t *container, + uint8_t typecode, uint32_t base); + +/** + * Checks whether a container is not empty, requires a typecode + */ +static inline bool container_nonzero_cardinality( + const container_t *c, uint8_t typecode +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_const_nonzero_cardinality( + const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_nonzero_cardinality(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_nonzero_cardinality(const_CAST_run(c)); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * Recover memory from a container, requires a typecode + */ +void container_free(container_t *container, uint8_t typecode); + +/** + * Convert a container to an array of values, requires a typecode as well as a + * "base" (most significant values) + * Returns number of ints added. + */ +static inline int container_to_uint32_array( + uint32_t *output, + const container_t *c, uint8_t typecode, + uint32_t base +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_to_uint32_array( + output, const_CAST_bitset(c), base); + case ARRAY_CONTAINER_TYPE: + return array_container_to_uint32_array( + output, const_CAST_array(c), base); + case RUN_CONTAINER_TYPE: + return run_container_to_uint32_array( + output, const_CAST_run(c), base); + } + assert(false); + __builtin_unreachable(); + return 0; // unreached +} + +/** + * Add a value to a container, requires a typecode, fills in new_typecode and + * return (possibly different) container. + * This function may allocate a new container, and caller is responsible for + * memory deallocation + */ +static inline container_t *container_add( + container_t *c, uint16_t val, + uint8_t typecode, // !!! should be second argument? + uint8_t *new_typecode +){ + c = get_writable_copy_if_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + bitset_container_set(CAST_bitset(c), val); + *new_typecode = BITSET_CONTAINER_TYPE; + return c; + case ARRAY_CONTAINER_TYPE: { + array_container_t *ac = CAST_array(c); + if (array_container_try_add(ac, val, DEFAULT_MAX_SIZE) != -1) { + *new_typecode = ARRAY_CONTAINER_TYPE; + return ac; + } else { + bitset_container_t* bitset = bitset_container_from_array(ac); + bitset_container_add(bitset, val); + *new_typecode = BITSET_CONTAINER_TYPE; + return bitset; + } + } break; + case RUN_CONTAINER_TYPE: + // per Java, no container type adjustments are done (revisit?) + run_container_add(CAST_run(c), val); + *new_typecode = RUN_CONTAINER_TYPE; + return c; + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Remove a value from a container, requires a typecode, fills in new_typecode + * and + * return (possibly different) container. + * This function may allocate a new container, and caller is responsible for + * memory deallocation + */ +static inline container_t *container_remove( + container_t *c, uint16_t val, + uint8_t typecode, // !!! should be second argument? + uint8_t *new_typecode +){ + c = get_writable_copy_if_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + if (bitset_container_remove(CAST_bitset(c), val)) { + int card = bitset_container_cardinality(CAST_bitset(c)); + if (card <= DEFAULT_MAX_SIZE) { + *new_typecode = ARRAY_CONTAINER_TYPE; + return array_container_from_bitset(CAST_bitset(c)); + } + } + *new_typecode = typecode; + return c; + case ARRAY_CONTAINER_TYPE: + *new_typecode = typecode; + array_container_remove(CAST_array(c), val); + return c; + case RUN_CONTAINER_TYPE: + // per Java, no container type adjustments are done (revisit?) + run_container_remove(CAST_run(c), val); + *new_typecode = RUN_CONTAINER_TYPE; + return c; + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Check whether a value is in a container, requires a typecode + */ +static inline bool container_contains( + const container_t *c, + uint16_t val, + uint8_t typecode // !!! should be second argument? +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_get(const_CAST_bitset(c), val); + case ARRAY_CONTAINER_TYPE: + return array_container_contains(const_CAST_array(c), val); + case RUN_CONTAINER_TYPE: + return run_container_contains(const_CAST_run(c), val); + default: + assert(false); + __builtin_unreachable(); + return false; + } +} + +/** + * Check whether a range of values from range_start (included) to range_end (excluded) + * is in a container, requires a typecode + */ +static inline bool container_contains_range( + const container_t *c, + uint32_t range_start, uint32_t range_end, + uint8_t typecode // !!! should be second argument? +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_get_range(const_CAST_bitset(c), + range_start, range_end); + case ARRAY_CONTAINER_TYPE: + return array_container_contains_range(const_CAST_array(c), + range_start, range_end); + case RUN_CONTAINER_TYPE: + return run_container_contains_range(const_CAST_run(c), + range_start, range_end); + default: + assert(false); + __builtin_unreachable(); + return false; + } +} + +/** + * Returns true if the two containers have the same content. Note that + * two containers having different types can be "equal" in this sense. + */ +static inline bool container_equals( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2 +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + return bitset_container_equals(const_CAST_bitset(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,RUN): + return run_container_equals_bitset(const_CAST_run(c2), + const_CAST_bitset(c1)); + + case CONTAINER_PAIR(RUN,BITSET): + return run_container_equals_bitset(const_CAST_run(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,ARRAY): + // java would always return false? + return array_container_equal_bitset(const_CAST_array(c2), + const_CAST_bitset(c1)); + + case CONTAINER_PAIR(ARRAY,BITSET): + // java would always return false? + return array_container_equal_bitset(const_CAST_array(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,RUN): + return run_container_equals_array(const_CAST_run(c2), + const_CAST_array(c1)); + + case CONTAINER_PAIR(RUN,ARRAY): + return run_container_equals_array(const_CAST_run(c1), + const_CAST_array(c2)); + + case CONTAINER_PAIR(ARRAY,ARRAY): + return array_container_equals(const_CAST_array(c1), + const_CAST_array(c2)); + + case CONTAINER_PAIR(RUN,RUN): + return run_container_equals(const_CAST_run(c1), + const_CAST_run(c2)); + + default: + assert(false); + __builtin_unreachable(); + return false; + } +} + +/** + * Returns true if the container c1 is a subset of the container c2. Note that + * c1 can be a subset of c2 even if they have a different type. + */ +static inline bool container_is_subset( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2 +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + return bitset_container_is_subset(const_CAST_bitset(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,RUN): + return bitset_container_is_subset_run(const_CAST_bitset(c1), + const_CAST_run(c2)); + + case CONTAINER_PAIR(RUN,BITSET): + return run_container_is_subset_bitset(const_CAST_run(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,ARRAY): + return false; // by construction, size(c1) > size(c2) + + case CONTAINER_PAIR(ARRAY,BITSET): + return array_container_is_subset_bitset(const_CAST_array(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,RUN): + return array_container_is_subset_run(const_CAST_array(c1), + const_CAST_run(c2)); + + case CONTAINER_PAIR(RUN,ARRAY): + return run_container_is_subset_array(const_CAST_run(c1), + const_CAST_array(c2)); + + case CONTAINER_PAIR(ARRAY,ARRAY): + return array_container_is_subset(const_CAST_array(c1), + const_CAST_array(c2)); + + case CONTAINER_PAIR(RUN,RUN): + return run_container_is_subset(const_CAST_run(c1), + const_CAST_run(c2)); + + default: + assert(false); + __builtin_unreachable(); + return false; + } +} + +// macro-izations possibilities for generic non-inplace binary-op dispatch + +/** + * Compute intersection between two containers, generate a new container (having + * type result_type), requires a typecode. This allocates new memory, caller + * is responsible for deallocation. + */ +static inline container_t *container_and( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = bitset_bitset_container_intersection( + const_CAST_bitset(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + result = array_container_create(); + array_container_intersection(const_CAST_array(c1), + const_CAST_array(c2), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + return result; + + case CONTAINER_PAIR(RUN,RUN): + result = run_container_create(); + run_container_intersection(const_CAST_run(c1), + const_CAST_run(c2), + CAST_run(result)); + return convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + + case CONTAINER_PAIR(BITSET,ARRAY): + result = array_container_create(); + array_bitset_container_intersection(const_CAST_array(c2), + const_CAST_bitset(c1), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_bitset_container_intersection(const_CAST_array(c1), + const_CAST_bitset(c2), + CAST_array(result)); + return result; + + case CONTAINER_PAIR(BITSET,RUN): + *result_type = run_bitset_container_intersection( + const_CAST_run(c2), + const_CAST_bitset(c1), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_intersection( + const_CAST_run(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_run_container_intersection(const_CAST_array(c1), + const_CAST_run(c2), + CAST_array(result)); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_run_container_intersection(const_CAST_array(c2), + const_CAST_run(c1), + CAST_array(result)); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Compute the size of the intersection between two containers. + */ +static inline int container_and_cardinality( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2 +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + return bitset_container_and_justcard( + const_CAST_bitset(c1), const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,ARRAY): + return array_container_intersection_cardinality( + const_CAST_array(c1), const_CAST_array(c2)); + + case CONTAINER_PAIR(RUN,RUN): + return run_container_intersection_cardinality( + const_CAST_run(c1), const_CAST_run(c2)); + + case CONTAINER_PAIR(BITSET,ARRAY): + return array_bitset_container_intersection_cardinality( + const_CAST_array(c2), const_CAST_bitset(c1)); + + case CONTAINER_PAIR(ARRAY,BITSET): + return array_bitset_container_intersection_cardinality( + const_CAST_array(c1), const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,RUN): + return run_bitset_container_intersection_cardinality( + const_CAST_run(c2), const_CAST_bitset(c1)); + + case CONTAINER_PAIR(RUN,BITSET): + return run_bitset_container_intersection_cardinality( + const_CAST_run(c1), const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,RUN): + return array_run_container_intersection_cardinality( + const_CAST_array(c1), const_CAST_run(c2)); + + case CONTAINER_PAIR(RUN,ARRAY): + return array_run_container_intersection_cardinality( + const_CAST_array(c2), const_CAST_run(c1)); + + default: + assert(false); + __builtin_unreachable(); + return 0; + } +} + +/** + * Check whether two containers intersect. + */ +static inline bool container_intersect( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2 +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + return bitset_container_intersect(const_CAST_bitset(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,ARRAY): + return array_container_intersect(const_CAST_array(c1), + const_CAST_array(c2)); + + case CONTAINER_PAIR(RUN,RUN): + return run_container_intersect(const_CAST_run(c1), + const_CAST_run(c2)); + + case CONTAINER_PAIR(BITSET,ARRAY): + return array_bitset_container_intersect(const_CAST_array(c2), + const_CAST_bitset(c1)); + + case CONTAINER_PAIR(ARRAY,BITSET): + return array_bitset_container_intersect(const_CAST_array(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(BITSET,RUN): + return run_bitset_container_intersect(const_CAST_run(c2), + const_CAST_bitset(c1)); + + case CONTAINER_PAIR(RUN,BITSET): + return run_bitset_container_intersect(const_CAST_run(c1), + const_CAST_bitset(c2)); + + case CONTAINER_PAIR(ARRAY,RUN): + return array_run_container_intersect(const_CAST_array(c1), + const_CAST_run(c2)); + + case CONTAINER_PAIR(RUN,ARRAY): + return array_run_container_intersect(const_CAST_array(c2), + const_CAST_run(c1)); + + default: + assert(false); + __builtin_unreachable(); + return 0; + } +} + +/** + * Compute intersection between two containers, with result in the first + container if possible. If the returned pointer is identical to c1, + then the container has been modified. If the returned pointer is different + from c1, then a new container has been created and the caller is responsible + for freeing it. + The type of the first container may change. Returns the modified + (and possibly new) container. +*/ +static inline container_t *container_iand( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = get_writable_copy_if_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = + bitset_bitset_container_intersection_inplace( + CAST_bitset(c1), const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + array_container_intersection_inplace(CAST_array(c1), + const_CAST_array(c2)); + *result_type = ARRAY_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(RUN,RUN): + result = run_container_create(); + run_container_intersection(const_CAST_run(c1), + const_CAST_run(c2), + CAST_run(result)); + // as of January 2016, Java code used non-in-place intersection for + // two runcontainers + return convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + + case CONTAINER_PAIR(BITSET,ARRAY): + // c1 is a bitmap so no inplace possible + result = array_container_create(); + array_bitset_container_intersection(const_CAST_array(c2), + const_CAST_bitset(c1), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_bitset_container_intersection( + const_CAST_array(c1), const_CAST_bitset(c2), + CAST_array(c1)); // result is allowed to be same as c1 + return c1; + + case CONTAINER_PAIR(BITSET,RUN): + // will attempt in-place computation + *result_type = run_bitset_container_intersection( + const_CAST_run(c2), + const_CAST_bitset(c1), &c1) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_intersection( + const_CAST_run(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_run_container_intersection(const_CAST_array(c1), + const_CAST_run(c2), + CAST_array(result)); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; // never bitset + array_run_container_intersection(const_CAST_array(c2), + const_CAST_run(c1), + CAST_array(result)); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Compute union between two containers, generate a new container (having type + * result_type), requires a typecode. This allocates new memory, caller + * is responsible for deallocation. + */ +static inline container_t *container_or( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + result = bitset_container_create(); + bitset_container_or(const_CAST_bitset(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_union( + const_CAST_array(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + result = run_container_create(); + run_container_union(const_CAST_run(c1), + const_CAST_run(c2), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // todo: could be optimized since will never convert to array + result = convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + result = bitset_container_create(); + array_bitset_container_union(const_CAST_array(c2), + const_CAST_bitset(c1), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + result = bitset_container_create(); + array_bitset_container_union(const_CAST_array(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(BITSET,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c2), + CAST_run(result)); + return result; + } + result = bitset_container_create(); + run_bitset_container_union(const_CAST_run(c2), + const_CAST_bitset(c1), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + if (run_container_is_full(const_CAST_run(c1))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c1), + CAST_run(result)); + return result; + } + result = bitset_container_create(); + run_bitset_container_union(const_CAST_run(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = run_container_create(); + array_run_container_union(const_CAST_array(c1), + const_CAST_run(c2), + CAST_run(result)); + result = convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + result = run_container_create(); + array_run_container_union(const_CAST_array(c2), + const_CAST_run(c1), + CAST_run(result)); + result = convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; // unreached + } +} + +/** + * Compute union between two containers, generate a new container (having type + * result_type), requires a typecode. This allocates new memory, caller + * is responsible for deallocation. + * + * This lazy version delays some operations such as the maintenance of the + * cardinality. It requires repair later on the generated containers. + */ +static inline container_t *container_lazy_or( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + result = bitset_container_create(); + bitset_container_or_nocard( + const_CAST_bitset(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_lazy_union( + const_CAST_array(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + result = run_container_create(); + run_container_union(const_CAST_run(c1), + const_CAST_run(c2), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // we are being lazy + result = convert_run_to_efficient_container( + CAST_run(result), result_type); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + result = bitset_container_create(); + array_bitset_container_lazy_union( + const_CAST_array(c2), const_CAST_bitset(c1), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + result = bitset_container_create(); + array_bitset_container_lazy_union( + const_CAST_array(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(BITSET,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c2), CAST_run(result)); + return result; + } + result = bitset_container_create(); + run_bitset_container_lazy_union( + const_CAST_run(c2), const_CAST_bitset(c1), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + if (run_container_is_full(const_CAST_run(c1))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c1), CAST_run(result)); + return result; + } + result = bitset_container_create(); + run_bitset_container_lazy_union( + const_CAST_run(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = run_container_create(); + array_run_container_union(const_CAST_array(c1), + const_CAST_run(c2), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container(result, result_type); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + result = run_container_create(); + array_run_container_union( + const_CAST_array(c2), const_CAST_run(c1), + CAST_run(result)); // TODO make lazy + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container(result, result_type); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; // unreached + } +} + +/** + * Compute the union between two containers, with result in the first container. + * If the returned pointer is identical to c1, then the container has been + * modified. + * If the returned pointer is different from c1, then a new container has been + * created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container +*/ +static inline container_t *container_ior( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = get_writable_copy_if_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + bitset_container_or(const_CAST_bitset(c1), + const_CAST_bitset(c2), + CAST_bitset(c1)); +#ifdef OR_BITSET_CONVERSION_TO_FULL + if (CAST_bitset(c1)->cardinality == (1 << 16)) { // we convert + result = run_container_create_range(0, (1 << 16)); + *result_type = RUN_CONTAINER_TYPE; + return result; + } +#endif + *result_type = BITSET_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_inplace_union( + CAST_array(c1), const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + if((result == NULL) + && (*result_type == ARRAY_CONTAINER_TYPE)) { + return c1; // the computation was done in-place! + } + return result; + + case CONTAINER_PAIR(RUN,RUN): + run_container_union_inplace(CAST_run(c1), const_CAST_run(c2)); + return convert_run_to_efficient_container(CAST_run(c1), + result_type); + + case CONTAINER_PAIR(BITSET,ARRAY): + array_bitset_container_union(const_CAST_array(c2), + const_CAST_bitset(c1), + CAST_bitset(c1)); + *result_type = BITSET_CONTAINER_TYPE; // never array + return c1; + + case CONTAINER_PAIR(ARRAY,BITSET): + // c1 is an array, so no in-place possible + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_bitset_container_union(const_CAST_array(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + return result; + + case CONTAINER_PAIR(BITSET,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c2), CAST_run(result)); + return result; + } + run_bitset_container_union(const_CAST_run(c2), + const_CAST_bitset(c1), + CAST_bitset(c1)); // allowed + *result_type = BITSET_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(RUN,BITSET): + if (run_container_is_full(const_CAST_run(c1))) { + *result_type = RUN_CONTAINER_TYPE; + return c1; + } + result = bitset_container_create(); + run_bitset_container_union(const_CAST_run(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = run_container_create(); + array_run_container_union(const_CAST_array(c1), + const_CAST_run(c2), + CAST_run(result)); + result = convert_run_to_efficient_container_and_free( + CAST_run(result), result_type); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + array_run_container_inplace_union(const_CAST_array(c2), + CAST_run(c1)); + c1 = convert_run_to_efficient_container(CAST_run(c1), + result_type); + return c1; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Compute the union between two containers, with result in the first container. + * If the returned pointer is identical to c1, then the container has been + * modified. + * If the returned pointer is different from c1, then a new container has been + * created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container + * + * This lazy version delays some operations such as the maintenance of the + * cardinality. It requires repair later on the generated containers. +*/ +static inline container_t *container_lazy_ior( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + assert(type1 != SHARED_CONTAINER_TYPE); + // c1 = get_writable_copy_if_shared(c1,&type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): +#ifdef LAZY_OR_BITSET_CONVERSION_TO_FULL + // if we have two bitsets, we might as well compute the cardinality + bitset_container_or(const_CAST_bitset(c1), + const_CAST_bitset(c2), + CAST_bitset(c1)); + // it is possible that two bitsets can lead to a full container + if (CAST_bitset(c1)->cardinality == (1 << 16)) { // we convert + result = run_container_create_range(0, (1 << 16)); + *result_type = RUN_CONTAINER_TYPE; + return result; + } +#else + bitset_container_or_nocard(const_CAST_bitset(c1), + const_CAST_bitset(c2), + CAST_bitset(c1)); + +#endif + *result_type = BITSET_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_lazy_inplace_union( + CAST_array(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + if((result == NULL) + && (*result_type == ARRAY_CONTAINER_TYPE)) { + return c1; // the computation was done in-place! + } + return result; + + case CONTAINER_PAIR(RUN,RUN): + run_container_union_inplace(CAST_run(c1), + const_CAST_run(c2)); + *result_type = RUN_CONTAINER_TYPE; + return convert_run_to_efficient_container(CAST_run(c1), + result_type); + + case CONTAINER_PAIR(BITSET,ARRAY): + array_bitset_container_lazy_union( + const_CAST_array(c2), const_CAST_bitset(c1), + CAST_bitset(c1)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; // never array + return c1; + + case CONTAINER_PAIR(ARRAY,BITSET): + // c1 is an array, so no in-place possible + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_bitset_container_lazy_union( + const_CAST_array(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // is lazy + return result; + + case CONTAINER_PAIR(BITSET,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = run_container_create(); + *result_type = RUN_CONTAINER_TYPE; + run_container_copy(const_CAST_run(c2), + CAST_run(result)); + return result; + } + run_bitset_container_lazy_union( + const_CAST_run(c2), const_CAST_bitset(c1), + CAST_bitset(c1)); // allowed // lazy + *result_type = BITSET_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(RUN,BITSET): + if (run_container_is_full(const_CAST_run(c1))) { + *result_type = RUN_CONTAINER_TYPE; + return c1; + } + result = bitset_container_create(); + run_bitset_container_lazy_union( + const_CAST_run(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = run_container_create(); + array_run_container_union(const_CAST_array(c1), + const_CAST_run(c2), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container_and_free(result, + // result_type); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + array_run_container_inplace_union(const_CAST_array(c2), + CAST_run(c1)); + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container_and_free(result, + // result_type); + return c1; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Compute symmetric difference (xor) between two containers, generate a new + * container (having type result_type), requires a typecode. This allocates new + * memory, caller is responsible for deallocation. + */ +static inline container_t* container_xor( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = bitset_bitset_container_xor( + const_CAST_bitset(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_xor( + const_CAST_array(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + *result_type = + run_run_container_xor(const_CAST_run(c1), + const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + *result_type = array_bitset_container_xor( + const_CAST_array(c2), + const_CAST_bitset(c1), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + *result_type = array_bitset_container_xor( + const_CAST_array(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(BITSET,RUN): + *result_type = run_bitset_container_xor( + const_CAST_run(c2), + const_CAST_bitset(c1), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_xor( + const_CAST_run(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + *result_type = + array_run_container_xor(const_CAST_array(c1), + const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + *result_type = + array_run_container_xor(const_CAST_array(c2), + const_CAST_run(c1), &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; // unreached + } +} + +/* Applies an offset to the non-empty container 'c'. + * The results are stored in new containers returned via 'lo' and 'hi', for the + * low and high halves of the result (where the low half matches the original key + * and the high one corresponds to values for the following key). + * Either one of 'lo' and 'hi' are allowed to be 'NULL', but not both. + * Whenever one of them is not 'NULL', it should point to a 'NULL' container. + * Whenever one of them is 'NULL' the shifted elements for that part will not be + * computed. + * If either of the resulting containers turns out to be empty, the pointed + * container will remain 'NULL'. + */ +static inline void container_add_offset(const container_t *c, uint8_t type, + container_t **lo, container_t **hi, + uint16_t offset) { + assert(offset != 0); + assert(container_nonzero_cardinality(c, type)); + assert(lo != NULL || hi != NULL); + assert(lo == NULL || *lo == NULL); + assert(hi == NULL || *hi == NULL); + + switch (type) { + case BITSET_CONTAINER_TYPE: + bitset_container_offset(const_CAST_bitset(c), lo, hi, offset); + break; + case ARRAY_CONTAINER_TYPE: + array_container_offset(const_CAST_array(c), lo, hi, offset); + break; + case RUN_CONTAINER_TYPE: + run_container_offset(const_CAST_run(c), lo, hi, offset); + break; + default: + assert(false); + __builtin_unreachable(); + break; + } +} + +/** + * Compute xor between two containers, generate a new container (having type + * result_type), requires a typecode. This allocates new memory, caller + * is responsible for deallocation. + * + * This lazy version delays some operations such as the maintenance of the + * cardinality. It requires repair later on the generated containers. + */ +static inline container_t *container_lazy_xor( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + result = bitset_container_create(); + bitset_container_xor_nocard( + const_CAST_bitset(c1), const_CAST_bitset(c2), + CAST_bitset(result)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_lazy_xor( + const_CAST_array(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + // nothing special done yet. + *result_type = + run_run_container_xor(const_CAST_run(c1), + const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_bitset_container_lazy_xor(const_CAST_array(c2), + const_CAST_bitset(c1), + CAST_bitset(result)); + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_bitset_container_lazy_xor(const_CAST_array(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + return result; + + case CONTAINER_PAIR(BITSET,RUN): + result = bitset_container_create(); + run_bitset_container_lazy_xor(const_CAST_run(c2), + const_CAST_bitset(c1), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + result = bitset_container_create(); + run_bitset_container_lazy_xor(const_CAST_run(c1), + const_CAST_bitset(c2), + CAST_bitset(result)); + *result_type = BITSET_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + result = run_container_create(); + array_run_container_lazy_xor(const_CAST_array(c1), + const_CAST_run(c2), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container(result, result_type); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + result = run_container_create(); + array_run_container_lazy_xor(const_CAST_array(c2), + const_CAST_run(c1), + CAST_run(result)); + *result_type = RUN_CONTAINER_TYPE; + // next line skipped since we are lazy + // result = convert_run_to_efficient_container(result, result_type); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; // unreached + } +} + +/** + * Compute the xor between two containers, with result in the first container. + * If the returned pointer is identical to c1, then the container has been + * modified. + * If the returned pointer is different from c1, then a new container has been + * created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container +*/ +static inline container_t *container_ixor( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = get_writable_copy_if_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = bitset_bitset_container_ixor( + CAST_bitset(c1), const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + *result_type = array_array_container_ixor( + CAST_array(c1), const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + *result_type = run_run_container_ixor( + CAST_run(c1), const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + *result_type = bitset_array_container_ixor( + CAST_bitset(c1), const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + *result_type = array_bitset_container_ixor( + CAST_array(c1), const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(BITSET,RUN): + *result_type = + bitset_run_container_ixor( + CAST_bitset(c1), const_CAST_run(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + + return result; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_ixor( + CAST_run(c1), const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + *result_type = array_run_container_ixor( + CAST_array(c1), const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + *result_type = run_array_container_ixor( + CAST_run(c1), const_CAST_array(c2), &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Compute the xor between two containers, with result in the first container. + * If the returned pointer is identical to c1, then the container has been + * modified. + * If the returned pointer is different from c1, then a new container has been + * created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container + * + * This lazy version delays some operations such as the maintenance of the + * cardinality. It requires repair later on the generated containers. +*/ +static inline container_t *container_lazy_ixor( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + assert(type1 != SHARED_CONTAINER_TYPE); + // c1 = get_writable_copy_if_shared(c1,&type1); + c2 = container_unwrap_shared(c2, &type2); + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + bitset_container_xor_nocard(CAST_bitset(c1), + const_CAST_bitset(c2), + CAST_bitset(c1)); // is lazy + *result_type = BITSET_CONTAINER_TYPE; + return c1; + + // TODO: other cases being lazy, esp. when we know inplace not likely + // could see the corresponding code for union + default: + // we may have a dirty bitset (without a precomputed cardinality) + // and calling container_ixor on it might be unsafe. + if (type1 == BITSET_CONTAINER_TYPE) { + bitset_container_t *bc = CAST_bitset(c1); + if (bc->cardinality == BITSET_UNKNOWN_CARDINALITY) { + bc->cardinality = bitset_container_compute_cardinality(bc); + } + } + return container_ixor(c1, type1, c2, type2, result_type); + } +} + +/** + * Compute difference (andnot) between two containers, generate a new + * container (having type result_type), requires a typecode. This allocates new + * memory, caller is responsible for deallocation. + */ +static inline container_t *container_andnot( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = container_unwrap_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = bitset_bitset_container_andnot( + const_CAST_bitset(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + result = array_container_create(); + array_array_container_andnot(const_CAST_array(c1), + const_CAST_array(c2), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + } + *result_type = + run_run_container_andnot(const_CAST_run(c1), + const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + *result_type = bitset_array_container_andnot( + const_CAST_bitset(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + result = array_container_create(); + array_bitset_container_andnot(const_CAST_array(c1), + const_CAST_bitset(c2), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(BITSET,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + } + *result_type = bitset_run_container_andnot( + const_CAST_bitset(c1), + const_CAST_run(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_andnot( + const_CAST_run(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + if (run_container_is_full(const_CAST_run(c2))) { + result = array_container_create(); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + } + result = array_container_create(); + array_run_container_andnot(const_CAST_array(c1), + const_CAST_run(c2), + CAST_array(result)); + *result_type = ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,ARRAY): + *result_type = run_array_container_andnot( + const_CAST_run(c1), const_CAST_array(c2), + &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; // unreached + } +} + +/** + * Compute the andnot between two containers, with result in the first + * container. + * If the returned pointer is identical to c1, then the container has been + * modified. + * If the returned pointer is different from c1, then a new container has been + * created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container +*/ +static inline container_t *container_iandnot( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type +){ + c1 = get_writable_copy_if_shared(c1, &type1); + c2 = container_unwrap_shared(c2, &type2); + container_t *result = NULL; + switch (PAIR_CONTAINER_TYPES(type1, type2)) { + case CONTAINER_PAIR(BITSET,BITSET): + *result_type = bitset_bitset_container_iandnot( + CAST_bitset(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,ARRAY): + array_array_container_iandnot(CAST_array(c1), + const_CAST_array(c2)); + *result_type = ARRAY_CONTAINER_TYPE; + return c1; + + case CONTAINER_PAIR(RUN,RUN): + *result_type = run_run_container_iandnot( + CAST_run(c1), const_CAST_run(c2), &result); + return result; + + case CONTAINER_PAIR(BITSET,ARRAY): + *result_type = bitset_array_container_iandnot( + CAST_bitset(c1), + const_CAST_array(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,BITSET): + *result_type = ARRAY_CONTAINER_TYPE; + array_bitset_container_iandnot(CAST_array(c1), + const_CAST_bitset(c2)); + return c1; + + case CONTAINER_PAIR(BITSET,RUN): + *result_type = bitset_run_container_iandnot( + CAST_bitset(c1), + const_CAST_run(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(RUN,BITSET): + *result_type = run_bitset_container_iandnot( + CAST_run(c1), + const_CAST_bitset(c2), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + + case CONTAINER_PAIR(ARRAY,RUN): + *result_type = ARRAY_CONTAINER_TYPE; + array_run_container_iandnot(CAST_array(c1), + const_CAST_run(c2)); + return c1; + + case CONTAINER_PAIR(RUN,ARRAY): + *result_type = run_array_container_iandnot( + CAST_run(c1), const_CAST_array(c2), &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +/** + * Visit all values x of the container once, passing (base+x,ptr) + * to iterator. You need to specify a container and its type. + * Returns true if the iteration should continue. + */ +static inline bool container_iterate( + const container_t *c, uint8_t type, + uint32_t base, + roaring_iterator iterator, void *ptr +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_iterate(const_CAST_bitset(c), + base, iterator, ptr); + case ARRAY_CONTAINER_TYPE: + return array_container_iterate(const_CAST_array(c), + base, iterator, ptr); + case RUN_CONTAINER_TYPE: + return run_container_iterate(const_CAST_run(c), + base, iterator, ptr); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +static inline bool container_iterate64( + const container_t *c, uint8_t type, + uint32_t base, + roaring_iterator64 iterator, + uint64_t high_bits, void *ptr +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_iterate64(const_CAST_bitset(c), base, + iterator, high_bits, ptr); + case ARRAY_CONTAINER_TYPE: + return array_container_iterate64(const_CAST_array(c), base, + iterator, high_bits, ptr); + case RUN_CONTAINER_TYPE: + return run_container_iterate64(const_CAST_run(c), base, + iterator, high_bits, ptr); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +static inline container_t *container_not( + const container_t *c, uint8_t type, + uint8_t *result_type +){ + c = container_unwrap_shared(c, &type); + container_t *result = NULL; + switch (type) { + case BITSET_CONTAINER_TYPE: + *result_type = bitset_container_negation( + const_CAST_bitset(c), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case ARRAY_CONTAINER_TYPE: + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_container_negation(const_CAST_array(c), + CAST_bitset(result)); + return result; + case RUN_CONTAINER_TYPE: + *result_type = + run_container_negation(const_CAST_run(c), &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return NULL; +} + +static inline container_t *container_not_range( + const container_t *c, uint8_t type, + uint32_t range_start, uint32_t range_end, + uint8_t *result_type +){ + c = container_unwrap_shared(c, &type); + container_t *result = NULL; + switch (type) { + case BITSET_CONTAINER_TYPE: + *result_type = + bitset_container_negation_range( + const_CAST_bitset(c), range_start, range_end, &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case ARRAY_CONTAINER_TYPE: + *result_type = + array_container_negation_range( + const_CAST_array(c), range_start, range_end, &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case RUN_CONTAINER_TYPE: + *result_type = run_container_negation_range( + const_CAST_run(c), range_start, range_end, &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return NULL; +} + +static inline container_t *container_inot( + container_t *c, uint8_t type, + uint8_t *result_type +){ + c = get_writable_copy_if_shared(c, &type); + container_t *result = NULL; + switch (type) { + case BITSET_CONTAINER_TYPE: + *result_type = bitset_container_negation_inplace( + CAST_bitset(c), &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case ARRAY_CONTAINER_TYPE: + // will never be inplace + result = bitset_container_create(); + *result_type = BITSET_CONTAINER_TYPE; + array_container_negation(CAST_array(c), + CAST_bitset(result)); + array_container_free(CAST_array(c)); + return result; + case RUN_CONTAINER_TYPE: + *result_type = + run_container_negation_inplace(CAST_run(c), &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return NULL; +} + +static inline container_t *container_inot_range( + container_t *c, uint8_t type, + uint32_t range_start, uint32_t range_end, + uint8_t *result_type +){ + c = get_writable_copy_if_shared(c, &type); + container_t *result = NULL; + switch (type) { + case BITSET_CONTAINER_TYPE: + *result_type = + bitset_container_negation_range_inplace( + CAST_bitset(c), range_start, range_end, &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case ARRAY_CONTAINER_TYPE: + *result_type = + array_container_negation_range_inplace( + CAST_array(c), range_start, range_end, &result) + ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + return result; + case RUN_CONTAINER_TYPE: + *result_type = run_container_negation_range_inplace( + CAST_run(c), range_start, range_end, &result); + return result; + + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return NULL; +} + +/** + * If the element of given rank is in this container, supposing that + * the first + * element has rank start_rank, then the function returns true and + * sets element + * accordingly. + * Otherwise, it returns false and update start_rank. + */ +static inline bool container_select( + const container_t *c, uint8_t type, + uint32_t *start_rank, uint32_t rank, + uint32_t *element +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_select(const_CAST_bitset(c), + start_rank, rank, element); + case ARRAY_CONTAINER_TYPE: + return array_container_select(const_CAST_array(c), + start_rank, rank, element); + case RUN_CONTAINER_TYPE: + return run_container_select(const_CAST_run(c), + start_rank, rank, element); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +static inline uint16_t container_maximum( + const container_t *c, uint8_t type +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_maximum(const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_maximum(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_maximum(const_CAST_run(c)); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +static inline uint16_t container_minimum( + const container_t *c, uint8_t type +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_minimum(const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_minimum(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_minimum(const_CAST_run(c)); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +// number of values smaller or equal to x +static inline int container_rank( + const container_t *c, uint8_t type, + uint16_t x +){ + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + return bitset_container_rank(const_CAST_bitset(c), x); + case ARRAY_CONTAINER_TYPE: + return array_container_rank(const_CAST_array(c), x); + case RUN_CONTAINER_TYPE: + return run_container_rank(const_CAST_run(c), x); + default: + assert(false); + __builtin_unreachable(); + } + assert(false); + __builtin_unreachable(); + return false; +} + +/** + * Add all values in range [min, max] to a given container. + * + * If the returned pointer is different from $container, then a new container + * has been created and the caller is responsible for freeing it. + * The type of the first container may change. Returns the modified + * (and possibly new) container. + */ +static inline container_t *container_add_range( + container_t *c, uint8_t type, + uint32_t min, uint32_t max, + uint8_t *result_type +){ + // NB: when selecting new container type, we perform only inexpensive checks + switch (type) { + case BITSET_CONTAINER_TYPE: { + bitset_container_t *bitset = CAST_bitset(c); + + int32_t union_cardinality = 0; + union_cardinality += bitset->cardinality; + union_cardinality += max - min + 1; + union_cardinality -= bitset_lenrange_cardinality(bitset->words, + min, max-min); + + if (union_cardinality == INT32_C(0x10000)) { + *result_type = RUN_CONTAINER_TYPE; + return run_container_create_range(0, INT32_C(0x10000)); + } else { + *result_type = BITSET_CONTAINER_TYPE; + bitset_set_lenrange(bitset->words, min, max - min); + bitset->cardinality = union_cardinality; + return bitset; + } + } + case ARRAY_CONTAINER_TYPE: { + array_container_t *array = CAST_array(c); + + int32_t nvals_greater = count_greater(array->array, array->cardinality, max); + int32_t nvals_less = count_less(array->array, array->cardinality - nvals_greater, min); + int32_t union_cardinality = nvals_less + (max - min + 1) + nvals_greater; + + if (union_cardinality == INT32_C(0x10000)) { + *result_type = RUN_CONTAINER_TYPE; + return run_container_create_range(0, INT32_C(0x10000)); + } else if (union_cardinality <= DEFAULT_MAX_SIZE) { + *result_type = ARRAY_CONTAINER_TYPE; + array_container_add_range_nvals(array, min, max, nvals_less, nvals_greater); + return array; + } else { + *result_type = BITSET_CONTAINER_TYPE; + bitset_container_t *bitset = bitset_container_from_array(array); + bitset_set_lenrange(bitset->words, min, max - min); + bitset->cardinality = union_cardinality; + return bitset; + } + } + case RUN_CONTAINER_TYPE: { + run_container_t *run = CAST_run(c); + + int32_t nruns_greater = rle16_count_greater(run->runs, run->n_runs, max); + int32_t nruns_less = rle16_count_less(run->runs, run->n_runs - nruns_greater, min); + + int32_t run_size_bytes = (nruns_less + 1 + nruns_greater) * sizeof(rle16_t); + int32_t bitset_size_bytes = BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + + if (run_size_bytes <= bitset_size_bytes) { + run_container_add_range_nruns(run, min, max, nruns_less, nruns_greater); + *result_type = RUN_CONTAINER_TYPE; + return run; + } else { + return container_from_run_range(run, min, max, result_type); + } + } + default: + __builtin_unreachable(); + } +} + +/* + * Removes all elements in range [min, max]. + * Returns one of: + * - NULL if no elements left + * - pointer to the original container + * - pointer to a newly-allocated container (if it is more efficient) + * + * If the returned pointer is different from $container, then a new container + * has been created and the caller is responsible for freeing the original container. + */ +static inline container_t *container_remove_range( + container_t *c, uint8_t type, + uint32_t min, uint32_t max, + uint8_t *result_type +){ + switch (type) { + case BITSET_CONTAINER_TYPE: { + bitset_container_t *bitset = CAST_bitset(c); + + int32_t result_cardinality = bitset->cardinality - + bitset_lenrange_cardinality(bitset->words, min, max-min); + + if (result_cardinality == 0) { + return NULL; + } else if (result_cardinality < DEFAULT_MAX_SIZE) { + *result_type = ARRAY_CONTAINER_TYPE; + bitset_reset_range(bitset->words, min, max+1); + bitset->cardinality = result_cardinality; + return array_container_from_bitset(bitset); + } else { + *result_type = BITSET_CONTAINER_TYPE; + bitset_reset_range(bitset->words, min, max+1); + bitset->cardinality = result_cardinality; + return bitset; + } + } + case ARRAY_CONTAINER_TYPE: { + array_container_t *array = CAST_array(c); + + int32_t nvals_greater = count_greater(array->array, array->cardinality, max); + int32_t nvals_less = count_less(array->array, array->cardinality - nvals_greater, min); + int32_t result_cardinality = nvals_less + nvals_greater; + + if (result_cardinality == 0) { + return NULL; + } else { + *result_type = ARRAY_CONTAINER_TYPE; + array_container_remove_range(array, nvals_less, + array->cardinality - result_cardinality); + return array; + } + } + case RUN_CONTAINER_TYPE: { + run_container_t *run = CAST_run(c); + + if (run->n_runs == 0) { + return NULL; + } + if (min <= run_container_minimum(run) && max >= run_container_maximum(run)) { + return NULL; + } + + run_container_remove_range(run, min, max); + + if (run_container_serialized_size_in_bytes(run->n_runs) <= + bitset_container_serialized_size_in_bytes()) { + *result_type = RUN_CONTAINER_TYPE; + return run; + } else { + *result_type = BITSET_CONTAINER_TYPE; + return bitset_container_from_run(run); + } + } + default: + __builtin_unreachable(); + } +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif + +#endif +/* end file include/roaring/containers/containers.h */ +/* begin file include/roaring/roaring_array.h */ +#ifndef INCLUDE_ROARING_ARRAY_H +#define INCLUDE_ROARING_ARRAY_H + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { + +// Note: in pure C++ code, you should avoid putting `using` in header files +using api::roaring_array_t; + +namespace internal { +#endif + +enum { + SERIAL_COOKIE_NO_RUNCONTAINER = 12346, + SERIAL_COOKIE = 12347, + FROZEN_COOKIE = 13766, + NO_OFFSET_THRESHOLD = 4 +}; + +/** + * Create a new roaring array + */ +roaring_array_t *ra_create(void); + +/** + * Initialize an existing roaring array with the specified capacity (in number + * of containers) + */ +bool ra_init_with_capacity(roaring_array_t *new_ra, uint32_t cap); + +/** + * Initialize with zero capacity + */ +void ra_init(roaring_array_t *t); + +/** + * Copies this roaring array, we assume that dest is not initialized + */ +bool ra_copy(const roaring_array_t *source, roaring_array_t *dest, + bool copy_on_write); + +/* + * Shrinks the capacity, returns the number of bytes saved. + */ +int ra_shrink_to_fit(roaring_array_t *ra); + +/** + * Copies this roaring array, we assume that dest is initialized + */ +bool ra_overwrite(const roaring_array_t *source, roaring_array_t *dest, + bool copy_on_write); + +/** + * Frees the memory used by a roaring array + */ +void ra_clear(roaring_array_t *r); + +/** + * Frees the memory used by a roaring array, but does not free the containers + */ +void ra_clear_without_containers(roaring_array_t *r); + +/** + * Frees just the containers + */ +void ra_clear_containers(roaring_array_t *ra); + +/** + * Get the index corresponding to a 16-bit key + */ +inline int32_t ra_get_index(const roaring_array_t *ra, uint16_t x) { + if ((ra->size == 0) || ra->keys[ra->size - 1] == x) return ra->size - 1; + return binarySearch(ra->keys, (int32_t)ra->size, x); +} + +/** + * Retrieves the container at index i, filling in the typecode + */ +inline container_t *ra_get_container_at_index( + const roaring_array_t *ra, uint16_t i, uint8_t *typecode +){ + *typecode = ra->typecodes[i]; + return ra->containers[i]; +} + +/** + * Retrieves the key at index i + */ +uint16_t ra_get_key_at_index(const roaring_array_t *ra, uint16_t i); + +/** + * Add a new key-value pair at index i + */ +void ra_insert_new_key_value_at( + roaring_array_t *ra, int32_t i, uint16_t key, + container_t *c, uint8_t typecode); + +/** + * Append a new key-value pair + */ +void ra_append( + roaring_array_t *ra, uint16_t key, + container_t *c, uint8_t typecode); + +/** + * Append a new key-value pair to ra, cloning (in COW sense) a value from sa + * at index index + */ +void ra_append_copy(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t index, bool copy_on_write); + +/** + * Append new key-value pairs to ra, cloning (in COW sense) values from sa + * at indexes + * [start_index, end_index) + */ +void ra_append_copy_range(roaring_array_t *ra, const roaring_array_t *sa, + int32_t start_index, int32_t end_index, + bool copy_on_write); + +/** appends from sa to ra, ending with the greatest key that is + * is less or equal stopping_key + */ +void ra_append_copies_until(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t stopping_key, bool copy_on_write); + +/** appends from sa to ra, starting with the smallest key that is + * is strictly greater than before_start + */ + +void ra_append_copies_after(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t before_start, bool copy_on_write); + +/** + * Move the key-value pairs to ra from sa at indexes + * [start_index, end_index), old array should not be freed + * (use ra_clear_without_containers) + **/ +void ra_append_move_range(roaring_array_t *ra, roaring_array_t *sa, + int32_t start_index, int32_t end_index); +/** + * Append new key-value pairs to ra, from sa at indexes + * [start_index, end_index) + */ +void ra_append_range(roaring_array_t *ra, roaring_array_t *sa, + int32_t start_index, int32_t end_index, + bool copy_on_write); + +/** + * Set the container at the corresponding index using the specified + * typecode. + */ +inline void ra_set_container_at_index( + const roaring_array_t *ra, int32_t i, + container_t *c, uint8_t typecode +){ + assert(i < ra->size); + ra->containers[i] = c; + ra->typecodes[i] = typecode; +} + +/** + * If needed, increase the capacity of the array so that it can fit k values + * (at + * least); + */ +bool extend_array(roaring_array_t *ra, int32_t k); + +inline int32_t ra_get_size(const roaring_array_t *ra) { return ra->size; } + +static inline int32_t ra_advance_until(const roaring_array_t *ra, uint16_t x, + int32_t pos) { + return advanceUntil(ra->keys, pos, ra->size, x); +} + +int32_t ra_advance_until_freeing(roaring_array_t *ra, uint16_t x, int32_t pos); + +void ra_downsize(roaring_array_t *ra, int32_t new_length); + +inline void ra_replace_key_and_container_at_index( + roaring_array_t *ra, int32_t i, uint16_t key, + container_t *c, uint8_t typecode +){ + assert(i < ra->size); + + ra->keys[i] = key; + ra->containers[i] = c; + ra->typecodes[i] = typecode; +} + +// write set bits to an array +void ra_to_uint32_array(const roaring_array_t *ra, uint32_t *ans); + +bool ra_range_uint32_array(const roaring_array_t *ra, size_t offset, size_t limit, uint32_t *ans); + +/** + * write a bitmap to a buffer. This is meant to be compatible with + * the + * Java and Go versions. Return the size in bytes of the serialized + * output (which should be ra_portable_size_in_bytes(ra)). + */ +size_t ra_portable_serialize(const roaring_array_t *ra, char *buf); + +/** + * read a bitmap from a serialized version. This is meant to be compatible + * with the Java and Go versions. + * maxbytes indicates how many bytes available from buf. + * When the function returns true, roaring_array_t is populated with the data + * and *readbytes indicates how many bytes were read. In all cases, if the function + * returns true, then maxbytes >= *readbytes. + */ +bool ra_portable_deserialize(roaring_array_t *ra, const char *buf, const size_t maxbytes, size_t * readbytes); + +/** + * Quickly checks whether there is a serialized bitmap at the pointer, + * not exceeding size "maxbytes" in bytes. This function does not allocate + * memory dynamically. + * + * This function returns 0 if and only if no valid bitmap is found. + * Otherwise, it returns how many bytes are occupied by the bitmap data. + */ +size_t ra_portable_deserialize_size(const char *buf, const size_t maxbytes); + +/** + * How many bytes are required to serialize this bitmap (meant to be + * compatible + * with Java and Go versions) + */ +size_t ra_portable_size_in_bytes(const roaring_array_t *ra); + +/** + * return true if it contains at least one run container. + */ +bool ra_has_run_container(const roaring_array_t *ra); + +/** + * Size of the header when serializing (meant to be compatible + * with Java and Go versions) + */ +uint32_t ra_portable_header_size(const roaring_array_t *ra); + +/** + * If the container at the index i is share, unshare it (creating a local + * copy if needed). + */ +static inline void ra_unshare_container_at_index(roaring_array_t *ra, + uint16_t i) { + assert(i < ra->size); + ra->containers[i] = get_writable_copy_if_shared(ra->containers[i], + &ra->typecodes[i]); +} + +/** + * remove at index i, sliding over all entries after i + */ +void ra_remove_at_index(roaring_array_t *ra, int32_t i); + + +/** +* clears all containers, sets the size at 0 and shrinks the memory usage. +*/ +void ra_reset(roaring_array_t *ra); + +/** + * remove at index i, sliding over all entries after i. Free removed container. + */ +void ra_remove_at_index_and_free(roaring_array_t *ra, int32_t i); + +/** + * remove a chunk of indices, sliding over entries after it + */ +// void ra_remove_index_range(roaring_array_t *ra, int32_t begin, int32_t end); + +// used in inplace andNot only, to slide left the containers from +// the mutated RoaringBitmap that are after the largest container of +// the argument RoaringBitmap. It is followed by a call to resize. +// +void ra_copy_range(roaring_array_t *ra, uint32_t begin, uint32_t end, + uint32_t new_begin); + +/** + * Shifts rightmost $count containers to the left (distance < 0) or + * to the right (distance > 0). + * Allocates memory if necessary. + * This function doesn't free or create new containers. + * Caller is responsible for that. + */ +void ra_shift_tail(roaring_array_t *ra, int32_t count, int32_t distance); + +#ifdef __cplusplus +} // namespace internal +} } // extern "C" { namespace roaring { +#endif + +#endif +/* end file include/roaring/roaring_array.h */ +/* begin file include/roaring/misc/configreport.h */ +/* + * configreport.h + * + */ + +#ifndef INCLUDE_MISC_CONFIGREPORT_H_ +#define INCLUDE_MISC_CONFIGREPORT_H_ + +#include // for size_t +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace misc { +#endif + +#ifdef CROARING_IS_X64 +// useful for basic info (0) +static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, + unsigned int *ecx, unsigned int *edx) { +#ifdef ROARING_INLINE_ASM + __asm volatile("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "0"(*eax), "2"(*ecx)); +#endif /* not sure what to do when inline assembly is unavailable*/ +} + +// CPUID instruction takes no parameters as CPUID implicitly uses the EAX +// register. +// The EAX register should be loaded with a value specifying what information to +// return +static inline void cpuinfo(int code, int *eax, int *ebx, int *ecx, int *edx) { +#ifdef ROARING_INLINE_ASM + __asm__ volatile("cpuid;" // call cpuid instruction + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), + "=d"(*edx) // output equal to "movl %%eax %1" + : "a"(code) // input equal to "movl %1, %%eax" + //:"%eax","%ebx","%ecx","%edx"// clobbered register + ); +#endif /* not sure what to do when inline assembly is unavailable*/ +} + +static inline int computecacheline() { + int eax = 0, ebx = 0, ecx = 0, edx = 0; + cpuinfo((int)0x80000006, &eax, &ebx, &ecx, &edx); + return ecx & 0xFF; +} + +// this is quite imperfect, but can be handy +static inline const char *guessprocessor() { + unsigned eax = 1, ebx = 0, ecx = 0, edx = 0; + native_cpuid(&eax, &ebx, &ecx, &edx); + const char *codename; + switch (eax >> 4) { + case 0x506E: + codename = "Skylake"; + break; + case 0x406C: + codename = "CherryTrail"; + break; + case 0x306D: + codename = "Broadwell"; + break; + case 0x306C: + codename = "Haswell"; + break; + case 0x306A: + codename = "IvyBridge"; + break; + case 0x206A: + case 0x206D: + codename = "SandyBridge"; + break; + case 0x2065: + case 0x206C: + case 0x206F: + codename = "Westmere"; + break; + case 0x106E: + case 0x106A: + case 0x206E: + codename = "Nehalem"; + break; + case 0x1067: + case 0x106D: + codename = "Penryn"; + break; + case 0x006F: + case 0x1066: + codename = "Merom"; + break; + case 0x0066: + codename = "Presler"; + break; + case 0x0063: + case 0x0064: + codename = "Prescott"; + break; + case 0x006D: + codename = "Dothan"; + break; + case 0x0366: + codename = "Cedarview"; + break; + case 0x0266: + codename = "Lincroft"; + break; + case 0x016C: + codename = "Pineview"; + break; + default: + codename = "UNKNOWN"; + break; + } + return codename; +} + +static inline void tellmeall() { + printf("x64 processor: %s\t", guessprocessor()); + +#ifdef __VERSION__ + printf(" compiler version: %s\t", __VERSION__); +#endif + uint32_t config = croaring_detect_supported_architectures(); + if((config & CROARING_NEON) == CROARING_NEON) { + printf(" NEON detected\t"); + } + #ifdef __AVX2__ + printf(" Building for AVX2\t"); + #endif + if(croaring_avx2()) { + printf( "AVX2 usable\t"); + } + if((config & CROARING_AVX2) == CROARING_AVX2) { + printf( "AVX2 detected\t"); + if(!croaring_avx2()) { + printf( "AVX2 not used\t"); + } + } + if((config & CROARING_SSE42) == CROARING_SSE42) { + printf(" SSE4.2 detected\t"); + } + if((config & CROARING_BMI1) == CROARING_BMI1) { + printf(" BMI1 detected\t"); + } + if((config & CROARING_BMI2) == CROARING_BMI2) { + printf(" BMI2 detected\t"); + } + printf("\n"); + if ((sizeof(int) != 4) || (sizeof(long) != 8)) { + printf("number of bytes: int = %lu long = %lu \n", + (long unsigned int)sizeof(size_t), + (long unsigned int)sizeof(int)); + } +#if __LITTLE_ENDIAN__ +// This is what we expect! +// printf("you have little endian machine"); +#endif +#if __BIG_ENDIAN__ + printf("you have a big endian machine"); +#endif +#if __CHAR_BIT__ + if (__CHAR_BIT__ != 8) printf("on your machine, chars don't have 8bits???"); +#endif + if (computecacheline() != 64) + printf("cache line: %d bytes\n", computecacheline()); +} +#else + +static inline void tellmeall() { + printf("Non-X64 processor\n"); +#ifdef __arm__ + printf("ARM processor detected\n"); +#endif +#ifdef __VERSION__ + printf(" compiler version: %s\t", __VERSION__); +#endif + uint32_t config = croaring_detect_supported_architectures(); + if((config & CROARING_NEON) == CROARING_NEON) { + printf(" NEON detected\t"); + } + if((config & CROARING_ALTIVEC) == CROARING_ALTIVEC) { + printf("Altivec detected\n"); + } + + if ((sizeof(int) != 4) || (sizeof(long) != 8)) { + printf("number of bytes: int = %lu long = %lu \n", + (long unsigned int)sizeof(size_t), + (long unsigned int)sizeof(int)); + } +#if __LITTLE_ENDIAN__ +// This is what we expect! +// printf("you have little endian machine"); +#endif +#if __BIG_ENDIAN__ + printf("you have a big endian machine"); +#endif +#if __CHAR_BIT__ + if (__CHAR_BIT__ != 8) printf("on your machine, chars don't have 8bits???"); +#endif +} + +#endif + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace misc { +#endif + +#endif /* INCLUDE_MISC_CONFIGREPORT_H_ */ +/* end file include/roaring/misc/configreport.h */ +/* begin file src/array_util.c */ +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +extern inline int32_t binarySearch(const uint16_t *array, int32_t lenarray, + uint16_t ikey); + +#ifdef CROARING_IS_X64 +// used by intersect_vector16 +ALIGNED(0x1000) +static const uint8_t shuffle_mask16[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 8, 9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 8, 9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, 8, 9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, + 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 6, 7, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 6, 7, 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 10, 11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 10, 11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 6, 7, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 6, 7, 10, 11, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 6, 7, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 6, 7, 10, 11, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 6, 7, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, 10, 11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 8, 9, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, 10, 11, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 8, 9, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 8, 9, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 8, 9, 10, 11, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 6, 7, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 8, 9, + 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 0xFF, 0xFF, 0xFF, 0xFF, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 6, 7, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 6, 7, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 8, 9, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 8, 9, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 8, 9, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 8, 9, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, + 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 6, 7, 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 6, 7, 8, 9, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, + 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 6, 7, 8, 9, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 10, 11, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 10, 11, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 10, 11, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 6, 7, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, + 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 8, 9, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, + 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 8, 9, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, 8, 9, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, + 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 0xFF, 0xFF, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 6, 7, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 6, 7, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 6, 7, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 6, 7, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 6, 7, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 8, 9, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 8, 9, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 8, 9, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 8, 9, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 6, 7, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 8, 9, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 8, 9, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 10, 11, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 10, 11, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, + 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 6, 7, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, + 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 8, 9, 10, 11, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 8, 9, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 8, 9, 10, 11, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 8, 9, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, + 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 6, 7, 8, 9, + 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, + 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xFF, 0xFF, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 12, 13, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 12, 13, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 6, 7, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 8, 9, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 8, 9, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 6, 7, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, 8, 9, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, + 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, 8, 9, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 6, 7, 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 12, 13, 14, 15, 0xFF, 0xFF, 10, 11, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 4, 5, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 10, 11, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 6, 7, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 6, 7, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 6, 7, 10, 11, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 6, 7, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 4, 5, 6, 7, 10, 11, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, + 8, 9, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 8, 9, 10, 11, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 8, 9, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 4, 5, 8, 9, 10, 11, 12, 13, + 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, + 8, 9, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, + 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, 4, 5, 8, 9, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 2, 3, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 2, 3, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0xFF, 0xFF, 0xFF, 0xFF, 0, 1, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15}; + +/** + * From Schlegel et al., Fast Sorted-Set Intersection using SIMD Instructions + * Optimized by D. Lemire on May 3rd 2013 + */ +CROARING_TARGET_AVX2 +int32_t intersect_vector16(const uint16_t *__restrict__ A, size_t s_a, + const uint16_t *__restrict__ B, size_t s_b, + uint16_t *C) { + size_t count = 0; + size_t i_a = 0, i_b = 0; + const int vectorlength = sizeof(__m128i) / sizeof(uint16_t); + const size_t st_a = (s_a / vectorlength) * vectorlength; + const size_t st_b = (s_b / vectorlength) * vectorlength; + __m128i v_a, v_b; + if ((i_a < st_a) && (i_b < st_b)) { + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + while ((A[i_a] == 0) || (B[i_b] == 0)) { + const __m128i res_v = _mm_cmpestrm( + v_b, vectorlength, v_a, vectorlength, + _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK); + const int r = _mm_extract_epi32(res_v, 0); + __m128i sm16 = _mm_load_si128((const __m128i *)shuffle_mask16 + r); + __m128i p = _mm_shuffle_epi8(v_a, sm16); + _mm_storeu_si128((__m128i *)&C[count], p); // can overflow + count += _mm_popcnt_u32(r); + const uint16_t a_max = A[i_a + vectorlength - 1]; + const uint16_t b_max = B[i_b + vectorlength - 1]; + if (a_max <= b_max) { + i_a += vectorlength; + if (i_a == st_a) break; + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + } + if (b_max <= a_max) { + i_b += vectorlength; + if (i_b == st_b) break; + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + } + } + if ((i_a < st_a) && (i_b < st_b)) + while (true) { + const __m128i res_v = _mm_cmpistrm( + v_b, v_a, + _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK); + const int r = _mm_extract_epi32(res_v, 0); + __m128i sm16 = + _mm_load_si128((const __m128i *)shuffle_mask16 + r); + __m128i p = _mm_shuffle_epi8(v_a, sm16); + _mm_storeu_si128((__m128i *)&C[count], p); // can overflow + count += _mm_popcnt_u32(r); + const uint16_t a_max = A[i_a + vectorlength - 1]; + const uint16_t b_max = B[i_b + vectorlength - 1]; + if (a_max <= b_max) { + i_a += vectorlength; + if (i_a == st_a) break; + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + } + if (b_max <= a_max) { + i_b += vectorlength; + if (i_b == st_b) break; + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + } + } + } + // intersect the tail using scalar intersection + while (i_a < s_a && i_b < s_b) { + uint16_t a = A[i_a]; + uint16_t b = B[i_b]; + if (a < b) { + i_a++; + } else if (b < a) { + i_b++; + } else { + C[count] = a; //==b; + count++; + i_a++; + i_b++; + } + } + return (int32_t)count; +} +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +int32_t intersect_vector16_cardinality(const uint16_t *__restrict__ A, + size_t s_a, + const uint16_t *__restrict__ B, + size_t s_b) { + size_t count = 0; + size_t i_a = 0, i_b = 0; + const int vectorlength = sizeof(__m128i) / sizeof(uint16_t); + const size_t st_a = (s_a / vectorlength) * vectorlength; + const size_t st_b = (s_b / vectorlength) * vectorlength; + __m128i v_a, v_b; + if ((i_a < st_a) && (i_b < st_b)) { + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + while ((A[i_a] == 0) || (B[i_b] == 0)) { + const __m128i res_v = _mm_cmpestrm( + v_b, vectorlength, v_a, vectorlength, + _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK); + const int r = _mm_extract_epi32(res_v, 0); + count += _mm_popcnt_u32(r); + const uint16_t a_max = A[i_a + vectorlength - 1]; + const uint16_t b_max = B[i_b + vectorlength - 1]; + if (a_max <= b_max) { + i_a += vectorlength; + if (i_a == st_a) break; + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + } + if (b_max <= a_max) { + i_b += vectorlength; + if (i_b == st_b) break; + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + } + } + if ((i_a < st_a) && (i_b < st_b)) + while (true) { + const __m128i res_v = _mm_cmpistrm( + v_b, v_a, + _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK); + const int r = _mm_extract_epi32(res_v, 0); + count += _mm_popcnt_u32(r); + const uint16_t a_max = A[i_a + vectorlength - 1]; + const uint16_t b_max = B[i_b + vectorlength - 1]; + if (a_max <= b_max) { + i_a += vectorlength; + if (i_a == st_a) break; + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + } + if (b_max <= a_max) { + i_b += vectorlength; + if (i_b == st_b) break; + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + } + } + } + // intersect the tail using scalar intersection + while (i_a < s_a && i_b < s_b) { + uint16_t a = A[i_a]; + uint16_t b = B[i_b]; + if (a < b) { + i_a++; + } else if (b < a) { + i_b++; + } else { + count++; + i_a++; + i_b++; + } + } + return (int32_t)count; +} +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +///////// +// Warning: +// This function may not be safe if A == C or B == C. +///////// +int32_t difference_vector16(const uint16_t *__restrict__ A, size_t s_a, + const uint16_t *__restrict__ B, size_t s_b, + uint16_t *C) { + // we handle the degenerate case + if (s_a == 0) return 0; + if (s_b == 0) { + if (A != C) memcpy(C, A, sizeof(uint16_t) * s_a); + return (int32_t)s_a; + } + // handle the leading zeroes, it is messy but it allows us to use the fast + // _mm_cmpistrm instrinsic safely + int32_t count = 0; + if ((A[0] == 0) || (B[0] == 0)) { + if ((A[0] == 0) && (B[0] == 0)) { + A++; + s_a--; + B++; + s_b--; + } else if (A[0] == 0) { + C[count++] = 0; + A++; + s_a--; + } else { + B++; + s_b--; + } + } + // at this point, we have two non-empty arrays, made of non-zero + // increasing values. + size_t i_a = 0, i_b = 0; + const size_t vectorlength = sizeof(__m128i) / sizeof(uint16_t); + const size_t st_a = (s_a / vectorlength) * vectorlength; + const size_t st_b = (s_b / vectorlength) * vectorlength; + if ((i_a < st_a) && (i_b < st_b)) { // this is the vectorized code path + __m128i v_a, v_b; //, v_bmax; + // we load a vector from A and a vector from B + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + // we have a runningmask which indicates which values from A have been + // spotted in B, these don't get written out. + __m128i runningmask_a_found_in_b = _mm_setzero_si128(); + /**** + * start of the main vectorized loop + *****/ + while (true) { + // afoundinb will contain a mask indicate for each entry in A + // whether it is seen + // in B + const __m128i a_found_in_b = + _mm_cmpistrm(v_b, v_a, _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | + _SIDD_BIT_MASK); + runningmask_a_found_in_b = + _mm_or_si128(runningmask_a_found_in_b, a_found_in_b); + // we always compare the last values of A and B + const uint16_t a_max = A[i_a + vectorlength - 1]; + const uint16_t b_max = B[i_b + vectorlength - 1]; + if (a_max <= b_max) { + // Ok. In this code path, we are ready to write our v_a + // because there is no need to read more from B, they will + // all be large values. + const int bitmask_belongs_to_difference = + _mm_extract_epi32(runningmask_a_found_in_b, 0) ^ 0xFF; + /*** next few lines are probably expensive *****/ + __m128i sm16 = _mm_load_si128((const __m128i *)shuffle_mask16 + + bitmask_belongs_to_difference); + __m128i p = _mm_shuffle_epi8(v_a, sm16); + _mm_storeu_si128((__m128i *)&C[count], p); // can overflow + count += _mm_popcnt_u32(bitmask_belongs_to_difference); + // we advance a + i_a += vectorlength; + if (i_a == st_a) // no more + break; + runningmask_a_found_in_b = _mm_setzero_si128(); + v_a = _mm_lddqu_si128((__m128i *)&A[i_a]); + } + if (b_max <= a_max) { + // in this code path, the current v_b has become useless + i_b += vectorlength; + if (i_b == st_b) break; + v_b = _mm_lddqu_si128((__m128i *)&B[i_b]); + } + } + // at this point, either we have i_a == st_a, which is the end of the + // vectorized processing, + // or we have i_b == st_b, and we are not done processing the vector... + // so we need to finish it off. + if (i_a < st_a) { // we have unfinished business... + uint16_t buffer[8]; // buffer to do a masked load + memset(buffer, 0, 8 * sizeof(uint16_t)); + memcpy(buffer, B + i_b, (s_b - i_b) * sizeof(uint16_t)); + v_b = _mm_lddqu_si128((__m128i *)buffer); + const __m128i a_found_in_b = + _mm_cmpistrm(v_b, v_a, _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | + _SIDD_BIT_MASK); + runningmask_a_found_in_b = + _mm_or_si128(runningmask_a_found_in_b, a_found_in_b); + const int bitmask_belongs_to_difference = + _mm_extract_epi32(runningmask_a_found_in_b, 0) ^ 0xFF; + __m128i sm16 = _mm_load_si128((const __m128i *)shuffle_mask16 + + bitmask_belongs_to_difference); + __m128i p = _mm_shuffle_epi8(v_a, sm16); + _mm_storeu_si128((__m128i *)&C[count], p); // can overflow + count += _mm_popcnt_u32(bitmask_belongs_to_difference); + i_a += vectorlength; + } + // at this point we should have i_a == st_a and i_b == st_b + } + // do the tail using scalar code + while (i_a < s_a && i_b < s_b) { + uint16_t a = A[i_a]; + uint16_t b = B[i_b]; + if (b < a) { + i_b++; + } else if (a < b) { + C[count] = a; + count++; + i_a++; + } else { //== + i_a++; + i_b++; + } + } + if (i_a < s_a) { + if(C == A) { + assert((size_t)count <= i_a); + if((size_t)count < i_a) { + memmove(C + count, A + i_a, sizeof(uint16_t) * (s_a - i_a)); + } + } else { + for(size_t i = 0; i < (s_a - i_a); i++) { + C[count + i] = A[i + i_a]; + } + } + count += (int32_t)(s_a - i_a); + } + return count; +} +CROARING_UNTARGET_REGION +#endif // CROARING_IS_X64 + + + +/** +* Branchless binary search going after 4 values at once. +* Assumes that array is sorted. +* You have that array[*index1] >= target1, array[*index12] >= target2, ... +* except when *index1 = n, in which case you know that all values in array are +* smaller than target1, and so forth. +* It has logarithmic complexity. +*/ +static void binarySearch4(const uint16_t *array, int32_t n, uint16_t target1, + uint16_t target2, uint16_t target3, uint16_t target4, + int32_t *index1, int32_t *index2, int32_t *index3, + int32_t *index4) { + const uint16_t *base1 = array; + const uint16_t *base2 = array; + const uint16_t *base3 = array; + const uint16_t *base4 = array; + if (n == 0) + return; + while (n > 1) { + int32_t half = n >> 1; + base1 = (base1[half] < target1) ? &base1[half] : base1; + base2 = (base2[half] < target2) ? &base2[half] : base2; + base3 = (base3[half] < target3) ? &base3[half] : base3; + base4 = (base4[half] < target4) ? &base4[half] : base4; + n -= half; + } + *index1 = (int32_t)((*base1 < target1) + base1 - array); + *index2 = (int32_t)((*base2 < target2) + base2 - array); + *index3 = (int32_t)((*base3 < target3) + base3 - array); + *index4 = (int32_t)((*base4 < target4) + base4 - array); +} + +/** +* Branchless binary search going after 2 values at once. +* Assumes that array is sorted. +* You have that array[*index1] >= target1, array[*index12] >= target2. +* except when *index1 = n, in which case you know that all values in array are +* smaller than target1, and so forth. +* It has logarithmic complexity. +*/ +static void binarySearch2(const uint16_t *array, int32_t n, uint16_t target1, + uint16_t target2, int32_t *index1, int32_t *index2) { + const uint16_t *base1 = array; + const uint16_t *base2 = array; + if (n == 0) + return; + while (n > 1) { + int32_t half = n >> 1; + base1 = (base1[half] < target1) ? &base1[half] : base1; + base2 = (base2[half] < target2) ? &base2[half] : base2; + n -= half; + } + *index1 = (int32_t)((*base1 < target1) + base1 - array); + *index2 = (int32_t)((*base2 < target2) + base2 - array); +} + +/* Computes the intersection between one small and one large set of uint16_t. + * Stores the result into buffer and return the number of elements. + * Processes the small set in blocks of 4 values calling binarySearch4 + * and binarySearch2. This approach can be slightly superior to a conventional + * galloping search in some instances. + */ +int32_t intersect_skewed_uint16(const uint16_t *small, size_t size_s, + const uint16_t *large, size_t size_l, + uint16_t *buffer) { + size_t pos = 0, idx_l = 0, idx_s = 0; + + if (0 == size_s) { + return 0; + } + int32_t index1 = 0, index2 = 0, index3 = 0, index4 = 0; + while ((idx_s + 4 <= size_s) && (idx_l < size_l)) { + uint16_t target1 = small[idx_s]; + uint16_t target2 = small[idx_s + 1]; + uint16_t target3 = small[idx_s + 2]; + uint16_t target4 = small[idx_s + 3]; + binarySearch4(large + idx_l, (int32_t)(size_l - idx_l), target1, target2, target3, + target4, &index1, &index2, &index3, &index4); + if ((index1 + idx_l < size_l) && (large[idx_l + index1] == target1)) { + buffer[pos++] = target1; + } + if ((index2 + idx_l < size_l) && (large[idx_l + index2] == target2)) { + buffer[pos++] = target2; + } + if ((index3 + idx_l < size_l) && (large[idx_l + index3] == target3)) { + buffer[pos++] = target3; + } + if ((index4 + idx_l < size_l) && (large[idx_l + index4] == target4)) { + buffer[pos++] = target4; + } + idx_s += 4; + idx_l += index4; + } + if ((idx_s + 2 <= size_s) && (idx_l < size_l)) { + uint16_t target1 = small[idx_s]; + uint16_t target2 = small[idx_s + 1]; + binarySearch2(large + idx_l, (int32_t)(size_l - idx_l), target1, target2, &index1, + &index2); + if ((index1 + idx_l < size_l) && (large[idx_l + index1] == target1)) { + buffer[pos++] = target1; + } + if ((index2 + idx_l < size_l) && (large[idx_l + index2] == target2)) { + buffer[pos++] = target2; + } + idx_s += 2; + idx_l += index2; + } + if ((idx_s < size_s) && (idx_l < size_l)) { + uint16_t val_s = small[idx_s]; + int32_t index = binarySearch(large + idx_l, (int32_t)(size_l - idx_l), val_s); + if (index >= 0) + buffer[pos++] = val_s; + } + return (int32_t)pos; +} + + + +// TODO: this could be accelerated, possibly, by using binarySearch4 as above. +int32_t intersect_skewed_uint16_cardinality(const uint16_t *small, + size_t size_s, + const uint16_t *large, + size_t size_l) { + size_t pos = 0, idx_l = 0, idx_s = 0; + + if (0 == size_s) { + return 0; + } + + uint16_t val_l = large[idx_l], val_s = small[idx_s]; + + while (true) { + if (val_l < val_s) { + idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s); + if (idx_l == size_l) break; + val_l = large[idx_l]; + } else if (val_s < val_l) { + idx_s++; + if (idx_s == size_s) break; + val_s = small[idx_s]; + } else { + pos++; + idx_s++; + if (idx_s == size_s) break; + val_s = small[idx_s]; + idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s); + if (idx_l == size_l) break; + val_l = large[idx_l]; + } + } + + return (int32_t)pos; +} + +bool intersect_skewed_uint16_nonempty(const uint16_t *small, size_t size_s, + const uint16_t *large, size_t size_l) { + size_t idx_l = 0, idx_s = 0; + + if (0 == size_s) { + return false; + } + + uint16_t val_l = large[idx_l], val_s = small[idx_s]; + + while (true) { + if (val_l < val_s) { + idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s); + if (idx_l == size_l) break; + val_l = large[idx_l]; + } else if (val_s < val_l) { + idx_s++; + if (idx_s == size_s) break; + val_s = small[idx_s]; + } else { + return true; + } + } + + return false; +} + +/** + * Generic intersection function. + */ +int32_t intersect_uint16(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB, uint16_t *out) { + const uint16_t *initout = out; + if (lenA == 0 || lenB == 0) return 0; + const uint16_t *endA = A + lenA; + const uint16_t *endB = B + lenB; + + while (1) { + while (*A < *B) { + SKIP_FIRST_COMPARE: + if (++A == endA) return (int32_t)(out - initout); + } + while (*A > *B) { + if (++B == endB) return (int32_t)(out - initout); + } + if (*A == *B) { + *out++ = *A; + if (++A == endA || ++B == endB) return (int32_t)(out - initout); + } else { + goto SKIP_FIRST_COMPARE; + } + } + return (int32_t)(out - initout); // NOTREACHED +} + +int32_t intersect_uint16_cardinality(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB) { + int32_t answer = 0; + if (lenA == 0 || lenB == 0) return 0; + const uint16_t *endA = A + lenA; + const uint16_t *endB = B + lenB; + + while (1) { + while (*A < *B) { + SKIP_FIRST_COMPARE: + if (++A == endA) return answer; + } + while (*A > *B) { + if (++B == endB) return answer; + } + if (*A == *B) { + ++answer; + if (++A == endA || ++B == endB) return answer; + } else { + goto SKIP_FIRST_COMPARE; + } + } + return answer; // NOTREACHED +} + + +bool intersect_uint16_nonempty(const uint16_t *A, const size_t lenA, + const uint16_t *B, const size_t lenB) { + if (lenA == 0 || lenB == 0) return 0; + const uint16_t *endA = A + lenA; + const uint16_t *endB = B + lenB; + + while (1) { + while (*A < *B) { + SKIP_FIRST_COMPARE: + if (++A == endA) return false; + } + while (*A > *B) { + if (++B == endB) return false; + } + if (*A == *B) { + return true; + } else { + goto SKIP_FIRST_COMPARE; + } + } + return false; // NOTREACHED +} + + + +/** + * Generic intersection function. + */ +size_t intersection_uint32(const uint32_t *A, const size_t lenA, + const uint32_t *B, const size_t lenB, + uint32_t *out) { + const uint32_t *initout = out; + if (lenA == 0 || lenB == 0) return 0; + const uint32_t *endA = A + lenA; + const uint32_t *endB = B + lenB; + + while (1) { + while (*A < *B) { + SKIP_FIRST_COMPARE: + if (++A == endA) return (out - initout); + } + while (*A > *B) { + if (++B == endB) return (out - initout); + } + if (*A == *B) { + *out++ = *A; + if (++A == endA || ++B == endB) return (out - initout); + } else { + goto SKIP_FIRST_COMPARE; + } + } + return (out - initout); // NOTREACHED +} + +size_t intersection_uint32_card(const uint32_t *A, const size_t lenA, + const uint32_t *B, const size_t lenB) { + if (lenA == 0 || lenB == 0) return 0; + size_t card = 0; + const uint32_t *endA = A + lenA; + const uint32_t *endB = B + lenB; + + while (1) { + while (*A < *B) { + SKIP_FIRST_COMPARE: + if (++A == endA) return card; + } + while (*A > *B) { + if (++B == endB) return card; + } + if (*A == *B) { + card++; + if (++A == endA || ++B == endB) return card; + } else { + goto SKIP_FIRST_COMPARE; + } + } + return card; // NOTREACHED +} + +// can one vectorize the computation of the union? (Update: Yes! See +// union_vector16). + +size_t union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, + size_t size_2, uint16_t *buffer) { + size_t pos = 0, idx_1 = 0, idx_2 = 0; + + if (0 == size_2) { + memmove(buffer, set_1, size_1 * sizeof(uint16_t)); + return size_1; + } + if (0 == size_1) { + memmove(buffer, set_2, size_2 * sizeof(uint16_t)); + return size_2; + } + + uint16_t val_1 = set_1[idx_1], val_2 = set_2[idx_2]; + + while (true) { + if (val_1 < val_2) { + buffer[pos++] = val_1; + ++idx_1; + if (idx_1 >= size_1) break; + val_1 = set_1[idx_1]; + } else if (val_2 < val_1) { + buffer[pos++] = val_2; + ++idx_2; + if (idx_2 >= size_2) break; + val_2 = set_2[idx_2]; + } else { + buffer[pos++] = val_1; + ++idx_1; + ++idx_2; + if (idx_1 >= size_1 || idx_2 >= size_2) break; + val_1 = set_1[idx_1]; + val_2 = set_2[idx_2]; + } + } + + if (idx_1 < size_1) { + const size_t n_elems = size_1 - idx_1; + memmove(buffer + pos, set_1 + idx_1, n_elems * sizeof(uint16_t)); + pos += n_elems; + } else if (idx_2 < size_2) { + const size_t n_elems = size_2 - idx_2; + memmove(buffer + pos, set_2 + idx_2, n_elems * sizeof(uint16_t)); + pos += n_elems; + } + + return pos; +} + +int difference_uint16(const uint16_t *a1, int length1, const uint16_t *a2, + int length2, uint16_t *a_out) { + int out_card = 0; + int k1 = 0, k2 = 0; + if (length1 == 0) return 0; + if (length2 == 0) { + if (a1 != a_out) memcpy(a_out, a1, sizeof(uint16_t) * length1); + return length1; + } + uint16_t s1 = a1[k1]; + uint16_t s2 = a2[k2]; + while (true) { + if (s1 < s2) { + a_out[out_card++] = s1; + ++k1; + if (k1 >= length1) { + break; + } + s1 = a1[k1]; + } else if (s1 == s2) { + ++k1; + ++k2; + if (k1 >= length1) { + break; + } + if (k2 >= length2) { + memmove(a_out + out_card, a1 + k1, + sizeof(uint16_t) * (length1 - k1)); + return out_card + length1 - k1; + } + s1 = a1[k1]; + s2 = a2[k2]; + } else { // if (val1>val2) + ++k2; + if (k2 >= length2) { + memmove(a_out + out_card, a1 + k1, + sizeof(uint16_t) * (length1 - k1)); + return out_card + length1 - k1; + } + s2 = a2[k2]; + } + } + return out_card; +} + +int32_t xor_uint16(const uint16_t *array_1, int32_t card_1, + const uint16_t *array_2, int32_t card_2, uint16_t *out) { + int32_t pos1 = 0, pos2 = 0, pos_out = 0; + while (pos1 < card_1 && pos2 < card_2) { + const uint16_t v1 = array_1[pos1]; + const uint16_t v2 = array_2[pos2]; + if (v1 == v2) { + ++pos1; + ++pos2; + continue; + } + if (v1 < v2) { + out[pos_out++] = v1; + ++pos1; + } else { + out[pos_out++] = v2; + ++pos2; + } + } + if (pos1 < card_1) { + const size_t n_elems = card_1 - pos1; + memcpy(out + pos_out, array_1 + pos1, n_elems * sizeof(uint16_t)); + pos_out += (int32_t)n_elems; + } else if (pos2 < card_2) { + const size_t n_elems = card_2 - pos2; + memcpy(out + pos_out, array_2 + pos2, n_elems * sizeof(uint16_t)); + pos_out += (int32_t)n_elems; + } + return pos_out; +} + +#ifdef CROARING_IS_X64 + +/*** + * start of the SIMD 16-bit union code + * + */ +CROARING_TARGET_AVX2 + +// Assuming that vInput1 and vInput2 are sorted, produces a sorted output going +// from vecMin all the way to vecMax +// developed originally for merge sort using SIMD instructions. +// Standard merge. See, e.g., Inoue and Taura, SIMD- and Cache-Friendly +// Algorithm for Sorting an Array of Structures +static inline void sse_merge(const __m128i *vInput1, + const __m128i *vInput2, // input 1 & 2 + __m128i *vecMin, __m128i *vecMax) { // output + __m128i vecTmp; + vecTmp = _mm_min_epu16(*vInput1, *vInput2); + *vecMax = _mm_max_epu16(*vInput1, *vInput2); + vecTmp = _mm_alignr_epi8(vecTmp, vecTmp, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + vecTmp = _mm_alignr_epi8(*vecMin, *vecMin, 2); + *vecMin = _mm_min_epu16(vecTmp, *vecMax); + *vecMax = _mm_max_epu16(vecTmp, *vecMax); + *vecMin = _mm_alignr_epi8(*vecMin, *vecMin, 2); +} +CROARING_UNTARGET_REGION +// used by store_unique, generated by simdunion.py +static uint8_t uniqshuf[] = { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xc, 0xd, 0xe, 0xf, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xa, 0xb, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0xa, 0xb, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xa, 0xb, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, + 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8, 0x9, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0xc, 0xd, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0xc, 0xd, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xc, 0xd, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x8, 0x9, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x8, 0x9, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, 0xa, 0xb, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6, 0x7, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0xa, 0xb, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xa, 0xb, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x8, 0x9, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0xe, 0xf, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xe, 0xf, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xe, 0xf, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, + 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8, 0x9, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0xa, 0xb, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0xa, 0xb, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xa, 0xb, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0x8, 0x9, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x8, 0x9, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x8, 0x9, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6, 0x7, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xc, 0xd, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xc, 0xd, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xa, 0xb, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x8, 0x9, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xa, 0xb, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0xa, 0xb, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xa, 0xb, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xa, 0xb, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x6, 0x7, + 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x6, 0x7, + 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x6, 0x7, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x8, 0x9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, + 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x4, 0x5, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8, 0x9, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, + 0x6, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x4, 0x5, 0x6, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, 0x6, 0x7, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0x6, 0x7, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x6, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0x7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x2, 0x3, + 0x4, 0x5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x2, 0x3, 0x4, 0x5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0x4, 0x5, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4, 0x5, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0, 0x1, 0x2, 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x2, 0x3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF}; +CROARING_TARGET_AVX2 +// write vector new, while omitting repeated values assuming that previously +// written vector was "old" +static inline int store_unique(__m128i old, __m128i newval, uint16_t *output) { + __m128i vecTmp = _mm_alignr_epi8(newval, old, 16 - 2); + // lots of high latency instructions follow (optimize?) + int M = _mm_movemask_epi8( + _mm_packs_epi16(_mm_cmpeq_epi16(vecTmp, newval), _mm_setzero_si128())); + int numberofnewvalues = 8 - _mm_popcnt_u32(M); + __m128i key = _mm_lddqu_si128((const __m128i *)uniqshuf + M); + __m128i val = _mm_shuffle_epi8(newval, key); + _mm_storeu_si128((__m128i *)output, val); + return numberofnewvalues; +} +CROARING_UNTARGET_REGION + +// working in-place, this function overwrites the repeated values +// could be avoided? +static inline uint32_t unique(uint16_t *out, uint32_t len) { + uint32_t pos = 1; + for (uint32_t i = 1; i < len; ++i) { + if (out[i] != out[i - 1]) { + out[pos++] = out[i]; + } + } + return pos; +} + +// use with qsort, could be avoided +static int uint16_compare(const void *a, const void *b) { + return (*(uint16_t *)a - *(uint16_t *)b); +} + +CROARING_TARGET_AVX2 +// a one-pass SSE union algorithm +// This function may not be safe if array1 == output or array2 == output. +uint32_t union_vector16(const uint16_t *__restrict__ array1, uint32_t length1, + const uint16_t *__restrict__ array2, uint32_t length2, + uint16_t *__restrict__ output) { + if ((length1 < 8) || (length2 < 8)) { + return (uint32_t)union_uint16(array1, length1, array2, length2, output); + } + __m128i vA, vB, V, vecMin, vecMax; + __m128i laststore; + uint16_t *initoutput = output; + uint32_t len1 = length1 / 8; + uint32_t len2 = length2 / 8; + uint32_t pos1 = 0; + uint32_t pos2 = 0; + // we start the machine + vA = _mm_lddqu_si128((const __m128i *)array1 + pos1); + pos1++; + vB = _mm_lddqu_si128((const __m128i *)array2 + pos2); + pos2++; + sse_merge(&vA, &vB, &vecMin, &vecMax); + laststore = _mm_set1_epi16(-1); + output += store_unique(laststore, vecMin, output); + laststore = vecMin; + if ((pos1 < len1) && (pos2 < len2)) { + uint16_t curA, curB; + curA = array1[8 * pos1]; + curB = array2[8 * pos2]; + while (true) { + if (curA <= curB) { + V = _mm_lddqu_si128((const __m128i *)array1 + pos1); + pos1++; + if (pos1 < len1) { + curA = array1[8 * pos1]; + } else { + break; + } + } else { + V = _mm_lddqu_si128((const __m128i *)array2 + pos2); + pos2++; + if (pos2 < len2) { + curB = array2[8 * pos2]; + } else { + break; + } + } + sse_merge(&V, &vecMax, &vecMin, &vecMax); + output += store_unique(laststore, vecMin, output); + laststore = vecMin; + } + sse_merge(&V, &vecMax, &vecMin, &vecMax); + output += store_unique(laststore, vecMin, output); + laststore = vecMin; + } + // we finish the rest off using a scalar algorithm + // could be improved? + // + // copy the small end on a tmp buffer + uint32_t len = (uint32_t)(output - initoutput); + uint16_t buffer[16]; + uint32_t leftoversize = store_unique(laststore, vecMax, buffer); + if (pos1 == len1) { + memcpy(buffer + leftoversize, array1 + 8 * pos1, + (length1 - 8 * len1) * sizeof(uint16_t)); + leftoversize += length1 - 8 * len1; + qsort(buffer, leftoversize, sizeof(uint16_t), uint16_compare); + + leftoversize = unique(buffer, leftoversize); + len += (uint32_t)union_uint16(buffer, leftoversize, array2 + 8 * pos2, + length2 - 8 * pos2, output); + } else { + memcpy(buffer + leftoversize, array2 + 8 * pos2, + (length2 - 8 * len2) * sizeof(uint16_t)); + leftoversize += length2 - 8 * len2; + qsort(buffer, leftoversize, sizeof(uint16_t), uint16_compare); + leftoversize = unique(buffer, leftoversize); + len += (uint32_t)union_uint16(buffer, leftoversize, array1 + 8 * pos1, + length1 - 8 * pos1, output); + } + return len; +} +CROARING_UNTARGET_REGION + +/** + * End of the SIMD 16-bit union code + * + */ + +/** + * Start of SIMD 16-bit XOR code + */ + +CROARING_TARGET_AVX2 +// write vector new, while omitting repeated values assuming that previously +// written vector was "old" +static inline int store_unique_xor(__m128i old, __m128i newval, + uint16_t *output) { + __m128i vecTmp1 = _mm_alignr_epi8(newval, old, 16 - 4); + __m128i vecTmp2 = _mm_alignr_epi8(newval, old, 16 - 2); + __m128i equalleft = _mm_cmpeq_epi16(vecTmp2, vecTmp1); + __m128i equalright = _mm_cmpeq_epi16(vecTmp2, newval); + __m128i equalleftoright = _mm_or_si128(equalleft, equalright); + int M = _mm_movemask_epi8( + _mm_packs_epi16(equalleftoright, _mm_setzero_si128())); + int numberofnewvalues = 8 - _mm_popcnt_u32(M); + __m128i key = _mm_lddqu_si128((const __m128i *)uniqshuf + M); + __m128i val = _mm_shuffle_epi8(vecTmp2, key); + _mm_storeu_si128((__m128i *)output, val); + return numberofnewvalues; +} +CROARING_UNTARGET_REGION + +// working in-place, this function overwrites the repeated values +// could be avoided? Warning: assumes len > 0 +static inline uint32_t unique_xor(uint16_t *out, uint32_t len) { + uint32_t pos = 1; + for (uint32_t i = 1; i < len; ++i) { + if (out[i] != out[i - 1]) { + out[pos++] = out[i]; + } else + pos--; // if it is identical to previous, delete it + } + return pos; +} +CROARING_TARGET_AVX2 +// a one-pass SSE xor algorithm +uint32_t xor_vector16(const uint16_t *__restrict__ array1, uint32_t length1, + const uint16_t *__restrict__ array2, uint32_t length2, + uint16_t *__restrict__ output) { + if ((length1 < 8) || (length2 < 8)) { + return xor_uint16(array1, length1, array2, length2, output); + } + __m128i vA, vB, V, vecMin, vecMax; + __m128i laststore; + uint16_t *initoutput = output; + uint32_t len1 = length1 / 8; + uint32_t len2 = length2 / 8; + uint32_t pos1 = 0; + uint32_t pos2 = 0; + // we start the machine + vA = _mm_lddqu_si128((const __m128i *)array1 + pos1); + pos1++; + vB = _mm_lddqu_si128((const __m128i *)array2 + pos2); + pos2++; + sse_merge(&vA, &vB, &vecMin, &vecMax); + laststore = _mm_set1_epi16(-1); + uint16_t buffer[17]; + output += store_unique_xor(laststore, vecMin, output); + + laststore = vecMin; + if ((pos1 < len1) && (pos2 < len2)) { + uint16_t curA, curB; + curA = array1[8 * pos1]; + curB = array2[8 * pos2]; + while (true) { + if (curA <= curB) { + V = _mm_lddqu_si128((const __m128i *)array1 + pos1); + pos1++; + if (pos1 < len1) { + curA = array1[8 * pos1]; + } else { + break; + } + } else { + V = _mm_lddqu_si128((const __m128i *)array2 + pos2); + pos2++; + if (pos2 < len2) { + curB = array2[8 * pos2]; + } else { + break; + } + } + sse_merge(&V, &vecMax, &vecMin, &vecMax); + // conditionally stores the last value of laststore as well as all + // but the + // last value of vecMin + output += store_unique_xor(laststore, vecMin, output); + laststore = vecMin; + } + sse_merge(&V, &vecMax, &vecMin, &vecMax); + // conditionally stores the last value of laststore as well as all but + // the + // last value of vecMin + output += store_unique_xor(laststore, vecMin, output); + laststore = vecMin; + } + uint32_t len = (uint32_t)(output - initoutput); + + // we finish the rest off using a scalar algorithm + // could be improved? + // conditionally stores the last value of laststore as well as all but the + // last value of vecMax, + // we store to "buffer" + int leftoversize = store_unique_xor(laststore, vecMax, buffer); + uint16_t vec7 = _mm_extract_epi16(vecMax, 7); + uint16_t vec6 = _mm_extract_epi16(vecMax, 6); + if (vec7 != vec6) buffer[leftoversize++] = vec7; + if (pos1 == len1) { + memcpy(buffer + leftoversize, array1 + 8 * pos1, + (length1 - 8 * len1) * sizeof(uint16_t)); + leftoversize += length1 - 8 * len1; + if (leftoversize == 0) { // trivial case + memcpy(output, array2 + 8 * pos2, + (length2 - 8 * pos2) * sizeof(uint16_t)); + len += (length2 - 8 * pos2); + } else { + qsort(buffer, leftoversize, sizeof(uint16_t), uint16_compare); + leftoversize = unique_xor(buffer, leftoversize); + len += xor_uint16(buffer, leftoversize, array2 + 8 * pos2, + length2 - 8 * pos2, output); + } + } else { + memcpy(buffer + leftoversize, array2 + 8 * pos2, + (length2 - 8 * len2) * sizeof(uint16_t)); + leftoversize += length2 - 8 * len2; + if (leftoversize == 0) { // trivial case + memcpy(output, array1 + 8 * pos1, + (length1 - 8 * pos1) * sizeof(uint16_t)); + len += (length1 - 8 * pos1); + } else { + qsort(buffer, leftoversize, sizeof(uint16_t), uint16_compare); + leftoversize = unique_xor(buffer, leftoversize); + len += xor_uint16(buffer, leftoversize, array1 + 8 * pos1, + length1 - 8 * pos1, output); + } + } + return len; +} +CROARING_UNTARGET_REGION +/** + * End of SIMD 16-bit XOR code + */ + +#endif // CROARING_IS_X64 + +size_t union_uint32(const uint32_t *set_1, size_t size_1, const uint32_t *set_2, + size_t size_2, uint32_t *buffer) { + size_t pos = 0, idx_1 = 0, idx_2 = 0; + + if (0 == size_2) { + memmove(buffer, set_1, size_1 * sizeof(uint32_t)); + return size_1; + } + if (0 == size_1) { + memmove(buffer, set_2, size_2 * sizeof(uint32_t)); + return size_2; + } + + uint32_t val_1 = set_1[idx_1], val_2 = set_2[idx_2]; + + while (true) { + if (val_1 < val_2) { + buffer[pos++] = val_1; + ++idx_1; + if (idx_1 >= size_1) break; + val_1 = set_1[idx_1]; + } else if (val_2 < val_1) { + buffer[pos++] = val_2; + ++idx_2; + if (idx_2 >= size_2) break; + val_2 = set_2[idx_2]; + } else { + buffer[pos++] = val_1; + ++idx_1; + ++idx_2; + if (idx_1 >= size_1 || idx_2 >= size_2) break; + val_1 = set_1[idx_1]; + val_2 = set_2[idx_2]; + } + } + + if (idx_1 < size_1) { + const size_t n_elems = size_1 - idx_1; + memmove(buffer + pos, set_1 + idx_1, n_elems * sizeof(uint32_t)); + pos += n_elems; + } else if (idx_2 < size_2) { + const size_t n_elems = size_2 - idx_2; + memmove(buffer + pos, set_2 + idx_2, n_elems * sizeof(uint32_t)); + pos += n_elems; + } + + return pos; +} + +size_t union_uint32_card(const uint32_t *set_1, size_t size_1, + const uint32_t *set_2, size_t size_2) { + size_t pos = 0, idx_1 = 0, idx_2 = 0; + + if (0 == size_2) { + return size_1; + } + if (0 == size_1) { + return size_2; + } + + uint32_t val_1 = set_1[idx_1], val_2 = set_2[idx_2]; + + while (true) { + if (val_1 < val_2) { + ++idx_1; + ++pos; + if (idx_1 >= size_1) break; + val_1 = set_1[idx_1]; + } else if (val_2 < val_1) { + ++idx_2; + ++pos; + if (idx_2 >= size_2) break; + val_2 = set_2[idx_2]; + } else { + ++idx_1; + ++idx_2; + ++pos; + if (idx_1 >= size_1 || idx_2 >= size_2) break; + val_1 = set_1[idx_1]; + val_2 = set_2[idx_2]; + } + } + + if (idx_1 < size_1) { + const size_t n_elems = size_1 - idx_1; + pos += n_elems; + } else if (idx_2 < size_2) { + const size_t n_elems = size_2 - idx_2; + pos += n_elems; + } + return pos; +} + + + +size_t fast_union_uint16(const uint16_t *set_1, size_t size_1, const uint16_t *set_2, + size_t size_2, uint16_t *buffer) { +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + // compute union with smallest array first + if (size_1 < size_2) { + return union_vector16(set_1, (uint32_t)size_1, + set_2, (uint32_t)size_2, buffer); + } else { + return union_vector16(set_2, (uint32_t)size_2, + set_1, (uint32_t)size_1, buffer); + } + } else { + // compute union with smallest array first + if (size_1 < size_2) { + return union_uint16( + set_1, size_1, set_2, size_2, buffer); + } else { + return union_uint16( + set_2, size_2, set_1, size_1, buffer); + } + } +#else + // compute union with smallest array first + if (size_1 < size_2) { + return union_uint16( + set_1, size_1, set_2, size_2, buffer); + } else { + return union_uint16( + set_2, size_2, set_1, size_1, buffer); + } +#endif +} +#ifdef CROARING_IS_X64 +CROARING_TARGET_AVX2 +static inline bool _avx2_memequals(const void *s1, const void *s2, size_t n) { + const uint8_t *ptr1 = (const uint8_t *)s1; + const uint8_t *ptr2 = (const uint8_t *)s2; + const uint8_t *end1 = ptr1 + n; + const uint8_t *end8 = ptr1 + n/8*8; + const uint8_t *end32 = ptr1 + n/32*32; + + while (ptr1 < end32) { + __m256i r1 = _mm256_loadu_si256((const __m256i*)ptr1); + __m256i r2 = _mm256_loadu_si256((const __m256i*)ptr2); + int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(r1, r2)); + if ((uint32_t)mask != UINT32_MAX) { + return false; + } + ptr1 += 32; + ptr2 += 32; + } + + while (ptr1 < end8) { + uint64_t v1 = *((const uint64_t*)ptr1); + uint64_t v2 = *((const uint64_t*)ptr2); + if (v1 != v2) { + return false; + } + ptr1 += 8; + ptr2 += 8; + } + + while (ptr1 < end1) { + if (*ptr1 != *ptr2) { + return false; + } + ptr1++; + ptr2++; + } + + return true; +} +CROARING_UNTARGET_REGION +#endif + +bool memequals(const void *s1, const void *s2, size_t n) { + if (n == 0) { + return true; + } +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + return _avx2_memequals(s1, s2, n); + } else { + return memcmp(s1, s2, n) == 0; + } +#else + return memcmp(s1, s2, n) == 0; +#endif +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/array_util.c */ +/* begin file src/bitset_util.c */ +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +#ifdef CROARING_IS_X64 +static uint8_t lengthTable[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, + 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, + 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, + 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; +#endif + +#ifdef CROARING_IS_X64 +ALIGNED(32) +static uint32_t vecDecodeTable[256][8] = { + {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x00 (00000000) */ + {1, 0, 0, 0, 0, 0, 0, 0}, /* 0x01 (00000001) */ + {2, 0, 0, 0, 0, 0, 0, 0}, /* 0x02 (00000010) */ + {1, 2, 0, 0, 0, 0, 0, 0}, /* 0x03 (00000011) */ + {3, 0, 0, 0, 0, 0, 0, 0}, /* 0x04 (00000100) */ + {1, 3, 0, 0, 0, 0, 0, 0}, /* 0x05 (00000101) */ + {2, 3, 0, 0, 0, 0, 0, 0}, /* 0x06 (00000110) */ + {1, 2, 3, 0, 0, 0, 0, 0}, /* 0x07 (00000111) */ + {4, 0, 0, 0, 0, 0, 0, 0}, /* 0x08 (00001000) */ + {1, 4, 0, 0, 0, 0, 0, 0}, /* 0x09 (00001001) */ + {2, 4, 0, 0, 0, 0, 0, 0}, /* 0x0A (00001010) */ + {1, 2, 4, 0, 0, 0, 0, 0}, /* 0x0B (00001011) */ + {3, 4, 0, 0, 0, 0, 0, 0}, /* 0x0C (00001100) */ + {1, 3, 4, 0, 0, 0, 0, 0}, /* 0x0D (00001101) */ + {2, 3, 4, 0, 0, 0, 0, 0}, /* 0x0E (00001110) */ + {1, 2, 3, 4, 0, 0, 0, 0}, /* 0x0F (00001111) */ + {5, 0, 0, 0, 0, 0, 0, 0}, /* 0x10 (00010000) */ + {1, 5, 0, 0, 0, 0, 0, 0}, /* 0x11 (00010001) */ + {2, 5, 0, 0, 0, 0, 0, 0}, /* 0x12 (00010010) */ + {1, 2, 5, 0, 0, 0, 0, 0}, /* 0x13 (00010011) */ + {3, 5, 0, 0, 0, 0, 0, 0}, /* 0x14 (00010100) */ + {1, 3, 5, 0, 0, 0, 0, 0}, /* 0x15 (00010101) */ + {2, 3, 5, 0, 0, 0, 0, 0}, /* 0x16 (00010110) */ + {1, 2, 3, 5, 0, 0, 0, 0}, /* 0x17 (00010111) */ + {4, 5, 0, 0, 0, 0, 0, 0}, /* 0x18 (00011000) */ + {1, 4, 5, 0, 0, 0, 0, 0}, /* 0x19 (00011001) */ + {2, 4, 5, 0, 0, 0, 0, 0}, /* 0x1A (00011010) */ + {1, 2, 4, 5, 0, 0, 0, 0}, /* 0x1B (00011011) */ + {3, 4, 5, 0, 0, 0, 0, 0}, /* 0x1C (00011100) */ + {1, 3, 4, 5, 0, 0, 0, 0}, /* 0x1D (00011101) */ + {2, 3, 4, 5, 0, 0, 0, 0}, /* 0x1E (00011110) */ + {1, 2, 3, 4, 5, 0, 0, 0}, /* 0x1F (00011111) */ + {6, 0, 0, 0, 0, 0, 0, 0}, /* 0x20 (00100000) */ + {1, 6, 0, 0, 0, 0, 0, 0}, /* 0x21 (00100001) */ + {2, 6, 0, 0, 0, 0, 0, 0}, /* 0x22 (00100010) */ + {1, 2, 6, 0, 0, 0, 0, 0}, /* 0x23 (00100011) */ + {3, 6, 0, 0, 0, 0, 0, 0}, /* 0x24 (00100100) */ + {1, 3, 6, 0, 0, 0, 0, 0}, /* 0x25 (00100101) */ + {2, 3, 6, 0, 0, 0, 0, 0}, /* 0x26 (00100110) */ + {1, 2, 3, 6, 0, 0, 0, 0}, /* 0x27 (00100111) */ + {4, 6, 0, 0, 0, 0, 0, 0}, /* 0x28 (00101000) */ + {1, 4, 6, 0, 0, 0, 0, 0}, /* 0x29 (00101001) */ + {2, 4, 6, 0, 0, 0, 0, 0}, /* 0x2A (00101010) */ + {1, 2, 4, 6, 0, 0, 0, 0}, /* 0x2B (00101011) */ + {3, 4, 6, 0, 0, 0, 0, 0}, /* 0x2C (00101100) */ + {1, 3, 4, 6, 0, 0, 0, 0}, /* 0x2D (00101101) */ + {2, 3, 4, 6, 0, 0, 0, 0}, /* 0x2E (00101110) */ + {1, 2, 3, 4, 6, 0, 0, 0}, /* 0x2F (00101111) */ + {5, 6, 0, 0, 0, 0, 0, 0}, /* 0x30 (00110000) */ + {1, 5, 6, 0, 0, 0, 0, 0}, /* 0x31 (00110001) */ + {2, 5, 6, 0, 0, 0, 0, 0}, /* 0x32 (00110010) */ + {1, 2, 5, 6, 0, 0, 0, 0}, /* 0x33 (00110011) */ + {3, 5, 6, 0, 0, 0, 0, 0}, /* 0x34 (00110100) */ + {1, 3, 5, 6, 0, 0, 0, 0}, /* 0x35 (00110101) */ + {2, 3, 5, 6, 0, 0, 0, 0}, /* 0x36 (00110110) */ + {1, 2, 3, 5, 6, 0, 0, 0}, /* 0x37 (00110111) */ + {4, 5, 6, 0, 0, 0, 0, 0}, /* 0x38 (00111000) */ + {1, 4, 5, 6, 0, 0, 0, 0}, /* 0x39 (00111001) */ + {2, 4, 5, 6, 0, 0, 0, 0}, /* 0x3A (00111010) */ + {1, 2, 4, 5, 6, 0, 0, 0}, /* 0x3B (00111011) */ + {3, 4, 5, 6, 0, 0, 0, 0}, /* 0x3C (00111100) */ + {1, 3, 4, 5, 6, 0, 0, 0}, /* 0x3D (00111101) */ + {2, 3, 4, 5, 6, 0, 0, 0}, /* 0x3E (00111110) */ + {1, 2, 3, 4, 5, 6, 0, 0}, /* 0x3F (00111111) */ + {7, 0, 0, 0, 0, 0, 0, 0}, /* 0x40 (01000000) */ + {1, 7, 0, 0, 0, 0, 0, 0}, /* 0x41 (01000001) */ + {2, 7, 0, 0, 0, 0, 0, 0}, /* 0x42 (01000010) */ + {1, 2, 7, 0, 0, 0, 0, 0}, /* 0x43 (01000011) */ + {3, 7, 0, 0, 0, 0, 0, 0}, /* 0x44 (01000100) */ + {1, 3, 7, 0, 0, 0, 0, 0}, /* 0x45 (01000101) */ + {2, 3, 7, 0, 0, 0, 0, 0}, /* 0x46 (01000110) */ + {1, 2, 3, 7, 0, 0, 0, 0}, /* 0x47 (01000111) */ + {4, 7, 0, 0, 0, 0, 0, 0}, /* 0x48 (01001000) */ + {1, 4, 7, 0, 0, 0, 0, 0}, /* 0x49 (01001001) */ + {2, 4, 7, 0, 0, 0, 0, 0}, /* 0x4A (01001010) */ + {1, 2, 4, 7, 0, 0, 0, 0}, /* 0x4B (01001011) */ + {3, 4, 7, 0, 0, 0, 0, 0}, /* 0x4C (01001100) */ + {1, 3, 4, 7, 0, 0, 0, 0}, /* 0x4D (01001101) */ + {2, 3, 4, 7, 0, 0, 0, 0}, /* 0x4E (01001110) */ + {1, 2, 3, 4, 7, 0, 0, 0}, /* 0x4F (01001111) */ + {5, 7, 0, 0, 0, 0, 0, 0}, /* 0x50 (01010000) */ + {1, 5, 7, 0, 0, 0, 0, 0}, /* 0x51 (01010001) */ + {2, 5, 7, 0, 0, 0, 0, 0}, /* 0x52 (01010010) */ + {1, 2, 5, 7, 0, 0, 0, 0}, /* 0x53 (01010011) */ + {3, 5, 7, 0, 0, 0, 0, 0}, /* 0x54 (01010100) */ + {1, 3, 5, 7, 0, 0, 0, 0}, /* 0x55 (01010101) */ + {2, 3, 5, 7, 0, 0, 0, 0}, /* 0x56 (01010110) */ + {1, 2, 3, 5, 7, 0, 0, 0}, /* 0x57 (01010111) */ + {4, 5, 7, 0, 0, 0, 0, 0}, /* 0x58 (01011000) */ + {1, 4, 5, 7, 0, 0, 0, 0}, /* 0x59 (01011001) */ + {2, 4, 5, 7, 0, 0, 0, 0}, /* 0x5A (01011010) */ + {1, 2, 4, 5, 7, 0, 0, 0}, /* 0x5B (01011011) */ + {3, 4, 5, 7, 0, 0, 0, 0}, /* 0x5C (01011100) */ + {1, 3, 4, 5, 7, 0, 0, 0}, /* 0x5D (01011101) */ + {2, 3, 4, 5, 7, 0, 0, 0}, /* 0x5E (01011110) */ + {1, 2, 3, 4, 5, 7, 0, 0}, /* 0x5F (01011111) */ + {6, 7, 0, 0, 0, 0, 0, 0}, /* 0x60 (01100000) */ + {1, 6, 7, 0, 0, 0, 0, 0}, /* 0x61 (01100001) */ + {2, 6, 7, 0, 0, 0, 0, 0}, /* 0x62 (01100010) */ + {1, 2, 6, 7, 0, 0, 0, 0}, /* 0x63 (01100011) */ + {3, 6, 7, 0, 0, 0, 0, 0}, /* 0x64 (01100100) */ + {1, 3, 6, 7, 0, 0, 0, 0}, /* 0x65 (01100101) */ + {2, 3, 6, 7, 0, 0, 0, 0}, /* 0x66 (01100110) */ + {1, 2, 3, 6, 7, 0, 0, 0}, /* 0x67 (01100111) */ + {4, 6, 7, 0, 0, 0, 0, 0}, /* 0x68 (01101000) */ + {1, 4, 6, 7, 0, 0, 0, 0}, /* 0x69 (01101001) */ + {2, 4, 6, 7, 0, 0, 0, 0}, /* 0x6A (01101010) */ + {1, 2, 4, 6, 7, 0, 0, 0}, /* 0x6B (01101011) */ + {3, 4, 6, 7, 0, 0, 0, 0}, /* 0x6C (01101100) */ + {1, 3, 4, 6, 7, 0, 0, 0}, /* 0x6D (01101101) */ + {2, 3, 4, 6, 7, 0, 0, 0}, /* 0x6E (01101110) */ + {1, 2, 3, 4, 6, 7, 0, 0}, /* 0x6F (01101111) */ + {5, 6, 7, 0, 0, 0, 0, 0}, /* 0x70 (01110000) */ + {1, 5, 6, 7, 0, 0, 0, 0}, /* 0x71 (01110001) */ + {2, 5, 6, 7, 0, 0, 0, 0}, /* 0x72 (01110010) */ + {1, 2, 5, 6, 7, 0, 0, 0}, /* 0x73 (01110011) */ + {3, 5, 6, 7, 0, 0, 0, 0}, /* 0x74 (01110100) */ + {1, 3, 5, 6, 7, 0, 0, 0}, /* 0x75 (01110101) */ + {2, 3, 5, 6, 7, 0, 0, 0}, /* 0x76 (01110110) */ + {1, 2, 3, 5, 6, 7, 0, 0}, /* 0x77 (01110111) */ + {4, 5, 6, 7, 0, 0, 0, 0}, /* 0x78 (01111000) */ + {1, 4, 5, 6, 7, 0, 0, 0}, /* 0x79 (01111001) */ + {2, 4, 5, 6, 7, 0, 0, 0}, /* 0x7A (01111010) */ + {1, 2, 4, 5, 6, 7, 0, 0}, /* 0x7B (01111011) */ + {3, 4, 5, 6, 7, 0, 0, 0}, /* 0x7C (01111100) */ + {1, 3, 4, 5, 6, 7, 0, 0}, /* 0x7D (01111101) */ + {2, 3, 4, 5, 6, 7, 0, 0}, /* 0x7E (01111110) */ + {1, 2, 3, 4, 5, 6, 7, 0}, /* 0x7F (01111111) */ + {8, 0, 0, 0, 0, 0, 0, 0}, /* 0x80 (10000000) */ + {1, 8, 0, 0, 0, 0, 0, 0}, /* 0x81 (10000001) */ + {2, 8, 0, 0, 0, 0, 0, 0}, /* 0x82 (10000010) */ + {1, 2, 8, 0, 0, 0, 0, 0}, /* 0x83 (10000011) */ + {3, 8, 0, 0, 0, 0, 0, 0}, /* 0x84 (10000100) */ + {1, 3, 8, 0, 0, 0, 0, 0}, /* 0x85 (10000101) */ + {2, 3, 8, 0, 0, 0, 0, 0}, /* 0x86 (10000110) */ + {1, 2, 3, 8, 0, 0, 0, 0}, /* 0x87 (10000111) */ + {4, 8, 0, 0, 0, 0, 0, 0}, /* 0x88 (10001000) */ + {1, 4, 8, 0, 0, 0, 0, 0}, /* 0x89 (10001001) */ + {2, 4, 8, 0, 0, 0, 0, 0}, /* 0x8A (10001010) */ + {1, 2, 4, 8, 0, 0, 0, 0}, /* 0x8B (10001011) */ + {3, 4, 8, 0, 0, 0, 0, 0}, /* 0x8C (10001100) */ + {1, 3, 4, 8, 0, 0, 0, 0}, /* 0x8D (10001101) */ + {2, 3, 4, 8, 0, 0, 0, 0}, /* 0x8E (10001110) */ + {1, 2, 3, 4, 8, 0, 0, 0}, /* 0x8F (10001111) */ + {5, 8, 0, 0, 0, 0, 0, 0}, /* 0x90 (10010000) */ + {1, 5, 8, 0, 0, 0, 0, 0}, /* 0x91 (10010001) */ + {2, 5, 8, 0, 0, 0, 0, 0}, /* 0x92 (10010010) */ + {1, 2, 5, 8, 0, 0, 0, 0}, /* 0x93 (10010011) */ + {3, 5, 8, 0, 0, 0, 0, 0}, /* 0x94 (10010100) */ + {1, 3, 5, 8, 0, 0, 0, 0}, /* 0x95 (10010101) */ + {2, 3, 5, 8, 0, 0, 0, 0}, /* 0x96 (10010110) */ + {1, 2, 3, 5, 8, 0, 0, 0}, /* 0x97 (10010111) */ + {4, 5, 8, 0, 0, 0, 0, 0}, /* 0x98 (10011000) */ + {1, 4, 5, 8, 0, 0, 0, 0}, /* 0x99 (10011001) */ + {2, 4, 5, 8, 0, 0, 0, 0}, /* 0x9A (10011010) */ + {1, 2, 4, 5, 8, 0, 0, 0}, /* 0x9B (10011011) */ + {3, 4, 5, 8, 0, 0, 0, 0}, /* 0x9C (10011100) */ + {1, 3, 4, 5, 8, 0, 0, 0}, /* 0x9D (10011101) */ + {2, 3, 4, 5, 8, 0, 0, 0}, /* 0x9E (10011110) */ + {1, 2, 3, 4, 5, 8, 0, 0}, /* 0x9F (10011111) */ + {6, 8, 0, 0, 0, 0, 0, 0}, /* 0xA0 (10100000) */ + {1, 6, 8, 0, 0, 0, 0, 0}, /* 0xA1 (10100001) */ + {2, 6, 8, 0, 0, 0, 0, 0}, /* 0xA2 (10100010) */ + {1, 2, 6, 8, 0, 0, 0, 0}, /* 0xA3 (10100011) */ + {3, 6, 8, 0, 0, 0, 0, 0}, /* 0xA4 (10100100) */ + {1, 3, 6, 8, 0, 0, 0, 0}, /* 0xA5 (10100101) */ + {2, 3, 6, 8, 0, 0, 0, 0}, /* 0xA6 (10100110) */ + {1, 2, 3, 6, 8, 0, 0, 0}, /* 0xA7 (10100111) */ + {4, 6, 8, 0, 0, 0, 0, 0}, /* 0xA8 (10101000) */ + {1, 4, 6, 8, 0, 0, 0, 0}, /* 0xA9 (10101001) */ + {2, 4, 6, 8, 0, 0, 0, 0}, /* 0xAA (10101010) */ + {1, 2, 4, 6, 8, 0, 0, 0}, /* 0xAB (10101011) */ + {3, 4, 6, 8, 0, 0, 0, 0}, /* 0xAC (10101100) */ + {1, 3, 4, 6, 8, 0, 0, 0}, /* 0xAD (10101101) */ + {2, 3, 4, 6, 8, 0, 0, 0}, /* 0xAE (10101110) */ + {1, 2, 3, 4, 6, 8, 0, 0}, /* 0xAF (10101111) */ + {5, 6, 8, 0, 0, 0, 0, 0}, /* 0xB0 (10110000) */ + {1, 5, 6, 8, 0, 0, 0, 0}, /* 0xB1 (10110001) */ + {2, 5, 6, 8, 0, 0, 0, 0}, /* 0xB2 (10110010) */ + {1, 2, 5, 6, 8, 0, 0, 0}, /* 0xB3 (10110011) */ + {3, 5, 6, 8, 0, 0, 0, 0}, /* 0xB4 (10110100) */ + {1, 3, 5, 6, 8, 0, 0, 0}, /* 0xB5 (10110101) */ + {2, 3, 5, 6, 8, 0, 0, 0}, /* 0xB6 (10110110) */ + {1, 2, 3, 5, 6, 8, 0, 0}, /* 0xB7 (10110111) */ + {4, 5, 6, 8, 0, 0, 0, 0}, /* 0xB8 (10111000) */ + {1, 4, 5, 6, 8, 0, 0, 0}, /* 0xB9 (10111001) */ + {2, 4, 5, 6, 8, 0, 0, 0}, /* 0xBA (10111010) */ + {1, 2, 4, 5, 6, 8, 0, 0}, /* 0xBB (10111011) */ + {3, 4, 5, 6, 8, 0, 0, 0}, /* 0xBC (10111100) */ + {1, 3, 4, 5, 6, 8, 0, 0}, /* 0xBD (10111101) */ + {2, 3, 4, 5, 6, 8, 0, 0}, /* 0xBE (10111110) */ + {1, 2, 3, 4, 5, 6, 8, 0}, /* 0xBF (10111111) */ + {7, 8, 0, 0, 0, 0, 0, 0}, /* 0xC0 (11000000) */ + {1, 7, 8, 0, 0, 0, 0, 0}, /* 0xC1 (11000001) */ + {2, 7, 8, 0, 0, 0, 0, 0}, /* 0xC2 (11000010) */ + {1, 2, 7, 8, 0, 0, 0, 0}, /* 0xC3 (11000011) */ + {3, 7, 8, 0, 0, 0, 0, 0}, /* 0xC4 (11000100) */ + {1, 3, 7, 8, 0, 0, 0, 0}, /* 0xC5 (11000101) */ + {2, 3, 7, 8, 0, 0, 0, 0}, /* 0xC6 (11000110) */ + {1, 2, 3, 7, 8, 0, 0, 0}, /* 0xC7 (11000111) */ + {4, 7, 8, 0, 0, 0, 0, 0}, /* 0xC8 (11001000) */ + {1, 4, 7, 8, 0, 0, 0, 0}, /* 0xC9 (11001001) */ + {2, 4, 7, 8, 0, 0, 0, 0}, /* 0xCA (11001010) */ + {1, 2, 4, 7, 8, 0, 0, 0}, /* 0xCB (11001011) */ + {3, 4, 7, 8, 0, 0, 0, 0}, /* 0xCC (11001100) */ + {1, 3, 4, 7, 8, 0, 0, 0}, /* 0xCD (11001101) */ + {2, 3, 4, 7, 8, 0, 0, 0}, /* 0xCE (11001110) */ + {1, 2, 3, 4, 7, 8, 0, 0}, /* 0xCF (11001111) */ + {5, 7, 8, 0, 0, 0, 0, 0}, /* 0xD0 (11010000) */ + {1, 5, 7, 8, 0, 0, 0, 0}, /* 0xD1 (11010001) */ + {2, 5, 7, 8, 0, 0, 0, 0}, /* 0xD2 (11010010) */ + {1, 2, 5, 7, 8, 0, 0, 0}, /* 0xD3 (11010011) */ + {3, 5, 7, 8, 0, 0, 0, 0}, /* 0xD4 (11010100) */ + {1, 3, 5, 7, 8, 0, 0, 0}, /* 0xD5 (11010101) */ + {2, 3, 5, 7, 8, 0, 0, 0}, /* 0xD6 (11010110) */ + {1, 2, 3, 5, 7, 8, 0, 0}, /* 0xD7 (11010111) */ + {4, 5, 7, 8, 0, 0, 0, 0}, /* 0xD8 (11011000) */ + {1, 4, 5, 7, 8, 0, 0, 0}, /* 0xD9 (11011001) */ + {2, 4, 5, 7, 8, 0, 0, 0}, /* 0xDA (11011010) */ + {1, 2, 4, 5, 7, 8, 0, 0}, /* 0xDB (11011011) */ + {3, 4, 5, 7, 8, 0, 0, 0}, /* 0xDC (11011100) */ + {1, 3, 4, 5, 7, 8, 0, 0}, /* 0xDD (11011101) */ + {2, 3, 4, 5, 7, 8, 0, 0}, /* 0xDE (11011110) */ + {1, 2, 3, 4, 5, 7, 8, 0}, /* 0xDF (11011111) */ + {6, 7, 8, 0, 0, 0, 0, 0}, /* 0xE0 (11100000) */ + {1, 6, 7, 8, 0, 0, 0, 0}, /* 0xE1 (11100001) */ + {2, 6, 7, 8, 0, 0, 0, 0}, /* 0xE2 (11100010) */ + {1, 2, 6, 7, 8, 0, 0, 0}, /* 0xE3 (11100011) */ + {3, 6, 7, 8, 0, 0, 0, 0}, /* 0xE4 (11100100) */ + {1, 3, 6, 7, 8, 0, 0, 0}, /* 0xE5 (11100101) */ + {2, 3, 6, 7, 8, 0, 0, 0}, /* 0xE6 (11100110) */ + {1, 2, 3, 6, 7, 8, 0, 0}, /* 0xE7 (11100111) */ + {4, 6, 7, 8, 0, 0, 0, 0}, /* 0xE8 (11101000) */ + {1, 4, 6, 7, 8, 0, 0, 0}, /* 0xE9 (11101001) */ + {2, 4, 6, 7, 8, 0, 0, 0}, /* 0xEA (11101010) */ + {1, 2, 4, 6, 7, 8, 0, 0}, /* 0xEB (11101011) */ + {3, 4, 6, 7, 8, 0, 0, 0}, /* 0xEC (11101100) */ + {1, 3, 4, 6, 7, 8, 0, 0}, /* 0xED (11101101) */ + {2, 3, 4, 6, 7, 8, 0, 0}, /* 0xEE (11101110) */ + {1, 2, 3, 4, 6, 7, 8, 0}, /* 0xEF (11101111) */ + {5, 6, 7, 8, 0, 0, 0, 0}, /* 0xF0 (11110000) */ + {1, 5, 6, 7, 8, 0, 0, 0}, /* 0xF1 (11110001) */ + {2, 5, 6, 7, 8, 0, 0, 0}, /* 0xF2 (11110010) */ + {1, 2, 5, 6, 7, 8, 0, 0}, /* 0xF3 (11110011) */ + {3, 5, 6, 7, 8, 0, 0, 0}, /* 0xF4 (11110100) */ + {1, 3, 5, 6, 7, 8, 0, 0}, /* 0xF5 (11110101) */ + {2, 3, 5, 6, 7, 8, 0, 0}, /* 0xF6 (11110110) */ + {1, 2, 3, 5, 6, 7, 8, 0}, /* 0xF7 (11110111) */ + {4, 5, 6, 7, 8, 0, 0, 0}, /* 0xF8 (11111000) */ + {1, 4, 5, 6, 7, 8, 0, 0}, /* 0xF9 (11111001) */ + {2, 4, 5, 6, 7, 8, 0, 0}, /* 0xFA (11111010) */ + {1, 2, 4, 5, 6, 7, 8, 0}, /* 0xFB (11111011) */ + {3, 4, 5, 6, 7, 8, 0, 0}, /* 0xFC (11111100) */ + {1, 3, 4, 5, 6, 7, 8, 0}, /* 0xFD (11111101) */ + {2, 3, 4, 5, 6, 7, 8, 0}, /* 0xFE (11111110) */ + {1, 2, 3, 4, 5, 6, 7, 8} /* 0xFF (11111111) */ +}; + +#endif // #ifdef CROARING_IS_X64 + +#ifdef CROARING_IS_X64 +// same as vecDecodeTable but in 16 bits +ALIGNED(32) +static uint16_t vecDecodeTable_uint16[256][8] = { + {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x00 (00000000) */ + {1, 0, 0, 0, 0, 0, 0, 0}, /* 0x01 (00000001) */ + {2, 0, 0, 0, 0, 0, 0, 0}, /* 0x02 (00000010) */ + {1, 2, 0, 0, 0, 0, 0, 0}, /* 0x03 (00000011) */ + {3, 0, 0, 0, 0, 0, 0, 0}, /* 0x04 (00000100) */ + {1, 3, 0, 0, 0, 0, 0, 0}, /* 0x05 (00000101) */ + {2, 3, 0, 0, 0, 0, 0, 0}, /* 0x06 (00000110) */ + {1, 2, 3, 0, 0, 0, 0, 0}, /* 0x07 (00000111) */ + {4, 0, 0, 0, 0, 0, 0, 0}, /* 0x08 (00001000) */ + {1, 4, 0, 0, 0, 0, 0, 0}, /* 0x09 (00001001) */ + {2, 4, 0, 0, 0, 0, 0, 0}, /* 0x0A (00001010) */ + {1, 2, 4, 0, 0, 0, 0, 0}, /* 0x0B (00001011) */ + {3, 4, 0, 0, 0, 0, 0, 0}, /* 0x0C (00001100) */ + {1, 3, 4, 0, 0, 0, 0, 0}, /* 0x0D (00001101) */ + {2, 3, 4, 0, 0, 0, 0, 0}, /* 0x0E (00001110) */ + {1, 2, 3, 4, 0, 0, 0, 0}, /* 0x0F (00001111) */ + {5, 0, 0, 0, 0, 0, 0, 0}, /* 0x10 (00010000) */ + {1, 5, 0, 0, 0, 0, 0, 0}, /* 0x11 (00010001) */ + {2, 5, 0, 0, 0, 0, 0, 0}, /* 0x12 (00010010) */ + {1, 2, 5, 0, 0, 0, 0, 0}, /* 0x13 (00010011) */ + {3, 5, 0, 0, 0, 0, 0, 0}, /* 0x14 (00010100) */ + {1, 3, 5, 0, 0, 0, 0, 0}, /* 0x15 (00010101) */ + {2, 3, 5, 0, 0, 0, 0, 0}, /* 0x16 (00010110) */ + {1, 2, 3, 5, 0, 0, 0, 0}, /* 0x17 (00010111) */ + {4, 5, 0, 0, 0, 0, 0, 0}, /* 0x18 (00011000) */ + {1, 4, 5, 0, 0, 0, 0, 0}, /* 0x19 (00011001) */ + {2, 4, 5, 0, 0, 0, 0, 0}, /* 0x1A (00011010) */ + {1, 2, 4, 5, 0, 0, 0, 0}, /* 0x1B (00011011) */ + {3, 4, 5, 0, 0, 0, 0, 0}, /* 0x1C (00011100) */ + {1, 3, 4, 5, 0, 0, 0, 0}, /* 0x1D (00011101) */ + {2, 3, 4, 5, 0, 0, 0, 0}, /* 0x1E (00011110) */ + {1, 2, 3, 4, 5, 0, 0, 0}, /* 0x1F (00011111) */ + {6, 0, 0, 0, 0, 0, 0, 0}, /* 0x20 (00100000) */ + {1, 6, 0, 0, 0, 0, 0, 0}, /* 0x21 (00100001) */ + {2, 6, 0, 0, 0, 0, 0, 0}, /* 0x22 (00100010) */ + {1, 2, 6, 0, 0, 0, 0, 0}, /* 0x23 (00100011) */ + {3, 6, 0, 0, 0, 0, 0, 0}, /* 0x24 (00100100) */ + {1, 3, 6, 0, 0, 0, 0, 0}, /* 0x25 (00100101) */ + {2, 3, 6, 0, 0, 0, 0, 0}, /* 0x26 (00100110) */ + {1, 2, 3, 6, 0, 0, 0, 0}, /* 0x27 (00100111) */ + {4, 6, 0, 0, 0, 0, 0, 0}, /* 0x28 (00101000) */ + {1, 4, 6, 0, 0, 0, 0, 0}, /* 0x29 (00101001) */ + {2, 4, 6, 0, 0, 0, 0, 0}, /* 0x2A (00101010) */ + {1, 2, 4, 6, 0, 0, 0, 0}, /* 0x2B (00101011) */ + {3, 4, 6, 0, 0, 0, 0, 0}, /* 0x2C (00101100) */ + {1, 3, 4, 6, 0, 0, 0, 0}, /* 0x2D (00101101) */ + {2, 3, 4, 6, 0, 0, 0, 0}, /* 0x2E (00101110) */ + {1, 2, 3, 4, 6, 0, 0, 0}, /* 0x2F (00101111) */ + {5, 6, 0, 0, 0, 0, 0, 0}, /* 0x30 (00110000) */ + {1, 5, 6, 0, 0, 0, 0, 0}, /* 0x31 (00110001) */ + {2, 5, 6, 0, 0, 0, 0, 0}, /* 0x32 (00110010) */ + {1, 2, 5, 6, 0, 0, 0, 0}, /* 0x33 (00110011) */ + {3, 5, 6, 0, 0, 0, 0, 0}, /* 0x34 (00110100) */ + {1, 3, 5, 6, 0, 0, 0, 0}, /* 0x35 (00110101) */ + {2, 3, 5, 6, 0, 0, 0, 0}, /* 0x36 (00110110) */ + {1, 2, 3, 5, 6, 0, 0, 0}, /* 0x37 (00110111) */ + {4, 5, 6, 0, 0, 0, 0, 0}, /* 0x38 (00111000) */ + {1, 4, 5, 6, 0, 0, 0, 0}, /* 0x39 (00111001) */ + {2, 4, 5, 6, 0, 0, 0, 0}, /* 0x3A (00111010) */ + {1, 2, 4, 5, 6, 0, 0, 0}, /* 0x3B (00111011) */ + {3, 4, 5, 6, 0, 0, 0, 0}, /* 0x3C (00111100) */ + {1, 3, 4, 5, 6, 0, 0, 0}, /* 0x3D (00111101) */ + {2, 3, 4, 5, 6, 0, 0, 0}, /* 0x3E (00111110) */ + {1, 2, 3, 4, 5, 6, 0, 0}, /* 0x3F (00111111) */ + {7, 0, 0, 0, 0, 0, 0, 0}, /* 0x40 (01000000) */ + {1, 7, 0, 0, 0, 0, 0, 0}, /* 0x41 (01000001) */ + {2, 7, 0, 0, 0, 0, 0, 0}, /* 0x42 (01000010) */ + {1, 2, 7, 0, 0, 0, 0, 0}, /* 0x43 (01000011) */ + {3, 7, 0, 0, 0, 0, 0, 0}, /* 0x44 (01000100) */ + {1, 3, 7, 0, 0, 0, 0, 0}, /* 0x45 (01000101) */ + {2, 3, 7, 0, 0, 0, 0, 0}, /* 0x46 (01000110) */ + {1, 2, 3, 7, 0, 0, 0, 0}, /* 0x47 (01000111) */ + {4, 7, 0, 0, 0, 0, 0, 0}, /* 0x48 (01001000) */ + {1, 4, 7, 0, 0, 0, 0, 0}, /* 0x49 (01001001) */ + {2, 4, 7, 0, 0, 0, 0, 0}, /* 0x4A (01001010) */ + {1, 2, 4, 7, 0, 0, 0, 0}, /* 0x4B (01001011) */ + {3, 4, 7, 0, 0, 0, 0, 0}, /* 0x4C (01001100) */ + {1, 3, 4, 7, 0, 0, 0, 0}, /* 0x4D (01001101) */ + {2, 3, 4, 7, 0, 0, 0, 0}, /* 0x4E (01001110) */ + {1, 2, 3, 4, 7, 0, 0, 0}, /* 0x4F (01001111) */ + {5, 7, 0, 0, 0, 0, 0, 0}, /* 0x50 (01010000) */ + {1, 5, 7, 0, 0, 0, 0, 0}, /* 0x51 (01010001) */ + {2, 5, 7, 0, 0, 0, 0, 0}, /* 0x52 (01010010) */ + {1, 2, 5, 7, 0, 0, 0, 0}, /* 0x53 (01010011) */ + {3, 5, 7, 0, 0, 0, 0, 0}, /* 0x54 (01010100) */ + {1, 3, 5, 7, 0, 0, 0, 0}, /* 0x55 (01010101) */ + {2, 3, 5, 7, 0, 0, 0, 0}, /* 0x56 (01010110) */ + {1, 2, 3, 5, 7, 0, 0, 0}, /* 0x57 (01010111) */ + {4, 5, 7, 0, 0, 0, 0, 0}, /* 0x58 (01011000) */ + {1, 4, 5, 7, 0, 0, 0, 0}, /* 0x59 (01011001) */ + {2, 4, 5, 7, 0, 0, 0, 0}, /* 0x5A (01011010) */ + {1, 2, 4, 5, 7, 0, 0, 0}, /* 0x5B (01011011) */ + {3, 4, 5, 7, 0, 0, 0, 0}, /* 0x5C (01011100) */ + {1, 3, 4, 5, 7, 0, 0, 0}, /* 0x5D (01011101) */ + {2, 3, 4, 5, 7, 0, 0, 0}, /* 0x5E (01011110) */ + {1, 2, 3, 4, 5, 7, 0, 0}, /* 0x5F (01011111) */ + {6, 7, 0, 0, 0, 0, 0, 0}, /* 0x60 (01100000) */ + {1, 6, 7, 0, 0, 0, 0, 0}, /* 0x61 (01100001) */ + {2, 6, 7, 0, 0, 0, 0, 0}, /* 0x62 (01100010) */ + {1, 2, 6, 7, 0, 0, 0, 0}, /* 0x63 (01100011) */ + {3, 6, 7, 0, 0, 0, 0, 0}, /* 0x64 (01100100) */ + {1, 3, 6, 7, 0, 0, 0, 0}, /* 0x65 (01100101) */ + {2, 3, 6, 7, 0, 0, 0, 0}, /* 0x66 (01100110) */ + {1, 2, 3, 6, 7, 0, 0, 0}, /* 0x67 (01100111) */ + {4, 6, 7, 0, 0, 0, 0, 0}, /* 0x68 (01101000) */ + {1, 4, 6, 7, 0, 0, 0, 0}, /* 0x69 (01101001) */ + {2, 4, 6, 7, 0, 0, 0, 0}, /* 0x6A (01101010) */ + {1, 2, 4, 6, 7, 0, 0, 0}, /* 0x6B (01101011) */ + {3, 4, 6, 7, 0, 0, 0, 0}, /* 0x6C (01101100) */ + {1, 3, 4, 6, 7, 0, 0, 0}, /* 0x6D (01101101) */ + {2, 3, 4, 6, 7, 0, 0, 0}, /* 0x6E (01101110) */ + {1, 2, 3, 4, 6, 7, 0, 0}, /* 0x6F (01101111) */ + {5, 6, 7, 0, 0, 0, 0, 0}, /* 0x70 (01110000) */ + {1, 5, 6, 7, 0, 0, 0, 0}, /* 0x71 (01110001) */ + {2, 5, 6, 7, 0, 0, 0, 0}, /* 0x72 (01110010) */ + {1, 2, 5, 6, 7, 0, 0, 0}, /* 0x73 (01110011) */ + {3, 5, 6, 7, 0, 0, 0, 0}, /* 0x74 (01110100) */ + {1, 3, 5, 6, 7, 0, 0, 0}, /* 0x75 (01110101) */ + {2, 3, 5, 6, 7, 0, 0, 0}, /* 0x76 (01110110) */ + {1, 2, 3, 5, 6, 7, 0, 0}, /* 0x77 (01110111) */ + {4, 5, 6, 7, 0, 0, 0, 0}, /* 0x78 (01111000) */ + {1, 4, 5, 6, 7, 0, 0, 0}, /* 0x79 (01111001) */ + {2, 4, 5, 6, 7, 0, 0, 0}, /* 0x7A (01111010) */ + {1, 2, 4, 5, 6, 7, 0, 0}, /* 0x7B (01111011) */ + {3, 4, 5, 6, 7, 0, 0, 0}, /* 0x7C (01111100) */ + {1, 3, 4, 5, 6, 7, 0, 0}, /* 0x7D (01111101) */ + {2, 3, 4, 5, 6, 7, 0, 0}, /* 0x7E (01111110) */ + {1, 2, 3, 4, 5, 6, 7, 0}, /* 0x7F (01111111) */ + {8, 0, 0, 0, 0, 0, 0, 0}, /* 0x80 (10000000) */ + {1, 8, 0, 0, 0, 0, 0, 0}, /* 0x81 (10000001) */ + {2, 8, 0, 0, 0, 0, 0, 0}, /* 0x82 (10000010) */ + {1, 2, 8, 0, 0, 0, 0, 0}, /* 0x83 (10000011) */ + {3, 8, 0, 0, 0, 0, 0, 0}, /* 0x84 (10000100) */ + {1, 3, 8, 0, 0, 0, 0, 0}, /* 0x85 (10000101) */ + {2, 3, 8, 0, 0, 0, 0, 0}, /* 0x86 (10000110) */ + {1, 2, 3, 8, 0, 0, 0, 0}, /* 0x87 (10000111) */ + {4, 8, 0, 0, 0, 0, 0, 0}, /* 0x88 (10001000) */ + {1, 4, 8, 0, 0, 0, 0, 0}, /* 0x89 (10001001) */ + {2, 4, 8, 0, 0, 0, 0, 0}, /* 0x8A (10001010) */ + {1, 2, 4, 8, 0, 0, 0, 0}, /* 0x8B (10001011) */ + {3, 4, 8, 0, 0, 0, 0, 0}, /* 0x8C (10001100) */ + {1, 3, 4, 8, 0, 0, 0, 0}, /* 0x8D (10001101) */ + {2, 3, 4, 8, 0, 0, 0, 0}, /* 0x8E (10001110) */ + {1, 2, 3, 4, 8, 0, 0, 0}, /* 0x8F (10001111) */ + {5, 8, 0, 0, 0, 0, 0, 0}, /* 0x90 (10010000) */ + {1, 5, 8, 0, 0, 0, 0, 0}, /* 0x91 (10010001) */ + {2, 5, 8, 0, 0, 0, 0, 0}, /* 0x92 (10010010) */ + {1, 2, 5, 8, 0, 0, 0, 0}, /* 0x93 (10010011) */ + {3, 5, 8, 0, 0, 0, 0, 0}, /* 0x94 (10010100) */ + {1, 3, 5, 8, 0, 0, 0, 0}, /* 0x95 (10010101) */ + {2, 3, 5, 8, 0, 0, 0, 0}, /* 0x96 (10010110) */ + {1, 2, 3, 5, 8, 0, 0, 0}, /* 0x97 (10010111) */ + {4, 5, 8, 0, 0, 0, 0, 0}, /* 0x98 (10011000) */ + {1, 4, 5, 8, 0, 0, 0, 0}, /* 0x99 (10011001) */ + {2, 4, 5, 8, 0, 0, 0, 0}, /* 0x9A (10011010) */ + {1, 2, 4, 5, 8, 0, 0, 0}, /* 0x9B (10011011) */ + {3, 4, 5, 8, 0, 0, 0, 0}, /* 0x9C (10011100) */ + {1, 3, 4, 5, 8, 0, 0, 0}, /* 0x9D (10011101) */ + {2, 3, 4, 5, 8, 0, 0, 0}, /* 0x9E (10011110) */ + {1, 2, 3, 4, 5, 8, 0, 0}, /* 0x9F (10011111) */ + {6, 8, 0, 0, 0, 0, 0, 0}, /* 0xA0 (10100000) */ + {1, 6, 8, 0, 0, 0, 0, 0}, /* 0xA1 (10100001) */ + {2, 6, 8, 0, 0, 0, 0, 0}, /* 0xA2 (10100010) */ + {1, 2, 6, 8, 0, 0, 0, 0}, /* 0xA3 (10100011) */ + {3, 6, 8, 0, 0, 0, 0, 0}, /* 0xA4 (10100100) */ + {1, 3, 6, 8, 0, 0, 0, 0}, /* 0xA5 (10100101) */ + {2, 3, 6, 8, 0, 0, 0, 0}, /* 0xA6 (10100110) */ + {1, 2, 3, 6, 8, 0, 0, 0}, /* 0xA7 (10100111) */ + {4, 6, 8, 0, 0, 0, 0, 0}, /* 0xA8 (10101000) */ + {1, 4, 6, 8, 0, 0, 0, 0}, /* 0xA9 (10101001) */ + {2, 4, 6, 8, 0, 0, 0, 0}, /* 0xAA (10101010) */ + {1, 2, 4, 6, 8, 0, 0, 0}, /* 0xAB (10101011) */ + {3, 4, 6, 8, 0, 0, 0, 0}, /* 0xAC (10101100) */ + {1, 3, 4, 6, 8, 0, 0, 0}, /* 0xAD (10101101) */ + {2, 3, 4, 6, 8, 0, 0, 0}, /* 0xAE (10101110) */ + {1, 2, 3, 4, 6, 8, 0, 0}, /* 0xAF (10101111) */ + {5, 6, 8, 0, 0, 0, 0, 0}, /* 0xB0 (10110000) */ + {1, 5, 6, 8, 0, 0, 0, 0}, /* 0xB1 (10110001) */ + {2, 5, 6, 8, 0, 0, 0, 0}, /* 0xB2 (10110010) */ + {1, 2, 5, 6, 8, 0, 0, 0}, /* 0xB3 (10110011) */ + {3, 5, 6, 8, 0, 0, 0, 0}, /* 0xB4 (10110100) */ + {1, 3, 5, 6, 8, 0, 0, 0}, /* 0xB5 (10110101) */ + {2, 3, 5, 6, 8, 0, 0, 0}, /* 0xB6 (10110110) */ + {1, 2, 3, 5, 6, 8, 0, 0}, /* 0xB7 (10110111) */ + {4, 5, 6, 8, 0, 0, 0, 0}, /* 0xB8 (10111000) */ + {1, 4, 5, 6, 8, 0, 0, 0}, /* 0xB9 (10111001) */ + {2, 4, 5, 6, 8, 0, 0, 0}, /* 0xBA (10111010) */ + {1, 2, 4, 5, 6, 8, 0, 0}, /* 0xBB (10111011) */ + {3, 4, 5, 6, 8, 0, 0, 0}, /* 0xBC (10111100) */ + {1, 3, 4, 5, 6, 8, 0, 0}, /* 0xBD (10111101) */ + {2, 3, 4, 5, 6, 8, 0, 0}, /* 0xBE (10111110) */ + {1, 2, 3, 4, 5, 6, 8, 0}, /* 0xBF (10111111) */ + {7, 8, 0, 0, 0, 0, 0, 0}, /* 0xC0 (11000000) */ + {1, 7, 8, 0, 0, 0, 0, 0}, /* 0xC1 (11000001) */ + {2, 7, 8, 0, 0, 0, 0, 0}, /* 0xC2 (11000010) */ + {1, 2, 7, 8, 0, 0, 0, 0}, /* 0xC3 (11000011) */ + {3, 7, 8, 0, 0, 0, 0, 0}, /* 0xC4 (11000100) */ + {1, 3, 7, 8, 0, 0, 0, 0}, /* 0xC5 (11000101) */ + {2, 3, 7, 8, 0, 0, 0, 0}, /* 0xC6 (11000110) */ + {1, 2, 3, 7, 8, 0, 0, 0}, /* 0xC7 (11000111) */ + {4, 7, 8, 0, 0, 0, 0, 0}, /* 0xC8 (11001000) */ + {1, 4, 7, 8, 0, 0, 0, 0}, /* 0xC9 (11001001) */ + {2, 4, 7, 8, 0, 0, 0, 0}, /* 0xCA (11001010) */ + {1, 2, 4, 7, 8, 0, 0, 0}, /* 0xCB (11001011) */ + {3, 4, 7, 8, 0, 0, 0, 0}, /* 0xCC (11001100) */ + {1, 3, 4, 7, 8, 0, 0, 0}, /* 0xCD (11001101) */ + {2, 3, 4, 7, 8, 0, 0, 0}, /* 0xCE (11001110) */ + {1, 2, 3, 4, 7, 8, 0, 0}, /* 0xCF (11001111) */ + {5, 7, 8, 0, 0, 0, 0, 0}, /* 0xD0 (11010000) */ + {1, 5, 7, 8, 0, 0, 0, 0}, /* 0xD1 (11010001) */ + {2, 5, 7, 8, 0, 0, 0, 0}, /* 0xD2 (11010010) */ + {1, 2, 5, 7, 8, 0, 0, 0}, /* 0xD3 (11010011) */ + {3, 5, 7, 8, 0, 0, 0, 0}, /* 0xD4 (11010100) */ + {1, 3, 5, 7, 8, 0, 0, 0}, /* 0xD5 (11010101) */ + {2, 3, 5, 7, 8, 0, 0, 0}, /* 0xD6 (11010110) */ + {1, 2, 3, 5, 7, 8, 0, 0}, /* 0xD7 (11010111) */ + {4, 5, 7, 8, 0, 0, 0, 0}, /* 0xD8 (11011000) */ + {1, 4, 5, 7, 8, 0, 0, 0}, /* 0xD9 (11011001) */ + {2, 4, 5, 7, 8, 0, 0, 0}, /* 0xDA (11011010) */ + {1, 2, 4, 5, 7, 8, 0, 0}, /* 0xDB (11011011) */ + {3, 4, 5, 7, 8, 0, 0, 0}, /* 0xDC (11011100) */ + {1, 3, 4, 5, 7, 8, 0, 0}, /* 0xDD (11011101) */ + {2, 3, 4, 5, 7, 8, 0, 0}, /* 0xDE (11011110) */ + {1, 2, 3, 4, 5, 7, 8, 0}, /* 0xDF (11011111) */ + {6, 7, 8, 0, 0, 0, 0, 0}, /* 0xE0 (11100000) */ + {1, 6, 7, 8, 0, 0, 0, 0}, /* 0xE1 (11100001) */ + {2, 6, 7, 8, 0, 0, 0, 0}, /* 0xE2 (11100010) */ + {1, 2, 6, 7, 8, 0, 0, 0}, /* 0xE3 (11100011) */ + {3, 6, 7, 8, 0, 0, 0, 0}, /* 0xE4 (11100100) */ + {1, 3, 6, 7, 8, 0, 0, 0}, /* 0xE5 (11100101) */ + {2, 3, 6, 7, 8, 0, 0, 0}, /* 0xE6 (11100110) */ + {1, 2, 3, 6, 7, 8, 0, 0}, /* 0xE7 (11100111) */ + {4, 6, 7, 8, 0, 0, 0, 0}, /* 0xE8 (11101000) */ + {1, 4, 6, 7, 8, 0, 0, 0}, /* 0xE9 (11101001) */ + {2, 4, 6, 7, 8, 0, 0, 0}, /* 0xEA (11101010) */ + {1, 2, 4, 6, 7, 8, 0, 0}, /* 0xEB (11101011) */ + {3, 4, 6, 7, 8, 0, 0, 0}, /* 0xEC (11101100) */ + {1, 3, 4, 6, 7, 8, 0, 0}, /* 0xED (11101101) */ + {2, 3, 4, 6, 7, 8, 0, 0}, /* 0xEE (11101110) */ + {1, 2, 3, 4, 6, 7, 8, 0}, /* 0xEF (11101111) */ + {5, 6, 7, 8, 0, 0, 0, 0}, /* 0xF0 (11110000) */ + {1, 5, 6, 7, 8, 0, 0, 0}, /* 0xF1 (11110001) */ + {2, 5, 6, 7, 8, 0, 0, 0}, /* 0xF2 (11110010) */ + {1, 2, 5, 6, 7, 8, 0, 0}, /* 0xF3 (11110011) */ + {3, 5, 6, 7, 8, 0, 0, 0}, /* 0xF4 (11110100) */ + {1, 3, 5, 6, 7, 8, 0, 0}, /* 0xF5 (11110101) */ + {2, 3, 5, 6, 7, 8, 0, 0}, /* 0xF6 (11110110) */ + {1, 2, 3, 5, 6, 7, 8, 0}, /* 0xF7 (11110111) */ + {4, 5, 6, 7, 8, 0, 0, 0}, /* 0xF8 (11111000) */ + {1, 4, 5, 6, 7, 8, 0, 0}, /* 0xF9 (11111001) */ + {2, 4, 5, 6, 7, 8, 0, 0}, /* 0xFA (11111010) */ + {1, 2, 4, 5, 6, 7, 8, 0}, /* 0xFB (11111011) */ + {3, 4, 5, 6, 7, 8, 0, 0}, /* 0xFC (11111100) */ + {1, 3, 4, 5, 6, 7, 8, 0}, /* 0xFD (11111101) */ + {2, 3, 4, 5, 6, 7, 8, 0}, /* 0xFE (11111110) */ + {1, 2, 3, 4, 5, 6, 7, 8} /* 0xFF (11111111) */ +}; + +#endif + +#ifdef CROARING_IS_X64 +CROARING_TARGET_AVX2 +size_t bitset_extract_setbits_avx2(const uint64_t *words, size_t length, + uint32_t *out, size_t outcapacity, + uint32_t base) { + uint32_t *initout = out; + __m256i baseVec = _mm256_set1_epi32(base - 1); + __m256i incVec = _mm256_set1_epi32(64); + __m256i add8 = _mm256_set1_epi32(8); + uint32_t *safeout = out + outcapacity; + size_t i = 0; + for (; (i < length) && (out + 64 <= safeout); ++i) { + uint64_t w = words[i]; + if (w == 0) { + baseVec = _mm256_add_epi32(baseVec, incVec); + } else { + for (int k = 0; k < 4; ++k) { + uint8_t byteA = (uint8_t)w; + uint8_t byteB = (uint8_t)(w >> 8); + w >>= 16; + __m256i vecA = + _mm256_load_si256((const __m256i *)vecDecodeTable[byteA]); + __m256i vecB = + _mm256_load_si256((const __m256i *)vecDecodeTable[byteB]); + uint8_t advanceA = lengthTable[byteA]; + uint8_t advanceB = lengthTable[byteB]; + vecA = _mm256_add_epi32(baseVec, vecA); + baseVec = _mm256_add_epi32(baseVec, add8); + vecB = _mm256_add_epi32(baseVec, vecB); + baseVec = _mm256_add_epi32(baseVec, add8); + _mm256_storeu_si256((__m256i *)out, vecA); + out += advanceA; + _mm256_storeu_si256((__m256i *)out, vecB); + out += advanceB; + } + } + } + base += i * 64; + for (; (i < length) && (out < safeout); ++i) { + uint64_t w = words[i]; + while ((w != 0) && (out < safeout)) { + uint64_t t = w & (~w + 1); // on x64, should compile to BLSI (careful: the Intel compiler seems to fail) + int r = __builtin_ctzll(w); // on x64, should compile to TZCNT + uint32_t val = r + base; + memcpy(out, &val, + sizeof(uint32_t)); // should be compiled as a MOV on x64 + out++; + w ^= t; + } + base += 64; + } + return out - initout; +} +CROARING_UNTARGET_REGION +#endif // CROARING_IS_X64 + +size_t bitset_extract_setbits(const uint64_t *words, size_t length, + uint32_t *out, uint32_t base) { + int outpos = 0; + for (size_t i = 0; i < length; ++i) { + uint64_t w = words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); // on x64, should compile to BLSI (careful: the Intel compiler seems to fail) + int r = __builtin_ctzll(w); // on x64, should compile to TZCNT + uint32_t val = r + base; + memcpy(out + outpos, &val, + sizeof(uint32_t)); // should be compiled as a MOV on x64 + outpos++; + w ^= t; + } + base += 64; + } + return outpos; +} + +size_t bitset_extract_intersection_setbits_uint16(const uint64_t * __restrict__ words1, + const uint64_t * __restrict__ words2, + size_t length, uint16_t *out, + uint16_t base) { + int outpos = 0; + for (size_t i = 0; i < length; ++i) { + uint64_t w = words1[i] & words2[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + out[outpos++] = r + base; + w ^= t; + } + base += 64; + } + return outpos; +} + +#ifdef CROARING_IS_X64 +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out" as 16-bit integers, values start at "base" (can + *be set to zero). + * + * The "out" pointer should be sufficient to store the actual number of bits + *set. + * + * Returns how many values were actually decoded. + * + * This function uses SSE decoding. + */ +CROARING_TARGET_AVX2 +size_t bitset_extract_setbits_sse_uint16(const uint64_t *words, size_t length, + uint16_t *out, size_t outcapacity, + uint16_t base) { + uint16_t *initout = out; + __m128i baseVec = _mm_set1_epi16(base - 1); + __m128i incVec = _mm_set1_epi16(64); + __m128i add8 = _mm_set1_epi16(8); + uint16_t *safeout = out + outcapacity; + const int numberofbytes = 2; // process two bytes at a time + size_t i = 0; + for (; (i < length) && (out + numberofbytes * 8 <= safeout); ++i) { + uint64_t w = words[i]; + if (w == 0) { + baseVec = _mm_add_epi16(baseVec, incVec); + } else { + for (int k = 0; k < 4; ++k) { + uint8_t byteA = (uint8_t)w; + uint8_t byteB = (uint8_t)(w >> 8); + w >>= 16; + __m128i vecA = _mm_load_si128( + (const __m128i *)vecDecodeTable_uint16[byteA]); + __m128i vecB = _mm_load_si128( + (const __m128i *)vecDecodeTable_uint16[byteB]); + uint8_t advanceA = lengthTable[byteA]; + uint8_t advanceB = lengthTable[byteB]; + vecA = _mm_add_epi16(baseVec, vecA); + baseVec = _mm_add_epi16(baseVec, add8); + vecB = _mm_add_epi16(baseVec, vecB); + baseVec = _mm_add_epi16(baseVec, add8); + _mm_storeu_si128((__m128i *)out, vecA); + out += advanceA; + _mm_storeu_si128((__m128i *)out, vecB); + out += advanceB; + } + } + } + base += (uint16_t)(i * 64); + for (; (i < length) && (out < safeout); ++i) { + uint64_t w = words[i]; + while ((w != 0) && (out < safeout)) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + *out = r + base; + out++; + w ^= t; + } + base += 64; + } + return out - initout; +} +CROARING_UNTARGET_REGION +#endif + +/* + * Given a bitset containing "length" 64-bit words, write out the position + * of all the set bits to "out", values start at "base" (can be set to zero). + * + * The "out" pointer should be sufficient to store the actual number of bits + *set. + * + * Returns how many values were actually decoded. + */ +size_t bitset_extract_setbits_uint16(const uint64_t *words, size_t length, + uint16_t *out, uint16_t base) { + int outpos = 0; + for (size_t i = 0; i < length; ++i) { + uint64_t w = words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + out[outpos++] = r + base; + w ^= t; + } + base += 64; + } + return outpos; +} + +#if defined(CROARING_ASMBITMANIPOPTIMIZATION) && defined(CROARING_IS_X64) + +static inline uint64_t _asm_bitset_set_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length) { + uint64_t offset, load, pos; + uint64_t shift = 6; + const uint16_t *end = list + length; + if (!length) return card; + // TODO: could unroll for performance, see bitset_set_list + // bts is not available as an intrinsic in GCC + __asm volatile( + "1:\n" + "movzwq (%[list]), %[pos]\n" + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)\n" + "sbb $-1, %[card]\n" + "add $2, %[list]\n" + "cmp %[list], %[end]\n" + "jnz 1b" + : [card] "+&r"(card), [list] "+&r"(list), [load] "=&r"(load), + [pos] "=&r"(pos), [offset] "=&r"(offset) + : [end] "r"(end), [words] "r"(words), [shift] "r"(shift)); + return card; +} + +static inline void _asm_bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length) { + uint64_t pos; + const uint16_t *end = list + length; + + uint64_t shift = 6; + uint64_t offset; + uint64_t load; + for (; list + 3 < end; list += 4) { + pos = list[0]; + __asm volatile( + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)" + : [load] "=&r"(load), [offset] "=&r"(offset) + : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos)); + pos = list[1]; + __asm volatile( + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)" + : [load] "=&r"(load), [offset] "=&r"(offset) + : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos)); + pos = list[2]; + __asm volatile( + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)" + : [load] "=&r"(load), [offset] "=&r"(offset) + : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos)); + pos = list[3]; + __asm volatile( + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)" + : [load] "=&r"(load), [offset] "=&r"(offset) + : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos)); + } + + while (list != end) { + pos = list[0]; + __asm volatile( + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "bts %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)" + : [load] "=&r"(load), [offset] "=&r"(offset) + : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos)); + list++; + } +} + +static inline uint64_t _asm_bitset_clear_list(uint64_t *words, uint64_t card, const uint16_t *list, + uint64_t length) { + uint64_t offset, load, pos; + uint64_t shift = 6; + const uint16_t *end = list + length; + if (!length) return card; + // btr is not available as an intrinsic in GCC + __asm volatile( + "1:\n" + "movzwq (%[list]), %[pos]\n" + "shrx %[shift], %[pos], %[offset]\n" + "mov (%[words],%[offset],8), %[load]\n" + "btr %[pos], %[load]\n" + "mov %[load], (%[words],%[offset],8)\n" + "sbb $0, %[card]\n" + "add $2, %[list]\n" + "cmp %[list], %[end]\n" + "jnz 1b" + : [card] "+&r"(card), [list] "+&r"(list), [load] "=&r"(load), + [pos] "=&r"(pos), [offset] "=&r"(offset) + : [end] "r"(end), [words] "r"(words), [shift] "r"(shift) + : + /* clobbers */ "memory"); + return card; +} + +static inline uint64_t _scalar_bitset_clear_list(uint64_t *words, uint64_t card, const uint16_t *list, + uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *(const uint16_t *)list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load & ~(UINT64_C(1) << index); + card -= (load ^ newload) >> index; + words[offset] = newload; + list++; + } + return card; +} + +static inline uint64_t _scalar_bitset_set_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load | (UINT64_C(1) << index); + card += (load ^ newload) >> index; + words[offset] = newload; + list++; + } + return card; +} + +static inline void _scalar_bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load | (UINT64_C(1) << index); + words[offset] = newload; + list++; + } +} + +uint64_t bitset_clear_list(uint64_t *words, uint64_t card, const uint16_t *list, + uint64_t length) { + if( croaring_avx2() ) { + return _asm_bitset_clear_list(words, card, list, length); + } else { + return _scalar_bitset_clear_list(words, card, list, length); + } +} + +uint64_t bitset_set_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length) { + if( croaring_avx2() ) { + return _asm_bitset_set_list_withcard(words, card, list, length); + } else { + return _scalar_bitset_set_list_withcard(words, card, list, length); + } +} + +void bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length) { + if( croaring_avx2() ) { + _asm_bitset_set_list(words, list, length); + } else { + _scalar_bitset_set_list(words, list, length); + } +} +#else +uint64_t bitset_clear_list(uint64_t *words, uint64_t card, const uint16_t *list, + uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *(const uint16_t *)list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load & ~(UINT64_C(1) << index); + card -= (load ^ newload) >> index; + words[offset] = newload; + list++; + } + return card; +} + +uint64_t bitset_set_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load | (UINT64_C(1) << index); + card += (load ^ newload) >> index; + words[offset] = newload; + list++; + } + return card; +} + +void bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load | (UINT64_C(1) << index); + words[offset] = newload; + list++; + } +} + +#endif + +/* flip specified bits */ +/* TODO: consider whether worthwhile to make an asm version */ + +uint64_t bitset_flip_list_withcard(uint64_t *words, uint64_t card, + const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load ^ (UINT64_C(1) << index); + // todo: is a branch here all that bad? + card += + (1 - 2 * (((UINT64_C(1) << index) & load) >> index)); // +1 or -1 + words[offset] = newload; + list++; + } + return card; +} + +void bitset_flip_list(uint64_t *words, const uint16_t *list, uint64_t length) { + uint64_t offset, load, newload, pos, index; + const uint16_t *end = list + length; + while (list != end) { + pos = *list; + offset = pos >> 6; + index = pos % 64; + load = words[offset]; + newload = load ^ (UINT64_C(1) << index); + words[offset] = newload; + list++; + } +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/bitset_util.c */ +/* begin file src/containers/array.c */ +/* + * array.c + * + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +extern inline uint16_t array_container_minimum(const array_container_t *arr); +extern inline uint16_t array_container_maximum(const array_container_t *arr); +extern inline int array_container_index_equalorlarger(const array_container_t *arr, uint16_t x); + +extern inline int array_container_rank(const array_container_t *arr, + uint16_t x); +extern inline bool array_container_contains(const array_container_t *arr, + uint16_t pos); +extern inline int array_container_cardinality(const array_container_t *array); +extern inline bool array_container_nonzero_cardinality(const array_container_t *array); +extern inline void array_container_clear(array_container_t *array); +extern inline int32_t array_container_serialized_size_in_bytes(int32_t card); +extern inline bool array_container_empty(const array_container_t *array); +extern inline bool array_container_full(const array_container_t *array); + +/* Create a new array with capacity size. Return NULL in case of failure. */ +array_container_t *array_container_create_given_capacity(int32_t size) { + array_container_t *container; + + if ((container = (array_container_t *)roaring_malloc(sizeof(array_container_t))) == + NULL) { + return NULL; + } + + if( size <= 0 ) { // we don't want to rely on malloc(0) + container->array = NULL; + } else if ((container->array = (uint16_t *)roaring_malloc(sizeof(uint16_t) * size)) == + NULL) { + roaring_free(container); + return NULL; + } + + container->capacity = size; + container->cardinality = 0; + + return container; +} + +/* Create a new array. Return NULL in case of failure. */ +array_container_t *array_container_create() { + return array_container_create_given_capacity(ARRAY_DEFAULT_INIT_SIZE); +} + +/* Create a new array containing all values in [min,max). */ +array_container_t * array_container_create_range(uint32_t min, uint32_t max) { + array_container_t * answer = array_container_create_given_capacity(max - min + 1); + if(answer == NULL) return answer; + answer->cardinality = 0; + for(uint32_t k = min; k < max; k++) { + answer->array[answer->cardinality++] = k; + } + return answer; +} + +/* Duplicate container */ +array_container_t *array_container_clone(const array_container_t *src) { + array_container_t *newcontainer = + array_container_create_given_capacity(src->capacity); + if (newcontainer == NULL) return NULL; + + newcontainer->cardinality = src->cardinality; + + memcpy(newcontainer->array, src->array, + src->cardinality * sizeof(uint16_t)); + + return newcontainer; +} + +void array_container_offset(const array_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset) { + array_container_t *lo = NULL, *hi = NULL; + int top, lo_cap, hi_cap; + + top = (1 << 16) - offset; + + lo_cap = count_less(c->array, c->cardinality, top); + if (loc && lo_cap) { + lo = array_container_create_given_capacity(lo_cap); + for (int i = 0; i < lo_cap; ++i) { + array_container_add(lo, c->array[i] + offset); + } + *loc = (container_t*)lo; + } + + hi_cap = c->cardinality - lo_cap; + if (hic && hi_cap) { + hi = array_container_create_given_capacity(hi_cap); + for (int i = lo_cap; i < c->cardinality; ++i) { + array_container_add(hi, c->array[i] + offset); + } + *hic = (container_t*)hi; + } +} + +int array_container_shrink_to_fit(array_container_t *src) { + if (src->cardinality == src->capacity) return 0; // nothing to do + int savings = src->capacity - src->cardinality; + src->capacity = src->cardinality; + if( src->capacity == 0) { // we do not want to rely on realloc for zero allocs + roaring_free(src->array); + src->array = NULL; + } else { + uint16_t *oldarray = src->array; + src->array = + (uint16_t *)roaring_realloc(oldarray, src->capacity * sizeof(uint16_t)); + if (src->array == NULL) roaring_free(oldarray); // should never happen? + } + return savings; +} + +/* Free memory. */ +void array_container_free(array_container_t *arr) { + if(arr->array != NULL) {// Jon Strabala reports that some tools complain otherwise + roaring_free(arr->array); + arr->array = NULL; // pedantic + } + roaring_free(arr); +} + +static inline int32_t grow_capacity(int32_t capacity) { + return (capacity <= 0) ? ARRAY_DEFAULT_INIT_SIZE + : capacity < 64 ? capacity * 2 + : capacity < 1024 ? capacity * 3 / 2 + : capacity * 5 / 4; +} + +static inline int32_t clamp(int32_t val, int32_t min, int32_t max) { + return ((val < min) ? min : (val > max) ? max : val); +} + +void array_container_grow(array_container_t *container, int32_t min, + bool preserve) { + + int32_t max = (min <= DEFAULT_MAX_SIZE ? DEFAULT_MAX_SIZE : 65536); + int32_t new_capacity = clamp(grow_capacity(container->capacity), min, max); + + container->capacity = new_capacity; + uint16_t *array = container->array; + + if (preserve) { + container->array = + (uint16_t *)roaring_realloc(array, new_capacity * sizeof(uint16_t)); + if (container->array == NULL) roaring_free(array); + } else { + // Jon Strabala reports that some tools complain otherwise + if (array != NULL) { + roaring_free(array); + } + container->array = (uint16_t *)roaring_malloc(new_capacity * sizeof(uint16_t)); + } + + // handle the case where realloc fails + if (container->array == NULL) { + fprintf(stderr, "could not allocate memory\n"); + } + assert(container->array != NULL); +} + +/* Copy one container into another. We assume that they are distinct. */ +void array_container_copy(const array_container_t *src, + array_container_t *dst) { + const int32_t cardinality = src->cardinality; + if (cardinality > dst->capacity) { + array_container_grow(dst, cardinality, false); + } + + dst->cardinality = cardinality; + memcpy(dst->array, src->array, cardinality * sizeof(uint16_t)); +} + +void array_container_add_from_range(array_container_t *arr, uint32_t min, + uint32_t max, uint16_t step) { + for (uint32_t value = min; value < max; value += step) { + array_container_append(arr, value); + } +} + +/* Computes the union of array1 and array2 and write the result to arrayout. + * It is assumed that arrayout is distinct from both array1 and array2. + */ +void array_container_union(const array_container_t *array_1, + const array_container_t *array_2, + array_container_t *out) { + const int32_t card_1 = array_1->cardinality, card_2 = array_2->cardinality; + const int32_t max_cardinality = card_1 + card_2; + + if (out->capacity < max_cardinality) { + array_container_grow(out, max_cardinality, false); + } + out->cardinality = (int32_t)fast_union_uint16(array_1->array, card_1, + array_2->array, card_2, out->array); + +} + +/* Computes the difference of array1 and array2 and write the result + * to array out. + * Array out does not need to be distinct from array_1 + */ +void array_container_andnot(const array_container_t *array_1, + const array_container_t *array_2, + array_container_t *out) { + if (out->capacity < array_1->cardinality) + array_container_grow(out, array_1->cardinality, false); +#ifdef CROARING_IS_X64 + if(( croaring_avx2() ) && (out != array_1) && (out != array_2)) { + out->cardinality = + difference_vector16(array_1->array, array_1->cardinality, + array_2->array, array_2->cardinality, out->array); + } else { + out->cardinality = + difference_uint16(array_1->array, array_1->cardinality, array_2->array, + array_2->cardinality, out->array); + } +#else + out->cardinality = + difference_uint16(array_1->array, array_1->cardinality, array_2->array, + array_2->cardinality, out->array); +#endif +} + +/* Computes the symmetric difference of array1 and array2 and write the + * result + * to arrayout. + * It is assumed that arrayout is distinct from both array1 and array2. + */ +void array_container_xor(const array_container_t *array_1, + const array_container_t *array_2, + array_container_t *out) { + const int32_t card_1 = array_1->cardinality, card_2 = array_2->cardinality; + const int32_t max_cardinality = card_1 + card_2; + if (out->capacity < max_cardinality) { + array_container_grow(out, max_cardinality, false); + } + +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + out->cardinality = + xor_vector16(array_1->array, array_1->cardinality, array_2->array, + array_2->cardinality, out->array); + } else { + out->cardinality = + xor_uint16(array_1->array, array_1->cardinality, array_2->array, + array_2->cardinality, out->array); + } +#else + out->cardinality = + xor_uint16(array_1->array, array_1->cardinality, array_2->array, + array_2->cardinality, out->array); +#endif +} + +static inline int32_t minimum_int32(int32_t a, int32_t b) { + return (a < b) ? a : b; +} + +/* computes the intersection of array1 and array2 and write the result to + * arrayout. + * It is assumed that arrayout is distinct from both array1 and array2. + * */ +void array_container_intersection(const array_container_t *array1, + const array_container_t *array2, + array_container_t *out) { + int32_t card_1 = array1->cardinality, card_2 = array2->cardinality, + min_card = minimum_int32(card_1, card_2); + const int threshold = 64; // subject to tuning +#ifdef CROARING_IS_X64 + if (out->capacity < min_card) { + array_container_grow(out, min_card + sizeof(__m128i) / sizeof(uint16_t), + false); + } +#else + if (out->capacity < min_card) { + array_container_grow(out, min_card, false); + } +#endif + + if (card_1 * threshold < card_2) { + out->cardinality = intersect_skewed_uint16( + array1->array, card_1, array2->array, card_2, out->array); + } else if (card_2 * threshold < card_1) { + out->cardinality = intersect_skewed_uint16( + array2->array, card_2, array1->array, card_1, out->array); + } else { +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + out->cardinality = intersect_vector16( + array1->array, card_1, array2->array, card_2, out->array); + } else { + out->cardinality = intersect_uint16(array1->array, card_1, + array2->array, card_2, out->array); + } +#else + out->cardinality = intersect_uint16(array1->array, card_1, + array2->array, card_2, out->array); +#endif + } +} + +/* computes the size of the intersection of array1 and array2 + * */ +int array_container_intersection_cardinality(const array_container_t *array1, + const array_container_t *array2) { + int32_t card_1 = array1->cardinality, card_2 = array2->cardinality; + const int threshold = 64; // subject to tuning + if (card_1 * threshold < card_2) { + return intersect_skewed_uint16_cardinality(array1->array, card_1, + array2->array, card_2); + } else if (card_2 * threshold < card_1) { + return intersect_skewed_uint16_cardinality(array2->array, card_2, + array1->array, card_1); + } else { +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + return intersect_vector16_cardinality(array1->array, card_1, + array2->array, card_2); + } else { + return intersect_uint16_cardinality(array1->array, card_1, + array2->array, card_2); + } +#else + return intersect_uint16_cardinality(array1->array, card_1, + array2->array, card_2); +#endif + } +} + +bool array_container_intersect(const array_container_t *array1, + const array_container_t *array2) { + int32_t card_1 = array1->cardinality, card_2 = array2->cardinality; + const int threshold = 64; // subject to tuning + if (card_1 * threshold < card_2) { + return intersect_skewed_uint16_nonempty( + array1->array, card_1, array2->array, card_2); + } else if (card_2 * threshold < card_1) { + return intersect_skewed_uint16_nonempty( + array2->array, card_2, array1->array, card_1); + } else { + // we do not bother vectorizing + return intersect_uint16_nonempty(array1->array, card_1, + array2->array, card_2); + } +} + +/* computes the intersection of array1 and array2 and write the result to + * array1. + * */ +void array_container_intersection_inplace(array_container_t *src_1, + const array_container_t *src_2) { + // todo: can any of this be vectorized? + int32_t card_1 = src_1->cardinality, card_2 = src_2->cardinality; + const int threshold = 64; // subject to tuning + if (card_1 * threshold < card_2) { + src_1->cardinality = intersect_skewed_uint16( + src_1->array, card_1, src_2->array, card_2, src_1->array); + } else if (card_2 * threshold < card_1) { + src_1->cardinality = intersect_skewed_uint16( + src_2->array, card_2, src_1->array, card_1, src_1->array); + } else { + src_1->cardinality = intersect_uint16( + src_1->array, card_1, src_2->array, card_2, src_1->array); + } +} + +int array_container_to_uint32_array(void *vout, const array_container_t *cont, + uint32_t base) { + int outpos = 0; + uint32_t *out = (uint32_t *)vout; + for (int i = 0; i < cont->cardinality; ++i) { + const uint32_t val = base + cont->array[i]; + memcpy(out + outpos, &val, + sizeof(uint32_t)); // should be compiled as a MOV on x64 + outpos++; + } + return outpos; +} + +void array_container_printf(const array_container_t *v) { + if (v->cardinality == 0) { + printf("{}"); + return; + } + printf("{"); + printf("%d", v->array[0]); + for (int i = 1; i < v->cardinality; ++i) { + printf(",%d", v->array[i]); + } + printf("}"); +} + +void array_container_printf_as_uint32_array(const array_container_t *v, + uint32_t base) { + if (v->cardinality == 0) { + return; + } + printf("%u", v->array[0] + base); + for (int i = 1; i < v->cardinality; ++i) { + printf(",%u", v->array[i] + base); + } +} + +/* Compute the number of runs */ +int32_t array_container_number_of_runs(const array_container_t *ac) { + // Can SIMD work here? + int32_t nr_runs = 0; + int32_t prev = -2; + for (const uint16_t *p = ac->array; p != ac->array + ac->cardinality; ++p) { + if (*p != prev + 1) nr_runs++; + prev = *p; + } + return nr_runs; +} + +/** + * Writes the underlying array to buf, outputs how many bytes were written. + * The number of bytes written should be + * array_container_size_in_bytes(container). + * + */ +int32_t array_container_write(const array_container_t *container, char *buf) { + memcpy(buf, container->array, container->cardinality * sizeof(uint16_t)); + return array_container_size_in_bytes(container); +} + +bool array_container_is_subset(const array_container_t *container1, + const array_container_t *container2) { + if (container1->cardinality > container2->cardinality) { + return false; + } + int i1 = 0, i2 = 0; + while (i1 < container1->cardinality && i2 < container2->cardinality) { + if (container1->array[i1] == container2->array[i2]) { + i1++; + i2++; + } else if (container1->array[i1] > container2->array[i2]) { + i2++; + } else { // container1->array[i1] < container2->array[i2] + return false; + } + } + if (i1 == container1->cardinality) { + return true; + } else { + return false; + } +} + +int32_t array_container_read(int32_t cardinality, array_container_t *container, + const char *buf) { + if (container->capacity < cardinality) { + array_container_grow(container, cardinality, false); + } + container->cardinality = cardinality; + memcpy(container->array, buf, container->cardinality * sizeof(uint16_t)); + + return array_container_size_in_bytes(container); +} + +bool array_container_iterate(const array_container_t *cont, uint32_t base, + roaring_iterator iterator, void *ptr) { + for (int i = 0; i < cont->cardinality; i++) + if (!iterator(cont->array[i] + base, ptr)) return false; + return true; +} + +bool array_container_iterate64(const array_container_t *cont, uint32_t base, + roaring_iterator64 iterator, uint64_t high_bits, + void *ptr) { + for (int i = 0; i < cont->cardinality; i++) + if (!iterator(high_bits | (uint64_t)(cont->array[i] + base), ptr)) + return false; + return true; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/array.c */ +/* begin file src/containers/bitset.c */ +/* + * bitset.c + * + */ +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +extern inline int bitset_container_cardinality(const bitset_container_t *bitset); +extern inline bool bitset_container_nonzero_cardinality(bitset_container_t *bitset); +extern inline void bitset_container_set(bitset_container_t *bitset, uint16_t pos); +extern inline void bitset_container_unset(bitset_container_t *bitset, uint16_t pos); +extern inline bool bitset_container_get(const bitset_container_t *bitset, + uint16_t pos); +extern inline int32_t bitset_container_serialized_size_in_bytes(void); +extern inline bool bitset_container_add(bitset_container_t *bitset, uint16_t pos); +extern inline bool bitset_container_remove(bitset_container_t *bitset, uint16_t pos); +extern inline bool bitset_container_contains(const bitset_container_t *bitset, + uint16_t pos); + +void bitset_container_clear(bitset_container_t *bitset) { + memset(bitset->words, 0, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); + bitset->cardinality = 0; +} + +void bitset_container_set_all(bitset_container_t *bitset) { + memset(bitset->words, INT64_C(-1), + sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); + bitset->cardinality = (1 << 16); +} + + + +/* Create a new bitset. Return NULL in case of failure. */ +bitset_container_t *bitset_container_create(void) { + bitset_container_t *bitset = + (bitset_container_t *)roaring_malloc(sizeof(bitset_container_t)); + + if (!bitset) { + return NULL; + } + // sizeof(__m256i) == 32 + bitset->words = (uint64_t *)roaring_aligned_malloc( + 32, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); + if (!bitset->words) { + roaring_free(bitset); + return NULL; + } + bitset_container_clear(bitset); + return bitset; +} + +/* Copy one container into another. We assume that they are distinct. */ +void bitset_container_copy(const bitset_container_t *source, + bitset_container_t *dest) { + dest->cardinality = source->cardinality; + memcpy(dest->words, source->words, + sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); +} + +void bitset_container_add_from_range(bitset_container_t *bitset, uint32_t min, + uint32_t max, uint16_t step) { + if (step == 0) return; // refuse to crash + if ((64 % step) == 0) { // step divides 64 + uint64_t mask = 0; // construct the repeated mask + for (uint32_t value = (min % step); value < 64; value += step) { + mask |= ((uint64_t)1 << value); + } + uint32_t firstword = min / 64; + uint32_t endword = (max - 1) / 64; + bitset->cardinality = (max - min + step - 1) / step; + if (firstword == endword) { + bitset->words[firstword] |= + mask & (((~UINT64_C(0)) << (min % 64)) & + ((~UINT64_C(0)) >> ((~max + 1) % 64))); + return; + } + bitset->words[firstword] = mask & ((~UINT64_C(0)) << (min % 64)); + for (uint32_t i = firstword + 1; i < endword; i++) + bitset->words[i] = mask; + bitset->words[endword] = mask & ((~UINT64_C(0)) >> ((~max + 1) % 64)); + } else { + for (uint32_t value = min; value < max; value += step) { + bitset_container_add(bitset, value); + } + } +} + +/* Free memory. */ +void bitset_container_free(bitset_container_t *bitset) { + if(bitset->words != NULL) {// Jon Strabala reports that some tools complain otherwise + roaring_aligned_free(bitset->words); + bitset->words = NULL; // pedantic + } + roaring_free(bitset); +} + +/* duplicate container. */ +bitset_container_t *bitset_container_clone(const bitset_container_t *src) { + bitset_container_t *bitset = + (bitset_container_t *)roaring_malloc(sizeof(bitset_container_t)); + + if (!bitset) { + return NULL; + } + // sizeof(__m256i) == 32 + bitset->words = (uint64_t *)roaring_aligned_malloc( + 32, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); + if (!bitset->words) { + roaring_free(bitset); + return NULL; + } + bitset->cardinality = src->cardinality; + memcpy(bitset->words, src->words, + sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS); + return bitset; +} + +void bitset_container_offset(const bitset_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset) { + bitset_container_t *bc = NULL; + uint64_t val; + uint16_t b, i, end; + + b = offset >> 6; + i = offset % 64; + end = 1024 - b; + + if (loc != NULL) { + bc = bitset_container_create(); + if (i == 0) { + memcpy(bc->words+b, c->words, 8*end); + } else { + bc->words[b] = c->words[0] << i; + for (uint32_t k = 1; k < end; ++k) { + val = c->words[k] << i; + val |= c->words[k-1] >> (64 - i); + bc->words[b+k] = val; + } + } + + bc->cardinality = bitset_container_compute_cardinality(bc); + if (bc->cardinality != 0) { + *loc = bc; + } + if (bc->cardinality == c->cardinality) { + return; + } + } + + if (hic == NULL) { + // Both hic and loc can't be NULL, so bc is never NULL here + if (bc->cardinality == 0) { + bitset_container_free(bc); + } + return; + } + + if (bc == NULL || bc->cardinality != 0) { + bc = bitset_container_create(); + } + + if (i == 0) { + memcpy(bc->words, c->words+end, 8*b); + } else { + for (uint32_t k = end; k < 1024; ++k) { + val = c->words[k] << i; + val |= c->words[k-1] >> (64 - i); + bc->words[k-end] = val; + } + bc->words[b] = c->words[1023] >> (64 - i); + } + + bc->cardinality = bitset_container_compute_cardinality(bc); + if (bc->cardinality == 0) { + bitset_container_free(bc); + return; + } + *hic = bc; +} + +void bitset_container_set_range(bitset_container_t *bitset, uint32_t begin, + uint32_t end) { + bitset_set_range(bitset->words, begin, end); + bitset->cardinality = + bitset_container_compute_cardinality(bitset); // could be smarter +} + + +bool bitset_container_intersect(const bitset_container_t *src_1, + const bitset_container_t *src_2) { + // could vectorize, but this is probably already quite fast in practice + const uint64_t * __restrict__ words_1 = src_1->words; + const uint64_t * __restrict__ words_2 = src_2->words; + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i ++) { + if((words_1[i] & words_2[i]) != 0) return true; + } + return false; +} + + +#ifdef CROARING_IS_X64 +#ifndef WORDS_IN_AVX2_REG +#define WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t) +#endif +/* Get the number of bits set (force computation) */ +static inline int _scalar_bitset_container_compute_cardinality(const bitset_container_t *bitset) { + const uint64_t *words = bitset->words; + int32_t sum = 0; + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 4) { + sum += hamming(words[i]); + sum += hamming(words[i + 1]); + sum += hamming(words[i + 2]); + sum += hamming(words[i + 3]); + } + return sum; +} +/* Get the number of bits set (force computation) */ +int bitset_container_compute_cardinality(const bitset_container_t *bitset) { + if( croaring_avx2() ) { + return (int) avx2_harley_seal_popcount256( + (const __m256i *)bitset->words, + BITSET_CONTAINER_SIZE_IN_WORDS / (WORDS_IN_AVX2_REG)); + } else { + return _scalar_bitset_container_compute_cardinality(bitset); + + } +} + +#elif defined(USENEON) +int bitset_container_compute_cardinality(const bitset_container_t *bitset) { + uint16x8_t n0 = vdupq_n_u16(0); + uint16x8_t n1 = vdupq_n_u16(0); + uint16x8_t n2 = vdupq_n_u16(0); + uint16x8_t n3 = vdupq_n_u16(0); + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 8) { + uint64x2_t c0 = vld1q_u64(&bitset->words[i + 0]); + n0 = vaddq_u16(n0, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c0)))); + uint64x2_t c1 = vld1q_u64(&bitset->words[i + 2]); + n1 = vaddq_u16(n1, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c1)))); + uint64x2_t c2 = vld1q_u64(&bitset->words[i + 4]); + n2 = vaddq_u16(n2, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c2)))); + uint64x2_t c3 = vld1q_u64(&bitset->words[i + 6]); + n3 = vaddq_u16(n3, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c3)))); + } + uint64x2_t n = vdupq_n_u64(0); + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n0))); + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n1))); + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n2))); + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n3))); + return vgetq_lane_u64(n, 0) + vgetq_lane_u64(n, 1); +} + +#else // CROARING_IS_X64 + +/* Get the number of bits set (force computation) */ +int bitset_container_compute_cardinality(const bitset_container_t *bitset) { + const uint64_t *words = bitset->words; + int32_t sum = 0; + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 4) { + sum += hamming(words[i]); + sum += hamming(words[i + 1]); + sum += hamming(words[i + 2]); + sum += hamming(words[i + 3]); + } + return sum; +} + +#endif // CROARING_IS_X64 + +#ifdef CROARING_IS_X64 + +#define BITSET_CONTAINER_FN_REPEAT 8 +#ifndef WORDS_IN_AVX2_REG +#define WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t) +#endif // WORDS_IN_AVX2_REG +#define LOOP_SIZE \ + BITSET_CONTAINER_SIZE_IN_WORDS / \ + ((WORDS_IN_AVX2_REG)*BITSET_CONTAINER_FN_REPEAT) + +/* Computes a binary operation (eg union) on bitset1 and bitset2 and write the + result to bitsetout */ +// clang-format off +#define AVX_BITSET_CONTAINER_FN1(before, opname, opsymbol, avx_intrinsic, \ + neon_intrinsic, after) \ + static inline int _avx2_bitset_container_##opname##_nocard( \ + const bitset_container_t *src_1, const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint8_t *__restrict__ words_1 = (const uint8_t *)src_1->words; \ + const uint8_t *__restrict__ words_2 = (const uint8_t *)src_2->words; \ + /* not using the blocking optimization for some reason*/ \ + uint8_t *out = (uint8_t *)dst->words; \ + const int innerloop = 8; \ + for (size_t i = 0; \ + i < BITSET_CONTAINER_SIZE_IN_WORDS / (WORDS_IN_AVX2_REG); \ + i += innerloop) { \ + __m256i A1, A2, AO; \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)out, AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 32)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 32)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 32), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 64)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 64)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 64), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 96)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 96)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 96), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 128)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 128)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 128), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 160)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 160)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 160), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 192)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 192)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 192), AO); \ + A1 = _mm256_lddqu_si256((const __m256i *)(words_1 + 224)); \ + A2 = _mm256_lddqu_si256((const __m256i *)(words_2 + 224)); \ + AO = avx_intrinsic(A2, A1); \ + _mm256_storeu_si256((__m256i *)(out + 224), AO); \ + out += 256; \ + words_1 += 256; \ + words_2 += 256; \ + } \ + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; \ + return dst->cardinality; \ + } + +#define AVX_BITSET_CONTAINER_FN2(before, opname, opsymbol, avx_intrinsic, \ + neon_intrinsic, after) \ + /* next, a version that updates cardinality*/ \ + static inline int _avx2_bitset_container_##opname(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const __m256i *__restrict__ words_1 = (const __m256i *)src_1->words; \ + const __m256i *__restrict__ words_2 = (const __m256i *)src_2->words; \ + __m256i *out = (__m256i *)dst->words; \ + dst->cardinality = (int32_t)avx2_harley_seal_popcount256andstore_##opname( \ + words_2, words_1, out, \ + BITSET_CONTAINER_SIZE_IN_WORDS / (WORDS_IN_AVX2_REG)); \ + return dst->cardinality; \ + } \ + +#define AVX_BITSET_CONTAINER_FN3(before, opname, opsymbol, avx_intrinsic, \ + neon_intrinsic, after) \ + /* next, a version that just computes the cardinality*/ \ + static inline int _avx2_bitset_container_##opname##_justcard( \ + const bitset_container_t *src_1, const bitset_container_t *src_2) { \ + const __m256i *__restrict__ data1 = (const __m256i *)src_1->words; \ + const __m256i *__restrict__ data2 = (const __m256i *)src_2->words; \ + return (int)avx2_harley_seal_popcount256_##opname( \ + data2, data1, BITSET_CONTAINER_SIZE_IN_WORDS / (WORDS_IN_AVX2_REG)); \ + } + + +// we duplicate the function because other containers use the "or" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, or, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, union, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +// we duplicate the function because other containers use the "intersection" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, and, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, intersection, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, xor, ^, _mm256_xor_si256, veorq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN1(CROARING_TARGET_AVX2, andnot, &~, _mm256_andnot_si256, vbicq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +// we duplicate the function because other containers use the "or" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, or, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, union, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +// we duplicate the function because other containers use the "intersection" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, and, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, intersection, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, xor, ^, _mm256_xor_si256, veorq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN2(CROARING_TARGET_AVX2, andnot, &~, _mm256_andnot_si256, vbicq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +// we duplicate the function because other containers use the "or" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, or, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, union, |, _mm256_or_si256, vorrq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +// we duplicate the function because other containers use the "intersection" term, makes API more consistent +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, and, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, intersection, &, _mm256_and_si256, vandq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, xor, ^, _mm256_xor_si256, veorq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION +CROARING_TARGET_AVX2 +AVX_BITSET_CONTAINER_FN3(CROARING_TARGET_AVX2, andnot, &~, _mm256_andnot_si256, vbicq_u64, CROARING_UNTARGET_REGION) +CROARING_UNTARGET_REGION + + +#define SCALAR_BITSET_CONTAINER_FN(opname, opsymbol, avx_intrinsic, \ + neon_intrinsic) \ + static inline int _scalar_bitset_container_##opname(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t *__restrict__ words_1 = src_1->words; \ + const uint64_t *__restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + int32_t sum = 0; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 2) { \ + const uint64_t word_1 = (words_1[i])opsymbol(words_2[i]), \ + word_2 = (words_1[i + 1]) opsymbol(words_2[i + 1]); \ + out[i] = word_1; \ + out[i + 1] = word_2; \ + sum += hamming(word_1); \ + sum += hamming(word_2); \ + } \ + dst->cardinality = sum; \ + return dst->cardinality; \ + } \ + static inline int _scalar_bitset_container_##opname##_nocard( \ + const bitset_container_t *src_1, const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t *__restrict__ words_1 = src_1->words; \ + const uint64_t *__restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i++) { \ + out[i] = (words_1[i])opsymbol(words_2[i]); \ + } \ + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; \ + return dst->cardinality; \ + } \ + static inline int _scalar_bitset_container_##opname##_justcard( \ + const bitset_container_t *src_1, const bitset_container_t *src_2) { \ + const uint64_t *__restrict__ words_1 = src_1->words; \ + const uint64_t *__restrict__ words_2 = src_2->words; \ + int32_t sum = 0; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 2) { \ + const uint64_t word_1 = (words_1[i])opsymbol(words_2[i]), \ + word_2 = (words_1[i + 1]) opsymbol(words_2[i + 1]); \ + sum += hamming(word_1); \ + sum += hamming(word_2); \ + } \ + return sum; \ + } + +// we duplicate the function because other containers use the "or" term, makes API more consistent +SCALAR_BITSET_CONTAINER_FN(or, |, _mm256_or_si256, vorrq_u64) +SCALAR_BITSET_CONTAINER_FN(union, |, _mm256_or_si256, vorrq_u64) + +// we duplicate the function because other containers use the "intersection" term, makes API more consistent +SCALAR_BITSET_CONTAINER_FN(and, &, _mm256_and_si256, vandq_u64) +SCALAR_BITSET_CONTAINER_FN(intersection, &, _mm256_and_si256, vandq_u64) + +SCALAR_BITSET_CONTAINER_FN(xor, ^, _mm256_xor_si256, veorq_u64) +SCALAR_BITSET_CONTAINER_FN(andnot, &~, _mm256_andnot_si256, vbicq_u64) + + +#define BITSET_CONTAINER_FN(opname, opsymbol, avx_intrinsic, neon_intrinsic) \ + int bitset_container_##opname(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + if ( croaring_avx2() ) { \ + return _avx2_bitset_container_##opname(src_1, src_2, dst); \ + } else { \ + return _scalar_bitset_container_##opname(src_1, src_2, dst); \ + } \ + } \ + int bitset_container_##opname##_nocard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + if ( croaring_avx2() ) { \ + return _avx2_bitset_container_##opname##_nocard(src_1, src_2, dst); \ + } else { \ + return _scalar_bitset_container_##opname##_nocard(src_1, src_2, dst); \ + } \ + } \ + int bitset_container_##opname##_justcard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2) { \ + if ((croaring_detect_supported_architectures() & CROARING_AVX2) == \ + CROARING_AVX2) { \ + return _avx2_bitset_container_##opname##_justcard(src_1, src_2); \ + } else { \ + return _scalar_bitset_container_##opname##_justcard(src_1, src_2); \ + } \ + } + + + +#elif defined(USENEON) + +#define BITSET_CONTAINER_FN(opname, opsymbol, avx_intrinsic, neon_intrinsic) \ +int bitset_container_##opname(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + uint16x8_t n0 = vdupq_n_u16(0); \ + uint16x8_t n1 = vdupq_n_u16(0); \ + uint16x8_t n2 = vdupq_n_u16(0); \ + uint16x8_t n3 = vdupq_n_u16(0); \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 8) { \ + uint64x2_t c0 = neon_intrinsic(vld1q_u64(&words_1[i + 0]), \ + vld1q_u64(&words_2[i + 0])); \ + n0 = vaddq_u16(n0, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c0)))); \ + vst1q_u64(&out[i + 0], c0); \ + uint64x2_t c1 = neon_intrinsic(vld1q_u64(&words_1[i + 2]), \ + vld1q_u64(&words_2[i + 2])); \ + n1 = vaddq_u16(n1, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c1)))); \ + vst1q_u64(&out[i + 2], c1); \ + uint64x2_t c2 = neon_intrinsic(vld1q_u64(&words_1[i + 4]), \ + vld1q_u64(&words_2[i + 4])); \ + n2 = vaddq_u16(n2, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c2)))); \ + vst1q_u64(&out[i + 4], c2); \ + uint64x2_t c3 = neon_intrinsic(vld1q_u64(&words_1[i + 6]), \ + vld1q_u64(&words_2[i + 6])); \ + n3 = vaddq_u16(n3, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c3)))); \ + vst1q_u64(&out[i + 6], c3); \ + } \ + uint64x2_t n = vdupq_n_u64(0); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n0))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n1))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n2))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n3))); \ + dst->cardinality = vgetq_lane_u64(n, 0) + vgetq_lane_u64(n, 1); \ + return dst->cardinality; \ +} \ +int bitset_container_##opname##_nocard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 8) { \ + vst1q_u64(&out[i + 0], neon_intrinsic(vld1q_u64(&words_1[i + 0]), \ + vld1q_u64(&words_2[i + 0]))); \ + vst1q_u64(&out[i + 2], neon_intrinsic(vld1q_u64(&words_1[i + 2]), \ + vld1q_u64(&words_2[i + 2]))); \ + vst1q_u64(&out[i + 4], neon_intrinsic(vld1q_u64(&words_1[i + 4]), \ + vld1q_u64(&words_2[i + 4]))); \ + vst1q_u64(&out[i + 6], neon_intrinsic(vld1q_u64(&words_1[i + 6]), \ + vld1q_u64(&words_2[i + 6]))); \ + } \ + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; \ + return dst->cardinality; \ +} \ +int bitset_container_##opname##_justcard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + uint16x8_t n0 = vdupq_n_u16(0); \ + uint16x8_t n1 = vdupq_n_u16(0); \ + uint16x8_t n2 = vdupq_n_u16(0); \ + uint16x8_t n3 = vdupq_n_u16(0); \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 8) { \ + uint64x2_t c0 = neon_intrinsic(vld1q_u64(&words_1[i + 0]), \ + vld1q_u64(&words_2[i + 0])); \ + n0 = vaddq_u16(n0, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c0)))); \ + uint64x2_t c1 = neon_intrinsic(vld1q_u64(&words_1[i + 2]), \ + vld1q_u64(&words_2[i + 2])); \ + n1 = vaddq_u16(n1, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c1)))); \ + uint64x2_t c2 = neon_intrinsic(vld1q_u64(&words_1[i + 4]), \ + vld1q_u64(&words_2[i + 4])); \ + n2 = vaddq_u16(n2, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c2)))); \ + uint64x2_t c3 = neon_intrinsic(vld1q_u64(&words_1[i + 6]), \ + vld1q_u64(&words_2[i + 6])); \ + n3 = vaddq_u16(n3, vpaddlq_u8(vcntq_u8(vreinterpretq_u8_u64(c3)))); \ + } \ + uint64x2_t n = vdupq_n_u64(0); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n0))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n1))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n2))); \ + n = vaddq_u64(n, vpaddlq_u32(vpaddlq_u16(n3))); \ + return vgetq_lane_u64(n, 0) + vgetq_lane_u64(n, 1); \ +} + +#else + +#define BITSET_CONTAINER_FN(opname, opsymbol, avx_intrinsic, neon_intrinsic) \ +int bitset_container_##opname(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + int32_t sum = 0; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 2) { \ + const uint64_t word_1 = (words_1[i])opsymbol(words_2[i]), \ + word_2 = (words_1[i + 1])opsymbol(words_2[i + 1]); \ + out[i] = word_1; \ + out[i + 1] = word_2; \ + sum += hamming(word_1); \ + sum += hamming(word_2); \ + } \ + dst->cardinality = sum; \ + return dst->cardinality; \ +} \ +int bitset_container_##opname##_nocard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2, \ + bitset_container_t *dst) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + uint64_t *out = dst->words; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i++) { \ + out[i] = (words_1[i])opsymbol(words_2[i]); \ + } \ + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; \ + return dst->cardinality; \ +} \ +int bitset_container_##opname##_justcard(const bitset_container_t *src_1, \ + const bitset_container_t *src_2) { \ + const uint64_t * __restrict__ words_1 = src_1->words; \ + const uint64_t * __restrict__ words_2 = src_2->words; \ + int32_t sum = 0; \ + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 2) { \ + const uint64_t word_1 = (words_1[i])opsymbol(words_2[i]), \ + word_2 = (words_1[i + 1])opsymbol(words_2[i + 1]); \ + sum += hamming(word_1); \ + sum += hamming(word_2); \ + } \ + return sum; \ +} + +#endif // CROARING_IS_X64 + +// we duplicate the function because other containers use the "or" term, makes API more consistent +BITSET_CONTAINER_FN(or, |, _mm256_or_si256, vorrq_u64) +BITSET_CONTAINER_FN(union, |, _mm256_or_si256, vorrq_u64) + +// we duplicate the function because other containers use the "intersection" term, makes API more consistent +BITSET_CONTAINER_FN(and, &, _mm256_and_si256, vandq_u64) +BITSET_CONTAINER_FN(intersection, &, _mm256_and_si256, vandq_u64) + +BITSET_CONTAINER_FN(xor, ^, _mm256_xor_si256, veorq_u64) +BITSET_CONTAINER_FN(andnot, &~, _mm256_andnot_si256, vbicq_u64) +// clang-format On + + +int bitset_container_to_uint32_array( + uint32_t *out, + const bitset_container_t *bc, + uint32_t base +){ +#ifdef CROARING_IS_X64 + if(( croaring_avx2() ) && (bc->cardinality >= 8192)) // heuristic + return (int) bitset_extract_setbits_avx2(bc->words, + BITSET_CONTAINER_SIZE_IN_WORDS, out, bc->cardinality, base); + else + return (int) bitset_extract_setbits(bc->words, + BITSET_CONTAINER_SIZE_IN_WORDS, out, base); +#else + return (int) bitset_extract_setbits(bc->words, + BITSET_CONTAINER_SIZE_IN_WORDS, out, base); +#endif +} + +/* + * Print this container using printf (useful for debugging). + */ +void bitset_container_printf(const bitset_container_t * v) { + printf("{"); + uint32_t base = 0; + bool iamfirst = true;// TODO: rework so that this is not necessary yet still readable + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) { + uint64_t w = v->words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + if(iamfirst) {// predicted to be false + printf("%u",base + r); + iamfirst = false; + } else { + printf(",%u",base + r); + } + w ^= t; + } + base += 64; + } + printf("}"); +} + + +/* + * Print this container using printf as a comma-separated list of 32-bit integers starting at base. + */ +void bitset_container_printf_as_uint32_array(const bitset_container_t * v, uint32_t base) { + bool iamfirst = true;// TODO: rework so that this is not necessary yet still readable + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) { + uint64_t w = v->words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + if(iamfirst) {// predicted to be false + printf("%u", r + base); + iamfirst = false; + } else { + printf(",%u",r + base); + } + w ^= t; + } + base += 64; + } +} + + +// TODO: use the fast lower bound, also +int bitset_container_number_of_runs(bitset_container_t *bc) { + int num_runs = 0; + uint64_t next_word = bc->words[0]; + + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS-1; ++i) { + uint64_t word = next_word; + next_word = bc->words[i+1]; + num_runs += hamming((~word) & (word << 1)) + ( (word >> 63) & ~next_word); + } + + uint64_t word = next_word; + num_runs += hamming((~word) & (word << 1)); + if((word & 0x8000000000000000ULL) != 0) + num_runs++; + return num_runs; +} + + +int32_t bitset_container_write(const bitset_container_t *container, + char *buf) { + memcpy(buf, container->words, BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t)); + return bitset_container_size_in_bytes(container); +} + + +int32_t bitset_container_read(int32_t cardinality, bitset_container_t *container, + const char *buf) { + container->cardinality = cardinality; + memcpy(container->words, buf, BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t)); + return bitset_container_size_in_bytes(container); +} + +bool bitset_container_iterate(const bitset_container_t *cont, uint32_t base, roaring_iterator iterator, void *ptr) { + for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) { + uint64_t w = cont->words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + if(!iterator(r + base, ptr)) return false; + w ^= t; + } + base += 64; + } + return true; +} + +bool bitset_container_iterate64(const bitset_container_t *cont, uint32_t base, roaring_iterator64 iterator, uint64_t high_bits, void *ptr) { + for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) { + uint64_t w = cont->words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + if(!iterator(high_bits | (uint64_t)(r + base), ptr)) return false; + w ^= t; + } + base += 64; + } + return true; +} + +#ifdef CROARING_IS_X64 +CROARING_TARGET_AVX2 +static inline bool _avx2_bitset_container_equals(const bitset_container_t *container1, const bitset_container_t *container2) { + const __m256i *ptr1 = (const __m256i*)container1->words; + const __m256i *ptr2 = (const __m256i*)container2->words; + for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS*sizeof(uint64_t)/32; i++) { + __m256i r1 = _mm256_load_si256(ptr1+i); + __m256i r2 = _mm256_load_si256(ptr2+i); + int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(r1, r2)); + if ((uint32_t)mask != UINT32_MAX) { + return false; + } + } + return true; +} +CROARING_UNTARGET_REGION +#endif // CROARING_IS_X64 + +bool bitset_container_equals(const bitset_container_t *container1, const bitset_container_t *container2) { + if((container1->cardinality != BITSET_UNKNOWN_CARDINALITY) && (container2->cardinality != BITSET_UNKNOWN_CARDINALITY)) { + if(container1->cardinality != container2->cardinality) { + return false; + } + if (container1->cardinality == INT32_C(0x10000)) { + return true; + } + } +#ifdef CROARING_IS_X64 + if( croaring_avx2() ) { + return _avx2_bitset_container_equals(container1, container2); + } +#endif + return memcmp(container1->words, + container2->words, + BITSET_CONTAINER_SIZE_IN_WORDS*sizeof(uint64_t)) == 0; +} + +bool bitset_container_is_subset(const bitset_container_t *container1, + const bitset_container_t *container2) { + if((container1->cardinality != BITSET_UNKNOWN_CARDINALITY) && (container2->cardinality != BITSET_UNKNOWN_CARDINALITY)) { + if(container1->cardinality > container2->cardinality) { + return false; + } + } + for(int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) { + if((container1->words[i] & container2->words[i]) != container1->words[i]) { + return false; + } + } + return true; +} + +bool bitset_container_select(const bitset_container_t *container, uint32_t *start_rank, uint32_t rank, uint32_t *element) { + int card = bitset_container_cardinality(container); + if(rank >= *start_rank + card) { + *start_rank += card; + return false; + } + const uint64_t *words = container->words; + int32_t size; + for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i += 1) { + size = hamming(words[i]); + if(rank <= *start_rank + size) { + uint64_t w = container->words[i]; + uint16_t base = i*64; + while (w != 0) { + uint64_t t = w & (~w + 1); + int r = __builtin_ctzll(w); + if(*start_rank == rank) { + *element = r+base; + return true; + } + w ^= t; + *start_rank += 1; + } + } + else + *start_rank += size; + } + assert(false); + __builtin_unreachable(); +} + + +/* Returns the smallest value (assumes not empty) */ +uint16_t bitset_container_minimum(const bitset_container_t *container) { + for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) { + uint64_t w = container->words[i]; + if (w != 0) { + int r = __builtin_ctzll(w); + return r + i * 64; + } + } + return UINT16_MAX; +} + +/* Returns the largest value (assumes not empty) */ +uint16_t bitset_container_maximum(const bitset_container_t *container) { + for (int32_t i = BITSET_CONTAINER_SIZE_IN_WORDS - 1; i > 0; --i ) { + uint64_t w = container->words[i]; + if (w != 0) { + int r = __builtin_clzll(w); + return i * 64 + 63 - r; + } + } + return 0; +} + +/* Returns the number of values equal or smaller than x */ +int bitset_container_rank(const bitset_container_t *container, uint16_t x) { + // credit: aqrit + int sum = 0; + int i = 0; + for (int end = x / 64; i < end; i++){ + sum += hamming(container->words[i]); + } + uint64_t lastword = container->words[i]; + uint64_t lastpos = UINT64_C(1) << (x % 64); + uint64_t mask = lastpos + lastpos - 1; // smear right + sum += hamming(lastword & mask); + return sum; +} + +/* Returns the index of the first value equal or larger than x, or -1 */ +int bitset_container_index_equalorlarger(const bitset_container_t *container, uint16_t x) { + uint32_t x32 = x; + uint32_t k = x32 / 64; + uint64_t word = container->words[k]; + const int diff = x32 - k * 64; // in [0,64) + word = (word >> diff) << diff; // a mask is faster, but we don't care + while(word == 0) { + k++; + if(k == BITSET_CONTAINER_SIZE_IN_WORDS) return -1; + word = container->words[k]; + } + return k * 64 + __builtin_ctzll(word); +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/bitset.c */ +/* begin file src/containers/containers.c */ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +extern inline const container_t *container_unwrap_shared( + const container_t *candidate_shared_container, uint8_t *type); + +extern inline container_t *container_mutable_unwrap_shared( + container_t *candidate_shared_container, uint8_t *type); + +extern inline int container_get_cardinality( + const container_t *c, uint8_t typecode); + +extern inline container_t *container_iand( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_ior( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_ixor( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_iandnot( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +void container_free(container_t *c, uint8_t type) { + switch (type) { + case BITSET_CONTAINER_TYPE: + bitset_container_free(CAST_bitset(c)); + break; + case ARRAY_CONTAINER_TYPE: + array_container_free(CAST_array(c)); + break; + case RUN_CONTAINER_TYPE: + run_container_free(CAST_run(c)); + break; + case SHARED_CONTAINER_TYPE: + shared_container_free(CAST_shared(c)); + break; + default: + assert(false); + __builtin_unreachable(); + } +} + +void container_printf(const container_t *c, uint8_t type) { + c = container_unwrap_shared(c, &type); + switch (type) { + case BITSET_CONTAINER_TYPE: + bitset_container_printf(const_CAST_bitset(c)); + return; + case ARRAY_CONTAINER_TYPE: + array_container_printf(const_CAST_array(c)); + return; + case RUN_CONTAINER_TYPE: + run_container_printf(const_CAST_run(c)); + return; + default: + __builtin_unreachable(); + } +} + +void container_printf_as_uint32_array( + const container_t *c, uint8_t typecode, + uint32_t base +){ + c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + bitset_container_printf_as_uint32_array( + const_CAST_bitset(c), base); + return; + case ARRAY_CONTAINER_TYPE: + array_container_printf_as_uint32_array( + const_CAST_array(c), base); + return; + case RUN_CONTAINER_TYPE: + run_container_printf_as_uint32_array( + const_CAST_run(c), base); + return; + default: + __builtin_unreachable(); + } +} + +extern inline bool container_nonzero_cardinality( + const container_t *c, uint8_t typecode); + +extern inline int container_to_uint32_array( + uint32_t *output, + const container_t *c, uint8_t typecode, + uint32_t base); + +extern inline container_t *container_add( + container_t *c, + uint16_t val, + uint8_t typecode, // !!! 2nd arg? + uint8_t *new_typecode); + +extern inline bool container_contains( + const container_t *c, + uint16_t val, + uint8_t typecode); // !!! 2nd arg? + +extern inline container_t *container_and( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_or( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_xor( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +container_t *get_copy_of_container( + container_t *c, uint8_t *typecode, + bool copy_on_write +){ + if (copy_on_write) { + shared_container_t *shared_container; + if (*typecode == SHARED_CONTAINER_TYPE) { + shared_container = CAST_shared(c); + shared_container->counter += 1; + return shared_container; + } + assert(*typecode != SHARED_CONTAINER_TYPE); + + if ((shared_container = (shared_container_t *)roaring_malloc( + sizeof(shared_container_t))) == NULL) { + return NULL; + } + + shared_container->container = c; + shared_container->typecode = *typecode; + + shared_container->counter = 2; + *typecode = SHARED_CONTAINER_TYPE; + + return shared_container; + } // copy_on_write + // otherwise, no copy on write... + const container_t *actual_container = container_unwrap_shared(c, typecode); + assert(*typecode != SHARED_CONTAINER_TYPE); + return container_clone(actual_container, *typecode); +} + +/** + * Copies a container, requires a typecode. This allocates new memory, caller + * is responsible for deallocation. + */ +container_t *container_clone(const container_t *c, uint8_t typecode) { + // We do not want to allow cloning of shared containers. + // c = container_unwrap_shared(c, &typecode); + switch (typecode) { + case BITSET_CONTAINER_TYPE: + return bitset_container_clone(const_CAST_bitset(c)); + case ARRAY_CONTAINER_TYPE: + return array_container_clone(const_CAST_array(c)); + case RUN_CONTAINER_TYPE: + return run_container_clone(const_CAST_run(c)); + case SHARED_CONTAINER_TYPE: + // Shared containers are not cloneable. Are you mixing COW and non-COW bitmaps? + return NULL; + default: + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +container_t *shared_container_extract_copy( + shared_container_t *sc, uint8_t *typecode +){ + assert(sc->counter > 0); + assert(sc->typecode != SHARED_CONTAINER_TYPE); + sc->counter--; + *typecode = sc->typecode; + container_t *answer; + if (sc->counter == 0) { + answer = sc->container; + sc->container = NULL; // paranoid + roaring_free(sc); + } else { + answer = container_clone(sc->container, *typecode); + } + assert(*typecode != SHARED_CONTAINER_TYPE); + return answer; +} + +void shared_container_free(shared_container_t *container) { + assert(container->counter > 0); + container->counter--; + if (container->counter == 0) { + assert(container->typecode != SHARED_CONTAINER_TYPE); + container_free(container->container, container->typecode); + container->container = NULL; // paranoid + roaring_free(container); + } +} + +extern inline container_t *container_not( + const container_t *c1, uint8_t type1, + uint8_t *result_type); + +extern inline container_t *container_not_range( + const container_t *c1, uint8_t type1, + uint32_t range_start, uint32_t range_end, + uint8_t *result_type); + +extern inline container_t *container_inot( + container_t *c1, uint8_t type1, + uint8_t *result_type); + +extern inline container_t *container_inot_range( + container_t *c1, uint8_t type1, + uint32_t range_start, uint32_t range_end, + uint8_t *result_type); + +extern inline container_t *container_range_of_ones( + uint32_t range_start, uint32_t range_end, + uint8_t *result_type); + +// where are the correponding things for union and intersection?? +extern inline container_t *container_lazy_xor( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_lazy_ixor( + container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +extern inline container_t *container_andnot( + const container_t *c1, uint8_t type1, + const container_t *c2, uint8_t type2, + uint8_t *result_type); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/containers.c */ +/* begin file src/containers/convert.c */ +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +// file contains grubby stuff that must know impl. details of all container +// types. +bitset_container_t *bitset_container_from_array(const array_container_t *ac) { + bitset_container_t *ans = bitset_container_create(); + int limit = array_container_cardinality(ac); + for (int i = 0; i < limit; ++i) bitset_container_set(ans, ac->array[i]); + return ans; +} + +bitset_container_t *bitset_container_from_run(const run_container_t *arr) { + int card = run_container_cardinality(arr); + bitset_container_t *answer = bitset_container_create(); + for (int rlepos = 0; rlepos < arr->n_runs; ++rlepos) { + rle16_t vl = arr->runs[rlepos]; + bitset_set_lenrange(answer->words, vl.value, vl.length); + } + answer->cardinality = card; + return answer; +} + +array_container_t *array_container_from_run(const run_container_t *arr) { + array_container_t *answer = + array_container_create_given_capacity(run_container_cardinality(arr)); + answer->cardinality = 0; + for (int rlepos = 0; rlepos < arr->n_runs; ++rlepos) { + int run_start = arr->runs[rlepos].value; + int run_end = run_start + arr->runs[rlepos].length; + + for (int run_value = run_start; run_value <= run_end; ++run_value) { + answer->array[answer->cardinality++] = (uint16_t)run_value; + } + } + return answer; +} + +array_container_t *array_container_from_bitset(const bitset_container_t *bits) { + array_container_t *result = + array_container_create_given_capacity(bits->cardinality); + result->cardinality = bits->cardinality; + // sse version ends up being slower here + // (bitset_extract_setbits_sse_uint16) + // because of the sparsity of the data + bitset_extract_setbits_uint16(bits->words, BITSET_CONTAINER_SIZE_IN_WORDS, + result->array, 0); + return result; +} + +/* assumes that container has adequate space. Run from [s,e] (inclusive) */ +static void add_run(run_container_t *rc, int s, int e) { + rc->runs[rc->n_runs].value = s; + rc->runs[rc->n_runs].length = e - s; + rc->n_runs++; +} + +run_container_t *run_container_from_array(const array_container_t *c) { + int32_t n_runs = array_container_number_of_runs(c); + run_container_t *answer = run_container_create_given_capacity(n_runs); + int prev = -2; + int run_start = -1; + int32_t card = c->cardinality; + if (card == 0) return answer; + for (int i = 0; i < card; ++i) { + const uint16_t cur_val = c->array[i]; + if (cur_val != prev + 1) { + // new run starts; flush old one, if any + if (run_start != -1) add_run(answer, run_start, prev); + run_start = cur_val; + } + prev = c->array[i]; + } + // now prev is the last seen value + add_run(answer, run_start, prev); + // assert(run_container_cardinality(answer) == c->cardinality); + return answer; +} + +/** + * Convert the runcontainer to either a Bitmap or an Array Container, depending + * on the cardinality. Frees the container. + * Allocates and returns new container, which caller is responsible for freeing. + * It does not free the run container. + */ +container_t *convert_to_bitset_or_array_container( + run_container_t *rc, int32_t card, + uint8_t *resulttype +){ + if (card <= DEFAULT_MAX_SIZE) { + array_container_t *answer = array_container_create_given_capacity(card); + answer->cardinality = 0; + for (int rlepos = 0; rlepos < rc->n_runs; ++rlepos) { + uint16_t run_start = rc->runs[rlepos].value; + uint16_t run_end = run_start + rc->runs[rlepos].length; + for (uint16_t run_value = run_start; run_value <= run_end; + ++run_value) { + answer->array[answer->cardinality++] = run_value; + } + } + assert(card == answer->cardinality); + *resulttype = ARRAY_CONTAINER_TYPE; + //run_container_free(r); + return answer; + } + bitset_container_t *answer = bitset_container_create(); + for (int rlepos = 0; rlepos < rc->n_runs; ++rlepos) { + uint16_t run_start = rc->runs[rlepos].value; + bitset_set_lenrange(answer->words, run_start, rc->runs[rlepos].length); + } + answer->cardinality = card; + *resulttype = BITSET_CONTAINER_TYPE; + //run_container_free(r); + return answer; +} + +/* Converts a run container to either an array or a bitset, IF it saves space. + */ +/* If a conversion occurs, the caller is responsible to free the original + * container and + * he becomes responsible to free the new one. */ +container_t *convert_run_to_efficient_container( + run_container_t *c, + uint8_t *typecode_after +){ + int32_t size_as_run_container = + run_container_serialized_size_in_bytes(c->n_runs); + + int32_t size_as_bitset_container = + bitset_container_serialized_size_in_bytes(); + int32_t card = run_container_cardinality(c); + int32_t size_as_array_container = + array_container_serialized_size_in_bytes(card); + + int32_t min_size_non_run = + size_as_bitset_container < size_as_array_container + ? size_as_bitset_container + : size_as_array_container; + if (size_as_run_container <= min_size_non_run) { // no conversion + *typecode_after = RUN_CONTAINER_TYPE; + return c; + } + if (card <= DEFAULT_MAX_SIZE) { + // to array + array_container_t *answer = array_container_create_given_capacity(card); + answer->cardinality = 0; + for (int rlepos = 0; rlepos < c->n_runs; ++rlepos) { + int run_start = c->runs[rlepos].value; + int run_end = run_start + c->runs[rlepos].length; + + for (int run_value = run_start; run_value <= run_end; ++run_value) { + answer->array[answer->cardinality++] = (uint16_t)run_value; + } + } + *typecode_after = ARRAY_CONTAINER_TYPE; + return answer; + } + + // else to bitset + bitset_container_t *answer = bitset_container_create(); + + for (int rlepos = 0; rlepos < c->n_runs; ++rlepos) { + int start = c->runs[rlepos].value; + int end = start + c->runs[rlepos].length; + bitset_set_range(answer->words, start, end + 1); + } + answer->cardinality = card; + *typecode_after = BITSET_CONTAINER_TYPE; + return answer; +} + +// like convert_run_to_efficient_container but frees the old result if needed +container_t *convert_run_to_efficient_container_and_free( + run_container_t *c, + uint8_t *typecode_after +){ + container_t *answer = convert_run_to_efficient_container(c, typecode_after); + if (answer != c) run_container_free(c); + return answer; +} + +/* once converted, the original container is disposed here, rather than + in roaring_array +*/ + +// TODO: split into run- array- and bitset- subfunctions for sanity; +// a few function calls won't really matter. + +container_t *convert_run_optimize( + container_t *c, uint8_t typecode_original, + uint8_t *typecode_after +){ + if (typecode_original == RUN_CONTAINER_TYPE) { + container_t *newc = convert_run_to_efficient_container( + CAST_run(c), typecode_after); + if (newc != c) { + container_free(c, typecode_original); + } + return newc; + } else if (typecode_original == ARRAY_CONTAINER_TYPE) { + // it might need to be converted to a run container. + array_container_t *c_qua_array = CAST_array(c); + int32_t n_runs = array_container_number_of_runs(c_qua_array); + int32_t size_as_run_container = + run_container_serialized_size_in_bytes(n_runs); + int32_t card = array_container_cardinality(c_qua_array); + int32_t size_as_array_container = + array_container_serialized_size_in_bytes(card); + + if (size_as_run_container >= size_as_array_container) { + *typecode_after = ARRAY_CONTAINER_TYPE; + return c; + } + // else convert array to run container + run_container_t *answer = run_container_create_given_capacity(n_runs); + int prev = -2; + int run_start = -1; + + assert(card > 0); + for (int i = 0; i < card; ++i) { + uint16_t cur_val = c_qua_array->array[i]; + if (cur_val != prev + 1) { + // new run starts; flush old one, if any + if (run_start != -1) add_run(answer, run_start, prev); + run_start = cur_val; + } + prev = c_qua_array->array[i]; + } + assert(run_start >= 0); + // now prev is the last seen value + add_run(answer, run_start, prev); + *typecode_after = RUN_CONTAINER_TYPE; + array_container_free(c_qua_array); + return answer; + } else if (typecode_original == + BITSET_CONTAINER_TYPE) { // run conversions on bitset + // does bitset need conversion to run? + bitset_container_t *c_qua_bitset = CAST_bitset(c); + int32_t n_runs = bitset_container_number_of_runs(c_qua_bitset); + int32_t size_as_run_container = + run_container_serialized_size_in_bytes(n_runs); + int32_t size_as_bitset_container = + bitset_container_serialized_size_in_bytes(); + + if (size_as_bitset_container <= size_as_run_container) { + // no conversion needed. + *typecode_after = BITSET_CONTAINER_TYPE; + return c; + } + // bitset to runcontainer (ported from Java RunContainer( + // BitmapContainer bc, int nbrRuns)) + assert(n_runs > 0); // no empty bitmaps + run_container_t *answer = run_container_create_given_capacity(n_runs); + + int long_ctr = 0; + uint64_t cur_word = c_qua_bitset->words[0]; + int run_count = 0; + while (true) { + while (cur_word == UINT64_C(0) && + long_ctr < BITSET_CONTAINER_SIZE_IN_WORDS - 1) + cur_word = c_qua_bitset->words[++long_ctr]; + + if (cur_word == UINT64_C(0)) { + bitset_container_free(c_qua_bitset); + *typecode_after = RUN_CONTAINER_TYPE; + return answer; + } + + int local_run_start = __builtin_ctzll(cur_word); + int run_start = local_run_start + 64 * long_ctr; + uint64_t cur_word_with_1s = cur_word | (cur_word - 1); + + int run_end = 0; + while (cur_word_with_1s == UINT64_C(0xFFFFFFFFFFFFFFFF) && + long_ctr < BITSET_CONTAINER_SIZE_IN_WORDS - 1) + cur_word_with_1s = c_qua_bitset->words[++long_ctr]; + + if (cur_word_with_1s == UINT64_C(0xFFFFFFFFFFFFFFFF)) { + run_end = 64 + long_ctr * 64; // exclusive, I guess + add_run(answer, run_start, run_end - 1); + bitset_container_free(c_qua_bitset); + *typecode_after = RUN_CONTAINER_TYPE; + return answer; + } + int local_run_end = __builtin_ctzll(~cur_word_with_1s); + run_end = local_run_end + long_ctr * 64; + add_run(answer, run_start, run_end - 1); + run_count++; + cur_word = cur_word_with_1s & (cur_word_with_1s + 1); + } + return answer; + } else { + assert(false); + __builtin_unreachable(); + return NULL; + } +} + +container_t *container_from_run_range( + const run_container_t *run, + uint32_t min, uint32_t max, uint8_t *typecode_after +){ + // We expect most of the time to end up with a bitset container + bitset_container_t *bitset = bitset_container_create(); + *typecode_after = BITSET_CONTAINER_TYPE; + int32_t union_cardinality = 0; + for (int32_t i = 0; i < run->n_runs; ++i) { + uint32_t rle_min = run->runs[i].value; + uint32_t rle_max = rle_min + run->runs[i].length; + bitset_set_lenrange(bitset->words, rle_min, rle_max - rle_min); + union_cardinality += run->runs[i].length + 1; + } + union_cardinality += max - min + 1; + union_cardinality -= bitset_lenrange_cardinality(bitset->words, min, max-min); + bitset_set_lenrange(bitset->words, min, max - min); + bitset->cardinality = union_cardinality; + if(bitset->cardinality <= DEFAULT_MAX_SIZE) { + // we need to convert to an array container + array_container_t * array = array_container_from_bitset(bitset); + *typecode_after = ARRAY_CONTAINER_TYPE; + bitset_container_free(bitset); + return array; + } + return bitset; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/convert.c */ +/* begin file src/containers/mixed_andnot.c */ +/* + * mixed_andnot.c. More methods since operation is not symmetric, + * except no "wide" andnot , so no lazy options motivated. + */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst, a valid array container that could be the same as dst.*/ +void array_bitset_container_andnot(const array_container_t *src_1, + const bitset_container_t *src_2, + array_container_t *dst) { + // follows Java implementation as of June 2016 + if (dst->capacity < src_1->cardinality) { + array_container_grow(dst, src_1->cardinality, false); + } + int32_t newcard = 0; + const int32_t origcard = src_1->cardinality; + for (int i = 0; i < origcard; ++i) { + uint16_t key = src_1->array[i]; + dst->array[newcard] = key; + newcard += 1 - bitset_container_contains(src_2, key); + } + dst->cardinality = newcard; +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * src_1 */ + +void array_bitset_container_iandnot(array_container_t *src_1, + const bitset_container_t *src_2) { + array_bitset_container_andnot(src_1, src_2, src_1); +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst, which does not initially have a valid container. + * Return true for a bitset result; false for array + */ + +bool bitset_array_container_andnot( + const bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + // Java did this directly, but we have option of asm or avx + bitset_container_t *result = bitset_container_create(); + bitset_container_copy(src_1, result); + result->cardinality = + (int32_t)bitset_clear_list(result->words, (uint64_t)result->cardinality, + src_2->array, (uint64_t)src_2->cardinality); + + // do required type conversions. + if (result->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(result); + bitset_container_free(result); + return false; + } + *dst = result; + return true; +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_array_container_iandnot( + bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + *dst = src_1; + src_1->cardinality = + (int32_t)bitset_clear_list(src_1->words, (uint64_t)src_1->cardinality, + src_2->array, (uint64_t)src_2->cardinality); + + if (src_1->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(src_1); + bitset_container_free(src_1); + return false; // not bitset + } else + return true; +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_andnot( + const run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + // follows the Java implementation as of June 2016 + int card = run_container_cardinality(src_1); + if (card <= DEFAULT_MAX_SIZE) { + // must be an array + array_container_t *answer = array_container_create_given_capacity(card); + answer->cardinality = 0; + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + for (int run_value = rle.value; run_value <= rle.value + rle.length; + ++run_value) { + if (!bitset_container_get(src_2, (uint16_t)run_value)) { + answer->array[answer->cardinality++] = (uint16_t)run_value; + } + } + } + *dst = answer; + return false; + } else { // we guess it will be a bitset, though have to check guess when + // done + bitset_container_t *answer = bitset_container_clone(src_2); + + uint32_t last_pos = 0; + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + + uint32_t start = rle.value; + uint32_t end = start + rle.length + 1; + bitset_reset_range(answer->words, last_pos, start); + bitset_flip_range(answer->words, start, end); + last_pos = end; + } + bitset_reset_range(answer->words, last_pos, (uint32_t)(1 << 16)); + + answer->cardinality = bitset_container_compute_cardinality(answer); + + if (answer->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(answer); + bitset_container_free(answer); + return false; // not bitset + } + *dst = answer; + return true; // bitset + } +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_iandnot( + run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + // dummy implementation + bool ans = run_bitset_container_andnot(src_1, src_2, dst); + run_container_free(src_1); + return ans; +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool bitset_run_container_andnot( + const bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + // follows Java implementation + bitset_container_t *result = bitset_container_create(); + + bitset_container_copy(src_1, result); + for (int32_t rlepos = 0; rlepos < src_2->n_runs; ++rlepos) { + rle16_t rle = src_2->runs[rlepos]; + bitset_reset_range(result->words, rle.value, + rle.value + rle.length + UINT32_C(1)); + } + result->cardinality = bitset_container_compute_cardinality(result); + + if (result->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(result); + bitset_container_free(result); + return false; // not bitset + } + *dst = result; + return true; // bitset +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_run_container_iandnot( + bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + *dst = src_1; + + for (int32_t rlepos = 0; rlepos < src_2->n_runs; ++rlepos) { + rle16_t rle = src_2->runs[rlepos]; + bitset_reset_range(src_1->words, rle.value, + rle.value + rle.length + UINT32_C(1)); + } + src_1->cardinality = bitset_container_compute_cardinality(src_1); + + if (src_1->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(src_1); + bitset_container_free(src_1); + return false; // not bitset + } else + return true; +} + +/* helper. a_out must be a valid array container with adequate capacity. + * Returns the cardinality of the output container. Partly Based on Java + * implementation Util.unsignedDifference. + * + * TODO: Util.unsignedDifference does not use advanceUntil. Is it cheaper + * to avoid advanceUntil? + */ + +static int run_array_array_subtract(const run_container_t *rc, + const array_container_t *a_in, + array_container_t *a_out) { + int out_card = 0; + int32_t in_array_pos = + -1; // since advanceUntil always assumes we start the search AFTER this + + for (int rlepos = 0; rlepos < rc->n_runs; rlepos++) { + int32_t start = rc->runs[rlepos].value; + int32_t end = start + rc->runs[rlepos].length + 1; + + in_array_pos = advanceUntil(a_in->array, in_array_pos, + a_in->cardinality, (uint16_t)start); + + if (in_array_pos >= a_in->cardinality) { // run has no items subtracted + for (int32_t i = start; i < end; ++i) + a_out->array[out_card++] = (uint16_t)i; + } else { + uint16_t next_nonincluded = a_in->array[in_array_pos]; + if (next_nonincluded >= end) { + // another case when run goes unaltered + for (int32_t i = start; i < end; ++i) + a_out->array[out_card++] = (uint16_t)i; + in_array_pos--; // ensure we see this item again if necessary + } else { + for (int32_t i = start; i < end; ++i) + if (i != next_nonincluded) + a_out->array[out_card++] = (uint16_t)i; + else // 0 should ensure we don't match + next_nonincluded = + (in_array_pos + 1 >= a_in->cardinality) + ? 0 + : a_in->array[++in_array_pos]; + in_array_pos--; // see again + } + } + } + return out_card; +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any type of container. + */ + +int run_array_container_andnot( + const run_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + // follows the Java impl as of June 2016 + + int card = run_container_cardinality(src_1); + const int arbitrary_threshold = 32; + + if (card <= arbitrary_threshold) { + if (src_2->cardinality == 0) { + *dst = run_container_clone(src_1); + return RUN_CONTAINER_TYPE; + } + // Java's "lazyandNot.toEfficientContainer" thing + run_container_t *answer = run_container_create_given_capacity( + card + array_container_cardinality(src_2)); + + int rlepos = 0; + int xrlepos = 0; // "x" is src_2 + rle16_t rle = src_1->runs[rlepos]; + int32_t start = rle.value; + int32_t end = start + rle.length + 1; + int32_t xstart = src_2->array[xrlepos]; + + while ((rlepos < src_1->n_runs) && (xrlepos < src_2->cardinality)) { + if (end <= xstart) { + // output the first run + answer->runs[answer->n_runs++] = + MAKE_RLE16(start, end - start - 1); + rlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + } else if (xstart + 1 <= start) { + // exit the second run + xrlepos++; + if (xrlepos < src_2->cardinality) { + xstart = src_2->array[xrlepos]; + } + } else { + if (start < xstart) { + answer->runs[answer->n_runs++] = + MAKE_RLE16(start, xstart - start - 1); + } + if (xstart + 1 < end) { + start = xstart + 1; + } else { + rlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + } + } + } + if (rlepos < src_1->n_runs) { + answer->runs[answer->n_runs++] = MAKE_RLE16(start, end - start - 1); + rlepos++; + if (rlepos < src_1->n_runs) { + memcpy(answer->runs + answer->n_runs, src_1->runs + rlepos, + (src_1->n_runs - rlepos) * sizeof(rle16_t)); + answer->n_runs += (src_1->n_runs - rlepos); + } + } + uint8_t return_type; + *dst = convert_run_to_efficient_container(answer, &return_type); + if (answer != *dst) run_container_free(answer); + return return_type; + } + // else it's a bitmap or array + + if (card <= DEFAULT_MAX_SIZE) { + array_container_t *ac = array_container_create_given_capacity(card); + // nb Java code used a generic iterator-based merge to compute + // difference + ac->cardinality = run_array_array_subtract(src_1, src_2, ac); + *dst = ac; + return ARRAY_CONTAINER_TYPE; + } + bitset_container_t *ans = bitset_container_from_run(src_1); + bool result_is_bitset = bitset_array_container_iandnot(ans, src_2, dst); + return (result_is_bitset ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE); +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +int run_array_container_iandnot( + run_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + // dummy implementation same as June 2016 Java + int ans = run_array_container_andnot(src_1, src_2, dst); + run_container_free(src_1); + return ans; +} + +/* dst must be a valid array container, allowed to be src_1 */ + +void array_run_container_andnot(const array_container_t *src_1, + const run_container_t *src_2, + array_container_t *dst) { + // basically following Java impl as of June 2016 + if (src_1->cardinality > dst->capacity) { + array_container_grow(dst, src_1->cardinality, false); + } + + if (src_2->n_runs == 0) { + memmove(dst->array, src_1->array, + sizeof(uint16_t) * src_1->cardinality); + dst->cardinality = src_1->cardinality; + return; + } + int32_t run_start = src_2->runs[0].value; + int32_t run_end = run_start + src_2->runs[0].length; + int which_run = 0; + + uint16_t val = 0; + int dest_card = 0; + for (int i = 0; i < src_1->cardinality; ++i) { + val = src_1->array[i]; + if (val < run_start) + dst->array[dest_card++] = val; + else if (val <= run_end) { + ; // omitted item + } else { + do { + if (which_run + 1 < src_2->n_runs) { + ++which_run; + run_start = src_2->runs[which_run].value; + run_end = run_start + src_2->runs[which_run].length; + + } else + run_start = run_end = (1 << 16) + 1; + } while (val > run_end); + --i; + } + } + dst->cardinality = dest_card; +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +void array_run_container_iandnot(array_container_t *src_1, + const run_container_t *src_2) { + array_run_container_andnot(src_1, src_2, src_1); +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int run_run_container_andnot( + const run_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + run_container_t *ans = run_container_create(); + run_container_andnot(src_1, src_2, ans); + uint8_t typecode_after; + *dst = convert_run_to_efficient_container_and_free(ans, &typecode_after); + return typecode_after; +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +int run_run_container_iandnot( + run_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + // following Java impl as of June 2016 (dummy) + int ans = run_run_container_andnot(src_1, src_2, dst); + run_container_free(src_1); + return ans; +} + +/* + * dst is a valid array container and may be the same as src_1 + */ + +void array_array_container_andnot(const array_container_t *src_1, + const array_container_t *src_2, + array_container_t *dst) { + array_container_andnot(src_1, src_2, dst); +} + +/* inplace array-array andnot will always be able to reuse the space of + * src_1 */ +void array_array_container_iandnot(array_container_t *src_1, + const array_container_t *src_2) { + array_container_andnot(src_1, src_2, src_1); +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). Return value is + * "dst is a bitset" + */ + +bool bitset_bitset_container_andnot( + const bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bitset_container_t *ans = bitset_container_create(); + int card = bitset_container_andnot(src_1, src_2, ans); + if (card <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(ans); + bitset_container_free(ans); + return false; // not bitset + } else { + *dst = ans; + return true; + } +} + +/* Compute the andnot of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_bitset_container_iandnot( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + int card = bitset_container_andnot(src_1, src_2, src_1); + if (card <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(src_1); + bitset_container_free(src_1); + return false; // not bitset + } else { + *dst = src_1; + return true; + } +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_andnot.c */ +/* begin file src/containers/mixed_equal.c */ + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +bool array_container_equal_bitset(const array_container_t* container1, + const bitset_container_t* container2) { + if (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) { + if (container2->cardinality != container1->cardinality) { + return false; + } + } + int32_t pos = 0; + for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) { + uint64_t w = container2->words[i]; + while (w != 0) { + uint64_t t = w & (~w + 1); + uint16_t r = i * 64 + __builtin_ctzll(w); + if (pos >= container1->cardinality) { + return false; + } + if (container1->array[pos] != r) { + return false; + } + ++pos; + w ^= t; + } + } + return (pos == container1->cardinality); +} + +bool run_container_equals_array(const run_container_t* container1, + const array_container_t* container2) { + if (run_container_cardinality(container1) != container2->cardinality) + return false; + int32_t pos = 0; + for (int i = 0; i < container1->n_runs; ++i) { + const uint32_t run_start = container1->runs[i].value; + const uint32_t le = container1->runs[i].length; + + if (container2->array[pos] != run_start) { + return false; + } + + if (container2->array[pos + le] != run_start + le) { + return false; + } + + pos += le + 1; + } + return true; +} + +bool run_container_equals_bitset(const run_container_t* container1, + const bitset_container_t* container2) { + + int run_card = run_container_cardinality(container1); + int bitset_card = (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) ? + container2->cardinality : + bitset_container_compute_cardinality(container2); + if (bitset_card != run_card) { + return false; + } + + for (int32_t i = 0; i < container1->n_runs; i++) { + uint32_t begin = container1->runs[i].value; + if (container1->runs[i].length) { + uint32_t end = begin + container1->runs[i].length + 1; + if (!bitset_container_contains_range(container2, begin, end)) { + return false; + } + } else { + if (!bitset_container_contains(container2, begin)) { + return false; + } + } + } + + return true; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_equal.c */ +/* begin file src/containers/mixed_intersection.c */ +/* + * mixed_intersection.c + * + */ + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the intersection of src_1 and src_2 and write the result to + * dst. */ +void array_bitset_container_intersection(const array_container_t *src_1, + const bitset_container_t *src_2, + array_container_t *dst) { + if (dst->capacity < src_1->cardinality) { + array_container_grow(dst, src_1->cardinality, false); + } + int32_t newcard = 0; // dst could be src_1 + const int32_t origcard = src_1->cardinality; + for (int i = 0; i < origcard; ++i) { + uint16_t key = src_1->array[i]; + // this branchless approach is much faster... + dst->array[newcard] = key; + newcard += bitset_container_contains(src_2, key); + /** + * we could do it this way instead... + * if (bitset_container_contains(src_2, key)) { + * dst->array[newcard++] = key; + * } + * but if the result is unpredictible, the processor generates + * many mispredicted branches. + * Difference can be huge (from 3 cycles when predictible all the way + * to 16 cycles when unpredictible. + * See + * https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/extra/bitset/c/arraybitsetintersection.c + */ + } + dst->cardinality = newcard; +} + +/* Compute the size of the intersection of src_1 and src_2. */ +int array_bitset_container_intersection_cardinality( + const array_container_t *src_1, const bitset_container_t *src_2) { + int32_t newcard = 0; + const int32_t origcard = src_1->cardinality; + for (int i = 0; i < origcard; ++i) { + uint16_t key = src_1->array[i]; + newcard += bitset_container_contains(src_2, key); + } + return newcard; +} + + +bool array_bitset_container_intersect(const array_container_t *src_1, + const bitset_container_t *src_2) { + const int32_t origcard = src_1->cardinality; + for (int i = 0; i < origcard; ++i) { + uint16_t key = src_1->array[i]; + if(bitset_container_contains(src_2, key)) return true; + } + return false; +} + +/* Compute the intersection of src_1 and src_2 and write the result to + * dst. It is allowed for dst to be equal to src_1. We assume that dst is a + * valid container. */ +void array_run_container_intersection(const array_container_t *src_1, + const run_container_t *src_2, + array_container_t *dst) { + if (run_container_is_full(src_2)) { + if (dst != src_1) array_container_copy(src_1, dst); + return; + } + if (dst->capacity < src_1->cardinality) { + array_container_grow(dst, src_1->cardinality, false); + } + if (src_2->n_runs == 0) { + return; + } + int32_t rlepos = 0; + int32_t arraypos = 0; + rle16_t rle = src_2->runs[rlepos]; + int32_t newcard = 0; + while (arraypos < src_1->cardinality) { + const uint16_t arrayval = src_1->array[arraypos]; + while (rle.value + rle.length < + arrayval) { // this will frequently be false + ++rlepos; + if (rlepos == src_2->n_runs) { + dst->cardinality = newcard; + return; // we are done + } + rle = src_2->runs[rlepos]; + } + if (rle.value > arrayval) { + arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality, + rle.value); + } else { + dst->array[newcard] = arrayval; + newcard++; + arraypos++; + } + } + dst->cardinality = newcard; +} + +/* Compute the intersection of src_1 and src_2 and write the result to + * *dst. If the result is true then the result is a bitset_container_t + * otherwise is a array_container_t. If *dst == src_2, an in-place processing + * is attempted.*/ +bool run_bitset_container_intersection( + const run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + if (run_container_is_full(src_1)) { + if (*dst != src_2) *dst = bitset_container_clone(src_2); + return true; + } + int32_t card = run_container_cardinality(src_1); + if (card <= DEFAULT_MAX_SIZE) { + // result can only be an array (assuming that we never make a + // RunContainer) + if (card > src_2->cardinality) { + card = src_2->cardinality; + } + array_container_t *answer = array_container_create_given_capacity(card); + *dst = answer; + if (*dst == NULL) { + return false; + } + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + uint32_t endofrun = (uint32_t)rle.value + rle.length; + for (uint32_t runValue = rle.value; runValue <= endofrun; + ++runValue) { + answer->array[answer->cardinality] = (uint16_t)runValue; + answer->cardinality += + bitset_container_contains(src_2, runValue); + } + } + return false; + } + if (*dst == src_2) { // we attempt in-place + bitset_container_t *answer = CAST_bitset(*dst); + uint32_t start = 0; + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + const rle16_t rle = src_1->runs[rlepos]; + uint32_t end = rle.value; + bitset_reset_range(src_2->words, start, end); + + start = end + rle.length + 1; + } + bitset_reset_range(src_2->words, start, UINT32_C(1) << 16); + answer->cardinality = bitset_container_compute_cardinality(answer); + if (src_2->cardinality > DEFAULT_MAX_SIZE) { + return true; + } else { + array_container_t *newanswer = array_container_from_bitset(src_2); + if (newanswer == NULL) { + *dst = NULL; + return false; + } + *dst = newanswer; + return false; + } + } else { // no inplace + // we expect the answer to be a bitmap (if we are lucky) + bitset_container_t *answer = bitset_container_clone(src_2); + + *dst = answer; + if (answer == NULL) { + return true; + } + uint32_t start = 0; + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + const rle16_t rle = src_1->runs[rlepos]; + uint32_t end = rle.value; + bitset_reset_range(answer->words, start, end); + start = end + rle.length + 1; + } + bitset_reset_range(answer->words, start, UINT32_C(1) << 16); + answer->cardinality = bitset_container_compute_cardinality(answer); + + if (answer->cardinality > DEFAULT_MAX_SIZE) { + return true; + } else { + array_container_t *newanswer = array_container_from_bitset(answer); + bitset_container_free(CAST_bitset(*dst)); + if (newanswer == NULL) { + *dst = NULL; + return false; + } + *dst = newanswer; + return false; + } + } +} + +/* Compute the size of the intersection between src_1 and src_2 . */ +int array_run_container_intersection_cardinality(const array_container_t *src_1, + const run_container_t *src_2) { + if (run_container_is_full(src_2)) { + return src_1->cardinality; + } + if (src_2->n_runs == 0) { + return 0; + } + int32_t rlepos = 0; + int32_t arraypos = 0; + rle16_t rle = src_2->runs[rlepos]; + int32_t newcard = 0; + while (arraypos < src_1->cardinality) { + const uint16_t arrayval = src_1->array[arraypos]; + while (rle.value + rle.length < + arrayval) { // this will frequently be false + ++rlepos; + if (rlepos == src_2->n_runs) { + return newcard; // we are done + } + rle = src_2->runs[rlepos]; + } + if (rle.value > arrayval) { + arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality, + rle.value); + } else { + newcard++; + arraypos++; + } + } + return newcard; +} + +/* Compute the intersection between src_1 and src_2 + **/ +int run_bitset_container_intersection_cardinality( + const run_container_t *src_1, const bitset_container_t *src_2) { + if (run_container_is_full(src_1)) { + return bitset_container_cardinality(src_2); + } + int answer = 0; + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + answer += + bitset_lenrange_cardinality(src_2->words, rle.value, rle.length); + } + return answer; +} + + +bool array_run_container_intersect(const array_container_t *src_1, + const run_container_t *src_2) { + if( run_container_is_full(src_2) ) { + return !array_container_empty(src_1); + } + if (src_2->n_runs == 0) { + return false; + } + int32_t rlepos = 0; + int32_t arraypos = 0; + rle16_t rle = src_2->runs[rlepos]; + while (arraypos < src_1->cardinality) { + const uint16_t arrayval = src_1->array[arraypos]; + while (rle.value + rle.length < + arrayval) { // this will frequently be false + ++rlepos; + if (rlepos == src_2->n_runs) { + return false; // we are done + } + rle = src_2->runs[rlepos]; + } + if (rle.value > arrayval) { + arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality, + rle.value); + } else { + return true; + } + } + return false; +} + +/* Compute the intersection between src_1 and src_2 + **/ +bool run_bitset_container_intersect(const run_container_t *src_1, + const bitset_container_t *src_2) { + if( run_container_is_full(src_1) ) { + return !bitset_container_empty(src_2); + } + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + if(!bitset_lenrange_empty(src_2->words, rle.value,rle.length)) return true; + } + return false; +} + +/* + * Compute the intersection between src_1 and src_2 and write the result + * to *dst. If the return function is true, the result is a bitset_container_t + * otherwise is a array_container_t. + */ +bool bitset_bitset_container_intersection( + const bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + const int newCardinality = bitset_container_and_justcard(src_1, src_2); + if (newCardinality > DEFAULT_MAX_SIZE) { + *dst = bitset_container_create(); + if (*dst != NULL) { + bitset_container_and_nocard(src_1, src_2, CAST_bitset(*dst)); + CAST_bitset(*dst)->cardinality = newCardinality; + } + return true; // it is a bitset + } + *dst = array_container_create_given_capacity(newCardinality); + if (*dst != NULL) { + CAST_array(*dst)->cardinality = newCardinality; + bitset_extract_intersection_setbits_uint16( + src_1->words, src_2->words, BITSET_CONTAINER_SIZE_IN_WORDS, + CAST_array(*dst)->array, 0); + } + return false; // not a bitset +} + +bool bitset_bitset_container_intersection_inplace( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + const int newCardinality = bitset_container_and_justcard(src_1, src_2); + if (newCardinality > DEFAULT_MAX_SIZE) { + *dst = src_1; + bitset_container_and_nocard(src_1, src_2, src_1); + CAST_bitset(*dst)->cardinality = newCardinality; + return true; // it is a bitset + } + *dst = array_container_create_given_capacity(newCardinality); + if (*dst != NULL) { + CAST_array(*dst)->cardinality = newCardinality; + bitset_extract_intersection_setbits_uint16( + src_1->words, src_2->words, BITSET_CONTAINER_SIZE_IN_WORDS, + CAST_array(*dst)->array, 0); + } + return false; // not a bitset +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_intersection.c */ +/* begin file src/containers/mixed_negation.c */ +/* + * mixed_negation.c + * + */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +// TODO: make simplified and optimized negation code across +// the full range. + +/* Negation across the entire range of the container. + * Compute the negation of src and write the result + * to *dst. The complement of a + * sufficiently sparse set will always be dense and a hence a bitmap +' * We assume that dst is pre-allocated and a valid bitset container + * There can be no in-place version. + */ +void array_container_negation(const array_container_t *src, + bitset_container_t *dst) { + uint64_t card = UINT64_C(1 << 16); + bitset_container_set_all(dst); + + if (src->cardinality == 0) { + return; + } + + dst->cardinality = (int32_t)bitset_clear_list(dst->words, card, src->array, + (uint64_t)src->cardinality); +} + +/* Negation across the entire range of the container + * Compute the negation of src and write the result + * to *dst. A true return value indicates a bitset result, + * otherwise the result is an array container. + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool bitset_container_negation( + const bitset_container_t *src, container_t **dst +){ + return bitset_container_negation_range(src, 0, (1 << 16), dst); +} + +/* inplace version */ +/* + * Same as bitset_container_negation except that if the output is to + * be a + * bitset_container_t, then src is modified and no allocation is made. + * If the output is to be an array_container_t, then caller is responsible + * to free the container. + * In all cases, the result is in *dst. + */ +bool bitset_container_negation_inplace( + bitset_container_t *src, container_t **dst +){ + return bitset_container_negation_range_inplace(src, 0, (1 << 16), dst); +} + +/* Negation across the entire range of container + * Compute the negation of src and write the result + * to *dst. Return values are the *_TYPECODES as defined * in containers.h + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +int run_container_negation(const run_container_t *src, container_t **dst) { + return run_container_negation_range(src, 0, (1 << 16), dst); +} + +/* + * Same as run_container_negation except that if the output is to + * be a + * run_container_t, and has the capacity to hold the result, + * then src is modified and no allocation is made. + * In all cases, the result is in *dst. + */ +int run_container_negation_inplace(run_container_t *src, container_t **dst) { + return run_container_negation_range_inplace(src, 0, (1 << 16), dst); +} + +/* Negation across a range of the container. + * Compute the negation of src and write the result + * to *dst. Returns true if the result is a bitset container + * and false for an array container. *dst is not preallocated. + */ +bool array_container_negation_range( + const array_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + /* close port of the Java implementation */ + if (range_start >= range_end) { + *dst = array_container_clone(src); + return false; + } + + int32_t start_index = + binarySearch(src->array, src->cardinality, (uint16_t)range_start); + if (start_index < 0) start_index = -start_index - 1; + + int32_t last_index = + binarySearch(src->array, src->cardinality, (uint16_t)(range_end - 1)); + if (last_index < 0) last_index = -last_index - 2; + + const int32_t current_values_in_range = last_index - start_index + 1; + const int32_t span_to_be_flipped = range_end - range_start; + const int32_t new_values_in_range = + span_to_be_flipped - current_values_in_range; + const int32_t cardinality_change = + new_values_in_range - current_values_in_range; + const int32_t new_cardinality = src->cardinality + cardinality_change; + + if (new_cardinality > DEFAULT_MAX_SIZE) { + bitset_container_t *temp = bitset_container_from_array(src); + bitset_flip_range(temp->words, (uint32_t)range_start, + (uint32_t)range_end); + temp->cardinality = new_cardinality; + *dst = temp; + return true; + } + + array_container_t *arr = + array_container_create_given_capacity(new_cardinality); + *dst = (container_t *)arr; + if(new_cardinality == 0) { + arr->cardinality = new_cardinality; + return false; // we are done. + } + // copy stuff before the active area + memcpy(arr->array, src->array, start_index * sizeof(uint16_t)); + + // work on the range + int32_t out_pos = start_index, in_pos = start_index; + int32_t val_in_range = range_start; + for (; val_in_range < range_end && in_pos <= last_index; ++val_in_range) { + if ((uint16_t)val_in_range != src->array[in_pos]) { + arr->array[out_pos++] = (uint16_t)val_in_range; + } else { + ++in_pos; + } + } + for (; val_in_range < range_end; ++val_in_range) + arr->array[out_pos++] = (uint16_t)val_in_range; + + // content after the active range + memcpy(arr->array + out_pos, src->array + (last_index + 1), + (src->cardinality - (last_index + 1)) * sizeof(uint16_t)); + arr->cardinality = new_cardinality; + return false; +} + +/* Even when the result would fit, it is unclear how to make an + * inplace version without inefficient copying. + */ + +bool array_container_negation_range_inplace( + array_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + bool ans = array_container_negation_range(src, range_start, range_end, dst); + // TODO : try a real inplace version + array_container_free(src); + return ans; +} + +/* Negation across a range of the container + * Compute the negation of src and write the result + * to *dst. A true return value indicates a bitset result, + * otherwise the result is an array container. + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +bool bitset_container_negation_range( + const bitset_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + // TODO maybe consider density-based estimate + // and sometimes build result directly as array, with + // conversion back to bitset if wrong. Or determine + // actual result cardinality, then go directly for the known final cont. + + // keep computation using bitsets as long as possible. + bitset_container_t *t = bitset_container_clone(src); + bitset_flip_range(t->words, (uint32_t)range_start, (uint32_t)range_end); + t->cardinality = bitset_container_compute_cardinality(t); + + if (t->cardinality > DEFAULT_MAX_SIZE) { + *dst = t; + return true; + } else { + *dst = array_container_from_bitset(t); + bitset_container_free(t); + return false; + } +} + +/* inplace version */ +/* + * Same as bitset_container_negation except that if the output is to + * be a + * bitset_container_t, then src is modified and no allocation is made. + * If the output is to be an array_container_t, then caller is responsible + * to free the container. + * In all cases, the result is in *dst. + */ +bool bitset_container_negation_range_inplace( + bitset_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + bitset_flip_range(src->words, (uint32_t)range_start, (uint32_t)range_end); + src->cardinality = bitset_container_compute_cardinality(src); + if (src->cardinality > DEFAULT_MAX_SIZE) { + *dst = src; + return true; + } + *dst = array_container_from_bitset(src); + bitset_container_free(src); + return false; +} + +/* Negation across a range of container + * Compute the negation of src and write the result + * to *dst. Return values are the *_TYPECODES as defined * in containers.h + * We assume that dst is not pre-allocated. In + * case of failure, *dst will be NULL. + */ +int run_container_negation_range( + const run_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + uint8_t return_typecode; + + // follows the Java implementation + if (range_end <= range_start) { + *dst = run_container_clone(src); + return RUN_CONTAINER_TYPE; + } + + run_container_t *ans = run_container_create_given_capacity( + src->n_runs + 1); // src->n_runs + 1); + int k = 0; + for (; k < src->n_runs && src->runs[k].value < range_start; ++k) { + ans->runs[k] = src->runs[k]; + ans->n_runs++; + } + + run_container_smart_append_exclusive( + ans, (uint16_t)range_start, (uint16_t)(range_end - range_start - 1)); + + for (; k < src->n_runs; ++k) { + run_container_smart_append_exclusive(ans, src->runs[k].value, + src->runs[k].length); + } + + *dst = convert_run_to_efficient_container(ans, &return_typecode); + if (return_typecode != RUN_CONTAINER_TYPE) run_container_free(ans); + + return return_typecode; +} + +/* + * Same as run_container_negation except that if the output is to + * be a + * run_container_t, and has the capacity to hold the result, + * then src is modified and no allocation is made. + * In all cases, the result is in *dst. + */ +int run_container_negation_range_inplace( + run_container_t *src, + const int range_start, const int range_end, + container_t **dst +){ + uint8_t return_typecode; + + if (range_end <= range_start) { + *dst = src; + return RUN_CONTAINER_TYPE; + } + + // TODO: efficient special case when range is 0 to 65535 inclusive + + if (src->capacity == src->n_runs) { + // no excess room. More checking to see if result can fit + bool last_val_before_range = false; + bool first_val_in_range = false; + bool last_val_in_range = false; + bool first_val_past_range = false; + + if (range_start > 0) + last_val_before_range = + run_container_contains(src, (uint16_t)(range_start - 1)); + first_val_in_range = run_container_contains(src, (uint16_t)range_start); + + if (last_val_before_range == first_val_in_range) { + last_val_in_range = + run_container_contains(src, (uint16_t)(range_end - 1)); + if (range_end != 0x10000) + first_val_past_range = + run_container_contains(src, (uint16_t)range_end); + + if (last_val_in_range == + first_val_past_range) { // no space for inplace + int ans = run_container_negation_range(src, range_start, + range_end, dst); + run_container_free(src); + return ans; + } + } + } + // all other cases: result will fit + + run_container_t *ans = src; + int my_nbr_runs = src->n_runs; + + ans->n_runs = 0; + int k = 0; + for (; (k < my_nbr_runs) && (src->runs[k].value < range_start); ++k) { + // ans->runs[k] = src->runs[k]; (would be self-copy) + ans->n_runs++; + } + + // as with Java implementation, use locals to give self a buffer of depth 1 + rle16_t buffered = MAKE_RLE16(0, 0); + rle16_t next = buffered; + if (k < my_nbr_runs) buffered = src->runs[k]; + + run_container_smart_append_exclusive( + ans, (uint16_t)range_start, (uint16_t)(range_end - range_start - 1)); + + for (; k < my_nbr_runs; ++k) { + if (k + 1 < my_nbr_runs) next = src->runs[k + 1]; + + run_container_smart_append_exclusive(ans, buffered.value, + buffered.length); + buffered = next; + } + + *dst = convert_run_to_efficient_container(ans, &return_typecode); + if (return_typecode != RUN_CONTAINER_TYPE) run_container_free(ans); + + return return_typecode; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_negation.c */ +/* begin file src/containers/mixed_subset.c */ + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +bool array_container_is_subset_bitset(const array_container_t* container1, + const bitset_container_t* container2) { + if (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) { + if (container2->cardinality < container1->cardinality) { + return false; + } + } + for (int i = 0; i < container1->cardinality; ++i) { + if (!bitset_container_contains(container2, container1->array[i])) { + return false; + } + } + return true; +} + +bool run_container_is_subset_array(const run_container_t* container1, + const array_container_t* container2) { + if (run_container_cardinality(container1) > container2->cardinality) + return false; + int32_t start_pos = -1, stop_pos = -1; + for (int i = 0; i < container1->n_runs; ++i) { + int32_t start = container1->runs[i].value; + int32_t stop = start + container1->runs[i].length; + start_pos = advanceUntil(container2->array, stop_pos, + container2->cardinality, start); + stop_pos = advanceUntil(container2->array, stop_pos, + container2->cardinality, stop); + if (start_pos == container2->cardinality) { + return false; + } else if (stop_pos - start_pos != stop - start || + container2->array[start_pos] != start || + container2->array[stop_pos] != stop) { + return false; + } + } + return true; +} + +bool array_container_is_subset_run(const array_container_t* container1, + const run_container_t* container2) { + if (container1->cardinality > run_container_cardinality(container2)) + return false; + int i_array = 0, i_run = 0; + while (i_array < container1->cardinality && i_run < container2->n_runs) { + uint32_t start = container2->runs[i_run].value; + uint32_t stop = start + container2->runs[i_run].length; + if (container1->array[i_array] < start) { + return false; + } else if (container1->array[i_array] > stop) { + i_run++; + } else { // the value of the array is in the run + i_array++; + } + } + if (i_array == container1->cardinality) { + return true; + } else { + return false; + } +} + +bool run_container_is_subset_bitset(const run_container_t* container1, + const bitset_container_t* container2) { + // todo: this code could be much faster + if (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) { + if (container2->cardinality < run_container_cardinality(container1)) { + return false; + } + } else { + int32_t card = bitset_container_compute_cardinality( + container2); // modify container2? + if (card < run_container_cardinality(container1)) { + return false; + } + } + for (int i = 0; i < container1->n_runs; ++i) { + uint32_t run_start = container1->runs[i].value; + uint32_t le = container1->runs[i].length; + for (uint32_t j = run_start; j <= run_start + le; ++j) { + if (!bitset_container_contains(container2, j)) { + return false; + } + } + } + return true; +} + +bool bitset_container_is_subset_run(const bitset_container_t* container1, + const run_container_t* container2) { + // todo: this code could be much faster + if (container1->cardinality != BITSET_UNKNOWN_CARDINALITY) { + if (container1->cardinality > run_container_cardinality(container2)) { + return false; + } + } + int32_t i_bitset = 0, i_run = 0; + while (i_bitset < BITSET_CONTAINER_SIZE_IN_WORDS && + i_run < container2->n_runs) { + uint64_t w = container1->words[i_bitset]; + while (w != 0 && i_run < container2->n_runs) { + uint32_t start = container2->runs[i_run].value; + uint32_t stop = start + container2->runs[i_run].length; + uint64_t t = w & (~w + 1); + uint16_t r = i_bitset * 64 + __builtin_ctzll(w); + if (r < start) { + return false; + } else if (r > stop) { + i_run++; + continue; + } else { + w ^= t; + } + } + if (w == 0) { + i_bitset++; + } else { + return false; + } + } + if (i_bitset < BITSET_CONTAINER_SIZE_IN_WORDS) { + // terminated iterating on the run containers, check that rest of bitset + // is empty + for (; i_bitset < BITSET_CONTAINER_SIZE_IN_WORDS; i_bitset++) { + if (container1->words[i_bitset] != 0) { + return false; + } + } + } + return true; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_subset.c */ +/* begin file src/containers/mixed_union.c */ +/* + * mixed_union.c + * + */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the union of src_1 and src_2 and write the result to + * dst. */ +void array_bitset_container_union(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + if (src_2 != dst) bitset_container_copy(src_2, dst); + dst->cardinality = (int32_t)bitset_set_list_withcard( + dst->words, dst->cardinality, src_1->array, src_1->cardinality); +} + +/* Compute the union of src_1 and src_2 and write the result to + * dst. It is allowed for src_2 to be dst. This version does not + * update the cardinality of dst (it is set to BITSET_UNKNOWN_CARDINALITY). */ +void array_bitset_container_lazy_union(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + if (src_2 != dst) bitset_container_copy(src_2, dst); + bitset_set_list(dst->words, src_1->array, src_1->cardinality); + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; +} + +void run_bitset_container_union(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + assert(!run_container_is_full(src_1)); // catch this case upstream + if (src_2 != dst) bitset_container_copy(src_2, dst); + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + bitset_set_lenrange(dst->words, rle.value, rle.length); + } + dst->cardinality = bitset_container_compute_cardinality(dst); +} + +void run_bitset_container_lazy_union(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + assert(!run_container_is_full(src_1)); // catch this case upstream + if (src_2 != dst) bitset_container_copy(src_2, dst); + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + bitset_set_lenrange(dst->words, rle.value, rle.length); + } + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; +} + +// why do we leave the result as a run container?? +void array_run_container_union(const array_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst) { + if (run_container_is_full(src_2)) { + run_container_copy(src_2, dst); + return; + } + // TODO: see whether the "2*" is spurious + run_container_grow(dst, 2 * (src_1->cardinality + src_2->n_runs), false); + int32_t rlepos = 0; + int32_t arraypos = 0; + rle16_t previousrle; + if (src_2->runs[rlepos].value <= src_1->array[arraypos]) { + previousrle = run_container_append_first(dst, src_2->runs[rlepos]); + rlepos++; + } else { + previousrle = + run_container_append_value_first(dst, src_1->array[arraypos]); + arraypos++; + } + while ((rlepos < src_2->n_runs) && (arraypos < src_1->cardinality)) { + if (src_2->runs[rlepos].value <= src_1->array[arraypos]) { + run_container_append(dst, src_2->runs[rlepos], &previousrle); + rlepos++; + } else { + run_container_append_value(dst, src_1->array[arraypos], + &previousrle); + arraypos++; + } + } + if (arraypos < src_1->cardinality) { + while (arraypos < src_1->cardinality) { + run_container_append_value(dst, src_1->array[arraypos], + &previousrle); + arraypos++; + } + } else { + while (rlepos < src_2->n_runs) { + run_container_append(dst, src_2->runs[rlepos], &previousrle); + rlepos++; + } + } +} + +void array_run_container_inplace_union(const array_container_t *src_1, + run_container_t *src_2) { + if (run_container_is_full(src_2)) { + return; + } + const int32_t maxoutput = src_1->cardinality + src_2->n_runs; + const int32_t neededcapacity = maxoutput + src_2->n_runs; + if (src_2->capacity < neededcapacity) + run_container_grow(src_2, neededcapacity, true); + memmove(src_2->runs + maxoutput, src_2->runs, + src_2->n_runs * sizeof(rle16_t)); + rle16_t *inputsrc2 = src_2->runs + maxoutput; + int32_t rlepos = 0; + int32_t arraypos = 0; + int src2nruns = src_2->n_runs; + src_2->n_runs = 0; + + rle16_t previousrle; + + if (inputsrc2[rlepos].value <= src_1->array[arraypos]) { + previousrle = run_container_append_first(src_2, inputsrc2[rlepos]); + rlepos++; + } else { + previousrle = + run_container_append_value_first(src_2, src_1->array[arraypos]); + arraypos++; + } + + while ((rlepos < src2nruns) && (arraypos < src_1->cardinality)) { + if (inputsrc2[rlepos].value <= src_1->array[arraypos]) { + run_container_append(src_2, inputsrc2[rlepos], &previousrle); + rlepos++; + } else { + run_container_append_value(src_2, src_1->array[arraypos], + &previousrle); + arraypos++; + } + } + if (arraypos < src_1->cardinality) { + while (arraypos < src_1->cardinality) { + run_container_append_value(src_2, src_1->array[arraypos], + &previousrle); + arraypos++; + } + } else { + while (rlepos < src2nruns) { + run_container_append(src_2, inputsrc2[rlepos], &previousrle); + rlepos++; + } + } +} + +bool array_array_container_union( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = src_1->cardinality + src_2->cardinality; + if (totalCardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_create_given_capacity(totalCardinality); + if (*dst != NULL) { + array_container_union(src_1, src_2, CAST_array(*dst)); + } else { + return true; // otherwise failure won't be caught + } + return false; // not a bitset + } + *dst = bitset_container_create(); + bool returnval = true; // expect a bitset + if (*dst != NULL) { + bitset_container_t *ourbitset = CAST_bitset(*dst); + bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality); + ourbitset->cardinality = (int32_t)bitset_set_list_withcard( + ourbitset->words, src_1->cardinality, src_2->array, + src_2->cardinality); + if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) { + // need to convert! + *dst = array_container_from_bitset(ourbitset); + bitset_container_free(ourbitset); + returnval = false; // not going to be a bitset + } + } + return returnval; +} + +bool array_array_container_inplace_union( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = src_1->cardinality + src_2->cardinality; + *dst = NULL; + if (totalCardinality <= DEFAULT_MAX_SIZE) { + if(src_1->capacity < totalCardinality) { + *dst = array_container_create_given_capacity(2 * totalCardinality); // be purposefully generous + if (*dst != NULL) { + array_container_union(src_1, src_2, CAST_array(*dst)); + } else { + return true; // otherwise failure won't be caught + } + return false; // not a bitset + } else { + memmove(src_1->array + src_2->cardinality, src_1->array, src_1->cardinality * sizeof(uint16_t)); + src_1->cardinality = (int32_t)union_uint16(src_1->array + src_2->cardinality, src_1->cardinality, + src_2->array, src_2->cardinality, src_1->array); + return false; // not a bitset + } + } + *dst = bitset_container_create(); + bool returnval = true; // expect a bitset + if (*dst != NULL) { + bitset_container_t *ourbitset = CAST_bitset(*dst); + bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality); + ourbitset->cardinality = (int32_t)bitset_set_list_withcard( + ourbitset->words, src_1->cardinality, src_2->array, + src_2->cardinality); + if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) { + // need to convert! + if(src_1->capacity < ourbitset->cardinality) { + array_container_grow(src_1, ourbitset->cardinality, false); + } + + bitset_extract_setbits_uint16(ourbitset->words, BITSET_CONTAINER_SIZE_IN_WORDS, + src_1->array, 0); + src_1->cardinality = ourbitset->cardinality; + *dst = src_1; + bitset_container_free(ourbitset); + returnval = false; // not going to be a bitset + } + } + return returnval; +} + + +bool array_array_container_lazy_union( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = src_1->cardinality + src_2->cardinality; + if (totalCardinality <= ARRAY_LAZY_LOWERBOUND) { + *dst = array_container_create_given_capacity(totalCardinality); + if (*dst != NULL) { + array_container_union(src_1, src_2, CAST_array(*dst)); + } else { + return true; // otherwise failure won't be caught + } + return false; // not a bitset + } + *dst = bitset_container_create(); + bool returnval = true; // expect a bitset + if (*dst != NULL) { + bitset_container_t *ourbitset = CAST_bitset(*dst); + bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality); + bitset_set_list(ourbitset->words, src_2->array, src_2->cardinality); + ourbitset->cardinality = BITSET_UNKNOWN_CARDINALITY; + } + return returnval; +} + + +bool array_array_container_lazy_inplace_union( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = src_1->cardinality + src_2->cardinality; + *dst = NULL; + if (totalCardinality <= ARRAY_LAZY_LOWERBOUND) { + if(src_1->capacity < totalCardinality) { + *dst = array_container_create_given_capacity(2 * totalCardinality); // be purposefully generous + if (*dst != NULL) { + array_container_union(src_1, src_2, CAST_array(*dst)); + } else { + return true; // otherwise failure won't be caught + } + return false; // not a bitset + } else { + memmove(src_1->array + src_2->cardinality, src_1->array, src_1->cardinality * sizeof(uint16_t)); + src_1->cardinality = (int32_t)union_uint16(src_1->array + src_2->cardinality, src_1->cardinality, + src_2->array, src_2->cardinality, src_1->array); + return false; // not a bitset + } + } + *dst = bitset_container_create(); + bool returnval = true; // expect a bitset + if (*dst != NULL) { + bitset_container_t *ourbitset = CAST_bitset(*dst); + bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality); + bitset_set_list(ourbitset->words, src_2->array, src_2->cardinality); + ourbitset->cardinality = BITSET_UNKNOWN_CARDINALITY; + } + return returnval; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_union.c */ +/* begin file src/containers/mixed_xor.c */ +/* + * mixed_xor.c + */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). + * Result is true iff dst is a bitset */ +bool array_bitset_container_xor( + const array_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bitset_container_t *result = bitset_container_create(); + bitset_container_copy(src_2, result); + result->cardinality = (int32_t)bitset_flip_list_withcard( + result->words, result->cardinality, src_1->array, src_1->cardinality); + + // do required type conversions. + if (result->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(result); + bitset_container_free(result); + return false; // not bitset + } + *dst = result; + return true; // bitset +} + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. It is allowed for src_2 to be dst. This version does not + * update the cardinality of dst (it is set to BITSET_UNKNOWN_CARDINALITY). + */ + +void array_bitset_container_lazy_xor(const array_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + if (src_2 != dst) bitset_container_copy(src_2, dst); + bitset_flip_list(dst->words, src_1->array, src_1->cardinality); + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; +} + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_xor( + const run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bitset_container_t *result = bitset_container_create(); + + bitset_container_copy(src_2, result); + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + bitset_flip_range(result->words, rle.value, + rle.value + rle.length + UINT32_C(1)); + } + result->cardinality = bitset_container_compute_cardinality(result); + + if (result->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(result); + bitset_container_free(result); + return false; // not bitset + } + *dst = result; + return true; // bitset +} + +/* lazy xor. Dst is initialized and may be equal to src_2. + * Result is left as a bitset container, even if actual + * cardinality would dictate an array container. + */ + +void run_bitset_container_lazy_xor(const run_container_t *src_1, + const bitset_container_t *src_2, + bitset_container_t *dst) { + if (src_2 != dst) bitset_container_copy(src_2, dst); + for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) { + rle16_t rle = src_1->runs[rlepos]; + bitset_flip_range(dst->words, rle.value, + rle.value + rle.length + UINT32_C(1)); + } + dst->cardinality = BITSET_UNKNOWN_CARDINALITY; +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int array_run_container_xor( + const array_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + // semi following Java XOR implementation as of May 2016 + // the C OR implementation works quite differently and can return a run + // container + // TODO could optimize for full run containers. + + // use of lazy following Java impl. + const int arbitrary_threshold = 32; + if (src_1->cardinality < arbitrary_threshold) { + run_container_t *ans = run_container_create(); + array_run_container_lazy_xor(src_1, src_2, ans); // keeps runs. + uint8_t typecode_after; + *dst = + convert_run_to_efficient_container_and_free(ans, &typecode_after); + return typecode_after; + } + + int card = run_container_cardinality(src_2); + if (card <= DEFAULT_MAX_SIZE) { + // Java implementation works with the array, xoring the run elements via + // iterator + array_container_t *temp = array_container_from_run(src_2); + bool ret_is_bitset = array_array_container_xor(temp, src_1, dst); + array_container_free(temp); + return ret_is_bitset ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE; + + } else { // guess that it will end up as a bitset + bitset_container_t *result = bitset_container_from_run(src_2); + bool is_bitset = bitset_array_container_ixor(result, src_1, dst); + // any necessary type conversion has been done by the ixor + int retval = (is_bitset ? BITSET_CONTAINER_TYPE + : ARRAY_CONTAINER_TYPE); + return retval; + } +} + +/* Dst is a valid run container. (Can it be src_2? Let's say not.) + * Leaves result as run container, even if other options are + * smaller. + */ + +void array_run_container_lazy_xor(const array_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst) { + run_container_grow(dst, src_1->cardinality + src_2->n_runs, false); + int32_t rlepos = 0; + int32_t arraypos = 0; + dst->n_runs = 0; + + while ((rlepos < src_2->n_runs) && (arraypos < src_1->cardinality)) { + if (src_2->runs[rlepos].value <= src_1->array[arraypos]) { + run_container_smart_append_exclusive(dst, src_2->runs[rlepos].value, + src_2->runs[rlepos].length); + rlepos++; + } else { + run_container_smart_append_exclusive(dst, src_1->array[arraypos], + 0); + arraypos++; + } + } + while (arraypos < src_1->cardinality) { + run_container_smart_append_exclusive(dst, src_1->array[arraypos], 0); + arraypos++; + } + while (rlepos < src_2->n_runs) { + run_container_smart_append_exclusive(dst, src_2->runs[rlepos].value, + src_2->runs[rlepos].length); + rlepos++; + } +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int run_run_container_xor( + const run_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + run_container_t *ans = run_container_create(); + run_container_xor(src_1, src_2, ans); + uint8_t typecode_after; + *dst = convert_run_to_efficient_container_and_free(ans, &typecode_after); + return typecode_after; +} + +/* + * Java implementation (as of May 2016) for array_run, run_run + * and bitset_run don't do anything different for inplace. + * Could adopt the mixed_union.c approach instead (ie, using + * smart_append_exclusive) + * + */ + +bool array_array_container_xor( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = + src_1->cardinality + src_2->cardinality; // upper bound + if (totalCardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_create_given_capacity(totalCardinality); + array_container_xor(src_1, src_2, CAST_array(*dst)); + return false; // not a bitset + } + *dst = bitset_container_from_array(src_1); + bool returnval = true; // expect a bitset + bitset_container_t *ourbitset = CAST_bitset(*dst); + ourbitset->cardinality = (uint32_t)bitset_flip_list_withcard( + ourbitset->words, src_1->cardinality, src_2->array, src_2->cardinality); + if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) { + // need to convert! + *dst = array_container_from_bitset(ourbitset); + bitset_container_free(ourbitset); + returnval = false; // not going to be a bitset + } + + return returnval; +} + +bool array_array_container_lazy_xor( + const array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int totalCardinality = src_1->cardinality + src_2->cardinality; + // upper bound, but probably poor estimate for xor + if (totalCardinality <= ARRAY_LAZY_LOWERBOUND) { + *dst = array_container_create_given_capacity(totalCardinality); + if (*dst != NULL) + array_container_xor(src_1, src_2, CAST_array(*dst)); + return false; // not a bitset + } + *dst = bitset_container_from_array(src_1); + bool returnval = true; // expect a bitset (maybe, for XOR??) + if (*dst != NULL) { + bitset_container_t *ourbitset = CAST_bitset(*dst); + bitset_flip_list(ourbitset->words, src_2->array, src_2->cardinality); + ourbitset->cardinality = BITSET_UNKNOWN_CARDINALITY; + } + return returnval; +} + +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). Return value is + * "dst is a bitset" + */ + +bool bitset_bitset_container_xor( + const bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bitset_container_t *ans = bitset_container_create(); + int card = bitset_container_xor(src_1, src_2, ans); + if (card <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(ans); + bitset_container_free(ans); + return false; // not bitset + } else { + *dst = ans; + return true; + } +} + +/* Compute the xor of src_1 and src_2 and write the result to + * dst (which has no container initially). It will modify src_1 + * to be dst if the result is a bitset. Otherwise, it will + * free src_1 and dst will be a new array container. In both + * cases, the caller is responsible for deallocating dst. + * Returns true iff dst is a bitset */ + +bool bitset_array_container_ixor( + bitset_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + *dst = src_1; + src_1->cardinality = (uint32_t)bitset_flip_list_withcard( + src_1->words, src_1->cardinality, src_2->array, src_2->cardinality); + + if (src_1->cardinality <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(src_1); + bitset_container_free(src_1); + return false; // not bitset + } else + return true; +} + +/* a bunch of in-place, some of which may not *really* be inplace. + * TODO: write actual inplace routine if efficiency warrants it + * Anything inplace with a bitset is a good candidate + */ + +bool bitset_bitset_container_ixor( + bitset_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + int card = bitset_container_xor(src_1, src_2, src_1); + if (card <= DEFAULT_MAX_SIZE) { + *dst = array_container_from_bitset(src_1); + bitset_container_free(src_1); + return false; // not bitset + } else { + *dst = src_1; + return true; + } +} + +bool array_bitset_container_ixor( + array_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bool ans = array_bitset_container_xor(src_1, src_2, dst); + array_container_free(src_1); + return ans; +} + +/* Compute the xor of src_1 and src_2 and write the result to + * dst. Result may be either a bitset or an array container + * (returns "result is bitset"). dst does not initially have + * any container, but becomes either a bitset container (return + * result true) or an array container. + */ + +bool run_bitset_container_ixor( + run_container_t *src_1, const bitset_container_t *src_2, + container_t **dst +){ + bool ans = run_bitset_container_xor(src_1, src_2, dst); + run_container_free(src_1); + return ans; +} + +bool bitset_run_container_ixor( + bitset_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + bool ans = run_bitset_container_xor(src_2, src_1, dst); + bitset_container_free(src_1); + return ans; +} + +/* dst does not indicate a valid container initially. Eventually it + * can become any kind of container. + */ + +int array_run_container_ixor( + array_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + int ans = array_run_container_xor(src_1, src_2, dst); + array_container_free(src_1); + return ans; +} + +int run_array_container_ixor( + run_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + int ans = array_run_container_xor(src_2, src_1, dst); + run_container_free(src_1); + return ans; +} + +bool array_array_container_ixor( + array_container_t *src_1, const array_container_t *src_2, + container_t **dst +){ + bool ans = array_array_container_xor(src_1, src_2, dst); + array_container_free(src_1); + return ans; +} + +int run_run_container_ixor( + run_container_t *src_1, const run_container_t *src_2, + container_t **dst +){ + int ans = run_run_container_xor(src_1, src_2, dst); + run_container_free(src_1); + return ans; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/mixed_xor.c */ +/* begin file src/containers/run.c */ +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +extern inline uint16_t run_container_minimum(const run_container_t *run); +extern inline uint16_t run_container_maximum(const run_container_t *run); +extern inline int32_t interleavedBinarySearch(const rle16_t *array, + int32_t lenarray, uint16_t ikey); +extern inline bool run_container_contains(const run_container_t *run, + uint16_t pos); +extern inline int run_container_index_equalorlarger(const run_container_t *arr, uint16_t x); +extern inline bool run_container_is_full(const run_container_t *run); +extern inline bool run_container_nonzero_cardinality(const run_container_t *rc); +extern inline void run_container_clear(run_container_t *run); +extern inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs); +extern inline run_container_t *run_container_create_range(uint32_t start, + uint32_t stop); +extern inline int run_container_cardinality(const run_container_t *run); + + +bool run_container_add(run_container_t *run, uint16_t pos) { + int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos); + if (index >= 0) return false; // already there + index = -index - 2; // points to preceding value, possibly -1 + if (index >= 0) { // possible match + int32_t offset = pos - run->runs[index].value; + int32_t le = run->runs[index].length; + if (offset <= le) return false; // already there + if (offset == le + 1) { + // we may need to fuse + if (index + 1 < run->n_runs) { + if (run->runs[index + 1].value == pos + 1) { + // indeed fusion is needed + run->runs[index].length = run->runs[index + 1].value + + run->runs[index + 1].length - + run->runs[index].value; + recoverRoomAtIndex(run, (uint16_t)(index + 1)); + return true; + } + } + run->runs[index].length++; + return true; + } + if (index + 1 < run->n_runs) { + // we may need to fuse + if (run->runs[index + 1].value == pos + 1) { + // indeed fusion is needed + run->runs[index + 1].value = pos; + run->runs[index + 1].length = run->runs[index + 1].length + 1; + return true; + } + } + } + if (index == -1) { + // we may need to extend the first run + if (0 < run->n_runs) { + if (run->runs[0].value == pos + 1) { + run->runs[0].length++; + run->runs[0].value--; + return true; + } + } + } + makeRoomAtIndex(run, (uint16_t)(index + 1)); + run->runs[index + 1].value = pos; + run->runs[index + 1].length = 0; + return true; +} + +/* Create a new run container. Return NULL in case of failure. */ +run_container_t *run_container_create_given_capacity(int32_t size) { + run_container_t *run; + /* Allocate the run container itself. */ + if ((run = (run_container_t *)roaring_malloc(sizeof(run_container_t))) == NULL) { + return NULL; + } + if (size <= 0 ) { // we don't want to rely on malloc(0) + run->runs = NULL; + } else if ((run->runs = (rle16_t *)roaring_malloc(sizeof(rle16_t) * size)) == NULL) { + roaring_free(run); + return NULL; + } + run->capacity = size; + run->n_runs = 0; + return run; +} + +int run_container_shrink_to_fit(run_container_t *src) { + if (src->n_runs == src->capacity) return 0; // nothing to do + int savings = src->capacity - src->n_runs; + src->capacity = src->n_runs; + rle16_t *oldruns = src->runs; + src->runs = (rle16_t *)roaring_realloc(oldruns, src->capacity * sizeof(rle16_t)); + if (src->runs == NULL) roaring_free(oldruns); // should never happen? + return savings; +} +/* Create a new run container. Return NULL in case of failure. */ +run_container_t *run_container_create(void) { + return run_container_create_given_capacity(RUN_DEFAULT_INIT_SIZE); +} + +run_container_t *run_container_clone(const run_container_t *src) { + run_container_t *run = run_container_create_given_capacity(src->capacity); + if (run == NULL) return NULL; + run->capacity = src->capacity; + run->n_runs = src->n_runs; + memcpy(run->runs, src->runs, src->n_runs * sizeof(rle16_t)); + return run; +} + +void run_container_offset(const run_container_t *c, + container_t **loc, container_t **hic, + uint16_t offset) { + run_container_t *lo = NULL, *hi = NULL; + + bool split; + int lo_cap, hi_cap; + int top, pivot; + + top = (1 << 16) - offset; + pivot = run_container_index_equalorlarger(c, top); + + if (pivot == -1) { + split = false; + lo_cap = c->n_runs; + hi_cap = 0; + } else { + split = c->runs[pivot].value <= top; + lo_cap = pivot + (split ? 1 : 0); + hi_cap = c->n_runs - pivot; + } + + if (loc && lo_cap) { + lo = run_container_create_given_capacity(lo_cap); + memcpy(lo->runs, c->runs, lo_cap*sizeof(rle16_t)); + lo->n_runs = lo_cap; + for (int i = 0; i < lo_cap; ++i) { + lo->runs[i].value += offset; + } + *loc = (container_t*)lo; + } + + if (hic && hi_cap) { + hi = run_container_create_given_capacity(hi_cap); + memcpy(hi->runs, c->runs+pivot, hi_cap*sizeof(rle16_t)); + hi->n_runs = hi_cap; + for (int i = 0; i < hi_cap; ++i) { + hi->runs[i].value += offset; + } + *hic = (container_t*)hi; + } + + // Fix the split. + if (split) { + if (lo != NULL) { + // Add the missing run to 'lo', exhausting length. + lo->runs[lo->n_runs-1].length = (1 << 16) - lo->runs[lo->n_runs-1].value - 1; + } + + if (hi != NULL) { + // Fix the first run in 'hi'. + hi->runs[0].length -= UINT16_MAX - hi->runs[0].value + 1; + hi->runs[0].value = 0; + } + } +} + +/* Free memory. */ +void run_container_free(run_container_t *run) { + if(run->runs != NULL) {// Jon Strabala reports that some tools complain otherwise + roaring_free(run->runs); + run->runs = NULL; // pedantic + } + roaring_free(run); +} + +void run_container_grow(run_container_t *run, int32_t min, bool copy) { + int32_t newCapacity = + (run->capacity == 0) + ? RUN_DEFAULT_INIT_SIZE + : run->capacity < 64 ? run->capacity * 2 + : run->capacity < 1024 ? run->capacity * 3 / 2 + : run->capacity * 5 / 4; + if (newCapacity < min) newCapacity = min; + run->capacity = newCapacity; + assert(run->capacity >= min); + if (copy) { + rle16_t *oldruns = run->runs; + run->runs = + (rle16_t *)roaring_realloc(oldruns, run->capacity * sizeof(rle16_t)); + if (run->runs == NULL) roaring_free(oldruns); + } else { + // Jon Strabala reports that some tools complain otherwise + if (run->runs != NULL) { + roaring_free(run->runs); + } + run->runs = (rle16_t *)roaring_malloc(run->capacity * sizeof(rle16_t)); + } + // handle the case where realloc fails + if (run->runs == NULL) { + fprintf(stderr, "could not allocate memory\n"); + } + assert(run->runs != NULL); +} + +/* copy one container into another */ +void run_container_copy(const run_container_t *src, run_container_t *dst) { + const int32_t n_runs = src->n_runs; + if (src->n_runs > dst->capacity) { + run_container_grow(dst, n_runs, false); + } + dst->n_runs = n_runs; + memcpy(dst->runs, src->runs, sizeof(rle16_t) * n_runs); +} + +/* Compute the union of `src_1' and `src_2' and write the result to `dst' + * It is assumed that `dst' is distinct from both `src_1' and `src_2'. */ +void run_container_union(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst) { + // TODO: this could be a lot more efficient + + // we start out with inexpensive checks + const bool if1 = run_container_is_full(src_1); + const bool if2 = run_container_is_full(src_2); + if (if1 || if2) { + if (if1) { + run_container_copy(src_1, dst); + return; + } + if (if2) { + run_container_copy(src_2, dst); + return; + } + } + const int32_t neededcapacity = src_1->n_runs + src_2->n_runs; + if (dst->capacity < neededcapacity) + run_container_grow(dst, neededcapacity, false); + dst->n_runs = 0; + int32_t rlepos = 0; + int32_t xrlepos = 0; + + rle16_t previousrle; + if (src_1->runs[rlepos].value <= src_2->runs[xrlepos].value) { + previousrle = run_container_append_first(dst, src_1->runs[rlepos]); + rlepos++; + } else { + previousrle = run_container_append_first(dst, src_2->runs[xrlepos]); + xrlepos++; + } + + while ((xrlepos < src_2->n_runs) && (rlepos < src_1->n_runs)) { + rle16_t newrl; + if (src_1->runs[rlepos].value <= src_2->runs[xrlepos].value) { + newrl = src_1->runs[rlepos]; + rlepos++; + } else { + newrl = src_2->runs[xrlepos]; + xrlepos++; + } + run_container_append(dst, newrl, &previousrle); + } + while (xrlepos < src_2->n_runs) { + run_container_append(dst, src_2->runs[xrlepos], &previousrle); + xrlepos++; + } + while (rlepos < src_1->n_runs) { + run_container_append(dst, src_1->runs[rlepos], &previousrle); + rlepos++; + } +} + +/* Compute the union of `src_1' and `src_2' and write the result to `src_1' + */ +void run_container_union_inplace(run_container_t *src_1, + const run_container_t *src_2) { + // TODO: this could be a lot more efficient + + // we start out with inexpensive checks + const bool if1 = run_container_is_full(src_1); + const bool if2 = run_container_is_full(src_2); + if (if1 || if2) { + if (if1) { + return; + } + if (if2) { + run_container_copy(src_2, src_1); + return; + } + } + // we move the data to the end of the current array + const int32_t maxoutput = src_1->n_runs + src_2->n_runs; + const int32_t neededcapacity = maxoutput + src_1->n_runs; + if (src_1->capacity < neededcapacity) + run_container_grow(src_1, neededcapacity, true); + memmove(src_1->runs + maxoutput, src_1->runs, + src_1->n_runs * sizeof(rle16_t)); + rle16_t *inputsrc1 = src_1->runs + maxoutput; + const int32_t input1nruns = src_1->n_runs; + src_1->n_runs = 0; + int32_t rlepos = 0; + int32_t xrlepos = 0; + + rle16_t previousrle; + if (inputsrc1[rlepos].value <= src_2->runs[xrlepos].value) { + previousrle = run_container_append_first(src_1, inputsrc1[rlepos]); + rlepos++; + } else { + previousrle = run_container_append_first(src_1, src_2->runs[xrlepos]); + xrlepos++; + } + while ((xrlepos < src_2->n_runs) && (rlepos < input1nruns)) { + rle16_t newrl; + if (inputsrc1[rlepos].value <= src_2->runs[xrlepos].value) { + newrl = inputsrc1[rlepos]; + rlepos++; + } else { + newrl = src_2->runs[xrlepos]; + xrlepos++; + } + run_container_append(src_1, newrl, &previousrle); + } + while (xrlepos < src_2->n_runs) { + run_container_append(src_1, src_2->runs[xrlepos], &previousrle); + xrlepos++; + } + while (rlepos < input1nruns) { + run_container_append(src_1, inputsrc1[rlepos], &previousrle); + rlepos++; + } +} + +/* Compute the symmetric difference of `src_1' and `src_2' and write the result + * to `dst' + * It is assumed that `dst' is distinct from both `src_1' and `src_2'. */ +void run_container_xor(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst) { + // don't bother to convert xor with full range into negation + // since negation is implemented similarly + + const int32_t neededcapacity = src_1->n_runs + src_2->n_runs; + if (dst->capacity < neededcapacity) + run_container_grow(dst, neededcapacity, false); + + int32_t pos1 = 0; + int32_t pos2 = 0; + dst->n_runs = 0; + + while ((pos1 < src_1->n_runs) && (pos2 < src_2->n_runs)) { + if (src_1->runs[pos1].value <= src_2->runs[pos2].value) { + run_container_smart_append_exclusive(dst, src_1->runs[pos1].value, + src_1->runs[pos1].length); + pos1++; + } else { + run_container_smart_append_exclusive(dst, src_2->runs[pos2].value, + src_2->runs[pos2].length); + pos2++; + } + } + while (pos1 < src_1->n_runs) { + run_container_smart_append_exclusive(dst, src_1->runs[pos1].value, + src_1->runs[pos1].length); + pos1++; + } + + while (pos2 < src_2->n_runs) { + run_container_smart_append_exclusive(dst, src_2->runs[pos2].value, + src_2->runs[pos2].length); + pos2++; + } +} + +/* Compute the intersection of src_1 and src_2 and write the result to + * dst. It is assumed that dst is distinct from both src_1 and src_2. */ +void run_container_intersection(const run_container_t *src_1, + const run_container_t *src_2, + run_container_t *dst) { + const bool if1 = run_container_is_full(src_1); + const bool if2 = run_container_is_full(src_2); + if (if1 || if2) { + if (if1) { + run_container_copy(src_2, dst); + return; + } + if (if2) { + run_container_copy(src_1, dst); + return; + } + } + // TODO: this could be a lot more efficient, could use SIMD optimizations + const int32_t neededcapacity = src_1->n_runs + src_2->n_runs; + if (dst->capacity < neededcapacity) + run_container_grow(dst, neededcapacity, false); + dst->n_runs = 0; + int32_t rlepos = 0; + int32_t xrlepos = 0; + int32_t start = src_1->runs[rlepos].value; + int32_t end = start + src_1->runs[rlepos].length + 1; + int32_t xstart = src_2->runs[xrlepos].value; + int32_t xend = xstart + src_2->runs[xrlepos].length + 1; + while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) { + if (end <= xstart) { + ++rlepos; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + } else if (xend <= start) { + ++xrlepos; + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } else { // they overlap + const int32_t lateststart = start > xstart ? start : xstart; + int32_t earliestend; + if (end == xend) { // improbable + earliestend = end; + rlepos++; + xrlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } else if (end < xend) { + earliestend = end; + rlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + + } else { // end > xend + earliestend = xend; + xrlepos++; + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } + dst->runs[dst->n_runs].value = (uint16_t)lateststart; + dst->runs[dst->n_runs].length = + (uint16_t)(earliestend - lateststart - 1); + dst->n_runs++; + } + } +} + +/* Compute the size of the intersection of src_1 and src_2 . */ +int run_container_intersection_cardinality(const run_container_t *src_1, + const run_container_t *src_2) { + const bool if1 = run_container_is_full(src_1); + const bool if2 = run_container_is_full(src_2); + if (if1 || if2) { + if (if1) { + return run_container_cardinality(src_2); + } + if (if2) { + return run_container_cardinality(src_1); + } + } + int answer = 0; + int32_t rlepos = 0; + int32_t xrlepos = 0; + int32_t start = src_1->runs[rlepos].value; + int32_t end = start + src_1->runs[rlepos].length + 1; + int32_t xstart = src_2->runs[xrlepos].value; + int32_t xend = xstart + src_2->runs[xrlepos].length + 1; + while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) { + if (end <= xstart) { + ++rlepos; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + } else if (xend <= start) { + ++xrlepos; + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } else { // they overlap + const int32_t lateststart = start > xstart ? start : xstart; + int32_t earliestend; + if (end == xend) { // improbable + earliestend = end; + rlepos++; + xrlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } else if (end < xend) { + earliestend = end; + rlepos++; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + + } else { // end > xend + earliestend = xend; + xrlepos++; + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } + answer += earliestend - lateststart; + } + } + return answer; +} + +bool run_container_intersect(const run_container_t *src_1, + const run_container_t *src_2) { + const bool if1 = run_container_is_full(src_1); + const bool if2 = run_container_is_full(src_2); + if (if1 || if2) { + if (if1) { + return !run_container_empty(src_2); + } + if (if2) { + return !run_container_empty(src_1); + } + } + int32_t rlepos = 0; + int32_t xrlepos = 0; + int32_t start = src_1->runs[rlepos].value; + int32_t end = start + src_1->runs[rlepos].length + 1; + int32_t xstart = src_2->runs[xrlepos].value; + int32_t xend = xstart + src_2->runs[xrlepos].length + 1; + while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) { + if (end <= xstart) { + ++rlepos; + if (rlepos < src_1->n_runs) { + start = src_1->runs[rlepos].value; + end = start + src_1->runs[rlepos].length + 1; + } + } else if (xend <= start) { + ++xrlepos; + if (xrlepos < src_2->n_runs) { + xstart = src_2->runs[xrlepos].value; + xend = xstart + src_2->runs[xrlepos].length + 1; + } + } else { // they overlap + return true; + } + } + return false; +} + + +/* Compute the difference of src_1 and src_2 and write the result to + * dst. It is assumed that dst is distinct from both src_1 and src_2. */ +void run_container_andnot(const run_container_t *src_1, + const run_container_t *src_2, run_container_t *dst) { + // following Java implementation as of June 2016 + + if (dst->capacity < src_1->n_runs + src_2->n_runs) + run_container_grow(dst, src_1->n_runs + src_2->n_runs, false); + + dst->n_runs = 0; + + int rlepos1 = 0; + int rlepos2 = 0; + int32_t start = src_1->runs[rlepos1].value; + int32_t end = start + src_1->runs[rlepos1].length + 1; + int32_t start2 = src_2->runs[rlepos2].value; + int32_t end2 = start2 + src_2->runs[rlepos2].length + 1; + + while ((rlepos1 < src_1->n_runs) && (rlepos2 < src_2->n_runs)) { + if (end <= start2) { + // output the first run + dst->runs[dst->n_runs++] = MAKE_RLE16(start, end - start - 1); + rlepos1++; + if (rlepos1 < src_1->n_runs) { + start = src_1->runs[rlepos1].value; + end = start + src_1->runs[rlepos1].length + 1; + } + } else if (end2 <= start) { + // exit the second run + rlepos2++; + if (rlepos2 < src_2->n_runs) { + start2 = src_2->runs[rlepos2].value; + end2 = start2 + src_2->runs[rlepos2].length + 1; + } + } else { + if (start < start2) { + dst->runs[dst->n_runs++] = + MAKE_RLE16(start, start2 - start - 1); + } + if (end2 < end) { + start = end2; + } else { + rlepos1++; + if (rlepos1 < src_1->n_runs) { + start = src_1->runs[rlepos1].value; + end = start + src_1->runs[rlepos1].length + 1; + } + } + } + } + if (rlepos1 < src_1->n_runs) { + dst->runs[dst->n_runs++] = MAKE_RLE16(start, end - start - 1); + rlepos1++; + if (rlepos1 < src_1->n_runs) { + memcpy(dst->runs + dst->n_runs, src_1->runs + rlepos1, + sizeof(rle16_t) * (src_1->n_runs - rlepos1)); + dst->n_runs += src_1->n_runs - rlepos1; + } + } +} + +int run_container_to_uint32_array(void *vout, const run_container_t *cont, + uint32_t base) { + int outpos = 0; + uint32_t *out = (uint32_t *)vout; + for (int i = 0; i < cont->n_runs; ++i) { + uint32_t run_start = base + cont->runs[i].value; + uint16_t le = cont->runs[i].length; + for (int j = 0; j <= le; ++j) { + uint32_t val = run_start + j; + memcpy(out + outpos, &val, + sizeof(uint32_t)); // should be compiled as a MOV on x64 + outpos++; + } + } + return outpos; +} + +/* + * Print this container using printf (useful for debugging). + */ +void run_container_printf(const run_container_t *cont) { + for (int i = 0; i < cont->n_runs; ++i) { + uint16_t run_start = cont->runs[i].value; + uint16_t le = cont->runs[i].length; + printf("[%d,%d]", run_start, run_start + le); + } +} + +/* + * Print this container using printf as a comma-separated list of 32-bit + * integers starting at base. + */ +void run_container_printf_as_uint32_array(const run_container_t *cont, + uint32_t base) { + if (cont->n_runs == 0) return; + { + uint32_t run_start = base + cont->runs[0].value; + uint16_t le = cont->runs[0].length; + printf("%u", run_start); + for (uint32_t j = 1; j <= le; ++j) printf(",%u", run_start + j); + } + for (int32_t i = 1; i < cont->n_runs; ++i) { + uint32_t run_start = base + cont->runs[i].value; + uint16_t le = cont->runs[i].length; + for (uint32_t j = 0; j <= le; ++j) printf(",%u", run_start + j); + } +} + +int32_t run_container_write(const run_container_t *container, char *buf) { + memcpy(buf, &container->n_runs, sizeof(uint16_t)); + memcpy(buf + sizeof(uint16_t), container->runs, + container->n_runs * sizeof(rle16_t)); + return run_container_size_in_bytes(container); +} + +int32_t run_container_read(int32_t cardinality, run_container_t *container, + const char *buf) { + (void)cardinality; + memcpy(&container->n_runs, buf, sizeof(uint16_t)); + if (container->n_runs > container->capacity) + run_container_grow(container, container->n_runs, false); + if(container->n_runs > 0) { + memcpy(container->runs, buf + sizeof(uint16_t), + container->n_runs * sizeof(rle16_t)); + } + return run_container_size_in_bytes(container); +} + +bool run_container_iterate(const run_container_t *cont, uint32_t base, + roaring_iterator iterator, void *ptr) { + for (int i = 0; i < cont->n_runs; ++i) { + uint32_t run_start = base + cont->runs[i].value; + uint16_t le = cont->runs[i].length; + + for (int j = 0; j <= le; ++j) + if (!iterator(run_start + j, ptr)) return false; + } + return true; +} + +bool run_container_iterate64(const run_container_t *cont, uint32_t base, + roaring_iterator64 iterator, uint64_t high_bits, + void *ptr) { + for (int i = 0; i < cont->n_runs; ++i) { + uint32_t run_start = base + cont->runs[i].value; + uint16_t le = cont->runs[i].length; + + for (int j = 0; j <= le; ++j) + if (!iterator(high_bits | (uint64_t)(run_start + j), ptr)) + return false; + } + return true; +} + +bool run_container_is_subset(const run_container_t *container1, + const run_container_t *container2) { + int i1 = 0, i2 = 0; + while (i1 < container1->n_runs && i2 < container2->n_runs) { + int start1 = container1->runs[i1].value; + int stop1 = start1 + container1->runs[i1].length; + int start2 = container2->runs[i2].value; + int stop2 = start2 + container2->runs[i2].length; + if (start1 < start2) { + return false; + } else { // start1 >= start2 + if (stop1 < stop2) { + i1++; + } else if (stop1 == stop2) { + i1++; + i2++; + } else { // stop1 > stop2 + i2++; + } + } + } + if (i1 == container1->n_runs) { + return true; + } else { + return false; + } +} + +// TODO: write smart_append_exclusive version to match the overloaded 1 param +// Java version (or is it even used?) + +// follows the Java implementation closely +// length is the rle-value. Ie, run [10,12) uses a length value 1. +void run_container_smart_append_exclusive(run_container_t *src, + const uint16_t start, + const uint16_t length) { + int old_end; + rle16_t *last_run = src->n_runs ? src->runs + (src->n_runs - 1) : NULL; + rle16_t *appended_last_run = src->runs + src->n_runs; + + if (!src->n_runs || + (start > (old_end = last_run->value + last_run->length + 1))) { + *appended_last_run = MAKE_RLE16(start, length); + src->n_runs++; + return; + } + if (old_end == start) { + // we merge + last_run->length += (length + 1); + return; + } + int new_end = start + length + 1; + + if (start == last_run->value) { + // wipe out previous + if (new_end < old_end) { + *last_run = MAKE_RLE16(new_end, old_end - new_end - 1); + return; + } else if (new_end > old_end) { + *last_run = MAKE_RLE16(old_end, new_end - old_end - 1); + return; + } else { + src->n_runs--; + return; + } + } + last_run->length = start - last_run->value - 1; + if (new_end < old_end) { + *appended_last_run = MAKE_RLE16(new_end, old_end - new_end - 1); + src->n_runs++; + } else if (new_end > old_end) { + *appended_last_run = MAKE_RLE16(old_end, new_end - old_end - 1); + src->n_runs++; + } +} + +bool run_container_select(const run_container_t *container, + uint32_t *start_rank, uint32_t rank, + uint32_t *element) { + for (int i = 0; i < container->n_runs; i++) { + uint16_t length = container->runs[i].length; + if (rank <= *start_rank + length) { + uint16_t value = container->runs[i].value; + *element = value + rank - (*start_rank); + return true; + } else + *start_rank += length + 1; + } + return false; +} + +int run_container_rank(const run_container_t *container, uint16_t x) { + int sum = 0; + uint32_t x32 = x; + for (int i = 0; i < container->n_runs; i++) { + uint32_t startpoint = container->runs[i].value; + uint32_t length = container->runs[i].length; + uint32_t endpoint = length + startpoint; + if (x <= endpoint) { + if (x < startpoint) break; + return sum + (x32 - startpoint) + 1; + } else { + sum += length + 1; + } + } + return sum; +} + +#ifdef CROARING_IS_X64 + +CROARING_TARGET_AVX2 +/* Get the cardinality of `run'. Requires an actual computation. */ +static inline int _avx2_run_container_cardinality(const run_container_t *run) { + const int32_t n_runs = run->n_runs; + const rle16_t *runs = run->runs; + + /* by initializing with n_runs, we omit counting the +1 for each pair. */ + int sum = n_runs; + int32_t k = 0; + const int32_t step = sizeof(__m256i) / sizeof(rle16_t); + if (n_runs > step) { + __m256i total = _mm256_setzero_si256(); + for (; k + step <= n_runs; k += step) { + __m256i ymm1 = _mm256_lddqu_si256((const __m256i *)(runs + k)); + __m256i justlengths = _mm256_srli_epi32(ymm1, 16); + total = _mm256_add_epi32(total, justlengths); + } + // a store might be faster than extract? + uint32_t buffer[sizeof(__m256i) / sizeof(rle16_t)]; + _mm256_storeu_si256((__m256i *)buffer, total); + sum += (buffer[0] + buffer[1]) + (buffer[2] + buffer[3]) + + (buffer[4] + buffer[5]) + (buffer[6] + buffer[7]); + } + for (; k < n_runs; ++k) { + sum += runs[k].length; + } + + return sum; +} + +CROARING_UNTARGET_REGION + +/* Get the cardinality of `run'. Requires an actual computation. */ +static inline int _scalar_run_container_cardinality(const run_container_t *run) { + const int32_t n_runs = run->n_runs; + const rle16_t *runs = run->runs; + + /* by initializing with n_runs, we omit counting the +1 for each pair. */ + int sum = n_runs; + for (int k = 0; k < n_runs; ++k) { + sum += runs[k].length; + } + + return sum; +} + +int run_container_cardinality(const run_container_t *run) { + if( croaring_avx2() ) { + return _avx2_run_container_cardinality(run); + } else { + return _scalar_run_container_cardinality(run); + } +} +#else + +/* Get the cardinality of `run'. Requires an actual computation. */ +int run_container_cardinality(const run_container_t *run) { + const int32_t n_runs = run->n_runs; + const rle16_t *runs = run->runs; + + /* by initializing with n_runs, we omit counting the +1 for each pair. */ + int sum = n_runs; + for (int k = 0; k < n_runs; ++k) { + sum += runs[k].length; + } + + return sum; +} +#endif + + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/containers/run.c */ +/* begin file src/memory.c */ +#include + +// without the following, we get lots of warnings about posix_memalign +#ifndef __cplusplus +extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size); +#endif //__cplusplus // C++ does not have a well defined signature + +// portable version of posix_memalign +static void *roaring_bitmap_aligned_malloc(size_t alignment, size_t size) { + void *p; +#ifdef _MSC_VER + p = _aligned_malloc(size, alignment); +#elif defined(__MINGW32__) || defined(__MINGW64__) + p = __mingw_aligned_malloc(size, alignment); +#else + // somehow, if this is used before including "x86intrin.h", it creates an + // implicit defined warning. + if (posix_memalign(&p, alignment, size) != 0) return NULL; +#endif + return p; +} + +static void roaring_bitmap_aligned_free(void *memblock) { +#ifdef _MSC_VER + _aligned_free(memblock); +#elif defined(__MINGW32__) || defined(__MINGW64__) + __mingw_aligned_free(memblock); +#else + free(memblock); +#endif +} + +static roaring_memory_t global_memory_hook = { + .malloc = malloc, + .realloc = realloc, + .calloc = calloc, + .free = free, + .aligned_malloc = roaring_bitmap_aligned_malloc, + .aligned_free = roaring_bitmap_aligned_free, +}; + +void roaring_init_memory_hook(roaring_memory_t memory_hook) { + global_memory_hook = memory_hook; +} + +void* roaring_malloc(size_t n) { + return global_memory_hook.malloc(n); +} + +void* roaring_realloc(void* p, size_t new_sz) { + return global_memory_hook.realloc(p, new_sz); +} + +void* roaring_calloc(size_t n_elements, size_t element_size) { + return global_memory_hook.calloc(n_elements, element_size); +} + +void roaring_free(void* p) { + global_memory_hook.free(p); +} + +void* roaring_aligned_malloc(size_t alignment, size_t size) { + return global_memory_hook.aligned_malloc(alignment, size); +} + +void roaring_aligned_free(void* p) { + global_memory_hook.aligned_free(p); +} +/* end file src/memory.c */ +/* begin file src/roaring.c */ +#include +#include +#include +#include +#include +#include + + + +#ifdef __cplusplus +using namespace ::roaring::internal; + +extern "C" { namespace roaring { namespace api { +#endif + +#define CROARING_SERIALIZATION_ARRAY_UINT32 1 +#define CROARING_SERIALIZATION_CONTAINER 2 + +extern inline bool roaring_bitmap_get_copy_on_write(const roaring_bitmap_t* r); +extern inline void roaring_bitmap_set_copy_on_write(roaring_bitmap_t* r, bool cow); + +static inline bool is_cow(const roaring_bitmap_t *r) { + return r->high_low_container.flags & ROARING_FLAG_COW; +} +static inline bool is_frozen(const roaring_bitmap_t *r) { + return r->high_low_container.flags & ROARING_FLAG_FROZEN; +} + +// this is like roaring_bitmap_add, but it populates pointer arguments in such a +// way +// that we can recover the container touched, which, in turn can be used to +// accelerate some functions (when you repeatedly need to add to the same +// container) +static inline container_t *containerptr_roaring_bitmap_add( + roaring_bitmap_t *r, uint32_t val, + uint8_t *type, int *index +){ + roaring_array_t *ra = &r->high_low_container; + + uint16_t hb = val >> 16; + const int i = ra_get_index(ra, hb); + if (i >= 0) { + ra_unshare_container_at_index(ra, i); + container_t *c = ra_get_container_at_index(ra, i, type); + uint8_t new_type = *type; + container_t *c2 = container_add(c, val & 0xFFFF, *type, &new_type); + *index = i; + if (c2 != c) { + container_free(c, *type); + ra_set_container_at_index(ra, i, c2, new_type); + *type = new_type; + return c2; + } else { + return c; + } + } else { + array_container_t *new_ac = array_container_create(); + container_t *c = container_add(new_ac, val & 0xFFFF, + ARRAY_CONTAINER_TYPE, type); + // we could just assume that it stays an array container + ra_insert_new_key_value_at(ra, -i - 1, hb, c, *type); + *index = -i - 1; + return c; + } +} + +roaring_bitmap_t *roaring_bitmap_create_with_capacity(uint32_t cap) { + roaring_bitmap_t *ans = + (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t)); + if (!ans) { + return NULL; + } + bool is_ok = ra_init_with_capacity(&ans->high_low_container, cap); + if (!is_ok) { + roaring_free(ans); + return NULL; + } + return ans; +} + +bool roaring_bitmap_init_with_capacity(roaring_bitmap_t *r, uint32_t cap) { + return ra_init_with_capacity(&r->high_low_container, cap); +} + + +void roaring_bitmap_add_many(roaring_bitmap_t *r, size_t n_args, + const uint32_t *vals) { + container_t *container = NULL; // hold value of last container touched + uint8_t typecode = 0; // typecode of last container touched + uint32_t prev = 0; // previous valued inserted + size_t i = 0; // index of value + int containerindex = 0; + if (n_args == 0) return; + uint32_t val; + memcpy(&val, vals + i, sizeof(val)); + container = + containerptr_roaring_bitmap_add(r, val, &typecode, &containerindex); + prev = val; + i++; + for (; i < n_args; i++) { + memcpy(&val, vals + i, sizeof(val)); + if (((prev ^ val) >> 16) == + 0) { // no need to seek the container, it is at hand + // because we already have the container at hand, we can do the + // insertion + // automatically, bypassing the roaring_bitmap_add call + uint8_t newtypecode = typecode; + container_t *container2 = + container_add(container, val & 0xFFFF, typecode, &newtypecode); + if (container2 != container) { // rare instance when we need to + // change the container type + container_free(container, typecode); + ra_set_container_at_index(&r->high_low_container, + containerindex, container2, + newtypecode); + typecode = newtypecode; + container = container2; + } + } else { + container = containerptr_roaring_bitmap_add(r, val, &typecode, + &containerindex); + } + prev = val; + } +} + +roaring_bitmap_t *roaring_bitmap_of_ptr(size_t n_args, const uint32_t *vals) { + roaring_bitmap_t *answer = roaring_bitmap_create(); + roaring_bitmap_add_many(answer, n_args, vals); + return answer; +} + +roaring_bitmap_t *roaring_bitmap_of(size_t n_args, ...) { + // todo: could be greatly optimized but we do not expect this call to ever + // include long lists + roaring_bitmap_t *answer = roaring_bitmap_create(); + va_list ap; + va_start(ap, n_args); + for (size_t i = 1; i <= n_args; i++) { + uint32_t val = va_arg(ap, uint32_t); + roaring_bitmap_add(answer, val); + } + va_end(ap); + return answer; +} + +static inline uint32_t minimum_uint32(uint32_t a, uint32_t b) { + return (a < b) ? a : b; +} + +static inline uint64_t minimum_uint64(uint64_t a, uint64_t b) { + return (a < b) ? a : b; +} + +roaring_bitmap_t *roaring_bitmap_from_range(uint64_t min, uint64_t max, + uint32_t step) { + if(max >= UINT64_C(0x100000000)) { + max = UINT64_C(0x100000000); + } + if (step == 0) return NULL; + if (max <= min) return NULL; + roaring_bitmap_t *answer = roaring_bitmap_create(); + if (step >= (1 << 16)) { + for (uint32_t value = (uint32_t)min; value < max; value += step) { + roaring_bitmap_add(answer, value); + } + return answer; + } + uint64_t min_tmp = min; + do { + uint32_t key = (uint32_t)min_tmp >> 16; + uint32_t container_min = min_tmp & 0xFFFF; + uint32_t container_max = (uint32_t)minimum_uint64(max - (key << 16), 1 << 16); + uint8_t type; + container_t *container = container_from_range(&type, container_min, + container_max, (uint16_t)step); + ra_append(&answer->high_low_container, key, container, type); + uint32_t gap = container_max - container_min + step - 1; + min_tmp += gap - (gap % step); + } while (min_tmp < max); + // cardinality of bitmap will be ((uint64_t) max - min + step - 1 ) / step + return answer; +} + +void roaring_bitmap_add_range_closed(roaring_bitmap_t *r, uint32_t min, uint32_t max) { + if (min > max) { + return; + } + + roaring_array_t *ra = &r->high_low_container; + + uint32_t min_key = min >> 16; + uint32_t max_key = max >> 16; + + int32_t num_required_containers = max_key - min_key + 1; + int32_t suffix_length = count_greater(ra->keys, ra->size, max_key); + int32_t prefix_length = count_less(ra->keys, ra->size - suffix_length, + min_key); + int32_t common_length = ra->size - prefix_length - suffix_length; + + if (num_required_containers > common_length) { + ra_shift_tail(ra, suffix_length, + num_required_containers - common_length); + } + + int32_t src = prefix_length + common_length - 1; + int32_t dst = ra->size - suffix_length - 1; + for (uint32_t key = max_key; key != min_key-1; key--) { // beware of min_key==0 + uint32_t container_min = (min_key == key) ? (min & 0xffff) : 0; + uint32_t container_max = (max_key == key) ? (max & 0xffff) : 0xffff; + container_t* new_container; + uint8_t new_type; + + if (src >= 0 && ra->keys[src] == key) { + ra_unshare_container_at_index(ra, src); + new_container = container_add_range(ra->containers[src], + ra->typecodes[src], + container_min, container_max, + &new_type); + if (new_container != ra->containers[src]) { + container_free(ra->containers[src], + ra->typecodes[src]); + } + src--; + } else { + new_container = container_from_range(&new_type, container_min, + container_max+1, 1); + } + ra_replace_key_and_container_at_index(ra, dst, key, new_container, + new_type); + dst--; + } +} + +void roaring_bitmap_remove_range_closed(roaring_bitmap_t *r, uint32_t min, uint32_t max) { + if (min > max) { + return; + } + + roaring_array_t *ra = &r->high_low_container; + + uint32_t min_key = min >> 16; + uint32_t max_key = max >> 16; + + int32_t src = count_less(ra->keys, ra->size, min_key); + int32_t dst = src; + while (src < ra->size && ra->keys[src] <= max_key) { + uint32_t container_min = (min_key == ra->keys[src]) ? (min & 0xffff) : 0; + uint32_t container_max = (max_key == ra->keys[src]) ? (max & 0xffff) : 0xffff; + ra_unshare_container_at_index(ra, src); + container_t *new_container; + uint8_t new_type; + new_container = container_remove_range(ra->containers[src], + ra->typecodes[src], + container_min, container_max, + &new_type); + if (new_container != ra->containers[src]) { + container_free(ra->containers[src], + ra->typecodes[src]); + } + if (new_container) { + ra_replace_key_and_container_at_index(ra, dst, ra->keys[src], + new_container, new_type); + dst++; + } + src++; + } + if (src > dst) { + ra_shift_tail(ra, ra->size - src, dst - src); + } +} + +extern inline void roaring_bitmap_add_range(roaring_bitmap_t *r, uint64_t min, uint64_t max); +extern inline void roaring_bitmap_remove_range(roaring_bitmap_t *r, uint64_t min, uint64_t max); + +void roaring_bitmap_printf(const roaring_bitmap_t *r) { + const roaring_array_t *ra = &r->high_low_container; + + printf("{"); + for (int i = 0; i < ra->size; ++i) { + container_printf_as_uint32_array(ra->containers[i], ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16); + + if (i + 1 < ra->size) { + printf(","); + } + } + printf("}"); +} + +void roaring_bitmap_printf_describe(const roaring_bitmap_t *r) { + const roaring_array_t *ra = &r->high_low_container; + + printf("{"); + for (int i = 0; i < ra->size; ++i) { + printf("%d: %s (%d)", ra->keys[i], + get_full_container_name(ra->containers[i], ra->typecodes[i]), + container_get_cardinality(ra->containers[i], ra->typecodes[i])); + if (ra->typecodes[i] == SHARED_CONTAINER_TYPE) { + printf( + "(shared count = %" PRIu32 " )", + CAST_shared(ra->containers[i])->counter); + } + + if (i + 1 < ra->size) { + printf(", "); + } + } + printf("}"); +} + +typedef struct min_max_sum_s { + uint32_t min; + uint32_t max; + uint64_t sum; +} min_max_sum_t; + +static bool min_max_sum_fnc(uint32_t value, void *param) { + min_max_sum_t *mms = (min_max_sum_t *)param; + if (value > mms->max) mms->max = value; + if (value < mms->min) mms->min = value; + mms->sum += value; + return true; // we always process all data points +} + +/** +* (For advanced users.) +* Collect statistics about the bitmap +*/ +void roaring_bitmap_statistics(const roaring_bitmap_t *r, + roaring_statistics_t *stat) { + const roaring_array_t *ra = &r->high_low_container; + + memset(stat, 0, sizeof(*stat)); + stat->n_containers = ra->size; + stat->cardinality = roaring_bitmap_get_cardinality(r); + min_max_sum_t mms; + mms.min = UINT32_C(0xFFFFFFFF); + mms.max = UINT32_C(0); + mms.sum = 0; + roaring_iterate(r, &min_max_sum_fnc, &mms); + stat->min_value = mms.min; + stat->max_value = mms.max; + stat->sum_value = mms.sum; + + for (int i = 0; i < ra->size; ++i) { + uint8_t truetype = + get_container_type(ra->containers[i], ra->typecodes[i]); + uint32_t card = + container_get_cardinality(ra->containers[i], ra->typecodes[i]); + uint32_t sbytes = + container_size_in_bytes(ra->containers[i], ra->typecodes[i]); + switch (truetype) { + case BITSET_CONTAINER_TYPE: + stat->n_bitset_containers++; + stat->n_values_bitset_containers += card; + stat->n_bytes_bitset_containers += sbytes; + break; + case ARRAY_CONTAINER_TYPE: + stat->n_array_containers++; + stat->n_values_array_containers += card; + stat->n_bytes_array_containers += sbytes; + break; + case RUN_CONTAINER_TYPE: + stat->n_run_containers++; + stat->n_values_run_containers += card; + stat->n_bytes_run_containers += sbytes; + break; + default: + assert(false); + __builtin_unreachable(); + } + } +} + +roaring_bitmap_t *roaring_bitmap_copy(const roaring_bitmap_t *r) { + roaring_bitmap_t *ans = + (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t)); + if (!ans) { + return NULL; + } + if (!ra_init_with_capacity( // allocation of list of containers can fail + &ans->high_low_container, r->high_low_container.size) + ){ + roaring_free(ans); + return NULL; + } + if (!ra_overwrite( // memory allocation of individual containers may fail + &r->high_low_container, &ans->high_low_container, is_cow(r)) + ){ + roaring_bitmap_free(ans); // overwrite should leave in freeable state + return NULL; + } + roaring_bitmap_set_copy_on_write(ans, is_cow(r)); + return ans; +} + +bool roaring_bitmap_overwrite(roaring_bitmap_t *dest, + const roaring_bitmap_t *src) { + roaring_bitmap_set_copy_on_write(dest, is_cow(src)); + return ra_overwrite(&src->high_low_container, &dest->high_low_container, + is_cow(src)); +} + +void roaring_bitmap_free(const roaring_bitmap_t *r) { + if (!is_frozen(r)) { + ra_clear((roaring_array_t*)&r->high_low_container); + } + roaring_free((roaring_bitmap_t*)r); +} + +void roaring_bitmap_clear(roaring_bitmap_t *r) { + ra_reset(&r->high_low_container); +} + +void roaring_bitmap_add(roaring_bitmap_t *r, uint32_t val) { + roaring_array_t *ra = &r->high_low_container; + + const uint16_t hb = val >> 16; + const int i = ra_get_index(ra, hb); + uint8_t typecode; + if (i >= 0) { + ra_unshare_container_at_index(ra, i); + container_t *container = + ra_get_container_at_index(ra, i, &typecode); + uint8_t newtypecode = typecode; + container_t *container2 = + container_add(container, val & 0xFFFF, typecode, &newtypecode); + if (container2 != container) { + container_free(container, typecode); + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + } + } else { + array_container_t *newac = array_container_create(); + container_t *container = container_add(newac, val & 0xFFFF, + ARRAY_CONTAINER_TYPE, &typecode); + // we could just assume that it stays an array container + ra_insert_new_key_value_at(&r->high_low_container, -i - 1, hb, + container, typecode); + } +} + +bool roaring_bitmap_add_checked(roaring_bitmap_t *r, uint32_t val) { + const uint16_t hb = val >> 16; + const int i = ra_get_index(&r->high_low_container, hb); + uint8_t typecode; + bool result = false; + if (i >= 0) { + ra_unshare_container_at_index(&r->high_low_container, i); + container_t *container = + ra_get_container_at_index(&r->high_low_container, i, &typecode); + + const int oldCardinality = + container_get_cardinality(container, typecode); + + uint8_t newtypecode = typecode; + container_t *container2 = + container_add(container, val & 0xFFFF, typecode, &newtypecode); + if (container2 != container) { + container_free(container, typecode); + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + result = true; + } else { + const int newCardinality = + container_get_cardinality(container, newtypecode); + + result = oldCardinality != newCardinality; + } + } else { + array_container_t *newac = array_container_create(); + container_t *container = container_add(newac, val & 0xFFFF, + ARRAY_CONTAINER_TYPE, &typecode); + // we could just assume that it stays an array container + ra_insert_new_key_value_at(&r->high_low_container, -i - 1, hb, + container, typecode); + result = true; + } + + return result; +} + +void roaring_bitmap_remove(roaring_bitmap_t *r, uint32_t val) { + const uint16_t hb = val >> 16; + const int i = ra_get_index(&r->high_low_container, hb); + uint8_t typecode; + if (i >= 0) { + ra_unshare_container_at_index(&r->high_low_container, i); + container_t *container = + ra_get_container_at_index(&r->high_low_container, i, &typecode); + uint8_t newtypecode = typecode; + container_t *container2 = + container_remove(container, val & 0xFFFF, typecode, &newtypecode); + if (container2 != container) { + container_free(container, typecode); + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + } + if (container_get_cardinality(container2, newtypecode) != 0) { + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + } else { + ra_remove_at_index_and_free(&r->high_low_container, i); + } + } +} + +bool roaring_bitmap_remove_checked(roaring_bitmap_t *r, uint32_t val) { + const uint16_t hb = val >> 16; + const int i = ra_get_index(&r->high_low_container, hb); + uint8_t typecode; + bool result = false; + if (i >= 0) { + ra_unshare_container_at_index(&r->high_low_container, i); + container_t *container = + ra_get_container_at_index(&r->high_low_container, i, &typecode); + + const int oldCardinality = + container_get_cardinality(container, typecode); + + uint8_t newtypecode = typecode; + container_t *container2 = + container_remove(container, val & 0xFFFF, typecode, &newtypecode); + if (container2 != container) { + container_free(container, typecode); + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + } + + const int newCardinality = + container_get_cardinality(container2, newtypecode); + + if (newCardinality != 0) { + ra_set_container_at_index(&r->high_low_container, i, container2, + newtypecode); + } else { + ra_remove_at_index_and_free(&r->high_low_container, i); + } + + result = oldCardinality != newCardinality; + } + return result; +} + +void roaring_bitmap_remove_many(roaring_bitmap_t *r, size_t n_args, + const uint32_t *vals) { + if (n_args == 0 || r->high_low_container.size == 0) { + return; + } + int32_t pos = -1; // position of the container used in the previous iteration + for (size_t i = 0; i < n_args; i++) { + uint16_t key = (uint16_t)(vals[i] >> 16); + if (pos < 0 || key != r->high_low_container.keys[pos]) { + pos = ra_get_index(&r->high_low_container, key); + } + if (pos >= 0) { + uint8_t new_typecode; + container_t *new_container; + new_container = container_remove(r->high_low_container.containers[pos], + vals[i] & 0xffff, + r->high_low_container.typecodes[pos], + &new_typecode); + if (new_container != r->high_low_container.containers[pos]) { + container_free(r->high_low_container.containers[pos], + r->high_low_container.typecodes[pos]); + ra_replace_key_and_container_at_index(&r->high_low_container, + pos, key, new_container, + new_typecode); + } + if (!container_nonzero_cardinality(new_container, new_typecode)) { + container_free(new_container, new_typecode); + ra_remove_at_index(&r->high_low_container, pos); + pos = -1; + } + } + } +} + +// there should be some SIMD optimizations possible here +roaring_bitmap_t *roaring_bitmap_and(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + uint32_t neededcap = length1 > length2 ? length2 : length1; + roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(neededcap); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + + int pos1 = 0, pos2 = 0; + + while (pos1 < length1 && pos2 < length2) { + const uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + const uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + if (s1 == s2) { + uint8_t type1, type2; + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_and(c1, type1, c2, type2, &result_type); + + if (container_nonzero_cardinality(c, result_type)) { + ra_append(&answer->high_low_container, s1, c, result_type); + } else { + container_free(c, result_type); // otherwise: memory leak! + } + ++pos1; + ++pos2; + } else if (s1 < s2) { // s1 < s2 + pos1 = ra_advance_until(&x1->high_low_container, s2, pos1); + } else { // s1 > s2 + pos2 = ra_advance_until(&x2->high_low_container, s1, pos2); + } + } + return answer; +} + +/** + * Compute the union of 'number' bitmaps. + */ +roaring_bitmap_t *roaring_bitmap_or_many(size_t number, + const roaring_bitmap_t **x) { + if (number == 0) { + return roaring_bitmap_create(); + } + if (number == 1) { + return roaring_bitmap_copy(x[0]); + } + roaring_bitmap_t *answer = + roaring_bitmap_lazy_or(x[0], x[1], LAZY_OR_BITSET_CONVERSION); + for (size_t i = 2; i < number; i++) { + roaring_bitmap_lazy_or_inplace(answer, x[i], LAZY_OR_BITSET_CONVERSION); + } + roaring_bitmap_repair_after_lazy(answer); + return answer; +} + +/** + * Compute the xor of 'number' bitmaps. + */ +roaring_bitmap_t *roaring_bitmap_xor_many(size_t number, + const roaring_bitmap_t **x) { + if (number == 0) { + return roaring_bitmap_create(); + } + if (number == 1) { + return roaring_bitmap_copy(x[0]); + } + roaring_bitmap_t *answer = roaring_bitmap_lazy_xor(x[0], x[1]); + for (size_t i = 2; i < number; i++) { + roaring_bitmap_lazy_xor_inplace(answer, x[i]); + } + roaring_bitmap_repair_after_lazy(answer); + return answer; +} + +// inplace and (modifies its first argument). +void roaring_bitmap_and_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + if (x1 == x2) return; + int pos1 = 0, pos2 = 0, intersection_size = 0; + const int length1 = ra_get_size(&x1->high_low_container); + const int length2 = ra_get_size(&x2->high_low_container); + + // any skipped-over or newly emptied containers in x1 + // have to be freed. + while (pos1 < length1 && pos2 < length2) { + const uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + const uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + if (s1 == s2) { + uint8_t type1, type2, result_type; + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + + // We do the computation "in place" only when c1 is not a shared container. + // Rationale: using a shared container safely with in place computation would + // require making a copy and then doing the computation in place which is likely + // less efficient than avoiding in place entirely and always generating a new + // container. + container_t *c = + (type1 == SHARED_CONTAINER_TYPE) + ? container_and(c1, type1, c2, type2, &result_type) + : container_iand(c1, type1, c2, type2, &result_type); + + if (c != c1) { // in this instance a new container was created, and + // we need to free the old one + container_free(c1, type1); + } + if (container_nonzero_cardinality(c, result_type)) { + ra_replace_key_and_container_at_index(&x1->high_low_container, + intersection_size, s1, c, + result_type); + intersection_size++; + } else { + container_free(c, result_type); + } + ++pos1; + ++pos2; + } else if (s1 < s2) { + pos1 = ra_advance_until_freeing(&x1->high_low_container, s2, pos1); + } else { // s1 > s2 + pos2 = ra_advance_until(&x2->high_low_container, s1, pos2); + } + } + + // if we ended early because x2 ran out, then all remaining in x1 should be + // freed + while (pos1 < length1) { + container_free(x1->high_low_container.containers[pos1], + x1->high_low_container.typecodes[pos1]); + ++pos1; + } + + // all containers after this have either been copied or freed + ra_downsize(&x1->high_low_container, intersection_size); +} + +roaring_bitmap_t *roaring_bitmap_or(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + if (0 == length1) { + return roaring_bitmap_copy(x2); + } + if (0 == length2) { + return roaring_bitmap_copy(x1); + } + roaring_bitmap_t *answer = + roaring_bitmap_create_with_capacity(length1 + length2); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_or(c1, type1, c2, type2, &result_type); + + // since we assume that the initial containers are non-empty, the + // result here + // can only be non-empty + ra_append(&answer->high_low_container, s1, c, result_type); + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + // c1 = container_clone(c1, type1); + c1 = get_copy_of_container(c1, &type1, is_cow(x1)); + if (is_cow(x1)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c1, + type1); + } + ra_append(&answer->high_low_container, s1, c1, type1); + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + // c2 = container_clone(c2, type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_append(&answer->high_low_container, s2, c2, type2); + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&answer->high_low_container, + &x2->high_low_container, pos2, length2, + is_cow(x2)); + } else if (pos2 == length2) { + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1, + is_cow(x1)); + } + return answer; +} + +// inplace or (modifies its first argument). +void roaring_bitmap_or_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + int length1 = x1->high_low_container.size; + const int length2 = x2->high_low_container.size; + + if (0 == length2) return; + + if (0 == length1) { + roaring_bitmap_overwrite(x1, x2); + return; + } + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + if (!container_is_full(c1, type1)) { + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = + (type1 == SHARED_CONTAINER_TYPE) + ? container_or(c1, type1, c2, type2, &result_type) + : container_ior(c1, type1, c2, type2, &result_type); + + if (c != c1) { // in this instance a new container was created, + // and we need to free the old one + container_free(c1, type1); + } + ra_set_container_at_index(&x1->high_low_container, pos1, c, + result_type); + } + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index(&x2->high_low_container, + pos2, &type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + + // container_t *c2_clone = container_clone(c2, type2); + ra_insert_new_key_value_at(&x1->high_low_container, pos1, s2, c2, + type2); + pos1++; + length1++; + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&x1->high_low_container, &x2->high_low_container, + pos2, length2, is_cow(x2)); + } +} + +roaring_bitmap_t *roaring_bitmap_xor(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + if (0 == length1) { + return roaring_bitmap_copy(x2); + } + if (0 == length2) { + return roaring_bitmap_copy(x1); + } + roaring_bitmap_t *answer = + roaring_bitmap_create_with_capacity(length1 + length2); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_xor(c1, type1, c2, type2, &result_type); + + if (container_nonzero_cardinality(c, result_type)) { + ra_append(&answer->high_low_container, s1, c, result_type); + } else { + container_free(c, result_type); + } + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + c1 = get_copy_of_container(c1, &type1, is_cow(x1)); + if (is_cow(x1)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c1, + type1); + } + ra_append(&answer->high_low_container, s1, c1, type1); + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_append(&answer->high_low_container, s2, c2, type2); + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&answer->high_low_container, + &x2->high_low_container, pos2, length2, + is_cow(x2)); + } else if (pos2 == length2) { + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1, + is_cow(x1)); + } + return answer; +} + +// inplace xor (modifies its first argument). + +void roaring_bitmap_xor_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + assert(x1 != x2); + uint8_t result_type = 0; + int length1 = x1->high_low_container.size; + const int length2 = x2->high_low_container.size; + + if (0 == length2) return; + + if (0 == length1) { + roaring_bitmap_overwrite(x1, x2); + return; + } + + // XOR can have new containers inserted from x2, but can also + // lose containers when x1 and x2 are nonempty and identical. + + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + + // We do the computation "in place" only when c1 is not a shared container. + // Rationale: using a shared container safely with in place computation would + // require making a copy and then doing the computation in place which is likely + // less efficient than avoiding in place entirely and always generating a new + // container. + + container_t *c; + if (type1 == SHARED_CONTAINER_TYPE) { + c = container_xor(c1, type1, c2, type2, &result_type); + shared_container_free(CAST_shared(c1)); // so release + } + else { + c = container_ixor(c1, type1, c2, type2, &result_type); + } + + if (container_nonzero_cardinality(c, result_type)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c, + result_type); + ++pos1; + } else { + container_free(c, result_type); + ra_remove_at_index(&x1->high_low_container, pos1); + --length1; + } + + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + + ra_insert_new_key_value_at(&x1->high_low_container, pos1, s2, c2, + type2); + pos1++; + length1++; + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&x1->high_low_container, &x2->high_low_container, + pos2, length2, is_cow(x2)); + } +} + +roaring_bitmap_t *roaring_bitmap_andnot(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + if (0 == length1) { + roaring_bitmap_t *empty_bitmap = roaring_bitmap_create(); + roaring_bitmap_set_copy_on_write(empty_bitmap, is_cow(x1) || is_cow(x2)); + return empty_bitmap; + } + if (0 == length2) { + return roaring_bitmap_copy(x1); + } + roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(length1); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = 0; + uint16_t s2 = 0; + while (true) { + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_andnot(c1, type1, c2, type2, + &result_type); + + if (container_nonzero_cardinality(c, result_type)) { + ra_append(&answer->high_low_container, s1, c, result_type); + } else { + container_free(c, result_type); + } + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + } else if (s1 < s2) { // s1 < s2 + const int next_pos1 = + ra_advance_until(&x1->high_low_container, s2, pos1); + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, next_pos1, + is_cow(x1)); + // TODO : perhaps some of the copy_on_write should be based on + // answer rather than x1 (more stringent?). Many similar cases + pos1 = next_pos1; + if (pos1 == length1) break; + } else { // s1 > s2 + pos2 = ra_advance_until(&x2->high_low_container, s1, pos2); + if (pos2 == length2) break; + } + } + if (pos2 == length2) { + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1, + is_cow(x1)); + } + return answer; +} + +// inplace andnot (modifies its first argument). + +void roaring_bitmap_andnot_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + assert(x1 != x2); + + uint8_t result_type = 0; + int length1 = x1->high_low_container.size; + const int length2 = x2->high_low_container.size; + int intersection_size = 0; + + if (0 == length2) return; + + if (0 == length1) { + roaring_bitmap_clear(x1); + return; + } + + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + + // We do the computation "in place" only when c1 is not a shared container. + // Rationale: using a shared container safely with in place computation would + // require making a copy and then doing the computation in place which is likely + // less efficient than avoiding in place entirely and always generating a new + // container. + + container_t *c; + if (type1 == SHARED_CONTAINER_TYPE) { + c = container_andnot(c1, type1, c2, type2, &result_type); + shared_container_free(CAST_shared(c1)); // release + } + else { + c = container_iandnot(c1, type1, c2, type2, &result_type); + } + + if (container_nonzero_cardinality(c, result_type)) { + ra_replace_key_and_container_at_index(&x1->high_low_container, + intersection_size++, s1, + c, result_type); + } else { + container_free(c, result_type); + } + + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + if (pos1 != intersection_size) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + + ra_replace_key_and_container_at_index(&x1->high_low_container, + intersection_size, s1, c1, + type1); + } + intersection_size++; + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + pos2 = ra_advance_until(&x2->high_low_container, s1, pos2); + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + + if (pos1 < length1) { + // all containers between intersection_size and + // pos1 are junk. However, they have either been moved + // (thus still referenced) or involved in an iandnot + // that will clean up all containers that could not be reused. + // Thus we should not free the junk containers between + // intersection_size and pos1. + if (pos1 > intersection_size) { + // left slide of remaining items + ra_copy_range(&x1->high_low_container, pos1, length1, + intersection_size); + } + // else current placement is fine + intersection_size += (length1 - pos1); + } + ra_downsize(&x1->high_low_container, intersection_size); +} + +uint64_t roaring_bitmap_get_cardinality(const roaring_bitmap_t *r) { + const roaring_array_t *ra = &r->high_low_container; + + uint64_t card = 0; + for (int i = 0; i < ra->size; ++i) + card += container_get_cardinality(ra->containers[i], ra->typecodes[i]); + return card; +} + +uint64_t roaring_bitmap_range_cardinality(const roaring_bitmap_t *r, + uint64_t range_start, + uint64_t range_end) { + const roaring_array_t *ra = &r->high_low_container; + + if (range_end > UINT32_MAX) { + range_end = UINT32_MAX + UINT64_C(1); + } + if (range_start >= range_end) { + return 0; + } + range_end--; // make range_end inclusive + // now we have: 0 <= range_start <= range_end <= UINT32_MAX + + uint16_t minhb = range_start >> 16; + uint16_t maxhb = range_end >> 16; + + uint64_t card = 0; + + int i = ra_get_index(ra, minhb); + if (i >= 0) { + if (minhb == maxhb) { + card += container_rank(ra->containers[i], ra->typecodes[i], + range_end & 0xffff); + } else { + card += container_get_cardinality(ra->containers[i], + ra->typecodes[i]); + } + if ((range_start & 0xffff) != 0) { + card -= container_rank(ra->containers[i], ra->typecodes[i], + (range_start & 0xffff) - 1); + } + i++; + } else { + i = -i - 1; + } + + for (; i < ra->size; i++) { + uint16_t key = ra->keys[i]; + if (key < maxhb) { + card += container_get_cardinality(ra->containers[i], + ra->typecodes[i]); + } else if (key == maxhb) { + card += container_rank(ra->containers[i], ra->typecodes[i], + range_end & 0xffff); + break; + } else { + break; + } + } + + return card; +} + + +bool roaring_bitmap_is_empty(const roaring_bitmap_t *r) { + return r->high_low_container.size == 0; +} + +void roaring_bitmap_to_uint32_array(const roaring_bitmap_t *r, uint32_t *ans) { + ra_to_uint32_array(&r->high_low_container, ans); +} + +bool roaring_bitmap_range_uint32_array(const roaring_bitmap_t *r, + size_t offset, size_t limit, + uint32_t *ans) { + return ra_range_uint32_array(&r->high_low_container, offset, limit, ans); +} + +/** convert array and bitmap containers to run containers when it is more + * efficient; + * also convert from run containers when more space efficient. Returns + * true if the result has at least one run container. +*/ +bool roaring_bitmap_run_optimize(roaring_bitmap_t *r) { + bool answer = false; + for (int i = 0; i < r->high_low_container.size; i++) { + uint8_t type_original, type_after; + ra_unshare_container_at_index( + &r->high_low_container, i); // TODO: this introduces extra cloning! + container_t *c = ra_get_container_at_index(&r->high_low_container, i, + &type_original); + container_t *c1 = convert_run_optimize(c, type_original, &type_after); + if (type_after == RUN_CONTAINER_TYPE) { + answer = true; + } + ra_set_container_at_index(&r->high_low_container, i, c1, type_after); + } + return answer; +} + +size_t roaring_bitmap_shrink_to_fit(roaring_bitmap_t *r) { + size_t answer = 0; + for (int i = 0; i < r->high_low_container.size; i++) { + uint8_t type_original; + container_t *c = ra_get_container_at_index(&r->high_low_container, i, + &type_original); + answer += container_shrink_to_fit(c, type_original); + } + answer += ra_shrink_to_fit(&r->high_low_container); + return answer; +} + +/** + * Remove run-length encoding even when it is more space efficient + * return whether a change was applied + */ +bool roaring_bitmap_remove_run_compression(roaring_bitmap_t *r) { + bool answer = false; + for (int i = 0; i < r->high_low_container.size; i++) { + uint8_t type_original, type_after; + container_t *c = ra_get_container_at_index(&r->high_low_container, i, + &type_original); + if (get_container_type(c, type_original) == RUN_CONTAINER_TYPE) { + answer = true; + if (type_original == SHARED_CONTAINER_TYPE) { + run_container_t *truec = CAST_run(CAST_shared(c)->container); + int32_t card = run_container_cardinality(truec); + container_t *c1 = convert_to_bitset_or_array_container( + truec, card, &type_after); + shared_container_free(CAST_shared(c)); // frees run as needed + ra_set_container_at_index(&r->high_low_container, i, c1, + type_after); + + } else { + int32_t card = run_container_cardinality(CAST_run(c)); + container_t *c1 = convert_to_bitset_or_array_container( + CAST_run(c), card, &type_after); + run_container_free(CAST_run(c)); + ra_set_container_at_index(&r->high_low_container, i, c1, + type_after); + } + } + } + return answer; +} + +size_t roaring_bitmap_serialize(const roaring_bitmap_t *r, char *buf) { + size_t portablesize = roaring_bitmap_portable_size_in_bytes(r); + uint64_t cardinality = roaring_bitmap_get_cardinality(r); + uint64_t sizeasarray = cardinality * sizeof(uint32_t) + sizeof(uint32_t); + if (portablesize < sizeasarray) { + buf[0] = CROARING_SERIALIZATION_CONTAINER; + return roaring_bitmap_portable_serialize(r, buf + 1) + 1; + } else { + buf[0] = CROARING_SERIALIZATION_ARRAY_UINT32; + memcpy(buf + 1, &cardinality, sizeof(uint32_t)); + roaring_bitmap_to_uint32_array( + r, (uint32_t *)(buf + 1 + sizeof(uint32_t))); + return 1 + (size_t)sizeasarray; + } +} + +size_t roaring_bitmap_size_in_bytes(const roaring_bitmap_t *r) { + size_t portablesize = roaring_bitmap_portable_size_in_bytes(r); + uint64_t sizeasarray = roaring_bitmap_get_cardinality(r) * sizeof(uint32_t) + + sizeof(uint32_t); + return portablesize < sizeasarray ? portablesize + 1 : (size_t)sizeasarray + 1; +} + +size_t roaring_bitmap_portable_size_in_bytes(const roaring_bitmap_t *r) { + return ra_portable_size_in_bytes(&r->high_low_container); +} + + +roaring_bitmap_t *roaring_bitmap_portable_deserialize_safe(const char *buf, size_t maxbytes) { + roaring_bitmap_t *ans = + (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t)); + if (ans == NULL) { + return NULL; + } + size_t bytesread; + bool is_ok = ra_portable_deserialize(&ans->high_low_container, buf, maxbytes, &bytesread); + if(is_ok) assert(bytesread <= maxbytes); + roaring_bitmap_set_copy_on_write(ans, false); + if (!is_ok) { + roaring_free(ans); + return NULL; + } + return ans; +} + +roaring_bitmap_t *roaring_bitmap_portable_deserialize(const char *buf) { + return roaring_bitmap_portable_deserialize_safe(buf, SIZE_MAX); +} + + +size_t roaring_bitmap_portable_deserialize_size(const char *buf, size_t maxbytes) { + return ra_portable_deserialize_size(buf, maxbytes); +} + + +size_t roaring_bitmap_portable_serialize(const roaring_bitmap_t *r, + char *buf) { + return ra_portable_serialize(&r->high_low_container, buf); +} + +roaring_bitmap_t *roaring_bitmap_deserialize(const void *buf) { + const char *bufaschar = (const char *)buf; + if (*(const unsigned char *)buf == CROARING_SERIALIZATION_ARRAY_UINT32) { + /* This looks like a compressed set of uint32_t elements */ + uint32_t card; + memcpy(&card, bufaschar + 1, sizeof(uint32_t)); + const uint32_t *elems = + (const uint32_t *)(bufaschar + 1 + sizeof(uint32_t)); + + return roaring_bitmap_of_ptr(card, elems); + } else if (bufaschar[0] == CROARING_SERIALIZATION_CONTAINER) { + return roaring_bitmap_portable_deserialize(bufaschar + 1); + } else + return (NULL); +} + +bool roaring_iterate(const roaring_bitmap_t *r, roaring_iterator iterator, + void *ptr) { + const roaring_array_t *ra = &r->high_low_container; + + for (int i = 0; i < ra->size; ++i) + if (!container_iterate(ra->containers[i], ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16, + iterator, ptr)) { + return false; + } + return true; +} + +bool roaring_iterate64(const roaring_bitmap_t *r, roaring_iterator64 iterator, + uint64_t high_bits, void *ptr) { + const roaring_array_t *ra = &r->high_low_container; + + for (int i = 0; i < ra->size; ++i) + if (!container_iterate64( + ra->containers[i], ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16, iterator, + high_bits, ptr)) { + return false; + } + return true; +} + +/**** +* begin roaring_uint32_iterator_t +*****/ + +// Partially initializes the roaring iterator when it begins looking at +// a new container. +static bool iter_new_container_partial_init(roaring_uint32_iterator_t *newit) { + newit->in_container_index = 0; + newit->run_index = 0; + newit->current_value = 0; + if (newit->container_index >= newit->parent->high_low_container.size || + newit->container_index < 0) { + newit->current_value = UINT32_MAX; + return (newit->has_value = false); + } + // assume not empty + newit->has_value = true; + // we precompute container, typecode and highbits so that successive + // iterators do not have to grab them from odd memory locations + // and have to worry about the (easily predicted) container_unwrap_shared + // call. + newit->container = + newit->parent->high_low_container.containers[newit->container_index]; + newit->typecode = + newit->parent->high_low_container.typecodes[newit->container_index]; + newit->highbits = + ((uint32_t) + newit->parent->high_low_container.keys[newit->container_index]) + << 16; + newit->container = + container_unwrap_shared(newit->container, &(newit->typecode)); + return newit->has_value; +} + +static bool loadfirstvalue(roaring_uint32_iterator_t *newit) { + if (!iter_new_container_partial_init(newit)) + return newit->has_value; + + switch (newit->typecode) { + case BITSET_CONTAINER_TYPE: { + const bitset_container_t *bc = const_CAST_bitset(newit->container); + + uint32_t wordindex = 0; + uint64_t word; + while ((word = bc->words[wordindex]) == 0) { + wordindex++; // advance + } + // here "word" is non-zero + newit->in_container_index = wordindex * 64 + __builtin_ctzll(word); + newit->current_value = newit->highbits | newit->in_container_index; + break; } + + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = const_CAST_array(newit->container); + newit->current_value = newit->highbits | ac->array[0]; + break; } + + case RUN_CONTAINER_TYPE: { + const run_container_t *rc = const_CAST_run(newit->container); + newit->current_value = newit->highbits | rc->runs[0].value; + break; } + + default: + // if this ever happens, bug! + assert(false); + } // switch (typecode) + return true; +} + +static bool loadlastvalue(roaring_uint32_iterator_t* newit) { + if (!iter_new_container_partial_init(newit)) + return newit->has_value; + + switch(newit->typecode) { + case BITSET_CONTAINER_TYPE: { + uint32_t wordindex = BITSET_CONTAINER_SIZE_IN_WORDS - 1; + uint64_t word; + const bitset_container_t* bitset_container = (const bitset_container_t*)newit->container; + while ((word = bitset_container->words[wordindex]) == 0) + --wordindex; + + int num_leading_zeros = __builtin_clzll(word); + newit->in_container_index = (wordindex * 64) + (63 - num_leading_zeros); + newit->current_value = newit->highbits | newit->in_container_index; + break; + } + case ARRAY_CONTAINER_TYPE: { + const array_container_t* array_container = (const array_container_t*)newit->container; + newit->in_container_index = array_container->cardinality - 1; + newit->current_value = newit->highbits | array_container->array[newit->in_container_index]; + break; + } + case RUN_CONTAINER_TYPE: { + const run_container_t* run_container = (const run_container_t*)newit->container; + newit->run_index = run_container->n_runs - 1; + const rle16_t* last_run = &run_container->runs[newit->run_index]; + newit->current_value = newit->highbits | (last_run->value + last_run->length); + break; + } + default: + // if this ever happens, bug! + assert(false); + } + return true; +} + +// prerequesite: the value should be in range of the container +static bool loadfirstvalue_largeorequal(roaring_uint32_iterator_t *newit, uint32_t val) { + // Don't have to check return value because of prerequisite + iter_new_container_partial_init(newit); + uint16_t lb = val & 0xFFFF; + + switch (newit->typecode) { + case BITSET_CONTAINER_TYPE: { + const bitset_container_t *bc = const_CAST_bitset(newit->container); + newit->in_container_index = + bitset_container_index_equalorlarger(bc, lb); + newit->current_value = newit->highbits | newit->in_container_index; + break; } + + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = const_CAST_array(newit->container); + newit->in_container_index = + array_container_index_equalorlarger(ac, lb); + newit->current_value = + newit->highbits | ac->array[newit->in_container_index]; + break; } + + case RUN_CONTAINER_TYPE: { + const run_container_t *rc = const_CAST_run(newit->container); + newit->run_index = run_container_index_equalorlarger(rc, lb); + if (rc->runs[newit->run_index].value <= lb) { + newit->current_value = val; + } else { + newit->current_value = + newit->highbits | rc->runs[newit->run_index].value; + } + break; } + + default: + __builtin_unreachable(); + } + + return true; +} + +void roaring_init_iterator(const roaring_bitmap_t *r, + roaring_uint32_iterator_t *newit) { + newit->parent = r; + newit->container_index = 0; + newit->has_value = loadfirstvalue(newit); +} + +void roaring_init_iterator_last(const roaring_bitmap_t *r, + roaring_uint32_iterator_t *newit) { + newit->parent = r; + newit->container_index = newit->parent->high_low_container.size - 1; + newit->has_value = loadlastvalue(newit); +} + +roaring_uint32_iterator_t *roaring_create_iterator(const roaring_bitmap_t *r) { + roaring_uint32_iterator_t *newit = + (roaring_uint32_iterator_t *)roaring_malloc(sizeof(roaring_uint32_iterator_t)); + if (newit == NULL) return NULL; + roaring_init_iterator(r, newit); + return newit; +} + +roaring_uint32_iterator_t *roaring_copy_uint32_iterator( + const roaring_uint32_iterator_t *it) { + roaring_uint32_iterator_t *newit = + (roaring_uint32_iterator_t *)roaring_malloc(sizeof(roaring_uint32_iterator_t)); + memcpy(newit, it, sizeof(roaring_uint32_iterator_t)); + return newit; +} + +bool roaring_move_uint32_iterator_equalorlarger(roaring_uint32_iterator_t *it, uint32_t val) { + uint16_t hb = val >> 16; + const int i = ra_get_index(& it->parent->high_low_container, hb); + if (i >= 0) { + uint32_t lowvalue = container_maximum(it->parent->high_low_container.containers[i], it->parent->high_low_container.typecodes[i]); + uint16_t lb = val & 0xFFFF; + if(lowvalue < lb ) { + it->container_index = i+1; // will have to load first value of next container + } else {// the value is necessarily within the range of the container + it->container_index = i; + it->has_value = loadfirstvalue_largeorequal(it, val); + return it->has_value; + } + } else { + // there is no matching, so we are going for the next container + it->container_index = -i-1; + } + it->has_value = loadfirstvalue(it); + return it->has_value; +} + + +bool roaring_advance_uint32_iterator(roaring_uint32_iterator_t *it) { + if (it->container_index >= it->parent->high_low_container.size) { + return (it->has_value = false); + } + if (it->container_index < 0) { + it->container_index = 0; + return (it->has_value = loadfirstvalue(it)); + } + + switch (it->typecode) { + case BITSET_CONTAINER_TYPE: { + const bitset_container_t *bc = const_CAST_bitset(it->container); + it->in_container_index++; + + uint32_t wordindex = it->in_container_index / 64; + if (wordindex >= BITSET_CONTAINER_SIZE_IN_WORDS) break; + + uint64_t word = bc->words[wordindex] & + (UINT64_MAX << (it->in_container_index % 64)); + // next part could be optimized/simplified + while ((word == 0) && + (wordindex + 1 < BITSET_CONTAINER_SIZE_IN_WORDS)) { + wordindex++; + word = bc->words[wordindex]; + } + if (word != 0) { + it->in_container_index = wordindex * 64 + __builtin_ctzll(word); + it->current_value = it->highbits | it->in_container_index; + return (it->has_value = true); + } + break; } + + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = const_CAST_array(it->container); + it->in_container_index++; + if (it->in_container_index < ac->cardinality) { + it->current_value = + it->highbits | ac->array[it->in_container_index]; + return (it->has_value = true); + } + break; } + + case RUN_CONTAINER_TYPE: { + if(it->current_value == UINT32_MAX) { // avoid overflow to zero + return (it->has_value = false); + } + + const run_container_t* rc = const_CAST_run(it->container); + uint32_t limit = (it->highbits | (rc->runs[it->run_index].value + + rc->runs[it->run_index].length)); + if (++it->current_value <= limit) { + return (it->has_value = true); + } + + if (++it->run_index < rc->n_runs) { // Assume the run has a value + it->current_value = + it->highbits | rc->runs[it->run_index].value; + return (it->has_value = true); + } + break; + } + + default: + __builtin_unreachable(); + } + + // moving to next container + it->container_index++; + return (it->has_value = loadfirstvalue(it)); +} + +bool roaring_previous_uint32_iterator(roaring_uint32_iterator_t *it) { + if (it->container_index < 0) { + return (it->has_value = false); + } + if (it->container_index >= it->parent->high_low_container.size) { + it->container_index = it->parent->high_low_container.size - 1; + return (it->has_value = loadlastvalue(it)); + } + + switch (it->typecode) { + case BITSET_CONTAINER_TYPE: { + if (--it->in_container_index < 0) + break; + + const bitset_container_t* bitset_container = (const bitset_container_t*)it->container; + int32_t wordindex = it->in_container_index / 64; + uint64_t word = bitset_container->words[wordindex] & (UINT64_MAX >> (63 - (it->in_container_index % 64))); + + while (word == 0 && --wordindex >= 0) { + word = bitset_container->words[wordindex]; + } + if (word == 0) + break; + + int num_leading_zeros = __builtin_clzll(word); + it->in_container_index = (wordindex * 64) + (63 - num_leading_zeros); + it->current_value = it->highbits | it->in_container_index; + return (it->has_value = true); + } + case ARRAY_CONTAINER_TYPE: { + if (--it->in_container_index < 0) + break; + + const array_container_t* array_container = (const array_container_t*)it->container; + it->current_value = it->highbits | array_container->array[it->in_container_index]; + return (it->has_value = true); + } + case RUN_CONTAINER_TYPE: { + if(it->current_value == 0) + return (it->has_value = false); + + const run_container_t* run_container = (const run_container_t*)it->container; + if (--it->current_value >= (it->highbits | run_container->runs[it->run_index].value)) { + return (it->has_value = true); + } + + if (--it->run_index < 0) + break; + + it->current_value = it->highbits | (run_container->runs[it->run_index].value + + run_container->runs[it->run_index].length); + return (it->has_value = true); + } + default: + // if this ever happens, bug! + assert(false); + } // switch (typecode) + + // moving to previous container + it->container_index--; + return (it->has_value = loadlastvalue(it)); +} + +uint32_t roaring_read_uint32_iterator(roaring_uint32_iterator_t *it, uint32_t* buf, uint32_t count) { + uint32_t ret = 0; + uint32_t num_values; + uint32_t wordindex; // used for bitsets + uint64_t word; // used for bitsets + const array_container_t* acont; //TODO remove + const run_container_t* rcont; //TODO remove + const bitset_container_t* bcont; //TODO remove + + while (it->has_value && ret < count) { + switch (it->typecode) { + case BITSET_CONTAINER_TYPE: + bcont = const_CAST_bitset(it->container); + wordindex = it->in_container_index / 64; + word = bcont->words[wordindex] & (UINT64_MAX << (it->in_container_index % 64)); + do { + while (word != 0 && ret < count) { + buf[0] = it->highbits | (wordindex * 64 + __builtin_ctzll(word)); + word = word & (word - 1); + buf++; + ret++; + } + while (word == 0 && wordindex+1 < BITSET_CONTAINER_SIZE_IN_WORDS) { + wordindex++; + word = bcont->words[wordindex]; + } + } while (word != 0 && ret < count); + it->has_value = (word != 0); + if (it->has_value) { + it->in_container_index = wordindex * 64 + __builtin_ctzll(word); + it->current_value = it->highbits | it->in_container_index; + } + break; + case ARRAY_CONTAINER_TYPE: + acont = const_CAST_array(it->container); + num_values = minimum_uint32(acont->cardinality - it->in_container_index, count - ret); + for (uint32_t i = 0; i < num_values; i++) { + buf[i] = it->highbits | acont->array[it->in_container_index + i]; + } + buf += num_values; + ret += num_values; + it->in_container_index += num_values; + it->has_value = (it->in_container_index < acont->cardinality); + if (it->has_value) { + it->current_value = it->highbits | acont->array[it->in_container_index]; + } + break; + case RUN_CONTAINER_TYPE: + rcont = const_CAST_run(it->container); + //"in_run_index" name is misleading, read it as "max_value_in_current_run" + do { + uint32_t largest_run_value = it->highbits | (rcont->runs[it->run_index].value + rcont->runs[it->run_index].length); + num_values = minimum_uint32(largest_run_value - it->current_value + 1, count - ret); + for (uint32_t i = 0; i < num_values; i++) { + buf[i] = it->current_value + i; + } + it->current_value += num_values; // this can overflow to zero: UINT32_MAX+1=0 + buf += num_values; + ret += num_values; + + if (it->current_value > largest_run_value || it->current_value == 0) { + it->run_index++; + if (it->run_index < rcont->n_runs) { + it->current_value = it->highbits | rcont->runs[it->run_index].value; + } else { + it->has_value = false; + } + } + } while ((ret < count) && it->has_value); + break; + default: + assert(false); + } + if (it->has_value) { + assert(ret == count); + return ret; + } + it->container_index++; + it->has_value = loadfirstvalue(it); + } + return ret; +} + + + +void roaring_free_uint32_iterator(roaring_uint32_iterator_t *it) { roaring_free(it); } + +/**** +* end of roaring_uint32_iterator_t +*****/ + +bool roaring_bitmap_equals(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2) { + const roaring_array_t *ra1 = &r1->high_low_container; + const roaring_array_t *ra2 = &r2->high_low_container; + + if (ra1->size != ra2->size) { + return false; + } + for (int i = 0; i < ra1->size; ++i) { + if (ra1->keys[i] != ra2->keys[i]) { + return false; + } + } + for (int i = 0; i < ra1->size; ++i) { + bool areequal = container_equals(ra1->containers[i], + ra1->typecodes[i], + ra2->containers[i], + ra2->typecodes[i]); + if (!areequal) { + return false; + } + } + return true; +} + +bool roaring_bitmap_is_subset(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2) { + const roaring_array_t *ra1 = &r1->high_low_container; + const roaring_array_t *ra2 = &r2->high_low_container; + + const int length1 = ra1->size, + length2 = ra2->size; + + int pos1 = 0, pos2 = 0; + + while (pos1 < length1 && pos2 < length2) { + const uint16_t s1 = ra_get_key_at_index(ra1, pos1); + const uint16_t s2 = ra_get_key_at_index(ra2, pos2); + + if (s1 == s2) { + uint8_t type1, type2; + container_t *c1 = ra_get_container_at_index(ra1, pos1, &type1); + container_t *c2 = ra_get_container_at_index(ra2, pos2, &type2); + if (!container_is_subset(c1, type1, c2, type2)) + return false; + ++pos1; + ++pos2; + } else if (s1 < s2) { // s1 < s2 + return false; + } else { // s1 > s2 + pos2 = ra_advance_until(ra2, s1, pos2); + } + } + if (pos1 == length1) + return true; + else + return false; +} + +static void insert_flipped_container(roaring_array_t *ans_arr, + const roaring_array_t *x1_arr, uint16_t hb, + uint16_t lb_start, uint16_t lb_end) { + const int i = ra_get_index(x1_arr, hb); + const int j = ra_get_index(ans_arr, hb); + uint8_t ctype_in, ctype_out; + container_t *flipped_container = NULL; + if (i >= 0) { + container_t *container_to_flip = + ra_get_container_at_index(x1_arr, i, &ctype_in); + flipped_container = + container_not_range(container_to_flip, ctype_in, (uint32_t)lb_start, + (uint32_t)(lb_end + 1), &ctype_out); + + if (container_get_cardinality(flipped_container, ctype_out)) + ra_insert_new_key_value_at(ans_arr, -j - 1, hb, flipped_container, + ctype_out); + else { + container_free(flipped_container, ctype_out); + } + } else { + flipped_container = container_range_of_ones( + (uint32_t)lb_start, (uint32_t)(lb_end + 1), &ctype_out); + ra_insert_new_key_value_at(ans_arr, -j - 1, hb, flipped_container, + ctype_out); + } +} + +static void inplace_flip_container(roaring_array_t *x1_arr, uint16_t hb, + uint16_t lb_start, uint16_t lb_end) { + const int i = ra_get_index(x1_arr, hb); + uint8_t ctype_in, ctype_out; + container_t *flipped_container = NULL; + if (i >= 0) { + container_t *container_to_flip = + ra_get_container_at_index(x1_arr, i, &ctype_in); + flipped_container = container_inot_range( + container_to_flip, ctype_in, (uint32_t)lb_start, + (uint32_t)(lb_end + 1), &ctype_out); + // if a new container was created, the old one was already freed + if (container_get_cardinality(flipped_container, ctype_out)) { + ra_set_container_at_index(x1_arr, i, flipped_container, ctype_out); + } else { + container_free(flipped_container, ctype_out); + ra_remove_at_index(x1_arr, i); + } + + } else { + flipped_container = container_range_of_ones( + (uint32_t)lb_start, (uint32_t)(lb_end + 1), &ctype_out); + ra_insert_new_key_value_at(x1_arr, -i - 1, hb, flipped_container, + ctype_out); + } +} + +static void insert_fully_flipped_container(roaring_array_t *ans_arr, + const roaring_array_t *x1_arr, + uint16_t hb) { + const int i = ra_get_index(x1_arr, hb); + const int j = ra_get_index(ans_arr, hb); + uint8_t ctype_in, ctype_out; + container_t *flipped_container = NULL; + if (i >= 0) { + container_t *container_to_flip = + ra_get_container_at_index(x1_arr, i, &ctype_in); + flipped_container = + container_not(container_to_flip, ctype_in, &ctype_out); + if (container_get_cardinality(flipped_container, ctype_out)) + ra_insert_new_key_value_at(ans_arr, -j - 1, hb, flipped_container, + ctype_out); + else { + container_free(flipped_container, ctype_out); + } + } else { + flipped_container = container_range_of_ones(0U, 0x10000U, &ctype_out); + ra_insert_new_key_value_at(ans_arr, -j - 1, hb, flipped_container, + ctype_out); + } +} + +static void inplace_fully_flip_container(roaring_array_t *x1_arr, uint16_t hb) { + const int i = ra_get_index(x1_arr, hb); + uint8_t ctype_in, ctype_out; + container_t *flipped_container = NULL; + if (i >= 0) { + container_t *container_to_flip = + ra_get_container_at_index(x1_arr, i, &ctype_in); + flipped_container = + container_inot(container_to_flip, ctype_in, &ctype_out); + + if (container_get_cardinality(flipped_container, ctype_out)) { + ra_set_container_at_index(x1_arr, i, flipped_container, ctype_out); + } else { + container_free(flipped_container, ctype_out); + ra_remove_at_index(x1_arr, i); + } + + } else { + flipped_container = container_range_of_ones(0U, 0x10000U, &ctype_out); + ra_insert_new_key_value_at(x1_arr, -i - 1, hb, flipped_container, + ctype_out); + } +} + +roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *x1, + uint64_t range_start, + uint64_t range_end) { + if (range_start >= range_end) { + return roaring_bitmap_copy(x1); + } + if(range_end >= UINT64_C(0x100000000)) { + range_end = UINT64_C(0x100000000); + } + + roaring_bitmap_t *ans = roaring_bitmap_create(); + roaring_bitmap_set_copy_on_write(ans, is_cow(x1)); + + uint16_t hb_start = (uint16_t)(range_start >> 16); + const uint16_t lb_start = (uint16_t)range_start; // & 0xFFFF; + uint16_t hb_end = (uint16_t)((range_end - 1) >> 16); + const uint16_t lb_end = (uint16_t)(range_end - 1); // & 0xFFFF; + + ra_append_copies_until(&ans->high_low_container, &x1->high_low_container, + hb_start, is_cow(x1)); + if (hb_start == hb_end) { + insert_flipped_container(&ans->high_low_container, + &x1->high_low_container, hb_start, lb_start, + lb_end); + } else { + // start and end containers are distinct + if (lb_start > 0) { + // handle first (partial) container + insert_flipped_container(&ans->high_low_container, + &x1->high_low_container, hb_start, + lb_start, 0xFFFF); + ++hb_start; // for the full containers. Can't wrap. + } + + if (lb_end != 0xFFFF) --hb_end; // later we'll handle the partial block + + for (uint32_t hb = hb_start; hb <= hb_end; ++hb) { + insert_fully_flipped_container(&ans->high_low_container, + &x1->high_low_container, hb); + } + + // handle a partial final container + if (lb_end != 0xFFFF) { + insert_flipped_container(&ans->high_low_container, + &x1->high_low_container, hb_end + 1, 0, + lb_end); + ++hb_end; + } + } + ra_append_copies_after(&ans->high_low_container, &x1->high_low_container, + hb_end, is_cow(x1)); + return ans; +} + +void roaring_bitmap_flip_inplace(roaring_bitmap_t *x1, uint64_t range_start, + uint64_t range_end) { + if (range_start >= range_end) { + return; // empty range + } + if(range_end >= UINT64_C(0x100000000)) { + range_end = UINT64_C(0x100000000); + } + + uint16_t hb_start = (uint16_t)(range_start >> 16); + const uint16_t lb_start = (uint16_t)range_start; + uint16_t hb_end = (uint16_t)((range_end - 1) >> 16); + const uint16_t lb_end = (uint16_t)(range_end - 1); + + if (hb_start == hb_end) { + inplace_flip_container(&x1->high_low_container, hb_start, lb_start, + lb_end); + } else { + // start and end containers are distinct + if (lb_start > 0) { + // handle first (partial) container + inplace_flip_container(&x1->high_low_container, hb_start, lb_start, + 0xFFFF); + ++hb_start; // for the full containers. Can't wrap. + } + + if (lb_end != 0xFFFF) --hb_end; + + for (uint32_t hb = hb_start; hb <= hb_end; ++hb) { + inplace_fully_flip_container(&x1->high_low_container, hb); + } + // handle a partial final container + if (lb_end != 0xFFFF) { + inplace_flip_container(&x1->high_low_container, hb_end + 1, 0, + lb_end); + ++hb_end; + } + } +} + +static void offset_append_with_merge(roaring_array_t *ra, int k, container_t *c, uint8_t t) { + int size = ra_get_size(ra); + if (size == 0 || ra_get_key_at_index(ra, size-1) != k) { + // No merge. + ra_append(ra, k, c, t); + return; + } + + uint8_t last_t, new_t; + container_t *last_c, *new_c; + + // NOTE: we don't need to unwrap here, since we added last_c ourselves + // we have the certainty it's not a shared container. + // The same applies to c, as it's the result of calling container_offset. + last_c = ra_get_container_at_index(ra, size-1, &last_t); + new_c = container_ior(last_c, last_t, c, t, &new_t); + + ra_set_container_at_index(ra, size-1, new_c, new_t); + + // Comparison of pointers of different origin is UB (or so claim some compiler + // makers), so we compare their bit representation only. + if ((uintptr_t)last_c != (uintptr_t)new_c) { + container_free(last_c, last_t); + } + container_free(c, t); +} + +// roaring_bitmap_add_offset adds the value 'offset' to each and every value in +// a bitmap, generating a new bitmap in the process. If offset + element is +// outside of the range [0,2^32), that the element will be dropped. +// We need "offset" to be 64 bits because we want to support values +// between -0xFFFFFFFF up to +0xFFFFFFFF. +roaring_bitmap_t *roaring_bitmap_add_offset(const roaring_bitmap_t *bm, + int64_t offset) { + roaring_bitmap_t *answer; + roaring_array_t *ans_ra; + int64_t container_offset; + uint16_t in_offset; + + const roaring_array_t *bm_ra = &bm->high_low_container; + int length = bm_ra->size; + + if (offset == 0) { + return roaring_bitmap_copy(bm); + } + + container_offset = offset >> 16; + in_offset = (uint16_t)(offset - container_offset * (1 << 16)); + + answer = roaring_bitmap_create(); + roaring_bitmap_set_copy_on_write(answer, is_cow(bm)); + + ans_ra = &answer->high_low_container; + + if (in_offset == 0) { + ans_ra = &answer->high_low_container; + + for (int i = 0, j = 0; i < length; ++i) { + int64_t key = ra_get_key_at_index(bm_ra, i); + key += container_offset; + + if (key < 0 || key >= (1 << 16)) { + continue; + } + + ra_append_copy(ans_ra, bm_ra, i, false); + ans_ra->keys[j++] = key; + } + + return answer; + } + + uint8_t t; + const container_t *c; + container_t *lo, *hi, **lo_ptr, **hi_ptr; + int64_t k; + + for (int i = 0; i < length; ++i) { + lo = hi = NULL; + lo_ptr = hi_ptr = NULL; + + k = ra_get_key_at_index(bm_ra, i)+container_offset; + if (k >= 0 && k < (1 << 16)) { + lo_ptr = &lo; + } + if (k+1 >= 0 && k+1 < (1 << 16)) { + hi_ptr = &hi; + } + if (lo_ptr == NULL && hi_ptr == NULL) { + continue; + } + + c = ra_get_container_at_index(bm_ra, i, &t); + c = container_unwrap_shared(c, &t); + + container_add_offset(c, t, lo_ptr, hi_ptr, in_offset); + if (lo != NULL) { + offset_append_with_merge(ans_ra, k, lo, t); + } + if (hi != NULL) { + ra_append(ans_ra, k+1, hi, t); + } + } + + return answer; +} + +roaring_bitmap_t *roaring_bitmap_lazy_or(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2, + const bool bitsetconversion) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + if (0 == length1) { + return roaring_bitmap_copy(x2); + } + if (0 == length2) { + return roaring_bitmap_copy(x1); + } + roaring_bitmap_t *answer = + roaring_bitmap_create_with_capacity(length1 + length2); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c; + if (bitsetconversion && + (get_container_type(c1, type1) != BITSET_CONTAINER_TYPE) && + (get_container_type(c2, type2) != BITSET_CONTAINER_TYPE) + ){ + container_t *newc1 = + container_mutable_unwrap_shared(c1, &type1); + newc1 = container_to_bitset(newc1, type1); + type1 = BITSET_CONTAINER_TYPE; + c = container_lazy_ior(newc1, type1, c2, type2, + &result_type); + if (c != newc1) { // should not happen + container_free(newc1, type1); + } + } else { + c = container_lazy_or(c1, type1, c2, type2, &result_type); + } + // since we assume that the initial containers are non-empty, + // the + // result here + // can only be non-empty + ra_append(&answer->high_low_container, s1, c, result_type); + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + c1 = get_copy_of_container(c1, &type1, is_cow(x1)); + if (is_cow(x1)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c1, + type1); + } + ra_append(&answer->high_low_container, s1, c1, type1); + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_append(&answer->high_low_container, s2, c2, type2); + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&answer->high_low_container, + &x2->high_low_container, pos2, length2, + is_cow(x2)); + } else if (pos2 == length2) { + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1, + is_cow(x1)); + } + return answer; +} + +void roaring_bitmap_lazy_or_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2, + const bool bitsetconversion) { + uint8_t result_type = 0; + int length1 = x1->high_low_container.size; + const int length2 = x2->high_low_container.size; + + if (0 == length2) return; + + if (0 == length1) { + roaring_bitmap_overwrite(x1, x2); + return; + } + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + if (!container_is_full(c1, type1)) { + if ((bitsetconversion == false) || + (get_container_type(c1, type1) == BITSET_CONTAINER_TYPE) + ){ + c1 = get_writable_copy_if_shared(c1, &type1); + } else { + // convert to bitset + container_t *old_c1 = c1; + uint8_t old_type1 = type1; + c1 = container_mutable_unwrap_shared(c1, &type1); + c1 = container_to_bitset(c1, type1); + container_free(old_c1, old_type1); + type1 = BITSET_CONTAINER_TYPE; + } + + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_lazy_ior(c1, type1, c2, type2, + &result_type); + + if (c != c1) { // in this instance a new container was created, + // and we need to free the old one + container_free(c1, type1); + } + + ra_set_container_at_index(&x1->high_low_container, pos1, c, + result_type); + } + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + // container_t *c2_clone = container_clone(c2, type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_insert_new_key_value_at(&x1->high_low_container, pos1, s2, c2, + type2); + pos1++; + length1++; + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&x1->high_low_container, &x2->high_low_container, + pos2, length2, is_cow(x2)); + } +} + +roaring_bitmap_t *roaring_bitmap_lazy_xor(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + if (0 == length1) { + return roaring_bitmap_copy(x2); + } + if (0 == length2) { + return roaring_bitmap_copy(x1); + } + roaring_bitmap_t *answer = + roaring_bitmap_create_with_capacity(length1 + length2); + roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2)); + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + container_t *c = container_lazy_xor( + c1, type1, c2, type2, &result_type); + + if (container_nonzero_cardinality(c, result_type)) { + ra_append(&answer->high_low_container, s1, c, result_type); + } else { + container_free(c, result_type); + } + + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + c1 = get_copy_of_container(c1, &type1, is_cow(x1)); + if (is_cow(x1)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c1, + type1); + } + ra_append(&answer->high_low_container, s1, c1, type1); + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_append(&answer->high_low_container, s2, c2, type2); + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&answer->high_low_container, + &x2->high_low_container, pos2, length2, + is_cow(x2)); + } else if (pos2 == length2) { + ra_append_copy_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1, + is_cow(x1)); + } + return answer; +} + +void roaring_bitmap_lazy_xor_inplace(roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + assert(x1 != x2); + uint8_t result_type = 0; + int length1 = x1->high_low_container.size; + const int length2 = x2->high_low_container.size; + + if (0 == length2) return; + + if (0 == length1) { + roaring_bitmap_overwrite(x1, x2); + return; + } + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + + // We do the computation "in place" only when c1 is not a shared container. + // Rationale: using a shared container safely with in place computation would + // require making a copy and then doing the computation in place which is likely + // less efficient than avoiding in place entirely and always generating a new + // container. + + container_t *c; + if (type1 == SHARED_CONTAINER_TYPE) { + c = container_lazy_xor(c1, type1, c2, type2, &result_type); + shared_container_free(CAST_shared(c1)); // release + } + else { + c = container_lazy_ixor(c1, type1, c2, type2, &result_type); + } + + if (container_nonzero_cardinality(c, result_type)) { + ra_set_container_at_index(&x1->high_low_container, pos1, c, + result_type); + ++pos1; + } else { + container_free(c, result_type); + ra_remove_at_index(&x1->high_low_container, pos1); + --length1; + } + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + // container_t *c2_clone = container_clone(c2, type2); + c2 = get_copy_of_container(c2, &type2, is_cow(x2)); + if (is_cow(x2)) { + ra_set_container_at_index(&x2->high_low_container, pos2, c2, + type2); + } + ra_insert_new_key_value_at(&x1->high_low_container, pos1, s2, c2, + type2); + pos1++; + length1++; + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_copy_range(&x1->high_low_container, &x2->high_low_container, + pos2, length2, is_cow(x2)); + } +} + +void roaring_bitmap_repair_after_lazy(roaring_bitmap_t *r) { + roaring_array_t *ra = &r->high_low_container; + + for (int i = 0; i < ra->size; ++i) { + const uint8_t old_type = ra->typecodes[i]; + container_t *old_c = ra->containers[i]; + uint8_t new_type = old_type; + container_t *new_c = container_repair_after_lazy(old_c, &new_type); + ra->containers[i] = new_c; + ra->typecodes[i] = new_type; + } +} + + + +/** +* roaring_bitmap_rank returns the number of integers that are smaller or equal +* to x. +*/ +uint64_t roaring_bitmap_rank(const roaring_bitmap_t *bm, uint32_t x) { + uint64_t size = 0; + uint32_t xhigh = x >> 16; + for (int i = 0; i < bm->high_low_container.size; i++) { + uint32_t key = bm->high_low_container.keys[i]; + if (xhigh > key) { + size += + container_get_cardinality(bm->high_low_container.containers[i], + bm->high_low_container.typecodes[i]); + } else if (xhigh == key) { + return size + container_rank(bm->high_low_container.containers[i], + bm->high_low_container.typecodes[i], + x & 0xFFFF); + } else { + return size; + } + } + return size; +} + +/** +* roaring_bitmap_smallest returns the smallest value in the set. +* Returns UINT32_MAX if the set is empty. +*/ +uint32_t roaring_bitmap_minimum(const roaring_bitmap_t *bm) { + if (bm->high_low_container.size > 0) { + container_t *c = bm->high_low_container.containers[0]; + uint8_t type = bm->high_low_container.typecodes[0]; + uint32_t key = bm->high_low_container.keys[0]; + uint32_t lowvalue = container_minimum(c, type); + return lowvalue | (key << 16); + } + return UINT32_MAX; +} + +/** +* roaring_bitmap_smallest returns the greatest value in the set. +* Returns 0 if the set is empty. +*/ +uint32_t roaring_bitmap_maximum(const roaring_bitmap_t *bm) { + if (bm->high_low_container.size > 0) { + container_t *container = + bm->high_low_container.containers[bm->high_low_container.size - 1]; + uint8_t typecode = + bm->high_low_container.typecodes[bm->high_low_container.size - 1]; + uint32_t key = + bm->high_low_container.keys[bm->high_low_container.size - 1]; + uint32_t lowvalue = container_maximum(container, typecode); + return lowvalue | (key << 16); + } + return 0; +} + +bool roaring_bitmap_select(const roaring_bitmap_t *bm, uint32_t rank, + uint32_t *element) { + container_t *container; + uint8_t typecode; + uint16_t key; + uint32_t start_rank = 0; + int i = 0; + bool valid = false; + while (!valid && i < bm->high_low_container.size) { + container = bm->high_low_container.containers[i]; + typecode = bm->high_low_container.typecodes[i]; + valid = + container_select(container, typecode, &start_rank, rank, element); + i++; + } + + if (valid) { + key = bm->high_low_container.keys[i - 1]; + *element |= (((uint32_t)key) << 16); // w/o cast, key promotes signed + return true; + } else + return false; +} + +bool roaring_bitmap_intersect(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + uint64_t answer = 0; + int pos1 = 0, pos2 = 0; + + while (pos1 < length1 && pos2 < length2) { + const uint16_t s1 = ra_get_key_at_index(& x1->high_low_container, pos1); + const uint16_t s2 = ra_get_key_at_index(& x2->high_low_container, pos2); + + if (s1 == s2) { + uint8_t type1, type2; + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + if (container_intersect(c1, type1, c2, type2)) + return true; + ++pos1; + ++pos2; + } else if (s1 < s2) { // s1 < s2 + pos1 = ra_advance_until(& x1->high_low_container, s2, pos1); + } else { // s1 > s2 + pos2 = ra_advance_until(& x2->high_low_container, s1, pos2); + } + } + return answer != 0; +} + +bool roaring_bitmap_intersect_with_range(const roaring_bitmap_t *bm, + uint64_t x, uint64_t y) { + if (x >= y) { + // Empty range. + return false; + } + roaring_uint32_iterator_t it; + roaring_init_iterator(bm, &it); + if (!roaring_move_uint32_iterator_equalorlarger(&it, x)) { + // No values above x. + return false; + } + if (it.current_value >= y) { + // No values below y. + return false; + } + return true; +} + + +uint64_t roaring_bitmap_and_cardinality(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const int length1 = x1->high_low_container.size, + length2 = x2->high_low_container.size; + uint64_t answer = 0; + int pos1 = 0, pos2 = 0; + + while (pos1 < length1 && pos2 < length2) { + const uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + const uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + if (s1 == s2) { + uint8_t type1, type2; + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + answer += container_and_cardinality(c1, type1, c2, type2); + ++pos1; + ++pos2; + } else if (s1 < s2) { // s1 < s2 + pos1 = ra_advance_until(&x1->high_low_container, s2, pos1); + } else { // s1 > s2 + pos2 = ra_advance_until(&x2->high_low_container, s1, pos2); + } + } + return answer; +} + +double roaring_bitmap_jaccard_index(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const uint64_t c1 = roaring_bitmap_get_cardinality(x1); + const uint64_t c2 = roaring_bitmap_get_cardinality(x2); + const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2); + return (double)inter / (double)(c1 + c2 - inter); +} + +uint64_t roaring_bitmap_or_cardinality(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const uint64_t c1 = roaring_bitmap_get_cardinality(x1); + const uint64_t c2 = roaring_bitmap_get_cardinality(x2); + const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2); + return c1 + c2 - inter; +} + +uint64_t roaring_bitmap_andnot_cardinality(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const uint64_t c1 = roaring_bitmap_get_cardinality(x1); + const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2); + return c1 - inter; +} + +uint64_t roaring_bitmap_xor_cardinality(const roaring_bitmap_t *x1, + const roaring_bitmap_t *x2) { + const uint64_t c1 = roaring_bitmap_get_cardinality(x1); + const uint64_t c2 = roaring_bitmap_get_cardinality(x2); + const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2); + return c1 + c2 - 2 * inter; +} + + +bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val) { + const uint16_t hb = val >> 16; + /* + * the next function call involves a binary search and lots of branching. + */ + int32_t i = ra_get_index(&r->high_low_container, hb); + if (i < 0) return false; + + uint8_t typecode; + // next call ought to be cheap + container_t *container = + ra_get_container_at_index(&r->high_low_container, i, &typecode); + // rest might be a tad expensive, possibly involving another round of binary search + return container_contains(container, val & 0xFFFF, typecode); +} + + +/** + * Check whether a range of values from range_start (included) to range_end (excluded) is present + */ +bool roaring_bitmap_contains_range(const roaring_bitmap_t *r, uint64_t range_start, uint64_t range_end) { + if(range_end >= UINT64_C(0x100000000)) { + range_end = UINT64_C(0x100000000); + } + if (range_start >= range_end) return true; // empty range are always contained! + if (range_end - range_start == 1) return roaring_bitmap_contains(r, (uint32_t)range_start); + uint16_t hb_rs = (uint16_t)(range_start >> 16); + uint16_t hb_re = (uint16_t)((range_end - 1) >> 16); + const int32_t span = hb_re - hb_rs; + const int32_t hlc_sz = ra_get_size(&r->high_low_container); + if (hlc_sz < span + 1) { + return false; + } + int32_t is = ra_get_index(&r->high_low_container, hb_rs); + int32_t ie = ra_get_index(&r->high_low_container, hb_re); + ie = (ie < 0 ? -ie - 1 : ie); + if ((is < 0) || ((ie - is) != span)) { + return false; + } + const uint32_t lb_rs = range_start & 0xFFFF; + const uint32_t lb_re = ((range_end - 1) & 0xFFFF) + 1; + uint8_t type; + container_t *c = ra_get_container_at_index(&r->high_low_container, is, + &type); + if (hb_rs == hb_re) { + return container_contains_range(c, lb_rs, lb_re, type); + } + if (!container_contains_range(c, lb_rs, 1 << 16, type)) { + return false; + } + assert(ie < hlc_sz); // would indicate an algorithmic bug + c = ra_get_container_at_index(&r->high_low_container, ie, &type); + if (!container_contains_range(c, 0, lb_re, type)) { + return false; + } + for (int32_t i = is + 1; i < ie; ++i) { + c = ra_get_container_at_index(&r->high_low_container, i, &type); + if (!container_is_full(c, type) ) { + return false; + } + } + return true; +} + + +bool roaring_bitmap_is_strict_subset(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2) { + return (roaring_bitmap_get_cardinality(r2) > + roaring_bitmap_get_cardinality(r1) && + roaring_bitmap_is_subset(r1, r2)); +} + + +/* + * FROZEN SERIALIZATION FORMAT DESCRIPTION + * + * -- (beginning must be aligned by 32 bytes) -- + * uint64_t[BITSET_CONTAINER_SIZE_IN_WORDS * num_bitset_containers] + * rle16_t[total number of rle elements in all run containers] + * uint16_t[total number of array elements in all array containers] + * uint16_t[num_containers] + * uint16_t[num_containers] + * uint8_t[num_containers] + *
uint32_t + * + *
is a 4-byte value which is a bit union of FROZEN_COOKIE (15 bits) + * and the number of containers (17 bits). + * + * stores number of elements for every container. + * Its meaning depends on container type. + * For array and bitset containers, this value is the container cardinality minus one. + * For run container, it is the number of rle_t elements (n_runs). + * + * ,, are flat arrays of elements of + * all containers of respective type. + * + * <*_data> and are kept close together because they are not accessed + * during deserilization. This may reduce IO in case of large mmaped bitmaps. + * All members have their native alignments during deserilization except
, + * which is not guaranteed to be aligned by 4 bytes. + */ + +size_t roaring_bitmap_frozen_size_in_bytes(const roaring_bitmap_t *rb) { + const roaring_array_t *ra = &rb->high_low_container; + size_t num_bytes = 0; + for (int32_t i = 0; i < ra->size; i++) { + switch (ra->typecodes[i]) { + case BITSET_CONTAINER_TYPE: { + num_bytes += BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + break; + } + case RUN_CONTAINER_TYPE: { + const run_container_t *rc = const_CAST_run(ra->containers[i]); + num_bytes += rc->n_runs * sizeof(rle16_t); + break; + } + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = + const_CAST_array(ra->containers[i]); + num_bytes += ac->cardinality * sizeof(uint16_t); + break; + } + default: + __builtin_unreachable(); + } + } + num_bytes += (2 + 2 + 1) * ra->size; // keys, counts, typecodes + num_bytes += 4; // header + return num_bytes; +} + +inline static void *arena_alloc(char **arena, size_t num_bytes) { + char *res = *arena; + *arena += num_bytes; + return res; +} + +void roaring_bitmap_frozen_serialize(const roaring_bitmap_t *rb, char *buf) { + /* + * Note: we do not require user to supply a specifically aligned buffer. + * Thus we have to use memcpy() everywhere. + */ + + const roaring_array_t *ra = &rb->high_low_container; + + size_t bitset_zone_size = 0; + size_t run_zone_size = 0; + size_t array_zone_size = 0; + for (int32_t i = 0; i < ra->size; i++) { + switch (ra->typecodes[i]) { + case BITSET_CONTAINER_TYPE: { + bitset_zone_size += + BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + break; + } + case RUN_CONTAINER_TYPE: { + const run_container_t *rc = const_CAST_run(ra->containers[i]); + run_zone_size += rc->n_runs * sizeof(rle16_t); + break; + } + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = + const_CAST_array(ra->containers[i]); + array_zone_size += ac->cardinality * sizeof(uint16_t); + break; + } + default: + __builtin_unreachable(); + } + } + + uint64_t *bitset_zone = (uint64_t *)arena_alloc(&buf, bitset_zone_size); + rle16_t *run_zone = (rle16_t *)arena_alloc(&buf, run_zone_size); + uint16_t *array_zone = (uint16_t *)arena_alloc(&buf, array_zone_size); + uint16_t *key_zone = (uint16_t *)arena_alloc(&buf, 2*ra->size); + uint16_t *count_zone = (uint16_t *)arena_alloc(&buf, 2*ra->size); + uint8_t *typecode_zone = (uint8_t *)arena_alloc(&buf, ra->size); + uint32_t *header_zone = (uint32_t *)arena_alloc(&buf, 4); + + for (int32_t i = 0; i < ra->size; i++) { + uint16_t count; + switch (ra->typecodes[i]) { + case BITSET_CONTAINER_TYPE: { + const bitset_container_t *bc = + const_CAST_bitset(ra->containers[i]); + memcpy(bitset_zone, bc->words, + BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t)); + bitset_zone += BITSET_CONTAINER_SIZE_IN_WORDS; + if (bc->cardinality != BITSET_UNKNOWN_CARDINALITY) { + count = bc->cardinality - 1; + } else { + count = bitset_container_compute_cardinality(bc) - 1; + } + break; + } + case RUN_CONTAINER_TYPE: { + const run_container_t *rc = const_CAST_run(ra->containers[i]); + size_t num_bytes = rc->n_runs * sizeof(rle16_t); + memcpy(run_zone, rc->runs, num_bytes); + run_zone += rc->n_runs; + count = rc->n_runs; + break; + } + case ARRAY_CONTAINER_TYPE: { + const array_container_t *ac = + const_CAST_array(ra->containers[i]); + size_t num_bytes = ac->cardinality * sizeof(uint16_t); + memcpy(array_zone, ac->array, num_bytes); + array_zone += ac->cardinality; + count = ac->cardinality - 1; + break; + } + default: + __builtin_unreachable(); + } + memcpy(&count_zone[i], &count, 2); + } + memcpy(key_zone, ra->keys, ra->size * sizeof(uint16_t)); + memcpy(typecode_zone, ra->typecodes, ra->size * sizeof(uint8_t)); + uint32_t header = ((uint32_t)ra->size << 15) | FROZEN_COOKIE; + memcpy(header_zone, &header, 4); +} + +const roaring_bitmap_t * +roaring_bitmap_frozen_view(const char *buf, size_t length) { + if ((uintptr_t)buf % 32 != 0) { + return NULL; + } + + // cookie and num_containers + if (length < 4) { + return NULL; + } + uint32_t header; + memcpy(&header, buf + length - 4, 4); // header may be misaligned + if ((header & 0x7FFF) != FROZEN_COOKIE) { + return NULL; + } + int32_t num_containers = (header >> 15); + + // typecodes, counts and keys + if (length < 4 + (size_t)num_containers * (1 + 2 + 2)) { + return NULL; + } + uint16_t *keys = (uint16_t *)(buf + length - 4 - num_containers * 5); + uint16_t *counts = (uint16_t *)(buf + length - 4 - num_containers * 3); + uint8_t *typecodes = (uint8_t *)(buf + length - 4 - num_containers * 1); + + // {bitset,array,run}_zone + int32_t num_bitset_containers = 0; + int32_t num_run_containers = 0; + int32_t num_array_containers = 0; + size_t bitset_zone_size = 0; + size_t run_zone_size = 0; + size_t array_zone_size = 0; + for (int32_t i = 0; i < num_containers; i++) { + switch (typecodes[i]) { + case BITSET_CONTAINER_TYPE: + num_bitset_containers++; + bitset_zone_size += BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + break; + case RUN_CONTAINER_TYPE: + num_run_containers++; + run_zone_size += counts[i] * sizeof(rle16_t); + break; + case ARRAY_CONTAINER_TYPE: + num_array_containers++; + array_zone_size += (counts[i] + UINT32_C(1)) * sizeof(uint16_t); + break; + default: + return NULL; + } + } + if (length != bitset_zone_size + run_zone_size + array_zone_size + + 5 * num_containers + 4) { + return NULL; + } + uint64_t *bitset_zone = (uint64_t*) (buf); + rle16_t *run_zone = (rle16_t*) (buf + bitset_zone_size); + uint16_t *array_zone = (uint16_t*) (buf + bitset_zone_size + run_zone_size); + + size_t alloc_size = 0; + alloc_size += sizeof(roaring_bitmap_t); + alloc_size += num_containers * sizeof(container_t*); + alloc_size += num_bitset_containers * sizeof(bitset_container_t); + alloc_size += num_run_containers * sizeof(run_container_t); + alloc_size += num_array_containers * sizeof(array_container_t); + + char *arena = (char *)roaring_malloc(alloc_size); + if (arena == NULL) { + return NULL; + } + + roaring_bitmap_t *rb = (roaring_bitmap_t *) + arena_alloc(&arena, sizeof(roaring_bitmap_t)); + rb->high_low_container.flags = ROARING_FLAG_FROZEN; + rb->high_low_container.allocation_size = num_containers; + rb->high_low_container.size = num_containers; + rb->high_low_container.keys = (uint16_t *)keys; + rb->high_low_container.typecodes = (uint8_t *)typecodes; + rb->high_low_container.containers = + (container_t **)arena_alloc(&arena, + sizeof(container_t*) * num_containers); + // Ensure offset of high_low_container.containers is known distance used in + // C++ wrapper. sizeof(roaring_bitmap_t) is used as it is the size of the + // only allocation that precedes high_low_container.containers. If this is + // changed (new allocation or changed order), this offset will also need to + // be changed in the C++ wrapper. + assert(rb == + (roaring_bitmap_t *)((char *)rb->high_low_container.containers - + sizeof(roaring_bitmap_t))); + for (int32_t i = 0; i < num_containers; i++) { + switch (typecodes[i]) { + case BITSET_CONTAINER_TYPE: { + bitset_container_t *bitset = (bitset_container_t *) + arena_alloc(&arena, sizeof(bitset_container_t)); + bitset->words = bitset_zone; + bitset->cardinality = counts[i] + UINT32_C(1); + rb->high_low_container.containers[i] = bitset; + bitset_zone += BITSET_CONTAINER_SIZE_IN_WORDS; + break; + } + case RUN_CONTAINER_TYPE: { + run_container_t *run = (run_container_t *) + arena_alloc(&arena, sizeof(run_container_t)); + run->capacity = counts[i]; + run->n_runs = counts[i]; + run->runs = run_zone; + rb->high_low_container.containers[i] = run; + run_zone += run->n_runs; + break; + } + case ARRAY_CONTAINER_TYPE: { + array_container_t *array = (array_container_t *) + arena_alloc(&arena, sizeof(array_container_t)); + array->capacity = counts[i] + UINT32_C(1); + array->cardinality = counts[i] + UINT32_C(1); + array->array = array_zone; + rb->high_low_container.containers[i] = array; + array_zone += counts[i] + UINT32_C(1); + break; + } + default: + roaring_free(arena); + return NULL; + } + } + + return rb; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { +#endif +/* end file src/roaring.c */ +/* begin file src/roaring_array.c */ +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace internal { +#endif + +// Convention: [0,ra->size) all elements are initialized +// [ra->size, ra->allocation_size) is junk and contains nothing needing freeing + +extern inline int32_t ra_get_size(const roaring_array_t *ra); +extern inline int32_t ra_get_index(const roaring_array_t *ra, uint16_t x); + +extern inline container_t *ra_get_container_at_index( + const roaring_array_t *ra, uint16_t i, + uint8_t *typecode); + +extern inline void ra_unshare_container_at_index(roaring_array_t *ra, + uint16_t i); + +extern inline void ra_replace_key_and_container_at_index( + roaring_array_t *ra, int32_t i, uint16_t key, + container_t *c, uint8_t typecode); + +extern inline void ra_set_container_at_index( + const roaring_array_t *ra, int32_t i, + container_t *c, uint8_t typecode); + +static bool realloc_array(roaring_array_t *ra, int32_t new_capacity) { + // + // Note: not implemented using C's realloc(), because the memory layout is + // Struct-of-Arrays vs. Array-of-Structs: + // https://github.com/RoaringBitmap/CRoaring/issues/256 + + if ( new_capacity == 0 ) { + roaring_free(ra->containers); + ra->containers = NULL; + ra->keys = NULL; + ra->typecodes = NULL; + ra->allocation_size = 0; + return true; + } + const size_t memoryneeded = new_capacity * ( + sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t)); + void *bigalloc = roaring_malloc(memoryneeded); + if (!bigalloc) return false; + void *oldbigalloc = ra->containers; + container_t **newcontainers = (container_t **)bigalloc; + uint16_t *newkeys = (uint16_t *)(newcontainers + new_capacity); + uint8_t *newtypecodes = (uint8_t *)(newkeys + new_capacity); + assert((char *)(newtypecodes + new_capacity) == + (char *)bigalloc + memoryneeded); + if(ra->size > 0) { + memcpy(newcontainers, ra->containers, sizeof(container_t *) * ra->size); + memcpy(newkeys, ra->keys, sizeof(uint16_t) * ra->size); + memcpy(newtypecodes, ra->typecodes, sizeof(uint8_t) * ra->size); + } + ra->containers = newcontainers; + ra->keys = newkeys; + ra->typecodes = newtypecodes; + ra->allocation_size = new_capacity; + roaring_free(oldbigalloc); + return true; +} + +bool ra_init_with_capacity(roaring_array_t *new_ra, uint32_t cap) { + if (!new_ra) return false; + ra_init(new_ra); + + if (cap > INT32_MAX) { return false; } + + if(cap > 0) { + void *bigalloc = roaring_malloc(cap * + (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t))); + if( bigalloc == NULL ) return false; + new_ra->containers = (container_t **)bigalloc; + new_ra->keys = (uint16_t *)(new_ra->containers + cap); + new_ra->typecodes = (uint8_t *)(new_ra->keys + cap); + // Narrowing is safe because of above check + new_ra->allocation_size = (int32_t)cap; + } + return true; +} + +int ra_shrink_to_fit(roaring_array_t *ra) { + int savings = (ra->allocation_size - ra->size) * + (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t)); + if (!realloc_array(ra, ra->size)) { + return 0; + } + ra->allocation_size = ra->size; + return savings; +} + +void ra_init(roaring_array_t *new_ra) { + if (!new_ra) { return; } + new_ra->keys = NULL; + new_ra->containers = NULL; + new_ra->typecodes = NULL; + + new_ra->allocation_size = 0; + new_ra->size = 0; + new_ra->flags = 0; +} + +bool ra_overwrite(const roaring_array_t *source, roaring_array_t *dest, + bool copy_on_write) { + ra_clear_containers(dest); // we are going to overwrite them + if (source->size == 0) { // Note: can't call memcpy(NULL), even w/size + dest->size = 0; // <--- This is important. + return true; // output was just cleared, so they match + } + if (dest->allocation_size < source->size) { + if (!realloc_array(dest, source->size)) { + return false; + } + } + dest->size = source->size; + memcpy(dest->keys, source->keys, dest->size * sizeof(uint16_t)); + // we go through the containers, turning them into shared containers... + if (copy_on_write) { + for (int32_t i = 0; i < dest->size; ++i) { + source->containers[i] = get_copy_of_container( + source->containers[i], &source->typecodes[i], copy_on_write); + } + // we do a shallow copy to the other bitmap + memcpy(dest->containers, source->containers, + dest->size * sizeof(container_t *)); + memcpy(dest->typecodes, source->typecodes, + dest->size * sizeof(uint8_t)); + } else { + memcpy(dest->typecodes, source->typecodes, + dest->size * sizeof(uint8_t)); + for (int32_t i = 0; i < dest->size; i++) { + dest->containers[i] = + container_clone(source->containers[i], source->typecodes[i]); + if (dest->containers[i] == NULL) { + for (int32_t j = 0; j < i; j++) { + container_free(dest->containers[j], dest->typecodes[j]); + } + ra_clear_without_containers(dest); + return false; + } + } + } + return true; +} + +void ra_clear_containers(roaring_array_t *ra) { + for (int32_t i = 0; i < ra->size; ++i) { + container_free(ra->containers[i], ra->typecodes[i]); + } +} + +void ra_reset(roaring_array_t *ra) { + ra_clear_containers(ra); + ra->size = 0; + ra_shrink_to_fit(ra); +} + +void ra_clear_without_containers(roaring_array_t *ra) { + roaring_free(ra->containers); // keys and typecodes are allocated with containers + ra->size = 0; + ra->allocation_size = 0; + ra->containers = NULL; + ra->keys = NULL; + ra->typecodes = NULL; +} + +void ra_clear(roaring_array_t *ra) { + ra_clear_containers(ra); + ra_clear_without_containers(ra); +} + +bool extend_array(roaring_array_t *ra, int32_t k) { + int32_t desired_size = ra->size + k; + const int32_t max_containers = 65536; + assert(desired_size <= max_containers); + if (desired_size > ra->allocation_size) { + int32_t new_capacity = + (ra->size < 1024) ? 2 * desired_size : 5 * desired_size / 4; + if (new_capacity > max_containers) { + new_capacity = max_containers; + } + + return realloc_array(ra, new_capacity); + } + return true; +} + +void ra_append( + roaring_array_t *ra, uint16_t key, + container_t *c, uint8_t typecode +){ + extend_array(ra, 1); + const int32_t pos = ra->size; + + ra->keys[pos] = key; + ra->containers[pos] = c; + ra->typecodes[pos] = typecode; + ra->size++; +} + +void ra_append_copy(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t index, bool copy_on_write) { + extend_array(ra, 1); + const int32_t pos = ra->size; + + // old contents is junk not needing freeing + ra->keys[pos] = sa->keys[index]; + // the shared container will be in two bitmaps + if (copy_on_write) { + sa->containers[index] = get_copy_of_container( + sa->containers[index], &sa->typecodes[index], copy_on_write); + ra->containers[pos] = sa->containers[index]; + ra->typecodes[pos] = sa->typecodes[index]; + } else { + ra->containers[pos] = + container_clone(sa->containers[index], sa->typecodes[index]); + ra->typecodes[pos] = sa->typecodes[index]; + } + ra->size++; +} + +void ra_append_copies_until(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t stopping_key, bool copy_on_write) { + for (int32_t i = 0; i < sa->size; ++i) { + if (sa->keys[i] >= stopping_key) break; + ra_append_copy(ra, sa, i, copy_on_write); + } +} + +void ra_append_copy_range(roaring_array_t *ra, const roaring_array_t *sa, + int32_t start_index, int32_t end_index, + bool copy_on_write) { + extend_array(ra, end_index - start_index); + for (int32_t i = start_index; i < end_index; ++i) { + const int32_t pos = ra->size; + ra->keys[pos] = sa->keys[i]; + if (copy_on_write) { + sa->containers[i] = get_copy_of_container( + sa->containers[i], &sa->typecodes[i], copy_on_write); + ra->containers[pos] = sa->containers[i]; + ra->typecodes[pos] = sa->typecodes[i]; + } else { + ra->containers[pos] = + container_clone(sa->containers[i], sa->typecodes[i]); + ra->typecodes[pos] = sa->typecodes[i]; + } + ra->size++; + } +} + +void ra_append_copies_after(roaring_array_t *ra, const roaring_array_t *sa, + uint16_t before_start, bool copy_on_write) { + int start_location = ra_get_index(sa, before_start); + if (start_location >= 0) + ++start_location; + else + start_location = -start_location - 1; + ra_append_copy_range(ra, sa, start_location, sa->size, copy_on_write); +} + +void ra_append_move_range(roaring_array_t *ra, roaring_array_t *sa, + int32_t start_index, int32_t end_index) { + extend_array(ra, end_index - start_index); + + for (int32_t i = start_index; i < end_index; ++i) { + const int32_t pos = ra->size; + + ra->keys[pos] = sa->keys[i]; + ra->containers[pos] = sa->containers[i]; + ra->typecodes[pos] = sa->typecodes[i]; + ra->size++; + } +} + +void ra_append_range(roaring_array_t *ra, roaring_array_t *sa, + int32_t start_index, int32_t end_index, + bool copy_on_write) { + extend_array(ra, end_index - start_index); + + for (int32_t i = start_index; i < end_index; ++i) { + const int32_t pos = ra->size; + ra->keys[pos] = sa->keys[i]; + if (copy_on_write) { + sa->containers[i] = get_copy_of_container( + sa->containers[i], &sa->typecodes[i], copy_on_write); + ra->containers[pos] = sa->containers[i]; + ra->typecodes[pos] = sa->typecodes[i]; + } else { + ra->containers[pos] = + container_clone(sa->containers[i], sa->typecodes[i]); + ra->typecodes[pos] = sa->typecodes[i]; + } + ra->size++; + } +} + +container_t *ra_get_container( + roaring_array_t *ra, uint16_t x, uint8_t *typecode +){ + int i = binarySearch(ra->keys, (int32_t)ra->size, x); + if (i < 0) return NULL; + *typecode = ra->typecodes[i]; + return ra->containers[i]; +} + +extern inline container_t *ra_get_container_at_index( + const roaring_array_t *ra, uint16_t i, + uint8_t *typecode); + +#ifdef ROARING_NOT_USED +container_t *ra_get_writable_container( + roaring_array_t *ra, uint16_t x, + uint8_t *typecode +){ + int i = binarySearch(ra->keys, (int32_t)ra->size, x); + if (i < 0) return NULL; + *typecode = ra->typecodes[i]; + return get_writable_copy_if_shared(ra->containers[i], typecode); +} + +container_t *ra_get_writable_container_at_index( + roaring_array_t *ra, uint16_t i, + uint8_t *typecode +){ + assert(i < ra->size); + *typecode = ra->typecodes[i]; + return get_writable_copy_if_shared(ra->containers[i], typecode); +} +#endif + +uint16_t ra_get_key_at_index(const roaring_array_t *ra, uint16_t i) { + return ra->keys[i]; +} + +extern inline int32_t ra_get_index(const roaring_array_t *ra, uint16_t x); + +extern inline int32_t ra_advance_until(const roaring_array_t *ra, uint16_t x, + int32_t pos); + +// everything skipped over is freed +int32_t ra_advance_until_freeing(roaring_array_t *ra, uint16_t x, int32_t pos) { + while (pos < ra->size && ra->keys[pos] < x) { + container_free(ra->containers[pos], ra->typecodes[pos]); + ++pos; + } + return pos; +} + +void ra_insert_new_key_value_at( + roaring_array_t *ra, int32_t i, uint16_t key, + container_t *c, uint8_t typecode +){ + extend_array(ra, 1); + // May be an optimization opportunity with DIY memmove + memmove(&(ra->keys[i + 1]), &(ra->keys[i]), + sizeof(uint16_t) * (ra->size - i)); + memmove(&(ra->containers[i + 1]), &(ra->containers[i]), + sizeof(container_t *) * (ra->size - i)); + memmove(&(ra->typecodes[i + 1]), &(ra->typecodes[i]), + sizeof(uint8_t) * (ra->size - i)); + ra->keys[i] = key; + ra->containers[i] = c; + ra->typecodes[i] = typecode; + ra->size++; +} + +// note: Java routine set things to 0, enabling GC. +// Java called it "resize" but it was always used to downsize. +// Allowing upsize would break the conventions about +// valid containers below ra->size. + +void ra_downsize(roaring_array_t *ra, int32_t new_length) { + assert(new_length <= ra->size); + ra->size = new_length; +} + +void ra_remove_at_index(roaring_array_t *ra, int32_t i) { + memmove(&(ra->containers[i]), &(ra->containers[i + 1]), + sizeof(container_t *) * (ra->size - i - 1)); + memmove(&(ra->keys[i]), &(ra->keys[i + 1]), + sizeof(uint16_t) * (ra->size - i - 1)); + memmove(&(ra->typecodes[i]), &(ra->typecodes[i + 1]), + sizeof(uint8_t) * (ra->size - i - 1)); + ra->size--; +} + +void ra_remove_at_index_and_free(roaring_array_t *ra, int32_t i) { + container_free(ra->containers[i], ra->typecodes[i]); + ra_remove_at_index(ra, i); +} + +// used in inplace andNot only, to slide left the containers from +// the mutated RoaringBitmap that are after the largest container of +// the argument RoaringBitmap. In use it should be followed by a call to +// downsize. +// +void ra_copy_range(roaring_array_t *ra, uint32_t begin, uint32_t end, + uint32_t new_begin) { + assert(begin <= end); + assert(new_begin < begin); + + const int range = end - begin; + + // We ensure to previously have freed overwritten containers + // that are not copied elsewhere + + memmove(&(ra->containers[new_begin]), &(ra->containers[begin]), + sizeof(container_t *) * range); + memmove(&(ra->keys[new_begin]), &(ra->keys[begin]), + sizeof(uint16_t) * range); + memmove(&(ra->typecodes[new_begin]), &(ra->typecodes[begin]), + sizeof(uint8_t) * range); +} + +void ra_shift_tail(roaring_array_t *ra, int32_t count, int32_t distance) { + if (distance > 0) { + extend_array(ra, distance); + } + int32_t srcpos = ra->size - count; + int32_t dstpos = srcpos + distance; + memmove(&(ra->keys[dstpos]), &(ra->keys[srcpos]), + sizeof(uint16_t) * count); + memmove(&(ra->containers[dstpos]), &(ra->containers[srcpos]), + sizeof(container_t *) * count); + memmove(&(ra->typecodes[dstpos]), &(ra->typecodes[srcpos]), + sizeof(uint8_t) * count); + ra->size += distance; +} + + +void ra_to_uint32_array(const roaring_array_t *ra, uint32_t *ans) { + size_t ctr = 0; + for (int32_t i = 0; i < ra->size; ++i) { + int num_added = container_to_uint32_array( + ans + ctr, ra->containers[i], ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16); + ctr += num_added; + } +} + +bool ra_range_uint32_array(const roaring_array_t *ra, size_t offset, size_t limit, uint32_t *ans) { + size_t ctr = 0; + size_t dtr = 0; + + size_t t_limit = 0; + + bool first = false; + size_t first_skip = 0; + + uint32_t *t_ans = NULL; + size_t cur_len = 0; + + for (int i = 0; i < ra->size; ++i) { + + const container_t *c = container_unwrap_shared( + ra->containers[i], &ra->typecodes[i]); + switch (ra->typecodes[i]) { + case BITSET_CONTAINER_TYPE: + t_limit = (const_CAST_bitset(c))->cardinality; + break; + case ARRAY_CONTAINER_TYPE: + t_limit = (const_CAST_array(c))->cardinality; + break; + case RUN_CONTAINER_TYPE: + t_limit = run_container_cardinality(const_CAST_run(c)); + break; + } + if (ctr + t_limit - 1 >= offset && ctr < offset + limit){ + if (!first){ + //first_skip = t_limit - (ctr + t_limit - offset); + first_skip = offset - ctr; + first = true; + t_ans = (uint32_t *)roaring_malloc(sizeof(*t_ans) * (first_skip + limit)); + if(t_ans == NULL) { + return false; + } + memset(t_ans, 0, sizeof(*t_ans) * (first_skip + limit)) ; + cur_len = first_skip + limit; + } + if (dtr + t_limit > cur_len){ + uint32_t * append_ans = (uint32_t *)roaring_malloc(sizeof(*append_ans) * (cur_len + t_limit)); + if(append_ans == NULL) { + if(t_ans != NULL) roaring_free(t_ans); + return false; + } + memset(append_ans, 0, sizeof(*append_ans) * (cur_len + t_limit)); + cur_len = cur_len + t_limit; + memcpy(append_ans, t_ans, dtr * sizeof(uint32_t)); + roaring_free(t_ans); + t_ans = append_ans; + } + switch (ra->typecodes[i]) { + case BITSET_CONTAINER_TYPE: + container_to_uint32_array( + t_ans + dtr, + const_CAST_bitset(c), ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16); + break; + case ARRAY_CONTAINER_TYPE: + container_to_uint32_array( + t_ans + dtr, + const_CAST_array(c), ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16); + break; + case RUN_CONTAINER_TYPE: + container_to_uint32_array( + t_ans + dtr, + const_CAST_run(c), ra->typecodes[i], + ((uint32_t)ra->keys[i]) << 16); + break; + } + dtr += t_limit; + } + ctr += t_limit; + if (dtr-first_skip >= limit) break; + } + if(t_ans != NULL) { + memcpy(ans, t_ans+first_skip, limit * sizeof(uint32_t)); + free(t_ans); + } + return true; +} + +bool ra_has_run_container(const roaring_array_t *ra) { + for (int32_t k = 0; k < ra->size; ++k) { + if (get_container_type(ra->containers[k], ra->typecodes[k]) == + RUN_CONTAINER_TYPE) + return true; + } + return false; +} + +uint32_t ra_portable_header_size(const roaring_array_t *ra) { + if (ra_has_run_container(ra)) { + if (ra->size < + NO_OFFSET_THRESHOLD) { // for small bitmaps, we omit the offsets + return 4 + (ra->size + 7) / 8 + 4 * ra->size; + } + return 4 + (ra->size + 7) / 8 + + 8 * ra->size; // - 4 because we pack the size with the cookie + } else { + return 4 + 4 + 8 * ra->size; + } +} + +size_t ra_portable_size_in_bytes(const roaring_array_t *ra) { + size_t count = ra_portable_header_size(ra); + + for (int32_t k = 0; k < ra->size; ++k) { + count += container_size_in_bytes(ra->containers[k], ra->typecodes[k]); + } + return count; +} + +size_t ra_portable_serialize(const roaring_array_t *ra, char *buf) { + char *initbuf = buf; + uint32_t startOffset = 0; + bool hasrun = ra_has_run_container(ra); + if (hasrun) { + uint32_t cookie = SERIAL_COOKIE | ((ra->size - 1) << 16); + memcpy(buf, &cookie, sizeof(cookie)); + buf += sizeof(cookie); + uint32_t s = (ra->size + 7) / 8; + uint8_t *bitmapOfRunContainers = (uint8_t *)roaring_calloc(s, 1); + assert(bitmapOfRunContainers != NULL); // todo: handle + for (int32_t i = 0; i < ra->size; ++i) { + if (get_container_type(ra->containers[i], ra->typecodes[i]) == + RUN_CONTAINER_TYPE) { + bitmapOfRunContainers[i / 8] |= (1 << (i % 8)); + } + } + memcpy(buf, bitmapOfRunContainers, s); + buf += s; + roaring_free(bitmapOfRunContainers); + if (ra->size < NO_OFFSET_THRESHOLD) { + startOffset = 4 + 4 * ra->size + s; + } else { + startOffset = 4 + 8 * ra->size + s; + } + } else { // backwards compatibility + uint32_t cookie = SERIAL_COOKIE_NO_RUNCONTAINER; + + memcpy(buf, &cookie, sizeof(cookie)); + buf += sizeof(cookie); + memcpy(buf, &ra->size, sizeof(ra->size)); + buf += sizeof(ra->size); + + startOffset = 4 + 4 + 4 * ra->size + 4 * ra->size; + } + for (int32_t k = 0; k < ra->size; ++k) { + memcpy(buf, &ra->keys[k], sizeof(ra->keys[k])); + buf += sizeof(ra->keys[k]); + // get_cardinality returns a value in [1,1<<16], subtracting one + // we get [0,1<<16 - 1] which fits in 16 bits + uint16_t card = (uint16_t)( + container_get_cardinality(ra->containers[k], ra->typecodes[k]) - 1); + memcpy(buf, &card, sizeof(card)); + buf += sizeof(card); + } + if ((!hasrun) || (ra->size >= NO_OFFSET_THRESHOLD)) { + // writing the containers offsets + for (int32_t k = 0; k < ra->size; k++) { + memcpy(buf, &startOffset, sizeof(startOffset)); + buf += sizeof(startOffset); + startOffset = + startOffset + + container_size_in_bytes(ra->containers[k], ra->typecodes[k]); + } + } + for (int32_t k = 0; k < ra->size; ++k) { + buf += container_write(ra->containers[k], ra->typecodes[k], buf); + } + return buf - initbuf; +} + +// Quickly checks whether there is a serialized bitmap at the pointer, +// not exceeding size "maxbytes" in bytes. This function does not allocate +// memory dynamically. +// +// This function returns 0 if and only if no valid bitmap is found. +// Otherwise, it returns how many bytes are occupied. +// +size_t ra_portable_deserialize_size(const char *buf, const size_t maxbytes) { + size_t bytestotal = sizeof(int32_t);// for cookie + if(bytestotal > maxbytes) return 0; + uint32_t cookie; + memcpy(&cookie, buf, sizeof(int32_t)); + buf += sizeof(uint32_t); + if ((cookie & 0xFFFF) != SERIAL_COOKIE && + cookie != SERIAL_COOKIE_NO_RUNCONTAINER) { + return 0; + } + int32_t size; + + if ((cookie & 0xFFFF) == SERIAL_COOKIE) + size = (cookie >> 16) + 1; + else { + bytestotal += sizeof(int32_t); + if(bytestotal > maxbytes) return 0; + memcpy(&size, buf, sizeof(int32_t)); + buf += sizeof(uint32_t); + } + if (size > (1<<16)) { + return 0; // logically impossible + } + char *bitmapOfRunContainers = NULL; + bool hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; + if (hasrun) { + int32_t s = (size + 7) / 8; + bytestotal += s; + if(bytestotal > maxbytes) return 0; + bitmapOfRunContainers = (char *)buf; + buf += s; + } + bytestotal += size * 2 * sizeof(uint16_t); + if(bytestotal > maxbytes) return 0; + uint16_t *keyscards = (uint16_t *)buf; + buf += size * 2 * sizeof(uint16_t); + if ((!hasrun) || (size >= NO_OFFSET_THRESHOLD)) { + // skipping the offsets + bytestotal += size * 4; + if(bytestotal > maxbytes) return 0; + buf += size * 4; + } + // Reading the containers + for (int32_t k = 0; k < size; ++k) { + uint16_t tmp; + memcpy(&tmp, keyscards + 2*k+1, sizeof(tmp)); + uint32_t thiscard = tmp + 1; + bool isbitmap = (thiscard > DEFAULT_MAX_SIZE); + bool isrun = false; + if(hasrun) { + if((bitmapOfRunContainers[k / 8] & (1 << (k % 8))) != 0) { + isbitmap = false; + isrun = true; + } + } + if (isbitmap) { + size_t containersize = BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + bytestotal += containersize; + if(bytestotal > maxbytes) return 0; + buf += containersize; + } else if (isrun) { + bytestotal += sizeof(uint16_t); + if(bytestotal > maxbytes) return 0; + uint16_t n_runs; + memcpy(&n_runs, buf, sizeof(uint16_t)); + buf += sizeof(uint16_t); + size_t containersize = n_runs * sizeof(rle16_t); + bytestotal += containersize; + if(bytestotal > maxbytes) return 0; + buf += containersize; + } else { + size_t containersize = thiscard * sizeof(uint16_t); + bytestotal += containersize; + if(bytestotal > maxbytes) return 0; + buf += containersize; + } + } + return bytestotal; +} + + +// this function populates answer from the content of buf (reading up to maxbytes bytes). +// The function returns false if a properly serialized bitmap cannot be found. +// if it returns true, readbytes is populated by how many bytes were read, we have that *readbytes <= maxbytes. +bool ra_portable_deserialize(roaring_array_t *answer, const char *buf, const size_t maxbytes, size_t * readbytes) { + *readbytes = sizeof(int32_t);// for cookie + if(*readbytes > maxbytes) { + fprintf(stderr, "Ran out of bytes while reading first 4 bytes.\n"); + return false; + } + uint32_t cookie; + memcpy(&cookie, buf, sizeof(int32_t)); + buf += sizeof(uint32_t); + if ((cookie & 0xFFFF) != SERIAL_COOKIE && + cookie != SERIAL_COOKIE_NO_RUNCONTAINER) { + fprintf(stderr, "I failed to find one of the right cookies. Found %" PRIu32 "\n", + cookie); + return false; + } + int32_t size; + + if ((cookie & 0xFFFF) == SERIAL_COOKIE) + size = (cookie >> 16) + 1; + else { + *readbytes += sizeof(int32_t); + if(*readbytes > maxbytes) { + fprintf(stderr, "Ran out of bytes while reading second part of the cookie.\n"); + return false; + } + memcpy(&size, buf, sizeof(int32_t)); + buf += sizeof(uint32_t); + } + if (size < 0) { + fprintf(stderr, "You cannot have a negative number of containers, the data must be corrupted: %" PRId32 "\n", + size); + return false; // logically impossible + } + if (size > (1<<16)) { + fprintf(stderr, "You cannot have so many containers, the data must be corrupted: %" PRId32 "\n", + size); + return false; // logically impossible + } + const char *bitmapOfRunContainers = NULL; + bool hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE; + if (hasrun) { + int32_t s = (size + 7) / 8; + *readbytes += s; + if(*readbytes > maxbytes) {// data is corrupted? + fprintf(stderr, "Ran out of bytes while reading run bitmap.\n"); + return false; + } + bitmapOfRunContainers = buf; + buf += s; + } + uint16_t *keyscards = (uint16_t *)buf; + + *readbytes += size * 2 * sizeof(uint16_t); + if(*readbytes > maxbytes) { + fprintf(stderr, "Ran out of bytes while reading key-cardinality array.\n"); + return false; + } + buf += size * 2 * sizeof(uint16_t); + + bool is_ok = ra_init_with_capacity(answer, size); + if (!is_ok) { + fprintf(stderr, "Failed to allocate memory for roaring array. Bailing out.\n"); + return false; + } + + for (int32_t k = 0; k < size; ++k) { + uint16_t tmp; + memcpy(&tmp, keyscards + 2*k, sizeof(tmp)); + answer->keys[k] = tmp; + } + if ((!hasrun) || (size >= NO_OFFSET_THRESHOLD)) { + *readbytes += size * 4; + if(*readbytes > maxbytes) {// data is corrupted? + fprintf(stderr, "Ran out of bytes while reading offsets.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + + // skipping the offsets + buf += size * 4; + } + // Reading the containers + for (int32_t k = 0; k < size; ++k) { + uint16_t tmp; + memcpy(&tmp, keyscards + 2*k+1, sizeof(tmp)); + uint32_t thiscard = tmp + 1; + bool isbitmap = (thiscard > DEFAULT_MAX_SIZE); + bool isrun = false; + if(hasrun) { + if((bitmapOfRunContainers[k / 8] & (1 << (k % 8))) != 0) { + isbitmap = false; + isrun = true; + } + } + if (isbitmap) { + // we check that the read is allowed + size_t containersize = BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t); + *readbytes += containersize; + if(*readbytes > maxbytes) { + fprintf(stderr, "Running out of bytes while reading a bitset container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + // it is now safe to read + bitset_container_t *c = bitset_container_create(); + if(c == NULL) {// memory allocation failure + fprintf(stderr, "Failed to allocate memory for a bitset container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + answer->size++; + buf += bitset_container_read(thiscard, c, buf); + answer->containers[k] = c; + answer->typecodes[k] = BITSET_CONTAINER_TYPE; + } else if (isrun) { + // we check that the read is allowed + *readbytes += sizeof(uint16_t); + if(*readbytes > maxbytes) { + fprintf(stderr, "Running out of bytes while reading a run container (header).\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + uint16_t n_runs; + memcpy(&n_runs, buf, sizeof(uint16_t)); + size_t containersize = n_runs * sizeof(rle16_t); + *readbytes += containersize; + if(*readbytes > maxbytes) {// data is corrupted? + fprintf(stderr, "Running out of bytes while reading a run container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + // it is now safe to read + + run_container_t *c = run_container_create(); + if(c == NULL) {// memory allocation failure + fprintf(stderr, "Failed to allocate memory for a run container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + answer->size++; + buf += run_container_read(thiscard, c, buf); + answer->containers[k] = c; + answer->typecodes[k] = RUN_CONTAINER_TYPE; + } else { + // we check that the read is allowed + size_t containersize = thiscard * sizeof(uint16_t); + *readbytes += containersize; + if(*readbytes > maxbytes) {// data is corrupted? + fprintf(stderr, "Running out of bytes while reading an array container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + // it is now safe to read + array_container_t *c = + array_container_create_given_capacity(thiscard); + if(c == NULL) {// memory allocation failure + fprintf(stderr, "Failed to allocate memory for an array container.\n"); + ra_clear(answer);// we need to clear the containers already allocated, and the roaring array + return false; + } + answer->size++; + buf += array_container_read(thiscard, c, buf); + answer->containers[k] = c; + answer->typecodes[k] = ARRAY_CONTAINER_TYPE; + } + } + return true; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace internal { +#endif +/* end file src/roaring_array.c */ +/* begin file src/roaring_priority_queue.c */ + + +#ifdef __cplusplus +using namespace ::roaring::internal; + +extern "C" { namespace roaring { namespace api { +#endif + +struct roaring_pq_element_s { + uint64_t size; + bool is_temporary; + roaring_bitmap_t *bitmap; +}; + +typedef struct roaring_pq_element_s roaring_pq_element_t; + +struct roaring_pq_s { + roaring_pq_element_t *elements; + uint64_t size; +}; + +typedef struct roaring_pq_s roaring_pq_t; + +static inline bool compare(roaring_pq_element_t *t1, roaring_pq_element_t *t2) { + return t1->size < t2->size; +} + +static void pq_add(roaring_pq_t *pq, roaring_pq_element_t *t) { + uint64_t i = pq->size; + pq->elements[pq->size++] = *t; + while (i > 0) { + uint64_t p = (i - 1) >> 1; + roaring_pq_element_t ap = pq->elements[p]; + if (!compare(t, &ap)) break; + pq->elements[i] = ap; + i = p; + } + pq->elements[i] = *t; +} + +static void pq_free(roaring_pq_t *pq) { + roaring_free(pq); +} + +static void percolate_down(roaring_pq_t *pq, uint32_t i) { + uint32_t size = (uint32_t)pq->size; + uint32_t hsize = size >> 1; + roaring_pq_element_t ai = pq->elements[i]; + while (i < hsize) { + uint32_t l = (i << 1) + 1; + uint32_t r = l + 1; + roaring_pq_element_t bestc = pq->elements[l]; + if (r < size) { + if (compare(pq->elements + r, &bestc)) { + l = r; + bestc = pq->elements[r]; + } + } + if (!compare(&bestc, &ai)) { + break; + } + pq->elements[i] = bestc; + i = l; + } + pq->elements[i] = ai; +} + +static roaring_pq_t *create_pq(const roaring_bitmap_t **arr, uint32_t length) { + size_t alloc_size = sizeof(roaring_pq_t) + sizeof(roaring_pq_element_t) * length; + roaring_pq_t *answer = (roaring_pq_t *)roaring_malloc(alloc_size); + answer->elements = (roaring_pq_element_t *)(answer + 1); + answer->size = length; + for (uint32_t i = 0; i < length; i++) { + answer->elements[i].bitmap = (roaring_bitmap_t *)arr[i]; + answer->elements[i].is_temporary = false; + answer->elements[i].size = + roaring_bitmap_portable_size_in_bytes(arr[i]); + } + for (int32_t i = (length >> 1); i >= 0; i--) { + percolate_down(answer, i); + } + return answer; +} + +static roaring_pq_element_t pq_poll(roaring_pq_t *pq) { + roaring_pq_element_t ans = *pq->elements; + if (pq->size > 1) { + pq->elements[0] = pq->elements[--pq->size]; + percolate_down(pq, 0); + } else + --pq->size; + // memmove(pq->elements,pq->elements+1,(pq->size-1)*sizeof(roaring_pq_element_t));--pq->size; + return ans; +} + +// this function consumes and frees the inputs +static roaring_bitmap_t *lazy_or_from_lazy_inputs(roaring_bitmap_t *x1, + roaring_bitmap_t *x2) { + uint8_t result_type = 0; + const int length1 = ra_get_size(&x1->high_low_container), + length2 = ra_get_size(&x2->high_low_container); + if (0 == length1) { + roaring_bitmap_free(x1); + return x2; + } + if (0 == length2) { + roaring_bitmap_free(x2); + return x1; + } + uint32_t neededcap = length1 > length2 ? length2 : length1; + roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(neededcap); + int pos1 = 0, pos2 = 0; + uint8_t type1, type2; + uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + while (true) { + if (s1 == s2) { + // todo: unsharing can be inefficient as it may create a clone where + // none + // is needed, but it has the benefit of being easy to reason about. + + ra_unshare_container_at_index(&x1->high_low_container, pos1); + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + assert(type1 != SHARED_CONTAINER_TYPE); + + ra_unshare_container_at_index(&x2->high_low_container, pos2); + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + assert(type2 != SHARED_CONTAINER_TYPE); + + container_t *c; + + if ((type2 == BITSET_CONTAINER_TYPE) && + (type1 != BITSET_CONTAINER_TYPE) + ){ + c = container_lazy_ior(c2, type2, c1, type1, &result_type); + container_free(c1, type1); + if (c != c2) { + container_free(c2, type2); + } + } else { + c = container_lazy_ior(c1, type1, c2, type2, &result_type); + container_free(c2, type2); + if (c != c1) { + container_free(c1, type1); + } + } + // since we assume that the initial containers are non-empty, the + // result here + // can only be non-empty + ra_append(&answer->high_low_container, s1, c, result_type); + ++pos1; + ++pos2; + if (pos1 == length1) break; + if (pos2 == length2) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + + } else if (s1 < s2) { // s1 < s2 + container_t *c1 = ra_get_container_at_index( + &x1->high_low_container, pos1, &type1); + ra_append(&answer->high_low_container, s1, c1, type1); + pos1++; + if (pos1 == length1) break; + s1 = ra_get_key_at_index(&x1->high_low_container, pos1); + + } else { // s1 > s2 + container_t *c2 = ra_get_container_at_index( + &x2->high_low_container, pos2, &type2); + ra_append(&answer->high_low_container, s2, c2, type2); + pos2++; + if (pos2 == length2) break; + s2 = ra_get_key_at_index(&x2->high_low_container, pos2); + } + } + if (pos1 == length1) { + ra_append_move_range(&answer->high_low_container, + &x2->high_low_container, pos2, length2); + } else if (pos2 == length2) { + ra_append_move_range(&answer->high_low_container, + &x1->high_low_container, pos1, length1); + } + ra_clear_without_containers(&x1->high_low_container); + ra_clear_without_containers(&x2->high_low_container); + roaring_free(x1); + roaring_free(x2); + return answer; +} + +/** + * Compute the union of 'number' bitmaps using a heap. This can + * sometimes be faster than roaring_bitmap_or_many which uses + * a naive algorithm. Caller is responsible for freeing the + * result. + */ +roaring_bitmap_t *roaring_bitmap_or_many_heap(uint32_t number, + const roaring_bitmap_t **x) { + if (number == 0) { + return roaring_bitmap_create(); + } + if (number == 1) { + return roaring_bitmap_copy(x[0]); + } + roaring_pq_t *pq = create_pq(x, number); + while (pq->size > 1) { + roaring_pq_element_t x1 = pq_poll(pq); + roaring_pq_element_t x2 = pq_poll(pq); + + if (x1.is_temporary && x2.is_temporary) { + roaring_bitmap_t *newb = + lazy_or_from_lazy_inputs(x1.bitmap, x2.bitmap); + // should normally return a fresh new bitmap *except* that + // it can return x1.bitmap or x2.bitmap in degenerate cases + bool temporary = !((newb == x1.bitmap) && (newb == x2.bitmap)); + uint64_t bsize = roaring_bitmap_portable_size_in_bytes(newb); + roaring_pq_element_t newelement = { + .size = bsize, .is_temporary = temporary, .bitmap = newb}; + pq_add(pq, &newelement); + } else if (x2.is_temporary) { + roaring_bitmap_lazy_or_inplace(x2.bitmap, x1.bitmap, false); + x2.size = roaring_bitmap_portable_size_in_bytes(x2.bitmap); + pq_add(pq, &x2); + } else if (x1.is_temporary) { + roaring_bitmap_lazy_or_inplace(x1.bitmap, x2.bitmap, false); + x1.size = roaring_bitmap_portable_size_in_bytes(x1.bitmap); + + pq_add(pq, &x1); + } else { + roaring_bitmap_t *newb = + roaring_bitmap_lazy_or(x1.bitmap, x2.bitmap, false); + uint64_t bsize = roaring_bitmap_portable_size_in_bytes(newb); + roaring_pq_element_t newelement = { + .size = bsize, .is_temporary = true, .bitmap = newb}; + + pq_add(pq, &newelement); + } + } + roaring_pq_element_t X = pq_poll(pq); + roaring_bitmap_t *answer = X.bitmap; + roaring_bitmap_repair_after_lazy(answer); + pq_free(pq); + return answer; +} + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace api { +#endif +/* end file src/roaring_priority_queue.c */ diff --git a/src/core/CLucene/util/croaring/roaring.h b/src/core/CLucene/util/croaring/roaring.h new file mode 100644 index 00000000000..955feb21770 --- /dev/null +++ b/src/core/CLucene/util/croaring/roaring.h @@ -0,0 +1,1031 @@ +// !!! DO NOT EDIT - THIS IS AN AUTO-GENERATED FILE !!! +// Created by amalgamation.sh on Wed 20 Jul 2022 16:25:25 EDT + +/* + * The CRoaring project is under a dual license (Apache/MIT). + * Users of the library may choose one or the other license. + */ +/* + * Copyright 2016-2022 The CRoaring authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * MIT License + * + * Copyright 2016-2022 The CRoaring authors + * + * Permission is hereby granted, free of charge, to any + * person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the + * Software without restriction, including without + * limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE + * + * SPDX-License-Identifier: MIT + */ + +/* begin file include/roaring/roaring_version.h */ +// /include/roaring/roaring_version.h automatically generated by release.py, do not change by hand +#ifndef ROARING_INCLUDE_ROARING_VERSION +#define ROARING_INCLUDE_ROARING_VERSION +#define ROARING_VERSION "0.6.0" +enum { + ROARING_VERSION_MAJOR = 0, + ROARING_VERSION_MINOR = 6, + ROARING_VERSION_REVISION = 0 +}; +#endif // ROARING_INCLUDE_ROARING_VERSION +/* end file include/roaring/roaring_version.h */ +/* begin file include/roaring/roaring_types.h */ +/* + Typedefs used by various components +*/ + +#ifndef ROARING_TYPES_H +#define ROARING_TYPES_H + +#include +#include + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace api { +#endif + + +/** + * When building .c files as C++, there's added compile-time checking if the + * container types are derived from a `container_t` base class. So long as + * such a base class is empty, the struct will behave compatibly with C structs + * despite the derivation. This is due to the Empty Base Class Optimization: + * + * https://en.cppreference.com/w/cpp/language/ebo + * + * But since C isn't namespaced, taking `container_t` globally might collide + * with other projects. So roaring.h uses ROARING_CONTAINER_T, while internal + * code #undefs that after declaring `typedef ROARING_CONTAINER_T container_t;` + */ +#if defined(__cplusplus) + extern "C++" { + struct container_s {}; + } + #define ROARING_CONTAINER_T ::roaring::api::container_s +#else + #define ROARING_CONTAINER_T void // no compile-time checking +#endif + +#define ROARING_FLAG_COW UINT8_C(0x1) +#define ROARING_FLAG_FROZEN UINT8_C(0x2) + +/** + * Roaring arrays are array-based key-value pairs having containers as values + * and 16-bit integer keys. A roaring bitmap might be implemented as such. + */ + +// parallel arrays. Element sizes quite different. +// Alternative is array +// of structs. Which would have better +// cache performance through binary searches? + +typedef struct roaring_array_s { + int32_t size; + int32_t allocation_size; + ROARING_CONTAINER_T **containers; // Use container_t in non-API files! + uint16_t *keys; + uint8_t *typecodes; + uint8_t flags; +} roaring_array_t; + + +typedef bool (*roaring_iterator)(uint32_t value, void *param); +typedef bool (*roaring_iterator64)(uint64_t value, void *param); + +/** +* (For advanced users.) +* The roaring_statistics_t can be used to collect detailed statistics about +* the composition of a roaring bitmap. +*/ +typedef struct roaring_statistics_s { + uint32_t n_containers; /* number of containers */ + + uint32_t n_array_containers; /* number of array containers */ + uint32_t n_run_containers; /* number of run containers */ + uint32_t n_bitset_containers; /* number of bitmap containers */ + + uint32_t + n_values_array_containers; /* number of values in array containers */ + uint32_t n_values_run_containers; /* number of values in run containers */ + uint32_t + n_values_bitset_containers; /* number of values in bitmap containers */ + + uint32_t n_bytes_array_containers; /* number of allocated bytes in array + containers */ + uint32_t n_bytes_run_containers; /* number of allocated bytes in run + containers */ + uint32_t n_bytes_bitset_containers; /* number of allocated bytes in bitmap + containers */ + + uint32_t + max_value; /* the maximal value, undefined if cardinality is zero */ + uint32_t + min_value; /* the minimal value, undefined if cardinality is zero */ + uint64_t sum_value; /* the sum of all values (could be used to compute + average) */ + + uint64_t cardinality; /* total number of values stored in the bitmap */ + + // and n_values_arrays, n_values_rle, n_values_bitmap +} roaring_statistics_t; + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace api { +#endif + +#endif /* ROARING_TYPES_H */ +/* end file include/roaring/roaring_types.h */ +/* begin file include/roaring/roaring.h */ +/* + * An implementation of Roaring Bitmaps in C. + */ + +#ifndef ROARING_H +#define ROARING_H + +#include +#include +#include // for `size_t` + + +#ifdef __cplusplus +extern "C" { namespace roaring { namespace api { +#endif + +typedef struct roaring_bitmap_s { + roaring_array_t high_low_container; +} roaring_bitmap_t; + +/** + * Dynamically allocates a new bitmap (initially empty). + * Returns NULL if the allocation fails. + * Capacity is a performance hint for how many "containers" the data will need. + * Client is responsible for calling `roaring_bitmap_free()`. + */ +roaring_bitmap_t *roaring_bitmap_create_with_capacity(uint32_t cap); + +/** + * Dynamically allocates a new bitmap (initially empty). + * Returns NULL if the allocation fails. + * Client is responsible for calling `roaring_bitmap_free()`. + */ +static inline roaring_bitmap_t *roaring_bitmap_create(void) + { return roaring_bitmap_create_with_capacity(0); } + +/** + * Initialize a roaring bitmap structure in memory controlled by client. + * Capacity is a performance hint for how many "containers" the data will need. + * Can return false if auxiliary allocations fail when capacity greater than 0. + */ +bool roaring_bitmap_init_with_capacity(roaring_bitmap_t *r, uint32_t cap); + +/** + * Initialize a roaring bitmap structure in memory controlled by client. + * The bitmap will be in a "clear" state, with no auxiliary allocations. + * Since this performs no allocations, the function will not fail. + */ +static inline void roaring_bitmap_init_cleared(roaring_bitmap_t *r) + { roaring_bitmap_init_with_capacity(r, 0); } + +/** + * Add all the values between min (included) and max (excluded) that are at a + * distance k*step from min. +*/ +roaring_bitmap_t *roaring_bitmap_from_range(uint64_t min, uint64_t max, + uint32_t step); + +/** + * Creates a new bitmap from a pointer of uint32_t integers + */ +roaring_bitmap_t *roaring_bitmap_of_ptr(size_t n_args, const uint32_t *vals); + +/* + * Whether you want to use copy-on-write. + * Saves memory and avoids copies, but needs more care in a threaded context. + * Most users should ignore this flag. + * + * Note: If you do turn this flag to 'true', enabling COW, then ensure that you + * do so for all of your bitmaps, since interactions between bitmaps with and + * without COW is unsafe. + */ +static inline bool roaring_bitmap_get_copy_on_write(const roaring_bitmap_t* r) { + return r->high_low_container.flags & ROARING_FLAG_COW; +} +static inline void roaring_bitmap_set_copy_on_write(roaring_bitmap_t* r, + bool cow) { + if (cow) { + r->high_low_container.flags |= ROARING_FLAG_COW; + } else { + r->high_low_container.flags &= ~ROARING_FLAG_COW; + } +} + +roaring_bitmap_t *roaring_bitmap_add_offset(const roaring_bitmap_t *bm, + int64_t offset); +/** + * Describe the inner structure of the bitmap. + */ +void roaring_bitmap_printf_describe(const roaring_bitmap_t *r); + +/** + * Creates a new bitmap from a list of uint32_t integers + */ +roaring_bitmap_t *roaring_bitmap_of(size_t n, ...); + +/** + * Copies a bitmap (this does memory allocation). + * The caller is responsible for memory management. + */ +roaring_bitmap_t *roaring_bitmap_copy(const roaring_bitmap_t *r); + +/** + * Copies a bitmap from src to dest. It is assumed that the pointer dest + * is to an already allocated bitmap. The content of the dest bitmap is + * freed/deleted. + * + * It might be preferable and simpler to call roaring_bitmap_copy except + * that roaring_bitmap_overwrite can save on memory allocations. + */ +bool roaring_bitmap_overwrite(roaring_bitmap_t *dest, + const roaring_bitmap_t *src); + +/** + * Print the content of the bitmap. + */ +void roaring_bitmap_printf(const roaring_bitmap_t *r); + +/** + * Computes the intersection between two bitmaps and returns new bitmap. The + * caller is responsible for memory management. + */ +roaring_bitmap_t *roaring_bitmap_and(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Computes the size of the intersection between two bitmaps. + */ +uint64_t roaring_bitmap_and_cardinality(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Check whether two bitmaps intersect. + */ +bool roaring_bitmap_intersect(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Check whether a bitmap and a closed range intersect. + */ +bool roaring_bitmap_intersect_with_range(const roaring_bitmap_t *bm, + uint64_t x, uint64_t y); + +/** + * Computes the Jaccard index between two bitmaps. (Also known as the Tanimoto + * distance, or the Jaccard similarity coefficient) + * + * The Jaccard index is undefined if both bitmaps are empty. + */ +double roaring_bitmap_jaccard_index(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Computes the size of the union between two bitmaps. + */ +uint64_t roaring_bitmap_or_cardinality(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Computes the size of the difference (andnot) between two bitmaps. + */ +uint64_t roaring_bitmap_andnot_cardinality(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Computes the size of the symmetric difference (xor) between two bitmaps. + */ +uint64_t roaring_bitmap_xor_cardinality(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Inplace version of `roaring_bitmap_and()`, modifies r1 + * r1 == r2 is allowed + */ +void roaring_bitmap_and_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Computes the union between two bitmaps and returns new bitmap. The caller is + * responsible for memory management. + */ +roaring_bitmap_t *roaring_bitmap_or(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Inplace version of `roaring_bitmap_or(), modifies r1. + * TODO: decide whether r1 == r2 ok + */ +void roaring_bitmap_or_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Compute the union of 'number' bitmaps. + * Caller is responsible for freeing the result. + * See also `roaring_bitmap_or_many_heap()` + */ +roaring_bitmap_t *roaring_bitmap_or_many(size_t number, + const roaring_bitmap_t **rs); + +/** + * Compute the union of 'number' bitmaps using a heap. This can sometimes be + * faster than `roaring_bitmap_or_many() which uses a naive algorithm. + * Caller is responsible for freeing the result. + */ +roaring_bitmap_t *roaring_bitmap_or_many_heap(uint32_t number, + const roaring_bitmap_t **rs); + +/** + * Computes the symmetric difference (xor) between two bitmaps + * and returns new bitmap. The caller is responsible for memory management. + */ +roaring_bitmap_t *roaring_bitmap_xor(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Inplace version of roaring_bitmap_xor, modifies r1, r1 != r2. + */ +void roaring_bitmap_xor_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Compute the xor of 'number' bitmaps. + * Caller is responsible for freeing the result. + */ +roaring_bitmap_t *roaring_bitmap_xor_many(size_t number, + const roaring_bitmap_t **rs); + +/** + * Computes the difference (andnot) between two bitmaps and returns new bitmap. + * Caller is responsible for freeing the result. + */ +roaring_bitmap_t *roaring_bitmap_andnot(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Inplace version of roaring_bitmap_andnot, modifies r1, r1 != r2. + */ +void roaring_bitmap_andnot_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * TODO: consider implementing: + * + * "Compute the xor of 'number' bitmaps using a heap. This can sometimes be + * faster than roaring_bitmap_xor_many which uses a naive algorithm. Caller is + * responsible for freeing the result."" + * + * roaring_bitmap_t *roaring_bitmap_xor_many_heap(uint32_t number, + * const roaring_bitmap_t **rs); + */ + +/** + * Frees the memory. + */ +void roaring_bitmap_free(const roaring_bitmap_t *r); + +/** + * Add value n_args from pointer vals, faster than repeatedly calling + * `roaring_bitmap_add()` + */ +void roaring_bitmap_add_many(roaring_bitmap_t *r, size_t n_args, + const uint32_t *vals); + +/** + * Add value x + */ +void roaring_bitmap_add(roaring_bitmap_t *r, uint32_t x); + +/** + * Add value x + * Returns true if a new value was added, false if the value already existed. + */ +bool roaring_bitmap_add_checked(roaring_bitmap_t *r, uint32_t x); + +/** + * Add all values in range [min, max] + */ +void roaring_bitmap_add_range_closed(roaring_bitmap_t *r, + uint32_t min, uint32_t max); + +/** + * Add all values in range [min, max) + */ +static inline void roaring_bitmap_add_range(roaring_bitmap_t *r, + uint64_t min, uint64_t max) { + if(max == min) return; + roaring_bitmap_add_range_closed(r, (uint32_t)min, (uint32_t)(max - 1)); +} + +/** + * Remove value x + */ +void roaring_bitmap_remove(roaring_bitmap_t *r, uint32_t x); + +/** + * Remove all values in range [min, max] + */ +void roaring_bitmap_remove_range_closed(roaring_bitmap_t *r, + uint32_t min, uint32_t max); + +/** + * Remove all values in range [min, max) + */ +static inline void roaring_bitmap_remove_range(roaring_bitmap_t *r, + uint64_t min, uint64_t max) { + if(max == min) return; + roaring_bitmap_remove_range_closed(r, (uint32_t)min, (uint32_t)(max - 1)); +} + +/** + * Remove multiple values + */ +void roaring_bitmap_remove_many(roaring_bitmap_t *r, size_t n_args, + const uint32_t *vals); + +/** + * Remove value x + * Returns true if a new value was removed, false if the value was not existing. + */ +bool roaring_bitmap_remove_checked(roaring_bitmap_t *r, uint32_t x); + +/** + * Check if value is present + */ +bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val); + +/** + * Check whether a range of values from range_start (included) + * to range_end (excluded) is present + */ +bool roaring_bitmap_contains_range(const roaring_bitmap_t *r, + uint64_t range_start, + uint64_t range_end); + +/** + * Get the cardinality of the bitmap (number of elements). + */ +uint64_t roaring_bitmap_get_cardinality(const roaring_bitmap_t *r); + +/** + * Returns the number of elements in the range [range_start, range_end). + */ +uint64_t roaring_bitmap_range_cardinality(const roaring_bitmap_t *r, + uint64_t range_start, + uint64_t range_end); + +/** +* Returns true if the bitmap is empty (cardinality is zero). +*/ +bool roaring_bitmap_is_empty(const roaring_bitmap_t *r); + + +/** + * Empties the bitmap. It will have no auxiliary allocations (so if the bitmap + * was initialized in client memory via roaring_bitmap_init(), then a call to + * roaring_bitmap_clear() would be enough to "free" it) + */ +void roaring_bitmap_clear(roaring_bitmap_t *r); + +/** + * Convert the bitmap to a sorted array, output in `ans`. + * + * Caller is responsible to ensure that there is enough memory allocated, e.g. + * + * ans = malloc(roaring_bitmap_get_cardinality(bitmap) * sizeof(uint32_t)); + */ +void roaring_bitmap_to_uint32_array(const roaring_bitmap_t *r, uint32_t *ans); + + +/** + * Convert the bitmap to a sorted array from `offset` by `limit`, output in `ans`. + * + * Caller is responsible to ensure that there is enough memory allocated, e.g. + * + * ans = malloc(roaring_bitmap_get_cardinality(limit) * sizeof(uint32_t)); + * + * Return false in case of failure (e.g., insufficient memory) + */ +bool roaring_bitmap_range_uint32_array(const roaring_bitmap_t *r, + size_t offset, size_t limit, + uint32_t *ans); + +/** + * Remove run-length encoding even when it is more space efficient. + * Return whether a change was applied. + */ +bool roaring_bitmap_remove_run_compression(roaring_bitmap_t *r); + +/** + * Convert array and bitmap containers to run containers when it is more + * efficient; also convert from run containers when more space efficient. + * + * Returns true if the result has at least one run container. + * Additional savings might be possible by calling `shrinkToFit()`. + */ +bool roaring_bitmap_run_optimize(roaring_bitmap_t *r); + +/** + * If needed, reallocate memory to shrink the memory usage. + * Returns the number of bytes saved. + */ +size_t roaring_bitmap_shrink_to_fit(roaring_bitmap_t *r); + +/** + * Write the bitmap to an output pointer, this output buffer should refer to + * at least `roaring_bitmap_size_in_bytes(r)` allocated bytes. + * + * See `roaring_bitmap_portable_serialize()` if you want a format that's + * compatible with Java and Go implementations. This format can sometimes be + * more space efficient than the portable form, e.g. when the data is sparse. + * + * Returns how many bytes written, should be `roaring_bitmap_size_in_bytes(r)`. + */ +size_t roaring_bitmap_serialize(const roaring_bitmap_t *r, char *buf); + +/** + * Use with `roaring_bitmap_serialize()`. + * + * (See `roaring_bitmap_portable_deserialize()` if you want a format that's + * compatible with Java and Go implementations) + */ +roaring_bitmap_t *roaring_bitmap_deserialize(const void *buf); + +/** + * How many bytes are required to serialize this bitmap (NOT compatible + * with Java and Go versions) + */ +size_t roaring_bitmap_size_in_bytes(const roaring_bitmap_t *r); + +/** + * Read bitmap from a serialized buffer. + * In case of failure, NULL is returned. + * + * This function is unsafe in the sense that if there is no valid serialized + * bitmap at the pointer, then many bytes could be read, possibly causing a + * buffer overflow. See also roaring_bitmap_portable_deserialize_safe(). + * + * This is meant to be compatible with the Java and Go versions: + * https://github.com/RoaringBitmap/RoaringFormatSpec + */ +roaring_bitmap_t *roaring_bitmap_portable_deserialize(const char *buf); + +/** + * Read bitmap from a serialized buffer safely (reading up to maxbytes). + * In case of failure, NULL is returned. + * + * This is meant to be compatible with the Java and Go versions: + * https://github.com/RoaringBitmap/RoaringFormatSpec + */ +roaring_bitmap_t *roaring_bitmap_portable_deserialize_safe(const char *buf, + size_t maxbytes); + +/** + * Check how many bytes would be read (up to maxbytes) at this pointer if there + * is a bitmap, returns zero if there is no valid bitmap. + * + * This is meant to be compatible with the Java and Go versions: + * https://github.com/RoaringBitmap/RoaringFormatSpec + */ +size_t roaring_bitmap_portable_deserialize_size(const char *buf, + size_t maxbytes); + +/** + * How many bytes are required to serialize this bitmap. + * + * This is meant to be compatible with the Java and Go versions: + * https://github.com/RoaringBitmap/RoaringFormatSpec + */ +size_t roaring_bitmap_portable_size_in_bytes(const roaring_bitmap_t *r); + +/** + * Write a bitmap to a char buffer. The output buffer should refer to at least + * `roaring_bitmap_portable_size_in_bytes(r)` bytes of allocated memory. + * + * Returns how many bytes were written which should match + * `roaring_bitmap_portable_size_in_bytes(r)`. + * + * This is meant to be compatible with the Java and Go versions: + * https://github.com/RoaringBitmap/RoaringFormatSpec + */ +size_t roaring_bitmap_portable_serialize(const roaring_bitmap_t *r, char *buf); + +/* + * "Frozen" serialization format imitates memory layout of roaring_bitmap_t. + * Deserialized bitmap is a constant view of the underlying buffer. + * This significantly reduces amount of allocations and copying required during + * deserialization. + * It can be used with memory mapped files. + * Example can be found in benchmarks/frozen_benchmark.c + * + * [#####] const roaring_bitmap_t * + * | | | + * +----+ | +-+ + * | | | + * [#####################################] underlying buffer + * + * Note that because frozen serialization format imitates C memory layout + * of roaring_bitmap_t, it is not fixed. It is different on big/little endian + * platforms and can be changed in future. + */ + +/** + * Returns number of bytes required to serialize bitmap using frozen format. + */ +size_t roaring_bitmap_frozen_size_in_bytes(const roaring_bitmap_t *r); + +/** + * Serializes bitmap using frozen format. + * Buffer size must be at least roaring_bitmap_frozen_size_in_bytes(). + */ +void roaring_bitmap_frozen_serialize(const roaring_bitmap_t *r, char *buf); + +/** + * Creates constant bitmap that is a view of a given buffer. + * Buffer data should have been written by `roaring_bitmap_frozen_serialize()` + * Its beginning must also be aligned by 32 bytes. + * Length must be equal exactly to `roaring_bitmap_frozen_size_in_bytes()`. + * In case of failure, NULL is returned. + * + * Bitmap returned by this function can be used in all readonly contexts. + * Bitmap must be freed as usual, by calling roaring_bitmap_free(). + * Underlying buffer must not be freed or modified while it backs any bitmaps. + */ +const roaring_bitmap_t *roaring_bitmap_frozen_view(const char *buf, + size_t length); + +/** + * Iterate over the bitmap elements. The function iterator is called once for + * all the values with ptr (can be NULL) as the second parameter of each call. + * + * `roaring_iterator` is simply a pointer to a function that returns bool + * (true means that the iteration should continue while false means that it + * should stop), and takes (uint32_t,void*) as inputs. + * + * Returns true if the roaring_iterator returned true throughout (so that all + * data points were necessarily visited). + * + * Iteration is ordered: from the smallest to the largest elements. + */ +bool roaring_iterate(const roaring_bitmap_t *r, roaring_iterator iterator, + void *ptr); + +bool roaring_iterate64(const roaring_bitmap_t *r, roaring_iterator64 iterator, + uint64_t high_bits, void *ptr); + +/** + * Return true if the two bitmaps contain the same elements. + */ +bool roaring_bitmap_equals(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Return true if all the elements of r1 are also in r2. + */ +bool roaring_bitmap_is_subset(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Return true if all the elements of r1 are also in r2, and r2 is strictly + * greater than r1. + */ +bool roaring_bitmap_is_strict_subset(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * (For expert users who seek high performance.) + * + * Computes the union between two bitmaps and returns new bitmap. The caller is + * responsible for memory management. + * + * The lazy version defers some computations such as the maintenance of the + * cardinality counts. Thus you must call `roaring_bitmap_repair_after_lazy()` + * after executing "lazy" computations. + * + * It is safe to repeatedly call roaring_bitmap_lazy_or_inplace on the result. + * + * `bitsetconversion` is a flag which determines whether container-container + * operations force a bitset conversion. + */ +roaring_bitmap_t *roaring_bitmap_lazy_or(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2, + const bool bitsetconversion); + +/** + * (For expert users who seek high performance.) + * + * Inplace version of roaring_bitmap_lazy_or, modifies r1. + * + * `bitsetconversion` is a flag which determines whether container-container + * operations force a bitset conversion. + */ +void roaring_bitmap_lazy_or_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2, + const bool bitsetconversion); + +/** + * (For expert users who seek high performance.) + * + * Execute maintenance on a bitmap created from `roaring_bitmap_lazy_or()` + * or modified with `roaring_bitmap_lazy_or_inplace()`. + */ +void roaring_bitmap_repair_after_lazy(roaring_bitmap_t *r1); + +/** + * Computes the symmetric difference between two bitmaps and returns new bitmap. + * The caller is responsible for memory management. + * + * The lazy version defers some computations such as the maintenance of the + * cardinality counts. Thus you must call `roaring_bitmap_repair_after_lazy()` + * after executing "lazy" computations. + * + * It is safe to repeatedly call `roaring_bitmap_lazy_xor_inplace()` on + * the result. + */ +roaring_bitmap_t *roaring_bitmap_lazy_xor(const roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * (For expert users who seek high performance.) + * + * Inplace version of roaring_bitmap_lazy_xor, modifies r1. r1 != r2 + */ +void roaring_bitmap_lazy_xor_inplace(roaring_bitmap_t *r1, + const roaring_bitmap_t *r2); + +/** + * Compute the negation of the bitmap in the interval [range_start, range_end). + * The number of negated values is range_end - range_start. + * Areas outside the range are passed through unchanged. + */ +roaring_bitmap_t *roaring_bitmap_flip(const roaring_bitmap_t *r1, + uint64_t range_start, uint64_t range_end); + +/** + * compute (in place) the negation of the roaring bitmap within a specified + * interval: [range_start, range_end). The number of negated values is + * range_end - range_start. + * Areas outside the range are passed through unchanged. + */ +void roaring_bitmap_flip_inplace(roaring_bitmap_t *r1, uint64_t range_start, + uint64_t range_end); + +/** + * Selects the element at index 'rank' where the smallest element is at index 0. + * If the size of the roaring bitmap is strictly greater than rank, then this + * function returns true and sets element to the element of given rank. + * Otherwise, it returns false. + */ +bool roaring_bitmap_select(const roaring_bitmap_t *r, uint32_t rank, + uint32_t *element); + +/** + * roaring_bitmap_rank returns the number of integers that are smaller or equal + * to x. Thus if x is the first element, this function will return 1. If + * x is smaller than the smallest element, this function will return 0. + * + * The indexing convention differs between roaring_bitmap_select and + * roaring_bitmap_rank: roaring_bitmap_select refers to the smallest value + * as having index 0, whereas roaring_bitmap_rank returns 1 when ranking + * the smallest value. + */ +uint64_t roaring_bitmap_rank(const roaring_bitmap_t *r, uint32_t x); + +/** + * Returns the smallest value in the set, or UINT32_MAX if the set is empty. + */ +uint32_t roaring_bitmap_minimum(const roaring_bitmap_t *r); + +/** + * Returns the greatest value in the set, or 0 if the set is empty. + */ +uint32_t roaring_bitmap_maximum(const roaring_bitmap_t *r); + +/** + * (For advanced users.) + * + * Collect statistics about the bitmap, see roaring_types.h for + * a description of roaring_statistics_t + */ +void roaring_bitmap_statistics(const roaring_bitmap_t *r, + roaring_statistics_t *stat); + +/********************* +* What follows is code use to iterate through values in a roaring bitmap + +roaring_bitmap_t *r =... +roaring_uint32_iterator_t i; +roaring_create_iterator(r, &i); +while(i.has_value) { + printf("value = %d\n", i.current_value); + roaring_advance_uint32_iterator(&i); +} + +Obviously, if you modify the underlying bitmap, the iterator +becomes invalid. So don't. +*/ + +typedef struct roaring_uint32_iterator_s { + const roaring_bitmap_t *parent; // owner + int32_t container_index; // point to the current container index + int32_t in_container_index; // for bitset and array container, this is out + // index + int32_t run_index; // for run container, this points at the run + + uint32_t current_value; + bool has_value; + + const ROARING_CONTAINER_T + *container; // should be: + // parent->high_low_container.containers[container_index]; + uint8_t typecode; // should be: + // parent->high_low_container.typecodes[container_index]; + uint32_t highbits; // should be: + // parent->high_low_container.keys[container_index]) << + // 16; + +} roaring_uint32_iterator_t; + +/** + * Initialize an iterator object that can be used to iterate through the + * values. If there is a value, then this iterator points to the first value + * and `it->has_value` is true. The value is in `it->current_value`. + */ +void roaring_init_iterator(const roaring_bitmap_t *r, + roaring_uint32_iterator_t *newit); + +/** + * Initialize an iterator object that can be used to iterate through the + * values. If there is a value, then this iterator points to the last value + * and `it->has_value` is true. The value is in `it->current_value`. + */ +void roaring_init_iterator_last(const roaring_bitmap_t *r, + roaring_uint32_iterator_t *newit); + +/** + * Create an iterator object that can be used to iterate through the values. + * Caller is responsible for calling `roaring_free_iterator()`. + * + * The iterator is initialized (this function calls `roaring_init_iterator()`) + * If there is a value, then this iterator points to the first value and + * `it->has_value` is true. The value is in `it->current_value`. + */ +roaring_uint32_iterator_t *roaring_create_iterator(const roaring_bitmap_t *r); + +/** +* Advance the iterator. If there is a new value, then `it->has_value` is true. +* The new value is in `it->current_value`. Values are traversed in increasing +* orders. For convenience, returns `it->has_value`. +*/ +bool roaring_advance_uint32_iterator(roaring_uint32_iterator_t *it); + +/** +* Decrement the iterator. If there's a new value, then `it->has_value` is true. +* The new value is in `it->current_value`. Values are traversed in decreasing +* order. For convenience, returns `it->has_value`. +*/ +bool roaring_previous_uint32_iterator(roaring_uint32_iterator_t *it); + +/** + * Move the iterator to the first value >= `val`. If there is a such a value, + * then `it->has_value` is true. The new value is in `it->current_value`. + * For convenience, returns `it->has_value`. + */ +bool roaring_move_uint32_iterator_equalorlarger(roaring_uint32_iterator_t *it, + uint32_t val); + +/** + * Creates a copy of an iterator. + * Caller must free it. + */ +roaring_uint32_iterator_t *roaring_copy_uint32_iterator( + const roaring_uint32_iterator_t *it); + +/** + * Free memory following `roaring_create_iterator()` + */ +void roaring_free_uint32_iterator(roaring_uint32_iterator_t *it); + +/* + * Reads next ${count} values from iterator into user-supplied ${buf}. + * Returns the number of read elements. + * This number can be smaller than ${count}, which means that iterator is drained. + * + * This function satisfies semantics of iteration and can be used together with + * other iterator functions. + * - first value is copied from ${it}->current_value + * - after function returns, iterator is positioned at the next element + */ +uint32_t roaring_read_uint32_iterator(roaring_uint32_iterator_t *it, + uint32_t* buf, uint32_t count); + +#ifdef __cplusplus +} } } // extern "C" { namespace roaring { namespace api { +#endif + +#endif /* ROARING_H */ + +#ifdef __cplusplus + /** + * Best practices for C++ headers is to avoid polluting global scope. + * But for C compatibility when just `roaring.h` is included building as + * C++, default to global access for the C public API. + * + * BUT when `roaring.hh` is included instead, it sets this flag. That way + * explicit namespacing must be used to get the C functions. + * + * This is outside the include guard so that if you include BOTH headers, + * the order won't matter; you still get the global definitions. + */ + #if !defined(ROARING_API_NOT_IN_GLOBAL_NAMESPACE) + using namespace ::roaring::api; + #endif +#endif + +/* end file include/roaring/roaring.h */ +/* begin file include/roaring/memory.h */ +#ifndef INCLUDE_ROARING_MEMORY_H_ +#define INCLUDE_ROARING_MEMORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include // for size_t + +typedef void* (*roaring_malloc_p)(size_t); +typedef void* (*roaring_realloc_p)(void*, size_t); +typedef void* (*roaring_calloc_p)(size_t, size_t); +typedef void (*roaring_free_p)(void*); +typedef void* (*roaring_aligned_malloc_p)(size_t, size_t); +typedef void (*roaring_aligned_free_p)(void*); + +typedef struct roaring_memory_s { + roaring_malloc_p malloc; + roaring_realloc_p realloc; + roaring_calloc_p calloc; + roaring_free_p free; + roaring_aligned_malloc_p aligned_malloc; + roaring_aligned_free_p aligned_free; +} roaring_memory_t; + +void roaring_init_memory_hook(roaring_memory_t memory_hook); + +void* roaring_malloc(size_t); +void* roaring_realloc(void*, size_t); +void* roaring_calloc(size_t, size_t); +void roaring_free(void*); +void* roaring_aligned_malloc(size_t, size_t); +void roaring_aligned_free(void*); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_ROARING_MEMORY_H_ +/* end file include/roaring/memory.h */ diff --git a/src/core/CLucene/util/croaring/roaring.hh b/src/core/CLucene/util/croaring/roaring.hh new file mode 100644 index 00000000000..eed5c75f2e3 --- /dev/null +++ b/src/core/CLucene/util/croaring/roaring.hh @@ -0,0 +1,2016 @@ +// !!! DO NOT EDIT - THIS IS AN AUTO-GENERATED FILE !!! +// Created by amalgamation.sh on Wed 20 Jul 2022 16:25:25 EDT + +/* + * The CRoaring project is under a dual license (Apache/MIT). + * Users of the library may choose one or the other license. + */ +/* + * Copyright 2016-2022 The CRoaring authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * MIT License + * + * Copyright 2016-2022 The CRoaring authors + * + * Permission is hereby granted, free of charge, to any + * person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the + * Software without restriction, including without + * limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software + * is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice + * shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF + * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED + * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE + * + * SPDX-License-Identifier: MIT + */ + +#define ROARING_API_NOT_IN_GLOBAL_NAMESPACE // see remarks in roaring.h +#include "roaring.h" +#undef ROARING_API_NOT_IN_GLOBAL_NAMESPACE +/* begin file cpp/roaring.hh */ +/* +A C++ header for Roaring Bitmaps. +*/ +#ifndef INCLUDE_ROARING_HH_ +#define INCLUDE_ROARING_HH_ + +#include + +#include +#include +#include +#include + +#if !defined(ROARING_EXCEPTIONS) +// __cpp_exceptions is required by C++98 and we require C++11 or better. +#ifndef __cpp_exceptions +#error "__cpp_exceptions should be defined" +#endif +# if __cpp_exceptions +# define ROARING_EXCEPTIONS 1 +# else +# define ROARING_EXCEPTIONS 0 +# endif +#endif + +#ifndef ROARING_TERMINATE +# if ROARING_EXCEPTIONS +# define ROARING_TERMINATE(_s) throw std::runtime_error(_s) +# else +# define ROARING_TERMINATE(_s) std::terminate() +# endif +#endif + +#define ROARING_API_NOT_IN_GLOBAL_NAMESPACE // see remarks in roaring.h +#undef ROARING_API_NOT_IN_GLOBAL_NAMESPACE + + +namespace roaring { + +class RoaringSetBitForwardIterator; + +class Roaring { + typedef api::roaring_bitmap_t roaring_bitmap_t; // class-local name alias + +public: + /** + * Create an empty bitmap in the existing memory for the class. + * The bitmap will be in the "clear" state with no auxiliary allocations. + */ + Roaring() : roaring{} { + // The empty constructor roaring{} silences warnings from pedantic static analyzers. + api::roaring_bitmap_init_cleared(&roaring); + } + + /** + * Construct a bitmap from a list of integer values. + */ + Roaring(size_t n, const uint32_t *data) : Roaring() { + api::roaring_bitmap_add_many(&roaring, n, data); + } + + /** + * Copy constructor + */ + Roaring(const Roaring &r) : Roaring() { + if (!api::roaring_bitmap_overwrite(&roaring, &r.roaring)) { + ROARING_TERMINATE("failed roaring_bitmap_overwrite in constructor"); + } + api::roaring_bitmap_set_copy_on_write( + &roaring, + api::roaring_bitmap_get_copy_on_write(&r.roaring)); + } + + /** + * Move constructor. The moved object remains valid, i.e. + * all methods can still be called on it. + */ + explicit Roaring(Roaring &&r) noexcept : roaring(r.roaring) { + // + // !!! This clones the bits of the roaring structure to a new location + // and then overwrites the old bits...assuming that this will still + // work. There are scenarios where this could break; e.g. if some of + // those bits were pointers into the structure memory itself. If such + // things were possible, a roaring_bitmap_move() API would be needed. + // + api::roaring_bitmap_init_cleared(&r.roaring); + } + + /** + * Construct a roaring object by taking control of a malloc()'d C struct. + * + * Passing a NULL pointer is unsafe. + * The pointer to the C struct will be invalid after the call. + */ + explicit Roaring(roaring_bitmap_t *s) noexcept : roaring (*s) { + roaring_free(s); // deallocate the passed-in pointer + } + + /** + * Construct a bitmap from a list of integer values. + */ + static Roaring bitmapOf(size_t n, ...) { + Roaring ans; + va_list vl; + va_start(vl, n); + for (size_t i = 0; i < n; i++) { + ans.add(va_arg(vl, uint32_t)); + } + va_end(vl); + return ans; + } + + /** + * Add value x + */ + void add(uint32_t x) { api::roaring_bitmap_add(&roaring, x); } + + /** + * Add value x + * Returns true if a new value was added, false if the value was already + * existing. + */ + bool addChecked(uint32_t x) { + return api::roaring_bitmap_add_checked(&roaring, x); + } + + /** + * Add all values from x (included) to y (excluded) + */ + void addRange(const uint64_t x, const uint64_t y) { + return api::roaring_bitmap_add_range(&roaring, x, y); + } + + /** + * Add value n_args from pointer vals + */ + void addMany(size_t n_args, const uint32_t *vals) { + api::roaring_bitmap_add_many(&roaring, n_args, vals); + } + + /** + * Remove value x + */ + void remove(uint32_t x) { api::roaring_bitmap_remove(&roaring, x); } + + /** + * Remove value x + * Returns true if a new value was removed, false if the value was not + * existing. + */ + bool removeChecked(uint32_t x) { + return api::roaring_bitmap_remove_checked(&roaring, x); + } + + /** + * Return the largest value (if not empty) + */ + uint32_t maximum() const { return api::roaring_bitmap_maximum(&roaring); } + + /** + * Return the smallest value (if not empty) + */ + uint32_t minimum() const { return api::roaring_bitmap_minimum(&roaring); } + + /** + * Check if value x is present + */ + bool contains(uint32_t x) const { + return api::roaring_bitmap_contains(&roaring, x); + } + + /** + * Check if all values from x (included) to y (excluded) are present + */ + bool containsRange(const uint64_t x, const uint64_t y) const { + return api::roaring_bitmap_contains_range(&roaring, x, y); + } + + /** + * Destructor. By contract, calling roaring_bitmap_clear() is enough to + * release all auxiliary memory used by the structure. + */ + ~Roaring() { + if (!(roaring.high_low_container.flags & ROARING_FLAG_FROZEN)) { + api::roaring_bitmap_clear(&roaring); + } else { + // The roaring member variable copies the `roaring_bitmap_t` and + // nested `roaring_array_t` structures by value and is freed in the + // constructor, however the underlying memory arena used for the + // container data is not freed with it. Here we derive the arena + // pointer from the second arena allocation in + // `roaring_bitmap_frozen_view` and free it as well. + roaring_bitmap_free( + (roaring_bitmap_t *)((char *) + roaring.high_low_container.containers - + sizeof(roaring_bitmap_t))); + } + } + + /** + * Copies the content of the provided bitmap, and + * discard the current content. + */ + Roaring &operator=(const Roaring &r) { + if (!api::roaring_bitmap_overwrite(&roaring, &r.roaring)) { + ROARING_TERMINATE("failed memory alloc in assignment"); + } + api::roaring_bitmap_set_copy_on_write( + &roaring, + api::roaring_bitmap_get_copy_on_write(&r.roaring)); + return *this; + } + + /** + * Moves the content of the provided bitmap, and + * discard the current content. + */ + Roaring &operator=(Roaring &&r) noexcept { + api::roaring_bitmap_clear(&roaring); // free this class's allocations + + // !!! See notes in the Move Constructor regarding roaring_bitmap_move() + // + roaring = r.roaring; + api::roaring_bitmap_init_cleared(&r.roaring); + + return *this; + } + + /** + * Compute the intersection between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring &operator&=(const Roaring &r) { + api::roaring_bitmap_and_inplace(&roaring, &r.roaring); + return *this; + } + + /** + * Compute the difference between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring &operator-=(const Roaring &r) { + api::roaring_bitmap_andnot_inplace(&roaring, &r.roaring); + return *this; + } + + /** + * Compute the union between the current bitmap and the provided bitmap, + * writing the result in the current bitmap. The provided bitmap is not + * modified. + * + * See also the fastunion function to aggregate many bitmaps more quickly. + */ + Roaring &operator|=(const Roaring &r) { + api::roaring_bitmap_or_inplace(&roaring, &r.roaring); + return *this; + } + + /** + * Compute the symmetric union between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring &operator^=(const Roaring &r) { + api::roaring_bitmap_xor_inplace(&roaring, &r.roaring); + return *this; + } + + /** + * Exchange the content of this bitmap with another. + */ + void swap(Roaring &r) { std::swap(r.roaring, roaring); } + + /** + * Get the cardinality of the bitmap (number of elements). + */ + uint64_t cardinality() const { + return api::roaring_bitmap_get_cardinality(&roaring); + } + + /** + * Returns true if the bitmap is empty (cardinality is zero). + */ + bool isEmpty() const { return api::roaring_bitmap_is_empty(&roaring); } + + /** + * Returns true if the bitmap is subset of the other. + */ + bool isSubset(const Roaring &r) const { + return api::roaring_bitmap_is_subset(&roaring, &r.roaring); + } + + /** + * Returns true if the bitmap is strict subset of the other. + */ + bool isStrictSubset(const Roaring &r) const { + return api::roaring_bitmap_is_strict_subset(&roaring, &r.roaring); + } + + /** + * Convert the bitmap to an array. Write the output to "ans", caller is + * responsible to ensure that there is enough memory allocated + * (e.g., ans = new uint32[mybitmap.cardinality()];) + */ + void toUint32Array(uint32_t *ans) const { + api::roaring_bitmap_to_uint32_array(&roaring, ans); + } + /** + * To int array with pagination + */ + void rangeUint32Array(uint32_t *ans, size_t offset, size_t limit) const { + api::roaring_bitmap_range_uint32_array(&roaring, offset, limit, ans); + } + + /** + * Return true if the two bitmaps contain the same elements. + */ + bool operator==(const Roaring &r) const { + return api::roaring_bitmap_equals(&roaring, &r.roaring); + } + + /** + * Compute the negation of the roaring bitmap within a specified interval. + * Areas outside the range are passed through unchanged. + */ + void flip(uint64_t range_start, uint64_t range_end) { + api::roaring_bitmap_flip_inplace(&roaring, range_start, range_end); + } + + /** + * Remove run-length encoding even when it is more space efficient. + * Return whether a change was applied. + */ + bool removeRunCompression() { + return api::roaring_bitmap_remove_run_compression(&roaring); + } + + /** + * Convert array and bitmap containers to run containers when it is more + * efficient; also convert from run containers when more space efficient. + * Returns true if the result has at least one run container. Additional + * savings might be possible by calling shrinkToFit(). + */ + bool runOptimize() { return api::roaring_bitmap_run_optimize(&roaring); } + + /** + * If needed, reallocate memory to shrink the memory usage. Returns + * the number of bytes saved. + */ + size_t shrinkToFit() { return api::roaring_bitmap_shrink_to_fit(&roaring); } + + /** + * Iterate over the bitmap elements. The function iterator is called once + * for all the values with ptr (can be NULL) as the second parameter of + * each call. + * + * roaring_iterator is simply a pointer to a function that returns bool + * (true means that the iteration should continue while false means that it + * should stop), and takes (uint32_t,void*) as inputs. + */ + void iterate(api::roaring_iterator iterator, void *ptr) const { + api::roaring_iterate(&roaring, iterator, ptr); + } + + /** + * Selects the value at index rnk in the bitmap, where the smallest value + * is at index 0. + * + * If the size of the roaring bitmap is strictly greater than rank, then + * this function returns true and sets element to the element of given rank. + * Otherwise, it returns false. + */ + bool select(uint32_t rnk, uint32_t *element) const { + return api::roaring_bitmap_select(&roaring, rnk, element); + } + + /** + * Computes the size of the intersection between two bitmaps. + */ + uint64_t and_cardinality(const Roaring &r) const { + return api::roaring_bitmap_and_cardinality(&roaring, &r.roaring); + } + + /** + * Check whether the two bitmaps intersect. + */ + bool intersect(const Roaring &r) const { + return api::roaring_bitmap_intersect(&roaring, &r.roaring); + } + + /** + * Computes the Jaccard index between two bitmaps. (Also known as the + * Tanimoto distance, + * or the Jaccard similarity coefficient) + * + * The Jaccard index is undefined if both bitmaps are empty. + */ + double jaccard_index(const Roaring &r) const { + return api::roaring_bitmap_jaccard_index(&roaring, &r.roaring); + } + + /** + * Computes the size of the union between two bitmaps. + */ + uint64_t or_cardinality(const Roaring &r) const { + return api::roaring_bitmap_or_cardinality(&roaring, &r.roaring); + } + + /** + * Computes the size of the difference (andnot) between two bitmaps. + */ + uint64_t andnot_cardinality(const Roaring &r) const { + return api::roaring_bitmap_andnot_cardinality(&roaring, &r.roaring); + } + + /** + * Computes the size of the symmetric difference (andnot) between two + * bitmaps. + */ + uint64_t xor_cardinality(const Roaring &r) const { + return api::roaring_bitmap_xor_cardinality(&roaring, &r.roaring); + } + + /** + * Returns the number of integers that are smaller or equal to x. + * Thus the rank of the smallest element is one. If + * x is smaller than the smallest element, this function will return 0. + * The rank and select functions differ in convention: this function returns + * 1 when ranking the smallest value, but the select function returns the + * smallest value when using index 0. + */ + uint64_t rank(uint32_t x) const { + return api::roaring_bitmap_rank(&roaring, x); + } + + /** + * Write a bitmap to a char buffer. This is meant to be compatible with + * the Java and Go versions. Returns how many bytes were written which + * should be getSizeInBytes(). + * + * Setting the portable flag to false enable a custom format that + * can save space compared to the portable format (e.g., for very + * sparse bitmaps). + * + * Boost users can serialize bitmaps in this manner: + * + * BOOST_SERIALIZATION_SPLIT_FREE(Roaring) + * namespace boost { + * namespace serialization { + * + * template + * void save(Archive& ar, const Roaring& bitmask, + * const unsigned int version) { + * std::size_t expected_size_in_bytes = bitmask.getSizeInBytes(); + * std::vector buffer(expected_size_in_bytes); + * std::size_t size_in_bytes = bitmask.write(buffer.data()); + * + * ar& size_in_bytes; + * ar& boost::serialization::make_binary_object(buffer.data(), + * size_in_bytes); + * } + * template + * void load(Archive& ar, Roaring& bitmask, + * const unsigned int version) { + * std::size_t size_in_bytes = 0; + * ar& size_in_bytes; + * std::vector buffer(size_in_bytes); + * ar& boost::serialization::make_binary_object(buffer.data(), + * size_in_bytes); + * bitmask = Roaring::readSafe(buffer.data(), size_in_bytes); + * } + * } // namespace serialization + * } // namespace boost + */ + size_t write(char *buf, bool portable = true) const { + if (portable) + return api::roaring_bitmap_portable_serialize(&roaring, buf); + else + return api::roaring_bitmap_serialize(&roaring, buf); + } + + /** + * Read a bitmap from a serialized version. This is meant to be compatible + * with the Java and Go versions. + * + * Setting the portable flag to false enable a custom format that + * can save space compared to the portable format (e.g., for very + * sparse bitmaps). + * + * This function is unsafe in the sense that if you provide bad data, + * many, many bytes could be read. See also readSafe. + */ + static Roaring read(const char *buf, bool portable = true) { + roaring_bitmap_t * r = portable + ? api::roaring_bitmap_portable_deserialize(buf) + : api::roaring_bitmap_deserialize(buf); + if (r == NULL) { + ROARING_TERMINATE("failed alloc while reading"); + } + return Roaring(r); + } + + /** + * Read a bitmap from a serialized version, reading no more than maxbytes + * bytes. This is meant to be compatible with the Java and Go versions. + * + */ + static Roaring readSafe(const char *buf, size_t maxbytes) { + roaring_bitmap_t * r = + api::roaring_bitmap_portable_deserialize_safe(buf,maxbytes); + if (r == NULL) { + ROARING_TERMINATE("failed alloc while reading"); + } + return Roaring(r); + } + + /** + * How many bytes are required to serialize this bitmap (meant to be + * compatible with Java and Go versions) + * + * Setting the portable flag to false enable a custom format that + * can save space compared to the portable format (e.g., for very + * sparse bitmaps). + */ + size_t getSizeInBytes(bool portable = true) const { + if (portable) + return api::roaring_bitmap_portable_size_in_bytes(&roaring); + else + return api::roaring_bitmap_size_in_bytes(&roaring); + } + + static const Roaring frozenView(const char *buf, size_t length) { + const roaring_bitmap_t *s = + api::roaring_bitmap_frozen_view(buf, length); + if (s == NULL) { + ROARING_TERMINATE("failed to read frozen bitmap"); + } + Roaring r; + r.roaring = *s; + return r; + } + + void writeFrozen(char *buf) const { + roaring_bitmap_frozen_serialize(&roaring, buf); + } + + size_t getFrozenSizeInBytes() const { + return roaring_bitmap_frozen_size_in_bytes(&roaring); + } + + /** + * Computes the intersection between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring operator&(const Roaring &o) const { + roaring_bitmap_t *r = api::roaring_bitmap_and(&roaring, &o.roaring); + if (r == NULL) { + ROARING_TERMINATE("failed materalization in and"); + } + return Roaring(r); + } + + /** + * Computes the difference between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring operator-(const Roaring &o) const { + roaring_bitmap_t *r = api::roaring_bitmap_andnot(&roaring, &o.roaring); + if (r == NULL) { + ROARING_TERMINATE("failed materalization in andnot"); + } + return Roaring(r); + } + + /** + * Computes the union between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring operator|(const Roaring &o) const { + roaring_bitmap_t *r = api::roaring_bitmap_or(&roaring, &o.roaring); + if (r == NULL) { + ROARING_TERMINATE("failed materalization in or"); + } + return Roaring(r); + } + + /** + * Computes the symmetric union between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring operator^(const Roaring &o) const { + roaring_bitmap_t *r = api::roaring_bitmap_xor(&roaring, &o.roaring); + if (r == NULL) { + ROARING_TERMINATE("failed materalization in xor"); + } + return Roaring(r); + } + + /** + * Whether or not we apply copy and write. + */ + void setCopyOnWrite(bool val) { + api::roaring_bitmap_set_copy_on_write(&roaring, val); + } + + /** + * Print the content of the bitmap + */ + void printf() const { api::roaring_bitmap_printf(&roaring); } + + /** + * Print the content of the bitmap into a string + */ + std::string toString() const { + struct iter_data { + std::string str{}; // The empty constructor silences warnings from pedantic static analyzers. + char first_char = '{'; + } outer_iter_data; + if (!isEmpty()) { + iterate( + [](uint32_t value, void *inner_iter_data) -> bool { + ((iter_data *)inner_iter_data)->str += + ((iter_data *)inner_iter_data)->first_char; + ((iter_data *)inner_iter_data)->str += + std::to_string(value); + ((iter_data *)inner_iter_data)->first_char = ','; + return true; + }, + (void *)&outer_iter_data); + } else + outer_iter_data.str = '{'; + outer_iter_data.str += '}'; + return outer_iter_data.str; + } + + /** + * Whether or not copy and write is active. + */ + bool getCopyOnWrite() const { + return api::roaring_bitmap_get_copy_on_write(&roaring); + } + + /** + * Computes the logical or (union) between "n" bitmaps (referenced by a + * pointer). + */ + static Roaring fastunion(size_t n, const Roaring **inputs) { + const roaring_bitmap_t **x = + (const roaring_bitmap_t **)roaring_malloc(n * sizeof(roaring_bitmap_t *)); + if (x == NULL) { + ROARING_TERMINATE("failed memory alloc in fastunion"); + } + for (size_t k = 0; k < n; ++k) x[k] = &inputs[k]->roaring; + + roaring_bitmap_t *c_ans = api::roaring_bitmap_or_many(n, x); + if (c_ans == NULL) { + roaring_free(x); + ROARING_TERMINATE("failed memory alloc in fastunion"); + } + Roaring ans(c_ans); + roaring_free(x); + return ans; + } + + typedef RoaringSetBitForwardIterator const_iterator; + + /** + * Returns an iterator that can be used to access the position of the set + * bits. The running time complexity of a full scan is proportional to the + * number of set bits: be aware that if you have long strings of 1s, this + * can be very inefficient. + * + * It can be much faster to use the toArray method if you want to retrieve + * the set bits. + */ + const_iterator begin() const; + + /** + * A bogus iterator that can be used together with begin() + * for constructions such as for (auto i = b.begin(); * i!=b.end(); ++i) {} + */ + const_iterator &end() const; + + roaring_bitmap_t roaring; +}; + +/** + * Used to go through the set bits. Not optimally fast, but convenient. + */ +class RoaringSetBitForwardIterator final { +public: + typedef std::forward_iterator_tag iterator_category; + typedef uint32_t *pointer; + typedef uint32_t &reference_type; + typedef uint32_t value_type; + typedef int32_t difference_type; + typedef RoaringSetBitForwardIterator type_of_iterator; + + /** + * Provides the location of the set bit. + */ + value_type operator*() const { return i.current_value; } + + bool operator<(const type_of_iterator &o) const { + if (!i.has_value) return false; + if (!o.i.has_value) return true; + return i.current_value < *o; + } + + bool operator<=(const type_of_iterator &o) const { + if (!o.i.has_value) return true; + if (!i.has_value) return false; + return i.current_value <= *o; + } + + bool operator>(const type_of_iterator &o) const { + if (!o.i.has_value) return false; + if (!i.has_value) return true; + return i.current_value > *o; + } + + bool operator>=(const type_of_iterator &o) const { + if (!i.has_value) return true; + if (!o.i.has_value) return false; + return i.current_value >= *o; + } + + /** + * Move the iterator to the first value >= val. + */ + void equalorlarger(uint32_t val) { + api::roaring_move_uint32_iterator_equalorlarger(&i,val); + } + + type_of_iterator &operator++() { // ++i, must returned inc. value + api::roaring_advance_uint32_iterator(&i); + return *this; + } + + type_of_iterator operator++(int) { // i++, must return orig. value + RoaringSetBitForwardIterator orig(*this); + api::roaring_advance_uint32_iterator(&i); + return orig; + } + + type_of_iterator& operator--() { // prefix -- + api::roaring_previous_uint32_iterator(&i); + return *this; + } + + type_of_iterator operator--(int) { // postfix -- + RoaringSetBitForwardIterator orig(*this); + api::roaring_previous_uint32_iterator(&i); + return orig; + } + + bool operator==(const RoaringSetBitForwardIterator &o) const { + return i.current_value == *o && i.has_value == o.i.has_value; + } + + bool operator!=(const RoaringSetBitForwardIterator &o) const { + return i.current_value != *o || i.has_value != o.i.has_value; + } + + RoaringSetBitForwardIterator(const Roaring &parent, + bool exhausted = false) { + if (exhausted) { + i.parent = &parent.roaring; + i.container_index = INT32_MAX; + i.has_value = false; + i.current_value = UINT32_MAX; + } else { + api::roaring_init_iterator(&parent.roaring, &i); + } + } + + api::roaring_uint32_iterator_t i{}; // The empty constructor silences warnings from pedantic static analyzers. +}; + +inline RoaringSetBitForwardIterator Roaring::begin() const { + return RoaringSetBitForwardIterator(*this); +} + +inline RoaringSetBitForwardIterator &Roaring::end() const { + static RoaringSetBitForwardIterator e(*this, true); + return e; +} + +} // namespace roaring + +#endif /* INCLUDE_ROARING_HH_ */ +/* end file cpp/roaring.hh */ +/* begin file cpp/roaring64map.hh */ +/* +A C++ header for 64-bit Roaring Bitmaps, implemented by way of a map of many +32-bit Roaring Bitmaps. +*/ +#ifndef INCLUDE_ROARING_64_MAP_HH_ +#define INCLUDE_ROARING_64_MAP_HH_ + +#include +#include // for va_list handling in bitmapOf() +#include // for std::printf() in the printf() method +#include // for std::memcpy() +#include +#include +#include +#include +#include +#include +#include + +using roaring::Roaring; + +namespace roaring { + +class Roaring64MapSetBitForwardIterator; +class Roaring64MapSetBitBiDirectionalIterator; + +class Roaring64Map { + typedef api::roaring_bitmap_t roaring_bitmap_t; + +public: + /** + * Create an empty bitmap + */ + Roaring64Map() = default; + + /** + * Construct a bitmap from a list of 32-bit integer values. + */ + Roaring64Map(size_t n, const uint32_t *data) { addMany(n, data); } + + /** + * Construct a bitmap from a list of 64-bit integer values. + */ + Roaring64Map(size_t n, const uint64_t *data) { addMany(n, data); } + + /** + * Construct a 64-bit map from a 32-bit one + */ + explicit Roaring64Map(const Roaring &r) { emplaceOrInsert(0, r); } + + /** + * Construct a roaring object from the C struct. + * + * Passing a NULL point is unsafe. + */ + explicit Roaring64Map(roaring_bitmap_t *s) { + Roaring r(s); + emplaceOrInsert(0, r); + } + + Roaring64Map(const Roaring64Map& r) + : roarings(r.roarings), + copyOnWrite(r.copyOnWrite) { } + + Roaring64Map(Roaring64Map&& r) + : roarings(r.roarings), + copyOnWrite(r.copyOnWrite) { } + + /** + * Assignment operator. + */ + Roaring64Map &operator=(const Roaring64Map &r) { + roarings = r.roarings; + return *this; + } + + /** + * Construct a bitmap from a list of integer values. + */ + static Roaring64Map bitmapOf(size_t n...) { + Roaring64Map ans; + va_list vl; + va_start(vl, n); + for (size_t i = 0; i < n; i++) { + ans.add(va_arg(vl, uint64_t)); + } + va_end(vl); + return ans; + } + + /** + * Add value x + */ + void add(uint32_t x) { + roarings[0].add(x); + roarings[0].setCopyOnWrite(copyOnWrite); + } + void add(uint64_t x) { + roarings[highBytes(x)].add(lowBytes(x)); + roarings[highBytes(x)].setCopyOnWrite(copyOnWrite); + } + + /** + * Add value x + * Returns true if a new value was added, false if the value was already existing. + */ + bool addChecked(uint32_t x) { + bool result = roarings[0].addChecked(x); + roarings[0].setCopyOnWrite(copyOnWrite); + return result; + } + bool addChecked(uint64_t x) { + bool result = roarings[highBytes(x)].addChecked(lowBytes(x)); + roarings[highBytes(x)].setCopyOnWrite(copyOnWrite); + return result; + } + + /** + * Add value n_args from pointer vals + */ + void addMany(size_t n_args, const uint32_t *vals) { + for (size_t lcv = 0; lcv < n_args; lcv++) { + roarings[0].add(vals[lcv]); + roarings[0].setCopyOnWrite(copyOnWrite); + } + } + void addMany(size_t n_args, const uint64_t *vals) { + for (size_t lcv = 0; lcv < n_args; lcv++) { + roarings[highBytes(vals[lcv])].add(lowBytes(vals[lcv])); + roarings[highBytes(vals[lcv])].setCopyOnWrite(copyOnWrite); + } + } + + /** + * Remove value x + */ + void remove(uint32_t x) { roarings[0].remove(x); } + void remove(uint64_t x) { + auto roaring_iter = roarings.find(highBytes(x)); + if (roaring_iter != roarings.cend()) + roaring_iter->second.remove(lowBytes(x)); + } + + /** + * Remove value x + * Returns true if a new value was removed, false if the value was not existing. + */ + bool removeChecked(uint32_t x) { + return roarings[0].removeChecked(x); + } + bool removeChecked(uint64_t x) { + auto roaring_iter = roarings.find(highBytes(x)); + if (roaring_iter != roarings.cend()) + return roaring_iter->second.removeChecked(lowBytes(x)); + return false; + } + + /** + * Clear the bitmap + */ + void clear() { + roarings.clear(); + } + + /** + * Return the largest value (if not empty) + */ + uint64_t maximum() const { + for (auto roaring_iter = roarings.crbegin(); + roaring_iter != roarings.crend(); ++roaring_iter) { + if (!roaring_iter->second.isEmpty()) { + return uniteBytes(roaring_iter->first, + roaring_iter->second.maximum()); + } + } + // we put std::numeric_limits<>::max/min in parenthesis + // to avoid a clash with the Windows.h header under Windows + return (std::numeric_limits::min)(); + } + + /** + * Return the smallest value (if not empty) + */ + uint64_t minimum() const { + for (auto roaring_iter = roarings.cbegin(); + roaring_iter != roarings.cend(); ++roaring_iter) { + if (!roaring_iter->second.isEmpty()) { + return uniteBytes(roaring_iter->first, + roaring_iter->second.minimum()); + } + } + // we put std::numeric_limits<>::max/min in parenthesis + // to avoid a clash with the Windows.h header under Windows + return (std::numeric_limits::max)(); + } + + /** + * Check if value x is present + */ + bool contains(uint32_t x) const { + return roarings.count(0) == 0 ? false : roarings.at(0).contains(x); + } + bool contains(uint64_t x) const { + return roarings.count(highBytes(x)) == 0 + ? false + : roarings.at(highBytes(x)).contains(lowBytes(x)); + } + + /** + * Compute the intersection between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring64Map &operator&=(const Roaring64Map &r) { + for (auto &map_entry : roarings) { + if (r.roarings.count(map_entry.first) == 1) + map_entry.second &= r.roarings.at(map_entry.first); + else + map_entry.second = Roaring(); + } + return *this; + } + + /** + * Compute the difference between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring64Map &operator-=(const Roaring64Map &r) { + for (auto &map_entry : roarings) { + if (r.roarings.count(map_entry.first) == 1) + map_entry.second -= r.roarings.at(map_entry.first); + } + return *this; + } + + /** + * Compute the union between the current bitmap and the provided bitmap, + * writing the result in the current bitmap. The provided bitmap is not + * modified. + * + * See also the fastunion function to aggregate many bitmaps more quickly. + */ + Roaring64Map &operator|=(const Roaring64Map &r) { + for (const auto &map_entry : r.roarings) { + if (roarings.count(map_entry.first) == 0) { + roarings[map_entry.first] = map_entry.second; + roarings[map_entry.first].setCopyOnWrite(copyOnWrite); + } else + roarings[map_entry.first] |= map_entry.second; + } + return *this; + } + + /** + * Compute the symmetric union between the current bitmap and the provided + * bitmap, writing the result in the current bitmap. The provided bitmap + * is not modified. + */ + Roaring64Map &operator^=(const Roaring64Map &r) { + for (const auto &map_entry : r.roarings) { + if (roarings.count(map_entry.first) == 0) { + roarings[map_entry.first] = map_entry.second; + roarings[map_entry.first].setCopyOnWrite(copyOnWrite); + } else + roarings[map_entry.first] ^= map_entry.second; + } + return *this; + } + + /** + * Exchange the content of this bitmap with another. + */ + void swap(Roaring64Map &r) { roarings.swap(r.roarings); } + + /** + * Get the cardinality of the bitmap (number of elements). + * Throws std::length_error in the special case where the bitmap is full + * (cardinality() == 2^64). Check isFull() before calling to avoid + * exception. + */ + uint64_t cardinality() const { + if (isFull()) { +#if ROARING_EXCEPTIONS + throw std::length_error("bitmap is full, cardinality is 2^64, " + "unable to represent in a 64-bit integer"); +#else + ROARING_TERMINATE("bitmap is full, cardinality is 2^64, " + "unable to represent in a 64-bit integer"); +#endif + } + return std::accumulate( + roarings.cbegin(), roarings.cend(), (uint64_t)0, + [](uint64_t previous, + const std::pair &map_entry) { + return previous + map_entry.second.cardinality(); + }); + } + + /** + * Returns true if the bitmap is empty (cardinality is zero). + */ + bool isEmpty() const { + return std::all_of(roarings.cbegin(), roarings.cend(), + [](const std::pair &map_entry) { + return map_entry.second.isEmpty(); + }); + } + + /** + * Returns true if the bitmap is full (cardinality is max uint64_t + 1). + */ + bool isFull() const { + // only bother to check if map is fully saturated + // + // we put std::numeric_limits<>::max/min in parenthesis + // to avoid a clash with the Windows.h header under Windows + return roarings.size() == + ((uint64_t)(std::numeric_limits::max)()) + 1 + ? std::all_of( + roarings.cbegin(), roarings.cend(), + [](const std::pair &roaring_map_entry) { + // roarings within map are saturated if cardinality + // is uint32_t max + 1 + return roaring_map_entry.second.cardinality() == + ((uint64_t) + (std::numeric_limits::max)()) + + 1; + }) + : false; + } + + /** + * Returns true if the bitmap is subset of the other. + */ + bool isSubset(const Roaring64Map &r) const { + for (const auto &map_entry : roarings) { + auto roaring_iter = r.roarings.find(map_entry.first); + if (roaring_iter == r.roarings.cend()) + return false; + else if (!map_entry.second.isSubset(roaring_iter->second)) + return false; + } + return true; + } + + /** + * Returns true if the bitmap is strict subset of the other. + * Throws std::length_error in the special case where the bitmap is full + * (cardinality() == 2^64). Check isFull() before calling to avoid exception. + */ + bool isStrictSubset(const Roaring64Map &r) const { + return isSubset(r) && cardinality() != r.cardinality(); + } + + /** + * Convert the bitmap to an array. Write the output to "ans", + * caller is responsible to ensure that there is enough memory + * allocated + * (e.g., ans = new uint32[mybitmap.cardinality()];) + */ + void toUint64Array(uint64_t *ans) const { + // Annoyingly, VS 2017 marks std::accumulate() as [[nodiscard]] + (void)std::accumulate(roarings.cbegin(), roarings.cend(), ans, + [](uint64_t *previous, + const std::pair &map_entry) { + for (uint32_t low_bits : map_entry.second) + *previous++ = + uniteBytes(map_entry.first, low_bits); + return previous; + }); + } + + /** + * Return true if the two bitmaps contain the same elements. + */ + bool operator==(const Roaring64Map &r) const { + // we cannot use operator == on the map because either side may contain + // empty Roaring Bitmaps + auto lhs_iter = roarings.cbegin(); + auto lhs_cend = roarings.cend(); + auto rhs_iter = r.roarings.cbegin(); + auto rhs_cend = r.roarings.cend(); + while (lhs_iter != lhs_cend && rhs_iter != rhs_cend) { + auto lhs_key = lhs_iter->first, rhs_key = rhs_iter->first; + const auto &lhs_map = lhs_iter->second, &rhs_map = rhs_iter->second; + if (lhs_map.isEmpty()) { + ++lhs_iter; + continue; + } + if (rhs_map.isEmpty()) { + ++rhs_iter; + continue; + } + if (!(lhs_key == rhs_key)) { + return false; + } + if (!(lhs_map == rhs_map)) { + return false; + } + ++lhs_iter; + ++rhs_iter; + } + while (lhs_iter != lhs_cend) { + if (!lhs_iter->second.isEmpty()) { + return false; + } + ++lhs_iter; + } + while (rhs_iter != rhs_cend) { + if (!rhs_iter->second.isEmpty()) { + return false; + } + ++rhs_iter; + } + return true; + } + + /** + * Compute the negation of the roaring bitmap within a specified interval. + * areas outside the range are passed through unchanged. + */ + void flip(uint64_t range_start, uint64_t range_end) { + uint32_t start_high = highBytes(range_start); + uint32_t start_low = lowBytes(range_start); + uint32_t end_high = highBytes(range_end); + uint32_t end_low = lowBytes(range_end); + + if (start_high == end_high) { + roarings[start_high].flip(start_low, end_low); + return; + } + // we put std::numeric_limits<>::max/min in parenthesis + // to avoid a clash with the Windows.h header under Windows + roarings[start_high].flip(start_low, + (std::numeric_limits::max)()); + roarings[start_high++].setCopyOnWrite(copyOnWrite); + + for (; start_high <= highBytes(range_end) - 1; ++start_high) { + roarings[start_high].flip((std::numeric_limits::min)(), + (std::numeric_limits::max)()); + roarings[start_high].setCopyOnWrite(copyOnWrite); + } + + roarings[start_high].flip((std::numeric_limits::min)(), + end_low); + roarings[start_high].setCopyOnWrite(copyOnWrite); + } + + /** + * Remove run-length encoding even when it is more space efficient + * return whether a change was applied + */ + bool removeRunCompression() { + return std::accumulate( + roarings.begin(), roarings.end(), true, + [](bool previous, std::pair &map_entry) { + return map_entry.second.removeRunCompression() && previous; + }); + } + + /** + * Convert array and bitmap containers to run containers when it is more + * efficient; also convert from run containers when more space efficient. + * Returns true if the result has at least one run container. + * Additional savings might be possible by calling shrinkToFit(). + */ + bool runOptimize() { + return std::accumulate( + roarings.begin(), roarings.end(), true, + [](bool previous, std::pair &map_entry) { + return map_entry.second.runOptimize() && previous; + }); + } + + /** + * If needed, reallocate memory to shrink the memory usage. + * Returns the number of bytes saved. + */ + size_t shrinkToFit() { + size_t savedBytes = 0; + auto iter = roarings.begin(); + while (iter != roarings.cend()) { + if (iter->second.isEmpty()) { + // empty Roarings are 84 bytes + savedBytes += 88; + roarings.erase(iter++); + } else { + savedBytes += iter->second.shrinkToFit(); + iter++; + } + } + return savedBytes; + } + + /** + * Iterate over the bitmap elements in order(start from the smallest one) + * and call iterator once for every element until the iterator function + * returns false. To iterate over all values, the iterator function should + * always return true. + * + * The roaring_iterator64 parameter is a pointer to a function that + * returns bool (true means that the iteration should continue while false + * means that it should stop), and takes (uint64_t element, void* ptr) as + * inputs. + */ + void iterate(api::roaring_iterator64 iterator, void *ptr) const { + for (const auto &map_entry : roarings) { + bool should_continue = + roaring_iterate64(&map_entry.second.roaring, iterator, + uint64_t(map_entry.first) << 32, ptr); + if (!should_continue) { + break; + } + } + } + + /** + * If the size of the roaring bitmap is strictly greater than rank, then + * this function returns true and set element to the element of given + * rank. Otherwise, it returns false. + */ + bool select(uint64_t rnk, uint64_t *element) const { + for (const auto &map_entry : roarings) { + uint64_t sub_cardinality = (uint64_t)map_entry.second.cardinality(); + if (rnk < sub_cardinality) { + *element = ((uint64_t)map_entry.first) << 32; + // assuming little endian + return map_entry.second.select((uint32_t)rnk, + ((uint32_t *)element)); + } + rnk -= sub_cardinality; + } + return false; + } + + /** + * Returns the number of integers that are smaller or equal to x. + */ + uint64_t rank(uint64_t x) const { + uint64_t result = 0; + auto roaring_destination = roarings.find(highBytes(x)); + if (roaring_destination != roarings.cend()) { + for (auto roaring_iter = roarings.cbegin(); + roaring_iter != roaring_destination; ++roaring_iter) { + result += roaring_iter->second.cardinality(); + } + result += roaring_destination->second.rank(lowBytes(x)); + return result; + } + roaring_destination = roarings.lower_bound(highBytes(x)); + for (auto roaring_iter = roarings.cbegin(); + roaring_iter != roaring_destination; ++roaring_iter) { + result += roaring_iter->second.cardinality(); + } + return result; + } + + /** + * Write a bitmap to a char buffer. This is meant to be compatible with + * the Java and Go versions. Returns how many bytes were written which + * should be getSizeInBytes(). + * + * Setting the portable flag to false enables a custom format that + * can save space compared to the portable format (e.g., for very + * sparse bitmaps). + */ + size_t write(char *buf, bool portable = true) const { + const char *orig = buf; + // push map size + uint64_t map_size = roarings.size(); + std::memcpy(buf, &map_size, sizeof(uint64_t)); + buf += sizeof(uint64_t); + std::for_each( + roarings.cbegin(), roarings.cend(), + [&buf, portable](const std::pair &map_entry) { + // push map key + std::memcpy(buf, &map_entry.first, sizeof(uint32_t)); + // ^-- Note: `*((uint32_t*)buf) = map_entry.first;` is undefined + + buf += sizeof(uint32_t); + // push map value Roaring + buf += map_entry.second.write(buf, portable); + }); + return buf - orig; + } + + /** + * Read a bitmap from a serialized version. This is meant to be compatible + * with the Java and Go versions. + * + * Setting the portable flag to false enable a custom format that + * can save space compared to the portable format (e.g., for very + * sparse bitmaps). + * + * This function is unsafe in the sense that if you provide bad data, many + * bytes could be read, possibly causing a buffer overflow. See also + * readSafe. + */ + static Roaring64Map read(const char *buf, bool portable = true) { + Roaring64Map result; + // get map size + uint64_t map_size; + std::memcpy(&map_size, buf, sizeof(uint64_t)); + buf += sizeof(uint64_t); + for (uint64_t lcv = 0; lcv < map_size; lcv++) { + // get map key + uint32_t key; + std::memcpy(&key, buf, sizeof(uint32_t)); + // ^-- Note: `uint32_t key = *((uint32_t*)buf);` is undefined + + buf += sizeof(uint32_t); + // read map value Roaring + Roaring read_var = Roaring::read(buf, portable); + // forward buffer past the last Roaring Bitmap + buf += read_var.getSizeInBytes(portable); + result.emplaceOrInsert(key, std::move(read_var)); + } + return result; + } + + /** + * Read a bitmap from a serialized version, reading no more than maxbytes + * bytes. This is meant to be compatible with the Java and Go versions. + * + * Setting the portable flag to false enable a custom format that can save + * space compared to the portable format (e.g., for very sparse bitmaps). + */ + static Roaring64Map readSafe(const char *buf, size_t maxbytes) { + Roaring64Map result; + // get map size + uint64_t map_size; + std::memcpy(&map_size, buf, sizeof(uint64_t)); + buf += sizeof(uint64_t); + for (uint64_t lcv = 0; lcv < map_size; lcv++) { + // get map key + if(maxbytes < sizeof(uint32_t)) { +#if ROARING_EXCEPTIONS + throw std::runtime_error("ran out of bytes"); +#else + ROARING_TERMINATE("ran out of bytes"); +#endif + } + uint32_t key; + std::memcpy(&key, buf, sizeof(uint32_t)); + // ^-- Note: `uint32_t key = *((uint32_t*)buf);` is undefined + + buf += sizeof(uint32_t); + maxbytes -= sizeof(uint32_t); + // read map value Roaring + Roaring read_var = Roaring::readSafe(buf, maxbytes); + // forward buffer past the last Roaring Bitmap + size_t tz = read_var.getSizeInBytes(true); + buf += tz; + maxbytes -= tz; + result.emplaceOrInsert(key, std::move(read_var)); + } + return result; + } + + /** + * Return the number of bytes required to serialize this bitmap (meant to + * be compatible with Java and Go versions) + * + * Setting the portable flag to false enable a custom format that can save + * space compared to the portable format (e.g., for very sparse bitmaps). + */ + size_t getSizeInBytes(bool portable = true) const { + // start with, respectively, map size and size of keys for each map + // entry + return std::accumulate( + roarings.cbegin(), roarings.cend(), + sizeof(uint64_t) + roarings.size() * sizeof(uint32_t), + [=](size_t previous, + const std::pair &map_entry) { + // add in bytes used by each Roaring + return previous + map_entry.second.getSizeInBytes(portable); + }); + } + + static const Roaring64Map frozenView(const char *buf) { + // size of bitmap buffer and key + const size_t metadata_size = sizeof(size_t) + sizeof(uint32_t); + + Roaring64Map result; + + // get map size + uint64_t map_size; + memcpy(&map_size, buf, sizeof(uint64_t)); + buf += sizeof(uint64_t); + + for (uint64_t lcv = 0; lcv < map_size; lcv++) { + // pad to 32 bytes minus the metadata size + while (((uintptr_t)buf + metadata_size) % 32 != 0) buf++; + + // get bitmap size + size_t len; + memcpy(&len, buf, sizeof(size_t)); + buf += sizeof(size_t); + + // get map key + uint32_t key; + memcpy(&key, buf, sizeof(uint32_t)); + buf += sizeof(uint32_t); + + // read map value Roaring + const Roaring read = Roaring::frozenView(buf, len); + result.emplaceOrInsert(key, read); + + // forward buffer past the last Roaring Bitmap + buf += len; + } + return result; + } + + // As with serialized 64-bit bitmaps, 64-bit frozen bitmaps are serialized + // by concatenating one or more Roaring::write output buffers with the + // preceeding map key. Unlike standard bitmap serialization, frozen bitmaps + // must be 32-byte aligned and requires a buffer length to parse. As a + // result, each concatenated output of Roaring::writeFrozen is preceeded by + // padding, the buffer size (size_t), and the map key (uint32_t). The + // padding is used to ensure 32-byte alignment, but since it is followed by + // the buffer size and map key, it actually pads to `(x - sizeof(size_t) + + // sizeof(uint32_t)) mod 32` to leave room for the metadata. + void writeFrozen(char *buf) const { + // size of bitmap buffer and key + const size_t metadata_size = sizeof(size_t) + sizeof(uint32_t); + + // push map size + uint64_t map_size = roarings.size(); + memcpy(buf, &map_size, sizeof(uint64_t)); + buf += sizeof(uint64_t); + + for (auto &map_entry : roarings) { + size_t frozenSizeInBytes = map_entry.second.getFrozenSizeInBytes(); + + // pad to 32 bytes minus the metadata size + while (((uintptr_t)buf + metadata_size) % 32 != 0) buf++; + + // push bitmap size + memcpy(buf, &frozenSizeInBytes, sizeof(size_t)); + buf += sizeof(size_t); + + // push map key + memcpy(buf, &map_entry.first, sizeof(uint32_t)); + buf += sizeof(uint32_t); + + // push map value Roaring + map_entry.second.writeFrozen(buf); + buf += map_entry.second.getFrozenSizeInBytes(); + } + } + + size_t getFrozenSizeInBytes() const { + // size of bitmap size and map key + const size_t metadata_size = sizeof(size_t) + sizeof(uint32_t); + size_t ret = 0; + + // map size + ret += sizeof(uint64_t); + + for (auto &map_entry : roarings) { + // pad to 32 bytes minus the metadata size + while ((ret + metadata_size) % 32 != 0) ret++; + ret += metadata_size; + + // frozen bitmaps must be 32-byte aligned + ret += map_entry.second.getFrozenSizeInBytes(); + } + return ret; + } + + /** + * Computes the intersection between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring64Map operator&(const Roaring64Map &o) const { + return Roaring64Map(*this) &= o; + } + + /** + * Computes the difference between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring64Map operator-(const Roaring64Map &o) const { + return Roaring64Map(*this) -= o; + } + + /** + * Computes the union between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring64Map operator|(const Roaring64Map &o) const { + return Roaring64Map(*this) |= o; + } + + /** + * Computes the symmetric union between two bitmaps and returns new bitmap. + * The current bitmap and the provided bitmap are unchanged. + */ + Roaring64Map operator^(const Roaring64Map &o) const { + return Roaring64Map(*this) ^= o; + } + + /** + * Whether or not we apply copy and write. + */ + void setCopyOnWrite(bool val) { + if (copyOnWrite == val) return; + copyOnWrite = val; + std::for_each(roarings.begin(), roarings.end(), + [=](std::pair &map_entry) { + map_entry.second.setCopyOnWrite(val); + }); + } + + /** + * Print the content of the bitmap + */ + void printf() const { + if (!isEmpty()) { + auto map_iter = roarings.cbegin(); + while (map_iter->second.isEmpty()) ++map_iter; + struct iter_data { + uint32_t high_bits{}; + char first_char{'{'}; + } outer_iter_data; + outer_iter_data.high_bits = roarings.begin()->first; + map_iter->second.iterate( + [](uint32_t low_bits, void *inner_iter_data) -> bool { + std::printf("%c%llu", + ((iter_data *)inner_iter_data)->first_char, + (long long unsigned)uniteBytes( + ((iter_data *)inner_iter_data)->high_bits, + low_bits)); + ((iter_data *)inner_iter_data)->first_char = ','; + return true; + }, + (void *)&outer_iter_data); + std::for_each( + ++map_iter, roarings.cend(), + [](const std::pair &map_entry) { + map_entry.second.iterate( + [](uint32_t low_bits, void *high_bits) -> bool { + std::printf(",%llu", + (long long unsigned)uniteBytes( + *(uint32_t *)high_bits, low_bits)); + return true; + }, + (void *)&map_entry.first); + }); + } else + std::printf("{"); + std::printf("}\n"); + } + + /** + * Print the content of the bitmap into a string + */ + std::string toString() const { + struct iter_data { + std::string str{}; // The empty constructor silences warnings from pedantic static analyzers. + uint32_t high_bits{0}; + char first_char{'{'}; + } outer_iter_data; + if (!isEmpty()) { + auto map_iter = roarings.cbegin(); + while (map_iter->second.isEmpty()) ++map_iter; + outer_iter_data.high_bits = roarings.begin()->first; + map_iter->second.iterate( + [](uint32_t low_bits, void *inner_iter_data) -> bool { + ((iter_data *)inner_iter_data)->str += + ((iter_data *)inner_iter_data)->first_char; + ((iter_data *)inner_iter_data)->str += std::to_string( + uniteBytes(((iter_data *)inner_iter_data)->high_bits, + low_bits)); + ((iter_data *)inner_iter_data)->first_char = ','; + return true; + }, + (void *)&outer_iter_data); + std::for_each( + ++map_iter, roarings.cend(), + [&outer_iter_data]( + const std::pair &map_entry) { + outer_iter_data.high_bits = map_entry.first; + map_entry.second.iterate( + [](uint32_t low_bits, void *inner_iter_data) -> bool { + ((iter_data *)inner_iter_data)->str += + ((iter_data *)inner_iter_data)->first_char; + ((iter_data *)inner_iter_data)->str += + std::to_string(uniteBytes( + ((iter_data *)inner_iter_data)->high_bits, + low_bits)); + return true; + }, + (void *)&outer_iter_data); + }); + } else + outer_iter_data.str = '{'; + outer_iter_data.str += '}'; + return outer_iter_data.str; + } + + /** + * Whether or not copy and write is active. + */ + bool getCopyOnWrite() const { return copyOnWrite; } + + /** + * Computes the logical or (union) between "n" bitmaps (referenced by a + * pointer). + */ + static Roaring64Map fastunion(size_t n, const Roaring64Map **inputs) { + Roaring64Map ans; + // not particularly fast + for (size_t lcv = 0; lcv < n; ++lcv) { + ans |= *(inputs[lcv]); + } + return ans; + } + + friend class Roaring64MapSetBitForwardIterator; + friend class Roaring64MapSetBitBiDirectionalIterator; + typedef Roaring64MapSetBitForwardIterator const_iterator; + typedef Roaring64MapSetBitBiDirectionalIterator const_bidirectional_iterator; + + /** + * Returns an iterator that can be used to access the position of the set + * bits. The running time complexity of a full scan is proportional to the + * number of set bits: be aware that if you have long strings of 1s, this + * can be very inefficient. + * + * It can be much faster to use the toArray method if you want to + * retrieve the set bits. + */ + const_iterator begin() const; + + /** + * A bogus iterator that can be used together with begin() + * for constructions such as: for (auto i = b.begin(); * i!=b.end(); ++i) {} + */ + const_iterator end() const; + +private: + std::map roarings{}; // The empty constructor silences warnings from pedantic static analyzers. + bool copyOnWrite{false}; + static uint32_t highBytes(const uint64_t in) { return uint32_t(in >> 32); } + static uint32_t lowBytes(const uint64_t in) { return uint32_t(in); } + static uint64_t uniteBytes(const uint32_t highBytes, + const uint32_t lowBytes) { + return (uint64_t(highBytes) << 32) | uint64_t(lowBytes); + } + // this is needed to tolerate gcc's C++11 libstdc++ lacking emplace + // prior to version 4.8 + void emplaceOrInsert(const uint32_t key, const Roaring &value) { +#if defined(__GLIBCXX__) && __GLIBCXX__ < 20130322 + roarings.insert(std::make_pair(key, value)); +#else + roarings.emplace(std::make_pair(key, value)); +#endif + } + + void emplaceOrInsert(const uint32_t key, Roaring &&value) { +#if defined(__GLIBCXX__) && __GLIBCXX__ < 20130322 + roarings.insert(std::make_pair(key, std::move(value))); +#else + roarings.emplace(key, value); +#endif + } +}; + +/** + * Used to go through the set bits. Not optimally fast, but convenient. + */ +class Roaring64MapSetBitForwardIterator { +public: + typedef std::forward_iterator_tag iterator_category; + typedef uint64_t *pointer; + typedef uint64_t &reference_type; + typedef uint64_t value_type; + typedef int64_t difference_type; + typedef Roaring64MapSetBitForwardIterator type_of_iterator; + + /** + * Provides the location of the set bit. + */ + value_type operator*() const { + return Roaring64Map::uniteBytes(map_iter->first, i.current_value); + } + + bool operator<(const type_of_iterator &o) const { + if (map_iter == map_end) return false; + if (o.map_iter == o.map_end) return true; + return **this < *o; + } + + bool operator<=(const type_of_iterator &o) const { + if (o.map_iter == o.map_end) return true; + if (map_iter == map_end) return false; + return **this <= *o; + } + + bool operator>(const type_of_iterator &o) const { + if (o.map_iter == o.map_end) return false; + if (map_iter == map_end) return true; + return **this > *o; + } + + bool operator>=(const type_of_iterator &o) const { + if (map_iter == map_end) return true; + if (o.map_iter == o.map_end) return false; + return **this >= *o; + } + + type_of_iterator &operator++() { // ++i, must returned inc. value + if (i.has_value == true) roaring_advance_uint32_iterator(&i); + while (!i.has_value) { + map_iter++; + if (map_iter == map_end) return *this; + roaring_init_iterator(&map_iter->second.roaring, &i); + } + return *this; + } + + type_of_iterator operator++(int) { // i++, must return orig. value + Roaring64MapSetBitForwardIterator orig(*this); + roaring_advance_uint32_iterator(&i); + while (!i.has_value) { + map_iter++; + if (map_iter == map_end) return orig; + roaring_init_iterator(&map_iter->second.roaring, &i); + } + return orig; + } + + bool move(const value_type& x) { + map_iter = p.lower_bound(Roaring64Map::highBytes(x)); + if (map_iter != p.cend()) { + roaring_init_iterator(&map_iter->second.roaring, &i); + if (map_iter->first == Roaring64Map::highBytes(x)) { + if (roaring_move_uint32_iterator_equalorlarger(&i, Roaring64Map::lowBytes(x))) + return true; + map_iter++; + if (map_iter == map_end) return false; + roaring_init_iterator(&map_iter->second.roaring, &i); + } + return true; + } + return false; + } + + bool operator==(const Roaring64MapSetBitForwardIterator &o) const { + if (map_iter == map_end && o.map_iter == o.map_end) return true; + if (o.map_iter == o.map_end) return false; + return **this == *o; + } + + bool operator!=(const Roaring64MapSetBitForwardIterator &o) const { + if (map_iter == map_end && o.map_iter == o.map_end) return false; + if (o.map_iter == o.map_end) return true; + return **this != *o; + } + + Roaring64MapSetBitForwardIterator &operator=(const Roaring64MapSetBitForwardIterator& r) { + map_iter = r.map_iter; + map_end = r.map_end; + i = r.i; + return *this; + } + + Roaring64MapSetBitForwardIterator(const Roaring64MapSetBitForwardIterator& r) + : p(r.p), + map_iter(r.map_iter), + map_end(r.map_end), + i(r.i) + {} + + Roaring64MapSetBitForwardIterator(const Roaring64Map &parent, + bool exhausted = false) + : p(parent.roarings), map_end(parent.roarings.cend()) { + if (exhausted || parent.roarings.empty()) { + map_iter = parent.roarings.cend(); + } else { + map_iter = parent.roarings.cbegin(); + roaring_init_iterator(&map_iter->second.roaring, &i); + while (!i.has_value) { + map_iter++; + if (map_iter == map_end) return; + roaring_init_iterator(&map_iter->second.roaring, &i); + } + } + } + +protected: + const std::map& p; + std::map::const_iterator map_iter{}; // The empty constructor silences warnings from pedantic static analyzers. + std::map::const_iterator map_end{}; // The empty constructor silences warnings from pedantic static analyzers. + api::roaring_uint32_iterator_t i{}; // The empty constructor silences warnings from pedantic static analyzers. +}; + +class Roaring64MapSetBitBiDirectionalIterator final :public Roaring64MapSetBitForwardIterator { +public: + explicit Roaring64MapSetBitBiDirectionalIterator(const Roaring64Map &parent, + bool exhausted = false) + : Roaring64MapSetBitForwardIterator(parent, exhausted), map_begin(parent.roarings.cbegin()) + {} + + Roaring64MapSetBitBiDirectionalIterator &operator=(const Roaring64MapSetBitForwardIterator& r) { + *(Roaring64MapSetBitForwardIterator*)this = r; + return *this; + } + + Roaring64MapSetBitBiDirectionalIterator& operator--() { // --i, must return dec.value + if (map_iter == map_end) { + --map_iter; + roaring_init_iterator_last(&map_iter->second.roaring, &i); + if (i.has_value) return *this; + } + + roaring_previous_uint32_iterator(&i); + while (!i.has_value) { + if (map_iter == map_begin) return *this; + map_iter--; + roaring_init_iterator_last(&map_iter->second.roaring, &i); + } + return *this; + } + + Roaring64MapSetBitBiDirectionalIterator operator--(int) { // i--, must return orig. value + Roaring64MapSetBitBiDirectionalIterator orig(*this); + if (map_iter == map_end) { + --map_iter; + roaring_init_iterator_last(&map_iter->second.roaring, &i); + return orig; + } + + roaring_previous_uint32_iterator(&i); + while (!i.has_value) { + if (map_iter == map_begin) return orig; + map_iter--; + roaring_init_iterator_last(&map_iter->second.roaring, &i); + } + return orig; + } + +protected: + std::map::const_iterator map_begin; +}; + +inline Roaring64MapSetBitForwardIterator Roaring64Map::begin() const { + return Roaring64MapSetBitForwardIterator(*this); +} + +inline Roaring64MapSetBitForwardIterator Roaring64Map::end() const { + return Roaring64MapSetBitForwardIterator(*this, true); +} + +} // namespace roaring + +#endif /* INCLUDE_ROARING_64_MAP_HH_ */ +/* end file cpp/roaring64map.hh */ diff --git a/src/core/CLucene/util/stringUtil.cpp b/src/core/CLucene/util/stringUtil.cpp new file mode 100644 index 00000000000..68437f56869 --- /dev/null +++ b/src/core/CLucene/util/stringUtil.cpp @@ -0,0 +1,51 @@ +// +// Created by 姜凯 on 2022/9/20. +// +#include "stringUtil.h" + +template <> +const char* LUCENE_BLANK_SSTRING() { + return LUCENE_BLANK_ASTRING; +} + +template <> +const TCHAR* LUCENE_BLANK_SSTRING() { + return LUCENE_BLANK_STRING; +} + +template<> +void strnCopy(char *dst, const char *src, size_t size) { + strncpy(dst, src, size); +} +template<> +void strnCopy(TCHAR *dst, const TCHAR *src, size_t size) { _tcsncpy(dst, src, size); } + +template<> +void strCopy(char *dst, const char *src) { + strcpy(dst, src); +} +template<> +void strCopy(TCHAR *dst, const TCHAR *src) { _tcscpy(dst, src); } + +template<> +int strCompare(const char *leftStr, const char *rightStr) { + return strcmp(leftStr, rightStr); +} +template<> +int strCompare(const TCHAR *leftStr, const TCHAR *rightStr) { + return _tcscmp(leftStr, rightStr); +} + +template<> +char *strDuplicate(const char *str) { + return strdup(str); +} +template<> +TCHAR *strDuplicate(const TCHAR *str) { + return STRDUP_TtoT(str); +} + +template<> +size_t lenOfString(const char *str) { return strlen(str); } +template<> +size_t lenOfString(const TCHAR *str) { return _tcslen(str); } \ No newline at end of file diff --git a/src/core/CLucene/util/stringUtil.h b/src/core/CLucene/util/stringUtil.h new file mode 100644 index 00000000000..eeddce79b89 --- /dev/null +++ b/src/core/CLucene/util/stringUtil.h @@ -0,0 +1,27 @@ +// +// Created by 姜凯 on 2022/9/20. +// + +#ifndef _lucene_util__stringutil_H +#define _lucene_util__stringutil_H + +#include "CLucene/_ApiHeader.h" + +template +const T* LUCENE_BLANK_SSTRING(); + +template +void strnCopy(T *dst, const T *src, size_t size); + +template +void strCopy(T *dst, const T *src); + +template +int strCompare(const T *leftStr, const T *rightStr); + +template +T *strDuplicate(const T *str); + +template +size_t lenOfString(const T *str); +#endif//_lucene_util__stringutil_H diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 00000000000..c526e701fa8 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,348 @@ +PROJECT(clucene-core) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${clucene_SOURCE_DIR}/cmake" "${clucene-shared_SOURCE_DIR}/cmake") + +#define command line options +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS} -DMAKE_CLUCENE_CORE_LIB) + +#see if we can hide all symbols by default... +MACRO_CHECK_GCC_VISIBILITY(_CL_HAVE_GCCVISIBILITYPATCH) + +#add the files to our groups and core +SOURCE_GROUP("analysis" ./CLucene/analysis/*) +#seems to be a bug in cmake, can't put these in analysis\\standard folder :( +SOURCE_GROUP("analysis-standard" ./CLucene/analysis/standard/*) +SOURCE_GROUP("document" ./CLucene/document/*) +SOURCE_GROUP("debug" ./CLucene/debug/*) +SOURCE_GROUP("index" ./CLucene/index/*) +SOURCE_GROUP("queryParser" ./CLucene/queryParser/*) +SOURCE_GROUP("queryParser-legacy" ./CLucene/queryParser/legacy/*) +SOURCE_GROUP("search" ./CLucene/search/*) +SOURCE_GROUP("search-spans" ./CLucene/search/spans/*) +SOURCE_GROUP("store" ./CLucene/store/*) +SOURCE_GROUP("util" ./CLucene/util/*) + +SET(clucene_core_Files + ./CLucene/StdHeader.cpp + ./CLucene/debug/error.cpp + ./CLucene/util/ThreadLocal.cpp + ./CLucene/util/Reader.cpp + ./CLucene/util/Equators.cpp + ./CLucene/util/FastCharStream.cpp + ./CLucene/util/MD5Digester.cpp + ./CLucene/util/StringIntern.cpp + ./CLucene/util/BitSet.cpp + CLucene/util/bkd/bkd_writer.cpp + CLucene/util/bkd/bkd_reader.cpp + CLucene/util/bkd/index_tree.cpp + CLucene/util/bkd/packed_index_tree.cpp + CLucene/util/bkd/legacy_index_tree.cpp + CLucene/util/bkd/heap_point_writer.cpp + CLucene/util/bkd/heap_point_reader.cpp + CLucene/util/bkd/point_reader.cpp + CLucene/util/bkd/docIds_writer.cpp + CLucene/util/bkd/bkd_msb_radix_sorter.cpp + CLucene/util/croaring/roaring.c + CLucene/util/croaring/roaring.h + CLucene/util/croaring/roaring.hh + ./CLucene/util/BitUtil.cpp + ./CLucene/util/BytesRef.cpp + ./CLucene/util/BytesRefBuilder.cpp + ./CLucene/util/CodecUtil.cpp + ./CLucene/util/LongBitSet.cpp + ./CLucene/util/IntroSorter.cpp + ./CLucene/util/Sorter.cpp + ./CLucene/util/MSBRadixSorter.cpp + ./CLucene/util/FixedBitSet.cpp + ./CLucene/util/FutureArrays.cpp + ./CLucene/util/NumericUtils.cpp + ./CLucene/util/stringUtil.cpp + ./CLucene/queryParser/FastCharStream.cpp + ./CLucene/queryParser/MultiFieldQueryParser.cpp + ./CLucene/queryParser/QueryParser.cpp + ./CLucene/queryParser/QueryParserTokenManager.cpp + ./CLucene/queryParser/QueryToken.cpp + ./CLucene/queryParser/legacy/Lexer.cpp + ./CLucene/queryParser/legacy/MultiFieldQueryParser.cpp + ./CLucene/queryParser/legacy/QueryParser.cpp + ./CLucene/queryParser/legacy/QueryParserBase.cpp + ./CLucene/queryParser/legacy/QueryToken.cpp + ./CLucene/queryParser/legacy/TokenList.cpp + + #./CLucene/queryParser/QueryBuilder.cpp + #./CLucene/queryParser/classic/QueryParserBase.cpp + #./CLucene/queryParser/classic/QueryParser.cpp + #./CLucene/queryParser/classic/Token.cpp + #./CLucene/queryParser/classic/TokenMgrError.cpp + #./CLucene/queryParser/classic/CharStream.cpp + #./CLucene/queryParser/classic/ParseException.cpp + #./CLucene/queryParser/classic/QueryParserTokenManager.cpp + ./CLucene/analysis/standard/StandardAnalyzer.cpp + ./CLucene/analysis/standard/StandardFilter.cpp + ./CLucene/analysis/standard/StandardTokenizer.cpp + #./CLucene/analysis/mmseg/MMsegAnalyzer.cpp + #./CLucene/analysis/mmseg/MmsegTokenizer.cpp + ./CLucene/analysis/Analyzers.cpp + ./CLucene/analysis/AnalysisHeader.cpp + ./CLucene/store/MMapInput.cpp + ./CLucene/store/IndexInput.cpp + ./CLucene/store/ByteArrayDataInput.cpp + ./CLucene/store/Lock.cpp + ./CLucene/store/LockFactory.cpp + ./CLucene/store/IndexOutput.cpp + ./CLucene/store/Directory.cpp + ./CLucene/store/FSDirectory.cpp + ./CLucene/store/RAMDirectory.cpp + ./CLucene/document/Document.cpp + ./CLucene/document/DateField.cpp + ./CLucene/document/DateTools.cpp + ./CLucene/document/Field.cpp + ./CLucene/document/FieldSelector.cpp + ./CLucene/document/NumberTools.cpp + ./CLucene/index/IndexFileNames.cpp + ./CLucene/index/IndexFileNameFilter.cpp + ./CLucene/index/IndexDeletionPolicy.cpp + ./CLucene/index/SegmentMergeInfo.cpp + ./CLucene/index/SegmentInfos.cpp + ./CLucene/index/MergeScheduler.cpp + ./CLucene/index/SegmentTermDocs.cpp + ./CLucene/index/FieldsWriter.cpp + ./CLucene/index/TermInfosWriter.cpp + ./CLucene/index/Term.cpp + ./CLucene/index/Terms.cpp + ./CLucene/index/MergePolicy.cpp + ./CLucene/index/DocumentsWriter.cpp + ./CLucene/index/SDocumentWriter.cpp + ./CLucene/index/SDocumentWriter.h + ./CLucene/index/DocumentsWriterThreadState.cpp + ./CLucene/index/SegmentTermVector.cpp + ./CLucene/index/TermVectorReader.cpp + ./CLucene/index/FieldInfos.cpp + ./CLucene/index/CompoundFile.cpp + ./CLucene/index/SkipListReader.cpp + ./CLucene/index/SkipListWriter.cpp + ./CLucene/index/IndexFileDeleter.cpp + ./CLucene/index/SegmentReader.cpp + ./CLucene/index/DirectoryIndexReader.cpp + ./CLucene/index/TermVectorWriter.cpp + ./CLucene/index/IndexReader.cpp + ./CLucene/index/SegmentTermPositions.cpp + ./CLucene/index/SegmentMerger.cpp + ./CLucene/index/IndexWriter.cpp + ./CLucene/index/MultiReader.cpp + ./CLucene/index/MultiSegmentReader.cpp + ./CLucene/index/Payload.cpp + ./CLucene/index/SegmentTermEnum.cpp + ./CLucene/index/TermInfo.cpp + ./CLucene/index/IndexModifier.cpp + ./CLucene/index/SegmentMergeQueue.cpp + ./CLucene/index/FieldsReader.cpp + ./CLucene/index/TermInfosReader.cpp + ./CLucene/index/MultipleTermPositions.cpp + ./CLucene/search/Compare.cpp + ./CLucene/search/Scorer.cpp + ./CLucene/search/ScorerDocQueue.cpp + ./CLucene/search/PhraseScorer.cpp + ./CLucene/search/SloppyPhraseScorer.cpp + ./CLucene/search/DisjunctionSumScorer.cpp + ./CLucene/search/ConjunctionScorer.cpp + ./CLucene/search/PhraseQuery.cpp + ./CLucene/search/PrefixQuery.cpp + ./CLucene/search/ExactPhraseScorer.cpp + ./CLucene/search/TermScorer.cpp + ./CLucene/search/Similarity.cpp + ./CLucene/search/BooleanScorer.cpp + ./CLucene/search/BooleanScorer2.cpp + ./CLucene/search/HitQueue.cpp + ./CLucene/search/FieldCacheImpl.cpp + ./CLucene/search/ChainedFilter.cpp + ./CLucene/search/RangeFilter.cpp + ./CLucene/search/CachingWrapperFilter.cpp + ./CLucene/search/QueryFilter.cpp + ./CLucene/search/TermQuery.cpp + ./CLucene/search/FuzzyQuery.cpp + ./CLucene/search/SearchHeader.cpp + ./CLucene/search/RangeQuery.cpp + ./CLucene/search/IndexSearcher.cpp + ./CLucene/search/Sort.cpp + ./CLucene/search/PhrasePositions.cpp + ./CLucene/search/FieldDocSortedHitQueue.cpp + ./CLucene/search/WildcardTermEnum.cpp + ./CLucene/search/MultiSearcher.cpp + ./CLucene/search/Hits.cpp + ./CLucene/search/MultiTermQuery.cpp + ./CLucene/search/FilteredTermEnum.cpp + ./CLucene/search/FieldSortedHitQueue.cpp + ./CLucene/search/WildcardQuery.cpp + ./CLucene/search/Explanation.cpp + ./CLucene/search/BooleanQuery.cpp + ./CLucene/search/FieldCache.cpp + ./CLucene/search/DateFilter.cpp + ./CLucene/search/MatchAllDocsQuery.cpp + ./CLucene/search/MultiPhraseQuery.cpp + ./CLucene/search/ConstantScoreQuery.cpp + ./CLucene/search/CachingSpanFilter.cpp + ./CLucene/search/CachingSpanFilter.h + ./CLucene/search/SpanFilter.h + ./CLucene/search/SpanFilterResult.h + ./CLucene/search/SpanQueryFilter.cpp + ./CLucene/search/SpanQueryFilter.h + ./CLucene/search/spans/_EmptySpans.h + ./CLucene/search/spans/_NearSpansOrdered.h + ./CLucene/search/spans/_NearSpansUnordered.h + ./CLucene/search/spans/_TermSpans.h + ./CLucene/search/spans/NearSpansOrdered.cpp + ./CLucene/search/spans/NearSpansUnordered.cpp + ./CLucene/search/spans/SpanFirstQuery.cpp + ./CLucene/search/spans/SpanFirstQuery.h + ./CLucene/search/spans/SpanNearQuery.cpp + ./CLucene/search/spans/SpanNearQuery.h + ./CLucene/search/spans/SpanNotQuery.cpp + ./CLucene/search/spans/SpanNotQuery.h + ./CLucene/search/spans/SpanOrQuery.cpp + ./CLucene/search/spans/SpanOrQuery.h + ./CLucene/search/spans/SpanQuery.h + ./CLucene/search/spans/Spans.h + ./CLucene/search/spans/SpanScorer.cpp + ./CLucene/search/spans/SpanScorer.h + ./CLucene/search/spans/SpanTermQuery.cpp + ./CLucene/search/spans/SpanTermQuery.h + ./CLucene/search/spans/SpanWeight.cpp + ./CLucene/search/spans/SpanWeight.h + ./CLucene/search/spans/TermSpans.cpp +) + +#if (CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64") +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=haswell -DAVX2_ON -fstrict-aliasing") + #ADD_DEFINITIONS(-DAVX2_ON) + #ADD_DEFINITIONS(-DSSE2_ON) +#endif() + +#SET(pfor_Files_SSE +# ${clucene-ext_SOURCE_DIR}/for/transpose.c +# ${clucene-ext_SOURCE_DIR}/for/bitunpack.c +# ${clucene-ext_SOURCE_DIR}/for/bitpack.c +# ${clucene-ext_SOURCE_DIR}/for/bitutil.c +# ${clucene-ext_SOURCE_DIR}/for/vp4d.c +# ${clucene-ext_SOURCE_DIR}/for/vp4c.c +# ) + +#if USE_SHARED_OBJECT_FILES then we link directly to the object files (means rebuilding them for the core) +IF ( USE_SHARED_OBJECT_FILES ) + GET_SHARED_FILES(clucene_shared_Files) +ENDIF ( USE_SHARED_OBJECT_FILES ) + +#find our headers +file(GLOB_RECURSE HEADERS ${clucene-core_SOURCE_DIR}/*.h ${clucene-ext_SOURCE_DIR}/for/vp4.h) + +#create the libraries +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/core ) +add_library(clucene-core SHARED + ${clucene_core_Files} ${clucene_shared_Files} ${HEADERS} +) + +#set properties on the libraries +SET_TARGET_PROPERTIES(clucene-core PROPERTIES + VERSION ${CLUCENE_VERSION} + SOVERSION ${CLUCENE_SOVERSION} + COMPILE_DEFINITIONS_DEBUG _DEBUG +) + +#link the clucene-core library against the releavent clucene-shared library (if we aren't using the object files) +IF ( NOT USE_SHARED_OBJECT_FILES ) + TARGET_LINK_LIBRARIES(clucene-core clucene-shared ${EXTRA_LIBS}) +ENDIF ( NOT USE_SHARED_OBJECT_FILES ) + + +IF ( BUILD_STATIC_LIBRARIES ) + + add_library(clucene-core-static STATIC + ${clucene_core_Files} ${clucene_shared_Files} ${HEADERS} + ) + + #target_link_libraries(clucene-core-static PRIVATE clucene-mmseg-static) + #target_include_directories(clucene-core-static PUBLIC ${clucene-mmseg_SOURCE_DIR}/include) + + SET_TARGET_PROPERTIES(clucene-core-static PROPERTIES + VERSION ${CLUCENE_VERSION} + SOVERSION ${CLUCENE_SOVERSION} + COMPILE_DEFINITIONS_DEBUG _DEBUG + ) + + #and install library + install(TARGETS clucene-core-static + DESTINATION ${LIB_DESTINATION} + COMPONENT runtime ) +ENDIF ( BUILD_STATIC_LIBRARIES ) + +#install public headers. +FOREACH(file ${HEADERS}) + get_filename_component(apath ${file} PATH) + get_filename_component(aname ${file} NAME) + file(RELATIVE_PATH relpath ${CMAKE_SOURCE_DIR}/src/core ${apath}) + IF ( NOT aname MATCHES "^_.*" ) + install(FILES ${file} + DESTINATION include/${relpath} + COMPONENT development) + ENDIF ( NOT aname MATCHES "^_.*" ) +ENDFOREACH(file) + +#install clucene-shared headers. +install(FILES ${clucene-shared_SOURCE_DIR}/CLucene/SharedHeader.h + DESTINATION include/CLucene + COMPONENT development) +install(FILES ${clucene-shared_SOURCE_DIR}/CLucene/LuceneThreads.h + DESTINATION include/CLucene + COMPONENT development ) + +# code for installing an script to help cmake applications determine +# the CLucene version number +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CLuceneConfig.cmake" " + set(CLUCENE_VERSION_MAJOR ${CLUCENE_VERSION_MAJOR}) + set(CLUCENE_VERSION_MINOR ${CLUCENE_VERSION_MINOR}) + set(CLUCENE_VERSION_REVISION ${CLUCENE_VERSION_REVISION}) + set(CLUCENE_VERSION_PATCH ${CLUCENE_VERSION_PATCH}) + + set(CLUCENE_VERSION ${CLUCENE_VERSION}) + set(CLUCENE_SOVERSION ${CLUCENE_SOVERSION}) +") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CLuceneConfig.cmake" + DESTINATION ${LIB_DESTINATION}/CLuceneConfig.cmake) + +# install pkg-config file +IF(NOT WIN32) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libclucene-core.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libclucene-core.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libclucene-core.pc + DESTINATION ${LIB_DESTINATION}/pkgconfig ) +ENDIF(NOT WIN32) + + +#install non system-independent +IF ( LUCENE_SYS_INCLUDES ) + install(FILES ${clucene-shared_BINARY_DIR}/CLucene/clucene-config.h + DESTINATION ${LUCENE_SYS_INCLUDES}/CLucene + COMPONENT development) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CLuceneConfig.cmake + DESTINATION ${LUCENE_SYS_INCLUDES}/CLucene + COMPONENT development) +ELSE ( LUCENE_SYS_INCLUDES ) + install(FILES ${clucene-shared_BINARY_DIR}/CLucene/clucene-config.h + DESTINATION include/CLucene + COMPONENT development) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CLuceneConfig.cmake + DESTINATION include/CLucene + COMPONENT development) + install(FILES ${clucene-shared_BINARY_DIR}/CLucene/util/Misc.h + DESTINATION include/CLucene/util + COMPONENT development) + install(FILES ${clucene_SOURCE_DIR}/src/core/CLucene/util/croaring/roaring.hh + DESTINATION include/CLucene/util/croaring + COMPONENT development) +ENDIF ( LUCENE_SYS_INCLUDES ) + + +#and install library +install(TARGETS clucene-core + DESTINATION ${LIB_DESTINATION} + COMPONENT runtime ) diff --git a/src/core/files_list.txt b/src/core/files_list.txt new file mode 100644 index 00000000000..5d0efe62867 --- /dev/null +++ b/src/core/files_list.txt @@ -0,0 +1,314 @@ +Lucene 2.3.2 Files: +--------------- + +DONE ISH analysis\Analyzer.java - Needs testing of mem-leaks caused by the reusableTokenStream interface. See http://permalink.gmane.org/gmane.comp.jakarta.lucene.clucene.devel/3359. Currently all class-specific data is being released on its destructor, and the Tokenizer is never being released by the Analyzer. +? analysis\CachingTokenFilter.java +? analysis\CharArraySet.java +? analysis\CharTokenizer.java +? analysis\ISOLatin1AccentFilter.java +? analysis\KeywordTokenizer.java +? analysis\LetterTokenizer.java +? analysis\LowerCaseFilter.java +? analysis\LowerCaseTokenizer.java +? analysis\SinkTokenizer.java +? analysis\standard\StandardAnalyzer.java +? analysis\standard\StandardFilter.java +? analysis\standard\StandardTokenizer.java +? analysis\standard\StandardTokenizerImpl.java +? analysis\standard\StandardTokenizerImpl.jflex +DONE ISH analysis\StopAnalyzer.java - reusableTokenStream and StopAnalyzer(Set stopWords) were not implemented. May need to revisit reusableTokenStream() +? analysis\TeeTokenFilter.java +? analysis\Token.java +? analysis\TokenFilter.java +DONE ISH analysis\TokenStream.java - Should we keep next() deprecated for performance reasons, or comply with JL? Also, check to see if reset() is required here at all, or can be defined for Tokenizer only (one level above) +DONE ISH analysis\WhitespaceTokenizer.java +DONE ISH analysis\WordlistLoader.java - Missing getStemDict +DONE ISH document\DateTools.java - TODO: Create a test suite for this based on values tested with Java Lucene + + + +DONE ISH queryParser\MultiFieldQueryParser.java - Some tests are missing +DONE ISH queryParser\QueryParser.java - Missing Locale and Calendar support (for RangeQuery) and some tests. _tcstod. +IRRELEVANT queryParser\QueryParser.jj +DONE ISH queryParser\QueryParserConstants.java +DONE ISH queryParser\QueryParserTokenManager.java - PrintStream implementation is missing (if at all necessary) +DONE ISH queryParser\Token.java - If LUCENE_TOKEN_WORD_LENGTH is still necessary, it needs to be implemented in the new code, and have tests written to make sure it works flawlessly with the new QP. Currently it's half implemented. +DONE ISH queryParser\TokenMgrError.java - Integrated within QueryParserTokenManager as functions + +? search\BooleanScorer.java +? search\DisjunctionMaxQuery.java - new file, not ported yet +? search\ExtendedFieldCache.java +? search\ExtendedFieldCacheImpl.java +? search\FieldCache.java +? search\FieldCacheImpl.java +? search\FieldDoc.java +? search\FieldDocSortedHitQueue.java +? search\FieldSortedHitQueue.java +? search\FilteredQuery.java +DONE ISH search\FilteredTermEnum.java - Can we mend term(void) and term(bool) ? +? search\FilterManager.java +DONE ISH search\FuzzyQuery.java - See TODOs. +DONE ISH search\FuzzyTermEnum.java - See TODOs. Also, Old similarity code is commented out and marked as "legacy". It looks like some optimizations were made there, but since Fuzzy queries weren't working as they should we had to revert to Java's implementation. Perhaps after tests are complete we could try and get the optimized version to work again. +? search\Hit.java +? search\HitIterator.java +DONE ISH search\Hits.java - Needs rethinking of why Query* is used instead of Weight* +PARTIAL search\IndexSearcher.java - Almost no difference. See todo and complete comparison between JL and CL. +? search\MultiSearcher.java +? search\PhrasePositions.java +? search\QueryFilter.java +? search\QueryTermVector.java +? search\QueryWrapperFilter.java +? search\RemoteSearchable.java +? search\Searchable.java - Any idea why the explain() function in Searchable and derived differs from Java (accepts Query* instead of Weight*)? can we safely confrom with Java now? +? search\Similarity.java +? search\SimilarityDelegator.java +DONE ISH search\TermQuery.java - Missing implementation for extractTerms(Set) +? search\TopDocCollector.java +? search\TopFieldDocCollector.java + +PARTIAL JW store\NativeFSLockFactory.java - 1 class implemented as FSLockFactory +PARTIAL JW store\SimpleFSLockFactory.java - 1 class implemented as FSLockFactory +? store\VerifyingLockFactory.java + +? util\ScorerDocQueue.java + +Pending: waiting on other things... +DONE ISH search\Filter.java - Remove virtual toString once CachingWrapperFilter and ChainedFilter (does not exist in JL?) conform to JL. Missing equals() and hashCode() virtual functions, hence all derived miss this as well. +PARTIAL ISH search\RangeFilter.java - Missing hashCode() and equals() -- see comment on Filter. Needs testing for bits() and toString(). + +Finished except a few functions: +DONE ISH search\PhraseQuery.java - extractTerms(Set) was never ported (probably not needed). Inconsitency in return value of getPositions getTerms. +DONE ISH search\Query.java - Missing implementation for extractTerms(Set terms) +DONE ISH search\MultiTermQuery.java - hashcode and equals were never ported +DONE ISH search\MatchAllDocsQuery.java - MatchAllDocsWeight::explain needs to support ComplexExplanation in order to set "match", plus we might want to reconsider returning void instead of Explanation* in Weight::explain an derived +DONE ISH search\MultiPhraseQuery.java - Complete TODOs (2 unported functions, test hashCode(), clone(), and decide on memory contract for rewrite) +DONE ISH index\SegmentTermPositions.java - getPayload is still incomplete +DONE ISH search\ConstantScoreQuery.java - See TODOs +DONE ISH search\ConstantScoreRangeQuery.java - See TODOs + +CMake: +Check todos in (_)clucene-config.h.cmake. Some checks arent being done yet. +for example: _CL_HAVE_PTHREAD_MUTEX_RECURSIVE +get rid of Misc.h, repl_* +check up on sub-folders bug (analysis/standard) +MapViewOfFile issues (cmake not picking up functions in kernel32) +Use safe CRT where possible. For example, make _tcsdup / stringDuplicate require n and call the _s version if cmake realizes it exists + +Misc TODOs: + + + + + + + +Post v1 Final: +DONE ISH analysis\StopFilter.java - Should we implement a CharArraySet or similar? Radix/PATRICIA maybe? +DONE ISH analysis\TokenStream.java - Should we keep next() deprecated for performance reasons, or comply with JL? (ben: for me, it's fine as it is now) Also, check to see if reset() is required here at all, or can be defined for Tokenizer only (one level above) +DONE ISH analysis\WordlistLoader.java - Missing getStemDict +DONE ISH document\DateTools.java - TODO: Create a test suite for this based on values tested with Java Lucene +PARTIAL ISH/BEN index\SegmentInfos.java - Still requires some testing of the sub-classes under SegmentInfos used for the retry mechanism, the write function (only after reading totally conforms with JL) + +? search\CachingSpanFilter.java +? search\CachingWrapperFilter.java +? index\SortedTermVectorMapper.java -alt +? index\TermVectorEntryFreqSortedComparator.java -alt +? index\PositionBasedTermVectorMapper.java -alt +? index\CheckIndex.java +DONE BEN search\BooleanScorer2.java +? search\SpanFilter.java +? search\SpanFilterResult.java +? search\SpanQueryFilter.java +? search\spans\NearSpansOrdered.java +? search\spans\NearSpansUnordered.java +? search\spans\SpanFirstQuery.java +? search\spans\SpanNearQuery.java +? search\spans\SpanNotQuery.java +? search\spans\SpanOrQuery.java +? search\spans\SpanQuery.java +? search\spans\Spans.java +? search\spans\SpanScorer.java +? search\spans\SpanTermQuery.java +? search\spans\SpanWeight.java +? search\spans\TermSpans.java +? search\function\ByteFieldSource.java +? search\function\CustomScoreQuery.java +? search\function\DocValues.java +? search\function\FieldCacheSource.java +? search\function\FieldScoreQuery.java +? search\function\FloatFieldSource.java +? search\function\IntFieldSource.java +? search\function\OrdFieldSource.java +? search\function\ReverseOrdFieldSource.java +? search\function\ShortFieldSource.java +? search\function\ValueSource.java +? search\function\ValueSourceQuery.java +? index\ConcurrentMergeScheduler.java +? index\SnapshotDeletionPolicy.java +? index\ParallelReader.java +? store\LockStressTest.java +? store\LockVerifyServer.java +? search\ParallelMultiSearcher.java +? search\payloads\BoostingTermQuery.java +? search\RemoteCachingWrapperFilter.java + + + + + + + +"Archived" +DONE ISH document\Fieldable.java - Merged into Field +DONE ISH document\FieldSelector.java +DONE ISH document\FieldSelectorResult.java +DONE ISH document\LoadFirstFieldSelector.java +DONE ISH document\NumberTools.java +DONE BEN document\MapFieldSelector.java +DONE BEN document\SetBasedFieldSelector.java (Irrelevent, actually, we achive both in MapFieldSelector) +DONE ISH document\Document.java - All Fieldable mentiones were kept Field*. +DONE ISH document\Field.java - Still need to complete all TODOs in file + +DONE ISH queryParser\ParseException.java - Done, integrated within QueryParser as functions (no special Exception class required) + +DONE ISH/BEN index\TermInfosReader.java +DONE ISH index\FieldsReader.java +DONE BEN index\FieldsWriter.java +DONE ISH index\TermVectorMapper.java +DONE ISH index\TermVectorOffsetInfo.java +DONE ISH index\TermVectorsReader.java +DONE ISH/BEN index\SegmentInfo.java +DONE BEN index\StaleReaderException.java +DONE BEN index\TermBuffer.java (actually, not nessary, Term has the same functionality) +DONE BEN index\TermInfosWriter.java +DONE ISH index\FieldInfo.java +DONE ISH index\SegmentMergeInfo.java +DONE ISH index\SegmentMergeQueue.java +DONE ISH index\SegmentTermVector.java +DONE ISH index\Term.java +DONE ISH index\TermDocs.java +DONE ISH index\TermEnum.java +DONE ISH index\TermFreqVector.java +DONE ISH index\TermInfo.java +DONE ISH index\TermPositions.java +DONE ISH index\TermPositionVector.java +IRRELEVANT LucenePackage.java +DONE ISH queryParser\CharStream.java +DONE ISH queryParser\FastCharStream.java +DONE ISH index\CompoundFileReader.java +DONE BEN index\CompoundFileWriter.java +DONE BEN index\CorruptIndexException.java +DONE ISH index\DefaultSkipListReader.java +DONE BEN index\DefaultSkipListWriter.java +DONE BEN index\DirectoryIndexReader.java +DONE BEN index\DocumentsWriter.java +DONE ISH index\FieldInfos.java +DONE BEN index\FieldReaderException.java +DONE ISH index\FieldSortedTermVectorMapper.java +DONE ISH index\FilterIndexReader.java +DONE BEN index\IndexCommitPoint.java +DONE BEN index\IndexDeletionPolicy.java +DONE BEN index\IndexFileDeleter.java +DONE BEN index\IndexFileNameFilter.java +DONE JW index\IndexFileNames.java +DONE BEN index\IndexModifier.java +DONE BEN index\IndexReader.java +DONE BEN index\IndexWriter.java +DONE BEN index\KeepOnlyLastCommitDeletionPolicy.java +DONE BEN index\LogByteSizeMergePolicy.java +DONE BEN index\LogDocMergePolicy.java +DONE BEN index\LogMergePolicy.java +DONE BEN index\MergePolicy.java +DONE BEN index\MergeScheduler.java +DONE ISH index\MultiLevelSkipListReader.java +DONE BEN index\MultiLevelSkipListWriter.java +DONE BEN index\MultiReader.java +DONE BEN index\MultiSegmentReader.java +DONE ISH index\Payload.java +DONE BEN index\SegmentMerger.java +DONE BEN index\SegmentReader.java +DONE BEN index\SegmentTermDocs.java +DONE BEN index\SegmentTermEnum.java +DONE ISH index\SegmentTermPositionVector.java +DONE BEN index\SerialMergeScheduler.java +DONE BEN index\TermVectorEntry.java +DONE BEN index\TermVectorsWriter.java + + +DONE ISH/BEN index\MultipleTermPositions.java +DONE BEN search\BooleanQuery.java +DONE BEN search\DefaultSimilarity.java +DONE BEN search\ConjunctionScorer.java +DONE ISH search\SloppyPhraseScorer.java +DONE ISH search\ExactPhraseScorer.java +DONE BEN search\NonMatchingScorer.java - This class is under BooleanScorer2 - should this ever be used anywhere else in the namespace it's going to be a problem. Perhaps we should move it now already outside to the namespace scope? +DONE BEN search\ReqExclScorer.java - This class is under BooleanScorer2 - should this ever be used anywhere else in the namespace it's going to be a problem. Perhaps we should move it now already outside to the namespace scope? +DONE BEN search\ReqOptSumScorer.java - This class is under BooleanScorer2 - should this ever be used anywhere else in the namespace it's going to be a problem. Perhaps we should move it now already outside to the namespace scope? +DONE BEN search\PhraseQueue.java +DONE ISH search\PhraseScorer.java +DONE ISH search\DisjunctionSumScorer.java +DONE ISH search\ComplexExplanation.java +DONE BEN search\HitQueue.java - no changes +DONE BEN search\Weight.java +DONE BEN search\TopDocs.java +DONE ISH search\PrefixQuery.java +DONE BEN search\RangeQuery.java +DONE ISH search\ScoreDocComparator.java +DONE ISH search\Scorer.java +DONE BEN search\Searcher.java - no changes +DONE BEN search\SortComparator.java +DONE BEN search\SortComparatorSource.java +DONE BEN search\TopFieldDocs.java - no changes +DONE BEN search\WildcardQuery.java +DONE BEN search\WildcardTermEnum.java - no changes +DONE ISH search\BooleanClause.java - Should we change the flags in Occur to be named with an OCCUR_ prefix, since they're being used as BooleanClause::SHOULD all throughout the code? +BEN DONE search\PrefixFilter.java - all done +BEN DONE search\SortField.java +BEN DONE search\Sort.java +BEN DONE search\TermScorer.java +DONE ISH search\Explanation.java - Why can't we use TCHAR* for description? +DONE ISH search\ScoreDoc.java - Implemented. Java Lucene has a constructor for it, we don't. +DONE ISH search\HitCollector.java - No changes, abstract class + + +IRRELEVANT analysis\PorterStemFilter.java - deprecated +IRRELEVANT analysis\PorterStemmer.java - deprecated +DONE ISH analysis\WhitespaceAnalyzer.java +DONE ISH analysis\PerFieldAnalyzerWrapper.java - toString() not yet implemented +DONE ISH analysis\LengthFilter.java +DONE ISH analysis\KeywordAnalyzer.java +DONE ISH analysis\SimpleAnalyzer.java +DONE ISH analysis\Tokenizer.java -- Should we delete input on destructor and close? perhaps allow this through an optional parameter? + +DONE ISH store\IndexInput.java - Clone method implemented as constructor only +IRRELEVANT store\AlreadyClosedException.java - Using CL_ERR_IllegalState for this +DONE JW store\Directory.java +DONE JW store\FSDirectory.java +DONE JW store\NoLockFactory.java +DONE JW store\RAMDirectory.java +DONE JW store\RAMFile.java +DONE JW store\RAMInputStream.java +DONE JW store\RAMOutputStream.java +DONE ISH store\IndexOutput.java +DONE JW store\Lock.java +DONE JW store\LockFactory.java +IRRELEVANT store\LockObtainFailedException.java +IRRELEVANT store\LockReleaseFailedException.java +IRRELEVANT store\MMapDirectory.java +DONE JW store\SingleInstanceLockFactory.java +DONE ISH store\BufferedIndexInput.java +DONE ISH store\BufferedIndexOutput.java +DONE ISH document\AbstractField.java - Merged into Field +DEPRECATED document\DateField.java + +DONE BEN util\BitVector.java +DONE BEN util\Constants.java +DONE BEN util\Parameter.java +DONE BEN util\SmallFloat.java +DONE BEN util\StringHelper.java +DONE ISH util\ToStringUtils.java +DONE JW util\PriorityQueue.java + +Update jstreams from latest code of Strigi: strigi isn't really used anymore... we can link to it as necessary... +Create an auxiliary namespace with all the platform-dependant code, to enable static linking to it by contrib, tests and other apps which might need this: that's what the clucene-shared lib is +update Internal* internal to be named otherwise (internal is a preserved word in VS; perhaps ChesireCat* chesCat?)? renamed to _internal diff --git a/src/core/libclucene-core.pc.cmake b/src/core/libclucene-core.pc.cmake new file mode 100644 index 00000000000..0152b258053 --- /dev/null +++ b/src/core/libclucene-core.pc.cmake @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix}/bin +libdir=${prefix}/@LIB_DESTINATION@ +includedir=${prefix}/include:${prefix}/include/CLucene/ext + +Name: libclucene +Description: CLucene - a C++ search engine, ported from the popular Apache Lucene +Version: @CLUCENE_VERSION_MAJOR@.@CLUCENE_VERSION_MINOR@.@CLUCENE_VERSION_REVISION@.@CLUCENE_VERSION_PATCH@ +Libs: -L${prefix}/@LIB_DESTINATION@/ -lclucene-core +Cflags: -I${prefix}/include -I${prefix}/include/CLucene/ext +~ diff --git a/src/core/vp4.h b/src/core/vp4.h new file mode 100644 index 00000000000..fae28df8d45 --- /dev/null +++ b/src/core/vp4.h @@ -0,0 +1,355 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "TurboPFor: Integer Compression" PFor/PForDelta + Direct access +#ifndef VP4_H_ +#define VP4_H_ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif +//************************************************ High level API - n unlimited **************************************************** +// Compress integer array with n values to the buffer out. +// Return value = number of bytes written to compressed buffer out +size_t p4nenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); // SIMD (Vertical bitpacking) +size_t p4nenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc128v64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc256w32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + + +size_t p4ndenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t p4nd1enc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc256v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t p4nzenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +// Decompress the compressed n values in input buffer in to the integer array out. +// Return value = number of bytes read from the ompressed buffer in +size_t p4ndec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4ndec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4ndec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4ndec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t p4ndec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4ndec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4ndec128v64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t p4ndec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +// Delta minimum = 0 +size_t p4nddec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nddec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nddec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nddec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec256w32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +// Delta minimum = 1 +size_t p4nd1dec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nd1dec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nd1dec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nd1dec128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +//Zigzag +size_t p4nzdec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nzdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nzdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nzdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); + +//************** Low level API - n limited to 128/256 *************************************** +#define P4D_MAX 256 + +// -------------- TurboPFor: Encode ------------ +//#include +// Low level API: Single block n limited +//compress integer array with n values to the buffer out. Return value = end of compressed buffer out +unsigned char *p4enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); // SSE (Vertical bitpacking) +unsigned char *p4enc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc128v64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); // AVX2 +unsigned char *p4enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4enc256w32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4encx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out);// Direct access +unsigned char *p4encx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4encx32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4encx64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4denc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4denc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4denc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4denc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4denc256w32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4dencx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); // Direct access +unsigned char *p4dencx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4dencx32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4d1enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4d1enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4d1enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc128v16(uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); // SIMD (Vertical bitpacking) +unsigned char *p4d1enc128v32(uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc256v32(uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4d1encx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); // Direct access +unsigned char *p4d1encx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4d1encx32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4zenc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4zenc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4zenc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4zenc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4senc16(uint16_t *in, unsigned n, unsigned char *out, uint16_t start); +unsigned char *p4senc32(uint32_t *in, unsigned n, unsigned char *out, uint32_t start); +unsigned char *p4senc64(uint64_t *in, unsigned n, unsigned char *out, uint64_t start); + +unsigned char *p4sdec16(unsigned char *in, unsigned n, uint16_t *out, uint16_t start); +unsigned char *p4sdec32(unsigned char *in, unsigned n, uint32_t *out, uint32_t start); +unsigned char *p4sdec64(unsigned char *in, unsigned n, uint64_t *out, uint64_t start); + +size_t p4nsenc16(uint16_t *in, size_t n, unsigned char *out); +size_t p4nsenc32(uint32_t *in, size_t n, unsigned char *out); +size_t p4nsenc64(uint64_t *in, size_t n, unsigned char *out); + +size_t p4nsdec16(unsigned char *in, size_t n, uint16_t *out); +size_t p4nsdec32(unsigned char *in, size_t n, uint32_t *out); +size_t p4nsdec64(unsigned char *in, size_t n, uint64_t *out); + +// same as p4enc, but with b and bx as parameters. Call after _p4bitsXX +inline unsigned char *_p4enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc128v64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +// calculate the best bit sizes b and bx, return b. +unsigned _p4bits8( uint8_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits16( uint16_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits32( uint32_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits64( uint64_t *__restrict in, unsigned n, unsigned *pbx); + +unsigned _p4bitsx8( uint8_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx16( uint16_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx32( uint32_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx64( uint64_t *__restrict in, unsigned n, unsigned *pbx); + +#define P4HVE(_out_, _b_, _bx_,_usize_) do { if(!_bx_) *_out_++ = _b_;else if(_bx_ <= _usize_) *_out_++ = 0x80|_b_, *_out_++ = _bx_; else *_out_++= (_bx_ == _usize_+1?0x40:0xc0)|_b_; } while(0) + +#define P4HVE8( _out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_, 8) +#define P4HVE16(_out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_,16) +#define P4HVE32(_out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_,32) +#define P4HVE64(_out_, _b_, _bx_) do { unsigned _c = _b_==64?64-1:_b_; P4HVE(_out_, _c, _bx_,64); } while(0) + +//---------------------------- TurboPFor: Decode -------------------------------------------------------- +// decompress a previously (with p4enc32) bit packed array. Return value = end of packed buffer in +//-- scalar. (see p4getx32 for direct access) +// b and bx specified (not stored within the compressed stream header) +inline unsigned char *_p4dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical BitPacking) +inline unsigned char *_p4dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec128v64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b, unsigned bx); + +unsigned char *p4dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out); +unsigned char *p4dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out); +unsigned char *p4dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out); // SIMD (Vertical BitPacking) +unsigned char *p4dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec128v64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out); +unsigned char *p4dec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out); +//------ Delta decoding --------------------------- Return value = end of packed input buffer in --------------------------- +//-- Increasing integer lists. out[i] = out[i-1] + in[i] +// b and bx specified +unsigned char *_p4ddec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4ddec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4ddec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4ddec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4ddec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//-- Strictly increasing (never remaining constant or decreasing) integer lists. out[i] = out[i-1] + in[i] + 1 +// b and bx specified (see idxcr.c/idxqry.c for an example) +unsigned char *_p4d1dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec128v16(unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); // SIMD (Vertical BitPacking) +unsigned char *_p4d1dec128v32(unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec256v32(unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4d1dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4d1dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4d1dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4d1dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +// ZigZag encoding +inline unsigned char *_p4zdec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4zdec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4zdec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4zdec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4zdec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//---------------- Direct Access functions to compressed TurboPFor array p4encx16/p4encx32 ------------------------------------------------------- + #ifdef TURBOPFOR_DAC +#include "conf.h" +#define P4D_PAD8(_x_) ( (((_x_)+8-1)/8) ) +#define P4D_B(_x_) ((_x_) & 0x7f) +#define P4D_XB(_x_) (((_x_) & 0x80)?((_x_) >> 8):0) +#define P4D_ININC(_in_, _x_) _in_ += 1+((_x_) >> 7) + +static inline unsigned p4bits(unsigned char *__restrict in, int *bx) { unsigned i = ctou16(in); *bx = P4D_XB(i); return P4D_B(i); } + +struct p4 { + unsigned long long *xmap; + unsigned char *ex; + unsigned isx,bx,cum[P4D_MAX/64+1]; + int oval,idx; +}; + +static unsigned long long p4xmap[P4D_MAX/64+1] = { 0 }; + +// prepare direct access usage +static inline void p4ini(struct p4 *p4, unsigned char **pin, unsigned n, unsigned *b) { unsigned char *in = *pin; + unsigned p4i = ctou16(in); + p4->isx = p4i&0x80; + *b = P4D_B(p4i); + p4->bx = P4D_XB(p4i); //printf("p4i=%x,b=%d,bx=%d ", p4->i, *b, p4->bx); //assert(n <= P4D_MAX); + *pin = p4->ex = ++in; + if(p4->isx) { + unsigned num=0,j; + unsigned char *p; + ++in; + p4->xmap = (unsigned long long *)in; + for(j=0; j < n/64; j++) { p4->cum[j] = num; num += popcnt64(ctou64(in+j*8)); } + if(n & 0x3f) num += popcnt64(ctou64(in+j*8) & ((1ull<<(n&0x3f))-1) ); + p4->ex = p = in + (n+7)/8; + *pin = p = p4->ex+(((uint64_t)num*p4->bx+7)/8); + } else p4->xmap = p4xmap; + p4->oval = p4->idx = -1; +} + +//---------- Get a single value with index "idx" from a "p4encx32" packed array +static ALWAYS_INLINE uint8_t p4getx8( struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx8( in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx8(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} + +static ALWAYS_INLINE uint16_t p4getx16(struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx16(in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx16(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} +static ALWAYS_INLINE uint32_t p4getx32(struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx32(in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx32(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} + +// Get the next single value greater of equal to val +static ALWAYS_INLINE uint16_t p4geqx8( struct p4 *p4, unsigned char *in, unsigned b, uint8_t val) { do p4->oval += p4getx8( p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } +static ALWAYS_INLINE uint16_t p4geqx16(struct p4 *p4, unsigned char *in, unsigned b, uint16_t val) { do p4->oval += p4getx16(p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } +static ALWAYS_INLINE uint32_t p4geqx32(struct p4 *p4, unsigned char *in, unsigned b, uint32_t val) { do p4->oval += p4getx32(p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } + +/* DO NOT USE : like p4dec32 but using direct access. This is only a demo showing direct access usage. Use p4dec32 instead for decompressing entire blocks */ +unsigned char *p4decx32( unsigned char *in, unsigned n, uint32_t *out); // unsorted +unsigned char *p4fdecx32( unsigned char *in, unsigned n, uint32_t *out, uint32_t start); // FOR increasing +unsigned char *p4f1decx32( unsigned char *in, unsigned n, uint32_t *out, uint32_t start); // FOR strictly increasing + #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt new file mode 100644 index 00000000000..440eab49281 --- /dev/null +++ b/src/demo/CMakeLists.txt @@ -0,0 +1,44 @@ +PROJECT(cl_demo) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${clucene_SOURCE_DIR}/cmake" "${clucene-shared_SOURCE_DIR}/cmake") + +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS}) + +INCLUDE_DIRECTORIES( ${clucene-demo_SOURCE_DIR} ) +INCLUDE_DIRECTORIES( ${clucene_SOURCE_DIR}/src/core ) + +file(GLOB_RECURSE demo_HEADERS ${CMAKE_SOURCE_DIR}/test/*.h) + +ADD_EXECUTABLE(cl_demo EXCLUDE_FROM_ALL +#./DeleteFiles.cpp +./IndexFiles.cpp +./Main.cpp +./SearchFiles.cpp +./Statistics.cpp +${clucene-shared_SOURCE_DIR}/CLucene/util/Misc.cpp +${clucene-shared_SOURCE_DIR}/CLucene/util/dirent.cpp +${demo_HEADERS} +) + +ADD_EXECUTABLE(cl_demo_index EXCLUDE_FROM_ALL + #./DeleteFiles.cpp + ./IndexFiles.cpp + ./Main_Index.cpp + #./SearchFiles.cpp + ./Statistics.cpp + ${clucene-shared_SOURCE_DIR}/CLucene/util/Misc.cpp + ${clucene-shared_SOURCE_DIR}/CLucene/util/dirent.cpp + ${demo_HEADERS} + ) + +#ADD_EXECUTABLE(cl_demo EXCLUDE_FROM_ALL +#./TestAnalyzer.cpp +#${demo_HEADERS} +#) +#add_library(ic STATIC IMPORTED) + +#set_target_properties(ic PROPERTIES IMPORTED_LOCATION "${clucene-ext_SOURCE_DIR}/for/libic.a") + +TARGET_LINK_LIBRARIES(cl_demo clucene-core-static clucene-shared-static zstd ic ${EXTRA_LIBS}) +TARGET_LINK_LIBRARIES(cl_demo_index clucene-core-static clucene-shared-static zstd ic ${EXTRA_LIBS}) diff --git a/src/demo/DeleteFiles.cpp b/src/demo/DeleteFiles.cpp new file mode 100644 index 00000000000..9a9036fd9dd --- /dev/null +++ b/src/demo/DeleteFiles.cpp @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "stdafx.h" + +#include "CLucene.h" +#include + +using namespace std; +using namespace lucene::index; +using namespace lucene::util; +using namespace lucene::store; +using namespace lucene::document; + +void DeleteFiles(const char* dir) { + IndexReader* reader = IndexReader::open(dir); + + int32_t count = 0; + for (int32_t i = 0; i < reader->maxDoc(); i++){ + reader->deleteDocument (i); + count ++; + } + printf("Deleted %d files\n", count); + reader->close(); + _CLDELETE(reader); + + //OPTIMIZE + if ( IndexReader::indexExists(dir) ){ + lucene::analysis::SimpleAnalyzer an; + if ( IndexReader::isLocked(dir) ){ + printf("Index was locked... unlocking it.\n"); + IndexReader::unlock(dir); + } + + IndexWriter* writer = _CLNEW IndexWriter( dir, &an, false); + writer->optimize(); + _CLDELETE(writer); + } +} diff --git a/src/demo/IndexFiles.cpp b/src/demo/IndexFiles.cpp new file mode 100644 index 00000000000..3934f217c05 --- /dev/null +++ b/src/demo/IndexFiles.cpp @@ -0,0 +1,207 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/config/repl_tchar.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/util/Misc.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/dirent.h" +#include "CLucene/index/SDocumentWriter.h" + +using namespace std; +using namespace lucene::index; +using namespace lucene::analysis; +using namespace lucene::util; +using namespace lucene::store; +using namespace lucene::document; + +void FileSDocument(IndexWriter *writer, const char *f, Document *doc) { + ifstream file1(f); + string stuff; + + int i = 0; + Document doc1; + SimpleAnalyzer sanalyzer; + auto stringReader = _CLNEW lucene::util::SStringReader; + //auto stream = sanalyzer.reusableTokenStream(_T("log"), stringReader); + auto field = _CLNEW Field(_T("log"), Field::INDEX_TOKENIZED | Field::STORE_NO); + doc1.add(*field); + + //field->setValue(stream); + + while (getline(file1, stuff, '\n')) { + i++; + stringReader->init( + stuff.c_str(), stuff.length(), false); + //auto stringReader = _CLNEW lucene::util::SStringReader( + // stuff.c_str(), stuff.length(), false); + auto stream = sanalyzer.reusableTokenStream(_T("log"), stringReader); + + //auto field = _CLNEW Field(_T("log"), Field::INDEX_TOKENIZED | Field::STORE_NO); + //doc1.add(*field); + + field->setValue(stream); + writer->addDocument(&doc1, &sanalyzer); + //doc1.clear(); + } + + file1.close(); +} +void FileDocument(IndexWriter *writer, const char *f, Document *doc) { + ifstream file1(f); + string stuff; + TCHAR tbuf[1024100]; + + int i = 0; + Document doc1; + + while (getline(file1, stuff, '\n')) { + i++; + //std::cout << stuff <addDocument(&doc1); + doc1.clear(); + } + /*FILE* fh = fopen(f,"r"); + if ( fh != NULL ){ + StringBuffer str; + char abuf[1024]; + TCHAR tbuf[1024]; + size_t r; + do{ + r = fread(abuf,1,1023,fh); + abuf[r]=0; + STRCPY_AtoT(tbuf,abuf,r); + tbuf[r]=0; + str.append(tbuf); + }while(r>0); + fclose(fh); + + doc->add( *_CLNEW Field(_T("log"), str.getBuffer(), Field::STORE_NO | Field::INDEX_TOKENIZED) ); + }*/ + file1.close(); + /* + // Add the path of the file as a field named "path". Use an indexed and stored field, so + // that the index stores the path, and so that the path is searchable. + TCHAR tf[CL_MAX_DIR]; + STRCPY_AtoT(tf,f,CL_MAX_DIR); + doc->add( *_CLNEW Field(_T("path"), tf, Field::STORE_YES | Field::INDEX_UNTOKENIZED ) ); + + // Add the last modified date of the file a field named "modified". Again, we make it + // searchable, but no attempt is made to tokenize the field into words. + //doc->add( *_CLNEW Field(_T("modified"), DateTools::timeToString(f->lastModified()), Field::STORE_YES | Field::INDEX_NO)); + + // Add the contents of the file a field named "contents". This time we use a tokenized + // field so that the text can be searched for words in it. + + // Here we read the data without any encoding. If you want to use special encoding + // see the contrib/jstreams - they contain various types of stream readers + FILE* fh = fopen(f,"r"); + if ( fh != NULL ){ + StringBuffer str; + char abuf[1024]; + TCHAR tbuf[1024]; + size_t r; + do{ + r = fread(abuf,1,1023,fh); + abuf[r]=0; + STRCPY_AtoT(tbuf,abuf,r); + tbuf[r]=0; + str.append(tbuf); + }while(r>0); + fclose(fh); + + doc->add( *_CLNEW Field(_T("contents"), str.getBuffer(), Field::STORE_NO | Field::INDEX_TOKENIZED) ); + } + */ +} + +void indexDocs(IndexWriter *writer, const char *directory) { + vector files; + std::sort(files.begin(), files.end()); + Misc::listFiles(directory, files, true); + vector::iterator itr = files.begin(); + + // Re-use the document object + Document doc; + int i = 0; + while (itr != files.end()) { + const char *path = itr->c_str(); + printf("adding file %d: %s\n", ++i, path); + + //doc.clear(); + FileDocument(writer,path, &doc); + //FileSDocument(writer, path, &doc); + //writer->addDocument(&doc); + ++itr; + } +} + +void IndexFiles(const char *path, const char *target, const bool clearIndex) { + IndexWriter *writer = NULL; + //standard::StandardAnalyzer an; + //lucene::analysis::WhitespaceAnalyzer an; + SimpleAnalyzer an; + + + if (!clearIndex && IndexReader::indexExists(target)) { + if (IndexReader::isLocked(target)) { + printf("Index was locked... unlocking it.\n"); + IndexReader::unlock(target); + } + + writer = _CLNEW IndexWriter(target, &an, false); + } else { + writer = _CLNEW IndexWriter(target, &an, true); + } + + //writer->setInfoStream(&std::cout); + + // We can tell the writer to flush at certain occasions + writer->setRAMBufferSizeMB(500); + writer->setMaxBufferedDocs(0x7FFFFFFFL); + writer->setMaxMergeDocs(0x7FFFFFFFL); + writer->setMergeFactor(0x7FFFFFFFL); + + // To bypass a possible exception (we have no idea what we will be indexing...) + writer->setMaxFieldLength(0x7FFFFFFFL);// LUCENE_INT32_MAX_SHOULDBE + + // Turn this off to make indexing faster; we'll turn it on later before optimizing + writer->setUseCompoundFile(false); + + uint64_t str = Misc::currentTimeMillis(); + + indexDocs(writer, path); + + // Make the index use as little files as possible, and optimize it + //writer->setUseCompoundFile(true); + //writer->optimize(); + + // Close and clean up + writer->close(); + _CLLDELETE(writer); + + printf("Indexing took: %d ms.\n\n", (int32_t) (Misc::currentTimeMillis() - str)); +} diff --git a/src/demo/Main.cpp b/src/demo/Main.cpp new file mode 100644 index 00000000000..48f177356ed --- /dev/null +++ b/src/demo/Main.cpp @@ -0,0 +1,87 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/util/Misc.h" + +//test for memory leaks: +#ifdef _MSC_VER +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif +#endif + +#include +#include +#include +#include + +using namespace std; +using namespace lucene::util; +using namespace lucene::index; + +//void DeleteFiles(const char* dir); +//void IndexFiles(const char *path, const char *target, const bool clearIndex); + +void SearchFiles(const char *index, int &total); + +void getStats(const char *directory); + +int main(int32_t argc, char **argv) { + //Dumper Debug +#ifdef _MSC_VER +#ifdef _DEBUG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF); + _crtBreakAlloc = -1; +#endif +#endif + uint64_t str = Misc::currentTimeMillis(); + try { + printf("Location of files indexed: "); + char ndx[250] = ""; + + char *tmp = fgets(ndx, 250, stdin); + if (tmp == NULL) return 1; + ndx[strlen(ndx) - 1] = 0; + + vector files; + std::sort(files.begin(), files.end()); + Misc::listDirs(ndx, files, true); + auto itr = files.begin(); + str = Misc::currentTimeMillis(); + int total = 0; + while (itr != files.end()) { + //printf("\n%s:%d\n", itr->c_str(), IndexReader::indexExists(itr->c_str())); + + if (!IndexReader::indexExists(itr->c_str())) { + printf("\n%s:%d\n", itr->c_str(), IndexReader::indexExists(itr->c_str())); + itr++; + continue; + } + getStats(itr->c_str()); + SearchFiles(itr->c_str(), total); + itr++; + } + if (total >= 0) { + printf("term was found %d docIDs in files\n", total); + } + + } catch (CLuceneError &err) { + printf("Error: %s\n", err.what()); + } catch (...) { + printf("Unknown error\n"); + } + + _lucene_shutdown();//clears all static memory + + printf("\n\nTime taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + return 0; +} diff --git a/src/demo/Main_Index.cpp b/src/demo/Main_Index.cpp new file mode 100644 index 00000000000..918b6aabc55 --- /dev/null +++ b/src/demo/Main_Index.cpp @@ -0,0 +1,79 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/util/Misc.h" + +//test for memory leaks: +#ifdef _MSC_VER +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#endif +#endif + +#include +#include +#include + +using namespace std; +using namespace lucene::util; + +//void DeleteFiles(const char* dir); +void IndexFiles(const char* path, const char* target, const bool clearIndex); +void SearchFiles(const char* index); +void getStats(const char* directory); + +int main( int32_t argc, char** argv ){ + //Dumper Debug + #ifdef _MSC_VER + #ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF ); + _crtBreakAlloc=-1; + #endif + #endif + + uint64_t str = Misc::currentTimeMillis(); + try{ + + printf("Location of text files to be indexed: "); + char files[250]; + char* tmp = fgets(files,250,stdin); + if ( tmp == NULL ) return 1; + files[strlen(files)-1] = 0; + + printf("Location to store the clucene index: "); + char ndx[250]; + tmp = fgets(ndx,250,stdin); + if ( tmp == NULL ) return 1; + ndx[strlen(ndx)-1] = 0; + + IndexFiles(files,ndx,true); + //getStats(ndx); + //SearchFiles(ndx); + //DeleteFiles(ndx); + + }catch(CLuceneError& err){ + printf("Error: %s\n", err.what()); + }catch(...){ + printf("Unknown error\n"); + } + + _lucene_shutdown(); //clears all static memory + //print lucenebase debug + + //Debugging techniques: + //For msvc, use this for breaking on memory leaks: + // _crtBreakAlloc + //for linux, use valgrind + + printf ("\n\nTime taken: %d\n\n", (int32_t)(Misc::currentTimeMillis() - str)); + return 0; +} diff --git a/src/demo/README b/src/demo/README new file mode 100644 index 00000000000..38775baaa92 --- /dev/null +++ b/src/demo/README @@ -0,0 +1,2 @@ +A small demonstration program similar to the lucene demo program, except +that it runs index,search and delete it one go. diff --git a/src/demo/SearchFiles.cpp b/src/demo/SearchFiles.cpp new file mode 100644 index 00000000000..e5319aaca9d --- /dev/null +++ b/src/demo/SearchFiles.cpp @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include +#include +#include + +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/config/repl_tchar.h" +#include "CLucene/config/repl_wchar.h" +#include "CLucene/util/Misc.h" + +using namespace std; +using namespace lucene::analysis; +using namespace lucene::index; +using namespace lucene::util; +using namespace lucene::queryParser; +using namespace lucene::document; +using namespace lucene::search; + +void clearTermSet(TermSet &termSet) { + for (auto pTerm: termSet) { + _CLLDECDELETE(pTerm); + } + termSet.clear(); +} + +std::vector simple_analyzer(const std::wstring& field_name, const std::wstring& value) { + lucene::analysis::SimpleAnalyzer analyzer; + std::vector analyse_result; + + auto reader = + _CLNEW lucene::util::StringReader(value.c_str()); + auto token_stream = + analyzer.tokenStream(field_name.c_str(), reader); + + lucene::analysis::Token token; + while (token_stream->next(&token)) { + std::wstring tk(token.termBuffer(), token.termLength()); + analyse_result.emplace_back(tk); + } + + if (token_stream != nullptr) { + token_stream->close(); + } + std::set unrepeated_result(analyse_result.begin(), analyse_result.end()); + analyse_result.assign(unrepeated_result.begin(), unrepeated_result.end()); + return analyse_result; +} + +void SearchFiles(const char *index, int &total) { + standard::StandardAnalyzer analyzer; + + IndexReader *reader = IndexReader::open(index); + + IndexReader *newreader = reader->reopen(); + if (newreader != reader) { + _CLLDELETE(reader); + reader = newreader; + } + IndexSearcher s(reader); + + std::wstring field_ws = L"request"; + std::wstring token_wss = L"GET /english/frntpage.htm HTTP/1.0"; + auto q = _CLNEW lucene::search::BooleanQuery(); + auto tokens = simple_analyzer(field_ws, token_wss); + for (auto token_ws: tokens) + { + lucene::index::Term *term = + _CLNEW lucene::index::Term(field_ws.c_str(), token_ws.c_str()); + static_cast(q) + ->add(_CLNEW lucene::search::TermQuery(term), true, + lucene::search::BooleanClause::MUST); + _CLDECDELETE(term); + } + + + uint64_t str = Misc::currentTimeMillis(); + + std::vector result; + s._search(q, + [&result, &total](const int32_t docid, const float_t /*score*/) { + // docid equal to rowid in segment + result.push_back(docid); + printf("docid is %d\n", docid); + total += 1; + }); + _CLLDELETE(q); + + s.close(); + reader->close(); + _CLLDELETE(reader); + printf("\nFile %s search time taken: %d ms\n\n", index,(int32_t) (Misc::currentTimeMillis() - str)); +} diff --git a/src/demo/Statistics.cpp b/src/demo/Statistics.cpp new file mode 100644 index 00000000000..e53f5bda78f --- /dev/null +++ b/src/demo/Statistics.cpp @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include +#include + +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/config/repl_tchar.h" +#include "CLucene/config/repl_wchar.h" +#include "CLucene/util/Misc.h" + +using namespace std; +using namespace lucene::analysis; +using namespace lucene::index; +using namespace lucene::util; +using namespace lucene::search; + +void getStats(const char* directory){ + + IndexReader* r = IndexReader::open(directory); + printf("Statistics for %s\n", directory); + printf("==================================\n"); + + printf("Max Docs: %d\n", r->maxDoc() ); + printf("Num Docs: %d\n", r->numDocs() ); + + int64_t ver = r->getCurrentVersion(directory); + _tprintf(_T("Current Version: %f\n"), (float_t)ver ); + + TermEnum* te = r->terms(); + int32_t nterms; + for (nterms = 0; te->next() == true; nterms++) { + /* empty */ + //printf("term %ls freq %d\n",te->term()->text(), te->docFreq()); + } + printf("Term count: %d\n\n", nterms ); + _CLLDELETE(te); + + r->close(); + _CLLDELETE(r); +} diff --git a/src/demo/TestAnalyzer.cpp b/src/demo/TestAnalyzer.cpp new file mode 100644 index 00000000000..3b01ce1bde8 --- /dev/null +++ b/src/demo/TestAnalyzer.cpp @@ -0,0 +1,83 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include +#include + +#include "CLucene/StdHeader.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene.h" +#include "CLucene/util/Misc.h" + +using namespace lucene::analysis; + +//test for memory leaks: +#ifdef _MSC_VER +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#endif +#endif + +#include +#include +#include + +using namespace std; +using namespace lucene::util; + + +int main( int32_t argc, char** argv ){ + + std::ifstream ifs("test.txt", std::ios::binary | std::ios::in); + if (!ifs.good()) { + std::cerr << "Failed to open " << std::endl; + return -1; + } + + int64_t begin = Misc::currentTimeMillis(); + + std::vector lines; + std::string line; + while (getline(ifs, line)) { + std::wstring wstr(line.begin(), line.end()); + lines.push_back(wstr); + } + +// int64_t begin = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + + standard::StandardAnalyzer analyzer; + + size_t n_lines = 0; + size_t n_words = 0; + for (vector::iterator iter = lines.begin(); iter != lines.end(); ++iter) { + n_lines++; + Reader* reader = new StringReader((*iter).c_str(), (*iter).size()); + TokenStream* tokenStream = analyzer.tokenStream(L"text", reader); + tokenStream->reset(); + Token token; + while (tokenStream->next(&token)) + { + n_words++; + //std::cout << token.termText() << "|"; + } + //std::cout << std::endl; + } + +// int64_t end = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + int64_t end = Misc::currentTimeMillis(); + + std::cout << "begin = " << begin << std::endl; + std::cout << "end = " << end << std::endl; + std::cout << "time = " << end - begin << std::endl; + std::cout << "n_lines = " << n_lines << " n_words = " << n_words << std::endl; + std::cout << "---------------------------" << std::endl; + + return 0; + +} diff --git a/src/ext/CMakeLists.txt b/src/ext/CMakeLists.txt new file mode 100644 index 00000000000..0ab402ec2ce --- /dev/null +++ b/src/ext/CMakeLists.txt @@ -0,0 +1,15 @@ +PROJECT(clucene-ext) + +file(GLOB_RECURSE EXTHEADERS ${clucene-ext_SOURCE_DIR}/boost/*.hpp) + +#install public headers. +FOREACH(file ${EXTHEADERS}) + get_filename_component(apath ${file} PATH) + get_filename_component(aname ${file} NAME) + file(RELATIVE_PATH relpath ${CMAKE_SOURCE_DIR}/src/ext/boost ${apath}) + + install(FILES ${file} + DESTINATION "include/CLucene/ext/boost/${relpath}" + COMPONENT development) +ENDFOREACH(file) + diff --git a/src/ext/boost/assert.hpp b/src/ext/boost/assert.hpp new file mode 100644 index 00000000000..c227f17b9e9 --- /dev/null +++ b/src/ext/boost/assert.hpp @@ -0,0 +1,50 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/utility/assert.html for documentation. +// + +#undef BOOST_ASSERT + +#if defined(BOOST_DISABLE_ASSERTS) + +# define BOOST_ASSERT(expr) ((void)0) + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) + +#include + +namespace boost +{ + +void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + +} // namespace boost + +#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else +# include // .h to support old libraries w/o - effect is the same +# define BOOST_ASSERT(expr) assert(expr) +#endif + +#undef BOOST_VERIFY + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) + +#endif diff --git a/src/ext/boost/checked_delete.hpp b/src/ext/boost/checked_delete.hpp new file mode 100644 index 00000000000..9bb84e8e1ba --- /dev/null +++ b/src/ext/boost/checked_delete.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED +#define BOOST_CHECKED_DELETE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/checked_delete.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) 2003 Daniel Frey +// Copyright (c) 2003 Howard Hinnant +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/utility/checked_delete.html for documentation. +// + +namespace boost +{ + +// verify that types are complete for increased safety + +template inline void checked_delete(T * x) +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +} + +template inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // boost:: disables ADL + boost::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + boost::checked_array_delete(x); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED diff --git a/src/ext/boost/config.hpp b/src/ext/boost/config.hpp new file mode 100644 index 00000000000..055a27855b1 --- /dev/null +++ b/src/ext/boost/config.hpp @@ -0,0 +1,70 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#endif // BOOST_CONFIG_HPP + + + + + + + + + + + diff --git a/src/ext/boost/config/abi/borland_prefix.hpp b/src/ext/boost/config/abi/borland_prefix.hpp new file mode 100644 index 00000000000..49f42494999 --- /dev/null +++ b/src/ext/boost/config/abi/borland_prefix.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// for C++ Builder the following options effect the ABI: +// +// -b (on or off - effect emum sizes) +// -Vx (on or off - empty members) +// -Ve (on or off - empty base classes) +// -aX (alignment - 5 options). +// -pX (Calling convention - 4 options) +// -VmX (member pointer size and layout - 5 options) +// -VC (on or off, changes name mangling) +// -Vl (on or off, changes struct layout). + +// In addition the following warnings are sufficiently annoying (and +// unfixable) to have them turned off by default: +// +// 8027 - functions containing [for|while] loops are not expanded inline +// 8026 - functions taking class by value arguments are not expanded inline + +#pragma nopushoptwarn +# pragma option push -Vx -Ve -a8 -b -pc -Vmv -VC- -Vl- -w-8027 -w-8026 + + + diff --git a/src/ext/boost/config/abi/borland_suffix.hpp b/src/ext/boost/config/abi/borland_suffix.hpp new file mode 100644 index 00000000000..940535f3819 --- /dev/null +++ b/src/ext/boost/config/abi/borland_suffix.hpp @@ -0,0 +1,12 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# pragma option pop +#pragma nopushoptwarn + + + + + diff --git a/src/ext/boost/config/abi/msvc_prefix.hpp b/src/ext/boost/config/abi/msvc_prefix.hpp new file mode 100644 index 00000000000..97f06cdc0c2 --- /dev/null +++ b/src/ext/boost/config/abi/msvc_prefix.hpp @@ -0,0 +1,22 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// +// Boost binaries are built with the compiler's default ABI settings, +// if the user changes their default alignment in the VS IDE then their +// code will no longer be binary compatible with the bjam built binaries +// unless this header is included to force Boost code into a consistent ABI. +// +// Note that inclusion of this header is only necessary for libraries with +// separate source, header only libraries DO NOT need this as long as all +// translation units are built with the same options. +// +#if defined(_M_X64) +# pragma pack(push,16) +#else +# pragma pack(push,8) +#endif + + diff --git a/src/ext/boost/config/abi/msvc_suffix.hpp b/src/ext/boost/config/abi/msvc_suffix.hpp new file mode 100644 index 00000000000..a64d783eb0f --- /dev/null +++ b/src/ext/boost/config/abi/msvc_suffix.hpp @@ -0,0 +1,8 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#pragma pack(pop) + + diff --git a/src/ext/boost/config/abi_prefix.hpp b/src/ext/boost/config/abi_prefix.hpp new file mode 100644 index 00000000000..3b1347492ca --- /dev/null +++ b/src/ext/boost/config/abi_prefix.hpp @@ -0,0 +1,25 @@ +// abi_prefix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# define BOOST_CONFIG_ABI_PREFIX_HPP +#else +# error double inclusion of header boost/config/abi_prefix.hpp is an error +#endif + +#include + +// this must occur after all other includes and before any code appears: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + diff --git a/src/ext/boost/config/abi_suffix.hpp b/src/ext/boost/config/abi_suffix.hpp new file mode 100644 index 00000000000..939161662ae --- /dev/null +++ b/src/ext/boost/config/abi_suffix.hpp @@ -0,0 +1,27 @@ +// abi_sufffix header -------------------------------------------------------// + +// (c) Copyright John Maddock 2003 + +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +// This header should be #included AFTER code that was preceded by a #include +// . + +#ifndef BOOST_CONFIG_ABI_PREFIX_HPP +# error Header boost/config/abi_suffix.hpp must only be used after boost/config/abi_prefix.hpp +#else +# undef BOOST_CONFIG_ABI_PREFIX_HPP +#endif + +// the suffix header occurs after all of our code: +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif + +#if defined( __BORLANDC__ ) +#pragma nopushoptwarn +#endif + + diff --git a/src/ext/boost/config/auto_link.hpp b/src/ext/boost/config/auto_link.hpp new file mode 100644 index 00000000000..f2eb583f043 --- /dev/null +++ b/src/ext/boost/config/auto_link.hpp @@ -0,0 +1,373 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + "-" + + BOOST_LIB_VERSION + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hiphen: + + s static runtime (dynamic if not present). + d debug build (release if not present). + g debug/diagnostic runtime (release if not present). + p STLPort Build. + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(__BORLANDC__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +// Note: no compilers before 1200 are supported +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // vc6: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1300) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1310) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1400) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1500) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +#elif defined(BOOST_MSVC) && (BOOST_MSVC >= 1600) + + // vc10: +# define BOOST_LIB_TOOLSET "vc100" + +#elif defined(__BORLANDC__) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +#elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +#elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +#elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +#endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLPort debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(__BORLANDC__) + +// +// figure out whether we want the debug builds or not: +// +#if __BORLANDC__ > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLPort-debug form" +#endif + +# ifdef _RTLDLL + +# ifdef BOOST_BORLAND_DEBUG +# define BOOST_LIB_RT_OPT "-d" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# ifdef BOOST_BORLAND_DEBUG +# define BOOST_LIB_RT_OPT "-sd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_VERSION) + +#ifndef BOOST_AUTO_LINK_NOMANGLE +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib") +# endif +#else +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) ".lib") +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif +#if defined(BOOST_AUTO_LINK_NOMANGLE) +# undef BOOST_AUTO_LINK_NOMANGLE +#endif + + + + + + + + + + + diff --git a/src/ext/boost/config/compiler/borland.hpp b/src/ext/boost/config/compiler/borland.hpp new file mode 100644 index 00000000000..6a7b988d166 --- /dev/null +++ b/src/ext/boost/config/compiler/borland.hpp @@ -0,0 +1,267 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Borland C++ compiler setup: + +// +// versions check: +// we don't support Borland prior to version 5.4: +#if __BORLANDC__ < 0x540 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// last known compiler version: +#if (__BORLANDC__ > 0x613) +//# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +//# else +//# pragma message( "Unknown compiler version - please run the configure tests and report the results") +//# endif +#elif (__BORLANDC__ == 0x600) +# error "CBuilderX preview compiler is no longer supported" +#endif + +// +// Support macros to help with standard library detection +#if (__BORLANDC__ < 0x560) || defined(_USE_OLD_RW_STL) +# define BOOST_BCB_WITH_ROGUE_WAVE +#elif __BORLANDC__ < 0x570 +# define BOOST_BCB_WITH_STLPORT +#else +# define BOOST_BCB_WITH_DINKUMWARE +#endif + +// +// Version 5.0 and below: +# if __BORLANDC__ <= 0x0550 +// Borland C++Builder 4 and 5: +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# if __BORLANDC__ == 0x0550 +// Borland C++Builder 5, command-line compiler 5.5: +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif +# endif + +// Version 5.51 and below: +#if (__BORLANDC__ <= 0x551) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_DEDUCED_TYPENAME +// workaround for missing WCHAR_MAX/WCHAR_MIN: +#include +#include +#ifndef WCHAR_MAX +# define WCHAR_MAX 0xffff +#endif +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#endif + +// Borland C++ Builder 6 and below: +#if (__BORLANDC__ <= 0x564) + +# ifdef NDEBUG + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif + +// +// new bug in 5.61: +#if (__BORLANDC__ >= 0x561) && (__BORLANDC__ <= 0x580) + // this seems to be needed by the command line compiler, but not the IDE: +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +// Borland C++ Builder 2006 Update 2 and below: +#if (__BORLANDC__ <= 0x582) +# define BOOST_NO_SFINAE +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# define BOOST_NO_TEMPLATE_TEMPLATES + +# define BOOST_NO_PRIVATE_IN_AGGREGATE + +# ifdef _WIN32 +# define BOOST_NO_SWPRINTF +# elif defined(linux) || defined(__linux__) || defined(__linux) + // we should really be able to do without this + // but the wcs* functions aren't imported into std:: +# define BOOST_NO_STDC_NAMESPACE + // _CPPUNWIND doesn't get automatically set for some reason: +# pragma defineonoption BOOST_CPPUNWIND -x +# endif +#endif + +#if (__BORLANDC__ <= 0x613) // Beman has asked Alisdair for more info + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +# define BOOST_NO_USING_TEMPLATE +# define BOOST_SP_NO_SP_CONVERTIBLE + +// Temporary workaround +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#endif + +// Borland C++ Builder 2008 and below: +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_NO_NESTED_FRIENDSHIP +# define BOOST_NO_TYPENAME_WITH_CTOR +#if (__BORLANDC__ < 0x600) +# define BOOST_ILLEGAL_CV_REFERENCES +#endif + +// +// Positive Feature detection +// +// Borland C++ Builder 2008 and below: +#if (__BORLANDC__ >= 0x599) +# pragma defineonoption BOOST_CODEGEAR_0X_SUPPORT -Ax +#endif +// +// C++0x Macros: +// +#if !defined( BOOST_CODEGEAR_0X_SUPPORT ) || (__BORLANDC__ < 0x610) +# define BOOST_NO_CHAR16_T +# define BOOST_NO_CHAR32_T +# define BOOST_NO_DECLTYPE +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_EXTERN_TEMPLATE +# define BOOST_NO_RVALUE_REFERENCES +# define BOOST_NO_SCOPED_ENUMS +# define BOOST_NO_STATIC_ASSERT +#else +# define BOOST_HAS_ALIGNOF +# define BOOST_HAS_CHAR16_T +# define BOOST_HAS_CHAR32_T +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_EXPLICIT_CONVERSION_OPS +# define BOOST_HAS_REF_QUALIFIER +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +#endif + +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS // UTF-8 still not supported +#define BOOST_NO_VARIADIC_TEMPLATES + +#if __BORLANDC__ >= 0x590 +# define BOOST_HAS_TR1_HASH + +# define BOOST_HAS_MACRO_USE_FACET +#endif + +// +// Post 0x561 we have long long and stdint.h: +#if __BORLANDC__ >= 0x561 +# ifndef __NO_LONG_LONG +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + // On non-Win32 platforms let the platform config figure this out: +# ifdef _WIN32 +# define BOOST_HAS_STDINT_H +# endif +#endif + +// Borland C++Builder 6 defaults to using STLPort. If _USE_OLD_RW_STL is +// defined, then we have 0x560 or greater with the Rogue Wave implementation +// which presumably has the std::DBL_MAX bug. +#if defined( BOOST_BCB_WITH_ROGUE_WAVE ) +// is partly broken, some macros define symbols that are really in +// namespace std, so you end up having to use illegal constructs like +// std::DBL_MAX, as a fix we'll just include float.h and have done with: +#include +#endif +// +// __int64: +// +#if (__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#ifndef __STRICT_ANSI__ +# define BOOST_HAS_DECLSPEC +#endif +// +// ABI fixing headers: +// +#if __BORLANDC__ != 0x600 // not implemented for version 6 compiler yet +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +#endif +// +// Disable Win32 support in ANSI mode: +// +#if __BORLANDC__ < 0x600 +# pragma defineonoption BOOST_DISABLE_WIN32 -A +#elif defined(__STRICT_ANSI__) +# define BOOST_DISABLE_WIN32 +#endif +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) + + + diff --git a/src/ext/boost/config/compiler/codegear.hpp b/src/ext/boost/config/compiler/codegear.hpp new file mode 100644 index 00000000000..698624ece29 --- /dev/null +++ b/src/ext/boost/config/compiler/codegear.hpp @@ -0,0 +1,163 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// CodeGear C++ compiler setup: + +#if !defined( BOOST_WITH_CODEGEAR_WARNINGS ) +// these warnings occur frequently in optimized template code +# pragma warn -8004 // var assigned value, but never used +# pragma warn -8008 // condition always true/false +# pragma warn -8066 // dead code can never execute +# pragma warn -8104 // static members with ctors not threadsafe +# pragma warn -8105 // reference member in class without ctors +#endif +// +// versions check: +// last known and checked version is 0x620 +#if (__CODEGEARC__ > 0x620) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message( "Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + +// CodeGear C++ Builder 2009 +#if (__CODEGEARC__ <= 0x613) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + // we shouldn't really need this - but too many things choke + // without it, this needs more investigation: +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +// CodeGear C++ Builder 2010 +#if (__CODEGEARC__ <= 0x620) +# define BOOST_NO_TYPENAME_WITH_CTOR // Cannot use typename keyword when making temporaries of a dependant type +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_NESTED_FRIENDSHIP // TC1 gives nested classes access rights as any other member +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +// Temporary hack, until specific MPL preprocessed headers are generated +# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS + +# ifdef NDEBUG + // fix broken so that Boost.test works: +# include +# undef strcmp +# endif + // fix broken errno declaration: +# include +# ifndef errno +# define errno errno +# endif + +#endif +// +// C++0x macros: +// +#define BOOST_HAS_CHAR16_T +#define BOOST_HAS_CHAR32_T +#define BOOST_HAS_LONG_LONG +// #define BOOST_HAS_ALIGNOF +#define BOOST_HAS_DECLTYPE +#define BOOST_HAS_EXPLICIT_CONVERSION_OPS +// #define BOOST_HAS_RVALUE_REFS +#define BOOST_HAS_SCOPED_ENUM +// #define BOOST_HAS_STATIC_ASSERT +#define BOOST_HAS_STD_TYPE_TRAITS + +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +// +// TR1 macros: +// +#define BOOST_HAS_TR1_HASH +#define BOOST_HAS_TR1_TYPE_TRAITS +#define BOOST_HAS_TR1_UNORDERED_MAP +#define BOOST_HAS_TR1_UNORDERED_SET + +#define BOOST_HAS_MACRO_USE_FACET + +#define BOOST_NO_INITIALIZER_LISTS + +// On non-Win32 platforms let the platform config figure this out: +#ifdef _WIN32 +# define BOOST_HAS_STDINT_H +#endif + +// +// __int64: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_MS_INT64 +#endif +// +// check for exception handling support: +// +#if !defined(_CPPUNWIND) && !defined(BOOST_CPPUNWIND) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif +// +// all versions have a : +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DIRENT_H +#endif +// +// all versions support __declspec: +// +#if !defined(__STRICT_ANSI__) +# define BOOST_HAS_DECLSPEC +#endif +// +// ABI fixing headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/borland_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/borland_suffix.hpp" +#endif +// +// Disable Win32 support in ANSI mode: +// +# pragma defineonoption BOOST_DISABLE_WIN32 -A +// +// MSVC compatibility mode does some nasty things: +// TODO: look up if this doesn't apply to the whole 12xx range +// +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_VOID_RETURNS +#endif + +#define BOOST_COMPILER "CodeGear C++ version " BOOST_STRINGIZE(__CODEGEARC__) + diff --git a/src/ext/boost/config/compiler/comeau.hpp b/src/ext/boost/config/compiler/comeau.hpp new file mode 100644 index 00000000000..278222dcfdd --- /dev/null +++ b/src/ext/boost/config/compiler/comeau.hpp @@ -0,0 +1,59 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Douglas Gregor 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau C++ compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +#if (__COMO_VERSION__ <= 4245) + +# if defined(_MSC_VER) && _MSC_VER <= 1300 +# if _MSC_VER > 100 + // only set this in non-strict mode: +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# endif +# endif + +// Void returns don't work when emulating VC 6 (Peter Dimov) +// TODO: look up if this doesn't apply to the whole 12xx range +# if defined(_MSC_VER) && (_MSC_VER < 1300) +# define BOOST_NO_VOID_RETURNS +# endif + +#endif // version 4245 + +// +// enable __int64 support in VC emulation mode +// +# if defined(_MSC_VER) && (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +# endif + +#define BOOST_COMPILER "Comeau compiler version " BOOST_STRINGIZE(__COMO_VERSION__) + +// +// versions check: +// we don't know Comeau prior to version 4245: +#if __COMO_VERSION__ < 4245 +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4245: +#if (__COMO_VERSION__ > 4245) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + diff --git a/src/ext/boost/config/compiler/common_edg.hpp b/src/ext/boost/config/compiler/common_edg.hpp new file mode 100644 index 00000000000..9dc4cef8eb5 --- /dev/null +++ b/src/ext/boost/config/compiler/common_edg.hpp @@ -0,0 +1,97 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright Markus Schoepflin 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// +// Options common to all edg based compilers. +// +// This is included from within the individual compiler mini-configs. + +#ifndef __EDG_VERSION__ +# error This file requires that __EDG_VERSION__ be defined. +#endif + +#if (__EDG_VERSION__ <= 238) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_SFINAE +#endif + +#if (__EDG_VERSION__ <= 240) +# define BOOST_NO_VOID_RETURNS +#endif + +#if (__EDG_VERSION__ <= 241) && !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +#endif + +#if (__EDG_VERSION__ <= 244) && !defined(BOOST_NO_TEMPLATE_TEMPLATES) +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (__EDG_VERSION__ < 300) && !defined(BOOST_NO_IS_ABSTRACT) +# define BOOST_NO_IS_ABSTRACT +#endif + +#if (__EDG_VERSION__ <= 303) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// See also kai.hpp which checks a Kai-specific symbol for EH +# if !defined(__KCC) && !defined(__EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +# if !defined(__NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG +// +#if (__EDG_VERSION__ <= 310) || !defined(BOOST_STRICT_CONFIG) +// No support for initializer lists +# define BOOST_NO_INITIALIZER_LISTS +#endif + +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +#ifdef c_plusplus +// EDG has "long long" in non-strict mode +// However, some libraries have insufficient "long long" support +// #define BOOST_HAS_LONG_LONG +#endif + + + diff --git a/src/ext/boost/config/compiler/compaq_cxx.hpp b/src/ext/boost/config/compiler/compaq_cxx.hpp new file mode 100644 index 00000000000..b44486c6739 --- /dev/null +++ b/src/ext/boost/config/compiler/compaq_cxx.hpp @@ -0,0 +1,19 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Tru64 C++ compiler setup (now HP): + +#define BOOST_COMPILER "HP Tru64 C++ " BOOST_STRINGIZE(__DECCXX_VER) + +#include "boost/config/compiler/common_edg.hpp" + +// +// versions check: +// Nothing to do here? + + + diff --git a/src/ext/boost/config/compiler/digitalmars.hpp b/src/ext/boost/config/compiler/digitalmars.hpp new file mode 100644 index 00000000000..a01b4c28ec4 --- /dev/null +++ b/src/ext/boost/config/compiler/digitalmars.hpp @@ -0,0 +1,93 @@ +// Copyright (C) Christof Meerwald 2003 +// Copyright (C) Dan Watkins 2003 +// +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Digital Mars C++ compiler setup: +#define BOOST_COMPILER __DMC_VERSION_STRING__ + +#define BOOST_HAS_LONG_LONG +#define BOOST_HAS_PRAGMA_ONCE + +#if (__DMC__ <= 0x833) +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TEMPLATE_TEMPLATES +#define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING +#define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +#endif +#if (__DMC__ <= 0x840) || !defined(BOOST_STRICT_CONFIG) +#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#define BOOST_NO_OPERATORS_IN_NAMESPACE +#define BOOST_NO_UNREACHABLE_RETURN_DETECTION +#define BOOST_NO_SFINAE +#define BOOST_NO_USING_TEMPLATE +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// has macros: +#if (__DMC__ >= 0x840) +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_STDINT_H +#define BOOST_HAS_WINTHREADS +#endif + +#if (__DMC__ >= 0x847) +#define BOOST_HAS_EXPM1 +#define BOOST_HAS_LOG1P +#endif + +// +// Is this really the best way to detect whether the std lib is in namespace std? +// +#include +#if !defined(__STL_IMPORT_VENDOR_CSTD) && !defined(_STLP_IMPORT_VENDOR_CSTD) +# define BOOST_NO_STDC_NAMESPACE +#endif + + +// check for exception handling support: +#ifndef _CPPUNWIND +# define BOOST_NO_EXCEPTIONS +#endif + +// +// C++0x features +// +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +#if __DMC__ < 0x800 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is ...: +#if (__DMC__ > 0x848) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/src/ext/boost/config/compiler/gcc.hpp b/src/ext/boost/config/compiler/gcc.hpp new file mode 100644 index 00000000000..6cae94cae67 --- /dev/null +++ b/src/ext/boost/config/compiler/gcc.hpp @@ -0,0 +1,204 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GNU C++ compiler setup: + +#if __GNUC__ < 3 +# if __GNUC_MINOR__ == 91 + // egcs 1.1 won't parse shared_ptr.hpp without this: +# define BOOST_NO_AUTO_PTR +# endif +# if __GNUC_MINOR__ < 95 + // + // Prior to gcc 2.95 member templates only partly + // work - define BOOST_MSVC6_MEMBER_TEMPLATES + // instead since inline member templates mostly work. + // +# define BOOST_NO_MEMBER_TEMPLATES +# if __GNUC_MINOR__ >= 9 +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif +# endif + +# if __GNUC_MINOR__ < 96 +# define BOOST_NO_SFINAE +# endif + +# if __GNUC_MINOR__ <= 97 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# endif + +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# define BOOST_NO_IS_ABSTRACT +#elif __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + // + // gcc-3.x problems: + // + // Bug specific to gcc 3.1 and 3.2: + // +# if ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2)) +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# endif +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# ifdef __OPEN64__ +# define BOOST_NO_IS_ABSTRACT +# endif +#endif + +#ifndef __EXCEPTIONS +# define BOOST_NO_EXCEPTIONS +#endif + + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +// +// gcc implements the named return value optimization since version 3.1 +// +#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) +#define BOOST_HAS_NRVO +#endif +// +// RTTI and typeinfo detection is possible post gcc-4.3: +// +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 403 +# ifndef __GXX_RTTI +# define BOOST_NO_TYPEID +# define BOOST_NO_RTTI +# endif +#endif + +// C++0x features not implemented in any GCC version +// +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS + +// C++0x features in 4.3.n and later +// +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_DECLTYPE +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_RVALUE_REFERENCES +# define BOOST_NO_STATIC_ASSERT + +// Variadic templates compiler: +// http://www.generic-programming.org/~dgregor/cpp/variadic-templates.html +# ifdef __VARIADIC_TEMPLATES +# define BOOST_HAS_VARIADIC_TMPL +# else +# define BOOST_NO_VARIADIC_TEMPLATES +# endif +#endif + +// C++0x features in 4.4.n and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_AUTO_DECLARATIONS +# define BOOST_NO_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CHAR16_T +# define BOOST_NO_CHAR32_T +# define BOOST_NO_DEFAULTED_FUNCTIONS +# define BOOST_NO_DELETED_FUNCTIONS +# define BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_SCOPED_ENUMS +#endif + +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4) +# define BOOST_NO_SFINAE_EXPR +#endif + +// C++0x features in 4.4.1 and later +// +#if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40401) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_SCOPED_ENUMS before 4.4.1 +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 +# define BOOST_NO_SCOPED_ENUMS +#endif + +// C++0x features in 4.5.n and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#endif + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#else +# define BOOST_NO_CONCEPTS +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "GNU C++ version " __VERSION__ +#endif + +// +// versions check: +// we don't know gcc prior to version 2.90: +#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 90) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 4.4 (Pre-release): +#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 4)) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/src/ext/boost/config/compiler/gcc_xml.hpp b/src/ext/boost/config/compiler/gcc_xml.hpp new file mode 100644 index 00000000000..5dd67c76040 --- /dev/null +++ b/src/ext/boost/config/compiler/gcc_xml.hpp @@ -0,0 +1,30 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GCC-XML C++ compiler setup: + +# if !defined(__GCCXML_GNUC__) || ((__GCCXML_GNUC__ <= 3) && (__GCCXML_GNUC_MINOR__ <= 3)) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// +#define BOOST_HAS_LONG_LONG + +#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ + + diff --git a/src/ext/boost/config/compiler/greenhills.hpp b/src/ext/boost/config/compiler/greenhills.hpp new file mode 100644 index 00000000000..038b6b2b52e --- /dev/null +++ b/src/ext/boost/config/compiler/greenhills.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Greenhills C++ compiler setup: + +#define BOOST_COMPILER "Greenhills C++ version " BOOST_STRINGIZE(__ghs) + +#include "boost/config/compiler/common_edg.hpp" + +// +// versions check: +// we don't support Greenhills prior to version 0: +#if __ghs < 0 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0: +#if (__ghs > 0) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/src/ext/boost/config/compiler/hp_acc.hpp b/src/ext/boost/config/compiler/hp_acc.hpp new file mode 100644 index 00000000000..98e7772af28 --- /dev/null +++ b/src/ext/boost/config/compiler/hp_acc.hpp @@ -0,0 +1,127 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// HP aCC C++ compiler setup: + +#if defined(__EDG__) +#include "boost/config/compiler/common_edg.hpp" +#endif + +#if (__HP_aCC <= 33100) +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_OPERATORS_IN_NAMESPACE +# if !defined(_NAMESPACE_STD) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +# endif +#endif + +#if (__HP_aCC <= 33300) +// member templates are sufficiently broken that we disable them for now +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE +#endif + +#if (__HP_aCC <= 38000) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if (__HP_aCC > 50000) && (__HP_aCC < 60000) +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SWPRINTF +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +// optional features rather than defects: +#if (__HP_aCC >= 33900) +# define BOOST_HAS_LONG_LONG +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +#if (__HP_aCC >= 50000 ) && (__HP_aCC <= 53800 ) || (__HP_aCC < 31300 ) +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +// This macro should not be defined when compiling in strict ansi +// mode, but, currently, we don't have the ability to determine +// what standard mode we are compiling with. Some future version +// of aCC6 compiler will provide predefined macros reflecting the +// compilation options, including the standard mode. +#if (__HP_aCC >= 60000) || ((__HP_aCC > 38000) && defined(__hpxstd98)) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#define BOOST_COMPILER "HP aCC version " BOOST_STRINGIZE(__HP_aCC) + +// +// versions check: +// we don't support HP aCC prior to version 33000: +#if __HP_aCC < 33000 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// +// Extended checks for supporting aCC on PA-RISC +#if __HP_aCC > 30000 && __HP_aCC < 50000 +# if __HP_aCC < 38000 + // versions prior to version A.03.80 not supported +# error "Compiler version not supported - version A.03.80 or higher is required" +# elif !defined(__hpxstd98) + // must compile using the option +hpxstd98 with version A.03.80 and above +# error "Compiler option '+hpxstd98' is required for proper support" +# endif //PA-RISC +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if !defined(__EDG__) + +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES +#endif + +// +// last known and checked version for HP-UX/ia64 is 61300 +// last known and checked version for PA-RISC is 38000 +#if ((__HP_aCC > 61300) || ((__HP_aCC > 38000) && defined(__hpxstd98))) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/src/ext/boost/config/compiler/intel.hpp b/src/ext/boost/config/compiler/intel.hpp new file mode 100644 index 00000000000..531242e9642 --- /dev/null +++ b/src/ext/boost/config/compiler/intel.hpp @@ -0,0 +1,173 @@ +// (C) Copyright John Maddock 2001-8. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright Guillaume Melquiond 2002 - 2003. +// (C) Copyright Beman Dawes 2003. +// (C) Copyright Martin Wille 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Intel compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +#if defined(__INTEL_COMPILER) +# define BOOST_INTEL_CXX_VERSION __INTEL_COMPILER +#elif defined(__ICL) +# define BOOST_INTEL_CXX_VERSION __ICL +#elif defined(__ICC) +# define BOOST_INTEL_CXX_VERSION __ICC +#elif defined(__ECC) +# define BOOST_INTEL_CXX_VERSION __ECC +#endif + +#define BOOST_COMPILER "Intel C++ version " BOOST_STRINGIZE(BOOST_INTEL_CXX_VERSION) +#define BOOST_INTEL BOOST_INTEL_CXX_VERSION + +#if defined(_WIN32) || defined(_WIN64) +# define BOOST_INTEL_WIN BOOST_INTEL +#else +# define BOOST_INTEL_LINUX BOOST_INTEL +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 500) && defined(_MSC_VER) +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# define BOOST_NO_TEMPLATE_TEMPLATES +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 600) + +# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) + +// Boost libraries assume strong standard conformance unless otherwise +// indicated by a config macro. As configured by Intel, the EDG front-end +// requires certain compiler options be set to achieve that strong conformance. +// Particularly /Qoption,c,--arg_dep_lookup (reported by Kirk Klobe & Thomas Witt) +// and /Zc:wchar_t,forScope. See boost-root/tools/build/intel-win32-tools.jam for +// details as they apply to particular versions of the compiler. When the +// compiler does not predefine a macro indicating if an option has been set, +// this config file simply assumes the option has been set. +// Thus BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP will not be defined, even if +// the compiler option is not enabled. + +# define BOOST_NO_SWPRINTF +# endif + +// Void returns, 64 bit integrals don't work when emulating VC 6 (Peter Dimov) + +# if defined(_MSC_VER) && (_MSC_VER <= 1200) +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +#endif + +#if (BOOST_INTEL_CXX_VERSION <= 710) && defined(_WIN32) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +#endif + +// See http://aspn.activestate.com/ASPN/Mail/Message/boost/1614864 +#if BOOST_INTEL_CXX_VERSION < 600 +# define BOOST_NO_INTRINSIC_WCHAR_T +#else +// We should test the macro _WCHAR_T_DEFINED to check if the compiler +// supports wchar_t natively. *BUT* there is a problem here: the standard +// headers define this macro if they typedef wchar_t. Anyway, we're lucky +// because they define it without a value, while Intel C++ defines it +// to 1. So we can check its value to see if the macro was defined natively +// or not. +// Under UNIX, the situation is exactly the same, but the macro _WCHAR_T +// is used instead. +# if ((_WCHAR_T_DEFINED + 0) == 0) && ((_WCHAR_T + 0) == 0) +# define BOOST_NO_INTRINSIC_WCHAR_T +# endif +#endif + +#if defined(__GNUC__) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +// +// Figure out when Intel is emulating this gcc bug +// (All Intel versions prior to 9.0.26, and versions +// later than that if they are set up to emulate gcc 3.2 +// or earlier): +// +# if ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 2)) || (BOOST_INTEL < 900) || (__INTEL_COMPILER_BUILD_DATE < 20050912) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +# endif +#endif +#if (defined(__GNUC__) && (__GNUC__ < 4)) || defined(_WIN32) || (BOOST_INTEL_CXX_VERSION <= 1110) +// GCC or VC emulation: +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif +// +// Verify that we have actually got BOOST_NO_INTRINSIC_WCHAR_T +// set correctly, if we don't do this now, we will get errors later +// in type_traits code among other things, getting this correct +// for the Intel compiler is actually remarkably fragile and tricky: +// +#if defined(BOOST_NO_INTRINSIC_WCHAR_T) +#include +template< typename T > struct assert_no_intrinsic_wchar_t; +template<> struct assert_no_intrinsic_wchar_t { typedef void type; }; +// if you see an error here then you need to unset BOOST_NO_INTRINSIC_WCHAR_T +// where it is defined above: +typedef assert_no_intrinsic_wchar_t::type assert_no_intrinsic_wchar_t_; +#else +template< typename T > struct assert_intrinsic_wchar_t; +template<> struct assert_intrinsic_wchar_t {}; +// if you see an error here then define BOOST_NO_INTRINSIC_WCHAR_T on the command line: +template<> struct assert_intrinsic_wchar_t {}; +#endif + +#if _MSC_VER+0 >= 1000 +# if _MSC_VER >= 1200 +# define BOOST_HAS_MS_INT64 +# endif +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#elif defined(_WIN32) +# define BOOST_DISABLE_WIN32 +#endif + +// I checked version 6.0 build 020312Z, it implements the NRVO. +// Correct this as you find out which version of the compiler +// implemented the NRVO first. (Daniel Frey) +#if (BOOST_INTEL_CXX_VERSION >= 600) +# define BOOST_HAS_NRVO +#endif + +// +// versions check: +// we don't support Intel prior to version 5.0: +#if BOOST_INTEL_CXX_VERSION < 500 +# error "Compiler not supported or configured - please reconfigure" +#endif + +// Intel on MacOS requires +#if defined(__APPLE__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// Intel on Altix Itanium +#if defined(__itanium__) && defined(__INTEL_COMPILER) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +// +// last known and checked version: +#if (BOOST_INTEL_CXX_VERSION > 1110) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# elif defined(_MSC_VER) +// +// We don't emit this warning any more, since we have so few +// defect macros set anyway (just the one). +// +//# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif + diff --git a/src/ext/boost/config/compiler/kai.hpp b/src/ext/boost/config/compiler/kai.hpp new file mode 100644 index 00000000000..ea06f9f4d06 --- /dev/null +++ b/src/ext/boost/config/compiler/kai.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Kai C++ compiler setup: + +#include "boost/config/compiler/common_edg.hpp" + +# if (__KCC_VERSION <= 4001) || !defined(BOOST_STRICT_CONFIG) + // at least on Sun, the contents of is not in namespace std +# define BOOST_NO_STDC_NAMESPACE +# endif + +// see also common_edg.hpp which needs a special check for __KCC +# if !defined(_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + +// +// last known and checked version is 4001: +#if (__KCC_VERSION > 4001) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + diff --git a/src/ext/boost/config/compiler/metrowerks.hpp b/src/ext/boost/config/compiler/metrowerks.hpp new file mode 100644 index 00000000000..aeba7f805c8 --- /dev/null +++ b/src/ext/boost/config/compiler/metrowerks.hpp @@ -0,0 +1,139 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Stefan Slapeta 2004. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks C++ compiler setup: + +// locale support is disabled when linking with the dynamic runtime +# ifdef _MSL_NO_LOCALE +# define BOOST_NO_STD_LOCALE +# endif + +# if __MWERKS__ <= 0x2301 // 5.3 +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_POINTER_TO_MEMBER_CONST +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# endif + +# if __MWERKS__ <= 0x2401 // 6.2 +//# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if(__MWERKS__ <= 0x2407) // 7.x +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# define BOOST_NO_UNREACHABLE_RETURN_DETECTION +# endif + +# if(__MWERKS__ <= 0x3003) // 8.x +# define BOOST_NO_SFINAE +# endif + +// the "|| !defined(BOOST_STRICT_CONFIG)" part should apply to the last +// tested version *only*: +# if(__MWERKS__ <= 0x3207) || !defined(BOOST_STRICT_CONFIG) // 9.6 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_IS_ABSTRACT +# endif + +#if !__option(wchar_type) +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if !__option(exceptions) +# define BOOST_NO_EXCEPTIONS +#endif + +#if (__INTEL__ && _WIN32) || (__POWERPC__ && macintosh) +# if __MWERKS__ == 0x3000 +# define BOOST_COMPILER_VERSION 8.0 +# elif __MWERKS__ == 0x3001 +# define BOOST_COMPILER_VERSION 8.1 +# elif __MWERKS__ == 0x3002 +# define BOOST_COMPILER_VERSION 8.2 +# elif __MWERKS__ == 0x3003 +# define BOOST_COMPILER_VERSION 8.3 +# elif __MWERKS__ == 0x3200 +# define BOOST_COMPILER_VERSION 9.0 +# elif __MWERKS__ == 0x3201 +# define BOOST_COMPILER_VERSION 9.1 +# elif __MWERKS__ == 0x3202 +# define BOOST_COMPILER_VERSION 9.2 +# elif __MWERKS__ == 0x3204 +# define BOOST_COMPILER_VERSION 9.3 +# elif __MWERKS__ == 0x3205 +# define BOOST_COMPILER_VERSION 9.4 +# elif __MWERKS__ == 0x3206 +# define BOOST_COMPILER_VERSION 9.5 +# elif __MWERKS__ == 0x3207 +# define BOOST_COMPILER_VERSION 9.6 +# else +# define BOOST_COMPILER_VERSION __MWERKS__ +# endif +#else +# define BOOST_COMPILER_VERSION __MWERKS__ +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#if __MWERKS__ > 0x3206 && __option(rvalue_refs) +# define BOOST_HAS_RVALUE_REFS +#else +# define BOOST_NO_RVALUE_REFERENCES +#endif +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Metrowerks prior to version 5.3: +#if __MWERKS__ < 0x2301 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version: +#if (__MWERKS__ > 0x3205) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + + + + + + diff --git a/src/ext/boost/config/compiler/mpw.hpp b/src/ext/boost/config/compiler/mpw.hpp new file mode 100644 index 00000000000..4db14ddef3a --- /dev/null +++ b/src/ext/boost/config/compiler/mpw.hpp @@ -0,0 +1,81 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Aleksey Gurtovoy 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// MPW C++ compilers setup: + +# if defined(__SC__) +# define BOOST_COMPILER "MPW SCpp version " BOOST_STRINGIZE(__SC__) +# elif defined(__MRC__) +# define BOOST_COMPILER "MPW MrCpp version " BOOST_STRINGIZE(__MRC__) +# else +# error "Using MPW compiler configuration by mistake. Please update." +# endif + +// +// MPW 8.90: +// +#if (MPW_CPLUS <= 0x890) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_CV_SPECIALIZATIONS +# define BOOST_NO_DEPENDENT_NESTED_DERIVATIONS +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_USING_TEMPLATE + +# define BOOST_NO_CWCHAR +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + +# define BOOST_NO_STD_ALLOCATOR /* actually a bug with const reference overloading */ + +#endif + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +// +// versions check: +// we don't support MPW prior to version 8.9: +#if MPW_CPLUS < 0x890 +# error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x890: +#if (MPW_CPLUS > 0x890) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + + diff --git a/src/ext/boost/config/compiler/pgi.hpp b/src/ext/boost/config/compiler/pgi.hpp new file mode 100644 index 00000000000..e40553efc04 --- /dev/null +++ b/src/ext/boost/config/compiler/pgi.hpp @@ -0,0 +1,62 @@ +// (C) Copyright Noel Belcourt 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// PGI C++ compiler setup: + +#define BOOST_COMPILER_VERSION __PGIC__##__PGIC_MINOR__ +#define BOOST_COMPILER "PGI compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// + +#if (__PGIC__ >= 7) + +#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_SWPRINTF + +#else + +# error "Pgi compiler not configured - please reconfigure" + +#endif +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +// +// version check: +// probably nothing to do here? + diff --git a/src/ext/boost/config/compiler/sgi_mipspro.hpp b/src/ext/boost/config/compiler/sgi_mipspro.hpp new file mode 100644 index 00000000000..90688314ad5 --- /dev/null +++ b/src/ext/boost/config/compiler/sgi_mipspro.hpp @@ -0,0 +1,29 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// SGI C++ compiler setup: + +#define BOOST_COMPILER "SGI Irix compiler version " BOOST_STRINGIZE(_COMPILER_VERSION) + +#include "boost/config/compiler/common_edg.hpp" + +// +// Threading support: +// Turn this on unconditionally here, it will get turned off again later +// if no threading API is detected. +// +#define BOOST_HAS_THREADS +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP + +#undef BOOST_NO_SWPRINTF +#undef BOOST_DEDUCED_TYPENAME + +// +// version check: +// probably nothing to do here? + + diff --git a/src/ext/boost/config/compiler/sunpro_cc.hpp b/src/ext/boost/config/compiler/sunpro_cc.hpp new file mode 100644 index 00000000000..f5184887f11 --- /dev/null +++ b/src/ext/boost/config/compiler/sunpro_cc.hpp @@ -0,0 +1,130 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright Peter Dimov 2002. +// (C) Copyright Aleksey Gurtovoy 2002 - 2003. +// (C) Copyright David Abrahams 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Sun C++ compiler setup: + +# if __SUNPRO_CC <= 0x500 +# define BOOST_NO_MEMBER_TEMPLATES +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# endif + +# if (__SUNPRO_CC <= 0x520) + // + // Sunpro 5.2 and earler: + // + // although sunpro 5.2 supports the syntax for + // inline initialization it often gets the value + // wrong, especially where the value is computed + // from other constants (J Maddock 6th May 2001) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // Although sunpro 5.2 supports the syntax for + // partial specialization, it often seems to + // bind to the wrong specialization. Better + // to disable it until suppport becomes more stable + // (J Maddock 6th May 2001). +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# endif + +# if (__SUNPRO_CC <= 0x530) + // Requesting debug info (-g) with Boost.Python results + // in an internal compiler error for "static const" + // initialized in-class. + // >> Assertion: (../links/dbg_cstabs.cc, line 611) + // while processing ../test.cpp at line 0. + // (Jens Maurer according to Gottfried Ganssauge 04 Mar 2002) +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION + + // SunPro 5.3 has better support for partial specialization, + // but breaks when compiling std::less > + // (Jens Maurer 4 Nov 2001). + + // std::less specialization fixed as reported by George + // Heintzelman; partial specialization re-enabled + // (Peter Dimov 17 Jan 2002) + +//# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // integral constant expressions with 64 bit numbers fail +# define BOOST_NO_INTEGRAL_INT64_T +# endif + +# if (__SUNPRO_CC < 0x570) +# define BOOST_NO_TEMPLATE_TEMPLATES + // see http://lists.boost.org/MailArchives/boost/msg47184.php + // and http://lists.boost.org/MailArchives/boost/msg47220.php +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_SFINAE +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif +# if (__SUNPRO_CC <= 0x580) +# define BOOST_NO_IS_ABSTRACT +# endif + +// +// Issues that effect all known versions: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#define BOOST_NO_ADL_BARRIER + +// +// C++0x features +// + +#if(__SUNPRO_CC >= 0x590) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif + +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +// +// Version +// + +#define BOOST_COMPILER "Sun compiler version " BOOST_STRINGIZE(__SUNPRO_CC) + +// +// versions check: +// we don't support sunpro prior to version 4: +#if __SUNPRO_CC < 0x400 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 0x590: +#if (__SUNPRO_CC > 0x590) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif diff --git a/src/ext/boost/config/compiler/vacpp.hpp b/src/ext/boost/config/compiler/vacpp.hpp new file mode 100644 index 00000000000..01956d3a702 --- /dev/null +++ b/src/ext/boost/config/compiler/vacpp.hpp @@ -0,0 +1,88 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Toon Knapen 2001 - 2003. +// (C) Copyright Lie-Quan Lee 2001. +// (C) Copyright Markus Schoepflin 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Visual Age (IBM) C++ compiler setup: + +#if __IBMCPP__ <= 501 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +#endif + +#if (__IBMCPP__ <= 502) +// Actually the compiler supports inclass member initialization but it +// requires a definition for the class member and it doesn't recognize +// it as an integral constant expression when used as a template argument. +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_MEMBER_TEMPLATE_KEYWORD +#endif + +#if (__IBMCPP__ <= 600) || !defined(BOOST_STRICT_CONFIG) +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// +// On AIX thread support seems to be indicated by _THREAD_SAFE: +// +#ifdef _THREAD_SAFE +# define BOOST_HAS_THREADS +#endif + +#define BOOST_COMPILER "IBM Visual Age version " BOOST_STRINGIZE(__IBMCPP__) + +// +// versions check: +// we don't support Visual age prior to version 5: +#if __IBMCPP__ < 500 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 600: +#if (__IBMCPP__ > 1010) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + +// Some versions of the compiler have issues with default arguments on partial specializations +#define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS + +// +// C++0x features +// +// See boost\config\suffix.hpp for BOOST_NO_LONG_LONG +// +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DECLTYPE +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_LAMBDAS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_STATIC_ASSERT +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + + + diff --git a/src/ext/boost/config/compiler/visualc.hpp b/src/ext/boost/config/compiler/visualc.hpp new file mode 100644 index 00000000000..990901f0489 --- /dev/null +++ b/src/ext/boost/config/compiler/visualc.hpp @@ -0,0 +1,258 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright Aleksey Gurtovoy 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Microsoft Visual C++ compiler setup: + +#define BOOST_MSVC _MSC_VER + +#if _MSC_FULL_VER > 100000000 +# define BOOST_MSVC_FULL_VER _MSC_FULL_VER +#else +# define BOOST_MSVC_FULL_VER (_MSC_FULL_VER * 10) +#endif + +// turn off the warnings before we #include anything +#pragma warning( disable : 4503 ) // warning: decorated name length exceeded + +#if _MSC_VER < 1300 // 1200 == VC++ 6.0, 1200-1202 == eVC++4 +# pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# define BOOST_NO_VOID_RETURNS +# define BOOST_NO_EXCEPTION_STD_NAMESPACE + +# if BOOST_MSVC == 1202 +# define BOOST_NO_STD_TYPEINFO +# endif + + // disable min/max macro defines on vc6: + // +#endif + +#if (_MSC_VER <= 1300) // 1300 == VC++ 7.0 + +# if !defined(_MSC_EXTENSIONS) && !defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) // VC7 bug with /Za +# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS +# endif + +# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS +# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_NO_PRIVATE_IN_AGGREGATE +# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP +# define BOOST_NO_INTEGRAL_INT64_T +# define BOOST_NO_DEDUCED_TYPENAME +# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE + +// VC++ 6/7 has member templates but they have numerous problems including +// cases of silent failure, so for safety we define: +# define BOOST_NO_MEMBER_TEMPLATES +// For VC++ experts wishing to attempt workarounds, we define: +# define BOOST_MSVC6_MEMBER_TEMPLATES + +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING +# define BOOST_NO_USING_TEMPLATE +# define BOOST_NO_SWPRINTF +# define BOOST_NO_TEMPLATE_TEMPLATES +# define BOOST_NO_SFINAE +# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS +# define BOOST_NO_IS_ABSTRACT +# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS +// TODO: what version is meant here? Have there really been any fixes in cl 12.01 (as e.g. shipped with eVC4)? +# if (_MSC_VER > 1200) +# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS +# endif + +#endif + +#if _MSC_VER < 1400 +// although a conforming signature for swprint exists in VC7.1 +// it appears not to actually work: +# define BOOST_NO_SWPRINTF +#endif + +#if defined(UNDER_CE) +// Windows CE does not have a conforming signature for swprintf +# define BOOST_NO_SWPRINTF +#endif + +#if _MSC_VER <= 1400 // 1400 == VC++ 8.0 +# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS +#endif + +#if _MSC_VER <= 1600 // 1600 == VC++ 10.0 +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +#endif + +#if _MSC_VER == 1500 // 1500 == VC++ 9.0 + // A bug in VC9: +# define BOOST_NO_ADL_BARRIER +#endif + +#if _MSC_VER <= 1500 || !defined(BOOST_STRICT_CONFIG) // 1500 == VC++ 9.0 +# define BOOST_NO_INITIALIZER_LISTS +#endif + +#ifndef _NATIVE_WCHAR_T_DEFINED +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +#if defined(_WIN32_WCE) || defined(UNDER_CE) +# define BOOST_NO_THREADEX +# define BOOST_NO_GETSYSTEMTIMEASFILETIME +# define BOOST_NO_SWPRINTF +#endif + +// +// check for exception handling support: +#ifndef _CPPUNWIND +# define BOOST_NO_EXCEPTIONS +#endif + +// +// __int64 support: +// +#if (_MSC_VER >= 1200) +# define BOOST_HAS_MS_INT64 +#endif +#if (_MSC_VER >= 1310) && (defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1500)) +# define BOOST_HAS_LONG_LONG +#else +# define BOOST_NO_LONG_LONG +#endif +#if (_MSC_VER >= 1400) && !defined(_DEBUG) +# define BOOST_HAS_NRVO +#endif +// +// disable Win32 API's if compiler extentions are +// turned off: +// +#if !defined(_MSC_EXTENSIONS) && !defined(BOOST_DISABLE_WIN32) +# define BOOST_DISABLE_WIN32 +#endif +#if !defined(_CPPRTTI) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// all versions support __declspec: +// +#define BOOST_HAS_DECLSPEC + +// +// C++0x features +// +// See above for BOOST_NO_LONG_LONG + +// C++ features supported by VC++ 10 (aka 2010) +// +#if _MSC_VER < 1600 +#define BOOST_NO_AUTO_DECLARATIONS +#define BOOST_NO_AUTO_MULTIDECLARATIONS +#define BOOST_NO_DECLTYPE +#define BOOST_NO_LAMBDAS +#define BOOST_NO_RVALUE_REFERENCES +#define BOOST_NO_STATIC_ASSERT +#endif // _MSC_VER < 1600 + +// C++0x features not supported by any versions +#define BOOST_NO_CHAR16_T +#define BOOST_NO_CHAR32_T +#define BOOST_NO_CONCEPTS +#define BOOST_NO_CONSTEXPR +#define BOOST_NO_DEFAULTED_FUNCTIONS +#define BOOST_NO_DELETED_FUNCTIONS +#define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#define BOOST_NO_EXTERN_TEMPLATE +#define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#define BOOST_NO_INITIALIZER_LISTS +#define BOOST_NO_NULLPTR +#define BOOST_NO_RAW_LITERALS +#define BOOST_NO_SCOPED_ENUMS +#define BOOST_NO_SFINAE_EXPR +#define BOOST_NO_TEMPLATE_ALIASES +#define BOOST_NO_UNICODE_LITERALS +#define BOOST_NO_VARIADIC_TEMPLATES + +// +// prefix and suffix headers: +// +#ifndef BOOST_ABI_PREFIX +# define BOOST_ABI_PREFIX "boost/config/abi/msvc_prefix.hpp" +#endif +#ifndef BOOST_ABI_SUFFIX +# define BOOST_ABI_SUFFIX "boost/config/abi/msvc_suffix.hpp" +#endif + +// TODO: +// these things are mostly bogus. 1200 means version 12.0 of the compiler. The +// artificial versions assigned to them only refer to the versions of some IDE +// these compilers have been shipped with, and even that is not all of it. Some +// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. +// IOW, you can't use these 'versions' in any sensible way. Sorry. +# if defined(UNDER_CE) +# if _MSC_VER < 1200 + // Note: these are so far off, they are not really supported +# elif _MSC_VER < 1300 // eVC++ 4 comes with 1200-1202 +# define BOOST_COMPILER_VERSION evc4.0 +# elif _MSC_VER == 1400 +# define BOOST_COMPILER_VERSION evc8 +# elif _MSC_VER == 1500 +# define BOOST_COMPILER_VERSION evc9 +# elif _MSC_VER == 1600 +# define BOOST_COMPILER_VERSION evc10 +# else +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown EVC++ compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown EVC++ compiler version - please run the configure tests and report the results") +# endif +# endif +# else +# if _MSC_VER < 1200 + // Note: these are so far off, they are not really supported +# define BOOST_COMPILER_VERSION 5.0 +# elif _MSC_VER < 1300 +# define BOOST_COMPILER_VERSION 6.0 +# elif _MSC_VER == 1300 +# define BOOST_COMPILER_VERSION 7.0 +# elif _MSC_VER == 1310 +# define BOOST_COMPILER_VERSION 7.1 +# elif _MSC_VER == 1400 +# define BOOST_COMPILER_VERSION 8.0 +# elif _MSC_VER == 1500 +# define BOOST_COMPILER_VERSION 9.0 +# elif _MSC_VER == 1600 +# define BOOST_COMPILER_VERSION 10.0 +# else +# define BOOST_COMPILER_VERSION _MSC_VER +# endif +# endif + +#define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) + +// +// versions check: +// we don't support Visual C++ prior to version 6: +#if _MSC_VER < 1200 +#error "Compiler not supported or configured - please reconfigure" +#endif +// +// last known and checked version is 1600 (VC10, aka 2010): +#if (_MSC_VER > 1600) +# if defined(BOOST_ASSERT_CONFIG) +# error "Unknown compiler version - please run the configure tests and report the results" +# else +# pragma message("Unknown compiler version - please run the configure tests and report the results") +# endif +#endif diff --git a/src/ext/boost/config/no_tr1/cmath.hpp b/src/ext/boost/config/no_tr1/cmath.hpp new file mode 100644 index 00000000000..d8268d842a7 --- /dev/null +++ b/src/ext/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/cmath is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_CMATH +# define BOOST_CONFIG_CMATH + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_CMATH_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +#endif diff --git a/src/ext/boost/config/no_tr1/complex.hpp b/src/ext/boost/config/no_tr1/complex.hpp new file mode 100644 index 00000000000..ca200922b3c --- /dev/null +++ b/src/ext/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/src/ext/boost/config/no_tr1/functional.hpp b/src/ext/boost/config/no_tr1/functional.hpp new file mode 100644 index 00000000000..e395efc1977 --- /dev/null +++ b/src/ext/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/src/ext/boost/config/no_tr1/memory.hpp b/src/ext/boost/config/no_tr1/memory.hpp new file mode 100644 index 00000000000..2b5d2080272 --- /dev/null +++ b/src/ext/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/src/ext/boost/config/no_tr1/utility.hpp b/src/ext/boost/config/no_tr1/utility.hpp new file mode 100644 index 00000000000..dea8f115bce --- /dev/null +++ b/src/ext/boost/config/no_tr1/utility.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/utility is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_UTILITY +# define BOOST_CONFIG_UTILITY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_UTILITY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_UTILITY_RECURSION +# endif + +#endif diff --git a/src/ext/boost/config/platform/aix.hpp b/src/ext/boost/config/platform/aix.hpp new file mode 100644 index 00000000000..894ef42ce91 --- /dev/null +++ b/src/ext/boost/config/platform/aix.hpp @@ -0,0 +1,33 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// IBM/Aix specific config options: + +#define BOOST_PLATFORM "IBM Aix" + +#define BOOST_HAS_UNISTD_H +#define BOOST_HAS_NL_TYPES_H +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_CLOCK_GETTIME + +// This needs support in "boost/cstdint.hpp" exactly like FreeBSD. +// This platform has header named which includes all +// the things needed. +#define BOOST_HAS_STDINT_H + +// Threading API's: +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_DELAY_NP +#define BOOST_HAS_SCHED_YIELD +//#define BOOST_HAS_PTHREAD_YIELD + +// boilerplate code: +#include + + + + diff --git a/src/ext/boost/config/platform/amigaos.hpp b/src/ext/boost/config/platform/amigaos.hpp new file mode 100644 index 00000000000..34bcf4128b7 --- /dev/null +++ b/src/ext/boost/config/platform/amigaos.hpp @@ -0,0 +1,15 @@ +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#define BOOST_PLATFORM "AmigaOS" + +#define BOOST_DISABLE_THREADS +#define BOOST_NO_CWCHAR +#define BOOST_NO_STD_WSTRING +#define BOOST_NO_INTRINSIC_WCHAR_T + + diff --git a/src/ext/boost/config/platform/beos.hpp b/src/ext/boost/config/platform/beos.hpp new file mode 100644 index 00000000000..48c3d8dc5ba --- /dev/null +++ b/src/ext/boost/config/platform/beos.hpp @@ -0,0 +1,26 @@ +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// BeOS specific config options: + +#define BOOST_PLATFORM "BeOS" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_CWCTYPE +#define BOOST_HAS_UNISTD_H + +#define BOOST_HAS_BETHREADS + +#ifndef BOOST_DISABLE_THREADS +# define BOOST_HAS_THREADS +#endif + +// boilerplate code: +#include + + + diff --git a/src/ext/boost/config/platform/bsd.hpp b/src/ext/boost/config/platform/bsd.hpp new file mode 100644 index 00000000000..f02b0e2630a --- /dev/null +++ b/src/ext/boost/config/platform/bsd.hpp @@ -0,0 +1,86 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Douglas Gregor 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic BSD config options: + +#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__) +#error "This platform is not BSD" +#endif + +#ifdef __FreeBSD__ +#define BOOST_PLATFORM "FreeBSD " BOOST_STRINGIZE(__FreeBSD__) +#elif defined(__NetBSD__) +#define BOOST_PLATFORM "NetBSD " BOOST_STRINGIZE(__NetBSD__) +#elif defined(__OpenBSD__) +#define BOOST_PLATFORM "OpenBSD " BOOST_STRINGIZE(__OpenBSD__) +#elif defined(__DragonFly__) +#define BOOST_PLATFORM "DragonFly " BOOST_STRINGIZE(__DragonFly__) +#endif + +// +// is this the correct version check? +// FreeBSD has but does not +// advertise the fact in : +// +#if (defined(__FreeBSD__) && (__FreeBSD__ >= 3)) || defined(__DragonFly__) +# define BOOST_HAS_NL_TYPES_H +#endif + +// +// FreeBSD 3.x has pthreads support, but defines _POSIX_THREADS in +// and not in +// +#if (defined(__FreeBSD__) && (__FreeBSD__ <= 3))\ + || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_HAS_PTHREADS +#endif + +// +// No wide character support in the BSD header files: +// +#if defined(__NetBSD__) +#define __NetBSD_GCC__ (__GNUC__ * 1000000 \ + + __GNUC_MINOR__ * 1000 \ + + __GNUC_PATCHLEVEL__) +// XXX - the following is required until c++config.h +// defines _GLIBCXX_HAVE_SWPRINTF and friends +// or the preprocessor conditionals are removed +// from the cwchar header. +#define _GLIBCXX_HAVE_SWPRINTF 1 +#endif + +#if !((defined(__FreeBSD__) && (__FreeBSD__ >= 5)) \ + || (__NetBSD_GCC__ >= 2095003) || defined(__DragonFly__)) +# define BOOST_NO_CWCHAR +#endif +// +// The BSD has macros only, no functions: +// +#if !defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// thread API's not auto detected: +// +#define BOOST_HAS_SCHED_YIELD +#define BOOST_HAS_NANOSLEEP +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#define BOOST_HAS_SIGACTION + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + + + + diff --git a/src/ext/boost/config/platform/cygwin.hpp b/src/ext/boost/config/platform/cygwin.hpp new file mode 100644 index 00000000000..41fcaa10c78 --- /dev/null +++ b/src/ext/boost/config/platform/cygwin.hpp @@ -0,0 +1,51 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// cygwin specific config options: + +#define BOOST_PLATFORM "Cygwin" +#define BOOST_NO_CWCTYPE +#define BOOST_NO_CWCHAR +#define BOOST_NO_SWPRINTF +#define BOOST_HAS_DIRENT_H +#define BOOST_HAS_LOG1P +#define BOOST_HAS_EXPM1 + +// +// Threading API: +// See if we have POSIX threads, if we do use them, otherwise +// revert to native Win threads. +#define BOOST_HAS_UNISTD_H +#include +#if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_PTHREADS +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_SIGACTION +#else +# if !defined(BOOST_HAS_WINTHREADS) +# define BOOST_HAS_WINTHREADS +# endif +# define BOOST_HAS_FTIME +#endif + +// +// find out if we have a stdint.h, there should be a better way to do this: +// +#include +#ifdef _STDINT_H +#define BOOST_HAS_STDINT_H +#endif + +// boilerplate code: +#include + + + + + diff --git a/src/ext/boost/config/platform/hpux.hpp b/src/ext/boost/config/platform/hpux.hpp new file mode 100644 index 00000000000..19ce68e5973 --- /dev/null +++ b/src/ext/boost/config/platform/hpux.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Toon Knapen 2003. +// (C) Copyright Boris Gubenko 2006 - 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// hpux specific config options: + +#define BOOST_PLATFORM "HP-UX" + +// In principle, HP-UX has a nice under the name +// However, it has the following problem: +// Use of UINT32_C(0) results in "0u l" for the preprocessed source +// (verifyable with gcc 2.95.3) +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__HP_aCC) +# define BOOST_HAS_STDINT_H +#endif + +#if !(defined(__HP_aCC) || !defined(_INCLUDE__STDC_A1_SOURCE)) +# define BOOST_NO_SWPRINTF +#endif +#if defined(__HP_aCC) && !defined(_INCLUDE__STDC_A1_SOURCE) +# define BOOST_NO_CWCTYPE +#endif + +#if defined(__GNUC__) +# if (__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 3)) + // GNU C on HP-UX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +# elif !defined(BOOST_DISABLE_THREADS) + // threads supported from gcc-3.3 onwards: +# define BOOST_HAS_THREADS +# define BOOST_HAS_PTHREADS +# endif +#elif defined(__HP_aCC) && !defined(BOOST_DISABLE_THREADS) +# define BOOST_HAS_PTHREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// the following are always available: +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_SCHED_YIELD +#endif +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +#endif +#ifndef BOOST_HAS_NL_TYPES_H +# define BOOST_HAS_NL_TYPES_H +#endif +#ifndef BOOST_HAS_NANOSLEEP +# define BOOST_HAS_NANOSLEEP +#endif +#ifndef BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_GETTIMEOFDAY +#endif +#ifndef BOOST_HAS_DIRENT_H +# define BOOST_HAS_DIRENT_H +#endif +#ifndef BOOST_HAS_CLOCK_GETTIME +# define BOOST_HAS_CLOCK_GETTIME +#endif +#ifndef BOOST_HAS_SIGACTION +# define BOOST_HAS_SIGACTION +#endif +#ifndef BOOST_HAS_NRVO +# ifndef __parisc +# define BOOST_HAS_NRVO +# endif +#endif +#ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +#endif +#ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +#endif + diff --git a/src/ext/boost/config/platform/irix.hpp b/src/ext/boost/config/platform/irix.hpp new file mode 100644 index 00000000000..aeae49c8b49 --- /dev/null +++ b/src/ext/boost/config/platform/irix.hpp @@ -0,0 +1,31 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// SGI Irix specific config options: + +#define BOOST_PLATFORM "SGI Irix" + +#define BOOST_NO_SWPRINTF +// +// these are not auto detected by POSIX feature tests: +// +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#ifdef __GNUC__ + // GNU C on IRIX does not support threads (checked up to gcc 3.3) +# define BOOST_DISABLE_THREADS +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + + + diff --git a/src/ext/boost/config/platform/linux.hpp b/src/ext/boost/config/platform/linux.hpp new file mode 100644 index 00000000000..51ae13347cd --- /dev/null +++ b/src/ext/boost/config/platform/linux.hpp @@ -0,0 +1,98 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#include + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. +# if defined __GNUC__ +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/src/ext/boost/config/platform/macos.hpp b/src/ext/boost/config/platform/macos.hpp new file mode 100644 index 00000000000..2780ef99e9e --- /dev/null +++ b/src/ext/boost/config/platform/macos.hpp @@ -0,0 +1,86 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Bill Kempf 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Mac OS specific config options: + +#define BOOST_PLATFORM "Mac OS" + +#if __MACH__ && !defined(_MSL_USING_MSL_C) + +// Using the Mac OS X system BSD-style C library. + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif +// +// Begin by including our boilerplate code for POSIX +// feature detection, this is safe even when using +// the MSL as Metrowerks supply their own +// to replace the platform-native BSD one. G++ users +// should also always be able to do this on MaxOS X. +// +# include +# ifndef BOOST_HAS_STDINT_H +# define BOOST_HAS_STDINT_H +# endif + +// +// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday, +// of these only pthreads are advertised in , so set the +// other options explicitly: +// +# define BOOST_HAS_SCHED_YIELD +# define BOOST_HAS_GETTIMEOFDAY +# define BOOST_HAS_SIGACTION + +# if (__GNUC__ < 3) && !defined( __APPLE_CC__) + +// GCC strange "ignore std" mode works better if you pretend everything +// is in the std namespace, for the most part. + +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if (__GNUC__ == 4) + +// Both gcc and intel require these. +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# define BOOST_HAS_NANOSLEEP + +# endif + +#else + +// Using the MSL C library. + +// We will eventually support threads in non-Carbon builds, but we do +// not support this yet. +# if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON ) + +# if !defined(BOOST_HAS_PTHREADS) +# define BOOST_HAS_MPTASKS +# elif ( __dest_os == __mac_os_x ) +// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the +// gettimeofday and no posix. +# define BOOST_HAS_GETTIMEOFDAY +# endif + +// The MP task implementation of Boost Threads aims to replace MP-unsafe +// parts of the MSL, so we turn on threads unconditionally. +# define BOOST_HAS_THREADS + +// The remote call manager depends on this. +# define BOOST_BIND_ENABLE_PASCAL + +# endif + +#endif + + + diff --git a/src/ext/boost/config/platform/qnxnto.hpp b/src/ext/boost/config/platform/qnxnto.hpp new file mode 100644 index 00000000000..b1377c8d2c3 --- /dev/null +++ b/src/ext/boost/config/platform/qnxnto.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Jim Douglas 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// QNX specific config options: + +#define BOOST_PLATFORM "QNX" + +#define BOOST_HAS_UNISTD_H +#include + +// QNX claims XOpen version 5 compatibility, but doesn't have an nl_types.h +// or log1p and expm1: +#undef BOOST_HAS_NL_TYPES_H +#undef BOOST_HAS_LOG1P +#undef BOOST_HAS_EXPM1 + +#define BOOST_HAS_PTHREADS +#define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE + +#define BOOST_HAS_GETTIMEOFDAY +#define BOOST_HAS_CLOCK_GETTIME +#define BOOST_HAS_NANOSLEEP + + + + + diff --git a/src/ext/boost/config/platform/solaris.hpp b/src/ext/boost/config/platform/solaris.hpp new file mode 100644 index 00000000000..9f9256664bd --- /dev/null +++ b/src/ext/boost/config/platform/solaris.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// sun specific config options: + +#define BOOST_PLATFORM "Sun Solaris" + +#define BOOST_HAS_GETTIMEOFDAY + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include + +// +// pthreads don't actually work with gcc unless _PTHREADS is defined: +// +#if defined(__GNUC__) && defined(_POSIX_THREADS) && !defined(_PTHREADS) +# undef BOOST_HAS_PTHREADS +#endif + + + + diff --git a/src/ext/boost/config/platform/vxworks.hpp b/src/ext/boost/config/platform/vxworks.hpp new file mode 100644 index 00000000000..6ec5171e390 --- /dev/null +++ b/src/ext/boost/config/platform/vxworks.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Dustin Spicuzza 2009. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// vxWorks specific config options: + +#define BOOST_PLATFORM "vxWorks" + +#define BOOST_NO_CWCHAR +#define BOOST_NO_INTRINSIC_WCHAR_T + +#if defined(__GNUC__) && defined(__STRICT_ANSI__) +#define BOOST_NO_INT64_T +#endif + +#define BOOST_HAS_UNISTD_H + +// these allow posix_features to work, since vxWorks doesn't +// define them itself +#define _POSIX_TIMERS 1 +#define _POSIX_THREADS 1 + +// vxworks doesn't work with asio serial ports +#define BOOST_ASIO_DISABLE_SERIAL_PORT + +// boilerplate code: +#include + diff --git a/src/ext/boost/config/platform/win32.hpp b/src/ext/boost/config/platform/win32.hpp new file mode 100644 index 00000000000..9344818f87a --- /dev/null +++ b/src/ext/boost/config/platform/win32.hpp @@ -0,0 +1,58 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Bill Kempf 2001. +// (C) Copyright Aleksey Gurtovoy 2003. +// (C) Copyright Rene Rivera 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Win32 specific config options: + +#define BOOST_PLATFORM "Win32" + +// Get the information about the MinGW runtime, i.e. __MINGW32_*VERSION. +#if defined(__MINGW32__) +# include <_mingw.h> +#endif + +#if defined(__GNUC__) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +#endif + +#if !defined(__GNUC__) && !defined(BOOST_HAS_DECLSPEC) +# define BOOST_HAS_DECLSPEC +#endif + +#if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) +# define BOOST_HAS_STDINT_H +# define __STDC_LIMIT_MACROS +# define BOOST_HAS_DIRENT_H +# define BOOST_HAS_UNISTD_H +#endif + +// +// Win32 will normally be using native Win32 threads, +// but there is a pthread library avaliable as an option, +// we used to disable this when BOOST_DISABLE_WIN32 was +// defined but no longer - this should allow some +// files to be compiled in strict mode - while maintaining +// a consistent setting of BOOST_HAS_THREADS across +// all translation units (needed for shared_ptr etc). +// + +#ifdef _WIN32_WCE +# define BOOST_NO_ANSI_APIS +#endif + +#ifndef BOOST_HAS_PTHREADS +# define BOOST_HAS_WINTHREADS +#endif + +#ifndef BOOST_DISABLE_WIN32 +// WEK: Added +#define BOOST_HAS_FTIME +#define BOOST_WINDOWS 1 + +#endif diff --git a/src/ext/boost/config/posix_features.hpp b/src/ext/boost/config/posix_features.hpp new file mode 100644 index 00000000000..d12954797f9 --- /dev/null +++ b/src/ext/boost/config/posix_features.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/src/ext/boost/config/requires_threads.hpp b/src/ext/boost/config/requires_threads.hpp new file mode 100644 index 00000000000..cfaff23027c --- /dev/null +++ b/src/ext/boost/config/requires_threads.hpp @@ -0,0 +1,92 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef BOOST_CONFIG_REQUIRES_THREADS_HPP +#define BOOST_CONFIG_REQUIRES_THREADS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_DISABLE_THREADS) + +// +// special case to handle versions of gcc which don't currently support threads: +// +#if defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC_MINOR__ <= 3) || !defined(BOOST_STRICT_CONFIG)) +// +// this is checked up to gcc 3.3: +// +#if defined(__sgi) || defined(__hpux) +# error "Multi-threaded programs are not supported by gcc on HPUX or Irix (last checked with gcc 3.3)" +#endif + +#endif + +# error "Threading support unavaliable: it has been explicitly disabled with BOOST_DISABLE_THREADS" + +#elif !defined(BOOST_HAS_THREADS) + +# if defined __COMO__ +// Comeau C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_MT (Windows) or -D_REENTRANT (Unix)" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +#ifdef _WIN32 +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" +#else +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -openmp" +#endif + +# elif defined __GNUC__ +// GNU C++: +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + +#elif defined __sgi +// SGI MIPSpro C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -D_SGI_MP_SOURCE" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -pthread" + +#elif defined __BORLANDC__ +// Borland +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -tWM" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either -runtime sm, -runtime smd, -runtime dm, or -runtime dmd" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined __HP_aCC +// HP aCC +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: -mt" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# error "Compiler threading support is not turned on. Please compile the code with the xlC_r compiler" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# error "Compiler threading support is not turned on. Please set the correct command line options for threading: either /MT /MTd /MD or /MDd" + +#else + +# error "Compiler threading support is not turned on. Please consult your compiler's documentation for the appropriate options to use" + +#endif // compilers + +#endif // BOOST_HAS_THREADS + +#endif // BOOST_CONFIG_REQUIRES_THREADS_HPP diff --git a/src/ext/boost/config/select_compiler_config.hpp b/src/ext/boost/config/select_compiler_config.hpp new file mode 100644 index 00000000000..9141cd6376a --- /dev/null +++ b/src/ext/boost/config/select_compiler_config.hpp @@ -0,0 +1,119 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + + +// one identification macro for each of the +// compilers we support: + +# define BOOST_CXX_GCCXML 0 +# define BOOST_CXX_COMO 0 +# define BOOST_CXX_DMC 0 +# define BOOST_CXX_INTEL 0 +# define BOOST_CXX_GNUC 0 +# define BOOST_CXX_KCC 0 +# define BOOST_CXX_SGI 0 +# define BOOST_CXX_TRU64 0 +# define BOOST_CXX_GHS 0 +# define BOOST_CXX_BORLAND 0 +# define BOOST_CXX_CW 0 +# define BOOST_CXX_SUNPRO 0 +# define BOOST_CXX_HPACC 0 +# define BOOST_CXX_MPW 0 +# define BOOST_CXX_IBMCPP 0 +# define BOOST_CXX_MSVC 0 +# define BOOST_CXX_PGI 0 + + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +# elif defined __GNUC__ +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __CODEGEARC__ +// CodeGear - must be checked for before Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif diff --git a/src/ext/boost/config/select_platform_config.hpp b/src/ext/boost/config/select_platform_config.hpp new file mode 100644 index 00000000000..615bb064ff8 --- /dev/null +++ b/src/ext/boost/config/select_platform_config.hpp @@ -0,0 +1,94 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) +// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#elif defined(__VXWORKS__) +// vxWorks: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" + +#else + +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + + + diff --git a/src/ext/boost/config/select_stdlib_config.hpp b/src/ext/boost/config/select_stdlib_config.hpp new file mode 100644 index 00000000000..2a1430aef4b --- /dev/null +++ b/src/ext/boost/config/select_stdlib_config.hpp @@ -0,0 +1,77 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// First include to determine if some version of STLport is in use as the std lib +// (do not rely on this header being included since users can short-circuit this header +// if they know whose std lib they are using.) +#include + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#else + +// If our std lib was not some version of STLport, then include as it is about +// the smallest of the std lib headers that includes real C++ stuff. (Some std libs do not +// include their C++-related macros in so this additional include makes sure +// we get those definitions) +// (again do not rely on this header being included since users can short-circuit this +// header if they know whose std lib they are using.) +#include + +#if defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + +#endif + + + diff --git a/src/ext/boost/config/stdlib/dinkumware.hpp b/src/ext/boost/config/stdlib/dinkumware.hpp new file mode 100644 index 00000000000..ab770599a7d --- /dev/null +++ b/src/ext/boost/config/stdlib/dinkumware.hpp @@ -0,0 +1,138 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright Peter Dimov 2001. +// (C) Copyright David Abrahams 2002. +// (C) Copyright Guillaume Melquiond 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Dinkumware standard library config: + +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#if !defined(_YVALS) && !defined(_CPPLIB_VER) +#error This is not the Dinkumware lib! +#endif +#endif + + +#if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 306) + // full dinkumware 3.06 and above + // fully conforming provided the compiler supports it: +# if !(defined(_GLOBAL_USING) && (_GLOBAL_USING+0 > 0)) && !defined(__BORLANDC__) && !defined(_STD) && !(defined(__ICC) && (__ICC >= 700)) // can be defined in yvals.h +# define BOOST_NO_STDC_NAMESPACE +# endif +# if !(defined(_HAS_MEMBER_TEMPLATES_REBIND) && (_HAS_MEMBER_TEMPLATES_REBIND+0 > 0)) && !(defined(_MSC_VER) && (_MSC_VER > 1300)) && defined(BOOST_MSVC) +# define BOOST_NO_STD_ALLOCATOR +# endif +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + // if this lib version is set up for vc6 then there is no std::use_facet: +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET + // C lib functions aren't in namespace std either: +# define BOOST_NO_STDC_NAMESPACE + // and nor is +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +// There's no numeric_limits support unless _LONGLONG is defined: +# if !defined(_LONGLONG) && (_CPPLIB_VER <= 310) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +// 3.06 appears to have (non-sgi versions of) & , +// and no at all +#else +# define BOOST_MSVC_STD_ITERATOR 1 +# define BOOST_NO_STD_ITERATOR +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_STD_USE_FACET +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +# define BOOST_HAS_MACRO_USE_FACET +# ifndef _CPPLIB_VER + // Updated Dinkum library defines this, and provides + // its own min and max definitions, as does MTA version. +# ifndef __MTA__ +# define BOOST_NO_STD_MIN_MAX +# endif +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# endif +#endif + +// +// std extension namespace is stdext for vc7.1 and later, +// the same applies to other compilers that sit on top +// of vc7.1 (Intel and Comeau): +// +#if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(__BORLANDC__) +# define BOOST_STD_EXTENSION_NAMESPACE stdext +#endif + + +#if (defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(__BORLANDC__)) || !defined(_CPPLIB_VER) || (_CPPLIB_VER < 306) + // if we're using a dinkum lib that's + // been configured for VC6/7 then there is + // no iterator traits (true even for icl) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +#if defined(__ICL) && (__ICL < 800) && defined(_CPPLIB_VER) && (_CPPLIB_VER <= 310) +// Intel C++ chokes over any non-trivial use of +// this may be an overly restrictive define, but regex fails without it: +# define BOOST_NO_STD_LOCALE +#endif + +// C++0x headers implemented in 520 (as shipped by Microsoft) +// +#if !defined(_CPPLIB_VER) || _CPPLIB_VER < 520 +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE + +#ifdef _CPPLIB_VER +# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER +#else +# define BOOST_DINKUMWARE_STDLIB 1 +#endif + +#ifdef _CPPLIB_VER +# define BOOST_STDLIB "Dinkumware standard library version " BOOST_STRINGIZE(_CPPLIB_VER) +#else +# define BOOST_STDLIB "Dinkumware standard library version 1.x" +#endif + + + + + + + + + diff --git a/src/ext/boost/config/stdlib/libcomo.hpp b/src/ext/boost/config/stdlib/libcomo.hpp new file mode 100644 index 00000000000..06731e32e70 --- /dev/null +++ b/src/ext/boost/config/stdlib/libcomo.hpp @@ -0,0 +1,71 @@ +// (C) Copyright John Maddock 2002 - 2003. +// (C) Copyright Jens Maurer 2002 - 2003. +// (C) Copyright Beman Dawes 2002 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Comeau STL: + +#if !defined(__LIBCOMO__) +# include +# if !defined(__LIBCOMO__) +# error "This is not the Comeau STL!" +# endif +#endif + +// +// std::streambuf is non-standard +// NOTE: versions of libcomo prior to beta28 have octal version numbering, +// e.g. version 25 is 21 (dec) +#if __LIBCOMO_VERSION__ <= 22 +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if (__LIBCOMO_VERSION__ <= 31) && defined(_WIN32) +#define BOOST_NO_SWPRINTF +#endif + +#if __LIBCOMO_VERSION__ >= 31 +# define BOOST_HAS_HASH +# define BOOST_HAS_SLIST +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +#define BOOST_STDLIB "Comeau standard library " BOOST_STRINGIZE(__LIBCOMO_VERSION__) + + diff --git a/src/ext/boost/config/stdlib/libstdcpp3.hpp b/src/ext/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 00000000000..6a57319ffd2 --- /dev/null +++ b/src/ext/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,127 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// config for libstdc++ v3 +// not much to go in here: + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# else +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# endif +#endif + +// stdlibc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly +// __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the stdlibc++ +// developers. He also commented: +// +// "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in +// GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. +// Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support +// than any release in the 4.2 series." +// +// Another resource for understanding stdlibc++ features is: +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x + +// C++0x headers in GCC 4.3.0 and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// C++0x headers in GCC 4.4.0 and later +// +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4) || !defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS + +// --- end --- diff --git a/src/ext/boost/config/stdlib/modena.hpp b/src/ext/boost/config/stdlib/modena.hpp new file mode 100644 index 00000000000..7bd50cecb7c --- /dev/null +++ b/src/ext/boost/config/stdlib/modena.hpp @@ -0,0 +1,55 @@ +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Modena C++ standard library (comes with KAI C++) + +#if !defined(MSIPL_COMPILE_H) +# include +# if !defined(__MSIPL_COMPILE_H) +# error "This is not the Modena C++ library!" +# endif +#endif + +#ifndef MSIPL_NL_TYPES +#define BOOST_NO_STD_MESSAGES +#endif + +#ifndef MSIPL_WCHART +#define BOOST_NO_STD_WSTRING +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +#define BOOST_STDLIB "Modena C++ standard library" + + + + + diff --git a/src/ext/boost/config/stdlib/msl.hpp b/src/ext/boost/config/stdlib/msl.hpp new file mode 100644 index 00000000000..6bcd232a573 --- /dev/null +++ b/src/ext/boost/config/stdlib/msl.hpp @@ -0,0 +1,83 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Darin Adler 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Metrowerks standard library: + +#ifndef __MSL_CPP__ +# include +# ifndef __MSL_CPP__ +# error This is not the MSL standard library! +# endif +#endif + +#if __MSL_CPP__ >= 0x6000 // Pro 6 +# define BOOST_HAS_HASH +# define BOOST_STD_EXTENSION_NAMESPACE Metrowerks +#endif +#define BOOST_HAS_SLIST + +#if __MSL_CPP__ < 0x6209 +# define BOOST_NO_STD_MESSAGES +#endif + +// check C lib version for +#include + +#if defined(__MSL__) && (__MSL__ >= 0x5000) +# define BOOST_HAS_STDINT_H +# if !defined(__PALMOS_TRAPS__) +# define BOOST_HAS_UNISTD_H +# endif + // boilerplate code: +# include +#endif + +#if defined(_MWMT) || _MSL_THREADSAFE +# define BOOST_HAS_THREADS +#endif + +#ifdef _MSL_NO_EXPLICIT_FUNC_TEMPLATE_ARG +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +#define BOOST_STDLIB "Metrowerks Standard Library version " BOOST_STRINGIZE(__MSL_CPP__) + + + + + + + + + diff --git a/src/ext/boost/config/stdlib/roguewave.hpp b/src/ext/boost/config/stdlib/roguewave.hpp new file mode 100644 index 00000000000..cba2f54a1a0 --- /dev/null +++ b/src/ext/boost/config/stdlib/roguewave.hpp @@ -0,0 +1,179 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001. +// (C) Copyright David Abrahams 2003. +// (C) Copyright Boris Gubenko 2007. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// Rogue Wave std lib: + +#if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# include +# if !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER) +# error This is not the Rogue Wave standard library +# endif +#endif +// +// figure out a consistent version number: +// +#ifndef _RWSTD_VER +# define BOOST_RWSTD_VER 0x010000 +#elif _RWSTD_VER < 0x010000 +# define BOOST_RWSTD_VER (_RWSTD_VER << 8) +#else +# define BOOST_RWSTD_VER _RWSTD_VER +#endif + +#ifndef _RWSTD_VER +# define BOOST_STDLIB "Rogue Wave standard library version (Unknown version)" +#elif _RWSTD_VER < 0x04010200 + # define BOOST_STDLIB "Rogue Wave standard library version " BOOST_STRINGIZE(_RWSTD_VER) +#else +# ifdef _RWSTD_VER_STR +# define BOOST_STDLIB "Apache STDCXX standard library version " _RWSTD_VER_STR +# else +# define BOOST_STDLIB "Apache STDCXX standard library version " BOOST_STRINGIZE(_RWSTD_VER) +# endif +#endif + +// +// Prior to version 2.2.0 the primary template for std::numeric_limits +// does not have compile time constants, even though specializations of that +// template do: +// +#if BOOST_RWSTD_VER < 0x020200 +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// Sun CC 5.5 patch 113817-07 adds long long specialization, but does not change the +// library version number (http://sunsolve6.sun.com/search/document.do?assetkey=1-21-113817): +#if BOOST_RWSTD_VER <= 0x020101 && (!defined(__SUNPRO_CC) || (__SUNPRO_CC < 0x550)) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// Borland version of numeric_limits lacks __int64 specialisation: +// +#ifdef __BORLANDC__ +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// No std::iterator if it can't figure out default template args: +// +#if defined(_RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || defined(RWSTD_NO_SIMPLE_DEFAULT_TEMPLATES) || (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// No iterator traits without partial specialization: +// +#if defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) || defined(RWSTD_NO_CLASS_PARTIAL_SPEC) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// Prior to version 2.0, std::auto_ptr was buggy, and there were no +// new-style iostreams, and no conformant std::allocator: +// +#if (BOOST_RWSTD_VER < 0x020000) +# define BOOST_NO_AUTO_PTR +# define BOOST_NO_STRINGSTREAM +# define BOOST_NO_STD_ALLOCATOR +# define BOOST_NO_STD_LOCALE +#endif + +// +// No template iterator constructors without member template support: +// +#if defined(RWSTD_NO_MEMBER_TEMPLATES) || defined(_RWSTD_NO_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +#endif + +// +// RW defines _RWSTD_ALLOCATOR if the allocator is conformant and in use +// (the or _HPACC_ part is a hack - the library seems to define _RWSTD_ALLOCATOR +// on HP aCC systems even though the allocator is in fact broken): +// +#if !defined(_RWSTD_ALLOCATOR) || (defined(__HP_aCC) && __HP_aCC <= 33100) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If we have a std::locale, we still may not have std::use_facet: +// +#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE) && !defined(BOOST_NO_STD_LOCALE) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_TWO_ARG_USE_FACET +#endif + +// +// There's no std::distance prior to version 2, or without +// partial specialization support: +// +#if (BOOST_RWSTD_VER < 0x020000) || defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + #define BOOST_NO_STD_DISTANCE +#endif + +// +// Some versions of the rogue wave library don't have assignable +// OutputIterators: +// +#if BOOST_RWSTD_VER < 0x020100 +# define BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN +#endif + +// +// Disable BOOST_HAS_LONG_LONG when the library has no support for it. +// +#if !defined(_RWSTD_LONG_LONG) && defined(BOOST_HAS_LONG_LONG) +# undef BOOST_HAS_LONG_LONG +#endif + +// +// check that on HP-UX, the proper RW library is used +// +#if defined(__HP_aCC) && !defined(_HP_NAMESPACE_STD) +# error "Boost requires Standard RW library. Please compile and link with -AA" +#endif + +// +// Define macros specific to RW V2.2 on HP-UX +// +#if defined(__HP_aCC) && (BOOST_RWSTD_VER == 0x02020100) +# ifndef __HP_TC1_MAKE_PAIR +# define __HP_TC1_MAKE_PAIR +# endif +# ifndef _HP_INSTANTIATE_STD2_VL +# define _HP_INSTANTIATE_STD2_VL +# endif +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + diff --git a/src/ext/boost/config/stdlib/sgi.hpp b/src/ext/boost/config/stdlib/sgi.hpp new file mode 100644 index 00000000000..c505008b7d7 --- /dev/null +++ b/src/ext/boost/config/stdlib/sgi.hpp @@ -0,0 +1,136 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// generic SGI STL: + +#if !defined(__STL_CONFIG_H) +# include +# if !defined(__STL_CONFIG_H) +# error "This is not the SGI STL!" +# endif +#endif + +// +// No std::iterator traits without partial specialisation: +// +#if !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No std::stringstream with gcc < 3 +// +#if defined(__GNUC__) && (__GNUC__ < 3) && \ + ((__GNUC_MINOR__ < 95) || (__GNUC_MINOR__ == 96)) && \ + !defined(__STL_USE_NEW_IOSTREAMS) || \ + defined(__APPLE_CC__) + // Note that we only set this for GNU C++ prior to 2.95 since the + // latest patches for that release do contain a minimal + // If you are running a 2.95 release prior to 2.95.3 then this will need + // setting, but there is no way to detect that automatically (other + // than by running the configure script). + // Also, the unofficial GNU C++ 2.96 included in RedHat 7.1 doesn't + // have . +# define BOOST_NO_STRINGSTREAM +#endif + +// +// Assume no std::locale without own iostreams (this may be an +// incorrect assumption in some cases): +// +#if !defined(__SGI_STL_OWN_IOSTREAMS) && !defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// Original native SGI streams have non-standard std::messages facet: +// +#if defined(__sgi) && (_COMPILER_VERSION <= 650) && !defined(__SGI_STL_OWN_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +#endif + +// +// SGI's new iostreams have missing "const" in messages<>::open +// +#if defined(__sgi) && (_COMPILER_VERSION <= 740) && defined(__STL_USE_NEW_IOSTREAMS) +# define BOOST_NO_STD_MESSAGES +#endif + +// +// No template iterator constructors, or std::allocator +// without member templates: +// +#if !defined(__STL_MEMBER_TEMPLATES) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST + +// +// If this is GNU libstdc++2, then no and no std::wstring: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) +# include +# if defined(__BASTRING__) +# define BOOST_NO_LIMITS +// Note: will provide compile-time constants +# undef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_STD_WSTRING +# endif +#endif + +// +// There is no standard iterator unless we have namespace support: +// +#if !defined(__STL_USE_NAMESPACES) +# define BOOST_NO_STD_ITERATOR +#endif + +// +// Intrinsic type_traits support. +// The SGI STL has it's own __type_traits class, which +// has intrinsic compiler support with SGI's compilers. +// Whatever map SGI style type traits to boost equivalents: +// +#define BOOST_HAS_SGI_TYPE_TRAITS + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +#define BOOST_STDLIB "SGI standard library" + + + diff --git a/src/ext/boost/config/stdlib/stlport.hpp b/src/ext/boost/config/stdlib/stlport.hpp new file mode 100644 index 00000000000..3dfd529effb --- /dev/null +++ b/src/ext/boost/config/stdlib/stlport.hpp @@ -0,0 +1,236 @@ +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Darin Adler 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// STLPort standard library config: + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# include +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +# error "This is not STLPort!" +# endif +#endif + +// +// __STL_STATIC_CONST_INIT_BUG implies BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// for versions prior to 4.1(beta) +// +#if (defined(__STL_STATIC_CONST_INIT_BUG) || defined(_STLP_STATIC_CONST_INIT_BUG)) && (__SGI_STL_PORT <= 0x400) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#endif + +// +// If STLport thinks that there is no partial specialisation, then there is no +// std::iterator traits: +// +#if !(defined(_STLP_CLASS_PARTIAL_SPECIALIZATION) || defined(__STL_CLASS_PARTIAL_SPECIALIZATION)) +# define BOOST_NO_STD_ITERATOR_TRAITS +#endif + +// +// No new style iostreams on GCC without STLport's iostreams enabled: +// +#if (defined(__GNUC__) && (__GNUC__ < 3)) && !(defined(__SGI_STL_OWN_IOSTREAMS) || defined(_STLP_OWN_IOSTREAMS)) +# define BOOST_NO_STRINGSTREAM +#endif + +// +// No new iostreams implies no std::locale, and no std::stringstream: +// +#if defined(__STL_NO_IOSTREAMS) || defined(__STL_NO_NEW_IOSTREAMS) || defined(_STLP_NO_IOSTREAMS) || defined(_STLP_NO_NEW_IOSTREAMS) +# define BOOST_NO_STD_LOCALE +# define BOOST_NO_STRINGSTREAM +#endif + +// +// If the streams are not native, and we have a "using ::x" compiler bug +// then the io stream facets are not available in namespace std:: +// +#ifdef _STLPORT_VERSION +# if !(_STLPORT_VERSION >= 0x500) && !defined(_STLP_OWN_IOSTREAMS) && defined(_STLP_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#else +# if !defined(__SGI_STL_OWN_IOSTREAMS) && defined(__STL_USE_NAMESPACES) && defined(BOOST_NO_USING_TEMPLATE) && !defined(__BORLANDC__) +# define BOOST_NO_STD_LOCALE +# endif +#endif + +#if defined(_STLPORT_VERSION) && ((_STLPORT_VERSION < 0x500) || (_STLPORT_VERSION >= 0x520)) +# define BOOST_NO_STD_UNORDERED +#endif + +#if defined(_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x520) +# define BOOST_HAS_TR1_UNORDERED_SET +# define BOOST_HAS_TR1_UNORDERED_MAP +#endif +// +// Without member template support enabled, their are no template +// iterate constructors, and no std::allocator: +// +#if !(defined(__STL_MEMBER_TEMPLATES) || defined(_STLP_MEMBER_TEMPLATES)) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# define BOOST_NO_STD_ALLOCATOR +#endif +// +// however we always have at least a partial allocator: +// +#define BOOST_HAS_PARTIAL_STD_ALLOCATOR + +#if !defined(_STLP_MEMBER_TEMPLATE_CLASSES) || defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) +# define BOOST_NO_STD_ALLOCATOR +#endif + +#if defined(_STLP_NO_MEMBER_TEMPLATE_KEYWORD) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1300) +# define BOOST_NO_STD_ALLOCATOR +#endif + +// +// If STLport thinks there is no wchar_t at all, then we have to disable +// the support for the relevant specilazations of std:: templates. +// +#if !defined(_STLP_HAS_WCHAR_T) && !defined(_STLP_WCHAR_T_IS_USHORT) +# ifndef BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTRING +# endif +# ifndef BOOST_NO_STD_WSTREAMBUF +# define BOOST_NO_STD_WSTREAMBUF +# endif +#endif + +// +// We always have SGI style hash_set, hash_map, and slist: +// +#ifndef _STLP_NO_EXTENSIONS +#define BOOST_HAS_HASH +#define BOOST_HAS_SLIST +#endif + +// +// STLport does a good job of importing names into namespace std::, +// but doesn't always get them all, define BOOST_NO_STDC_NAMESPACE, since our +// workaround does not conflict with STLports: +// +// +// Harold Howe says: +// Borland switched to STLport in BCB6. Defining BOOST_NO_STDC_NAMESPACE with +// BCB6 does cause problems. If we detect C++ Builder, then don't define +// BOOST_NO_STDC_NAMESPACE +// +#if !defined(__BORLANDC__) && !defined(__DMC__) +// +// If STLport is using it's own namespace, and the real names are in +// the global namespace, then we duplicate STLport's using declarations +// (by defining BOOST_NO_STDC_NAMESPACE), we do this because STLport doesn't +// necessarily import all the names we need into namespace std:: +// +# if (defined(__STL_IMPORT_VENDOR_CSTD) \ + || defined(__STL_USE_OWN_NAMESPACE) \ + || defined(_STLP_IMPORT_VENDOR_CSTD) \ + || defined(_STLP_USE_OWN_NAMESPACE)) \ + && (defined(__STL_VENDOR_GLOBAL_CSTD) || defined (_STLP_VENDOR_GLOBAL_CSTD)) +# define BOOST_NO_STDC_NAMESPACE +# define BOOST_NO_EXCEPTION_STD_NAMESPACE +# endif +#elif defined(__BORLANDC__) && __BORLANDC__ < 0x560 +// STLport doesn't import std::abs correctly: +#include +namespace std { using ::abs; } +// and strcmp/strcpy don't get imported either ('cos they are macros) +#include +#ifdef strcpy +# undef strcpy +#endif +#ifdef strcmp +# undef strcmp +#endif +#ifdef _STLP_VENDOR_CSTD +namespace std{ using _STLP_VENDOR_CSTD::strcmp; using _STLP_VENDOR_CSTD::strcpy; } +#endif +#endif + +// +// std::use_facet may be non-standard, uses a class instead: +// +#if defined(__STL_NO_EXPLICIT_FUNCTION_TMPL_ARGS) || defined(_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) +# define BOOST_NO_STD_USE_FACET +# define BOOST_HAS_STLP_USE_FACET +#endif + +// +// If STLport thinks there are no wide functions, etc. is not working; but +// only if BOOST_NO_STDC_NAMESPACE is not defined (if it is then we do the import +// into std:: ourselves). +// +#if defined(_STLP_NO_NATIVE_WIDE_FUNCTIONS) && !defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +#endif + +// +// If STLport for some reason was configured so that it thinks that wchar_t +// is not an intrinsic type, then we have to disable the support for it as +// well (we would be missing required specializations otherwise). +// +#if !defined( _STLP_HAS_WCHAR_T) || defined(_STLP_WCHAR_T_IS_USHORT) +# undef BOOST_NO_INTRINSIC_WCHAR_T +# define BOOST_NO_INTRINSIC_WCHAR_T +#endif + +// +// Borland ships a version of STLport with C++ Builder 6 that lacks +// hashtables and the like: +// +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x560) +# undef BOOST_HAS_HASH +#endif + +// +// gcc-2.95.3/STLPort does not like the using declarations we use to get ADL with std::min/max +// +#if defined(__GNUC__) && (__GNUC__ < 3) +# include // for std::min and std::max +# define BOOST_USING_STD_MIN() ((void)0) +# define BOOST_USING_STD_MAX() ((void)0) +namespace boost { using std::min; using std::max; } +#endif + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +#define BOOST_STDLIB "STLPort standard library version " BOOST_STRINGIZE(__SGI_STL_PORT) + + + + + + + + diff --git a/src/ext/boost/config/stdlib/vacpp.hpp b/src/ext/boost/config/stdlib/vacpp.hpp new file mode 100644 index 00000000000..c8d6d5ad697 --- /dev/null +++ b/src/ext/boost/config/stdlib/vacpp.hpp @@ -0,0 +1,43 @@ +// (C) Copyright John Maddock 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +#if __IBMCPP__ <= 501 +# define BOOST_NO_STD_ALLOCATOR +#endif + +#define BOOST_HAS_MACRO_USE_FACET +#define BOOST_NO_STD_MESSAGES + +// C++0x headers not yet implemented +// +# define BOOST_NO_0X_HDR_ARRAY +# define BOOST_NO_0X_HDR_CHRONO +# define BOOST_NO_0X_HDR_CODECVT +# define BOOST_NO_0X_HDR_CONCEPTS +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +# define BOOST_NO_0X_HDR_CONTAINER_CONCEPTS +# define BOOST_NO_0X_HDR_FORWARD_LIST +# define BOOST_NO_0X_HDR_FUTURE +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_ITERATOR_CONCEPTS +# define BOOST_NO_0X_HDR_MEMORY_CONCEPTS +# define BOOST_NO_0X_HDR_MUTEX +# define BOOST_NO_0X_HDR_RANDOM +# define BOOST_NO_0X_HDR_RATIO +# define BOOST_NO_0X_HDR_REGEX +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +# define BOOST_NO_0X_HDR_THREAD +# define BOOST_NO_0X_HDR_TUPLE +# define BOOST_NO_0X_HDR_TYPE_TRAITS +# define BOOST_NO_STD_UNORDERED // deprecated; see following +# define BOOST_NO_0X_HDR_UNORDERED_MAP +# define BOOST_NO_0X_HDR_UNORDERED_SET + +#define BOOST_STDLIB "Visual Age default standard library" + + + diff --git a/src/ext/boost/config/suffix.hpp b/src/ext/boost/config/suffix.hpp new file mode 100644 index 00000000000..fa44986946c --- /dev/null +++ b/src/ext/boost/config/suffix.hpp @@ -0,0 +1,601 @@ +// Boost config.hpp configuration header file ------------------------------// + +// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001 Darin Adler +// Copyright (c) 2001 Peter Dimov +// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Jens Maurer +// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2003 Gennaro Prota +// Copyright (c) 2003 Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config/ +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +// +// look for long long by looking for the appropriate macros in . +// Note that we use limits.h rather than climits for maximal portability, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(__BORLANDC__) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without partial specialization, partial +// specialization with default args won't work either: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) +# define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// Without typeid support we have no dynamic RTTI either: +// +#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ + && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_PTHREAD_YIELD +# undef BOOST_HAS_PTHREAD_DELAY_NP +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) +# define BOOST_NO_SLIST +# endif + +# if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// +// Set BOOST_NO_INITIALIZER_LISTS if there is no library support. +// + +#if defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# ifdef BOOST_NO_STDC_NAMESPACE +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# ifdef BOOST_NO_STD_MIN_MAX + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analogous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +#else +# define BOOST_UNREACHABLE_RETURN(x) +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +#ifndef BOOST_NO_TYPENAME_WITH_CTOR +# define BOOST_CTOR_TYPENAME typename +#else +# define BOOST_CTOR_TYPENAME +#endif + +// long long workaround ------------------------------------------// +// On gcc (and maybe other compilers?) long long is alway supported +// but it's use may generate either warnings (with -ansi), or errors +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// +// +// Some compilers have problems with function templates whose template +// parameters don't appear in the function parameter list (basically +// they just link one instantiation of the template in the final +// executable). These macros provide a uniform way to cope with the +// problem with no effects on the calling syntax. + +// Example: +// +// #include +// #include +// #include +// +// template +// void f() { std::cout << n << ' '; } +// +// template +// void g() { std::cout << typeid(T).name() << ' '; } +// +// int main() { +// f<1>(); +// f<2>(); +// +// g(); +// g(); +// } +// +// With VC++ 6.0 the output is: +// +// 2 2 double double +// +// To fix it, write +// +// template +// void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... } +// +// template +// void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... } +// + + +#if defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS + +# include "boost/type.hpp" +# include "boost/non_type.hpp" + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) boost::type* = 0 +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type* +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type* = 0 +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type* + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ + , BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ + , BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ + , BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ + , BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +#else + +// no workaround needed: expand to nothing + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + + +#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS + + +// ---------------------------------------------------------------------------// + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y ) +#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2( X, Y ) X##Y + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +#endif + + diff --git a/src/ext/boost/config/user.hpp b/src/ext/boost/config/user.hpp new file mode 100644 index 00000000000..5a4a9d47762 --- /dev/null +++ b/src/ext/boost/config/user.hpp @@ -0,0 +1,124 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be statically linked (Boost.Test for example) and others which may only +// be dynamically linked (Boost.Threads for example), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only be statically linked +// (Boost.Test for example) and others which may only be dynamically linked +// (Boost.Threads for example), in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + + + diff --git a/src/ext/boost/config/warning_disable.hpp b/src/ext/boost/config/warning_disable.hpp new file mode 100644 index 00000000000..26ff1323c03 --- /dev/null +++ b/src/ext/boost/config/warning_disable.hpp @@ -0,0 +1,47 @@ +// Copyright John Maddock 2008 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// This file exists to turn off some overly-pedantic warning emitted +// by certain compilers. You should include this header only in: +// +// * A test case, before any other headers, or, +// * A library source file before any other headers. +// +// IT SHOULD NOT BE INCLUDED BY ANY BOOST HEADER. +// +// YOU SHOULD NOT INCLUDE IT IF YOU CAN REASONABLY FIX THE WARNING. +// +// The only warnings disabled here are those that are: +// +// * Quite unreasonably pedantic. +// * Generally only emitted by a single compiler. +// * Can't easily be fixed: for example if the vendors own std lib +// code emits these warnings! +// +// Note that THIS HEADER MUST NOT INCLUDE ANY OTHER HEADERS: +// not even std library ones! Doing so may turn the warning +// off too late to be of any use. For example the VC++ C4996 +// warning can be omitted from if that header is included +// before or by this one :-( +// + +#ifndef BOOST_CONFIG_WARNING_DISABLE_HPP +#define BOOST_CONFIG_WARNING_DISABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + // Error 'function': was declared deprecated + // http://msdn2.microsoft.com/en-us/library/ttcz0bys(VS.80).aspx + // This error is emitted when you use some perfectly conforming + // std lib functions in a perfectly correct way, and also by + // some of Microsoft's own std lib code ! +# pragma warning(disable:4996) +#endif +#if defined(__INTEL_COMPILER) || defined(__ICL) + // As above: gives warning when a "deprecated" + // std library function is encountered. +# pragma warning(disable:1786) +#endif + +#endif // BOOST_CONFIG_WARNING_DISABLE_HPP diff --git a/src/ext/boost/current_function.hpp b/src/ext/boost/current_function.hpp new file mode 100644 index 00000000000..aa5756e0a5b --- /dev/null +++ b/src/ext/boost/current_function.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/utility/current_function.html +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/src/ext/boost/detail/algorithm.hpp b/src/ext/boost/detail/algorithm.hpp new file mode 100644 index 00000000000..252e9f461c5 --- /dev/null +++ b/src/ext/boost/detail/algorithm.hpp @@ -0,0 +1,222 @@ +// (C) Copyright Jeremy Siek 2001. +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#ifndef BOOST_ALGORITHM_HPP +# define BOOST_ALGORITHM_HPP +# include +// Algorithms on sequences +// +// The functions in this file have not yet gone through formal +// review, and are subject to change. This is a work in progress. +// They have been checked into the detail directory because +// there are some graph algorithms that use these functions. + +#include +#include + +namespace boost { + + template + Iter1 begin(const std::pair& p) { return p.first; } + + template + Iter2 end(const std::pair& p) { return p.second; } + + template + typename boost::detail::iterator_traits::difference_type + size(const std::pair& p) { + return std::distance(p.first, p.second); + } + +#if 0 + // These seem to interfere with the std::pair overloads :( + template + typename Container::iterator + begin(Container& c) { return c.begin(); } + + template + typename Container::const_iterator + begin(const Container& c) { return c.begin(); } + + template + typename Container::iterator + end(Container& c) { return c.end(); } + + template + typename Container::const_iterator + end(const Container& c) { return c.end(); } + + template + typename Container::size_type + size(const Container& c) { return c.size(); } +#else + template + typename std::vector::iterator + begin(std::vector& c) { return c.begin(); } + + template + typename std::vector::const_iterator + begin(const std::vector& c) { return c.begin(); } + + template + typename std::vector::iterator + end(std::vector& c) { return c.end(); } + + template + typename std::vector::const_iterator + end(const std::vector& c) { return c.end(); } + + template + typename std::vector::size_type + size(const std::vector& c) { return c.size(); } +#endif + + template + void iota(ForwardIterator first, ForwardIterator last, T value) + { + for (; first != last; ++first, ++value) + *first = value; + } + template + void iota(Container& c, const T& value) + { + iota(begin(c), end(c), value); + } + + // Also do version with 2nd container? + template + OutIter copy(const Container& c, OutIter result) { + return std::copy(begin(c), end(c), result); + } + + template + bool equal(const Container1& c1, const Container2& c2) + { + if (size(c1) != size(c2)) + return false; + return std::equal(begin(c1), end(c1), begin(c2)); + } + + template + void sort(Container& c) { std::sort(begin(c), end(c)); } + + template + void sort(Container& c, const Predicate& p) { + std::sort(begin(c), end(c), p); + } + + template + void stable_sort(Container& c) { std::stable_sort(begin(c), end(c)); } + + template + void stable_sort(Container& c, const Predicate& p) { + std::stable_sort(begin(c), end(c), p); + } + + template + bool any_if(InputIterator first, InputIterator last, Predicate p) + { + return std::find_if(first, last, p) != last; + } + template + bool any_if(const Container& c, Predicate p) + { + return any_if(begin(c), end(c), p); + } + + template + bool container_contains(InputIterator first, InputIterator last, T value) + { + return std::find(first, last, value) != last; + } + template + bool container_contains(const Container& c, const T& value) + { + return container_contains(begin(c), end(c), value); + } + + template + std::size_t count(const Container& c, const T& value) + { + return std::count(begin(c), end(c), value); + } + + template + std::size_t count_if(const Container& c, Predicate p) + { + return std::count_if(begin(c), end(c), p); + } + + template + bool is_sorted(ForwardIterator first, ForwardIterator last) + { + if (first == last) + return true; + + ForwardIterator next = first; + for (++next; next != last; first = next, ++next) { + if (*next < *first) + return false; + } + + return true; + } + + template + bool is_sorted(ForwardIterator first, ForwardIterator last, + StrictWeakOrdering comp) + { + if (first == last) + return true; + + ForwardIterator next = first; + for (++next; next != last; first = next, ++next) { + if (comp(*next, *first)) + return false; + } + + return true; + } + + template + bool is_sorted(const Container& c) + { + return is_sorted(begin(c), end(c)); + } + + template + bool is_sorted(const Container& c, StrictWeakOrdering comp) + { + return is_sorted(begin(c), end(c), comp); + } + +} // namespace boost + +#endif // BOOST_ALGORITHM_HPP diff --git a/src/ext/boost/detail/allocator_utilities.hpp b/src/ext/boost/detail/allocator_utilities.hpp new file mode 100644 index 00000000000..5d6ef48b05b --- /dev/null +++ b/src/ext/boost/detail/allocator_utilities.hpp @@ -0,0 +1,212 @@ +/* Copyright 2003-2009 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See Boost website at http://www.boost.org/ + */ + +#ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP +#define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace detail{ + +/* Allocator adaption layer. Some stdlibs provide allocators without rebind + * and template ctors. These facilities are simulated with the external + * template class rebind_to and the aid of partial_std_allocator_wrapper. + */ + +namespace allocator{ + +/* partial_std_allocator_wrapper inherits the functionality of a std + * allocator while providing a templatized ctor and other bits missing + * in some stdlib implementation or another. + */ + +template +class partial_std_allocator_wrapper:public std::allocator +{ +public: + /* Oddly enough, STLport does not define std::allocator::value_type + * when configured to work without partial template specialization. + * No harm in supplying the definition here unconditionally. + */ + + typedef Type value_type; + + partial_std_allocator_wrapper(){}; + + template + partial_std_allocator_wrapper(const partial_std_allocator_wrapper&){} + + partial_std_allocator_wrapper(const std::allocator& x): + std::allocator(x) + { + }; + +#if defined(BOOST_DINKUMWARE_STDLIB) + /* Dinkumware guys didn't provide a means to call allocate() without + * supplying a hint, in disagreement with the standard. + */ + + Type* allocate(std::size_t n,const void* hint=0) + { + std::allocator& a=*this; + return a.allocate(n,hint); + } +#endif + +}; + +/* Detects whether a given allocator belongs to a defective stdlib not + * having the required member templates. + * Note that it does not suffice to check the Boost.Config stdlib + * macros, as the user might have passed a custom, compliant allocator. + * The checks also considers partial_std_allocator_wrapper to be + * a standard defective allocator. + */ + +#if defined(BOOST_NO_STD_ALLOCATOR)&&\ + (defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB)) + +template +struct is_partial_std_allocator +{ + BOOST_STATIC_CONSTANT(bool, + value= + (is_same< + std::allocator, + Allocator + >::value)|| + (is_same< + partial_std_allocator_wrapper< + BOOST_DEDUCED_TYPENAME Allocator::value_type>, + Allocator + >::value)); +}; + +#else + +template +struct is_partial_std_allocator +{ + BOOST_STATIC_CONSTANT(bool,value=false); +}; + +#endif + +/* rebind operations for defective std allocators */ + +template +struct partial_std_allocator_rebind_to +{ + typedef partial_std_allocator_wrapper type; +}; + +/* rebind operation in all other cases */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1300) +/* Workaround for a problem in MSVC with dependent template typedefs + * when doing rebinding of allocators. + * Modeled after (thanks, Aleksey!) + */ + +template +struct rebinder +{ + template struct fake_allocator:Allocator{}; + template<> struct fake_allocator + { + template struct rebind{}; + }; + + template + struct result: + fake_allocator::value>:: + template rebind + { + }; +}; +#else +template +struct rebinder +{ + template + struct result + { + typedef typename Allocator::BOOST_NESTED_TEMPLATE + rebind::other other; + }; +}; +#endif + +template +struct compliant_allocator_rebind_to +{ + typedef typename rebinder:: + BOOST_NESTED_TEMPLATE result::other type; +}; + +/* rebind front-end */ + +template +struct rebind_to: + mpl::eval_if_c< + is_partial_std_allocator::value, + partial_std_allocator_rebind_to, + compliant_allocator_rebind_to + > +{ +}; + +/* allocator-independent versions of construct and destroy */ + +template +void construct(void* p,const Type& t) +{ + new (p) Type(t); +} + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +/* MSVC++ issues spurious warnings about unreferencend formal parameters + * in destroy when Type is a class with trivial dtor. + */ + +#pragma warning(push) +#pragma warning(disable:4100) +#endif + +template +void destroy(const Type* p) +{ + +#if BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590)) + const_cast(p)->~Type(); +#else + p->~Type(); +#endif + +} + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(pop) +#endif + +} /* namespace boost::detail::allocator */ + +} /* namespace boost::detail */ + +} /* namespace boost */ + +#endif diff --git a/src/ext/boost/detail/atomic_count.hpp b/src/ext/boost/detail/atomic_count.hpp new file mode 100644 index 00000000000..5411c7ae990 --- /dev/null +++ b/src/ext/boost/detail/atomic_count.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/atomic_count.hpp - thread/SMP safe reference counter +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED diff --git a/src/ext/boost/detail/binary_search.hpp b/src/ext/boost/detail/binary_search.hpp new file mode 100644 index 00000000000..3dca9b65092 --- /dev/null +++ b/src/ext/boost/detail/binary_search.hpp @@ -0,0 +1,216 @@ +// Copyright (c) 2000 David Abrahams. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Copyright (c) 1994 +// Hewlett-Packard Company +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Hewlett-Packard Company makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +// Copyright (c) 1996 +// Silicon Graphics Computer Systems, Inc. +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appear in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Silicon Graphics makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. +// +#ifndef BINARY_SEARCH_DWA_122600_H_ +# define BINARY_SEARCH_DWA_122600_H_ + +# include +# include + +namespace boost { namespace detail { + +template +ForwardIter lower_bound(ForwardIter first, ForwardIter last, + const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (*middle < val) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template +ForwardIter lower_bound(ForwardIter first, ForwardIter last, + const Tp& val, Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(*middle, val)) { + first = middle; + ++first; + len = len - half - 1; + } + else + len = half; + } + return first; +} + +template +ForwardIter upper_bound(ForwardIter first, ForwardIter last, + const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (val < *middle) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template +ForwardIter upper_bound(ForwardIter first, ForwardIter last, + const Tp& val, Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(val, *middle)) + len = half; + else { + first = middle; + ++first; + len = len - half - 1; + } + } + return first; +} + +template +std::pair +equal_range(ForwardIter first, ForwardIter last, const Tp& val) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (*middle < val) { + first = middle; + ++first; + len = len - half - 1; + } + else if (val < *middle) + len = half; + else { + left = boost::detail::lower_bound(first, middle, val); + std::advance(first, len); + right = boost::detail::upper_bound(++middle, first, val); + return std::pair(left, right); + } + } + return std::pair(first, first); +} + +template +std::pair +equal_range(ForwardIter first, ForwardIter last, const Tp& val, + Compare comp) +{ + typedef detail::iterator_traits traits; + + typename traits::difference_type len = boost::detail::distance(first, last); + typename traits::difference_type half; + ForwardIter middle, left, right; + + while (len > 0) { + half = len >> 1; + middle = first; + std::advance(middle, half); + if (comp(*middle, val)) { + first = middle; + ++first; + len = len - half - 1; + } + else if (comp(val, *middle)) + len = half; + else { + left = boost::detail::lower_bound(first, middle, val, comp); + std::advance(first, len); + right = boost::detail::upper_bound(++middle, first, val, comp); + return std::pair(left, right); + } + } + return std::pair(first, first); +} + +template +bool binary_search(ForwardIter first, ForwardIter last, + const Tp& val) { + ForwardIter i = boost::detail::lower_bound(first, last, val); + return i != last && !(val < *i); +} + +template +bool binary_search(ForwardIter first, ForwardIter last, + const Tp& val, + Compare comp) { + ForwardIter i = boost::detail::lower_bound(first, last, val, comp); + return i != last && !comp(val, *i); +} + +}} // namespace boost::detail + +#endif // BINARY_SEARCH_DWA_122600_H_ diff --git a/src/ext/boost/detail/call_traits.hpp b/src/ext/boost/detail/call_traits.hpp new file mode 100644 index 00000000000..6ad646ec60b --- /dev/null +++ b/src/ext/boost/detail/call_traits.hpp @@ -0,0 +1,164 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// call_traits: defines typedefs for function usage +// (see libs/utility/call_traits.htm) + +/* Release notes: + 23rd July 2000: + Fixed array specialization. (JM) + Added Borland specific fixes for reference types + (issue raised by Steve Cleary). +*/ + +#ifndef BOOST_DETAIL_CALL_TRAITS_HPP +#define BOOST_DETAIL_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif +#include + +#include +#include +#include + +namespace boost{ + +namespace detail{ + +template +struct ct_imp2 +{ + typedef const T& param_type; +}; + +template +struct ct_imp2 +{ + typedef const T param_type; +}; + +template +struct ct_imp +{ + typedef const T& param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef const T param_type; +}; + +} + +template +struct call_traits +{ +public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + // + // C++ Builder workaround: we should be able to define a compile time + // constant and pass that as a single template parameter to ct_imp, + // however compiler bugs prevent this - instead pass three bool's to + // ct_imp and add an extra partial specialisation + // of ct_imp to handle the logic. (JM) + typedef typename boost::detail::ct_imp< + T, + ::boost::is_pointer::value, + ::boost::is_arithmetic::value + >::param_type param_type; +}; + +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +#if BOOST_WORKAROUND( __BORLANDC__, < 0x5A0 ) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +template +struct call_traits< T * > +{ + typedef T * value_type; + typedef T * & reference; + typedef T * const & const_reference; + typedef T * const param_type; // hh removed const +}; +#endif +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template +struct call_traits +{ +private: + typedef T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; + +template +struct call_traits +{ +private: + typedef const T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; +#endif + +} + +#endif // BOOST_DETAIL_CALL_TRAITS_HPP diff --git a/src/ext/boost/detail/catch_exceptions.hpp b/src/ext/boost/detail/catch_exceptions.hpp new file mode 100644 index 00000000000..b1a3c76b2a8 --- /dev/null +++ b/src/ext/boost/detail/catch_exceptions.hpp @@ -0,0 +1,146 @@ +// boost/catch_exceptions.hpp -----------------------------------------------// + +// Copyright Beman Dawes 1995-2001. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/test for documentation. + +// Revision History +// 13 Jun 01 report_exception() made inline. (John Maddock, Jesse Jones) +// 26 Feb 01 Numerous changes suggested during formal review. (Beman) +// 25 Jan 01 catch_exceptions.hpp code factored out of cpp_main.cpp. +// 22 Jan 01 Remove test_tools dependencies to reduce coupling. +// 5 Nov 00 Initial boost version (Beman Dawes) + +#ifndef BOOST_CATCH_EXCEPTIONS_HPP +#define BOOST_CATCH_EXCEPTIONS_HPP + +// header dependencies are deliberately restricted to the standard library +// to reduce coupling to other boost libraries. +#include // for string +#include // for bad_alloc +#include // for bad_cast, bad_typeid +#include // for exception, bad_exception +#include // for std exception hierarchy +#include // for exit codes +# if __GNUC__ != 2 || __GNUC_MINOR__ > 96 +# include // for ostream +# else +# include // workaround GNU missing ostream header +# endif + +# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x0551) +# define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT +# endif + +#if defined(MPW_CPLUS) && (MPW_CPLUS <= 0x890) +# define BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT + namespace std { class bad_typeid { }; } +# endif + +namespace boost +{ + + namespace detail + { + // A separate reporting function was requested during formal review. + inline void report_exception( std::ostream & os, + const char * name, const char * info ) + { os << "\n** uncaught exception: " << name << " " << info << std::endl; } + } + + // catch_exceptions ------------------------------------------------------// + + template< class Generator > // Generator is function object returning int + int catch_exceptions( Generator function_object, + std::ostream & out, std::ostream & err ) + { + int result = 0; // quiet compiler warnings + bool exception_thrown = true; // avoid setting result for each excptn type + +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + result = function_object(); + exception_thrown = false; +#ifndef BOOST_NO_EXCEPTIONS + } + + // As a result of hard experience with strangely interleaved output + // under some compilers, there is a lot of use of endl in the code below + // where a simple '\n' might appear to do. + + // The rules for catch & arguments are a bit different from function + // arguments (ISO 15.3 paragraphs 18 & 19). Apparently const isn't + // required, but it doesn't hurt and some programmers ask for it. + + catch ( const char * ex ) + { detail::report_exception( out, "", ex ); } + catch ( const std::string & ex ) + { detail::report_exception( out, "", ex.c_str() ); } + + // std:: exceptions + catch ( const std::bad_alloc & ex ) + { detail::report_exception( out, "std::bad_alloc:", ex.what() ); } + +# ifndef BOOST_BUILT_IN_EXCEPTIONS_MISSING_WHAT + catch ( const std::bad_cast & ex ) + { detail::report_exception( out, "std::bad_cast:", ex.what() ); } + catch ( const std::bad_typeid & ex ) + { detail::report_exception( out, "std::bad_typeid:", ex.what() ); } +# else + catch ( const std::bad_cast & ) + { detail::report_exception( out, "std::bad_cast", "" ); } + catch ( const std::bad_typeid & ) + { detail::report_exception( out, "std::bad_typeid", "" ); } +# endif + + catch ( const std::bad_exception & ex ) + { detail::report_exception( out, "std::bad_exception:", ex.what() ); } + catch ( const std::domain_error & ex ) + { detail::report_exception( out, "std::domain_error:", ex.what() ); } + catch ( const std::invalid_argument & ex ) + { detail::report_exception( out, "std::invalid_argument:", ex.what() ); } + catch ( const std::length_error & ex ) + { detail::report_exception( out, "std::length_error:", ex.what() ); } + catch ( const std::out_of_range & ex ) + { detail::report_exception( out, "std::out_of_range:", ex.what() ); } + catch ( const std::range_error & ex ) + { detail::report_exception( out, "std::range_error:", ex.what() ); } + catch ( const std::overflow_error & ex ) + { detail::report_exception( out, "std::overflow_error:", ex.what() ); } + catch ( const std::underflow_error & ex ) + { detail::report_exception( out, "std::underflow_error:", ex.what() ); } + catch ( const std::logic_error & ex ) + { detail::report_exception( out, "std::logic_error:", ex.what() ); } + catch ( const std::runtime_error & ex ) + { detail::report_exception( out, "std::runtime_error:", ex.what() ); } + catch ( const std::exception & ex ) + { detail::report_exception( out, "std::exception:", ex.what() ); } + + catch ( ... ) + { detail::report_exception( out, "unknown exception", "" ); } +#endif // BOOST_NO_EXCEPTIONS + + if ( exception_thrown ) result = boost::exit_exception_failure; + + if ( result != 0 && result != exit_success ) + { + out << std::endl << "**** returning with error code " + << result << std::endl; + err + << "********** errors detected; see stdout for details ***********" + << std::endl; + } +#if !defined(BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE) + else { out << std::flush << "no errors detected" << std::endl; } +#endif + return result; + } // catch_exceptions + +} // boost + +#endif // BOOST_CATCH_EXCEPTIONS_HPP + diff --git a/src/ext/boost/detail/compressed_pair.hpp b/src/ext/boost/detail/compressed_pair.hpp new file mode 100644 index 00000000000..3f326456ce7 --- /dev/null +++ b/src/ext/boost/detail/compressed_pair.hpp @@ -0,0 +1,443 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// compressed_pair: pair that "compresses" empty members +// (see libs/utility/compressed_pair.htm) +// +// JM changes 25 Jan 2004: +// For the case where T1 == T2 and both are empty, then first() and second() +// should return different objects. +// JM changes 25 Jan 2000: +// Removed default arguments from compressed_pair_switch to get +// C++ Builder 4 to accept them +// rewriten swap to get gcc and C++ builder to compile. +// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs. + +#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP +#define BOOST_DETAIL_COMPRESSED_PAIR_HPP + +#include + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4512) +#endif +namespace boost +{ + +template +class compressed_pair; + + +// compressed_pair + +namespace details +{ + // JM altered 26 Jan 2000: + template + struct compressed_pair_switch; + + template + struct compressed_pair_switch + {static const int value = 0;}; + + template + struct compressed_pair_switch + {static const int value = 3;}; + + template + struct compressed_pair_switch + {static const int value = 1;}; + + template + struct compressed_pair_switch + {static const int value = 2;}; + + template + struct compressed_pair_switch + {static const int value = 4;}; + + template + struct compressed_pair_switch + {static const int value = 5;}; + + template class compressed_pair_imp; + +#ifdef __GNUC__ + // workaround for GCC (JM): + using std::swap; +#endif + // + // can't call unqualified swap from within classname::swap + // as Koenig lookup rules will find only the classname::swap + // member function not the global declaration, so use cp_swap + // as a forwarding function (JM): + template + inline void cp_swap(T& t1, T& t2) + { +#ifndef __GNUC__ + using std::swap; +#endif + swap(t1, t2); + } + + // 0 derive from neither + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + + // 1 derive from T1 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(second_, y.second()); + } + private: + second_type second_; + }; + + // 2 derive from T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : second_type(y), first_(x) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(first_, y.first()); + } + + private: + first_type first_; + }; + + // 3 derive from T1 and T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type, + protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_type(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + // + // no need to swap empty bases: + void swap(::boost::compressed_pair&) {} + }; + + // JM + // 4 T1 == T2, T1 and T2 both empty + // Originally this did not store an instance of T2 at all + // but that led to problems beause it meant &x.first() == &x.second() + // which is not true for any other kind of pair, so now we store an instance + // of T2 just in case the user is relying on first() and second() returning + // different objects (albeit both empty). + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), m_second(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x), m_second(x) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return m_second;} + second_const_reference second() const {return m_second;} + + void swap(::boost::compressed_pair&) {} + private: + T2 m_second; + }; + + // 5 T1 == T2 and are not empty: //JM + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x), second_(x) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + +} // details + +template +class compressed_pair + : private ::boost::details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> base; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} + explicit compressed_pair(first_param_type x) : base(x) {} + explicit compressed_pair(second_param_type y) : base(y) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(compressed_pair& y) { base::swap(y); } +}; + +// JM +// Partial specialisation for case where T1 == T2: +// +template +class compressed_pair + : private details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::is_empty::value, + ::boost::is_empty::value>::value> base; +public: + typedef T first_type; + typedef T second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} +#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) + explicit +#endif + compressed_pair(first_param_type x) : base(x) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(::boost::compressed_pair& y) { base::swap(y); } +}; + +template +inline +void +swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +} // boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP + diff --git a/src/ext/boost/detail/container_fwd.hpp b/src/ext/boost/detail/container_fwd.hpp new file mode 100644 index 00000000000..bc7f780b060 --- /dev/null +++ b/src/ext/boost/detail/container_fwd.hpp @@ -0,0 +1,99 @@ + +// Copyright 2005-2008 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_DETAIL_CONTAINER_FWD_HPP) +#define BOOST_DETAIL_CONTAINER_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include + +#if ((defined(__GLIBCPP__) || defined(__GLIBCXX__)) && defined(_GLIBCXX_DEBUG)) \ + || BOOST_WORKAROUND(__BORLANDC__, > 0x551) \ + || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \ + || (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) + +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include + +#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && \ + defined(__STL_CONFIG_H) + +#define BOOST_CONTAINER_FWD_BAD_BITSET + +#if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG) +#define BOOST_CONTAINER_FWD_BAD_DEQUE +#endif + +#endif + +#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE) +#include +#endif + +#if defined(BOOST_CONTAINER_FWD_BAD_BITSET) +#include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4099) // struct/class mismatch in fwd declarations +#endif + +namespace std +{ + template class allocator; + template class basic_string; + +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) + template struct string_char_traits; +#else + template struct char_traits; +#endif + + template class complex; +} + +// gcc 3.4 and greater +namespace std +{ +#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE) + template class deque; +#endif + + template class list; + template class vector; + template class map; + template + class multimap; + template class set; + template class multiset; + +#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET) + template class bitset; +#endif + template struct pair; +} + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif + +#endif diff --git a/src/ext/boost/detail/dynamic_bitset.hpp b/src/ext/boost/detail/dynamic_bitset.hpp new file mode 100644 index 00000000000..281aa55cd67 --- /dev/null +++ b/src/ext/boost/detail/dynamic_bitset.hpp @@ -0,0 +1,229 @@ +// ----------------------------------------------------------- +// +// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek +// Copyright (c) 2003-2006, 2008 Gennaro Prota +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// ----------------------------------------------------------- + +#ifndef BOOST_DETAIL_DYNAMIC_BITSET_HPP +#define BOOST_DETAIL_DYNAMIC_BITSET_HPP + +#include +#include "boost/config.hpp" +#include "boost/detail/workaround.hpp" + + +namespace boost { + + namespace detail { + namespace dynamic_bitset_impl { + + // Gives (read-)access to the object representation + // of an object of type T (3.9p4). CANNOT be used + // on a base sub-object + // + template + inline const unsigned char * object_representation (T* p) + { + return static_cast(static_cast(p)); + } + + template + struct shifter + { + static void left_shift(T & v) { + amount >= width ? (v = 0) + : (v >>= BOOST_DYNAMIC_BITSET_WRAP_CONSTANT(amount)); + } + }; + + // ------- count function implementation -------------- + + typedef unsigned char byte_type; + + // These two entities + // + // enum mode { access_by_bytes, access_by_blocks }; + // template struct mode_to_type {}; + // + // were removed, since the regression logs (as of 24 Aug 2008) + // showed that several compilers had troubles with recognizing + // + // const mode m = access_by_bytes + // + // as a constant expression + // + // * So, we'll use bool, instead of enum *. + // + template + struct value_to_type + { + value_to_type() {} + }; + const bool access_by_bytes = true; + const bool access_by_blocks = false; + + + // the table: wrapped in a class template, so + // that it is only instantiated if/when needed + // + template + struct count_table { static const byte_type table[]; }; + + template <> + struct count_table { /* no table */ }; + + + const unsigned int table_width = 8; + template + const byte_type count_table::table[] = + { + // Automatically generated by GPTableGen.exe v.1.0 + // + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + }; + + + // overload for access by bytes + // + + template + inline std::size_t do_count(Iterator first, std::size_t length, + int /*dummy param*/, + value_to_type* ) + { + std::size_t num = 0; + if (length) + { + const byte_type * p = object_representation(&*first); + length *= sizeof(*first); + + do { + num += count_table<>::table[*p]; + ++p; + --length; + + } while (length); + } + + return num; + } + + + // overload for access by blocks + // + template + inline std::size_t do_count(Iterator first, std::size_t length, ValueType, + value_to_type*) + { + std::size_t num = 0; + while (length){ + + ValueType value = *first; + while (value) { + num += count_table<>::table[value & ((1u<>= table_width; + } + + ++first; + --length; + } + + return num; + } + + // ------------------------------------------------------- + + + // Some library implementations simply return a dummy + // value such as + // + // size_type(-1) / sizeof(T) + // + // from vector<>::max_size. This tries to get more + // meaningful info. + // + template + typename T::size_type vector_max_size_workaround(const T & v) { + + typedef typename T::allocator_type allocator_type; + + const typename allocator_type::size_type alloc_max = + v.get_allocator().max_size(); + const typename T::size_type container_max = v.max_size(); + + return alloc_max < container_max? + alloc_max : + container_max; + } + + // for static_asserts + template + struct allowed_block_type { + enum { value = T(-1) > 0 }; // ensure T has no sign + }; + + template <> + struct allowed_block_type { + enum { value = false }; + }; + + + template + struct is_numeric { + enum { value = false }; + }; + +# define BOOST_dynamic_bitset_is_numeric(x) \ + template<> \ + struct is_numeric< x > { \ + enum { value = true }; \ + } /**/ + + BOOST_dynamic_bitset_is_numeric(bool); + BOOST_dynamic_bitset_is_numeric(char); + +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_dynamic_bitset_is_numeric(wchar_t); +#endif + + BOOST_dynamic_bitset_is_numeric(signed char); + BOOST_dynamic_bitset_is_numeric(short int); + BOOST_dynamic_bitset_is_numeric(int); + BOOST_dynamic_bitset_is_numeric(long int); + + BOOST_dynamic_bitset_is_numeric(unsigned char); + BOOST_dynamic_bitset_is_numeric(unsigned short); + BOOST_dynamic_bitset_is_numeric(unsigned int); + BOOST_dynamic_bitset_is_numeric(unsigned long); + +#if defined(BOOST_HAS_LONG_LONG) + BOOST_dynamic_bitset_is_numeric(::boost::long_long_type); + BOOST_dynamic_bitset_is_numeric(::boost::ulong_long_type); +#endif + + // intentionally omitted + //BOOST_dynamic_bitset_is_numeric(float); + //BOOST_dynamic_bitset_is_numeric(double); + //BOOST_dynamic_bitset_is_numeric(long double); + +#undef BOOST_dynamic_bitset_is_numeric + + } // dynamic_bitset_impl + } // namespace detail + +} // namespace boost + +#endif // include guard + diff --git a/src/ext/boost/detail/endian.hpp b/src/ext/boost/detail/endian.hpp new file mode 100644 index 00000000000..36ddb7e1e5d --- /dev/null +++ b/src/ext/boost/detail/endian.hpp @@ -0,0 +1,73 @@ +// Copyright 2005 Caleb Epstein +// Copyright 2006 John Maddock +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* + * Copyright notice reproduced from , from + * which this code was originally taken. + * + * Modified by Caleb Epstein to use with GNU libc and to + * defined the BOOST_ENDIAN macro. + */ + +#ifndef BOOST_DETAIL_ENDIAN_HPP +#define BOOST_DETAIL_ENDIAN_HPP + +// GNU libc offers the helpful header which defines +// __BYTE_ORDER + +#if defined (__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define BOOST_LITTLE_ENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define BOOST_BIG_ENDIAN +# elif (__BYTE_ORDER == __PDP_ENDIAN) +# define BOOST_PDP_ENDIAN +# else +# error Unknown machine endianness detected. +# endif +# define BOOST_BYTE_ORDER __BYTE_ORDER +#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define BOOST_BIG_ENDIAN +# define BOOST_BYTE_ORDER 4321 +#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define BOOST_LITTLE_ENDIAN +# define BOOST_BYTE_ORDER 1234 +#elif defined(__sparc) || defined(__sparc__) \ + || defined(_POWER) || defined(__powerpc__) \ + || defined(__ppc__) || defined(__hpux) || defined(__hppa) \ + || defined(_MIPSEB) || defined(_POWER) \ + || defined(__s390__) +# define BOOST_BIG_ENDIAN +# define BOOST_BYTE_ORDER 4321 +#elif defined(__i386__) || defined(__alpha__) \ + || defined(__ia64) || defined(__ia64__) \ + || defined(_M_IX86) || defined(_M_IA64) \ + || defined(_M_ALPHA) || defined(__amd64) \ + || defined(__amd64__) || defined(_M_AMD64) \ + || defined(__x86_64) || defined(__x86_64__) \ + || defined(_M_X64) || defined(__bfin__) + +# define BOOST_LITTLE_ENDIAN +# define BOOST_BYTE_ORDER 1234 +#else +# error The file boost/detail/endian.hpp needs to be set up for your CPU type. +#endif + + +#endif diff --git a/src/ext/boost/detail/has_default_constructor.hpp b/src/ext/boost/detail/has_default_constructor.hpp new file mode 100644 index 00000000000..319b30abcd0 --- /dev/null +++ b/src/ext/boost/detail/has_default_constructor.hpp @@ -0,0 +1,29 @@ + +// (C) Copyright Matthias Troyerk 2006. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/type_traits for most recent version including documentation. + +#ifndef BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED +#define BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED + +#include + +namespace boost { namespace detail { + +/// type trait to check for a default constructor +/// +/// The default implementation just checks for a trivial constructor. +/// Using some compiler magic it might be possible to provide a better default + +template +struct has_default_constructor + : public has_trivial_constructor +{}; + +} } // namespace boost::detail + + +#endif // BOOST_DETAIL_HAS_DEFAULT_CONSTRUCTOR_HPP_INCLUDED diff --git a/src/ext/boost/detail/identifier.hpp b/src/ext/boost/detail/identifier.hpp new file mode 100644 index 00000000000..688a664f7d9 --- /dev/null +++ b/src/ext/boost/detail/identifier.hpp @@ -0,0 +1,89 @@ +// boost/identifier.hpp ----------------------------------------------------// + +// Copyright Beman Dawes 2006 + +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See documentation at http://www.boost.org/libs/utility + +#ifndef BOOST_IDENTIFIER_HPP +#define BOOST_IDENTIFIER_HPP + +#include +#include +#include + +namespace boost +{ + namespace detail + { + // class template identifier ---------------------------------------------// + + // Always used as a base class so that different instantiations result in + // different class types even if instantiated with the same value type T. + + // Expected usage is that T is often an integer type, best passed by + // value. There is no reason why T can't be a possibly larger class such as + // std::string, best passed by const reference. + + // This implementation uses pass by value, based on expected common uses. + + template + class identifier + { + public: + typedef T value_type; + + const value_type value() const { return m_value; } + void assign( value_type v ) { m_value = v; } + + bool operator==( const D & rhs ) const { return m_value == rhs.m_value; } + bool operator!=( const D & rhs ) const { return m_value != rhs.m_value; } + bool operator< ( const D & rhs ) const { return m_value < rhs.m_value; } + bool operator<=( const D & rhs ) const { return m_value <= rhs.m_value; } + bool operator> ( const D & rhs ) const { return m_value > rhs.m_value; } + bool operator>=( const D & rhs ) const { return m_value >= rhs.m_value; } + + typedef void (*unspecified_bool_type)(D); // without the D, unspecified_bool_type + static void unspecified_bool_true(D){} // conversion allows relational operators + // between different identifier types + + operator unspecified_bool_type() const { return m_value == value_type() ? 0 : unspecified_bool_true; } + bool operator!() const { return m_value == value_type(); } + + // constructors are protected so that class can only be used as a base class + protected: + identifier() {} + explicit identifier( value_type v ) : m_value(v) {} + + #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // 1300 == VC++ 7.0 bug workaround + private: + #endif + T m_value; + }; + + //#ifndef BOOST_NO_SFINAE + + // template + // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, + // Ostream & >::type operator<<( Ostream & os, const Id & id ) + // { + // return os << id.value(); + // } + + // template + // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, + // Istream & >::type operator>>( Istream & is, Id & id ) + // { + // typename Id::value_type v; + // is >> v; + // id.value( v ); + // return is; + // } + //#endif + + } // namespace detail +} // namespace boost + +#endif // BOOST_IDENTIFIER_HPP diff --git a/src/ext/boost/detail/indirect_traits.hpp b/src/ext/boost/detail/indirect_traits.hpp new file mode 100644 index 00000000000..f9c0cd6a04c --- /dev/null +++ b/src/ext/boost/detail/indirect_traits.hpp @@ -0,0 +1,487 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef INDIRECT_TRAITS_DWA2002131_HPP +# define INDIRECT_TRAITS_DWA2002131_HPP +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +# include +# include +# include +# include +# include +# include + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# endif + +namespace boost { namespace detail { + +namespace indirect_traits { + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct is_reference_to_const : mpl::false_ +{ +}; + +template +struct is_reference_to_const : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_const : mpl::true_ +{ +}; +# endif + +template +struct is_reference_to_function : mpl::false_ +{ +}; + +template +struct is_reference_to_function : is_function +{ +}; + +template +struct is_pointer_to_function : mpl::false_ +{ +}; + +// There's no such thing as a pointer-to-cv-function, so we don't need +// specializations for those +template +struct is_pointer_to_function : is_function +{ +}; + +template +struct is_reference_to_member_function_pointer_impl : mpl::false_ +{ +}; + +template +struct is_reference_to_member_function_pointer_impl + : is_member_function_pointer::type> +{ +}; + + +template +struct is_reference_to_member_function_pointer + : is_reference_to_member_function_pointer_impl +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + +template +struct is_reference_to_function_pointer_aux + : mpl::and_< + is_reference + , is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those +}; + +template +struct is_reference_to_function_pointer + : mpl::if_< + is_reference_to_function + , mpl::false_ + , is_reference_to_function_pointer_aux + >::type +{ +}; + +template +struct is_reference_to_non_const + : mpl::and_< + is_reference + , mpl::not_< + is_reference_to_const + > + > +{ +}; + +template +struct is_reference_to_volatile : mpl::false_ +{ +}; + +template +struct is_reference_to_volatile : mpl::true_ +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_volatile : mpl::true_ +{ +}; +# endif + + +template +struct is_reference_to_pointer : mpl::false_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_pointer : mpl::true_ +{ +}; + +template +struct is_reference_to_class + : mpl::and_< + is_reference + , is_class< + typename remove_cv< + typename remove_reference::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) +}; + +template +struct is_pointer_to_class + : mpl::and_< + is_pointer + , is_class< + typename remove_cv< + typename remove_pointer::type + >::type + > + > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T)) +}; + +# else + +using namespace boost::detail::is_function_ref_tester_; + +typedef char (&inner_yes_type)[3]; +typedef char (&inner_no_type)[2]; +typedef char (&outer_no_type)[1]; + +template +struct is_const_help +{ + typedef typename mpl::if_< + is_const + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_volatile_help +{ + typedef typename mpl::if_< + is_volatile + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_pointer_help +{ + typedef typename mpl::if_< + is_pointer + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_class_help +{ + typedef typename mpl::if_< + is_class + , inner_yes_type + , inner_no_type + >::type type; +}; + +template +struct is_reference_to_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value = sizeof(detail::is_function_ref_tester(t,0)) == sizeof(::boost::type_traits::yes_type)); + typedef mpl::bool_ type; + }; + +template +struct is_reference_to_function + : mpl::if_, is_reference_to_function_aux, mpl::bool_ >::type +{ +}; + +template +struct is_pointer_to_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(::boost::type_traits::is_function_ptr_tester(t)) == sizeof(::boost::type_traits::yes_type)); + typedef mpl::bool_ type; +}; + +template +struct is_pointer_to_function + : mpl::if_, is_pointer_to_function_aux, mpl::bool_ >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_function,(T)) +}; + +struct false_helper1 +{ + template + struct apply : mpl::false_ + { + }; +}; + +template +typename is_const_help::type reference_to_const_helper(V&); +outer_no_type +reference_to_const_helper(...); + +struct true_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; + }; +}; + +template +struct is_reference_to_const_helper1 : true_helper1 +{ +}; + +template <> +struct is_reference_to_const_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_const + : is_reference_to_const_helper1::value>::template apply +{ +}; + + +template +struct is_reference_to_non_const_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_const_helper(t)) == sizeof(inner_no_type)); + + typedef mpl::bool_ type; + }; +}; + +template <> +struct is_reference_to_non_const_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_non_const + : is_reference_to_non_const_helper1::value>::template apply +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_non_const,(T)) +}; + + +template +typename is_volatile_help::type reference_to_volatile_helper(V&); +outer_no_type +reference_to_volatile_helper(...); + +template +struct is_reference_to_volatile_helper1 +{ + template + struct apply + { + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof(reference_to_volatile_helper(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; + }; +}; + +template <> +struct is_reference_to_volatile_helper1 : false_helper1 +{ +}; + + +template +struct is_reference_to_volatile + : is_reference_to_volatile_helper1::value>::template apply +{ +}; + +template +typename is_pointer_help::type reference_to_pointer_helper(V&); +outer_no_type reference_to_pointer_helper(...); + +template +struct reference_to_pointer_impl +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (sizeof((reference_to_pointer_helper)(t)) == sizeof(inner_yes_type)) + ); + + typedef mpl::bool_ type; +}; + +template +struct is_reference_to_pointer + : mpl::eval_if, reference_to_pointer_impl, mpl::false_>::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_pointer,(T)) +}; + +template +struct is_reference_to_function_pointer + : mpl::eval_if, is_pointer_to_function_aux, mpl::false_>::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_function_pointer,(T)) +}; + + +template +struct is_member_function_pointer_help + : mpl::if_, inner_yes_type, inner_no_type> +{}; + +template +typename is_member_function_pointer_help::type member_function_pointer_helper(V&); +outer_no_type member_function_pointer_helper(...); + +template +struct is_pointer_to_member_function_aux +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = sizeof((member_function_pointer_helper)(t)) == sizeof(inner_yes_type)); + typedef mpl::bool_ type; +}; + +template +struct is_reference_to_member_function_pointer + : mpl::if_< + is_reference + , is_pointer_to_member_function_aux + , mpl::bool_ + >::type +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T)) +}; + +template +typename is_class_help::type reference_to_class_helper(V const volatile&); +outer_no_type reference_to_class_helper(...); + +template +struct is_reference_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_reference::value + & (sizeof(reference_to_class_helper(t)) == sizeof(inner_yes_type))) + ); + typedef mpl::bool_ type; + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T)) +}; + +template +typename is_class_help::type pointer_to_class_helper(V const volatile*); +outer_no_type pointer_to_class_helper(...); + +template +struct is_pointer_to_class +{ + static T t; + BOOST_STATIC_CONSTANT( + bool, value + = (is_pointer::value + && sizeof(pointer_to_class_helper(t)) == sizeof(inner_yes_type)) + ); + typedef mpl::bool_ type; +}; +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +} + +using namespace indirect_traits; + +}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/src/ext/boost/detail/interlocked.hpp b/src/ext/boost/detail/interlocked.hpp new file mode 100644 index 00000000000..fccebc3f707 --- /dev/null +++ b/src/ext/boost/detail/interlocked.hpp @@ -0,0 +1,142 @@ +#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED +#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/interlocked.hpp +// +// Copyright 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer + +#elif defined(_WIN32_WCE) + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +#if defined( __CLRCALL_PURE_OR_CDECL ) + +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +#else + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +#endif + +# pragma intrinsic( _InterlockedIncrement ) +# pragma intrinsic( _InterlockedDecrement ) +# pragma intrinsic( _InterlockedCompareExchange ) +# pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedExchangeAdd ) + +# if defined(_M_IA64) || defined(_M_AMD64) + +extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); + +# pragma intrinsic( _InterlockedCompareExchangePointer ) +# pragma intrinsic( _InterlockedExchangePointer ) + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED diff --git a/src/ext/boost/detail/is_function_ref_tester.hpp b/src/ext/boost/detail/is_function_ref_tester.hpp new file mode 100644 index 00000000000..5f367ea8189 --- /dev/null +++ b/src/ext/boost/detail/is_function_ref_tester.hpp @@ -0,0 +1,135 @@ + +// (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, +// Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(BOOST_PP_IS_ITERATING) + +///// header body + +#ifndef BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED +#define BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +#include "boost/type_traits/detail/yes_no_type.hpp" +#include "boost/type_traits/config.hpp" + +#if defined(BOOST_TT_PREPROCESSING_MODE) +# include "boost/preprocessor/iterate.hpp" +# include "boost/preprocessor/enum_params.hpp" +# include "boost/preprocessor/comma_if.hpp" +#endif + +namespace boost { +namespace detail { +namespace is_function_ref_tester_ { + +template +boost::type_traits::no_type BOOST_TT_DECL is_function_ref_tester(T& ...); + +#if !defined(BOOST_TT_PREPROCESSING_MODE) +// preprocessor-generated part, don't edit by hand! + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23), int); + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,T20,T21,T22,T23,T24), int); + +#else + +#define BOOST_PP_ITERATION_PARAMS_1 \ + (3, (0, 25, "boost/type_traits/detail/is_function_ref_tester.hpp")) +#include BOOST_PP_ITERATE() + +#endif // BOOST_TT_PREPROCESSING_MODE + +} // namespace detail +} // namespace python +} // namespace boost + +#endif // BOOST_DETAIL_IS_FUNCTION_REF_TESTER_HPP_INCLUDED + +///// iteration + +#else +#define i BOOST_PP_FRAME_ITERATION(1) + +template +boost::type_traits::yes_type is_function_ref_tester(R (&)(BOOST_PP_ENUM_PARAMS(i,T)), int); + +#undef i +#endif // BOOST_PP_IS_ITERATING diff --git a/src/ext/boost/detail/is_incrementable.hpp b/src/ext/boost/detail/is_incrementable.hpp new file mode 100644 index 00000000000..1c8fd5785b5 --- /dev/null +++ b/src/ext/boost/detail/is_incrementable.hpp @@ -0,0 +1,134 @@ +// Copyright David Abrahams 2004. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_INCREMENTABLE_DWA200415_HPP +# define IS_INCREMENTABLE_DWA200415_HPP + +# include +# include +# include +# include +# include + +// Must be the last include +# include + +namespace boost { namespace detail { + +// is_incrementable metafunction +// +// Requires: Given x of type T&, if the expression ++x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_incrementable_ +{ + // a type returned from operator++ when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator++ less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator++ for when none other is found +# if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 + +} + +namespace is_incrementable_2 +{ + is_incrementable_::tag operator++(is_incrementable_::any const&); + is_incrementable_::tag operator++(is_incrementable_::any const&,int); +} +using namespace is_incrementable_2; + +namespace is_incrementable_ +{ + +# else + + tag operator++(any const&); + tag operator++(any const&,int); + +# endif + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \ + || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4913) // Warning about operator, +# endif + + // two check overloads help us identify which operator++ was picked + char (& check(tag) )[2]; + + template + char check(T const&); + + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check(BOOST_comma(++x,0))) == 1 + ); + }; + + template + struct postfix_impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check(BOOST_comma(x++,0))) == 1 + ); + }; + +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif + +} + +# undef BOOST_comma + +template +struct is_incrementable +BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl::value) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::impl::value) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_incrementable,(T)) +}; + +template +struct is_postfix_incrementable +BOOST_TT_AUX_BOOL_C_BASE(::boost::detail::is_incrementable_::impl::value) +{ + BOOST_TT_AUX_BOOL_TRAIT_VALUE_DECL(::boost::detail::is_incrementable_::postfix_impl::value) + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_postfix_incrementable,(T)) +}; + +} // namespace detail + +BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_incrementable) +BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1, ::boost::detail::is_postfix_incrementable) + +} // namespace boost + +# include + +#endif // IS_INCREMENTABLE_DWA200415_HPP diff --git a/src/ext/boost/detail/is_xxx.hpp b/src/ext/boost/detail/is_xxx.hpp new file mode 100644 index 00000000000..cb64fb32b81 --- /dev/null +++ b/src/ext/boost/detail/is_xxx.hpp @@ -0,0 +1,61 @@ +// Copyright David Abrahams 2005. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_DETAIL_IS_XXX_DWA20051011_HPP +# define BOOST_DETAIL_IS_XXX_DWA20051011_HPP + +# include +# include +# include + +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include +# include + +# define BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) \ +template \ +struct is_##name \ +{ \ + typedef char yes; \ + typedef char (&no)[2]; \ + \ + static typename add_reference::type dummy; \ + \ + struct helpers \ + { \ + template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class U) > \ + static yes test( \ + qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, U) >&, int \ + ); \ + \ + template \ + static no test(U&, ...); \ + }; \ + \ + BOOST_STATIC_CONSTANT( \ + bool, value \ + = !is_reference::value \ + & (sizeof(helpers::test(dummy, 0)) == sizeof(yes))); \ + \ + typedef mpl::bool_ type; \ +}; + +# else + +# define BOOST_DETAIL_IS_XXX_DEF(name, qualified_name, nargs) \ +template \ +struct is_##name : mpl::false_ \ +{ \ +}; \ + \ +template < BOOST_PP_ENUM_PARAMS_Z(1, nargs, class T) > \ +struct is_##name< \ + qualified_name< BOOST_PP_ENUM_PARAMS_Z(1, nargs, T) > \ +> \ + : mpl::true_ \ +{ \ +}; + +# endif + +#endif // BOOST_DETAIL_IS_XXX_DWA20051011_HPP diff --git a/src/ext/boost/detail/iterator.hpp b/src/ext/boost/detail/iterator.hpp new file mode 100644 index 00000000000..5bb9c6269cf --- /dev/null +++ b/src/ext/boost/detail/iterator.hpp @@ -0,0 +1,494 @@ +// (C) Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Boost versions of +// +// std::iterator_traits<>::iterator_category +// std::iterator_traits<>::difference_type +// std::distance() +// +// ...for all compilers and iterators +// +// Additionally, if X is a pointer +// std::iterator_traits::pointer + +// Otherwise, if partial specialization is supported or X is not a pointer +// std::iterator_traits::value_type +// std::iterator_traits::pointer +// std::iterator_traits::reference +// +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 04 Mar 2001 - More attempted fixes for Intel C++ (David Abrahams) +// 03 Mar 2001 - Put all implementation into namespace +// boost::detail::iterator_traits_. Some progress made on fixes +// for Intel compiler. (David Abrahams) +// 02 Mar 2001 - Changed BOOST_MSVC to BOOST_MSVC_STD_ITERATOR in a few +// places. (Jeremy Siek) +// 19 Feb 2001 - Improved workarounds for stock MSVC6; use yes_type and +// no_type from type_traits.hpp; stopped trying to remove_cv +// before detecting is_pointer, in honor of the new type_traits +// semantics. (David Abrahams) +// 13 Feb 2001 - Make it work with nearly all standard-conforming iterators +// under raw VC6. The one category remaining which will fail is +// that of iterators derived from std::iterator but not +// boost::iterator and which redefine difference_type. +// 11 Feb 2001 - Clean away code which can never be used (David Abrahams) +// 09 Feb 2001 - Always have a definition for each traits member, even if it +// can't be properly deduced. These will be incomplete types in +// some cases (undefined), but it helps suppress MSVC errors +// elsewhere (David Abrahams) +// 07 Feb 2001 - Support for more of the traits members where possible, making +// this useful as a replacement for std::iterator_traits when +// used as a default template parameter. +// 06 Feb 2001 - Removed useless #includes of standard library headers +// (David Abrahams) + +#ifndef ITERATOR_DWA122600_HPP_ +# define ITERATOR_DWA122600_HPP_ + +# include +# include + +// STLPort 4.0 and betas have a bug when debugging is enabled and there is no +// partial specialization: instead of an iterator_category typedef, the standard +// container iterators have _Iterator_category. +// +// Also, whether debugging is enabled or not, there is a broken specialization +// of std::iterator which has no +// typedefs but iterator_category. +# if defined(__SGI_STL_PORT) + +# if (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && defined(__STL_DEBUG) +# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# endif + +# define BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +# endif // STLPort <= 4.1b4 && no partial specialization + +# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \ + && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MSVC_STD_ITERATOR) + +namespace boost { namespace detail { + +// Define a new template so it can be specialized +template +struct iterator_traits + : std::iterator_traits +{}; +using std::distance; + +}} // namespace boost::detail + +# else + +# if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_MSVC_STD_ITERATOR) + +// This is the case where everything conforms except BOOST_NO_STD_ITERATOR_TRAITS + +namespace boost { namespace detail { + +// Rogue Wave Standard Library fools itself into thinking partial +// specialization is missing on some platforms (e.g. Sun), so fails to +// supply iterator_traits! +template +struct iterator_traits +{ + typedef typename Iterator::value_type value_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct iterator_traits +{ + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; + +template +struct iterator_traits +{ + typedef T value_type; + typedef T const& reference; + typedef T const* pointer; + typedef std::ptrdiff_t difference_type; + typedef std::random_access_iterator_tag iterator_category; +}; + +}} // namespace boost::detail + +# else + +# include +# include +# include + +# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +# include +# include +# endif +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +# include +# endif + +# include +# include +# include + +// should be the last #include +# include "boost/type_traits/detail/bool_trait_def.hpp" + +namespace boost { namespace detail { + +BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(reference) +BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer) +BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type) +BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category) + +// is_mutable_iterator -- +// +// A metafunction returning true iff T is a mutable iterator type +// with a nested value_type. Will only work portably with iterators +// whose operator* returns a reference, but that seems to be OK for +// the iterators supplied by Dinkumware. Some input iterators may +// compile-time if they arrive here, and if the compiler is strict +// about not taking the address of an rvalue. + +// This one detects ordinary mutable iterators - the result of +// operator* is convertible to the value_type. +template +type_traits::yes_type is_mutable_iterator_helper(T const*, BOOST_DEDUCED_TYPENAME T::value_type*); + +// Since you can't take the address of an rvalue, the guts of +// is_mutable_iterator_impl will fail if we use &*t directly. This +// makes sure we can still work with non-lvalue iterators. +template T* mutable_iterator_lvalue_helper(T& x); +int mutable_iterator_lvalue_helper(...); + + +// This one detects output iterators such as ostream_iterator which +// return references to themselves. +template +type_traits::yes_type is_mutable_iterator_helper(T const*, T const*); + +type_traits::no_type is_mutable_iterator_helper(...); + +template +struct is_mutable_iterator_impl +{ + static T t; + + BOOST_STATIC_CONSTANT( + bool, value = sizeof( + detail::is_mutable_iterator_helper( + (T*)0 + , mutable_iterator_lvalue_helper(*t) // like &*t + )) + == sizeof(type_traits::yes_type) + ); +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl::value) + + +// is_full_iterator_traits -- +// +// A metafunction returning true iff T has all the requisite nested +// types to satisfy the requirements for a fully-conforming +// iterator_traits implementation. +template +struct is_full_iterator_traits_impl +{ + enum { value = + has_value_type::value + & has_reference::value + & has_pointer::value + & has_difference_type::value + & has_iterator_category::value + }; +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl::value) + + +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +BOOST_MPL_HAS_XXX_TRAIT_DEF(_Iterator_category) + +// is_stlport_40_debug_iterator -- +// +// A metafunction returning true iff T has all the requisite nested +// types to satisfy the requirements of an STLPort 4.0 debug iterator +// iterator_traits implementation. +template +struct is_stlport_40_debug_iterator_impl +{ + enum { value = + has_value_type::value + & has_reference::value + & has_pointer::value + & has_difference_type::value + & has__Iterator_category::value + }; +}; + +BOOST_TT_AUX_BOOL_TRAIT_DEF1( + is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl::value) + +template +struct stlport_40_debug_iterator_traits +{ + typedef typename T::value_type value_type; + typedef typename T::reference reference; + typedef typename T::pointer pointer; + typedef typename T::difference_type difference_type; + typedef typename T::_Iterator_category iterator_category; +}; +# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + +template struct pointer_iterator_traits; + +# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION +template +struct pointer_iterator_traits +{ + typedef typename remove_const::type value_type; + typedef T* pointer; + typedef T& reference; + typedef std::random_access_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; +}; +# else + +// In case of no template partial specialization, and if T is a +// pointer, iterator_traits::value_type can still be computed. For +// some basic types, remove_pointer is manually defined in +// type_traits/broken_compiler_spec.hpp. For others, do it yourself. + +template class please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee; + +template +struct pointer_value_type + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_const< + typename remove_pointer

::type + >::type + > +{ +}; + + +template +struct pointer_reference + : mpl::if_< + is_same::type> + , please_invoke_BOOST_TT_BROKEN_COMPILER_SPEC_on_cv_unqualified_pointee

+ , typename remove_pointer

::type& + > +{ +}; + +template +struct pointer_iterator_traits +{ + typedef T pointer; + typedef std::random_access_iterator_tag iterator_category; + typedef std::ptrdiff_t difference_type; + + typedef typename pointer_value_type::type value_type; + typedef typename pointer_reference::type reference; +}; + +# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +// We'll sort iterator types into one of these classifications, from which we +// can determine the difference_type, pointer, reference, and value_type +template +struct standard_iterator_traits +{ + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; + typedef typename Iterator::iterator_category iterator_category; +}; + +template +struct msvc_stdlib_mutable_traits + : std::iterator_traits +{ + typedef typename std::iterator_traits::distance_type difference_type; + typedef typename std::iterator_traits::value_type* pointer; + typedef typename std::iterator_traits::value_type& reference; +}; + +template +struct msvc_stdlib_const_traits + : std::iterator_traits +{ + typedef typename std::iterator_traits::distance_type difference_type; + typedef const typename std::iterator_traits::value_type* pointer; + typedef const typename std::iterator_traits::value_type& reference; +}; + +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION +template +struct is_bad_output_iterator + : is_base_and_derived< + std::iterator + , Iterator> +{ +}; + +struct bad_output_iterator_traits +{ + typedef void value_type; + typedef void difference_type; + typedef std::output_iterator_tag iterator_category; + typedef void pointer; + typedef void reference; +}; +# endif + +// If we're looking at an MSVC6 (old Dinkumware) ``standard'' +// iterator, this will generate an appropriate traits class. +template +struct msvc_stdlib_iterator_traits + : mpl::if_< + is_mutable_iterator + , msvc_stdlib_mutable_traits + , msvc_stdlib_const_traits + >::type +{}; + +template +struct non_pointer_iterator_traits + : mpl::if_< + // if the iterator contains all the right nested types... + is_full_iterator_traits + // Use a standard iterator_traits implementation + , standard_iterator_traits +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + // Check for STLPort 4.0 broken _Iterator_category type + , mpl::if_< + is_stlport_40_debug_iterator + , stlport_40_debug_iterator_traits +# endif + // Otherwise, assume it's a Dinkum iterator + , msvc_stdlib_iterator_traits +# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF + >::type +# endif + >::type +{ +}; + +template +struct iterator_traits_aux + : mpl::if_< + is_pointer + , pointer_iterator_traits + , non_pointer_iterator_traits + >::type +{ +}; + +template +struct iterator_traits +{ + // Explicit forwarding from base class needed to keep MSVC6 happy + // under some circumstances. + private: +# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + typedef + typename mpl::if_< + is_bad_output_iterator + , bad_output_iterator_traits + , iterator_traits_aux + >::type base; +# else + typedef iterator_traits_aux base; +# endif + public: + typedef typename base::value_type value_type; + typedef typename base::pointer pointer; + typedef typename base::reference reference; + typedef typename base::difference_type difference_type; + typedef typename base::iterator_category iterator_category; +}; + +// This specialization cuts off ETI (Early Template Instantiation) for MSVC. +template <> struct iterator_traits +{ + typedef int value_type; + typedef int pointer; + typedef int reference; + typedef int difference_type; + typedef int iterator_category; +}; + +}} // namespace boost::detail + +# endif // workarounds + +namespace boost { namespace detail { + +namespace iterator_traits_ +{ + template + struct distance_select + { + static Difference execute(Iterator i1, const Iterator i2, ...) + { + Difference result = 0; + while (i1 != i2) + { + ++i1; + ++result; + } + return result; + } + + static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*) + { + return i2 - i1; + } + }; +} // namespace boost::detail::iterator_traits_ + +template +inline typename iterator_traits::difference_type +distance(Iterator first, Iterator last) +{ + typedef typename iterator_traits::difference_type diff_t; + typedef typename ::boost::detail::iterator_traits::iterator_category iterator_category; + + return iterator_traits_::distance_select::execute( + first, last, (iterator_category*)0); +} + +}} + +# endif + + +# undef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF +# undef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION + +#endif // ITERATOR_DWA122600_HPP_ diff --git a/src/ext/boost/detail/lcast_precision.hpp b/src/ext/boost/detail/lcast_precision.hpp new file mode 100644 index 00000000000..d40ca21eb3c --- /dev/null +++ b/src/ext/boost/detail/lcast_precision.hpp @@ -0,0 +1,184 @@ +// Copyright Alexander Nasonov & Paul A. Bristow 2006. + +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED +#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + +#include +#include +#include + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT +// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL +#include +#include +#endif + +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \ + (defined(BOOST_MSVC) && (BOOST_MSVC<1310)) + +#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#endif + +#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#include +#else +#include +#endif + +namespace boost { namespace detail { + +class lcast_abstract_stub {}; + +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +// Calculate an argument to pass to std::ios_base::precision from +// lexical_cast. See alternative implementation for broken standard +// libraries in lcast_get_precision below. Keep them in sync, please. +template +struct lcast_precision +{ +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + BOOST_STATIC_CONSTANT(bool, use_default_precision = + !limits::is_specialized || limits::is_exact + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_bin = + !use_default_precision && + limits::radix == 2 && limits::digits > 0 + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_dec = + !use_default_precision && + limits::radix == 10 && limits::digits10 > 0 + ); + + BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max = + boost::integer_traits::const_max + ); + + BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U); + + BOOST_STATIC_ASSERT(!is_specialized_dec || + precision_dec <= streamsize_max + 0UL + ); + + BOOST_STATIC_CONSTANT(unsigned long, precision_bin = + 2UL + limits::digits * 30103UL / 100000UL + ); + + BOOST_STATIC_ASSERT(!is_specialized_bin || + (limits::digits + 0UL < ULONG_MAX / 30103UL && + precision_bin > limits::digits10 + 0UL && + precision_bin <= streamsize_max + 0UL) + ); + + BOOST_STATIC_CONSTANT(std::streamsize, value = + is_specialized_bin ? precision_bin + : is_specialized_dec ? precision_dec : 6 + ); +}; +#endif + +template +inline std::streamsize lcast_get_precision(T* = 0) +{ +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION + return lcast_precision::value; +#else // Follow lcast_precision algorithm at run-time: + +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_< + boost::is_abstract + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + bool const use_default_precision = + !limits::is_specialized || limits::is_exact; + + if(!use_default_precision) + { // Includes all built-in floating-point types, float, double ... + // and UDT types for which digits (significand bits) is defined (not zero) + + bool const is_specialized_bin = + limits::radix == 2 && limits::digits > 0; + bool const is_specialized_dec = + limits::radix == 10 && limits::digits10 > 0; + std::streamsize const streamsize_max = + (boost::integer_traits::max)(); + + if(is_specialized_bin) + { // Floating-point types with + // limits::digits defined by the specialization. + + unsigned long const digits = limits::digits; + unsigned long const precision = 2UL + digits * 30103UL / 100000UL; + // unsigned long is selected because it is at least 32-bits + // and thus ULONG_MAX / 30103UL is big enough for all types. + BOOST_ASSERT( + digits < ULONG_MAX / 30103UL && + precision > limits::digits10 + 0UL && + precision <= streamsize_max + 0UL + ); + return precision; + } + else if(is_specialized_dec) + { // Decimal Floating-point type, most likely a User Defined Type + // rather than a real floating-point hardware type. + unsigned int const precision = limits::digits10 + 1U; + BOOST_ASSERT(precision <= streamsize_max + 0UL); + return precision; + } + } + + // Integral type (for which precision has no effect) + // or type T for which limits is NOT specialized, + // so assume stream precision remains the default 6 decimal digits. + // Warning: if your User-defined Floating-point type T is NOT specialized, + // then you may lose accuracy by only using 6 decimal digits. + // To avoid this, you need to specialize T with either + // radix == 2 and digits == the number of significand bits, + // OR + // radix = 10 and digits10 == the number of decimal digits. + + return 6; +#endif +} + +template +inline void lcast_set_precision(std::ios_base& stream, T*) +{ + stream.precision(lcast_get_precision()); +} + +template +inline void lcast_set_precision(std::ios_base& stream, Source*, Target*) +{ + std::streamsize const s = lcast_get_precision((Source*)0); + std::streamsize const t = lcast_get_precision((Target*)0); + stream.precision(s > t ? s : t); +} + +}} + +#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + diff --git a/src/ext/boost/detail/lightweight_mutex.hpp b/src/ext/boost/detail/lightweight_mutex.hpp new file mode 100644 index 00000000000..b7a7f6dd4ed --- /dev/null +++ b/src/ext/boost/detail/lightweight_mutex.hpp @@ -0,0 +1,22 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_mutex.hpp - lightweight mutex +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED diff --git a/src/ext/boost/detail/lightweight_test.hpp b/src/ext/boost/detail/lightweight_test.hpp new file mode 100644 index 00000000000..ffa750d324e --- /dev/null +++ b/src/ext/boost/detail/lightweight_test.hpp @@ -0,0 +1,91 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_test.hpp - lightweight test library +// +// Copyright (c) 2002, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// BOOST_TEST(expression) +// BOOST_ERROR(message) +// BOOST_TEST_EQ(expr1, expr2) +// +// int boost::report_errors() +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline int & test_errors() +{ + static int x = 0; + return x; +} + +inline void test_failed_impl(char const * expr, char const * file, int line, char const * function) +{ + std::cerr << file << "(" << line << "): test '" << expr << "' failed in function '" << function << "'" << std::endl; + ++test_errors(); +} + +inline void error_impl(char const * msg, char const * file, int line, char const * function) +{ + std::cerr << file << "(" << line << "): " << msg << " in function '" << function << "'" << std::endl; + ++test_errors(); +} + +template inline void test_eq_impl( char const * expr1, char const * expr2, char const * file, int line, char const * function, T const & t, U const & u ) +{ + if( t == u ) + { + } + else + { + std::cerr << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " + << "'" << t << "' != '" << u << "'" << std::endl; + ++test_errors(); + } +} + +} // namespace detail + +inline int report_errors() +{ + int errors = detail::test_errors(); + + if( errors == 0 ) + { + std::cerr << "No errors detected." << std::endl; + return 0; + } + else + { + std::cerr << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl; + return 1; + } +} + +} // namespace boost + +#define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) +#define BOOST_ERROR(msg) ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) +#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED diff --git a/src/ext/boost/detail/lightweight_thread.hpp b/src/ext/boost/detail/lightweight_thread.hpp new file mode 100644 index 00000000000..6fe70a613d2 --- /dev/null +++ b/src/ext/boost/detail/lightweight_thread.hpp @@ -0,0 +1,135 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/detail/lightweight_thread.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +// pthread_create, pthread_join + +#if defined( BOOST_HAS_PTHREADS ) + +#include + +#else + +#include +#include + +typedef HANDLE pthread_t; + +int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg ) +{ + HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 ); + + if( h != 0 ) + { + *thread = h; + return 0; + } + else + { + return EAGAIN; + } +} + +int pthread_join( pthread_t thread, void ** /*value_ptr*/ ) +{ + ::WaitForSingleObject( thread, INFINITE ); + ::CloseHandle( thread ); + return 0; +} + +#endif + +// template int lw_thread_create( pthread_t & pt, F f ); + +namespace boost +{ + +namespace detail +{ + +class lw_abstract_thread +{ +public: + + virtual ~lw_abstract_thread() {} + virtual void run() = 0; +}; + +#if defined( BOOST_HAS_PTHREADS ) + +extern "C" void * lw_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + + pt->run(); + + return 0; +} + +#else + +unsigned __stdcall lw_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + + pt->run(); + + return 0; +} + +#endif + +template class lw_thread_impl: public lw_abstract_thread +{ +public: + + explicit lw_thread_impl( F f ): f_( f ) + { + } + + void run() + { + f_(); + } + +private: + + F f_; +}; + +template int lw_thread_create( pthread_t & pt, F f ) +{ + std::auto_ptr p( new lw_thread_impl( f ) ); + + int r = pthread_create( &pt, 0, lw_thread_routine, p.get() ); + + if( r == 0 ) + { + p.release(); + } + + return r; +} + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED diff --git a/src/ext/boost/detail/limits.hpp b/src/ext/boost/detail/limits.hpp new file mode 100644 index 00000000000..6f018dfaca7 --- /dev/null +++ b/src/ext/boost/detail/limits.hpp @@ -0,0 +1,449 @@ +// Copyright 2001 John Maddock +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/* + * Copyright (c) 1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +/* NOTE: This is not portable code. Parts of numeric_limits<> are + * inherently machine-dependent, and this file is written for the MIPS + * architecture and the SGI MIPSpro C++ compiler. Parts of it (in + * particular, some of the characteristics of floating-point types) + * are almost certainly incorrect for any other platform. + */ + +/* The above comment is almost certainly out of date. This file works + * on systems other than SGI MIPSpro C++ now. + */ + +/* + * Revision history: + * 21 Sep 2001: + * Only include if BOOST_NO_CWCHAR is defined. (Darin Adler) + * 10 Aug 2001: + * Added MIPS (big endian) to the big endian family. (Jens Maurer) + * 13 Apr 2001: + * Added powerpc to the big endian family. (Jeremy Siek) + * 5 Apr 2001: + * Added sparc (big endian) processor support (John Maddock). + * Initial sub: + * Modified by Jens Maurer for gcc 2.95 on x86. + */ + +#ifndef BOOST_SGI_CPP_LIMITS +#define BOOST_SGI_CPP_LIMITS + +#include +#include +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include // for WCHAR_MIN and WCHAR_MAX +#endif + +namespace std { + +enum float_round_style { + round_indeterminate = -1, + round_toward_zero = 0, + round_to_nearest = 1, + round_toward_infinity = 2, + round_toward_neg_infinity = 3 +}; + +enum float_denorm_style { + denorm_indeterminate = -1, + denorm_absent = 0, + denorm_present = 1 +}; + +// The C++ standard (section 18.2.1) requires that some of the members of +// numeric_limits be static const data members that are given constant- +// initializers within the class declaration. On compilers where the +// BOOST_NO_INCLASS_MEMBER_INITIALIZATION macro is defined, it is impossible to write +// a standard-conforming numeric_limits class. +// +// There are two possible workarounds: either initialize the data +// members outside the class, or change them from data members to +// enums. Neither workaround is satisfactory: the former makes it +// impossible to use the data members in constant-expressions, and the +// latter means they have the wrong type and that it is impossible to +// take their addresses. We choose the former workaround. + +#ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + enum { __mem_name = __mem_value } +#else /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ +# define BOOST_STL_DECLARE_LIMITS_MEMBER(__mem_type, __mem_name, __mem_value) \ + static const __mem_type __mem_name = __mem_value +#endif /* BOOST_NO_INCLASS_MEMBER_INITIALIZATION */ + +// Base class for all specializations of numeric_limits. +template +class _Numeric_limits_base { +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, false); + + static __number min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } + static __number max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, 0); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 0); + + static __number epsilon() throw() { return __number(); } + static __number round_error() throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, 0); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_absent); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + static __number infinity() throw() { return __number(); } + static __number quiet_NaN() throw() { return __number(); } + static __number signaling_NaN() throw() { return __number(); } + static __number denorm_min() throw() { return __number(); } + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, + round_style, + round_toward_zero); +}; + +// Base class for integers. + +template +class _Integer_limits : public _Numeric_limits_base<_Int> +{ +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + static _Int min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imin; } + static _Int max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return __imax; } + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, + digits, + (__idigits < 0) ? (int)(sizeof(_Int) * CHAR_BIT) + - (__imin == 0 ? 0 : 1) + : __idigits); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, (digits * 301) / 1000); + // log 2 = 0.301029995664... + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, __imin != 0); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_integer, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_exact, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_modulo, true); +}; + +#if defined(BOOST_BIG_ENDIAN) + + template + struct float_helper{ + static Number get_word() throw() { + // sizeof(long double) == 16 + const unsigned int _S_word[4] = { Word, 0, 0, 0 }; + return *reinterpret_cast(&_S_word); + } +}; + +#else + + template + struct float_helper{ + static Number get_word() throw() { + // sizeof(long double) == 12, but only 10 bytes significant + const unsigned int _S_word[4] = { 0, 0, 0, Word }; + return *reinterpret_cast( + reinterpret_cast(&_S_word)+16- + (sizeof(Number) == 12 ? 10 : sizeof(Number))); + } +}; + +#endif + +// Base class for floating-point numbers. +template +class _Floating_limits : public _Numeric_limits_base<__number> +{ +public: + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_specialized, true); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits, __Digits); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, digits10, __Digits10); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_signed, true); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, radix, 2); + + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent, __MinExp); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent, __MaxExp); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, min_exponent10, __MinExp10); + BOOST_STL_DECLARE_LIMITS_MEMBER(int, max_exponent10, __MaxExp10); + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_infinity, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_quiet_NaN, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_signaling_NaN, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(float_denorm_style, + has_denorm, + denorm_indeterminate); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, has_denorm_loss, false); + + + static __number infinity() throw() { + return float_helper<__number, __InfinityWord>::get_word(); + } + static __number quiet_NaN() throw() { + return float_helper<__number,__QNaNWord>::get_word(); + } + static __number signaling_NaN() throw() { + return float_helper<__number,__SNaNWord>::get_word(); + } + + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_iec559, __IsIEC559); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, is_bounded, true); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, traps, false /* was: true */ ); + BOOST_STL_DECLARE_LIMITS_MEMBER(bool, tinyness_before, false); + + BOOST_STL_DECLARE_LIMITS_MEMBER(float_round_style, round_style, __RoundStyle); +}; + +// Class numeric_limits + +// The unspecialized class. + +template +class numeric_limits : public _Numeric_limits_base {}; + +// Specializations for all built-in integral types. + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template<> +class numeric_limits +#if !defined(WCHAR_MAX) || !defined(WCHAR_MIN) +#if defined(_WIN32) || defined(__CYGWIN__) + : public _Integer_limits +#elif defined(__hppa) +// wchar_t has "unsigned int" as the underlying type + : public _Integer_limits +#else +// assume that wchar_t has "int" as the underlying type + : public _Integer_limits +#endif +#else +// we have WCHAR_MIN and WCHAR_MAX defined, so use it + : public _Integer_limits +#endif +{}; +#endif + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +template<> +class numeric_limits + : public _Integer_limits +{}; + +#ifdef __GNUC__ + +// Some compilers have long long, but don't define the +// LONGLONG_MIN and LONGLONG_MAX macros in limits.h. This +// assumes that long long is 64 bits. +#if !defined(LONGLONG_MAX) && !defined(ULONGLONG_MAX) + +# define ULONGLONG_MAX 0xffffffffffffffffLLU +# define LONGLONG_MAX 0x7fffffffffffffffLL + +#endif + +#if !defined(LONGLONG_MIN) +# define LONGLONG_MIN (-LONGLONG_MAX - 1) +#endif + + +#if !defined(ULONGLONG_MIN) +# define ULONGLONG_MIN 0 +#endif + +#endif /* __GNUC__ */ + +// Specializations for all built-in floating-point type. + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static float min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MIN; } + static float denorm_min() throw() { return FLT_MIN; } + static float max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return FLT_MAX; } + static float epsilon() throw() { return FLT_EPSILON; } + static float round_error() throw() { return 0.5f; } // Units: ulps. +}; + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MIN; } + static double denorm_min() throw() { return DBL_MIN; } + static double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return DBL_MAX; } + static double epsilon() throw() { return DBL_EPSILON; } + static double round_error() throw() { return 0.5; } // Units: ulps. +}; + +template<> class numeric_limits + : public _Floating_limits +{ +public: + static long double min BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MIN; } + static long double denorm_min() throw() { return LDBL_MIN; } + static long double max BOOST_PREVENT_MACRO_SUBSTITUTION () throw() { return LDBL_MAX; } + static long double epsilon() throw() { return LDBL_EPSILON; } + static long double round_error() throw() { return 4; } // Units: ulps. +}; + +} // namespace std + +#endif /* BOOST_SGI_CPP_LIMITS */ + +// Local Variables: +// mode:C++ +// End: + + + diff --git a/src/ext/boost/detail/named_template_params.hpp b/src/ext/boost/detail/named_template_params.hpp new file mode 100644 index 00000000000..e7cb0794330 --- /dev/null +++ b/src/ext/boost/detail/named_template_params.hpp @@ -0,0 +1,177 @@ +// (C) Copyright Jeremy Siek 2001. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Revision History: + +// 04 Oct 2001 David Abrahams +// Changed name of "bind" to "select" to avoid problems with MSVC. + +#ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP +#define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP + +#include +#include // for is_reference +#if defined(__BORLANDC__) +#include +#endif + +namespace boost { + namespace detail { + + struct default_argument { }; + + struct dummy_default_gen { + template + struct select { + typedef default_argument type; + }; + }; + + // This class template is a workaround for MSVC. + template struct default_generator { + typedef detail::dummy_default_gen type; + }; + + template struct is_default { + enum { value = false }; + typedef type_traits::no_type type; + }; + template <> struct is_default { + enum { value = true }; + typedef type_traits::yes_type type; + }; + + struct choose_default { + template + struct select { + typedef typename default_generator::type Gen; + typedef typename Gen::template select::type type; + }; + }; + struct choose_arg { + template + struct select { + typedef Arg type; + }; + }; + +#if defined(__BORLANDC__) + template + struct choose_arg_or_default { typedef choose_arg type; }; + template <> + struct choose_arg_or_default { + typedef choose_default type; + }; +#else + template + struct choose_arg_or_default { typedef choose_arg type; }; + template <> + struct choose_arg_or_default { + typedef choose_default type; + }; +#endif + + template + class resolve_default { +#if defined(__BORLANDC__) + typedef typename choose_arg_or_default::type>::type Selector; +#else + // This usually works for Borland, but I'm seeing weird errors in + // iterator_adaptor_test.cpp when using this method. + enum { is_def = is_default::value }; + typedef typename choose_arg_or_default::type Selector; +#endif + public: + typedef typename Selector + ::template select::type type; + }; + + // To differentiate an unnamed parameter from a traits generator + // we use is_convertible. + struct named_template_param_base { }; + + template + struct is_named_param_list { + enum { value = is_convertible::value }; + }; + + struct choose_named_params { + template struct select { typedef Prev type; }; + }; + struct choose_default_arg { + template struct select { + typedef detail::default_argument type; + }; + }; + + template struct choose_default_dispatch_; + template <> struct choose_default_dispatch_ { + typedef choose_named_params type; + }; + template <> struct choose_default_dispatch_ { + typedef choose_default_arg type; + }; + // The use of inheritance here is a Solaris Forte 6 workaround. + template struct choose_default_dispatch + : public choose_default_dispatch_ { }; + + template + struct choose_default_argument { + enum { is_named = is_named_param_list::value }; + typedef typename choose_default_dispatch::type Selector; + typedef typename Selector::template select::type type; + }; + + // This macro assumes that there is a class named default_##TYPE + // defined before the application of the macro. This class should + // have a single member class template named "select" with two + // template parameters: the type of the class being created (e.g., + // the iterator_adaptor type when creating iterator adaptors) and + // a traits class. The select class should have a single typedef + // named "type" that produces the default for TYPE. See + // boost/iterator_adaptors.hpp for an example usage. Also, + // applications of this macro must be placed in namespace + // boost::detail. + +#define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \ + struct get_##TYPE##_from_named { \ + template \ + struct select { \ + typedef typename NamedParams::traits NamedTraits; \ + typedef typename NamedTraits::TYPE TYPE; \ + typedef typename resolve_default::type type; \ + }; \ + }; \ + struct pass_thru_##TYPE { \ + template struct select { \ + typedef typename resolve_default::type type; \ + };\ + }; \ + template \ + struct get_##TYPE##_dispatch { }; \ + template <> struct get_##TYPE##_dispatch<1> { \ + typedef get_##TYPE##_from_named type; \ + }; \ + template <> struct get_##TYPE##_dispatch<0> { \ + typedef pass_thru_##TYPE type; \ + }; \ + template \ + class get_##TYPE { \ + enum { is_named = is_named_param_list::value }; \ + typedef typename get_##TYPE##_dispatch::type Selector; \ + public: \ + typedef typename Selector::template select::type type; \ + }; \ + template <> struct default_generator { \ + typedef default_##TYPE type; \ + } + + + } // namespace detail +} // namespace boost + +#endif // BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP diff --git a/src/ext/boost/detail/no_exceptions_support.hpp b/src/ext/boost/detail/no_exceptions_support.hpp new file mode 100644 index 00000000000..d94e35834f7 --- /dev/null +++ b/src/ext/boost/detail/no_exceptions_support.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_ +#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP_ + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +//---------------------------------------------------------------------- +// (C) Copyright 2004 Pavel Vozenilek. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// +// This file contains helper macros used when exception support may be +// disabled (as indicated by macro BOOST_NO_EXCEPTIONS). +// +// Before picking up these macros you may consider using RAII techniques +// to deal with exceptions - their syntax can be always the same with +// or without exception support enabled. +// + +/* Example of use: + +void foo() { + BOOST_TRY { + ... + } BOOST_CATCH(const std::bad_alloc&) { + ... + BOOST_RETHROW + } BOOST_CATCH(const std::exception& e) { + ... + } + BOOST_CATCH_END +} + +With exception support enabled it will expand into: + +void foo() { + { try { + ... + } catch (const std::bad_alloc&) { + ... + throw; + } catch (const std::exception& e) { + ... + } + } +} + +With exception support disabled it will expand into: + +void foo() { + { if(true) { + ... + } else if (false) { + ... + } else if (false) { + ... + } + } +} +*/ +//---------------------------------------------------------------------- + +#include +#include + +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_TRY { try +# define BOOST_CATCH(x) catch(x) +# define BOOST_RETHROW throw; +# define BOOST_CATCH_END } +#else +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +# define BOOST_TRY { if ("") +# define BOOST_CATCH(x) else if (!"") +# else +# define BOOST_TRY { if (true) +# define BOOST_CATCH(x) else if (false) +# endif +# define BOOST_RETHROW +# define BOOST_CATCH_END } +#endif + + +#endif diff --git a/src/ext/boost/detail/none_t.hpp b/src/ext/boost/detail/none_t.hpp new file mode 100644 index 00000000000..76ba97a02f5 --- /dev/null +++ b/src/ext/boost/detail/none_t.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/lib/optional for documentation. +// +// You are welcome to contact the author at: +// fernando_cacciola@hotmail.com +// +#ifndef BOOST_DETAIL_NONE_T_17SEP2003_HPP +#define BOOST_DETAIL_NONE_T_17SEP2003_HPP + +namespace boost { + +namespace detail { + +struct none_helper{}; + +typedef int none_helper::*none_t ; + +} // namespace detail + +} // namespace boost + +#endif + diff --git a/src/ext/boost/detail/numeric_traits.hpp b/src/ext/boost/detail/numeric_traits.hpp new file mode 100644 index 00000000000..6325d70cb00 --- /dev/null +++ b/src/ext/boost/detail/numeric_traits.hpp @@ -0,0 +1,191 @@ +// (C) Copyright David Abrahams 2001, Howard Hinnant 2001. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Template class numeric_traits -- +// +// Supplies: +// +// typedef difference_type -- a type used to represent the difference +// between any two values of Number. +// +// Support: +// 1. Not all specializations are supplied +// +// 2. Use of specializations that are not supplied will cause a +// compile-time error +// +// 3. Users are free to specialize numeric_traits for any type. +// +// 4. Right now, specializations are only supplied for integer types. +// +// 5. On implementations which do not supply compile-time constants in +// std::numeric_limits<>, only specializations for built-in integer types +// are supplied. +// +// 6. Handling of numbers whose range of representation is at least as +// great as boost::intmax_t can cause some differences to be +// unrepresentable in difference_type: +// +// Number difference_type +// ------ --------------- +// signed Number +// unsigned intmax_t +// +// template typename numeric_traits::difference_type +// numeric_distance(Number x, Number y) +// computes (y - x), attempting to avoid overflows. +// + +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 11 Feb 2001 - Use BOOST_STATIC_CONSTANT (David Abrahams) +// 11 Feb 2001 - Rolled back ineffective Borland-specific code +// (David Abrahams) +// 10 Feb 2001 - Rolled in supposed Borland fixes from John Maddock, but +// not seeing any improvement yet (David Abrahams) +// 06 Feb 2001 - Factored if_true out into boost/detail/select_type.hpp +// (David Abrahams) +// 23 Jan 2001 - Fixed logic of difference_type selection, which was +// completely wack. In the process, added digit_traits<> +// to compute the number of digits in intmax_t even when +// not supplied by numeric_limits<>. (David Abrahams) +// 21 Jan 2001 - Created (David Abrahams) + +#ifndef BOOST_NUMERIC_TRAITS_HPP_DWA20001901 +# define BOOST_NUMERIC_TRAITS_HPP_DWA20001901 + +# include +# include +# include +# include +# include +# include + +namespace boost { namespace detail { + + // Template class is_signed -- determine whether a numeric type is signed + // Requires that T is constructable from the literals -1 and 0. Compile-time + // error results if that requirement is not met (and thus signedness is not + // likely to have meaning for that type). + template + struct is_signed + { +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + BOOST_STATIC_CONSTANT(bool, value = (Number(-1) < Number(0))); +#else + BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits::is_signed); +#endif + }; + +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + // digit_traits - compute the number of digits in a built-in integer + // type. Needed for implementations on which numeric_limits is not specialized + // for intmax_t (e.g. VC6). + template struct digit_traits_select; + + // numeric_limits is specialized; just select that version of digits + template <> struct digit_traits_select + { + template struct traits + { + BOOST_STATIC_CONSTANT(int, digits = std::numeric_limits::digits); + }; + }; + + // numeric_limits is not specialized; compute digits from sizeof(T) + template <> struct digit_traits_select + { + template struct traits + { + BOOST_STATIC_CONSTANT(int, digits = ( + sizeof(T) * std::numeric_limits::digits + - (is_signed::value ? 1 : 0)) + ); + }; + }; + + // here's the "usable" template + template struct digit_traits + { + typedef digit_traits_select< + ::std::numeric_limits::is_specialized> selector; + typedef typename selector::template traits traits; + BOOST_STATIC_CONSTANT(int, digits = traits::digits); + }; +#endif + + // Template class integer_traits -- traits of various integer types + // This should probably be rolled into boost::integer_traits one day, but I + // need it to work without + template + struct integer_traits + { +# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + private: + typedef Integer integer_type; + typedef std::numeric_limits x; +# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // for some reason, MSVC asserts when it shouldn't unless we make these + // local definitions + BOOST_STATIC_CONSTANT(bool, is_integer = x::is_integer); + BOOST_STATIC_CONSTANT(bool, is_specialized = x::is_specialized); + + BOOST_STATIC_ASSERT(is_integer); + BOOST_STATIC_ASSERT(is_specialized); +# endif + public: + typedef typename + if_true<(int(x::is_signed) + && (!int(x::is_bounded) + // digits is the number of no-sign bits + || (int(x::digits) + 1 >= digit_traits::digits)))>::template then< + Integer, + + typename if_true<(int(x::digits) + 1 < digit_traits::digits)>::template then< + signed int, + + typename if_true<(int(x::digits) + 1 < digit_traits::digits)>::template then< + signed long, + + // else + intmax_t + >::type>::type>::type difference_type; +#else + BOOST_STATIC_ASSERT(boost::is_integral::value); + + typedef typename + if_true<(sizeof(Integer) >= sizeof(intmax_t))>::template then< + + typename if_true<(is_signed::value)>::template then< + Integer, + intmax_t + >::type, + + typename if_true<(sizeof(Integer) < sizeof(std::ptrdiff_t))>::template then< + std::ptrdiff_t, + intmax_t + >::type + >::type difference_type; +# endif + }; + + // Right now, only supports integers, but should be expanded. + template + struct numeric_traits + { + typedef typename integer_traits::difference_type difference_type; + }; + + template + typename numeric_traits::difference_type numeric_distance(Number x, Number y) + { + typedef typename numeric_traits::difference_type difference_type; + return difference_type(y) - difference_type(x); + } +}} + +#endif // BOOST_NUMERIC_TRAITS_HPP_DWA20001901 diff --git a/src/ext/boost/detail/ob_call_traits.hpp b/src/ext/boost/detail/ob_call_traits.hpp new file mode 100644 index 00000000000..eb4df7a30f1 --- /dev/null +++ b/src/ext/boost/detail/ob_call_traits.hpp @@ -0,0 +1,168 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. +// +// Crippled version for crippled compilers: +// see libs/utility/call_traits.htm +// + +/* Release notes: + 01st October 2000: + Fixed call_traits on VC6, using "poor man's partial specialisation", + using ideas taken from "Generative programming" by Krzysztof Czarnecki + & Ulrich Eisenecker. +*/ + +#ifndef BOOST_OB_CALL_TRAITS_HPP +#define BOOST_OB_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP +#include +#endif + +namespace boost{ + +#ifdef BOOST_MSVC6_MEMBER_TEMPLATES +// +// use member templates to emulate +// partial specialisation: +// +namespace detail{ + +template +struct standard_call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T& param_type; +}; +template +struct simple_call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T param_type; +}; +template +struct reference_call_traits +{ + typedef T value_type; + typedef T reference; + typedef T const_reference; + typedef T param_type; +}; + +template +struct call_traits_chooser +{ + template + struct rebind + { + typedef standard_call_traits type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + typedef simple_call_traits type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + typedef reference_call_traits type; + }; +}; + +template +struct call_traits_sizeof_chooser2 +{ + template + struct small_rebind + { + typedef simple_call_traits small_type; + }; +}; + +template<> +struct call_traits_sizeof_chooser2 +{ + template + struct small_rebind + { + typedef standard_call_traits small_type; + }; +}; + +template <> +struct call_traits_chooser +{ + template + struct rebind + { + enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) }; + typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser; + typedef typename chooser::template small_rebind bound_type; + typedef typename bound_type::small_type type; + }; +}; + +} // namespace detail +template +struct call_traits +{ +private: + typedef detail::call_traits_chooser< + ::boost::is_pointer::value, + ::boost::is_arithmetic::value, + ::boost::is_reference::value + > chooser; + typedef typename chooser::template rebind bound_type; + typedef typename bound_type::type call_traits_type; +public: + typedef typename call_traits_type::value_type value_type; + typedef typename call_traits_type::reference reference; + typedef typename call_traits_type::const_reference const_reference; + typedef typename call_traits_type::param_type param_type; +}; + +#else +// +// sorry call_traits is completely non-functional +// blame your broken compiler: +// + +template +struct call_traits +{ + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef const T& param_type; +}; + +#endif // member templates + +} + +#endif // BOOST_OB_CALL_TRAITS_HPP diff --git a/src/ext/boost/detail/ob_compressed_pair.hpp b/src/ext/boost/detail/ob_compressed_pair.hpp new file mode 100644 index 00000000000..727acab6da4 --- /dev/null +++ b/src/ext/boost/detail/ob_compressed_pair.hpp @@ -0,0 +1,510 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. +// see libs/utility/compressed_pair.hpp +// +/* Release notes: + 20 Jan 2001: + Fixed obvious bugs (David Abrahams) + 07 Oct 2000: + Added better single argument constructor support. + 03 Oct 2000: + Added VC6 support (JM). + 23rd July 2000: + Additional comments added. (JM) + Jan 2000: + Original version: this version crippled for use with crippled compilers + - John Maddock Jan 2000. +*/ + + +#ifndef BOOST_OB_COMPRESSED_PAIR_HPP +#define BOOST_OB_COMPRESSED_PAIR_HPP + +#include +#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP +#include +#endif +#ifndef BOOST_SAME_TRAITS_HPP +#include +#endif +#ifndef BOOST_CALL_TRAITS_HPP +#include +#endif + +namespace boost +{ +#ifdef BOOST_MSVC6_MEMBER_TEMPLATES +// +// use member templates to emulate +// partial specialisation. Note that due to +// problems with overload resolution with VC6 +// each of the compressed_pair versions that follow +// have one template single-argument constructor +// in place of two specific constructors: +// + +template +class compressed_pair; + +namespace detail{ + +template +struct best_conversion_traits +{ + typedef char one; + typedef char (&two)[2]; + static A a; + static one test(T1); + static two test(T2); + + enum { value = sizeof(test(a)) }; +}; + +template +struct init_one; + +template <> +struct init_one<1> +{ + template + static void init(const A& a, T1* p1, T2*) + { + *p1 = a; + } +}; + +template <> +struct init_one<2> +{ + template + static void init(const A& a, T1*, T2* p2) + { + *p2 = a; + } +}; + + +// T1 != T2, both non-empty +template +class compressed_pair_0 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_0() : _first(), _second() {} + compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {} + template + explicit compressed_pair_0(const A& val) + { + init_one::value>::init(val, &_first, &_second); + } + compressed_pair_0(const ::boost::compressed_pair& x) + : _first(x.first()), _second(x.second()) {} + +#if 0 + compressed_pair_0& operator=(const compressed_pair_0& x) { + cout << "assigning compressed pair 0" << endl; + _first = x._first; + _second = x._second; + cout << "finished assigning compressed pair 0" << endl; + return *this; + } +#endif + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_0& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +// T1 != T2, T2 empty +template +class compressed_pair_1 : T2 +{ +private: + T1 _first; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_1() : T2(), _first() {} + compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {} + + template + explicit compressed_pair_1(const A& val) + { + init_one::value>::init(val, &_first, static_cast(this)); + } + + compressed_pair_1(const ::boost::compressed_pair& x) + : T2(x.second()), _first(x.first()) {} + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 + // Total weirdness. If the assignment to _first is moved after + // the call to the inherited operator=, then this breaks graph/test/graph.cpp + // by way of iterator_adaptor. + compressed_pair_1& operator=(const compressed_pair_1& x) { + _first = x._first; + T2::operator=(x); + return *this; + } +#endif + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_1& y) + { + // no need to swap empty base class: + using std::swap; + swap(_first, y._first); + } +}; + +// T1 != T2, T1 empty +template +class compressed_pair_2 : T1 +{ +private: + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_2() : T1(), _second() {} + compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {} + template + explicit compressed_pair_2(const A& val) + { + init_one::value>::init(val, static_cast(this), &_second); + } + compressed_pair_2(const ::boost::compressed_pair& x) + : T1(x.first()), _second(x.second()) {} + +#if 0 + compressed_pair_2& operator=(const compressed_pair_2& x) { + cout << "assigning compressed pair 2" << endl; + T1::operator=(x); + _second = x._second; + cout << "finished assigning compressed pair 2" << endl; + return *this; + } +#endif + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_2& y) + { + // no need to swap empty base class: + using std::swap; + swap(_second, y._second); + } +}; + +// T1 != T2, both empty +template +class compressed_pair_3 : T1, T2 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_3() : T1(), T2() {} + compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {} + template + explicit compressed_pair_3(const A& val) + { + init_one::value>::init(val, static_cast(this), static_cast(this)); + } + compressed_pair_3(const ::boost::compressed_pair& x) + : T1(x.first()), T2(x.second()) {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return *this; } + second_const_reference second() const { return *this; } + + void swap(compressed_pair_3& y) + { + // no need to swap empty base classes: + } +}; + +// T1 == T2, and empty +template +class compressed_pair_4 : T1 +{ +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_4() : T1() {} + compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {} + // only one single argument constructor since T1 == T2 + explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {} + compressed_pair_4(const ::boost::compressed_pair& x) + : T1(x.first()), m_second(x.second()) {} + + first_reference first() { return *this; } + first_const_reference first() const { return *this; } + + second_reference second() { return m_second; } + second_const_reference second() const { return m_second; } + + void swap(compressed_pair_4& y) + { + // no need to swap empty base classes: + } +private: + T2 m_second; +}; + +// T1 == T2, not empty +template +class compressed_pair_5 +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_5() : _first(), _second() {} + compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {} + // only one single argument constructor since T1 == T2 + explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {} + compressed_pair_5(const ::boost::compressed_pair& c) + : _first(c.first()), _second(c.second()) {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair_5& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_0 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_1 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_2 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_3 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_4 type; + }; +}; + +template <> +struct compressed_pair_chooser +{ + template + struct rebind + { + typedef compressed_pair_5 type; + }; +}; + +template +struct compressed_pair_traits +{ +private: + typedef compressed_pair_chooser::value, is_empty::value, is_same::value> chooser; + typedef typename chooser::template rebind bound_type; +public: + typedef typename bound_type::type type; +}; + +} // namespace detail + +template +class compressed_pair : public detail::compressed_pair_traits::type +{ +private: + typedef typename detail::compressed_pair_traits::type base_type; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base_type() {} + compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {} + template + explicit compressed_pair(const A& x) : base_type(x){} + + first_reference first() { return base_type::first(); } + first_const_reference first() const { return base_type::first(); } + + second_reference second() { return base_type::second(); } + second_const_reference second() const { return base_type::second(); } +}; + +template +inline void swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +#else +// no partial specialisation, no member templates: + +template +class compressed_pair +{ +private: + T1 _first; + T2 _second; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : _first(), _second() {} + compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {} + explicit compressed_pair(first_param_type x) : _first(x), _second() {} + // can't define this in case T1 == T2: + // explicit compressed_pair(second_param_type y) : _first(), _second(y) {} + + first_reference first() { return _first; } + first_const_reference first() const { return _first; } + + second_reference second() { return _second; } + second_const_reference second() const { return _second; } + + void swap(compressed_pair& y) + { + using std::swap; + swap(_first, y._first); + swap(_second, y._second); + } +}; + +template +inline void swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +#endif + +} // boost + +#endif // BOOST_OB_COMPRESSED_PAIR_HPP + + + diff --git a/src/ext/boost/detail/quick_allocator.hpp b/src/ext/boost/detail/quick_allocator.hpp new file mode 100644 index 00000000000..d54b3a792d7 --- /dev/null +++ b/src/ext/boost/detail/quick_allocator.hpp @@ -0,0 +1,23 @@ +#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/quick_allocator.hpp +// +// Copyright (c) 2003 David Abrahams +// Copyright (c) 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED diff --git a/src/ext/boost/detail/reference_content.hpp b/src/ext/boost/detail/reference_content.hpp new file mode 100644 index 00000000000..daf56a8b193 --- /dev/null +++ b/src/ext/boost/detail/reference_content.hpp @@ -0,0 +1,141 @@ +//----------------------------------------------------------------------------- +// boost detail/reference_content.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_REFERENCE_CONTENT_HPP +#define BOOST_DETAIL_REFERENCE_CONTENT_HPP + +#include "boost/config.hpp" + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +# include "boost/mpl/bool.hpp" +# include "boost/type_traits/has_nothrow_copy.hpp" +#else +# include "boost/mpl/if.hpp" +# include "boost/type_traits/is_reference.hpp" +#endif + +#include "boost/mpl/void.hpp" + +namespace boost { + +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) class template reference_content +// +// Non-Assignable wrapper for references. +// +template +class reference_content +{ +private: // representation + + RefT content_; + +public: // structors + + ~reference_content() + { + } + + reference_content(RefT r) + : content_( r ) + { + } + + reference_content(const reference_content& operand) + : content_( operand.content_ ) + { + } + +private: // non-Assignable + + reference_content& operator=(const reference_content&); + +public: // queries + + RefT get() const + { + return content_; + } + +}; + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_reference_content +// +// Wraps with reference_content if specified type is reference. +// + +template struct make_reference_content; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_content +{ + typedef T type; +}; + +template +struct make_reference_content< T& > +{ + typedef reference_content type; +}; + +#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_content + : mpl::if_< + is_reference + , reference_content + , T + > +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround + +template <> +struct make_reference_content< mpl::void_ > +{ + template + struct apply + : make_reference_content + { + }; + + typedef mpl::void_ type; +}; + +} // namespace detail + +/////////////////////////////////////////////////////////////////////////////// +// reference_content type traits specializations +// + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct has_nothrow_copy< + ::boost::detail::reference_content< T& > + > + : mpl::true_ +{ +}; + +#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +} // namespace boost + +#endif // BOOST_DETAIL_REFERENCE_CONTENT_HPP diff --git a/src/ext/boost/detail/scoped_enum_emulation.hpp b/src/ext/boost/detail/scoped_enum_emulation.hpp new file mode 100644 index 00000000000..644c1386b7a --- /dev/null +++ b/src/ext/boost/detail/scoped_enum_emulation.hpp @@ -0,0 +1,56 @@ +// scoped_enum_emulation.hpp ---------------------------------------------------------// + +// Copyright Beman Dawes, 2009 + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// Generates C++0x scoped enums if the feature is present, otherwise emulates C++0x +// scoped enums with C++03 namespaces and enums. The Boost.Config BOOST_NO_SCOPED_ENUMS +// macro is used to detect feature support. +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf for a +// description of the scoped enum feature. Note that the committee changed the name +// from strongly typed enum to scoped enum. +// +// Caution: only the syntax is emulated; the semantics are not emulated and +// the syntax emulation doesn't include being able to specify the underlying +// representation type. +// +// The emulation is via struct rather than namespace to allow use within classes. +// Thanks to Andrey Semashev for pointing that out. +// +// Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott, +// Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida, Matt Calabrese, Vincente +// Botet, and Daniel James. +// +// Sample usage: +// +// BOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; BOOST_SCOPED_ENUM_END +// ... +// BOOST_SCOPED_ENUM(algae) sample( algae::red ); +// void foo( BOOST_SCOPED_ENUM(algae) color ); +// ... +// sample = algae::green; +// foo( algae::cyan ); + +#ifndef BOOST_SCOPED_ENUM_EMULATION_HPP +#define BOOST_SCOPED_ENUM_EMULATION_HPP + +#include + +#ifdef BOOST_NO_SCOPED_ENUMS + +# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_t +# define BOOST_SCOPED_ENUM_END }; +# define BOOST_SCOPED_ENUM(name) name::enum_t + +#else + +# define BOOST_SCOPED_ENUM_START(name) enum class name +# define BOOST_SCOPED_ENUM_END +# define BOOST_SCOPED_ENUM(name) name + +#endif + +#endif // BOOST_SCOPED_ENUM_EMULATION_HPP diff --git a/src/ext/boost/detail/select_type.hpp b/src/ext/boost/detail/select_type.hpp new file mode 100644 index 00000000000..c13946f3384 --- /dev/null +++ b/src/ext/boost/detail/select_type.hpp @@ -0,0 +1,36 @@ +// (C) Copyright David Abrahams 2001. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 09 Feb 01 Applied John Maddock's Borland patch Moving +// specialization to unspecialized template (David Abrahams) +// 06 Feb 01 Created (David Abrahams) + +#ifndef SELECT_TYPE_DWA20010206_HPP +# define SELECT_TYPE_DWA20010206_HPP + +namespace boost { namespace detail { + + // Template class if_true -- select among 2 types based on a bool constant expression + // Usage: + // typename if_true<(bool_const_expression)>::template then::type + + // HP aCC cannot deal with missing names for template value parameters + template struct if_true + { + template + struct then { typedef T type; }; + }; + + template <> + struct if_true + { + template + struct then { typedef F type; }; + }; +}} +#endif // SELECT_TYPE_DWA20010206_HPP diff --git a/src/ext/boost/detail/sp_typeinfo.hpp b/src/ext/boost/detail/sp_typeinfo.hpp new file mode 100644 index 00000000000..636fe277bc0 --- /dev/null +++ b/src/ext/boost/detail/sp_typeinfo.hpp @@ -0,0 +1,129 @@ +#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED +#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_typeinfo.hpp +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if defined( BOOST_NO_TYPEID ) + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_typeinfo +{ +private: + + sp_typeinfo( sp_typeinfo const& ); + sp_typeinfo& operator=( sp_typeinfo const& ); + + char const * name_; + +public: + + explicit sp_typeinfo( char const * name ): name_( name ) + { + } + + bool operator==( sp_typeinfo const& rhs ) const + { + return this == &rhs; + } + + bool operator!=( sp_typeinfo const& rhs ) const + { + return this != &rhs; + } + + bool before( sp_typeinfo const& rhs ) const + { + return std::less< sp_typeinfo const* >()( this, &rhs ); + } + + char const* name() const + { + return name_; + } +}; + +template struct sp_typeid_ +{ + static sp_typeinfo ti_; + + static char const * name() + { + return BOOST_CURRENT_FUNCTION; + } +}; + +template sp_typeinfo sp_typeid_< T >::ti_( sp_typeid_< T >::name() ); + +template struct sp_typeid_< T & >: sp_typeid_< T > +{ +}; + +template struct sp_typeid_< T const >: sp_typeid_< T > +{ +}; + +template struct sp_typeid_< T volatile >: sp_typeid_< T > +{ +}; + +template struct sp_typeid_< T const volatile >: sp_typeid_< T > +{ +}; + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_::ti_) + +#else + +#include + +namespace boost +{ + +namespace detail +{ + +#if defined( BOOST_NO_STD_TYPEINFO ) + +typedef ::type_info sp_typeinfo; + +#else + +typedef std::type_info sp_typeinfo; + +#endif + +} // namespace detail + +} // namespace boost + +#define BOOST_SP_TYPEID(T) typeid(T) + +#endif + +#endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED diff --git a/src/ext/boost/detail/templated_streams.hpp b/src/ext/boost/detail/templated_streams.hpp new file mode 100644 index 00000000000..1fa6ee35343 --- /dev/null +++ b/src/ext/boost/detail/templated_streams.hpp @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// boost detail/templated_streams.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2003 +// Eric Friedman +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_TEMPLATED_STREAMS_HPP +#define BOOST_DETAIL_TEMPLATED_STREAMS_HPP + +#include "boost/config.hpp" + +/////////////////////////////////////////////////////////////////////////////// +// (detail) BOOST_TEMPLATED_STREAM_* macros +// +// Provides workaround platforms without stream class templates. +// + +#if !defined(BOOST_NO_STD_LOCALE) + +#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) \ + template < typename E , typename T > + +#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) \ + template < typename E , typename T , typename A > + +#define BOOST_TEMPLATED_STREAM_ARGS(E,T) \ + typename E , typename T + +#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) \ + typename E , typename T , typename A + +#define BOOST_TEMPLATED_STREAM_COMMA , + +#define BOOST_TEMPLATED_STREAM_ELEM(E) E +#define BOOST_TEMPLATED_STREAM_TRAITS(T) T +#define BOOST_TEMPLATED_STREAM_ALLOC(A) A + +#define BOOST_TEMPLATED_STREAM(X,E,T) \ + BOOST_JOIN(std::basic_,X)< E , T > + +#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \ + BOOST_JOIN(std::basic_,X)< E , T , A > + +#else // defined(BOOST_NO_STD_LOCALE) + +#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) /**/ + +#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) /**/ + +#define BOOST_TEMPLATED_STREAM_ARGS(E,T) /**/ + +#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) /**/ + +#define BOOST_TEMPLATED_STREAM_COMMA /**/ + +#define BOOST_TEMPLATED_STREAM_ELEM(E) char +#define BOOST_TEMPLATED_STREAM_TRAITS(T) std::char_traits +#define BOOST_TEMPLATED_STREAM_ALLOC(A) std::allocator + +#define BOOST_TEMPLATED_STREAM(X,E,T) \ + std::X + +#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \ + std::X + +#endif // BOOST_NO_STD_LOCALE + +#endif // BOOST_DETAIL_TEMPLATED_STREAMS_HPP diff --git a/src/ext/boost/detail/utf8_codecvt_facet.hpp b/src/ext/boost/detail/utf8_codecvt_facet.hpp new file mode 100644 index 00000000000..b777ff934eb --- /dev/null +++ b/src/ext/boost/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,190 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See accompany- +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_UTF8_CODECVT_FACET_HPP +#define BOOST_UTF8_CODECVT_FACET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// utf8_codecvt_facet.hpp + +// This header defines class utf8_codecvt_facet, derived fro +// std::codecvt, which can be used to convert utf8 data in +// files into wchar_t strings in the application. +// +// The header is NOT STANDALONE, and is not to be included by the USER. +// There are at least two libraries which want to use this functionality, and +// we want to avoid code duplication. It would be possible to create utf8 +// library, but: +// - this requires review process first +// - in the case, when linking the a library which uses utf8 +// (say 'program_options'), user should also link to the utf8 library. +// This seems inconvenient, and asking a user to link to an unrevieved +// library is strange. +// Until the above points are fixed, a library which wants to use utf8 must: +// - include this header from one of it's headers or sources +// - include the corresponding .cpp file from one of the sources +// - before including either file, the library must define +// - BOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used +// - BOOST_UTF8_END_NAMESPACE to the code to close the previous namespace +// - declaration. +// - BOOST_UTF8_DECL -- to the code which must be used for all 'exportable' +// symbols. +// +// For example, program_options library might contain: +// #define BOOST_UTF8_BEGIN_NAMESPACE +// namespace boost { namespace program_options { +// #define BOOST_UTF8_END_NAMESPACE }} +// #define BOOST_UTF8_DECL BOOST_PROGRAM_OPTIONS_DECL +// #include "../../detail/utf8/utf8_codecvt.cpp" +// +// Essentially, each library will have its own copy of utf8 code, in +// different namespaces. + +// Note:(Robert Ramey). I have made the following alterations in the original +// code. +// a) Rendered utf8_codecvt with using templates +// b) Move longer functions outside class definition to prevent inlining +// and make code smaller +// c) added on a derived class to permit translation to/from current +// locale to utf8 + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters +// +// utf8_codecvt_facet +// This is an implementation of a std::codecvt facet for translating +// from UTF-8 externally to UCS-4. Note that this is not tied to +// any specific types in order to allow customization on platforms +// where wchar_t is not big enough. +// +// NOTES: The current implementation jumps through some unpleasant hoops in +// order to deal with signed character types. As a std::codecvt_base::result, +// it is necessary for the ExternType to be convertible to unsigned char. +// I chose not to tie the extern_type explicitly to char. But if any combination +// of types other than is used, then std::codecvt must be +// specialized on those types for this to work. + +#include +#include // for mbstate_t +#include // for std::size_t + +#include +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { + using ::mbstate_t; + using ::size_t; +} +#endif + +#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) + #define BOOST_CODECVT_DO_LENGTH_CONST const +#else + #define BOOST_CODECVT_DO_LENGTH_CONST +#endif + +// maximum lenght of a multibyte string +#define MB_LENGTH_MAX 8 + +BOOST_UTF8_BEGIN_NAMESPACE + +struct BOOST_UTF8_DECL utf8_codecvt_facet : + public std::codecvt +{ +public: + explicit utf8_codecvt_facet(std::size_t no_locale_manage=0) + : std::codecvt(no_locale_manage) + {} +protected: + virtual std::codecvt_base::result do_in( + std::mbstate_t& state, + const char * from, + const char * from_end, + const char * & from_next, + wchar_t * to, + wchar_t * to_end, + wchar_t*& to_next + ) const; + + virtual std::codecvt_base::result do_out( + std::mbstate_t & state, const wchar_t * from, + const wchar_t * from_end, const wchar_t* & from_next, + char * to, char * to_end, char * & to_next + ) const; + + bool invalid_continuing_octet(unsigned char octet_1) const { + return (octet_1 < 0x80|| 0xbf< octet_1); + } + + bool invalid_leading_octet(unsigned char octet_1) const { + return (0x7f < octet_1 && octet_1 < 0xc0) || + (octet_1 > 0xfd); + } + + // continuing octets = octets except for the leading octet + static unsigned int get_cont_octet_count(unsigned char lead_octet) { + return get_octet_count(lead_octet) - 1; + } + + static unsigned int get_octet_count(unsigned char lead_octet); + + // How many "continuing octets" will be needed for this word + // == total octets - 1. + int get_cont_octet_out_count(wchar_t word) const ; + + virtual bool do_always_noconv() const throw() { return false; } + + // UTF-8 isn't really stateful since we rewind on partial conversions + virtual std::codecvt_base::result do_unshift( + std::mbstate_t&, + char * from, + char * /*to*/, + char * & next + ) const + { + next = from; + return ok; + } + + virtual int do_encoding() const throw() { + const int variable_byte_external_encoding=0; + return variable_byte_external_encoding; + } + + // How many char objects can I process to get <= max_limit + // wchar_t objects? + virtual int do_length( + BOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &, + const char * from, + const char * from_end, + std::size_t max_limit +#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) + ) const throw(); +#else + ) const; +#endif + + // Largest possible value do_length(state,from,from_end,1) could return. + virtual int do_max_length() const throw () { + return 6; // largest UTF-8 encoding of a UCS-4 character + } +}; + +BOOST_UTF8_END_NAMESPACE + +#endif // BOOST_UTF8_CODECVT_FACET_HPP diff --git a/src/ext/boost/detail/workaround.hpp b/src/ext/boost/detail/workaround.hpp new file mode 100644 index 00000000000..b6b64125c6a --- /dev/null +++ b/src/ext/boost/detail/workaround.hpp @@ -0,0 +1,262 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef WORKAROUND_DWA2002126_HPP +# define WORKAROUND_DWA2002126_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +# ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __CODEGEARC__ +#define __CODEGEARC___WORKAROUND_GUARD 1 +#else +#define __CODEGEARC___WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_VER +#define _MSC_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG__ +#define __EDG___WORKAROUND_GUARD 1 +#else +#define __EDG___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef __hpxstd98 +#define __hpxstd98_WORKAROUND_GUARD 1 +#else +#define __hpxstd98_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif +#ifndef __COMO__ +#define __COMO___WORKAROUND_GUARD 1 +#else +#define __COMO___WORKAROUND_GUARD 0 +#endif +#ifndef __COMO_VERSION__ +#define __COMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __COMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __INTEL_COMPILER +#define __INTEL_COMPILER_WORKAROUND_GUARD 1 +#else +#define __INTEL_COMPILER_WORKAROUND_GUARD 0 +#endif +#ifndef __ICL +#define __ICL_WORKAROUND_GUARD 1 +#else +#define __ICL_WORKAROUND_GUARD 0 +#endif +#ifndef _COMPILER_VERSION +#define _COMPILER_VERSION_WORKAROUND_GUARD 1 +#else +#define _COMPILER_VERSION_WORKAROUND_GUARD 0 +#endif + +#ifndef _RWSTD_VER +#define _RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_RWSTD_VER +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GLIBCPP__ +#define __GLIBCPP___WORKAROUND_GUARD 1 +#else +#define __GLIBCPP___WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __LIBCOMO_VERSION__ +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef _CPPLIB_VER +#define _CPPLIB_VER_WORKAROUND_GUARD 1 +#else +#define _CPPLIB_VER_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WORKAROUND_GUARD 0 +#endif +// Always define to zero, if it's used it'll be defined my MPL: +#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 + +# define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +# else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +# endif + +# else + +# define BOOST_WORKAROUND(symbol, test) 0 + +# endif + +#endif // WORKAROUND_DWA2002126_HPP diff --git a/src/ext/boost/exception/all.hpp b/src/ext/boost/exception/all.hpp new file mode 100644 index 00000000000..9ffe42a9d0c --- /dev/null +++ b/src/ext/boost/exception/all.hpp @@ -0,0 +1,36 @@ +//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_316FDA946C0D11DEA9CBAE5255D89593 +#define UUID_316FDA946C0D11DEA9CBAE5255D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_EXCEPTIONS +#include +#include +#endif + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/current_exception_cast.hpp b/src/ext/boost/exception/current_exception_cast.hpp new file mode 100644 index 00000000000..af2f1531130 --- /dev/null +++ b/src/ext/boost/exception/current_exception_cast.hpp @@ -0,0 +1,43 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_7E83C166200811DE885E826156D89593 +#define UUID_7E83C166200811DE885E826156D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + template + inline + E * + current_exception_cast() + { + try + { + throw; + } + catch( + E & e ) + { + return &e; + } + catch( + ...) + { + return 0; + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/detail/attribute_noreturn.hpp b/src/ext/boost/exception/detail/attribute_noreturn.hpp new file mode 100644 index 00000000000..f6a0b5903e3 --- /dev/null +++ b/src/ext/boost/exception/detail/attribute_noreturn.hpp @@ -0,0 +1,17 @@ +//Copyright (c) 2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_61531AB0680611DEADD5846855D89593 +#define UUID_61531AB0680611DEADD5846855D89593 + +#if defined(_MSC_VER) +#define BOOST_ATTRIBUTE_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) +#define BOOST_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#else +#define BOOST_ATTRIBUTE_NORETURN +#endif + +#endif diff --git a/src/ext/boost/exception/detail/error_info_impl.hpp b/src/ext/boost/exception/detail/error_info_impl.hpp new file mode 100644 index 00000000000..32113b1391e --- /dev/null +++ b/src/ext/boost/exception/detail/error_info_impl.hpp @@ -0,0 +1,75 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_CE6983AC753411DDA764247956D89593 +#define UUID_CE6983AC753411DDA764247956D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include + +namespace +boost + { + namespace + exception_detail + { + class + error_info_base + { + public: + + virtual char const * tag_typeid_name() const = 0; + virtual std::string value_as_string() const = 0; + + protected: + + ~error_info_base() throw() + { + } + }; + } + + template + class + error_info: + public exception_detail::error_info_base + { + public: + + typedef T value_type; + + error_info( value_type const & value ); + ~error_info() throw(); + + value_type const & + value() const + { + return value_; + } + + value_type & + value() + { + return value_; + } + + private: + + char const * tag_typeid_name() const; + std::string value_as_string() const; + + value_type value_; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/detail/exception_ptr.hpp b/src/ext/boost/exception/detail/exception_ptr.hpp new file mode 100644 index 00000000000..78db17c065b --- /dev/null +++ b/src/ext/boost/exception/detail/exception_ptr.hpp @@ -0,0 +1,490 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_618474C2DE1511DEB74A388C56D89593 +#define UUID_618474C2DE1511DEB74A388C56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#ifdef BOOST_NO_EXCEPTIONS +#error This header requires exception handling to be enabled. +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +boost + { +#ifndef BOOST_NO_RTTI + typedef error_info original_exception_type; + + inline + std::string + to_string( original_exception_type const & x ) + { + return x.value()->name(); + } +#endif + + class exception_ptr; + exception_ptr current_exception(); + void rethrow_exception( exception_ptr const & ); + + class + exception_ptr + { + typedef bool exception_ptr::*unspecified_bool_type; + friend exception_ptr current_exception(); + friend void rethrow_exception( exception_ptr const & ); + + shared_ptr c_; + bool bad_alloc_; + + struct + bad_alloc_tag + { + }; + + explicit + exception_ptr( bad_alloc_tag ): + bad_alloc_(true) + { + } + + explicit + exception_ptr( shared_ptr const & c ): + c_(c), + bad_alloc_(false) + { + BOOST_ASSERT(c); + } + + void + rethrow() const + { + BOOST_ASSERT(*this); + if( bad_alloc_ ) + throw enable_current_exception(std::bad_alloc()); + else + c_->rethrow(); + } + + bool + empty() const + { + return !bad_alloc_ && !c_; + } + + public: + + exception_ptr(): + bad_alloc_(false) + { + } + + ~exception_ptr() throw() + { + } + + operator unspecified_bool_type() const + { + return empty() ? 0 : &exception_ptr::bad_alloc_; + } + + friend + bool + operator==( exception_ptr const & a, exception_ptr const & b ) + { + return a.c_==b.c_ && a.bad_alloc_==b.bad_alloc_; + } + + friend + bool + operator!=( exception_ptr const & a, exception_ptr const & b ) + { + return !(a==b); + } + }; + + class + unknown_exception: + public exception, + public std::exception, + public exception_detail::clone_base + { + public: + + unknown_exception() + { + } + + explicit + unknown_exception( std::exception const & e ) + { + add_original_type(e); + } + + explicit + unknown_exception( boost::exception const & e ): + boost::exception(e) + { + add_original_type(e); + } + + ~unknown_exception() throw() + { + } + + private: + + exception_detail::clone_base const * + clone() const + { + return new unknown_exception(*this); + } + + void + rethrow() const + { + throw*this; + } + + template + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; + + namespace + exception_detail + { + template + class + current_exception_std_exception_wrapper: + public T, + public boost::exception, + public clone_base + { + public: + + explicit + current_exception_std_exception_wrapper( T const & e1 ): + T(e1) + { + add_original_type(e1); + } + + current_exception_std_exception_wrapper( T const & e1, boost::exception const & e2 ): + T(e1), + boost::exception(e2) + { + add_original_type(e1); + } + + ~current_exception_std_exception_wrapper() throw() + { + } + + private: + + clone_base const * + clone() const + { + return new current_exception_std_exception_wrapper(*this); + } + + void + rethrow() const + { + throw *this; + } + + template + void + add_original_type( E const & e ) + { +#ifndef BOOST_NO_RTTI + (*this) << original_exception_type(&typeid(e)); +#endif + } + }; + +#ifdef BOOST_NO_RTTI + template + exception const * + get_boost_exception( T const * ) + { + try + { + throw; + } + catch( + exception & x ) + { + return &x; + } + catch(...) + { + return 0; + } + } +#else + template + exception const * + get_boost_exception( T const * x ) + { + return dynamic_cast(x); + } +#endif + + template + inline + shared_ptr + current_exception_std_exception( T const & e1 ) + { + if( boost::exception const * e2 = get_boost_exception(&e1) ) + return shared_ptr const>(new current_exception_std_exception_wrapper(e1,*e2)); + else + return shared_ptr const>(new current_exception_std_exception_wrapper(e1)); + } + + inline + shared_ptr + current_exception_unknown_exception() + { + return shared_ptr(new unknown_exception()); + } + + inline + shared_ptr + current_exception_unknown_boost_exception( boost::exception const & e ) + { + return shared_ptr(new unknown_exception(e)); + } + + inline + shared_ptr + current_exception_unknown_std_exception( std::exception const & e ) + { + if( boost::exception const * be = get_boost_exception(&e) ) + return current_exception_unknown_boost_exception(*be); + else + return shared_ptr(new unknown_exception(e)); + } + + inline + shared_ptr + current_exception_impl() + { + try + { + throw; + } + catch( + exception_detail::clone_base & e ) + { + return shared_ptr(e.clone()); + } + catch( + std::domain_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::invalid_argument & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::length_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::out_of_range & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::logic_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::range_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::overflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::underflow_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::ios_base::failure & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::runtime_error & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_alloc & e ) + { + return exception_detail::current_exception_std_exception(e); + } +#ifndef BOOST_NO_TYPEID + catch( + std::bad_cast & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::bad_typeid & e ) + { + return exception_detail::current_exception_std_exception(e); + } +#endif + catch( + std::bad_exception & e ) + { + return exception_detail::current_exception_std_exception(e); + } + catch( + std::exception & e ) + { + return exception_detail::current_exception_unknown_std_exception(e); + } + catch( + boost::exception & e ) + { + return exception_detail::current_exception_unknown_boost_exception(e); + } + catch( + ... ) + { + return exception_detail::current_exception_unknown_exception(); + } + } + } + + inline + exception_ptr + current_exception() + { + try + { + return exception_ptr(exception_detail::current_exception_impl()); + } + catch( + std::bad_alloc & ) + { + } + catch( + ... ) + { + try + { + return exception_ptr(exception_detail::current_exception_std_exception(std::bad_exception())); + } + catch( + std::bad_alloc & ) + { + } + catch( + ... ) + { + BOOST_ASSERT(0); + } + } + return exception_ptr(exception_ptr::bad_alloc_tag()); + } + + template + inline + exception_ptr + copy_exception( T const & e ) + { + try + { + throw enable_current_exception(e); + } + catch( + ... ) + { + return current_exception(); + } + } + + inline + void + rethrow_exception( exception_ptr const & p ) + { + p.rethrow(); + } + + inline + std::string + diagnostic_information( exception_ptr const & p ) + { + if( p ) + try + { + rethrow_exception(p); + } + catch( + ... ) + { + return current_exception_diagnostic_information(); + } + return ""; + } + + inline + std::string + to_string( exception_ptr const & p ) + { + std::string s='\n'+diagnostic_information(p); + std::string padding(" "); + std::string r; + bool f=false; + for( std::string::const_iterator i=s.begin(),e=s.end(); i!=e; ++i ) + { + if( f ) + r+=padding; + char c=*i; + r+=c; + f=(c=='\n'); + } + return r; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/detail/is_output_streamable.hpp b/src/ext/boost/exception/detail/is_output_streamable.hpp new file mode 100644 index 00000000000..5eb1695d2a2 --- /dev/null +++ b/src/ext/boost/exception/detail/is_output_streamable.hpp @@ -0,0 +1,47 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_898984B4076411DD973EDFA055D89593 +#define UUID_898984B4076411DD973EDFA055D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include + +namespace +boost + { + namespace + to_string_detail + { + template + char operator<<( std::basic_ostream &, T const & ); + + template + struct + is_output_streamable_impl + { + static std::basic_ostream & f(); + static T const & g(); + enum e { value=1!=(sizeof(f()< > + struct + is_output_streamable + { + enum e { value=to_string_detail::is_output_streamable_impl::value }; + }; + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/detail/object_hex_dump.hpp b/src/ext/boost/exception/detail/object_hex_dump.hpp new file mode 100644 index 00000000000..ccf1bac3f74 --- /dev/null +++ b/src/ext/boost/exception/detail/object_hex_dump.hpp @@ -0,0 +1,50 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_6F463AC838DF11DDA3E6909F56D89593 +#define UUID_6F463AC838DF11DDA3E6909F56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include +#include +#include +#include + +namespace +boost + { + namespace + exception_detail + { + template + inline + std::string + object_hex_dump( T const & x, std::size_t max_size=16 ) + { + std::ostringstream s; + s << "type: " << type_name() << ", size: " << sizeof(T) << ", dump: "; + std::size_t n=sizeof(T)>max_size?max_size:sizeof(T); + s.fill('0'); + s.width(2); + unsigned char const * b=reinterpret_cast(&x); + s << std::setw(2) << std::hex << (unsigned int)*b; + for( unsigned char const * e=b+n; ++b!=e; ) + s << " " << std::setw(2) << std::hex << (unsigned int)*b; + return s.str(); + } + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/detail/type_info.hpp b/src/ext/boost/exception/detail/type_info.hpp new file mode 100644 index 00000000000..60709a1f6c0 --- /dev/null +++ b/src/ext/boost/exception/detail/type_info.hpp @@ -0,0 +1,79 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_C3E1741C754311DDB2834CCA55D89593 +#define UUID_C3E1741C754311DDB2834CCA55D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include + +namespace +boost + { + template + inline + char const * + tag_type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return typeid(T*).name(); +#endif + } + + template + inline + char const * + type_name() + { +#ifdef BOOST_NO_TYPEID + return BOOST_CURRENT_FUNCTION; +#else + return typeid(T).name(); +#endif + } + + namespace + exception_detail + { + struct + type_info_ + { + detail::sp_typeinfo const & type_; + + explicit + type_info_( detail::sp_typeinfo const & type ): + type_(type) + { + } + + friend + bool + operator<( type_info_ const & a, type_info_ const & b ) + { + return 0!=(a.type_.before(b.type_)); + } + }; + } + } + +#define BOOST_EXCEPTION_STATIC_TYPEID(T) ::boost::exception_detail::type_info_(BOOST_SP_TYPEID(T)) + +#ifndef BOOST_NO_RTTI +#define BOOST_EXCEPTION_DYNAMIC_TYPEID(x) ::boost::exception_detail::type_info_(typeid(x)) +#endif + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/diagnostic_information.hpp b/src/ext/boost/exception/diagnostic_information.hpp new file mode 100644 index 00000000000..632a5a33397 --- /dev/null +++ b/src/ext/boost/exception/diagnostic_information.hpp @@ -0,0 +1,182 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_0552D49838DD11DD90146B8956D89593 +#define UUID_0552D49838DD11DD90146B8956D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_NO_EXCEPTIONS +#include +namespace +boost + { + namespace + exception_detail + { + std::string diagnostic_information_impl( boost::exception const *, std::exception const *, bool ); + } + + inline + std::string + current_exception_diagnostic_information() + { + boost::exception const * be=current_exception_cast(); + std::exception const * se=current_exception_cast(); + if( be || se ) + return exception_detail::diagnostic_information_impl(be,se,true); + else + return "No diagnostic information available."; + } + } +#endif + +namespace +boost + { + namespace + exception_detail + { + inline + exception const * + get_boost_exception( exception const * e ) + { + return e; + } + + inline + exception const * + get_boost_exception( ... ) + { + return 0; + } + + inline + std::exception const * + get_std_exception( std::exception const * e ) + { + return e; + } + + inline + std::exception const * + get_std_exception( ... ) + { + return 0; + } + + inline + char const * + get_diagnostic_information( exception const & x, char const * header ) + { + if( error_info_container * c=x.data_.get() ) +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + return c->diagnostic_information(header); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + } +#endif + return 0; + } + + inline + std::string + diagnostic_information_impl( boost::exception const * be, std::exception const * se, bool with_what ) + { + if( !be && !se ) + return "Unknown exception."; +#ifndef BOOST_NO_RTTI + if( !be ) + be=dynamic_cast(se); + if( !se ) + se=dynamic_cast(be); +#endif + char const * wh=0; + if( with_what && se ) + { + wh=se->what(); + if( be && exception_detail::get_diagnostic_information(*be,0)==wh ) + return wh; + } + std::ostringstream tmp; + if( be ) + { + if( char const * const * f=get_error_info(*be) ) + { + tmp << *f; + if( int const * l=get_error_info(*be) ) + tmp << '(' << *l << "): "; + } + tmp << "Throw in function "; + if( char const * const * fn=get_error_info(*be) ) + tmp << *fn; + else + tmp << "(unknown)"; + tmp << '\n'; + } +#ifndef BOOST_NO_RTTI + tmp << std::string("Dynamic exception type: ") << + (be?BOOST_EXCEPTION_DYNAMIC_TYPEID(*be):BOOST_EXCEPTION_DYNAMIC_TYPEID(*se)).type_.name() << '\n'; +#endif + if( with_what && se ) + tmp << "std::exception::what: " << wh << '\n'; + if( be ) + if( char const * s=exception_detail::get_diagnostic_information(*be,tmp.str().c_str()) ) + if( *s ) + return s; + return tmp.str(); + } + } + + template + std::string + diagnostic_information( T const & e ) + { + return exception_detail::diagnostic_information_impl(exception_detail::get_boost_exception(&e),exception_detail::get_std_exception(&e),true); + } + + inline + char const * + diagnostic_information_what( exception const & e ) throw() + { + char const * w=0; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + (void) exception_detail::diagnostic_information_impl(&e,0,false); + return exception_detail::get_diagnostic_information(e,0); +#ifndef BOOST_NO_EXCEPTIONS + } + catch( + ... ) + { + } +#endif + return w; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/enable_current_exception.hpp b/src/ext/boost/exception/enable_current_exception.hpp new file mode 100644 index 00000000000..988105378cc --- /dev/null +++ b/src/ext/boost/exception/enable_current_exception.hpp @@ -0,0 +1,6 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include diff --git a/src/ext/boost/exception/enable_error_info.hpp b/src/ext/boost/exception/enable_error_info.hpp new file mode 100644 index 00000000000..988105378cc --- /dev/null +++ b/src/ext/boost/exception/enable_error_info.hpp @@ -0,0 +1,6 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include diff --git a/src/ext/boost/exception/errinfo_api_function.hpp b/src/ext/boost/exception/errinfo_api_function.hpp new file mode 100644 index 00000000000..481c61314e3 --- /dev/null +++ b/src/ext/boost/exception/errinfo_api_function.hpp @@ -0,0 +1,22 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_DDFBB4546C1211DEA4659E9055D89593 +#define UUID_DDFBB4546C1211DEA4659E9055D89593 + +#include "boost/exception/error_info.hpp" + +namespace +boost + { + //Usage hint: + //if( api_function(....)!=0 ) + // BOOST_THROW_EXCEPTION( + // failure() << + // errinfo_api_function("api_function") ); + typedef error_info errinfo_api_function; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_at_line.hpp b/src/ext/boost/exception/errinfo_at_line.hpp new file mode 100644 index 00000000000..cbd5ccefba0 --- /dev/null +++ b/src/ext/boost/exception/errinfo_at_line.hpp @@ -0,0 +1,18 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_E7255CE26C1211DE85800C9155D89593 +#define UUID_E7255CE26C1211DE85800C9155D89593 + +namespace +boost + { + template class error_info; + + //Use with parsing errors exceptions, for example in a XML file parser. + typedef error_info errinfo_at_line; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_errno.hpp b/src/ext/boost/exception/errinfo_errno.hpp new file mode 100644 index 00000000000..ea74010c944 --- /dev/null +++ b/src/ext/boost/exception/errinfo_errno.hpp @@ -0,0 +1,44 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_F0EE17BE6C1211DE87FF459155D89593 +#define UUID_F0EE17BE6C1211DE87FF459155D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include "boost/exception/info.hpp" +#include +#include + +namespace +boost + { + typedef error_info errinfo_errno; + + //Usage hint: + //if( c_function(....)!=0 ) + // BOOST_THROW_EXCEPTION( + // failure() << + // errinfo_errno(errno) << + // errinfo_api_function("c_function") ); + inline + std::string + to_string( errinfo_errno const & e ) + { + std::ostringstream tmp; + int v=e.value(); + tmp << v << ", \"" << strerror(v) << "\""; + return tmp.str(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/errinfo_file_handle.hpp b/src/ext/boost/exception/errinfo_file_handle.hpp new file mode 100644 index 00000000000..8e6cff8fd89 --- /dev/null +++ b/src/ext/boost/exception/errinfo_file_handle.hpp @@ -0,0 +1,20 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_F79E6EE26C1211DEB26E929155D89593 +#define UUID_F79E6EE26C1211DEB26E929155D89593 + +#include + +namespace +boost + { + template class weak_ptr; + template class error_info; + + typedef error_info > errinfo_file_handle; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_file_name.hpp b/src/ext/boost/exception/errinfo_file_name.hpp new file mode 100644 index 00000000000..d3cce4d356b --- /dev/null +++ b/src/ext/boost/exception/errinfo_file_name.hpp @@ -0,0 +1,26 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_FEE5120A6C1211DE94E8BC9155D89593 +#define UUID_FEE5120A6C1211DE94E8BC9155D89593 + +#include + +namespace +boost + { + template class error_info; + + //Usage hint: + //FILE * f=fopen(name,mode); + //if( !f ) + // BOOST_THROW_EXCEPTION( + // file_open_error() << + // errinfo_file_name(name) << + // errinfo_file_open_mode(mode) ); + typedef error_info errinfo_file_name; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_file_open_mode.hpp b/src/ext/boost/exception/errinfo_file_open_mode.hpp new file mode 100644 index 00000000000..f4fba0d5cc0 --- /dev/null +++ b/src/ext/boost/exception/errinfo_file_open_mode.hpp @@ -0,0 +1,26 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_056F1F266C1311DE8E74299255D89593 +#define UUID_056F1F266C1311DE8E74299255D89593 + +#include + +namespace +boost + { + template class error_info; + + //Usage hint: + //FILE * f=fopen(name,mode); + //if( !f ) + // BOOST_THROW_EXCEPTION( + // file_open_error() << + // errinfo_file_name(name) << + // errinfo_file_open_mode(mode) ); + typedef error_info errinfo_file_open_mode; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_nested_exception.hpp b/src/ext/boost/exception/errinfo_nested_exception.hpp new file mode 100644 index 00000000000..de055e035f8 --- /dev/null +++ b/src/ext/boost/exception/errinfo_nested_exception.hpp @@ -0,0 +1,17 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_45CC9A82B77511DEB330FC4956D89593 +#define UUID_45CC9A82B77511DEB330FC4956D89593 + +namespace +boost + { + template class error_info; + class exception_ptr; + typedef error_info errinfo_nested_exception; + } + +#endif diff --git a/src/ext/boost/exception/errinfo_type_info_name.hpp b/src/ext/boost/exception/errinfo_type_info_name.hpp new file mode 100644 index 00000000000..0b060e2e11c --- /dev/null +++ b/src/ext/boost/exception/errinfo_type_info_name.hpp @@ -0,0 +1,23 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_0E11109E6C1311DEB7EA649255D89593 +#define UUID_0E11109E6C1311DEB7EA649255D89593 + +#include + +namespace +boost + { + template class error_info; + + //Usage hint: + //BOOST_THROW_EXCEPTION( + // bad_type() << + // errinfo_type_info_name(typeid(x).name()) ); + typedef error_info errinfo_type_info_name; + } + +#endif diff --git a/src/ext/boost/exception/error_info.hpp b/src/ext/boost/exception/error_info.hpp new file mode 100644 index 00000000000..2e6832a338e --- /dev/null +++ b/src/ext/boost/exception/error_info.hpp @@ -0,0 +1,6 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +namespace boost { template class error_info; } diff --git a/src/ext/boost/exception/exception.hpp b/src/ext/boost/exception/exception.hpp new file mode 100644 index 00000000000..79b273999c3 --- /dev/null +++ b/src/ext/boost/exception/exception.hpp @@ -0,0 +1,422 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_274DA366004E11DCB1DDFE2E56D89593 +#define UUID_274DA366004E11DCB1DDFE2E56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +namespace +boost + { + namespace + exception_detail + { + template + class + refcount_ptr + { + public: + + refcount_ptr(): + px_(0) + { + } + + ~refcount_ptr() + { + release(); + } + + refcount_ptr( refcount_ptr const & x ): + px_(x.px_) + { + add_ref(); + } + + refcount_ptr & + operator=( refcount_ptr const & x ) + { + adopt(x.px_); + return *this; + } + + void + adopt( T * px ) + { + release(); + px_=px; + add_ref(); + } + + T * + get() const + { + return px_; + } + + private: + + T * px_; + + void + add_ref() + { + if( px_ ) + px_->add_ref(); + } + + void + release() + { + if( px_ ) + px_->release(); + } + }; + } + + //////////////////////////////////////////////////////////////////////// + + template + class error_info; + + typedef error_info throw_function; + typedef error_info throw_file; + typedef error_info throw_line; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template + E const & operator<<( E const &, error_info const & ); + + template + E const & operator<<( E const &, throw_function const & ); + + template + E const & operator<<( E const &, throw_file const & ); + + template + E const & operator<<( E const &, throw_line const & ); + + class exception; + + template + class shared_ptr; + + namespace + exception_detail + { + class error_info_base; + struct type_info_; + + struct + error_info_container + { + virtual char const * diagnostic_information( char const * ) const = 0; + virtual shared_ptr get( type_info_ const & ) const = 0; + virtual void set( shared_ptr const &, type_info_ const & ) = 0; + virtual void add_ref() const = 0; + virtual void release() const = 0; + + protected: + + ~error_info_container() throw() + { + } + }; + + template + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + char const * get_diagnostic_information( exception const &, char const * ); + } + + class + exception + { + protected: + + exception(): + throw_function_(0), + throw_file_(0), + throw_line_(-1) + { + } + +#ifdef __HP_aCC + //On HP aCC, this protected copy constructor prevents throwing boost::exception. + //On all other platforms, the same effect is achieved by the pure virtual destructor. + exception( exception const & x ) throw(): + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_) + { + } +#endif + + virtual ~exception() throw() +#ifndef __HP_aCC + = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. +#endif + ; + +#if defined(__MWERKS__) && __MWERKS__<=0x3207 + public: +#else + private: + + template + friend E const & operator<<( E const &, throw_function const & ); + + template + friend E const & operator<<( E const &, throw_file const & ); + + template + friend E const & operator<<( E const &, throw_line const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + + template + friend E const & operator<<( E const &, error_info const & ); + + template + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; +#endif + mutable exception_detail::refcount_ptr data_; + mutable char const * throw_function_; + mutable char const * throw_file_; + mutable int throw_line_; + }; + + inline + exception:: + ~exception() throw() + { + } + + template + E const & + operator<<( E const & x, throw_function const & y ) + { + x.throw_function_=y.v_; + return x; + } + + template + E const & + operator<<( E const & x, throw_file const & y ) + { + x.throw_file_=y.v_; + return x; + } + + template + E const & + operator<<( E const & x, throw_line const & y ) + { + x.throw_line_=y.v_; + return x; + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + template + struct + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() throw() + { + } + }; + + struct large_size { char c[256]; }; + large_size dispatch( exception * ); + + struct small_size { }; + small_size dispatch( void * ); + + template + struct enable_error_info_helper; + + template + struct + enable_error_info_helper + { + typedef T type; + }; + + template + struct + enable_error_info_helper + { + typedef error_info_injector type; + }; + + template + struct + enable_error_info_return_type + { + typedef typename enable_error_info_helper::type type; + }; + } + + template + inline + typename + exception_detail::enable_error_info_return_type::type + enable_error_info( T const & x ) + { + typedef typename exception_detail::enable_error_info_return_type::type rt; + return rt(x); + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + class + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() throw() + { + } + }; + + inline + void + copy_boost_exception( exception * a, exception const * b ) + { + *a = *b; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + + template + class + clone_impl: + public T, + public clone_base + { + public: + + explicit + clone_impl( T const & x ): + T(x) + { + copy_boost_exception(this,&x); + } + + ~clone_impl() throw() + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this); + } + + void + rethrow() const + { + throw*this; + } + }; + } + + template + inline + exception_detail::clone_impl + enable_current_exception( T const & x ) + { + return exception_detail::clone_impl(x); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/get_error_info.hpp b/src/ext/boost/exception/get_error_info.hpp new file mode 100644 index 00000000000..046f05aeefd --- /dev/null +++ b/src/ext/boost/exception/get_error_info.hpp @@ -0,0 +1,130 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_1A590226753311DD9E4CCF6156D89593 +#define UUID_1A590226753311DD9E4CCF6156D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include +#include + +namespace +boost + { + namespace + exception_detail + { + template + struct + get_info + { + static + typename ErrorInfo::value_type * + get( exception const & x ) + { + if( exception_detail::error_info_container * c=x.data_.get() ) + if( shared_ptr eib = c->get(BOOST_EXCEPTION_STATIC_TYPEID(ErrorInfo)) ) + { +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( 0!=dynamic_cast(eib.get()) ); +#endif + ErrorInfo * w = static_cast(eib.get()); + return &w->value(); + } + return 0; + } + }; + + template <> + struct + get_info + { + static + char const * * + get( exception const & x ) + { + return x.throw_function_ ? &x.throw_function_ : 0; + } + }; + + template <> + struct + get_info + { + static + char const * * + get( exception const & x ) + { + return x.throw_file_ ? &x.throw_file_ : 0; + } + }; + + template <> + struct + get_info + { + static + int * + get( exception const & x ) + { + return x.throw_line_!=-1 ? &x.throw_line_ : 0; + } + }; + + template + struct + get_error_info_return_type + { + typedef R * type; + }; + + template + struct + get_error_info_return_type + { + typedef R const * type; + }; + } + +#ifdef BOOST_NO_RTTI + template + inline + typename ErrorInfo::value_type const * + get_error_info( boost::exception const & x ) + { + return exception_detail::get_info::get(x); + } + template + inline + typename ErrorInfo::value_type * + get_error_info( boost::exception & x ) + { + return exception_detail::get_info::get(x); + } +#else + template + inline + typename exception_detail::get_error_info_return_type::type + get_error_info( E & some_exception ) + { + if( exception const * x = dynamic_cast(&some_exception) ) + return exception_detail::get_info::get(*x); + else + return 0; + } +#endif + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/info.hpp b/src/ext/boost/exception/info.hpp new file mode 100644 index 00000000000..cbbc2c0b2f1 --- /dev/null +++ b/src/ext/boost/exception/info.hpp @@ -0,0 +1,167 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_8D22C4CA9CC811DCAA9133D256D89593 +#define UUID_8D22C4CA9CC811DCAA9133D256D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include +#include +#include +#include + +namespace +boost + { + template + inline + typename enable_if,std::string>::type + to_string( error_info const & x ) + { + return to_string(x.value()); + } + + template + inline + error_info:: + error_info( value_type const & value ): + value_(value) + { + } + + template + inline + error_info:: + ~error_info() throw() + { + } + + template + inline + char const * + error_info:: + tag_typeid_name() const + { + return tag_type_name(); + } + + template + inline + std::string + error_info:: + value_as_string() const + { + return to_string_stub(*this); + } + + namespace + exception_detail + { + class + error_info_container_impl: + public error_info_container + { + public: + + error_info_container_impl(): + count_(0) + { + } + + ~error_info_container_impl() throw() + { + } + + void + set( shared_ptr const & x, type_info_ const & typeid_ ) + { + BOOST_ASSERT(x); + info_[typeid_] = x; + diagnostic_info_str_.clear(); + } + + shared_ptr + get( type_info_ const & ti ) const + { + error_info_map::const_iterator i=info_.find(ti); + if( info_.end()!=i ) + { + shared_ptr const & p = i->second; +#ifndef BOOST_NO_RTTI + BOOST_ASSERT( BOOST_EXCEPTION_DYNAMIC_TYPEID(*p).type_==ti.type_ ); +#endif + return p; + } + return shared_ptr(); + } + + char const * + diagnostic_information( char const * header ) const + { + if( header ) + { + BOOST_ASSERT(*header!=0); + std::ostringstream tmp; + tmp << header; + for( error_info_map::const_iterator i=info_.begin(),end=info_.end(); i!=end; ++i ) + { + shared_ptr const & x = i->second; + tmp << '[' << x->tag_typeid_name() << "] = " << x->value_as_string() << '\n'; + } + tmp.str().swap(diagnostic_info_str_); + } + return diagnostic_info_str_.c_str(); + } + + private: + + friend class boost::exception; + + typedef std::map< type_info_, shared_ptr > error_info_map; + error_info_map info_; + mutable std::string diagnostic_info_str_; + mutable int count_; + + void + add_ref() const + { + ++count_; + } + + void + release() const + { + if( !--count_ ) + delete this; + } + }; + } + + template + inline + E const & + operator<<( E const & x, error_info const & v ) + { + typedef error_info error_info_tag_t; + shared_ptr p( new error_info_tag_t(v) ); + exception_detail::error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); + return x; + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/info_tuple.hpp b/src/ext/boost/exception/info_tuple.hpp new file mode 100644 index 00000000000..34afe421b16 --- /dev/null +++ b/src/ext/boost/exception/info_tuple.hpp @@ -0,0 +1,76 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_63EE924290FB11DC87BB856555D89593 +#define UUID_63EE924290FB11DC87BB856555D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include + +namespace +boost + { + template < + class E, + class Tag1,class T1, + class Tag2,class T2 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info, + error_info > const & v ) + { + return x << v.template get<0>() << v.template get<1>(); + } + + template < + class E, + class Tag1,class T1, + class Tag2,class T2, + class Tag3,class T3 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info, + error_info, + error_info > const & v ) + { + return x << v.template get<0>() << v.template get<1>() << v.template get<2>(); + } + + template < + class E, + class Tag1,class T1, + class Tag2,class T2, + class Tag3,class T3, + class Tag4,class T4 > + inline + E const & + operator<<( + E const & x, + tuple< + error_info, + error_info, + error_info, + error_info > const & v ) + { + return x << v.template get<0>() << v.template get<1>() << v.template get<2>() << v.template get<3>(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/to_string.hpp b/src/ext/boost/exception/to_string.hpp new file mode 100644 index 00000000000..59bf83d4c01 --- /dev/null +++ b/src/ext/boost/exception/to_string.hpp @@ -0,0 +1,83 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_7E48761AD92811DC9011477D56D89593 +#define UUID_7E48761AD92811DC9011477D56D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include + +namespace +boost + { + namespace + to_string_detail + { + template + typename disable_if,char>::type to_string( T const & ); + + template + struct has_to_string_impl; + + template + struct + has_to_string_impl + { + enum e { value=1 }; + }; + + template + struct + has_to_string_impl + { + static T const & f(); + enum e { value=1!=sizeof(to_string(f())) }; + }; + } + + template + inline + typename enable_if,std::string>::type + to_string( T const & x ) + { + std::ostringstream out; + out << x; + return out.str(); + } + + template + struct + has_to_string + { + enum e { value=to_string_detail::has_to_string_impl::value>::value }; + }; + + template + inline + std::string + to_string( std::pair const & x ) + { + return std::string("(") + to_string(x.first) + ',' + to_string(x.second) + ')'; + } + + inline + std::string + to_string( std::exception const & x ) + { + return x.what(); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/exception/to_string_stub.hpp b/src/ext/boost/exception/to_string_stub.hpp new file mode 100644 index 00000000000..e41d3697751 --- /dev/null +++ b/src/ext/boost/exception/to_string_stub.hpp @@ -0,0 +1,109 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_E788439ED9F011DCB181F25B55D89593 +#define UUID_E788439ED9F011DCB181F25B55D89593 +#if defined(__GNUC__) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include +#include + +namespace +boost + { + namespace + exception_detail + { + template + struct + to_string_dispatcher + { + template + static + std::string + convert( T const & x, Stub ) + { + return to_string(x); + } + }; + + template <> + struct + to_string_dispatcher + { + template + static + std::string + convert( T const & x, Stub s ) + { + return s(x); + } + + template + static + std::string + convert( T const & x, std::string s ) + { + return s; + } + + template + static + std::string + convert( T const & x, char const * s ) + { + BOOST_ASSERT(s!=0); + return s; + } + }; + + namespace + to_string_dispatch + { + template + inline + std::string + dispatch( T const & x, Stub s ) + { + return to_string_dispatcher::value>::convert(x,s); + } + } + + template + inline + std::string + string_stub_dump( T const & x ) + { + return "[ " + exception_detail::object_hex_dump(x) + " ]"; + } + } + + template + inline + std::string + to_string_stub( T const & x ) + { + return exception_detail::to_string_dispatch::dispatch(x,&exception_detail::string_stub_dump); + } + + template + inline + std::string + to_string_stub( T const & x, Stub s ) + { + return exception_detail::to_string_dispatch::dispatch(x,s); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/src/ext/boost/memory_order.hpp b/src/ext/boost/memory_order.hpp new file mode 100644 index 00000000000..4945af623b2 --- /dev/null +++ b/src/ext/boost/memory_order.hpp @@ -0,0 +1,53 @@ +#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED +#define BOOST_MEMORY_ORDER_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/memory_order.hpp +// +// Defines enum boost::memory_order per the C++0x working draft +// +// Copyright (c) 2008, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +namespace boost +{ + +// +// Enum values are chosen so that code that needs to insert +// a trailing fence for acquire semantics can use a single +// test such as: +// +// if( mo & memory_order_acquire ) { ...fence... } +// +// For leading fences one can use: +// +// if( mo & memory_order_release ) { ...fence... } +// +// Architectures such as Alpha that need a fence on consume +// can use: +// +// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... } +// + +enum memory_order +{ + memory_order_relaxed = 0, + memory_order_acquire = 1, + memory_order_release = 2, + memory_order_acq_rel = 3, // acquire | release + memory_order_seq_cst = 7, // acq_rel | 4 + memory_order_consume = 8 +}; + +} // namespace boost + +#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED diff --git a/src/ext/boost/shared_ptr.hpp b/src/ext/boost/shared_ptr.hpp new file mode 100644 index 00000000000..d31978c9250 --- /dev/null +++ b/src/ext/boost/shared_ptr.hpp @@ -0,0 +1,19 @@ +#ifndef BOOST_SHARED_PTR_HPP_INCLUDED +#define BOOST_SHARED_PTR_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include + +#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/bad_weak_ptr.hpp b/src/ext/boost/smart_ptr/bad_weak_ptr.hpp new file mode 100644 index 00000000000..3e0a1b72867 --- /dev/null +++ b/src/ext/boost/smart_ptr/bad_weak_ptr.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/bad_weak_ptr.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#ifdef __BORLANDC__ +# pragma warn -8026 // Functions with excep. spec. are not expanded inline +#endif + +namespace boost +{ + +// The standard library that comes with Borland C++ 5.5.1, 5.6.4 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option push -pc +#endif + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "tr1::bad_weak_ptr"; + } +}; + +#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564 +# pragma option pop +#endif + +} // namespace boost + +#ifdef __BORLANDC__ +# pragma warn .8026 // Functions with excep. spec. are not expanded inline +#endif + +#endif // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count.hpp b/src/ext/boost/smart_ptr/detail/atomic_count.hpp new file mode 100644 index 00000000000..cc44ac2f96d --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/atomic_count.hpp - thread/SMP safe reference counter +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// typedef boost::detail::atomic_count; +// +// atomic_count a(n); +// +// (n is convertible to long) +// +// Effects: Constructs an atomic_count with an initial value of n +// +// a; +// +// Returns: (long) the current value of a +// +// ++a; +// +// Effects: Atomically increments the value of a +// Returns: (long) the new value of a +// +// --a; +// +// Effects: Atomically decrements the value of a +// Returns: (long) the new value of a +// +// Important note: when --a returns zero, it must act as a +// read memory barrier (RMB); i.e. the calling thread must +// have a synchronized view of the memory +// +// On Intel IA-32 (x86) memory is always synchronized, so this +// is not a problem. +// +// On many architectures the atomic instructions already act as +// a memory barrier. +// +// This property is necessary for proper reference counting, since +// a thread can update the contents of a shared object, then +// release its reference, and another thread may immediately +// release the last reference causing object destruction. +// +// The destructor needs to have a synchronized view of the +// object to perform proper cleanup. +// +// Original example by Alexander Terekhov: +// +// Given: +// +// - a mutable shared object OBJ; +// - two threads THREAD1 and THREAD2 each holding +// a private smart_ptr object pointing to that OBJ. +// +// t1: THREAD1 updates OBJ (thread-safe via some synchronization) +// and a few cycles later (after "unlock") destroys smart_ptr; +// +// t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization +// with respect to shared mutable object OBJ; OBJ destructors +// are called driven by smart_ptr interface... +// + +#include +#include + +#ifndef BOOST_HAS_THREADS + +namespace boost +{ + +namespace detail +{ + +typedef long atomic_count; + +} + +} + +#elif defined(BOOST_AC_USE_PTHREADS) +# include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) +# include + +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include + +#elif defined( BOOST_SP_HAS_SYNC ) +# include + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +# include + +#elif defined(BOOST_HAS_PTHREADS) + +# define BOOST_AC_USE_PTHREADS +# include + +#else + +// Use #define BOOST_DISABLE_THREADS to avoid the error +#error Unrecognized threading platform + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_gcc.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_gcc.hpp new file mode 100644 index 00000000000..54807e944e2 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_gcc.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED + +// +// boost/detail/atomic_count_gcc.hpp +// +// atomic_count for GNU libstdc++ v3 +// +// http://gcc.gnu.org/onlinedocs/porting/Thread-safety.html +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2002 Lars Gullik Bjnnes +// Copyright 2003-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402 +# include +#else +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#if defined(__GLIBCXX__) // g++ 3.4+ + +using __gnu_cxx::__atomic_add; +using __gnu_cxx::__exchange_and_add; + +#endif + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( v ) {} + + long operator++() + { + return __exchange_and_add( &value_, +1 ) + 1; + } + + long operator--() + { + return __exchange_and_add( &value_, -1 ) - 1; + } + + operator long() const + { + return __exchange_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable _Atomic_word value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp new file mode 100644 index 00000000000..5c44d7c1efa --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_gcc_x86.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED + +// +// boost/detail/atomic_count_gcc_x86.hpp +// +// atomic_count for g++ on 486+/AMD64 +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} + + long operator++() + { + return atomic_exchange_and_add( &value_, +1 ) + 1; + } + + long operator--() + { + return atomic_exchange_and_add( &value_, -1 ) - 1; + } + + operator long() const + { + return atomic_exchange_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable int value_; + +private: + + static int atomic_exchange_and_add( int * pw, int dv ) + { + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "+m"( *pw ), "=r"( r ): // outputs (%0, %1) + "1"( dv ): // inputs (%2 == %1) + "memory", "cc" // clobbers + ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_pthreads.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_pthreads.hpp new file mode 100644 index 00000000000..05f78673c68 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_pthreads.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED + +// +// boost/detail/atomic_count_pthreads.hpp +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +// +// The generic pthread_mutex-based implementation sometimes leads to +// inefficiencies. Example: a class with two atomic_count members +// can get away with a single mutex. +// +// Users can detect this situation by checking BOOST_AC_USE_PTHREADS. +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +private: + + class scoped_lock + { + public: + + scoped_lock(pthread_mutex_t & m): m_(m) + { + pthread_mutex_lock(&m_); + } + + ~scoped_lock() + { + pthread_mutex_unlock(&m_); + } + + private: + + pthread_mutex_t & m_; + }; + +public: + + explicit atomic_count(long v): value_(v) + { + pthread_mutex_init(&mutex_, 0); + } + + ~atomic_count() + { + pthread_mutex_destroy(&mutex_); + } + + long operator++() + { + scoped_lock lock(mutex_); + return ++value_; + } + + long operator--() + { + scoped_lock lock(mutex_); + return --value_; + } + + operator long() const + { + scoped_lock lock(mutex_); + return value_; + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable pthread_mutex_t mutex_; + long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_PTHREADS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_solaris.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_solaris.hpp new file mode 100644 index 00000000000..a13bcfb4230 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_solaris.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED + +// +// boost/detail/atomic_count_solaris.hpp +// based on: boost/detail/atomic_count_win32.hpp +// +// Copyright (c) 2001-2005 Peter Dimov +// Copyright (c) 2006 Michael van der Westhuizen +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( uint32_t v ): value_( v ) + { + } + + long operator++() + { + return atomic_inc_32_nv( &value_ ); + } + + long operator--() + { + return atomic_dec_32_nv( &value_ ); + } + + operator uint32_t() const + { + return static_cast( value_ ); + } + +private: + + atomic_count( atomic_count const & ); + atomic_count & operator=( atomic_count const & ); + + uint32_t value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SOLARIS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_sync.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_sync.hpp new file mode 100644 index 00000000000..b6359b5bcf0 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_sync.hpp @@ -0,0 +1,61 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED + +// +// boost/detail/atomic_count_sync.hpp +// +// atomic_count for g++ 4.1+ +// +// http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html +// +// Copyright 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( v ) {} + + long operator++() + { + return __sync_add_and_fetch( &value_, 1 ); + } + + long operator--() + { + return __sync_add_and_fetch( &value_, -1 ); + } + + operator long() const + { + return __sync_fetch_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/atomic_count_win32.hpp b/src/ext/boost/smart_ptr/detail/atomic_count_win32.hpp new file mode 100644 index 00000000000..60a056943b6 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/atomic_count_win32.hpp @@ -0,0 +1,63 @@ +#ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/atomic_count_win32.hpp +// +// Copyright (c) 2001-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ): value_( v ) + { + } + + long operator++() + { + return BOOST_INTERLOCKED_INCREMENT( &value_ ); + } + + long operator--() + { + return BOOST_INTERLOCKED_DECREMENT( &value_ ); + } + + operator long() const + { + return static_cast( value_ ); + } + +private: + + atomic_count( atomic_count const & ); + atomic_count & operator=( atomic_count const & ); + + long value_; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_WIN32_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/lightweight_mutex.hpp b/src/ext/boost/smart_ptr/detail/lightweight_mutex.hpp new file mode 100644 index 00000000000..d46b1932c2b --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/lightweight_mutex.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lightweight_mutex.hpp - lightweight mutex +// +// Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// typedef boost::detail::lightweight_mutex; +// +// boost::detail::lightweight_mutex is a header-only implementation of +// a subset of the Mutex concept requirements: +// +// http://www.boost.org/doc/html/threads/concepts.html#threads.concepts.Mutex +// +// It maps to a CRITICAL_SECTION on Windows or a pthread_mutex on POSIX. +// + +#include + +#if !defined(BOOST_HAS_THREADS) +# include +#elif defined(BOOST_HAS_PTHREADS) +# include +#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include +#else +// Use #define BOOST_DISABLE_THREADS to avoid the error +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/lwm_nop.hpp b/src/ext/boost/smart_ptr/detail/lwm_nop.hpp new file mode 100644 index 00000000000..521a88ec1cd --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/lwm_nop.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_nop.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +public: + + typedef lightweight_mutex scoped_lock; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_NOP_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/lwm_pthreads.hpp b/src/ext/boost/smart_ptr/detail/lwm_pthreads.hpp new file mode 100644 index 00000000000..8eda5182338 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/lwm_pthreads.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_pthreads.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +private: + + pthread_mutex_t m_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + BOOST_VERIFY( pthread_mutex_init( &m_, pthread_mutexattr_default ) == 0 ); +#else + BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 ); +#endif + } + + ~lightweight_mutex() + { + BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 ); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + pthread_mutex_t & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + scoped_lock(lightweight_mutex & m): m_(m.m_) + { + BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 ); + } + + ~scoped_lock() + { + BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 ); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_PTHREADS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/lwm_win32_cs.hpp b/src/ext/boost/smart_ptr/detail/lwm_win32_cs.hpp new file mode 100644 index 00000000000..00477e49f8f --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/lwm_win32_cs.hpp @@ -0,0 +1,108 @@ +#ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/lwm_win32_cs.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#ifdef BOOST_USE_WINDOWS_H +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#ifndef BOOST_USE_WINDOWS_H + +struct critical_section +{ + struct critical_section_debug * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; +#if defined(_WIN64) + unsigned __int64 SpinCount; +#else + unsigned long SpinCount; +#endif +}; + +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *); + +#else + +typedef ::CRITICAL_SECTION critical_section; + +#endif // #ifndef BOOST_USE_WINDOWS_H + +class lightweight_mutex +{ +private: + + critical_section cs_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + InitializeCriticalSection(&cs_); + } + + ~lightweight_mutex() + { + DeleteCriticalSection(&cs_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + lightweight_mutex & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + explicit scoped_lock(lightweight_mutex & m): m_(m) + { + EnterCriticalSection(&m_.cs_); + } + + ~scoped_lock() + { + LeaveCriticalSection(&m_.cs_); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_LWM_WIN32_CS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/operator_bool.hpp b/src/ext/boost/smart_ptr/detail/operator_bool.hpp new file mode 100644 index 00000000000..842a05d02bc --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/operator_bool.hpp @@ -0,0 +1,56 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2001-2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#if ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) + + operator bool () const + { + return px != 0; + } + +#elif defined( _MANAGED ) + + static void unspecified_bool( this_type*** ) + { + } + + typedef void (*unspecified_bool_type)( this_type*** ); + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: unspecified_bool; + } + +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } + +#else + + typedef T * this_type::*unspecified_bool_type; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } + +#endif + + // operator! is redundant, but some compilers need it + bool operator! () const // never throws + { + return px == 0; + } diff --git a/src/ext/boost/smart_ptr/detail/quick_allocator.hpp b/src/ext/boost/smart_ptr/detail/quick_allocator.hpp new file mode 100644 index 00000000000..159bd5e7aa8 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/quick_allocator.hpp @@ -0,0 +1,199 @@ +#ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/quick_allocator.hpp +// +// Copyright (c) 2003 David Abrahams +// Copyright (c) 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#include +#include +#include + +#include // ::operator new, ::operator delete +#include // std::size_t + +namespace boost +{ + +namespace detail +{ + +template union freeblock +{ + typedef typename boost::type_with_alignment::type aligner_type; + aligner_type aligner; + char bytes[size]; + freeblock * next; +}; + +template struct allocator_impl +{ + typedef freeblock block; + + // It may seem odd to use such small pages. + // + // However, on a typical Windows implementation that uses + // the OS allocator, "normal size" pages interact with the + // "ordinary" operator new, slowing it down dramatically. + // + // 512 byte pages are handled by the small object allocator, + // and don't interfere with ::new. + // + // The other alternative is to use much bigger pages (1M.) + // + // It is surprisingly easy to hit pathological behavior by + // varying the page size. g++ 2.96 on Red Hat Linux 7.2, + // for example, passionately dislikes 496. 512 seems OK. + +#if defined(BOOST_QA_PAGE_SIZE) + + enum { items_per_page = BOOST_QA_PAGE_SIZE / size }; + +#else + + enum { items_per_page = 512 / size }; // 1048560 / size + +#endif + +#ifdef BOOST_HAS_THREADS + + static lightweight_mutex & mutex() + { + static freeblock< sizeof( lightweight_mutex ), boost::alignment_of< lightweight_mutex >::value > fbm; + static lightweight_mutex * pm = new( &fbm ) lightweight_mutex; + return *pm; + } + + static lightweight_mutex * mutex_init; + +#endif + + static block * free; + static block * page; + static unsigned last; + + static inline void * alloc() + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + // "Listen to me carefully: there is no memory leak" + // -- Scott Meyers, Eff C++ 2nd Ed Item 10 + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + + static inline void * alloc(std::size_t n) + { + if(n != size) // class-specific new called for a derived object + { + return ::operator new(n); + } + else + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + if(last == items_per_page) + { + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; + } + } + } + + static inline void dealloc(void * pv) + { + if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } + + static inline void dealloc(void * pv, std::size_t n) + { + if(n != size) // class-specific delete called for a derived object + { + ::operator delete(pv); + } + else if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock( mutex() ); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } +}; + +#ifdef BOOST_HAS_THREADS + +template + lightweight_mutex * allocator_impl::mutex_init = &allocator_impl::mutex(); + +#endif + +template + freeblock * allocator_impl::free = 0; + +template + freeblock * allocator_impl::page = 0; + +template + unsigned allocator_impl::last = allocator_impl::items_per_page; + +template +struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/shared_array_nmt.hpp b/src/ext/boost/smart_ptr/detail/shared_array_nmt.hpp new file mode 100644 index 00000000000..450c9bcf595 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/shared_array_nmt.hpp @@ -0,0 +1,151 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED + +// +// detail/shared_array_nmt.hpp - shared_array.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation. +// + +#include +#include +#include +#include + +#include // for std::ptrdiff_t +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_array +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + + explicit shared_array(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_array_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_array_delete(p); + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_array() + { + if(--*pn == 0) + { + boost::checked_array_delete(px); + delete pn; + } + } + + shared_array(shared_array const & r) : px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_array & operator=(shared_array const & r) + { + shared_array(r).swap(*this); + return *this; + } + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_array(p).swap(*this); + } + + T * get() const // never throws + { + return px; + } + + T & operator[](std::ptrdiff_t i) const // never throws + { + BOOST_ASSERT(px != 0); + BOOST_ASSERT(i >= 0); + return px[i]; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_array & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter + +}; // shared_array + +template inline bool operator==(shared_array const & a, shared_array const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_array const & a, shared_array const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_array const & a, shared_array const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_array & a, shared_array & b) +{ + a.swap(b); +} + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_ARRAY_NMT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/shared_count.hpp b/src/ext/boost/smart_ptr/detail/shared_count.hpp new file mode 100644 index 00000000000..4943e37643f --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/shared_count.hpp @@ -0,0 +1,444 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#ifdef __BORLANDC__ +# pragma warn -8027 // Functions containing try are not expanded inline +#endif + +#include +#include +#include +#include +#include +#include +#include +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr +#include // std::less +#include // std::bad_alloc + +namespace boost +{ + +namespace detail +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +#endif + +struct sp_nothrow_tag {}; + +class weak_count; + +class shared_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + + template explicit shared_count( Y * p ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_p( p ); + } + catch(...) + { + boost::checked_delete( p ); + throw; + } + +#else + + pi_ = new sp_counted_impl_p( p ); + + if( pi_ == 0 ) + { + boost::checked_delete( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + template shared_count( Y * p, D d ): pi_(0) +#else + template shared_count( P p, D d ): pi_(0) +#endif +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 ) + typedef Y* P; +#endif +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_impl_pd(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + +#else + + pi_ = new sp_counted_impl_pd(p, d); + + if(pi_ == 0) + { + d(p); // delete p + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + template shared_count( P p, D d, A a ): pi_( 0 ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + typedef sp_counted_impl_pda impl_type; + typedef typename A::template rebind< impl_type >::other A2; + + A2 a2( a ); + +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + } + catch(...) + { + d( p ); + + if( pi_ != 0 ) + { + a2.deallocate( static_cast< impl_type* >( pi_ ), 1 ); + } + + throw; + } + +#else + + pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) ); + + if( pi_ != 0 ) + { + new( static_cast< void* >( pi_ ) ) impl_type( p, d, a ); + } + else + { + d( p ); + boost::throw_exception( std::bad_alloc() ); + } + +#endif + } + +#ifndef BOOST_NO_AUTO_PTR + + // auto_ptr is special cased to provide the strong guarantee + + template + explicit shared_count( std::auto_ptr & r ): pi_( new sp_counted_impl_p( r.get() ) ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifdef BOOST_NO_EXCEPTIONS + + if( pi_ == 0 ) + { + boost::throw_exception(std::bad_alloc()); + } + +#endif + + r.release(); + } + +#endif + + ~shared_count() // nothrow + { + if( pi_ != 0 ) pi_->release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if( pi_ != 0 ) pi_->add_ref_copy(); + } + +#if defined( BOOST_HAS_RVALUE_REFS ) + + shared_count(shared_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if( tmp != 0 ) tmp->add_ref_copy(); + if( pi_ != 0 ) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()( a.pi_, b.pi_ ); + } + + void * get_deleter( sp_typeinfo const & ti ) const + { + return pi_? pi_->get_deleter( ti ): 0; + } +}; + + +class weak_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + +// Move support + +#if defined( BOOST_HAS_RVALUE_REFS ) + + weak_count(weak_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if( tmp != pi_ ) + { + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + } + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool empty() const // nothrow + { + return pi_ == 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ == 0 || !pi_->add_ref_lock() ) + { + boost::throw_exception( boost::bad_weak_ptr() ); + } +} + +inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ != 0 && !pi_->add_ref_lock() ) + { + pi_ = 0; + } +} + +} // namespace detail + +} // namespace boost + +#ifdef __BORLANDC__ +# pragma warn .8027 // Functions containing try are not expanded inline +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/shared_ptr_nmt.hpp b/src/ext/boost/smart_ptr/detail/shared_ptr_nmt.hpp new file mode 100644 index 00000000000..afc1ec03f1b --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/shared_ptr_nmt.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED + +// +// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include +#include +#include +#include + +#ifndef BOOST_NO_AUTO_PTR +# include // for std::auto_ptr +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_ptr +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + typedef T value_type; + + explicit shared_ptr(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_delete(p); + boost::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_ptr() + { + if(--*pn == 0) + { + boost::checked_delete(px); + delete pn; + } + } + + shared_ptr(shared_ptr const & r): px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_ptr & operator=(shared_ptr const & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit shared_ptr(std::auto_ptr & r) + { + pn = new count_type(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_ptr & operator=(std::auto_ptr & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#endif + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_ptr(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_ptr & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter +}; + +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_ptr & a, shared_ptr & b) +{ + a.swap(b); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr const & p) +{ + return p.get(); +} + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_PTR_NMT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_convertible.hpp b/src/ext/boost/smart_ptr/detail/sp_convertible.hpp new file mode 100644 index 00000000000..b7f0ea8f2dd --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_convertible.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_convertible.hpp +// +// Copyright 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x620 ) +# define BOOST_SP_NO_SP_CONVERTIBLE +#endif + +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + +namespace boost +{ + +namespace detail +{ + +template< class Y, class T > struct sp_convertible +{ + typedef char (&yes) [1]; + typedef char (&no) [2]; + + static yes f( T* ); + static no f( ... ); + + enum _vt { value = sizeof( f( static_cast(0) ) ) == sizeof(yes) }; +}; + +struct sp_empty +{ +}; + +template< bool > struct sp_enable_if_convertible_impl; + +template<> struct sp_enable_if_convertible_impl +{ + typedef sp_empty type; +}; + +template<> struct sp_enable_if_convertible_impl +{ +}; + +template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base.hpp new file mode 100644 index 00000000000..cab45cce30d --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base.hpp @@ -0,0 +1,70 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base.hpp +// +// Copyright 2005, 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +#if defined( BOOST_SP_DISABLE_THREADS ) +# include + +#elif defined( BOOST_SP_USE_SPINLOCK ) +# include + +#elif defined( BOOST_SP_USE_PTHREADS ) +# include + +#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 ) +# include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) +# include + +#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) +# include + +#elif defined(__HP_aCC) && defined(__ia64) +# include + +#elif defined( __MWERKS__ ) && defined( __POWERPC__ ) +# include + +#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) +# include + +#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) +# include + +#elif defined( BOOST_SP_HAS_SYNC ) +# include + +#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) ) +# include + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__) +# include + +#elif !defined( BOOST_HAS_THREADS ) +# include + +#else +# include + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp new file mode 100644 index 00000000000..dffd995b16e --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_acc_ia64.hpp - aC++ on HP-UX IA64 +// +// Copyright 2007 Baruch Zilber +// Copyright 2007 Boris Gubenko +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + _Asm_fetchadd(_FASZ_W, _SEM_REL, pw, +1, _LDHINT_NONE); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int r = static_cast(_Asm_fetchadd(_FASZ_W, _SEM_REL, pw, -1, _LDHINT_NONE)); + if (1 == r) + { + _Asm_mf(); + } + + return r - 1; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int v = *pw; + + for (;;) + { + if (0 == v) + { + return 0; + } + + _Asm_mov_to_ar(_AREG_CCV, + v, + (_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE)); + int r = static_cast(_Asm_cmpxchg(_SZ_W, _SEM_ACQ, pw, v + 1, _LDHINT_NONE)); + if (r == v) + { + return r + 1; + } + + v = r; + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_ACC_IA64_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp new file mode 100644 index 00000000000..51ac56a9438 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -0,0 +1,170 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_cw_ppc.hpp - CodeWarrior on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + addi a, a, 1 + stwcx. a, 0, pw + bne- loop + } +} + +inline long atomic_decrement( register long * pw ) +{ + register int a; + + asm + { + sync + +loop: + + lwarx a, 0, pw + addi a, a, -1 + stwcx. a, 0, pw + bne- loop + + isync + } + + return a; +} + +inline long atomic_conditional_increment( register long * pw ) +{ + register int a; + + asm + { +loop: + + lwarx a, 0, pw + cmpwi a, 0 + beq store + + addi a, a, 1 + +store: + + stwcx. a, 0, pw + bne- loop + } + + return a; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_PPC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp new file mode 100644 index 00000000000..1234e78a6b4 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_cw_x86.hpp - CodeWarrion on 486+ +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2005 Rene Rivera +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + asm + { + mov esi, [pw] + mov eax, dv + lock xadd dword ptr [esi], eax + } +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + asm + { + mov esi, [pw] + lock inc dword ptr [esi] + } +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + asm + { + mov esi, [pw] + mov eax, dword ptr [esi] + L0: + test eax, eax + je L1 + mov ebx, eax + inc ebx + lock cmpxchg dword ptr [esi], ebx + jne L0 + L1: + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CW_X86_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp new file mode 100644 index 00000000000..d122a49bdb2 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -0,0 +1,157 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED + +// +// detail/sp_counted_base_gcc_ia64.hpp - g++ on IA64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2006 Peter Dimov +// Copyright 2005 Ben Hutchings +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + // No barrier is required here but fetchadd always has an acquire or + // release barrier associated with it. We choose release as it should be + // cheaper. + __asm__ ("fetchadd4.rel %0=%1,1" : + "=r"(tmp), "=m"(*pw) : + "m"( *pw )); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ (" fetchadd4.rel %0=%1,-1 ;; \n" + " cmp.eq p7,p0=1,%0 ;; \n" + "(p7) ld4.acq %0=%1 " : + "=&r"(rv), "=m"(*pw) : + "m"( *pw ) : + "p7"); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp, tmp2; + + __asm__ ("0: ld4 %0=%3 ;; \n" + " cmp.eq p7,p0=0,%0 ;; \n" + "(p7) br.cond.spnt 1f \n" + " mov ar.ccv=%0 \n" + " add %1=1,%0 ;; \n" + " cmpxchg4.acq %2=%3,%1,ar.ccv ;; \n" + " cmp.ne p7,p0=%0,%2 ;; \n" + "(p7) br.cond.spnt 0b \n" + " mov %0=%1 ;; \n" + "1:" : + "=&r"(rv), "=&r"(tmp), "=&r"(tmp2), "=m"(*pw) : + "m"( *pw ) : + "ar.ccv", "p7"); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); // TODO use ld.acq here + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_IA64_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp new file mode 100644 index 00000000000..0c69b0b891f --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -0,0 +1,172 @@ +#ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED +#define BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_mips.hpp - g++ on MIPS +// +// Copyright (c) 2009, Spirent Communications, Inc. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %0, %1\n\t" + "addiu %0, 1\n\t" + "sc %0, %1\n\t" + "beqz %0, 0b": + "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ) + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %1, %2\n\t" + "addiu %0, %1, -1\n\t" + "sc %0, %2\n\t" + "beqz %0, 0b\n\t" + "addiu %0, %1, -1": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv, tmp; + + __asm__ __volatile__ + ( + "0:\n\t" + "ll %0, %2\n\t" + "beqz %0, 1f\n\t" + "addiu %1, %0, 1\n\t" + "sc %1, %2\n\t" + "beqz %1, 0b\n\t" + "addiu %0, %0, 1\n\t" + "1:": + "=&r"( rv ), "=&r"( tmp ), "=m"( *pw ): + "m"( *pw ): + "memory" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_GCC_MIPS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp new file mode 100644 index 00000000000..7f5c414f17f --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -0,0 +1,181 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_ppc.hpp - g++ on PowerPC +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline void atomic_increment( int * pw ) +{ + // ++*pw; + + int tmp; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, 1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( tmp ): + "r"( pw ), "m"( *pw ): + "cc" + ); +} + +inline int atomic_decrement( int * pw ) +{ + // return --*pw; + + int rv; + + __asm__ __volatile__ + ( + "sync\n\t" + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "addi %1, %1, -1\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b\n\t" + "isync": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "memory", "cc" + ); + + return rv; +} + +inline int atomic_conditional_increment( int * pw ) +{ + // if( *pw != 0 ) ++*pw; + // return *pw; + + int rv; + + __asm__ + ( + "0:\n\t" + "lwarx %1, 0, %2\n\t" + "cmpwi %1, 0\n\t" + "beq 1f\n\t" + "addi %1, %1, 1\n\t" + "1:\n\t" + "stwcx. %1, 0, %2\n\t" + "bne- 0b": + + "=m"( *pw ), "=&b"( rv ): + "r"( pw ), "m"( *pw ): + "cc" + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_PPC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp new file mode 100644 index 00000000000..21fa59dcc4f --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -0,0 +1,166 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_gcc_sparc.hpp - g++ on Sparc V8+ +// +// Copyright (c) 2006 Piotr Wyderski +// Copyright (c) 2006 Tomas Puverle +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Thanks to Michael van der Westhuizen + +#include +#include // int32_t + +namespace boost +{ + +namespace detail +{ + +inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) +{ + __asm__ __volatile__( "cas [%1], %2, %0" + : "+r" (swap_) + : "r" (dest_), "r" (compare_) + : "memory" ); + + return swap_; +} + +inline int32_t atomic_fetch_and_add( int32_t * pw, int32_t dv ) +{ + // long r = *pw; + // *pw += dv; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( __builtin_expect((compare_and_swap(pw, r, r + dv) == r), 1) ) + { + return r; + } + } +} + +inline void atomic_increment( int32_t * pw ) +{ + atomic_fetch_and_add( pw, 1 ); +} + +inline int32_t atomic_decrement( int32_t * pw ) +{ + return atomic_fetch_and_add( pw, -1 ); +} + +inline int32_t atomic_conditional_increment( int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + for( ;; ) + { + int32_t r = *pw; + + if( r == 0 ) + { + return r; + } + + if( __builtin_expect( ( compare_and_swap( pw, r, r + 1 ) == r ), 1 ) ) + { + return r; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int32_t use_count_; // #shared + int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_SPARC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp new file mode 100644 index 00000000000..4d7fa8d4ab3 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -0,0 +1,173 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64 +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "=m"( *pw ), "=r"( r ): // outputs (%0, %1) + "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) + "memory", "cc" // clobbers + ); + + return r; +} + +inline void atomic_increment( int * pw ) +{ + //atomic_exchange_and_add( pw, 1 ); + + __asm__ + ( + "lock\n\t" + "incl %0": + "=m"( *pw ): // output (%0) + "m"( *pw ): // input (%1) + "cc" // clobbers + ); +} + +inline int atomic_conditional_increment( int * pw ) +{ + // int rv = *pw; + // if( rv != 0 ) ++*pw; + // return rv; + + int rv, tmp; + + __asm__ + ( + "movl %0, %%eax\n\t" + "0:\n\t" + "test %%eax, %%eax\n\t" + "je 1f\n\t" + "movl %%eax, %2\n\t" + "incl %2\n\t" + "lock\n\t" + "cmpxchgl %2, %0\n\t" + "jne 0b\n\t" + "1:": + "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) + "m"( *pw ): // input (%3) + "cc" // clobbers + ); + + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp new file mode 100644 index 00000000000..dfd70e7d7e0 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_nt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + ++use_count_; + } + + bool add_ref_lock() // true on success + { + if( use_count_ == 0 ) return false; + ++use_count_; + return true; + } + + void release() // nothrow + { + if( --use_count_ == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + ++weak_count_; + } + + void weak_release() // nothrow + { + if( --weak_count_ == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return use_count_; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_NT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp new file mode 100644 index 00000000000..3c56fecfc36 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -0,0 +1,135 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_pt.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable pthread_mutex_t m_; + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { +// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init + +#if defined(__hpux) && defined(_DECTHREADS_) + pthread_mutex_init( &m_, pthread_mutexattr_default ); +#else + pthread_mutex_init( &m_, 0 ); +#endif + } + + virtual ~sp_counted_base() // nothrow + { + pthread_mutex_destroy( &m_ ); + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + pthread_mutex_lock( &m_ ); + ++use_count_; + pthread_mutex_unlock( &m_ ); + } + + bool add_ref_lock() // true on success + { + pthread_mutex_lock( &m_ ); + bool r = use_count_ == 0? false: ( ++use_count_, true ); + pthread_mutex_unlock( &m_ ); + return r; + } + + void release() // nothrow + { + pthread_mutex_lock( &m_ ); + long new_use_count = --use_count_; + pthread_mutex_unlock( &m_ ); + + if( new_use_count == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + pthread_mutex_lock( &m_ ); + ++weak_count_; + pthread_mutex_unlock( &m_ ); + } + + void weak_release() // nothrow + { + pthread_mutex_lock( &m_ ); + long new_weak_count = --weak_count_; + pthread_mutex_unlock( &m_ ); + + if( new_weak_count == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + pthread_mutex_lock( &m_ ); + long r = use_count_; + pthread_mutex_unlock( &m_ ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_PT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp new file mode 100644 index 00000000000..d1b6beceb18 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_solaris.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED + +// +// detail/sp_counted_base_solaris.hpp +// based on: detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// Copyright 2006 Michael van der Westhuizen +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + uint32_t use_count_; // #shared + uint32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_inc_32( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + uint32_t tmp = static_cast< uint32_t const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + if( atomic_cas_32( &use_count_, tmp, tmp + 1 ) == tmp ) return true; + } + } + + void release() // nothrow + { + if( atomic_dec_32_nv( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_inc_32( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_dec_32_nv( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SOLARIS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp new file mode 100644 index 00000000000..bbd11e60e90 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_spin.hpp - spinlock pool atomic emulation +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline int atomic_exchange_and_add( int * pw, int dv ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + + int r = *pw; + *pw += dv; + return r; +} + +inline void atomic_increment( int * pw ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + ++*pw; +} + +inline int atomic_conditional_increment( int * pw ) +{ + spinlock_pool<1>::scoped_lock lock( pw ); + + int rv = *pw; + if( rv != 0 ) ++*pw; + return rv; +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + int use_count_; // #shared + int weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_exchange_and_add( &use_count_, -1 ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + spinlock_pool<1>::scoped_lock lock( &use_count_ ); + return use_count_; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp new file mode 100644 index 00000000000..41f654e19b1 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -0,0 +1,155 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// detail/sp_counted_base_sync.hpp - g++ 4.1+ __sync intrinsics +// +// Copyright (c) 2007 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#if INT_MAX >= 2147483647 + +typedef int sp_int32_t; + +#else + +typedef long sp_int32_t; + +#endif + +inline void atomic_increment( sp_int32_t * pw ) +{ + __sync_fetch_and_add( pw, 1 ); +} + +inline sp_int32_t atomic_decrement( sp_int32_t * pw ) +{ + return __sync_fetch_and_add( pw, -1 ); +} + +inline sp_int32_t atomic_conditional_increment( sp_int32_t * pw ) +{ + // long r = *pw; + // if( r != 0 ) ++*pw; + // return r; + + sp_int32_t r = *pw; + + for( ;; ) + { + if( r == 0 ) + { + return r; + } + + sp_int32_t r2 = __sync_val_compare_and_swap( pw, r, r + 1 ); + + if( r2 == r ) + { + return r; + } + else + { + r = r2; + } + } +} + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + sp_int32_t use_count_; // #shared + sp_int32_t weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + atomic_increment( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + return atomic_conditional_increment( &use_count_ ) != 0; + } + + void release() // nothrow + { + if( atomic_decrement( &use_count_ ) == 1 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + atomic_increment( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( atomic_decrement( &weak_count_ ) == 1 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return const_cast< sp_int32_t const volatile & >( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SYNC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_base_w32.hpp new file mode 100644 index 00000000000..06aa4565712 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -0,0 +1,130 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_base_w32.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// +// Lock-free algorithm by Alexander Terekhov +// +// Thanks to Ben Hitchings for the #weak + (#shared != 0) +// formulation +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +class sp_counted_base +{ +private: + + sp_counted_base( sp_counted_base const & ); + sp_counted_base & operator= ( sp_counted_base const & ); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +public: + + sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destroy() is called when weak_count_ drops to zero. + + virtual void destroy() // nothrow + { + delete this; + } + + virtual void * get_deleter( sp_typeinfo const & ti ) = 0; + + void add_ref_copy() + { + BOOST_INTERLOCKED_INCREMENT( &use_count_ ); + } + + bool add_ref_lock() // true on success + { + for( ;; ) + { + long tmp = static_cast< long const volatile& >( use_count_ ); + if( tmp == 0 ) return false; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 ) + + // work around a code generation bug + + long tmp2 = tmp + 1; + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true; + +#else + + if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true; + +#endif + } + } + + void release() // nothrow + { + if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 ) + { + dispose(); + weak_release(); + } + } + + void weak_add_ref() // nothrow + { + BOOST_INTERLOCKED_INCREMENT( &weak_count_ ); + } + + void weak_release() // nothrow + { + if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 ) + { + destroy(); + } + } + + long use_count() const // nothrow + { + return static_cast( use_count_ ); + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_counted_impl.hpp b/src/ext/boost/smart_ptr/detail/sp_counted_impl.hpp new file mode 100644 index 00000000000..397421ae9fa --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_counted_impl.hpp @@ -0,0 +1,231 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// detail/sp_counted_impl.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// Copyright 2004-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) +#include // std::allocator +#endif + +#include // std::size_t + +namespace boost +{ + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn ); +void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn ); + +#endif + +namespace detail +{ + +template class sp_counted_impl_p: public sp_counted_base +{ +private: + + X * px_; + + sp_counted_impl_p( sp_counted_impl_p const & ); + sp_counted_impl_p & operator= ( sp_counted_impl_p const & ); + + typedef sp_counted_impl_p this_type; + +public: + + explicit sp_counted_impl_p( X * px ): px_( px ) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px, sizeof(X), this ); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_destructor_hook( px_, sizeof(X), this ); +#endif + boost::checked_delete( px_ ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ) + { + return 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_impl_pd: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_impl_pd( sp_counted_impl_pd const & ); + sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & ); + + typedef sp_counted_impl_pd this_type; + +public: + + // pre: d(p) must not throw + + sp_counted_impl_pd( P p, D d ): ptr(p), del(d) + { + } + + virtual void dispose() // nothrow + { + del( ptr ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast( del ): 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new( std::size_t ) + { + return std::allocator().allocate( 1, static_cast(0) ); + } + + void operator delete( void * p ) + { + std::allocator().deallocate( static_cast(p), 1 ); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new( std::size_t ) + { + return quick_allocator::alloc(); + } + + void operator delete( void * p ) + { + quick_allocator::dealloc( p ); + } + +#endif +}; + +template class sp_counted_impl_pda: public sp_counted_base +{ +private: + + P p_; // copy constructor must not throw + D d_; // copy constructor must not throw + A a_; // copy constructor must not throw + + sp_counted_impl_pda( sp_counted_impl_pda const & ); + sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & ); + + typedef sp_counted_impl_pda this_type; + +public: + + // pre: d( p ) must not throw + + sp_counted_impl_pda( P p, D d, A a ): p_( p ), d_( d ), a_( a ) + { + } + + virtual void dispose() // nothrow + { + d_( p_ ); + } + + virtual void destroy() // nothrow + { + typedef typename A::template rebind< this_type >::other A2; + + A2 a2( a_ ); + + this->~this_type(); + a2.deallocate( this, 1 ); + } + + virtual void * get_deleter( detail::sp_typeinfo const & ti ) + { + return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast( d_ ): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/sp_has_sync.hpp b/src/ext/boost/smart_ptr/detail/sp_has_sync.hpp new file mode 100644 index 00000000000..7fcd09ef08b --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/sp_has_sync.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/smart_ptr/detail/sp_has_sync.hpp +// +// Copyright (c) 2008, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics +// are available. +// + +#if defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + +#define BOOST_SP_HAS_SYNC + +#if defined( __arm__ ) || defined( __armel__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __hppa ) || defined( __hppa__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __m68k__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __sparc__ ) +#undef BOOST_SP_HAS_SYNC +#endif + +#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1100 ) +#undef BOOST_SP_HAS_SYNC +#endif + +#endif // __GNUC__ * 100 + __GNUC_MINOR__ >= 401 + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock.hpp b/src/ext/boost/smart_ptr/detail/spinlock.hpp new file mode 100644 index 00000000000..1640a38d494 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock.hpp @@ -0,0 +1,53 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/spinlock.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// struct spinlock +// { +// void lock(); +// bool try_lock(); +// void unlock(); +// +// class scoped_lock; +// }; +// +// #define BOOST_DETAIL_SPINLOCK_INIT +// + +#include +#include + +#if defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) +# include + +#elif defined( BOOST_SP_HAS_SYNC ) +# include + +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# include + +#elif defined(BOOST_HAS_PTHREADS) +# include + +#elif !defined(BOOST_HAS_THREADS) +# include + +#else +# error Unrecognized threading platform +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp b/src/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp new file mode 100644 index 00000000000..ba6c511e280 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + int v_; + +public: + + bool try_lock() + { + int r; + + __asm__ __volatile__( + "swp %0, %1, [%2]": + "=&r"( r ): // outputs + "r"( 1 ), "r"( &v_ ): // inputs + "memory", "cc" ); + + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __asm__ __volatile__( "" ::: "memory" ); + *const_cast< int volatile* >( &v_ ) = 0; + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_GCC_ARM_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_nt.hpp b/src/ext/boost/smart_ptr/detail/spinlock_nt.hpp new file mode 100644 index 00000000000..1f399d0dd41 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_nt.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + bool locked_; + +public: + + inline bool try_lock() + { + if( locked_ ) + { + return false; + } + else + { + locked_ = true; + return true; + } + } + + inline void lock() + { + BOOST_ASSERT( !locked_ ); + locked_ = true; + } + + inline void unlock() + { + BOOST_ASSERT( locked_ ); + locked_ = false; + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { false } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_NT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_pool.hpp b/src/ext/boost/smart_ptr/detail/spinlock_pool.hpp new file mode 100644 index 00000000000..0e2e08ac80a --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_pool.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/spinlock_pool.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// spinlock_pool<0> is reserved for atomic<>, when/if it arrives +// spinlock_pool<1> is reserved for shared_ptr reference counts +// spinlock_pool<2> is reserved for shared_ptr atomic access +// + +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +template< int I > class spinlock_pool +{ +private: + + static spinlock pool_[ 41 ]; + +public: + + static spinlock & spinlock_for( void const * pv ) + { + std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41; + return pool_[ i ]; + } + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) ) + { + sp_.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +template< int I > spinlock spinlock_pool< I >::pool_[ 41 ] = +{ + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, + BOOST_DETAIL_SPINLOCK_INIT +}; + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_pt.hpp b/src/ext/boost/smart_ptr/detail/spinlock_pt.hpp new file mode 100644 index 00000000000..f9cabfc3a7c --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_pt.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + pthread_mutex_t v_; + +public: + + bool try_lock() + { + return pthread_mutex_trylock( &v_ ) == 0; + } + + void lock() + { + pthread_mutex_lock( &v_ ); + } + + void unlock() + { + pthread_mutex_unlock( &v_ ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { PTHREAD_MUTEX_INITIALIZER } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_PT_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_sync.hpp b/src/ext/boost/smart_ptr/detail/spinlock_sync.hpp new file mode 100644 index 00000000000..a7145c5ac27 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_sync.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( __ia64__ ) && defined( __INTEL_COMPILER ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + int v_; + +public: + + bool try_lock() + { + int r = __sync_lock_test_and_set( &v_, 1 ); + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + __sync_lock_release( &v_ ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/spinlock_w32.hpp b/src/ext/boost/smart_ptr/detail/spinlock_w32.hpp new file mode 100644 index 00000000000..fb97629c7cd --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/spinlock_w32.hpp @@ -0,0 +1,113 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +// BOOST_COMPILER_FENCE + +#if defined(__INTEL_COMPILER) + +#define BOOST_COMPILER_FENCE __memory_barrier(); + +#elif defined( _MSC_VER ) && _MSC_VER >= 1310 + +extern "C" void _ReadWriteBarrier(); +#pragma intrinsic( _ReadWriteBarrier ) + +#define BOOST_COMPILER_FENCE _ReadWriteBarrier(); + +#elif defined(__GNUC__) + +#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" ); + +#else + +#define BOOST_COMPILER_FENCE + +#endif + +// + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + long v_; + +public: + + bool try_lock() + { + long r = BOOST_INTERLOCKED_EXCHANGE( &v_, 1 ); + + BOOST_COMPILER_FENCE + + return r == 0; + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + BOOST_COMPILER_FENCE + *const_cast< long volatile* >( &v_ ) = 0; + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT {0} + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_W32_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/detail/yield_k.hpp b/src/ext/boost/smart_ptr/detail/yield_k.hpp new file mode 100644 index 00000000000..a956cc0c974 --- /dev/null +++ b/src/ext/boost/smart_ptr/detail/yield_k.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// yield_k.hpp +// +// Copyright (c) 2008 Peter Dimov +// +// void yield( unsigned k ); +// +// Typical use: +// +// for( unsigned k = 0; !try_lock(); ++k ) yield( k ); +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +// BOOST_SMT_PAUSE + +#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) ) + +extern "C" void _mm_pause(); +#pragma intrinsic( _mm_pause ) + +#define BOOST_SMT_PAUSE _mm_pause(); + +#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) ) + +#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" ); + +#endif + +// + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +#if defined( BOOST_USE_WINDOWS_H ) +# include +#endif + +namespace boost +{ + +namespace detail +{ + +#if !defined( BOOST_USE_WINDOWS_H ) + extern "C" void __stdcall Sleep( unsigned ms ); +#endif + +inline void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined( BOOST_SMT_PAUSE ) + else if( k < 16 ) + { + BOOST_SMT_PAUSE + } +#endif + else if( k < 32 ) + { + Sleep( 0 ); + } + else + { + Sleep( 1 ); + } +} + +} // namespace detail + +} // namespace boost + +#elif defined( BOOST_HAS_PTHREADS ) + +#include +#include + +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned k ) +{ + if( k < 4 ) + { + } +#if defined( BOOST_SMT_PAUSE ) + else if( k < 16 ) + { + BOOST_SMT_PAUSE + } +#endif + else if( k < 32 || k & 1 ) + { + sched_yield(); + } + else + { + // g++ -Wextra warns on {} or {0} + struct timespec rqtp = { 0, 0 }; + + // POSIX says that timespec has tv_sec and tv_nsec + // But it doesn't guarantee order or placement + + rqtp.tv_sec = 0; + rqtp.tv_nsec = 1000; + + nanosleep( &rqtp, 0 ); + } +} + +} // namespace detail + +} // namespace boost + +#else + +namespace boost +{ + +namespace detail +{ + +inline void yield( unsigned ) +{ +} + +} // namespace detail + +} // namespace boost + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/enable_shared_from_this.hpp b/src/ext/boost/smart_ptr/enable_shared_from_this.hpp new file mode 100644 index 00000000000..f7b144525b1 --- /dev/null +++ b/src/ext/boost/smart_ptr/enable_shared_from_this.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED +#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED + +// +// enable_shared_from_this.hpp +// +// Copyright 2002, 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html +// + +#include +#include +#include +#include + +namespace boost +{ + +template class enable_shared_from_this +{ +protected: + + enable_shared_from_this() + { + } + + enable_shared_from_this(enable_shared_from_this const &) + { + } + + enable_shared_from_this & operator=(enable_shared_from_this const &) + { + return *this; + } + + ~enable_shared_from_this() + { + } + +public: + + shared_ptr shared_from_this() + { + shared_ptr p( weak_this_ ); + BOOST_ASSERT( p.get() == this ); + return p; + } + + shared_ptr shared_from_this() const + { + shared_ptr p( weak_this_ ); + BOOST_ASSERT( p.get() == this ); + return p; + } + +public: // actually private, but avoids compiler template friendship issues + + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr const * ppx, Y * py ) const + { + if( weak_this_.expired() ) + { + weak_this_ = shared_ptr( *ppx, py ); + } + } + +private: + + mutable weak_ptr weak_this_; +}; + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/enable_shared_from_this2.hpp b/src/ext/boost/smart_ptr/enable_shared_from_this2.hpp new file mode 100644 index 00000000000..a5bfcff836f --- /dev/null +++ b/src/ext/boost/smart_ptr/enable_shared_from_this2.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED + +// +// enable_shared_from_this2.hpp +// +// Copyright 2002, 2009 Peter Dimov +// Copyright 2008 Frank Mori Hess +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +class esft2_deleter_wrapper +{ +private: + + shared_ptr deleter_; + +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +template< class T > class enable_shared_from_this2 +{ +protected: + + enable_shared_from_this2() + { + } + + enable_shared_from_this2( enable_shared_from_this2 const & ) + { + } + + enable_shared_from_this2 & operator=( enable_shared_from_this2 const & ) + { + return *this; + } + + ~enable_shared_from_this2() + { + BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + } + +private: + + mutable weak_ptr weak_this_; + mutable shared_ptr shared_this_; + +public: + + shared_ptr shared_from_this() + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + + shared_ptr shared_from_this() const + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + +private: + + void init_weak_once() const + { + if( weak_this_._empty() ) + { + shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() ); + weak_this_ = shared_this_; + } + } + +public: // actually private, but avoids compiler template friendship issues + + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const + { + BOOST_ASSERT( ppx != 0 ); + + if( weak_this_.use_count() == 0 ) + { + weak_this_ = shared_ptr( *ppx, py ); + } + else if( shared_this_.use_count() != 0 ) + { + BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that + + detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); + BOOST_ASSERT( pd != 0 ); + + pd->set_deleter( *ppx ); + + ppx->reset( shared_this_, ppx->get() ); + shared_this_.reset(); + } + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/intrusive_ptr.hpp b/src/ext/boost/smart_ptr/intrusive_ptr.hpp new file mode 100644 index 00000000000..e72eb218698 --- /dev/null +++ b/src/ext/boost/smart_ptr/intrusive_ptr.hpp @@ -0,0 +1,299 @@ +#ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED + +// +// intrusive_ptr.hpp +// +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation. +// + +#include + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +#include +#include +#include + +#include // for std::less + +#if !defined(BOOST_NO_IOSTREAM) +#if !defined(BOOST_NO_IOSFWD) +#include // for std::basic_ostream +#else +#include +#endif +#endif + + +namespace boost +{ + +// +// intrusive_ptr +// +// A smart pointer that uses intrusive reference counting. +// +// Relies on unqualified calls to +// +// void intrusive_ptr_add_ref(T * p); +// void intrusive_ptr_release(T * p); +// +// (p != 0) +// +// The object is responsible for destroying itself. +// + +template class intrusive_ptr +{ +private: + + typedef intrusive_ptr this_type; + +public: + + typedef T element_type; + + intrusive_ptr(): px( 0 ) + { + } + + intrusive_ptr( T * p, bool add_ref = true ): px( p ) + { + if( px != 0 && add_ref ) intrusive_ptr_add_ref( px ); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + intrusive_ptr( intrusive_ptr const & rhs, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + intrusive_ptr( intrusive_ptr const & rhs ) + +#endif + : px( rhs.get() ) + { + if( px != 0 ) intrusive_ptr_add_ref( px ); + } + +#endif + + intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) + { + if( px != 0 ) intrusive_ptr_add_ref( px ); + } + + ~intrusive_ptr() + { + if( px != 0 ) intrusive_ptr_release( px ); + } + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) + + template intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + +#endif + +// Move support + +#if defined( BOOST_HAS_RVALUE_REFS ) + + intrusive_ptr(intrusive_ptr && rhs): px( rhs.px ) + { + rhs.px = 0; + } + + intrusive_ptr & operator=(intrusive_ptr && rhs) + { + this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); + return *this; + } + +#endif + + intrusive_ptr & operator=(intrusive_ptr const & rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + intrusive_ptr & operator=(T * rhs) + { + this_type(rhs).swap(*this); + return *this; + } + + void reset() + { + this_type().swap( *this ); + } + + void reset( T * rhs ) + { + this_type( rhs ).swap( *this ); + } + + T * get() const + { + return px; + } + + T & operator*() const + { + BOOST_ASSERT( px != 0 ); + return *px; + } + + T * operator->() const + { + BOOST_ASSERT( px != 0 ); + return px; + } + +// implicit conversion to "bool" +#include + + void swap(intrusive_ptr & rhs) + { + T * tmp = px; + px = rhs.px; + rhs.px = tmp; + } + +private: + + T * px; +}; + +template inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator==(intrusive_ptr const & a, U * b) +{ + return a.get() == b; +} + +template inline bool operator!=(intrusive_ptr const & a, U * b) +{ + return a.get() != b; +} + +template inline bool operator==(T * a, intrusive_ptr const & b) +{ + return a == b.get(); +} + +template inline bool operator!=(T * a, intrusive_ptr const & b) +{ + return a != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return a.get() != b.get(); +} + +#endif + +template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) +{ + lhs.swap(rhs); +} + +// mem_fn support + +template T * get_pointer(intrusive_ptr const & p) +{ + return p.get(); +} + +template intrusive_ptr static_pointer_cast(intrusive_ptr const & p) +{ + return static_cast(p.get()); +} + +template intrusive_ptr const_pointer_cast(intrusive_ptr const & p) +{ + return const_cast(p.get()); +} + +template intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) +{ + return dynamic_cast(p.get()); +} + +// operator<< + +#if !defined(BOOST_NO_IOSTREAM) + +#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) + +template std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + +// in STLport's no-iostreams mode no iostream symbols can be used +#ifndef _STLP_NO_IOSTREAMS + +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) +# else +template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) +# endif +{ + os << p.get(); + return os; +} + +#endif // _STLP_NO_IOSTREAMS + +#endif // __GNUC__ < 3 + +#endif // !defined(BOOST_NO_IOSTREAM) + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/make_shared.hpp b/src/ext/boost/smart_ptr/make_shared.hpp new file mode 100644 index 00000000000..d47718808c4 --- /dev/null +++ b/src/ext/boost/smart_ptr/make_shared.hpp @@ -0,0 +1,506 @@ +#ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED +#define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED + +// make_shared.hpp +// +// Copyright (c) 2007, 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/smart_ptr/make_shared.html +// for documentation. + +#include +#include +#include +#include +#include +#include + +namespace boost +{ + +namespace detail +{ + +template< std::size_t N, std::size_t A > struct sp_aligned_storage +{ + union type + { + char data_[ N ]; + typename boost::type_with_alignment< A >::type align_; + }; +}; + +template< class T > class sp_ms_deleter +{ +private: + + typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type; + + bool initialized_; + storage_type storage_; + +private: + + void destroy() + { + if( initialized_ ) + { + reinterpret_cast< T* >( storage_.data_ )->~T(); + initialized_ = false; + } + } + +public: + + sp_ms_deleter(): initialized_( false ) + { + } + + // optimization: do not copy storage_ + sp_ms_deleter( sp_ms_deleter const & ): initialized_( false ) + { + } + + ~sp_ms_deleter() + { + destroy(); + } + + void operator()( T * ) + { + destroy(); + } + + void * address() + { + return storage_.data_; + } + + void set_initialized() + { + initialized_ = true; + } +}; + +#if defined( BOOST_HAS_RVALUE_REFS ) +template< class T > T&& forward( T &&t ) +{ + return t; +} +#endif + +} // namespace detail + +// Zero-argument versions +// +// Used even when variadic templates are available because of the new T() vs new T issue + +template< class T > boost::shared_ptr< T > make_shared() +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T(); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T(); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS ) + +// Variadic templates, rvalue reference + +template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( detail::forward( args )... ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( detail::forward( args )... ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +#else + +// C++03 version + +template< class T, class A1 > +boost::shared_ptr< T > make_shared( A1 const & a1 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > +boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 ) +{ + boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a ); + + detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt ); + + void * pv = pd->address(); + + ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + pd->set_initialized(); + + T * pt2 = static_cast< T* >( pv ); + + boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 ); + return boost::shared_ptr< T >( pt, pt2 ); +} + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/scoped_array.hpp b/src/ext/boost/smart_ptr/scoped_array.hpp new file mode 100644 index 00000000000..483460fa06b --- /dev/null +++ b/src/ext/boost/smart_ptr/scoped_array.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED +#define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED + +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/smart_ptr/scoped_array.htm +// + +#include +#include +#include // in case ptrdiff_t not in std + +#include + +#include // for std::ptrdiff_t + +namespace boost +{ + +// Debug hooks + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_array_constructor_hook(void * p); +void sp_array_destructor_hook(void * p); + +#endif + +// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to +// is guaranteed, either on destruction of the scoped_array or via an explicit +// reset(). Use shared_array or std::vector if your needs are more complex. + +template class scoped_array // noncopyable +{ +private: + + T * px; + + scoped_array(scoped_array const &); + scoped_array & operator=(scoped_array const &); + + typedef scoped_array this_type; + + void operator==( scoped_array const& ) const; + void operator!=( scoped_array const& ) const; + +public: + + typedef T element_type; + + explicit scoped_array( T * p = 0 ) : px( p ) // never throws + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_array_constructor_hook( px ); +#endif + } + + ~scoped_array() // never throws + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_array_destructor_hook( px ); +#endif + boost::checked_array_delete( px ); + } + + void reset(T * p = 0) // never throws + { + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors + this_type(p).swap(*this); + } + + T & operator[](std::ptrdiff_t i) const // never throws + { + BOOST_ASSERT( px != 0 ); + BOOST_ASSERT( i >= 0 ); + return px[i]; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + void swap(scoped_array & b) // never throws + { + T * tmp = b.px; + b.px = px; + px = tmp; + } +}; + +template inline void swap(scoped_array & a, scoped_array & b) // never throws +{ + a.swap(b); +} + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/scoped_ptr.hpp b/src/ext/boost/smart_ptr/scoped_ptr.hpp new file mode 100644 index 00000000000..df479e57279 --- /dev/null +++ b/src/ext/boost/smart_ptr/scoped_ptr.hpp @@ -0,0 +1,131 @@ +#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED + +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm +// + +#include +#include +#include + +#ifndef BOOST_NO_AUTO_PTR +# include // for std::auto_ptr +#endif + +namespace boost +{ + +// Debug hooks + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook(void * p); +void sp_scalar_destructor_hook(void * p); + +#endif + +// scoped_ptr mimics a built-in pointer except that it guarantees deletion +// of the object pointed to, either on destruction of the scoped_ptr or via +// an explicit reset(). scoped_ptr is a simple solution for simple needs; +// use shared_ptr or std::auto_ptr if your needs are more complex. + +template class scoped_ptr // noncopyable +{ +private: + + T * px; + + scoped_ptr(scoped_ptr const &); + scoped_ptr & operator=(scoped_ptr const &); + + typedef scoped_ptr this_type; + + void operator==( scoped_ptr const& ) const; + void operator!=( scoped_ptr const& ) const; + +public: + + typedef T element_type; + + explicit scoped_ptr( T * p = 0 ): px( p ) // never throws + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px ); +#endif + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit scoped_ptr( std::auto_ptr p ): px( p.release() ) // never throws + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_constructor_hook( px ); +#endif + } + +#endif + + ~scoped_ptr() // never throws + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + boost::sp_scalar_destructor_hook( px ); +#endif + boost::checked_delete( px ); + } + + void reset(T * p = 0) // never throws + { + BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors + this_type(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT( px != 0 ); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT( px != 0 ); + return px; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + void swap(scoped_ptr & b) // never throws + { + T * tmp = b.px; + b.px = px; + px = tmp; + } +}; + +template inline void swap(scoped_ptr & a, scoped_ptr & b) // never throws +{ + a.swap(b); +} + +// get_pointer(p) is a generic way to say p.get() + +template inline T * get_pointer(scoped_ptr const & p) +{ + return p.get(); +} + +} // namespace boost + +#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/shared_array.hpp b/src/ext/boost/smart_ptr/shared_array.hpp new file mode 100644 index 00000000000..1f50403a382 --- /dev/null +++ b/src/ext/boost/smart_ptr/shared_array.hpp @@ -0,0 +1,147 @@ +#ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED +#define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED + +// +// shared_array.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation. +// + +#include // for broken compiler workarounds + +#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +#include +#else + +#include // TR1 cyclic inclusion fix + +#include +#include + +#include +#include + +#include // for std::ptrdiff_t +#include // for std::swap +#include // for std::less + +namespace boost +{ + +// +// shared_array +// +// shared_array extends shared_ptr to arrays. +// The array pointed to is deleted when the last shared_array pointing to it +// is destroyed or reset. +// + +template class shared_array +{ +private: + + // Borland 5.5.1 specific workarounds + typedef checked_array_deleter deleter; + typedef shared_array this_type; + +public: + + typedef T element_type; + + explicit shared_array(T * p = 0): px(p), pn(p, deleter()) + { + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_array will release p by calling d(p) + // + + template shared_array(T * p, D d): px(p), pn(p, d) + { + } + +// generated copy constructor, assignment, destructor are fine + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + this_type(p).swap(*this); + } + + template void reset(T * p, D d) + { + this_type(p, d).swap(*this); + } + + T & operator[] (std::ptrdiff_t i) const // never throws + { + BOOST_ASSERT(px != 0); + BOOST_ASSERT(i >= 0); + return px[i]; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_array & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + +private: + + T * px; // contained pointer + detail::shared_count pn; // reference counter + +}; // shared_array + +template inline bool operator==(shared_array const & a, shared_array const & b) // never throws +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_array const & a, shared_array const & b) // never throws +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_array const & a, shared_array const & b) // never throws +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_array & a, shared_array & b) // never throws +{ + a.swap(b); +} + +} // namespace boost + +#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) + +#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/shared_ptr.hpp b/src/ext/boost/smart_ptr/shared_ptr.hpp new file mode 100644 index 00000000000..609cce90322 --- /dev/null +++ b/src/ext/boost/smart_ptr/shared_ptr.hpp @@ -0,0 +1,701 @@ +#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001-2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include // for broken compiler workarounds + +#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +#include +#else + +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr + +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_SP_NO_ATOMIC_ACCESS) +#include +#include +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_cast + +#if !defined(BOOST_NO_IOSTREAM) +#if !defined(BOOST_NO_IOSFWD) +#include // for std::basic_ostream +#else +#include +#endif +#endif + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +namespace boost +{ + +template class shared_ptr; +template class weak_ptr; +template class enable_shared_from_this; +template class enable_shared_from_this2; + +namespace detail +{ + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template struct shared_ptr_traits +{ + typedef T & reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#endif + +// enable_shared_from_this support + +template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + +template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe ) +{ + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } +} + +#ifdef _MANAGED + +// Avoid C4793, ... causes native code generation + +struct sp_any_pointer +{ + template sp_any_pointer( T* ) {} +}; + +inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer ) +{ +} + +#else // _MANAGED + +inline void sp_enable_shared_from_this( ... ) +{ +} + +#endif // _MANAGED + +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR ) + +// rvalue auto_ptr support based on a technique by Dave Abrahams + +template< class T, class R > struct sp_enable_if_auto_ptr +{ +}; + +template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R > +{ + typedef R type; +}; + +#endif + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template class shared_ptr +{ +private: + + // Borland 5.5.1 specific workaround + typedef shared_ptr this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename boost::detail::shared_ptr_traits::reference reference; + + shared_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + template + explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete + { + boost::detail::sp_enable_shared_from_this( this, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template shared_ptr(Y * p, D d): px(p), pn(p, d) + { + boost::detail::sp_enable_shared_from_this( this, p, p ); + } + + // As above, but with allocator. A's copy constructor shall not throw. + + template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) + { + boost::detail::sp_enable_shared_from_this( this, p, p ); + } + +// generated copy constructor, destructor are fine + + template + explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw + { + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template + shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws + { + if( !pn.empty() ) + { + px = r.px; + } + } + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr const & r ) + +#endif + : px( r.px ), pn( r.pn ) // never throws + { + } + + // aliasing + template< class Y > + shared_ptr( shared_ptr const & r, T * p ): px( p ), pn( r.pn ) // never throws + { + } + + template + shared_ptr(shared_ptr const & r, boost::detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, boost::detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = boost::detail::shared_count(); + } + } + + template + shared_ptr(shared_ptr const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) + { + boost::throw_exception(std::bad_cast()); + } + } + +#ifndef BOOST_NO_AUTO_PTR + + template + explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = boost::detail::shared_count(r); + boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); + } + +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + + template + explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr::type = 0 ): px( r.get() ), pn() + { + typename Ap::element_type * tmp = r.get(); + pn = boost::detail::shared_count( r ); + boost::detail::sp_enable_shared_from_this( this, tmp, tmp ); + } + + +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // BOOST_NO_AUTO_PTR + + // assignment + + shared_ptr & operator=( shared_ptr const & r ) // never throws + { + this_type(r).swap(*this); + return *this; + } + +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400) + + template + shared_ptr & operator=(shared_ptr const & r) // never throws + { + this_type(r).swap(*this); + return *this; + } + +#endif + +#ifndef BOOST_NO_AUTO_PTR + + template + shared_ptr & operator=( std::auto_ptr & r ) + { + this_type(r).swap(*this); + return *this; + } + +#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + + template + typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r ) + { + this_type( r ).swap( *this ); + return *this; + } + + +#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + +#endif // BOOST_NO_AUTO_PTR + +// Move support + +#if defined( BOOST_HAS_RVALUE_REFS ) + + shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws + { + pn.swap( r.pn ); + r.px = 0; + } + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + shared_ptr( shared_ptr && r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + shared_ptr( shared_ptr && r ) + +#endif + : px( r.px ), pn() // never throws + { + pn.swap( r.pn ); + r.px = 0; + } + + shared_ptr & operator=( shared_ptr && r ) // never throws + { + this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + return *this; + } + + template + shared_ptr & operator=( shared_ptr && r ) // never throws + { + this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); + return *this; + } + +#endif + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset(Y * p) // Y must be complete + { + BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template void reset( Y * p, D d ) + { + this_type( p, d ).swap( *this ); + } + + template void reset( Y * p, D d, A a ) + { + this_type( p, d, a ).swap( *this ); + } + + template void reset( shared_ptr const & r, T * p ) + { + this_type( r, p ).swap( *this ); + } + + reference operator* () const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + +// implicit conversion to "bool" +#include + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_ptr & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool _internal_less(shared_ptr const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const + { + return pn.get_deleter( ti ); + } + + bool _internal_equiv( shared_ptr const & r ) const + { + return px == r.px && pn == r.pn; + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + +private: + + template friend class shared_ptr; + template friend class weak_ptr; + + +#endif + + T * px; // contained pointer + boost::detail::shared_count pn; // reference counter + +}; // shared_ptr + +template inline bool operator==(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template inline bool operator!=(shared_ptr const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +#endif + +template inline bool operator<(shared_ptr const & a, shared_ptr const & b) +{ + return a._internal_less(b); +} + +template inline void swap(shared_ptr & a, shared_ptr & b) +{ + a.swap(b); +} + +template shared_ptr static_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::static_cast_tag()); +} + +template shared_ptr const_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::const_cast_tag()); +} + +template shared_ptr dynamic_pointer_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template shared_ptr shared_static_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::static_cast_tag()); +} + +template shared_ptr shared_dynamic_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::dynamic_cast_tag()); +} + +template shared_ptr shared_polymorphic_cast(shared_ptr const & r) +{ + return shared_ptr(r, boost::detail::polymorphic_cast_tag()); +} + +template shared_ptr shared_polymorphic_downcast(shared_ptr const & r) +{ + BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); + return shared_static_cast(r); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr const & p) +{ + return p.get(); +} + +// operator<< + +#if !defined(BOOST_NO_IOSTREAM) + +#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) + +template std::ostream & operator<< (std::ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +#else + +// in STLport's no-iostreams mode no iostream symbols can be used +#ifndef _STLP_NO_IOSTREAMS + +# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) +// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL +using std::basic_ostream; +template basic_ostream & operator<< (basic_ostream & os, shared_ptr const & p) +# else +template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +# endif +{ + os << p.get(); + return os; +} + +#endif // _STLP_NO_IOSTREAMS + +#endif // __GNUC__ < 3 + +#endif // !defined(BOOST_NO_IOSTREAM) + +// get_deleter + +#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ + ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ + ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) + +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it + +template D * get_deleter(shared_ptr const & p) +{ + void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); + return const_cast(static_cast(q)); +} + +#else + +template D * get_deleter(shared_ptr const & p) +{ + return static_cast(p._internal_get_deleter(BOOST_SP_TYPEID(D))); +} + +#endif + +// atomic access + +#if !defined(BOOST_SP_NO_ATOMIC_ACCESS) + +template inline bool atomic_is_lock_free( shared_ptr const * /*p*/ ) +{ + return false; +} + +template shared_ptr atomic_load( shared_ptr const * p ) +{ + boost::detail::spinlock_pool<2>::scoped_lock lock( p ); + return *p; +} + +template inline shared_ptr atomic_load_explicit( shared_ptr const * p, memory_order /*mo*/ ) +{ + return atomic_load( p ); +} + +template void atomic_store( shared_ptr * p, shared_ptr r ) +{ + boost::detail::spinlock_pool<2>::scoped_lock lock( p ); + p->swap( r ); +} + +template inline void atomic_store_explicit( shared_ptr * p, shared_ptr r, memory_order /*mo*/ ) +{ + atomic_store( p, r ); // std::move( r ) +} + +template shared_ptr atomic_exchange( shared_ptr * p, shared_ptr r ) +{ + boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + p->swap( r ); + sp.unlock(); + + return r; // return std::move( r ) +} + +template shared_ptr atomic_exchange_explicit( shared_ptr * p, shared_ptr r, memory_order /*mo*/ ) +{ + return atomic_exchange( p, r ); // std::move( r ) +} + +template bool atomic_compare_exchange( shared_ptr * p, shared_ptr * v, shared_ptr w ) +{ + boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p ); + + sp.lock(); + + if( p->_internal_equiv( *v ) ) + { + p->swap( w ); + + sp.unlock(); + + return true; + } + else + { + shared_ptr tmp( *p ); + + sp.unlock(); + + tmp.swap( *v ); + return false; + } +} + +template inline bool atomic_compare_exchange_explicit( shared_ptr * p, shared_ptr * v, shared_ptr w, memory_order /*success*/, memory_order /*failure*/ ) +{ + return atomic_compare_exchange( p, v, w ); // std::move( w ) +} + +#endif + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) + +#endif // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED diff --git a/src/ext/boost/smart_ptr/weak_ptr.hpp b/src/ext/boost/smart_ptr/weak_ptr.hpp new file mode 100644 index 00000000000..d314b0df3ea --- /dev/null +++ b/src/ext/boost/smart_ptr/weak_ptr.hpp @@ -0,0 +1,230 @@ +#ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED +#define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED + +// +// weak_ptr.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation. +// + +#include // boost.TR1 include order fix +#include +#include + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +namespace boost +{ + +template class weak_ptr +{ +private: + + // Borland 5.5.1 specific workarounds + typedef weak_ptr this_type; + +public: + + typedef T element_type; + + weak_ptr(): px(0), pn() // never throws in 1.30+ + { + } + +// generated copy constructor, assignment, destructor are fine + + +// +// The "obvious" converting constructor implementation: +// +// template +// weak_ptr(weak_ptr const & r): px(r.px), pn(r.pn) // never throws +// { +// } +// +// has a serious problem. +// +// r.px may already have been invalidated. The px(r.px) +// conversion may require access to *r.px (virtual inheritance). +// +// It is not possible to avoid spurious access violations since +// in multithreaded programs r.px may be invalidated at any point. +// + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( weak_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + weak_ptr( weak_ptr const & r ) + +#endif + : px(r.lock().get()), pn(r.pn) // never throws + { + } + +#if defined( BOOST_HAS_RVALUE_REFS ) + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( weak_ptr && r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + weak_ptr( weak_ptr && r ) + +#endif + : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws + { + r.px = 0; + } + + // for better efficiency in the T == Y case + weak_ptr( weak_ptr && r ): px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) ) // never throws + { + r.px = 0; + } + + // for better efficiency in the T == Y case + weak_ptr & operator=( weak_ptr && r ) // never throws + { + this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); + return *this; + } + + +#endif + + template +#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) + + weak_ptr( shared_ptr const & r, typename boost::detail::sp_enable_if_convertible::type = boost::detail::sp_empty() ) + +#else + + weak_ptr( shared_ptr const & r ) + +#endif + : px( r.px ), pn( r.pn ) // never throws + { + } + +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300) + + template + weak_ptr & operator=(weak_ptr const & r) // never throws + { + px = r.lock().get(); + pn = r.pn; + return *this; + } + +#if defined( BOOST_HAS_RVALUE_REFS ) + + template + weak_ptr & operator=( weak_ptr && r ) + { + this_type( static_cast< weak_ptr && >( r ) ).swap( *this ); + return *this; + } + +#endif + + template + weak_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; + return *this; + } + +#endif + + shared_ptr lock() const // never throws + { + return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + bool expired() const // never throws + { + return pn.use_count() == 0; + } + + bool _empty() const // extension, not in std::weak_ptr + { + return pn.empty(); + } + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + void swap(this_type & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + void _internal_assign(T * px2, boost::detail::shared_count const & pn2) + { + px = px2; + pn = pn2; + } + + template bool _internal_less(weak_ptr const & rhs) const + { + return pn < rhs.pn; + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + +private: + + template friend class weak_ptr; + template friend class shared_ptr; + +#endif + + T * px; // contained pointer + boost::detail::weak_count pn; // reference counter + +}; // weak_ptr + +template inline bool operator<(weak_ptr const & a, weak_ptr const & b) +{ + return a._internal_less(b); +} + +template void swap(weak_ptr & a, weak_ptr & b) +{ + a.swap(b); +} + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED diff --git a/src/ext/boost/throw_exception.hpp b/src/ext/boost/throw_exception.hpp new file mode 100644 index 00000000000..656b8de31e2 --- /dev/null +++ b/src/ext/boost/throw_exception.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED +#define BOOST_THROW_EXCEPTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/throw_exception.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// http://www.boost.org/libs/utility/throw_exception.html +// + +#include +#include +#include +#include + +#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x593) ) +# define BOOST_EXCEPTION_DISABLE +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1310 ) +# define BOOST_EXCEPTION_DISABLE +#endif + +#if !defined( BOOST_EXCEPTION_DISABLE ) +# include +# include +# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(::boost::enable_error_info(x) <<\ + ::boost::throw_function(BOOST_CURRENT_FUNCTION) <<\ + ::boost::throw_file(__FILE__) <<\ + ::boost::throw_line(__LINE__)) +#else +# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x) +#endif + +namespace boost +{ + +#ifdef BOOST_NO_EXCEPTIONS + +void throw_exception( std::exception const & e ); // user defined + +#else + +inline void throw_exception_assert_compatibility( std::exception const & ) { } + +template BOOST_ATTRIBUTE_NORETURN inline void throw_exception( E const & e ) +{ + //All boost exceptions are required to derive from std::exception, + //to ensure compatibility with BOOST_NO_EXCEPTIONS. + throw_exception_assert_compatibility(e); + +#ifndef BOOST_EXCEPTION_DISABLE + throw enable_current_exception(enable_error_info(e)); +#else + throw e; +#endif +} + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED diff --git a/src/ext/boost/version.hpp b/src/ext/boost/version.hpp new file mode 100644 index 00000000000..e95ff85e710 --- /dev/null +++ b/src/ext/boost/version.hpp @@ -0,0 +1,35 @@ +// Boost version.hpp configuration header file ------------------------------// + +// (C) Copyright John maddock 1999. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for documentation + +#ifndef BOOST_VERSION_HPP +#define BOOST_VERSION_HPP + +// +// Caution, this is the only boost header that is guarenteed +// to change with every boost release, including this header +// will cause a recompile every time a new boost version is +// released. +// +// BOOST_VERSION % 100 is the patch level +// BOOST_VERSION / 100 % 1000 is the minor version +// BOOST_VERSION / 100000 is the major version + +#define BOOST_VERSION 104200 + +// +// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION +// but as a *string* in the form "x_y[_z]" where x is the major version +// number, y is the minor version number, and z is the patch level if not 0. +// This is used by to select which library version to link to. + +#define BOOST_LIB_VERSION "1_42" + +#endif + + + diff --git a/src/ext/for/README.md b/src/ext/for/README.md new file mode 100644 index 00000000000..31e8f25ebb4 --- /dev/null +++ b/src/ext/for/README.md @@ -0,0 +1,585 @@ +TurboPFor: Fastest Integer Compression + +[//]: # ([![Build Status][travisBadge]][travisLink]) +[//]: # ([travisBadge]: https://api.travis-ci.com/powturbo/TurboPFor-Integer-Compression.svg?branch=master) +[//]: # ([travisLink]: https://app.travis-ci.com/powturbo/TurboPFor-Integer-Compression) +====================================== +* **TurboPFor: The synonym for "integer compression"** + * **ALL** functions available for **AMD/Intel**, **64 bits ARMv8 NEON** Linux+MacOS/M1 & **Power9 Altivec** + * 100% C (C++ headers), as simple as memcpy. OS:Linux amd64, arm64, Power9, MacOs (Amd/intel + Apple M1), + * :+1: **Java** Critical Natives/JNI. Access TurboPFor **incl. SIMD/AVX2!** from Java as fast as calling from C + * :sparkles: **FULL** range 8/16/32/64 bits scalar + 16/32/64 bits SIMD functions + * No other "Integer Compression" compress/decompress faster + * :sparkles: Direct Access, **integrated** (SIMD/AVX2) FOR/delta/Delta of Delta/Zigzag for sorted/unsorted arrays + * **16 bits** + **64 bits** SIMD integrated functions +* **For/PFor/PForDelta** + * **Novel TurboPFor** (PFor/PForDelta) scheme w./ **direct access** + **SIMD/AVX2**. **+RLE** + * Outstanding compression/speed. More efficient than **ANY** other fast "integer compression" scheme. + * Compress 70 times faster and decompress up to 4 times faster than OptPFD +* **Bit Packing** + * Fastest and most efficient **"SIMD Bit Packing"** **15 Billions integers/sec (60Gb/s!)** + * Scalar **"Bit Packing"** decoding nearly as fast as SIMD-Packing in realistic (No "pure cache") scenarios + * **Direct/Random Access** : Access any single bit packed entry with **zero decompression** +* **Variable byte** + * Scalar **"Variable Byte"** faster and more efficient than **ANY** other implementation + * SIMD **TurboByte** fastest group varint (16+32 bits) incl. integrated delta,zigzag,... + * **TurboByte+TurboPackV** novel hybrid scheme combining the fastest SIMD codecs. +* **Simple family** + * **Novel** **"Variable Simple"** (incl. **RLE**) faster and more efficient than simple16, simple-8b +* **Elias fano** + * Fastest **"Elias Fano"** implementation w/ or w/o SIMD/AVX2 ++ **Transform** + * Scalar & SIMD Transform: Delta, Zigzag, Zigzag of delta, XOR, Transpose/Shuffle, + * **lossy** floating point compression with *TurboPFor* or [TurboTranspose](https://github.com/powturbo/TurboTranspose)+lz77 +* **Floating Point Compression** + * Delta/Zigzag + improved gorilla style + (Differential) Finite Context Method FCM/DFCM floating point compression + * Using **TurboPFor**, unsurpassed compression and more than 5 GB/s throughput + * Point wise relative error bound **lossy** floating point compression + * **TurboFloat** novel efficient floating point compression using TurboPFor +* **Time Series Compression** + * **Fastest Gorilla** 16/32/64 bits style compression (**zigzag of delta** + **RLE**). + * can compress times series to only 0.01%. Speed > 10 GB/s compression and > 13 GB/s decompress. +* **Inverted Index ...do less, go fast!** + * Direct Access to compressed *frequency* and *position* data w/ zero decompression + * **Novel** **"Intersection w/ skip intervals"**, decompress the minimum necessary blocks (**~10-15%)!**. + * **Novel** Implicit skips with zero extra overhead + * **Novel** Efficient **Bidirectional** Inverted Index Architecture (forward/backwards traversal) incl. "integer compression". + * more than **2000! queries per second** on GOV2 dataset (25 millions documents) on a **SINGLE** core + * :sparkles: Revolutionary Parallel Query Processing on Multicores **> 7000!!! queries/sec** on a simple quad core PC.
+ **...forget** ~~Map Reduce, Hadoop, multi-node clusters,~~ ... + +![Promo video](turbopfor.jpg?raw=true) + +### Integer Compression Benchmark (single thread): +- Download [IcApp](https://sites.google.com/site/powturbo/downloads) a new benchmark for TurboPFor
+ for testing allmost all integer and floating point file types. +- Practical (No **PURE** cache) "integer compression" benchmark w/ **large** arrays. +- [Benchmark Intel CPU: Skylake i7-6700 3.4GHz gcc 9.2](https://github.com/powturbo/TurboPFor/issues/47) +- [Benchmark ARM: ARMv8 A73-ODROID-N2 1.8GHz](https://github.com/powturbo/TurboPFor/issues/49) + +##### - Synthetic data: + - Generate and test (zipfian) skewed distribution (100.000.000 integers, Block size=128/256)
+ Note: Unlike general purpose compression, a small fixed size (ex. 128 integers) is in general used in "integer compression". + Large blocks involved, while processing queries (inverted index, search engines, databases, graphs, in memory computing,...) need to be entirely decoded. + + ./icbench -a1.5 -m0 -M255 -n100M ZIPF + +|C Size|ratio%|Bits/Integer|C MB/s|D MB/s|Name 2019.11| +|--------:|-----:|--------:|----------:|----------:|--------------| +|62,939,886| 15.7| 5.04|**2369**|**10950**|**TurboPFor256**| +|63,392,759| 15.8| 5.07|1359|7803|**TurboPFor128**| +|63,392,801| 15.8| 5.07|1328|924|**TurboPForDA**| +|65,060,504| 16.3| 5.20|60|2748|[FP_SIMDOptPFor](#FastPFor)| +|65,359,916|16.3| 5.23| 32|2436|PC_OptPFD| +|73,477,088|18.4| 5.88|408|2484|PC_Simple16| +|73,481,096| 18.4| 5.88|624|8748|[FP_SimdFastPFor](#FastPFor) 64Ki *| +|76,345,136| 19.1| 6.11|1072|2878|**VSimple**| +|91,947,533| 23.0| 7.36|284|11737|[QMX](#QMX) 64k *| +|93,285,864| 23.3| 7.46|1568|10232|[FP_GroupSimple](#FastPFor) 64Ki *| +|95,915,096|24.0| 7.67| 848|3832|Simple-8b| +|99,910,930| 25.0| 7.99|**17298**|**12408**|**TurboByte+TurboPack**| +|99,910,930| 25.0| 7.99|**17357**|**12363**|**TurboPackV** sse| +|99,910,930| 25.0| 7.99|11694|10138|**TurboPack** scalar| +|99,910,930| 25.0| 7.99|8420|8876|**TurboFor**| +|100,332,929| 25.1| 8.03|17077|11170|**TurboPack256V** avx2| +|101,015,650| 25.3| 8.08|11191|10333|**TurboVByte**| +|102,074,663| 25.5| 8.17|6689|9524|[MaskedVByte](#MaskedVByte)| +|102,074,663| 25.5| 8.17|2260|4208|[PC_Vbyte](#PolyCom)| +|102,083,036| 25.5| 8.17|5200|4268|[FP_VByte](#FastPFor)| +|112,500,000| 28.1| 9.00|1528|12140|[VarintG8IU](#VarintG8IU)| +|125,000,000| 31.2|10.00|13039|12366|**TurboByte**| +|125,000,000| 31.2|10.00|11197|11984|[StreamVbyte 2019](#StreamVByte)| +|400,000,000| 100.00| 32.00| 8960|8948|Copy| +| | | | N/A | N/A |EliasFano| + +(*) codecs inefficient for small block sizes are tested with 64Ki integers/block. + +- MB/s: 1.000.000 bytes/second. **1000 MB/s = 1 GB/s**
+- **#BOLD** = pareto frontier.
+- FP=FastPFor SC:simdcomp PC:Polycom
+- TurboPForDA,TurboForDA: Direct Access is normally used when accessing few individual values.
+- Eliasfano can be directly used only for increasing sequences +------------------------------------------------------------------------ +##### - Data files: + - gov2.sorted from [DocId data set](#DocId) Block size=128/Delta coding + + ./icbench -fS -r gov2.sorted + +![Speed/Ratio](ext/gov2.png "Speed/Ratio: Decompression") + +|Size |Ratio %|Bits/Integer|C Time MB/s|D Time MB/s|Function 2019.11| +|-----------:|------:|-----:|-------:|-------:|---------------------| +| 3,321,663,893| 13.9| 4.44|**1320**|**6088**|**TurboPFor**| +| 3,339,730,557| 14.0| 4.47| 32| 2144|PC.OptPFD| +| 3,350,717,959| 14.0| 4.48|**1536**|**7128**|**TurboPFor256**| +| 3,501,671,314| 14.6| 4.68| 56| 2840|**VSimple**| +| 3,768,146,467| 15.8| 5.04|**3228**| 3652|**EliasFanoV**| +| 3,822,161,885| 16.0| 5.11| 572| 2444|PC_Simple16| +| 4,411,714,936| 18.4| 5.90|**9304**|**10444**|**TurboByte+TurboPack**| +| 4,521,326,518| 18.9| 6.05| 836| 3296|Simple-8b| +| 4,649,671,427| 19.4| 6.22|3084| 3848|**TurboVbyte**| +| 4,955,740,045| 20.7| 6.63|7064|10268|**TurboPackV**| +| 4,955,740,045| 20.7| 6.63|5724| 8020|**TurboPack**| +| 5,205,324,760| 21.8| 6.96|6952| 9488|SC_SIMDPack128| +| 5,393,769,503| 22.5| 7.21|**14466**|**11902**|**TurboPackV256**| +| 6,221,886,390| 26.0| 8.32|6668| 6952|**TurboFor**| +| 6,221,886,390| 26.0| 8.32|6644| 2260|**TurboForDA**| +| 6,699,519,000| 28.0| 8.96|1888| 1980|FP_Vbyte| +| 6,700,989,563| 28.0| 8.96|2740| 3384|MaskedVByte| +| 7,622,896,878| 31.9|10.20| 836| 4792|VarintG8IU| +| 8,060,125,035| 33.7|11.50|8456| 9476|Streamvbyte 2019| +| 8,594,342,216| 35.9|11.50|5228| 6376|libfor| +|23,918,861,764|100.0|32.00|5824| 5924|Copy| + +Block size: 64Ki = 256k bytes. Ki=1024 Integers + +|Size |Ratio %|Bits/Integer|C Time MB/s|D Time MB/s|Function | +|----------:|-----:|----:|------:|------:|---------------------| +| 3,164,940,562| 13.2|**4.23**|**1344**|**6004**|**TurboPFor 64Ki**| +| 3,273,213,464| 13.7| 4.38|**1496**|**7008**|**TurboPFor256 64Ki**| +| 3,965,982,954| 16.6| 5.30|**1520**| 2452|[lz4](#lz4)+DT 64Ki| +| 4,234,154,427| 17.7| 5.66| 436| 5672|qmx 64Ki| +| 6,074,995,117| 25.4| 8.13| 1976| 2916|[blosc_lz4](#blosc) 64Ki| +| 8,773,150,644| 36.7|11.74| 2548|5204|blosc_lz 64Ki| + +"lz4+DT 64Ki" = Delta+Transpose from TurboPFor + lz4
+"blosc_lz4" internal lz4 compressor+vectorized shuffle + +##### - Time Series: +- Test file [Timestamps: ts.txt(sorted)](https://github.com/zhenjl/encoding/tree/master/benchmark/data) + + ./icapp -Ft ts.txt -I15 -J15 + +|Function |C MB/s| size |ratio%| D MB/s|Text +|----------------|-----:|--------:|------:|------:|--------------------| +|bvzenc32 |**10632**|45,909|0.008|**12823**|ZigZag| +|bvzzenc32 |**8914**|56,713|0.010|**13499**|ZigZag Delta of delta| +|vsenc32 |**12294**|140,400| 0.024 |12877 |Variable Simple| +|p4nzenc256v32 | 1932| 596,018| 0.10 |13326 |TurboPFor256 ZigZag| +|p4ndenc256v32 | 1961| 596,018| 0.10 |13339 |TurboPFor256 Delta| +|bitndpack256v32 |**12564**|909,189| 0.16 |13505 |TurboPackV256 Delta| +|p4nzenc32 | 1810| 1,159,633| 0.20 | 8502 |TurboPFor ZigZag| +|p4nzenc128v32 | 1795| 1,159,633| 0.20 |13338 |TurboPFor ZigZag| +|bitnzpack256v32 | 9651| 1,254,757| 0.22 |**13503**|TurboPackV256 ZigZag| +|bitnzpack128v32 |10155| 1,472,804| 0.26 |13380 |TurboPackV ZigZag| +|vbddenc32 | 6198| 18,057,296| 3.13 |10982 |TurboVByte Delta of delta| +|memcpy |13397|577,141,992|100.00|| + +##### - Transpose/Shuffle (no compression) + ./icbench -eTRANSFORM ZIPF + +|Size |C Time MB/s|D Time MB/s|Function| +|----------:|------:|------:|-----------------------------------| +|100,000,000|**9400**|**9132**|**TPbyte 4** TurboPFor Byte Transpose/shuffle AVX2| +|100,000,000|8784|8860|**TPbyte 4** TurboPFor Byte Transpose/shuffle SSE| +|100,000,000|7688|7656|Blosc_Shuffle AVX2| +|100,000,000|**5204**|**7460**|**TPnibble 4** TurboPFor Nibble Transpose/shuffle SSE| +|100,000,000|6620|6284|Blosc shuffle SSE| +|100,000,000|3156|3372|Bitshuffle AVX2| +|100,000,000|2100|2176|Bitshuffle SSE| + +##### - (Lossy) Floating point compression: + ./icapp -Fd file " 64 bits floating point raw file + ./icapp -Ff file " 32 bits floating point raw file + ./icapp -Fcf file " text file with miltiple entries (ex. 8.657,56.8,4.5 ...) + ./icapp -Ftf file " text file (1 entry per line) + ./icapp -Ftf file -v5 " + display the first entries read + ./icapp -Ftf file.csv -K3 " but 3th column in a csv file (ex. number,Text,456.5 -> 456.5 + ./icapp -Ftf file -g.001 " lossy compression with allowed pointwise relative error 0.001 + +- see also [TurboTranspose](https://github.com/powturbo/TurboTranspose) + +##### - Compressed Inverted Index Intersections with GOV2
+ GOV2: 426GB, 25 Millions documents, average doc. size=18k. + + + Aol query log: 18.000 queries
+ **~1300** queries per second (single core)
+ **~5000** queries per second (quad core)
+ Ratio = 14.37% Decoded/Total Integers. + + + TREC Million Query Track (1MQT):
+ **~1100** queries per second (Single core)
+ **~4500** queries per second (Quad core CPU)
+ Ratio = 11.59% Decoded/Total Integers. + +- Benchmarking intersections (Single core, AOL query log) + +| max.docid/q|Time s| q/s | ms/q | % docid found| +|-----------------:|---:|----:|-----:|-------:| +|1.000|7.88|2283.1|0.438|81| +|10.000|10.54|1708.5|0.585|84| +| ALL |13.96|1289.0|0.776|100| +q/s: queries/second, ms/q:milliseconds/query + +- Benchmarking Parallel Query Processing (Quad core, AOL query log) + +| max.docid/q|Time s| q/s | ms/q | % docids found| +|-----------------:|----:|----:|-----:|-------:| +|1.000|2.66|6772.6|0.148|81| +|10.000|3.39|5307.5|0.188|84| +|ALL|3.57|5036.5|0.199|100| + +###### Notes: +- Search engines are spending 90% of the time in intersections when processing queries. +- Most search engines are using pruning strategies, caching popular queries,... to reduce the time for intersections and query processing. +- As indication, google is processing [40.000 Queries per seconds](http://www.internetlivestats.com/google-search-statistics/), +using [900.000 multicore servers](https://www.cloudyn.com/blog/10-facts-didnt-know-server-farms/) for searching [8 billions web pages](http://searchenginewatch.com/sew/study/2063479/coincidentally-googles-index-size-jumps) (320 X size of GOV2). +- Recent "integer compression" GOV2 experiments (best paper at ECIR 2014) [On Inverted Index Compression for Search Engine Efficiency](http://www.dcs.gla.ac.uk/~craigm/publications/catena14compression.pdf) using 8-core Xeon PC are reporting 1.2 seconds per query (for 1.000 Top-k docids). + +### Compile: + Download or clone TurboPFor + git clone git://github.com/powturbo/TurboPFor.git + cd TurboPFor + make + + + To benchmark external libraries + lz77 compression: + git clone --recursive git://github.com/powturbo/TurboPFor.git + cd TurboPFor + make CODEC1=1 CODEC2=1 LZ=1 + +###### Windows visual c++ + nmake /f makefile.vs + +###### Windows visual studio c++ + project files under vs/vs2017 + +### Testing: +##### - Synthetic data (use ZIPF parameter): + + benchmark groups of "integer compression" functions
+ + ./icbench -eBENCH -a1.2 -m0 -M255 -n100M ZIPF + ./icbench -eBITPACK/VBYTE -a1.2 -m0 -M255 -n100M ZIPF + + >*Type "icbench -l1" for a list* + + >*-zipfian distribution alpha = 1.2 (Ex. -a1.0=uniform -a1.5=skewed distribution)
+ -number of integers = 100.000.000
+ -integer range from 0 to 255
* + + + Unsorted lists: individual function test (ex. Copy TurboPack TurboPFor)
+ + ./icbench -a1.5 -m0 -M255 -ecopy/turbopack/turbopfor/turbopack256v ZIPF + + + Unsorted lists: Zigzag encoding w/ option **-fz** or FOR encoding
+ + ./icbench -fz -eturbovbyte/turbopfor/turbopackv ZIPF + ./icbench -eturboforv ZIPF + + + Sorted lists: differential coding w/ option **-fs** (increasing) or **-fS** (strictly increasing)
+ + ./icbench -fs -eturbopack/turbopfor/turbopfor256v ZIPF + + + Generate interactive "file.html" plot for browsing + + ./icbench -p2 -S2 -Q3 file.tbb + + + Unit test: test function from bit size 0 to 32 + + ./icbench -m0 -M32 -eturbpfor -fu + ./icbench -m0 -M8 -eturbopack -fs -n1M + +##### - Data files: + - Raw 32 bits binary data file [Test data](https://github.com/ot/partitioned_elias_fano/tree/master/test/test_data) + + ./icbench file + ./icapp file + ./icapp -Fs file "16 bits raw binary file + ./icapp -Fu file "32 bits raw binary file + ./icapp -Fl file "64 bits raw binary file + ./icapp -Ff file "32 bits raw floating point binary file + ./icapp -Fd file "64 bits raw floating point binary file + + - Text file: 1 entry per line. [Test data: ts.txt(sorted) and lat.txt(unsorted)](https://github.com/zhenjl/encoding/tree/master/benchmark/data)) + + ./icbench -eBENCH -fts ts.txt + ./icbench -eBENCH -ft lat.txt + + ./icapp -Fts data.txt "text file, one 16 bits integer per line + ./icapp -Ftu ts.txt "text file, one 32 bits integer per line + ./icapp -Ftl ts.txt "text file, one 64 bits integer per line + ./icapp -Ftf file "text file, one 32 bits floating point (ex. 8.32456) per line + ./icapp -Ftd file "text file, one 64 bits floating point (ex. 8.324567789) per line + ./icapp -Ftd file -v5 "like prev., display the first 100 values read + ./icapp -Ftd file -v5 -g.00001 "like prev., error bound lossy floating point compression + ./icapp -Ftt file "text file, timestamp in seconds iso-8601 -> 32 bits integer (ex. 2018-03-12T04:31:06) + ./icapp -FtT file "text file, timestamp in milliseconds iso-8601 -> 64 bits integer (ex. 2018-03-12T04:31:06.345) + ./icapp -Ftl -D2 -H file "skip 1th line, convert numbers with 2 decimal digits to 64 bits integers (ex. 456.23 -> 45623) + ./icapp -Ftl -D2 -H -K3 file.csv "like prev., use the 3th number in the line (ex. label=3245, text=99 usage=456.23 -> 456.23 ) + ./icapp -Ftl -D2 -H -K3 -k| file.csv "like prev., use '|' as separator + + - Text file: multiple numbers separated by non-digits (0..9,-,.) characters (ex. 134534,-45678,98788,4345, ) + + ./icapp -Fc data.txt "text file, 32 bits integers (ex. 56789,3245,23,678 ) + ./icapp -Fcd data.txt "text file, 64 bits floting-point numbers (ex. 34.7689,5.20,45.789 ) + + - Multiblocks of 32 bits binary file. (Example gov2 from [DocId data set](#DocId))
+ Block format: [n1: #of Ids][Id1] [Id2]...[IdN] [n2: #of Ids][Id1][Id2]...[IdN]... + + ./icbench -fS -r gov2.sorted + + +##### - Intersections: + 1 - Download Gov2 (or ClueWeb09) + query files (Ex. "1mq.txt") from [DocId data set](#DocId)
+ 8GB RAM required (16GB recommended for benchmarking "clueweb09" files). + + 2 - Create index file + + + ./idxcr gov2.sorted . + + + >*create inverted index file "gov2.sorted.i" in the current directory* + + 3 - Test intersections + + + ./idxqry gov2.sorted.i 1mq.txt + + + >*run queries in file "1mq.txt" over the index of gov2 file* + +##### - Parallel Query Processing: + 1 - Create partitions + + + ./idxseg gov2.sorted . -26m -s8 + + + >*create 8 (CPU hardware threads) partitions for a total of ~26 millions document ids* + + 2 - Create index file for each partition + + + ./idxcr gov2.sorted.s* + + + >*create inverted index file for all partitions "gov2.sorted.s00 - gov2.sorted.s07" in the current directory* + + 3 - Intersections: + + delete "idxqry.o" file and then type "make para" to compile "idxqry" w. multithreading + + + ./idxqry gov2.sorted.s*.i 1mq.txt + + >*run queries in file "1mq.txt" over the index of all gov2 partitions "gov2.sorted.s00.i - gov2.sorted.s07.i".* + +### Function usage: +See benchmark "icbench" program for "integer compression" usage examples. +In general encoding/decoding functions are of the form: + + >**char *endptr = encode( unsigned *in, unsigned n, char *out, [unsigned start], [int b])**
+ endptr : set by encode to the next character in "out" after the encoded buffer
+ in : input integer array
+ n : number of elements
+ out : pointer to output buffer
+ b : number of bits. Only for bit packing functions
+ start : previous value. Only for integrated delta encoding functions + + + >**char *endptr = decode( char *in, unsigned n, unsigned *out, [unsigned start], [int b])**
+ endptr : set by decode to the next character in "in" after the decoded buffer
+ in : pointer to input buffer
+ n : number of elements
+ out : output integer array
+ b : number of bits. Only for bit unpacking functions
+ start : previous value. Only for integrated delta decoding functions + + **Simple high level functions:** + >**size_t compressed_size = encode( unsigned *in, size_t n, char *out)**
+ compressed_size : number of bytes written into compressed output buffer out
+ + >**size_t compressed_size = decode( char *in, size_t n, unsigned *out)**
+ compressed_size : number of bytes read from compressed input buffer in
+ +### Function syntax: + - {vb | p4 | bit | vs}[n][d | d1 | f | fm | z ]{enc/dec | pack/unpack}[| 128V | 256V][8 | 16 | 32 | 64]:
+ vb: variable byte
+ p4: turbopfor
+ vs: variable simple
+ bit: bit packing
+ n : high level array functions for large arrays. + + '' : encoding for unsorted integer lists
+ 'd' : delta encoding for increasing integer lists (sorted w/ duplicate)
+ 'd1': delta encoding for strictly increasing integer lists (sorted unique)
+ 'f' : FOR encoding for sorted integer lists
+ 'z' : ZigZag encoding for unsorted integer lists
+ + 'enc' or 'pack' : encode or bitpack
+ 'dec' or 'unpack': decode or bitunpack
+ 'NN' : integer size (8/16/32/64)
+ +header files to use with documentation:
+ +| c/c++ header file|Integer Compression functions| examples | +|------------|-----------------------------|-----------------| +|vint.h|variable byte| vbenc32/vbdec32 vbdenc32/vbddec32 vbzenc32/vbzdec32 | +|vsimple.h|variable simple| vsenc64/vsdec64 | +|vp4.h|TurboPFor| p4enc32/p4dec32 p4denc32/p4ddec32 p4zenc32/p4zdec32 | +|bitpack.h|Bit Packing, For, +Direct Access| bitpack256v32/bitunpack256v32 bitforenc64/bitfordec64| +|eliasfano.h|Elias Fano| efanoenc256v32/efanoc256v32 | + +Note: Some low level functions (like p4enc32) are limited to 128/256 (SSE/AVX2) integers per call. + +### Environment: +###### OS/Compiler (64 bits): +- Windows: MinGW-w64 makefile +- Windows: Visual c++ (>=VS2008) - makefile.vs (for nmake) +- Windows: Visual Studio project file - vs/vs2017 - Thanks to [PavelP](https://github.com/pps83) +- Linux amd64: GNU GCC (>=4.6) +- Linux amd64: Clang (>=3.2) +- Linux arm64: 64 bits aarch64 ARMv8: gcc (>=6.3) +- Linux arm64: 64 bits aarch64 ARMv8: clang +- MaxOS: XCode (>=9) +- MaxOS: Apple M1 (Clang) +- PowerPC ppc64le (incl. SIMD): gcc (>=8.0) + +###### Multithreading: +- All TurboPFor integer compression functions are thread safe + +### References: + +* [TurboPFor: an analysis](https://michael.stapelberg.ch/posts/2019-02-05-turbopfor-analysis/) + +* **Applications:** + * [Debian Code Search](https://github.com/Debian/dcs/)
+ [Debian Code Search: positional index, TurboPFor-compressed](https://michael.stapelberg.ch/posts/2019-09-29-dcs-positional-turbopfor-index/) + * [Graph500](https://github.com/julianromera/graph500) + * [Small Polygon Compression](https://arxiv.org/abs/1509.05505) + [Poster](http://abhinavjauhri.me/publications/dcc_poster_2016.pdf) + [code](https://github.com/ajauhri/bignum_compression) + * [Parallel Graph Analysis (Lecture 18)](http://www.cs.rpi.edu/~slotag/classes/FA16/) + [code](http://www.cs.rpi.edu/~slotag/classes/FA16/handson/lec18-comp2.cpp) + +* **Benchmark references:** + * [FastPFor](https://github.com/lemire/FastPFor) + [Simdcomp](https://github.com/lemire/simdcomp): SIMDPack FPF, Vbyte FPF, VarintG8IU, StreamVbyte, GroupSimple + * [Optimized Pfor-delta compression code](http://jinruhe.com): OptPFD/OptP4, Simple16 (limited to 28 bits integers) + * [MaskedVByte](http://maskedvbyte.org/). See also: [Vectorized VByte Decoding](http://engineering.indeed.com/blog/2015/03/vectorized-vbyte-decoding-high-performance-vector-instructions/) + * [Streamvbyte](https://github.com/lemire/streamvbyte). + * [Index Compression Using 64-Bit Words](http://people.eng.unimelb.edu.au/ammoffat/abstracts/am10spe.html): Simple-8b (speed optimized version tested) + * [libfor](https://github.com/cruppstahl/for) + * [Compression, SIMD, and Postings Lists](http://www.cs.otago.ac.nz/homepages/andrew/papers/) QMX integer compression from the "simple family" + * [lz4](https://github.com/Cyan4973/lz4). included w. block size 64K as indication. Tested after preprocessing w. delta+transpose + * [blosc](https://github.com/Blosc/c-blosc). blosc is like transpose/shuffle+lz77. Tested blosc+lz4 and blosclz incl. vectorizeed shuffle.
+ * [Document identifier data set](http://lemire.me/data/integercompression2014.html) + +* **Integer compression publications:** + * :green_book:[Evaluating Lightweight Integer Compression Algorithms in Column-Oriented In-Memory DBMS](http://www.adms-conf.org/2021-camera-ready/heinzl_adms21.pdf) + * :green_book:[In Vacuo and In Situ Evaluation of SIMD Codecs (TurboPackV,TurboPFor/QMX)](http://dl.acm.org/citation.cfm?id=3015023) + [paper](http://www.cs.otago.ac.nz/homepages/andrew/papers/) + * :green_book:[SIMD Compression and the Intersection of Sorted Integers](http://arxiv.org/abs/1401.6399) + * :green_book:[Partitioned Elias-Fano Indexes](http://www.di.unipi.it/~ottavian/files/elias_fano_sigir14.pdf) + * :green_book:[On Inverted Index Compression for Search Engine Efficiency](http://www.dcs.gla.ac.uk/~craigm/publications/catena14compression.pdf) + * :green_book:[Google's Group Varint Encoding](http://static.googleusercontent.com/media/research.google.com/de//people/jeff/WSDM09-keynote.pdf) + * :green_book:[Integer Compression tweets](https://twitter.com/search?q=%23integercompression&src=typd) + * :green_book:[Efficient Compression of Scientific Floating-Point Data and An Application in Structural Analysis](https://www.jstage.jst.go.jp/article/jsces/2017/0/2017_20170002/_article) + * :green_book:[SPDP is a compression/decompression algorithm for binary IEEE 754 32/64 bits floating-point data](http://cs.txstate.edu/~burtscher/research/SPDPcompressor/)
+ :green_book:[ SPDP - An Automatically Synthesized Lossless Compression Algorithm for Floating-Point Data](http://cs.txstate.edu/~mb92/papers/dcc18.pdf) + [DCC 2018](http://www.cs.brandeis.edu//~dcc/Programs/Program2018.pdf) + +Last update: 13 Nov 2021 + +## APPENDIX: icbench Integer Compression Benchmark + +##### TurboPFor + external libraries +

+TurboPFor               	https://github.com/powturbo/TurboPFor
+FastPFor (FP)              	https://github.com/lemire/FastPFor
+lz4				https://github.com/Cyan4973/lz4
+LittleIntPacker (LI)       	https://github.com/lemire/LittleIntPacker
+MaskedVbyte             	http://maskedvbyte.org
+Polycom (PC)               	https://github.com/encode84/bcm
+simdcomp (SC)              	https://github.com/lemire/simdcomp
+Simple-8b optimized     	https://github.com/powturbo/TurboPFor
+Streamvbyte             	https://github.com/lemire/streamvbyte
+VarintG8IU              	https://github.com/lemire/FastPFor
+
+ +##### Functions integrated into 'icbench' for benchmarking +
+Codec group:
+TURBOPFOR        TurboPFor library TurboPFor256V/TurboPack256V/TurboPFor256N/TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboForDA/EliasFano/VSimple/TurboPForN/TurboPackN/TurboPForDI
+DEFAULT          Default TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboFor/TurboPForN/TurboPackN/TurboPForDI/TurboPFor256V/TurboPack256V/TurboPFor256N
+BENCH            Benchmark TurboPFor/TurboPackV/TurboVByte/TurboPack/QMX/FP.SimdFastPfor/FP.SimdOptPFor/MaskedVbyte/StreamVbyte
+EFFICIENT        Efficient TurboPFor/vsimple/turbovbyte
+TRANSFORM        transpose/shufle,delta,zigzag tpbyte4s/tpbyte,4/tpnibble,4/ZigZag_32/Delta_32/BitShuffle,4
+BITPACK          Bit Packing TurboPack256V/TurboPackV/TurboPackH/TurboPack/SC.SimdPack128/SC.SimdPack256
+VBYTE            Variable byte TurboVByte/FP.VByte/PC.Vbyte/VarintG8IU/MaskedVbyte/StreamVbyte
+SIMPLE           Simple Family simple8b/simple16/vsimple/qmx
+LZ4              lz4+bitshufle/transpose 4,8 lz4_bitshufle/lz4_tp4/lz4_tp8
+LI               Little Integer LI_Pack/LI_TurboPack/LI_SuperPack/LI_HorPack
+
+
+Function         Description                                      level
+
+--------         -----------                                      -----
+TurboPFor        PFor (SSE2)
+TurboPForN       PFor (SSE2) large blocks
+TurboPFor256     PFor (AVX2)
+TurboPFor256N    PFor (AVX2) large blocks
+TurboPForDA      PFor direct access
+TurboPForDI      PFord min
+TurboPForZZ      PFor zigzag of delta
+TurboFor         FOR
+TurboForV        FOR (SIMD)
+TurboFor256V     FOR (AVX2)
+TurboForDA       FOR direct access
+TurboPackDA      Bit packing direct access
+TurboPack        Bit packing (scalar)
+TurboPackN       Bit packing (scalar) large blocks
+TurboPackV       Bit packing (SSE2 Vertical)
+TurboPackH       Bit packing (SSE2 Horizontal)
+TurboPackVN      Bit packing (SSE2 large block)
+TurboPack256V    Bit packing (AVX2 Vertical)
+TurboPack256N    Bit packing (AVX2 large block)
+TurboVByte       Variable byte (scalar)
+VSimple          Variable simple (scalar)
+EliasFano        Elias fano (scalar)
+EliasFanoV       Eliasfano  (SSE2)
+EliasFano256V    Elias fano (AVX2)
+memcpy           memcpy
+copy             Integer copy
+tpbyte4s         Byte Transpose (scalar)
+tpbyte           Byte transpose (simd)  2,4,8
+tpnibble         Nibble transpose (simd)  2,4,8
+ZigZag32         ZigZag encoding (sse2)
+Delta32          Delta encoding (sse2)
+DDelta32         Delta of delta encoding (sse2)
+Xor32            Xor encoding (sse2)
+FP_PREV64        Floating point PFOR
+FP_FCM64         Floating point PFOR (FCM)
+FP_DFCM64        Floating point PFOR (DFCM)
+TurboPFor64      PFOR 64
+TurboPFor64V     PFOR 64
+Simple8b         64 bits Simple family (instable)
+PC_Simple16      Simple 16. limited to 28 bits
+PC_OptPFD        OptPFD. limited to 28 bits
+PC_Vbyte         Variable byte
+PC_Rice          Rice coding (instable)
+VarintG8IU       Variable byte SIMD
+MaskedVbyte      Variable byte SIMD
+StreamVbyte      Variable byte SIMD
+FP_FastPFor      PFor scalar (inefficient for small blocks)
+FP_SimdFastPFor  PFor SIMD (inefficient for small blocks)
+FP_OptPFor       OptPFor scalar 
+FP_SIMDOptPFor   OptPFor SIMD
+FP_VByte         Variable byte
+FP_Simple8bRLE   Simple-8b + rle
+FP_GROUPSIMPLE   Group Simple
+SC_SIMDPack128   Bit packing (SSE4.1)
+SC_SIMDPack256   Bit packing (SSE4.1)
+SC_For           For (SSE4.1)
+SC_ForDA         For direct access (SSE4.1)
+LibFor_For       For
+LibFor_ForDA     For direct access
+LI_Pack          Bit packing (scalar)
+LI_TurboPack     Bit packing (scalar)
+LI_SuperPack     Bit packing (scalar)
+LI_HorPack       Bit packing (sse4.1 horizontal) 
+LI_BMIPack256    Bit packing (avx2)
+lz4              lz4
+lz4_bit          Bitshuffle + [delta]+lz4 2,4,8
+lz4_nibble       TurboPFor's [delta]+nibble transpose + lz4 2,4,8
+lz4_bitxor       Bitshuffle + [xor]+lz4 2,4,8
+lz4_nibblexor    TurboPFor's [xor]+nibble transpose + lz4 2,4,8
+lz4_byte         TurboPFor's [delta]+byte transpose + lz4 2,4,8
+BitShuffle       Bit shuffle (simd) 2,4,8
+
+ diff --git a/src/ext/for/bitpack.c b/src/ext/for/bitpack.c new file mode 100644 index 00000000000..74542bb7373 --- /dev/null +++ b/src/ext/for/bitpack.c @@ -0,0 +1,426 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression" bit packing + +#include +#define BITUTIL_IN +#define VINT_IN +#include "conf.h" +#include "bitutil.h" +#include "vint.h" +#include "bitpack.h" +#define PAD8(_x_) ( (((_x_)+8-1)/8) ) + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif + +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsequenced" + +#if !defined(SSE2_ON) && !defined(AVX2_ON) //----------------------------------- Plain ----------------------------------------------------------------------- +typedef unsigned char *(*BITPACK_F8)( uint8_t *__restrict out, unsigned n, const unsigned char *__restrict in); +typedef unsigned char *(*BITPACK_D8)( uint8_t *__restrict out, unsigned n, const unsigned char *__restrict in, uint8_t start); +typedef unsigned char *(*BITPACK_F16)(uint16_t *__restrict out, unsigned n, const unsigned char *__restrict in); +typedef unsigned char *(*BITPACK_D16)(uint16_t *__restrict out, unsigned n, const unsigned char *__restrict in, uint16_t start); +typedef unsigned char *(*BITPACK_F32)(uint32_t *__restrict out, unsigned n, const unsigned char *__restrict in); +typedef unsigned char *(*BITPACK_D32)(uint32_t *__restrict out, unsigned n, const unsigned char *__restrict in, uint32_t start); +typedef unsigned char *(*BITPACK_F64)(uint64_t *__restrict out, unsigned n, const unsigned char *__restrict in); +typedef unsigned char *(*BITPACK_D64)(uint64_t *__restrict out, unsigned n, const unsigned char *__restrict in, uint64_t start); + +#if 1 //def _MSC_VER +#define VX (v=x) +#define V x +#else +#define VX v +#define V v +#endif + +#if 0 +#define IP0(_ip_,_x_) *_ip_ +#define IP( _ip_,_x_) *_ip_++ +#define IPI(_ip_) +#else +#define IP0(_ip_,_x_) _ip_[_x_] +#define IP( _ip_,_x_) _ip_[_x_] +#define IPI(_ip_) _ip_ += 32 +#endif + +#define IP9(_ip_,_x_, _parm_) +#define IPW(_ip_,_x_) VX +#define IPX(_ip_,_x_) (V = IP(_ip_,_x_)) + +#define IPV(_ip_,_x_) IP(_ip_,_x_) +#define IP16(_ip_,_x_, _parm_) +#define IP32(_ip_,_x_, _parm_) +#define IP64(_ip_,_x_, _parm_) +#define _BITPACK_ bitpack +#include "bitpack_.h" +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +#define DELTA + +#define IP9(_ip_,_x_, _parm_) V = IP0(_ip_,_x_) - start; start = IP(_ip_,_x_) +#define IPV(_ip_,_x_) VX +#define IPX(_ip_,_x_) (V = IP(_ip_,_x_) - start) +#define IP16(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP32(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP64(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define _BITPACK_ bitdpack +#include "bitpack_.h" +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +#define IP9(_ip_,_x_, _parm_) +#define IPV(_ip_,_x_) IP(_ip_,_x_) - start +#define IPX(_ip_,_x_) (V = IP(_ip_,_x_) - start) +#define IP16(_ip_,_x_, _parm_) +#define IP32(_ip_,_x_, _parm_) +#define IP64(_ip_,_x_, _parm_) +#define _BITPACK_ bitfpack +#include "bitpack_.h" +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +#define IP9( _ip_,_x_, _parm_) V = IP0(_ip_,_x_) - start - 1; start = IP(_ip_,_x_) +#define IPV( _ip_,_x_) VX +#define IPX(_ip_,_x_) (V = IP(_ip_,_x_) - start - 1) +#define IP16(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP32(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP64(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define _BITPACK_ bitd1pack +#include "bitpack_.h" +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +/*#define IP9( _ip_,_x_, _parm_) v = IP(_ip_,_x_) - start - mdelta; start = IP(_ip_,_x_) +#define IPV( _ip_,_x_) v +#define IPX(_ip_,_x_) (v = IP(_ip_,_x_) - start - mdelta) +#define IP32(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define _BITPACK_ bitepack +#include "bitpack_.h"*/ + +#define IP9(_ip_,_x_, _parm_) V = TEMPLATE2(zigzagenc, USIZE)(IP(_ip_,_x_) - start); start = IP(_ip_,_x_) +#define IPV(_ip_,_x_) VX +#define IPX(_ip_,_x_) (V = TEMPLATE2(zigzagenc, USIZE)(IP(_ip_,_x_) - start)) +#define IP16(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP32(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define IP64(_ip_,_x_, _parm_) start = IP(_ip_,_x_) +#define _BITPACK_ bitzpack +#include "bitpack_.h" +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +#define IPI(_ip_) _ip_ += 32; start += 32 +#define IP9(_ip_,_x_, _parm_) +#define IPV(_ip_,_x_) (IP(_ip_,_x_) - start - (_x_) - 1) +#define IPX(_ip_,_x_) (V = IP(_ip_,_x_) - start - (_x_) - 1) +#define IP16(_ip_,_x_, _parm_) +#define IP32(_ip_,_x_, _parm_) +#define IP64(_ip_,_x_, _parm_) +#define _BITPACK_ bitf1pack +#include "bitpack_.h" +#undef IPI +#undef IP9 +#undef IPV +#undef IPX +#undef IP16 +#undef IP32 +#undef IP64 + +#define BITNPACK(in, n, out, _csize_, _usize_) { unsigned char *op = out;\ + for(ip = in, in += n; ip < in;) { \ + TEMPLATE3(uint, _usize_, _t) o,x;\ + unsigned iplen = in - ip,b; \ + if(iplen > _csize_) iplen = _csize_; PREFETCH(ip+512,0);\ + o = TEMPLATE2(bit,_usize_)(ip, iplen, &x); b = TEMPLATE2(bsr,_usize_)(o);\ + *op++ = b; op = TEMPLATE2(bitpacka, _usize_)[b](ip, iplen, op);\ + ip += iplen;\ + }\ + return op - out;\ +} + +#define BITNDPACK(in, n, out, _csize_, _usize_, _bitd_, _bitpacka_) { if(!n) return 0;\ + unsigned char *op = out; \ + TEMPLATE3(uint, _usize_, _t) o,x;\ + start = *in++; \ + TEMPLATE2(vbxput, _usize_)(op, start);\ + for(n--,ip = in; ip != in + (n&~(_csize_-1)); ) { unsigned b; PREFETCH(ip+512,0);\ + o = TEMPLATE2(_bitd_, _usize_)(ip, _csize_, &x, start); b = TEMPLATE2(bsr,_usize_)(o); *op++ = b; op = TEMPLATE2(_bitpacka_,_usize_)[b](ip, _csize_, op, start); ip += _csize_; start = ip[-1];\ + }\ + if(n&=(_csize_-1)) { unsigned b;\ + o = TEMPLATE2(_bitd_, _usize_)(ip, n, &x, start); b = TEMPLATE2(bsr,_usize_)(o); *op++ = b; op = TEMPLATE2(_bitpacka_,_usize_)[b](ip, n, op, start);\ + }\ + return op - out;\ +} + +size_t bitnpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out) { uint8_t *ip,start; BITNPACK(in, n, out, 128, 8); } +size_t bitnpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; BITNPACK(in, n, out, 128, 16); } +size_t bitnpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; BITNPACK(in, n, out, 128, 32); } +size_t bitnpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip,start; BITNPACK(in, n, out, 128, 64); } + +size_t bitndpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out) { uint8_t *ip,start; BITNDPACK(in, n, out, 128, 8, bitd, bitdpacka); } +size_t bitndpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; BITNDPACK(in, n, out, 128, 16, bitd, bitdpacka); } +size_t bitndpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; BITNDPACK(in, n, out, 128, 32, bitd, bitdpacka); } +size_t bitndpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip,start; BITNDPACK(in, n, out, 128, 64, bitd, bitdpacka); } + +size_t bitnd1pack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out) { uint8_t *ip,start; BITNDPACK(in, n, out, 128, 8, bitd1, bitd1packa); } +size_t bitnd1pack16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; BITNDPACK(in, n, out, 128, 16, bitd1, bitd1packa); } +size_t bitnd1pack32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; BITNDPACK(in, n, out, 128, 32, bitd1, bitd1packa); } +size_t bitnd1pack64(uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip,start; BITNDPACK(in, n, out, 128, 64, bitd1, bitd1packa); } + +size_t bitnzpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out) { uint8_t *ip,start; BITNDPACK(in, n, out, 128, 8, bitz, bitzpacka); } +size_t bitnzpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; BITNDPACK(in, n, out, 128, 16, bitz, bitzpacka); } +size_t bitnzpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; BITNDPACK(in, n, out, 128, 32, bitz, bitzpacka); } +size_t bitnzpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip,start; BITNDPACK(in, n, out, 128, 64, bitz, bitzpacka); } + +size_t bitnfpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out) { uint8_t *ip,start; BITNDPACK(in, n, out, 128, 8, bitf, bitfpacka); } +size_t bitnfpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; BITNDPACK(in, n, out, 128, 16, bitf, bitfpacka); } +size_t bitnfpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; BITNDPACK(in, n, out, 128, 32, bitf, bitfpacka); } +size_t bitnfpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip,start; BITNDPACK(in, n, out, 128, 64, bitf, bitfpacka); } + +#else //--------------------------------------- SIMD ---------------------------------------------------------------------------------------------- + +#define _BITNPACKV(in, n, out, _csize_, _usize_, _bitpackv_) {\ + unsigned char *op = out; TEMPLATE3(uint, _usize_, _t) _o,_x;\ + for(ip = in; ip != in + (n&~(_csize_-1)); ip += _csize_) { PREFETCH(ip+512,0);\ + unsigned _b; _o = TEMPLATE2(bit,_usize_)(ip, _csize_, &_x); _b = TEMPLATE2(bsr,_usize_)(_o); *op++ = _b; op = TEMPLATE2(_bitpackv_, _usize_)(ip, _csize_, op, _b);\ + } if(n&=(_csize_-1)) { unsigned _b; _o = TEMPLATE2(bit,_usize_)(ip, n, &_x); _b = TEMPLATE2(bsr,_usize_)(_o); *op++ = _b; op = TEMPLATE2(bitpack, _usize_)(ip, n, op, _b); }\ + return op - out;\ +} + +#define _BITNDPACKV(in, n, out, _csize_, _usize_, _bitdv_, _bitpackv_, _bitd_, _bitpack_) { if(!n) return 0;\ + unsigned char *op = out; TEMPLATE3(uint, _usize_, _t) _o,_x;\ + start = *in++; \ + TEMPLATE2(vbxput, _usize_)(op, start);\ + for(n--,ip = in; ip != in + (n&~(_csize_-1)); ) { PREFETCH(ip+512,0);\ + unsigned _b; _o = TEMPLATE2(_bitdv_, _usize_)(ip, _csize_, &_x, start); _b = TEMPLATE2(bsr,_usize_)(_o); *op++ = _b; op = TEMPLATE2(_bitpackv_, _usize_)(ip, _csize_, op, start, _b); ip += _csize_; start = ip[-1];\ + } if(n&=(_csize_-1)) { unsigned _b; _o = TEMPLATE2(_bitd_, _usize_)(ip, n, &_x, start); _b = TEMPLATE2(bsr,_usize_)(_o); *op++ = _b; op = TEMPLATE2(_bitpack_, _usize_)(ip, n, op, start, _b); }\ + return op - out;\ +} + + #ifdef __AVX2__ +#include +#include "bitpack_.h" + +#define OPPE(__op) +#define IPPE(__op) + +#define PAD8(__x) (((__x)+8-1)/8) +#define OPPE(__op) +#define IPPE(__op) + +#define VI32(ip, i, iv, parm) +#define IP32(ip, i, iv) _mm256_loadu_si256(ip++) + +unsigned char *bitpack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b) { unsigned char *pout = out+PAD8(256*b); BITPACK256V32(in, b, out, 0); return pout; } +#undef VI32 +#undef IP32 + + +#define VI32(_ip_, _i_, _iv_, _sv_) _iv_ = _mm256_sub_epi32(_mm256_loadu_si256(_ip_++),sv) +#define IP32(_ip_, i, _iv_) _iv_ +#include "bitpack_.h" +unsigned char *bitfpack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(256*b); + __m256i v, sv = _mm256_set1_epi32(start); + BITPACK256V32(in, b, out, sv); + return pout; +} + +#define VI32(_ip_, _i_, _iv_, _sv_) _iv_ = _mm256_sub_epi32(_mm256_loadu_si256(_ip_++),_sv_); _sv_ = _mm256_add_epi32(_sv_,cv); +#define IP32(ip, i, _iv_) _iv_ +unsigned char *bitf1pack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(256*b); + __m256i v, sv = _mm256_set_epi32(start+8,start+7,start+6,start+5,start+4,start+3,start+2,start+1), cv = _mm256_set1_epi32(8); + BITPACK256V32(in, b, out, sv); return pout; +} + +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm256_loadu_si256(_ip_++); _iv_ = mm256_delta_epi32(v,_sv_); _sv_ = v +#define IP32(ip, i, _iv_) _iv_ +#include "bitpack_.h" +unsigned char *bitdpack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(256*b); + __m256i v,sv = _mm256_set1_epi32(start); + BITPACK256V32(in, b, out, sv); + return pout; +} + +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm256_loadu_si256(_ip_++); _iv_ = _mm256_sub_epi32(mm256_delta_epi32(v,_sv_),cv); _sv_ = v +unsigned char *bitd1pack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(256*b); + __m256i v, sv = _mm256_set1_epi32(start), cv = _mm256_set1_epi32(1); + BITPACK256V32(in, b, out, sv); + return pout; +} + +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm256_loadu_si256(_ip_++); _iv_ = mm256_delta_epi32(v,_sv_); _sv_ = v; _iv_ = mm256_zzage_epi32(_iv_) +unsigned char *bitzpack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(256*b); + __m256i v, sv = _mm256_set1_epi32(start), cv = _mm256_set1_epi32(1); + BITPACK256V32(in, b, out, sv); + return pout; +} + +size_t bitnpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip; _BITNPACKV( in, n, out, 256, 32, bitpack256v); } +size_t bitndpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 256, 32, bitd, bitdpack256v, bitd, bitdpack); } +size_t bitnd1pack256v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 256, 32, bitd1, bitd1pack256v,bitd1, bitd1pack); } +size_t bitnzpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 256, 32, bitz, bitzpack256v, bitz, bitzpack); } +size_t bitnfpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 256, 32, bitf, bitfpack256v, bitf, bitfpack); } + + #elif defined(__SSE2__) || defined(__ARM_NEON) //----------------------------- SSE --------------------------------------------------------------- +#define OPPE(__op) +#define IPPE(__op) + +#define VI16(ip, i, iv, parm) +#define VI32(ip, i, iv, parm) +#define IP16(_ip_, i, iv) _mm_loadu_si128(_ip_++) +#define IP32(_ip_, i, iv) _mm_loadu_si128(_ip_++) +#include "bitpack_.h" +unsigned char *bitpack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b) { unsigned char *pout = out+PAD8(128*b); BITPACK128V16(in, b, out, 0); return pout; } +unsigned char *bitpack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b) { unsigned char *pout = out+PAD8(128*b); BITPACK128V32(in, b, out, 0); return pout; } +unsigned char *bitpack256w32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b) { unsigned char *_out=out; unsigned *_in=in; +BITPACK128V32(in, b, out, 0); in = _in+128; out = _out+PAD8(128*b); BITPACK128V32(in, b, out, 0); return _out+PAD8(256*b); } + +#ifdef __ARM_NEON +//#define IP32(_ip_, i, iv) _mm_or_si128(_mm_shuffle_epi32( _mm_loadu_si128(_ip_++),_MM_SHUFFLE(3, 1, 2, 0)), _mm_shuffle_epi32( _mm_loadu_si128(_ip_++),_MM_SHUFFLE(2, 0, 3, 1)) ) +#define IP32(_ip_, _i_, _iv_) _mm_or_si128(mm_shuffle_3120_epi32(_mm_loadu_si128(_ip_++) ), mm_shuffle_2031_epi32(_mm_loadu_si128(_ip++) ) ) // optimized shuffle +#else +#define IP32(_ip_, i, iv) _mm_or_si128(_mm_shuffle_epi32( _mm_loadu_si128(_ip_++),_MM_SHUFFLE(2, 0, 3, 1)), _mm_shuffle_epi32( _mm_loadu_si128(_ip_++),_MM_SHUFFLE(3, 1, 2, 0)) ) +#endif +#include "bitpack_.h" +unsigned char *bitpack128v64(uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b) { + if(b<=32) { unsigned char *pout = out+PAD8(128*b); BITPACK128V32(in, b, out, 0); return pout; } else return bitpack64(in,n,out,b); +} + +#define VI16(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = mm_delta_epi16(v,_sv_); _sv_ = v +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = mm_delta_epi32(v,_sv_); _sv_ = v +#define IP16(ip, i, _iv_) _iv_ +#define IP32(ip, i, _iv_) _iv_ +#include "bitpack_.h" +unsigned char *bitdpack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v,sv = _mm_set1_epi16(start); BITPACK128V16(in, b, out, sv); return pout; +} +unsigned char *bitdpack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v,sv = _mm_set1_epi32(start); BITPACK128V32(in, b, out, sv); return pout; +} + +#define VI16(_ip_, _i_, _iv_, _sv_) +#define VI32(_ip_, _i_, _iv_, _sv_) +#define IP16(_ip_, i, _iv_) _mm_sub_epi16(_mm_loadu_si128(_ip_++),sv) +#define IP32(_ip_, i, _iv_) _mm_sub_epi32(_mm_loadu_si128(_ip_++),sv) +#include "bitpack_.h" +unsigned char *bitfpack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi16(start); BITPACK128V16(in, b, out, sv); return pout; +} +unsigned char *bitfpack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi32(start); BITPACK128V32(in, b, out, sv); return pout; +} + +#define VI16(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = _mm_sub_epi16(mm_delta_epi16(v,_sv_),cv); _sv_ = v +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = _mm_sub_epi32(mm_delta_epi32(v,_sv_),cv); _sv_ = v +#define IP16(ip, i, _iv_) _iv_ +#define IP32(ip, i, _iv_) _iv_ +unsigned char *bitd1pack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i sv = _mm_set1_epi16(start), cv = _mm_set1_epi16(1), v; BITPACK128V16(in, b, out, sv); return pout; +} +unsigned char *bitd1pack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(1); BITPACK128V32(in, b, out, sv); return pout; +} + +#define VI16(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = _mm_sub_epi16(SUBI16x8(v,_sv_),cv); _sv_ = v +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = _mm_sub_epi32(SUBI32x4(v,_sv_),cv); _sv_ = v +#define IP16(ip, i, _iv_) _iv_ +#define IP32(ip, i, _iv_) _iv_ +unsigned char *bits1pack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi16(start), cv = _mm_set1_epi16(8); BITPACK128V16(in, b, out, sv); return pout; +} +unsigned char *bits1pack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(4); BITPACK128V32(in, b, out, sv); return pout; +} + +#define VI16(_ip_, _i_, _iv_, _sv_) _iv_ = _mm_sub_epi16(_mm_loadu_si128(_ip_++),_sv_); _sv_ = _mm_add_epi16(_sv_,cv); +#define VI32(_ip_, _i_, _iv_, _sv_) _iv_ = _mm_sub_epi32(_mm_loadu_si128(_ip_++),_sv_); _sv_ = _mm_add_epi32(_sv_,cv); +#define IP16(ip, i, _iv_) _iv_ +#define IP32(ip, i, _iv_) _iv_ +unsigned char *bitf1pack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set_epi16(start+8,start+7,start+6,start+5,start+4,start+3,start+2,start+1), cv = _mm_set1_epi16(8); BITPACK128V16(in, b, out, sv); return pout; +} +unsigned char *bitf1pack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set_epi32( start+4,start+3,start+2,start+1), cv = _mm_set1_epi32(4); BITPACK128V32(in, b, out, sv); return pout; +} + +#define VI16(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = mm_delta_epi16(v,_sv_); _sv_ = v; _iv_ = mm_zzage_epi16(_iv_) +unsigned char *bitzpack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi16(start), cv = _mm_set1_epi16(1); BITPACK128V16(in, b, out, sv); return pout; +} +#define VI32(_ip_, _i_, _iv_, _sv_) v = _mm_loadu_si128(_ip_++); _iv_ = mm_delta_epi32(v,_sv_); _sv_ = v; _iv_ = mm_zzage_epi32(_iv_) +unsigned char *bitzpack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b) { unsigned char *pout = out+PAD8(128*b); + __m128i v, sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(1); BITPACK128V32(in, b, out, sv); return pout; +} + +size_t bitnpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip; _BITNPACKV( in, n, out, 128, 16, bitpack128v); } +size_t bitnpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip; _BITNPACKV( in, n, out, 128, 32, bitpack128v); } +size_t bitnpack128v64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out) { uint64_t *ip; _BITNPACKV( in, n, out, 128, 64, bitpack128v); } +size_t bitnpack256w32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip; _BITNPACKV( in, n, out, 256, 32, bitpack256w); } + +size_t bitndpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; _BITNDPACKV(in, n, out, 128, 16, bitd, bitdpack128v, bitd, bitdpack); } +size_t bitndpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 128, 32, bitd, bitdpack128v, bitd, bitdpack); } + +size_t bitnd1pack128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; _BITNDPACKV(in, n, out, 128, 16, bitd1, bitd1pack128v, bitd1, bitd1pack); } +size_t bitnd1pack128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 128, 32, bitd1, bitd1pack128v, bitd1, bitd1pack); } + +size_t bitns1pack128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; _BITNDPACKV(in, n, out, 128, 16, bits128v, bits1pack128v, bitd1, bitd1pack); } +size_t bitns1pack128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 128, 32, bits128v, bits1pack128v, bitd1, bitd1pack); } + +size_t bitnzpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; _BITNDPACKV(in, n, out, 128, 16, bitz, bitzpack128v, bitz, bitzpack); } +size_t bitnzpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 128, 32, bitz, bitzpack128v, bitz, bitzpack); } + +size_t bitnfpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start; _BITNDPACKV(in, n, out, 128, 16, bitf, bitfpack128v, bitf, bitfpack); } +size_t bitnfpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start; _BITNDPACKV(in, n, out, 128, 32, bitf, bitfpack128v, bitf, bitfpack); } + #endif // SSE +#endif // Plain + +#pragma clang diagnostic pop diff --git a/src/ext/for/bitpack.h b/src/ext/for/bitpack.h new file mode 100644 index 00000000000..e4a2e682add --- /dev/null +++ b/src/ext/for/bitpack.h @@ -0,0 +1,310 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// bitpack.h - "Integer Compression" Binary Packing header file +#ifndef BITPACK_H_ +#define BITPACK_H_ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//******************** Bit Packing High Level API - n unlimited *************************************************** +size_t bitnpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack128v64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t bitndpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitndpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t bitnd1pack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnd1pack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t bitnzpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnzpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t bitnfpack8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t bitnfpack256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t bitnunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t bitnunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitnunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnunpack128v64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitnunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t bitndunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t bitndunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitndunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitndunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitndunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitndunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitndunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t bitnd1unpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t bitnd1unpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnd1unpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnd1unpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitnd1unpack128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnd1unpack128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnd1unpack256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t bitnzunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t bitnzunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnzunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnzunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitnzunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnzunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnzunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t bitnfunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t bitnfunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnfunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnfunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t bitnfunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t bitnfunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t bitnfunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +//******** Bit Packing Low level API **************************************************************** +// bipackNN: Pack array with n unsigned (NN bits in[n]) values to the buffer out using nbits per value. Return value = end of compressed buffer out +unsigned char *bitpack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out , unsigned b); +unsigned char *bitpack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out , unsigned b); +unsigned char *bitpack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out , unsigned b); +unsigned char *bitpack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out , unsigned b); + +// delta bit packing +unsigned char *bitdpack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint8_t start, unsigned b); +unsigned char *bitdpack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint16_t start, unsigned b); +unsigned char *bitdpack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint32_t start, unsigned b); +unsigned char *bitdpack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint64_t start, unsigned b); + +unsigned char *bitd1pack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint8_t start, unsigned b); +unsigned char *bitd1pack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint16_t start, unsigned b); +unsigned char *bitd1pack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint32_t start, unsigned b); +unsigned char *bitd1pack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint64_t start, unsigned b); + +// FOR bit packing : sorted integer array +unsigned char *bitfpack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint8_t start, unsigned b); +unsigned char *bitfpack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint16_t start, unsigned b); +unsigned char *bitfpack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint32_t start, unsigned b); +unsigned char *bitfpack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint64_t start, unsigned b); + +unsigned char *bitf1pack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint8_t start, unsigned b); +unsigned char *bitf1pack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint16_t start, unsigned b); +unsigned char *bitf1pack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint32_t start, unsigned b); +unsigned char *bitf1pack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint64_t start, unsigned b); + +// zigzag : unsorted integer array +unsigned char *bitzpack8( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint8_t start, unsigned b); +unsigned char *bitzpack16( uint16_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint16_t start, unsigned b); +unsigned char *bitzpack32( uint32_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint32_t start, unsigned b); +unsigned char *bitzpack64( uint64_t *__restrict in, unsigned n, const unsigned char *__restrict out, uint64_t start, unsigned b); + +//-------------------------------------- SIMD ------------------------------------------------------------------------------------------ +// Pack array with 128 unsigned (32 bits in[n]) values to the buffer out using nbits per value. Return value = end of compressed buffer out +unsigned char *bitpack128v16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out , unsigned b); +unsigned char *bitdpack128v16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b); +unsigned char *bitd1pack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b); +unsigned char *bitfpack128v16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b); +unsigned char *bitf1pack128v16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b); +unsigned char *bitzpack128v16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start, unsigned b); + +unsigned char *bitpack128v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out , unsigned b); +unsigned char *bitdpack128v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitd1pack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitfpack128v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitf1pack128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitzpack128v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); + +//unsigned char *bitpack256w32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out , unsigned b); +unsigned char *bitpack128v64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out , unsigned b); + +unsigned char *bitpack256v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out , unsigned b); +unsigned char *bitdpack256v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitd1pack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitfpack256v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitf1pack256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); +unsigned char *bitzpack256v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start, unsigned b); + +//********************************** Bit Packing : Unpack **************************************************************** + +// ---------------- Unpack a b-bits packed integer array ------------------------------------------------------------------------------- +// unpack a bitpacked integer array. Return value = end of packed buffer in +unsigned char *bitunpack8( const unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, unsigned b); +unsigned char *bitunpack16( const unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, unsigned b); +unsigned char *bitunpack32( const unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, unsigned b); +unsigned char *bitunpack64( const unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b); + +// ---------------- Direct Access to a single packed integer array entry -------------------------------------------------------------- + #ifdef TURBOPFOR_DAC + #ifdef __AVX2__ +#include +#define bzhi64(_u_, _b_) _bzhi_u64(_u_, _b_) +#define bzhi32(_u_, _b_) _bzhi_u32(_u_, _b_) + #else +#define bzhi64(_u_, _b_) ((_u_) & ((1ull<<(_b_))-1)) +#define bzhi32(_u_, _b_) ((_u_) & ((1u <<(_b_))-1)) + #endif + +#include "conf.h" + +static ALWAYS_INLINE unsigned bitgetx32(const unsigned char *__restrict in, unsigned idx, unsigned b) { unsigned bidx = b*idx; return bzhi64( ctou64((uint32_t *)in+(bidx>>5)) >> (bidx&0x1f), b ); } +//static ALWAYS_INLINE unsigned bitgetx32(const unsigned char *__restrict in, unsigned idx, unsigned b) { unsigned bidx = b*idx; + //return (ctou64((uint32_t *)in+(bidx>>5)) << 32+(bidx&0x1f)) >> (64-b); +// return bzhi64( ctou64((uint32_t *)in+(bidx>>5)) >> (bidx&0x1f), b ); } +static ALWAYS_INLINE unsigned _bitgetx32(const unsigned char *__restrict in, uint64_t bidx, unsigned b) { return bzhi64( ctou64((uint32_t *)in+(bidx>>5)) >> (bidx&0x1f), b ); } + +// like bitgetx32 but for 16 bits integer array +static ALWAYS_INLINE unsigned bitgetx8( const unsigned char *__restrict in, unsigned idx, unsigned b) { unsigned bidx = b*idx; return bzhi32( ctou16((uint16_t *)in+(bidx>>4)) >> (bidx& 0xf), b ); } +static ALWAYS_INLINE unsigned _bitgetx8( const unsigned char *__restrict in, unsigned bidx, unsigned b) { return bzhi32( ctou16((uint16_t *)in+(bidx>>4)) >> (bidx& 0xf), b ); } +static ALWAYS_INLINE unsigned bitgetx16(const unsigned char *__restrict in, unsigned idx, unsigned b) { unsigned bidx = b*idx; return bzhi32( ctou32((uint32_t *)in+(bidx>>4)) >> (bidx& 0xf), b ); } +static ALWAYS_INLINE unsigned _bitgetx16(const unsigned char *__restrict in, unsigned bidx, unsigned b) { return bzhi32( ctou32((uint32_t *)in+(bidx>>4)) >> (bidx& 0xf), b ); } + +// Set a single value with index "idx" +static ALWAYS_INLINE void bitsetx16(const unsigned char *__restrict in, unsigned idx, unsigned v, unsigned b) { unsigned bidx = b*idx; unsigned *p = (unsigned *) in+(bidx>>4) ; *p = ( *p & ~(((1u <>5)); *p = ( *p & ~(((1ull<> 1;\ + IP9(ip, i*64+22, parm); w |= (uint64_t)IPV(ip, i*64+22) << 2;\ + IP9(ip, i*64+23, parm); w |= (uint64_t)IPV(ip, i*64+23) << 5;\ + IP9(ip, i*64+24, parm); w |= (uint64_t)IPV(ip, i*64+24) << 8;\ + IP9(ip, i*64+25, parm); w |= (uint64_t)IPV(ip, i*64+25) << 11;\ + IP9(ip, i*64+26, parm); w |= (uint64_t)IPV(ip, i*64+26) << 14;\ + IP9(ip, i*64+27, parm); w |= (uint64_t)IPV(ip, i*64+27) << 17;\ + IP9(ip, i*64+28, parm); w |= (uint64_t)IPV(ip, i*64+28) << 20;\ + IP9(ip, i*64+29, parm); w |= (uint64_t)IPV(ip, i*64+29) << 23;\ + IP9(ip, i*64+30, parm); w |= (uint64_t)IPV(ip, i*64+30) << 26;\ + IP9(ip, i*64+31, parm); w |= (uint64_t)IPV(ip, i*64+31) << 29;*((uint64_t *)op+i*3+ 1) = w;;\ +} + +#define BITPACK64_3(ip, op, parm) { \ + BITBLK64_3(ip, 0, op, parm); IPI(ip); op += 3*4/sizeof(op[0]);\ +} + +#define BITBLK64_4(ip, i, op, parm) { uint64_t w;;\ + IP9(ip, i*16+ 0, parm); w = (uint64_t)IPV(ip, i*16+ 0) ;\ + IP9(ip, i*16+ 1, parm); w |= (uint64_t)IPV(ip, i*16+ 1) << 4;\ + IP9(ip, i*16+ 2, parm); w |= (uint64_t)IPV(ip, i*16+ 2) << 8;\ + IP9(ip, i*16+ 3, parm); w |= (uint64_t)IPV(ip, i*16+ 3) << 12;\ + IP9(ip, i*16+ 4, parm); w |= (uint64_t)IPV(ip, i*16+ 4) << 16;\ + IP9(ip, i*16+ 5, parm); w |= (uint64_t)IPV(ip, i*16+ 5) << 20;\ + IP9(ip, i*16+ 6, parm); w |= (uint64_t)IPV(ip, i*16+ 6) << 24;\ + IP9(ip, i*16+ 7, parm); w |= (uint64_t)IPV(ip, i*16+ 7) << 28;\ + IP9(ip, i*16+ 8, parm); w |= (uint64_t)IPV(ip, i*16+ 8) << 32;\ + IP9(ip, i*16+ 9, parm); w |= (uint64_t)IPV(ip, i*16+ 9) << 36;\ + IP9(ip, i*16+10, parm); w |= (uint64_t)IPV(ip, i*16+10) << 40;\ + IP9(ip, i*16+11, parm); w |= (uint64_t)IPV(ip, i*16+11) << 44;\ + IP9(ip, i*16+12, parm); w |= (uint64_t)IPV(ip, i*16+12) << 48;\ + IP9(ip, i*16+13, parm); w |= (uint64_t)IPV(ip, i*16+13) << 52;\ + IP9(ip, i*16+14, parm); w |= (uint64_t)IPV(ip, i*16+14) << 56;\ + IP9(ip, i*16+15, parm); w |= (uint64_t)IPV(ip, i*16+15) << 60;*((uint64_t *)op+i*1+ 0) = w;;\ +} + +#define BITPACK64_4(ip, op, parm) { \ + BITBLK64_4(ip, 0, op, parm);\ + BITBLK64_4(ip, 1, op, parm); IPI(ip); op += 4*4/sizeof(op[0]);\ +} + +#define BITBLK64_5(ip, i, op, parm) { uint64_t w;;\ + IP9(ip, i*64+ 0, parm); w = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); w |= (uint64_t)IPV(ip, i*64+ 1) << 5;\ + IP9(ip, i*64+ 2, parm); w |= (uint64_t)IPV(ip, i*64+ 2) << 10;\ + IP9(ip, i*64+ 3, parm); w |= (uint64_t)IPV(ip, i*64+ 3) << 15;\ + IP9(ip, i*64+ 4, parm); w |= (uint64_t)IPV(ip, i*64+ 4) << 20;\ + IP9(ip, i*64+ 5, parm); w |= (uint64_t)IPV(ip, i*64+ 5) << 25;\ + IP9(ip, i*64+ 6, parm); w |= (uint64_t)IPV(ip, i*64+ 6) << 30;\ + IP9(ip, i*64+ 7, parm); w |= (uint64_t)IPV(ip, i*64+ 7) << 35;\ + IP9(ip, i*64+ 8, parm); w |= (uint64_t)IPV(ip, i*64+ 8) << 40;\ + IP9(ip, i*64+ 9, parm); w |= (uint64_t)IPV(ip, i*64+ 9) << 45;\ + IP9(ip, i*64+10, parm); w |= (uint64_t)IPV(ip, i*64+10) << 50;\ + IP9(ip, i*64+11, parm); w |= (uint64_t)IPV(ip, i*64+11) << 55 | (uint64_t)IPX(ip, i*64+12) << 60;*((uint64_t *)op+i*5+ 0) = w;\ + IP64(ip, i*64+12, parm); w = (uint64_t)IPW(ip, i*64+12) >> 4;\ + IP9(ip, i*64+13, parm); w |= (uint64_t)IPV(ip, i*64+13) << 1;\ + IP9(ip, i*64+14, parm); w |= (uint64_t)IPV(ip, i*64+14) << 6;\ + IP9(ip, i*64+15, parm); w |= (uint64_t)IPV(ip, i*64+15) << 11;\ + IP9(ip, i*64+16, parm); w |= (uint64_t)IPV(ip, i*64+16) << 16;\ + IP9(ip, i*64+17, parm); w |= (uint64_t)IPV(ip, i*64+17) << 21;\ + IP9(ip, i*64+18, parm); w |= (uint64_t)IPV(ip, i*64+18) << 26;\ + IP9(ip, i*64+19, parm); w |= (uint64_t)IPV(ip, i*64+19) << 31;\ + IP9(ip, i*64+20, parm); w |= (uint64_t)IPV(ip, i*64+20) << 36;\ + IP9(ip, i*64+21, parm); w |= (uint64_t)IPV(ip, i*64+21) << 41;\ + IP9(ip, i*64+22, parm); w |= (uint64_t)IPV(ip, i*64+22) << 46;\ + IP9(ip, i*64+23, parm); w |= (uint64_t)IPV(ip, i*64+23) << 51;\ + IP9(ip, i*64+24, parm); w |= (uint64_t)IPV(ip, i*64+24) << 56 | (uint64_t)IPX(ip, i*64+25) << 61;*((uint64_t *)op+i*5+ 1) = w;\ + IP64(ip, i*64+25, parm); w = (uint64_t)IPW(ip, i*64+25) >> 3;\ + IP9(ip, i*64+26, parm); w |= (uint64_t)IPV(ip, i*64+26) << 2;\ + IP9(ip, i*64+27, parm); w |= (uint64_t)IPV(ip, i*64+27) << 7;\ + IP9(ip, i*64+28, parm); w |= (uint64_t)IPV(ip, i*64+28) << 12;\ + IP9(ip, i*64+29, parm); w |= (uint64_t)IPV(ip, i*64+29) << 17;\ + IP9(ip, i*64+30, parm); w |= (uint64_t)IPV(ip, i*64+30) << 22;\ + IP9(ip, i*64+31, parm); w |= (uint64_t)IPV(ip, i*64+31) << 27;*((uint64_t *)op+i*5+ 2) = w;;\ +} + +#define BITPACK64_5(ip, op, parm) { \ + BITBLK64_5(ip, 0, op, parm); IPI(ip); op += 5*4/sizeof(op[0]);\ +} + +#define BITBLK64_6(ip, i, op, parm) { uint64_t w;;\ + IP9(ip, i*32+ 0, parm); w = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); w |= (uint64_t)IPV(ip, i*32+ 1) << 6;\ + IP9(ip, i*32+ 2, parm); w |= (uint64_t)IPV(ip, i*32+ 2) << 12;\ + IP9(ip, i*32+ 3, parm); w |= (uint64_t)IPV(ip, i*32+ 3) << 18;\ + IP9(ip, i*32+ 4, parm); w |= (uint64_t)IPV(ip, i*32+ 4) << 24;\ + IP9(ip, i*32+ 5, parm); w |= (uint64_t)IPV(ip, i*32+ 5) << 30;\ + IP9(ip, i*32+ 6, parm); w |= (uint64_t)IPV(ip, i*32+ 6) << 36;\ + IP9(ip, i*32+ 7, parm); w |= (uint64_t)IPV(ip, i*32+ 7) << 42;\ + IP9(ip, i*32+ 8, parm); w |= (uint64_t)IPV(ip, i*32+ 8) << 48;\ + IP9(ip, i*32+ 9, parm); w |= (uint64_t)IPV(ip, i*32+ 9) << 54 | (uint64_t)IPX(ip, i*32+10) << 60;*((uint64_t *)op+i*3+ 0) = w;\ + IP64(ip, i*32+10, parm); w = (uint64_t)IPW(ip, i*32+10) >> 4;\ + IP9(ip, i*32+11, parm); w |= (uint64_t)IPV(ip, i*32+11) << 2;\ + IP9(ip, i*32+12, parm); w |= (uint64_t)IPV(ip, i*32+12) << 8;\ + IP9(ip, i*32+13, parm); w |= (uint64_t)IPV(ip, i*32+13) << 14;\ + IP9(ip, i*32+14, parm); w |= (uint64_t)IPV(ip, i*32+14) << 20;\ + IP9(ip, i*32+15, parm); w |= (uint64_t)IPV(ip, i*32+15) << 26;\ + IP9(ip, i*32+16, parm); w |= (uint64_t)IPV(ip, i*32+16) << 32;\ + IP9(ip, i*32+17, parm); w |= (uint64_t)IPV(ip, i*32+17) << 38;\ + IP9(ip, i*32+18, parm); w |= (uint64_t)IPV(ip, i*32+18) << 44;\ + IP9(ip, i*32+19, parm); w |= (uint64_t)IPV(ip, i*32+19) << 50;\ + IP9(ip, i*32+20, parm); w |= (uint64_t)IPV(ip, i*32+20) << 56 | (uint64_t)IPX(ip, i*32+21) << 62;*((uint64_t *)op+i*3+ 1) = w;\ + IP64(ip, i*32+21, parm); w = (uint64_t)IPW(ip, i*32+21) >> 2;\ + IP9(ip, i*32+22, parm); w |= (uint64_t)IPV(ip, i*32+22) << 4;\ + IP9(ip, i*32+23, parm); w |= (uint64_t)IPV(ip, i*32+23) << 10;\ + IP9(ip, i*32+24, parm); w |= (uint64_t)IPV(ip, i*32+24) << 16;\ + IP9(ip, i*32+25, parm); w |= (uint64_t)IPV(ip, i*32+25) << 22;\ + IP9(ip, i*32+26, parm); w |= (uint64_t)IPV(ip, i*32+26) << 28;\ + IP9(ip, i*32+27, parm); w |= (uint64_t)IPV(ip, i*32+27) << 34;\ + IP9(ip, i*32+28, parm); w |= (uint64_t)IPV(ip, i*32+28) << 40;\ + IP9(ip, i*32+29, parm); w |= (uint64_t)IPV(ip, i*32+29) << 46;\ + IP9(ip, i*32+30, parm); w |= (uint64_t)IPV(ip, i*32+30) << 52;\ + IP9(ip, i*32+31, parm); w |= (uint64_t)IPV(ip, i*32+31) << 58;*((uint64_t *)op+i*3+ 2) = w;;\ +} + +#define BITPACK64_6(ip, op, parm) { \ + BITBLK64_6(ip, 0, op, parm); IPI(ip); op += 6*4/sizeof(op[0]);\ +} + +#define BITBLK64_7(ip, i, op, parm) { uint64_t w;;\ + IP9(ip, i*64+ 0, parm); w = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); w |= (uint64_t)IPV(ip, i*64+ 1) << 7;\ + IP9(ip, i*64+ 2, parm); w |= (uint64_t)IPV(ip, i*64+ 2) << 14;\ + IP9(ip, i*64+ 3, parm); w |= (uint64_t)IPV(ip, i*64+ 3) << 21;\ + IP9(ip, i*64+ 4, parm); w |= (uint64_t)IPV(ip, i*64+ 4) << 28;\ + IP9(ip, i*64+ 5, parm); w |= (uint64_t)IPV(ip, i*64+ 5) << 35;\ + IP9(ip, i*64+ 6, parm); w |= (uint64_t)IPV(ip, i*64+ 6) << 42;\ + IP9(ip, i*64+ 7, parm); w |= (uint64_t)IPV(ip, i*64+ 7) << 49;\ + IP9(ip, i*64+ 8, parm); w |= (uint64_t)IPV(ip, i*64+ 8) << 56 | (uint64_t)IPX(ip, i*64+9) << 63;*((uint64_t *)op+i*7+ 0) = w;\ + IP64(ip, i*64+ 9, parm); w = (uint64_t)IPW(ip, i*64+ 9) >> 1;\ + IP9(ip, i*64+10, parm); w |= (uint64_t)IPV(ip, i*64+10) << 6;\ + IP9(ip, i*64+11, parm); w |= (uint64_t)IPV(ip, i*64+11) << 13;\ + IP9(ip, i*64+12, parm); w |= (uint64_t)IPV(ip, i*64+12) << 20;\ + IP9(ip, i*64+13, parm); w |= (uint64_t)IPV(ip, i*64+13) << 27;\ + IP9(ip, i*64+14, parm); w |= (uint64_t)IPV(ip, i*64+14) << 34;\ + IP9(ip, i*64+15, parm); w |= (uint64_t)IPV(ip, i*64+15) << 41;\ + IP9(ip, i*64+16, parm); w |= (uint64_t)IPV(ip, i*64+16) << 48;\ + IP9(ip, i*64+17, parm); w |= (uint64_t)IPV(ip, i*64+17) << 55 | (uint64_t)IPX(ip, i*64+18) << 62;*((uint64_t *)op+i*7+ 1) = w;\ + IP64(ip, i*64+18, parm); w = (uint64_t)IPW(ip, i*64+18) >> 2;\ + IP9(ip, i*64+19, parm); w |= (uint64_t)IPV(ip, i*64+19) << 5;\ + IP9(ip, i*64+20, parm); w |= (uint64_t)IPV(ip, i*64+20) << 12;\ + IP9(ip, i*64+21, parm); w |= (uint64_t)IPV(ip, i*64+21) << 19;\ + IP9(ip, i*64+22, parm); w |= (uint64_t)IPV(ip, i*64+22) << 26;\ + IP9(ip, i*64+23, parm); w |= (uint64_t)IPV(ip, i*64+23) << 33;\ + IP9(ip, i*64+24, parm); w |= (uint64_t)IPV(ip, i*64+24) << 40;\ + IP9(ip, i*64+25, parm); w |= (uint64_t)IPV(ip, i*64+25) << 47;\ + IP9(ip, i*64+26, parm); w |= (uint64_t)IPV(ip, i*64+26) << 54 | (uint64_t)IPX(ip, i*64+27) << 61;*((uint64_t *)op+i*7+ 2) = w;\ + IP64(ip, i*64+27, parm); w = (uint64_t)IPW(ip, i*64+27) >> 3;\ + IP9(ip, i*64+28, parm); w |= (uint64_t)IPV(ip, i*64+28) << 4;\ + IP9(ip, i*64+29, parm); w |= (uint64_t)IPV(ip, i*64+29) << 11;\ + IP9(ip, i*64+30, parm); w |= (uint64_t)IPV(ip, i*64+30) << 18;\ + IP9(ip, i*64+31, parm); w |= (uint64_t)IPV(ip, i*64+31) << 25;*((uint64_t *)op+i*7+ 3) = w;;\ +} + +#define BITPACK64_7(ip, op, parm) { \ + BITBLK64_7(ip, 0, op, parm); IPI(ip); op += 7*4/sizeof(op[0]);\ +} + +#define BITBLK64_8(ip, i, op, parm) { ;\ + IP9(ip, i*8+ 0, parm); *((uint64_t *)op+i*1+ 0) = (uint64_t)IPV(ip, i*8+ 0) ;\ + IP9(ip, i*8+ 1, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 1) << 8;\ + IP9(ip, i*8+ 2, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 2) << 16;\ + IP9(ip, i*8+ 3, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 3) << 24;\ + IP9(ip, i*8+ 4, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 4) << 32;\ + IP9(ip, i*8+ 5, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 5) << 40;\ + IP9(ip, i*8+ 6, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 6) << 48;\ + IP9(ip, i*8+ 7, parm); *((uint64_t *)op+i*1+ 0) |= (uint64_t)IPV(ip, i*8+ 7) << 56;\ +} + +#define BITPACK64_8(ip, op, parm) { \ + BITBLK64_8(ip, 0, op, parm);\ + BITBLK64_8(ip, 1, op, parm);\ + BITBLK64_8(ip, 2, op, parm);\ + BITBLK64_8(ip, 3, op, parm); IPI(ip); op += 8*4/sizeof(op[0]);\ +} + +#define BITBLK64_9(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*9+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 9;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 18;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 3) << 27;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 4) << 36;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 5) << 45;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*64+ 6) << 54 | (uint64_t)IPX(ip, i*64+7) << 63;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*9+ 1) = (uint64_t)IPW(ip, i*64+ 7) >> 1;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+ 8) << 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+ 9) << 17;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+10) << 26;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+11) << 35;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+12) << 44;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*64+13) << 53 | (uint64_t)IPX(ip, i*64+14) << 62;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*9+ 2) = (uint64_t)IPW(ip, i*64+14) >> 2;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+15) << 7;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+16) << 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+17) << 25;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+18) << 34;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+19) << 43;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*64+20) << 52 | (uint64_t)IPX(ip, i*64+21) << 61;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*9+ 3) = (uint64_t)IPW(ip, i*64+21) >> 3;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+22) << 6;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+23) << 15;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+24) << 24;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+25) << 33;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+26) << 42;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*64+27) << 51 | (uint64_t)IPX(ip, i*64+28) << 60;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*9+ 4) = (uint64_t)IPW(ip, i*64+28) >> 4;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*9+ 4) |= (uint64_t)IPV(ip, i*64+29) << 5;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*9+ 4) |= (uint64_t)IPV(ip, i*64+30) << 14;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*9+ 4) |= (uint64_t)IPV(ip, i*64+31) << 23;\ +} + +#define BITPACK64_9(ip, op, parm) { \ + BITBLK64_9(ip, 0, op, parm); IPI(ip); op += 9*4/sizeof(op[0]);\ +} + +#define BITBLK64_10(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*5+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 10;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*32+ 2) << 20;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*32+ 3) << 30;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*32+ 4) << 40;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*32+ 5) << 50 | (uint64_t)IPX(ip, i*32+6) << 60;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*5+ 1) = (uint64_t)IPW(ip, i*32+ 6) >> 4;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*32+ 7) << 6;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*32+ 8) << 16;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*32+ 9) << 26;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*32+10) << 36;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*32+11) << 46 | (uint64_t)IPX(ip, i*32+12) << 56;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*5+ 2) = (uint64_t)IPW(ip, i*32+12) >> 8;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+13) << 2;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+14) << 12;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+15) << 22;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+16) << 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+17) << 42;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*32+18) << 52 | (uint64_t)IPX(ip, i*32+19) << 62;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*5+ 3) = (uint64_t)IPW(ip, i*32+19) >> 2;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*32+20) << 8;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*32+21) << 18;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*32+22) << 28;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*32+23) << 38;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*32+24) << 48 | (uint64_t)IPX(ip, i*32+25) << 58;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*5+ 4) = (uint64_t)IPW(ip, i*32+25) >> 6;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+26) << 4;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+27) << 14;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+28) << 24;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+29) << 34;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+30) << 44;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*32+31) << 54;\ +} + +#define BITPACK64_10(ip, op, parm) { \ + BITBLK64_10(ip, 0, op, parm); IPI(ip); op += 10*4/sizeof(op[0]);\ +} + +#define BITBLK64_11(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*11+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*11+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 11;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*11+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 22;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*11+ 0) |= (uint64_t)IPV(ip, i*64+ 3) << 33;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*11+ 0) |= (uint64_t)IPV(ip, i*64+ 4) << 44 | (uint64_t)IPX(ip, i*64+5) << 55;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*11+ 1) = (uint64_t)IPW(ip, i*64+ 5) >> 9;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*64+ 6) << 2;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*64+ 7) << 13;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*64+ 8) << 24;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*64+ 9) << 35;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*64+10) << 46 | (uint64_t)IPX(ip, i*64+11) << 57;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*11+ 2) = (uint64_t)IPW(ip, i*64+11) >> 7;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*64+12) << 4;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*64+13) << 15;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*64+14) << 26;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*64+15) << 37;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*64+16) << 48 | (uint64_t)IPX(ip, i*64+17) << 59;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*11+ 3) = (uint64_t)IPW(ip, i*64+17) >> 5;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*64+18) << 6;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*64+19) << 17;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*64+20) << 28;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*64+21) << 39;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*64+22) << 50 | (uint64_t)IPX(ip, i*64+23) << 61;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*11+ 4) = (uint64_t)IPW(ip, i*64+23) >> 3;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*64+24) << 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*64+25) << 19;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*64+26) << 30;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*64+27) << 41;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*64+28) << 52 | (uint64_t)IPX(ip, i*64+29) << 63;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*11+ 5) = (uint64_t)IPW(ip, i*64+29) >> 1;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*11+ 5) |= (uint64_t)IPV(ip, i*64+30) << 10;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*11+ 5) |= (uint64_t)IPV(ip, i*64+31) << 21;\ +} + +#define BITPACK64_11(ip, op, parm) { \ + BITBLK64_11(ip, 0, op, parm); IPI(ip); op += 11*4/sizeof(op[0]);\ +} + +#define BITBLK64_12(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*3+ 0) = (uint64_t)IPV(ip, i*16+ 0) ;\ + IP9(ip, i*16+ 1, parm); *((uint64_t *)op+i*3+ 0) |= (uint64_t)IPV(ip, i*16+ 1) << 12;\ + IP9(ip, i*16+ 2, parm); *((uint64_t *)op+i*3+ 0) |= (uint64_t)IPV(ip, i*16+ 2) << 24;\ + IP9(ip, i*16+ 3, parm); *((uint64_t *)op+i*3+ 0) |= (uint64_t)IPV(ip, i*16+ 3) << 36;\ + IP9(ip, i*16+ 4, parm); *((uint64_t *)op+i*3+ 0) |= (uint64_t)IPV(ip, i*16+ 4) << 48 | (uint64_t)IPX(ip, i*16+5) << 60;\ + IP64(ip, i*16+ 5, parm); *((uint64_t *)op+i*3+ 1) = (uint64_t)IPW(ip, i*16+ 5) >> 4;\ + IP9(ip, i*16+ 6, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*16+ 6) << 8;\ + IP9(ip, i*16+ 7, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*16+ 7) << 20;\ + IP9(ip, i*16+ 8, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*16+ 8) << 32;\ + IP9(ip, i*16+ 9, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*16+ 9) << 44 | (uint64_t)IPX(ip, i*16+10) << 56;\ + IP64(ip, i*16+10, parm); *((uint64_t *)op+i*3+ 2) = (uint64_t)IPW(ip, i*16+10) >> 8;\ + IP9(ip, i*16+11, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*16+11) << 4;\ + IP9(ip, i*16+12, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*16+12) << 16;\ + IP9(ip, i*16+13, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*16+13) << 28;\ + IP9(ip, i*16+14, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*16+14) << 40;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*16+15) << 52;\ +} + +#define BITPACK64_12(ip, op, parm) { \ + BITBLK64_12(ip, 0, op, parm);\ + BITBLK64_12(ip, 1, op, parm); IPI(ip); op += 12*4/sizeof(op[0]);\ +} + +#define BITBLK64_13(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*13+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*13+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 13;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*13+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 26;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*13+ 0) |= (uint64_t)IPV(ip, i*64+ 3) << 39 | (uint64_t)IPX(ip, i*64+4) << 52;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*13+ 1) = (uint64_t)IPW(ip, i*64+ 4) >> 12;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*13+ 1) |= (uint64_t)IPV(ip, i*64+ 5) << 1;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*13+ 1) |= (uint64_t)IPV(ip, i*64+ 6) << 14;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*13+ 1) |= (uint64_t)IPV(ip, i*64+ 7) << 27;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*13+ 1) |= (uint64_t)IPV(ip, i*64+ 8) << 40 | (uint64_t)IPX(ip, i*64+9) << 53;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*13+ 2) = (uint64_t)IPW(ip, i*64+ 9) >> 11;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*64+10) << 2;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*64+11) << 15;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*64+12) << 28;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*64+13) << 41 | (uint64_t)IPX(ip, i*64+14) << 54;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*13+ 3) = (uint64_t)IPW(ip, i*64+14) >> 10;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*13+ 3) |= (uint64_t)IPV(ip, i*64+15) << 3;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*13+ 3) |= (uint64_t)IPV(ip, i*64+16) << 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*13+ 3) |= (uint64_t)IPV(ip, i*64+17) << 29;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*13+ 3) |= (uint64_t)IPV(ip, i*64+18) << 42 | (uint64_t)IPX(ip, i*64+19) << 55;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*13+ 4) = (uint64_t)IPW(ip, i*64+19) >> 9;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*64+20) << 4;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*64+21) << 17;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*64+22) << 30;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*64+23) << 43 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*13+ 5) = (uint64_t)IPW(ip, i*64+24) >> 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*13+ 5) |= (uint64_t)IPV(ip, i*64+25) << 5;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*13+ 5) |= (uint64_t)IPV(ip, i*64+26) << 18;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*13+ 5) |= (uint64_t)IPV(ip, i*64+27) << 31;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*13+ 5) |= (uint64_t)IPV(ip, i*64+28) << 44 | (uint64_t)IPX(ip, i*64+29) << 57;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*13+ 6) = (uint64_t)IPW(ip, i*64+29) >> 7;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*13+ 6) |= (uint64_t)IPV(ip, i*64+30) << 6;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*13+ 6) |= (uint64_t)IPV(ip, i*64+31) << 19;\ +} + +#define BITPACK64_13(ip, op, parm) { \ + BITBLK64_13(ip, 0, op, parm); IPI(ip); op += 13*4/sizeof(op[0]);\ +} + +#define BITBLK64_14(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*7+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*7+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 14;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*7+ 0) |= (uint64_t)IPV(ip, i*32+ 2) << 28;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*7+ 0) |= (uint64_t)IPV(ip, i*32+ 3) << 42 | (uint64_t)IPX(ip, i*32+4) << 56;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*7+ 1) = (uint64_t)IPW(ip, i*32+ 4) >> 8;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*7+ 1) |= (uint64_t)IPV(ip, i*32+ 5) << 6;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*7+ 1) |= (uint64_t)IPV(ip, i*32+ 6) << 20;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*7+ 1) |= (uint64_t)IPV(ip, i*32+ 7) << 34;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*7+ 1) |= (uint64_t)IPV(ip, i*32+ 8) << 48 | (uint64_t)IPX(ip, i*32+9) << 62;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*7+ 2) = (uint64_t)IPW(ip, i*32+ 9) >> 2;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*7+ 2) |= (uint64_t)IPV(ip, i*32+10) << 12;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*7+ 2) |= (uint64_t)IPV(ip, i*32+11) << 26;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*7+ 2) |= (uint64_t)IPV(ip, i*32+12) << 40 | (uint64_t)IPX(ip, i*32+13) << 54;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*7+ 3) = (uint64_t)IPW(ip, i*32+13) >> 10;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*32+14) << 4;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*32+15) << 18;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*32+16) << 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*32+17) << 46 | (uint64_t)IPX(ip, i*32+18) << 60;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*7+ 4) = (uint64_t)IPW(ip, i*32+18) >> 4;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*7+ 4) |= (uint64_t)IPV(ip, i*32+19) << 10;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*7+ 4) |= (uint64_t)IPV(ip, i*32+20) << 24;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*7+ 4) |= (uint64_t)IPV(ip, i*32+21) << 38 | (uint64_t)IPX(ip, i*32+22) << 52;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*7+ 5) = (uint64_t)IPW(ip, i*32+22) >> 12;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*7+ 5) |= (uint64_t)IPV(ip, i*32+23) << 2;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*7+ 5) |= (uint64_t)IPV(ip, i*32+24) << 16;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*7+ 5) |= (uint64_t)IPV(ip, i*32+25) << 30;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*7+ 5) |= (uint64_t)IPV(ip, i*32+26) << 44 | (uint64_t)IPX(ip, i*32+27) << 58;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*7+ 6) = (uint64_t)IPW(ip, i*32+27) >> 6;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*32+28) << 8;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*32+29) << 22;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*32+30) << 36;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*32+31) << 50;\ +} + +#define BITPACK64_14(ip, op, parm) { \ + BITBLK64_14(ip, 0, op, parm); IPI(ip); op += 14*4/sizeof(op[0]);\ +} + +#define BITBLK64_15(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*15+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*15+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 15;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*15+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 30;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*15+ 0) |= (uint64_t)IPV(ip, i*64+ 3) << 45 | (uint64_t)IPX(ip, i*64+4) << 60;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*15+ 1) = (uint64_t)IPW(ip, i*64+ 4) >> 4;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*15+ 1) |= (uint64_t)IPV(ip, i*64+ 5) << 11;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*15+ 1) |= (uint64_t)IPV(ip, i*64+ 6) << 26;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*15+ 1) |= (uint64_t)IPV(ip, i*64+ 7) << 41 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*15+ 2) = (uint64_t)IPW(ip, i*64+ 8) >> 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*15+ 2) |= (uint64_t)IPV(ip, i*64+ 9) << 7;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*15+ 2) |= (uint64_t)IPV(ip, i*64+10) << 22;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*15+ 2) |= (uint64_t)IPV(ip, i*64+11) << 37 | (uint64_t)IPX(ip, i*64+12) << 52;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*15+ 3) = (uint64_t)IPW(ip, i*64+12) >> 12;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*15+ 3) |= (uint64_t)IPV(ip, i*64+13) << 3;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*15+ 3) |= (uint64_t)IPV(ip, i*64+14) << 18;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*15+ 3) |= (uint64_t)IPV(ip, i*64+15) << 33;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*15+ 3) |= (uint64_t)IPV(ip, i*64+16) << 48 | (uint64_t)IPX(ip, i*64+17) << 63;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*15+ 4) = (uint64_t)IPW(ip, i*64+17) >> 1;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*15+ 4) |= (uint64_t)IPV(ip, i*64+18) << 14;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*15+ 4) |= (uint64_t)IPV(ip, i*64+19) << 29;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*15+ 4) |= (uint64_t)IPV(ip, i*64+20) << 44 | (uint64_t)IPX(ip, i*64+21) << 59;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*15+ 5) = (uint64_t)IPW(ip, i*64+21) >> 5;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*15+ 5) |= (uint64_t)IPV(ip, i*64+22) << 10;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*15+ 5) |= (uint64_t)IPV(ip, i*64+23) << 25;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*15+ 5) |= (uint64_t)IPV(ip, i*64+24) << 40 | (uint64_t)IPX(ip, i*64+25) << 55;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*15+ 6) = (uint64_t)IPW(ip, i*64+25) >> 9;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*15+ 6) |= (uint64_t)IPV(ip, i*64+26) << 6;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*15+ 6) |= (uint64_t)IPV(ip, i*64+27) << 21;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*15+ 6) |= (uint64_t)IPV(ip, i*64+28) << 36 | (uint64_t)IPX(ip, i*64+29) << 51;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*15+ 7) = (uint64_t)IPW(ip, i*64+29) >> 13;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*15+ 7) |= (uint64_t)IPV(ip, i*64+30) << 2;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*15+ 7) |= (uint64_t)IPV(ip, i*64+31) << 17;\ +} + +#define BITPACK64_15(ip, op, parm) { \ + BITBLK64_15(ip, 0, op, parm); IPI(ip); op += 15*4/sizeof(op[0]);\ +} + +#define BITBLK64_16(ip, i, op, parm) { \ + IP9(ip, i*4+ 0, parm); *(uint16_t *)(op+i*8+ 0) = IPV(ip, i*4+ 0);\ + IP9(ip, i*4+ 1, parm); *(uint16_t *)(op+i*8+ 2) = IPV(ip, i*4+ 1);\ + IP9(ip, i*4+ 2, parm); *(uint16_t *)(op+i*8+ 4) = IPV(ip, i*4+ 2);\ + IP9(ip, i*4+ 3, parm); *(uint16_t *)(op+i*8+ 6) = IPV(ip, i*4+ 3);;\ +} + +#define BITPACK64_16(ip, op, parm) { \ + BITBLK64_16(ip, 0, op, parm);\ + BITBLK64_16(ip, 1, op, parm);\ + BITBLK64_16(ip, 2, op, parm);\ + BITBLK64_16(ip, 3, op, parm);\ + BITBLK64_16(ip, 4, op, parm);\ + BITBLK64_16(ip, 5, op, parm);\ + BITBLK64_16(ip, 6, op, parm);\ + BITBLK64_16(ip, 7, op, parm); IPI(ip); op += 16*4/sizeof(op[0]);\ +} + +#define BITBLK64_17(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*17+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*17+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 17;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*17+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 34 | (uint64_t)IPX(ip, i*64+3) << 51;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*17+ 1) = (uint64_t)IPW(ip, i*64+ 3) >> 13;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*17+ 1) |= (uint64_t)IPV(ip, i*64+ 4) << 4;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*17+ 1) |= (uint64_t)IPV(ip, i*64+ 5) << 21;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*17+ 1) |= (uint64_t)IPV(ip, i*64+ 6) << 38 | (uint64_t)IPX(ip, i*64+7) << 55;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*17+ 2) = (uint64_t)IPW(ip, i*64+ 7) >> 9;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*17+ 2) |= (uint64_t)IPV(ip, i*64+ 8) << 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*17+ 2) |= (uint64_t)IPV(ip, i*64+ 9) << 25;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*17+ 2) |= (uint64_t)IPV(ip, i*64+10) << 42 | (uint64_t)IPX(ip, i*64+11) << 59;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*17+ 3) = (uint64_t)IPW(ip, i*64+11) >> 5;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*17+ 3) |= (uint64_t)IPV(ip, i*64+12) << 12;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*17+ 3) |= (uint64_t)IPV(ip, i*64+13) << 29;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*17+ 3) |= (uint64_t)IPV(ip, i*64+14) << 46 | (uint64_t)IPX(ip, i*64+15) << 63;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*17+ 4) = (uint64_t)IPW(ip, i*64+15) >> 1;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*17+ 4) |= (uint64_t)IPV(ip, i*64+16) << 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*17+ 4) |= (uint64_t)IPV(ip, i*64+17) << 33 | (uint64_t)IPX(ip, i*64+18) << 50;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*17+ 5) = (uint64_t)IPW(ip, i*64+18) >> 14;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*17+ 5) |= (uint64_t)IPV(ip, i*64+19) << 3;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*17+ 5) |= (uint64_t)IPV(ip, i*64+20) << 20;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*17+ 5) |= (uint64_t)IPV(ip, i*64+21) << 37 | (uint64_t)IPX(ip, i*64+22) << 54;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*17+ 6) = (uint64_t)IPW(ip, i*64+22) >> 10;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*17+ 6) |= (uint64_t)IPV(ip, i*64+23) << 7;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*17+ 6) |= (uint64_t)IPV(ip, i*64+24) << 24;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*17+ 6) |= (uint64_t)IPV(ip, i*64+25) << 41 | (uint64_t)IPX(ip, i*64+26) << 58;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*17+ 7) = (uint64_t)IPW(ip, i*64+26) >> 6;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*17+ 7) |= (uint64_t)IPV(ip, i*64+27) << 11;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*17+ 7) |= (uint64_t)IPV(ip, i*64+28) << 28;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*17+ 7) |= (uint64_t)IPV(ip, i*64+29) << 45 | (uint64_t)IPX(ip, i*64+30) << 62;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*17+ 8) = (uint64_t)IPW(ip, i*64+30) >> 2;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*17+ 8) |= (uint64_t)IPV(ip, i*64+31) << 15;\ +} + +#define BITPACK64_17(ip, op, parm) { \ + BITBLK64_17(ip, 0, op, parm); IPI(ip); op += 17*4/sizeof(op[0]);\ +} + +#define BITBLK64_18(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*9+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 18;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*9+ 0) |= (uint64_t)IPV(ip, i*32+ 2) << 36 | (uint64_t)IPX(ip, i*32+3) << 54;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*9+ 1) = (uint64_t)IPW(ip, i*32+ 3) >> 10;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*32+ 4) << 8;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*32+ 5) << 26;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*32+ 6) << 44 | (uint64_t)IPX(ip, i*32+7) << 62;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*9+ 2) = (uint64_t)IPW(ip, i*32+ 7) >> 2;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*32+ 8) << 16;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*32+ 9) << 34 | (uint64_t)IPX(ip, i*32+10) << 52;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*9+ 3) = (uint64_t)IPW(ip, i*32+10) >> 12;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*32+11) << 6;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*32+12) << 24;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*32+13) << 42 | (uint64_t)IPX(ip, i*32+14) << 60;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*9+ 4) = (uint64_t)IPW(ip, i*32+14) >> 4;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*9+ 4) |= (uint64_t)IPV(ip, i*32+15) << 14;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*9+ 4) |= (uint64_t)IPV(ip, i*32+16) << 32 | (uint64_t)IPX(ip, i*32+17) << 50;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*9+ 5) = (uint64_t)IPW(ip, i*32+17) >> 14;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*9+ 5) |= (uint64_t)IPV(ip, i*32+18) << 4;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*9+ 5) |= (uint64_t)IPV(ip, i*32+19) << 22;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*9+ 5) |= (uint64_t)IPV(ip, i*32+20) << 40 | (uint64_t)IPX(ip, i*32+21) << 58;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*9+ 6) = (uint64_t)IPW(ip, i*32+21) >> 6;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*9+ 6) |= (uint64_t)IPV(ip, i*32+22) << 12;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*9+ 6) |= (uint64_t)IPV(ip, i*32+23) << 30 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*9+ 7) = (uint64_t)IPW(ip, i*32+24) >> 16;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*9+ 7) |= (uint64_t)IPV(ip, i*32+25) << 2;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*9+ 7) |= (uint64_t)IPV(ip, i*32+26) << 20;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*9+ 7) |= (uint64_t)IPV(ip, i*32+27) << 38 | (uint64_t)IPX(ip, i*32+28) << 56;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*9+ 8) = (uint64_t)IPW(ip, i*32+28) >> 8;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*9+ 8) |= (uint64_t)IPV(ip, i*32+29) << 10;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*9+ 8) |= (uint64_t)IPV(ip, i*32+30) << 28;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*9+ 8) |= (uint64_t)IPV(ip, i*32+31) << 46;\ +} + +#define BITPACK64_18(ip, op, parm) { \ + BITBLK64_18(ip, 0, op, parm); IPI(ip); op += 18*4/sizeof(op[0]);\ +} + +#define BITBLK64_19(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*19+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*19+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 19;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*19+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 38 | (uint64_t)IPX(ip, i*64+3) << 57;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*19+ 1) = (uint64_t)IPW(ip, i*64+ 3) >> 7;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*19+ 1) |= (uint64_t)IPV(ip, i*64+ 4) << 12;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*19+ 1) |= (uint64_t)IPV(ip, i*64+ 5) << 31 | (uint64_t)IPX(ip, i*64+6) << 50;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*19+ 2) = (uint64_t)IPW(ip, i*64+ 6) >> 14;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*19+ 2) |= (uint64_t)IPV(ip, i*64+ 7) << 5;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*19+ 2) |= (uint64_t)IPV(ip, i*64+ 8) << 24;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*19+ 2) |= (uint64_t)IPV(ip, i*64+ 9) << 43 | (uint64_t)IPX(ip, i*64+10) << 62;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*19+ 3) = (uint64_t)IPW(ip, i*64+10) >> 2;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*19+ 3) |= (uint64_t)IPV(ip, i*64+11) << 17;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*19+ 3) |= (uint64_t)IPV(ip, i*64+12) << 36 | (uint64_t)IPX(ip, i*64+13) << 55;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*19+ 4) = (uint64_t)IPW(ip, i*64+13) >> 9;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*19+ 4) |= (uint64_t)IPV(ip, i*64+14) << 10;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*19+ 4) |= (uint64_t)IPV(ip, i*64+15) << 29 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*19+ 5) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*19+ 5) |= (uint64_t)IPV(ip, i*64+17) << 3;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*19+ 5) |= (uint64_t)IPV(ip, i*64+18) << 22;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*19+ 5) |= (uint64_t)IPV(ip, i*64+19) << 41 | (uint64_t)IPX(ip, i*64+20) << 60;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*19+ 6) = (uint64_t)IPW(ip, i*64+20) >> 4;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*19+ 6) |= (uint64_t)IPV(ip, i*64+21) << 15;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*19+ 6) |= (uint64_t)IPV(ip, i*64+22) << 34 | (uint64_t)IPX(ip, i*64+23) << 53;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*19+ 7) = (uint64_t)IPW(ip, i*64+23) >> 11;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*19+ 7) |= (uint64_t)IPV(ip, i*64+24) << 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*19+ 7) |= (uint64_t)IPV(ip, i*64+25) << 27 | (uint64_t)IPX(ip, i*64+26) << 46;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*19+ 8) = (uint64_t)IPW(ip, i*64+26) >> 18;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*19+ 8) |= (uint64_t)IPV(ip, i*64+27) << 1;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*19+ 8) |= (uint64_t)IPV(ip, i*64+28) << 20;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*19+ 8) |= (uint64_t)IPV(ip, i*64+29) << 39 | (uint64_t)IPX(ip, i*64+30) << 58;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*19+ 9) = (uint64_t)IPW(ip, i*64+30) >> 6;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*19+ 9) |= (uint64_t)IPV(ip, i*64+31) << 13;\ +} + +#define BITPACK64_19(ip, op, parm) { \ + BITBLK64_19(ip, 0, op, parm); IPI(ip); op += 19*4/sizeof(op[0]);\ +} + +#define BITBLK64_20(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*5+ 0) = (uint64_t)IPV(ip, i*16+ 0) ;\ + IP9(ip, i*16+ 1, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*16+ 1) << 20;\ + IP9(ip, i*16+ 2, parm); *((uint64_t *)op+i*5+ 0) |= (uint64_t)IPV(ip, i*16+ 2) << 40 | (uint64_t)IPX(ip, i*16+3) << 60;\ + IP64(ip, i*16+ 3, parm); *((uint64_t *)op+i*5+ 1) = (uint64_t)IPW(ip, i*16+ 3) >> 4;\ + IP9(ip, i*16+ 4, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*16+ 4) << 16;\ + IP9(ip, i*16+ 5, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*16+ 5) << 36 | (uint64_t)IPX(ip, i*16+6) << 56;\ + IP64(ip, i*16+ 6, parm); *((uint64_t *)op+i*5+ 2) = (uint64_t)IPW(ip, i*16+ 6) >> 8;\ + IP9(ip, i*16+ 7, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*16+ 7) << 12;\ + IP9(ip, i*16+ 8, parm); *((uint64_t *)op+i*5+ 2) |= (uint64_t)IPV(ip, i*16+ 8) << 32 | (uint64_t)IPX(ip, i*16+9) << 52;\ + IP64(ip, i*16+ 9, parm); *((uint64_t *)op+i*5+ 3) = (uint64_t)IPW(ip, i*16+ 9) >> 12;\ + IP9(ip, i*16+10, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*16+10) << 8;\ + IP9(ip, i*16+11, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*16+11) << 28 | (uint64_t)IPX(ip, i*16+12) << 48;\ + IP64(ip, i*16+12, parm); *((uint64_t *)op+i*5+ 4) = (uint64_t)IPW(ip, i*16+12) >> 16;\ + IP9(ip, i*16+13, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*16+13) << 4;\ + IP9(ip, i*16+14, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*16+14) << 24;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*16+15) << 44;\ +} + +#define BITPACK64_20(ip, op, parm) { \ + BITBLK64_20(ip, 0, op, parm);\ + BITBLK64_20(ip, 1, op, parm); IPI(ip); op += 20*4/sizeof(op[0]);\ +} + +#define BITBLK64_21(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*21+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*21+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 21;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*21+ 0) |= (uint64_t)IPV(ip, i*64+ 2) << 42 | (uint64_t)IPX(ip, i*64+3) << 63;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*21+ 1) = (uint64_t)IPW(ip, i*64+ 3) >> 1;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*21+ 1) |= (uint64_t)IPV(ip, i*64+ 4) << 20;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*21+ 1) |= (uint64_t)IPV(ip, i*64+ 5) << 41 | (uint64_t)IPX(ip, i*64+6) << 62;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*21+ 2) = (uint64_t)IPW(ip, i*64+ 6) >> 2;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*21+ 2) |= (uint64_t)IPV(ip, i*64+ 7) << 19;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*21+ 2) |= (uint64_t)IPV(ip, i*64+ 8) << 40 | (uint64_t)IPX(ip, i*64+9) << 61;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*21+ 3) = (uint64_t)IPW(ip, i*64+ 9) >> 3;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*21+ 3) |= (uint64_t)IPV(ip, i*64+10) << 18;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*21+ 3) |= (uint64_t)IPV(ip, i*64+11) << 39 | (uint64_t)IPX(ip, i*64+12) << 60;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*21+ 4) = (uint64_t)IPW(ip, i*64+12) >> 4;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*21+ 4) |= (uint64_t)IPV(ip, i*64+13) << 17;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*21+ 4) |= (uint64_t)IPV(ip, i*64+14) << 38 | (uint64_t)IPX(ip, i*64+15) << 59;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*21+ 5) = (uint64_t)IPW(ip, i*64+15) >> 5;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*21+ 5) |= (uint64_t)IPV(ip, i*64+16) << 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*21+ 5) |= (uint64_t)IPV(ip, i*64+17) << 37 | (uint64_t)IPX(ip, i*64+18) << 58;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*21+ 6) = (uint64_t)IPW(ip, i*64+18) >> 6;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*21+ 6) |= (uint64_t)IPV(ip, i*64+19) << 15;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*21+ 6) |= (uint64_t)IPV(ip, i*64+20) << 36 | (uint64_t)IPX(ip, i*64+21) << 57;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*21+ 7) = (uint64_t)IPW(ip, i*64+21) >> 7;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*21+ 7) |= (uint64_t)IPV(ip, i*64+22) << 14;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*21+ 7) |= (uint64_t)IPV(ip, i*64+23) << 35 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*21+ 8) = (uint64_t)IPW(ip, i*64+24) >> 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*21+ 8) |= (uint64_t)IPV(ip, i*64+25) << 13;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*21+ 8) |= (uint64_t)IPV(ip, i*64+26) << 34 | (uint64_t)IPX(ip, i*64+27) << 55;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*21+ 9) = (uint64_t)IPW(ip, i*64+27) >> 9;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*21+ 9) |= (uint64_t)IPV(ip, i*64+28) << 12;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*21+ 9) |= (uint64_t)IPV(ip, i*64+29) << 33 | (uint64_t)IPX(ip, i*64+30) << 54;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*21+10) = (uint64_t)IPW(ip, i*64+30) >> 10;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*21+10) |= (uint64_t)IPV(ip, i*64+31) << 11;\ +} + +#define BITPACK64_21(ip, op, parm) { \ + BITBLK64_21(ip, 0, op, parm); IPI(ip); op += 21*4/sizeof(op[0]);\ +} + +#define BITBLK64_22(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*11+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*11+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 22 | (uint64_t)IPX(ip, i*32+2) << 44;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*11+ 1) = (uint64_t)IPW(ip, i*32+ 2) >> 20;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*32+ 3) << 2;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*11+ 1) |= (uint64_t)IPV(ip, i*32+ 4) << 24 | (uint64_t)IPX(ip, i*32+5) << 46;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*11+ 2) = (uint64_t)IPW(ip, i*32+ 5) >> 18;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*32+ 6) << 4;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*32+ 7) << 26 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*11+ 3) = (uint64_t)IPW(ip, i*32+ 8) >> 16;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*32+ 9) << 6;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*11+ 3) |= (uint64_t)IPV(ip, i*32+10) << 28 | (uint64_t)IPX(ip, i*32+11) << 50;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*11+ 4) = (uint64_t)IPW(ip, i*32+11) >> 14;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*32+12) << 8;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*32+13) << 30 | (uint64_t)IPX(ip, i*32+14) << 52;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*11+ 5) = (uint64_t)IPW(ip, i*32+14) >> 12;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*11+ 5) |= (uint64_t)IPV(ip, i*32+15) << 10;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*11+ 5) |= (uint64_t)IPV(ip, i*32+16) << 32 | (uint64_t)IPX(ip, i*32+17) << 54;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*11+ 6) = (uint64_t)IPW(ip, i*32+17) >> 10;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*11+ 6) |= (uint64_t)IPV(ip, i*32+18) << 12;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*11+ 6) |= (uint64_t)IPV(ip, i*32+19) << 34 | (uint64_t)IPX(ip, i*32+20) << 56;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*11+ 7) = (uint64_t)IPW(ip, i*32+20) >> 8;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*11+ 7) |= (uint64_t)IPV(ip, i*32+21) << 14;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*11+ 7) |= (uint64_t)IPV(ip, i*32+22) << 36 | (uint64_t)IPX(ip, i*32+23) << 58;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*11+ 8) = (uint64_t)IPW(ip, i*32+23) >> 6;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*11+ 8) |= (uint64_t)IPV(ip, i*32+24) << 16;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*11+ 8) |= (uint64_t)IPV(ip, i*32+25) << 38 | (uint64_t)IPX(ip, i*32+26) << 60;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*11+ 9) = (uint64_t)IPW(ip, i*32+26) >> 4;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*11+ 9) |= (uint64_t)IPV(ip, i*32+27) << 18;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*11+ 9) |= (uint64_t)IPV(ip, i*32+28) << 40 | (uint64_t)IPX(ip, i*32+29) << 62;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*11+10) = (uint64_t)IPW(ip, i*32+29) >> 2;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*11+10) |= (uint64_t)IPV(ip, i*32+30) << 20;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*11+10) |= (uint64_t)IPV(ip, i*32+31) << 42;\ +} + +#define BITPACK64_22(ip, op, parm) { \ + BITBLK64_22(ip, 0, op, parm); IPI(ip); op += 22*4/sizeof(op[0]);\ +} + +#define BITBLK64_23(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*23+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*23+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 23 | (uint64_t)IPX(ip, i*64+2) << 46;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*23+ 1) = (uint64_t)IPW(ip, i*64+ 2) >> 18;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*23+ 1) |= (uint64_t)IPV(ip, i*64+ 3) << 5;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*23+ 1) |= (uint64_t)IPV(ip, i*64+ 4) << 28 | (uint64_t)IPX(ip, i*64+5) << 51;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*23+ 2) = (uint64_t)IPW(ip, i*64+ 5) >> 13;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*23+ 2) |= (uint64_t)IPV(ip, i*64+ 6) << 10;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*23+ 2) |= (uint64_t)IPV(ip, i*64+ 7) << 33 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*23+ 3) = (uint64_t)IPW(ip, i*64+ 8) >> 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*23+ 3) |= (uint64_t)IPV(ip, i*64+ 9) << 15;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*23+ 3) |= (uint64_t)IPV(ip, i*64+10) << 38 | (uint64_t)IPX(ip, i*64+11) << 61;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*23+ 4) = (uint64_t)IPW(ip, i*64+11) >> 3;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*23+ 4) |= (uint64_t)IPV(ip, i*64+12) << 20 | (uint64_t)IPX(ip, i*64+13) << 43;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*23+ 5) = (uint64_t)IPW(ip, i*64+13) >> 21;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*23+ 5) |= (uint64_t)IPV(ip, i*64+14) << 2;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*23+ 5) |= (uint64_t)IPV(ip, i*64+15) << 25 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*23+ 6) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*23+ 6) |= (uint64_t)IPV(ip, i*64+17) << 7;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*23+ 6) |= (uint64_t)IPV(ip, i*64+18) << 30 | (uint64_t)IPX(ip, i*64+19) << 53;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*23+ 7) = (uint64_t)IPW(ip, i*64+19) >> 11;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*23+ 7) |= (uint64_t)IPV(ip, i*64+20) << 12;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*23+ 7) |= (uint64_t)IPV(ip, i*64+21) << 35 | (uint64_t)IPX(ip, i*64+22) << 58;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*23+ 8) = (uint64_t)IPW(ip, i*64+22) >> 6;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*23+ 8) |= (uint64_t)IPV(ip, i*64+23) << 17;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*23+ 8) |= (uint64_t)IPV(ip, i*64+24) << 40 | (uint64_t)IPX(ip, i*64+25) << 63;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*23+ 9) = (uint64_t)IPW(ip, i*64+25) >> 1;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*23+ 9) |= (uint64_t)IPV(ip, i*64+26) << 22 | (uint64_t)IPX(ip, i*64+27) << 45;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*23+10) = (uint64_t)IPW(ip, i*64+27) >> 19;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*23+10) |= (uint64_t)IPV(ip, i*64+28) << 4;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*23+10) |= (uint64_t)IPV(ip, i*64+29) << 27 | (uint64_t)IPX(ip, i*64+30) << 50;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*23+11) = (uint64_t)IPW(ip, i*64+30) >> 14;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*23+11) |= (uint64_t)IPV(ip, i*64+31) << 9;\ +} + +#define BITPACK64_23(ip, op, parm) { \ + BITBLK64_23(ip, 0, op, parm); IPI(ip); op += 23*4/sizeof(op[0]);\ +} + +#define BITBLK64_24(ip, i, op, parm) { ;\ + IP9(ip, i*8+ 0, parm); *((uint64_t *)op+i*3+ 0) = (uint64_t)IPV(ip, i*8+ 0) ;\ + IP9(ip, i*8+ 1, parm); *((uint64_t *)op+i*3+ 0) |= (uint64_t)IPV(ip, i*8+ 1) << 24 | (uint64_t)IPX(ip, i*8+2) << 48;\ + IP64(ip, i*8+ 2, parm); *((uint64_t *)op+i*3+ 1) = (uint64_t)IPW(ip, i*8+ 2) >> 16;\ + IP9(ip, i*8+ 3, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*8+ 3) << 8;\ + IP9(ip, i*8+ 4, parm); *((uint64_t *)op+i*3+ 1) |= (uint64_t)IPV(ip, i*8+ 4) << 32 | (uint64_t)IPX(ip, i*8+5) << 56;\ + IP64(ip, i*8+ 5, parm); *((uint64_t *)op+i*3+ 2) = (uint64_t)IPW(ip, i*8+ 5) >> 8;\ + IP9(ip, i*8+ 6, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*8+ 6) << 16;\ + IP9(ip, i*8+ 7, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*8+ 7) << 40;\ +} + +#define BITPACK64_24(ip, op, parm) { \ + BITBLK64_24(ip, 0, op, parm);\ + BITBLK64_24(ip, 1, op, parm);\ + BITBLK64_24(ip, 2, op, parm);\ + BITBLK64_24(ip, 3, op, parm); IPI(ip); op += 24*4/sizeof(op[0]);\ +} + +#define BITBLK64_25(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*25+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*25+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 25 | (uint64_t)IPX(ip, i*64+2) << 50;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*25+ 1) = (uint64_t)IPW(ip, i*64+ 2) >> 14;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*25+ 1) |= (uint64_t)IPV(ip, i*64+ 3) << 11;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*25+ 1) |= (uint64_t)IPV(ip, i*64+ 4) << 36 | (uint64_t)IPX(ip, i*64+5) << 61;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*25+ 2) = (uint64_t)IPW(ip, i*64+ 5) >> 3;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*25+ 2) |= (uint64_t)IPV(ip, i*64+ 6) << 22 | (uint64_t)IPX(ip, i*64+7) << 47;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*25+ 3) = (uint64_t)IPW(ip, i*64+ 7) >> 17;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*25+ 3) |= (uint64_t)IPV(ip, i*64+ 8) << 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*25+ 3) |= (uint64_t)IPV(ip, i*64+ 9) << 33 | (uint64_t)IPX(ip, i*64+10) << 58;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*25+ 4) = (uint64_t)IPW(ip, i*64+10) >> 6;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*25+ 4) |= (uint64_t)IPV(ip, i*64+11) << 19 | (uint64_t)IPX(ip, i*64+12) << 44;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*25+ 5) = (uint64_t)IPW(ip, i*64+12) >> 20;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*25+ 5) |= (uint64_t)IPV(ip, i*64+13) << 5;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*25+ 5) |= (uint64_t)IPV(ip, i*64+14) << 30 | (uint64_t)IPX(ip, i*64+15) << 55;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*25+ 6) = (uint64_t)IPW(ip, i*64+15) >> 9;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*25+ 6) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 41;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*25+ 7) = (uint64_t)IPW(ip, i*64+17) >> 23;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*25+ 7) |= (uint64_t)IPV(ip, i*64+18) << 2;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*25+ 7) |= (uint64_t)IPV(ip, i*64+19) << 27 | (uint64_t)IPX(ip, i*64+20) << 52;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*25+ 8) = (uint64_t)IPW(ip, i*64+20) >> 12;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*25+ 8) |= (uint64_t)IPV(ip, i*64+21) << 13;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*25+ 8) |= (uint64_t)IPV(ip, i*64+22) << 38 | (uint64_t)IPX(ip, i*64+23) << 63;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*25+ 9) = (uint64_t)IPW(ip, i*64+23) >> 1;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*25+ 9) |= (uint64_t)IPV(ip, i*64+24) << 24 | (uint64_t)IPX(ip, i*64+25) << 49;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*25+10) = (uint64_t)IPW(ip, i*64+25) >> 15;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*25+10) |= (uint64_t)IPV(ip, i*64+26) << 10;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*25+10) |= (uint64_t)IPV(ip, i*64+27) << 35 | (uint64_t)IPX(ip, i*64+28) << 60;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*25+11) = (uint64_t)IPW(ip, i*64+28) >> 4;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*25+11) |= (uint64_t)IPV(ip, i*64+29) << 21 | (uint64_t)IPX(ip, i*64+30) << 46;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*25+12) = (uint64_t)IPW(ip, i*64+30) >> 18;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*25+12) |= (uint64_t)IPV(ip, i*64+31) << 7;\ +} + +#define BITPACK64_25(ip, op, parm) { \ + BITBLK64_25(ip, 0, op, parm); IPI(ip); op += 25*4/sizeof(op[0]);\ +} + +#define BITBLK64_26(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*13+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*13+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 26 | (uint64_t)IPX(ip, i*32+2) << 52;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*13+ 1) = (uint64_t)IPW(ip, i*32+ 2) >> 12;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*13+ 1) |= (uint64_t)IPV(ip, i*32+ 3) << 14 | (uint64_t)IPX(ip, i*32+4) << 40;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*13+ 2) = (uint64_t)IPW(ip, i*32+ 4) >> 24;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*32+ 5) << 2;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*13+ 2) |= (uint64_t)IPV(ip, i*32+ 6) << 28 | (uint64_t)IPX(ip, i*32+7) << 54;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*13+ 3) = (uint64_t)IPW(ip, i*32+ 7) >> 10;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*13+ 3) |= (uint64_t)IPV(ip, i*32+ 8) << 16 | (uint64_t)IPX(ip, i*32+9) << 42;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*13+ 4) = (uint64_t)IPW(ip, i*32+ 9) >> 22;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*32+10) << 4;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*32+11) << 30 | (uint64_t)IPX(ip, i*32+12) << 56;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*13+ 5) = (uint64_t)IPW(ip, i*32+12) >> 8;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*13+ 5) |= (uint64_t)IPV(ip, i*32+13) << 18 | (uint64_t)IPX(ip, i*32+14) << 44;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*13+ 6) = (uint64_t)IPW(ip, i*32+14) >> 20;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*13+ 6) |= (uint64_t)IPV(ip, i*32+15) << 6;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*13+ 6) |= (uint64_t)IPV(ip, i*32+16) << 32 | (uint64_t)IPX(ip, i*32+17) << 58;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*13+ 7) = (uint64_t)IPW(ip, i*32+17) >> 6;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*13+ 7) |= (uint64_t)IPV(ip, i*32+18) << 20 | (uint64_t)IPX(ip, i*32+19) << 46;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*13+ 8) = (uint64_t)IPW(ip, i*32+19) >> 18;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*13+ 8) |= (uint64_t)IPV(ip, i*32+20) << 8;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*13+ 8) |= (uint64_t)IPV(ip, i*32+21) << 34 | (uint64_t)IPX(ip, i*32+22) << 60;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*13+ 9) = (uint64_t)IPW(ip, i*32+22) >> 4;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*13+ 9) |= (uint64_t)IPV(ip, i*32+23) << 22 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*13+10) = (uint64_t)IPW(ip, i*32+24) >> 16;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*13+10) |= (uint64_t)IPV(ip, i*32+25) << 10;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*13+10) |= (uint64_t)IPV(ip, i*32+26) << 36 | (uint64_t)IPX(ip, i*32+27) << 62;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*13+11) = (uint64_t)IPW(ip, i*32+27) >> 2;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*13+11) |= (uint64_t)IPV(ip, i*32+28) << 24 | (uint64_t)IPX(ip, i*32+29) << 50;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*13+12) = (uint64_t)IPW(ip, i*32+29) >> 14;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*13+12) |= (uint64_t)IPV(ip, i*32+30) << 12;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*13+12) |= (uint64_t)IPV(ip, i*32+31) << 38;\ +} + +#define BITPACK64_26(ip, op, parm) { \ + BITBLK64_26(ip, 0, op, parm); IPI(ip); op += 26*4/sizeof(op[0]);\ +} + +#define BITBLK64_27(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*27+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*27+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 27 | (uint64_t)IPX(ip, i*64+2) << 54;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*27+ 1) = (uint64_t)IPW(ip, i*64+ 2) >> 10;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*27+ 1) |= (uint64_t)IPV(ip, i*64+ 3) << 17 | (uint64_t)IPX(ip, i*64+4) << 44;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*27+ 2) = (uint64_t)IPW(ip, i*64+ 4) >> 20;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*27+ 2) |= (uint64_t)IPV(ip, i*64+ 5) << 7;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*27+ 2) |= (uint64_t)IPV(ip, i*64+ 6) << 34 | (uint64_t)IPX(ip, i*64+7) << 61;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*27+ 3) = (uint64_t)IPW(ip, i*64+ 7) >> 3;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*27+ 3) |= (uint64_t)IPV(ip, i*64+ 8) << 24 | (uint64_t)IPX(ip, i*64+9) << 51;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*27+ 4) = (uint64_t)IPW(ip, i*64+ 9) >> 13;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*27+ 4) |= (uint64_t)IPV(ip, i*64+10) << 14 | (uint64_t)IPX(ip, i*64+11) << 41;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*27+ 5) = (uint64_t)IPW(ip, i*64+11) >> 23;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*27+ 5) |= (uint64_t)IPV(ip, i*64+12) << 4;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*27+ 5) |= (uint64_t)IPV(ip, i*64+13) << 31 | (uint64_t)IPX(ip, i*64+14) << 58;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*27+ 6) = (uint64_t)IPW(ip, i*64+14) >> 6;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*27+ 6) |= (uint64_t)IPV(ip, i*64+15) << 21 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*27+ 7) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*27+ 7) |= (uint64_t)IPV(ip, i*64+17) << 11 | (uint64_t)IPX(ip, i*64+18) << 38;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*27+ 8) = (uint64_t)IPW(ip, i*64+18) >> 26;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*27+ 8) |= (uint64_t)IPV(ip, i*64+19) << 1;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*27+ 8) |= (uint64_t)IPV(ip, i*64+20) << 28 | (uint64_t)IPX(ip, i*64+21) << 55;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*27+ 9) = (uint64_t)IPW(ip, i*64+21) >> 9;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*27+ 9) |= (uint64_t)IPV(ip, i*64+22) << 18 | (uint64_t)IPX(ip, i*64+23) << 45;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*27+10) = (uint64_t)IPW(ip, i*64+23) >> 19;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*27+10) |= (uint64_t)IPV(ip, i*64+24) << 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*27+10) |= (uint64_t)IPV(ip, i*64+25) << 35 | (uint64_t)IPX(ip, i*64+26) << 62;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*27+11) = (uint64_t)IPW(ip, i*64+26) >> 2;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*27+11) |= (uint64_t)IPV(ip, i*64+27) << 25 | (uint64_t)IPX(ip, i*64+28) << 52;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*27+12) = (uint64_t)IPW(ip, i*64+28) >> 12;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*27+12) |= (uint64_t)IPV(ip, i*64+29) << 15 | (uint64_t)IPX(ip, i*64+30) << 42;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*27+13) = (uint64_t)IPW(ip, i*64+30) >> 22;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*27+13) |= (uint64_t)IPV(ip, i*64+31) << 5;\ +} + +#define BITPACK64_27(ip, op, parm) { \ + BITBLK64_27(ip, 0, op, parm); IPI(ip); op += 27*4/sizeof(op[0]);\ +} + +#define BITBLK64_28(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*7+ 0) = (uint64_t)IPV(ip, i*16+ 0) ;\ + IP9(ip, i*16+ 1, parm); *((uint64_t *)op+i*7+ 0) |= (uint64_t)IPV(ip, i*16+ 1) << 28 | (uint64_t)IPX(ip, i*16+2) << 56;\ + IP64(ip, i*16+ 2, parm); *((uint64_t *)op+i*7+ 1) = (uint64_t)IPW(ip, i*16+ 2) >> 8;\ + IP9(ip, i*16+ 3, parm); *((uint64_t *)op+i*7+ 1) |= (uint64_t)IPV(ip, i*16+ 3) << 20 | (uint64_t)IPX(ip, i*16+4) << 48;\ + IP64(ip, i*16+ 4, parm); *((uint64_t *)op+i*7+ 2) = (uint64_t)IPW(ip, i*16+ 4) >> 16;\ + IP9(ip, i*16+ 5, parm); *((uint64_t *)op+i*7+ 2) |= (uint64_t)IPV(ip, i*16+ 5) << 12 | (uint64_t)IPX(ip, i*16+6) << 40;\ + IP64(ip, i*16+ 6, parm); *((uint64_t *)op+i*7+ 3) = (uint64_t)IPW(ip, i*16+ 6) >> 24;\ + IP9(ip, i*16+ 7, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*16+ 7) << 4;\ + IP9(ip, i*16+ 8, parm); *((uint64_t *)op+i*7+ 3) |= (uint64_t)IPV(ip, i*16+ 8) << 32 | (uint64_t)IPX(ip, i*16+9) << 60;\ + IP64(ip, i*16+ 9, parm); *((uint64_t *)op+i*7+ 4) = (uint64_t)IPW(ip, i*16+ 9) >> 4;\ + IP9(ip, i*16+10, parm); *((uint64_t *)op+i*7+ 4) |= (uint64_t)IPV(ip, i*16+10) << 24 | (uint64_t)IPX(ip, i*16+11) << 52;\ + IP64(ip, i*16+11, parm); *((uint64_t *)op+i*7+ 5) = (uint64_t)IPW(ip, i*16+11) >> 12;\ + IP9(ip, i*16+12, parm); *((uint64_t *)op+i*7+ 5) |= (uint64_t)IPV(ip, i*16+12) << 16 | (uint64_t)IPX(ip, i*16+13) << 44;\ + IP64(ip, i*16+13, parm); *((uint64_t *)op+i*7+ 6) = (uint64_t)IPW(ip, i*16+13) >> 20;\ + IP9(ip, i*16+14, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*16+14) << 8;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*16+15) << 36;\ +} + +#define BITPACK64_28(ip, op, parm) { \ + BITBLK64_28(ip, 0, op, parm);\ + BITBLK64_28(ip, 1, op, parm); IPI(ip); op += 28*4/sizeof(op[0]);\ +} + +#define BITBLK64_29(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*29+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*29+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 29 | (uint64_t)IPX(ip, i*64+2) << 58;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*29+ 1) = (uint64_t)IPW(ip, i*64+ 2) >> 6;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*29+ 1) |= (uint64_t)IPV(ip, i*64+ 3) << 23 | (uint64_t)IPX(ip, i*64+4) << 52;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*29+ 2) = (uint64_t)IPW(ip, i*64+ 4) >> 12;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*29+ 2) |= (uint64_t)IPV(ip, i*64+ 5) << 17 | (uint64_t)IPX(ip, i*64+6) << 46;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*29+ 3) = (uint64_t)IPW(ip, i*64+ 6) >> 18;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*29+ 3) |= (uint64_t)IPV(ip, i*64+ 7) << 11 | (uint64_t)IPX(ip, i*64+8) << 40;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*29+ 4) = (uint64_t)IPW(ip, i*64+ 8) >> 24;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*29+ 4) |= (uint64_t)IPV(ip, i*64+ 9) << 5;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*29+ 4) |= (uint64_t)IPV(ip, i*64+10) << 34 | (uint64_t)IPX(ip, i*64+11) << 63;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*29+ 5) = (uint64_t)IPW(ip, i*64+11) >> 1;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*29+ 5) |= (uint64_t)IPV(ip, i*64+12) << 28 | (uint64_t)IPX(ip, i*64+13) << 57;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*29+ 6) = (uint64_t)IPW(ip, i*64+13) >> 7;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*29+ 6) |= (uint64_t)IPV(ip, i*64+14) << 22 | (uint64_t)IPX(ip, i*64+15) << 51;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*29+ 7) = (uint64_t)IPW(ip, i*64+15) >> 13;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*29+ 7) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 45;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*29+ 8) = (uint64_t)IPW(ip, i*64+17) >> 19;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*29+ 8) |= (uint64_t)IPV(ip, i*64+18) << 10 | (uint64_t)IPX(ip, i*64+19) << 39;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*29+ 9) = (uint64_t)IPW(ip, i*64+19) >> 25;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*29+ 9) |= (uint64_t)IPV(ip, i*64+20) << 4;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*29+ 9) |= (uint64_t)IPV(ip, i*64+21) << 33 | (uint64_t)IPX(ip, i*64+22) << 62;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*29+10) = (uint64_t)IPW(ip, i*64+22) >> 2;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*29+10) |= (uint64_t)IPV(ip, i*64+23) << 27 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*29+11) = (uint64_t)IPW(ip, i*64+24) >> 8;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*29+11) |= (uint64_t)IPV(ip, i*64+25) << 21 | (uint64_t)IPX(ip, i*64+26) << 50;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*29+12) = (uint64_t)IPW(ip, i*64+26) >> 14;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*29+12) |= (uint64_t)IPV(ip, i*64+27) << 15 | (uint64_t)IPX(ip, i*64+28) << 44;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*29+13) = (uint64_t)IPW(ip, i*64+28) >> 20;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*29+13) |= (uint64_t)IPV(ip, i*64+29) << 9 | (uint64_t)IPX(ip, i*64+30) << 38;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*29+14) = (uint64_t)IPW(ip, i*64+30) >> 26;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*29+14) |= (uint64_t)IPV(ip, i*64+31) << 3;\ +} + +#define BITPACK64_29(ip, op, parm) { \ + BITBLK64_29(ip, 0, op, parm); IPI(ip); op += 29*4/sizeof(op[0]);\ +} + +#define BITBLK64_30(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*15+ 0) = (uint64_t)IPV(ip, i*32+ 0) ;\ + IP9(ip, i*32+ 1, parm); *((uint64_t *)op+i*15+ 0) |= (uint64_t)IPV(ip, i*32+ 1) << 30 | (uint64_t)IPX(ip, i*32+2) << 60;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*15+ 1) = (uint64_t)IPW(ip, i*32+ 2) >> 4;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*15+ 1) |= (uint64_t)IPV(ip, i*32+ 3) << 26 | (uint64_t)IPX(ip, i*32+4) << 56;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*15+ 2) = (uint64_t)IPW(ip, i*32+ 4) >> 8;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*15+ 2) |= (uint64_t)IPV(ip, i*32+ 5) << 22 | (uint64_t)IPX(ip, i*32+6) << 52;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*15+ 3) = (uint64_t)IPW(ip, i*32+ 6) >> 12;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*15+ 3) |= (uint64_t)IPV(ip, i*32+ 7) << 18 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*15+ 4) = (uint64_t)IPW(ip, i*32+ 8) >> 16;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*15+ 4) |= (uint64_t)IPV(ip, i*32+ 9) << 14 | (uint64_t)IPX(ip, i*32+10) << 44;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*15+ 5) = (uint64_t)IPW(ip, i*32+10) >> 20;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*15+ 5) |= (uint64_t)IPV(ip, i*32+11) << 10 | (uint64_t)IPX(ip, i*32+12) << 40;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*15+ 6) = (uint64_t)IPW(ip, i*32+12) >> 24;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*15+ 6) |= (uint64_t)IPV(ip, i*32+13) << 6 | (uint64_t)IPX(ip, i*32+14) << 36;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*15+ 7) = (uint64_t)IPW(ip, i*32+14) >> 28;\ + IP9(ip, i*32+15, parm); *((uint64_t *)op+i*15+ 7) |= (uint64_t)IPV(ip, i*32+15) << 2;\ + IP9(ip, i*32+16, parm); *((uint64_t *)op+i*15+ 7) |= (uint64_t)IPV(ip, i*32+16) << 32 | (uint64_t)IPX(ip, i*32+17) << 62;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*15+ 8) = (uint64_t)IPW(ip, i*32+17) >> 2;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*15+ 8) |= (uint64_t)IPV(ip, i*32+18) << 28 | (uint64_t)IPX(ip, i*32+19) << 58;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*15+ 9) = (uint64_t)IPW(ip, i*32+19) >> 6;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*15+ 9) |= (uint64_t)IPV(ip, i*32+20) << 24 | (uint64_t)IPX(ip, i*32+21) << 54;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*15+10) = (uint64_t)IPW(ip, i*32+21) >> 10;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*15+10) |= (uint64_t)IPV(ip, i*32+22) << 20 | (uint64_t)IPX(ip, i*32+23) << 50;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*15+11) = (uint64_t)IPW(ip, i*32+23) >> 14;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*15+11) |= (uint64_t)IPV(ip, i*32+24) << 16 | (uint64_t)IPX(ip, i*32+25) << 46;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*15+12) = (uint64_t)IPW(ip, i*32+25) >> 18;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*15+12) |= (uint64_t)IPV(ip, i*32+26) << 12 | (uint64_t)IPX(ip, i*32+27) << 42;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*15+13) = (uint64_t)IPW(ip, i*32+27) >> 22;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*15+13) |= (uint64_t)IPV(ip, i*32+28) << 8 | (uint64_t)IPX(ip, i*32+29) << 38;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*15+14) = (uint64_t)IPW(ip, i*32+29) >> 26;\ + IP9(ip, i*32+30, parm); *((uint64_t *)op+i*15+14) |= (uint64_t)IPV(ip, i*32+30) << 4;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*15+14) |= (uint64_t)IPV(ip, i*32+31) << 34;\ +} + +#define BITPACK64_30(ip, op, parm) { \ + BITBLK64_30(ip, 0, op, parm); IPI(ip); op += 30*4/sizeof(op[0]);\ +} + +#define BITBLK64_31(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*31+ 0) = (uint64_t)IPV(ip, i*64+ 0) ;\ + IP9(ip, i*64+ 1, parm); *((uint64_t *)op+i*31+ 0) |= (uint64_t)IPV(ip, i*64+ 1) << 31 | (uint64_t)IPX(ip, i*64+2) << 62;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*31+ 1) = (uint64_t)IPW(ip, i*64+ 2) >> 2;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*31+ 1) |= (uint64_t)IPV(ip, i*64+ 3) << 29 | (uint64_t)IPX(ip, i*64+4) << 60;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*31+ 2) = (uint64_t)IPW(ip, i*64+ 4) >> 4;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*31+ 2) |= (uint64_t)IPV(ip, i*64+ 5) << 27 | (uint64_t)IPX(ip, i*64+6) << 58;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*31+ 3) = (uint64_t)IPW(ip, i*64+ 6) >> 6;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*31+ 3) |= (uint64_t)IPV(ip, i*64+ 7) << 25 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*31+ 4) = (uint64_t)IPW(ip, i*64+ 8) >> 8;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*31+ 4) |= (uint64_t)IPV(ip, i*64+ 9) << 23 | (uint64_t)IPX(ip, i*64+10) << 54;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*31+ 5) = (uint64_t)IPW(ip, i*64+10) >> 10;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*31+ 5) |= (uint64_t)IPV(ip, i*64+11) << 21 | (uint64_t)IPX(ip, i*64+12) << 52;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*31+ 6) = (uint64_t)IPW(ip, i*64+12) >> 12;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*31+ 6) |= (uint64_t)IPV(ip, i*64+13) << 19 | (uint64_t)IPX(ip, i*64+14) << 50;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*31+ 7) = (uint64_t)IPW(ip, i*64+14) >> 14;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*31+ 7) |= (uint64_t)IPV(ip, i*64+15) << 17 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*31+ 8) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*31+ 8) |= (uint64_t)IPV(ip, i*64+17) << 15 | (uint64_t)IPX(ip, i*64+18) << 46;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*31+ 9) = (uint64_t)IPW(ip, i*64+18) >> 18;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*31+ 9) |= (uint64_t)IPV(ip, i*64+19) << 13 | (uint64_t)IPX(ip, i*64+20) << 44;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*31+10) = (uint64_t)IPW(ip, i*64+20) >> 20;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*31+10) |= (uint64_t)IPV(ip, i*64+21) << 11 | (uint64_t)IPX(ip, i*64+22) << 42;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*31+11) = (uint64_t)IPW(ip, i*64+22) >> 22;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*31+11) |= (uint64_t)IPV(ip, i*64+23) << 9 | (uint64_t)IPX(ip, i*64+24) << 40;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*31+12) = (uint64_t)IPW(ip, i*64+24) >> 24;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*31+12) |= (uint64_t)IPV(ip, i*64+25) << 7 | (uint64_t)IPX(ip, i*64+26) << 38;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*31+13) = (uint64_t)IPW(ip, i*64+26) >> 26;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*31+13) |= (uint64_t)IPV(ip, i*64+27) << 5 | (uint64_t)IPX(ip, i*64+28) << 36;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*31+14) = (uint64_t)IPW(ip, i*64+28) >> 28;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*31+14) |= (uint64_t)IPV(ip, i*64+29) << 3 | (uint64_t)IPX(ip, i*64+30) << 34;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*31+15) = (uint64_t)IPW(ip, i*64+30) >> 30;\ + IP9(ip, i*64+31, parm); *((uint64_t *)op+i*31+15) |= (uint64_t)IPV(ip, i*64+31) << 1;\ +} + +#define BITPACK64_31(ip, op, parm) { \ + BITBLK64_31(ip, 0, op, parm); IPI(ip); op += 31*4/sizeof(op[0]);\ +} + +#define BITBLK64_32(ip, i, op, parm) { \ + IP9(ip, i*2+ 0, parm); *(uint32_t *)(op+i*8+ 0) = IPV(ip, i*2+ 0);\ + IP9(ip, i*2+ 1, parm); *(uint32_t *)(op+i*8+ 4) = IPV(ip, i*2+ 1);;\ +} + +#define BITPACK64_32(ip, op, parm) { \ + BITBLK64_32(ip, 0, op, parm);\ + BITBLK64_32(ip, 1, op, parm);\ + BITBLK64_32(ip, 2, op, parm);\ + BITBLK64_32(ip, 3, op, parm);\ + BITBLK64_32(ip, 4, op, parm);\ + BITBLK64_32(ip, 5, op, parm);\ + BITBLK64_32(ip, 6, op, parm);\ + BITBLK64_32(ip, 7, op, parm);\ + BITBLK64_32(ip, 8, op, parm);\ + BITBLK64_32(ip, 9, op, parm);\ + BITBLK64_32(ip, 10, op, parm);\ + BITBLK64_32(ip, 11, op, parm);\ + BITBLK64_32(ip, 12, op, parm);\ + BITBLK64_32(ip, 13, op, parm);\ + BITBLK64_32(ip, 14, op, parm);\ + BITBLK64_32(ip, 15, op, parm); IPI(ip); op += 32*4/sizeof(op[0]);\ +} + +#define BITBLK64_33(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*33+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 33;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*33+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 31;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*33+ 1) |= (uint64_t)IPV(ip, i*64+ 2) << 2 | (uint64_t)IPX(ip, i*64+3) << 35;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*33+ 2) = (uint64_t)IPW(ip, i*64+ 3) >> 29;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*33+ 2) |= (uint64_t)IPV(ip, i*64+ 4) << 4 | (uint64_t)IPX(ip, i*64+5) << 37;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*33+ 3) = (uint64_t)IPW(ip, i*64+ 5) >> 27;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*33+ 3) |= (uint64_t)IPV(ip, i*64+ 6) << 6 | (uint64_t)IPX(ip, i*64+7) << 39;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*33+ 4) = (uint64_t)IPW(ip, i*64+ 7) >> 25;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*33+ 4) |= (uint64_t)IPV(ip, i*64+ 8) << 8 | (uint64_t)IPX(ip, i*64+9) << 41;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*33+ 5) = (uint64_t)IPW(ip, i*64+ 9) >> 23;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*33+ 5) |= (uint64_t)IPV(ip, i*64+10) << 10 | (uint64_t)IPX(ip, i*64+11) << 43;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*33+ 6) = (uint64_t)IPW(ip, i*64+11) >> 21;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*33+ 6) |= (uint64_t)IPV(ip, i*64+12) << 12 | (uint64_t)IPX(ip, i*64+13) << 45;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*33+ 7) = (uint64_t)IPW(ip, i*64+13) >> 19;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*33+ 7) |= (uint64_t)IPV(ip, i*64+14) << 14 | (uint64_t)IPX(ip, i*64+15) << 47;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*33+ 8) = (uint64_t)IPW(ip, i*64+15) >> 17;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*33+ 8) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 49;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*33+ 9) = (uint64_t)IPW(ip, i*64+17) >> 15;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*33+ 9) |= (uint64_t)IPV(ip, i*64+18) << 18 | (uint64_t)IPX(ip, i*64+19) << 51;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*33+10) = (uint64_t)IPW(ip, i*64+19) >> 13;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*33+10) |= (uint64_t)IPV(ip, i*64+20) << 20 | (uint64_t)IPX(ip, i*64+21) << 53;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*33+11) = (uint64_t)IPW(ip, i*64+21) >> 11;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*33+11) |= (uint64_t)IPV(ip, i*64+22) << 22 | (uint64_t)IPX(ip, i*64+23) << 55;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*33+12) = (uint64_t)IPW(ip, i*64+23) >> 9;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*33+12) |= (uint64_t)IPV(ip, i*64+24) << 24 | (uint64_t)IPX(ip, i*64+25) << 57;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*33+13) = (uint64_t)IPW(ip, i*64+25) >> 7;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*33+13) |= (uint64_t)IPV(ip, i*64+26) << 26 | (uint64_t)IPX(ip, i*64+27) << 59;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*33+14) = (uint64_t)IPW(ip, i*64+27) >> 5;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*33+14) |= (uint64_t)IPV(ip, i*64+28) << 28 | (uint64_t)IPX(ip, i*64+29) << 61;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*33+15) = (uint64_t)IPW(ip, i*64+29) >> 3;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*33+15) |= (uint64_t)IPV(ip, i*64+30) << 30 | (uint64_t)IPX(ip, i*64+31) << 63;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*33+16) = (uint64_t)IPW(ip, i*64+31) >> 1;\ +} + +#define BITPACK64_33(ip, op, parm) { \ + BITBLK64_33(ip, 0, op, parm); IPI(ip); op += 33*4/sizeof(op[0]);\ +} + +#define BITBLK64_34(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*17+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 34;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*17+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 30;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*17+ 1) |= (uint64_t)IPV(ip, i*32+ 2) << 4 | (uint64_t)IPX(ip, i*32+3) << 38;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*17+ 2) = (uint64_t)IPW(ip, i*32+ 3) >> 26;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*17+ 2) |= (uint64_t)IPV(ip, i*32+ 4) << 8 | (uint64_t)IPX(ip, i*32+5) << 42;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*17+ 3) = (uint64_t)IPW(ip, i*32+ 5) >> 22;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*17+ 3) |= (uint64_t)IPV(ip, i*32+ 6) << 12 | (uint64_t)IPX(ip, i*32+7) << 46;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*17+ 4) = (uint64_t)IPW(ip, i*32+ 7) >> 18;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*17+ 4) |= (uint64_t)IPV(ip, i*32+ 8) << 16 | (uint64_t)IPX(ip, i*32+9) << 50;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*17+ 5) = (uint64_t)IPW(ip, i*32+ 9) >> 14;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*17+ 5) |= (uint64_t)IPV(ip, i*32+10) << 20 | (uint64_t)IPX(ip, i*32+11) << 54;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*17+ 6) = (uint64_t)IPW(ip, i*32+11) >> 10;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*17+ 6) |= (uint64_t)IPV(ip, i*32+12) << 24 | (uint64_t)IPX(ip, i*32+13) << 58;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*17+ 7) = (uint64_t)IPW(ip, i*32+13) >> 6;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*17+ 7) |= (uint64_t)IPV(ip, i*32+14) << 28 | (uint64_t)IPX(ip, i*32+15) << 62;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*17+ 8) = (uint64_t)IPW(ip, i*32+15) >> 2 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*17+ 9) = (uint64_t)IPW(ip, i*32+16) >> 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*17+ 9) |= (uint64_t)IPV(ip, i*32+17) << 2 | (uint64_t)IPX(ip, i*32+18) << 36;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*17+10) = (uint64_t)IPW(ip, i*32+18) >> 28;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*17+10) |= (uint64_t)IPV(ip, i*32+19) << 6 | (uint64_t)IPX(ip, i*32+20) << 40;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*17+11) = (uint64_t)IPW(ip, i*32+20) >> 24;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*17+11) |= (uint64_t)IPV(ip, i*32+21) << 10 | (uint64_t)IPX(ip, i*32+22) << 44;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*17+12) = (uint64_t)IPW(ip, i*32+22) >> 20;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*17+12) |= (uint64_t)IPV(ip, i*32+23) << 14 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*17+13) = (uint64_t)IPW(ip, i*32+24) >> 16;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*17+13) |= (uint64_t)IPV(ip, i*32+25) << 18 | (uint64_t)IPX(ip, i*32+26) << 52;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*17+14) = (uint64_t)IPW(ip, i*32+26) >> 12;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*17+14) |= (uint64_t)IPV(ip, i*32+27) << 22 | (uint64_t)IPX(ip, i*32+28) << 56;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*17+15) = (uint64_t)IPW(ip, i*32+28) >> 8;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*17+15) |= (uint64_t)IPV(ip, i*32+29) << 26 | (uint64_t)IPX(ip, i*32+30) << 60;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*17+16) = (uint64_t)IPW(ip, i*32+30) >> 4;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*17+16) |= (uint64_t)IPV(ip, i*32+31) << 30;\ +} + +#define BITPACK64_34(ip, op, parm) { \ + BITBLK64_34(ip, 0, op, parm); IPI(ip); op += 34*4/sizeof(op[0]);\ +} + +#define BITBLK64_35(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*35+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 35;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*35+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 29;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*35+ 1) |= (uint64_t)IPV(ip, i*64+ 2) << 6 | (uint64_t)IPX(ip, i*64+3) << 41;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*35+ 2) = (uint64_t)IPW(ip, i*64+ 3) >> 23;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*35+ 2) |= (uint64_t)IPV(ip, i*64+ 4) << 12 | (uint64_t)IPX(ip, i*64+5) << 47;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*35+ 3) = (uint64_t)IPW(ip, i*64+ 5) >> 17;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*35+ 3) |= (uint64_t)IPV(ip, i*64+ 6) << 18 | (uint64_t)IPX(ip, i*64+7) << 53;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*35+ 4) = (uint64_t)IPW(ip, i*64+ 7) >> 11;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*35+ 4) |= (uint64_t)IPV(ip, i*64+ 8) << 24 | (uint64_t)IPX(ip, i*64+9) << 59;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*35+ 5) = (uint64_t)IPW(ip, i*64+ 9) >> 5 | (uint64_t)IPX(ip, i*64+10) << 30;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*35+ 6) = (uint64_t)IPW(ip, i*64+10) >> 34;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*35+ 6) |= (uint64_t)IPV(ip, i*64+11) << 1 | (uint64_t)IPX(ip, i*64+12) << 36;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*35+ 7) = (uint64_t)IPW(ip, i*64+12) >> 28;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*35+ 7) |= (uint64_t)IPV(ip, i*64+13) << 7 | (uint64_t)IPX(ip, i*64+14) << 42;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*35+ 8) = (uint64_t)IPW(ip, i*64+14) >> 22;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*35+ 8) |= (uint64_t)IPV(ip, i*64+15) << 13 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*35+ 9) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*35+ 9) |= (uint64_t)IPV(ip, i*64+17) << 19 | (uint64_t)IPX(ip, i*64+18) << 54;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*35+10) = (uint64_t)IPW(ip, i*64+18) >> 10;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*35+10) |= (uint64_t)IPV(ip, i*64+19) << 25 | (uint64_t)IPX(ip, i*64+20) << 60;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*35+11) = (uint64_t)IPW(ip, i*64+20) >> 4 | (uint64_t)IPX(ip, i*64+21) << 31;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*35+12) = (uint64_t)IPW(ip, i*64+21) >> 33;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*35+12) |= (uint64_t)IPV(ip, i*64+22) << 2 | (uint64_t)IPX(ip, i*64+23) << 37;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*35+13) = (uint64_t)IPW(ip, i*64+23) >> 27;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*35+13) |= (uint64_t)IPV(ip, i*64+24) << 8 | (uint64_t)IPX(ip, i*64+25) << 43;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*35+14) = (uint64_t)IPW(ip, i*64+25) >> 21;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*35+14) |= (uint64_t)IPV(ip, i*64+26) << 14 | (uint64_t)IPX(ip, i*64+27) << 49;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*35+15) = (uint64_t)IPW(ip, i*64+27) >> 15;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*35+15) |= (uint64_t)IPV(ip, i*64+28) << 20 | (uint64_t)IPX(ip, i*64+29) << 55;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*35+16) = (uint64_t)IPW(ip, i*64+29) >> 9;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*35+16) |= (uint64_t)IPV(ip, i*64+30) << 26 | (uint64_t)IPX(ip, i*64+31) << 61;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*35+17) = (uint64_t)IPW(ip, i*64+31) >> 3;\ +} + +#define BITPACK64_35(ip, op, parm) { \ + BITBLK64_35(ip, 0, op, parm); IPI(ip); op += 35*4/sizeof(op[0]);\ +} + +#define BITBLK64_36(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*9+ 0) = (uint64_t)IPV(ip, i*16+ 0) | (uint64_t)IPX(ip, i*16+1) << 36;\ + IP64(ip, i*16+ 1, parm); *((uint64_t *)op+i*9+ 1) = (uint64_t)IPW(ip, i*16+ 1) >> 28;\ + IP9(ip, i*16+ 2, parm); *((uint64_t *)op+i*9+ 1) |= (uint64_t)IPV(ip, i*16+ 2) << 8 | (uint64_t)IPX(ip, i*16+3) << 44;\ + IP64(ip, i*16+ 3, parm); *((uint64_t *)op+i*9+ 2) = (uint64_t)IPW(ip, i*16+ 3) >> 20;\ + IP9(ip, i*16+ 4, parm); *((uint64_t *)op+i*9+ 2) |= (uint64_t)IPV(ip, i*16+ 4) << 16 | (uint64_t)IPX(ip, i*16+5) << 52;\ + IP64(ip, i*16+ 5, parm); *((uint64_t *)op+i*9+ 3) = (uint64_t)IPW(ip, i*16+ 5) >> 12;\ + IP9(ip, i*16+ 6, parm); *((uint64_t *)op+i*9+ 3) |= (uint64_t)IPV(ip, i*16+ 6) << 24 | (uint64_t)IPX(ip, i*16+7) << 60;\ + IP64(ip, i*16+ 7, parm); *((uint64_t *)op+i*9+ 4) = (uint64_t)IPW(ip, i*16+ 7) >> 4 | (uint64_t)IPX(ip, i*16+8) << 32;\ + IP64(ip, i*16+ 8, parm); *((uint64_t *)op+i*9+ 5) = (uint64_t)IPW(ip, i*16+ 8) >> 32;\ + IP9(ip, i*16+ 9, parm); *((uint64_t *)op+i*9+ 5) |= (uint64_t)IPV(ip, i*16+ 9) << 4 | (uint64_t)IPX(ip, i*16+10) << 40;\ + IP64(ip, i*16+10, parm); *((uint64_t *)op+i*9+ 6) = (uint64_t)IPW(ip, i*16+10) >> 24;\ + IP9(ip, i*16+11, parm); *((uint64_t *)op+i*9+ 6) |= (uint64_t)IPV(ip, i*16+11) << 12 | (uint64_t)IPX(ip, i*16+12) << 48;\ + IP64(ip, i*16+12, parm); *((uint64_t *)op+i*9+ 7) = (uint64_t)IPW(ip, i*16+12) >> 16;\ + IP9(ip, i*16+13, parm); *((uint64_t *)op+i*9+ 7) |= (uint64_t)IPV(ip, i*16+13) << 20 | (uint64_t)IPX(ip, i*16+14) << 56;\ + IP64(ip, i*16+14, parm); *((uint64_t *)op+i*9+ 8) = (uint64_t)IPW(ip, i*16+14) >> 8;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*9+ 8) |= (uint64_t)IPV(ip, i*16+15) << 28;\ +} + +#define BITPACK64_36(ip, op, parm) { \ + BITBLK64_36(ip, 0, op, parm);\ + BITBLK64_36(ip, 1, op, parm); IPI(ip); op += 36*4/sizeof(op[0]);\ +} + +#define BITBLK64_37(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*37+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 37;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*37+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 27;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*37+ 1) |= (uint64_t)IPV(ip, i*64+ 2) << 10 | (uint64_t)IPX(ip, i*64+3) << 47;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*37+ 2) = (uint64_t)IPW(ip, i*64+ 3) >> 17;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*37+ 2) |= (uint64_t)IPV(ip, i*64+ 4) << 20 | (uint64_t)IPX(ip, i*64+5) << 57;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*37+ 3) = (uint64_t)IPW(ip, i*64+ 5) >> 7 | (uint64_t)IPX(ip, i*64+6) << 30;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*37+ 4) = (uint64_t)IPW(ip, i*64+ 6) >> 34;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*37+ 4) |= (uint64_t)IPV(ip, i*64+ 7) << 3 | (uint64_t)IPX(ip, i*64+8) << 40;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*37+ 5) = (uint64_t)IPW(ip, i*64+ 8) >> 24;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*37+ 5) |= (uint64_t)IPV(ip, i*64+ 9) << 13 | (uint64_t)IPX(ip, i*64+10) << 50;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*37+ 6) = (uint64_t)IPW(ip, i*64+10) >> 14;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*37+ 6) |= (uint64_t)IPV(ip, i*64+11) << 23 | (uint64_t)IPX(ip, i*64+12) << 60;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*37+ 7) = (uint64_t)IPW(ip, i*64+12) >> 4 | (uint64_t)IPX(ip, i*64+13) << 33;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*37+ 8) = (uint64_t)IPW(ip, i*64+13) >> 31;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*37+ 8) |= (uint64_t)IPV(ip, i*64+14) << 6 | (uint64_t)IPX(ip, i*64+15) << 43;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*37+ 9) = (uint64_t)IPW(ip, i*64+15) >> 21;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*37+ 9) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 53;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*37+10) = (uint64_t)IPW(ip, i*64+17) >> 11;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*37+10) |= (uint64_t)IPV(ip, i*64+18) << 26 | (uint64_t)IPX(ip, i*64+19) << 63;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*37+11) = (uint64_t)IPW(ip, i*64+19) >> 1 | (uint64_t)IPX(ip, i*64+20) << 36;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*37+12) = (uint64_t)IPW(ip, i*64+20) >> 28;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*37+12) |= (uint64_t)IPV(ip, i*64+21) << 9 | (uint64_t)IPX(ip, i*64+22) << 46;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*37+13) = (uint64_t)IPW(ip, i*64+22) >> 18;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*37+13) |= (uint64_t)IPV(ip, i*64+23) << 19 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*37+14) = (uint64_t)IPW(ip, i*64+24) >> 8 | (uint64_t)IPX(ip, i*64+25) << 29;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*37+15) = (uint64_t)IPW(ip, i*64+25) >> 35;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*37+15) |= (uint64_t)IPV(ip, i*64+26) << 2 | (uint64_t)IPX(ip, i*64+27) << 39;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*37+16) = (uint64_t)IPW(ip, i*64+27) >> 25;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*37+16) |= (uint64_t)IPV(ip, i*64+28) << 12 | (uint64_t)IPX(ip, i*64+29) << 49;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*37+17) = (uint64_t)IPW(ip, i*64+29) >> 15;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*37+17) |= (uint64_t)IPV(ip, i*64+30) << 22 | (uint64_t)IPX(ip, i*64+31) << 59;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*37+18) = (uint64_t)IPW(ip, i*64+31) >> 5;\ +} + +#define BITPACK64_37(ip, op, parm) { \ + BITBLK64_37(ip, 0, op, parm); IPI(ip); op += 37*4/sizeof(op[0]);\ +} + +#define BITBLK64_38(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*19+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 38;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*19+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 26;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*19+ 1) |= (uint64_t)IPV(ip, i*32+ 2) << 12 | (uint64_t)IPX(ip, i*32+3) << 50;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*19+ 2) = (uint64_t)IPW(ip, i*32+ 3) >> 14;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*19+ 2) |= (uint64_t)IPV(ip, i*32+ 4) << 24 | (uint64_t)IPX(ip, i*32+5) << 62;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*19+ 3) = (uint64_t)IPW(ip, i*32+ 5) >> 2 | (uint64_t)IPX(ip, i*32+6) << 36;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*19+ 4) = (uint64_t)IPW(ip, i*32+ 6) >> 28;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*19+ 4) |= (uint64_t)IPV(ip, i*32+ 7) << 10 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*19+ 5) = (uint64_t)IPW(ip, i*32+ 8) >> 16;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*19+ 5) |= (uint64_t)IPV(ip, i*32+ 9) << 22 | (uint64_t)IPX(ip, i*32+10) << 60;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*19+ 6) = (uint64_t)IPW(ip, i*32+10) >> 4 | (uint64_t)IPX(ip, i*32+11) << 34;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*19+ 7) = (uint64_t)IPW(ip, i*32+11) >> 30;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*19+ 7) |= (uint64_t)IPV(ip, i*32+12) << 8 | (uint64_t)IPX(ip, i*32+13) << 46;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*19+ 8) = (uint64_t)IPW(ip, i*32+13) >> 18;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*19+ 8) |= (uint64_t)IPV(ip, i*32+14) << 20 | (uint64_t)IPX(ip, i*32+15) << 58;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*19+ 9) = (uint64_t)IPW(ip, i*32+15) >> 6 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*19+10) = (uint64_t)IPW(ip, i*32+16) >> 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*19+10) |= (uint64_t)IPV(ip, i*32+17) << 6 | (uint64_t)IPX(ip, i*32+18) << 44;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*19+11) = (uint64_t)IPW(ip, i*32+18) >> 20;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*19+11) |= (uint64_t)IPV(ip, i*32+19) << 18 | (uint64_t)IPX(ip, i*32+20) << 56;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*19+12) = (uint64_t)IPW(ip, i*32+20) >> 8 | (uint64_t)IPX(ip, i*32+21) << 30;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*19+13) = (uint64_t)IPW(ip, i*32+21) >> 34;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*19+13) |= (uint64_t)IPV(ip, i*32+22) << 4 | (uint64_t)IPX(ip, i*32+23) << 42;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*19+14) = (uint64_t)IPW(ip, i*32+23) >> 22;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*19+14) |= (uint64_t)IPV(ip, i*32+24) << 16 | (uint64_t)IPX(ip, i*32+25) << 54;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*19+15) = (uint64_t)IPW(ip, i*32+25) >> 10 | (uint64_t)IPX(ip, i*32+26) << 28;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*19+16) = (uint64_t)IPW(ip, i*32+26) >> 36;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*19+16) |= (uint64_t)IPV(ip, i*32+27) << 2 | (uint64_t)IPX(ip, i*32+28) << 40;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*19+17) = (uint64_t)IPW(ip, i*32+28) >> 24;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*19+17) |= (uint64_t)IPV(ip, i*32+29) << 14 | (uint64_t)IPX(ip, i*32+30) << 52;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*19+18) = (uint64_t)IPW(ip, i*32+30) >> 12;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*19+18) |= (uint64_t)IPV(ip, i*32+31) << 26;\ +} + +#define BITPACK64_38(ip, op, parm) { \ + BITBLK64_38(ip, 0, op, parm); IPI(ip); op += 38*4/sizeof(op[0]);\ +} + +#define BITBLK64_39(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*39+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 39;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*39+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 25;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*39+ 1) |= (uint64_t)IPV(ip, i*64+ 2) << 14 | (uint64_t)IPX(ip, i*64+3) << 53;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*39+ 2) = (uint64_t)IPW(ip, i*64+ 3) >> 11 | (uint64_t)IPX(ip, i*64+4) << 28;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*39+ 3) = (uint64_t)IPW(ip, i*64+ 4) >> 36;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*39+ 3) |= (uint64_t)IPV(ip, i*64+ 5) << 3 | (uint64_t)IPX(ip, i*64+6) << 42;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*39+ 4) = (uint64_t)IPW(ip, i*64+ 6) >> 22;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*39+ 4) |= (uint64_t)IPV(ip, i*64+ 7) << 17 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*39+ 5) = (uint64_t)IPW(ip, i*64+ 8) >> 8 | (uint64_t)IPX(ip, i*64+9) << 31;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*39+ 6) = (uint64_t)IPW(ip, i*64+ 9) >> 33;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*39+ 6) |= (uint64_t)IPV(ip, i*64+10) << 6 | (uint64_t)IPX(ip, i*64+11) << 45;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*39+ 7) = (uint64_t)IPW(ip, i*64+11) >> 19;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*39+ 7) |= (uint64_t)IPV(ip, i*64+12) << 20 | (uint64_t)IPX(ip, i*64+13) << 59;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*39+ 8) = (uint64_t)IPW(ip, i*64+13) >> 5 | (uint64_t)IPX(ip, i*64+14) << 34;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*39+ 9) = (uint64_t)IPW(ip, i*64+14) >> 30;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*39+ 9) |= (uint64_t)IPV(ip, i*64+15) << 9 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*39+10) = (uint64_t)IPW(ip, i*64+16) >> 16;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*39+10) |= (uint64_t)IPV(ip, i*64+17) << 23 | (uint64_t)IPX(ip, i*64+18) << 62;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*39+11) = (uint64_t)IPW(ip, i*64+18) >> 2 | (uint64_t)IPX(ip, i*64+19) << 37;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*39+12) = (uint64_t)IPW(ip, i*64+19) >> 27;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*39+12) |= (uint64_t)IPV(ip, i*64+20) << 12 | (uint64_t)IPX(ip, i*64+21) << 51;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*39+13) = (uint64_t)IPW(ip, i*64+21) >> 13 | (uint64_t)IPX(ip, i*64+22) << 26;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*39+14) = (uint64_t)IPW(ip, i*64+22) >> 38;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*39+14) |= (uint64_t)IPV(ip, i*64+23) << 1 | (uint64_t)IPX(ip, i*64+24) << 40;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*39+15) = (uint64_t)IPW(ip, i*64+24) >> 24;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*39+15) |= (uint64_t)IPV(ip, i*64+25) << 15 | (uint64_t)IPX(ip, i*64+26) << 54;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*39+16) = (uint64_t)IPW(ip, i*64+26) >> 10 | (uint64_t)IPX(ip, i*64+27) << 29;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*39+17) = (uint64_t)IPW(ip, i*64+27) >> 35;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*39+17) |= (uint64_t)IPV(ip, i*64+28) << 4 | (uint64_t)IPX(ip, i*64+29) << 43;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*39+18) = (uint64_t)IPW(ip, i*64+29) >> 21;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*39+18) |= (uint64_t)IPV(ip, i*64+30) << 18 | (uint64_t)IPX(ip, i*64+31) << 57;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*39+19) = (uint64_t)IPW(ip, i*64+31) >> 7;\ +} + +#define BITPACK64_39(ip, op, parm) { \ + BITBLK64_39(ip, 0, op, parm); IPI(ip); op += 39*4/sizeof(op[0]);\ +} + +#define BITBLK64_40(ip, i, op, parm) { ;\ + IP9(ip, i*8+ 0, parm); *((uint64_t *)op+i*5+ 0) = (uint64_t)IPV(ip, i*8+ 0) | (uint64_t)IPX(ip, i*8+1) << 40;\ + IP64(ip, i*8+ 1, parm); *((uint64_t *)op+i*5+ 1) = (uint64_t)IPW(ip, i*8+ 1) >> 24;\ + IP9(ip, i*8+ 2, parm); *((uint64_t *)op+i*5+ 1) |= (uint64_t)IPV(ip, i*8+ 2) << 16 | (uint64_t)IPX(ip, i*8+3) << 56;\ + IP64(ip, i*8+ 3, parm); *((uint64_t *)op+i*5+ 2) = (uint64_t)IPW(ip, i*8+ 3) >> 8 | (uint64_t)IPX(ip, i*8+4) << 32;\ + IP64(ip, i*8+ 4, parm); *((uint64_t *)op+i*5+ 3) = (uint64_t)IPW(ip, i*8+ 4) >> 32;\ + IP9(ip, i*8+ 5, parm); *((uint64_t *)op+i*5+ 3) |= (uint64_t)IPV(ip, i*8+ 5) << 8 | (uint64_t)IPX(ip, i*8+6) << 48;\ + IP64(ip, i*8+ 6, parm); *((uint64_t *)op+i*5+ 4) = (uint64_t)IPW(ip, i*8+ 6) >> 16;\ + IP9(ip, i*8+ 7, parm); *((uint64_t *)op+i*5+ 4) |= (uint64_t)IPV(ip, i*8+ 7) << 24;\ +} + +#define BITPACK64_40(ip, op, parm) { \ + BITBLK64_40(ip, 0, op, parm);\ + BITBLK64_40(ip, 1, op, parm);\ + BITBLK64_40(ip, 2, op, parm);\ + BITBLK64_40(ip, 3, op, parm); IPI(ip); op += 40*4/sizeof(op[0]);\ +} + +#define BITBLK64_41(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*41+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 41;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*41+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 23;\ + IP9(ip, i*64+ 2, parm); *((uint64_t *)op+i*41+ 1) |= (uint64_t)IPV(ip, i*64+ 2) << 18 | (uint64_t)IPX(ip, i*64+3) << 59;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*41+ 2) = (uint64_t)IPW(ip, i*64+ 3) >> 5 | (uint64_t)IPX(ip, i*64+4) << 36;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*41+ 3) = (uint64_t)IPW(ip, i*64+ 4) >> 28;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*41+ 3) |= (uint64_t)IPV(ip, i*64+ 5) << 13 | (uint64_t)IPX(ip, i*64+6) << 54;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*41+ 4) = (uint64_t)IPW(ip, i*64+ 6) >> 10 | (uint64_t)IPX(ip, i*64+7) << 31;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*41+ 5) = (uint64_t)IPW(ip, i*64+ 7) >> 33;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*41+ 5) |= (uint64_t)IPV(ip, i*64+ 8) << 8 | (uint64_t)IPX(ip, i*64+9) << 49;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*41+ 6) = (uint64_t)IPW(ip, i*64+ 9) >> 15 | (uint64_t)IPX(ip, i*64+10) << 26;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*41+ 7) = (uint64_t)IPW(ip, i*64+10) >> 38;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*41+ 7) |= (uint64_t)IPV(ip, i*64+11) << 3 | (uint64_t)IPX(ip, i*64+12) << 44;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*41+ 8) = (uint64_t)IPW(ip, i*64+12) >> 20;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*41+ 8) |= (uint64_t)IPV(ip, i*64+13) << 21 | (uint64_t)IPX(ip, i*64+14) << 62;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*41+ 9) = (uint64_t)IPW(ip, i*64+14) >> 2 | (uint64_t)IPX(ip, i*64+15) << 39;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*41+10) = (uint64_t)IPW(ip, i*64+15) >> 25;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*41+10) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 57;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*41+11) = (uint64_t)IPW(ip, i*64+17) >> 7 | (uint64_t)IPX(ip, i*64+18) << 34;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*41+12) = (uint64_t)IPW(ip, i*64+18) >> 30;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*41+12) |= (uint64_t)IPV(ip, i*64+19) << 11 | (uint64_t)IPX(ip, i*64+20) << 52;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*41+13) = (uint64_t)IPW(ip, i*64+20) >> 12 | (uint64_t)IPX(ip, i*64+21) << 29;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*41+14) = (uint64_t)IPW(ip, i*64+21) >> 35;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*41+14) |= (uint64_t)IPV(ip, i*64+22) << 6 | (uint64_t)IPX(ip, i*64+23) << 47;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*41+15) = (uint64_t)IPW(ip, i*64+23) >> 17 | (uint64_t)IPX(ip, i*64+24) << 24;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*41+16) = (uint64_t)IPW(ip, i*64+24) >> 40;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*41+16) |= (uint64_t)IPV(ip, i*64+25) << 1 | (uint64_t)IPX(ip, i*64+26) << 42;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*41+17) = (uint64_t)IPW(ip, i*64+26) >> 22;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*41+17) |= (uint64_t)IPV(ip, i*64+27) << 19 | (uint64_t)IPX(ip, i*64+28) << 60;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*41+18) = (uint64_t)IPW(ip, i*64+28) >> 4 | (uint64_t)IPX(ip, i*64+29) << 37;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*41+19) = (uint64_t)IPW(ip, i*64+29) >> 27;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*41+19) |= (uint64_t)IPV(ip, i*64+30) << 14 | (uint64_t)IPX(ip, i*64+31) << 55;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*41+20) = (uint64_t)IPW(ip, i*64+31) >> 9;\ +} + +#define BITPACK64_41(ip, op, parm) { \ + BITBLK64_41(ip, 0, op, parm); IPI(ip); op += 41*4/sizeof(op[0]);\ +} + +#define BITBLK64_42(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*21+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 42;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*21+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 22;\ + IP9(ip, i*32+ 2, parm); *((uint64_t *)op+i*21+ 1) |= (uint64_t)IPV(ip, i*32+ 2) << 20 | (uint64_t)IPX(ip, i*32+3) << 62;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*21+ 2) = (uint64_t)IPW(ip, i*32+ 3) >> 2 | (uint64_t)IPX(ip, i*32+4) << 40;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*21+ 3) = (uint64_t)IPW(ip, i*32+ 4) >> 24;\ + IP9(ip, i*32+ 5, parm); *((uint64_t *)op+i*21+ 3) |= (uint64_t)IPV(ip, i*32+ 5) << 18 | (uint64_t)IPX(ip, i*32+6) << 60;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*21+ 4) = (uint64_t)IPW(ip, i*32+ 6) >> 4 | (uint64_t)IPX(ip, i*32+7) << 38;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*21+ 5) = (uint64_t)IPW(ip, i*32+ 7) >> 26;\ + IP9(ip, i*32+ 8, parm); *((uint64_t *)op+i*21+ 5) |= (uint64_t)IPV(ip, i*32+ 8) << 16 | (uint64_t)IPX(ip, i*32+9) << 58;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*21+ 6) = (uint64_t)IPW(ip, i*32+ 9) >> 6 | (uint64_t)IPX(ip, i*32+10) << 36;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*21+ 7) = (uint64_t)IPW(ip, i*32+10) >> 28;\ + IP9(ip, i*32+11, parm); *((uint64_t *)op+i*21+ 7) |= (uint64_t)IPV(ip, i*32+11) << 14 | (uint64_t)IPX(ip, i*32+12) << 56;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*21+ 8) = (uint64_t)IPW(ip, i*32+12) >> 8 | (uint64_t)IPX(ip, i*32+13) << 34;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*21+ 9) = (uint64_t)IPW(ip, i*32+13) >> 30;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*21+ 9) |= (uint64_t)IPV(ip, i*32+14) << 12 | (uint64_t)IPX(ip, i*32+15) << 54;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*21+10) = (uint64_t)IPW(ip, i*32+15) >> 10 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*21+11) = (uint64_t)IPW(ip, i*32+16) >> 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*21+11) |= (uint64_t)IPV(ip, i*32+17) << 10 | (uint64_t)IPX(ip, i*32+18) << 52;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*21+12) = (uint64_t)IPW(ip, i*32+18) >> 12 | (uint64_t)IPX(ip, i*32+19) << 30;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*21+13) = (uint64_t)IPW(ip, i*32+19) >> 34;\ + IP9(ip, i*32+20, parm); *((uint64_t *)op+i*21+13) |= (uint64_t)IPV(ip, i*32+20) << 8 | (uint64_t)IPX(ip, i*32+21) << 50;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*21+14) = (uint64_t)IPW(ip, i*32+21) >> 14 | (uint64_t)IPX(ip, i*32+22) << 28;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*21+15) = (uint64_t)IPW(ip, i*32+22) >> 36;\ + IP9(ip, i*32+23, parm); *((uint64_t *)op+i*21+15) |= (uint64_t)IPV(ip, i*32+23) << 6 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*21+16) = (uint64_t)IPW(ip, i*32+24) >> 16 | (uint64_t)IPX(ip, i*32+25) << 26;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*21+17) = (uint64_t)IPW(ip, i*32+25) >> 38;\ + IP9(ip, i*32+26, parm); *((uint64_t *)op+i*21+17) |= (uint64_t)IPV(ip, i*32+26) << 4 | (uint64_t)IPX(ip, i*32+27) << 46;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*21+18) = (uint64_t)IPW(ip, i*32+27) >> 18 | (uint64_t)IPX(ip, i*32+28) << 24;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*21+19) = (uint64_t)IPW(ip, i*32+28) >> 40;\ + IP9(ip, i*32+29, parm); *((uint64_t *)op+i*21+19) |= (uint64_t)IPV(ip, i*32+29) << 2 | (uint64_t)IPX(ip, i*32+30) << 44;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*21+20) = (uint64_t)IPW(ip, i*32+30) >> 20;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*21+20) |= (uint64_t)IPV(ip, i*32+31) << 22;\ +} + +#define BITPACK64_42(ip, op, parm) { \ + BITBLK64_42(ip, 0, op, parm); IPI(ip); op += 42*4/sizeof(op[0]);\ +} + +#define BITBLK64_43(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*43+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 43;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*43+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 21 | (uint64_t)IPX(ip, i*64+2) << 22;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*43+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 42;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*43+ 2) |= (uint64_t)IPV(ip, i*64+ 3) << 1 | (uint64_t)IPX(ip, i*64+4) << 44;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*43+ 3) = (uint64_t)IPW(ip, i*64+ 4) >> 20 | (uint64_t)IPX(ip, i*64+5) << 23;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*43+ 4) = (uint64_t)IPW(ip, i*64+ 5) >> 41;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*43+ 4) |= (uint64_t)IPV(ip, i*64+ 6) << 2 | (uint64_t)IPX(ip, i*64+7) << 45;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*43+ 5) = (uint64_t)IPW(ip, i*64+ 7) >> 19 | (uint64_t)IPX(ip, i*64+8) << 24;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*43+ 6) = (uint64_t)IPW(ip, i*64+ 8) >> 40;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*43+ 6) |= (uint64_t)IPV(ip, i*64+ 9) << 3 | (uint64_t)IPX(ip, i*64+10) << 46;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*43+ 7) = (uint64_t)IPW(ip, i*64+10) >> 18 | (uint64_t)IPX(ip, i*64+11) << 25;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*43+ 8) = (uint64_t)IPW(ip, i*64+11) >> 39;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*43+ 8) |= (uint64_t)IPV(ip, i*64+12) << 4 | (uint64_t)IPX(ip, i*64+13) << 47;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*43+ 9) = (uint64_t)IPW(ip, i*64+13) >> 17 | (uint64_t)IPX(ip, i*64+14) << 26;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*43+10) = (uint64_t)IPW(ip, i*64+14) >> 38;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*43+10) |= (uint64_t)IPV(ip, i*64+15) << 5 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*43+11) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 27;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*43+12) = (uint64_t)IPW(ip, i*64+17) >> 37;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*43+12) |= (uint64_t)IPV(ip, i*64+18) << 6 | (uint64_t)IPX(ip, i*64+19) << 49;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*43+13) = (uint64_t)IPW(ip, i*64+19) >> 15 | (uint64_t)IPX(ip, i*64+20) << 28;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*43+14) = (uint64_t)IPW(ip, i*64+20) >> 36;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*43+14) |= (uint64_t)IPV(ip, i*64+21) << 7 | (uint64_t)IPX(ip, i*64+22) << 50;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*43+15) = (uint64_t)IPW(ip, i*64+22) >> 14 | (uint64_t)IPX(ip, i*64+23) << 29;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*43+16) = (uint64_t)IPW(ip, i*64+23) >> 35;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*43+16) |= (uint64_t)IPV(ip, i*64+24) << 8 | (uint64_t)IPX(ip, i*64+25) << 51;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*43+17) = (uint64_t)IPW(ip, i*64+25) >> 13 | (uint64_t)IPX(ip, i*64+26) << 30;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*43+18) = (uint64_t)IPW(ip, i*64+26) >> 34;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*43+18) |= (uint64_t)IPV(ip, i*64+27) << 9 | (uint64_t)IPX(ip, i*64+28) << 52;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*43+19) = (uint64_t)IPW(ip, i*64+28) >> 12 | (uint64_t)IPX(ip, i*64+29) << 31;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*43+20) = (uint64_t)IPW(ip, i*64+29) >> 33;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*43+20) |= (uint64_t)IPV(ip, i*64+30) << 10 | (uint64_t)IPX(ip, i*64+31) << 53;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*43+21) = (uint64_t)IPW(ip, i*64+31) >> 11;\ +} + +#define BITPACK64_43(ip, op, parm) { \ + BITBLK64_43(ip, 0, op, parm); IPI(ip); op += 43*4/sizeof(op[0]);\ +} + +#define BITBLK64_44(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*11+ 0) = (uint64_t)IPV(ip, i*16+ 0) | (uint64_t)IPX(ip, i*16+1) << 44;\ + IP64(ip, i*16+ 1, parm); *((uint64_t *)op+i*11+ 1) = (uint64_t)IPW(ip, i*16+ 1) >> 20 | (uint64_t)IPX(ip, i*16+2) << 24;\ + IP64(ip, i*16+ 2, parm); *((uint64_t *)op+i*11+ 2) = (uint64_t)IPW(ip, i*16+ 2) >> 40;\ + IP9(ip, i*16+ 3, parm); *((uint64_t *)op+i*11+ 2) |= (uint64_t)IPV(ip, i*16+ 3) << 4 | (uint64_t)IPX(ip, i*16+4) << 48;\ + IP64(ip, i*16+ 4, parm); *((uint64_t *)op+i*11+ 3) = (uint64_t)IPW(ip, i*16+ 4) >> 16 | (uint64_t)IPX(ip, i*16+5) << 28;\ + IP64(ip, i*16+ 5, parm); *((uint64_t *)op+i*11+ 4) = (uint64_t)IPW(ip, i*16+ 5) >> 36;\ + IP9(ip, i*16+ 6, parm); *((uint64_t *)op+i*11+ 4) |= (uint64_t)IPV(ip, i*16+ 6) << 8 | (uint64_t)IPX(ip, i*16+7) << 52;\ + IP64(ip, i*16+ 7, parm); *((uint64_t *)op+i*11+ 5) = (uint64_t)IPW(ip, i*16+ 7) >> 12 | (uint64_t)IPX(ip, i*16+8) << 32;\ + IP64(ip, i*16+ 8, parm); *((uint64_t *)op+i*11+ 6) = (uint64_t)IPW(ip, i*16+ 8) >> 32;\ + IP9(ip, i*16+ 9, parm); *((uint64_t *)op+i*11+ 6) |= (uint64_t)IPV(ip, i*16+ 9) << 12 | (uint64_t)IPX(ip, i*16+10) << 56;\ + IP64(ip, i*16+10, parm); *((uint64_t *)op+i*11+ 7) = (uint64_t)IPW(ip, i*16+10) >> 8 | (uint64_t)IPX(ip, i*16+11) << 36;\ + IP64(ip, i*16+11, parm); *((uint64_t *)op+i*11+ 8) = (uint64_t)IPW(ip, i*16+11) >> 28;\ + IP9(ip, i*16+12, parm); *((uint64_t *)op+i*11+ 8) |= (uint64_t)IPV(ip, i*16+12) << 16 | (uint64_t)IPX(ip, i*16+13) << 60;\ + IP64(ip, i*16+13, parm); *((uint64_t *)op+i*11+ 9) = (uint64_t)IPW(ip, i*16+13) >> 4 | (uint64_t)IPX(ip, i*16+14) << 40;\ + IP64(ip, i*16+14, parm); *((uint64_t *)op+i*11+10) = (uint64_t)IPW(ip, i*16+14) >> 24;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*11+10) |= (uint64_t)IPV(ip, i*16+15) << 20;\ +} + +#define BITPACK64_44(ip, op, parm) { \ + BITBLK64_44(ip, 0, op, parm);\ + BITBLK64_44(ip, 1, op, parm); IPI(ip); op += 44*4/sizeof(op[0]);\ +} + +#define BITBLK64_45(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*45+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 45;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*45+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 19 | (uint64_t)IPX(ip, i*64+2) << 26;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*45+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 38;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*45+ 2) |= (uint64_t)IPV(ip, i*64+ 3) << 7 | (uint64_t)IPX(ip, i*64+4) << 52;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*45+ 3) = (uint64_t)IPW(ip, i*64+ 4) >> 12 | (uint64_t)IPX(ip, i*64+5) << 33;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*45+ 4) = (uint64_t)IPW(ip, i*64+ 5) >> 31;\ + IP9(ip, i*64+ 6, parm); *((uint64_t *)op+i*45+ 4) |= (uint64_t)IPV(ip, i*64+ 6) << 14 | (uint64_t)IPX(ip, i*64+7) << 59;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*45+ 5) = (uint64_t)IPW(ip, i*64+ 7) >> 5 | (uint64_t)IPX(ip, i*64+8) << 40;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*45+ 6) = (uint64_t)IPW(ip, i*64+ 8) >> 24 | (uint64_t)IPX(ip, i*64+9) << 21;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*45+ 7) = (uint64_t)IPW(ip, i*64+ 9) >> 43;\ + IP9(ip, i*64+10, parm); *((uint64_t *)op+i*45+ 7) |= (uint64_t)IPV(ip, i*64+10) << 2 | (uint64_t)IPX(ip, i*64+11) << 47;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*45+ 8) = (uint64_t)IPW(ip, i*64+11) >> 17 | (uint64_t)IPX(ip, i*64+12) << 28;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*45+ 9) = (uint64_t)IPW(ip, i*64+12) >> 36;\ + IP9(ip, i*64+13, parm); *((uint64_t *)op+i*45+ 9) |= (uint64_t)IPV(ip, i*64+13) << 9 | (uint64_t)IPX(ip, i*64+14) << 54;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*45+10) = (uint64_t)IPW(ip, i*64+14) >> 10 | (uint64_t)IPX(ip, i*64+15) << 35;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*45+11) = (uint64_t)IPW(ip, i*64+15) >> 29;\ + IP9(ip, i*64+16, parm); *((uint64_t *)op+i*45+11) |= (uint64_t)IPV(ip, i*64+16) << 16 | (uint64_t)IPX(ip, i*64+17) << 61;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*45+12) = (uint64_t)IPW(ip, i*64+17) >> 3 | (uint64_t)IPX(ip, i*64+18) << 42;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*45+13) = (uint64_t)IPW(ip, i*64+18) >> 22 | (uint64_t)IPX(ip, i*64+19) << 23;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*45+14) = (uint64_t)IPW(ip, i*64+19) >> 41;\ + IP9(ip, i*64+20, parm); *((uint64_t *)op+i*45+14) |= (uint64_t)IPV(ip, i*64+20) << 4 | (uint64_t)IPX(ip, i*64+21) << 49;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*45+15) = (uint64_t)IPW(ip, i*64+21) >> 15 | (uint64_t)IPX(ip, i*64+22) << 30;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*45+16) = (uint64_t)IPW(ip, i*64+22) >> 34;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*45+16) |= (uint64_t)IPV(ip, i*64+23) << 11 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*45+17) = (uint64_t)IPW(ip, i*64+24) >> 8 | (uint64_t)IPX(ip, i*64+25) << 37;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*45+18) = (uint64_t)IPW(ip, i*64+25) >> 27;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*45+18) |= (uint64_t)IPV(ip, i*64+26) << 18 | (uint64_t)IPX(ip, i*64+27) << 63;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*45+19) = (uint64_t)IPW(ip, i*64+27) >> 1 | (uint64_t)IPX(ip, i*64+28) << 44;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*45+20) = (uint64_t)IPW(ip, i*64+28) >> 20 | (uint64_t)IPX(ip, i*64+29) << 25;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*45+21) = (uint64_t)IPW(ip, i*64+29) >> 39;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*45+21) |= (uint64_t)IPV(ip, i*64+30) << 6 | (uint64_t)IPX(ip, i*64+31) << 51;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*45+22) = (uint64_t)IPW(ip, i*64+31) >> 13;\ +} + +#define BITPACK64_45(ip, op, parm) { \ + BITBLK64_45(ip, 0, op, parm); IPI(ip); op += 45*4/sizeof(op[0]);\ +} + +#define BITBLK64_46(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*23+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 46;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*23+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 18 | (uint64_t)IPX(ip, i*32+2) << 28;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*23+ 2) = (uint64_t)IPW(ip, i*32+ 2) >> 36;\ + IP9(ip, i*32+ 3, parm); *((uint64_t *)op+i*23+ 2) |= (uint64_t)IPV(ip, i*32+ 3) << 10 | (uint64_t)IPX(ip, i*32+4) << 56;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*23+ 3) = (uint64_t)IPW(ip, i*32+ 4) >> 8 | (uint64_t)IPX(ip, i*32+5) << 38;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*23+ 4) = (uint64_t)IPW(ip, i*32+ 5) >> 26 | (uint64_t)IPX(ip, i*32+6) << 20;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*23+ 5) = (uint64_t)IPW(ip, i*32+ 6) >> 44;\ + IP9(ip, i*32+ 7, parm); *((uint64_t *)op+i*23+ 5) |= (uint64_t)IPV(ip, i*32+ 7) << 2 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*23+ 6) = (uint64_t)IPW(ip, i*32+ 8) >> 16 | (uint64_t)IPX(ip, i*32+9) << 30;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*23+ 7) = (uint64_t)IPW(ip, i*32+ 9) >> 34;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*23+ 7) |= (uint64_t)IPV(ip, i*32+10) << 12 | (uint64_t)IPX(ip, i*32+11) << 58;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*23+ 8) = (uint64_t)IPW(ip, i*32+11) >> 6 | (uint64_t)IPX(ip, i*32+12) << 40;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*23+ 9) = (uint64_t)IPW(ip, i*32+12) >> 24 | (uint64_t)IPX(ip, i*32+13) << 22;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*23+10) = (uint64_t)IPW(ip, i*32+13) >> 42;\ + IP9(ip, i*32+14, parm); *((uint64_t *)op+i*23+10) |= (uint64_t)IPV(ip, i*32+14) << 4 | (uint64_t)IPX(ip, i*32+15) << 50;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*23+11) = (uint64_t)IPW(ip, i*32+15) >> 14 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*23+12) = (uint64_t)IPW(ip, i*32+16) >> 32;\ + IP9(ip, i*32+17, parm); *((uint64_t *)op+i*23+12) |= (uint64_t)IPV(ip, i*32+17) << 14 | (uint64_t)IPX(ip, i*32+18) << 60;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*23+13) = (uint64_t)IPW(ip, i*32+18) >> 4 | (uint64_t)IPX(ip, i*32+19) << 42;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*23+14) = (uint64_t)IPW(ip, i*32+19) >> 22 | (uint64_t)IPX(ip, i*32+20) << 24;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*23+15) = (uint64_t)IPW(ip, i*32+20) >> 40;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*23+15) |= (uint64_t)IPV(ip, i*32+21) << 6 | (uint64_t)IPX(ip, i*32+22) << 52;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*23+16) = (uint64_t)IPW(ip, i*32+22) >> 12 | (uint64_t)IPX(ip, i*32+23) << 34;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*23+17) = (uint64_t)IPW(ip, i*32+23) >> 30;\ + IP9(ip, i*32+24, parm); *((uint64_t *)op+i*23+17) |= (uint64_t)IPV(ip, i*32+24) << 16 | (uint64_t)IPX(ip, i*32+25) << 62;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*23+18) = (uint64_t)IPW(ip, i*32+25) >> 2 | (uint64_t)IPX(ip, i*32+26) << 44;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*23+19) = (uint64_t)IPW(ip, i*32+26) >> 20 | (uint64_t)IPX(ip, i*32+27) << 26;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*23+20) = (uint64_t)IPW(ip, i*32+27) >> 38;\ + IP9(ip, i*32+28, parm); *((uint64_t *)op+i*23+20) |= (uint64_t)IPV(ip, i*32+28) << 8 | (uint64_t)IPX(ip, i*32+29) << 54;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*23+21) = (uint64_t)IPW(ip, i*32+29) >> 10 | (uint64_t)IPX(ip, i*32+30) << 36;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*23+22) = (uint64_t)IPW(ip, i*32+30) >> 28;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*23+22) |= (uint64_t)IPV(ip, i*32+31) << 18;\ +} + +#define BITPACK64_46(ip, op, parm) { \ + BITBLK64_46(ip, 0, op, parm); IPI(ip); op += 46*4/sizeof(op[0]);\ +} + +#define BITBLK64_47(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*47+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 47;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*47+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 17 | (uint64_t)IPX(ip, i*64+2) << 30;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*47+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 34;\ + IP9(ip, i*64+ 3, parm); *((uint64_t *)op+i*47+ 2) |= (uint64_t)IPV(ip, i*64+ 3) << 13 | (uint64_t)IPX(ip, i*64+4) << 60;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*47+ 3) = (uint64_t)IPW(ip, i*64+ 4) >> 4 | (uint64_t)IPX(ip, i*64+5) << 43;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*47+ 4) = (uint64_t)IPW(ip, i*64+ 5) >> 21 | (uint64_t)IPX(ip, i*64+6) << 26;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*47+ 5) = (uint64_t)IPW(ip, i*64+ 6) >> 38;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*47+ 5) |= (uint64_t)IPV(ip, i*64+ 7) << 9 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*47+ 6) = (uint64_t)IPW(ip, i*64+ 8) >> 8 | (uint64_t)IPX(ip, i*64+9) << 39;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*47+ 7) = (uint64_t)IPW(ip, i*64+ 9) >> 25 | (uint64_t)IPX(ip, i*64+10) << 22;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*47+ 8) = (uint64_t)IPW(ip, i*64+10) >> 42;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*47+ 8) |= (uint64_t)IPV(ip, i*64+11) << 5 | (uint64_t)IPX(ip, i*64+12) << 52;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*47+ 9) = (uint64_t)IPW(ip, i*64+12) >> 12 | (uint64_t)IPX(ip, i*64+13) << 35;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*47+10) = (uint64_t)IPW(ip, i*64+13) >> 29 | (uint64_t)IPX(ip, i*64+14) << 18;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*47+11) = (uint64_t)IPW(ip, i*64+14) >> 46;\ + IP9(ip, i*64+15, parm); *((uint64_t *)op+i*47+11) |= (uint64_t)IPV(ip, i*64+15) << 1 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*47+12) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 31;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*47+13) = (uint64_t)IPW(ip, i*64+17) >> 33;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*47+13) |= (uint64_t)IPV(ip, i*64+18) << 14 | (uint64_t)IPX(ip, i*64+19) << 61;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*47+14) = (uint64_t)IPW(ip, i*64+19) >> 3 | (uint64_t)IPX(ip, i*64+20) << 44;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*47+15) = (uint64_t)IPW(ip, i*64+20) >> 20 | (uint64_t)IPX(ip, i*64+21) << 27;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*47+16) = (uint64_t)IPW(ip, i*64+21) >> 37;\ + IP9(ip, i*64+22, parm); *((uint64_t *)op+i*47+16) |= (uint64_t)IPV(ip, i*64+22) << 10 | (uint64_t)IPX(ip, i*64+23) << 57;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*47+17) = (uint64_t)IPW(ip, i*64+23) >> 7 | (uint64_t)IPX(ip, i*64+24) << 40;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*47+18) = (uint64_t)IPW(ip, i*64+24) >> 24 | (uint64_t)IPX(ip, i*64+25) << 23;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*47+19) = (uint64_t)IPW(ip, i*64+25) >> 41;\ + IP9(ip, i*64+26, parm); *((uint64_t *)op+i*47+19) |= (uint64_t)IPV(ip, i*64+26) << 6 | (uint64_t)IPX(ip, i*64+27) << 53;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*47+20) = (uint64_t)IPW(ip, i*64+27) >> 11 | (uint64_t)IPX(ip, i*64+28) << 36;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*47+21) = (uint64_t)IPW(ip, i*64+28) >> 28 | (uint64_t)IPX(ip, i*64+29) << 19;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*47+22) = (uint64_t)IPW(ip, i*64+29) >> 45;\ + IP9(ip, i*64+30, parm); *((uint64_t *)op+i*47+22) |= (uint64_t)IPV(ip, i*64+30) << 2 | (uint64_t)IPX(ip, i*64+31) << 49;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*47+23) = (uint64_t)IPW(ip, i*64+31) >> 15;\ +} + +#define BITPACK64_47(ip, op, parm) { \ + BITBLK64_47(ip, 0, op, parm); IPI(ip); op += 47*4/sizeof(op[0]);\ +} + +#define BITBLK64_48(ip, i, op, parm) { ;\ + IP9(ip, i*4+ 0, parm); *((uint64_t *)op+i*3+ 0) = (uint64_t)IPV(ip, i*4+ 0) | (uint64_t)IPX(ip, i*4+1) << 48;\ + IP64(ip, i*4+ 1, parm); *((uint64_t *)op+i*3+ 1) = (uint64_t)IPW(ip, i*4+ 1) >> 16 | (uint64_t)IPX(ip, i*4+2) << 32;\ + IP64(ip, i*4+ 2, parm); *((uint64_t *)op+i*3+ 2) = (uint64_t)IPW(ip, i*4+ 2) >> 32;\ + IP9(ip, i*4+ 3, parm); *((uint64_t *)op+i*3+ 2) |= (uint64_t)IPV(ip, i*4+ 3) << 16;\ +} + +#define BITPACK64_48(ip, op, parm) { \ + BITBLK64_48(ip, 0, op, parm);\ + BITBLK64_48(ip, 1, op, parm);\ + BITBLK64_48(ip, 2, op, parm);\ + BITBLK64_48(ip, 3, op, parm);\ + BITBLK64_48(ip, 4, op, parm);\ + BITBLK64_48(ip, 5, op, parm);\ + BITBLK64_48(ip, 6, op, parm);\ + BITBLK64_48(ip, 7, op, parm); IPI(ip); op += 48*4/sizeof(op[0]);\ +} + +#define BITBLK64_49(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*49+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 49;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*49+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 15 | (uint64_t)IPX(ip, i*64+2) << 34;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*49+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 30 | (uint64_t)IPX(ip, i*64+3) << 19;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*49+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 45;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*49+ 3) |= (uint64_t)IPV(ip, i*64+ 4) << 4 | (uint64_t)IPX(ip, i*64+5) << 53;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*49+ 4) = (uint64_t)IPW(ip, i*64+ 5) >> 11 | (uint64_t)IPX(ip, i*64+6) << 38;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*49+ 5) = (uint64_t)IPW(ip, i*64+ 6) >> 26 | (uint64_t)IPX(ip, i*64+7) << 23;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*49+ 6) = (uint64_t)IPW(ip, i*64+ 7) >> 41;\ + IP9(ip, i*64+ 8, parm); *((uint64_t *)op+i*49+ 6) |= (uint64_t)IPV(ip, i*64+ 8) << 8 | (uint64_t)IPX(ip, i*64+9) << 57;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*49+ 7) = (uint64_t)IPW(ip, i*64+ 9) >> 7 | (uint64_t)IPX(ip, i*64+10) << 42;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*49+ 8) = (uint64_t)IPW(ip, i*64+10) >> 22 | (uint64_t)IPX(ip, i*64+11) << 27;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*49+ 9) = (uint64_t)IPW(ip, i*64+11) >> 37;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*49+ 9) |= (uint64_t)IPV(ip, i*64+12) << 12 | (uint64_t)IPX(ip, i*64+13) << 61;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*49+10) = (uint64_t)IPW(ip, i*64+13) >> 3 | (uint64_t)IPX(ip, i*64+14) << 46;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*49+11) = (uint64_t)IPW(ip, i*64+14) >> 18 | (uint64_t)IPX(ip, i*64+15) << 31;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*49+12) = (uint64_t)IPW(ip, i*64+15) >> 33 | (uint64_t)IPX(ip, i*64+16) << 16;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*49+13) = (uint64_t)IPW(ip, i*64+16) >> 48;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*49+13) |= (uint64_t)IPV(ip, i*64+17) << 1 | (uint64_t)IPX(ip, i*64+18) << 50;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*49+14) = (uint64_t)IPW(ip, i*64+18) >> 14 | (uint64_t)IPX(ip, i*64+19) << 35;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*49+15) = (uint64_t)IPW(ip, i*64+19) >> 29 | (uint64_t)IPX(ip, i*64+20) << 20;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*49+16) = (uint64_t)IPW(ip, i*64+20) >> 44;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*49+16) |= (uint64_t)IPV(ip, i*64+21) << 5 | (uint64_t)IPX(ip, i*64+22) << 54;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*49+17) = (uint64_t)IPW(ip, i*64+22) >> 10 | (uint64_t)IPX(ip, i*64+23) << 39;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*49+18) = (uint64_t)IPW(ip, i*64+23) >> 25 | (uint64_t)IPX(ip, i*64+24) << 24;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*49+19) = (uint64_t)IPW(ip, i*64+24) >> 40;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*49+19) |= (uint64_t)IPV(ip, i*64+25) << 9 | (uint64_t)IPX(ip, i*64+26) << 58;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*49+20) = (uint64_t)IPW(ip, i*64+26) >> 6 | (uint64_t)IPX(ip, i*64+27) << 43;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*49+21) = (uint64_t)IPW(ip, i*64+27) >> 21 | (uint64_t)IPX(ip, i*64+28) << 28;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*49+22) = (uint64_t)IPW(ip, i*64+28) >> 36;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*49+22) |= (uint64_t)IPV(ip, i*64+29) << 13 | (uint64_t)IPX(ip, i*64+30) << 62;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*49+23) = (uint64_t)IPW(ip, i*64+30) >> 2 | (uint64_t)IPX(ip, i*64+31) << 47;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*49+24) = (uint64_t)IPW(ip, i*64+31) >> 17;\ +} + +#define BITPACK64_49(ip, op, parm) { \ + BITBLK64_49(ip, 0, op, parm); IPI(ip); op += 49*4/sizeof(op[0]);\ +} + +#define BITBLK64_50(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*25+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 50;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*25+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 14 | (uint64_t)IPX(ip, i*32+2) << 36;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*25+ 2) = (uint64_t)IPW(ip, i*32+ 2) >> 28 | (uint64_t)IPX(ip, i*32+3) << 22;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*25+ 3) = (uint64_t)IPW(ip, i*32+ 3) >> 42;\ + IP9(ip, i*32+ 4, parm); *((uint64_t *)op+i*25+ 3) |= (uint64_t)IPV(ip, i*32+ 4) << 8 | (uint64_t)IPX(ip, i*32+5) << 58;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*25+ 4) = (uint64_t)IPW(ip, i*32+ 5) >> 6 | (uint64_t)IPX(ip, i*32+6) << 44;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*25+ 5) = (uint64_t)IPW(ip, i*32+ 6) >> 20 | (uint64_t)IPX(ip, i*32+7) << 30;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*25+ 6) = (uint64_t)IPW(ip, i*32+ 7) >> 34 | (uint64_t)IPX(ip, i*32+8) << 16;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*25+ 7) = (uint64_t)IPW(ip, i*32+ 8) >> 48;\ + IP9(ip, i*32+ 9, parm); *((uint64_t *)op+i*25+ 7) |= (uint64_t)IPV(ip, i*32+ 9) << 2 | (uint64_t)IPX(ip, i*32+10) << 52;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*25+ 8) = (uint64_t)IPW(ip, i*32+10) >> 12 | (uint64_t)IPX(ip, i*32+11) << 38;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*25+ 9) = (uint64_t)IPW(ip, i*32+11) >> 26 | (uint64_t)IPX(ip, i*32+12) << 24;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*25+10) = (uint64_t)IPW(ip, i*32+12) >> 40;\ + IP9(ip, i*32+13, parm); *((uint64_t *)op+i*25+10) |= (uint64_t)IPV(ip, i*32+13) << 10 | (uint64_t)IPX(ip, i*32+14) << 60;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*25+11) = (uint64_t)IPW(ip, i*32+14) >> 4 | (uint64_t)IPX(ip, i*32+15) << 46;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*25+12) = (uint64_t)IPW(ip, i*32+15) >> 18 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*25+13) = (uint64_t)IPW(ip, i*32+16) >> 32 | (uint64_t)IPX(ip, i*32+17) << 18;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*25+14) = (uint64_t)IPW(ip, i*32+17) >> 46;\ + IP9(ip, i*32+18, parm); *((uint64_t *)op+i*25+14) |= (uint64_t)IPV(ip, i*32+18) << 4 | (uint64_t)IPX(ip, i*32+19) << 54;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*25+15) = (uint64_t)IPW(ip, i*32+19) >> 10 | (uint64_t)IPX(ip, i*32+20) << 40;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*25+16) = (uint64_t)IPW(ip, i*32+20) >> 24 | (uint64_t)IPX(ip, i*32+21) << 26;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*25+17) = (uint64_t)IPW(ip, i*32+21) >> 38;\ + IP9(ip, i*32+22, parm); *((uint64_t *)op+i*25+17) |= (uint64_t)IPV(ip, i*32+22) << 12 | (uint64_t)IPX(ip, i*32+23) << 62;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*25+18) = (uint64_t)IPW(ip, i*32+23) >> 2 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*25+19) = (uint64_t)IPW(ip, i*32+24) >> 16 | (uint64_t)IPX(ip, i*32+25) << 34;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*25+20) = (uint64_t)IPW(ip, i*32+25) >> 30 | (uint64_t)IPX(ip, i*32+26) << 20;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*25+21) = (uint64_t)IPW(ip, i*32+26) >> 44;\ + IP9(ip, i*32+27, parm); *((uint64_t *)op+i*25+21) |= (uint64_t)IPV(ip, i*32+27) << 6 | (uint64_t)IPX(ip, i*32+28) << 56;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*25+22) = (uint64_t)IPW(ip, i*32+28) >> 8 | (uint64_t)IPX(ip, i*32+29) << 42;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*25+23) = (uint64_t)IPW(ip, i*32+29) >> 22 | (uint64_t)IPX(ip, i*32+30) << 28;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*25+24) = (uint64_t)IPW(ip, i*32+30) >> 36;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*25+24) |= (uint64_t)IPV(ip, i*32+31) << 14;\ +} + +#define BITPACK64_50(ip, op, parm) { \ + BITBLK64_50(ip, 0, op, parm); IPI(ip); op += 50*4/sizeof(op[0]);\ +} + +#define BITBLK64_51(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*51+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 51;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*51+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 13 | (uint64_t)IPX(ip, i*64+2) << 38;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*51+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 26 | (uint64_t)IPX(ip, i*64+3) << 25;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*51+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 39;\ + IP9(ip, i*64+ 4, parm); *((uint64_t *)op+i*51+ 3) |= (uint64_t)IPV(ip, i*64+ 4) << 12 | (uint64_t)IPX(ip, i*64+5) << 63;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*51+ 4) = (uint64_t)IPW(ip, i*64+ 5) >> 1 | (uint64_t)IPX(ip, i*64+6) << 50;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*51+ 5) = (uint64_t)IPW(ip, i*64+ 6) >> 14 | (uint64_t)IPX(ip, i*64+7) << 37;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*51+ 6) = (uint64_t)IPW(ip, i*64+ 7) >> 27 | (uint64_t)IPX(ip, i*64+8) << 24;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*51+ 7) = (uint64_t)IPW(ip, i*64+ 8) >> 40;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*51+ 7) |= (uint64_t)IPV(ip, i*64+ 9) << 11 | (uint64_t)IPX(ip, i*64+10) << 62;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*51+ 8) = (uint64_t)IPW(ip, i*64+10) >> 2 | (uint64_t)IPX(ip, i*64+11) << 49;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*51+ 9) = (uint64_t)IPW(ip, i*64+11) >> 15 | (uint64_t)IPX(ip, i*64+12) << 36;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*51+10) = (uint64_t)IPW(ip, i*64+12) >> 28 | (uint64_t)IPX(ip, i*64+13) << 23;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*51+11) = (uint64_t)IPW(ip, i*64+13) >> 41;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*51+11) |= (uint64_t)IPV(ip, i*64+14) << 10 | (uint64_t)IPX(ip, i*64+15) << 61;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*51+12) = (uint64_t)IPW(ip, i*64+15) >> 3 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*51+13) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 35;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*51+14) = (uint64_t)IPW(ip, i*64+17) >> 29 | (uint64_t)IPX(ip, i*64+18) << 22;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*51+15) = (uint64_t)IPW(ip, i*64+18) >> 42;\ + IP9(ip, i*64+19, parm); *((uint64_t *)op+i*51+15) |= (uint64_t)IPV(ip, i*64+19) << 9 | (uint64_t)IPX(ip, i*64+20) << 60;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*51+16) = (uint64_t)IPW(ip, i*64+20) >> 4 | (uint64_t)IPX(ip, i*64+21) << 47;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*51+17) = (uint64_t)IPW(ip, i*64+21) >> 17 | (uint64_t)IPX(ip, i*64+22) << 34;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*51+18) = (uint64_t)IPW(ip, i*64+22) >> 30 | (uint64_t)IPX(ip, i*64+23) << 21;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*51+19) = (uint64_t)IPW(ip, i*64+23) >> 43;\ + IP9(ip, i*64+24, parm); *((uint64_t *)op+i*51+19) |= (uint64_t)IPV(ip, i*64+24) << 8 | (uint64_t)IPX(ip, i*64+25) << 59;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*51+20) = (uint64_t)IPW(ip, i*64+25) >> 5 | (uint64_t)IPX(ip, i*64+26) << 46;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*51+21) = (uint64_t)IPW(ip, i*64+26) >> 18 | (uint64_t)IPX(ip, i*64+27) << 33;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*51+22) = (uint64_t)IPW(ip, i*64+27) >> 31 | (uint64_t)IPX(ip, i*64+28) << 20;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*51+23) = (uint64_t)IPW(ip, i*64+28) >> 44;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*51+23) |= (uint64_t)IPV(ip, i*64+29) << 7 | (uint64_t)IPX(ip, i*64+30) << 58;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*51+24) = (uint64_t)IPW(ip, i*64+30) >> 6 | (uint64_t)IPX(ip, i*64+31) << 45;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*51+25) = (uint64_t)IPW(ip, i*64+31) >> 19;\ +} + +#define BITPACK64_51(ip, op, parm) { \ + BITBLK64_51(ip, 0, op, parm); IPI(ip); op += 51*4/sizeof(op[0]);\ +} + +#define BITBLK64_52(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*13+ 0) = (uint64_t)IPV(ip, i*16+ 0) | (uint64_t)IPX(ip, i*16+1) << 52;\ + IP64(ip, i*16+ 1, parm); *((uint64_t *)op+i*13+ 1) = (uint64_t)IPW(ip, i*16+ 1) >> 12 | (uint64_t)IPX(ip, i*16+2) << 40;\ + IP64(ip, i*16+ 2, parm); *((uint64_t *)op+i*13+ 2) = (uint64_t)IPW(ip, i*16+ 2) >> 24 | (uint64_t)IPX(ip, i*16+3) << 28;\ + IP64(ip, i*16+ 3, parm); *((uint64_t *)op+i*13+ 3) = (uint64_t)IPW(ip, i*16+ 3) >> 36 | (uint64_t)IPX(ip, i*16+4) << 16;\ + IP64(ip, i*16+ 4, parm); *((uint64_t *)op+i*13+ 4) = (uint64_t)IPW(ip, i*16+ 4) >> 48;\ + IP9(ip, i*16+ 5, parm); *((uint64_t *)op+i*13+ 4) |= (uint64_t)IPV(ip, i*16+ 5) << 4 | (uint64_t)IPX(ip, i*16+6) << 56;\ + IP64(ip, i*16+ 6, parm); *((uint64_t *)op+i*13+ 5) = (uint64_t)IPW(ip, i*16+ 6) >> 8 | (uint64_t)IPX(ip, i*16+7) << 44;\ + IP64(ip, i*16+ 7, parm); *((uint64_t *)op+i*13+ 6) = (uint64_t)IPW(ip, i*16+ 7) >> 20 | (uint64_t)IPX(ip, i*16+8) << 32;\ + IP64(ip, i*16+ 8, parm); *((uint64_t *)op+i*13+ 7) = (uint64_t)IPW(ip, i*16+ 8) >> 32 | (uint64_t)IPX(ip, i*16+9) << 20;\ + IP64(ip, i*16+ 9, parm); *((uint64_t *)op+i*13+ 8) = (uint64_t)IPW(ip, i*16+ 9) >> 44;\ + IP9(ip, i*16+10, parm); *((uint64_t *)op+i*13+ 8) |= (uint64_t)IPV(ip, i*16+10) << 8 | (uint64_t)IPX(ip, i*16+11) << 60;\ + IP64(ip, i*16+11, parm); *((uint64_t *)op+i*13+ 9) = (uint64_t)IPW(ip, i*16+11) >> 4 | (uint64_t)IPX(ip, i*16+12) << 48;\ + IP64(ip, i*16+12, parm); *((uint64_t *)op+i*13+10) = (uint64_t)IPW(ip, i*16+12) >> 16 | (uint64_t)IPX(ip, i*16+13) << 36;\ + IP64(ip, i*16+13, parm); *((uint64_t *)op+i*13+11) = (uint64_t)IPW(ip, i*16+13) >> 28 | (uint64_t)IPX(ip, i*16+14) << 24;\ + IP64(ip, i*16+14, parm); *((uint64_t *)op+i*13+12) = (uint64_t)IPW(ip, i*16+14) >> 40;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*13+12) |= (uint64_t)IPV(ip, i*16+15) << 12;\ +} + +#define BITPACK64_52(ip, op, parm) { \ + BITBLK64_52(ip, 0, op, parm);\ + BITBLK64_52(ip, 1, op, parm); IPI(ip); op += 52*4/sizeof(op[0]);\ +} + +#define BITBLK64_53(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*53+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 53;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*53+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 11 | (uint64_t)IPX(ip, i*64+2) << 42;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*53+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 22 | (uint64_t)IPX(ip, i*64+3) << 31;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*53+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 33 | (uint64_t)IPX(ip, i*64+4) << 20;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*53+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 44;\ + IP9(ip, i*64+ 5, parm); *((uint64_t *)op+i*53+ 4) |= (uint64_t)IPV(ip, i*64+ 5) << 9 | (uint64_t)IPX(ip, i*64+6) << 62;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*53+ 5) = (uint64_t)IPW(ip, i*64+ 6) >> 2 | (uint64_t)IPX(ip, i*64+7) << 51;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*53+ 6) = (uint64_t)IPW(ip, i*64+ 7) >> 13 | (uint64_t)IPX(ip, i*64+8) << 40;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*53+ 7) = (uint64_t)IPW(ip, i*64+ 8) >> 24 | (uint64_t)IPX(ip, i*64+9) << 29;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*53+ 8) = (uint64_t)IPW(ip, i*64+ 9) >> 35 | (uint64_t)IPX(ip, i*64+10) << 18;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*53+ 9) = (uint64_t)IPW(ip, i*64+10) >> 46;\ + IP9(ip, i*64+11, parm); *((uint64_t *)op+i*53+ 9) |= (uint64_t)IPV(ip, i*64+11) << 7 | (uint64_t)IPX(ip, i*64+12) << 60;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*53+10) = (uint64_t)IPW(ip, i*64+12) >> 4 | (uint64_t)IPX(ip, i*64+13) << 49;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*53+11) = (uint64_t)IPW(ip, i*64+13) >> 15 | (uint64_t)IPX(ip, i*64+14) << 38;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*53+12) = (uint64_t)IPW(ip, i*64+14) >> 26 | (uint64_t)IPX(ip, i*64+15) << 27;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*53+13) = (uint64_t)IPW(ip, i*64+15) >> 37 | (uint64_t)IPX(ip, i*64+16) << 16;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*53+14) = (uint64_t)IPW(ip, i*64+16) >> 48;\ + IP9(ip, i*64+17, parm); *((uint64_t *)op+i*53+14) |= (uint64_t)IPV(ip, i*64+17) << 5 | (uint64_t)IPX(ip, i*64+18) << 58;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*53+15) = (uint64_t)IPW(ip, i*64+18) >> 6 | (uint64_t)IPX(ip, i*64+19) << 47;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*53+16) = (uint64_t)IPW(ip, i*64+19) >> 17 | (uint64_t)IPX(ip, i*64+20) << 36;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*53+17) = (uint64_t)IPW(ip, i*64+20) >> 28 | (uint64_t)IPX(ip, i*64+21) << 25;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*53+18) = (uint64_t)IPW(ip, i*64+21) >> 39 | (uint64_t)IPX(ip, i*64+22) << 14;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*53+19) = (uint64_t)IPW(ip, i*64+22) >> 50;\ + IP9(ip, i*64+23, parm); *((uint64_t *)op+i*53+19) |= (uint64_t)IPV(ip, i*64+23) << 3 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*53+20) = (uint64_t)IPW(ip, i*64+24) >> 8 | (uint64_t)IPX(ip, i*64+25) << 45;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*53+21) = (uint64_t)IPW(ip, i*64+25) >> 19 | (uint64_t)IPX(ip, i*64+26) << 34;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*53+22) = (uint64_t)IPW(ip, i*64+26) >> 30 | (uint64_t)IPX(ip, i*64+27) << 23;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*53+23) = (uint64_t)IPW(ip, i*64+27) >> 41 | (uint64_t)IPX(ip, i*64+28) << 12;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*53+24) = (uint64_t)IPW(ip, i*64+28) >> 52;\ + IP9(ip, i*64+29, parm); *((uint64_t *)op+i*53+24) |= (uint64_t)IPV(ip, i*64+29) << 1 | (uint64_t)IPX(ip, i*64+30) << 54;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*53+25) = (uint64_t)IPW(ip, i*64+30) >> 10 | (uint64_t)IPX(ip, i*64+31) << 43;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*53+26) = (uint64_t)IPW(ip, i*64+31) >> 21;\ +} + +#define BITPACK64_53(ip, op, parm) { \ + BITBLK64_53(ip, 0, op, parm); IPI(ip); op += 53*4/sizeof(op[0]);\ +} + +#define BITBLK64_54(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*27+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 54;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*27+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 10 | (uint64_t)IPX(ip, i*32+2) << 44;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*27+ 2) = (uint64_t)IPW(ip, i*32+ 2) >> 20 | (uint64_t)IPX(ip, i*32+3) << 34;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*27+ 3) = (uint64_t)IPW(ip, i*32+ 3) >> 30 | (uint64_t)IPX(ip, i*32+4) << 24;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*27+ 4) = (uint64_t)IPW(ip, i*32+ 4) >> 40 | (uint64_t)IPX(ip, i*32+5) << 14;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*27+ 5) = (uint64_t)IPW(ip, i*32+ 5) >> 50;\ + IP9(ip, i*32+ 6, parm); *((uint64_t *)op+i*27+ 5) |= (uint64_t)IPV(ip, i*32+ 6) << 4 | (uint64_t)IPX(ip, i*32+7) << 58;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*27+ 6) = (uint64_t)IPW(ip, i*32+ 7) >> 6 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*27+ 7) = (uint64_t)IPW(ip, i*32+ 8) >> 16 | (uint64_t)IPX(ip, i*32+9) << 38;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*27+ 8) = (uint64_t)IPW(ip, i*32+ 9) >> 26 | (uint64_t)IPX(ip, i*32+10) << 28;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*27+ 9) = (uint64_t)IPW(ip, i*32+10) >> 36 | (uint64_t)IPX(ip, i*32+11) << 18;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*27+10) = (uint64_t)IPW(ip, i*32+11) >> 46;\ + IP9(ip, i*32+12, parm); *((uint64_t *)op+i*27+10) |= (uint64_t)IPV(ip, i*32+12) << 8 | (uint64_t)IPX(ip, i*32+13) << 62;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*27+11) = (uint64_t)IPW(ip, i*32+13) >> 2 | (uint64_t)IPX(ip, i*32+14) << 52;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*27+12) = (uint64_t)IPW(ip, i*32+14) >> 12 | (uint64_t)IPX(ip, i*32+15) << 42;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*27+13) = (uint64_t)IPW(ip, i*32+15) >> 22 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*27+14) = (uint64_t)IPW(ip, i*32+16) >> 32 | (uint64_t)IPX(ip, i*32+17) << 22;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*27+15) = (uint64_t)IPW(ip, i*32+17) >> 42 | (uint64_t)IPX(ip, i*32+18) << 12;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*27+16) = (uint64_t)IPW(ip, i*32+18) >> 52;\ + IP9(ip, i*32+19, parm); *((uint64_t *)op+i*27+16) |= (uint64_t)IPV(ip, i*32+19) << 2 | (uint64_t)IPX(ip, i*32+20) << 56;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*27+17) = (uint64_t)IPW(ip, i*32+20) >> 8 | (uint64_t)IPX(ip, i*32+21) << 46;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*27+18) = (uint64_t)IPW(ip, i*32+21) >> 18 | (uint64_t)IPX(ip, i*32+22) << 36;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*27+19) = (uint64_t)IPW(ip, i*32+22) >> 28 | (uint64_t)IPX(ip, i*32+23) << 26;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*27+20) = (uint64_t)IPW(ip, i*32+23) >> 38 | (uint64_t)IPX(ip, i*32+24) << 16;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*27+21) = (uint64_t)IPW(ip, i*32+24) >> 48;\ + IP9(ip, i*32+25, parm); *((uint64_t *)op+i*27+21) |= (uint64_t)IPV(ip, i*32+25) << 6 | (uint64_t)IPX(ip, i*32+26) << 60;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*27+22) = (uint64_t)IPW(ip, i*32+26) >> 4 | (uint64_t)IPX(ip, i*32+27) << 50;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*27+23) = (uint64_t)IPW(ip, i*32+27) >> 14 | (uint64_t)IPX(ip, i*32+28) << 40;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*27+24) = (uint64_t)IPW(ip, i*32+28) >> 24 | (uint64_t)IPX(ip, i*32+29) << 30;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*27+25) = (uint64_t)IPW(ip, i*32+29) >> 34 | (uint64_t)IPX(ip, i*32+30) << 20;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*27+26) = (uint64_t)IPW(ip, i*32+30) >> 44;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*27+26) |= (uint64_t)IPV(ip, i*32+31) << 10;\ +} + +#define BITPACK64_54(ip, op, parm) { \ + BITBLK64_54(ip, 0, op, parm); IPI(ip); op += 54*4/sizeof(op[0]);\ +} + +#define BITBLK64_55(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*55+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 55;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*55+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 9 | (uint64_t)IPX(ip, i*64+2) << 46;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*55+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 18 | (uint64_t)IPX(ip, i*64+3) << 37;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*55+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 27 | (uint64_t)IPX(ip, i*64+4) << 28;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*55+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 36 | (uint64_t)IPX(ip, i*64+5) << 19;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*55+ 5) = (uint64_t)IPW(ip, i*64+ 5) >> 45 | (uint64_t)IPX(ip, i*64+6) << 10;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*55+ 6) = (uint64_t)IPW(ip, i*64+ 6) >> 54;\ + IP9(ip, i*64+ 7, parm); *((uint64_t *)op+i*55+ 6) |= (uint64_t)IPV(ip, i*64+ 7) << 1 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*55+ 7) = (uint64_t)IPW(ip, i*64+ 8) >> 8 | (uint64_t)IPX(ip, i*64+9) << 47;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*55+ 8) = (uint64_t)IPW(ip, i*64+ 9) >> 17 | (uint64_t)IPX(ip, i*64+10) << 38;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*55+ 9) = (uint64_t)IPW(ip, i*64+10) >> 26 | (uint64_t)IPX(ip, i*64+11) << 29;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*55+10) = (uint64_t)IPW(ip, i*64+11) >> 35 | (uint64_t)IPX(ip, i*64+12) << 20;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*55+11) = (uint64_t)IPW(ip, i*64+12) >> 44 | (uint64_t)IPX(ip, i*64+13) << 11;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*55+12) = (uint64_t)IPW(ip, i*64+13) >> 53;\ + IP9(ip, i*64+14, parm); *((uint64_t *)op+i*55+12) |= (uint64_t)IPV(ip, i*64+14) << 2 | (uint64_t)IPX(ip, i*64+15) << 57;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*55+13) = (uint64_t)IPW(ip, i*64+15) >> 7 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*55+14) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 39;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*55+15) = (uint64_t)IPW(ip, i*64+17) >> 25 | (uint64_t)IPX(ip, i*64+18) << 30;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*55+16) = (uint64_t)IPW(ip, i*64+18) >> 34 | (uint64_t)IPX(ip, i*64+19) << 21;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*55+17) = (uint64_t)IPW(ip, i*64+19) >> 43 | (uint64_t)IPX(ip, i*64+20) << 12;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*55+18) = (uint64_t)IPW(ip, i*64+20) >> 52;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*55+18) |= (uint64_t)IPV(ip, i*64+21) << 3 | (uint64_t)IPX(ip, i*64+22) << 58;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*55+19) = (uint64_t)IPW(ip, i*64+22) >> 6 | (uint64_t)IPX(ip, i*64+23) << 49;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*55+20) = (uint64_t)IPW(ip, i*64+23) >> 15 | (uint64_t)IPX(ip, i*64+24) << 40;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*55+21) = (uint64_t)IPW(ip, i*64+24) >> 24 | (uint64_t)IPX(ip, i*64+25) << 31;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*55+22) = (uint64_t)IPW(ip, i*64+25) >> 33 | (uint64_t)IPX(ip, i*64+26) << 22;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*55+23) = (uint64_t)IPW(ip, i*64+26) >> 42 | (uint64_t)IPX(ip, i*64+27) << 13;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*55+24) = (uint64_t)IPW(ip, i*64+27) >> 51;\ + IP9(ip, i*64+28, parm); *((uint64_t *)op+i*55+24) |= (uint64_t)IPV(ip, i*64+28) << 4 | (uint64_t)IPX(ip, i*64+29) << 59;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*55+25) = (uint64_t)IPW(ip, i*64+29) >> 5 | (uint64_t)IPX(ip, i*64+30) << 50;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*55+26) = (uint64_t)IPW(ip, i*64+30) >> 14 | (uint64_t)IPX(ip, i*64+31) << 41;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*55+27) = (uint64_t)IPW(ip, i*64+31) >> 23;\ +} + +#define BITPACK64_55(ip, op, parm) { \ + BITBLK64_55(ip, 0, op, parm); IPI(ip); op += 55*4/sizeof(op[0]);\ +} + +#define BITBLK64_56(ip, i, op, parm) { ;\ + IP9(ip, i*8+ 0, parm); *((uint64_t *)op+i*7+ 0) = (uint64_t)IPV(ip, i*8+ 0) | (uint64_t)IPX(ip, i*8+1) << 56;\ + IP64(ip, i*8+ 1, parm); *((uint64_t *)op+i*7+ 1) = (uint64_t)IPW(ip, i*8+ 1) >> 8 | (uint64_t)IPX(ip, i*8+2) << 48;\ + IP64(ip, i*8+ 2, parm); *((uint64_t *)op+i*7+ 2) = (uint64_t)IPW(ip, i*8+ 2) >> 16 | (uint64_t)IPX(ip, i*8+3) << 40;\ + IP64(ip, i*8+ 3, parm); *((uint64_t *)op+i*7+ 3) = (uint64_t)IPW(ip, i*8+ 3) >> 24 | (uint64_t)IPX(ip, i*8+4) << 32;\ + IP64(ip, i*8+ 4, parm); *((uint64_t *)op+i*7+ 4) = (uint64_t)IPW(ip, i*8+ 4) >> 32 | (uint64_t)IPX(ip, i*8+5) << 24;\ + IP64(ip, i*8+ 5, parm); *((uint64_t *)op+i*7+ 5) = (uint64_t)IPW(ip, i*8+ 5) >> 40 | (uint64_t)IPX(ip, i*8+6) << 16;\ + IP64(ip, i*8+ 6, parm); *((uint64_t *)op+i*7+ 6) = (uint64_t)IPW(ip, i*8+ 6) >> 48;\ + IP9(ip, i*8+ 7, parm); *((uint64_t *)op+i*7+ 6) |= (uint64_t)IPV(ip, i*8+ 7) << 8;\ +} + +#define BITPACK64_56(ip, op, parm) { \ + BITBLK64_56(ip, 0, op, parm);\ + BITBLK64_56(ip, 1, op, parm);\ + BITBLK64_56(ip, 2, op, parm);\ + BITBLK64_56(ip, 3, op, parm); IPI(ip); op += 56*4/sizeof(op[0]);\ +} + +#define BITBLK64_57(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*57+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 57;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*57+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 7 | (uint64_t)IPX(ip, i*64+2) << 50;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*57+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 14 | (uint64_t)IPX(ip, i*64+3) << 43;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*57+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 21 | (uint64_t)IPX(ip, i*64+4) << 36;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*57+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 28 | (uint64_t)IPX(ip, i*64+5) << 29;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*57+ 5) = (uint64_t)IPW(ip, i*64+ 5) >> 35 | (uint64_t)IPX(ip, i*64+6) << 22;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*57+ 6) = (uint64_t)IPW(ip, i*64+ 6) >> 42 | (uint64_t)IPX(ip, i*64+7) << 15;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*57+ 7) = (uint64_t)IPW(ip, i*64+ 7) >> 49 | (uint64_t)IPX(ip, i*64+8) << 8;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*57+ 8) = (uint64_t)IPW(ip, i*64+ 8) >> 56;\ + IP9(ip, i*64+ 9, parm); *((uint64_t *)op+i*57+ 8) |= (uint64_t)IPV(ip, i*64+ 9) << 1 | (uint64_t)IPX(ip, i*64+10) << 58;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*57+ 9) = (uint64_t)IPW(ip, i*64+10) >> 6 | (uint64_t)IPX(ip, i*64+11) << 51;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*57+10) = (uint64_t)IPW(ip, i*64+11) >> 13 | (uint64_t)IPX(ip, i*64+12) << 44;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*57+11) = (uint64_t)IPW(ip, i*64+12) >> 20 | (uint64_t)IPX(ip, i*64+13) << 37;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*57+12) = (uint64_t)IPW(ip, i*64+13) >> 27 | (uint64_t)IPX(ip, i*64+14) << 30;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*57+13) = (uint64_t)IPW(ip, i*64+14) >> 34 | (uint64_t)IPX(ip, i*64+15) << 23;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*57+14) = (uint64_t)IPW(ip, i*64+15) >> 41 | (uint64_t)IPX(ip, i*64+16) << 16;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*57+15) = (uint64_t)IPW(ip, i*64+16) >> 48 | (uint64_t)IPX(ip, i*64+17) << 9;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*57+16) = (uint64_t)IPW(ip, i*64+17) >> 55;\ + IP9(ip, i*64+18, parm); *((uint64_t *)op+i*57+16) |= (uint64_t)IPV(ip, i*64+18) << 2 | (uint64_t)IPX(ip, i*64+19) << 59;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*57+17) = (uint64_t)IPW(ip, i*64+19) >> 5 | (uint64_t)IPX(ip, i*64+20) << 52;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*57+18) = (uint64_t)IPW(ip, i*64+20) >> 12 | (uint64_t)IPX(ip, i*64+21) << 45;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*57+19) = (uint64_t)IPW(ip, i*64+21) >> 19 | (uint64_t)IPX(ip, i*64+22) << 38;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*57+20) = (uint64_t)IPW(ip, i*64+22) >> 26 | (uint64_t)IPX(ip, i*64+23) << 31;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*57+21) = (uint64_t)IPW(ip, i*64+23) >> 33 | (uint64_t)IPX(ip, i*64+24) << 24;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*57+22) = (uint64_t)IPW(ip, i*64+24) >> 40 | (uint64_t)IPX(ip, i*64+25) << 17;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*57+23) = (uint64_t)IPW(ip, i*64+25) >> 47 | (uint64_t)IPX(ip, i*64+26) << 10;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*57+24) = (uint64_t)IPW(ip, i*64+26) >> 54;\ + IP9(ip, i*64+27, parm); *((uint64_t *)op+i*57+24) |= (uint64_t)IPV(ip, i*64+27) << 3 | (uint64_t)IPX(ip, i*64+28) << 60;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*57+25) = (uint64_t)IPW(ip, i*64+28) >> 4 | (uint64_t)IPX(ip, i*64+29) << 53;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*57+26) = (uint64_t)IPW(ip, i*64+29) >> 11 | (uint64_t)IPX(ip, i*64+30) << 46;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*57+27) = (uint64_t)IPW(ip, i*64+30) >> 18 | (uint64_t)IPX(ip, i*64+31) << 39;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*57+28) = (uint64_t)IPW(ip, i*64+31) >> 25;\ +} + +#define BITPACK64_57(ip, op, parm) { \ + BITBLK64_57(ip, 0, op, parm); IPI(ip); op += 57*4/sizeof(op[0]);\ +} + +#define BITBLK64_58(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*29+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 58;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*29+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 6 | (uint64_t)IPX(ip, i*32+2) << 52;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*29+ 2) = (uint64_t)IPW(ip, i*32+ 2) >> 12 | (uint64_t)IPX(ip, i*32+3) << 46;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*29+ 3) = (uint64_t)IPW(ip, i*32+ 3) >> 18 | (uint64_t)IPX(ip, i*32+4) << 40;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*29+ 4) = (uint64_t)IPW(ip, i*32+ 4) >> 24 | (uint64_t)IPX(ip, i*32+5) << 34;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*29+ 5) = (uint64_t)IPW(ip, i*32+ 5) >> 30 | (uint64_t)IPX(ip, i*32+6) << 28;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*29+ 6) = (uint64_t)IPW(ip, i*32+ 6) >> 36 | (uint64_t)IPX(ip, i*32+7) << 22;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*29+ 7) = (uint64_t)IPW(ip, i*32+ 7) >> 42 | (uint64_t)IPX(ip, i*32+8) << 16;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*29+ 8) = (uint64_t)IPW(ip, i*32+ 8) >> 48 | (uint64_t)IPX(ip, i*32+9) << 10;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*29+ 9) = (uint64_t)IPW(ip, i*32+ 9) >> 54;\ + IP9(ip, i*32+10, parm); *((uint64_t *)op+i*29+ 9) |= (uint64_t)IPV(ip, i*32+10) << 4 | (uint64_t)IPX(ip, i*32+11) << 62;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*29+10) = (uint64_t)IPW(ip, i*32+11) >> 2 | (uint64_t)IPX(ip, i*32+12) << 56;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*29+11) = (uint64_t)IPW(ip, i*32+12) >> 8 | (uint64_t)IPX(ip, i*32+13) << 50;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*29+12) = (uint64_t)IPW(ip, i*32+13) >> 14 | (uint64_t)IPX(ip, i*32+14) << 44;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*29+13) = (uint64_t)IPW(ip, i*32+14) >> 20 | (uint64_t)IPX(ip, i*32+15) << 38;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*29+14) = (uint64_t)IPW(ip, i*32+15) >> 26 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*29+15) = (uint64_t)IPW(ip, i*32+16) >> 32 | (uint64_t)IPX(ip, i*32+17) << 26;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*29+16) = (uint64_t)IPW(ip, i*32+17) >> 38 | (uint64_t)IPX(ip, i*32+18) << 20;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*29+17) = (uint64_t)IPW(ip, i*32+18) >> 44 | (uint64_t)IPX(ip, i*32+19) << 14;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*29+18) = (uint64_t)IPW(ip, i*32+19) >> 50 | (uint64_t)IPX(ip, i*32+20) << 8;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*29+19) = (uint64_t)IPW(ip, i*32+20) >> 56;\ + IP9(ip, i*32+21, parm); *((uint64_t *)op+i*29+19) |= (uint64_t)IPV(ip, i*32+21) << 2 | (uint64_t)IPX(ip, i*32+22) << 60;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*29+20) = (uint64_t)IPW(ip, i*32+22) >> 4 | (uint64_t)IPX(ip, i*32+23) << 54;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*29+21) = (uint64_t)IPW(ip, i*32+23) >> 10 | (uint64_t)IPX(ip, i*32+24) << 48;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*29+22) = (uint64_t)IPW(ip, i*32+24) >> 16 | (uint64_t)IPX(ip, i*32+25) << 42;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*29+23) = (uint64_t)IPW(ip, i*32+25) >> 22 | (uint64_t)IPX(ip, i*32+26) << 36;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*29+24) = (uint64_t)IPW(ip, i*32+26) >> 28 | (uint64_t)IPX(ip, i*32+27) << 30;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*29+25) = (uint64_t)IPW(ip, i*32+27) >> 34 | (uint64_t)IPX(ip, i*32+28) << 24;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*29+26) = (uint64_t)IPW(ip, i*32+28) >> 40 | (uint64_t)IPX(ip, i*32+29) << 18;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*29+27) = (uint64_t)IPW(ip, i*32+29) >> 46 | (uint64_t)IPX(ip, i*32+30) << 12;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*29+28) = (uint64_t)IPW(ip, i*32+30) >> 52;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*29+28) |= (uint64_t)IPV(ip, i*32+31) << 6;\ +} + +#define BITPACK64_58(ip, op, parm) { \ + BITBLK64_58(ip, 0, op, parm); IPI(ip); op += 58*4/sizeof(op[0]);\ +} + +#define BITBLK64_59(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*59+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 59;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*59+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 5 | (uint64_t)IPX(ip, i*64+2) << 54;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*59+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 10 | (uint64_t)IPX(ip, i*64+3) << 49;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*59+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 15 | (uint64_t)IPX(ip, i*64+4) << 44;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*59+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 20 | (uint64_t)IPX(ip, i*64+5) << 39;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*59+ 5) = (uint64_t)IPW(ip, i*64+ 5) >> 25 | (uint64_t)IPX(ip, i*64+6) << 34;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*59+ 6) = (uint64_t)IPW(ip, i*64+ 6) >> 30 | (uint64_t)IPX(ip, i*64+7) << 29;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*59+ 7) = (uint64_t)IPW(ip, i*64+ 7) >> 35 | (uint64_t)IPX(ip, i*64+8) << 24;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*59+ 8) = (uint64_t)IPW(ip, i*64+ 8) >> 40 | (uint64_t)IPX(ip, i*64+9) << 19;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*59+ 9) = (uint64_t)IPW(ip, i*64+ 9) >> 45 | (uint64_t)IPX(ip, i*64+10) << 14;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*59+10) = (uint64_t)IPW(ip, i*64+10) >> 50 | (uint64_t)IPX(ip, i*64+11) << 9;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*59+11) = (uint64_t)IPW(ip, i*64+11) >> 55;\ + IP9(ip, i*64+12, parm); *((uint64_t *)op+i*59+11) |= (uint64_t)IPV(ip, i*64+12) << 4 | (uint64_t)IPX(ip, i*64+13) << 63;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*59+12) = (uint64_t)IPW(ip, i*64+13) >> 1 | (uint64_t)IPX(ip, i*64+14) << 58;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*59+13) = (uint64_t)IPW(ip, i*64+14) >> 6 | (uint64_t)IPX(ip, i*64+15) << 53;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*59+14) = (uint64_t)IPW(ip, i*64+15) >> 11 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*59+15) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 43;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*59+16) = (uint64_t)IPW(ip, i*64+17) >> 21 | (uint64_t)IPX(ip, i*64+18) << 38;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*59+17) = (uint64_t)IPW(ip, i*64+18) >> 26 | (uint64_t)IPX(ip, i*64+19) << 33;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*59+18) = (uint64_t)IPW(ip, i*64+19) >> 31 | (uint64_t)IPX(ip, i*64+20) << 28;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*59+19) = (uint64_t)IPW(ip, i*64+20) >> 36 | (uint64_t)IPX(ip, i*64+21) << 23;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*59+20) = (uint64_t)IPW(ip, i*64+21) >> 41 | (uint64_t)IPX(ip, i*64+22) << 18;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*59+21) = (uint64_t)IPW(ip, i*64+22) >> 46 | (uint64_t)IPX(ip, i*64+23) << 13;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*59+22) = (uint64_t)IPW(ip, i*64+23) >> 51 | (uint64_t)IPX(ip, i*64+24) << 8;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*59+23) = (uint64_t)IPW(ip, i*64+24) >> 56;\ + IP9(ip, i*64+25, parm); *((uint64_t *)op+i*59+23) |= (uint64_t)IPV(ip, i*64+25) << 3 | (uint64_t)IPX(ip, i*64+26) << 62;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*59+24) = (uint64_t)IPW(ip, i*64+26) >> 2 | (uint64_t)IPX(ip, i*64+27) << 57;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*59+25) = (uint64_t)IPW(ip, i*64+27) >> 7 | (uint64_t)IPX(ip, i*64+28) << 52;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*59+26) = (uint64_t)IPW(ip, i*64+28) >> 12 | (uint64_t)IPX(ip, i*64+29) << 47;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*59+27) = (uint64_t)IPW(ip, i*64+29) >> 17 | (uint64_t)IPX(ip, i*64+30) << 42;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*59+28) = (uint64_t)IPW(ip, i*64+30) >> 22 | (uint64_t)IPX(ip, i*64+31) << 37;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*59+29) = (uint64_t)IPW(ip, i*64+31) >> 27;\ +} + +#define BITPACK64_59(ip, op, parm) { \ + BITBLK64_59(ip, 0, op, parm); IPI(ip); op += 59*4/sizeof(op[0]);\ +} + +#define BITBLK64_60(ip, i, op, parm) { ;\ + IP9(ip, i*16+ 0, parm); *((uint64_t *)op+i*15+ 0) = (uint64_t)IPV(ip, i*16+ 0) | (uint64_t)IPX(ip, i*16+1) << 60;\ + IP64(ip, i*16+ 1, parm); *((uint64_t *)op+i*15+ 1) = (uint64_t)IPW(ip, i*16+ 1) >> 4 | (uint64_t)IPX(ip, i*16+2) << 56;\ + IP64(ip, i*16+ 2, parm); *((uint64_t *)op+i*15+ 2) = (uint64_t)IPW(ip, i*16+ 2) >> 8 | (uint64_t)IPX(ip, i*16+3) << 52;\ + IP64(ip, i*16+ 3, parm); *((uint64_t *)op+i*15+ 3) = (uint64_t)IPW(ip, i*16+ 3) >> 12 | (uint64_t)IPX(ip, i*16+4) << 48;\ + IP64(ip, i*16+ 4, parm); *((uint64_t *)op+i*15+ 4) = (uint64_t)IPW(ip, i*16+ 4) >> 16 | (uint64_t)IPX(ip, i*16+5) << 44;\ + IP64(ip, i*16+ 5, parm); *((uint64_t *)op+i*15+ 5) = (uint64_t)IPW(ip, i*16+ 5) >> 20 | (uint64_t)IPX(ip, i*16+6) << 40;\ + IP64(ip, i*16+ 6, parm); *((uint64_t *)op+i*15+ 6) = (uint64_t)IPW(ip, i*16+ 6) >> 24 | (uint64_t)IPX(ip, i*16+7) << 36;\ + IP64(ip, i*16+ 7, parm); *((uint64_t *)op+i*15+ 7) = (uint64_t)IPW(ip, i*16+ 7) >> 28 | (uint64_t)IPX(ip, i*16+8) << 32;\ + IP64(ip, i*16+ 8, parm); *((uint64_t *)op+i*15+ 8) = (uint64_t)IPW(ip, i*16+ 8) >> 32 | (uint64_t)IPX(ip, i*16+9) << 28;\ + IP64(ip, i*16+ 9, parm); *((uint64_t *)op+i*15+ 9) = (uint64_t)IPW(ip, i*16+ 9) >> 36 | (uint64_t)IPX(ip, i*16+10) << 24;\ + IP64(ip, i*16+10, parm); *((uint64_t *)op+i*15+10) = (uint64_t)IPW(ip, i*16+10) >> 40 | (uint64_t)IPX(ip, i*16+11) << 20;\ + IP64(ip, i*16+11, parm); *((uint64_t *)op+i*15+11) = (uint64_t)IPW(ip, i*16+11) >> 44 | (uint64_t)IPX(ip, i*16+12) << 16;\ + IP64(ip, i*16+12, parm); *((uint64_t *)op+i*15+12) = (uint64_t)IPW(ip, i*16+12) >> 48 | (uint64_t)IPX(ip, i*16+13) << 12;\ + IP64(ip, i*16+13, parm); *((uint64_t *)op+i*15+13) = (uint64_t)IPW(ip, i*16+13) >> 52 | (uint64_t)IPX(ip, i*16+14) << 8;\ + IP64(ip, i*16+14, parm); *((uint64_t *)op+i*15+14) = (uint64_t)IPW(ip, i*16+14) >> 56;\ + IP9(ip, i*16+15, parm); *((uint64_t *)op+i*15+14) |= (uint64_t)IPV(ip, i*16+15) << 4;\ +} + +#define BITPACK64_60(ip, op, parm) { \ + BITBLK64_60(ip, 0, op, parm);\ + BITBLK64_60(ip, 1, op, parm); IPI(ip); op += 60*4/sizeof(op[0]);\ +} + +#define BITBLK64_61(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*61+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 61;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*61+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 3 | (uint64_t)IPX(ip, i*64+2) << 58;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*61+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 6 | (uint64_t)IPX(ip, i*64+3) << 55;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*61+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 9 | (uint64_t)IPX(ip, i*64+4) << 52;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*61+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 12 | (uint64_t)IPX(ip, i*64+5) << 49;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*61+ 5) = (uint64_t)IPW(ip, i*64+ 5) >> 15 | (uint64_t)IPX(ip, i*64+6) << 46;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*61+ 6) = (uint64_t)IPW(ip, i*64+ 6) >> 18 | (uint64_t)IPX(ip, i*64+7) << 43;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*61+ 7) = (uint64_t)IPW(ip, i*64+ 7) >> 21 | (uint64_t)IPX(ip, i*64+8) << 40;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*61+ 8) = (uint64_t)IPW(ip, i*64+ 8) >> 24 | (uint64_t)IPX(ip, i*64+9) << 37;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*61+ 9) = (uint64_t)IPW(ip, i*64+ 9) >> 27 | (uint64_t)IPX(ip, i*64+10) << 34;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*61+10) = (uint64_t)IPW(ip, i*64+10) >> 30 | (uint64_t)IPX(ip, i*64+11) << 31;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*61+11) = (uint64_t)IPW(ip, i*64+11) >> 33 | (uint64_t)IPX(ip, i*64+12) << 28;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*61+12) = (uint64_t)IPW(ip, i*64+12) >> 36 | (uint64_t)IPX(ip, i*64+13) << 25;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*61+13) = (uint64_t)IPW(ip, i*64+13) >> 39 | (uint64_t)IPX(ip, i*64+14) << 22;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*61+14) = (uint64_t)IPW(ip, i*64+14) >> 42 | (uint64_t)IPX(ip, i*64+15) << 19;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*61+15) = (uint64_t)IPW(ip, i*64+15) >> 45 | (uint64_t)IPX(ip, i*64+16) << 16;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*61+16) = (uint64_t)IPW(ip, i*64+16) >> 48 | (uint64_t)IPX(ip, i*64+17) << 13;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*61+17) = (uint64_t)IPW(ip, i*64+17) >> 51 | (uint64_t)IPX(ip, i*64+18) << 10;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*61+18) = (uint64_t)IPW(ip, i*64+18) >> 54 | (uint64_t)IPX(ip, i*64+19) << 7;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*61+19) = (uint64_t)IPW(ip, i*64+19) >> 57 | (uint64_t)IPX(ip, i*64+20) << 4;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*61+20) = (uint64_t)IPW(ip, i*64+20) >> 60;\ + IP9(ip, i*64+21, parm); *((uint64_t *)op+i*61+20) |= (uint64_t)IPV(ip, i*64+21) << 1 | (uint64_t)IPX(ip, i*64+22) << 62;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*61+21) = (uint64_t)IPW(ip, i*64+22) >> 2 | (uint64_t)IPX(ip, i*64+23) << 59;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*61+22) = (uint64_t)IPW(ip, i*64+23) >> 5 | (uint64_t)IPX(ip, i*64+24) << 56;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*61+23) = (uint64_t)IPW(ip, i*64+24) >> 8 | (uint64_t)IPX(ip, i*64+25) << 53;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*61+24) = (uint64_t)IPW(ip, i*64+25) >> 11 | (uint64_t)IPX(ip, i*64+26) << 50;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*61+25) = (uint64_t)IPW(ip, i*64+26) >> 14 | (uint64_t)IPX(ip, i*64+27) << 47;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*61+26) = (uint64_t)IPW(ip, i*64+27) >> 17 | (uint64_t)IPX(ip, i*64+28) << 44;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*61+27) = (uint64_t)IPW(ip, i*64+28) >> 20 | (uint64_t)IPX(ip, i*64+29) << 41;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*61+28) = (uint64_t)IPW(ip, i*64+29) >> 23 | (uint64_t)IPX(ip, i*64+30) << 38;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*61+29) = (uint64_t)IPW(ip, i*64+30) >> 26 | (uint64_t)IPX(ip, i*64+31) << 35;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*61+30) = (uint64_t)IPW(ip, i*64+31) >> 29;\ +} + +#define BITPACK64_61(ip, op, parm) { \ + BITBLK64_61(ip, 0, op, parm); IPI(ip); op += 61*4/sizeof(op[0]);\ +} + +#define BITBLK64_62(ip, i, op, parm) { ;\ + IP9(ip, i*32+ 0, parm); *((uint64_t *)op+i*31+ 0) = (uint64_t)IPV(ip, i*32+ 0) | (uint64_t)IPX(ip, i*32+1) << 62;\ + IP64(ip, i*32+ 1, parm); *((uint64_t *)op+i*31+ 1) = (uint64_t)IPW(ip, i*32+ 1) >> 2 | (uint64_t)IPX(ip, i*32+2) << 60;\ + IP64(ip, i*32+ 2, parm); *((uint64_t *)op+i*31+ 2) = (uint64_t)IPW(ip, i*32+ 2) >> 4 | (uint64_t)IPX(ip, i*32+3) << 58;\ + IP64(ip, i*32+ 3, parm); *((uint64_t *)op+i*31+ 3) = (uint64_t)IPW(ip, i*32+ 3) >> 6 | (uint64_t)IPX(ip, i*32+4) << 56;\ + IP64(ip, i*32+ 4, parm); *((uint64_t *)op+i*31+ 4) = (uint64_t)IPW(ip, i*32+ 4) >> 8 | (uint64_t)IPX(ip, i*32+5) << 54;\ + IP64(ip, i*32+ 5, parm); *((uint64_t *)op+i*31+ 5) = (uint64_t)IPW(ip, i*32+ 5) >> 10 | (uint64_t)IPX(ip, i*32+6) << 52;\ + IP64(ip, i*32+ 6, parm); *((uint64_t *)op+i*31+ 6) = (uint64_t)IPW(ip, i*32+ 6) >> 12 | (uint64_t)IPX(ip, i*32+7) << 50;\ + IP64(ip, i*32+ 7, parm); *((uint64_t *)op+i*31+ 7) = (uint64_t)IPW(ip, i*32+ 7) >> 14 | (uint64_t)IPX(ip, i*32+8) << 48;\ + IP64(ip, i*32+ 8, parm); *((uint64_t *)op+i*31+ 8) = (uint64_t)IPW(ip, i*32+ 8) >> 16 | (uint64_t)IPX(ip, i*32+9) << 46;\ + IP64(ip, i*32+ 9, parm); *((uint64_t *)op+i*31+ 9) = (uint64_t)IPW(ip, i*32+ 9) >> 18 | (uint64_t)IPX(ip, i*32+10) << 44;\ + IP64(ip, i*32+10, parm); *((uint64_t *)op+i*31+10) = (uint64_t)IPW(ip, i*32+10) >> 20 | (uint64_t)IPX(ip, i*32+11) << 42;\ + IP64(ip, i*32+11, parm); *((uint64_t *)op+i*31+11) = (uint64_t)IPW(ip, i*32+11) >> 22 | (uint64_t)IPX(ip, i*32+12) << 40;\ + IP64(ip, i*32+12, parm); *((uint64_t *)op+i*31+12) = (uint64_t)IPW(ip, i*32+12) >> 24 | (uint64_t)IPX(ip, i*32+13) << 38;\ + IP64(ip, i*32+13, parm); *((uint64_t *)op+i*31+13) = (uint64_t)IPW(ip, i*32+13) >> 26 | (uint64_t)IPX(ip, i*32+14) << 36;\ + IP64(ip, i*32+14, parm); *((uint64_t *)op+i*31+14) = (uint64_t)IPW(ip, i*32+14) >> 28 | (uint64_t)IPX(ip, i*32+15) << 34;\ + IP64(ip, i*32+15, parm); *((uint64_t *)op+i*31+15) = (uint64_t)IPW(ip, i*32+15) >> 30 | (uint64_t)IPX(ip, i*32+16) << 32;\ + IP64(ip, i*32+16, parm); *((uint64_t *)op+i*31+16) = (uint64_t)IPW(ip, i*32+16) >> 32 | (uint64_t)IPX(ip, i*32+17) << 30;\ + IP64(ip, i*32+17, parm); *((uint64_t *)op+i*31+17) = (uint64_t)IPW(ip, i*32+17) >> 34 | (uint64_t)IPX(ip, i*32+18) << 28;\ + IP64(ip, i*32+18, parm); *((uint64_t *)op+i*31+18) = (uint64_t)IPW(ip, i*32+18) >> 36 | (uint64_t)IPX(ip, i*32+19) << 26;\ + IP64(ip, i*32+19, parm); *((uint64_t *)op+i*31+19) = (uint64_t)IPW(ip, i*32+19) >> 38 | (uint64_t)IPX(ip, i*32+20) << 24;\ + IP64(ip, i*32+20, parm); *((uint64_t *)op+i*31+20) = (uint64_t)IPW(ip, i*32+20) >> 40 | (uint64_t)IPX(ip, i*32+21) << 22;\ + IP64(ip, i*32+21, parm); *((uint64_t *)op+i*31+21) = (uint64_t)IPW(ip, i*32+21) >> 42 | (uint64_t)IPX(ip, i*32+22) << 20;\ + IP64(ip, i*32+22, parm); *((uint64_t *)op+i*31+22) = (uint64_t)IPW(ip, i*32+22) >> 44 | (uint64_t)IPX(ip, i*32+23) << 18;\ + IP64(ip, i*32+23, parm); *((uint64_t *)op+i*31+23) = (uint64_t)IPW(ip, i*32+23) >> 46 | (uint64_t)IPX(ip, i*32+24) << 16;\ + IP64(ip, i*32+24, parm); *((uint64_t *)op+i*31+24) = (uint64_t)IPW(ip, i*32+24) >> 48 | (uint64_t)IPX(ip, i*32+25) << 14;\ + IP64(ip, i*32+25, parm); *((uint64_t *)op+i*31+25) = (uint64_t)IPW(ip, i*32+25) >> 50 | (uint64_t)IPX(ip, i*32+26) << 12;\ + IP64(ip, i*32+26, parm); *((uint64_t *)op+i*31+26) = (uint64_t)IPW(ip, i*32+26) >> 52 | (uint64_t)IPX(ip, i*32+27) << 10;\ + IP64(ip, i*32+27, parm); *((uint64_t *)op+i*31+27) = (uint64_t)IPW(ip, i*32+27) >> 54 | (uint64_t)IPX(ip, i*32+28) << 8;\ + IP64(ip, i*32+28, parm); *((uint64_t *)op+i*31+28) = (uint64_t)IPW(ip, i*32+28) >> 56 | (uint64_t)IPX(ip, i*32+29) << 6;\ + IP64(ip, i*32+29, parm); *((uint64_t *)op+i*31+29) = (uint64_t)IPW(ip, i*32+29) >> 58 | (uint64_t)IPX(ip, i*32+30) << 4;\ + IP64(ip, i*32+30, parm); *((uint64_t *)op+i*31+30) = (uint64_t)IPW(ip, i*32+30) >> 60;\ + IP9(ip, i*32+31, parm); *((uint64_t *)op+i*31+30) |= (uint64_t)IPV(ip, i*32+31) << 2;\ +} + +#define BITPACK64_62(ip, op, parm) { \ + BITBLK64_62(ip, 0, op, parm); IPI(ip); op += 62*4/sizeof(op[0]);\ +} + +#define BITBLK64_63(ip, i, op, parm) { ;\ + IP9(ip, i*64+ 0, parm); *((uint64_t *)op+i*63+ 0) = (uint64_t)IPV(ip, i*64+ 0) | (uint64_t)IPX(ip, i*64+1) << 63;\ + IP64(ip, i*64+ 1, parm); *((uint64_t *)op+i*63+ 1) = (uint64_t)IPW(ip, i*64+ 1) >> 1 | (uint64_t)IPX(ip, i*64+2) << 62;\ + IP64(ip, i*64+ 2, parm); *((uint64_t *)op+i*63+ 2) = (uint64_t)IPW(ip, i*64+ 2) >> 2 | (uint64_t)IPX(ip, i*64+3) << 61;\ + IP64(ip, i*64+ 3, parm); *((uint64_t *)op+i*63+ 3) = (uint64_t)IPW(ip, i*64+ 3) >> 3 | (uint64_t)IPX(ip, i*64+4) << 60;\ + IP64(ip, i*64+ 4, parm); *((uint64_t *)op+i*63+ 4) = (uint64_t)IPW(ip, i*64+ 4) >> 4 | (uint64_t)IPX(ip, i*64+5) << 59;\ + IP64(ip, i*64+ 5, parm); *((uint64_t *)op+i*63+ 5) = (uint64_t)IPW(ip, i*64+ 5) >> 5 | (uint64_t)IPX(ip, i*64+6) << 58;\ + IP64(ip, i*64+ 6, parm); *((uint64_t *)op+i*63+ 6) = (uint64_t)IPW(ip, i*64+ 6) >> 6 | (uint64_t)IPX(ip, i*64+7) << 57;\ + IP64(ip, i*64+ 7, parm); *((uint64_t *)op+i*63+ 7) = (uint64_t)IPW(ip, i*64+ 7) >> 7 | (uint64_t)IPX(ip, i*64+8) << 56;\ + IP64(ip, i*64+ 8, parm); *((uint64_t *)op+i*63+ 8) = (uint64_t)IPW(ip, i*64+ 8) >> 8 | (uint64_t)IPX(ip, i*64+9) << 55;\ + IP64(ip, i*64+ 9, parm); *((uint64_t *)op+i*63+ 9) = (uint64_t)IPW(ip, i*64+ 9) >> 9 | (uint64_t)IPX(ip, i*64+10) << 54;\ + IP64(ip, i*64+10, parm); *((uint64_t *)op+i*63+10) = (uint64_t)IPW(ip, i*64+10) >> 10 | (uint64_t)IPX(ip, i*64+11) << 53;\ + IP64(ip, i*64+11, parm); *((uint64_t *)op+i*63+11) = (uint64_t)IPW(ip, i*64+11) >> 11 | (uint64_t)IPX(ip, i*64+12) << 52;\ + IP64(ip, i*64+12, parm); *((uint64_t *)op+i*63+12) = (uint64_t)IPW(ip, i*64+12) >> 12 | (uint64_t)IPX(ip, i*64+13) << 51;\ + IP64(ip, i*64+13, parm); *((uint64_t *)op+i*63+13) = (uint64_t)IPW(ip, i*64+13) >> 13 | (uint64_t)IPX(ip, i*64+14) << 50;\ + IP64(ip, i*64+14, parm); *((uint64_t *)op+i*63+14) = (uint64_t)IPW(ip, i*64+14) >> 14 | (uint64_t)IPX(ip, i*64+15) << 49;\ + IP64(ip, i*64+15, parm); *((uint64_t *)op+i*63+15) = (uint64_t)IPW(ip, i*64+15) >> 15 | (uint64_t)IPX(ip, i*64+16) << 48;\ + IP64(ip, i*64+16, parm); *((uint64_t *)op+i*63+16) = (uint64_t)IPW(ip, i*64+16) >> 16 | (uint64_t)IPX(ip, i*64+17) << 47;\ + IP64(ip, i*64+17, parm); *((uint64_t *)op+i*63+17) = (uint64_t)IPW(ip, i*64+17) >> 17 | (uint64_t)IPX(ip, i*64+18) << 46;\ + IP64(ip, i*64+18, parm); *((uint64_t *)op+i*63+18) = (uint64_t)IPW(ip, i*64+18) >> 18 | (uint64_t)IPX(ip, i*64+19) << 45;\ + IP64(ip, i*64+19, parm); *((uint64_t *)op+i*63+19) = (uint64_t)IPW(ip, i*64+19) >> 19 | (uint64_t)IPX(ip, i*64+20) << 44;\ + IP64(ip, i*64+20, parm); *((uint64_t *)op+i*63+20) = (uint64_t)IPW(ip, i*64+20) >> 20 | (uint64_t)IPX(ip, i*64+21) << 43;\ + IP64(ip, i*64+21, parm); *((uint64_t *)op+i*63+21) = (uint64_t)IPW(ip, i*64+21) >> 21 | (uint64_t)IPX(ip, i*64+22) << 42;\ + IP64(ip, i*64+22, parm); *((uint64_t *)op+i*63+22) = (uint64_t)IPW(ip, i*64+22) >> 22 | (uint64_t)IPX(ip, i*64+23) << 41;\ + IP64(ip, i*64+23, parm); *((uint64_t *)op+i*63+23) = (uint64_t)IPW(ip, i*64+23) >> 23 | (uint64_t)IPX(ip, i*64+24) << 40;\ + IP64(ip, i*64+24, parm); *((uint64_t *)op+i*63+24) = (uint64_t)IPW(ip, i*64+24) >> 24 | (uint64_t)IPX(ip, i*64+25) << 39;\ + IP64(ip, i*64+25, parm); *((uint64_t *)op+i*63+25) = (uint64_t)IPW(ip, i*64+25) >> 25 | (uint64_t)IPX(ip, i*64+26) << 38;\ + IP64(ip, i*64+26, parm); *((uint64_t *)op+i*63+26) = (uint64_t)IPW(ip, i*64+26) >> 26 | (uint64_t)IPX(ip, i*64+27) << 37;\ + IP64(ip, i*64+27, parm); *((uint64_t *)op+i*63+27) = (uint64_t)IPW(ip, i*64+27) >> 27 | (uint64_t)IPX(ip, i*64+28) << 36;\ + IP64(ip, i*64+28, parm); *((uint64_t *)op+i*63+28) = (uint64_t)IPW(ip, i*64+28) >> 28 | (uint64_t)IPX(ip, i*64+29) << 35;\ + IP64(ip, i*64+29, parm); *((uint64_t *)op+i*63+29) = (uint64_t)IPW(ip, i*64+29) >> 29 | (uint64_t)IPX(ip, i*64+30) << 34;\ + IP64(ip, i*64+30, parm); *((uint64_t *)op+i*63+30) = (uint64_t)IPW(ip, i*64+30) >> 30 | (uint64_t)IPX(ip, i*64+31) << 33;\ + IP64(ip, i*64+31, parm); *((uint64_t *)op+i*63+31) = (uint64_t)IPW(ip, i*64+31) >> 31;\ +} + +#define BITPACK64_63(ip, op, parm) { \ + BITBLK64_63(ip, 0, op, parm); IPI(ip); op += 63*4/sizeof(op[0]);\ +} + +#define BITBLK64_64(ip, i, op, parm) { ;\ + IP9(ip, i*1+ 0, parm); *((uint64_t *)op+i*1+ 0) = (uint64_t)IPV(ip, i*1+ 0) ;\ +} + +#define BITPACK64_64(ip, op, parm) { \ + BITBLK64_64(ip, 0, op, parm);\ + BITBLK64_64(ip, 1, op, parm);\ + BITBLK64_64(ip, 2, op, parm);\ + BITBLK64_64(ip, 3, op, parm);\ + BITBLK64_64(ip, 4, op, parm);\ + BITBLK64_64(ip, 5, op, parm);\ + BITBLK64_64(ip, 6, op, parm);\ + BITBLK64_64(ip, 7, op, parm);\ + BITBLK64_64(ip, 8, op, parm);\ + BITBLK64_64(ip, 9, op, parm);\ + BITBLK64_64(ip, 10, op, parm);\ + BITBLK64_64(ip, 11, op, parm);\ + BITBLK64_64(ip, 12, op, parm);\ + BITBLK64_64(ip, 13, op, parm);\ + BITBLK64_64(ip, 14, op, parm);\ + BITBLK64_64(ip, 15, op, parm);\ + BITBLK64_64(ip, 16, op, parm);\ + BITBLK64_64(ip, 17, op, parm);\ + BITBLK64_64(ip, 18, op, parm);\ + BITBLK64_64(ip, 19, op, parm);\ + BITBLK64_64(ip, 20, op, parm);\ + BITBLK64_64(ip, 21, op, parm);\ + BITBLK64_64(ip, 22, op, parm);\ + BITBLK64_64(ip, 23, op, parm);\ + BITBLK64_64(ip, 24, op, parm);\ + BITBLK64_64(ip, 25, op, parm);\ + BITBLK64_64(ip, 26, op, parm);\ + BITBLK64_64(ip, 27, op, parm);\ + BITBLK64_64(ip, 28, op, parm);\ + BITBLK64_64(ip, 29, op, parm);\ + BITBLK64_64(ip, 30, op, parm);\ + BITBLK64_64(ip, 31, op, parm); IPI(ip); op += 64*4/sizeof(op[0]);\ +} + +#ifndef DELTA +#define USIZE 8 +unsigned char *TEMPLATE2(_BITPACK_,8_0)( uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out ) { return out; } +unsigned char *TEMPLATE2(_BITPACK_,8_1)(uint8_t *__restrict in, unsigned n, const unsigned char *__restrict out ) { unsigned char *out_=out+PAD8(n*1); uint8_t v,x;do { BITPACK64_1( in, out, start); PREFETCH(in+512,0); } while(out _csize_) oplen = _csize_; PREFETCH(ip+512,0);\ + b = *ip++; ip = TEMPLATE2(bitunpacka, _usize_)[b](ip, oplen, op);\ + op += oplen;\ + } \ + return ip - in;\ +} + +#define BITNDUNPACK(in, n, out, _csize_, _usize_, _bitunpacka_) { if(!n) return 0;\ + unsigned char *ip = in;\ + TEMPLATE2(vbxget, _usize_)(ip, start);\ + for(*out++ = start,--n,op = out; op != out+(n&~(_csize_-1)); ) { PREFETCH(ip+512,0);\ + unsigned b = *ip++; ip = TEMPLATE2(_bitunpacka_, _usize_)[b](ip, _csize_, op, start); op += _csize_; start = op[-1];\ + } if(n&=(_csize_-1)) { unsigned b = *ip++; ip = TEMPLATE2(_bitunpacka_, _usize_)[b](ip, n, op, start); }\ + return ip - in;\ +} + +size_t bitnunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out) { uint8_t *op; BITNUNPACK(in, n, out, 128, 8); } +size_t bitnunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op; BITNUNPACK(in, n, out, 128, 16); } +size_t bitnunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; BITNUNPACK(in, n, out, 128, 32); } +size_t bitnunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op; BITNUNPACK(in, n, out, 128, 64); } + +size_t bitndunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out) { uint8_t *op,start; BITNDUNPACK(in, n, out, 128, 8, bitdunpacka); } +size_t bitndunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; BITNDUNPACK(in, n, out, 128, 16, bitdunpacka); } +size_t bitndunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; BITNDUNPACK(in, n, out, 128, 32, bitdunpacka); } +size_t bitndunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op,start; BITNDUNPACK(in, n, out, 128, 64, bitdunpacka); } + +size_t bitnd1unpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out) { uint8_t *op,start; BITNDUNPACK(in, n, out, 128, 8, bitd1unpacka); } +size_t bitnd1unpack16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; BITNDUNPACK(in, n, out, 128, 16, bitd1unpacka); } +size_t bitnd1unpack32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; BITNDUNPACK(in, n, out, 128, 32, bitd1unpacka); } +size_t bitnd1unpack64(unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op,start; BITNDUNPACK(in, n, out, 128, 64, bitd1unpacka); } + +size_t bitnzunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out) { uint8_t *op,start; BITNDUNPACK(in, n, out, 128, 8, bitzunpacka); } +size_t bitnzunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; BITNDUNPACK(in, n, out, 128, 16, bitzunpacka); } +size_t bitnzunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; BITNDUNPACK(in, n, out, 128, 32, bitzunpacka); } +size_t bitnzunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op,start; BITNDUNPACK(in, n, out, 128, 64, bitzunpacka); } + +size_t bitnfunpack8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out) { uint8_t *op,start; BITNDUNPACK(in, n, out, 128, 8, bitfunpacka); } +size_t bitnfunpack16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; BITNDUNPACK(in, n, out, 128, 16, bitfunpacka); } +size_t bitnfunpack32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; BITNDUNPACK(in, n, out, 128, 32, bitfunpacka); } +size_t bitnfunpack64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op,start; BITNDUNPACK(in, n, out, 128, 64, bitfunpacka); } + +#else //-------------------------------------------- SSE/AVX2 --------------------------------------------------------------------------------------- + +#define _BITNUNPACKV(in, n, out, _csize_, _usize_, _bitunpackv_) {\ + unsigned char *ip = in;\ + for(op = out; op != out+(n&~(_csize_-1)); op += _csize_) { PREFETCH(in+512,0);\ + unsigned b = *ip++; ip = TEMPLATE2(_bitunpackv_, _usize_)(ip, _csize_, op,b);\ + } if(n&=(_csize_-1)) { unsigned b = *ip++; ip = TEMPLATE2(bitunpack, _usize_)(ip, n, op,b); }\ + return ip - in;\ +} + +#define _BITNDUNPACKV(in, n, out, _csize_, _usize_, _bitunpackv_, _bitunpack_) { if(!n) return 0;\ + unsigned char *ip = in;\ + TEMPLATE2(vbxget, _usize_)(ip, start); \ + *out++ = start;\ + for(--n,op = out; op != out+(n&~(_csize_-1)); ) { PREFETCH(ip+512,0);\ + unsigned b = *ip++; ip = TEMPLATE2(_bitunpackv_, _usize_)(ip, _csize_, op, start,b); op += _csize_; start = op[-1];\ + } if(n&=(_csize_-1)) { unsigned b = *ip++; ip = TEMPLATE2(_bitunpack_, _usize_)(ip, n, op, start,b); }\ + return ip - in;\ +} + #ifdef __AVX2__ //-------------------------------- AVX2 ---------------------------------------------------------------------------- +#include + + #ifdef __AVX512F__ +#define mm256_maskz_expand_epi32(_m_,_v_) _mm256_maskz_expand_epi32(_m_,_v_) +#define mm256_maskz_loadu_epi32( _m_,_v_) _mm256_maskz_loadu_epi32( _m_,_v_) + #else +#if !(defined(_M_X64) || defined(__amd64__)) && (defined(__i386__) || defined(_M_IX86)) +static inline __m128i _mm_cvtsi64_si128(__int64 a) { return _mm_loadl_epi64((__m128i*)&a); } + #endif +static ALIGNED(unsigned char, permv[256][8], 32) = { +0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,1, +1,0,1,1,1,1,1,1, +0,1,2,2,2,2,2,2, +1,1,0,1,1,1,1,1, +0,2,1,2,2,2,2,2, +2,0,1,2,2,2,2,2, +0,1,2,3,3,3,3,3, +1,1,1,0,1,1,1,1, +0,2,2,1,2,2,2,2, +2,0,2,1,2,2,2,2, +0,1,3,2,3,3,3,3, +2,2,0,1,2,2,2,2, +0,3,1,2,3,3,3,3, +3,0,1,2,3,3,3,3, +0,1,2,3,4,4,4,4, +1,1,1,1,0,1,1,1, +0,2,2,2,1,2,2,2, +2,0,2,2,1,2,2,2, +0,1,3,3,2,3,3,3, +2,2,0,2,1,2,2,2, +0,3,1,3,2,3,3,3, +3,0,1,3,2,3,3,3, +0,1,2,4,3,4,4,4, +2,2,2,0,1,2,2,2, +0,3,3,1,2,3,3,3, +3,0,3,1,2,3,3,3, +0,1,4,2,3,4,4,4, +3,3,0,1,2,3,3,3, +0,4,1,2,3,4,4,4, +4,0,1,2,3,4,4,4, +0,1,2,3,4,5,5,5, +1,1,1,1,1,0,1,1, +0,2,2,2,2,1,2,2, +2,0,2,2,2,1,2,2, +0,1,3,3,3,2,3,3, +2,2,0,2,2,1,2,2, +0,3,1,3,3,2,3,3, +3,0,1,3,3,2,3,3, +0,1,2,4,4,3,4,4, +2,2,2,0,2,1,2,2, +0,3,3,1,3,2,3,3, +3,0,3,1,3,2,3,3, +0,1,4,2,4,3,4,4, +3,3,0,1,3,2,3,3, +0,4,1,2,4,3,4,4, +4,0,1,2,4,3,4,4, +0,1,2,3,5,4,5,5, +2,2,2,2,0,1,2,2, +0,3,3,3,1,2,3,3, +3,0,3,3,1,2,3,3, +0,1,4,4,2,3,4,4, +3,3,0,3,1,2,3,3, +0,4,1,4,2,3,4,4, +4,0,1,4,2,3,4,4, +0,1,2,5,3,4,5,5, +3,3,3,0,1,2,3,3, +0,4,4,1,2,3,4,4, +4,0,4,1,2,3,4,4, +0,1,5,2,3,4,5,5, +4,4,0,1,2,3,4,4, +0,5,1,2,3,4,5,5, +5,0,1,2,3,4,5,5, +0,1,2,3,4,5,6,6, +1,1,1,1,1,1,0,1, +0,2,2,2,2,2,1,2, +2,0,2,2,2,2,1,2, +0,1,3,3,3,3,2,3, +2,2,0,2,2,2,1,2, +0,3,1,3,3,3,2,3, +3,0,1,3,3,3,2,3, +0,1,2,4,4,4,3,4, +2,2,2,0,2,2,1,2, +0,3,3,1,3,3,2,3, +3,0,3,1,3,3,2,3, +0,1,4,2,4,4,3,4, +3,3,0,1,3,3,2,3, +0,4,1,2,4,4,3,4, +4,0,1,2,4,4,3,4, +0,1,2,3,5,5,4,5, +2,2,2,2,0,2,1,2, +0,3,3,3,1,3,2,3, +3,0,3,3,1,3,2,3, +0,1,4,4,2,4,3,4, +3,3,0,3,1,3,2,3, +0,4,1,4,2,4,3,4, +4,0,1,4,2,4,3,4, +0,1,2,5,3,5,4,5, +3,3,3,0,1,3,2,3, +0,4,4,1,2,4,3,4, +4,0,4,1,2,4,3,4, +0,1,5,2,3,5,4,5, +4,4,0,1,2,4,3,4, +0,5,1,2,3,5,4,5, +5,0,1,2,3,5,4,5, +0,1,2,3,4,6,5,6, +2,2,2,2,2,0,1,2, +0,3,3,3,3,1,2,3, +3,0,3,3,3,1,2,3, +0,1,4,4,4,2,3,4, +3,3,0,3,3,1,2,3, +0,4,1,4,4,2,3,4, +4,0,1,4,4,2,3,4, +0,1,2,5,5,3,4,5, +3,3,3,0,3,1,2,3, +0,4,4,1,4,2,3,4, +4,0,4,1,4,2,3,4, +0,1,5,2,5,3,4,5, +4,4,0,1,4,2,3,4, +0,5,1,2,5,3,4,5, +5,0,1,2,5,3,4,5, +0,1,2,3,6,4,5,6, +3,3,3,3,0,1,2,3, +0,4,4,4,1,2,3,4, +4,0,4,4,1,2,3,4, +0,1,5,5,2,3,4,5, +4,4,0,4,1,2,3,4, +0,5,1,5,2,3,4,5, +5,0,1,5,2,3,4,5, +0,1,2,6,3,4,5,6, +4,4,4,0,1,2,3,4, +0,5,5,1,2,3,4,5, +5,0,5,1,2,3,4,5, +0,1,6,2,3,4,5,6, +5,5,0,1,2,3,4,5, +0,6,1,2,3,4,5,6, +6,0,1,2,3,4,5,6, +0,1,2,3,4,5,6,7, +1,1,1,1,1,1,1,0, +0,2,2,2,2,2,2,1, +2,0,2,2,2,2,2,1, +0,1,3,3,3,3,3,2, +2,2,0,2,2,2,2,1, +0,3,1,3,3,3,3,2, +3,0,1,3,3,3,3,2, +0,1,2,4,4,4,4,3, +2,2,2,0,2,2,2,1, +0,3,3,1,3,3,3,2, +3,0,3,1,3,3,3,2, +0,1,4,2,4,4,4,3, +3,3,0,1,3,3,3,2, +0,4,1,2,4,4,4,3, +4,0,1,2,4,4,4,3, +0,1,2,3,5,5,5,4, +2,2,2,2,0,2,2,1, +0,3,3,3,1,3,3,2, +3,0,3,3,1,3,3,2, +0,1,4,4,2,4,4,3, +3,3,0,3,1,3,3,2, +0,4,1,4,2,4,4,3, +4,0,1,4,2,4,4,3, +0,1,2,5,3,5,5,4, +3,3,3,0,1,3,3,2, +0,4,4,1,2,4,4,3, +4,0,4,1,2,4,4,3, +0,1,5,2,3,5,5,4, +4,4,0,1,2,4,4,3, +0,5,1,2,3,5,5,4, +5,0,1,2,3,5,5,4, +0,1,2,3,4,6,6,5, +2,2,2,2,2,0,2,1, +0,3,3,3,3,1,3,2, +3,0,3,3,3,1,3,2, +0,1,4,4,4,2,4,3, +3,3,0,3,3,1,3,2, +0,4,1,4,4,2,4,3, +4,0,1,4,4,2,4,3, +0,1,2,5,5,3,5,4, +3,3,3,0,3,1,3,2, +0,4,4,1,4,2,4,3, +4,0,4,1,4,2,4,3, +0,1,5,2,5,3,5,4, +4,4,0,1,4,2,4,3, +0,5,1,2,5,3,5,4, +5,0,1,2,5,3,5,4, +0,1,2,3,6,4,6,5, +3,3,3,3,0,1,3,2, +0,4,4,4,1,2,4,3, +4,0,4,4,1,2,4,3, +0,1,5,5,2,3,5,4, +4,4,0,4,1,2,4,3, +0,5,1,5,2,3,5,4, +5,0,1,5,2,3,5,4, +0,1,2,6,3,4,6,5, +4,4,4,0,1,2,4,3, +0,5,5,1,2,3,5,4, +5,0,5,1,2,3,5,4, +0,1,6,2,3,4,6,5, +5,5,0,1,2,3,5,4, +0,6,1,2,3,4,6,5, +6,0,1,2,3,4,6,5, +0,1,2,3,4,5,7,6, +2,2,2,2,2,2,0,1, +0,3,3,3,3,3,1,2, +3,0,3,3,3,3,1,2, +0,1,4,4,4,4,2,3, +3,3,0,3,3,3,1,2, +0,4,1,4,4,4,2,3, +4,0,1,4,4,4,2,3, +0,1,2,5,5,5,3,4, +3,3,3,0,3,3,1,2, +0,4,4,1,4,4,2,3, +4,0,4,1,4,4,2,3, +0,1,5,2,5,5,3,4, +4,4,0,1,4,4,2,3, +0,5,1,2,5,5,3,4, +5,0,1,2,5,5,3,4, +0,1,2,3,6,6,4,5, +3,3,3,3,0,3,1,2, +0,4,4,4,1,4,2,3, +4,0,4,4,1,4,2,3, +0,1,5,5,2,5,3,4, +4,4,0,4,1,4,2,3, +0,5,1,5,2,5,3,4, +5,0,1,5,2,5,3,4, +0,1,2,6,3,6,4,5, +4,4,4,0,1,4,2,3, +0,5,5,1,2,5,3,4, +5,0,5,1,2,5,3,4, +0,1,6,2,3,6,4,5, +5,5,0,1,2,5,3,4, +0,6,1,2,3,6,4,5, +6,0,1,2,3,6,4,5, +0,1,2,3,4,7,5,6, +3,3,3,3,3,0,1,2, +0,4,4,4,4,1,2,3, +4,0,4,4,4,1,2,3, +0,1,5,5,5,2,3,4, +4,4,0,4,4,1,2,3, +0,5,1,5,5,2,3,4, +5,0,1,5,5,2,3,4, +0,1,2,6,6,3,4,5, +4,4,4,0,4,1,2,3, +0,5,5,1,5,2,3,4, +5,0,5,1,5,2,3,4, +0,1,6,2,6,3,4,5, +5,5,0,1,5,2,3,4, +0,6,1,2,6,3,4,5, +6,0,1,2,6,3,4,5, +0,1,2,3,7,4,5,6, +4,4,4,4,0,1,2,3, +0,5,5,5,1,2,3,4, +5,0,5,5,1,2,3,4, +0,1,6,6,2,3,4,5, +5,5,0,5,1,2,3,4, +0,6,1,6,2,3,4,5, +6,0,1,6,2,3,4,5, +0,1,2,7,3,4,5,6, +5,5,5,0,1,2,3,4, +0,6,6,1,2,3,4,5, +6,0,6,1,2,3,4,5, +0,1,7,2,3,4,5,6, +6,6,0,1,2,3,4,5, +0,7,1,2,3,4,5,6, +7,0,1,2,3,4,5,6, +0,1,2,3,4,5,6,7 +}; +#define u2vmask(_m_,_tv_) _mm256_sllv_epi32(_mm256_set1_epi8(_m_), _tv_) +#define mm256_maskz_expand_epi32(_m_, _v_) _mm256_permutevar8x32_epi32(_v_, _mm256_cvtepu8_epi32(_mm_cvtsi64_si128(ctou64(permv[_m_]))) ) +#define mm256_maskz_loadu_epi32(_m_,_v_) _mm256_blendv_epi8(zv, mm256_maskz_expand_epi32(xm, _mm256_loadu_si256((__m256i*)pex)), u2vmask(xm,tv)) // emulate AVX512 _mm256_maskz_loadu_epi32 on AVX2 + #endif + +//----------------------------------------------------------------------------- +#define VO32( _op_, _i_, ov, _nb_,_parm_) _mm256_storeu_si256(_op_++, ov) +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm256_storeu_si256(_op_++, _parm_) +#include "bitunpack_.h" + +#define BITUNBLK256V32_0(ip, _i_, _op_, _nb_,_parm_) {__m256i ov;\ + VOZ32(_op_, 0, ov, _nb_,_parm_);\ + VOZ32(_op_, 1, ov, _nb_,_parm_);\ + VOZ32(_op_, 2, ov, _nb_,_parm_);\ + VOZ32(_op_, 3, ov, _nb_,_parm_);\ + VOZ32(_op_, 4, ov, _nb_,_parm_);\ + VOZ32(_op_, 5, ov, _nb_,_parm_);\ + VOZ32(_op_, 6, ov, _nb_,_parm_);\ + VOZ32(_op_, 7, ov, _nb_,_parm_);\ + VOZ32(_op_, 8, ov, _nb_,_parm_);\ + VOZ32(_op_, 9, ov, _nb_,_parm_);\ + VOZ32(_op_, 10, ov, _nb_,_parm_);\ + VOZ32(_op_, 11, ov, _nb_,_parm_);\ + VOZ32(_op_, 12, ov, _nb_,_parm_);\ + VOZ32(_op_, 13, ov, _nb_,_parm_);\ + VOZ32(_op_, 14, ov, _nb_,_parm_);\ + VOZ32(_op_, 15, ov, _nb_,_parm_);\ + VOZ32(_op_, 16, ov, _nb_,_parm_);\ + VOZ32(_op_, 17, ov, _nb_,_parm_);\ + VOZ32(_op_, 18, ov, _nb_,_parm_);\ + VOZ32(_op_, 19, ov, _nb_,_parm_);\ + VOZ32(_op_, 20, ov, _nb_,_parm_);\ + VOZ32(_op_, 21, ov, _nb_,_parm_);\ + VOZ32(_op_, 22, ov, _nb_,_parm_);\ + VOZ32(_op_, 23, ov, _nb_,_parm_);\ + VOZ32(_op_, 24, ov, _nb_,_parm_);\ + VOZ32(_op_, 25, ov, _nb_,_parm_);\ + VOZ32(_op_, 26, ov, _nb_,_parm_);\ + VOZ32(_op_, 27, ov, _nb_,_parm_);\ + VOZ32(_op_, 28, ov, _nb_,_parm_);\ + VOZ32(_op_, 29, ov, _nb_,_parm_);\ + VOZ32(_op_, 30, ov, _nb_,_parm_);\ + VOZ32(_op_, 31, ov, _nb_,_parm_);\ +} +#define BITUNPACK0(_parm_) _parm_ = _mm256_setzero_si256() + +unsigned char *bitunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + __m256i sv; + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +//--------------------------------------- zeromask unpack for TurboPFor vp4d.c -------------------------------------- +#define VO32(_op_, _i_, _ov_, _nb_,_parm_) xm = *bb++; _mm256_storeu_si256(_op_++, _mm256_add_epi32(_ov_, _mm256_slli_epi32(mm256_maskz_loadu_epi32(xm,(__m256i*)pex), _nb_) )); pex += popcnt32(xm) +#define VOZ32(_op_, _i_, _ov_, _nb_,_parm_) xm = *bb++; _mm256_storeu_si256(_op_++, mm256_maskz_loadu_epi32(xm,(__m256i*)pex) ); pex += popcnt32(xm) +#define BITUNPACK0(_parm_) +#include "bitunpack_.h" +unsigned char *_bitunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(256*b); unsigned xm; __m256i sv, zv = _mm256_setzero_si256(), tv = _mm256_set_epi32(0,1,2,3,4,5,6,7); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm256_storeu_si256(_op_++, _parm_) +#define VO32(_op_, i, _ov_, _nb_,_sv_) _ov_ = mm256_zzagd_epi32(_ov_); _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitzunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + __m256i sv = _mm256_set1_epi32(start);//, zv = _mm256_setzero_si256(); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + + +#define VO32(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitdunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + __m256i sv = _mm256_set1_epi32(start);// zv = _mm256_setzero_si256(); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VO32( _op_, _i_, _ov_, _nb_,_parm_) _mm256_storeu_si256(_op_++, _mm256_add_epi32(_ov_, sv)) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitfunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + __m256i sv = _mm256_set1_epi32(start); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} +//----------------------------------------------------------------------------- +#define VX32(_i_, _nb_,_ov_) xm = *bb++; _ov_ = _mm256_add_epi32(_ov_, _mm256_slli_epi32(mm256_maskz_loadu_epi32(xm,(__m256i*)pex), _nb_) ); pex += popcnt32(xm) +#define VXZ32(_i_, _nb_,_ov_) xm = *bb++; _ov_ = mm256_maskz_loadu_epi32(xm,(__m256i*)pex); pex += popcnt32(xm) + +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *_bitdunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(256*b); unsigned xm; + __m256i sv = _mm256_set1_epi32(start), tv = _mm256_set_epi32(0,1,2,3,4,5,6,7),zv = _mm256_setzero_si256(); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VX32(_i_, _nb_,_ov_) xm = *bb++; _ov_ = _mm256_add_epi32(_ov_, _mm256_slli_epi32(mm256_maskz_loadu_epi32(xm,(__m256i*)pex), _nb_) ); pex += popcnt32(xm) +#define VXZ32(_i_, _nb_,_ov_) xm = *bb++; _ov_ = mm256_maskz_loadu_epi32(xm,(__m256i*)pex); pex += popcnt32(xm) + + #ifdef _MSC_VER +#define SCAN32x8( _v_, _sv_) {\ + _v_ = _mm256_add_epi32(_v_, _mm256_slli_si256(_v_, 4));\ + _v_ = _mm256_add_epi32(_v_, _mm256_slli_si256(_v_, 8));\ + _sv_ = _mm256_add_epi32( _mm256_permute2x128_si256( _mm256_shuffle_epi32(_sv_,_MM_SHUFFLE(3, 3, 3, 3)), _sv_, 0x11), \ + _mm256_add_epi32(_v_, _mm256_permute2x128_si256(zv,_mm256_shuffle_epi32(_v_, _MM_SHUFFLE(3, 3, 3, 3)), 0x20)));\ +} +#define SCANI32x8(_v_, _sv_, _vi_) SCAN32x8(_v_, _sv_); _sv_ = _mm256_add_epi32(_sv_, _vi_) +#define ZIGZAG32x8(_v_) _mm256_xor_si256(_mm256_slli_epi32(_v_,1), _mm256_srai_epi32(_v_,31)) +#define UNZIGZAG32x8(_v_) _mm256_xor_si256(_mm256_srli_epi32(_v_,1), _mm256_srai_epi32(_mm256_slli_epi32(_v_,31),31) ) + +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _ov_ = UNZIGZAG32x8(_ov_); SCAN32x8(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _ov_ = UNZIGZAG32x8(_ov_); SCAN32x8(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); + #else +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _ov_ = mm256_zzagd_epi32(_ov_); _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _ov_ = mm256_zzagd_epi32(_ov_); _sv_ = mm256_scan_epi32(_ov_,_sv_); _mm256_storeu_si256(_op_++, _sv_); + #endif + +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *_bitzunpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(256*b); + unsigned xm; + const __m256i zv = _mm256_setzero_si256(), tv = _mm256_set_epi32(0,1,2,3,4,5,6,7); + __m256i sv = _mm256_set1_epi32(start); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VO32(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm256_scani_epi32(_ov_,_sv_,cv); _mm256_storeu_si256(_op_++, _sv_); +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm256_storeu_si256(_op_++, _parm_); _parm_ = _mm256_add_epi32(_parm_, cv) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) _parm_ = _mm256_add_epi32(_parm_, cv); cv = _mm256_set1_epi32(8) +unsigned char *bitd1unpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + const __m256i zv = _mm256_setzero_si256(); + __m256i sv = _mm256_set1_epi32(start), cv = _mm256_set_epi32(8,7,6,5,4,3,2,1); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) _mm256_storeu_si256(_op_++, _mm256_add_epi32(_ov_, _sv_)); _sv_ = _mm256_add_epi32(_sv_, cv) +#define VOZ32(_op_, _i_, ov, _nb_,_sv_) _mm256_storeu_si256(_op_++, _sv_); _sv_ = _mm256_add_epi32(_sv_, cv); +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitf1unpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(256*b); + const __m256i cv = _mm256_set1_epi32(8); + __m256i sv = _mm256_set_epi32(start+8,start+7,start+6,start+5,start+4,start+3,start+2,start+1); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _sv_ = mm256_scani_epi32(_ov_,_sv_,cv); _mm256_storeu_si256(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _sv_ = mm256_scani_epi32(_ov_,_sv_,cv); _mm256_storeu_si256(_op_++, _sv_); +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) mv = _mm256_set1_epi32(0) //_parm_ = _mm_setzero_si128() +unsigned char *_bitd1unpack256v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(256*b); unsigned xm; + const __m256i cv = _mm256_set_epi32(8,7,6,5,4,3,2,1), zv = _mm256_setzero_si256(), tv = _mm256_set_epi32(0,1,2,3,4,5,6,7); + __m256i sv = _mm256_set1_epi32(start); + BITUNPACK256V32(in, b, out, sv); + return (unsigned char *)ip; +} + +size_t bitnunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _BITNUNPACKV( in, n, out, 256, 32, bitunpack256v); } +size_t bitndunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 256, 32, bitdunpack256v, bitdunpack); } +size_t bitnd1unpack256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 256, 32, bitd1unpack256v, bitd1unpack); } +//size_t bitns1unpack256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 256, 32, bits1unpack256v, bitd1unpack); } +size_t bitnzunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 256, 32, bitzunpack256v, bitzunpack); } +size_t bitnfunpack256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 256, 32, bitfunpack256v, bitfunpack); } + #elif defined(__SSE2__) || defined(__ARM_NEON) //------------------------------ SSE2/SSSE3 --------------------------------------------------------- +#define BITMAX16 16 +#define BITMAX32 32 + +#define VO16( _op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, ov) +#define VO32( _op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, ov) +#include "bitunpack_.h" + +#define VOZ16(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_) +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_) +#define BITUNBLK128V16_0(ip, _i_, _op_, _nb_,_parm_) {__m128i ov;\ + VOZ16(_op_, 0, ov, _nb_,_parm_);\ + VOZ16(_op_, 1, ov, _nb_,_parm_);\ + VOZ16(_op_, 2, ov, _nb_,_parm_);\ + VOZ16(_op_, 3, ov, _nb_,_parm_);\ + VOZ16(_op_, 4, ov, _nb_,_parm_);\ + VOZ16(_op_, 5, ov, _nb_,_parm_);\ + VOZ16(_op_, 6, ov, _nb_,_parm_);\ + VOZ16(_op_, 7, ov, _nb_,_parm_);\ + VOZ16(_op_, 8, ov, _nb_,_parm_);\ + VOZ16(_op_, 9, ov, _nb_,_parm_);\ + VOZ16(_op_, 10, ov, _nb_,_parm_);\ + VOZ16(_op_, 11, ov, _nb_,_parm_);\ + VOZ16(_op_, 12, ov, _nb_,_parm_);\ + VOZ16(_op_, 13, ov, _nb_,_parm_);\ + VOZ16(_op_, 14, ov, _nb_,_parm_);\ + VOZ16(_op_, 15, ov, _nb_,_parm_);\ + /*VOZ16(_op_, 16, ov, _nb_,_parm_);\ + VOZ16(_op_, 17, ov, _nb_,_parm_);\ + VOZ16(_op_, 18, ov, _nb_,_parm_);\ + VOZ16(_op_, 19, ov, _nb_,_parm_);\ + VOZ16(_op_, 20, ov, _nb_,_parm_);\ + VOZ16(_op_, 21, ov, _nb_,_parm_);\ + VOZ16(_op_, 22, ov, _nb_,_parm_);\ + VOZ16(_op_, 23, ov, _nb_,_parm_);\ + VOZ16(_op_, 24, ov, _nb_,_parm_);\ + VOZ16(_op_, 25, ov, _nb_,_parm_);\ + VOZ16(_op_, 26, ov, _nb_,_parm_);\ + VOZ16(_op_, 27, ov, _nb_,_parm_);\ + VOZ16(_op_, 28, ov, _nb_,_parm_);\ + VOZ16(_op_, 29, ov, _nb_,_parm_);\ + VOZ16(_op_, 30, ov, _nb_,_parm_);\ + VOZ16(_op_, 31, ov, _nb_,_parm_);*/\ +} + +#define BITUNBLK128V32_0(ip, _i_, _op_, _nb_,_parm_) {__m128i ov;\ + VOZ32(_op_, 0, ov, _nb_,_parm_);\ + VOZ32(_op_, 1, ov, _nb_,_parm_);\ + VOZ32(_op_, 2, ov, _nb_,_parm_);\ + VOZ32(_op_, 3, ov, _nb_,_parm_);\ + VOZ32(_op_, 4, ov, _nb_,_parm_);\ + VOZ32(_op_, 5, ov, _nb_,_parm_);\ + VOZ32(_op_, 6, ov, _nb_,_parm_);\ + VOZ32(_op_, 7, ov, _nb_,_parm_);\ + VOZ32(_op_, 8, ov, _nb_,_parm_);\ + VOZ32(_op_, 9, ov, _nb_,_parm_);\ + VOZ32(_op_, 10, ov, _nb_,_parm_);\ + VOZ32(_op_, 11, ov, _nb_,_parm_);\ + VOZ32(_op_, 12, ov, _nb_,_parm_);\ + VOZ32(_op_, 13, ov, _nb_,_parm_);\ + VOZ32(_op_, 14, ov, _nb_,_parm_);\ + VOZ32(_op_, 15, ov, _nb_,_parm_);\ + VOZ32(_op_, 16, ov, _nb_,_parm_);\ + VOZ32(_op_, 17, ov, _nb_,_parm_);\ + VOZ32(_op_, 18, ov, _nb_,_parm_);\ + VOZ32(_op_, 19, ov, _nb_,_parm_);\ + VOZ32(_op_, 20, ov, _nb_,_parm_);\ + VOZ32(_op_, 21, ov, _nb_,_parm_);\ + VOZ32(_op_, 22, ov, _nb_,_parm_);\ + VOZ32(_op_, 23, ov, _nb_,_parm_);\ + VOZ32(_op_, 24, ov, _nb_,_parm_);\ + VOZ32(_op_, 25, ov, _nb_,_parm_);\ + VOZ32(_op_, 26, ov, _nb_,_parm_);\ + VOZ32(_op_, 27, ov, _nb_,_parm_);\ + VOZ32(_op_, 28, ov, _nb_,_parm_);\ + VOZ32(_op_, 29, ov, _nb_,_parm_);\ + VOZ32(_op_, 30, ov, _nb_,_parm_);\ + VOZ32(_op_, 31, ov, _nb_,_parm_);\ +} +#define BITUNPACK0(_parm_) _parm_ = _mm_setzero_si128() + +unsigned char *bitunpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned b) { const unsigned char *ip = in+PAD8(128*b); __m128i sv; BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; } +unsigned char *bitunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b) { const unsigned char *ip = in+PAD8(128*b); __m128i sv; BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; } +unsigned char *bitunpack256w32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b) { + const unsigned char *_in=in; unsigned *_out=out; __m128i sv; + BITUNPACK128V32(in, b, out, sv); out = _out+128; in=_in+PAD8(128*b); + BITUNPACK128V32(in, b, out, sv); + return (unsigned char *)_in+PAD8(256*b); +} + +#define STOZ64(_op_, _ov_) _mm_storeu_si128(_op_++, _ov_); _mm_storeu_si128(_op_++, _ov_) +#define STO64( _op_, _ov_, _zv_) _mm_storeu_si128(_op_++, _mm_unpacklo_epi32(_ov_,_zv_));_mm_storeu_si128(_op_++, _mm_unpacklo_epi32(_mm_srli_si128(_ov_,8),_zv_)) + +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) STOZ64(_op_, _parm_) +#define VO32( _op_, _i_, ov, _nb_,_parm_) STO64(_op_, ov, zv) +#include "bitunpack_.h" +unsigned char *bitunpack128v64( const unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b) { + if(b <= 32) { const unsigned char *ip = in+PAD8(128*b); + __m128i sv,zv = _mm_setzero_si128(); + BITUNPACK128V32(in, b, out, sv); + return (unsigned char *)ip; + } else return bitunpack64(in,n,out,b); +} +#undef VO32 +#undef VOZ32 +#undef VO16 +#undef VOZ16 +#undef BITUNPACK0 + + #if defined(__SSSE3__) || defined(__ARM_NEON) + #define _ 0x80 +ALIGNED(char, _shuffle_32[16][16],16) = { + { _,_,_,_, _,_,_,_, _,_, _, _, _, _, _,_ }, + { 0,1,2,3, _,_,_,_, _,_, _, _, _, _, _,_ }, + { _,_,_,_, 0,1,2,3, _,_, _, _, _, _, _,_ }, + { 0,1,2,3, 4,5,6,7, _,_, _, _, _, _, _,_ }, + { _,_,_,_, _,_,_,_, 0,1, 2, 3, _, _, _,_ }, + { 0,1,2,3, _,_,_,_, 4,5, 6, 7, _, _, _,_ }, + { _,_,_,_, 0,1,2,3, 4,5, 6, 7, _, _, _,_ }, + { 0,1,2,3, 4,5,6,7, 8,9,10,11, _, _, _,_ }, + { _,_,_,_, _,_,_,_, _,_,_,_, 0, 1, 2, 3 }, + { 0,1,2,3, _,_,_,_, _,_,_, _, 4, 5, 6, 7 }, + { _,_,_,_, 0,1,2,3, _,_,_, _, 4, 5, 6, 7 }, + { 0,1,2,3, 4,5,6,7, _,_, _, _, 8, 9,10,11 }, + { _,_,_,_, _,_,_,_, 0,1, 2, 3, 4, 5, 6, 7 }, + { 0,1,2,3, _,_,_,_, 4,5, 6, 7, 8, 9,10,11 }, + { _,_,_,_, 0,1,2,3, 4,5, 6, 7, 8, 9,10,11 }, + { 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 }, +}; +ALIGNED(char, _shuffle_16[256][16],16) = { + { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ }, + { 0, 1, _, _, _, _, _, _, _, _, _, _, _, _, _, _ }, + { _, _, 0, 1, _, _, _, _, _, _, _, _, _, _, _, _ }, + { 0, 1, 2, 3, _, _, _, _, _, _, _, _, _, _, _, _ }, + { _, _, _, _, 0, 1, _, _, _, _, _, _, _, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, _, _, _, _, _, _, _, _ }, + { _, _, 0, 1, 2, 3, _, _, _, _, _, _, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, _, _, _, _ }, + { _, _, _, _, _, _, 0, 1, _, _, _, _, _, _, _, _ }, + { 0, 1, _, _, _, _, 2, 3, _, _, _, _, _, _, _, _ }, + { _, _, 0, 1, _, _, 2, 3, _, _, _, _, _, _, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, _, _, _, _ }, + { _, _, _, _, 0, 1, 2, 3, _, _, _, _, _, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, _, _, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, _, _, _, _ }, + { _, _, _, _, _, _, _, _, 0, 1, _, _, _, _, _, _ }, + { 0, 1, _, _, _, _, _, _, 2, 3, _, _, _, _, _, _ }, + { _, _, 0, 1, _, _, _, _, 2, 3, _, _, _, _, _, _ }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, _, _, _, _ }, + { _, _, _, _, 0, 1, _, _, 2, 3, _, _, _, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, _, _, _, _ }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, _, _, _, _ }, + { _, _, _, _, _, _, 0, 1, 2, 3, _, _, _, _, _, _ }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, _, _, _, _ }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, _, _, _, _ }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, _, _, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _, _, _, _, _ }, + { _, _, _, _, _, _, _, _, _, _, 0, 1, _, _, _, _ }, + { 0, 1, _, _, _, _, _, _, _, _, 2, 3, _, _, _, _ }, + { _, _, 0, 1, _, _, _, _, _, _, 2, 3, _, _, _, _ }, + { 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, _, _, _, _ }, + { _, _, _, _, 0, 1, _, _, _, _, 2, 3, _, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, _, _, _, _ }, + { _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, _, _, _, _ }, + { _, _, _, _, _, _, 0, 1, _, _, 2, 3, _, _, _, _ }, + { 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, _, _, _, _ }, + { _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, _, _, _, _ }, + { _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, _, _, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9, _, _, _, _ }, + { _, _, _, _, _, _, _, _, 0, 1, 2, 3, _, _, _, _ }, + { 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, _, _, _, _ }, + { _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, _, _ }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, _, _, _, _ }, + { _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, _, _, _, _ }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9, _, _, _, _ }, + { _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, _, _ }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, _, _, _, _ }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9, _, _, _, _ }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9, _, _, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _, _, _, _ }, + { _, _, _, _, _, _, _, _, _, _, _, _, 0, 1, _, _ }, + { 0, 1, _, _, _, _, _, _, _, _, _, _, 2, 3, _, _ }, + { _, _, 0, 1, _, _, _, _, _, _, _, _, 2, 3, _, _ }, + { 0, 1, 2, 3, _, _, _, _, _, _, _, _, 4, 5, _, _ }, + { _, _, _, _, 0, 1, _, _, _, _, _, _, 2, 3, _, _ }, + { 0, 1, _, _, 2, 3, _, _, _, _, _, _, 4, 5, _, _ }, + { _, _, 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, 6, 7, _, _ }, + { _, _, _, _, _, _, 0, 1, _, _, _, _, 2, 3, _, _ }, + { 0, 1, _, _, _, _, 2, 3, _, _, _, _, 4, 5, _, _ }, + { _, _, 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, 6, 7, _, _ }, + { _, _, _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, 6, 7, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, 8, 9, _, _ }, + { _, _, _, _, _, _, _, _, 0, 1, _, _, 2, 3, _, _ }, + { 0, 1, _, _, _, _, _, _, 2, 3, _, _, 4, 5, _, _ }, + { _, _, 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, _, _ }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, 6, 7, _, _ }, + { _, _, _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7, _, _ }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9, _, _ }, + { _, _, _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, _, _ }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, 6, 7, _, _ }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, 8, 9, _, _ }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11, _, _ }, + { _, _, _, _, _, _, _, _, _, _, 0, 1, 2, 3, _, _ }, + { 0, 1, _, _, _, _, _, _, _, _, 2, 3, 4, 5, _, _ }, + { _, _, 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, _, _ }, + { 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, 6, 7, _, _ }, + { _, _, _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, _, _ }, + { 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, 6, 7, _, _ }, + { _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, 8, 9, _, _ }, + { _, _, _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, _, _ }, + { 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, 6, 7, _, _ }, + { _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, 9, _, _ }, + { _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, 8, 9, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10,11, _, _ }, + { _, _, _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, _, _ }, + { 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, 6, 7, _, _ }, + { _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, _, _ }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, 8, 9, _, _ }, + { _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9, _, _ }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11, _, _ }, + { _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _ }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, 8, 9, _, _ }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10,11, _, _ }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _, _ }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, _, _ }, + { _, _, _, _, _, _, _, _, _, _, _, _, _, _, 0, 1 }, + { 0, 1, _, _, _, _, _, _, _, _, _, _, _, _, 2, 3 }, + { _, _, 0, 1, _, _, _, _, _, _, _, _, _, _, 2, 3 }, + { 0, 1, 2, 3, _, _, _, _, _, _, _, _, _, _, 4, 5 }, + { _, _, _, _, 0, 1, _, _, _, _, _, _, _, _, 2, 3 }, + { 0, 1, _, _, 2, 3, _, _, _, _, _, _, _, _, 4, 5 }, + { _, _, 0, 1, 2, 3, _, _, _, _, _, _, _, _, 4, 5 }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, _, _, 6, 7 }, + { _, _, _, _, _, _, 0, 1, _, _, _, _, _, _, 2, 3 }, + { 0, 1, _, _, _, _, 2, 3, _, _, _, _, _, _, 4, 5 }, + { _, _, 0, 1, _, _, 2, 3, _, _, _, _, _, _, 4, 5 }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, _, _, 6, 7 }, + { _, _, _, _, 0, 1, 2, 3, _, _, _, _, _, _, 4, 5 }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, _, _, 6, 7 }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, 6, 7 }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, _, _, 8, 9 }, + { _, _, _, _, _, _, _, _, 0, 1, _, _, _, _, 2, 3 }, + { 0, 1, _, _, _, _, _, _, 2, 3, _, _, _, _, 4, 5 }, + { _, _, 0, 1, _, _, _, _, 2, 3, _, _, _, _, 4, 5 }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, _, _, 6, 7 }, + { _, _, _, _, 0, 1, _, _, 2, 3, _, _, _, _, 4, 5 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, _, _, 6, 7 }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, 6, 7 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, _, _, 8, 9 }, + { _, _, _, _, _, _, 0, 1, 2, 3, _, _, _, _, 4, 5 }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, _, _, 6, 7 }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, 6, 7 }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, _, _, 8, 9 }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, _, _, 8, 9 }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, 8, 9 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _, _, _,10,11 }, + { _, _, _, _, _, _, _, _, _, _, 0, 1, _, _, 2, 3 }, + { 0, 1, _, _, _, _, _, _, _, _, 2, 3, _, _, 4, 5 }, + { _, _, 0, 1, _, _, _, _, _, _, 2, 3, _, _, 4, 5 }, + { 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, _, _, 6, 7 }, + { _, _, _, _, 0, 1, _, _, _, _, 2, 3, _, _, 4, 5 }, + { 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, _, _, 6, 7 }, + { _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, 6, 7 }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, _, _, 8, 9 }, + { _, _, _, _, _, _, 0, 1, _, _, 2, 3, _, _, 4, 5 }, + { 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7 }, + { _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7 }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, _, _, 8, 9 }, + { _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7 }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9 }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9 }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9, _, _,10,11 }, + { _, _, _, _, _, _, _, _, 0, 1, 2, 3, _, _, 4, 5 }, + { 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, _, _, 6, 7 }, + { _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, 6, 7 }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, _, _, 8, 9 }, + { _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, _, _, 8, 9 }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, 8, 9 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9, _, _,10,11 }, + { _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7 }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9 }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9 }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9, _, _,10,11 }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11 }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _, _,12,13 }, + { _, _, _, _, _, _, _, _, _, _, _, _, 0, 1, 2, 3 }, + { 0, 1, _, _, _, _, _, _, _, _, _, _, 2, 3, 4, 5 }, + { _, _, 0, 1, _, _, _, _, _, _, _, _, 2, 3, 4, 5 }, + { 0, 1, 2, 3, _, _, _, _, _, _, _, _, 4, 5, 6, 7 }, + { _, _, _, _, 0, 1, _, _, _, _, _, _, 2, 3, 4, 5 }, + { 0, 1, _, _, 2, 3, _, _, _, _, _, _, 4, 5, 6, 7 }, + { _, _, 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, 6, 7 }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, _, _, 6, 7, 8, 9 }, + { _, _, _, _, _, _, 0, 1, _, _, _, _, 2, 3, 4, 5 }, + { 0, 1, _, _, _, _, 2, 3, _, _, _, _, 4, 5, 6, 7 }, + { _, _, 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, 6, 7 }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, _, _, 6, 7, 8, 9 }, + { _, _, _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7 }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, _, _, 6, 7, 8, 9 }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, _, _, 8, 9,10,11 }, + { _, _, _, _, _, _, _, _, 0, 1, _, _, 2, 3, 4, 5 }, + { 0, 1, _, _, _, _, _, _, 2, 3, _, _, 4, 5, 6, 7 }, + { _, _, 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, 6, 7 }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, _, _, 6, 7, 8, 9 }, + { _, _, _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, 9 }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9,10,11 }, + { _, _, _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7 }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, _, _, 6, 7, 8, 9 }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, _, _, 8, 9,10,11 }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10,11 }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11,12,13 }, + { _, _, _, _, _, _, _, _, _, _, 0, 1, 2, 3, 4, 5 }, + { 0, 1, _, _, _, _, _, _, _, _, 2, 3, 4, 5, 6, 7 }, + { _, _, 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, 6, 7 }, + { 0, 1, 2, 3, _, _, _, _, _, _, 4, 5, 6, 7, 8, 9 }, + { _, _, _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7 }, + { 0, 1, _, _, 2, 3, _, _, _, _, 4, 5, 6, 7, 8, 9 }, + { _, _, 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, 8, 9 }, + { 0, 1, 2, 3, 4, 5, _, _, _, _, 6, 7, 8, 9,10,11 }, + { _, _, _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7 }, + { 0, 1, _, _, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9 }, + { _, _, 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9 }, + { 0, 1, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, 9,10,11 }, + { _, _, _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11 }, + { _, _, 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10,11,12,13 }, + { _, _, _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7 }, + { 0, 1, _, _, _, _, _, _, 2, 3, 4, 5, 6, 7, 8, 9 }, + { _, _, 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 0, 1, 2, 3, _, _, _, _, 4, 5, 6, 7, 8, 9,10,11 }, + { _, _, _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10,11 }, + { _, _, 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11,12,13 }, + { _, _, _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 0, 1, _, _, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, + { _, _, 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10,11,12,13 }, + { _, _, _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13 }, + { _, _, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 }, +}; + #undef _ + #endif // SSSE3 + +#define BITMAX16 15 +#define BITMAX32 31 + +#define VO16( _op_, _i_, _ov_, _nb_,_parm_) m = *bb++; _mm_storeu_si128(_op_++, _mm_add_epi16(_ov_, _mm_shuffle_epi8( mm_slli_epi16(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ) )); pex += popcnt32(m) +#define VO32( _op_, _i_, _ov_, _nb_,_parm_) if((_i_) & 1) m = (*bb++) >> 4; else m = (*bb) & 0xf; _mm_storeu_si128(_op_++, _mm_add_epi32(_ov_, _mm_shuffle_epi8( mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ) )); pex += popcnt32(m) +#define VOZ16(_op_, _i_, _ov_, _nb_,_parm_) m = *bb++; _mm_storeu_si128(_op_++, _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ) ); pex += popcnt32(m) +#define VOZ32(_op_, _i_, _ov_, _nb_,_parm_) if((_i_) & 1) m = (*bb++) >> 4; else m = (*bb) & 0xf; _mm_storeu_si128(_op_++, _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ) ); pex += popcnt32(m) +#define BITUNPACK0(_parm_) //_parm_ = _mm_setzero_si128() +#include "bitunpack_.h" + +unsigned char *_bitunpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned b, unsigned short *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv; BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *_bitunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv; BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *_bitunpack256w32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *_in=in; unsigned *_out=out, m; __m128i sv; + BITUNPACK128V32(in, b, out, sv); out = _out+128; in=_in+PAD8(128*b); + BITUNPACK128V32(in, b, out, sv); + return (unsigned char *)_in+PAD8(256*b); +} + +//#define STOZ64(_op_, _ov_) _mm_storeu_si128(_op_++, _ov_); _mm_storeu_si128(_op_++, _ov_) +#define STO64( _op_, _ov_, _zv_) _mm_storeu_si128(_op_++, _mm_unpacklo_epi32(_ov_,_zv_));_mm_storeu_si128(_op_++, _mm_unpacklo_epi32(_mm_srli_si128(_ov_,8),_zv_)) + +#define VO32( _op_, _i_, _ov_, _nb_,_parm_) if((_i_) & 1) m = (*bb++) >> 4; else m = (*bb) & 0xf; { __m128i _wv = _mm_add_epi32(_ov_, _mm_shuffle_epi8( mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ) ); STO64(_op_, _wv, zv);} pex += popcnt32(m) +#define VOZ32(_op_, _i_, _ov_, _nb_,_parm_) if((_i_) & 1) m = (*bb++) >> 4; else m = (*bb) & 0xf; { __m128i _wv = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ) ; STO64(_op_, _wv, zv);} pex += popcnt32(m) +#define BITUNPACK0(_parm_) + +#include "bitunpack_.h" +unsigned char *_bitunpack128v64( const unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b, uint32_t *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i zv = _mm_setzero_si128(); BITUNPACK128V32(in, b, out, 0); return (unsigned char *)ip; +} + +#define BITMAX16 16 +#define BITMAX32 32 + +#undef VO32 +#undef VOZ32 +#undef VO16 +#undef VOZ16 +#undef BITUNPACK0 + +//------------------------------------------------------------------- +#define VOZ16(_op_, _i_, _ov_, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_) +#define VOZ32(_op_, _i_, _ov_, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_) +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) _ov_ = mm_zzagd_epi16(_ov_); _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_) +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) _ov_ = mm_zzagd_epi32(_ov_); _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitzunpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi16(start); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *bitzunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi32(start); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +#define VO32(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_) +#define VO16(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitdunpack128v16( const unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi16(start); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *bitdunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi32(start); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +#define VO32( _op_, _i_, _ov_, _nb_,_parm_) _mm_storeu_si128(_op_++, _mm_add_epi32(_ov_, sv)) +#define VO16( _op_, _i_, _ov_, _nb_,_parm_) _mm_storeu_si128(_op_++, _mm_add_epi16(_ov_, sv)) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitfunpack128v16( const unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi16(start); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *bitfunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi32(start); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + + #if defined(__SSSE3__) || defined(__ARM_NEON) +#define BITMAX16 15 +#define BITMAX32 31 + +#define VX32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_add_epi32(_ov_, _mm_shuffle_epi8( mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_32[m]))); pex += popcnt32(m) +#define VXZ32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_32[m])); pex += popcnt32(m) +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); + +#define VX16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_add_epi16(_ov_, _mm_shuffle_epi8( mm_slli_epi16(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ) ); pex += popcnt32(m) +#define VXZ16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ); pex += popcnt32(m) +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) VX16( _i_, _nb_,_ov_); _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, _ov_, _nb_,_sv_) VXZ16( _i_, _nb_,_ov_); _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *_bitdunpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b, unsigned short *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi16(start); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *_bitdunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi32(start); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +/* +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _ov_); mm_scan_epi32(_ov_,_sv_); STO64( _op_, _sv_) //_mm_storeu_si128(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32( _i_, _ov_); mm_scan_epi32(_ov_,_sv_); STOZ64( _op_, _sv_, zv) //_mm_storeu_si128(_op_++, _sv_); +unsigned char *_bitdunpack128v64( const unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, uint64_t *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi32(start),zv = _mm_setzero_si128(); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +}*/ + +#define VX16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_add_epi16(_ov_, _mm_shuffle_epi8( mm_slli_epi16(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ) ); pex += popcnt32(m) +#define VXZ16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_16[m]) ); pex += popcnt32(m) +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) VX16( _i_, _nb_,_ov_); _ov_ = mm_zzagd_epi16(_ov_); _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, _ov_, _nb_,_sv_) VXZ16( _i_, _nb_,_ov_); _ov_ = mm_zzagd_epi16(_ov_); _sv_ = mm_scan_epi16(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); + +#define VX32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_add_epi32(_ov_, _mm_shuffle_epi8( mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ) ); pex += popcnt32(m) +#define VXZ32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_32[m]) ); pex += popcnt32(m) +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _ov_ = mm_zzagd_epi32(_ov_); _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32(_i_, _nb_,_ov_); _ov_ = mm_zzagd_epi32(_ov_); _sv_ = mm_scan_epi32(_ov_,_sv_); _mm_storeu_si128(_op_++, _sv_); + +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *_bitzunpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b, unsigned short *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi16(start); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *_bitzunpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi32(start); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} +#define BITMAX16 16 +#define BITMAX32 32 + #endif + +#define VO16(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm_scani_epi16(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VO32(_op_, i, _ov_, _nb_,_sv_) _sv_ = mm_scani_epi32(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_); _parm_ = _mm_add_epi16(_parm_, cv) +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_); _parm_ = _mm_add_epi32(_parm_, cv) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) _parm_ = _mm_add_epi16(_parm_, cv); cv = _mm_set1_epi16(8) +unsigned char *bitd1unpack128v16( const unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi16(start), cv = _mm_set_epi16(8,7,6,5,4,3,2,1); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +#define BITUNPACK0(_parm_) _parm_ = _mm_add_epi32(_parm_, cv); cv = _mm_set1_epi32(4) +unsigned char *bitd1unpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi32(start), cv = _mm_set_epi32(4,3,2,1); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +#define VO16(_op_, i, _ov_, _nb_,_sv_) ADDI16x8(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VO32(_op_, i, _ov_, _nb_,_sv_) ADDI32x4(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_); _parm_ = _mm_add_epi16(_parm_, cv) +#define VOZ32(_op_, _i_, ov, _nb_,_parm_) _mm_storeu_si128(_op_++, _parm_); _parm_ = _mm_add_epi32(_parm_, cv) +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) _parm_ = _mm_add_epi16(_parm_, cv); cv = _mm_set1_epi16(8) +unsigned char *bits1unpack128v16( const unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi16(start), cv = _mm_set1_epi16(8); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +#define BITUNPACK0(_parm_) _parm_ = _mm_add_epi32(_parm_, cv); cv = _mm_set1_epi32(4) +unsigned char *bits1unpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(4); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) _mm_storeu_si128(_op_++, _mm_add_epi16(_ov_, _sv_)); _sv_ = _mm_add_epi16(_sv_, cv) +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) _mm_storeu_si128(_op_++, _mm_add_epi32(_ov_, _sv_)); _sv_ = _mm_add_epi32(_sv_, cv) +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) _mm_storeu_si128(_op_++, _sv_); _sv_ = _mm_add_epi32(_sv_, cv); +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) +unsigned char *bitf1unpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set_epi16(start+8,start+7,start+6,start+5,start+4,start+3,start+2,start+1), cv = _mm_set1_epi16(8); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +unsigned char *bitf1unpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b) { + const unsigned char *ip = in+PAD8(128*b); __m128i sv = _mm_set_epi32(start+4,start+3,start+2,start+1), cv = _mm_set1_epi32(4); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + + #if defined(__SSSE3__) || defined(__ARM_NEON) +#define BITMAX16 15 +#define BITMAX32 31 + +#define VX16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_add_epi16(_ov_, _mm_shuffle_epi8( mm_slli_epi16(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_16[m]))); pex += popcnt32(m) +#define VX32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_add_epi32(_ov_, _mm_shuffle_epi8( mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), _nb_), _mm_loadu_si128((__m128i*)_shuffle_32[m]))); pex += popcnt32(m) +#define VXZ16(_i_, _nb_,_ov_) m = *bb++; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_16[m])); pex += popcnt32(m) +#define VXZ32(_i_, _nb_,_ov_) if(!((_i_) & 1)) m = (*bb) & 0xf;else m = (*bb++) >> 4; _ov_ = _mm_shuffle_epi8( _mm_loadu_si128((__m128i*)pex), _mm_loadu_si128((__m128i*)_shuffle_32[m])); pex += popcnt32(m) + +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) VX16( _i_, _nb_,_ov_); _sv_ = mm_scani_epi16(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, _ov_, _nb_,_sv_) VXZ16( _i_, _nb_,_ov_); _sv_ = mm_scani_epi16(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); _sv_ = mm_scani_epi32(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32( _i_, _nb_,_ov_); _sv_ = mm_scani_epi32(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); + +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) mv = _mm_setzero_si128() //_parm_ = _mm_setzero_si128() +unsigned char *_bitd1unpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b, unsigned short *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi16(start), cv = _mm_set_epi16(8,7,6,5,4,3,2,1); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +#define BITUNPACK0(_parm_) mv = _mm_setzero_si128() +unsigned char *_bitd1unpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi32(start), cv = _mm_set_epi32( 4,3,2,1); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} + +#define VO16( _op_, _i_, _ov_, _nb_,_sv_) VX16( _i_, _nb_,_ov_); ADDI16x8(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ16(_op_, _i_, _ov_, _nb_,_sv_) VXZ16( _i_, _nb_,_ov_); ADDI16x8(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VO32( _op_, _i_, _ov_, _nb_,_sv_) VX32( _i_, _nb_,_ov_); ADDI32x4(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); +#define VOZ32(_op_, _i_, _ov_, _nb_,_sv_) VXZ32( _i_, _nb_,_ov_); ADDI32x4(_ov_,_sv_,cv); _mm_storeu_si128(_op_++, _sv_); + +#include "bitunpack_.h" +#define BITUNPACK0(_parm_) mv = _mm_setzero_si128() //_parm_ = _mm_setzero_si128() +unsigned char *_bits1unpack128v16( const unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start, unsigned b, unsigned short *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi16(start), cv = _mm_set1_epi16(8); BITUNPACK128V16(in, b, out, sv); return (unsigned char *)ip; +} +#define BITUNPACK0(_parm_) mv = _mm_setzero_si128() +unsigned char *_bits1unpack128v32( const unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start, unsigned b, unsigned *__restrict pex, unsigned char *bb) { + const unsigned char *ip = in+PAD8(128*b); unsigned m; __m128i sv = _mm_set1_epi32(start), cv = _mm_set1_epi32(4); BITUNPACK128V32(in, b, out, sv); return (unsigned char *)ip; +} +#define BITMAX16 16 +#define BITMAX32 32 + #endif + +size_t bitnunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op; _BITNUNPACKV( in, n, out, 128, 16, bitunpack128v); } +size_t bitnunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _BITNUNPACKV( in, n, out, 128, 32, bitunpack128v); } +size_t bitnunpack128v64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out) { uint64_t *op; _BITNUNPACKV( in, n, out, 128, 64, bitunpack128v); } +size_t bitnunpack256w32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _BITNUNPACKV( in, n, out, 256, 32, bitunpack256w); } + +size_t bitndunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _BITNDUNPACKV(in, n, out, 128, 16, bitdunpack128v, bitdunpack); } +size_t bitndunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 128, 32, bitdunpack128v, bitdunpack); } + +size_t bitnd1unpack128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _BITNDUNPACKV(in, n, out, 128, 16, bitd1unpack128v, bitd1unpack); } +size_t bitnd1unpack128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 128, 32, bitd1unpack128v, bitd1unpack); } + +size_t bitns1unpack128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _BITNDUNPACKV(in, n, out, 128, 16, bits1unpack128v, bitd1unpack); } +size_t bitns1unpack128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 128, 32, bits1unpack128v, bitd1unpack); } + +size_t bitnzunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _BITNDUNPACKV(in, n, out, 128, 16, bitzunpack128v, bitzunpack); } +size_t bitnzunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 128, 32, bitzunpack128v, bitzunpack); } + +size_t bitnfunpack128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _BITNDUNPACKV(in, n, out, 128, 16, bitfunpack128v, bitfunpack); } +size_t bitnfunpack128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _BITNDUNPACKV(in, n, out, 128, 32, bitfunpack128v, bitfunpack); } + +#endif +#endif + +#pragma clang diagnostic pop +#pragma GCC pop_options diff --git a/src/ext/for/bitunpack_.h b/src/ext/for/bitunpack_.h new file mode 100644 index 00000000000..cebbbe9f6fc --- /dev/null +++ b/src/ext/for/bitunpack_.h @@ -0,0 +1,6049 @@ +/** + Copyright (C) powturbo 2013-2017 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// TurboPFor Integer Compression: Bit Packing +#ifdef OPI +#define BITUNBLK64_0(ip, i, op, nb,parm) { \ + OUT(op,i*0+ 0, 0, nb,parm);\ + OUT(op,i*0+ 1, 0, nb,parm);\ + OUT(op,i*0+ 2, 0, nb,parm);\ + OUT(op,i*0+ 3, 0, nb,parm);\ + OUT(op,i*0+ 4, 0, nb,parm);\ + OUT(op,i*0+ 5, 0, nb,parm);\ + OUT(op,i*0+ 6, 0, nb,parm);\ + OUT(op,i*0+ 7, 0, nb,parm);\ + OUT(op,i*0+ 8, 0, nb,parm);\ + OUT(op,i*0+ 9, 0, nb,parm);\ + OUT(op,i*0+10, 0, nb,parm);\ + OUT(op,i*0+11, 0, nb,parm);\ + OUT(op,i*0+12, 0, nb,parm);\ + OUT(op,i*0+13, 0, nb,parm);\ + OUT(op,i*0+14, 0, nb,parm);\ + OUT(op,i*0+15, 0, nb,parm);\ + OUT(op,i*0+16, 0, nb,parm);\ + OUT(op,i*0+17, 0, nb,parm);\ + OUT(op,i*0+18, 0, nb,parm);\ + OUT(op,i*0+19, 0, nb,parm);\ + OUT(op,i*0+20, 0, nb,parm);\ + OUT(op,i*0+21, 0, nb,parm);\ + OUT(op,i*0+22, 0, nb,parm);\ + OUT(op,i*0+23, 0, nb,parm);\ + OUT(op,i*0+24, 0, nb,parm);\ + OUT(op,i*0+25, 0, nb,parm);\ + OUT(op,i*0+26, 0, nb,parm);\ + OUT(op,i*0+27, 0, nb,parm);\ + OUT(op,i*0+28, 0, nb,parm);\ + OUT(op,i*0+29, 0, nb,parm);\ + OUT(op,i*0+30, 0, nb,parm);\ + OUT(op,i*0+31, 0, nb,parm);;\ +} + +#define BITUNPACK64_0(ip, op, nb,parm) { \ + BITUNBLK64_0(ip, 0, op, nb,parm); OPI(op, nb,parm);\ +} + +#define BITUNBLK64_1(ip, i, op, nb,parm) { uint32_t w0; w0 = *(uint32_t *)(ip+(i*1+0)*4/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x1, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 1) & 0x1, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 2) & 0x1, nb,parm);\ + OUT(op,i*32+ 3, (w0 >> 3) & 0x1, nb,parm);\ + OUT(op,i*32+ 4, (w0 >> 4) & 0x1, nb,parm);\ + OUT(op,i*32+ 5, (w0 >> 5) & 0x1, nb,parm);\ + OUT(op,i*32+ 6, (w0 >> 6) & 0x1, nb,parm);\ + OUT(op,i*32+ 7, (w0 >> 7) & 0x1, nb,parm);\ + OUT(op,i*32+ 8, (w0 >> 8) & 0x1, nb,parm);\ + OUT(op,i*32+ 9, (w0 >> 9) & 0x1, nb,parm);\ + OUT(op,i*32+10, (w0 >> 10) & 0x1, nb,parm);\ + OUT(op,i*32+11, (w0 >> 11) & 0x1, nb,parm);\ + OUT(op,i*32+12, (w0 >> 12) & 0x1, nb,parm);\ + OUT(op,i*32+13, (w0 >> 13) & 0x1, nb,parm);\ + OUT(op,i*32+14, (w0 >> 14) & 0x1, nb,parm);\ + OUT(op,i*32+15, (w0 >> 15) & 0x1, nb,parm);\ + OUT(op,i*32+16, (w0 >> 16) & 0x1, nb,parm);\ + OUT(op,i*32+17, (w0 >> 17) & 0x1, nb,parm);\ + OUT(op,i*32+18, (w0 >> 18) & 0x1, nb,parm);\ + OUT(op,i*32+19, (w0 >> 19) & 0x1, nb,parm);\ + OUT(op,i*32+20, (w0 >> 20) & 0x1, nb,parm);\ + OUT(op,i*32+21, (w0 >> 21) & 0x1, nb,parm);\ + OUT(op,i*32+22, (w0 >> 22) & 0x1, nb,parm);\ + OUT(op,i*32+23, (w0 >> 23) & 0x1, nb,parm);\ + OUT(op,i*32+24, (w0 >> 24) & 0x1, nb,parm);\ + OUT(op,i*32+25, (w0 >> 25) & 0x1, nb,parm);\ + OUT(op,i*32+26, (w0 >> 26) & 0x1, nb,parm);\ + OUT(op,i*32+27, (w0 >> 27) & 0x1, nb,parm);\ + OUT(op,i*32+28, (w0 >> 28) & 0x1, nb,parm);\ + OUT(op,i*32+29, (w0 >> 29) & 0x1, nb,parm);\ + OUT(op,i*32+30, (w0 >> 30) & 0x1, nb,parm);\ + OUT(op,i*32+31, (w0 >> 31) , nb,parm);;\ +} + +#define BITUNPACK64_1(ip, op, nb,parm) { \ + BITUNBLK64_1(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 1*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_2(ip, i, op, nb,parm) { uint64_t w0; w0 = *(uint64_t *)(ip+(i*1+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 2) & 0x3, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 4) & 0x3, nb,parm);\ + OUT(op,i*32+ 3, (w0 >> 6) & 0x3, nb,parm);\ + OUT(op,i*32+ 4, (w0 >> 8) & 0x3, nb,parm);\ + OUT(op,i*32+ 5, (w0 >> 10) & 0x3, nb,parm);\ + OUT(op,i*32+ 6, (w0 >> 12) & 0x3, nb,parm);\ + OUT(op,i*32+ 7, (w0 >> 14) & 0x3, nb,parm);\ + OUT(op,i*32+ 8, (w0 >> 16) & 0x3, nb,parm);\ + OUT(op,i*32+ 9, (w0 >> 18) & 0x3, nb,parm);\ + OUT(op,i*32+10, (w0 >> 20) & 0x3, nb,parm);\ + OUT(op,i*32+11, (w0 >> 22) & 0x3, nb,parm);\ + OUT(op,i*32+12, (w0 >> 24) & 0x3, nb,parm);\ + OUT(op,i*32+13, (w0 >> 26) & 0x3, nb,parm);\ + OUT(op,i*32+14, (w0 >> 28) & 0x3, nb,parm);\ + OUT(op,i*32+15, (w0 >> 30) & 0x3, nb,parm);\ + OUT(op,i*32+16, (w0 >> 32) & 0x3, nb,parm);\ + OUT(op,i*32+17, (w0 >> 34) & 0x3, nb,parm);\ + OUT(op,i*32+18, (w0 >> 36) & 0x3, nb,parm);\ + OUT(op,i*32+19, (w0 >> 38) & 0x3, nb,parm);\ + OUT(op,i*32+20, (w0 >> 40) & 0x3, nb,parm);\ + OUT(op,i*32+21, (w0 >> 42) & 0x3, nb,parm);\ + OUT(op,i*32+22, (w0 >> 44) & 0x3, nb,parm);\ + OUT(op,i*32+23, (w0 >> 46) & 0x3, nb,parm);\ + OUT(op,i*32+24, (w0 >> 48) & 0x3, nb,parm);\ + OUT(op,i*32+25, (w0 >> 50) & 0x3, nb,parm);\ + OUT(op,i*32+26, (w0 >> 52) & 0x3, nb,parm);\ + OUT(op,i*32+27, (w0 >> 54) & 0x3, nb,parm);\ + OUT(op,i*32+28, (w0 >> 56) & 0x3, nb,parm);\ + OUT(op,i*32+29, (w0 >> 58) & 0x3, nb,parm);\ + OUT(op,i*32+30, (w0 >> 60) & 0x3, nb,parm);\ + OUT(op,i*32+31, (w0 >> 62) , nb,parm);;\ +} + +#define BITUNPACK64_2(ip, op, nb,parm) { \ + BITUNBLK64_2(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 2*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_3(ip, i, op, nb,parm) { uint64_t w0,w1; w0 = *(uint64_t *)(ip+(i*3+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 3) & 0x7, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 6) & 0x7, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 9) & 0x7, nb,parm);\ + OUT(op,i*64+ 4, (w0 >> 12) & 0x7, nb,parm);\ + OUT(op,i*64+ 5, (w0 >> 15) & 0x7, nb,parm);\ + OUT(op,i*64+ 6, (w0 >> 18) & 0x7, nb,parm);\ + OUT(op,i*64+ 7, (w0 >> 21) & 0x7, nb,parm);\ + OUT(op,i*64+ 8, (w0 >> 24) & 0x7, nb,parm);\ + OUT(op,i*64+ 9, (w0 >> 27) & 0x7, nb,parm);\ + OUT(op,i*64+10, (w0 >> 30) & 0x7, nb,parm);\ + OUT(op,i*64+11, (w0 >> 33) & 0x7, nb,parm);\ + OUT(op,i*64+12, (w0 >> 36) & 0x7, nb,parm);\ + OUT(op,i*64+13, (w0 >> 39) & 0x7, nb,parm);\ + OUT(op,i*64+14, (w0 >> 42) & 0x7, nb,parm);\ + OUT(op,i*64+15, (w0 >> 45) & 0x7, nb,parm);\ + OUT(op,i*64+16, (w0 >> 48) & 0x7, nb,parm);\ + OUT(op,i*64+17, (w0 >> 51) & 0x7, nb,parm);\ + OUT(op,i*64+18, (w0 >> 54) & 0x7, nb,parm);\ + OUT(op,i*64+19, (w0 >> 57) & 0x7, nb,parm);\ + OUT(op,i*64+20, (w0 >> 60) & 0x7, nb,parm); w1 = *(uint32_t *)(ip+(i*3+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w0 >> 63) | (w1 << 1) & 0x7, nb,parm);\ + OUT(op,i*64+22, (w1 >> 2) & 0x7, nb,parm);\ + OUT(op,i*64+23, (w1 >> 5) & 0x7, nb,parm);\ + OUT(op,i*64+24, (w1 >> 8) & 0x7, nb,parm);\ + OUT(op,i*64+25, (w1 >> 11) & 0x7, nb,parm);\ + OUT(op,i*64+26, (w1 >> 14) & 0x7, nb,parm);\ + OUT(op,i*64+27, (w1 >> 17) & 0x7, nb,parm);\ + OUT(op,i*64+28, (w1 >> 20) & 0x7, nb,parm);\ + OUT(op,i*64+29, (w1 >> 23) & 0x7, nb,parm);\ + OUT(op,i*64+30, (w1 >> 26) & 0x7, nb,parm);\ + OUT(op,i*64+31, (w1 >> 29) & 0x7, nb,parm);;\ +} + +#define BITUNPACK64_3(ip, op, nb,parm) { \ + BITUNBLK64_3(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 3*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_4(ip, i, op, nb,parm) { uint64_t w0,w1; w0 = *(uint64_t *)(ip+(i*1+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xf, nb,parm);\ + OUT(op,i*16+ 1, (w0 >> 4) & 0xf, nb,parm);\ + OUT(op,i*16+ 2, (w0 >> 8) & 0xf, nb,parm);\ + OUT(op,i*16+ 3, (w0 >> 12) & 0xf, nb,parm);\ + OUT(op,i*16+ 4, (w0 >> 16) & 0xf, nb,parm);\ + OUT(op,i*16+ 5, (w0 >> 20) & 0xf, nb,parm);\ + OUT(op,i*16+ 6, (w0 >> 24) & 0xf, nb,parm);\ + OUT(op,i*16+ 7, (w0 >> 28) & 0xf, nb,parm);\ + OUT(op,i*16+ 8, (w0 >> 32) & 0xf, nb,parm);\ + OUT(op,i*16+ 9, (w0 >> 36) & 0xf, nb,parm);\ + OUT(op,i*16+10, (w0 >> 40) & 0xf, nb,parm);\ + OUT(op,i*16+11, (w0 >> 44) & 0xf, nb,parm);\ + OUT(op,i*16+12, (w0 >> 48) & 0xf, nb,parm);\ + OUT(op,i*16+13, (w0 >> 52) & 0xf, nb,parm);\ + OUT(op,i*16+14, (w0 >> 56) & 0xf, nb,parm);\ + OUT(op,i*16+15, (w0 >> 60) , nb,parm);;\ +} + +#define BITUNPACK64_4(ip, op, nb,parm) { \ + BITUNBLK64_4(ip, 0, op, nb,parm);\ + BITUNBLK64_4(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 4*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_5(ip, i, op, nb,parm) { uint64_t w0,w1,w2; w0 = *(uint64_t *)(ip+(i*5+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1f, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 5) & 0x1f, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 10) & 0x1f, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 15) & 0x1f, nb,parm);\ + OUT(op,i*64+ 4, (w0 >> 20) & 0x1f, nb,parm);\ + OUT(op,i*64+ 5, (w0 >> 25) & 0x1f, nb,parm);\ + OUT(op,i*64+ 6, (w0 >> 30) & 0x1f, nb,parm);\ + OUT(op,i*64+ 7, (w0 >> 35) & 0x1f, nb,parm);\ + OUT(op,i*64+ 8, (w0 >> 40) & 0x1f, nb,parm);\ + OUT(op,i*64+ 9, (w0 >> 45) & 0x1f, nb,parm);\ + OUT(op,i*64+10, (w0 >> 50) & 0x1f, nb,parm);\ + OUT(op,i*64+11, (w0 >> 55) & 0x1f, nb,parm); w1 = *(uint64_t *)(ip+(i*5+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w0 >> 60) | (w1 << 4) & 0x1f, nb,parm);\ + OUT(op,i*64+13, (w1 >> 1) & 0x1f, nb,parm);\ + OUT(op,i*64+14, (w1 >> 6) & 0x1f, nb,parm);\ + OUT(op,i*64+15, (w1 >> 11) & 0x1f, nb,parm);\ + OUT(op,i*64+16, (w1 >> 16) & 0x1f, nb,parm);\ + OUT(op,i*64+17, (w1 >> 21) & 0x1f, nb,parm);\ + OUT(op,i*64+18, (w1 >> 26) & 0x1f, nb,parm);\ + OUT(op,i*64+19, (w1 >> 31) & 0x1f, nb,parm);\ + OUT(op,i*64+20, (w1 >> 36) & 0x1f, nb,parm);\ + OUT(op,i*64+21, (w1 >> 41) & 0x1f, nb,parm);\ + OUT(op,i*64+22, (w1 >> 46) & 0x1f, nb,parm);\ + OUT(op,i*64+23, (w1 >> 51) & 0x1f, nb,parm);\ + OUT(op,i*64+24, (w1 >> 56) & 0x1f, nb,parm); w2 = *(uint32_t *)(ip+(i*5+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w1 >> 61) | (w2 << 3) & 0x1f, nb,parm);\ + OUT(op,i*64+26, (w2 >> 2) & 0x1f, nb,parm);\ + OUT(op,i*64+27, (w2 >> 7) & 0x1f, nb,parm);\ + OUT(op,i*64+28, (w2 >> 12) & 0x1f, nb,parm);\ + OUT(op,i*64+29, (w2 >> 17) & 0x1f, nb,parm);\ + OUT(op,i*64+30, (w2 >> 22) & 0x1f, nb,parm);\ + OUT(op,i*64+31, (w2 >> 27) & 0x1f, nb,parm);;\ +} + +#define BITUNPACK64_5(ip, op, nb,parm) { \ + BITUNBLK64_5(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 5*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_6(ip, i, op, nb,parm) { uint64_t w0,w1,w2; w0 = *(uint64_t *)(ip+(i*3+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3f, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 6) & 0x3f, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 12) & 0x3f, nb,parm);\ + OUT(op,i*32+ 3, (w0 >> 18) & 0x3f, nb,parm);\ + OUT(op,i*32+ 4, (w0 >> 24) & 0x3f, nb,parm);\ + OUT(op,i*32+ 5, (w0 >> 30) & 0x3f, nb,parm);\ + OUT(op,i*32+ 6, (w0 >> 36) & 0x3f, nb,parm);\ + OUT(op,i*32+ 7, (w0 >> 42) & 0x3f, nb,parm);\ + OUT(op,i*32+ 8, (w0 >> 48) & 0x3f, nb,parm);\ + OUT(op,i*32+ 9, (w0 >> 54) & 0x3f, nb,parm); w1 = *(uint64_t *)(ip+(i*3+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w0 >> 60) | (w1 << 4) & 0x3f, nb,parm);\ + OUT(op,i*32+11, (w1 >> 2) & 0x3f, nb,parm);\ + OUT(op,i*32+12, (w1 >> 8) & 0x3f, nb,parm);\ + OUT(op,i*32+13, (w1 >> 14) & 0x3f, nb,parm);\ + OUT(op,i*32+14, (w1 >> 20) & 0x3f, nb,parm);\ + OUT(op,i*32+15, (w1 >> 26) & 0x3f, nb,parm);\ + OUT(op,i*32+16, (w1 >> 32) & 0x3f, nb,parm);\ + OUT(op,i*32+17, (w1 >> 38) & 0x3f, nb,parm);\ + OUT(op,i*32+18, (w1 >> 44) & 0x3f, nb,parm);\ + OUT(op,i*32+19, (w1 >> 50) & 0x3f, nb,parm);\ + OUT(op,i*32+20, (w1 >> 56) & 0x3f, nb,parm); w2 = *(uint64_t *)(ip+(i*3+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w1 >> 62) | (w2 << 2) & 0x3f, nb,parm);\ + OUT(op,i*32+22, (w2 >> 4) & 0x3f, nb,parm);\ + OUT(op,i*32+23, (w2 >> 10) & 0x3f, nb,parm);\ + OUT(op,i*32+24, (w2 >> 16) & 0x3f, nb,parm);\ + OUT(op,i*32+25, (w2 >> 22) & 0x3f, nb,parm);\ + OUT(op,i*32+26, (w2 >> 28) & 0x3f, nb,parm);\ + OUT(op,i*32+27, (w2 >> 34) & 0x3f, nb,parm);\ + OUT(op,i*32+28, (w2 >> 40) & 0x3f, nb,parm);\ + OUT(op,i*32+29, (w2 >> 46) & 0x3f, nb,parm);\ + OUT(op,i*32+30, (w2 >> 52) & 0x3f, nb,parm);\ + OUT(op,i*32+31, (w2 >> 58) , nb,parm);;\ +} + +#define BITUNPACK64_6(ip, op, nb,parm) { \ + BITUNBLK64_6(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 6*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_7(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3; w0 = *(uint64_t *)(ip+(i*7+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7f, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 7) & 0x7f, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 14) & 0x7f, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 21) & 0x7f, nb,parm);\ + OUT(op,i*64+ 4, (w0 >> 28) & 0x7f, nb,parm);\ + OUT(op,i*64+ 5, (w0 >> 35) & 0x7f, nb,parm);\ + OUT(op,i*64+ 6, (w0 >> 42) & 0x7f, nb,parm);\ + OUT(op,i*64+ 7, (w0 >> 49) & 0x7f, nb,parm);\ + OUT(op,i*64+ 8, (w0 >> 56) & 0x7f, nb,parm); w1 = *(uint64_t *)(ip+(i*7+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w0 >> 63) | (w1 << 1) & 0x7f, nb,parm);\ + OUT(op,i*64+10, (w1 >> 6) & 0x7f, nb,parm);\ + OUT(op,i*64+11, (w1 >> 13) & 0x7f, nb,parm);\ + OUT(op,i*64+12, (w1 >> 20) & 0x7f, nb,parm);\ + OUT(op,i*64+13, (w1 >> 27) & 0x7f, nb,parm);\ + OUT(op,i*64+14, (w1 >> 34) & 0x7f, nb,parm);\ + OUT(op,i*64+15, (w1 >> 41) & 0x7f, nb,parm);\ + OUT(op,i*64+16, (w1 >> 48) & 0x7f, nb,parm);\ + OUT(op,i*64+17, (w1 >> 55) & 0x7f, nb,parm); w2 = *(uint64_t *)(ip+(i*7+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w1 >> 62) | (w2 << 2) & 0x7f, nb,parm);\ + OUT(op,i*64+19, (w2 >> 5) & 0x7f, nb,parm);\ + OUT(op,i*64+20, (w2 >> 12) & 0x7f, nb,parm);\ + OUT(op,i*64+21, (w2 >> 19) & 0x7f, nb,parm);\ + OUT(op,i*64+22, (w2 >> 26) & 0x7f, nb,parm);\ + OUT(op,i*64+23, (w2 >> 33) & 0x7f, nb,parm);\ + OUT(op,i*64+24, (w2 >> 40) & 0x7f, nb,parm);\ + OUT(op,i*64+25, (w2 >> 47) & 0x7f, nb,parm);\ + OUT(op,i*64+26, (w2 >> 54) & 0x7f, nb,parm); w3 = *(uint32_t *)(ip+(i*7+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w2 >> 61) | (w3 << 3) & 0x7f, nb,parm);\ + OUT(op,i*64+28, (w3 >> 4) & 0x7f, nb,parm);\ + OUT(op,i*64+29, (w3 >> 11) & 0x7f, nb,parm);\ + OUT(op,i*64+30, (w3 >> 18) & 0x7f, nb,parm);\ + OUT(op,i*64+31, (w3 >> 25) & 0x7f, nb,parm);;\ +} + +#define BITUNPACK64_7(ip, op, nb,parm) { \ + BITUNBLK64_7(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 7*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_8(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3; w0 = *(uint64_t *)(ip+(i*1+0)*8/sizeof(ip[0]));\ + OUT(op,i*8+ 0, (w0 ) & 0xff, nb,parm);\ + OUT(op,i*8+ 1, (w0 >> 8) & 0xff, nb,parm);\ + OUT(op,i*8+ 2, (w0 >> 16) & 0xff, nb,parm);\ + OUT(op,i*8+ 3, (w0 >> 24) & 0xff, nb,parm);\ + OUT(op,i*8+ 4, (w0 >> 32) & 0xff, nb,parm);\ + OUT(op,i*8+ 5, (w0 >> 40) & 0xff, nb,parm);\ + OUT(op,i*8+ 6, (w0 >> 48) & 0xff, nb,parm);\ + OUT(op,i*8+ 7, (w0 >> 56) , nb,parm);;\ +} + +#define BITUNPACK64_8(ip, op, nb,parm) { \ + BITUNBLK64_8(ip, 0, op, nb,parm);\ + BITUNBLK64_8(ip, 1, op, nb,parm);\ + BITUNBLK64_8(ip, 2, op, nb,parm);\ + BITUNBLK64_8(ip, 3, op, nb,parm); OPI(op, nb,parm); ip += 8*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_9(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4; w0 = *(uint64_t *)(ip+(i*9+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 9) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 18) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 27) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 4, (w0 >> 36) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 5, (w0 >> 45) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 6, (w0 >> 54) & 0x1ff, nb,parm); w1 = *(uint64_t *)(ip+(i*9+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w0 >> 63) | (w1 << 1) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 8, (w1 >> 8) & 0x1ff, nb,parm);\ + OUT(op,i*64+ 9, (w1 >> 17) & 0x1ff, nb,parm);\ + OUT(op,i*64+10, (w1 >> 26) & 0x1ff, nb,parm);\ + OUT(op,i*64+11, (w1 >> 35) & 0x1ff, nb,parm);\ + OUT(op,i*64+12, (w1 >> 44) & 0x1ff, nb,parm);\ + OUT(op,i*64+13, (w1 >> 53) & 0x1ff, nb,parm); w2 = *(uint64_t *)(ip+(i*9+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w1 >> 62) | (w2 << 2) & 0x1ff, nb,parm);\ + OUT(op,i*64+15, (w2 >> 7) & 0x1ff, nb,parm);\ + OUT(op,i*64+16, (w2 >> 16) & 0x1ff, nb,parm);\ + OUT(op,i*64+17, (w2 >> 25) & 0x1ff, nb,parm);\ + OUT(op,i*64+18, (w2 >> 34) & 0x1ff, nb,parm);\ + OUT(op,i*64+19, (w2 >> 43) & 0x1ff, nb,parm);\ + OUT(op,i*64+20, (w2 >> 52) & 0x1ff, nb,parm); w3 = *(uint64_t *)(ip+(i*9+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w2 >> 61) | (w3 << 3) & 0x1ff, nb,parm);\ + OUT(op,i*64+22, (w3 >> 6) & 0x1ff, nb,parm);\ + OUT(op,i*64+23, (w3 >> 15) & 0x1ff, nb,parm);\ + OUT(op,i*64+24, (w3 >> 24) & 0x1ff, nb,parm);\ + OUT(op,i*64+25, (w3 >> 33) & 0x1ff, nb,parm);\ + OUT(op,i*64+26, (w3 >> 42) & 0x1ff, nb,parm);\ + OUT(op,i*64+27, (w3 >> 51) & 0x1ff, nb,parm); w4 = *(uint32_t *)(ip+(i*9+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w3 >> 60) | (w4 << 4) & 0x1ff, nb,parm);\ + OUT(op,i*64+29, (w4 >> 5) & 0x1ff, nb,parm);\ + OUT(op,i*64+30, (w4 >> 14) & 0x1ff, nb,parm);\ + OUT(op,i*64+31, (w4 >> 23) & 0x1ff, nb,parm);;\ +} + +#define BITUNPACK64_9(ip, op, nb,parm) { \ + BITUNBLK64_9(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 9*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_10(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4; w0 = *(uint64_t *)(ip+(i*5+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 10) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 20) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 3, (w0 >> 30) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 4, (w0 >> 40) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 5, (w0 >> 50) & 0x3ff, nb,parm); w1 = *(uint64_t *)(ip+(i*5+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w0 >> 60) | (w1 << 4) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 7, (w1 >> 6) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 8, (w1 >> 16) & 0x3ff, nb,parm);\ + OUT(op,i*32+ 9, (w1 >> 26) & 0x3ff, nb,parm);\ + OUT(op,i*32+10, (w1 >> 36) & 0x3ff, nb,parm);\ + OUT(op,i*32+11, (w1 >> 46) & 0x3ff, nb,parm); w2 = *(uint64_t *)(ip+(i*5+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w1 >> 56) | (w2 << 8) & 0x3ff, nb,parm);\ + OUT(op,i*32+13, (w2 >> 2) & 0x3ff, nb,parm);\ + OUT(op,i*32+14, (w2 >> 12) & 0x3ff, nb,parm);\ + OUT(op,i*32+15, (w2 >> 22) & 0x3ff, nb,parm);\ + OUT(op,i*32+16, (w2 >> 32) & 0x3ff, nb,parm);\ + OUT(op,i*32+17, (w2 >> 42) & 0x3ff, nb,parm);\ + OUT(op,i*32+18, (w2 >> 52) & 0x3ff, nb,parm); w3 = *(uint64_t *)(ip+(i*5+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w2 >> 62) | (w3 << 2) & 0x3ff, nb,parm);\ + OUT(op,i*32+20, (w3 >> 8) & 0x3ff, nb,parm);\ + OUT(op,i*32+21, (w3 >> 18) & 0x3ff, nb,parm);\ + OUT(op,i*32+22, (w3 >> 28) & 0x3ff, nb,parm);\ + OUT(op,i*32+23, (w3 >> 38) & 0x3ff, nb,parm);\ + OUT(op,i*32+24, (w3 >> 48) & 0x3ff, nb,parm); w4 = *(uint64_t *)(ip+(i*5+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w3 >> 58) | (w4 << 6) & 0x3ff, nb,parm);\ + OUT(op,i*32+26, (w4 >> 4) & 0x3ff, nb,parm);\ + OUT(op,i*32+27, (w4 >> 14) & 0x3ff, nb,parm);\ + OUT(op,i*32+28, (w4 >> 24) & 0x3ff, nb,parm);\ + OUT(op,i*32+29, (w4 >> 34) & 0x3ff, nb,parm);\ + OUT(op,i*32+30, (w4 >> 44) & 0x3ff, nb,parm);\ + OUT(op,i*32+31, (w4 >> 54) , nb,parm);;\ +} + +#define BITUNPACK64_10(ip, op, nb,parm) { \ + BITUNBLK64_10(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 10*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_11(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5; w0 = *(uint64_t *)(ip+(i*11+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 11) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 22) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 33) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 4, (w0 >> 44) & 0x7ff, nb,parm); w1 = *(uint64_t *)(ip+(i*11+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w0 >> 55) | (w1 << 9) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 6, (w1 >> 2) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 7, (w1 >> 13) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 8, (w1 >> 24) & 0x7ff, nb,parm);\ + OUT(op,i*64+ 9, (w1 >> 35) & 0x7ff, nb,parm);\ + OUT(op,i*64+10, (w1 >> 46) & 0x7ff, nb,parm); w2 = *(uint64_t *)(ip+(i*11+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w1 >> 57) | (w2 << 7) & 0x7ff, nb,parm);\ + OUT(op,i*64+12, (w2 >> 4) & 0x7ff, nb,parm);\ + OUT(op,i*64+13, (w2 >> 15) & 0x7ff, nb,parm);\ + OUT(op,i*64+14, (w2 >> 26) & 0x7ff, nb,parm);\ + OUT(op,i*64+15, (w2 >> 37) & 0x7ff, nb,parm);\ + OUT(op,i*64+16, (w2 >> 48) & 0x7ff, nb,parm); w3 = *(uint64_t *)(ip+(i*11+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w2 >> 59) | (w3 << 5) & 0x7ff, nb,parm);\ + OUT(op,i*64+18, (w3 >> 6) & 0x7ff, nb,parm);\ + OUT(op,i*64+19, (w3 >> 17) & 0x7ff, nb,parm);\ + OUT(op,i*64+20, (w3 >> 28) & 0x7ff, nb,parm);\ + OUT(op,i*64+21, (w3 >> 39) & 0x7ff, nb,parm);\ + OUT(op,i*64+22, (w3 >> 50) & 0x7ff, nb,parm); w4 = *(uint64_t *)(ip+(i*11+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w3 >> 61) | (w4 << 3) & 0x7ff, nb,parm);\ + OUT(op,i*64+24, (w4 >> 8) & 0x7ff, nb,parm);\ + OUT(op,i*64+25, (w4 >> 19) & 0x7ff, nb,parm);\ + OUT(op,i*64+26, (w4 >> 30) & 0x7ff, nb,parm);\ + OUT(op,i*64+27, (w4 >> 41) & 0x7ff, nb,parm);\ + OUT(op,i*64+28, (w4 >> 52) & 0x7ff, nb,parm); w5 = *(uint32_t *)(ip+(i*11+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w4 >> 63) | (w5 << 1) & 0x7ff, nb,parm);\ + OUT(op,i*64+30, (w5 >> 10) & 0x7ff, nb,parm);\ + OUT(op,i*64+31, (w5 >> 21) & 0x7ff, nb,parm);;\ +} + +#define BITUNPACK64_11(ip, op, nb,parm) { \ + BITUNBLK64_11(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 11*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_12(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5; w0 = *(uint64_t *)(ip+(i*3+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfff, nb,parm);\ + OUT(op,i*16+ 1, (w0 >> 12) & 0xfff, nb,parm);\ + OUT(op,i*16+ 2, (w0 >> 24) & 0xfff, nb,parm);\ + OUT(op,i*16+ 3, (w0 >> 36) & 0xfff, nb,parm);\ + OUT(op,i*16+ 4, (w0 >> 48) & 0xfff, nb,parm); w1 = *(uint64_t *)(ip+(i*3+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 5, (w0 >> 60) | (w1 << 4) & 0xfff, nb,parm);\ + OUT(op,i*16+ 6, (w1 >> 8) & 0xfff, nb,parm);\ + OUT(op,i*16+ 7, (w1 >> 20) & 0xfff, nb,parm);\ + OUT(op,i*16+ 8, (w1 >> 32) & 0xfff, nb,parm);\ + OUT(op,i*16+ 9, (w1 >> 44) & 0xfff, nb,parm); w2 = *(uint64_t *)(ip+(i*3+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+10, (w1 >> 56) | (w2 << 8) & 0xfff, nb,parm);\ + OUT(op,i*16+11, (w2 >> 4) & 0xfff, nb,parm);\ + OUT(op,i*16+12, (w2 >> 16) & 0xfff, nb,parm);\ + OUT(op,i*16+13, (w2 >> 28) & 0xfff, nb,parm);\ + OUT(op,i*16+14, (w2 >> 40) & 0xfff, nb,parm);\ + OUT(op,i*16+15, (w2 >> 52) , nb,parm);;\ +} + +#define BITUNPACK64_12(ip, op, nb,parm) { \ + BITUNBLK64_12(ip, 0, op, nb,parm);\ + BITUNBLK64_12(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 12*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_13(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6; w0 = *(uint64_t *)(ip+(i*13+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 13) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 26) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 39) & 0x1fff, nb,parm); w1 = *(uint64_t *)(ip+(i*13+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w0 >> 52) | (w1 << 12) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 5, (w1 >> 1) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 6, (w1 >> 14) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 7, (w1 >> 27) & 0x1fff, nb,parm);\ + OUT(op,i*64+ 8, (w1 >> 40) & 0x1fff, nb,parm); w2 = *(uint64_t *)(ip+(i*13+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w1 >> 53) | (w2 << 11) & 0x1fff, nb,parm);\ + OUT(op,i*64+10, (w2 >> 2) & 0x1fff, nb,parm);\ + OUT(op,i*64+11, (w2 >> 15) & 0x1fff, nb,parm);\ + OUT(op,i*64+12, (w2 >> 28) & 0x1fff, nb,parm);\ + OUT(op,i*64+13, (w2 >> 41) & 0x1fff, nb,parm); w3 = *(uint64_t *)(ip+(i*13+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w2 >> 54) | (w3 << 10) & 0x1fff, nb,parm);\ + OUT(op,i*64+15, (w3 >> 3) & 0x1fff, nb,parm);\ + OUT(op,i*64+16, (w3 >> 16) & 0x1fff, nb,parm);\ + OUT(op,i*64+17, (w3 >> 29) & 0x1fff, nb,parm);\ + OUT(op,i*64+18, (w3 >> 42) & 0x1fff, nb,parm); w4 = *(uint64_t *)(ip+(i*13+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w3 >> 55) | (w4 << 9) & 0x1fff, nb,parm);\ + OUT(op,i*64+20, (w4 >> 4) & 0x1fff, nb,parm);\ + OUT(op,i*64+21, (w4 >> 17) & 0x1fff, nb,parm);\ + OUT(op,i*64+22, (w4 >> 30) & 0x1fff, nb,parm);\ + OUT(op,i*64+23, (w4 >> 43) & 0x1fff, nb,parm); w5 = *(uint64_t *)(ip+(i*13+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w4 >> 56) | (w5 << 8) & 0x1fff, nb,parm);\ + OUT(op,i*64+25, (w5 >> 5) & 0x1fff, nb,parm);\ + OUT(op,i*64+26, (w5 >> 18) & 0x1fff, nb,parm);\ + OUT(op,i*64+27, (w5 >> 31) & 0x1fff, nb,parm);\ + OUT(op,i*64+28, (w5 >> 44) & 0x1fff, nb,parm); w6 = *(uint32_t *)(ip+(i*13+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w5 >> 57) | (w6 << 7) & 0x1fff, nb,parm);\ + OUT(op,i*64+30, (w6 >> 6) & 0x1fff, nb,parm);\ + OUT(op,i*64+31, (w6 >> 19) & 0x1fff, nb,parm);;\ +} + +#define BITUNPACK64_13(ip, op, nb,parm) { \ + BITUNBLK64_13(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 13*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_14(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6; w0 = *(uint64_t *)(ip+(i*7+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 14) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 28) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 3, (w0 >> 42) & 0x3fff, nb,parm); w1 = *(uint64_t *)(ip+(i*7+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w0 >> 56) | (w1 << 8) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 5, (w1 >> 6) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 6, (w1 >> 20) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 7, (w1 >> 34) & 0x3fff, nb,parm);\ + OUT(op,i*32+ 8, (w1 >> 48) & 0x3fff, nb,parm); w2 = *(uint64_t *)(ip+(i*7+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w1 >> 62) | (w2 << 2) & 0x3fff, nb,parm);\ + OUT(op,i*32+10, (w2 >> 12) & 0x3fff, nb,parm);\ + OUT(op,i*32+11, (w2 >> 26) & 0x3fff, nb,parm);\ + OUT(op,i*32+12, (w2 >> 40) & 0x3fff, nb,parm); w3 = *(uint64_t *)(ip+(i*7+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w2 >> 54) | (w3 << 10) & 0x3fff, nb,parm);\ + OUT(op,i*32+14, (w3 >> 4) & 0x3fff, nb,parm);\ + OUT(op,i*32+15, (w3 >> 18) & 0x3fff, nb,parm);\ + OUT(op,i*32+16, (w3 >> 32) & 0x3fff, nb,parm);\ + OUT(op,i*32+17, (w3 >> 46) & 0x3fff, nb,parm); w4 = *(uint64_t *)(ip+(i*7+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w3 >> 60) | (w4 << 4) & 0x3fff, nb,parm);\ + OUT(op,i*32+19, (w4 >> 10) & 0x3fff, nb,parm);\ + OUT(op,i*32+20, (w4 >> 24) & 0x3fff, nb,parm);\ + OUT(op,i*32+21, (w4 >> 38) & 0x3fff, nb,parm); w5 = *(uint64_t *)(ip+(i*7+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w4 >> 52) | (w5 << 12) & 0x3fff, nb,parm);\ + OUT(op,i*32+23, (w5 >> 2) & 0x3fff, nb,parm);\ + OUT(op,i*32+24, (w5 >> 16) & 0x3fff, nb,parm);\ + OUT(op,i*32+25, (w5 >> 30) & 0x3fff, nb,parm);\ + OUT(op,i*32+26, (w5 >> 44) & 0x3fff, nb,parm); w6 = *(uint64_t *)(ip+(i*7+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w5 >> 58) | (w6 << 6) & 0x3fff, nb,parm);\ + OUT(op,i*32+28, (w6 >> 8) & 0x3fff, nb,parm);\ + OUT(op,i*32+29, (w6 >> 22) & 0x3fff, nb,parm);\ + OUT(op,i*32+30, (w6 >> 36) & 0x3fff, nb,parm);\ + OUT(op,i*32+31, (w6 >> 50) , nb,parm);;\ +} + +#define BITUNPACK64_14(ip, op, nb,parm) { \ + BITUNBLK64_14(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 14*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_15(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7; w0 = *(uint64_t *)(ip+(i*15+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 15) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 30) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 3, (w0 >> 45) & 0x7fff, nb,parm); w1 = *(uint64_t *)(ip+(i*15+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w0 >> 60) | (w1 << 4) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 5, (w1 >> 11) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 6, (w1 >> 26) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 7, (w1 >> 41) & 0x7fff, nb,parm); w2 = *(uint64_t *)(ip+(i*15+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w1 >> 56) | (w2 << 8) & 0x7fff, nb,parm);\ + OUT(op,i*64+ 9, (w2 >> 7) & 0x7fff, nb,parm);\ + OUT(op,i*64+10, (w2 >> 22) & 0x7fff, nb,parm);\ + OUT(op,i*64+11, (w2 >> 37) & 0x7fff, nb,parm); w3 = *(uint64_t *)(ip+(i*15+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w2 >> 52) | (w3 << 12) & 0x7fff, nb,parm);\ + OUT(op,i*64+13, (w3 >> 3) & 0x7fff, nb,parm);\ + OUT(op,i*64+14, (w3 >> 18) & 0x7fff, nb,parm);\ + OUT(op,i*64+15, (w3 >> 33) & 0x7fff, nb,parm);\ + OUT(op,i*64+16, (w3 >> 48) & 0x7fff, nb,parm); w4 = *(uint64_t *)(ip+(i*15+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w3 >> 63) | (w4 << 1) & 0x7fff, nb,parm);\ + OUT(op,i*64+18, (w4 >> 14) & 0x7fff, nb,parm);\ + OUT(op,i*64+19, (w4 >> 29) & 0x7fff, nb,parm);\ + OUT(op,i*64+20, (w4 >> 44) & 0x7fff, nb,parm); w5 = *(uint64_t *)(ip+(i*15+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w4 >> 59) | (w5 << 5) & 0x7fff, nb,parm);\ + OUT(op,i*64+22, (w5 >> 10) & 0x7fff, nb,parm);\ + OUT(op,i*64+23, (w5 >> 25) & 0x7fff, nb,parm);\ + OUT(op,i*64+24, (w5 >> 40) & 0x7fff, nb,parm); w6 = *(uint64_t *)(ip+(i*15+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w5 >> 55) | (w6 << 9) & 0x7fff, nb,parm);\ + OUT(op,i*64+26, (w6 >> 6) & 0x7fff, nb,parm);\ + OUT(op,i*64+27, (w6 >> 21) & 0x7fff, nb,parm);\ + OUT(op,i*64+28, (w6 >> 36) & 0x7fff, nb,parm); w7 = *(uint32_t *)(ip+(i*15+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w6 >> 51) | (w7 << 13) & 0x7fff, nb,parm);\ + OUT(op,i*64+30, (w7 >> 2) & 0x7fff, nb,parm);\ + OUT(op,i*64+31, (w7 >> 17) & 0x7fff, nb,parm);;\ +} + +#define BITUNPACK64_15(ip, op, nb,parm) { \ + BITUNBLK64_15(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 15*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_16(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7;\ + OUT(op,i*4+ 0, *(uint16_t *)(ip+i*8+ 0), nb,parm);\ + OUT(op,i*4+ 1, *(uint16_t *)(ip+i*8+ 2), nb,parm);\ + OUT(op,i*4+ 2, *(uint16_t *)(ip+i*8+ 4), nb,parm);\ + OUT(op,i*4+ 3, *(uint16_t *)(ip+i*8+ 6), nb,parm);;\ +} + +#define BITUNPACK64_16(ip, op, nb,parm) { \ + BITUNBLK64_16(ip, 0, op, nb,parm);\ + BITUNBLK64_16(ip, 1, op, nb,parm);\ + BITUNBLK64_16(ip, 2, op, nb,parm);\ + BITUNBLK64_16(ip, 3, op, nb,parm);\ + BITUNBLK64_16(ip, 4, op, nb,parm);\ + BITUNBLK64_16(ip, 5, op, nb,parm);\ + BITUNBLK64_16(ip, 6, op, nb,parm);\ + BITUNBLK64_16(ip, 7, op, nb,parm); OPI(op, nb,parm); ip += 16*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_17(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8; w0 = *(uint64_t *)(ip+(i*17+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 17) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 34) & 0x1ffff, nb,parm); w1 = *(uint64_t *)(ip+(i*17+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w0 >> 51) | (w1 << 13) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 4, (w1 >> 4) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 5, (w1 >> 21) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 6, (w1 >> 38) & 0x1ffff, nb,parm); w2 = *(uint64_t *)(ip+(i*17+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w1 >> 55) | (w2 << 9) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 8, (w2 >> 8) & 0x1ffff, nb,parm);\ + OUT(op,i*64+ 9, (w2 >> 25) & 0x1ffff, nb,parm);\ + OUT(op,i*64+10, (w2 >> 42) & 0x1ffff, nb,parm); w3 = *(uint64_t *)(ip+(i*17+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w2 >> 59) | (w3 << 5) & 0x1ffff, nb,parm);\ + OUT(op,i*64+12, (w3 >> 12) & 0x1ffff, nb,parm);\ + OUT(op,i*64+13, (w3 >> 29) & 0x1ffff, nb,parm);\ + OUT(op,i*64+14, (w3 >> 46) & 0x1ffff, nb,parm); w4 = *(uint64_t *)(ip+(i*17+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w3 >> 63) | (w4 << 1) & 0x1ffff, nb,parm);\ + OUT(op,i*64+16, (w4 >> 16) & 0x1ffff, nb,parm);\ + OUT(op,i*64+17, (w4 >> 33) & 0x1ffff, nb,parm); w5 = *(uint64_t *)(ip+(i*17+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w4 >> 50) | (w5 << 14) & 0x1ffff, nb,parm);\ + OUT(op,i*64+19, (w5 >> 3) & 0x1ffff, nb,parm);\ + OUT(op,i*64+20, (w5 >> 20) & 0x1ffff, nb,parm);\ + OUT(op,i*64+21, (w5 >> 37) & 0x1ffff, nb,parm); w6 = *(uint64_t *)(ip+(i*17+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w5 >> 54) | (w6 << 10) & 0x1ffff, nb,parm);\ + OUT(op,i*64+23, (w6 >> 7) & 0x1ffff, nb,parm);\ + OUT(op,i*64+24, (w6 >> 24) & 0x1ffff, nb,parm);\ + OUT(op,i*64+25, (w6 >> 41) & 0x1ffff, nb,parm); w7 = *(uint64_t *)(ip+(i*17+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w6 >> 58) | (w7 << 6) & 0x1ffff, nb,parm);\ + OUT(op,i*64+27, (w7 >> 11) & 0x1ffff, nb,parm);\ + OUT(op,i*64+28, (w7 >> 28) & 0x1ffff, nb,parm);\ + OUT(op,i*64+29, (w7 >> 45) & 0x1ffff, nb,parm); w8 = *(uint32_t *)(ip+(i*17+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w7 >> 62) | (w8 << 2) & 0x1ffff, nb,parm);\ + OUT(op,i*64+31, (w8 >> 15) & 0x1ffff, nb,parm);;\ +} + +#define BITUNPACK64_17(ip, op, nb,parm) { \ + BITUNBLK64_17(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 17*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_18(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8; w0 = *(uint64_t *)(ip+(i*9+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 18) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 2, (w0 >> 36) & 0x3ffff, nb,parm); w1 = *(uint64_t *)(ip+(i*9+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w0 >> 54) | (w1 << 10) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 4, (w1 >> 8) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 5, (w1 >> 26) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 6, (w1 >> 44) & 0x3ffff, nb,parm); w2 = *(uint64_t *)(ip+(i*9+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w1 >> 62) | (w2 << 2) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 8, (w2 >> 16) & 0x3ffff, nb,parm);\ + OUT(op,i*32+ 9, (w2 >> 34) & 0x3ffff, nb,parm); w3 = *(uint64_t *)(ip+(i*9+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w2 >> 52) | (w3 << 12) & 0x3ffff, nb,parm);\ + OUT(op,i*32+11, (w3 >> 6) & 0x3ffff, nb,parm);\ + OUT(op,i*32+12, (w3 >> 24) & 0x3ffff, nb,parm);\ + OUT(op,i*32+13, (w3 >> 42) & 0x3ffff, nb,parm); w4 = *(uint64_t *)(ip+(i*9+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w3 >> 60) | (w4 << 4) & 0x3ffff, nb,parm);\ + OUT(op,i*32+15, (w4 >> 14) & 0x3ffff, nb,parm);\ + OUT(op,i*32+16, (w4 >> 32) & 0x3ffff, nb,parm); w5 = *(uint64_t *)(ip+(i*9+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w4 >> 50) | (w5 << 14) & 0x3ffff, nb,parm);\ + OUT(op,i*32+18, (w5 >> 4) & 0x3ffff, nb,parm);\ + OUT(op,i*32+19, (w5 >> 22) & 0x3ffff, nb,parm);\ + OUT(op,i*32+20, (w5 >> 40) & 0x3ffff, nb,parm); w6 = *(uint64_t *)(ip+(i*9+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w5 >> 58) | (w6 << 6) & 0x3ffff, nb,parm);\ + OUT(op,i*32+22, (w6 >> 12) & 0x3ffff, nb,parm);\ + OUT(op,i*32+23, (w6 >> 30) & 0x3ffff, nb,parm); w7 = *(uint64_t *)(ip+(i*9+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w6 >> 48) | (w7 << 16) & 0x3ffff, nb,parm);\ + OUT(op,i*32+25, (w7 >> 2) & 0x3ffff, nb,parm);\ + OUT(op,i*32+26, (w7 >> 20) & 0x3ffff, nb,parm);\ + OUT(op,i*32+27, (w7 >> 38) & 0x3ffff, nb,parm); w8 = *(uint64_t *)(ip+(i*9+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w7 >> 56) | (w8 << 8) & 0x3ffff, nb,parm);\ + OUT(op,i*32+29, (w8 >> 10) & 0x3ffff, nb,parm);\ + OUT(op,i*32+30, (w8 >> 28) & 0x3ffff, nb,parm);\ + OUT(op,i*32+31, (w8 >> 46) , nb,parm);;\ +} + +#define BITUNPACK64_18(ip, op, nb,parm) { \ + BITUNBLK64_18(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 18*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_19(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9; w0 = *(uint64_t *)(ip+(i*19+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 19) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 38) & 0x7ffff, nb,parm); w1 = *(uint64_t *)(ip+(i*19+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w0 >> 57) | (w1 << 7) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 4, (w1 >> 12) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 5, (w1 >> 31) & 0x7ffff, nb,parm); w2 = *(uint64_t *)(ip+(i*19+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w1 >> 50) | (w2 << 14) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 7, (w2 >> 5) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 8, (w2 >> 24) & 0x7ffff, nb,parm);\ + OUT(op,i*64+ 9, (w2 >> 43) & 0x7ffff, nb,parm); w3 = *(uint64_t *)(ip+(i*19+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w2 >> 62) | (w3 << 2) & 0x7ffff, nb,parm);\ + OUT(op,i*64+11, (w3 >> 17) & 0x7ffff, nb,parm);\ + OUT(op,i*64+12, (w3 >> 36) & 0x7ffff, nb,parm); w4 = *(uint64_t *)(ip+(i*19+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w3 >> 55) | (w4 << 9) & 0x7ffff, nb,parm);\ + OUT(op,i*64+14, (w4 >> 10) & 0x7ffff, nb,parm);\ + OUT(op,i*64+15, (w4 >> 29) & 0x7ffff, nb,parm); w5 = *(uint64_t *)(ip+(i*19+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w4 >> 48) | (w5 << 16) & 0x7ffff, nb,parm);\ + OUT(op,i*64+17, (w5 >> 3) & 0x7ffff, nb,parm);\ + OUT(op,i*64+18, (w5 >> 22) & 0x7ffff, nb,parm);\ + OUT(op,i*64+19, (w5 >> 41) & 0x7ffff, nb,parm); w6 = *(uint64_t *)(ip+(i*19+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w5 >> 60) | (w6 << 4) & 0x7ffff, nb,parm);\ + OUT(op,i*64+21, (w6 >> 15) & 0x7ffff, nb,parm);\ + OUT(op,i*64+22, (w6 >> 34) & 0x7ffff, nb,parm); w7 = *(uint64_t *)(ip+(i*19+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w6 >> 53) | (w7 << 11) & 0x7ffff, nb,parm);\ + OUT(op,i*64+24, (w7 >> 8) & 0x7ffff, nb,parm);\ + OUT(op,i*64+25, (w7 >> 27) & 0x7ffff, nb,parm); w8 = *(uint64_t *)(ip+(i*19+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w7 >> 46) | (w8 << 18) & 0x7ffff, nb,parm);\ + OUT(op,i*64+27, (w8 >> 1) & 0x7ffff, nb,parm);\ + OUT(op,i*64+28, (w8 >> 20) & 0x7ffff, nb,parm);\ + OUT(op,i*64+29, (w8 >> 39) & 0x7ffff, nb,parm); w9 = *(uint32_t *)(ip+(i*19+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w8 >> 58) | (w9 << 6) & 0x7ffff, nb,parm);\ + OUT(op,i*64+31, (w9 >> 13) & 0x7ffff, nb,parm);;\ +} + +#define BITUNPACK64_19(ip, op, nb,parm) { \ + BITUNBLK64_19(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 19*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_20(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9; w0 = *(uint64_t *)(ip+(i*5+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 1, (w0 >> 20) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 2, (w0 >> 40) & 0xfffff, nb,parm); w1 = *(uint64_t *)(ip+(i*5+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 3, (w0 >> 60) | (w1 << 4) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 4, (w1 >> 16) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 5, (w1 >> 36) & 0xfffff, nb,parm); w2 = *(uint64_t *)(ip+(i*5+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 6, (w1 >> 56) | (w2 << 8) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 7, (w2 >> 12) & 0xfffff, nb,parm);\ + OUT(op,i*16+ 8, (w2 >> 32) & 0xfffff, nb,parm); w3 = *(uint64_t *)(ip+(i*5+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 9, (w2 >> 52) | (w3 << 12) & 0xfffff, nb,parm);\ + OUT(op,i*16+10, (w3 >> 8) & 0xfffff, nb,parm);\ + OUT(op,i*16+11, (w3 >> 28) & 0xfffff, nb,parm); w4 = *(uint64_t *)(ip+(i*5+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+12, (w3 >> 48) | (w4 << 16) & 0xfffff, nb,parm);\ + OUT(op,i*16+13, (w4 >> 4) & 0xfffff, nb,parm);\ + OUT(op,i*16+14, (w4 >> 24) & 0xfffff, nb,parm);\ + OUT(op,i*16+15, (w4 >> 44) , nb,parm);;\ +} + +#define BITUNPACK64_20(ip, op, nb,parm) { \ + BITUNBLK64_20(ip, 0, op, nb,parm);\ + BITUNBLK64_20(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 20*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_21(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10; w0 = *(uint64_t *)(ip+(i*21+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 21) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 2, (w0 >> 42) & 0x1fffff, nb,parm); w1 = *(uint64_t *)(ip+(i*21+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w0 >> 63) | (w1 << 1) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 4, (w1 >> 20) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 5, (w1 >> 41) & 0x1fffff, nb,parm); w2 = *(uint64_t *)(ip+(i*21+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w1 >> 62) | (w2 << 2) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 7, (w2 >> 19) & 0x1fffff, nb,parm);\ + OUT(op,i*64+ 8, (w2 >> 40) & 0x1fffff, nb,parm); w3 = *(uint64_t *)(ip+(i*21+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w2 >> 61) | (w3 << 3) & 0x1fffff, nb,parm);\ + OUT(op,i*64+10, (w3 >> 18) & 0x1fffff, nb,parm);\ + OUT(op,i*64+11, (w3 >> 39) & 0x1fffff, nb,parm); w4 = *(uint64_t *)(ip+(i*21+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w3 >> 60) | (w4 << 4) & 0x1fffff, nb,parm);\ + OUT(op,i*64+13, (w4 >> 17) & 0x1fffff, nb,parm);\ + OUT(op,i*64+14, (w4 >> 38) & 0x1fffff, nb,parm); w5 = *(uint64_t *)(ip+(i*21+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w4 >> 59) | (w5 << 5) & 0x1fffff, nb,parm);\ + OUT(op,i*64+16, (w5 >> 16) & 0x1fffff, nb,parm);\ + OUT(op,i*64+17, (w5 >> 37) & 0x1fffff, nb,parm); w6 = *(uint64_t *)(ip+(i*21+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w5 >> 58) | (w6 << 6) & 0x1fffff, nb,parm);\ + OUT(op,i*64+19, (w6 >> 15) & 0x1fffff, nb,parm);\ + OUT(op,i*64+20, (w6 >> 36) & 0x1fffff, nb,parm); w7 = *(uint64_t *)(ip+(i*21+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w6 >> 57) | (w7 << 7) & 0x1fffff, nb,parm);\ + OUT(op,i*64+22, (w7 >> 14) & 0x1fffff, nb,parm);\ + OUT(op,i*64+23, (w7 >> 35) & 0x1fffff, nb,parm); w8 = *(uint64_t *)(ip+(i*21+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w7 >> 56) | (w8 << 8) & 0x1fffff, nb,parm);\ + OUT(op,i*64+25, (w8 >> 13) & 0x1fffff, nb,parm);\ + OUT(op,i*64+26, (w8 >> 34) & 0x1fffff, nb,parm); w9 = *(uint64_t *)(ip+(i*21+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w8 >> 55) | (w9 << 9) & 0x1fffff, nb,parm);\ + OUT(op,i*64+28, (w9 >> 12) & 0x1fffff, nb,parm);\ + OUT(op,i*64+29, (w9 >> 33) & 0x1fffff, nb,parm); w10 = *(uint32_t *)(ip+(i*21+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w9 >> 54) | (w10 << 10) & 0x1fffff, nb,parm);\ + OUT(op,i*64+31, (w10 >> 11) & 0x1fffff, nb,parm);;\ +} + +#define BITUNPACK64_21(ip, op, nb,parm) { \ + BITUNBLK64_21(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 21*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_22(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10; w0 = *(uint64_t *)(ip+(i*11+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 22) & 0x3fffff, nb,parm); w1 = *(uint64_t *)(ip+(i*11+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w0 >> 44) | (w1 << 20) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 3, (w1 >> 2) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 4, (w1 >> 24) & 0x3fffff, nb,parm); w2 = *(uint64_t *)(ip+(i*11+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w1 >> 46) | (w2 << 18) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 6, (w2 >> 4) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 7, (w2 >> 26) & 0x3fffff, nb,parm); w3 = *(uint64_t *)(ip+(i*11+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w2 >> 48) | (w3 << 16) & 0x3fffff, nb,parm);\ + OUT(op,i*32+ 9, (w3 >> 6) & 0x3fffff, nb,parm);\ + OUT(op,i*32+10, (w3 >> 28) & 0x3fffff, nb,parm); w4 = *(uint64_t *)(ip+(i*11+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w3 >> 50) | (w4 << 14) & 0x3fffff, nb,parm);\ + OUT(op,i*32+12, (w4 >> 8) & 0x3fffff, nb,parm);\ + OUT(op,i*32+13, (w4 >> 30) & 0x3fffff, nb,parm); w5 = *(uint64_t *)(ip+(i*11+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w4 >> 52) | (w5 << 12) & 0x3fffff, nb,parm);\ + OUT(op,i*32+15, (w5 >> 10) & 0x3fffff, nb,parm);\ + OUT(op,i*32+16, (w5 >> 32) & 0x3fffff, nb,parm); w6 = *(uint64_t *)(ip+(i*11+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w5 >> 54) | (w6 << 10) & 0x3fffff, nb,parm);\ + OUT(op,i*32+18, (w6 >> 12) & 0x3fffff, nb,parm);\ + OUT(op,i*32+19, (w6 >> 34) & 0x3fffff, nb,parm); w7 = *(uint64_t *)(ip+(i*11+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w6 >> 56) | (w7 << 8) & 0x3fffff, nb,parm);\ + OUT(op,i*32+21, (w7 >> 14) & 0x3fffff, nb,parm);\ + OUT(op,i*32+22, (w7 >> 36) & 0x3fffff, nb,parm); w8 = *(uint64_t *)(ip+(i*11+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w7 >> 58) | (w8 << 6) & 0x3fffff, nb,parm);\ + OUT(op,i*32+24, (w8 >> 16) & 0x3fffff, nb,parm);\ + OUT(op,i*32+25, (w8 >> 38) & 0x3fffff, nb,parm); w9 = *(uint64_t *)(ip+(i*11+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w8 >> 60) | (w9 << 4) & 0x3fffff, nb,parm);\ + OUT(op,i*32+27, (w9 >> 18) & 0x3fffff, nb,parm);\ + OUT(op,i*32+28, (w9 >> 40) & 0x3fffff, nb,parm); w10 = *(uint64_t *)(ip+(i*11+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w9 >> 62) | (w10 << 2) & 0x3fffff, nb,parm);\ + OUT(op,i*32+30, (w10 >> 20) & 0x3fffff, nb,parm);\ + OUT(op,i*32+31, (w10 >> 42) , nb,parm);;\ +} + +#define BITUNPACK64_22(ip, op, nb,parm) { \ + BITUNBLK64_22(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 22*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_23(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11; w0 = *(uint64_t *)(ip+(i*23+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 23) & 0x7fffff, nb,parm); w1 = *(uint64_t *)(ip+(i*23+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w0 >> 46) | (w1 << 18) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 3, (w1 >> 5) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 4, (w1 >> 28) & 0x7fffff, nb,parm); w2 = *(uint64_t *)(ip+(i*23+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w1 >> 51) | (w2 << 13) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 6, (w2 >> 10) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 7, (w2 >> 33) & 0x7fffff, nb,parm); w3 = *(uint64_t *)(ip+(i*23+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w2 >> 56) | (w3 << 8) & 0x7fffff, nb,parm);\ + OUT(op,i*64+ 9, (w3 >> 15) & 0x7fffff, nb,parm);\ + OUT(op,i*64+10, (w3 >> 38) & 0x7fffff, nb,parm); w4 = *(uint64_t *)(ip+(i*23+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w3 >> 61) | (w4 << 3) & 0x7fffff, nb,parm);\ + OUT(op,i*64+12, (w4 >> 20) & 0x7fffff, nb,parm); w5 = *(uint64_t *)(ip+(i*23+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w4 >> 43) | (w5 << 21) & 0x7fffff, nb,parm);\ + OUT(op,i*64+14, (w5 >> 2) & 0x7fffff, nb,parm);\ + OUT(op,i*64+15, (w5 >> 25) & 0x7fffff, nb,parm); w6 = *(uint64_t *)(ip+(i*23+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w5 >> 48) | (w6 << 16) & 0x7fffff, nb,parm);\ + OUT(op,i*64+17, (w6 >> 7) & 0x7fffff, nb,parm);\ + OUT(op,i*64+18, (w6 >> 30) & 0x7fffff, nb,parm); w7 = *(uint64_t *)(ip+(i*23+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w6 >> 53) | (w7 << 11) & 0x7fffff, nb,parm);\ + OUT(op,i*64+20, (w7 >> 12) & 0x7fffff, nb,parm);\ + OUT(op,i*64+21, (w7 >> 35) & 0x7fffff, nb,parm); w8 = *(uint64_t *)(ip+(i*23+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w7 >> 58) | (w8 << 6) & 0x7fffff, nb,parm);\ + OUT(op,i*64+23, (w8 >> 17) & 0x7fffff, nb,parm);\ + OUT(op,i*64+24, (w8 >> 40) & 0x7fffff, nb,parm); w9 = *(uint64_t *)(ip+(i*23+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w8 >> 63) | (w9 << 1) & 0x7fffff, nb,parm);\ + OUT(op,i*64+26, (w9 >> 22) & 0x7fffff, nb,parm); w10 = *(uint64_t *)(ip+(i*23+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w9 >> 45) | (w10 << 19) & 0x7fffff, nb,parm);\ + OUT(op,i*64+28, (w10 >> 4) & 0x7fffff, nb,parm);\ + OUT(op,i*64+29, (w10 >> 27) & 0x7fffff, nb,parm); w11 = *(uint32_t *)(ip+(i*23+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w10 >> 50) | (w11 << 14) & 0x7fffff, nb,parm);\ + OUT(op,i*64+31, (w11 >> 9) & 0x7fffff, nb,parm);;\ +} + +#define BITUNPACK64_23(ip, op, nb,parm) { \ + BITUNBLK64_23(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 23*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_24(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11; w0 = *(uint64_t *)(ip+(i*3+0)*8/sizeof(ip[0]));\ + OUT(op,i*8+ 0, (w0 ) & 0xffffff, nb,parm);\ + OUT(op,i*8+ 1, (w0 >> 24) & 0xffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*3+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 2, (w0 >> 48) | (w1 << 16) & 0xffffff, nb,parm);\ + OUT(op,i*8+ 3, (w1 >> 8) & 0xffffff, nb,parm);\ + OUT(op,i*8+ 4, (w1 >> 32) & 0xffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*3+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 5, (w1 >> 56) | (w2 << 8) & 0xffffff, nb,parm);\ + OUT(op,i*8+ 6, (w2 >> 16) & 0xffffff, nb,parm);\ + OUT(op,i*8+ 7, (w2 >> 40) , nb,parm);;\ +} + +#define BITUNPACK64_24(ip, op, nb,parm) { \ + BITUNBLK64_24(ip, 0, op, nb,parm);\ + BITUNBLK64_24(ip, 1, op, nb,parm);\ + BITUNBLK64_24(ip, 2, op, nb,parm);\ + BITUNBLK64_24(ip, 3, op, nb,parm); OPI(op, nb,parm); ip += 24*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_25(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12; w0 = *(uint64_t *)(ip+(i*25+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 25) & 0x1ffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*25+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w0 >> 50) | (w1 << 14) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 3, (w1 >> 11) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 4, (w1 >> 36) & 0x1ffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*25+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w1 >> 61) | (w2 << 3) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 6, (w2 >> 22) & 0x1ffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*25+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w2 >> 47) | (w3 << 17) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 8, (w3 >> 8) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+ 9, (w3 >> 33) & 0x1ffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*25+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w3 >> 58) | (w4 << 6) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+11, (w4 >> 19) & 0x1ffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*25+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w4 >> 44) | (w5 << 20) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+13, (w5 >> 5) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+14, (w5 >> 30) & 0x1ffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*25+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w5 >> 55) | (w6 << 9) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+16, (w6 >> 16) & 0x1ffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*25+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w6 >> 41) | (w7 << 23) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+18, (w7 >> 2) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+19, (w7 >> 27) & 0x1ffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*25+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w7 >> 52) | (w8 << 12) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+21, (w8 >> 13) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+22, (w8 >> 38) & 0x1ffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*25+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w8 >> 63) | (w9 << 1) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+24, (w9 >> 24) & 0x1ffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*25+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w9 >> 49) | (w10 << 15) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+26, (w10 >> 10) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+27, (w10 >> 35) & 0x1ffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*25+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w10 >> 60) | (w11 << 4) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+29, (w11 >> 21) & 0x1ffffff, nb,parm); w12 = *(uint32_t *)(ip+(i*25+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w11 >> 46) | (w12 << 18) & 0x1ffffff, nb,parm);\ + OUT(op,i*64+31, (w12 >> 7) & 0x1ffffff, nb,parm);;\ +} + +#define BITUNPACK64_25(ip, op, nb,parm) { \ + BITUNBLK64_25(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 25*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_26(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12; w0 = *(uint64_t *)(ip+(i*13+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 26) & 0x3ffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*13+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w0 >> 52) | (w1 << 12) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+ 3, (w1 >> 14) & 0x3ffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*13+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w1 >> 40) | (w2 << 24) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+ 5, (w2 >> 2) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+ 6, (w2 >> 28) & 0x3ffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*13+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w2 >> 54) | (w3 << 10) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+ 8, (w3 >> 16) & 0x3ffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*13+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w3 >> 42) | (w4 << 22) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+10, (w4 >> 4) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+11, (w4 >> 30) & 0x3ffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*13+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w4 >> 56) | (w5 << 8) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+13, (w5 >> 18) & 0x3ffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*13+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w5 >> 44) | (w6 << 20) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+15, (w6 >> 6) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+16, (w6 >> 32) & 0x3ffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*13+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w6 >> 58) | (w7 << 6) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+18, (w7 >> 20) & 0x3ffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*13+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w7 >> 46) | (w8 << 18) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+20, (w8 >> 8) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+21, (w8 >> 34) & 0x3ffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*13+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w8 >> 60) | (w9 << 4) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+23, (w9 >> 22) & 0x3ffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*13+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w9 >> 48) | (w10 << 16) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+25, (w10 >> 10) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+26, (w10 >> 36) & 0x3ffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*13+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w10 >> 62) | (w11 << 2) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+28, (w11 >> 24) & 0x3ffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*13+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w11 >> 50) | (w12 << 14) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+30, (w12 >> 12) & 0x3ffffff, nb,parm);\ + OUT(op,i*32+31, (w12 >> 38) , nb,parm);;\ +} + +#define BITUNPACK64_26(ip, op, nb,parm) { \ + BITUNBLK64_26(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 26*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_27(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13; w0 = *(uint64_t *)(ip+(i*27+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 27) & 0x7ffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*27+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w0 >> 54) | (w1 << 10) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+ 3, (w1 >> 17) & 0x7ffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*27+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w1 >> 44) | (w2 << 20) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+ 5, (w2 >> 7) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+ 6, (w2 >> 34) & 0x7ffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*27+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w2 >> 61) | (w3 << 3) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+ 8, (w3 >> 24) & 0x7ffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*27+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w3 >> 51) | (w4 << 13) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+10, (w4 >> 14) & 0x7ffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*27+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w4 >> 41) | (w5 << 23) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+12, (w5 >> 4) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+13, (w5 >> 31) & 0x7ffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*27+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w5 >> 58) | (w6 << 6) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+15, (w6 >> 21) & 0x7ffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*27+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w6 >> 48) | (w7 << 16) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+17, (w7 >> 11) & 0x7ffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*27+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w7 >> 38) | (w8 << 26) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+19, (w8 >> 1) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+20, (w8 >> 28) & 0x7ffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*27+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w8 >> 55) | (w9 << 9) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+22, (w9 >> 18) & 0x7ffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*27+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w9 >> 45) | (w10 << 19) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+24, (w10 >> 8) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+25, (w10 >> 35) & 0x7ffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*27+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w10 >> 62) | (w11 << 2) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+27, (w11 >> 25) & 0x7ffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*27+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w11 >> 52) | (w12 << 12) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+29, (w12 >> 15) & 0x7ffffff, nb,parm); w13 = *(uint32_t *)(ip+(i*27+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w12 >> 42) | (w13 << 22) & 0x7ffffff, nb,parm);\ + OUT(op,i*64+31, (w13 >> 5) & 0x7ffffff, nb,parm);;\ +} + +#define BITUNPACK64_27(ip, op, nb,parm) { \ + BITUNBLK64_27(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 27*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_28(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13; w0 = *(uint64_t *)(ip+(i*7+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffffff, nb,parm);\ + OUT(op,i*16+ 1, (w0 >> 28) & 0xfffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*7+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 2, (w0 >> 56) | (w1 << 8) & 0xfffffff, nb,parm);\ + OUT(op,i*16+ 3, (w1 >> 20) & 0xfffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*7+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 4, (w1 >> 48) | (w2 << 16) & 0xfffffff, nb,parm);\ + OUT(op,i*16+ 5, (w2 >> 12) & 0xfffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*7+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 6, (w2 >> 40) | (w3 << 24) & 0xfffffff, nb,parm);\ + OUT(op,i*16+ 7, (w3 >> 4) & 0xfffffff, nb,parm);\ + OUT(op,i*16+ 8, (w3 >> 32) & 0xfffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*7+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 9, (w3 >> 60) | (w4 << 4) & 0xfffffff, nb,parm);\ + OUT(op,i*16+10, (w4 >> 24) & 0xfffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*7+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+11, (w4 >> 52) | (w5 << 12) & 0xfffffff, nb,parm);\ + OUT(op,i*16+12, (w5 >> 16) & 0xfffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*7+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+13, (w5 >> 44) | (w6 << 20) & 0xfffffff, nb,parm);\ + OUT(op,i*16+14, (w6 >> 8) & 0xfffffff, nb,parm);\ + OUT(op,i*16+15, (w6 >> 36) , nb,parm);;\ +} + +#define BITUNPACK64_28(ip, op, nb,parm) { \ + BITUNBLK64_28(ip, 0, op, nb,parm);\ + BITUNBLK64_28(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 28*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_29(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14; w0 = *(uint64_t *)(ip+(i*29+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 29) & 0x1fffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*29+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w0 >> 58) | (w1 << 6) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+ 3, (w1 >> 23) & 0x1fffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*29+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w1 >> 52) | (w2 << 12) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+ 5, (w2 >> 17) & 0x1fffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*29+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w2 >> 46) | (w3 << 18) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+ 7, (w3 >> 11) & 0x1fffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*29+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w3 >> 40) | (w4 << 24) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+ 9, (w4 >> 5) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+10, (w4 >> 34) & 0x1fffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*29+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w4 >> 63) | (w5 << 1) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+12, (w5 >> 28) & 0x1fffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*29+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w5 >> 57) | (w6 << 7) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+14, (w6 >> 22) & 0x1fffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*29+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w6 >> 51) | (w7 << 13) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+16, (w7 >> 16) & 0x1fffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*29+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w7 >> 45) | (w8 << 19) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+18, (w8 >> 10) & 0x1fffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*29+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w8 >> 39) | (w9 << 25) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+20, (w9 >> 4) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+21, (w9 >> 33) & 0x1fffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*29+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w9 >> 62) | (w10 << 2) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+23, (w10 >> 27) & 0x1fffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*29+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w10 >> 56) | (w11 << 8) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+25, (w11 >> 21) & 0x1fffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*29+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w11 >> 50) | (w12 << 14) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+27, (w12 >> 15) & 0x1fffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*29+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w12 >> 44) | (w13 << 20) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+29, (w13 >> 9) & 0x1fffffff, nb,parm); w14 = *(uint32_t *)(ip+(i*29+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w13 >> 38) | (w14 << 26) & 0x1fffffff, nb,parm);\ + OUT(op,i*64+31, (w14 >> 3) & 0x1fffffff, nb,parm);;\ +} + +#define BITUNPACK64_29(ip, op, nb,parm) { \ + BITUNBLK64_29(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 29*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_30(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14; w0 = *(uint64_t *)(ip+(i*15+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+ 1, (w0 >> 30) & 0x3fffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*15+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w0 >> 60) | (w1 << 4) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+ 3, (w1 >> 26) & 0x3fffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*15+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w1 >> 56) | (w2 << 8) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+ 5, (w2 >> 22) & 0x3fffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*15+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w2 >> 52) | (w3 << 12) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+ 7, (w3 >> 18) & 0x3fffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*15+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w3 >> 48) | (w4 << 16) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+ 9, (w4 >> 14) & 0x3fffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*15+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w4 >> 44) | (w5 << 20) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+11, (w5 >> 10) & 0x3fffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*15+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w5 >> 40) | (w6 << 24) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+13, (w6 >> 6) & 0x3fffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*15+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w6 >> 36) | (w7 << 28) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+15, (w7 >> 2) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+16, (w7 >> 32) & 0x3fffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*15+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w7 >> 62) | (w8 << 2) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+18, (w8 >> 28) & 0x3fffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*15+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w8 >> 58) | (w9 << 6) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+20, (w9 >> 24) & 0x3fffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*15+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w9 >> 54) | (w10 << 10) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+22, (w10 >> 20) & 0x3fffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*15+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w10 >> 50) | (w11 << 14) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+24, (w11 >> 16) & 0x3fffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*15+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w11 >> 46) | (w12 << 18) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+26, (w12 >> 12) & 0x3fffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*15+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w12 >> 42) | (w13 << 22) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+28, (w13 >> 8) & 0x3fffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*15+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w13 >> 38) | (w14 << 26) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+30, (w14 >> 4) & 0x3fffffff, nb,parm);\ + OUT(op,i*32+31, (w14 >> 34) , nb,parm);;\ +} + +#define BITUNPACK64_30(ip, op, nb,parm) { \ + BITUNBLK64_30(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 30*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_31(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15; w0 = *(uint64_t *)(ip+(i*31+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+ 1, (w0 >> 31) & 0x7fffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*31+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w0 >> 62) | (w1 << 2) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+ 3, (w1 >> 29) & 0x7fffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*31+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w1 >> 60) | (w2 << 4) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+ 5, (w2 >> 27) & 0x7fffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*31+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w2 >> 58) | (w3 << 6) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+ 7, (w3 >> 25) & 0x7fffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*31+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w3 >> 56) | (w4 << 8) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+ 9, (w4 >> 23) & 0x7fffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*31+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w4 >> 54) | (w5 << 10) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+11, (w5 >> 21) & 0x7fffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*31+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w5 >> 52) | (w6 << 12) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+13, (w6 >> 19) & 0x7fffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*31+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w6 >> 50) | (w7 << 14) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+15, (w7 >> 17) & 0x7fffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*31+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w7 >> 48) | (w8 << 16) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+17, (w8 >> 15) & 0x7fffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*31+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w8 >> 46) | (w9 << 18) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+19, (w9 >> 13) & 0x7fffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*31+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w9 >> 44) | (w10 << 20) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+21, (w10 >> 11) & 0x7fffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*31+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w10 >> 42) | (w11 << 22) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+23, (w11 >> 9) & 0x7fffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*31+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w11 >> 40) | (w12 << 24) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+25, (w12 >> 7) & 0x7fffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*31+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w12 >> 38) | (w13 << 26) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+27, (w13 >> 5) & 0x7fffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*31+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w13 >> 36) | (w14 << 28) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+29, (w14 >> 3) & 0x7fffffff, nb,parm); w15 = *(uint32_t *)(ip+(i*31+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w14 >> 34) | (w15 << 30) & 0x7fffffff, nb,parm);\ + OUT(op,i*64+31, (w15 >> 1) & 0x7fffffff, nb,parm);;\ +} + +#define BITUNPACK64_31(ip, op, nb,parm) { \ + BITUNBLK64_31(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 31*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_32(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15;\ + OUT(op,i*2+ 0, *(uint32_t *)(ip+i*8+ 0), nb,parm);\ + OUT(op,i*2+ 1, *(uint32_t *)(ip+i*8+ 4), nb,parm);;\ +} + +#define BITUNPACK64_32(ip, op, nb,parm) { \ + BITUNBLK64_32(ip, 0, op, nb,parm);\ + BITUNBLK64_32(ip, 1, op, nb,parm);\ + BITUNBLK64_32(ip, 2, op, nb,parm);\ + BITUNBLK64_32(ip, 3, op, nb,parm);\ + BITUNBLK64_32(ip, 4, op, nb,parm);\ + BITUNBLK64_32(ip, 5, op, nb,parm);\ + BITUNBLK64_32(ip, 6, op, nb,parm);\ + BITUNBLK64_32(ip, 7, op, nb,parm);\ + BITUNBLK64_32(ip, 8, op, nb,parm);\ + BITUNBLK64_32(ip, 9, op, nb,parm);\ + BITUNBLK64_32(ip, 10, op, nb,parm);\ + BITUNBLK64_32(ip, 11, op, nb,parm);\ + BITUNBLK64_32(ip, 12, op, nb,parm);\ + BITUNBLK64_32(ip, 13, op, nb,parm);\ + BITUNBLK64_32(ip, 14, op, nb,parm);\ + BITUNBLK64_32(ip, 15, op, nb,parm); OPI(op, nb,parm); ip += 32*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_33(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16; w0 = *(uint64_t *)(ip+(i*33+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*33+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 33) | (w1 << 31) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+ 2, (w1 >> 2) & 0x1ffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*33+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w1 >> 35) | (w2 << 29) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+ 4, (w2 >> 4) & 0x1ffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*33+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w2 >> 37) | (w3 << 27) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+ 6, (w3 >> 6) & 0x1ffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*33+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w3 >> 39) | (w4 << 25) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+ 8, (w4 >> 8) & 0x1ffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*33+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w4 >> 41) | (w5 << 23) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+10, (w5 >> 10) & 0x1ffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*33+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w5 >> 43) | (w6 << 21) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+12, (w6 >> 12) & 0x1ffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*33+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w6 >> 45) | (w7 << 19) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+14, (w7 >> 14) & 0x1ffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*33+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w7 >> 47) | (w8 << 17) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+16, (w8 >> 16) & 0x1ffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*33+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w8 >> 49) | (w9 << 15) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+18, (w9 >> 18) & 0x1ffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*33+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w9 >> 51) | (w10 << 13) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+20, (w10 >> 20) & 0x1ffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*33+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w10 >> 53) | (w11 << 11) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+22, (w11 >> 22) & 0x1ffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*33+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w11 >> 55) | (w12 << 9) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+24, (w12 >> 24) & 0x1ffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*33+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w12 >> 57) | (w13 << 7) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+26, (w13 >> 26) & 0x1ffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*33+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w13 >> 59) | (w14 << 5) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+28, (w14 >> 28) & 0x1ffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*33+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w14 >> 61) | (w15 << 3) & 0x1ffffffff, nb,parm);\ + OUT(op,i*64+30, (w15 >> 30) & 0x1ffffffff, nb,parm); w16 = *(uint32_t *)(ip+(i*33+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w15 >> 63) | (w16 << 1) & 0x1ffffffff, nb,parm);;\ +} + +#define BITUNPACK64_33(ip, op, nb,parm) { \ + BITUNBLK64_33(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 33*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_34(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16; w0 = *(uint64_t *)(ip+(i*17+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*17+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 34) | (w1 << 30) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+ 2, (w1 >> 4) & 0x3ffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*17+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w1 >> 38) | (w2 << 26) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+ 4, (w2 >> 8) & 0x3ffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*17+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w2 >> 42) | (w3 << 22) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+ 6, (w3 >> 12) & 0x3ffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*17+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w3 >> 46) | (w4 << 18) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+ 8, (w4 >> 16) & 0x3ffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*17+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w4 >> 50) | (w5 << 14) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+10, (w5 >> 20) & 0x3ffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*17+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w5 >> 54) | (w6 << 10) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+12, (w6 >> 24) & 0x3ffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*17+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w6 >> 58) | (w7 << 6) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+14, (w7 >> 28) & 0x3ffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*17+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w7 >> 62) | (w8 << 2) & 0x3ffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*17+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w8 >> 32) | (w9 << 32) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+17, (w9 >> 2) & 0x3ffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*17+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w9 >> 36) | (w10 << 28) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+19, (w10 >> 6) & 0x3ffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*17+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w10 >> 40) | (w11 << 24) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+21, (w11 >> 10) & 0x3ffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*17+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w11 >> 44) | (w12 << 20) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+23, (w12 >> 14) & 0x3ffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*17+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w12 >> 48) | (w13 << 16) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+25, (w13 >> 18) & 0x3ffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*17+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w13 >> 52) | (w14 << 12) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+27, (w14 >> 22) & 0x3ffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*17+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w14 >> 56) | (w15 << 8) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+29, (w15 >> 26) & 0x3ffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*17+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w15 >> 60) | (w16 << 4) & 0x3ffffffff, nb,parm);\ + OUT(op,i*32+31, (w16 >> 30) , nb,parm);;\ +} + +#define BITUNPACK64_34(ip, op, nb,parm) { \ + BITUNBLK64_34(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 34*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_35(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17; w0 = *(uint64_t *)(ip+(i*35+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*35+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 35) | (w1 << 29) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+ 2, (w1 >> 6) & 0x7ffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*35+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w1 >> 41) | (w2 << 23) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+ 4, (w2 >> 12) & 0x7ffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*35+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w2 >> 47) | (w3 << 17) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+ 6, (w3 >> 18) & 0x7ffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*35+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w3 >> 53) | (w4 << 11) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+ 8, (w4 >> 24) & 0x7ffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*35+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w4 >> 59) | (w5 << 5) & 0x7ffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*35+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w5 >> 30) | (w6 << 34) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+11, (w6 >> 1) & 0x7ffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*35+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w6 >> 36) | (w7 << 28) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+13, (w7 >> 7) & 0x7ffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*35+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w7 >> 42) | (w8 << 22) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+15, (w8 >> 13) & 0x7ffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*35+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w8 >> 48) | (w9 << 16) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+17, (w9 >> 19) & 0x7ffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*35+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w9 >> 54) | (w10 << 10) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+19, (w10 >> 25) & 0x7ffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*35+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w10 >> 60) | (w11 << 4) & 0x7ffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*35+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w11 >> 31) | (w12 << 33) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+22, (w12 >> 2) & 0x7ffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*35+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w12 >> 37) | (w13 << 27) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+24, (w13 >> 8) & 0x7ffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*35+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w13 >> 43) | (w14 << 21) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+26, (w14 >> 14) & 0x7ffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*35+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w14 >> 49) | (w15 << 15) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+28, (w15 >> 20) & 0x7ffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*35+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w15 >> 55) | (w16 << 9) & 0x7ffffffff, nb,parm);\ + OUT(op,i*64+30, (w16 >> 26) & 0x7ffffffff, nb,parm); w17 = *(uint32_t *)(ip+(i*35+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w16 >> 61) | (w17 << 3) & 0x7ffffffff, nb,parm);;\ +} + +#define BITUNPACK64_35(ip, op, nb,parm) { \ + BITUNBLK64_35(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 35*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_36(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17; w0 = *(uint64_t *)(ip+(i*9+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*9+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 1, (w0 >> 36) | (w1 << 28) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+ 2, (w1 >> 8) & 0xfffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*9+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 3, (w1 >> 44) | (w2 << 20) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+ 4, (w2 >> 16) & 0xfffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*9+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 5, (w2 >> 52) | (w3 << 12) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+ 6, (w3 >> 24) & 0xfffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*9+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 7, (w3 >> 60) | (w4 << 4) & 0xfffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*9+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 8, (w4 >> 32) | (w5 << 32) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+ 9, (w5 >> 4) & 0xfffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*9+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+10, (w5 >> 40) | (w6 << 24) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+11, (w6 >> 12) & 0xfffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*9+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+12, (w6 >> 48) | (w7 << 16) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+13, (w7 >> 20) & 0xfffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*9+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+14, (w7 >> 56) | (w8 << 8) & 0xfffffffff, nb,parm);\ + OUT(op,i*16+15, (w8 >> 28) , nb,parm);;\ +} + +#define BITUNPACK64_36(ip, op, nb,parm) { \ + BITUNBLK64_36(ip, 0, op, nb,parm);\ + BITUNBLK64_36(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 36*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_37(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18; w0 = *(uint64_t *)(ip+(i*37+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*37+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 37) | (w1 << 27) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+ 2, (w1 >> 10) & 0x1fffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*37+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w1 >> 47) | (w2 << 17) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+ 4, (w2 >> 20) & 0x1fffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*37+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w2 >> 57) | (w3 << 7) & 0x1fffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*37+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w3 >> 30) | (w4 << 34) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+ 7, (w4 >> 3) & 0x1fffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*37+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w4 >> 40) | (w5 << 24) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+ 9, (w5 >> 13) & 0x1fffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*37+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w5 >> 50) | (w6 << 14) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+11, (w6 >> 23) & 0x1fffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*37+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w6 >> 60) | (w7 << 4) & 0x1fffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*37+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w7 >> 33) | (w8 << 31) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+14, (w8 >> 6) & 0x1fffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*37+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w8 >> 43) | (w9 << 21) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+16, (w9 >> 16) & 0x1fffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*37+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w9 >> 53) | (w10 << 11) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+18, (w10 >> 26) & 0x1fffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*37+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w10 >> 63) | (w11 << 1) & 0x1fffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*37+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w11 >> 36) | (w12 << 28) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+21, (w12 >> 9) & 0x1fffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*37+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w12 >> 46) | (w13 << 18) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+23, (w13 >> 19) & 0x1fffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*37+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w13 >> 56) | (w14 << 8) & 0x1fffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*37+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w14 >> 29) | (w15 << 35) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+26, (w15 >> 2) & 0x1fffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*37+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w15 >> 39) | (w16 << 25) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+28, (w16 >> 12) & 0x1fffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*37+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w16 >> 49) | (w17 << 15) & 0x1fffffffff, nb,parm);\ + OUT(op,i*64+30, (w17 >> 22) & 0x1fffffffff, nb,parm); w18 = *(uint32_t *)(ip+(i*37+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w17 >> 59) | (w18 << 5) & 0x1fffffffff, nb,parm);;\ +} + +#define BITUNPACK64_37(ip, op, nb,parm) { \ + BITUNBLK64_37(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 37*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_38(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18; w0 = *(uint64_t *)(ip+(i*19+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*19+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 38) | (w1 << 26) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+ 2, (w1 >> 12) & 0x3fffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*19+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w1 >> 50) | (w2 << 14) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+ 4, (w2 >> 24) & 0x3fffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*19+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w2 >> 62) | (w3 << 2) & 0x3fffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*19+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w3 >> 36) | (w4 << 28) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+ 7, (w4 >> 10) & 0x3fffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*19+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w4 >> 48) | (w5 << 16) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+ 9, (w5 >> 22) & 0x3fffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*19+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w5 >> 60) | (w6 << 4) & 0x3fffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*19+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w6 >> 34) | (w7 << 30) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+12, (w7 >> 8) & 0x3fffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*19+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w7 >> 46) | (w8 << 18) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+14, (w8 >> 20) & 0x3fffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*19+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w8 >> 58) | (w9 << 6) & 0x3fffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*19+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w9 >> 32) | (w10 << 32) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+17, (w10 >> 6) & 0x3fffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*19+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w10 >> 44) | (w11 << 20) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+19, (w11 >> 18) & 0x3fffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*19+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w11 >> 56) | (w12 << 8) & 0x3fffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*19+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w12 >> 30) | (w13 << 34) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+22, (w13 >> 4) & 0x3fffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*19+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w13 >> 42) | (w14 << 22) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+24, (w14 >> 16) & 0x3fffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*19+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w14 >> 54) | (w15 << 10) & 0x3fffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*19+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w15 >> 28) | (w16 << 36) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+27, (w16 >> 2) & 0x3fffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*19+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w16 >> 40) | (w17 << 24) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+29, (w17 >> 14) & 0x3fffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*19+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w17 >> 52) | (w18 << 12) & 0x3fffffffff, nb,parm);\ + OUT(op,i*32+31, (w18 >> 26) , nb,parm);;\ +} + +#define BITUNPACK64_38(ip, op, nb,parm) { \ + BITUNBLK64_38(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 38*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_39(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19; w0 = *(uint64_t *)(ip+(i*39+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*39+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 39) | (w1 << 25) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+ 2, (w1 >> 14) & 0x7fffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*39+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w1 >> 53) | (w2 << 11) & 0x7fffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*39+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w2 >> 28) | (w3 << 36) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+ 5, (w3 >> 3) & 0x7fffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*39+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w3 >> 42) | (w4 << 22) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+ 7, (w4 >> 17) & 0x7fffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*39+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w4 >> 56) | (w5 << 8) & 0x7fffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*39+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w5 >> 31) | (w6 << 33) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+10, (w6 >> 6) & 0x7fffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*39+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w6 >> 45) | (w7 << 19) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+12, (w7 >> 20) & 0x7fffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*39+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w7 >> 59) | (w8 << 5) & 0x7fffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*39+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w8 >> 34) | (w9 << 30) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+15, (w9 >> 9) & 0x7fffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*39+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w9 >> 48) | (w10 << 16) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+17, (w10 >> 23) & 0x7fffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*39+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w10 >> 62) | (w11 << 2) & 0x7fffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*39+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w11 >> 37) | (w12 << 27) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+20, (w12 >> 12) & 0x7fffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*39+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w12 >> 51) | (w13 << 13) & 0x7fffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*39+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w13 >> 26) | (w14 << 38) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+23, (w14 >> 1) & 0x7fffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*39+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w14 >> 40) | (w15 << 24) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+25, (w15 >> 15) & 0x7fffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*39+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w15 >> 54) | (w16 << 10) & 0x7fffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*39+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w16 >> 29) | (w17 << 35) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+28, (w17 >> 4) & 0x7fffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*39+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w17 >> 43) | (w18 << 21) & 0x7fffffffff, nb,parm);\ + OUT(op,i*64+30, (w18 >> 18) & 0x7fffffffff, nb,parm); w19 = *(uint32_t *)(ip+(i*39+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w18 >> 57) | (w19 << 7) & 0x7fffffffff, nb,parm);;\ +} + +#define BITUNPACK64_39(ip, op, nb,parm) { \ + BITUNBLK64_39(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 39*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_40(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19; w0 = *(uint64_t *)(ip+(i*5+0)*8/sizeof(ip[0]));\ + OUT(op,i*8+ 0, (w0 ) & 0xffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*5+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 1, (w0 >> 40) | (w1 << 24) & 0xffffffffff, nb,parm);\ + OUT(op,i*8+ 2, (w1 >> 16) & 0xffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*5+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 3, (w1 >> 56) | (w2 << 8) & 0xffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*5+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 4, (w2 >> 32) | (w3 << 32) & 0xffffffffff, nb,parm);\ + OUT(op,i*8+ 5, (w3 >> 8) & 0xffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*5+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 6, (w3 >> 48) | (w4 << 16) & 0xffffffffff, nb,parm);\ + OUT(op,i*8+ 7, (w4 >> 24) , nb,parm);;\ +} + +#define BITUNPACK64_40(ip, op, nb,parm) { \ + BITUNBLK64_40(ip, 0, op, nb,parm);\ + BITUNBLK64_40(ip, 1, op, nb,parm);\ + BITUNBLK64_40(ip, 2, op, nb,parm);\ + BITUNBLK64_40(ip, 3, op, nb,parm); OPI(op, nb,parm); ip += 40*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_41(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20; w0 = *(uint64_t *)(ip+(i*41+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*41+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 41) | (w1 << 23) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+ 2, (w1 >> 18) & 0x1ffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*41+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w1 >> 59) | (w2 << 5) & 0x1ffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*41+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w2 >> 36) | (w3 << 28) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+ 5, (w3 >> 13) & 0x1ffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*41+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w3 >> 54) | (w4 << 10) & 0x1ffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*41+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w4 >> 31) | (w5 << 33) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+ 8, (w5 >> 8) & 0x1ffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*41+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w5 >> 49) | (w6 << 15) & 0x1ffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*41+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w6 >> 26) | (w7 << 38) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+11, (w7 >> 3) & 0x1ffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*41+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w7 >> 44) | (w8 << 20) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+13, (w8 >> 21) & 0x1ffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*41+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w8 >> 62) | (w9 << 2) & 0x1ffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*41+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w9 >> 39) | (w10 << 25) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+16, (w10 >> 16) & 0x1ffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*41+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w10 >> 57) | (w11 << 7) & 0x1ffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*41+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w11 >> 34) | (w12 << 30) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+19, (w12 >> 11) & 0x1ffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*41+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w12 >> 52) | (w13 << 12) & 0x1ffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*41+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w13 >> 29) | (w14 << 35) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+22, (w14 >> 6) & 0x1ffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*41+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w14 >> 47) | (w15 << 17) & 0x1ffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*41+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w15 >> 24) | (w16 << 40) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+25, (w16 >> 1) & 0x1ffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*41+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w16 >> 42) | (w17 << 22) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+27, (w17 >> 19) & 0x1ffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*41+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w17 >> 60) | (w18 << 4) & 0x1ffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*41+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w18 >> 37) | (w19 << 27) & 0x1ffffffffff, nb,parm);\ + OUT(op,i*64+30, (w19 >> 14) & 0x1ffffffffff, nb,parm); w20 = *(uint32_t *)(ip+(i*41+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w19 >> 55) | (w20 << 9) & 0x1ffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_41(ip, op, nb,parm) { \ + BITUNBLK64_41(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 41*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_42(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20; w0 = *(uint64_t *)(ip+(i*21+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*21+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 42) | (w1 << 22) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+ 2, (w1 >> 20) & 0x3ffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*21+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w1 >> 62) | (w2 << 2) & 0x3ffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*21+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w2 >> 40) | (w3 << 24) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+ 5, (w3 >> 18) & 0x3ffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*21+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w3 >> 60) | (w4 << 4) & 0x3ffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*21+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w4 >> 38) | (w5 << 26) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+ 8, (w5 >> 16) & 0x3ffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*21+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w5 >> 58) | (w6 << 6) & 0x3ffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*21+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w6 >> 36) | (w7 << 28) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+11, (w7 >> 14) & 0x3ffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*21+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w7 >> 56) | (w8 << 8) & 0x3ffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*21+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w8 >> 34) | (w9 << 30) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+14, (w9 >> 12) & 0x3ffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*21+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w9 >> 54) | (w10 << 10) & 0x3ffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*21+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w10 >> 32) | (w11 << 32) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+17, (w11 >> 10) & 0x3ffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*21+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w11 >> 52) | (w12 << 12) & 0x3ffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*21+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w12 >> 30) | (w13 << 34) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+20, (w13 >> 8) & 0x3ffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*21+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w13 >> 50) | (w14 << 14) & 0x3ffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*21+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w14 >> 28) | (w15 << 36) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+23, (w15 >> 6) & 0x3ffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*21+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w15 >> 48) | (w16 << 16) & 0x3ffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*21+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w16 >> 26) | (w17 << 38) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+26, (w17 >> 4) & 0x3ffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*21+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w17 >> 46) | (w18 << 18) & 0x3ffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*21+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w18 >> 24) | (w19 << 40) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+29, (w19 >> 2) & 0x3ffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*21+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w19 >> 44) | (w20 << 20) & 0x3ffffffffff, nb,parm);\ + OUT(op,i*32+31, (w20 >> 22) , nb,parm);;\ +} + +#define BITUNPACK64_42(ip, op, nb,parm) { \ + BITUNBLK64_42(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 42*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_43(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21; w0 = *(uint64_t *)(ip+(i*43+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*43+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 43) | (w1 << 21) & 0x7ffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*43+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 22) | (w2 << 42) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+ 3, (w2 >> 1) & 0x7ffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*43+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w2 >> 44) | (w3 << 20) & 0x7ffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*43+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w3 >> 23) | (w4 << 41) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+ 6, (w4 >> 2) & 0x7ffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*43+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w4 >> 45) | (w5 << 19) & 0x7ffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*43+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w5 >> 24) | (w6 << 40) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+ 9, (w6 >> 3) & 0x7ffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*43+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w6 >> 46) | (w7 << 18) & 0x7ffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*43+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w7 >> 25) | (w8 << 39) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+12, (w8 >> 4) & 0x7ffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*43+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w8 >> 47) | (w9 << 17) & 0x7ffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*43+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w9 >> 26) | (w10 << 38) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+15, (w10 >> 5) & 0x7ffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*43+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w10 >> 48) | (w11 << 16) & 0x7ffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*43+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w11 >> 27) | (w12 << 37) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+18, (w12 >> 6) & 0x7ffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*43+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w12 >> 49) | (w13 << 15) & 0x7ffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*43+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w13 >> 28) | (w14 << 36) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+21, (w14 >> 7) & 0x7ffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*43+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w14 >> 50) | (w15 << 14) & 0x7ffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*43+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w15 >> 29) | (w16 << 35) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+24, (w16 >> 8) & 0x7ffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*43+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w16 >> 51) | (w17 << 13) & 0x7ffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*43+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w17 >> 30) | (w18 << 34) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+27, (w18 >> 9) & 0x7ffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*43+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w18 >> 52) | (w19 << 12) & 0x7ffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*43+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w19 >> 31) | (w20 << 33) & 0x7ffffffffff, nb,parm);\ + OUT(op,i*64+30, (w20 >> 10) & 0x7ffffffffff, nb,parm); w21 = *(uint32_t *)(ip+(i*43+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w20 >> 53) | (w21 << 11) & 0x7ffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_43(ip, op, nb,parm) { \ + BITUNBLK64_43(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 43*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_44(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21; w0 = *(uint64_t *)(ip+(i*11+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*11+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 1, (w0 >> 44) | (w1 << 20) & 0xfffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*11+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 2, (w1 >> 24) | (w2 << 40) & 0xfffffffffff, nb,parm);\ + OUT(op,i*16+ 3, (w2 >> 4) & 0xfffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*11+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 4, (w2 >> 48) | (w3 << 16) & 0xfffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*11+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 5, (w3 >> 28) | (w4 << 36) & 0xfffffffffff, nb,parm);\ + OUT(op,i*16+ 6, (w4 >> 8) & 0xfffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*11+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 7, (w4 >> 52) | (w5 << 12) & 0xfffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*11+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 8, (w5 >> 32) | (w6 << 32) & 0xfffffffffff, nb,parm);\ + OUT(op,i*16+ 9, (w6 >> 12) & 0xfffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*11+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+10, (w6 >> 56) | (w7 << 8) & 0xfffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*11+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+11, (w7 >> 36) | (w8 << 28) & 0xfffffffffff, nb,parm);\ + OUT(op,i*16+12, (w8 >> 16) & 0xfffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*11+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+13, (w8 >> 60) | (w9 << 4) & 0xfffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*11+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+14, (w9 >> 40) | (w10 << 24) & 0xfffffffffff, nb,parm);\ + OUT(op,i*16+15, (w10 >> 20) , nb,parm);;\ +} + +#define BITUNPACK64_44(ip, op, nb,parm) { \ + BITUNBLK64_44(ip, 0, op, nb,parm);\ + BITUNBLK64_44(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 44*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_45(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22; w0 = *(uint64_t *)(ip+(i*45+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*45+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 45) | (w1 << 19) & 0x1fffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*45+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 26) | (w2 << 38) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+ 3, (w2 >> 7) & 0x1fffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*45+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w2 >> 52) | (w3 << 12) & 0x1fffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*45+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w3 >> 33) | (w4 << 31) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+ 6, (w4 >> 14) & 0x1fffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*45+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w4 >> 59) | (w5 << 5) & 0x1fffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*45+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w5 >> 40) | (w6 << 24) & 0x1fffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*45+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w6 >> 21) | (w7 << 43) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+10, (w7 >> 2) & 0x1fffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*45+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w7 >> 47) | (w8 << 17) & 0x1fffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*45+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w8 >> 28) | (w9 << 36) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+13, (w9 >> 9) & 0x1fffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*45+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w9 >> 54) | (w10 << 10) & 0x1fffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*45+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w10 >> 35) | (w11 << 29) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+16, (w11 >> 16) & 0x1fffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*45+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w11 >> 61) | (w12 << 3) & 0x1fffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*45+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w12 >> 42) | (w13 << 22) & 0x1fffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*45+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w13 >> 23) | (w14 << 41) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+20, (w14 >> 4) & 0x1fffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*45+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w14 >> 49) | (w15 << 15) & 0x1fffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*45+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w15 >> 30) | (w16 << 34) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+23, (w16 >> 11) & 0x1fffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*45+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w16 >> 56) | (w17 << 8) & 0x1fffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*45+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w17 >> 37) | (w18 << 27) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+26, (w18 >> 18) & 0x1fffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*45+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w18 >> 63) | (w19 << 1) & 0x1fffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*45+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w19 >> 44) | (w20 << 20) & 0x1fffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*45+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w20 >> 25) | (w21 << 39) & 0x1fffffffffff, nb,parm);\ + OUT(op,i*64+30, (w21 >> 6) & 0x1fffffffffff, nb,parm); w22 = *(uint32_t *)(ip+(i*45+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w21 >> 51) | (w22 << 13) & 0x1fffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_45(ip, op, nb,parm) { \ + BITUNBLK64_45(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 45*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_46(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22; w0 = *(uint64_t *)(ip+(i*23+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*23+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 46) | (w1 << 18) & 0x3fffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*23+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w1 >> 28) | (w2 << 36) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+ 3, (w2 >> 10) & 0x3fffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*23+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w2 >> 56) | (w3 << 8) & 0x3fffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*23+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w3 >> 38) | (w4 << 26) & 0x3fffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*23+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w4 >> 20) | (w5 << 44) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+ 7, (w5 >> 2) & 0x3fffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*23+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w5 >> 48) | (w6 << 16) & 0x3fffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*23+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w6 >> 30) | (w7 << 34) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+10, (w7 >> 12) & 0x3fffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*23+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w7 >> 58) | (w8 << 6) & 0x3fffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*23+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w8 >> 40) | (w9 << 24) & 0x3fffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*23+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w9 >> 22) | (w10 << 42) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+14, (w10 >> 4) & 0x3fffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*23+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w10 >> 50) | (w11 << 14) & 0x3fffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*23+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w11 >> 32) | (w12 << 32) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+17, (w12 >> 14) & 0x3fffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*23+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w12 >> 60) | (w13 << 4) & 0x3fffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*23+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w13 >> 42) | (w14 << 22) & 0x3fffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*23+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w14 >> 24) | (w15 << 40) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+21, (w15 >> 6) & 0x3fffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*23+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w15 >> 52) | (w16 << 12) & 0x3fffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*23+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w16 >> 34) | (w17 << 30) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+24, (w17 >> 16) & 0x3fffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*23+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w17 >> 62) | (w18 << 2) & 0x3fffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*23+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w18 >> 44) | (w19 << 20) & 0x3fffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*23+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w19 >> 26) | (w20 << 38) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+28, (w20 >> 8) & 0x3fffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*23+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w20 >> 54) | (w21 << 10) & 0x3fffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*23+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w21 >> 36) | (w22 << 28) & 0x3fffffffffff, nb,parm);\ + OUT(op,i*32+31, (w22 >> 18) , nb,parm);;\ +} + +#define BITUNPACK64_46(ip, op, nb,parm) { \ + BITUNBLK64_46(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 46*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_47(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23; w0 = *(uint64_t *)(ip+(i*47+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*47+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 47) | (w1 << 17) & 0x7fffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*47+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 30) | (w2 << 34) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+ 3, (w2 >> 13) & 0x7fffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*47+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w2 >> 60) | (w3 << 4) & 0x7fffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*47+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w3 >> 43) | (w4 << 21) & 0x7fffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*47+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w4 >> 26) | (w5 << 38) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+ 7, (w5 >> 9) & 0x7fffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*47+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w5 >> 56) | (w6 << 8) & 0x7fffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*47+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w6 >> 39) | (w7 << 25) & 0x7fffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*47+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w7 >> 22) | (w8 << 42) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+11, (w8 >> 5) & 0x7fffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*47+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w8 >> 52) | (w9 << 12) & 0x7fffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*47+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w9 >> 35) | (w10 << 29) & 0x7fffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*47+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w10 >> 18) | (w11 << 46) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+15, (w11 >> 1) & 0x7fffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*47+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w11 >> 48) | (w12 << 16) & 0x7fffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*47+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w12 >> 31) | (w13 << 33) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+18, (w13 >> 14) & 0x7fffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*47+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w13 >> 61) | (w14 << 3) & 0x7fffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*47+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w14 >> 44) | (w15 << 20) & 0x7fffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*47+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w15 >> 27) | (w16 << 37) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+22, (w16 >> 10) & 0x7fffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*47+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w16 >> 57) | (w17 << 7) & 0x7fffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*47+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w17 >> 40) | (w18 << 24) & 0x7fffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*47+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w18 >> 23) | (w19 << 41) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+26, (w19 >> 6) & 0x7fffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*47+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w19 >> 53) | (w20 << 11) & 0x7fffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*47+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w20 >> 36) | (w21 << 28) & 0x7fffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*47+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w21 >> 19) | (w22 << 45) & 0x7fffffffffff, nb,parm);\ + OUT(op,i*64+30, (w22 >> 2) & 0x7fffffffffff, nb,parm); w23 = *(uint32_t *)(ip+(i*47+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w22 >> 49) | (w23 << 15) & 0x7fffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_47(ip, op, nb,parm) { \ + BITUNBLK64_47(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 47*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_48(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23; w0 = *(uint64_t *)(ip+(i*3+0)*8/sizeof(ip[0]));\ + OUT(op,i*4+ 0, (w0 ) & 0xffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*3+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*4+ 1, (w0 >> 48) | (w1 << 16) & 0xffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*3+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*4+ 2, (w1 >> 32) | (w2 << 32) & 0xffffffffffff, nb,parm);\ + OUT(op,i*4+ 3, (w2 >> 16) , nb,parm);;\ +} + +#define BITUNPACK64_48(ip, op, nb,parm) { \ + BITUNBLK64_48(ip, 0, op, nb,parm);\ + BITUNBLK64_48(ip, 1, op, nb,parm);\ + BITUNBLK64_48(ip, 2, op, nb,parm);\ + BITUNBLK64_48(ip, 3, op, nb,parm);\ + BITUNBLK64_48(ip, 4, op, nb,parm);\ + BITUNBLK64_48(ip, 5, op, nb,parm);\ + BITUNBLK64_48(ip, 6, op, nb,parm);\ + BITUNBLK64_48(ip, 7, op, nb,parm); OPI(op, nb,parm); ip += 48*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_49(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24; w0 = *(uint64_t *)(ip+(i*49+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*49+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 49) | (w1 << 15) & 0x1ffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*49+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 34) | (w2 << 30) & 0x1ffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*49+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 19) | (w3 << 45) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+ 4, (w3 >> 4) & 0x1ffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*49+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w3 >> 53) | (w4 << 11) & 0x1ffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*49+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w4 >> 38) | (w5 << 26) & 0x1ffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*49+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w5 >> 23) | (w6 << 41) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+ 8, (w6 >> 8) & 0x1ffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*49+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w6 >> 57) | (w7 << 7) & 0x1ffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*49+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w7 >> 42) | (w8 << 22) & 0x1ffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*49+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w8 >> 27) | (w9 << 37) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+12, (w9 >> 12) & 0x1ffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*49+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w9 >> 61) | (w10 << 3) & 0x1ffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*49+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w10 >> 46) | (w11 << 18) & 0x1ffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*49+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w11 >> 31) | (w12 << 33) & 0x1ffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*49+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w12 >> 16) | (w13 << 48) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+17, (w13 >> 1) & 0x1ffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*49+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w13 >> 50) | (w14 << 14) & 0x1ffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*49+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w14 >> 35) | (w15 << 29) & 0x1ffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*49+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w15 >> 20) | (w16 << 44) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+21, (w16 >> 5) & 0x1ffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*49+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w16 >> 54) | (w17 << 10) & 0x1ffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*49+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w17 >> 39) | (w18 << 25) & 0x1ffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*49+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w18 >> 24) | (w19 << 40) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+25, (w19 >> 9) & 0x1ffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*49+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w19 >> 58) | (w20 << 6) & 0x1ffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*49+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w20 >> 43) | (w21 << 21) & 0x1ffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*49+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w21 >> 28) | (w22 << 36) & 0x1ffffffffffff, nb,parm);\ + OUT(op,i*64+29, (w22 >> 13) & 0x1ffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*49+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w22 >> 62) | (w23 << 2) & 0x1ffffffffffff, nb,parm); w24 = *(uint32_t *)(ip+(i*49+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w23 >> 47) | (w24 << 17) & 0x1ffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_49(ip, op, nb,parm) { \ + BITUNBLK64_49(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 49*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_50(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24; w0 = *(uint64_t *)(ip+(i*25+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*25+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 50) | (w1 << 14) & 0x3ffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*25+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w1 >> 36) | (w2 << 28) & 0x3ffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*25+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w2 >> 22) | (w3 << 42) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+ 4, (w3 >> 8) & 0x3ffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*25+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w3 >> 58) | (w4 << 6) & 0x3ffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*25+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w4 >> 44) | (w5 << 20) & 0x3ffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*25+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w5 >> 30) | (w6 << 34) & 0x3ffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*25+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w6 >> 16) | (w7 << 48) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+ 9, (w7 >> 2) & 0x3ffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*25+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w7 >> 52) | (w8 << 12) & 0x3ffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*25+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w8 >> 38) | (w9 << 26) & 0x3ffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*25+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w9 >> 24) | (w10 << 40) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+13, (w10 >> 10) & 0x3ffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*25+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w10 >> 60) | (w11 << 4) & 0x3ffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*25+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w11 >> 46) | (w12 << 18) & 0x3ffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*25+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w12 >> 32) | (w13 << 32) & 0x3ffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*25+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w13 >> 18) | (w14 << 46) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+18, (w14 >> 4) & 0x3ffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*25+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w14 >> 54) | (w15 << 10) & 0x3ffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*25+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w15 >> 40) | (w16 << 24) & 0x3ffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*25+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w16 >> 26) | (w17 << 38) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+22, (w17 >> 12) & 0x3ffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*25+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w17 >> 62) | (w18 << 2) & 0x3ffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*25+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w18 >> 48) | (w19 << 16) & 0x3ffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*25+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w19 >> 34) | (w20 << 30) & 0x3ffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*25+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w20 >> 20) | (w21 << 44) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+27, (w21 >> 6) & 0x3ffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*25+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w21 >> 56) | (w22 << 8) & 0x3ffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*25+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w22 >> 42) | (w23 << 22) & 0x3ffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*25+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w23 >> 28) | (w24 << 36) & 0x3ffffffffffff, nb,parm);\ + OUT(op,i*32+31, (w24 >> 14) , nb,parm);;\ +} + +#define BITUNPACK64_50(ip, op, nb,parm) { \ + BITUNBLK64_50(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 50*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_51(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25; w0 = *(uint64_t *)(ip+(i*51+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*51+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 51) | (w1 << 13) & 0x7ffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*51+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 38) | (w2 << 26) & 0x7ffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*51+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 25) | (w3 << 39) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+ 4, (w3 >> 12) & 0x7ffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*51+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w3 >> 63) | (w4 << 1) & 0x7ffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*51+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w4 >> 50) | (w5 << 14) & 0x7ffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*51+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w5 >> 37) | (w6 << 27) & 0x7ffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*51+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w6 >> 24) | (w7 << 40) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+ 9, (w7 >> 11) & 0x7ffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*51+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w7 >> 62) | (w8 << 2) & 0x7ffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*51+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w8 >> 49) | (w9 << 15) & 0x7ffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*51+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w9 >> 36) | (w10 << 28) & 0x7ffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*51+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w10 >> 23) | (w11 << 41) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+14, (w11 >> 10) & 0x7ffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*51+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w11 >> 61) | (w12 << 3) & 0x7ffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*51+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w12 >> 48) | (w13 << 16) & 0x7ffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*51+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w13 >> 35) | (w14 << 29) & 0x7ffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*51+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w14 >> 22) | (w15 << 42) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+19, (w15 >> 9) & 0x7ffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*51+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w15 >> 60) | (w16 << 4) & 0x7ffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*51+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w16 >> 47) | (w17 << 17) & 0x7ffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*51+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w17 >> 34) | (w18 << 30) & 0x7ffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*51+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w18 >> 21) | (w19 << 43) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+24, (w19 >> 8) & 0x7ffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*51+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w19 >> 59) | (w20 << 5) & 0x7ffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*51+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w20 >> 46) | (w21 << 18) & 0x7ffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*51+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w21 >> 33) | (w22 << 31) & 0x7ffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*51+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w22 >> 20) | (w23 << 44) & 0x7ffffffffffff, nb,parm);\ + OUT(op,i*64+29, (w23 >> 7) & 0x7ffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*51+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w23 >> 58) | (w24 << 6) & 0x7ffffffffffff, nb,parm); w25 = *(uint32_t *)(ip+(i*51+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w24 >> 45) | (w25 << 19) & 0x7ffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_51(ip, op, nb,parm) { \ + BITUNBLK64_51(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 51*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_52(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25; w0 = *(uint64_t *)(ip+(i*13+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*13+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 1, (w0 >> 52) | (w1 << 12) & 0xfffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*13+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 2, (w1 >> 40) | (w2 << 24) & 0xfffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*13+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 3, (w2 >> 28) | (w3 << 36) & 0xfffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*13+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 4, (w3 >> 16) | (w4 << 48) & 0xfffffffffffff, nb,parm);\ + OUT(op,i*16+ 5, (w4 >> 4) & 0xfffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*13+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 6, (w4 >> 56) | (w5 << 8) & 0xfffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*13+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 7, (w5 >> 44) | (w6 << 20) & 0xfffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*13+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 8, (w6 >> 32) | (w7 << 32) & 0xfffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*13+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 9, (w7 >> 20) | (w8 << 44) & 0xfffffffffffff, nb,parm);\ + OUT(op,i*16+10, (w8 >> 8) & 0xfffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*13+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+11, (w8 >> 60) | (w9 << 4) & 0xfffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*13+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+12, (w9 >> 48) | (w10 << 16) & 0xfffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*13+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+13, (w10 >> 36) | (w11 << 28) & 0xfffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*13+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+14, (w11 >> 24) | (w12 << 40) & 0xfffffffffffff, nb,parm);\ + OUT(op,i*16+15, (w12 >> 12) , nb,parm);;\ +} + +#define BITUNPACK64_52(ip, op, nb,parm) { \ + BITUNBLK64_52(ip, 0, op, nb,parm);\ + BITUNBLK64_52(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 52*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_53(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26; w0 = *(uint64_t *)(ip+(i*53+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*53+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 53) | (w1 << 11) & 0x1fffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*53+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 42) | (w2 << 22) & 0x1fffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*53+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 31) | (w3 << 33) & 0x1fffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*53+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 20) | (w4 << 44) & 0x1fffffffffffff, nb,parm);\ + OUT(op,i*64+ 5, (w4 >> 9) & 0x1fffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*53+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w4 >> 62) | (w5 << 2) & 0x1fffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*53+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w5 >> 51) | (w6 << 13) & 0x1fffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*53+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w6 >> 40) | (w7 << 24) & 0x1fffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*53+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w7 >> 29) | (w8 << 35) & 0x1fffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*53+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w8 >> 18) | (w9 << 46) & 0x1fffffffffffff, nb,parm);\ + OUT(op,i*64+11, (w9 >> 7) & 0x1fffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*53+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w9 >> 60) | (w10 << 4) & 0x1fffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*53+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w10 >> 49) | (w11 << 15) & 0x1fffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*53+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w11 >> 38) | (w12 << 26) & 0x1fffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*53+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w12 >> 27) | (w13 << 37) & 0x1fffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*53+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w13 >> 16) | (w14 << 48) & 0x1fffffffffffff, nb,parm);\ + OUT(op,i*64+17, (w14 >> 5) & 0x1fffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*53+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w14 >> 58) | (w15 << 6) & 0x1fffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*53+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w15 >> 47) | (w16 << 17) & 0x1fffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*53+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w16 >> 36) | (w17 << 28) & 0x1fffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*53+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w17 >> 25) | (w18 << 39) & 0x1fffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*53+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w18 >> 14) | (w19 << 50) & 0x1fffffffffffff, nb,parm);\ + OUT(op,i*64+23, (w19 >> 3) & 0x1fffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*53+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w19 >> 56) | (w20 << 8) & 0x1fffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*53+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w20 >> 45) | (w21 << 19) & 0x1fffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*53+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w21 >> 34) | (w22 << 30) & 0x1fffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*53+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w22 >> 23) | (w23 << 41) & 0x1fffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*53+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w23 >> 12) | (w24 << 52) & 0x1fffffffffffff, nb,parm);\ + OUT(op,i*64+29, (w24 >> 1) & 0x1fffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*53+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w24 >> 54) | (w25 << 10) & 0x1fffffffffffff, nb,parm); w26 = *(uint32_t *)(ip+(i*53+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w25 >> 43) | (w26 << 21) & 0x1fffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_53(ip, op, nb,parm) { \ + BITUNBLK64_53(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 53*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_54(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26; w0 = *(uint64_t *)(ip+(i*27+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*27+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 54) | (w1 << 10) & 0x3fffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*27+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w1 >> 44) | (w2 << 20) & 0x3fffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*27+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w2 >> 34) | (w3 << 30) & 0x3fffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*27+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w3 >> 24) | (w4 << 40) & 0x3fffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*27+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w4 >> 14) | (w5 << 50) & 0x3fffffffffffff, nb,parm);\ + OUT(op,i*32+ 6, (w5 >> 4) & 0x3fffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*27+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w5 >> 58) | (w6 << 6) & 0x3fffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*27+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w6 >> 48) | (w7 << 16) & 0x3fffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*27+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w7 >> 38) | (w8 << 26) & 0x3fffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*27+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w8 >> 28) | (w9 << 36) & 0x3fffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*27+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w9 >> 18) | (w10 << 46) & 0x3fffffffffffff, nb,parm);\ + OUT(op,i*32+12, (w10 >> 8) & 0x3fffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*27+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w10 >> 62) | (w11 << 2) & 0x3fffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*27+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w11 >> 52) | (w12 << 12) & 0x3fffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*27+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w12 >> 42) | (w13 << 22) & 0x3fffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*27+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w13 >> 32) | (w14 << 32) & 0x3fffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*27+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w14 >> 22) | (w15 << 42) & 0x3fffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*27+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w15 >> 12) | (w16 << 52) & 0x3fffffffffffff, nb,parm);\ + OUT(op,i*32+19, (w16 >> 2) & 0x3fffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*27+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w16 >> 56) | (w17 << 8) & 0x3fffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*27+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w17 >> 46) | (w18 << 18) & 0x3fffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*27+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w18 >> 36) | (w19 << 28) & 0x3fffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*27+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w19 >> 26) | (w20 << 38) & 0x3fffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*27+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w20 >> 16) | (w21 << 48) & 0x3fffffffffffff, nb,parm);\ + OUT(op,i*32+25, (w21 >> 6) & 0x3fffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*27+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w21 >> 60) | (w22 << 4) & 0x3fffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*27+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w22 >> 50) | (w23 << 14) & 0x3fffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*27+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w23 >> 40) | (w24 << 24) & 0x3fffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*27+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w24 >> 30) | (w25 << 34) & 0x3fffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*27+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w25 >> 20) | (w26 << 44) & 0x3fffffffffffff, nb,parm);\ + OUT(op,i*32+31, (w26 >> 10) , nb,parm);;\ +} + +#define BITUNPACK64_54(ip, op, nb,parm) { \ + BITUNBLK64_54(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 54*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_55(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27; w0 = *(uint64_t *)(ip+(i*55+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*55+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 55) | (w1 << 9) & 0x7fffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*55+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 46) | (w2 << 18) & 0x7fffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*55+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 37) | (w3 << 27) & 0x7fffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*55+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 28) | (w4 << 36) & 0x7fffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*55+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w4 >> 19) | (w5 << 45) & 0x7fffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*55+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w5 >> 10) | (w6 << 54) & 0x7fffffffffffff, nb,parm);\ + OUT(op,i*64+ 7, (w6 >> 1) & 0x7fffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*55+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w6 >> 56) | (w7 << 8) & 0x7fffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*55+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w7 >> 47) | (w8 << 17) & 0x7fffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*55+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w8 >> 38) | (w9 << 26) & 0x7fffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*55+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w9 >> 29) | (w10 << 35) & 0x7fffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*55+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w10 >> 20) | (w11 << 44) & 0x7fffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*55+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w11 >> 11) | (w12 << 53) & 0x7fffffffffffff, nb,parm);\ + OUT(op,i*64+14, (w12 >> 2) & 0x7fffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*55+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w12 >> 57) | (w13 << 7) & 0x7fffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*55+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w13 >> 48) | (w14 << 16) & 0x7fffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*55+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w14 >> 39) | (w15 << 25) & 0x7fffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*55+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w15 >> 30) | (w16 << 34) & 0x7fffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*55+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w16 >> 21) | (w17 << 43) & 0x7fffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*55+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w17 >> 12) | (w18 << 52) & 0x7fffffffffffff, nb,parm);\ + OUT(op,i*64+21, (w18 >> 3) & 0x7fffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*55+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w18 >> 58) | (w19 << 6) & 0x7fffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*55+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w19 >> 49) | (w20 << 15) & 0x7fffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*55+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w20 >> 40) | (w21 << 24) & 0x7fffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*55+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w21 >> 31) | (w22 << 33) & 0x7fffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*55+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w22 >> 22) | (w23 << 42) & 0x7fffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*55+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w23 >> 13) | (w24 << 51) & 0x7fffffffffffff, nb,parm);\ + OUT(op,i*64+28, (w24 >> 4) & 0x7fffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*55+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w24 >> 59) | (w25 << 5) & 0x7fffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*55+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w25 >> 50) | (w26 << 14) & 0x7fffffffffffff, nb,parm); w27 = *(uint32_t *)(ip+(i*55+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w26 >> 41) | (w27 << 23) & 0x7fffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_55(ip, op, nb,parm) { \ + BITUNBLK64_55(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 55*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_56(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27; w0 = *(uint64_t *)(ip+(i*7+0)*8/sizeof(ip[0]));\ + OUT(op,i*8+ 0, (w0 ) & 0xffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*7+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 1, (w0 >> 56) | (w1 << 8) & 0xffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*7+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 2, (w1 >> 48) | (w2 << 16) & 0xffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*7+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 3, (w2 >> 40) | (w3 << 24) & 0xffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*7+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 4, (w3 >> 32) | (w4 << 32) & 0xffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*7+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 5, (w4 >> 24) | (w5 << 40) & 0xffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*7+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*8+ 6, (w5 >> 16) | (w6 << 48) & 0xffffffffffffff, nb,parm);\ + OUT(op,i*8+ 7, (w6 >> 8) , nb,parm);;\ +} + +#define BITUNPACK64_56(ip, op, nb,parm) { \ + BITUNBLK64_56(ip, 0, op, nb,parm);\ + BITUNBLK64_56(ip, 1, op, nb,parm);\ + BITUNBLK64_56(ip, 2, op, nb,parm);\ + BITUNBLK64_56(ip, 3, op, nb,parm); OPI(op, nb,parm); ip += 56*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_57(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28; w0 = *(uint64_t *)(ip+(i*57+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1ffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*57+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 57) | (w1 << 7) & 0x1ffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*57+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 50) | (w2 << 14) & 0x1ffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*57+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 43) | (w3 << 21) & 0x1ffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*57+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 36) | (w4 << 28) & 0x1ffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*57+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w4 >> 29) | (w5 << 35) & 0x1ffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*57+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w5 >> 22) | (w6 << 42) & 0x1ffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*57+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w6 >> 15) | (w7 << 49) & 0x1ffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*57+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w7 >> 8) | (w8 << 56) & 0x1ffffffffffffff, nb,parm);\ + OUT(op,i*64+ 9, (w8 >> 1) & 0x1ffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*57+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w8 >> 58) | (w9 << 6) & 0x1ffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*57+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w9 >> 51) | (w10 << 13) & 0x1ffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*57+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w10 >> 44) | (w11 << 20) & 0x1ffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*57+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w11 >> 37) | (w12 << 27) & 0x1ffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*57+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w12 >> 30) | (w13 << 34) & 0x1ffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*57+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w13 >> 23) | (w14 << 41) & 0x1ffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*57+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w14 >> 16) | (w15 << 48) & 0x1ffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*57+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w15 >> 9) | (w16 << 55) & 0x1ffffffffffffff, nb,parm);\ + OUT(op,i*64+18, (w16 >> 2) & 0x1ffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*57+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w16 >> 59) | (w17 << 5) & 0x1ffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*57+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w17 >> 52) | (w18 << 12) & 0x1ffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*57+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w18 >> 45) | (w19 << 19) & 0x1ffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*57+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w19 >> 38) | (w20 << 26) & 0x1ffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*57+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w20 >> 31) | (w21 << 33) & 0x1ffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*57+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w21 >> 24) | (w22 << 40) & 0x1ffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*57+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w22 >> 17) | (w23 << 47) & 0x1ffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*57+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w23 >> 10) | (w24 << 54) & 0x1ffffffffffffff, nb,parm);\ + OUT(op,i*64+27, (w24 >> 3) & 0x1ffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*57+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w24 >> 60) | (w25 << 4) & 0x1ffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*57+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w25 >> 53) | (w26 << 11) & 0x1ffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*57+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w26 >> 46) | (w27 << 18) & 0x1ffffffffffffff, nb,parm); w28 = *(uint32_t *)(ip+(i*57+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w27 >> 39) | (w28 << 25) & 0x1ffffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_57(ip, op, nb,parm) { \ + BITUNBLK64_57(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 57*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_58(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28; w0 = *(uint64_t *)(ip+(i*29+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3ffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*29+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 58) | (w1 << 6) & 0x3ffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*29+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w1 >> 52) | (w2 << 12) & 0x3ffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*29+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w2 >> 46) | (w3 << 18) & 0x3ffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*29+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w3 >> 40) | (w4 << 24) & 0x3ffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*29+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w4 >> 34) | (w5 << 30) & 0x3ffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*29+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w5 >> 28) | (w6 << 36) & 0x3ffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*29+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w6 >> 22) | (w7 << 42) & 0x3ffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*29+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w7 >> 16) | (w8 << 48) & 0x3ffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*29+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w8 >> 10) | (w9 << 54) & 0x3ffffffffffffff, nb,parm);\ + OUT(op,i*32+10, (w9 >> 4) & 0x3ffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*29+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w9 >> 62) | (w10 << 2) & 0x3ffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*29+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w10 >> 56) | (w11 << 8) & 0x3ffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*29+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w11 >> 50) | (w12 << 14) & 0x3ffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*29+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w12 >> 44) | (w13 << 20) & 0x3ffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*29+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w13 >> 38) | (w14 << 26) & 0x3ffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*29+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w14 >> 32) | (w15 << 32) & 0x3ffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*29+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w15 >> 26) | (w16 << 38) & 0x3ffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*29+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w16 >> 20) | (w17 << 44) & 0x3ffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*29+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w17 >> 14) | (w18 << 50) & 0x3ffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*29+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w18 >> 8) | (w19 << 56) & 0x3ffffffffffffff, nb,parm);\ + OUT(op,i*32+21, (w19 >> 2) & 0x3ffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*29+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w19 >> 60) | (w20 << 4) & 0x3ffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*29+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w20 >> 54) | (w21 << 10) & 0x3ffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*29+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w21 >> 48) | (w22 << 16) & 0x3ffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*29+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w22 >> 42) | (w23 << 22) & 0x3ffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*29+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w23 >> 36) | (w24 << 28) & 0x3ffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*29+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w24 >> 30) | (w25 << 34) & 0x3ffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*29+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w25 >> 24) | (w26 << 40) & 0x3ffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*29+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w26 >> 18) | (w27 << 46) & 0x3ffffffffffffff, nb,parm); w28 = *(uint64_t *)(ip+(i*29+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w27 >> 12) | (w28 << 52) & 0x3ffffffffffffff, nb,parm);\ + OUT(op,i*32+31, (w28 >> 6) , nb,parm);;\ +} + +#define BITUNPACK64_58(ip, op, nb,parm) { \ + BITUNBLK64_58(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 58*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_59(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29; w0 = *(uint64_t *)(ip+(i*59+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7ffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*59+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 59) | (w1 << 5) & 0x7ffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*59+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 54) | (w2 << 10) & 0x7ffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*59+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 49) | (w3 << 15) & 0x7ffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*59+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 44) | (w4 << 20) & 0x7ffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*59+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w4 >> 39) | (w5 << 25) & 0x7ffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*59+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w5 >> 34) | (w6 << 30) & 0x7ffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*59+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w6 >> 29) | (w7 << 35) & 0x7ffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*59+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w7 >> 24) | (w8 << 40) & 0x7ffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*59+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w8 >> 19) | (w9 << 45) & 0x7ffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*59+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w9 >> 14) | (w10 << 50) & 0x7ffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*59+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w10 >> 9) | (w11 << 55) & 0x7ffffffffffffff, nb,parm);\ + OUT(op,i*64+12, (w11 >> 4) & 0x7ffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*59+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w11 >> 63) | (w12 << 1) & 0x7ffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*59+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w12 >> 58) | (w13 << 6) & 0x7ffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*59+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w13 >> 53) | (w14 << 11) & 0x7ffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*59+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w14 >> 48) | (w15 << 16) & 0x7ffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*59+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w15 >> 43) | (w16 << 21) & 0x7ffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*59+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w16 >> 38) | (w17 << 26) & 0x7ffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*59+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w17 >> 33) | (w18 << 31) & 0x7ffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*59+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w18 >> 28) | (w19 << 36) & 0x7ffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*59+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w19 >> 23) | (w20 << 41) & 0x7ffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*59+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w20 >> 18) | (w21 << 46) & 0x7ffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*59+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w21 >> 13) | (w22 << 51) & 0x7ffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*59+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w22 >> 8) | (w23 << 56) & 0x7ffffffffffffff, nb,parm);\ + OUT(op,i*64+25, (w23 >> 3) & 0x7ffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*59+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w23 >> 62) | (w24 << 2) & 0x7ffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*59+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w24 >> 57) | (w25 << 7) & 0x7ffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*59+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w25 >> 52) | (w26 << 12) & 0x7ffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*59+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w26 >> 47) | (w27 << 17) & 0x7ffffffffffffff, nb,parm); w28 = *(uint64_t *)(ip+(i*59+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w27 >> 42) | (w28 << 22) & 0x7ffffffffffffff, nb,parm); w29 = *(uint32_t *)(ip+(i*59+29)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w28 >> 37) | (w29 << 27) & 0x7ffffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_59(ip, op, nb,parm) { \ + BITUNBLK64_59(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 59*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_60(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29; w0 = *(uint64_t *)(ip+(i*15+0)*8/sizeof(ip[0]));\ + OUT(op,i*16+ 0, (w0 ) & 0xfffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*15+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 1, (w0 >> 60) | (w1 << 4) & 0xfffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*15+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 2, (w1 >> 56) | (w2 << 8) & 0xfffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*15+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 3, (w2 >> 52) | (w3 << 12) & 0xfffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*15+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 4, (w3 >> 48) | (w4 << 16) & 0xfffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*15+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 5, (w4 >> 44) | (w5 << 20) & 0xfffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*15+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 6, (w5 >> 40) | (w6 << 24) & 0xfffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*15+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 7, (w6 >> 36) | (w7 << 28) & 0xfffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*15+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 8, (w7 >> 32) | (w8 << 32) & 0xfffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*15+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+ 9, (w8 >> 28) | (w9 << 36) & 0xfffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*15+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+10, (w9 >> 24) | (w10 << 40) & 0xfffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*15+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+11, (w10 >> 20) | (w11 << 44) & 0xfffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*15+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+12, (w11 >> 16) | (w12 << 48) & 0xfffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*15+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+13, (w12 >> 12) | (w13 << 52) & 0xfffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*15+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*16+14, (w13 >> 8) | (w14 << 56) & 0xfffffffffffffff, nb,parm);\ + OUT(op,i*16+15, (w14 >> 4) , nb,parm);;\ +} + +#define BITUNPACK64_60(ip, op, nb,parm) { \ + BITUNBLK64_60(ip, 0, op, nb,parm);\ + BITUNBLK64_60(ip, 1, op, nb,parm); OPI(op, nb,parm); ip += 60*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_61(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30; w0 = *(uint64_t *)(ip+(i*61+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x1fffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*61+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 61) | (w1 << 3) & 0x1fffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*61+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 58) | (w2 << 6) & 0x1fffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*61+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 55) | (w3 << 9) & 0x1fffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*61+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 52) | (w4 << 12) & 0x1fffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*61+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w4 >> 49) | (w5 << 15) & 0x1fffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*61+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w5 >> 46) | (w6 << 18) & 0x1fffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*61+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w6 >> 43) | (w7 << 21) & 0x1fffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*61+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w7 >> 40) | (w8 << 24) & 0x1fffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*61+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w8 >> 37) | (w9 << 27) & 0x1fffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*61+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w9 >> 34) | (w10 << 30) & 0x1fffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*61+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w10 >> 31) | (w11 << 33) & 0x1fffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*61+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w11 >> 28) | (w12 << 36) & 0x1fffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*61+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w12 >> 25) | (w13 << 39) & 0x1fffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*61+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w13 >> 22) | (w14 << 42) & 0x1fffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*61+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w14 >> 19) | (w15 << 45) & 0x1fffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*61+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w15 >> 16) | (w16 << 48) & 0x1fffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*61+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w16 >> 13) | (w17 << 51) & 0x1fffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*61+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w17 >> 10) | (w18 << 54) & 0x1fffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*61+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w18 >> 7) | (w19 << 57) & 0x1fffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*61+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w19 >> 4) | (w20 << 60) & 0x1fffffffffffffff, nb,parm);\ + OUT(op,i*64+21, (w20 >> 1) & 0x1fffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*61+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w20 >> 62) | (w21 << 2) & 0x1fffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*61+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w21 >> 59) | (w22 << 5) & 0x1fffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*61+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w22 >> 56) | (w23 << 8) & 0x1fffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*61+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w23 >> 53) | (w24 << 11) & 0x1fffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*61+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w24 >> 50) | (w25 << 14) & 0x1fffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*61+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w25 >> 47) | (w26 << 17) & 0x1fffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*61+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w26 >> 44) | (w27 << 20) & 0x1fffffffffffffff, nb,parm); w28 = *(uint64_t *)(ip+(i*61+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w27 >> 41) | (w28 << 23) & 0x1fffffffffffffff, nb,parm); w29 = *(uint64_t *)(ip+(i*61+29)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w28 >> 38) | (w29 << 26) & 0x1fffffffffffffff, nb,parm); w30 = *(uint32_t *)(ip+(i*61+30)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w29 >> 35) | (w30 << 29) & 0x1fffffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_61(ip, op, nb,parm) { \ + BITUNBLK64_61(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 61*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_62(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30; w0 = *(uint64_t *)(ip+(i*31+0)*8/sizeof(ip[0]));\ + OUT(op,i*32+ 0, (w0 ) & 0x3fffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*31+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 1, (w0 >> 62) | (w1 << 2) & 0x3fffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*31+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 2, (w1 >> 60) | (w2 << 4) & 0x3fffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*31+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 3, (w2 >> 58) | (w3 << 6) & 0x3fffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*31+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 4, (w3 >> 56) | (w4 << 8) & 0x3fffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*31+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 5, (w4 >> 54) | (w5 << 10) & 0x3fffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*31+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 6, (w5 >> 52) | (w6 << 12) & 0x3fffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*31+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 7, (w6 >> 50) | (w7 << 14) & 0x3fffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*31+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 8, (w7 >> 48) | (w8 << 16) & 0x3fffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*31+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+ 9, (w8 >> 46) | (w9 << 18) & 0x3fffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*31+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+10, (w9 >> 44) | (w10 << 20) & 0x3fffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*31+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+11, (w10 >> 42) | (w11 << 22) & 0x3fffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*31+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+12, (w11 >> 40) | (w12 << 24) & 0x3fffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*31+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+13, (w12 >> 38) | (w13 << 26) & 0x3fffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*31+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+14, (w13 >> 36) | (w14 << 28) & 0x3fffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*31+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+15, (w14 >> 34) | (w15 << 30) & 0x3fffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*31+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+16, (w15 >> 32) | (w16 << 32) & 0x3fffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*31+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+17, (w16 >> 30) | (w17 << 34) & 0x3fffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*31+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+18, (w17 >> 28) | (w18 << 36) & 0x3fffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*31+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+19, (w18 >> 26) | (w19 << 38) & 0x3fffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*31+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+20, (w19 >> 24) | (w20 << 40) & 0x3fffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*31+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+21, (w20 >> 22) | (w21 << 42) & 0x3fffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*31+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+22, (w21 >> 20) | (w22 << 44) & 0x3fffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*31+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+23, (w22 >> 18) | (w23 << 46) & 0x3fffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*31+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+24, (w23 >> 16) | (w24 << 48) & 0x3fffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*31+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+25, (w24 >> 14) | (w25 << 50) & 0x3fffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*31+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+26, (w25 >> 12) | (w26 << 52) & 0x3fffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*31+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+27, (w26 >> 10) | (w27 << 54) & 0x3fffffffffffffff, nb,parm); w28 = *(uint64_t *)(ip+(i*31+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+28, (w27 >> 8) | (w28 << 56) & 0x3fffffffffffffff, nb,parm); w29 = *(uint64_t *)(ip+(i*31+29)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+29, (w28 >> 6) | (w29 << 58) & 0x3fffffffffffffff, nb,parm); w30 = *(uint64_t *)(ip+(i*31+30)*8/sizeof(ip[0]));\ +\ + OUT(op,i*32+30, (w29 >> 4) | (w30 << 60) & 0x3fffffffffffffff, nb,parm);\ + OUT(op,i*32+31, (w30 >> 2) , nb,parm);;\ +} + +#define BITUNPACK64_62(ip, op, nb,parm) { \ + BITUNBLK64_62(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 62*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_63(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31; w0 = *(uint64_t *)(ip+(i*63+0)*8/sizeof(ip[0]));\ + OUT(op,i*64+ 0, (w0 ) & 0x7fffffffffffffff, nb,parm); w1 = *(uint64_t *)(ip+(i*63+1)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 1, (w0 >> 63) | (w1 << 1) & 0x7fffffffffffffff, nb,parm); w2 = *(uint64_t *)(ip+(i*63+2)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 2, (w1 >> 62) | (w2 << 2) & 0x7fffffffffffffff, nb,parm); w3 = *(uint64_t *)(ip+(i*63+3)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 3, (w2 >> 61) | (w3 << 3) & 0x7fffffffffffffff, nb,parm); w4 = *(uint64_t *)(ip+(i*63+4)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 4, (w3 >> 60) | (w4 << 4) & 0x7fffffffffffffff, nb,parm); w5 = *(uint64_t *)(ip+(i*63+5)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 5, (w4 >> 59) | (w5 << 5) & 0x7fffffffffffffff, nb,parm); w6 = *(uint64_t *)(ip+(i*63+6)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 6, (w5 >> 58) | (w6 << 6) & 0x7fffffffffffffff, nb,parm); w7 = *(uint64_t *)(ip+(i*63+7)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 7, (w6 >> 57) | (w7 << 7) & 0x7fffffffffffffff, nb,parm); w8 = *(uint64_t *)(ip+(i*63+8)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 8, (w7 >> 56) | (w8 << 8) & 0x7fffffffffffffff, nb,parm); w9 = *(uint64_t *)(ip+(i*63+9)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+ 9, (w8 >> 55) | (w9 << 9) & 0x7fffffffffffffff, nb,parm); w10 = *(uint64_t *)(ip+(i*63+10)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+10, (w9 >> 54) | (w10 << 10) & 0x7fffffffffffffff, nb,parm); w11 = *(uint64_t *)(ip+(i*63+11)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+11, (w10 >> 53) | (w11 << 11) & 0x7fffffffffffffff, nb,parm); w12 = *(uint64_t *)(ip+(i*63+12)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+12, (w11 >> 52) | (w12 << 12) & 0x7fffffffffffffff, nb,parm); w13 = *(uint64_t *)(ip+(i*63+13)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+13, (w12 >> 51) | (w13 << 13) & 0x7fffffffffffffff, nb,parm); w14 = *(uint64_t *)(ip+(i*63+14)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+14, (w13 >> 50) | (w14 << 14) & 0x7fffffffffffffff, nb,parm); w15 = *(uint64_t *)(ip+(i*63+15)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+15, (w14 >> 49) | (w15 << 15) & 0x7fffffffffffffff, nb,parm); w16 = *(uint64_t *)(ip+(i*63+16)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+16, (w15 >> 48) | (w16 << 16) & 0x7fffffffffffffff, nb,parm); w17 = *(uint64_t *)(ip+(i*63+17)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+17, (w16 >> 47) | (w17 << 17) & 0x7fffffffffffffff, nb,parm); w18 = *(uint64_t *)(ip+(i*63+18)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+18, (w17 >> 46) | (w18 << 18) & 0x7fffffffffffffff, nb,parm); w19 = *(uint64_t *)(ip+(i*63+19)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+19, (w18 >> 45) | (w19 << 19) & 0x7fffffffffffffff, nb,parm); w20 = *(uint64_t *)(ip+(i*63+20)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+20, (w19 >> 44) | (w20 << 20) & 0x7fffffffffffffff, nb,parm); w21 = *(uint64_t *)(ip+(i*63+21)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+21, (w20 >> 43) | (w21 << 21) & 0x7fffffffffffffff, nb,parm); w22 = *(uint64_t *)(ip+(i*63+22)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+22, (w21 >> 42) | (w22 << 22) & 0x7fffffffffffffff, nb,parm); w23 = *(uint64_t *)(ip+(i*63+23)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+23, (w22 >> 41) | (w23 << 23) & 0x7fffffffffffffff, nb,parm); w24 = *(uint64_t *)(ip+(i*63+24)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+24, (w23 >> 40) | (w24 << 24) & 0x7fffffffffffffff, nb,parm); w25 = *(uint64_t *)(ip+(i*63+25)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+25, (w24 >> 39) | (w25 << 25) & 0x7fffffffffffffff, nb,parm); w26 = *(uint64_t *)(ip+(i*63+26)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+26, (w25 >> 38) | (w26 << 26) & 0x7fffffffffffffff, nb,parm); w27 = *(uint64_t *)(ip+(i*63+27)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+27, (w26 >> 37) | (w27 << 27) & 0x7fffffffffffffff, nb,parm); w28 = *(uint64_t *)(ip+(i*63+28)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+28, (w27 >> 36) | (w28 << 28) & 0x7fffffffffffffff, nb,parm); w29 = *(uint64_t *)(ip+(i*63+29)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+29, (w28 >> 35) | (w29 << 29) & 0x7fffffffffffffff, nb,parm); w30 = *(uint64_t *)(ip+(i*63+30)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+30, (w29 >> 34) | (w30 << 30) & 0x7fffffffffffffff, nb,parm); w31 = *(uint32_t *)(ip+(i*63+31)*8/sizeof(ip[0]));\ +\ + OUT(op,i*64+31, (w30 >> 33) | (w31 << 31) & 0x7fffffffffffffff, nb,parm);;\ +} + +#define BITUNPACK64_63(ip, op, nb,parm) { \ + BITUNBLK64_63(ip, 0, op, nb,parm); OPI(op, nb,parm); ip += 63*4/sizeof(ip[0]);\ +} + +#define BITUNBLK64_64(ip, i, op, nb,parm) { uint64_t w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w17,w18,w19,w20,w21,w22,w23,w24,w25,w26,w27,w28,w29,w30,w31; w0 = *(uint64_t *)(ip+(i*1+0)*8/sizeof(ip[0]));\ + OUT(op,i*1+ 0, (w0 ) , nb,parm);;\ +} + +#define BITUNPACK64_64(ip, op, nb,parm) { \ + BITUNBLK64_64(ip, 0, op, nb,parm);\ + BITUNBLK64_64(ip, 1, op, nb,parm);\ + BITUNBLK64_64(ip, 2, op, nb,parm);\ + BITUNBLK64_64(ip, 3, op, nb,parm);\ + BITUNBLK64_64(ip, 4, op, nb,parm);\ + BITUNBLK64_64(ip, 5, op, nb,parm);\ + BITUNBLK64_64(ip, 6, op, nb,parm);\ + BITUNBLK64_64(ip, 7, op, nb,parm);\ + BITUNBLK64_64(ip, 8, op, nb,parm);\ + BITUNBLK64_64(ip, 9, op, nb,parm);\ + BITUNBLK64_64(ip, 10, op, nb,parm);\ + BITUNBLK64_64(ip, 11, op, nb,parm);\ + BITUNBLK64_64(ip, 12, op, nb,parm);\ + BITUNBLK64_64(ip, 13, op, nb,parm);\ + BITUNBLK64_64(ip, 14, op, nb,parm);\ + BITUNBLK64_64(ip, 15, op, nb,parm);\ + BITUNBLK64_64(ip, 16, op, nb,parm);\ + BITUNBLK64_64(ip, 17, op, nb,parm);\ + BITUNBLK64_64(ip, 18, op, nb,parm);\ + BITUNBLK64_64(ip, 19, op, nb,parm);\ + BITUNBLK64_64(ip, 20, op, nb,parm);\ + BITUNBLK64_64(ip, 21, op, nb,parm);\ + BITUNBLK64_64(ip, 22, op, nb,parm);\ + BITUNBLK64_64(ip, 23, op, nb,parm);\ + BITUNBLK64_64(ip, 24, op, nb,parm);\ + BITUNBLK64_64(ip, 25, op, nb,parm);\ + BITUNBLK64_64(ip, 26, op, nb,parm);\ + BITUNBLK64_64(ip, 27, op, nb,parm);\ + BITUNBLK64_64(ip, 28, op, nb,parm);\ + BITUNBLK64_64(ip, 29, op, nb,parm);\ + BITUNBLK64_64(ip, 30, op, nb,parm);\ + BITUNBLK64_64(ip, 31, op, nb,parm); OPI(op, nb,parm); ip += 64*4/sizeof(ip[0]);\ +} + +#ifndef DELTA +#define USIZE 8 +unsigned char *TEMPLATE2(_BITUNPACK_,8_0)(const unsigned char *__restrict in, unsigned n, uint8_t *__restrict out ) { unsigned char *in_=in+PAD8(n*0); const uint8_t *out_ = out+n; do { BITUNPACK64_0( in, out, 0,start); PREFETCH(in+512,0); } while(out //nan +#include "conf.h" +#define BITUTIL_IN +#include "bitutil.h" + +//------------ 'or' for bitsize + 'xor' for all duplicate ------------------ +#define BT(_i_) { o |= ip[_i_]; x |= ip[_i_] ^ u0; } +#define BIT(_in_, _n_, _usize_) {\ + u0 = _in_[0]; o = x = 0;\ + for(ip = _in_; ip != _in_+(_n_&~(4-1)); ip += 4) { BT(0); BT(1); BT(2); BT(3); }\ + for(;ip != _in_+_n_; ip++) BT(0);\ +} + +uint8_t bit8( uint8_t *in, unsigned n, uint8_t *px) { uint8_t o,x,u0,*ip; BIT(in, n, 8); if(px) *px = x; return o; } +uint64_t bit64(uint64_t *in, unsigned n, uint64_t *px) { uint64_t o,x,u0,*ip; BIT(in, n, 64); if(px) *px = x; return o; } + +uint16_t bit16(uint16_t *in, unsigned n, uint16_t *px) { + uint16_t o, x, u0 = in[0], *ip; + #if defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi16(u0), vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m128i v0 = _mm_loadu_si128((__m128i *) ip); + __m128i v1 = _mm_loadu_si128((__m128i *)(ip+8)); + vo0 = _mm_or_si128( vo0, v0); + vo1 = _mm_or_si128( vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi16(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi16(vx0); + #else + ip = in; o = x = 0; //BIT( in, n, 16); + #endif + for(; ip != in+n; ip++) BT(0); + if(px) *px = x; + return o; +} + +uint32_t bit32(uint32_t *in, unsigned n, uint32_t *px) { + uint32_t o,x,u0 = in[0], *ip; + #ifdef __AVX2__ + __m256i vb0 = _mm256_set1_epi32(*in), vo0 = _mm256_setzero_si256(), vx0 = _mm256_setzero_si256(), + vo1 = _mm256_setzero_si256(), vx1 = _mm256_setzero_si256(); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m256i v0 = _mm256_loadu_si256((__m256i *) ip); + __m256i v1 = _mm256_loadu_si256((__m256i *)(ip+8)); + vo0 = _mm256_or_si256(vo0, v0); + vo1 = _mm256_or_si256(vo1, v1); + vx0 = _mm256_or_si256(vx0, _mm256_xor_si256(v0, vb0)); + vx1 = _mm256_or_si256(vx1, _mm256_xor_si256(v1, vb0)); + } + vo0 = _mm256_or_si256(vo0, vo1); o = mm256_hor_epi32(vo0); + vx0 = _mm256_or_si256(vx0, vx1); x = mm256_hor_epi32(vx0); + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi32(u0), vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); + for(ip = in; ip != in+(n&~(8-1)); ip += 8) { PREFETCH(ip+512,0); + __m128i v0 = _mm_loadu_si128((__m128i *) ip); + __m128i v1 = _mm_loadu_si128((__m128i *)(ip+4)); + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi32(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi32(vx0); + #else + ip = in; o = x = 0; //BIT( in, n, 32); + #endif + for(; ip != in+n; ip++) BT(0); + if(px) *px = x; + return o; +} + +//----------------------------------------------------------- Delta ---------------------------------------------------------------- +#define DE(_ip_,_i_) u = (_ip_[_i_]-start)-_md; start = _ip_[_i_]; +#define BITDE(_t_, _in_, _n_, _md_, _act_) { _t_ _md = _md_, *_ip; o = x = 0;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { DE(_ip,0);_act_; DE(_ip,1);_act_; DE(_ip,2);_act_; DE(_ip,3);_act_; }\ + for(;_ip != _in_+_n_;_ip++) { DE(_ip,0); _act_; }\ +} +//---- (min. Delta = 0) +//-- delta encoding +uint8_t bitd8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { uint8_t u, u0 = in[0]-start, o, x; BITDE(uint8_t, in, n, 0, o |= u; x |= u^u0); if(px) *px = x; return o; } +uint64_t bitd64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { uint64_t u, u0 = in[0]-start, o, x; BITDE(uint64_t, in, n, 0, o |= u; x |= u^u0); if(px) *px = x; return o; } + +uint16_t bitd16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { + uint16_t o, x, *ip, u0 = in[0]-start; + #if defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi16(u0), + vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); __m128i vs = _mm_set1_epi16(start); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m128i vi0 = _mm_loadu_si128((__m128i *) ip); + __m128i vi1 = _mm_loadu_si128((__m128i *)(ip+8)); __m128i v0 = mm_delta_epi16(vi0,vs); vs = vi0; + __m128i v1 = mm_delta_epi16(vi1,vs); vs = vi1; + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } start = _mm_cvtsi128_si16(_mm_srli_si128(vs,14)); + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi16(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi16(vx0); + #else + ip = in; o = x = 0; + #endif + for(;ip != in+n; ip++) { + uint16_t u = *ip - start; start = *ip; + o |= u; + x |= u ^ u0; + } + if(px) *px = x; + return o; +} + +uint32_t bitd32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { + uint32_t o, x, *ip, u0 = in[0] - start; + #ifdef __AVX2__ + __m256i vb0 = _mm256_set1_epi32(u0), + vo0 = _mm256_setzero_si256(), vx0 = _mm256_setzero_si256(), + vo1 = _mm256_setzero_si256(), vx1 = _mm256_setzero_si256(); __m256i vs = _mm256_set1_epi32(start); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m256i vi0 = _mm256_loadu_si256((__m256i *) ip); + __m256i vi1 = _mm256_loadu_si256((__m256i *)(ip+8)); __m256i v0 = mm256_delta_epi32(vi0,vs); vs = vi0; + __m256i v1 = mm256_delta_epi32(vi1,vs); vs = vi1; + vo0 = _mm256_or_si256(vo0, v0); + vo1 = _mm256_or_si256(vo1, v1); + vx0 = _mm256_or_si256(vx0, _mm256_xor_si256(v0, vb0)); + vx1 = _mm256_or_si256(vx1, _mm256_xor_si256(v1, vb0)); + } start = (unsigned)_mm256_extract_epi32(vs, 7); + vo0 = _mm256_or_si256(vo0, vo1); o = mm256_hor_epi32(vo0); + vx0 = _mm256_or_si256(vx0, vx1); x = mm256_hor_epi32(vx0); + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi32(u0), + vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); __m128i vs = _mm_set1_epi32(start); + for(ip = in; ip != in+(n&~(8-1)); ip += 8) { PREFETCH(ip+512,0); + __m128i vi0 = _mm_loadu_si128((__m128i *)ip); + __m128i vi1 = _mm_loadu_si128((__m128i *)(ip+4)); __m128i v0 = mm_delta_epi32(vi0,vs); vs = vi0; + __m128i v1 = mm_delta_epi32(vi1,vs); vs = vi1; + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } start = _mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi32(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi32(vx0); + #else + ip = in; o = x = 0; + #endif + for(;ip != in+n; ip++) { + uint32_t u = *ip - start; start = *ip; + o |= u; + x |= u ^ u0; + } + if(px) *px = x; + return o; +} + +//----- Undelta: In-place prefix sum (min. Delta = 0) ------------------- +#define DD(i) _ip[i] = (start += _ip[i] + _md); +#define BITDD(_t_, _in_, _n_, _md_) { _t_ *_ip; const _md = _md_;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { DD(0); DD(1); DD(2); DD(3); }\ + for(;_ip != _in_+_n_; _ip++) DD(0);\ +} + +void bitddec8( uint8_t *p, unsigned n, uint8_t start) { BITDD(uint8_t, p, n, 0); } +void bitddec16(uint16_t *p, unsigned n, uint16_t start) { BITDD(uint16_t, p, n, 0); } +void bitddec64(uint64_t *p, unsigned n, uint64_t start) { BITDD(uint64_t, p, n, 0); } +void bitddec32(uint32_t *p, unsigned n, unsigned start) { + #ifdef __AVX2__ + __m256i vs = _mm256_set1_epi32(start); + unsigned *ip; + for(ip = p; ip != p+(n&~(8-1)); ip += 8) { + __m256i v = _mm256_loadu_si256((__m256i *)ip); + vs = mm256_scan_epi32(v,vs); + _mm256_storeu_si256((__m256i *)ip, vs); + } + start = (unsigned)_mm256_extract_epi32(vs, 7); + while(ip != p+n) { + *ip = (start += (*ip)); + ip++; + } + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vs = _mm_set1_epi32(start); + unsigned *ip; + for(ip = p; ip != p+(n&~(4-1)); ip += 4) { + __m128i v = _mm_loadu_si128((__m128i *)ip); + vs = mm_scan_epi32(v, vs); + _mm_storeu_si128((__m128i *)ip, vs); + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + while(ip != p+n) { + *ip = (start += (*ip)); + ip++; + } + #else + BITDD(uint32_t, p, n, 0); + #endif +} + +//----------- Zigzag of Delta -------------------------- +#define ZDE(i, _usize_) d = (_ip[i]-start)-_md; u = TEMPLATE2(zigzagenc, _usize_)(d - startd); startd = d; start = _ip[i] +#define BITZDE(_t_, _in_, _n_, _md_, _usize_, _act_) { _t_ *_ip, _md = _md_;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { ZDE(0, _usize_);_act_; ZDE(1, _usize_);_act_; ZDE(2, _usize_);_act_; ZDE(3, _usize_);_act_; }\ + for(;_ip != _in_+_n_;_ip++) { ZDE(0, _usize_); _act_; }\ +} + +uint8_t bitzz8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { uint8_t o=0, x=0,d,startd=0,u; BITZDE(uint8_t, in, n, 1, 8, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint16_t bitzz16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { uint16_t o=0, x=0,d,startd=0,u; BITZDE(uint16_t, in, n, 1, 16, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint32_t bitzz32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { uint64_t o=0, x=0,d,startd=0,u; BITZDE(uint32_t, in, n, 1, 32, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint64_t bitzz64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { uint64_t o=0, x=0,d,startd=0,u; BITZDE(uint64_t, in, n, 1, 64, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint8_t bitzzenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta) { uint8_t o=0,*op = out,u,d,startd=0; BITZDE(uint8_t, in, n, mindelta, 8,o |= u;*op++ = u); return o;} +uint16_t bitzzenc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta) { uint16_t o=0,*op = out,u,d,startd=0; BITZDE(uint16_t, in, n, mindelta, 16,o |= u;*op++ = u); return o;} +uint32_t bitzzenc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta) { uint32_t o=0,*op = out,u,d,startd=0; BITZDE(uint32_t, in, n, mindelta, 32,o |= u;*op++ = u); return o;} +uint64_t bitzzenc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta) { uint64_t o=0,*op = out,u,d,startd=0; BITZDE(uint64_t, in, n, mindelta, 64,o |= u;*op++ = u); return o;} + +#define ZDD(i) u = _ip[i]; d = u - start; _ip[i] = zigzagdec64(u)+(int64_t)startd+_md; startd = d; start = u +#define BITZDD(_t_, _in_, _n_, _md_) { _t_ *_ip, startd=0,d,u; const _md = _md_;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { ZDD(0); ZDD(1); ZDD(2); ZDD(3); }\ + for(;_ip != _in_+_n_; _ip++) ZDD(0);\ +} +void bitzzdec8( uint8_t *p, unsigned n, uint8_t start) { BITZDD(uint8_t, p, n, 1); } +void bitzzdec16(uint16_t *p, unsigned n, uint16_t start) { BITZDD(uint16_t, p, n, 1); } +void bitzzdec64(uint64_t *p, unsigned n, uint64_t start) { BITZDD(uint64_t, p, n, 1); } +void bitzzdec32(uint32_t *p, unsigned n, uint32_t start) { BITZDD(uint32_t, p, n, 1); } + +//-----Undelta: In-place prefix sum (min. Delta = 1) ------------------- +uint8_t bitd18( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { uint8_t o=0,x=0,u,*ip; BITDE(uint8_t, in, n, 1, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint16_t bitd116(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { uint16_t o=0,x=0,u,*ip; BITDE(uint16_t, in, n, 1, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } +uint64_t bitd164(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { uint64_t o=0,x=0,u,*ip; BITDE(uint64_t, in, n, 1, o |= u; x |= u ^ in[0]); if(px) *px = x; return o; } + +uint32_t bitd132(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { + uint32_t o, x, *ip, u0 = in[0]-start-1; + #ifdef __AVX2__ + __m256i vb0 = _mm256_set1_epi32(u0), + vo0 = _mm256_setzero_si256(), vx0 = _mm256_setzero_si256(), + vo1 = _mm256_setzero_si256(), vx1 = _mm256_setzero_si256(); __m256i vs = _mm256_set1_epi32(start), cv = _mm256_set1_epi32(1); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m256i vi0 = _mm256_loadu_si256((__m256i *)ip); + __m256i vi1 = _mm256_loadu_si256((__m256i *)(ip+8)); __m256i v0 = _mm256_sub_epi32(mm256_delta_epi32(vi0,vs),cv); vs = vi0; + __m256i v1 = _mm256_sub_epi32(mm256_delta_epi32(vi1,vs),cv); vs = vi1; + vo0 = _mm256_or_si256(vo0, v0); + vo1 = _mm256_or_si256(vo1, v1); + vx0 = _mm256_or_si256(vx0, _mm256_xor_si256(v0, vb0)); + vx1 = _mm256_or_si256(vx1, _mm256_xor_si256(v1, vb0)); + } start = (unsigned)_mm256_extract_epi32(vs, 7); + vo0 = _mm256_or_si256(vo0, vo1); o = mm256_hor_epi32(vo0); + vx0 = _mm256_or_si256(vx0, vx1); x = mm256_hor_epi32(vx0); + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi32(u0), + vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); __m128i vs = _mm_set1_epi32(start), cv = _mm_set1_epi32(1); + for(ip = in; ip != in+(n&~(8-1)); ip += 8) { PREFETCH(ip+512,0); + __m128i vi0 = _mm_loadu_si128((__m128i *)ip); + __m128i vi1 = _mm_loadu_si128((__m128i *)(ip+4)); __m128i v0 = _mm_sub_epi32(mm_delta_epi32(vi0,vs),cv); vs = vi0; + __m128i v1 = _mm_sub_epi32(mm_delta_epi32(vi1,vs),cv); vs = vi1; + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } start = _mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi32(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi32(vx0); + #else + ip = in; o = x = 0; + #endif + for(;ip != in+n; ip++) { + uint32_t u = ip[0] - start-1; start = *ip; + o |= u; + x |= u ^ u0; + } + if(px) *px = x; + return o; +} + +uint16_t bits128v16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { + #if defined(__SSE2__) || defined(__ARM_NEON) + unsigned *ip,b; __m128i bv = _mm_setzero_si128(), vs = _mm_set1_epi16(start), cv = _mm_set1_epi16(8); + for(ip = in; ip != in+(n&~(4-1)); ip += 4) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + bv = _mm_or_si128(bv,_mm_sub_epi16(SUBI16x8(iv,vs),cv)); + vs = iv; + } + start = (unsigned short)_mm_cvtsi128_si32(_mm_srli_si128(vs,14)); + b = mm_hor_epi16(bv); + if(px) *px = 0; + return b; + #endif +} + +unsigned bits128v32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { + #if defined(__SSE2__) || defined(__ARM_NEON) + unsigned *ip,b; __m128i bv = _mm_setzero_si128(), vs = _mm_set1_epi32(start), cv = _mm_set1_epi32(4); + for(ip = in; ip != in+(n&~(4-1)); ip += 4) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + bv = _mm_or_si128(bv,_mm_sub_epi32(SUBI32x4(iv,vs),cv)); + vs = iv; + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + b = mm_hor_epi32(bv); + if(px) *px = 0; + return b; + #endif +} + +void bitd1dec8( uint8_t *p, unsigned n, uint8_t start) { BITDD(uint8_t, p, n, 1); } +void bitd1dec16(uint16_t *p, unsigned n, uint16_t start) { BITDD(uint16_t, p, n, 1); } +void bitd1dec64(uint64_t *p, unsigned n, uint64_t start) { BITDD(uint64_t, p, n, 1); } +void bitd1dec32(uint32_t *p, unsigned n, uint32_t start) { + #ifdef __AVX2__ + __m256i vs = _mm256_set1_epi32(start),zv = _mm256_setzero_si256(), cv = _mm256_set_epi32(8,7,6,5,4,3,2,1); + unsigned *ip; + for(ip = p; ip != p+(n&~(8-1)); ip += 8) { + __m256i v = _mm256_loadu_si256((__m256i *)ip); vs = mm256_scani_epi32(v, vs, cv); + _mm256_storeu_si256((__m256i *)ip, vs); + } + start = (unsigned)_mm256_extract_epi32(vs, 7); + while(ip != p+n) { + *ip = (start += (*ip) + 1); + ip++; + } + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vs = _mm_set1_epi32(start), cv = _mm_set_epi32(4,3,2,1); + unsigned *ip; + for(ip = p; ip != p+(n&~(4-1)); ip += 4) { + __m128i v = _mm_loadu_si128((__m128i *)ip); + vs = mm_scani_epi32(v, vs, cv); + _mm_storeu_si128((__m128i *)ip, vs); + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + while(ip != p+n) { + *ip = (start += (*ip) + 1); + ip++; + } + #else + BITDD(uint32_t, p, n, 1); + #endif +} + +//---------Delta encoding/decoding (min. Delta = mindelta) ------------------- +//determine min. delta for encoding w/ bitdiencNN function +#define DI(_ip_,_i_) u = _ip_[_i_] - start; start = _ip_[_i_]; if(u < mindelta) mindelta = u +#define BITDIE(_in_, _n_) {\ + for(_ip = _in_,mindelta = _ip[0]; _ip != _in_+(_n_&~(4-1)); _ip+=4) { DI(_ip,0); DI(_ip,1); DI(_ip,2); DI(_ip,3); }\ + for(;_ip != _in_+_n_;_ip++) DI(_ip,0);\ +} + +uint8_t bitdi8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { uint8_t mindelta,u,*_ip; BITDIE(in, n); if(px) *px = 0; return mindelta; } +uint16_t bitdi16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { uint16_t mindelta,u,*_ip; BITDIE(in, n); if(px) *px = 0; return mindelta; } +uint32_t bitdi32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { uint32_t mindelta,u,*_ip; BITDIE(in, n); if(px) *px = 0; return mindelta; } +uint64_t bitdi64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { uint64_t mindelta,u,*_ip; BITDIE(in, n); if(px) *px = 0; return mindelta; } + +uint8_t bitdienc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta) { uint8_t o=0,x=0,*op = out,u,*ip; BITDE(uint8_t, in, n, mindelta, o |= u; x |= u ^ in[0]; *op++ = u); return o; } +uint16_t bitdienc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta) { uint16_t o=0,x=0,*op = out,u,*ip; BITDE(uint16_t, in, n, mindelta, o |= u; x |= u ^ in[0]; *op++ = u); return o; } +uint64_t bitdienc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta) { uint64_t o=0,x=0,*op = out,u,*ip; BITDE(uint64_t, in, n, mindelta, o |= u; x |= u ^ in[0]; *op++ = u); return o; } +uint32_t bitdienc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta) { + #if defined(__SSE2__) || defined(__ARM_NEON) + unsigned *ip,b,*op = out; + __m128i bv = _mm_setzero_si128(), vs = _mm_set1_epi32(start), cv = _mm_set1_epi32(mindelta), dv; + for(ip = in; ip != in+(n&~(4-1)); ip += 4,op += 4) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + bv = _mm_or_si128(bv, dv = _mm_sub_epi32(mm_delta_epi32(iv,vs),cv)); + vs = iv; + _mm_storeu_si128((__m128i *)op, dv); + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + b = mm_hor_epi32(bv); + while(ip != in+n) { + unsigned x = *ip-start-mindelta; + start = *ip++; + b |= x; + *op++ = x; + } + #else + uint32_t b = 0,*op = out, x, *_ip; + BITDE(uint32_t, in, n, mindelta, b |= x; *op++ = x); + #endif + return b; +} + +void bitdidec8( uint8_t *p, unsigned n, uint8_t start, uint8_t mindelta) { BITDD(uint8_t, p, n, mindelta); } +void bitdidec16( uint16_t *p, unsigned n, uint16_t start, uint16_t mindelta) { BITDD(uint16_t, p, n, mindelta); } +void bitdidec32( uint32_t *p, unsigned n, uint32_t start, uint32_t mindelta) { BITDD(uint32_t, p, n, mindelta); } +void bitdidec64( uint64_t *p, unsigned n, uint64_t start, uint64_t mindelta) { BITDD(uint64_t, p, n, mindelta); } + +//------------------- For ------------------------------ +uint8_t bitf8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { if(px) *px = 0; return n?in[n-1] - start :0; } +uint8_t bitf18( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { if(px) *px = 0; return n?in[n-1] - start - n:0; } +uint16_t bitf16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { if(px) *px = 0; return n?in[n-1] - start :0; } +uint16_t bitf116(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { if(px) *px = 0; return n?in[n-1] - start - n:0; } +uint32_t bitf32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { if(px) *px = 0; return n?in[n-1] - start :0; } +uint32_t bitf132(uint32_t *in, unsigned n, uint32_t *px, uint32_t start) { if(px) *px = 0; return n?in[n-1] - start - n:0; } +uint64_t bitf64( uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { if(px) *px = 0; return n?in[n-1] - start :0; } +uint64_t bitf164(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { if(px) *px = 0; return n?in[n-1] - start - n:0; } + +//------------------- Zigzag --------------------------- +#define ZE(i,_it_,_usize_) u = TEMPLATE2(zigzagenc, _usize_)((_it_)_ip[i]-(_it_)start); start = _ip[i] +#define BITZENC(_ut_, _it_, _usize_, _in_,_n_, _act_) { _ut_ *_ip; o = 0; x = -1;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { ZE(0,_it_,_usize_);_act_; ZE(1,_it_,_usize_);_act_; ZE(2,_it_,_usize_);_act_; ZE(3,_it_,_usize_);_act_; }\ + for(;_ip != _in_+_n_; _ip++) { ZE(0,_it_,_usize_); _act_; }\ +} + +// 'or' bits for zigzag encoding +uint8_t bitz8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start) { uint8_t o, u,x; BITZENC(uint8_t, int8_t, 8, in, n, o |= x); if(px) *px = 0; return o; } +uint64_t bitz64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start) { uint64_t o, u,x; BITZENC(uint64_t, int64_t,64,in, n, o |= x); if(px) *px = 0; return o; } + +uint16_t bitz16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start) { + uint16_t o, x, *ip; uint32_t u0 = zigzagenc16((int)in[0] - (int)start); + + #if defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi16(u0), vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); __m128i vs = _mm_set1_epi16(start); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m128i vi0 = _mm_loadu_si128((__m128i *) ip); + __m128i vi1 = _mm_loadu_si128((__m128i *)(ip+8)); __m128i v0 = mm_delta_epi16(vi0,vs); vs = vi0; v0 = mm_zzage_epi16(v0); + __m128i v1 = mm_delta_epi16(vi1,vs); vs = vi1; v1 = mm_zzage_epi16(v1); + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } start = _mm_cvtsi128_si16(_mm_srli_si128(vs,14)); + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi16(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi16(vx0); + #else + ip = in; //uint16_t u; o=x=0; BITDE(uint16_t, in, n, 0, o |= u; x |= u^u0); //BITZENC(uint16_t, int16_t, 16, in, n, o |= u,x &= u^u0); + #endif + for(;ip != in+n; ip++) { + uint16_t u = zigzagenc16((int)ip[0] - (int)start); //int i = ((int)(*ip) - (int)start); i = (i << 1) ^ (i >> 15); + start = *ip; + o |= u; + x |= u ^ u0; + } + if(px) *px = x; + return o; +} + +uint32_t bitz32(unsigned *in, unsigned n, uint32_t *px, unsigned start) { + uint32_t o, x, *ip; uint32_t u0 = zigzagenc32((int)in[0] - (int)start); + #ifdef __AVX2__ + __m256i vb0 = _mm256_set1_epi32(u0), vo0 = _mm256_setzero_si256(), vx0 = _mm256_setzero_si256(), + vo1 = _mm256_setzero_si256(), vx1 = _mm256_setzero_si256(); __m256i vs = _mm256_set1_epi32(start); + for(ip = in; ip != in+(n&~(16-1)); ip += 16) { PREFETCH(ip+512,0); + __m256i vi0 = _mm256_loadu_si256((__m256i *) ip); + __m256i vi1 = _mm256_loadu_si256((__m256i *)(ip+8)); __m256i v0 = mm256_delta_epi32(vi0,vs); vs = vi0; v0 = mm256_zzage_epi32(v0); + __m256i v1 = mm256_delta_epi32(vi1,vs); vs = vi1; v1 = mm256_zzage_epi32(v1); + vo0 = _mm256_or_si256(vo0, v0); + vo1 = _mm256_or_si256(vo1, v1); + vx0 = _mm256_or_si256(vx0, _mm256_xor_si256(v0, vb0)); + vx1 = _mm256_or_si256(vx1, _mm256_xor_si256(v1, vb0)); + } start = (unsigned)_mm256_extract_epi32(vs, 7); + vo0 = _mm256_or_si256(vo0, vo1); o = mm256_hor_epi32(vo0); + vx0 = _mm256_or_si256(vx0, vx1); x = mm256_hor_epi32(vx0); + + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vb0 = _mm_set1_epi32(u0), + vo0 = _mm_setzero_si128(), vx0 = _mm_setzero_si128(), + vo1 = _mm_setzero_si128(), vx1 = _mm_setzero_si128(); __m128i vs = _mm_set1_epi32(start); + for(ip = in; ip != in+(n&~(8-1)); ip += 8) { PREFETCH(ip+512,0); + __m128i vi0 = _mm_loadu_si128((__m128i *) ip); + __m128i vi1 = _mm_loadu_si128((__m128i *)(ip+4)); __m128i v0 = mm_delta_epi32(vi0,vs); vs = vi0; v0 = mm_zzage_epi32(v0); + __m128i v1 = mm_delta_epi32(vi1,vs); vs = vi1; v1 = mm_zzage_epi32(v1); + vo0 = _mm_or_si128(vo0, v0); + vo1 = _mm_or_si128(vo1, v1); + vx0 = _mm_or_si128(vx0, _mm_xor_si128(v0, vb0)); + vx1 = _mm_or_si128(vx1, _mm_xor_si128(v1, vb0)); + } start = _mm_cvtsi128_si16(_mm_srli_si128(vs,12)); + vo0 = _mm_or_si128(vo0, vo1); o = mm_hor_epi32(vo0); + vx0 = _mm_or_si128(vx0, vx1); x = mm_hor_epi32(vx0); + #else + ip = in; o = x = 0; //uint32_t u; BITDE(uint32_t, in, n, 0, o |= u; x |= u^u0); + #endif + for(;ip != in+n; ip++) { + uint32_t u = zigzagenc32((int)ip[0] - (int)start); start = *ip; //((int)(*ip) - (int)start); //i = (i << 1) ^ (i >> 31); + o |= u; + x |= u ^ u0; + } + if(px) *px = x; + return o; +} + +uint8_t bitzenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta) { uint8_t o,x,u,*op = out; BITZENC(uint8_t, int8_t, 8,in, n, o |= u; *op++ = u); return o; } +uint16_t bitzenc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta) { uint16_t o,x,u,*op = out; BITZENC(uint16_t, int16_t,16,in, n, o |= u; *op++ = u); return o; } +uint64_t bitzenc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta) { uint64_t o,x,u,*op = out; BITZENC(uint64_t, int64_t,64,in, n, o |= u; *op++ = u); return o; } +uint32_t bitzenc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta) { + #if defined(__SSE2__) || defined(__ARM_NEON) + unsigned *ip,b,*op = out; + __m128i bv = _mm_setzero_si128(), vs = _mm_set1_epi32(start), dv; + for(ip = in; ip != in+(n&~(4-1)); ip += 4,op += 4) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + dv = mm_delta_epi32(iv,vs); vs = iv; + dv = mm_zzage_epi32(dv); + bv = _mm_or_si128(bv, dv); + _mm_storeu_si128((__m128i *)op, dv); + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + b = mm_hor_epi32(bv); + while(ip != in+n) { + int x = ((int)(*ip)-(int)start); + x = (x << 1) ^ (x >> 31); + start = *ip++; + b |= x; + *op++ = x; + } + #else + uint32_t b = 0, *op = out,x; + BITZENC(uint32_t, int32_t, 32,in, n, b |= x; *op++ = x); + #endif + return bsr32(b); +} + +#define ZD(_t_, _usize_, i) { _t_ _z = _ip[i]; _ip[i] = (start += TEMPLATE2(zigzagdec, _usize_)(_z)); } +#define BITZDEC(_t_, _usize_, _in_, _n_) { _t_ *_ip;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { ZD(_t_, _usize_, 0); ZD(_t_, _usize_, 1); ZD(_t_, _usize_, 2); ZD(_t_, _usize_, 3); }\ + for(;_ip != _in_+_n_;_ip++) ZD(_t_, _usize_, 0);\ +} + +void bitzdec8( uint8_t *p, unsigned n, uint8_t start) { BITZDEC(uint8_t, 8, p, n); } +void bitzdec64(uint64_t *p, unsigned n, uint64_t start) { BITZDEC(uint64_t, 64,p, n); } + +void bitzdec16(uint16_t *p, unsigned n, uint16_t start) { + #if defined(__SSSE3__) || defined(__ARM_NEON) + __m128i vs = _mm_set1_epi16(start); //, c1 = _mm_set1_epi32(1), cz = _mm_setzero_si128(); + uint16_t *ip; + for(ip = p; ip != p+(n&~(8-1)); ip += 8) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + iv = mm_zzagd_epi16(iv); + vs = mm_scan_epi16(iv, vs); + _mm_storeu_si128((__m128i *)ip, vs); + } + start = (uint16_t)_mm_cvtsi128_si32(_mm_srli_si128(vs,14)); + while(ip != p+n) { + uint16_t z = *ip; + *ip++ = (start += (z >> 1 ^ -(z & 1))); + } + #else + BITZDEC(uint16_t, 16, p, n); + #endif +} + +void bitzdec32(unsigned *p, unsigned n, unsigned start) { + #ifdef __AVX2__ + __m256i vs = _mm256_set1_epi32(start); //, zv = _mm256_setzero_si256()*/; //, c1 = _mm_set1_epi32(1), cz = _mm_setzero_si128(); + unsigned *ip; + for(ip = p; ip != p+(n&~(8-1)); ip += 8) { + __m256i iv = _mm256_loadu_si256((__m256i *)ip); + iv = mm256_zzagd_epi32(iv); + vs = mm256_scan_epi32(iv,vs); + _mm256_storeu_si256((__m256i *)ip, vs); + } + start = (unsigned)_mm256_extract_epi32(_mm256_srli_si256(vs,12), 4); + while(ip != p+n) { + unsigned z = *ip; + *ip++ = (start += (z >> 1 ^ -(z & 1))); + } + #elif defined(__SSE2__) || defined(__ARM_NEON) + __m128i vs = _mm_set1_epi32(start); //, c1 = _mm_set1_epi32(1), cz = _mm_setzero_si128(); + unsigned *ip; + for(ip = p; ip != p+(n&~(4-1)); ip += 4) { + __m128i iv = _mm_loadu_si128((__m128i *)ip); + iv = mm_zzagd_epi32(iv); + vs = mm_scan_epi32(iv, vs); + _mm_storeu_si128((__m128i *)ip, vs); + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(vs,12)); + while(ip != p+n) { + unsigned z = *ip; + *ip++ = (start += zigzagdec32(z)); + } + #else + BITZDEC(uint32_t, 32, p, n); + #endif +} + +//----------------------- XOR : return max. bits --------------------------------- +#define XE(i) x = _ip[i] ^ start; start = _ip[i] +#define BITXENC(_t_, _in_, _n_, _act_) { _t_ *_ip;\ + for(_ip = _in_; _ip != _in_+(_n_&~(4-1)); _ip += 4) { XE(0);_act_; XE(1);_act_; XE(2);_act_; XE(3);_act_; }\ + for( ; _ip != _in_+ _n_; _ip++ ) { XE(0);_act_; }\ +} +uint8_t bitxenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start) { uint8_t b = 0,*op = out,x; BITXENC(uint8_t, in, n, b |= x; *op++ = x); return b; } +uint16_t bitxenc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start) { uint16_t b = 0,*op = out,x; BITXENC(uint16_t, in, n, b |= x; *op++ = x); return b; } +uint32_t bitxenc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start) { uint32_t b = 0,*op = out,x; BITXENC(uint32_t, in, n, b |= x; *op++ = x); return b; } +uint64_t bitxenc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start) { uint64_t b = 0,*op = out,x; BITXENC(uint64_t, in, n, b |= x; *op++ = x); return b; } + +#define XD(i) _ip[i] = (start ^= _ip[i]) +#define BITXDEC(_t_, _in_, _n_) { _t_ *_ip, _x;\ + for(_ip = _in_;_ip != _in_+(_n_&~(4-1)); _ip += 4) { XD(0); XD(1); XD(2); XD(3); }\ + for( ;_ip != _in_+ _n_ ; _ip++ ) XD(0);\ +} + +void bitxdec8( uint8_t *p, unsigned n, uint8_t start) { BITXDEC(uint8_t, p, n); } +void bitxdec16(uint16_t *p, unsigned n, uint16_t start) { BITXDEC(uint16_t, p, n); } +void bitxdec32(uint32_t *p, unsigned n, uint32_t start) { BITXDEC(uint32_t, p, n); } +void bitxdec64(uint64_t *p, unsigned n, uint64_t start) { BITXDEC(uint64_t, p, n); } + +//-------------- For : calc max. bits, min,max value ------------------------ +#define FM(i) mi = _ip[i] < mi?_ip[i]:mi; mx = _ip[i] > mx?_ip[i]:mx +#define BITFM(_t_, _in_,_n_) { _t_ *_ip; \ + for(_ip = _in_, mi = mx = *_ip; _ip != _in_+(_n_&~(4-1)); _ip += 4) { FM(0); FM(1); FM(2); FM(3); }\ + for(;_ip != _in_+_n_; _ip++) FM(0);\ +} + +uint8_t bitfm8( uint8_t *in, unsigned n, uint8_t *px, uint8_t *pmin) { uint8_t mi,mx; BITFM(uint8_t, in, n); *pmin = mi; if(px) *px = 0; return mx - mi; } +uint16_t bitfm16(uint16_t *in, unsigned n, uint16_t *px, uint16_t *pmin) { uint16_t mi,mx; BITFM(uint16_t, in, n); *pmin = mi; if(px) *px = 0; return mx - mi; } +uint32_t bitfm32(uint32_t *in, unsigned n, uint32_t *px, uint32_t *pmin) { uint32_t mi,mx; BITFM(uint32_t, in, n); *pmin = mi; if(px) *px = 0; return mx - mi; } +uint64_t bitfm64(uint64_t *in, unsigned n, uint64_t *px, uint64_t *pmin) { uint64_t mi,mx; BITFM(uint64_t, in, n); *pmin = mi; if(px) *px = 0; return mx - mi; } + +//----------- Lossy floating point conversion: pad the trailing mantissa bits with zero bits according to the relative error e (ex. 0.00001) ---------- + + #ifdef USE_FLOAT16 +// https://clang.llvm.org/docs/LanguageExtensions.html#half-precision-floating-point +#define ctof16(_cp_) (*(_Float16 *)(_cp_)) + +static inline _Float16 _fppad16(_Float16 d, float e, int lg2e) { + uint16_t u, du = ctou16(&d); + int b = (du>>10 & 0x1f)-15; // mantissa=10 bits, exponent=5bits, bias=15 + if ((b = 12 - b - lg2e) <= 0) return d; + b = (b > 10) ? 10 : b; + do { u = du & (~((1u<<(--b))-1)); } while (fabs((ctof16(&u) - d)/d) > e); + return ctof16(&u); +} + +void fppad16(_Float16 *in, size_t n, _Float16 *out, float e) { int lg2e = -log(e)/log(2.0); _Float16 *ip; for (ip = in; ip < in+n; ip++,out++) *out = _fppad16(*ip, e, lg2e); } + #endif + +//do u = du & (~((1u<<(--b))-1)); while(fabsf((ctof32(&u) - d)/d) > e); +#define OP(t,s) sign = du & ((t)1<<(s-1)); du &= ~((t)1<<(s-1)); d = TEMPLATE2(ctof,s)(&du);\ + do u = du & (~(((t)1<<(--b))-1)); while(d - TEMPLATE2(ctof,s)(&u) > e*d);\ + u |= sign;\ + return TEMPLATE2(ctof,s)(&u); + +static inline float _fppad32(float d, float e, int lg2e) { + uint32_t u, du = ctou32(&d), sign; + int b = (du>>23 & 0xff)-0x7e; + if((b = 25 - b - lg2e) <= 0) + return d; + b = b > 23?23:b; + sign = du & (1<<31); + du &= 0x7fffffffu; + d = ctof32(&du); + do u = du & (~((1u<<(--b))-1)); while(d - ctof32(&u) > e*d); + u |= sign; + return ctof32(&u); +} + +void fppad32(float *in, size_t n, float *out, float e) { int lg2e = -log(e)/log(2.0); float *ip; for(ip = in; ip < in+n; ip++,out++) *out = _fppad32(*ip, e, lg2e); } + +static inline double _fppad64(double d, double e, int lg2e) { if(isnan(d)) return d; + union r { uint64_t u; double d; } u,du; du.d = d; //if((du.u>>52)==0xfff) + uint64_t sign; + int b = (du.u>>52 & 0x7ff)-0x3fe; + if((b = 54 - b - lg2e) <= 0) + return d; + b = b > 52?52:b; + sign = du.u & (1ull<<63); du.u &= 0x7fffffffffffffffull; + int _b = b; + for(;;) { if((_b -= 8) <= 0) break; u.u = du.u & (~((1ull<<_b)-1)); if(d - u.d <= e*d) break; b = _b; } + do u.u = du.u & (~((1ull<<(--b))-1)); while(d - u.d > e*d); + u.u |= sign; + return ctof64(&u); +} + +void fppad64(double *in, size_t n, double *out, double e) { int lg2e = -log(e)/log(2.0); double *ip; for(ip = in; ip < in+n; ip++,out++) *out = _fppad64(*ip, e, lg2e); } + diff --git a/src/ext/for/bitutil.h b/src/ext/for/bitutil.h new file mode 100644 index 00000000000..7428060bbfb --- /dev/null +++ b/src/ext/for/bitutil.h @@ -0,0 +1,547 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression: max.bits, delta, zigzag, xor" + +#ifdef BITUTIL_IN + #ifdef __AVX2__ +#include + #elif defined(__AVX__) +#include + #elif defined(__SSE4_1__) +#include + #elif defined(__SSSE3__) + #ifdef __powerpc64__ +#define __SSE__ 1 +#define __SSE2__ 1 +#define __SSE3__ 1 +#define NO_WARN_X86_INTRINSICS 1 + #endif +#include + #elif defined(__SSE2__) +#include + #elif defined(__ARM_NEON) +#include + #endif + #if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" + #else +#include + #endif +#include "sse_neon.h" + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif +//------------------------ zigzag encoding ------------------------------------------------------------- +static inline unsigned char zigzagenc8( signed char x) { return x << 1 ^ x >> 7; } +static inline char zigzagdec8( unsigned char x) { return x >> 1 ^ -(x & 1); } + +static inline unsigned short zigzagenc16(short x) { return x << 1 ^ x >> 15; } +static inline short zigzagdec16(unsigned short x) { return x >> 1 ^ -(x & 1); } + +static inline unsigned zigzagenc32(int x) { return x << 1 ^ x >> 31; } +static inline int zigzagdec32(unsigned x) { return x >> 1 ^ -(x & 1); } + +static inline uint64_t zigzagenc64(int64_t x) { return x << 1 ^ x >> 63; } +static inline int64_t zigzagdec64(uint64_t x) { return x >> 1 ^ -(x & 1); } + + #if defined(__SSE2__) || defined(__ARM_NEON) +static ALWAYS_INLINE __m128i mm_zzage_epi16(__m128i v) { return _mm_xor_si128( mm_slli_epi16(v,1), mm_srai_epi16(v,15)); } +static ALWAYS_INLINE __m128i mm_zzage_epi32(__m128i v) { return _mm_xor_si128( mm_slli_epi32(v,1), mm_srai_epi32(v,31)); } +//static ALWAYS_INLINE __m128i mm_zzage_epi64(__m128i v) { return _mm_xor_si128( mm_slli_epi64(v,1), _mm_srai_epi64(v,63)); } + +static ALWAYS_INLINE __m128i mm_zzagd_epi16(__m128i v) { return _mm_xor_si128( mm_srli_epi16(v,1), mm_srai_epi16( mm_slli_epi16(v,15),15) ); } +static ALWAYS_INLINE __m128i mm_zzagd_epi32(__m128i v) { return _mm_xor_si128( mm_srli_epi32(v,1), mm_srai_epi32( mm_slli_epi32(v,31),31) ); } +//static ALWAYS_INLINE __m128i mm_zzagd_epi64(__m128i v) { return _mm_xor_si128(mm_srli_epi64(v,1), _mm_srai_epi64( m_slli_epi64(v,63),63) ); } + + #endif + #ifdef __AVX2__ +static ALWAYS_INLINE __m256i mm256_zzage_epi32(__m256i v) { return _mm256_xor_si256(_mm256_slli_epi32(v,1), _mm256_srai_epi32(v,31)); } +static ALWAYS_INLINE __m256i mm256_zzagd_epi32(__m256i v) { return _mm256_xor_si256(_mm256_srli_epi32(v,1), _mm256_srai_epi32(_mm256_slli_epi32(v,31),31) ); } + #endif + +//-------------- AVX2 delta + prefix sum (scan) / xor encode/decode --------------------------------------------------------------------------------------- + #ifdef __AVX2__ +static ALWAYS_INLINE __m256i mm256_delta_epi32(__m256i v, __m256i sv) { return _mm256_sub_epi32(v, _mm256_alignr_epi8(v, _mm256_permute2f128_si256(sv, v, _MM_SHUFFLE(0, 2, 0, 1)), 12)); } +static ALWAYS_INLINE __m256i mm256_delta_epi64(__m256i v, __m256i sv) { return _mm256_sub_epi64(v, _mm256_alignr_epi8(v, _mm256_permute2f128_si256(sv, v, _MM_SHUFFLE(0, 2, 0, 1)), 8)); } +static ALWAYS_INLINE __m256i mm256_xore_epi32( __m256i v, __m256i sv) { return _mm256_xor_si256(v, _mm256_alignr_epi8(v, _mm256_permute2f128_si256(sv, v, _MM_SHUFFLE(0, 2, 0, 1)), 12)); } +static ALWAYS_INLINE __m256i mm256_xore_epi64( __m256i v, __m256i sv) { return _mm256_xor_si256(v, _mm256_alignr_epi8(v, _mm256_permute2f128_si256(sv, v, _MM_SHUFFLE(0, 2, 0, 1)), 8)); } + +static ALWAYS_INLINE __m256i mm256_scan_epi32(__m256i v, __m256i sv) { + v = _mm256_add_epi32(v, _mm256_slli_si256(v, 4)); + v = _mm256_add_epi32(v, _mm256_slli_si256(v, 8)); + return _mm256_add_epi32( _mm256_permute2x128_si256( _mm256_shuffle_epi32(sv,_MM_SHUFFLE(3, 3, 3, 3)), sv, 0x11), + _mm256_add_epi32(v, _mm256_permute2x128_si256(_mm256_setzero_si256(),_mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 3, 3)), 0x20))); +} +static ALWAYS_INLINE __m256i mm256_xord_epi32(__m256i v, __m256i sv) { + v = _mm256_xor_si256(v, _mm256_slli_si256(v, 4)); + v = _mm256_xor_si256(v, _mm256_slli_si256(v, 8)); + return _mm256_xor_si256( _mm256_permute2x128_si256( _mm256_shuffle_epi32(sv,_MM_SHUFFLE(3, 3, 3, 3)), sv, 0x11), + _mm256_xor_si256(v, _mm256_permute2x128_si256(_mm256_setzero_si256(),_mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 3, 3)), 0x20))); +} + +static ALWAYS_INLINE __m256i mm256_scan_epi64(__m256i v, __m256i sv) { + v = _mm256_add_epi64(v, _mm256_alignr_epi8(v, _mm256_permute2x128_si256(v, v, _MM_SHUFFLE(0, 0, 2, 0)), 8)); + return _mm256_add_epi64(_mm256_permute4x64_epi64(sv, _MM_SHUFFLE(3, 3, 3, 3)), _mm256_add_epi64(_mm256_permute2x128_si256(v, v, _MM_SHUFFLE(0, 0, 2, 0)), v) ); +} +static ALWAYS_INLINE __m256i mm256_xord_epi64(__m256i v, __m256i sv) { + v = _mm256_xor_si256(v, _mm256_alignr_epi8(v, _mm256_permute2x128_si256(v, v, _MM_SHUFFLE(0, 0, 2, 0)), 8)); + return _mm256_xor_si256(_mm256_permute4x64_epi64(sv, _MM_SHUFFLE(3, 3, 3, 3)), _mm256_xor_si256(_mm256_permute2x128_si256(v, v, _MM_SHUFFLE(0, 0, 2, 0)), v) ); +} + +static ALWAYS_INLINE __m256i mm256_scani_epi32(__m256i v, __m256i sv, __m256i vi) { return _mm256_add_epi32(mm256_scan_epi32(v, sv), vi); } + #endif + + #if defined(__SSSE3__) || defined(__ARM_NEON) +static ALWAYS_INLINE __m128i mm_delta_epi16(__m128i v, __m128i sv) { return _mm_sub_epi16(v, _mm_alignr_epi8(v, sv, 14)); } +static ALWAYS_INLINE __m128i mm_delta_epi32(__m128i v, __m128i sv) { return _mm_sub_epi32(v, _mm_alignr_epi8(v, sv, 12)); } +static ALWAYS_INLINE __m128i mm_xore_epi16( __m128i v, __m128i sv) { return _mm_xor_si128(v, _mm_alignr_epi8(v, sv, 14)); } +static ALWAYS_INLINE __m128i mm_xore_epi32( __m128i v, __m128i sv) { return _mm_xor_si128(v, _mm_alignr_epi8(v, sv, 12)); } + +#define MM_HDEC_EPI32(_v_,_sv_,_hop_) { _v_ = _hop_(_v_, _mm_slli_si128(_v_, 4)); _v_ = _hop_(mm_shuffle_nnnn_epi32(_sv_, 3), _hop_(_mm_slli_si128(_v_, 8), _v_)); } +static ALWAYS_INLINE __m128i mm_scan_epi32(__m128i v, __m128i sv) { MM_HDEC_EPI32(v,sv,_mm_add_epi32); return v; } +static ALWAYS_INLINE __m128i mm_xord_epi32(__m128i v, __m128i sv) { MM_HDEC_EPI32(v,sv,_mm_xor_si128); return v; } + +#define MM_HDEC_EPI16(_v_,_sv_,_hop_) {\ + _v_ = _hop_( _v_, _mm_slli_si128(_v_, 2));\ + _v_ = _hop_( _v_, _mm_slli_si128(_v_, 4));\ + _v_ = _hop_(_hop_(_v_, _mm_slli_si128(_v_, 8)), _mm_shuffle_epi8(_sv_, _mm_set1_epi16(0x0f0e)));\ +} + +static ALWAYS_INLINE __m128i mm_scan_epi16(__m128i v, __m128i sv) { MM_HDEC_EPI16(v,sv,_mm_add_epi16); return v; } +static ALWAYS_INLINE __m128i mm_xord_epi16(__m128i v, __m128i sv) { MM_HDEC_EPI16(v,sv,_mm_xor_si128); return v; } +//-------- scan with vi delta > 0 ----------------------------- +static ALWAYS_INLINE __m128i mm_scani_epi16(__m128i v, __m128i sv, __m128i vi) { return _mm_add_epi16(mm_scan_epi16(v, sv), vi); } +static ALWAYS_INLINE __m128i mm_scani_epi32(__m128i v, __m128i sv, __m128i vi) { return _mm_add_epi32(mm_scan_epi32(v, sv), vi); } + + #elif defined(__SSE2__) +static ALWAYS_INLINE __m128i mm_delta_epi16(__m128i v, __m128i sv) { return _mm_sub_epi16(v, _mm_or_si128(_mm_srli_si128(sv, 14), _mm_slli_si128(v, 2))); } +static ALWAYS_INLINE __m128i mm_xore_epi16( __m128i v, __m128i sv) { return _mm_xor_si128(v, _mm_or_si128(_mm_srli_si128(sv, 14), _mm_slli_si128(v, 2))); } +static ALWAYS_INLINE __m128i mm_delta_epi32(__m128i v, __m128i sv) { return _mm_sub_epi32(v, _mm_or_si128(_mm_srli_si128(sv, 12), _mm_slli_si128(v, 4))); } +static ALWAYS_INLINE __m128i mm_xore_epi32( __m128i v, __m128i sv) { return _mm_xor_si128(v, _mm_or_si128(_mm_srli_si128(sv, 12), _mm_slli_si128(v, 4))); } + #endif + +#if !defined(_M_X64) && !defined(__x86_64__) && defined(__AVX__) +#define _mm256_extract_epi64(v, index) ((__int64)((uint64_t)(uint32_t)_mm256_extract_epi32((v), (index) * 2) | (((uint64_t)(uint32_t)_mm256_extract_epi32((v), (index) * 2 + 1)) << 32))) +#endif + +//------------------ Horizontal OR ----------------------------------------------- + #ifdef __AVX2__ +static ALWAYS_INLINE unsigned mm256_hor_epi32(__m256i v) { + v = _mm256_or_si256(v, _mm256_srli_si256(v, 8)); + v = _mm256_or_si256(v, _mm256_srli_si256(v, 4)); + return _mm256_extract_epi32(v,0) | _mm256_extract_epi32(v, 4); +} + +static ALWAYS_INLINE uint64_t mm256_hor_epi64(__m256i v) { + v = _mm256_or_si256(v, _mm256_permute2x128_si256(v, v, _MM_SHUFFLE(2, 0, 0, 1))); + return _mm256_extract_epi64(v, 1) | _mm256_extract_epi64(v,0); +} + #endif + + #if defined(__SSE2__) || defined(__ARM_NEON) +#define MM_HOZ_EPI16(v,_hop_) {\ + v = _hop_(v, _mm_srli_si128(v, 8));\ + v = _hop_(v, _mm_srli_si128(v, 6));\ + v = _hop_(v, _mm_srli_si128(v, 4));\ + v = _hop_(v, _mm_srli_si128(v, 2));\ +} + +#define MM_HOZ_EPI32(v,_hop_) {\ + v = _hop_(v, _mm_srli_si128(v, 8));\ + v = _hop_(v, _mm_srli_si128(v, 4));\ +} + +static ALWAYS_INLINE uint16_t mm_hor_epi16( __m128i v) { MM_HOZ_EPI16(v,_mm_or_si128); return (unsigned short)_mm_cvtsi128_si32(v); } +static ALWAYS_INLINE uint32_t mm_hor_epi32( __m128i v) { MM_HOZ_EPI32(v,_mm_or_si128); return (unsigned )_mm_cvtsi128_si32(v); } +static ALWAYS_INLINE uint64_t mm_hor_epi64( __m128i v) { v = _mm_or_si128( v, _mm_srli_si128(v, 8)); return (uint64_t )_mm_cvtsi128_si64(v); } + #endif + +//----------------- sub / add ---------------------------------------------------------- + #if defined(__SSE2__) || defined(__ARM_NEON) +#define SUBI16x8(_v_, _sv_) _mm_sub_epi16(_v_, _sv_) +#define SUBI32x4(_v_, _sv_) _mm_sub_epi32(_v_, _sv_) +#define ADDI16x8(_v_, _sv_, _vi_) _sv_ = _mm_add_epi16(_mm_add_epi16(_sv_, _vi_),_v_) +#define ADDI32x4(_v_, _sv_, _vi_) _sv_ = _mm_add_epi32(_mm_add_epi32(_sv_, _vi_),_v_) + +//---------------- Convert _mm_cvtsi128_siXX ------------------------------------------- +static ALWAYS_INLINE uint8_t _mm_cvtsi128_si8 (__m128i v) { return (uint8_t )_mm_cvtsi128_si32(v); } +static ALWAYS_INLINE uint16_t _mm_cvtsi128_si16(__m128i v) { return (uint16_t)_mm_cvtsi128_si32(v); } + #endif + +//--------- memset ----------------------------------------- +#define BITFORSET_(_out_, _n_, _start_, _mindelta_) do { unsigned _i;\ + for(_i = 0; _i != (_n_&~3); _i+=4) { \ + _out_[_i+0] = _start_+(_i )*_mindelta_; \ + _out_[_i+1] = _start_+(_i+1)*_mindelta_; \ + _out_[_i+2] = _start_+(_i+2)*_mindelta_; \ + _out_[_i+3] = _start_+(_i+3)*_mindelta_; \ + } \ + while(_i != _n_) \ + _out_[_i] = _start_+_i*_mindelta_, ++_i; \ +} while(0) + +//--------- SIMD zero ----------------------------------------- + #ifdef __AVX2__ +#define BITZERO32(_out_, _n_, _start_) do {\ + __m256i _sv_ = _mm256_set1_epi32(_start_), *_ov = (__m256i *)(_out_), *_ove = (__m256i *)(_out_ + _n_);\ + do _mm256_storeu_si256(_ov++, _sv_); while(_ov < _ove);\ +} while(0) + +#define BITFORZERO32(_out_, _n_, _start_, _mindelta_) do {\ + __m256i _sv = _mm256_set1_epi32(_start_), *_ov=(__m256i *)(_out_), *_ove = (__m256i *)(_out_ + _n_), _cv = _mm256_set_epi32(7+_mindelta_,6+_mindelta_,5+_mindelta_,4+_mindelta_,3*_mindelta_,2*_mindelta_,1*_mindelta_,0); \ + _sv = _mm256_add_epi32(_sv, _cv);\ + _cv = _mm256_set1_epi32(4);\ + do { _mm256_storeu_si256(_ov++, _sv); _sv = _mm256_add_epi32(_sv, _cv); } while(_ov < _ove);\ +} while(0) + +#define BITDIZERO32(_out_, _n_, _start_, _mindelta_) do { __m256i _sv = _mm256_set1_epi32(_start_), _cv = _mm256_set_epi32(7+_mindelta_,6+_mindelta_,5+_mindelta_,4+_mindelta_,3+_mindelta_,2+_mindelta_,1+_mindelta_,_mindelta_), *_ov=(__m256i *)(_out_), *_ove = (__m256i *)(_out_ + _n_);\ + _sv = _mm256_add_epi32(_sv, _cv); _cv = _mm256_set1_epi32(4*_mindelta_); do { _mm256_storeu_si256(_ov++, _sv), _sv = _mm256_add_epi32(_sv, _cv); } while(_ov < _ove);\ +} while(0) + + #elif defined(__SSE2__) || defined(__ARM_NEON) // ------------- +// SIMD set value (memset) +#define BITZERO32(_out_, _n_, _v_) do {\ + __m128i _sv_ = _mm_set1_epi32(_v_), *_ov = (__m128i *)(_out_), *_ove = (__m128i *)(_out_ + _n_);\ + do _mm_storeu_si128(_ov++, _sv_); while(_ov < _ove); \ +} while(0) + +#define BITFORZERO32(_out_, _n_, _start_, _mindelta_) do {\ + __m128i _sv = _mm_set1_epi32(_start_), *_ov=(__m128i *)(_out_), *_ove = (__m128i *)(_out_ + _n_), _cv = _mm_set_epi32(3*_mindelta_,2*_mindelta_,1*_mindelta_,0); \ + _sv = _mm_add_epi32(_sv, _cv);\ + _cv = _mm_set1_epi32(4);\ + do { _mm_storeu_si128(_ov++, _sv); _sv = _mm_add_epi32(_sv, _cv); } while(_ov < _ove);\ +} while(0) + +#define BITDIZERO32(_out_, _n_, _start_, _mindelta_) do { __m128i _sv = _mm_set1_epi32(_start_), _cv = _mm_set_epi32(3+_mindelta_,2+_mindelta_,1+_mindelta_,_mindelta_), *_ov=(__m128i *)(_out_), *_ove = (__m128i *)(_out_ + _n_);\ + _sv = _mm_add_epi32(_sv, _cv); _cv = _mm_set1_epi32(4*_mindelta_); do { _mm_storeu_si128(_ov++, _sv), _sv = _mm_add_epi32(_sv, _cv); } while(_ov < _ove);\ +} while(0) + #else +#define BITFORZERO32(_out_, _n_, _start_, _mindelta_) BITFORSET_(_out_, _n_, _start_, _mindelta_) +#define BITZERO32( _out_, _n_, _start_) BITFORSET_(_out_, _n_, _start_, 0) + #endif + +#define DELTR( _in_, _n_, _start_, _mindelta_, _out_) { unsigned _v; for( _v = 0; _v < _n_; _v++) _out_[_v] = _in_[_v] - (_start_) - _v*(_mindelta_) - (_mindelta_); } +#define DELTRB(_in_, _n_, _start_, _mindelta_, _b_, _out_) { unsigned _v; for(_b_=0,_v = 0; _v < _n_; _v++) _out_[_v] = _in_[_v] - (_start_) - _v*(_mindelta_) - (_mindelta_), _b_ |= _out_[_v]; _b_ = bsr32(_b_); } + +//----------------------------------------- bitreverse scalar + SIMD ------------------------------------------- + #if __clang__ && defined __has_builtin + #if __has_builtin(__builtin_bitreverse64) +#define BUILTIN_BITREVERSE + #else +#define BUILTIN_BITREVERSE + #endif + #endif + #ifdef BUILTIN_BITREVERSE +#define rbit8(x) __builtin_bitreverse8( x) +#define rbit16(x) __builtin_bitreverse16(x) +#define rbit32(x) __builtin_bitreverse32(x) +#define rbit64(x) __builtin_bitreverse64(x) + #else + + #if (__CORTEX_M >= 0x03u) || (__CORTEX_SC >= 300u) +static ALWAYS_INLINE uint32_t _rbit_(uint32_t x) { uint32_t rc; __asm volatile ("rbit %0, %1" : "=r" (rc) : "r" (x) ); } + #endif +static ALWAYS_INLINE uint8_t rbit8(uint8_t x) { + #if (__CORTEX_M >= 0x03u) || (__CORTEX_SC >= 300u) + return _rbit_(x) >> 24; + #elif 0 + x = (x & 0xaa) >> 1 | (x & 0x55) << 1; + x = (x & 0xcc) >> 2 | (x & 0x33) << 2; + return x << 4 | x >> 4; + #else + return (x * 0x0202020202ull & 0x010884422010ull) % 1023; + #endif +} + +static ALWAYS_INLINE uint16_t rbit16(uint16_t x) { + #if (__CORTEX_M >= 0x03u) || (__CORTEX_SC >= 300u) + return _rbit_(x) >> 16; + #else + x = (x & 0xaaaa) >> 1 | (x & 0x5555) << 1; + x = (x & 0xcccc) >> 2 | (x & 0x3333) << 2; + x = (x & 0xf0f0) >> 4 | (x & 0x0f0f) << 4; + return x << 8 | x >> 8; + #endif +} + +static ALWAYS_INLINE uint32_t rbit32(uint32_t x) { + #if (__CORTEX_M >= 0x03u) || (__CORTEX_SC >= 300u) + return _rbit_(x); + #else + x = ((x & 0xaaaaaaaa) >> 1 | (x & 0x55555555) << 1); + x = ((x & 0xcccccccc) >> 2 | (x & 0x33333333) << 2); + x = ((x & 0xf0f0f0f0) >> 4 | (x & 0x0f0f0f0f) << 4); + x = ((x & 0xff00ff00) >> 8 | (x & 0x00ff00ff) << 8); + return x << 16 | x >> 16; + #endif +} +static ALWAYS_INLINE uint64_t rbit64(uint64_t x) { + #if (__CORTEX_M >= 0x03u) || (__CORTEX_SC >= 300u) + return (uint64_t)_rbit_(x) << 32 | _rbit_(x >> 32); + #else + x = (x & 0xaaaaaaaaaaaaaaaa) >> 1 | (x & 0x5555555555555555) << 1; + x = (x & 0xcccccccccccccccc) >> 2 | (x & 0x3333333333333333) << 2; + x = (x & 0xf0f0f0f0f0f0f0f0) >> 4 | (x & 0x0f0f0f0f0f0f0f0f) << 4; + x = (x & 0xff00ff00ff00ff00) >> 8 | (x & 0x00ff00ff00ff00ff) << 8; + x = (x & 0xffff0000ffff0000) >> 16 | (x & 0x0000ffff0000ffff) << 16; + return x << 32 | x >> 32; + #endif +} + #endif + + #if defined(__SSSE3__) || defined(__ARM_NEON) +static ALWAYS_INLINE __m128i mm_rbit_epi16(__m128i v) { return mm_rbit_epi8(mm_rev_epi16(v)); } +static ALWAYS_INLINE __m128i mm_rbit_epi32(__m128i v) { return mm_rbit_epi8(mm_rev_epi32(v)); } +static ALWAYS_INLINE __m128i mm_rbit_epi64(__m128i v) { return mm_rbit_epi8(mm_rev_epi64(v)); } +//static ALWAYS_INLINE __m128i mm_rbit_si128(__m128i v) { return mm_rbit_epi8(mm_rev_si128(v)); } + #endif + + #ifdef __AVX2__ +static ALWAYS_INLINE __m256i mm256_rbit_epi8(__m256i v) { + __m256i fv = _mm256_setr_epi8(0, 8, 4,12, 2,10, 6,14, 1, 9, 5,13, 3,11, 7,15, 0, 8, 4,12, 2,10, 6,14, 1, 9, 5,13, 3,11, 7,15), cv0f_8 = _mm256_set1_epi8(0xf); + __m256i lv = _mm256_shuffle_epi8(fv,_mm256_and_si256( v, cv0f_8)); + __m256i hv = _mm256_shuffle_epi8(fv,_mm256_and_si256(_mm256_srli_epi64(v, 4), cv0f_8)); + return _mm256_or_si256(_mm256_slli_epi64(lv,4), hv); +} + +static ALWAYS_INLINE __m256i mm256_rev_epi16(__m256i v) { return _mm256_shuffle_epi8(v, _mm256_setr_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8,11,10,13,12,15,14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8,11,10,13,12,15,14)); } +static ALWAYS_INLINE __m256i mm256_rev_epi32(__m256i v) { return _mm256_shuffle_epi8(v, _mm256_setr_epi8( 3, 2, 1, 0, 7, 6, 5, 4, 11,10, 9, 8,15,14,13,12, 3, 2, 1, 0, 7, 6, 5, 4, 11,10, 9, 8,15,14,13,12)); } +static ALWAYS_INLINE __m256i mm256_rev_epi64(__m256i v) { return _mm256_shuffle_epi8(v, _mm256_setr_epi8( 7, 6, 5, 4, 3, 2, 1, 0, 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15,14,13,12,11,10, 9, 8)); } +static ALWAYS_INLINE __m256i mm256_rev_si128(__m256i v) { return _mm256_shuffle_epi8(v, _mm256_setr_epi8(15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)); } + +static ALWAYS_INLINE __m256i mm256_rbit_epi16(__m256i v) { return mm256_rbit_epi8(mm256_rev_epi16(v)); } +static ALWAYS_INLINE __m256i mm256_rbit_epi32(__m256i v) { return mm256_rbit_epi8(mm256_rev_epi32(v)); } +static ALWAYS_INLINE __m256i mm256_rbit_epi64(__m256i v) { return mm256_rbit_epi8(mm256_rev_epi64(v)); } +static ALWAYS_INLINE __m256i mm256_rbit_si128(__m256i v) { return mm256_rbit_epi8(mm256_rev_si128(v)); } + #endif + +// ------------------ bitio genaral macros --------------------------- + #ifdef __AVX2__ + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#include + #else +#include + #endif +#define bzhi_u32(_u_, _b_) _bzhi_u32(_u_, _b_) + + #if !(defined(_M_X64) || defined(__amd64__)) && (defined(__i386__) || defined(_M_IX86)) +#define bzhi_u64(_u_, _b_) ((_u_) & ((1ull<<(_b_))-1)) + #else +#define bzhi_u64(_u_, _b_) _bzhi_u64(_u_, _b_) + #endif + #else +#define bzhi_u64(_u_, _b_) ((_u_) & ((1ull<<(_b_))-1)) +#define bzhi_u32(_u_, _b_) ((_u_) & ((1u <<(_b_))-1)) + #endif + +#define BZHI64(_u_, _b_) (_b_ == 64?0xffffffffffffffffull:((_u_) & ((1ull<<(_b_))-1))) +#define BZHI32(_u_, _b_) (_b_ == 32? 0xffffffffu :((_u_) & ((1u <<(_b_))-1))) + +#define bitdef( _bw_,_br_) uint64_t _bw_=0; unsigned _br_=0 +#define bitini( _bw_,_br_) _bw_=_br_=0 +//-- bitput --------- +#define bitput( _bw_,_br_,_nb_,_x_) (_bw_) += (uint64_t)(_x_) << (_br_), (_br_) += (_nb_) +#define bitenorm( _bw_,_br_,_op_) ctou64(_op_) = _bw_; _op_ += ((_br_)>>3), (_bw_) >>=((_br_)&~7), (_br_) &= 7 +#define bitflush( _bw_,_br_,_op_) ctou64(_op_) = _bw_, _op_ += ((_br_)+7)>>3, _bw_=_br_=0 +//-- bitget --------- +#define bitbw( _bw_,_br_) ((_bw_)>>(_br_)) +#define bitrmv( _bw_,_br_,_nb_) (_br_) += _nb_ + +#define bitdnorm( _bw_,_br_,_ip_) _bw_ = ctou64((_ip_) += ((_br_)>>3)), (_br_) &= 7 +#define bitalign( _bw_,_br_,_ip_) ((_ip_) += ((_br_)+7)>>3) + +#define BITPEEK32( _bw_,_br_,_nb_) BZHI32(bitbw(_bw_,_br_), _nb_) +#define BITGET32( _bw_,_br_,_nb_,_x_) _x_ = BITPEEK32(_bw_, _br_, _nb_), bitrmv(_bw_, _br_, _nb_) +#define BITPEEK64( _bw_,_br_,_nb_) BZHI64(bitbw(_bw_,_br_), _nb_) +#define BITGET64( _bw_,_br_,_nb_,_x_) _x_ = BITPEEK64(_bw_, _br_, _nb_), bitrmv(_bw_, _br_, _nb_) + +#define bitpeek57( _bw_,_br_,_nb_) bzhi_u64(bitbw(_bw_,_br_), _nb_) +#define bitget57( _bw_,_br_,_nb_,_x_) _x_ = bitpeek57(_bw_, _br_, _nb_), bitrmv(_bw_, _br_, _nb_) +#define bitpeek31( _bw_,_br_,_nb_) bzhi_u32(bitbw(_bw_,_br_), _nb_) +#define bitget31( _bw_,_br_,_nb_,_x_) _x_ = bitpeek31(_bw_, _br_, _nb_), bitrmv(_bw_, _br_, _nb_) +//------------------ templates ----------------------------------- +#define bitput8( _bw_,_br_,_b_,_x_,_op_) bitput(_bw_,_br_,_b_,_x_) +#define bitput16(_bw_,_br_,_b_,_x_,_op_) bitput(_bw_,_br_,_b_,_x_) +#define bitput32(_bw_,_br_,_b_,_x_,_op_) bitput(_bw_,_br_,_b_,_x_) +#define bitput64(_bw_,_br_,_b_,_x_,_op_) if((_b_)>45) { bitput(_bw_,_br_,(_b_)-32, (_x_)>>32); bitenorm(_bw_,_br_,_op_); bitput(_bw_,_br_,32,(unsigned)(_x_)); } else bitput(_bw_,_br_,_b_,_x_) + +#define bitget8( _bw_,_br_,_b_,_x_,_ip_) bitget31(_bw_,_br_,_b_,_x_) +#define bitget16(_bw_,_br_,_b_,_x_,_ip_) bitget31(_bw_,_br_,_b_,_x_) +#define bitget32(_bw_,_br_,_b_,_x_,_ip_) bitget57(_bw_,_br_,_b_,_x_) +#define bitget64(_bw_,_br_,_b_,_x_,_ip_) if((_b_)>45) { unsigned _v; bitget57(_bw_,_br_,(_b_)-32,_x_); bitdnorm(_bw_,_br_,_ip_); BITGET64(_bw_,_br_,32,_v); _x_ = _x_<<32|_v; } else bitget57(_bw_,_br_,_b_,_x_) +#endif + +//---------- max. bit length + transform for sorted/unsorted arrays, delta,delta 1, delta > 1, zigzag, zigzag of delta, xor, FOR,---------------- +#ifdef __cplusplus +extern "C" { +#endif +//------ ORed array, used to determine the maximum bit length of the elements in an unsorted integer array --------------------- +uint8_t bit8( uint8_t *in, unsigned n, uint8_t *px); +uint16_t bit16(uint16_t *in, unsigned n, uint16_t *px); +uint32_t bit32(uint32_t *in, unsigned n, uint32_t *px); +uint64_t bit64(uint64_t *in, unsigned n, uint64_t *px); + +//-------------- delta = 0: Sorted integer array w/ mindelta = 0 ---------------------------------------------- +//-- ORed array, maximum bit length of the non decreasing integer array. out[i] = in[i] - in[i-1] +uint8_t bitd8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitd16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitd32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitd64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +//-- in-place reverse delta 0 +void bitddec8( uint8_t *p, unsigned n, uint8_t start); // non decreasing (out[i] = in[i] - in[i-1]) +void bitddec16( uint16_t *p, unsigned n, uint16_t start); +void bitddec32( uint32_t *p, unsigned n, uint32_t start); +void bitddec64( uint64_t *p, unsigned n, uint64_t start); + +//-- vectorized fast delta4 one: out[0] = in[4]-in[0], out[1]=in[5]-in[1], out[2]=in[6]-in[2], out[3]=in[7]-in[3],... +uint16_t bits128v16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bits128v32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start); + +//------------- delta = 1: Sorted integer array w/ mindelta = 1 --------------------------------------------- +//-- get delta maximum bit length of the non strictly decreasing integer array. out[i] = in[i] - in[i-1] - 1 +uint8_t bitd18( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitd116(uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitd132(uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitd164(uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +//-- in-place reverse delta one +void bitd1dec8( uint8_t *p, unsigned n, uint8_t start); // non strictly decreasing (out[i] = in[i] - in[i-1] - 1) +void bitd1dec16( uint16_t *p, unsigned n, uint16_t start); +void bitd1dec32( uint32_t *p, unsigned n, uint32_t start); +void bitd1dec64( uint64_t *p, unsigned n, uint64_t start); + +//------------- delta > 1: Sorted integer array w/ mindelta > 1 --------------------------------------------- +//-- ORed array, for max. bit length get min. delta () +uint8_t bitdi8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitdi16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitdi32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitdi64( uint64_t *in, unsigned n, uint64_t *px, uint64_t start); +//-- transform sorted integer array to delta array: out[i] = in[i] - in[i-1] - mindelta +uint8_t bitdienc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta); +uint16_t bitdienc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta); +uint32_t bitdienc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta); +uint64_t bitdienc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta); +//-- in-place reverse delta +void bitdidec8( uint8_t *in, unsigned n, uint8_t start, uint8_t mindelta); +void bitdidec16(uint16_t *in, unsigned n, uint16_t start, uint16_t mindelta); +void bitdidec32(uint32_t *in, unsigned n, uint32_t start, uint32_t mindelta); +void bitdidec64(uint64_t *in, unsigned n, uint64_t start, uint64_t mindelta); + +//------------- FOR : array bit length: --------------------------------------------------------------------- +//------ ORed array, for max. bit length of the non decreasing integer array. out[i] = in[i] - start +uint8_t bitf8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitf16(uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitf32(uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitf64(uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +//------ ORed array, for max. bit length of the non strictly decreasing integer array out[i] = in[i] - 1 - start +uint8_t bitf18( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitf116(uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitf132(uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitf164(uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +//------ ORed array, for max. bit length for usorted array +uint8_t bitfm8( uint8_t *in, unsigned n, uint8_t *px, uint8_t *pmin); // unsorted +uint16_t bitfm16(uint16_t *in, unsigned n, uint16_t *px, uint16_t *pmin); +uint32_t bitfm32(uint32_t *in, unsigned n, uint32_t *px, uint32_t *pmin); +uint64_t bitfm64(uint64_t *in, unsigned n, uint64_t *px, uint64_t *pmin); + +//------------- Zigzag encoding for unsorted integer lists: out[i] = in[i] - in[i-1] ------------------------ +//-- ORed array, to get maximum zigzag bit length integer array +uint8_t bitz8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitz16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitz32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitz64( uint64_t *in, unsigned n, uint64_t *px, uint64_t start); +//-- Zigzag transform +uint8_t bitzenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta); +uint16_t bitzenc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta); +uint32_t bitzenc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta); +uint64_t bitzenc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta); +//-- in-place zigzag reverse transform +void bitzdec8( uint8_t *in, unsigned n, uint8_t start); +void bitzdec16( uint16_t *in, unsigned n, uint16_t start); +void bitzdec32( uint32_t *in, unsigned n, uint32_t start); +void bitzdec64( uint64_t *in, unsigned n, uint64_t start); + +//------------- Zigzag of zigzag/delta : unsorted/sorted integer array ---------------------------------------------------- +//-- get delta maximum bit length of the non strictly decreasing integer array. out[i] = in[i] - in[i-1] - 1 +uint8_t bitzz8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitzz16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitzz32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitzz64( uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +uint8_t bitzzenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start, uint8_t mindelta); +uint16_t bitzzenc16(uint16_t *in, unsigned n, uint16_t *out, uint16_t start, uint16_t mindelta); +uint32_t bitzzenc32(uint32_t *in, unsigned n, uint32_t *out, uint32_t start, uint32_t mindelta); +uint64_t bitzzenc64(uint64_t *in, unsigned n, uint64_t *out, uint64_t start, uint64_t mindelta); + +//-- in-place reverse zigzag of delta (encoded w/ bitdiencNN and parameter mindelta = 1) +void bitzzdec8( uint8_t *in, unsigned n, uint8_t start); // non strictly decreasing (out[i] = in[i] - in[i-1] - 1) +void bitzzdec16( uint16_t *in, unsigned n, uint16_t start); +void bitzzdec32( uint32_t *in, unsigned n, uint32_t start); +void bitzzdec64( uint64_t *in, unsigned n, uint64_t start); + +//------------- XOR encoding for unsorted integer lists: out[i] = in[i] - in[i-1] ------------- +//-- ORed array, to get maximum zigzag bit length integer array +uint8_t bitx8( uint8_t *in, unsigned n, uint8_t *px, uint8_t start); +uint16_t bitx16( uint16_t *in, unsigned n, uint16_t *px, uint16_t start); +uint32_t bitx32( uint32_t *in, unsigned n, uint32_t *px, uint32_t start); +uint64_t bitx64( uint64_t *in, unsigned n, uint64_t *px, uint64_t start); + +//-- XOR transform +uint8_t bitxenc8( uint8_t *in, unsigned n, uint8_t *out, uint8_t start); +uint16_t bitxenc16( uint16_t *in, unsigned n, uint16_t *out, uint16_t start); +uint32_t bitxenc32( uint32_t *in, unsigned n, uint32_t *out, uint32_t start); +uint64_t bitxenc64( uint64_t *in, unsigned n, uint64_t *out, uint64_t start); + +//-- XOR in-place reverse transform +void bitxdec8( uint8_t *p, unsigned n, uint8_t start); +void bitxdec16( uint16_t *p, unsigned n, uint16_t start); +void bitxdec32( uint32_t *p, unsigned n, uint32_t start); +void bitxdec64( uint64_t *p, unsigned n, uint64_t start); + +//------- Lossy floating point transform: pad the trailing mantissa bits with zeros according to the error e (ex. e=0.00001) + #ifdef USE_FLOAT16 +void fppad16(_Float16 *in, size_t n, _Float16 *out, float e); + #endif +void fppad32(float *in, size_t n, float *out, float e); +void fppad64(double *in, size_t n, double *out, double e); + +#ifdef __cplusplus +} +#endif + +//---- Floating point to Integer decomposition --------------------------------- +// seeeeeeee21098765432109876543210 (s:sign, e:exponent, 0-9:mantissa) + #ifdef BITUTIL_IN +#define MANTF32 23 +#define MANTF64 52 + +#define BITFENC(_u_, _sgn_, _expo_, _mant_, _mantbits_, _one_) _sgn_ = _u_ >> (sizeof(_u_)*8-1); _expo_ = ((_u_ >> (_mantbits_)) & ( (_one_<<(sizeof(_u_)*8 - 1 - _mantbits_)) -1)); _mant_ = _u_ & ((_one_<<_mantbits_)-1); +#define BITFDEC( _sgn_, _expo_, _mant_, _u_, _mantbits_) _u_ = (_sgn_) << (sizeof(_u_)*8-1) | (_expo_) << _mantbits_ | (_mant_) + #endif diff --git a/src/ext/for/conf.h b/src/ext/for/conf.h new file mode 100644 index 00000000000..be6face433d --- /dev/null +++ b/src/ext/for/conf.h @@ -0,0 +1,282 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ + +// conf.h - config & common +#ifndef CONF_H +#define CONF_H +//------------------------- Compiler ------------------------------------------ + #if defined(__GNUC__) +#include +#define ALIGNED(t,v,n) t v __attribute__ ((aligned (n))) +#define ALWAYS_INLINE inline __attribute__((always_inline)) +#define NOINLINE __attribute__((noinline)) +#define _PACKED __attribute__ ((packed)) +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + +#define popcnt32(_x_) __builtin_popcount(_x_) +#define popcnt64(_x_) __builtin_popcountll(_x_) + + #if defined(__i386__) || defined(__x86_64__) +//x,__bsr32: 1:0,2:1,3:1,4:2,5:2,6:2,7:2,8:3,9:3,10:3,11:3,12:3,13:3,14:3,15:3,16:4,17:4,18:4,19:4,20:4,21:4,22:4,23:4,24:4,25:4,26:4,27:4,28:4,29:4,30:4,31:4,32:5 +// x,bsr32: 0:0,1:1,2:2,3:2,4:3,5:3,6:3,7:3,8:4,9:4,10:4,11:4,12:4,13:4,14:4,15:4,16:5,17:5,18:5,19:5,20:5,21:5,22:5,23:5,24:5,25:5,26:5,27:5,28:5,29:5,30:5,31:5,32:6, +static inline int __bsr32( int x) { asm("bsr %1,%0" : "=r" (x) : "rm" (x) ); return x; } +static inline int bsr32( int x) { int b = -1; asm("bsrl %1,%0" : "+r" (b) : "rm" (x) ); return b + 1; } +static inline int bsr64(uint64_t x ) { return x?64 - __builtin_clzll(x):0; } +static inline int __bsr64(uint64_t x ) { return 63 - __builtin_clzll(x); } + +static inline unsigned rol32(unsigned x, int s) { asm ("roll %%cl,%0" :"=r" (x) :"0" (x),"c" (s)); return x; } +static inline unsigned ror32(unsigned x, int s) { asm ("rorl %%cl,%0" :"=r" (x) :"0" (x),"c" (s)); return x; } +static inline uint64_t rol64(uint64_t x, int s) { asm ("rolq %%cl,%0" :"=r" (x) :"0" (x),"c" (s)); return x; } +static inline uint64_t ror64(uint64_t x, int s) { asm ("rorq %%cl,%0" :"=r" (x) :"0" (x),"c" (s)); return x; } + #else +static inline int __bsr32(unsigned x ) { return 31 - __builtin_clz( x); } +static inline int bsr32(int x ) { return x?32 - __builtin_clz( x):0; } +static inline int bsr64(uint64_t x) { return x?64 - __builtin_clzll(x):0; } + +static inline unsigned rol32(unsigned x, int s) { return x << s | x >> (32 - s); } +static inline unsigned ror32(unsigned x, int s) { return x >> s | x << (32 - s); } +static inline unsigned rol64(unsigned x, int s) { return x << s | x >> (64 - s); } +static inline unsigned ror64(unsigned x, int s) { return x >> s | x << (64 - s); } + #endif + +#define ctz64(_x_) __builtin_ctzll(_x_) +#define ctz32(_x_) __builtin_ctz(_x_) // 0:32 ctz32(1< 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +#define bswap16(x) __builtin_bswap16(x) + #else +static inline unsigned short bswap16(unsigned short x) { return __builtin_bswap32(x << 16); } + #endif +#define bswap32(x) __builtin_bswap32(x) +#define bswap64(x) __builtin_bswap64(x) + + #elif _MSC_VER //---------------------------------------------------- +#include +#include + #if _MSC_VER < 1600 +#include "vs/stdint.h" +#define __builtin_prefetch(x,a) +#define inline __inline + #else +#include +#define __builtin_prefetch(x,a) _mm_prefetch(x, _MM_HINT_NTA) + #endif + +#define ALIGNED(t,v,n) __declspec(align(n)) t v +#define ALWAYS_INLINE __forceinline +#define NOINLINE __declspec(noinline) +#define THREADLOCAL __declspec(thread) +#define likely(x) (x) +#define unlikely(x) (x) + +static inline int __bsr32(unsigned x) { unsigned long z=0; _BitScanReverse(&z, x); return z; } +static inline int bsr32( unsigned x) { unsigned long z; _BitScanReverse(&z, x); return x?z+1:0; } +static inline int ctz32( unsigned x) { unsigned long z; _BitScanForward(&z, x); return x?z:32; } +static inline int clz32( unsigned x) { unsigned long z; _BitScanReverse(&z, x); return x?31-z:32; } + #if !defined(_M_ARM64) && !defined(_M_X64) +static inline unsigned char _BitScanForward64(unsigned long* ret, uint64_t x) { + unsigned long x0 = (unsigned long)x, top, bottom; _BitScanForward(&top, (unsigned long)(x >> 32)); _BitScanForward(&bottom, x0); + *ret = x0 ? bottom : 32 + top; return x != 0; +} +static unsigned char _BitScanReverse64(unsigned long* ret, uint64_t x) { + unsigned long x1 = (unsigned long)(x >> 32), top, bottom; _BitScanReverse(&top, x1); _BitScanReverse(&bottom, (unsigned long)x); + *ret = x1 ? top + 32 : bottom; return x != 0; +} + #endif +static inline int bsr64(uint64_t x) { unsigned long z=0; _BitScanReverse64(&z, x); return x?z+1:0; } +static inline int ctz64(uint64_t x) { unsigned long z; _BitScanForward64(&z, x); return x?z:64; } +static inline int clz64(uint64_t x) { unsigned long z; _BitScanReverse64(&z, x); return x?63-z:64; } + +#define rol32(x,s) _lrotl(x, s) +#define ror32(x,s) _lrotr(x, s) + +#define bswap16(x) _byteswap_ushort(x) +#define bswap32(x) _byteswap_ulong(x) +#define bswap64(x) _byteswap_uint64(x) + +#define popcnt32(x) __popcnt(x) + #ifdef _WIN64 +#define popcnt64(x) __popcnt64(x) + #else +#define popcnt64(x) (popcnt32(x) + popcnt32(x>>32)) + #endif + +#define sleep(x) Sleep(x/1000) +#define fseeko _fseeki64 +#define ftello _ftelli64 +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#define strtoull _strtoui64 +static inline double round(double num) { return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5); } + #endif + +#define __bsr8(_x_) __bsr32(_x_) +#define __bsr16(_x_) __bsr32(_x_) +#define bsr8(_x_) bsr32(_x_) +#define bsr16(_x_) bsr32(_x_) +#define ctz8(_x_) ctz32(_x_) +#define ctz16(_x_) ctz32(_x_) +#define clz8(_x_) (clz32(_x_)-24) +#define clz16(_x_) (clz32(_x_)-16) + +#define popcnt8(x) popcnt32(x) +#define popcnt16(x) popcnt32(x) + +//--------------- Unaligned memory access ------------------------------------- + #ifdef UA_MEMCPY +#include +static inline unsigned short ctou16(const void *cp) { unsigned short x; memcpy(&x, cp, sizeof(x)); return x; } +static inline unsigned ctou32(const void *cp) { unsigned x; memcpy(&x, cp, sizeof(x)); return x; } +static inline unsigned long long ctou64(const void *cp) { unsigned long long x; memcpy(&x, cp, sizeof(x)); return x; } +static inline size_t ctousz(const void *cp) { size_t x; memcpy(&x, cp, sizeof(x)); return x; } +static inline float ctof32(const void *cp) { float x; memcpy(&x, cp, sizeof(x)); return x; } +static inline double ctof64(const void *cp) { double x; memcpy(&x, cp, sizeof(x)); return x; } + +static inline void stou16( void *cp, unsigned short x) { memcpy(cp, &x, sizeof(x)); } +static inline void stou32( void *cp, unsigned x) { memcpy(cp, &x, sizeof(x)); } +static inline void stou64( void *cp, unsigned long long x) { memcpy(cp, &x, sizeof(x)); } +static inline void stousz( void *cp, size_t x) { memcpy(cp, &x, sizeof(x)); } +static inline void stof32( void *cp, float x) { memcpy(cp, &x, sizeof(x)); } +static inline void stof64( void *cp, double x) { memcpy(cp, &x, sizeof(x)); } + #elif defined(__i386__) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || _MSC_VER ||\ + defined(__powerpc__) || defined(__s390__) ||\ + defined(__ARM_FEATURE_UNALIGNED) || defined(__aarch64__) || defined(__arm__) ||\ + defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \ + defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) || \ + defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) +#define ctou16(_cp_) (*(unsigned short *)(_cp_)) +#define ctou32(_cp_) (*(unsigned *)(_cp_)) +#define ctof32(_cp_) (*(float *)(_cp_)) + + #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__s390__) || defined(_MSC_VER) +#define ctou64(_cp_) (*(uint64_t *)(_cp_)) +#define ctof64(_cp_) (*(double *)(_cp_)) + #elif defined(__ARM_FEATURE_UNALIGNED) +struct _PACKED longu { uint64_t l; }; +struct _PACKED doubleu { double d; }; +#define ctou64(_cp_) ((struct longu *)(_cp_))->l +#define ctof64(_cp_) ((struct doubleu *)(_cp_))->d + #endif + + #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__) +struct _PACKED shortu { unsigned short s; }; +struct _PACKED unsignedu { unsigned u; }; +struct _PACKED longu { uint64_t l; }; +struct _PACKED floatu { float f; }; +struct _PACKED doubleu { double d; }; + +#define ctou16(_cp_) ((struct shortu *)(_cp_))->s +#define ctou32(_cp_) ((struct unsignedu *)(_cp_))->u +#define ctou64(_cp_) ((struct longu *)(_cp_))->l +#define ctof32(_cp_) ((struct floatu *)(_cp_))->f +#define ctof64(_cp_) ((struct doubleu *)(_cp_))->d + #else +#error "unknown cpu" + #endif + +#define ctou24(_cp_) (ctou32(_cp_) & 0xffffff) +#define ctou48(_cp_) (ctou64(_cp_) & 0xffffffffffffull) +#define ctou8(_cp_) (*(_cp_)) +//--------------------- wordsize ---------------------------------------------- + #if defined(__64BIT__) || defined(_LP64) || defined(__LP64__) || defined(_WIN64) ||\ + defined(__x86_64__) || defined(_M_X64) ||\ + defined(__ia64) || defined(_M_IA64) ||\ + defined(__aarch64__) ||\ + defined(__mips64) ||\ + defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) ||\ + defined(__s390x__) +#define __WORDSIZE 64 + #else +#define __WORDSIZE 32 + #endif +#endif + +//---------------------misc --------------------------------------------------- +#define BZHI64F(_u_, _b_) ((_u_) & ((1ull<<(_b_))-1)) // _b_ < 64 +#define BZHI32F(_u_, _b_) ((_u_) & ((1u <<(_b_))-1)) // _b_ < 32 +#define BZHI64( _u_, _b_) (_b_ == 64?0xffffffffffffffffull:((_u_) & ((1ull<<(_b_))-1))) // Constant +#define BZHI32( _u_, _b_) (_b_ == 32? 0xffffffffu :((_u_) & ((1u <<(_b_))-1))) +#define BZHI16( _u_, _b_) BZHI32(_u_, _b_) +#define BZHI8( _u_, _b_) BZHI32(_u_, _b_) + + #ifdef __AVX2__ + #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +#include + #else +#include + #endif +#define bzhi32(_u_, _b_) _bzhi_u32(_u_, _b_) + + #if !(defined(_M_X64) || defined(__amd64__)) && (defined(__i386__) || defined(_M_IX86)) +#define bzhi64(_u_, _b_) ((_u_) & ((1ull<<(_b_))-1)) + #else +#define bzhi64(_u_, _b_) _bzhi_u64(_u_, _b_) + #endif + #else +#define bzhi_u64(_u_, _b_) BZHI64(_u_, _b_) +#define bzhi_u32(_u_, _b_) BZHI32(_u_, _b_) + #endif + +#define SIZE_ROUNDUP(_n_, _a_) (((size_t)(_n_) + (size_t)((_a_) - 1)) & ~(size_t)((_a_) - 1)) +#define ALIGN_DOWN(__ptr, __a) ((void *)((uintptr_t)(__ptr) & ~(uintptr_t)((__a) - 1))) + +#define TEMPLATE2_(_x_, _y_) _x_##_y_ +#define TEMPLATE2(_x_, _y_) TEMPLATE2_(_x_,_y_) + +#define TEMPLATE3_(_x_,_y_,_z_) _x_##_y_##_z_ +#define TEMPLATE3(_x_,_y_,_z_) TEMPLATE3_(_x_, _y_, _z_) + +#define CACHE_LINE_SIZE 64 +#define PREFETCH_DISTANCE (CACHE_LINE_SIZE*4) + +#define CLAMP(_x_, _low_, _high_) (((_x_) > (_high_)) ? (_high_) : (((_x_) < (_low_)) ? (_low_) : (_x_))) + +//--- NDEBUG ------- +#include + #ifdef _MSC_VER + #ifdef NDEBUG +#define AS(expr, fmt, ...) +#define AC(expr, fmt, ...) do { if(!(expr)) { fprintf(stderr, fmt, ##__VA_ARGS__ ); fflush(stderr); abort(); } } while(0) +#define die(fmt, ...) do { fprintf(stderr, fmt, ##__VA_ARGS__ ); fflush(stderr); exit(-1); } while(0) + #else +#define AS(expr, fmt, ...) do { if(!(expr)) { fflush(stdout);fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ##__VA_ARGS__ ); fflush(stderr); abort(); } } while(0) +#define AC(expr, fmt, ...) do { if(!(expr)) { fflush(stdout);fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ##__VA_ARGS__ ); fflush(stderr); abort(); } } while(0) +#define die(fmt, ...) do { fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ##__VA_ARGS__ ); fflush(stderr); exit(-1); } while(0) + #endif + #else + #ifdef NDEBUG +#define AS(expr, fmt,args...) +#define AC(expr, fmt,args...) do { if(!(expr)) { fprintf(stderr, fmt, ## args ); fflush(stderr); abort(); } } while(0) +#define die(fmt,args...) do { fprintf(stderr, fmt, ## args ); fflush(stderr); exit(-1); } while(0) + #else +#define AS(expr, fmt,args...) do { if(!(expr)) { fflush(stdout);fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ## args ); fflush(stderr); abort(); } } while(0) +#define AC(expr, fmt,args...) do { if(!(expr)) { fflush(stdout);fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ## args ); fflush(stderr); abort(); } } while(0) +#define die(fmt,args...) do { fprintf(stderr, "%s:%s:%d:", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, fmt, ## args ); fflush(stderr); exit(-1); } while(0) + #endif + #endif diff --git a/src/ext/for/eliasfano.c b/src/ext/for/eliasfano.c new file mode 100644 index 00000000000..e47af1e7e6e --- /dev/null +++ b/src/ext/for/eliasfano.c @@ -0,0 +1,208 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ + +// eliasfano.c - "Integer Compression" Elias Fano +#ifndef USIZE +#include +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#include "conf.h" +#include "bitpack.h" +#define BITUTIL_IN +#include "bitutil.h" +#include "eliasfano.h" + +#define PAD8(__x) ( (((__x)+8-1)/8) ) + + #ifdef __SSE42__ +#include +#define bslr32(x) _blsr_u32(x) +#define bslr64(x) _blsr_u64(x) + #else +//static inline unsigned long long blsr(unsigned long long x) { return x & (x - 1); } +#define blsr32(_x_) ((_x_) & ((_x_) - 1)) +#define blsr64(_x_) ((_x_) & ((_x_) - 1)) + #endif +#define blsr8(_x_) blsr32(_x_) +#define blsr16(_x_) blsr32(_x_) + +#define EFE(__x,__i,__start) ((__x[__i] - __start)-(__i)*EF_INC) + +#define BITPACK bitpack +#define BITUNPACK bitunpack +#define EF_INC 1 +#define EFANOENC efano1enc +#define EFANODEC efano1dec + +#define USIZE 32 +#include "eliasfano.c" +#undef USIZE + +/*#define USIZE 16 +#include "eliasfano.c" +#undef USIZE*/ + +#undef EF_INC +#undef EFANOENC +#undef EFANODEC + +//---------- +#define EF_INC 0 +#define EFANOENC efanoenc +#define EFANODEC efanodec + +#define USIZE 32 +#include "eliasfano.c" +#undef USIZE + +#define USIZE 64 +#include "eliasfano.c" +#undef USIZE + +/*#define USIZE 16 +#include "eliasfano.c" +#undef USIZE*/ + +#undef BITPACK +#undef BITUNPACK + +#undef EF_INC +#undef EFANOENC +#undef EFANODEC + +//---------------------- + #if defined(__SSE2__) || defined(__ARM_NEON) +#define VSIZE 128 + +#define BITPACK bitpack128v +#define BITUNPACK bitunpack128v +#define EF_INC 1 +#define EFANOENC efano1enc128v +#define EFANODEC efano1dec128v + +#define USIZE 32 +#include "eliasfano.c" + +#define EF_INC 0 +#define EFANOENC efanoenc128v +#define EFANODEC efanodec128v + +#include "eliasfano.c" + #endif + + #ifdef __AVX2__ +#define VSIZE 256 +#define BITPACK bitpack256v +#define BITUNPACK bitunpack256v +#define EF_INC 1 +#define EFANOENC efano1enc256v +#define EFANODEC efano1dec256v +#include "eliasfano.c" + +#define EF_INC 0 +#define EFANOENC efanoenc256v +#define EFANODEC efanodec256v +#include "eliasfano.c" + #endif + +#else //--------------------------------------------- implementation --------------------------------------------------------------- +#define uint_t TEMPLATE3(uint, USIZE, _t) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wparentheses" + +unsigned char *TEMPLATE2(EFANOENC, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + uint_t *ip, e,x,hl,i; + unsigned char *op; + unsigned lb; + uint_t _pa[1024+64],*pa=_pa; + if(!n) return out; + if(n > 1024) pa = malloc(sizeof(pa[0])*(n+64)); if(!pa) die("efanoenc:malloc error size=%d ", n); + e = EFE(in,n-1,start); + if(!e) { out[0] = 0; if(pa != _pa) free(pa);return out+1; } + + lb = TEMPLATE2(bsr, USIZE)(e/n); + x = ((uint_t)1 << lb)-1; hl = PAD8((e>>lb)+n); + + for(i = 0; i != n&~3;) { + pa[i] = EFE(in,i,start) & x; ++i; + pa[i] = EFE(in,i,start) & x; ++i; + pa[i] = EFE(in,i,start) & x; ++i; + pa[i] = EFE(in,i,start) & x; ++i; + } + while(i < n) pa[i] = EFE(in,i,start) & x, ++i; + *out = lb+1; + op = TEMPLATE2(BITPACK,USIZE)(pa, n, out+1, lb); + + memset(op, 0, hl); + for(i = 0; i != n&~3; ) { + x = i + (EFE(in,i,start) >> lb), op[x >> 3] |= (uint_t)1 << (x & 7); ++i; + x = i + (EFE(in,i,start) >> lb), op[x >> 3] |= (uint_t)1 << (x & 7); ++i; + x = i + (EFE(in,i,start) >> lb), op[x >> 3] |= (uint_t)1 << (x & 7); ++i; + x = i + (EFE(in,i,start) >> lb), op[x >> 3] |= (uint_t)1 << (x & 7); ++i; + } + while(i < n) x = i + (EFE(in,i,start) >> lb), op[x >> 3] |= (uint_t)1 << (x & 7),++i; + if(pa != _pa) free(pa); + return op+hl; +} + +unsigned char *TEMPLATE2(EFANODEC, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out, uint_t start) { + unsigned char *ip = in; + uint_t i,j,lb = *ip++; + uint64_t b,x; + if(!n) + return in; + + if(!lb) { + #if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32 + #if EF_INC == 1 + BITFORZERO32(out, n, start, 1); + #else + BITZERO32( out, n, start); + #endif + #else + BITFORSET_(out, n, start, EF_INC); + #endif + return ip; + } + + ip = TEMPLATE2(BITUNPACK,USIZE)(ip, n, out, --lb); + #define EFD(i) if(!b) break; out[i] += ((uint_t)(j+ctz64(b)-i) << lb) + start+i*EF_INC; b = blsr64(b); ++i; + + for(i=j=0;; j += sizeof(uint64_t)*8) { //PREFETCH(ip+256,0); + for(b = ctou64(ip+(j>>3)); ; ) { + EFD(i); EFD(i); EFD(i); EFD(i); + if(!b) break; out[i] += ((uint_t)(j+ctz64(b)-i) << lb) + start+i*EF_INC; + if(unlikely(++i >= n)) + goto e; + b = blsr64(b); + } + } + e:return ip + PAD8((EFE(out,n-1,start)>>lb)+n); +} + +#pragma clang diagnostic pop +#endif diff --git a/src/ext/for/eliasfano.h b/src/ext/for/eliasfano.h new file mode 100644 index 00000000000..52584dcd142 --- /dev/null +++ b/src/ext/for/eliasfano.h @@ -0,0 +1,61 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// eliasfano.h - "Integer Compression" Elias Fano c/c++ header +#ifdef __cplusplus +extern "C" { +#endif +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif + +// compress/decompress integer array with n values to the buffer out. Return value = end of output/input buffer +unsigned char *efanoenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efanoenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *efanodec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *efanodec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +unsigned char *efano1enc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efano1enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *efano1dec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *efano1dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +unsigned char *efanoenc128v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efanodec128v32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +unsigned char *efano1enc128v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efano1dec128v32(unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +unsigned char *efanoenc256v32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efanodec256v32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +unsigned char *efano1enc256v32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *efano1dec256v32(unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +#ifdef __cplusplus +} +#endif diff --git a/src/ext/for/fp.c b/src/ext/for/fp.c new file mode 100644 index 00000000000..e181d58bcea --- /dev/null +++ b/src/ext/for/fp.c @@ -0,0 +1,684 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Floating Point + Integer Compression (All integer compression functions can be used for float/double and vice versa)" + #ifndef USIZE +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#define BITUTIL_IN +#include "conf.h" +#include "vp4.h" +#include "bitutil.h" +#include "fp.h" +//---------------------- template generation -------------------------------------------- +#define VSIZE 128 + +#define P4ENC p4enc +#define P4DEC p4dec +#define P4ENCV p4enc +#define P4DECV p4dec + +#define NL 18 +#define N4 17 // must be > 16 + +#define N_0 3 +#define N_1 4 + +#define N2 3 +#define N3 5 +#define USIZE 8 +#include "fp.c" + +#define P4ENCV p4enc128v +#define P4DECV p4dec128v + +#define N_0 3 +#define N_1 5 + +#define N2 6 +#define N3 12 +#define USIZE 16 +#include "fp.c" + +#define N_0 4 +#define N_1 6 + +#define N2 6 // for seconds time series +#define N3 10 +#define USIZE 32 +#include "fp.c" + +#define N_1 7 +#define N2 6 // for seconds/milliseconds,... time series +#define N3 12 +#define N4 20 // must be > 16 +#define USIZE 64 +#include "fp.c" + + #else //-------------------------------------- Template functions ------------------------------------------------------------ + +#define XORENC( _u_, _pu_, _usize_) ((_u_)^(_pu_)) // xor predictor +#define XORDEC( _u_, _pu_, _usize_) ((_u_)^(_pu_)) +#define ZZAGENC(_u_, _pu_, _usize_) TEMPLATE2(zigzagenc,_usize_)((_u_)-(_pu_)) //zigzag predictor +#define ZZAGDEC(_u_, _pu_, _usize_) (TEMPLATE2(zigzagdec,_usize_)(_u_)+(_pu_)) + +#define uint_t TEMPLATE3(uint, USIZE, _t) +#define int_t TEMPLATE3(int, USIZE, _t) + +//-------- TurboPFor Zigzag of zigzag for unsorted/sorted integer/floating point array --------------------------------------- +size_t TEMPLATE2(p4nzzenc128v,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t _p[VSIZE+32], *ip, *p, pd = 0; + unsigned char *op = out; + + #define FE(i,_usize_) { TEMPLATE3(uint, USIZE, _t) u = ip[i]; start = u-start; p[i] = ZZAGENC(start,pd,_usize_); pd = start; start = u; } + for(ip = in; ip != in + (n&~(VSIZE-1)); ) { + for(p = _p; p != &_p[VSIZE]; p+=4,ip+=4) { FE(0,USIZE); FE(1,USIZE); FE(2,USIZE); FE(3,USIZE); } + op = TEMPLATE2(P4ENCV,USIZE)(_p, VSIZE, op); PREFETCH(ip+512,0); + } + if(n = (in+n)-ip) { + for(p = _p; p != &_p[n]; p++,ip++) FE(0,USIZE); + op = TEMPLATE2(P4ENC,USIZE)(_p, n, op); + } + return op - out; +} + +size_t TEMPLATE2(p4nzzdec128v,USIZE)(unsigned char *in, size_t n, uint_t *out, uint_t start) { + uint_t _p[VSIZE+32],*p, *op, pd=0; + unsigned char *ip = in; + + #define FD(i,_usize_) { TEMPLATE3(uint, USIZE, _t) u = ZZAGDEC(p[i],start+pd,_usize_); op[i] = u; pd = u - start; start = u; } + for(op = out; op != out+(n&~(VSIZE-1)); ) { PREFETCH(ip+512,0); + for(ip = TEMPLATE2(P4DECV,USIZE)(ip, VSIZE, _p), p = _p; p != &_p[VSIZE]; p+=4,op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); } + } + if(n = (out+n) - op) + for(ip = TEMPLATE2(P4DEC,USIZE)(ip, n, _p), p = _p; p != &_p[n]; p++,op++) FD(0,USIZE); + return ip - in; +} + +/*---------------- TurboFloat XOR: last value Predictor with TurboPFor --------------------------------------------------------- + Compress significantly (115% - 160%) better than Facebook's Gorilla algorithm for values + BEST results are obtained with LOSSY COMPRESSION (using fppad32/fppad64 in bitutil.c) + 1: XOR value with previous value. We have now leading (for common sign/exponent bits) + mantissa trailing zero bits + 2: Eliminate the common block leading zeros of sign/exponent by shifting all values in the block to left + 3: reverse values to bring the mantissa trailing zero bits to left for better compression with TurboPFor +*/ +size_t TEMPLATE2(fpxenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t _p[VSIZE+32], *ip, *p; + unsigned char *op = out; + #if defined(__AVX2__) && USIZE >= 32 + #define _mm256_set1_epi64(a) _mm256_set1_epi64x(a) + __m256i sv = TEMPLATE2(_mm256_set1_epi, USIZE)(start); + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + #define _mm_set1_epi64(a) _mm_set1_epi64x(a) + __m128i sv = TEMPLATE2(_mm_set1_epi, USIZE)(start); + #endif + + #define FE(i,_usize_) { TEMPLATE3(uint, _usize_, _t) u = ip[i]; p[i] = XORENC(u, start,_usize_); b |= p[i]; start = u; } + for(ip = in; ip != in + (n&~(VSIZE-1)); ) { uint_t b = 0; + #if defined(__AVX2__) && USIZE >= 32 + __m256i bv = _mm256_setzero_si256(); + for(p = _p; p != &_p[VSIZE]; p+=64/(USIZE/8),ip+=64/(USIZE/8)) { + __m256i v0 = _mm256_loadu_si256((__m256i *) ip); + __m256i v1 = _mm256_loadu_si256((__m256i *)(ip+32/(USIZE/8))); + sv = TEMPLATE2(mm256_xore_epi, USIZE)(v0,sv); bv = _mm256_or_si256(bv, sv); _mm256_storeu_si256((__m256i *) p, sv); sv = v0; + sv = TEMPLATE2(mm256_xore_epi, USIZE)(v1,sv); bv = _mm256_or_si256(bv, sv); _mm256_storeu_si256((__m256i *)(p+32/(USIZE/8)), sv); sv = v1; + } + start = (uint_t)TEMPLATE2(_mm256_extract_epi,USIZE)(sv, 256/USIZE-1); + b = TEMPLATE2(mm256_hor_epi, USIZE)(bv); + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + __m128i bv = _mm_setzero_si128(); + for(p = _p; p != &_p[VSIZE]; p+=32/(USIZE/8),ip+=32/(USIZE/8)) { + __m128i v0 = _mm_loadu_si128((__m128i *) ip); + __m128i v1 = _mm_loadu_si128((__m128i *)(ip+16/(USIZE/8))); + sv = TEMPLATE2(mm_xore_epi, USIZE)(v0,sv); bv = _mm_or_si128(bv, sv); _mm_storeu_si128((__m128i *) p, sv); sv = v0; + sv = TEMPLATE2(mm_xore_epi, USIZE)(v1,sv); bv = _mm_or_si128(bv, sv); _mm_storeu_si128((__m128i *)(p+16/(USIZE/8)), sv); sv = v1; + } + start = (uint_t)TEMPLATE2(_mm_cvtsi128_si,USIZE)(_mm_srli_si128(sv,16-USIZE/8)); + b = TEMPLATE2(mm_hor_epi, USIZE)(bv); + #else + for(p = _p; p != &_p[VSIZE]; p+=4,ip+=4) { FE(0,USIZE); FE(1,USIZE); FE(2,USIZE); FE(3,USIZE); } + #endif + *op++ = b = TEMPLATE2(clz,USIZE)(b); + #define TR(i,_usize_) p[i] = TEMPLATE2(rbit,_usize_)(p[i]<= 32 + for(p = _p; p != &_p[VSIZE]; p+=64/(USIZE/8)) { + __m256i v0 = _mm256_loadu_si256((__m256i *)p); + __m256i v1 = _mm256_loadu_si256((__m256i *)(p+32/(USIZE/8))); + v0 = TEMPLATE2(_mm256_slli_epi, USIZE)(v0,b); + v1 = TEMPLATE2(_mm256_slli_epi, USIZE)(v1,b); + v0 = TEMPLATE2( mm256_rbit_epi, USIZE)(v0); + v1 = TEMPLATE2( mm256_rbit_epi, USIZE)(v1); + _mm256_storeu_si256((__m256i *) p, v0); + _mm256_storeu_si256((__m256i *)(p+32/(USIZE/8)), v1); + } + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + for(p = _p; p != &_p[VSIZE]; p+=32/(USIZE/8)) { + __m128i v0 = _mm_loadu_si128((__m128i *) p); + __m128i v1 = _mm_loadu_si128((__m128i *)(p+16/(USIZE/8))); + v0 = TEMPLATE2(_mm_slli_epi, USIZE)(v0,b); + v0 = TEMPLATE2( mm_rbit_epi, USIZE)(v0); + v1 = TEMPLATE2(_mm_slli_epi, USIZE)(v1,b); + v1 = TEMPLATE2( mm_rbit_epi, USIZE)(v1); + _mm_storeu_si128((__m128i *) p, v0); + _mm_storeu_si128((__m128i *)(p+16/(USIZE/8)), v1); + } + #else + for(p = _p; p != &_p[VSIZE]; p+=4) { TR(0,USIZE); TR(1,USIZE); TR(2,USIZE); TR(3,USIZE); } + #endif + op = TEMPLATE2(P4ENCV,USIZE)(_p, VSIZE, op); PREFETCH(ip+512,0); + } + if(n = (in+n)-ip) { uint_t b = 0; + for(p = _p; p != &_p[n]; p++,ip++) FE(0,USIZE); + b = TEMPLATE2(clz,USIZE)(b); + *op++ = b; + for(p = _p; p != &_p[n]; p++) TR(0,USIZE); + op = TEMPLATE2(P4ENC,USIZE)(_p, n, op); + } + return op - out; +} + +size_t TEMPLATE2(fpxdec,USIZE)(unsigned char *in, size_t n, uint_t *out, uint_t start) { + uint_t *op, _p[VSIZE+32],*p; + unsigned char *ip = in; + #if defined(__AVX2__) && USIZE >= 32 + #define _mm256_set1_epi64(a) _mm256_set1_epi64x(a) + __m256i sv = TEMPLATE2(_mm256_set1_epi, USIZE)(start); + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + #define _mm_set1_epi64(a) _mm_set1_epi64x(a) + __m128i sv = TEMPLATE2(_mm_set1_epi, USIZE)(start); + #endif + #define FD(i,_usize_) { TEMPLATE3(uint, USIZE, _t) u = p[i]; u = TEMPLATE2(rbit,_usize_)(u)>>b; u = XORDEC(u, start,_usize_); op[i] = start = u; } + for(op = out; op != out+(n&~(VSIZE-1)); ) { PREFETCH(ip+512,0); + unsigned b = *ip++; ip = TEMPLATE2(P4DECV,USIZE)(ip, VSIZE, _p); + + #if defined(__AVX2__) && USIZE >= 32 + for(p = _p; p != &_p[VSIZE]; p+=64/(USIZE/8),op+=64/(USIZE/8)) { + __m256i v0 = _mm256_loadu_si256((__m256i *)p); + __m256i v1 = _mm256_loadu_si256((__m256i *)(p+32/(USIZE/8))); + v0 = TEMPLATE2( mm256_rbit_epi, USIZE)(v0); + v1 = TEMPLATE2( mm256_rbit_epi, USIZE)(v1); + v0 = TEMPLATE2(_mm256_srli_epi, USIZE)(v0,b); + v1 = TEMPLATE2(_mm256_srli_epi, USIZE)(v1,b); + v0 = TEMPLATE2( mm256_xord_epi, USIZE)(v0,sv); + sv = TEMPLATE2( mm256_xord_epi, USIZE)(v1,v0); + _mm256_storeu_si256((__m256i *)op, v0); + _mm256_storeu_si256((__m256i *)(op+32/(USIZE/8)), sv); + } + start = (uint_t)TEMPLATE2(_mm256_extract_epi,USIZE)(sv, 256/USIZE-1); + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + for(p = _p; p != &_p[VSIZE]; p+=32/(USIZE/8),op+=32/(USIZE/8)) { + __m128i v0 = _mm_loadu_si128((__m128i *)p); + __m128i v1 = _mm_loadu_si128((__m128i *)(p+16/(USIZE/8))); + v0 = TEMPLATE2( mm_rbit_epi, USIZE)(v0); + v0 = TEMPLATE2(_mm_srli_epi, USIZE)(v0,b); + v0 = TEMPLATE2( mm_xord_epi, USIZE)(v0,sv); + v1 = TEMPLATE2( mm_rbit_epi, USIZE)(v1); + v1 = TEMPLATE2(_mm_srli_epi, USIZE)(v1,b); + sv = TEMPLATE2( mm_xord_epi, USIZE)(v1,v0); + _mm_storeu_si128((__m128i *) op, v0); + _mm_storeu_si128((__m128i *)(op+16/(USIZE/8)), sv); + } + start = (uint_t)TEMPLATE2(_mm_cvtsi128_si,USIZE)(_mm_srli_si128(sv,16-USIZE/8)); + #else + for(p = _p; p != &_p[VSIZE]; p+=4,op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); } + #endif + } + if(n = (out+n) - op) { + uint_t b = *ip++; + for(ip = TEMPLATE2(P4DEC,USIZE)(ip, n, _p), p = _p; p < &_p[n]; p++,op++) FD(0,USIZE); + } + return ip - in; +} + +//-------- TurboFloat FCM: Finite Context Method Predictor --------------------------------------------------------------- +#define HBITS 13 //15 +#define HASH64(_h_,_u_) (((_h_)<<5 ^ (_u_)>>50) & ((1u<>23) & ((1u<>12) & ((1u<> 5) & ((1u<= 32 + #define _mm256_set1_epi64(a) _mm256_set1_epi64x(a) + __m256i sv = TEMPLATE2(_mm256_set1_epi, USIZE)(start); + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + #define _mm_set1_epi64(a) _mm_set1_epi64x(a) + __m128i sv = TEMPLATE2(_mm_set1_epi, USIZE)(start); + #endif + + for(ip = in; ip != in + (n&~(VSIZE-1)); ) { uint_t b = 0; + #define FE(i,_usize_) { TEMPLATE3(uint, _usize_, _t) u = ip[i]; p[i] = XORENC(u, htab[h],_usize_); b |= p[i]; htab[h] = u; h = TEMPLATE2(HASH,_usize_)(h,u); } + for(p = _p; p != &_p[VSIZE]; p+=4,ip+=4) { FE(0,USIZE); FE(1,USIZE); FE(2,USIZE); FE(3,USIZE); } + *op++ = b = TEMPLATE2(clz,USIZE)(b); + #if defined(__AVX2__) && USIZE >= 32 + for(p = _p; p != &_p[VSIZE]; p+=64/(USIZE/8)) { + __m256i v0 = _mm256_loadu_si256((__m256i *)p); + __m256i v1 = _mm256_loadu_si256((__m256i *)(p+32/(USIZE/8))); + v0 = TEMPLATE2(_mm256_slli_epi, USIZE)(v0,b); + v1 = TEMPLATE2(_mm256_slli_epi, USIZE)(v1,b); + v0 = TEMPLATE2( mm256_rbit_epi, USIZE)(v0); + v1 = TEMPLATE2( mm256_rbit_epi, USIZE)(v1); + _mm256_storeu_si256((__m256i *) p, v0); + _mm256_storeu_si256((__m256i *)(p+32/(USIZE/8)), v1); + } + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && (USIZE == 16 || USIZE == 32) + for(p = _p; p != &_p[VSIZE]; p+=32/(USIZE/8)) { + __m128i v0 = _mm_loadu_si128((__m128i *) p); + __m128i v1 = _mm_loadu_si128((__m128i *)(p+16/(USIZE/8))); + v0 = TEMPLATE2(_mm_slli_epi, USIZE)(v0,b); + v0 = TEMPLATE2( mm_rbit_epi, USIZE)(v0); + v1 = TEMPLATE2(_mm_slli_epi, USIZE)(v1,b); + v1 = TEMPLATE2( mm_rbit_epi, USIZE)(v1); + _mm_storeu_si128((__m128i *) p, v0); + _mm_storeu_si128((__m128i *)(p+16/(USIZE/8)), v1); + } + #else + #define TR(i,_usize_) p[i] = TEMPLATE2(rbit,_usize_)(p[i]<>b;\ + u = XORDEC(u, htab[h], _usize_); op[i] = u; htab[h] = u; h = TEMPLATE2(HASH,_usize_)(h,u);\ + } + for(op = (uint_t*)out; op != out+(n&~(VSIZE-1)); ) { PREFETCH(ip+512,0); + unsigned b = *ip++; ip = TEMPLATE2(P4DECV,USIZE)(ip, VSIZE, _p); + for(p = _p; p != &_p[VSIZE]; p+=4,op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); } + } + if(n = ((uint_t *)out+n) - op) { + unsigned b = *ip++; ip = TEMPLATE2(P4DEC,USIZE)(ip, n, _p); + for(p = _p; p != &_p[n]; p++,op++) FD(0,USIZE); + } + return ip - in; +} + +//-------- TurboFloat DFCM: Differential Finite Context Method Predictor ---------------------------------------------------------- +size_t TEMPLATE2(fpdfcmenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t *ip, _p[VSIZE+32], h = 0, *p, htab[1<>b; u = XORDEC(u, (htab[h]+start),_usize_); \ + op[i] = u; htab[h] = start = u-start; h = TEMPLATE2(HASH,_usize_)(h,start); start = u;\ + } + for(op = (uint_t*)out; op != out+(n&~(VSIZE-1)); ) { PREFETCH(ip+512,0); + uint_t b = *ip++; + ip = TEMPLATE2(P4DECV,USIZE)(ip, VSIZE, _p); + for(p = _p; p != &_p[VSIZE]; p+=4,op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); } + } + if(n = ((uint_t *)out+n) - op) { + uint_t b = *ip++; + ip = TEMPLATE2(P4DEC,USIZE)(ip, n, _p); + for(p = _p; p != &_p[n]; p++,op++) FD(0,USIZE); + } + return ip - in; +} + +//-------- TurboFloat 2D DFCM: Differential Finite Context Method Predictor ---------------------------------------------------------- +size_t TEMPLATE2(fp2dfcmenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t *ip, _p[VSIZE+32], h = 0, *p, htab[1<>b; u = XORDEC(u, (htab[h]+start),_usize_);\ + op[i] = u; htab[h] = start = u-start; h = TEMPLATE2(HASH,_usize_)(h,start); start = start0; start0 = u;\ + } + + for(op = (uint_t*)out; op != out+(n&~(VSIZE-1)); ) { PREFETCH(ip+512,0); + uint_t b = *ip++; + ip = TEMPLATE2(P4DECV,USIZE)(ip, VSIZE, _p); + for(p = _p; p != &_p[VSIZE]; p+=4,op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); } + } + if(n = ((uint_t *)out+n) - op) { + uint_t b = *ip++; + ip = TEMPLATE2(P4DEC,USIZE)(ip, n, _p); + for(p = _p; p != &_p[n]; p++,op++) FD(0,USIZE); + } + return ip - in; +} + +//-------- TurboGorilla : Improved Gorilla style (see Facebook paper) Floating point compression with bitio ------------------------------------ +#define bitput2(_bw_,_br_, _n1_, _n2_, _x_) {\ + if(!_x_) bitput(_bw_,_br_, 1, 1);/*1*/\ + else if( _x_ < (1<< (_n1_-1))) bitput(_bw_,_br_, _n1_+2,_x_<<2|2);/*10*/\ + else bitput(_bw_,_br_, _n2_+2,_x_<<2 );/*00*/\ +} + +#define bitget2(_bw_,_br_, _n1_, _n2_, _x_) { _x_ = bitbw(_bw_,_br_);\ + if(_x_ & 1) bitrmv(_bw_,_br_, 0+1), _x_ = 0;\ + else if(_x_ & 2) bitrmv(_bw_,_br_,_n1_+2), _x_ = BZHI32(_x_>>2, _n1_);\ + else bitrmv(_bw_,_br_,_n2_+2), _x_ = BZHI32(_x_>>2, _n2_);\ +} + +#define BSIZE(_usize_) (_usize_==64?6:(_usize_==32?5:(_usize_==16?4:3))) +size_t TEMPLATE2(fpgenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t *ip; + unsigned ol = 0,ot = 0; + unsigned char *op = out; + bitdef(bw,br); + if(start) { ol = TEMPLATE2(clz,USIZE)(start); ot = TEMPLATE2(ctz,USIZE)(start); } + + #define FE(i,_usize_) { TEMPLATE3(uint, _usize_, _t) z = XORENC(ip[i], start,_usize_); start = ip[i];\ + if(likely(!z)) bitput( bw,br, 1, 1);\ + else { unsigned t = TEMPLATE2(ctz,_usize_)(z), l = TEMPLATE2(clz,_usize_)(z);\ + unsigned s = _usize_ - l - t, os = _usize_ - ol - ot;\ + if(l >= ol && t >= ot && os < 6+5+s) { bitput( bw,br, 2, 2); TEMPLATE2(bitput,_usize_)(bw,br, os, z>>ot,op); }\ + else { bitput( bw,br, 2+BSIZE(_usize_), l<<2); bitput2(bw,br, N_0, N_1, t); bitenorm(bw,br,op);TEMPLATE2(bitput,_usize_)(bw,br, s, z>>t,op); ol = l; ot = t; }\ + } bitenorm(bw,br,op);\ + } + for(ip = in; ip != in + (n&~(4-1)); ip+=4) { PREFETCH(ip+512,0); FE(0,USIZE); FE(1,USIZE); FE(2,USIZE); FE(3,USIZE); } + for( ; ip != in + n ; ip++) FE(0,USIZE); + bitflush(bw,br,op); + return op - out; +} + +size_t TEMPLATE2(fpgdec,USIZE)(unsigned char *in, size_t n, uint_t *out, uint_t start) { if(!n) return 0; + uint_t *op; + unsigned ol = 0,ot = 0,x; + unsigned char *ip = in; + bitdef(bw,br); + if(start) { ol = TEMPLATE2(clz,USIZE)(start); ot = TEMPLATE2(ctz,USIZE)(start); } + + #define FD(i,_usize_) { TEMPLATE3(uint, _usize_, _t) z=0; unsigned _x; BITGET32(bw,br,1,_x); \ + if(likely(!_x)) { BITGET32(bw,br,1,_x);\ + if(!_x) { BITGET32(bw,br,BSIZE(_usize_),ol); bitget2(bw,br, N_0, N_1, ot); bitdnorm(bw,br,ip); }\ + TEMPLATE2(bitget,_usize_)(bw,br,_usize_ - ol - ot,z,ip);\ + z<<=ot;\ + } op[i] = start = XORDEC(z, start,_usize_); bitdnorm(bw,br,ip);\ + } + for(bitdnorm(bw,br,ip),op = out; op != out+(n&~(4-1)); op+=4) { FD(0,USIZE); FD(1,USIZE); FD(2,USIZE); FD(3,USIZE); PREFETCH(ip+512,0); } + for( ; op != out+n; op++) FD(0,USIZE); + bitalign(bw,br,ip); + return ip - in; +} + +//------ Zigzag of zigzag with bitio for timestamps with bitio ------------------------------------------------------------------------------------------ +// Improved Gorilla style compression with sliding zigzag of delta + RLE + overflow handling for timestamps in time series. +// More than 300 times better compression and several times faster +#define OVERFLOW if(op >= out_) { *out++ = 1<<4; /*bitini(bw,br); bitput(bw,br,4+3,1<<4); bitflush(bw,br,out);*/ memcpy(out,in,n*sizeof(in[0])); return 1+n*sizeof(in[0]); } + +size_t TEMPLATE2(bvzzenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t *ip = in, pd = 0, *pp = in,dd; + unsigned char *op = out, *out_ = out+n*sizeof(in[0]); + + bitdef(bw,br); + #define FE(_pp_, _ip_, _d_, _op_,_usize_) do {\ + uint64_t _r = _ip_ - _pp_;\ + if(_r > NL) { _r -= NL; unsigned _b = (bsr64(_r)+7)>>3; bitput(bw,br,4+3+3,(_b-1)<<(4+3)); bitput64(bw,br,_b<<3, _r, _op_); bitenorm(bw,br,_op_); }\ + else while(_r--) { bitput(bw,br,1,1); bitenorm(bw,br,_op_); }\ + _d_ = TEMPLATE2(zigzagenc,_usize_)(_d_);\ + if(!_d_) bitput(bw,br, 1, 1);\ + else if(_d_ < (1<< (N2-1))) bitput(bw,br, N2+2,_d_<<2|2);\ + else if(_d_ < (1<< (N3-1))) bitput(bw,br, N3+3,_d_<<3|4);\ + else if(_d_ < (1<< (N4-1))) bitput(bw,br, N4+4,_d_<<4|8);\ + else { unsigned _b = (TEMPLATE2(bsr,_usize_)(_d_)+7)>>3; bitput(bw,br,4+3,(_b-1)<<4); TEMPLATE2(bitput,_usize_)(bw,br, _b<<3, _d_,_op_); }\ + bitenorm(bw,br,_op_);\ + } while(0) + + if(n > 4) + for(; ip < in+(n-1-4);) { + start = ip[0] - start; dd = start-pd; pd = start; start = ip[0]; if(dd) goto a; ip++; + start = ip[0] - start; dd = start-pd; pd = start; start = ip[0]; if(dd) goto a; ip++; + start = ip[0] - start; dd = start-pd; pd = start; start = ip[0]; if(dd) goto a; ip++; + start = ip[0] - start; dd = start-pd; pd = start; start = ip[0]; if(dd) goto a; ip++; PREFETCH(ip+256,0); + continue; + a:; + FE(pp,ip, dd, op,USIZE); + pp = ++ip; OVERFLOW; + } + + for(;ip < in+n;) { + start = ip[0] - start; dd = start-pd; pd = start; start = ip[0]; if(dd) goto b; ip++; + continue; + b:; + FE(pp,ip, dd, op,USIZE); + pp = ++ip; OVERFLOW; + } + if(ip > pp) { + start = ip[0] - start; dd = start-pd; + FE(pp, ip, dd, op, USIZE); OVERFLOW; + } + bitflush(bw,br,op); + return op - out; +} + +size_t TEMPLATE2(bvzzdec,USIZE)(unsigned char *in, size_t n, uint_t *out, uint_t start) { if(!n) return 0; + uint_t *op = out, pd = 0; + unsigned char *ip = in; + + bitdef(bw,br); + for(bitdnorm(bw,br,ip); op < out+n; ) { PREFETCH(ip+384,0); + #if USIZE == 64 + uint_t dd = bitbw(bw,br); + #else + uint32_t dd = bitbw(bw,br); + #endif + if(dd & 1) bitrmv(bw,br, 0+1), dd = 0; + else if(dd & 2) bitrmv(bw,br,N2+2), dd = BZHI32(dd>>2, N2); + else if(dd & 4) bitrmv(bw,br,N3+3), dd = BZHI32(dd>>3, N3); + else if(dd & 8) bitrmv(bw,br,N4+4), dd = BZHI32(dd>>4, N4); + else { + unsigned b; uint_t *_op; uint64_t r; + BITGET32(bw,br, 4+3, b); + if((b>>=4) <= 1) { + if(b==1) { // No compression, because of overflow + memcpy(out,in+1, n*sizeof(out[0])); + return 1+n*sizeof(out[0]); + } + BITGET32(bw,br,3,b); bitget32(bw,br,(b+1)<<3,r,ip); bitdnorm(bw,br,ip);//RLE //r+=NL; while(r--) *op++=(start+=pd); + #if (defined(__SSE2__) /*|| defined(__ARM_NEON)*/) && USIZE == 32 + __m128i sv = _mm_set1_epi32(start), cv = _mm_set_epi32(4*pd,3*pd,2*pd,1*pd); + for(r += NL, _op = op; op != _op+(r&~7);) { + sv = _mm_add_epi32(sv,cv); _mm_storeu_si128(op, sv); sv = mm_shuffle_nnnn_epi32(sv, 3); op += 4; //_mm_shuffle_epi32(sv, _MM_SHUFFLE(3, 3, 3, 3))->mm_shuffle_nnnn_epi32(sv, 3) + sv = _mm_add_epi32(sv,cv); _mm_storeu_si128(op, sv); sv = mm_shuffle_nnnn_epi32(sv, 3); op += 4; + } + start = (unsigned)_mm_cvtsi128_si32(_mm_srli_si128(sv,12)); + #else + for(r+=NL, _op = op; op != _op+(r&~7); op += 8) + op[0]=(start+=pd), + op[1]=(start+=pd), + op[2]=(start+=pd), + op[3]=(start+=pd), + op[4]=(start+=pd), + op[5]=(start+=pd), + op[6]=(start+=pd), + op[7]=(start+=pd); + #endif + for(; op != _op+r; op++) + *op = (start+=pd); + continue; + } + TEMPLATE2(bitget,USIZE)(bw,br,(b+1)<<3,dd,ip); + } + pd += TEMPLATE2(zigzagdec,USIZE)(dd); + *op++ = (start += pd); + bitdnorm(bw,br,ip); + } + bitalign(bw,br,ip); + return ip - in; +} + +//-------- Zigzag with bit/io + RLE -------------------------------------------------------------------------- +size_t TEMPLATE2(bvzenc,USIZE)(uint_t *in, size_t n, unsigned char *out, uint_t start) { + uint_t *ip = in, *pp = in,dd; + unsigned char *op = out, *out_ = out+n*sizeof(in[0]); + + bitdef(bw,br); + #define FE(_pp_, _ip_, _d_, _op_,_usize_) do {\ + uint64_t _r = _ip_ - _pp_;\ + if(_r > NL) { _r -= NL; unsigned _b = (bsr64(_r)+7)>>3; bitput(bw,br,4+3+3,(_b-1)<<(4+3)); bitput64(bw,br,_b<<3, _r, _op_); bitenorm(bw,br,_op_); }\ + else while(_r--) { bitput(bw,br,1,1); bitenorm(bw,br,_op_); }\ + _d_ = TEMPLATE2(zigzagenc,_usize_)(_d_);\ + if(!_d_) bitput(bw,br, 1, 1);\ + else if(_d_ < (1<< (N2-1))) bitput(bw,br, N2+2,_d_<<2|2);\ + else if(_d_ < (1<< (N3-1))) bitput(bw,br, N3+3,_d_<<3|4);\ + else if(_d_ < (1<< (N4-1))) bitput(bw,br, N4+4,_d_<<4|8);\ + else { unsigned _b = (TEMPLATE2(bsr,_usize_)(_d_)+7)>>3; bitput(bw,br,4+3,(_b-1)<<4); TEMPLATE2(bitput,_usize_)(bw,br, _b<<3, _d_,_op_); }\ + bitenorm(bw,br,_op_);\ + } while(0) + + if(n > 4) + for(; ip < in+(n-1-4);) { + dd = ip[0] - start; start = ip[0]; if(dd) goto a; ip++; + dd = ip[0] - start; start = ip[0]; if(dd) goto a; ip++; + dd = ip[0] - start; start = ip[0]; if(dd) goto a; ip++; + dd = ip[0] - start; start = ip[0]; if(dd) goto a; ip++; PREFETCH(ip+256,0); + continue; + a:; + FE(pp,ip, dd, op,USIZE); + pp = ++ip; OVERFLOW; + } + + for(;ip < in+n;) { + dd = ip[0] - start; start = ip[0]; if(dd) goto b; ip++; + continue; + b:; + FE(pp,ip, dd, op,USIZE); + pp = ++ip; OVERFLOW; + } + if(ip > pp) { + dd = ip[0] - start; start = ip[0]; + FE(pp, ip, dd, op, USIZE); OVERFLOW; + } + bitflush(bw,br,op); + return op - out; +} + +size_t TEMPLATE2(bvzdec,USIZE)(unsigned char *in, size_t n, uint_t *out, uint_t start) { if(!n) return 0; + uint_t *op = out; + unsigned char *ip = in; + + bitdef(bw,br); + for(bitdnorm(bw,br,ip); op < out+n; ) { PREFETCH(ip+384,0); + #if USIZE == 64 + uint_t dd = bitbw(bw,br); + #else + uint32_t dd = bitbw(bw,br); + #endif + if(dd & 1) bitrmv(bw,br, 0+1), dd = 0; + else if(dd & 2) bitrmv(bw,br,N2+2), dd = BZHI32(dd>>2, N2); + else if(dd & 4) bitrmv(bw,br,N3+3), dd = BZHI32(dd>>3, N3); + else if(dd & 8) bitrmv(bw,br,N4+4), dd = BZHI32(dd>>4, N4); + else { + unsigned b; uint_t *_op; uint64_t r; + BITGET32(bw,br, 4+3, b); + if((b>>=4) <= 1) { + if(b==1) { // No compression, because of overflow + memcpy(out,in+1, n*sizeof(out[0])); + return 1+n*sizeof(out[0]); + } + BITGET32(bw,br,3,b); bitget32(bw,br,(b+1)<<3,r,ip); bitdnorm(bw,br,ip);//RLE //r+=NL; while(r--) *op++=(start+=pd); + #if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32 + __m128i sv = _mm_set1_epi32(start); + for(r += NL, _op = op; op != _op+(r&~7);) { + _mm_storeu_si128(op, sv); op += 4; + _mm_storeu_si128(op, sv); op += 4; + } + #else + for(r+=NL, _op = op; op != _op+(r&~7); op += 8) + op[0]=op[1]=op[2]=op[3]=op[4]=op[5]=op[6]=op[7]=start; + #endif + for(; op != _op+r; op++) + *op = start; + continue; + } + TEMPLATE2(bitget,USIZE)(bw,br,(b+1)<<3,dd,ip); + } + dd = TEMPLATE2(zigzagdec,USIZE)(dd); + *op++ = (start += dd); + bitdnorm(bw,br,ip); + } + bitalign(bw,br,ip); + return ip - in; +} + +#undef USIZE + #endif diff --git a/src/ext/for/fp.h b/src/ext/for/fp.h new file mode 100644 index 00000000000..f50d43f9f17 --- /dev/null +++ b/src/ext/for/fp.h @@ -0,0 +1,125 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Floating Point + Integer Compression" +#ifdef __cplusplus +extern "C" { +#endif +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif + +// ---------- TurboPFor Zigzag of delta (=delta of delta + zigzag encoding) (TurboPFor) +size_t p4nzzenc128v8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t p4nzzdec128v8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t p4nzzenc128v16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t p4nzzdec128v16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t p4nzzenc128v32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t p4nzzdec128v32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t p4nzzenc128v64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t p4nzzdec128v64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- Zigzag (bit/io) ------------------------------------------------------- +size_t bvzenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t bvzdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t bvzenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t bvzdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t bvzenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t bvzdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t bvzenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t bvzdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); +//----------- Zigzag of delta (bit/io) --------------------------------------------- +size_t bvzzenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t bvzzdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t bvzzenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t bvzzdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t bvzzenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t bvzzdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t bvzzenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t bvzzdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- TurboGorilla : Improved gorilla style + RLE (bit/io) ------------------ +size_t fpgenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fpgdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fpgenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fpgdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fpgenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fpgdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fpgenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fpgdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- TurboFloat XOR : Last value predictor (TurboPFor) --------------------- +size_t fpxenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fpxdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fpxenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fpxdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fpxenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fpxdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fpxenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fpxdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- TurboFloat FCM: Finite Context Method Predictor (TurboPFor) ----------- +size_t fpfcmenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fpfcmdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fpfcmenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fpfcmdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fpfcmenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fpfcmdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fpfcmenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fpfcmdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- TurboFloat DFCM: Differential Finite Context Method Predictor (TurboPFor) +size_t fpdfcmenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fpdfcmdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fpdfcmenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fpdfcmdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fpdfcmenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fpdfcmdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fpdfcmenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fpdfcmdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +//----------- TurboFloat 2D DFCM: Differential Finite Context Method Predictor ----- +size_t fp2dfcmenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fp2dfcmdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fp2dfcmenc16(uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fp2dfcmdec16(unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fp2dfcmenc32(uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fp2dfcmdec32(unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fp2dfcmenc64(uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fp2dfcmdec64(unsigned char *in, size_t n, uint64_t *out, uint64_t start); + +/*/-------------- delta (=zigzag). Same as p4zenc ------------------------------------ +size_t fppenc8( uint8_t *in, size_t n, unsigned char *out, uint8_t start); +size_t fppdec8( unsigned char *in, size_t n, uint8_t *out, uint8_t start); +size_t fppenc16( uint16_t *in, size_t n, unsigned char *out, uint16_t start); +size_t fppdec16( unsigned char *in, size_t n, uint16_t *out, uint16_t start); +size_t fppenc32( uint32_t *in, size_t n, unsigned char *out, uint32_t start); +size_t fppdec32( unsigned char *in, size_t n, uint32_t *out, uint32_t start); +size_t fppenc64( uint64_t *in, size_t n, unsigned char *out, uint64_t start); +size_t fppdec64( unsigned char *in, size_t n, uint64_t *out, uint64_t start);*/ + +#ifdef __cplusplus +} +#endif diff --git a/src/ext/for/icapp.c b/src/ext/for/icapp.c new file mode 100644 index 00000000000..0509f18fb63 --- /dev/null +++ b/src/ext/for/icapp.c @@ -0,0 +1,1909 @@ +/** + Copyright (C) powturbo 2015-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - email : powturbo [AT] gmail.com + - github : https://github.com/powturbo + - homepage : https://sites.google.com/site/powturbo/ + - twitter : https://twitter.com/powturbo +**/ +// TurboPFor - "IcApp: Benchmark application" + +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + #ifdef _MSC_VER +#include "vs/getopt.h" + #else +#include +#endif + #if defined(_WIN32) +#include +#define srand48(x) srand(x) +#define drand48() ((double)(rand()) / RAND_MAX) +#define __off64_t _off64_t + #endif +#include // pow,fabs +#include + +#include "conf.h" +#include "time_.h" +#define BITUTIL_IN +#include "bitutil.h" + + #if defined(__i386__) || defined(__x86_64__) +#define SSE +#define AVX2 + #elif defined(__ARM_NEON) || defined(__powerpc64__) +#define SSE + #endif + +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#define max(x,y) (((x)>(y)) ? (x) : (y)) +#endif + +int verbose = 1,isa; + +//------------------------------ bits statistics -------------------------------------------------- +static unsigned xbits[65],tbits[65],zbits[65]; +unsigned histl8( uint8_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) xbits[i]=0; for(i = 0; i < n; i++) xbits[l=bsr8( in[i])]++,s+=l; return (s+7)/8; } +unsigned histl16(uint16_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) xbits[i]=0; for(i = 0; i < n; i++) xbits[l=bsr16(in[i])]++,s+=l; return (s+7)/8; } +unsigned histl32(uint32_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) xbits[i]=0; for(i = 0; i < n; i++) xbits[l=bsr32(in[i])]++,s+=l; return (s+7)/8; } +unsigned histl64(uint64_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) xbits[i]=0; for(i = 0; i < n; i++) xbits[l=bsr64(in[i])]++,s+=l; return (s+7)/8; } + +unsigned histz8( uint8_t *in, unsigned n) { unsigned i,l; uint64_t s=0; uint8_t x = 0; for(i = 0; i < 65; i++) zbits[i]=0; for(i = 0; i < n; i++) zbits[l=bsr8( zigzagenc8( in[i]-x))]++,s+=l,x=in[i]; return (s+7)/8; } +unsigned histz16(uint16_t *in, unsigned n) { unsigned i,l; uint64_t s=0; uint16_t x = 0; for(i = 0; i < 65; i++) zbits[i]=0; for(i = 0; i < n; i++) zbits[l=bsr16(zigzagenc16(in[i]-x))]++,s+=l,x=in[i]; return (s+7)/8; } +unsigned histz32(uint32_t *in, unsigned n) { unsigned i,l; uint64_t s=0; uint32_t x = 0; for(i = 0; i < 65; i++) zbits[i]=0; for(i = 0; i < n; i++) zbits[l=bsr32(zigzagenc32(in[i]-x))]++,s+=l,x=in[i]; return (s+7)/8; } +unsigned histz64(uint64_t *in, unsigned n) { unsigned i,l; uint64_t s=0; uint64_t x = 0; for(i = 0; i < 65; i++) zbits[i]=0; for(i = 0; i < n; i++) zbits[l=bsr64(zigzagenc64(in[i]-x))]++,s+=l,x=in[i]; return (s+7)/8; } + +unsigned histt8( uint8_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) tbits[i]=0; for(i = 0; i < n; i++) l=tbits[in[i]?ctz8( in[i]): 8]++,s+=l; return (s+7)/8; } +unsigned histt16(uint16_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) tbits[i]=0; for(i = 0; i < n; i++) l=tbits[in[i]?ctz16(in[i]):16]++,s+=l; return (s+7)/8; } +unsigned histt32(uint32_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) tbits[i]=0; for(i = 0; i < n; i++) l=tbits[in[i]?ctz32(in[i]):32]++,s+=l; return (s+7)/8; } +unsigned histt64(uint64_t *in, unsigned n) { unsigned i,l; uint64_t s=0; for(i = 0; i < 65; i++) tbits[i]=0; for(i = 0; i < n; i++) l=tbits[in[i]?ctz64(in[i]):64]++,s+=l; return (s+7)/8; } + +//----------------------------- Convert iso-8601 and similar formats to timestamp ------------------------- +// Date separator : '.'. '/' or '-' +// Hour separator : ':' +// Fraction sep.: '.' or ',' +// examples: "2020" "20211203" "20211022 11:09:45.1234", +uint64_t strtots(char *p, char **pq, int type) { // string to timestamp + struct tm tm; + uint64_t u; + char *s=p; + int frac = 0,c; + + memset(&tm, 0, sizeof(tm)); tm.tm_mday = 1; + while(!isdigit(*p)) p++; + u = strtoull(p, &p, 10); // first number + + if( u <= 99) u += 2000; // year "yy": 00-99 -> 2000-2099 + else if(u >= 19710101 && u < 20381212) { // date: "yyyymmdd" + tm.tm_year = u/10000; + tm.tm_mon = (u%10000)/100; if(!tm.tm_mon || tm.tm_mon > 12) goto a; tm.tm_mon--; + tm.tm_mday = u%10; if(!tm.tm_mday || tm.tm_mday > 31) goto a; + goto h; + } else if(u < 1971 || u > 2099) goto a; // invalid + tm.tm_year = u; // year "yyyy" + c = *p; // month,day: "mm.dd", "mm-dd", "mm/dd" + if(c != '.' && c != '-' && c != '/') goto b; tm.tm_mon = strtoul(p+1, &p, 10); if(!tm.tm_mon || tm.tm_mon > 12) goto a; tm.tm_mon--; + if(c != '.' && c != '-' && c != '/') goto b; tm.tm_mday = strtoul(p+1, &p, 10); if(!tm.tm_mday || tm.tm_mday > 31) goto a; + if(c != '.' && c != '-' && c != '/') goto b; h:tm.tm_hour = strtoul(p+1, &p, 10); + if(tm.tm_hour <= 24 && *p == ':') { // time ":hh:mm:ss.frac", ":hh:mm:ss,frac" + tm.tm_min = strtoul(p+1, &p, 10); if(tm.tm_min > 60) tm.tm_hour = tm.tm_min = 0; + tm.tm_sec = strtoul(p+1, &p, 10); if(tm.tm_sec > 60) tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + if(type > 0 && (*p == '.' || *p == ',')) { frac = strtoul(p+1, &p, 10); if((c=p-(p+1)) > 6) frac /= 1000000;else if(c > 3) frac /= 1000; } + } else tm.tm_hour = 0; + b:u = mktime(&tm); + u = u * 1000 + frac; // milliseconds + a:*pq = p; //if(verbose >= 9) printf("[%d-%d-%d %.2d:%.2d:%.2d.%d]\n", tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, frac, u);exit(0); + return u; +} + +//----------------------------- Zipfian + Timestamps generator -------------------------------------------------------- +static double a = 1.5; + +void stprint(char *s, unsigned *xbits) { + int i; + uint64_t t = 0; + for(i = 0; i <= 64; i++) + t += xbits[i]; + printf("%s bits histogram:",s); + if(!t) { printf("ALL zero\n"); return; } + printf("\n"); + for(i = 0; i <= 64; i++) + if(xbits[i]) { + double f = (double)xbits[i]*100/(double)t; + unsigned u = round(f); + printf("%.2d:", i); for(int j=0; j < u; j++) printf("#"); + if (f > 10) printf(" %.0f%% ", f); + else if(f > 0.1) printf(" %.1f%% ", f); + else if(f > 0.01) printf(" %.2f%% ", f); + else if(f > 0.001) printf(" %.3f%% ", f); + else if(f > 0.0001) printf(" %.4f%% ", f); + else if(f > 0.00001) printf(" %.5f%% ", f); + else printf(" %.6f%% ", f); + printf("\n"); + } +} + +int dcmp(double *a, double *b) { + if(*a < *b) return -1; + if(*a > *b) return 1; + return 0; +} + +void zipu8(uint8_t *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + double prob, cum, *zmap; + x2 = x2>0xffu?0xffu:x2; if(x1 > x2) x1 = x2; + unsigned m = x2 - x1 + 1; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; if(a[i]>x2) a[i]=x2; + } + free(zmap); +} + +void zipu16(uint16_t *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + double prob, cum, *zmap; + x2 = x2>0xffffu?0xffffu:x2; if(x1 > x2) x1 = x2; + unsigned m = x2 - x1 + 1; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +void zipu32(unsigned *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + double prob, cum, *zmap; + if(x1 > x2) x1 = x2; + unsigned m = x2 - x1 + 1; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +void zipf32(float *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + double prob, cum, *zmap; + if(x1 > x2) x1 = x2; + unsigned m = x2 - x1 + 1; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +void zipu64(uint64_t *a, unsigned n, double alpha, uint64_t x1, uint64_t x2) { + int i; + double prob, cum, *zmap; + if(x1 > x2) x1 = x2; + unsigned m = x2 - x1 + 1; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +void zipf64(double *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + unsigned m = x2 - x1 + 1; + double prob, cum, *zmap; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +void tms64(uint64_t *a, unsigned n, unsigned x1, unsigned x2, double z) { // generator for timestamps + srand48(1); + double freq = drand48()*0.5 + 0.1, amp = (drand48()*z + 0.5); + int i; + for(i = 0; i < n; i++) { + double x = x1 + sin(i * freq) * amp; + a[i] = x>x2?x2:x; + } +} + +#define OVD (10*MB) +static unsigned rm = 0, rx = 255; + +unsigned datagen(unsigned char *in, unsigned n, int isize, double be_mindelta) { + unsigned char *ip; printf("zipf alpha=%.2f range[%u..%u].n=%u\n ", a, rm, rx, n); + int mindelta = be_mindelta,i; //in = malloc(n*isize+OVD); if(!in) die("malloc err=%u", n*isize); + switch(isize) { + case 1: zipu8((uint8_t *)in, n, a, rm, rx); //{ int i; for(i = 0; i < n; i++) in[i] = i; } // + for(i = 1; i <= n; i++) xbits[bsr32(ctou8(in+i))]++; + if(mindelta == 0 || mindelta == 1) { + uint8_t *ip = (uint8_t *)in, v; stprint("delta", xbits); + for(ip[0]=0,v = 1; v < n; v++) { + ip[v] += ip[v-1] + mindelta; if(ip[v]>=(1u<<8)) die("overflow generating sorted array %d\n", ip[v]); + } + } else stprint("",xbits); + break; + case 2: zipu16((unsigned short *)in, n, a, rm, rx); //{ int i; for(i = 0; i < n; i++) in[i] = i; } // + for(i = 1; i <= n; i++) xbits[bsr32(ctou16(in+i*2))]++; + if(mindelta == 0 || mindelta == 1) { + unsigned short *ip = (unsigned short *)in, v; stprint("delta", xbits); + for(ip[0]=0,v = 1; v < n; v++) { + ip[v] += ip[v-1] + mindelta; if(ip[v]>=(1u<<16)) die("overflow generating sorted array %d\n", ip[v]); + } + } else stprint("",xbits); + break; + case 4: zipu32((unsigned *)in, n, a, rm, rx); //{ int i; for(i = 0; i < n; i++) in[i] = i; } // + for(i = 1; i <= n; i++) xbits[bsr32(ctou32(in+i*4))]++; + if(mindelta == 0 || mindelta == 1) { + unsigned *ip = (unsigned *)in, v; stprint(mindelta?"delta=1":"delta=0", xbits); + for(ip[0]=0,v = 1; v < n; v++) { + ip[v] += ip[v-1] + mindelta; if(ip[v]>=(1u<<31)) die("overflow generating sorted array %d\n", ip[v]); + } + } else stprint("",xbits); + break; + case 8: zipu64((uint64_t *)in, n, a, rm, rx); //{ int i; for(i = 0; i < n; i++) in[i] = i; } // + for(i = 1; i <= n; i++) xbits[bsr64(ctou64(in+i*8))]++; + if(mindelta == 0 || mindelta == 1) { + uint64_t *ip = (uint64_t *)in, v; stprint("delta", xbits); + for(ip[0]=0,v = 1; v < n; v++) { + ip[v] += ip[v-1] + mindelta; if(ip[v]>=(1u<<31)) die("overflow generating sorted array %lld\n", ip[v]); + } + } else stprint("",xbits); + break; + case -4: zipf32((float *)in, n, a, rm, rx); + stprint("", xbits); + break; + case -8: zipf64((double *)in, n, a, rm, rx); + stprint("", xbits); + break; + } + return n*abs(isize); +} + +// 0 1 2 3 4 5 6 7, 8 9 10 11 12 13 14 +enum { T_0, T_UINT8, T_UINT16, T_UINT24, T_UINT32, T_UINT40, T_UINT48, T_UINT56, T_UINT64, T_FLOAT, T_DOUBLE, T_CHAR, T_TXT, T_TIM32, T_TIM64, T_TST }; + +#define IPUSH(in,n,isize, nmax,u) { \ + if(n >= nmax) { nmax = nmax?(nmax << 1):(1<<20);\ + in = realloc(in, nmax*isize+OVD); if(!in) die("malloc err=%u", nmax); }\ + ctou64(in+n*isize) = u; n++;\ +} + +int mdelta; +char *keysep; + +unsigned befgen(unsigned char **_in, unsigned n, int fmt, int isize, FILE *fi, int kid, int skiph, int decs, int divs, int mdelta) { + unsigned char *in = *_in,*ip; + unsigned nmax = 0, ovf=0; + #define LSIZE (1024*16) + char s[LSIZE+1]; + double pre; + + n = 0; + while(skiph-- > 0) { + fgets(s, LSIZE, fi); if(verbose>=5 && n < 100 ||verbose>5) printf("skip first line\n"); + } + if(decs) { + pre = decs?pow(10.0f,(float)decs):1; + pre /= divs; + } else pre = 1; + switch(fmt) { + case T_TXT: + case T_TIM32: + case T_TIM64: if(verbose>1) printf("reading text lines. pre=%.2f, col=%d, sep=%s\n", pre, kid, keysep?keysep:""); + while(fgets(s, LSIZE, fi)) { + unsigned char *p = s,*q; + int k = 0, keyid = 1, c; + s[strlen(s) - 1] = 0; + q = p; + if(kid > 1) + do { + p = q; + if(keysep && strchr(keysep,*q)) keyid++; + q++; + } while(*q && keyid != kid); + if(fmt == T_TIM32 || fmt == T_TIM64) { + while(!isdigit(*p)) p++; + uint64_t u = strtots(p, &q, fmt == T_TIM64?1:0); + if(fmt == T_TIM32) u /= 1000; + a: IPUSH(in,n,isize,nmax,u); c=*q; *q=0; if(verbose>=5 && n < 100 || verbose>=9) printf("\'%s\'->%llu ", p, u); *q = c; + } else if(isize > 0) { + while(!isdigit(*p) && *p != '-' && *p != '+') p++; + uint64_t u = strtoll(p, &q, 10)*pre - mdelta; + if(*q == '.') + u = pre>1.0?round(strtod(p, &q)*pre):strtod(p, &q) - mdelta; + switch(isize) { + case 1: if(u > 0xffu) ovf++; break; + case 2: if(u > 0xffffu) ovf++; break; + case 4: if(u > 0xffffffffu) ovf++; break; + } + IPUSH(in,n,isize,nmax,u); c=*q; *q=0; if(verbose>=5 && n < 100 || verbose>=9) printf("\'%s\'->%lld ", p, u); *q = c; + } else { + while(*p && !isdigit(*p) && *p != '-' && *p != '.' && *p != '+') { if(keysep && strchr(keysep,*p)) keyid++; p++; } + double d = strtod(p, &q) - mdelta; + uint64_t u; + memcpy(&u,&d,sizeof(u)); + IPUSH(in,n,-isize,nmax,u); if(verbose>=5 && n < 100 || verbose>=9) { c=*q; *q=0; double d; memcpy(&d,&u,sizeof(d)); printf("\'%s\'->%f ", p, d); *q = c; } + } + } + break; + case T_CHAR: if(verbose>1) printf("reading char file. pre=%.2f\n", pre); + for(;;) { + char *p = s,*q; + int c; + if(isize > 0) { + int64_t u; + while((c = getc(fi)) >= '0' && c <= '9' || c == '-' || c == '+') + if(p - s < LSIZE) *p++ = c; + if(c == '.') { + *p++ = c; + while((c = getc(fi)) >= '0' && c <= '9' || c == '-' || c == '+' || c == 'e' || c == 'E') + if(p - s < LSIZE) *p++ = c; + *p = 0; + u = pre>1.0?round(strtod(s, &q)*pre):strtod(s, &q) - mdelta; + } else { + *p = 0; + u = strtoll(s, &p, 10) - mdelta; + } + IPUSH(in,n,isize,nmax,u); if(verbose>=5 && n < 100 || verbose>=9) printf("%s->%lld ", s, (int64_t)u); + } else { + while((c = getc(fi)) >= '0' && c <= '9' || c == '-') + if(p - s < LSIZE) *p++ = c; + if((*p++ = c) == '.') + while((c = getc(fi)) >= '0' && c <= '9') + if(p - s < LSIZE) *p++ = c; + *p = 0; + double d = strtod(s, &p) - mdelta; + uint64_t u; + memcpy(&u,&d,sizeof(u)); if(verbose>=5 && n < 100 || verbose>=9) { double d; memcpy(&d,&u,sizeof(u)); printf("\'%s\'->%e ", s, d); } + IPUSH(in,n,-isize,nmax,u); + } + if(c == EOF) break; + } + break; + default: die("unknown data format %d\n", fmt); + } + if(verbose>=5) printf("\n"); + *_in = in; + if(ovf) printf("number of items truncated=%d\n", ovf); + return n*abs(isize); +} + +//-------------------------------------------- memcheck : buffer compare for equality --------------------------------------------------------------- +static int mcpy=1, cmp=2; + +#define CBUF(_n_) (((size_t)(_n_))*5/3+1024/*1024*/) +int memcheck(unsigned char *in, unsigned n, unsigned char *cpy) { + int i; + if(cmp <= 1) return 0; + for(i = 0; i < n; i++) + if(in[i] != cpy[i]) { + if(cmp > 3) abort(); // crash (AFL) fuzzing + printf("ERROR at %d:in=%x,%x,%x,%x dec=%x,%x,%x,%x cmp=%d\n", i, in[i], in[i+1], in[i+2], in[i+3], cpy[i],cpy[i+1],cpy[i+2],cpy[i+3], cmp); + if(cmp > 2) exit(EXIT_FAILURE); + return i+1; + } + return 0; +} + +int memcheck32(unsigned *in, unsigned n, unsigned *cpy) { + int i; + if(cmp <= 1) return 0; + for(i = 0; i < n; i++) + if(in[i] != cpy[i]) { + if(cmp > 3) abort(); // crash (AFL) fuzzing + printf("ERROR at %d:in=%x,%x,%x,%x dec=%x,%x,%x,%x cmp=%d\n", i, in[i], in[i+1], in[i+2], in[i+3], cpy[i],cpy[i+1],cpy[i+2],cpy[i+3], cmp); + if(cmp > 2) exit(EXIT_FAILURE); + return i+1; + } + return 0; +} + +void libmemcpy(unsigned char *dst, unsigned char *src, int len) { + void *(*memcpy_ptr)(void *, const void *, size_t) = memcpy; + if (time(NULL) == 1) + memcpy_ptr = NULL; + memcpy_ptr(dst, src, len); +} + +//---------------------------------------- IcApp: Benchmark -------------------------------------------------------------------------- +#include "bitpack.h" +#include "vp4.h" +#include "vint.h" +#include "fp.h" +#include "eliasfano.h" +#include "vsimple.h" +#include "transpose.h" +#include "trle.h" +//#include "bic.h" + + #ifdef STREAMVBYTE +#include "streamvbyte/include/streamvbyte.h" +#include "streamvbyte/include/streamvbytedelta.h" +static size_t streamvbyte_zzag_encode(const uint32_t *in, uint32_t length, uint8_t *out, uint32_t prev, uint8_t *tmp) { + zigzag_delta_encode(in, tmp, length, prev); + return streamvbyte_encode(tmp, length, out); +} +static size_t streamvbyte_zzag_decode(const uint8_t *in, uint32_t *out, uint32_t length, uint32_t prev, uint8_t *tmp) { + streamvbyte_decode(in, tmp, length); + zigzag_delta_decode(tmp, out, length, prev); + return length; +} + #endif + + #ifdef MASKEDVBYTE +#undef VARINTDECODE_H_ +#include "ext/fastpfor.h" +#include "MaskedVByte/include/varintencode.h" + #undef VARINTDECODE_H_ +#include "MaskedVByte/include/varintdecode.h" + #endif + + #ifdef BITSHUFFLE +#include "bitshuffle/src/bitshuffle.h" + #ifndef LZ4 +#include "bitshuffle/lz4/lz4.h" + #endif + #endif + + #ifdef BLOSC +#include "c-blosc2/blosc/shuffle.h" +#include "c-blosc2/blosc/blosc2.h" + #endif + + #ifdef VBZ +#define bool int +#include "vbz_compression/vbz/vbz.h" + #endif + + #ifdef VTENC +#include "VTEnc/vtenc.h" + #endif + + +void pr(unsigned l, unsigned n) { + double r = (double)l*100.0/n; + if(r>0.1) printf("%10u %6.2f%% ", l, r); + else if(r>0.01) printf("%10u %7.3f%% ", l, r); + else printf("%10u %8.4f%% ", l, r); fflush(stdout); } + +#define CPYR(in,n,esize,out) memcpy(out+((n)&(~(esize-1))),in+((n)&(~(esize-1))),(n)&(esize-1)) //, out+((n)&(8*esize-1)) +/*unsigned char *p4menc32(uint32_t *in, unsigned n, unsigned char *out, uint32_t start, unsigned char *tmp) { + uint32_t x, mdelta,*pa = (unsigned *)tmp; + bitfm32(in, n, &x); // determine minimum value + mdelta = bitdi32(in, n, x); if(mdelta>(1<<27)) mdelta=1<<27; // determine minimum delta + bitdienc32(in, n, pa, x, mdelta); // delta transform + mdelta = mdelta<<5|(x&31); x>>=5; vbxput32(out, x); vbput32(out, mdelta); + return p4nenc32(pa, n, out); +}*/ + +#if 0 //def __AVX2__ +void ictste32(uint32_t *in, size_t _n, uint32_t *out) { uint32_t *ip,*op,n=_n/4; + for(ip = in,op=out; ip != in+(n&~(8-1)); ip += 8, op += 8) { + __m256i vi = _mm256_loadu_si256((__m256i *)ip); + vi = mm256_zzage_epi32(vi); + _mm256_storeu_si256((__m256i *)op, vi); + } +} + +void ictstd32(uint32_t *in, size_t _n, uint32_t *out) { uint32_t *ip,*op,n=_n/4; + for(ip = in,op=out; ip != in+(n&~(8-1)); ip += 8, op += 8) { + __m256i vi = _mm256_loadu_si256((__m256i *)ip); + vi = mm256_zzagd_epi32(vi); + _mm256_storeu_si256((__m256i *)op,vi); + } +} +#endif + +//------------------ TurboVSsimple zigzag------------------------------------------ +unsigned char *vszenc8( uint8_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitzenc8( in, n, tmp, 0, 0); return vsenc8( tmp, n, out); } +unsigned char *vszenc16(uint16_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitzenc16(in, n, tmp, 0, 0); return vsenc16(tmp, n, out); } +unsigned char *vszenc32(uint32_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitzenc32(in, n, tmp, 0, 0); return vsenc32(tmp, n, out); } +unsigned char *vszenc64(uint64_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitzenc64(in, n, tmp, 0, 0); return vsenc64(tmp, n, out); } + +unsigned char *vszdec8( unsigned char *in, unsigned n, unsigned char *out) { unsigned char *p = vsdec8( in,n,out); bitzdec8( out, n, 0); return p; } +unsigned char *vszdec16(unsigned char *in, unsigned n, unsigned char *out) { unsigned char *p = vsdec16(in,n,out); bitzdec16(out, n, 0); return p; } +unsigned char *vszdec32(unsigned char *in, unsigned n, unsigned char *out) { unsigned char *p = vsdec32(in,n,out); bitzdec32(out, n, 0); return p; } +unsigned char *vszdec64(unsigned char *in, unsigned n, unsigned char *out) { unsigned char *p = vsdec64(in,n,out); bitzdec64(out, n, 0); return p; } + +//------------------ TurboRLE (Run Length Encoding) + zigzag/xor ------------------------- +#define RLE8 0xdau +#define RLE16 0xdadau +#define RLE32 0xdadadadau +#define RLE64 0xdadadadadadadadaull +unsigned trlezc( uint8_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitzenc8(in, n, tmp, 0, 0); unsigned rc = trlec(tmp, n, out); if(rc >=n) { rc = n; memcpy(out,in,n); } return rc; } +unsigned trlezd(unsigned char *in, unsigned inlen, uint8_t *out, unsigned n) { if(inlen >= n) { memcpy(out,in,n); return inlen; } trled(in, inlen, out, n); bitzdec8(out, n, 0); return n; } + +unsigned trlexc( uint8_t *in, unsigned n, unsigned char *out, unsigned char *tmp) { bitxenc8(in, n, tmp, 0); unsigned rc = trlec(tmp, n, out); if(rc >=n) { rc = n; memcpy(out,in,n); } return rc; } +unsigned trlexd(unsigned char *in, unsigned inlen, uint8_t *out, unsigned n) { if(inlen >= n) { memcpy(out,in,n); return inlen; } trled(in, inlen, out, n); bitxdec8(out, n, 0); return n; } + +unsigned srlezc8( uint8_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint8_t e) { bitzenc8( in, n/( 8/8), tmp, 0, 0); return srlec8( tmp, n, out, e); } +unsigned srlezc16(uint16_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint16_t e) { bitzenc16(in, n/(16/8), tmp, 0, 0); return srlec16(tmp, n, out, e); } +unsigned srlezc32(uint32_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint32_t e) { bitzenc32(in, n/(32/8), tmp, 0, 0); return srlec32(tmp, n, out, e); } +unsigned srlezc64(uint64_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint64_t e) { bitzenc64(in, n/(64/8), tmp, 0, 0); return srlec64(tmp, n, out, e); } + +unsigned srlezd8( unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint8_t e) { srled8(in,inlen,out, n, e); bitzdec8( out, n/(8/8), 0); return n; } +unsigned srlezd16(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint16_t e) { srled16(in,inlen,out, n, e); bitzdec16(out, n/(16/8), 0); return n; } +unsigned srlezd32(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint32_t e) { srled32(in,inlen,out, n, e); bitzdec32(out, n/(32/8), 0); return n; } +unsigned srlezd64(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint64_t e) { srled64(in,inlen,out, n, e); bitzdec64(out, n/(64/8), 0); return n; } + +unsigned srlexc8( uint8_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint8_t e) { bitxenc8( in, n/( 8/8), tmp, 0); return srlec8( tmp, n, out, e); } +unsigned srlexc16(uint16_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint16_t e) { bitxenc16(in, n/(16/8), tmp, 0); return srlec16(tmp, n, out, e); } +unsigned srlexc32(uint32_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint32_t e) { bitxenc32(in, n/(32/8), tmp, 0); return srlec32(tmp, n, out, e); } +unsigned srlexc64(uint64_t *in, unsigned n, unsigned char *out, unsigned char *tmp, uint64_t e) { bitxenc64(in, n/(64/8), tmp, 0); return srlec64(tmp, n, out, e); } + +unsigned srlexd8( unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint8_t e) { srled8(in,inlen,out, n, e); bitxdec8( out, n/(8/8), 0); return n; } +unsigned srlexd16(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint16_t e) { srled16(in,inlen,out, n, e); bitxdec16(out, n/(16/8), 0); return n; } +unsigned srlexd32(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint32_t e) { srled32(in,inlen,out, n, e); bitxdec32(out, n/(32/8), 0); return n; } +unsigned srlexd64(unsigned char *in, unsigned inlen, unsigned char *out, unsigned n, uint64_t e) { srled64(in,inlen,out, n, e); bitxdec64(out, n/(64/8), 0); return n; } + +void bitxenc(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + switch(esize) { + case 1 : bitxenc8( in, n/1, out, 0); break; + case 2 : bitxenc16(in, n/2, out, 0); break; + case 4 : bitxenc32(in, n/4, out, 0); break; + case 8 : bitxenc64(in, n/8, out, 0); break; + } +} + +void bitxdec(unsigned char *in, unsigned n, unsigned esize) { + switch(esize) { + case 1: bitxdec8( in, n/1, 0);break; + case 2: bitxdec16(in, n/2, 0);break; + case 4: bitxdec32(in, n/4, 0);break; + case 8: bitxdec64(in, n/8, 0);break; + } +} + +void bitzenc(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + switch(esize) { + case 1 : bitzenc8( in, n/1, out, 0, 0); break; + case 2 : bitzenc16(in, n/2, out, 0, 0); break; + case 4 : bitzenc32(in, n/4, out, 0, 0); break; + case 8 : bitzenc64(in, n/8, out, 0, 0); break; + } +} + +void bitzdec(unsigned char *in, unsigned n, unsigned esize) { + switch(esize) { + case 1: bitzdec8( in, n/1, 0);break; + case 2: bitzdec16(in, n/2, 0);break; + case 4: bitzdec32(in, n/4, 0);break; + case 8: bitzdec64(in, n/8, 0);break; + } +} + +#if 0 +void bitzzenc(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + switch(esize) { + case 1 : bitzzenc8( in, n/1, out, 0, 0); break; + case 2 : bitzzenc16(in, n/2, out, 0, 0); break; + case 4 : bitzzenc32(in, n/4, out, 0, 0); break; + case 8 : bitzzenc64(in, n/8, out, 0, 0); break; + } +} + +void bitzzdec(unsigned char *in, unsigned n, unsigned esize) { + switch(esize) { + case 1: bitzzdec8( in, n/1, 0);break; + case 2: bitzzdec16(in, n/2, 0);break; + case 4: bitzzdec32(in, n/4, 0);break; + case 8: bitzzdec64(in, n/8, 0);break; + } +} +#endif + + #ifdef BITSHUFFLE //--------------------------bit transpose ---------------------------------------------------------------------- +static void bitshuffle(uint8_t *in, unsigned n, uint8_t *out, unsigned esize) { + bshuf_bitshuffle( in, out, n/esize, esize, 0); memcpy((char *)out+(n&(~(8*esize-1))), (char *)in+(n&(~(8*esize-1))), n&(8*esize-1)); +} +static void bitunshuffle(uint8_t *in, unsigned n, uint8_t *out, unsigned esize) { + bshuf_bitunshuffle(in, out, n/esize, esize, 0); memcpy((char *)out+(n&(~(8*esize-1))), (char *)in+(n&(~(8*esize-1))), n&(8*esize-1)); +} + #endif + +//----------------------- lz -------------------------------------------------------------------------------------- +unsigned codid = 0, codlev = 1, dsize = 0; +unsigned char codprm[256]; + +#include "lz.c" + +//---------------------SPDP (https://userweb.cs.txstate.edu/~burtscher/research/SPDPcompressor/) ----------------------- +#ifdef SPDP +#define NMAIN +#include "ext/SPDP_10.c" +#define SPDPSIZE (1<<23) +char ibuf[SPDPSIZE*2]; + +unsigned spdpenc(unsigned char *in, size_t n, unsigned char *out, unsigned bsize, int codlev) { + unsigned char *op = out,*ip; + for(ip = in, in += n; ip < in;) { + unsigned iplen = in - ip,l; + if(iplen > bsize) iplen = bsize; + memcpy(ibuf,ip,iplen); // SPDP is overwriting the input, copy to a tmp buffer + l = spdp_compress(codlev, iplen, ibuf, op+4); ctou32(op)=l; op+=4+l; //AC(l <= bsize,"Compress Fatal=%d>%d\n", l, bsize); + ip += iplen; + } + return op - out; +} + +size_t spdpdec(unsigned char *in, size_t n, unsigned char *out, unsigned bsize, int codlev) {\ + unsigned char *ip = in,*op; + for(op = out,out+=n; op < out;) { unsigned oplen = out - op,l; + if(oplen > bsize) oplen = bsize; + l = ctou32(ip); + ip += 4; + memcpy(ibuf,ip,l); + spdp_decompress(codlev, l, ibuf, op); ip += l; + op += oplen; + } + return ip - in; +} +#endif + +//------------------------------------- Benchmark ------------------------------------------------------------------- + +#define ID_MEMCPY 120 +unsigned char *bestr(unsigned id, unsigned b, unsigned char *s, char *prms, int prmi) { + static char *fmt[] = { + "%3d:000 ", + "%3d:p4nenc%d TurboPFor ", //1 + "%3d:p4nenc128v%d TurboPForV ", + "%3d:p4nenc256v%d TurboPFor256 ", + "%3d:p4ndenc%d TurboPFor delta ", + "%3d:p4ndenc128v%d TurboPForV delta ", + "%3d:p4ndenc256v%d TurboPFor256 delta ", + "%3d:p4nd1enc%d TurboPFor delta1 ", + "%3d:p4nd1enc128v%d TurboPForV delta1 ", + "%3d:p4nd1enc256v%d TurboPFor256 delta1 ", + + "%3d:p4nzenc%d TurboPFor zigzag ", //10 + "%3d:p4nzenc128v%d TurboPForV zigzag ", + "%3d:p4nzenc256v%d TurboPFor256 zigzag ", + "%3d:p4nzzenc128v%d TurboPFor zzag/delta", + "%3d:bics32 Interpolative Cod. S", + "%3d:bic32 Interpolative Cod. L", + "%3d:bicm32 Interpolative Cod. M", + "%3d:17 ", + "%3d:18 ", + "%3d:19 ", + + "%3d:bitnpack%d TurboPack ", //20 + "%3d:bitnpack128v%d TurboPackV ", + "%3d:bitnpack256v%d TurboPack256 ", + "%3d:bitndpack%d TurboPack delta ", + "%3d:bitndpack128v%d TurboPackV delta ", + "%3d:bitndpack256v%d TurboPack256 delta ", + "%3d:bitnd1pack%d TurboPack delta1 ", + "%3d:bitnd1pack128v%d TurboPackV delta1 ", + "%3d:bitnd1pack256v%d TurboPack256 delta1 ", + "%3d:bitnzpack%d TurboPack zigzag ", + + "%3d:bitnzpack128v%d TurboPackV zigzag ", //30 + "%3d:bitnzpack256v%d TurboPack256 zigzag ", + "%3d:bitnfpack%d TurboPack FOR ", + "%3d:bitnfpack128v%d TurboPackV FOR ", + "%3d:bitnfpack256v%d TurboPack256 FOR ", + "%3d:bitns1pack128v32 TurboPack256 delt4_1", + "%3d:36 ", + "%3d:37 ", + "%3d:vsenc%d TurboVSimple ", + "%3d:vszenc%d TurboVSimple zigzag ", + + "%3d:vbenc%d TurboVByte scalar ", //40 + "%3d:vbzenc%d TurboVByte zigzag ", + "%3d:vbdenc%d TurboVByte delta ", + "%3d:vbd1enc%d TurboVByte delta1 ", + "%3d:vbddenc%d TurboVByte zzag delt", + "%3d:v8enc%d TurboByte SIMD ", + "%3d:v8denc%d TurboByte delta ", + "%3d:v8d1enc%d TurboByte delta1 ", + "%3d:v8xenc%d TurboByte xor ", + "%3d:v8zenc%d TurboByte zigzag ", + + "%3d:v8nenc128v%d TurboByte+TbPackV ", //50 //TurboByte Hybrid + "%3d:v8nzenc128v%d TByte+TPackV zigzag ", + "%3d:v8ndenc128v%d TByte+TPackV delta ", + "%3d:v8nd1enc128v%d TByte+TPackV delta1 ", + "%3d:54 ", + "%3d:v8nenc256v%d TurboByte+TbPackV ", + "%3d:v8nzenc256v%d TByte+TPackV zigzag ", + "%3d:v8ndenc256v%d TByte+TPackV delta ", + "%3d:v8nd1enc256v%d TByte+TPackV delta1 ", + "%3d:59 ", + + "%3d:bvzzenc%d bitio zigzag/delta ", //60 + "%3d:bvzenc%d bitio zigzag ", + "%3d:fpgenc%d bitio TurboGorilla ", + "%3d:63 ", + "%3d:64 ", //"fphenc%d slope predictor", + "%3d:fpxenc%d TurboFloat XOR ", //bvzaenc%d moving average pred.", + "%3d:fpfcmenc%d TurboFloat FCM ", + "%3d:fpdfcmenc%d TurboFloat DFCM ", + "%3d:fp2dfcmenc%d TurboFloat DFCM 2D ", + "%3d:69 ", + + "%3d:trle TurboRLE ", //70 + "%3d:trlex TurboRLE xor ", + "%3d:trlez TurboRLE zigzag ", + "%3d:srle%d TurboRLE ESC ", + "%3d:srlex%d TurboRLE ESC xor ", + "%3d:srlez%d TurboRLE ESC zigzag ", + "%3d:76 ", + "%3d:77 ", + "%3d:78 ", + "%3d:79 ", + + "%3d:Lz %s,%d ", //80 + "%3d:Lztp Byte Transpose+%s,%d ", + "%3d:Lztpx Byte Transpose+xor+%s,%d ", + "%3d:Lztpz Byte Transpose+zzag+%s,%d ", + "%3d:Lztp4 Nibble Transpose+%s,%d ", + "%3d:Lztp4x Nibble Transpose+xor+%s,%d ", + "%3d:Lztp4z Nibble Transpose+zigzag+%s,%d ", + "%3d:Lztp1 Bit Bitshuffle+%s,%d ", + "%3d:Lztp1x Bit Bitshuffle+xor+%s,%d ", + "%3d:Lztp1z Bit Bitshuffle+zigzag+%s,%d", + + "%3d:lztprle Transpose+rle+%s,%d ", //90 + "%3d:lztprlex Transpose+xor+rle+%s,%d", + "%3d:lztprlez Transpose+zzg+rle+%s,%d", + "%3d:lzv8enc TurboByte+%s,%d ", + "%3d:lzv8xenc TurboByte+xor+%s,%d ", + "%3d:lzv8zenc TurboByte+zzag+%s,%d ", + "%3d:96 ", + "%3d:97 ", + "%3d:98 ", + "%3d:99 ", + + "%3d:LztpD2byte 2D Transpose+%s,%d ", //100 + "%3d:LztpxD2byte 2D Transpose+xor+%s,%d ", + "%3d:LztpzD2byte 2D Transpose+zzag+%s,%d", + "%3d:LztpD3byte 3D Transpose+%s,%d ", + "%3d:LztpxD3byte 3D Transpose+xor+%s,%d ", + "%3d:LztpzD3byte 3D Transpose+zzag+%s,%d", + "%3d:LztpD4byte 4D Transpose+%s,%d ", + "%3d:LztpxD4byte 4D Transpose+xor+%s,%d ", + "%3d:LztpzD4byte 4D Transpose+zzag+%s,%d", + "%3d:SPDP SPDP Floating Point ", + + "%3d:streamvbyte StreamVByte SIMD ", //110 + "%3d:streamvbyte delt StreamVByte delta ", + "%3d:streamvbyte zzag StreamVByte zigzag ", + "%3d:maskeydvbyte MasedVByte SIMD ", + "%3d:FastPFor FastPFor ", + "%3d:SimdFastPFor FastPFor SIMD ", + "%3d:SimdOptPFor FastPFor SIMD ", + "%3d:tpenc Byte transpose ", + "%3d:tp4enc Nibble transpose ", + "%3d:bitshuffle Bit transpose ", + + "%3d:memcpy memcpy ", //120 + "%3d:vtenc VTEnc lib ", + "%3d:vbz vbz (nanopore) " + }; + #define CID_BEG 76 + #define CID_END 108 + if(id >= CID_BEG && id <= CID_END) + sprintf(s,fmt[id], id, prms, prmi); + else + sprintf(s,fmt[id], id, b, prms, prmi); + return s; +} + +//------------------------ Floating point statistics ------------------------------------------------------------------ +//#define BR(b) (double)(((double)(b)*100.0)/(double)(n*abs(s)*8)) +#define BR(b) (((b)/8)*100.0/(double)(n*esize)) + +void fpstat(unsigned char *in, size_t n, unsigned char *out, int s) { + double imin = DBL_MAX, imax = DBL_MIN, isum = 0, //original data (input) : minimum,maximum,sum + eamin = DBL_MAX, eamax = DBL_MIN, easum = 0, easumsqr = 0, //absolute error : abs(input-output) + ermin = DBL_MAX, ermax = DBL_MIN, ersum = 0, ersumsqr = 0, //relative error : abs(input-output)/abs(input) + osum = 0; //transformed lossy data (output) : sum + unsigned long long xtb = 0, xlb = 0, tb = 0, lb = 0, elb=0, mtb=0; + size_t idn = 0; + unsigned char *ip, *op; + unsigned esize = s<0?-s:s,t; + long long mant = 0,m; + int expo = 0,e; + + for(ip = in, op = out; ip < in+n*esize; ip += esize, op += esize) + switch(s) { + case -4: isum += ctof32(ip); osum += ctof32(op); break; + case -8: isum += ctof64(ip); osum += ctof64(op); break; + case 1: isum += ctou8( ip); osum += ctou8( op); break; + case 2: isum += ctou16(ip); osum += ctou16(op); break; + case 4: isum += ctou32(ip); osum += ctou32(op); break; + case 8: isum += ctou64(ip); osum += ctou64(op); break; + } + double iavg = isum/n, oavg = osum/n, isumpavg = 0, osumpavg = 0, iosumpavg = 0; uint64_t start = 0; + #define EXPO32(u) ((u>>23 & 0xff) - 0x7e ) + #define EXPO64(u) ((u>>52 & 0x7ff) - 0x3fe) + #define MANT32(u) (u & 0x807fffffu) + #define MANT64(u) (u & 0x800fffffffffffffull) + #define U(s) TEMPLATE3(uint, s, _t) u = TEMPLATE2(ctou,s)(op);\ + t = TEMPLATE2(ctz,s)(u); tb += t; if(u) lb += TEMPLATE2(clz,s)(u); AC(t<=s,"Fatal t=%d ", t); \ + start ^= u; t = TEMPLATE2(ctz,s)(start); xtb += t; if(start) xlb += TEMPLATE2(clz,s)(start); start = u + + for(ip = in, op = out; ip < in+n*esize; ip += esize, op += esize) { + double id, od; + switch(s) { + case -4: { id = ctof32(ip); od = ctof32(op); U(32); e = EXPO32(u); expo = clz32(zigzagenc32(e-expo))/*-(32-(32-MANTF32-1))*/; elb+=expo; expo = e; + m = MANT32(u); mant = ctz32( m^mant) ; mtb+=mant; mant = m;//ctz32(zigzagenc32(m-mant)) + } break; + case -8: { id = ctof64(ip); od = ctof64(op); U(64); e = EXPO64(u); expo = clz32(zigzagenc32(e-expo))/*-(32-(64-MANTF64-1))*/; elb+=expo; expo = e; + m = MANT64(u); mant = ctz64( m^mant) ; mtb+=mant; mant = m;//ctz64(zigzagenc64(m-mant)) + } break; + case 1: { id = ctou8( ip); od = ctou8( op); U( 8);} break; + case 2: { id = ctou16(ip); od = ctou16(op); U(16);} break; + case 4: { id = ctou32(ip); od = ctou32(op); U(32);} break; + case 8: { id = ctou64(ip); od = ctou64(op); U(64);} break; + } + + imax = max(id, imax); + imin = min(id, imin); + + double ea = fabs(id - od); eamax = max(eamax,ea); eamin = min(eamin,ea); easum += ea; easumsqr += ea*ea; // absolute error + if(id) { idn++; + double er = ea/fabs(id); ermax = max(ermax,er); ermin = min(ermin,er); ersum += er; ersumsqr += er*er; // relative error + } + isumpavg += (id - iavg)*(id - iavg); + osumpavg += (od - oavg)*(od - oavg); + iosumpavg += (id - iavg)*(od - oavg); //bits += ctz64(ctou64(&od)) - ctz64(ctou64(&id)); + } + double fb = 0; + if(s == -4) fb = (double)elb*100/((double)n*8); + else if(s == -8) fb = (double)elb*100/((double)n*11); + + double mse = easumsqr/n, irange = imax - imin; + //printf("Leading/Trailing bits [%.2f%%,%.2f%%=%.2f%%]. XOR[%.2f%%,%.2f%%=%.2f%%] Zigzag[%.2f%%,%.2f%%=%.2f%%]\n", BR(lb), BR(tb), BR(lb+tb), BR(xlb), BR(xtb), BR(xlb+xtb), BR(elb), BR(mtb), BR(elb+mtb) ); + printf("Range: [%g - %g] = %g\n", imin, imax, irange); + //printf("Min error: Absolute = %.12f, Relative = %f, pointwise relative = %f\n", eamin, eamin/irange, eamax/irange, ermax); + //printf("Avg error: Absolute = %.12f, Relative = %f, pointwise relative = %f\n", easum/idn, (easum/idn)/irange, ersum/idn); + printf("Max error: Absolute = %g, Relative = %g, pointwise relative = %g\n", eamax, eamax/irange, ermax); + printf("Peak Signal-to-Noise Ratio: PSNR = %f\n", 20*log10(irange)-10*log10(mse)); + printf("Normalized Root Mean Square Error: NRMSE = %g\n", sqrt(mse)/irange); + double std1 = sqrt(isumpavg/n), std2 = sqrt(osumpavg/n), ee = iosumpavg/n, acEff = (iosumpavg/n)/sqrt(isumpavg/n)/sqrt(osumpavg/n); + printf("Pearson Correlation Coefficient = %f\n", (iosumpavg/n)/sqrt(isumpavg/n)/sqrt(osumpavg/n)); +} + +//--------------------------------------------------------------------------------------- +#define MINDELTA(_t_, _in_, _n_, _dmin_) {\ + _t_ *_p = (_t_ *)_in_, _i;\ + for(_dmin_ = (_t_)-1, _i = 1; _i < _n_; _i++)\ + if(_p[_i] < _p[_i-1]) { dmin = (_t_)-1; break; }\ + else { _t_ _d = _p[_i] - _p[_i-1]; if(_d < _dmin_) { _dmin_ = _d; /*printf("[%u]", _dmin_);*/} }\ +} + +uint8_t mindelta8( unsigned char *in, unsigned n) { uint8_t dmin; MINDELTA(uint8_t, in, n, dmin); return dmin; } +uint16_t mindelta16(unsigned char *in, unsigned n) { uint16_t dmin; MINDELTA(uint16_t, in, n, dmin); return dmin; } +uint32_t mindelta32(unsigned char *in, unsigned n) { uint32_t dmin; MINDELTA(uint32_t, in, n, dmin); return dmin; } +uint64_t mindelta64(unsigned char *in, unsigned n) { uint64_t dmin; MINDELTA(uint64_t, in, n, dmin); return dmin; } +uint64_t mindelta( unsigned char *in, unsigned n, unsigned siz) { + switch(siz) { + case 1: { uint8_t d = mindelta8( in,n); return d == (uint8_t )-1?(uint64_t)-1:d; } + case 2: { uint16_t d = mindelta16(in,n); return d == (uint16_t)-1?(uint64_t)-1:d; }; + case 4: { uint32_t d = mindelta32(in,n); return d == (uint32_t)-1?(uint64_t)-1:d; }; + case 8: { uint64_t d = mindelta64(in,n); return d == (uint64_t)-1?(uint64_t)-1:d; }; + } + return -2; +} + +//--------------------------------------------------------------------------------------------------------------------------------------------------- +#define NEEDTMP (id == 39 || id == 102 || id == 112 || id>=70 && id <= 99) +unsigned dim1,dim2,dim3,dim4; + +#define USIZE 1 +unsigned bench8(unsigned char *in, unsigned n, unsigned char *out, unsigned char *cpy, int id, char *inname, int codlev) { + unsigned l=0,m = n/(USIZE), rc = 0, ns = CBUF(n); uint8_t dmin = mindelta8(in,m); + uint8_t *p; + char *tmp = NULL; + if(NEEDTMP && !(tmp = (unsigned char*)malloc(ns))) die(stderr, "malloc error\n"); + memrcpy(cpy,in,n); l = 0; + + switch(id) { + case 1: TMBENCH("",l=p4nenc8( in, m, out) ,n); pr(l,n); TMBENCH2(" 1",p4ndec8( out, m, cpy) ,n); break; + + case 4: TMBENCH("",l=p4ndenc8( in, m, out) ,n); pr(l,n); TMBENCH2(" 4",p4nddec8( out, m, cpy) ,n); break; + + case 7: TMBENCH("",l=p4nd1enc8( in, m, out) ,n); pr(l,n); TMBENCH2(" 7",p4nd1dec8( out, m, cpy) ,n); break; + + case 10: TMBENCH("",l=p4nzenc8( in, m, out) ,n); pr(l,n); TMBENCH2(" 10",p4nzdec8( out, m, cpy) ,n); break; + + case 20: TMBENCH("",l=bitnpack8( in, m, out) ,n); pr(l,n); TMBENCH2(" 20",bitnunpack8( out, m, cpy) ,n); break; + + case 23: TMBENCH("",l=bitndpack8( in, m, out) ,n); pr(l,n); TMBENCH2(" 23",bitndunpack8( out, m, cpy) ,n); break; + + case 26: TMBENCH("",l=bitnd1pack8( in, m, out) ,n); pr(l,n); TMBENCH2(" 26",bitnd1unpack8( out, m, cpy) ,n); break; + + case 29: TMBENCH("",l=bitnzpack8( in, m, out) ,n); pr(l,n); TMBENCH2(" 29",bitnzunpack8( out, m, cpy) ,n); break; + + case 32: if(dmin==(uint8_t)-1) goto end; + TMBENCH("",l=bitnfpack8( in, m, out) ,n); pr(l,n); TMBENCH2(" 32",bitnfunpack8( out, m, cpy) ,n); break; + + case 38: TMBENCH("",l=vsenc8( in, m, out)-out,n); pr(l,n); TMBENCH2(" 38",vsdec8( out, m, cpy) ,n); break; // vsimple : variable simple + case 39: TMBENCH("",l=vszenc8( in, m, out,tmp)-out,n); pr(l,n); TMBENCH2(" 39",vszdec8( out, m, cpy) ,n); break; + + //case 40: TMBENCH("",l=vbenc8( in, m, out)-out,n); pr(l,n); TMBENCH2(" 40",vbdec8( out, m, cpy) ,n); break; // TurboVbyte : variable byte + case 41: TMBENCH("",l=vbzenc8( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 41",vbzdec8( out, m, cpy,0) ,n); break; + //case 42: TMBENCH("",l=vbdenc8( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 42",vbddec8( out, m, cpy,0) ,n); break; + //case 43: TMBENCH("",l=vbd1enc8( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 43",vbd1dec8( out, m, cpy,0) ,n); break; + //case 44: TMBENCH("",l=vbddenc8( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 44",vbdddec8( out, m, cpy,0) ,n); break; + + case 60: TMBENCH("",l=bvzzenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 60",bvzzdec8( out, m, cpy,0) ,n); break; // bitio + case 61: TMBENCH("",l=bvzenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 61",bvzdec8( out, m, cpy,0) ,n); break; + case 62: TMBENCH("",l=fpgenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 62",fpgdec8( out, m, cpy,0) ,n); break; + + case 65: TMBENCH("",l=fpxenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 65",fpxdec8( out, m, cpy,0) ,n); break; //Floating point/Integer + case 66: TMBENCH("",l=fpfcmenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 66",fpfcmdec8( out, m, cpy,0) ,n); break; + case 67: TMBENCH("",l=fpdfcmenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 67",fpdfcmdec8( out, m, cpy,0) ,n); break; + case 68: TMBENCH("",l=fp2dfcmenc8( in, m, out,0),n); pr(l,n); TMBENCH2(" 68",fp2dfcmdec8( out, m, cpy,0) ,n); break; + + case 70: TMBENCH("",l=trlec( in, n,out),n); pr(l,n); TMBENCH2(" 70",trled( out,l,cpy, n),n); break; // TurboRLE + case 71: TMBENCH("",l=trlexc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 71",trlexd( out,l,cpy, n),n); break; + case 72: TMBENCH("",l=trlezc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 72",trlezd( out,l,cpy, n),n); break; + case 73: TMBENCH("",l=srlec8( in, n,out,RLE8),n); pr(l,n); TMBENCH2(" 73",srled8( out,l,cpy, n,RLE8),n);break; + case 74: TMBENCH("",l=srlexc8( in, n,out,tmp,RLE8),n); pr(l,n); TMBENCH2(" 74",srlexd8( out,l,cpy, n,RLE8),n);break; + case 75: TMBENCH("",l=srlezc8( in, n,out,tmp,RLE8),n); pr(l,n); TMBENCH2(" 75",srlezd8( out,l,cpy, n,RLE8),n);break; + + #ifdef USE_LZ + case 80: TMBENCH("",l=lzenc( in,n,out,ns,codid,codlev,codprm) ,n); pr(l,n); TMBENCH2(" 80",lzdec(out,l,cpy,n,codid,codlev,codprm),n); break; + case 81: TMBENCH("",l=lztpenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 81",lztpdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 82: TMBENCH("",l=lztpxenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 82",lztpxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 83: TMBENCH("",l=lztpzenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 83",lztpzdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 84: TMBENCH("",l=lztp4enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 84",lztpd4ec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 85: TMBENCH("",l=lztp4xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 85",lztp4xdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 86: TMBENCH("",l=lztp4zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 86",lztp4zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + #ifdef BITSHUFFLE + case 87: TMBENCH("",l=lztp1enc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 87",lztp1dec( out,l,cpy,n,USIZE,tmp), n); break; + case 88: TMBENCH("",l=lztp1xenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 88",lztp1xdec( out,l,cpy,n,USIZE,tmp), n); break; + case 89: TMBENCH("",l=lztp1zenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 89",lztp1zdec( out,l,cpy,n,USIZE,tmp), n); break; + #endif + case 90: TMBENCH("",l=lztprleenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 90",lztprledec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 91: TMBENCH("",l=lztprlexenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 91",lztprlexdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 92: TMBENCH("",l=lztprlezenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 92",lztprlezdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 93: TMBENCH("",l=lzv8enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 93",lzv8dec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 94: TMBENCH("",l=lzv8xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 94",v8lzxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 95: TMBENCH("",l=lzv8zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 95",lzv8zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + + case 100: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2enc( in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("100",lztpd2dec( out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 101: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2xenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("101",lztpd2xdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 102: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2zenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("102",lztpd2zdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + + case 103: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3enc( in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("103",lztpd3dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 104: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3xenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("104",lztpd3xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 105: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3zenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("105",lztpd3zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 106: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4enc( in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("106",lztpd4dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + case 107: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4xenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("107",lztpd4xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n);} break; + case 108: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4zenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("108",lztpd4zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + #endif + + #ifdef CODEC1 + case 109: TMBENCH("",l=spdpenc(in,m*(USIZE),out,SPDPSIZE,codlev),n);pr(l,n); TMBENCH2("109",spdpdec( out, m*(USIZE), cpy,SPDPSIZE,codlev); ,n); break; + #endif + case 117: l = n; TMBENCH("", tpenc( in, n, out,USIZE),n); pr(l,n); TMBENCH2("117", tpdec( out, n,cpy, USIZE),n); break; + case 118: l = n; TMBENCH("", tp4enc(in, n, out,USIZE),n); pr(l,n); TMBENCH2("118", tp4dec(out, n,cpy, USIZE),n); break; + #ifdef BITSHUFFLE + case 119: l = n; TMBENCH("", bitshuffle(in, n, out, USIZE),n); pr(l,n); TMBENCH2("119", bitunshuffle(out, n,cpy, USIZE),n); break; + #endif + case ID_MEMCPY: if(!mcpy) goto end; + TMBENCH( "", libmemcpy(out,in,n) ,n); l=n; pr(l,n); pr(n,n); TMBENCH2("120", libmemcpy( cpy,out,n) ,n); break; + default: goto end; + } + if(l) { + char s[65]; printf("%-35 ", bestr(id, 8, s, codstr(codid), codlev)); + if(cpy) rc = memcheck(in,m*(USIZE),cpy); + if(!rc) + printf("\t%s\n", inname?inname:""); + } + end:if(tmp) free(tmp); + return l; +} + +#undef USIZE +#define USIZE 2 +unsigned bench16(unsigned char *in, unsigned n, unsigned char *out, unsigned char *cpy, int id, char *inname, int codlev) { + unsigned l=0,m = n/(USIZE),rc = 0, d,ns=CBUF(n); uint16_t dmin = mindelta16(in,m); + uint16_t *p; + char *tmp = NULL; + if(NEEDTMP && !(tmp = (unsigned char*)malloc(ns))) die(stderr, "malloc error\n"); + memrcpy(cpy,in,n); l=0; + + switch(id) { + case 1: TMBENCH("",l=p4nenc16( in, m, out) ,n); pr(l,n); TMBENCH2(" 1",p4ndec16( out, m, cpy) ,n); break; + #ifdef SSE + case 2: TMBENCH("",l=p4nenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 2",p4ndec128v16( out, m, cpy) ,n); break; + #endif + case 4: TMBENCH("",l=p4ndenc16( in, m, out) ,n); pr(l,n); TMBENCH2(" 4",p4nddec16( out, m, cpy) ,n); break; + #ifdef SSE + case 5: TMBENCH("",l=p4ndenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 5",p4nddec128v16( out, m, cpy) ,n); break; + #endif + case 7: TMBENCH("",l=p4nd1enc16( in, m, out) ,n); pr(l,n); TMBENCH2(" 7",p4nd1dec16( out, m, cpy) ,n); break; + #ifdef SSE + case 8: TMBENCH("",l=p4nd1enc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 8",p4nd1dec128v16( out, m, cpy) ,n); break; + #endif + case 10: TMBENCH("",l=p4nzenc16( in, m, out) ,n); pr(l,n); TMBENCH2(" 10",p4nzdec16( out, m, cpy) ,n); break; + #ifdef SSE + case 11: TMBENCH("",l=p4nzenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 11",p4nzdec128v16( out, m, cpy) ,n); break; + case 13: TMBENCH("",l=p4nzzenc128v16( in, m, out,0),n); pr(l,n); TMBENCH2(" 13",p4nzzdec128v16( out, m, cpy,0) ,n); break; + #endif + + case 20: TMBENCH("",l=bitnpack16( in, m, out) ,n); pr(l,n); TMBENCH2(" 20",bitnunpack16( out, m, cpy) ,n); break; + #ifdef SSE + case 21: TMBENCH("",l=bitnpack128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 21",bitnunpack128v16( out, m, cpy) ,n); break; + #endif + case 23: TMBENCH("",l=bitndpack16( in, m, out) ,n); pr(l,n); TMBENCH2(" 23",bitndunpack16( out, m, cpy) ,n); break; + #ifdef SSE + case 24: TMBENCH("",l=bitndpack128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 24",bitndunpack128v16( out, m, cpy) ,n); break; + #endif + case 26: TMBENCH("",l=bitnd1pack16( in, m, out) ,n); pr(l,n); TMBENCH2(" 26",bitnd1unpack16( out, m, cpy) ,n); break; + #ifdef SSE + case 27: TMBENCH("",l=bitnd1pack128v16(in, m, out) ,n); pr(l,n); TMBENCH2(" 27",bitnd1unpack128v16(out, m, cpy) ,n); break; + #endif + case 29: TMBENCH("",l=bitnzpack16( in, m, out) ,n); pr(l,n); TMBENCH2(" 29",bitnzunpack16( out, m, cpy) ,n); break; + #ifdef SSE + case 30: TMBENCH("",l=bitnzpack128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 30",bitnzunpack128v16( out, m, cpy) ,n); break; + #endif + case 32: if(dmin==(uint16_t)-1) goto end; + TMBENCH("",l=bitnfpack16( in, m, out) ,n); pr(l,n); TMBENCH2(" 32",bitnfunpack16( out, m, cpy) ,n); break; + #ifdef SSE + case 33: if(dmin==(uint16_t)-1) goto end; + TMBENCH("",l=bitnfpack128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 33",bitnfunpack128v16( out, m, cpy) ,n); break; + + case 35: if(dmin==(uint16_t)-1) goto end; + TMBENCH("",l=bitns1pack128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 35",bitns1unpack128v16( out, m, cpy) ,n); break; + #endif + //case 35: if(dmin==-1 /*|| !dmin*/) goto end; TMBENCH("",l=efanoenc16( in, m, out,0) ,n); pr(l,n); TMBENCH2("efanoenc16 ",efanodec16( out, m, cpy,0) ,n); break; + case 38: TMBENCH("",l=vsenc16( in, m, out)-out,n); pr(l,n); TMBENCH2(" 38",vsdec16( out, m, cpy) ,n); break; // vsimple : variable simple + case 39: TMBENCH("",l=vszenc16( in, m, out,tmp)-out,n); pr(l,n); TMBENCH2(" 39",vszdec16( out, m, cpy) ,n); break; + + case 40: TMBENCH("",l=vbenc16( in, m, out)-out,n); pr(l,n); TMBENCH2(" 40",vbdec16( out, m, cpy) ,n); break; // TurboVbyte : variable byte + case 41: TMBENCH("",l=vbzenc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 41",vbzdec16( out, m, cpy,0) ,n); break; + case 42: TMBENCH("",l=vbdenc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 42",vbddec16( out, m, cpy,0) ,n); break; + case 43: TMBENCH("",l=vbd1enc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 43",vbd1dec16( out, m, cpy,0) ,n); break; + case 44: TMBENCH("",l=vbddenc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 44",vbdddec16( out, m, cpy,0) ,n); break; + case 45: TMBENCH("",l=v8enc16( in, m, out)-out,n); pr(l,n); TMBENCH2(" 45",v8dec16( out, m, cpy) ,n); break; // Turbobyte : Group varint + case 46: TMBENCH("",l=v8denc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 46",v8ddec16( out, m, cpy,0) ,n); break; + case 47: TMBENCH("",l=v8d1enc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 47",v8d1dec16( out, m, cpy,0) ,n); break; + case 48: TMBENCH("",l=v8xenc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 48",v8xdec16( out, m, cpy,0) ,n); break; + case 49: TMBENCH("",l=v8zenc16( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 49",v8zdec16( out, m, cpy,0) ,n); break; + + #ifdef SSE + case 50: TMBENCH("",l=v8nenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 50",v8ndec128v16( out, m, cpy) ,n); break; + case 51: TMBENCH("",l=v8nzenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 51",v8nzdec128v16( out, m, cpy) ,n); break; + case 52: TMBENCH("",l=v8ndenc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 52",v8nddec128v16( out, m, cpy) ,n); break; + case 53: TMBENCH("",l=v8nd1enc128v16( in, m, out) ,n); pr(l,n); TMBENCH2(" 53",v8nd1dec128v16( out, m, cpy) ,n); break; + #endif + case 60: TMBENCH("",l=bvzzenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 60",bvzzdec16( out, m, cpy,0) ,n); break; // bitio + case 61: TMBENCH("",l=bvzenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 61",bvzdec16( out, m, cpy,0) ,n); break; + case 62: TMBENCH("",l=fpgenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 62",fpgdec16( out, m, cpy,0) ,n); break; + + case 65: TMBENCH("",l=fpxenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 65",fpxdec16( out, m, cpy,0) ,n); break; //Floating point/Integer + case 66: TMBENCH("",l=fpfcmenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 66",fpfcmdec16( out, m, cpy,0) ,n); break; + case 67: TMBENCH("",l=fpdfcmenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 67",fpdfcmdec16( out, m, cpy,0) ,n); break; + case 68: TMBENCH("",l=fp2dfcmenc16( in, m, out,0),n); pr(l,n); TMBENCH2(" 68",fp2dfcmdec16( out, m, cpy,0) ,n); break; + + case 70: TMBENCH("",l=trlec( in, n,out),n); pr(l,n); TMBENCH2(" 70",trled( out,l,cpy, n),n); break; // TurboRLE + case 71: TMBENCH("",l=trlexc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 71",trlexd( out,l,cpy, n),n); break; + case 72: TMBENCH("",l=trlezc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 72",trlezd( out,l,cpy, n),n); break; + case 73: TMBENCH("",l=srlec16( in, n,out,RLE16),n); pr(l,n); TMBENCH2(" 73",srled16( out,l,cpy, n,RLE16),n);break; + case 74: TMBENCH("",l=srlexc16( in, n,out,tmp,RLE16),n); pr(l,n); TMBENCH2(" 74",srlexd16( out,l,cpy, n,RLE16),n);break; + case 75: TMBENCH("",l=srlezc16( in, n,out,tmp,RLE16),n); pr(l,n); TMBENCH2(" 75",srlezd16( out,l,cpy, n,RLE16),n);break; + + #ifdef USE_LZ + case 80: TMBENCH("",l=lzenc( in,n,out,ns,codid,codlev,codprm) ,n); pr(l,n); TMBENCH2(" 80",lzdec(out,l,cpy,n,codid,codlev,codprm),n); break; + case 81: TMBENCH("",l=lztpenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 81",lztpdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 82: TMBENCH("",l=lztpxenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 82",lztpxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 83: TMBENCH("",l=lztpzenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 83",lztpzdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 84: TMBENCH("",l=lztp4enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 84",lztpd4ec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 85: TMBENCH("",l=lztp4xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 85",lztp4xdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 86: TMBENCH("",l=lztp4zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 86",lztp4zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + #ifdef BITSHUFFLE + case 87: TMBENCH("",l=lztp1enc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 87",lztp1dec( out,l,cpy,n,USIZE,tmp), n); break; + case 88: TMBENCH("",l=lztp1xenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 88",lztp1xdec( out,l,cpy,n,USIZE,tmp), n); break; + case 89: TMBENCH("",l=lztp1zenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 89",lztp1zdec( out,l,cpy,n,USIZE,tmp), n); break; + #endif + case 90: TMBENCH("",l=lztprleenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 90",lztprledec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 91: TMBENCH("",l=lztprlexenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 91",lztprlexdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 92: TMBENCH("",l=lztprlezenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 92",lztprlezdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 93: TMBENCH("",l=lzv8enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 93",lzv8dec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 94: TMBENCH("",l=lzv8xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 94",v8lzxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 95: TMBENCH("",l=lzv8zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 95",lzv8zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + + case 100: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2enc( in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("100",lztpd2dec( out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 101: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2xenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("101",lztpd2xdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 102: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2zenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("102",lztpd2zdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + + case 103: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3enc( in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("103",lztpd3dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 104: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3xenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("104",lztpd3xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 105: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3zenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("105",lztpd3zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 106: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4enc( in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("106",lztpd4dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + case 107: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4xenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("107",lztpd4xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n);} break; + case 108: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4zenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("108",lztpd4zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + #endif + + #ifdef CODEC1 + case 109: TMBENCH("",l=spdpenc(in,m*(USIZE),out,SPDPSIZE,codlev),n);pr(l,n); TMBENCH2("109",spdpdec( out, m*(USIZE), cpy,SPDPSIZE,codlev); ,n); break; + #endif + case 117: l = n; TMBENCH("", tpenc( in, n, out,USIZE),n); pr(l,n); TMBENCH2("117", tpdec( out, n,cpy, USIZE),n); break; + case 118: l = n; TMBENCH("", tp4enc(in, n, out,USIZE),n); pr(l,n); TMBENCH2("118", tp4dec(out, n,cpy, USIZE),n); break; + #ifdef BITSHUFFLE + case 119: l = n; TMBENCH("", bitshuffle(in, n, out, USIZE),n); pr(l,n); TMBENCH2("119", bitunshuffle(out, n,cpy, USIZE),n); break; + #endif + case ID_MEMCPY: if(!mcpy) goto end; + TMBENCH( "", libmemcpy(out,in,n) ,n); l=n; pr(l,n); TMBENCH2("120", libmemcpy( cpy,out,n) ,n); break; + #ifdef VBZ + case 122: { CompressionOptions opt; opt.perform_delta_zig_zag = 1; opt.integer_size = 2; opt.zstd_compression_level = 22; opt.vbz_version = VBZ_DEFAULT_VERSION; + TMBENCH("", l = vbz_compress(in, n, out, ns, &opt),n); pr(l,n); TMBENCH2("122", vbz_decompress(out, l, cpy, n, &opt),n); + } break; + #endif + default: goto end; + } + if(l) { + char s[65]; printf("%-30s ", bestr(id, 16,s, codstr(codid),codlev)); + if(cpy) rc = memcheck(in,m*(USIZE),cpy); + if(!rc) + printf("\t%s\n", inname?inname:""); + } + end:if(tmp) free(tmp); + return l; +} + +#undef USIZE +#define USIZE 4 +unsigned bench32(unsigned char *in, unsigned n, unsigned char *out, unsigned char *cpy, int id, char *inname, int codlev) { + unsigned l=0,m = n/(USIZE),rc = 0, d,ns=CBUF(n); + uint32_t *p; + char *tmp = NULL; + uint32_t dmin = mindelta32(in,m); + if(NEEDTMP && !(tmp = (unsigned char*)malloc(ns))) die(stderr, "malloc error\n"); + memrcpy(cpy,in,n); + + switch(id) { + case 1: TMBENCH("",l=p4nenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 1",p4ndec32( out, m, cpy) ,n); break; + #ifdef SSE + case 2: TMBENCH("",l=p4nenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 2",p4ndec128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 3: if(isa>=0x60) { TMBENCH("",l=p4nenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 3",p4ndec256v32( out, m, cpy) ,n); } break; + #endif + case 4: TMBENCH("",l=p4ndenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 4",p4nddec32( out, m, cpy) ,n); break; + #ifdef SSE + case 5: TMBENCH("",l=p4ndenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 5",p4nddec128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 6: if(isa>=0x60) { TMBENCH("",l=p4ndenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 6", p4nddec256v32( out, m, cpy) ,n); } break; + #endif + case 7: TMBENCH("",l=p4nd1enc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 7",p4nd1dec32( out, m, cpy) ,n); break; + #ifdef SSE + case 8: TMBENCH("",l=p4nd1enc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 8",p4nd1dec128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 9: if(isa>=0x60) { TMBENCH("",l=p4nd1enc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 9",p4nd1dec256v32( out, m, cpy) ,n); } break; + #endif + + case 10: TMBENCH("",l=p4nzenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 10",p4nzdec32( out, m, cpy) ,n); break; + #ifdef SSE + case 11: TMBENCH("",l=p4nzenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 11",p4nzdec128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 12: if(isa>=0x60) { TMBENCH("",l=p4nzenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 12",p4nzdec256v32( out, m, cpy) ,n); } break; + #endif + #ifdef SSE + case 13: TMBENCH("",l=p4nzzenc128v32( in, m, out,0),n); pr(l,n); TMBENCH2(" 13",p4nzzdec128v32( out, m, cpy,0) ,n); break; + #endif + //case 13: TMBENCH("",l=p4nsenc32( in, m, out) ,n); pr(l,n); TMBENCH2("",p4nsdec32( out, m, cpy) ,n); break; + // case 14: if(dmin!=(uint32_t)-1 && dmin > 0) { TMBENCH("",l=bicsenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 14",bicsdec32(out, m, cpy) ,n); } break; + // case 15: if(dmin!=(uint32_t)-1 && dmin > 0) { TMBENCH("",l=bicenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 15",bicdec32(out, m, cpy) ,n); } break; + // case 16: if(dmin!=(uint32_t)-1 && dmin > 0) { TMBENCH("",l=bicmenc32( in, m, out) ,n); pr(l,n); TMBENCH2(" 16",bicmdec32(out, m, cpy) ,n); }break; + + case 20: TMBENCH("",l=bitnpack32( in, m, out) ,n); pr(l,n); TMBENCH2(" 20",bitnunpack32( out, m, cpy) ,n); break; + #ifdef SSE + case 21: TMBENCH("",l=bitnpack128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 21",bitnunpack128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 22: if(isa>=0x60) { TMBENCH("",l=bitnpack256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 22",bitnunpack256v32( out, m, cpy) ,n); } break; + #endif + case 23: TMBENCH("",l=bitndpack32( in, m, out) ,n); pr(l,n); TMBENCH2(" 23",bitndunpack32( out, m, cpy) ,n); break; + #ifdef SSE + case 24: TMBENCH("",l=bitndpack128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 24",bitndunpack128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 25: if(isa>=0x60) { TMBENCH("",l=bitndpack256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 25",bitndunpack256v32( out, m, cpy) ,n); } break; + #endif + case 26: TMBENCH("",l=bitnd1pack32( in, m, out) ,n); pr(l,n); TMBENCH2(" 26",bitnd1unpack32( out, m, cpy) ,n); break; + #ifdef SSE + case 27: TMBENCH("",l=bitnd1pack128v32(in, m, out) ,n); pr(l,n); TMBENCH2(" 27",bitnd1unpack128v32(out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 28: if(isa>=0x60) { TMBENCH("",l=bitnd1pack256v32(in, m, out) ,n); pr(l,n); TMBENCH2(" 28",bitnd1unpack256v32(out, m, cpy) ,n); } break; + #endif + case 29: TMBENCH("",l=bitnzpack32( in, m, out) ,n); pr(l,n); TMBENCH2(" 29",bitnzunpack32( out, m, cpy) ,n); break; + #ifdef SSE + case 30: TMBENCH("",l=bitnzpack128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 30",bitnzunpack128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 31: if(isa>=0x60) { TMBENCH("",l=bitnzpack256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 31",bitnzunpack256v32( out, m, cpy) ,n); } break; + #endif + case 32: if(dmin==(uint32_t)-1) goto end; printf("DMIN=%d ", dmin); + TMBENCH("",l=bitnfpack32( in, m, out) ,n); pr(l,n); TMBENCH2(" 32",bitnfunpack32( out, m, cpy) ,n); break; + #ifdef SSE + case 33: if(dmin==(uint32_t)-1) goto end; + TMBENCH("",l=bitnfpack128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 33",bitnfunpack128v32( out, m, cpy) ,n); break; + #endif + #ifdef AVX2 + case 34: if(dmin==(uint32_t)-1) goto end; + if(isa>=0x60) { TMBENCH("",l=bitnfpack256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 34",bitnfunpack256v32( out, m, cpy) ,n);} break; + #endif + #ifdef SSE + case 35: if(dmin==(uint32_t)-1) goto end; + TMBENCH("",l=bitns1pack128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 35",bitns1unpack128v32( out, m, cpy) ,n); break; + #endif + //case 35: if(dmin==-1 /*|| !dmin*/) goto end; TMBENCH("",l=efanoenc32( in, m, out,0) ,n); pr(l,n); TMBENCH2("efanoenc32 ",efanodec32( out, m, cpy,0) ,n); break; + case 38: TMBENCH("",l=vsenc32( in, m, out)-out,n); pr(l,n); TMBENCH2(" 38",vsdec32( out, m, cpy) ,n); break; // vsimple : variable simple + case 39: TMBENCH("",l=vszenc32( in, m, out,tmp)-out,n); pr(l,n); TMBENCH2(" 39",vszdec32( out, m, cpy) ,n); break; + + case 40: TMBENCH("",l=vbenc32( in, m, out)-out,n); pr(l,n); TMBENCH2(" 40",vbdec32( out, m, cpy) ,n); break; // TurboVbyte : variable byte + case 41: TMBENCH("",l=vbzenc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 41",vbzdec32( out, m, cpy,0) ,n); break; + case 42: TMBENCH("",l=vbdenc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 42",vbddec32( out, m, cpy,0) ,n); break; + case 43: TMBENCH("",l=vbd1enc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 43",vbd1dec32( out, m, cpy,0) ,n); break; + case 44: TMBENCH("",l=vbddenc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 44",vbdddec32( out, m, cpy,0) ,n); break; + case 45: TMBENCH("",l=v8enc32( in, m, out)-out,n); pr(l,n); TMBENCH2(" 45",v8dec32( out, m, cpy) ,n); break; // Turbobyte : Group varint + case 46: TMBENCH("",l=v8denc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 46",v8ddec32( out, m, cpy,0) ,n); break; + case 47: TMBENCH("",l=v8d1enc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 47",v8d1dec32( out, m, cpy,0) ,n); break; + case 48: TMBENCH("",l=v8xenc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 48",v8xdec32( out, m, cpy,0) ,n); break; + case 49: TMBENCH("",l=v8zenc32( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 49",v8zdec32( out, m, cpy,0) ,n); break; + + #ifdef SSE + case 50: TMBENCH("",l=v8nenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 50",v8ndec128v32( out, m, cpy) ,n); break; + case 51: TMBENCH("",l=v8nzenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 51",v8nzdec128v32( out, m, cpy) ,n); break; + case 52: TMBENCH("",l=v8ndenc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 52",v8nddec128v32( out, m, cpy) ,n); break; + case 53: TMBENCH("",l=v8nd1enc128v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 53",v8nd1dec128v32( out, m, cpy) ,n); break; + #endif + + #ifdef AVX2 + case 55: if(isa>=0x60) { TMBENCH("",l=v8nenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 55",v8ndec256v32( out, m, cpy) ,n);} break; + case 56: if(isa>=0x60) { TMBENCH("",l=v8nzenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 56",v8nzdec256v32( out, m, cpy) ,n);} break; + case 57: if(isa>=0x60) { TMBENCH("",l=v8ndenc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 57",v8nddec256v32( out, m, cpy) ,n);} break; + case 58: if(isa>=0x60) { TMBENCH("",l=v8nd1enc256v32( in, m, out) ,n); pr(l,n); TMBENCH2(" 58",v8nd1dec256v32( out, m, cpy) ,n);} break; + #endif + + case 60: TMBENCH("",l=bvzzenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 60",bvzzdec32( out, m, cpy,0) ,n); break; // bitio + case 61: TMBENCH("",l=bvzenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 61",bvzdec32( out, m, cpy,0) ,n); break; + case 62: TMBENCH("",l=fpgenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 62",fpgdec32( out, m, cpy,0) ,n); break; + + case 65: TMBENCH("",l=fpxenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 65",fpxdec32( out, m, cpy,0) ,n); break; //Floating point/Integer + case 66: TMBENCH("",l=fpfcmenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 66",fpfcmdec32( out, m, cpy,0) ,n); break; + case 67: TMBENCH("",l=fpdfcmenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 67",fpdfcmdec32( out, m, cpy,0) ,n); break; + case 68: TMBENCH("",l=fp2dfcmenc32( in, m, out,0),n); pr(l,n); TMBENCH2(" 68",fp2dfcmdec32( out, m, cpy,0) ,n); break; + + case 70: TMBENCH("",l=trlec( in, n,out),n); pr(l,n); TMBENCH2(" 70",trled( out,l,cpy, n),n); break; // TurboRLE + case 71: TMBENCH("",l=trlexc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 71",trlexd( out,l,cpy, n),n); break; + case 72: TMBENCH("",l=trlezc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 72",trlezd( out,l,cpy, n),n); break; + case 73: TMBENCH("",l=srlec32( in, n,out,RLE32),n); pr(l,n); TMBENCH2(" 73",srled32( out,l,cpy, n,RLE32),n);break; + case 74: TMBENCH("",l=srlexc32( in, n,out,tmp,RLE32),n); pr(l,n); TMBENCH2(" 74",srlexd32( out,l,cpy, n,RLE32),n);break; + case 75: TMBENCH("",l=srlezc32( in, n,out,tmp,RLE32),n); pr(l,n); TMBENCH2(" 75",srlezd32( out,l,cpy, n,RLE32),n);break; + + #ifdef USE_LZ + case 80: TMBENCH("",l=lzenc( in,n,out,ns,codid,codlev,codprm) ,n); pr(l,n); TMBENCH2(" 80",lzdec(out,l,cpy,n,codid,codlev,codprm),n); break; + case 81: TMBENCH("",l=lztpenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 81",lztpdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 82: TMBENCH("",l=lztpxenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 82",lztpxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 83: TMBENCH("",l=lztpzenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 83",lztpzdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 84: TMBENCH("",l=lztp4enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 84",lztpd4ec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 85: TMBENCH("",l=lztp4xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 85",lztp4xdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 86: TMBENCH("",l=lztp4zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 86",lztp4zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + #ifdef BITSHUFFLE + case 87: TMBENCH("",l=lztp1enc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 87",lztp1dec( out,l,cpy,n,USIZE,tmp), n); break; + case 88: TMBENCH("",l=lztp1xenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 88",lztp1xdec( out,l,cpy,n,USIZE,tmp), n); break; + case 89: TMBENCH("",l=lztp1zenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 89",lztp1zdec( out,l,cpy,n,USIZE,tmp), n); break; + #endif + case 90: TMBENCH("",l=lztprleenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 90",lztprledec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 91: TMBENCH("",l=lztprlexenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 91",lztprlexdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 92: TMBENCH("",l=lztprlezenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 92",lztprlezdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 93: TMBENCH("",l=lzv8enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 93",lzv8dec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 94: TMBENCH("",l=lzv8xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 94",v8lzxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 95: TMBENCH("",l=lzv8zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 95",lzv8zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + + case 100: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2enc( in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("100",lztpd2dec( out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 101: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2xenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("101",lztpd2xdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 102: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2zenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("102",lztpd2zdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + + case 103: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3enc( in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("103",lztpd3dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 104: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3xenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("104",lztpd3xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 105: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3zenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("105",lztpd3zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 106: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4enc( in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("106",lztpd4dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + case 107: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4xenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("107",lztpd4xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n);} break; + case 108: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4zenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("108",lztpd4zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + #endif + + #ifdef CODEC1 + case 109: TMBENCH("",l=spdpenc(in,m*(USIZE),out,SPDPSIZE,codlev),n);pr(l,n); TMBENCH2("109",spdpdec( out, m*(USIZE), cpy,SPDPSIZE,codlev); ,n); break; + case 110: TMBENCH("",l=streamvbyte_encode(in, m, out),n); pr(l,n); TMBENCH2("110", streamvbyte_decode( out, cpy, m),n); break; + case 111: TMBENCH("",l=streamvbyte_delta_encode(in,m,out,0),n); pr(l,n); TMBENCH2("111", streamvbyte_delta_decode( out, cpy, m,0),n); break; + case 112: TMBENCH("",l=streamvbyte_zzag_encode( in,m,out,0,tmp),n); pr(l,n); TMBENCH2("112", streamvbyte_zzag_decode( out, cpy, m,0,tmp),n); break; + #endif + #if defined(CODEC2) && defined(__SSE4_1__) + case 113: TMBENCH("",l=vbyte_encode(in, m, out),n); pr(l,n); TMBENCH2("113", masked_vbyte_decode(out, cpy, m),n); break; + case 114: TMBENCH("",l=FastPFore32( in, m, out,ns),n); pr(l,n); TMBENCH2("114", FastPFord32( out, m, cpy),n); break; + case 115: TMBENCH("",l=FastPFore128v32(in, m, out,ns),n); pr(l,n); TMBENCH2("115", FastPFord128v32(out, m, cpy),n); break; + case 116: TMBENCH("",l=OptPFore128v32( in, m, out,ns),n); pr(l,n); TMBENCH2("116", OptPFord128v32( out, m, cpy),n); break; + #endif + case 117: l = n; TMBENCH("", tpenc( in, n, out,USIZE),n); pr(l,n); TMBENCH2("117", tpdec( out, n,cpy, USIZE),n); break; + case 118: l = n; TMBENCH("", tp4enc(in, n, out,USIZE),n); pr(l,n); TMBENCH2("118", tp4dec(out, n,cpy, USIZE),n); break; + #ifdef BITSHUFFLE + case 119: l = n; TMBENCH("", bitshuffle(in, n, out, USIZE),n); pr(l,n); TMBENCH2("119", bitunshuffle(out, n,cpy, USIZE),n); break; + #endif + case ID_MEMCPY: if(!mcpy) goto end; + TMBENCH( "", libmemcpy(out,in,n) ,n); l=n; pr(l,n); TMBENCH2("120", libmemcpy( cpy,out,n) ,n); break; + //case 121: if(dmin == (uint32_t)-1) goto end; + // { size_t _l; TMBENCH("",vtenc_list_encode_u32(in, m, out,ns,&_l),n); l = _l; pr(l,n); TMBENCH2("104", vtenc_list_decode_u32(out, _l, cpy, m),n); } break; + //case 112: TMBENCH("",fppad32(in, m, out,errlim),n); pr(n,n); TMBENCH2("fppad32 ", fppad32(in, m, out,errlim),n); break; + default: goto end; + } + if(l) { + char s[128];AC(codstr(codid), "Fatal"); printf("%-40s ", bestr(id,32,s, codstr(codid),codlev)); + if(cpy) rc = memcheck32(in,m,cpy); + if(!rc) + printf("\t%s\n", inname?inname:""); + } + end:if(tmp) free(tmp); + return l; +} + +#undef USIZE +#define USIZE 8 +unsigned bench64(unsigned char *in, unsigned n, unsigned char *out, unsigned char *cpy, int id, char *inname, int codlev) { + unsigned l,m = n/(USIZE),rc = 0, d,ns=CBUF(n); uint64_t dmin = mindelta64(in,m); + uint64_t *p; + char *tmp = NULL; + if(NEEDTMP && !(tmp = (unsigned char*)malloc(ns))) die(stderr, "malloc error\n"); + memrcpy(cpy,in,n); + + switch(id) { + case 1: TMBENCH("",l=p4nenc64( in, m, out) ,n); pr(l,n); TMBENCH2(" 1",p4ndec64( out, m, cpy) ,n); break; + #ifdef SSE + case 2: TMBENCH("",l=p4nenc128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 2",p4ndec128v64( out, m, cpy) ,n); break; + #endif + case 4: TMBENCH("",l=p4ndenc64( in, m, out) ,n); pr(l,n); TMBENCH2(" 4",p4nddec64( out, m, cpy) ,n); break; + //case 5: TMBENCH("",l=p4ndenc128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 5",p4nddec128v64( out, m, cpy) ,n); break; + + case 7: TMBENCH("",l=p4nd1enc64( in, m, out) ,n); pr(l,n); TMBENCH2(" 7",p4nd1dec64( out, m, cpy) ,n); break; + //case 8: TMBENCH("",l=p4nd1enc128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 8",p4nd1dec128v64( out, m, cpy) ,n); break; + + case 10: TMBENCH("",l=p4nzenc64( in, m, out) ,n); pr(l,n); TMBENCH2(" 10",p4nzdec64( out, m, cpy) ,n); break; + //case 11: TMBENCH("",l=p4nzenc128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 11",p4nzdec128v64( out, m, cpy) ,n); break; + + #ifdef SSE + case 13: TMBENCH("",l=p4nzzenc128v64( in, m, out,0),n); pr(l,n); TMBENCH2(" 13",p4nzzdec128v64( out, m, cpy,0) ,n); break; + #endif + + case 20: TMBENCH("",l=bitnpack64( in, m, out) ,n); pr(l,n); TMBENCH2(" 20",bitnunpack64( out, m, cpy) ,n); break; + #ifdef SSE + case 21: TMBENCH("",l=bitnpack128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 21",bitnunpack128v64( out, m, cpy) ,n); break; + #endif + + case 23: TMBENCH("",l=bitndpack64( in, m, out) ,n); pr(l,n); TMBENCH2(" 23",bitndunpack64( out, m, cpy) ,n); break; + //case 24: TMBENCH("",l=bitndpack128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 24",bitndunpack128v64( out, m, cpy) ,n); break; + + case 26: TMBENCH("",l=bitnd1pack64( in, m, out) ,n); pr(l,n); TMBENCH2(" 26",bitnd1unpack64( out, m, cpy) ,n); break; + //case 27: TMBENCH("",l=bitnd1pack128v64(in, m, out) ,n); pr(l,n); TMBENCH2(" 27",bitnd1unpack128v64(out, m, cpy) ,n); break; + + case 29: TMBENCH("",l=bitnzpack64( in, m, out) ,n); pr(l,n); TMBENCH2(" 29",bitnzunpack64( out, m, cpy) ,n); break; + //case 30: TMBENCH("",l=bitnzpack128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 30",bitnzunpack128v64( out, m, cpy) ,n); break; + + case 32: if(dmin==(uint64_t)-1) goto end; + TMBENCH("",l=bitnfpack64( in, m, out) ,n); pr(l,n); TMBENCH2(" 32",bitnfunpack64( out, m, cpy) ,n); break; + //case 33: if(dmin==-1) goto end; + // TMBENCH("",l=bitnfpack128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 33",bitnfunpack128v64( out, m, cpy) ,n); break; + + //case 35: if(dmin==-1) goto end; + // TMBENCH("",l=bitns1pack128v64( in, m, out) ,n); pr(l,n); TMBENCH2(" 35",bitns1unpack128v64( out, m, cpy) ,n); break; + //case 35: if(dmin==-1 /*|| !dmin*/) goto end; TMBENCH("",l=efanoenc64( in, m, out,0) ,n); pr(l,n); TMBENCH2("efanoenc64 ",efanodec64( out, m, cpy,0) ,n); break; + case 38: TMBENCH("",l=vsenc64( in, m, out)-out,n); pr(l,n); TMBENCH2(" 38",vsdec64( out, m, cpy) ,n); break; // vsimple : variable simple + case 39: TMBENCH("",l=vszenc64( in, m, out,tmp)-out,n); pr(l,n); TMBENCH2(" 39",vszdec64( out, m, cpy) ,n); break; + + case 40: TMBENCH("",l=vbenc64( in, m, out)-out,n); pr(l,n); TMBENCH2(" 40",vbdec64( out, m, cpy) ,n); break; // TurboVbyte : variable byte + case 41: TMBENCH("",l=vbzenc64( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 41",vbzdec64( out, m, cpy,0) ,n); break; + case 42: TMBENCH("",l=vbdenc64( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 42",vbddec64( out, m, cpy,0) ,n); break; + case 43: TMBENCH("",l=vbd1enc64( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 43",vbd1dec64( out, m, cpy,0) ,n); break; + case 44: TMBENCH("",l=vbddenc64( in, m, out,0)-out,n); pr(l,n); TMBENCH2(" 44",vbdddec64( out, m, cpy,0) ,n); break; + + case 60: TMBENCH("",l=bvzzenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 60",bvzzdec64( out, m, cpy,0) ,n); break; // bitio + case 61: TMBENCH("",l=bvzenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 61",bvzdec64( out, m, cpy,0) ,n); break; + case 62: TMBENCH("",l=fpgenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 62",fpgdec64( out, m, cpy,0) ,n); break; + + case 65: TMBENCH("",l=fpxenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 65",fpxdec64( out, m, cpy,0) ,n); break; //Floating point/Integer + case 66: TMBENCH("",l=fpfcmenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 66",fpfcmdec64( out, m, cpy,0) ,n); break; + case 67: TMBENCH("",l=fpdfcmenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 67",fpdfcmdec64( out, m, cpy,0) ,n); break; + case 68: TMBENCH("",l=fp2dfcmenc64( in, m, out,0),n); pr(l,n); TMBENCH2(" 68",fp2dfcmdec64( out, m, cpy,0) ,n); break; + + case 70: TMBENCH("",l=trlec( in, n,out),n); pr(l,n); TMBENCH2(" 70",trled( out,l,cpy, n),n); break; // TurboRLE + case 71: TMBENCH("",l=trlexc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 71",trlexd( out,l,cpy, n),n); break; + case 72: TMBENCH("",l=trlezc( in, n,out,tmp),n); pr(l,n); TMBENCH2(" 72",trlezd( out,l,cpy, n),n); break; + case 73: TMBENCH("",l=srlec64( in, n,out,RLE64),n); pr(l,n); TMBENCH2(" 73",srled64( out,l,cpy, n,RLE64),n);break; + case 74: TMBENCH("",l=srlexc64( in, n,out,tmp,RLE64),n); pr(l,n); TMBENCH2(" 74",srlexd64( out,l,cpy, n,RLE64),n);break; + case 75: TMBENCH("",l=srlezc64( in, n,out,tmp,RLE64),n); pr(l,n); TMBENCH2(" 75",srlezd64( out,l,cpy, n,RLE64),n);break; + + #ifdef USE_LZ + case 80: TMBENCH("",l=lzenc( in,n,out,ns,codid,codlev,codprm) ,n); pr(l,n); TMBENCH2(" 80",lzdec(out,l,cpy,n,codid,codlev,codprm),n); break; + case 81: TMBENCH("",l=lztpenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 81",lztpdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 82: TMBENCH("",l=lztpxenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 82",lztpxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 83: TMBENCH("",l=lztpzenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 83",lztpzdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 84: TMBENCH("",l=lztp4enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 84",lztpd4ec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 85: TMBENCH("",l=lztp4xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 85",lztp4xdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 86: TMBENCH("",l=lztp4zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 86",lztp4zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + #ifdef BITSHUFFLE + case 87: TMBENCH("",l=lztp1enc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 87",lztp1dec( out,l,cpy,n,USIZE,tmp), n); break; + case 88: TMBENCH("",l=lztp1xenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 88",lztp1xdec( out,l,cpy,n,USIZE,tmp), n); break; + case 89: TMBENCH("",l=lztp1zenc( in,n,out,ns,USIZE,tmp), n); pr(l,n); TMBENCH2(" 89",lztp1zdec( out,l,cpy,n,USIZE,tmp), n); break; + #endif + case 90: TMBENCH("",l=lztprleenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 90",lztprledec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 91: TMBENCH("",l=lztprlexenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 91",lztprlexdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 92: TMBENCH("",l=lztprlezenc(in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 92",lztprlezdec(out,l,cpy,n,USIZE,tmp) ,n); break; + case 93: TMBENCH("",l=lzv8enc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 93",lzv8dec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 94: TMBENCH("",l=lzv8xenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 94",v8lzxdec( out,l,cpy,n,USIZE,tmp) ,n); break; + case 95: TMBENCH("",l=lzv8zenc( in,n,out,ns,USIZE,tmp) ,n); pr(l,n); TMBENCH2(" 95",lzv8zdec( out,l,cpy,n,USIZE,tmp) ,n); break; + + case 100: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2enc( in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("100",lztpd2dec( out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 101: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2xenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("101",lztpd2xdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + case 102: if(dim2<=0) goto end; { unsigned d2 = dim2*(dim3?dim3:1)*(dim4?dim4:1); + TMBENCH("",l=lztpd2zenc(in,n,out,ns,USIZE,tmp, dim1,d2),n); pr(l,n); TMBENCH2("102",lztpd2zdec(out,l,cpy,n,USIZE,tmp, dim1,d2),n); } break; + + case 103: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3enc( in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("103",lztpd3dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 104: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3xenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("104",lztpd3xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 105: if(dim3<=0) goto end; { unsigned d3 = dim3*(dim4?dim4:1); + TMBENCH("",l=lztpd3zenc(in,n,out,ns,USIZE,tmp, dim1,dim2,d3),n); pr(l,n); TMBENCH2("105",lztpd3zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,d3),n); } break; + case 106: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4enc( in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("106",lztpd4dec( out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + case 107: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4xenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("107",lztpd4xdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n);} break; + case 108: if(dim4<=0) goto end; { + TMBENCH("",l=lztpd4zenc(in,n,out,ns,USIZE,tmp,dim1,dim2,dim3,dim4),n);pr(l,n); TMBENCH2("108",lztpd4zdec(out,l,cpy,n,USIZE,tmp, dim1,dim2,dim3,dim4),n); } break; + #endif + + #ifdef CODEC1 + case 109: TMBENCH("",l=spdpenc(in,m*(USIZE),out,SPDPSIZE,codlev),n);pr(l,n); TMBENCH2("109",spdpdec( out, m*(USIZE), cpy,SPDPSIZE,codlev); ,n); break; + #endif + + case 117: l = n; TMBENCH("", tpenc( in, n, out,USIZE),n); pr(l,n); TMBENCH2("107", tpdec( out, n,cpy, USIZE),n); break; + case 118: l = n; TMBENCH("", tp4enc(in, n, out,USIZE),n); pr(l,n); TMBENCH2("108", tp4dec(out, n,cpy, USIZE),n); break; + #ifdef BITSHUFFLE + case 119: l = n; TMBENCH("", bitshuffle(in, n, out, USIZE),n); pr(l,n); TMBENCH2("109", bitunshuffle(out, n,cpy, USIZE),n); break; + #endif + case ID_MEMCPY: if(!mcpy) goto end; + TMBENCH( "", libmemcpy(out,in,n) ,n); l=n; pr(l,n); TMBENCH2("110", libmemcpy( cpy,out,n) ,n); break; + default: goto end; + } + if(l) { + char s[65]; printf("%-30s ", bestr(id, 64,s, codstr(codid),codlev)); + if(cpy) rc = memcheck(in,m*(USIZE),cpy); + if(!rc) + printf("\t%s\n", inname?inname:""); + } + end:if(tmp) free(tmp); + return l; +} + +void usage(char *pgm) { + fprintf(stderr, "\nIcApp Copyright (c) 2013-2021 Powturbo %s\n", __DATE__); + fprintf(stderr, "Usage: %s [options] [file]\n", pgm); + //fprintf(stderr, " -b#s # = blocksize (default filesize,). max=1GB\n"); + fprintf(stderr, " -B#s # = max. benchmark filesize (default 1GB) ex. -B4G\n"); + fprintf(stderr, " s = modifier s:K,M,G=(1000, 1.000.000, 1.000.000.000) s:k,m,h=(1024,1Mb,1Gb). (default m) ex. 64k or 64K\n"); + fprintf(stderr, "Benchmark:\n"); + fprintf(stderr, " -i#/-j# # = Minimum de/compression iterations per run (default=auto)\n"); + fprintf(stderr, " -I#/-J# # = Number of de/compression runs (default=3)\n"); + fprintf(stderr, " -e# # = function ids separated by ',' or ranges '#-#' (default='1-%d')\n", ID_MEMCPY); + fprintf(stderr, "File format:\n"); + fprintf(stderr, " -F[Xx[k][H]][.d]\n"); + fprintf(stderr, " X = file format:\n"); + fprintf(stderr, " t = text:one integer per line, k=column number in multiple columns line\n"); + fprintf(stderr, " c = text:integers separated by non digit char\n"); + fprintf(stderr, " x = entry format\n"); + fprintf(stderr, " [b=int8], [s=int16], [u=int32(default)], [l=int64], [f:float] [d:double]\n"); + fprintf(stderr, " .# = decimal digits (default 2). Convert dec. numbers to integers\n"); + fprintf(stderr, " H = skip first line(s)\n"); + fprintf(stderr, " -H = skip first line(s). Only for text files\n"); + fprintf(stderr, " -K# = #:column number in multiple columns/line. Only for text files\n"); + fprintf(stderr, " -ks = s:separator(s) (default , ; and TAB) in multiple columns/line. Only for text files\n"); + fprintf(stderr, " -s# = #:integer size 2,4,8\n"); + fprintf(stderr, " -f# = #:floating point size 4,8\n"); + fprintf(stderr, " -t# = #:Timestamp in iso-8601 converted to seconds (32 bits)\n"); + fprintf(stderr, " -T# = #:Timestamp in iso-8601 converted to milliseconds (64 bits)\n"); + fprintf(stderr, " -V# = #:divisor. Only for text files\n"); + fprintf(stderr, " -D# = #:decimals. Only for text files\n"); + fprintf(stderr, " -g# = allowed relative error for lossy floating point compression (ex. -g.00001)\n"); + fprintf(stderr, " -RD1xD2xD3xD4 = D1,D2,D3,D4 : dimensions (ex. -R128x64x1024)\n"); + fprintf(stderr, "Output:\n"); + fprintf(stderr, " -v# # = verbosity 0..5 (default 1). 5=print first values read from text file\n"); + fprintf(stderr, "----- arg. ZIPF specified --------------\n"); + fprintf(stderr, " -aF F = zipfian distribution alpha ex. -a1.0 uniform -a1.5 skewed\n"); + fprintf(stderr, " -m#s # = minimum number. s=(k,K, m,M, g,G\n"); + fprintf(stderr, " -M#s # = maximum number\n"); + fprintf(stderr, " -n#s # = number of integers to generate\n"); + fprintf(stderr, " -d# Generate a non decreasing sequence. #:delta 0=non decreasing 1=strictly non decreasing\n"); + fprintf(stderr, "Examples:\n"); + fprintf(stderr, "./icapp -a1.5 -m0 -M255 -n100M ZIPF\n"); + fprintf(stderr, "./icapp -e45-59,90,91 -I15 -J15 -d0 ZIPF\n"); + fprintf(stderr, "./icapp -e45-59 -I15 -J15 -d1 -M16 -Fs -n10000 ZIPF\n"); + fprintf(stderr, "./icapp file -e2,7-9,14,15\n"); + fprintf(stderr, "./icapp -Ft -D2 ibm.data\n"); + fprintf(stderr, "./icapp -Ft -f8 usages.dat\n"); + fprintf(stderr, "./icapp -Ft -f8 -HH tripdata.csv\n"); + fprintf(stderr, "./icapp -Fd -g.001 double.raw\n"); + exit(0); +} + +int main(int argc, char* argv[]) { + unsigned b = 1 << 30, lz=0, fno,m=1000000; + int isize=4,dfmt = 0,kid=1,skiph=0,decs=0,divs=1,nsd=-1,dim0=0;//tp2test();tp3test();exit(0); + uint64_t be_mindelta=0; + unsigned char *in = NULL, *out, *cpy, *scmd = NULL, *icmd = NULL; + double mdelta=-10,errlim=0.0; + tm_verbose = 1; + + int c, digit_optind = 0, this_option_optind = optind ? optind : 1, option_index = 0; + static struct option long_options[] = { {"blocsize", 0, 0, 'b'}, {0, 0, 0} }; + for(;;) { + if((c = getopt_long(argc, argv, "a:B:C:d:D:d:e:E:f:F:g:G:I:J:k:K:Hl:m:M:n:R:s:v:V:w:y", long_options, &option_index)) == -1) break; + switch(c) { + case 0 : printf("Option %s", long_options[option_index].name); if(optarg) printf (" with arg %s", optarg); printf ("\n"); break; + case 'C': cmp = atoi(optarg); break; + case 'e': icmd = optarg; break; + case 'E': scmd = optarg; break; + case 'G': nsd = atoi(optarg); break; + case 'D': decs = atoi(optarg); break; + + case 'F': { char *s = optarg; + if(*s=='c') { dfmt = T_CHAR; s++;} + else if(*s=='t') { dfmt = T_TXT; if(*++s > '0' && *s <= '9') { kid = *s++ - '0'; if(*s > '0' && *s <= '9') kid = kid*10 + (*s++ - '0'); } } + else if(*s=='e') { dfmt = T_TST; s++; } + else if(*s=='r') { dfmt = 0; s++; } // default + + if(*s=='f') isize = -4, s++; // float : 4 bytes + else if(*s=='d') isize = -8, s++; // double: 8 bytes + else if(*s=='b') isize = 1, s++; // 1 byte + else if(*s=='s') isize = 2, s++; // 2 bytes + else if(*s=='u') isize = 4, s++; // 4 bytes + else if(*s=='l') isize = 8, s++; // 8 bytes + else if(*s=='t') isize = 4, s++, dfmt = T_TIM32; // 4 bytes, timestamp + else if(*s=='T') isize = 8, s++, dfmt = T_TIM64; // 8 bytes, timestamp + if(*s == '.') { if(*++s >= '0' && *s <= '9') { decs = s[0] - '0'; s++; } } // number of decimals after . + if(*s == 'v') { divs = strtod(++s, &s); } + if(*s == 'H') { skiph++; s++; } // skip first line(s). ex. HHH : skip 3 first lines + //switch(*s) { case 's': be_mindelta = 0; break; case 'S': be_mindelta = 1; break; case 'z': be_mindelta = 2; break; } + } break; + + case 'g': errlim = strtod(optarg, NULL); break; + case 'H': skiph++; break; + case 'K': { kid = atoi(optarg); if(!keysep) keysep = ",;\t"; } break; + case 'k': keysep = optarg; break; + case 'I': if((tm_Rep = atoi(optarg))<=0) tm_rep=tm_Rep=1; break; + case 'J': if((tm_Rep2 = atoi(optarg))<=0) tm_rep=tm_Rep2=1; break; + case 's': isize = argtoi(optarg,1); break; + case 'B': b = argtoi(optarg,1); break; + //case 'c': cmp++; break; + case 'l': codlev = atoi(optarg); break; + case 'y': mcpy = 0; break; + + case 'a': a = strtod(optarg, NULL); break; + case 'd': mdelta = strtod(optarg, NULL); /*printf("MDELTA=%d ");*/break; + case 'n': m = argtoi(optarg,1); break; + case 'm': rm = argtoi(optarg,1); break; + case 'M': rx = argtoi(optarg,1); break; + case 'f': isize = -argtoi(optarg,1); break; + case 'R': { char *p; dim1 = strtoul(optarg, &p, 10); if(!dim1) dim0++; + if(*p) dim2 = strtoul(p+1, &p, 10); + if(*p) dim3 = strtoul(p+1, &p, 10); + if(*p) dim4 = strtoul(p+1, &p, 10); printf("dim=%dx%dx%dx%d ", dim1, dim2, dim3, dim4); + } break; + case 'w': tm_verbose = atoi(optarg); break; + case 'v': verbose = atoi(optarg); break; + case 'V': divs = atoi(optarg); break; + default: + usage(argv[0]); + exit(0); + } + } + #ifdef LZTURBO + beini(); + #endif + if(argc - optind < 1) { + usage(argv[0]); + exit(0); + } + isa = cpuisa(); + printf("detected simd id=%x, %s\n\n", cpuini(0), cpustr(cpuini(0))); + unsigned char _scmd[33]; strcpy(_scmd, "lz4,1"); + if(!scmd) scmd = _scmd; + while(isspace(*scmd)) scmd++; + char *q; + int i; + if(q = strchr(scmd,',')) *q = '\0'; + for(i = 0; _codstr[i]; i++) + if(!strcasecmp(scmd, _codstr[i])) { codid = i; break; } + if(!_codstr[i]) { printf("compressor '%s' not implemented\n", scmd); exit(-1); } + scmd = q?(q+1):(char*)""; + codlev = strtoul(scmd, &scmd, 10); + + if(scmd) strcpy(codprm,scmd); + if(verbose>1) printf("dfmt=%d,size=%d\n", dfmt, isize); + for(fno = optind; fno < argc; fno++) { + char *inname = argv[fno]; + int i,n; + long long flen; + FILE *fi = NULL; + if(!strcmp(inname,"ZIPF") || !strcmp(inname,"TMS")) flen = n = m*abs(isize); + else { + fi = fopen(inname, "rb"); if(!fi) { perror(inname); continue; } + if(dfmt) { + n = flen = befgen(&in, 0, dfmt, isize, fi, kid, skiph, decs, divs, be_mindelta); + } else { + fseek(fi, 0, SEEK_END); + flen = ftell(fi); + fseek(fi, 0, SEEK_SET); + if(flen > b) flen = b; + n = flen; + if(dim0) { char *p; if(!(p = strrchr(inname, '\\')) && !(p = strrchr(inname, '/'))) p=inname; + dim1=dim2=dim3=dim4=0; + while(!isdigit(*p)) p++; if(verbose>1) printf("fn='%s' ", p); + dim1 = strtoul(p, &p, 10); + if(dim1 && *p) dim2 = strtoul(p+1, &p, 10); + if(dim2 && *p) dim3 = strtoul(p+1, &p, 10); + if(dim3 && *p) dim4 = strtoul(p+1, &p, 10); + } + } + } + + if(dim4 && !dim3) dim3 = 1; if(dim3 && !dim2) dim2 = 1; if(dim2 && !dim1) dim1 = 1; + if(dim1 || dim2 || dim3) printf("dim=%dx%dx%dx%d\n", dim1, dim2, dim3, dim4); + + if(!in && !(in = (unsigned char*)malloc(n+64+1024 ))) die("malloc error 'in =%d'\n", n); cpy = in; + if(!(out = (unsigned char*)malloc(CBUF(n)+1024*1024))) die("malloc error 'out=%d'\n", n); + if(cmp && !(cpy = (unsigned char*)malloc(CBUF(n)+1024*1024))) die("malloc error 'cpy=%d'\n", n); + if(fi) { + if(!dfmt) n = fread(in, 1, n, fi); + fclose(fi); + int delta = mdelta; + if(delta>=0) { uint32_t *_in = in,*p,m = n/sizeof(_in[0]); for(p = _in+1; p < _in+m; p++) { uint64_t u = (uint64_t)p[0]+p[-1]+delta; if(u>0xffffffffull) { printf("delta overflow\n"); exit(0); } p[0]=u; } + printf("delta=%d in[m-1]=%u ", delta, _in[m-1]); + for(unsigned i = 1; i < m; i++) { AC(_in[i]>_in[i-1], "icapp: Not sorted at=%u,count=%d\n", i, n); } + } + } else if(!strcmp(inname,"TMS") && abs(isize) == 8) + tms64(in, m, rm, rx, a); + else + datagen(in, m, isize, mdelta); + if(n <= 0) exit(0); + + //if(fno == optind) + tm_init(tm_Rep, tm_verbose /* 2 print id */); + + if(errlim > 0.0 || nsd>=0) { // convert input for lossy floating point compression + if(errlim < 0.000009999) errlim = 0.00001; + if(isize == -4) { + fppad32(in,n/4,out,errlim); if(verbose>0) fpstat(in, n/4, out, -4); //if(nsd >= 0) fprnd32(in,n/4,out,nsd); else // + fppad32(in,n/4, in,errlim); /*if(nsd >= 0) fprnd32(in,n/4,in, nsd); else */ + //TMBENCH("fppad32",fppad32(in,n/8,out,errlim),n);printf("\n"); + } else if(isize == -8) { //TMBENCH("fppad64",fppad64(in,n/8,out,errlim),n);printf("\n"); + fppad64(in,n/8,out,errlim); if(verbose>0) fpstat(in, n/8, out, -8); /*if(nsd>=0) fprnd64(in,n/8,out,nsd); else*/ + fppad64(in,n/8, in,errlim); /*if(nsd>=0) fprnd64(in,n/8, in,nsd); else*/ + } + #ifdef USE_FLOAT16 + else if(isize == -2) { + fppad16(in,n/2,out,errlim); if(verbose>0) fpstat(in, n/2, out, -2); /*if(nsd>=0) fprnd64(in,n/8,out,nsd); else*/ + fppad16(in,n/2, in,errlim); /*if(nsd>=0) fprnd64(in,n/8, in,nsd); else*/ + } + #endif + } + be_mindelta = mindelta(in, n/abs(isize), abs(isize)); + + if(fi && verbose) { unsigned l; // Calculate bits distributions + switch(abs(isize)) { + case 1: l=histl8( in,n); stprint("file: max", xbits); if(histz8( in,n )1 || fno == optind) { + printf(" E MB/s size ratio D MB/s function %s size=%d bits (lz=%s,%d%s) ", isize>0?"integer":"floating point", abs(isize)*8, codstr(codid), codlev, codprm); + if(be_mindelta == (uint64_t)-1) printf("unsorted %lld ", be_mindelta); + else printf("sorted(mindelta=%lld) ", be_mindelta); + if(errlim>0.0) printf("FP err=%f", errlim); + printf("\n"); + } + do { + unsigned id = strtoul(p, &p, 10),idx = id, i; + while(isspace(*p)) p++; if(*p == '-') { if((idx = strtoul(p+1, &p, 10)) < id) idx = id; if(idx > ID_MEMCPY) idx = ID_MEMCPY; } + for(i = id; i <= idx; i++) + switch(abs(isize)) { + case 1: bench8( in,n,out,cpy,i,optind+1==argc?NULL:inname,codlev); break; + case 2: bench16(in,n,out,cpy,i,optind+1==argc?NULL:inname,codlev); break; + case 4: bench32(in,n,out,cpy,i,optind+1==argc?NULL:inname,codlev); break; + case 8: bench64(in,n,out,cpy,i,optind+1==argc?NULL:inname,codlev); break; + default: die("integer size must be 1, 2, 4 or 8\n"); + } + } while(*p++); + printf("\n"); + free(in); free(out); free(cpy); in = out = cpy = NULL; + } +} diff --git a/src/ext/for/icbench.c b/src/ext/for/icbench.c new file mode 100644 index 00000000000..a9278c340dd --- /dev/null +++ b/src/ext/for/icbench.c @@ -0,0 +1,1736 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// IcBench: main program +#define _CRT_SECURE_NO_WARNINGS +#define _GNU_SOURCE +#define _LARGEFILE64_SOURCE 1 +#include +#include +#include +//#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + #ifndef _WIN32 +#include + #endif + #ifdef _MSC_VER +#define PRId64 "I64d" +#include "vs/getopt.h" + #else +#include +#include +#include + #endif + + #if !defined(_WIN32) +#include +#include +#include +#include +#include + #else +#include +#include +#define srand48(x) srand(x) +#define drand48() ((double)(rand()) / RAND_MAX) +#define __off64_t _off64_t + #endif + +#include +#include "conf.h" +#define VINT_IN +#include "vint.h" +#include "bitpack.h" +#include "vsimple.h" +#include "eliasfano.h" +#include "vp4.h" +#include "plugins.h" + +//#define RDTSC_ON +#define TM_F 4 +#include "time_.h" + +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#endif + +int strpref(char **str, int n, char sep1, char sep2) { + int i, j=0; + for(;;j++) + for(i = 0; i < n; i++) + if(!str[i][j] || str[i][j] != str[0][j]) { + while (j > 0 && str[0][j-1] != sep1 && str[0][j-1] != sep2) j--; + return j; + } + return 0; +} + +int memcheck(unsigned char *_in, unsigned _n, unsigned char *_cpy, int cmp) { + unsigned *in = (unsigned *)_in,*cpy=_cpy,n = (_n+3)/4; + int i; + if(cmp <= 1) + return 0; + for(i = 0; i < n; i++) + if(in[i] != cpy[i]) { + if(cmp > 4) abort(); // crash (AFL) fuzzing + printf("ERROR in[%d]=%x,%d dec[%d]=%x,%d\n", i, in[i], bsr64(in[i]), i, cpy[i], bsr64(cpy[i]) ); + if(cmp>3) { + int j; + for(j=i & 0xffffff80u; j < i+128;j++) { unsigned e = in[j] != cpy[j]; + if(e) printf("#%d:%x,%x ", j, in[j], cpy[j]);else printf("%d:%x ", j, in[j]); + } + printf("\n"); + } + if(cmp > 2) exit(EXIT_FAILURE); + return i+1; + } + return 0; +} + +int memcheck64(unsigned char *_in, unsigned _n, unsigned char *_cpy, int cmp) { + uint64_t *in = (uint64_t *)_in,*cpy=_cpy,n = (_n+7)/8; + int i; + if(cmp <= 1) + return 0; + for(i = 0; i < n; i++) + if(in[i] != cpy[i]) { + if(cmp > 4) abort(); // crash (AFL) fuzzing + printf("ERROR in[%d]=%llx,%d dec[%d]=%llx,%d\n", i, in[i], bsr64(in[i]), i, cpy[i], bsr64(cpy[i]) ); + if(cmp>3) { + int j; + for(j=i & 0xffffff80u; j < i+128;j++) { unsigned e = in[j] != cpy[j]; + if(e) printf("#%d:%x,%x ", j, in[j], cpy[j]);else printf("%d:%x ", j, in[j]); + } + printf("\n"); + } + if(cmp > 2) exit(EXIT_FAILURE); + return i+1; + } + return 0; +} +//------------------------------- malloc ------------------------------------------------ +#define USE_MMAP + #if __WORDSIZE == 64 +#define MAP_BITS 31 + #else +#define MAP_BITS 28 + #endif + +void *_valloc(size_t size, int a) { + if(!size) return NULL; + #if defined(_WIN32) + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + #elif defined(USE_MMAP) + void *ptr = mmap((size_t)a<id[0]; pg++) + printf("%-16s %s %s\n", pg->id, pg->desc, pg->name); + + printf("\n\n%-16s %-48s %s\n", "Function","Description", "level"); + printf("\n%-16s %-48s %s\n", "--------","-----------", "-----"); + for(gs = plugs; gs->id >= 0; gs++) + if(gs->codec) + printf("%-16s %-48s %s\n", gs->name, gs->desc?gs->desc:"", gs->lev?gs->lev:""); +} + +void plugsprtv(FILE *f, int fmt) { + struct codecs *co; + char *pv = ""; + + switch(fmt) { + case FMT_HTMLT: + case FMT_HTML: + printf("%s\n", "IcBench
    "); + break; + case FMT_VBULLETIN: + fprintf(f,"[list]\n"); + break; + } + + for(co = codecs; co->coid >= 0; co++) + if(co->coid) { + char name[65],ver[33]; + pv = co->name; + ver[0] = 0; + codver(co->coid, co->ver, ver); + sprintf(name, "%s %c%s", co->name, co->ver?'v':' ', ver); + switch(fmt) { + case FMT_VBULLETIN: + fprintf(f, "[*][URL=\"%s\"]%s[/URL]\n", co->url, name ); + break; + case FMT_HTML : + fprintf(f, "
  • %s\n", co->url, name ); + break; + case FMT_MARKDOWN : + fprintf(f, " - [%s](%s)\n", name, co->url); + break; + default: + fprintf(f, "%-24s\t%s\n", name, co->url ); + } + } + + switch(fmt) { + case FMT_VBULLETIN: + fprintf(f,"[/list]\n"); + break; + case FMT_HTML: + fprintf(f,"
"); + break; + } +} + +//------------------ plugin: process ---------------------------------- +struct plug { + int id,err,blksize,lev; + char *name,prm[17],tms[20]; + int64_t len,memc,memd; + double tc,td; +}; + +struct plug plug[255]; +int seg_ans = 32*1024, seg_huf = 32*1024, seg_anx = 12*1024, seg_hufx=11*1024; +static int cmp = 2,trans; +int verbose=1; +double fac = 1.3; + +int plugins(struct plug *plug, struct plugs *gs, int *pk, unsigned bsize, int bsizex, int lev, char *prm) { + int i,k = *pk; + struct plug *p = &plug[k]; + for(i = 0; i < k; i++) + if(plug[i].id == gs->id && plug[i].lev == lev && !strcmp(plug[i].prm,prm)) + return -1; + memset(p, 0, sizeof(struct plug)); + p->id = gs->id; + p->err = 0; + p->name = gs->name; + p->lev = lev; + strncpy(p->prm, prm?prm:(char *)"", 16); + p->prm[16] = 0; + p->tms[0] = 0; + p->blksize = gs->blksize?gs->blksize:bsize; + *pk = ++k; + return 0; +} + +int plugreg(struct plug *plug, char *cmd, int k, int bsize, int bsizex) { + static char *cempty=""; + int ignore = 0; + + while(*cmd) { + char *name; + while(isspace(*cmd)) + cmd++; + name = cmd; + while(isalnum(*cmd) || *cmd == '_' || *cmd == '-' || *cmd == '.') + cmd++; + if(*cmd) *cmd++ = 0; + + if(!strcmp(name, "ON" )) { + ignore = 1; + continue; + } + else if(!strcmp(name, "OFF")) { + ignore = 0; + continue; + } + + for(;;) { + char *prm; + int lev; + while(isspace(*cmd) || *cmd == ',') + cmd++; + + prm = cmd; + lev = strtol(cmd, &cmd, 10); + if(prm == cmd) { + lev = -1; + prm = cempty; + } + else if(isalnum(*cmd)) { + prm = cmd; + while(isalnum(*cmd) || *cmd == '_' || *cmd == '-' || *cmd == '.') + cmd++; + if(*cmd) + *cmd++ = 0; + } else + prm = cempty; + + { int found = 0; + struct plugs *gs,*gfs = NULL; + if(!*name) + break; + for(gs = plugs; gs->id >= 0; gs++) + if(!strcasecmp(gs->name, name) ) { + char s[33],*q; + sprintf(s,"%d", lev); + found++; + if(lev<0 && gs->lev && !gs->lev[0] || gs->lev && (q=strstr(gs->lev, s)) && (q==gs->lev || *(q-1) == ',')) { + found++; + plugins(plug, gs, &k, bsize, bsizex, lev, prm); + } + break; + } + if((found<2 || !gs->codec) && !ignore) { + if(!found) + fprintf(stderr, "codec '%s' not found\n", name); + else if(!gs->codec) + fprintf(stderr, "codec '%s' not compiled in icbench\n", name); + else if(lev<0) + fprintf(stderr, "level [%s] not specified for codec '%s'\n", gs->lev, name ); + else if(gs->lev && gs->lev[0]) + fprintf(stderr, "level '%d' for codec '%s' not in range [%s]\n", lev, name, gs->lev); + else + fprintf(stderr, "codec '%s' has no levels\n", name); + exit(0); + } + } + + while(isspace(*cmd)) + cmd++; + if(*cmd != ',' && (*cmd < '0' || *cmd > '9')) + break; + } + } + a:plug[k].id = -1; + return k; +} + +//------------------ plugin: print/plot ----------------------------- +struct bandw { + uint64_t bw; + unsigned rtt; + char *s; +}; + +static struct bandw bw[] = { + { 7*KB, 500, "GPRS 56" },//56kbps + { 57*KB, 150, "2G 456" }, + { 125*KB, 40, "3G 1M" }, + { 250*KB, 5, "DSL 2M" },//DSL 2000 + { 500*KB, 20, "4G 4M" }, + { 3750*KB, 5, "WIFI 30M" }, + {12500*KB, 5, "CAB 100M" }, + { 40*MB, 0, "USB2 40MB"}, + { 125*MB, 0, "ETH 1000" }, + { 200*MB, 0, "HDD 200MB"}, + { 550*MB, 0, "SSD 550MB"}, + { 1u*GB, 0, "SSD 1GB" }, + { 2u*GB, 0, "SSD 2GB" }, + { 4ull*GB, 0, "4GB/s" }, + { 8ull*GB, 0, "8GB/s" } +}; +#define BWSIZE (sizeof(bw)/sizeof(struct bandw)) + +void plugprth(FILE *f, int fmt, char *t) { + char *plot = ""; + char *jquery = ""; + char *tstyle = ""; + char *table = ""; + char *code = ""; + char s[128]; + time_t tm; + time(&tm); + sprintf(s, "IcBench: %s - %s", t, asctime(localtime(&tm))); + + switch(fmt) { + case FMT_TEXT: + fprintf(f,"%s\n", s ); + break; + case FMT_VBULLETIN: + fprintf(f,"%s\n", s); + break; + case FMT_HTMLT: + fprintf(f,"IcBench: %s - \n", s); + break; + case FMT_HTML: + fprintf(f,"IcBench: %s - %s%s%s%s%s\n", s, plot, jquery, tstyle, table, code); + break; + case FMT_MARKDOWN: + fprintf(f,"#### %s (bold = pareto) MB=1.000.000\n", s); + break; + } +} + +void plugprtf(FILE *f, int fmt) { + switch(fmt) { + case FMT_HTML: + fprintf(f,"\n"); + break; + } +} + +void plugprtth(FILE *f, int fmt) { + char *head = " C Size ratio%% Bits/Int C MI/s D MI/s Name File (bold = pareto)"; + + switch(fmt) { + case FMT_TEXT: + fprintf(f," C Size ratio%% Bits/Int C MI/s D MI/s Name File\n"); + break; + case FMT_VBULLETIN: + fprintf(f,"[CODE][B]%s[/B] MB=1.000.0000\n", head); + break; + case FMT_HTMLT: + fprintf(f,"
%s MB=1.000.0000\n", head);
+      break;
+    case FMT_HTML:
+      fprintf(f,"

IcBench: Compressor Benchmark

\n"); + break; + case FMT_MARKDOWN: + fprintf(f,"|C Size|ratio%%|Bits/Integer|C MI/s|D MI/s|Name|File|\n|--------:|-----:|--------:|--------:|----------------|----------------|\n"); + break; + case FMT_CSV: + fprintf(f,"size,csize,ratio,bpi,ctime,dtime,name,file\n"); + break; + case FMT_TSV: + fprintf(f,"size\tcsize\tratio\tbpi\tctime\tdtime\tname\tfile\n"); + break; + case FMT_SQUASH: + fprintf(f,"dataset,plugin,codec,level,compressed_size,compress_cpu,compress_wall,decompress_cpu,decompress_wall\n"); + break; + } +} + +void plugprttf(FILE *f, int fmt) { + switch(fmt) { + case FMT_VBULLETIN: + fprintf(f,"[/CODE]\n"); + break; + case FMT_HTMLT: + fprintf(f,"\n"); + break; + case FMT_HTML: + fprintf(f,"
C Sizeratio%%C MI/sD MI/sNameC MemD MemFile
\n"); + break; + case FMT_MARKDOWN: + fprintf(f,"\n\n"); + break; + } +} + +#define RATIO(_clen_, _len_) ((double)_clen_*100.0/_len_) +#define RATIOI(_clen_, _len_) ((double)_clen_*32.0/_len_) +#define FACTOR(_clen_, _len_) ((double)_len_*100.0/(double)_clen_) +#define RATIOF(_clen_, _len_, _mode_) _mode_?FACTOR(_clen_, _len_):RATIO(_clen_, _len_) +int be_factor=0; +void plugprt(struct plug *plug, int64_t totinlen, char *finame, int fmt, FILE *f) { + double ratio = RATIOF(plug->len,totinlen, be_factor), + ratioi = RATIOI(plug->len,totinlen), + tc = TMBS(totinlen,plug->tc), td = TMBS(totinlen,plug->td); + char name[65]; + int c = 0, d = 0, n = 0; + if(plug->lev >= 0) + sprintf(name, "%s%s %d%s", plug->err?"?":"", plug->name, plug->lev, plug->prm); + else + sprintf(name, "%s%s%s", plug->err?"?":"", plug->name, plug->prm); + + switch(fmt) { + case FMT_TEXT: + fprintf(f,"%12"PRId64" %5.1f %5.2f %8.2f %8.2f %-16s%s\n", + plug->len, ratio, ratioi, tc, td, name, finame); + break; + case FMT_VBULLETIN: + fprintf(f, "%12"PRId64" %5.1f %5.2f %s%8.2f%s %s%8.2f%s %s%-16s%s%s\n", + plug->len, ratio, ratioi, c?"[B]":"", tc, c?"[/B]":"", d?"[B]":"", td, d?"[/B]":"", n?"[B]":"", name, n?"[/B]":"", finame); + break; + case FMT_HTMLT: + fprintf(f, "%12"PRId64" %5.1f %5.2f %s%8.2f%s %s%8.2f%s %s%-16s%s%s\n", + plug->len, ratio, ratioi, c?"":"", tc, c?"":"", d?"":"", td, d?"":"", n?"":"", name, n?"":"", finame); + break; + case FMT_HTML: + fprintf(f, "%11"PRId64"%5.1f%5.2f%s%8.2f%s%s%8.2f%s%s%-16s%s%"PRId64"%"PRId64"%s\n", + plug->len, ratio, ratioi, c?"":"", tc, c?"":"", d?"":"", td, d?"":"", n?"":"", name, n?"":"", +// SIZE_ROUNDUP(plug->memc, Kb)/Kb, SIZE_ROUNDUP(plug->memd,Kb)/Kb, + plug->memc, plug->memd, + finame); + break; + case FMT_MARKDOWN: + fprintf(f, "|%"PRId64"|%5.1f|%5.2f|%s%.2f%s|%s%.2f%s|%s%s%s|%s|\n", + plug->len, ratio, ratioi, c?"**":"", tc, c?"**":"", d?"**":"", td, d?"**":"", n?"**":"", name, n?"**":"", finame); + break; + case FMT_CSV: + fprintf(f, "%12"PRId64",%11"PRId64",%5.1f,%5.2f,%8.2f,%8.2f,%-16s,%s\n", + totinlen, plug->len, ratio, ratioi, tc, td, name, finame); + break; + case FMT_TSV: + fprintf(f,"%12"PRId64"\t%11"PRId64"\t%5.1f\t5.2f\t%8.2f\t%8.2f\t%-16s\t%s\n", + totinlen, plug->len, ratio, ratioi, tc, td, name, finame); + break; + case FMT_SQUASH: + fprintf(f,"%12"PRId64",%11"PRId64",%5.1f,%8.2f,%8.2f,%-16s,%s\n", + finame, name, name, plug->len, tc, tc, td, td); + break; + } +} + +static int blknum, speedup; +enum { SP_SPEEDUPC=1, SP_SPEEDUPD, SP_TRANSFERC, SP_TRANSFERD }; + +void plugprtph(FILE *f, int fmt) { + int i; + + switch(fmt) { + case FMT_HTML: + fprintf(f,"

IcBench: Speedup %s sheet

", (speedup&1)?"compression":"decompression"); + for(i = 0; i < BWSIZE; i++) + fprintf(f, "", bw[i].s); + fprintf(f, "\n"); + break; + case FMT_MARKDOWN: + fprintf(f,"#### IcBench: Speedup %s sheet\n\n", (speedup&1)?"compression":"decompression"); + fprintf(f, "|Name"); + for(i = 0; i < BWSIZE; i++) + fprintf(f, "|%s", bw[i].s); + fprintf(f, "|File"); + if(blknum) + fprintf(f, " blknum=%d ", blknum); + fprintf(f, "|\n"); + fprintf(f, "|-------------"); + for(i = 0; i < BWSIZE; i++) + fprintf(f, "|---------:"); + fprintf(f, "|-------------|\n"); + break; + case FMT_VBULLETIN: + fprintf(f,"IcBench: Speedup %s sheet\n\n", (speedup&1)?"compression":"decompression"); + fprintf(f,"[CODE][B]\n"); + default: + fprintf(f,"Name "); + for(i = 0; i < BWSIZE; i++) + fprintf(f, "%10s", bw[i].s); + if(blknum) + fprintf(f, " blknum=%d ", blknum); + fprintf(f, "\n"); + if(fmt == FMT_VBULLETIN) + fprintf(f,"[/B]\n"); + } +} + +static inline double spmbs(double td, int64_t len, int i, int64_t totinlen) { + double t = td + len*TM_T/(double)bw[i].bw + blknum*(bw[i].rtt*1000.0); + return TMBS(totinlen,t); +} + +//static inline double spdup(double td, int64_t len, int i, int64_t totinlen) { double t = td + len*TM_T/(double)bw[i].bw + blknum*(bw[i].rtt*1000.0); return ((double)totinlen*TM_T*100.0/t)/(double)bw[i].bw;} +static inline double spdup(double td, int64_t len, int i, int64_t totinlen) { + return (double)totinlen*100.0 / ((double)len + ((td+blknum*bw[i].rtt*1000.0)/TM_T)*(double)bw[i].bw ); +} + +void plugprtp(struct plug *plug, int64_t totinlen, char *finame, int fmt, int speedup, FILE *f) { + int i; + char name[65]; + if(plug->lev>=0) + sprintf(name, "%s%s%s%d%s", plug->err?"?":"", plug->name, fmt==FMT_MARKDOWN?"_":" ", plug->lev, plug->prm); + else + sprintf(name, "%s%s%s", plug->err?"?":"", plug->name, plug->prm); + if(fmt == FMT_HTML) + fprintf(f, "", name); + else + fprintf(f, "%-16s", name); + + for(i = 0; i < BWSIZE; i++) { + switch(fmt) { + case FMT_HTMLT: + case FMT_HTML: + fprintf(f, ""); + break; + case FMT_MARKDOWN: + break; + } + } + switch(fmt) { + case FMT_HTMLT: + case FMT_HTML: + fprintf(f, "\n", finame); + break; + case FMT_MARKDOWN: + fprintf(f, "|%s|\n", finame); + break; + default: + fprintf(f, "%s\n", finame); + break; + } +} + +struct { unsigned x,y; } divplot[] = { + { 1920, 1080}, // 16:9 + { 1600, 900}, + { 1280, 720}, + { 800, 600} +}; + +static unsigned divxy = 1, xlog = 1, xlog2, ylog, ylog2, plotmcpy; + +void plugplotb(FILE *f, int fmt, int idiv) { + fprintf(f, "
\n", + s, (speedup&1)?"Compression":"Decompression", xlog?"log":"", xlog?"type: 'log',\n":"", ylog?"type: 'log',\n":""); +} + +int libcmp(const struct plug *e1, const struct plug *e2) { + if(e1->len < e2->len) + return -1; + else if(e1->len > e2->len) + return 1; + else if(e1->td < e2->td) + return -1; + else if(e1->td > e2->td) + return 1; + return 0; +} + +int libcmpn(const struct plug *e1, const struct plug *e2) { + int c = strcmp(e1->name, e2->name); + if(c < 0) + return -1; + else if(c > 0) + return 1; + else if(e1->lev < e2->lev) + return -1; + else if(e1->lev > e2->lev) + return 1; + return 0; +} + +#define P_MCPY 1 // memcpy id +void plugplotc(struct plug *plug, int k, int64_t totinlen, int fmt, int speedup, char *s, FILE *f) { + int i, n = 0; + char name[65],txt[256]; + struct plug *g,*gs=plug,*p; + qsort(plug, k, sizeof(struct plug), (int(*)(const void*,const void*))libcmpn); + + for(txt[0] = name[0] = 0, g = plug; g < plug+k; g++) + if(g->id <= P_MCPY && !plotmcpy) + continue; + else { + if(strcmp(g->name, name)) { + if(name[0]) { + fprintf(f, "],\ny: ["); + for(p = gs; p < g; p++) + fprintf(f, "%.2f%s", RATIOF(p->len,totinlen, be_factor), p+1name); + fprintf(f, "var %s = {\n x: [", g->name); + strcat(s, g->name); + } else { + fprintf(f, ","); + strcat(txt, ","); + } + if(g->lev >= 0) { + char ts[33]; + sprintf(ts, "'%s%s%d%s'", divxy>=2?"":g->name, divxy>=2?"":",", g->lev, g->prm); + strcat(txt, ts); + } + { double t = (speedup&1)?g->tc:g->td; fprintf(f, "%.2f", TMBS(totinlen,t)); } + } + fprintf(f, "],\ny: ["); + for(p = gs; p < g; p++) + fprintf(f, "%.2f%s", RATIOF(p->len,totinlen, be_factor), p+1\n", + s, (speedup&1)?"Compression":"Decompression", xlog2?"log":"", xlog2?"type: 'log',\n":"", ylog2?"type: 'log',\n":""); +} + +int plugprts(struct plug *plug, int k, char *finame, int xstdout, uint64_t totlen, int fmt, char *t) { + struct plug *g; + char s[257]; + FILE *fo; + if(!totlen) return 0; if(verbose>1) printf("'%s'\n", finame); + + qsort(plug, k, sizeof(struct plug), (int(*)(const void*,const void*))libcmp); + sprintf(s, "%s.%s", finame, fmtext[fmt]); + fo = xstdout>=0?stdout:fopen(s, "w"); + if(!fo) + die("file create error for '%s'\n", finame); + + plugprth( fo, fmt, t); + plugprtth(fo, fmt); + for(g = plug; g < plug+k; g++) + plugprt(g, totlen, finame, fmt, fo); + plugprttf(fo, fmt); + + if(speedup) { + switch(fmt) { + case FMT_TEXT : + fprintf(fo, "\n"); + break; + case FMT_HTML : + break; + case FMT_HTMLT: + fprintf(fo, "
\n");
+        break;
+      case FMT_MARKDOWN :
+        fprintf(fo, "\n");
+        break;
+    }
+    plugprtph(fo, fmt);
+    for(g = plug; g < plug+k; g++)
+      plugprtp(g, totlen, finame, fmt, speedup, fo);
+    fprintf(fo, "\n");
+    switch(fmt) {
+      case FMT_TEXT :
+        fprintf(fo, "\n"); break;
+      case FMT_HTML :
+        fprintf(fo, "
Name%sFile"); + if(blknum) + fprintf(f, " blknum=%d ", blknum); + fprintf(f, "
%s"); + break; + case FMT_MARKDOWN: + fprintf(f, "|"); + break; + } + switch(speedup) { + case SP_TRANSFERD: + fprintf(f,"%9.3f ", spmbs(plug->td, plug->len, i, totinlen)); + break; + case SP_SPEEDUPD: + fprintf(f,"%9d ", (int)(spdup(plug->td, plug->len, i, totinlen)+0.5)); + break; + case SP_TRANSFERC: + fprintf(f,"%9.3f ", spmbs(plug->td, plug->len, i, totinlen)); + break; + case SP_SPEEDUPC: + fprintf(f,"%9d ", (int)(spdup(plug->td, plug->len, i, totinlen)+0.5)); + break; + } + switch(fmt) { + case FMT_HTMLT: + case FMT_HTML: + fprintf(f, "%s
\n"); break; + case FMT_HTMLT: + fprintf(fo, "
\n"); + break; + case FMT_VBULLETIN: + fprintf(fo,"[/CODE]\n"); + break; + case FMT_MARKDOWN : + fprintf(fo, "\n"); + break; + } + if(fmt == FMT_HTML) { + char s[1025]; + s[0] = 0; if(verbose>1) printf("generate speedup plot\n"); + plugplotb(fo, fmt, 1); + for(g = plug; g < plug+k; g++) + if(g->id > P_MCPY || plotmcpy) + plugplot(g, totlen, fmt, speedup, s, fo); + plugplote(fo, fmt, s); + + s[0] = 0; if(verbose>1) printf("generate speed/ratio plot\n"); + plugplotb(fo, fmt, 2); + plugplotc(plug, k, totlen, fmt, speedup, s, fo); + plugplotce(fo, fmt, s); + + } + } + plugprtf(fo, fmt); + if(xstdout<0) fclose(fo); +} + +int plugread(struct plug *plug, char *finame, int64_t *totinlen) { + char s[256],name[33]; + struct plug *p=plug; + FILE *fi = fopen(finame, "r"); + if(!fi) return -1; + + fgets(s, 255, fi); + for(p = plug;;) { + char ss[256],*t = ss,*q; + int i; + memset(p, 0, sizeof(p[0])); + p->tms[0] = 0; + if(!fgets(ss, 255, fi)) break; + for(q = t; *q && *q != '\t'; q++); *q++ = 0; strcpy(s, t); t = q; + *totinlen = strtoull(t, &t, 10); + p->len = strtoull(++t, &t, 10); + p->td = strtod( ++t, &t); + p->tc = strtod( ++t, &t); + for(q = ++t; *q && *q != '\t'; q++); *q++ = 0; strcpy(name,t); t=q; + p->lev = strtoul(t, &t, 10); + for(q = t; *q && *q != '\t'; q++); *q++ = 0; strcpy(p->prm,t); t = q; + p->memc = strtoull(t, &t, 10); + p->memd = strtoull(++t, &t, 10); + for(q = ++t; *q && *q != '\t'; q++); *q++ = 0; strcpy(p->tms,t); t = q; + if(p->prm[0]=='!') + p->prm[0]=0; + for(i = 0; plugs[i].id >=0; i++) + if(!strcmp(name, plugs[i].name)) { + p->name = plugs[i].name; + p->id = plugs[i].id; if(verbose>1) { fprintf(stdout, "%s\t%"PRId64"\t%"PRId64"\t%.6f\t%.6f\t%s\t%d%s\t%s\t%"PRId64"\t%"PRId64"\n", s, *totinlen, p->len, p->td, p->tc, p->name, p->lev, p->prm, p->tms, p->memc, p->memd); fflush(stdout); } + p++; + break; + } + } + fclose(fi); + return p - plug; +} + +//----------------------------------- Benchmark ----------------------------------------------------------------------------- +static int be_mcpy, be_nblocks, fuzz; +int be_mindelta=-1,mdelta=0; + +int checksort(unsigned *in, unsigned n) { + if((be_mindelta == 0 || be_mindelta == 1) && !be_nblocks) { + int i; + for(i = 1; i < n/4; i++) + if(in[i] < in[i-1]+be_mindelta) { + fprintf(stderr, "WARNING: IDs not sorted %d:%u,%u\n", i, in[i-1], in[i]);fflush(stderr); + return -1; + } + } + return 0; +} +unsigned becomp(unsigned char *_in, unsigned _inlen, unsigned char *_out, unsigned outsize, unsigned bsize, int id, int lev, char *prm, int be_mindelta, CODCOMP codcomp) { + unsigned char *op,*oe = _out + outsize; + unsigned char *in,*ip; + if(!_inlen) return 0; + TMBEG(tm_rep,tm_Rep); + for(op = _out, in = _in; in < _in+_inlen; ) { + unsigned inlen = _inlen,bs; + if(be_nblocks) { blknum++; + inlen = ctou32(in); in+=4; + vbput32(op, inlen); // ctou32(op) = inlen; op+=4; + inlen *= 4; if(in+inlen>_in+_inlen) die("FATAL buffer overflow error %d", in - _inlen); + } + + for(ip = in, in += inlen; ip < in; ) { + unsigned iplen = in - ip; iplen = min(iplen, bsize); // cnt++; csize += iplen; + op = codcomp(ip, iplen, op, oe-op, id, lev, prm, be_mindelta); + ip += iplen; + if(op > _out+outsize) + die("Compress overflow error %llu, %u in lib=%d\n", outsize, (int)(ptrdiff_t)(op - _out), id); + } + } + TMEND(_inlen); // printf("cnt=%d, csize=%d\n", cnt, csize); + return op - _out; +} + +int bedecomp(unsigned char *_in, int _inlen, unsigned char *_out, unsigned _outlen, unsigned bsize, int id, int lev, char *prm, int be_mindelta, CODDECOMP coddecomp) { + unsigned char *ip; + unsigned char *out,*op; + + TMBEG(tm_rep2,tm_Rep2); + for(ip = _in, out = _out; out < _out+_outlen;) { + unsigned outlen=_outlen,bs; + if(be_nblocks) { + vbget32(ip, outlen); //outlen = ctou32(ip); ip += 4; + ctou32(out) = outlen; out += 4; + outlen *= 4; if(out+outlen >_out+_outlen) die("FATAL: decompress overflow output error %d ", outlen); + } + for(op = out, out += outlen; op < out; ) { + unsigned oplen = out - op; + oplen = min(oplen, bsize); + ip = coddecomp(ip, 0, op, oplen, id, lev, prm, be_mindelta); if(ip-_in>_inlen) die("FATAL inlen %d,%d,bsize=%d ", _inlen, ip-_in, bsize); + op += oplen; + } + } + if(!(ip - _in)) + return 0; + TMEND(_outlen); + return ip - _in; +} + +struct plug plugr[32]; +int tid; +#define BEPRE +#define BEINI +#define BEPOST +#define BEOPT +#define BEUSAGE +#define BEFILE +#define BENCHSTA + +#define INOVD 4*1024 + + #if defined(_WIN32) && !defined(__MINGW__) +int getpagesize() { + static int pagesize = 0; + if (pagesize == 0) { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + pagesize = max(system_info.dwPageSize, system_info.dwAllocationGranularity); + } + return pagesize; +} + #endif + +struct cod { CODCOMP comp; CODDECOMP decomp; }; +struct cod cods[] = { { codcomp, coddecomp }, {codcomps, coddecomps }, {codcompz, coddecompz } }; + +unsigned mininlen; +uint64_t filen; +size_t insizem; +char name[65]; + +uint64_t plugbench(struct plug *plug, unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, + unsigned char *_cpy, unsigned bsize, struct plug *plugr, int tid, char *finame) { + double tc = 0.0, td = 0.0; + int be_mode = be_mindelta<0?0:(be_mindelta>1?2:1); + unsigned outlen = becomp(in, inlen, out, outsize, bsize, plug->id, plug->lev, plug->prm, be_mindelta, cods[be_mode].comp); + plug->len += outlen; + plug->tc += (tc += (double)tm_tm/(double)tm_rm); + if(!outlen) plug->tc = 0; + if(outlen && verbose /*&& inlen == filen*/) { printf("%12u %5.1f %5.2f %8.2f ", outlen, RATIOF(outlen,inlen, be_factor), RATIOI(outlen,inlen), TMBS(inlen,tc)); fflush(stdout); } + if(cmp && outlen) { + unsigned char *cpy = _cpy; + unsigned cpylen,e; + if(_cpy != in) memrcpy(cpy, in, inlen); + cpylen = bedecomp(out, outlen, cpy, inlen, bsize, plug->id, plug->lev, plug->prm, be_mindelta, cods[be_mode].decomp); + td = (double)tm_tm/(double)tm_rm; if(verbose /*&& inlen == filen*/) { printf("%8.2f %c%-16s%s\n", TMBS(inlen,td), outlen?' ':'?',name, finame); } + e = memcheck(in, inlen, cpy, cmp); + plug->err = plug->err?plug->err:e; + plug->td += td; + } else if(outlen && verbose /*&& inlen == filen*/) { printf("%8.2f %c%-16s%s\n", 0.0, outlen?' ':'?', name, finame); } + if(!plug->len) plug->err++; + return outlen; +} + +//--------------------------------------- Zipfian generator -------------------------------------------------------- +double a = 1.5; + unsigned xbits[33]; +void stprint(char *s) { + int m; + uint64_t t=0; + for(m = 0; m < 33; m++) + t += xbits[m]; + printf("\n%s bits histogram:",s); + for(m = 0; m < 33; m++) + if(xbits[m]) printf("%d:%.2f%% ", m, (double)xbits[m]*100/t); printf("\n"); +} + +int dcmp(double *a, double *b) { + if(*a < *b) return -1; + if(*a > *b) return 1; + return 0; +} + +void zipfgen(unsigned *a, unsigned n, double alpha, unsigned x1, unsigned x2) { + int i; + unsigned m = x2 - x1 + 1; + double prob, cum, *zmap; + if(!(zmap = malloc(m*sizeof(zmap[0])))) die("mallo error %d\n", m); + + // generate initial sample (slow) + srand48(1); + if(alpha > 0) { + for(cum = 0.0,i = 0; i < m; i++) + cum += 1.0 / pow(i+1, alpha); + cum = 1.0 / cum; + for(zmap[0] = prob = cum,i = 1; i < m; i++) zmap[i] = (prob += (cum / pow(i+1, alpha))); + } else for(i = 0; i < m; i++) zmap[i] = 1.0 / m; + + // use binary search to speed up zipfgen + qsort(zmap, m, sizeof(zmap[0]), (int(*)(const void*,const void*))dcmp); + for(i = 0; i < n; i++) { + double r = drand48(); + int l = 0, h = m-1; + while(l < h) { + int k = (l + h) >> 1; + if(r >= zmap[k]) l = k + 1; + else h = k; + } + a[i] = x1 + l; + } + free(zmap); +} + +// 0 1 2 3 4 5 6 7, 8 +enum { T_0, T_UINT8, T_UINT16, T_UINT24, T_UINT32, T_UINT40, T_UINT48, T_UINT56, T_UINT64, T_CHAR, T_TXT, T_TST }; +int mdelta; +unsigned rm=0,rx=255; +#define OVD (10*MB) +#define IPUSH(in,n,isize, nmax,u) { if(n >= nmax) { nmax = nmax?(nmax << 1):(1<<20); in = realloc(in, nmax*isize+OVD); if(!in) die("malloc err=%u", nmax); }\ + ctou32(in+n*isize) = u; n++; if(verbose>5) printf("%u,",(unsigned)u );\ + } +unsigned befgen(unsigned char **_in, unsigned n, int fmt, unsigned isize, FILE *fi, int kid, int skiph, int decs, int divs) { + unsigned char *in = *_in,*ip; + unsigned nmax = 0; + #define LSIZE 1024 + char s[LSIZE+1]; + double pre; + + if(!fi) { printf("zipf alpha=%.2f range[%u..%u].n=%u\n ", a, rm, rx, n); + in = malloc(n*isize+OVD); if(!in) die("malloc err=%u", nmax); + + zipfgen((unsigned *)in, n, a, rm, rx); //{ int i; for(i = 0; i < n; i++) in[i] = i; } + int i;for(i = 1; i <= n; i++) xbits[bsr32(ctou32(in+i*4))]++; + if(be_mindelta == 0 || be_mindelta == 1) { + unsigned *ip = (unsigned *)in, v; stprint("delta"); + for(ip[0]=0,v = 1; v < n; v++) { + ip[v] += ip[v-1] + be_mindelta; if(ip[v]>=(1u<<31)) die("overflow generating sorted array %d\n", ip[v]); + } + } else stprint(""); + *_in = in; + return n*isize; + } + + n = 0; //printf("fmt=%d,", fmt);fflush(stdout); + if(skiph) { + fgets(s, LSIZE, fi); if(verbose>5) printf("skip first line\n"); + } + pre = decs?pow(10.0f,(float)decs):1; + pre /= divs; + switch(fmt) { + + case T_TXT: if(verbose) printf("reading text file\n"); + + while(fgets(s, LSIZE, fi)) { + unsigned char *p = s,*q; + int k; + s[strlen(s) - 1] = 0; + for(k = 0; *p; ) { + uint64_t u; + while(*p && (*p < '0' || *p > '9') ) *p++; + u = strtoull(p, &q, 10) - mdelta; + if(*q == '.') { + u = round(strtod(p, &q)*pre) - mdelta; + } + p = q; + if(++k == kid) { + IPUSH(in,n,isize,nmax,u); + break; + } + while(*p && (*p >= '0' && *p <= '9' || *p == '.') ) *p++; + } + } + break; + case T_CHAR: + for(;;) { + char *p = s,*q; + int c; + uint64_t u; + while((c = getc(fi)) >= '0' && c <= '9') + if(p - s < LSIZE) *p++ = c; + *p = 0; + u = strtoull(s, &p, 10) - mdelta; + if(*p == '.') + u = round(strtod(s, &q)*pre) - mdelta; + IPUSH(in,n,isize,nmax,u); + if(c == EOF) break; + } + break; + case T_UINT8: { + unsigned char u; + while(fread(&u, 1, 1, fi)>0) + IPUSH(in,n,isize,nmax, u-mdelta); + } break; + case T_UINT16: { + unsigned short u; + while(fread(&u, sizeof(u), 1, fi)>0) + IPUSH(in,n,isize,nmax, u-mdelta); + } break; + /*case T_DBL: + double d,*din = NULL; n=0; + while(fread(&u, sizeof(u), 1, fi)>0) + IPUSH(din,n,isize,nmax, d); + }*/ + /*case T_UINT32: { + unsigned u; + while(fread(&u, sizeof(u), 1, fi)>0) + IPUSH(in,n,isize,nmax, u-mdelta); + } break;*/ + default: die("unknown data format %d\n", fmt); + } + *_in = in; + return n*isize; +} + +void usage(char *pgm) { + fprintf(stderr, "\nIcBench Copyright (c) 2013-2019 Powturbo %s\n", __DATE__); + fprintf(stderr, "Usage: %s [options] [file]\n", pgm); + fprintf(stderr, " -eS S = compressors/groups separated by '/' Parameter can be specified after ','\n"); + fprintf(stderr, " -b#s # = blocksize (default filesize,). max=1GB\n"); + fprintf(stderr, " -B#s # = max. benchmark filesize (default 1GB) ex. -B4G\n"); + fprintf(stderr, " -s#s # = min. buffer size to duplicate & test small files (ex. -s50)\n"); + fprintf(stderr, " s = modifier s:K,M,G=(1000, 1.000.000, 1.000.000.000) s:k,m,h=(1024,1Mb,1Gb). (default m) ex. 64k or 64K\n"); + fprintf(stderr, "Benchmark:\n"); + fprintf(stderr, " -i#/-j# # = Minimum de/compression iterations per run (default=auto)\n"); + fprintf(stderr, " -I#/-J# # = Number of de/compression runs (default=3)\n"); + fprintf(stderr, " -t# # = min. time in seconds per run.(default=1sec)\n"); + fprintf(stderr, " -S# Sleep # min. after 2 min. processing mimizing CPU trottling\n"); + fprintf(stderr, " t = M:millisecond s:second m:minute h:hour. ex. 3h\n"); + fprintf(stderr, " -D No process real-time priority setting\n"); + fprintf(stderr, "Check:\n"); + fprintf(stderr, " -C# #=0 compress only, #=1 ignore errors, #=2 exit on error, #=3 crash on error\n"); + fprintf(stderr, " -f[X[c][H]][.d][s] X = file format:\n"); + fprintf(stderr, " [1=int8], [2=int16], [4=int32(default)], [f:float] [d:double]\n"); + fprintf(stderr, " t = text:one integer per line, c=column number in multiple columns line\n"); + fprintf(stderr, " c = text:integers separated by non digit char\n"); + fprintf(stderr, " . = decimal digits (default 2)\n"); + fprintf(stderr, " H = skip first line\n"); + fprintf(stderr, " s = sorted (increasing), S=sorted (strictly increasing, no duplicates), z=ZigZag\n"); +// fprintf(stderr, " -z# check reading/writing outside bounds: #=1 compress, #=2 decompress, #3:both\n"); + fprintf(stderr, "Output:\n"); + fprintf(stderr, " -v# # = verbosity 0..3 (default 1)\n"); + fprintf(stderr, " -l# # = 1 : print all groups/plugins, # = 2 : print all codecs\n"); + fprintf(stderr, " -S# Plot transfer speed: #=1 Comp speedup #=2 Decomp speedup #=3 Comp 'MI/s' #=4 Decomp 'MI/s'\n"); + fprintf(stderr, " -p# #='print format' 1=text 2=html 3=htm 4=markdown 5:vBulletin 6:csv(comma) 7=tsv(tab)\n"); + fprintf(stderr, " -Q# # Plot window 0:1920x1080, 1:1600x900, 2:1280x720, 3:800x600 (default=1)\n"); + fprintf(stderr, " -g -g:no merge w/ old result 'file.tbb', -gg:process w/o output (use for fuzzing)\n"); + fprintf(stderr, " -o print on standard output\n"); + fprintf(stderr, " -G plot memcpy\n"); + fprintf(stderr, " -1 Plot Speedup linear x-axis (default log)\n"); + fprintf(stderr, " -3 Plot Ratio/Speed logarithmic x-axis (default linear)\n"); + fprintf(stderr, "Multiblock (0=number of integers followed by integer array):\n"); + fprintf(stderr, " -Moutput concatenate all input files to multiple blocks file output\n");\ + fprintf(stderr, " -r process multiple blocks per file (ex. gov2.sorted).\n"); + fprintf(stderr, "----- arg. ZIPF specified --------------\n"); + fprintf(stderr, " -aF F = zipfian distribution alpha ex. -a1.0 uniform -a1.5 skewed\n"); + fprintf(stderr, " -mNs N = minimum number. s=(k,K, m,M, g,G\n"); + fprintf(stderr, " -MNs N = maximum number\n"); + fprintf(stderr, " -nNs N = number of integers to generate\n"); + fprintf(stderr, "Ex. ./icbench -a1.5 -m0 -M255 -n100M ZIPF\n"); + BEUSAGE; + fprintf(stderr, "ex. ./icbench file -eVBYTE/turbopfor ZIPF\n"); + fprintf(stderr, "ex. ./icbench -eTurboPFor -fS -r gov2.sorted\n"); + fprintf(stderr, "ex. ./icbench -eTurboPFor -fS -ft3.1H ratings.csv \n"); + exit(0); +} + +struct plug pluga[255]; + +void printfile(char *finame, int xstdout, int fmt, char *rem) { + int64_t totinlen; + int k = plugread(plug, finame, &totinlen); + char *p, s[256]; + if(k < 0) + die("file open error for '%s'\n", finame); + if(!k) return; + strncpy(s, finame, 255); + s[255]=0; + if((p = strrchr(s,'.')) && !strcmp(p, ".tbb")) + *p=0; + plugprts(plug, k, s, xstdout, totinlen, fmt, rem); +} + +int be_rand=1; +void ftest(struct plug *plug, unsigned k,unsigned n, unsigned bsize) { + unsigned *in,*cpy,b,i; + unsigned char *out; + char s[33]; + + if(!n) + n = 25000000; + in = malloc(n*4+OVD); if(!in) die("malloc err=%u", n*4); + out = malloc(n*5+OVD); if(!out) die("malloc err=%u", n*5); + cpy = malloc(n*4+OVD); if(!cpy) die("malloc err=%u", n*4); + s[0] = 0; printf("bittest: %u-%u, n=%u\n", rm, rx, n); fflush(stdout); + for(b = rm; b <= min(rx,64); b++) { + struct plug *p; + srand(time(NULL)); sprintf(s,"b=%d", b); + for(i = 0; i < n; i++) in[i] = be_rand?(rand()&((1ull << b)-1)):((1ull << b)-1); + in[n-1] = ((1ull << b)-1); + if(be_mindelta == 0 || be_mindelta == 1) + for(in[0]=0,i = 1; i < n; i++) { + uint64_t v = (uint64_t)in[i-1] + in[i] + be_mindelta; if(v >= (1ull<<32)) die("overflow generating sorted array at %d,%x+%x->v=%llx\n", i, in[i], in[i-1], v ); + in[i] = v; + } + for(p = plug; p < plug+k; p++) { + unsigned pbsize = p->blksize?p->blksize:bsize,outlen; + if(p->lev >= 0) + sprintf(name, "%s %d%s", p->name, p->lev, p->prm); + else + sprintf(name, "%s%s", p->name, p->prm); + + codini(n, p->id); + if(be_mindelta >= 0) + pbsize += 4; // start stored w. variable byte for delta coding + p->len = p->tc = p->td = p->err = 0; sprintf(s, "%d, %d", b, pbsize/4); + outlen = plugbench(p, in, n*4, out, n*5, cpy, pbsize, plugr,tid, s); + if(!outlen) die("Codec error or codec not available %d\n", outlen); + } + } +} + +#define TEST64 + #ifdef TEST64 + +#define R64 ((uint64_t)rand()) +#define RND64 ( (R64<<60) ^ (R64<<45) ^ (R64<<30) ^ (R64<<15) ^ (R64<<0) ) +#define NN (4*1024*1024) + +//uint64_t in[NN+256],cpy[NN+256]; +uint64_t _in[NN+256],_cpy[NN+256]; +unsigned char out[NN*16]; + +void vstest64(int id, int rm,int rx, unsigned n) { + unsigned b,i; fprintf(stderr,"64 bits test.id=%d n=%d [%d-%d] bits", id, n, rm, min(rx,64)); + uint64_t *in = _in,*cpy = _cpy; + if(n > NN) n = NN; //if(id==5) n = 128; + for(b = rm; b <= min(rx,64); b++) { + uint64_t start = 0, msk = b==64?0xffffffffffffffffull:(((uint64_t)1 << b)-1); + unsigned char *op; fprintf(stderr,"\nb=%d:", b); + for(i = 0; i < n; i++) { + in[i] = be_rand?(RND64&msk)>>(rand() & 3):msk; //(/*start +=*/ RND64 & msk); + //fprintf(stderr, "%llx,", in[i]); + if(bsr64(in[i]) > b) die("Fatal error at b=%d ", b); + } //fprintf(stderr,"\n"); + in[0] = msk; + in[n-1] = msk; + switch(id) { + case 0: fprintf(stderr,"vbenc64 "); op = vbenc64( in, n, out); break; + case 1: fprintf(stderr,"bitpack64 "); op = bitpack64( in, n, out, b);break; + case 2: fprintf(stderr,"bitnpack64 "); op = out+bitnpack64( in, n, out); break; + case 3: fprintf(stderr,"bitnpack128v64 "); op = out+bitnpack128v64(in, n, out); break; + case 4: fprintf(stderr,"p4nenc64 "); op = out+p4nenc64( in, n, out); break; + case 5: fprintf(stderr,"p4nenc128v64 "); op = out+p4nenc128v64( in, n, out); break; + case 6: fprintf(stderr,"vsenc64 "); op = vsenc64( in, n, out); break; + case 7: fprintf(stderr,"bitndpack64 "); op = out+bitndpack64( in, n, out); break; + case 8: fprintf(stderr,"bitnd1pack64 "); op = out+bitnd1pack64( in, n, out); break; + case 9: fprintf(stderr,"bitnzpack64 "); op = out+bitnzpack64( in, n, out); break; + case 10: fprintf(stderr,"vbzenc64 "); op = vbzenc64( in, n, out, 0);break; + case 11: fprintf(stderr,"p4nzenc64 "); op = out+p4nzenc64( in, n, out); break; + default: die("Fatal error: function %d not found\n", id); + //case 5: op = efanoenc64(in, n, out, 0); break; + } + fprintf(stderr,"%d %.2f%% ", (int)(op-out), ((double)(op-out)*100.0)/(double)(n*8)); if(op-out>sizeof(out)) die("vstest64:Overflow %d\n", op-out); + memrcpy(cpy, in, n*sizeof(in[0])); + switch(id) { + case 0: vbdec64( out, n, cpy); break; + case 1: bitunpack64( out, n, cpy, b);break; + case 2: bitnunpack64( out, n, cpy); break; + case 3: bitnunpack128v64(out, n, cpy); break; + case 4: p4ndec64( out, n, cpy); break; + case 5: p4ndec128v64( out, n, cpy); break; + case 6: vsdec64( out, n, cpy); break; + case 7: bitndunpack64( out, n, cpy); break; + case 8: bitnd1unpack64( out, n, cpy); break; + case 9: bitnzunpack64( out, n, cpy); break; + case 10: vbzdec64( out, n, cpy, 0);break; + case 11: p4nzdec64( out, n, cpy); break; + //case 5: efanodec64( out, n, cpy, 0); break; + } + for(i = 0; i < n; i++) { + if(in[i] != cpy[i]) { + fprintf(stderr, "Error b=%d at '%d' (in=%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx cpy=%llx,%llx,%llx,%llx,%llx,%llx,%llx,%llx, out=%x,%x,%x,%x,%x,%x,%x,%x)", b, i, + in[i], in[i+1], in[i+2], in[i+3], in[i+4], in[i+5], in[i+6], in[i+7], + cpy[i], cpy[i+1], cpy[i+2],cpy[i+3],cpy[i+4],cpy[i+5],cpy[i+6],cpy[i+7], + out[i], out[i+1], out[i+2],out[i+3],out[i+4],out[i+5],out[i+6],out[i+7]); + break; + } + } + } + fprintf(stderr,"\n"); + exit(0); +} + + +void vstest16(int id, int rm,int rx, unsigned n) { + unsigned b,i; fprintf(stderr,"16 bits test.n=%d ", n); + uint16_t *in = _in,*cpy = _cpy; + + if(n > NN) n = NN; //if(id==5) n = 128; + for(b = rm; b <= min(rx,16); b++) { + uint64_t start = 0, msk = (1u << b)-1; + unsigned char *op; fprintf(stderr,"\nb=%d:", b); + for(i = 0; i < n; i++) { + in[i] = be_rand?rand()&msk:msk; //(/*start +=*/ RND64 & msk); //fprintf(stderr, ".%llx ", in[0]); + if(bsr16(in[i]) > b) die("Fatal error at b=%d ", b); + } + in[0] = msk; + in[n-1] = msk; + switch(id) { + case 0: fprintf(stderr,"vbenc16 "); op = vbenc16( in, n, out); break; + case 1: fprintf(stderr,"bitpack16 "); op = bitpack16( in, n, out, b);break; + case 2: fprintf(stderr,"bitnpack16 "); op = out+bitnpack16( in, n, out); break; + case 3: fprintf(stderr,"bitnpack128v16 "); op = out+bitnpack128v16(in, n, out); break; + case 4: fprintf(stderr,"p4nenc16 "); op = out+p4nenc16( in, n, out); break; + case 5: fprintf(stderr,"p4nenc128v16 "); op = out+p4nenc128v16( in, n, out); break; + case 6: fprintf(stderr,"vsenc16 "); op = vsenc16( in, n, out); break; + case 7: fprintf(stderr,"bitndpack16 "); op = out+bitndpack16( in, n, out); break; + case 8: fprintf(stderr,"bitnd1pack16 "); op = out+bitnd1pack16( in, n, out); break; + case 9: fprintf(stderr,"bitnzpack16 "); op = out+bitnzpack16( in, n, out); break; + case 10: fprintf(stderr,"vbzenc16 "); op = vbzenc16( in, n, out, 0);break; + case 11: fprintf(stderr,"p4nzenc16 "); op = out+p4nzenc16( in, n, out); break; + default: die("Fatal error: function %d not found\n", id); + } + fprintf(stderr,"%d %.2f%% ", (int)(op-out), ((double)(op-out)*100.0)/(double)(n*8)); if(op-out>sizeof(out)) die("vstest16:Overflow %d\n", op-out); + memrcpy(cpy, in, n*sizeof(in[0])); + switch(id) { + case 0: vbdec16( out, n, cpy); break; + case 1: bitunpack16( out, n, cpy, b);break; + case 2: bitnunpack16( out, n, cpy); break; + case 3: bitnunpack128v16(out, n, cpy); break; + case 4: p4ndec16( out, n, cpy); break; + case 5: p4ndec128v16( out, n, cpy); break; + case 6: vsdec16( out, n, cpy); break; + case 7: bitndunpack16( out, n, cpy); break; + case 8: bitnd1unpack16( out, n, cpy); break; + case 9: bitnzunpack16( out, n, cpy); break; + case 10: vbzdec16( out, n, cpy, 0);break; + case 11: p4nzdec16( out, n, cpy); break; + } + uint16_t *p = cpy; + for(i = 0; i < n; i++) + if(in[i] != p[i]) { + fprintf(stderr, "Error b=%d at '%d' (in=%x,%x cpy=%x,%x)", b, i, in[i], in[i+1], p[i], p[i+1]); break; + } + } + fprintf(stderr,"\n"); + exit(0); +} + #else +#define vstest64(id,rm,rx,n) + #endif +//extern unsigned xbits[]; +char *sifmt[] = {"","s","i","z"}; + #ifdef __MINGW32__ +extern int _CRT_glob=1; + #endif +int main(int argc, char* argv[]) { + int xstdout=-1,xstdin=-1; + int recurse = 0, xplug = 0,tm_Repk=1,plot=-1,fmt=0,fno,merge=0,rprio=1,dfmt = 0,kid=1,skiph=0,decs=2,divs=1,k,vtest=-1,id; + unsigned bsize = 128*4, bsizex=0, n=25000000; + uint64_t filenmax = 0; + char *scmd = NULL,*trans=NULL,*beb=NULL,*rem="",s[2049]; + char *_argvx[1], **argvx=_argvx; + + int c, digit_optind = 0; + for(;;) { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = { + { "help", 0, 0, 'h'}, + { 0, 0, 0, 0} + }; + if((c = getopt_long(argc, argv, "1234a:A:b:B:cC:d:De:E:F:f:gGHi:I:j:J:k:K:l:L:m:M:n:N:oOPp:Q:q:rRs:S:t:T:Uv:V:W:X:Y:Z:y:z:", long_options, &option_index)) == -1) break; + switch(c) { + case 0: + printf("Option %s", long_options[option_index].name); + if(optarg) printf (" with arg %s", optarg); printf ("\n"); + break; + case 'a': a = strtod(optarg, NULL); break; + case 'b': bsize = argtoi(optarg,1)*4; bsizex++; break; + case 'B': filenmax = argtol(optarg); break; + case 'C': cmp = atoi(optarg); break; + case 'd': mdelta = atoi(optarg); break; + case 'e': scmd = optarg; break; + case 'f': { char *s = optarg; + dfmt = 0; + if(*s=='c') { dfmt = T_CHAR; s++;} + else if(*s=='t') { dfmt = T_TXT; if(*++s > '0' && *s <= '9') { kid = s[0] - '0'; s++; } } + else if(*s=='u') { dfmt = T_TST; s++;} + //else if(*s=='f') { dfmt = T_FLT; s++;} + //else if(*s=='d') { dfmt = T_DBL; s++;} + else if(*s=='1' || *s=='2') { dfmt = s[0]-'0'; s++; } + if(*s == '.') { if(*++s >= '0' && *s <= '9') { decs = s[0] - '0'; s++; } } + if(*s == 'v') { divs = strtod(++s, &s); } + if(*s == 'H') { skiph++; s++; } + switch(*s) { case 's': be_mindelta = 0; break; case 'S': be_mindelta = 1;break; case 'z': be_mindelta = 2; break; } + } break; + case 'F': fac = strtod(optarg, NULL); break; +// case 'f': fuzz = atoi(optarg); break; + case 'g': merge++; break; + case 'G': plotmcpy++; break; + + case 'H': be_factor++; break; + case 'i': if((tm_rep = atoi(optarg))<=0) + tm_rep=tm_Rep=1; break; + case 'I': tm_Rep = atoi(optarg); break; + case 'j': if((tm_rep2 = atoi(optarg))<=0) + tm_rep2=tm_Rep2=1; break; + case 'J': tm_Rep2 = atoi(optarg); break; + case 'k': if((tm_Repk = atoi(optarg))<=0) tm_rep=tm_Rep=tm_rep2=tm_Rep2=tm_Repk=1; break; + case 'L': tm_slp = atoi(optarg); break; + case 't': tm_tx = atoi(optarg)*TM_T; break; + case 'T': tm_TX = atoi(optarg)*TM_T; break; + case 'S': speedup = atoi(optarg); break; + + case 'l': xplug = atoi(optarg); break; + case 'r': be_nblocks++; break; + case 'o': xstdout++; break; + case 'p': fmt = atoi(optarg); break; + case 'P': be_mcpy++; break; + case 'Q': divxy = atoi(optarg); + if(divxy>3) divxy=3; break; + case 'D': rprio=0; break; + case 's': mininlen = argtoi(optarg,Mb); break; + case 'v': verbose = atoi(optarg); break; + case 'Y': seg_ans = argtoi(optarg,Kb); break; + case 'Z': seg_huf = argtoi(optarg,Kb); break; + case '1': xlog = xlog?0:1; break; + case '2': ylog = ylog?0:1; break; + case '3': xlog2 = xlog2?0:1; break; + case '4': ylog2 = ylog2?0:1; break; + case 'R': be_rand=0; break; + case 'q' : cpuini(atoi(optarg)); break; + #ifdef LZTURBO + case 'c': beb = optarg; break; + #else + case 'c': fprintf(stderr, "Option M: only in binary package available"); exit(0); + #endif + case 'n': n = argtoi(optarg,1); break; + case 'm': rm = argtoi(optarg,1); break; + case 'M': rx = argtoi(optarg,1); break; + case 'y': vtest = 16; id=atoi(optarg); break; + case 'z': vtest = 64; id=atoi(optarg); break; + BEOPT; + case 'h': + default: + usage(argv[0]); + exit(0); + } + } + if(vtest==64) vstest64(id,rm,rx,n); + else if(vtest==16) vstest16(id,rm,rx,n); + if(xplug) { + xplug==1?plugsprt():plugsprtv(stdout, fmt); + exit(0); + } + + if(argc <= optind) { + #ifdef _WIN32 + setmode( fileno(stdin), O_BINARY ); + #endif + argvx[0] = "stdin"; + optind = 0; + argc = 1; + recurse = 0; + } else + argvx = argv; + + if(fmt) { + if(argc <= optind) + die("no input file specified%s", ""); + for(fno = optind; fno < argc; fno++) + printfile(argvx[fno], xstdout, fmt, rem); + exit(0); + } + if(rprio) { + #ifdef _WIN32 + SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); + #else + setpriority(PRIO_PROCESS, 0, -19); + #endif + } + if(!scmd) scmd = "DEFAULT"; + for(s[0] = 0;;) { + char *q; int i; + if(!*scmd) break; + if(q = strchr(scmd,'/')) *q = '\0'; + for(i = 0; plugg[i].id[0]; i++) + if(!strcmp(scmd, plugg[i].id)) { + strcat(s, "ON/"); + strcat(s, plugg[i].name); + strcat(s, "/OFF"); + break; + } + if(!plugg[i].id[0]) { + strcat(s,scmd); + strcat(s,"/"); + } + scmd = q?(q+1):(char*)""; + } + k = plugreg(plug, s, 0, bsize, bsizex); + if(k > 1 && argc == 1 && !strcmp(argvx[0],"stdin")) { printf("multiple codecs not allowed when reading from stdin"); exit(0); } + + { //tm_init(15,1); + int krep=1; + char *finame = ""; + int pagesize = getpagesize(); + tm_t tmk0 = tminit(); + struct plug *g; + char sfiname[65]; + uint64_t totinlen=0; + BEINI; + if(!filenmax) filenmax = Gb; + + if(dfmt == T_TST) { // Unit test for fixed bit sizes + ftest(plug, k, n, bsize); + exit(0); + } + + for(fno = optind; fno < argc; fno++) { + FILE *fi = NULL; + char *q; + size_t outsize,insize; + unsigned char *_in, *_cpy, *out; + //int inlen; + int64_t inlen, ftotinlen=0; + struct plug *p; + int checks = 0; + finame = argvx[fno]; if(verbose > 1) printf("%s\n", finame); + if(!strcmp(finame,"ZIPF")) { sprintf(sfiname, "ZIPF%.2f_%u-%u-%u", a,rm,rx, n); + strcat(sfiname,sifmt[be_mindelta+1]); + finame = sfiname; + if(!dfmt) dfmt = T_UINT32; + } else { + fi = strcmp(finame,"stdin")?fopen(finame, "rb"):stdin; + if(!fi) { perror(finame); continue; /*die("open error '%s'\n", finame);*/ } + } + + if((q = strrchr(finame, '\\')) || (q = strrchr(finame, '/'))) finame = q+1; if(verbose>1) printf("'%s'\n", finame); + + _in = NULL; + if(dfmt) { + if(!_in) { filen = inlen = befgen(&_in, n, dfmt, 4, fi, kid, skiph, decs, divs); + insize = min(filen,(1u< filenmax) filen = filenmax; + } else + filen = filenmax; + //insize = filen; + insize = min(filen,(1u< filenmax) insize = filenmax; + insizem = (fuzz&3)?SIZE_ROUNDUP(insize, pagesize):(insize+INOVD); + + if(insizem && !(_in = _valloc(insizem,1))) + die("malloc error in size=%u\n", insizem); + } + outsize = insize*fac + 10*Mb; + _cpy = _in; + out = (unsigned char*)_valloc(outsize,2); if(!out) die("malloc error out size=%u\n", outsize); + + if((cmp || tid) && insizem && !(_cpy = _valloc(insizem,3))) + die("malloc error cpy size=%u\n", insizem); + + for(p = plug; p < plug+k; p++) { //{ int i; for(i=0;i<=64;i++) xbits[i]=0;} + unsigned pbsize = p->blksize?p->blksize:bsize; + int64_t outlen = 0; + if(p->lev >= 0) + sprintf(name, "%s %d%s", p->name, p->lev, p->prm); + else + sprintf(name, "%s%s", p->name, p->prm); + + codini(insize, p->id); + if(be_mindelta >= 0) + pbsize += 4; // start stored w. variable byte for delta coding + //printf("bsize=%d, ", pbsize); + //p->len = p->tc = p->td = p->err = 0; + blknum = 0; + if(dfmt) { + ftotinlen = inlen; memrcpy(out, _in, inlen); if(!checks) checksort(_in,inlen/4),checks++; + outlen = plugbench(p, _in, inlen, out, outsize, _cpy, pbsize, plugr,tid, finame); + } else { + ftotinlen = 0; + fseek(fi, 0, SEEK_SET); + if(be_nblocks) { + unsigned char *ip = _in; + unsigned num; + while(fread(&num, 1, 4, fi) == 4 && num) { //if(num < rm || num > rx) { fseeko(fi, num*4, SEEK_CUR); continue; } + num *= 4; + if(ip+num >= _in+insize) { + inlen = ip - _in; memrcpy(out, _in, inlen);if(!checks) checksort(_in,inlen/4),checks++; + ftotinlen += inlen; + outlen += plugbench(p, _in, inlen, out, outsize, _cpy, pbsize, plugr,tid, finame); //if(n && outlen > n) break; + ip = _in; + } + ctou32(ip) = num/4; ip += 4; + if(fread(ip, 1, num, fi) != num) + break; + if(be_mindelta >=0) { + unsigned *p = (unsigned *)ip,i; + for(i = 1; i < num/4; i++) if(p[i] < p[i-1]+be_mindelta) { printf("Warning: IDs not sorted :%d:%d,%d\n", i, p[i-1], p[i] );break; } + } + ip += num; + } + if(inlen = ip - _in) { + ftotinlen += inlen; + outlen += plugbench(p, _in, inlen, out, outsize, _cpy, pbsize, plugr,tid, finame); + } + //if(ftotinlen >= filen) break; + } else while((inlen = fread(_in, 1, insize, fi)) > 0) { memrcpy(out, _in, inlen);if(!checks) checksort(_in,inlen/4),checks++; + ftotinlen += inlen; + outlen += plugbench(p, _in, inlen, out, outsize, _cpy, pbsize, plugr,tid, finame); + if(ftotinlen >= filenmax) + break; + } + } + codexit(p->id); //if(verbose && filen > insize) plugprt(p, ftotinlen, finame, FMT_TEXT,stdout); + //{ int i; for(i=0;i<=64;i++) if(xbits[i]) printf("%d:%d ", i, xbits[i]);printf("\n");} + } + totinlen += ftotinlen; + if(fi) fclose(fi); + dfmt?free(_in):_vfree(_in, insizem); _in = NULL; + _vfree(out, outsize); + if(_cpy && _cpy != _in) + _vfree(_cpy, insizem); + } + BENCHSTA; + + if(argc - optind > 1) { + unsigned clen = strpref(&argvx[optind], argc-optind, '\\', '/'); + strncpy(s, argvx[optind], clen); + if(clen && (s[clen-1] == '/' || s[clen-1] == '\\')) + clen--; + s[clen] = 0; + finame = strrchr(s,'/'); + if(!finame) + finame = strrchr(s, '\\'); + if(!finame) + finame = s; + else finame++; + } else { + char *p; + if((p = strrchr(finame, '\\')) || (p = strrchr(finame, '/'))) + finame = p+1; + } + if(!strcmp(finame,"ZIPF")) finame = sfiname; + sprintf(s, "%s.tbb", finame); + if(merge) { + if(merge == 1) + plugprts(plug, k, s, 1, totinlen, FMT_TEXT, rem); + exit(0); + } + + { + int64_t _totinlen; + int gk = plugread(pluga, s, &_totinlen); + FILE *fo = fopen(s, "w"); + if(_totinlen != totinlen) + gk = 0; + if(fo) { + char tms[20]; + time_t tm; + struct tm *ltm; + struct plug *g,*p; + time(&tm); + ltm = localtime(&tm); + sprintf(tms, "%.4d-%.2d-%.2d.%.2d:%.2d:%.2d", 1900 + ltm->tm_year, ltm->tm_mon+1, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec); + + fprintf(fo, "dataset\tsize\tcsize\tdtime\tctime\tcodec\tlevel\tparam\tcmem\tdmem\ttime\n"); + for(p = plug; p < plug+k; p++) { + for(g = pluga; g < pluga+gk; g++) + if(g->id >= 0 && !strcmp(g->name, p->name) && g->lev == p->lev && !strcmp(g->prm, p->prm)) { + if(g->len == p->len) { + int u=0; + if(g->td < p->td || p->td < 0.01) + p->td = g->td,u++; + if(g->tc < p->tc || p->tc < 0.01) + p->tc = g->tc,u++; + if(g->memd != p->memd) u++; + if(g->memc != p->memc) u++; + strcpy(p->tms, u?tms:g->tms); + } + g->id = -1; + break; + } + if(p->len) + fprintf(fo, "%s\t%"PRId64"\t%"PRId64"\t%.6f\t%.6f\t%s\t%d\t%s\t%"PRId64"\t%"PRId64"\t%s\n", finame, totinlen, p->len, p->td, p->tc, p->name, p->lev, p->prm[0]?p->prm:"!", p->memc, p->memd, p->tms[0]?p->tms:tms); + } + for(g = pluga; g < pluga+gk; g++) + if(g->id >= 0 && g->len) + fprintf(fo, "%s\t%"PRId64"\t%"PRId64"\t%.6f\t%.6f\t%s\t%d\t%s\t%"PRId64"\t%"PRId64"\t%s\n", finame, totinlen, g->len, g->td, g->tc, g->name, g->lev, g->prm[0]?g->prm:"?", g->memc, g->memd, g->tms[0]?g->tms:tms); + fclose(fo); + printfile(s, 0, FMT_TEXT, rem); + } + } + } +} diff --git a/src/ext/for/idx.h b/src/ext/for/idx.h new file mode 100644 index 00000000000..d13cc403d84 --- /dev/null +++ b/src/ext/for/idx.h @@ -0,0 +1,53 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ + +// "Integer Compression" header for idxcr/idxqry +#include + +#define BLK_DIDNUM (128+1) // Block size 128 + 1 (1 stored in skips) + + // compressed size for 62 GB clueweb09.sorted + // Defaut is bitpackv/bitunpackv 18 GB +//#define _TURBOPFOR // for compact version 12 GB + + #ifdef _TURBOPFOR +//#define SKIP_S 6 +#define SKIP_SIZE 2 // always no implicit skip. + #else +//#define SKIP_S 5 +#define SKIP_SIZE 2 // no implicit skips +//#define SKIP_SIZE 1 // implicit skips + #endif +#define SKIP_M ((1< posting offset in file ---------------------------------- +typedef struct { uint8_t offseth; uint32_t offsetl; } __attribute__ ((packed)) tmap_t; // 40 bits offsets -> 1 Terabyte + +#define TIDMAPSET(_t_, _ofs_) { (_t_)->offseth = (_ofs_)>>32; (_t_)->offsetl = (_ofs_) & 0xffffffff; } +//#define TIDMAPGET(_t_) ((__off64_t)(_t_)->offseth << 32 | (_t_)->offsetl) +#define TIDMAPGET(_t_) ((unsigned long long)(_t_)->offseth << 32 | (_t_)->offsetl) +#define TIDMAP(_fdm_, _tid_) ({ unsigned char *_bp = _fdm_; tmap_t *_t = (tmap_t *)&_bp[(_tid_)*sizeof(tmap_t)]; TIDMAPGET(_t); }) diff --git a/src/ext/for/idxcr.c b/src/ext/for/idxcr.c new file mode 100644 index 00000000000..d19e956451d --- /dev/null +++ b/src/ext/for/idxcr.c @@ -0,0 +1,175 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// idxcr.c - "Integer Compression" Create inverted index for using by idxqry for benchmarking +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include "conf.h" +#define VINT_IN +#include "vint.h" +#include "bitpack.h" +#include "vp4.h" +#include "idx.h" +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#endif + +#ifdef NSIMD +#define bitpack128v32 bitpack32 +#endif + +//--------------------------------------------------------------------------------------------------------------- +#define DELTA( __in, __n, __b) do { unsigned _v; for(__b=0,_v = __n-1; _v > 0; --_v) __in[_v] = (__in[_v] - __in[_v-1]) - 1, __b |= __in[_v]; __b = bsr32(__b); } while(0) + +#define TERMNUM 2000000 +int verb; + +void usage() { + fprintf(stderr, "\nTurboPFor Copyright (c) 2013-2019 Powturbo %s\n", __DATE__); + fprintf(stderr, "https://github.com/powturbo/TurboPFor\n\n"); + fprintf(stderr, "Create inverted index from 'Document identifier data set' format\n"); + fprintf(stderr, "See http://lemire.me/data/integercompression2014.html'\n"); + fprintf(stderr, "Usage: idxcr \n"); + fprintf(stderr, "ex. idxcr clueweb09.sorted idxdir\n\n"); + fprintf(stderr, "ex. index partitions generated from idxseg\n\n"); + fprintf(stderr, "ex. idxcr ./idxcr gov2.sorted.s* .\n\n"); + exit(-1); +} + +int main(int argc, char *argv[]) { + int fno,c, digit_optind = 0, this_option_optind = optind ? optind : 1, option_index = 0; char *path=""; + static struct option long_options[] = { {"r", 0, 0, 'r'}, {0,0, 0, 0} }; + for(;;) { + if((c = getopt_long(argc, argv, "xv:", long_options, &option_index)) == -1) break; + switch(c) { + case 0 : printf("Option %s", long_options[option_index].name); + if(optarg) printf (" with arg %s", optarg); printf ("\n"); break; + case 'v': verb = atoi(optarg); break; + default: die("unknown option: %c \n", optopt); + } + } + if(argc - optind < 2) usage(); + path = argv[--argc]; + + for(fno = optind; fno < argc; fno++) { + char outname[257], *inname = argv[fno]; + strcpy(outname, path); + char *p = strrchr(inname,'/'); + if(!p) p = strrchr(inname,'\\'); if(!p) p=inname; + strcat(outname, p); strcat(outname,".i"); + + FILE *fi = fopen(inname, "rb"); if(!fi) { fprintf(stderr, "open error '%s'", inname); perror(inname); exit(-1); } int fdi = fileno(fi); + FILE *fo = fopen(outname,"wb"),*fm; if(!fo) { fprintf(stderr, "creat error '%s'", outname); perror(outname); exit(-1); } fprintf(stderr, "file='%s'", outname); + fseeko(fo, sizeof(unsigned)+sizeof(unsigned long long), SEEK_SET); + + tmap_t *tmap = calloc(1, TERMNUM*sizeof(tmap_t)); + if(!tmap) die("malloc error\n"); + unsigned *in = NULL,*ip,*ep,num,tid=0,numx=0,outsize; + unsigned char *out = NULL; + unsigned long long fofs; unsigned long long postsize=0,skipsize = 0; + + while(fread(&num, 1, 4, fi) == 4) { // read number of docid in term + if(!num) { ++tid; continue; } + unsigned bnum = (num+BLK_DIDNUM-1)/BLK_DIDNUM; + if(num > numx) { + numx = num; + in = realloc(in, num*4+64); + outsize = num*4+bnum*sizeof(unsigned)*SKIP_SIZE+1024; + out = realloc(out, outsize); + if(!in || !out) die("malloc err=%u", num); + } + if(fread(in, 4, num, fi) != num) break; // read docid list + + unsigned char *op = out,*_op; + vbput32(op, num); // store f_t + + unsigned *pix = (unsigned *)op; + if(num > BLK_DIDNUM) { + op += bnum*sizeof(unsigned)*SKIP_SIZE; skipsize += op-out; + } + for(_op = op, ip = in, ep = ip+num; ip < ep; ) { + unsigned n = min(ep-ip, BLK_DIDNUM), b = 0,bx; if(op+5*n > out+outsize) die("output buffer too small\n"); + if(n > 1) { + #ifndef _TURBOPFOR + DELTA(ip, n, b); //bitdenc32( in+1, --n, pa, in[0], mode); + // #ifdef _TURBOPFOR + //b = _p4bits32(ip+1, n-1, &bx); + #endif + } + #ifdef SKIP_S + unsigned u = ip[0]< BLK_DIDNUM) { // skip/index. docid[0] and offset to compressed block + *pix = u; + #if SKIP_SIZE == 2 + pix[bnum] = op - _op; // save posting offset + #endif + pix++; + } else vbput32(op, u); // skip not needed + + if(n > 1) { + #ifdef _TURBOPFOR + op = n==129?p4d1enc128v32( ip+1, n-1, op, u):p4d1enc32( ip+1, n-1, op, u);//*op++ = bx; op = n==129?_p4enc128v32( ip+1, n-1, op, b, bx):_p4enc32( ip+1, n-1, op, b, bx); + #else + #ifndef SKIP_S + *op++ = b; + #endif + op = n==129?bitpack128v32( ip+1, n-1, op, b) :bitpack32(ip+1, n-1, op, b); + #endif + } + ip += n; + } + fofs = ftello(fo); + tmap_t *t = &tmap[tid++]; + TIDMAPSET(t, fofs); + if(fwrite(out, 1, op-out, fo) != op-out) die("fwrite error\n"); postsize += op-out; + } + fofs = ftello(fo); // write termmap + if(fwrite(tmap, sizeof(tmap_t), tid, fo) != tid) die("fwrite error\n"); + + fseeko(fo, 0, SEEK_SET); + if(fwrite(&fofs, sizeof(unsigned long long), 1, fo) != 1) die("fwrite error\n"); + if(fwrite(&tid, sizeof(unsigned), 1, fo) != 1) die("fwrite error\n"); fofs = ftello(fi); + fclose(fi); fclose(fo); + if(in) { free(in); free(out); } + free(tmap); + printf("\nterms=%u size=[tmap=%u skip=%llu post=%llu total=%llu, ratio=%.2f %%\n", tid, (unsigned)(tid*sizeof(tmap_t)), + skipsize, postsize-skipsize, postsize+tid*sizeof(tmap_t)+12, (double)postsize*100/(double)fofs ); + } +} diff --git a/src/ext/for/idxqry.c b/src/ext/for/idxqry.c new file mode 100644 index 00000000000..424756cffa4 --- /dev/null +++ b/src/ext/for/idxqry.c @@ -0,0 +1,684 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// Inverted Index - query evaluation +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + + #ifdef _WIN32 +#include + #else +#include + #endif +#include + +#include "conf.h" +#define VINT_IN +#include "vint.h" +#include "bitpack.h" +#include "vp4.h" +#include "idx.h" +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#define max(x,y) (((x)>(y)) ? (x) : (y)) +#endif + +#ifdef NSIMD +#define bitd1unpack128v32 bitd1unpack32 +#define _p4d1dec128v32 _p4d1dec32 +#endif + +//#define STATS +//------------------------------------- index file (created by idxcr) ------------------------------------------------------------- +typedef struct { + unsigned char *fdp, // posting + *fdm; // mapping term id to offset in posting + unsigned long long fdsize; + unsigned tnum; + #ifdef _WIN32 + HANDLE hd; + #endif +} idxrd_t; // Index + +int idxopen(idxrd_t *idx, char *s) { + unsigned char *p; + + #ifdef _WIN32 + HANDLE fd; + if((fd = CreateFileA( s, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL, 0 ))==INVALID_HANDLE_VALUE) + die("can't open index file '%s' rc=%d\n", s, GetLastError()); + + struct stat sbuf; fstat((intptr_t)fd, &sbuf); + ULARGE_INTEGER ul; ul.QuadPart = sbuf.st_size; + if(!(idx->hd = CreateFileMapping(fd, NULL, PAGE_READONLY, ul.HighPart, ul.LowPart, NULL))) + die("CreateFileMapping failed or file not found.rc=%d \n", GetLastError()); + ul.QuadPart = 0; + if(!(p = MapViewOfFile(idx->hd, FILE_MAP_READ, ul.HighPart, ul.LowPart, sbuf.st_size))) + die("MapViewOfFile failed.rc=%d\n", GetLastError()); + CloseHandle( fd ); + #else + int fd; + if((fd = open(s, O_RDONLY/*| O_LARGEFILE*/)) < 0) + die("can't open index file '%s' rc=%d:%s\n", s, errno, strerror(errno)); + + struct stat sbuf; fstat((int)fd, &sbuf); + if(sbuf.st_size > 0 && (p = mmap( NULL, sbuf.st_size , PROT_READ, MAP_SHARED|MAP_NORESERVE, fd, 0)) == (void *)-1) + die("mmap errno=%d,'%s'\n", errno, strerror(errno) ); + close(fd); + #endif + + idx->fdsize = sbuf.st_size; + idx->fdp = p; + idx->fdm = p + *(uint64_t *)p; p += sizeof(uint64_t); // Termid map table. Termid->Posting + idx->tnum = *(unsigned *)p; + return 0; +} + +void idxclose(idxrd_t *idx) { + #ifdef _WIN32 + UnmapViewOfFile(idx->fdp); + CloseHandle(idx->hd); + #else + munmap(idx->fdp, idx->fdsize); + #endif +} + +//--------------------------------- Posting -------------------------------------------------------------- + #ifdef STATS +unsigned long long st_tot,st_dec,st_did,st_blk,st_ovl,st_noovl,st_skip,st_noi,st_terms,st_dids[8],st_decs[8],st_tots[8]; +#define STATINI st_tot=st_dec=st_did=st_blk=st_ovl=st_noovl=st_skip=st_noi=st_terms=0;{int i; for(i=0;i<8;i++) st_dids[i]=st_decs[i]=st_tots[i]=0;} +#define STAT(a) a + #else +#define STATINI +#define STAT(a) + #endif + +typedef struct { + unsigned char *bp,*p; + unsigned f_t,_f_t, did,ldid; + int didno,didnum, bno, bnum; + #if SKIP_SIZE == 1 + unsigned long long pofs; + #endif +} post_t; + +// Init posting for term id tid +int postinit( post_t *v, int tid, idxrd_t *idx, unsigned *dids) { + unsigned long long o = TIDMAP(idx->fdm, tid); if(!o) return 0; + unsigned char *p = idx->fdp + o; // start of posting; + vbget32(p, v->f_t); // num docs + v->didno = v->bno = -1; + v->bnum = (v->f_t+BLK_DIDNUM-1)/BLK_DIDNUM; // num blocks + v->_f_t = v->f_t; + + v->bp = p; // start skip block + v->p = p + v->bnum*sizeof(unsigned)*2; // start posting block + dids[0] = INT_MAX; + v->ldid = v->did = 0; + v->didnum = min(v->f_t,BLK_DIDNUM); STAT(if(v->f_t>BLK_DIDNUM) st_tot += v->f_t);STAT(if(v->f_t>BLK_DIDNUM) st_tots[st_terms] += v->f_t); + #if SKIP_SIZE == 1 + v->pofs = 0; + #endif + return v->f_t; +} + +static ALWAYS_INLINE unsigned postdec(post_t *v, int bno, unsigned *dids) { if(v->didno == bno) die("Fatal postdec"); + unsigned char *p = v->bp; + if(v->f_t > BLK_DIDNUM) { if(bno < 0 || bno >= v->bnum) die("Fatal bno\n"); + unsigned *pix = (unsigned *)p + bno; + p = v->p + pix[v->bnum]; // o=offset to posting block + dids[0] = *pix; // first did in block + v->didnum = bno < v->bnum-1?BLK_DIDNUM:v->f_t - bno*BLK_DIDNUM; + } else { v->didnum = v->f_t; vbget32(p, dids[0]); } STAT(st_dec += v->didnum); STAT(st_decs[st_terms] += v->didnum); + #ifdef SKIP_S + unsigned b = dids[0] & SKIP_M; dids[0] >>= SKIP_S; + #endif + + if(v->didnum > 1) { + #ifdef _TURBOPFOR + //unsigned bx = *p++; p = v->didnum == 129?_p4d1dec128v32( p, 128, &dids[1], dids[0], b, bx):_p4d1dec32( p, v->didnum-1, &dids[1], dids[0], b, bx); + p = v->didnum == 129?p4d1dec128v32( p, 128, &dids[1], dids[0]):p4d1dec32( p, v->didnum-1, &dids[1], dids[0]); + #else + #ifndef SKIP_S + unsigned b = *p++; + #endif + p = v->didnum == 129?bitd1unpack128v32( p, 128, &dids[1], dids[0], b ):bitd1unpack32(p, v->didnum-1, &dids[1], dids[0], b); + #endif + } + v->didno = bno; + dids[v->didnum] = INT_MAX; + return v->didnum; +} + + #ifdef SKIP_S +#define QS(__x) ((__x)>>SKIP_S) + #else +#define QS(__x) (__x) + #endif + + #if SKIP_SIZE == 1 + #ifdef _TURBOPFOR +#error "implicit skip not implemented for turbopfor" + #else +#define COFS(__ofs,__x) __ofs += (((__x)&SKIP_M)+7/8) // implicit skips: calculate the offset of the next block + #endif + #else +#define COFS(__ofs,__x) + #endif + +// Get next docid. Return value >= INT_MAX at end of posting +static ALWAYS_INLINE unsigned postnext(post_t *v, unsigned *dids) { + if((v->did = dids[++v->didno]) < INT_MAX) return v->did; + unsigned char *p = v->bp; + + if(v->f_t > BLK_DIDNUM) { + if(++v->bno >= v->bnum) return INT_MAX; + unsigned *pix = (unsigned *)p + v->bno; + p = v->p + pix[v->bnum]; // o=offset to posting block + dids[0] = *pix; // first did in block + } else vbget32(p, dids[0]); + #ifdef SKIP_S + unsigned b = dids[0] & SKIP_M; dids[0] >>= SKIP_S; + #endif + + v->didnum = min(v->_f_t, BLK_DIDNUM); + v->_f_t -= v->didnum; //STAT(st_dec+=v->didnum); + if(v->didnum > 1) { + #ifdef _TURBOPFOR + p = v->didnum == 129?p4d1dec128v32( p, 128, &dids[1], dids[0] ):p4d1dec32( p, v->didnum-1, &dids[1], dids[0]);//unsigned bx = *p++; p = v->didnum == 129?_p4d1dec128v32( p, 128, &dids[1], dids[0], b, bx):_p4d1dec32( p, v->didnum-1, &dids[1], dids[0], b, bx); + #else + #ifndef SKIP_S + unsigned b = *p++; + #endif + p = v->didnum == 129?bitd1unpack128v32( p, 128, &dids[1], dids[0], b):bitd1unpack32(p, v->didnum-1, &dids[1], dids[0], b); + #endif + } + dids[v->didnum] = INT_MAX; + v->didno = 0; + return v->did = dids[0]; +} + +#define DD if(v->did >= did) break; v->did = dids[++v->didno] +#define DS if(QS(q[1]) >= did || q >= qe) break; COFS(v->pofs, *q); q++ + +// Get next docid equal or greater than the parameter did +static ALWAYS_INLINE unsigned postget(post_t *v, unsigned did, unsigned *dids) { + if(did >= v->ldid) goto b; + for(;;) { a: DD;DD;DD;DD; DD;DD;DD;DD; } + if(v->did < v->ldid) { STAT(st_did += (v->diddiddid; + } + b:; unsigned char *p; // Skip index + if(v->f_t > BLK_DIDNUM) { + unsigned *_q = (unsigned *)v->bp, *q=_q+(++v->bno), *qe=_q+v->bnum-1; + for(;;) { DS;DS;DS;DS; DS;DS;DS;DS; } + v->bno = q - _q; + if(q < qe) v->ldid = QS(q[1]); + else { + v->ldid = UINT_MAX; + v->didnum = v->f_t - v->bno*BLK_DIDNUM; + } + dids[0] = v->did = QS(*q); // first did in block + #if SKIP_SIZE == 1 + p = v->p+v->pofs; // o=offset to posting block + #else + p = v->p+q[v->bnum]; // o=offset to posting block + #endif + } else { + p = v->bp; + vbget32(p, v->did); + v->ldid = UINT_MAX; + } + #ifdef SKIP_S + unsigned b = v->did&SKIP_M; v->did >>= SKIP_S; + #endif + dids[0] = v->did; + STAT(st_dec+=v->didnum); STAT(st_decs[st_terms] += v->didnum); + if(v->didnum > 1) { STAT(st_blk++); + #ifdef _TURBOPFOR + p = v->didnum == 129?p4d1dec128v32( p, 128, &dids[1], dids[0] ):p4d1dec32( p, v->didnum-1, &dids[1], dids[0]);//unsigned bx = *p++; p = v->didnum == 129?_p4d1dec128v32( p, 128, &dids[1], dids[0], b, bx):_p4d1dec32( p, v->didnum-1, &dids[1], dids[0], b, bx); + #else + #ifndef SKIP_S + unsigned b = *p++; + #endif + p = v->didnum == 129?bitd1unpack128v32( p, 128, &dids[1], dids[0], b):bitd1unpack32(p, v->didnum-1, &dids[1], dids[0], b); + #endif + } + dids[v->didnum] = v->ldid&INT_MAX; v->didno = 0; goto a; +} + +/********************************************* query search *************************************************************************************/ +//#define THREAD_MAX 32 //uncomment for parallel processing. +#define SKIP_INTERVALS + + #ifdef THREAD_MAX +#define QRYFIFOMAX (1<<14) +//--------------- thread/fifo ------------------------- +#include +typedef void *threadfunc_t; +typedef void *threadfuncarg_t; +typedef pthread_t thread_t; +typedef pthread_mutex_t thread_mutex_t; +#define thread_mutex_init(__mutex) pthread_mutex_init(__mutex, NULL) +#define thread_mutex_lock(__mutex) pthread_mutex_lock(__mutex) +#define thread_mutex_unlock(__mutex) pthread_mutex_unlock(__mutex) +#define thread_mutex_destroy(__mutex) pthread_mutex_destroy(__mutex) +#define thread_join(__th) pthread_join(__th, NULL); + +thread_t thread_create(threadfunc_t (*thread_func)(threadfuncarg_t), threadfuncarg_t arg) { + thread_t th; + int rc; + rc = pthread_create(&th, NULL, thread_func, arg); + return rc?-1:th; +} + +#define _FIFOPUT(__fifo, __obj) do { (__fifo)->buf[(++(__fifo)->tail) & ((__fifo)->size-1)] = (__obj); } while(0) +#define _FIFOGET(__fifo, __obj) do { (__obj) = (__fifo)->buf[(++(__fifo)->head) & ((__fifo)->size-1)]; } while(0) +#define FIFOEMPTY(__fifo) ((__fifo)->head == (__fifo)->tail) +#define FIFOFULL(__fifo) ((__fifo)->tail == (__fifo)->head + (__fifo)->size) + +#define FIFO_STRUCT_I pthread_mutex_t mutex; pthread_cond_t nofull, noempty; + +#define FIFO_INIT_I(__fifo, __fifosize) \ + pthread_mutex_init(&(__fifo)->mutex, NULL);\ + pthread_cond_init(&(__fifo)->nofull, NULL);\ + pthread_cond_init(&(__fifo)->noempty, NULL); + +#define FIFO_EXIT_I(__fifo) pthread_mutex_destroy(&(__fifo)->mutex); pthread_cond_destroy(&(__fifo)->nofull); pthread_cond_destroy(&(__fifo)->noempty); + +#define FIFOGET(__fifo, __obj) do {\ + pthread_mutex_lock(&(__fifo)->mutex);\ + while(FIFOEMPTY(__fifo)) pthread_cond_wait(&(__fifo)->noempty, &(__fifo)->mutex); _FIFOGET(__fifo, __obj);\ + pthread_mutex_unlock(&(__fifo)->mutex); pthread_cond_signal(&(__fifo)->nofull);\ +} while(0) + +#define FIFOPUT(__fifo, __obj) do {\ + pthread_mutex_lock(&(__fifo)->mutex);\ + while(FIFOFULL(__fifo)) pthread_cond_wait(&(__fifo)->nofull, &(__fifo)->mutex); _FIFOPUT(__fifo, __obj);\ + pthread_mutex_unlock(&(__fifo)->mutex); pthread_cond_signal(&(__fifo)->noempty);\ +} while(0) + +#define FIFO_STRUCT(__sfifo, __fifodata, __fifotype, __fifosize) \ +struct __sfifo { unsigned size, head, tail; FIFO_STRUCT_I; __fifodata; __fifotype buf[__fifosize]; } + +#define FIFOINIT(__fifo, __fifosize) do { memset(__fifo, 0, sizeof( typeof((__fifo)[0]))); (__fifo)->size = __fifosize; FIFO_INIT_I(__fifo, __fifosize); } while(0) +#define FIFOEXIT(__fifo) do { FIFO_EXIT_I(__fifo); } while(0) +//----------------------------------------------------------- +FIFO_STRUCT(ofifo, int sd, struct rsp *, QRYFIFOMAX); +FIFO_STRUCT(ififo, int dno; int dnonum; struct ofifo *ofifo, struct qry *, QRYFIFOMAX); + #endif + +#define TERMNUM 32 +typedef struct qry { + #ifdef THREAD_MAX + idxrd_t *idx; + unsigned id,dno,results; + thread_mutex_t mutex; + #endif + int term[TERMNUM], terms; +} qry_t; + +int postcmp(post_t *a, post_t *b) { + if(a->f_t < b->f_t) return -1; + if(a->f_t > b->f_t) return 1; + return 0; +} + +int intersec_max; unsigned long long st_f_t; +#define IY(_x,_y) if(*++_y >= *_x) break +#define IX(_x,_y) if(*++_x >= *_y) break +#define INTERSECT(__x,__x_, __y,__y_) { __label__ icmp,end;\ + if (__x < __x_ && __y < __y_) \ + for(;;) {\ + if(*__y < *__x) { icmp: for(;;) { IY(__x,__y); IY(__x,__y); IY(__x,__y); IY(__x,__y); IY(__x,__y); IY(__x,__y); } if(__y >= __y_) goto end; }\ + if(*__x < *__y) { for(;;) { IX(__x,__y); IX(__x,__y); IX(__x,__y); IX(__x,__y); IX(__x,__y); IX(__x,__y); } if(__x >= __x_) goto end; }\ + if(*__x == *__y) { _r++; if(++__x >= __x_ || ++__y >= __y_) break; } else goto icmp;\ + } end:;\ +} + +unsigned qrysearch(qry_t *q, idxrd_t *idx) { + int f_t = 0, i, intersec_mx = intersec_max; + post_t *p, *pe, v[TERMNUM]; + unsigned did, elim, dids[TERMNUM][BLK_DIDNUM+31]; STAT(st_terms = q->terms>=8?7:q->terms); + + if(q->terms == 1) { // 1 Term query + if(!(f_t = postinit(v, q->term[0], idx, dids[0]))) + return 0; + for(i = 0; i < min(f_t,intersec_mx); i++) { + if((did = postnext(v, dids[0])) >= INT_MAX) break; + f_t++; + } + } else if(q->terms == 2) { // optimized 2 terms query + if(!postinit(&v[0], q->term[0], idx, dids[0]) || !postinit(&v[1], q->term[1], idx, dids[1])) + return 0; + if(v[1].f_t < v[0].f_t) { post_t t = v[0]; v[0] = v[1]; v[1] = t; } // swap + #ifdef SKIP_INTERVALS + unsigned *_xd = dids[0], xdnum; + unsigned *_yd = dids[1], ydnum; + if(v[0].f_t > BLK_DIDNUM) { + unsigned *_x = (unsigned *)v[0].bp, *x_ = _x+v[0].bnum, *x = _x, *xd; + unsigned *_y = (unsigned *)v[1].bp, *y_ = _y+v[1].bnum, *y = _y, *yd; + _xd[0] = _yd[0] = UINT_MAX; + for(;;) { unsigned x0 = x[0] == _xd[0], y0 = y[0] == _yd[0]; + if((x0?xd[0]:x[0]+1) <= y[1] && (y0?yd[0]+1:y[0]) <= x[1]) { + if(!x0) xdnum = postdec(&v[0], x - _x, xd = _xd); + if(!y0) ydnum = postdec(&v[1], y - _y, yd = _yd); + unsigned _r = 0; + INTERSECT(xd, _xd+xdnum, yd, _yd+ydnum); + f_t += _r; STAT(_r?st_ovl++:st_noovl++); + } + if(y[1] < x[1]) { if(++y >= y_) break; } + else if(x[1] < y[1]) { if(++x >= x_) break; } + else if(++x == x_ || ++y == y_) break; STAT(st_skip++); + } + } else if(v[1].f_t <= BLK_DIDNUM) { + xdnum = postdec(&v[0], 0, _xd); + ydnum = postdec(&v[1], 0, _yd); + unsigned _r = 0,*xd_=_xd+xdnum,*yd_=_yd+ydnum; + INTERSECT(_xd, xd_, _yd, yd_); f_t += _r; STAT(_r?st_ovl++:st_noovl++); + } else + #endif + for(did = 0;;) { + if(unlikely((did = postget(&v[0], did, dids[0])) >= INT_MAX)) break; + if(( elim = postget(&v[1], did, dids[1])) == did) { + if(++f_t >= intersec_mx) break; + did++; // top-k: doc scoring + heap insertmin + continue; + } else if(elim >= INT_MAX) break; + did = elim; + } + } else { // multiple terms conjunctive query + pe = &v[q->terms]; + for(p = v; p < pe; p++) + if(!postinit(p, q->term[p-v], idx, dids[p-v])) + return 0; + qsort(v, q->terms, sizeof(v[0]), (int(*)(const void*,const void*))postcmp); // sort by f_t + + for(did = 0;;did++) { a: + if(unlikely((did = postget(v, did, dids[0])) >= INT_MAX)) + return f_t; + for(p = &v[1]; p < pe; p++) { + if((elim = postget(p, did, dids[p-v])) == did) continue; + if(elim >= INT_MAX) + return f_t; + did = elim; + goto a; + } // top-k: doc scoring + heap insertmin + if(++f_t >= intersec_mx) break; + } + } + return f_t; +} + + #ifdef THREAD_MAX +qry_t *qrynew() { + qry_t *qry = calloc(1,sizeof(qry_t)); if(!qry) die("malloc failed\n"); + return qry; +} + +void qrydestroy(qry_t *qry) { free(qry); } +//------------------------------------------------ +typedef struct rsp { + qry_t *qry; + unsigned dno,dnonum,results; +} rsp_t; + +rsp_t *rspnew() { + rsp_t *rsp = calloc(1,sizeof(rsp_t)); if(!rsp) die("malloc failed\n"); + return rsp; +} + +void rspdestroy(rsp_t *rsp) { free(rsp); } + +//----------------------------------------------- +void thrqryini() {} +void thrqry_exit() {} + +void *thrqrysearch( struct ififo *ififo ) { + struct ofifo *ofifo = ififo->ofifo; + for(;;) { + struct qry *qry; + FIFOGET(ififo, qry); if(!qry) return NULL; + rsp_t *rsp = rspnew(); + rsp->qry = qry; + rsp->dno = ififo->dno; + rsp->dnonum = ififo->dnonum; + rsp->results = qrysearch(qry, &qry->idx[ififo->dno]); + FIFOPUT(ofifo, rsp); + } +} + +void *thrqryout( struct ofifo *ofifo ) { + for(;;) { + rsp_t *rsp; + FIFOGET(ofifo, rsp); if(!rsp) return NULL; + qry_t *qry = rsp->qry; + unsigned r = rsp->results; + rspdestroy(rsp); //thread_mutex_lock(&qry->mutex); + qry->results += r; + if(++qry->dno == rsp->dnonum) { + st_f_t += qry->results; + qrydestroy(qry); + } + } +} + #endif + +//------------------------------ Test + Benchmark ---------------------------------------------------- +#define QRYLEN 255 +int qline, temin = 1,temax = TERMNUM,tem=32, tex=0, qmax=1<<30; + +int qrybatch(idxrd_t *idx, char *fqname + #ifdef THREAD_MAX + ,struct ififo *ififos, int dnonum + #endif +) { + char s[QRYLEN+1],*p,*q; + int id=0; + FILE *fq; + + if(!(fq = fopen(fqname, "r+"))) + die("can't open file '%s'\n", fqname); + + while(fgets(s, QRYLEN, fq)) { ++qline; + s[strlen(s)-1]=0; + #ifdef THREAD_MAX + qry_t *qry = qrynew(); + #else + qry_t _qry,*qry = &_qry; + #endif + for(qry->terms=0,p=s; *p && qry->terms < TERMNUM; ) { + while(*p && (*p < '0' || *p > '9')) p++; if(!*p) break; + q = p; while(*p >= '0' && *p <= '9') p++; + qry->term[qry->terms++] = strtol(q, NULL, 10); + } + if(qry->terms >= temin && qry->terms <= temax) { ++id; tex = max(qry->terms,tex);tem = min(qry->terms,tem); + #ifdef THREAD_MAX + qry->id = id; + qry->idx = idx; + thread_mutex_init(&qry->mutex); + struct ififo *ififo; + for(ififo = ififos; ififo < ififos+dnonum; ififo++) + FIFOPUT(ififo, qry); + #else + st_f_t += qrysearch(qry, idx); + #endif + if(id >= qmax) break; + } + #ifdef THREAD_MAX + else qrydestroy(qry); + #endif + } + fclose(fq); + return id; +} + +void usage() { + fprintf(stderr, "\nTurboPFor Copyright (c) 2013-2019 Powturbo %s\n", __DATE__); + fprintf(stderr, "https://github.com/powturbo/TurboPFor\n\n"); + #ifdef THREAD_MAX + fprintf(stderr, "Benchmark: parallel intersections in compressed inverted index\n\n"); + #else + fprintf(stderr, "Benchmark: compressed intersections in inverted index\n\n"); + #endif + fprintf(stderr, "Usage: idxqry [options] \n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -nN N = max. intersections/query. ex. -n1k=100.000 -n1m=1.000.000\n"); + fprintf(stderr, " -mN N = minimum query terms (default 1)\n"); + fprintf(stderr, " -MN N = maximum query terms (default 16)\n"); + fprintf(stderr, " -rN N = number of iterations (default 3)\n"); + fprintf(stderr, " -qN N = max. number of queries\n"); + fprintf(stderr, " index created by 'idxcr' program\n"); + fprintf(stderr, "Ex. idxqry -n100k -m2 clueweb.sorted.i aol.txt\n"); + fprintf(stderr, "Ex. idxqry gov2.sorted.i 1mq.txt\n"); + fprintf(stderr, "8-16 GB RAM recommended\n\n"); + exit(-1); +} + +//---------------------------------------- Time --------------------------------------------------------------------- +typedef unsigned long long tm_t; +#define TM_T 1000000.0 + + #ifdef _WIN32 +#include +static LARGE_INTEGER tps; +static tm_t tmtime(void) { LARGE_INTEGER tm; QueryPerformanceCounter(&tm); return (tm_t)(tm.QuadPart*1000000/tps.QuadPart); } +static tm_t tminit() { QueryPerformanceFrequency(&tps); tm_t t0=tmtime(),ts; while((ts = tmtime())==t0); return ts; } + #else +#include +//static tm_t tmtime(void) { struct timeval tm; gettimeofday(&tm, NULL); return (tm_t)tm.tv_sec*1000000ull + tm.tv_usec; } +static tm_t tmtime(void) { struct timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); return (tm_t)tm.tv_sec*1000000ull + tm.tv_nsec/1000; } +static tm_t tminit() { tm_t t0=tmtime(),ts; while((ts = tmtime())==t0) {}; return ts; } + #endif +static double tmsec( tm_t tm) { return (double)tm/1000000.0; } +static double tmmsec(tm_t tm) { return (double)tm/1000.0; } +//-------------- +unsigned argtoi(char *s) { + char *p; unsigned n = strtol(s, &p, 10),f=1; + switch(*p) { + case 'k': f = 1000; break; + case 'm': f = 1000000; break; + case 'g': f = 1000000000; break; + case 'K': f = 1<<10; break; + case 'M': f = 1<<20; break; + case 'G': f = 1<<30; break; + } + return n*f; +} + +int main(int argc, char **argv ) { + int reps = 3,r; + tminit(); + int c, digit_optind = 0, this_option_optind = optind ? optind : 1, option_index = 0; + static struct option long_options[] = { {"", 0, 0, 'r'}, {0,0, 0, 0} }; + for(;;) { + if((c = getopt_long(argc, argv, "n:m:M:q:r:s:", long_options, &option_index)) == -1) break; + switch(c) { + case 0 : printf("Option %s", long_options[option_index].name); + if(optarg) printf (" with arg %s", optarg); printf ("\n"); break; + case 'q': qmax = atoi(optarg); break; + case 'r': reps = atoi(optarg); break; + case 'm': temin = argtoi(optarg); break; + case 'M': temax = argtoi(optarg); break; + case 'n': intersec_max = argtoi(optarg); break; + default: usage(); + } + } + if(argc <= optind) usage(); + char *fqname = argv[--argc]; + if(intersec_max) printf("Max. Intersections/query=%d\n", intersec_max); + else intersec_max=1<<30; + + idxrd_t idx[64]; + int fno, dnonum = 0; + for(fno = optind; fno < argc; fno++) { printf("%s\n", argv[fno]); + if(idxopen(&idx[dnonum++], argv[fno])) + die("can't open idx file '%s'\n", argv[optind]); + #ifndef THREAD_MAX + break; + #endif + } + + for(r=0; r < reps; r++) { STATINI; printf("#");fflush(stdout); + #ifdef THREAD_MAX + thrqryini(); + thread_t ithreads[THREAD_MAX]; int i; printf("!");fflush(stdout); + + struct ofifo _ofifo,*ofifo = &_ofifo; + FIFOINIT(ofifo, QRYFIFOMAX); + thread_t othread; + if(!(othread = thread_create((void *)thrqryout, ofifo))) die("Error thread_create.\n"); + + struct ififo _ififo[THREAD_MAX],*ififo; + for(i = 0; i < THREAD_MAX; i++) _ififo[i].dno = -1; + for(i = 0; i < dnonum; i++) { + ififo = &_ififo[i]; + FIFOINIT(ififo, QRYFIFOMAX); + ififo->dno = i; + ififo->dnonum = dnonum; + ififo->ofifo = ofifo; + if(!(ithreads[i] = thread_create((void *)thrqrysearch, ififo))) + die("Error thread_create.\n"); + } + #endif + st_f_t = 0; tm_t t0 = tminit(); + int id = qrybatch(idx, fqname + #ifdef THREAD_MAX + , _ififo, dnonum + #endif + ); + #ifdef THREAD_MAX + end:for(i = 0; i < dnonum; i++) { ififo = &_ififo[i]; FIFOPUT(ififo, NULL); } + for(i = 0; i < dnonum; i++) thread_join(ithreads[i]); + for(i = 0; i < dnonum; i++) { ififo = &_ififo[i]; FIFOEXIT(ififo); } + FIFOPUT(ofifo, NULL); + thread_join(othread); + FIFOEXIT(ofifo); + thrqry_exit(); + #endif + tm_t t1 = tmtime()-t0; + printf("qry=%d/%.2fs. [%.1f q/s] [%.3f ms/q].%llu\n", id, tmsec(t1), (double)id/tmsec(t1), tmmsec(t1)/(double)id, st_f_t ); + if(r 20?20:5); + } + for(r = 0; r < dnonum; r++) idxclose(&idx[r]); + #ifdef STATS + if(st_tot) { printf("Terms=[%d-%d] Integers: total=%llu decompressed=%llu ratio=%.2f%%. %lld docs found\n", tem, tex, st_tot, st_dec, (double)st_dec*100/(double)st_tot, st_f_t); + int i; printf("Ratio:");for(i=2;i<8;i++) if(st_tots[i]) printf("%d:%.2f ", i, (double)st_decs[i]*100/(double)st_tots[i]); + } + printf("ovl=%llu,novl=%llu,skip=%lld stno=%lld\n", st_ovl, st_noovl, st_skip, st_noi); + #endif +} diff --git a/src/ext/for/idxseg.c b/src/ext/for/idxseg.c new file mode 100644 index 00000000000..85c0682ace8 --- /dev/null +++ b/src/ext/for/idxseg.c @@ -0,0 +1,133 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// idxseg.c - Inverted Index - Create partitions from DocId file for prallel query evaluation +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif + +#include +#include "conf.h" + +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#define max(x,y) (((x)>(y)) ? (x) : (y)) +#endif + +unsigned argtoi(char *s) { + char *p; unsigned n = strtol(s, &p, 10),f=1; + switch(*p) { + case 'k': f = 1000; break; + case 'm': f = 1000000; break; + case 'g': f = 1000000000; break; + case 'K': f = 1<<10; break; + case 'M': f = 1<<20; break; + case 'G': f = 1<<30; break; + } + return n*f; +} + +void usage() { + fprintf(stderr, "\nTurboPFor Copyright (c) 2013-2019 Powturbo %s\n", __DATE__); + fprintf(stderr, "Partitioning\n"); + fprintf(stderr, "Usage: idxseg -nNs -sPs \n"); + fprintf(stderr, "Ns=total number of documents. Ps=number of partitions\n"); + fprintf(stderr, " s = modifier s:k,m,g=(1000,1 million,1 billion) s:K,M,G=(1024,1MB,1GB) ex. 64k or 64K\n"); + fprintf(stderr, "ex. ./idxseg gov2.sorted . -n26m -s8\n"); + fprintf(stderr, "ex. ./idxseg clueweb09.sorted . -n60m -s8\n\n"); + fprintf(stderr, "ex. parallel query evaluation\n\n"); + fprintf(stderr, "./idxqry ~/gov2.sorted.s*.i ~/aol.txt\n\n"); + exit(-1); +} + +#define SEGMAX 64 +int main(int argc, char *argv[]) { unsigned sb = 8,fno,n=25300000; char *path=""; + int c, digit_optind = 0, this_option_optind = optind ? optind : 1, option_index = 0; + static struct option long_options[] = { {"r", 0, 0, 'r'}, {0,0, 0, 0} }; + for(;;) { + if((c = getopt_long(argc, argv, "s:n:", long_options, &option_index)) == -1) break; + switch(c) { + case 0 : printf("Option %s", long_options[option_index].name); if(optarg) printf (" with arg %s", optarg); printf ("\n"); break; + case 's': sb = atoi(optarg); break; + case 'n': n = argtoi(optarg); break; + default: usage(); + } + } + if(argc - optind < 2) usage(); + path = argv[--argc]; + #ifndef SPOW2 + sb = (n+sb-1) / sb; + #endif + for(fno = optind; fno < argc; fno++) { + unsigned snum = 0; + unsigned long long inum=0; + char outname[257], *inname = argv[fno]; + strcpy(outname, path); + char *p = strrchr(inname,'/'); if(!p) p = strrchr(inname,'\\'); if(!p) p=inname; strcat(outname, p); strcat(outname,".s"); + + FILE *fi = fopen(inname, "rb"); if(!fi) { fprintf(stderr, "open error '%s'", inname); perror(inname); exit(-1); } + FILE *fo[SEGMAX] = {0}; + unsigned as[SEGMAX] = {0}, an[SEGMAX] = {0},s; + + unsigned *in = NULL,*ip, num, numx = 0, tid = 0,didmax=0; + while(fread(&num, 1, 4, fi) == 4) { inum+=num; + if(num > numx) { + numx = num; + if(!(in = realloc(in, num*4+64))) die("malloc err=%u", num); + } + + if(fread(in, 4, num, fi) != num) break; // read docid list + for(ip = in; ip < in+num; ip++) { if(*ip > didmax) didmax=*ip; + #ifdef SPOW2 + s = (*ip) >> sb; + #else + s = (*ip) / sb; + #endif + snum = max(snum,s+1); as[s] = as[s]?as[s]:(ip - in); an[s]++; + } + + for(s = 0; s < snum; s++) { + FILE *f = fo[s]; + if(!f) { + char oname[257]; sprintf(oname, "%s%.2d", outname, s); + f = fopen(oname,"wb"); if(!f) { fprintf(stderr, "creat error '%s'", oname); perror(oname); exit(-1); } + fo[s] = f; + int i; for(i = 0; i < tid; i++) { unsigned z = 0; if(fwrite(&z, 1, 4, f) != 4) die("write error"); printf("#");fflush(stdout); } + } + unsigned n = an[s]; + if(fwrite(&n, 1, 4, f) != 4 || (n && fwrite(in+as[s], 4, n, f) != n)) die("write error"); + as[s] = an[s] = 0; + } + tid++; + } + for(s = 0; s < snum; s++) if(fo[s]) fclose(fo[s]); printf("didmax=%u num docid=%llu\n", didmax, inum); + free(in); + } +} diff --git a/src/ext/for/index.md b/src/ext/for/index.md new file mode 100644 index 00000000000..34073b64e13 --- /dev/null +++ b/src/ext/for/index.md @@ -0,0 +1,567 @@ +TurboPFor: Fastest Integer Compression [![Build Status](https://travis-ci.org/powturbo/TurboPFor.svg?branch=master)](https://travis-ci.org/powturbo/TurboPFor) +====================================== +* **TurboPFor: The new synonym for "integer compression"** + * :new: (2019.7) all TurboPFor functions now available under 64 bits ARMv8 including NEON SIMD. + * 100% C (C++ headers), as simple as memcpy + * :+1: **Java** Critical Natives/JNI. Access TurboPFor **incl. SIMD/AVX2!** from Java as fast as calling from C + * :sparkles: **FULL** range 8/16/32/64 bits scalar + 16/32/64 bits SIMD functions + * No other "Integer Compression" compress/decompress faster + * :sparkles: Direct Access, **integrated** (SIMD/AVX2) FOR/delta/Delta of Delta/Zigzag for sorted/unsorted arrays + * :new: **16 bits** + **64 bits** SIMD integrated functions +* **For/PFor/PForDelta** + * **Novel TurboPFor** (PFor/PForDelta) scheme w./ **direct access** + **SIMD/AVX2**. :new:**+RLE** + * Outstanding compression/speed. More efficient than **ANY** other fast "integer compression" scheme. + * Compress 70 times faster and decompress up to 4 times faster than OptPFD +* **Bit Packing** + * Fastest and most efficient **"SIMD Bit Packing"** **10 Billions integers/sec (40Gb/s!)** + * Scalar **"Bit Packing"** decoding nearly as fast as SIMD-Packing in realistic (No "pure cache") scenarios + * **Direct/Random Access** : Access any single bit packed entry with **zero decompression** +* **Variable byte** + * Scalar **"Variable Byte"** faster than **ANY** other (incl. SIMD) implementation +* **Simple family** + * **Novel** **"Variable Simple"** (incl. **RLE**) faster and more efficient than simple16, simple-8b +* **Elias fano** + * Fastest **"Elias Fano"** implementation w/ or w/o SIMD/AVX2 ++ **Transform** + * Scalar & SIMD Transform: Delta, Zigzag, Zigzag of delta, XOR, Transpose/Shuffle, + * :new: **lossy** floating point compression with *TurboPFor* or [TurboTranspose](https://github.com/powturbo/TurboTranspose)+lz77 +* **Floating Point Compression** + * Delta/Zigzag + improved gorilla style + (Differential) Finite Context Method FCM/DFCM floating point compression + * Using **TurboPFor**, unsurpassed compression and more than 5 GB/s throughput + * :new: Error bound **lossy** floating point compression +* :new: **Time Series Compression** + * **Fastest Gorilla** 16/32/64 bits style compression (:new: **zigzag of delta** + **RLE**). + * can compress times series to only 0.01%. Speed > 10 GB/s compression and > 13 GB/s decompress. +* **Inverted Index ...do less, go fast!** + * Direct Access to compressed *frequency* and *position* data w/ zero decompression + * **Novel** **"Intersection w/ skip intervals"**, decompress the minimum necessary blocks (**~10-15%)!**. + * **Novel** Implicit skips with zero extra overhead + * **Novel** Efficient **Bidirectional** Inverted Index Architecture (forward/backwards traversal) incl. "integer compression". + * more than **2000! queries per second** on GOV2 dataset (25 millions documents) on a **SINGLE** core + * :sparkles: Revolutionary Parallel Query Processing on Multicores **> 7000!!! queries/sec** on a simple quad core PC.
+ **...forget** ~~Map Reduce, Hadoop, multi-node clusters,~~ ... + +### Integer Compression Benchmark: +- :new: Download [IcApp](https://sites.google.com/site/powturbo/downloads) a new benchmark for TurboPFor
+ for testing allmost all integer and floating point file types. +- Practical (No **PURE** cache) "integer compression" benchmark w/ **large** arrays. +- CPU: Skylake i7-6700 3.4GHz gcc 7.2 **single** thread + +##### - Synthetic data: + - Generate and test (zipfian) skewed distribution (100.000.000 integers, Block size=128/256)
+ Note: Unlike general purpose compression, a small fixed size (ex. 128 integers) is in general used in "integer compression". + Large blocks involved, while processing queries (inverted index, search engines, databases, graphs, in memory computing,...) need to be entirely decoded. + + ./icbench -a1.5 -m0 -M255 -n100M ZIPF + +|C Size|ratio%|Bits/Integer|C MB/s|D MB/s|Name| +|--------:|-----:|--------:|----------:|----------:|--------------| +|62,939,886| 15.7| 5.04|**1588**|**9400**|**TurboPFor256**| +|63,392,759| 15.8| 5.07|1320|6432|**TurboPFor**| +|63,392,801| 15.8| 5.07|1328|924|**TurboPForDA**| +|65,060,504| 16.3| 5.20|60|2748|[FP_SIMDOptPFor](#FastPFor)| +|65,359,916|16.3| 5.23| 32|2436|PC_OptPFD| +|73,477,088|18.4| 5.88|408|2484|PC_Simple16| +|73,481,096| 18.4| 5.88|624|8748|[FP_SimdFastPFor](#FastPFor) 64Ki *| +|76,345,136| 19.1| 6.11|980|2612|**VSimple**| +|91,947,533| 23.0| 7.36|284|11737|[QMX](#QMX) 64k *| +|93,285,864| 23.3| 7.46|1568|10232|[FP_GroupSimple](#FastPFor) 64Ki *| +|95,915,096|24.0| 7.67| 848|3832|Simple-8b| +|99,910,930| 25.0| 7.99|**13976**|**11872**|**TurboPackV**| +|99,910,930| 25.0| 7.99|9468|9404|**TurboPack**| +|99,910,930| 25.0| 7.99|8420|8876|**TurboFor**| +|100,332,929| 25.1| 8.03|**14320**|**12124**|**TurboPack256V**| +|101,015,650| 25.3| 8.08|9520|9484|**TurboVByte**| +|102,074,663| 25.5| 8.17|5712|7916|[MaskedVByte](#MaskedVByte)| +|102,074,663| 25.5| 8.17|2260|4208|[PC_Vbyte](#PolyCom)| +|102,083,036| 25.5| 8.17|5200|4268|[FP_VByte](#FastPFor)| +|112,500,000| 28.1| 9.00|1528|**12140**|[VarintG8IU](#VarintG8IU)| +|125,000,000| 31.2|10.00|4788|11288|[StreamVbyte](#StreamVByte)| +|400,000,000| 100.00| 32.00| 8960|8948|Copy| +| | | | N/A | N/A |EliasFano| + +(*) codecs inefficient for small block sizes are tested with 64Ki integers/block. + +- MB/s: 1.000.000 bytes/second. **1000 MB/s = 1 GB/s**
+- **#BOLD** = pareto frontier.
+- FP=FastPFor SC:simdcomp PC:Polycom
+- TurboPForDA,TurboForDA: Direct Access is normally used when accessing few individual values.
+- Eliasfano can be directly used only for increasing sequences +------------------------------------------------------------------------ +##### - Data files: + - gov2.sorted from [DocId data set](#DocId) Block size=128/Delta coding + + ./icbench -fS -r gov2.sorted + +![Speed/Ratio](ext/gov2.png "Speed/Ratio: Decompression") + +|Size |Ratio %|Bits/Integer|C Time MB/s|D Time MB/s|Function | +|-----------:|------:|-----:|-------:|-------:|---------------------| +| 3,321,663,893| 13.9| 4.44|**1320**|**6088**|**TurboPFor**| +| 3,339,730,557| 14.0| 4.47| 32| 2144|PC.OptPFD| +| 3,350,717,959| 14.0| 4.48|**1536**|**7128**|**TurboPFor256**| +| 3,501,671,314| 14.6| 4.68| 56| 2840|**VSimple**| +| 3,768,146,467| 15.8| 5.04|**3228**| 3652|**EliasFanoV**| +| 3,822,161,885| 16.0| 5.11| 572| 2444|PC_Simple16| +| 4,521,326,518| 18.9| 6.05| 836| 3296|Simple-8b| +| 4,649,671,427| 19.4| 6.22|3084|3848|**TurboVbyte**| +| 4,955,740,045| 20.7| 6.63|**7064**|**10268**|**TurboPackV**| +| 4,955,740,045| 20.7| 6.63|5724|8020|**TurboPack**| +| 5,205,324,760|21.8| 6.96|6952|9488|SC_SIMDPack128| +| 5,393,769,503| 22.5| 7.21|**9912**|**11588**|**TurboPackV256**| +| 6,221,886,390| 26.0| 8.32|6668|6952|**TurboFor**| +| 6,221,886,390| 26.0| 8.32|6644| 2260|**TurboForDA**| +| 6,699,519,000| 28.0| 8.96| 1888| 1980|FP_Vbyte| +| 6,700,989,563| 28.0| 8.96| 2740| 3384|MaskedVByte| +| 7,622,896,878| 31.9|10.20| 836|4792|VarintG8IU| +| 8,060,125,035| 33.7|11.50| 3536|8684|Streamvbyte| +| 8,594,342,216| 35.9|11.50|5228|6376|libfor| +|23,918,861,764|100.0|32.00|5824|5924|Copy| + +Block size: 64Ki = 256k bytes. Ki=1024 Integers + +|Size |Ratio %|Bits/Integer|C Time MB/s|D Time MB/s|Function | +|----------:|-----:|----:|------:|------:|---------------------| +| 3,164,940,562| 13.2|**4.23**|**1344**|**6004**|**TurboPFor 64Ki**| +| 3,273,213,464| 13.7| 4.38|**1496**|**7008**|**TurboPFor256 64Ki**| +| 3,965,982,954| 16.6| 5.30|**1520**| 2452|[lz4](#lz4)+DT 64Ki| +| 4,234,154,427| 17.7| 5.66| 436| 5672|qmx 64Ki| +| 6,074,995,117| 25.4| 8.13| 1976| 2916|[blosc_lz4](#blosc) 64Ki| +| 8,773,150,644| 36.7|11.74| 2548|5204|blosc_lz 64Ki| + +"lz4+DT 64Ki" = Delta+Transpose from TurboPFor + lz4
+"blosc_lz4" internal lz4 compressor+vectorized shuffle + +##### - Time Series: +- Test file [Timestamps: ts.txt(sorted)](https://github.com/zhenjl/encoding/tree/master/benchmark/data) + + ./icapp -Ft ts.txt -I15 -J15 + +|Function |C MB/s| size |ratio%| D MB/s|Text +|----------------|-----:|--------:|------:|------:|--------------------| +|bvzenc32 |**10632**|45,909|0.008|**12823**|ZigZag| +|bvzzenc32 |**8914**|56,713|0.010|**13499**|ZigZag Delta of delta| +|vsenc32 |**12294**|140,400| 0.024 |12877 |Variable Simple| +|p4nzenc256v32 | 1932| 596,018| 0.10 |13326 |TurboPFor256 ZigZag| +|p4ndenc256v32 | 1961| 596,018| 0.10 |13339 |TurboPFor256 Delta| +|bitndpack256v32 |**12564**|909,189| 0.16 |13505 |TurboPackV256 Delta| +|p4nzenc32 | 1810| 1,159,633| 0.20 | 8502 |TurboPFor ZigZag| +|p4nzenc128v32 | 1795| 1,159,633| 0.20 |13338 |TurboPFor ZigZag| +|bitnzpack256v32 | 9651| 1,254,757| 0.22 |**13503**|TurboPackV256 ZigZag| +|bitnzpack128v32 |10155| 1,472,804| 0.26 |13380 |TurboPackV ZigZag| +|vbddenc32 | 6198| 18,057,296| 3.13 |10982 |TurboVByte Delta of delta| +|memcpy |13397|577,141,992|100.00|| + +##### - Transpose/Shuffle (no compression) + ./icbench -eTRANSFORM ZIPF + +|Size |C Time MB/s|D Time MB/s|Function| +|----------:|------:|------:|-----------------------------------| +|100,000,000|**9400**|**9132**|**TPbyte 4** TurboPFor Byte Transpose/shuffle AVX2| +|100,000,000|8784|8860|**TPbyte 4** TurboPFor Byte Transpose/shuffle SSE| +|100,000,000|7688|7656|Blosc_Shuffle AVX2| +|100,000,000|**5204**|**7460**|**TPnibble 4** TurboPFor Nibble Transpose/shuffle SSE| +|100,000,000|6620|6284|Blosc shuffle SSE| +|100,000,000|3156|3372|Bitshuffle AVX2| +|100,000,000|2100|2176|Bitshuffle SSE| + +##### - (Lossy) Floating point compression: + ./icapp -Fd file " 64 bits floating point raw file + ./icapp -Ff file " 32 bits floating point raw file + ./icapp -Fcf file " text file with miltiple entries (ex. 8.657,56.8,4.5 ...) + ./icapp -Ftf file " text file (1 entry per line) + ./icapp -Ftf file -v5 " + display the first entries read + ./icapp -Ftf file.csv -K3 " but 3th column in a csv file (ex. number,Text,456.5 -> 456.5 + ./icapp -Ftf file -g.001 " lossy compression with allowed error 0.001 + +- see also [TurboTranspose](https://github.com/powturbo/TurboTranspose) + +##### - Compressed Inverted Index Intersections with GOV2
+ GOV2: 426GB, 25 Millions documents, average doc. size=18k. + + + Aol query log: 18.000 queries
+ **~1300** queries per second (single core)
+ **~5000** queries per second (quad core)
+ Ratio = 14.37% Decoded/Total Integers. + + + TREC Million Query Track (1MQT):
+ **~1100** queries per second (Single core)
+ **~4500** queries per second (Quad core CPU)
+ Ratio = 11.59% Decoded/Total Integers. + +- Benchmarking intersections (Single core, AOL query log) + +| max.docid/q|Time s| q/s | ms/q | % docid found| +|-----------------:|---:|----:|-----:|-------:| +|1.000|7.88|2283.1|0.438|81| +|10.000|10.54|1708.5|0.585|84| +| ALL |13.96|1289.0|0.776|100| +q/s: queries/second, ms/q:milliseconds/query + +- Benchmarking Parallel Query Processing (Quad core, AOL query log) + +| max.docid/q|Time s| q/s | ms/q | % docids found| +|-----------------:|----:|----:|-----:|-------:| +|1.000|2.66|6772.6|0.148|81| +|10.000|3.39|5307.5|0.188|84| +|ALL|3.57|5036.5|0.199|100| + +###### Notes: +- Search engines are spending 90% of the time in intersections when processing queries. +- Most search engines are using pruning strategies, caching popular queries,... to reduce the time for intersections and query processing. +- As indication, google is processing [40.000 Queries per seconds](http://www.internetlivestats.com/google-search-statistics/), +using [900.000 multicore servers](https://www.cloudyn.com/blog/10-facts-didnt-know-server-farms/) for searching [8 billions web pages](http://searchenginewatch.com/sew/study/2063479/coincidentally-googles-index-size-jumps) (320 X size of GOV2). +- Recent "integer compression" GOV2 experiments (best paper at ECIR 2014) [On Inverted Index Compression for Search Engine Efficiency](http://www.dcs.gla.ac.uk/~craigm/publications/catena14compression.pdf) using 8-core Xeon PC are reporting 1.2 seconds per query (for 1.000 Top-k docids). + +### Compile: + Download or clone TurboPFor + git clone git://github.com/powturbo/TurboPFor.git + cd TurboPFor + + To benchmark external libraries: + git clone --recursive git://github.com/powturbo/TurboPFor.git + cd TurboPFor + +###### Linux, Windows (MingW), Clang,... (see also makefile) + make + or + make AVX2=1 + + Include external libs + make CODEC1=1 CODEC2=1 + + Disable SIMD + make NSIMD=1 + +###### Windows visual c++ + nmake /f makefile.vs + +### Testing: +##### - Synthetic data (use ZIPF parameter): + + benchmark groups of "integer compression" functions
+ + ./icbench -eBENCH -a1.2 -m0 -M255 -n100M ZIPF + ./icbench -eBITPACK/VBYTE -a1.2 -m0 -M255 -n100M ZIPF + + >*Type "icbench -l1" for a list* + + >*-zipfian distribution alpha = 1.2 (Ex. -a1.0=uniform -a1.5=skewed distribution)
+ -number of integers = 100.000.000
+ -integer range from 0 to 255
* + + + Unsorted lists: individual function test (ex. Copy TurboPack TurboPFor)
+ + ./icbench -a1.5 -m0 -M255 -ecopy/turbopack/turbopfor/turbopack256v ZIPF + + + Unsorted lists: Zigzag encoding w/ option **-fz** or FOR encoding
+ + ./icbench -fz -eturbovbyte/turbopfor/turbopackv ZIPF + ./icbench -eturboforv ZIPF + + + Sorted lists: differential coding w/ option **-fs** (increasing) or **-fS** (strictly increasing)
+ + ./icbench -fs -eturbopack/turbopfor/turbopfor256v ZIPF + + + Generate interactive "file.html" plot for browsing + + ./icbench -p2 -S2 -Q3 file.tbb + + + Unit test: test function from bit size 0 to 32 + + ./icbench -m0 -M32 -eturbpfor -fu + ./icbench -m0 -M8 -eturbopack -fs -n1M + +##### - Data files: + - Raw 32 bits binary data file [Test data](https://github.com/ot/partitioned_elias_fano/tree/master/test/test_data) + + ./icbench file + ./icapp file + ./icapp -Fs file "16 bits raw binary file + ./icapp -Fu file "32 bits raw binary file + ./icapp -Fl file "64 bits raw binary file + ./icapp -Ff file "32 bits raw floating point binary file + ./icapp -Fd file "64 bits raw floating point binary file + + - Text file: 1 entry per line. [Test data: ts.txt(sorted) and lat.txt(unsorted)](https://github.com/zhenjl/encoding/tree/master/benchmark/data)) + + ./icbench -eBENCH -fts ts.txt + ./icbench -eBENCH -ft lat.txt + + ./icapp -Fts data.txt "text file, one 16 bits integer per line + ./icapp -Ftu ts.txt "text file, one 32 bits integer per line + ./icapp -Ftl ts.txt "text file, one 64 bits integer per line + ./icapp -Ftf file "text file, one 32 bits floating point (ex. 8.32456) per line + ./icapp -Ftd file "text file, one 64 bits floating point (ex. 8.324567789) per line + ./icapp -Ftd file -v5 "like prev., display the first 100 values read + ./icapp -Ftd file -v5 -g.00001 "like prev., error bound lossy floating point compression + ./icapp -Ftt file "text file, timestamp in seconds iso-8601 -> 32 bits integer (ex. 2018-03-12T04:31:06) + ./icapp -FtT file "text file, timestamp in milliseconds iso-8601 -> 64 bits integer (ex. 2018-03-12T04:31:06.345) + ./icapp -Ftl -D2 -H file "skip 1th line, convert numbers with 2 decimal digits to 64 bits integers (ex. 456.23 -> 45623) + ./icapp -Ftl -D2 -H -K3 file.csv "like prev., use the 3th number in the line (ex. label=3245, text=99 usage=456.23 -> 456.23 ) + ./icapp -Ftl -D2 -H -K3 -k| file.csv "like prev., use '|' as separator + + - Text file: multiple numbers separated by non-digits (0..9,-,.) characters (ex. 134534,-45678,98788,4345, ) + + ./icapp -Fc data.txt "text file, 32 bits integers (ex. 56789,3245,23,678 ) + ./icapp -Fcd data.txt "text file, 64 bits floting-point numbers (ex. 34.7689,5.20,45.789 ) + + - Multiblocks of 32 bits binary file. (Example gov2 from [DocId data set](#DocId))
+ Block format: [n1: #of Ids][Id1] [Id2]...[IdN] [n2: #of Ids][Id1][Id2]...[IdN]... + + ./icbench -fS -r gov2.sorted + + +##### - Intersections: + 1 - Download Gov2 (or ClueWeb09) + query files (Ex. "1mq.txt") from [DocId data set](#DocId)
+ 8GB RAM required (16GB recommended for benchmarking "clueweb09" files). + + 2 - Create index file + + + ./idxcr gov2.sorted . + + + >*create inverted index file "gov2.sorted.i" in the current directory* + + 3 - Test intersections + + + ./idxqry gov2.sorted.i 1mq.txt + + + >*run queries in file "1mq.txt" over the index of gov2 file* + +##### - Parallel Query Processing: + 1 - Create partitions + + + ./idxseg gov2.sorted . -26m -s8 + + + >*create 8 (CPU hardware threads) partitions for a total of ~26 millions document ids* + + 2 - Create index file for each partition + + + ./idxcr gov2.sorted.s* + + + >*create inverted index file for all partitions "gov2.sorted.s00 - gov2.sorted.s07" in the current directory* + + 3 - Intersections: + + delete "idxqry.o" file and then type "make para" to compile "idxqry" w. multithreading + + + ./idxqry gov2.sorted.s*.i 1mq.txt + + >*run queries in file "1mq.txt" over the index of all gov2 partitions "gov2.sorted.s00.i - gov2.sorted.s07.i".* + +### Function usage: +See benchmark "icbench" program for "integer compression" usage examples. +In general encoding/decoding functions are of the form: + + >**char *endptr = encode( unsigned *in, unsigned n, char *out, [unsigned start], [int b])**
+ endptr : set by encode to the next character in "out" after the encoded buffer
+ in : input integer array
+ n : number of elements
+ out : pointer to output buffer
+ b : number of bits. Only for bit packing functions
+ start : previous value. Only for integrated delta encoding functions + + + >**char *endptr = decode( char *in, unsigned n, unsigned *out, [unsigned start], [int b])**
+ endptr : set by decode to the next character in "in" after the decoded buffer
+ in : pointer to input buffer
+ n : number of elements
+ out : output integer array
+ b : number of bits. Only for bit unpacking functions
+ start : previous value. Only for integrated delta decoding functions + + **Simple high level functions:** + >**size_t compressed_size = encode( unsigned *in, size_t n, char *out)**
+ compressed_size : number of bytes written into compressed output buffer out
+ + >**size_t compressed_size = decode( char *in, size_t n, unsigned *out)**
+ compressed_size : number of bytes read from compressed input buffer in
+ +### Function syntax: + - {vb | p4 | bit | vs}[n][d | d1 | f | fm | z ]{enc/dec | pack/unpack}[| 128V | 256V][8 | 16 | 32 | 64]:
+ vb: variable byte
+ p4: turbopfor
+ vs: variable simple
+ bit: bit packing
+ n : high level array functions for large arrays. + + '' : encoding for unsorted integer lists
+ 'd' : delta encoding for increasing integer lists (sorted w/ duplicate)
+ 'd1': delta encoding for strictly increasing integer lists (sorted unique)
+ 'f' : FOR encoding for sorted integer lists
+ 'z' : ZigZag encoding for unsorted integer lists
+ + 'enc' or 'pack' : encode or bitpack
+ 'dec' or 'unpack': decode or bitunpack
+ 'NN' : integer size (8/16/32/64)
+ +header files to use with documentation:
+ +| c/c++ header file|Integer Compression functions| examples | +|------------|-----------------------------|-----------------| +|vint.h|variable byte| vbenc32/vbdec32 vbdenc32/vbddec32 vbzenc32/vbzdec32 | +|vsimple.h|variable simple| vsenc64/vsdec64 | +|vp4.h|TurboPFor| p4enc32/p4dec32 p4denc32/p4ddec32 p4zenc32/p4zdec32 | +|bitpack.h|Bit Packing, For, +Direct Access| bitpack256v32/bitunpack256v32 bitforenc64/bitfordec64| +|eliasfano.h|Elias Fano| efanoenc256v32/efanoc256v32 | + +Note: Some low level functions (like p4enc32) are limited to 128/256 (SSE/AVX2) integers per call. + +### Environment: +###### OS/Compiler (64 bits): +- Linux: GNU GCC (>=4.6) +- clang (>=3.2) +- Windows: MinGW-w64 (no parallel query processing demo app) +- Visual c++ (VS2008-VS2017) +- Linux aarch64 for 64 bits ARM CPU : gcc + +###### Multithreading: +- All TurboPFor integer compression functions are thread safe + +### References: + +* **Benchmark references:** + * [FastPFor](https://github.com/lemire/FastPFor) + [Simdcomp](https://github.com/lemire/simdcomp): SIMDPack FPF, Vbyte FPF, VarintG8IU, StreamVbyte, GroupSimple + * [Optimized Pfor-delta compression code](http://jinruhe.com): OptPFD/OptP4, Simple16 (limited to 28 bits integers) + * [MaskedVByte](http://maskedvbyte.org/). See also: [Vectorized VByte Decoding](http://engineering.indeed.com/blog/2015/03/vectorized-vbyte-decoding-high-performance-vector-instructions/) + * [Streamvbyte](https://github.com/lemire/streamvbyte). + * [Index Compression Using 64-Bit Words](http://people.eng.unimelb.edu.au/ammoffat/abstracts/am10spe.html): Simple-8b (speed optimized version tested) + * [libfor](https://github.com/cruppstahl/for) + * [Compression, SIMD, and Postings Lists](http://www.cs.otago.ac.nz/homepages/andrew/papers/) QMX integer compression from the "simple family" + * [lz4](https://github.com/Cyan4973/lz4). included w. block size 64K as indication. Tested after preprocessing w. delta+transpose + * [blosc](https://github.com/Blosc/c-blosc). blosc is like transpose/shuffle+lz77. Tested blosc+lz4 and blosclz incl. vectorizeed shuffle.
+ * [Document identifier data set](http://lemire.me/data/integercompression2014.html) + +* **Integer compression publications:** + * :green_book:[In Vacuo and In Situ Evaluation of SIMD Codecs (TurboPackV,TurboPFor/QMX)](http://dl.acm.org/citation.cfm?id=3015023) + [paper](http://www.cs.otago.ac.nz/homepages/andrew/papers/) + * :green_book:[SIMD Compression and the Intersection of Sorted Integers](http://arxiv.org/abs/1401.6399) + * :green_book:[Partitioned Elias-Fano Indexes](http://www.di.unipi.it/~ottavian/files/elias_fano_sigir14.pdf) + * :green_book:[On Inverted Index Compression for Search Engine Efficiency](http://www.dcs.gla.ac.uk/~craigm/publications/catena14compression.pdf) + * :green_book:[Google's Group Varint Encoding](http://static.googleusercontent.com/media/research.google.com/de//people/jeff/WSDM09-keynote.pdf) + * :green_book:[Integer Compression tweets](https://twitter.com/search?q=%23integercompression&src=typd) + * :green_book:[Efficient Compression of Scientific Floating-Point Data and An Application in Structural Analysis](https://www.jstage.jst.go.jp/article/jsces/2017/0/2017_20170002/_article) + * :green_book:[SPDP is a compression/decompression algorithm for binary IEEE 754 32/64 bits floating-point data](http://cs.txstate.edu/~burtscher/research/SPDPcompressor/)
+ :green_book:[ SPDP - An Automatically Synthesized Lossless Compression Algorithm for Floating-Point Data](http://cs.txstate.edu/~mb92/papers/dcc18.pdf) + [DCC 2018](http://www.cs.brandeis.edu//~dcc/Programs/Program2018.pdf) + +* **Applications:** + * [Graph500](https://github.com/julianromera/graph500) + * [Small Polygon Compression](https://arxiv.org/abs/1509.05505) + [Poster](http://abhinavjauhri.me/publications/dcc_poster_2016.pdf) + [code](https://github.com/ajauhri/bignum_compression) + * [Parallel Graph Analysis (Lecture 18)](http://www.cs.rpi.edu/~slotag/classes/FA16/) + [code](http://www.cs.rpi.edu/~slotag/classes/FA16/handson/lec18-comp2.cpp) + +Last update: 15 Jul 2019 + +## APPENDIX: icbench Integer Compression Benchmark + +##### TurboPFor + external libraries +
+TurboPFor               	https://github.com/powturbo/TurboPFor
+FastPFor (FP)              	https://github.com/lemire/FastPFor
+lz4                     	https://github.com/Cyan4973/lz4
+LittleIntPacker (LI)       	https://github.com/lemire/LittleIntPacker
+MaskedVbyte             	http://maskedvbyte.org
+Polycom (PC)               	https://github.com/encode84/bcm
+simdcomp (SC)              	https://github.com/lemire/simdcomp
+Simple-8b optimized     	https://github.com/powturbo/TurboPFor
+Streamvbyte             	https://github.com/lemire/streamvbyte
+VarintG8IU              	https://github.com/lemire/FastPFor
+
+ +##### Functions integrated into 'icbench' for benchmarking +
+Codec group:
+TURBOPFOR        TurboPFor library TurboPFor256V/TurboPack256V/TurboPFor256N/TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboForDA/EliasFano/VSimple/TurboPForN/TurboPackN/TurboPForDI
+DEFAULT          Default TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboFor/TurboPForN/TurboPackN/TurboPForDI/TurboPFor256V/TurboPack256V/TurboPFor256N
+BENCH            Benchmark TurboPFor/TurboPackV/TurboVByte/TurboPack/QMX/FP.SimdFastPfor/FP.SimdOptPFor/MaskedVbyte/StreamVbyte
+EFFICIENT        Efficient TurboPFor/vsimple/turbovbyte
+TRANSFORM        transpose/shufle,delta,zigzag tpbyte4s/tpbyte,4/tpnibble,4/ZigZag_32/Delta_32/BitShuffle,4
+BITPACK          Bit Packing TurboPack256V/TurboPackV/TurboPackH/TurboPack/SC.SimdPack128/SC.SimdPack256
+VBYTE            Variable byte TurboVByte/FP.VByte/PC.Vbyte/VarintG8IU/MaskedVbyte/StreamVbyte
+SIMPLE           Simple Family simple8b/simple16/vsimple/qmx
+LZ4              lz4+bitshufle/transpose 4,8 lz4_bitshufle/lz4_tp4/lz4_tp8
+LI               Little Integer LI_Pack/LI_TurboPack/LI_SuperPack/LI_HorPack
+
+
+Function         Description                                      level
+
+--------         -----------                                      -----
+TurboPFor        PFor (SSE2)
+TurboPForN       PFor (SSE2) large blocks
+TurboPFor256     PFor (AVX2)
+TurboPFor256N    PFor (AVX2) large blocks
+TurboPForDA      PFor direct access
+TurboPForDI      PFord min                                        
+TurboPForZZ      PFor zigzag of delta                             
+TurboFor         FOR                                              
+TurboForV        FOR (SIMD)                                       
+TurboFor256V     FOR (AVX2)                                       
+TurboForDA       FOR direct access                                
+TurboPackDA      Bit packing direct access                        
+TurboPack        Bit packing (scalar)                             
+TurboPackN       Bit packing (scalar) large blocks                
+TurboPackV       Bit packing (SSE2 Vertical)                      
+TurboPackH       Bit packing (SSE2 Horizontal)                    
+TurboPackVN      Bit packing (SSE2 large block)                   
+TurboPack256V    Bit packing (AVX2 Vertical)                      
+TurboPack256N    Bit packing (AVX2 large block)                   
+TurboVByte       Variable byte (scalar)                           
+VSimple          Variable simple (scalar)                         
+EliasFano        Elias fano (scalar)                              
+EliasFanoV       Eliasfano  (SSE2)                                
+EliasFano256V    Elias fano (AVX2                                 
+memcpy           memcpy                                           
+copy             Integer copy                                     
+tpbyte4s         Byte Transpose (scalar)                          
+tpbyte           Byte transpose (simd)                            2,4,8
+tpnibble         Nibble transpose (simd)                          2,4,8
+ZigZag32         ZigZag encoding (sse2)                           
+Delta32          Delta encoding (sse2)                            
+DDelta32         Delta of delta encoding (sse2)                   
+Xor32            Xor encoding (sse2)                              
+FP_PREV64        Floating point PFOR                              
+FP_FCM64         Floating point PFOR (FCM)                        
+FP_DFCM64        Floating point PFOR (DFCM)                       
+TurboPFor64      PFOR 64                                          
+TurboPFor64V     PFOR 64                                          
+Simple8b         64 bits Simple family (instable)                 
+PC_Simple16      Simple 16. limited to 28 bits                    
+PC_OptPFD        OptPFD. limited to 28 bits                       
+PC_Vbyte         Variable byte                                    
+PC_Rice          Rice coding (instable)                           
+VarintG8IU       Variable byte SIMD                               
+MaskedVbyte      Variable byte SIMD                               
+StreamVbyte      Variable byte SIMD                               
+FP_FastPFor      PFor scalar (inefficient for small blocks)       
+FP_SimdFastPFor  PFor SIMD (inefficient for small blocks)         
+FP_OptPFor       OptPFor scalar                                   
+FP_SIMDOptPFor   OptPFor SIMD                                     
+FP_VByte         Variable byte                                    
+FP_Simple8bRLE   Simple-8b + rle                                  
+FP_GROUPSIMPLE   Group Simple                                     
+SC_SIMDPack128   Bit packing (SSE4.1)                             
+SC_SIMDPack256   Bit packing (SSE4.1)                             
+SC_For           For (SSE4.1)                                     
+SC_ForDA         For direct access (SSE4.1)                       
+LibFor_For       For                                              
+LibFor_ForDA     For direct access                                
+LI_Pack          Bit packing (scalar)                             
+LI_TurboPack     Bit packing (scalar)                             
+LI_SuperPack     Bit packing (scalar)                             
+LI_HorPack       Bit packing (sse4.1 horizontal)                  
+LI_BMIPack256    Bit packing (avx2)                               
+lz4              lz4                                              
+lz4_bit          Bitshuffle + [delta]+lz4                         2,4,8
+lz4_nibble       TurboPFor's [delta]+nibble transpose + lz4       2,4,8
+lz4_bitxor       Bitshuffle + [xor]+lz4                           2,4,8
+lz4_nibblexor    TurboPFor's [xor]+nibble transpose + lz4         2,4,8
+lz4_byte         TurboPFor's [delta]+byte transpose + lz4         2,4,8
+BitShuffle       Bit shuffle (simd)                               2,4,8
+
+ diff --git a/src/ext/for/jic.c b/src/ext/for/jic.c new file mode 100644 index 00000000000..4edbaa1bf5a --- /dev/null +++ b/src/ext/for/jic.c @@ -0,0 +1,172 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// ic - "Integer Compression" Java Critical Native Interface / JNI +#include +#include +#include "bitutil.h" +#include "vint.h" +#include "vsimple.h" +#include "bitpack.h" +#include "vp4.h" + +#include "jic.h" + +#define JNIB jboolean _inlock, _outlock;\ + jint i = (*env)->GetArrayLength(env, _in); jbyte *in = (jbyte *)(*env)->GetPrimitiveArrayCritical(env, _in, &_inlock);\ + jint o = (*env)->GetArrayLength(env, _out); jbyte *out = (jbyte *)(*env)->GetPrimitiveArrayCritical(env, _out,&_outlock) + +#define JNIE\ + (*env)->ReleasePrimitiveArrayCritical(env, _in, in, JNI_ABORT);\ + (*env)->ReleasePrimitiveArrayCritical(env, _out, out, JNI_ABORT) + +#define JNIENC(__func, _in, n, _out ) JNIB; jint l = __func ((unsigned *)in, n,(unsigned char *)out ) - (unsigned char *)out; JNIE; return l +#define JNIDEC(__func, _in, n, _out ) JNIB; jint l = __func ((unsigned char *)in, n,(unsigned *)out ) - (unsigned char *)in; JNIE; return l + +#define JNIENCS(__func, _in, n, _out, x ) JNIB; jint l = __func ((unsigned *)in, n,(unsigned char *)out, x ) - (unsigned char *)out; JNIE; return l +#define JNIDECS(__func, _in, n, _out, x ) JNIB; jint l = __func ((unsigned char *)in, n,(unsigned *)out, x ) - (unsigned char *)in; JNIE; return l + +#define JNIENCSB(__func, _in, n, _out, x, b) JNIB; jint l = __func ((unsigned *)in, n,(unsigned char *)out, x, b) - (unsigned char *)out; JNIE; return l +#define JNIDECSB(__func, _in, n, _out, x, b) JNIB; jint l = __func ((unsigned char *)in, n,(unsigned *)out, x, b) - (unsigned char *)in; JNIE; return l + +#define JNINENC(__func, _in, n, _out ) JNIB; jint l = __func ((unsigned *)in, n,(unsigned char *)out ); JNIE; return l +#define JNINDEC(__func, _in, n, _out ) JNIB; jint l = __func ((unsigned char *)in, n,(unsigned *)out ); JNIE; return l + +#define JNIBI jboolean _inlock; jint i = (*env)->GetArrayLength(env, _in); jbyte *in = (jbyte *)(*env)->GetPrimitiveArrayCritical(env, _in, &_inlock); + +#define JNIEI (*env)->ReleasePrimitiveArrayCritical(env, _in, in, JNI_ABORT); + +#define JNIBIT( __func, _in, n) JNIBI; jint l = __func ((unsigned *)in, n ); JNIEI; return l +#define JNIBITS(__func, _in, n, x) JNIBI; jint l = __func ((unsigned *)in, n, x); JNIEI; return l + +//---------------------------------- variable byte ------------------------------------------------------------------------------------------ +JNIEXPORT jint JNICALL Java_jic_vbenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNIENC(vbenc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbenc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return vbenc32( (unsigned *)in, n, (unsigned char *)out ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_vbdec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNIDEC(vbdec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbdec32( jint i, jbyte *in, jint n, jint o, jint *out ) { return vbdec32( (unsigned char *)in, n, (unsigned *)out ) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_vbdenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start ) { JNIENCS(vbdenc32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbdenc32( jint i, jint *in, jint n, jint o, jbyte *out, jint start ) { return vbdenc32( (unsigned *)in, n, (unsigned char *)out, start ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_vbddec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start ) { JNIDECS(vbddec32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbddec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return vbddec32( (unsigned char *)in, n, (unsigned *)out, start ) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_vbd1enc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start ) { JNIENCS(vbd1enc32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbd1enc32( jint i, jint *in, jint n, jint o, jbyte *out, jint start ) { return vbd1enc32( (unsigned *)in, n, (unsigned char *)out, start ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_vbd1dec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start ) { JNIDECS(vbd1dec32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_vbd1dec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return vbd1dec32( (unsigned char *)in, n, (unsigned *)out, start ) - (unsigned char *)in; } +//--------------------------------- variable simple ---------------------------------------------------------------------------------------------- +JNIEXPORT jint JNICALL Java_jic_vsenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNIENC(vsenc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_vsenc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return vsenc32( (unsigned *)in, n, (unsigned char *)out ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_vsdec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNIDEC(vsdec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_vsdec32( jint i, jbyte *in, jint n, jint o, jint *out ) { return vsdec32( (unsigned char *)in, n, (unsigned *)out ) - (unsigned char *)in; } +//--------------------------------- TurboPFor: PFor/PForDelta ----------------------------------------------------------------- +// High level API - n = unlimited +JNIEXPORT jint JNICALL Java_jic_p4nenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNNIENC(p4nenc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nenc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4nenc32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4ndec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNNIDEC(p4ndec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4ndec32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4ndec32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_p4nenc128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNNIENC(p4nenc128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nenc128v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4nenc128v32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4ndec128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNNIDEC(p4ndec128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4ndec128v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4ndec128v32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_p4nenc256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNNIENC(p4nenc256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nenc256v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4nenc256v32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4ndec256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNNIDEC(p4ndec256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4ndec256v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4ndec256v32( (unsigned char *)in, n, (unsigned *)out ); } +//-------- +JNIEXPORT jint JNICALL Java_jic_p4ndenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNNIENC(p4ndenc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4ndenc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4ndenc32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4nddec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNNIDEC(p4nddec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nddec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return p4nddec32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_p4nd1enc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNNIENC(p4nd1enc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nd1enc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4nd1enc32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4nd1dec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNNIDEC(p4nd1dec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nd1dec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return p4nd1dec32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_p4nzenc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(p4nzenc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nzenc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4nzenc32( (unsigned *)in, n, (unsigned char *)out ); } +JNIEXPORT jint JNICALL Java_jic_p4nzdec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(p4nzdec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4nzdec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return p4nzdec32( (unsigned char *)in, n, (unsigned *)out ); } + +// Low level: Single block +JNIEXPORT jint JNICALL Java_jic_p4denc32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNIENC(p4enc32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4enc32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4enc32( (unsigned *)in, n, (unsigned char *)out ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_p4dec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNIDEC(p4dec32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4dec32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4dec32( (unsigned char *)in, n, (unsigned *)out ) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_p4enc128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNIENC(p4enc128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4enc128v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4enc128v32( (unsigned *)in, n, (unsigned char *)out ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_p4dec128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNIDEC(p4dec128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4dec128v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4dec128v32( (unsigned char *)in, n, (unsigned *)out ) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_p4enc256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNIENC(p4enc256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4enc256v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return p4enc256v32( (unsigned *)in, n, (unsigned char *)out ) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_p4dec256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNIDEC(p4dec256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4dec256v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return p4dec256v32( (unsigned char *)in, n, (unsigned *)out ) - (unsigned char *)in; } + +//-------- +JNIEXPORT jint JNICALL Java_jic_p4ddec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start ) { JNIDECS(p4ddec32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4ddec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return p4ddec32( (unsigned char *)in, n, (unsigned *)out, start ) - (unsigned char *)in; } +JNIEXPORT jint JNICALL Java_jic_p4d1dec32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start ) { JNIDECS(p4d1dec32, _in, n, _out, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_p4d1dec32( jint i, jbyte *in, jint n, jint o, jint *out, jint start ) { return p4d1dec32( (unsigned char *)in, n, (unsigned *)out, start ) - (unsigned char *)in; } +//--------------------------------- BitPack/BitUnpack ---------------------------------------------------------------------------- +// High level API +JNIEXPORT jint JNICALL Java_jic_bitnpack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnpack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnpack32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnpack32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnunpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnunpack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnunpack32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnunpack32( (unsigned char *)in, n, (unsigned *)out); } + +JNIEXPORT jint JNICALL Java_jic_bitndpack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitndpack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndpack32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitndpack32(( unsigned *)in, n, (unsigned char *)out);} +JNIEXPORT jint JNICALL Java_jic_bitndunpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitndunpack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndunpack32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitndunpack32(( unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_bitnd1pack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnd1pack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1pack32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnd1pack32(( unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnd1unpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnd1unpack32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1unpack32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnd1unpack32( (unsigned char *)in, n, (unsigned *)out); } + +// low level API +JNIEXPORT jint JNICALL Java_jic_bitpack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint b) { JNIENCS(bitpack32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitpack32( jint i, jint *in, jint n, jint o, jbyte *out, jint b ) { return bitpack32( (unsigned *)in, n, (unsigned char *)out, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitunpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint b) { JNIDECS(bitunpack32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitunpack32( jint i, jbyte *in, jint n, jint o, jint *out, jint b ) { return bitunpack32( (unsigned char *)in, n, (unsigned *)out, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitdpack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitdpack32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdpack32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b ) { return bitdpack32( (unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out;} +JNIEXPORT jint JNICALL Java_jic_bitdunpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitdunpack32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdunpack32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b ) { return bitdunpack32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitd1pack32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitd1pack32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1pack32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b ) { return bitd1pack32(( unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitd1unpack32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitd1unpack32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1unpack32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b ) { return bitd1unpack32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } + +//--------------------------------- BitPack/BitUnpack SIMD ----------------------------------------------------------------------------------- +// GHigh Level API: n unlimited +JNIEXPORT jint JNICALL Java_jic_bitnpack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnpack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnpack128v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnpack128v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnunpack128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnunpack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnunpack128v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnunpack128v32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_bitndpack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitndpack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndpack128v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitndpack128v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitndunpack128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitndunpack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndunpack128v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitndunpack128v32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_bitnd1pack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnd1pack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1pack128v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnd1pack128v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnd1unpack128v32(JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnd1unpack128v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1unpack128v32(jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnd1unpack128v32((unsigned char *)in, n, (unsigned *)out ); } + +// AVX2 +JNIEXPORT jint JNICALL Java_jic_bitnpack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnpack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnpack256v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnpack256v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnunpack256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnunpack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnunpack256v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnunpack256v32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_bitndpack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitndpack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndpack256v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitndpack256v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitndunpack256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitndunpack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitndunpack256v32( jint i, jbyte *in, jint n, jint o, jint *out ) { return bitndunpack256v32( (unsigned char *)in, n, (unsigned *)out ); } + +JNIEXPORT jint JNICALL Java_jic_bitnd1pack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out ) { JNINENC(bitnd1pack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1pack256v32( jint i, jint *in, jint n, jint o, jbyte *out ) { return bitnd1pack256v32( (unsigned *)in, n, (unsigned char *)out); } +JNIEXPORT jint JNICALL Java_jic_bitnd1unpack256v32(JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out ) { JNINDEC(bitnd1unpack256v32, _in, n, _out ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitnd1unpack256v32(jint i, jbyte *in, jint n, jint o, jint *out ) { return bitnd1unpack256v32((unsigned char *)in, n, (unsigned *)out ); } + +// Low level API +JNIEXPORT jint JNICALL Java_jic_bitpack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint b) { JNIENCS(bitpack128v32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitpack128v32( jint i, jint *in, jint n, jint o, jbyte *out, jint b) { return bitpack128v32( (unsigned *)in, n, (unsigned char *)out, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitunpack128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint b) { JNIDECS(bitunpack128v32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitunpack128v32( jint i, jbyte *in, jint n, jint o, jint *out, jint b) { return bitunpack128v32( (unsigned char *)in, n, (unsigned *)out, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitdpack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitdpack128v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdpack128v32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b) { return bitdpack128v32( (unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitdunpack128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitdunpack128v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdunpack128v32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b) { return bitdunpack128v32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitd1pack128v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitd1pack128v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1pack128v32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b) { return bitd1pack128v32( (unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitd1unpack128v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitd1unpack128v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1unpack128v32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b) { return bitd1unpack128v32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } + +// AVX2 +JNIEXPORT jint JNICALL Java_jic_bitpack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint b) { JNIENCS(bitpack256v32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitpack256v32( jint i, jint *in, jint n, jint o, jbyte *out, jint b) { return bitpack256v32( (unsigned *)in, n, (unsigned char *)out, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitunpack256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint b) { JNIDECS(bitunpack256v32, _in, n, _out, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitunpack256v32( jint i, jbyte *in, jint n, jint o, jint *out, jint b) { return bitunpack256v32( (unsigned char *)in, n, (unsigned *)out, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitdpack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitdpack256v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdpack256v32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b) { return bitdpack256v32( (unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitdunpack256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitdunpack256v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitdunpack256v32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b) { return bitdunpack256v32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } + +JNIEXPORT jint JNICALL Java_jic_bitd1pack256v32( JNIEnv *env, jclass cls, jintArray _in, jint n, jbyteArray _out, jint start, jint b) { JNIENCSB(bitd1pack256v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1pack256v32( jint i, jint *in, jint n, jint o, jbyte *out, jint start, jint b) { return bitd1pack256v32( (unsigned *)in, n, (unsigned char *)out, start, b) - (unsigned char *)out; } +JNIEXPORT jint JNICALL Java_jic_bitd1unpack256v32( JNIEnv *env, jclass cls, jbyteArray _in, jint n, jintArray _out, jint start, jint b) { JNIDECSB(bitd1unpack256v32, _in, n, _out, start, b); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd1unpack256v32( jint i, jbyte *in, jint n, jint o, jint *out, jint start, jint b) { return bitd1unpack256v32( (unsigned char *)in, n, (unsigned *)out, start, b) - (unsigned char *)in; } +//--------------------------------- bitutil -------------------------------------------------------------------------------------------------- +JNIEXPORT jint JNICALL Java_jic_bit32( JNIEnv *env, jclass cls, jintArray _in, jint n ) { JNIBIT( bit32, _in, n ); } JNIEXPORT jint JNICALL JavaCritical_jic_bit32( jint i, jint *in, jint n ) { return bit32( (unsigned *)in, n ); } +JNIEXPORT jint JNICALL Java_jic_bitd32( JNIEnv *env, jclass cls, jintArray _in, jint n, jint start ) { JNIBITS(bitd32, _in, n, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd32( jint i, jint *in, jint n, jint start ) { return bitd32( (unsigned *)in, n, start ); } +JNIEXPORT jint JNICALL Java_jic_bitd132( JNIEnv *env, jclass cls, jintArray _in, jint n, jint start ) { JNIBITS(bitd132, _in, n, start ); } JNIEXPORT jint JNICALL JavaCritical_jic_bitd132( jint i, jint *in, jint n, jint start ) { return bitd132( (unsigned *)in, n, start ); } + diff --git a/src/ext/for/lz.c b/src/ext/for/lz.c new file mode 100644 index 00000000000..c730e3f9be6 --- /dev/null +++ b/src/ext/for/lz.c @@ -0,0 +1,442 @@ +//------------------- LZ compression -------------------------------------------------- +#define powof2(n) !((n)&((n)-1)) + +enum { + P_NONE, + P_LZTURBO, + P_LZ4, + P_ZLIB, + + P_ZSTD, + P_FSE, + P_FSEH, + P_LZTANS, + P_TURBORC, + P_LAST, +}; + +char *_codstr[] = { "none", "lzturbo", "lz4", "zlib", "zstd", "fse", "fsehuf", "turboanx", "turborc", NULL }; +char *codstr(unsigned id) { return (id < P_LAST)?_codstr[id]:""; } + + #ifdef LZTURBO +#include "lzt.c" +#define LZTANS +#include "../lz/ans.h" +#include "../lz/anst.h" +#include "ext/TurboRC/turborc.h" + #endif + + #if defined(LZ4) +#include "ext/lz4/lib/lz4.h" +#include "ext/lz4/lib/lz4hc.h" +#include "ext/lz4/lib/lz4frame.h" +#define USE_LZ + #endif + + #if defined(TURBORC) +#include "ext/TurboRC/turborc.h" + #endif + + #if defined(ZSTD) +#define ZSTD_STATIC_LINKING_ONLY +#include "ext/zstd/lib/zstd.h" +#define USE_LZ + #endif + + #if defined(ZLIB) +#include "ext/zlib/zlib.h" //#include + +#define USE_LZ + #endif + +int lzenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, int codid, int codlev, char *codprm) { if(!inlen) return 0; + switch(codid) { + #if defined(LZTURBO) + #include "lztc.c" + #endif + + #if defined(LZ4) + case P_LZ4: if(codlev > 16) codlev = 16; + if(strchr(codprm,'M')) { return !codlev?LZ4_compress_fast((char *)in, (char *)out, inlen, outsize, 4):(codlev<9?LZ4_compress_default((char *)in, (char *)out, inlen, outsize):LZ4_compress_HC((char *)in, (char *)out, inlen, outsize, codlev)); } + else { char *q; + LZ4F_preferences_t opts = LZ4F_INIT_PREFERENCES; + opts.compressionLevel = codlev; + if(strchr(codprm,'s')) opts.favorDecSpeed = 1; + if(strchr(codprm,'f')) opts.autoFlush = 1; + opts.frameInfo.blockSizeID = LZ4F_max4MB; + if(q=strchr(codprm,'B')) opts.frameInfo.blockSizeID = (LZ4F_blockSizeID_t)atoi(q+(q[1]=='='?2:1)); + if(opts.frameInfo.blockSizeID>LZ4F_max4MB) opts.frameInfo.blockSizeID=LZ4F_max4MB; + else if(opts.frameInfo.blockSizeID && opts.frameInfo.blockSizeID= inlen) { memcpy(out, in, inlen); return inlen; } + return o; + } + case P_FSEH: { size_t o = HUF_compress(out, outsize, in, inlen); + if(o == 1) { out[0] = in[0]; return 1; } + if(!o || o >= inlen) { memcpy(out, in, inlen); return inlen; } + return o; + } + #endif + + #if defined(ZLIB) + case P_ZLIB: { uLongf outlen = outsize; if(codlev < 1) codlev=1; if(codlev>9) codlev=9; + int rc = compress2(out, &outlen, in, inlen, codlev); + if(rc != Z_OK) printf("zlib compress2 rc=%d\n", rc); + return outlen; + } + #endif + } + return 0; +} + +int lzdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, int codec, int codlev, char *codprm) { if(!inlen) return 0; + switch(codid) { + #if defined(LZTURBO) + #include "lztd.c" + #endif + + #if defined(LZ4) + case P_LZ4: + if(strchr(codprm,'M')) { LZ4_decompress_safe((const char *)in, (char *)out, inlen, outlen); break; } + else { + LZ4F_dctx *ctx; LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION); + size_t ilen = inlen, olen = outlen, rc = LZ4F_decompress(ctx, out, &olen, in, &ilen, NULL); + LZ4F_freeDecompressionContext(ctx); + return rc; + } + #endif + + #if defined(TURBORC) + case P_TURBORC: { int ec = 0; char *q; if(q=strchr(codprm,'e')) ec = atoi(q+(q[1]=='='?2:1)); + switch(codlev) { + case 0 : return ec==2?turborcsxdec( in, outlen, out):turborcsdec(in, outlen, out); + case 1 : return ec==2?turborcssxdec(in, outlen, out):turborcssdec( in, outlen, out); + case 2 : return turborcndec( in, outlen, out); + } + } + #endif + + #if defined(ZSTD) + case P_ZSTD: ZSTD_decompress( out, outlen, in, inlen); break; + case P_FSE: if(inlen == outlen) memcpy(out, in, outlen); else if(inlen == 1) memset(out,in[0],outlen); else FSE_decompress(out, outlen, in, inlen); break; + case P_FSEH: if(inlen == outlen) memcpy(out, in, outlen); else if(inlen == 1) memset(out,in[0],outlen); else HUF_decompress(out, outlen, in, inlen); break; + #endif + + #if defined(ZLIB ) + case P_ZLIB: { uLongf outsize = outlen; int rc = uncompress(out, &outsize, in, inlen); } break; + #endif + } + return 0; +} + +//------------------- TurboByte + lz ---------------------------- +unsigned lzv8enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + unsigned clen = (esize==2?v8enc16(in, inlen/2, tmp):v8enc32(in, inlen/4, tmp)) - tmp; //streamvbyte_encode(in, inlen/4, tmp);// + ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned lzv8dec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, tmp, clen, codid, codlev, codprm); + esize==2?v8dec16(tmp, outlen/2, out):v8dec32(tmp, outlen/4, out);//streamvbyte_decode(tmp, outlen/4, out); + return inlen; +} + +unsigned lzv8zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + unsigned clen = (esize==2?v8zenc16(in, inlen/2, tmp,0):v8zenc32(in, inlen/4, tmp,0)) - tmp; ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned lzv8zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, tmp, clen, codid, codlev, codprm); + esize==2?v8zdec16(tmp, outlen/2, out,0):v8zdec32(tmp, outlen/4, out,0); + return inlen; +} + +unsigned lzv8xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // TurboVByte + unsigned clen = (esize==2?v8xenc16(in, inlen/2, tmp,0):v8xenc32(in, inlen/4, tmp,0)) - tmp; ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned v8lzxdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, tmp, clen, codid, codlev, codprm); + esize==2?v8xdec16(tmp, outlen/2, out,0):v8xdec32(tmp, outlen/4, out,0); + return inlen; +} + +//----------------- Byte transpose + Lz ------------------------------------------------------------------------------------- +unsigned lztpenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + tpenc(in, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} + +unsigned lztpdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tpdec(tmp, outlen, out, esize); + return inlen; +} + +unsigned lztpxenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // XOR + bitxenc(in, inlen, out, esize); + tpenc(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpxdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tpdec(tmp, outlen, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztpzenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // Zigzag + bitzenc(in, inlen, out, esize); + tpenc(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpzdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tpdec( tmp, outlen, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + +unsigned lztprleenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // Zigzag rle + tpenc(in, inlen, out, esize); + unsigned clen = trlec(out, inlen, tmp); if(clen >= inlen) { clen = inlen; memcpy(tmp,out,inlen); } + ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned lztprledec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, out, clen, codid, codlev, codprm); if(clen >= outlen) { memcpy(tmp, out, outlen); } else + trled(out, clen, tmp, outlen); + tpdec(tmp, outlen, out, esize); + return inlen; +} + +unsigned lztprlexenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // Zigzag rle + bitxenc(in, inlen, tmp, esize); + tpenc(tmp, inlen, out, esize); + unsigned clen = trlec(out, inlen, tmp); if(clen >= inlen) { clen = inlen; memcpy(tmp,out,inlen); } + ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned lztprlexdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, out, clen, codid, codlev, codprm); if(clen >= outlen) { memcpy(tmp, out, outlen); } else + trled(out, clen, tmp, outlen); + tpdec(tmp, outlen, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztprlezenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { // Zigzag rle + bitzenc(in, inlen, tmp, esize); + tpenc(tmp, inlen, out, esize); + unsigned clen = trlec(out, inlen, tmp); if(clen >= inlen) { clen = inlen; memcpy(tmp,out,inlen); } + ctou32(out) = clen; + return lzenc(tmp, clen, out+4, outsize, codid, codlev, codprm)+4; +} +unsigned lztprlezdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + unsigned clen = ctou32(in); lzdec(in+4, inlen-4, out, clen, codid, codlev, codprm); if(clen >= outlen) { memcpy(tmp, out, outlen); } else + trled(out, clen, tmp, outlen); + tpdec(tmp, outlen, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + +//------------------- tp4 : Nibble transpose + lz -------------------------------- +unsigned lztp4enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + tp4enc(in, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd4ec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4dec(tmp, outlen, out, esize); + return inlen; +} + +unsigned lztp4xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { //XOR + bitxenc(in, inlen, out, esize); + tp4enc(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} + +unsigned lztp4xdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4dec( tmp, outlen, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztp4zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + bitzenc(in, inlen, out, esize); + tp4enc(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztp4zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4dec(tmp, outlen, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + +//------------------ 2D ----------------- +unsigned lztpd2enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + tp2denc(in, x, y, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd2dec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp2ddec(tmp, x, y, out, esize); + return x*y*esize; +} + +unsigned lztpd2xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + bitxenc(in, inlen, out, esize); + tp2denc(out, x, y, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd2xdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp2ddec(tmp, x, y, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztpd2zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + bitzenc(in, inlen, out, esize); + tp2denc(out, x, y, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} + +unsigned lztpd2zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp2ddec(tmp, x, y, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + +//------------------ 3D ----------------- +unsigned lztpd3enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + tp3denc(in, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd3dec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp3ddec(tmp, x, y, z, out, esize); + return inlen; +} + +unsigned lztpd3xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + bitxenc(in, inlen, out, esize); + tp3denc(out, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd3xdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp3ddec(tmp, x, y, z, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztpd3zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + bitzenc(in, inlen, out, esize); + tp3denc(out, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd3zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp3ddec(tmp, x, y, z, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + +//------------------ 4D ----------------- +unsigned lztpd4enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + tp4denc(in, w, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd4dec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4ddec(tmp, w, x, y, z, out, esize); + return inlen; +} + +unsigned lztpd4xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + bitxenc(in, inlen, out, esize); + tp4denc(out, w, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd4xdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4ddec(tmp, w, x, y, z, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztpd4zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + bitzenc(in, inlen, out, esize); + tp4denc(out, w, x, y, z, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztpd4zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp, unsigned w, unsigned x, unsigned y, unsigned z) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + tp4ddec(tmp, w, x, y, z, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + + #ifdef BITSHUFFLE //--------------------------bit transpose ---------------------------------------------------------------------- +unsigned lztp1enc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + bitshuffle(in, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztp1dec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + bitunshuffle(tmp, outlen, out, esize); + return inlen; +} + +unsigned lztp1xenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + bitxenc(in, inlen, out, esize); + bitshuffle(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztp1xdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + bitunshuffle(tmp, outlen, out, esize); + bitxdec(out, outlen, esize); + return inlen; +} + +unsigned lztp1zenc(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outsize, unsigned esize, unsigned char *tmp) { + bitzenc(in, inlen, out, esize); CPYR(in,inlen,esize,out); + bitshuffle(out, inlen, tmp, esize); + return lzenc(tmp, inlen, out, outsize, codid, codlev, codprm); +} +unsigned lztp1zdec(unsigned char *in, unsigned inlen, unsigned char *out, unsigned outlen, unsigned esize, unsigned char *tmp) { + lzdec(in, inlen, tmp, outlen, codid, codlev, codprm); + bitunshuffle(tmp, outlen, out, esize); + bitzdec(out, outlen, esize); + return inlen; +} + #endif diff --git a/src/ext/for/makefile b/src/ext/for/makefile new file mode 100644 index 00000000000..d9bd00ebc76 --- /dev/null +++ b/src/ext/for/makefile @@ -0,0 +1,156 @@ +# powturbo (c) Copyright 2013-2019 +# Download or clone TurboPFor: +# git clone git://github.com/powturbo/TurboPFor.git +# make +# +# To benchmark external libraries: +# git clone --recursive git://github.com/powturbo/TurboPFor.git +# make: "make CODEC1=1 CODEC2=1 LZ=1" +# on arm make: "make CODEC1=1 LZ=1" + +CC ?= gcc +CXX ?= g++ + +#CC=powerpc64le-linux-gnu-gcc +CL = $(CC) +#DEBUG=-DDEBUG -g +DEBUG=-DNDEBUG -s + +PREFIX ?= /usr/local +DIRBIN ?= $(PREFIX)/bin +DIRINC ?= $(PREFIX)/include +DIRLIB ?= $(PREFIX)/lib + +OPT=-fstrict-aliasing +ifeq (,$(findstring clang, $(CC))) +OPT+=-falign-loops +endif +ifneq (,$(findstring clang, $(CC))) +OPT+=-Wno-int-conversion +endif + +#------- OS/ARCH ------------------- +ifneq (,$(filter Windows%,$(OS))) + OS := Windows + CC=gcc + CXX=g++ + ARCH=x86_64 +else + OS := $(shell uname -s) + ARCH := $(shell uname -m) + +ifneq (,$(findstring aarch64,$(CC))) + ARCH = aarch64 +else ifneq (,$(findstring powerpc64le,$(CC))) + ARCH = ppc64le +endif +endif + +ifeq ($(ARCH),ppc64le) + SSE=-D__SSSE3__ + CFLAGS=-mcpu=power9 -mtune=power9 $(SSE) +else ifeq ($(ARCH),aarch64) + CFLAGS=-march=armv8-a +ifneq (,$(findstring clang, $(CC))) + OPT+=-fomit-frame-pointer +#-fmacro-backtrace-limit=0 +endif + SSE=-march=armv8-a +else ifeq ($(ARCH),$(filter $(ARCH),x86_64)) +# set minimum arch sandy bridge SSE4.1 + AVX + SSE=-msse4.2 + #SSE=-march=corei7-avx -mtune=corei7-avx +# SSE+=-mno-avx -mno-aes + CFLAGS=$(SSE) + #AVX2=-march=haswell + AVX2=-mavx2 +# SSE=$(AVX2) +endif + +CFLAGS+=-w -Wall $(DEBUG) $(OPT) + +ifeq ($(OS),$(filter $(OS),Linux GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku)) +LDFLAGS+=-lrt -lm +endif + +# compiler supports float16 +ifeq ($(FLOAT16),1) +CFLAGS+=-DUSE_FLOAT16 +endif +ifeq ($(STATIC),1) +LDFLAGS+=-static +endif +#LDFLAGS+=-Wl -fsanitize=address +all: icapp + +vp4c_sse.o: vp4c.c + $(CC) -O3 -w $(SSE) -DSSE2_ON $(OPT) -c vp4c.c -o vp4c_sse.o + +vp4c_avx2.o: vp4c.c + $(CC) -O3 -w $(AVX2) -DAVX2_ON $(OPT) -c vp4c.c -o vp4c_avx2.o + +vp4d_sse.o: vp4d.c + $(CC) -O3 -w $(SSE) -DSSE2_ON $(OPT) -c vp4d.c -o vp4d_sse.o + +vp4d_avx2.o: vp4d.c + $(CC) -O3 -w $(AVX2) -DAVX2_ON $(OPT) -c vp4d.c -o vp4d_avx2.o + +bitpack_sse.o: bitpack.c + $(CC) -O3 -w $(SSE) -DSSE2_ON $(OPT) -c bitpack.c -o bitpack_sse.o + +bitpack_avx2.o: bitpack.c + $(CC) -O3 -w $(AVX2) -DAVX2_ON $(OPT) -c bitpack.c -o bitpack_avx2.o + +bitunpack_sse.o: bitunpack.c + $(CC) -O3 -w $(SSE) -DSSE2_ON $(OPT) -c bitunpack.c -o bitunpack_sse.o + +bitunpack_avx2.o: bitunpack.c + $(CC) -O3 -w $(AVX2) -DAVX2_ON $(OPT) -c bitunpack.c -o bitunpack_avx2.o + +transpose_sse.o: transpose.c + $(CC) -O3 -w $(SSE) -DSSE2_ON $(OPT) -c transpose.c -o transpose_sse.o + +transpose_avx2.o: transpose.c + $(CC) -O3 -w $(AVX2) -DAVX2_ON $(OPT) -c transpose.c -o transpose_avx2.o + +-include ext/libext.mak + +LIB=bitpack.o bitpack_sse.o bitunpack.o bitunpack_sse.o \ + vp4c.o vp4c_sse.o vp4d.o vp4d_sse.o \ + bitutil.o fp.o v8.o vint.o transpose.o transpose_sse.o trlec.o trled.o vsimple.o eliasfano.o +#bic.o +#ifeq ($(ARCH),x86_64) +ifeq ($(USE_AVX2),1) +LIB+=bitpack_avx2.o bitunpack_avx2.o vp4c_avx2.o vp4d_avx2.o transpose_avx2.o +endif + +libic.a: $(LIB) + ar cr $@ $+ + +icapp: icapp.o libic.a $(OB) + $(CL) $^ $(LDFLAGS) -o icapp + +myapp: myapp.o libic.a + $(CC) $^ $(LDFLAGS) -o myapp + +mycpp: mycpp.o libic.a + $(CXX) $^ $(LDFLAGS) -o mycpp + +.c.o: + $(CC) -O3 $(CFLAGS) $< -c -o $@ + +.cc.o: + $(CXX) -O2 $(CXXFLAGS) $< -c -o $@ + +.cpp.o: + $(CXX) -O2 $(CXXFLAGS) $< -c -o $@ + +ifeq ($(OS),Windows_NT) +clean: + del /S *.o + del /S *~ +else +clean: + @find . -type f -name "*\.o" -delete -or -name "*\~" -delete -or -name "core" -delete -or -name "icbench" -delete -or -name "libic.a" -delete + @find . -type f -name "icbench" -delete -or -name "idxqry" -delete -or -name "idxseg" -delete -or -name "idxcr" -delete -or -name "icapp" -delete +endif diff --git a/src/ext/for/makefile.vs b/src/ext/for/makefile.vs new file mode 100644 index 00000000000..d77ef0ed4ea --- /dev/null +++ b/src/ext/for/makefile.vs @@ -0,0 +1,78 @@ +# powturbo (c) Copyright 2013-2019 +# nmake /f makefile.vs +# or +# nmake "AVX2=1" /f makefile.vs + +.SUFFIXES: .c .obj .dllobj + +CC = cl /nologo +LD = link /nologo +AR = lib /nologo +CFLAGS = /MD /O2 -I. /W0 +LDFLAGS = +ARCH = + +LIB_LIB = libic.lib +LIB_DLL = ic.dll +LIB_IMP = ic.lib + +OBJS = bitpack.obj bitunpack.obj bitutil.obj vp4c.obj vp4d.obj transpose.obj fp.obj trlec.obj trled.obj vint.obj vsimple.obj vsimple.obj +OBJS_SSE = vs\bitpack_sse.obj vs\bitunpack_sse.obj vs\vp4c_sse.obj vs\vp4d_sse.obj vs\transpose_sse.obj +OBJS_AVX2 = vs\bitpack_avx2.obj vs\bitunpack_avx2.obj vs\vp4c_avx2.obj vs\vp4d_avx2.obj vs\transpose_avx2.obj + +!if "$(NSIMD)" == "1" +CFLAGS = $(CFLAGS) /DNSIMD +!else +OBJS = $(OBJS) $(OBJS_SSE) +CFLAGS = $(CFLAGS) /D__SSE__ /D__SSE2__ /D__SSE3__ /D__SSSE3__ /D__SSE4_1__ /D__SSE4_2__ +!if "$(AVX2)" == "1" +OBJS = $(OBJS) $(OBJS_AVX2) +CFLAGS = $(CFLAGS) /D__AVX2__ +ARCH = /arch:AVX2 +!endif +!endif + +!if "$(CODEC1)" == "1" +CFLAGS = $(CFLAGS) /DCODEC1 +!endif + +!IF "$(CODEC2)" == "1" +CFLAGS = $(CFLAGS) /DCODEC2 +!endif + +!IF "($(BLOSC)" == "1" +CFLAGS = $(CFLAGS) /DBLOSC +!endif + +DLL_OBJS = $(OBJS:.obj=.dllobj) + +all: $(LIB_LIB) icbench.exe icapp.exe + +#$(LIB_DLL) $(LIB_IMP) + +#------------ +.c.obj: + $(CC) -c /Fo$@ /O2 $(CFLAGS) $(ARCH) $** + +.cc.obj: + $(CC) -c /Fo$@ /O2 $(CFLAGS) $(ARCH) $** + +.c.dllobj: + $(CC) -c /Fo$@ /O2 $(CFLAGS) $(ARCH) /DLIB_DLL $** + +$(LIB_LIB): $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(LIB_DLL): $(DLL_OBJS) + $(LD) $(LDFLAGS) -out:$@ -dll -implib:$(LIB_IMP) $(DLL_OBJS) + +$(LIB_IMP): $(LIB_DLL) + +icbench.exe: icbench.obj vs\getopt.obj plugins.obj eliasfano.obj $(LIB_LIB) + $(LD) $(LDFLAGS) -out:$@ $** + +icapp.exe: icapp.obj vs\getopt.obj plugins.obj eliasfano.obj $(LIB_LIB) + $(LD) $(LDFLAGS) -out:$@ $** + +clean: + -del *.obj vs\*.obj *.dll *.exe *.exp *.dllobj *.lib *.manifest 2>nul diff --git a/src/ext/for/plugins.cc b/src/ext/for/plugins.cc new file mode 100644 index 00000000000..61d50ce1fff --- /dev/null +++ b/src/ext/for/plugins.cc @@ -0,0 +1,798 @@ +/** + Copyright (C) powturbo 2013-2018 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// TurboPFor: Integer Compression - Benchmark App +#define _LARGEFILE64_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include +#include +#include +#include "conf.h" + +#include "plugins.h" + + #ifdef NCODEC0 +#define CODEC0 0 +#define CODEC0S 0 + #else +#define CODEC0 1 + #ifdef NSIMD +#define CODEC0V 0 + #else +#define CODEC0V 1 + #endif + #endif + + #ifdef CODEC1 +#define CODEC1 1 + #else +#define CODEC1 0 + #endif + + #ifdef CODEC2 +#define CODEC2 1 + #else +#define CODEC2 0 + #endif + + #ifdef LZTURBO +#define C_LZTURBO CODEC2 + #else +#define C_LZTURBO 0 + #endif + + #ifdef BLOSC +#define C_C_BLOSC CODEC2 + #else +#define C_C_BLOSC 0 + #endif + +enum { +#define C_MEMCPY 1 + P_LMCPY, // must be 0 + P_MCPY, // must be 1 + P_COPY, + +#define C_TURBOPFOR CODEC0 + TB_PFDA, + TB_FOR, + TB_FORDA, + TB_BP, + TB_BPN, + TB_BPDA, + TB_PDI, + TB_VBYTE, + TB_BYTE, + TB_BYTE128V, + TB_BYTE256V, + TB_VSIMPLE, + TB_EF, +// TB_FPPFOR64, + TB_FPFFOR64, + TB_FPDFOR64, + TB_PF64, + TB_PF64V, + TB_PFNZZ, + + #ifdef TURBOPFORH +#define C_TURBOPFORH CODEC0V + #else +#define C_TURBOPFORH 0 + #endif + TB_BP128H, + +#define C_TURBOPFOR128 CODEC0V + TB_FOR128V, + TB_PF128V, + TB_PF256V, + TB_PFN128V, + TB_PFN256V, + TB_BP128V, + TB_BPN128V, + TB_EF128V, + + #if defined(__AVX2__) +#define C_TURBOPFOR256 CODEC0V + #else +#define C_TURBOPFOR256 0 + #endif + TB_FOR256V, + TB_BP256H, + TB_BP256V, + TB_BPN256V, + TB_EF256V, + +#define C_BITSHUFFLE CODEC2 + P_BITSHUFFLE, + P_BS_LZ, + P_BS_LZ4, + P_BS_ZLIB, + P_BS_SHUFFLE, + + #ifdef __ARM_NEON +#define C_FASTPFOR 0 + #else +#define C_FASTPFOR CODEC2 + #endif + FP_VBYTE, + FP_SIMPLE8BRLE, + FP_GROUPSIMPLE, + + #ifdef __ARM_NEON +#define C_FASTPFOR128 0 + #else +#define C_FASTPFOR128 CODEC2 + #endif + FP_FASTPFOR, + FP_OPTPFOR, + FP_SIMDPACK, + FP_SIMDFASTPFOR, + FP_SIMDOPTPFOR, + +#define C_LIBFOR CODEC1 + LF_FOR, + LF_FORX, + + #ifdef __ARM_NEON +#define C_LITTLEPACK 0 + #else +#define C_LITTLEPACK CODEC1 + #endif + LI_PACK, + LI_TURBOPACK, + LI_SCPACK, + + #ifdef __ARM_NEON +#define C_LITTLEPACK128 0 + #else +#define C_LITTLEPACK128 CODEC1 + #endif + LI_HORPACK, + + #if defined(__AVX2__) +#define C_LITTLEPACKBMI CODEC1 + #else +#define C_LITTLEPACKBMI 0 + #endif + LI_BMIPACK, + +#define C_LZ4 CODEC1 + LZ4_, + LZ4_BIT, + LZ4_BITX, + LZ4_NIBBLE, + LZ4_NIBBLEX, + LZ4_BYTE,//LZ4_FP8, + + #if defined(__SSSE3__) +#define C_MASKEDVBYTE CODEC1 + #else +#define C_MASKEDVBYTE 0 + #endif + P_MASKEDVBYTE, + +#define C_POLYCOM CODEC2 + PC_OPTPFD, // compression too slow and limited to 28 bits. crashs on some lists + PC_VBYTE, + PC_RICE, // incl. only as demo, crash on some lists + PC_SIMPLE16, // limited to 28 bits. + + #if defined(QMX) +#define C_QMX CODEC1 + #else +#define C_QMX 0 + #endif + P_QMX, + + #if defined(VTENC) +#define C_VTENC CODEC1 + #else +#define C_VTENC 0 + #endif + P_VTENC, + + #ifdef __ARM_NEON +#define C_SIMDCOMP128 0 + #else +#define C_SIMDCOMP128 CODEC2 + #endif + SC_PACK, + SC_FOR, + SC_FORDA, + SC_SIMDPACK128, + + #if defined(__AVX2__) +#define C_SIMDCOMP256 CODEC0V + #else +#define C_SIMDCOMP256 0 + #endif +SC_SIMDPACK256, + +#define C_SIMPLE8B CODEC2 //crash on integers w. size 32 bits ! + AM_SIMPLE8B, +#define C_STREAMVBYTE CODEC1 + P_STREAMVBYTE, + #if defined(__SSSE3__) +#define C_VARINTG8IU CODEC1 + #else +#define C_VARINTG8IU 0 + #endif + P_VARINTG8IU, + + #ifdef ZLIB +#define C_ZLIB CODEC2 + #else +#define C_ZLIB 0 + #endif + P_ZLIB, +#define C_TRANSFORM CODEC0 + TP_BYTES, + TP_BYTE, + TP_NIBBLE, + TB_ZIGZAG32, + TB_DELTA32, + TB_ZDELTA32, + TB_XOR32, +#define C_LZTURBO 0 + P_LZT, + P_VSHUF, + + P_MAX +}; + +#define PAD8(_x_) ( (((_x_)+8-1)/8) ) +#if CODEC1==1 || CODEC2==1 +#include "ext/beplug_.h" // external libs +#endif + + #if C_TURBOPFOR +#define BITUTIL_IN +#define VINT_IN +#define TURBOPFOR_DAC +#define BITPACK_DAC +#include "vint.h" +#include "vsimple.h" +#include "eliasfano.h" +#include "bitutil.h" +#include "transpose.h" +#include "fp.h" +#include "bitpack.h" +#include "vp4.h" + #endif + +#define BLK_SIZE (64*1024*4) +#define BLK_V128 (128*4) +#define BLK_V256 (256*4) + +unsigned char *u32enc(unsigned *__restrict in, int n, unsigned *__restrict out) { unsigned *ip; + for(ip = in; ip != in+(n&~3); ) { + *out++ = *ip++; + *out++ = *ip++; + *out++ = *ip++; + *out++ = *ip++; + } + while(ip < in+n) *out++ = *ip++; + return (unsigned char *)out; +} + +unsigned char *u32dec(unsigned *__restrict in, int n, unsigned *__restrict out) { unsigned *op; + for(op = out; op != out+(n&~3); ) { + *op++ = *in++; + *op++ = *in++; + *op++ = *in++; + *op++ = *in++; + } + while(op < out+n) *op++ = *in++; + return (unsigned char *)in; +} + +unsigned char *_bitunpackx32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out , unsigned b) { unsigned i,k=0; for(i=0; i < n; i++,k+=b ) *out++ = _bitgetx16(in, k, b); return in + PAD8(n*b); } +// direct access functions : included for demonstration only. Use the bulk functions instead, if you are decompressing most of the values +unsigned char *bitf1unpackx32(unsigned char *__restrict in, unsigned n, unsigned *__restrict out, int start, unsigned b) { int i; for(i = 0; i < n; i++) out[i] = bitgetx32(in, i, b)+start+i+1; return in + PAD8(n*b); } +unsigned char *bitfunpackx32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, int start, unsigned b) { int i; for(i = 0; i < n; i++) out[i] = bitgetx16(in, i, b)+start; return in + PAD8(n*b); } + +//------------------------------------------------- plugins: codes+function ------------------------------------------------- +struct codecs codecs[] = { + { C_TURBOPFOR, "TurboPFor", "https://github.com/powturbo/TurboPFor" }, + // External libs + { C_C_BLOSC, "blosc", "https://github.com/Blosc/c-blosc" }, + { C_FASTPFOR, "FastPFor", "https://github.com/lemire/FastPFor" }, + { C_FASTPFOR128, "FastPFor SSE", "https://github.com/lemire/FastPFor" }, + { C_LZ4, "lz4", "https://github.com/Cyan4973/lz4" }, + { C_LITTLEPACK, "LittleIntPacker", "https://github.com/lemire/LittleIntPacker" }, + { C_LZTURBO, "LzTurbo", "https://sites.google.com/site/powturbo" }, + { C_MASKEDVBYTE, "MaskedVbyte", "http://maskedvbyte.org" }, + { C_POLYCOM, "Polycom", "https://github.com/encode84/bcm" }, + { C_QMX, "QMX", "https://bitbucket.org/andrewtrotman/bench" }, + { C_SIMDCOMP128, "simdcomp", "https://github.com/lemire/simdcomp" }, + { C_SIMPLE8B, "Simple-8b optimized", "https://github.com/powturbo/TurboPFor" }, + { C_STREAMVBYTE, "Streamvbyte", "https://github.com/lemire/streamvbyte" }, + { C_VARINTG8IU, "VarintG8IU", "https://github.com/lemire/FastPFor" }, + { C_ZLIB, "zlib", "http://zlib.net\thttps://github.com/madler/zlib" }, + { C_VTENC, "VTEnc", "VTENC" }, + { C_MEMCPY, "memcpy/copy", "--------------------------------------" }, + { -1 } +}; + +struct plugs plugs[] = { + { TB_PF128V, "TurboPFor", C_TURBOPFOR128, BLK_V128,0,"","PFor (SSE2)" }, + { TB_PFN128V, "TurboPForN", C_TURBOPFOR128, 0, 0,"","PFor (SSE2) large blocks" }, + { TB_PF256V, "TurboPFor256", C_TURBOPFOR256, BLK_V256,0,"","PFor (AVX2)" }, + { TB_PFN256V, "TurboPFor256N", C_TURBOPFOR256, 0, 0,"","PFor (AVX2) large blocks" }, + { TB_PFDA, "TurboPForDA", C_TURBOPFOR, BLK_V128,0,"","PFor direct access" }, + { TB_PDI, "TurboPForDI", C_TURBOPFOR, BLK_V128,0,"","PFord min" }, + { TB_PFNZZ, "TurboPForZZ", C_TURBOPFOR, 0, 0,"","PFor zigzag of delta" }, + + { TB_FOR, "TurboFor", C_TURBOPFOR, BLK_V128,0,"","FOR" }, + { TB_FOR128V, "TurboForV", C_TURBOPFOR128, BLK_V128,0,"","FOR (SIMD)" }, + { TB_FOR256V, "TurboFor256V", C_TURBOPFOR256, BLK_V256,0,"","FOR (AVX2)" }, + { TB_FORDA, "TurboForDA", C_TURBOPFOR, BLK_V128,0,"","FOR direct access" }, + { TB_BPDA, "TurboPackDA", C_TURBOPFOR, BLK_V128,0,"","Bit packing direct access" }, + + { TB_BP, "TurboPack", C_TURBOPFOR, 0, 0,"","Bit packing (scalar)" }, + { TB_BPN, "TurboPackN", C_TURBOPFOR, 0, 0,"","Bit packing (scalar) large blocks" }, + { TB_BP128V, "TurboPackV", C_TURBOPFOR128, BLK_V128,0,"","Bit packing (SSE2 Vertical)" }, + { TB_BP128H, "TurboPackH", C_TURBOPFOR128, BLK_V128,0,"","Bit packing (SSE2 Horizontal)" }, + { TB_BPN128V, "TurboPackVN", C_TURBOPFOR128, 0, 0,"","Bit packing (SSE2 large block)" }, + { TB_BP256V, "TurboPack256V", C_TURBOPFOR256, BLK_V256,0,"","Bit packing (AVX2 Vertical)" }, + { TB_BPN256V, "TurboPack256N", C_TURBOPFOR256, 0, 0,"","Bit packing (AVX2 large block)" }, + + { TB_VBYTE, "TurboVByte", C_TURBOPFOR, 0, 0,"","Variable byte (scalar)" }, + { TB_BYTE, "TurboByte", C_TURBOPFOR, 0, 0,"","SIMD Group Varint" }, + { TB_BYTE128V, "TurboByte128V", C_TURBOPFOR, 0, 0,"","TurboByte+Bitpacking" }, + { TB_BYTE256V, "TurboByte256V", C_TURBOPFOR, 0, 0,"","TurboByte+Bitpacking" }, + { TB_VSIMPLE, "VSimple", C_TURBOPFOR, 0, 0,"","Variable simple (scalar)" }, + { TB_EF, "EliasFano", C_TURBOPFOR, 0, 0,"","Elias fano (scalar)" }, + { TB_EF128V, "EliasFanoV", C_TURBOPFOR128, BLK_V128,0,"","Eliasfano (SSE2)" }, + { TB_EF256V, "EliasFano256V", C_TURBOPFOR256, BLK_V256,0,"","Elias fano (AVX2" }, + + { P_MCPY, "memcpy", C_MEMCPY, 0, 0,"","memcpy" }, + { P_COPY, "copy", C_MEMCPY, 0, 0,"","Integer copy" }, + //----- Transform -------------- + { TP_BYTES, "tpbyte4s", C_TURBOPFOR, BLK_SIZE,0,"","Byte Transpose (scalar)" }, + { TP_BYTE, "tpbyte", C_TURBOPFOR, BLK_SIZE,0,"2,4,8","Byte transpose (simd)" }, + { TP_NIBBLE, "tpnibble", C_TURBOPFOR, BLK_SIZE,0,"2,4,8","Nibble transpose (simd)" }, + { TB_ZIGZAG32, "ZigZag32", C_TURBOPFOR, BLK_SIZE,0,"","ZigZag encoding (sse2)" }, + { TB_DELTA32, "Delta32", C_TURBOPFOR, BLK_SIZE,0,"","Delta encoding (sse2)"}, + { TB_ZDELTA32, "ZDelta32", C_TURBOPFOR, BLK_SIZE,0,"","Zigzag of delta encoding (sse2)"}, + { TB_XOR32, "Xor32", C_TURBOPFOR, BLK_SIZE,0,"","Xor encoding (sse2)" }, + // ---- Floating point -------- +//{ TB_FPPFOR64, "FP_PREV64", C_TURBOPFOR, BLK_SIZE,0,"","Floating point PFOR" }, + { TB_FPFFOR64, "FP_FCM64", C_TURBOPFOR, BLK_SIZE,0,"","Floating point PFOR (FCM)" }, + { TB_FPDFOR64, "FP_DFCM64", C_TURBOPFOR, BLK_SIZE,0,"","Floating point PFOR (DFCM)" }, + { TB_PF64, "TurboPFor64", C_TURBOPFOR, BLK_V128,0,"","PFOR 64" }, + { TB_PF64V, "TurboPFor64V", C_TURBOPFOR, BLK_V128,0,"","PFOR 64" }, + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugr_.h" // external libs + #endif + { -1 } +}; + +struct plugg plugg[] = { + { "TURBOPFOR","TurboPFor library", "TurboPFor256V/TurboPack256V/TurboPFor256N/TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboForDA/EliasFano/VSimple/TurboPForN/TurboPackN/TurboPForDI" }, + { "DEFAULT", "Default", "TurboPFor/TurboPackV/TurboVByte/TurboPack/TurboFor/TurboPForN/TurboPackN/TurboPForDI/TurboPFor256V/TurboPack256V/TurboPFor256N" }, + { "BENCH", "Benchmark", "TurboPFor/TurboPackV/TurboVByte/TurboPack/QMX/FP.SimdFastPfor/FP.SimdOptPFor/MaskedVbyte/StreamVbyte" }, + { "EFFICIENT","Efficient", "TurboPFor/vsimple/turbovbyte" }, + { "TRANSFORM","transpose/shufle,delta,zigzag","tpbyte4s/tpbyte,4/tpnibble,4/ZigZag_32/Delta_32/BitShuffle,4" }, + + { "BITPACK", "Bit Packing", "TurboPack256V/TurboPackV/TurboPackH/TurboPack/SC.SimdPack128/SC.SimdPack256" }, + { "VBYTE", "Variable byte", "TurboVByte/FP.VByte/PC.Vbyte/VarintG8IU/MaskedVbyte/StreamVbyte" }, + { "SIMPLE", "Simple Family", "simple8b/simple16/vsimple/qmx" }, + + { "LZ4", "lz4+bitshufle/transpose 4,8", "lz4_bitshufle/lz4_tp4/lz4_tp8" }, + { "LI", "Little Integer", "LI_Pack/LI_TurboPack/LI_SuperPack/LI_HorPack" }, + { "" } +}; + +#define PAD8(__x) (((__x)+7)/8) +//---------------------------------------------- plugins -------------------------------------------------------- +#include "conf.h" +unsigned char sbuf[BLK_SIZE*2+1024]; + +int codini(size_t insize, int codec) { + switch(codec) { + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugi_.c" + #endif + } + return 0; +} + +void codexit(int codec) {} + +//--- Sorted integer array : Delta/Differential compression (mdelta=0 increasing, mdelta=1 strictly increasing sequence) --------------- +unsigned char *codcomps(unsigned char *_in, unsigned _n, unsigned char *out, int outsize, int codec, int lev, char *prm, int mdelta) { + unsigned *in = (unsigned *)_in, n = (_n+3) / 4, i, *pa=(unsigned *)sbuf, x, b; + + switch(codec) { + case TB_VSIMPLE: x = *in++; bitdienc32( in, --n, pa, x, mdelta); + vbxput32(out, x); return vsenc32( pa, n, out); + case TB_VBYTE: x = *in++; --n; vbxput32(out, x); return mdelta?vbd1enc32( in, n, out, x ):vbdenc32( in, n, out, x); + case TB_BYTE: x = *in++; --n; vbxput32(out, x); return mdelta?v8d1enc32( in, n, out, x ):v8denc32( in, n, out, x); + case TB_EF: x = *in++; --n; vbxput32(out, x); return mdelta?efano1enc32( in, n, out, x+1 ):efanoenc32( in, n, out, x); + + case TB_PFDA: x = *in++; --n; vbxput32(out, x); DELTR(in,n,x,mdelta,pa); + return p4encx32(pa,n,out); + case TB_FOR : + case TB_FORDA: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitf132(in, n, 0,x)); *out++=b; return bitf1pack32(in, n, out, x, b); } + else { b = bsr32(bitf32( in, n, 0,x)); *out++=b; return bitfpack32( in, n, out, x, b); } + + #if C_TURBOPFORH + case TB_BP128H: + #endif + case TB_BP: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitd132(in, n, 0,x)); *out++=b; return bitd1pack32(in, n, out, x, b); } + else { b = bsr32(bitd32( in, n, 0, x)); *out++=b; return bitdpack32( in, n, out, x, b); } + case TB_BPN: return out+(mdelta?bitnd1pack32(in, n, out):bitndpack32( in, n, out)); + + case TB_PDI: x = *in++; --n; vbxput32(out, x); return p4senc32(in, n, out, x ); + + #if C_TURBOPFOR128 + case TB_EF128V: x = *in++; --n; vbxput32(out, x); + if(mdelta) return n == 128?efano1enc128v32(in, n, out, x+1 ):efano1enc32( in, n, out, x+1); + else return n == 128?efanoenc128v32( in, n, out, x ):efanoenc32( in, n, out, x ); + case TB_PF128V: x = *in++; --n; vbxput32(out, x); + if(mdelta) return n == 128?p4d1enc128v32( in, n, out, x ):p4d1enc32( in, n, out, x); + else return n == 128?p4denc128v32( in, n, out, x ):p4denc32( in, n, out, x); + case TB_PFN128V: return out+(mdelta?p4nd1enc128v32( in, n, out ):p4ndenc128v32(in, n, out)); + + case TB_FOR128V: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitf132(in, n, 0,x)); *out++=b; return n == 128?bitf1pack128v32(in, n, out, x, b):bitf1pack32( in, n, out, x, b); } + else { b = bsr32(bitf32( in, n, 0,x)); *out++=b; return n == 128?bitfpack128v32( in, n, out, x, b):bitfpack32( in, n, out, x, b); } + case TB_BP128V: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitd132(in, n, 0,x));*out++=b; return n == 128?bitd1pack128v32(in, n, out, x, b):bitd1pack32( in, n, out, x, b); } + else { b = bsr32(bitd32( in, n, 0,x)); *out++=b; return n == 128?bitdpack128v32( in, n, out, x, b):bitdpack32( in, n, out, x, b); } + case TB_BPN128V: return out+(mdelta?bitnd1pack128v32( in, n, out ):bitndpack128v32(in, n, out)); + case TB_BYTE128V: return out+(mdelta?v8nd1enc128v32( in, n, out ):v8ndenc128v32( in, n, out)); + #endif + + #if C_TURBOPFOR256 + case TB_FOR256V: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitf132(in, n, 0,x)); *out++=b; return n == 256?bitf1pack256v32(in, n, out, x, b):bitf1pack32( in, n, out, x, b); } + else { b = bsr32(bitf32( in, n, 0,x)); *out++=b; return n == 256?bitfpack256v32( in, n, out, x, b):bitfpack32( in, n, out, x, b); } + case TB_EF256V: x = *in++; --n; vbxput32(out, x); + if(mdelta) return n == 256?efano1enc256v32(in, n, out, x+1 ):efano1enc32( in, n, out, x+1); + else return n == 256?efanoenc256v32( in, n, out, x ):efanoenc32( in, n, out, x ); + case TB_PF256V: x = *in++; bitdienc32( in, --n, pa, x, mdelta); + vbxput32(out, x); return n == 256?p4enc256v32( pa, n, out ):p4enc32( pa, n, out); + case TB_PFN256V: return out+(mdelta?p4nd1enc256v32( in, n, out ):p4ndenc256v32(in, n, out)); + case TB_BP256V: x = *in++; --n; vbxput32(out, x); + if(mdelta) { b = bsr32(bitd132(in, n, 0,x)); *out++=b; return n == 256?bitd1pack256v32(in, n, out, x, b):bitd1pack32( in, n, out, x, b); } + else { b = bsr32(bitd32( in, n, 0,x)); *out++=b; return n == 256?bitdpack256v32( in, n, out, x, b):bitdpack32( in, n, out, x, b); } + case TB_BPN256V: return out+(mdelta?bitnd1pack256v32( in, n, out ):bitndpack256v32(in, n, out)); + case TB_BYTE256V: return out+(mdelta?v8nd1enc256v32( in, n, out ):v8ndenc256v32( in, n, out)); + #endif + // --------- transform ------------------------------------------------------------------------------------------------ + #if C_TRANSFORM + case TB_ZIGZAG32: bitzenc32( in, n, (unsigned *)out, 0, 0); return out + _n; + case TP_BYTES: bitdienc32(in, n, (unsigned *)sbuf, -mdelta, mdelta); tpenc4((unsigned char *)sbuf, _n, out); return out + _n; + case TP_BYTE: bitdienc32(in, n, (unsigned *)sbuf, -mdelta, mdelta); tpenc( (unsigned char *)sbuf, _n, out, lev); return out + _n; + case TP_NIBBLE: bitdienc32(in, n, (unsigned *)sbuf, -mdelta, mdelta); tp4enc((unsigned char *)sbuf, _n, out, lev); return out + _n; + case TB_DELTA32: bitdienc32(in, n, (unsigned *)out, -mdelta, mdelta); return out + _n; + case TB_ZDELTA32: bitzzenc32(in, n, (unsigned *)out, -mdelta, mdelta); return out + _n; + case TB_XOR32: bitxenc32( in, n, (unsigned *)out, -mdelta); return out + _n; + #endif + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugcs_.c" + #endif + } + return out; +} + +unsigned char *coddecomps(unsigned char *in, unsigned _n, unsigned char *_out, int outlen, int codec, int lev, char *prm, int mdelta) { + unsigned *out = (unsigned *)_out, n = (outlen+3) / 4,x,b; + + switch(codec) { + case TB_VSIMPLE:vbxget32(in, x);*out++ = x; --n; in = vsdec32( in, n, out); bitdidec32(out, n, x+mdelta, mdelta); return in; + case TB_EF: vbxget32(in, x);*out++ = x; --n; return mdelta?efano1dec32( in, n, out, x+1 ):efanodec32( in, n, out, x); + case TB_VBYTE: vbxget32(in, x);*out++ = x; --n; return mdelta?vbd1dec32( in, n, out, x ):vbddec32( in, n, out, x); + case TB_BYTE: vbxget32(in, x);*out++ = x; --n; return mdelta?v8d1dec32( in, n, out, x ):v8ddec32( in, n, out, x); + + case TB_PFDA: vbxget32(in, x);*out++ = x; --n; return mdelta?p4f1decx32( in, n, out, x ):p4fdecx32( in, n, out, x); + + case TB_FOR: vbxget32(in, x);*out++ = x; --n; b = *in++; return mdelta?bitf1unpack32( in, n, out, x, b):bitfunpack32( in, n, out, x, b); + case TB_FORDA: vbxget32(in, x);*out++ = x; --n; b = *in++; return mdelta?bitf1unpackx32( in, n, out, x, b):bitfunpackx32( in, n, out, x, b); + case TB_BP: vbxget32(in, x);*out++ = x; --n; b = *in++; return mdelta?bitd1unpack32( in, n, out, x, b):bitdunpack32( in, n, out, x, b); + case TB_BPN: return in+(mdelta?bitnd1unpack32(in, n, out ):bitndunpack32( in, n, out)); + + case TB_PDI: vbxget32(in, x);*out++ = x; --n; return p4sdec32(in, n, out, x); + + #if C_TURBOPFOR128 + case TB_FOR128V:vbxget32(in, x);*out++ = x; --n; b = *in++; + if(mdelta) { return n==128?bitf1unpack128v32( in, n, out, x, b):bitf1unpack32( in, n, out, x, b); } + else { return n==128?bitfunpack128v32( in, n, out, x, b):bitfunpack32(in, n, out, x, b); } + case TB_EF128V: vbxget32(in, x);*out++ = x; --n; + if(mdelta) { return n==128?efano1dec128v32(in, n, out, x+1 ):efano1dec32( in, n, out, x+1); } + else { return n==128?efanodec128v32( in, n, out, x ):efanodec32( in, n, out, x); } + case TB_PF128V: vbxget32(in, x);*out++ = x; --n; //__builtin_prefetch(in+256); + if(mdelta) { return n==128?p4d1dec128v32( in, n, out, x ):p4d1dec32( in, n, out, x); } + else { return n==128?p4ddec128v32( in, n, out, x ):p4ddec32( in, n, out, x); } + case TB_PFN128V: return in+(mdelta?p4nd1dec128v32(in, n, out ):p4nddec128v32( in, n, out)); + case TB_BP128V: vbxget32(in, x);*out++ = x; --n; b = *in++; + if(mdelta) { return n==128?bitd1unpack128v32(in, n, out, x, b):bitd1unpack32( in, n, out, x, b); } + else { return n==128?bitdunpack128v32( in, n, out, x, b):bitdunpack32( in, n, out, x, b); } + case TB_BPN128V: return in+(mdelta?bitnd1unpack128v32(in, n, out ):bitndunpack128v32(in, n, out)); + case TB_BYTE128V: return in+(mdelta?v8nd1dec128v32(in, n, out ):v8nd1dec128v32(in, n, out)); + #endif + + #if C_TURBOPFORH + case TB_BP128H: vbxget32(in, x);*out++ = x; --n; b = *in++; + if(mdelta) { return n==128?bitd1unpack128h32(in, n, out, x, b):bitd1unpack32( in, n, out, x, b); } + else { return n==128?bitdunpack128h32( in, n, out, x, b):bitdunpack32( in, n, out, x, b); } + #endif + + #if C_TURBOPFOR256 + case TB_EF256V: vbxget32(in, x);*out++ = x; --n; + if(mdelta) { return n==256?efano1dec256v32(in, n, out, x+1 ):efano1dec32( in, n, out, x+1); } + else { return n==256?efanodec256v32( in, n, out, x ):efanodec32( in, n, out, x); } + case TB_PF256V: vbxget32(in, x);*out++ = x; --n; //__builtin_prefetch(in+256); + if(mdelta) { return n==256?p4d1dec256v32( in, n, out, x ):p4d1dec32( in, n, out, x); } + else { return n==256?p4ddec256v32( in, n, out, x ):p4ddec32( in, n, out, x); } + case TB_PFN256V: return in+(mdelta?p4nd1dec256v32(in, n, out ):p4nddec256v32( in, n, out)); + case TB_FOR256V:vbxget32(in, x);*out++ = x; --n; b = *in++; + if(mdelta) { return n==256?bitf1unpack256v32( in, n, out, x, b):bitf1unpack32( in, n, out, x, b); } + else { return n==256?bitfunpack256v32( in, n, out, x, b):bitfunpack32(in, n, out, x, b); } + case TB_BP256V: vbxget32(in, x);*out++ = x; --n; b = *in++; + if(mdelta) { return n==256?bitd1unpack256v32(in, n, out, x, b):bitd1unpack32( in, n, out, x, b); } + else { return n==256?bitdunpack256v32( in, n, out, x, b):bitdunpack32( in, n, out, x, b); } + case TB_BPN256V: return in+(mdelta?bitnd1unpack256v32(in, n, out ):bitndunpack256v32(in, n, out)); + case TB_BYTE256V: return in+(mdelta?v8nd1dec256v32(in, n, out ):v8nddec256v32(in, n, out)); + #endif + + //---------- transpose + lz77 ---------------------- + #if C_TRANSFORM + case TB_ZIGZAG32: memcpy(out, in, outlen); bitzdec32(out, n, 0); return in + outlen; + case TP_BYTES: tpdec4((unsigned char *)in, outlen, (unsigned char *)out); bitdidec32(out, n, -mdelta, mdelta); return in + outlen; + case TP_BYTE: tpdec( (unsigned char *)in, outlen, (unsigned char *)out,lev); bitdidec32(out, n, -mdelta, mdelta); return in + outlen; + case TP_NIBBLE: tp4dec((unsigned char *)in, outlen, (unsigned char *)out,lev); bitdidec32(out, n, -mdelta, mdelta); return in + outlen; + case TB_DELTA32: memcpy(out, in, outlen); mdelta?bitd1dec32(out, n, -mdelta):bitddec32(out, n, 0); return in + outlen; + case TB_ZDELTA32: memcpy(out, in, outlen); bitzzdec32(out, n, -mdelta); return in + outlen; + case TB_XOR32: memcpy(out, in, outlen); bitxdec32(out, n, -mdelta); return in + outlen; + #endif + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugds_.c" + #endif + } + return in; +} + +//---- ZigZag---- +unsigned char *codcompz(unsigned char *_in, unsigned _n, unsigned char *out, int outsize, int codec, int lev, char *prm, int mdelta) { + unsigned *in = (unsigned *)_in, n = (_n+3) / 4, i, *pa = (unsigned *)sbuf, x, b; + + switch(codec) { + case TB_VBYTE: x = *in++; --n; vbxput32(out, x); return vbzenc32( in, n, out, x); + case TB_BYTE: x = *in++; --n; vbxput32(out, x); return v8zenc32( in, n, out, x); + case TB_BP: x = *in++; --n; vbxput32(out, x);b = bsr32(bitz32(in, n, 0,x)); *out++=b;return bitzpack32(in, n, out, x, b); + case TB_BPN: return out+bitnzpack32(in, n, out); + #if C_TURBOPFOR128 + case TB_PF128V: x = *in++; --n; vbxput32(out, x); return n == 128?p4zenc128v32(in, n, out, x):p4zenc32(in, n, out, x); + case TB_PFN128V: return out+p4nzenc128v32( in, n, out ); + case TB_BP128V: x = *in++; --n; vbxput32(out, x);b = bsr32(bitz32(in, n, 0,x)); *out++=b;return n == 128?bitzpack128v32(in, n, out, x, b):bitzpack32(in, n, out, x, b); + case TB_BPN128V: return out+bitnzpack128v32( in, n, out ); + #endif + + #if C_TURBOPFOR256 + case TB_PF256V: x = *in++; --n; vbxput32(out, x); return n == 256?p4zenc256v32(in, n, out, x):p4zenc32(in, n, out, x); + case TB_PFN256V: return out+p4nzenc256v32( in, n, out ); + case TB_BP256V: x = *in++; --n; vbxput32(out, x);b = bsr32(bitz32(in, n, 0, x)); *out++=b;return n == 256?bitzpack256v32(in, n, out, x, b):bitzpack32(in, n, out,x, b); + case TB_BPN256V: return out+bitnzpack256v32( in, n, out ); + #endif + } + return out; +} + +unsigned char *coddecompz(unsigned char *in, unsigned _n, unsigned char *_out, int outlen, int codec, int lev, char *prm, int mdelta) { + unsigned *out = (unsigned *)_out, n = (outlen+3) / 4,x,b; + + switch(codec) { + case TB_VBYTE: vbxget32(in, x); *out++ = x; --n; return vbzdec32(in, n, out, x); + case TB_BP: vbxget32(in, x); *out++ = x; --n; b = *in++; return bitzunpack32(in, n, out, x, b); + case TB_BPN: return in+bitnzunpack32(in, n, out); + case TB_BYTE: vbxget32(in, x); *out++ = x; --n; return v8zdec32(in, n, out, x); + + #if C_TURBOPFOR128 + case TB_PF128V:vbxget32(in, x); *out++ = x; --n; return n == 128?p4zdec128v32(in, n, out, x):p4zdec32(in, n, out, x); + case TB_PFN128V: return in+p4nzdec128v32(in, n, out); + case TB_BP128V:vbxget32(in, x); *out++ = x; --n; b = *in++; return n == 128?bitzunpack128v32(in, n, out, x, b):bitzunpack32(in, n, out, x, b); + case TB_BPN128V: return in+bitnzunpack128v32(in, n, out); + case TB_BYTE128V: return in+v8nzdec128v32(in, n, out); + #endif + + #if C_TURBOPFOR256 + case TB_PF256V:vbxget32(in, x); *out++ = x; --n; return n == 256?p4zdec256v32(in, n, out, x):p4zdec32(in, n, out, x); + case TB_PFN256V: return in+p4nzdec256v32(in, n, out); + case TB_BP256V:vbxget32(in, x); *out++ = x; --n; b = *in++; return n == 256?bitzunpack256v32(in, n, out, x, b):bitzunpack32(in, n, out, x, b); + case TB_BPN256V: return in+bitnzunpack256v32(in, n, out); + case TB_BYTE256V: return in+v8nzdec256v32(in, n, out); + #endif + } + return in; +} + +unsigned char *codcomp(unsigned char *_in, unsigned _n, unsigned char *out, int outsize, int codec, int lev, char *prm, int b) { + unsigned *in = (unsigned *)_in, n = (_n+3) / 4, x; + + switch(codec) { + case TB_EF: return out; // Not applicable + case TB_VBYTE: return vbenc32( in, n, out); + case TB_BYTE: return v8enc32( in, n, out); + case TB_VSIMPLE: return vsenc32( in, n, out); + + case TB_PFDA: return p4encx32( in, n, out); //case TB_PFM: bsr32(bitfm32( in, n, 0,&x)); vbxput32(out, x); return p4denc32(in, n, out, x); + case TB_PDI: { unsigned *pa = (unsigned *)sbuf,mdelta; + bitfm32(in, n, 0, &x); // determine minimum value + mdelta = bitdi32(in, n, 0, x); if(mdelta>(1<<27)) mdelta=1<<27;// determine minimum delta + bitdienc32(in, n, pa, x, mdelta); // delta transform + mdelta=mdelta<<5|(x&31); x>>=5; vbxput32(out, x); vbput32(out, mdelta); + return p4enc32(pa, n, out); + } + case TB_FOR : + case TB_FORDA: b = bsr32(bitfm32( in, n, 0, &x)); vbxput32(out, x); *out++=b; return bitfpack32( in, n, out, x, b); + + #if C_TURBOPFORH + case TB_BP128H: + #endif + case TB_BPDA: + case TB_BP: if(b < 0) { b = bsr32(bit32(in, n, 0)); *out++ = b; } + return bitpack32(in, n, out, b); + case TB_BPN: return out+bitnpack32(in, n, out); + + #if C_TURBOPFOR128 + case TB_EF128V: return out; + + case TB_PF128V: return n == 128?p4enc128v32(in, n, out):p4enc32(in, n, out); + case TB_PFN128V: return out+p4nenc128v32(in, n, out); + case TB_PFNZZ: return out+p4nzzenc128v32( in, n, out, 0); + + case TB_FOR128V: b = bsr32(bitfm32( in, n, 0, &x)); vbxput32(out, x); *out++=b; return bitfpack128v32( in, n, out, x, b); + + case TB_BP128V: if(b < 0) { b = bsr32(bit32(in, n, 0)); *out++ = b; } + return n == 128?bitpack128v32(in, n, out, b):bitpack32(in, n, out, b); + case TB_BPN128V: return out+bitnpack128v32(in, n, out); + case TB_BYTE128V: return out+v8nenc128v32(in, n, out); + #endif + + #if C_TURBOPFOR256 + case TB_PF256V: return n == 256?p4enc256v32(in, n, out):p4enc32(in, n, out); + case TB_PFN256V: return out+p4nenc256v32(in, n, out); + + case TB_FOR256V: b = bsr32(bitfm32( in, n, 0, &x)); vbxput32(out, x); *out++=b; return bitfpack256v32( in, n, out, x, b); + + case TB_BP256V: if(b < 0) { b = bsr32(bit32(in, n, 0)); *out++ = b; } + return n == 256?bitpack256v32(in, n, out, b):bitpack32(in, n, out, b); + case TB_BPN256V: return out+bitnpack256v32(in, n, out); + case TB_BYTE256V: return out+v8nenc256v32(in, n, out); + #endif + + case P_COPY: return u32enc( in, n, (unsigned *)out); + case P_MCPY: memcpy(out, _in, _n); return out+_n; + // --------- transform ---------------------------------------- + #if C_TRANSFORM + case TP_BYTES: tpenc4((unsigned char *)in, _n, out); return out + _n; + case TP_BYTE: tpenc( (unsigned char *)in, _n, out,lev); return out + _n; + case TP_NIBBLE: tp4enc((unsigned char *)in, _n, out,lev); return out + _n; + case TB_DELTA32: bitdienc32( in,n, (unsigned *)out,0,0); return out + _n; + case TB_ZDELTA32: bitzzenc32( in,n, (unsigned *)out,0,0); return out + _n; + case TB_ZIGZAG32: bitzenc32( in, n,(unsigned *)out,0,0); return out + _n; + #endif + //---- Floating point ---------------------- + //case TB_FPPFOR64: ctou64(out) = ctou64(_in); return out+fppenc64( (uint64_t *)(_in+8), PAD8(_n)-1, out+8, ctou64(_in)); + case TB_FPFFOR64: ctou64(out) = ctou64(_in); return out+fpfcmenc64( (uint64_t *)(_in+8), PAD8(_n)-1, out+8, ctou64(_in)); + case TB_FPDFOR64: ctou64(out) = ctou64(_in); return out+fpdfcmenc64((uint64_t *)(_in+8), PAD8(_n)-1, out+8, ctou64(_in)); + case TB_PF64: return p4enc64((uint64_t *)in, PAD8(_n), out); + case TB_PF64V: return p4enc128v64((uint64_t *)in, PAD8(_n), out); + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugc_.c" + #endif + } + return out; +} + +unsigned char *coddecomp(unsigned char *in, unsigned _n, unsigned char *_out, int outlen, int codec, int lev, char *prm, int b) { + unsigned *out = (unsigned *)_out, n = (outlen+3) / 4,x; + switch(codec) { + case TB_VBYTE: return vbdec32( in, n, out); // case P_VU: return vudec32( in, n, out); + case TB_BYTE: return v8dec32( in, n, out); + case TB_VSIMPLE: return vsdec32( in, n, out); + case TB_EF: return in; // Not applicable + case TB_PFDA : return p4decx32( in, n, out); //case TB_PFM: vbxget32(in, x); return p4ddec32( in, n, out, x); + case TB_PDI: { uint32_t mdelta; vbxget32(in, x); vbget32(in, mdelta); x = x << 5 | (mdelta & 31); in = p4dec32(in, n, out); bitdidec32(out, n, x, mdelta>>5); break; } + + case TB_FOR: vbxget32(in, x); b = *in++; return bitfunpack32( in, n, out, x, b); + case TB_FORDA: vbxget32(in, x); b = *in++; return bitfunpackx32(in, n, out, x, b); + + case TB_BPDA: if(b < 0) b = *in++; return _bitunpackx32( in, n, out, b); + case TB_BP: if(b < 0) b = *in++; return bitunpack32( in, n, out, b); + case TB_BPN: return in+bitnunpack32( in, n, out); + + #if C_TURBOPFOR128 + case TB_PF128V : return n == 128?p4dec128v32(in, n, out):p4dec32(in, n, out); + case TB_PFN128V : return in+p4ndec128v32(in, n, out); + case TB_PFNZZ: return in+p4nzzdec128v32( in, n, out,0); + + case TB_EF128V: return in; + + case TB_FOR128V: vbxget32(in, x); b = *in++;return bitfunpack128v32( in, n, out, x, b); + + case TB_BP128V: if(b < 0) b = *in++; return n != 128?bitunpack32(in, n, out, b):bitunpack128v32(in, n, out, b); + case TB_BPN128V : return in+bitnunpack128v32(in, n, out); + case TB_BYTE128V : return in+v8ndec128v32(in, n, out); + #endif + + #if C_TURBOPFORH + case TB_BP128H: if(b < 0) b = *in++; return n == 128?bitunpack128h32(in, n, out, b):bitunpack32(in, n, out, b); + #endif + + #if C_TURBOPFOR256 + case TB_FOR256V: vbxget32(in, x); b = *in++;return bitfunpack256v32( in, n, out, x, b); + + case TB_PF256V : __builtin_prefetch(in+256);return n == 256?p4dec256v32(in, n, out):p4dec32(in, n, out); + case TB_PFN256V : return in+p4ndec256v32(in, n, out); + case TB_BP256V: if(b < 0) b = *in++; return n != 256?bitunpack32(in, n, out, b):bitunpack256v32(in, n, out, b); + case TB_BPN256V: return in+bitnunpack256v32(in, n, out); + case TB_BYTE256V: return in+v8ndec256v32(in, n, out); + #endif + + //---------- transform ---------------------- + #if C_TRANSFORM + case TP_BYTES: tpdec4( (unsigned char *)in, outlen, (unsigned char *)out); return in + outlen; + case TP_BYTE: tpdec( (unsigned char *)in, outlen, (unsigned char *)out,lev); return in + outlen; + case TP_NIBBLE: tp4dec( (unsigned char *)in, outlen, (unsigned char *)out,lev); return in + outlen; + case TB_DELTA32: memcpy(out, in, outlen); bitddec32(out, n, 0); return in + outlen; + case TB_ZDELTA32: memcpy(out, in, outlen); bitzzdec32(out, n, 0); return in + outlen; + case TB_ZIGZAG32: memcpy(out, in, outlen); bitzdec32(out, n, 0); return in + outlen; + #endif + //---- Floating point (64 bits)---------------------- + //case TB_FPPFOR64: ctou64(_out) = ctou64(in); return in+fppdec64( in+8, PAD8(outlen)-1, (uint64_t *)(_out+8), ctou64(in)); + case TB_FPFFOR64: ctou64(_out) = ctou64(in); return in+fpfcmdec64( in+8, PAD8(outlen)-1, (uint64_t *)(_out+8), ctou64(in));; + case TB_FPDFOR64: ctou64(_out) = ctou64(in); return in+fpdfcmdec64(in+8, PAD8(outlen)-1, (uint64_t *)(_out+8), ctou64(in)); + case TB_PF64: return p4dec64( in, PAD8(outlen), (uint64_t *)out); + case TB_PF64V: return p4dec128v64(in, PAD8(outlen), (uint64_t *)out); + #if CODEC1==1 || CODEC2==1 + #include "ext/beplugd_.c" + #endif + } + return in; +} + +char *codver(int codec, char *v, char *s) { + switch(codec) { + #if C_C_BLOSC + return BLOSC_VERSION_STRING; + #endif + #if C_LZ4 + case LZ4_: sprintf(s,"%d.%d.%d", LZ4_VERSION_MAJOR, LZ4_VERSION_MINOR, LZ4_VERSION_RELEASE); return s; + #endif + #if C_ZSTD + case P_ZSTD: sprintf(s,"%d.%d.%d", ZSTD_VERSION_MAJOR, ZSTD_VERSION_MINOR, ZSTD_VERSION_RELEASE); return s; + #endif + default: if(v) strcpy(s,v); + } + return s; +} + diff --git a/src/ext/for/plugins.h b/src/ext/for/plugins.h new file mode 100644 index 00000000000..a561883f27f --- /dev/null +++ b/src/ext/for/plugins.h @@ -0,0 +1,74 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// TurboPFor: plugins.h - settings +#define G_N 0x1 +#define G_D0 0x2 +#define G_D1 0x4 +#define G_Z 0x8 +#define G_D (G_D1|G_D0) + +struct codecs { + int coid; + char *name,*url,*ver; +}; + +struct plugs { + int id; + char *name; + unsigned codec,blksize,flag; + char *lev,*desc; +}; + +struct plugg { + char id[17],*desc,*name; +}; + + #ifdef __cplusplus +extern "C" { + #endif +extern struct plugg plugg[]; +extern struct codecs codecs[]; +extern struct plugs plugs[]; +int codini(size_t insize, int codec); +void codexit(int codec); +int codstart( unsigned char *in, int inlen, int codec); +unsigned char *codcomp( unsigned char *in, unsigned n, unsigned char *out, int outsize, int codec, int lev, char *prm, int b); +unsigned char *coddecomp( unsigned char *in, unsigned n, unsigned char *out, int outlen, int codec, int lev, char *prm, int b); + +unsigned char *codcomps( unsigned char *in, unsigned n, unsigned char *out, int outsize, int codec, int lev, char *prm, int mdelta); +unsigned char *coddecomps(unsigned char *in, unsigned n, unsigned char *out, int outlen, int codec, int lev, char *prm, int mdelta); + +unsigned char *codcompz( unsigned char *in, unsigned n, unsigned char *out, int outsize, int codec, int lev, char *prm, int mdelta); +unsigned char *coddecompz(unsigned char *in, unsigned n, unsigned char *out, int outlen, int codec, int lev, char *prm, int mdelta); + +char *codver(int codec, char *v, char *s); +void *_valloc(size_t size, int a); +void _vfree(void *p, size_t size); + +typedef unsigned char *(*CODCOMP)( unsigned char *_in, unsigned _n, unsigned char *out, int outsize, int codec, int lev, char *prm, int b); +typedef unsigned char *(*CODDECOMP)(unsigned char *in, unsigned _n, unsigned char *_out, int outlen, int codec, int lev, char *prm, int b); + + #ifdef __cplusplus +} + #endif diff --git a/src/ext/for/sse_neon.h b/src/ext/for/sse_neon.h new file mode 100755 index 00000000000..1ed3aca88db --- /dev/null +++ b/src/ext/for/sse_neon.h @@ -0,0 +1,355 @@ +/** + Copyright (C) powturbo 2013-2021 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// Intel SSE to ARM NEON optimized for maximum speed (and compatibility gcc/clang) with possible minor changes to the source code + +#ifndef _SSE_NEON_H_ +#define _SSE_NEON_H_ +#include "conf.h" + +#ifdef __ARM_NEON //------------------------------------------------------------------------------------------------------------------ +#include +#define __m128i uint32x4_t // int32x4_t can also be used +#define __m128 float32x4_t + +//#define USE_MACROS +#define uint8x16_to_8x8x2(_u_) ((uint8x8x2_t) { vget_low_u8(_u_), vget_high_u8(_u_) }) + + #ifdef USE_MACROS //---------------------------- Set : _mm_set_epi/_mm_set1_epi ---------------------------------------------------------- +#define _mm_set_epi8(u15,u14,u13,u12,\ + u11,u10, u9, u8,\ + u7,u6,u5,u4,\ + u3,u2,u1,u0) ({ uint8_t __attribute__((aligned(16))) _u[16] = { u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15 }; (uint32x4_t)vld1q_u8( _u);}) +#define _mm_set_epi16( u7,u6,u5,u4,\ + u3,u2,u1,u0) ({ uint16_t __attribute__((aligned(16))) _u[ 8] = { u0,u1,u2,u3,u4,u5,u6,u7 }; (uint32x4_t)vld1q_u16(_u);}) +//#define _mm_set_epi32( u3,u2,u1,u0) ({ uint32_t __attribute__((aligned(16))) _u[ 4] = { u0,u1,u2,u3 }; vld1q_u32(_u);}) +//#define _mm_set_epi64x( u1,u0) ({ uint64_t __attribute__((aligned(16))) _u[ 2] = { u0,u1 }; (uint32x4_t)vld1q_u64(_u);}) +#define _mm_set_epi32(u3, u2, u1, u0) vcombine_u32(vcreate_u32((uint64_t)u1 << 32 | u0), vcreate_u32((uint64_t)u3 << 32 | u2)) +#define _mm_set_epi64x(u1, u0) (__m128i)vcombine_u64(vcreate_u64(u0), vcreate_u64(u1)) + + #else +static ALWAYS_INLINE __m128i _mm_set_epi8( uint8_t u15, uint8_t u14, uint8_t u13, uint8_t u12, uint8_t u11, uint8_t u10, uint8_t u9, uint8_t u8, + uint8_t u7, uint8_t u6, uint8_t u5, uint8_t u4, + uint8_t u3, uint8_t u2, uint8_t u1, uint8_t u0) { + uint8_t __attribute__((aligned(16))) u[16] = { u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15 }; return (uint32x4_t)vld1q_u8( u); } +static ALWAYS_INLINE __m128i _mm_set_epi16( uint16_t u7, uint16_t u6, uint16_t u5, uint16_t u4, + uint16_t u3, uint16_t u2, uint16_t u1, uint16_t u0) { uint16_t __attribute__((aligned(16))) u[ 8] = { u0,u1,u2,u3,u4,u5,u6,u7 }; return (uint32x4_t)vld1q_u16(u); } +static ALWAYS_INLINE __m128i _mm_set_epi32( uint32_t u3, uint32_t u2, uint32_t u1, uint32_t u0) { uint32_t __attribute__((aligned(16))) u[ 4] = { u0,u1,u2,u3 }; return vld1q_u32(u); } +static ALWAYS_INLINE __m128i _mm_set_epi64x( uint64_t u1, uint64_t u0) { uint64_t __attribute__((aligned(16))) u[ 2] = { u0,u1 }; return (uint32x4_t)vld1q_u64(u); } + #endif + +#define _mm_setr_epi16(u7,u6,u5,u4,u3,u2,u1,u0) _mm_set_epi16( u0,u1,u2,u3,u4,u5,u6,u7) +#define _mm_setr_epi32(u3,u2,u1,u0) _mm_set_epi32( u0,u1,u2,u3) +#define _mm_setr_epi64x(u1,u0) _mm_set_epi64x(u0,u0) + +#define _mm_set1_epi8( _u8_ ) (__m128i)vdupq_n_u8( _u8_ ) +#define _mm_set1_epi16( _u16_) (__m128i)vdupq_n_u16(_u16_) +#define _mm_set1_epi32( _u32_) vdupq_n_u32(_u32_) +#define _mm_set1_epi64x(_u64_) (__m128i)vdupq_n_u64(_u64_) +#define _mm_setzero_si128() vdupq_n_u32( 0 ) + +#define _mm_cvtss_f32(_u_) vgetq_lane_f32((float32x4_t)(_u_), 0) +#define _mm_setzero_ps() (__m128)vdupq_n_f32(0) +#define _mm_set1_ps(_f32_) (__m128)vdupq_n_f32(_f32_) +//---------------------------------------------- Arithmetic ----------------------------------------------------------------------- +#define _mm_add_epi8( _u_,_v_) (__m128i)vaddq_u8((uint8x16_t)(_u_), (uint8x16_t)(_v_)) +#define _mm_add_epi16( _u_,_v_) (__m128i)vaddq_u16((uint16x8_t)(_u_), (uint16x8_t)(_v_)) +#define _mm_add_epi32( _u_,_v_) vaddq_u32( _u_, _v_ ) +#define _mm_sub_epi8( _u_,_v_) (__m128i)vsubq_s8( ( int8x16_t)(_u_), ( int8x16_t)(_v_)) +#define _mm_sub_epi16( _u_,_v_) (__m128i)vsubq_u16((uint16x8_t)(_u_), (uint16x8_t)(_v_)) +#define _mm_sub_epi32( _u_,_v_) (__m128i)vsubq_u32((uint32x4_t)(_u_), (uint32x4_t)(_v_)) +#define _mm_subs_epu8( _u_,_v_) (__m128i)vqsubq_u8((uint8x16_t)(_u_), (uint8x16_t)(_v_)) + +#define _mm_mullo_epi16(_u_,_v_) (__m128i)vmulq_s16(( int16x8_t)(_u_), ( int16x8_t)(_v_)) +#define _mm_mullo_epi32(_u_,_v_) (__m128i)vmulq_s32(( int32x4_t)(_u_), ( int32x4_t)(_v_)) +#define mm_mullo_epu32(_u_,_v_) vmulq_u32(_u_,_v_) + +#define _mm_mulhi_epi16s(_u_,_v_) (__m128i)vqdmulhq_s16(( int16x8_t)(_u_), ( int16x8_t)(_v_)) //only for small values?? +static ALWAYS_INLINE __m128i _mm_mulhi_epi16(__m128i u, __m128i v) { + int32x4_t lo = vmull_s16(vget_low_s16( (int16x8_t)(u)), vget_low_s16( (int16x8_t)(v))); + int32x4_t hi = vmull_s16(vget_high_s16((int16x8_t)(u)), vget_high_s16((int16x8_t)(v))); + uint16x8x2_t a = vuzpq_u16((uint16x8_t)(lo), (uint16x8_t)(hi)); + return (__m128i)(vreinterpretq_s32_u16(a.val[1])); +} +#define _mm_mul_epu32( _u_,_v_) (__m128i)vmull_u32(vget_low_u32(_u_),vget_low_u32(_v_)) +#define _mm_adds_epu16( _u_,_v_) (__m128i)vqaddq_u16((uint16x8_t)(_u_),(uint16x8_t)(_v_)) +static ALWAYS_INLINE __m128i _mm_madd_epi16(__m128i u, __m128i v) { + int32x4_t mlo = vmull_s16(vget_low_s16( (int16x8_t)u), vget_low_s16( (int16x8_t)v)), + mhi = vmull_s16(vget_high_s16((int16x8_t)u), vget_high_s16((int16x8_t)v)); + int32x2_t alo = vpadd_s32(vget_low_s32(mlo), vget_high_s32(mlo)), + ahi = vpadd_s32(vget_low_s32(mhi), vget_high_s32(mhi)); + return (__m128i)vcombine_s32(alo, ahi); +} +//---------------------------------------------- Special math functions ----------------------------------------------------------- +#define _mm_min_epu8( _u_,_v_) (__m128i)vminq_u8( (uint8x16_t)(_u_), (uint8x16_t)(_v_)) +#define _mm_min_epu16( _u_,_v_) (__m128i)vminq_u16((uint16x8_t)(_u_), (uint16x8_t)(_v_)) +#define _mm_min_epi16( _u_,_v_) (__m128i)vminq_s16(( int16x8_t)(_u_), ( int16x8_t)(_v_)) +//---------------------------------------------- Logical -------------------------------------------------------------------------- +#define mm_testnz_epu32(_u_) vmaxvq_u32(_u_) //vaddvq_u32(_u_) +#define mm_testnz_epu8( _u_) vmaxv_u8(_u_) +#define _mm_or_si128( _u_,_v_) (__m128i)vorrq_u32( (uint32x4_t)(_u_), (uint32x4_t)(_v_)) +#define _mm_and_si128( _u_,_v_) (__m128i)vandq_u32( (uint32x4_t)(_u_), (uint32x4_t)(_v_)) +#define _mm_xor_si128( _u_,_v_) (__m128i)veorq_u32( (uint32x4_t)(_u_), (uint32x4_t)(_v_)) +//---------------------------------------------- Shift ---------------------------------------------------------------------------- +#define mm_slli_epi8( _u_,_c_) (_c_)<1?(_u_):((_c_)> 7?(__m128i)vdupq_n_u8( 0):(__m128i)vshlq_n_u8( (uint8x16_t)(_u_), (_c_))) // parameter c MUST be a constant / vshlq_n_u8: __constrange(0-(N-1)) +#define mm_slli_epi16( _u_,_c_) (_c_)<1?(_u_):((_c_)>15?(__m128i)vdupq_n_u16(0):(__m128i)vshlq_n_u16((uint16x8_t)(_u_), (_c_))) +#define mm_slli_epi32( _u_,_c_) (_c_)<1?(_u_):((_c_)>31?(__m128i)vdupq_n_u32(0):(__m128i)vshlq_n_u32((uint32x4_t)(_u_), (_c_))) +#define mm_slli_epi64( _u_,_c_) (_c_)<1?(_u_):((_c_)>63?(__m128i)vdupq_n_u64(0):(__m128i)vshlq_n_u64((uint64x2_t)(_u_), (_c_))) +#define _mm_slli_si128( _u_,_c_) (_c_)<1?(_u_):((_c_)>15?(__m128i)vdupq_n_u8( 0):(__m128i)vextq_u8(vdupq_n_u8(0), (uint8x16_t)(_u_), 16-(_c_) ))// vextq_u8: __constrange(0-15) + +#define mm_srli_epi8( _u_,_c_) (_c_)<1?(_u_):((_c_)> 7?(__m128i)vdupq_n_u8( 0):(__m128i)vshrq_n_u8( (uint8x16_t)(_u_), (_c_))) // vshrq_n: __constrange(1-N) +#define mm_srli_epi16( _u_,_c_) (_c_)<1?(_u_):((_c_)>15?(__m128i)vdupq_n_u16(0):(__m128i)vshrq_n_u16((uint16x8_t)(_u_), (_c_))) +#define mm_srli_epi32( _u_,_c_) (_c_)<1?(_u_):((_c_)>31?(__m128i)vdupq_n_u32(0):(__m128i)vshrq_n_u32((uint32x4_t)(_u_), (_c_))) +#define mm_srli_epi64( _u_,_c_) (_c_)<1?(_u_):((_c_)>63?(__m128i)vdupq_n_u64(0):(__m128i)vshlq_n_u64((uint64x2_t)(_u_), (_c_)))) +#define _mm_srli_si128( _u_,_c_) (_c_)<1?(_u_):((_c_)>15?(__m128i)vdupq_n_u8(0):(__m128i)vextq_u8((uint8x16_t)(_u_), vdupq_n_u8(0), (_c_) )) // vextq_u8: __constrange(0-15) + +#define mm_srai_epi8( _u_,_c_) (_c_)<1?(_u_):(__m128i)vshrq_n_s8( (int8x16_t)(_u_), (_c_)) // c <= 8 (vshrq_n:1-N) +#define mm_srai_epi16( _u_,_c_) (_c_)<1?(_u_):(__m128i)vshrq_n_s16((int16x8_t)(_u_), (_c_)) // c <= 16 +#define mm_srai_epi32( _u_,_c_) (_c_)<1?(_u_):(__m128i)vshrq_n_s32((int32x4_t)(_u_), (_c_)) // c <= 32 +#define mm_srai_epi64( _u_,_c_) (_c_)<1?(_u_):(__m128i)vshrq_n_s64((int64x2_t)(_u_), (_c_))) // c <= 64 + +#define _mm_slli_epi8( _u_,_m_) (__m128i)vshlq_u8( (uint8x16_t)(_u_), vdupq_n_s8( (_m_))) // parameter c integer constant/variable +#define _mm_slli_epi16( _u_,_m_) (__m128i)vshlq_u16((uint16x8_t)(_u_), vdupq_n_s16( (_m_))) +#define _mm_slli_epi32( _u_,_m_) (__m128i)vshlq_u32((uint32x4_t)(_u_), vdupq_n_s32( (_m_))) +#define _mm_slli_epi64( _u_,_m_) (__m128i)vshlq_u64((uint64x2_t)(_u_), vdupq_n_s64( (_m_))) + +#define _mm_srli_epi8( _u_,_m_) (__m128i)vshlq_u8( (uint8x16_t)(_u_), vdupq_n_s8( -(_m_))) +#define _mm_srli_epi16( _u_,_m_) (__m128i)vshlq_u16((uint16x8_t)(_u_), vdupq_n_s16(-(_m_))) +#define _mm_srli_epi32( _u_,_m_) (__m128i)vshlq_u32((uint32x4_t)(_u_), vdupq_n_s32(-(_m_))) +#define _mm_srli_epi64( _u_,_m_) (__m128i)vshlq_u64((uint64x2_t)(_u_), vdupq_n_s64(-(_m_))) + +#define _mm_srai_epi8( _u_,_m_) (__m128i)vshlq_s8( (int8x16_t)(_u_), vdupq_n_s8( -(_m_))) +#define _mm_srai_epi16( _u_,_m_) (__m128i)vshlq_s16((int16x8_t)(_u_), vdupq_n_s16(-(_m_))) +#define _mm_srai_epi32( _u_,_m_) (__m128i)vshlq_s32((int32x4_t)(_u_), vdupq_n_s32(-(_m_))) +#define _mm_srai_epi64( _u_,_m_) (__m128i)vshlq_s64((int64x2_t)(_u_), vdupq_n_s64(-(_m_))) + +#define _mm_sll_epi8( _u_,_v_) (__m128i)vshlq_s8( (int8x16_t)(_u_), (int8x16_t)(_v_)) //_v_:all lanes equal +#define _mm_sll_epi16( _u_,_v_) (__m128i)vshlq_s16( (int16x8_t)(_u_), (int16x8_t)(_v_)) +#define _mm_sll_epi32( _u_,_v_) (__m128i)vshlq_s32( (int32x4_t)(_u_), (int32x4_t)(_v_)) +#define _mm_sll_epi64( _u_,_v_) (__m128i)vshlq_s64( (int64x2_t)(_u_), (int64x2_t)(_v_)) + +#define _mm_srl_epi8( _u_,_v_) (__m128i)vshrq_s8( (int8x16_t)(_u_), (int8x16_t)(_v_)) +#define _mm_srl_epi16( _u_,_v_) (__m128i)vshrq_s16( (int16x8_t)(_u_), (int16x8_t)(_v_)) +#define _mm_srl_epi32( _u_,_v_) (__m128i)vshrq_s32( (int32x4_t)(_u_), (int32x4_t)(_v_)) +#define _mm_srl_epi64( _u_,_v_) (__m128i)vshrq_s64( (int64x2_t)(_u_), (int64x2_t)(_v_)) + +#define _mm_sllv_epi32( _u_,_v_) (__m128i)vshlq_u32((uint32x4_t)(_u_), (uint32x4_t)(_v_)) //variable shift +#define _mm_srlv_epi32( _u_,_v_) (__m128i)vshlq_u32((uint32x4_t)(_u_), vnegq_s32((int32x4_t)(_v_))) +//---------------------------------------------- Compare --------- true/false->1/0 (all bits set) --------------------------------- +#define _mm_cmpeq_epi8( _u_,_v_) (__m128i)vceqq_s8( ( int8x16_t)(_u_), ( int8x16_t)(_v_)) +#define _mm_cmpeq_epi16( _u_,_v_) (__m128i)vceqq_s16(( int16x8_t)(_u_), ( int16x8_t)(_v_)) +#define _mm_cmpeq_epi32( _u_,_v_) (__m128i)vceqq_s32(( int32x4_t)(_u_), ( int32x4_t)(_v_)) + +#define _mm_cmpgt_epi8( _u_,_v_) (__m128i)vcgtq_s8( ( int8x16_t)(_u_), ( int8x16_t)(_v_)) +#define _mm_cmpgt_epi16( _u_,_v_) (__m128i)vcgtq_s16(( int16x8_t)(_u_), ( int16x8_t)(_v_)) +#define _mm_cmpgt_epi32( _u_,_v_) (__m128i)vcgtq_s32(( int32x4_t)(_u_), ( int32x4_t)(_v_)) + +#define _mm_cmpgt_epu16( _u_,_v_) (__m128i)vcgtq_u16((uint16x8_t)(_u_), (uint16x8_t)(_v_)) +#define mm_cmpgt_epu32( _u_,_v_) (__m128i)vcgtq_u32( _u_, _v_) +//---------------------------------------------- Load ----------------------------------------------------------------------------- +#define _mm_loadl_epi64( _u64p_) (__m128i)vcombine_s32(vld1_s32((int32_t const *)(_u64p_)), vcreate_s32(0)) +#define mm_loadu_epi64p(_u64p_,_u_) (__m128i)vld1q_lane_u64((uint64_t *)(_u64p_), (uint64x2_t)(_u_), 0) +#define _mm_loadu_si128( _ip_) vld1q_u32(_ip_) +#define _mm_load_si128( _ip_) vld1q_u32(_ip_) + +#define _mm_load_ps( _ip_) (__m128)vld1q_f32((float32_t *)(_ip_)) +#define _mm_loadu_ps( _ip_) (__m128)vld1q_f32((float32_t *)(_ip_)) +#define _mm_load1_ps( _ip_) (__m128)vld1q_dup_f32((float32_t *)(_p_)) +#define _mm_loadl_pi(_u_,_ip_) (__m128)vcombine_f32((float32x2_t)vld1_f32((float32_t *)(_ip)), (float32x2_t)vget_high_f32(_u_)) +#define _mm_loadh_pi(_u_,_ip_) (__m128)vcombine_f32((float32x2_t)vget_low_f32(_u_), (float32x2_t)vld1_f32((const float *)(_ip_))) +//---------------------------------------------- Store ---------------------------------------------------------------------------- +#define _mm_storel_epi64(_ip_,_u_) vst1q_lane_u64((uint64_t *)(_ip_), (uint64x2_t)(_u_), 0) +#define _mm_storeu_si128(_ip_,_u_) vst1q_u32((__m128i *)(_ip_), _u_) + +#define _mm_store_ps( _ip_,_u_) vst1q_f32( (float32_t *)(_ip_), (float32x4_t)(_u_)) +#define _mm_storeu_ps( _ip_,_u_) vst1q_f32( (float32_t *)(_ip_), (float32x4_t)(_u_)) +#define _mm_store_ss( _ip_,_u_) vst1q_lane_f32((float32_t *)(_ip_), (float32x4_t)(_u_), 0) +//---------------------------------------------- Convert -------------------------------------------------------------------------- +#define mm_cvtsi64_si128p(_u64p_,_u_) mm_loadu_epi64p(_u64p_,_u_) +#define _mm_cvtsi64_si128(_u_) (__m128i)vdupq_n_u64(_u_) //vld1q_s64(_u_) +//---------------------------------------------- Reverse bits/bytes --------------------------------------------------------------- +#define mm_rbit_epi8(_v_) (__m128i)vrbitq_u8( (uint8x16_t)(_v_)) // reverse bits +#define mm_rev_epi16(_v_) vrev16q_u8((uint8x16_t)(_v_)) // reverse bytes +#define mm_rev_epi32(_v_) vrev32q_u8((uint8x16_t)(_v_)) +#define mm_rev_epi64(_v_) vrev64q_u8((uint8x16_t)(_v_)) +//--------------------------------------------- Insert/extract -------------------------------------------------------------------- +#define mm_extract_epi32x(_u_,_u32_,_id_) vst1q_lane_u32((uint32_t *)&(_u32_), _u_, _id_) +#define _mm_extract_epi64x(_u_,_u64_,_id_) vst1q_lane_u64((uint64_t *)&(_u64_), (uint64x2_t)(_u_), _id_) + +#define _mm_extract_epi8( _u_, _id_) vgetq_lane_u8( (uint8x16_t)(_u_), _id_) +#define _mm_extract_epi16(_u_, _id_) vgetq_lane_u16(_u_, _id_) +#define _mm_extract_epi32(_u_, _id_) vgetq_lane_u32(_u_, _id_) +#define mm_extract_epu32(_u_, _id_) vgetq_lane_u32(_u_, _id_) +#define _mm_cvtsi128_si32(_u_) vgetq_lane_u32((uint32x4_t)(_u_),0) +#define _mm_cvtsi128_si64(_u_) vgetq_lane_u64((uint64x2_t)(_u_),0) + +#define _mm_insert_epu32p(_u_,_u32p_,_id_) vsetq_lane_u32(_u32p_, _u_, _id_) +#define mm_insert_epi32p(_u_,_u32p_,_id_) vld1q_lane_u32(_u32p_, (uint32x4_t)(_u_), _id_) +#define _mm_cvtsi32_si128(_x_) (__m128i)vsetq_lane_s32(_x_, vdupq_n_s32(0), 0) + +#define _mm_blendv_epi8(_u_,_v_,_m_) vbslq_u32(_m_,_v_,_u_) +//---------------------------------------------- Miscellaneous -------------------------------------------------------------------- +#define _mm_alignr_epi8(_u_,_v_,_m_) (__m128i)vextq_u8( (uint8x16_t)(_v_), (uint8x16_t)(_u_), _m_) +#define _mm_packs_epi16( _u_,_v_) (__m128i)vcombine_s8( vqmovn_s16((int16x8_t)(_u_)), vqmovn_s16((int16x8_t)(_v_))) +#define _mm_packs_epi32( _u_,_v_) (__m128i)vcombine_s16(vqmovn_s32((int32x4_t)(_u_)), vqmovn_s32((int32x4_t)(_v_))) + +#define _mm_packs_epu16( _u_,_v_) (__m128i)vcombine_u8((uint16x8_t)(_u_), (uint16x8_t)(_v_)) +#define _mm_packus_epi16( _u_,_v_) (__m128i)vcombine_u8(vqmovun_s16((int16x8_t)(_u_)), vqmovun_s16((int16x8_t)(_v_))) + +static ALWAYS_INLINE uint16_t _mm_movemask_epi8(__m128i v) { + const uint8x16_t __attribute__ ((aligned (16))) m = {1, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7, 1, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7}; + uint8x16_t mv = (uint8x16_t)vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(vandq_u8(vcltq_s8((int8x16_t)v, vdupq_n_s8(0)), m)))); + return vgetq_lane_u8(mv, 8) << 8 | vgetq_lane_u8(mv, 0); +} +//-------- Neon movemask ------ All lanes must be 0 or -1 (=0xff, 0xffff or 0xffffffff) + #ifdef __aarch64__ +static ALWAYS_INLINE uint8_t mm_movemask_epi8s(uint8x8_t sv) { const uint8x8_t m = { 1, 1<<1, 1<<2, 1<<3, 1<<4, 1<< 5, 1<< 6, 1<<7 }; return vaddv_u8( vand_u8( sv, m)); } // short only ARM +//static ALWAYS_INLINE uint16_t mm_movemask_epu16(uint32x4_t v) { const uint16x8_t m = { 1, 1<<2, 1<<4, 1<<6, 1<<8, 1<<10, 1<<12, 1<<14}; return vaddvq_u16(vandq_u16((uint16x8_t)v, m)); } +static ALWAYS_INLINE uint16_t mm_movemask_epu16(__m128i v) { const uint16x8_t m = { 1, 1<<1, 1<<2, 1<<3, 1<<4, 1<< 5, 1<< 6, 1<<7 }; return vaddvq_u16(vandq_u16((uint16x8_t)v, m)); } +static ALWAYS_INLINE uint32_t mm_movemask_epu32(__m128i v) { const uint32x4_t m = { 1, 1<<1, 1<<2, 1<<3 }; return vaddvq_u32(vandq_u32((uint32x4_t)v, m)); } +static ALWAYS_INLINE uint64_t mm_movemask_epu64(__m128i v) { const uint64x2_t m = { 1, 1<<1 }; return vaddvq_u64(vandq_u64((uint64x2_t)v, m)); } + #else +static ALWAYS_INLINE uint32_t mm_movemask_epu32(uint32x4_t v) { const uint32x4_t mask = {1,2,4,8}, av = vandq_u32(v, mask), xv = vextq_u32(av, av, 2), ov = vorrq_u32(av, xv); return vgetq_lane_u32(vorrq_u32(ov, vextq_u32(ov, ov, 3)), 0); } + #endif +// --------------------------------------------- Swizzle : _mm_shuffle_epi8 / _mm_shuffle_epi32 / Pack/Unpack ----------------------------------------- +#define _MM_SHUFFLE(_u3_,_u2_,_u1_,_u0_) ((_u3_) << 6 | (_u2_) << 4 | (_u1_) << 2 | (_u0_)) + +#define _mm_shuffle_epi8(_u_, _v_) (__m128i)vqtbl1q_u8((uint8x16_t)(_u_), (uint8x16_t)(_v_)) + #if defined(__aarch64__) +#define mm_shuffle_nnnn_epi32(_u_,_m_) (__m128i)vdupq_laneq_u32(_u_, _m_) + #else +#define mm_shuffle_nnnn_epi32(_u_,_m_) (__m128i)vdupq_n_u32(vgetq_lane_u32(_u_, _m_) + #endif + + #ifdef USE_MACROS +#define mm_shuffle_2031_epi32(_u_) ({ uint32x4_t _zv = (uint32x4_t)vrev64q_u32(_u_); uint32x2x2_t _zv = vtrn_u32(vget_low_u32(_zv), vget_high_u32(_zv)); vcombine_u32(_zv.val[0], _zv.val[1]);}) +#define mm_shuffle_3120_epi32(_u_) ({ uint32x4_t _zv = _u_; _zv = vtrn_u32(vget_low_u32(_zv), vget_high_u32(_zv)); vcombine_u32(_zv.val[0], _zv.val[1]);}) + #else +static ALWAYS_INLINE __m128i mm_shuffle_2031_epi32(__m128i v) { uint32x4_t a = (uint32x4_t)vrev64q_u32(v); uint32x2x2_t z = vtrn_u32(vget_low_u32(a), vget_high_u32(a)); return vcombine_u32(z.val[0], z.val[1]);} +static ALWAYS_INLINE __m128i mm_shuffle_3120_epi32(__m128i v) { uint32x2x2_t z = vtrn_u32(vget_low_u32(v), vget_high_u32(v)); return vcombine_u32(z.val[0], z.val[1]);} + #endif + + #if defined(USE_MACROS) || defined(__clang__) +#define _mm_shuffle_epi32(_u_, _m_) ({ const uint32x4_t _av =_u_;\ + uint32x4_t _v = vmovq_n_u32(vgetq_lane_u32(_av, (_m_) & 0x3));\ + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 2) & 0x3), _v, 1);\ + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 4) & 0x3), _v, 2);\ + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 6) & 0x3), _v, 3); _v;\ + }) +#define _mm_shuffle_epi32s(_u_, _m_) _mm_set_epi32(vgetq_lane_u32(_u_, ((_m_) ) & 0x3),\ + vgetq_lane_u32(_u_, ((_m_) >> 2) & 0x3),\ + vgetq_lane_u32(_u_, ((_m_) >> 4) & 0x3),\ + vgetq_lane_u32(_u_, ((_m_) >> 6) & 0x3)) + #else +static ALWAYS_INLINE __m128i _mm_shuffle_epi32(__m128i _u_, const unsigned _m_) { const uint32x4_t _av =_u_; + uint32x4_t _v = vmovq_n_u32(vgetq_lane_u32(_av, (_m_) & 0x3)); + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 2) & 0x3), _v, 1); + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 4) & 0x3), _v, 2); + _v = vsetq_lane_u32(vgetq_lane_u32(_av, ((_m_) >> 6) & 0x3), _v, 3); + return _v; +} +static ALWAYS_INLINE __m128i _mm_shuffle_epi32s(__m128i _u_, const unsigned _m_) { + return _mm_set_epi32(vgetq_lane_u32(_u_, ((_m_) ) & 0x3), + vgetq_lane_u32(_u_, ((_m_) >> 2) & 0x3), + vgetq_lane_u32(_u_, ((_m_) >> 4) & 0x3), + vgetq_lane_u32(_u_, ((_m_) >> 6) & 0x3)); +} + #endif + #ifdef USE_MACROS +#define _mm_unpacklo_epi8( _u_,_v_) ({ uint8x8x2_t _zv = vzip_u8 ( vget_low_u8( (uint8x16_t)(_u_)), vget_low_u8 ((uint8x16_t)(_v_))); (uint32x4_t)vcombine_u8( _zv.val[0], _zv.val[1]);}) +#define _mm_unpacklo_epi16(_u_,_v_) ({ uint16x4x2_t _zv = vzip_u16( vget_low_u16((uint16x8_t)(_u_)), vget_low_u16((uint16x8_t)(_v_))); (uint32x4_t)vcombine_u16(_zv.val[0], _zv.val[1]);}) +#define _mm_unpacklo_epi32(_u_,_v_) ({ uint32x2x2_t _zv = vzip_u32( vget_low_u32( _u_ ), vget_low_u32( _v_ )); vcombine_u32(_zv.val[0], _zv.val[1]);}) +#define _mm_unpacklo_epi64(_u_,_v_) (uint32x4_t)vcombine_u64(vget_low_u64((uint64x2_t)(_u_)), vget_low_u64((uint64x2_t)(_v_))) + +#define _mm_unpackhi_epi8( _u_,_v_) ({ uint8x8x2_t _zv = vzip_u8 (vget_high_u8( (uint8x16_t)(_u_)), vget_high_u8( (uint8x16_t)(_v_))); (uint32x4_t)vcombine_u8( _zv.val[0], _zv.val[1]);}) +#define _mm_unpackhi_epi16(_u_,_v_) ({ uint16x4x2_t _zv = vzip_u16(vget_high_u16((uint16x8_t)(_u_)), vget_high_u16((uint16x8_t)(_v_))); (uint32x4_t)vcombine_u16(_zv.val[0], _zv.val[1]);}) +#define _mm_unpackhi_epi32(_u_,_v_) ({ uint32x2x2_t _zv = vzip_u32(vget_high_u32( _u_ ), vget_high_u32( _v_ )); vcombine_u32(_zv.val[0], _zv.val[1]);}) +#define _mm_unpackhi_epi64(_u_,_v_) (uint32x4_t)vcombine_u64(vget_high_u64((uint64x2_t)(_u_)), vget_high_u64((uint64x2_t)(_v_))) + #else +static ALWAYS_INLINE __m128i _mm_unpacklo_epi8( __m128i _u_, __m128i _v_) { uint8x8x2_t _zv = vzip_u8 ( vget_low_u8( (uint8x16_t)(_u_)), vget_low_u8 ((uint8x16_t)(_v_))); return (uint32x4_t)vcombine_u8( _zv.val[0], _zv.val[1]);} +static ALWAYS_INLINE __m128i _mm_unpacklo_epi16(__m128i _u_, __m128i _v_) { uint16x4x2_t _zv = vzip_u16( vget_low_u16((uint16x8_t)(_u_)), vget_low_u16((uint16x8_t)(_v_))); return (uint32x4_t)vcombine_u16(_zv.val[0], _zv.val[1]);} +static ALWAYS_INLINE __m128i _mm_unpacklo_epi32(__m128i _u_, __m128i _v_) { uint32x2x2_t _zv = vzip_u32( vget_low_u32( _u_ ), vget_low_u32( _v_ )); return vcombine_u32(_zv.val[0], _zv.val[1]);} +static ALWAYS_INLINE __m128i _mm_unpacklo_epi64(__m128i _u_, __m128i _v_) { return (uint32x4_t)vcombine_u64(vget_low_u64((uint64x2_t)(_u_)), vget_low_u64((uint64x2_t)(_v_))); } + +static ALWAYS_INLINE __m128i _mm_unpackhi_epi8( __m128i _u_, __m128i _v_) { uint8x8x2_t _zv = vzip_u8 (vget_high_u8( (uint8x16_t)(_u_)), vget_high_u8( (uint8x16_t)(_v_))); return (uint32x4_t)vcombine_u8( _zv.val[0], _zv.val[1]); } +static ALWAYS_INLINE __m128i _mm_unpackhi_epi16(__m128i _u_, __m128i _v_) { uint16x4x2_t _zv = vzip_u16(vget_high_u16((uint16x8_t)(_u_)), vget_high_u16((uint16x8_t)(_v_))); return (uint32x4_t)vcombine_u16(_zv.val[0], _zv.val[1]); } +static ALWAYS_INLINE __m128i _mm_unpackhi_epi32(__m128i _u_, __m128i _v_) { uint32x2x2_t _zv = vzip_u32(vget_high_u32( _u_ ), vget_high_u32( _v_ )); return vcombine_u32(_zv.val[0], _zv.val[1]); } +static ALWAYS_INLINE __m128i _mm_unpackhi_epi64(__m128i _u_, __m128i _v_) { return (uint32x4_t)vcombine_u64(vget_high_u64((uint64x2_t)(_u_)), vget_high_u64((uint64x2_t)(_v_))); } + #endif + +#else //----------------- intel SSE2/SSSE3 ( wraper functions compatible with intel/arm; permits to have one source code version for arm+intel) -------------- +#define mm_movemask_epu32(_u_) _mm_movemask_ps(_mm_castsi128_ps(_u_)) +#define mm_movemask_epu16(_u_) _mm_movemask_epi8(_u_) +#define mm_loadu_epi64p( _u64p_,_u_) _u_ = _mm_cvtsi64_si128(ctou64(_u64p_)) + +#define mm_extract_epu32( _u_, _id_) _mm_extract_epi32(_u_, _id_) +#define mm_extract_epi32x(_u_,_u32_, _id_) _u32_ = _mm_extract_epi32(_u_, _id_) +#define mm_extract_epi64x(_u_,_u64_, _id_) _u64_ = _mm_extract_epi64(_u_, _id_) +#define mm_insert_epi32p( _u_,_u32p_,_c_) _mm_insert_epi32( _u_,ctou32(_u32p_),_c_) + +#define mm_mullo_epu32( _u_,_v_) _mm_mullo_epi32(_u_,_v_) +#define mm_cvtsi64_si128p(_u64p_,_u_) _u_ = _mm_cvtsi64_si128(ctou64(_u64p_)) + +#define mm_cmplt_epu32( _u_, _v_) _mm_cmplt_epi32(_mm_xor_si128(_u_, cv80000000), _mm_xor_si128(_v_, cv80000000)) //__m128i cv80000000 = _mm_set1_epi32(0x80000000); must be declared +#define mm_cmpgt_epu32( _u_, _v_) _mm_cmpgt_epi32(_mm_xor_si128(_u_, cv80000000), _mm_xor_si128(_v_, cv80000000)) +#define _mm_cmplt_epu32( _u_, _v_) _mm_cmplt_epi32(_mm_xor_si128(_u_, _mm_set1_epi32(0x80000000)), _mm_xor_si128(_v_, _mm_set1_epi32(0x80000000))) +#define _mm_cmpgt_epu32( _u_, _v_) _mm_cmpgt_epi32(_mm_xor_si128(_u_, _mm_set1_epi32(0x80000000)), _mm_xor_si128(_v_, _mm_set1_epi32(0x80000000))) + +#define mm_shuffle_nnnn_epi32(_u_, _n_) _mm_shuffle_epi32(_u_, _MM_SHUFFLE(_n_,_n_,_n_,_n_)) +#define mm_shuffle_2031_epi32(_u_) _mm_shuffle_epi32(_u_, _MM_SHUFFLE(2,0,3,1)) +#define mm_shuffle_3120_epi32(_u_) _mm_shuffle_epi32(_u_, _MM_SHUFFLE(3,1,2,0)) + +#define _mm_slli_epi8(_u_, _m_ ) _mm_and_si128(_mm_set1_epi8(0xff << _m_), _mm_slli_epi32(_u_, _m_ )) +#define _mm_srli_epi8(_u_, _m_ ) _mm_and_si128(_mm_set1_epi8(0xff >> _m_), _mm_srli_epi32(_u_, _m_ )) + +#define mm_slli_epi8( _u_,_c_) _mm_slli_epi8( _u_,_c_) // parameter c MUST be a constant for compatibilty with the arm functions above +#define mm_slli_epi16( _u_,_c_) _mm_slli_epi16(_u_,_c_) +#define mm_slli_epi32( _u_,_c_) _mm_slli_epi32(_u_,_c_) +#define mm_slli_epi64( _u_,_c_) _mm_slli_epi64(_u_,_c_) + +#define mm_srli_epi8( _u_,_c_) _mm_srli_epi8( _u_,_c_) +#define mm_srli_epi16( _u_,_c_) _mm_srli_epi16(_u_,_c_) +#define mm_srli_epi32( _u_,_c_) _mm_srli_epi32(_u_,_c_) +#define mm_srli_epi64( _u_,_c_) _mm_srli_epi64(_u_,_c_) + +#define mm_srai_epi8( _u_,_c_) _mm_srai_epi8( _u_,_c_) +#define mm_srai_epi16( _u_,_c_) _mm_srai_epi16(_u_,_c_) +#define mm_srai_epi32( _u_,_c_) _mm_srai_epi32(_u_,_c_) +#define mm_srai_epi64( _u_,_c_) _mm_srai_epi64(_u_,_c_) + + #ifdef __SSSE3__ +static ALWAYS_INLINE __m128i mm_rbit_epi8(__m128i v) { // reverse bits in bytes + __m128i fv = _mm_set_epi8(15, 7,11, 3,13, 5, 9, 1,14, 6,10, 2,12, 4, 8, 0), cv0f_8 = _mm_set1_epi8(0xf); + __m128i lv = _mm_shuffle_epi8(fv,_mm_and_si128( v, cv0f_8)); + __m128i hv = _mm_shuffle_epi8(fv,_mm_and_si128( mm_srli_epi64(v, 4), cv0f_8)); + return _mm_or_si128( mm_slli_epi64(lv,4), hv); +} + +static ALWAYS_INLINE __m128i mm_rev_epi16(__m128i v) { return _mm_shuffle_epi8(v, _mm_set_epi8(14,15,12,13,10,11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1)); } // reverse vector bytes in uint??_t +static ALWAYS_INLINE __m128i mm_rev_epi32(__m128i v) { return _mm_shuffle_epi8(v, _mm_set_epi8(12,13,14,15, 8, 9,10,11, 4, 5, 6, 7, 0, 1, 2, 3)); } +static ALWAYS_INLINE __m128i mm_rev_epi64(__m128i v) { return _mm_shuffle_epi8(v, _mm_set_epi8( 8, 9,10,11,12,13,14,15, 0, 1, 2, 3, 4, 5, 6, 7)); } +static ALWAYS_INLINE __m128i mm_rev_si128(__m128i v) { return _mm_shuffle_epi8(v, _mm_set_epi8( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15)); } + #endif + #endif +#endif + diff --git a/src/ext/for/time_.h b/src/ext/for/time_.h new file mode 100644 index 00000000000..4f32b264261 --- /dev/null +++ b/src/ext/for/time_.h @@ -0,0 +1,252 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// time_.h : parameter free high precision time/benchmark functions +#include +#include + + #ifdef _WIN32 +#include + #ifndef sleep +#define sleep(n) Sleep((n) * 1000) + #endif + +typedef unsigned __int64 uint64_t; +typedef unsigned __int64 tm_t; + + #else +#include +#include +#define Sleep(ms) usleep((ms) * 1000) + +typedef struct timespec tm_t; + #endif + +#if defined (__i386__) || defined( __x86_64__ ) + #ifdef _MSC_VER +#include // __rdtsc + #else +#include + #endif + + #ifdef __corei7__ +#define RDTSC_INI(_c_) do { unsigned _cl, _ch; \ + __asm volatile ("couid\n\t" \ + "rdtsc\n\t" \ + "mov %%edx, %0\n" \ + "mov %%eax, %1\n": "=r" (_ch), "=r" (_cl):: \ + "%rax", "%rbx", "%rcx", "%rdx"); \ + _c_ = (uint64_t)_ch << 32 | _cl; \ +} while(0) + +#define RDTSC(_c_) do { unsigned _cl, _ch; \ + __asm volatile("rdtscp\n" \ + "mov %%edx, %0\n" \ + "mov %%eax, %1\n" \ + "cpuid\n\t": "=r" (_ch), "=r" (_cl):: "%rax",\ + "%rbx", "%rcx", "%rdx");\ + _c_ = (uint64_t)_ch << 32 | _cl;\ +} while(0) + #else +#define RDTSC(_c_) do { unsigned _cl, _ch;\ + __asm volatile ("cpuid \n"\ + "rdtsc"\ + : "=a"(_cl), "=d"(_ch)\ + : "a"(0)\ + : "%ebx", "%ecx");\ + _c_ = (uint64_t)_ch << 32 | _cl;\ +} while(0) +#define RDTSC_INI(_c_) RDTSC(_c_) + #endif +#else +#define RDTSC_INI(_c_) +#define RDTSC(_c_) +#endif + +#define tmrdtscini() ({ uint64_t _c; __asm volatile("" ::: "memory"); RDTSC_INI(_c); _c; }) +#define tmrdtsc() ({ uint64_t _c; RDTSC(_c); _c; }) + +#ifndef TM_F +#define TM_F 1.0 // TM_F=4 -> MI/s +#endif + + #ifdef RDTSC_ON +#define tminit() tmrdtscini() +#define tmtime() tmrdtsc() +#define TM_T CLOCKS_PER_SEC +static double TMBS(unsigned l, double t) { double dt = t, dl = l; return t/l; } +#define TM_C 1000 + + #else +#define TM_C 1 +static double TMBS(unsigned l, double t) { return (l/t)/1000000.0; } + + #ifdef _WIN32 +static LARGE_INTEGER tps; +static tm_t tmtime(void) { + LARGE_INTEGER tm; + tm_t t; + QueryPerformanceCounter(&tm); + return tm.QuadPart; +} + +static tm_t tminit() { tm_t t0,ts; QueryPerformanceFrequency(&tps); t0 = tmtime(); while((ts = tmtime())==t0) {}; return ts; } +static double tmdiff(tm_t start, tm_t stop) { return (double)(stop - start)/tps.QuadPart; } +static int tmiszero(tm_t t) { return !t; } + #else + #ifdef __APPLE__ +#include + #ifndef MAC_OS_X_VERSION_10_12 +#define MAC_OS_X_VERSION_10_12 101200 + #endif +#define CIVETWEB_APPLE_HAVE_CLOCK_GETTIME (defined(__APPLE__) && defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12) + #if !(CIVETWEB_APPLE_HAVE_CLOCK_GETTIME) +#include +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 0 +int clock_gettime(int /*clk_id*/, struct timespec* t) { + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) return rv; + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; +} + #endif + #endif +static tm_t tmtime() { struct timespec tm; clock_gettime(CLOCK_MONOTONIC, &tm); return tm; } +static double tmdiff(tm_t start, tm_t stop) { return (stop.tv_sec - start.tv_sec) + (double)(stop.tv_nsec - start.tv_nsec)/1e9f; } +static tm_t tminit() { tm_t t0 = tmtime(),t; while(!tmdiff(t = tmtime(),t0)) {}; return t; } +static int tmiszero(tm_t t) { return !(t.tv_sec|t.tv_nsec); } + #endif +#endif + +//---------------------------------------- bench ---------------------------------------------------------------------- +// for each a function call is repeated until exceding tm_tx seconds. +// A run duration is always tm_tx seconds +// The number of runs can be set with the program options -I and -J (specify -I15 -J15 for more precision) + +// sleep after each 8 runs to avoid cpu trottling. +#define TMSLEEP do { tm_T = tmtime(); if(tmiszero(tm_0)) tm_0 = tm_T; else if(tmdiff(tm_0, tm_T) > tm_TX) { if(tm_verbose) { printf("S \b\b");fflush(stdout); } sleep(tm_slp); tm_0=tmtime();} } while(0) + +// benchmark loop +#define TMBEG(_tm_Reps_) { unsigned _tm_r,_tm_c = 0,_tm_R,_tm_Rx = _tm_Reps_,_tm_Rn = _tm_Reps_; double _tm_t;\ + for(tm_rm = tm_rep, tm_tm = DBL_MAX, _tm_R = 0; _tm_R < _tm_Rn; _tm_R++) { tm_t _tm_t0 = tminit(); /*for each run*/\ + for(_tm_r = 0;_tm_r < tm_rm;) { /*repeat tm_rm times */ + +#define TMEND(_len_) \ + _tm_r++; if(tm_tm == DBL_MAX && (_tm_t = tmdiff(_tm_t0, tmtime())) > tm_tx) break;\ + }\ + /*1st run: break the loop after tm_tx=1 sec, calculate a new repeats 'tm_rm' to avoid calling time() after each function call*/\ + /*other runs: break the loop only after 'tm_rm' repeats */ \ + _tm_t = tmdiff(_tm_t0, tmtime());\ + /*set min time, recalculte repeats tm_rm based on tm_tx, recalculte number of runs based on tm_TX*/\ + if(_tm_t < tm_tm) { if(tm_tm == DBL_MAX) { tm_rm = _tm_r; _tm_Rn = tm_TX/_tm_t; _tm_Rn = _tm_Rn<_tm_Rx?_tm_Rn:_tm_Rx; /*printf("[%d,%d] ", tm_rm, _tm_Rn);*/ } tm_tm = _tm_t; _tm_c++; }\ + else if(_tm_t > tm_tm*1.15) TMSLEEP;/*force sleep at 15% divergence*/\ + if(tm_verbose) { printf("%8.2f %2d_%.2d\b\b\b\b\b\b\b\b\b\b\b\b\b\b",TMBS(_len_, tm_tm/tm_rm),_tm_R+1,_tm_c),fflush(stdout); }\ + if((_tm_R & 7)==7) sleep(tm_slp); /*pause 20 secs after each 8 runs to avoid cpu trottling*/\ + }\ +} + +static unsigned tm_rep = 1<<30, tm_Rep = 3, tm_Rep2 = 3, tm_rm, tm_RepMin = 1, tm_slp = 20, tm_verbose = 2; +static tm_t tm_0, tm_T; +static double tm_tm, tm_tx = 1, tm_TX = 60; + +static void tm_init(int _tm_Rep, int _tm_verbose) { tm_verbose = _tm_verbose; if(_tm_Rep) tm_Rep = _tm_Rep; } + +#define TMBENCH(_name_, _func_, _len_) do { if(tm_verbose>1) printf("%s ", _name_?_name_:#_func_);\ + TMBEG(tm_Rep) _func_; TMEND(_len_); \ + double dm = tm_tm, dr = tm_rm; if(tm_verbose) printf("%8.2f \b\b\b\b\b", TMBS(_len_, dm*TM_C/dr) );\ +} while(0) + +// second TMBENCH. Example: use TMBENCH for encoding and TMBENCH2 for decoding +#define TMBENCH2(_name_, _func_, _len_) do { \ + TMBEG(tm_Rep2) _func_; TMEND(_len_);\ + double dm = tm_tm, dr = tm_rm; if(tm_verbose) printf("%8.2f \b\b\b\b\b", TMBS(_len_, dm*TM_C/dr) );\ + if(tm_verbose>1) printf("%s ", _name_?_name_:#_func_);\ +} while(0) + +// Check +#define TMBENCHT(_name_,_func_, _len_, _res_) do { \ + TMBEG(tm_Rep) \ + if(_func_ != _res_) { printf("ERROR: %lld != %lld", (long long)_func_, (long long)_res_ ); exit(0); };\ + TMEND(_len_);\ + if(tm_verbose) printf("%8.2f \b\b\b\b\b", TMBS(_len_,(double)tm_tm*TM_C/(double)tm_rm) );\ + if(tm_verbose) printf("%s ", _name_?_name_:#_func_ );\ +} while(0) +//---------------------------------------------------------------------------------------------------------------------------------- +#define Kb (1u<<10) +#define Mb (1u<<20) +#define Gb (1u<<30) +#define KB 1000 +#define MB 1000000 +#define GB 1000000000 + +static unsigned argtoi(char *s, unsigned def) { + char *p; + unsigned n = strtol(s, &p, 10),f = 1; + switch(*p) { + case 'K': f = KB; break; + case 'M': f = MB; break; + case 'G': f = GB; break; + case 'k': f = Kb; break; + case 'm': f = Mb; break; + case 'g': f = Gb; break; + case 'B': return n; break; + case 'b': def = 0; + default: if(!def) return n>=32?0xffffffffu:(1u << n); f = def; + } + return n*f; +} +static uint64_t argtol(char *s) { + char *p; + uint64_t n = strtol(s, &p, 10),f=1; + switch(*p) { + case 'K': f = KB; break; + case 'M': f = MB; break; + case 'G': f = GB; break; + case 'k': f = Kb; break; + case 'm': f = Mb; break; + case 'g': f = Gb; break; + case 'B': return n; break; + case 'b': return 1u << n; + default: f = MB; + } + return n*f; +} + +static uint64_t argtot(char *s) { + char *p; + uint64_t n = strtol(s, &p, 10),f=1; + switch(*p) { + case 'h': f = 3600000; break; + case 'm': f = 60000; break; + case 's': f = 1000; break; + case 'M': f = 1; break; + default: f = 1000; + } + return n*f; +} + +static void memrcpy(unsigned char *out, unsigned char *in, unsigned n) { int i; for(i = 0; i < n; i++) out[i] = ~in[i]; } + diff --git a/src/ext/for/transpose.c b/src/ext/for/transpose.c new file mode 100644 index 00000000000..2db63cc565e --- /dev/null +++ b/src/ext/for/transpose.c @@ -0,0 +1,1223 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// Nibble/Byte transpose +#ifndef ESIZE //---------------------------------- Functions ----------------------------------------------------------------- +#include + #ifdef __AVX2__ +#include + #elif defined(__AVX__) +#include + #elif defined(__SSE4_1__) +#include + #elif defined(__SSSE3__) + #ifdef __powerpc64__ +#define __SSE__ 1 +#define __SSE2__ 1 +#define __SSE3__ 1 +#define NO_WARN_X86_INTRINSICS 1 + #endif +#include + #elif defined(__SSE2__) +#include + #elif defined(__ARM_NEON) +#include +#include "sse_neon.h" + #endif + +#pragma warning( disable : 4005) + +#include "conf.h" +#include "transpose.h" + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif + +#define powof2(n) !((n)&((n)-1)) + +#define TPENC tpenc +#define TPDEC tpdec + +#define ESIZE 3 +#define STRIDE ESIZE +#include "transpose.c" +#undef ESIZE + +#define ESIZE 16 +#define STRIDE ESIZE +#include "transpose.c" +#undef ESIZE + +#define ESIZE 2 + +#define STRIDE ESIZE +#define LD128(_ip_) _mm_loadu_si128((__m128i *)(_ip_)) +#define ST128(_op_,_v_) _mm_storeu_si128((__m128i *)(_op_),_v_) +#define TPENC128V tpenc128v +#define TPDEC128V tpdec128v + +#define LD256(ip) _mm256_loadu_si256(ip) +#define ST256(op,v) _mm256_storeu_si256(op,v) +#define TPENC256V tpenc256v +#define TPDEC256V tpdec256v +#include "transpose.c" +#undef STRIDE + +#define STRIDE 4 +#define TPENC128V tp4enc128v +#define TPDEC128V tp4dec128v +#define TPENC256V tp4enc256v +#define TPDEC256V tp4dec256v +#include "transpose.c" +#undef ESIZE + +#define ESIZE 4 + +#define STRIDE ESIZE +#define TPENC128V tpenc128v +#define TPDEC128V tpdec128v +#define TPENC256V tpenc256v +#define TPDEC256V tpdec256v +#include "transpose.c" +#undef STRIDE + +#define STRIDE 8 +#define TPENC128V tp4enc128v +#define TPDEC128V tp4dec128v +#define TPENC256V tp4enc256v +#define TPDEC256V tp4dec256v +#include "transpose.c" +#undef ESIZE +#undef STRIDE + +#define ESIZE 8 + +#define STRIDE ESIZE +#define TPENC128V tpenc128v +#define TPDEC128V tpdec128v +#define TPENC256V tpenc256v +#define TPDEC256V tpdec256v +#include "transpose.c" +#undef STRIDE + +#define STRIDE 16 +#define TPENC128V tp4enc128v +#define TPDEC128V tp4dec128v +#define TPENC256V tp4enc256v +#define TPDEC256V tp4dec256v +#include "transpose.c" + +#if !defined(SSE2_ON) && !defined(AVX2_ON) +//--------------------- CPU detection ------------------------------------------- + #if _MSC_VER >=1300 +#include + #elif defined (__INTEL_COMPILER) +#include + #endif + +static unsigned _cpuisa; + #if defined(__ARM_NEON) || defined(__SSE__) || defined(__powerpc64__) +//--------------------- CPU detection ------------------------------------------- + #if defined(__i386__) || defined(__x86_64__) + #if _MSC_VER >=1300 +#include + #elif defined (__INTEL_COMPILER) +#include + #endif + +static inline void cpuid(int reg[4], int id) { + #if defined (_MSC_VER) //|| defined (__INTEL_COMPILER) + __cpuidex(reg, id, 0); + #elif defined(__i386__) || defined(__x86_64__) + __asm("cpuid" : "=a"(reg[0]),"=b"(reg[1]),"=c"(reg[2]),"=d"(reg[3]) : "a"(id),"c"(0) : ); + #endif +} + +static inline uint64_t xgetbv (int ctr) { + #if(defined _MSC_VER && (_MSC_FULL_VER >= 160040219) || defined __INTEL_COMPILER) + return _xgetbv(ctr); + #elif defined(__i386__) || defined(__x86_64__) + unsigned a, d; + __asm("xgetbv" : "=a"(a),"=d"(d) : "c"(ctr) : ); + return (uint64_t)d << 32 | a; + #else + unsigned a=0, d=0; + return (uint64_t)d << 32 | a; + #endif +} + #endif + +#define AVX512F 0x001 +#define AVX512DQ 0x002 +#define AVX512IFMA 0x004 +#define AVX512PF 0x008 +#define AVX512ER 0x010 +#define AVX512CD 0x020 +#define AVX512BW 0x040 +#define AVX512VL 0x080 +#define AVX512VNNI 0x100 +#define AVX512VBMI 0x200 +#define AVX512VBMI2 0x400 + +#define IS_SSE 0x10 +#define IS_SSE2 0x20 +#define IS_SSE3 0x30 +#define IS_SSSE3 0x32 +#define IS_POWER9 0x34 // powerpc +#define IS_NEON 0x38 // arm neon +#define IS_SSE41 0x40 +#define IS_SSE41x 0x41 //+popcount +#define IS_SSE42 0x42 +#define IS_AVX 0x50 +#define IS_AVX2 0x60 +#define IS_AVX512 0x800 + +unsigned cpuisa(void) { + int c[4] = {0}; + if(_cpuisa) return _cpuisa; + _cpuisa++; + #if defined(__i386__) || defined(__x86_64__) + cpuid(c, 0); + if(c[0]) { + cpuid(c, 1); + //family = ((c >> 8) & 0xf) + ((c >> 20) & 0xff) + //model = ((c >> 4) & 0xf) + ((c >> 12) & 0xf0) + if( c[3] & (1 << 25)) { _cpuisa = IS_SSE; + if( c[3] & (1 << 26)) { _cpuisa = IS_SSE2; + if( c[2] & (1 << 0)) { _cpuisa = IS_SSE3; + // _cpuisa = IS_SSE3SLOW; // Atom SSSE3 slow + if( c[2] & (1 << 9)) { _cpuisa = IS_SSSE3; + if( c[2] & (1 << 19)) { _cpuisa = IS_SSE41; + if( c[2] & (1 << 23)) { _cpuisa = IS_SSE41x; // +popcount + if( c[2] & (1 << 20)) { _cpuisa = IS_SSE42; // SSE4.2 + if((c[2] & (1 << 28)) && + (c[2] & (1 << 27)) && // OSXSAVE + (c[2] & (1 << 26)) && // XSAVE + (xgetbv(0) & 6)==6) { _cpuisa = IS_AVX; // AVX + if(c[2]& (1 << 3)) _cpuisa |= 1; // +FMA3 + if(c[2]& (1 << 16)) _cpuisa |= 2; // +FMA4 + if(c[2]& (1 << 25)) _cpuisa |= 4; // +AES + cpuid(c, 7); + if(c[1] & (1 << 5)) { _cpuisa = IS_AVX2; + if(c[1] & (1 << 16)) { + cpuid(c, 0xd); + if((c[0] & 0x60)==0x60) { _cpuisa = IS_AVX512; + cpuid(c, 7); + if(c[1] & (1<<16)) _cpuisa |= AVX512F; + if(c[1] & (1<<17)) _cpuisa |= AVX512DQ; + if(c[1] & (1<<21)) _cpuisa |= AVX512IFMA; + if(c[1] & (1<<26)) _cpuisa |= AVX512PF; + if(c[1] & (1<<27)) _cpuisa |= AVX512ER; + if(c[1] & (1<<28)) _cpuisa |= AVX512CD; + if(c[1] & (1<<30)) _cpuisa |= AVX512BW; + if(c[1] & (1<<31)) _cpuisa |= AVX512VL; + if(c[2] & (1<< 1)) _cpuisa |= AVX512VBMI; + if(c[2] & (1<<11)) _cpuisa |= AVX512VNNI; + if(c[2] & (1<< 6)) _cpuisa |= AVX512VBMI2; + }}} + }}}}}}}}} + #elif defined(__powerpc64__) + _cpuisa = IS_POWER9; // power9 + #elif defined(__ARM_NEON) + _cpuisa = IS_NEON; // ARM_NEON + #endif + return _cpuisa; +} + #endif + +unsigned cpuini(unsigned cpuisa) { if(cpuisa) _cpuisa = cpuisa; return _cpuisa; } + +char *cpustr(unsigned cpuisa) { + if(!cpuisa) cpuisa = _cpuisa; + #if defined(__i386__) || defined(__x86_64__) + if(cpuisa >= IS_AVX512) { + if(cpuisa & AVX512VBMI2) return "avx512vbmi2"; + if(cpuisa & AVX512VBMI) return "avx512vbmi"; + if(cpuisa & AVX512VNNI) return "avx512vnni"; + if(cpuisa & AVX512VL) return "avx512vl"; + if(cpuisa & AVX512BW) return "avx512bw"; + if(cpuisa & AVX512CD) return "avx512cd"; + if(cpuisa & AVX512ER) return "avx512er"; + if(cpuisa & AVX512PF) return "avx512pf"; + if(cpuisa & AVX512IFMA) return "avx512ifma"; + if(cpuisa & AVX512DQ) return "avx512dq"; + if(cpuisa & AVX512F) return "avx512f"; + return "avx512"; + } + else if(cpuisa >= IS_AVX2) return "avx2"; + else if(cpuisa >= IS_AVX) + switch(cpuisa&0xf) { + case 1: return "avx+fma3"; + case 2: return "avx+fma4"; + case 4: return "avx+aes"; + case 5: return "avx+fma3+aes"; + default:return "avx"; + } + else if(cpuisa >= IS_SSE42) return "sse4.2"; + else if(cpuisa >= IS_SSE41x) return "sse4.1+popcnt"; + else if(cpuisa >= IS_SSE41) return "sse4.1"; + else if(cpuisa >= IS_SSSE3) return "ssse3"; + else if(cpuisa >= IS_SSE3) return "sse3"; + else if(cpuisa >= IS_SSE2) return "sse2"; + else if(cpuisa >= IS_SSE) return "sse"; + #elif defined(__powerpc64__) + if(cpuisa >= IS_POWER9) return "power9"; + #elif defined(__ARM_NEON) + if(cpuisa >= IS_NEON) return "arm_neon"; + #endif + return "none"; +} + +//--------------------------------------------------------------------------------- +typedef void (*TPFUNC)( unsigned char *in, unsigned n, unsigned char *out); + + // 0 1 2 3 4 5 6 7 8 9 16 +static TPFUNC _tpe[] = { 0, 0, tpenc2, tpenc3, tpenc4, 0, 0, 0, tpenc8, 0, 0, 0, 0, 0, 0, 0, tpenc16 }; +static TPFUNC _tpd[] = { 0, 0, tpdec2, tpdec3, tpdec4, 0, 0, 0, tpdec8, 0, 0, 0, 0, 0, 0, 0, tpdec16 }; + +static TPFUNC _tp4e[] = { 0, 0, tpenc2, tpenc3, tpenc4, 0, 0, 0, tpenc8, 0, 0, 0, 0, 0, 0, 0, tpenc16 }; // Nibble +static TPFUNC _tp4d[] = { 0, 0, tpdec2, tpdec3, tpdec4, 0, 0, 0, tpdec8, 0, 0, 0, 0, 0, 0, 0, tpdec16 }; + +static int tpset; + +void tpini(int id) { + int i; + if(tpset) return; + tpset++; + i = id?id:cpuisa(); + #if defined(__i386__) || defined(__x86_64__) + if(i >= IS_AVX2) { + _tpe[2] = tpenc128v2; _tpd[2] = tpdec256v2; _tp4e[2] = tp4enc256v2; _tp4d[2] = tp4dec256v2; //SSE encoding _tpe[2] is faster + _tpe[4] = tpenc128v4; _tpd[4] = tpdec256v4; _tp4e[4] = tp4enc256v4; _tp4d[4] = tp4dec256v4; //SSE encoding _tpe[4] is faster + _tpe[8] = tpenc256v8; _tpd[8] = tpdec256v8; _tp4e[8] = tp4enc256v8; _tp4d[8] = tp4dec256v8; + } else + #endif + #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_NEON) || defined(__powerpc64__) + if(i >= IS_SSE2) { + _tpe[2] = tpenc128v2; _tpd[2] = tpdec128v2; _tp4e[2] = tp4enc128v2; _tp4d[2] = tp4dec128v2; + _tpe[4] = tpenc128v4; _tpd[4] = tpdec128v4; _tp4e[4] = tp4enc128v4; _tp4d[4] = tp4dec128v4; + _tpe[8] = tpenc128v8; _tpd[8] = tpdec128v8; _tp4e[8] = tp4enc128v8; _tp4d[8] = tp4dec128v8; + if(i == 35) _tpd[8] = tpdec8; // ARM NEON scalar is faster + } + #endif +} + +void tpenc(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + TPFUNC f; + if(!tpset) tpini(0); + if(esize <= 16 && (f = _tpe[esize])) f(in,n,out); + else { + unsigned i, stride=n/esize; + unsigned char *op,*ip; + for(ip = in,op = out; ip < in+stride*esize; op++) + for(i = 0; i < esize; i++) + op[i*stride] = *ip++; + for(op = out + esize*stride; ip < in+n;) + *op++ = *ip++; + } +} + +void tpdec(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + TPFUNC f; + if(!tpset) tpini(0); + if(esize <= 16 && (f = _tpd[esize])) f(in,n,out); + else { + unsigned i, stride = n/esize; + unsigned char *op,*ip; + for(op = out,ip = in; op < out+stride*esize; ip++) + for(i = 0; i < esize; i++) + *op++ = ip[i*stride]; + for(ip = in+esize*stride; op < out+n;) + *op++ = *ip++; + } +} + +#define E for(e = esize-1; e >= 0; e--) +//#define E for(e=0; e < esize; e++) +#define ODX2 (_x + _y * x) * esize + e +void tp2denc(unsigned char *in, unsigned x, unsigned y, unsigned char *out, unsigned esize) { + unsigned _x,_y; uint8_t *op = out, *ip = in; int e; + for( _x = 0; _x < x; _x++) + for(_y = 0; _y < y; _y++) E + op[ODX2] = *ip++; + +} + +void tp2ddec(unsigned char *in, unsigned x, unsigned y, unsigned char *out, unsigned esize) { + unsigned _x,_y; uint8_t *op=out,*ip=in; int e; + for( _x = 0; _x < x; _x++) + for(_y = 0; _y < y; _y++) E +*op++ = ip[ODX2]; +} + +#define ODX3 (_x + _y * x + _z * y * x) * esize + e +void tp3denc(unsigned char *in, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize) { + unsigned _x,_y,_z; uint8_t *op = out, *ip=in; int e; + for( _x = 0; _x < x; _x++) + for( _y = 0; _y < y; _y++) + for(_z = 0; _z < z; _z++) E + op[ODX3] = *ip++; +} + +void tp3ddec(unsigned char *in, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize) { + unsigned _x,_y,_z; uint8_t *op=out,*ip=in; int e; + for(_x = 0; _x < x; ++_x) + for(_y = 0; _y < y; ++_y) + for(_z = 0; _z < z; ++_z) E + *op++= ip[ODX3]; +} + +#define ODX4 (_w + _x * w + _y * x * w + _z * x * y * w) * esize + e +void tp4denc(unsigned char *in, unsigned w, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize) { + unsigned _w,_x,_y,_z; uint8_t *op = out, *ip=in; int e; + for( _w = 0; _w < w; _w++) + for( _x = 0; _x < x; _x++) + for( _y = 0; _y < y; _y++) + for(_z = 0; _z < z; _z++) E + op[ODX4] = *ip++; +} + +void tp4ddec(unsigned char *in, unsigned w, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize) { + unsigned _w,_x,_y,_z; uint8_t *op=out,*ip=in; int e; + for( _w = 0; _w < w; _w++) + for( _x = 0; _x < x; ++_x) + for( _y = 0; _y < y; ++_y) + for(_z = 0; _z < z; ++_z) E + *op++= ip[ODX4]; +} + +void tp4enc(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + TPFUNC f; + if(!tpset) tpini(0); + if(esize <= 16 && (f = _tp4e[esize])) f(in,n,out); + else tpenc(in,n,out,esize); +} + +void tp4dec(unsigned char *in, unsigned n, unsigned char *out, unsigned esize) { + TPFUNC f; + if(!tpset) tpini(0); + if(esize <= 16 && (f = _tp4d[esize])) f(in,n,out); + else tpdec(in,n,out,esize); +} + #endif +#else //---------------------------------------------- Templates -------------------------------------------------------------- + +#define SIE(p,i) (p+=stride) //faster on ARM +//#define SIE(_p_,_i_) (_p_+ _i_*stride) + +#define SID(p,i) (p+=stride) +//#define SID(_p_,_i_) (_p_+ _i_*stride) + +#if !defined(SSE2_ON) && !defined(AVX2_ON) //--------------------------------------- plain ------------------------------------------------------------------- + + #if STRIDE == ESIZE +void TEMPLATE2(TPENC, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned char *op,*ip,*e; + unsigned stride = n/STRIDE; + + #if powof2(ESIZE) + e = in+(n&~(ESIZE-1)); + #else + e = in+stride*ESIZE; + #endif + + for(ip = in,op = out; ip < e; op++, ip+=ESIZE) { unsigned char *p = op; + p[0] = ip[ 0]; + *SIE(p, 1) = ip[ 1]; + #if ESIZE > 2 + *SIE(p, 2) = ip[ 2]; + #if ESIZE > 3 + *SIE(p, 3) = ip[ 3]; + #if ESIZE > 4 + uint32_t u = ctou32(p); + *SIE(p, 4) = ip[ 4]; + *SIE(p, 5) = ip[ 5]; + *SIE(p, 6) = ip[ 6]; + *SIE(p, 7) = ip[ 7]; + #if ESIZE > 8 + *SIE(p, 8) = ip[ 8]; + *SIE(p, 9) = ip[ 9]; + *SIE(p,10) = ip[10]; + *SIE(p,11) = ip[11]; + *SIE(p,12) = ip[12]; + *SIE(p,13) = ip[13]; + *SIE(p,14) = ip[14]; + *SIE(p,15) = ip[15]; + #endif + #endif + #endif + #endif + } + for(op = out+stride*ESIZE;ip < in+n;) + *op++ = *ip++; +} + +void TEMPLATE2(TPDEC, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned char *op,*ip,*e; + unsigned stride = n/STRIDE; + + #if powof2(ESIZE) + e = out+(n&~(ESIZE-1)); + #else + e = out+stride*ESIZE; + #endif + for(op = out,ip = in; op < e; ip++,op+=ESIZE) { unsigned char *p = ip; + op[ 0] = *p; + op[ 1] = *SID(p,1); + #if ESIZE > 2 + op[ 2] = *SID(p,2); + #if ESIZE > 3 + op[ 3] = *SID(p,3); + #if ESIZE > 4 + op[ 4] = *SID(p,4); + op[ 5] = *SID(p,5); + op[ 6] = *SID(p,6); + op[ 7] = *SID(p,7); + #if ESIZE > 8 + op[ 8] = *SID(p,8); + op[ 9] = *SID(p,9); + op[10] = *SID(p,10); + op[11] = *SID(p,11); + op[12] = *SID(p,12); + op[13] = *SID(p,13); + op[14] = *SID(p,14); + op[15] = *SID(p,15); + #endif + #endif + #endif + #endif + } + for(ip = in+stride*ESIZE; op < out+n; ) + *op++ = *ip++; +} + #endif // STRIDE + +#else + +#if ESIZE == 2 || ESIZE == 4 || ESIZE == 8 + #if defined(__AVX2__) +void TEMPLATE2(TPENC256V, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned v = n&~(ESIZE*32-1); + unsigned stride = v/STRIDE; + unsigned char *op,*ip; + + #if ESIZE == 2 + __m256i sv = _mm256_set_epi8( 15, 13, 11, 9, 7, 5, 3, 1, + 14, 12, 10, 8, 6, 4, 2, 0, + 15, 13, 11, 9, 7, 5, 3, 1, + 14, 12, 10, 8, 6, 4, 2, 0); + __m256i sv0 = _mm256_set_epi8(15, 13, 11, 9, + 7, 5, 3, 1, + 14, 12, 10, 8, + 6, 4, 2, 0, + 15, 13, 11, 9, + 7, 5, 3, 1, + 14, 12, 10, 8, + 6, 4, 2, 0); + __m256i sv1 = _mm256_set_epi8(14, 12, 10, 8, + 6, 4, 2, 0, + 15, 13, 11, 9, + 7, 5, 3, 1, + 14, 12, 10, 8, + 6, 4, 2, 0, + 15, 13, 11, 9, + 7, 5, 3, 1); + #else + __m256i pv = _mm256_set_epi32( 7, 3, 6, 2, 5, 1, 4, 0), + #if ESIZE == 4 + sv0 = _mm256_set_epi8(15, 11, 7, 3, + 13, 9, 5, 1, + 14, 10, 6, 2, + 12, 8, 4, 0, + 15, 11, 7, 3, + 13, 9, 5, 1, + 14, 10, 6, 2, + 12, 8, 4, 0), + sv1= _mm256_set_epi8(13, 9, 5, 1, + 15, 11, 7, 3, + 12, 8, 4, 0, + 14, 10, 6, 2, + 13, 9, 5, 1, + 15, 11, 7, 3, + 12, 8, 4, 0, + 14, 10, 6, 2); + #else + sv = _mm256_set_epi8(15, 7, + 14, 6, + 13, 5, + 12, 4, + 11, 3, + 10, 2, + 9, 1, + 8, 0, + 15, 7, + 14, 6, + 13, 5, + 12, 4, + 11, 3, + 10, 2, + 9, 1, + 8, 0 ), + tv = _mm256_set_epi8(15, 14, 11, 10, 13, 12, 9, 8, + 7, 6, 3, 2, 5, 4, 1, 0, + 15, 14, 11, 10, 13, 12, 9, 8, + 7, 6, 3, 2, 5, 4, 1, 0); + #endif + #endif + + #if STRIDE > ESIZE // ------------------ byte transpose ---------------------------------- + __m256i cl = _mm256_set1_epi8( 0x0f), + ch = _mm256_set1_epi8( 0xf0), + cb = _mm256_set1_epi16(0xff); + #endif + + for(ip = in,op = out; ip != in+v; ip += ESIZE*32, op += ESIZE*32/STRIDE) { + unsigned char *p = op; PREFETCH(ip+ESIZE*192,0); + __m256i iv[ESIZE],ov[ESIZE]; + #if ESIZE == 2 + ov[0] = _mm256_shuffle_epi8(LD256((__m256i *) ip ), sv0); + ov[1] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+32)), sv1); + iv[0] = _mm256_permute4x64_epi64(_mm256_blend_epi32(ov[0], ov[1],0b11001100),_MM_SHUFFLE(3, 1, 2, 0)); + iv[1] = _mm256_blend_epi32(ov[0], ov[1],0b00110011); + iv[1] = _mm256_permute4x64_epi64(_mm256_shuffle_epi32(iv[1],_MM_SHUFFLE(1, 0, 3, 2)),_MM_SHUFFLE(3, 1, 2, 0)); + #elif ESIZE == 4 + iv[0] = _mm256_shuffle_epi8(LD256((__m256i *) ip ), sv0); + iv[1] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+32)), sv1); + iv[2] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+64)), sv0); + iv[3] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+96)), sv1); + + ov[0] = _mm256_blend_epi32(iv[0], iv[1],0b10101010); + ov[1] = _mm256_shuffle_epi32(_mm256_blend_epi32(iv[0], iv[1],0b01010101),_MM_SHUFFLE(2, 3, 0, 1)); + ov[2] = _mm256_blend_epi32(iv[2], iv[3],0b10101010); + ov[3] = _mm256_shuffle_epi32(_mm256_blend_epi32(iv[2], iv[3],0b01010101),_MM_SHUFFLE(2, 3, 0, 1)); + + iv[0] = _mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[0], ov[2]), pv); + iv[1] = _mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[0], ov[2]), pv); + iv[2] = _mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[1], ov[3]), pv); + iv[3] = _mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[1], ov[3]), pv); + #else + ov[0] = _mm256_shuffle_epi8(LD256((__m256i *) ip ), sv); + ov[1] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+32)), sv); + ov[2] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+64)), sv); + ov[3] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+96)), sv); + + iv[0] = _mm256_unpacklo_epi16(ov[0], ov[1]); iv[1] = _mm256_unpackhi_epi16(ov[0], ov[1]); + iv[2] = _mm256_unpacklo_epi16(ov[2], ov[3]); iv[3] = _mm256_unpackhi_epi16(ov[2], ov[3]); + + ov[0] = _mm256_unpacklo_epi32(iv[0], iv[2]); ov[1] = _mm256_unpackhi_epi32(iv[0], iv[2]); + ov[2] = _mm256_unpacklo_epi32(iv[1], iv[3]); ov[3] = _mm256_unpackhi_epi32(iv[1], iv[3]); + + + ov[4] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+128)), sv); + ov[5] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+160)), sv); + ov[6] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+192)), sv); + ov[7] = _mm256_shuffle_epi8(LD256((__m256i *)(ip+224)), sv); + + iv[4] = _mm256_unpacklo_epi16(ov[4], ov[5]); iv[5] = _mm256_unpackhi_epi16(ov[4], ov[5]); + iv[6] = _mm256_unpacklo_epi16(ov[6], ov[7]); iv[7] = _mm256_unpackhi_epi16(ov[6], ov[7]); + + ov[4] = _mm256_unpacklo_epi32(iv[4], iv[6]); ov[5] = _mm256_unpackhi_epi32(iv[4], iv[6]); + ov[6] = _mm256_unpacklo_epi32(iv[5], iv[7]); ov[7] = _mm256_unpackhi_epi32(iv[5], iv[7]); + + iv[0] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[0], ov[4]), pv), tv); + iv[1] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[0], ov[4]), pv), tv); + iv[2] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[1], ov[5]), pv), tv); + iv[3] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[1], ov[5]), pv), tv); + + iv[4] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[2], ov[6]), pv), tv); + iv[5] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[2], ov[6]), pv), tv); + iv[6] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpacklo_epi64(ov[3], ov[7]), pv), tv); + iv[7] = _mm256_shuffle_epi8(_mm256_permutevar8x32_epi32(_mm256_unpackhi_epi64(ov[3], ov[7]), pv), tv); + #endif + + #if STRIDE <= ESIZE + _mm256_storeu_si256((__m256i *) p, iv[0]); + _mm256_storeu_si256((__m256i *)(p+=stride), iv[1]); + #if ESIZE > 2 + _mm256_storeu_si256((__m256i *)(p+=stride), iv[2]); + _mm256_storeu_si256((__m256i *)(p+=stride), iv[3]); + #if ESIZE > 4 + _mm256_storeu_si256((__m256i *)(p+=stride), iv[4]); + _mm256_storeu_si256((__m256i *)(p+=stride), iv[5]); + _mm256_storeu_si256((__m256i *)(p+=stride), iv[6]); + _mm256_storeu_si256((__m256i *)(p+=stride), iv[7]); + #endif + #endif + + #else //---------------------- Nibble Transpose ------------------------ + #define mm256_packus_epi16(a, b) _mm256_permute4x64_epi64(_mm256_packus_epi16(a, b), _MM_SHUFFLE(3, 1, 2, 0)) + #define ST128(_p_,_v_,_i_) _mm_storeu_si128((__m256i *)SIE(_p_,_i_), _mm256_castsi256_si128(_v_)) + #define ST1280(_p_,_v_) _mm_storeu_si128((__m256i *)(_p_), _mm256_castsi256_si128(_v_)) + + ov[0] = _mm256_and_si256(iv[0], cl); ov[0] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = mm256_packus_epi16(ov[0], _mm256_srli_si256( ov[0],2)); + ov[1] = _mm256_srli_epi16(_mm256_and_si256(iv[0], ch),4); ov[1] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = mm256_packus_epi16(ov[1], _mm256_srli_si256( ov[1],2)); + ov[2] = _mm256_and_si256(iv[1], cl); ov[2] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = mm256_packus_epi16(ov[2], _mm256_srli_si256( ov[2],2)); + ov[3] = _mm256_srli_epi16(_mm256_and_si256(iv[1], ch),4); ov[3] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = mm256_packus_epi16(ov[3], _mm256_srli_si256( ov[3],2)); + ST1280(p,ov[0]); ST128(p,ov[1],1); ST128(p,ov[2],2); ST128(p,ov[3],3); + #if ESIZE > 2 + ov[0] = _mm256_and_si256(iv[2], cl); ov[0] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = mm256_packus_epi16(ov[0], _mm256_srli_si256( ov[0],2)); + ov[1] = _mm256_srli_epi16(_mm256_and_si256(iv[2], ch),4); ov[1] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = mm256_packus_epi16(ov[1], _mm256_srli_si256( ov[1],2)); + ov[2] = _mm256_and_si256(iv[3], cl); ov[2] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = mm256_packus_epi16(ov[2], _mm256_srli_si256( ov[2],2)); + ov[3] = _mm256_srli_epi16(_mm256_and_si256(iv[3], ch),4); ov[3] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = mm256_packus_epi16(ov[3], _mm256_srli_si256( ov[3],2)); + ST128(p,ov[0],4); ST128(p,ov[1],5); ST128(p,ov[2],6); ST128(p,ov[3],7); + #if ESIZE > 4 + ov[0] = _mm256_and_si256(iv[4], cl); ov[0] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = mm256_packus_epi16(ov[0], _mm256_srli_si256( ov[0],2)); + ov[1] = _mm256_srli_epi16(_mm256_and_si256(iv[4], ch),4); ov[1] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = mm256_packus_epi16(ov[1], _mm256_srli_si256( ov[1],2)); + ov[2] = _mm256_and_si256(iv[5], cl); ov[2] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = mm256_packus_epi16(ov[2], _mm256_srli_si256( ov[2],2)); + ov[3] = _mm256_srli_epi16(_mm256_and_si256(iv[5], ch),4); ov[3] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = mm256_packus_epi16(ov[3], _mm256_srli_si256( ov[3],2)); + ST128(p,ov[0],8); ST128(p,ov[1],9); ST128(p,ov[2],10); ST128(p,ov[3],11); + + ov[0] = _mm256_and_si256(iv[6], cl); ov[0] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = mm256_packus_epi16(ov[0], _mm256_srli_si256( ov[0],2)); + ov[1] = _mm256_srli_epi16(_mm256_and_si256(iv[6], ch),4); ov[1] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = mm256_packus_epi16(ov[1], _mm256_srli_si256( ov[1],2)); + ov[2] = _mm256_and_si256(iv[7], cl); ov[2] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = mm256_packus_epi16(ov[2], _mm256_srli_si256( ov[2],2)); + ov[3] = _mm256_srli_epi16(_mm256_and_si256(iv[7], ch),4); ov[3] = _mm256_and_si256(_mm256_or_si256(_mm256_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = mm256_packus_epi16(ov[3], _mm256_srli_si256( ov[3],2)); + ST128(p,ov[0],12); ST128(p,ov[1],13); ST128(p,ov[2],14); ST128(p,ov[3],15); + #endif + #endif + #endif + } + TEMPLATE2(tpenc,ESIZE)(in+v, n-v, out+v); +} + +#define NBL0(x,y) ov[x] = _mm256_permute4x64_epi64(_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)(p ))),_MM_SHUFFLE(3, 1, 2, 0));\ + ov[y] = _mm256_permute4x64_epi64(_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)(p+=stride))),_MM_SHUFFLE(3, 1, 2, 0)); + +#define NBL(x,y) ov[x] = _mm256_permute4x64_epi64(_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)(p+=stride))),_MM_SHUFFLE(3, 1, 2, 0));\ + ov[y] = _mm256_permute4x64_epi64(_mm256_castsi128_si256(_mm_loadu_si128((__m128i *)(p+=stride))),_MM_SHUFFLE(3, 1, 2, 0)); + +#define NB(x,y,_iv_) {\ + ov[x] = _mm256_and_si256(_mm256_unpacklo_epi8(ov[x], _mm256_srli_epi16(ov[x],4)), cl);\ + ov[y] = _mm256_and_si256(_mm256_unpacklo_epi8(ov[y], _mm256_srli_epi16(ov[y],4)), cl);\ + _iv_ = _mm256_or_si256(_mm256_slli_epi16(ov[y],4), ov[x]); \ +} + +void TEMPLATE2(TPDEC256V, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned v = n&~(ESIZE*32-1); + unsigned stride = v/STRIDE; + unsigned char *op,*ip; + + #if STRIDE > ESIZE + __m256i cl = _mm256_set1_epi8(0x0f), ch=_mm256_set1_epi8(0xf0), cb = _mm256_set1_epi16(0xff); + #endif + + for(op = out,ip = in; op != out+v; ip += ESIZE*32/STRIDE, op += ESIZE*32) { unsigned char *p = ip; PREFETCH(ip+ESIZE*192,0); + __m256i iv[ESIZE], ov[ESIZE]; + + #if STRIDE > ESIZE + NBL0(0,1); NBL( 2,3); NB(0,1,iv[0]); NB(2,3,iv[1]); + #if ESIZE > 2 + NBL( 0,1); NBL( 2,3); NB(0,1,iv[2]); NB(2,3,iv[3]); + #if ESIZE > 4 + NBL(4,5); NBL( 6,7); NB(4,5,iv[4]); NB(6,7,iv[5]); + NBL(4,5); NBL( 6,7); NB(4,5,iv[6]); NB(6,7,iv[7]); + #endif + #endif + #else + iv[0] = _mm256_loadu_si256((__m256i *) p ); + iv[1] = _mm256_loadu_si256((__m256i *)(p+=stride)); + #if ESIZE > 2 + iv[2] = _mm256_loadu_si256((__m256i *)(p+=stride)); + iv[3] = _mm256_loadu_si256((__m256i *)(p+=stride)); + #if ESIZE > 4 + iv[4] = _mm256_loadu_si256((__m256i *)(p+=stride)); + iv[5] = _mm256_loadu_si256((__m256i *)(p+=stride)); + iv[6] = _mm256_loadu_si256((__m256i *)(p+=stride)); + iv[7] = _mm256_loadu_si256((__m256i *)(p+=stride)); + #endif + #endif + #endif + + #if ESIZE == 2 + ov[0] = _mm256_permute4x64_epi64(iv[0], _MM_SHUFFLE(3, 1, 2, 0)); + ov[1] = _mm256_permute4x64_epi64(iv[1], _MM_SHUFFLE(3, 1, 2, 0)); + _mm256_storeu_si256((__m256i *)op, _mm256_unpacklo_epi8(ov[0], ov[1])); + _mm256_storeu_si256((__m256i *)(op+32), _mm256_unpackhi_epi8(ov[0], ov[1])); + #elif ESIZE == 4 + ov[0] = _mm256_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm256_unpackhi_epi8( iv[0], iv[1]); + ov[2] = _mm256_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm256_unpackhi_epi8( iv[2], iv[3]); + + iv[0] = _mm256_unpacklo_epi16(ov[0], ov[2]); iv[1] = _mm256_unpackhi_epi16(ov[0], ov[2]); + iv[2] = _mm256_unpacklo_epi16(ov[1], ov[3]); iv[3] = _mm256_unpackhi_epi16(ov[1], ov[3]); + + ov[0] = _mm256_permute2x128_si256(iv[0], iv[1], (2 << 4) | 0); + ov[1] = _mm256_permute2x128_si256(iv[2], iv[3], (2 << 4) | 0); + ov[2] = _mm256_permute2x128_si256(iv[0], iv[1], (3 << 4) | 1); + ov[3] = _mm256_permute2x128_si256(iv[2], iv[3], (3 << 4) | 1); + _mm256_storeu_si256((__m256i *) op, ov[0]); + _mm256_storeu_si256((__m256i *)(op+32), ov[1]); + _mm256_storeu_si256((__m256i *)(op+64), ov[2]); + _mm256_storeu_si256((__m256i *)(op+96), ov[3]); + #else + ov[0] = _mm256_unpacklo_epi8(iv[0], iv[1]); ov[1] = _mm256_unpackhi_epi8(iv[0], iv[1]); + ov[2] = _mm256_unpacklo_epi8(iv[2], iv[3]); ov[3] = _mm256_unpackhi_epi8(iv[2], iv[3]); + iv[0] = _mm256_permute4x64_epi64(_mm256_unpacklo_epi16(ov[0], ov[2]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[1] = _mm256_permute4x64_epi64(_mm256_unpackhi_epi16(ov[0], ov[2]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[2] = _mm256_permute4x64_epi64(_mm256_unpacklo_epi16(ov[1], ov[3]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[3] = _mm256_permute4x64_epi64(_mm256_unpackhi_epi16(ov[1], ov[3]), _MM_SHUFFLE(3, 1, 2, 0)); + + ov[4] = _mm256_unpacklo_epi8(iv[4], iv[5]); ov[5] = _mm256_unpackhi_epi8(iv[4], iv[5]); + ov[6] = _mm256_unpacklo_epi8(iv[6], iv[7]); ov[7] = _mm256_unpackhi_epi8(iv[6], iv[7]); + iv[4] = _mm256_permute4x64_epi64(_mm256_unpacklo_epi16(ov[4], ov[6]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[5] = _mm256_permute4x64_epi64(_mm256_unpackhi_epi16(ov[4], ov[6]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[6] = _mm256_permute4x64_epi64(_mm256_unpacklo_epi16(ov[5], ov[7]), _MM_SHUFFLE(3, 1, 2, 0)); + iv[7] = _mm256_permute4x64_epi64(_mm256_unpackhi_epi16(ov[5], ov[7]), _MM_SHUFFLE(3, 1, 2, 0)); + + ov[0] = _mm256_unpacklo_epi32(iv[0], iv[4]); + ov[1] = _mm256_unpacklo_epi32(iv[1], iv[5]); + ov[2] = _mm256_unpacklo_epi32(iv[2], iv[6]); + ov[3] = _mm256_unpacklo_epi32(iv[3], iv[7]); + ov[4] = _mm256_unpackhi_epi32(iv[0], iv[4]); + ov[5] = _mm256_unpackhi_epi32(iv[1], iv[5]); + ov[6] = _mm256_unpackhi_epi32(iv[2], iv[6]); + ov[7] = _mm256_unpackhi_epi32(iv[3], iv[7]); + + ST256((__m256i *) op, ov[0] ); + ST256((__m256i *)(op+ 32), ov[1] ); + ST256((__m256i *)(op+ 64), ov[2] ); + ST256((__m256i *)(op+ 96), ov[3] ); + ST256((__m256i *)(op+128), ov[4] ); + ST256((__m256i *)(op+160), ov[5] ); + ST256((__m256i *)(op+192), ov[6] ); + ST256((__m256i *)(op+224), ov[7] ); + #endif + } + if(n-v) TEMPLATE2(tpdec,ESIZE)(in+v, n-v, out+v); +} + + #elif defined(__SSE3__) || defined(__ARM_NEON) +#define ST(_p_,_v_,_i_) _mm_storeu_si128((__m128i *)SIE(_p_,_i_), _v_) +#define ST0(_p_,_v_) _mm_storeu_si128((__m128i *)(_p_), _v_) + +void TEMPLATE2(TPENC128V, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned v = n&~(ESIZE*32-1); + unsigned stride = v/STRIDE; + unsigned char *op,*ip; + + #if defined(__SSE3__) || defined(__ARM_NEON) + #if ESIZE == 2 + __m128i sv = _mm_set_epi8(15, 13, 11, 9, 7, 5, 3, 1, + 14, 12, 10, 8, 6, 4, 2, 0); + #elif ESIZE == 4 + __m128i sv = _mm_set_epi8(15, 11, 7,3, + 14, 10, 6,2, + 13, 9, 5,1, + 12, 8, 4,0); + #else + __m128i sv = _mm_set_epi8(15, 7, + 14, 6, + 13, 5, + 12, 4, + 11, 3, + 10, 2, + 9, 1, + 8, 0 ); + #endif + #endif + + #if STRIDE > ESIZE + __m128i cl = _mm_set1_epi8(0x0f), ch=_mm_set1_epi8(0xf0), cb = _mm_set1_epi16(0xff); + #endif + + for(ip = in, op = out; ip != in+v; ip+=ESIZE*16,op += ESIZE*16/STRIDE) { unsigned char *p = op; PREFETCH(ip+(ESIZE*16)*ESIZE,0); + __m128i iv[ESIZE],ov[ESIZE]; + #if defined(__SSSE3__) || defined(__ARM_NEON) + #if ESIZE == 2 + #ifdef __ARM_NEON + uint8x16x2_t w = vld2q_u8(ip); + #if STRIDE <= ESIZE + ST0(p,(__m128i)w.val[0]); ST(p,(__m128i)w.val[1],1); + #else + iv[0] = (__m128i)w.val[0]; iv[1] = (__m128i)w.val[1]; + #endif + #else + ov[0] = LD128(ip); ov[0] = _mm_shuffle_epi8(ov[0], sv); + ov[1] = LD128(ip+16); ov[1] = _mm_shuffle_epi8(ov[1], sv); + + iv[0] = _mm_unpacklo_epi64(ov[0], ov[1]); iv[1] = _mm_unpackhi_epi64(ov[0], ov[1]); + #if STRIDE <= ESIZE + ST0(p,iv[0]); ST(p,iv[1],1); + #endif + #endif + + #elif ESIZE == 4 + #ifdef __ARM_NEON + uint8x16x4_t w = vld4q_u8(ip); + #if STRIDE <= ESIZE + ST0(p,(__m128i)w.val[0]); ST(p,(__m128i)w.val[1],1); ST(p,(__m128i)w.val[2],2); ST(p,(__m128i)w.val[3],3); + #else + iv[0] = (__m128i)w.val[0]; iv[1] = (__m128i)w.val[1]; iv[2] = (__m128i)w.val[2]; iv[3] = (__m128i)w.val[3]; + #endif + #else + iv[0] = LD128(ip ); iv[0] = _mm_shuffle_epi8(iv[0], sv); + iv[1] = LD128(ip+16); iv[1] = _mm_shuffle_epi8(iv[1], sv); + iv[2] = LD128(ip+32); iv[2] = _mm_shuffle_epi8(iv[2], sv); + iv[3] = LD128(ip+48); iv[3] = _mm_shuffle_epi8(iv[3], sv); + + ov[0] = _mm_unpacklo_epi32(iv[0], iv[1]); ov[1] = _mm_unpackhi_epi32(iv[0], iv[1]); + ov[2] = _mm_unpacklo_epi32(iv[2], iv[3]); ov[3] = _mm_unpackhi_epi32(iv[2], iv[3]); + + iv[0] = _mm_unpacklo_epi64(ov[0], ov[2]); iv[1] = _mm_unpackhi_epi64(ov[0], ov[2]); + iv[2] = _mm_unpacklo_epi64(ov[1], ov[3]); iv[3] = _mm_unpackhi_epi64(ov[1], ov[3]); + #if STRIDE <= ESIZE + ST0(p,iv[0]); ST(p,iv[1],1); ST(p,iv[2],2); ST(p,iv[3],3); + #endif + #endif + + #elif ESIZE == 8 + #ifdef __ARM_NEON +#define vzipl_u16(_a_,_b_) vzip_u16(vget_low_u16((uint16x8_t)(_a_)), vget_low_u16((uint16x8_t)(_b_))) +#define vziph_u16(_a_,_b_) vzip_u16(vget_high_u16((uint16x8_t)(_a_)), vget_high_u16((uint16x8_t)(_b_))) +//#define VQ + #ifndef VQ + uint16x4x2_t v16[8]; + uint32x2x2_t v32[8]; + #else + uint8x16x2_t v8[4]; + uint16x8x2_t v16[4]; + uint32x4x2_t v32[4]; //uint64x2x2_t v64[4]; + #endif + #ifdef VQ + ov[0] = LD128(ip ); //ov[0] = _mm_shuffle_epi8(ov[0], sv); + ov[1] = LD128(ip+ 16); //ov[1] = _mm_shuffle_epi8(ov[1], sv); + ov[2] = LD128(ip+ 32); //ov[2] = _mm_shuffle_epi8(ov[2], sv); + ov[3] = LD128(ip+ 48); //ov[3] = _mm_shuffle_epi8(ov[3], sv); + ov[4] = LD128(ip+ 64); //ov[4] = _mm_shuffle_epi8(ov[4], sv); + ov[5] = LD128(ip+ 80); //ov[5] = _mm_shuffle_epi8(ov[5], sv); + ov[6] = LD128(ip+ 96); //ov[6] = _mm_shuffle_epi8(ov[6], sv); + ov[7] = LD128(ip+112); //ov[7] = _mm_shuffle_epi8(ov[7], sv); + + v8[0] = vzipq_u8((uint8x16_t)ov[0], (uint8x16_t)ov[1]); + v8[1] = vzipq_u8((uint8x16_t)ov[2], (uint8x16_t)ov[3]); + v8[2] = vzipq_u8((uint8x16_t)ov[4], (uint8x16_t)ov[5]); + v8[3] = vzipq_u8((uint8x16_t)ov[6], (uint8x16_t)ov[7]); + +/* v16[0] = vzipq_u16((uint16x8_t)ov[0], (uint16x8_t)ov[1]); + v16[1] = vzipq_u16((uint16x8_t)ov[2], (uint16x8_t)ov[3]); + v16[2] = vzipq_u16((uint16x8_t)ov[4], (uint16x8_t)ov[5]); + v16[3] = vzipq_u16((uint16x8_t)ov[6], (uint16x8_t)ov[7]);*/ + v16[0] = vzipq_u16(vreinterpretq_u16_u8( v8[0].val[0]), vreinterpretq_u16_u8(v8[1].val[0])); + v16[1] = vzipq_u16(vreinterpretq_u16_u8( v8[0].val[1]), vreinterpretq_u16_u8(v8[1].val[1])); + v16[2] = vzipq_u16(vreinterpretq_u16_u8( v8[2].val[0]), vreinterpretq_u16_u8(v8[3].val[0])); + v16[3] = vzipq_u16(vreinterpretq_u16_u8( v8[2].val[1]), vreinterpretq_u16_u8(v8[3].val[1])); + + v32[0] = vzipq_u32(vreinterpretq_u32_u16(v16[0].val[0]), vreinterpretq_u32_u16(v16[2].val[0])); + v32[1] = vzipq_u32(vreinterpretq_u32_u16(v16[0].val[1]), vreinterpretq_u32_u16(v16[2].val[1])); + v32[2] = vzipq_u32(vreinterpretq_u32_u16(v16[1].val[0]), vreinterpretq_u32_u16(v16[3].val[0])); + v32[3] = vzipq_u32(vreinterpretq_u32_u16(v16[1].val[1]), vreinterpretq_u32_u16(v16[3].val[1])); + + iv[0] = _mm_unpacklo_epi64(v32[0].val[0], v32[2].val[0]); iv[1] = _mm_unpackhi_epi64(v32[0].val[0], v32[2].val[0]); + iv[2] = _mm_unpacklo_epi64(v32[0].val[1], v32[2].val[1]); iv[3] = _mm_unpackhi_epi64(v32[0].val[1], v32[2].val[1]); + iv[4] = _mm_unpacklo_epi64(v32[1].val[0], v32[3].val[0]); iv[5] = _mm_unpackhi_epi64(v32[1].val[0], v32[3].val[0]); + iv[6] = _mm_unpacklo_epi64(v32[1].val[1], v32[3].val[1]); iv[7] = _mm_unpackhi_epi64(v32[1].val[1], v32[3].val[1]); + #else + ov[0] = LD128(ip ); ov[0] = _mm_shuffle_epi8(ov[0], sv); + ov[1] = LD128(ip+ 16); ov[1] = _mm_shuffle_epi8(ov[1], sv); + ov[2] = LD128(ip+ 32); ov[2] = _mm_shuffle_epi8(ov[2], sv); + ov[3] = LD128(ip+ 48); ov[3] = _mm_shuffle_epi8(ov[3], sv); + ov[4] = LD128(ip+ 64); ov[4] = _mm_shuffle_epi8(ov[4], sv); + ov[5] = LD128(ip+ 80); ov[5] = _mm_shuffle_epi8(ov[5], sv); + ov[6] = LD128(ip+ 96); ov[6] = _mm_shuffle_epi8(ov[6], sv); + ov[7] = LD128(ip+112); ov[7] = _mm_shuffle_epi8(ov[7], sv); + v16[0] = vzipl_u16(ov[0], ov[1]); v16[1] = vziph_u16(ov[0], ov[1]); + v16[2] = vzipl_u16(ov[2], ov[3]); v16[3] = vziph_u16(ov[2], ov[3]); + v16[4] = vzipl_u16(ov[4], ov[5]); v16[5] = vziph_u16(ov[4], ov[5]); + v16[6] = vzipl_u16(ov[6], ov[7]); v16[7] = vziph_u16(ov[6], ov[7]); + + v32[0] = vzip_u32(vreinterpret_u32_u16(v16[0].val[0]), vreinterpret_u32_u16(v16[2].val[0]) ); + v32[1] = vzip_u32(vreinterpret_u32_u16(v16[0].val[1]), vreinterpret_u32_u16(v16[2].val[1]) ); + v32[2] = vzip_u32(vreinterpret_u32_u16(v16[1].val[0]), vreinterpret_u32_u16(v16[3].val[0]) ); + v32[3] = vzip_u32(vreinterpret_u32_u16(v16[1].val[1]), vreinterpret_u32_u16(v16[3].val[1]) ); + v32[4] = vzip_u32(vreinterpret_u32_u16(v16[4].val[0]), vreinterpret_u32_u16(v16[6].val[0]) ); + v32[5] = vzip_u32(vreinterpret_u32_u16(v16[4].val[1]), vreinterpret_u32_u16(v16[6].val[1]) ); + v32[6] = vzip_u32(vreinterpret_u32_u16(v16[5].val[0]), vreinterpret_u32_u16(v16[7].val[0]) ); + v32[7] = vzip_u32(vreinterpret_u32_u16(v16[5].val[1]), vreinterpret_u32_u16(v16[7].val[1]) ); + + iv[0] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[0].val[0]), vreinterpret_u64_u32(v32[4].val[0]) ); + iv[1] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[0].val[1]), vreinterpret_u64_u32(v32[4].val[1]) ); + iv[2] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[1].val[0]), vreinterpret_u64_u32(v32[5].val[0]) ); + iv[3] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[1].val[1]), vreinterpret_u64_u32(v32[5].val[1]) ); + + iv[4] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[2].val[0]), vreinterpret_u64_u32(v32[6].val[0]) ); + iv[5] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[2].val[1]), vreinterpret_u64_u32(v32[6].val[1]) ); + iv[6] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[3].val[0]), vreinterpret_u64_u32(v32[7].val[0]) ); + iv[7] = (__m128i)vcombine_u64(vreinterpret_u64_u32(v32[3].val[1]), vreinterpret_u64_u32(v32[7].val[1]) ); + #endif + #if STRIDE <= ESIZE + ST0(p,iv[0]); ST(p,iv[1],1); ST(p,iv[2],2); ST(p,iv[3],3); ST(p,iv[4],4); ST(p,iv[5],5); ST(p,iv[6],6); ST(p,iv[7],7); + #endif + #else // SSE + ov[0] = LD128(ip ); ov[0] = _mm_shuffle_epi8(ov[0], sv); + ov[1] = LD128(ip+16); ov[1] = _mm_shuffle_epi8(ov[1], sv); + ov[2] = LD128(ip+32); ov[2] = _mm_shuffle_epi8(ov[2], sv); + ov[3] = LD128(ip+48); ov[3] = _mm_shuffle_epi8(ov[3], sv); + + iv[0] = _mm_unpacklo_epi16(ov[0], ov[1]); iv[1] = _mm_unpackhi_epi16(ov[0], ov[1]); + iv[2] = _mm_unpacklo_epi16(ov[2], ov[3]); iv[3] = _mm_unpackhi_epi16(ov[2], ov[3]); + + ov[0] = _mm_unpacklo_epi32(iv[0], iv[2]); ov[1] = _mm_unpackhi_epi32(iv[0], iv[2]); + ov[2] = _mm_unpacklo_epi32(iv[1], iv[3]); ov[3] = _mm_unpackhi_epi32(iv[1], iv[3]); + + ov[4] = LD128(ip+ 64); ov[4] = _mm_shuffle_epi8(ov[4], sv); + ov[5] = LD128(ip+ 80); ov[5] = _mm_shuffle_epi8(ov[5], sv); + ov[6] = LD128(ip+ 96); ov[6] = _mm_shuffle_epi8(ov[6], sv); + ov[7] = LD128(ip+112); ov[7] = _mm_shuffle_epi8(ov[7], sv); + + iv[4] = _mm_unpacklo_epi16(ov[4], ov[5]); iv[5] = _mm_unpackhi_epi16(ov[4], ov[5]); + iv[6] = _mm_unpacklo_epi16(ov[6], ov[7]); iv[7] = _mm_unpackhi_epi16(ov[6], ov[7]); + + ov[4] = _mm_unpacklo_epi32(iv[4], iv[6]); ov[5] = _mm_unpackhi_epi32(iv[4], iv[6]); + ov[6] = _mm_unpacklo_epi32(iv[5], iv[7]); ov[7] = _mm_unpackhi_epi32(iv[5], iv[7]); + + iv[0] = _mm_unpacklo_epi64(ov[0], ov[4]); iv[1] = _mm_unpackhi_epi64(ov[0], ov[4]); + iv[2] = _mm_unpacklo_epi64(ov[1], ov[5]); iv[3] = _mm_unpackhi_epi64(ov[1], ov[5]); + + iv[4] = _mm_unpacklo_epi64(ov[2], ov[6]); iv[5] = _mm_unpackhi_epi64(ov[2], ov[6]); + iv[6] = _mm_unpacklo_epi64(ov[3], ov[7]); iv[7] = _mm_unpackhi_epi64(ov[3], ov[7]); + #if STRIDE <= ESIZE + ST0(p,iv[0]); ST(p,iv[1],1); ST(p,iv[2],2); ST(p,iv[3],3); ST(p,iv[4],4); ST(p,iv[5],5); ST(p,iv[6],6); ST(p,iv[7],7); + #endif + #endif + #endif + + #elif defined(__SSE2__) + #if ESIZE == 2 + iv[0] = LD128(ip ); iv[1] = LD128(ip+16)); + + ov[0] = _mm_unpacklo_epi8(iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8(iv[0], iv[1]); + iv[0] = _mm_unpacklo_epi8(ov[0], ov[1]); iv[1] = _mm_unpackhi_epi8(ov[0], ov[1]); + + ov[0] = _mm_unpacklo_epi8(iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8(iv[0], iv[1]); + iv[0] = _mm_unpacklo_epi8(ov[0], ov[1]); iv[1] = _mm_unpackhi_epi8(ov[0], ov[1]); + ST0(p,iv[0]); ST(p,iv[1],1); + #elif ESIZE == 4 + iv[0] = LD128(ip ); iv[1] = LD128(ip+16); iv[2] = LD128(ip+32); iv[3] = LD128(ip+48); + + ov[0] = _mm_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8( iv[0], iv[1]); + iv[0] = _mm_unpacklo_epi8( ov[0], ov[1]); iv[1] = _mm_unpackhi_epi8( ov[0], ov[1]); + + ov[0] = _mm_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8( iv[0], iv[1]); + iv[0] = _mm_unpacklo_epi64(ov[0], ov[2]); iv[1] = _mm_unpackhi_epi64(ov[0], ov[2]); + + ov[2] = _mm_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm_unpackhi_epi8( iv[2], iv[3]); + iv[2] = _mm_unpacklo_epi8( ov[2], ov[3]); iv[3] = _mm_unpackhi_epi8( ov[2], ov[3]); + ov[2] = _mm_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm_unpackhi_epi8( iv[2], iv[3]); + + iv[2] = _mm_unpacklo_epi64(ov[1], ov[3]); iv[3] = _mm_unpackhi_epi64(ov[1], ov[3]); + ST0(p,iv[0]); ST(p,iv[1],1); ST(p,iv[2],2); ST(p,iv[3],3); + #elif ESIZE == 8 + iv[0] = LD128(ip ); iv[1] = LD128(ip+16); iv[2] = LD128(ip+32); iv[3] = LD128(ip+48); + iv[4] = LD128(ip+64); iv[5] = LD128(ip+80); iv[6] = LD128(ip+96); iv[7] = LD128(ip+112); + + ov[0] = _mm_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8( iv[0], iv[1]); + ov[2] = _mm_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm_unpackhi_epi8( iv[2], iv[3]); + ov[4] = _mm_unpacklo_epi8( iv[4], iv[5]); ov[5] = _mm_unpackhi_epi8( iv[4], iv[5]); + ov[6] = _mm_unpacklo_epi8( iv[6], iv[7]); ov[7] = _mm_unpackhi_epi8( iv[6], iv[7]); + + iv[0] = _mm_unpacklo_epi8( ov[0], ov[1]); iv[1] = _mm_unpackhi_epi8( ov[0], ov[1]); + iv[2] = _mm_unpacklo_epi8( ov[2], ov[3]); iv[3] = _mm_unpackhi_epi8( ov[2], ov[3]); + iv[4] = _mm_unpacklo_epi8( ov[4], ov[5]); iv[5] = _mm_unpackhi_epi8( ov[4], ov[5]); + iv[6] = _mm_unpacklo_epi8( ov[6], ov[7]); iv[7] = _mm_unpackhi_epi8( ov[6], ov[7]); + + ov[0] = _mm_unpacklo_epi32(iv[0], iv[2]); ov[1] = _mm_unpackhi_epi32(iv[0], iv[2]); + ov[2] = _mm_unpacklo_epi32(iv[1], iv[3]); ov[3] = _mm_unpackhi_epi32(iv[1], iv[3]); + ov[4] = _mm_unpacklo_epi32(iv[4], iv[6]); ov[5] = _mm_unpackhi_epi32(iv[4], iv[6]); + ov[6] = _mm_unpacklo_epi32(iv[5], iv[7]); ov[7] = _mm_unpackhi_epi32(iv[5], iv[7]); + ST0(p,iv[0]); ST(p,iv[1],1); ST(p,iv[2],2); ST(p,iv[3],3); + + iv[0] = _mm_unpacklo_epi64(ov[0], ov[4]); iv[1] = _mm_unpackhi_epi64(ov[0], ov[4]); + iv[2] = _mm_unpacklo_epi64(ov[1], ov[5]); iv[3] = _mm_unpackhi_epi64(ov[1], ov[5]); + iv[4] = _mm_unpacklo_epi64(ov[2], ov[6]); iv[5] = _mm_unpackhi_epi64(ov[2], ov[6]); + iv[6] = _mm_unpacklo_epi64(ov[3], ov[7]); iv[7] = _mm_unpackhi_epi64(ov[3], ov[7]); + ST(p,iv[4],4); ST(p,iv[5],5); ST(p,iv[6],6); ST(p,iv[7],7); + #endif + #endif + + #if STRIDE > ESIZE // ---------------------- Nibble ------------------------------------------- + #define STL(_p_,_v_,_i_) _mm_storel_epi64((__m128i *)SIE(_p_,_i_), _v_) + #define STL0(_p_,_v_) _mm_storel_epi64((__m128i *)(_p_), _v_) + + ov[0] = _mm_and_si128(iv[0], cl); ov[0] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = _mm_packus_epi16(ov[0], _mm_srli_si128(ov[0],2)); + ov[1] = _mm_srli_epi16(_mm_and_si128(iv[0], ch),4); ov[1] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = _mm_packus_epi16(ov[1], _mm_srli_si128(ov[1],2)); + ov[2] = _mm_and_si128(iv[1], cl); ov[2] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = _mm_packus_epi16(ov[2], _mm_srli_si128(ov[2],2)); + ov[3] = _mm_srli_epi16(_mm_and_si128(iv[1], ch),4); ov[3] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = _mm_packus_epi16(ov[3], _mm_srli_si128(ov[3],2)); + STL0(p,ov[0]); STL(p,ov[1],1);STL(p,ov[2],2);STL(p,ov[3],3); + #if ESIZE > 2 + ov[0] = _mm_and_si128(iv[2], cl); ov[0] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = _mm_packus_epi16(ov[0], _mm_srli_si128(ov[0],2)); + ov[1] = _mm_srli_epi16(_mm_and_si128(iv[2], ch),4); ov[1] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = _mm_packus_epi16(ov[1], _mm_srli_si128(ov[1],2)); + ov[2] = _mm_and_si128(iv[3], cl); ov[2] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = _mm_packus_epi16(ov[2], _mm_srli_si128(ov[2],2)); + ov[3] = _mm_srli_epi16(_mm_and_si128(iv[3], ch),4); ov[3] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = _mm_packus_epi16(ov[3], _mm_srli_si128(ov[3],2)); + STL(p,ov[0],4); STL(p,ov[1],5);STL(p,ov[2],6);STL(p,ov[3],7); + #if ESIZE > 4 + ov[0] = _mm_and_si128(iv[4], cl); ov[0] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[0],4), ov[0]),cb); ov[0] = _mm_packus_epi16(ov[0], _mm_srli_si128(ov[0],2)); + ov[1] = _mm_srli_epi16(_mm_and_si128(iv[4], ch),4); ov[1] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[1],4), ov[1]),cb); ov[1] = _mm_packus_epi16(ov[1], _mm_srli_si128(ov[1],2)); + ov[2] = _mm_and_si128(iv[5], cl); ov[2] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[2],4), ov[2]),cb); ov[2] = _mm_packus_epi16(ov[2], _mm_srli_si128(ov[2],2)); + ov[3] = _mm_srli_epi16(_mm_and_si128(iv[5], ch),4); ov[3] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[3],4), ov[3]),cb); ov[3] = _mm_packus_epi16(ov[3], _mm_srli_si128(ov[3],2)); + STL(p,ov[0],8); STL(p,ov[1],9);STL(p,ov[2],10);STL(p,ov[3],11); + + ov[4] = _mm_and_si128(iv[6], cl); ov[4] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[4],4), ov[4]),cb); ov[4] = _mm_packus_epi16(ov[4], _mm_srli_si128(ov[4],2)); + ov[5] = _mm_srli_epi16(_mm_and_si128(iv[6], ch),4); ov[5] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[5],4), ov[5]),cb); ov[5] = _mm_packus_epi16(ov[5], _mm_srli_si128(ov[5],2)); + ov[6] = _mm_and_si128(iv[7], cl); ov[6] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[6],4), ov[6]),cb); ov[6] = _mm_packus_epi16(ov[6], _mm_srli_si128(ov[6],2)); + ov[7] = _mm_srli_epi16(_mm_and_si128(iv[7], ch),4); ov[7] = _mm_and_si128(_mm_or_si128(_mm_srli_epi16(ov[7],4), ov[7]),cb); ov[7] = _mm_packus_epi16(ov[7], _mm_srli_si128(ov[7],2)); + STL(p,ov[4],12); STL(p,ov[5],13);STL(p,ov[6],14);STL(p,ov[7],15); + #endif + #endif + #endif + } + TEMPLATE2(tpenc,ESIZE)(in+v, n-v, out+v); +} + +void TEMPLATE2(TPDEC128V, ESIZE)(unsigned char *in, unsigned n, unsigned char *out) { + unsigned v = n&~(ESIZE*32-1); + unsigned stride = v/STRIDE; + unsigned char *op,*ip; + + #if STRIDE > ESIZE + __m128i cl = _mm_set1_epi8(0x0f), ch=_mm_set1_epi8(0xf0), cb = _mm_set1_epi16(0xff); + #endif + + for(op = out,ip = in; op != out+v; op+=ESIZE*16,ip += ESIZE*16/STRIDE) { + unsigned char *p=ip; PREFETCH(ip+(ESIZE*16/STRIDE)*ESIZE,0); + __m128i iv[ESIZE], ov[ESIZE]; + + #if STRIDE > ESIZE //------------ Nibble transpose ------------------- + ov[0] = _mm_loadl_epi64((__m128i *) p ); + ov[1] = _mm_loadl_epi64((__m128i *)SID(p,1)); + ov[2] = _mm_loadl_epi64((__m128i *)SID(p,2)); + ov[3] = _mm_loadl_epi64((__m128i *)SID(p,3)); + + ov[0] = _mm_unpacklo_epi8(ov[0], _mm_srli_epi16(ov[0],4)); ov[0] = _mm_and_si128(ov[0], cl); // 0,1->0 + ov[1] = _mm_unpacklo_epi8(ov[1], _mm_srli_epi16(ov[1],4)); ov[1] = _mm_and_si128(ov[1], cl); + iv[0] = _mm_or_si128(_mm_slli_epi16(ov[1],4), ov[0]); + + ov[2] = _mm_unpacklo_epi8(ov[2], _mm_srli_epi16(ov[2],4)); ov[2] = _mm_and_si128(ov[2], cl); // 2,3->1 + ov[3] = _mm_unpacklo_epi8(ov[3], _mm_srli_epi16(ov[3],4)); ov[3] = _mm_and_si128(ov[3], cl); + iv[1] = _mm_or_si128(_mm_slli_epi16(ov[3],4), ov[2]); + #if ESIZE > 2 + ov[0] = _mm_loadl_epi64((__m128i *)SID(p,4)); + ov[1] = _mm_loadl_epi64((__m128i *)SID(p,5)); + ov[2] = _mm_loadl_epi64((__m128i *)SID(p,6)); + ov[3] = _mm_loadl_epi64((__m128i *)SID(p,7)); + + ov[0] = _mm_unpacklo_epi8(ov[0], _mm_srli_epi16(ov[0],4)); ov[0] = _mm_and_si128(ov[0], cl); // 0,1->2 + ov[1] = _mm_unpacklo_epi8(ov[1], _mm_srli_epi16(ov[1],4)); ov[1] = _mm_and_si128(ov[1], cl); + iv[2] = _mm_or_si128(_mm_slli_epi16(ov[1],4), ov[0]); + + ov[2] = _mm_unpacklo_epi8(ov[2], _mm_srli_epi16(ov[2],4)); ov[2] = _mm_and_si128(ov[2], cl); // 2,3->3 + ov[3] = _mm_unpacklo_epi8(ov[3], _mm_srli_epi16(ov[3],4)); ov[3] = _mm_and_si128(ov[3], cl); + iv[3] = _mm_or_si128(_mm_slli_epi16(ov[3],4), ov[2]); + #endif + #if ESIZE > 4 + ov[0] = _mm_loadl_epi64((__m128i *)SID(p,8)); + ov[1] = _mm_loadl_epi64((__m128i *)SID(p,9)); + ov[2] = _mm_loadl_epi64((__m128i *)SID(p,10)); + ov[3] = _mm_loadl_epi64((__m128i *)SID(p,11)); + + ov[0] = _mm_unpacklo_epi8(ov[0], _mm_srli_epi16(ov[0],4)); ov[0] = _mm_and_si128(ov[0], cl); // 0,1->4 + ov[1] = _mm_unpacklo_epi8(ov[1], _mm_srli_epi16(ov[1],4)); ov[1] = _mm_and_si128(ov[1], cl); + iv[4] = _mm_or_si128(_mm_slli_epi16(ov[1],4), ov[0]); + + ov[2] = _mm_unpacklo_epi8(ov[2], _mm_srli_epi16(ov[2],4)); ov[2] = _mm_and_si128(ov[2], cl); // 2,3->5 + ov[3] = _mm_unpacklo_epi8(ov[3], _mm_srli_epi16(ov[3],4)); + ov[3] = _mm_and_si128(ov[3], cl); + iv[5] = _mm_or_si128(_mm_slli_epi16(ov[3],4), ov[2]); + + ov[0] = _mm_loadl_epi64((__m128i *)SID(p,12)); + ov[1] = _mm_loadl_epi64((__m128i *)SID(p,13)); + ov[2] = _mm_loadl_epi64((__m128i *)SID(p,14)); + ov[3] = _mm_loadl_epi64((__m128i *)SID(p,15)); + + ov[0] = _mm_unpacklo_epi8(ov[0], _mm_srli_epi16(ov[0],4)); ov[0] = _mm_and_si128(ov[0], cl); // 0,1->6 + ov[1] = _mm_unpacklo_epi8(ov[1], _mm_srli_epi16(ov[1],4)); ov[1] = _mm_and_si128(ov[1], cl); + iv[6] = _mm_or_si128(_mm_slli_epi16(ov[1],4), ov[0]); + + ov[2] = _mm_unpacklo_epi8(ov[2], _mm_srli_epi16(ov[2],4)); ov[2] = _mm_and_si128(ov[2], cl); // 2,3->7 + ov[3] = _mm_unpacklo_epi8(ov[3], _mm_srli_epi16(ov[3],4)); ov[3] = _mm_and_si128(ov[3], cl); + iv[7] = _mm_or_si128(_mm_slli_epi16(ov[3],4), ov[2]); + #endif + #else // --------------------------- Byte transpose ------------------- + iv[0] = _mm_loadu_si128((__m128i *) p ); + iv[1] = _mm_loadu_si128((__m128i *)SID(p,1)); + #if ESIZE > 2 + iv[2] = _mm_loadu_si128((__m128i *)SID(p,2)); + iv[3] = _mm_loadu_si128((__m128i *)SID(p,3)); + #if ESIZE > 4 + iv[4] = _mm_loadu_si128((__m128i *)SID(p,4)); + iv[5] = _mm_loadu_si128((__m128i *)SID(p,5)); + iv[6] = _mm_loadu_si128((__m128i *)SID(p,6)); + iv[7] = _mm_loadu_si128((__m128i *)SID(p,7)); + #endif + #endif + #endif + #if ESIZE == 2 + #ifdef __ARM_NEON + uint8x16x2_t w; w.val[0] = (uint8x16_t)iv[0]; + w.val[1] = (uint8x16_t)iv[1]; vst2q_u8(op, w); + #else + ov[0] = _mm_unpacklo_epi8(iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8(iv[0], iv[1]);//i(0,1)->o(0,1) + ST128(op, ov[0]); ST128(op+16, ov[1]); + #endif + #elif ESIZE == 4 + #ifdef __ARM_NEON + uint8x16x4_t w; w.val[0] = (uint8x16_t)iv[0]; + w.val[1] = (uint8x16_t)iv[1]; + w.val[2] = (uint8x16_t)iv[2]; + w.val[3] = (uint8x16_t)iv[3]; vst4q_u8(op,w); + #else + ov[0] = _mm_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8(iv[0], iv[1]); //i(0,1)->o(0,1) + ov[2] = _mm_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm_unpackhi_epi8(iv[2], iv[3]); //i(2,3)->o(2,3) + + iv[0] = _mm_unpacklo_epi16(ov[0], ov[2]); iv[1] = _mm_unpackhi_epi16(ov[0], ov[2]);//o(0,2)->i(0,1) + iv[2] = _mm_unpacklo_epi16(ov[1], ov[3]); iv[3] = _mm_unpackhi_epi16(ov[1], ov[3]);//o(1,3)->i(2,3) + ST128(op, iv[0]); ST128(op+16,iv[1]); ST128(op+32,iv[2]); ST128(op+48,iv[3]); + #endif + #else + ov[0] = _mm_unpacklo_epi8( iv[0], iv[1]); ov[1] = _mm_unpackhi_epi8( iv[0], iv[1]);//i(0,1)->o(0,1) + ov[2] = _mm_unpacklo_epi8( iv[2], iv[3]); ov[3] = _mm_unpackhi_epi8( iv[2], iv[3]);//i(2,3)->o(2,3) + ov[4] = _mm_unpacklo_epi8( iv[4], iv[5]); ov[5] = _mm_unpackhi_epi8( iv[4], iv[5]);//i(4,5)->o(4,5) + ov[6] = _mm_unpacklo_epi8( iv[6], iv[7]); ov[7] = _mm_unpackhi_epi8( iv[6], iv[7]);//i(6,7)->o(6,7) + + iv[0] = _mm_unpacklo_epi16(ov[0], ov[2]); iv[1] = _mm_unpackhi_epi16(ov[0], ov[2]); + iv[2] = _mm_unpacklo_epi16(ov[1], ov[3]); iv[3] = _mm_unpackhi_epi16(ov[1], ov[3]); + iv[4] = _mm_unpacklo_epi16(ov[4], ov[6]); iv[5] = _mm_unpackhi_epi16(ov[4], ov[6]); + iv[6] = _mm_unpacklo_epi16(ov[5], ov[7]); iv[7] = _mm_unpackhi_epi16(ov[5], ov[7]); + + ov[0] = _mm_unpacklo_epi32(iv[0], iv[4]); ov[1] = _mm_unpackhi_epi32(iv[0], iv[4]); + ov[2] = _mm_unpacklo_epi32(iv[1], iv[5]); ov[3] = _mm_unpackhi_epi32(iv[1], iv[5]); + ov[4] = _mm_unpacklo_epi32(iv[2], iv[6]); ov[5] = _mm_unpackhi_epi32(iv[2], iv[6]); + ov[6] = _mm_unpacklo_epi32(iv[3], iv[7]); ov[7] = _mm_unpackhi_epi32(iv[3], iv[7]); + + ST128(op, ov[0]); ST128(op+16,ov[1]); ST128(op+32,ov[2]); ST128(op+48, ov[3]); + ST128(op+64,ov[4]); ST128(op+80,ov[5]); ST128(op+96,ov[6]); ST128(op+112,ov[7]); + #endif + } + TEMPLATE2(tpdec,ESIZE)(in+v, n-v, out+v); +} + #endif + + #endif + +#endif +#endif diff --git a/src/ext/for/transpose.h b/src/ext/for/transpose.h new file mode 100644 index 00000000000..5f4f1e62f12 --- /dev/null +++ b/src/ext/for/transpose.h @@ -0,0 +1,113 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// transpose.h - Byte/Nibble transpose for further compressing with lz77 or other compressors +#ifdef __cplusplus +extern "C" { +#endif +// Syntax +// in : Input buffer +// n : Total number of bytes in input buffer +// out : output buffer +// esize : element size in bytes (ex. 2, 4, 8,... ) + +//---------- High level functions with dynamic cpu detection and JIT scalar/sse/avx2 switching +void tpenc( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); // tranpose +void tpdec( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); // reverse transpose + +void tp2denc(unsigned char *in, unsigned x, unsigned y, unsigned char *out, unsigned esize); //2D transpose +void tp2ddec(unsigned char *in, unsigned x, unsigned y, unsigned char *out, unsigned esize); +void tp3denc(unsigned char *in, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize); //3D transpose +void tp3ddec(unsigned char *in, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize); +void tp4denc(unsigned char *in, unsigned w, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize); //4D transpose +void tp4ddec(unsigned char *in, unsigned w, unsigned x, unsigned y, unsigned z, unsigned char *out, unsigned esize); + +// Nibble transpose SIMD (SSE2,AVX2, ARM Neon) +void tp4enc( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); +void tp4dec( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); + +// bit transpose +//void tp1enc( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); +//void tp1dec( unsigned char *in, unsigned n, unsigned char *out, unsigned esize); + +//---------- Low level functions ------------------------------------ +void tpenc2( unsigned char *in, unsigned n, unsigned char *out); // scalar +void tpenc3( unsigned char *in, unsigned n, unsigned char *out); +void tpenc4( unsigned char *in, unsigned n, unsigned char *out); +void tpenc8( unsigned char *in, unsigned n, unsigned char *out); +void tpenc16( unsigned char *in, unsigned n, unsigned char *out); + +void tpdec2( unsigned char *in, unsigned n, unsigned char *out); +void tpdec3( unsigned char *in, unsigned n, unsigned char *out); +void tpdec4( unsigned char *in, unsigned n, unsigned char *out); +void tpdec8( unsigned char *in, unsigned n, unsigned char *out); +void tpdec16( unsigned char *in, unsigned n, unsigned char *out); + +void tpenc128v2( unsigned char *in, unsigned n, unsigned char *out); // sse2 +void tpdec128v2( unsigned char *in, unsigned n, unsigned char *out); +void tpenc128v4( unsigned char *in, unsigned n, unsigned char *out); +void tpdec128v4( unsigned char *in, unsigned n, unsigned char *out); +void tpenc128v8( unsigned char *in, unsigned n, unsigned char *out); +void tpdec128v8( unsigned char *in, unsigned n, unsigned char *out); + +void tp4enc128v2( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec128v2( unsigned char *in, unsigned n, unsigned char *out); +void tp4enc128v4( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec128v4( unsigned char *in, unsigned n, unsigned char *out); +void tp4enc128v8( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec128v8( unsigned char *in, unsigned n, unsigned char *out); + +void tp1enc128v2( unsigned char *in, unsigned n, unsigned char *out); +void tp1dec128v2( unsigned char *in, unsigned n, unsigned char *out); +void tp1enc128v4( unsigned char *in, unsigned n, unsigned char *out); +void tp1dec128v4( unsigned char *in, unsigned n, unsigned char *out); +void tp1enc128v8( unsigned char *in, unsigned n, unsigned char *out); +void tp1dec128v8( unsigned char *in, unsigned n, unsigned char *out); + +void tpenc256v2( unsigned char *in, unsigned n, unsigned char *out); // avx2 +void tpdec256v2( unsigned char *in, unsigned n, unsigned char *out); +void tpenc256v4( unsigned char *in, unsigned n, unsigned char *out); +void tpdec256v4( unsigned char *in, unsigned n, unsigned char *out); +void tpenc256v8( unsigned char *in, unsigned n, unsigned char *out); +void tpdec256v8( unsigned char *in, unsigned n, unsigned char *out); + +void tp4enc256v2( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec256v2( unsigned char *in, unsigned n, unsigned char *out); +void tp4enc256v4( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec256v4( unsigned char *in, unsigned n, unsigned char *out); +void tp4enc256v8( unsigned char *in, unsigned n, unsigned char *out); +void tp4dec256v8( unsigned char *in, unsigned n, unsigned char *out); + +//------- CPU instruction set +// cpuiset = 0: return current simd set, +// cpuiset != 0: set simd set 0:scalar, 20:sse2, 52:avx2 +unsigned cpuini(unsigned cpuiset); + +// convert simd set to string "sse3", "sse3", "sse4.1" or "avx2" +// Ex.: printf("current cpu set=%s\n", cpustr(cpuini(0)) ); +char *cpustr(unsigned cpuisa); + +unsigned cpuisa(void); +#ifdef __cplusplus +} +#endif diff --git a/src/ext/for/trle.h b/src/ext/for/trle.h new file mode 100644 index 00000000000..f40e65d14a7 --- /dev/null +++ b/src/ext/for/trle.h @@ -0,0 +1,72 @@ +/** + Copyright (C) powturbo 2015-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - email : powturbo [AT] gmail.com + - github : https://github.com/powturbo + - homepage : https://sites.google.com/site/powturbo/ + - twitter : https://twitter.com/powturbo + + TurboRLE - "Most efficient and fastest Run Length Encoding" +**/ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif +// RLE with specified escape char +unsigned _srlec8( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint8_t e); +unsigned _srled8( const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, uint8_t e); + +unsigned _srlec16(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint16_t e); +unsigned _srled16(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, uint16_t e); + +unsigned _srlec32(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint32_t e); +unsigned _srled32(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, uint32_t e); + +unsigned _srlec64(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint64_t e); +unsigned _srled64(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, uint64_t e); + +// functions w/ overflow handling +unsigned srlec8( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint8_t e); +unsigned srled8( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen, uint8_t e); + +unsigned srlec16(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint16_t e); +unsigned srled16(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen, uint16_t e); + +unsigned srlec32(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint32_t e); +unsigned srled32(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen, uint32_t e); + +unsigned srlec64(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint64_t e); +unsigned srled64(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen, uint64_t e); + +// RLE w. automatic escape char determination +unsigned srlec( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out); +unsigned _srled( const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen); +unsigned srled( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen); + +// Turbo RLE +unsigned trlec( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out); +unsigned _trled( const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen); +unsigned trled( const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen); +#ifdef __cplusplus +} +#endif diff --git a/src/ext/for/trle_.h b/src/ext/for/trle_.h new file mode 100644 index 00000000000..83dbebfc4f8 --- /dev/null +++ b/src/ext/for/trle_.h @@ -0,0 +1,60 @@ +/** + Copyright (C) powturbo 2015-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - email : powturbo [AT] gmail.com + - github : https://github.com/powturbo + - homepage : https://sites.google.com/site/powturbo/ + - twitter : https://twitter.com/powturbo + + TurboRLE - "Most efficient and fastest Run Length Encoding" +**/ +//------------------------- Variable Byte ( see https://github.com/powturbo/TurboPFor )----------------------------------------------------- +#include "conf.h" +#define TMIN 3 + +#define VL_SIZE 32 +#define VL_MAX 0xff +#define VL_B2 4 +#define VL_B3 3 +#define VL_BA3 (VL_MAX - (VL_SIZE/8 - 3)) +#define VL_BA2 (VL_BA3 - (1<> 16); ctou16(_op_) = (_x_); _op_ += 2; _act_;}\ + else { unsigned _b = (bsr32((_x_))+7)/8; *_op_++ = VL_BA3 + (_b - 3); ctou32(_op_) = (_x_); _op_ += _b; _act_;}\ +} + +#define _vlget32(_ip_, _x_, _act_) do { _x_ = *_ip_++;\ + if(likely(_x_ < VL_OFS1)) { _act_ ;}\ + else if(likely(_x_ < VL_BA2)) { _x_ = ((_x_<<8) + (*_ip_)) + (VL_OFS1 - (VL_OFS1 << 8)); _ip_++; _act_;} \ + else if(likely(_x_ < VL_BA3)) { _x_ = ctou16(_ip_) + ((_x_ - VL_BA2 ) << 16) + VL_OFS2; _ip_ += 2; _act_;}\ + else { unsigned _b = _x_-VL_BA3; _x_ = ctou32(_ip_) & ((1u << 8 * _b << 24) - 1); _ip_ += 3 + _b; _act_;}\ +} while(0) + +#define vlput32(_op_, _x_) { register unsigned _x = _x_; _vlput32(_op_, _x, ;); } +#define vlget32(_ip_, _x_) _vlget32(_ip_, _x_, ;) + +#define vlzput(_op_, _x_, _m_, _rmap_) do { if(unlikely((_x_) < _m_)) *_op_++ = _rmap_[_x_]; else { unsigned _xi = (_x_) - _m_; *_op_++ = _rmap_[_m_]; vlput32(_op_, _xi); } } while(0) +#define vlzget(_ip_, _x_, _m_, _e_) { _x_ = _e_; if(unlikely(_x_ == _m_)) { vlget32(_ip_,_x_ ); _x_+=_m_; } } + diff --git a/src/ext/for/trlec.c b/src/ext/for/trlec.c new file mode 100644 index 00000000000..0ffdc0538f3 --- /dev/null +++ b/src/ext/for/trlec.c @@ -0,0 +1,343 @@ +/** + Copyright (C) powturbo 2015-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - email : powturbo [AT] gmail.com + - github : https://github.com/powturbo + - homepage : https://sites.google.com/site/powturbo/ + - twitter : https://twitter.com/powturbo + + TurboRLE - "Most efficient and fastest Run Length Encoding" +**/ + #ifndef USIZE +#include +#include "conf.h" +#include "trle.h" +#include "trle_.h" + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif + +//------------------------------------- Fastet Histogram : https://github.com/powturbo/TurboHist ------------------------------------------- +#define cnt_t unsigned +#define CSIZE (256 + 8) + +#define CU32(u,_i_) {\ + c[_i_+0][(unsigned char) u ]++;\ + c[_i_+1][(unsigned char)(u>> 8)]++;\ + c[_i_+2][(unsigned char)(u>>16)]++;\ + c[_i_+3][ u>>24 ]++;\ +} + +#define OV 8 +#define INC4_32(_i_) { { unsigned u = ux, v = vx; ux = ctou32(ip+_i_+OV+0); vx = ctou32(ip+_i_+OV+ 4); CU32(u,0); CU32(v,0); }\ + { unsigned u = ux, v = vx; ux = ctou32(ip+_i_+OV+8); vx = ctou32(ip+_i_+OV+12); CU32(u,0); CU32(v,0); }\ +} + +static unsigned cntcalc32(const unsigned char *__restrict in, unsigned inlen, cnt_t *__restrict cnt) { + cnt_t c[4][CSIZE] = {0},i; + + unsigned char *ip = in; + if(inlen >= 64) { + unsigned ux = ctou32(ip), vx = ctou32(ip+4); + for(; ip != in+(inlen&~(64-1))-64; ip += 64) { INC4_32(0); INC4_32(16); INC4_32(32); INC4_32(48); __builtin_prefetch(ip+512, 0); } + } + while(ip != in+inlen) + c[0][*ip++]++; + + for(i = 0; i < 256; i++) + cnt[i] = c[0][i]+c[1][i]+c[2][i]+c[3][i]; + unsigned a = 256; while(a > 1 && !cnt[a-1]) a--; + return a; +} + +//------------------------------ speed optimized RLE 8 with escape char. SSE/AVX2 slower than scalar in encoding ---------------------------------------- +#define SRLE8 (__WORDSIZE/2) + +#define USIZE 8 +#include "trlec.c" + + #if SRLE8 +#define PUTC(_op_, _x_) *_op_++ = _x_ +#define PUTE(_op_, _e_) do { PUTC(_op_, _e_); vlput32(_op_, 0); } while(0) + +#define SZ64 if((z = (ctou64(ip) ^ ctou64(ip+1)))) goto a; ip += 8; +#define SZ32 if((z = (ctou32(ip) ^ ctou32(ip+1)))) break; ip += 4; + +#define SRLEPUT8(_pp_, _ip_, _e_, _op_) do {\ + unsigned _r = (_ip_ - _pp_)+1;\ + if(_r >= 4) { PUTC(_op_, _e_); _r = (_r-4)+3; vlput32(_op_, _r); PUTC(_op_, pp[0]); }\ + else if(pp[0] == _e_) {\ + PUTC(_op_, _e_); _r -= 1; vlput32(_op_, _r); /*1-3:Escape char -> 2-6 bytes */\ + } else while(_r--) PUTC(_op_, pp[0]);\ +} while(0) + +unsigned _srlec8(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint8_t e) { + uint8_t *ip = in, *pp = in, *ie = in+inlen, *op = out; + + if(inlen > SRLE8+1) + while(ip < ie-1-SRLE8) { + #if __WORDSIZE == 64 + uint64_t z; SZ64; SZ64; SZ64; SZ64; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz64(z)>>3; + #else + uint32_t z; SZ32; SZ32; SZ32; SZ32; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz32(z)>>3; + #endif + SRLEPUT8(pp, ip, e, op); + pp = ++ip; + } + + while(ip < ie-1) { + while(ip < ie-1 && ip[1] == *pp) ip++; + SRLEPUT8(pp, ip, e, op); + pp = ++ip; + } + if(ip < ie) { + unsigned c = *ip++; + if(c == e) PUTE(op,e); + else PUTC(op, c); + } //AS(ip == ie,"FatalI ip!=ie=%d ", ip-ie) + return op - out; +} + +#define SRLEPUT8X(_pp_, _ip_, _e_, _op_) do {\ + unsigned _r = (_ip_ - _pp_)+1, _cr = pp[0];\ + if(_r >= 4 /*|| _r == 3 && _cr == ix*/) { PUTC(_op_, _e_); _r = ((_r-4)+3)<<1; if(_cr == ix) { vlput32(_op_, _r); } else { vlput32(_op_, _r|1); PUTC(_op_, pp[0]); } }\ + else if(_cr == _e_) { PUTC(_op_, _e_); _r = (_r-1)<<1|1; vlput32(_op_, _r); /*1-3:Escape char -> 2-6 bytes */ } \ + else while(_r--) PUTC(_op_, _cr);\ +} while(0) + +static inline unsigned _srlec8x(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint8_t e, uint8_t ix) { + uint8_t *ip = in, *pp = in, *ie = in+inlen, *op = out; + + if(inlen > SRLE8+1) + while(ip < ie-1-SRLE8) { + #if __WORDSIZE == 64 + uint64_t z; SZ64; SZ64; SZ64; SZ64; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz64(z)>>3; + #else + uint32_t z; SZ32; SZ32; SZ32; SZ32; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz32(z)>>3; + #endif + SRLEPUT8X(pp, ip, e, op); + pp = ++ip; + } + + while(ip < ie-1) { + while(ip < ie-1 && ip[1] == *pp) ip++; + SRLEPUT8X(pp, ip, e, op); + pp = ++ip; + } + if(ip < ie) { + unsigned c = *ip++; + if(c == e) PUTE(op,e); + else PUTC(op, c); + } //AS(ip == ie,"FatalI ip!=ie=%d ", ip-ie) + return op - out; +} + #endif + +unsigned srlec(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out) { // Automatic escape char determination + unsigned cnt[256] = {0}, a, m = -1, x = 0, im = 0, i, ix, l; + if(!inlen) return 0; + + a = cntcalc32(in, inlen, cnt); + if(cnt[a-1] == inlen) { + *out = *in; + return 1; // RETURN 1 = memset + } + + if(a != 256) { // determine escape char + for(im = a, i = m = 0; i < a; i++) + if(cnt[i] > x) x = cnt[i],ix = i; + } else for(i = 0; i < a; i++) { + if(cnt[i] < m) m = cnt[i],im = i; // minimum for ESC char + if(cnt[i] > x) x = cnt[i],ix = i; // maximum for embeding in the run length + } + out[0] = im; + out[1] = ix; + if((l = _srlec8x(in, inlen, out+2, im, ix)+2) < inlen) + return l; + memcpy(out, in, inlen); + return inlen; +} + +//------------------------------------------------- TurboRLE ------------------------------------------ +#define TRLEPUT(pp, ip, m, rmap, op) do {\ + int _r_ = (ip - pp)+1;\ + if(_r_ >= TMIN) { \ + unsigned char *q = op; /*checkpoint*/\ + if(pp[0] == ix) { unsigned _r = (_r_ - TMIN)<<1|1; vlzput(op, _r, m, rmap); } else { unsigned _r = (_r_ - TMIN)<<1; vlzput(op, _r, m, rmap); *op++ = pp[0]; }\ + if(op-q >= _r_) { op = q; while(_r_--) *op++ = pp[0]; } /*rollback rle*/\ + } else while(_r_--) *op++ = pp[0];\ +} while(0) + +unsigned trlec(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out) { + unsigned cnt[256] = {0}, m=-1, x=0, im, i, a, c; + unsigned char rmap[256], *op=out, *ie = in+inlen, *ip = in,*pp = in, ix; + if(!inlen) return 0; // RETURN 0 = zero length + + a = cntcalc32(in, inlen, cnt); + if(cnt[a-1] == inlen) { + *out = *in; + return 1; // RETURN 1 = memset + } + + if(a != 256) { // determine escape char + for(im = a, i = m = 0; i < a; i++) + if(cnt[i] > x) x = cnt[i],ix = i; + } else for(i = 0; i < a; i++) { + if(cnt[i] < m) m = cnt[i],im = i; // minimum for ESC char + if(cnt[i] > x) x = cnt[i],ix = i; // maximum for embeding in the run length + } + if(m) { // no unused bytes found + PUTC(op, 0); // 0: srle mode + PUTC(op, im); // _srlec8 escape char + op += _srlec8(in, inlen, op, im); + if(op - out < inlen) return op - out; // RETURN rle/escape + memcpy(out, in, inlen); // no compression, use memcpy + return inlen; // RETURN outlen = inlen (memcpy) + } + + c = (a+7)/8; + PUTC(op, c); // c = bitmap length in bytes + memset(op, 0, 32); + for(m = i = 0; i != c*8; i++) // set bitmap for unused chars + if(!cnt[i]) op[i>>3] |= 1<<(i&7), rmap[m++] = i; + op += c; + for(; i != 256; i++) rmap[m++] = i; + + m--; + PUTC(op, ix); + + if(inlen > SRLE8+1) // encode + while(ip < ie-1-SRLE8) { + #if __WORDSIZE == 64 + uint64_t z; SZ64; SZ64; SZ64; SZ64; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz64(z)>>3; + #else + uint32_t z; SZ32; SZ32; SZ32; SZ32; __builtin_prefetch(ip +256, 0); + continue; + a: ip += ctz32(z)>>3; + #endif + TRLEPUT(pp, ip, m, rmap, op); + pp = ++ip; + } + + while(ip < ie-1) { + while(ip < ie-1 && ip[1] == *pp) ip++; + TRLEPUT(pp, ip, m, rmap, op); + pp = ++ip; + } + if(ip < ie) PUTC(op, *ip++); AS(ip == ie, "Fatal ip>ie=%d ", (int)(ip-ie)); + + if(op - out < inlen) + return op - out; // RETURN length = rle + memcpy(out, in, inlen); // no compression, use memcpy + return inlen; // RETURN outlen = inlen (memcpy) +} + +#undef USIZE +#undef SRLE8 +//------------------------------------- RLE 16, 32, 64 -------------------------------------------------- +#define USIZE 16 +#include "trlec.c" +#undef USIZE + +#define USIZE 32 +#include "trlec.c" +#undef USIZE + +#define USIZE 64 +#include "trlec.c" +#undef USIZE + +#else // ------------------- include RLE 16, 32, 64 +#define uint_t TEMPLATE3(uint, USIZE, _t) +#define ctout(_x_) *(uint_t *)(_x_) + +#define PUTC(_op_, _x_) ctout(_op_) = _x_, _op_ += sizeof(uint_t) +#define PUTE(_op_, _e_) do { PUTC(_op_, _e_); vlput32(_op_, 0); } while(0) + +#define SRLEPUT(_pp_, _ip_, _e_, _op_) do {\ + unsigned _r = (_ip_ - _pp_)+1;\ + if(_r >= 4) { PUTC(_op_, _e_); _r = (_r-4)+3; vlput32(_op_, _r); PUTC(_op_, pp[0]); }\ + else if(pp[0] == _e_) {\ + PUTC(_op_, _e_); _r -= 1; vlput32(_op_, _r);\ + } else while(_r--) PUTC(_op_, pp[0]);\ +} while(0) + + #if !SRLE8 +unsigned TEMPLATE2(_srlec, USIZE)(const unsigned char *__restrict cin, unsigned inlen, unsigned char *__restrict out, uint_t e) { + unsigned char *op = out; + unsigned n = inlen/sizeof(uint_t); + uint_t *in = (uint_t *)cin, *pp = in, *ip = in, *ie = in+n; + + if(!inlen) return 0; + #define SZ1 if(ip[0] != ip[1]) goto a; ++ip; + if(n > 6+1) + while(ip < ie-1-6) { // fast encode + SZ1; SZ1; SZ1; SZ1; SZ1; SZ1; __builtin_prefetch(ip +128*USIZE/8, 0); + continue; + a: + SRLEPUT(pp, ip, e, op); + pp = ++ip; + } + + while(ip < ie - 1) { // encode rest + while(ip < ie-1 && ip[1] == *pp) ip++; + SRLEPUT(pp, ip, e, op); + pp = ++ip; + } + if(ip < ie) { // last item + uint_t c = *ip++; + if(c == e) PUTE(op, e); + else PUTC(op, c); + } //AS(ip == ie,"FatalI ip!=ie=%d ", ip-ie) + #if USIZE > 8 + { unsigned char *p = (unsigned char *)ip; // remaining bytes inlen % USIZE/8 + while(p < cin+inlen) + *op++ = *p++; + } + #endif + //AS(ip == ie,"FatalI ip!=ie=%d ", ip-ie) + return op - out; +} + #endif +#undef SRLEPUT +#undef PUTC +#undef PUTE + +unsigned TEMPLATE2(srlec, USIZE)(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, uint_t e) { + unsigned l = TEMPLATE2(_srlec, USIZE)(in, inlen, out, e); + + if(l < inlen) + return l; + memcpy(out, in, inlen); + return inlen; +} +#endif + diff --git a/src/ext/for/trled.c b/src/ext/for/trled.c new file mode 100644 index 00000000000..f88606669c0 --- /dev/null +++ b/src/ext/for/trled.c @@ -0,0 +1,413 @@ +/** + Copyright (C) powturbo 2015-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - email : powturbo [AT] gmail.com + - github : https://github.com/powturbo + - homepage : https://sites.google.com/site/powturbo/ + - twitter : https://twitter.com/powturbo + + TurboRLE - "Most efficient and fastest Run Length Encoding" +**/ + #ifndef USIZE +#include + #ifdef __AVX2__ +#include + #elif defined(__AVX__) +#include + #elif defined(__SSE4_1__) +#include + #elif defined(__SSSE3__) + #ifdef __powerpc64__ +#define __SSE__ 1 +#define __SSE2__ 1 +#define __SSE3__ 1 +#define NO_WARN_X86_INTRINSICS 1 + #endif +#include + #elif defined(__SSE2__) +#include + #elif defined(__ARM_NEON) +#include +#include "sse_neon.h" + #endif + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif + +#include "trle.h" +#include "trle_.h" +//------------------------------------- RLE 8 with Escape char ------------------------------------------------------------------ +//#define MEMSAFE +#define SRLE8 32 +#define USIZE 8 +#include "trled.c" + + #if SRLE8 +#define rmemset8(_op_, _c_, _i_) while(_i_--) *_op_++ = _c_ +unsigned _srled8(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, unsigned char e) { + uint8_t *ip = in, *op = out, c, *oe = out+outlen; + uint32_t r; + + #ifdef __AVX2__ + __m256i ev = _mm256_set1_epi8(e); + #elif defined(__SSE__) + __m128i ev = _mm_set1_epi8(e); + #endif + if(outlen >= SRLE8) + while(op < out+(outlen-SRLE8)) { + #if defined(__AVX2__) || defined(__SSE__) //|| defined(__ARM_NEON) + uint32_t mask; + #ifdef __AVX2__ + __m256i v = _mm256_loadu_si256((__m256i*)ip); _mm256_storeu_si256((__m256i *)op, v); mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(v, ev)); if(mask) goto a; op += 32; ip += 32; + #elif defined(__SSE__) + __m128i v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(_mm_cmpeq_epi8(v, ev)); if(mask) goto a; ip += 16; op += 16; + #if SRLE8 >= 32 + v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(_mm_cmpeq_epi8(v, ev)); if(mask) goto a; ip += 16; op += 16; + #endif + #endif + PREFETCH(ip+512, 0); + continue; + a: r = ctz32(mask); ip += r+1; PREFETCH(ip+512, 0); + op += r; + #else + if(likely((c = *ip++) != e)) { *op++ = c; continue; } + #endif + vlget32(ip, r); + if(likely(r) >= 3) { + uint8_t c = *ip++; + r = r-3+4; + rmemset(op, c, r); + } else { r++; + rmemset8(op, e, r); + } + } + + while(op < out+outlen) + if(likely((c = *ip++) != e)) { + *op++ = c; + } else { + vlget32(ip, r); + if(likely(r) >= 3) { + c = *ip++; + r = r-3+4; + rmemset8(op, c, r); + } else { r++; + rmemset8(op, e, r); + } + } + return ip - in; +} + +static inline unsigned _srled8x(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen, unsigned char e, unsigned char ix) { + uint8_t *ip = in, *op = out, c, *oe = out+outlen; + uint32_t r; + + #ifdef __AVX2__ + __m256i ev = _mm256_set1_epi8(e); + #elif defined(__SSE__) + __m128i ev = _mm_set1_epi8(e); + #elif defined(__ARM_NEON) + uint8x8_t ev = vdup_n_u8(e); + #endif + if(outlen >= SRLE8) + while(op < out+(outlen-SRLE8)) { + #if defined(__AVX2__) || defined(__SSE__) //|| defined(__ARM_NEON) + uint32_t mask; + #ifdef __AVX2__ + __m256i v = _mm256_loadu_si256((__m256i*)ip); _mm256_storeu_si256((__m256i *)op, v); mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(v, ev)); if(mask) goto a; op += 32; ip += 32; + #elif defined(__SSE__) + __m128i v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(_mm_cmpeq_epi8(v, ev)); if(mask) goto a; ip += 16; op += 16; + #if SRLE8 >= 32 + v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(_mm_cmpeq_epi8(v, ev)); if(mask) goto a; ip += 16; op += 16; + #endif + #endif + PREFETCH(ip+512, 0); + continue; + a: r = ctz32(mask); ip += r+1; PREFETCH(ip+512, 0); + op += r; + #else + if(likely((c = *ip++) != e)) { *op++ = c; continue; } + #endif + vlget32(ip, r); + + int f = r&1; r >>= 1; + if(likely(r) >= 3) { + uint8_t y=ip[0],c = f?y:ix; ip+=f; + r = r-3+4; + rmemset(op, c, r); + } else { r++; rmemset8(op, e, r); + /*switch(r) { + case 3: *op++ = c; + case 2: *op++ = c; + case 1: *op++ = c; + case 0: *op++ = c; + }*/ + } + } + + while(op < out+outlen) + if(likely((c = *ip++) != e)) { + *op++ = c; + } else { + vlget32(ip, r); + int f = r&1; r >>= 1; + if(likely(r) >= 3) { + uint8_t c = f?ip[0]:ix; ip+=f; + r = r-3+4; + rmemset(op, c, r); + } else { r++; + rmemset8(op, e, r); + } + } + return ip - in; +} + #endif + +unsigned _srled(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen) { + return _srled8(in+1, out, outlen, *in); +} + +unsigned srled(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen) { unsigned l; + if(inlen == outlen) + memcpy(out, in, outlen); //No compression + else if(inlen == 1) + memset(out, in[0], outlen); //Only 1 char + else _srled8x(in+2, out, outlen, in[0], in[1]); //AS((ip-in) == inlen,"FatalI l>inlen %d ", (ip-in) - inlen); + return inlen; +} +//------------------------------------- TurboRLE ------------------------------------------ +unsigned _trled(const unsigned char *__restrict in, unsigned char *__restrict out, unsigned outlen) { + uint8_t rmap[256] = {0}, *op = out, *ip = in; + unsigned m = 0, i, c; + + if(!outlen) + return 0; + + if(!(c = *ip++)) + return _srled8(ip+1, out, outlen, *ip)+2; + + for(i = 0; i != c; i++) { uint8_t *pb = &rmap[i<<3]; unsigned u = ip[i],v; + v = (u >> 0) & 1; m += v; pb[0] = v?m:0; + v = (u >> 1) & 1; m += v; pb[1] = v?m:0; + v = (u >> 2) & 1; m += v; pb[2] = v?m:0; + v = (u >> 3) & 1; m += v; pb[3] = v?m:0; + v = (u >> 4) & 1; m += v; pb[4] = v?m:0; + v = (u >> 5) & 1; m += v; pb[5] = v?m:0; + v = (u >> 6) & 1; m += v; pb[6] = v?m:0; + v = (u >> 7) & 1; m += v; pb[7] = v?m:0; + } + ip += c; + for(i = c*8; i != 256; i++) rmap[i] = ++m; + + m--; + unsigned char ix = *ip++; + + if(outlen >= 32) + while(op < out+(outlen-32)) { + #if __WORDSIZE == 64 + uint64_t z = (uint64_t)rmap[ip[7]]<<56 | (uint64_t)rmap[ip[6]] << 48 | (uint64_t)rmap[ip[5]] << 40 | (uint64_t)rmap[ip[4]] << 32 | (uint32_t)rmap[ip[3]] << 24 | (uint32_t)rmap[ip[2]] << 16| (uint32_t)rmap[ip[1]] << 8| rmap[ip[0]]; + ctou64(op) = ctou64(ip); if(z) goto a; ip += 8; op += 8; + continue; + a: z = ctz64(z)>>3; + #else + uint32_t z = (uint32_t)rmap[ip[3]] << 24 | (uint32_t)rmap[ip[2]] << 16| (uint32_t)rmap[ip[1]] << 8| rmap[ip[0]]; + ctou32(op) = ctou32(ip); if(z) goto a; ip += 4; op += 4; + continue; + a: z = ctz32(z)>>3; + #endif + + ip += z; op += z; + c = rmap[*ip++]; + vlzget(ip, i, m, c-1); + if(i&1) c = ix; else c = *ip++; i = (i>>1) + TMIN; + rmemset(op,c,i); PREFETCH(ip+512, 0); + } + + while(op < out+outlen) { + if(likely(!(c = rmap[*ip]))) *op++ = *ip++; + else { + ip++; + vlzget(ip, i, m, c-1); + if(i&1) c = ix; else c = *ip++; i = (i>>1) + TMIN; + rmemset8(op,c,i); + } + } + return ip - in; +} + +unsigned trled(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen) { + if(inlen == outlen) + memcpy(out, in, outlen); + else if(inlen == 1) + memset(out, in[0], outlen); + else { + unsigned l = _trled(in, out, outlen); //AS(l == inlen,"FatalI l>inlen %d ", l - inlen); + } + return inlen; +} + +#undef USIZE +#undef rmemset +#undef SRLE8 + +//------------------------------------- RLE 16, 32, 64 -------------------------------------------------- +#define USIZE 16 +#include "trled.c" +#undef rmemset +#undef USIZE +#undef runcpy + +#define USIZE 32 +#include "trled.c" +#undef rmemset +#undef USIZE +#undef runcpy + +#define USIZE 64 +#include "trled.c" +#undef rmemset +#undef USIZE + + #else // ---------------------------- include 16, 32, 64---------------------------------------------- + #ifdef MEMSAFE +#define rmemset(_op_, _c_, _i_) while(_i_--) *_op_++ = _c_ + #elif (__AVX2__ != 0) && USIZE < 64 +#define rmemset(_op_, _c_, _i_) do {\ + __m256i cv = TEMPLATE2(_mm256_set1_epi, USIZE)(_c_); unsigned char *_p = _op_; _op_ += _i_;\ + do _mm256_storeu_si256((__m256i *)_p, cv),_p+=32; while(_p < _op_);\ +} while(0) + #elif (__SSE__ != 0 || __ARM_NEON != 0) && USIZE < 64 +#define rmemset(_op_, _c_, _i_) do { \ + __m128i *_up = (__m128i *)_op_, cv = TEMPLATE2(_mm_set1_epi, USIZE)(_c_);\ + _op_ += _i_;\ + do { _mm_storeu_si128( _up, cv); _mm_storeu_si128(_up+1, cv); _up+=2; } while(_up < (__m128i *)_op_);\ +} while(0) + #else +#define _cset64(_cc,_c_) _cc = _c_ +#define _cset32(_cc,_c_) _cc = _c_; _cc = _cc<<32|_cc +#define _cset16(_cc,_c_) _cc = _c_; _cc = _cc<<48|_cc<<32|_cc<<16|_cc +#define _cset8( _cc,_c_) _cc = (uint32_t)_c_<<24 | (uint32_t)_c_<<16 | (uint32_t)_c_<<8 | (uint32_t)_c_; _cc = _cc<<32|_cc + +#define rmemset(_op_, _c_, _i_) do { uint64_t _cc; uint8_t *_up = (uint8_t *)_op_; _op_ +=_i_;\ + TEMPLATE2(_cset, USIZE)(_cc,_c_);\ + do {\ + TEMPLATE2(ctou, USIZE)(_up) = _c_; _up += USIZE/8;\ + TEMPLATE2(ctou, USIZE)(_up) = _c_; _up += USIZE/8;\ + } while(_up < (uint8_t *)_op_);\ +} while(0) + #endif + +#define uint_t TEMPLATE3(uint, USIZE, _t) +#define ctout(_x_) *(uint_t *)(_x_) + #if !SRLE8 +unsigned TEMPLATE2(_srled, USIZE)(const unsigned char *__restrict in, unsigned char *__restrict cout, unsigned outlen, uint_t e) { + uint_t *out = (uint_t *)cout, *op = out, c; + const unsigned char *ip = in; + + #ifdef __AVX2__ + #define _mm256_set1_epi64 _mm256_set1_epi64x + __m256i ev = TEMPLATE2(_mm256_set1_epi, USIZE)(e); + #elif (defined(__SSE__) /*|| defined(__ARM_NEON)*/) + // #if USIZE != 64 + #define _mm_set1_epi64 _mm_set1_epi64x + __m128i ev = TEMPLATE2(_mm_set1_epi, USIZE)(e); + // #endif + #endif + + if(outlen >= sizeof(uint_t)*8) + while(op < out+outlen/sizeof(uint_t)-sizeof(uint_t)*8) { int r; + #if __AVX2__ != 0 && USIZE != 64 + uint32_t mask; + __m256i v = _mm256_loadu_si256((__m256i*)ip); _mm256_storeu_si256((__m256i *)op, v); mask = _mm256_movemask_epi8(TEMPLATE2(_mm256_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 32; op += 256/USIZE; + v = _mm256_loadu_si256((__m256i*)ip); _mm256_storeu_si256((__m256i *)op, v); mask = _mm256_movemask_epi8(TEMPLATE2(_mm256_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 32; op += 256/USIZE; + PREFETCH(ip+512, 0); + continue; + a: r = ctz32(mask)/(USIZE/8); + op += r; + ip += (r+1)*sizeof(uint_t); PREFETCH(ip+512, 0); + #elif (__SSE__ != 0 /*|| __ARM_NEON != 0*/) && USIZE != 64 + uint32_t mask; + __m128i v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(TEMPLATE2(_mm_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 16; op += 128/USIZE; + v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(TEMPLATE2(_mm_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 16; op += 128/USIZE; + v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(TEMPLATE2(_mm_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 16; op += 128/USIZE; + v = _mm_loadu_si128((__m128i*)ip); _mm_storeu_si128((__m128i *)op, v); mask = _mm_movemask_epi8(TEMPLATE2(_mm_cmpeq_epi,USIZE)(v, ev)); if(mask) goto a; ip += 16; op += 128/USIZE; + PREFETCH(ip+512, 0); + continue; + a: r = ctz32(mask)/(USIZE/8); + op += r; + ip += (r+1)*sizeof(uint_t); PREFETCH(ip+512, 0); + #else + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; + if(((c = ctout(ip)) == e)) goto a; ip += sizeof(uint_t); *op++ = c; PREFETCH(ip +512, 0); + continue; + a: ip += sizeof(uint_t); PREFETCH(ip +512, 0); + #endif + vlget32(ip, r); + if(likely(r) >= 3) { + c = ctout(ip); ip += sizeof(uint_t); + r = r-3+4; + rmemset(op, c, r); + } else { r++; + rmemset(op, e, r); + } + } + + while(op < out+outlen/sizeof(uint_t)) { + c = ctout(ip); ip += sizeof(uint_t); + if(likely(c != e)) { + *op++ = c; + } else { + int r; + vlget32(ip, r); + if(likely(r) >= 3) { + c = ctout(ip); ip += sizeof(uint_t); + r = r-3+4; + rmemset(op, c, r); + } else { + r++; + rmemset(op, e, r); + } + } + } + { unsigned char *p = (unsigned char *)op; + while(p < cout+outlen) *p++ = *ip++; + } + return ip - in; +} + #endif + +unsigned TEMPLATE2(srled, USIZE)(const unsigned char *__restrict in, unsigned inlen, unsigned char *__restrict out, unsigned outlen, uint_t e) { + if(inlen == outlen) + memcpy(out, in, outlen); + else if(inlen == 1) + memset(out, in[0], outlen); + else + return TEMPLATE2(_srled, USIZE)(in, out, outlen, e); + return inlen; +} + #endif + diff --git a/src/ext/for/v8.c b/src/ext/for/v8.c new file mode 100644 index 00000000000..6fc8a6152ed --- /dev/null +++ b/src/ext/for/v8.c @@ -0,0 +1,1465 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// v8.c - "Integer Compression" TurboByte 16/32 bits (SIMD Group Varint, Streamvbyte family) + #ifndef V8ENC +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#define BITUTIL_IN +#define VINT_IN +#include "conf.h" +#include "vint.h" +#include "bitutil.h" + +#define LEN32(_m_,_i_) len32[(uint8_t)(_m_>>(_i_*8))] +static const unsigned char len32[256] = { + 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9,10, + 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9,10, 8, 9,10,11, + 6, 7, 8, 9, 7, 8, 9,10, 8, 9,10,11, 9,10,11,12, + 7, 8, 9,10, 8, 9,10,11, 9,10,11,12,10,11,12,13, + 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9,10, 8, 9,10,11, + 6, 7, 8, 9, 7, 8, 9,10, 8, 9,10,11, 9,10,11,12, + 7, 8, 9,10, 8, 9,10,11, 9,10,11,12,10,11,12,13, + 8, 9,10,11, 9,10,11,12,10,11,12,13,11,12,13,14, + 6, 7, 8, 9, 7, 8, 9,10, 8, 9,10,11, 9,10,11,12, + 7, 8, 9,10, 8, 9,10,11, 9,10,11,12,10,11,12,13, + 8, 9,10,11, 9,10,11,12,10,11,12,13,11,12,13,14, + 9,10,11,12,10,11,12,13,11,12,13,14,12,13,14,15, + 7, 8, 9,10, 8, 9,10,11, 9,10,11,12,10,11,12,13, + 8, 9,10,11, 9,10,11,12,10,11,12,13,11,12,13,14, + 9,10,11,12,10,11,12,13,11,12,13,14,12,13,14,15, + 10,11,12,13,11,12,13,14,12,13,14,15,13,14,15,16 +}; + +#define _ 0 +#define SVE32(_m_) _mm_loadu_si128((__m128i*)&sve32[(_m_) & 0x3f0]) +static const ALIGNED(uint8_t, sve32[64*16],16) = { + _, 4, 8,12,13,14,15, _, _, _, _, _, _, _, _, _, + _, 1, 4, 8,12,13,14,15, _, _, _, _, _, _, _, _, + _, 1, 2, 4, 8,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 2, 3, 4, 8,12,13,14,15, _, _, _, _, _, _, + _, 4, 5, 8,12,13,14,15, _, _, _, _, _, _, _, _, + _, 1, 4, 5, 8,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 2, 4, 5, 8,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 3, 4, 5, 8,12,13,14,15, _, _, _, _, _, + _, 4, 5, 6, 8,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 4, 5, 6, 8,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8,12,13,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8,12,13,14,15, _, _, _, _, + _, 4, 5, 6, 7, 8,12,13,14,15, _, _, _, _, _, _, + _, 1, 4, 5, 6, 7, 8,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8,12,13,14,15, _, _, _, + _, 4, 8, 9,12,13,14,15, _, _, _, _, _, _, _, _, + _, 1, 4, 8, 9,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 2, 4, 8, 9,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 3, 4, 8, 9,12,13,14,15, _, _, _, _, _, + _, 4, 5, 8, 9,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 4, 5, 8, 9,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 5, 8, 9,12,13,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 5, 8, 9,12,13,14,15, _, _, _, _, + _, 4, 5, 6, 8, 9,12,13,14,15, _, _, _, _, _, _, + _, 1, 4, 5, 6, 8, 9,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,12,13,14,15, _, _, _, + _, 4, 5, 6, 7, 8, 9,12,13,14,15, _, _, _, _, _, + _, 1, 4, 5, 6, 7, 8, 9,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,12,13,14,15, _, _, + _, 4, 8, 9,10,12,13,14,15, _, _, _, _, _, _, _, + _, 1, 4, 8, 9,10,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 8, 9,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 8, 9,10,12,13,14,15, _, _, _, _, + _, 4, 5, 8, 9,10,12,13,14,15, _, _, _, _, _, _, + _, 1, 4, 5, 8, 9,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 8, 9,10,12,13,14,15, _, _, _, + _, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, _, _, + _, 1, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, + _, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, + _, 4, 8, 9,10,11,12,13,14,15, _, _, _, _, _, _, + _, 1, 4, 8, 9,10,11,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 8, 9,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 8, 9,10,11,12,13,14,15, _, _, _, + _, 4, 5, 8, 9,10,11,12,13,14,15, _, _, _, _, _, + _, 1, 4, 5, 8, 9,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 8, 9,10,11,12,13,14,15, _, _, + _, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, _, _, + _, 1, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, + _, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 +}; + +#define SVE16(_m_) _mm_loadu_si128((__m128i*)&sve16[(_m_) & 0x7f0]) +static const ALIGNED(uint8_t, sve16[128*16],16) = { + _, 2, 4, 6, 8,10,12,14,15, _, _, _, _, _, _, _, + _, 1, 2, 4, 6, 8,10,12,14,15, _, _, _, _, _, _, + _, 2, 3, 4, 6, 8,10,12,14,15, _, _, _, _, _, _, + _, 1, 2, 3, 4, 6, 8,10,12,14,15, _, _, _, _, _, + _, 2, 4, 5, 6, 8,10,12,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8,10,12,14,15, _, _, _, _, _, + _, 2, 3, 4, 5, 6, 8,10,12,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8,10,12,14,15, _, _, _, _, + _, 2, 4, 6, 7, 8,10,12,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 6, 7, 8,10,12,14,15, _, _, _, _, _, + _, 2, 3, 4, 6, 7, 8,10,12,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8,10,12,14,15, _, _, _, _, + _, 2, 4, 5, 6, 7, 8,10,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8,10,12,14,15, _, _, _, _, + _, 2, 3, 4, 5, 6, 7, 8,10,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8,10,12,14,15, _, _, _, + _, 2, 4, 6, 8, 9,10,12,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 6, 8, 9,10,12,14,15, _, _, _, _, _, + _, 2, 3, 4, 6, 8, 9,10,12,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 6, 8, 9,10,12,14,15, _, _, _, _, + _, 2, 4, 5, 6, 8, 9,10,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,12,14,15, _, _, _, _, + _, 2, 3, 4, 5, 6, 8, 9,10,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,12,14,15, _, _, _, + _, 2, 4, 6, 7, 8, 9,10,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 7, 8, 9,10,12,14,15, _, _, _, _, + _, 2, 3, 4, 6, 7, 8, 9,10,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8, 9,10,12,14,15, _, _, _, + _, 2, 4, 5, 6, 7, 8, 9,10,12,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,12,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 7, 8, 9,10,12,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,12,14,15, _, _, + _, 2, 4, 6, 8,10,11,12,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 6, 8,10,11,12,14,15, _, _, _, _, _, + _, 2, 3, 4, 6, 8,10,11,12,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 6, 8,10,11,12,14,15, _, _, _, _, + _, 2, 4, 5, 6, 8,10,11,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8,10,11,12,14,15, _, _, _, _, + _, 2, 3, 4, 5, 6, 8,10,11,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8,10,11,12,14,15, _, _, _, + _, 2, 4, 6, 7, 8,10,11,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 7, 8,10,11,12,14,15, _, _, _, _, + _, 2, 3, 4, 6, 7, 8,10,11,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8,10,11,12,14,15, _, _, _, + _, 2, 4, 5, 6, 7, 8,10,11,12,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8,10,11,12,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 7, 8,10,11,12,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8,10,11,12,14,15, _, _, + _, 2, 4, 6, 8, 9,10,11,12,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 8, 9,10,11,12,14,15, _, _, _, _, + _, 2, 3, 4, 6, 8, 9,10,11,12,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 8, 9,10,11,12,14,15, _, _, _, + _, 2, 4, 5, 6, 8, 9,10,11,12,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,11,12,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 8, 9,10,11,12,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,11,12,14,15, _, _, + _, 2, 4, 6, 7, 8, 9,10,11,12,14,15, _, _, _, _, + _, 1, 2, 4, 6, 7, 8, 9,10,11,12,14,15, _, _, _, + _, 2, 3, 4, 6, 7, 8, 9,10,11,12,14,15, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8, 9,10,11,12,14,15, _, _, + _, 2, 4, 5, 6, 7, 8, 9,10,11,12,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,11,12,14,15, _, _, + _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,14,15, _, + _, 2, 4, 6, 8,10,12,13,14,15, _, _, _, _, _, _, + _, 1, 2, 4, 6, 8,10,12,13,14,15, _, _, _, _, _, + _, 2, 3, 4, 6, 8,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 3, 4, 6, 8,10,12,13,14,15, _, _, _, _, + _, 2, 4, 5, 6, 8,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 5, 6, 8,10,12,13,14,15, _, _, _, _, + _, 2, 3, 4, 5, 6, 8,10,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8,10,12,13,14,15, _, _, _, + _, 2, 4, 6, 7, 8,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 7, 8,10,12,13,14,15, _, _, _, _, + _, 2, 3, 4, 6, 7, 8,10,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8,10,12,13,14,15, _, _, _, + _, 2, 4, 5, 6, 7, 8,10,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8,10,12,13,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 7, 8,10,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8,10,12,13,14,15, _, _, + _, 2, 4, 6, 8, 9,10,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 8, 9,10,12,13,14,15, _, _, _, _, + _, 2, 3, 4, 6, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 8, 9,10,12,13,14,15, _, _, _, + _, 2, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,12,13,14,15, _, _, + _, 2, 4, 6, 7, 8, 9,10,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 6, 7, 8, 9,10,12,13,14,15, _, _, _, + _, 2, 3, 4, 6, 7, 8, 9,10,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8, 9,10,12,13,14,15, _, _, + _, 2, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, + _, 2, 3, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,12,13,14,15, _, + _, 2, 4, 6, 8,10,11,12,13,14,15, _, _, _, _, _, + _, 1, 2, 4, 6, 8,10,11,12,13,14,15, _, _, _, _, + _, 2, 3, 4, 6, 8,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 3, 4, 6, 8,10,11,12,13,14,15, _, _, _, + _, 2, 4, 5, 6, 8,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 5, 6, 8,10,11,12,13,14,15, _, _, _, + _, 2, 3, 4, 5, 6, 8,10,11,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 5, 6, 8,10,11,12,13,14,15, _, _, + _, 2, 4, 6, 7, 8,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 6, 7, 8,10,11,12,13,14,15, _, _, _, + _, 2, 3, 4, 6, 7, 8,10,11,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 6, 7, 8,10,11,12,13,14,15, _, _, + _, 2, 4, 5, 6, 7, 8,10,11,12,13,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 7, 8,10,11,12,13,14,15, _, _, + _, 2, 3, 4, 5, 6, 7, 8,10,11,12,13,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 7, 8,10,11,12,13,14,15, _, + _, 2, 4, 6, 8, 9,10,11,12,13,14,15, _, _, _, _, + _, 1, 2, 4, 6, 8, 9,10,11,12,13,14,15, _, _, _, + _, 2, 3, 4, 6, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 2, 3, 4, 6, 8, 9,10,11,12,13,14,15, _, _, + _, 2, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 2, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, + _, 2, 3, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, _, + _, 1, 2, 3, 4, 5, 6, 8, 9,10,11,12,13,14,15, _, + _, 2, 4, 6, 7, 8, 9,10,11,12,13,14,15, _, _, _, + _, 1, 2, 4, 6, 7, 8, 9,10,11,12,13,14,15, _, _, + _, 2, 3, 4, 6, 7, 8, 9,10,11,12,13,14,15, _, _, + _, 1, 2, 3, 4, 6, 7, 8, 9,10,11,12,13,14,15, _, + _, 2, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, _, + _, 1, 2, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, + _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, _, + _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 +}; +#undef _ + +#define _ 0xff +#define SVD32(_m_,_i_) _mm_loadu_si128(svd32[(uint8_t)(_m_>>(_i_<<3))]) +static const ALIGNED(unsigned char, svd32[256][16],16) = { + { 0, _, _, _, 1, _, _, _, 2, _, _, _, 3, _, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, _, _, _, 4, _, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, _, _, _, 5, _, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, _, _, _, 6, _, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, _, _, _, 4, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, _, _, _, 5, _, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, _, _, _, 6, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, _, _, _, 7, _, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, _, _, _, 5, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, _, _, _, 6, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, _, _, 7, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, _, _, 8, _, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, _, _, _, 6, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, _, _, _, 7, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, _, _, 8, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, _, _, 9, _, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, _, _, 4, _, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, _, _, 5, _, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, _, _, 6, _, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, _, _, 7, _, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, _, _, 5, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, _, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, _, _, 7, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, _, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, _, _, 6, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, _, _, 7, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, _, _, 8, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, _, _, 9, _, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, _, _, 7, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, _, _, 9, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10, _, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, _, 5, _, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, _, 6, _, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, _, 7, _, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, _, 8, _, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, _, 6, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, _, 7, _, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, _, 8, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, _, 9, _, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, _, 7, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, _, 8, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10, _, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, _, 8, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, _, 9, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11, _, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, 5, 6, _, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, 6, 7, _, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, 7, 8, _, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, 8, 9, _, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, 6, 7, _, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, _, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, 8, 9, _, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10, _, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, 7, 8, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, 8, 9, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11, _, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10, _, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11, _, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, _, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, _, _, _, 3, 4, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, _, _, _, 4, 5, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, _, _, _, 5, 6, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, _, _, _, 6, 7, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, _, _, _, 4, 5, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, _, _, _, 5, 6, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, _, _, _, 6, 7, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, _, _, _, 7, 8, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, _, _, _, 5, 6, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, _, _, _, 6, 7, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, _, _, 7, 8, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, _, _, 8, 9, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, _, _, _, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, _, _, _, 7, 8, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, _, _, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, _, _, 9,10, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, _, _, 4, 5, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, _, _, 5, 6, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, _, _, 7, 8, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, _, _, 5, 6, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, _, _, 7, 8, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, _, _, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, _, _, 7, 8, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, _, _, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, _, _, 9,10, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, _, _, 7, 8, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, _, _, 9,10, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, _, 5, 6, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, _, 6, 7, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, _, 7, 8, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, _, 8, 9, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, _, 6, 7, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, _, 7, 8, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, _, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, _, 9,10, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, _, 8, 9, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, _, 9,10, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, 5, 6, 7, _, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, 6, 7, 8, _, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, 8, 9,10, _, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, 6, 7, 8, _, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, 8, 9,10, _, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11, _, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9, _, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, 8, 9,10, _, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12, _, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12, _, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, _, _ }, + { 0, _, _, _, 1, _, _, _, 2, _, _, _, 3, 4, 5, _ }, + { 0, 1, _, _, 2, _, _, _, 3, _, _, _, 4, 5, 6, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, _, _, _, 5, 6, 7, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, _, _, _, 6, 7, 8, _ }, + { 0, _, _, _, 1, 2, _, _, 3, _, _, _, 4, 5, 6, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, _, _, _, 5, 6, 7, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, _, _, _, 6, 7, 8, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, _, _, _, 7, 8, 9, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, _, _, _, 5, 6, 7, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, _, _, _, 6, 7, 8, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, _, _, 7, 8, 9, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, _, _, 8, 9,10, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, _, _, _, 6, 7, 8, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, _, _, _, 7, 8, 9, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, _, _, 8, 9,10, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, _, _, 9,10,11, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, _, _, 4, 5, 6, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, _, _, 5, 6, 7, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, _, _, 6, 7, 8, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, _, _, 7, 8, 9, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, _, _, 5, 6, 7, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, _, _, 7, 8, 9, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9,10, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, _, _, 6, 7, 8, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, _, _, 7, 8, 9, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, _, _, 8, 9,10, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, _, _, 9,10,11, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, _, _, 7, 8, 9, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, _, _, 9,10,11, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11,12, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, _, 5, 6, 7, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, _, 6, 7, 8, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, _, 7, 8, 9, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, _, 8, 9,10, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, _, 6, 7, 8, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, _, 7, 8, 9, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, _, 8, 9,10, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, _, 9,10,11, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10,11, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11,12, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11,12, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12,13, _ }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, 5, 6, 7, 8, _ }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, 6, 7, 8, 9, _ }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, 7, 8, 9,10, _ }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, 8, 9,10,11, _ }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, 6, 7, 8, 9, _ }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10, _ }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, 8, 9,10,11, _ }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11,12, _ }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10, _ }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11, _ }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11,12, _ }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12,13, _ }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _ }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, _ }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, _ }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, _ }, + { 0, _, _, _, 1, _, _, _, 2, _, _, _, 3, 4, 5, 6 }, + { 0, 1, _, _, 2, _, _, _, 3, _, _, _, 4, 5, 6, 7 }, + { 0, 1, 2, _, 3, _, _, _, 4, _, _, _, 5, 6, 7, 8 }, + { 0, 1, 2, 3, 4, _, _, _, 5, _, _, _, 6, 7, 8, 9 }, + { 0, _, _, _, 1, 2, _, _, 3, _, _, _, 4, 5, 6, 7 }, + { 0, 1, _, _, 2, 3, _, _, 4, _, _, _, 5, 6, 7, 8 }, + { 0, 1, 2, _, 3, 4, _, _, 5, _, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, _, _, _, 7, 8, 9,10 }, + { 0, _, _, _, 1, 2, 3, _, 4, _, _, _, 5, 6, 7, 8 }, + { 0, 1, _, _, 2, 3, 4, _, 5, _, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, _, _, 7, 8, 9,10 }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, _, _, 8, 9,10,11 }, + { 0, _, _, _, 1, 2, 3, 4, 5, _, _, _, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, _, _, _, 7, 8, 9,10 }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, _, _, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, _, _, 9,10,11,12 }, + { 0, _, _, _, 1, _, _, _, 2, 3, _, _, 4, 5, 6, 7 }, + { 0, 1, _, _, 2, _, _, _, 3, 4, _, _, 5, 6, 7, 8 }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, _, _, 7, 8, 9,10 }, + { 0, _, _, _, 1, 2, _, _, 3, 4, _, _, 5, 6, 7, 8 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, _, _, 7, 8, 9,10 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, _, _, 8, 9,10,11 }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, _, _, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, _, _, 7, 8, 9,10 }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, _, _, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, _, _, 9,10,11,12 }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, _, _, 7, 8, 9,10 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, _, _, 8, 9,10,11 }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, _, _, 9,10,11,12 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, _, _,10,11,12,13 }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, _, 5, 6, 7, 8 }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, _, 6, 7, 8, 9 }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, _, 7, 8, 9,10 }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, _, 8, 9,10,11 }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, _, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, _, 7, 8, 9,10 }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, _, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, _, 9,10,11,12 }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9,10 }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10,11 }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10,11,12 }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11,12,13 }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10,11 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11,12 }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11,12,13 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12,13,14 }, + { 0, _, _, _, 1, _, _, _, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 0, 1, _, _, 2, _, _, _, 3, 4, 5, 6, 7, 8, 9,10 }, + { 0, 1, 2, _, 3, _, _, _, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, 2, 3, 4, _, _, _, 5, 6, 7, 8, 9,10,11,12 }, + { 0, _, _, _, 1, 2, _, _, 3, 4, 5, 6, 7, 8, 9,10 }, + { 0, 1, _, _, 2, 3, _, _, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, 2, _, 3, 4, _, _, 5, 6, 7, 8, 9,10,11,12 }, + { 0, 1, 2, 3, 4, 5, _, _, 6, 7, 8, 9,10,11,12,13 }, + { 0, _, _, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10,11 }, + { 0, 1, _, _, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11,12 }, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11,12,13 }, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12,13,14 }, + { 0, _, _, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12 }, + { 0, 1, _, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13 }, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 } +}; + +#define SVD16(_m_,_i_) _mm_loadu_si128(svd16[(uint8_t)(_m_>>(_i_<<3))]) +static const ALIGNED(unsigned char, svd16[256][16],16) = { + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, _, 6, _, 7, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, _, 7, _, 8, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, _, 7, _, 8, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, _, 9, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, _, 9, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, _, 8, _, 9, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9, _,10, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, _, 9, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, _, 8, _, 9, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9, _,10, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9, _,10, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, _, 9, _,10, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10, _,11, _}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, _, 9, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, _, 8, _, 9, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9, _,10, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9, _,10, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, _, 9, _,10, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10, _,11, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9, _,10, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, _, 9, _,10, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10, _,11, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10, _,11, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9, _,10, _,11, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11, _,12, _}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, _, 9, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, 7, 8, _, 9, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9, _,10, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9, _,10, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, 8, 9, _,10, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10, _,11, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9, _,10, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9, _,10, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10, _,11, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10, _,11, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10, _,11, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11, _,12, _}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9, _,10, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, 8, 9, _,10, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10, _,11, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10, _,11, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, 9,10, _,11, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11, _,12, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10, _,11, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10, _,11, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11, _,12, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11, _,12, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _,12, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, _,13, _}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, _, 7, 8, 9, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, _, 7, 8, 9, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, 9,10, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, 9,10, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, _, 8, 9,10, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9,10,11, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, 9,10, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, _, 8, 9,10, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9,10,11, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9,10,11, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, _, 9,10,11, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10,11,12, _}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, 9,10, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, _, 8, 9,10, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9,10,11, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10,11, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, _, 9,10,11, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11,12, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9,10,11, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, _, 9,10,11, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10,11,12, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11,12, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9, _,10,11,12, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12,13, _}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, 9,10, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, 7, 8, 9,10, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9,10,11, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9,10,11, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, 8, 9,10,11, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10,11,12, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9,10,11, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9,10,11, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10,11,12, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10,11,12, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10,11,12, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11,12,13, _}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10, _}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9,10,11, _}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, 8, 9,10,11, _}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10,11,12, _}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11, _}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11,12, _}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, 9,10,11,12, _}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12,13, _}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11, _}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10,11,12, _}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10,11,12, _}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11,12,13, _}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, _}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, _}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, _}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, _}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, _, 6, _, 7, 8}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, _, 7, _, 8, 9}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, _, 7, _, 8, 9}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, _, 9,10}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, 9}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, _, 9,10}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, _, 8, _, 9,10}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9, _,10,11}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, 9}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, _, 9,10}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, _, 8, _, 9,10}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9, _,10,11}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9,10}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9, _,10,11}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, _, 9, _,10,11}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10, _,11,12}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, 9}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, _, 9,10}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, _, 8, _, 9,10}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9, _,10,11}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9,10}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9, _,10,11}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, _, 9, _,10,11}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10, _,11,12}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9,10}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9, _,10,11}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, _, 9, _,10,11}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10, _,11,12}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10,11}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10, _,11,12}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9, _,10, _,11,12}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11, _,12,13}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, 9}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, _, 9,10}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, 7, 8, _, 9,10}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9, _,10,11}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9,10}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9, _,10,11}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, 8, 9, _,10,11}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10, _,11,12}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9, _,10,11}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9, _,10,11}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10, _,11,12}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10, _,11,12}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10, _,11,12}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11, _,12,13}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9,10}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9, _,10,11}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, 8, 9, _,10,11}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10, _,11,12}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10,11}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10, _,11,12}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, 9,10, _,11,12}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11, _,12,13}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10, _,11,12}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10, _,11,12}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11, _,12,13}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11, _,12,13}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, _,12,13}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, _,13,14}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, 9}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, _, 7, 8, 9,10}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, _, 7, 8, 9,10}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, _, 8, 9,10,11}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9,10}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, _, 8, 9,10,11}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, _, 8, 9,10,11}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, _, 9,10,11,12}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9,10}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, _, 8, 9,10,11}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, _, 8, 9,10,11}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, _, 9,10,11,12}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10,11}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, _, 9,10,11,12}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, _, 9,10,11,12}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9, _,10,11,12,13}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9,10}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, _, 8, 9,10,11}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, _, 8, 9,10,11}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, _, 9,10,11,12}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10,11}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, _, 9,10,11,12}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, _, 9,10,11,12}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9, _,10,11,12,13}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10,11}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, _, 9,10,11,12}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, _, 9,10,11,12}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9, _,10,11,12,13}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11,12}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9, _,10,11,12,13}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9, _,10,11,12,13}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, _,11,12,13,14}, + { 0, _, 1, _, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9,10}, + { 0, 1, 2, _, 3, _, 4, _, 5, _, 6, 7, 8, 9,10,11}, + { 0, _, 1, 2, 3, _, 4, _, 5, _, 6, 7, 8, 9,10,11}, + { 0, 1, 2, 3, 4, _, 5, _, 6, _, 7, 8, 9,10,11,12}, + { 0, _, 1, _, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10,11}, + { 0, 1, 2, _, 3, 4, 5, _, 6, _, 7, 8, 9,10,11,12}, + { 0, _, 1, 2, 3, 4, 5, _, 6, _, 7, 8, 9,10,11,12}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, _, 8, 9,10,11,12,13}, + { 0, _, 1, _, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11}, + { 0, 1, 2, _, 3, _, 4, 5, 6, _, 7, 8, 9,10,11,12}, + { 0, _, 1, 2, 3, _, 4, 5, 6, _, 7, 8, 9,10,11,12}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, _, 8, 9,10,11,12,13}, + { 0, _, 1, _, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, _, 8, 9,10,11,12,13}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, _, 8, 9,10,11,12,13}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, _, 9,10,11,12,13,14}, + { 0, _, 1, _, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10,11}, + { 0, 1, 2, _, 3, _, 4, _, 5, 6, 7, 8, 9,10,11,12}, + { 0, _, 1, 2, 3, _, 4, _, 5, 6, 7, 8, 9,10,11,12}, + { 0, 1, 2, 3, 4, _, 5, _, 6, 7, 8, 9,10,11,12,13}, + { 0, _, 1, _, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11,12}, + { 0, 1, 2, _, 3, 4, 5, _, 6, 7, 8, 9,10,11,12,13}, + { 0, _, 1, 2, 3, 4, 5, _, 6, 7, 8, 9,10,11,12,13}, + { 0, 1, 2, 3, 4, 5, 6, _, 7, 8, 9,10,11,12,13,14}, + { 0, _, 1, _, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12}, + { 0, 1, 2, _, 3, _, 4, 5, 6, 7, 8, 9,10,11,12,13}, + { 0, _, 1, 2, 3, _, 4, 5, 6, 7, 8, 9,10,11,12,13}, + { 0, 1, 2, 3, 4, _, 5, 6, 7, 8, 9,10,11,12,13,14}, + { 0, _, 1, _, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13}, + { 0, 1, 2, _, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14}, + { 0, _, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14}, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15} +}; +#undef _ + +#define LENBLOCK // All length keys encoded at the beginning of the buffer. + #ifdef LENBLOCK +#define OP out +#define IP in +#define IPINC 0 +#define DATABEG(_p_,_n_,_s_) _p_ + (((_n_)+(_s_-1))/_s_) +#define PNEXT(_p0_,_p_,_i_) _p0_ += _i_ +#define PNEXTA(_p0_,_p_,_i_) 0 +#define PNEXTB(_p0_,_i_) _p0_ += _i_ + #else +#define OP op +#define IP ip +#define IPINC 8 +#define DATABEG(_p_,_n_,_s_) _p_ +#define PNEXT(_p0_,_p_,_i_) _p0_ = _p_ +#define PNEXTA(_p0_,_p_,_i_) _p0_ = _p_, _p_+=_i_ +#define PNEXTB(_p0_,_i_) + #endif + +//----------------------------------- Templates parameter macros ----------------------------------------------------------------- +#define V8DELTA32 +#define V8DELTA16 +#define V8ENC v8enc +#define V8DEC v8dec +#define VE16(_x_) v = _x_ +#define VD16(_x_) _x_ +#define VE32(_x_) v = _x_ +#define VD32(_x_) _x_ +#define VEINI128v32 +#define VEINI256v32 +#define VE128v32(_v_,_sv_) +#define VE256v32(_v_,_sv_) +#define VDINI128v32 +#define VDINI256v32 +#define VD128v32(_ov_,_sv_) +#define VD256v32(_ov_,_sv_) + +#define VEINI128v16 +#define VDINI128v16 +#define VE128v16(_ov_,_sv_) +#define VD128v16(_ov_,_sv_) +#include "v8.c" + +#define V8DELTA32 ,uint32_t start +#define V8DELTA16 ,uint16_t start + +#define V8ENC v8zenc //------------ zigzag ----------------------------- +#define V8DEC v8zdec +#define VDELTA 0 + +#define VEINI128v16 __m128i sv = _mm_set1_epi16(start); const __m128i zv = _mm_setzero_si128() +#define VEINI128v32 __m128i sv = _mm_set1_epi32(start); const __m128i zv = _mm_setzero_si128() +#define VEINI256v32 __m256i sv = _mm256_set1_epi32(start) + +#define VE16(_x_) v = zigzagenc16((_x_)-start); start = _x_ +#define VE32(_x_) v = zigzagenc32((_x_)-start); start = _x_ + +#define VD16(_x_) (start += zigzagdec16(_x_)) +#define VD32(_x_) (start += zigzagdec32(_x_)) + +#define VE128v16(_iv_,_sv_) { __m128i _tv = mm_delta_epi16(_iv_,_sv_); _sv_ = _iv_; _iv_ = mm_zzage_epi16(_tv); } +#define VE128v32(_iv_,_sv_) { __m128i _tv = mm_delta_epi32(_iv_,_sv_); _sv_ = _iv_; _iv_ = mm_zzage_epi32(_tv); } +#define VE256v32(_iv_,_sv_) { __m256i _tv = mm256_delta_epi32(_iv_,_sv_); _sv_ = _iv_; _iv_ = mm256_zzage_epi32(_tv); } + +#define VDINI128v16 __m128i sv = _mm_set1_epi16(start); const __m128i zv = _mm_setzero_si128() +#define VDINI128v32 __m128i sv = _mm_set1_epi32(start); const __m128i zv = _mm_setzero_si128() +#define VDINI256v32 __m256i sv = _mm256_set1_epi32(start); const __m128i zv = _mm256_setzero_si256() + +#define VD128v16(_v_,_sv_) _v_ = mm_zzagd_epi16( _v_); _sv_ = mm_scan_epi16(_v_,_sv_); _v_ = _sv_ +#define VD128v32(_v_,_sv_) _v_ = mm_zzagd_epi32( _v_); _sv_ = mm_scan_epi32(_v_,_sv_); _v_ = _sv_ +#define VD256v32(_v_,_sv_) _v_ = mm256_zzagd_epi32(_v_); _sv_ = mm256_scan_epi32(_v_,_sv_, zv); _v_ = _sv_ + +#include "v8.c" + +#define V8ENC v8xenc //------------ xor ----------------------------- +#define V8DEC v8xdec +#define VDELTA 0 + +#define VEINI128v16 __m128i sv = _mm_set1_epi16(start); +#define VEINI128v32 __m128i sv = _mm_set1_epi32(start); +#define VEINI256v32 __m256i sv = _mm256_set1_epi32(start) + +#define VE16(_x_) v = (_x_)^start; start = _x_ +#define VE32(_x_) v = (_x_)^start; start = _x_ + +#define VD16(_x_) (start ^= _x_) +#define VD32(_x_) (start ^= _x_) + +#define VE128v16(_iv_,_sv_) { __m128i _tv = _mm_xor_si128(_iv_,_sv_); _sv_ = _iv_; _iv_ = _tv; } +#define VE128v32(_iv_,_sv_) { __m128i _tv = _mm_xor_si128(_iv_,_sv_); _sv_ = _iv_; _iv_ = _tv; } +#define VE256v32(_iv_,_sv_) { __m256i _tv = _mm256_xor_si256(_iv_,_sv_); _sv_ = _iv_; _iv_ = _tv; } + +#define VDINI128v16 __m128i sv = _mm_set1_epi16(start); +#define VDINI128v32 __m128i sv = _mm_set1_epi32(start); +#define VDINI256v32 __m256i sv = _mm256_set1_epi32(start); + +#define VD128v16(_v_,_sv_) _v_ = _sv_ = _mm_xor_si128(_v_,_sv_); +#define VD128v32(_v_,_sv_) _v_ = _sv_ = _mm_xor_si128(_v_,_sv_); +#define VD256v32(_v_,_sv_) _v_ = _sv_ = _mm256_xor_si256(_v_,_sv_); + +#include "v8.c" + + +#define V8ENC v8denc //---------- delta ---------------------------------- +#define V8DEC v8ddec +#define VE16(_x_) v = (_x_)-start; start = _x_ +#define VE32(_x_) VE16(_x_) +#define VD16(_x_) (start += _x_) +#define VD32(_x_) VD16(_x_) + +#define VEINI128v16 __m128i sv = _mm_set1_epi16(start) +#define VEINI128v32 __m128i sv = _mm_set1_epi32(start) +#define VEINI256v32 __m256i sv = _mm256_set1_epi32(start) + +#define VE128v16(_v_,_sv_) { __m128i _tv = mm_delta_epi16(_v_,_sv_); _sv_ = _v_; _v_ = _tv; } +#define VE128v32(_v_,_sv_) { __m128i _tv = mm_delta_epi32(_v_,_sv_); _sv_ = _v_; _v_ = _tv; } +#define VE256v32(_v_,_sv_) { __m256i _tv = mm256_delta_epi32(_v_,_sv_); _sv_ = _v_; _v_ = _tv; } + +#define VDINI128v16 __m128i sv = _mm_set1_epi16(start); const __m128i zv = _mm_setzero_si128() +#define VDINI128v32 __m128i sv = _mm_set1_epi32(start); const __m128i zv = _mm_setzero_si128() +#define VDINI256v32 __m256i sv = _mm256_set1_epi32(start); const __m128i zv = _mm256_setzero_si256() + +#define VD128v16(_v_,_sv_) _sv_ = mm_scan_epi16(_v_,_sv_); _v_ = _sv_ +#define VD128v32(_v_,_sv_) _sv_ = mm_scan_epi32(_v_,_sv_); _v_ = _sv_ +#define VD256v32(_v_,_sv_) _sv_ = mm256_scan_epi32(_v_,_sv_, zv); _v_ = _sv_ +#include "v8.c" + +#define V8ENC v8d1enc // delta 1 +#define V8DEC v8d1dec +#define VDELTA 1 + +#define VE16(_x_) v = (_x_)-start-VDELTA; start = _x_ +#define VE32(_x_) VE16(_x_) +#define VD16(_x_) (start += _x_+VDELTA) +#define VD32(_x_) VD16(_x_) + +#define VEINI128v16 __m128i sv = _mm_set1_epi16(start); const __m128i cv1_16 = _mm_set1_epi16(1) +#define VEINI128v32 __m128i sv = _mm_set1_epi32(start); const __m128i cv1_32 = _mm_set1_epi32(1) +#define VEINI256v32 __m256i sv = _mm256_set1_epi32(start); const __m128i cv1_32 = _mm256_set1_epi32(1) + +#define VE128v16(_v_,_sv_) { __m128i _tv = _mm_sub_epi16(mm_delta_epi16(_v_,_sv_),cv1_16); _sv_ = _v_; _v_ = _tv; } +#define VE128v32(_v_,_sv_) { __m128i _tv = _mm_sub_epi32(mm_delta_epi32(_v_,_sv_),cv1_32); _sv_ = _v_; _v_ = _tv; } +#define VE256v32(_v_,_sv_) { __m256i _tv = _mm256_sub_epi32(mm256_delta_epi32(_v_,_sv_),cv1_32); _sv_ = _v_; _v_ = _tv; } + +#define VDINI128v16 __m128i sv = _mm_set1_epi16(start); const __m128i zv = _mm_setzero_si128(), cvi = _mm_set_epi16(8,7,6,5,4,3,2,1) +#define VDINI128v32 __m128i sv = _mm_set1_epi32(start); const __m128i zv = _mm_setzero_si128(), cvi = _mm_set_epi32( 4,3,2,1) +#define VDINI256v32 __m256i sv = _mm256_set1_epi32(start); const __m128i zv = _mm256_setzero_si256(), cvi = _mm256_set_epi32(8,7,6,5,4,3,2,1) + +#define VD128v16(_v_,_sv_) _sv_ = mm_scani_epi16(_v_,_sv_, cvi); _v_ = _sv_ +#define VD128v32(_v_,_sv_) _sv_ = mm_scani_epi32(_v_,_sv_, cvi); _v_ = _sv_ +#define VD256v32(_v_,_sv_) _sv_ = mm256_scani_epi32(_v_,_sv_, cvi); _v_ = _sv_ +#include "v8.c" + +#include "bitpack.h" +#ifndef min +#define min(x,y) (((x)<(y)) ? (x) : (y)) +#define max(x,y) (((x)>(y)) ? (x) : (y)) +#endif +#define PAD8(_x_) ( (((_x_)+8-1)/8) ) +// 0-0x1f: bitpacking, 0xff: EOS, 0xfe/0x00 = memcpy, 0xfd:varint, 0xf0|0000-0100: constant + +#define _V8E(in, n, out, _csize_, _usize_, _bit_, _bitpackv_, _bitpack_) {\ + unsigned char *op = out; if(!n) return 0;\ + for(ip = in; ip < in+n;) { PREFETCH(ip+512,0);\ + unsigned _b, iplen = (in+n) - ip; iplen = min(iplen,_csize_);\ + o = TEMPLATE2(_bit_,_usize_)(ip, iplen, &x); _b = TEMPLATE2(bsr,_usize_)(o);\ + if(!x) { /*st++;*/ \ + _b = (_b+7)/8; *op++ = 0xf0 | _b; \ + TEMPLATE2(ctou, _usize_)(op) = ip[0];\ + op += _b; \ + } else {\ + if(_b <= (_usize_==16?9:10) ) goto a;\ + unsigned char *sp = op; *op++ = 0xfd; op = TEMPLATE2(v8enc, _usize_)(ip, iplen, op);\ + if(op-sp >= PAD8(_b*iplen)+1) { op = sp; a:*op++ = _b; op = iplen == _csize_?TEMPLATE2(_bitpackv_, _usize_)(ip, _csize_, op, _b):\ + TEMPLATE2(_bitpack_, _usize_)(ip, iplen, op, _b); }\ + }\ + ip += iplen;\ + if(op >= out + n*(_usize_/8)) { op = out; *op++ = 0xfe; memcpy(op, in, n*(_usize_/8)); op += n*(_usize_/8); break; }\ + } \ + return op - out;\ +} + +#define _V8DE(in, n, out, _csize_, _usize_, _v8enc_, _bitd_, _bitpackv_, _bitpack_,_delta_) { if(!n) return 0;\ + unsigned char *op = out;\ + start = *in++; uint64_t start64 = start; start64++; TEMPLATE2(vbxput, _usize_)(op, start64);\ + for(n--,ip = in; ip < in + n; ) { PREFETCH(ip+512,0);\ + unsigned _b, iplen = (in+n) - ip; iplen = min(iplen,_csize_);\ + o = TEMPLATE2(_bitd_, _usize_)(ip, iplen, &x, start); _b = TEMPLATE2(bsr,_usize_)(o);\ + if(!x) { _b = (_b+7)/8; /*constant*/\ + *op++ = 0xf0 | _b;\ + TEMPLATE2(ctou, _usize_)(op) = (ip[0]-start)-_delta_; op += _b; \ + } else { \ + if(_b <= (_usize_==16?9:10) ) goto a;\ + unsigned char *sp = op; *op++ = 0xfd; op = TEMPLATE2(_v8enc_, _usize_)(ip, iplen, op, start); /*TurboByte*/\ + if(op-sp >= PAD8(_b*iplen)+1) { op = sp; a:*op++ = _b; op = iplen == _csize_?TEMPLATE2(_bitpackv_, _usize_)(ip, _csize_, op, start, _b):/*TurboPackV*/\ + TEMPLATE2(_bitpack_, _usize_)(ip, iplen, op, start, _b);/*TurboPack*/\ + }\ + }\ + ip += iplen; start = ip[-1];\ + if(op >= out + (n+1)*(_usize_/8)+1) { op = out; *op++ = 0; n++; in--; memcpy(op, in, n*(_usize_/8)); op += n*(_usize_/8); break; } /*overflow->memcpy*/\ + }\ + return op - out;\ +} + +size_t v8nenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8E( in, n, out, 128, 16, bit, bitpack, bitpack); } +size_t v8nenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8E( in, n, out, 128, 32, bit, bitpack, bitpack); } + +size_t v8ndenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8denc, bitd, bitdpack, bitdpack,0); } +size_t v8ndenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8denc, bitd, bitdpack, bitdpack,0); } + +size_t v8nd1enc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8d1enc, bitd1, bitd1pack, bitd1pack,1); } +size_t v8nd1enc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8d1enc, bitd1, bitd1pack, bitd1pack,1); } + +size_t v8nzenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8zenc, bitz, bitzpack, bitzpack,0); } +size_t v8nzenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8zenc, bitz, bitzpack, bitzpack,0); } + +//size_t v8nxenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8xenc, bitx, bitxpack, bitxpack,0); } +//size_t v8nxenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8xenc, bitx, bitxpack, bitxpack,0); } +//---- +size_t v8nenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8E( in, n, out, 128, 16, bit, bitpack128v, bitpack); } +size_t v8nenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8E( in, n, out, 128, 32, bit, bitpack128v, bitpack); } + +size_t v8ndenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8denc, bitd, bitdpack128v, bitdpack,0); } +size_t v8ndenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8denc, bitd, bitdpack128v, bitdpack,0); } + +size_t v8nd1enc128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8d1enc, bitd1, bitd1pack128v,bitd1pack,1); } +size_t v8nd1enc128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8d1enc, bitd1, bitd1pack128v,bitd1pack,1); } + +size_t v8nzenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8zenc, bitz, bitzpack128v, bitzpack,0); } +size_t v8nzenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8zenc, bitz, bitzpack128v, bitzpack,0); } + +//size_t v8nxenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out) { uint16_t *ip,start,o,x; _V8DE(in, n, out, 128, 16, v8xenc, bitx, bitxpack128v, bitxpack,0); } +//size_t v8nxenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 128, 32, v8xenc, bitx, bitxpack128v, bitxpack,0); } +//------- + #if defined(__i386__) || defined(__x86_64__) +size_t v8nenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8E( in, n, out, 256, 32, bit, bitpack256v, bitpack); } +size_t v8ndenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 256, 32, v8denc, bitd, bitdpack256v, bitdpack,0); } +size_t v8nd1enc256v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 256, 32, v8d1enc, bitd1, bitd1pack256v,bitd1pack,1); } +size_t v8nzenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 256, 32, v8zenc, bitz, bitzpack256v, bitzpack,0); } +//size_t v8nxenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out) { uint32_t *ip,start,o,x; _V8DE(in, n, out, 256, 32, v8xenc, bitx, bitxpack256v, bitxpack,0); } + #endif + +#define _V8D(in, n, out, _csize_, _usize_, _bitunpackv_, _bitunpack_) {\ + unsigned char *ip = in; if(!n) return 0;\ + if(*in == 0xfe) { ip = in+1; memcpy(out,ip, n*(_usize_/8)); ip+=n*(_usize_/8); }\ + else for(op = out, out += n; op < out;) { PREFETCH(ip+512,0);\ + unsigned oplen = min(out-op,_csize_), _b = *ip++;\ + if((_b & 0xf8)==0xf0) { _b &= 0x7; \ + unsigned _u = TEMPLATE2(ctou,_usize_)(ip) & ((1ull<<(_b*8))-1);\ + ip+=_b;\ + BITZERO32(op, oplen, _u); \ + } else {\ + if(_b == 0xfd) ip = TEMPLATE2(v8dec, _usize_)(ip, oplen, op);\ + else ip = oplen == _csize_?TEMPLATE2(_bitunpackv_, _usize_)(ip, _csize_, op, _b):\ + TEMPLATE2(_bitunpack_, _usize_)(ip, oplen, op, _b);\ + }\ + op += oplen;\ + }\ + return ip - in;\ +} + +#define BITIZERO(op, n, start, _u_) { for(int i=0; i < n; i++) op[i] = (start += _u_); } + +#define _V8DD(in, n, out, _csize_, _usize_, _v8dec_, _bitunpackv_, _bitunpack_, _delta_) { if(!n) return 0;\ + unsigned char *ip = in;\ + uint64_t start64; TEMPLATE2(vbxget, _usize_)(ip, start64);\ + if(!start64) { memcpy(out, ip, n*(_usize_/8)); ip += n*(_usize_/8); }\ + else { start = start64 - 1;\ + for(*out++ = start,--n, op = out, out+=n; op < out; ) { PREFETCH(ip+512,0);\ + unsigned oplen = min(out-op,_csize_),_b=*ip++;\ + if((_b & 0xf8)==0xf0) { \ + _b &= 0x7;\ + unsigned _u = (TEMPLATE2(ctou,_usize_)(ip) & ((1ull<<(_b*8))-1))+_delta_;\ + ip += _b;\ + BITIZERO(op, oplen, start, _u);\ + } else {\ + if(_b==0xfd) ip = TEMPLATE2(_v8dec_, _usize_)(ip, oplen, op, start);\ + else ip = oplen == _csize_?TEMPLATE2(_bitunpackv_, _usize_)(ip, _csize_, op, start, _b):\ + TEMPLATE2(_bitunpack_, _usize_)(ip, oplen, op, start, _b);\ + } op += oplen; start = op[-1];\ + }\ + }\ + return ip - in;\ +} + +size_t v8ndec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op; _V8D(in, n, out, 128, 16, bitunpack, bitunpack); } +size_t v8ndec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _V8D(in, n, out, 128, 32, bitunpack, bitunpack); } + +size_t v8nddec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8ddec, bitdunpack, bitdunpack, 0); } +size_t v8nddec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8ddec, bitdunpack, bitdunpack, 0); } + +size_t v8nd1dec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8d1dec,bitd1unpack, bitd1unpack,1); } +size_t v8nd1dec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8d1dec,bitd1unpack, bitd1unpack,1); } + +size_t v8nzdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8zdec, bitzunpack, bitzunpack, 0); } +size_t v8nzdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8zdec, bitzunpack, bitzunpack, 0); } + +//size_t v8nxdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8xdec, bitxunpack, bitxunpack, 0); } +//size_t v8nxdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8xdec, bitxunpack, bitxunpack, 0); } +//--------- +size_t v8ndec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op; _V8D(in, n, out, 128, 16, bitunpack128v, bitunpack); } +size_t v8ndec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _V8D(in, n, out, 128, 32, bitunpack128v, bitunpack); } + +size_t v8nddec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8ddec, bitdunpack128v, bitdunpack, 0); } +size_t v8nddec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8ddec, bitdunpack128v, bitdunpack, 0); } + +size_t v8nd1dec128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8d1dec,bitd1unpack128v,bitd1unpack,1); } +size_t v8nd1dec128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8d1dec,bitd1unpack128v,bitd1unpack,1); } + +size_t v8nzdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8zdec, bitzunpack128v, bitzunpack, 0); } +size_t v8nzdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8zdec, bitzunpack128v, bitzunpack, 0); } + +//size_t v8nxdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out) { uint16_t *op,start; _V8DD(in, n, out, 128, 16, v8xdec, bitxunpack128v, bitxunpack, 0); } +//size_t v8nxdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 128, 32, v8xdec, bitxunpack128v, bitxunpack, 0); } +//--------- + #if defined(__i386__) || defined(__x86_64__) +size_t v8ndec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op; _V8D( in, n, out, 256, 32, bitunpack256v, bitunpack); } +size_t v8nddec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 256, 32, v8ddec, bitdunpack256v, bitdunpack, 0); } +size_t v8nd1dec256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 256, 32, v8d1dec,bitd1unpack256v,bitd1unpack,1); } +size_t v8nzdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 256, 32, v8zdec, bitzunpack256v, bitzunpack, 0); } +//size_t v8nxdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out) { uint32_t *op,start; _V8DD(in, n, out, 256, 32, v8xdec, bitxunpack256v, bitxunpack, 0); } + #endif + #else //---------------------------------------------- Templates ------------------------------------------------------------- +#define BN32(x) (x?(__bsr32(x)/8):0) +#define VLE1(_m_) { VE32(ip[0]); unsigned _b = BN32(v); ctou32(op) = v; op += _b+1; _m_ |= _b<<((ip-sp)*2); } +#define VLE4(_i_) { unsigned _b,_m;\ + VE32(ip[_i_+0]); _b = BN32(v); ctou32(op) = v; op += _b+1; _m = _b; \ + VE32(ip[_i_+1]); _b = BN32(v); ctou32(op) = v; op += _b+1; _m |= _b<<2;\ + VE32(ip[_i_+2]); _b = BN32(v); ctou32(op) = v; op += _b+1; _m |= _b<<4;\ + VE32(ip[_i_+3]); _b = BN32(v); ctou32(op) = v; op += _b+1; _m |= _b<<6;\ + *out++ = _m;\ +} + +#define mm256_packus_epi16(a, b) _mm256_permute4x64_epi64(_mm256_packus_epi16(a, b), _MM_SHUFFLE(3, 1, 2, 0)) + +unsigned char *TEMPLATE2(V8ENC,32)(uint32_t *__restrict in, unsigned n, unsigned char *__restrict out V8DELTA32) { + uint32_t *ip,v; + unsigned char *op = DATABEG(out,n,4),*sp=out; + + #if 0 //def __AVX2__ // ---------------------------------------------------------------------------------------------- + VEINI256v32; const __m256i cv1_8 = _mm256_set1_epi8(1), cv7f00 = _mm256_set1_epi16(0x7F00), zv = _mm256_setzero_si256(); + for(ip = in; ip != in+(n&~(32-1)); ip += 32) { PREFETCH(ip+512,0); + __m256i iv0 = _mm256_loadu_si256(ip ), + iv1 = _mm256_loadu_si256(ip+ 8); VE256v32(iv0); VE256v32(iv1); + __m256i iv2 = _mm256_loadu_si256(ip+16), + iv3 = _mm256_loadu_si256(ip+24); VE256v32(iv2); VE256v32(iv3); + __m256i mv0 = mm256_packus_epi16(_mm256_min_epu8(iv0,cv1_8), _mm256_min_epu8(iv1,cv1_8)); //mv0 = _mm256_permute4x64_epi64(mv0, _MM_SHUFFLE(3, 1, 2, 0)); + mv0 = _mm256_min_epi16(mv0, cv1_8); mv0 = _mm256_adds_epu16(mv0, cv7f00); + uint32_t m0 = _mm256_movemask_epi8(mv0); + + __m256i ov0 = _mm256_castsi128_si256( SVE32(m0 << 4)); + ov0 = _mm256_inserti128_si256(ov0, SVE32(m0 >> 4),1); + __m256i ov1 = _mm256_castsi128_si256( SVE32(m0 >>12)); + ov1 = _mm256_inserti128_si256(ov1, SVE32(m0 >>20),1); + + __m256i mv1 = _mm256_packus_epi16(_mm256_min_epu8(iv2,cv1_8), _mm256_min_epu8(iv3,cv1_8)); mv1 = _mm256_permute4x64_epi64(mv1, _MM_SHUFFLE(3, 1, 2, 0)); + mv1 = _mm256_min_epi16(mv1, cv1_8); mv1 = _mm256_adds_epu16(mv1, cv7f00); + uint32_t m1 = _mm256_movemask_epi8(mv1); + __m256i ov2 = _mm256_castsi128_si256( SVE32(m1 << 4)); + ov2 = _mm256_inserti128_si256(ov2, SVE32(m1 >> 4),1); + __m256i ov3 = _mm256_castsi128_si256( SVE32(m1 >>12)); + ov3 = _mm256_inserti128_si256(ov3, SVE32(m1 >>20),1); + + ov0 = _mm256_shuffle_epi8(iv0,ov0); + ov1 = _mm256_shuffle_epi8(iv1,ov1); + + ctou32(OP) = m0; ctou32(OP+4) = m1; OP += 8; + _mm_storeu_si128((__m128i *)op, _mm256_castsi256_si128( ov0)); op += LEN32(m0,0); + _mm_storeu_si128((__m128i *)op, _mm256_extracti128_si256(ov0,1)); op += LEN32(m0,1); + _mm_storeu_si128((__m128i *)op, _mm256_castsi256_si128( ov1)); op += LEN32(m0,2); + _mm_storeu_si128((__m128i *)op, _mm256_extracti128_si256(ov1,1)); op += LEN32(m0,3); + + ov2 = _mm256_shuffle_epi8(iv2,ov2); + ov3 = _mm256_shuffle_epi8(iv3,ov3); + _mm_storeu_si128((__m128i *)op, _mm256_castsi256_si128( ov2)); op += LEN32(m1,0); + _mm_storeu_si128((__m128i *)op, _mm256_extracti128_si256(ov2,1)); op += LEN32(m1,1); + _mm_storeu_si128((__m128i *)op, _mm256_castsi256_si128( ov3)); op += LEN32(m1,2); + _mm_storeu_si128((__m128i *)op, _mm256_extracti128_si256(ov3,1)); op += LEN32(m1,3); + } + #elif defined(__SSSE3__) || defined(__ARM_NEON) // https://gist.github.com/aqrit/746d2f5e4ad1909230e2283272333dc1 + VEINI128v32; const __m128i cv1_8 = _mm_set1_epi8(1), cv7f00 = _mm_set1_epi16(0x7f00); + for(ip = in; ip != in+(n&~(32-1)); ip += 32, PNEXT(out,op,8) ) { + __m128i iv0 = _mm_loadu_si128(ip ), + iv1 = _mm_loadu_si128(ip+ 4); + __m128i iv2 = _mm_loadu_si128(ip+ 8), + iv3 = _mm_loadu_si128(ip+12); VE128v32(iv0,sv); VE128v32(iv1,sv); VE128v32(iv2,sv); VE128v32(iv3,sv); //delta,zigzag,... + __m128i mv0 = _mm_packus_epi16(_mm_min_epu8(iv0,cv1_8), _mm_min_epu8(iv1,cv1_8)); mv0 = _mm_min_epi16( mv0, cv1_8); mv0 = _mm_adds_epu16(mv0, cv7f00); + __m128i mv1 = _mm_packus_epi16(_mm_min_epu8(iv2,cv1_8), _mm_min_epu8(iv3,cv1_8)); mv1 = _mm_min_epi16( mv1, cv1_8); mv1 = _mm_adds_epu16(mv1, cv7f00); + uint16_t m0 = _mm_movemask_epi8(mv0); + uint16_t m1 = _mm_movemask_epi8(mv1); + __m128i iv4 = _mm_loadu_si128(ip+16), + iv5 = _mm_loadu_si128(ip+20); + __m128i iv6 = _mm_loadu_si128(ip+24), + iv7 = _mm_loadu_si128(ip+28); VE128v32(iv4,sv); VE128v32(iv5,sv); VE128v32(iv6,sv); VE128v32(iv7,sv); + __m128i mv2 = _mm_packus_epi16(_mm_min_epu8(iv4,cv1_8), _mm_min_epu8(iv5,cv1_8)); mv2 = _mm_min_epi16( mv2, cv1_8); mv2 = _mm_adds_epu16(mv2, cv7f00); + __m128i mv3 = _mm_packus_epi16(_mm_min_epu8(iv6,cv1_8), _mm_min_epu8(iv7,cv1_8)); mv3 = _mm_min_epi16( mv3, cv1_8); mv3 = _mm_adds_epu16(mv3, cv7f00); + uint16_t m2 = _mm_movemask_epi8(mv2); + uint16_t m3 = _mm_movemask_epi8(mv3); + + { __m128i ov0 = _mm_shuffle_epi8(iv0, SVE32(m0 << 4)), + ov1 = _mm_shuffle_epi8(iv1, SVE32(m0 >> 4)); + __m128i ov2 = _mm_shuffle_epi8(iv2, SVE32(m1 << 4)), + ov3 = _mm_shuffle_epi8(iv3, SVE32(m1 >> 4)); + + ctou32(out) = (unsigned)m1<<16|m0; + _mm_storeu_si128((__m128i *)(op+IPINC), ov0); op += LEN32(m0,0)+IPINC; + _mm_storeu_si128((__m128i *)op, ov1); op += LEN32(m0,1); + _mm_storeu_si128((__m128i *)op, ov2); op += LEN32(m1,0); + _mm_storeu_si128((__m128i *)op, ov3); op += LEN32(m1,1); + } + ctou32(out+4) = (unsigned)m3<<16|m2; + { __m128i ov0 = _mm_shuffle_epi8(iv4, SVE32(m2 << 4)), + ov1 = _mm_shuffle_epi8(iv5, SVE32(m2 >> 4)); + __m128i ov2 = _mm_shuffle_epi8(iv6, SVE32(m3 << 4)), + ov3 = _mm_shuffle_epi8(iv7, SVE32(m3 >> 4)); + _mm_storeu_si128((__m128i *)op, ov0); op += LEN32(m2,0); + _mm_storeu_si128((__m128i *)op, ov1); op += LEN32(m2,1); + _mm_storeu_si128((__m128i *)op, ov2); op += LEN32(m3,0); + _mm_storeu_si128((__m128i *)op, ov3); op += LEN32(m3,1); + } PREFETCH(ip+512,0); + } + #else //------------------------------ scalar ---------------------------------------------- + for(ip = in; ip != in+(n&~(32-1)); ip += 32) { PNEXTA(out,op,8); VLE4( 0); VLE4( 4); VLE4( 8); VLE4(12); VLE4(16); VLE4(20); VLE4(24); VLE4(28); PREFETCH(ip+512,0); } + #endif + for( ; ip != in+(n&~(4-1)); ip += 4) { PNEXTA(out,op,1); VLE4(0); } + if(ip != in+n) { uint32_t *sp = ip; for(*OP=0,PNEXTA(out,op,1); ip != in+n; ip++ ) VLE1(out[0]); } + return op; +} + +#define VLD1(_i_) { unsigned _b = ((m>>((op-sp)*2))& 3)+1; v = ctou32(ip) & ((1ull<<(_b*8))-1); *op = VD32(v); ip+=_b; } +#define VLD4(_i_) { unsigned _b,m = *in++;\ + _b = (m & 3)+1; v = ctou32(ip) & ((1ull<<(_b*8))-1); op[_i_+0] = VD32(v); ip+=_b;\ + _b = ((m>>2)& 3)+1; v = ctou32(ip) & ((1ull<<(_b*8))-1); op[_i_+1] = VD32(v); ip+=_b;\ + _b = ((m>>4)& 3)+1; v = ctou32(ip) & ((1ull<<(_b*8))-1); op[_i_+2] = VD32(v); ip+=_b;\ + _b = ((m>>6)& 3)+1; v = ctou32(ip) & ((1ull<<(_b*8))-1); op[_i_+3] = VD32(v); ip+=_b;\ +} + +unsigned char *TEMPLATE2(V8DEC,32)(unsigned char *__restrict in, unsigned n, uint32_t *__restrict out V8DELTA32) { + uint32_t *op; + unsigned char *ip = DATABEG(in,n,4); + uint32_t v; + #if 0 //def __AVX2__ //----------------------------------------------------------------------------------------------- + VDINI256v32; + for(op = out; op != out+(n&~(32-1)); op += 32) { PREFETCH(ip+512,0); + uint32_t m0 = ctou32(IP), m1 = ctou32(IP+4); IP+=8; + __m256i ov0 = _mm256_castsi128_si256( _mm_loadu_si128(ip)); ip += LEN32(m0,0); + ov0 = _mm256_inserti128_si256(ov0, _mm_loadu_si128(ip),1); ip += LEN32(m0,1); + __m256i fv0 = _mm256_castsi128_si256( SVD32(m0,0)); + fv0 = _mm256_inserti128_si256(fv0, SVD32(m0,1),1); + __m256i ov1 = _mm256_castsi128_si256( _mm_loadu_si128(ip)); ip += LEN32(m0,2); + ov1 = _mm256_inserti128_si256(ov1, _mm_loadu_si128(ip),1); ip += LEN32(m0,3); + __m256i fv1 = _mm256_castsi128_si256( SVD32(m0,2)); + fv1 = _mm256_inserti128_si256(fv1, SVD32(m0,3),1); + + __m256i ov2 = _mm256_castsi128_si256( _mm_loadu_si128(ip)); ip += LEN32(m1,0); + ov2 = _mm256_inserti128_si256(ov2, _mm_loadu_si128(ip),1); ip += LEN32(m1,1); + __m256i fv2 = _mm256_castsi128_si256( SVD32(m1,0)); + fv2 = _mm256_inserti128_si256(fv2, SVD32(m1,1),1); + __m256i ov3 = _mm256_castsi128_si256( _mm_loadu_si128(ip)); ip += LEN32(m1,2); + ov3 = _mm256_inserti128_si256(ov3, _mm_loadu_si128(ip),1); ip += LEN32(m1,3); + + __m256i fv3 = _mm256_castsi128_si256( SVD32(m1,2)); + fv3 = _mm256_inserti128_si256(fv3, SVD32(m1,3),1); + ov0 = _mm256_shuffle_epi8(ov0, fv0); + ov1 = _mm256_shuffle_epi8(ov1, fv1); VD256v32(ov0,sv); VD256v32(ov1,sv); + ov2 = _mm256_shuffle_epi8(ov2, fv2); + ov3 = _mm256_shuffle_epi8(ov3, fv3); VD256v32(ov2,sv); VD256v32(ov3,sv); + _mm256_storeu_si256(op, ov0); + _mm256_storeu_si256(op+8, ov1); + _mm256_storeu_si256(op+16, ov2); + _mm256_storeu_si256(op+24, ov3); + } + #elif defined(__SSSE3__) // optimzed for x86 + VDINI128v32; + for(op = out; op != out+(n&~(32-1)); op += 32) { PREFETCH(ip+512,0); + uint32_t m0 = ctou32(IP), m1 = ctou32(IP+4); IP+=8; + { __m128i ov0 = _mm_loadu_si128(ip); ip += LEN32(m0,0); + __m128i ov1 = _mm_loadu_si128(ip); ip += LEN32(m0,1); + __m128i ov2 = _mm_loadu_si128(ip); ip += LEN32(m0,2); + __m128i ov3 = _mm_loadu_si128(ip); ip += LEN32(m0,3); + + ov0 = _mm_shuffle_epi8(ov0, SVD32(m0,0)); + ov1 = _mm_shuffle_epi8(ov1, SVD32(m0,1)); + ov2 = _mm_shuffle_epi8(ov2, SVD32(m0,2)); + ov3 = _mm_shuffle_epi8(ov3, SVD32(m0,3)); + + VD128v32(ov0,sv); _mm_storeu_si128(op, ov0); + VD128v32(ov1,sv); _mm_storeu_si128(op+ 4, ov1); + VD128v32(ov2,sv); _mm_storeu_si128(op+ 8, ov2); + VD128v32(ov3,sv); _mm_storeu_si128(op+12, ov3); + } + { __m128i ov0 = _mm_loadu_si128(ip); ip += LEN32(m1,0); + __m128i ov1 = _mm_loadu_si128(ip); ip += LEN32(m1,1); + __m128i ov2 = _mm_loadu_si128(ip); ip += LEN32(m1,2); + __m128i ov3 = _mm_loadu_si128(ip); ip += LEN32(m1,3); + + ov0 = _mm_shuffle_epi8(ov0, SVD32(m1,0)); + ov1 = _mm_shuffle_epi8(ov1, SVD32(m1,1)); + ov2 = _mm_shuffle_epi8(ov2, SVD32(m1,2)); + ov3 = _mm_shuffle_epi8(ov3, SVD32(m1,3)); + + VD128v32(ov0,sv); _mm_storeu_si128(op+16, ov0); + VD128v32(ov1,sv); _mm_storeu_si128(op+20, ov1); + VD128v32(ov2,sv); _mm_storeu_si128(op+24, ov2); + VD128v32(ov3,sv); _mm_storeu_si128(op+28, ov3); + } + } + #elif defined(__ARM_NEON) || defined(__SSSE3__) // optimzed for ARM ---------------------------------------------------------- + VDINI128v32; + for(op = out; op != out+(n&~(32-1)); op += 32) { PREFETCH(ip+512,0); + uint32_t m0 = ctou32(IP), m1 = ctou32(IP+4); + __m128i ov0 = _mm_loadu_si128(ip+IPINC); ip += LEN32(m0,0)+IPINC; + __m128i fv0 = SVD32(m0,0); + __m128i ov1 = _mm_loadu_si128(ip); ip += LEN32(m0,1); + __m128i fv1 = SVD32(m0,1); + __m128i ov2 = _mm_loadu_si128(ip); ip += LEN32(m0,2); + __m128i fv2 = SVD32(m0,2); + __m128i ov3 = _mm_loadu_si128(ip); ip += LEN32(m0,3); + __m128i fv3 = SVD32(m0,3); + ov0 = _mm_shuffle_epi8( ov0, fv0); + ov1 = _mm_shuffle_epi8( ov1, fv1); + ov2 = _mm_shuffle_epi8( ov2, fv2); + ov3 = _mm_shuffle_epi8( ov3, fv3); + + __m128i fv4 = SVD32(m1,0); + __m128i ov4 = _mm_loadu_si128(ip); ip += LEN32(m1,0); + __m128i fv5 = SVD32(m1,1); + __m128i ov5 = _mm_loadu_si128(ip); ip += LEN32(m1,1); + __m128i fv6 = SVD32(m1,2); + __m128i ov6 = _mm_loadu_si128(ip); ip += LEN32(m1,2); + __m128i fv7 = SVD32(m1,3); + __m128i ov7 = _mm_loadu_si128(ip); ip += LEN32(m1,3); + + ov4 = _mm_shuffle_epi8( ov4, fv4); + ov5 = _mm_shuffle_epi8( ov5, fv5); + ov6 = _mm_shuffle_epi8( ov6, fv6); + ov7 = _mm_shuffle_epi8( ov7, fv7); + VD128v32(ov0,sv); VD128v32(ov1,sv); VD128v32(ov2,sv); VD128v32(ov3,sv); + VD128v32(ov4,sv); VD128v32(ov5,sv); VD128v32(ov6,sv); VD128v32(ov7,sv); //delta,zigzag,.... + _mm_storeu_si128(op, ov0); + _mm_storeu_si128(op+4, ov1); + _mm_storeu_si128(op+8, ov2); + _mm_storeu_si128(op+12, ov3); + _mm_storeu_si128(op+16, ov4); + _mm_storeu_si128(op+20, ov5); + _mm_storeu_si128(op+24, ov6); + _mm_storeu_si128(op+28, ov7); + PNEXTB(in,8); + } + #else //----------------------------- scalar ----------------------------------------------- + for(op = out; op != out+(n&~(32-1)); op += 32) { in = ip; ip+=8; + VLD4( 0); VLD4( 4); VLD4( 8); VLD4(12); VLD4(16); VLD4(20); VLD4(24); VLD4(28); + PREFETCH(ip+512,0); + } + #endif + uint32_t m; for(; op != out+(n&~(4-1)); op += 4) { PNEXTA(in,ip,1); VLD4( 0); } + if(op != out+n) { uint32_t *sp = op; for(m = *IP++; op != out+n; op++ ) VLD1( 0);} + return ip; +} + +//------------------------------------ 16 bits --------------------------------------------------------------------- +#define LEN16(_m_,_i_) (8+popcnt32((uint8_t)(_m_>>(_i_<<3)))) + +#define BN16(_x_) ((_x_)>0xff?1:0) +#define VLE1(_m_) { VE16(ip[0]); unsigned _b = BN16(v); ctou16(op) = v; op += _b+1; _m_ |= _b<<(ip-sp); } + +#define VLE8(_i_) { unsigned _b,_m; PNEXTA(out,op,1);\ + VE16(ip[_i_+0]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m = _b; \ + VE16(ip[_i_+1]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<1; \ + VE16(ip[_i_+2]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<2; \ + VE16(ip[_i_+3]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<3; \ + VE16(ip[_i_+4]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<4; \ + VE16(ip[_i_+5]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<5; \ + VE16(ip[_i_+6]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<6; \ + VE16(ip[_i_+7]); _b = BN16(v); ctou16(op) = v; op += _b+1; _m |= _b<<7; \ + *out++ = _m;\ +} + +unsigned char *TEMPLATE2(V8ENC,16)(uint16_t *__restrict in, unsigned n, unsigned char *__restrict out V8DELTA16) { + uint16_t *ip,v; + unsigned char *op = DATABEG(out,n,2); + + #if defined(__SSSE3__) || defined(__ARM_NEON) //-------------------------------- + VEINI128v16; const __m128i cv1_8 = _mm_set1_epi8(1); + for(ip = in; ip != in+(n&~(64-1)); ip += 64, PNEXT(out,op,8)) { PREFETCH(ip+512,0); + __m128i iv0 = _mm_loadu_si128(ip ), + iv1 = _mm_loadu_si128(ip+ 8); + __m128i iv2 = _mm_loadu_si128(ip+16), + iv3 = _mm_loadu_si128(ip+24); VE128v16(iv0,sv); VE128v16(iv1,sv); VE128v16(iv2,sv); VE128v16(iv3,sv); + __m128i mv0 = _mm_packus_epi16(_mm_min_epu8(iv0,cv1_8), _mm_min_epu8(iv1,cv1_8)); + __m128i mv1 = _mm_packus_epi16(_mm_min_epu8(iv2,cv1_8), _mm_min_epu8(iv3,cv1_8)); + uint16_t m0 = _mm_movemask_epi8(mv0), m1 = _mm_movemask_epi8(mv1); + ctou16(out) = m0; ctou16(out+2) = m1; + __m128i iv4 = _mm_loadu_si128(ip+32), + iv5 = _mm_loadu_si128(ip+40); + __m128i iv6 = _mm_loadu_si128(ip+48), + iv7 = _mm_loadu_si128(ip+56); VE128v16(iv4,sv); VE128v16(iv5,sv);VE128v16(iv6,sv); VE128v16(iv7,sv); + __m128i mv4 = _mm_packus_epi16(_mm_min_epu8(iv4,cv1_8), _mm_min_epu8(iv5,cv1_8)); + __m128i mv5 = _mm_packus_epi16(_mm_min_epu8(iv6,cv1_8), _mm_min_epu8(iv7,cv1_8)); + uint16_t m2 = _mm_movemask_epi8(mv4), m3 = _mm_movemask_epi8(mv5); + + __m128i ov0 = _mm_shuffle_epi8(iv0, SVE16(m0 << 4)), + ov1 = _mm_shuffle_epi8(iv1, SVE16(m0 >> 4)), + ov2 = _mm_shuffle_epi8(iv2, SVE16(m1 << 4)), + ov3 = _mm_shuffle_epi8(iv3, SVE16(m1 >> 4)); + _mm_storeu_si128((__m128i *)(op+IPINC), ov0); op += LEN16(m0,0)+IPINC; + _mm_storeu_si128((__m128i *)op, ov1); op += LEN16(m0,1); + _mm_storeu_si128((__m128i *)op, ov2); op += LEN16(m1,0); + _mm_storeu_si128((__m128i *)op, ov3); op += LEN16(m1,1); + + __m128i ov4 = _mm_shuffle_epi8(iv4, SVE16(m2 << 4)), + ov5 = _mm_shuffle_epi8(iv5, SVE16(m2 >> 4)), + ov6 = _mm_shuffle_epi8(iv6, SVE16(m3 << 4)), + ov7 = _mm_shuffle_epi8(iv7, SVE16(m3 >> 4)); + _mm_storeu_si128((__m128i *)op, ov4); op += LEN16(m2,0); + _mm_storeu_si128((__m128i *)op, ov5); op += LEN16(m2,1); + _mm_storeu_si128((__m128i *)op, ov6); op += LEN16(m3,0); + _mm_storeu_si128((__m128i *)op, ov7); op += LEN16(m3,1); + ctou16(out+4) = m2; ctou16(out+6) = m3; + } + #else //---------------------- scalar --------------------------------------- + for(ip = in; ip != in+(n&~(64-1)); ip += 64) { PREFETCH(ip+512,0); + op += 8; + VLE8( 0); VLE8( 8); VLE8(16); VLE8(24); VLE8(32); VLE8(40); VLE8(48); VLE8(56); + out = op; + } + #endif + for( ; ip != in+(n&~(8-1)); ip += 8) VLE8(0); + if(ip != in+n) { uint16_t *sp = ip; for(PNEXTA(out,op,1),*out=0; ip != in+n; ip++ ) VLE1(out[0]); } + return op; +} + +#define VLD1(_i_) { unsigned _b = ((m>>(op-sp))& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); *op = VD16(v); ip+=_b; } + +#define VLD8(_i_) { unsigned _b,m = *IP++;\ + _b = (m & 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+0] = VD16(v); ip+=_b;\ + _b = ((m>>1)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+1] = VD16(v); ip+=_b;\ + _b = ((m>>2)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+2] = VD16(v); ip+=_b;\ + _b = ((m>>3)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+3] = VD16(v); ip+=_b;\ + _b = ((m>>4)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+4] = VD16(v); ip+=_b;\ + _b = ((m>>5)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+5] = VD16(v); ip+=_b;\ + _b = ((m>>6)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+6] = VD16(v); ip+=_b;\ + _b = ((m>>7)& 1)+1; v = ctou16(ip) & ((1<<(_b*8))-1); op[_i_+7] = VD16(v); ip+=_b;\ + } + +unsigned char *TEMPLATE2(V8DEC,16)(unsigned char *__restrict in, unsigned n, uint16_t *__restrict out V8DELTA16) { + uint16_t *op; + unsigned char *ip = DATABEG(in,n,2); + uint16_t v; + + #if defined(__SSSE3__) || defined(__ARM_NEON)//----------------------- + VDINI128v16; + for(op = out; op != out+(n&~(64-1)); op += 64) { PREFETCH(ip+512,0); + uint32_t m0 = ctou32(IP), m1 = ctou32(IP+4); + __m128i ov0 = _mm_shuffle_epi8(_mm_loadu_si128(ip+IPINC), SVD16(m0,0)); ip += LEN16(m0,0)+IPINC; + __m128i ov1 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m0,1)); ip += LEN16(m0,1); + __m128i ov2 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m0,2)); ip += LEN16(m0,2); + __m128i ov3 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m0,3)); ip += LEN16(m0,3); + VD128v16(ov0,sv); VD128v16(ov1,sv); VD128v16(ov2,sv); VD128v16(ov3,sv); + _mm_storeu_si128(op, ov0); + _mm_storeu_si128(op+8, ov1); + _mm_storeu_si128(op+16, ov2); + _mm_storeu_si128(op+24, ov3); + + __m128i ov4 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m1,0)); ip += LEN16(m1,0); + __m128i ov5 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m1,1)); ip += LEN16(m1,1); + __m128i ov6 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m1,2)); ip += LEN16(m1,2); + __m128i ov7 = _mm_shuffle_epi8(_mm_loadu_si128(ip), SVD16(m1,3)); ip += LEN16(m1,3); + VD128v16(ov4,sv); VD128v16(ov5,sv); VD128v16(ov6,sv); VD128v16(ov7,sv); + _mm_storeu_si128(op+32, ov4); + _mm_storeu_si128(op+40, ov5); + _mm_storeu_si128(op+48, ov6); + _mm_storeu_si128(op+56, ov7); + PNEXTB(in,8); + } + #else //-------------- scalar -------------------------------------------------------- + for(op = out; op != out+(n&~(64-1)); op += 64) { ip += 8; + VLD8( 0); VLD8( 8); VLD8(16); VLD8(24); VLD8(32); VLD8(40); VLD8(48); VLD8(56); PREFETCH(ip+512,0); + in = ip; + } + #endif + uint32_t m; for(; op != out+(n&~(8-1)); op += 8) VLD8( 0); + if(op != out+n) { uint16_t *sp = op; for(m = *IP++; op != out+n; op++ ) VLD1( 0);} + return ip; +} +#endif diff --git a/src/ext/for/vint.c b/src/ext/for/vint.c new file mode 100644 index 00000000000..a6e46a1547e --- /dev/null +++ b/src/ext/for/vint.c @@ -0,0 +1,407 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// vint.c - "Integer Compression" variable byte + #ifndef USIZE +#include +#include +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#define BITUTIL_IN +#define VINT_IN +#include "conf.h" +#include "vint.h" +#include "bitutil.h" + +#define UN 8 // 4 // + +#define VDELTA 0 +#define VBDENC vbdenc +#define VBDDEC vbddec +#define VBDGETX vbdgetx +#define VBDGETGEQ vbdgetgeq + +#define USIZE 32 +#include "vint.c" +#undef USIZE + +#define USIZE 64 +#include "vint.c" +#undef USIZE + +#define USIZE 16 +#include "vint.c" +#undef USIZE + +#define USIZE 8 +#include "vint.c" +#undef USIZE + +#define VDELTA 1 +#define VBDENC vbd1enc +#define VBDDEC vbd1dec +#define VBDGETX vbd1getx +#define VBDGETGEQ vbd1getgeq + +#define USIZE 32 +#include "vint.c" +#undef USIZE + +#define USIZE 64 +#include "vint.c" +#undef USIZE + +#define USIZE 16 +#include "vint.c" +#undef USIZE + +#define USIZE 8 +#include "vint.c" +#undef USIZE + #else +#define uint_t TEMPLATE3(uint, USIZE, _t) + + #if VDELTA == 0 +//#if USIZE < 64 +#define OVERFLOWD(in,n,out,vbmax) if(*in == (vbmax)) { memcpy(out, in+1, n*(USIZE/8)); return in+1+n*(USIZE/8); } +#define OVERFLOWE(in,n,out,op,vbmax) if(op > out + n*(USIZE/8)) { *out = (vbmax); memcpy(out+1, in, n*(USIZE/8)); op = out+1+n*(USIZE/8); } +//#else +//#define OVERFLOWD(in,n,out,vbmax) +//#define OVERFLOWE(in,n,out,op,vbmax) +//#endif +unsigned char *TEMPLATE2(vbdec, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out) { + register uint_t x, *op; + OVERFLOWD(in, n, out, VB_MAX+1); + + #define VBE(_i_) TEMPLATE2(_vbget, USIZE)(in, x, op[_i_] = x) + for(op = out; op != out+(n&~(UN-1)); op += UN) { + VBE(0); VBE(1); VBE(2); VBE(3); + #if UN > 4 + VBE(4); VBE(5); VBE(6); VBE(7); + #endif + PREFETCH(in+16*USIZE, 0); + } + while(op != out+n) + TEMPLATE2(_vbget, USIZE)(in, x, *op++ = x ); + return in; +} +#undef VBE + +unsigned char *TEMPLATE2(vbenc, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out) { + uint_t x, *ip; + unsigned char *op = out; + + #define VBD(_i_) x = ip[_i_]; TEMPLATE2(_vbput, USIZE)(op, x, ;); + for(ip = in; ip != in+(n&~(UN-1)); ip += UN) { PREFETCH(ip+USIZE*8, 0); + VBD(0); VBD(1); VBD(2); VBD(3); + #if UN > 4 + VBD(4); VBD(5); VBD(6); VBD(7); + #endif + } + while(ip != in+n) { + x = *ip++; + TEMPLATE2(_vbput, USIZE)(op, x, ;); + } + + OVERFLOWE(in,n,out,op,VB_MAX+1); + return op; +} +#undef VBD + +uint_t TEMPLATE2(vbgetx, USIZE)(unsigned char *__restrict in, unsigned idx) { + unsigned char *ip; + unsigned i; + uint_t x; + if(*in == 255) + return TEMPLATE2(ctou, USIZE)(in+1+idx*(USIZE/8)); + for(ip = in,i = 0; i <= idx; i++) + ip += TEMPLATE2(_vbvlen, USIZE)(*ip); + TEMPLATE2(_vbget, USIZE)(in, x, ;); + return x; +} + +/*unsigned TEMPLATE2(vbgeteq, USIZE)(unsigned char *__restrict in, unsigned n, uint_t key, unsigned char **__restrict _ip) { + unsigned i; + unsigned char *ip; + uint_t x; + if(*in == 255) { + for(ip = (*_ip==in)?in:*ip; ip < in+n; ip+USIZE/8) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + if((x = TEMPLATE2(ctou, USIZE)(ip)) == key) break; + } + } else for(ip = *_ip,i=idx; i < n; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + if(x == key) break; + } + *_ip = ip; + return i; +}*/ +#define BITS 8 +#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS))) +#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS))) +#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS))) +unsigned char *TEMPLATE2(vbddenc, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + uint_t *ip,v,pd=0,*p; + unsigned char *bp=out; out += (n+7)/8; + #define VBDDE(i) { uint_t x; start = ip[i]-start; x = start-pd; pd = start; \ + if(!x) BIT_CLEAR(bp,i); else { BIT_SET(bp,i); x = TEMPLATE2(zigzagenc, USIZE)(x); TEMPLATE2(_vbput, USIZE)(out, x, ;); } start = ip[i]; } + + for(ip = in; ip != in+(n&~(8-1)); ip+=8,bp++) { VBDDE(0);VBDDE(1);VBDDE(2);VBDDE(3);VBDDE(4);VBDDE(5);VBDDE(6);VBDDE(7);} + for(p=ip; p != in+n; p++) VBDDE(p-ip); + return out; +} + +unsigned char *TEMPLATE2(vbdddec, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out, uint_t start) { + uint_t *op,pd=0,*p; + unsigned i; + #define VBDDD(i) { uint_t x=0; if(BIT_ISSET(bp,i)) { TEMPLATE2(_vbget, USIZE)(in, x, ;); pd += TEMPLATE2(zigzagdec, USIZE)(x); } op[i] = (start += pd); } + unsigned char *bp=in; in+=(n+7)/8; + for(op = out; op != out+(n&~(8-1)); op+=8,bp++) { + if(!bp[0]) { op[0]=(start+=pd); op[1]=(start+=pd); op[2]=(start+=pd); op[3]=(start+=pd); op[4]=(start+=pd); op[5]=(start+=pd); op[6]=(start+=pd); op[7]=(start+=pd); continue; } + VBDDD(0); VBDDD(1); VBDDD(2); VBDDD(3); VBDDD(4); VBDDD(5); VBDDD(6); VBDDD(7); PREFETCH(in+16*USIZE, 0); + } + for(p=op; p != out+n; p++) VBDDD(p-op); + return in; +} +#undef VBDDE +#undef VBDDD + +unsigned char *TEMPLATE2(vbzenc, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + uint_t *ip,v; + unsigned char *op = out; + + #define VBZE { v = TEMPLATE2(zigzagenc, USIZE)((TEMPLATE3(int, USIZE, _t))(*ip)-(TEMPLATE3(int, USIZE, _t))start); start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); } + for(ip = in; ip != in+(n&~(UN-1)); ) { VBZE;VBZE;VBZE;VBZE; } + while(ip != in+n) VBZE; //OVERFLOWE(in,n,out,op); + return op; +} +#undef VBZE + +unsigned char *TEMPLATE2(vbzdec, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out, uint_t start) { + uint_t x,*op; + + #define VBZD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start += TEMPLATE2(zigzagdec, USIZE)(x)); } + for(op = out; op != out+(n&~(UN-1)); ) { VBZD; VBZD; VBZD; VBZD; + #if UN > 4 + VBZD; VBZD; VBZD; VBZD; + #endif + PREFETCH(in+16*USIZE, 0); + } + while(op != out+n) VBZD; + + return in; +} +#undef VBZD + +uint_t TEMPLATE2(vbzgetx, USIZE)(unsigned char *__restrict in, unsigned idx, uint_t start) { + unsigned char *ip; + unsigned i; + uint_t x; + + for(ip = in,i = 0; i <= idx; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + start += x+VDELTA; + } + return start; +} + +unsigned TEMPLATE2(vbzgeteq, USIZE)(unsigned char **__restrict in, unsigned n, unsigned idx, uint_t key, uint_t start ) { + unsigned i; + unsigned char *ip; + uint_t x; + for(ip = *in,i=idx; i < n; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + if((start += x+VDELTA) == key) + break; + } + *in = ip; + return i; +} + +unsigned char *TEMPLATE2(vbxenc, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + uint_t *ip,v; + unsigned char *op = out; + + #define VBXE { v = (*ip)^start; start=*ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); } + for(ip = in; ip != in+(n&~(UN-1)); ) { VBXE;VBXE;VBXE;VBXE; } + while(ip != in+n) VBXE; //OVERFLOWE(in,n,out,op); + return op; +} +#undef VBZE + +unsigned char *TEMPLATE2(vbxdec, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out, uint_t start) { + uint_t x,*op; + + #define VBXD { TEMPLATE2(_vbget, USIZE)(in, x, ;); *op++ = (start ^= x); } + for(op = out; op != out+(n&~(UN-1)); ) { VBXD; VBXD; VBXD; VBXD; + #if UN > 4 + VBXD; VBXD; VBXD; VBXD; + #endif + PREFETCH(in+16*USIZE, 0); + } + while(op != out+n) VBXD; + + return in; +} +#undef VBZD + +uint_t TEMPLATE2(vbxgetx, USIZE)(unsigned char *__restrict in, unsigned idx, uint_t start) { + unsigned char *ip; + unsigned i; + uint_t x; + + for(ip = in,i = 0; i <= idx; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + start ^= x; + } + return start; +} + +unsigned TEMPLATE2(vbxgeteq, USIZE)(unsigned char **__restrict in, unsigned n, unsigned idx, uint_t key, uint_t start ) { + unsigned i; + unsigned char *ip; + uint_t x; + for(ip = *in,i=idx; i < n; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + if((start ^= x) == key) + break; + } + *in = ip; + return i; +} + #endif + +unsigned char *TEMPLATE2(VBDENC, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + unsigned char *op = out; + uint_t *ip, b = 0,v; + if(!n) return out; + #if USIZE == 64 + #define VB_MX 255 + #else + #define VB_MX VB_MAX + #endif + #define VBDE { v = ip[0]-start-VDELTA; start = *ip++; TEMPLATE2(_vbput, USIZE)(op, v, ;); b |= (v /*^ x*/); } + for(ip = in; ip != in + (n&~(UN-1)); ) { VBDE; VBDE; VBDE; VBDE; + #if UN > 4 + VBDE; VBDE; VBDE; VBDE; + #endif + } + while(ip != in+n) VBDE; + if(!b) { op = out; *op++ = VB_MX; } // if (x) { op = out; *op++ = VB_MAX-2; TEMPLATE2(_vbput, USIZE)(op, x, ;); } + #if USIZE < 64 + OVERFLOWE(in,n,out,op,VB_MAX-1); + #endif + return op; +} +#undef VBDE + +unsigned char *TEMPLATE2(VBDDEC, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out, uint_t start) { + uint_t x,*op; + if(!n) return in; + + #if USIZE < 64 + OVERFLOWD(in,n,out,VB_MAX-1); + #endif + + if(in[0] == VB_MX) { + in++; + #if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32 + #if VDELTA == 0 + if(n) TEMPLATE2(BITZERO, USIZE)(out, n, start); + #else + if(n) TEMPLATE2(BITDIZERO,USIZE)(out, n, start, VDELTA); + #endif + #else + #if VDELTA == 0 + for(x = 0; x < n; x++) out[x] = start; + #else + for(x = 0; x < n; x++) out[x] = start+x*VDELTA; + #endif + #endif + return in; + } + #if 0 //USIZE < 64 + else if(in[0] == VB_MAX-2) { in++; + uint_t z; + TEMPLATE2(_vbget, USIZE)(in, z, ;); + #if VDELTA == 0 + for(x = 0; x < n; x++) out[x] = start+z; + #else + for(x = 0; x < n; x++) out[x] = start+x+z; + #endif + return in; + } + #endif + #define VBDD(i) { TEMPLATE2(_vbget, USIZE)(in, x, x+=VDELTA); op[i] = (start += x); } + for(op = out; op != out+(n&~(UN-1)); op+=UN) { + VBDD(0); VBDD(1); VBDD(2); VBDD(3); + #if UN > 4 + VBDD(4); VBDD(5); VBDD(6); VBDD(7); + #endif + PREFETCH(in+16*USIZE, 0); + } + for(;op != out+n;op++) VBDD(0); + return in; +} +#undef VBDD + +uint_t TEMPLATE2(VBDGETX, USIZE)(unsigned char *__restrict in, unsigned idx, uint_t start) { + unsigned char *ip; + unsigned i=0; + uint_t x; + + #if USIZE > 64 + unsigned long long u; + _vbget64(in, u, ;); x = u>>1; start += x+VDELTA; + if(u & 1) return start + VDELTA; + #endif + for(ip = in; i <= idx; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + start += x+VDELTA; + } + return start; +} + +unsigned TEMPLATE2(VBDGETGEQ, USIZE)(unsigned char **__restrict in, unsigned n, unsigned idx, uint_t *key, uint_t start ) { + unsigned i=0; + unsigned char *ip=*in; + uint_t x; + #if USIZE < 64 + if(!idx) { + unsigned long long u; _vbget64(ip, u, ;); x = u>>1; start += x+VDELTA; + if((u & 1) && start == *key) { *in = ip; return 0; } + i++; + } + #endif + for(ip = *in; i < n; i++) { + TEMPLATE2(_vbget, USIZE)(ip, x, ;); + if((start += x+VDELTA) == *key) + break; + } + *in = ip; + return i; +} +#undef uint_t +#endif diff --git a/src/ext/for/vint.h b/src/ext/for/vint.h new file mode 100644 index 00000000000..9cc617443eb --- /dev/null +++ b/src/ext/for/vint.h @@ -0,0 +1,401 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression" variable byte include header (scalar TurboVByte+ SIMD TurboByte) +#ifndef _VINT_H_ +#define _VINT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + #ifdef VINT_IN +#include "conf.h" +//----------------------------------- Variable byte: single value macros (low level) ----------------------------------------------- +//------------- 32 bits ------------- +extern unsigned char _vtab32_[]; +#define _vbxvlen32(_x_) _vtab32_[(unsigned char)(_x_)>>4] // (clz32((_x_) ^ 0xff) - 23) // +#define _vbxlen32(_x_) ((bsr32(_x_|1)+6)/7) + +#define _vbxput32(_op_, _x_, _act_) {\ + if(likely((_x_) < (1<< 7))) { *_op_++ = _x_; _act_;}\ + else if(likely((_x_) < (1<<14))) { ctou16(_op_) = bswap16((_x_) | 0x8000u); _op_ += 2; _act_;}\ + else if(likely((_x_) < (1<<21))) { *_op_++ = _x_ >> 16 | 0xc0u; ctou16(_op_) = _x_; _op_ += 2; _act_;}\ + else if(likely((_x_) < (1<<28))) { ctou32(_op_) = bswap32((_x_) | 0xe0000000u); _op_ += 4; _act_;}\ + else { *_op_++ = (unsigned long long)(_x_) >> 32 | 0xf0u; ctou32(_op_) = _x_; _op_ += 4; _act_;}\ +} + +#define _vbxget32(_ip_, _x_, _act_) do { _x_ = (unsigned)(*_ip_++);\ + if(!(_x_ & 0x80u)) { _act_;}\ + else if(!(_x_ & 0x40u)) { _x_ = bswap16(ctou16(_ip_ - 1) & 0xff3fu); _ip_++; _act_;}\ + else if(!(_x_ & 0x20u)) { _x_ = (_x_ & 0x1f)<<16 | ctou16(_ip_); _ip_ += 2; _act_;}\ + else if(!(_x_ & 0x10u)) { _x_ = bswap32(ctou32(_ip_-1) & 0xffffff0fu); _ip_ += 3; _act_;}\ + else { _x_ = (unsigned long long)((_x_) & 0x07)<<32 | ctou32(_ip_); _ip_ += 4; _act_;}\ +} while(0) + +//------------- 64 bits ----------- +#define _vbxlen64(_x_) ((bsr64(_x_)+6)/7) +#define _vbxvlen64(_x_) ((_x_)==0xff?9:clz32((_x_) ^ 0xff) - 23) + +#define _vbxput64(_op_, _x_, _act_) {\ + if(likely(_x_ < (1<< 7))) { *_op_++ = _x_; _act_;}\ + else if(likely(_x_ < (1<<14))) { ctou16(_op_) = bswap16(_x_| 0x8000); _op_ += 2; _act_;}\ + else if(likely(_x_ < (1<<21))) { *_op_++ = _x_ >> 16 | 0xc0; ctou16(_op_) = _x_; _op_ += 2; _act_;}\ + else if(likely(_x_ < (1<<28))) { ctou32(_op_) = bswap32(_x_| 0xe0000000); _op_ += 4; _act_;}\ + else if( _x_ < 1ull<<35) { *_op_++ = _x_ >> 32 | 0xf0; ctou32(_op_) = _x_; _op_ += 4; _act_;}\ + else if( _x_ < 1ull<<42) { ctou16(_op_) = bswap16(_x_ >> 32 | 0xf800); _op_ += 2; ctou32(_op_) = _x_; _op_ += 4; _act_;}\ + else if( _x_ < 1ull<<49) { *_op_++ = _x_ >> 48 | 0xfc; ctou16(_op_) = _x_ >> 32; _op_ += 2; ctou32(_op_) = _x_; _op_ += 4; _act_;}\ + else if( _x_ < 1ull<<56) { ctou64(_op_) = bswap64(_x_ | 0xfe00000000000000ull); _op_ += 8; _act_;}\ + else { *_op_++ = 0xff; ctou64(_op_) = _x_; _op_ += 8; _act_;}\ +} + +#define _vbxget64(_ip_, _x_, _act_) do { _x_ = *_ip_++;\ + if(!(_x_ & 0x80)) { _act_;}\ + else if(!(_x_ & 0x40)) { _x_ = bswap16(ctou16(_ip_++-1) & 0xff3f); _act_;}\ + else if(!(_x_ & 0x20)) { _x_ = (_x_ & 0x1f)<<16 | ctou16(_ip_); _ip_ += 2; _act_;}\ + else if(!(_x_ & 0x10)) { _x_ = bswap32(ctou32(_ip_-1) & 0xffffff0f); _ip_ += 3; _act_;}\ + else if(!(_x_ & 0x08)) { _x_ = (_x_ & 0x07)<<32 | ctou32(_ip_); _ip_ += 4; _act_;}\ + else if(!(_x_ & 0x04)) { _x_ = (unsigned long long)(bswap16(ctou16(_ip_-1)) & 0x7ff) << 32 | ctou32(_ip_+1); _ip_ += 5; _act_;}\ + else if(!(_x_ & 0x02)) { _x_ = (_x_ & 0x03)<<48 | (unsigned long long)ctou16(_ip_) << 32 | ctou32(_ip_+2); _ip_ += 6; _act_;}\ + else if(!(_x_ & 0x01)) { _x_ = bswap64(ctou64(_ip_-1)) & 0x01ffffffffffffffull; _ip_ += 7; _act_;}\ + else { _x_ = ctou64(_ip_); _ip_ += 8; _act_;}\ +} while(0) + +#define vbxput64(_op_, _x_) { unsigned long long _x = _x_; _vbxput64(_op_, _x, ;); } +#define vbxput32(_op_, _x_) { register unsigned _x = _x_; _vbxput32(_op_, _x, ;); } +#define vbxput16(_op_, _x_) vbxput32(_op_, _x_) +#define vbxput8( _op_, _x_) (*_op_++ = _x_) + +#define vbxget64(_ip_, _x_) _vbxget64(_ip_, _x_, ;) +#define vbxget32(_ip_, _x_) _vbxget32(_ip_, _x_, ;) +#define vbxget16(_ip_, _x_) vbxget32(_ip_,_x_) +#define vbxget8(_ip_, _x_) (_x_ = *_ip_++) +//--------------------------------------------------------------------------- +#define VB_SIZE 64 +#define VB_MAX 254 +#define VB_B2 6 +#define VB_B3 3 +#define VB_BA3 (VB_MAX - (VB_SIZE/8 - 3)) +#define VB_BA2 (VB_BA3 - (1<> 8); *_op_++ = (_x_);*/ _act_; }\ + else if ((_x_) < VB_OFS3) { *_op_++ = VB_BA2 + (((_x_) -= VB_OFS2) >> 16); ctou16(_op_) = (_x_); _op_ += 2; _act_;}\ + else { unsigned _b = (bsr32((_x_))+7)/8; *_op_++ = VB_BA3 + (_b - 3); ctou32(_op_) = (_x_); _op_ += _b; _act_;}\ +} + +#define _vbget32(_ip_, _x_, _act_) do { _x_ = *_ip_++;\ + if(likely(_x_ < VB_OFS1)) { _act_ ;}\ + else if(likely(_x_ < VB_BA2)) { _x_ = /*bswap16(ctou16(_ip_-1))*/ ((_x_<<8) + (*_ip_)) + (VB_OFS1 - (VB_OFS1 << 8)); _ip_++; _act_;} \ + else if(likely(_x_ < VB_BA3)) { _x_ = ctou16(_ip_) + ((_x_ - VB_BA2 ) << 16) + VB_OFS2; _ip_ += 2; _act_;}\ + else { unsigned _b = _x_-VB_BA3; _x_ = ctou32(_ip_) & ((1u << 8 * _b << 24) - 1); _ip_ += 3 + _b; _act_;}\ +} while(0) + +#define _vblen64(_x_) _vblen32(_x_) +#define _vbvlen64(_x_) _vbvlen32(_x_) +#define _vbput64(_op_, _x_, _act_) {\ + if(likely((_x_) < VB_OFS1)){ *_op_++ = (_x_); _act_;}\ + else if ((_x_) < VB_OFS2) { ctou16(_op_) = bswap16((VB_OFS1<<8)+((_x_)-VB_OFS1)); _op_ += 2; /*(_x_) -= VB_OFS1; *_op_++ = VB_OFS1 + ((_x_) >> 8); *_op_++ = (_x_);*/ _act_; }\ + else if ((_x_) < VB_OFS3) { *_op_++ = VB_BA2 + (((_x_) -= VB_OFS2) >> 16); ctou16(_op_) = (_x_); _op_ += 2; _act_;}\ + else { unsigned _b = (bsr64((_x_))+7)/8; *_op_++ = VB_BA3 + (_b - 3); ctou64(_op_) = (_x_); _op_ += _b; _act_;}\ +} + +#define _vbget64(_ip_, _x_, _act_) do { _x_ = *_ip_++;\ + if(likely(_x_ < VB_OFS1)) { _act_ ;}\ + else if(likely(_x_ < VB_BA2)) { _x_ = /*bswap16(ctou16(_ip_-1))*/ ((_x_<<8) + (*_ip_)) + (VB_OFS1 - (VB_OFS1 << 8)); _ip_++; _act_;} \ + else if(likely(_x_ < VB_BA3)) { _x_ = ctou16(_ip_) + ((_x_ - VB_BA2 ) << 16) + VB_OFS2; _ip_ += 2; _act_;}\ + else { unsigned _b = _x_-VB_BA3; _x_ = ctou64(_ip_) & ((1ull << 8 * _b << 24) - 1); _ip_ += 3 + _b; _act_;}\ +} while(0) + +#ifdef _WIN32 +//#define fgetc_unlocked(_f_) _fgetc_nolock(_f_) +#define fputc_unlocked(_c_, _f_) fputc(_c_,_f_) +#define fgetc_unlocked(_f_) fgetc(_f_) +#else +#define fputc_unlocked(_c_, _f_) fputc(_c_,_f_) //_IO_putc_unlocked(_c_,_f_) +#define fgetc_unlocked(_f_) fgetc(_f_) //_IO_getc_unlocked(_f_) +#endif + +#define leb128put(_op_, _x_) { uint64_t _x = _x_; while(_x > 0x7f) { *_op_++ = _x & 0x7f; _x >>= 7; } *_op_++ = _x | 0x80; } +#define vbfput32(_f_, _x_) ({ uint64_t _x = _x_; while(_x > 0x7f) { fputc_unlocked(_x & 0x7f, _f_); _x >>= 7; } fputc_unlocked(_x | 0x80, _f_); }) + +#define _leb128get(_ip_, _x_, _act_) { unsigned _sft=0; for(_x_=0;;_sft += 7) { unsigned _c = *_ip_++; _x_ += (_c & 0x7f) << _sft; if(_c >= 0x80) { _act_; break; } } } +#define leb128get(_ip_, _x_) vbgetax(_ip_, _x_, ;) +#define vbfget32(_f_ ) ({ unsigned _sft=0,_x=0; for(;;_sft += 7) { unsigned _c = fgetc_unlocked(_f_); if(_c != EOF) { _x += (_c & 0x7f) << _sft; if(_c & 0x80) break; } else { _x = EOF; break; } } _x; }) + +//------------- 16 bits ----------- +#define _vblen16(_x_) _vblen32(_x_) +#define _vbvlen16(_x_) _vbvlen32(_x_) + +#define _vbput16(_op_, _x_, _act_) _vbput32(_op_, _x_, _act_) +#define _vbget16(_ip_, _x_, _act_) _vbget32(_ip_, _x_, _act_) + +#define _vblen8(_x_) 1 +#define _vbvlen8(_x_) 1 +#define _vbput8(_op_, _x_, _act_) { *_op_++ = _x_; _act_; } +#define _vbget8(_ip_, _x_, _act_) { _x_ = *_ip_++; _act_; } +//----------------------------------- Variable byte: single value functions ----------------------------------------------- +// ---- Variable byte length after compression +static inline unsigned vblen16(unsigned short x) { return _vblen16(x); } +static inline unsigned vblen32(unsigned x) { return _vblen32(x); } +static inline unsigned vblen64(uint64_t x) { return _vblen64(x); } + +// ---- Length of compressed value. Input in is the first char of the compressed buffer start (Ex. vbvlen32(in[0]) ) +static inline unsigned vbvlen16(unsigned x) { return _vbvlen32(x); } +static inline unsigned vbvlen32(unsigned x) { return _vbvlen32(x); } +static inline unsigned vbvlen64(unsigned x) { return _vbvlen64(x); } + +//----- encode/decode 16/32/64 single value and advance output/input pointer +#define vbput64(_op_, _x_) { unsigned long long _x = _x_; _vbput64(_op_, _x, ;); } +#define vbput32(_op_, _x_) { register unsigned _x = _x_; _vbput32(_op_, _x, ;); } +#define vbput16(_op_, _x_) vbput32(_op_, _x_) +#define vbput8(_op_, _x_) (*_op_++ = _x_) + +#define vbget64(_ip_, _x_) _vbget64(_ip_, _x_, ;) +#define vbget32(_ip_, _x_) _vbget32(_ip_, _x_, ;) +#define vbget16(_ip_, _x_) vbget32(_ip_,_x_) +#define vbget8(_ip_, _x_) (_x_ = *_ip_++) + #endif +//----------------------------- TurboVByte 'vb':Variable byte + SIMD TurboByte 'v8': array functions ---------------------------------------- +// Encoding/DEcoding: Return value = end of compressed output/input buffer out/in + +//----------------------- Encoding/Decoding unsorted array with n integer values -------------------------- +unsigned char *vbenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out); //TurboVByte +unsigned char *vbenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *vbenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); + +//-- Decode +unsigned char *vbdec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out); +unsigned char *vbdec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out); +unsigned char *vbdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out); + +//-- Get value stored at index idx (idx:0...n-1) +unsigned short vbgetx16( unsigned char *__restrict in, unsigned idx); +unsigned vbgetx32( unsigned char *__restrict in, unsigned idx); +uint64_t vbgetx64( unsigned char *__restrict in, unsigned idx); + +//-- Search and return index of next value equal to key or n when no key value found +// ex. unsigned idx;unsigned char *ip; for(idx=0,ip=in;;) { if((idx = vgeteq32(&ip, idx, 4321))>=n) break; printf("found at %u ", idx); } +unsigned vbgeteq16( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned short key); +unsigned vbgeteq32( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned key); +unsigned vbgeteq64( unsigned char **__restrict in, unsigned n, unsigned idx, uint64_t key); + +//---------------------- Delta encoding/decoding sorted array --------------------------------------------- +//-- Increasing integer array. out[i] = out[i-1] + in[i] +unsigned char *vbdenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *vbdenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *vbdenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *vbddec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *vbddec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *vbddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//-- Get value stored at index idx (idx:0...n-1) +unsigned short vbdgetx16( unsigned char *__restrict in, unsigned idx, unsigned short start); +unsigned vbdgetx32( unsigned char *__restrict in, unsigned idx, unsigned start); +uint64_t vbdgetx64( unsigned char *__restrict in, unsigned idx, uint64_t start); + +//-- Search and return index of next value equal to key or n when no key value found +// ex. unsigned idx;unsigned char *ip; for(idx=0,ip=in;;) { if((idx = vgeteq32(&ip, idx, 4321))>=n) break; printf("found at %u ", idx); } +unsigned vbdgetgeq16( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned short *key, unsigned short start); +unsigned vbdgetgeq32( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned *key, unsigned start); +unsigned vbdgetgeq64( unsigned char **__restrict in, unsigned n, unsigned idx, uint64_t *key, uint64_t start); + +//-- Strictly increasing (never remaining constant or decreasing) integer array. out[i] = out[i-1] + in[i] + 1 +unsigned char *vbd1enc16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *vbd1enc32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *vbd1enc64(uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *vbd1dec16(unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *vbd1dec32(unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *vbd1dec64(unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + + +//-- Get value stored at index idx (idx:0...n-1) +unsigned short vbd1getx16( unsigned char *__restrict in, unsigned idx, unsigned short start); +unsigned vbd1getx32( unsigned char *__restrict in, unsigned idx, unsigned start); +uint64_t vbd1getx64( unsigned char *__restrict in, unsigned idx, uint64_t start); + +//-- Search and return index of next value equal to key or n when no key value found +// ex. unsigned idx;unsigned char *ip; for(idx=0,ip=in;;) { if((idx = vgeteq32(&ip, idx, 4321))>=n) break; printf("found at %u ", idx); } +unsigned vbd1getgeq16( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned short *key, unsigned short start); +unsigned vbd1getgeq32( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned *key, unsigned start); +unsigned vbd1getgeq64( unsigned char **__restrict in, unsigned n, unsigned idx, uint64_t *key, uint64_t start); + +//---------------------- Zigzag encoding/decoding for unsorted integer lists. +unsigned char *vbzenc8( unsigned char *__restrict in, unsigned n, unsigned char *__restrict out, unsigned char start); +unsigned char *vbzenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *vbzenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *vbzenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *vbzdec8( unsigned char *__restrict in, unsigned n, unsigned char *__restrict out, unsigned char start); +unsigned char *vbzdec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *vbzdec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *vbzdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//---------------------- XOR encoding/decoding for unsorted integer lists. +unsigned char *vbxenc8( unsigned char *__restrict in, unsigned n, unsigned char *__restrict out, unsigned char start); +unsigned char *vbxenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *vbxenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *vbxenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *vbxdec8( unsigned char *__restrict in, unsigned n, unsigned char *__restrict out, unsigned char start); +unsigned char *vbxdec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *vbxdec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *vbxdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//---------------------- Delta of delta encoding/decoding for unsorted integer lists. +unsigned char *vbddenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *vbddenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); +unsigned char *vbddenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *vbdddec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *vbdddec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +unsigned char *vbdddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//-- Get value stored at index idx (idx:0...n-1) +unsigned short vbzgetx16( unsigned char *__restrict in, unsigned idx, unsigned short start); +unsigned vbzgetx32( unsigned char *__restrict in, unsigned idx, unsigned start); +uint64_t vbzgetx64( unsigned char *__restrict in, unsigned idx, uint64_t start); + +//-- Search and return index of next value equal to key or n when no key value found +// ex. unsigned idx;unsigned char *ip; for(idx=0,ip=in;;) { if((idx = vgeteq32(&ip, idx, 4321))>=n) break; printf("found at %u ", idx); } +/*unsigned vbzgeteq15( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned short key, unsigned start); +unsigned vbzgeteq16( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned short key, unsigned start); +unsigned vbzgeteq32( unsigned char **__restrict in, unsigned n, unsigned idx, unsigned key, unsigned start); +unsigned vbzgeteq64( unsigned char **__restrict in, unsigned n, unsigned idx, uint64_t key, unsigned start);*/ + +//-------------------------- TurboByte (SIMD Group varint) -------------------------------------------------------------- +unsigned char *v8enc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out); //TurboByte +unsigned char *v8enc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *v8dec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out); +unsigned char *v8dec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out); + +//------ delta --------- +unsigned char *v8denc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *v8denc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); + +unsigned char *v8ddec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *v8ddec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +//------ delta 1 ------- +unsigned char *v8d1enc16(unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *v8d1enc32(unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); + +unsigned char *v8d1dec16(unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *v8d1dec32(unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +//------- zigzag ------- +unsigned char *v8zenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *v8zenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); + +unsigned char *v8zdec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *v8zdec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); + +//------- xor ---------- +unsigned char *v8xenc16( unsigned short *__restrict in, unsigned n, unsigned char *__restrict out, unsigned short start); +unsigned char *v8xenc32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, unsigned start); + +unsigned char *v8xdec16( unsigned char *__restrict in, unsigned n, unsigned short *__restrict out, unsigned short start); +unsigned char *v8xdec32( unsigned char *__restrict in, unsigned n, unsigned *__restrict out, unsigned start); +//-------------------------- TurboByte Hybrid (SIMD Group varint) + Bitpacking ------------------------------------------- +size_t v8nenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8ndenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8ndenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8nd1enc16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nd1enc32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8nzenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nzenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8ndec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8ndec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nddec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nddec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nd1dec16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nd1dec32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nzdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nzdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nxdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nxdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +//------------- +size_t v8nenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8ndenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8ndenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8nd1enc128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nd1enc128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8nzenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nzenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8ndec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8ndec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nddec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nddec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nd1dec128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nd1dec128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nzdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nzdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +size_t v8nxdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t v8nxdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +//------------- +size_t v8nenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8ndenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nd1enc256v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nzenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t v8nxenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t v8ndec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t v8nddec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t v8nd1dec256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t v8nzdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t v8nxdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ext/for/vp4.h b/src/ext/for/vp4.h new file mode 100644 index 00000000000..fae28df8d45 --- /dev/null +++ b/src/ext/for/vp4.h @@ -0,0 +1,355 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "TurboPFor: Integer Compression" PFor/PForDelta + Direct access +#ifndef VP4_H_ +#define VP4_H_ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#include "vs/stdint.h" +#else +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif +//************************************************ High level API - n unlimited **************************************************** +// Compress integer array with n values to the buffer out. +// Return value = number of bytes written to compressed buffer out +size_t p4nenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); // SIMD (Vertical bitpacking) +size_t p4nenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc128v64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc256w32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); + + +size_t p4ndenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4ndenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t p4nd1enc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc128v16(uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc128v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc256v32(uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nd1enc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +size_t p4nzenc8( uint8_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc128v16( uint16_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc128v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc256v32( uint32_t *__restrict in, size_t n, unsigned char *__restrict out); +size_t p4nzenc64( uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +// Decompress the compressed n values in input buffer in to the integer array out. +// Return value = number of bytes read from the ompressed buffer in +size_t p4ndec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4ndec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4ndec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4ndec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t p4ndec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4ndec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4ndec128v64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +size_t p4ndec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); + +// Delta minimum = 0 +size_t p4nddec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nddec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nddec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nddec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec256w32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nddec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +// Delta minimum = 1 +size_t p4nd1dec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nd1dec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nd1dec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec128v16(unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nd1dec128v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec256v32(unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nd1dec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); +//Zigzag +size_t p4nzdec8( unsigned char *__restrict in, size_t n, uint8_t *__restrict out); +size_t p4nzdec16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nzdec32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec128v16( unsigned char *__restrict in, size_t n, uint16_t *__restrict out); +size_t p4nzdec128v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec256v32( unsigned char *__restrict in, size_t n, uint32_t *__restrict out); +size_t p4nzdec64( unsigned char *__restrict in, size_t n, uint64_t *__restrict out); + +//************** Low level API - n limited to 128/256 *************************************** +#define P4D_MAX 256 + +// -------------- TurboPFor: Encode ------------ +//#include +// Low level API: Single block n limited +//compress integer array with n values to the buffer out. Return value = end of compressed buffer out +unsigned char *p4enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); // SSE (Vertical bitpacking) +unsigned char *p4enc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc128v64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4enc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); // AVX2 +unsigned char *p4enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4enc256w32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4encx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out);// Direct access +unsigned char *p4encx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4encx32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out); +unsigned char *p4encx64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out); + +unsigned char *p4denc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4denc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4denc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4denc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4denc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4denc256w32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4dencx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); // Direct access +unsigned char *p4dencx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4dencx32( unsigned *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4d1enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4d1enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4d1enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc128v16(uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); // SIMD (Vertical bitpacking) +unsigned char *p4d1enc128v32(uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc256v32(uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4d1enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4d1encx8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); // Direct access +unsigned char *p4d1encx16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4d1encx32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); + +unsigned char *p4zenc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, uint8_t start); +unsigned char *p4zenc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4zenc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, uint16_t start); +unsigned char *p4zenc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, uint32_t start); +unsigned char *p4zenc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, uint64_t start); + +unsigned char *p4senc16(uint16_t *in, unsigned n, unsigned char *out, uint16_t start); +unsigned char *p4senc32(uint32_t *in, unsigned n, unsigned char *out, uint32_t start); +unsigned char *p4senc64(uint64_t *in, unsigned n, unsigned char *out, uint64_t start); + +unsigned char *p4sdec16(unsigned char *in, unsigned n, uint16_t *out, uint16_t start); +unsigned char *p4sdec32(unsigned char *in, unsigned n, uint32_t *out, uint32_t start); +unsigned char *p4sdec64(unsigned char *in, unsigned n, uint64_t *out, uint64_t start); + +size_t p4nsenc16(uint16_t *in, size_t n, unsigned char *out); +size_t p4nsenc32(uint32_t *in, size_t n, unsigned char *out); +size_t p4nsenc64(uint64_t *in, size_t n, unsigned char *out); + +size_t p4nsdec16(unsigned char *in, size_t n, uint16_t *out); +size_t p4nsdec32(unsigned char *in, size_t n, uint32_t *out); +size_t p4nsdec64(unsigned char *in, size_t n, uint64_t *out); + +// same as p4enc, but with b and bx as parameters. Call after _p4bitsXX +inline unsigned char *_p4enc8( uint8_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc128v16( uint16_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc128v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc128v64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical bitpacking) +inline unsigned char *_p4enc256v32( uint32_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4enc64( uint64_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx); +// calculate the best bit sizes b and bx, return b. +unsigned _p4bits8( uint8_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits16( uint16_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits32( uint32_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bits64( uint64_t *__restrict in, unsigned n, unsigned *pbx); + +unsigned _p4bitsx8( uint8_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx16( uint16_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx32( uint32_t *__restrict in, unsigned n, unsigned *pbx); +unsigned _p4bitsx64( uint64_t *__restrict in, unsigned n, unsigned *pbx); + +#define P4HVE(_out_, _b_, _bx_,_usize_) do { if(!_bx_) *_out_++ = _b_;else if(_bx_ <= _usize_) *_out_++ = 0x80|_b_, *_out_++ = _bx_; else *_out_++= (_bx_ == _usize_+1?0x40:0xc0)|_b_; } while(0) + +#define P4HVE8( _out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_, 8) +#define P4HVE16(_out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_,16) +#define P4HVE32(_out_, _b_, _bx_) P4HVE(_out_, _b_, _bx_,32) +#define P4HVE64(_out_, _b_, _bx_) do { unsigned _c = _b_==64?64-1:_b_; P4HVE(_out_, _c, _bx_,64); } while(0) + +//---------------------------- TurboPFor: Decode -------------------------------------------------------- +// decompress a previously (with p4enc32) bit packed array. Return value = end of packed buffer in +//-- scalar. (see p4getx32 for direct access) +// b and bx specified (not stored within the compressed stream header) +inline unsigned char *_p4dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, unsigned b, unsigned bx); // SIMD (Vertical BitPacking) +inline unsigned char *_p4dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec128v64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b, unsigned bx); +inline unsigned char *_p4dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, unsigned b, unsigned bx); + +unsigned char *p4dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out); +unsigned char *p4dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out); +unsigned char *p4dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out); // SIMD (Vertical BitPacking) +unsigned char *p4dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec128v64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out); +unsigned char *p4dec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out); +unsigned char *p4dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out); +//------ Delta decoding --------------------------- Return value = end of packed input buffer in --------------------------- +//-- Increasing integer lists. out[i] = out[i-1] + in[i] +// b and bx specified +unsigned char *_p4ddec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4ddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4ddec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4ddec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4ddec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4ddec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4ddec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//-- Strictly increasing (never remaining constant or decreasing) integer lists. out[i] = out[i-1] + in[i] + 1 +// b and bx specified (see idxcr.c/idxqry.c for an example) +unsigned char *_p4d1dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec128v16(unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); // SIMD (Vertical BitPacking) +unsigned char *_p4d1dec128v32(unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec256v32(unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +unsigned char *_p4d1dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4d1dec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4d1dec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4d1dec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4d1dec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4d1dec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +// ZigZag encoding +inline unsigned char *_p4zdec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start, unsigned b, unsigned bx); +inline unsigned char *_p4zdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start, unsigned b, unsigned bx); + +unsigned char *p4zdec8( unsigned char *__restrict in, unsigned n, uint8_t *__restrict out, uint8_t start); +unsigned char *p4zdec16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); +unsigned char *p4zdec32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec128v16( unsigned char *__restrict in, unsigned n, uint16_t *__restrict out, uint16_t start); // SIMD (Vertical BitPacking) +unsigned char *p4zdec128v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec256v32( unsigned char *__restrict in, unsigned n, uint32_t *__restrict out, uint32_t start); +unsigned char *p4zdec64( unsigned char *__restrict in, unsigned n, uint64_t *__restrict out, uint64_t start); + +//---------------- Direct Access functions to compressed TurboPFor array p4encx16/p4encx32 ------------------------------------------------------- + #ifdef TURBOPFOR_DAC +#include "conf.h" +#define P4D_PAD8(_x_) ( (((_x_)+8-1)/8) ) +#define P4D_B(_x_) ((_x_) & 0x7f) +#define P4D_XB(_x_) (((_x_) & 0x80)?((_x_) >> 8):0) +#define P4D_ININC(_in_, _x_) _in_ += 1+((_x_) >> 7) + +static inline unsigned p4bits(unsigned char *__restrict in, int *bx) { unsigned i = ctou16(in); *bx = P4D_XB(i); return P4D_B(i); } + +struct p4 { + unsigned long long *xmap; + unsigned char *ex; + unsigned isx,bx,cum[P4D_MAX/64+1]; + int oval,idx; +}; + +static unsigned long long p4xmap[P4D_MAX/64+1] = { 0 }; + +// prepare direct access usage +static inline void p4ini(struct p4 *p4, unsigned char **pin, unsigned n, unsigned *b) { unsigned char *in = *pin; + unsigned p4i = ctou16(in); + p4->isx = p4i&0x80; + *b = P4D_B(p4i); + p4->bx = P4D_XB(p4i); //printf("p4i=%x,b=%d,bx=%d ", p4->i, *b, p4->bx); //assert(n <= P4D_MAX); + *pin = p4->ex = ++in; + if(p4->isx) { + unsigned num=0,j; + unsigned char *p; + ++in; + p4->xmap = (unsigned long long *)in; + for(j=0; j < n/64; j++) { p4->cum[j] = num; num += popcnt64(ctou64(in+j*8)); } + if(n & 0x3f) num += popcnt64(ctou64(in+j*8) & ((1ull<<(n&0x3f))-1) ); + p4->ex = p = in + (n+7)/8; + *pin = p = p4->ex+(((uint64_t)num*p4->bx+7)/8); + } else p4->xmap = p4xmap; + p4->oval = p4->idx = -1; +} + +//---------- Get a single value with index "idx" from a "p4encx32" packed array +static ALWAYS_INLINE uint8_t p4getx8( struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx8( in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx8(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} + +static ALWAYS_INLINE uint16_t p4getx16(struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx16(in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx16(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} +static ALWAYS_INLINE uint32_t p4getx32(struct p4 *p4, unsigned char *in, unsigned idx, unsigned b) { unsigned bi, cl, u = bitgetx32(in, idx, b); + if(p4->xmap[bi=idx>>6] & (1ull<<(cl=idx&63))) u += bitgetx32(p4->ex, p4->cum[bi] + popcnt64(p4->xmap[bi] & ~(~0ull<bx) << b; + return u; +} + +// Get the next single value greater of equal to val +static ALWAYS_INLINE uint16_t p4geqx8( struct p4 *p4, unsigned char *in, unsigned b, uint8_t val) { do p4->oval += p4getx8( p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } +static ALWAYS_INLINE uint16_t p4geqx16(struct p4 *p4, unsigned char *in, unsigned b, uint16_t val) { do p4->oval += p4getx16(p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } +static ALWAYS_INLINE uint32_t p4geqx32(struct p4 *p4, unsigned char *in, unsigned b, uint32_t val) { do p4->oval += p4getx32(p4, in, ++p4->idx, b)+1; while(p4->oval < val); return p4->oval; } + +/* DO NOT USE : like p4dec32 but using direct access. This is only a demo showing direct access usage. Use p4dec32 instead for decompressing entire blocks */ +unsigned char *p4decx32( unsigned char *in, unsigned n, uint32_t *out); // unsorted +unsigned char *p4fdecx32( unsigned char *in, unsigned n, uint32_t *out, uint32_t start); // FOR increasing +unsigned char *p4f1decx32( unsigned char *in, unsigned n, uint32_t *out, uint32_t start); // FOR strictly increasing + #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/ext/for/vp4c.c b/src/ext/for/vp4c.c new file mode 100644 index 00000000000..f9237f252de --- /dev/null +++ b/src/ext/for/vp4c.c @@ -0,0 +1,423 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "TurboPFor: Integer Compression" Turbo PFor/PforDelta + +#ifndef USIZE //--------------------------------- Functions ---------------------------------------------------------------------- +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#define VINT_IN +#define BITUTIL_IN +#include "conf.h" +#include "bitpack.h" +#include "vint.h" +#include "bitutil.h" +#include "vp4.h" + +#undef P4DELTA +#define PAD8(_x_) ( (((_x_)+8-1)/8) ) + +#define HYBRID 1 // Hybrid TurboPFor : 0=fixed bit packing, 1=fixed BP+Variable byte + + #if !defined(SSE2_ON) && !defined(AVX2_ON) +#define _P4BITS _p4bits +#define P4BITS _p4bits +#define _P4ENC _p4enc +#define P4ENC p4enc +#define P4NENC p4nenc +#define BITPACK bitpack +#define BITDELTA bitdienc +#define USIZE 8 +#include "vp4c.c" +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + +#define P4DELTA 0 // p4d functions +#define P4DENC p4denc +#define P4NENC p4ndenc +#define P4NENCS p4denc +#define USIZE 8 +#include "vp4c.c" +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + +#define P4DELTA 1 // p4d1 functions +#define P4DENC p4d1enc +#define P4NENC p4nd1enc +#define P4NENCS p4d1enc +#define USIZE 8 +#include "vp4c.c" +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + +#define BITDELTA bitzenc // // p4z functions +#define P4DENC p4zenc +#define P4NENC p4nzenc +#define P4NENCS p4zenc +#define USIZE 8 +#include "vp4c.c" +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + +#undef P4DELTA +#define BITDELTA bitdienc + +#define HYBRID 0 // Direct access +#define P4BITS _p4bitsx +#define _P4BITS _p4bitsx +#define _P4ENC _p4encx +#define P4ENC p4encx +#define P4NENC p4nencx +#define USIZE 8 +#include "vp4c.c" +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + + +#undef _P4ENC +#undef P4ENC +#undef BITPACK + +#define P4NDENC(in, n, out, _csize_, _usize_, _p4c_) { if(!n) return 0;\ + unsigned char *op = out; \ + start = *in++;\ + TEMPLATE2(vbxput, _usize_)(op, start);\ + for(n--,ip = in; ip != in + (n&~(_csize_-1)); ) { PREFETCH(ip+512,0);\ + op = TEMPLATE2(_p4c_, _usize_)(ip, _csize_, op, start); ip += _csize_; start = ip[-1];\ + } if(n&=(_csize_-1)) { op = TEMPLATE2(_p4c_, _usize_)(ip, n, op, start); }\ + return op - out;\ +} + +#define P4NDDEC(in, n, out, _csize_, _usize_, _p4d_) { if(!n) return 0;\ + unsigned char *ip = in;\ + TEMPLATE2(vbxget, _usize_)(ip, start);\ + for(*out++ = start,--n,op = out; op != out+(n&~(_csize_-1)); ) { PREFETCH(ip+512,0);\ + ip = TEMPLATE2(_p4d_, _usize_)(ip, _csize_, op, start); op += _csize_; start = op[-1];\ + } if(n&=(_csize_-1)) { ip = TEMPLATE2(_p4d_, _usize_)(ip, n, op, start); }\ + return ip - in;\ +} + +unsigned char *p4senc16(uint16_t *in, unsigned n, unsigned char *out, uint16_t x) { uint16_t pa[128+32],eq, mdelta = bitdi16(in, n, 0, x); vbput16(out, mdelta); bitdienc16(in, n, pa, x, mdelta); return p4enc16(pa, n, out);} +unsigned char *p4senc32(uint32_t *in, unsigned n, unsigned char *out, uint32_t x) { uint32_t pa[128+32],eq, mdelta = bitdi32(in, n, 0, x); vbput32(out, mdelta); bitdienc32(in, n, pa, x, mdelta); return p4enc32(pa, n, out);} +unsigned char *p4senc64(uint64_t *in, unsigned n, unsigned char *out, uint64_t x) { uint64_t pa[128+64],eq, mdelta = bitdi64(in, n, 0, x); vbput64(out, mdelta); bitdienc64(in, n, pa, x, mdelta); return p4enc64(pa, n, out);} + +unsigned char *p4sdec16(unsigned char *in, unsigned n, uint16_t *out, uint16_t x) { uint16_t mdelta; vbget16(in, mdelta); in = p4dec16(in, n, out); bitdidec16(out, n, x, mdelta); return in; } +unsigned char *p4sdec32(unsigned char *in, unsigned n, uint32_t *out, uint32_t x) { uint32_t mdelta; vbget32(in, mdelta); in = p4dec32(in, n, out); bitdidec32(out, n, x, mdelta); return in; } +unsigned char *p4sdec64(unsigned char *in, unsigned n, uint64_t *out, uint64_t x) { uint64_t mdelta; vbget64(in, mdelta); in = p4dec64(in, n, out); bitdidec64(out, n, x, mdelta); return in; } + +size_t p4nsenc16(uint16_t *in, size_t n, unsigned char *out) { uint16_t *ip,start; P4NDENC(in, n, out, 128, 16, p4senc); } +size_t p4nsenc32(uint32_t *in, size_t n, unsigned char *out) { uint32_t *ip,start; P4NDENC(in, n, out, 128, 32, p4senc); } +size_t p4nsenc64(uint64_t *in, size_t n, unsigned char *out) { uint64_t *ip,start; P4NDENC(in, n, out, 128, 64, p4senc); } + +size_t p4nsdec16(unsigned char *in, size_t n, uint16_t *out) { uint16_t *op,start; P4NDDEC(in, n, out, 128, 16, p4sdec); } +size_t p4nsdec32(unsigned char *in, size_t n, uint32_t *out) { uint32_t *op,start; P4NDDEC(in, n, out, 128, 32, p4sdec); } +size_t p4nsdec64(unsigned char *in, size_t n, uint64_t *out) { uint64_t *op,start; P4NDDEC(in, n, out, 128, 64, p4sdec); } +#undef _P4BITS + #elif defined(__AVX2__) +#define BITDELTA bitdienc +#define HYBRID 1 +#define P4BITS _p4bits +#define VSIZE 256 + +#define _P4ENC _p4enc256v +#define P4ENC p4enc256v +#define P4NENC p4nenc256v +#define P4NENCS p4enc +#define BITPACK bitpack256v +#define USIZE 32 +#include "vp4c.c" + +#define P4DELTA 0 +#define P4DENC p4denc256v +#define P4NENC p4ndenc256v +#define P4NENCS p4denc +#include "vp4c.c" + +#define P4DELTA 1 +#define P4DENC p4d1enc256v +#define P4NENC p4nd1enc256v +#define P4NENCS p4d1enc +#include "vp4c.c" +#undef P4DELTA + +#define P4DELTA 0 +#define BITDELTA bitzenc +#define P4DENC p4zenc256v +#define P4NENC p4nzenc256v +#define P4NENCS p4zenc +#include "vp4c.c" + +#undef _P4ENC +#undef P4ENC +#undef BITPACK + #elif defined(__SSE2__) || defined(__ARM_NEON) //-------------------------------------------------- +#define BITDELTA bitdienc +#define HYBRID 1 +#define P4BITS _p4bits +#define USIZE 32 + +#define VSIZE 128 +#define _P4ENC _p4enc128v +#define P4ENC p4enc128v +#define P4NENCS p4enc +#define P4NENC p4nenc128v +#define BITPACK bitpack128v +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" +#define USIZE 64 +#include "vp4c.c" + +#define P4DELTA 0 +#define P4DENC p4denc128v +#define P4NENC p4ndenc128v +#define P4NENCS p4denc +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" + +#define P4DELTA 1 +#define P4DENC p4d1enc128v +#define P4NENC p4nd1enc128v +#define P4NENCS p4d1enc +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" + +#define P4DELTA 0 +#define BITDELTA bitzenc +#define P4DENC p4zenc128v +#define P4NENC p4nzenc128v +#define P4NENCS p4zenc +#define USIZE 16 +#include "vp4c.c" +#define USIZE 32 +#include "vp4c.c" + +/*#define BITDELTA bitdienc +#define VSIZE 256 +#define _P4ENC _p4enc256w +#define P4ENC p4enc256w +#define P4NENCS p4encw +#define P4NENC p4nenc256w +#define BITPACK bitpack256w +#include "vp4c.c"*/ + #endif + +#undef P4DELTA +#undef _P4ENC +#undef P4ENC +#undef BITPACK + +#else //------------------------------------------ Templates --------------------------------------------------------------- +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wparentheses" + +#pragma GCC push_options +#pragma GCC optimize ("align-functions=16") + +#define uint_t TEMPLATE3(uint, USIZE, _t) + + #ifdef VSIZE +#define CSIZE VSIZE + #else +#define CSIZE 128 + #endif + + #ifndef P4DELTA + + #ifdef _P4BITS +unsigned TEMPLATE2(_P4BITS, USIZE)(uint_t *__restrict in, unsigned n, unsigned *pbx) { + #if HYBRID > 0 && USIZE >= 16 + unsigned _vb[USIZE*2+64] = {0}, *vb=&_vb[USIZE]; + #endif + unsigned cnt[USIZE+8] = {0}, x, bx, bmp8=(n+7)/8; + uint_t *ip, u=0, a = in[0]; + int b,i,ml,l,fx=0,vv,eq=0; + + #define CNTE(i) { ++cnt[TEMPLATE2(bsr, USIZE)(ip[i])], u |= ip[i]; eq += (ip[i] == a); } + for(ip = in; ip != in+(n&~3); ip+=4) { CNTE(0); CNTE(1); CNTE(2); CNTE(3); } + for(;ip != in+n;ip++) CNTE(0); + + b = TEMPLATE2(bsr, USIZE)(u); + #if HYBRID > 0 + if(eq == n && a) { *pbx = USIZE+2; + #if USIZE == 64 + if(b == USIZE-1) b = USIZE; + #endif + return b; + } + #endif + bx = b; + ml = PAD8(n*b)+1; x = cnt[b]; + + #if HYBRID > 0 && USIZE >= 16 + #define VBB(_x_,_b_) vb[_b_-7]+=_x_; vb[_b_-15]+=_x_*2; vb[_b_-19]+=_x_*3; vb[_b_-25]+=_x_*4; + vv = x; VBB(x,b); + #else + ml -= 2+bmp8; + #endif + for(i = b-1; i >= 0; --i) { + int fi,v; + #if HYBRID > 0 && USIZE >= 16 + v = PAD8(n*i) + 2 + x + vv; + l = PAD8(n*i) + 2+bmp8 + PAD8(x*(bx-i)); + x += cnt[i]; + vv += cnt[i]+vb[i]; + VBB(cnt[i],i); + fi = l < ml; ml = fi?l:ml; b = fi?i:b; fx=fi?0:fx; + fi = v < ml; ml = fi?v:ml; b = fi?i:b; fx=fi?1:fx; + #else + l = PAD8(n*i) + PAD8(x*(bx-i)); + x += cnt[i]; + fi = l < ml; + ml = fi?l:ml; b = fi?i:b; + #endif + } //fx = 0; + #if HYBRID > 0 && USIZE >= 16 + *pbx = fx?(USIZE+1):(bx - b); + #if USIZE == 64 + if(b == USIZE-1) { b = USIZE; *pbx = 0; } + #endif + #else + *pbx = bx - b; + #endif + return b; +} + #endif + + +unsigned char *TEMPLATE2(_P4ENC, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, unsigned b, unsigned bx) { + uint_t msk = (1ull << b)-1, _in[P4D_MAX+32]={0}, inx[P4D_MAX+32]={0},a,ax; + unsigned long long xmap[P4D_MAX/64] = {0}; + unsigned miss[P4D_MAX]={0},i, xn, c; //, eq=0,eqx=0; + unsigned char *_out = out; + + if(!bx) + return TEMPLATE2(BITPACK, USIZE)(in, n, out, b); + #if HYBRID > 0 + if(bx == USIZE+2) { + TEMPLATE2(ctou, USIZE)(out) = in[0]; + return out+((b+7)/8); + } + #endif + #define MISS { miss[xn] = i; xn += in[i] > msk; _in[i] = in[i] & msk; i++; } //eq+= (_in[i] == a); } a = in[0] & msk; + for(xn = i = 0; i != n&~3; ) { MISS; MISS; MISS; MISS; } + while(i != n) MISS; + //ax = inx[miss[0]] >> b; + for(i = 0; i != xn; ++i) { + c = miss[i]; + xmap[c>>6] |= (1ull << (c&0x3f)); + inx[i] = in[c] >> b; // eqx += inx[i] == a; + } + + #if HYBRID > 0 && USIZE >= 16 + if(bx <= USIZE) { + #endif + for(i = 0; i < (n+63)/64; i++) ctou64(out+i*8) = xmap[i]; out += PAD8(n); //if(eqx == xn && bx) { out[-1] |=0x80; TEMPLATE2(ctou, USIZE)(out)=ax; out += (bx+7)/8; } else + out = TEMPLATE2(bitpack, USIZE)(inx, xn, out, bx); //if(eq == n && b) { out[-1]|= 0x80; TEMPLATE2(ctou, USIZE)(out)=a; out += (b+7)/8; } else + out = TEMPLATE2(BITPACK, USIZE)(_in, n, out, b); + #if HYBRID > 0 && USIZE >= 16 + } + else { + *out++ = xn; //if(b && eq == n) { *out++ = 0x80; TEMPLATE2(ctou, USIZE)(out) = _in[0]; out += (b+7)/8; } else { *out++ = 0; + out = TEMPLATE2(BITPACK, USIZE)(_in, n, out, b); + + out = TEMPLATE2(vbenc, USIZE)(inx, xn, out); + for(i = 0; i != xn; ++i) *out++ = miss[i]; + } + #endif + return out; +} + +unsigned char *TEMPLATE2(P4ENC, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out) { unsigned bx, b; + if(!n) return out; + b = TEMPLATE2(P4BITS, USIZE)(in, n, &bx); + TEMPLATE2(P4HVE, USIZE)(out,b,bx); + out = TEMPLATE2(_P4ENC, USIZE)(in, n, out, b, bx); + return out; +} + +size_t TEMPLATE2(P4NENC, USIZE)(uint_t *__restrict in, size_t n, unsigned char *__restrict out) { if(!n) return 0; + unsigned char *op = out; + uint_t *ip; + + for(ip = in; ip != in+(n&~(CSIZE-1)); ip += CSIZE) { unsigned bx, b; PREFETCH(ip+512,0); + b = TEMPLATE2(P4BITS, USIZE)(ip, CSIZE, &bx); + TEMPLATE2(P4HVE, USIZE)(op,b,bx); + op = TEMPLATE2(_P4ENC, USIZE)(ip, CSIZE, op, b, bx); + } + return TEMPLATE2(p4enc, USIZE)(ip, n&(CSIZE-1), op) - out; +} + #else +unsigned char *TEMPLATE2(P4DENC, USIZE)(uint_t *__restrict in, unsigned n, unsigned char *__restrict out, uint_t start) { + uint_t _in[P4D_MAX+8]={0}; + if(!n) return out; + TEMPLATE2(BITDELTA, USIZE)(in, n, _in, start, P4DELTA); + return TEMPLATE2(P4ENC, USIZE)(_in, n, out); +} + +size_t TEMPLATE2(P4NENC, USIZE)(uint_t *__restrict in, size_t n, unsigned char *__restrict out) { + unsigned char *op = out; + uint_t *ip, start = *in++; + if(!n) + return 0; + + TEMPLATE2(vbxput, USIZE)(op, start); + for(ip = in, --n; ip != in+(n&~(CSIZE-1)); ip += CSIZE) { uint_t _in[P4D_MAX+8];unsigned bx, b; PREFETCH(ip+512,0); + TEMPLATE2(BITDELTA, USIZE)(ip, CSIZE, _in, start, P4DELTA); + b = TEMPLATE2(_p4bits, USIZE)(_in, CSIZE, &bx); + TEMPLATE2(P4HVE, USIZE)(op,b,bx); + op = TEMPLATE2(_P4ENC, USIZE)(_in, CSIZE, op, b, bx); // op = TEMPLATE2(P4ENC, USIZE)(_in, CSIZE, op); + start = ip[CSIZE-1]; + } + return TEMPLATE2(P4NENCS, USIZE)(ip, n&(CSIZE-1), op, start) - out; +} + #endif +#pragma clang diagnostic pop + #endif diff --git a/src/ext/for/vp4d.c b/src/ext/for/vp4d.c new file mode 100644 index 00000000000..a255fc2a2f0 --- /dev/null +++ b/src/ext/for/vp4d.c @@ -0,0 +1,534 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression" TurboPFor - Pfor/PforDelta + +#ifndef USIZE +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#define VINT_IN +#define BITPACK_DAC +#define TURBOPFOR_DAC +#define BITUTIL_IN +#include "conf.h" +#include "bitutil.h" +#include "vint.h" +#include "bitpack.h" +#include "vp4.h" + +#define PAD8(__x) ( (((__x)+8-1)/8) ) + +#define P4DELTA(a) +#define P4DELTA_(a) + #if defined(__SSSE3__) || defined(__ARM_NEON) +extern char _shuffle_32[16][16]; // defined in bitunpack.c +extern char _shuffle_16[256][16]; + #endif + + #ifdef __AVX2__ +#define VSIZE 256 +#define P4DELTA(a) +#define P4DELTA_(a) + +#define _P4DEC _p4dec256v +#define P4DEC p4dec256v +#define P4NDEC p4ndec256v +#define P4NDECS p4dec +#define BITUNPACK bitunpack256v +#define BITUNPACKD bitunpack256v +#define _BITUNPACKD _bitunpack256v +#define USIZE 32 +#include "vp4d.c" + +#define P4DELTA(a) ,a +#define P4DELTA_(a) a +#define DELTA + +#define _P4DEC _p4ddec256v +#define P4DEC p4ddec256v +#define P4NDEC p4nddec256v +#define P4NDECS p4ddec +#define BITUNPACKD bitdunpack256v +#define _BITUNPACKD _bitdunpack256v +#define BITUNDD bitddec +#include "vp4d.c" + +#define _P4DEC _p4d1dec256v +#define P4DEC p4d1dec256v +#define P4NDEC p4nd1dec256v +#define P4NDECS p4d1dec +#define BITUNPACKD bitd1unpack256v +#define _BITUNPACKD _bitd1unpack256v +#define BITUNDD bitd1dec +#include "vp4d.c" + +#define _P4DEC _p4zdec256v +#define P4DEC p4zdec256v +#define P4NDEC p4nzdec256v +#define P4NDECS p4zdec +#define BITUNPACKD bitzunpack256v +#define _BITUNPACKD _bitzunpack256v +#define BITUNDD bitzdec +#define USIZE 32 +#include "vp4d.c" + +#undef BITUNDD + #elif !defined(SSE2_ON) && !defined(AVX2_ON) + +#define _P4DEC _p4dec +#define P4DEC p4dec +#define P4NDEC p4ndec +#define P4NDECS p4dec +#define BITUNPACK bitunpack // unpack only +#define BITUNPACKD bitunpack // integrated unpack +#define _BITUNPACKD bitunpack // integrated pfor + +#define P4DECX // direct access no 64 bits +#define USIZE 8 +#include "vp4d.c" +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" + +#undef P4DECX +#define USIZE 64 +#include "vp4d.c" + +#define P4DELTA(a) ,a +#define P4DELTA_(a) a +#define DELTA + +#define _P4DEC _p4ddec //delta0 +#define P4DEC p4ddec +#define P4NDEC p4nddec +#define P4NDECS p4ddec +#define BITUNPACKD bitdunpack +#define _BITUNPACKD _bitdunpack +#define BITUNDD bitddec +#define USIZE 8 +#include "vp4d.c" +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" +#define USIZE 64 +#include "vp4d.c" + +#define _P4DEC _p4d1dec //delta1 +#define P4DEC p4d1dec +#define P4NDEC p4nd1dec +#define P4NDECS p4d1dec +#define BITUNPACKD bitd1unpack +#define _BITUNPACKD bitd1unpack +#define BITUNDD bitd1dec +#define USIZE 8 +#include "vp4d.c" +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" +#define USIZE 64 +#include "vp4d.c" + +#define _P4DEC _p4zdec //zigzag0 +#define P4DEC p4zdec +#define P4NDEC p4nzdec +#define P4NDECS p4zdec +#define BITUNPACKD bitzunpack +#define _BITUNPACKD _bitzunpack +#define BITUNDD bitzdec +#define USIZE 8 +#include "vp4d.c" +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" +#define USIZE 64 +#include "vp4d.c" + +#undef _P4DEC +#undef P4DEC +#undef BITUNPACK +#undef BITUNDD +#undef P4DELTA +#undef USIZE +#undef DELTA + + #elif defined(__SSSE3__) || defined(__ARM_NEON) +#define VSIZE 128 +#define P4DELTA(a) +#define P4DELTA_(a) + +#define _P4DEC _p4dec128v +#define P4DEC p4dec128v +#define P4NDEC p4ndec128v +#define P4NDECS p4dec +#define BITUNPACK bitunpack128v +#define BITUNPACKD bitunpack128v +#define _BITUNPACKD _bitunpack128v +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" +#define USIZE 64 +#include "vp4d.c" + +#define P4DELTA(a) ,a +#define P4DELTA_(a) a +#define DELTA + +#define _P4DEC _p4ddec128v +#define P4DEC p4ddec128v +#define P4NDEC p4nddec128v +#define P4NDECS p4ddec +#define BITUNPACKD bitdunpack128v +#define _BITUNPACKD _bitdunpack128v +#define BITUNDD bitddec +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" + +#define _P4DEC _p4d1dec128v +#define P4DEC p4d1dec128v +#define P4NDEC p4nd1dec128v +#define P4NDECS p4d1dec +#define BITUNPACKD bitd1unpack128v +#define _BITUNPACKD _bitd1unpack128v +#define BITUNDD bitd1dec +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" + +#define _P4DEC _p4zdec128v +#define P4DEC p4zdec128v +#define P4NDEC p4nzdec128v +#define P4NDECS p4zdec +#define BITUNPACKD bitzunpack128v +#define _BITUNPACKD _bitzunpack128v +#define BITUNDD bitzdec +#define USIZE 16 +#include "vp4d.c" +#define USIZE 32 +#include "vp4d.c" + +#undef BITUNDD +#undef P4DELTA +#undef DELTA + +#define VSIZE 256 + +#define P4DELTA(a) +#define P4DELTA_(a) +#undef DELTA + +#define _P4DEC _p4dec256w +#define P4DEC p4dec256w +#define P4NDEC p4ndec256w +#define P4NDECS p4dec +#define BITUNPACK bitunpack256w +#define BITUNPACKD bitunpack256w +#define _BITUNPACKD _bitunpack256w +#include "vp4d.c" + #endif +#undef DELTA + +#else +#define uint_t TEMPLATE3(uint, USIZE, _t) + +#pragma GCC push_options +#pragma GCC optimize ("align-functions=16") + +ALWAYS_INLINE unsigned char *TEMPLATE2(_P4DEC, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out P4DELTA(uint_t start), unsigned b, unsigned bx ) { + if(!(b & 0x80)) { + #if USIZE == 64 + b = (b == 63)?64:b; // 63,64 are both encoded w. same bitsize 64 (permits using only 6 bits for b) + #endif + return TEMPLATE2(BITUNPACKD, USIZE)(in, n, out P4DELTA(start), b); // bitunpack only + } + b &= 0x7f; + #if VSIZE >= 128 // vertical SIMD bitpacking + #if USIZE == 64 + if(b+bx <= 32) // use SIMD when bitsize <= 32 (scalar horizontal bitunpack64 is used when 32 < bitsize <=64 ) + #endif + { unsigned char *pb = in; + #if VSIZE == 128 + #if USIZE == 64 + uint32_t ex[P4D_MAX+64]; + in = TEMPLATE2(bitunpack, 32)(in+16, popcnt64(ctou64(in)) + popcnt64(ctou64(in+8)), ex, bx); // unpack the fixex size part + #else + uint_t ex[P4D_MAX+64]; + in = TEMPLATE2(bitunpack, USIZE)(in+16, popcnt64(ctou64(in)) + popcnt64(ctou64(in+8)), ex, bx); + #endif + #else + uint_t ex[P4D_MAX+64]; + in = TEMPLATE2(bitunpack, USIZE)(in+32, popcnt64(ctou64(in)) + popcnt64(ctou64(in+8)) + popcnt64(ctou64(in+16)) + popcnt64(ctou64(in+24)), ex, bx); + #endif + return TEMPLATE2(_BITUNPACKD, USIZE)(in, n, out P4DELTA(start), b, ex, pb); // unpack the exceptions + } + #endif + #if VSIZE < 128 || USIZE == 64 // bitunpack the rest number of elements < 128/256 or when 32 < bitsize <=64 is used + { uint_t ex[P4D_MAX+64]; + unsigned long long bb[P4D_MAX/64]; + unsigned num=0,i,p4dn = (n+63)/64; + for(i = 0; i < n/64; i++) { bb[i] = ctou64(in+i*8); num += popcnt64(bb[i]); } + if(n & 0x3f) { bb[i] = ctou64(in+i*8) & ((1ull<<(n&0x3f))-1); num += popcnt64(bb[i]); } + in = TEMPLATE2(bitunpack, USIZE)(in+PAD8(n), num, ex, bx); + in = TEMPLATE2(BITUNPACK, USIZE)(in, n, out, b); + #if 0 //defined(__AVX2__) + { uint_t *op,*pex = ex; + for(i = 0; i < p4dn; i++) { + for(op = out; bb[i]; bb[i] >>= 8,op += 8) { unsigned m = (unsigned char)bb[i], mc=popcnt32(m), s = pex[mc]; pex[mc]=0; + _mm256_storeu_si256((__m256i *)op, _mm256_add_epi32(_mm256_loadu_si256((const __m256i*)op), mm256_maskz_expand_epi32(m,_mm256_slli_epi32(_mm256_load_si256((const __m256i*)pex), b)))); pex += mc; *pex=s; + } //out += 64; + } + } + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && USIZE == 32 + { uint_t *_op = out,*op,*pex = ex; + for(i = 0; i < p4dn; i++) { + for(op=_op; bb[i]; bb[i] >>= 4,op+=4) { const unsigned m = bb[i]&0xf; + _mm_storeu_si128((__m128i *)op, _mm_add_epi32(_mm_loadu_si128((__m128i*)op), _mm_shuffle_epi8(_mm_slli_epi32(_mm_loadu_si128((__m128i*)pex), b), _mm_load_si128((__m128i*)_shuffle_32[m]) ) )); pex += popcnt32(m); + } _op+=64; + } + } + #elif (defined(__SSSE3__) || defined(__ARM_NEON)) && USIZE == 16 + { uint_t *_op = out, *op, *pex = ex; + for(i = 0; i < p4dn; i++) { + for(op = _op; bb[i]; bb[i] >>= 8,op += 8) { const unsigned char m = bb[i]; + _mm_storeu_si128((__m128i *)op, _mm_add_epi16(_mm_loadu_si128((__m128i*)op), _mm_shuffle_epi8(_mm_slli_epi16(_mm_loadu_si128((__m128i*)pex), b), _mm_load_si128((__m128i*)_shuffle_16[m]) ) )); pex += popcnt32(m); + } _op += 64; + } + } + #else + { unsigned k = 0; + uint_t *op,*p; + for(op=out,i = 0; i < p4dn; i++,op += 64) { unsigned long long u = bb[i]; + #if 1 // faster + while(u) op[ctz64(u)] += ex[k++]<>= x; p+=x; + switch(u&0xf) { + case 0: break; //0000 + case 1: OP(0); break; //0001 + case 2: OP(1); break; //0010 + case 3: OP(1); OP(0); break; //0011 + case 4: OP(2); break; //0100 + case 5: OP(2); OP(0); break; //0101 + case 6: OP(2); OP(1); break; //0110 + case 7: OP(2); OP(1); OP(0); break; //0111 + case 8: OP(3); break; //1000 + case 9: OP(3); OP(0); break; //1001 + case 10: OP(3); OP(1); break; //1010 + case 11: OP(3); OP(1); OP(0); break; //1011 + case 12: OP(3); OP(2); break; //1100 + case 13: OP(3); OP(2); OP(0); break; //1101 + case 14: OP(3); OP(2); OP(1); break; //1110 + case 15: OP(3); OP(2); OP(1); OP(0); break; //1111 + } + u >>= 4; + p += 4; + } + #endif + } + } + #endif + } + #ifdef BITUNDD + TEMPLATE2(BITUNDD, USIZE)(out, n, start); + #endif + return in; + #endif +} + +unsigned char *TEMPLATE2(P4DEC, USIZE)(unsigned char *__restrict in, unsigned n, uint_t *__restrict out P4DELTA(uint_t start) ) { + unsigned b, bx = 0, i; + if(!n) return in; + b = *in++; + if((b & 0xc0) == 0xc0) { // all items are equal + b &= 0x3f; + #if USIZE == 64 + b = b == 63?64:b; // use 64 instead of 63 (permis using only 6 bits to store b) + #endif + uint_t u = TEMPLATE2(ctou, USIZE)(in); if(b < USIZE) u = TEMPLATE2(BZHI, USIZE)(u,b); + for(i=0; i < n; i++) out[i] = u; + #ifdef BITUNDD + TEMPLATE2(BITUNDD, USIZE)(out, n, start); + #endif + return in+(b+7)/8; + } else if(likely(!(b & 0x40))) { // PFOR + if(b & 0x80) + bx = *in++; + return TEMPLATE2(_P4DEC, USIZE)(in, n, out P4DELTA(start), b, bx); + } + else { // Variable byte +#if USIZE > 8 + uint_t ex[P4D_MAX+64],*pex=ex; + b &= 0x3f; + bx = *in++; /*if(b && *in++ == 0x80) { uint_t u = TEMPLATE2(ctou, USIZE)(in); if(b < USIZE) u = TEMPLATE2(BZHI, USIZE)(u,b); int i; for(i = 0; i < n; i++) out[i] = u; in+=(b+7)/8; } else*/ + in = TEMPLATE2(BITUNPACK, USIZE)(in, n, out, b); + in = TEMPLATE2(vbdec, USIZE)(in, bx, ex); + #define ST(j) out[in[i+j]] |= ex[i+j] << b + //#define ST(j) out[*ip++] |= (*pex++) << b; + //unsigned char *ip;for(ip = in; ip != in + (bx & ~3); ) + for(i = 0; i != (bx & ~7); i+=8) + { ST(0);ST(1);ST(2);ST(3); ST(4);ST(5);ST(6);ST(7); } + //for(;ip != in+bx; ) ST(0); + for(;i != bx; i++) ST(0); + in += bx; + #ifdef BITUNDD + TEMPLATE2(BITUNDD, USIZE)(out, n, start); + #endif + #undef ST +#endif // USIZE > 8 + return in; + } +} + +#ifdef VSIZE + #define CSIZE VSIZE +#else + #define CSIZE 128 +#endif + +size_t TEMPLATE2(P4NDEC, USIZE)(unsigned char *__restrict in, size_t n, uint_t *__restrict out) { + unsigned char *ip = in; + uint_t *op; + if(!n) return 0; + { + #ifdef DELTA + uint_t start; + TEMPLATE2(vbxget, USIZE)(ip, start); + *out++ = start; + --n; + #endif + for(op = out; op != out+(n&~(CSIZE-1)); op += CSIZE) { + unsigned b = *ip++, bx = 0, i; PREFETCH(ip+512,0);//ip = TEMPLATE2(P4DEC, USIZE)(ip, CSIZE, op P4DELTA(start)); + + if((b & 0xc0) == 0xc0) { + b &= 0x3f; + #if USIZE == 64 + b = b == 63?64:b; + #endif + uint_t u = TEMPLATE2(ctou, USIZE)(ip); if(b < USIZE) u = TEMPLATE2(BZHI, USIZE)(u,b); + int i; for(i=0; i < CSIZE; i++) op[i] = u; + #ifdef BITUNDD + TEMPLATE2(BITUNDD, USIZE)(op, CSIZE, start); + #endif + ip += (b+7)/8; + } else if(likely(!(b & 0x40))) { + if(b & 0x80) + bx = *ip++; + ip = TEMPLATE2(_P4DEC, USIZE)(ip, CSIZE, op P4DELTA(start), b, bx); + } + #if USIZE > 8 + else { + uint_t ex[P4D_MAX+64]; + b &= 0x3f; + bx = *ip++; //f(*ip++ == 0x80 && b) { uint_t u = TEMPLATE2(ctou, USIZE)(ip); ip+=(b+7)/8; if(b < USIZE) u = TEMPLATE2(BZHI, USIZE)(u,b); int i; for(i=0; i < CSIZE; i++) op[i] = u; } else + ip = TEMPLATE2(BITUNPACK, USIZE)(ip, CSIZE, op, b); + ip = TEMPLATE2(vbdec, USIZE)(ip, bx, ex); + for(i = 0; i != (bx & ~7); i += 8) { + op[ip[i ]] |= ex[i ] << b; + op[ip[i+1]] |= ex[i+1] << b; + op[ip[i+2]] |= ex[i+2] << b; + op[ip[i+3]] |= ex[i+3] << b; + op[ip[i+4]] |= ex[i+4] << b; + op[ip[i+5]] |= ex[i+5] << b; + op[ip[i+6]] |= ex[i+6] << b; + op[ip[i+7]] |= ex[i+7] << b; + } + for(;i != bx; i++) + op[ip[i]] |= ex[i] << b; + ip += bx; + #ifdef BITUNDD + TEMPLATE2(BITUNDD, USIZE)(op, CSIZE, start); + #endif + } + #endif + P4DELTA_(start = op[CSIZE-1]); + } + return TEMPLATE2(P4NDECS, USIZE)(ip, n&(CSIZE-1), op P4DELTA(start)) - in; + } +} + + #ifdef P4DECX +unsigned char *TEMPLATE2(p4decx, USIZE)(unsigned char *in, unsigned n, uint_t *__restrict out) { + unsigned b,i; + struct p4 p4; + + p4ini(&p4, &in, n, &b); + + if(unlikely(p4.isx)) { + #define ITX(k) out[i+k] = TEMPLATE2(p4getx, USIZE)(&p4, in, i+k, b); + for(i = 0; i != n&~3; i += 4) { ITX(0); ITX(1); ITX(2); ITX(3); } + for( ; i != n; i++ ) ITX(0); + } else { + #define ITY(k) out[i+k] = TEMPLATE2(bitgetx, USIZE)(in, i+k, b); + for(i = 0; i != n&~3; i += 4) { ITY(0); ITY(1); ITY(2); ITY(3); } + for( ; i != n; i++) ITY(0); + } + return in + PAD8(n*b); +} + +unsigned char *TEMPLATE2(p4f1decx, USIZE)(unsigned char *in, unsigned n, uint_t *__restrict out, uint_t start) { + unsigned b,i; + struct p4 p4; + + p4ini(&p4, &in, n, &b); + if(unlikely(p4.isx)) { + #define ITX(k) out[i+k] = TEMPLATE2(p4getx, USIZE)(&p4, in, (i+k), b)+start+i+k+1; + for(i = 0; i != n&~3; i+=4) { ITX(0); ITX(1); ITX(2); ITX(3); } + for( ; i != n; i++) ITX(0); + } else { + #define ITY(k) out[i+k] = TEMPLATE2(bitgetx, USIZE)(in, (i+k), b)+start+i+k+1; + for(i = 0; i != n&~3; i += 4) { ITY(0); ITY(1); ITY(2); ITY(3); } + for( ; i != n; i++) ITY(0); + } + return in + PAD8(n*b); +} + +unsigned char *TEMPLATE2(p4fdecx, USIZE)(unsigned char *in, unsigned n, uint_t *__restrict out, uint_t start) { + unsigned b,i; + struct p4 p4; + p4ini(&p4, &in, n, &b); + + if(unlikely(p4.isx)) { + #define ITX(k) out[i+k] = TEMPLATE2(p4getx, USIZE)(&p4, in, i+k, b)+start; + for(i = 0; i != n&~3; i+=4) { ITX(0); ITX(1); ITX(2); ITX(3); } + for( ; i != n; i++) ITX(0); + } else { + #define ITY(k) out[i+k] = TEMPLATE2(bitgetx, USIZE)(in, (i+k), b)+start; + for(i = 0; i != n&~3; i+=4) { ITY(0); ITY(1); ITY(2); ITY(3); } + for( ; i != n; i++) ITY(0); + } + return in + PAD8(n*b); +} + #endif +#endif diff --git a/src/ext/for/vs/bitpack_avx2.c b/src/ext/for/vs/bitpack_avx2.c new file mode 100644 index 00000000000..8e00972f785 --- /dev/null +++ b/src/ext/for/vs/bitpack_avx2.c @@ -0,0 +1,2 @@ +#define AVX2_ON +#include "bitpack.c" diff --git a/src/ext/for/vs/bitpack_sse.c b/src/ext/for/vs/bitpack_sse.c new file mode 100644 index 00000000000..7984e6a07df --- /dev/null +++ b/src/ext/for/vs/bitpack_sse.c @@ -0,0 +1,2 @@ +#define SSE2_ON +#include "bitpack.c" diff --git a/src/ext/for/vs/bitunpack_avx2.c b/src/ext/for/vs/bitunpack_avx2.c new file mode 100644 index 00000000000..26d1115d15c --- /dev/null +++ b/src/ext/for/vs/bitunpack_avx2.c @@ -0,0 +1,2 @@ +#define AVX2_ON +#include "bitunpack.c" diff --git a/src/ext/for/vs/bitunpack_sse.c b/src/ext/for/vs/bitunpack_sse.c new file mode 100644 index 00000000000..fe0f4de48e0 --- /dev/null +++ b/src/ext/for/vs/bitunpack_sse.c @@ -0,0 +1,2 @@ +#define SSE2_ON +#include "bitunpack.c" diff --git a/src/ext/for/vs/getopt.c b/src/ext/for/vs/getopt.c new file mode 100644 index 00000000000..0d5fa5df697 --- /dev/null +++ b/src/ext/for/vs/getopt.c @@ -0,0 +1,562 @@ +/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "getopt.h" +#include +#include +#include + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char __declspec(dllimport) *__progname; +#endif + +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt,va_list ap) +{ + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); +} + +static void +warnx(const char *fmt,...) +{ + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} diff --git a/src/ext/for/vs/getopt.h b/src/ext/for/vs/getopt.h new file mode 100644 index 00000000000..65d533ef92a --- /dev/null +++ b/src/ext/for/vs/getopt.h @@ -0,0 +1,97 @@ +#ifndef __GETOPT_H__ +/** + * DISCLAIMER + * This file has no copyright assigned and is placed in the Public Domain. + * This file is a part of the w64 mingw-runtime package. + * + * The w64 mingw-runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#if _MSC_VER >= 1300 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern int optind; /* index of first non-option in argv */ +extern int optopt; /* single option character, as parsed */ +extern int opterr; /* flag to enable built-in diagnostics... */ + /* (user may set to zero, to suppress) */ + +extern char *optarg; /* pointer to argument of current option */ + +extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; + +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; + +extern int getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +extern int getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ diff --git a/src/ext/for/vs/inttypes.h b/src/ext/for/vs/inttypes.h new file mode 100644 index 00000000000..2410b13a115 --- /dev/null +++ b/src/ext/for/vs/inttypes.h @@ -0,0 +1,306 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/src/ext/for/vs/stdint.h b/src/ext/for/vs/stdint.h new file mode 100644 index 00000000000..cb2acd93848 --- /dev/null +++ b/src/ext/for/vs/stdint.h @@ -0,0 +1,259 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if _MSC_VER >= 1600 // [ +#include +#else // ] _MSC_VER >= 1600 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/src/ext/for/vs/transpose_avx2.c b/src/ext/for/vs/transpose_avx2.c new file mode 100644 index 00000000000..f7948d88991 --- /dev/null +++ b/src/ext/for/vs/transpose_avx2.c @@ -0,0 +1,2 @@ +#define AVX2_ON +#include "transpose.c" diff --git a/src/ext/for/vs/transpose_sse.c b/src/ext/for/vs/transpose_sse.c new file mode 100644 index 00000000000..84c18de7ebb --- /dev/null +++ b/src/ext/for/vs/transpose_sse.c @@ -0,0 +1,2 @@ +#define SSE2_ON +#include "transpose.c" diff --git a/src/ext/for/vs/vp4c_avx2.c b/src/ext/for/vs/vp4c_avx2.c new file mode 100644 index 00000000000..db5c4acaacd --- /dev/null +++ b/src/ext/for/vs/vp4c_avx2.c @@ -0,0 +1,2 @@ +#define AVX2_ON +#include "vp4c.c" diff --git a/src/ext/for/vs/vp4c_sse.c b/src/ext/for/vs/vp4c_sse.c new file mode 100644 index 00000000000..5bdbdd54cf1 --- /dev/null +++ b/src/ext/for/vs/vp4c_sse.c @@ -0,0 +1,2 @@ +#define SSE2_ON +#include "vp4c.c" diff --git a/src/ext/for/vs/vp4d_avx2.c b/src/ext/for/vs/vp4d_avx2.c new file mode 100644 index 00000000000..b454a42eb54 --- /dev/null +++ b/src/ext/for/vs/vp4d_avx2.c @@ -0,0 +1,2 @@ +#define AVX2_ON +#include "vp4d.c" diff --git a/src/ext/for/vs/vp4d_sse.c b/src/ext/for/vs/vp4d_sse.c new file mode 100644 index 00000000000..c8cc159f410 --- /dev/null +++ b/src/ext/for/vs/vp4d_sse.c @@ -0,0 +1,2 @@ +#define SSE2_ON +#include "vp4d.c" diff --git a/src/ext/for/vs/vs2017/TurboPFor.sln b/src/ext/for/vs/vs2017/TurboPFor.sln new file mode 100644 index 00000000000..43f78806c82 --- /dev/null +++ b/src/ext/for/vs/vs2017/TurboPFor.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.757 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TurboPFor", "TurboPFor.vcxproj", "{A162F37F-183F-4250-88AB-9B9FBDE30B04}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "icapp", "icapp.vcxproj", "{6876BEB8-2B45-48B9-8381-1D4094FE8868}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Debug|x64.ActiveCfg = Debug|x64 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Debug|x64.Build.0 = Debug|x64 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Debug|x86.ActiveCfg = Debug|Win32 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Debug|x86.Build.0 = Debug|Win32 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Release|x64.ActiveCfg = Release|x64 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Release|x64.Build.0 = Release|x64 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Release|x86.ActiveCfg = Release|Win32 + {A162F37F-183F-4250-88AB-9B9FBDE30B04}.Release|x86.Build.0 = Release|Win32 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Debug|x64.ActiveCfg = Debug|x64 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Debug|x64.Build.0 = Debug|x64 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Debug|x86.ActiveCfg = Debug|Win32 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Debug|x86.Build.0 = Debug|Win32 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Release|x64.ActiveCfg = Release|x64 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Release|x64.Build.0 = Release|x64 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Release|x86.ActiveCfg = Release|Win32 + {6876BEB8-2B45-48B9-8381-1D4094FE8868}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A02524FA-10E2-4E1C-BE79-0AE7B077D2CE} + EndGlobalSection +EndGlobal diff --git a/src/ext/for/vs/vs2017/TurboPFor.vcxproj b/src/ext/for/vs/vs2017/TurboPFor.vcxproj new file mode 100644 index 00000000000..526a68fedaf --- /dev/null +++ b/src/ext/for/vs/vs2017/TurboPFor.vcxproj @@ -0,0 +1,226 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 15.0 + {A162F37F-183F-4250-88AB-9B9FBDE30B04} + Win32Proj + TurboPFor + 10.0.17763.0 + TurboPFor + + + + StaticLibrary + true + v141 + + + StaticLibrary + true + v141 + + + StaticLibrary + false + v141 + + + StaticLibrary + false + v141 + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + + + true + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + + + false + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + + + false + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + + + + Disabled + true + __SSE__;__SSE2__;__SSE3__;__SSSE3__;__SSE4_1__;__SSE4_2__;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;_DEBUG;%(PreprocessorDefinitions) + AdvancedVectorExtensions + MultiThreadedDebug + true + /w24003 /w24005 /w24028 /w24047 /w24090 /w24133 /w24146 /w24333 /w24789 %(AdditionalOptions) + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-array-bounds -Wno-implicit-int -Wno-unused-label -Wno-uninitialized -Wno-missing-braces -Wno-int-conversion -Wno-macro-redefined -Wno-unknown-pragmas -Wno-shift-op-parentheses -Wno-compare-distinct-pointer-types %(AdditionalOptions) + ../.. + + + + + Disabled + true + __SSE__;__SSE2__;__SSE3__;__SSSE3__;__SSE4_1__;__SSE4_2__;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;_DEBUG;%(PreprocessorDefinitions) + AdvancedVectorExtensions + MultiThreadedDebug + true + /w24003 /w24005 /w24028 /w24047 /w24090 /w24133 /w24146 /w24333 /w24789 %(AdditionalOptions) + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-array-bounds -Wno-implicit-int -Wno-unused-label -Wno-uninitialized -Wno-missing-braces -Wno-int-conversion -Wno-macro-redefined -Wno-unknown-pragmas -Wno-shift-op-parentheses -Wno-compare-distinct-pointer-types %(AdditionalOptions) + ../.. + + + + + MaxSpeed + true + true + true + __SSE__;__SSE2__;__SSE3__;__SSSE3__;__SSE4_1__;__SSE4_2__;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + AdvancedVectorExtensions + Speed + MultiThreaded + true + /w24003 /w24005 /w24028 /w24047 /w24090 /w24133 /w24146 /w24333 /w24789 %(AdditionalOptions) + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-array-bounds -Wno-implicit-int -Wno-unused-label -Wno-uninitialized -Wno-missing-braces -Wno-int-conversion -Wno-macro-redefined -Wno-unknown-pragmas -Wno-shift-op-parentheses -Wno-compare-distinct-pointer-types %(AdditionalOptions) + ../.. + + + + + MaxSpeed + true + true + true + __SSE__;__SSE2__;__SSE3__;__SSSE3__;__SSE4_1__;__SSE4_2__;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + AdvancedVectorExtensions + Speed + MultiThreaded + true + /w24003 /w24005 /w24028 /w24047 /w24090 /w24133 /w24146 /w24333 /w24789 %(AdditionalOptions) + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-array-bounds -Wno-implicit-int -Wno-unused-label -Wno-uninitialized -Wno-missing-braces -Wno-int-conversion -Wno-macro-redefined -Wno-unknown-pragmas -Wno-shift-op-parentheses -Wno-compare-distinct-pointer-types %(AdditionalOptions) + ../.. + + + + + + + + + + + + + + + + + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + + + + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + + + + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + + + + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + + + + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + AdvancedVectorExtensions2 + __AVX2__;%(PreprocessorDefinitions) + __AVX2__;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/for/vs/vs2017/TurboPFor.vcxproj.filters b/src/ext/for/vs/vs2017/TurboPFor.vcxproj.filters new file mode 100644 index 00000000000..80e1698104d --- /dev/null +++ b/src/ext/for/vs/vs2017/TurboPFor.vcxproj.filters @@ -0,0 +1,101 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/src/ext/for/vs/vs2017/icapp.vcxproj b/src/ext/for/vs/vs2017/icapp.vcxproj new file mode 100644 index 00000000000..883892af4c7 --- /dev/null +++ b/src/ext/for/vs/vs2017/icapp.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + {a162f37f-183f-4250-88ab-9b9fbde30b04} + + + + 15.0 + {6876BEB8-2B45-48B9-8381-1D4094FE8868} + Win32Proj + icapp + 10.0.17763.0 + + + + Application + true + v141 + + + Application + true + v141 + + + Application + false + v141 + + + Application + false + v141 + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)msvc.build\$(Platform)-$(Configuration)\ + $(SolutionDir)msvc.build\.obj\$(Platform)-$(Configuration)\$(ProjectName)\ + + + + Disabled + true + CODEC2;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;_DEBUG;%(PreprocessorDefinitions) + true + /w24146 /w24133 /w24996 + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-unused-label -Wno-unused-function -Wno-logical-op-parentheses -Wno-pointer-type-mismatch -Wno-sometimes-uninitialized + MultiThreadedDebug + AdvancedVectorExtensions + ..\..\ext + + + Console + true + + + + + Disabled + true + CODEC2;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;_DEBUG;%(PreprocessorDefinitions) + true + /w24146 /w24133 /w24996 + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-unused-label -Wno-unused-function -Wno-logical-op-parentheses -Wno-pointer-type-mismatch -Wno-sometimes-uninitialized + MultiThreadedDebug + AdvancedVectorExtensions2 + ..\..\ext + + + Console + true + + + + + MaxSpeed + true + true + true + CODEC2;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + true + /w24146 /w24133 /w24996 + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-unused-label -Wno-unused-function -Wno-logical-op-parentheses -Wno-pointer-type-mismatch -Wno-sometimes-uninitialized + MultiThreaded + AdvancedVectorExtensions + ..\..\ext + + + Console + true + true + true + + + + + MaxSpeed + true + true + true + CODEC2;_CRT_SECURE_NO_WARNINGS=;_CONSOLE;NDEBUG;%(PreprocessorDefinitions) + true + /w24146 /w24133 /w24996 + -Wno-parentheses -Wno-unused-variable -Wno-incompatible-pointer-types -Wno-implicit-function-declaration -Wno-tautological-constant-out-of-range-compare -Wno-pointer-sign -Wno-unused-label -Wno-unused-function -Wno-logical-op-parentheses -Wno-pointer-type-mismatch -Wno-sometimes-uninitialized + MultiThreaded + AdvancedVectorExtensions2 + ..\..\ext + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/src/ext/for/vs/vs2017/icapp.vcxproj.filters b/src/ext/for/vs/vs2017/icapp.vcxproj.filters new file mode 100644 index 00000000000..01dec6bdeec --- /dev/null +++ b/src/ext/for/vs/vs2017/icapp.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + Source Files + + + Source Files + + + diff --git a/src/ext/for/vsimple.c b/src/ext/for/vsimple.c new file mode 100644 index 00000000000..0eccc6d76eb --- /dev/null +++ b/src/ext/for/vsimple.c @@ -0,0 +1,536 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression" variable simple + #ifndef USIZE + #ifdef __SSE2__ +#include + #elif defined(__ARM_NEON) +#include +#include "sse_neon.h" + #endif +#pragma warning( disable : 4005) +#pragma warning( disable : 4090) +#pragma warning( disable : 4068) + +#include "conf.h" +#include "vsimple.h" + + #ifdef __ARM_NEON +#define PREFETCH(_ip_,_rw_) + #else +#define PREFETCH(_ip_,_rw_) __builtin_prefetch(_ip_,_rw_) + #endif + + #ifndef SV_LIM32 +#define USE_RLE + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 +#define SV_LIM8 unsigned char s_lim8[] = { 0, 28, 28, 28, 28, 36, 36, 36, 36, 0 }; +#define SV_ITM8 unsigned s_itm8[] = { 0, 28, 14, 9, 7, 7, 6, 5, 4, -1 } +#define SV_LIM16 unsigned char s_lim16[] = { 0, 28, 28, 28, 28, 36, 36, 36, 36, 36, 60, 60, 60, 60, 60, 60, 60, 0 }; +#define SV_ITM16 unsigned s_itm16[] = { 0, 28, 14, 9, 7, 7, 6, 5, 4, 4, 6, 5, 5, 4, 4, 4, 3, -1 } +#define SV_LIM32 unsigned char s_lim32[] = { 0, 28, 28, 28, 28, 36, 36, 36, 36, 36, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 0 }; +#define SV_ITM32 unsigned s_itm32[] = { 0, 28, 14, 9, 7, 7, 6, 5, 4, 4, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, -1 } + +#define SV_LIM64 unsigned char s_lim64[] = { 0, 28, 28, 28, 28, 36, 36, 36, 36, 36, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,\ + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 64, 64, 0 }; + +#define SV_ITM64 unsigned s_itm64[] = { 0, 28, 14, 9, 7, 7, 6, 5, 4, 4, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,\ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1 } + +static SV_LIM8; +static SV_ITM8; +static SV_LIM16; +static SV_ITM16; +static SV_LIM32; +static SV_ITM32; +static SV_ITM64; +static SV_LIM64; + +#define EFE(__x,__i,__start) ((__x[__i] - __start)-(__i)*EF_INC) + + #endif + +#define VSENC vsenc +#define VSDEC vsdec + +#define USIZE 8 +#include "vsimple.c" +#undef USIZE + +#define USIZE 16 +#include "vsimple.c" +#undef USIZE + +#define USIZE 32 +#include "vsimple.c" +#undef USIZE + +#define USIZE 64 +#include "vsimple.c" +#undef USIZE + + #else + +#include +#include +#include "conf.h" +#define VINT_IN +#include "vint.h" +#define uint_t TEMPLATE3(uint, USIZE, _t) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunsequenced" + +unsigned char *TEMPLATE2(VSENC, USIZE)(uint_t *__restrict in, size_t n, unsigned char *__restrict out) { + unsigned xm,m,r,x; + uint_t *e = in+n,*ip,*sp; + unsigned char *op = out,*op_ = out+n*(USIZE/8); + for(ip = in; ip < e; ) { PREFETCH(ip+256, 0); + sp = ip; + #ifdef USE_RLE + if(ip+4 < e && *ip == *(ip+1)) { + uint_t *q = ip+1; + while(q+1 < e && *(q+1) == *ip) q++; + r = q - ip; + if(r*TEMPLATE2(bsr, USIZE)(*ip) > 16 || (!*ip && r>4)) { + m = (*ip)?(USIZE<=32?33:65):0; + goto a; + } + } else + #endif + r = 0; + for(m = x = TEMPLATE2(bsr, USIZE)(*ip);(r+1)*(xm = x > m?x:m) <= TEMPLATE2(s_lim, USIZE)[xm] && ip+r= 0xf) { + *op++ = 0xf0; + if(n <= 0x100) + *op++ = r; + else + vbxput32(op, r); + } else *op++ = r<<4; + break; + case 1: + ctou32(op) = 1 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 5 | + (unsigned)ip[ 2] << 6 | + (unsigned)ip[ 3] << 7 | + (unsigned)ip[ 4] << 8 | + (unsigned)ip[ 5] << 9 | + (unsigned)ip[ 6] << 10 | + (unsigned)ip[ 7] << 11 | + (unsigned)ip[ 8] << 12 | + (unsigned)ip[ 9] << 13 | + (unsigned)ip[10] << 14 | + (unsigned)ip[11] << 15 | + (unsigned)ip[12] << 16 | + (unsigned)ip[13] << 17 | + (unsigned)ip[14] << 18 | + (unsigned)ip[15] << 19 | + (unsigned)ip[16] << 20 | + (unsigned)ip[17] << 21 | + (unsigned)ip[18] << 22 | + (unsigned)ip[19] << 23 | + (unsigned)ip[20] << 24 | + (unsigned)ip[21] << 25 | + (unsigned)ip[22] << 26 | + (unsigned)ip[23] << 27 | + (unsigned)ip[24] << 28 | + (unsigned)ip[25] << 29 | + (unsigned)ip[26] << 30 | + (unsigned)ip[27] << 31; ip += 28; op += 4; + break; + case 2: + ctou32(op) = 2 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 6 | + (unsigned)ip[ 2] << 8 | + (unsigned)ip[ 3] << 10 | + (unsigned)ip[ 4] << 12 | + (unsigned)ip[ 5] << 14 | + (unsigned)ip[ 6] << 16 | + (unsigned)ip[ 7] << 18 | + (unsigned)ip[ 8] << 20 | + (unsigned)ip[ 9] << 22 | + (unsigned)ip[10] << 24 | + (unsigned)ip[11] << 26 | + (unsigned)ip[12] << 28 | + (unsigned)ip[13] << 30; ip += 14; op += 4; + break; + case 3: + ctou32(op) = 3 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 7 | + (unsigned)ip[ 2] << 10 | + (unsigned)ip[ 3] << 13 | + (unsigned)ip[ 4] << 16 | + (unsigned)ip[ 5] << 19 | + (unsigned)ip[ 6] << 22 | + (unsigned)ip[ 7] << 25 | + (unsigned)ip[ 8] << 28; ip += 9; op += 4; + break; + case 4: + ctou64(op) = 4 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 8 | + (unsigned)ip[ 2] << 12 | + (unsigned)ip[ 3] << 16 | + (unsigned)ip[ 4] << 20 | + (unsigned)ip[ 5] << 24 | + (unsigned)ip[ 6] << 28; ip += 7; op += 4; + break; + case 5: + ctou64(op) = 5 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 9 | + (unsigned)ip[ 2] << 14 | + (unsigned)ip[ 3] << 19 | + (unsigned)ip[ 4] << 24 | + (uint64_t)ip[ 5] << 29 | + (uint64_t)ip[ 6] << 34; ip += 7; op += 5; + break; + case 6: + ctou64(op) = 6 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 10 | + (unsigned)ip[ 2] << 16 | + (unsigned)ip[ 3] << 22 | + (uint64_t)ip[ 4] << 28 | + (uint64_t)ip[ 5] << 34; ip += 6; op += 5; + break; + case 7: + ctou64(op) = 7 | + (unsigned)ip[ 0] << 5 | + (unsigned)ip[ 1] << 12 | + (unsigned)ip[ 2] << 19 | + (uint64_t)ip[ 3] << 26 | + (uint64_t)ip[ 4] << 33; ip += 5; op += 5; + break; + case 8: + case 9: + ctou64(op) = 9 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 13 | + (unsigned)ip[ 2] << 22 | + (uint64_t)ip[ 3] << 31; ip += 4; op += 5; + break; + case 10: + ctou64(op) = 10 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 14 | + (uint64_t)ip[ 2] << 24 | + (uint64_t)ip[ 3] << 34 | + (uint64_t)ip[ 4] << 44 | + (uint64_t)ip[ 5] << 54; ip += 6; op += 8; + break; + + case 11: + case 12: + ctou64(op) = 12 | + (unsigned)ip[ 0] << 4 | + (unsigned)ip[ 1] << 16 | + (uint64_t)ip[ 2] << 28 | + (uint64_t)ip[ 3] << 40 | + (uint64_t)ip[ 4] << 52; ip += 5; op += 8; + break; + case 13: + case 14: + case 15: + ctou64(op) = 15 | + (unsigned)ip[ 0] << 4 | + (uint64_t)ip[ 1] << 19 | + (uint64_t)ip[ 2] << 34 | + (uint64_t)ip[ 3] << 49; ip += 4; op += 8; + break; + case 16: + case 17: + case 18: + case 19: + case 20: + ctou64(op) = 11 | + (unsigned)ip[ 0] << 4 | + (uint64_t)ip[ 1] << 24 | + (uint64_t)ip[ 2] << 44; ip += 3; op += 8; + break; + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + ctou64(op) = 13 | + (uint64_t)ip[ 0] << 4 | + (uint64_t)ip[ 1] << 34; ip += 2; op += 8; + break; + case 31: + case 32: + #if USIZE == 64 + case 33: case 34: case 35: case 36: + #endif + ctou64(op) = 14 | + (uint64_t)ip[ 0] << 4; ip++; op += 5; + break; + #if USIZE == 64 + default: xm = (m+7)/8; + *op++ = 0x17 | (xm-1) << 5; + ctou64(op) = (uint64_t)ip[ 0]; ip++; op += xm; + break; + #endif + #ifdef USE_RLE + case USIZE<=32?33:65: ip += r; + if(--r >= 0xf) { + *op++ = 0xf0|8; + if(n <= 0x100) + *op++ = r; + else + vbxput32(op, r); + } else *op++ = r<<4|8; + TEMPLATE2(vbxput, USIZE)(op, ip[0]); + break; + #endif + + } + if(op > op_) { *out++ = 0; memcpy(out, in, n*(USIZE/8)); return out+n*(USIZE/8); } + } + return op; +} +#pragma clang diagnostic pop + + +#define OP(__x) op[__x] // *op++ // +#define OPI(__x) op+=__x// // + +unsigned char *TEMPLATE2(VSDEC, USIZE)(unsigned char *__restrict ip, size_t n, uint_t *__restrict op) { + uint_t *op_ = op+n; + while(op < op_) { + uint64_t w = *(uint64_t *)ip; PREFETCH(ip+256, 0); + switch(w & 0xf) { + case 0: { + uint_t *q = op; + unsigned r = (w>>4)&0xf; + if(!r) { memcpy(op,ip+1, n*(USIZE/8)); return ip+n*(USIZE/8); } + #if defined(__SSE2__) || defined(__ARM_NEON) + __m128i zv = _mm_setzero_si128(); + #endif + ip++; + if(unlikely(r == 0xf)) { + if(n <= 0x100) + r = (w>>8)&0xff, ip++; + else { vbxget32(ip, r); } + } + r -= 1; + op += r+1; + while(q < op) { + #if defined(__SSE2__) || defined(__ARM_NEON) + _mm_storeu_si128((__m128i *)q,zv); q = (uint_t *)((unsigned char *)q+16); + _mm_storeu_si128((__m128i *)q,zv); q = (uint_t *)((unsigned char *)q+16); + #else + q[0]=q[1]=q[2]=q[3]=q[4]=q[5]=q[6]=q[7]=0; q+=8; + #endif + } //while(r-->=0) *op++=0; + } break; + case 1: + OP( 0) = (w >> 4) & 1; + OP( 1) = (w >> 5) & 1; + OP( 2) = (w >> 6) & 1; + OP( 3) = (w >> 7) & 1; + OP( 4) = (w >> 8) & 1; + OP( 5) = (w >> 9) & 1; + OP( 6) = (w >> 10) & 1; + OP( 7) = (w >> 11) & 1; + OP( 8) = (w >> 12) & 1; + OP( 9) = (w >> 13) & 1; + OP(10) = (w >> 14) & 1; + OP(11) = (w >> 15) & 1; + OP(12) = (w >> 16) & 1; + OP(13) = (w >> 17) & 1; + OP(14) = (w >> 18) & 1; + OP(15) = (w >> 19) & 1; + OP(16) = (w >> 20) & 1; + OP(17) = (w >> 21) & 1; + OP(18) = (w >> 22) & 1; + OP(19) = (w >> 23) & 1; + OP(20) = (w >> 24) & 1; + OP(21) = (w >> 25) & 1; + OP(22) = (w >> 26) & 1; + OP(23) = (w >> 27) & 1; + OP(24) = (w >> 28) & 1; + OP(25) = (w >> 29) & 1; + OP(26) = (w >> 30) & 1; + OP(27) = (w >> 31) & 1; OPI( 28); ip+=4; + break; + case 2: + OP( 0) = (w >> 4) & 3; + OP( 1) = (w >> 6) & 3; + OP( 2) = (w >> 8) & 3; + OP( 3) = (w >> 10) & 3; + OP( 4) = (w >> 12) & 3; + OP( 5) = (w >> 14) & 3; + OP( 6) = (w >> 16) & 3; + OP( 7) = (w >> 18) & 3; + OP( 8) = (w >> 20) & 3; + OP( 9) = (w >> 22) & 3; + OP(10) = (w >> 24) & 3; + OP(11) = (w >> 26) & 3; + OP(12) = (w >> 28) & 3; + OP(13) = (w >> 30) & 3; OPI( 14); ip+=4; + break; + case 3: + OP( 0) = (w >> 4) & 7; + OP( 1) = (w >> 7) & 7; + OP( 2) = (w >> 10) & 7; + OP( 3) = (w >> 13) & 7; + OP( 4) = (w >> 16) & 7; + OP( 5) = (w >> 19) & 7; + OP( 6) = (w >> 22) & 7; + OP( 7) = (w >> 25) & 7; + OP( 8) = (w >> 28) & 7; OPI( 9); ip+=4; + break; + case 4: + OP( 0) = (w >> 4) & 0xf; + OP( 1) = (w >> 8) & 0xf; + OP( 2) = (w >> 12) & 0xf; + OP( 3) = (w >> 16) & 0xf; + OP( 4) = (w >> 20) & 0xf; + OP( 5) = (w >> 24) & 0xf; + OP( 6) = (w >> 28) & 0xf; OPI( 7); ip+=4; + break; + case 5: + OP( 0) = (w >> 4) & 0x1f; + OP( 1) = (w >> 9) & 0x1f; + OP( 2) = (w >> 14) & 0x1f; + OP( 3) = (w >> 19) & 0x1f; + OP( 4) = (w >> 24) & 0x1f; + OP( 5) = (w >> 29) & 0x1f; + OP( 6) = (w >> 34) & 0x1f; OPI( 7); ip+=5; + break; + case 6: + OP(0) = (w >> 4) & 0x3f; + OP(1) = (w >> 10) & 0x3f; + OP(2) = (w >> 16) & 0x3f; + OP(3) = (w >> 22) & 0x3f; + OP(4) = (w >> 28) & 0x3f; + OP(5) = (w >> 34) & 0x3f; OPI( 6); ip+=5; + break; + + case 7: + #if USIZE == 64 + if(unlikely((w>>4) & 1)) { + unsigned b = ((*ip++) >> 5)+1; + *op = *(unsigned long long *)ip; + if(unlikely(b!=8)) + *op &= (1ull<<(b*8))-1; op++; ip += b; + break; + } + #endif + OP(0) = (w >> 5) & 0x7f; + OP(1) = (w >> 12) & 0x7f; + OP(2) = (w >> 19) & 0x7f; + OP(3) = (w >> 26) & 0x7f; + OP(4) = (w >> 33) & 0x7f; OPI( 5); ip+=5; + break; + + #ifdef USE_RLE + case 8: { + uint_t *q=op,u; + int r = (w>>4)&0xf; + ip++; + if(unlikely(r == 0xf)) { + if(n <= 0x100) + r = (w>>8)&0xff, ip++; + else { vbxget32(ip, r); } + } + op += r+1; TEMPLATE2(vbxget, USIZE)(ip,u); + #if (defined(__SSE2__) || defined(__ARM_NEON)) && USIZE == 32 + { __m128i v = _mm_set1_epi32(u); + while(q < op) { + _mm_storeu_si128((__m128i *)q,v); q += 4; + _mm_storeu_si128((__m128i *)q,v); q += 4; + } + } + #else + while(q < op) { + q[0]=q[1]=q[2]=q[3]=q[4]=q[5]=q[6]=q[7]=u; q+=8; + } //while(r-->=0) *op++=u; + #endif + } break; + #endif + case 9: + OP(0) = (w >> 4) & 0x1ff; + OP(1) = (w >> 13) & 0x1ff; + OP(2) = (w >> 22) & 0x1ff; + OP(3) = (w >> 31) & 0x1ff; OPI( 4); ip+=5; + break; + + case 10: + OP(0) = (w >> 4) & 0x3ff; + OP(1) = (w >> 14) & 0x3ff; + OP(2) = (w >> 24) & 0x3ff; + OP(3) = (w >> 34) & 0x3ff; + OP(4) = (w >> 44) & 0x3ff; + OP(5) = (w >> 54) & 0x3ff; OPI( 6); ip+=8; + break; + case 12: + OP(0) = (w >> 4) & 0xfffu; + OP(1) = (w >> 16) & 0xfffu; + OP(2) = (w >> 28) & 0xfffu; + OP(3) = (w >> 40) & 0xfffu; + OP(4) = (w >> 52) & 0xfffu; OPI( 5); ip+=8; + break; + case 15: + OP(0) = (w >> 4) & 0x7fffu; + OP(1) = (w >> 19) & 0x7fffu; + OP(2) = (w >> 34) & 0x7fffu; + OP(3) = (w >> 49) & 0x7fffu; OPI( 4); ip+=8; + break; + case 11: + OP(0) = (w >> 4) & 0xfffffu; // 20 + OP(1) = (w >> 24) & 0xfffffu; + OP(2) = (w >> 44) & 0xfffffu; OPI( 3); ip+=8; + break; + case 13: + OP(0) = (w >> 4) & 0x3fffffffu; + OP(1) = (w >> 34) & 0x3fffffffu; OPI( 2); ip+=8; + break; + case 14: + #if USIZE <= 32 + OP(0) = (w >> 4) & 0xfffffffffull; OPI( 1); ip+=5; + #else + OP(0) = (w >> 4) & 0xfffffffffull; OPI( 1); ip+=5; + #endif + break; + } + } + return ip; +} +#endif diff --git a/src/ext/for/vsimple.h b/src/ext/for/vsimple.h new file mode 100644 index 00000000000..1291424ca7b --- /dev/null +++ b/src/ext/for/vsimple.h @@ -0,0 +1,47 @@ +/** + Copyright (C) powturbo 2013-2019 + GPL v2 License + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + - homepage : https://sites.google.com/site/powturbo/ + - github : https://github.com/powturbo + - twitter : https://twitter.com/powturbo + - email : powturbo [_AT_] gmail [_DOT_] com +**/ +// "Integer Compression" variable simple "SimpleV" +// this belongs to the integer compression known as "simple family", like simple-9,simple-16 +// or simple-8b. SimpleV is compressing integers in groups into variable word size 32, 40 and 64 bits + RLE (run length encoding) +// SimpleV is faster than simple-16 and compress better than simple-16 or simple-8b. + +#ifdef __cplusplus +extern "C" { +#endif + +// vsencNN: compress array with n unsigned (NN bits in[n]) values to the buffer out. Return value = end of compressed output buffer out +unsigned char *vsenc8( unsigned char *__restrict in, size_t n, unsigned char *__restrict out); +unsigned char *vsenc16(unsigned short *__restrict in, size_t n, unsigned char *__restrict out); +unsigned char *vsenc32(unsigned *__restrict in, size_t n, unsigned char *__restrict out); +unsigned char *vsenc64(uint64_t *__restrict in, size_t n, unsigned char *__restrict out); + +// vsdecNN: decompress buffer into an array of n unsigned values. Return value = end of compressed input buffer in +unsigned char *vsdec8( unsigned char *__restrict in, size_t n, unsigned char *__restrict out); +unsigned char *vsdec16(unsigned char *__restrict in, size_t n, unsigned short *__restrict out); +unsigned char *vsdec32(unsigned char *__restrict in, size_t n, unsigned *__restrict out); +unsigned char *vsdec64(unsigned char *__restrict in, size_t n, uint64_t *__restrict out); + +#ifdef __cplusplus +} +#endif diff --git a/src/ext/zlib/ChangeLog b/src/ext/zlib/ChangeLog new file mode 100755 index 00000000000..7f6869d3235 --- /dev/null +++ b/src/ext/zlib/ChangeLog @@ -0,0 +1,855 @@ + + ChangeLog file for zlib + +Changes in 1.2.3 (18 July 2005) +- Apply security vulnerability fixes to contrib/infback9 as well +- Clean up some text files (carriage returns, trailing space) +- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] + +Changes in 1.2.2.4 (11 July 2005) +- Add inflatePrime() function for starting inflation at bit boundary +- Avoid some Visual C warnings in deflate.c +- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit + compile +- Fix some spelling errors in comments [Betts] +- Correct inflateInit2() error return documentation in zlib.h +- Added zran.c example of compressed data random access to examples + directory, shows use of inflatePrime() +- Fix cast for assignments to strm->state in inflate.c and infback.c +- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] +- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] +- Add cast in trees.c t avoid a warning [Oberhumer] +- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] +- Update make_vms.com [Zinser] +- Initialize state->write in inflateReset() since copied in inflate_fast() +- Be more strict on incomplete code sets in inflate_table() and increase + ENOUGH and MAXD -- this repairs a possible security vulnerability for + invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for + discovering the vulnerability and providing test cases. +- Add ia64 support to configure for HP-UX [Smith] +- Add error return to gzread() for format or i/o error [Levin] +- Use malloc.h for OS/2 [Necasek] + +Changes in 1.2.2.3 (27 May 2005) +- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile +- Typecast fread() return values in gzio.c [Vollant] +- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) +- Fix crc check bug in gzread() after gzungetc() [Heiner] +- Add the deflateTune() function to adjust internal compression parameters +- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) +- Remove an incorrect assertion in examples/zpipe.c +- Add C++ wrapper in infback9.h [Donais] +- Fix bug in inflateCopy() when decoding fixed codes +- Note in zlib.h how much deflateSetDictionary() actually uses +- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) +- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] +- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] +- Add gzdirect() function to indicate transparent reads +- Update contrib/minizip [Vollant] +- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] +- Add casts in crc32.c to avoid warnings [Oberhumer] +- Add contrib/masmx64 [Vollant] +- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] + +Changes in 1.2.2.2 (30 December 2004) +- Replace structure assignments in deflate.c and inflate.c with zmemcpy to + avoid implicit memcpy calls (portability for no-library compilation) +- Increase sprintf() buffer size in gzdopen() to allow for large numbers +- Add INFLATE_STRICT to check distances against zlib header +- Improve WinCE errno handling and comments [Chang] +- Remove comment about no gzip header processing in FAQ +- Add Z_FIXED strategy option to deflateInit2() to force fixed trees +- Add updated make_vms.com [Coghlan], update README +- Create a new "examples" directory, move gzappend.c there, add zpipe.c, + fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. +- Add FAQ entry and comments in deflate.c on uninitialized memory access +- Add Solaris 9 make options in configure [Gilbert] +- Allow strerror() usage in gzio.c for STDC +- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] +- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] +- Use z_off_t for adler32_combine() and crc32_combine() lengths +- Make adler32() much faster for small len +- Use OS_CODE in deflate() default gzip header + +Changes in 1.2.2.1 (31 October 2004) +- Allow inflateSetDictionary() call for raw inflate +- Fix inflate header crc check bug for file names and comments +- Add deflateSetHeader() and gz_header structure for custom gzip headers +- Add inflateGetheader() to retrieve gzip headers +- Add crc32_combine() and adler32_combine() functions +- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list +- Use zstreamp consistently in zlib.h (inflate_back functions) +- Remove GUNZIP condition from definition of inflate_mode in inflate.h + and in contrib/inflate86/inffast.S [Truta, Anderson] +- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] +- Update projects/README.projects and projects/visualc6 [Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] +- Deprecate Z_ASCII; use Z_TEXT instead [Truta] +- Use a new algorithm for setting strm->data_type in trees.c [Truta] +- Do not define an exit() prototype in zutil.c unless DEBUG defined +- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] +- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() +- Fix Darwin build version identification [Peterson] + +Changes in 1.2.2 (3 October 2004) +- Update zlib.h comments on gzip in-memory processing +- Set adler to 1 in inflateReset() to support Java test suite [Walles] +- Add contrib/dotzlib [Ravn] +- Update win32/DLL_FAQ.txt [Truta] +- Update contrib/minizip [Vollant] +- Move contrib/visual-basic.txt to old/ [Truta] +- Fix assembler builds in projects/visualc6/ [Truta] + +Changes in 1.2.1.2 (9 September 2004) +- Update INDEX file +- Fix trees.c to update strm->data_type (no one ever noticed!) +- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] +- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) +- Add limited multitasking protection to DYNAMIC_CRC_TABLE +- Add NO_vsnprintf for VMS in zutil.h [Mozilla] +- Don't declare strerror() under VMS [Mozilla] +- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize +- Update contrib/ada [Anisimkov] +- Update contrib/minizip [Vollant] +- Fix configure to not hardcode directories for Darwin [Peterson] +- Fix gzio.c to not return error on empty files [Brown] +- Fix indentation; update version in contrib/delphi/ZLib.pas and + contrib/pascal/zlibpas.pas [Truta] +- Update mkasm.bat in contrib/masmx86 [Truta] +- Update contrib/untgz [Truta] +- Add projects/README.projects [Truta] +- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] +- Update win32/DLL_FAQ.txt [Truta] +- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] +- Remove an unnecessary assignment to curr in inftrees.c [Truta] +- Add OS/2 to exe builds in configure [Poltorak] +- Remove err dummy parameter in zlib.h [Kientzle] + +Changes in 1.2.1.1 (9 January 2004) +- Update email address in README +- Several FAQ updates +- Fix a big fat bug in inftrees.c that prevented decoding valid + dynamic blocks with only literals and no distance codes -- + Thanks to "Hot Emu" for the bug report and sample file +- Add a note to puff.c on no distance codes case. + +Changes in 1.2.1 (17 November 2003) +- Remove a tab in contrib/gzappend/gzappend.c +- Update some interfaces in contrib for new zlib functions +- Update zlib version number in some contrib entries +- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] +- Support shared libraries on Hurd and KFreeBSD [Brown] +- Fix error in NO_DIVIDE option of adler32.c + +Changes in 1.2.0.8 (4 November 2003) +- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas +- Add experimental NO_DIVIDE #define in adler32.c + - Possibly faster on some processors (let me know if it is) +- Correct Z_BLOCK to not return on first inflate call if no wrap +- Fix strm->data_type on inflate() return to correctly indicate EOB +- Add deflatePrime() function for appending in the middle of a byte +- Add contrib/gzappend for an example of appending to a stream +- Update win32/DLL_FAQ.txt [Truta] +- Delete Turbo C comment in README [Truta] +- Improve some indentation in zconf.h [Truta] +- Fix infinite loop on bad input in configure script [Church] +- Fix gzeof() for concatenated gzip files [Johnson] +- Add example to contrib/visual-basic.txt [Michael B.] +- Add -p to mkdir's in Makefile.in [vda] +- Fix configure to properly detect presence or lack of printf functions +- Add AS400 support [Monnerat] +- Add a little Cygwin support [Wilson] + +Changes in 1.2.0.7 (21 September 2003) +- Correct some debug formats in contrib/infback9 +- Cast a type in a debug statement in trees.c +- Change search and replace delimiter in configure from % to # [Beebe] +- Update contrib/untgz to 0.2 with various fixes [Truta] +- Add build support for Amiga [Nikl] +- Remove some directories in old that have been updated to 1.2 +- Add dylib building for Mac OS X in configure and Makefile.in +- Remove old distribution stuff from Makefile +- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X +- Update links in README + +Changes in 1.2.0.6 (13 September 2003) +- Minor FAQ updates +- Update contrib/minizip to 1.00 [Vollant] +- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] +- Update POSTINC comment for 68060 [Nikl] +- Add contrib/infback9 with deflate64 decoding (unsupported) +- For MVS define NO_vsnprintf and undefine FAR [van Burik] +- Add pragma for fdopen on MVS [van Burik] + +Changes in 1.2.0.5 (8 September 2003) +- Add OF to inflateBackEnd() declaration in zlib.h +- Remember start when using gzdopen in the middle of a file +- Use internal off_t counters in gz* functions to properly handle seeks +- Perform more rigorous check for distance-too-far in inffast.c +- Add Z_BLOCK flush option to return from inflate at block boundary +- Set strm->data_type on return from inflate + - Indicate bits unused, if at block boundary, and if in last block +- Replace size_t with ptrdiff_t in crc32.c, and check for correct size +- Add condition so old NO_DEFLATE define still works for compatibility +- FAQ update regarding the Windows DLL [Truta] +- INDEX update: add qnx entry, remove aix entry [Truta] +- Install zlib.3 into mandir [Wilson] +- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] +- Adapt the zlib interface to the new DLL convention guidelines [Truta] +- Introduce ZLIB_WINAPI macro to allow the export of functions using + the WINAPI calling convention, for Visual Basic [Vollant, Truta] +- Update msdos and win32 scripts and makefiles [Truta] +- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] +- Add contrib/ada [Anisimkov] +- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] +- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] +- Add contrib/masm686 [Truta] +- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm + [Truta, Vollant] +- Update contrib/delphi; rename to contrib/pascal; add example [Truta] +- Remove contrib/delphi2; add a new contrib/delphi [Truta] +- Avoid inclusion of the nonstandard in contrib/iostream, + and fix some method prototypes [Truta] +- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip + [Truta] +- Avoid the use of backslash (\) in contrib/minizip [Vollant] +- Fix file time handling in contrib/untgz; update makefiles [Truta] +- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines + [Vollant] +- Remove contrib/vstudio/vc15_16 [Vollant] +- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] +- Update README.contrib [Truta] +- Invert the assignment order of match_head and s->prev[...] in + INSERT_STRING [Truta] +- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings + [Truta] +- Compare function pointers with 0, not with NULL or Z_NULL [Truta] +- Fix prototype of syncsearch in inflate.c [Truta] +- Introduce ASMINF macro to be enabled when using an ASM implementation + of inflate_fast [Truta] +- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] +- Modify test_gzio in example.c to take a single file name as a + parameter [Truta] +- Exit the example.c program if gzopen fails [Truta] +- Add type casts around strlen in example.c [Truta] +- Remove casting to sizeof in minigzip.c; give a proper type + to the variable compared with SUFFIX_LEN [Truta] +- Update definitions of STDC and STDC99 in zconf.h [Truta] +- Synchronize zconf.h with the new Windows DLL interface [Truta] +- Use SYS16BIT instead of __32BIT__ to distinguish between + 16- and 32-bit platforms [Truta] +- Use far memory allocators in small 16-bit memory models for + Turbo C [Truta] +- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in + zlibCompileFlags [Truta] +- Cygwin has vsnprintf [Wilson] +- In Windows16, OS_CODE is 0, as in MSDOS [Truta] +- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] + +Changes in 1.2.0.4 (10 August 2003) +- Minor FAQ updates +- Be more strict when checking inflateInit2's windowBits parameter +- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well +- Add gzip wrapper option to deflateInit2 using windowBits +- Add updated QNX rule in configure and qnx directory [Bonnefoy] +- Make inflate distance-too-far checks more rigorous +- Clean up FAR usage in inflate +- Add casting to sizeof() in gzio.c and minigzip.c + +Changes in 1.2.0.3 (19 July 2003) +- Fix silly error in gzungetc() implementation [Vollant] +- Update contrib/minizip and contrib/vstudio [Vollant] +- Fix printf format in example.c +- Correct cdecl support in zconf.in.h [Anisimkov] +- Minor FAQ updates + +Changes in 1.2.0.2 (13 July 2003) +- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons +- Attempt to avoid warnings in crc32.c for pointer-int conversion +- Add AIX to configure, remove aix directory [Bakker] +- Add some casts to minigzip.c +- Improve checking after insecure sprintf() or vsprintf() calls +- Remove #elif's from crc32.c +- Change leave label to inf_leave in inflate.c and infback.c to avoid + library conflicts +- Remove inflate gzip decoding by default--only enable gzip decoding by + special request for stricter backward compatibility +- Add zlibCompileFlags() function to return compilation information +- More typecasting in deflate.c to avoid warnings +- Remove leading underscore from _Capital #defines [Truta] +- Fix configure to link shared library when testing +- Add some Windows CE target adjustments [Mai] +- Remove #define ZLIB_DLL in zconf.h [Vollant] +- Add zlib.3 [Rodgers] +- Update RFC URL in deflate.c and algorithm.txt [Mai] +- Add zlib_dll_FAQ.txt to contrib [Truta] +- Add UL to some constants [Truta] +- Update minizip and vstudio [Vollant] +- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h +- Expand use of NO_DUMMY_DECL to avoid all dummy structures +- Added iostream3 to contrib [Schwardt] +- Replace rewind() with fseek() for WinCE [Truta] +- Improve setting of zlib format compression level flags + - Report 0 for huffman and rle strategies and for level == 0 or 1 + - Report 2 only for level == 6 +- Only deal with 64K limit when necessary at compile time [Truta] +- Allow TOO_FAR check to be turned off at compile time [Truta] +- Add gzclearerr() function [Souza] +- Add gzungetc() function + +Changes in 1.2.0.1 (17 March 2003) +- Add Z_RLE strategy for run-length encoding [Truta] + - When Z_RLE requested, restrict matches to distance one + - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE +- Correct FASTEST compilation to allow level == 0 +- Clean up what gets compiled for FASTEST +- Incorporate changes to zconf.in.h [Vollant] + - Refine detection of Turbo C need for dummy returns + - Refine ZLIB_DLL compilation + - Include additional header file on VMS for off_t typedef +- Try to use _vsnprintf where it supplants vsprintf [Vollant] +- Add some casts in inffast.c +- Enchance comments in zlib.h on what happens if gzprintf() tries to + write more than 4095 bytes before compression +- Remove unused state from inflateBackEnd() +- Remove exit(0) from minigzip.c, example.c +- Get rid of all those darn tabs +- Add "check" target to Makefile.in that does the same thing as "test" +- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in +- Update contrib/inflate86 [Anderson] +- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] +- Add msdos and win32 directories with makefiles [Truta] +- More additions and improvements to the FAQ + +Changes in 1.2.0 (9 March 2003) +- New and improved inflate code + - About 20% faster + - Does not allocate 32K window unless and until needed + - Automatically detects and decompresses gzip streams + - Raw inflate no longer needs an extra dummy byte at end + - Added inflateBack functions using a callback interface--even faster + than inflate, useful for file utilities (gzip, zip) + - Added inflateCopy() function to record state for random access on + externally generated deflate streams (e.g. in gzip files) + - More readable code (I hope) +- New and improved crc32() + - About 50% faster, thanks to suggestions from Rodney Brown +- Add deflateBound() and compressBound() functions +- Fix memory leak in deflateInit2() +- Permit setting dictionary for raw deflate (for parallel deflate) +- Fix const declaration for gzwrite() +- Check for some malloc() failures in gzio.c +- Fix bug in gzopen() on single-byte file 0x1f +- Fix bug in gzread() on concatenated file with 0x1f at end of buffer + and next buffer doesn't start with 0x8b +- Fix uncompress() to return Z_DATA_ERROR on truncated input +- Free memory at end of example.c +- Remove MAX #define in trees.c (conflicted with some libraries) +- Fix static const's in deflate.c, gzio.c, and zutil.[ch] +- Declare malloc() and free() in gzio.c if STDC not defined +- Use malloc() instead of calloc() in zutil.c if int big enough +- Define STDC for AIX +- Add aix/ with approach for compiling shared library on AIX +- Add HP-UX support for shared libraries in configure +- Add OpenUNIX support for shared libraries in configure +- Use $cc instead of gcc to build shared library +- Make prefix directory if needed when installing +- Correct Macintosh avoidance of typedef Byte in zconf.h +- Correct Turbo C memory allocation when under Linux +- Use libz.a instead of -lz in Makefile (assure use of compiled library) +- Update configure to check for snprintf or vsnprintf functions and their + return value, warn during make if using an insecure function +- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that + is lost when library is used--resolution is to build new zconf.h +- Documentation improvements (in zlib.h): + - Document raw deflate and inflate + - Update RFCs URL + - Point out that zlib and gzip formats are different + - Note that Z_BUF_ERROR is not fatal + - Document string limit for gzprintf() and possible buffer overflow + - Note requirement on avail_out when flushing + - Note permitted values of flush parameter of inflate() +- Add some FAQs (and even answers) to the FAQ +- Add contrib/inflate86/ for x86 faster inflate +- Add contrib/blast/ for PKWare Data Compression Library decompression +- Add contrib/puff/ simple inflate for deflate format description + +Changes in 1.1.4 (11 March 2002) +- ZFREE was repeated on same allocation on some error conditions. + This creates a security problem described in + http://www.zlib.org/advisory-2002-03-11.txt +- Returned incorrect error (Z_MEM_ERROR) on some invalid data +- Avoid accesses before window for invalid distances with inflate window + less than 32K. +- force windowBits > 8 to avoid a bug in the encoder for a window size + of 256 bytes. (A complete fix will be available in 1.1.5). + +Changes in 1.1.3 (9 July 1998) +- fix "an inflate input buffer bug that shows up on rare but persistent + occasions" (Mark) +- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) +- fix gzseek(..., SEEK_SET) in write mode +- fix crc check after a gzeek (Frank Faubert) +- fix miniunzip when the last entry in a zip file is itself a zip file + (J Lillge) +- add contrib/asm586 and contrib/asm686 (Brian Raiter) + See http://www.muppetlabs.com/~breadbox/software/assembly.html +- add support for Delphi 3 in contrib/delphi (Bob Dellaca) +- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) +- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) +- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) +- added a FAQ file + +- Support gzdopen on Mac with Metrowerks (Jason Linhart) +- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) +- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) +- avoid some warnings with Borland C (Tom Tanner) +- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) +- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) +- allow several arguments to configure (Tim Mooney, Frodo Looijaard) +- use libdir and includedir in Makefile.in (Tim Mooney) +- support shared libraries on OSF1 V4 (Tim Mooney) +- remove so_locations in "make clean" (Tim Mooney) +- fix maketree.c compilation error (Glenn, Mark) +- Python interface to zlib now in Python 1.5 (Jeremy Hylton) +- new Makefile.riscos (Rich Walker) +- initialize static descriptors in trees.c for embedded targets (Nick Smith) +- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) +- add the OS/2 files in Makefile.in too (Andrew Zabolotny) +- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) +- fix maketree.c to allow clean compilation of inffixed.h (Mark) +- fix parameter check in deflateCopy (Gunther Nikl) +- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) +- Many portability patches by Christian Spieler: + . zutil.c, zutil.h: added "const" for zmem* + . Make_vms.com: fixed some typos + . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists + . msdos/Makefile.msc: remove "default rtl link library" info from obj files + . msdos/Makefile.*: use model-dependent name for the built zlib library + . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: + new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) +- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) +- replace __far with _far for better portability (Christian Spieler, Tom Lane) +- fix test for errno.h in configure (Tim Newsham) + +Changes in 1.1.2 (19 March 98) +- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) + See http://www.winimage.com/zLibDll/unzip.html +- preinitialize the inflate tables for fixed codes, to make the code + completely thread safe (Mark) +- some simplifications and slight speed-up to the inflate code (Mark) +- fix gzeof on non-compressed files (Allan Schrum) +- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) +- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) +- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) +- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) +- do not wrap extern "C" around system includes (Tom Lane) +- mention zlib binding for TCL in README (Andreas Kupries) +- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) +- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) +- allow "configure --prefix $HOME" (Tim Mooney) +- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) +- move Makefile.sas to amiga/Makefile.sas + +Changes in 1.1.1 (27 Feb 98) +- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) +- remove block truncation heuristic which had very marginal effect for zlib + (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the + compression ratio on some files. This also allows inlining _tr_tally for + matches in deflate_slow. +- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) + +Changes in 1.1.0 (24 Feb 98) +- do not return STREAM_END prematurely in inflate (John Bowler) +- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) +- compile with -DFASTEST to get compression code optimized for speed only +- in minigzip, try mmap'ing the input file first (Miguel Albrecht) +- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain + on Sun but significant on HP) + +- add a pointer to experimental unzip library in README (Gilles Vollant) +- initialize variable gcc in configure (Chris Herborth) + +Changes in 1.0.9 (17 Feb 1998) +- added gzputs and gzgets functions +- do not clear eof flag in gzseek (Mark Diekhans) +- fix gzseek for files in transparent mode (Mark Diekhans) +- do not assume that vsprintf returns the number of bytes written (Jens Krinke) +- replace EXPORT with ZEXPORT to avoid conflict with other programs +- added compress2 in zconf.h, zlib.def, zlib.dnt +- new asm code from Gilles Vollant in contrib/asm386 +- simplify the inflate code (Mark): + . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() + . ZALLOC the length list in inflate_trees_fixed() instead of using stack + . ZALLOC the value area for huft_build() instead of using stack + . Simplify Z_FINISH check in inflate() + +- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 +- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) +- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with + the declaration of FAR (Gilles VOllant) +- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) +- read_buf buf parameter of type Bytef* instead of charf* +- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) +- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) +- fix check for presence of directories in "make install" (Ian Willis) + +Changes in 1.0.8 (27 Jan 1998) +- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) +- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) +- added compress2() to allow setting the compression level +- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) +- use constant arrays for the static trees in trees.c instead of computing + them at run time (thanks to Ken Raeburn for this suggestion). To create + trees.h, compile with GEN_TREES_H and run "make test". +- check return code of example in "make test" and display result +- pass minigzip command line options to file_compress +- simplifying code of inflateSync to avoid gcc 2.8 bug + +- support CC="gcc -Wall" in configure -s (QingLong) +- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) +- fix test for shared library support to avoid compiler warnings +- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) +- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) +- do not use fdopen for Metrowerks on Mac (Brad Pettit)) +- add checks for gzputc and gzputc in example.c +- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) +- use const for the CRC table (Ken Raeburn) +- fixed "make uninstall" for shared libraries +- use Tracev instead of Trace in infblock.c +- in example.c use correct compressed length for test_sync +- suppress +vnocompatwarnings in configure for HPUX (not always supported) + +Changes in 1.0.7 (20 Jan 1998) +- fix gzseek which was broken in write mode +- return error for gzseek to negative absolute position +- fix configure for Linux (Chun-Chung Chen) +- increase stack space for MSC (Tim Wegner) +- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) +- define EXPORTVA for gzprintf (Gilles Vollant) +- added man page zlib.3 (Rick Rodgers) +- for contrib/untgz, fix makedir() and improve Makefile + +- check gzseek in write mode in example.c +- allocate extra buffer for seeks only if gzseek is actually called +- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) +- add inflateSyncPoint in zconf.h +- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def + +Changes in 1.0.6 (19 Jan 1998) +- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and + gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) +- Fix a deflate bug occurring only with compression level 0 (thanks to + Andy Buckler for finding this one). +- In minigzip, pass transparently also the first byte for .Z files. +- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() +- check Z_FINISH in inflate (thanks to Marc Schluper) +- Implement deflateCopy (thanks to Adam Costello) +- make static libraries by default in configure, add --shared option. +- move MSDOS or Windows specific files to directory msdos +- suppress the notion of partial flush to simplify the interface + (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) +- suppress history buffer provided by application to simplify the interface + (this feature was not implemented anyway in 1.0.4) +- next_in and avail_in must be initialized before calling inflateInit or + inflateInit2 +- add EXPORT in all exported functions (for Windows DLL) +- added Makefile.nt (thanks to Stephen Williams) +- added the unsupported "contrib" directory: + contrib/asm386/ by Gilles Vollant + 386 asm code replacing longest_match(). + contrib/iostream/ by Kevin Ruland + A C++ I/O streams interface to the zlib gz* functions + contrib/iostream2/ by Tyge Lvset + Another C++ I/O streams interface + contrib/untgz/ by "Pedro A. Aranda Guti\irrez" + A very simple tar.gz file extractor using zlib + contrib/visual-basic.txt by Carlos Rios + How to use compress(), uncompress() and the gz* functions from VB. +- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression + level) in minigzip (thanks to Tom Lane) + +- use const for rommable constants in deflate +- added test for gzseek and gztell in example.c +- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) +- add undocumented function zError to convert error code to string + (for Tim Smithers) +- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. +- Use default memcpy for Symantec MSDOS compiler. +- Add EXPORT keyword for check_func (needed for Windows DLL) +- add current directory to LD_LIBRARY_PATH for "make test" +- create also a link for libz.so.1 +- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) +- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) +- added -soname for Linux in configure (Chun-Chung Chen, +- assign numbers to the exported functions in zlib.def (for Windows DLL) +- add advice in zlib.h for best usage of deflateSetDictionary +- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) +- allow compilation with ANSI keywords only enabled for TurboC in large model +- avoid "versionString"[0] (Borland bug) +- add NEED_DUMMY_RETURN for Borland +- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). +- allow compilation with CC +- defined STDC for OS/2 (David Charlap) +- limit external names to 8 chars for MVS (Thomas Lund) +- in minigzip.c, use static buffers only for 16-bit systems +- fix suffix check for "minigzip -d foo.gz" +- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) +- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) +- added makelcc.bat for lcc-win32 (Tom St Denis) +- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) +- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. +- check for unistd.h in configure (for off_t) +- remove useless check parameter in inflate_blocks_free +- avoid useless assignment of s->check to itself in inflate_blocks_new +- do not flush twice in gzclose (thanks to Ken Raeburn) +- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h +- use NO_ERRNO_H instead of enumeration of operating systems with errno.h +- work around buggy fclose on pipes for HP/UX +- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) +- fix configure if CC is already equal to gcc + +Changes in 1.0.5 (3 Jan 98) +- Fix inflate to terminate gracefully when fed corrupted or invalid data +- Use const for rommable constants in inflate +- Eliminate memory leaks on error conditions in inflate +- Removed some vestigial code in inflate +- Update web address in README + +Changes in 1.0.4 (24 Jul 96) +- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF + bit, so the decompressor could decompress all the correct data but went + on to attempt decompressing extra garbage data. This affected minigzip too. +- zlibVersion and gzerror return const char* (needed for DLL) +- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) +- use z_error only for DEBUG (avoid problem with DLLs) + +Changes in 1.0.3 (2 Jul 96) +- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS + small and medium models; this makes the library incompatible with previous + versions for these models. (No effect in large model or on other systems.) +- return OK instead of BUF_ERROR if previous deflate call returned with + avail_out as zero but there is nothing to do +- added memcmp for non STDC compilers +- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) +- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) +- better check for 16-bit mode MSC (avoids problem with Symantec) + +Changes in 1.0.2 (23 May 96) +- added Windows DLL support +- added a function zlibVersion (for the DLL support) +- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) +- Bytef is define's instead of typedef'd only for Borland C +- avoid reading uninitialized memory in example.c +- mention in README that the zlib format is now RFC1950 +- updated Makefile.dj2 +- added algorithm.doc + +Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] +- fix array overlay in deflate.c which sometimes caused bad compressed data +- fix inflate bug with empty stored block +- fix MSDOS medium model which was broken in 0.99 +- fix deflateParams() which could generated bad compressed data. +- Bytef is define'd instead of typedef'ed (work around Borland bug) +- added an INDEX file +- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), + Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) +- speed up adler32 for modern machines without auto-increment +- added -ansi for IRIX in configure +- static_init_done in trees.c is an int +- define unlink as delete for VMS +- fix configure for QNX +- add configure branch for SCO and HPUX +- avoid many warnings (unused variables, dead assignments, etc...) +- no fdopen for BeOS +- fix the Watcom fix for 32 bit mode (define FAR as empty) +- removed redefinition of Byte for MKWERKS +- work around an MWKERKS bug (incorrect merge of all .h files) + +Changes in 0.99 (27 Jan 96) +- allow preset dictionary shared between compressor and decompressor +- allow compression level 0 (no compression) +- add deflateParams in zlib.h: allow dynamic change of compression level + and compression strategy. +- test large buffers and deflateParams in example.c +- add optional "configure" to build zlib as a shared library +- suppress Makefile.qnx, use configure instead +- fixed deflate for 64-bit systems (detected on Cray) +- fixed inflate_blocks for 64-bit systems (detected on Alpha) +- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) +- always return Z_BUF_ERROR when deflate() has nothing to do +- deflateInit and inflateInit are now macros to allow version checking +- prefix all global functions and types with z_ with -DZ_PREFIX +- make falloc completely reentrant (inftrees.c) +- fixed very unlikely race condition in ct_static_init +- free in reverse order of allocation to help memory manager +- use zlib-1.0/* instead of zlib/* inside the tar.gz +- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith + -Wconversion -Wstrict-prototypes -Wmissing-prototypes" +- allow gzread on concatenated .gz files +- deflateEnd now returns Z_DATA_ERROR if it was premature +- deflate is finally (?) fully deterministic (no matches beyond end of input) +- Document Z_SYNC_FLUSH +- add uninstall in Makefile +- Check for __cpluplus in zlib.h +- Better test in ct_align for partial flush +- avoid harmless warnings for Borland C++ +- initialize hash_head in deflate.c +- avoid warning on fdopen (gzio.c) for HP cc -Aa +- include stdlib.h for STDC compilers +- include errno.h for Cray +- ignore error if ranlib doesn't exist +- call ranlib twice for NeXTSTEP +- use exec_prefix instead of prefix for libz.a +- renamed ct_* as _tr_* to avoid conflict with applications +- clear z->msg in inflateInit2 before any error return +- initialize opaque in example.c, gzio.c, deflate.c and inflate.c +- fixed typo in zconf.h (_GNUC__ => __GNUC__) +- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) +- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) +- in fcalloc, normalize pointer if size > 65520 bytes +- don't use special fcalloc for 32 bit Borland C++ +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use Z_BINARY instead of BINARY +- document that gzclose after gzdopen will close the file +- allow "a" as mode in gzopen. +- fix error checking in gzread +- allow skipping .gz extra-field on pipes +- added reference to Perl interface in README +- put the crc table in FAR data (I dislike more and more the medium model :) +- added get_crc_table +- added a dimension to all arrays (Borland C can't count). +- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast +- guard against multiple inclusion of *.h (for precompiled header on Mac) +- Watcom C pretends to be Microsoft C small model even in 32 bit mode. +- don't use unsized arrays to avoid silly warnings by Visual C++: + warning C4746: 'inflate_mask' : unsized array treated as '__far' + (what's wrong with far data in far model?). +- define enum out of inflate_blocks_state to allow compilation with C++ + +Changes in 0.95 (16 Aug 95) +- fix MSDOS small and medium model (now easier to adapt to any compiler) +- inlined send_bits +- fix the final (:-) bug for deflate with flush (output was correct but + not completely flushed in rare occasions). +- default window size is same for compression and decompression + (it's now sufficient to set MAX_WBITS in zconf.h). +- voidp -> voidpf and voidnp -> voidp (for consistency with other + typedefs and because voidnp was not near in large model). + +Changes in 0.94 (13 Aug 95) +- support MSDOS medium model +- fix deflate with flush (could sometimes generate bad output) +- fix deflateReset (zlib header was incorrectly suppressed) +- added support for VMS +- allow a compression level in gzopen() +- gzflush now calls fflush +- For deflate with flush, flush even if no more input is provided. +- rename libgz.a as libz.a +- avoid complex expression in infcodes.c triggering Turbo C bug +- work around a problem with gcc on Alpha (in INSERT_STRING) +- don't use inline functions (problem with some gcc versions) +- allow renaming of Byte, uInt, etc... with #define. +- avoid warning about (unused) pointer before start of array in deflate.c +- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c +- avoid reserved word 'new' in trees.c + +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror() diff --git a/src/ext/zlib/FAQ b/src/ext/zlib/FAQ new file mode 100755 index 00000000000..441d910daa1 --- /dev/null +++ b/src/ext/zlib/FAQ @@ -0,0 +1,339 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. + See the file win32/DLL_FAQ.txt in the zlib distribution. + Pointers to the precompiled DLL are found in the zlib web site at + http://www.zlib.org. + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact us (zlib@gzip.org). Examples of zlib usage are in the files + example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to it. + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . + To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip + formats use the same compressed data format internally, but have different + headers and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about + a single file, such as the name and last modification date. The zlib + format on the other hand was designed for in-memory and communication + channel applications, and has a much more compact header and trailer and + uses a faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode + the gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's Init functions allow + for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + It should. It has been tested on 64-bit machines, and has no dependence + on any data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format + than does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically + use Z_FULL_FLUSH, carefully write all the pending data at those points, + and keep an index of those locations, then you can start decompression + at those points. You have to be careful to not use Z_FULL_FLUSH too + often, since it can significantly degrade compression. + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + We don't know for sure. We have heard occasional reports of success on + these systems. If you do use it on one of these, please provide us with + a report, instructions, and patches that we can reference when we get + these questions. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at + to understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit + only if the compiler's "long" type is 32 bits. If the compiler's "long" + type is 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib + is compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of a 4K string space, other than the caller of + gzprintf() assuring that the output will not exceed 4K. On the other + hand, if zlib is compiled to use snprintf() or vsnprintf(), which should + normally be the case, then there is no vulnerability. The ./configure + script will display warnings if an insecure variation of sprintf() will + be used by gzprintf(). Also the zlibCompileFlags() function will return + information on what variant of sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://www.zlib.org/ + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly. So now, we simply make sure that the code always + works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of + deflate is not affected. This only started showing up recently since + zlib 1.2.x uses malloc() by default for allocations, whereas earlier + versions used calloc(), which zeros out the allocated memory. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very weak + and can be broken with freely available programs. To get strong encryption, + use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. + For PKZIP compatible "encryption", look at http://www.info-zip.org/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion + with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specficiation in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. + In any case, the compression improvements are so modest compared to other + more modern approaches, that it's not worth the effort to implement. + +41. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/src/ext/zlib/INDEX b/src/ext/zlib/INDEX new file mode 100755 index 00000000000..0587e5902bd --- /dev/null +++ b/src/ext/zlib/INDEX @@ -0,0 +1,51 @@ +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +zconf.in.h template for zconf.h (used by configure) + +amiga/ makefiles for Amiga SAS C +as400/ makefiles for IBM AS/400 +msdos/ makefiles for MSDOS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +projects/ projects for various Integrated Development Environments +qnx/ makefiles for QNX +win32/ makefiles for Windows + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzio.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties +See contrib/README.contrib diff --git a/src/ext/zlib/README b/src/ext/zlib/README new file mode 100755 index 00000000000..758cc50020d --- /dev/null +++ b/src/ext/zlib/README @@ -0,0 +1,125 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.3 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install". For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.3 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2004 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/src/ext/zlib/adler32.c b/src/ext/zlib/adler32.c new file mode 100755 index 00000000000..007ba26277c --- /dev/null +++ b/src/ext/zlib/adler32.c @@ -0,0 +1,149 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* use NO_DIVIDE if your processor does not do division in hardware */ +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +# define MOD4(a) \ + do { \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +# define MOD4(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) { + while (len--) { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD4(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) { /* avoid modulos if none remaining */ + while (len >= 16) { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } + + /* return recombined sums */ + return adler | (sum2 << 16); +} + +/* ========================================================================= */ +uLong ZEXPORT adler32_combine(adler1, adler2, len2) + uLong adler1; + uLong adler2; + z_off_t len2; +{ + unsigned long sum1; + unsigned long sum2; + unsigned rem; + + /* the derivation of this formula is left as an exercise for the reader */ + rem = (unsigned)(len2 % BASE); + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 > BASE) sum1 -= BASE; + if (sum1 > BASE) sum1 -= BASE; + if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 > BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} diff --git a/src/ext/zlib/algorithm.txt b/src/ext/zlib/algorithm.txt new file mode 100755 index 00000000000..b022dde312a --- /dev/null +++ b/src/ext/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/src/ext/zlib/compress.c b/src/ext/zlib/compress.c new file mode 100755 index 00000000000..df04f0148e6 --- /dev/null +++ b/src/ext/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/src/ext/zlib/crc32.c b/src/ext/zlib/crc32.c new file mode 100755 index 00000000000..f658a9ef55e --- /dev/null +++ b/src/ext/zlib/crc32.c @@ -0,0 +1,423 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results in about a + * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id$ */ + +/* + Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore + protection on the static variables used to control the first-use generation + of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should + first call get_crc_table() to initialize the tables before allowing more than + one thread to use crc32(). + */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +/* Local functions for crc concatenation */ +local unsigned long gf2_matrix_times OF((unsigned long *mat, + unsigned long vec)); +local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); + +#ifdef DYNAMIC_CRC_TABLE + +local volatile int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* See if another task is already doing this (not thread-safe, but better + than nothing -- significantly reduces duration of vulnerability in + case the advice about DYNAMIC_CRC_TABLE is ignored) */ + if (first) { + first = 0; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, + and then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + } + else { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ + +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ + +/* ========================================================================= */ +local unsigned long gf2_matrix_times(mat, vec) + unsigned long *mat; + unsigned long vec; +{ + unsigned long sum; + + sum = 0; + while (vec) { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; +} + +/* ========================================================================= */ +local void gf2_matrix_square(square, mat) + unsigned long *square; + unsigned long *mat; +{ + int n; + + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); +} + +/* ========================================================================= */ +uLong ZEXPORT crc32_combine(crc1, crc2, len2) + uLong crc1; + uLong crc2; + z_off_t len2; +{ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + + /* degenerate case */ + if (len2 == 0) + return crc1; + + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320L; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); + + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); + + /* apply len2 zeros to crc1 (first square will put the operator for one + zero byte, eight zero bits, in even) */ + do { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + if (len2 == 0) + break; + + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + /* if no more bits set, then done */ + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; +} diff --git a/src/ext/zlib/crc32.h b/src/ext/zlib/crc32.h new file mode 100755 index 00000000000..8053b6117c0 --- /dev/null +++ b/src/ext/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/src/ext/zlib/deflate.c b/src/ext/zlib/deflate.c new file mode 100755 index 00000000000..29ce1f64a57 --- /dev/null +++ b/src/ext/zlib/deflate.c @@ -0,0 +1,1736 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader (strm, head) + z_streamp strm; + gz_headerp head; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) + z_streamp strm; + int good_length; + int max_lazy; + int nice_length; + int max_chain; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/src/ext/zlib/deflate.h b/src/ext/zlib/deflate.h new file mode 100755 index 00000000000..05a5ab3a2c1 --- /dev/null +++ b/src/ext/zlib/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/src/ext/zlib/gzio.c b/src/ext/zlib/gzio.c new file mode 100755 index 00000000000..7e90f4928fc --- /dev/null +++ b/src/ext/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id$ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/src/ext/zlib/inffast.c b/src/ext/zlib/inffast.c new file mode 100755 index 00000000000..bbee92ed1e6 --- /dev/null +++ b/src/ext/zlib/inffast.c @@ -0,0 +1,318 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - M68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); +#ifdef INFLATE_STRICT + if (dist > dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/src/ext/zlib/inffast.h b/src/ext/zlib/inffast.h new file mode 100755 index 00000000000..1e88d2d97b5 --- /dev/null +++ b/src/ext/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/src/ext/zlib/inffixed.h b/src/ext/zlib/inffixed.h new file mode 100755 index 00000000000..75ed4b5978d --- /dev/null +++ b/src/ext/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/src/ext/zlib/inflate.c b/src/ext/zlib/inflate.c new file mode 100755 index 00000000000..792fdee8e9c --- /dev/null +++ b/src/ext/zlib/inflate.c @@ -0,0 +1,1368 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + strm->adler = 1; /* to support ill-conceived Java test suite */ + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->write = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflatePrime(strm, bits, value) +z_streamp strm; +int bits; +int value; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (len > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) break; + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } +#endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + if (state->mode == DICT) { + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) + return Z_DATA_ERROR; + } + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int ZEXPORT inflateGetHeader(strm, head) +z_streamp strm; +gz_headerp head; +{ + struct inflate_state FAR *state; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; +} diff --git a/src/ext/zlib/inflate.h b/src/ext/zlib/inflate.h new file mode 100755 index 00000000000..07bd3e78a7c --- /dev/null +++ b/src/ext/zlib/inflate.h @@ -0,0 +1,115 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2004 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/src/ext/zlib/inftrees.c b/src/ext/zlib/inftrees.c new file mode 100755 index 00000000000..8a9c13ff03d --- /dev/null +++ b/src/ext/zlib/inftrees.c @@ -0,0 +1,329 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) { /* no symbols to code at all */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)1; + this.val = (unsigned short)0; + *(*table)++ = this; /* make a table to force an error */ + *(*table)++ = this; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/src/ext/zlib/inftrees.h b/src/ext/zlib/inftrees.h new file mode 100755 index 00000000000..b1104c87e76 --- /dev/null +++ b/src/ext/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1444 code structures (852 for length/literals + and 592 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 2048 +#define MAXD 592 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/src/ext/zlib/trees.c b/src/ext/zlib/trees.c new file mode 100755 index 00000000000..395e4e16814 --- /dev/null +++ b/src/ext/zlib/trees.c @@ -0,0 +1,1219 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2005 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id$ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned) tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is binary or text */ + if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) + set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to BINARY or TEXT, using a crude approximation: + * set it to Z_TEXT if all symbols are either printable characters (33 to 255) + * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local void set_data_type(s) + deflate_state *s; +{ + int n; + + for (n = 0; n < 9; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + if (n == 9) + for (n = 14; n < 32; n++) + if (s->dyn_ltree[n].Freq != 0) + break; + s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/src/ext/zlib/trees.h b/src/ext/zlib/trees.h new file mode 100755 index 00000000000..72facf900f7 --- /dev/null +++ b/src/ext/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/src/ext/zlib/zconf.h b/src/ext/zlib/zconf.h new file mode 100755 index 00000000000..03a9431c8be --- /dev/null +++ b/src/ext/zlib/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/src/ext/zlib/zlib.h b/src/ext/zlib/zlib.h new file mode 100755 index 00000000000..022817927ce --- /dev/null +++ b/src/ext/zlib/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/src/ext/zlib/zutil.c b/src/ext/zlib/zutil.c new file mode 100755 index 00000000000..d55f5948a37 --- /dev/null +++ b/src/ext/zlib/zutil.c @@ -0,0 +1,318 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif +#ifdef FASTEST + flags += 1L << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1L << 25; +# ifdef HAS_vsprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1L << 26; +# endif +# endif +#else + flags += 1L << 24; +# ifdef NO_snprintf + flags += 1L << 25; +# ifdef HAS_sprintf_void + flags += 1L << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1L << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. + */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/src/ext/zlib/zutil.h b/src/ext/zlib/zutil.h new file mode 100755 index 00000000000..b7d5eff81b6 --- /dev/null +++ b/src/ext/zlib/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/src/gtest/CMakeLists.txt b/src/gtest/CMakeLists.txt new file mode 100644 index 00000000000..1eaacf8406c --- /dev/null +++ b/src/gtest/CMakeLists.txt @@ -0,0 +1,26 @@ +include (${ClickHouse_SOURCE_DIR}/cmake/add_check.cmake) + +file(GLOB_RECURSE TESTER_SOURCES + "parser/*.cpp" +) + +#set(PLATFORM_LIBS ${CMAKE_DL_LIBS}) + +GET_SHARED_FILES(clucene_shared_Files) + +#message (STATUS "Parser Using ${ZLIB_LIBRARIES}: ${ZLIB_INCLUDE_DIR}") +#message (STATUS "Parser Using shared files: ${clucene_shared_Files}") + +add_executable(unittest_parser EXCLUDE_FROM_ALL ${clucene_shared_Files} ${TESTER_SOURCES}) +target_link_libraries(unittest_parser PRIVATE ${ZLIB_LIBRARIES} clucene-core-static clucene-shared-static ${GTEST_LIBRARIES} ) +target_include_directories(unittest_parser + PUBLIC + ${ZLIB_INCLUDE_DIR} + #${ClickHouse_SOURCE_DIR}/contrib/zlib-ng + ${ClickHouse_SOURCE_DIR}/clucene/src/shared + ${ClickHouse_SOURCE_DIR}/clucene/src/core + ${CMAKE_CURRENT_BINARY_DIR}/../clucene/src/shared #for _clucene-config.h + ) + + +add_check(unittest_parser) \ No newline at end of file diff --git a/src/gtest/parser/main.cpp b/src/gtest/parser/main.cpp new file mode 100644 index 00000000000..d4f2e614375 --- /dev/null +++ b/src/gtest/parser/main.cpp @@ -0,0 +1,14 @@ +#include +#include "gtest/gtest.h" +#include "CLucene/analysis/mmseg/MMsegAnalyzer.h" + +int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + +#ifndef NDEBUG + ::testing::GTEST_FLAG(filter) = "ValueTypeParserTest.ipv4"; +#endif + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/htdocs/README b/src/htdocs/README new file mode 100644 index 00000000000..130d46b6c83 --- /dev/null +++ b/src/htdocs/README @@ -0,0 +1,9 @@ +How to upload: + +#create your shell space: +ssh ustramooner,clucene@shell.sf.net create + +#upload (make sure you upload with group write permissions otherwise other people can't overwrite) +rsync --chmod=ug=rwX -Pav htdocs/ ustramooner,clucene@shell.sf.net:/home/groups/c/cl/clucene/htdocs/ + + diff --git a/src/htdocs/_footer.html b/src/htdocs/_footer.html new file mode 100644 index 00000000000..0b7d4d937b4 --- /dev/null +++ b/src/htdocs/_footer.html @@ -0,0 +1,55 @@ +
 
+ + + + +
 
+ + + + + + + + + \ No newline at end of file diff --git a/src/htdocs/_header.html b/src/htdocs/_header.html new file mode 100644 index 00000000000..74a4edea342 --- /dev/null +++ b/src/htdocs/_header.html @@ -0,0 +1,37 @@ + + + + + + + +CLucene - lightning fast C++ search engine + + + +
+ + + + +
+
+
+
\ No newline at end of file diff --git a/src/htdocs/_index.php b/src/htdocs/_index.php new file mode 100644 index 00000000000..2ccb8b49173 --- /dev/null +++ b/src/htdocs/_index.php @@ -0,0 +1,9 @@ + diff --git a/src/htdocs/clucene.jpg b/src/htdocs/clucene.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ad3b29276f0096b4e95fa1b53ad31d508120aff8 GIT binary patch literal 7432 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 +
+

How to contribute?

+
+

We at CLucene would welcome any help from any capable person. Wether you are a developer, just a user, platform owner, or a webmaster, here is how you could help evolve and become the strongest and fastest indexing library out there:

+ +

C++ developers

+

Well, CLucene is written in C++ after all...

+

We need several tasks to be performed by experienced C++ developers. Examples for such include: porting of new code (Java Lucene always has new code to port), writing or porting miscellenous contribs, writing useful utilities (benchmarker for example), finding new ways to improve the speed of CLucene (memory pooling or special ways to handle strings for example), move lagacy code out and replace it with code from Boost libs, and much more...

+

There is really a lot to do, and if you like programming this is where you can get the best out of yourself.

+

Even if you can't actively participate in the project, we would really like to hear what you think of it, and if you find anything you think should be improved, don't hasitate dropping us a line!

+ +

Other developers

+

Write wrappers, use and file bug reports or feature requests

+

Being written in cross-platform C++, CLucene can be used from virtually any language and on any platform. If you can write or maintain (or both...) a decent wrapper for .NET, Perl, PHP, or any other language or platform, please do so. We will give you any help you need, and will host your project if necessary. Please contact us before starting any work on this, we might have exta info or pointers you would find useful (for example, there is a SWIG project in our SVN repository you can jump start from).

+

Alternatively, just use CLucene on your projects and report back any bugs or drawbacks you find. If you find it useful, please don't be shy to spread the word :)

+ + +

Testers

+

Make CLucene crash!

+

Yes, thats correct. We are looking for ways to crash CLucene, or at least stress-test any part of it. If you can provide us with creative ways to do so, please do!

+ + +

Platform owners

+

Help us test CLucene on more platforms

+

If you have access, or own, a non-standard platform, or one that CLucene has not been tested on yet, please take 5 minutes to test it and let us know how it went. If broken it is, fix it we would.

+ + +

Webmasters

+

Help make this pretty website even prettier

+

We need this website to contain loads of useful content, and someone to keep it up to date. That shouldn't be a tremendous task, but it requires a certain level of expertise.

+

Oh, and the pages you're seeing now are static HTML pages. We can install any LAMP CMS.

+ +
+
+ \ No newline at end of file diff --git a/src/htdocs/download.shtml b/src/htdocs/download.shtml new file mode 100644 index 00000000000..50f48799350 --- /dev/null +++ b/src/htdocs/download.shtml @@ -0,0 +1,168 @@ + +
+

What version to get?

+
+

For most new projects we recommend using the code in our git master HEAD. This version conforms with Java Lucene 2.3.2, and is considerably faster than any previous version of CLucene. It also uses cmake as it's build system, and continuesly evolves to be stronger and faster.

+

There is also the 0.9.21b version we release quite a while ago. It is proven to be stable, but we provide almost no support for it nowadays. Use it only if you have a compelling reason not to use the one in the git master HEAD.

+

For more info on this, please read this thread. You are welcome to ask any follow-up questions in our mailing list. Also, don't forget to check on how you can contribute.

+
+
+ + +
+
+
+

The 2_3_2 branch from the git master HEAD

+

Being continuesly updated

+
+

The recommended branch to use. Easier to build and maintain.

+

Use a git client to keep in sync with our working copy:

git clone git://clucene.git.sourceforge.net/gitroot/clucene/clucene
+

Alternatively, you can download a tarball through our WebGUI (click "snapshot").

+

Build instructions (more info in the INSTALLATION and README files):

+
+Building from source:
+--------------------
+
+Dependencies:
+* CMake version 2.4.2 or later (2.6 or later recommended due to an improved FindBoost module)
+* Boost libs (http://www.boost.org/), latest version recommended
+* A functioning and fairly new C++ compiler. We test mostly on GCC and Visual Studio 6+.
+Anything other than that may not work.
+* Something to unzip/untar the source code.
+
+Build instructions:
+1.) Download the latest sourcecode of the HEAD of the master branch in our git repository
+2.) Unpack the tarball/zip/bzip/whatever if downloaded as such
+3.) Open a command prompt, terminal window, or cygwin session.
+4.) Change directory into the root of the sourcecode (from now on referred to as )
+# cd 
+5.) Create and change directory into an 'out-of-source' directory for your build. 
+    [This is by far the easiest way to build,  it has the benefit of being able to 
+    create different types of builds in the same source-tree.]
+# mkdir /build-name
+# cd /build-name
+5*.) Windows users: make sure Boost environment variables are defined at least for the current
+   command prompt session. You can check this by typing "set" (no quotes). If you have any doubts,
+   just type the following 3 commands to set those variables, as follows (boost_1_40_0 being the
+   current Boost version):
+	set BOOST_BUILD_PATH=C:\{parent directory for boost}\boost_1_40_0\tools\build\v2
+	set BOOST_PATH=C:\{parent directory for boost}
+	set BOOST_ROOT=C:\{parent directory for boost}\boost_1_40_0
+6.) Configure using cmake. This can be done many different ways, but the basic syntax is
+# cmake [-G "Script name"] ..
+    [Where "Script name" is the name of the scripts to build (e.g. Visual Studio 8 2005).
+    A list of supported build scripts can be found by]
+# cmake --help
+7.) You can configure several options such as the build type, debugging information, 
+    mmap support, etc, by using the CMake GUI or by calling 
+# ccmake ..
+    Make sure you call configure again if you make any changes.
+8.) Start the build. This depends on which build script you specified, but it would be something like
+# make
+or
+# nmake
+    Or open the solution files with your IDE.
+
+    [You can also specify to just build a certain target (such as cl_test, cl_demo, 
+    clucene-core (shared library), clucene-core-static (static library).]
+9.) The binary files will be available in build-name/bin
+10.)Test the code. (After building the tests - this is done by default, or by calling make cl_test)
+# ctest -V
+11.)At this point you can install the library:
+# make install
+    [There are options to do this from the IDE, but I find it easier to create a 
+    distribution (see instructions below) and install that instead.]
+or
+# make cl_demo
+    [This creates the demo application, which demonstrates a simple text indexing and searching].
+or
+	Adjust build values using ccmake or the Cmake GUI and rebuild.
+	
+12.)Now you can develop your own code. This is beyond the scope of this document.
+    Read the README for information about documentation or to get help on the mailinglist.
+
+
+
+
+
+
+ + +
+
+
+

Release 0.9.21b

+

October 23rd, 2008

+
+

This is the latest stable official release.

+

Installation notes

+
+Rebuilding the autobuild scripts
+--------------------------------
+If you made changes to the configure.ac or any of the Makefile.am 
+files you will also need to run through this process.
+
+Requirements:
+GNU autotools is required. I have the following versions installed:
+Autoconf 2.57
+Automake 1.72
+Libtool 1.5a
+
+If you use significantly older versions, I can almost guarantee
+issues.  This is because each of the autotools is constantly changing
+with little regard to backward compatability or even compatiability
+with the other autotools.
+
+Run the autogen.sh file in the root directory of clucene to run the necessary commands.
+
+
+Building
+--------
+The following will get you building assuming that you have suffciently
+recent buld tools installed.  
+1.) unpack tarball 
+2.) cd into clucene
+3.) if you downloaded a tar version skip to 5
+4.) run ./autogen.sh
+5.) run ./configure
+6.) run make
+7.) things will churn for a very long time, the clucene library will
+be built as well as the examples.
+8.) check the src/demo, test and src directory
+
+In src/demo you should see:
+cl_demo
+
+In test you should see
+cl_test
+
+In src you should see:
+libclucene.so.0.0.0 libclucene.la libclucene.a 
+and symbolic links to these files.
+
+9.) If you want to run make install to copy the clucene files into the system 
+    include and lib directories
+10.) You may have to run
+export LD_LIBRARY_PATH=/path/to/clucene/lib 
+
+11.) run ./cl_test in the test directory and check that the tests all run
+
+Alternative (faster) way of building:
+-------------------------------------
+This method does not create library files, so depending on your needs you may not
+find this method useful.
+
+* Do steps 1-5 of the previous build process.
+* Change directory into src/
+* run make monolithic
+* Change directory into test/ (cd ../test/)
+* run make monolithic
+* You should see cl_test_monolithic in this directory
+* run ./cl_test_monolithic and check that the tests all run
+
+ +
+
+
+
+ \ No newline at end of file diff --git a/src/htdocs/images/disk.png b/src/htdocs/images/disk.png new file mode 100644 index 0000000000000000000000000000000000000000..99d532e8b1750115952f97302a92d713c0486f97 GIT binary patch literal 620 zcmV-y0+aoTP)~H+MJzd|s z^YP1Hc07G_>)Lgir!F1{Qn4GcTg%?koHo<=1qRN{}nPDolOeI^o4N5I>! zU$N=L=sg~ zDx#dOA*B0N~cqPsWI(^rbbkh)DS0_H_UN0C4l_kvWIm2#Kyy6%BCh z(yIUf003&1xdx>t$*eR2ZvXxT0001Z_R$y3Iju92q*wg58};}zm(OaAH=p|y0002M zh5O5#fxp|~jc?yi@+7$`d4Q6Hl%z;WiWG??NXR{Hx%)pMd~SE0000OQI literal 0 HcmV?d00001 diff --git a/src/htdocs/images/img01.gif b/src/htdocs/images/img01.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cc99182aee0dfe384ea40e29ac5fc52461f9f7d GIT binary patch literal 1945 zcmb`C{XY|k1AxbAoTd}q5nZ|Jkh-X=Hk+$?+nbF@UY4YiQQj-EUNCuSro42~M8g;x z^H$L+p|XvwB|u!xc?KM`w?N zPRPUVN5O~D`yj4I5Z*8sT>ESO_~h52u_?Z=PuM%?g7NL`mkdZov|8=xrx^#ZOBes` zt1f|f=o8@o#Ba-b|10hJ&;LCEfLeG;EDB_PhX;t;g@xYtAecb6pzi21dx=J&kB7dR z5odrvJp5_)AiF+_8F;^xp_9;%1Tyki#@_HuaU-GQu7_o%k}roPCgJmr7Tmpa`(#80 zD%+zNS(2WUUr4`SRm1cmHolH+dc)>MH-`$b zF|5vGA5gVtc;c>PiD!$;`;mz8%+D{{I@VS#&5I5c4 z`7-^Y$vNEL;CHq3z^21%#{@sQdYwJ_ zEFkV|b;!whquq&>;>toD*iH}8!_)7Em}dr{)CLQotHYoDSBvB)2Wbb%ZPI! zVggQIOWmx#oskyTs{J*68{T|-hRj=e?B>pd)=|=iCfg6UjJuYsCnZSx5X%!mu+Y zKZ26}87|Z=5@rO&IDE07_={ohuHT7EiXo~*crLmi4(M#i5NZQgT z3V3emb1ri4^28?J=;g^G0(*JtLE>DJE-iDfW`Ti0+uJZJE=2ZQ$-*`R5TV zM7#2>b(+00_gp=TPZ0c9_1mOAA#a^WSnxfzTWxG;Ls9#eJCC;y@ z#|T#6mnI5hzAw)(>c4A@AI*PXk#X&{s|ry}vd+?Uz4rU6dS0sqfM@`HRJ*QWgRTLV zrfbG)2SR13#uO`{HLAl9FC&=?Xh1N}S?`K0%?eazfJAkgP-QnwP-TYxyv|=ZvUCSZ z8OR9!%0ep3fC$PqB=TNu)yOj8pz@!7gumWyAQtd{aErN=zY912g zCcBdYqFe0_X?L+$$j!orZvV#RA)pI+#sLp^+MxNEFu=7U0o@w>G-Wnvp@0UO)Vqu9 z_MtA^1ud1>`SZK|peYFrl*&DXh}3?`!o60(IbA1iPq1d8a8uC(hfK8K3<40x!&dDt zTuy0oT)f{)3HxCJAv}*?q#8ns54G@x(ZO)NF%Sd7MZb-wE!H$6)%=92^fdf{C77riw}P{sD|rfdPx=vngOob1=il10acV4=Ty7dVBV97W98<; zY6Q6Z{cWP6!fIVA3W@2YhYRJOXo-ykYcR^K+ zxjD6=HXf30ysD{4SQ`fJk-R0UnrTLL;Ybf@A650J8drDTzehUAQ9W+Rsl%rM0I+`n Dd&1aS literal 0 HcmV?d00001 diff --git a/src/htdocs/images/img02.gif b/src/htdocs/images/img02.gif new file mode 100644 index 0000000000000000000000000000000000000000..ed75e84a0a662a7945e7b1326256a780bf0e84c4 GIT binary patch literal 11174 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 Q1yC5UDGKfoZ!!NAXaf|*f}fk}{&S&;Gn5rznm z!+?%N0vuczLJTYdj0{Z7NQxL3*w{Chm(+G<0NP`hSao2Pn=Y$SlZU&u}|b z{&K{x3vVWEy}R?X$?W-sS(aQAPz<9Y$IraoHzwPs$W^>B{Yq3`udhhGZ}MyBOC5UDGKfoZ!!C=FDf|*f}fk}{&S&;Gn5r$ld z!+_3&0}ggZF0gHI5fFogkx77&fq|WYk(q@VCc`-KB6A3v1pDR^GeJioRz)T;K}H5< zMg}Gzh5<&wLZQZkhK?*u|8FtyfFuQ(1sUuazFmFrpJ8&P{O!zp%dYMI_UAu?U9B3B ztg~J5M9TrDo60n!#m~b}?pb`h-M?~`-k*5;>;0Mg-LKDgZ~o`|q&|0f)$GXMb@lV@ z`p11f_ep;4@?Wz95y_*MhRI|4?1%DS?pc1j-M(_wIz%${VJ`hR z|3&%yWAfWK|IPbnAHV$R*Wdpc>{Blb+H2;{{%qFTniaTsp5pf9#u*V|OQmEStBS#5 z3y+A83XO)uXqw0h9L);UC=}KzdjU(LlKfNhD>nblt&8_x|M=_gdi(M~L3y5S6RyE4 LI;u15|K9`viGQ?} literal 0 HcmV?d00001 diff --git a/src/htdocs/images/img07.gif b/src/htdocs/images/img07.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff2e4ee7bb6bfe72d431de6f4a5e923ed350bcf4 GIT binary patch literal 469 zcmV;`0V@7SNk%w1VG;m<0K@H2P(esjFE>IvLQXV1 zNIynVLP}IHI7Bu+Ni;i0IY3J-H93{?jE#qAVZ2ANwTELlOi)xs9edirOTHvW5#Siv!>0PICJXU$+IWU z0YHNa9ZIyQ(W6L{DpiW0sne%Wqe`7hwW`&q0+KIzZDQm8D`ukOehG#{d^!fY=H?*bRuO zGKU+DGVMA-R|dlfj;h0gfYm7~8@9+QvRc@Rl$X4HwAi!5;+%ghi!;%%de6i}aisH0Tl7z0ok7|y`pd5|@}F@R%epMNzf zj=4;lGX6ZIKNi3#7}aHxD;;1sjywQEmp{V;m6b8-!d|*$5V7;Shto%-G2QmBp zObapFY-}`|n;>8f3T+U`?sX5`bMSL6-s1C35LDHUZtWv3LNL?8AB5odMjPMSph1BQ zV<*u;m3JyCT`;&PSsUMx0|Zqh5k8jYqZc;TuRlTul$ z(Liu+pW;^j)?XorQ9&?b?uB587$$lN|0=@v@u(Ss)zcs-Z(S8e46kmo5y@5wF%AI& zG{rugM-9j5AgD#etiw!csQy4uJ1?4EDQc#2nbHvV zY}4{Zr0|S+?C;*-tB<7R?3F}^s#M;dbZd!hu^?y`+u6jp*++YS`;Zj>cR+RrS$^yB_N>=RV&3S|i$5)1oXS;_!>6JlER70qw%7e1KVb3m zSL`Z&z$p#ntDE2V9XV2BamYXLDllyLMs5>DrxL=_+=#CEk(Wrzv*Oa@mY5?b%eyi; z*5?pi8}84R99p@k%m4Tu!>TxUb%l;4Ow8tz;s1(dMfjxd43D~E!ST2C{!=936eT%$ zoPjPmiu9bS4IHJ%##5^GWY_sPaK2lazdAbf*ev!h2kAXa z_DYKcK?arg`bgS|64?tHI63cT|Is56s^qlhvwB`tcbipV8cmUiZrdt@ICnF|-prjf zWwd=~%rUM4x# zaDm#C8p!=bF0Hqmwuy{y=5?Y}J~y0{ota5@(uK=IoBfL86SuoGeP2Q`^kiYlse!^y7manOmj zT~jaVLiGhI=3-CMwZgI+sHQP)7I5=Wxxo_7Z;fhwdOHDrnS6H zwwRy>`Q2md*Pf;2I3`PC20~S}S>B#wbTas_5PTJ7FQ*q|n^G1mK#6I4J5M}yD#}yS z)6vhyb0}?{F@q_s8$emCtBf=~M+AfWTb6eo;y&P9-ksNP*i;focAb!e5w`pRSnM!h literal 0 HcmV?d00001 diff --git a/src/htdocs/images/img09.jpg b/src/htdocs/images/img09.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2c65a7c1206010fb90f0df59779b0430bffe6138 GIT binary patch literal 1571 zcmex=C5UDGKfoZ!!63u5hnZ23fk}{&S&;Gn5r$Z> z!+@?t0A?00Mn(o^gaC-e#LOYUz{t#sBFY#jB&e9UaHAkdJtMM|AfsZT(EnQuJV0S4 zL1sY)dxlrrmUZ?lf3c!{(IUC7jw&t15y4EKwC{A9;F77|)VMt3lM+T50~!cZCjRgY zeW_B%^ktGgW0j|T!(NsC196kwALx53e-K|X@dx)Mk3X!V3aAkdSM(cl_Azey!FKwA L^ax?r|GxC5UDGKfoZ!!63r4hnZ23fk}{&S&;Gn5s10Y(O9py!!cI9Z{RjEO=_g2E!AVv2@J%#MM| z$;~P$Q&>%1*~QfbfsO`xoP`^1kRYRwu%e-(Xd;tRQqv@6XErf4Z z*fYFJyrk!eY%f`CiJ$rHdNGzC&+FMN@7FUH7Ct^*@};5S7at#^lRJxdO20Zg`+mo( zOhaK_Ux67}87+r{UDTvzDH>e4$l126!^hObDRJeZQAzB9(E0pX+3y?kuKlh(H+kN( z(!PCf({EpXm0TMalfPA~B44h!;%2S3^`E^j)`!=tzm%80`*FYh*E} zUcYzqt>2dXNqzredw)u(x70GS(gZ@&{L{yNl$YPWFZVou*~e?$v9r2&^`H2c^UF$W@9mH8KYhIa@bUZg|8D{S7XmxY literal 0 HcmV?d00001 diff --git a/src/htdocs/images/img11.gif b/src/htdocs/images/img11.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f0120dbb630258bcec7c153703fa69607a0d739 GIT binary patch literal 272 zcmZ?wbhEHbyu+Zuu$h5D*VOU<|Np;#{|=5!UcPF5azx-AK<}Y4p>EIn6 zo6dj)6o0aSc{(5xWCjDvUIP}#Q;Zg`&+h)8pwX9-IWMD2j#bfvanp*D-1`;lo--Tq z?p{#fp(DoL)KYjd$7(L;;bO0~QSNLLjTSs4Pn^5bd{;A;;rKU`q?LTo=@0^8hz4I3>b6wE2 ze6`C0hFNPiTGXxIuxY#bmL0oIoA>P3=ss{*rEA@h6Y|GTo;iE&{Dq5`E?>EN?fQ+I Qw{G9Ld++{(O@a*809;jo0{{R3 literal 0 HcmV?d00001 diff --git a/src/htdocs/images/spacer.gif b/src/htdocs/images/spacer.gif new file mode 100644 index 0000000000000000000000000000000000000000..5bfd67a2d6f72ac3a55cbfcea5866e841d22f5d9 GIT binary patch literal 43 mcmZ?wbhEHbWMp7uXkdT>#h)yUAf^t80Ld^gF}W}@SOWlZ0R#L1 literal 0 HcmV?d00001 diff --git a/src/htdocs/index.shtml b/src/htdocs/index.shtml new file mode 100644 index 00000000000..2ceb2d7fd47 --- /dev/null +++ b/src/htdocs/index.shtml @@ -0,0 +1,19 @@ + +
+

What is CLucene?

+
+

CLucene is a high-performance, scalable, cross platform, full-featured, open-source indexing and searching API. Specifically, CLucene is the guts of a search engine, the hard stuff. You write the easy stuff: the UI and the process of selecting and parsing your data files to pump them into the search engine yourself, and any specialized queries to pull it back for display or further processing.

+

CLucene is a port of the very popular Java Lucene text search engine API. CLucene aims to be a good alternative to Java Lucene when performance really matters or if you want to stick to good old C++. CLucene is faster than Lucene as it is written in C++, meaning it is being compiled into machine code, has no background GC operations, and requires no any extra setup procedures.

+

Being written in pure cross-platform C++ code, and utilizing the flexible cmake build system, CLucene can virtually be used for any purpose, on any machine. From PCs running Windows or Linux to Mobile devices. The sky is the limit.

+
+
+ +
+

Current status

+
+

Currently you can get CLucene in two flavors - one is the 0.9.21 release, which has been proven to be stable over time, but is only compatiable with Java Lucene 1.9.1. Another option is our current working copy on git, which conforms with Java Lucene 2.3.2. A detailed status and info on how to decide which one to use was posted on our Mailing List not long ago.

+

Since we all are very busy people, unfortunately we cannot dedicate all the time we would have wanted to in this project. We do believe in what we do, but the work on this is never ending. Please, if you believe in open-source software, like we do, see if you can contribute to the project.

+

More info and download instructions on our downloads page.

+
+
+ \ No newline at end of file diff --git a/src/htdocs/style.css b/src/htdocs/style.css new file mode 100644 index 00000000000..0b45b46cd12 --- /dev/null +++ b/src/htdocs/style.css @@ -0,0 +1,344 @@ +/* +Design by Free CSS Templates +http://www.freecsstemplates.org +Released for free under a Creative Commons Attribution 2.5 License +*/ + +body { + margin: 0; + padding: 0; + background: #E3E7ED url(images/img01.gif) repeat-x left top; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + color: #787878; +} + +h1, h2, h3 { + margin: 0; + padding: 0; + font-family: Georgia, "Times New Roman", Times, serif; + font-weight: normal; + color: #000; +} + +h1 { + font-size: 2em; +} + +h2 { + font-size: 1.6em; +} + +h3 { + font-size: 1.6em; +} + +p, ul, ol { + margin-top: 0; + line-height: 180%; +} + +ul, ol { +} + +a { + text-decoration: none; + border-bottom: 1px dotted #999999; + color: #417FDA; +} + +a:hover { +} + +#wrapper { + width: 968px; + margin: 0 auto; + padding: 0; +} + +/* Header */ + +#header { + width: 968px; + height: 150px; + margin: 0 auto; + background: url(images/img02.gif) no-repeat left top; +} + +/* Logo */ + +#logo { + float: left; + width: 968px; + height: 60px; + color: #616161; +} + +#logo h1, #logo p { + margin: 0; + padding: 0; +} + +#logo h1 { + float: left; + padding: 80px 0 0 80px; + letter-spacing: -1px; + text-transform: lowercase; + font-size: 2.6em; +} + +#logo p { + float: left; + margin: 0; + padding: 90px 10px; + font: normal 14px Georgia, "Times New Roman", Times, serif; + font-style: italic; +} + +#logo a { + border: none; + background: none; + text-decoration: none; + color: #616161; +} + +/* Search */ + +#search { + float: right; + width: 230px; + padding: 0; +} + +#search form { + height: 41px; + margin: 0; + padding: 70px 0 0 0px; +} + +#search fieldset { + margin: 0; + padding: 0; + border: none; +} + +#search-text { + width: 210px; + border: none; + text-transform: lowercase; + font: bold 1.2em Arial, Helvetica, sans-serif; + color: #FFFFFF; +} + +#search-submit { + display: none; +} + +/* Menu */ + +#menu { + width: 968px; + height: 50px; + margin: 0 auto; + padding: 0; +} + +#menu ul { + margin: 0; + padding: 0; + padding-left: 10px; + list-style: none; + line-height: normal; +} + +#menu li { + float: left; + height: 50px; + background: url(images/img03.gif) no-repeat right top; +} + +#menu a { + display: block; + margin-top: 10px; + margin-right: 3px; + padding: 7px 20px 7px 20px; + text-decoration: none; + font-family: Arial, Helvetica, sans-serif; + font-size: 13px; + color: #FFFFFF; + border: none; +} + +#menu a:hover, #menu .current_page_item a { +} + +#menu a:hover { + text-decoration: underline; +} + +/* Page */ + +#page { + width: 968px; + margin: 0 auto; + background: url(images/img05.jpg) repeat-y left top; +} + +#page-bgtop { + background: url(images/img04.jpg) no-repeat left top; +} + +#page-bgbtm { + background: url(images/img06.jpg) no-repeat left bottom; +} + +/* Content */ + +#content { + float: right; + width: 700px; + padding: 60px 20px 0 0; +} + +.post { + margin-bottom: 8px; + background: url(images/img09.jpg) repeat-y left top; +} + +.post-bgtop { + background: url(images/img08.jpg) no-repeat left top; +} + +.post-bgbtm { + background: url(images/img10.jpg) no-repeat left bottom; +} +.whitepost {padding-left: 20px;} +.whitepost .title {color:#000000;padding-bottom:15px;} +.post .title { + padding-top: 15px; + padding-left: 20px; + color: #000000; +} + +.post .title a { + color: #000000; + border: none; +} + +.post .meta { + border-bottom: 1px dashed #B5DEF4; + padding-left: 20px; + padding-bottom: 5px; + text-align: left; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; + font-style: italic; +} + +.post .entry { + padding: 10px 20px 15px 20px; + text-align: justify; +} + +/* Sidebar */ + +#sidebar { + float: left; + width: 220px; + padding: 60px 0 0 20px; + color: #787878; +} + +#sidebar ul { + margin: 0; + padding: 0; + list-style: none; +} + +#sidebar li { + margin: 0; + padding: 0; +} + +#sidebar li ul { + padding-bottom: 30px; +} + +#sidebar li li { + line-height: 35px; + border-bottom: 1px dashed #D2D4C9; +} + +#sidebar li li span { + display: block; + margin-top: -20px; + padding: 0; + font-size: 11px; + font-style: italic; +} + +#sidebar h2 { + height: 32px; + padding: 8px 0 0 30px; + background: url(images/img11.gif) no-repeat left top; + letter-spacing: -.5px; + color: #FFFFFF; +} + +#sidebar p { + padding-bottom: 20px; + text-align: justify; +} + +#sidebar a { + color: #417FDA; + border: none; +} + +#sidebar a:hover { + text-decoration: underline; + color: #787878; +} + +/* Calendar */ + +#calendar { +} + +#calendar_wrap { + padding: 20px; +} + +#calendar table { + width: 100%; +} + +#calendar tbody td { + text-align: center; +} + +#calendar #next { + text-align: right; +} + +/* Footer */ + +#footer { + height: 50px; + margin: 0 auto; + padding: 0px 0 15px 0; + font-family: Arial, Helvetica, sans-serif; + color: #B2B2B2; +} + +#footer p { + margin: 0; + line-height: normal; + font-size: 9px; + text-transform: uppercase; + text-align: center; +} + +#footer a { + color: #3D444F; +} \ No newline at end of file diff --git a/src/shared/CLucene/CLSharedMonolithic.cpp b/src/shared/CLucene/CLSharedMonolithic.cpp new file mode 100644 index 00000000000..9e73f9a85f8 --- /dev/null +++ b/src/shared/CLucene/CLSharedMonolithic.cpp @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +/* +* this is a monolithic file that can be used to compile clucene using one source file. +* it simplifies some build processes by avoiding static & dynamic compalation pitfalls. +* +* note: when creating a project add either this file, or all the other .cpp files, not both! +*/ +#include "CLucene/SharedHeader.cpp" +#include "CLucene/config/gunichartables.cpp" +#include "CLucene/config/repl_tcscasecmp.cpp" +#include "CLucene/config/repl_tcslwr.cpp" +#include "CLucene/config/repl_tcstod.cpp" +#include "CLucene/config/repl_lltot.cpp" +#include "CLucene/config/repl_tcstoll.cpp" +#include "CLucene/config/repl_tprintf.cpp" +#include "CLucene/config/threads.cpp" +#include "CLucene/config/utf8.cpp" +#include "CLucene/debug/condition.cpp" +#include "CLucene/util/Misc.cpp" +#include "CLucene/util/dirent.cpp" +#include "CLucene/util/StringBuffer.cpp" diff --git a/src/shared/CLucene/LuceneThreads.h b/src/shared/CLucene/LuceneThreads.h new file mode 100644 index 00000000000..97072eee60a --- /dev/null +++ b/src/shared/CLucene/LuceneThreads.h @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _LuceneThreads_h +#define _LuceneThreads_h + + +CL_NS_DEF(util) +class CLuceneThreadIdCompare; + +#if defined(_CL_DISABLE_MULTITHREADING) + #define SCOPED_LOCK_MUTEX(theMutex) + #define DEFINE_MUTEX(x) + #define DEFINE_MUTABLE_MUTEX(x) + #define DEFINE_CONDITION(x) + #define STATIC_DEFINE_MUTEX(x) + #define CONDITION_WAIT(theMutex, theCondition) + #define CONDITION_NOTIFYALL(theCondition) + #define _LUCENE_CURRTHREADID 1 + #define _LUCENE_THREADID_TYPE int + #define _LUCENE_THREAD_FUNC(name, argName) int name(void* argName) + #define _LUCENE_THREAD_FUNC_RETURN(val) return (int)val; + #define _LUCENE_THREAD_CREATE(func, arg) (*func)(arg) + #define _LUCENE_THREAD_JOIN(value) //nothing to do... + #define _LUCENE_THREADMUTEX void* + + #define _LUCENE_ATOMIC_INC(theInteger) (++(*theInteger)) + #define _LUCENE_ATOMIC_DEC(theInteger) (--(*theInteger)) + #define _LUCENE_ATOMIC_INT int +#else + #if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX) + //do nothing + #else + class mutexGuard; + + #if defined(_CL_HAVE_PTHREAD) + #define _LUCENE_THREADID_TYPE pthread_t + #define _LUCENE_THREAD_FUNC(name, argName) void* name(void* argName) //< use this macro to correctly define the thread start routine + #define _LUCENE_THREAD_FUNC_RETURN(val) return (void*)val; + typedef void* (luceneThreadStartRoutine)(void* lpThreadParameter ); + + class CLUCENE_SHARED_EXPORT mutex_thread + { + public: + struct Internal; + Internal* _internal; + + mutex_thread(const mutex_thread& clone); + mutex_thread(); + ~mutex_thread(); + void lock(); + void unlock(); + static _LUCENE_THREADID_TYPE _GetCurrentThreadId(); + static _LUCENE_THREADID_TYPE CreateThread(luceneThreadStartRoutine* func, void* arg); + static void JoinThread(_LUCENE_THREADID_TYPE id); + void Wait(mutex_thread* shared_lock); + void NotifyAll(); + }; + class CLUCENE_SHARED_EXPORT shared_condition{ + private: + class Internal; + Internal* _internal; + public: + shared_condition(); + ~shared_condition(); + void Wait(mutex_thread* shared_lock); + void NotifyAll(); + }; + + #ifdef _CL_HAVE_GCC_ATOMIC_FUNCTIONS + #define _LUCENE_ATOMIC_INT uint32_t + #define _LUCENE_ATOMIC_INT_SET(x,v) x=v + #define _LUCENE_ATOMIC_INT_GET(x) x + #else + class CLUCENE_SHARED_EXPORT __LUCENE_ATOMIC_INT{ + public: + int value; + CL_NS(util)::mutex_thread THIS_LOCK; + }; + #define _LUCENE_ATOMIC_INT CL_NS(util)::__LUCENE_ATOMIC_INT + #define _LUCENE_ATOMIC_INT_SET(x,v) x.value=v + #define _LUCENE_ATOMIC_INT_GET(x) x.value + #endif + + class CLUCENE_SHARED_EXPORT atomic_threads{ + public: + static int32_t atomic_increment(_LUCENE_ATOMIC_INT* theInteger); + static int32_t atomic_decrement(_LUCENE_ATOMIC_INT* theInteger); + }; + + #define _LUCENE_ATOMIC_INC(theInteger) CL_NS(util)::atomic_threads::atomic_increment(theInteger) + #define _LUCENE_ATOMIC_DEC(theInteger) CL_NS(util)::atomic_threads::atomic_decrement(theInteger) + + #elif defined(_CL_HAVE_WIN32_THREADS) + #define _LUCENE_THREADID_TYPE uint64_t + #define _LUCENE_THREAD_FUNC(name, argName) void __stdcall name(void* argName) //< use this macro to correctly define the thread start routine + #define _LUCENE_THREAD_FUNC_RETURN(val) CL_NS(util)::mutex_thread::_exitThread(val) + + #define _LUCENE_ATOMIC_INC(theInteger) CL_NS(util)::mutex_thread::atomic_increment(theInteger) + #define _LUCENE_ATOMIC_DEC(theInteger) CL_NS(util)::mutex_thread::atomic_decrement(theInteger) +#ifdef _M_X64 + #define _LUCENE_ATOMIC_INT long long +#else + #define _LUCENE_ATOMIC_INT long +#endif + #define _LUCENE_ATOMIC_INT_SET(x,v) x=v + #define _LUCENE_ATOMIC_INT_GET(x) x + + typedef void (__stdcall luceneThreadStartRoutine)(void* lpThreadParameter ); + class CLUCENE_SHARED_EXPORT mutex_thread + { + private: + struct Internal; + Internal* _internal; + public: + mutex_thread(const mutex_thread& clone); + mutex_thread(); + ~mutex_thread(); + void lock(); + void unlock(); + static void _exitThread(int ret); + static _LUCENE_THREADID_TYPE _GetCurrentThreadId(); + static _LUCENE_THREADID_TYPE CreateThread(luceneThreadStartRoutine* func, void* arg); + static void JoinThread(_LUCENE_THREADID_TYPE id); + + static int32_t atomic_increment(_LUCENE_ATOMIC_INT* theInteger); + static int32_t atomic_decrement(_LUCENE_ATOMIC_INT* theInteger); + }; + class CLUCENE_SHARED_EXPORT shared_condition{ + private: + class Internal; + Internal* _internal; + public: + shared_condition(); + ~shared_condition(); + void Wait(mutex_thread* shared_lock); + void NotifyAll(); + }; + #else + #error A valid thread library was not found + #endif //mutex types + + #define _LUCENE_THREAD_CREATE(func, arg) CL_NS(util)::mutex_thread::CreateThread(func,arg) + #define _LUCENE_THREAD_JOIN(id) CL_NS(util)::mutex_thread::JoinThread(id) + #define _LUCENE_CURRTHREADID CL_NS(util)::mutex_thread::_GetCurrentThreadId() + #define _LUCENE_THREADMUTEX CL_NS(util)::mutex_thread + #define _LUCENE_THREADCOND CL_NS(util)::shared_condition + #endif //don't implement + + /** @internal */ + class CLUCENE_SHARED_EXPORT mutexGuard + { + private: + _LUCENE_THREADMUTEX* mrMutex; + mutexGuard(const mutexGuard& clone); + public: + mutexGuard( _LUCENE_THREADMUTEX& rMutex ); + ~mutexGuard(); + }; + + #define SCOPED_LOCK_MUTEX(theMutex) CL_NS(util)::mutexGuard theMutexGuard(theMutex); + #define DEFINE_MUTEX(theMutex) _LUCENE_THREADMUTEX theMutex; + #define DEFINE_CONDITION(theCondition) _LUCENE_THREADCOND theCondition; + #define DEFINE_MUTABLE_MUTEX(theMutex) mutable _LUCENE_THREADMUTEX theMutex; + #define STATIC_DEFINE_MUTEX(theMutex) static _LUCENE_THREADMUTEX theMutex; + + #define CONDITION_WAIT(theMutex, theCondition) theCondition.Wait(&theMutex); + #define CONDITION_NOTIFYALL(theCondition) theCondition.NotifyAll(); + +#endif //_CL_DISABLE_MULTITHREADING +CL_NS_END + +#endif diff --git a/src/shared/CLucene/SharedHeader.cpp b/src/shared/CLucene/SharedHeader.cpp new file mode 100644 index 00000000000..0efb61bec77 --- /dev/null +++ b/src/shared/CLucene/SharedHeader.cpp @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_SharedHeader.h" + + +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif + + +const TCHAR* _LUCENE_BLANK_STRING=_T(""); +const char* _LUCENE_BLANK_ASTRING=""; + +#if defined(_ASCII) + #if defined(_LUCENE_PRAGMA_WARNINGS) + #pragma message ("==================Using ascii mode!!!==================") + #else + #warning "==================Using ascii mode!!!==================" + #endif +#endif + +wchar_t* lucene_wcsdup( const wchar_t* str ){ + size_t len = wcslen(str); + wchar_t* ret = (wchar_t*)malloc( (len + 1) * sizeof(wchar_t) ); + wcscpy(ret, str); + return ret; +} diff --git a/src/shared/CLucene/SharedHeader.h b/src/shared/CLucene/SharedHeader.h new file mode 100644 index 00000000000..d43a149176f --- /dev/null +++ b/src/shared/CLucene/SharedHeader.h @@ -0,0 +1,213 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef lucene_sharedheader_h +#define lucene_sharedheader_h + +/** +* This header contains definitions and macros for helping create cross-platform code. +* It is primarily for use by the clucene-core library, but is split off so that +* other applications such as the demo, test, benchmarks, etc can benefit from the +* cross platform code. Cross platform code is not distributed with the clucene-core +* and is not available through the shared library. +*/ + +#include "CLucene/clucene-config.h" + +//some early definitions +#if defined(_MSC_VER) || defined(__BORLANDC__) + #define _LUCENE_PRAGMA_WARNINGS //tell lucene to display warnings using pragmas instead of #warning +#endif + + +//////////////////////////////////////////////////////// +//Are we in unicode mode? +//////////////////////////////////////////////////////// +#if defined(_MBCS) || defined(_ASCII) + #undef _ASCII + #undef _UCS2 + #define _ASCII +#elif defined(_UNICODE) + #ifndef _UCS2 + #define _UCS2 + #endif +#elif !defined(_UCS2) + #define _UCS2 +#endif + +//msvc needs unicode define so that it uses unicode library +#ifdef _UCS2 + #undef _UNICODE + #define _UNICODE + #undef _ASCII +#else + #undef _UNICODE + #undef _UCS2 +#endif +//////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////// +//platform includes that MUST be included for the public headers to work... +//////////////////////////////////////////////////////// +#include //need this for wchar_t, size_t, NULL +#ifdef _CL_HAVE_STDINT_H + #include //need this for int32_t, etc +#endif +#include //required for float_t +#include //need to include this really early... + +#ifdef _CL_HAVE_TCHAR_H + #include //required for _T and TCHAR +#endif + +//////////////////////////////////////////////////////// +//namespace helper +//////////////////////////////////////////////////////// +#if defined(_LUCENE_DONTIMPLEMENT_NS_MACROS) + //do nothing +#elif !defined(DISABLE_NAMESPACE) && defined(_CL_HAVE_NAMESPACES) + #define CL_NS_DEF(sub) namespace lucene{ namespace sub{ + #define CL_NS_DEF2(sub,sub2) namespace lucene{ namespace sub{ namespace sub2 { + + #define CL_NS_END }} + #define CL_NS_END2 }}} + + #define CL_NS_USE(sub) using namespace lucene::sub; + #define CL_NS_USE2(sub,sub2) using namespace lucene::sub::sub2; + + #define CL_NS(sub) lucene::sub + #define CL_NS2(sub,sub2) lucene::sub::sub2 + + #define CL_STRUCT_DEF(sub,clazz) namespace lucene { namespace sub{ struct clazz; } } + #define CL_CLASS_DEF(sub,clazz) namespace lucene { namespace sub{ class clazz; } } + #define CL_CLASS_DEF2(sub,sub2, clazz) namespace lucene { namespace sub{ namespace sub2{ class clazz; } } } + + #define CL_TEMPATE_DEF(sub, clazz, typedefs) namespace lucene { namespace sub{ template class clazz; }} + #define CL_TYPE_DEF(sub, clazz, def) namespace lucene { namespace sub{ typedef def clazz; }} +#else + #define CL_NS_DEF(sub) + #define CL_NS_DEF2(sub, sub2) + #define CL_NS_END + #define CL_NS_END2 + #define CL_NS_USE(sub) + #define CL_NS_USE2(sub,sub2) + #define CL_NS(sub) + #define CL_NS2(sub,sub2) + #define CL_CLASS_DEF(sub,clazz) class clazz; + #define CL_CLASS_DEF2(sub,sub2, clazz) class clazz; +#endif + +#if defined(LUCENE_NO_STDC_NAMESPACE) + //todo: haven't actually tested this on a non-stdc compliant compiler + #define CL_NS_STD(func) ::func +#else + #define CL_NS_STD(func) std::func +#endif +// +//////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////// +// EXPORTS definition +//////////////////////////////////////////////////////// +#if defined(_WIN32) || defined(_WIN64) + #define CLUCENE_EXPORT_DECL __declspec(dllexport) + #define CLUCENE_IMPORT_DECL __declspec(dllimport) + #define CLUCENE_LOCAL_DECL +#elif defined(_CL_HAVE_GCCVISIBILITYPATCH) + #define CLUCENE_EXPORT_DECL __attribute__ ((visibility("default"))) + #define CLUCENE_LOCAL_DECL __attribute__ ((visibility("hidden"))) + #define CLUCENE_IMPORT_DECL +#else + #define CLUCENE_EXPORT_DECL + #define CLUCENE_IMPORT_DECL + #define CLUCENE_LOCAL_DECL +#endif + +//define for the libraries +#if defined(clucene_shared_EXPORTS) + #define CLUCENE_SHARED_EXPORT CLUCENE_EXPORT_DECL + #define CLUCENE_LOCAL CLUCENE_LOCAL_DECL +#elif defined(MAKE_CLUCENE_SHARED_LIB) + #define CLUCENE_SHARED_EXPORT //don't export if we are building a static library +#else + #define CLUCENE_SHARED_EXPORT CLUCENE_IMPORT_DECL +#endif +#if defined(clucene_core_EXPORTS) + #define CLUCENE_EXPORT CLUCENE_EXPORT_DECL + #define CLUCENE_LOCAL CLUCENE_LOCAL_DECL +#elif defined(MAKE_CLUCENE_CORE_LIB) + #define CLUCENE_EXPORT +#else + #define CLUCENE_EXPORT CLUCENE_IMPORT_DECL +#endif +#if defined(clucene_contribs_lib_EXPORTS) + #define CLUCENE_CONTRIBS_EXPORT CLUCENE_EXPORT_DECL + #define CLUCENE_LOCAL CLUCENE_LOCAL_DECL +#elif defined(MAKE_CLUCENE_CONTRIBS_LIB) + #define CLUCENE_CONTRIBS_EXPORT +#else + #define CLUCENE_CONTRIBS_EXPORT CLUCENE_IMPORT_DECL +#endif +#ifndef CLUCENE_LOCAL + #define CLUCENE_LOCAL +#endif + +//inline definitions +#if defined(__MINGW32__) || defined(_MSC_VER) + #define CLUCENE_SHARED_INLINE_EXPORT + #define CLUCENE_INLINE_EXPORT + #define CLUCENE_CONTRIBS_INLINE_EXPORT +#else + #define CLUCENE_SHARED_INLINE_EXPORT CLUCENE_SHARED_EXPORT + #define CLUCENE_INLINE_EXPORT CLUCENE_EXPORT + #define CLUCENE_CONTRIBS_INLINE_EXPORT CLUCENE_CONTRIBS_EXPORT +#endif +//////////////////////////////////////////////////////// + + +//todo: put this logic in cmake +#if defined(_MSC_VER) + #if _MSC_FULL_VER >= 140050320 + #define _CL_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text)) + #elif _MSC_VER >= 1300 + #define _CL_DEPRECATE_TEXT(_Text) __declspec(deprecated) + #else + #define _CL_DEPRECATE_TEXT(_Text) + #endif +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + #define _CL_DEPRECATE_TEXT(_Text) __attribute__((__deprecated__)) +#else + #define _CL_DEPRECATE_TEXT(_Text) +#endif +#define _CL_DEPRECATED(_NewItem) _CL_DEPRECATE_TEXT("This function or variable has been superceded by newer library or operating system functionality. Consider using " #_NewItem " instead. See online help for details.") +// +//////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////// +// boost stuff +//////////////////////////////////////////////////////// +#if defined(_MSC_VER) +# pragma warning (disable : 4251) // disable exported dll function +# endif + +//////////////////////////////////////////////////////// +//Class interfaces +//////////////////////////////////////////////////////// +#include "CLucene/debug/lucenebase.h" +//////////////////////////////////////////////////////// + +//memory handling macros/functions +#include "CLucene/debug/mem.h" + +#ifdef DMALLOC + #include + #include + #include +#endif + +#endif //lucene_sharedheader_h diff --git a/src/shared/CLucene/_SharedHeader.h b/src/shared/CLucene/_SharedHeader.h new file mode 100644 index 00000000000..be1ed4bdb75 --- /dev/null +++ b/src/shared/CLucene/_SharedHeader.h @@ -0,0 +1,71 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef lucene_internal_sharedheader_h +#define lucene_internal_sharedheader_h + +#define LUCENE_INT32_MAX_SHOULDBE 0x7FFFFFFFL + +#include "CLucene/_clucene-config.h" +#include "CLucene/SharedHeader.h" + +//don't show deprecated warnings while building internally... +#undef _CL_DEPRECATE_TEXT +#define _CL_DEPRECATE_TEXT(_Text) + +#define LUCENE_INT64_MAX_SHOULDBE _ILONGLONG(0x7FFFFFFFFFFFFFFF) +#define LUCENE_INT64_MIN_SHOULDBE (-LUCENE_INT64_MAX_SHOULDBE - _ILONGLONG(1) ) + +//required globally (internally only) +#include +#include + +//we always need this stuff.... +#include "CLucene/debug/_condition.h" +#include "CLucene/LuceneThreads.h" +#include "CLucene/config/repl_tchar.h" +#include "CLucene/config/repl_wchar.h" +#include "CLucene/config/repl_wctype.h" //replacements for functions + +#define cl_min(a,b) ((a)>(b) ? (b) : (a)) +#define cl_min3(a,b,c) ((a)<(b) ? ((a)<(c) ? (a) : (c)) : ((b)<(c) ? (b) : (c))) +#define cl_max(a,b) ((a)>(b) ? (a): (b)) +#define cl_max3(a,b,c) ((a)>(b) ? ((a)>(c) ? (a) : (c)) : ((b)>(c) ? (b) : (c))) + +#ifdef _CL_HAVE_SAFE_CRT + #define cl_sprintf sprintf_s + #define cl_stprintf _stprintf_s + #define cl_strcpy(Dst,Src,DstLen) strcpy_s(Dst,DstLen,Src) +#else + #define cl_sprintf _snprintf + #define cl_stprintf _sntprintf + #define cl_strcpy(Dst,Src,DstLen) strcpy(Dst,Src) +#endif + + +template +CLUCENE_SHARED_EXPORT extern const T* _LUCENE_BLANK_SSTRING; + +///a blank string... +CLUCENE_SHARED_EXPORT extern const TCHAR* _LUCENE_BLANK_STRING; +#define LUCENE_BLANK_STRING _LUCENE_BLANK_STRING +CLUCENE_SHARED_EXPORT extern const char* _LUCENE_BLANK_ASTRING; +#define LUCENE_BLANK_ASTRING _LUCENE_BLANK_ASTRING + +#if defined(_WIN32) || defined(_WIN64) + #define PATH_DELIMITERA "\\" +#else + #define PATH_DELIMITERA "/" +#endif + +#define _LUCENE_SLEEP(ms) CL_NS(util)::Misc::sleep(ms) + +//if a wide character is being converted to a ascii character and it +//cannot fit, this character is used instead. +#define LUCENE_OOR_CHAR(c) ((char)(((unsigned short)c)&0xFF)) + + +#endif //lucene_internal_sharedheader_h diff --git a/src/shared/CLucene/_clucene-config.h.cmake b/src/shared/CLucene/_clucene-config.h.cmake new file mode 100644 index 00000000000..1e8e72ade09 --- /dev/null +++ b/src/shared/CLucene/_clucene-config.h.cmake @@ -0,0 +1,112 @@ +#ifndef _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H +#define _SRC_CLUCENE_INTERNAL_CLUCENE_CONFIG_H 1 + +/* src/shared/CLucene/_clucene-config.h. +* Generated automatically at end of cmake. +* These are internal definitions, and this file does not need to be distributed +*/ + +/* CMake will look for these functions: */ +#cmakedefine _CL_HAVE_FUNCTION__VSNWPRINTF +#cmakedefine _CL_HAVE_FUNCTION__SNWPRINTF +#cmakedefine _CL_HAVE_FUNCTION_WCSCASECMP +#cmakedefine _CL_HAVE_FUNCTION_WCSCAT 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSCHR 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSCMP 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSCPY 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSCSPN 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSICMP +#cmakedefine _CL_HAVE_FUNCTION_WCSLEN 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSNCMP 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSNCPY 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSSTR 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSTOD 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSDUP 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSTOLL 1 +#cmakedefine _CL_HAVE_FUNCTION_WCSUPR 1 +#cmakedefine _CL_HAVE_FUNCTION_GETTIMEOFDAY 1 +#cmakedefine _CL_HAVE_FUNCTION_MAPVIEWOFFILE 1 + +#cmakedefine _CL_HAVE_FUNCTION_LLTOA 1 +#cmakedefine _CL_HAVE_FUNCTION_LLTOW 1 +#cmakedefine _CL_HAVE_FUNCTION_PRINTF 1 +#cmakedefine _CL_HAVE_FUNCTION_SNPRINTF 1 +#cmakedefine _CL_HAVE_FUNCTION_MMAP 1 +#cmakedefine _CL_HAVE_FUNCTION_STRLWR 1 +#cmakedefine _CL_HAVE_FUNCTION_STRTOLL 1 +#cmakedefine _CL_HAVE_FUNCTION_STRUPR 1 +#cmakedefine _CL_HAVE_FUNCTION_GETPAGESIZE 1 +#cmakedefine _CL_HAVE_FUNCTION_USLEEP 1 +#cmakedefine _CL_HAVE_FUNCTION_SLEEP 1 + +${SYMBOL_CL_MAX_PATH} +//this is the max filename... for now its just the same, +//but this could change, so we use a different name +#define CL_MAX_NAME CL_MAX_PATH +//this used to be CL_MAX_NAME * 32, but as Alex Hudson points out, this could come to be 128kb. +//the above logic for CL_MAX_NAME should be correct enough to handle all file names +#define CL_MAX_DIR CL_MAX_PATH + +${SYMBOL__O_RANDOM} +${SYMBOL__O_BINARY} +${SYMBOL__S_IREAD} +${SYMBOL__S_IWRITE} +${TYPE__TIMEB} + +#define _ILONG(x) x ## L +#define _ILONGLONG(x) ${_CL_ILONGLONG_VALUE} + +${FUNCTION_FILESTAT} +${TYPE_CL_STAT_T} +${FUNCTION_FILESIZE} +${FUNCTION_FILESEEK} +${FUNCTION_FILETELL} +${FUNCTION_FILEHANDLESTAT} +${FUNCTION__REALPATH} +${FUNCTION__RENAME} +${FUNCTION__CLOSE} +${FUNCTION__READ} +${FUNCTION__CL_OPEN} +${FUNCTION__WRITE} +${FUNCTION__SNPRINTF} +${FUNCTION__MKDIR} +${FUNCTION__UNLINK} +${FUNCTION__FTIME} +${FUNCTION_SLEEPFUNCTION} + +/* CMake will determine these specifics. Things like bugs, etc */ + +/* Does not support new float byte<->float conversions */ +#cmakedefine _CL_HAVE_NO_FLOAT_BYTE 1 + +/* Define if recursive pthread mutexes are available */ +#cmakedefine _CL_HAVE_PTHREAD_MUTEX_RECURSIVE 1 + +/** define if you would like to force clucene to use the internal +* character functions. +* Tests may display unpredictable behaviour if this is not defined. +*/ +#ifndef LUCENE_USE_INTERNAL_CHAR_FUNCTIONS + #cmakedefine LUCENE_USE_INTERNAL_CHAR_FUNCTIONS 1 +#endif + +/** fix ansi for loop scope */ +#if @CMAKE_ANSI_FOR_SCOPE@==0 + #define for if (0); else for +#endif + + +/* Compiler oddities */ + +//not sure why, but cygwin reports _S_IREAD, but doesn't actually work... +//TODO: make this work properly (this bit shouldn't be necessary) +#ifdef __CYGWIN__ + #define _S_IREAD 0333 + #define _S_IWRITE 0333 +#endif + +#ifdef __BORLANDC__ //borland compiler + #define O_RANDOM 0 +#endif + +#endif diff --git a/src/shared/CLucene/clucene-config.h.cmake b/src/shared/CLucene/clucene-config.h.cmake new file mode 100644 index 00000000000..bd8683a588e --- /dev/null +++ b/src/shared/CLucene/clucene-config.h.cmake @@ -0,0 +1,148 @@ +#ifndef _SRC_CLUCENE_CLUCENE_CONFIG_H +#define _SRC_CLUCENE_CLUCENE_CONFIG_H 1 + +/* src/shared/CLucene/clucene-config.h. +* Generated automatically at end of cmake. +*/ + +/* CMake will look for these headers: */ +#cmakedefine _CL_HAVE_STRING_H 1 +#cmakedefine _CL_HAVE_MEMORY_H 1 +#cmakedefine _CL_HAVE_UNISTD_H 1 +#cmakedefine _CL_HAVE_IO_H 1 +#cmakedefine _CL_HAVE_DIRECT_H 1 +#cmakedefine _CL_HAVE_DIRENT_H 1 +#cmakedefine _CL_HAVE_SYS_DIR_H +#cmakedefine _CL_HAVE_SYS_NDIR_H +#cmakedefine _CL_HAVE_ERRNO_H 1 +#cmakedefine _CL_HAVE_WCHAR_H 1 +#cmakedefine _CL_HAVE_WCTYPE_H +#cmakedefine _CL_HAVE_CTYPE_H 1 +#cmakedefine _CL_HAVE_WINDOWS_H 1 +#cmakedefine _CL_HAVE_WINDEF_H 1 +#cmakedefine _CL_HAVE_SYS_TYPES_H 1 +#cmakedefine _CL_HAVE_DLFCN_H 1 +#cmakedefine _CL_HAVE_EXT_HASH_MAP 1 +#cmakedefine _CL_HAVE_EXT_HASH_SET 1 +#cmakedefine _CL_HAVE_TR1_UNORDERED_MAP 1 +#cmakedefine _CL_HAVE_TR1_UNORDERED_SET 1 +#cmakedefine _CL_HAVE_HASH_MAP +#cmakedefine _CL_HAVE_HASH_SET +#cmakedefine _CL_HAVE_NDIR_H +#cmakedefine _CL_HAVE_SYS_STAT_H 1 +#cmakedefine _CL_HAVE_SYS_TIMEB_H 1 +#cmakedefine _CL_HAVE_SYS_TIME_H 1 +#cmakedefine _CL_HAVE_TCHAR_H 1 +#cmakedefine _CL_HAVE_SYS_MMAN_H 1 +#cmakedefine _CL_HAVE_WINERROR_H 1 +#cmakedefine _CL_HAVE_STDINT_H 1 + +// our needed types +${TYPE_INT8_T} +${TYPE_UINT8_T} +${TYPE_INT16_T} +${TYPE_UINT16_T} +${TYPE_INT32_T} +${TYPE_UINT32_T} +${TYPE_INT64_T} +${TYPE_UINT64_T} + +${TYPE_FLOAT_T} +${TYPE__CL_DWORD_T} +${TYPE_SIZE_T} + +/* tchar & _T definitions... */ +${TYPE_TCHAR} +${SYMBOL__T} + +/* CMake will determine these specifics. Things like bugs, etc */ + +/* if we can't support the map/set hashing */ +#cmakedefine LUCENE_DISABLE_HASHING 1 + +/* Define if you have POSIX threads libraries and header files. */ +#cmakedefine _CL_HAVE_PTHREAD 1 + +/* Define if you have Win32 threads libraries and header files. */ +#cmakedefine _CL_HAVE_WIN32_THREADS 1 + +/* Define if we have gcc atomic functions */ +#cmakedefine _CL_HAVE_GCC_ATOMIC_FUNCTIONS 1 + +/* Define what eval method is required for float_t to be defined (for GCC). */ +#cmakedefine _FLT_EVAL_METHOD ${_FLT_EVAL_METHOD} + +/* If we use hashmaps, which namespace do we use: */ +#define CL_NS_HASHING(func) ${CL_NS_HASHING_VALUE} +/* If we use hashmaps, which classes do we use: */ +#define _CL_HASH_MAP ${_CL_HASH_MAP} +#define _CL_HASH_SET ${_CL_HASH_SET} + +/* define if the compiler implements namespaces */ +#cmakedefine _CL_HAVE_NAMESPACES + +/* Defined if the snprintf overflow test fails */ +#cmakedefine _CL_HAVE_SNPRINTF_BUG + +/* Defined if the swprintf test fails */ +#cmakedefine _CL_HAVE_SNWPRINTF_BUG + +/* How to define a static const in a class */ +#define LUCENE_STATIC_CONSTANT(type, assignment) ${LUCENE_STATIC_CONSTANT_SYNTAX} + +/* Define to the necessary symbol if this constant uses a non-standard name on + your system. */ +//todo: not checked +#cmakedefine _CL_PTHREAD_CREATE_JOINABLE + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +//todo: not being checked for... +//#cmakedefine _CL_STAT_MACROS_BROKEN + +/* Define to 1 if you can safely include both and . */ +//not actually used for anything... +//#cmakedefine _CL_TIME_WITH_SYS_TIME 1 + +/* Define that we will be using -fvisibility=hidden, and + * make public classes visible using __attribute__ ((visibility("default"))) + */ +#cmakedefine _CL_HAVE_GCCVISIBILITYPATCH 1 + + +/* Versions, etc */ + +/* Name of package */ +#define _CL_PACKAGE "clucene-core" + +/* Version number of package */ +#define _CL_VERSION "@CLUCENE_VERSION@" + +/* So-Version number of package */ +#define _CL_SOVERSION "@CLUCENE_SOVERSION@" + +/* A comparable version number */ +#define _CL_INT_VERSION @CLUCENE_INT_VERSION@ + +/* Configured options (from command line) */ + +/* Forces into Ascii mode */ +#cmakedefine _ASCII + +/* Conditional Debugging */ +#cmakedefine _CL__CND_DEBUG + +/* debuging option */ +#cmakedefine _DEBUG + +/* Disable multithreading */ +#cmakedefine _CL_DISABLE_MULTITHREADING + + +#ifdef __BORLANDC__ //borland compiler + //todo: bcc incorrectly detects this... fix this in cmake + #undef LUCENE_STATIC_CONSTANT + #define LUCENE_STATIC_CONSTANT(type, assignment) enum { assignment } +#endif + + +#endif diff --git a/src/shared/CLucene/config/_gunichartables.h b/src/shared/CLucene/config/_gunichartables.h new file mode 100644 index 00000000000..182a870545c --- /dev/null +++ b/src/shared/CLucene/config/_gunichartables.h @@ -0,0 +1,11264 @@ +/* This file is automatically generated. DO NOT EDIT! + Instead, edit gen-unicode-tables.pl and re-run. */ + +#ifndef CHARTABLES_H +#define CHARTABLES_H + +#define G_UNICODE_DATA_VERSION "4.0" + +#define G_UNICODE_LAST_CHAR 0x10ffff + +#define G_UNICODE_MAX_TABLE_INDEX 10000 + +#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF + +#define G_UNICODE_LAST_PAGE_PART1 762 + +static const char type_data[][256] = { + { /* page 0, index 0 */ + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 1, index 1 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 2, index 2 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL + }, + { /* page 3, index 3 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 4, index 4 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 5, index 5 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 6, index 6 */ + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_LETTER + }, + { /* page 7, index 7 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 9, index 8 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 10, index 9 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 11, index 10 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 12, index 11 */ + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 13, index 12 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 14, index 13 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 15, index 14 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 16, index 15 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 17, index 16 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 18, index 17 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 19, index 18 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 20, index 19 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 22, index 20 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 23, index 21 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 24, index 22 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 25, index 23 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL + }, + { /* page 29, index 24 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 30, index 25 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 31, index 26 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED + }, + { /* page 32, index 27 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 33, index 28 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL + }, + { /* page 35, index 29 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 36, index 30 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER + }, + { /* page 37, index 31 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { /* page 38, index 32 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 39, index 33 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL + }, + { /* page 41, index 34 */ + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { /* page 43, index 35 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 46, index 36 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 47, index 37 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 48, index 38 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 49, index 39 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 50, index 40 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED + }, + { /* page 77, index 41 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { /* page 159, index 42 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 164, index 43 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 215, index 44 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 250, index 45 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 251, index 46 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { /* page 253, index 47 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 254, index 48 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT + }, + { /* page 255, index 49 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 256, index 50 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 257, index 51 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 259, index 52 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 260, index 53 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 264, index 54 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 464, index 55 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 465, index 56 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, + G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 467, index 57 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 468, index 58 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 469, index 59 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 470, index 60 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 471, index 61 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER + }, + { /* page 678, index 62 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 762, index 63 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 3584, index 64 */ + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 3585, index 65 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 4095, index 66 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 4351, index 67 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + } +}; + +/* U+0000 through U+2FAFF */ +static const gint16 type_table_part1[763] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 7 /* page 7 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 8 /* page 9 */, + 9 /* page 10 */, + 10 /* page 11 */, + 11 /* page 12 */, + 12 /* page 13 */, + 13 /* page 14 */, + 14 /* page 15 */, + 15 /* page 16 */, + 16 /* page 17 */, + 17 /* page 18 */, + 18 /* page 19 */, + 19 /* page 20 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 20 /* page 22 */, + 21 /* page 23 */, + 22 /* page 24 */, + 23 /* page 25 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 24 /* page 29 */, + 25 /* page 30 */, + 26 /* page 31 */, + 27 /* page 32 */, + 28 /* page 33 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 29 /* page 35 */, + 30 /* page 36 */, + 31 /* page 37 */, + 32 /* page 38 */, + 33 /* page 39 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 34 /* page 41 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 35 /* page 43 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 36 /* page 46 */, + 37 /* page 47 */, + 38 /* page 48 */, + 39 /* page 49 */, + 40 /* page 50 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 41 /* page 77 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 42 /* page 159 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 43 /* page 164 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 44 /* page 215 */, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 45 /* page 250 */, + 46 /* page 251 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 47 /* page 253 */, + 48 /* page 254 */, + 49 /* page 255 */, + 50 /* page 256 */, + 51 /* page 257 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 52 /* page 259 */, + 53 /* page 260 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 54 /* page 264 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 55 /* page 464 */, + 56 /* page 465 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 57 /* page 467 */, + 58 /* page 468 */, + 59 /* page 469 */, + 60 /* page 470 */, + 61 /* page 471 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 62 /* page 678 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 63 /* page 762 */ +}; + +/* U+E0000 through U+10FFFF */ +static const gint16 type_table_part2[768] = { + 64 /* page 3584 */, + 65 /* page 3585 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 66 /* page 4095 */, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 67 /* page 4351 */ +}; + +static const gunichar attr_data[][256] = { + { /* page 0, index 0 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, + 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, + 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178 + }, + { /* page 1, index 1 */ + 0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109, + 0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110, + 0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b, + 0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122, + 0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d, + 0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135, + 0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e, + 0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145, + 0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f, + 0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156, + 0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161, + 0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168, + 0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173, + 0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c, + 0x017b, 0x017e, 0x017d, 0x0053, 0x0000, 0x0253, 0x0183, 0x0182, 0x0185, + 0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000, + 0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269, + 0x0268, 0x0199, 0x0198, 0x0000, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275, + 0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7, + 0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a, + 0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000, + 0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca, + 0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6, + 0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df, + 0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6, + 0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee, + 0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf, + 0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe + }, + { /* page 2, index 2 */ + 0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209, + 0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210, + 0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b, + 0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222, + 0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d, + 0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f, + 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000, + 0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x0000, 0x019d, 0x0000, 0x0000, + 0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x01ae, 0x0000, 0x01b1, 0x01b2, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 3, index 3 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac, + 0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce, + 0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 0x0391, + 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, + 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c, + 0x038e, 0x038f, 0x0000, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6, + 0x03a0, 0x0000, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df, + 0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6, + 0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a, + 0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2, + 0x03fb, 0x03fa, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 4, index 4 */ + 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, + 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, + 0x044d, 0x044e, 0x044f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, + 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0400, + 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, + 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463, + 0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a, + 0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475, + 0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c, + 0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e, + 0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499, + 0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0, + 0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab, + 0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2, + 0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd, + 0x04bc, 0x04bf, 0x04be, 0x0000, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6, + 0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd, + 0x0000, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6, + 0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1, + 0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8, + 0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3, + 0x04f2, 0x04f5, 0x04f4, 0x0000, 0x0000, 0x04f9, 0x04f8, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 5, index 5 */ + 0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509, + 0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, + 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, + 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, + 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, + 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0531, 0x0532, + 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053a, 0x053b, + 0x053c, 0x053d, 0x053e, 0x053f, 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, + 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, + 0x054e, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, + 0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 6, index 6 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 9, index 7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 10, index 8 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 11, index 9 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 12, index 10 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 13, index 11 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 14, index 12 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 15, index 13 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 16, index 14 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 19, index 15 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 23, index 16 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 24, index 17 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 25, index 18 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 30, index 19 */ + 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09, + 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10, + 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b, + 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22, + 0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, + 0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, + 0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, + 0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, + 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51, + 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58, + 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63, + 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, + 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, + 0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, + 0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, + 0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, + 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf, + 0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x0000, 0x0000, + 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9, + 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0, + 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb, + 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, + 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, + 0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, + 0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, + 0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, + 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1, + 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 31, index 20 */ + 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00, + 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19, + 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12, + 0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, + 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, + 0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, + 0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, + 0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000, + 0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c, + 0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57, + 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60, + 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb, + 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, + 0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1, + 0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f, + 0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b, + 0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3, + 0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb, + 0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327, + 0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375, + 0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7, + 0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df, + 0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, + 0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4, + 0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75, + 0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140, + 0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178, + 0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, + 0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409, + 0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, + 0x1000415, 0x0000, 0x0000, 0x0000 + }, + { /* page 33, index 21 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 251, index 22 */ + 0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036, + 0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065, + 0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }, + { /* page 255, index 23 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff41, 0xff42, 0xff43, + 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, + 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, + 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, + 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, + 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 260, index 24 */ + 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, + 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, + 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, + 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, + 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, + 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, + 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, + 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, + 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, + 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 471, index 25 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, + 0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009 + } +}; + +/* U+0000 through U+2FAFF */ +static const gint16 attr_table_part1[763] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 7 /* page 9 */, + 8 /* page 10 */, + 9 /* page 11 */, + 10 /* page 12 */, + 11 /* page 13 */, + 12 /* page 14 */, + 13 /* page 15 */, + 14 /* page 16 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 15 /* page 19 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 16 /* page 23 */, + 17 /* page 24 */, + 18 /* page 25 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 19 /* page 30 */, + 20 /* page 31 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 21 /* page 33 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 22 /* page 251 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 23 /* page 255 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 24 /* page 260 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 25 /* page 471 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX +}; + +/* U+E0000 through U+10FFFF */ +static const gint16 attr_table_part2[768] = { + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX +}; + +static const gunichar title_table[][3] = { + { 0x01c5, 0x01c4, 0x01c6 }, + { 0x01c8, 0x01c7, 0x01c9 }, + { 0x01cb, 0x01ca, 0x01cc }, + { 0x01f2, 0x01f1, 0x01f3 }, + { 0x1f88, 0x0000, 0x1f80 }, + { 0x1f89, 0x0000, 0x1f81 }, + { 0x1f8a, 0x0000, 0x1f82 }, + { 0x1f8b, 0x0000, 0x1f83 }, + { 0x1f8c, 0x0000, 0x1f84 }, + { 0x1f8d, 0x0000, 0x1f85 }, + { 0x1f8e, 0x0000, 0x1f86 }, + { 0x1f8f, 0x0000, 0x1f87 }, + { 0x1f98, 0x0000, 0x1f90 }, + { 0x1f99, 0x0000, 0x1f91 }, + { 0x1f9a, 0x0000, 0x1f92 }, + { 0x1f9b, 0x0000, 0x1f93 }, + { 0x1f9c, 0x0000, 0x1f94 }, + { 0x1f9d, 0x0000, 0x1f95 }, + { 0x1f9e, 0x0000, 0x1f96 }, + { 0x1f9f, 0x0000, 0x1f97 }, + { 0x1fa8, 0x0000, 0x1fa0 }, + { 0x1fa9, 0x0000, 0x1fa1 }, + { 0x1faa, 0x0000, 0x1fa2 }, + { 0x1fab, 0x0000, 0x1fa3 }, + { 0x1fac, 0x0000, 0x1fa4 }, + { 0x1fad, 0x0000, 0x1fa5 }, + { 0x1fae, 0x0000, 0x1fa6 }, + { 0x1faf, 0x0000, 0x1fa7 }, + { 0x1fbc, 0x0000, 0x1fb3 }, + { 0x1fcc, 0x0000, 0x1fc3 }, + { 0x1ffc, 0x0000, 0x1ff3 } +}; + + +/* Table of special cases for case conversion; each record contains + * First, the best single character mapping to lowercase if Lu, + * and to uppercase if Ll, followed by the output mapping for the two cases + * other than the case of the codepoint, in the order [Ll],[Lu],[Lt], + * encoded in UTF-8, separated and terminated by a null character. + */ +static const gchar special_case_table[] = { + "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */ + "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */ + "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */ + "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */ + "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */ + "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */ + "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */ + "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */ + "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */ + "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */ + "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */ + "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */ + "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */ + "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */ + "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */ + "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */ + "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */ + "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */ + "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */ + "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */ + "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */ + "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */ + "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */ + "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */ + "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */ + "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */ + "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */ + "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */ + "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */ + "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */ + "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */ + "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */ + "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */ + "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */ + "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */ + "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */ + "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */ + "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */ + "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */ + "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */ + "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */ + "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */ + "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */ + "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */ + "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */ + "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */ + "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */ + "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */ + "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */ + "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */ + "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */ + "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */ + "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */ + "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */ + "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */ + "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */ + "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */ + "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */ + "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */ + "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */ + "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */ + "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */ + "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */ + "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */ + "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */ + "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */ + "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */ + "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */ + "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */ + "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */ + "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */ + "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */ + "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */ + "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */ + "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */ + "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */ + "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */ + "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */ + "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */ + "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */ + "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */ + "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */ + "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */ + "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */ + "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */ + "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */ + "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */ + "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */ + "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */ + "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */ + "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */ + "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */ + "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */ + "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */ + "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */ + "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */ + "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */ +}; + + +/* Table of casefolding cases that can't be derived by lowercasing + */ +static const struct { + guint16 ch; + gchar data[7]; +} casefold_table[] = { + { 0x00b5, "\xce\xbc" }, + { 0x00df, "\x73\x73" }, + { 0x0130, "\x69\xcc\x87" }, + { 0x0149, "\xca\xbc\x6e" }, + { 0x017f, "\x73" }, + { 0x01f0, "\x6a\xcc\x8c" }, + { 0x0345, "\xce\xb9" }, + { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x03c2, "\xcf\x83" }, + { 0x03d0, "\xce\xb2" }, + { 0x03d1, "\xce\xb8" }, + { 0x03d5, "\xcf\x86" }, + { 0x03d6, "\xcf\x80" }, + { 0x03f0, "\xce\xba" }, + { 0x03f1, "\xcf\x81" }, + { 0x03f5, "\xce\xb5" }, + { 0x0587, "\xd5\xa5\xd6\x82" }, + { 0x1e96, "\x68\xcc\xb1" }, + { 0x1e97, "\x74\xcc\x88" }, + { 0x1e98, "\x77\xcc\x8a" }, + { 0x1e99, "\x79\xcc\x8a" }, + { 0x1e9a, "\x61\xca\xbe" }, + { 0x1e9b, "\xe1\xb9\xa1" }, + { 0x1f50, "\xcf\x85\xcc\x93" }, + { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" }, + { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" }, + { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" }, + { 0x1f80, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f81, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f82, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f83, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f84, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f85, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f86, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f87, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f88, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f89, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f8a, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f8b, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f8c, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f8d, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f8e, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f8f, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f90, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f91, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f92, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f93, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f94, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f95, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f96, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f97, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1f98, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f99, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1faa, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fab, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fac, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fad, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fae, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1faf, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" }, + { 0x1fb3, "\xce\xb1\xce\xb9" }, + { 0x1fb4, "\xce\xac\xce\xb9" }, + { 0x1fb6, "\xce\xb1\xcd\x82" }, + { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" }, + { 0x1fbc, "\xce\xb1\xce\xb9" }, + { 0x1fbe, "\xce\xb9" }, + { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" }, + { 0x1fc3, "\xce\xb7\xce\xb9" }, + { 0x1fc4, "\xce\xae\xce\xb9" }, + { 0x1fc6, "\xce\xb7\xcd\x82" }, + { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" }, + { 0x1fcc, "\xce\xb7\xce\xb9" }, + { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" }, + { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x1fd6, "\xce\xb9\xcd\x82" }, + { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" }, + { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" }, + { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x1fe4, "\xcf\x81\xcc\x93" }, + { 0x1fe6, "\xcf\x85\xcd\x82" }, + { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" }, + { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" }, + { 0x1ff3, "\xcf\x89\xce\xb9" }, + { 0x1ff4, "\xcf\x8e\xce\xb9" }, + { 0x1ff6, "\xcf\x89\xcd\x82" }, + { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" }, + { 0x1ffc, "\xcf\x89\xce\xb9" }, + { 0x2160, "\xe2\x85\xb0" }, + { 0x2161, "\xe2\x85\xb1" }, + { 0x2162, "\xe2\x85\xb2" }, + { 0x2163, "\xe2\x85\xb3" }, + { 0x2164, "\xe2\x85\xb4" }, + { 0x2165, "\xe2\x85\xb5" }, + { 0x2166, "\xe2\x85\xb6" }, + { 0x2167, "\xe2\x85\xb7" }, + { 0x2168, "\xe2\x85\xb8" }, + { 0x2169, "\xe2\x85\xb9" }, + { 0x216a, "\xe2\x85\xba" }, + { 0x216b, "\xe2\x85\xbb" }, + { 0x216c, "\xe2\x85\xbc" }, + { 0x216d, "\xe2\x85\xbd" }, + { 0x216e, "\xe2\x85\xbe" }, + { 0x216f, "\xe2\x85\xbf" }, + { 0x24b6, "\xe2\x93\x90" }, + { 0x24b7, "\xe2\x93\x91" }, + { 0x24b8, "\xe2\x93\x92" }, + { 0x24b9, "\xe2\x93\x93" }, + { 0x24ba, "\xe2\x93\x94" }, + { 0x24bb, "\xe2\x93\x95" }, + { 0x24bc, "\xe2\x93\x96" }, + { 0x24bd, "\xe2\x93\x97" }, + { 0x24be, "\xe2\x93\x98" }, + { 0x24bf, "\xe2\x93\x99" }, + { 0x24c0, "\xe2\x93\x9a" }, + { 0x24c1, "\xe2\x93\x9b" }, + { 0x24c2, "\xe2\x93\x9c" }, + { 0x24c3, "\xe2\x93\x9d" }, + { 0x24c4, "\xe2\x93\x9e" }, + { 0x24c5, "\xe2\x93\x9f" }, + { 0x24c6, "\xe2\x93\xa0" }, + { 0x24c7, "\xe2\x93\xa1" }, + { 0x24c8, "\xe2\x93\xa2" }, + { 0x24c9, "\xe2\x93\xa3" }, + { 0x24ca, "\xe2\x93\xa4" }, + { 0x24cb, "\xe2\x93\xa5" }, + { 0x24cc, "\xe2\x93\xa6" }, + { 0x24cd, "\xe2\x93\xa7" }, + { 0x24ce, "\xe2\x93\xa8" }, + { 0x24cf, "\xe2\x93\xa9" }, + { 0xfb00, "\x66\x66" }, + { 0xfb01, "\x66\x69" }, + { 0xfb02, "\x66\x6c" }, + { 0xfb03, "\x66\x66\x69" }, + { 0xfb04, "\x66\x66\x6c" }, + { 0xfb05, "\x73\x74" }, + { 0xfb06, "\x73\x74" }, + { 0xfb13, "\xd5\xb4\xd5\xb6" }, + { 0xfb14, "\xd5\xb4\xd5\xa5" }, + { 0xfb15, "\xd5\xb4\xd5\xab" }, + { 0xfb16, "\xd5\xbe\xd5\xb6" }, + { 0xfb17, "\xd5\xb4\xd5\xad" }, +}; + +static const struct { + gunichar ch; + gunichar mirrored_ch; +} bidi_mirroring_table[] = +{ + { 0x0028, 0x0029 }, + { 0x0029, 0x0028 }, + { 0x003c, 0x003e }, + { 0x003e, 0x003c }, + { 0x005b, 0x005d }, + { 0x005d, 0x005b }, + { 0x007b, 0x007d }, + { 0x007d, 0x007b }, + { 0x00ab, 0x00bb }, + { 0x00bb, 0x00ab }, + { 0x2039, 0x203a }, + { 0x203a, 0x2039 }, + { 0x2045, 0x2046 }, + { 0x2046, 0x2045 }, + { 0x207d, 0x207e }, + { 0x207e, 0x207d }, + { 0x208d, 0x208e }, + { 0x208e, 0x208d }, + { 0x2208, 0x220b }, + { 0x2209, 0x220c }, + { 0x220a, 0x220d }, + { 0x220b, 0x2208 }, + { 0x220c, 0x2209 }, + { 0x220d, 0x220a }, + { 0x2215, 0x29f5 }, + { 0x223c, 0x223d }, + { 0x223d, 0x223c }, + { 0x2243, 0x22cd }, + { 0x2252, 0x2253 }, + { 0x2253, 0x2252 }, + { 0x2254, 0x2255 }, + { 0x2255, 0x2254 }, + { 0x2264, 0x2265 }, + { 0x2265, 0x2264 }, + { 0x2266, 0x2267 }, + { 0x2267, 0x2266 }, + { 0x2268, 0x2269 }, + { 0x2269, 0x2268 }, + { 0x226a, 0x226b }, + { 0x226b, 0x226a }, + { 0x226e, 0x226f }, + { 0x226f, 0x226e }, + { 0x2270, 0x2271 }, + { 0x2271, 0x2270 }, + { 0x2272, 0x2273 }, + { 0x2273, 0x2272 }, + { 0x2274, 0x2275 }, + { 0x2275, 0x2274 }, + { 0x2276, 0x2277 }, + { 0x2277, 0x2276 }, + { 0x2278, 0x2279 }, + { 0x2279, 0x2278 }, + { 0x227a, 0x227b }, + { 0x227b, 0x227a }, + { 0x227c, 0x227d }, + { 0x227d, 0x227c }, + { 0x227e, 0x227f }, + { 0x227f, 0x227e }, + { 0x2280, 0x2281 }, + { 0x2281, 0x2280 }, + { 0x2282, 0x2283 }, + { 0x2283, 0x2282 }, + { 0x2284, 0x2285 }, + { 0x2285, 0x2284 }, + { 0x2286, 0x2287 }, + { 0x2287, 0x2286 }, + { 0x2288, 0x2289 }, + { 0x2289, 0x2288 }, + { 0x228a, 0x228b }, + { 0x228b, 0x228a }, + { 0x228f, 0x2290 }, + { 0x2290, 0x228f }, + { 0x2291, 0x2292 }, + { 0x2292, 0x2291 }, + { 0x2298, 0x29b8 }, + { 0x22a2, 0x22a3 }, + { 0x22a3, 0x22a2 }, + { 0x22a6, 0x2ade }, + { 0x22a8, 0x2ae4 }, + { 0x22a9, 0x2ae3 }, + { 0x22ab, 0x2ae5 }, + { 0x22b0, 0x22b1 }, + { 0x22b1, 0x22b0 }, + { 0x22b2, 0x22b3 }, + { 0x22b3, 0x22b2 }, + { 0x22b4, 0x22b5 }, + { 0x22b5, 0x22b4 }, + { 0x22b6, 0x22b7 }, + { 0x22b7, 0x22b6 }, + { 0x22c9, 0x22ca }, + { 0x22ca, 0x22c9 }, + { 0x22cb, 0x22cc }, + { 0x22cc, 0x22cb }, + { 0x22cd, 0x2243 }, + { 0x22d0, 0x22d1 }, + { 0x22d1, 0x22d0 }, + { 0x22d6, 0x22d7 }, + { 0x22d7, 0x22d6 }, + { 0x22d8, 0x22d9 }, + { 0x22d9, 0x22d8 }, + { 0x22da, 0x22db }, + { 0x22db, 0x22da }, + { 0x22dc, 0x22dd }, + { 0x22dd, 0x22dc }, + { 0x22de, 0x22df }, + { 0x22df, 0x22de }, + { 0x22e0, 0x22e1 }, + { 0x22e1, 0x22e0 }, + { 0x22e2, 0x22e3 }, + { 0x22e3, 0x22e2 }, + { 0x22e4, 0x22e5 }, + { 0x22e5, 0x22e4 }, + { 0x22e6, 0x22e7 }, + { 0x22e7, 0x22e6 }, + { 0x22e8, 0x22e9 }, + { 0x22e9, 0x22e8 }, + { 0x22ea, 0x22eb }, + { 0x22eb, 0x22ea }, + { 0x22ec, 0x22ed }, + { 0x22ed, 0x22ec }, + { 0x22f0, 0x22f1 }, + { 0x22f1, 0x22f0 }, + { 0x22f2, 0x22fa }, + { 0x22f3, 0x22fb }, + { 0x22f4, 0x22fc }, + { 0x22f6, 0x22fd }, + { 0x22f7, 0x22fe }, + { 0x22fa, 0x22f2 }, + { 0x22fb, 0x22f3 }, + { 0x22fc, 0x22f4 }, + { 0x22fd, 0x22f6 }, + { 0x22fe, 0x22f7 }, + { 0x2308, 0x2309 }, + { 0x2309, 0x2308 }, + { 0x230a, 0x230b }, + { 0x230b, 0x230a }, + { 0x2329, 0x232a }, + { 0x232a, 0x2329 }, + { 0x2768, 0x2769 }, + { 0x2769, 0x2768 }, + { 0x276a, 0x276b }, + { 0x276b, 0x276a }, + { 0x276c, 0x276d }, + { 0x276d, 0x276c }, + { 0x276e, 0x276f }, + { 0x276f, 0x276e }, + { 0x2770, 0x2771 }, + { 0x2771, 0x2770 }, + { 0x2772, 0x2773 }, + { 0x2773, 0x2772 }, + { 0x2774, 0x2775 }, + { 0x2775, 0x2774 }, + { 0x27d5, 0x27d6 }, + { 0x27d6, 0x27d5 }, + { 0x27dd, 0x27de }, + { 0x27de, 0x27dd }, + { 0x27e2, 0x27e3 }, + { 0x27e3, 0x27e2 }, + { 0x27e4, 0x27e5 }, + { 0x27e5, 0x27e4 }, + { 0x27e6, 0x27e7 }, + { 0x27e7, 0x27e6 }, + { 0x27e8, 0x27e9 }, + { 0x27e9, 0x27e8 }, + { 0x27ea, 0x27eb }, + { 0x27eb, 0x27ea }, + { 0x2983, 0x2984 }, + { 0x2984, 0x2983 }, + { 0x2985, 0x2986 }, + { 0x2986, 0x2985 }, + { 0x2987, 0x2988 }, + { 0x2988, 0x2987 }, + { 0x2989, 0x298a }, + { 0x298a, 0x2989 }, + { 0x298b, 0x298c }, + { 0x298c, 0x298b }, + { 0x298d, 0x2990 }, + { 0x298e, 0x298f }, + { 0x298f, 0x298e }, + { 0x2990, 0x298d }, + { 0x2991, 0x2992 }, + { 0x2992, 0x2991 }, + { 0x2993, 0x2994 }, + { 0x2994, 0x2993 }, + { 0x2995, 0x2996 }, + { 0x2996, 0x2995 }, + { 0x2997, 0x2998 }, + { 0x2998, 0x2997 }, + { 0x29b8, 0x2298 }, + { 0x29c0, 0x29c1 }, + { 0x29c1, 0x29c0 }, + { 0x29c4, 0x29c5 }, + { 0x29c5, 0x29c4 }, + { 0x29cf, 0x29d0 }, + { 0x29d0, 0x29cf }, + { 0x29d1, 0x29d2 }, + { 0x29d2, 0x29d1 }, + { 0x29d4, 0x29d5 }, + { 0x29d5, 0x29d4 }, + { 0x29d8, 0x29d9 }, + { 0x29d9, 0x29d8 }, + { 0x29da, 0x29db }, + { 0x29db, 0x29da }, + { 0x29f5, 0x2215 }, + { 0x29f8, 0x29f9 }, + { 0x29f9, 0x29f8 }, + { 0x29fc, 0x29fd }, + { 0x29fd, 0x29fc }, + { 0x2a2b, 0x2a2c }, + { 0x2a2c, 0x2a2b }, + { 0x2a2d, 0x2a2c }, + { 0x2a2e, 0x2a2d }, + { 0x2a34, 0x2a35 }, + { 0x2a35, 0x2a34 }, + { 0x2a3c, 0x2a3d }, + { 0x2a3d, 0x2a3c }, + { 0x2a64, 0x2a65 }, + { 0x2a65, 0x2a64 }, + { 0x2a79, 0x2a7a }, + { 0x2a7a, 0x2a79 }, + { 0x2a7d, 0x2a7e }, + { 0x2a7e, 0x2a7d }, + { 0x2a7f, 0x2a80 }, + { 0x2a80, 0x2a7f }, + { 0x2a81, 0x2a82 }, + { 0x2a82, 0x2a81 }, + { 0x2a83, 0x2a84 }, + { 0x2a84, 0x2a83 }, + { 0x2a8b, 0x2a8c }, + { 0x2a8c, 0x2a8b }, + { 0x2a91, 0x2a92 }, + { 0x2a92, 0x2a91 }, + { 0x2a93, 0x2a94 }, + { 0x2a94, 0x2a93 }, + { 0x2a95, 0x2a96 }, + { 0x2a96, 0x2a95 }, + { 0x2a97, 0x2a98 }, + { 0x2a98, 0x2a97 }, + { 0x2a99, 0x2a9a }, + { 0x2a9a, 0x2a99 }, + { 0x2a9b, 0x2a9c }, + { 0x2a9c, 0x2a9b }, + { 0x2aa1, 0x2aa2 }, + { 0x2aa2, 0x2aa1 }, + { 0x2aa6, 0x2aa7 }, + { 0x2aa7, 0x2aa6 }, + { 0x2aa8, 0x2aa9 }, + { 0x2aa9, 0x2aa8 }, + { 0x2aaa, 0x2aab }, + { 0x2aab, 0x2aaa }, + { 0x2aac, 0x2aad }, + { 0x2aad, 0x2aac }, + { 0x2aaf, 0x2ab0 }, + { 0x2ab0, 0x2aaf }, + { 0x2ab3, 0x2ab4 }, + { 0x2ab4, 0x2ab3 }, + { 0x2abb, 0x2abc }, + { 0x2abc, 0x2abb }, + { 0x2abd, 0x2abe }, + { 0x2abe, 0x2abd }, + { 0x2abf, 0x2ac0 }, + { 0x2ac0, 0x2abf }, + { 0x2ac1, 0x2ac2 }, + { 0x2ac2, 0x2ac1 }, + { 0x2ac3, 0x2ac4 }, + { 0x2ac4, 0x2ac3 }, + { 0x2ac5, 0x2ac6 }, + { 0x2ac6, 0x2ac5 }, + { 0x2acd, 0x2ace }, + { 0x2ace, 0x2acd }, + { 0x2acf, 0x2ad0 }, + { 0x2ad0, 0x2acf }, + { 0x2ad1, 0x2ad2 }, + { 0x2ad2, 0x2ad1 }, + { 0x2ad3, 0x2ad4 }, + { 0x2ad4, 0x2ad3 }, + { 0x2ad5, 0x2ad6 }, + { 0x2ad6, 0x2ad5 }, + { 0x2ade, 0x22a6 }, + { 0x2ae3, 0x22a9 }, + { 0x2ae4, 0x22a8 }, + { 0x2ae5, 0x22ab }, + { 0x2aec, 0x2aed }, + { 0x2aed, 0x2aec }, + { 0x2af7, 0x2af8 }, + { 0x2af8, 0x2af7 }, + { 0x2af9, 0x2afa }, + { 0x2afa, 0x2af9 }, + { 0x3008, 0x3009 }, + { 0x3009, 0x3008 }, + { 0x300a, 0x300b }, + { 0x300b, 0x300a }, + { 0x300c, 0x300d }, + { 0x300d, 0x300c }, + { 0x300e, 0x300f }, + { 0x300f, 0x300e }, + { 0x3010, 0x3011 }, + { 0x3011, 0x3010 }, + { 0x3014, 0x3015 }, + { 0x3015, 0x3014 }, + { 0x3016, 0x3017 }, + { 0x3017, 0x3016 }, + { 0x3018, 0x3019 }, + { 0x3019, 0x3018 }, + { 0x301a, 0x301b }, + { 0x301b, 0x301a }, + { 0xff08, 0xff09 }, + { 0xff09, 0xff08 }, + { 0xff1c, 0xff1e }, + { 0xff1e, 0xff1c }, + { 0xff3b, 0xff3d }, + { 0xff3d, 0xff3b }, + { 0xff5b, 0xff5d }, + { 0xff5d, 0xff5b }, + { 0xff5f, 0xff60 }, + { 0xff60, 0xff5f }, + { 0xff62, 0xff63 }, + { 0xff63, 0xff62 } +}; + +#endif /* CHARTABLES_H */ diff --git a/src/shared/CLucene/config/_threads.h b/src/shared/CLucene/config/_threads.h new file mode 100644 index 00000000000..b86dd242a94 --- /dev/null +++ b/src/shared/CLucene/config/_threads.h @@ -0,0 +1,125 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _config_threads_h +#define _config_threads_h + +#ifndef _CL_DISABLE_MULTITHREADING + #if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX) + //do nothing + #elif defined(_CL_HAVE_WIN32_THREADS) + //we have not explicity included windows.h and windows.h has + //not been included (check _WINBASE_), then we must define + //our own definitions to the thread locking functions: + #ifndef _WINBASE_ + extern "C"{ + struct CRITICAL_SECTION + { + struct critical_section_debug * DebugInfo; + long LockCount; + long RecursionCount; + void * OwningThread; + void * LockSemaphore; + _cl_dword_t SpinCount; + }; + + __declspec(dllimport) void __stdcall InitializeCriticalSection(CRITICAL_SECTION *); + __declspec(dllimport) void __stdcall EnterCriticalSection(CRITICAL_SECTION *); + __declspec(dllimport) void __stdcall LeaveCriticalSection(CRITICAL_SECTION *); + __declspec(dllimport) void __stdcall DeleteCriticalSection(CRITICAL_SECTION *); + __declspec(dllimport) void __stdcall ExitThread(_cl_dword_t); + + __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); + +#ifdef _M_X64 + __declspec(dllimport) long long __stdcall _InterlockedIncrement64(__inout long long volatile*); + __declspec(dllimport) long long __stdcall _InterlockedDecrement64(__inout long long volatile*); +#else + __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile*); + __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile*); +#endif + typedef struct _SECURITY_ATTRIBUTES + { + _cl_dword_t nLength; + void* lpSecurityDescriptor; + bool bInheritHandle; + } SECURITY_ATTRIBUTES; + __declspec(dllimport) _cl_dword_t __stdcall WaitForSingleObject( void* hHandle, _cl_dword_t dwMilliseconds ); + __declspec(dllimport) void* __stdcall CreateEventA( SECURITY_ATTRIBUTES* lpEventAttributes, + bool bManualReset, bool bInitialState, char* lpName ); + __declspec(dllimport) bool __stdcall SetEvent(void* hEvent); + __declspec(dllimport) bool __stdcall CloseHandle(void* hObject); + void* _beginthread( void( __stdcall *start_address )( void * ), unsigned stack_size, void *arglist ); + } + #endif //_WINBASE_ + #elif defined(_CL_HAVE_PTHREAD) + #include + #endif +#endif + +CL_NS_DEF(util) + +#ifndef _CL_DISABLE_MULTITHREADING + +#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX) + +#elif defined(_CL_HAVE_WIN32_THREADS) + class CLuceneThreadIdCompare + { + public: + + enum + { // parameters for hash table + bucket_size = 4, // 0 < bucket_size + min_buckets = 8 + }; // min_buckets = 2 ^^ N, 0 < N + + bool operator()( uint64_t t1, uint64_t t2 ) const{ + return t1 < t2; + } + }; + + +#elif defined(_CL_HAVE_PTHREAD) + + class CLuceneThreadIdCompare + { + public: + enum + { // parameters for hash table + bucket_size = 4, // 0 < bucket_size + min_buckets = 8 + }; // min_buckets = 2 ^^ N, 0 < N + + bool operator()( pthread_t t1, pthread_t t2 ) const{ + //pthread_equal should be used, but it returns only non-zero if equal, so we can't use it for order compare + return t1 < t2; + } + }; + +#endif //thread impl choice + + +#else //!_CL_DISABLE_MULTITHREADING + class CLuceneThreadIdCompare + { + public: + enum + { // parameters for hash table + bucket_size = 4, // 0 < bucket_size + min_buckets = 8 + }; // min_buckets = 2 ^^ N, 0 < N + + bool operator()( char t1, char t2 ) const{ + return t1 < t2; + } + }; +#endif //!_CL_DISABLE_MULTITHREADING + +CL_NS_END + + +#endif //_config_threads_h diff --git a/src/shared/CLucene/config/gunichartables.cpp b/src/shared/CLucene/config/gunichartables.cpp new file mode 100644 index 00000000000..a0cfb7855d4 --- /dev/null +++ b/src/shared/CLucene/config/gunichartables.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + ************************************************ + * Also licensed with permission from Tom Tromey + * and Owen Taylor under the Apache license. + * Original location: + * http://cvs.gnome.org/viewcvs/glib/glib/guniprop.c?view=log + ************************************************ + * + * Copyright 2003-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "CLucene/_SharedHeader.h" + +typedef unsigned long gunichar; +typedef unsigned short guint16; +typedef short gint16; +typedef char gchar; +typedef unsigned char guchar; + +/* These are the possible character classifications. + * See http://www.unicode.org/Public/UNIDATA/UnicodeData.txt + or http://www.unicode.org/Public/UNIDATA/UCD.html. + + todo: i think there is a new version of the unicode, which we should use. + data is licensed like this: http://www.unicode.org/copyright.html... not sure but looks apache compatible + */ +typedef enum +{ + G_UNICODE_CONTROL, + G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, + G_UNICODE_PRIVATE_USE, + G_UNICODE_SURROGATE, + G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, + G_UNICODE_TITLECASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_COMBINING_MARK, + G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_NUMBER, + G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LINE_SEPARATOR, + G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR +} GUnicodeType; + + +#include "_gunichartables.h" + +#define ATTR_TABLE(Page) (((Page) <= G_UNICODE_LAST_PAGE_PART1) \ + ? attr_table_part1[Page] \ + : attr_table_part2[(Page) - 0xe00]) + +#define ATTTABLE(Page, Char) \ + ((ATTR_TABLE(Page) == G_UNICODE_MAX_TABLE_INDEX) ? 0 : (attr_data[ATTR_TABLE(Page)][Char])) + + +#define TTYPE_PART1(Page, Char) \ + ((type_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (type_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (type_data[type_table_part1[Page]][Char])) + +#define TTYPE_PART2(Page, Char) \ + ((type_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (type_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (type_data[type_table_part2[Page]][Char])) + +#define TYPE(Char) \ + (((Char) <= G_UNICODE_LAST_CHAR_PART1) \ + ? TTYPE_PART1 ((Char) >> 8, (Char) & 0xff) \ + : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \ + ? TTYPE_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \ + : G_UNICODE_UNASSIGNED)) + +/* Count the number of elements in an array. The array must be defined + * as such; using this with a dynamically allocated array will give + * incorrect results. + */ +#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + + + + +#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) +#ifdef _LUCENE_PRAGMA_WARNINGS + #pragma message ("===== Note: using internal character function for compatibility =====") +#else + #warning "===== Note: using internal character function for compatibility =====" +#endif + +bool cl_isletter(gunichar c) +{ + int t = TYPE (c); + switch(t) + { + case G_UNICODE_LOWERCASE_LETTER: return true; + case G_UNICODE_TITLECASE_LETTER: return true; + case G_UNICODE_UPPERCASE_LETTER: return true; + case G_UNICODE_MODIFIER_LETTER: return true; + case G_UNICODE_OTHER_LETTER: return true; + default: return false; + } +} + +bool cl_isalnum(gunichar c) +{ + int t = TYPE (c); + switch(t) + { + case G_UNICODE_LOWERCASE_LETTER: return true; + case G_UNICODE_TITLECASE_LETTER: return true; + case G_UNICODE_UPPERCASE_LETTER: return true; + case G_UNICODE_MODIFIER_LETTER: return true; + case G_UNICODE_OTHER_LETTER: return true; + case G_UNICODE_DECIMAL_NUMBER: return true; + case G_UNICODE_LETTER_NUMBER: return true; + case G_UNICODE_OTHER_NUMBER: return true; + default: return false; + } +} + +bool cl_isdigit(gunichar c) +{ + int t = TYPE (c); + switch(t) + { + case G_UNICODE_DECIMAL_NUMBER: return true; + case G_UNICODE_LETTER_NUMBER: return true; + case G_UNICODE_OTHER_NUMBER: return true; + default: return false; + } +} + +/** + * cl_isspace: + * @c: a Unicode character + * + * Determines whether a character is a space, tab, or line separator + * (newline, carriage return, etc.). Given some UTF-8 text, obtain a + * character value with lucene_utf8towc(). + * + * (Note: don't use this to do word breaking; you have to use + * Pango or equivalent to get word breaking right, the algorithm + * is fairly complex.) + * + * Return value: %TRUE if @c is a punctuation character + **/ +bool cl_isspace (gunichar c) +{ + switch (c) + { + /* special-case these since Unicode thinks they are not spaces */ + case '\t': + case '\n': + case '\r': + case '\f': + return true; + + default: + { + int t = TYPE ((gunichar)c); + return (t == G_UNICODE_SPACE_SEPARATOR || t == G_UNICODE_LINE_SEPARATOR + || t == G_UNICODE_PARAGRAPH_SEPARATOR); + } + } +} + + + +/** + * cl_tolower: + * @c: a Unicode character. + * + * Converts a character to lower case. + * + * Return value: the result of converting @c to lower case. + * If @c is not an upperlower or titlecase character, + * or has no lowercase equivalent @c is returned unchanged. + **/ +TCHAR cl_tolower (TCHAR ch) +{ + gunichar c=ch; + int t = TYPE ((gunichar)c); + if (t == G_UNICODE_UPPERCASE_LETTER) + { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) + { + const gchar *p = special_case_table + val - 0x1000000; + wchar_t ret=0; + lucene_utf8towc(ret,p); +#ifdef _UCS2 + return ret; +#else + return LUCENE_OOR_CHAR(ret); +#endif + }else + return val ? val : c; + }else if (t == G_UNICODE_TITLECASE_LETTER){ + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + return title_table[i][2]; + } + } + return c; +} + +/** + * cl_toupper: + * @c: a Unicode character + * + * Converts a character to uppercase. + * + * Return value: the result of converting @c to uppercase. + * If @c is not an lowercase or titlecase character, + * or has no upper case equivalent @c is returned unchanged. + **/ +TCHAR cl_toupper (TCHAR ch) +{ + gunichar c=ch; + int t = TYPE (c); + if (t == G_UNICODE_LOWERCASE_LETTER) + { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) + { + const gchar *p = special_case_table + val - 0x1000000; + + wchar_t ret=0; + lucene_utf8towc(ret,p); +#ifdef _UCS2 + return ret; +#else + return LUCENE_OOR_CHAR(ret); +#endif + //return lucene_utf8towc (p); + } + else + return val ? val : c; + } + else if (t == G_UNICODE_TITLECASE_LETTER) + { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + return title_table[i][1]; + } + } + return c; +} + + + +/** + * cl_tcasefold: + * @str: a unicode string + * + * Converts a string into a form that is independent of case. The + * result will not correspond to any particular case, but can be + * compared for equality or ordered with the results of calling + * cl_tcasefold() on other strings. + * + * Note that calling cl_tcasefold() followed by g_utf8_collate() is + * only an approximation to the correct linguistic case insensitive + * ordering, though it is a fairly good one. Getting this exactly + * right would require a more sophisticated collation function that + * takes case sensitivity into account. GLib does not currently + * provide such a function. + * + * Return value: a newly allocated string, that is a + * case independent form of @str. + **/ +TCHAR cl_tcasefold(const TCHAR ch){ + int start = 0; + int end = G_N_ELEMENTS (casefold_table); + + if (ch >= casefold_table[start].ch && + ch <= casefold_table[end - 1].ch) + { + while (1) + { + int half = (start + end) / 2; + if (ch == casefold_table[half].ch) + { + wchar_t ret=0; + lucene_utf8towc(ret,casefold_table[half].data); + + #ifdef _UCS2 + return ret; + #else + return LUCENE_OOR_CHAR(ret); + #endif + }else if (half == start){ + break; + }else if (ch > casefold_table[half].ch){ + start = half; + }else{ + end = half; + } + } + } + return cl_tolower(ch); + +} + + +//this function was not taken from gnome +TCHAR* cl_tcscasefold( TCHAR * str, int len ) //len default is -1 +{ + TCHAR *p = str; + while ((len < 0 || p < str + len) && *p) + { + *p = cl_tcasefold(*p); + p++; + } + return str; +} +//this function was not taken from gnome +int cl_tcscasefoldcmp(const TCHAR * dst, const TCHAR * src){ + TCHAR f,l; + + do{ + f = cl_tcasefold( (*(dst++)) ); + l = cl_tcasefold( (*(src++)) ); + } while ( (f) && (f == l) ); + + return (int)(f - l); +} + +#endif diff --git a/src/shared/CLucene/config/repl_lltot.cpp b/src/shared/CLucene/config/repl_lltot.cpp new file mode 100644 index 00000000000..37f2331da07 --- /dev/null +++ b/src/shared/CLucene/config/repl_lltot.cpp @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_SharedHeader.h" + +TCHAR* lucene_i64tot( + int64_t value, /* [I] Value to be converted */ + TCHAR* str, /* [O] Destination for the converted value */ + int radix) /* [I] Number base for conversion */ +{ + uint64_t val; + int negative; + TCHAR buffer[65]; + TCHAR* pos; + int digit; + + if (value < 0 && radix == 10) { + negative = 1; + val = -value; + } else { + negative = 0; + val = value; + } /* if */ + + pos = &buffer[64]; + *pos = '\0'; + + do { + digit = (int)(val % radix); + val = val / radix; + if (digit < 10) { + *--pos = '0' + digit; + } else { + *--pos = 'a' + digit - 10; + } /* if */ + } while (val != 0L); + + if (negative) { + *--pos = '-'; + } /* if */ + + _tcsncpy(str,pos,&buffer[64] - pos + 1); //needed for unicode to work + return str; +} diff --git a/src/shared/CLucene/config/repl_tchar.h b/src/shared/CLucene/config/repl_tchar.h new file mode 100644 index 00000000000..159dcc1d291 --- /dev/null +++ b/src/shared/CLucene/config/repl_tchar.h @@ -0,0 +1,181 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _REPL_TCHAR_H +#define _REPL_TCHAR_H + +#ifndef _CL_HAVE_TCHAR_H + #if defined(_UCS2) + + //note: descriptions with * in front have replacement functions + + //formatting functions + #define _sntprintf swprintf //* make a formatted a string + #define _tprintf wprintf //* print a formatted string + + //this one has no replacement functions yet, but it is only used in the tests + #define _vsntprintf vsnwprintf //* print a formatted string using variable arguments + + //we are using the internal functions of the compiler here + //if LUCENE_USE_INTERNAL_CHAR_FUNCTIONS is defined, thesse + //will be replaced by internal functions + #define _istalnum iswalnum //* alpha/numeric char check + #define _istalpha iswalpha //* alpha char check + #define _istspace iswspace //* space char check + #define _istdigit iswdigit //* digit char check + #define _totlower towlower //* convert char to lower case + #define _totupper towupper //* convert char to lower case + #define _tcslwr wcslwr //* convert string to lower case + + //these are the string handling functions + //we may need to create wide-character/multi-byte replacements for these + #define _tcscpy wcscpy //copy a string to another string + #define _tcsncpy wcsncpy //copy a specified amount of one string to another string. + #define _tcscat wcscat //copy a string onto the end of the other string + #define _tcsncat wcsncat + #define _tcschr wcschr //find location of one character + #define _tcsstr wcsstr //find location of a string + #define _tcslen wcslen //get length of a string + #define _tcscmp wcscmp //case sensitive compare two strings + #define _tcsncmp wcsncmp //case sensitive compare two strings + #define _tcscspn wcscspn //location of any of a set of character in a string + + //string compare + #ifdef _CL_HAVE_FUNCTION_WCSICMP + #define _tcsicmp wcsicmp //* case insensitive compare two string + #else + #define _tcsicmp wcscasecmp //* case insensitive compare two string + #endif + #if defined(_CL_HAVE_FUNCTION_WCSDUP) + #define _tcsdup wcsdup + #else + #define _tcsdup lucene_wcsdup + #endif + + //conversion functions + #define _tcstod wcstod //convert a string to a double + #define _tcstoi64 wcstoll //* convers a string to an 64bit bit integer + #define _itot _i64tot + #define _i64tot lltow //* converts a 64 bit integer to a string (with base) + #else //if defined(_ASCII) + + //formatting functions + #define _sntprintf snprintf + #define _tprintf printf + #define _vsntprintf vsnprintf + + //we are using the internal functions of the compiler here + //if LUCENE_USE_INTERNAL_CHAR_FUNCTIONS is defined, thesse + //will be replaced by internal functions + #define _istalnum isalnum + #define _istalpha isalpha + #define _istspace isspace + #define _istdigit isdigit + #define _totlower tolower + #define _totupper toupper + #define _tcslwr strlwr + + //these are the string handling functions + #define _tcscpy strcpy + #define _tcsncpy strncpy + #define _tcscat strcat + #define _tcsncat strncat + #define _tcschr strchr + #define _tcsstr strstr + #define _tcslen strlen + #define _tcscmp strcmp + #define _tcsncmp strncmp + #define _tcsicmp strcasecmp + #define _tcscspn strcspn + #define _tcsdup strdup //string duplicate + //converstion methods + #define _tcstod strtod + #define _tcstoi64 strtoll + #define _itot _i64tot + #define _i64tot lltoa + + #endif + +#else //HAVE_TCHAR_H + #include + + //some tchar headers miss these... + #ifndef _tcstoi64 + #if defined(_UCS2) + #define _tcstoi64 wcstoll //* convers a string to an 64bit bit integer + #else + #define _tcstoi64 strtoll + #endif + #endif + +#endif //HAVE_TCHAR_H + +#ifndef _ttoi + #define _ttoi(x) (int)_tcstoi64(x,NULL,10) +#endif + +#ifndef _itot + #define _itot(i, buf, radix) lucene_i64tot(i, buf, radix) +#endif + +namespace std +{ +#ifndef tstring + #ifdef _UNICODE + typedef wstring tstring; + #else + typedef string tstring; + #endif +#endif +}; + +#define STRCPY_AtoA(target,src,len) strncpy(target,src,len) +#define STRDUP_AtoA(x) strdup(x) + +#if defined(_UCS2) + #define stringDuplicate(x) _tcsdup(x) + + #if defined(_CL_HAVE_FUNCTION_WCSDUP) + #define STRDUP_WtoW wcsdup + #else + #define STRDUP_WtoW lucene_wcsdup + #endif + #define STRDUP_TtoT STRDUP_WtoW + #define STRDUP_WtoT STRDUP_WtoW + #define STRDUP_TtoW STRDUP_WtoW + + #define STRDUP_AtoW(x) CL_NS(util)::Misc::_charToWide(x) + #define STRDUP_AtoT STRDUP_AtoW + + #define STRDUP_WtoA(x) CL_NS(util)::Misc::_wideToChar(x) + #define STRDUP_TtoA STRDUP_WtoA + + #define STRCPY_WtoW(target,src,len) _tcsncpy(target,src,len) + #define STRCPY_TtoW STRCPY_WtoW + #define STRCPY_WtoT STRCPY_WtoW + //#define _tcscpy STRCPY_WtoW + + #define STRCPY_AtoW(target,src,len) CL_NS(util)::Misc::_cpycharToWide(src,target,len) + #define STRCPY_AtoT STRCPY_AtoW + + #define STRCPY_WtoA(target,src,len) CL_NS(util)::Misc::_cpywideToChar(src,target,len) + #define STRCPY_TtoA STRCPY_WtoA +#else + #define stringDuplicate(x) strdup(x) + #define STRDUP_AtoT STRDUP_AtoA + #define STRDUP_TtoA STRDUP_AtoA + #define STRDUP_TtoT STRDUP_AtoA + + #define STRDUP_WtoT(x) xxxxxxxxxxxxxxx //not possible + #define STRCPY_WtoT(target,src,len) xxxxxxxxxxxxxxx //not possible + + #define STRCPY_AtoT STRCPY_AtoA + #define STRCPY_TtoA STRCPY_AtoA + //#define _tcscpy STRCPY_AtoA +#endif + + +#endif //_REPL_TCHAR_H diff --git a/src/shared/CLucene/config/repl_tcscasecmp.cpp b/src/shared/CLucene/config/repl_tcscasecmp.cpp new file mode 100644 index 00000000000..b2e27e8178b --- /dev/null +++ b/src/shared/CLucene/config/repl_tcscasecmp.cpp @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_SharedHeader.h" + +int lucene_tcscasecmp(const TCHAR * sa, const TCHAR * sb){ + TCHAR ca,cb; + if (sa == sb) + return 0; + + do{ + ca = _totlower( (*(sa++)) ); + cb = _totlower( (*(sb++)) ); + } while ( ca != L'\0' && (ca == cb) ); + + return (int)(ca - cb); +} diff --git a/src/shared/CLucene/config/repl_tcslwr.cpp b/src/shared/CLucene/config/repl_tcslwr.cpp new file mode 100644 index 00000000000..90a9d2e3b0a --- /dev/null +++ b/src/shared/CLucene/config/repl_tcslwr.cpp @@ -0,0 +1,15 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_SharedHeader.h" + +TCHAR* lucene_tcslwr( TCHAR* str ) +{ + TCHAR* ret = str; + for ( ; *str; str++) *str = _totlower(*str); + return ret; +} diff --git a/src/shared/CLucene/config/repl_tcstod.cpp b/src/shared/CLucene/config/repl_tcstod.cpp new file mode 100644 index 00000000000..0c52a595fc7 --- /dev/null +++ b/src/shared/CLucene/config/repl_tcstod.cpp @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_SharedHeader.h" +#include "CLucene/util/Misc.h" + +#ifndef _ASCII +double lucene_tcstod(const TCHAR *value, TCHAR **end){ + int32_t len = _tcslen(value)+1; + char* avalue=_CL_NEWARRAY(char,len); + char* aend=NULL; + STRCPY_TtoA(avalue,value,len); + + double ret = strtod(avalue,&aend); + *end=(TCHAR*)value+(aend-avalue); + _CLDELETE_CaARRAY(avalue); + + return ret; +} +#endif diff --git a/src/shared/CLucene/config/repl_tcstoll.cpp b/src/shared/CLucene/config/repl_tcstoll.cpp new file mode 100644 index 00000000000..4eb0c5e049e --- /dev/null +++ b/src/shared/CLucene/config/repl_tcstoll.cpp @@ -0,0 +1,53 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "CLucene/_SharedHeader.h" + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +int64_t lucene_tcstoi64(const TCHAR* str, TCHAR**end, int radix){ + #define LUCENE_TCSTOI64_RADIX(x,r) ((x>=_T('0') && x<=_T('9'))?x-_T('0'):((x>=_T('a') && x<=_T('z'))?x-_T('a')+10:((x>=_T('A') && x<=_T('Z'))?x-_T('A')+10:1000))) + + if (radix < 2 || radix > 36) + return 0; + + /* Skip white space. */ + while (_istspace (*str)) + ++str; + + int sign=1; + if ( str[0] == _T('+') ) + str++; + else if ( str[0] == _T('-') ){ + sign = -1; + str++; + } + + *end=(TCHAR*)str; + long r = -1; + while ( (r=LUCENE_TCSTOI64_RADIX(*end[0],radix)) >=0 && r=str;p-- ){ + int i=LUCENE_TCSTOI64_RADIX(p[0],radix); + if ( pos == 0 ) + ret=i; + else + ret += (int64_t)pow((float_t)radix,(float_t)pos) * i; //todo: might be quicker with a different pow overload + + pos++; + } + return sign*ret; +} diff --git a/src/shared/CLucene/config/repl_tprintf.cpp b/src/shared/CLucene/config/repl_tprintf.cpp new file mode 100644 index 00000000000..bbf0c934313 --- /dev/null +++ b/src/shared/CLucene/config/repl_tprintf.cpp @@ -0,0 +1,149 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_SharedHeader.h" +#include "CLucene/util/StringBuffer.h" + +#include //MB_LEN_MAX + +CL_NS_USE(util) + +//print a variable argument to a stream +//currently special number formatting is not supported. it is very minimalistic +void lucene_vfnwprintf(StringBuffer* buffer, size_t /*count*/, const wchar_t * format, va_list& valist){ + const wchar_t *iter = format; + StringBuffer* tmp = NULL; + if ( buffer == NULL ) + tmp = _CLNEW StringBuffer; + else + tmp = buffer; + + while (*iter) + { + while (*iter && *iter != '%') + { + tmp->appendChar(*iter++); + } + if (*iter == '%') + { + if (iter[1] == '%') + { + //just print a % + tmp->appendChar('%'); + iter += 2; + continue; + } + + iter++; + switch (*iter) + { + case 's': + { + //todo: this is faulty. it doesn't heed count + + //print a string or null + const TCHAR *wstr = va_arg(valist, TCHAR *); + if ( !wstr ) + wstr = _T("(null)"); + + tmp->append(wstr); + iter++; + break; + } + + case 'c': + tmp->appendChar((TCHAR)va_arg(valist, int)); + iter++; + break; + + default: + { + //todo: this is faulty. it doesn't heed count + + if (*iter == 'p') + tmp->appendInt((int32_t)va_arg(valist, long)); + else + { + if (*iter == 'a' || *iter == 'A' || + *iter == 'e' || *iter == 'E' || + *iter == 'f' || *iter == 'F' || + *iter == 'g' || *iter == 'G') + tmp->appendFloat((float_t)va_arg(valist, double),8); + else if (*iter == 'd' || *iter == 'i' ){ + tmp->appendInt((int32_t)va_arg(valist, int)); + }else if (*iter == 'l' ){ + TCHAR b[100]; + _i64tot((int64_t)va_arg(valist, int64_t),b,10); + tmp->append(b); + }/*else{ + TCHAR b[100]; + _i64tot((int64_t)va_arg(valist, void*),b,10); + tmp->append(b); + }*/ + } + iter++; + break; + } + } + } + } + + + if ( buffer == NULL ){ + //we are supposed to be writing to the console +#ifdef _UCS2 + TCHAR* pointer = tmp->getBuffer(); + char ob[MB_LEN_MAX]; + size_t v; + size_t len = tmp->length(); + for (size_t i=0;i 0 ){ + ob[v]='\0'; + fputs(ob,stdout); + } + pointer++; + } + + +#else + fputs(tmp->getBuffer(),stdout); +#endif + _CLDELETE(tmp); + } +} + +#ifdef _UCS2 +//print a list of arguments to a string +int lucene_snwprintf(wchar_t* strbuf, size_t count, const wchar_t * format, ...){ + va_list ap; + va_start(ap, format); + StringBuffer buffer; + lucene_vfnwprintf(&buffer,count,format,ap); + va_end(ap); + + size_t ret = cl_min(count,(size_t)(buffer.length()+1)); + wcsncpy(strbuf,buffer.getBuffer(),ret); + return ret; +} + +//print a list of arguments to the stdout +void lucene_wprintf(const wchar_t * format, ...){ + va_list ap; + va_start(ap, format); + lucene_vfnwprintf(NULL,LUCENE_INT32_MAX_SHOULDBE,format,ap); + va_end(ap); +} + +//print a variable argument to a string +int lucene_vsnwprintf(wchar_t * strbuf, size_t count, const wchar_t * format, va_list& ap){ + StringBuffer buffer; + lucene_vfnwprintf(&buffer,count,format,ap); + int ret = cl_min((size_t)count,buffer.length()+1); + wcsncpy(strbuf,buffer.getBuffer(),ret); + return ret; +} +#endif diff --git a/src/shared/CLucene/config/repl_wchar.h b/src/shared/CLucene/config/repl_wchar.h new file mode 100644 index 00000000000..c3c0e614eae --- /dev/null +++ b/src/shared/CLucene/config/repl_wchar.h @@ -0,0 +1,89 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_repl_wchar_h +#define _lucene_repl_wchar_h + +#include +#include "repl_tchar.h" +#ifdef _CL_HAVE_STRING_H + #include +#endif +#ifdef _CL_HAVE_WCHAR_H + #include +#endif + + +CLUCENE_SHARED_EXPORT int cl_tcscasefoldcmp(const TCHAR * dst, const TCHAR * src); +CLUCENE_SHARED_EXPORT TCHAR* cl_tcscasefold( TCHAR * str, int len=-1 ); + +//we provide utf8 conversion functions +CLUCENE_SHARED_EXPORT size_t lucene_utf8towc (wchar_t& ret, const char *s); +CLUCENE_SHARED_EXPORT size_t lucene_utf8towcs(wchar_t *, const char *, size_t maxslen); +CLUCENE_SHARED_EXPORT size_t lucene_wctoutf8 (char * ret, const wchar_t str); +CLUCENE_SHARED_EXPORT size_t lucene_wcstoutf8 (char *, const wchar_t *, size_t maxslen); +#ifdef _ASCII +#define lucene_wcstoutf8string(str,strlen) str +#else +CLUCENE_SHARED_EXPORT std::string lucene_wcstoutf8string(const wchar_t* str, size_t strlen); +#endif +CLUCENE_SHARED_EXPORT size_t lucene_utf8charlen(const unsigned char p); //< the number of characters that this first utf8 character will expect + +//string function replacements +#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) || (defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_WCSCASECMP)) || (defined(_ASCII) && !defined(_CL_HAVE_FUNCTION_STRCASECMP)) + CLUCENE_SHARED_EXPORT int lucene_tcscasecmp(const TCHAR *, const TCHAR *); + #undef _tcsicmp + #define _tcsicmp lucene_tcscasecmp +#endif +#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) || (defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_WCSLWR)) || (defined(_ASCII) && !defined(_CL_HAVE_FUNCTION_STRLWR)) + CLUCENE_SHARED_EXPORT TCHAR* lucene_tcslwr( TCHAR* str ); + #undef _tcslwr + #define _tcslwr lucene_tcslwr +#endif + +//conversion functions +#if (defined(_ASCII) && !defined(_CL_HAVE_FUNCTION_LLTOA)) || (defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_LLTOW)) + CLUCENE_SHARED_EXPORT TCHAR* lucene_i64tot( int64_t value, TCHAR* str, int radix); + #undef _i64tot + #define _i64tot lucene_i64tot +#endif +#if !defined(_CL_HAVE_FUNCTION_WCSDUP) + CLUCENE_SHARED_EXPORT wchar_t* lucene_wcsdup( const wchar_t* str); +#endif +#if (defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_WCSTOLL)) || (defined(_ASCII) && !defined(_CL_HAVE_FUNCTION_STRTOLL)) + CLUCENE_SHARED_EXPORT int64_t lucene_tcstoi64(const TCHAR* str, TCHAR**end, int radix); + #undef _tcstoi64 + #define _tcstoi64 lucene_tcstoi64 +#endif +#if defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_WCSTOD) + CLUCENE_SHARED_EXPORT double lucene_tcstod(const TCHAR *value, TCHAR **end); + #undef _tcstod + #define _tcstod lucene_tcstod +#endif + +//printf functions +#if (defined(_UCS2) && (!defined(_CL_HAVE_FUNCTION__SNWPRINTF)) || defined(_CL_HAVE_SNWPRINTF_BUG) ) + #undef _sntprintf + #define _sntprintf lucene_snwprintf + CLUCENE_SHARED_EXPORT int lucene_snwprintf(wchar_t* strbuf, size_t count, const wchar_t * format, ...); +#endif +#if defined(_UCS2) && !defined(_CL_HAVE_FUNCTION_WPRINTF) + #undef _tprintf + #define _tprintf lucene_wprintf + CLUCENE_SHARED_EXPORT void lucene_wprintf(const wchar_t * format, ...); +#endif +#if defined(_UCS2) && (!defined(_CL_HAVE_FUNCTION__VSNWPRINTF) || defined(_CL_HAVE_SNWPRINTF_BUG) ) + #undef _vsntprintf + #define _vsntprintf lucene_vsnwprintf + CLUCENE_SHARED_EXPORT int lucene_vsnwprintf(wchar_t * strbuf, size_t count, const wchar_t * format, va_list& ap); +#endif + + + +//todo: if _CL_HAVE_SNPRINTF_BUG fails(snprintf overflow),we should use our own +//function. but we don't have it currently, and our functions are dubious anyway... + +#endif //end of _lucene_repl_wchar_h diff --git a/src/shared/CLucene/config/repl_wctype.h b/src/shared/CLucene/config/repl_wctype.h new file mode 100644 index 00000000000..f7064280e7b --- /dev/null +++ b/src/shared/CLucene/config/repl_wctype.h @@ -0,0 +1,76 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_repl_wctype_h +#define _lucene_repl_wctype_h + + +//////////////////////////////////////////////////////// +// Character functions. +// Here we decide whose character functions to use +//////////////////////////////////////////////////////// +#if defined(LUCENE_USE_INTERNAL_CHAR_FUNCTIONS) + #define stringCaseFold cl_tcscasefold + #define stringCaseFoldCmp cl_tcscasefoldcmp + + #undef _istspace + #undef _istdigit + #undef _istalnum + #undef _istalpha + #undef _totlower + #undef _totupper + #define _istalnum cl_isalnum + #define _istalpha cl_isletter + #define _istspace cl_isspace + #define _istdigit cl_isdigit + #define _totlower cl_tolower + #define _totupper cl_toupper + + //here are some functions to help deal with utf8/ucs2 conversions + //lets let the user decide what mb functions to use... we provide pure utf8 ones no matter what. + /*#undef _mbtowc + #undef _mbstowcs + #undef _wctomb + #undef _wcstombs + #define _mbtowc lucene_mbstowc + #define _mbsstowcs lucene_mbstowcs + #define _wctomb lucene_wcto_mb + #define _wcstombs lucene_wcstombs*/ +#else + //we are using native functions + //here are some functions to help deal with utf8/ucs2 conversions + /*#define _mbtowc mbtowc + #define _wctomb wctomb + #define _mbstowcs mbstowcs + #define _wcstombs wcstombs*/ + + //we are using native character functions + #if defined(_ASCII) + #undef _istspace + #undef _istdigit + #undef _istalnum + #undef _istalpha + #undef _totlower + #undef _totupper + #define _istspace(x) isspace((unsigned char)x) + #define _istdigit(x) isdigit((unsigned char)x) + #define _istalnum(x) isalnum((unsigned char)x) + #define _istalpha(x) isalpha((unsigned char)x) + #define _totlower(x) tolower((unsigned char)x) + #define _totupper(x) toupper((unsigned char)x) + #endif +#endif + +//the methods contained in gunichartables.h +typedef unsigned long clunichar; +CLUCENE_SHARED_EXPORT bool cl_isletter(clunichar c); +CLUCENE_SHARED_EXPORT bool cl_isalnum(clunichar c); +CLUCENE_SHARED_EXPORT bool cl_isdigit(clunichar c); +CLUCENE_SHARED_EXPORT bool cl_isspace (clunichar c); +CLUCENE_SHARED_EXPORT TCHAR cl_tolower (TCHAR c); +CLUCENE_SHARED_EXPORT TCHAR cl_toupper (TCHAR c); + +#endif diff --git a/src/shared/CLucene/config/threads.cpp b/src/shared/CLucene/config/threads.cpp new file mode 100644 index 00000000000..0b5f30ab8c1 --- /dev/null +++ b/src/shared/CLucene/config/threads.cpp @@ -0,0 +1,292 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_SharedHeader.h" +#include "CLucene/LuceneThreads.h" +#include "_threads.h" +#include + +CL_NS_DEF(util) + +#ifndef _CL_DISABLE_MULTITHREADING + +#if defined(_LUCENE_DONTIMPLEMENT_THREADMUTEX) + //do nothing + #if defined(_LUCENE_PRAGMA_WARNINGS) + #pragma message ("==================Not implementing any thread mutex==================") + #else + #warning "==================Not implementing any thread mutex==================" + #endif + + + +#elif defined(_CL_HAVE_WIN32_THREADS) + struct mutex_thread::Internal{ + CRITICAL_SECTION mtx; + }; + + mutex_thread::mutex_thread(const mutex_thread& clone): + _internal(new Internal) + { + InitializeCriticalSection(&_internal->mtx); + } + mutex_thread::mutex_thread(): + _internal(new Internal) + { + InitializeCriticalSection(&_internal->mtx); + } + + mutex_thread::~mutex_thread() + { + DeleteCriticalSection(&_internal->mtx); + delete _internal; + } + + void mutex_thread::lock() + { + EnterCriticalSection(&_internal->mtx); + } + + void mutex_thread::unlock() + { + LeaveCriticalSection(&_internal->mtx); + } + + _LUCENE_THREADID_TYPE mutex_thread::_GetCurrentThreadId(){ + return GetCurrentThreadId(); + } + void mutex_thread::_exitThread(int val){ + ExitThread(val); + } + + int32_t mutex_thread::atomic_increment(_LUCENE_ATOMIC_INT *theInteger){ +#ifdef _M_X64 + return _InterlockedIncrement64(theInteger); +#else + return InterlockedIncrement(theInteger); +#endif + } + int32_t mutex_thread::atomic_decrement(_LUCENE_ATOMIC_INT *theInteger){ +#ifdef _M_X64 + return _InterlockedDecrement64(theInteger); +#else + return InterlockedDecrement(theInteger); +#endif + } + + + + class shared_condition::Internal{ + public: + void* _event; + Internal(){ + _event = CreateEventA( NULL, false, false, NULL ); + } + ~Internal(){ + CloseHandle( _event ); + } + }; + shared_condition::shared_condition(){ + _internal = new Internal; + } + shared_condition::~shared_condition(){ + delete _internal; + } + void shared_condition::Wait(mutex_thread* shared_lock){ + shared_lock->unlock(); + _cl_dword_t dwRes = WaitForSingleObject( _internal->_event, 0xFFFFFFFF ); + assert ( 0x0 == dwRes ); + shared_lock->lock(); + } + void shared_condition::NotifyAll(){ + bool bRes = SetEvent(_internal->_event); + assert( bRes ); + } + + _LUCENE_THREADID_TYPE mutex_thread::CreateThread(luceneThreadStartRoutine* func, void* arg){ + return (_LUCENE_THREADID_TYPE) ::_beginthread (func, 0, arg); + } + void mutex_thread::JoinThread(_LUCENE_THREADID_TYPE id){ + WaitForSingleObject((void*)id, 0xFFFFFFFF); + } + + +#elif defined(_CL_HAVE_PTHREAD) + #ifndef _REENTRANT + #error ACK! You need to compile with _REENTRANT defined since this uses threads + #endif + + #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + bool mutex_pthread_attr_initd=false; + pthread_mutexattr_t mutex_thread_attr; + #endif + + #ifdef _CL__CND_DEBUG + #define _CLPTHREAD_CHECK(c,m) CND_PRECONDITION(c==0,m) + #else + #define _CLPTHREAD_CHECK(c,m) c; + #endif + + struct mutex_thread::Internal{ + pthread_mutex_t mtx; + #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + pthread_t lockOwner; + unsigned int lockCount; + #endif + }; + + mutex_thread::mutex_thread(const mutex_thread& /*clone*/): + _internal(new Internal) + { + #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, &mutex_thread_attr), "mutex_thread(clone) constructor failed") + #else + #if defined(__hpux) && defined(_DECTHREADS_) + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, pthread_mutexattr_default), "mutex_thread(clone) constructor failed") + #else + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, 0), "mutex_thread(clone) constructor failed") + #endif + _internal->lockCount=0; + _internal->lockOwner=0; + #endif + } + mutex_thread::mutex_thread(): + _internal(new Internal) + { + #ifdef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + if ( mutex_pthread_attr_initd == false ){ + pthread_mutexattr_init(&mutex_thread_attr); + pthread_mutexattr_settype(&mutex_thread_attr, PTHREAD_MUTEX_RECURSIVE); + mutex_pthread_attr_initd = true; + } + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, &mutex_thread_attr), "mutex_thread(clone) constructor failed") + #else + #if defined(__hpux) && defined(_DECTHREADS_) + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, pthread_mutexattr_default), "mutex_thread(clone) constructor failed") + #else + _CLPTHREAD_CHECK(pthread_mutex_init(&_internal->mtx, 0), "mutex_thread(clone) constructor failed") + #endif + _internal->lockCount=0; + _internal->lockOwner=0; + #endif + } + + mutex_thread::~mutex_thread() + { + _CLPTHREAD_CHECK(pthread_mutex_destroy(&_internal->mtx), "~mutex_thread destructor failed") + delete _internal; + } + + _LUCENE_THREADID_TYPE mutex_thread::_GetCurrentThreadId(){ + return pthread_self(); + } + + int32_t atomic_threads::atomic_increment(_LUCENE_ATOMIC_INT *theInteger){ + #ifdef _CL_HAVE_GCC_ATOMIC_FUNCTIONS + return __sync_add_and_fetch(theInteger, 1); + #else + SCOPED_LOCK_MUTEX(theInteger->THIS_LOCK) + return ++theInteger->value; + #endif + } + int32_t atomic_threads::atomic_decrement(_LUCENE_ATOMIC_INT *theInteger){ + #ifdef _CL_HAVE_GCC_ATOMIC_FUNCTIONS + return __sync_sub_and_fetch(theInteger, 1); + #else + SCOPED_LOCK_MUTEX(theInteger->THIS_LOCK) + return --theInteger->value; + #endif + } + + + _LUCENE_THREADID_TYPE mutex_thread::CreateThread(luceneThreadStartRoutine* func, void* arg){ + _LUCENE_THREADID_TYPE ret; + int nRes = pthread_create(&ret, NULL, func, arg); + assert( nRes == 0 ); + return ret; + } + void mutex_thread::JoinThread(_LUCENE_THREADID_TYPE id){ + pthread_join(id, NULL); + } + + void mutex_thread::lock() + { + #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + pthread_t currentThread = pthread_self(); + if( pthread_equal( _internal->lockOwner, currentThread ) ) { + ++_internal->lockCount; + } else { + _CLPTHREAD_CHECK(pthread_mutex_lock(&_internal->mtx), "mutex_thread::lock") + _internal->lockOwner = currentThread; + _internal->lockCount = 1; + } + #else + _CLPTHREAD_CHECK(pthread_mutex_lock(&_internal->mtx), "mutex_thread::lock") + #endif + } + + void mutex_thread::unlock() + { + #ifndef _CL_HAVE_PTHREAD_MUTEX_RECURSIVE + --_internal->lockCount; + if( _internal->lockCount == 0 ) + { + _internal->lockOwner = 0; + _CLPTHREAD_CHECK(pthread_mutex_unlock(&_internal->mtx), "mutex_thread::unlock") + } + #else + _CLPTHREAD_CHECK(pthread_mutex_unlock(&_internal->mtx), "mutex_thread::unlock") + #endif + } + + + struct shared_condition::Internal{ + pthread_cond_t condition; + Internal(){ + pthread_cond_init (&condition, NULL); + } + ~Internal(){ + pthread_cond_destroy(&condition); + } + }; + shared_condition::shared_condition(){ + _internal = new Internal; + } + shared_condition::~shared_condition(){ + delete _internal; + } + void shared_condition::Wait(mutex_thread* shared_lock){ + int res = 0; + res = pthread_cond_wait(&_internal->condition, &shared_lock->_internal->mtx); + assert(res == 0); + } + void shared_condition::NotifyAll(){ + int res = 0; + res = pthread_cond_broadcast(&_internal->condition); + assert(res == 0); + } + + +#endif //thread impl choice + + +mutexGuard::mutexGuard(const mutexGuard& /*clone*/){ + //no autoclone + mrMutex = NULL; +} +mutexGuard::mutexGuard( _LUCENE_THREADMUTEX& rMutex ) : + mrMutex(&rMutex) +{ + mrMutex->lock(); +} +mutexGuard::~mutexGuard() +{ + mrMutex->unlock(); +} + +#endif //!_CL_DISABLE_MULTITHREADING + +CL_NS_END diff --git a/src/shared/CLucene/config/utf8.cpp b/src/shared/CLucene/config/utf8.cpp new file mode 100644 index 00000000000..0a9c1fe2579 --- /dev/null +++ b/src/shared/CLucene/config/utf8.cpp @@ -0,0 +1,249 @@ +/* + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * + ************************************************ + * Also licensed with permission from Tom Tromey + * and Owen Taylor under the Apache license. + * Original location: + * http://cvs.gnome.org/viewcvs/glib/glib/gutf8.c?rev=1.50&view=log + ************************************************ + * + * Copyright 2003-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "CLucene/_SharedHeader.h" + +typedef unsigned long gunichar; +typedef unsigned char guchar; + +#define UTF8_COMPUTE(Char, Mask, Len) \ + if (Char < 128) \ + { \ + Len = 1; \ + Mask = 0x7f; \ + } \ + else if ((Char & 0xe0) == 0xc0) \ + { \ + Len = 2; \ + Mask = 0x1f; \ + } \ + else if ((Char & 0xf0) == 0xe0) \ + { \ + Len = 3; \ + Mask = 0x0f; \ + } \ + else if ((Char & 0xf8) == 0xf0) \ + { \ + Len = 4; \ + Mask = 0x07; \ + } \ + else if ((Char & 0xfc) == 0xf8) \ + { \ + Len = 5; \ + Mask = 0x03; \ + } \ + else if ((Char & 0xfe) == 0xfc) \ + { \ + Len = 6; \ + Mask = 0x01; \ + } \ + else \ + Len = -1; + +/*#define UTF8_LENGTH(Char) \ + ((Char) < 0x80 ? 1 : \ + ((Char) < 0x800 ? 2 : \ + ((Char) < 0x10000 ? 3 : \ + ((Char) < 0x200000 ? 4 : \ + ((Char) < 0x4000000 ? 5 : 6)))))*/ + + +#define UTF8_GET(Result, Chars, Count, Mask, Len) \ + (Result) = (Chars)[0] & (Mask); \ + for ((Count) = 1; (Count) < (Len); ++(Count)) \ + { \ + if (((Chars)[(Count)] & 0xc0) != 0x80) \ + { \ + (Result) = -1; \ + break; \ + } \ + (Result) <<= 6; \ + (Result) |= ((Chars)[(Count)] & 0x3f); \ + } + + +/** + * lucene_wctoutf8: + * @c: a ISO10646 character code + * @outbuf: output buffer, must have at least 6 bytes of space. + * If %NULL, the length will be computed and returned + * and nothing will be written to @outbuf. + * + * Converts a single character to UTF-8. + * + * Return value: number of bytes written + **/ +size_t lucene_wctoutf8(char * outbuf, const wchar_t ch) +{ + gunichar c = ch; + guchar len = 0; + int first; + int i; + + if (c < 0x80) + { + first = 0; + len = 1; + } + else if (c < 0x800) + { + first = 0xc0; + len = 2; + } + else if (c < 0x10000) + { + first = 0xe0; + len = 3; + } + else if (c < 0x200000) + { + first = 0xf0; + len = 4; + } + else if (c < 0x4000000) + { + first = 0xf8; + len = 5; + } + else + { + first = 0xfc; + len = 6; + } + + if (outbuf) + { + for (i = len - 1; i > 0; --i) + { + outbuf[i] = (char)((c & 0x3f) | 0x80); + c >>= 6; + } + outbuf[0] = (char)(c | first); + } + + return len; +} + + +/** + * lucene_utf8towc: + * @p: a pointer to Unicode character encoded as UTF-8 + * + * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. + * If @p does not point to a valid UTF-8 encoded character, results are + * undefined. If you are not sure that the bytes are complete + * valid Unicode characters, you should use lucene_utf8towc_validated() + * instead. + * + * Return value: the number of p consumed for the character, or 0 on error + **/ +size_t lucene_utf8towc(wchar_t& pwc, const char *p) +{ + int i, mask = 0; + int result; + unsigned char c = (unsigned char) *p; + int len=0; + + UTF8_COMPUTE (c, mask, len); + if (len == -1) + return 0; + UTF8_GET (result, p, i, mask, len); + + pwc = result; + return len; +} + + +//this function was not taken from gnome +size_t lucene_wcstoutf8(char * result, const wchar_t * str, size_t result_length){ + char *p=result; + int i = 0; + + while (p < result + result_length-1 && str[i] != 0) + p += lucene_wctoutf8(p,str[i++]); + + *p = '\0'; + + return p-result; +} +//this function was not taken from gnome +size_t lucene_utf8towcs(wchar_t * result, const char * str, size_t result_length){ + char *sp = const_cast(str); + wchar_t *rp = result; + + while (rp < result + result_length && *sp!=0){ + size_t r = lucene_utf8towc(*rp,sp); + if ( r == 0 ) + return 0; + sp += r; + rp++; + } + + size_t ret = sp-str; + if ( ret < result_length ) + *rp = '\0'; + + return ret; +} +//get the number of bytes that make up the utf8 character. +//this function was not taken from gnome +size_t lucene_utf8charlen(const unsigned char c) +{ + int mask = 0; + int len=0; + + UTF8_COMPUTE (c, mask, len); + return len; +} +#ifndef _ASCII +//convert unicode string to a utf8 string +std::string lucene_wcstoutf8string(const wchar_t* str, size_t strlen){ + size_t i = 0; + std::string result; + char p[6]; + + while (i < strlen && str[i] != 0){ + result.append(p, lucene_wctoutf8(p,str[i++])); + } + + return result; +} +#endif diff --git a/src/shared/CLucene/debug/_condition.h b/src/shared/CLucene/debug/_condition.h new file mode 100644 index 00000000000..a88856f1fdd --- /dev/null +++ b/src/shared/CLucene/debug/_condition.h @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef __CONDITION_H +#define __CONDITION_H + +//todo: this is a hack +#undef CND_PRECONDITION + +/* +To enable condition debugging uncomment _CND_DEBUG in CLConfig.h +*/ + +#ifdef _CL__CND_DEBUG /* Don't include the debug code */ + /* _CL__CND_DEBUG defined, include debug code */ + + #ifdef _CND_NODEBUGTEXT + #define CND_PRECONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_PRECONDITION,NULL) + #define CND_CONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_CONDITION,NULL) + #define CND_WARNING(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_WARNING,NULL) + #define CND_MESSAGE(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_MESSAGE,NULL) + #define CND_DEBUGMESSAGE(usermessage) CND__MESSAGE(__FILE__,__LINE__,CND_STR_DEBUGMESSAGE,NULL) + #else + #define CND_PRECONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_PRECONDITION,usermessage) + #define CND_CONDITION(cond,usermessage) CND__EXITCONDITION(cond,__FILE__,__LINE__,CND_STR_CONDITION,usermessage) + #define CND_WARNING(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_WARNING,usermessage) + #define CND_MESSAGE(cond,usermessage) CND__CONDITION(cond,__FILE__,__LINE__,CND_STR_MESSAGE,usermessage) + #define CND_DEBUGMESSAGE(usermessage) CND__MESSAGE(__FILE__,__LINE__,CND_STR_DEBUGMESSAGE,usermessage) + #endif + + //if _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG is defined, then you must implement + //this routine in the client application. The debug callback can then + //be better customised to the host application. + //Here is the default implementation: + void _Cnd_OutDebug( const char* FormattedMsg, const char* StrTitle, const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ); + + void CLUCENE_SHARED_EXPORT __cnd_FormatDebug( const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ); + #define CND__EXIT(file,line,title,mes2) {__cnd_FormatDebug(file,line,title,mes2,1);} + #define CND__EXITCONDITION(cond,file,line,title,mes2) {if(!(cond)){__cnd_FormatDebug(file,line,title,mes2,1);}} + #define CND__CONDITION(cond,file,line,title,mes2) {if(!(cond)){__cnd_FormatDebug(file,line,title,mes2,0);}} + #define CND__MESSAGE(file,line,title,mes2) {__cnd_FormatDebug(file,line,title,mes2,0);} +#else + #define CND_PRECONDITION(cond, usermessage) + #define CND_CONDITION(cond, usermessage) + #define CND_WARNING(cond,usermessage) + #define CND_MESSAGE(cond,usermessage) + #define CND_DEBUGMESSAGE(usermessage) +#endif + +#ifndef CND_STR_DEFINES + #define CND_STR_DEFINES + #define CND_STR_PRECONDITION 1 + #define CND_STR_CONDITION 2 + #define CND_STR_WARNING 3 + #define CND_STR_MESSAGE 4 + #define CND_STR_DEBUGMESSAGE 5 + #define CND_STR_EXIT 6 +#endif + +//cnd-debug exit command +#ifndef debugFatalExit + #define debugFatalExit(ret) exit(ret) +#endif + + +#endif diff --git a/src/shared/CLucene/debug/condition.cpp b/src/shared/CLucene/debug/condition.cpp new file mode 100644 index 00000000000..1343525569d --- /dev/null +++ b/src/shared/CLucene/debug/condition.cpp @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#define _CL__CND_DEBUG +#include "CLucene/_SharedHeader.h" +#include "_condition.h" +#include "CLucene/util/Misc.h" + +#define __CND_STR_PRECONDITION "PRECONDITION" +#define __CND_STR_CONDITION "CONDITION" +#define __CND_STR_WARNING "WARNING" +#define __CND_STR_MESSAGE "MESSAGE" +#define __CND_STR_DEBUGMESSAGE "DEBUG MESSAGE" +#define __CND_STR_EXIT "EXIT" + +#ifndef _CND_DEBUG_DONTIMPLEMENT_OUTDEBUG +void _Cnd_OutDebug( const char* FormattedMsg, const char* StrTitle, const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ){ + #ifdef __WINDOWS_H + /*Display a standard messagebox*/ + MessageBox(NULL, FormattedMsg, StrTitle, (fatal==1 ? MB_ICONSTOP:MB_ICONEXCLAMATION) | MB_OK | MB_TASKMODAL); + #else + printf("%s\n",FormattedMsg); + #endif + + #if defined(_CND_DEBUG_WARN_DEBUGGER) /*attempt to signal windows debugger*/ + OutputDebugString(FormattedMsg); + DebugBreak(); /*Position debugger just before exit program*/ + #endif + + if ( fatal ) + debugFatalExit(1); +} +#endif + +void __cnd_FormatDebug( const char* File, int32_t Line, int32_t Title, const char* Mes2, int32_t fatal ) { + char M[512]; + const char* StrTitle = NULL; + + if( Mes2 ) + _snprintf(M,512,"file:%s line:%d\n%s",File,Line,Mes2); + else + _snprintf(M,512,"file:%s line:%d",File,Line); + + /*Determine which title to use*/ + switch( Title ) { + case CND_STR_PRECONDITION: { + StrTitle = __CND_STR_PRECONDITION; + break; + } + case CND_STR_CONDITION: { + StrTitle = __CND_STR_CONDITION; + break; + } + case CND_STR_WARNING: { + StrTitle = __CND_STR_WARNING; + break; + } + case CND_STR_MESSAGE: { + StrTitle = __CND_STR_MESSAGE; + break; + } + case CND_STR_DEBUGMESSAGE: { + StrTitle = __CND_STR_DEBUGMESSAGE; + break; + } + case CND_STR_EXIT: { + StrTitle = __CND_STR_EXIT; + break; + } + default: + break; + }/*switch*/ + + _Cnd_OutDebug(M, StrTitle, File, Line, Title, Mes2, fatal); +} diff --git a/src/shared/CLucene/util/Misc.cpp b/src/shared/CLucene/util/Misc.cpp new file mode 100644 index 00000000000..6d29e5550d2 --- /dev/null +++ b/src/shared/CLucene/util/Misc.cpp @@ -0,0 +1,739 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "Misc.h" +#include +#include +#include +//#include // presumes zstd library is installed + +#if defined(_CL_HAVE_SYS_TIME_H) +# include +#elif defined(_CL_HAVE_TIME_H) +# include +#endif +#ifdef _CL_HAVE_SYS_TIMEB_H + #include +#endif + +#if defined(_CL_HAVE_SYS_STAT_H) + #include +#endif +#ifdef _CL_HAVE_STRINGS_H + #include +#endif +#ifdef _CL_HAVE_UNISTD_H + #include +#endif + +#include +#include +#include "CLucene/util/dirent.h" //if we have dirent, then the native one will be used + +//for zlib... +#include "zlib.h" +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif +#define CL_Z_DEFAULT_CHUNK 1024 + + +#ifdef _CL_HAVE_FUNCTION_SLEEP + //don't ignore windows.h... breaks mingw32 in some cases. Define Sleep instead + extern "C" __declspec(dllimport) void __stdcall Sleep(_cl_dword_t); +#endif + +CL_NS_DEF(util) + +size_t Misc::ahashCode(const char* str){ + // Compute the hash code using a local variable to be reentrant. + size_t hashCode = 0; + while ( *str != 0 ) + hashCode = hashCode * 31 + *str++; + return hashCode; +} +size_t Misc::ahashCode(const char* str, size_t len){ + // Compute the hash code using a local variable to be reentrant. + size_t hashCode = 0; + for (size_t i = 0; i +size_t Misc::swhashCode(const T* str, size_t len){ + // Compute the hash code using a local variable to be reentrant. + size_t hashCode = 0; + for (size_t i = 0; i 50 ) // if it still doesn't show up, then we do some sleeping for the last 50ms + _LUCENE_SLEEP( 1 ); + } + + if( maxAttempts > 0 ) + maxAttempts--; + } + + return 0; +} + + +//static +TCHAR* Misc::join ( const TCHAR* a, const TCHAR* b, const TCHAR* c, const TCHAR* d,const TCHAR* e,const TCHAR* f ) { +#define LEN(x) (x == NULL ? 0 : _tcslen(x)) +const size_t totalLen = + LEN(a) + LEN(b) + LEN(c) + LEN(d) + LEN(e) + LEN(f) + + sizeof(TCHAR); /* Space for terminator. */ + +TCHAR* buf = _CL_NEWARRAY(TCHAR,totalLen); +buf[0]=0; +if ( a != NULL) _tcscat(buf,a); +if ( b != NULL) _tcscat(buf,b); +if ( c != NULL) _tcscat(buf,c); +if ( d != NULL) _tcscat(buf,d); +if ( e != NULL) _tcscat(buf,e); +if ( f != NULL) _tcscat(buf,f); +return buf; +} + +char* Misc::ajoin ( const char* a, const char* b, const char* c, const char* d,const char* e,const char* f ) { + #define aLEN(x) (x == NULL ? 0 : strlen(x)) + const size_t totalLen = + aLEN(a) + aLEN(b) + aLEN(c) + aLEN(d) + aLEN(e) + aLEN(f) + + sizeof(char); /* Space for terminator. */ + + char* buf = _CL_NEWARRAY(char,totalLen); + buf[0]=0; + if ( a != NULL) strcat(buf,a); + if ( b != NULL) strcat(buf,b); + if ( c != NULL) strcat(buf,c); + if ( d != NULL) strcat(buf,d); + if ( e != NULL) strcat(buf,e); + if ( f != NULL) strcat(buf,f); +return buf; +} + +//static +bool Misc::priv_isDotDir( const TCHAR* name ) +{ +if( name[0] == '\0' ) { + return (false); +} +if( name[0] == '.' && name[1] == '\0' ) { + return (true); +} +if( name[1] == '\0' ) { + return (false); +} +if( name[0] == '.' && name[1] == '.' && name[2] == '\0' ) { + return (true); +} + +return (false); +} + +//internal static function shared for clucene +string Misc::segmentname( const char* segment, const char* ext, const int32_t x ){ +//Func - Returns an allocated buffer in which it creates a filename by +// concatenating segment with ext and x +//Pre ext != NULL and holds the extension +// x contains a number +//Post - A buffer has been instantiated an when x = -1 buffer contains the concatenation of +// segment and ext otherwise buffer contains the contentation of segment, ext and x + + CND_PRECONDITION(ext != NULL, "ext is NULL"); + + + if ( x!=-1 ){ + char buf[30]; + _snprintf(buf,10,"%d",x); + return string(segment) + ext + buf; + }else{ + return string(segment) + ext; + } +} +void Misc::segmentname(char* buffer,int32_t bufferLen, const char* Segment, const char* ext, const int32_t x){ +//Func - Static Method +// Creates a filename in buffer by concatenating Segment with ext and x +//Pre - buffer != NULL +// Segment != NULL and holds the name of the segment +// ext != NULL and holds the extension +// x contains a number +//Post - When x = -1 buffer contains the concatenation of Segment and ext otherwise +// buffer contains the contentation of Segment, ext and x + + CND_PRECONDITION(buffer != NULL, "buffer is NULL"); + CND_PRECONDITION(Segment != NULL, "Segment is NULL"); + CND_PRECONDITION(ext != NULL, "ext is NULL"); + + if ( x== -1 ) + _snprintf(buffer,bufferLen,"%s%s", Segment,ext ); + else + _snprintf(buffer,bufferLen,"%s%s%d", Segment,ext,x ); +} + + +//static +int32_t Misc::stringDifference(const TCHAR* s1, const int32_t len1, const TCHAR* s2, const int32_t len2) { + int32_t len = len1 < len2 ? len1 : len2; + for (int32_t i = 0; i < len; i++) + if ( s1[i] != s2[i]) + return i; + return len; +} + +TCHAR* Misc::stringTrim(TCHAR* text) { + size_t j, i; + size_t len = _tcslen(text); + + for ( i=0;i i; --j ){ // find the last non-space character and store it as j + if ( ! _istspace(text[j]) ) { + break; + } + } + + if (i==0 && j==len-1) // prevent unnecessary copy + return text; + + if (i==0) + text[j+1]=0; + else { + j++; + _tcsncpy(text, text+i, j-i); + text[j-i] = 0; + } + + return text; +} + +TCHAR* Misc::wordTrim(TCHAR* text) { + size_t j, i; + size_t len = _tcslen(text); + + for ( i=0;i buf && value ); + + memcpy( retval, ptr, end - ptr ); + retval[end-ptr] = 0; + + return end-ptr; +} + +int64_t Misc::base36ToLong( const char* value ) { + char* ptr = (char*)value; + int64_t lval = 0; + + while ( *ptr != '\0' ) { + lval = isdigit(*ptr) ? ( 36 * lval ) + ( *ptr - '0' ) : ( 36 * lval ) + ( *ptr - 'a' + 10 ); + ptr++; + } + + return lval; +} + +bool Misc::listDirs(const char* directory, std::vector& files, bool fullPath){ + //clear old files + DIR* dir = opendir(directory); + if ( dir == NULL ) return false; + struct dirent* fl = readdir(dir); + struct cl_stat_t buf; + string path; + while ( fl != NULL ){ + path = string(directory) + "/" + fl->d_name; + int32_t ret = fileStat(path.c_str(),&buf); + if ( ret==0 && (buf.st_mode & S_IFDIR) ) { + if ( (strcmp(fl->d_name, ".")) && (strcmp(fl->d_name, "..")) ) { + if ( fullPath ){ + files.push_back(path); + }else{ + files.push_back(fl->d_name); + } + } + } + fl = readdir(dir); + } + closedir(dir); + return true; +} + +bool Misc::listFiles(const char* directory, std::vector& files, bool fullPath){ + //clear old files + DIR* dir = opendir(directory); + if ( dir == NULL ) return false; + struct dirent* fl = readdir(dir); + struct cl_stat_t buf; + string path; + while ( fl != NULL ){ + path = string(directory) + "/" + fl->d_name; + int32_t ret = fileStat(path.c_str(),&buf); + if ( ret==0 && !(buf.st_mode & S_IFDIR) ) { + if ( (strcmp(fl->d_name, ".")) && (strcmp(fl->d_name, "..")) ) { + if ( fullPath ){ + files.push_back(path); + }else{ + files.push_back(fl->d_name); + } + } + } + fl = readdir(dir); + } + closedir(dir); + return true; +} + + +std::string Misc::toString(const bool value){ + return value ? "true" : "false"; +} +std::string Misc::toString(_LUCENE_THREADID_TYPE value){ + static int32_t nextindex = 0; + static std::map<_LUCENE_THREADID_TYPE, int32_t> ids; + if (ids.find(value) == ids.end()) { + ids[value] = nextindex++; + } + return toString(ids[value]); +} +std::string Misc::toString(const int32_t value){ + char buf[20]; + TCHAR tbuf[20]; + _i64tot(value, tbuf, 10); + STRCPY_TtoA(buf,tbuf,20); + return buf; +} +std::string Misc::toString(const int64_t value){ + char buf[20]; + TCHAR tbuf[20]; + _i64tot(value, tbuf, 10); + STRCPY_TtoA(buf,tbuf,20); + return buf; +} +std::string Misc::toString(const float_t value){ + char buf[20]; + _snprintf(buf,20,"%0.2f",(double)value); + return buf; +} + +void Misc::zerr(int ret, string& err) +{ + switch (ret) { + case Z_ERRNO: + err = "error occurred while reading or writing from the zlib streams"; + break; + case Z_STREAM_ERROR: + err = "invalid compression level"; + break; + case Z_DATA_ERROR: + err = "invalid or incomplete deflate data"; + break; + case Z_MEM_ERROR: + err = "out of memory"; + break; + case Z_VERSION_ERROR: + err ="zlib version mismatch"; + } +} + + + +/* Compress from file source to file dest until EOF on source. + def() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +bool Misc::deflate(const uint8_t* in, size_t inlen, std::ostream& dest, string& err, int CHUNK, int level) +{ + int ret, flush; + unsigned have; + z_stream strm; + if ( level == -1 ) level = Z_BEST_COMPRESSION; + if ( CHUNK == -1 ) CHUNK = CL_Z_DEFAULT_CHUNK; + uint8_t* out = (uint8_t*)malloc(CHUNK); + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK){ + free(out); + zerr(ret, err); + return false; + } + + /* compress until end of file */ + do { + strm.avail_in = inlen; + strm.next_in = (uint8_t*)in; + flush = Z_FINISH; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = ::deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = CHUNK - strm.avail_out; + dest.write( (char*)out,have); + if ( dest.fail() ) { + (void)deflateEnd(&strm); + free(out); + zerr(Z_ERRNO, err); + return false; + } + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)deflateEnd(&strm); + free(out); + return true; +} + +/* Decompress from file source to file dest until stream ends or EOF. + inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_DATA_ERROR if the deflate data is + invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and + the version of the library linked do not match, or Z_ERRNO if there + is an error reading or writing the files. */ +bool Misc::inflate(const uint8_t* in, size_t inlen, std::ostream& dest, string& err, int CHUNK) +{ + int ret; + unsigned have; + z_stream strm; + if ( CHUNK == -1 ) CHUNK = CL_Z_DEFAULT_CHUNK; + uint8_t* out = (uint8_t*)malloc(CHUNK); + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK){ + free(out); + zerr(ret, err); + return false; + } + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = inlen; + if (strm.avail_in == 0) + break; + strm.next_in = (uint8_t*)in; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = ::inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + free(out); + zerr(ret, err); + return false; + } + have = CHUNK - strm.avail_out; + dest.write( (char*)out,have); + if ( dest.fail() ) { + (void)inflateEnd(&strm); + free(out); + zerr(Z_ERRNO, err); + return false; + } + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + free(out); + if ( ret == Z_STREAM_END ) + return true; + zerr(Z_DATA_ERROR, err); + return false; +} + +//bool Misc::zstd_compress(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK, int level) +//{ +// size_t const cBuffSize = ZSTD_compressBound(sourcelen); +// void* cBuff = malloc(cBuffSize); +// if (!cBuff) +// { +// zerr(Z_MEM_ERROR, err); +// return false; +// } +// +// if ( level == -1 ) level = 3; +// +// size_t const cSize = ZSTD_compress(cBuff, cBuffSize, source, sourcelen, level); +// if (ZSTD_isError(cSize)) +// { +// zerr(Z_DATA_ERROR, err); +// return false; +// } +// +// dest.write((char *)cBuff, cSize); +// return true; +//} +// +//bool Misc::zstd_decompress(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK) +//{ +// unsigned long long const rSize = ZSTD_getFrameContentSize(source, sourcelen); +// void* rBuff = malloc(rSize); +// if (!rBuff) +// { +// zerr(Z_MEM_ERROR, err); +// return false; +// } +// +// size_t const dSize = ZSTD_decompress(rBuff, rSize, source, sourcelen); +// if (ZSTD_isError(dSize)) +// { +// zerr(Z_DATA_ERROR, err); +// return false; +// } +// +// dest.write((char *)rBuff, rSize); +// return true; +//} + +CL_NS_END diff --git a/src/shared/CLucene/util/Misc.h b/src/shared/CLucene/util/Misc.h new file mode 100644 index 00000000000..6518ab60c47 --- /dev/null +++ b/src/shared/CLucene/util/Misc.h @@ -0,0 +1,116 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_Misc_H +#define _lucene_util_Misc_H + +#include + +CL_NS_DEF(util) + /** A class containing various functions. + */ + class CLUCENE_SHARED_EXPORT Misc{ + static void zerr(int ret, std::string& err); + public: + static uint64_t currentTimeMillis(); + static const TCHAR* replace_all( const TCHAR* val, const TCHAR* srch, const TCHAR* repl ); + static bool dir_Exists(const char* path); + static int64_t file_Size(const char* path); + static int64_t filelength(int handle); + static void sleep(const int ms); + + /** + * Unlinks the given file, waits until dir_Exists is false. It makes maxAttempts + * attempts to remove the file. If maxAttemps is less than 0 then unlimited + * count of attempts is done. + * Returns 1 if deleted and dir_Exists returns false + * Returns 0 if deleted and dir_Exists returns still true + * Returns -1 if file can not be deleted. + */ + static int32_t file_Unlink(const char* path, int32_t maxAttempts = -1); + + static size_t ahashCode(const char* str); + static size_t ahashCode(const char* str, size_t len); + + static TCHAR* join ( const TCHAR* a, const TCHAR* b, const TCHAR* c=NULL, const TCHAR* d=NULL,const TCHAR* e=NULL,const TCHAR* f=NULL ); + static char* ajoin ( const char* a, const char* b, const char* c=NULL, const char* d=NULL,const char* e=NULL,const char* f=NULL ); + + static bool priv_isDotDir( const TCHAR* name ); + //Creates a filename by concatenating Segment with ext and x + static std::string segmentname(const char* segment, const char* ext, const int32_t x=-1 ); + //Creates a filename in buffer by concatenating Segment with ext and x + static void segmentname(char* buffer,int32_t bufferLen, const char* Segment, const char* ext, const int32_t x=-1); + + /** + * Compares two strings, character by character, and returns the + * first position where the two strings differ from one another. + * + * @param s1 The first string to compare + * @param s1Len The length of the first string to compare + * @param s2 The second string to compare + * @param s2Len The length of the second string to compare + * @return The first position where the two strings differ. + */ + static int32_t stringDifference(const TCHAR* s1, const int32_t s1Len, const TCHAR* s2, const int32_t s2Len); + + // In-place trimming for strings and words ("te st" will be returned by stringTrim, while wordTrim will return "te") + // This is by design only meant for use with on-memory strings, and calling it like stringTrim(_T("test")) will + // be errorneous + static TCHAR* stringTrim(TCHAR* s); + static TCHAR* wordTrim(TCHAR* s); + + static size_t longToBase( int64_t value, int32_t base, char* to ); //< length of to should be at least ((sizeof(unsigned long) << 3) + 1). returns actual length used + static int64_t base36ToLong( const char* value ); + + static std::string toString(const int32_t value); + static std::string toString(const int64_t value); + static std::string toString(const _LUCENE_THREADID_TYPE value); + static std::string toString(const bool value); + static std::string toString(const float_t value); + static std::string toString(const TCHAR* s, int32_t len=-1); + + template + static size_t swhashCode(const T* str, size_t len); + #ifdef _UCS2 + static size_t whashCode(const wchar_t* str); + static size_t whashCode(const wchar_t* str, size_t len); + #define thashCode whashCode + + static char* _wideToChar(const wchar_t* s); + static wchar_t* _charToWide(const char* s); + static wchar_t* _charToWide(const char* s, size_t len); + + static void _cpycharToWide(const char* s, wchar_t* d, size_t len); + static void _cpywideToChar(const wchar_t* s, char* d, size_t len); + #else + #define thashCode ahashCode + #endif + + /** List all files in dir. + * @param bool fullPath True to return entire path + */ + static bool listFiles(const char* dir, std::vector& files, bool fullPath=false); + static bool listDirs(const char* directory, std::vector& files, bool fullPath=false); + + + /** uncompress the source stream into the dest stream. + * Default CHUNK size is 1k + */ + static bool inflate(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK=-1); + /** compress the source stream into the dest stream. + * Default CHUNK size is 1k + * Default level is Z_BEST_COMPRESSION + */ + static bool deflate(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK=-1, int level=-1); + + // zstd compress and decompress + //static bool zstd_compress(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK=-1, int level=-1); + //static bool zstd_decompress(const uint8_t* source, size_t sourcelen, std::ostream& dest, std::string& err, int CHUNK=-1); + + }; + +CL_NS_END +#endif diff --git a/src/shared/CLucene/util/StringBuffer.cpp b/src/shared/CLucene/util/StringBuffer.cpp new file mode 100644 index 00000000000..f77d689a1b1 --- /dev/null +++ b/src/shared/CLucene/util/StringBuffer.cpp @@ -0,0 +1,430 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" +#include "StringBuffer.h" +#include "Misc.h" +#include + +#if defined(__i386__) || defined(__x86_64__) +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + +CL_NS_DEF(util) + + StringBuffer::StringBuffer(TCHAR* buf,size_t maxlen, const bool consumeBuffer){ + buffer = buf; + bufferLength = maxlen; + bufferOwner = !consumeBuffer; + len = 0; + } + StringBuffer::StringBuffer(){ + //Func - Constructor. Allocates a buffer with the default length. + //Pre - true + //Post - buffer of length bufferLength has been allocated + + //Initialize + bufferLength = LUCENE_DEFAULT_TOKEN_BUFFER_SIZE; + len = 0; + //Allocate a buffer of length bufferLength + buffer = _CL_NEWARRAY(TCHAR,bufferLength); + bufferOwner = true; + } + + StringBuffer::StringBuffer(const size_t initSize){ + //Func - Constructor. Allocates a buffer of length initSize + 1 + //Pre - initSize > 0 + //Post - A buffer has been allocated of length initSize + 1 + + //Initialize the bufferLength to initSize + 1 The +1 is for the terminator '\0' + bufferLength = initSize + 1; + len = 0; + //Allocate a buffer of length bufferLength + buffer = _CL_NEWARRAY(TCHAR,bufferLength); + bufferOwner = true; + } + + StringBuffer::StringBuffer(const TCHAR* value){ + //Func - Constructor. + // Creates an instance of Stringbuffer containing a copy of the string value + //Pre - value != NULL + //Post - An instance of StringBuffer has been created containing the copy of the string value + + //Initialize the length of the string to be stored in buffer + len = (size_t) _tcslen(value); + + //Calculate the space occupied in buffer by a copy of value + const size_t occupiedLength = len + 1; + + // Minimum allocated buffer length is LUCENE_DEFAULT_TOKEN_BUFFER_SIZE. + bufferLength = (occupiedLength >= LUCENE_DEFAULT_TOKEN_BUFFER_SIZE + ? occupiedLength : LUCENE_DEFAULT_TOKEN_BUFFER_SIZE); + + //Allocate a buffer of length bufferLength + buffer = _CL_NEWARRAY(TCHAR,bufferLength); + bufferOwner = true; + //Copy the string value into buffer + _tcsncpy(buffer, value, occupiedLength); + //Assert that the buffer has been terminated at the end of the string + CND_PRECONDITION (buffer[len] == '\0', "Buffer was not correctly terminated"); + } + + StringBuffer::~StringBuffer() { + // Func - Destructor + // Pre - true + // Post - Instanc has been destroyed + + if( bufferOwner ){ + _CLDELETE_CARRAY(buffer); + }else + buffer = NULL; + } + + void StringBuffer::clear(){ + //Func - Clears the Stringbuffer and resets it to it default empty state + //Pre - true + //Post - pre(buffer) has been destroyed and a new one has been allocated + + // TODO: Should we really delete and recreate the buffer - perhaps just reseting len should suffice? + // We should really look into at least providing both options + + //Destroy the current buffer if present + _CLDELETE_LCARRAY(buffer); + + //Initialize + len = 0; + bufferLength = LUCENE_DEFAULT_TOKEN_BUFFER_SIZE; + //Allocate a buffer of length bufferLength + buffer = _CL_NEWARRAY(TCHAR,bufferLength); + } + + void StringBuffer::appendChar(const TCHAR character) { + //Func - Appends a single character + //Pre - true + //Post - The character has been appended to the string in the buffer + + //Check if the current buffer length is sufficient to have the string value appended + if (len + 1 > bufferLength){ + //Have the size of the current string buffer increased because it is too small + growBuffer(len + 1); + } + //Put character at position len which is the end of the string in the buffer + //Note that this action might overwrite the terminator of the string '\0', which + //is kind of tricky + buffer[len] = character; + //Increase the len by to represent the correct length of the string in the buffer + len++; + } + + void StringBuffer::append(const TCHAR* value) { + //Func - Appends a copy of the string value + //Pre - value != NULL + //Post - value has been copied and appended to the string in buffer + + append(value, _tcslen(value)); + } + void StringBuffer::append(const TCHAR* value, size_t appendedLength) { + //Func - Appends a copy of the string value + //Pre - value != NULL + // appendedLength contains the length of the string value which is to be appended + //Post - value has been copied and appended to the string in buffer + + //Check if the current buffer length is sufficient to have the string value appended + if (len + appendedLength + 1 > bufferLength){ + //Have the size of the current string buffer increased because it is too small + growBuffer(len + appendedLength + 1); + } + + //Copy the string value into the buffer at postion len + _tcsncpy(buffer + len, value, appendedLength); + + //Add the length of the copied string to len to reflect the new length of the string in + //the buffer (Note: len is not the bufferlength!) + len += appendedLength; + } + + void StringBuffer::appendInt(const int64_t value, const int32_t _Radix) { + //Func - Appends an integer (after conversion to a character string) + //Pre - true + //Post - The converted integer value has been appended to the string in buffer + + //instantiate a buffer of 30 charactes for the conversion of the integer + TCHAR buf[30]; + //Convert the integer value to a string buf using _Radix + _i64tot(value, buf, _Radix); + //Have the converted integer now stored in buf appended to the string in buffer + append(buf); + } + + void StringBuffer::appendFloat(const float_t value, const size_t digits){ + //Func - Appends a float_t (after conversion to a character string) + //Pre - digits > 0. Indicates the minimum number of characters printed + //Post - The converted float_t value has been appended to the string in buffer + + //using sprintf("%f" was not reliable on other plaforms... we use a custom float convertor + //bvk: also, using sprintf and %f seems excessivelly slow + assert(digits <= 8); + + //the maximum number of characters that int64 will hold is 23. so we need 23*2+2 + TCHAR buf[48]; //the buffer to hold + int64_t v = (int64_t)value; //the integer value of the float + _i64tot(v,buf,10); //add the whole number + + size_t l = 99-_tcslen(buf); //how many digits we have to work with? + size_t dig = l< (size_t)digits ? l : digits; + if ( dig > 0 ){ + _tcscat(buf,_T(".")); //add a decimal point + + int64_t remi=(int64_t)((value-v)*pow((float_t)10,(float_t)(dig+1))); //take the remainder and make a whole number + if ( remi<0 ) remi*=-1; + int64_t remadj=remi/10; + if ( remi-(remadj*10) >=5 ) + remadj++; //adjust remainder + + // add as many zeros as necessary between the decimal point and the + // significant part of the number. Fixes a bug when trying to print + // numbers that have zeros right after the decimal point + if (remadj) { + size_t numZeros = dig - (size_t)log10((float_t)remadj) - 1; + while(numZeros-- > 0 && numZeros < 10) + _tcscat(buf,_T("0")); //add a zero before the decimal point + } + + _i64tot(remadj,buf+_tcslen(buf),10); //add the remainder + } + + append(buf); + } + + void StringBuffer::appendBoost(const float_t boost){ + if (boost != 1.0f) { + appendChar(_T('^')); appendFloat(boost,1); + } + } + + void StringBuffer::appendBool(const bool value){ + append( value ? _T( "true" ) : _T( "false" )); + } + + void StringBuffer::prepend(const TCHAR* value){ + //Func - Puts a copy of the string value infront of the current string in the StringBuffer + //Pre - value != NULL + //Post - The string in pre(buffer) has been shifted n positions where n equals the length of value. + // The string value was then copied to the beginning of stringbuffer + + prepend(value, _tcslen(value)); + } + + void StringBuffer::prepend(const TCHAR* value, const size_t prependedLength) { + //Func - Puts a copy of the string value in front of the string in the StringBuffer + //Pre - value != NULL + // prependedLength contains the length of the string value which is to be prepended + //Post - A copy of the string value is has been in front of the string in buffer + //todo: something is wrong with this code, i'm sure... it only grows (and therefore moves if the buffer is to small) + //Check if the current buffer length is sufficient to have the string value prepended + if (prependedLength + len + 1 > bufferLength){ + //Have the size of the current string buffer increased because it is too small + //Because prependedLength is passed as the second argument to growBuffer, + //growBuffer will have left the first prependedLength characters empty + //when it recopied buffer during reallocation. + growBuffer(prependedLength + len + 1, prependedLength); + } + + //Copy the string value into the buffer at postion 0 + _tcsncpy(buffer, value, prependedLength); + //Add the length of the copied string to len to reflect the new length of the string in + //the buffer (Note: len is not the bufferlength!) + len += prependedLength; + } + + size_t StringBuffer::length() const{ + //Func - Returns the length of the string in the StringBuffer + //Pre - true + //Post - The length len of the string in the buffer has been returned + + return len; + } + TCHAR* StringBuffer::toString(){ + //Func - Returns a copy of the current string in the StringBuffer sized equal to the length of the string + // in the StringBuffer. + //Pre - true + //Post - The copied string has been returned + + //Instantiate a buffer equal to the length len + 1 + TCHAR* ret = _CL_NEWARRAY(TCHAR,len + 1); + if (ret){ + //Copy the string in buffer + _tcsncpy(ret, buffer, len); + //terminate the string + ret[len] = '\0'; + } + //return the the copy + return ret; + } + TCHAR* StringBuffer::getBuffer() { + //Func - '\0' terminates the buffer and returns its pointer + //Pre - true + //Post - buffer has been '\0' terminated and returned + + // Check if the current buffer is '\0' terminated + if (len == bufferLength){ + //Make space for terminator, if necessary. + growBuffer(len + 1); + } + //'\0' buffer so it can be returned properly + buffer[len] = '\0'; + + return buffer; + } + + TCHAR* StringBuffer::giveBuffer() { + TCHAR* ret = getBuffer(); + buffer = NULL; + len = 0; + bufferLength = 0; + bufferOwner = false; + return ret; + } + + void StringBuffer::reserve(const size_t size){ + if ( bufferLength >= size ) + return; + bufferLength = size; + + //Allocate a new buffer of length bufferLength + TCHAR* tmp = _CL_NEWARRAY(TCHAR,bufferLength); + _tcsncpy(tmp, buffer, len); + tmp[len] = '\0'; + + //destroy the old buffer + if (buffer){ + _CLDELETE_CARRAY(buffer); + } + //Assign the new buffer tmp to buffer + buffer = tmp; + } + + void StringBuffer::growBuffer(const size_t minLength, const size_t skippingNInitialChars) { + //Func - Has the buffer grown to a minimum length of minLength or bigger and shifts the + // current string in buffer by skippingNInitialChars forward + //Pre - After growth, must have at least enough room for contents + terminator so + // minLength >= skippingNInitialChars + len + 1 + // skippingNInitialChars >= 0 + //Post - The buffer has been grown to a minimum length of minLength or bigger and + // if skippingNInitialChars > 0, the contents of the buffer has beeen shifted + // forward by skippingNInitialChars positions as the buffer is reallocated, + // leaving the first skippingNInitialChars uninitialized (presumably to be + // filled immediately thereafter by the caller). + + CND_PRECONDITION (minLength >= skippingNInitialChars + len + 1,"skippingNInitialChars is not large enough"); + + //More aggressive growth strategy to offset smaller default buffer size: + if ( !bufferOwner ){ + assert(bufferLength>=minLength); + return; + } + + bufferLength *= 2; + //Check that bufferLength is bigger than minLength + if (bufferLength < minLength){ + //Have bufferLength become minLength because it still was too small + bufferLength = minLength; + } + + //Allocate a new buffer of length bufferLength + TCHAR* tmp = _CL_NEWARRAY(TCHAR,bufferLength); + memset(tmp, 0, sizeof(TCHAR) * skippingNInitialChars); + + //The old buffer might not have been null-terminated, so we _tcsncpy + //only len bytes, not len+1 bytes (the latter might read one char off the + //end of the old buffer), then apply the terminator to the new buffer. + _tcsncpy(tmp + skippingNInitialChars, buffer, len); + tmp[skippingNInitialChars + len] = '\0'; + + //destroy the old buffer + _CLDELETE_LCARRAY(buffer); + + //Assign the new buffer tmp to buffer + buffer = tmp; + } + + void StringBuffer::setCharAt(size_t pos, const TCHAR chr) { + CND_PRECONDITION (pos < len, "pos is not in string"); + buffer[pos] = chr; + } + + TCHAR StringBuffer::charAt(size_t pos) { + CND_PRECONDITION (pos < len, "pos is not in string"); + return buffer[pos]; + } + + void StringBuffer::insert(const size_t pos, TCHAR chr) { + CND_PRECONDITION (pos <= len, "pos is larger than string len"); + growBuffer(len + 1, 0); + memmove(&buffer[pos + 1], &buffer[pos], sizeof(TCHAR) * (len - pos)); + buffer[pos] = chr; + len++; + } + + void StringBuffer::insert(const size_t pos, const TCHAR* chrs, size_t length) { + CND_PRECONDITION (pos <= len, "pos is larger than string len"); + + if (length == -1) { + length = _tcslen(chrs); + } + + if (length > 0) { + growBuffer(len + length, 0); + memmove(&buffer[pos + length], &buffer[pos], sizeof(TCHAR) * (len - pos)); + memcpy(&buffer[pos], chrs, sizeof(TCHAR) * (length)); + len += length; + } + } + + void StringBuffer::deleteCharAt(size_t pos) { + CND_PRECONDITION (pos < len, "pos is larger than string len"); + + memmove(&buffer[pos], &buffer[pos + 1], sizeof(TCHAR) * (len - pos)); + len--; + buffer[len] = _T('\0'); + } + + void StringBuffer::deleteChars(size_t start, size_t end) { + CND_PRECONDITION (start <= end && end <= len, "start/end is not in string"); + + if (start < end) { + memmove(&buffer[start], &buffer[end], sizeof(TCHAR) * (len - end)); + buffer[len - (end - start)] = _T('\0'); + len -= end - start; + } + } + + void StringBuffer::toLower() { + _tcslwr(buffer); + } + + bool StringBuffer::substringEquals(size_t start, size_t end, const TCHAR* str, size_t length) const { + if (length == -1) { + length = _tcslen(str); + } + + if (end - start != length) { + return false; + } + + for (size_t c = start; c < end; c++) { + if (buffer[c] != str[c - start]) { + return false; + } + } + + return true; + } + +CL_NS_END diff --git a/src/shared/CLucene/util/StringBuffer.h b/src/shared/CLucene/util/StringBuffer.h new file mode 100644 index 00000000000..52e4df484ed --- /dev/null +++ b/src/shared/CLucene/util/StringBuffer.h @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_util_StringBuffer_ +#define _lucene_util_StringBuffer_ + +CL_NS_DEF(util) + class CLUCENE_SHARED_EXPORT StringBuffer{ + public: + ///Constructor. Allocates a buffer with the default length. + StringBuffer(); + ///Constructor. Allocates a buffer of length initSize + 1 + StringBuffer(const size_t initSize); + ///Constructor. Creates an instance of Stringbuffer containing a copy of + ///the string value + StringBuffer(const TCHAR* value); + ///Constructs a StringBuffer using another buffer. The StringBuffer can + ///the be used to easily manipulate the buffer. + StringBuffer(TCHAR* buf,size_t maxlen, const bool consumeBuffer); + ///Destructor + virtual ~StringBuffer(); + ///Clears the Stringbuffer and resets it to it default empty state + void clear(); + + ///Appends a single character + void appendChar(const TCHAR chr); + ///Appends a copy of the string value + void append(const TCHAR* value); + ///Appends a copy of the string value + void append(const TCHAR* value, size_t appendedLength); + ///Appends an integer (after conversion to a character string) with a default radix of 10. Radixes lower than 10 not supported. + void appendInt(const int64_t value, const int32_t _Radix = 10); + ///Appends a float_t (after conversion to a character string) + void appendFloat(const float_t value, const size_t digits); + ///Appends a Lucene boost, formatted in the format used in the toString() functions; replaces JL's ToStringUtils::boost + void appendBoost(const float_t boost); + ///Appends a bool in the same way as java StringBuffer does (i.e. "true", "false" ) + void appendBool(const bool value); + ///Puts a copy of the string value in front of the current string in the StringBuffer + void prepend(const TCHAR* value); + ///Puts a copy of the string value in front of the current string in the StringBuffer + void prepend(const TCHAR* value, size_t prependedLength); + + StringBuffer& operator<< (const TCHAR* value) + { + append(value); + return *this; + } + StringBuffer& operator<< (const int64_t value) + { + appendInt(value); + return *this; + } + + void setCharAt(size_t pos, const TCHAR chr); + TCHAR charAt(size_t pos); + + void insert(const size_t pos, TCHAR chr); + void insert(const size_t pos, const TCHAR* chrs, size_t length = -1); + void deleteCharAt(size_t pos); + void deleteChars(size_t start, size_t end); + + void toLower(); + bool substringEquals(size_t start, size_t end, const TCHAR* str, size_t length = -1) const; + + ///Contains the length of string in the StringBuffer + ///Public so that analyzers can edit the length directly + size_t len; + ///Returns the length of the string in the StringBuffer + size_t length() const; + ///Returns a copy of the current string in the StringBuffer + TCHAR* toString(); + ///Returns a null terminated reference to the StringBuffer's text + TCHAR* getBuffer(); + /** Returns a null terminated reference to the StringBuffer's text + * the StringBuffer's buffer is released so that the text doesn't need to be copied + */ + TCHAR* giveBuffer(); + + ///reserve a minimum amount of data for the buffer. + ///no change made if the buffer is already longer than length + void reserve(const size_t length); + private: + ///A buffer that contains strings + TCHAR* buffer; + ///The length of the buffer + size_t bufferLength; + bool bufferOwner; + + ///Has the buffer grown to a minimum length of minLength or bigger and shifts the + ///current string in buffer by skippingNInitialChars forward + void growBuffer(const size_t minLength, const size_t skippingNInitialChars=0); + + }; +CL_NS_END +#endif diff --git a/src/shared/CLucene/util/deflate.cpp b/src/shared/CLucene/util/deflate.cpp new file mode 100644 index 00000000000..7f70ae230b2 --- /dev/null +++ b/src/shared/CLucene/util/deflate.cpp @@ -0,0 +1,1714 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id$ */ + +#include "zlib/deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size) +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_( + z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy, + const char *version, + int stream_size) +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary ( + z_streamp strm, + const Bytef *dictionary, + uInt dictLength +){ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); + dictionary += dictLength - length; /* use the tail of the dictionary */ + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (z_streamp strm) +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateSetHeader ( z_streamp strm, gz_headerp head) +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime ( + z_streamp strm, + int bits, + int value +){ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams( + z_streamp strm, + int level, + int strategy +){ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= */ +int ZEXPORT deflateTune( + z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain +){ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (deflate_state *s, uInt b) +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(z_streamp strm) +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (z_streamp strm, int flush) +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16) + ); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } +#ifdef GZIP + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; + + do { + if (s->pending == s->pending_buf_size) { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } +#endif + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (z_streamp strm) +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (z_streamp dest, z_streamp source) +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + zmemcpy(dest, source, sizeof(z_stream)); + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + zmemcpy(ds, ss, sizeof(deflate_state)); + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(z_streamp strm, Bytef *buf, unsigned size) +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (deflate_state *s) +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifndef FASTEST +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + /* %%% avoid this when Z_RLE */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ + +#if 0 +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +local block_state deflate_rle(s, flush) + deflate_state *s; + int flush; +{ + int bflush; /* set if current block must be flushed */ + uInt run; /* length of run */ + uInt max; /* maximum length of run */ + uInt prev; /* byte at distance one to match */ + Bytef *scan; /* scan for end of run */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest encodable run. + */ + if (s->lookahead < MAX_MATCH) { + fill_window(s); + if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + run = 0; + if (s->strstart > 0) { /* if there is a previous byte, that is */ + max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; + scan = s->window + s->strstart - 1; + prev = *scan++; + do { + if (*scan++ != prev) + break; + } while (++run < max); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (run >= MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, run); + _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); + s->lookahead -= run; + s->strstart += run; + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif diff --git a/src/shared/CLucene/util/dirent.cpp b/src/shared/CLucene/util/dirent.cpp new file mode 100644 index 00000000000..1216a67be42 --- /dev/null +++ b/src/shared/CLucene/util/dirent.cpp @@ -0,0 +1,224 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Matt J. Weinstein +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/_ApiHeader.h" + +#if !defined(_CL_HAVE_DIRENT_H) && !defined(_CL_HAVE_SYS_NDIR_H) && !defined(_CL_HAVE_SYS_DIR_H) && !defined(_CL_HAVE_NDIR_H) +#include "dirent.h" +#include +#include + + +DIR * +opendir (const char *szPath) +{ + DIR *nd; + char szFullPath[CL_MAX_PATH]; + + errno = 0; + + if (!szPath) + { + errno = EFAULT; + return NULL; + } + + if (szPath[0] == '\0') + { + errno = ENOTDIR; + return NULL; + } + + /* Attempt to determine if the given path really is a directory. */ + struct cl_stat_t rcs; + if ( fileStat(szPath,&rcs) == -1) + { + /* call GetLastError for more error info */ + errno = ENOENT; + return NULL; + } + if (!(rcs.st_mode & _S_IFDIR)) + { + /* Error, entry exists but not a directory. */ + errno = ENOTDIR; + return NULL; + } + + /* Make an absolute pathname. */ + _realpath(szPath,szFullPath); + + /* Allocate enough space to store DIR structure and the complete + * directory path given. */ + //nd = (DIR *) malloc (sizeof (DIR) + _tcslen (szFullPath) + _tcslen (DIRENT_SLASH) + + // _tcslen (DIRENT_SEARCH_SUFFIX)+1); + nd = new DIR; + + if (!nd) + { + /* Error, out of memory. */ + errno = ENOMEM; + return NULL; + } + + /* Create the search expression. */ + strcpy (nd->dd_name, szFullPath); + + /* Add on a slash if the path does not end with one. */ + if (nd->dd_name[0] != '\0' && + nd->dd_name[strlen (nd->dd_name) - 1] != '/' && + nd->dd_name[strlen (nd->dd_name) - 1] != '\\') + { + strcat (nd->dd_name, DIRENT_SLASH); + } + + /* Add on the search pattern */ + strcat (nd->dd_name, DIRENT_SEARCH_SUFFIX); + + /* Initialize handle to -1 so that a premature closedir doesn't try + * to call _findclose on it. */ + nd->dd_handle = -1; + + /* Initialize the status. */ + nd->dd_stat = 0; + + /* Initialize the dirent structure. ino and reclen are invalid under + * Win32, and name simply points at the appropriate part of the + * findfirst_t structure. */ + //nd->dd_dir.d_ino = 0; + //nd->dd_dir.d_reclen = 0; + nd->dd_dir.d_namlen = 0; + nd->dd_dir.d_name = nd->dd_dta.name; + + return nd; +} + + +struct dirent * readdir (DIR * dirp) +{ + errno = 0; + + /* Check for valid DIR struct. */ + if (!dirp) + { + errno = EFAULT; + return NULL; + } + + if (dirp->dd_dir.d_name != dirp->dd_dta.name) + { + /* The structure does not seem to be set up correctly. */ + errno = EINVAL; + return NULL; + } + + bool bCallFindNext = true; + + if (dirp->dd_stat < 0) + { + /* We have already returned all files in the directory + * (or the structure has an invalid dd_stat). */ + return NULL; + } + else if (dirp->dd_stat == 0) + { + /* We haven't started the search yet. */ + /* Start the search */ + dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta)); + + if (dirp->dd_handle == -1) + { + /* Whoops! Seems there are no files in that + * directory. */ + dirp->dd_stat = -1; + } + else + { + dirp->dd_stat = 1; + } + + /* Dont call _findnext first time. */ + bCallFindNext = false; + } + + while (dirp->dd_stat > 0) + { + if (bCallFindNext) + { + /* Get the next search entry. */ + if (_findnext (dirp->dd_handle, &(dirp->dd_dta))) + { + /* We are off the end or otherwise error. */ + _findclose (dirp->dd_handle); + dirp->dd_handle = -1; + dirp->dd_stat = -1; + return NULL; + } + else + { + /* Update the status to indicate the correct + * number. */ + dirp->dd_stat++; + } + } + + /* Successfully got an entry. Everything about the file is + * already appropriately filled in except the length of the + * file name. */ + dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name); + + bool bThisFolderOrUpFolder = dirp->dd_dir.d_name[0] == '.' && + (dirp->dd_dir.d_name[1] == 0 || (dirp->dd_dir.d_name[1] == '.' && dirp->dd_dir.d_name[2] == 0)); + + if (!bThisFolderOrUpFolder) + { + struct cl_stat_t buf; + char buffer[CL_MAX_DIR]; + size_t bl = strlen(dirp->dd_name)-strlen(DIRENT_SEARCH_SUFFIX); + strncpy(buffer,dirp->dd_name,bl); + buffer[bl]=0; + strcat(buffer, dirp->dd_dir.d_name); + if ( fileStat(buffer,&buf) == 0 ) + { + /* Finally we have a valid entry. */ + return &dirp->dd_dir; + } + } + + /* Allow to find next file. */ + bCallFindNext = true; + } + + return NULL; +} + + + +int32_t +closedir (DIR * dirp) +{ + int32_t rc; + + errno = 0; + rc = 0; + + if (!dirp) + { + errno = EFAULT; + return -1; + } + + if (dirp->dd_handle != -1) + { + rc = _findclose (dirp->dd_handle); + } + + /* Delete the dir structure. */ + _CLVDELETE(dirp); + + return rc; +} +#endif //HAVE_DIRENT_H + diff --git a/src/shared/CLucene/util/dirent.h b/src/shared/CLucene/util/dirent.h new file mode 100644 index 00000000000..46668ec9a55 --- /dev/null +++ b/src/shared/CLucene/util/dirent.h @@ -0,0 +1,109 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Matt J. Weinstein +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef lucene_util_dirent_H +#define lucene_util_dirent_H + + +#if !defined(_CL_HAVE_DIRENT_H) && !defined(_CL_HAVE_SYS_NDIR_H) && !defined(_CL_HAVE_SYS_DIR_H) && !defined(_CL_HAVE_NDIR_H) + +#ifdef _WIN64 + typedef __int64 intptr_t; +#else + typedef int intptr_t; +#endif +#include + + +/** + * dirent.c + * + * Derived from DIRLIB.C by Matt J. Weinstein + * This note appears in the DIRLIB.H + * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 + * + * Updated by Jeremy Bettis + * Significantly revised and rewinddir, seekdir and telldir added by Colin + * Cut down again & changed by Ben van Klinken + * Peters + * + */ + +/** dirent structure - used by the dirent.h directory iteration functions */ +struct CLUCENE_SHARED_INLINE_EXPORT dirent +{ + unsigned short d_namlen; /* Length of name in d_name. */ + char *d_name; /* File name. */ +}; + +/** DIR structure - used by the dirent.h directory iteration functions*/ +struct CLUCENE_SHARED_INLINE_EXPORT DIR +{ + /** disk transfer area for this dir */ + struct _finddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct dirent dd_dir; + + /** _findnext handle */ + intptr_t dd_handle; + + /** + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + int32_t dd_stat; + + /** given path for dir with search pattern (struct is extended) */ + char dd_name[CL_MAX_DIR]; + +}; + +#define DIRENT_SEARCH_SUFFIX "*" +#define DIRENT_SLASH PATH_DELIMITERA + + +/** +* Returns a pointer to a DIR structure appropriately filled in to begin +* searching a directory. +*/ +CLUCENE_SHARED_EXPORT DIR* opendir (const char* filespec); + +/** +* Return a pointer to a dirent structure filled with the information on the +* next entry in the directory. +*/ +CLUCENE_SHARED_EXPORT struct dirent* readdir (DIR* dir); + +/** +* Frees up resources allocated by opendir. +*/ +CLUCENE_SHARED_EXPORT int32_t closedir (DIR* dir); + + +#elif defined (_CL_HAVE_DIRENT_H) +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) + +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if defined(_CL_HAVE_SYS_NDIR_H) +# include +# endif +# if defined(_CL_HHAVE_SYS_DIR_H) +# include +# endif +# if defined(_CL_HHAVE_NDIR_H) +# include +# endif + +#endif //HAVE_DIRENT_H +#endif diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt new file mode 100644 index 00000000000..2369234e721 --- /dev/null +++ b/src/shared/CMakeLists.txt @@ -0,0 +1,375 @@ +PROJECT(clucene-shared) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${clucene_SOURCE_DIR}/cmake" "${clucene-shared_SOURCE_DIR}/cmake") + +#define command line options +INCLUDE (DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS} -DMAKE_CLUCENE_SHARED_LIB) + +# include specific modules +set(CMAKE_MODULE_PATH "${clucene-shared_SOURCE_DIR}/cmake") + +INCLUDE (CheckIncludeFiles) +INCLUDE (CheckIncludeFileCXX) +INCLUDE (CheckCXXSourceCompiles) +INCLUDE (CheckCXXSourceRuns) +INCLUDE (CheckFunctionExists) + +#local macros +INCLUDE (MacroMustDefine) +INCLUDE (MacroChooseType) +INCLUDE (MacroChooseMisc) +INCLUDE (MacroChooseFunction) +INCLUDE (MacroChooseSymbol) +INCLUDE (MacroCheckGccVisibility) + +INCLUDE (DefineFloat) +INCLUDE (DefineDword) +INCLUDE (DefineLongLongSyntax) +INCLUDE (DefineStaticSyntax) +INCLUDE (DefineMAXPATHValue) + +INCLUDE (CheckFloatByte) +INCLUDE (CheckErrorHandling) +INCLUDE (CheckHashmaps) +INCLUDE (CheckNamespace) +INCLUDE (CheckSnprintf) +INCLUDE (CheckStdCallFunctionExists) + +find_package(Threads REQUIRED) +INCLUDE (CheckPthread) +INCLUDE (CheckAtomicFunctions) + +if (NOT USE_INTERNAL_ZLIB_LIBRARY) + find_package (ZLIB) +endif () +IF ( ZLIB_FOUND ) + SET ( EXTRA_LIBS ${EXTRA_LIBS} ${ZLIB_LIBRARY} ) +ELSE ( ZLIB_FOUND ) + MESSAGE( "ZLIB not found, using local: ${clucene-ext_SOURCE_DIR}/zlib" ) + SET(ZLIB_INCLUDE_DIR ${clucene-ext_SOURCE_DIR}/zlib ) + SET(ZLIB_LIBRARY ${clucene-ext_BINARY_DIR}) +ENDIF ( ZLIB_FOUND ) +INCLUDE_DIRECTORIES( ${ZLIB_INCLUDE_DIR} ) + +#include(../../cmake/zstd.cmake) +#IF ( ZSTD_LIBRARY ) +# SET ( EXTRA_LIBS ${EXTRA_LIBS} ${ZSTD_LIBRARY} ) +# MESSAGE( "ZSTD found, using : ${ZSTD_LIBRARY} ${ZSTD_INCLUDE_DIR}" ) +#ELSE ( ZSTD_LIBRARY ) +# MESSAGE( "ZSTD not found, using local: ${clucene-ext_SOURCE_DIR}/zstd" ) +# SET(ZSTD_INCLUDE_DIR ${clucene-ext_SOURCE_DIR}/zlib ) +# SET(ZSTD_LIBRARY ${clucene-ext_BINARY_DIR}) +#ENDIF ( ZSTD_LIBRARY ) +#INCLUDE_DIRECTORIES( ${ZSTD_INCLUDE_DIR} ) + +######################################################################## +# test for headers +######################################################################## + +CHECK_INCLUDE_FILES ("sys/time.h;time.h" _CL_TIME_WITH_SYS_TIME) + +CHECK_REQUIRED_HEADERS ( stdlib.h stdarg.h stdio.h stddef.h ctype.h algorithm + functional map vector list set math.h fcntl.h limits.h) + +CHECK_OPTIONAL_HEADERS ( string.h sys/time.h memory.h sys/types.h + stdint.h unistd.h io.h direct.h sys/dir.h sys/ndir.h dirent.h wctype.h fcntl.h + stat.h sys/stat.h stdexcept errno.h fcntl.h windef.h windows.h wchar.h + hash_map hash_set ext/hash_map ext/hash_map tr1/unordered_set tr1/unordered_map + sys/timeb.h tchar.h strings.h stdexcept sys/mman.h winerror.h ) + + +######################################################################## +# test for types +######################################################################## +#find int_t types +CHOOSE_TYPE(int8_t 1 signed "int8_t;char") +CHOOSE_TYPE(uint8_t 1 unsigned "uint8_t;char") +CHOOSE_TYPE(int16_t 2 signed "int16_t;short") +CHOOSE_TYPE(uint16_t 2 unsigned "uint16_t;short") +CHOOSE_TYPE(int32_t 4 signed "int32_t;int;long") +CHOOSE_TYPE(uint32_t 4 unsigned "uint32_t;int;long") +CHOOSE_TYPE(int64_t 8 signed "int64_t;long long;__int64") +CHOOSE_TYPE(uint64_t 8 unsigned "uint64_t;long long;__int64") + +CHOOSE_TYPE(size_t -1 unsigned "size_t;int" ) +CHOOSE_MISC(TYPE__TIMEB + HAVE_TYPE__TIMEB + "struct _timeb x\;" "/* #undef _timeb */" "_timeb" + "struct timeb x\;" "#define _timeb timeb" "timeb" + ) + +#run macro for checking float. (and _FLT_EVAL_METHOD) +DEFINE_FLOAT() +DEFINE_DWORD() + +######################################################################## +# Test for functions +######################################################################## + + +CHECK_REQUIRED_FUNCTIONS( printf strftime wcscpy wcsncpy wcscat wcschr wcsstr wcslen + wcscmp wcsncmp wcscspn ) + +#todo: wcstoq is bsd equiv of wcstoll, we can use that... +CHECK_OPTIONAL_FUNCTIONS( wcsupr wcscasecmp wcsicmp wcstoll wprintf lltow + wcstod wcsdup strupr strlwr lltoa strtoll gettimeofday _vsnwprintf mmap "MapViewOfFile(0,0,0,0,0)" +) + +#make decisions about which functions to use... +CHOOSE_FUNCTION(fileHandleStat "fstati64;_fstati64;fstat64;fstat;_fstat") +IF ( _CL_HAVE_FUNCTION_FSTATI64 OR _CL_HAVE_FUNCTION__FSTATI64 OR _CL_HAVE_FUNCTION_FSTAT64 ) + SET ( USE_STAT64 1 ) +ENDIF ( _CL_HAVE_FUNCTION_FSTATI64 OR _CL_HAVE_FUNCTION__FSTATI64 OR _CL_HAVE_FUNCTION_FSTAT64 ) + +IF ( USE_STAT64 ) + CHOOSE_FUNCTION(fileStat "stati64;_stati64;stat64;stat;_stat") + CHOOSE_FUNCTION(fileSize "filelengthi64;_filelengthi64;filelength;_filelength" "#define fileSize CL_NS(util)::Misc::filelength") + CHOOSE_FUNCTION(fileSeek "lseeki64;_lseeki64;lseek64;lseek;_lseek") + CHOOSE_MISC(TYPE_CL_STAT_T + HAVE_TYPE_CL_STAT_T + "struct stati64 x\;" "#define cl_stat_t stati64" "stati64" + "struct _stati64 x\;" "#define cl_stat_t _stati64" "_stati64" + "struct stat64 x\;" "#define cl_stat_t stat64" "stat64" + "struct stat x\;" "#define cl_stat_t stat" "stat" + "struct _stat x\;" "#define cl_stat_t _stat" "_stat" + ) +ELSE( USE_STAT64 ) + #borland doesn't have a fstat64, so we have to fallback to non 64 bit everything... + CHOOSE_FUNCTION(fileStat "stat;_stat") + CHOOSE_FUNCTION(fileSize "filelength;_filelength" "#define fileSize CL_NS(util)::Misc::filelength") + CHOOSE_FUNCTION(fileSeek "lseek;_lseek") + CHOOSE_MISC(TYPE_CL_STAT_T + HAVE_TYPE_CL_STAT_T + "struct stat x\;" "#define cl_stat_t stat" "stat" + "struct _stat x\;" "#define cl_stat_t _stat" "_stat" + ) +ENDIF( USE_STAT64 ) + +#ftell (and probably soon ftell64) are POSIX standard functions, but tell and +#tell64 are not, so we define fileTell in terms of fileSeek. +CHOOSE_FUNCTION(fileTell "telli64;_telli64;tell64;tell;_tell" "#define fileTell(fhandle) fileSeek(fhandle, 0, SEEK_CUR)") + +CHOOSE_FUNCTION(_realpath "realpath" "#define _realpath(rel,abs) ::_fullpath(abs,rel,CL_MAX_PATH)") +CHOOSE_FUNCTION(_rename "rename") +CHOOSE_FUNCTION(_close "_close((int)0);close") +CHOOSE_FUNCTION(_read "_read((int)0, (void*)0, (unsigned int)0);read") +CHOOSE_FUNCTION(_cl_open "_open(0,0,0);open") +CHOOSE_FUNCTION(_write "_write((int)0, (const void*)0, (unsigned int)0);write") +CHOOSE_FUNCTION(_unlink "_unlink((const char*)0);unlink") +CHOOSE_FUNCTION(_ftime "_ftime(0);ftime") +CHOOSE_FUNCTION(_mkdir "_mkdir((const char*)0)" "#define _mkdir(x) mkdir(x,0777)") +CHOOSE_FUNCTION(SLEEPFUNCTION "usleep;Sleep(0);_sleep") + +CHOOSE_FUNCTION(_snprintf "snprintf;_snprintf") +CHOOSE_FUNCTION(_snwprintf "snwprintf;_snwprintf") + +######################################################################## +# test for symbols +######################################################################## +CHOOSE_SYMBOL (_O_RANDOM "_O_RANDOM;O_RANDOM") +CHOOSE_SYMBOL (_O_BINARY "_O_BINARY;O_BINARY") +CHOOSE_SYMBOL (_S_IREAD "_S_IREAD;S_IREAD") +CHOOSE_SYMBOL (_S_IWRITE "_S_IWRITE;S_IWRITE") + + +#define defaults +IF ( NOT HAVE_SYMBOL__O_RANDOM ) + SET (SYMBOL__O_RANDOM "#define _O_RANDOM 0") +ENDIF ( NOT HAVE_SYMBOL__O_RANDOM ) + +IF ( NOT HAVE_SYMBOL__O_BINARY ) + SET (SYMBOL__O_BINARY "#define _O_BINARY 0") +ENDIF ( NOT HAVE_SYMBOL__O_BINARY) + +IF ( NOT HAVE_SYMBOL__S_IREAD ) + SET (SYMBOL__S_IREAD "#define _S_IREAD 0333") +ENDIF ( NOT HAVE_SYMBOL__S_IREAD ) + +IF ( NOT HAVE_SYMBOL__S_IWRITE ) + SET (SYMBOL__S_IWRITE "#define _S_IWRITE 0333") +ENDIF ( NOT HAVE_SYMBOL__S_IWRITE ) + +#try and figure out the actual value of what _CL_MAX_PATH is +DEFINE_MAXPATH_VALUE (SYMBOL_CL_MAX_PATH) + + +######################################################################## +# test for tchar replacments +######################################################################## +IF ( ENABLE_ASCII_MODE ) + CHOOSE_TYPE(TCHAR 1 "" "TCHAR;char" SYMBOL_TCHAR ) +ELSE ( ENABLE_ASCII_MODE ) + CHOOSE_TYPE(TCHAR -1 "" "TCHAR;wchar_t;unsigned short" SYMBOL_TCHAR) +ENDIF ( ENABLE_ASCII_MODE ) +IF ( NOT SYMBOL_TCHAR STREQUAL "TCHAR" ) + SET( SYMBOL_TCHAR "#define TCHAR ${SYMBOL_TCHAR}" ) +ELSE ( NOT SYMBOL_TCHAR STREQUAL "TCHAR" ) + SET( SYMBOL_TCHAR "/* #undef TCHAR */" ) +ENDIF ( NOT SYMBOL_TCHAR STREQUAL "TCHAR" ) + +CHOOSE_SYMBOL (_T "_T" SYMBOL__T) +IF ( NOT HAVE_SYMBOL__T ) +IF ( ENABLE_ASCII_MODE ) + SET (SYMBOL__T "#define _T(x) x") +ELSE ( ENABLE_ASCII_MODE ) + SET (SYMBOL__T "#define _T(x) L ## x") +ENDIF ( ENABLE_ASCII_MODE ) +ELSE ( NOT HAVE_SYMBOL__T ) + SET( SYMBOL__T "/* #undef _T */" ) +ENDIF ( NOT HAVE_SYMBOL__T ) + + +######################################################################## +# test for compiler capabilities. +######################################################################## + +#check for pthreads +IF ( CMAKE_USE_WIN32_THREADS_INIT ) + SET ( _CL_HAVE_WIN32_THREADS 1 ) +ENDIF ( CMAKE_USE_WIN32_THREADS_INIT ) +IF ( CMAKE_USE_PTHREADS_INIT ) + SET ( _CL_HAVE_PTHREAD 1 ) +ENDIF (CMAKE_USE_PTHREADS_INIT) +IF ( CMAKE_USE_SPROC_INIT OR CMAKE_HP_PTHREADS_INIT ) + MESSAGE(FATAL_ERROR "Threads library not implemented") +ENDIF( CMAKE_USE_SPROC_INIT OR CMAKE_HP_PTHREADS_INIT ) + +#define if we have pthreads with recursive capabilities +CHECK_PTHREAD_RECURSIVE(_CL_HAVE_PTHREAD _CL_HAVE_PTHREAD_MUTEX_RECURSIVE) + +CHECK_HAVE_GCC_ATOMIC_FUNCTIONS(_CL_HAVE_GCC_ATOMIC_FUNCTIONS) + +#see if we can hide all symbols by default... +MACRO_CHECK_GCC_VISIBILITY(_CL_HAVE_GCCVISIBILITYPATCH) + +#Check that we can handle try/catch +CHECK_HAVE_FUNCTION_TRY_BLOCKS (_CL_HAVE_TRY_BLOCKS) + +#check that we support new float byte<->float conversions +CHECK_FLOAT_BYTE_WORKS(_CL_HAVE_NO_FLOAT_BYTE, 1) + +#check how to use hashmaps +CHECK_HASH_MAPS (CL_NS_HASHING_VALUE LUCENE_DISABLE_HASHING) + +#check that we have namespace support +CHECK_NAMESPACE (_CL_HAVE_NAMESPACES) + +#check if snprintf functions are buggy +CHECK_SNPRINTF() + +#define how we are going to define 64bit numbers +DEFINE_LONGLONG_SYNTAX() + +#define how to define a static const (or fallback to enum) +DEFINE_STATIC_SYNTAX() + +#test for ansi for scope (needed for msvc6) +INCLUDE(TestForANSIForScope) +IF ( CMAKE_ANSI_FOR_SCOPE ) + SET ( CMAKE_ANSI_FOR_SCOPE 1 ) +ELSE ( CMAKE_ANSI_FOR_SCOPE ) + SET ( CMAKE_ANSI_FOR_SCOPE 0 ) +ENDIF ( CMAKE_ANSI_FOR_SCOPE ) + + +#check that all these definitions are set, or fail... +MUSTDEFINE_VAR("HAVE_TYPE_INT8_T;HAVE_TYPE_UINT8_T;HAVE_TYPE_INT16_T;HAVE_TYPE_UINT16_T;HAVE_TYPE_UINT16_T;" ) +MUSTDEFINE_VAR("HAVE_TYPE_INT32_T;HAVE_TYPE_UINT32_T;HAVE_TYPE_INT64_T;HAVE_TYPE_UINT64_T;HAVE_TYPE_SIZE_T;HAVE_TYPE_CL_STAT_T") +MUSTDEFINE_VAR("_CL_HAVE_TRY_BLOCKS") + +#must have timeb OR GETTIMEOFDAY +IF ( NOT HAVE_TYPE__TIMEB AND NOT _CL_HAVE_FUNCTION_GETTIMEOFDAY ) + MESSAGE( FATAL_ERROR "timeb or gettimeofday must be available." ) +ENDIF ( NOT HAVE_TYPE__TIMEB AND NOT _CL_HAVE_FUNCTION_GETTIMEOFDAY ) + +#now write out our configuration.... +CONFIGURE_FILE(${clucene-shared_SOURCE_DIR}/CLucene/clucene-config.h.cmake ${clucene-shared_BINARY_DIR}/CLucene/clucene-config.h) +CONFIGURE_FILE(${clucene-shared_SOURCE_DIR}/CLucene/_clucene-config.h.cmake ${clucene-shared_BINARY_DIR}/CLucene/_clucene-config.h) +CONFIGURE_FILE(${clucene-shared_SOURCE_DIR}/CLucene/util/Misc.h ${clucene-shared_BINARY_DIR}/CLucene/util/Misc.h) + +#add the files to our groups +SOURCE_GROUP("config" ./CLucene/config/*) +SOURCE_GROUP("debug" ./CLucene/debug/*) +SOURCE_GROUP("util" ./CLucene/util/*) +SOURCE_GROUP("zlib" ./zlib/*) + +MACRO (GET_SHARED_FILES result) + IF ( "" STREQUAL "${ARGV2}" ) + SET ( rel ${clucene-shared_SOURCE_DIR} ) + ELSE ( "" STREQUAL "${ARGV2}" ) + SET ( rel ${ARGV2} ) + ENDIF ( "" STREQUAL "${ARGV2}" ) + + SET(${result} + ${rel}/CLucene/SharedHeader.cpp + ${rel}/CLucene/config/gunichartables.cpp + ${rel}/CLucene/config/repl_tcslwr.cpp + ${rel}/CLucene/config/repl_tcstoll.cpp + ${rel}/CLucene/config/repl_tcscasecmp.cpp + ${rel}/CLucene/config/repl_tprintf.cpp + ${rel}/CLucene/config/repl_lltot.cpp + ${rel}/CLucene/config/repl_tcstod.cpp + ${rel}/CLucene/config/utf8.cpp + ${rel}/CLucene/config/threads.cpp + ${rel}/CLucene/debug/condition.cpp + ${rel}/CLucene/util/StringBuffer.cpp + ${rel}/CLucene/util/Misc.cpp + ${rel}/CLucene/util/dirent.cpp + ) + + IF ( NOT ZLIB_FOUND ) + SET(${result} ${${result}} + ${clucene-ext_SOURCE_DIR}/zlib/adler32.c + ${clucene-ext_SOURCE_DIR}/zlib/compress.c + ${clucene-ext_SOURCE_DIR}/zlib/crc32.c + ${clucene-ext_SOURCE_DIR}/zlib/deflate.c + ${clucene-ext_SOURCE_DIR}/zlib/gzio.c + ${clucene-ext_SOURCE_DIR}/zlib/inffast.c + ${clucene-ext_SOURCE_DIR}/zlib/inflate.c + ${clucene-ext_SOURCE_DIR}/zlib/inftrees.c + ${clucene-ext_SOURCE_DIR}/zlib/trees.c + ${clucene-ext_SOURCE_DIR}/zlib/zutil.c + ) + ENDIF ( NOT ZLIB_FOUND ) +ENDMACRO (GET_SHARED_FILES) + +GET_SHARED_FILES(clucene_shared_Files ".") + +#find our headers +file(GLOB_RECURSE HEADERS ${clucene-shared_SOURCE_DIR}/*.h) + +add_library(clucene-shared SHARED + ${clucene_shared_Files} ${HEADERS} +) + +#set properties on the libraries +SET_TARGET_PROPERTIES(clucene-shared PROPERTIES + VERSION ${CLUCENE_VERSION} + SOVERSION ${CLUCENE_SOVERSION} + COMPILE_DEFINITIONS_DEBUG _DEBUG +) +TARGET_LINK_LIBRARIES(clucene-shared ${CMAKE_THREAD_LIBS_INIT}) +IF ( EXTRA_LIBS ) + TARGET_LINK_LIBRARIES(clucene-shared ${EXTRA_LIBS}) +ENDIF ( EXTRA_LIBS ) + +install(TARGETS clucene-shared + DESTINATION ${LIB_DESTINATION} + COMPONENT development ) + +IF ( BUILD_STATIC_LIBRARIES ) + add_library(clucene-shared-static STATIC + ${clucene_shared_Files} ${HEADERS} + ) + + SET_TARGET_PROPERTIES(clucene-shared-static PROPERTIES + VERSION ${CLUCENE_VERSION} + SOVERSION ${CLUCENE_SOVERSION} + COMPILE_DEFINITIONS_DEBUG _DEBUG + ) + TARGET_LINK_LIBRARIES(clucene-shared-static ${CMAKE_THREAD_LIBS_INIT}) + install(TARGETS clucene-shared-static + DESTINATION ${LIB_DESTINATION} + COMPONENT runtime ) +ENDIF ( BUILD_STATIC_LIBRARIES ) diff --git a/src/shared/README b/src/shared/README new file mode 100644 index 00000000000..508a9dbc563 --- /dev/null +++ b/src/shared/README @@ -0,0 +1,5 @@ +This package creates a library that is used in all the CLucene projects. It provides +cross-platform macros and functions that used to be inside CLucene. Since we need +to be able to link against the shared clucene-core library, we need these functions +to be seperate. They provide things like cl_* string macros, file handling functions, +replacement functions, etc. diff --git a/src/shared/cmake/CheckAtomicFunctions.cmake b/src/shared/cmake/CheckAtomicFunctions.cmake new file mode 100644 index 00000000000..e63f0891e38 --- /dev/null +++ b/src/shared/cmake/CheckAtomicFunctions.cmake @@ -0,0 +1,25 @@ +INCLUDE(CheckCXXSourceRuns) + +MACRO ( CHECK_HAVE_GCC_ATOMIC_FUNCTIONS result ) + +# Do step by step checking, +CHECK_CXX_SOURCE_RUNS(" +#include +int main() +{ + unsigned value = 0; + void* ptr = &value; + __sync_add_and_fetch(&value, 1); + __sync_synchronize(); + __sync_sub_and_fetch(&value, 1); + if (!__sync_bool_compare_and_swap(&value, 0, 1)) + return EXIT_FAILURE; + + if (!__sync_bool_compare_and_swap(&ptr, ptr, ptr)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} +" ${result} ) + +ENDMACRO ( CHECK_HAVE_GCC_ATOMIC_FUNCTIONS result ) diff --git a/src/shared/cmake/CheckErrorHandling.cmake b/src/shared/cmake/CheckErrorHandling.cmake new file mode 100644 index 00000000000..e60a49167d1 --- /dev/null +++ b/src/shared/cmake/CheckErrorHandling.cmake @@ -0,0 +1,12 @@ +#check if we can do try and catch. +#bit useless, since we don't have any alternatives to try and catch currently + +MACRO ( CHECK_HAVE_FUNCTION_TRY_BLOCKS result ) + #check for try/catch blocks + CHECK_CXX_SOURCE_RUNS(" + void foo() { try{ return; } catch( ... ){} } + int main(){ foo(); return 0; }" ${result}) + IF ( NOT ${result} ) + SET ( ${result} 1 FORCE) + ENDIF ( NOT ${result} ) +ENDMACRO ( CHECK_HAVE_FUNCTION_TRY_BLOCKS ) diff --git a/src/shared/cmake/CheckFloatByte.cmake b/src/shared/cmake/CheckFloatByte.cmake new file mode 100644 index 00000000000..3faa3444972 --- /dev/null +++ b/src/shared/cmake/CheckFloatByte.cmake @@ -0,0 +1,37 @@ +# - Check if our methods for converting from floats to bytes and back work. +# CHECK_FLOAT_BYTE_WORKS(RESULT reverse) +# reverse: set to false if the check succeeds +# +# CMAKE_REQUIRED_FLAGS = string of compile command line flags +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +# CMAKE_REQUIRED_INCLUDES = list of include directories +# CMAKE_REQUIRED_LIBRARIES = list of libraries to link +# CMAKE_EXTRA_INCLUDE_FILES = list of extra includes to check in + +MACRO(CHECK_FLOAT_BYTE_WORKS RESULT reverse) + IF("${RESULT}" MATCHES "^${RESULT}$") + MESSAGE(STATUS "Checking support new float byte<->float conversions") + + CONFIGURE_FILE("${clucene-shared_SOURCE_DIR}/cmake/CheckFloatByte.cpp.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckFloatByte.cpp" IMMEDIATE @ONLY) + + TRY_COMPILE(${RESULT} + ${CMAKE_BINARY_DIR} + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckFloatByte.cpp" + OUTPUT_VARIABLE OUTPUT) + IF(${RESULT}) + MESSAGE(STATUS "Checking support new float byte<->float conversions - yes") + ELSE(${RESULT}) + MESSAGE(STATUS "Checking support new float byte<->float conversions - no") + ENDIF(${RESULT}) + + #reverse decision if required. + IF (${reverse}) + IF (${RESULT}) + SET ( ${RESULT} 0 ) + ELSE (${RESULT}) + SET ( ${RESULT} 1 ) + ENDIF (${RESULT}) + ENDIF (${reverse}) + ENDIF("${RESULT}" MATCHES "^${RESULT}$") +ENDMACRO(CHECK_FLOAT_BYTE_WORKS) diff --git a/src/shared/cmake/CheckFloatByte.cpp.in b/src/shared/cmake/CheckFloatByte.cpp.in new file mode 100644 index 00000000000..4bf6e592853 --- /dev/null +++ b/src/shared/cmake/CheckFloatByte.cpp.in @@ -0,0 +1,81 @@ + typedef long double float_t; + typedef long int32_t; + typedef char uint8_t; + + //float to bits conversion utilities... + union clvalue { + int32_t i; + float f; //must use a float type, else types dont match up + }; + + int32_t floatToIntBits(float_t value) + { + clvalue u; + int32_t e, f; + u.f = value; + e = u.i & 0x7f800000; + f = u.i & 0x007fffff; + + if (e == 0x7f800000 && f != 0) + u.i = 0x7fc00000; + + return u.i; + } + float_t intBitsToFloat(int32_t bits) + { + clvalue u; + u.i = bits; + return u.f; + } + + float_t byteToFloat(uint8_t b) { + if (b == 0) // zero is a special case + return 0.0f; + int32_t mantissa = b & 7; + int32_t exponent = (b >> 3) & 31; + int32_t bits = ((exponent+(63-15)) << 24) | (mantissa << 21); + return intBitsToFloat(bits); + } + + uint8_t floatToByte(float_t f) { + if (f < 0.0f) // round negatives up to zero + f = 0.0f; + + if (f == 0.0f) // zero is a special case + return 0; + + int32_t bits = floatToIntBits(f); // parse float_t into parts + int32_t mantissa = (bits & 0xffffff) >> 21; + int32_t exponent = (((bits >> 24) & 0x7f) - 63) + 15; + + if (exponent > 31) { // overflow: use max value + exponent = 31; + mantissa = 7; + } + + if (exponent < 0) { // underflow: use min value + exponent = 0; + mantissa = 1; + } + + return (uint8_t)((exponent << 3) | mantissa); // pack into a uint8_t + } + + +#ifdef __CLASSIC_C__ +int main(){ + int ac; + char*av[]; +#else +int main(int ac, char*av[]){ +#endif + //well known conversion + if ( floatToByte(0.5f) != 120 ) + return 1; + + //converting back works? + if ( floatToByte(byteToFloat(57)) != 57 ) + return 1; + + return 0; +} diff --git a/src/shared/cmake/CheckHashmaps.cmake b/src/shared/cmake/CheckHashmaps.cmake new file mode 100644 index 00000000000..5d9bdf2a16c --- /dev/null +++ b/src/shared/cmake/CheckHashmaps.cmake @@ -0,0 +1,72 @@ +#check how to use hashmaps (which namespace) +#HashingValue is filled with namespace definition +#DisableHashing is set if we can't support hashing + +INCLUDE (Macro_ChooseStatus) + +#find hashing namespace (internal, use CHECK_HASH_MAPS) ... +MACRO(HASHMAP_TEST HashingValue namespace) + IF ( NOT ${HashingValue} ) + IF ( _CL_HAVE_TR1_UNORDERED_MAP ) + SET(_CL_HASH_MAP unordered_map) + SET(_CL_HASH_SET unordered_set) + SET(CMAKE_REQUIRED_DEFINITIONS "-D_CL_HAVE_TR1_UNORDERED_MAP=1") + ELSE ( _CL_HAVE_TR1_UNORDERED_MAP ) + IF ( _CL_HAVE_HASH_MAP ) + SET(_CL_HASH_MAP hash_map) + SET(_CL_HASH_SET hash_set) + SET(CMAKE_REQUIRED_DEFINITIONS "-D_CL_HAVE_HASH_MAP=1") + ELSE ( _CL_HAVE_HASH_MAP ) + IF ( _CL_HAVE_EXT_HASH_MAP ) + SET(_CL_HASH_MAP hash_map) + SET(_CL_HASH_SET hash_set) + SET(CMAKE_REQUIRED_DEFINITIONS "-D_CL_HAVE_EXT_HASH_MAP=1") + ENDIF ( _CL_HAVE_EXT_HASH_MAP ) + ENDIF ( _CL_HAVE_HASH_MAP ) + ENDIF ( _CL_HAVE_TR1_UNORDERED_MAP ) + + STRING(TOUPPER ${namespace} NAMESPACE) + STRING(REPLACE / _ NAMESPACE ${NAMESPACE}) + STRING(REPLACE : _ NAMESPACE ${NAMESPACE}) + + CHECK_CXX_SOURCE_COMPILES(" +#if defined(_CL_HAVE_HASH_MAP) + #include +#elif defined(_CL_HAVE_EXT_HASH_MAP) + #include +#elif defined(_CL_HAVE_TR1_UNORDERED_MAP) + #include +#endif +int main() { + ${namespace}::${_CL_HASH_MAP} a; + return 0; +} + " _CL_HAVE_${NAMESPACE}_HASHMAP) + + IF ( _CL_HAVE_${NAMESPACE}_HASHMAP ) + SET (${HashingValue} "${namespace}::func") + ENDIF ( _CL_HAVE_${NAMESPACE}_HASHMAP ) + + ENDIF ( NOT ${HashingValue} ) + +ENDMACRO(HASHMAP_TEST) + + +MACRO ( CHECK_HASH_MAPS HashingValue DisableHashing) + IF ( _CL_HAVE_EXT_HASH_MAP OR _CL_HAVE_HASH_MAP ) + _CHOOSE_STATUS(PROGRESS "hashmaps" "namespace") + HASHMAP_TEST (${HashingValue} "std::tr1") + HASHMAP_TEST (${HashingValue} std) + HASHMAP_TEST (${HashingValue} stdext) + HASHMAP_TEST (${HashingValue} __gnu_cxx) + + IF ( NOT ${HashingValue} ) + _CHOOSE_STATUS(END "hashmaps" "namespace" "failed") + SET(${DisableHashing} 1) + ELSE ( NOT ${HashingValue} ) + _CHOOSE_STATUS(END "hashmaps" "namespace" ${${HashingValue}}) + ENDIF ( NOT ${HashingValue} ) + + ENDIF ( _CL_HAVE_EXT_HASH_MAP OR _CL_HAVE_HASH_MAP ) + SET(CMAKE_REQUIRED_DEFINITIONS) +ENDMACRO ( CHECK_HASH_MAPS ) diff --git a/src/shared/cmake/CheckNamespace.cmake b/src/shared/cmake/CheckNamespace.cmake new file mode 100644 index 00000000000..688232ad9cf --- /dev/null +++ b/src/shared/cmake/CheckNamespace.cmake @@ -0,0 +1,8 @@ +#check if we support namespaces +MACRO ( CHECK_NAMESPACE haveNamespace ) + #Check if namespaces work in the compiler + CHECK_CXX_SOURCE_RUNS(" + namespace Outer { namespace Inner { int i = 0; }} + int main(){ using namespace Outer::Inner; return i; }" + ${haveNamespace} ) +ENDMACRO ( CHECK_NAMESPACE haveNamespace ) \ No newline at end of file diff --git a/src/shared/cmake/CheckPthread.cmake b/src/shared/cmake/CheckPthread.cmake new file mode 100644 index 00000000000..f69f13e59c1 --- /dev/null +++ b/src/shared/cmake/CheckPthread.cmake @@ -0,0 +1,27 @@ +#define if we have pthreads with recusrive capabilities + +MACRO ( CHECK_PTHREAD_RECURSIVE ifpthread result) + +IF ( ${ifpthread} ) + SET ( CMAKE_REQUIRED_FLAGS "${CMAKE_THREAD_LIBS_INIT}") + + CHECK_CXX_SOURCE_RUNS(" + #include + #include + #include + + int main() { + pthread_mutexattr_t attr; + pthread_mutex_t m; + + exit (pthread_mutexattr_init(&attr) + || pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) + || pthread_mutex_init(&m, &attr)); + } + " ${result} ) + #NOTE: pthread_mutexattr_setkind_np is the deprecated name for pthread_mutexattr_settype. old compilers might need it + + + SET ( CMAKE_REQUIRED_FLAGS) +ENDIF ( ${ifpthread} ) +ENDMACRO ( CHECK_PTHREAD_RECURSIVE ) diff --git a/src/shared/cmake/CheckSnprintf.cmake b/src/shared/cmake/CheckSnprintf.cmake new file mode 100644 index 00000000000..8e99e334ab4 --- /dev/null +++ b/src/shared/cmake/CheckSnprintf.cmake @@ -0,0 +1,42 @@ +#checks if snprintf have bugs + +MACRO ( CHECK_SNPRINTF ) + #check that our snprintf works correctly... + IF ( _CL_HAVE_FUNCTION_SNPRINTF ) + CHECK_CXX_SOURCE_RUNS(" + #include + int main(){ + char ovbuf[7]; + int i; + for (i=0; i<7; i++) ovbuf[i]='x'; + snprintf(ovbuf, 4,\"foo%s\", \"bar\"); + if (ovbuf[5]!='x') return 1; + snprintf(ovbuf, 4,\"foo%d\", 666); + if (ovbuf[5]!='x') return 1; + return 0; + }" _CL_HAVE_NO_SNPRINTF_BUG) + IF ( NOT _CL_HAVE_NO_SNPRINTF_BUG ) + SET ( _CL_HAVE_SNPRINTF_BUG 1 ) + MESSAGE ( FATAL_ERROR "snprintf has a bug, and we don't have a replacement!" ) + ENDIF ( NOT _CL_HAVE_NO_SNPRINTF_BUG ) + ENDIF ( _CL_HAVE_FUNCTION_SNPRINTF ) + + #check that our swnprintf works correctly... + IF ( _CL_HAVE_FUNCTION_SNWPRINTF ) + CHECK_CXX_SOURCE_RUNS(" + #include + #include + + int main(void) + { + wchar_t buf[5]; + snwprintf(buf,5,L\"%s\",L\"foo\"); + if ( wcslen(buf) != 3 ) + return 1; + return 0; + }" _CL_HAVE_NO_SNWPRINTF_BUG) + IF ( NOT _CL_HAVE_NO_SNWPRINTF_BUG ) + SET ( _CL_HAVE_SNWPRINTF_BUG 1 ) + ENDIF ( NOT _CL_HAVE_NO_SNWPRINTF_BUG ) + ENDIF ( _CL_HAVE_FUNCTION_SNWPRINTF ) +ENDMACRO ( CHECK_SNPRINTF ) diff --git a/src/shared/cmake/CheckStdCallFunctionExists.cmake b/src/shared/cmake/CheckStdCallFunctionExists.cmake new file mode 100644 index 00000000000..f87136e73fc --- /dev/null +++ b/src/shared/cmake/CheckStdCallFunctionExists.cmake @@ -0,0 +1,89 @@ +# - Check if the STDCALL function exists. +# This works for non-cdecl functions (kernel32 functions, for example) +# CHECK_STDCALL_FUNCTION_EXISTS(FUNCTION FUNCTION_DUMMY_ARGS VARIABLE) +# - macro which checks if the stdcall function exists +# FUNCTION_DECLARATION - the definition of the function ( e.g.: Sleep(500) ) +# VARIABLE - variable to store the result +# +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +# CMAKE_REQUIRED_FLAGS = string of compile command line flags +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +# CMAKE_REQUIRED_INCLUDES = list of include directories +# CMAKE_REQUIRED_LIBRARIES = list of libraries to link +# CMAKE_EXTRA_INCLUDE_FILES = list of extra includes to check in + +MACRO(CHECK_STDCALL_FUNCTION_EXISTS FUNCTION_DECLARATION VARIABLE) + IF("${VARIABLE}" MATCHES "^${VARIABLE}$") + #get includes + SET(CHECK_STDCALL_FUNCTION_PREMAIN) + FOREACH(def ${CMAKE_EXTRA_INCLUDE_FILES}) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"${def}\"\n") + ENDFOREACH(def) + + #add some default includes + IF ( HAVE_WINDOWS_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"windows.h\"\n") + ENDIF ( HAVE_WINDOWS_H ) + IF ( HAVE_UNISTD_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"unistd.h\"\n") + ENDIF ( HAVE_UNISTD_H ) + IF ( HAVE_DIRECT_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"direct.h\"\n") + ENDIF ( HAVE_DIRECT_H ) + IF ( HAVE_IO_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"io.h\"\n") + ENDIF ( HAVE_IO_H ) + IF ( HAVE_SYS_TIMEB_H ) + SET(CHECK_STDCALL_FUNCTION_PREMAIN "${CHECK_STDCALL_FUNCTION_PREMAIN}#include \"sys/timeb.h\"\n") + ENDIF ( HAVE_SYS_TIMEB_H ) + + STRING(REGEX REPLACE "(\\(.*\\))" "" CHECK_STDCALL_FUNCTION_EXISTS_FUNCTION ${FUNCTION_DECLARATION} ) + + SET(MACRO_CHECK_STDCALL_FUNCTION_DEFINITIONS "${CMAKE_REQUIRED_FLAGS}") + MESSAGE(STATUS "Looking for ${CHECK_STDCALL_FUNCTION_EXISTS_FUNCTION}") + + IF(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ELSE(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES) + ENDIF(CMAKE_REQUIRED_LIBRARIES) + + IF(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + ELSE(CMAKE_REQUIRED_INCLUDES) + SET(CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES) + ENDIF(CMAKE_REQUIRED_INCLUDES) + + SET(CHECK_STDCALL_FUNCTION_DECLARATION ${FUNCTION_DECLARATION}) + CONFIGURE_FILE("${clucene-shared_SOURCE_DIR}/cmake/CheckStdCallFunctionExists.cpp.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" IMMEDIATE @ONLY) + FILE(READ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" + CHECK_STDCALL_FUNCTION_CONTENT) + + TRY_COMPILE(${VARIABLE} + ${CMAKE_BINARY_DIR} + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckStdCallFunctionExists.cpp" + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_STDCALL_FUNCTION_DEFINITIONS} + "${CHECK_STDCALL_FUNCTION_EXISTS_ADD_LIBRARIES}" + "${CHECK_STDCALL_FUNCTION_EXISTS_ADD_INCLUDES}" + OUTPUT_VARIABLE OUTPUT) + IF(${VARIABLE}) + SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION_DECLARATION}") + MESSAGE(STATUS "Looking for ${FUNCTION_DECLARATION} - found") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Determining if the stdcall function ${FUNCTION_DECLARATION} exists passed with the following output:\n" + "${OUTPUT}\nCheckStdCallFunctionExists.cpp:\n${CHECK_STDCALL_FUNCTION_CONTENT}\n\n") + ELSE(${VARIABLE}) + MESSAGE(STATUS "Looking for ${FUNCTION_DECLARATION} - not found") + SET(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION_DECLARATION}") + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Determining if the stdcall function ${FUNCTION_DECLARATION} exists failed with the following output:\n" + "${OUTPUT}\nCheckStdCallFunctionExists.cpp:\n${CHECK_STDCALL_FUNCTION_CONTENT}\n\n") + ENDIF(${VARIABLE}) + ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") +ENDMACRO(CHECK_STDCALL_FUNCTION_EXISTS) diff --git a/src/shared/cmake/CheckStdCallFunctionExists.cpp.in b/src/shared/cmake/CheckStdCallFunctionExists.cpp.in new file mode 100644 index 00000000000..8ac965779d6 --- /dev/null +++ b/src/shared/cmake/CheckStdCallFunctionExists.cpp.in @@ -0,0 +1,12 @@ +@CHECK_STDCALL_FUNCTION_PREMAIN@ + +#ifdef __CLASSIC_C__ +int main(){ + int ac; + char*av[]; +#else +int main(int ac, char*av[]){ +#endif + @CHECK_STDCALL_FUNCTION_DECLARATION@; + return 0; +} diff --git a/src/shared/cmake/DefineDword.cmake b/src/shared/cmake/DefineDword.cmake new file mode 100644 index 00000000000..8d0efff43fa --- /dev/null +++ b/src/shared/cmake/DefineDword.cmake @@ -0,0 +1,17 @@ +#defines a dword replacement + +MACRO ( DEFINE_DWORD ) + + IF ( HAVE_WINDOWS_H ) + SET (CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES};windows.h") + ENDIF ( HAVE_WINDOWS_H ) + + CHECK_TYPE_SIZE ( DWORD _CL_HAVE_TYPE_DWORD ) + + IF ( _CL_HAVE_TYPE_DWORD ) + CHOOSE_TYPE(_cl_dword_t ${_CL_HAVE_TYPE_DWORD} unsigned "long;long long;__int64;short;int" ) + ENDIF ( _CL_HAVE_TYPE_DWORD ) + + SET ( CMAKE_EXTRA_INCLUDE_FILES ) + +ENDMACRO ( DEFINE_DWORD ) \ No newline at end of file diff --git a/src/shared/cmake/DefineFloat.cmake b/src/shared/cmake/DefineFloat.cmake new file mode 100644 index 00000000000..d52b59aab8c --- /dev/null +++ b/src/shared/cmake/DefineFloat.cmake @@ -0,0 +1,29 @@ +MACRO ( DEFINE_FLOAT ) + #find float symbol + CHECK_CXX_SOURCE_COMPILES(" + #include + int main(){ float_t x=0.0; }" + HAVE_SYMBOL_FLOAT_T) + + IF ( NOT HAVE_SYMBOL_FLOAT_T ) + #try using FLT_EVAL_METHOD + CHECK_CXX_SOURCE_COMPILES(" + #define FLT_EVAL_METHOD 2 + #include + int main(){ float_t x=0.0; }" + HAVE_SYMBOL_FLOAT_T) + + IF ( HAVE_SYMBOL_FLOAT_T ) + SET ( _FLT_EVAL_METHOD 2 ) + SET ( TYPE_FLOAT_T "/* undef float_t*/" ) + ENDIF ( HAVE_SYMBOL_FLOAT_T ) + + ELSE ( NOT HAVE_SYMBOL_FLOAT_T ) + SET ( TYPE_FLOAT_T "/* undef float_t*/" ) + ENDIF ( NOT HAVE_SYMBOL_FLOAT_T ) + + IF ( NOT HAVE_SYMBOL_FLOAT_T ) + #todo: could we do a better guess here? + SET ( TYPE_FLOAT_T "typedef double float_t;" ) + ENDIF ( NOT HAVE_SYMBOL_FLOAT_T ) +ENDMACRO ( DEFINE_FLOAT ) diff --git a/src/shared/cmake/DefineLongLongSyntax.cmake b/src/shared/cmake/DefineLongLongSyntax.cmake new file mode 100644 index 00000000000..490aa0431e9 --- /dev/null +++ b/src/shared/cmake/DefineLongLongSyntax.cmake @@ -0,0 +1,14 @@ +MACRO ( DEFINE_LONGLONG_SYNTAX ) + #check how to define a long (and longlong number) + CHECK_CXX_SOURCE_COMPILES("int main(){ int x = (int)(1234LL); }" _CL_ILONGLONG_LL) + IF ( _CL_ILONGLONG_LL ) + SET(_CL_ILONGLONG_VALUE "x ## LL") + ELSE ( _CL_ILONGLONG_LL ) + CHECK_CXX_SOURCE_COMPILES("int main(){ int x = (int)(1234i64); }" _CL_ILONGLONG_i64) + IF ( _CL_ILONGLONG_i64 ) + SET(_CL_ILONGLONG_VALUE "x ## i64") + ELSE ( _CL_ILONGLONG_i64 ) + MESSAGE( FATAL_ERROR "_CL_ILONGLONG_VALUE could not be determined" ) + ENDIF ( _CL_ILONGLONG_i64 ) + ENDIF ( _CL_ILONGLONG_LL ) +ENDMACRO ( DEFINE_LONGLONG_SYNTAX ) diff --git a/src/shared/cmake/DefineMAXPATHValue.cmake b/src/shared/cmake/DefineMAXPATHValue.cmake new file mode 100644 index 00000000000..7824581edd3 --- /dev/null +++ b/src/shared/cmake/DefineMAXPATHValue.cmake @@ -0,0 +1,30 @@ +#checks if snprintf have bugs + +MACRO ( DEFINE_MAXPATH_VALUE MaxPathValue ) +# also check for MAXPATHLEN +#or this: +#path_max = pathconf (path, _PC_PATH_MAX); + #if (path_max <= 0) + #path_max = 4096; + + #use CHOOSE_SYMBOL mechanism to determine which variable to use... + #CHOOSE_SYMBOL (_CL_MAX_PATH "PATH_MAX;MAX_PATH;_MAX_PATH;_POSIX_PATH_MAX" DefineMaxPathValue) + #IF ( DefineMaxPathValue ) + #now try and find its value... + # Include ( MacroGetVariableValue ) + + # SET ( _CL_MAX_PATH_VALUE ) + # GET_VARIABLE_VALUE (${DefineMaxPathValue} d _CL_MAX_PATH_VALUE) + # IF ( _CL_MAX_PATH_VALUE ) + # SET( ${MaxPathValue} "#define ${MaxPathValue} ${_CL_MAX_PATH_VALUE}" ) + # ENDIF( _CL_MAX_PATH_VALUE ) + #ELSE ( DefineMaxPathValue ) + # MESSAGE ( FATAL_ERROR "_CL_MAX_PATH could not be determined") + #ENDIF ( DefineMaxPathValue ) + + #SET (CMAKE_REQUIRED_DEFINITIONS) + + #HACK!!! + #todo: fix this + SET( ${MaxPathValue} "#define CL_MAX_PATH 4096") +ENDMACRO ( DEFINE_MAXPATH_VALUE ) diff --git a/src/shared/cmake/DefineStaticSyntax.cmake b/src/shared/cmake/DefineStaticSyntax.cmake new file mode 100644 index 00000000000..7be2415c813 --- /dev/null +++ b/src/shared/cmake/DefineStaticSyntax.cmake @@ -0,0 +1,13 @@ +#defines how we can define a static const (or fallback to using an enum) + +MACRO ( DEFINE_STATIC_SYNTAX ) + + #check which syntax of static const to use + CHECK_CXX_SOURCE_RUNS("class x{public: static const int SCI=55; }; int main(){ x a; if ( a.SCI!=55 ) throw \"err\"; return 0; }" LUCENE_STATIC_CONSTANT_SYNTAX) + IF ( LUCENE_STATIC_CONSTANT_SYNTAX ) + SET ( LUCENE_STATIC_CONSTANT_SYNTAX "static const type assignment") + ELSE ( LUCENE_STATIC_CONSTANT_SYNTAX ) + SET ( LUCENE_STATIC_CONSTANT_SYNTAX "enum { assignment }") + ENDIF ( LUCENE_STATIC_CONSTANT_SYNTAX ) + +ENDMACRO ( DEFINE_STATIC_SYNTAX ) \ No newline at end of file diff --git a/src/shared/cmake/MacroCheckGccVisibility.cmake b/src/shared/cmake/MacroCheckGccVisibility.cmake new file mode 100644 index 00000000000..2022aa31b15 --- /dev/null +++ b/src/shared/cmake/MacroCheckGccVisibility.cmake @@ -0,0 +1,58 @@ +# +# Copyright (c) 2006, Alexander Neundorf +# Copyright (c) 2006, Laurent Montel, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +macro(MACRO_CHECK_GCC_VISIBILITY GccVisibility) + if (CMAKE_COMPILER_IS_GNUCXX) + include(CheckCXXCompilerFlag) + include(MacroEnsureVersion) + # visibility support + check_cxx_compiler_flag(-fvisibility=hidden ${GccVisibility}) + + # get the gcc version + exec_program(${CMAKE_C_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info) + + string (REGEX MATCH "[345]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}") + if (NOT _gcc_version) + + # clang reports: clang version 1.1 (trunk 95754) + string (REGEX MATCH "clang version ([123]\\.[0-9])" _gcc_version "${_gcc_version_info}") + if ( _gcc_version ) + string(REGEX REPLACE "clang version (.*)" "\\1.0" _gcc_version "${_gcc_version}" ) + endif ( _gcc_version ) + + # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the patch level, handle this here: + if (NOT _gcc_version) + string (REGEX REPLACE ".*\\(GCC\\).* ([34]\\.[0-9]) .*" "\\1.0" _gcc_version "${_gcc_version_info}") + endif (NOT _gcc_version) + endif (NOT _gcc_version) + + + + macro_ensure_version("4.1.0" "${_gcc_version}" GCC_IS_NEWER_THAN_4_1) + macro_ensure_version("4.2.0" "${_gcc_version}" GCC_IS_NEWER_THAN_4_2) + + set(_GCC_COMPILED_WITH_BAD_ALLOCATOR FALSE) + if (GCC_IS_NEWER_THAN_4_1) + exec_program(${CMAKE_C_COMPILER} ARGS -v OUTPUT_VARIABLE _gcc_alloc_info) + string(REGEX MATCH "(--enable-libstdcxx-allocator=mt)" _GCC_COMPILED_WITH_BAD_ALLOCATOR "${_gcc_alloc_info}") + endif (GCC_IS_NEWER_THAN_4_1) + + if (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + set (KDE4_C_FLAGS "${KDE4_C_FLAGS}" "-fvisibility=hidden") + + if (GCC_IS_NEWER_THAN_4_2) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") + endif (GCC_IS_NEWER_THAN_4_2) + else (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) + set (${GccVisibility} 0) + endif (${GccVisibility} AND GCC_IS_NEWER_THAN_4_1 AND NOT _GCC_COMPILED_WITH_BAD_ALLOCATOR) + + else (CMAKE_COMPILER_IS_GNUCXX) + set(${GccVisibility} FALSE) + endif (CMAKE_COMPILER_IS_GNUCXX) +endmacro(MACRO_CHECK_GCC_VISIBILITY) diff --git a/src/shared/cmake/MacroChooseFunction.cmake b/src/shared/cmake/MacroChooseFunction.cmake new file mode 100644 index 00000000000..4c5ad703f7e --- /dev/null +++ b/src/shared/cmake/MacroChooseFunction.cmake @@ -0,0 +1,49 @@ + +INCLUDE (CheckFunctionExists) +INCLUDE (Macro_ChooseStatus) + +#macro that sets OUTPUT as the value of oneof options (if _CL_HAVE_OPTION exists) +MACRO(CHOOSE_FUNCTION name options) + STRING(TOUPPER ${name} NAME) + FOREACH(option ${options}) + IF ( NOT FUNCTION_${NAME} ) + STRING(TOUPPER ${option} OPTION) + SET( option1 ${option} ) + + STRING(REGEX MATCH "[(|)]+" MACRO_CHOOSE_FUNCTION_MATCH ${option} ) + IF ( MACRO_CHOOSE_FUNCTION_MATCH STREQUAL "" ) + _CHOOSE_STATUS(PROGRESS ${name} "function" ) + CHECK_FUNCTION_EXISTS (${option} _CL_HAVE_FUNCTION_${OPTION}) + ELSE ( MACRO_CHOOSE_FUNCTION_MATCH STREQUAL "" ) + STRING(REGEX REPLACE "(\\(.*\\))" "" option ${option} ) + STRING(TOUPPER ${option} OPTION) + _CHOOSE_STATUS(PROGRESS ${name} "function" ) + CHECK_STDCALL_FUNCTION_EXISTS (${option1} _CL_HAVE_FUNCTION_${OPTION}) + ENDIF ( MACRO_CHOOSE_FUNCTION_MATCH STREQUAL "" ) + + IF ( _CL_HAVE_FUNCTION_${OPTION} ) + _CHOOSE_STATUS(END ${name} function ${option}) + IF ( option STREQUAL ${name} ) + #already have it, ignore this... + SET (FUNCTION_${NAME} "/* undef ${name} ${option} */" ) + ELSE ( option STREQUAL ${name} ) + SET (FUNCTION_${NAME} "#define ${name} ${option}") + ENDIF ( option STREQUAL ${name} ) + ENDIF ( _CL_HAVE_FUNCTION_${OPTION} ) + ENDIF( NOT FUNCTION_${NAME} ) + ENDFOREACH(option ${options}) + + IF ( NOT FUNCTION_${NAME} ) + IF ( NOT ${ARGV2} STREQUAL "" ) + _CHOOSE_STATUS(END ${name} function "using default") + SET (FUNCTION_${NAME} ${ARGV2} ) + ELSE ( NOT ${ARGV2} STREQUAL "" ) + _CHOOSE_STATUS(END ${name} function "not found") + SET (FUNCTION_${NAME} "/* undef ${name} */" ) + ENDIF ( NOT ${ARGV2} STREQUAL "" ) + ENDIF ( NOT FUNCTION_${NAME} ) + + IF ( FUNCTION_${NAME} ) + SET (HAVE_FUNCTION_${NAME} 1) + ENDIF ( FUNCTION_${NAME} ) +ENDMACRO(CHOOSE_FUNCTION) diff --git a/src/shared/cmake/MacroChooseMisc.cmake b/src/shared/cmake/MacroChooseMisc.cmake new file mode 100644 index 00000000000..7db23d1d0c6 --- /dev/null +++ b/src/shared/cmake/MacroChooseMisc.cmake @@ -0,0 +1,82 @@ +#macro that sets result to one of results (and have_result to true) when the first option TRY_COMPILE is successful. +#this is mainly to get around the fact that some compilers couldn't do sizeof(structs), therefore CHOOSE_TYPE wasn't going to work +#syntax: CHOOSE_TYPE ( TYPE_X HAVE_TYPE_X "struct stat x\;" "typedef stat cl_stat" "stat" ) (the last 3 options can be repeated indefinately in pairs of 3) + +INCLUDE (Macro_ChooseStatus) + +MACRO(CHOOSE_MISC result have_result ) + IF ( HAVE_SYS_STAT_H ) + SET (HEADERS "${HEADERS} + #include \"sys/stat.h\"") + ENDIF ( HAVE_SYS_STAT_H ) + IF ( HAVE_SYS_TIMEB_H ) + SET (HEADERS "${HEADERS} + #include \"sys/timeb.h\"") + ENDIF ( HAVE_SYS_TIMEB_H ) + + SET ( M_TEST ) + SET ( M_SUCCESS ) + SET ( M_name ) + SET ( M_RESULT ) + SET ( M_HAVE_RESULT ) + + FOREACH(optiong ${ARGV}) + #MESSAGE( STATUS "m ${optiong}" ) + SET ( m_continue ) + + #this will only happen the first round... + IF ( NOT m_continue AND NOT M_RESULT ) + SET ( M_RESULT "${optiong}") + SET ( m_continue 1 ) + ENDIF ( NOT m_continue AND NOT M_RESULT ) + IF ( NOT m_continue AND NOT M_HAVE_RESULT ) + SET ( M_HAVE_RESULT "${optiong}") + SET ( m_continue 1 ) + ENDIF ( NOT m_continue AND NOT M_HAVE_RESULT ) + + #test and success in pairs... + IF ( NOT m_continue AND NOT M_TEST ) + SET ( M_TEST "${optiong}") + SET ( m_continue 1 ) + ENDIF ( NOT m_continue AND NOT M_TEST ) + IF ( NOT m_continue AND NOT M_SUCCESS ) + SET ( M_SUCCESS "${optiong}") + SET ( m_continue 1 ) + ENDIF ( NOT m_continue AND NOT M_SUCCESS ) + IF ( NOT m_continue AND NOT M_name ) + SET ( M_name "${optiong}") + STRING(TOUPPER ${M_name} M_NAME) + #this one doesn't continue... + ENDIF ( NOT m_continue AND NOT M_name ) + + IF ( NOT m_continue ) + _CHOOSE_STATUS(PROGRESS ${M_HAVE_RESULT} "option" ${M_TEST}) + + IF ( NOT ${M_HAVE_RESULT} ) + CHECK_CXX_SOURCE_COMPILES( + "${HEADERS} + int main(){ + ${M_TEST} + }" + _CL_HAVE_OPTION_${M_NAME} ) + + IF ( _CL_HAVE_OPTION_${M_NAME} ) + SET (${M_RESULT} "${M_SUCCESS}") + SET (${M_HAVE_RESULT} 1 ) + _CHOOSE_STATUS(END ${M_HAVE_RESULT} "option" "${M_name}") + ENDIF ( _CL_HAVE_OPTION_${M_NAME} ) + ENDIF ( NOT ${M_HAVE_RESULT} ) + + #reset for next round + SET ( M_TEST ) + SET ( M_SUCCESS ) + SET ( M_name ) + ENDIF ( NOT m_continue ) + ENDFOREACH(optiong) + + IF ( NOT ${M_HAVE_RESULT} ) + _CHOOSE_STATUS(END ${M_HAVE_RESULT} option "not found") + ENDIF ( NOT ${M_HAVE_RESULT} ) + + SET(CMAKE_EXTRA_INCLUDE_FILES) +ENDMACRO(CHOOSE_MISC) diff --git a/src/shared/cmake/MacroChooseSymbol.cmake b/src/shared/cmake/MacroChooseSymbol.cmake new file mode 100644 index 00000000000..839947a7ca3 --- /dev/null +++ b/src/shared/cmake/MacroChooseSymbol.cmake @@ -0,0 +1,62 @@ + +INCLUDE (CheckSymbolExists) +INCLUDE (Macro_ChooseStatus) + +MACRO(CHOOSE_SYMBOL name options) + #note: don't add windows.h to this list, since we don't want to find things + #in there (bcc might make you think otherwise, but it's true!)... + + IF ( CYGWIN ) + #cygwin requires this to determine some things... + SET ( CMAKE_REQUIRED_DEFINITIONS "-D_WIN32") + ENDIF( CYGWIN ) + + IF ( HAVE_LIMITS_H ) + SET (CHOOSE_SYMBOL_INCLUDES "${CHOOSE_SYMBOL_INCLUDES};limits.h") + ENDIF ( HAVE_LIMITS_H ) + IF ( HAVE_STAT_H ) + SET (CHOOSE_SYMBOL_INCLUDES "${CHOOSE_SYMBOL_INCLUDES};stat.h") + ENDIF ( HAVE_STAT_H ) + IF ( HAVE_SYS_STAT_H ) + SET (CHOOSE_SYMBOL_INCLUDES "${CHOOSE_SYMBOL_INCLUDES};sys/stat.h") + ENDIF ( HAVE_SYS_STAT_H ) + IF ( HAVE_TCHAR_H ) + SET (CHOOSE_SYMBOL_INCLUDES "${CHOOSE_SYMBOL_INCLUDES};tchar.h") + ENDIF ( HAVE_TCHAR_H ) + + SET (CHOOSE_SYMBOL_INCLUDES "${CHOOSE_SYMBOL_INCLUDES};fcntl.h") + + STRING(TOUPPER ${name} NAME) + FOREACH(option ${options}) + IF ( NOT SYMBOL_${NAME} ) + STRING(TOUPPER ${option} OPTION) + + _CHOOSE_STATUS(PROGRESS ${name} "symbol" ) + CHECK_SYMBOL_EXISTS (${option} "${CHOOSE_SYMBOL_INCLUDES}" _CL_HAVE_SYMBOL_${OPTION}) + + IF ( _CL_HAVE_SYMBOL_${OPTION} ) + IF ( option STREQUAL ${name} ) + #already have it, ignore this... + SET (SYMBOL_${NAME} "/* undef ${name} ${option} */" ) + ELSE ( option STREQUAL ${name} ) + SET (SYMBOL_${NAME} "#define ${name} ${option}") + ENDIF ( option STREQUAL ${name} ) + + IF ( NOT "${ARGV2}" STREQUAL "" ) + SET ( ${ARGV2} "${option}" ) + ENDIF ( NOT "${ARGV2}" STREQUAL "" ) + _CHOOSE_STATUS(END ${name} "symbol" ${option}) + ENDIF ( _CL_HAVE_SYMBOL_${OPTION} ) + ENDIF( NOT SYMBOL_${NAME} ) + ENDFOREACH(option ${options}) + + IF ( NOT SYMBOL_${NAME} ) + SET (SYMBOL_${NAME} "/* undef ${name} */" ) + _CHOOSE_STATUS(END ${name} "symbol" "not found" ) + ELSE ( NOT SYMBOL_${NAME} ) + SET (HAVE_SYMBOL_${NAME} 1) + ENDIF ( NOT SYMBOL_${NAME} ) + + SET (CHOOSE_SYMBOL_INCLUDES) + SET (CMAKE_REQUIRED_DEFINITIONS) +ENDMACRO(CHOOSE_SYMBOL) diff --git a/src/shared/cmake/MacroChooseType.cmake b/src/shared/cmake/MacroChooseType.cmake new file mode 100644 index 00000000000..71db0c08408 --- /dev/null +++ b/src/shared/cmake/MacroChooseType.cmake @@ -0,0 +1,49 @@ + +INCLUDE (CheckTypeSize) +INCLUDE (Macro_ChooseStatus) + +#macro that sets OUTPUT as the value of oneof options (if _CL_HAVE_OPTION exists) +MACRO(CHOOSE_TYPE name size sign options) + #note: don't add windows.h to this list, since we don't want to find things + #in there (bcc might make you think otherwise, but it's true!)... + IF ( HAVE_TCHAR_H ) + SET (CMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES};tchar.h") + ENDIF ( HAVE_TCHAR_H ) + + STRING(TOUPPER ${name} NAME) + FOREACH(option ${options}) + IF ( NOT TYPE_${NAME} ) + STRING(TOUPPER ${option} OPTION) + STRING(REPLACE " " "" OPTION ${OPTION}) + STRING(REPLACE "_" "" SO_OPTION ${OPTION}) + + _CHOOSE_STATUS(PROGRESS ${name} "type") + CHECK_TYPE_SIZE(${option} _CL_HAVE_TYPE_${OPTION}) + IF ( _CL_HAVE_TYPE_${OPTION} ) + IF ( option STREQUAL ${name} ) + #already have it, ignore this... + SET (TYPE_${NAME} "/* undef ${name} ${option} */" ) + ELSE ( option STREQUAL ${name} ) + IF ( ${size} LESS 0 OR _CL_HAVE_TYPE_${OPTION} EQUAL ${size} ) + SET (TYPE_${NAME} "typedef ${sign} ${option} ${name};") + ENDIF ( ${size} LESS 0 OR _CL_HAVE_TYPE_${OPTION} EQUAL ${size}) + ENDIF ( option STREQUAL ${name} ) + + IF ( NOT "${ARGV4}" STREQUAL "" ) + SET ( ${ARGV4} "${option}" ) + ENDIF ( NOT "${ARGV4}" STREQUAL "" ) + _CHOOSE_STATUS(END ${name} "type" "${sign} ${option}") + ENDIF ( _CL_HAVE_TYPE_${OPTION} ) + ENDIF( NOT TYPE_${NAME} ) + ENDFOREACH(option ${options}) + + IF ( NOT TYPE_${NAME} ) + SET (TYPE_${NAME} "/* undef ${name} */" ) + _CHOOSE_STATUS(END ${name} "type" "not found") + ELSE ( NOT TYPE_${NAME} ) + SET (HAVE_TYPE_${NAME} 1) + ENDIF ( NOT TYPE_${NAME} ) + + + SET(CMAKE_EXTRA_INCLUDE_FILES) +ENDMACRO(CHOOSE_TYPE) diff --git a/src/shared/cmake/MacroEnsureVersion.cmake b/src/shared/cmake/MacroEnsureVersion.cmake new file mode 100644 index 00000000000..e2c0862639c --- /dev/null +++ b/src/shared/cmake/MacroEnsureVersion.cmake @@ -0,0 +1,71 @@ +# This macro compares version numbers of the form "x.y.z" +# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK) +# will set FOO_VERSIN_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION +# where both have to be in a 3-part-version format, leading and trailing +# text is ok, e.g. +# MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK) +# which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system + +# Copyright (c) 2006, David Faure, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old) + + # parse the parts of the version string + STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_major_vers "${requested_version}") + STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" req_minor_vers "${requested_version}") + STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_patch_vers "${requested_version}") + + STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" found_major_vers "${found_version}") + STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" found_minor_vers "${found_version}") + STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" found_patch_vers "${found_version}") + + # compute an overall version number which can be compared at once + #MATH(EXPR req_vers_num "${req_major_vers}*10000 + ${req_minor_vers}*100 + ${req_patch_vers}") + #MATH(EXPR found_vers_num "${found_major_vers}*10000 + ${found_minor_vers}*100 + ${found_patch_vers}") + + if (found_vers_num LESS req_vers_num) + set( ${var_too_old} FALSE ) + else (found_vers_num LESS req_vers_num) + set( ${var_too_old} TRUE ) + endif (found_vers_num LESS req_vers_num) + +ENDMACRO(MACRO_ENSURE_VERSION) + + +# This macro compares version numbers of the form "x.y" +# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK) +# will set FOO_VERSIN_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION +# where both have to be in a 2-part-version format, leading and trailing +# text is ok, e.g. +# MACRO_ENSURE_VERSION( "0.5" "foo 0.6" VERSION_OK) +# which means 0.5 is required and "foo 0.6" is what was found on the system + +# Copyright (c) 2006, David Faure, +# Copyright (c) 2007, Pino Toscano, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +MACRO(MACRO_ENSURE_VERSION2 requested_version found_version var_too_old) + + # parse the parts of the version string + STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" req_major_vers "${requested_version}") + STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" req_minor_vers "${requested_version}") + + STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+.*" "\\1" found_major_vers "${found_version}") + STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+).*" "\\1" found_minor_vers "${found_version}") + + # compute an overall version number which can be compared at once + MATH(EXPR req_vers_num "${req_major_vers}*100 + ${req_minor_vers}") + MATH(EXPR found_vers_num "${found_major_vers}*100 + ${found_minor_vers}") + + if (found_vers_num LESS req_vers_num) + set( ${var_too_old} FALSE ) + else (found_vers_num LESS req_vers_num) + set( ${var_too_old} TRUE ) + endif (found_vers_num LESS req_vers_num) + +ENDMACRO(MACRO_ENSURE_VERSION2) diff --git a/src/shared/cmake/MacroGetVariableValue.c.in b/src/shared/cmake/MacroGetVariableValue.c.in new file mode 100644 index 00000000000..24255a56ef4 --- /dev/null +++ b/src/shared/cmake/MacroGetVariableValue.c.in @@ -0,0 +1,20 @@ + +#include + +#ifdef HAVE_WINDOWS_H + #include +#endif +#ifdef HAVE_LIMITS_H + #include +#endif +#ifdef HAVE_STAT_H + #include +#endif +#ifdef HAVE_SYS_STAT_H + #include +#endif + +int main(){ + printf("%${}", ${}); + return 0; +} diff --git a/src/shared/cmake/MacroGetVariableValue.cmake b/src/shared/cmake/MacroGetVariableValue.cmake new file mode 100644 index 00000000000..ed60f4ee851 --- /dev/null +++ b/src/shared/cmake/MacroGetVariableValue.cmake @@ -0,0 +1,33 @@ + +#macro that sets OUTPUT as the value of oneof options (if _CL_HAVE_OPTION exists) +MACRO(GET_VARIABLE_VALUE variable printfType result) + + SET ( GET_VARIABLE_VALUE_DEFINITIONS "-DVARIABLENAME=${variable} -DPRINTFTYPE=${printfType}") + + IF ( HAVE_WINDOWS_H ) + SET ( GET_VARIABLE_VALUE_DEFINITIONS "${GET_VARIABLE_VALUE_DEFINITIONS} -DHAVE_WINDOWS_H") + ENDIF ( HAVE_WINDOWS_H ) + IF ( HAVE_LIMITS_H ) + SET (GET_VARIABLE_VALUE_DEFINITIONS "${GET_VARIABLE_VALUE_DEFINITIONS} -DHAVE_LIMITS_H") + ENDIF ( HAVE_LIMITS_H ) + IF ( HAVE_STAT_H ) + SET (GET_VARIABLE_VALUE_DEFINITIONS "${GET_VARIABLE_VALUE_DEFINITIONS} -DHAVE_STAT_H") + ENDIF ( HAVE_STAT_H ) + IF ( HAVE_SYS_STAT_H ) + SET (GET_VARIABLE_VALUE_DEFINITIONS "${GET_VARIABLE_VALUE_DEFINITIONS} -DHAVE_SYS_STAT_H") + ENDIF ( HAVE_SYS_STAT_H ) + + CONFIGURE_FILE("${${PROJECT_SOURCE_DIR}}/cmake/MacroGetVariableValue.c.in" + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/MacroGetVariableValue.c" IMMEDIATE @ONLY) + + TRY_COMPILE(HAVE_${VARIABLE} + ${CMAKE_BINARY_DIR} + "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckTypeSizeC.c" + COMPILE_DEFINITIONS ${GET_VARIABLE_VALUE_DEFINITIONS} + OUTPUT_VARIABLE OUTPUT + COPY_FILE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MacroGetVariablesValue.bin" ) + + + MESSAGE(FATAL_ERROR stop) + SET(GET_VARIABLE_VALUE_DEFINITIONS) +ENDMACRO(GET_VARIABLE_VALUE) diff --git a/src/shared/cmake/MacroMustDefine.cmake b/src/shared/cmake/MacroMustDefine.cmake new file mode 100644 index 00000000000..4cda90e245c --- /dev/null +++ b/src/shared/cmake/MacroMustDefine.cmake @@ -0,0 +1,69 @@ +#this macro throws an error if any of the vars are not defined + +MACRO(MUSTDEFINE_VAR VARS) + foreach(ARG ${VARS}) + IF ( NOT ${ARG} ) + MESSAGE( FATAL_ERROR "The symbol '${ARG}' was not defined." ) + ENDIF ( NOT ${ARG} ) + endforeach(ARG) +ENDMACRO(MUSTDEFINE_VAR) + +#required headers +MACRO(CHECK_REQUIRED_HEADERS COMPULSARY_HEADERS) + FOREACH(func ${ARGV}) + STRING(TOUPPER ${func} FUNC) + STRING(REPLACE . _ FUNC ${FUNC}) + CHECK_INCLUDE_FILE_CXX (${func} HAVE_${FUNC}) + IF ( HAVE_${FUNC} ) + SET(_CL_HAVE_${FUNC} ${FUNC}) + ENDIF ( HAVE_${FUNC} ) + IF ( NOT HAVE_${FUNC} ) + MESSAGE ( FATAL_ERROR "${func} could not be found" ) + ENDIF ( NOT HAVE_${FUNC} ) + ENDFOREACH(func ${COMPULSARY_HEADERS}) +ENDMACRO(CHECK_REQUIRED_HEADERS) + +#optional headers +MACRO(CHECK_OPTIONAL_HEADERS OPTIONAL_HEADERS) + FOREACH(func ${ARGV}) + STRING(TOUPPER ${func} FUNC) + STRING(REPLACE . _ FUNC ${FUNC}) + STRING(REPLACE / _ FUNC ${FUNC}) + CHECK_INCLUDE_FILE_CXX (${func} HAVE_${FUNC}) + IF ( HAVE_${FUNC} ) + SET(_CL_HAVE_${FUNC} ${FUNC}) + ENDIF ( HAVE_${FUNC} ) + ENDFOREACH(func ${OPTIONAL_HEADERS}) +ENDMACRO(CHECK_OPTIONAL_HEADERS) + +#check for compulsary functions +MACRO(CHECK_REQUIRED_FUNCTIONS COMPULSARY_FUNCTIONS) + FOREACH(func ${ARGV}) + CHECK_OPTIONAL_FUNCTIONS ( ${func} ) + + IF ( NOT _CL_HAVE_FUNCTION_${FUNC} ) + MESSAGE ( FATAL_ERROR "${func} could not be found" ) + ENDIF ( NOT _CL_HAVE_FUNCTION_${FUNC} ) + ENDFOREACH(func ${COMPULSARY_FUNCTIONS}) + + SET( CMAKE_EXTRA_INCLUDE_FILES ) +ENDMACRO(CHECK_REQUIRED_FUNCTIONS) + +#check for optional functions +MACRO(CHECK_OPTIONAL_FUNCTIONS OPTIONAL_FUNCTIONS) + FOREACH(func ${ARGV}) + STRING(TOUPPER ${func} FUNC) + + STRING(REGEX MATCH "[(|)]+" CHECK_OPTIONAL_FUNCTIONS_MATCH ${func} ) + IF ( CHECK_OPTIONAL_FUNCTIONS_MATCH STREQUAL "" ) + CHECK_FUNCTION_EXISTS (${func} _CL_HAVE_FUNCTION_${FUNC}) + ELSE ( CHECK_OPTIONAL_FUNCTIONS_MATCH STREQUAL "" ) + STRING(REGEX REPLACE "(\\(.*\\))" "" CHECK_OPTIONAL_FUNCTIONS_MATCH ${func} ) + STRING( TOUPPER ${CHECK_OPTIONAL_FUNCTIONS_MATCH} FUNC ) + + CHECK_STDCALL_FUNCTION_EXISTS (${func} _CL_HAVE_FUNCTION_${FUNC}) + ENDIF ( CHECK_OPTIONAL_FUNCTIONS_MATCH STREQUAL "" ) + + ENDFOREACH(func ${OPTIONAL_FUNCTIONS}) + +ENDMACRO(CHECK_OPTIONAL_FUNCTIONS) \ No newline at end of file diff --git a/src/shared/cmake/Macro_ChooseStatus.cmake b/src/shared/cmake/Macro_ChooseStatus.cmake new file mode 100644 index 00000000000..3ec18c92f37 --- /dev/null +++ b/src/shared/cmake/Macro_ChooseStatus.cmake @@ -0,0 +1,20 @@ +#internal macro for choose_* macros. + +MACRO(_CHOOSE_STATUS status name type) + STRING(TOUPPER ${name} NAME) + STRING(TOUPPER ${type} TYPE) + + IF ( ${status} STREQUAL "PROGRESS" ) + IF ( "" STREQUAL "${_CHOOSE_STATUS_${TYPE}_${NAME}}" ) + MESSAGE ( STATUS "Choosing ${type} for ${name}" ) + SET ( _CHOOSE_STATUS_${TYPE}_${NAME} "XXX" ) + ENDIF ( "" STREQUAL "${_CHOOSE_STATUS_${TYPE}_${NAME}}" ) + ENDIF ( ${status} STREQUAL "PROGRESS" ) + + IF ( ${status} STREQUAL "END" ) + IF ( "XXX" STREQUAL "${_CHOOSE_STATUS_${TYPE}_${NAME}}" ) + MESSAGE ( STATUS "Choosing ${type} for ${name} - ${ARGV3}" ) + SET ( _CHOOSE_STATUS_${TYPE}_${NAME} ON CACHE INTERNAL "Chose ${type} for ${name} - ${ARGV3}" ) + ENDIF ( "XXX" STREQUAL "${_CHOOSE_STATUS_${TYPE}_${NAME}}" ) + ENDIF ( ${status} STREQUAL "END" ) +ENDMACRO(_CHOOSE_STATUS) diff --git a/src/test/CLMonolithic_Test.cpp b/src/test/CLMonolithic_Test.cpp new file mode 100644 index 00000000000..8ee795f7e5c --- /dev/null +++ b/src/test/CLMonolithic_Test.cpp @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +/* +* this is a monolithic file that can be used to compile clucene tests using one source file. +* +* note: when creating a project add either this file, or all the other .cpp files, not both! +*/ + +#include "CuTest.cpp" +#include "testall.cpp" +#include "tests.cpp" + +#include "analysis/TestAnalysis.cpp" +#include "analysis/TestAnalyzers.cpp" +#include "debug/TestError.cpp" +#include "document/TestDateTools.cpp" +#include "document/TestDocument.cpp" +#include "document/TestField.cpp" +#include "document/TestNumberTools.cpp" +#include "index/IndexWriter4Test.cpp" +#include "index/TestAddIndexesNoOptimize.cpp" +#include "index/TestHighFreqTerms.cpp" +#include "index/TestIndexModifier.cpp" +#include "index/TestIndexReader.cpp" +#include "index/TestIndexWriter.cpp" +#include "index/TestReuters.cpp" +#include "index/TestTermVectorsReader.cpp" +#include "index/TestThreading.cpp" +#include "index/TestUtf8.cpp" +#include "queryParser/TestMultiFieldQueryParser.cpp" +#include "queryParser/TestQueryParser.cpp" +#include "search/BaseTestRangeFilter.cpp" +#include "search/CheckHits.cpp" +#include "search/QueryUtils.cpp" +#include "search/spans/TestBasics.cpp" +#include "search/spans/TestNearSpansOrdered.cpp" +#include "search/spans/TestSpanExplanations.cpp" +#include "search/spans/TestSpanExplanationsOfNonMatches.cpp" +#include "search/spans/TestSpanQueries.cpp" +#include "search/spans/TestSpansAdvanced2.cpp" +#include "search/spans/TestSpansAdvanced.cpp" +#include "search/spans/TestSpans.cpp" +#include "search/TestBoolean.cpp" +#include "search/TestConstantScoreRangeQuery.cpp" +#include "search/TestDateFilter.cpp" +#include "search/TestExplanations.cpp" +#include "search/TestExtractTerms.cpp" +#include "search/TestForDuplicates.cpp" +#include "search/TestIndexSearcher.cpp" +#include "search/TestQueries.cpp" +#include "search/TestRangeFilter.cpp" +#include "search/TestSearch.cpp" +#include "search/TestSort.cpp" +#include "search/TestTermVector.cpp" +#include "search/TestWildcard.cpp" +#include "store/MockRAMDirectory.cpp" +#include "store/TestRAMDirectory.cpp" +#include "store/TestStore.cpp" +#include "util/English.cpp" +#include "util/TestBitSet.cpp" +#include "util/TestPriorityQueue.cpp" +#include "util/TestStringBuffer.cpp" + diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt new file mode 100644 index 00000000000..8c1f57a248f --- /dev/null +++ b/src/test/CMakeLists.txt @@ -0,0 +1,276 @@ +PROJECT(clucene-test) + +INCLUDE(DefineOptions) +DEFINE_OPTIONS(EXTRA_OPTIONS EXTRA_LIBS) +ADD_DEFINITIONS(${EXTRA_OPTIONS}) + +INCLUDE_DIRECTORIES(${clucene-test_SOURCE_DIR}) + +SOURCE_GROUP("unit_testing" ./*.cpp) +SOURCE_GROUP("analysis" ./analysis/*) +SOURCE_GROUP("debug" ./debug/*) +SOURCE_GROUP("document" ./document/*) +SOURCE_GROUP("index" ./index/*) +SOURCE_GROUP("queryParser" ./queryParser/*) +SOURCE_GROUP("search" ./search/*) +SOURCE_GROUP("search-spans" ./search/spans/*) +SOURCE_GROUP("store" ./store/*) +SOURCE_GROUP("util" ./util/*) + +IF (BUILD_CONTRIBS_LIB) + SET(test_contribs_lib_files ./contribs-lib/analysis/de/TestGermanStemFilter.cpp util/TestBKD.cpp) + SET(EXTRA_LIBS ${EXTRA_LIBS} clucene-contribs-lib) + ADD_DEFINITIONS(-DTEST_CONTRIB_LIBS) + INCLUDE_DIRECTORIES(${clucene-test_SOURCE_DIR} ${clucene-contribs-lib_SOURCE_DIR}) + + SOURCE_GROUP("contribs-lib" REGULAR_EXPRESSION ./contribs-lib/*) + SOURCE_GROUP("contribs-lib\\analysis" REGULAR_EXPRESSION ./contribs-lib/analysis/*) + SOURCE_GROUP("contribs-lib\\analysis\\de" FILES ${test_contribs_lib_files}) +ENDIF (BUILD_CONTRIBS_LIB) + +file(GLOB_RECURSE test_HEADERS ${CMAKE_SOURCE_DIR}/test/*.h) + +SET(test_files ./tests.cpp + ./CuTest.cpp + ./testall.cpp + ./queryParser/TestQueryParser.cpp + ./queryParser/TestMultiFieldQueryParser.cpp + ./analysis/TestAnalysis.cpp + ./analysis/TestAnalyzers.cpp + ./debug/TestError.cpp + ./document/TestDateTools.cpp + ./document/TestDocument.cpp + ./document/TestNumberTools.cpp + ./document/TestField.cpp + ./store/TestStore.cpp + ./store/MockRAMDirectory.cpp + ./store/TestRAMDirectory.cpp + ./search/MockScorer.h + ./search/MockHitCollector.h + ./search/TestBoolean.cpp + ./search/TestDateFilter.cpp + ./search/TestForDuplicates.cpp + ./search/TestQueries.cpp + ./search/TestRangeFilter.cpp + ./search/TestSearch.cpp + ./search/TestSort.cpp + ./search/TestWildcard.cpp + ./search/TestTermVector.cpp + ./search/TestExtractTerms.cpp + ./search/TestConstantScoreRangeQuery.cpp + ./search/TestIndexSearcher.cpp + ./index/IndexWriter4Test.cpp + ./search/BaseTestRangeFilter.h + ./search/BaseTestRangeFilter.cpp + ./search/QueryUtils.h + ./search/QueryUtils.cpp + ./search/CheckHits.h + ./search/CheckHits.cpp + ./search/TestExplanations.cpp + ./search/TestExplanations.h + ./search/spans/TestSpans.h + ./search/spans/TestSpans.cpp + ./search/spans/TestSpanQueries.cpp + ./search/spans/TestBasics.h + ./search/spans/TestBasics.cpp + ./search/spans/TestSpansAdvanced.cpp + ./search/spans/TestSpansAdvanced.h + ./search/spans/TestSpansAdvanced2.cpp + ./search/spans/TestSpansAdvanced2.h + ./search/spans/TestNearSpansOrdered.cpp + ./search/spans/TestNearSpansOrdered.h + ./search/spans/TestSpanExplanations.cpp + ./search/spans/TestSpanExplanations.h + ./search/spans/TestSpanExplanationsOfNonMatches.cpp + ./search/spans/TestSpanExplanationsOfNonMatches.h + ./index/TestIndexModifier.cpp + ./index/TestIndexWriter.cpp + ./index/TestIndexModifier.cpp + ./index/TestIndexReader.cpp + ./index/TestThreading.cpp + ./index/TestUtf8.cpp + ./index/TestHighFreqTerms.cpp + ./index/TestReuters.cpp + ./index/TestAddIndexesNoOptimize.cpp + ./index/TestTermVectorsReader.cpp + ./util/TestPriorityQueue.cpp + ./util/TestBitSet.cpp + ./util/TestBKD.cpp + ./util/TestMSBRadixSorter.cpp + ./util/TestStringBuffer.cpp + ./util/English.cpp + ${test_HEADERS} + ) +IF (USE_SHARED_OBJECT_FILES) + GET_SHARED_FILES(clucene_shared_Files) +ENDIF (USE_SHARED_OBJECT_FILES) + +#todo: do glob header and include header files for IDE. +#ADD_EXECUTABLE(cl_test EXCLUDE_FROM_ALL ${clucene_shared_Files} ${test_files} ${test_contribs_lib_files}) + +#link the executable against the releavent clucene-shared library (if we aren't using the object files) +#IF (NOT USE_SHARED_OBJECT_FILES) +# TARGET_LINK_LIBRARIES(cl_test clucene-core clucene-shared ${EXTRA_LIBS}) +#ENDIF (NOT USE_SHARED_OBJECT_FILES) + +############################ +#special tests: +############################ + +IF (ENABLE_COMPILE_TESTS) + + #define zlib library requirements... + if (NOT USE_INTERNAL_ZLIB_LIBRARY) + find_package(ZLIB) + endif () + IF (ZLIB_FOUND) + SET(EXTRA_LIBS ${EXTRA_LIBS} ${ZLIB_LIBRARY}) + INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) + ENDIF (ZLIB_FOUND) + + SET(test_monolithic_Files ${clucene-core_SOURCE_DIR}/CLucene/CLMonolithic.cpp ./CLMonolithic_Test.cpp) + + SET(TESTS_CXX_FLAGS "-DMAKE_CLUCENE_SHARED_LIB -DMAKE_CLUCENE_CORE_LIB") + SET(TESTS_EXE_LINKER_FLAGS "${CMAKE_THREAD_LIBS_INIT}") + + ADD_EXECUTABLE(cl_test-ascii EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-ascii "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-ascii PROPERTIES + COMPILE_DEFINITIONS "_ASCII" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + ADD_CUSTOM_TARGET(test-ascii + COMMENT "Running cl_test-ascii" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-ascii + DEPENDS cl_test-ascii) + + ADD_EXECUTABLE(cl_test-namespace EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-namespace "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-namespace PROPERTIES + COMPILE_DEFINITIONS "DISABLE_NAMESPACE" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + ADD_CUSTOM_TARGET(test-namespace + COMMENT "Running cl_test-namespace" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-namespace + DEPENDS cl_test-namespace) + + ADD_EXECUTABLE(cl_test-mmap EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-mmap "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-mmap PROPERTIES + COMPILE_DEFINITIONS "LUCENE_FS_MMAP" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + ADD_CUSTOM_TARGET(test-mmap + COMMENT "Running cl_test-mmap" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-mmap + DEPENDS cl_test-mmap) + + ADD_EXECUTABLE(cl_test-singlethreading EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-singlethreading "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-singlethreading PROPERTIES + COMPILE_DEFINITIONS "_CL_DISABLE_MULTITHREADING" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + ADD_CUSTOM_TARGET(test-singlethreading + COMMENT "Running cl_test-singlethreading" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-singlethreading + DEPENDS cl_test-singlethreading) + + ADD_EXECUTABLE(cl_test-refcnt EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-refcnt "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-refcnt PROPERTIES + COMPILE_DEFINITIONS "LUCENE_ENABLE_REFCOUNT" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + ADD_CUSTOM_TARGET(test-refcnt + COMMENT "Running cl_test-refcnt" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-refcnt + DEPENDS cl_test-refcnt) + + ADD_EXECUTABLE(cl_test-platform-charfuncs EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-platform-charfuncs "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-platform-charfuncs PROPERTIES + COMPILE_DEFINITIONS "LUCENE_USE_INTERNAL_CHAR_FUNCTIONS=0" + COMPILE_FLAGS "${TESTS_CXX_FLAGS}" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS}") + #this one just tests that the compile works... tests will (mostly) fail, since the + #internal functions do not produce the exact results expected. + ADD_CUSTOM_TARGET(test-platform-charfuncs + COMMENT "Running cl_test-platform-charfuncs" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-platform-charfuncs + DEPENDS cl_test-platform-charfuncs) + + #this one last so we only have pedantic for test-pedantic + ADD_EXECUTABLE(cl_test-pedantic EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-pedantic "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-pedantic PROPERTIES + COMPILE_DEFINITIONS "" + COMPILE_FLAGS "${TESTS_CXX_FLAGS} -std=c++11 -pedantic -Wnon-virtual-dtor -Wundef -Wcast-align -Wchar-subscripts -W -Wformat-security -Wextra -Wall -Wno-long-long -Wno-sign-compare" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS} -Wall") + ADD_CUSTOM_TARGET(test-pedantic + COMMENT "Running cl_test-pedantic" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-pedantic + DEPENDS cl_test-pedantic) + + + CHECK_CXX_ACCEPTS_FLAG("-fprofile-arcs -ftest-coverage" GccFlagGcov) + IF (GccFlagGcov) + ADD_EXECUTABLE(cl_test-gcov EXCLUDE_FROM_ALL ${test_monolithic_Files}) + TARGET_LINK_LIBRARIES(cl_test-gcov "${EXTRA_LIBS}") + SET_TARGET_PROPERTIES(cl_test-gcov PROPERTIES + COMPILE_FLAGS "${TESTS_CXX_FLAGS} -fprofile-arcs -ftest-coverage" + LINK_FLAGS "${TESTS_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") + ADD_CUSTOM_TARGET(test-gcov + COMMENT "Running cl_test-gcov" + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-gcov + COMMAND lcov --directory CMakeFiles/cl_test-gcov.dir/__/core/CLucene -c -o clucene-coverage.info + COMMAND lcov --remove clucene-coverage.info "\"/usr/*\"" -o clucene-coverage.clean + COMMAND genhtml -o ${CMAKE_BINARY_DIR}/clucene-coverage clucene-coverage.clean + DEPENDS cl_test-gcov) + ENDIF (GccFlagGcov) + + ADD_CUSTOM_TARGET(ic-make + COMMENT "Running pfor make" + COMMAND ls ${CMAKE_SOURCE_DIR}/src/ext/for + COMMAND ls ${CMAKE_BINARY_DIR} + COMMAND make -j 8 + COMMAND cp ${CMAKE_SOURCE_DIR}/src/ext/for/libic.a ${CMAKE_BINARY_DIR}/bin/) + #target for running all tests + ADD_CUSTOM_TARGET(test-all + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-pedantic + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-ascii + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-namespace + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-mmap + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-singlethreading + COMMAND ${EXECUTABLE_OUTPUT_PATH}/cl_test-refcnt + DEPENDS cl_test-pedantic cl_test-ascii cl_test-namespace cl_test-mmap cl_test-singlethreading cl_test-refcnt cl_test-platform-charfuncs + ) + +ENDIF (ENABLE_COMPILE_TESTS) + +############################ + +IF (BUILD_STATIC_LIBRARIES) + PROJECT(clucene-test) + + ADD_EXECUTABLE(cl_test EXCLUDE_FROM_ALL ${clucene_shared_Files} ${test_files}) + if (__COMPILER_CLANG) + SET_TARGET_PROPERTIES(cl_test PROPERTIES + COMPILE_FLAGS "-O0 -fsanitize=address -DADDRESS_SANITIZER -g" + LINK_FLAGS "-fsanitize=address") + else () + SET_TARGET_PROPERTIES(cl_test PROPERTIES + COMPILE_FLAGS "-O0 -fsanitize=address -DADDRESS_SANITIZER -g" + LINK_FLAGS "-fsanitize=address -static-libasan") + endif () + IF (UNIX) + TARGET_LINK_LIBRARIES(cl_test clucene-core-static clucene-shared-static pthread ic ${EXTRA_LIBS}) + ELSE () + TARGET_LINK_LIBRARIES(cl_test clucene-core-static clucene-shared-static ic gtest ${EXTRA_LIBS}) + ENDIF (UNIX) + +ENDIF (BUILD_STATIC_LIBRARIES) + +############################ + diff --git a/src/test/CuTest.cpp b/src/test/CuTest.cpp new file mode 100644 index 00000000000..7977485919b --- /dev/null +++ b/src/test/CuTest.cpp @@ -0,0 +1,639 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CuTest.h" +#include +#include +#include +#include + +static int verbose = 0; +static int messyPrinting = 0; + +void CuInit(int argc, char *argv[]) +{ + int i; + + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-v")) { + verbose = 1; + } + if (!strcmp(argv[i], "-p")) { + messyPrinting = 1; + } + } +} + +/*-------------------------------------------------------------------------* + * CuTcs + *-------------------------------------------------------------------------*/ +TCHAR* CuStrAlloc(int size) +{ + TCHAR* n = (TCHAR*) malloc( sizeof(TCHAR) * (size) ); + return n; +} + +TCHAR* CuTcsCopy(TCHAR* old) +{ + int len = _tcslen(old); + TCHAR* n = CuStrAlloc(len + 1); + _tcscpy(n, old); + return n; +} +TCHAR* CuTcsCat(TCHAR* orig, TCHAR* add) +{ + int len = _tcslen(orig) + _tcslen(add); + TCHAR* n = CuStrAlloc(len + 1); + _tcscpy(n, orig); + _tcscat(n, add); + return n; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +TCHAR* CuTcsAlloc(int size) +{ + TCHAR* n = (TCHAR*) malloc( sizeof(TCHAR) * (size) ); + return n; +} + +TCHAR* CuTcsCopy(const TCHAR* old) +{ + int len = _tcslen(old); + TCHAR* n = CuTcsAlloc(len + 1); + _tcscpy(n, old); + return n; +} + +/*-------------------------------------------------------------------------* + * CuString + *-------------------------------------------------------------------------*/ + +void CuStringInit(CuString* str) +{ + str->length = 0; + str->size = STRING_MAX; + str->buffer = (TCHAR*) malloc(sizeof(TCHAR) * str->size); + str->buffer[0] = '\0'; +} + +CuString* CuStringNew(void) +{ + CuString* str = (CuString*) malloc(sizeof(CuString)); + str->length = 0; + str->size = STRING_MAX; + str->buffer = (TCHAR*) malloc(sizeof(TCHAR) * str->size); + str->buffer[0] = '\0'; + return str; +} + +void CuStringFree(CuString* str){ + free(str->buffer); + free(str); +} + +void CuStringResize(CuString* str, int newSize) +{ + str->buffer = (TCHAR*) realloc(str->buffer, sizeof(TCHAR) * newSize); + str->size = newSize; +} + +void CuStringAppend(CuString* str, const TCHAR* text) +{ + int length = _tcslen(text); + if (str->length + length + 1 >= str->size) + CuStringResize(str, str->length + length + 1 + STRING_INC); + str->length += length; + _tcscat(str->buffer, text); +} + +void CuStringAppendChar(CuString* str, TCHAR ch) +{ + TCHAR text[2]; + text[0] = ch; + text[1] = '\0'; + CuStringAppend(str, text); +} + +void CuStringAppendFormat(CuString* str, const TCHAR* format, ...) +{ + TCHAR buf[HUGE_STRING_LEN]; + va_list argp; + va_start(argp, format); + _vsntprintf(buf, HUGE_STRING_LEN,format, argp); + va_end(argp); + CuStringAppend(str, buf); +} + +void CuStringRead(CuString *str, TCHAR *path) +{ + path = NULL; + CU_TDUP(path,str->buffer); +} + +/*-------------------------------------------------------------------------* + * CuTest + *-------------------------------------------------------------------------*/ + +void CuTestInit(CuTest* t, const TCHAR* name, TestFunction function) +{ + t->name = CuTcsCopy(name); + t->notimpl = 0; + t->failed = 0; + t->ran = 0; + t->message = NULL; + t->function = function; +// t->jumpBuf = NULL; +} + +CuTest* CuTestNew(const TCHAR* name, TestFunction function) +{ + CuTest* tc = CU_ALLOC(CuTest); + CuTestInit(tc, name, function); + return tc; +} + +void CuTestDelete(CuTest* tst){ + free(tst->name); + if ( tst->message != NULL ) + free(tst->message); + free(tst); +} + +void CuNotImpl(CuTest* tc, const TCHAR* message) +{ + CuString* newstr = CuStringNew(); + CuStringAppend(newstr, message); + CuStringAppend(newstr, _T(" not implemented on this platform")); + tc->notimpl = 1; + CuMessage(tc,newstr->buffer); + CuStringFree(newstr); +// if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0); +} + +void CuFail(CuTest* tc, const TCHAR* format, ...) +{ + tc->failed = 1; + + TCHAR buf[HUGE_STRING_LEN]; + va_list argp; + va_start(argp, format); + _vsntprintf(buf, HUGE_STRING_LEN, format, argp); + va_end(argp); + +// CuMessage(tc,buf); + _CLTHROWT(CL_ERR_Runtime, buf); +} + +void CuFail(CuTest* tc, CLuceneError& e) +{ + tc->failed = 1; + throw e; +} + +void CuMessageV(CuTest* tc, const TCHAR* format, va_list& argp){ + TCHAR buf[HUGE_STRING_LEN]; + _vsntprintf(buf, HUGE_STRING_LEN, format, argp); + + TCHAR* old = tc->message; + if ( messyPrinting ){ + _tprintf(_T("%s"),buf); + }else{ + if ( old == NULL ){ + tc->message = CuTcsCopy(buf); + }else{ + tc->message = CuTcsCat(old,buf); + free(old); + } + } +} +void CuMessage(CuTest* tc, const TCHAR* format, ...){ + va_list argp; + va_start(argp, format); + CuMessageV(tc,format,argp); + va_end(argp); +} +void CuMessageA(CuTest* tc, const char* format, ...){ + va_list argp; + char buf[HUGE_STRING_LEN]; + TCHAR tbuf[HUGE_STRING_LEN]; + va_start(argp, format); + vsprintf(buf, format, argp); + va_end(argp); + + TCHAR* old = tc->message; + STRCPY_AtoT(tbuf,buf,HUGE_STRING_LEN); + if ( messyPrinting ){ + _tprintf(_T("%s"),buf); + }else{ + if ( old == NULL ){ + tc->message = CuTcsCopy(tbuf); + }else{ + tc->message = CuTcsCat(old,tbuf); + free(old); + } + } +} + +void CuAssert(CuTest* tc, const TCHAR* message, int condition) +{ + if (condition) return; + CuFail(tc, message); +} + +void CuAssertTrue(CuTest* tc, int condition, const TCHAR* msg) +{ + if (condition) return; + if (msg != NULL) + CuFail(tc, msg); + else + CuFail(tc, _T("assert failed")); +} + +void CuAssertEquals(CuTest* tc, const int32_t expected, const int32_t actual, const TCHAR* msg) +{ + CuAssertIntEquals(tc, msg, expected, actual); +} + +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, TCHAR* actual, bool bDelActual){ + CuString* message; + if (_tcscmp(expected, actual) == 0) { + if (bDelActual) _CLDELETE_LCARRAY(actual); + return; + } + message = CuStringNew(); + if (preMessage) { + CuStringAppend(message, preMessage); + CuStringAppend(message, _T(" : ") ); + } + CuStringAppend(message, _T("expected\n---->\n")); + CuStringAppend(message, expected); + CuStringAppend(message, _T("\n<----\nbut saw\n---->\n")); + CuStringAppend(message, actual); + if (bDelActual) _CLDELETE_LCARRAY(actual); + CuStringAppend(message, _T("\n<----")); + CuFail(tc, message->buffer); + CuStringFree(message); +} +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, const TCHAR* actual) +{ + CuString* message; + if (_tcscmp(expected, actual) == 0) { + return; + } + message = CuStringNew(); + if (preMessage) { + CuStringAppend(message, preMessage); + CuStringAppend(message, _T(" : ") ); + } + CuStringAppend(message, _T("expected\n---->\n")); + CuStringAppend(message, expected); + CuStringAppend(message, _T("\n<----\nbut saw\n---->\n")); + CuStringAppend(message, actual); + CuStringAppend(message, _T("\n<----")); + CuFail(tc, message->buffer); + CuStringFree(message); +} + +void CuAssertIntEquals(CuTest* tc, const TCHAR* preMessage, int expected, int actual) +{ + if (expected == actual) return; + TCHAR buf[STRING_MAX]; + if (preMessage != NULL){ + _sntprintf(buf, STRING_MAX, _T("%s : expected <%d> but was <%d>"), preMessage, expected, actual); + } else { + _sntprintf(buf, STRING_MAX, _T("Assert failed : expected <%d> but was <%d>"), expected, actual); + } + CuFail(tc, buf); +} +void CuAssertSizeEquals(CuTest* tc, const TCHAR* preMessage, size_t expected, size_t actual) +{ + if (expected == actual) return; + TCHAR buf[STRING_MAX]; + if (preMessage != NULL){ + _sntprintf(buf, STRING_MAX, _T("%s : expected <%d> but was <%d>"), preMessage, expected, actual); + } else { + _sntprintf(buf, STRING_MAX, _T("Assert failed : expected <%d> but was <%d>"), expected, actual); + } + CuFail(tc, buf); +} + +void CuAssertPtrEquals(CuTest* tc, const TCHAR* preMessage, const void* expected, const void* actual) +{ + TCHAR buf[STRING_MAX]; + if (expected == actual) return; + _sntprintf(buf, STRING_MAX,_T("%s : expected pointer <%p> but was <%p>"), preMessage, expected, actual); + CuFail(tc, buf); +} + +void CuAssertPtrNotNull(CuTest* tc, const TCHAR* preMessage, const void* pointer) +{ + TCHAR buf[STRING_MAX]; + if (pointer != NULL ) return; + _sntprintf(buf,STRING_MAX, _T("%s : null pointer unexpected, but was <%p>"), preMessage, pointer); + CuFail(tc, buf); +} + +void CuTestRun(CuTest* tc) +{ +// jmp_buf buf; +// tc->jumpBuf = &buf; +// if (setjmp(buf) == 0) +// { + tc->ran = 1; + (tc->function)(tc); +// } +// tc->jumpBuf = 0; +} + +/*-------------------------------------------------------------------------* + * CuSuite + *-------------------------------------------------------------------------*/ + +void CuSuiteInit(CuSuite* testSuite, const TCHAR *name) +{ + testSuite->name = NULL; + CU_TDUP(testSuite->name,name); + testSuite->count = 0; + testSuite->failCount = 0; + testSuite->notimplCount = 0; + testSuite->timeTaken = 0; +} + +CuSuite* CuSuiteNew(const TCHAR *name) +{ + CuSuite* testSuite = CU_ALLOC(CuSuite); + CuSuiteInit(testSuite, name); + return testSuite; +} + +void CuSuiteDelete(CuSuite* suite){ + free(suite->name); + for ( int i=0;icount;i++ ){ + CuTestDelete(suite->list[i]); + } + free(suite); +} + +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) +{ + assert(testSuite->count < MAX_TEST_CASES); + testSuite->list[testSuite->count] = testCase; + testSuite->count++; +} + +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2) +{ + int i; + for (i = 0 ; i < testSuite2->count ; ++i) + { + CuTest* testCase = testSuite2->list[i]; + CuSuiteAdd(testSuite, testCase); + } +} + +void CuSuiteRun(CuSuite* testSuite) +{ + int i; + uint64_t start = Misc::currentTimeMillis(); + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + try{ + CuTestRun(testCase); + }catch(CLuceneError& err){ + testCase->failed=1; + CuMessage(testCase,err.twhat()); + } + testSuite->timeTaken = Misc::currentTimeMillis() - start; + if (testCase->failed) { testSuite->failCount += 1; } + if (testCase->notimpl) { testSuite->notimplCount += 1; } + } +} + +void CuSuiteSummary(CuSuite* testSuite, CuString* summary, bool times) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + CuStringAppend(summary, testCase->failed ? _T("F") : + testCase->notimpl ? _T("N"): _T(".")); + } + if ( times ){ + int bufferLen = 25-summary->length-10; + for (int i=0;itimeTaken); + } + CuStringAppend(summary, _T("\n")); +} + +void CuSuiteOverView(CuSuite* testSuite, CuString* details) +{ + CuStringAppendFormat(details, _T("%d %s run: %d passed, %d failed, ") + _T("%d not implemented.\n"), + testSuite->count, + testSuite->count == 1 ? "test" : "tests", + testSuite->count - testSuite->failCount - + testSuite->notimplCount, + testSuite->failCount, testSuite->notimplCount); +} + +void CuSuiteDetails(CuSuite* testSuite, CuString* details) +{ + int i; + int failCount = 0; + + if (testSuite->failCount != 0 && verbose) + { + CuStringAppendFormat(details, _T("\nFailed tests in %s:\n"), testSuite->name); + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + if (testCase->failed) + { + failCount++; + CuStringAppendFormat(details, _T("%d) %s: %s\n"), + failCount, testCase->name, testCase->message); + } + } + } + if (testSuite->notimplCount != 0 && verbose) + { + CuStringAppendFormat(details, _T("\nNot Implemented tests in %s:\n"), testSuite->name); + for (i = 0 ; i < testSuite->count ; ++i) + { + CuTest* testCase = testSuite->list[i]; + if (testCase->notimpl) + { + failCount++; + CuStringAppendFormat(details, _T("%d) %s: %s\n"), + failCount, testCase->name, testCase->message); + } + } + } +} + +/*-------------------------------------------------------------------------* + * CuSuiteList + *-------------------------------------------------------------------------*/ + +CuSuiteList* CuSuiteListNew(const TCHAR *name) +{ + CuSuiteList* testSuite = CU_ALLOC(CuSuiteList); + testSuite->name = NULL; + CU_TDUP(testSuite->name,name); + testSuite->count = 0; + return testSuite; +} +void CuSuiteListDelete(CuSuiteList* lst){ + free(lst->name); + for ( int i=0;icount;i++ ){ + CuSuiteDelete(lst->list[i]); + } + free(lst); +} + +void CuSuiteListAdd(CuSuiteList *suites, CuSuite *origsuite) +{ + assert(suites->count < MAX_TEST_CASES); + suites->list[suites->count] = origsuite; + suites->count++; +} + +void CuSuiteListRun(CuSuiteList* testSuite) +{ + int i; + for (i = 0 ; i < testSuite->count ; ++i) + { + CuSuite* testCase = testSuite->list[i]; + CuSuiteRun(testCase); + } +} + +static const TCHAR *genspaces(int i) +{ + TCHAR *str = (TCHAR*)malloc((i + 1) * sizeof(TCHAR)); + for ( int j=0;jname); + for (i = 0 ; i < testSuite->count ; ++i) + { + bool hasprinted=false; + CuSuite* testCase = testSuite->list[i]; + CuString *str = CuStringNew(); + + size_t len = _tcslen(testCase->name); + const TCHAR* spaces = len>31?NULL:genspaces(31 - len); + _tprintf(_T(" %s:%s"), testCase->name, len>31?_T(""):spaces); + free((void*)spaces); + fflush(stdout); + + CuSuiteRun(testCase); + if ( verbose ){ + for ( int i=0;icount;i++ ){ + if ( testCase->list[i]->ran ){ + if ( testCase->list[i]->message != NULL ){ + if ( !hasprinted ) + printf("\n"); + _tprintf(_T(" %s:\n"),testCase->list[i]->name); + + TCHAR* msg = testCase->list[i]->message; + bool nl = true; + //write out message, indenting on new lines + while ( *msg != '\0' ){ + if ( nl ){ + printf(" "); + nl=false; + } + if ( *msg == '\n' ) + nl = true; + putc(*msg,stdout); + + msg++; + } + + if ( testCase->list[i]->message[_tcslen(testCase->list[i]->message)-1] != '\n' ) + printf("\n"); + hasprinted=true; + } + } + } + } + CuSuiteSummary(testCase, str, times); + if ( hasprinted ) + _tprintf(_T(" Result: %s\n"), str->buffer); + else + _tprintf(_T(" %s"), str->buffer); + + CuStringFree(str); + } + _tprintf(_T("\n")); +} + +int CuSuiteListDetails(CuSuiteList* testSuite, CuString* details) +{ + int i; + int failCount = 0; + int notImplCount = 0; + int count = 0; + + for (i = 0 ; i < testSuite->count ; ++i) + { + failCount += testSuite->list[i]->failCount; + notImplCount += testSuite->list[i]->notimplCount; + count += testSuite->list[i]->count; + } + CuStringAppendFormat(details, _T("%d %s run: %d passed, %d failed, ") + _T("%d not implemented.\n"), + count, + count == 1 ? _T("test") : _T("tests"), + count - failCount - notImplCount, + failCount, notImplCount); + + if (failCount != 0 && verbose) + { + for (i = 0 ; i < testSuite->count ; ++i) + { + CuString *str = CuStringNew(); + CuSuite* testCase = testSuite->list[i]; + if (testCase->failCount) + { + CuSuiteDetails(testCase, str); + CuStringAppend(details, str->buffer); + } + CuStringFree(str); + } + } + if (notImplCount != 0 && verbose) + { + for (i = 0 ; i < testSuite->count ; ++i) + { + CuString *str = CuStringNew(); + CuSuite* testCase = testSuite->list[i]; + if (testCase->notimplCount) + { + CuSuiteDetails(testCase, str); + CuStringAppend(details, str->buffer); + } + CuStringFree(str); + } + } + return failCount; +} + diff --git a/src/test/CuTest.h b/src/test/CuTest.h new file mode 100644 index 00000000000..d934ab1b292 --- /dev/null +++ b/src/test/CuTest.h @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef CU_TEST_H +#define CU_TEST_H + +/* CuString */ + +TCHAR* CuWstrAlloc(int size); +TCHAR* CuWstrCopy(const TCHAR* old); + +#define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) +#define CU_TDUP(dest,src) dest=((TCHAR*)malloc(sizeof(TCHAR)*_tcslen(src)+sizeof(TCHAR)));_tcscpy(dest,src); + +#define HUGE_STRING_LEN 8192 +#define STRING_MAX 256 +#define STRING_INC 256 + +#define CLUCENE_ASSERT(x) CuAssert(tc,_T("Assert Failed: ") _T(#x),x) + +typedef struct +{ + int length; + int size; + TCHAR* buffer; +} CuString; + +void CuStringInit(CuString* str); +CuString* CuStringNew(void); +void CuStringFree(CuString* str); +void CuStringRead(CuString* str, TCHAR* path); +void CuStringAppend(CuString* str, const TCHAR* text); +void CuStringAppendChar(CuString* str, TCHAR ch); +void CuStringAppendFormat(CuString* str, const TCHAR* format, ...); +void CuStringResize(CuString* str, int newSize); + +/* CuTest */ + +typedef struct CuTest CuTest; + +typedef void (*TestFunction)(CuTest *); + +struct CuTest +{ + TCHAR* name; + TestFunction function; + int notimpl; + int failed; + int ran; + TCHAR* message; +// jmp_buf *jumpBuf; +}; + + +void CuInit(int argc, char *argv[]); +void CuTestInit(CuTest* t, const TCHAR* name, TestFunction function); +CuTest* CuTestNew(const TCHAR* name, TestFunction function); +void CuTestDelete(CuTest* tst); +void CuFail(CuTest* tc, const TCHAR* format, ...); +void CuFail(CuTest* tc, CLuceneError& e); +void CuMessage(CuTest* tc, const TCHAR* message,...); +void CuMessageV(CuTest* tc, const TCHAR* format, va_list& argp); +void CuMessageA(CuTest* tc, const char* format, ...); +void CuNotImpl(CuTest* tc, const TCHAR* message); +void CuAssert(CuTest* tc, const TCHAR* message, int condition); +void CuAssertTrue(CuTest* tc, int condition, const TCHAR* msg = NULL); +void CuAssertEquals(CuTest* tc, const int32_t expected, const int32_t actual, const TCHAR* msg = NULL); +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, const TCHAR* actual); +void CuAssertStrEquals(CuTest* tc, const TCHAR* preMessage, const TCHAR* expected, TCHAR* actual, bool bDelActual = false); +void CuAssertIntEquals(CuTest* tc, const TCHAR* preMessage, int expected, int actual); +void CuAssertSizeEquals(CuTest* tc, const TCHAR* preMessage, int expected, int actual); +void CuAssertPtrEquals(CuTest* tc, const TCHAR* preMessage, const void* expected, const void* actual); +void CuAssertPtrNotNull(CuTest* tc, const TCHAR* preMessage, const void* pointer); + +void CuTestRun(CuTest* tc); + +/* CuSuite */ + +#define MAX_TEST_CASES 1024 + +#define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(_T(#TEST), TEST)) + +/* + * Macros used to make porting of Java Lucene tests easier. Assumes CuTest exists in the scope as tc + */ +#define assertTrue(CND) CuAssertTrue(tc, CND) +#define assertTrueMsg(MSG, CND) CuAssertTrue(tc, CND, MSG) +#define assertEquals(EXPECTED, ACTUAL) CuAssertEquals(tc, EXPECTED, ACTUAL) +#define assertEqualsMsg(MSG, EXPECTED, ACTUAL) CuAssertEquals(tc, EXPECTED, ACTUAL, MSG) + +extern char clucene_data_location[1024]; + +typedef struct +{ + TCHAR *name; + int count; + CuTest* list[MAX_TEST_CASES]; + int failCount; + int notimplCount; + uint64_t timeTaken; +} CuSuite; + + +void CuSuiteInit(CuSuite* testSuite, const TCHAR* name); +CuSuite* CuSuiteNew(const TCHAR* name); +void CuSuiteDelete(CuSuite* suite); +void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); +void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); +void CuSuiteRun(CuSuite* testSuite); +void CuSuiteSummary(CuSuite* testSuite, CuString* summary, bool times); +void CuSuiteOverView(CuSuite* testSuite, CuString* details); +void CuSuiteDetails(CuSuite* testSuite, CuString* details); + +typedef struct +{ + TCHAR *name; + int count; + CuSuite* list[MAX_TEST_CASES]; +} CuSuiteList; + + +struct unittest { + const char *testname; + CuSuite *(*func)(void); +}; + +CuSuiteList* CuSuiteListNew(const TCHAR* name); +void CuSuiteListDelete(CuSuiteList* lst); +void CuSuiteListAdd(CuSuiteList* testSuite, CuSuite *testCase); +void CuSuiteListRun(CuSuiteList* testSuite); +void CuSuiteListRunWithSummary(CuSuiteList* testSuite, bool verbose, bool times); +//void CuSuiteListSummary(CuSuiteList* testSuite, CuString* summary); +/* Print details of test suite results; returns total number of + * tests which failed. */ +int CuSuiteListDetails(CuSuiteList* testSuite, CuString* details); +#endif /* CU_TEST_H */ diff --git a/src/test/README b/src/test/README new file mode 100644 index 00000000000..d813f6ed145 --- /dev/null +++ b/src/test/README @@ -0,0 +1,239 @@ +Writing CLucene tests + +The Full Suite +-------------- + +/* The driver function. This must return a CuSuite variable, which will + * then be used to actually run the tests. Essentially, all Suites are a + * collection of tests. The driver will take each Suite, and put it in a + * SuiteList, which is a collection of Suites. + */ +CuSuite *testtime(void) +{ + /* The actual suite, this must be created for each test program. Please + * give it a useful name, that will inform the user of the feature being + * tested. + */ + CuSuite *suite = CuSuiteNew("Test Time"); + + /* Each function must be added to the suite. Each function represents + * a single test. It is possible to test multiple features in a single + * function, although no tests currently do that. + */ + SUITE_ADD_TEST(suite, test_now); + SUITE_ADD_TEST(suite, test_gmtstr); + SUITE_ADD_TEST(suite, test_localstr); + SUITE_ADD_TEST(suite, test_exp_get_gmt); + SUITE_ADD_TEST(suite, test_exp_get_lt); + SUITE_ADD_TEST(suite, test_imp_gmt); + SUITE_ADD_TEST(suite, test_rfcstr); + SUITE_ADD_TEST(suite, test_ctime); + SUITE_ADD_TEST(suite, test_strftime); + SUITE_ADD_TEST(suite, test_strftimesmall); + SUITE_ADD_TEST(suite, test_exp_tz); + SUITE_ADD_TEST(suite, test_strftimeoffset); + + /* You must return the suite so that the driver knows which suites to + * run. + */ + return suite; +} + +Building the full driver +------------------------ + +All you need to do to build the full driver is run: + + make testall + +To run it, run: + + ./testall + +Caveats +------- + +Currently, some tests are known to fail in certain circumstances: + + * 'testpoll' opens 64 sockets concurrently; ensure that resource +limits are high enough to allow this (using ulimit or limit); for +instance, Solaris <=2.7 and HP-UX 11.00 both set the limit to <=64 by +default + + * 'testipsub' will tickle the Solaris 8 getaddrinfo() IPv6 +bug, causing the test to hang. Configure with --disable-ipv6 if using +an unpatched Solaris 8 installation. + + * The 'testdso' tests will not work if configured with +--disable-shared since the loadable modules cannot be built. + +Running individual tests +--------------------------------- + +It is not possible to build individual tests, however it is possible to +run individual tests. When running the test suite, specify the name of the +tests that you want to run on the command line. For example: + + ./testall teststr testrand + +Will run the Strings and Random generator tests. + +Reading the test suite output +----------------------------- + +Once you run the test suite, you will get output like: + +All APR Tests: + Test Strings: .... + Test Time: ............ + +16 tests run: 16 passed, 0 failed, 0 not implemented. + +There are a couple of things to look at with this. First, if you look at the +first function in this document, you should notice that the string passed to +the CuSuiteNew function is in the output. That is why the string should +explain the feature you are testing. + +Second, this test passed completely. This is obvious in two ways. First, and +most obvious, the summary line tells you that 16 tests were run and 16 tests +passed. However, the results can also be found in the lines above. Every +'.' in the output represents a passed test. + +If a test fails, the output will look like: + +All APR Tests: + Test Strings: .... + Test Time: ..F......... + +16 tests run: 15 passed, 1 failed, 0 not implemented. + +This is not very useful, because you don't know which test failed. However, +once you know that a test failed, you can run the suite again, with the +-v option. If you do this, you will get something like: + +All APR Tests: + Test Strings: .... + Test Time: ..F......... + +16 tests run: 15 passed, 1 failed, 0 not implemented. +Failed tests: +1) test_localstr: assert failed + +In this case, we know the test_localstr function failed, and there is an +Assert in this that failed (I modified the test to fail for this document). +Now, you can look at what that test does, and why it would have failed. + +There is one other possible output for the test suite (run with -v): + +All APR Tests: + Test Strings: .... + Test Time: ..N......... + +16 tests run: 15 passed, 0 failed, 1 not implemented. + +Not Implemented tests: + +Not Implemented tests: +1) test_localstr: apr_time_exp_lt not implemented on this platform + +The 'N' means that a function has returned APR_ENOTIMPL. This should be +treated as an error, and the function should be implemented as soon as +possible. + +Adding New test Suites to the full driver +------------------------------------------- + +To add a new Suite to the full driver, you must make a couple of modifications. + +1) Edit test_apr.h, and add the prototype for the function. +2) Edit testall.c, and add the function and name to the tests array. +3) Edit Makefile.in, and add the .lo file to the testall target. + +Once those four things are done, your tests will automatically be added +to the suite. + +Writing tests +------------- + +There are a couple of rules for writing good tests for the test suite. + +1) All tests can determine for themselves if it passed or not. This means +that there is no reason for the person running the test suite to interpret +the results of the tests. +2) Never use printf to add to the output of the test suite. The suite +library should be able to print all of the information required to debug +a problem. +3) Functions should be tested with both positive and negative tests. This +means that you should test things that should both succeed and fail. +4) Just checking the return code does _NOT_ make a useful test. You must +check to determine that the test actually did what you expected it to do. + +An example test +--------------- + +Finally, we will look at a quick test: + +/* All tests are passed a CuTest variable. This is how the suite determines + * if the test succeeded or failed. + */ +static void test_localstr(CuTest *tc) +{ + apr_status_t rv; + apr_time_exp_t xt; + time_t os_now; + + rv = apr_time_exp_lt(&xt, now); + os_now = now / APR_USEC_PER_SEC; + + /* If the function can return APR_ENOTIMPL, then you should check for it. + * This allows platform implementors to know if they have to implement + * the function. + */ + if (rv == APR_ENOTIMPL) { + CuNotImpl(tc, "apr_time_exp_lt"); + } + + /* It often helps to ensure that the return code was APR_SUCESS. If it + * wasn't, then we know the test failed. + */ + CuAssertTrue(tc, rv == APR_SUCCESS); + + /* Now that we know APR thinks it worked properly, we need to check the + * output to ensure that we got what we expected. + */ + CuAssertStrEquals(tc, "2002-08-14 12:05:36.186711 -25200 [257 Sat] DST", + print_time(p, &xt)); +} + +Notice, the same test can fail for any of a number of reasons. The first +test to fail ends the test. + +CuTest +------ + +CuTest is an open source test suite written by Asim Jalis. It has been +released under the zlib/libpng license. That license can be found in the +CuTest.c and CuTest.h files. + +The version of CuTest that is included in the APR test suite has been modified +from the original distribution in the following ways: + +1) The original distribution does not have a -v flag, the details are always +printed. +2) The NotImplemented result does not exist. +3) SuiteLists do not exist. In the original distribution, you can add suites +to suites, but it just adds the tests in the first suite to the list of tests +in the original suite. The output wasn't as detailed as I wanted, so I created +SuiteLists. + +The first two modifications have been sent to the original author of CuTest, +but they have not been integrated into the base distribution. The SuiteList +changes will be sent to the original author soon. + +The modified version of CuTest is not currently in any CVS or Subversion +server. In time, it will be hosted at rkbloom.net. + +There are currently no docs for how to write tests, but the teststr and +testtime programs should give an idea of how it is done. In time, a document +should be written to define how tests are written. + diff --git a/src/test/analysis/TestAnalysis.cpp b/src/test/analysis/TestAnalysis.cpp new file mode 100644 index 00000000000..f74193965b1 --- /dev/null +++ b/src/test/analysis/TestAnalysis.cpp @@ -0,0 +1,110 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +void test(CuTest *tc, Reader *reader, bool verbose, int64_t bytes) { + StandardAnalyzer analyzer; + TokenStream *stream = analyzer.tokenStream(NULL, reader); + + uint64_t start = Misc::currentTimeMillis(); + + int32_t count = 0; + CL_NS(analysis)::Token t; + while (stream->next(&t) != NULL) { + if (verbose) { + CuMessage(tc, _T("Text=%s start=%d end=%d\n"), t.termBuffer(), t.startOffset(), t.endOffset()); + } + count++; + } + + uint64_t end = Misc::currentTimeMillis(); + int64_t time = end - start; + CuMessageA(tc, "%d milliseconds to extract ", (int32_t) time); + CuMessageA(tc, "%d tokens\n", count); + CuMessageA(tc, "%f microseconds/token\n", (time * 1000.0) / count); + CuMessageA(tc, "%f megabytes/hour\n", (bytes * 1000.0 * 60.0 * 60.0) / (time * 1000000.0)); + + _CLDELETE(stream); +} + +/*todo: move this to contribs because we have no filereader + void _testFile(CuTest *tc,const char* fname, bool verbose) { + struct cl_stat_t buf; + fileStat(fname,&buf); + + int64_t bytes = buf.st_size; + + CuMessageA(tc," Reading test file containing %d bytes.\n", bytes ); + FileReader fr (fname); + const TCHAR *start; + size_t total = 0; + do { + size_t numRead = fr.read(start, numRead); + total += numRead; + } while (numRead >= 0); + test(tc,&fr, verbose, total); + fr.close(); + }*/ + +void _testText(CuTest *tc, const TCHAR *text, bool verbose) { + CuMessage(tc, _T(" Tokenizing string: %s\n"), text); + StringReader reader(text); + test(tc, &reader, verbose, _tcslen(text)); +} + +void testTokenStreamField(CuTest *tc) { + const char *text = "This is a test 123_test"; + SStringReader reader(text, strlen(text)); + SimpleAnalyzer analyzer; + TokenStream *stream = analyzer.reusableTokenStream(L"field1", &reader); + + int field_config = lucene::document::Field::STORE_NO | lucene::document::Field::INDEX_TOKENIZED; + auto field = _CLNEW Field(L"field1", field_config); + field->setValue(stream); + auto s = field->tokenStreamValue(); + int32_t count = 0; + CL_NS(analysis)::Token t; + while (s->next(&t) != NULL) { + count++; + } + CuAssertEquals(tc, count, 6); + //printf("count = %d\n", count); + //_CLDELETE(stream); +} + +void testChar(CuTest *tc) { + const char *text = "This is a test 123_test"; + SStringReader reader(text, strlen(text)); + SimpleAnalyzer analyzer; + TokenStream *stream = analyzer.tokenStream(NULL, &reader); + + int32_t count = 0; + CL_NS(analysis)::Token t; + while (stream->next(&t) != NULL) { + count++; + } + printf("count = %d\n", count); + _CLDELETE(stream); +} + +void testText(CuTest *tc) { + _testText(tc, _T("This is a test"), true); +} +/* void testFile(CuTest *tc){ + CuAssert(tc,_T("words.txt does not exist"),Misc::dir_Exists(CLUCENE_LOCATION "reuters-21578/feldman-cia-worldfactbook-data.txt")); + _testFile(tc,CLUCENE_LOCATION "reuters-21578/feldman-cia-worldfactbook-data.txt",false); + }*/ + +CuSuite *testanalysis(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Analysis Test")); + + SUITE_ADD_TEST(suite, testChar); + SUITE_ADD_TEST(suite, testText); + SUITE_ADD_TEST(suite, testTokenStreamField); + return suite; +} +// EOF diff --git a/src/test/analysis/TestAnalyzers.cpp b/src/test/analysis/TestAnalyzers.cpp new file mode 100644 index 00000000000..f9a2d09c2f4 --- /dev/null +++ b/src/test/analysis/TestAnalyzers.cpp @@ -0,0 +1,524 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/analysis/standard/StandardTokenizer.h" + +// Ported from Java Lucene tests + + void assertAnalyzesTo(CuTest *tc,Analyzer* a, const TCHAR* input, const TCHAR* output){ + Reader* reader = _CLNEW StringReader(input); + TokenStream* ts = a->tokenStream(_T("dummy"), reader ); + + const TCHAR* pos = output; + TCHAR buffer[80]; + const TCHAR* last = output; + CL_NS(analysis)::Token t; + while( (pos = _tcsstr(pos+1, _T(";"))) != NULL ) { + int32_t len = (int32_t)(pos-last); + _tcsncpy(buffer,last,len); + buffer[len]=0; + + CLUCENE_ASSERT(ts->next(&t)!=NULL); + CLUCENE_ASSERT( t.termLength () == _tcslen(buffer) ); + CLUCENE_ASSERT(_tcscmp( t.termBuffer (), buffer) == 0 ); + + last = pos+1; + } + CLUCENE_ASSERT(ts->next(&t)==NULL); //Test failed, more fields than expected. + + ts->close(); + _CLDELETE(reader); + _CLDELETE(ts); + } + + void assertReusableAnalyzesTo(CuTest *tc,Analyzer* a, const TCHAR* input, const TCHAR* output){ + Reader* reader = _CLNEW StringReader(input); + TokenStream* ts = a->reusableTokenStream(_T("dummy"), reader ); + + const TCHAR* pos = output; + TCHAR buffer[80]; + const TCHAR* last = output; + CL_NS(analysis)::Token t; + while( (pos = _tcsstr(pos+1, _T(";"))) != NULL ) { + int32_t len = (int32_t)(pos-last); + _tcsncpy(buffer,last,len); + buffer[len]=0; + + CLUCENE_ASSERT(ts->next(&t)!=NULL); + CLUCENE_ASSERT( t.termLength () == _tcslen(buffer) ); + CLUCENE_ASSERT(_tcscmp( t.termBuffer (), buffer) == 0 ); + + last = pos+1; + } + CLUCENE_ASSERT(ts->next(&t)==NULL); //Test failed, more fields than expected. + + ts->close(); + _CLLDELETE(reader); + } + + void testSimpleAnalyzer(CuTest *tc){ + Analyzer* a = _CLNEW SimpleAnalyzer (); + assertAnalyzesTo(tc,a, _T("foo bar FOO BAR"), _T("foo;bar;foo;bar;") ); + assertAnalyzesTo(tc,a, _T("foo bar . FOO <> BAR"), _T("foo;bar;foo;bar;")); + assertAnalyzesTo(tc,a, _T("foo.bar.FOO.BAR"), _T("foo;bar;foo;bar;")); + assertAnalyzesTo(tc,a, _T("U.S.A."), _T("u;s;a;") ); + assertAnalyzesTo(tc,a, _T("C++"), _T("c;") ); + assertAnalyzesTo(tc,a, _T("B2B"), _T("b2b;")); + assertAnalyzesTo(tc,a, _T("2B"), _T("2b;")); + assertAnalyzesTo(tc,a, _T("\"QUOTED\" word"), _T("quoted;word;")); + + _CLLDELETE(a); + } + + void useKeywordTokenizer(CuTest *tc, const TCHAR* text) { + StringReader reader(text); + KeywordTokenizer tokenizer(&reader, 1); + Token t; + CuAssertTrue(tc, tokenizer.next(&t) != NULL, _T("token expected")); + CuAssertStrEquals(tc, _T(""), text, t.termBuffer (), false); + CuAssertTrue(tc, tokenizer.next(&t) == NULL, _T("no further token expected")); + } + + // Tracker-Id: 3106808 + void testKeywordTokenizer(CuTest *tc) { + useKeywordTokenizer(tc, _T("1")); + useKeywordTokenizer(tc, _T("12")); + useKeywordTokenizer(tc, _T("123")); + useKeywordTokenizer(tc, _T("1234")); + useKeywordTokenizer(tc, _T("12345")); + useKeywordTokenizer(tc, _T("123456")); + useKeywordTokenizer(tc, _T("1234567")); + useKeywordTokenizer(tc, _T("12345678")); + useKeywordTokenizer(tc, _T("123456789")); + useKeywordTokenizer(tc, _T("1234567812345678")); + useKeywordTokenizer(tc, _T("123456781234567812345678")); + } + + void testKeywordAnalyzer(CuTest *tc){ + Analyzer* a = _CLNEW KeywordAnalyzer(); + + assertAnalyzesTo(tc,a, _T("foo bar FOO BAR"), _T("foo bar FOO BAR;") ); + assertAnalyzesTo(tc,a, _T("foo bar . FOO <> BAR"), _T("foo bar . FOO <> BAR;")); + assertAnalyzesTo(tc,a, _T("foo.bar.FOO.BAR"), _T("foo.bar.FOO.BAR;")); + assertAnalyzesTo(tc,a, _T("U.S.A."), _T("U.S.A.;") ); + assertAnalyzesTo(tc,a, _T("C++"), _T("C++;") ); + assertAnalyzesTo(tc,a, _T("B2B"), _T("B2B;")); + assertAnalyzesTo(tc,a, _T("2B"), _T("2B;")); + assertAnalyzesTo(tc,a, _T("\"QUOTED\" word"), _T("\"QUOTED\" word;")); + + _CLDELETE(a); + } + + void testNull(CuTest *tc){ + Analyzer* a = _CLNEW WhitespaceAnalyzer (); + assertAnalyzesTo(tc,a, _T("foo bar FOO BAR"), _T("foo;bar;FOO;BAR;")); + assertAnalyzesTo(tc,a, _T("foo bar . FOO <> BAR"), _T("foo;bar;.;FOO;<>;BAR;")); + assertAnalyzesTo(tc,a, _T("foo.bar.FOO.BAR"), _T("foo.bar.FOO.BAR;")); + assertAnalyzesTo(tc,a, _T("U.S.A."), _T("U.S.A.;")); + assertAnalyzesTo(tc,a, _T("C++"), _T("C++;")); + assertAnalyzesTo(tc,a, _T("B2B"), _T("B2B;")); + assertAnalyzesTo(tc,a, _T("2B"), _T("2B;")); + assertAnalyzesTo(tc,a, _T("\"QUOTED\" word"), _T("\"QUOTED\";word;") ); + + _CLLDELETE(a); + } + + void testStop(CuTest *tc){ + Analyzer* a = _CLNEW StopAnalyzer(); + assertAnalyzesTo(tc,a, _T("foo bar FOO BAR"), _T("foo;bar;foo;bar;")); + assertAnalyzesTo(tc,a, _T("foo a bar such FOO THESE BAR"), _T("foo;bar;foo;bar;")); + + _CLLDELETE(a); + } + + class BuffTokenFilter : public TokenFilter { + public: + std::list* lst; + + BuffTokenFilter(TokenStream* input) : TokenFilter(input), lst(NULL) { + } + + virtual ~BuffTokenFilter() + { + _CLLDELETE(lst); + } + + Token* next(Token* t) { + if (lst == NULL) { + lst = new std::list(); + for(;;) { + if (input->next(t) == NULL) break; + lst->push_back(t); + } + } + if (lst->size()==0) return NULL; + Token* ret = lst->back(); + lst->pop_back(); + return ret; + } + }; + + class PayloadSetter : public TokenFilter { + public: + ValueArray* data; + Payload* p; + + PayloadSetter(TokenStream* input) : TokenFilter(input), data(_CLNEW ValueArray) { + p = _CLNEW Payload(data->values, 1, false); + } + + Token* next(Token* target) { + if (input->next(target) == NULL) return NULL; + target->setPayload(p); // reuse the payload / byte[] + data->values[0]++; + return target; + } + }; + + void verifyPayload(CuTest* tc, TokenStream* ts) { + Token* t = _CLNEW Token(); + for(uint8_t b=1;;b++) { + t->clear(); + if ( ts->next(t) ) break; + // System.out.println("id="+System.identityHashCode(t) + " " + t); + // System.out.println("payload=" + (int)t.getPayload().toByteArray()[0]); + const ValueArray* pl = t->getPayload()->toByteArray(); + assertTrue(b == pl->values[0]); + _CLLDELETE(pl); + } + _CLLDELETE(t); + } + + // Make sure old style next() calls result in a new copy of payloads + void testPayloadCopy(CuTest* tc) { + const TCHAR* s = _T("how now brown cow"); + TokenStream* ts; + ts = _CLNEW WhitespaceTokenizer (_CLNEW StringReader(s)); + ts = _CLNEW BuffTokenFilter(ts); + ts = _CLNEW PayloadSetter(ts); + verifyPayload(tc, ts); + _CLLDELETE(ts); + + ts = _CLNEW WhitespaceTokenizer (_CLNEW StringReader(s)); + ts = _CLNEW PayloadSetter(ts); + ts = _CLNEW BuffTokenFilter(ts); + verifyPayload(tc, ts); + _CLLDELETE(ts); + } + + // LUCENE-1150: Just a compile time test, to ensure the + // StandardAnalyzer constants remain publicly accessible + void _testStandardConstants() { + int x = standard::ALPHANUM; + x = standard::APOSTROPHE; + x = standard::ACRONYM; + x = standard::COMPANY; + x = standard::EMAIL; + x = standard::HOST; + x = standard::NUM; + x = standard::CJK; // TODO: Java Lucene 2.3.2 declares this as CJ + // const TCHAR** y = standard::tokenImage; <-- TODO: Failing compile time test + } + +// TestPerFieldAnalzyerWrapper.Java + void testPerFieldAnalzyerWrapper(CuTest *tc){ + const TCHAR* text = _T("Qwerty"); + PerFieldAnalyzerWrapper analyzer(_CLNEW WhitespaceAnalyzer ()); + + analyzer.addAnalyzer(_T("special"), _CLNEW SimpleAnalyzer ()); + + StringReader reader(text); + TokenStream* tokenStream = analyzer.tokenStream( _T("field"), &reader); + CL_NS(analysis)::Token token; + + CLUCENE_ASSERT( tokenStream->next(&token) != NULL ); + CuAssertStrEquals(tc,_T("token.termBuffer()"), _T("Qwerty"), + token.termBuffer ()); + _CLDELETE(tokenStream); + + StringReader reader2(text); + tokenStream = analyzer.tokenStream(_T("special"), &reader2); + CLUCENE_ASSERT( tokenStream->next(&token) != NULL ); + CuAssertStrEquals(tc, _T("token.termBuffer()"), _T("qwerty"), + token.termBuffer ()); + _CLDELETE(tokenStream); + } + +// A CLucene-specific test +#define USE_PER_FIELD_ANALYZER +//#define SUB_ANALYZER_TYPE lucene::analysis::WhitespaceAnalyzer +#define SUB_ANALYZER_TYPE lucene::analysis::standard::StandardAnalyzer + + void testPerFieldAnalzyerWrapper2(CuTest *tc){ + try { +#ifdef USE_PER_FIELD_ANALYZER + lucene::analysis::PerFieldAnalyzerWrapper analyzer( + _CLNEW lucene::analysis::standard::StandardAnalyzer()); + analyzer.addAnalyzer(_T("First"), _CLNEW SUB_ANALYZER_TYPE()); + analyzer.addAnalyzer(_T("Second"), _CLNEW SUB_ANALYZER_TYPE()); + analyzer.addAnalyzer(_T("Third"), _CLNEW SUB_ANALYZER_TYPE()); + analyzer.addAnalyzer(_T("Fourth"), _CLNEW SUB_ANALYZER_TYPE()); + analyzer.addAnalyzer(_T("Fifth"), _CLNEW SUB_ANALYZER_TYPE()); +#else + lucene::analysis::WhitespaceAnalyzer analyzer; +#endif + char INDEX_PATH[CL_MAX_PATH]; + sprintf(INDEX_PATH,"%s/%s",cl_tempDir, "test.analyzers"); + lucene::index::IndexWriter writer(INDEX_PATH, &analyzer, true); + lucene::document::Document doc; + int flags = lucene::document::Field::STORE_YES + | lucene::document::Field::INDEX_TOKENIZED; + for (int i = 0; i < 100/*00000*/; i++) { + doc.clear(); + doc.add(*(_CLNEW lucene::document::Field( + _T("First"), _T("Blah blah blah"), flags))); + doc.add(*(_CLNEW lucene::document::Field( + _T("Second"), _T("Blah blah-- blah"), flags))); + doc.add(*(_CLNEW lucene::document::Field( + _T("Fifth"), _T("Blah blah__ blah"), flags))); + doc.add(*(_CLNEW lucene::document::Field( + _T("Eigth"), _T("Blah blah blah++"), flags))); + doc.add(*(_CLNEW lucene::document::Field( + _T("Ninth"), _T("Blah123 blah blah"), flags))); + writer.addDocument(&doc); + } + writer.close(); + } catch (CLuceneError err) { + printf("CLuceneError: %s", err.what()); + } + } + + + void testEmptyStopList(CuTest *tc) + { + const TCHAR* stopWords = { NULL }; + StandardAnalyzer a(&stopWords); + RAMDirectory ram; + IndexWriter writer(&ram, &a, true); + + Document doc; + doc.add(*(_CLNEW lucene::document::Field( + _T("First"), _T("Blah blah blah"), Field::STORE_YES | Field::INDEX_TOKENIZED))); + writer.addDocument(&doc); + writer.close(); + + IndexSearcher searcher(&ram); + Query* q = QueryParser::parse(_T("blah"), _T("First"), &a); + Hits* h = searcher.search(q); + _CLLDELETE(h); + _CLLDELETE(q); + } + + void testStandardAnalyzer(CuTest *tc){ + Analyzer* a = _CLNEW StandardAnalyzer(); + + //todo: check this + assertAnalyzesTo(tc,a, _T("[050-070]"), _T("050;-070;") ); + assertReusableAnalyzesTo(tc,a, _T("[050-070]"), _T("050;-070;") ); + assertReusableAnalyzesTo(tc,a, _T("[050-070]"), _T("050;-070;") ); + + _CLDELETE(a); + } + + void testISOLatin1AccentFilter(CuTest *tc){ + TCHAR str[200]; + _tcscpy(str, _T("Des mot cl\xe9s \xc0 LA CHA\xceNE \xc0 \xc1 \xc2 ") //Des mot cl?s ? LA CHA?NE ? ? ? + _T("\xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf") //? ? ? ? ? ? ? ? ? ? ? ? ? + _T(" \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd8 \xde \xd9 \xda \xdb") //? ? ? ? ? ? ? ? ? ? ? ? ? + _T(" \xdc \xdd \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 ") //? ? ? ? ? ? ? ? ? ? ? + _T("\xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 ") //? ? ? ? ? ? ? ? ? ? ? ? ? + _T("\xf8 \xdf \xfe \xf9 \xfa \xfb \xfc \xfd \xff") //? ? ? ? ? ? ? ? ? + _T(" ") ); //room for extra latin stuff + #ifdef _UCS2 + int p = _tcslen(str)-6; + str[p+1] = 0x152;// ? + str[p+3] = 0x153;// ? + str[p+5] = 0x178;//? + #endif + + StringReader reader(str); + WhitespaceTokenizer ws(&reader); + ISOLatin1AccentFilter filter(&ws,false); + CL_NS(analysis)::Token token; + + + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("Des"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("mot"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("cles"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("LA"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("CHAINE"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("A"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("AE"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("C"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("E"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("E"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("E"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("E"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("I"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("I"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("I"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("I"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("D"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("N"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("O"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("TH"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("U"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("U"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("U"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("U"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("Y"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("a"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("ae"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("c"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("e"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("e"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("e"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("e"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("i"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("i"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("i"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("i"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("d"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("n"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("o"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("ss"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("th"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("u"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("u"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("u"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("u"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("y"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("y"), token.termBuffer()); + + #ifdef _UCS2 + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("OE"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("oe"), token.termBuffer()); + CLUCENE_ASSERT(filter.next(&token) != NULL); CuAssertStrEquals(tc, _T("Token compare"), _T("Y"), token.termBuffer()); + #endif + + + CLUCENE_ASSERT(filter.next(&token)==NULL); + } + + void testWordlistLoader(CuTest *tc){ + char stopwordsfile[1024]; + strcpy(stopwordsfile, clucene_data_location); + strcat(stopwordsfile, "/StopWords.test"); + Analyzer* a = _CLNEW StopAnalyzer(stopwordsfile); + assertAnalyzesTo(tc,a, _T("foo bar FOO BAR"), _T("foo;bar;foo;bar;")); + assertAnalyzesTo(tc,a, _T("foo a bar such FOO THESE BAR"), _T("foo;bar;foo;bar;")); + + _CLDELETE(a); + + TCHAR testString[10]; + _tcscpy(testString, _T("test")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T("test ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T("test ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" test")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" test")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" test ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" test ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" test ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("test")); + _tcscpy(testString, _T(" te st ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("te")); + _tcscpy(testString, _T("tes t")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("tes")); + _tcscpy(testString, _T(" t est ")); + CuAssertStrEquals(tc, _T("stringTrim compare"), CL_NS(util)::Misc::wordTrim(testString), _T("t")); + } + + void testMutipleDocument(CuTest *tc) { + RAMDirectory dir; + KeywordAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter(&dir,&a, true); + Document* doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("partnum"), _T("Q36"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("partnum"), _T("Q37"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + writer->close(); + _CLLDELETE(writer); + + IndexReader* reader = IndexReader::open(&dir); + Term* t = _CLNEW Term(_T("partnum"), _T("Q36")); + TermDocs* td = reader->termDocs(t); + _CLDECDELETE(t); + CLUCENE_ASSERT(td->next()); + t = _CLNEW Term(_T("partnum"), _T("Q37")); + td = reader->termDocs(t); + _CLDECDELETE(t); + reader->close(); + CLUCENE_ASSERT(td->next()); + _CLLDELETE(reader); + } + +CuSuite *testanalyzers(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Analyzers Test")); + + // Ported from TestAnalyzers.java + SUITE_ADD_TEST(suite, testSimpleAnalyzer); + SUITE_ADD_TEST(suite, testStandardAnalyzer); + SUITE_ADD_TEST(suite, testNull); + SUITE_ADD_TEST(suite, testStop); + SUITE_ADD_TEST(suite, testKeywordTokenizer); + SUITE_ADD_TEST(suite, testPerFieldAnalzyerWrapper); + /*SUITE_ADD_TEST(suite, testNull); + SUITE_ADD_TEST(suite, testStop); + SUITE_ADD_TEST(suite, testKeywordTokenizer); + SUITE_ADD_TEST(suite, testStandardAnalyzer); + //SUITE_ADD_TEST(suite, testPayloadCopy); // <- TODO: Finish Payload and remove asserts before enabling this test + + // Ported from TestPerFieldAnalzyerWrapper.java + 1 test of our own + SUITE_ADD_TEST(suite, testPerFieldAnalzyerWrapper); + SUITE_ADD_TEST(suite, testPerFieldAnalzyerWrapper2); + +// Still incomplete: + // Ported from TestKeywordAnalyzer.java + //SUITE_ADD_TEST(suite, testMutipleDocument); // <- TODO: This is failing with an exception "Terms are out of order" + + // Ported from TestISOLatin1AccentFilter.java + SUITE_ADD_TEST(suite, testISOLatin1AccentFilter); + + SUITE_ADD_TEST(suite, testWordlistLoader); + SUITE_ADD_TEST(suite, testEmptyStopList);*/ + + // TODO: Remove testStandardAnalyzer and port TestStandardAnalyzer.java as a whole + + return suite; +} +// EOF diff --git a/src/test/contribs-lib/analysis/de/TestGermanStemFilter.cpp b/src/test/contribs-lib/analysis/de/TestGermanStemFilter.cpp new file mode 100644 index 00000000000..79155870572 --- /dev/null +++ b/src/test/contribs-lib/analysis/de/TestGermanStemFilter.cpp @@ -0,0 +1,65 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "test.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/analysis/de/GermanStemmer.h" +#include "CLucene/analysis/de/GermanStemFilter.h" +#include "CLucene/analysis/standard/StandardTokenizer.h" + +CL_NS_USE(util) +CL_NS_USE(analysis) +CL_NS_USE2(analysis,de) + + void check(CuTest* tc, const TCHAR* input, const TCHAR* expected) { + StandardTokenizer* tokenStream = new StandardTokenizer(new StringReader(input)); + GermanStemFilter filter(tokenStream, true); + Token t; + if (filter.next(&t) == NULL) + CuFail(tc, _T("Token expected!")); + CuAssertStrEquals(tc, _T(""), expected, t.termBuffer()); + filter.close(); + } + + void testStemming(CuTest *tc) { + try { + // read test cases from external file: + char path[CL_MAX_PATH]; + strcpy(path, clucene_data_location); + strcat(path, "/contribs-lib/analysis/de/data.txt"); + CuAssert(tc, _T("File with test data does not exist"), Misc::dir_Exists(path)); + FileReader reader(path, "UTF-8"); + TCHAR buffer[1024]; + while (true) { + int32_t len = reader.readLine(buffer, 1024); + if (len == 0) + break; + Misc::wordTrim(buffer); + if (_tcslen(buffer) == 0 || buffer[0] == _T('#')) + continue; // ignore comments and empty lines + const TCHAR* pos = _tcsstr(buffer, _T(";")); + TCHAR part0[1024], part1[1024]; + if (pos != NULL) { + _tcsncpy(part0, buffer, pos - buffer); + _tcscpy(part1, pos + 1); + part0[pos - buffer] = '\0'; + check(tc, part0, part1); + } else { + check(tc, buffer, _T("")); + } + } + } catch (CLuceneError &e) { + CuFail(tc, e); + } + } + +CuSuite *testGermanAnalyzer() { + CuSuite *suite = CuSuiteNew(_T("CLucene GermanAnalyzer Test")); + SUITE_ADD_TEST(suite, testStemming); + return suite; +} diff --git a/src/test/data/StopWords.test b/src/test/data/StopWords.test new file mode 100644 index 00000000000..b85c5f6cef1 --- /dev/null +++ b/src/test/data/StopWords.test @@ -0,0 +1,12 @@ +a +an +and +are +as +at +be +but +such +these +will +with diff --git a/src/test/data/contribs-lib/analysis/de/data.txt b/src/test/data/contribs-lib/analysis/de/data.txt new file mode 100644 index 00000000000..99fa944547c --- /dev/null +++ b/src/test/data/contribs-lib/analysis/de/data.txt @@ -0,0 +1,51 @@ +# German special characters are replaced: +häufig;haufig + +# here the stemmer works okay, it maps related words to the same stem: +abschließen;abschliess +abschließender;abschliess +abschließendes;abschliess +abschließenden;abschliess + +tisch;tisch +tische;tisch +tischen;tisch + +haus;hau +hauses;hau +häuser;hau +häusern;hau +# here's a case where overstemming occurs, i.e. a word is +# mapped to the same stem as unrelated words: +hauen;hau + +# here's a case where understemming occurs, i.e. two related words +# are not mapped to the same stem. This is the case with basically +# all irregular forms: +drama;drama +dramen;dram + +# replace "ß" with 'ss': +ausmaß;ausmass + +# fake words to test if suffixes are cut off: +xxxxxe;xxxxx +xxxxxs;xxxxx +xxxxxn;xxxxx +xxxxxt;xxxxx +xxxxxem;xxxxx +xxxxxer;xxxxx +xxxxxnd;xxxxx +# the suffixes are also removed when combined: +xxxxxetende;xxxxx + +# words that are shorter than four charcters are not changed: +xxe;xxe +# -em and -er are not removed from words shorter than five characters: +xxem;xxem +xxer;xxer +# -nd is not removed from words shorter than six characters: +xxxnd;xxxnd + +# words where section sign will be used +machen;mach diff --git a/src/test/data/french_unicode.bin b/src/test/data/french_unicode.bin new file mode 100644 index 0000000000000000000000000000000000000000..913f72baba49ca37a5f5f1e0cf65e725fa2074be GIT binary patch literal 5604 zcma)=O>SdV5QQ&O?;x|sqydR!0nGq~C{ofSG*W<;m^rpPad7P5pO9utETJbXrDw#w z1ty%YPO9&9+X7_Se((NPojP@Hy*DrGa#vPmssCOXlv%me)v%1qNcSiDU#j)GbY)-P zQF+klQJJfiyQzK`F@B{{OO2jITTgQj%Ou8k%__`T#LPvku!_;NF16-JdyjOr)bC37 zUHM!seO+M_ZmA;D_Eo**fuQ( zx<3u8=R$C$Rq=)u`q9rF*SW$%V+Q&>hIQ}M2YTbMDE-5S+dvU}@QX-JV@2?#wXT@6 zz_QLF#zdpPb3Rs|t8Y@SG-j>4W%!HT1FbVr-nL~8wC2sccPNR$%44RbBbWd!E z@qxJW{nPbQ?QjFk`})O)saAqzW=!kPg~nhv`-2U;-srbpdk63^H(;9M`5<0Y{$L-R z=*vq+5IyX@E$=^|3qQbi89iXxDORiaA80jV10Ow;=)s*_2~WT(bH`N!iVS4cB%cQkuhL9)d#eR zEi;(c6L0aG-R`x*sQec5o%OfnGJ04Yobi~P#tY_tt9xb<`4?)%AH1jUSUrq8SDS6f zp2N5&Mn6O!F*GyMra#qZZ6Gqt8_M5KN`VsG>Z(`1QxA5#7mqxHk*$6`*VtZpB|p#f z>B@yHI@Qi6x;`o|b$2dXvHwt4hw8g1&pOXxH?-(NdlCt>lO194r0jLc#>~DuwGwSI zWUcE*;g`9}ESOmBJ&^~j|3;Y4^cjYZoMnSauhi=67}$S+7g$|GYIR^G_RT& zg$lLYIa7b?C#=NM&B*%vumYn_MDr-(X@5O`CM?E6E62SGe?N|9wHaf2zK>QkZ|^aPETM4fR3$e%3YK5EIs4>le0V4MsL%htIES z&+gc@O8kxd2c7HiFY74IAoLu5In&KC_OA6&RXVW$F=7HUed@4=H4$zblWK9RQ*UE$ zpJla@@j9qpBC;rd$4ZVV>N!>)7Scj|ymM9vUNNh^VQAMpPIgdad}d1B6%Y1sR;)IVQ=nC9zj1EW3j;icq=l6P0Ywstwft zi%Hb&yVYZ_%N($ZOvET>jxE6|Y69{DE6lCr0WByICmZU)iB)S4u-=ZR^Eyu*=AiGO zo!Z1d{u6V@EwjmNs_3B<4;sb4<4xqON~xc)ZLcGL&|~5#I4cZHJz0lnx z@(mwRn!8X*+K8?1K*4C$x))w$j!^xPKl}Qf1mmz3oUqnU3_j%<`8sMAJWWRBlL#JB zOIg#*F!&EkAD>#yC-U!JEyRth)cUu&Gmo7kAWiLna;ArsS?Lw?v2?Ebmy>G|D$82i z>V)4gh}y5!(#^9l&rMihece72S;^X-8J}o#yA+m{^V?)uo*Kmb@G9+_yIVjNaT|fN`S8`AO#KXFr&At z%Vakia28f?qK|J_wEO%tXLzSVb`wk21AY=)$aiwBKKZqF!XK=1wdcHqyVTdTqlM@M z=Ra!fvw$9R)M`6^sxJLLVI8@8sJWGoR`NDm9EDUzGIGCBjas>&BYuxUbc|qqd%=DC zeqkJ(#t&zpy{OORjQ8`IBSf^V`s5wYE%~GljxZok1=njJ%$ot%CRZ9y_JA(yRZis7 zf$hTsYBt`EBqL#)`JV4vD!Nz&zUU%RHR^D{nn^US)YI+=p5ASuy-;ZGI4#H_l;T-u zt$87ztkSGrpM&uJUSE_apXHnl?1%p&#VF4dI5X93xPjh`HH-Wrr;pU;_dCwGd~#c8 zKC!?qc7Ct%K3UrO`!d=Y^|ijo4d=`vR|1ZLqg>TtsdW=2Rsb{92`p?czFD8^lVfU& zZOhzcCe>Efk7_H0!cCvKH#%?#mS6% G`S%}>k`j;r literal 0 HcmV?d00001 diff --git a/src/test/data/readme.txt b/src/test/data/readme.txt new file mode 100644 index 00000000000..238e1d3e4fb --- /dev/null +++ b/src/test/data/readme.txt @@ -0,0 +1,41 @@ +Reuters-21578 is the data set we use to test for index compatibility. + +Retuers-21578-index directory contains an index created using java lucene +version 1.4.3. The following changes were made to the java demo to create +this index: + +* The FileDocument is using f.getName() instead of f.getPath() for the path field. +* The modified field was removed +* The indexwriter must not use compound file: writer.setUseCompoundFile(false) +* The files are sorted using java.util.Arrays.sort(files, String.CASE_INSENSITIVE_ORDER); +* Used a special analyser instead of StandardAnalyzer. This is because the text + classification of java differs to that of clucene. See the TestReuters.cpp code + for implementation. Java version used exactly the same implementation. + +The java equivalent analyzer is: + + static class ReutersTokenizer extends org.apache.lucene.analysis.CharTokenizer { + // Construct a new LetterTokenizer. + public ReutersTokenizer(java.io.Reader in){ + super(in); + } + protected boolean isTokenChar(char c){ + if ( c == ' ' || c == '\t' || + c == '-' || c == '.' || + c == '\n' || c == '\r' || + c == ',' || c == '<' || + c == '>' || c<=9){ + return false; + }else + return true; + } + protected char normalize(char c){ + return c; + } + } + + static class ReutersAnalyzer extends org.apache.lucene.analysis.Analyzer { + public org.apache.lucene.analysis.TokenStream tokenStream(String fieldName, java.io.Reader reader){ + return new ReutersTokenizer(reader); + } + }; diff --git a/src/test/data/reuters-21578-index/_z.f0 b/src/test/data/reuters-21578-index/_z.f0 new file mode 100644 index 00000000000..86d5b304e98 --- /dev/null +++ b/src/test/data/reuters-21578-index/_z.f0 @@ -0,0 +1 @@ +qpjlldalbaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/src/test/data/reuters-21578-index/_z.f1 b/src/test/data/reuters-21578-index/_z.f1 new file mode 100644 index 00000000000..9d86a8ff38d --- /dev/null +++ b/src/test/data/reuters-21578-index/_z.f1 @@ -0,0 +1 @@ +||||||||||||||||||||||||||||||| \ No newline at end of file diff --git a/src/test/data/reuters-21578-index/_z.fdt b/src/test/data/reuters-21578-index/_z.fdt new file mode 100644 index 0000000000000000000000000000000000000000..8ce5976db9c25f08b41750e6345842e8439e403f GIT binary patch literal 616 zcmZwCu};G<6ouht1c@0Tn7Z4_bxWZmQZgXH0+C>=E{+?lx^ZM*L?55FbU=rU{!e0k zE{e$whoIcfesbTrtg@%>#|LL5Fh)zB2&(mixX(NcA?#JudHYF9aCu6Y~>@yjcQr=^wrr@{r32(tESq& z;ryk3sGe)xyf^#PMRH$aR9TifciX>#Fc=Io408;(7#0}rFx+EULLih9N(rTeQbH-A Rlu$}2C6p3M4NA>X`UCq6s-OS> literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578-index/_z.fdx b/src/test/data/reuters-21578-index/_z.fdx new file mode 100644 index 0000000000000000000000000000000000000000..e0cadd9ff7b269f19bee3895aee7f4d720f5b391 GIT binary patch literal 248 zcmY++tr^X7ek0.,76812G=4/:(0D /:9!&9=.+65701G=3.9(/D _  + - x& '%&+" ' +8- . +. ) +   .  + /; +%(1$6'1'%(%='54(/),;$113(,--&!&!9+02+00!;8 3!) /%03&0(%%,,))**= +% 1% 5<'$ <=*$-)71&&<2=)-(,()5++'4 5#6<31991;6*&0;6&25(4+<<31##4 (7=0/=#" "<11,, 5-! 0(,=) -!9'%$4" !"&4  +-&"+6!&$)7%+0)1=1-(/;56!)=%;$ %33421&398'77''0%0<33""=40*%1) 1;*3<+&(;997#$' 1#'7=,)"(< 1,)%;%-'%99=;/)1)1/6<(2*%%;$;$833=)4 53!-)6#.&66(7077,6/<<(''%=31;=)$6,<)&+*3-+)(=&"4<-35+$=2!%=1.=#=<2=<(,8&&)#$ 0)""+)'''38 %4##0! '#  8=1<*=++)<,$(%*2= ()3' 1*)1)4%%*##'1%!#+=1$1<;(60#29/# '1 +& "353511)7=& +-'=  5 1#  )1)   ; =   ! 9 + 4  9 %;;+ / + ! +  - %%=' ' ! 5 ' = '%  + / ) !*    , 1 %  3 - $   !1 %3 ! ) !  *  1  % %3 9  7 +5 1 + + ;  + +)/  % ; 9 - 3 + + + !  %  ! +7 + ! +    + 9 ; #99; / ! 9=    +  ' % !)3+ +=   #;!     !$   ;;/#;!#951= + " 7+%! 397'9'+ +    /= + i 6-! %7#+'$'% %76/3-#17%1  '!/'  !<%-60 %58&(//5*.&8,+/!8/;:"'9>.,76812G>4/:)0D 3hcsSPg~U\ea_eXvedcRkw0;:"'9>.,76812G>4/:)0D -70!&59&)006+/&8-+0! 8=/;:"'9>.,76812G>4/:)0D 571-5/;:"'9>.,76812G>4/:)0D =0;:"'9>.,76812G>4/:)0D 0;:"'9>.,76812G>4/:)0D /:9!&8=.+65701G=3.9(/D +9/:9!&9=.+65701G=3.9(/D /;9"'9>-+76810(<2.:(0C 0;:"'9>.,76812G>4/:)0D +/;:"'9>.,76812G=4/:(0D  +    + N" +)  +%/#2> ,-7"! #3%7/6      + 30+! +    %  !  6     &  +   !  #     +  +  + !'  +               +  !         !  +        +   9;9;;;;2%    ,-  )     + '  # '/"  +)% #'3)%'999/: #'#;;;;;;;v;"(9>/-8696) +'+;;;;;;;;12H>51/39)! ;;;;;;;;;;;;;;;< =//;;;;;;;;;; ;(';%='/ '#!!!!!!!!!!!!!!!!K3+3!!!!!!!!!!!!!!!!!>';!)-!!!!!  !!!!!!"5'#. =8/(,(#231O%%"& 2/9 +// &+ + +      +6L/  //% %/    /// / /777771111711711177117111777711717777711771717111711711117117717711117777177177771711y +     / . /# /# !/- + /" #  .1./7///+///+71//+/////////////7/////7//7/+++///+/.//7///+//1/+++/1/1///+////////1111/11 111+1//1/1//7//7///+/+7+/7//+7+7+7++77+++++++++5++++++5+5+++++55++++5++555      +    % /  /  // -  //55'55'55'55'5''''''5''''5'''''5'''55''''''--5'-'''5-5''-''''---5----'1 + -/   -  +  + '5''-----'''''''''-'--'-----'-------------------------=!    / ! 5././    ))))))))))))))))===)====))====)))=)========)============== +        A) + - //3# /////)=)=====)==)=====+))=))==))=)=)====))))==))==== === ) )))))))%) %!!   //////...//.//.+   %))%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%#%333%##%%3. %  // $-%#%##%%3%3%##3##3###3#33#3#3######33#3#33#33##333####333#3#3#3#33  +`k   !; =##3#333##33##3#3#33333353533353359999595  ! ; /:  -- !+7/%*7-79%  %7 9!        +    =9E@B1AH28@9B57MA;:=-1N +#= !< +N +! +      + "5595595599 /#%$  -/// +  z/`#!11'%-';!999999955959599ZN )   /'/999555999 ^ +!// - +999 1<-/1  # '''39999;99;9;  ' 1 +/)5/)/      &- +1/0  1 5..5  V)55'%1  . . s!/'+' /# C)    9  r + #/. +   + + N /7-     +  -  1 /=!!//!#+%1 +A) &#/)!4!9/ >)()!)       +       I5%/=5)-) '% //=!' !) !;+ 3# #2/ % +3-A5=# + +N / /54)5455F=5 555 55 5 5-//5#%5 -4/"- 1 =.//!= /.% #! +   z   5!I5 .4/--#)317,1/ ') ='-+ [   /!3 !! +/ 1 ! 4 ! )5!   + + =;; + # / 3       + @/ .) +7)!/  ;3+//=/=////1/ / !+%  + % N-')/'/3;)!& + &  ' #5'6 ) +'&;!  D  + + +  l   7H / 9.5/)../).//.// /.% +.// / .#3 +1))//.*//./;/.//////:-///////////.///35'=/  ) %9//' / 2 )   +#/!= /=-  E&)    _ +_ + +3 + + +3  + +          ./!  / 5);7=&= 681   1)  ./  +  +! *" +$./:/ (6(% !   .; +  #% .#  ;5 8 +   %3/33 .% +, ## )68*-1+)4=$ 9./ 4)/ + + +, (72& 5  * 5 3)  3 (89 /  :(&%17 *12U>4/..//./+ +/# + : 3/7 ---%0 2  089)= 6 &2%9 !1#+ 1%% 3  $<0) $"3 42(. / ) .4 ;00%00"<(/ + 4 5 +  #%6  +/= 7=  % -/1## 7 +61 +  3 + +   ! +  = + +d !4 + ) +2 + + 2=-);3' +  1  91 5  +6 3. *+  4599/ -'/  ' + +   + =, <' ;) +    +  ' & !  =!!3   )5 )5  31!)+ ()'    /3KF/7+ .8 2   + $)1   #  #  2=3 +80 ) +  +; + 9'; !!  + + O! +7% 2 # +!<1 +3-3(.+ &  +  * '1% !'0!  1= 5 Y # !&  #78) %    +%*(! 76-++; 0  <"%( 1 $//;1(&5/.' :%,;:!9>-*66710F=2-9(0@   + = ..0*$  " + ./ $% , < )0* /  +7  + !  &7 )0#'$ -70!&59&)008+/&8-+0! 83,3% !  +- 21/  + 796(= '7 * %  +6511,  + 6' 6 $#(% # # 6%  $ +'  , < ') 559 .9  + /.// +  +' %% +   +7   +#    7!   ; +0    +   +   +=   + ((  4;!  / 0)('! #'  '%27  5   6+/), !)  --1 1 *)= $( &''1*  + j"  +1#)79 +# -%   +!  !+     $$'    +   +,!   !!0 *  57!9 118 7%#, 3   9 ! "( +   + +!1% + + #=7 =,)')   1C1$% B   2  5 9<$) ( + #(#+=6,+)) # */7<"')=#1' +  +$ +-  -  < #=. +< 7=/9&&$0;:"'9>/,76812G>4:)0D  5$./  /*!'$  +/ 6) 3 #6=,# 3 & /$,   <0%   *1/ +!;.;+# 7&  11 /'  +  + ##$ ,5 ##=.%/$ 41 1./;:"';>.,77812G>4/:)0D 1%  ,   4$" +;'(7=   /)) . 2;07 +' + 1%8:,  : +    s98$/ ! + ' 1 < =,  )) .16!74$#/<= ;;61*  ('6<455 +' ) % #"  #  !  <=G + #% $7 #) C"  +  F8" <7,  ' +1*'5 +  + 66 +- <  ##'115 33.1*% &  .  +! ),= +%  9!451  80 +  #)  +7$!5 -   $+ 3!  " %9 % +   .()& +  ! !;)7= &"  #9 =& = %#, %& #   ,33';          +   +2) +  : + + +  , + % !$  - !3!9= + + +! + s + 4 3 +   % 8#  + + + + '  + +,!/=75  + 17 +/ ' - )& &7 +  39' ' + "#' + 77+9 , +  ) /0= +       + )1   %4  + +  3' + 1< <79'6"  ,<; &7  ) 1 #4 +3 )7< '1%#+ ' +icsSPgU]ga_eXwedcRkw '  +$-- 0;:"':>/,76812I>4/:)0D-70!&59&)006+/&8-+0! 855    +591 6# 3 ..9137#  7!9- 9 + #:)* 9/2#! (   7 1-/=;*1 -./00==/ %7713%'*&#5,#%%:*#;; 7// "0$5 0=%$")/.5 !*#&/4<"<% 7-!=5   !+5/,, + + * + %+ *5 + + 7    .// c27% 9;94   +/8-- #! '! 3+ !22  ! '#%'h)- #; +)   =+/ 11  + + 3 ,+1 ;#)!;001* +'= + + +<29);+  < + !'4   ))  & + +  +=845#' 520 +939  .  ')''  +#+ & %( 55=1   # < #-   ,+ %& "$"$   ,,###' 6 96 74#. 5 $*=" + #1 7/"-1"< !/)#'! +4 +.' &/2) &0=- *#+.  1$ (" $='. .  *)//!3 &  )75   /;:"'9>.,76813G>4/:)0D59+&':+%+   ##) !  )#%   + + +      %" +! +   ' #%1   +' #  < 9) 5.  +7)# # + 3==)&#7&==1 9 5 +'  + % '==01=*1*;<= /# + 5 0 ,  )=# +   + K% )7  +  ) +   &-   ++ !    +}  :%' 6 &4 -2 "   01$ 1  $,(10 ./   %   //* 9$/  +  (0=  +' ++=1-1 --   ./* 0, 6,.) 3'3!//6 +;:_; ''  =9)#  ! '* 33==  6.4)- ++* 88 3 != :& 4 4 /27"9%  717=( +)55    + + $7 + + [' // 9"   /% *  & ( 1/#8 - +. +} 17  #- - -. 9  + + :*3 7  + 1 ' '/ +&     1 ) + ! 11   + '   @# / )%*!  9  -  +* + # % # + 9 `/  8$( %% /  /$& 5&7 +  + #  -54   +2 +!8=7; &6&& $.,$ 3 61) ; + +D85& "%  +" 9 + +$ )2 3,  /9 3$ -  1 #*<$ +  +c!=7)  + + %  +  +   , =)# '!-#13!1 " + /+;2  ) & &1&  +"- #3+! 7 3! , 639%'#" !   +Q ;# $% 1+  /" 3 !5 $   2 + 7& + )(  ( %0=7 <*(+   '+  -!:6110&)#% . 1 0  !  $. 3 1 . + +;3.+ + 3! =  , 7=5//1 1-, "( ! %!  ) 9)   4%= 3   5 (189= % . + +9-      +=  '//30 & ++"(  '!$ " & . 7 '5;;#   ' = / + '!  547  . + :/ + 3)     k /   9C=2 - 99! + +C;% 4 , 6  *  3 : 5  - 05 4 32  ''999 %&   +  +  )+) )1"  1  + ()-+ )$3,3!! .#4!- +3#   $<3)// 9;-- 0'=,91%  + 575%54-# 3 -- /2() $   2 7' + ; ' 5  +  !6  +  1 7%; +          5!12! =#     =  +   +  ! %3 +     # .#    + /   + +#: + +  $< + + ;7 51 +)&' 32320  +   =  1 !    & ' '  6-  + #    A <   +       3 + !      +U7"% 9, )./   -1/7 $ =&  0/..6:)./7  ;! + + ; + 1##  /#'+ +5  +  { !  }  ( +*#5. +'#  1  5  + % ;   %! + + '3 !83=../// +@<-L5/ -3+ + +  *%  '   +. +<   + $; +5)+;' =  =,  ) +9;& 1:= .9;79:2)  15: 0< +; =  % '  ) =7 ;231 &     ' +       '"039 + +12 /- 7-44= 5  +L +%/;,;<3("-< ) =/, .,   +.53"4! $(7  *" 5 ! '=$0>4:)0E0;:"'9>/,76812G 2    .81' "''79 +) 7 /!!72/" / %&#.=-!  =(4.. 0,9%  1." ;.  += +/ .;, ;  -*%  -'  / 3"3 + ! <= <  '#1) + 69 ;    ;)#*  #%1 + 4 =3   3 "& + + +)4 =2  , +  ./%  # "'$)*#(-! 9/& 19! '9%1# + +  X+   /)% 5"  + :4 + + +  +} +  +1#3 +  +7   7  `    ** 3#3 5 $641 +  %  1: 7!7))!6*=;;"'9>/-768./7"&9. ==0/ ;* ..0 $ -59& + $) 0-, /4%  '&'- <1 6=3 $.(.:  33:1%  #*%$0.-5 !8+ +! ( '';  +'=5".!  "8.  a% ' 6 / <$)- ""1 3=#  0 . )" + "#'/% 137-7.  )/*(=" '  '$% +!)$  9)-;9 : 0    = # 8  '8 ,- '  !/   ?2#&C=*2F1@ + +#9/  31 + +  !-  +33$'= - 6) *+ '<     r/../5 #4"%%);/837  '0% !197; %),) + '+ '4   %4(% 0 )1  +  5  9!;7-' <$+ +.  + 01;=  ++ * +!1  + / 7 #' 4 3 13-3" '' 3# + + +# + +  $)  . +  +2      ;(!3'# 33#  =/   $ %'' 3! <' +##$ =  3 5- - )"1  V#5 - +  2)//3# +5$+ ==2" #  9 ;' 2%"== 225 '   +        +  + +  3''''''''''''''''''''''''''''''''''''''''''''''''''''''))))))))))))))))))))))))))))))))))))))))))))))))))))))))+++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------///////////////////////////////////////////////////////////////////////11111111111111111111111111111111111111111111111111111111111111333333333333333333333333333333333333333333333333333355555555555555555555555555555555555555555555555777777777777777777777777777777777777777777777777777777777799999999999999999999999999999999999999999;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;====================================================================!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!############################################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5-(++1#%% " $: +6.7 /-  /$ 7! 7% j #- .! 33$"1 +.,(  +  ,33 ;  $1 0' +M + +% + #!  + ($  )) #&+ 2    +3 + #  + +#7(  ; +33    " ,! +   6 ;!  )+!,0;=  ! % - 6 2'/ ) $ % &  % 0 +7 '' .+#0D./*  9  f&   '' & + *1 + @35' 3/' /+ 7*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!############################################%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%''''''''''''''''''''''''''''''''''''''''''''''''''''''5555555555555555555))))))))))))))))))))))))))))))))))))))))))))))))))))))))--------------------------------------------------====================================================================;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5555555555555555555555555555+++++++++++++++++++++++++++++++++++++++++++++++++///////////////////////////////////////////////////////////////////////111111111111111111111111111111111111111111111111111111111111113333333333333333333333333333333333333333333333333333999999999999999999999999999999999999999997777777777777777777777777777777777777777777777777777777777 %K = <, #!(5%1' 99-&'    6 /;:"'9>.,76812G>4/:)0D6# 7' 7&  '/  3).(. #    </   ) + '  +  $3;' ;5= =/  :; +  / ;=; +#  + + 6#3% - 5'0 + ':"91.(0  !  )  <&6 < / + =, 1.'0  4 283#32235&.0  %5 +! ;; h- +;;1 6 0;:"'9>.,76812G>4/:)0D/6 /!<6$8  3%618:  0/ *8)5 $-3 #' 0;:"'9>.,76812G>4/:)0D) - 1+== - 8#91 :; 8:/"&==5 !)9& $-!6 ! =6)) ):5   ',/**()% # 7&)()%   +3173$2--), 94)9#.&9'%$&%%.  /= / = ( -7# / ; 0' 11581 1=  9 & 54- ' +9 +&'-- ; +0"     ) 3' & += =(7   +  =5 5   " +   $)) +  6 ;;% +%) 15 $1  -+ %  !!7) +) ++ 3.  ;  + )   ') + ! ! / =#) !  !25%/ #% "=7 % !77-3 1 +.| /  37 +) +%)'1  ! 2"! +    = .  - +1 )!')1)9#' + !/  )3 %  + +  =*1 (&/*1 7# + + )-%;    %2% + !9/9 +   * !2 / ';0'  '##/2 9 :. ; ' $(=+) ) - -7&,. (77=7! 5%.;**7<%))9-  7 * +3 - 3%  -+=/5&% %%5! + 0;:"'9>/,76812I>4/:*0E++ '= *)#==$ ,=# .   +91  +=%"3&1  <4   +<1./&  +& )5 = 3 '-1 / 7+;  " 5 2 ,10   ! =*09';')  (//-!((" !96-- 3 %%9<<% -   &33 5 + +    + +1+ !!# ,,)"63 )-)5$,!4-&&8 +6    +-!*5+  +   +  + ()2# )" 5 5 % +  -'=-   ! #  1;+ +  *& =5 !"# 01# +0#  7 =5 /) +<=31 ! '2 +'  + (  5*  0  +%$#1 3;!2!!-  +;3<3& $    77(  + # = "6= #  +   _= $0'' +=: $,"  !  ++< ;7.!%82-(  #!..<;%7  )0;:"'9>/,76812G>4:)0D ;567%- /  +//9  +#   / 7&<*  49-) ;- ++ 7 # /<.; )!'89. 597 .  "(4 5( + 4 +<$ 5/ + $)/4 9='/ !   1.-.=4 59,- /2%! %# + +% "$+, &4<;/;/ :9/ , 4 :-- ) " +' &!9+;'11 % 8##5: +%"1 0" +  $ 3";&% .;% =! 55 1 +;<,, 9 1      ! <+  <  0" 7! , 5 ' + +/1 $4 =03 )6<05   +"&!-"-1- + O #; +`1  ==9;2=5 9. +///## 85    +2 !    ! +&&9-5; )' !;=    +  *-(:2;6< /  1'6 2 +  +  % : 393)  &;"3 % !  + /93 &$ B:#0(%4 +#)3 0+  +  # 1)$  + # !&" ' +<2   5*; 14/ /55 8 9" 8,53 + & %7 3 + # P7 = <==// +/*   % #- +  %  /' ;.*1;;  + +; 14- +#   0#"   + # 81 "83"9 ' +%3 1;%9 ';- % )&' : !=   +  8 32=     +[ - +&% +")% +    9:3: $! !5++ !3;  ,( #=#-=)( : 32,11*<-% 3 $///;:"'9>.,76812G=4/;(0D(%-: ='  =!/7/"+);#;8 8)!5!*5.5*34 /;9"'9>-+76810(<2/:(0C          3) 45/7%+ 00;:"'9>.,76812G>4/:)0D:  + $  '#)'&$",+ )9 * '*&/( #8(<)   ;$$,: *#0!+' 12-- / + /5'    + l + #2 + +< + 9%; :%3) ; ;) +#1  !! 7+-9-)&=!9 1,-      3,11' #   )(#: + #  + +/+D->25+G:+.2786==>729!   1  99#  h/  71 #!- .3 + !  7 / ) ;/- 1++5.. 9.;** +   +/+ -( + T(%/ ;()6!1 +  <= /5 + H%$-/10' %   )  45 ! !% #+"/.. +*  +2" &: $   ! . .! 9! !1 5*  +$ _1 1/;:"'9>.,76812G>4/:)0D*7=5.//j(''#$ % #   +$'*+ +     + :$< /)-+ 1  ! +c1 1  '5)+;  //)    !! ;)  =$== + + =6% +"77$ +0, - 7$01  !0 1 3  +7 % = = 2$1=)    ! 71 96;$ 6);% 3!  + + 6%!' *+;&  + + :;" +/   )(,%  )' := < $10$0 7::9  6     7<* =/8#68)) ' ( 21 %%5 31- 1!3) ;% ()#6   +  /!5' )#(/<!# 5#    ! = /;0! 9*1 +*"19)5 +    i/ !  +)  ) !1  == < )2 :   $;1 -)  8 = 42&&/! =7  )' + ! + + +F ;*      ]"' #_9 + '$   + +  ! 7-" "  / % + k;   +  +*:$ &: 2 $    +!;+3  <% ;# #                                             $                                                                   # 5 + +UltibPrqu}/r\n{z_! /# )9  +  + #      +  +  +  A ;7;33;! &7!;#   ' '+  #+ + '+   151)#-9!#$ 79 ;+ +  :-# J1 +;   +" P 9 '       -7  + t::5  3+  # )7;- +  $ + #    %9/ !-  + ;; ; -%  +4'=7    991*) 9%   + +   +  1 5 +   +-  %+ 9  +K7I) + +   +  # 5   7  % +/3,-)%1#-    +3% #)573 +15'1  8  *    &C +  + +  +   + +  + 72 9) 09 + +(!=E%  1     ;   c3)#3) +BqtvuyzqsKgoh%  ,' =U9# + P! ;!3 8#   -,%4'! + u3!8' !   ! ' +)) )   "%6''=9 31+  @ D5+ -.; 5!99# 9   +    +    ;  %;-;;')  Q;   #$, 3' *0   # !  - 5  28)    7  T% ;! -  3 #!3'= +! .-$#%#&)!=)- &5+  !  !( + +1 -#33/! 4+ %%/  ! $ +    + ) 7)3;'  N=B#'# #' +5   +  +  15=-% 561 57% 7  + 5+    +5 + '% #  !' +  7 + 0 '   ''  './= `=91    #Q55'9 !-*")/# /"1#1'!  = :  ) !%  |  +1  -  +   +          +"  M. # ;   N9   +   #3   ,  ).//'  / 7 9      '  +  +         +  11% $"7   +%  + +3 +  A24   ' ( )  9'56  +!  +  + = 1++  =$ #!'% + 1 )   y13!9= --  +327 +  ) '=%4))    + K '68:*!5-,! 9  +/ + /* 756   +  =88!+ ! =!%:  + +3Y 6=    :-/ ;'/3! !-#&'9  m   -3    +    +H   )  #<'!/(!(*!"+)0!2!2 2 5!3  S        +d#  i1#!+ 0!"           a9!)%59  + ' +-+; *& #/   +/ ;     k 3 '*''  +8'5  )     3#  - .!!  731 + +59 + / +/   $5 3H6%  + += +  +^777 9/    )7   %%   =  -4  -39%)33%. +91/<#%+%%  +    77=  =!13=53=   ##'5I# +  7,/#   1#3 + 2   + %5'"  -!89'&!0'-- ' +'" ! ! #/)+=   F#  ' +'  )    +   -#/=  8 `   % N+  +h  +3# 3   +)  B' " =  *%)  7/  3  -  %  +2##+  1!1     ' +54!   5% *# )5# + 3; ;%  !   1 %  7+5;%  %! -%,#5+ /' %+ 7  + #3   !  )  79#+9-+# #G  7' c !# ;%  # 9 6) ) +9'9+  =  '!77%; -;  + +   ,  +  9 0  &51</   3)   +   +! + +6! % +#+< #/#9 e D +99/ 1 +*  7   1   7/  =   !55' 7   "" +  ! 5  +      *  + +b3) 3   + #+#%A$ +   #1  G\ #9* +   b!=  /=!    +   '  !    '1+:--3; TQ+1 J# N+>!#*,A    =;+ -   +  +/ 7#9% -@  !'%RB + + %89 9-    7)    + )  +h7 '  :'; ! 1/+*  %5/    #7 4 1 +7#7%  5))  +   %97 + +-7/ '  # +  -)    #; +  1+-+!%7 !%9 !  &=;;567=# %==!= +    +G#93 & (9 +9-)+ 7R#%$';1%2!1!5  -94$'<==# +   )  ; 210 )-##!+2  +   #%  +;1-2) ;%  +     1)7;/#9%)% %9;) 55  +  + + 13 & 5 ) ')'%    ' +       C4>B++WC99H8>P/6'=#. ',T3 )3 + 3    + 5  3': 5 + + + +$5 +7= 3   7;d #3% !;! 3$ +7  #"#' !%'1  +  =7   +1 17  ! #"%!6 ' +\ %  ]'3  n +]- +  +    %Y  /  +9 +  9 +   +n!;  +     +  V +! ;&%%+ >*! + '  # 3 7 =  +7    +9 9# -++ )# +%) 39 )$  =+*989!  +; +2'#&   # % ' 45       +3m  , % =/'' 1+4-;!   ='  + +'' 92  !%% 1)  #)53 5=#  + +  A  %/4)1<<===%   ) +  %! ;8  3) )!% 1%5'  =/  + 1 9%=%  7 )   +   +# %; ' 3+9 c9%' -  %71- D88   %  +5  !!4     +  ?3)! !*')'&' ""   ##-    W +    / ]         6  - 1% % +0?@#(<C6-<::63IA72@0@M   /   "*  9 /  '  #&  92%  / % ;/7 +   +   1! 9- :1 7 +   591 5# +/2 !&   .  1  +    g ;  %%   . '  3!  /!  +@) + J' + =#%6!#7 G )    o'/)52 -9.+S-*  ) +  + + + +  +Z9      +  <9!= 9  +/% ; ;1 '  + =' 9 9    +   )  7 +5C9<IUH&2PH/>@M?GHE7/, 9 + + 3% + ,%    !3!  )+   1     !/79/  +  =' +  +   % ;   77  7)"37 5%5-! + + '-6"!-%%41 *, * #      +#5 '@  ) 9    ! +W1@  KB' 9% 5     & +$659 +  -& W-  9 '&'  +#%; 5..!;  -;;;) # # +   + 3 B + #- 8!    + +19  +,   X    !  #5 3 1:   2;  +5      k   " +` ! 9% #  95)=+5# 1     + +   +#71 # #7 !/%3 + % ; 1< ! =1/ +05  &"  + =-   +     !5   + ;57   / "   1-   +$+ +0)##  003#%.)> ==U  &';  +'.!8  K +l . 1  +( %+7   +x'*9/   .5%   43 ) +  !=% '#=7%1 #   + ;* #;D. 1% + +9/ 4     3'     ! +  73);!%"  ))   ++ 01#'!*  -59=   ; !    !  +=  +#! ! 7!   %;  +odrivUpresX_eRssl{h  /   *  =%1;)' +`9 Pb    N*;59# )  + + + + \  #5  1;-# %3  ! )#    !! 1;' +5:%% F'%   +   n -';%#9;#9;% 6 : 3%'= ) 1-  <  1+3,/# %738!!- +)-3 ) 7  - -  99- ,  :9;  7#  + -*%   4       +  #   #7&+ =915 Q)#% % + +  +u7=     % +  +[ 9  J9% #%, )    !#  +3 +*,&"-))+0.+!%. +42.='';;5  Z@  +.?)C#),%B"?4613'!.    */'"&#0!E71$3$! -= %2I#15  -%  '#% 7( , # &* 5*     1-1%4 3=$- 3 -' %   / (5  =   9   -1 /  0  +   -1          3;    #     ,'- 3    + + U%  +# '5/! %! K !  +  !  +559 -   !3 F!3 3- J )  9- 9  =*7! +  +  !) +8/#   +;#3%.3% 1(%   :* + + + +  +1-/  + +   + + '   '    &4=  !! !/)!   ##' ;V       9!9 + ;- " .    /   M #, '    ) ! !;0   +  #3    ' +2+ ) 7   ## +   *O     ; 531      _7'   5 + - 1 %=   ;6   '  Q5 '#  % % +  + .! ); #9 +  v!+# + '$*=     %;! ) # 9  + x  (%0  /')     "## +#5'   + t+=11 +  --9' 3&1'# ;9         & %=    !";;#  /* //'3C'# 5  1< +1    -)  + --     +!971=   + +  /  7 # "+997-;3#/ =45 + + );.-ID^H8LRW3>:8:Y/N)(J +1' $ 3 )'#"7/1 1// +   w5 +=   +#   3   +  +     ,   +] <$'' # /3=)I       +85 +J ++/9  ) . '-   3!-    9%   1 = 2  - +# +   9-'      +% +#!=(    +   3  !)  5 +    +       +   )5  + +  p  &  1;5A)9 '     6 V  ! ''%'=  -%' +  1 &    '#  ]77  #;55'97 +t + = + `   5.)'  %  %5# !;1*    +) + #&+;  +G8O~) H +  +  + h "     + T& s +#!  =-   + +    #=  / /#%3 +3.-?2)$-8,'!8,#:5!1C          -# e;/1 + +# ) ') 1 + + .   3  +3#      ,;          +  = -7 + !  ) 97    +=  +    =  /U97! s-;6 +5;!))     +   +&g!      + 1;93(9 % == + #2);;  !@G    0   /3 /   H -1;   1'/7 + %5   95 +4W' % ) $!  " +)  +)       +  3: 3*/0/;@=5%=1#   +0! + 9(M&1d3/.8(=4)89 / 3 -##    +)' '/   +  +    +*/! 31' +l=-7!!    )#%# -7 $ ## = : %3% ! & )&  +#5'93 !)'   /.5  +'!, 7) d-% + F A1;)1 +  & ;*< == //+ !+79/#*7;:  9 +   8 6!9  D3,#79%; + '7,  3     +  9   Q- +   $% 9 5    7 #+  1=! ';+! +   )+%&'77-7  - '' 5 3#9  7U  7 ;   03)1 3%  +IF          +  +%   + 13N! !  +S  11)5 + 6;  $ %    "      + +     +u  1.   +` G &0 +      9;W1%     '! + 5! 96!538,) + !3 37 '   -1! #N#-! +  ;    #'5! + ) A     18"   %"+ ( ;!'; _' 3    + #; =*P) 5++   5!#" 7# +/ + %+-%  #  +q7# # + 9 .!   .  +  +   # < & % 1      / 5+#  !   +/   9-  #       "   W  7 + )!!1  /   ; = +7 ,  ''"% +7! ' 775 !!70+)+)#  1 +?9!D!5 +=!+1 #5 & + (8=+  [ / +#% +"#11-  '- 5+>    *9 #7 ! ) ++%1 + +   +   3!    +!  99'9,'5! +!59#!)) '5' #/ + 7+  &%#   9*++7&)%9 ''*  + ! )     -9 33337=3*   +!  75016!;#'9!***%%7 + %)! +   )! !% #    o h   199  -    +        #-3#$   + ' +     J./ ! "!9 / )% +) #%   #   ;%   93+- +/%   %H    O  !-,,;;  1%) + 2  +!   < =#11$ /-! +%9!;  3  +! +  3 9#+ +19<(%'* /  /7-';=  + %3 391w    += %  '/+/; " ##  9 +5 x1  ='; %5   5%%!  7   17   /77- 4%#twh{zn7exlwo%!  6! ^   + %67  !S) + ;=3' + : 1    @ +  +93+ '/' + : ;/-559 %+;&7 + ) /    + +"#1+  T ; #  ! +X   <)),3    +3;==)    G  &   $- 3) #*D-  !9   "  + 9 +% '  ! h# , "!L!? 5:- ');#!;  + +   +  3 J;1:;    +   +    ;;'=< %=3'1;   + +   +" 9 '- +Z ) 3 '     ]- 1 #%85  89   +;    !  92       % 99"#h3  #.!   =9+1f  .# +)=1   :- 75/.5 5! ! ! !!;!!/3;  1 99 7'#-'+; +O'%  % + `9 13#-2!8,   #  +# #) 1 +    - + +\ ' 140 +  //+ %  !93 ;1  -3  !%; 1 ' ;/++:5+ -;; q9   '.  9;  55+9#  !..' !##!   8)5!E%* ! %%0  1E +%N     5 #  5,% !7  +/  + :;/./!     +77  /; !:#! ;    +   +*  99 /:: 3  3 / +;3'    3 +9 '''   # '!  +F -    %+)% = !  %! 5#5"711 ) d   !%)    !9  C !#3 :!  +  + +13 1 % $##" - +# + ) 011 7==!0#/# 35    +  +N K))/9;' +1'' /  +"' ( 1  33==39%=!3#"9' #% +!%'# {!! % - 8'+-57- %V --  -- U  9;3 +3$ '%  !)!95    + +;== _"8  3 ! 4 !39  4 5' =-' + ;# / + 7k;''="H';3  +      3   +    +9 7 'C,7"!)$$/>9/*)/3# + ++=    O'* 113 ~' a=  + +    7   +  ?    +$    +  +  L  5+ <! =%!  +!  #    2$ # # /;     +r/3 + 9! + 1 /=+35 ]^m+    +   %   + +;"-%+ +;  e +     7  59+1  |#   +  &;    # +    =  4 m ==9'' + '!7 #   ! (## 9  ; ! "7% 7;:/,#;- ! '52 + +!--  + +:1 / !  25   +  %#  5  +      1  % { % 1'5%5! - /;   %#  #- 5#-  + ')    +$3 );'95 7  *-5 , ' 5k& #):3%* !7;);=#+ :7'<!;7/=) );;;F%  -;;+        +-)#%'9%4=="5%3"   *)#-. +"/%1#$'+3R j' +  % '" #=41 13R +  + +   3"    !3      +    7-7  +5-933% +// ! =#749!! ="/   '- 55' -/" ! +. 330 =75G==.-/)e#) !% %/ 5- #  ++ + %7;%=1 *= '  ' !% # (,(""" *!7'/  % %; #  + s  ) ;+ #1' +    + +   / !': ==         + +   +  ?+  +    ;'n/+     +    + ~ !  }  +   ;     /-)5+ "&&'40.2 :#4 4 ;-!9- 4+'1;7!# 0 ' &/2-   "+-  )%3755)'#       # 7 ))!0   2* 57# +' !  5'  -" %  '   5"-# ## &-  + 5  )9 +   + +%7 9%  ( + +   !#%')+-/13579;= \ No newline at end of file diff --git a/src/test/data/reuters-21578-index/_z.prx b/src/test/data/reuters-21578-index/_z.prx new file mode 100644 index 0000000000000000000000000000000000000000..d7339988f37234b915c9172d53ea57d270c01032 GIT binary patch literal 388750 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�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

-#MvD{ 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 literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578-index/_z.tii b/src/test/data/reuters-21578-index/_z.tii new file mode 100644 index 0000000000000000000000000000000000000000..34801bcd82e6089859c678270725a60882e15fa0 GIT binary patch literal 3462 zcmY*cYjjgp7Cx_gb8phn2cY9P%n!uZnwd38n)DIY{0M1;YMU@=fyK=7$8CDsUQKd4 z$xV@eAn%vFY%N$&P()-Xf-^iutb(E-YY>=0LSJFi3va4ast$)@Lkazo zu28>Isa$Jjnzb~cy>wpDF_p49ld#X|O2;=U730D+@SMeFxpt~lNwnxGBcUY;?V|^j zvnq8o8QGSh&pt`$Kj^p85+_xYMw_0s%*6AA9-~{NGdQDF*DONcqua&TxGigG4N0BQ zcj<2NmXi#5>=B=D_`N^8!<#%FU*NGvO1;A~dd`B|9{Q1V+gao;_51EyW-rsX*c-(~ z?h0S&eap0yu4C^O7Y^`x%kFol^XZbjyWd-WpF8WKn^+f4sVx85DGTUw){Rqqfr^Uz z-Dl7_Y`uMH#m^33L|3pC#mp5z8h3wdi9CmI_|1VLDkrVs;m|ljcd{Slw-q6ts;(Pr zLw}vEfmIu-j}y9|_OU&R;G?6X3G1O>vh|9P>SN<$;|bkGPq2duk)9~^cmVTudY)}n zs55M4GJ3)?(#?dvL|yuanAk_0{1~ zu&1J`e|1sG%4O0pyXY=9-$jJSnkI4n=-d#rGwIP;#|i5HSm-| z9hE_UAn32O>%L2RQ6-Ak6ZBOCJr#t$%8w2H7%pB|K^#U;(&_RW3YSU)d2}H>;7Zoa}TJ%g7yy)TY zDsO^G*=#Olmy<8yJ6zjTB1S|)al$t9_QAah6=SMvs)#&^UoY8>gY|UQOcOSfA5&g~ znaO1n8lf}!4~`F2!oyG1657poDP1ZZ9ILGz69wbzt7Fl+$Iy;d;ZQZ9m)PZjD?rXM z@ey@|&gN$Z-2|R3nvqFC3kJ;QYaH!}%1kvFXY^@M$aFpdB{Bdw(qIw|gFYn36F z72+5fiALf8TkRC9oJ$a>k!;X2mPzPF-s@PZ5_wc8J|YITt!1A|wh(E#<`#V-3d_lMh;Sb}qFH{`ZTUwbn`{^v0rJhpHy{|99Ec1BE@0s&pR(O1OkLt%!RE>>|)Q*V6 zA4jL1p_9aFg)*~^h<*Hwb1kBc)l}V$wzAybb%0-qp`#gS+o$4goPdgQb`^)mi4cd-yK=Yr1waq}F;;!rM{MU-gdwJicuOPBN zVPiM@q2xX2$LLU9s45agA8g~R)q{3n>gpp^ge~B!hRy+fw2XxszRos_w^gc|$%*Iy zL&FIlvg6VUG{GOoRM*D{o5~j}TOgD1NF8V$9z{eCTP#gQpXyrD(i1Is5c$amAsUKl z_pMED`cHmw&}B3hw$w(@I)(F=xxf#*Eo&POy`Cht3l3yGVi704A8}l%BTWd5(TLxZ)+6O^y9c`x3n15Vf z7n_TZDMW72bt{W2I^-h{A695lbCZ^^o)}tXLbNdwp<3PIntQ#Ia?@%d56lwliiUL} z&qRLOVN;}Y4_r`~l*`(u%11?i!6X#QXfu*Tw2R5k6QGHiN*UR#t$fmH{-%0KVXkzO z(G20q%OU+ynlf;T%GEYx3oo1S%f$h8F-nusClEGEI_UlpUE8Q9bc|t0_LltlLnjrc zw3=B1bqD^PVxRgw5;W}b!OW1tvwXRNhk%=qu96+1t*JCfRjtQ`aG5{F&iA}8o~roqI`m@uT<1;)avztq6mUs%vQ^ z(Ub%Bm!&(!*yTV2pl)E)QgKc_kA+;)G7uVJ=cVbt-UK$J%{1y|Brprf7Y4oq_L#{= zA|ICb2Uh~OoMjJT7#kejk50oA*{Wr;x{Wsx=f&OvxVTzO%WN}~mS!KaSF9Y2r&YC! ziaOi0IwMxQE&=0=kyUoAPM5RuUgr1yc;Sq%RHdIC+S zqr7%QWr@@+ZE;^!n0OA|0cMD6m?4<_mmJ!qkreI{JDqb?Cfc-AE1?I(0_O~bo7EB- zqshSANN?~f>J@0Hu9Koqr5lev1T|7xjARm+K_@TED+hfJfRaXQtKAB`TiS)|sL~1- zv&|-UpXeyKj1|jB<&qly2OxhZHWutus4JI9=-DigxAVOuF1jb9*mg%@cv!}dIBufz zEeuBaL;%QQ_i+q_2Br_>yFpp?EV_sTAHrA2eZE_$Z7!{YO3)#DsuKYhR5Wge< literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578-index/_z.tis b/src/test/data/reuters-21578-index/_z.tis new file mode 100644 index 0000000000000000000000000000000000000000..08c6db663a8cce7c723348dbbd41ab69c6273d2e GIT binary patch literal 248046 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
gn~+w@;i@}l%}Z`n-(QyiLQ1jg?dCt1U*^ZI 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
&xIu11q3Ssbt>jgp#Zv81d{_a8R-$Qh7 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 Rew@#4|Np-3&gZ@Ee*ncYJ6He! literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578-index/deletable b/src/test/data/reuters-21578-index/deletable new file mode 100644 index 0000000000000000000000000000000000000000..593f4708db84ac8fd0f5cc47c634f38c013fe9e4 GIT binary patch literal 4 LcmZQzU|;|M00aO5 literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578-index/segments b/src/test/data/reuters-21578-index/segments new file mode 100644 index 0000000000000000000000000000000000000000..eafeca8abd53b7cef30a4e55e694015f4f12cafe GIT binary patch literal 27 fcmezW|Nnmm21dn3w{9i|1_l)%W@L)50#fn-hPeik literal 0 HcmV?d00001 diff --git a/src/test/data/reuters-21578/LEWIS.DTD b/src/test/data/reuters-21578/LEWIS.DTD new file mode 100644 index 00000000000..c56624dedfa --- /dev/null +++ b/src/test/data/reuters-21578/LEWIS.DTD @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/data/reuters-21578/README.TXT b/src/test/data/reuters-21578/README.TXT new file mode 100644 index 00000000000..2dce8045b12 --- /dev/null +++ b/src/test/data/reuters-21578/README.TXT @@ -0,0 +1,816 @@ + + Reuters-21578 text categorization test collection + Distribution 1.0 + README file (v 1.2) + 26 September 1997 + + David D. Lewis + AT&T Labs - Research + lewis@research.att.com + +I. Introduction + + This README describes Distribution 1.0 of the Reuters-21578 text +categorization test collection, a resource for research in information +retrieval, machine learning, and other corpus-based research. + + +II. Copyright & Notification + + The copyright for the text of newswire articles and Reuters +annotations in the Reuters-21578 collection resides with Reuters Ltd. +Reuters Ltd. and Carnegie Group, Inc. have agreed to allow the free +distribution of this data *for research purposes only*. + If you publish results based on this data set, please acknowledge +its use, refer to the data set by the name "Reuters-21578, +Distribution 1.0", and inform your readers of the current location of +the data set (see "Availability & Questions"). + + +III. Availability & Questions + + The Reuters-21578, Distribution 1.0 test collection is available +from David D. Lewis' professional home page, currently: + http://www.research.att.com/~lewis + +Besides this README file, the collection consists of 22 data files, an +SGML DTD file describing the data file format, and six files +describing the categories used to index the data. (See Sections VI +and VII for more details.) Some additional files, which are not part +of the collection but have been contributed by other researchers as +useful resources are also included. All files are available +uncompressed, and in addition a single gzipped Unix tar archive of the +entire distribution is available as reuters21578.tar.gz. + + The text categorization mailing list, DDLBETA, is a good place to +send questions about this collection and other text categorization +issues. You may join the list by writing David Lewis at +lewis@research.att.com. + + +IV. History & Acknowledgements + + The documents in the Reuters-21578 collection appeared on the +Reuters newswire in 1987. The documents were assembled and indexed +with categories by personnel from Reuters Ltd. (Sam Dobbins, Mike +Topliss, Steve Weinstein) and Carnegie Group, Inc. (Peggy Andersen, +Monica Cellio, Phil Hayes, Laura Knecht, Irene Nirenburg) in 1987. + +In 1990, the documents were made available by Reuters and CGI for +research purposes to the Information Retrieval Laboratory (W. Bruce +Croft, Director) of the Computer and Information Science Department at +the University of Massachusetts at Amherst. Formatting of the +documents and production of associated data files was done in 1990 by +David D. Lewis and Stephen Harding at the Information Retrieval +Laboratory. + +Further formatting and data file production was done in 1991 and 1992 +by David D. Lewis and Peter Shoemaker at the Center for Information +and Language Studies, University of Chicago. This version of the data +was made available for anonymous FTP as "Reuters-22173, Distribution +1.0" in January 1993. From 1993 through 1996, Distribution 1.0 was +hosted at a succession of FTP sites maintained by the Center for +Intelligent Information Retrieval (W. Bruce Croft, Director) of the +Computer Science Department at the University of Massachusetts at +Amherst. + +At the ACM SIGIR '96 conference in August, 1996 a group of text +categorization researchers discussed how published results on +Reuters-22173 could be made more comparable across studies. It was +decided that a new version of collection should be produced with less +ambiguous formatting, and including documentation carefully spelling +out standard methods of using the collection. The opportunity would +also be used to correct a variety of typographical and other errors in +the categorization and formatting of the collection. + +Steve Finch and David D. Lewis did this cleanup of the collection +September through November of 1996, relying heavily on Finch's +SGML-tagged version of the collection from an earlier study. One +result of the re-examination of the collection was the removal of 595 +documents which were exact duplicates (based on identity of timestamps +down to the second) of other documents in the collection. The new +collection therefore has only 21,578 documents, and thus is called the +Reuters-21578 collection. This README describes version 1.0 of this +new collection, which we refer to as "Reuters-21578, Distribution +1.0". + +In preparing the collection and documentation we have benefited from +discussions with Eric Brown, William Cohen, Fred Damerau, Yoram +Singer, Amit Singhal, and Yiming Yang, among many others. + +We thank all the people and organizations listed above for their +efforts and support, without which this collection would not exist. + +A variety of other changes were also made in going from Reuters-22173 +to Reuters-21578: + + 1. Documents were marked up with SGML tags, and a corresponding +SGML DTD was produced, so that the boundaries of important sections of +documents (e.g. category fields) are unambiguous. + 2. The set of categories that are legal for each of the five +controlled vocabulary fields was specified. All category names not +legal for a field were corrected to a legal category, moved to their +appropriate field, or removed, as appropriate. + 3. Documents were given new ID numbers, in chronological order, and +are collected 1000 to a file in order by ID (and therefore in order +chronologically). + + +V. What is a Text Categorization Test Collection and Who Cares? + + *Text categorization* is the task of deciding whether a piece of +text belongs to any of a set of prespecified categories. It is a +generic text processing task useful in indexing documents for later +retrieval, as a stage in natural language processing systems, for +content analysis, and in many other roles [LEWIS94d]. + + The use of standard, widely distributed test collections has been a +considerable aid in the development of algorithms for the related task +of *text retrieval* (finding documents that satisfy a particular +user's information need, usually expressed in an textual request). +Text retrieval test collections have allowed the comparison of +algorithms developed by a variety of researchers around the world. +(For more on text retrieval test collections see SPARCKJONES76.) + + Standard test collections have been lacking, however, for text +categorization. Few data sets have been used by more than one +researcher, making results hard to compare. The Reuters-22173 test +collection has been used in a number of published studies since it was +made available, and we believe that the Reuters-21578 collection will +be even more valuable. + + The collection may also be of interest to researchers in machine +learning, as it provides a classification task with challenging +properties. There are multiple categories, the categories are +overlapping and nonexhaustive, and there are relationships among the +categories. There are interesting possibilities for the use of domain +knowledge. There are many possible feature sets that can be extracted +from the text, and most plausible feature/example matrices are large +and sparse. There is even some temporal structure to the data +[LEWIS94b], though problems with the indexing and the uneven +distribution of stories within the timespan covered may make this +collection a poor one to explore temporal issues. + + +VI. Formatting + + The Reuters-21578 collection is distributed in 22 files. Each of +the first 21 files (reut2-000.sgm through reut2-020.sgm) contain 1000 +documents, while the last (reut2-021.sgm) contains 578 documents. + + The files are in SGML format. Rather than going into the details +of the SGML language, we describe here in an informal way how the SGML +tags are used to divide each file, and each document, into sections. +Readers interested in more detail on SGML are encouraged to pursue +one of the many books and web pages on the subject. + + Each of the 22 files begins with a document type declaration line: + + +The DTD file lewis.dtd is included in the distribution. Following the +document type declaration line are individual Reuters articles marked +up with SGML tags, as described below. + + + VI.A. The REUTERS tag: + + Each article starts with an "open tag" of the form + + + +where the ?? are filled in an appropriate fashion. Each article ends +with a "close tag" of the form: + + + +In all cases the and tags are the only items +on their line. + + Each REUTERS tag contains explicit specifications of the values +of five attributes, TOPICS, LEWISSPLIT, CGISPLIT, OLDID, and NEWID. +These attributes are meant to identify documents and groups of +documents, and have the following meanings: + + 1. TOPICS : The possible values are YES, NO, and BYPASS: + a. YES indicates that *in the original data* there was at +least one entry in the TOPICS fields. + b. NO indicates that *in the original data* the story had no +entries in the TOPICS field. + c. BYPASS indicates that *in the original data* the story was +marked with the string "bypass" (or a typographical variant on that +string). + This poorly-named attribute unfortunately is the subject of much +confusion. It is meant to indicate whether or not the document had +TOPICS categories *in the raw Reuters-22173 dataset*. The sole use of +this attribute is to defining training set splits similar to those +used in previous research. (See the section on training set splits.) +The TOPICS attribute does **NOT** indicate anything about whether or +not the Reuters-21578 document has any TOPICS categories. (Version +1.0 of this document was errorful on this point.) That can be +determined by actually looking at the TOPICS field. A story with +TOPICS="YES" can have no TOPICS categories, and a story with +TOPICS="NO" can have TOPICS categories. + Now, a reasonable (though not certain) assumption is that for all +TOPICS="YES" stories the indexer at least thought about whether the +story belonged to a valid TOPICS category. Thus, the TOPICS="YES" +stories with no topics can reasonably be considered negative examples +for all 135 valid TOPICS categories. + TOPICS="NO" stories are more problematic in their interpretation. +Some of them presumedly result because the indexer made an explicit +decision that they did not belong to any of the 135 valid TOPICS +categories. However, there are many cases where it is clear that a +story should belong to one or more TOPICS categories, but for some +reason the category was not assigned. There appear to be certain time +intervals where large numbers of such stories are concentrated, +suggesting that some parts of the data set were simply not indexed, or +not indexed for some categories or category sets. Also, in a few +cases, the indexer clearly meant to assign TOPICS categories, but put +them in the wrong field. These cases have been corrected in the +Reuters-21578 data, yielding stories that have TOPICS categories, but +where TOPICS="NO", because the the category was not assigned in the +raw version of the data. + "BYPASS" stories clearly were not indexed, and so are useful only +for general distributional information on the language used in the +documents. + + 2. LEWISSPLIT : The possible values are TRAINING, TEST, and +NOT-USED. TRAINING indicates it was used in the training set in the +experiments reported in LEWIS91d (Chapters 9 and 10), LEWIS92b, +LEWIS92e, and LEWIS94b. TEST indicates it was used in the test set +for those experiments, and NOT-USED means it was not used in those +experiments. + + 3. CGISPLIT : The possible values are TRAINING-SET and +PUBLISHED-TESTSET indicating whether the document was in the training +set or the test set for the experiments reported in HAYES89 and +HAYES90b. + + 4. OLDID : The identification number (ID) the story had in the +Reuters-22173 collection. + + 5. NEWID : The identification number (ID) the story has in the +Reuters-21578, Distribution 1.0 collection. These IDs are assigned to +the stories in chronological order. + +In addition, some REUTERS tags have a sixth attribute, CSECS, which +can be ignored. + +The use of these attributes is critical to allowing comparability +between different studies with the collection, and is discussed +further in Section VIII. + + + VI.B. Document-Internal Tags + + Just as the and tags serve to delimit +documents within a file, other tags are used to delimit elements +within a document. We discuss these in the order in which they +typically appear, though the exact order should not be relied upon in +processing. In some cases, additional tags occur within an element +delimited by these top level document-internal tags. These are +discussed in this section as well. + + We specify below whether each open/close tag pair is used exactly +once (ONCE) per a story, or a variable (VARIABLE) number of times +(possibly zero). In many cases the start tag of a pair appears only +at the beginning of a line, with the corresponding end tag always +appearing at the end of the same line. When this is the case, we +indicate it with the notation "SAMELINE" below, as an aid to those +processing the files without SGML tools. + + 1. , [ONCE, SAMELINE]: Encloses the date and time +of the document, possibly followed by some non-date noise material. + + 2. , [VARIABLE] : Notes on certain hand +corrections that were done to the original Reuters corpus by Steve +Finch. + + 3. , [ONCE, SAMELINE]: Encloses the list of +TOPICS categories, if any, for the document. If TOPICS categories are +present, each will be delimited by the tags and . + + 4. , [ONCE, SAMELINE]: Same as +but for PLACES categories. + + 5. , [ONCE, SAMELINE]: Same as +but for PEOPLE categories. + + 6. , [ONCE, SAMELINE]: Same as but +for ORGS categories. + + 7. , [ONCE, SAMELINE]: Same as + but for EXCHANGES categories. + + 8. , [ONCE, SAMELINE]: These tags always +appear adjacent to each other, since there are no COMPANIES categories +assigned in the collection. + + 9. , [VARIABLE]: These tags bracket control +characters and other noisy and/or somewhat mysterious material in the +Reuters stories. + + 10. , [ONCE]: We have attempted to delimit all the +textual material of each story between a pair of these tags. Some +control characters and other "junk" material may also be included. +The whitespace structure of the text has been preserved. The +tag has the following attribute: + + a. TYPE: This has one of three values: NORM, BRIEF, and +UNPROC. NORM is the default value and indicates that the text of the +story had a normal structure. In this case the TEXT tag appears simply +as . The tag appears as when the story is a +short one or two line note. The tags appears as +when the format of the story is unusual in some fashion that limited +our ability to further structure it. + +The following tags optionally delimit elements inside the TEXT +element. Not all stories will have these tags: + + a. , : Author of the story. + b. , : Location the story +originated from, and day of the year. + c. , : Title of the story. We have attempted +to capture the text of stories with TYPE="BRIEF" within a +element. + d. <BODY>, </BODY> : The main text of the story. + + +VII. Categories + + A test collection for text categorization contains, at minimum, a +set of texts and, for each text, a specification of what categories +that text belongs to. For the Reuters-21578 collection the documents +are Reuters newswire stories, and the categories are five different +sets of content related categories. For each document, a human +indexer decided which categories from which sets that document +belonged to. The category sets are as follows: + + Number of Number of Categories Number of Categories +Category Set Categories w/ 1+ Occurrences w/ 20+ Occurrences +************ ********** ******************** ******************** +EXCHANGES 39 32 7 +ORGS 56 32 9 +PEOPLE 267 114 15 +PLACES 175 147 60 +TOPICS 135 120 57 + + +The TOPICS categories are economic subject categories. Examples +include "coconut", "gold", "inventories", and "money-supply". This +set of categories is the one that has been used in almost all previous +research with the Reuters data. HAYES90b discusses some examples of +the policies (not always obvious) used by the human indexers in +deciding whether a document belonged to a particular TOPIC category. + +The EXCHANGES, ORGS, PEOPLE, and PLACES categories correspond to named +entities of the specified type. Examples include "nasdaq" +(EXCHANGES), "gatt" (ORGS), "perez-de-cuellar" (PEOPLE), and +"australia" (PLACES). Typically a document assigned to a category from +one of these sets explicitly includes some form of the category name +in the document's text. (Something which is usually not true for +TOPICS categories.) However, not all documents containing a named +entity corresponding to the category name are assigned to these +category, since the entity was required to be a focus of the news +story [HAYES90b]. Thus these proper name categories are not as simple +to assign correctly as might be thought. + +Reuters-21578, Distribution 1.0 includes five files +(all-exchanges-strings.lc.txt, all-orgs-strings.lc.txt, +all-people-strings.lc.txt, all-places-strings.lc.txt, and +all-topics-strings.lc.txt) which list the names of *all* legal +categories in each set. A sixth file, cat-descriptions_120396.txt +gives some additional information on the category sets. + +Note that a sixth category field, COMPANIES, was present in the +original Reuters materials distributed by Carnegie Group, but no +company information was actually included in these fields. In the +Reuters-21578 collection this field is always empty. + +In the table above we note how many categories appear in at least 1 of +the 21,578 documents in the collection, and how many appear at least +20 of the documents. Many categories appear in no documents, but we +encourage researchers to include these categories when evaluating the +effectiveness of their categorization system. + +Additional details of the documents, categories, and corpus +preparation process appear in LEWIS92b, and at greater length in +Section 8.1 of LEWIS91d. + +VIII. Using Reuters-21578 for Text Categorization Research + + In testing a method for text categorization it is important that +knowledge of the nature of the test data not unduly influence the +development of the system, or the performance obtained will be +unrealistically high. One way of dealing with this is to divide a set +of data into two subsets: a training set and a test set. An +experimenter then develops a categorization system by automated +training on the training set only, and/or by human knowledge +engineering based on examination of the training set only. The +categorization system is then tested on the previously unexamined test +set. A number of variations on this basic theme are possible---see +WEISS91 for a good discussion. + + Effectiveness results can only be compared between studies that +the same training and test set (or that use cross-validation +procedures). One problem with the Reuters-22173 collection was that +the ambiguity of formatting and annotation led different researchers +to use different training/test divisions. This was particularly +problematic when researchers attempted to remove documents that "had +no TOPICS", as there were several definitions of what this meant. + + To eliminate these ambiguities from the Reuters-21578 collection +we specify exactly which articles are in each of the recommended +training sets and test sets by specifying the values those articles +will have on the TOPICS, LEWISSPLIT, and CGISPLIT attributes of the +REUTERS tags. We strongly encourage that all studies on Reuters-21578 +use one of the following training test divisions (or use multiple +random splits, e.g. cross-validation): + +VIII.A. The Modified Lewis ("ModLewis") Split: + + Training Set (13,625 docs): LEWISSPLIT="TRAIN"; TOPICS="YES" or "NO" + Test Set (6,188 docs): LEWISSPLIT="TEST"; TOPICS="YES" or "NO" + Unused (1,765): LEWISSPLIT="NOT-USED" or TOPICS="BYPASS" + +This replaces the 14704/6746 split (723 unused) of the Reuters-22173 +collection, which was used in LEWIS91d (Chapters 9 and 10), LEWIS92b, +LEWIS92c, LEWIS92e, and LEWIS94b. Note the following: + + 1. The duplicate documents removed in forming Reuters-21578 are +of course not present. + 2. The documents with TOPICS="BYPASS" are not used, since +subsequent analysis strongly indicates that they were not categorized +by the indexers. + 3. The 1,765 unused documents should not be tested on and should +not be used for supervised learning. However, they may useful as +additional information on the statistical distribution of words, +phrases, and other features that might used to predict categories. + +This split assigns documents from April 7, 1987 and before to the +training set, and documents from April 8, 1987 and after to the test +set. + +WARNING: Given the many changes in going from Reuters-22173 to +Reuters-21578, including correction of many typographical errors in +category labels, results on the ModLewis split cannot be compared +with any published results on the Reuters-22173 collection! + + +VIII.B. The Modified Apte ("ModApte") Split : + + Training Set (9,603 docs): LEWISSPLIT="TRAIN"; TOPICS="YES" + Test Set (3,299 docs): LEWISSPLIT="TEST"; TOPICS="YES" + Unused (8,676 docs): LEWISSPLIT="NOT-USED"; TOPICS="YES" + or TOPICS="NO" + or TOPICS="BYPASS" + +This replaces the 10645/3672 split (7,856 not used) of the +Reuters-22173 collection. These are our best approximation to the +training and test splits used in APTE94 and APTE94b. Note the +following: + + 1. As with the ModLewis, those documents removed in forming +Reuters-21578 are not present, and BYPASS documents are not used. + 2. The intent in APTE94 and APTE94b was to use the Lewis split, +but restrict it to documents with at least one TOPICS categories. +However, but it was not clear exactly what Apte, et al meant by having +at least one TOPICS category (e.g. how was "bypass" treated, whether +this was before or after any fixing of typographical errors, etc.). We +have encoded our interpretation in the TOPICS attribute. ***Note +that, as discussed above, some TOPICS="YES" stories have no TOPICS +categories, and a few TOPICS="NO" stories have TOPICS +categories. These facts are irrelevant to the definition of the +split.*** If you are using a learning algorithm that requires each +training document to have at least TOPICS category, you can screen out +the training documents with no TOPICS categories. Please do NOT screen +out any of the 3,299 documents - that will make your results +incomparable with other studies. + + 3. As with ModLewis, it may be desirable to use the 8,676 Unused +documents for gathering statistical information about feature +distribution. + +As with ModLewis, this split assigns documents from April 7, 1987 and +before to the training set, and documents from April 8, 1987 and after +to the test set. The difference is that only documents with at least +one TOPICS category are used. The rationale for this restriction is +that while some documents lack TOPICS categories because no TOPICS +apply (i.e. the document is a true negative example for all TOPICS +categories), it appears that others simply were never assigned TOPICS +categories by the indexers. (Unfortunately, the amount of time that +has passed since the collection was created has made it difficult to +establish exactly what went on during the indexing.) + +WARNING: Given the many changes in going from Reuters-22173 to +Reuters-21578, including correction of many typographical errors in +category labels, results on the ModApte split cannot be compared +with any published results on the Reuters-22173 collection! + + +VIII.C. The Modified Hayes ("ModHayes") Split: + Training Set (20856 docs): CGISPLIT="TRAINING-SET" + Test Set (722 docs): CGISPLIT="PUBLISHED-TESTSET" + Unused (0 docs) + +This is the best approximation we have to the training and test splits +used in HAYES89, HAYES90b, and Chapter 8 of LEWIS91d. It replaces the +21450/723 split of the Reuters-22173 collection. Note the following: + + 1. As with the other splits, the duplicate documents removed in +forming Reuters-21578 are not present. + + 2. "Training" in HAYES89 and HAYES90b was actually done by human +beings looking at the documents and writing categorization rules. +We can not be sure which of the document files were actually looked +at. + + 3. We specify that the BYPASS stories and the TOPICS=NO stories +are part of the training set, since they were used during manual +knowledge engineering in the original Hayes experiments. That does not +mean researchers are obliged to give these stories to, for instance, a +supervised learning algorithm. As mentioned in the other splits, they +may be more useful for getting distributional information about +features. + +There are a number of problems with the ModHayes split that make it +less than desirable for text categorization research, including +unusual distribution of categories, pairs of near-duplicate documents, +and chronological burstiness. (See [LEWIS90b, Ch. 8] for more +details.) + +Despite these problems, this split is of interest because it provides +the ability to compare results with those of the CONSTRUE system +[HAYES89, HAYES90b]. Comparison of results on the ModHayes split with +previously published results on the original Hayes split in HAYES89 +and HAYES90b (and LEWIS90b, Ch. 8) is possible, though the following +points should be taken into account: + + 1. The testset we provide in the ModHayes split has one fewer +document than the one Hayes used. The document that was removed +(OLDID="22026") was a timestamp duplicate of the document with +OLDID="22027" and NEWID="13234". So in computing effectiveness +measures for comparison with HAYES89/90b, the document with +NEWID="13234" should be counted twice. + + 2. The documents in the Hayes testset had relatively few errors and +anomalies in their categorization. And the errors which we did find +and correct appear unlikely to have affected the original Hayes +results. In particular, it appears that the only errors in the TOPICS +field were the addition of a few invalid categories that were not +evaluated on. However, for completeness we list the changes in the +Hayes testset documents made going from Reuters-22173 to Reuters-21578 +(all documents are referred to by their NEWID): + + Removal of invalid TOPIC "loan" : 13234, 16946, 17111, 17112, 17207, +17217, 17228, 17234, 17271, 17310 + + Removal of invalid TOPIC "gbond" : 17138, 17260 + + Removal of invalid TOPIC "tbill" : 17258 + + Removal of invalid TOPIC "cbond" : 17024 + + Removal of invalid TOPIC "fbond" : 17087 + + Correction of invalid PEOPLE mancera to mancera-aguayo: 17142, +17149, 17154, 17177, 17187 + + Correction of invalid PEOPLE andriesssen to andriessen : 17366 + + Correction of invalid PLACES "ivory" and "coast" to single correct +PLACE "ivory-coast": 18383 + + 3. The effectiveness measures used in HAYES89 and HAYES90b were +somewhat nonstandard. See Ch. 8 of LEWIS91d for a discussion. + + +VIII.D. Other Splits + + We strongly encourage researchers to use one (or more) of the +above splits for their experiments (or use cross-validation on one of +the sets of documents defined in the above splits). We recommend the +Modified Apte ("ModApte") Split for research on predicting the TOPICS +field, since the evidence is that a significant number of documents +that should have TOPICS do not. The ModLewis split can be used if the +researcher has a strong need to test the ability of a system to deal +with examples belonging to no category. While it is likely that some +of these examples should indeed belong to a category, the ModLewis +split is at least better than the corresponding split from +Reuters-22173, in that it eliminates the "bypass" stories. + + We in particular encourage you to resist the following +temptations: + 1. Defining new splits based on whether or not the documents +actually have any TOPICS categories. (See the discussion of the +ModApte split.) + 2. Testing your system only on the "easy" categories. This is a +temptation we have succumbed to in the past, but will resist in the +future. Yes, we know that some of the 135 TOPICS categories have few +or no positive training examples or few or no positive test examples +or both. Yes, purely supervised learning systems will do very badly +on these categories. Knowledge-based systems, on the other hand, +might do well on them, while doing poorly in comparison with +supervised learning on categories with lots of positive +examples. These comparisons are of great interest. Of course, it's of +great interest to *in addition* analyze subsets of categories +(e.g. lots of positive examples vs. few positive examples, etc.). + + Note that one strategy we considered and rejected is to assume +that documents which have no TOPICS but do have categories in other +fields (PLACES, etc.) could be assumed to belong to no TOPICS +categories. This does not appear to be a safe assumption - we have +found a number of examples of documents with PLACES but no TOPICS when +there are TOPICS that clearly apply. + +IX. Feature Sets in Text Categorization + + For many text categorization methods, particularly those using +statistical classification techniques, it is convenient to represent +documents not as a sequence of characters, but rather as a tuple of +numeric or binary feature values. For instance, the value of feature +Fi for a document Dj might be 1 if the string of characters +"financial" occurred in the document with whitespace on either side, +and 0 otherwise. Or the value of Fi for Dj might be the number of +occurrences of "financial" in document Dj. In information retrieval +such features are often called "indexing terms" and one often speaks +of a term being "present" in a document, to mean that the feature +takes on a non-default value. (Usually, but not always, any value but +0 is non-default.) + + Comparisons between text categorization methods that represent +documents as feature tuples are aided by ensuring that the same tuple +representation is used with all methods, thus avoiding conflating +differences in feature extraction with differences in, say, machine +learning methods. For that reason, the Reuters-22173 distribution +included not only the formatted text of the Reuters stories, but also +feature tuple representations of the stories in each of two feature +sets, one based on words and one based on noun phrases. Surprisingly, +almost no use was made of these files by other researchers, so we have +not included files of this sort in the Reuters-21578 distribution. + + However, we are willing to make available as part of the +distribution any tuple representations of this sort that researchers +want to contribute. (Contact lewis@research.att.com if you would like +to do this.) Perhaps the ideal situation would be if someone with a +strong interest in feature set formation produced tuples based on a +high quality set of features which other researchers interested only +in learning algorithms could make use of. + + +X. Bibliography + +[This needs to be updated.] + +@article{APTE94 + ,author = "Chidanand Apt{\'{e}} and Fred Damerau and Sholom M. Weiss" + ,title = "Automated Learning of Decision Rules for Text Categorization" + ,journal = "ACM Transactions on Information Systems" + ,year = 1994 + , note = "To appear." + } + +@inproceedings{APTE94b + ,author = "Chidanand Apt{\'{e}} and Fred Damerau and Sholom M. Weiss" + ,title = "Toward Language Independent Automated Learning of Text Categorization Models" + ,booktitle = sigir94 + ,year = 1994 + ,note = "To appear." + } + +@inproceedings{HAYES89 +,author = "Philip J. Hayes and Peggy M. Anderson and Irene B. Nirenburg and +Linda M. Schmandt" +,title = "{TCS}: A Shell for Content-Based Text Categorization" +,booktitle = "IEEE Conference on Artificial Intelligence Applications" +,year = 1990 +} + +@inproceedings{HAYES90b +,author = "Philip J. Hayes and Steven P. Weinstein" +,title = "{CONSTRUE/TIS:} A System for Content-Based Indexing of a +Database of News Stories" +,booktitle = "Second Annual Conference on Innovative Applications of +Artificial Intelligence" +,year = 1990 +} + +@incollection{HAYES92 + ,author = "Philip J. Hayes" + ,title = "Intelligent High-Volume Text Processing using Shallow, +Domain-Specific Techniques" + ,booktitle = "Text-Based Intelligent Systems" + ,publisher = "Lawrence Erlbaum" + ,address = "Hillsdale, NJ" + ,year = 1992 + ,editor = "Paul S. Jacobs" +} + +@inproceedings{LEWIS91c + ,author = "David D. Lewis" + ,title = "Evaluating Text Categorization" + ,booktitle = "Proceedings of Speech and Natural Language Workshop" + ,year = 1991 + ,month = feb + ,organization = "Defense Advanced Research Projects Agency" + ,publisher = "Morgan Kaufmann" + ,pages = "312--318" + +} + +@phdthesis{LEWIS91d +,author = "David Dolan Lewis" +,title = "Representation and Learning in Information Retrieval" +,school = "Computer Science Dept.; Univ. of Massachusetts; Amherst, MA 01003" +,year = 1992 +,note = "Technical Report 91--93." +} + +@inproceedings{LEWIS91e +,author = "David D. Lewis" +,title = "Data Extraction as Text Categorization: An Experiment with +the {MUC-3} Corpus" +,booktitle = "Proceedings of the Third Message Understanding Evaluation +and Conference" +,year = 1991 +,month = may +,organization = "Defense Advanced Research Projects Agency" +,publisher = "Morgan Kaufmann" +,address = "Los Altos, CA" + +} + +@inproceedings{LEWIS92b + ,author = "David D. Lewis" + ,title = "An Evaluation of Phrasal and Clustered Representations on a Text +Categorization Task" + ,booktitle = "Fifteenth Annual International ACM SIGIR Conference on +Research and Development in Information Retrieval" + ,year = 1992 + ,pages = "37--50" +} + +@inproceedings{LEWIS92d +,author = "David D. Lewis and Richard M. Tong" +,title = "Text Filtering in {MUC-3} and {MUC-4}" +,booktitle = "Proceedings of the Fourth Message Understanding Conference ({MUC-4})" +,year = 1992 +,month = jun +,organization = "Defense Advanced Research Projects Agency" +,publisher = "Morgan Kaufmann" +,address = "Los Altos, CA" +} + +@inproceedings{LEWIS92e +,author = "David D. Lewis" +,title = "Feature Selection and Feature Extraction for Text Categorization" +,booktitle = "Proceedings of Speech and Natural Language Workshop" +,year = 1992 +,month = feb +,organization = "Defense Advanced Research Projects Agency" +,publisher = "Morgan Kaufmann" +,pages = "212--217" +} + +@inproceedings{LEWIS94b + ,author = "David D. Lewis and Marc Ringuette" + ,title = "A Comparison of Two Learning Algorithms for Text Categorization" + ,booktitle = "Symposium on Document Analysis and Information Retrieval" + ,year = 1994 + ,organization = "ISRI; Univ. of Nevada, Las Vegas" + ,address = "Las Vegas, NV" + ,month = apr + ,pages = "81--93" +} + +@article{LEWIS94d +, author = "David D. Lewis and Philip J. Hayes" +, title = "Guest Editorial" +, journal = "ACM Transactions on Information Systems" +, year = 1994 +, volume = 12 +, number = 3 +, pages = "231" +, month = jul +} + +@article{SPARCKJONES76 +,author = "K. {Sparck Jones} and C. J. {van Rijsbergen}" +,title = "Information Retrieval Test Collections" +,journal = "Journal of Documentation" +,year = 1976 +,volume = 32 +,number = 1 +,pages = "59--75" + } + +@book{WEISS91 + ,author = "Sholom M. Weiss and Casimir A. Kulikowski" + ,title = "Computer Systems That Learn" + ,publisher = "Morgan Kaufmann" + ,year = 1991 + ,address = "San Mateo, CA" + } + + + + diff --git a/src/test/data/reuters-21578/all-exchanges-strings.lc.txt b/src/test/data/reuters-21578/all-exchanges-strings.lc.txt new file mode 100644 index 00000000000..0fd57b9fbff --- /dev/null +++ b/src/test/data/reuters-21578/all-exchanges-strings.lc.txt @@ -0,0 +1,39 @@ +amex +ase +asx +biffex +bse +cboe +cbt +cme +comex +cse +fox +fse +hkse +ipe +jse +klce +klse +liffe +lme +lse +mase +mise +mnse +mose +nasdaq +nyce +nycsce +nymex +nyse +ose +pse +set +simex +sse +stse +tose +tse +wce +zse diff --git a/src/test/data/reuters-21578/all-orgs-strings.lc.txt b/src/test/data/reuters-21578/all-orgs-strings.lc.txt new file mode 100644 index 00000000000..9d85c329b78 --- /dev/null +++ b/src/test/data/reuters-21578/all-orgs-strings.lc.txt @@ -0,0 +1,56 @@ +adb-africa +adb-asia +aibd +aid +anrpc +asean +atpc +bis +cipec +comecon +ec +eca +ecafe +ece +ecla +ecsc +ecwa +efta +eib +emcf +escap +euratom +fao +gatt +gcc +geplacea +iaea +iata +icco +ico-coffee +ico-islam +ida +iea +iisi +ilo +ilzsg +imco +imf +inro +irsg +isa +itc +iwc-whale +iwc-wheat +iwcc +iws +iwto +lafta +mfa +oapec +oecd +opec +un +unctad +who +worldbank diff --git a/src/test/data/reuters-21578/all-people-strings.lc.txt b/src/test/data/reuters-21578/all-people-strings.lc.txt new file mode 100644 index 00000000000..3eb00fcf21b --- /dev/null +++ b/src/test/data/reuters-21578/all-people-strings.lc.txt @@ -0,0 +1,267 @@ +abdel-hadi-kandeel +alfonsin +alhaji-abdul-ahmed +alptemocin +amato +andersen +andriessen +aqazadeh +aquino +arafat +babangida +balladur +bangemann +barreto +berge +beteta +blix +boesky +bond +botha +bouey +braks +bresser-pereira +brodersohn +brundtland +camdessus +carlsson +caro +castelo-branco +castro +cavaco-silva +chaves +chen-muhua +chiang-ching-kuo +chien +chirac +ciampi +colombo +conable +concepcion +corrigan +cossiga +crow +dadzie +dauster +de-clercq +de-kock +de-korte +de-la-madrid +de-larosiere +del-mazo +delamuraz +delors +dementsev +deng-xiaoping +dennis +dhillon +dominguez +douglas +du-plessis +duisenberg +dunkel +edelman +enggaard +eser +evren +eyskens +feldt +fernandez +ferrari +finnbogadottir +friedman +fujioka +gaddafi +gandhi +garcia +gava +godeaux +gonzalez +gorbachev +goria +gostyev +graf +greenspan +gromyko +grosz +guillaume +halikias +hamad-saud-al-sayyari +hannibalsson +haughey +hawke +he-kang +herrington +hillery +hisham-nazer +hoefner +hoffmeyer +holberg +holkeri +honecker +hovmand +howard-baker +husak +icahn +james-baker +james-miller +jaruzelski +jayme +johnston +kaminsky +kaufman +keating +khameini +khomeini +kiechle +king-fahd +kohl +koivisto +kondo +koren +kullberg +lacina +lange +languetin +lawson +lee-ta-hai +lee-teng-hui +leenanon +leigh-pemberton +leitz +li-peng +li-xiannian +liikanen +lubbers +lukman +lyng +machinea +macsharry +malhotra +mancera-aguayo +martens +martin +masse +maxwell +maystadt +medgyessy +messner +mikulic +milliet +mitterrand +miyazawa +mohammad-ibrahim-jaffrey-baluch +mohammad-khan-junejo +mohammad-yasin-khan-wattoo +mohammed-ahmed-al-razaz +mohammed-ali-abal-khail +mohammed-salaheddin-hamid +morales-bermudez +mousavi +moyle +mubarak +mulroney +murdoch +mustapha +nakao +nakasone +nasko +nemeth +nobrega +o-cofaigh +o-kennedy +oeien +okongwu +ongpin +ortega +ozal +palsson +pandolfi +papandreou +parkinson +paye +perez-de-cuellar +petricioli +pickens +poehl +pottakis +prawiro +qassemi +rafnar +rafsanjani +reagan +rezende +riberio-cadilhe +rich +rikanovic +rojas +romero +roumeliotis +rowland +rubio +ruder +ruding +russell +ryzhkov +saberbein +salinas +samojlik +santer +saracoglu +sarney +sartzetakis +sathe +schlueter +sedki +simitis +simonsen +singhasaneh +siregar +skaanland +soares +solchaga +sourrouille +sprinkel +steeg +stich +stoltenberg +stoph +strougal +subroto +suharto +sumita +suominen +takeshita +tamura +tavares-moreia +thatcher +timar +tinsulanonda +tiwari +toernaes +toman +tsovolas +vancsa +venkataraman +vera-la-rosa +verity +villanyi +vlatkovic +volcker +von-weizsaecker +vranitzky +waldheim +wali +walsh +wang-bingqian +wardhana +wasim-aun-jaffrey +wilson +wise +yeutter +young +yu-kuo-hua +zak +zhao-ziyang +zheng-tuobin +zia-ul-haq diff --git a/src/test/data/reuters-21578/all-places-strings.lc.txt b/src/test/data/reuters-21578/all-places-strings.lc.txt new file mode 100644 index 00000000000..4eb2bec007d --- /dev/null +++ b/src/test/data/reuters-21578/all-places-strings.lc.txt @@ -0,0 +1,175 @@ +afghanistan +albania +algeria +american-samoa +andorra +angola +anguilla +antigua +argentina +aruba +australia +austria +bahamas +bahrain +bangladesh +barbados +belgium +belize +benin +bermuda +bhutan +bolivia +botswana +brazil +british-virgin-islands +brunei +bulgaria +burkina-faso +burma +burundi +cameroon +canada +cape-verde +cayman-islands +central-african-republic +chad +chile +china +colombia +congo +costa-rica +cuba +cyprus +czechoslovakia +denmark +djibouti +dominica +dominican-republic +east-germany +ecuador +egypt +el-salvador +equatorial-guinea +ethiopia +fiji +finland +france +french-guiana +gabon +gambia +ghana +gibraltar +greece +grenada +guadeloupe +guam +guatemala +guinea +guinea-bissau +guyana +haiti +honduras +hong-kong +hungary +iceland +india +indonesia +iran +iraq +ireland +israel +italy +ivory-coast +jamaica +japan +jordan +kampuchea +kenya +kuwait +laos +lebanon +lesotho +liberia +libya +liechtenstein +luxembourg +macao +madagascar +malawi +malaysia +mali +malta +martinique +mauritania +mauritius +mexico +monaco +morocco +mozambique +namibia +nepal +netherlands +netherlands-antilles +new-caledonia +new-zealand +nicaragua +niger +nigeria +north-korea +norway +oman +pakistan +panama +papua-new-guinea +paraguay +peru +philippines +poland +portugal +qatar +romania +rwanda +saudi-arabia +senegal +seychelles +sierra-leone +singapore +somalia +south-africa +south-korea +spain +sri-lanka +sudan +suriname +swaziland +sweden +switzerland +syria +taiwan +tanzania +thailand +togo +tonga +trinidad-tobago +tunisia +turkey +uae +uganda +uk +uruguay +us-virgin-islands +usa +ussr +vanuatu +vatican +venezuela +vietnam +west-germany +western-samoa +yemen-arab-republic +yemen-demo-republic +yugoslavia +zaire +zambia +zimbabwe diff --git a/src/test/data/reuters-21578/all-topics-strings.lc.txt b/src/test/data/reuters-21578/all-topics-strings.lc.txt new file mode 100644 index 00000000000..ba953061ebe --- /dev/null +++ b/src/test/data/reuters-21578/all-topics-strings.lc.txt @@ -0,0 +1,135 @@ +acq +alum +austdlr +austral +barley +bfr +bop +can +carcass +castor-meal +castor-oil +castorseed +citruspulp +cocoa +coconut +coconut-oil +coffee +copper +copra-cake +corn +corn-oil +cornglutenfeed +cotton +cotton-meal +cotton-oil +cottonseed +cpi +cpu +crude +cruzado +dfl +dkr +dlr +dmk +drachma +earn +escudo +f-cattle +ffr +fishmeal +flaxseed +fuel +gas +gnp +gold +grain +groundnut +groundnut-meal +groundnut-oil +heat +hk +hog +housing +income +instal-debt +interest +inventories +ipi +iron-steel +jet +jobs +l-cattle +lead +lei +lin-meal +lin-oil +linseed +lit +livestock +lumber +lupin +meal-feed +mexpeso +money-fx +money-supply +naphtha +nat-gas +nickel +nkr +nzdlr +oat +oilseed +orange +palladium +palm-meal +palm-oil +palmkernel +peseta +pet-chem +platinum +plywood +pork-belly +potato +propane +rand +rape-meal +rape-oil +rapeseed +red-bean +reserves +retail +rice +ringgit +rubber +rupiah +rye +saudriyal +sfr +ship +silk +silver +singdlr +skr +sorghum +soy-meal +soy-oil +soybean +stg +strategic-metal +sugar +sun-meal +sun-oil +sunseed +tapioca +tea +tin +trade +tung +tung-oil +veg-oil +wheat +wool +wpi +yen +zinc diff --git a/src/test/data/reuters-21578/cat-descriptions_120396.txt b/src/test/data/reuters-21578/cat-descriptions_120396.txt new file mode 100644 index 00000000000..89676397c0c --- /dev/null +++ b/src/test/data/reuters-21578/cat-descriptions_120396.txt @@ -0,0 +1,1203 @@ + +Some notes on the Reuters Categories +David D. Lewis +3-Dec-96 + + The letter W. Bruce Croft received from Phil Hayes (March 9, 1990) +gave a list of 135 TOPICS categories, which were used in HAYES89. I +reproduce this list below. + + The email message David D. Lewis received (Nov. 26, 1990) from Phil +Hayes gave lists (which I reproduce below) for categories in these +fields: + + number stated number actually + at top of list on list + ORGS 56 56 + EXCHANGES 39 39 + PLACES (i.e. COUNTRIES) 176 175 + PEOPLE 269 267 + + Total 540 537 + Total stated in IEEE paper: 539 + + The total 674 categories mentioned in HAYES90b is the sum of 135 and +539. So the published numbers are a little off. For the purposes of +Reuters-21578 we have taken as ground truth the actual lists of +category names, and the number of items on those lists. + +********************************************************************* + +****Subject Codes (135) + +Money/Foreign Exchange (MONEY-FX) +Shipping (SHIP) +Interest Rates (INTEREST) + +**Economic Indicator Codes (16) + +Balance of Payments (BOP) +Trade (TRADE) +Consumer Price Index (CPI) +Wholesale Price Index (WPI) +Unemployment (JOBS) +Industrial Production Index (IPI) +Capacity Utilisation (CPU) +Gross National/Domestic Product (GNP) +Money Supply (MONEY-SUPPLY) +Reserves (RESERVES) +Leading Economic Indicators (LEI) +Housing Starts (HOUSING) +Personal Income (INCOME) +Inventories (INVENTORIES) +Instalment Debt/Consumer Credit (INSTAL-DEBT) +Retail Sales (RETAIL) + +**Currency Codes (27) + +U.S. Dollar (DLR) +Australian Dollar (AUSTDLR) +Hong Kong Dollar (HK) +Singapore Dollar (SINGDLR) +New Zealand Dollar (NZDLR) +Canadian Dollar (CAN) +Sterling (STG) +D-Mark (DMK) +Japanese Yen (YEN) +Swiss Franc (SFR) +French Franc (FFR) +Belgian Franc (BFR) +Netherlands Guilder/Florin (DFL) +Italian Lira (LIT) +Danish Krone/Crown (DKR) +Norwegian Krone/Crown (NKR) +Swedish Krona/Crown (SKR) +Mexican Peso (MEXPESO) +Brazilian Cruzado (CRUZADO) +Argentine Austral (AUSTRAL) +Saudi Arabian Riyal (SAUDRIYAL) +South African Rand (RAND) +Indonesian Rupiah (RUPIAH) +Malaysian Ringitt (RINGGIT) +Portuguese Escudo (ESCUDO) +Spanish Peseta (PESETA) +Greek Drachma (DRACHMA) + +**Corporate Codes (2) + +Mergers/Acquisitions (ACQ) +Earnings and Earnings Forecasts (EARN) + +**Commodity Codes (78) + +ALUM +BARLEY +CARCASS +CASTOR-MEAL +CASTOR-OIL +CASTORSEED +CITRUSPULP +COCOA +COCONUT-OIL +COCONUT +COFFEE +COPPER +COPRA-CAKE +CORN-OIL +CORN +CORNGLUTENFEED +COTTON +COTTON-MEAL +COTTON-OIL +COTTONSEED +F-CATTLE +FISHMEAL +FLAXSEED +GOLD +GRAIN +GROUNDNUT +GROUNDNUT-MEAL +GROUNDNUT-OIL +IRON-STEEL +LEAD +LIN-MEAL +LIN-OIL +LINSEED +LIVESTOCK +L-CATTLE +HOG +LUMBER +LUPIN +MEAL-FEED +NICKEL +OAT +OILSEED +ORANGE +PALLADIUM +PALM-MEAL +PALM-OIL +PALMKERNEL +PLATINUM +PLYWOOD +PORK-BELLY +POTATO +RAPE-MEAL +RAPE-OIL +RAPESEED +RED-BEAN +RICE +RUBBER +RYE +SILK +SILVER +SORGHUM +SOY-MEAL +SOY-OIL +SOYBEAN +STRATEGIC-METAL +SUGAR +SUN-MEAL +SUN-OIL +SUNSEED +TAPIOCA +TEA +TIN +TUNG-OIL +TUNG +VEG-OIL +WHEAT +WOOL +ZINC + +**Energy Codes (9) + +Crude Oil (CRUDE) +Heating Oil/Gas Oil (HEAT) +Fuel Oil (FUEL) +Gasoline (GAS) +Natural Gas (NAT-GAS) +Petro-Chemicals (PET-CHEM) +Propane (PROPANE) +Jet and Kerosene (JET) +Naphtha (NAPHTHA) + +________________________________________________________________ + +@heading[Organization Codes (56)] +@begin[format] +African Development Bank (ADB-AFRICA)@* +Agency for International Development (AID)@* +Asian Development Bank (ADB-ASIA)@* +Association of International Bond Dealers (AIBD)@* +Association of Natural Rubber Producing Countries (ANRPC)@* +Association of South East Asian Nations (ASEAN)@* +Association of Tin Producing Countries (ATPC)@* +Bank for International Settlements (BIS)@* +Council for Mutual Economic Assistance (COMECON)@* +Economic Commission for Africa (ECA)@* +Economic Commission for Asia and the Far East (ECAFE)@* +Economic Commission for Europe (ECE)@* +Economic Commission for Latin America and The Caribbean (ECLA)@* +Economic Commission for West Asia (ECWA)@* +Economic and Social Commission for Asia and the Pacific (ESCAP)@* +European Atomic Energy Community (EURATOM)@* +European Coal and Steel Community (ECSC)@* +European Community (EC)@* +European Free Trade Association (EFTA)@* +European Investment Bank (EIB)@* +European Monetary Cooperation Fund (EMCF)@* +Food and Agriculture Organisation (FAO)@* +General Agreement on Tariffs and Trade (GATT)@* +Grupo de Paises Latinoamericanos y del Caribe Exportadores de Azucar +[Group of Latin American and Caribbean Sugar Exporting Countries] +(GEPLACEA)@* +Gulf Cooperation Council (GCC)@* +Inter-Government Council of Copper Exporting Countries (CIPEC)@* +Inter-Governmental Maritime Consultative Organisation (IMCO)@* +International Air Transport Association (IATA)@* +International Atomic Energy Authority (IAEA)@* +International Bank for Reconstruction and Development (WORLDBANK)@* +International Cocoa Organisation (ICCO)@* +International Coffee Organisation (ICO-COFFEE)@* +International Development Association (IDA)@* +International Energy Agency (IEA)@* +International Iron and Steel Institute (IISI)@* +International Labour Organisation (ILO)@* +International Lead and Zinc Study Group (ILZSG)@* +International Monetary Fund (IMF)@* +International Natural Rubber Organisation (INRO)@* +International Rubber Study Group (IRSG)@* +International Sugar Agreement (ISA)@* +International Tin Council (ITC)@* +International Whaling Commission (IWC-WHALE)@* +International Wheat Council (IWC-WHEAT)@* +International Wool Secretariat (IWS)@* +International Wool Textile Organisation (IWTO)@* +International Wrought Copper Council (IWCC)@* +Islamic Conference Organisation (ICO-ISLAM)@* +Latin American Free Trade Association (LAFTA)@* +Multi-Fibres Arrangement (MFA)@* +Organisation for Economic Cooperation and Development (OECD)@* +Organisation of Arab Petroleum Exporting Countries (OAPEC)@* +Organisation of Petroleum Exporting Countries (OPEC)@* +United Nations (UN)@* +United Nations Conference on Trade and Development (UNCTAD)@* +World Health Organisation (WHO)@* +@end[format] +@blankspace[3 lines] +________________________________________________________________ +@heading[Exchange Codes (39)] +@begin[format] +American Stock Exchange (AMEX)@* +Amsterdam Stock Exchange/Bourse (ASE)@* +Australian Stock Exchange (ASX)@* +Baltic International Freight Futures Exchange (BIFFEX)@* +Brussels Stock Exchange/Bourse (BSE)@* +Chicago Board of Trade (CBT)@* +Chicago Board of Trade Options Exchange (CBOE)@* +Chicago Mercantile Exchange (CME)@* +Copenhagen Stock Exchange/Bourse (CSE)@* +Frankfurt Stock Exchange/Bourse (FSE)@* +Hong Kong Stock Exchange (HKSE)@* +International Petroleum Exchange (IPE)@* +Johannesburg Stock Exchange (JSE)@* +Kuala Lumpur Commodity Exchange (KLCE)@* +Kuala Lumpur Stock Exchange (KLSE)@* +London Futures and Options Exchange (FOX)@* +London International Financial Futures Exchange (LIFFE)@* +London Metal Exchange (LME)@* +London Stock Exchange (LSE)@* +Madrid Stock Exchange (MASE)@* +Manila Stock Exchange (MNSE)@* +Milan Stock Exchange/Bourse (MISE)@* +Montreal Stock Exchange (MOSE)@* +National Association of Securities Dealers Automated Quotation System (NASDAQ)@* +New York Coffee, Sugar and Cocoa Exchange (NYCSCE)@* +New York Commodity Exchange (COMEX)@* +New York Cotton Exchange (NYCE)@* +New York Mercantile Exchange (NYMEX)@* +New York Stock Exchange (NYSE)@* +Oslo Stock Exchange/Bourse (OSE)@* +Paris Stock Exchange/Bourse (PSE)@* +Securities Exchange of Thailand (SET)@* +Singapore International Monetary Exchange (SIMEX)@* +Singapore Stock Exchange (SSE)@* +Stockholm Stock Exchange/Bourse (STSE)@* +Tokyo Stock Exchange (TSE)@* +Toronto Stock Exchange (TOSE)@* +Winnipeg Commodity Exchange (WCE)@* +Zurich Stock Exchange/Bourse (ZSE)@* +@end[format] +@blankspace[3 lines] +________________________________________________________________ +@heading[Country Codes (176)] +@begin[format] +AFGHANISTAN@* +ALBANIA @* +ALGERIA @* +AMERICAN-SAMOA@* +ANDORRA @* +ANGOLA @* +ANGUILLA@* +ANTIGUA @* +ARGENTINA @* +ARUBA@* +AUSTRALIA @* +AUSTRIA @* +BAHAMAS @* +BAHRAIN @* +BANGLADESH @* +BARBADOS@* +BELGIUM @* +BELIZE @* +BENIN@* +BERMUDA @* +BHUTAN @* +BOLIVIA @* +BOTSWANA@* +BRAZIL @* +BRITISH-VIRGIN-ISLANDS@* +BRUNEI @* +BULGARIA@* +BURKINA-FASO@* +BURMA@* +BURUNDI @* +CAMEROON@* +CANADA @* +CAPE-VERDE @* +CAYMAN-ISLANDS@* +CENTRAL-AFRICAN-REPUBLIC@* +CHAD @* +CHILE@* +CHINA@* +COLOMBIA@* +CONGO@* +COSTA-RICA @* +CUBA @* +CYPRUS @* +CZECHOSLOVAKIA@* +DENMARK@* +DJIBOUTI@* +DOMINICA@* +DOMINICAN-REPUBLIC@* +EAST-GERMANY@* +ECUADOR @* +EGYPT@* +EL-SALVADOR@* +EQUATORIAL-GUINEA@* +ETHIOPIA@* +FIJI @* +FINLAND @* +FRANCE @* +FRENCH-GUIANA@* +GABON@* +GAMBIA @* +GHANA@* +GIBRALTAR @* +GREECE @* +GRENADA @* +GUADELOUPE @* +GUAM @* +GUATEMALA @* +GUINEA-BISSAU@* +GUINEA @* +GUYANA @* +HAITI@* +HONDURAS@* +HONG-KONG @* +HUNGARY @* +ICELAND @* +INDIA@* +INDONESIA @* +IRAN @* +IRAQ @* +IRELAND @* +ISRAEL @* +ITALY@* +IVORY-COAST@* +JAMAICA @* +JAPAN@* +JORDAN @* +KAMPUCHEA @* +KENYA@* +KUWAIT @* +LAOS @* +LEBANON @* +LESOTHO @* +LIBERIA @* +LIBYA@* +LIECHTENSTEIN@* +LUXEMBOURG @* +MACAO@* +MADAGASCAR @* +MALAWI @* +MALAYSIA@* +MALI @* +MALTA@* +MARTINIQUE @* +MAURITANIA @* +MAURITIUS @* +MEXICO @* +MONACO @* +MOROCCO @* +MOZAMBIQUE @* +NAMIBIA @* +NEPAL@* +NETHERLANDS@* +NETHERLANDS-ANTILLES@* +NEW-CALEDONIA@* +NEW-ZEALAND@* +NICARAGUA @* +NIGER@* +NIGERIA @* +NORTH-KOREA@* +NORWAY @* +OMAN @* +PAKISTAN@* +PANAMA @* +PAPUA-NEW-GUINEA@* +PARAGUAY@* +PERU @* +PHILIPPINES@* +POLAND @* +PORTUGAL@* +QATAR@* +ROMANIA @* +RWANDA @* +SAUDI-ARABIA@* +SENEGAL @* +SEYCHELLES @* +SIERRA-LEONE@* +SINGAPORE @* +SOMALIA @* +SOUTH-AFRICA@* +SOUTH-KOREA@* +SPAIN@* +SRI-LANKA @* +SUDAN@* +SURINAME@* +SWAZILAND @* +SWEDEN @* +SWITZERLAND@* +SYRIA@* +TAIWAN @* +TANZANIA@* +THAILAND@* +TOGO @* +TONGA@* +TRINIDAD-TOBAGO@* +TUNISIA @* +TURKEY @* +UAE @* +UGANDA @* +UK@* +URUGUAY @* +USA@* +USSR@* +US-VIRGIN-ISLANDS@* +VANUATU @* +VATICAN @* +VENEZUELA @* +VIETNAM @* +WEST-GERMANY@* +WESTERN-SAMOA@* +YEMEN-ARAB-REPUBLIC@* +YEMEN-DEMO-REPUBLIC@* +YUGOSLAVIA @* +ZAIRE@* +ZAMBIA @* +ZIMBABWE@* +@end[format] +@blankspace[3 lines] +________________________________________________________________ +@heading[People Codes (269)] +@begin[itemize] +Argentina +@begin[itemize] + President Raul Alfonsin (ALFONSIN) + + Economy Minister Juan Sourrouille (SOURROUILLE) + + Finance Secretary Mario Brodersohn (BRODERSOHN) + + Central Bank Governor Jose Luis Machinea (MACHINEA) +@end[itemize] + +Australia +@begin[itemize] + Prime Minister Robert (Bob) Hawke (HAWKE) + + Federal Treasurer Paul Keating (KEATING) + + Finance Minister Peter Walsh (WALSH) + + Central Bank (Reserve Bank) Governor Bob Johnston (JOHNSTON) +@end[itemize] + +Austria +@begin[itemize] + President Kurt Waldheim (WALDHEIM) + + Chancellor Franz Vranitzky (VRANITZKY) + + Finance Minister Ferdinand Lacina (LACINA) + + Economy Minister Robert Graf (GRAF) + + Central Bank President Stephan Koren (KOREN) +@end[itemize] + +Belgium +@begin[itemize] + Prime Minister Wilfried Martens (MARTENS) + + Deputy Prime Minister and Economy Minister Philippe Maystadt (MAYSTADT) + + Finance Minister Mark Eyskens (EYSKENS) + + Central Bank (National Bank) Governor Jean Godeaux (GODEAUX) +@end[itemize] + +Brazil +@begin[itemize] + President Jose Sarney (SARNEY) + + Finance Minister Mailson Nobrega (NOBREGA) + + (former) Finance Minister Luiz Carlos Bresser Pereira (BRESSER-PEREIRA) + + Industry and Trade Minister Jose Hugo Castelo Branco (CASTELO-BRANCO) + + Agriculture Minister Iris Rezende (REZENDE) + + Mines and Energy Minister Aureliano Chaves (CHAVES) + + Central Bank President Fernando Milliet (MILLIET) +@end[itemize] + +Canada +@begin[itemize] + Prime Minister Brian Mulroney (MULRONEY) + + Agriculture Minister John Wise (WISE) + + Finance Minister Michael Wilson (WILSON) + + Energy Minister Marcel Masse (MASSE) + + (former) Central Bank (Bank of Canada) Governor Gerald K. Bouey (BOUEY) + + Central Bank (Bank of Canada) Governor John Crow (CROW) +@end[itemize] + +China +@begin[itemize] + President Li Xiannian (LI-XIANNIAN) + + Prime Minister Zhao Ziyang (ZHAO-ZIYANG) + + Premier Li Peng (LI-PENG) + + Elder Statesman (a member of the Standing Committee of the + Communist Party Politburo) Deng Xiaoping (DENG-XIAOPING) + + Finance Minister Wang Bingqian (WANG-BINGQIAN) + + Foreign Economic Relations and Trade Minister Zheng Tuobin (ZHENG-TUOBIN) + + Agriculture Minister He Kang (HE-KANG) + + President of the People's Bank of China and Head of National + Treasury Mrs Chen Muhua (CHEN-MUHUA) +@end[itemize] + +Cuba +@begin[itemize] +Fidel Castro, President of Cuba (CASTRO) +@end[itemize] + +Czechoslovakia +@begin[itemize] + President Gustav Husak (HUSAK) + + Prime Minister Lubomir Strougal (STROUGAL) + + Deputy Minister and Minister of Agriculture and Food + Miroslav Toman (TOMAN) + + Finance Minister Jaromir Zak (ZAK) +@end[itemize] + +Denmark +@begin[itemize] + Prime Minister Poul Schlueter (SCHLUETER) + + Finance Minister Palle Simonsen (SIMONSEN) + + (former) Economy Minister Anders Andersen (ANDERSEN) + + Economy Minister Knud Enggaard (ENGGAARD) + + Energy Minister Svend Erik Hovmand (HOVMAND) + + (former) Agriculture Minister Mrs Britta Schall Holberg (HOLBERG) + + Agriculture Minister Laurits Toernaes (TOERNAES) + + Central Bank Governor Erik Hoffmeyer (HOFFMEYER) +@end[itemize] + +East Germany +@begin[itemize] +Head of State and Chairman of Council of State Erich Honecker, who is also +General Secretary of the Socialist Unity Party (HONECKER) + + Prime Minister Willi Stoph (STOPH) + + Finance Minister Ernst Hoefner (HOEFNER) + + Agriculture, Forestry and Food Minister Bruno Leitz (LEITZ) + + State Bank President Horst Kaminsky (KAMINSKY) +@end[itemize] + +Egypt +@begin[itemize] + President Hosni Mubarak (MUBARAK) + + Prime Minister Atef Sedki (SEDKI) + + (former) Economy Minister Youssri Wali (WALI) + + Economy Minister Youssri mustapha (MUSTAPHA) + + Finance Minister Mohammed Ahmed al-Razaz (MOHAMMED-AHMED-AL-RAZAZ) + + Oil and Mineral Wealth Minister Abdel-Hadi Kandeel (ABDEL-HADI-KANDEEL) + + Central Bank Governor Mohammed Salaheddin Hamid (MOHAMMED-SALAHEDDIN-HAMID) +@end[itemize] + +Finland +@begin[itemize] + President Mauno Koivisto (KOIVISTO) + + Prime Minister Harri Holkeri (HOLKERI) + + Finance Minister Erkki Liikanen (LIIKANEN) + + Trade and Industry Minister Ilkka Suominen (SUOMINEN) + + Central Bank Governor Rolf Kullberg (KULLBERG) +@end[itemize] + + +France +@begin[itemize] + President Francois Mitterrand (MITTERRAND) + + Prime Minister Jacques Chirac (CHIRAC) + + Minister of State for Economy, Finance and Privatisation + Edouard Balladur (BALLADUR) + + Agriculture Minister Francois Guillaume (GUILLAUME) + + Central Bank (Bank of France) Governor Jacques de Larosiere + (DE-LAROSIERE) +@end[itemize] + +Greece +@begin[itemize] + President Christos Sartzetakis (SARTZETAKIS) + + Prime Minister Andreas Papandreou (PAPANDREOU) + + Economy Minister Panayotis Roumeliotis (ROUMELIOTIS) + + (former) Economy Minister Kostas Simitis (SIMITIS) + + Finance Minister Dimitris Tsovolas (TSOVOLAS) + + Agriculture Minister Yannis Pottakis (POTTAKIS) + + Central Bank Governor Dimitris Halikias (HALIKIAS) +@end[itemize] + +Hungary +@begin[itemize] + Head of State and President of Presidential Council Karoly Nemeth (NEMETH) + + Prime Minister Karoly Grosz (GROSZ) + + Finance Minister Miklos Villanyi (VILLANYI) + + (former) Finance Minister Peter Medgyessy (MEDGYESSY) + + Agriculture and Food Minister Jenoe Vancsa (VANCSA) + + Central Bank President Dr Matyas Timar (TIMAR) +@end[itemize] + +Iceland +@begin[itemize] + President Mrs Vigdis Finnbogadottir (FINNBOGADOTTIR) + + Prime Minister Thorsteinn Palsson (PALSSON) + + Finance Minister Jon Baldvin Hannibalsson (HANNIBALSSON) + + Central Bank Chairman Jonas G. Rafnar (RAFNAR) +@end[itemize] + +India +@begin[itemize] + President Ramaswamy Venkataraman (VENKATARAMAN) + + Prime Minister Rajiv Gandhi (GANDHI) + + Finance and Commerce Minister Narain Dutt Tiwari (TIWARI) + + Energy Minister Vasant Sathe (SATHE) + + Agriculture and Rural Development Minister Gurdial Singh Dhillon + (DHILLON) + + Central Bank (Reserve Bank) Governor R.N. Malhotra (MALHOTRA) +@end[itemize] + +Indonesia +@begin[itemize] + President General Suharto (SUHARTO) + + Economy Minister Ali Wardhana (WARDHANA) + + Finance Minister Radius Prawiro (PRAWIRO) + + Mining and Energy Minister Subroto (SUBROTO) + + Central Bank Governor Arifin Siregar (SIREGAR) +@end[itemize] + +Iran +@begin[itemize] + Revolutionary Leader Ayatollah Ruhollah Khomeini (KHOMEINI) + + President Hojatoleslam Ali Khameini (KHAMEINI) + + Prime Minister Mir-Hossein Mousavi (MOUSAVI) + + Oil Minister Gholamreza Aqazadeh (AQAZADEH) + + Central Bank Governor Majid Qassemi (QASSEMI) + + Speaker of the Majlis (Parliament) Hojatoleslam Ali Hashemi Rafsanjani + (RAFSANJANI) +@end[itemize] + +Ireland +@begin[itemize] + President Patrick Hillery (HILLERY) + + Prime Minister Charles Haughey (HAUGHEY) + + Finance Minister Ray MacSharry (MACSHARRY) + + Agriculture Minister Michael O'Kennedy (O-KENNEDY) + + Central Bank Governor Tomas O'Cofaigh (O-COFAIGH) +@end[itemize] + +Italy +@begin[itemize] + President Francesco Cossiga (COSSIGA) + + Prime Minister Giovanni Goria (GORIA) + + Deputy Prime Minister and Treasury Minister Guiliano Amato (AMATO) + + Finance Minister Antonio Gava (GAVA) + + Budget and Planning Minister Emilio Colombo (COLOMBO) + + Agriculture and Forestry Minister Filippo Maria Pandolfi (PANDOLFI) + + Central Bank (Bank of Italy) Governor Carlo Ciampi (CIAMPI) +@end[itemize] + + + +Japan +@begin[itemize] + Prime Minister Noboru Takeshita (TAKESHITA) + + (former) Prime Minister Yasuhiro Nakasone (NAKASONE) + + Finance Minister Kiichi Miyazawa (MIYAZAWA) + + International Trade and Industry Minister Hajime Tamura (TAMURA) + + Director-General of Economic Planning Agency Eiichi Nakao (NAKAO) + + (former) Director-General of Economic Planning Agency Tetsuo Kondo (KONDO) + + Central Bank (Bank of Japan) Governor Satoshi Sumita (SUMITA) +@end[itemize] + +Libya +@begin[itemize] +Muammar Gaddafi, Libyan leader (GADDAFI) +@end[itemize] + + +Luxembourg +@begin[itemize] + Prime Minister (who is also Minister of Communications, of Finance, + of Planning and of Posts, Telephone and Telegraph) + Jacques Santer (SANTER) +@end[itemize] + +Mexico +@begin[itemize] + President Miguel de la Madrid (DE-LA-MADRID) + + Finance Minister Gustavo Petricioli (PETRICIOLI) + + Oil, Mines and Parastatal Industry Minister Alfredo Del Mazo (DEL-MAZO) + + (former) Director-General of Pemex (State Oil Company) Ramon Beteta (BETETA) + + Director-General of Pemex (State Oil Company) francisco Rojas (ROJAS) + + Central Bank President Miguel Mancera Aguayo (MANCERA-AGUAYO) +@end[itemize] + + +The Netherlands +@begin[itemize] + Prime Minister Ruud Lubbers (LUBBERS) + + Deputy Prime Minister and Minister for Economic Affairs + Rudolf De Korte (DE-KORTE) + + Finance Minister Onno Ruding (RUDING) + + Agriculture Minister Gerrit Braks (BRAKS) + + Central Bank Governor Wim Duisenberg (DUISENBERG) +@end[itemize] + + +New Zealand +@begin[itemize] + Prime Minister David Lange (LANGE) + + Finance Minister Roger Douglas (DOUGLAS) + + Agriculture Minister Colin Moyle (MOYLE) + + Central Bank (Reserve Bank) Governor Spencer Russell (RUSSELL) +@end[itemize] + +Nicaragua +@begin[itemize] +Daniel Ortega, President of Nicaragua (ORTEGA) +@end[itemize] + +Nigeria +@begin[itemize] + President General Ibrahim Babangida (BABANGIDA) + + Agriculture Minister Major-General Mohammed Gado Nasko (NASKO) + + Finance Minister Chu Okongwu (OKONGWU) + + Petroleum Resources (Oil) Minister Rilwanu Lukman (LUKMAN) + + Central Bank Governor Alhaji Abdul Ahmed (ALHAJI-ABDUL-AHMED) +@end[itemize] + +Norway +@begin[itemize] + Prime Minister Mrs Gro Harlem Brundtland (BRUNDTLAND) + + Finance Minister Gunnar Berge (BERGE) + + Oil and Energy Minister Arne Oeien (OEIEN) + + Central Bank Governor Hermud Skaanland (SKAANLAND) +@end[itemize] + + +Pakistan +@begin[itemize] + President General Zia-ul-Haq (ZIA-UL-HAQ) + + Prime Minister Mohammad Khan Junejo (MOHAMMAD-KHAN-JUNEJO) + + Finance and Economic Affairs, Petroleum and Natural Resources + Minister Mohammad Yasin Khan Wattoo + (MOHAMMAD-YASIN-KHAN-WATTOO) + + Agriculture Minister Mohammad Ibrahim Jaffrey Baluch + (MOHAMMAD-IBRAHIM-JAFFREY-BALUCH) + + Central Bank (State Bank) Governor Wasim Aun Jaffrey (WASIM-AUN-JAFFREY) +@end[itemize] + +Peru +@begin[itemize] + President Alan Garcia (GARCIA) + + Economy and Finance Minister Gustavo Saberbein Chevalier (SABERBEIN) + + (former) Trade and Industry Minister Manuel Romero Caro (CARO) + + Industry and Trade Minister Alberto Vera La Rose (VERA-LA-ROSA) + + Energy Minister Abel Salinas (SALINAS) + + Agriculture Minister Remigio Morales Bermudez (MORALES-BERMUDEZ) + + Central Bank President Cesar Ferrari (FERRARI) +@end[itemize] + +Philippines +@begin[itemize] + President Mrs Corazon Aquino (AQUINO) + + (former) Finance Minister Jaime Ongpin (ONGPIN) + + Finance Minister Vicente Jayme (JAYME) + + Agriculture Minister Carlos Dominguez (DOMINGUEZ) + + Trade and Industry Minister Jose Concepcion (CONCEPCION) + + Central Bank Governor Jose Fernandez (FERNANDEZ) +@end[itemize] + +Poland +@begin[itemize] +Head of State and Chairman of Council of State (who is also First Secretary +of Polish United Workers (Communist) Party) General Wojciech Jaruzelski +(JARUZELSKI) + + Prime Minister Zbigniew Messner (MESSNER) + + Finance Minister Bazyli Samojlik (SAMOJLIK) +@end[itemize] + + + + +Portugal +@begin[itemize] + President Mario Soares (SOARES) + + Prime Minister Anibal Cavaco Silva (CAVACO-SILVA) + + Finance Minister Miguel Riberio Cadilhe (RIBERIO-CADILHE) + + Agriculture, Fisheries and Food Minister Alvaro Barreto (BARRETO) + + Central Bank Governor Jose Tavares Moreia (TAVARES-MOREIA) +@end[itemize] + + +Saudi Arabia +@begin[itemize] + Head of State and also Prime Minister King Fahd (Ibn Abdulaziz) + (KING-FAHD) + + Finance and National Economy Minister Sheikh Mohammed Ali Abal-Khail + (MOHAMMED-ALI-ABAL-KHAIL) + + Petroleum/Oil Minister Hisham Nazer (HISHAM-NAZER) + + Governor of the Saudi Arabian Monetary Agency Hamad Saud al-Sayyari + (HAMAD-SAUD-AL-SAYYARI) +@end[itemize] + +South Africa +@begin[itemize] + President P.W. Botha (BOTHA) + + Finance Minister Barend du Plessis (DU-PLESSIS) + + Central Bank (Reserve Bank) Governor Gerhard de Kock (DE-KOCK) +@end[itemize] + +Spain +@begin[itemize] + Prime Minister Felipe Gonzalez (GONZALEZ) + + Economy, Trade and Finance Minister Carlos Solchaga (SOLCHAGA) + + Agriculture Minister Carlos Romero (ROMERO) + + Central Bank Governor Mariano Rubio (RUBIO) +@end[itemize] + + +Sweden +@begin[itemize] + Prime Minister Ingvar Carlsson (CARLSSON) + + Finance Minister Kjell-Olof Feldt (FELDT) + + Central Bank Governor Bengt Dennis (DENNIS) +@end[itemize] + +Switzerland +@begin[itemize] + Economy Minister Jean-Pascal Delamuraz (DELAMURAZ) + + Finance Minister Otto Stich (STICH) + + Central Bank President Pierre Languetin (LANGUETIN) +@end[itemize] + +Taiwan +@begin[itemize] + President Lee Teng-hui (LEE-TENG-HUI) + + (former) President Chiang Ching-kuo (CHIANG-CHING-KUO) + + Prime Minister Yu Kuo-hua (YU-KUO-HUA) + + Economy Minister Lee Ta-hai (LEE-TA-HAI) + + Finance Minister Robert Chien (CHIEN) +@end[itemize] + +Thailand +@begin[itemize] + President General Prem Tinsulanonda (TINSULANONDA) + + Finance Minister Suthee Singhasaneh (SINGHASANEH) + + Agriculture Minister General Harn Leenanon (LEENANON) +@end[itemize] + +Turkey +@begin[itemize] + President Kenan Evren (EVREN) + + Prime Minister Turgut Ozal (OZAL) + + Finance Minister Ahmet Kurtcebe Alptemocin (ALPTEMOCIN) + + Central Bank Governor Rusdu Saracoglu (SARACOGLU) +@end[itemize] + + +United Kingdom +@begin[itemize] + Prime Minister Margaret Thatcher (THATCHER) + + Chancellor of the Exchequer (Finance Minister) Nigel Lawson (LAWSON) + + Energy Secretary Cecil Parkinson (PARKINSON) + + Trade and Industry Secretary Lord Young (YOUNG) + + Central Bank (Bank of England) Governor Robin Leigh-Pemberton + (LEIGH-PEMBERTON) +@end[itemize] + + +United States +@begin[itemize] + President Ronald Reagan (REAGAN) + + Treasury Secretary James Baker (JAMES-BAKER) + + Commerce Secretary C. William Verity (VERITY) + + Energy Secretary John Herrington (HERRINGTON) + + Agriculture Secretary Richard Lyng (LYNG) + + White House Chief of Staff Howard Baker (HOWARD-BAKER) + + Representative for Trade Negotiations Clayton Yeutter (YEUTTER) + + Director of Management and Budget Office James Miller (JAMES-MILLER) + + Chairman of Federal Reserve Board Alan Greenspan (GREENSPAN) + + President of New York Federal Reserve Bank E. Gerald Corrigan + (CORRIGAN) +@end[itemize] + +USSR (Soviet Union) +@begin[itemize] + President Andrei Gromyko (GROMYKO) + + General Secretary of the Communist Party Mikhail Gorbachev (GORBACHEV) + + Prime Minister Nikolai Ryzhkov (RYZHKOV) + + Finance Minister Boris Gostyev (GOSTYEV) + + State Bank Board Chairman Viktor Dementsev (DEMENTSEV) +@end[itemize] + +West Germany +@begin[itemize] + President Richard Von Weizsaecker (VON-WEIZSAECKER) + + Chancellor Helmut Kohl (KOHL) + + Finance Minister Gerhard Stoltenberg (STOLTENBERG) + + Economy Minister Martin Bangemann (BANGEMANN) + + Agriculture, Food and Forestry Minister Ignaz Kiechle (KIECHLE) + + Central Bank (Bundesbank) President Karl Otto Poehl (POEHL) +@end[itemize] + +Yugoslavia +@begin[itemize] + Prime Minister Branko Mikulic (MIKULIC) + + Finance Minister Svetozar Rikanovic (RIKANOVIC) + + Central Bank (National Bank) Governor Dusan Vlatkovic (VLATKOVIC) +@end[itemize] + +European Community Commission +@begin[itemize] + President Jacques Delors (DELORS) + + Commissioner for Agriculture and Forestry Frans Andriessen (ANDRIESSEN) + + Commissioner for Trade Policy Willy de Clercq (DE-CLERCQ) +@end[itemize] + +International Monetary Fund Managing Director Michel Camdessus (CAMDESSUS) + +World Bank President Barber Conable (CONABLE) + +International Atomic Energy Agency Director-General Hans Blix (BLIX) + +International Energy Agency Executive Director Helga Steeg (STEEG) + +Asian Development Bank President Masao Fujioka (FUJIOKA) + +United Nations Secretary-General Javier Perez de Cuellar (PEREZ-DE-CUELLAR) + +UNCTAD (United Nations Conference on Trade and Development) + Secretary-General Kenneth Dadzie (DADZIE) + +Organisation for Economic Cooperation and Development + Secretary-General Jean-Claude Paye (PAYE) + +International Air Transport Association Director General + Guenter Eser (ESER) + +Securities and Exchange Commission Chairman David S. Ruder (RUDER) + +General Agreement on Tariffs and Trade Director-General + Arthur Dunkel (DUNKEL) + +Milton Friedman, economist (FRIEDMAN) + +Henry Kaufman, economist with Salomon Bros. (KAUFMAN) + +Ivan Boesky (BOESKY) + +Carl Icahn (ICAHN) + +T. Boone Pickens (PICKENS) + +Rupert Murdoch, publisher and chairman of News Corp Ltd (MURDOCH) + +Robert Maxwell, publisher and chairman of Mirror Group of newspapers (MAXWELL) + +Roland (Tiny) Rowland, chairman of Lonrho Plc (ROWLAND) + +Asher Edelman (EDELMAN) + +Marc Rich (RICH) + +Alan Bond, chairman of Bond Corp Ltd (BOND) + +Jorio Dauster, President of The Brazilian Coffee Institute (DAUSTER) + +Beryl Sprinkel, Chairman of Council of Economic Advisers (SPRINKEL) + +Yasser Arafat, Chairman of Palestine Liberation Organisation (ARAFAT) + +Paul Volcker, economist (VOLCKER) + +Preston Martin, member of Federal Reserve Board (MARTIN) +@end[itemize] + + + + + + diff --git a/src/test/data/reuters-21578/feldman-cia-worldfactbook-data.txt b/src/test/data/reuters-21578/feldman-cia-worldfactbook-data.txt new file mode 100644 index 00000000000..961b1a56ee1 --- /dev/null +++ b/src/test/data/reuters-21578/feldman-cia-worldfactbook-data.txt @@ -0,0 +1,5199 @@ +This is a set of Prolog assertions for facts about countries, kindly +made available by Ronen Feldman of Bar-Ilan University. It was +extracted by Ronen Feldman and Amir Zilberstein from "The Project +Gutenberg Etext of the 1994 CIA World Factbook", available at a +variety of locations on the Web. --David D. Lewis, 9-Dec-96 + +pred_type("LandBounderies","countries","countries"). +pred_type("NaturalResources","countries","topics"). +pred_type("Population","countries","countries"). +pred_type("Capital","countries","countries"). +pred_type("MemberOf","countries","countries"). +pred_type("ExportCommodities","countries","topics"). +pred_type("ExportPartners","countries","countries"). +pred_type("ImportCommodities","countries","topics"). +pred_type("ImportPartners","countries","countries"). +pred_type("Industries","countries","topics"). +pred_type("Agriculture","countries","topics"). +bgfact("Afghanistan","LandBounderies",["China","Iran","Pakistan","Tajikis= +tan","Turkmenistan","Uzbekistan"]). +bgfact("Afghanistan","NaturalResources",["natural = +gas","petroleum","coal","copper","talc","barites","sulphur","lead","zinc"= +,"iron ore","salt","precious and semiprecious stones"]). +bgfact("Afghanistan","Population",["16903400"]). +bgfact("Afghanistan","Capital",["Kabul"]). +bgfact("Afghanistan","MemberOf",["AsDB","CP","ECO","ESCAP","FAO","G-77","= +IAEA","IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","INTELSAT","IOC"= +,"ITU","LORCS","NAM","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","W= +HO","WMO","WTO"]). +bgfact("Afghanistan","ExportCommodities",["fruits and nuts","handwoven = +carpets","wool","cotton","hides and pelts","precious and semi-precious = +gems"]). +bgfact("Afghanistan","ExportPartners",["FSU = +countries","Pakistan","Iran","Germany","India","UK","Belgium","Luxembourg= +","Czechoslovakia"]). +bgfact("Afghanistan","ImportCommodities",["most consumer goods"]). +bgfact("Afghanistan","ImportPartners",["FSU = +countries","Pakistan","Iran","Japan","Singapore","India","South = +Korea","Germany"]). +bgfact("Afghanistan","Industries",["textiles","soap","furniture","shoes",= +"fertilizer","natural gas","oil","coal","copper"]). +bgfact("Afghanistan","Agriculture",["wheat","fruits","nuts","karakul = +pelts","wool","mutton"]). +bgfact("Albania","LandBounderies",["Greece","The Former Yugoslav = +Republic of Macedonia","Serbia and Montenegro"]). +bgfact("Albania","NaturalResources",["petroleum","natural = +gas","coal","chromium","copper","timber","nickel"]). +bgfact("Albania","Population",["3374085"]). +bgfact("Albania","Capital",["Tirane"]). +bgfact("Albania","MemberOf",["BSEC","CCC","CE","ISO","ITU","LORCS","NACC"= +,"OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WIPO","WMO"]). +bgfact("Albania","ExportCommodities",["asphalt","metals and metallic = +ores","electricity","crude","vegetables","fruits","tobacco"]). +bgfact("Albania","ExportPartners",["Italy","The Former Yugoslav Republic = +of = +Macedonia","Germany","Greece","Czechoslovakia","Poland","Romania","Bulgar= +ia","Hungary"]). +bgfact("Albania","ImportCommodities",["machinery","consumer = +goods","grains"]). +bgfact("Albania","ImportPartners",["Italy","The Former Yugoslav Republic = +of = +Macedonia","Germany","Czechoslovakia","Romania","Poland","Hungary","Bulga= +ria","Greece"]). +bgfact("Albania","Industries",["food processing","textiles and = +clothing","lumber","oil","cement","chemicals","mining","basic = +metals","hydropower"]). +bgfact("Albania","Agriculture",["produces wide range of temperate-zone = +crops and livestock"]). +bgfact("Algeria","LandBounderies",["Libya","Mali","Mauritania","Morocco",= +"Niger","Tunisia","Western Sahara"]). +bgfact("Algeria","NaturalResources",["petroleum","natural gas","iron = +ore","phosphates","uranium","lead","zinc"]). +bgfact("Algeria","Population",["27895068"]). +bgfact("Algeria","Capital",["Algiers"]). +bgfact("Algeria","MemberOf",["ABEDA","AfDB","AFESD","AL","AMF","AMU","CCC= +","ECA","FAO","G-15","G-19","G-24","G-77","IAEA","IBRD","ICAO","IDA","IDB= +","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","= +ISO","ITU","LORCS","NAM","OAPEC","OAS","OAU","OIC","OPEC","UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNTAC","UPU","WCL","WHO","WIPO","W= +MO","WTO"]). +bgfact("Algeria","ExportCommodities",["petroleum and natural gas"]). +bgfact("Algeria","ExportPartners",["Italy","France","US","Germany","Spain= +"]). +bgfact("Algeria","ImportCommodities",["Capital goods","food and = +beverages","consumer goods"]). +bgfact("Algeria","ImportPartners",["France","Italy","Spain","US","Germany= +"]). +bgfact("Algeria","Industries",["petroleum","light Industries","natural = +gas","mining","electrical","petrochemical","food processing"]). +bgfact("Algeria","Agriculture",["wheat","barley","oats","grapes","olives"= +,"citrus","fruits","sheep","net importer of food - grain","vegetable = +oil","sugar"]). +bgfact("American Samoa","LandBounderies",[]). +bgfact("American Samoa","NaturalResources",["pumice","pumicite"]). +bgfact("American Samoa","Population",["55223"]). +bgfact("American Samoa","Capital",["Pago Pago"]). +bgfact("American Samoa","MemberOf",["ESCAP","IOC","SPC"]). +bgfact("American Samoa","ExportCommodities",["canned tuna"]). +bgfact("American Samoa","ExportPartners",["US"]). +bgfact("American Samoa","ImportCommodities",["materials for = +canneries","food","petroleum products","machinery and parts"]). +bgfact("American = +Samoa","ImportPartners",["US","Japan","NZ","Australia","Fiji"]). +bgfact("American Samoa","Industries",["tuna canneries","meat = +canning","handicrafts"]). +bgfact("American = +Samoa","Agriculture",["bananas","coconuts","vegetables","taro","breadfrui= +t","yams","copra","pineapples","papayas","dairy farming"]). +bgfact("Andorra","LandBounderies",["France","Spain"]). +bgfact("Andorra","NaturalResources",["hydropower","mineral = +water","timber","iron ore","lead"]). +bgfact("Andorra","Population",["63930"]). +bgfact("Andorra","Capital",["Andorra la Vella"]). +bgfact("Andorra","MemberOf",["ECE","INTERPOL","IOC","UN"]). +bgfact("Andorra","ExportCommodities",["electricity","tobacco = +products","furniture"]). +bgfact("Andorra","ExportPartners",["France","Spain"]). +bgfact("Andorra","ImportCommodities",["consumer goods","food"]). +bgfact("Andorra","ImportPartners",["France","Spain"]). +bgfact("Andorra","Industries",["tourism","sheep","timber","tobacco","bank= +ing"]). +bgfact("Andorra","Agriculture",["small quantities of = +tobacco","rye","wheat","barley","oats"]). +bgfact("Angola","LandBounderies",["Congo","Namibia","Zaire","Zambia"]). +bgfact("Angola","NaturalResources",["petroleum","diamonds","iron = +ore","phosphates","copper","feldspar","gold","bauxite","uranium"]). +bgfact("Angola","Population",["9803576"]). +bgfact("Angola","Capital",["Luanda"]). +bgfact("Angola","MemberOf",["ACP","AfDB","CCC","CEEAC","OAU","SADC","UN",= +"UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Angola","ExportCommodities",["oil","diamonds","refined petroleum = +products","gas","coffee","sisal","fish and fish = +products","timber","cotton"]). +bgfact("Angola","ExportPartners",["US","France","Germany","Netherlands","= +Brazil"]). +bgfact("Angola","ImportCommodities",["Capital = +equipment","food","vehicles and spare parts","textiles and = +clothing","substantial military deliveries"]). +bgfact("Angola","ImportPartners",["Portugal","Brazil","US","France","Spai= +n"]). +bgfact("Angola","Industries",["mining - diamonds","iron = +ore","phosphates","feldspar","bauxite","uranium","basic metal = +products"]). +bgfact("Angola","Agriculture",["bananas","sugar = +cane","coffee","sisal","corn","cotton","cane","manioc","food = +cassava","corn","vegetables","livestock production accounts = +for","fishing","disruptions caused by civil war"]). +bgfact("Anguilla","LandBounderies",[]). +bgfact("Anguilla","NaturalResources",["salt","fish","lobster"]). +bgfact("Anguilla","Population",["7052"]). +bgfact("Anguilla","Capital",["The Valley"]). +bgfact("Anguilla","MemberOf",["CARICOM"]). +bgfact("Anguilla","ExportCommodities",["lobster and salt"]). +bgfact("Anguilla","ExportPartners",["NA"]). +bgfact("Anguilla","ImportCommodities",["NA"]). +bgfact("Anguilla","ImportPartners",["NA"]). +bgfact("Anguilla","Industries",["tourism","boat building","salt"]). +bgfact("Anguilla","Agriculture",["pigeon peas","corn","sweet = +potatoes","sheep","goats","pigs","cattle","poultry","fishing"]). +bgfact("Antarctica","LandBounderies",["none","but see entry on = +International disputes"]). +bgfact("Antarctica","NaturalResources",["iron = +ore","chromium","copper","gold","nickel","uncommercial quantities"]). +bgfact("Antigua and Barbuda","LandBounderies",[]). +bgfact("Antigua and Barbuda","NaturalResources",["pleasant climate = +fosters tourism"]). +bgfact("Antigua and Barbuda","Population",["64762"]). +bgfact("Antigua and Barbuda","Capital",["Saint John's"]). +bgfact("Antigua and = +Barbuda","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-77","GATT= +","IBRD","ICAO","ICFTU","IFAD","IFC","ILO","IMF","IMO","INTELSAT","OAS","= +OECS","OPANAL","UN","UNCTAD","UNESCO","WCL","WHO","WMO"]). +bgfact("Antigua and Barbuda","ExportCommodities",["petroleum = +products","manubgfactures","food and live animals","machinery and = +transport equipment"]). +bgfact("Antigua and = +Barbuda","ExportPartners",["OECS","Barbados","Guyana","Trinidad and = +Tobago","US"]). +bgfact("Antigua and Barbuda","ImportCommodities",["food and live = +animals","machinery and transport = +equipment","manubgfactures","chemicals","oil"]). +bgfact("Antigua and = +Barbuda","ImportPartners",["US","UK","Canada","OECS"]). +bgfact("Antigua and = +Barbuda","Industries",["tourism","construction","light = +manubgfacturing"]). +bgfact("Antigua and Barbuda","Agriculture",["expanding output of = +cotton","fruits","vegetables","coconuts","cucumbers","mangoes","not = +self-sufficient in food"]). +bgfact("Arctic Ocean","NaturalResources",["sand and gravel = +aggregates","placer deposits","polymetallic nodules","oil and gas = +fields","fish","marine mammals"]). +bgfact("Argentina","LandBounderies",["Bolivia","Brazil","Chile","Paraguay= +","Uruguay"]). +bgfact("Argentina","NaturalResources",["fertile plains of the = +pampas","lead","zinc","tin","copper","iron = +ore","manganese","petroleum","uranium"]). +bgfact("Argentina","Population",["33912994"]). +bgfact("Argentina","Capital",["Buenos Aires"]). +bgfact("Argentina","MemberOf",["AG","Australia = +Group","BCIE","CCC","ECLAC","FAO","G-6","G-11","G-15","G-19","G-24","AfDB= +","G-77","GATT","IADB","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IFAD","I= +FC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","ISO",= +"ITU","LAES","LAIA","LORCS","MERCOSUR","MINURSO","MTCR","OAS","PCA","RG",= +"UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNIKOM","UNOMOZ","UNOSOM","UNPROFO= +R","UNTAC","UNTSO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Argentina","ExportCommodities",["meat","wheat","corn","oilseed","= +hides","wool"]). +bgfact("Argentina","ExportPartners",["US","Brazil","Italy","Japan","Nethe= +rlands"]). +bgfact("Argentina","ImportCommodities",["machinery and = +equipment","chemicals","metals","fuels and lubricants","agricultural = +products"]). +bgfact("Argentina","ImportPartners",["US","Brazil","Germany","Bolivia","J= +apan","Italy","Netherlands"]). +bgfact("Argentina","Industries",["food processing","motor = +vehicles","consumer durables","textiles","chemicals and = +petrochemicals","printing","metallurgy","steel"]). +bgfact("Argentina","Agriculture",["principal = +wheat","corn","sorghum","soybeans","sugar beets"]). +bgfact("Armenia","LandBounderies",["Azerbaijan","Georgia","Iran","Turkey"= +]). +bgfact("Armenia","NaturalResources",["small deposits of = +gold","copper","molybdenum","zinc","alumina"]). +bgfact("Armenia","Population",["3521517"]). +bgfact("Armenia","Capital",["Yerevan"]). +bgfact("Armenia","MemberOf",["BSEC","CCC","CIS","CSCE","EBRD","ECE","IAEA= +","IBRD","ICAO","IDA","IFAD","ILO","IMF","INTELSAT","INTERPOL","IOC","ITU= +","NACC","NAM","UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]).= + +bgfact("Armenia","ExportCommodities",["machinery and transport = +equipment","light industrial products","processed food items","alcoholic = +products"]). +bgfact("Armenia","ExportPartners",["NA"]). +bgfact("Armenia","ImportCommodities",["grain","fuel"]). +bgfact("Armenia","ImportPartners",["Russia","US","EC"]). +bgfact("Armenia","Industries",["traditionally diverse","currently","much = +of industry is shut down"]). +bgfact("Armenia","Agriculture",["fruits and vegetable farming"]). +bgfact("Aruba","LandBounderies",[]). +bgfact("Aruba","NaturalResources",["white sandy beaches"]). +bgfact("Aruba","Population",["65545"]). +bgfact("Aruba","Capital",["Oranjestad"]). +bgfact("Aruba","ExportCommodities",["mostly petroleum products"]). +bgfact("Aruba","ExportPartners",["US","EC"]). +bgfact("Aruba","ImportCommodities",["food","consumer = +goods","manubgfactures","petroleum products"]). +bgfact("Aruba","ImportPartners",["US","EC"]). +bgfact("Aruba","Industries",["tourism","transshipment facilities","oil = +refining"]). +bgfact("Aruba","Agriculture",["poor quality soils and low rainfall limit = +agricultural activity to the cultivation of aloes","some livestock"]). +bgfact("Ashmore and Cartier Islands","LandBounderies",[]). +bgfact("Ashmore and Cartier Islands","NaturalResources",["fish"]). +bgfact("Ashmore and Cartier Islands","Capital",["none; administered from = +Canberra, Australia"]). +bgfact("Atlantic Ocean","NaturalResources",["oil and gas = +fields","fish","marine mammals","sand and gravel aggregates","placer = +deposits","polymetallic nodules","precious stones"]). +bgfact("Australia","LandBounderies",[]). +bgfact("Australia","NaturalResources",["bauxite","coal","iron = +ore","copper","tin","silver","uranium","nickel","tungsten","mineral = +sands","lead","zinc","diamonds","natural gas","petroleum"]). +bgfact("Australia","Population",["18077419"]). +bgfact("Australia","Capital",["Canberra"]). +bgfact("Australia","MemberOf",["AfDB","AG","NEA","NSG","OECD","PCA","SPAR= +TECA","SPC","SPF","UN","UNCTAD","UNESCO","UNFICYP","UNHCR","UNIDO","UNOSO= +M","UNPROFOR","UNTAC","UNTSO","UPU","WFTU","WHO","WIPO","WMO","ZC"]). +bgfact("Australia","ExportCommodities",["coal","gold","meat","wool","alum= +ina","wheat","machinery and transport equipment"]). +bgfact("Australia","ExportPartners",["Japan","US","South = +Korea","NZ","UK","Taiwan","Singapore","Hong Kong"]). +bgfact("Australia","ImportCommodities",["machinery and transport = +equipment","computers and office machines","crude and petroleum = +products"]). +bgfact("Australia","ImportPartners",["US","Japan","UK","Germany","NZ"]). +bgfact("Australia","Industries",["mining","industrial and transportation = +equipment","food processing","chemicals","steel"]). +bgfact("Australia","Agriculture",["world's largest exporter of beef and = +wool","second-largest for mutton","major = +wheat","barley","sugarcane","livestock - cattle","sheep","poultry"]). +bgfact("Austria","LandBounderies",["Czech = +Republic","Germany","Hungary","Italy","Liechtenstein","Slovakia","Sloveni= +a","Switzerland"]). +bgfact("Austria","NaturalResources",["iron = +ore","petroleum","timber","magnesite","aluminum","lead","coal","lignite",= +"copper","hydropower"]). +bgfact("Austria","Population",["7954974"]). +bgfact("Austria","Capital",["Vienna"]). +bgfact("Austria","MemberOf",["AfDB","AG","OECD","ONUSAL","PCA","UN","UNCT= +AD","UNESCO","UNDOF","UNFICYP","UNHCR","UNIDO","UNIKOM","UNOMIG","UNTAC",= +"UNTSO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Austria","ExportCommodities",["machinery and equipment","iron = +and steel","lumber","textiles","paper products","chemicals"]). +bgfact("Austria","ExportPartners",["EC"]). +bgfact("Austria","ImportCommodities",["petroleum","foodstuffs","machinery= + and equipment","vehicles","chemicals","textiles and = +clothing","pharmaceuticals"]). +bgfact("Austria","ImportPartners",["EC"]). +bgfact("Austria","Industries",["foods","iron","steel","machines","textile= +s","chemicals","electrical","paper and pulp","tourism","mining","motor = +vehicles"]). +bgfact("Austria","Agriculture",["grains","fruit","potatoes","sugar = +beets","sawn wood","cattle","pigs","-90% self-sufficient in food"]). +bgfact("Azerbaijan","LandBounderies",["Armenia","Russia","Turkey"]). +bgfact("Azerbaijan","NaturalResources",["petroleum","natural gas","iron = +ore","nonferrous metals","alumina"]). +bgfact("Azerbaijan","Population",["7684456"]). +bgfact("Azerbaijan","Capital",["Baku"]). +bgfact("Azerbaijan","MemberOf",["BSEC","CCC","CIS","CSCE","EBRD","ECE","E= +CO","ESCAP","IBRD","ICAO","IDB","ILO","IMF","INTELSAT","INTERPOL","IOC","= +ITU","NACC","OIC","UN","UNCTAD","UNESCO","UPU","WHO"]). +bgfact("Azerbaijan","ExportCommodities",["oil","gas","chemicals","oilfiel= +d equipment","textiles","cotton"]). +bgfact("Azerbaijan","ExportPartners",["mostly CIS and European = +countries"]). +bgfact("Azerbaijan","ImportCommodities",["machinery and parts","consumer = +durables","foodstuffs","textiles"]). +bgfact("Azerbaijan","ImportPartners",["European countries"]). +bgfact("Azerbaijan","Industries",["petroleum","natural gas","petroleum = +products","steel","iron ore","textiles"]). +bgfact("The Bahamas","LandBounderies",[]). +bgfact("The Bahamas","NaturalResources",["salt","aragonite","timber"]). +bgfact("The Bahamas","Population",["273055"]). +bgfact("The Bahamas","Capital",["Nassau"]). +bgfact("The = +Bahamas","MemberOf",["ACP","C","CCC","CARICOM","CDB","ECLAC","FAO","G-77"= +,"IADB","IBRD","ICAO","ICFTU","IFC","ILO","IMF","IMO","INTELSAT","INTERPO= +L","IOC","ITU","LORCS","NAM","OAS","OPANAL","UN","UNCTAD","UNESCO","UNIDO= +","UPU","WHO","WIPO","WMO"]). +bgfact("The = +Bahamas","ExportCommodities",["pharmaceuticals","cement","rum","crawfish"= +]). +bgfact("The = +Bahamas","ExportPartners",["US","UK","Norway","France","Italy"]). +bgfact("The Bahamas","ImportCommodities",["foodstuffs","manubgfactured = +goods","mineral fuels","crude"]). +bgfact("The = +Bahamas","ImportPartners",["US","Japan","Nigeria","Denmark","Norway"]). +bgfact("The Bahamas","Industries",["tourism","banking","cement","oil = +refining and transshipment","salt = +production","rum","aragonite","pharmaceuticals","spiral welded steel = +pipe"]). +bgfact("The Bahamas","Agriculture",["citrus","vegetables","large net = +importer of food"]). +bgfact("Bahrain","LandBounderies",[]). +bgfact("Bahrain","NaturalResources",["oil","associated and nonassociated = +natural gas","fish"]). +bgfact("Bahrain","Population",["585683"]). +bgfact("Bahrain","Capital",["Manama"]). +bgfact("Bahrain","MemberOf",["ABEDA","AFESD","AL","AMF","ESCWA","FAO","G-= +77","GATT","GCC","IBRD","ICAO","IDB","ILO","IMF","IMO","INMARSAT","INTELS= +AT","ITU","LORCS","NAM","OAPEC","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU= +","WFTU","WHO","WMO"]). +bgfact("Bahrain","ExportCommodities",["petroleum and petroleum = +products","aluminum"]). +bgfact("Bahrain","ExportPartners",["Japan","UAE","India","Pakistan","Sing= +apore"]). +bgfact("Bahrain","ImportCommodities",["nonoil","crude"]). +bgfact("Bahrain","ImportPartners",["Saudi = +Arabia","US","UK","Japan","Germany"]). +bgfact("Bahrain","Industries",["petroleum processing and = +refining","aluminum smelting","offshore banking","ship repairing"]). +bgfact("Bahrain","Agriculture",["including fishing","heavily subsidized = +sector produces fruit","vegetables","poultry","dairy = +products","shrimp","fish"]). +bgfact("Baker Island","LandBounderies",[]). +bgfact("Baker Island","Population",["1942"]). +bgfact("Baker Island","Capital",["none; administered from Washington, = +DC"]). +bgfact("Bangladesh","LandBounderies",["Burma","India"]). +bgfact("Bangladesh","NaturalResources",["natural gas","arable = +land","timber"]). +bgfact("Bangladesh","Population",["125149469"]). +bgfact("Bangladesh","Capital",["Dhaka"]). +bgfact("Bangladesh","MemberOf",["AsDB","C","CCC","CP","ESCAP","FAO","G-77= +","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","IFC","ILO","IMF= +","IMO","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","MINURSO","= +NAM","OIC","SAARC","UN","UNCTAD","UNESCO","UNIDO","UNIKOM","UNOMIG","UNOM= +OZ","UNOMUR","UNOSOM","UNPROFOR","UNTAC","UPU","WCL","WHO","WFTU","WIPO",= +"WMO","WTO"]). +bgfact("Bangladesh","ExportCommodities",["garments","jute and jute = +goods","leather","shrimp"]). +bgfact("Bangladesh","ExportPartners",["US","Western Europe"]). +bgfact("Bangladesh","ImportCommodities",["Capital = +goods","petroleum","food","textiles"]). +bgfact("Bangladesh","ImportPartners",["Hong = +Kong","Singapore","China","Japan"]). +bgfact("Bangladesh","Industries",["jute manubgfacturing","cotton = +textiles","food processing","steel","fertilizer"]). +bgfact("Bangladesh","Agriculture",["accounts for of GDP","of = +employment","commercial = +jute","rice","wheat","tea","sugarcane","potatoes","beef","milk","shortage= +s include wheat","vegetable oils","cotton"]). +bgfact("Barbados","LandBounderies",[]). +bgfact("Barbados","NaturalResources",["petroleum","fishing","natural = +gas"]). +bgfact("Barbados","Population",["255827"]). +bgfact("Barbados","Capital",["Bridgetown"]). +bgfact("Barbados","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-= +77","GATT","IADB","IBRD","ICAO","ICFTU","IFAD","IFC","ILO","IMF","IMO","I= +NTELSAT","INTERPOL","IOC","ISO","ITU","LAES","LORCS","NAM","OAS","OPANAL"= +,"UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Barbados","ExportCommodities",["sugar and = +molasses","rum","chemicals","electrical components","clothing"]). +bgfact("Barbados","ExportPartners",["US","UK","Trinidad and = +Tobago","Windward Islands"]). +bgfact("Barbados","ImportCommodities",["machinery","foodstuffs","construc= +tion materials","chemicals","fuel","electrical components"]). +bgfact("Barbados","ImportPartners",["US","UK","Trinidad and = +Tobago","Japan"]). +bgfact("Barbados","Industries",["tourism","sugar","light = +manubgfacturing","component assembly for export","petroleum"]). +bgfact("Barbados","Agriculture",["not self-sufficient in food"]). +bgfact("Bassas da India","LandBounderies",[]). +bgfact("Bassas da India","NaturalResources",["none"]). +bgfact("Bassas da India","Capital",["none; administered by France from = +Reunion"]). +bgfact("Belarus","LandBounderies",["Latvia","Lithuania","Poland","Russia"= +,"Ukraine"]). +bgfact("Belarus","NaturalResources",["forest land","peat deposits"]). +bgfact("Belarus","Population",["10404862"]). +bgfact("Belarus","Capital",["Minsk"]). +bgfact("Belarus","MemberOf",["CBSS","IOC","ITU","NACC","PCA","UN","UNCTAD= +","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Belarus","ExportCommodities",["machinery and transport = +equipment","chemicals","foodstuffs"]). +bgfact("Belarus","ExportPartners",["Russia","Ukraine","Poland","Bulgaria"= +]). +bgfact("Belarus","ImportCommodities",["fuel","industrial raw = +materials","textiles","sugar"]). +bgfact("Belarus","ImportPartners",["Russia","Ukraine","Poland"]). +bgfact("Belarus","Industries",[]). +bgfact("Belarus","Agriculture",["net exporter of = +meat","milk","eggs","flour","potatoes"]). +bgfact("Belgium","LandBounderies",["France","Germany","Luxembourg","Nethe= +rlands"]). +bgfact("Belgium","NaturalResources",["coal","natural gas"]). +bgfact("Belgium","Population",["10062836"]). +bgfact("Belgium","Capital",["Brussels"]). +bgfact("Belgium","MemberOf",["AG","OECD","PCA","UN","UNCTAD","UNESCO","UN= +HCR","UNIDO","UNMOGIP","UNOSOM","UNPROFOR","UNRWA","UNTAC","UNTSO","UPU",= +"WCL","WEU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Belgium","ExportCommodities",["iron and steel","transportation = +equipment","tractors","diamonds","petroleum products"]). +bgfact("Belgium","ExportPartners",["EC","US","former Communist = +countries"]). +bgfact("Belgium","ImportCommodities",["fuels","grains","chemicals","foods= +tuffs"]). +bgfact("Belgium","ImportPartners",["EC","US","oil-exporting less = +developed countries","former Communist countries"]). +bgfact("Belgium","Industries",["engineering and metal products","motor = +vehicle assembly","processed food and beverages","chemicals","basic = +metals","textiles","glass","petroleum","coal"]). +bgfact("Belgium","Agriculture",["emphasis on livestock production - = +beef","veal","pork","major crops are sugar beets","fresh = +vegetables","fruits","grain","net importer of farm products"]). +bgfact("Belize","LandBounderies",["Guatemala","Mexico"]). +bgfact("Belize","NaturalResources",["arable land = +potential","timber","fish"]). +bgfact("Belize","Population",["208949"]). +bgfact("Belize","Capital",["Belmopan"]). +bgfact("Belize","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-77= +","GATT","IADB","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO= +","INTELSAT","ITU","LAES","LORCS","NAM","OAS","UN","UNCTAD","UNESCO","UNI= +DO","UPU","WCL","WHO","WMO"]). +bgfact("Belize","ExportCommodities",["sugar","citrus","clothing","fish = +products","bananas","molasses","wood"]). +bgfact("Belize","ExportPartners",["US","UK"]). +bgfact("Belize","ImportCommodities",["machinery and transportation = +equipment","food","manubgfactured = +goods","fuels","chemicals","pharmaceuticals"]). +bgfact("Belize","ImportPartners",["US","UK","Mexico"]). +bgfact("Belize","Industries",["garment production","citrus = +concentrates","sugar refining","rum","beverages","tourism"]). +bgfact("Belize","Agriculture",["commercial crops include sugar = +cane","bananas","coca","net importer of basic foods"]). +bgfact("Benin","LandBounderies",["Burkina","Niger","Nigeria","Togo"]). +bgfact("Benin","NaturalResources",["small offshore oil = +deposits","limestone","marble","timber"]). +bgfact("Benin","Population",["5341710"]). +bgfact("Benin","Capital",["Porto-Novo"]). +bgfact("Benin","MemberOf",["ACCT","ACP","AfDB","CEAO","ECA","ECOWAS","Ent= +ente","FAO","FZ","G-77","GATT","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","= +IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","O= +AU","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL","WFTU","WHO",= +"WIPO","WMO","WTO"]). +bgfact("Benin","ExportCommodities",["crude","cotton","palm = +products","cocoa"]). +bgfact("Benin","ExportPartners",["FRG","France","Spain","Italy","UK"]). +bgfact("Benin","ImportCommodities",["foodstuffs","beverages","tobacco","p= +etroleum products","intermediate goods","Capital goods","light = +consumer goods"]). +bgfact("Benin","ImportPartners",["France","Thailand","Netherlands","US"])= +. +bgfact("Benin","Industries",["textiles","cigarettes","construction = +materials","beverages","food production","petroleum"]). +bgfact("Benin","Agriculture",["production is dominated by food = +corn","sorghum","cassava","beans","crops include cotton","palm = +oil","poultry and livestock output has not kept up with consumption"]). +bgfact("Bermuda","LandBounderies",[]). +bgfact("Bermuda","NaturalResources",["limestone","pleasant climate = +fostering tourism"]). +bgfact("Bermuda","Population",["61158"]). +bgfact("Bermuda","Capital",["Hamilton"]). +bgfact("Bermuda","MemberOf",["CARICOM","IOC"]). +bgfact("Bermuda","ExportCommodities",["semitropical produce","light = +manubgfactures","re-exports of pharmaceuticals"]). +bgfact("Bermuda","ExportPartners",["US","UK","Canada"]). +bgfact("Bermuda","ImportCommodities",["fuel","foodstuffs","machinery"]). +bgfact("Bermuda","ImportPartners",["US","UK","Venezuela","Canada","Japan"= +]). +bgfact("Bermuda","Industries",["tourism","finance","structural concrete = +products","paints","pharmaceuticals","ship repairing"]). +bgfact("Bermuda","Agriculture",["produces bananas","vegetables","citrus = +fruits","flowers","dairy products"]). +bgfact("Bhutan","LandBounderies",["China","India"]). +bgfact("Bhutan","NaturalResources",["timber","hydropower","gypsum","calci= +um carbide"]). +bgfact("Bhutan","Population",["716380"]). +bgfact("Bhutan","Capital",["Thimphu"]). +bgfact("Bhutan","MemberOf",["AsDB","CP","ESCAP","FAO","G-77","IBRD","ICAO= +","IDA","IFAD","IMF","INTELSAT","IOC","ITU","NAM","SAARC","UN","UNCTAD","= +UNESCO","UNIDO","UPU","WHO"]). +bgfact("Bhutan","ExportCommodities",["cardamon","gypsum","timber","handic= +rafts","cement","fruit","electricity","precious stones","spices"]). +bgfact("Bhutan","ExportPartners",["India","Bangladesh","Singapore"]). +bgfact("Bhutan","ImportCommodities",["fuel and = +lubricants","grain","machinery and parts","vehicles","fabrics"]). +bgfact("Bhutan","ImportPartners",["India","Japan","Germany","US","UK"]). +bgfact("Bhutan","Industries",["cement","wood products","processed = +fruits","alcoholic beverages","calcium carbide"]). +bgfact("Bhutan","Agriculture",["corn","root crops","citrus fruit","dairy = +products","eggs"]). +bgfact("Bolivia","LandBounderies",["Argentina","Brazil","Chile","Paraguay= +","Peru"]). +bgfact("Bolivia","NaturalResources",["tin","natural = +gas","petroleum","zinc","tungsten","antimony","silver","iron = +ore","lead","gold","timber"]). +bgfact("Bolivia","Population",["7719445"]). +bgfact("Bolivia","Capital",["La Paz"]). +bgfact("Bolivia","MemberOf",["AG","ECLAC","FAO","GATT","G-11","G-77","IAD= +B","IAEA","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","= +INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS","NAM","OAS","OPANAL","P= +CA","RG","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","= +WMO","WTO"]). +bgfact("Bolivia","ExportCommodities",["metals","natural gas"]). +bgfact("Bolivia","ExportPartners",["US","Argentina"]). +bgfact("Bolivia","ImportCommodities",["food","petroleum","consumer = +goods","Capital goods"]). +bgfact("Bolivia","ImportPartners",["US"]). +bgfact("Bolivia","Industries",["mining","smelting","petroleum","food and = +beverage","tobacco","handicrafts","illicit drug industry reportedly = +produces of its revenues"]). +bgfact("Bolivia","Agriculture",["principal commodities - = +coffee","coca","cotton","corn","sugarcane","rice","potatoes","self-suffic= +ient in food"]). +bgfact("Bosnia and Herzegovina","LandBounderies",["Croatia","Serbia and = +Montenegro"]). +bgfact("Bosnia and = +Herzegovina","NaturalResources",["coal","iron","bauxite","manganese","tim= +ber","wood products","copper","chromium","lead","zinc"]). +bgfact("Bosnia and Herzegovina","Population",["4651485"]). +bgfact("Bosnia and Herzegovina","Capital",["Sarajevo"]). +bgfact("Bosnia and = +Herzegovina","MemberOf",["CEI","CSCE","ECE","ICAO","ILO","IMO","INTELSAT"= +,"UN","UNCTAD","UNESCO","UNIDO","UPU","WHO"]). +bgfact("Bosnia and Herzegovina","ExportCommodities",["NA"]). +bgfact("Bosnia and Herzegovina","ExportPartners",["NA"]). +bgfact("Bosnia and Herzegovina","ImportCommodities",["NA"]). +bgfact("Bosnia and Herzegovina","ImportPartners",["NA"]). +bgfact("Bosnia and Herzegovina","Industries",["steel = +production","mining"]). +bgfact("Bosnia and Herzegovina","Agriculture",["the foothills of = +northern Bosnia support orchards","vineyards","livestock","farms are = +mostly privately held","small"]). +bgfact("Botswana","LandBounderies",["Namibia","South = +Africa","Zimbabwe"]). +bgfact("Botswana","NaturalResources",["diamonds","copper","nickel","salt"= +,"soda ash","potash","coal","iron ore","silver"]). +bgfact("Botswana","Population",["1359352"]). +bgfact("Botswana","Capital",["Gaborone"]). +bgfact("Botswana","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","FLS","G= +-77","GATT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","INTELSA= +T","INTERPOL","IOC","ITU","LORCS","NAM","OAU","SACU","SADC","UN","UNCTAD"= +,"UNESCO","UNIDO","UNOMOZ","UNOMUR","UNOSOM","UPU","WCL","WHO","WMO"]). +bgfact("Botswana","ExportCommodities",["diamonds","copper and = +nickel","meat"]). +bgfact("Botswana","ExportPartners",["Switzerland","UK","SACU"]). +bgfact("Botswana","ImportCommodities",["foodstuffs","vehicles and = +transport equipment","textiles","petroleum products"]). +bgfact("Botswana","ImportPartners",["Switzerland","SACU","UK","US"]). +bgfact("Botswana","Industries",["mining of = +diamonds","copper","nickel","coal","salt","soda ash","livestock = +processing"]). +bgfact("Botswana","Agriculture",["must import up to of of food = +needs"]). +bgfact("Bouvet Island","LandBounderies",[]). +bgfact("Bouvet Island","NaturalResources",["none"]). +bgfact("Bouvet Island","Capital",["none; administered from Oslo, = +Norway"]). +bgfact("Brazil","LandBounderies",["Argentina","Bolivia","Colombia","Frenc= +h Guiana","Guyana","Paraguay","Peru","Suriname","Uruguay","Venezuela"]). +bgfact("Brazil","NaturalResources",["iron = +ore","manganese","bauxite","nickel","uranium","phosphates","tin","hydropo= +wer","gold","platinum","petroleum","timber"]). +bgfact("Brazil","Population",["158739257"]). +bgfact("Brazil","Capital",["Brasilia"]). +bgfact("Brazil","MemberOf",["AfDB","AG","OAS","ONUSAL","OPANAL","PCA","RG= +","UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNOMOZ","UNOMUR","UNPROFOR","UPU",= +"WCL","WHO","WFTU","WIPO","WMO","WTO"]). +bgfact("Brazil","ExportCommodities",["iron ore","soybean bran","orange = +juice","footwear","coffee","motor vehicle parts"]). +bgfact("Brazil","ExportPartners",["EC","Latin America","US","Japan"]). +bgfact("Brazil","ImportCommodities",["crude","Capital goods","chemical = +products","foodstuffs","coal"]). +bgfact("Brazil","ImportPartners",["US","EC","Middle East","Latin = +America","Japan"]). +bgfact("Brazil","Industries",["shoes","chemicals","cement","lumber","iron= + ore","steel","motor vehicles and auto parts","metalworking","Capital = +goods","tin"]). +bgfact("Brazil","Agriculture",["corn","sugarcane","cocoa","self-sufficien= +t in food","except for wheat"]). +bgfact("British Indian Ocean Territory","LandBounderies",[]). +bgfact("British Indian Ocean = +Territory","NaturalResources",["coconuts","fish"]). +bgfact("British Indian Ocean Territory","Capital",["none"]). +bgfact("British Virgin Islands","LandBounderies",[]). +bgfact("British Virgin Islands","NaturalResources",["negligible"]). +bgfact("British Virgin Islands","Population",["12864"]). +bgfact("British Virgin Islands","Capital",["Road Town"]). +bgfact("British Virgin Islands","MemberOf",["CARICOM"]). +bgfact("British Virgin Islands","ExportCommodities",["rum","fresh = +fish","gravel","sand","fruits","animals"]). +bgfact("British Virgin Islands","ExportPartners",["Virgin = +Islands","Puerto Rico","US"]). +bgfact("British Virgin Islands","ImportCommodities",["building = +materials","automobiles","foodstuffs","machinery"]). +bgfact("British Virgin Islands","ImportPartners",["Virgin = +Islands","Puerto Rico","US"]). +bgfact("British Virgin Islands","Industries",["tourism","light = +industry","construction","rum","concrete block","offshore financial = +center"]). +bgfact("British Virgin = +Islands","Agriculture",["livestock","fish","fruit","vegetables"]). +bgfact("Brunei","LandBounderies",["Malysia"]). +bgfact("Brunei","NaturalResources",["petroleum","natural = +gas","timber"]). +bgfact("Brunei","Population",["284653"]). +bgfact("Brunei","Capital",["Bandar Seri Begawan"]). +bgfact("Brunei","MemberOf",["APEC","ASEAN","C","ESCAP","FAO","G-77","GATT= +","ICAO","IDB","IMO","INTELSAT","ITU","NAM","OIC","UN","UNCTAD","UPU","UN= +TAC","WHO","WMO"]). +bgfact("Brunei","ExportCommodities",["crude","liquefied natural = +gas","petroleum products"]). +bgfact("Brunei","ExportPartners",["Japan","UK","South = +Korea","Thailand","Singapore"]). +bgfact("Brunei","ImportCommodities",["machinery and transport = +equipment","manubgfactured goods","food","chemicals"]). +bgfact("Brunei","ImportPartners",["Singapore","UK","Switzerland","US","Ja= +pan"]). +bgfact("Brunei","Industries",["petroleum","petroleum = +refining","liquefied natural gas","construction"]). +bgfact("Brunei","Agriculture",["principal crops and livestock include = +rice","cassava","bananas","buffaloes"]). +bgfact("Bulgaria","LandBounderies",["Greece","The Former Yugoslav = +Republic of Macedonia","Romania","Serbia and Montenegro","Turkey"]). +bgfact("Bulgaria","NaturalResources",["bauxite","copper","lead","zinc","c= +oal","timber","arable land"]). +bgfact("Bulgaria","Population",["8799986"]). +bgfact("Bulgaria","Capital",["Sofia"]). +bgfact("Bulgaria","MemberOf",["ACCT","NSG","PCA","UN","UNCTAD","UNESCO","= +UNIDO","UNTAC","UPU","WFTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Bulgaria","ExportCommodities",["fuels","minerals","raw = +materials"]). +bgfact("Bulgaria","ExportPartners",["former CEMA countries"]). +bgfact("Bulgaria","ImportCommodities",["fuels","minerals"]). +bgfact("Bulgaria","ImportPartners",["former CEMA countries"]). +bgfact("Bulgaria","Industries",["machine building and metal = +working","food processing","chemicals","textiles","building = +materials","ferrous and nonferrous metals"]). +bgfact("Bulgaria","Agriculture",["climate and soil conditions support = +livestock raising and the growing of various grain = +crops","oilseeds","vegetables","fruits","surplus food producer"]). +bgfact("Burkina","LandBounderies",["Benin","Ghana","Cote = +d'Ivoire","Mali","Niger","Togo"]). +bgfact("Burkina","NaturalResources",["manganese","limestone","small = +deposits of = +gold","antimony","copper","nickel","bauxite","lead","phosphates","zinc","= +silver"]). +bgfact("Burkina","Population",["10134661"]). +bgfact("Burkina","Capital",["Ouagadougou"]). +bgfact("Burkina","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOW= +AS","Entente","FAO","FZ","G-77","GATT","IBRD","ICAO","ICC","ICFTU","IDA",= +"IDB","IFAD","IFC","ILO","IMF","INTELSAT","INTERPOL","IOC","ITU","LORCS",= +"NAM","OAU","OIC","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL"= +,"WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Burkina","ExportCommodities",["cotton","gold","animal = +products"]). +bgfact("Burkina","ExportPartners",["EC","Cote d'Ivoire","Taiwan"]). +bgfact("Burkina","ImportCommodities",["machinery","food = +products","petroleum"]). +bgfact("Burkina","ImportPartners",["EC","Africa","Japan"]). +bgfact("Burkina","Industries",["cotton lint","beverages","agricultural = +processing","soap","cigarettes","textiles","gold mining and = +extraction"]). +bgfact("Burkina","Agriculture",["peanuts","shea nuts","sesame","food = +sorghum","millet","corn","not self-sufficient in food grains"]). +bgfact("Burma","LandBounderies",["Bangladesh","China","India","Laos","Tha= +iland"]). +bgfact("Burma","NaturalResources",["petroleum","timber","tin","antimony",= +"zinc","copper","tungsten","lead","coal","some = +marble","limestone","precious stones","natural gas"]). +bgfact("Burma","Population",["44277014"]). +bgfact("Burma","Capital",["Rangoon"]). +bgfact("Burma","MemberOf",["AsDB","CCC","CP","ESCAP","FAO","G-77","GATT",= +"IAEA","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INT= +ERPOL","IOC","ITU","LORCS","NAM","UN","UNCTAD","UNESCO","UNIDO","UPU","WH= +O","WMO"]). +bgfact("Burma","ExportCommodities",["pulses and = +beans","teak","rice","hardwood"]). +bgfact("Burma","ExportPartners",["Singapore","China","Thailand","India","= +Hong Kong"]). +bgfact("Burma","ImportCommodities",["machinery","transport = +equipment","chemicals","food products"]). +bgfact("Burma","ImportPartners",["Japan","China","Thailand","Singapore","= +Malaysia"]). +bgfact("Burma","Industries",["mining of = +copper","tin","tungsten","fertilizer"]). +bgfact("Burma","Agriculture",["principal paddy = +rice","corn","oilseed","sugarcane","rice and timber account for of = +export revenues"]). +bgfact("Burundi","LandBounderies",["Rwanda","Tanzania","Zaire"]). +bgfact("Burundi","NaturalResources",["nickel","uranium","rare earth = +oxide","peat","cobalt","copper","platinum","vanadium"]). +bgfact("Burundi","Population",["6124747"]). +bgfact("Burundi","Capital",["Bujumbura"]). +bgfact("Burundi","MemberOf",["ACCT","ACP","AfDB","CCC","CEEAC","CEPGL","E= +CA","FAO","G-77","GATT","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","INT= +ELSAT","INTERPOL","ITU","LORCS","NAM","OAU","UN","UNCTAD","UNESCO","UNIDO= +","UPU","WHO","WIPO","WMO","WTO"]). +bgfact("Burundi","ExportCommodities",["coffee","tea","cotton","hides"]). +bgfact("Burundi","ExportPartners",["EC","US","Asia"]). +bgfact("Burundi","ImportCommodities",["Capital goods","petroleum = +products","foodstuffs","consumer goods"]). +bgfact("Burundi","ImportPartners",["EC","Asia","US"]). +bgfact("Burundi","Industries",["light consumer goods such as = +blankets","shoes","food processing"]). +bgfact("Burundi","Agriculture",["coffee","cotton","food = +corn","sorghum","sweet potatoes","bananas","livestock - = +meat","milk","hides and skins"]). +bgfact("Cambodia","LandBounderies",["Laos","Thailand","Vietnam"]). +bgfact("Cambodia","NaturalResources",["timber","gemstones","some iron = +ore","manganese","phosphates","hydropower potential"]). +bgfact("Cambodia","Population",["10264628"]). +bgfact("Cambodia","Capital",["Phnom Penh"]). +bgfact("Cambodia","MemberOf",["ACCT","INTERPOL","ITU","LORCS","NAM","PCA"= +,"UN","UNCTAD","UNESCO","UPU","WFTU","WHO","WMO","WTO"]). +bgfact("Cambodia","ExportCommodities",["natural = +rubber","rice","pepper","raw timber"]). +bgfact("Cambodia","ExportPartners",["Thailand","Japan","India","Singapore= +","Malaysia","China","Vietnam"]). +bgfact("Cambodia","ImportCommodities",["fuels","consumer = +goods","machinery"]). +bgfact("Cambodia","ImportPartners",["Japan","India","Singapore","Malaysia= +","Thailand","China","Vietnam"]). +bgfact("Cambodia","Industries",["rice milling","fishing","wood and wood = +products","rubber","cement","gem mining"]). +bgfact("Cambodia","Agriculture",["main rice","rubber","food shortages - = +rice","meat","vegetables","dairy products","sugar","flour"]). +bgfact("Cameroon","LandBounderies",["Central African = +Republic","Chad","Congo","Equatorial Guinea","Gabon","Nigeria"]). +bgfact("Cameroon","NaturalResources",["petroleum","bauxite","iron = +ore","timber","hydropower potential"]). +bgfact("Cameroon","Population",["13132191"]). +bgfact("Cameroon","Capital",["Yaounde"]). +bgfact("Cameroon","MemberOf",["ACCT","ACP","AfDB","BDEAC","CCC","CEEAC","= +ECA","FAO","FZ","G-19","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","= +IDA","IDB","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL= +","IOC","ITU","LORCS","NAM","OAU","OIC","PCA","UDEAC","UN","UNCTAD","UNES= +CO","UNIDO","UNTAC","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Cameroon","ExportCommodities",["petroleum = +products","coffee","beans","cocoa","aluminum products","timber"]). +bgfact("Cameroon","ExportPartners",["EC about","US","African = +countries"]). +bgfact("Cameroon","ImportCommodities",["machines and electrical = +equipment","food","consumer goods","transport equipment"]). +bgfact("Cameroon","ImportPartners",["EC about","African = +countries","Japan","US"]). +bgfact("Cameroon","Industries",["petroleum production and = +refining","food processing","light consumer = +goods","textiles","sawmills"]). +bgfact("Cameroon","Agriculture",["the Agriculture and forestry sectors = +provide employment for the majority of the Population","commercial and = +food crops include = +coffee","cocoa","timber","cotton","rubber","bananas","oilseed","grains","= +livestock","root starches"]). +bgfact("Canada","LandBounderies",["US"]). +bgfact("Canada","NaturalResources",["nickel","zinc","copper","gold","lead= +","molybdenum","potash","silver","fish","timber","wildlife","coal","petro= +leum","natural gas"]). +bgfact("Canada","Population",["28113997"]). +bgfact("Canada","Capital",["Ottawa"]). +bgfact("Canada","MemberOf",["ACCT","AfDB","AG","NATO","NEA","NSG","OAS","= +OECD","ONUSAL","PCA","UN","UNAVEM = +II","UNCTAD","UNDOF","UNESCO","UNFICYP","UNHCR","UNIDO","UNIKOM","UNOMOZ"= +,"UNOMUR","UNPROFOR","UNTAC","UNTSO","UPU","WCL","WHO","WMO","WIPO","WTO"= +,"ZC"]). +bgfact("Canada","ExportCommodities",["newsprint","wood = +pulp","timber","crude petroleum","machinery","natural = +gas","aluminum","telecommunications equipment"]). +bgfact("Canada","ExportPartners",["US","Japan","UK","Germany","South = +Korea","Netherlands","China"]). +bgfact("Canada","ImportCommodities",["crude","chemicals","motor vehicles = +and parts","durable consumer goods","telecommunications equipment and = +parts"]). +bgfact("Canada","ImportPartners",["US","Japan","UK","Germany","France","M= +exico","Taiwan","South Korea"]). +bgfact("Canada","Industries",["processed and unprocessed minerals","food = +products","wood and paper products","transportation = +equipment","chemicals","fish products","petroleum and natural gas"]). +bgfact("Canada","Agriculture",["commercial fisheries provide annual = +catch of million metric tons","of which is exported"]). +bgfact("Cape Verde","LandBounderies",[]). +bgfact("Cape Verde","NaturalResources",["salt","basalt = +rock","pozzolana","limestone","kaolin","fish"]). +bgfact("Cape Verde","Population",["423120"]). +bgfact("Cape Verde","Capital",["Praia"]). +bgfact("Cape = +Verde","MemberOf",["ACP","AfDB","CCC","ECA","ECOWAS","FAO","G-77","IBRD",= +"ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL"= +,"IOM","UNCTAD","UNESCO","UNIDO","UNOMOZ","UPU","WCL","WHO","WMO"]). +bgfact("Cape Verde","ExportCommodities",["fish","bananas","hides and = +skins"]). +bgfact("Cape = +Verde","ExportPartners",["Portugal","Algeria","Angola","Netherlands"]). +bgfact("Cape Verde","ImportCommodities",["foodstuffs","consumer = +goods","industrial products","transport equipment"]). +bgfact("Cape = +Verde","ImportPartners",["Sweden","Spain","Germany","Portugal","France","= +Netherlands","US"]). +bgfact("Cape Verde","Industries",["fish processing","salt = +mining","clothing bgfactories","ship repair","construction = +materials","food and beverage production"]). +bgfact("Cape Verde","Agriculture",["beans","sweet potatoes","fish catch = +provides for both domestic consumption and small exports"]). +bgfact("Cayman Islands","LandBounderies",[]). +bgfact("Cayman Islands","NaturalResources",["fish","climate and beaches = +that foster tourism"]). +bgfact("Cayman Islands","Population",["31790"]). +bgfact("Cayman Islands","Capital",["George Town"]). +bgfact("Cayman Islands","MemberOf",["CARICOM","IOC"]). +bgfact("Cayman Islands","ExportCommodities",["turtle = +products","manubgfactured consumer goods"]). +bgfact("Cayman Islands","ExportPartners",["mostly US"]). +bgfact("Cayman = +Islands","ImportCommodities",["foodstuffs","manubgfactured goods"]). +bgfact("Cayman Islands","ImportPartners",["US","Trinidad and = +Tobago","UK","Netherlands Antilles","Japan"]). +bgfact("Cayman Islands","Industries",["tourism","banking","insurance and = +finance","construction","building materials","furniture making"]). +bgfact("Cayman Islands","Agriculture",["minor production of = +vegetables","fruit","turtle farming"]). +bgfact("Central African = +Republic","LandBounderies",["Cameroon","Chad","Congo","Sudan","Zaire"]). +bgfact("Central African = +Republic","NaturalResources",["diamonds","uranium","timber","gold","oil"]= +). +bgfact("Central African Republic","Population",["3142182"]). +bgfact("Central African Republic","Capital",["Bangui"]). +bgfact("Central African = +Republic","MemberOf",["ACCT","ACP","AfDB","BDEAC","CCC","CEEAC","ECA","FA= +O","FZ","G-77","GATT","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","INTEL= +SAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","UDEAC","UN","UNCTAD","UN= +ESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO"]). +bgfact("Central African = +Republic","ExportCommodities",["diamonds","cotton","coffee","timber","tob= +acco"]). +bgfact("Central African = +Republic","ExportPartners",["France","Belgium","Italy","Japan","US"]). +bgfact("Central African = +Republic","ImportCommodities",["food","textiles","petroleum = +products","machinery","electrical equipment","motor = +vehicles","chemicals","pharmaceuticals","consumer goods","industrial = +products"]). +bgfact("Central African = +Republic","ImportPartners",["France","Japan","Algeria"]). +bgfact("Central African Republic","Industries",["diamond = +mining","sawmills","breweries","textiles","footwear","assembly of = +bicycles and motorcycles"]). +bgfact("Central African Republic","Agriculture",["commercial = +cotton","coffee","tobacco","food crops - = +manioc","yams","millet","corn","bananas"]). +bgfact("Chad","LandBounderies",["Cameroon","Central African = +Republic","Libya","Niger","Nigeria","Sudan"]). +bgfact("Chad","NaturalResources",["petroleum"]). +bgfact("Chad","Population",["5466771"]). +bgfact("Chad","Capital",["N'Djamena"]). +bgfact("Chad","MemberOf",["ACCT","ACP","AfDB","BDEAC","CEEAC","ECA","FAO"= +,"FZ","G-77","GATT","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","ILO","IMF",= +"INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","OIC","UDEAC","UN",= +"UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Chad","ExportCommodities",["cotton","cattle","textiles","fish"]).= + +bgfact("Chad","ExportPartners",["France","Nigeria","Cameroon"]). +bgfact("Chad","ImportCommodities",["machinery and transportation = +equipment","industrial goods","petroleum products","note - excludes = +military equipment"]). +bgfact("Chad","ImportPartners",["US","France","Nigeria","Cameroon"]). +bgfact("Chad","Industries",["cotton textile = +mills","slaughterhouses","brewery","natron","soap","cigarettes"]). +bgfact("Chad","Agriculture",["food crops include = +sorghum","millet","peanuts","rice","potatoes","livestock - = +cattle","sheep","goats","self-sufficient in food in years of adequate = +rainfall"]). +bgfact("Chile","LandBounderies",["Argentina","Bolivia","Peru"]). +bgfact("Chile","NaturalResources",["copper","timber","iron = +ore","nitrates","precious metals","molybdenum"]). +bgfact("Chile","Population",["13950557"]). +bgfact("Chile","Capital",["Santiago"]). +bgfact("Chile","MemberOf",["CCC","ECLAC","FAO","G-11","G-77","GATT","IADB= +","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INMA= +RSAT","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LAES","LAIA","LORCS"= +,"NAM","OAS","ONUSAL","OPANAL","PCA","RG","UN","UNCTAD","UNESCO","UNIDO",= +"UNMOGIP","UNTAC","UNTSO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Chile","ExportCommodities",["copper","wood products","fish and = +fishmeal","fruits"]). +bgfact("Chile","ExportPartners",["EC","Japan","US","Argentina","Brazil"])= +. +bgfact("Chile","ImportCommodities",["Capital goods","spare parts","raw = +materials","petroleum","foodstuffs"]). +bgfact("Chile","ImportPartners",["EC","US","Brazil","Japan"]). +bgfact("Chile","Industries",["copper","foodstuffs","fish = +processing","iron and steel","wood and wood products","transport = +equipment","cement","textiles"]). +bgfact("Chile","Agriculture",["major exporter of fruit","fish","major = +wheat","corn","grapes","beans","sugar beets","potatoes","livestock = +beef","poultry","net agricultural importer"]). +bgfact("China","LandBounderies",["Afghanistan","Bhutan","Burma","Hong = +Kong","India","Kazakhstan","North = +Korea","Kyrgyzstan","Laos","Macau","Mongolia","Nepal","Pakistan","Russia"= +,"Tajikistan","Vietnam"]). +bgfact("China","NaturalResources",["coal","iron = +ore","petroleum","mercury","tin","tungsten","antimony","manganese","molyb= +denum","vanadium","magnetite","aluminum","lead","zinc","uranium","hydropo= +wer potential"]). +bgfact("China","Population",["1190431106"]). +bgfact("China","Capital",["Beijing"]). +bgfact("China","MemberOf",["AfDB","APEC","AsDB","CCC","ESCAP","FAO","IAEA= +","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INMARSAT","= +INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","MINURSO","NAM","PCA","UN"= +,"UNCTAD","UNESCO","UNHCR","UNIDO","UNIKOM","UN Security = +Council","UNTAC","UNTSO","UN Trusteeship = +Council","UPU","WHO","WIPO","WMO","WTO"]). +bgfact("China","ExportCommodities",["textiles","garments","footwear","toy= +s","crude"]). +bgfact("China","ExportPartners",["Hong = +Kong","US","Japan","Germany","South Korea","Russia"]). +bgfact("China","ImportCommodities",["rolled steel","motor = +vehicles","textile machinery","oil products"]). +bgfact("China","ImportPartners",["Japan","Taiwan","US","Hong = +Kong","Germany","South Korea"]). +bgfact("China","Industries",["iron and steel","coal","machine = +building","armaments","textiles","petroleum","cement","chemical = +fertilizers","consumer durables","food processing"]). +bgfact("China","Agriculture",["among the world's largest producers of = +rice","potatoes","sorghum","peanuts","tea","millet","barley","commercial = + crops include cotton","fish catch of million metric tons"]). +bgfact("Christmas Island","LandBounderies",[]). +bgfact("Christmas Island","NaturalResources",["phosphate"]). +bgfact("Christmas Island","Population",["973"]). +bgfact("Christmas Island","Capital",["The Settlement"]). +bgfact("Christmas Island","MemberOf",["none"]). +bgfact("Christmas Island","ExportCommodities",["phosphate"]). +bgfact("Christmas Island","ExportPartners",["Australia","NZ"]). +bgfact("Christmas Island","ImportCommodities",["consumer goods"]). +bgfact("Christmas Island","ImportPartners",["principally Australia"]). +bgfact("Christmas Island","Industries",["phosphate extraction"]). +bgfact("Christmas Island","Agriculture",["NA"]). +bgfact("Clipperton Island","LandBounderies",[]). +bgfact("Clipperton Island","NaturalResources",["none"]). +bgfact("Clipperton Island","Capital",["none; administered by France from = +French Polynesia"]). +bgfact("Cocos (Keeling) Islands","LandBounderies",[]). +bgfact("Cocos (Keeling) Islands","NaturalResources",["fish"]). +bgfact("Cocos (Keeling) Islands","Population",["598"]). +bgfact("Cocos (Keeling) Islands","Capital",["West Island"]). +bgfact("Cocos (Keeling) Islands","MemberOf",["none"]). +bgfact("Cocos (Keeling) Islands","ExportCommodities",["copra"]). +bgfact("Cocos (Keeling) Islands","ExportPartners",["Australia"]). +bgfact("Cocos (Keeling) Islands","ImportCommodities",["foodstuffs"]). +bgfact("Cocos (Keeling) Islands","ImportPartners",["Australia"]). +bgfact("Cocos (Keeling) Islands","Industries",["copra products"]). +bgfact("Cocos (Keeling) Islands","Agriculture",["gardens provide = +vegetables","bananas","pawpaws","coconuts"]). +bgfact("Colombia","LandBounderies",["Brazil","Ecuador","Panama","Peru","V= +enezuela"]). +bgfact("Colombia","NaturalResources",["petroleum","natural = +gas","coal","iron ore","nickel","gold","copper","emeralds"]). +bgfact("Colombia","Population",["35577556"]). +bgfact("Colombia","Capital",["Bogota"]). +bgfact("Colombia","MemberOf",["AG","CDB","CG","ECLAC","FAO","G-3","G-11",= +"G-24","G-77","GATT","IADB","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IFA= +D","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","= +ISO","ITU","LAES","LAIA","LORCS","NAM","OAS","ONUSAL","OPANAL","PCA","RG"= +,"UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNPROFOR","UNTAC","UPU","WCL","W= +FTU","WHO","WIPO","WMO","WTO"]). +bgfact("Colombia","ExportCommodities",["petroleum","coffee","coal","banan= +as","fresh cut flowers"]). +bgfact("Colombia","ExportPartners",["US","EC","Japan","Venezuela"]). +bgfact("Colombia","ImportCommodities",["industrial = +equipment","transportation equipment","consumer = +goods","chemicals","paper products"]). +bgfact("Colombia","ImportPartners",["US","EC","Brazil","Venezuela","Japan= +"]). +bgfact("Colombia","Industries",["textiles","food = +processing","oil","clothing and footwear","beverages","chemicals","metal = +products","mining - = +gold","coal","emeralds","iron","nickel","silver","salt"]). +bgfact("Colombia","Agriculture",["climate and soils permit a wide = +variety of crops","such as = +coffee","rice","tobacco","corn","sugarcane","cocoa = +beans","oilseeds","forest products and shrimp farming are becoming more = +important"]). +bgfact("Comoros","LandBounderies",[]). +bgfact("Comoros","NaturalResources",["negligible"]). +bgfact("Comoros","Population",["530136"]). +bgfact("Comoros","Capital",["Moroni"]). +bgfact("Comoros","MemberOf",["ACCT","ACP","AfDB","ECA","FAO","FZ","G-77",= +"IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","INTELSAT","ITU","NAM"= +,"OAU","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WMO"]). +bgfact("Comoros","ExportCommodities",["vanilla","cloves","perfume = +oil","copra","ylang-ylang"]). +bgfact("Comoros","ExportPartners",["US","France","Africa","FRG"]). +bgfact("Comoros","ImportCommodities",["cement","petroleum = +products","consumer goods"]). +bgfact("Comoros","ImportPartners",["Europe"]). +bgfact("Comoros","Industries",["perfume = +distillation","textiles","furniture","jewelry","construction = +materials","soft drinks"]). +bgfact("Comoros","Agriculture",["plantations produce crops for export - = +vanilla","cloves","perfume essences","principal food = +coconuts","bananas","large net food importer"]). +bgfact("Congo","LandBounderies",["Angola","Cameroon","Central African = +Republic","Gabon","Zaire"]). +bgfact("Congo","NaturalResources",["petroleum","timber","potash","lead","= +zinc","uranium","copper","phosphates","natural gas"]). +bgfact("Congo","Population",["2446902"]). +bgfact("Congo","Capital",["Brazzaville"]). +bgfact("Congo","MemberOf",["ACCT","ACP","AfDB","BDEAC","CCC","CEEAC","ECA= +","FAO","FZ","G-77","GATT","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","= +IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","UDEAC","UN","= +UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Congo","ExportCommodities",["crude","lumber","plywood","coffee","= +cocoa","sugar","diamonds"]). +bgfact("Congo","ExportPartners",["US","France"]). +bgfact("Congo","ImportCommodities",["foodstuffs","consumer = +goods","intermediate manubgfactures","Capital equipment"]). +bgfact("Congo","ImportPartners",["France","Germany","Italy","Spain","US",= +"Japan","Brazil"]). +bgfact("Congo","Industries",["petroleum","cement","lumbering","brewing","= +sugar milling","palm oil","soap","cigarette"]). +bgfact("Congo","Agriculture",["corn","peanuts","imports over of food = +needs"]). +bgfact("Cook Islands","LandBounderies",[]). +bgfact("Cook Islands","NaturalResources",["negligible"]). +bgfact("Cook Islands","Population",["19124"]). +bgfact("Cook Islands","Capital",["Avarua"]). +bgfact("Cook = +Islands","MemberOf",["AsDB","ESCAP","IOC","SPARTECA","SPC","SPF","UNESCO"= +,"WHO"]). +bgfact("Cook Islands","ExportCommodities",["copra","fresh and canned = +fruit","clothing"]). +bgfact("Cook Islands","ExportPartners",["NZ","Japan"]). +bgfact("Cook = +Islands","ImportCommodities",["foodstuffs","textiles","fuels","timber"]).= + +bgfact("Cook Islands","ImportPartners",["NZ","Japan","Australia","US"]). +bgfact("Cook Islands","Industries",["fruit processing","tourism"]). +bgfact("Cook Islands","Agriculture",["accounts for of GDP","export = +copra","citrus fruits","pineapples","tomatoes","subsistence = +yams","taro"]). +bgfact("Coral Sea Islands","LandBounderies",[]). +bgfact("Coral Sea Islands","NaturalResources",["negligible"]). +bgfact("Coral Sea Islands","Population",["3"]). +bgfact("Coral Sea Islands","Capital",["none; administered from Canberra, = +Australia"]). +bgfact("Costa Rica","LandBounderies",["Nicaragua","Panama"]). +bgfact("Costa Rica","NaturalResources",["hydropower potential"]). +bgfact("Costa Rica","Population",["3342154"]). +bgfact("Costa Rica","Capital",["San Jose"]). +bgfact("Costa = +Rica","MemberOf",["AG","OAS","OPANAL","UN","UNCTAD","UNESCO","UNIDO","UPU= +","WCL","WFTU","WHO","WIPO","WMO"]). +bgfact("Costa = +Rica","ExportCommodities",["coffee","bananas","textiles","sugar"]). +bgfact("Costa = +Rica","ExportPartners",["US","Germany","Italy","Guatemala","El = +Salvador","Netherlands","UK","France"]). +bgfact("Costa Rica","ImportCommodities",["raw materials","consumer = +goods","Capital equipment","petroleum"]). +bgfact("Costa = +Rica","ImportPartners",["US","Japan","Mexico","Guatemala","Venezuela","Ge= +rmany"]). +bgfact("Costa Rica","Industries",["food processing","textiles and = +clothing","construction materials","fertilizer","plastic products"]). +bgfact("Costa Rica","Agriculture",["commodities - = +coffee","beef","bananas","rice","beans","depletion of forest resources = +resulting in lower timber output"]). +bgfact("Cote = +d'Ivoire","LandBounderies",["Burkina","Ghana","Guinea","Liberia","Mali"])= +. +bgfact("Cote = +d'Ivoire","NaturalResources",["petroleum","diamonds","manganese","iron = +ore","cobalt","bauxite","copper"]). +bgfact("Cote d'Ivoire","Population",["14295501"]). +bgfact("Cote d'Ivoire","Capital",["Yamoussoukro"]). +bgfact("Cote = +d'Ivoire","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOWAS","En= +tente","FAO","FZ","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICC","IDA","= +IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","= +NAM","OAU","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL","WHO","WIPO"= +,"WMO","WTO"]). +bgfact("Cote d'Ivoire","ExportCommodities",["cocoa","coffee","tropical = +woods","petroleum","cotton","bananas","pineapples","palm = +oil","cotton"]). +bgfact("Cote = +d'Ivoire","ExportPartners",["France","FRG","Netherlands","US","Belgium","= +Spain"]). +bgfact("Cote d'Ivoire","ImportCommodities",["food","Capital = +goods","consumer goods","fuel"]). +bgfact("Cote = +d'Ivoire","ImportPartners",["France","Nigeria","US","Japan"]). +bgfact("Cote d'Ivoire","Industries",["foodstuffs","wood processing","oil = +refinery","automobile assembly","textiles","fertilizer","beverage"]). +bgfact("Cote d'Ivoire","Agriculture",["most important sector","crops = +include coffee","cocoa beans","timber","bananas","palm kernels","food = +corn","rice","manioc","not self-sufficient in bread grain and dairy = +products"]). +bgfact("Croatia","LandBounderies",["Bosnia and = +Herzegovina","Hungary","Serbia and Montenegro","Slovenia"]). +bgfact("Croatia","NaturalResources",["oil","some = +coal","bauxite","low-grade iron ore","calcium","natural = +asphalt","silica","mica","clays","salt"]). +bgfact("Croatia","Population",["4697614"]). +bgfact("Croatia","Capital",["Zagreb"]). +bgfact("Croatia","MemberOf",["CE","UN","UNCTAD","UNESCO","UNIDO","UPU","W= +HO","WIPO","WMO"]). +bgfact("Croatia","ExportCommodities",["machinery and transport = +equipment","chemicals","food and live animals","raw materials","fuels = +and lubricants"]). +bgfact("Croatia","ExportPartners",["EC countries","Slovenia"]). +bgfact("Croatia","ImportCommodities",["machinery and transport = +equipment","fuels and lubricants","food and live = +animals","chemicals","manubgfactured goods","miscellaneous = +manubgfactured articles","raw materials","beverages and tobacco"]). +bgfact("Croatia","ImportPartners",["EC countries","Slovenia","FSU = +countries"]). +bgfact("Croatia","Industries",["chemicals and plastics","machine = +tools","fabricated metal","electronics","pig iron and rolled steel = +products","aluminum reduction","paper","wood = +products","textiles","shipbuilding","petroleum and petroleum = +refining","food processing and beverages"]). +bgfact("Croatia","Agriculture",["wheat","corn","sugar = +beets","sunflowers","alfalfa","central Croatian highlands are less = +fertile but support cereal production","orchards","vineyards","livestock = + breeding","coastal areas and offshore islands grow olives","citrus = +fruits"]). +bgfact("Cuba","LandBounderies",["US Naval Base at Guantanamo Bay"]). +bgfact("Cuba","NaturalResources",["cobalt","nickel","iron = +ore","copper","manganese","salt","timber","silica","petroleum"]). +bgfact("Cuba","Population",["11064344"]). +bgfact("Cuba","Capital",["Havana"]). +bgfact("Cuba","MemberOf",["CCC","ECLAC","FAO","G-77","GATT","IAEA","ICAO"= +,"IFAD","ILO","IMO","INMARSAT","INTELSAT","PCA","UN","UNCTAD","UNESCO","U= +NIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Cuba","ExportCommodities",["sugar","nickel","shellfish","tobacco"= +,"medical products","citrus","coffee"]). +bgfact("Cuba","ExportPartners",["Russia","Canada","China","Ukraine","Japa= +n","Spain"]). +bgfact("Cuba","ImportCommodities",["petroleum","food","machinery","chemic= +als"]). +bgfact("Cuba","ImportPartners",["Venezuela","China","Spain","Mexico","Ita= +ly","Canada","France"]). +bgfact("Cuba","Industries",["sugar milling and refining","petroleum = +refining","food and tobacco processing","textiles","chemicals","paper = +and wood products","metals","cement","fertilizers","consumer = +goods","agricultural machinery"]). +bgfact("Cuba","Agriculture",["sector hurt by growing shortages of fuels = +and parts"]). +bgfact("Cyprus","LandBounderies",[]). +bgfact("Cyprus","NaturalResources",["copper","pyrites","asbestos","gypsum= +","timber","salt","marble","clay earth pigment"]). +bgfact("Cyprus","Population",["730084"]). +bgfact("Cyprus","Capital",["Nicosia"]). +bgfact("Cyprus","MemberOf",["C","CCC","CE","CSCE","EBRD","ECE","FAO","G-7= +7","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IFAD","IFC","ILO","IM= +F","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","NAM","= +OAS","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO"= +,"WTO"]). +bgfact("Cyprus","ExportCommodities",["citrus","potatoes","grapes","wine",= +"cement","clothing and shoes"]). +bgfact("Cyprus","ExportPartners",["UK","Greece","Lebanon","Egypt"]). +bgfact("Cyprus","ImportCommodities",["consumer goods","petroleum and = +lubricants","food and feed grains","machinery"]). +bgfact("Cyprus","ImportPartners",["UK","Japan","Italy","Germany","US"]). +bgfact("Cyprus","Industries",["food","beverages","textiles","chemicals","= +metal products","tourism","wood products"]). +bgfact("Cyprus","Agriculture",["major = +potatoes","vegetables","barley","grapes","olives","vegetables and fruit = +provide of export revenues"]). +bgfact("Czech = +Republic","LandBounderies",["Austria","Germany","Poland","Slovakia"]). +bgfact("Czech Republic","NaturalResources",["hard coal","soft = +coal","kaolin","clay","graphite"]). +bgfact("Czech Republic","Population",["10408280"]). +bgfact("Czech Republic","Capital",["Prague"]). +bgfact("Czech Republic","MemberOf",["BIS","CCC","CE","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMIG","UNOMOZ","UNPROFOR","UPU","WFTU","= +WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Czech Republic","ExportCommodities",["manubgfactured = +goods","machinery and transport = +equipment","chemicals","fuels","minerals"]). +bgfact("Czech = +Republic","ExportPartners",["Germany","Slovakia","Poland","Austria","Hung= +ary","Italy","France","US","UK","CIS republics"]). +bgfact("Czech Republic","ImportCommodities",["machinery and transport = +equipment","fuels and lubricants","manbgfactured goods","raw = +materials","chemicals","agricultural products"]). +bgfact("Czech Republic","ImportPartners",["Slovakia","CIS = +republics","Germany","Austria","Poland","Switzerland","Hungary","UK","Ita= +ly"]). +bgfact("Czech Republic","Industries",["fuels","ferrous = +metallurgy","machinery and equipment","coal","motor = +vehicles","glass","armaments"]). +bgfact("Czech Republic","Agriculture",["diversified crop and livestock = +production","including grains","potatoes","sugar = +beets","hops","fruit","hogs","cattle","exporter of forest products"]). +bgfact("Denmark","LandBounderies",["Germany"]). +bgfact("Denmark","NaturalResources",["petroleum","natural = +gas","fish","salt","limestone"]). +bgfact("Denmark","Population",["5187821"]). +bgfact("Denmark","Capital",["Copenhagen"]). +bgfact("Denmark","MemberOf",["AfDB","AG","AsDB","Australia = +Group","BIS","CBSS","CCC","CE","CERN","COCOM","CSCE","EBRD","EC","ECE","E= +IB","ESA","FAO","G-9","GATT","IADB","IAEA","IBRD","ICAO","ICC","ICFTU","I= +DA","IEA","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL"= +,"IOC","IOM","ISO","ITU","LORCS","MTCR","NACC","NATO","NC","NEA","NIB","N= +SG","OECD","PCA","UN","UNCTAD","UNESCO","UNFICYP","UNHCR","UNIDO","UNIKOM= +","UNOMIG","UNMOGIP","UNPROFOR","UNTSO","UPU","WEU","WFTU","WHO","WIPO","= +WMO","ZC"]). +bgfact("Denmark","ExportCommodities",["meat and meat products","dairy = +products","transport equipment","fish","chemicals","industrial = +machinery"]). +bgfact("Denmark","ExportPartners",["EC"]). +bgfact("Denmark","ImportCommodities",["petroleum","machinery and = +equipment","chemicals","grain and foodstuffs","textiles","paper"]). +bgfact("Denmark","ImportPartners",["EC"]). +bgfact("Denmark","Industries",["food processing","machinery and = +equipment","textiles and clothing","chemical = +products","electronics","construction","furniture","shipbuilding"]). +bgfact("Denmark","Agriculture",["principal = +meat","dairy","grain","potatoes","rape","sugar beets","self-sufficient = +in food production"]). +bgfact("Djibouti","LandBounderies",["Eritrea","Ethiopia","Somalia"]). +bgfact("Djibouti","NaturalResources",[]). +bgfact("Djibouti","Population",["412599"]). +bgfact("Djibouti","Capital",["Djibouti"]). +bgfact("Djibouti","MemberOf",["ACCT","ACP","AfDB","AFESD","AL","ECA","FAO= +","G-77","IBRD","ICAO","IDA","IDB","IFAD","IFC","IGADD","ILO","IMF","IMO"= +,"INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","OIC","UN","UNESCO= +","UNCTAD","UNIDO","UPU","WHO","WMO"]). +bgfact("Djibouti","ExportCommodities",["hides and skins","coffee"]). +bgfact("Djibouti","ExportPartners",["Africa","Middle East","Western = +Europe"]). +bgfact("Djibouti","ImportCommodities",["foods","beverages","transport = +equipment","chemicals","petroleum products"]). +bgfact("Djibouti","ImportPartners",["Western Europe","Asia","Africa"]). +bgfact("Djibouti","Industries",["limited to a few small-scale = +enterprises","such as dairy products and mineral-water bottling"]). +bgfact("Djibouti","Agriculture",["half of Population pastoral nomads = +herding goats","sheep","imports bulk of food needs"]). +bgfact("Dominica","LandBounderies",[]). +bgfact("Dominica","NaturalResources",["timber"]). +bgfact("Dominica","Population",["87696"]). +bgfact("Dominica","Capital",["Roseau"]). +bgfact("Dominica","MemberOf",["ACCT","ACP","C","CARICOM","CDB","ECLAC","F= +AO","G-77","GATT","IBRD","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","IN= +TERPOL","LORCS","NAM","OAS","OECS","UN","UNCTAD","UNESCO","UNIDO","UPU","= +WCL","WHO","WMO"]). +bgfact("Dominica","ExportCommodities",["bananas","soap","bay = +oil","vegetables","grapefruit","oranges"]). +bgfact("Dominica","ExportPartners",["UK","CARICOM = +countries","Italy","US"]). +bgfact("Dominica","ImportCommodities",["manubgfactured goods","machinery = +and equipment","food","chemicals"]). +bgfact("Dominica","ImportPartners",["US","CARICOM","UK","Canada"]). +bgfact("Dominica","Industries",["soap","coconut = +oil","tourism","copra","furniture","cement blocks","shoes"]). +bgfact("Dominica","Agriculture",["principal = +bananas","citrus","mangoes","root crops","forestry and fisheries = +potential not exploited"]). +bgfact("Dominican Republic","LandBounderies",["Haiti"]). +bgfact("Dominican = +Republic","NaturalResources",["nickel","bauxite","gold","silver"]). +bgfact("Dominican Republic","Population",["7826075"]). +bgfact("Dominican Republic","Capital",["Santo Domingo"]). +bgfact("Dominican = +Republic","MemberOf",["ACP","CARICOM","OAS","OPANAL","PCA","UN","UNCTAD",= +"UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WMO","WTO"]). +bgfact("Dominican = +Republic","ExportCommodities",["ferronickel","sugar","gold","coffee","coc= +oa"]). +bgfact("Dominican Republic","ExportPartners",["US","EC","Puerto Rico"]). +bgfact("Dominican = +Republic","ImportCommodities",["foodstuffs","petroleum","cotton and = +fabrics","chemicals and pharmaceuticals"]). +bgfact("Dominican Republic","ImportPartners",["US"]). +bgfact("Dominican Republic","Industries",["tourism","sugar = +processing","ferronickel and gold = +mining","textiles","cement","tobacco"]). +bgfact("Dominican Republic","Agriculture",["sugarcane is the most = +important commercial crop","followed by coffee","cotton","cocoa","food = +rice","beans","potatoes","corn","animal output - cattle","hogs","dairy = +products","meat","not self-sufficient in food"]). +bgfact("Ecuador","LandBounderies",["Colombia","Peru"]). +bgfact("Ecuador","NaturalResources",["petroleum","fish","timber"]). +bgfact("Ecuador","Population",["10677067"]). +bgfact("Ecuador","Capital",["Quito"]). +bgfact("Ecuador","MemberOf",["AG","ECLAC","FAO","G-11","G-77","IADB","IAE= +A","IBRD","ICAO","ICC","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTE= +LSAT","INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS","NAM","OAS","ONU= +SAL","OPANAL","PCA","RG","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU= +","WHO","WIPO","WMO","WTO"]). +bgfact("Ecuador","ExportCommodities",["petroleum","bananas","shrimp","coc= +oa","coffee"]). +bgfact("Ecuador","ExportPartners",["US","Latin America","Caribbean","EC = +countries"]). +bgfact("Ecuador","ImportCommodities",["transport = +equipment","vehicles","machinery","chemicals"]). +bgfact("Ecuador","ImportPartners",["US","Latin America","Caribbean","EC = +countries","Japan"]). +bgfact("Ecuador","Industries",["petroleum","food = +processing","textiles","metal works","paper products","wood = +products","chemicals","plastics","fishing","timber"]). +bgfact("Ecuador","Agriculture",["cocoa","fish","crop production - = +rice","potatoes","manioc","plantains","livestock sector - = +cattle","sheep","hogs","beef","pork","net importer of foodgrains","dairy = +products"]). +bgfact("Egypt","LandBounderies",["Gaza = +Strip","Israel","Libya","Sudan"]). +bgfact("Egypt","NaturalResources",["petroleum","natural gas","iron = +ore","phosphates","manganese","limestone","gypsum","talc","asbestos","lea= +d","zinc"]). +bgfact("Egypt","Population",["60765028"]). +bgfact("Egypt","Capital",["Cairo"]). +bgfact("Egypt","MemberOf",["ABEDA","ACC","ACCT","OAU","OIC","PCA","UN","U= +NAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMOZ","UNOSOM","UNPROFOR","UNTAC","UPU",= +"UNRWA","WHO","WIPO","WMO","WTO"]). +bgfact("Egypt","ExportCommodities",["crude and petroleum = +products","cotton yarn","raw cotton","textiles","metal = +products","chemicals"]). +bgfact("Egypt","ExportPartners",["EC","Eastern Europe","US","Japan"]). +bgfact("Egypt","ImportCommodities",["machinery and = +equipment","foods","fertilizers","wood products","durable consumer = +goods","Capital goods"]). +bgfact("Egypt","ImportPartners",["EC","US","Japan","Eastern Europe"]). +bgfact("Egypt","Industries",["textiles","food = +processing","tourism","chemicals","petroleum","construction","cement","me= +tals"]). +bgfact("Egypt","Agriculture",["corn","wheat","beans","fruit","livestock = +- cattle","water buffalo","sheep","annual fish catch about"]). +bgfact("El Salvador","LandBounderies",["Guatemala","Honduras"]). +bgfact("El Salvador","NaturalResources",["hydropower","petroleum"]). +bgfact("El Salvador","Population",["5752511"]). +bgfact("El Salvador","Capital",["San Salvador"]). +bgfact("El = +Salvador","MemberOf",["BCIE","CACM","ECLAC","FAO","G-77","GATT","IADB","I= +AEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT= +","IOC","IOM","ITU","LAES","LAIA","OAS","OPANAL","PCA","UN","UNCTAD","UNE= +SCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO"]). +bgfact("El = +Salvador","ExportCommodities",["coffee","sugarcane","shrimp"]). +bgfact("El Salvador","ExportPartners",["US","Guatemala","Costa = +Rica","Germany"]). +bgfact("El Salvador","ImportCommodities",["raw materials","consumer = +goods","Capital goods"]). +bgfact("El = +Salvador","ImportPartners",["US","Guatemala","Mexico","Venezuela","German= +y"]). +bgfact("El Salvador","Industries",["food = +processing","beverages","petroleum","nonmetallic = +products","tobacco","chemicals","textiles","furniture"]). +bgfact("El = +Salvador","Agriculture",["corn","rice","beans","oilseeds","beef","dairy = +products","not self-sufficient in food"]). +bgfact("Equatorial Guinea","LandBounderies",["Cameroon","Gabon"]). +bgfact("Equatorial = +Guinea","NaturalResources",["timber","petroleum","small unexploited = +deposits of gold","manganese","uranium"]). +bgfact("Equatorial Guinea","Population",["409550"]). +bgfact("Equatorial Guinea","Capital",["Malabo"]). +bgfact("Equatorial = +Guinea","MemberOf",["ACCT","ACP","AfDB","BDEAC","CEEAC","ECA","FAO","FZ",= +"G-77","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","OAU= +","UDEAC","UN","UNCTAD","UNESCO","UNIDO","UPU","WHO"]). +bgfact("Equatorial Guinea","ExportCommodities",["coffee","timber","cocoa = +beans"]). +bgfact("Equatorial = +Guinea","ExportPartners",["Spain","Nigeria","Cameroon"]). +bgfact("Equatorial = +Guinea","ImportCommodities",["petroleum","food","beverages","clothing","m= +achinery"]). +bgfact("Equatorial = +Guinea","ImportPartners",["Cameroon","Spain","France","US"]). +bgfact("Equatorial Guinea","Industries",["fishing","sawmilling"]). +bgfact("Equatorial Guinea","Agriculture",["accounts for almost of = +GDP","timber and coffee from Rio Muni","food = +rice","yams","cassava","bananas","oil palm nuts","manioc","livestock"]). +bgfact("Eritrea","LandBounderies",["Djibouti","Ethiopia","Sudan"]). +bgfact("Eritrea","NaturalResources",["gold","potash","zinc","copper","sal= +t","probably oil","fish"]). +bgfact("Eritrea","Population",["3782543"]). +bgfact("Eritrea","Capital",["Asmara"]). +bgfact("Eritrea","MemberOf",["OAU","ACP","AfDB","ECA","ILO","IMO","INTELS= +AT","ITU","UN","UNCTAD","UNESCO","UPU","WMO"]). +bgfact("Eritrea","ExportCommodities",["NA"]). +bgfact("Eritrea","ExportPartners",["NA"]). +bgfact("Eritrea","ImportCommodities",["NA"]). +bgfact("Eritrea","ImportPartners",["NA"]). +bgfact("Eritrea","Industries",["food processing","beverages","clothing = +and textiles"]). +bgfact("Eritrea","Agriculture",["sorghum","livestock"]). +bgfact("Estonia","LandBounderies",["Latvia","Russia"]). +bgfact("Estonia","NaturalResources",["shale = +oil","peat","phosphorite","amber"]). +bgfact("Estonia","Population",["1616882"]). +bgfact("Estonia","Capital",["Tallinn"]). +bgfact("Estonia","MemberOf",["BIS","CBSS","CCC","CE","CSCE","EBRD","ECE",= +"FAO","IAEA","IBRD","ICAO","ICFTU","IFC","ILO","IMF","IMO","INTERPOL","IO= +C","ISO","ITU","NACC","UN","UNCTAD","UNESCO","UPU","WHO","WMO"]). +bgfact("Estonia","ExportCommodities",["textile","food = +products","vehicles","metals"]). +bgfact("Estonia","ExportPartners",["Russia","Finland","Latvia","Germany",= +"Ukraine"]). +bgfact("Estonia","ImportCommodities",["machinery","fuels","vehicles","tex= +tiles"]). +bgfact("Estonia","ImportPartners",["Finland","Russia","Sweden","Germany",= +"Netherlands"]). +bgfact("Estonia","Industries",["oil = +shale","shipbuilding","phosphates","electric = +motors","excavators","cement","furniture","clothing","textiles","paper","= +shoes","apparel"]). +bgfact("Estonia","Agriculture",["net exports of meat","fish","dairy = +products","fruits and vegetables"]). +bgfact("Ethiopia","LandBounderies",["Djibouti","Eritrea","Kenya","Somalia= +","Sudan"]). +bgfact("Ethiopia","NaturalResources",["small reserves of = +gold","platinum","copper","potash"]). +bgfact("Ethiopia","Population",["54927108"]). +bgfact("Ethiopia","Capital",["Addis Ababa"]). +bgfact("Ethiopia","MemberOf",["ACP","AfDB","CCC","ECA","FAO","G-24","G-77= +","IAEA","IBRD","ICAO","IDA","IFAD","IFC","IGADD","ILO","IMF","IMO","INTE= +LSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","OAU","UN","UNCTAD","UNE= +SCO","UNHCR","UNIDO","UPU","WFTU","WHO","WMO","WTO"]). +bgfact("Ethiopia","ExportCommodities",["coffee","leather = +products","gold","petroleum products"]). +bgfact("Ethiopia","ExportPartners",["Germany","Japan","Saudi = +Arabia","France","Italy"]). +bgfact("Ethiopia","ImportCommodities",["Capital goods","consumer = +goods","fuel"]). +bgfact("Ethiopia","ImportPartners",["US","Germany","Italy","Saudi = +Arabia","Japan"]). +bgfact("Ethiopia","Industries",["food = +processing","beverages","textiles","chemicals","metals = +processing","cement"]). +bgfact("Ethiopia","Agriculture",["principal crops and livestock - = +cereals","pulses","coffee","oilseeds","sugarcane","hides and = +skins","cattle","sheep","goats"]). +bgfact("Europa Island","LandBounderies",[]). +bgfact("Europa Island","NaturalResources",["negligible"]). +bgfact("Europa Island","Capital",["none; administered by France from = +Reunion"]). +bgfact("Falkland Islands (Islas Malvinas)","LandBounderies",[]). +bgfact("Falkland Islands (Islas = +Malvinas)","NaturalResources",["fish","wildlife"]). +bgfact("Falkland Islands (Islas Malvinas)","Population",["2261"]). +bgfact("Falkland Islands (Islas Malvinas)","Capital",["Stanley"]). +bgfact("Falkland Islands (Islas Malvinas)","MemberOf",["ICFTU"]). +bgfact("Falkland Islands (Islas = +Malvinas)","ExportCommodities",["wool","hides and skins"]). +bgfact("Falkland Islands (Islas = +Malvinas)","ExportPartners",["UK","Netherlands","Japan"]). +bgfact("Falkland Islands (Islas = +Malvinas)","ImportCommodities",["food","clothing","fuels"]). +bgfact("Falkland Islands (Islas = +Malvinas)","ImportPartners",["UK","Netherlands Antilles"]). +bgfact("Falkland Islands (Islas Malvinas)","Industries",["wool and fish = +processing"]). +bgfact("Falkland Islands (Islas Malvinas)","Agriculture",["some fodder = +and vegetable crops"]). +bgfact("Faroe Islands","LandBounderies",[]). +bgfact("Faroe Islands","NaturalResources",["fish"]). +bgfact("Faroe Islands","Population",["48427"]). +bgfact("Faroe Islands","Capital",["Torshavn"]). +bgfact("Faroe Islands","MemberOf",["none"]). +bgfact("Faroe Islands","ExportCommodities",["fish and fish = +products","animal feedstuffs","transport equipment"]). +bgfact("Faroe = +Islands","ExportPartners",["Denmark","Germany","UK","France","Spain","US"= +]). +bgfact("Faroe Islands","ImportCommodities",["machinery and transport = +equipment","manubgfactures","food and livestock","fuels","chemicals"]). +bgfact("Faroe = +Islands","ImportPartners",["Denmark","Norway","Sweden","Germany","US"]). +bgfact("Faroe = +Islands","Industries",["fishing","shipbuilding","handicrafts"]). +bgfact("Faroe Islands","Agriculture",["annual fish catch about"]). +bgfact("Fiji","LandBounderies",[]). +bgfact("Fiji","NaturalResources",["timber","fish","gold","copper","offsho= +re oil potential"]). +bgfact("Fiji","Population",["764382"]). +bgfact("Fiji","Capital",["Suva"]). +bgfact("Fiji","MemberOf",["ACP","AsDB","CP","ESCAP","FAO","G-77","GATT","= +IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INT= +ERPOL","IOC","ITU","LORCS","PCA","SPARTECA","SPC","SPF","UN","UNCTAD","UN= +ESCO","UNIDO","UNIFIL","UNIKOM","UNOMUR","UNTAC","UPU","WHO","WIPO","WMO"= +]). +bgfact("Fiji","ExportCommodities",["sugar","clothing","processed = +fish","gold","lumber"]). +bgfact("Fiji","ExportPartners",["EC","Australia","Pacific = +Islands","Japan"]). +bgfact("Fiji","ImportCommodities",["machinery and transport = +equipment","petroleum products","food","consumer goods","chemicals"]). +bgfact("Fiji","ImportPartners",["Australia","NZ","Japan","EC","US"]). +bgfact("Fiji","Industries",["sugar","tourism","copra","gold","silver","cl= +othing","lumber","small cottage Industries"]). +bgfact("Fiji","Agriculture",["coconuts","cassava","rice","sweet = +potatoes","small livestock sector includes = +cattle","pigs","horses","fish catch nearly"]). +bgfact("Finland","LandBounderies",["Norway","Sweden","Russia"]). +bgfact("Finland","NaturalResources",["timber","copper","zinc","iron = +ore","silver"]). +bgfact("Finland","Population",["5068931"]). +bgfact("Finland","Capital",["Helsinki"]). +bgfact("Finland","MemberOf",["AfDB","AG","OECD","PCA","UN","UNCTAD","UNDO= +F","UNESCO","UNFICYP","UNHCR","UNIDO","UNIFIL","UNIKOM","UNMOGIP","UNPROF= +OR","UNTSO","UPU","WFTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Finland","ExportCommodities",["timber","paper and = +pulp","ships","machinery","clothing and footwear"]). +bgfact("Finland","ExportPartners",["EC"]). +bgfact("Finland","ImportCommodities",["foodstuffs","petroleum and = +petroleum products","chemicals","transport equipment","iron and = +steel","machinery","textile yarn and fabrics","fodder grains"]). +bgfact("Finland","ImportPartners",["EC"]). +bgfact("Finland","Industries",["metal products","shipbuilding","forestry = +and wood processing","copper = +refining","foodstuffs","chemicals","textiles","clothing"]). +bgfact("Finland","Agriculture",["livestock production","especially dairy = +cattle","main crops - cereals","sugar beets","self-sufficient","annual = +fish catch about"]). +bgfact("France","LandBounderies",["Andorra","Belgium","Germany","Italy","= +Luxembourg","Monaco","Spain","Switzerland"]). +bgfact("France","NaturalResources",["coal","iron = +ore","bauxite","fish","timber","zinc","potash"]). +bgfact("France","Population",["57840445"]). +bgfact("France","Capital",["Paris"]). +bgfact("France","MemberOf",["ACCT","AfDB","AG","OECD","ONUSAL","PCA","SPC= +","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNIFIL","UNIKOM","UNOSOM","UNPR= +OFOR","UNRWA","UN Security Council","UNTAC","UN Trusteeship = +Council","UNTSO","UPU","WCL","WEU","WFTU","WHO","WIPO","WMO","WTO","ZC"])= +. +bgfact("France","ExportCommodities",["machinery and transportation = +equipment","chemicals","foodstuffs","agricultural products","iron and = +steel products","textiles and clothing"]). +bgfact("France","ExportPartners",["Germany","Italy","Spain","Belgium-Luxe= +mbourg","UK","Netherlands","US","Japan","former USSR"]). +bgfact("France","ImportCommodities",["crude","machinery and = +equipment","agricultural products","chemicals","iron and steel = +products"]). +bgfact("France","ImportPartners",["Germany","Italy","US","Netherlands","S= +pain","Belgium-Luxembourg","UK","Japan","former USSR"]). +bgfact("France","Industries",["steel","machinery","chemicals","automobile= +s","metallurgy","aircraft","electronics","mining","textiles","food = +processing","tourism"]). +bgfact("France","Agriculture",["dairy products","cereals","sugar = +beets","potatoes","shortages include fats and oils and tropical = +produce","fish catch of"]). +bgfact("French Guiana","LandBounderies",["Brazil","Suriname"]). +bgfact("French = +Guiana","NaturalResources",["bauxite","timber","gold","cinnabar","kaolin"= +,"fish"]). +bgfact("French Guiana","Population",["139299"]). +bgfact("French Guiana","Capital",["Cayenne"]). +bgfact("French Guiana","MemberOf",["FZ","WCL"]). +bgfact("French = +Guiana","ExportCommodities",["shrimp","timber","rum","rosewood = +essence"]). +bgfact("French Guiana","ExportPartners",["France","Spain","US"]). +bgfact("French Guiana","ImportCommodities",["food","producer = +goods","petroleum"]). +bgfact("French Guiana","ImportPartners",["France","Germany","US"]). +bgfact("French Guiana","Industries",["construction","shrimp = +processing","forestry products","rum","gold mining"]). +bgfact("French = +Guiana","Agriculture",["rice","corn","manioc","cocoa","bananas","livestoc= +k - cattle","pigs","poultry"]). +bgfact("French Polynesia","LandBounderies",[]). +bgfact("French = +Polynesia","NaturalResources",["timber","fish","cobalt"]). +bgfact("French Polynesia","Population",["215129"]). +bgfact("French Polynesia","Capital",["Papeete"]). +bgfact("French = +Polynesia","MemberOf",["ESCAP","FZ","ICFTU","SPC","WMO"]). +bgfact("French Polynesia","ExportCommodities",["coconut = +products","vanilla","shark meat"]). +bgfact("French Polynesia","ExportPartners",["France","US","Japan"]). +bgfact("French = +Polynesia","ImportCommodities",["fuels","foodstuffs","equipment"]). +bgfact("French = +Polynesia","ImportPartners",["France","US","Australia","NZ"]). +bgfact("French Polynesia","Industries",["tourism","pearls","agricultural = +processing","handicrafts"]). +bgfact("French Polynesia","Agriculture",["poultry","beef","dairy = +products"]). +bgfact("French Southern and Antarctic Lands","LandBounderies",[]). +bgfact("French Southern and Antarctic = +Lands","NaturalResources",["fish","crayfish"]). +bgfact("French Southern and Antarctic Lands","Capital",["none; = +administered from Paris, France"]). +bgfact("Gabon","LandBounderies",["Cameroon","Congo","Equatorial = +Guinea"]). +bgfact("Gabon","NaturalResources",["petroleum","manganese","uranium","gol= +d","timber","iron ore"]). +bgfact("Gabon","Population",["1139006"]). +bgfact("Gabon","Capital",["Libreville"]). +bgfact("Gabon","MemberOf",["ACCT","ACP","AfDB","BDEAC","CCC","CEEAC","ECA= +","FAO","FZ","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA= +","IDB","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","= +IOC","ITU","LORCS","NAM","OAU","OIC","OPEC","UDEAC","UN","UNCTAD","UNESCO= +","UNIDO","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Gabon","ExportCommodities",["crude","timber","manganese","uranium= +"]). +bgfact("Gabon","ExportPartners",["France","US","Germany","Japan"]). +bgfact("Gabon","ImportCommodities",["foodstuffs","chemical = +products","petroleum products","construction = +materials","manubgfactures","machinery"]). +bgfact("Gabon","ImportPartners",["France","African = +countries","US","Japan"]). +bgfact("Gabon","Industries",["petroleum","food and beverages","lumbering = +and plywood","textiles","mining - = +manganese","uranium","gold","cement"]). +bgfact("Gabon","Agriculture",["accounts for of GDP is the most important = +timber product"]). +bgfact("The Gambia","LandBounderies",["Senegal"]). +bgfact("The Gambia","NaturalResources",["fish"]). +bgfact("The Gambia","Population",["959300"]). +bgfact("The Gambia","Capital",["Banjul"]). +bgfact("The = +Gambia","MemberOf",["ACP","AfDB","C","CCC","ECA","ECOWAS","FAO","G-77","G= +ATT","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","IFC","IMF","IMO","INTELSAT= +","INTERPOL","IOC","ITU","LORCS","NAM","OAU","OIC","UN","UNCTAD","UNESCO"= +,"UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("The Gambia","ExportCommodities",["peanuts and peanut = +products","fish","cotton lint","palm kernels"]). +bgfact("The Gambia","ExportPartners",["Japan","Europe","Africa","US"]). +bgfact("The = +Gambia","ImportCommodities",["foodstuffs","manubgfactures","raw = +materials","fuel","machinery and transport equipment"]). +bgfact("The Gambia","ImportPartners",["Europe","Asia","USSR and Eastern = +Europe","US"]). +bgfact("The Gambia","Industries",["peanut = +processing","tourism","beverages","agricultural machinery = +assembly","woodworking","metalworking","clothing"]). +bgfact("The = +Gambia","Agriculture",["sorghum","rice","corn","cassava","livestock - = +cattle","sheep","forestry and fishing resources not fully exploited"]). +bgfact("Gaza Strip","LandBounderies",["Egypt","Israel"]). +bgfact("Gaza Strip","NaturalResources",["negligible"]). +bgfact("Gaza Strip","Population",["731296"]). +bgfact("Gaza Strip","ExportCommodities",["citrus"]). +bgfact("Gaza Strip","ExportPartners",["Israel","Egypt"]). +bgfact("Gaza Strip","ImportCommodities",["food","consumer = +goods","construction materials"]). +bgfact("Gaza Strip","ImportPartners",["Israel","Egypt"]). +bgfact("Gaza Strip","Industries",["generally small family businesses = +that produce textiles","soap","olive-wood carvings","the Israelis have = +established some small-scale modern Industries in an industrial = +center"]). +bgfact("Gaza Strip","Agriculture",["olives","vegetables","beef","dairy = +products"]). +bgfact("Georgia","LandBounderies",["Armenia","Azerbaijan","Russia","Turke= +y"]). +bgfact("Georgia","NaturalResources",["forest = +lands","hydropower","manganese deposits","iron ores","copper","coastal = +climate and soils allow for important tea and citrus growth"]). +bgfact("Georgia","Population",["5681025"]). +bgfact("Georgia","Capital",["T'bilisi"]). +bgfact("Georgia","MemberOf",["BSEC","CIS","CSCE","EBRD","ECE","IBRD","IDA= +","ILO","IMF","IMO","INMARSAT","IOC","ITU","NACC","UN","UNCTAD","UNESCO",= +"UNIDO","UPU","WHO"]). +bgfact("Georgia","ExportCommodities",["citrus fruits","tea","wine","fuel = + re-exports"]). +bgfact("Georgia","ExportPartners",["Russia","Turkey","Armenia","Azerbaija= +n"]). +bgfact("Georgia","ImportCommodities",["fuel","machinery and = +parts","transport equipment"]). +bgfact("Georgia","ImportPartners",["Russia","Azerbaijan","Turkey"]). +bgfact("Georgia","Industries",["heavy industrial products include raw = +steel","rolled steel","machine tools","foundry equipment","electric = +locomotives","tower cranes","electric welding equipment","machinery for = +food preparation and meat packing","electric motors","process control = +equipment","trucks","tractors","light industrial products","including = +cloth","hosiery","the most important food industry is wine"]). +bgfact("Georgia","Agriculture",["dependent on imports for grain","dairy = +products","small livestock sector"]). +bgfact("Germany","LandBounderies",["Austria","Belgium","Czech = +Republic","Denmark","France","Luxembourg","Netherlands","Poland","Switzer= +land"]). +bgfact("Germany","NaturalResources",["iron = +ore","coal","potash","timber","lignite","uranium","copper","natural = +gas","salt","nickel"]). +bgfact("Germany","Population",["81087506"]). +bgfact("Germany","Capital",["Berlin"]). +bgfact("Germany","MemberOf",["AfDB","AG","OECD","PCA","UN","UNCTAD","UNES= +CO","UNIDO","UNHCR","UNOMIG","UNOSOM","UNTAC","UPU","WEU","WHO","WIPO","W= +MO","WTO","ZC"]). +bgfact("Germany","ExportCommodities",["manubgfactures"]). +bgfact("Germany","ExportPartners",["EC"]). +bgfact("Germany","ImportCommodities",["manubgfactures","agricultural = +products","fuels","raw materials"]). +bgfact("Germany","ImportPartners",["EC"]). +bgfact("Germany","Industries",[]). +bgfact("Germany","Agriculture",[]). +bgfact("Ghana","LandBounderies",["Burkina","Cote d'Ivoire","Togo"]). +bgfact("Ghana","NaturalResources",["gold","timber","industrial = +diamonds","bauxite","manganese","fish","rubber"]). +bgfact("Ghana","Population",["17225185"]). +bgfact("Ghana","Capital",["Accra"]). +bgfact("Ghana","MemberOf",["ACP","AfDB","C","CCC","ECA","ECOWAS","FAO","G= +-24","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO",= +"IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","MINURS= +O","NAM","OAU","UN","UNCTAD","UNESCO","UNIDO","UNIFIL","UNIKOM","UNPROFOR= +","UNTAC","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Ghana","ExportCommodities",["cocoa","gold","timber","tuna","bauxi= +te"]). +bgfact("Ghana","ExportPartners",["Germany","US","UK","Netherlands","Japan= +"]). +bgfact("Ghana","ImportCommodities",["petroleum","consumer = +goods","foods","intermediate goods","Capital equipment"]). +bgfact("Ghana","ImportPartners",["UK","US","Germany","Japan"]). +bgfact("Ghana","Industries",["mining","lumbering","light = +manubgfacturing","aluminum","food processing"]). +bgfact("Ghana","Agriculture",["coffee","cassava","peanuts","corn","shea = +nuts","normally self-sufficient in food"]). +bgfact("Gibraltar","LandBounderies",["Spain"]). +bgfact("Gibraltar","NaturalResources",["negligible"]). +bgfact("Gibraltar","Population",["31684"]). +bgfact("Gibraltar","Capital",["Gilbraltar"]). +bgfact("Gibraltar","MemberOf",["INTERPOL"]). +bgfact("Gibraltar","ExportCommodities",["petroleum","manubgfactured = +goods"]). +bgfact("Gibraltar","ExportPartners",["UK","Morocco","Portugal","Netherlan= +ds","Spain","US","FRG"]). +bgfact("Gibraltar","ImportCommodities",["fuels","manubgfactured = +goods"]). +bgfact("Gibraltar","ImportPartners",["UK","Spain","Japan","Netherlands"])= +. +bgfact("Gibraltar","Industries",["tourism","banking and = +finance","construction","light manubgfacturing of tobacco","roasted = +coffee","ice","mineral waters","candy","beer"]). +bgfact("Gibraltar","Agriculture",["none"]). +bgfact("Glorioso Islands","LandBounderies",[]). +bgfact("Glorioso Islands","NaturalResources",["guano","coconuts"]). +bgfact("Glorioso Islands","Capital",["none; administered by France from = +Reunion"]). +bgfact("Greece","LandBounderies",["Albania","Bulgaria","Turkey","The = +Former Yugoslav Republic of Macedonia"]). +bgfact("Greece","NaturalResources",["bauxite","lignite","magnesite","petr= +oleum","marble"]). +bgfact("Greece","Population",["10564630"]). +bgfact("Greece","Capital",["Athens"]). +bgfact("Greece","MemberOf",["Australian = +Group","BIS","BSEC","CCC","CE","CERN","COCOM","CSCE","EBRD","EC","ECE","E= +IB","FAO","G-6","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IEA","IF= +AD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM",= +"ISO","ITU","LORCS","MINURSO","MTCR","NACC","NAM","WFTU","WHO","WIPO","WM= +O","WTO","ZC"]). +bgfact("Greece","ExportCommodities",["manubgfactured = +goods","foodstuffs","fuels"]). +bgfact("Greece","ExportPartners",["Germany","Italy","France","UK","US"]).= + +bgfact("Greece","ImportCommodities",["manubgfactured = +goods","foodstuffs","fuels"]). +bgfact("Greece","ImportPartners",["Germany","Italy","France","Netherlands= +","Japan"]). +bgfact("Greece","Industries",["food and tobacco = +processing","textiles","chemicals","metal = +products","tourism","mining","petroleum"]). +bgfact("Greece","Agriculture",["including fishing and = +forestry","principal wheat","corn","barley","sugar = +beets","olives","tomatoes","wine","tobacco","self-sufficient in food = +except meat","dairy products"]). +bgfact("Greenland","LandBounderies",[]). +bgfact("Greenland","NaturalResources",["zinc","lead","iron = +ore","coal","molybdenum","cryolite","uranium","fish"]). +bgfact("Greenland","Population",["57040"]). +bgfact("Greenland","Capital",["Nuuk"]). +bgfact("Greenland","ExportCommodities",["fish and fish products"]). +bgfact("Greenland","ExportPartners",["Denmark","Benelux","Germany"]). +bgfact("Greenland","ImportCommodities",["manubgfactured = +goods","machinery and transport equipment","food and live = +animals","petroleum products"]). +bgfact("Greenland","ImportPartners",["Denmark","Norway","US","Germany","J= +apan","Sweden"]). +bgfact("Greenland","Industries",["fish processing","lead and zinc = +mining","handicrafts","some small shipyards","potential for platinum and = +gold mining"]). +bgfact("Greenland","Agriculture",["fish catch of"]). +bgfact("Grenada","LandBounderies",[]). +bgfact("Grenada","NaturalResources",["timber","tropical = +fruit","deepwater harbors"]). +bgfact("Grenada","Population",["94109"]). +bgfact("Grenada","Capital",["Saint George's"]). +bgfact("Grenada","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-7= +7","GATT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","INTERPOL"= +,"IOC","ITU","LAES","LORCS","NAM","OAS","OECS","OPANAL","UN","UNCTAD","UN= +ESCO","UNIDO","UPU","WCL","WHO","WTO"]). +bgfact("Grenada","ExportCommodities",["bananas","cocoa","nutmeg","fruit = +and vegetables","clothing","mace"]). +bgfact("Grenada","ExportPartners",["Netherlands","UK","Trinidad and = +Tobago","United States"]). +bgfact("Grenada","ImportCommodities",["food","manubgfactured = +goods","machinery","chemicals","fuel"]). +bgfact("Grenada","ImportPartners",["US","UK","Trinidad and = +Tobago","Japan","Canada"]). +bgfact("Grenada","Industries",["food and beverage","textile","light = +assembly operations","tourism","construction"]). +bgfact("Grenada","Agriculture",["bananas","cocoa","nutmeg","small-size = +farms predominate","growing a variety of citrus = +fruits","avocados","root crops","sugarcane","corn"]). +bgfact("Guadeloupe","LandBounderies",[]). +bgfact("Guadeloupe","NaturalResources",["cultivable land","beaches and = +climate that foster tourism"]). +bgfact("Guadeloupe","Population",["428947"]). +bgfact("Guadeloupe","Capital",["Basse-Terre"]). +bgfact("Guadeloupe","MemberOf",["FZ","WCL","WFTU"]). +bgfact("Guadeloupe","ExportCommodities",["bananas","sugar","rum"]). +bgfact("Guadeloupe","ExportPartners",["France","Martinique"]). +bgfact("Guadeloupe","ImportCommodities",["vehicles","foodstuffs","constru= +ction materials","petroleum products"]). +bgfact("Guadeloupe","ImportPartners",["France","Italy","FRG","US"]). +bgfact("Guadeloupe","Industries",["construction","cement","rum","sugar","= +tourism"]). +bgfact("Guadeloupe","Agriculture",["bananas","livestock - = +cattle","pigs","not self-sufficient in food"]). +bgfact("Guam","LandBounderies",[]). +bgfact("Guam","NaturalResources",["fishing"]). +bgfact("Guam","Population",["149620"]). +bgfact("Guam","Capital",["Agana"]). +bgfact("Guam","MemberOf",["ESCAP","IOC","SPC"]). +bgfact("Guam","ExportCommodities",["mostly transshipments of refined = +petroleum products","construction materials","fish","food and beverage = +products"]). +bgfact("Guam","ExportPartners",["US","Trust Territory of the Pacific = +Islands"]). +bgfact("Guam","ImportCommodities",["petroleum and petroleum = +products","food","manubgfactured goods"]). +bgfact("Guam","ImportPartners",["US","Japan"]). +bgfact("Guam","Industries",["US = +military","tourism","construction","transshipment services","concrete = +products","printing and publishing","food processing","textiles"]). +bgfact("Guam","Agriculture",["fruits","vegetables","eggs","pork","poultry= +","beef","copra"]). +bgfact("Guatemala","LandBounderies",["Belize","El = +Salvador","Honduras","Mexico"]). +bgfact("Guatemala","NaturalResources",["petroleum","nickel","rare = +woods","fish","chicle"]). +bgfact("Guatemala","Population",["10721387"]). +bgfact("Guatemala","Capital",["Guatemala"]). +bgfact("Guatemala","MemberOf",["BCIE","CACM","CCC","ECLAC","FAO","G-24","= +G-77","GATT","IADB","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO"= +,"IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS= +","NAM","OAS","OPANAL","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","= +WFTU","WHO","WIPO","WMO"]). +bgfact("Guatemala","ExportCommodities",["coffee","sugar","bananas","carda= +mon","beef"]). +bgfact("Guatemala","ExportPartners",["US","El Salvador","Costa = +Rica","Germany","Honduras"]). +bgfact("Guatemala","ImportCommodities",["fuel and petroleum = +products","machinery","grain","fertilizers","motor vehicles"]). +bgfact("Guatemala","ImportPartners",["US","Mexico","Venezuela","Japan","G= +ermany"]). +bgfact("Guatemala","Industries",["sugar","textiles and = +clothing","furniture","chemicals","petroleum","metals","rubber","tourism"= +]). +bgfact("Guatemala","Agriculture",["principal = +sugarcane","corn","bananas","coffee","beans","livestock - = +cattle","sheep","pigs","food importer"]). +bgfact("Guernsey","LandBounderies",[]). +bgfact("Guernsey","NaturalResources",["cropland"]). +bgfact("Guernsey","Population",["63719"]). +bgfact("Guernsey","Capital",["Saint Peter Port"]). +bgfact("Guernsey","MemberOf",["none"]). +bgfact("Guernsey","ExportCommodities",["tomatoes","flowers and = +ferns","sweet peppers","eggplant"]). +bgfact("Guernsey","ExportPartners",["UK"]). +bgfact("Guernsey","ImportCommodities",["coal","gasoline"]). +bgfact("Guernsey","ImportPartners",["UK"]). +bgfact("Guernsey","Industries",["tourism","banking"]). +bgfact("Guernsey","Agriculture",["tomatoes","flowers","sweet = +peppers","eggplant","Guernsey cattle"]). +bgfact("Guinea","LandBounderies",["Guinea-Bissau","Cote = +d'Ivoire","Liberia","Mali","Senegal","Sierra Leone"]). +bgfact("Guinea","NaturalResources",["bauxite","iron = +ore","diamonds","gold","uranium","hydropower","fish"]). +bgfact("Guinea","Population",["6391536"]). +bgfact("Guinea","Capital",["Conakry"]). +bgfact("Guinea","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOWA= +S","FAO","G-77","IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","IMO",= +"INTELSAT","INTERPOL","IOC","ITU","LORCS","MINURSO","NAM","OAU","OIC","UN= +","UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Guinea","ExportCommodities",["bauxite","alumina","diamonds","gold= +","coffee","pineapples","bananas","palm kernels"]). +bgfact("Guinea","ExportPartners",["US","Belgium","Ireland","Spain"]). +bgfact("Guinea","ImportCommodities",["petroleum = +products","metals","machinery","transport = +equipment","foodstuffs","textiles"]). +bgfact("Guinea","ImportPartners",["France","Cote d'Ivoire","Hong = +Kong","Germany"]). +bgfact("Guinea","Industries",["bauxite mining","alumina","gold","diamond = +mining","light manubgfacturing and agricultural processing = +Industries"]). +bgfact("Guinea","Agriculture",["principal = +rice","coffee","pineapples","palm kernels","cassava","bananas","sweet = +potatoes","livestock - cattle","not self-sufficient in food grains"]). +bgfact("Guinea-Bissau","LandBounderies",["Guinea","Senegal"]). +bgfact("Guinea-Bissau","NaturalResources",["unexploited deposits of = +petroleum","bauxite","phosphates","fish","timber"]). +bgfact("Guinea-Bissau","Population",["1098231"]). +bgfact("Guinea-Bissau","Capital",["Bissau"]). +bgfact("Guinea-Bissau","MemberOf",["ACCT","ITU","LORCS","NAM","OAU","OIC"= +,"UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMOZ","UPU","WFTU","WHO","WIPO","WMO","W= +TO"]). +bgfact("Guinea-Bissau","ExportCommodities",["cashews","fish","peanuts","p= +alm kernels"]). +bgfact("Guinea-Bissau","ExportPartners",["Portugal","Spain","Senegal","In= +dia","Nigeria"]). +bgfact("Guinea-Bissau","ImportCommodities",["foodstuffs","transport = +equipment","petroleum products","machinery and equipment"]). +bgfact("Guinea-Bissau","ImportPartners",["Portugal","Netherlands","China"= +,"Germany","Senegal"]). +bgfact("Guinea-Bissau","Industries",["agricultural = +processing","beer","soft drinks"]). +bgfact("Guinea-Bissau","Agriculture",["accounts for over of GDP","nearly = +of exports","beans","cassava","cashew nuts","peanuts","palm = +kernels","fishing and forestry potential not fully exploited"]). +bgfact("Guyana","LandBounderies",["Brazil","Suriname","Venezuela"]). +bgfact("Guyana","NaturalResources",["bauxite","gold","diamonds","hardwood= + timber","shrimp","fish"]). +bgfact("Guyana","Population",["729425"]). +bgfact("Guyana","Capital",["Georgetown"]). +bgfact("Guyana","MemberOf",["ACP","C","CARICOM","CCC","CDB","ECLAC","FAO"= +,"G-77","GATT","IADB","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF= +","IMO","INTELSAT","INTERPOL","IOC","ITU","LAES","LORCS","NAM","OAS","ONU= +SAL","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WMO"]). +bgfact("Guyana","ExportCommodities",["sugar","bauxite/alumina","rice","sh= +rimp","molasses"]). +bgfact("Guyana","ExportPartners",["UK","US","Canada","France","Japan"]). +bgfact("Guyana","ImportCommodities",["manubgfactures","machinery","petrol= +eum","food"]). +bgfact("Guyana","ImportPartners",["US","Trinidad and = +Tobago","UK","Italy","Japan"]). +bgfact("Guyana","Industries",["bauxite mining","sugar","rice = +milling","timber","fishing","textiles","gold mining"]). +bgfact("Guyana","Agriculture",["most important sector","not = +self-sufficient in food","especially wheat","vegetable oils"]). +bgfact("Haiti","LandBounderies",["Dominican Republic"]). +bgfact("Haiti","NaturalResources",["bauxite"]). +bgfact("Haiti","Population",["6491450"]). +bgfact("Haiti","Capital",["Port-au-Prince"]). +bgfact("Haiti","MemberOf",["ACCT","ACP","CARICOM","CCC","ECLAC","FAO","G-= +77","GATT","IADB","IAEA","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","IM= +O","INTELSAT","INTERPOL","IOC","ITU","LAES","LORCS","OAS","OPANAL","PCA",= +"UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO= +"]). +bgfact("Haiti","ExportCommodities",["light manubgfactures","coffee"]). +bgfact("Haiti","ExportPartners",["US","Italy","France","less developed = +countries"]). +bgfact("Haiti","ImportCommodities",["machines and manubgfactures","food = +and beverages","petroleum products","chemicals","fats and oils"]). +bgfact("Haiti","ImportPartners",["US","Netherlands = +Antilles","Japan","France","Canada","Germany"]). +bgfact("Haiti","Industries",["sugar refining","textiles","flour = +milling","cement manubgfacturing","tourism","light assembly Industries = +based on imported parts"]). +bgfact("Haiti","Agriculture",["commercial = +coffee","mangoes","sugarcane","staple rice","corn","shortage of wheat = +flour"]). +bgfact("Heard Island and McDonald Islands","LandBounderies",[]). +bgfact("Heard Island and McDonald Islands","NaturalResources",["none"]). +bgfact("Heard Island and McDonald Islands","Capital",["none; = +administered from Canberra, Australia"]). +bgfact("Holy See (Vatican City)","LandBounderies",["Italy"]). +bgfact("Holy See (Vatican City)","NaturalResources",["none"]). +bgfact("Holy See (Vatican City)","Population",["821"]). +bgfact("Holy See (Vatican City)","Capital",["Vatican City"]). +bgfact("Holy See (Vatican = +City)","MemberOf",["CSCE","IAEA","ICFTU","IMF"]). +bgfact("Holy See (Vatican City)","Industries",["worldwide banking and = +financial activities"]). +bgfact("Honduras","LandBounderies",["Guatemala","El = +Salvador","Nicaragua"]). +bgfact("Honduras","NaturalResources",["timber","gold","silver","copper","= +lead","zinc","iron ore","antimony","coal","fish"]). +bgfact("Honduras","Population",["5314794"]). +bgfact("Honduras","Capital",["Tegucigalpa"]). +bgfact("Honduras","MemberOf",["BCIE","CACM","ECLAC","FAO","G-77","GATT","= +IADB","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSA= +T","INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS","MINURSO","OAS","OP= +ANAL","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO= +","WMO"]). +bgfact("Honduras","ExportCommodities",["bananas","coffee","shrimp","lobst= +er","minerals","meat","lumber"]). +bgfact("Honduras","ExportPartners",["US","Germany","Belgium","UK"]). +bgfact("Honduras","ImportCommodities",["machinery and transport = +equipment","chemical products","manubgfactured goods","fuel and = +oil","foodstuffs"]). +bgfact("Honduras","ImportPartners",["US","Mexico","Guatemala"]). +bgfact("Honduras","Industries",["agricultural = +processing","textiles","clothing","wood products"]). +bgfact("Honduras","Agriculture",["most important sector","accounting for = +more than of GDP","more than of the labor force","principal products = +include bananas","coffee","timber","beef","citrus fruit","importer of = +wheat"]). +bgfact("Hong Kong","LandBounderies",["China"]). +bgfact("Hong Kong","NaturalResources",["outstanding deepwater = +harbor","feldspar"]). +bgfact("Hong Kong","Population",["5548754"]). +bgfact("Hong Kong","Capital",["Victoria"]). +bgfact("Hong Kong","MemberOf",["COCOM","WCL","WMO"]). +bgfact("Hong Kong","ExportCommodities",["clothing","textiles","yarn and = +fabric","footwear","electrical appliances","watches and = +clocks","toys"]). +bgfact("Hong = +Kong","ExportPartners",["China","US","Germany","Japan","UK"]). +bgfact("Hong Kong","ImportCommodities",["foodstuffs","transport = +equipment","raw materials","semimanubgfactures","petroleum"]). +bgfact("Hong Kong","ImportPartners",["China","Japan","Taiwan","US"]). +bgfact("Hong = +Kong","Industries",["textiles","clothing","tourism","electronics","plasti= +cs","toys","watches","clocks"]). +bgfact("Hong Kong","Agriculture",["local farmers produce fresh = +vegetables","of land area suitable for farming"]). +bgfact("Howland Island","LandBounderies",[]). +bgfact("Howland Island","NaturalResources",["guano"]). +bgfact("Howland Island","Population",["1942"]). +bgfact("Howland Island","Capital",["none; administered from Washington, = +DC"]). +bgfact("Hungary","LandBounderies",["Austria","Croatia","Romania","Serbia = + and Montenegro","Slovakia","Slovenia","Ukraine"]). +bgfact("Hungary","NaturalResources",["bauxite","coal","natural = +gas","fertile soils"]). +bgfact("Hungary","Population",["10319113"]). +bgfact("Hungary","Capital",["Budapest"]). +bgfact("Hungary","MemberOf",["Australian = +Group","BIS","CCC","CE","CEI","CERN","COCOM","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNIKOM","UNOMOZ","UNOMUR","UNOSOM"= +,"UNTAC","UPU","WFTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Hungary","ExportCommodities",["raw materials","semi-finished = +goods","chemicals","machinery","consumer goods","food and = +Agriculture","fuels and energy"]). +bgfact("Hungary","ExportPartners",["EC"]). +bgfact("Hungary","ImportCommodities",["fuels and energy","raw = +materials","semi-finished goods","chemicals","machinery","consumer = +goods","food and Agriculture"]). +bgfact("Hungary","ImportPartners",["EC","Austria","the FSU","Eastern = +Europe"]). +bgfact("Hungary","Industries",["mining","metallurgy","construction = +materials","processed = +foods","textiles","chemicals","buses","automobiles"]). +bgfact("Hungary","Agriculture",["including forestry","principal = +wheat","corn","sunflowers","potatoes","livestock - = +hogs","cattle","poultry","self-sufficient in food output"]). +bgfact("Iceland","LandBounderies",[]). +bgfact("Iceland","NaturalResources",["fish","hydropower","diatomite"]). +bgfact("Iceland","Population",["263599"]). +bgfact("Iceland","Capital",["Reykjavik"]). +bgfact("Iceland","MemberOf",["Australian = +Group","BIS","CCC","CE","CSCE","EBRD","ECE","EFTA","FAO","GATT","IAEA","I= +BRD","ICAO","ICC","ICFTU","IDA","IFC","ILO","IMF","IMO","INMARSAT","INTEL= +SAT","INTERPOL","IOC","ISO","ITU","LORCS","MTCR","NACC","NATO","NC","NEA"= +,"NIB","OECD","PCA","UN","UNCTAD","UNESCO","UPU","WEU","WHO","WIPO","WMO"= +]). +bgfact("Iceland","ExportCommodities",["fish and fish products","animal = +products","aluminum","ferrosilicon","diatomite"]). +bgfact("Iceland","ExportPartners",["EC"]). +bgfact("Iceland","ImportCommodities",["machinery and transportation = +equipment","petroleum products","foodstuffs","textiles"]). +bgfact("Iceland","ImportPartners",["EC"]). +bgfact("Iceland","Industries",["fish processing","aluminum = +smelting","ferro-silicon production"]). +bgfact("Iceland","Agriculture",["fishing is most important economic = +activity","principal crops - potatoes","livestock - cattle","fish catch = +of about million metric tons in"]). +bgfact("India","LandBounderies",["Bangladesh","Bhutan","Burma","China","N= +epal","Pakistan"]). +bgfact("India","NaturalResources",["coal","iron = +ore","manganese","mica","bauxite","titanium ore","chromite","natural = +gas","diamonds","petroleum","limestone"]). +bgfact("India","Population",["919903056"]). +bgfact("India","Capital",["New Delhi"]). +bgfact("India","MemberOf",["AG","ONUSAL","PCA","SAARC","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNIKOM","UNOMOZ","UNOSOM","UNPROFOR","UNTA= +C","UPU","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("India","ExportCommodities",["gems and = +jewelry","clothing","engineering goods","chemicals","leather = +manubgfactures","cotton yarn"]). +bgfact("India","ExportPartners",["US","Germany","Italy"]). +bgfact("India","ImportCommodities",["crude and petroleum = +products","gems","fertilizer","chemicals","machinery"]). +bgfact("India","ImportPartners",["US","Belgium","Germany"]). +bgfact("India","Industries",["textiles","chemicals","food = +processing","steel","transportation = +equipment","cement","mining","petroleum","machinery"]). +bgfact("India","Agriculture",["principal = +rice","wheat","oilseeds","cotton","jute","tea","sugarcane","livestock - = +cattle","buffaloes","sheep","goats","fish catch of about million metric = +tons ranks India among the world's top fishing nations"]). +bgfact("Indian Ocean","NaturalResources",["oil and gas = +fields","fish","shrimp","sand and gravel aggregates","placer = +deposits","polymetallic nodules"]). +bgfact("Indian Ocean","Industries",["based on exploitation of natural = +resources","particularly fish","minerals","oil and gas","fishing","sand = +and gravel"]). +bgfact("Indonesia","LandBounderies",["Malaysia","Papua New Guinea"]). +bgfact("Indonesia","NaturalResources",["petroleum","tin","natural = +gas","nickel","timber","bauxite","copper","fertile = +soils","coal","gold","silver"]). +bgfact("Indonesia","Population",["200409741"]). +bgfact("Indonesia","Capital",["Jakarta"]). +bgfact("Indonesia","MemberOf",["APEC","AsDB","ASEAN","CCC","CP","ESCAP","= +FAO","G-15","G-19","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA"= +,"IDB","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","I= +OC","IOM","ISO","ITU","LORCS","NAM","OIC","OPEC","UN","UNCTAD","UNESCO","= +UNIDO","UNIKOM","UNOSOM","UNTAC","UPU","WCL","WFTU","WHO","WIPO","WMO","W= +TO"]). +bgfact("Indonesia","ExportCommodities",["petroleum and gas","clothing = +and fabrics","plywood","footwear"]). +bgfact("Indonesia","ExportPartners",["Japan","US","Singapore","South = +Korea"]). +bgfact("Indonesia","ImportCommodities",["machinery","semi-finished = +goods","chemicals","raw materials","transport equipment","food = +stuffs","petroleum products","consumer goods"]). +bgfact("Indonesia","ImportPartners",["Japan","US","Germany","South = +Korea","Singapore","Australia","Taiwan"]). +bgfact("Indonesia","Industries",["petroleum and natural = +gas","textiles","mining","cement","chemical = +fertilizers","plywood","food","rubber"]). +bgfact("Indonesia","Agriculture",["main products are = +rice","cassava","peanuts","rubber","cocoa","coffee","palm = +oil","copra","poultry","beef","pork","eggs"]). +bgfact("Iran","LandBounderies",["Afghanistan","Armenia","Azerbaijan","Ira= +q","Pakistan","Turkey","Turkmenistan"]). +bgfact("Iran","NaturalResources",["petroleum","natural = +gas","coal","chromium","copper","iron = +ore","lead","manganese","zinc","sulfur"]). +bgfact("Iran","Population",["65615474"]). +bgfact("Iran","Capital",["Tehran"]). +bgfact("Iran","MemberOf",["CCC","CP","ESCAP","ECO","FAO","G-19","G-24","G= +-77","IAEA","IBRD","ICAO","ICC","IDA","IDB","IFAD","IFC","ILO","IMF","IMO= +","INMARSAT","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","OIC",= +"OPEC","PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WCL","WFTU","W= +HO","WIPO","WMO","WTO"]). +bgfact("Iran","ExportCommodities",["petroleum","carpets","fruits","nuts",= +"hides"]). +bgfact("Iran","ExportPartners",["Japan","Italy","France","Netherlands","B= +elgium/Luxembourg","Spain"]). +bgfact("Iran","ImportCommodities",["machinery","military = +supplies","metal works","foodstuffs","pharmaceuticals","technical = +services","refined oil products"]). +bgfact("Iran","ImportPartners",["Germany","Japan","Italy","UK","France"])= +. +bgfact("Iran","Industries",["petroleum","petrochemicals","textiles","food= + processing","metal fabricating"]). +bgfact("Iran","Agriculture",["principal wheat","rice","sugar = +beets","fruits","nuts","cotton","dairy products","wool","not = +self-sufficient in food"]). +bgfact("Iraq","LandBounderies",["Iran","Jordan","Kuwait","Saudi = +Arabia","Syria","Turkey"]). +bgfact("Iraq","NaturalResources",["petroleum","natural = +gas","phosphates","sulfur"]). +bgfact("Iraq","Population",["19889666"]). +bgfact("Iraq","Capital",["Baghdad"]). +bgfact("Iraq","MemberOf",["ABEDA","ACC","AFESD","AL","AMF","CAEU","CCC","= +ESCWA","FAO","G-19","G-77","IAEA","IBRD","ICAO","IDA","IDB","IFAD","IFC",= +"ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","ISO","ITU","LOR= +CS","NAM","OAPEC","OIC","OPEC","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU"= +,"WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Iraq","ExportCommodities",["crude and refined = +products","fertilizer","sulfur"]). +bgfact("Iraq","ExportPartners",["US","Brazil","Turkey","Japan","Netherlan= +ds","Spain"]). +bgfact("Iraq","ImportCommodities",["manubgfactures","food"]). +bgfact("Iraq","ImportPartners",["Germany","US","Turkey","France","UK"]). +bgfact("Iraq","Industries",["petroleum production and = +refining","chemicals","textiles","construction materials","food = +processing"]). +bgfact("Iraq","Agriculture",["principal = +wheat","barley","rice","vegetables","dates","cotton","livestock - = +cattle","not self-sufficient in food output"]). +bgfact("Ireland","LandBounderies",["UK"]). +bgfact("Ireland","NaturalResources",["zinc","lead","natural = +gas","petroleum","barite","copper","gypsum","limestone","dolomite","peat"= +,"silver"]). +bgfact("Ireland","Population",["3539296"]). +bgfact("Ireland","Capital",["Dublin"]). +bgfact("Ireland","MemberOf",["Australian = +Group","BIS","CCC","CE","COCOM","WHO","WIPO","WMO","ZC"]). +bgfact("Ireland","ExportCommodities",["chemicals","data processing = +equipment","industrial machinery","live animals","animal products"]). +bgfact("Ireland","ExportPartners",["EC","US"]). +bgfact("Ireland","ImportCommodities",["food","animal feed","data = +processing equipment","petroleum and petroleum = +products","machinery","textiles","clothing"]). +bgfact("Ireland","ImportPartners",["EC","US"]). +bgfact("Ireland","Industries",["food = +products","brewing","textiles","clothing","chemicals","pharmaceuticals","= +machinery","transportation equipment","glass and crystal"]). +bgfact("Ireland","Agriculture",["principal = +turnips","barley","potatoes","sugar beets","food shortages include = +bread grain","fruits","vegetables"]). +bgfact("Israel","LandBounderies",["Egypt","Gaza = +Strip","Jordan","Lebanon","Syria","West Bank"]). +bgfact("Israel","NaturalResources",["copper","phosphates","bromide","pota= +sh","clay","sand","sulfur","asphalt","manganese","small amounts of = +natural gas and crude"]). +bgfact("Israel","Population",["5050850"]). +bgfact("Israel","Capital",["Jerusalem"]). +bgfact("Israel","MemberOf",["AG","PCA","UN","UNCTAD","UNESCO","UNHCR","UN= +IDO","UPU","WHO","WIPO","WMO","WTO"]). +bgfact("Israel","ExportCommodities",["machinery and equipment","cut = +diamonds","chemicals","textiles and apparel","agricultural = +products","metals"]). +bgfact("Israel","ExportPartners",["US","EC","Japan"]). +bgfact("Israel","ImportCommodities",["military equipment","investment = +goods","rough diamonds","oil","consumer goods"]). +bgfact("Israel","ImportPartners",["US","EC"]). +bgfact("Israel","Industries",["food processing","diamond cutting and = +polishing","textiles and apparel","chemicals","metal products","military = +equipment","transport equipment","electrical equipment","miscellaneous = +machinery","potash mining","high-technology electronics","tourism"]). +bgfact("Israel","Agriculture",["largely self-sufficient in food = +production","vegetables","livestock beef","dairy","poultry"]). +bgfact("Italy","LandBounderies",["Austria","France","Holy See","San = +Marino","Slovenia","Switzerland"]). +bgfact("Italy","NaturalResources",["mercury","potash","marble","sulfur","= +dwindling natural gas and crude reserves","fish","coal"]). +bgfact("Italy","Population",["58138394"]). +bgfact("Italy","Capital",["Rome"]). +bgfact("Italy","MemberOf",["AfDB","AG","OECD","ONUSAL","PCA","UN","UNCTAD= +","UNESCO","UNHCR","UNIDO","UNIFIL","UNIKOM","UNMOGIP","UNOSOM","UNTAC","= +UNTSO","UPU","WCL","WEU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Italy","ExportCommodities",["metals","textiles and = +clothing","production machinery","motor vehicles","transportation = +equipment","chemicals"]). +bgfact("Italy","ExportPartners",["EC","US","OPEC"]). +bgfact("Italy","ImportCommodities",["industrial = +machinery","chemicals","transport = +equipment","petroleum","metals","food","agricultural products"]). +bgfact("Italy","ImportPartners",["EC","OPEC","US"]). +bgfact("Italy","Industries",["machinery","iron and = +steel","chemicals","food processing","textiles","motor = +vehicles","clothing","footwear","ceramics"]). +bgfact("Italy","Agriculture",["dairy products","principal = +fruits","vegetables","grapes","potatoes","sugar = +beets","soybeans","grain","fish catch of"]). +bgfact("Jamaica","LandBounderies",[]). +bgfact("Jamaica","NaturalResources",["bauxite","gypsum","limestone"]). +bgfact("Jamaica","Population",["2555064"]). +bgfact("Jamaica","Capital",["Kingston"]). +bgfact("Jamaica","MemberOf",["ACP","C","CARICOM","CCC","CDB","ECLAC","FAO= +","G-19","G-77","GATT","G-15","IADB","IAEA","IBRD","ICAO","ICFTU","IFAD",= +"IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LAES","L= +ORCS","NAM","OAS","OPANAL","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WF= +TU","WHO","WIPO","WMO","WTO"]). +bgfact("Jamaica","ExportCommodities",["alumina","bauxite","sugar","banana= +s","rum"]). +bgfact("Jamaica","ExportPartners",["US","UK","Germany","Canada","Norway"]= +). +bgfact("Jamaica","ImportCommodities",["fuel","construction = +materials","food","transport equipment"]). +bgfact("Jamaica","ImportPartners",["US","UK","Venezuela","Germany","Japan= +"]). +bgfact("Jamaica","Industries",["tourism","bauxite = +mining","textiles","food processing","light manubgfactures"]). +bgfact("Jamaica","Agriculture",["accounts for about of GDP","of work = +force","commercial = +sugarcane","bananas","coffee","citrus","potatoes","livestock and = +livestock products include poultry","goats","not self-sufficient in = +grain","meat"]). +bgfact("Jan Mayen","LandBounderies",[]). +bgfact("Jan Mayen","NaturalResources",["none"]). +bgfact("Jan Mayen","Capital",["none"]). +bgfact("Japan","LandBounderies",[]). +bgfact("Japan","NaturalResources",["negligible mineral = +resources","fish"]). +bgfact("Japan","Population",["125106937"]). +bgfact("Japan","Capital",["Tokyo"]). +bgfact("Japan","MemberOf",["AfDB","AG","OECD","PCA","UN","UNCTAD","UNESCO= +","UNHCR","UNIDO","UNRWA","UNTAC","UPU","WFTU","WHO","WIPO","WMO","WTO","= +ZC"]). +bgfact("Japan","ExportCommodities",["manubgfactures"]). +bgfact("Japan","ExportPartners",["Southeast Asia","US","Western = +Europe","China"]). +bgfact("Japan","ImportCommodities",["manubgfactures","fossil = +fuels","foodstuffs and raw materials"]). +bgfact("Japan","ImportPartners",["Southeast Asia","US","Western = +Europe","China"]). +bgfact("Japan","Industries",["steel and non-ferrous metallurgy","heavy = +electrical equipment","construction and mining equipment","motor = +vehicles and parts","electronic and telecommunication equipment and = +components","machine tools and automated production = +systems","locomotives and railroad rolling = +stock","shipbuilding","chemicals","textiles","food processing"]). +bgfact("Japan","Agriculture",["highly subsidized and protected = +sector","principal rice","sugar beets","vegetables","animal products = +include pork","poultry","shortages of wheat","corn","world's largest = +fish catch of million metric tons in"]). +bgfact("Jarvis Island","LandBounderies",[]). +bgfact("Jarvis Island","NaturalResources",["guano"]). +bgfact("Jarvis Island","Capital",["none; administered from Washington, = +DC"]). +bgfact("Jersey","LandBounderies",[]). +bgfact("Jersey","NaturalResources",["agricultural land"]). +bgfact("Jersey","Population",["86048"]). +bgfact("Jersey","Capital",["Saint Helier"]). +bgfact("Jersey","MemberOf",["none"]). +bgfact("Jersey","ExportCommodities",["light industrial and electrical = +goods","foodstuffs","textiles"]). +bgfact("Jersey","ExportPartners",["UK"]). +bgfact("Jersey","ImportCommodities",["machinery and transport = +equipment","manubgfactured goods","foodstuffs","mineral = +fuels","chemicals"]). +bgfact("Jersey","ImportPartners",["UK"]). +bgfact("Jersey","Industries",["tourism","banking and finance","dairy"]). +bgfact("Jersey","Agriculture",["potatoes","cauliflowers","dairy and = +cattle farming"]). +bgfact("Johnston Atoll","LandBounderies",[]). +bgfact("Johnston Atoll","NaturalResources",["guano"]). +bgfact("Johnston Atoll","Population",["327"]). +bgfact("Johnston Atoll","Capital",["none; administered from Washington, = +DC"]). +bgfact("Jordan","LandBounderies",["Iraq","Israel","Saudi = +Arabia","Syria","West Bank"]). +bgfact("Jordan","NaturalResources",["phosphates","potash","shale oil"]). +bgfact("Jordan","Population",["3961194"]). +bgfact("Jordan","Capital",["Amman"]). +bgfact("Jordan","MemberOf",["ABEDA","ACC","AFESD","AL","AMF","CAEU","CCC"= +,"ESCWA","FAO","G-77","IAEA","IBRD","ICAO","ICC","IDA","IDB","IFAD","IFC"= +,"ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ITU","LORCS","NAM",= +"OIC","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOSOM","UNRWA","UNPROFOR","UNTAC","UPU","= +WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Jordan","ExportCommodities",["phosphates","fertilizers","potash",= +"agricultural products","manubgfactures"]). +bgfact("Jordan","ExportPartners",["India","Iraq","Saudi = +Arabia","EC","Indonesia","UAE"]). +bgfact("Jordan","ImportCommodities",["crude","machinery","transport = +equipment","food","live animals","manubgfactured goods"]). +bgfact("Jordan","ImportPartners",["EC","US","Iraq","Japan","Turkey"]). +bgfact("Jordan","Industries",["phosphate mining","petroleum = +refining","cement","potash","light manubgfacturing"]). +bgfact("Jordan","Agriculture",["principal products are = +wheat","barley","citrus fruit","tomatoes","melons","livestock - = +sheep","goats","large net importer of food"]). +bgfact("Juan de Nova Island","LandBounderies",[]). +bgfact("Juan de Nova Island","NaturalResources",[]). +bgfact("Juan de Nova Island","Capital",["none; administered by France = +>from Reunion"]). +bgfact("Kazakhstan","LandBounderies",["China","Kyrgyzstan","Russia","Turk= +menistan","Uzbekistan"]). +bgfact("Kazakhstan","NaturalResources",["major deposits of = +petroleum","coal","iron ore","manganese","chrome = +ore","nickel","cobalt","copper","molybdenum","lead","zinc","bauxite","gol= +d","uranium"]). +bgfact("Kazakhstan","Population",["17267554"]). +bgfact("Kazakhstan","Capital",["Almaty"]). +bgfact("Kazakhstan","MemberOf",["CCC","CIS","CSCE","EBRD","ECO","ESCAP","= +IBRD","ICAO","IDA","IFC","ILO","IMF","INTELSAT","UN","UNCTAD","UNESCO","U= +PU","WHO","WMO"]). +bgfact("Kazakhstan","ExportCommodities",["oil","ferrous and nonferrous = +metals","chemicals","grain","wool","meat"]). +bgfact("Kazakhstan","ExportPartners",["Russia","Ukraine","Uzbekistan"]). +bgfact("Kazakhstan","ImportCommodities",["machinery and = +parts","industrial materials","oil and gas"]). +bgfact("Kazakhstan","ImportPartners",["China"]). +bgfact("Kazakhstan","Industries",["extractive Industries","iron and = +steel","nonferrous metal","electric motors","construction materials"]). +bgfact("Kazakhstan","Agriculture",["grain","meat","cotton","wool"]). +bgfact("Kenya","LandBounderies",["Ethiopia","Somalia","Sudan","Tanzania",= +"Uganda"]). +bgfact("Kenya","NaturalResources",["gold","limestone","soda ash","salt = +barytes","rubies","fluorspar","garnets","wildlife"]). +bgfact("Kenya","Population",["28240658"]). +bgfact("Kenya","Capital",["Nairobi"]). +bgfact("Kenya","MemberOf",["ACP","AfDB","C","CCC","EADB","ECA","FAO","G-7= +7","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","IGADD","ILO","= +IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","MINURSO= +","NAM","OAU","UN","UNCTAD","UNESCO","UNIDO","UNIKOM","UNPROFOR","UNTAC",= +"UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Kenya","ExportCommodities",["tea","coffee","petroleum = +products"]). +bgfact("Kenya","ExportPartners",["EC","Africa","Asia","US","Middle = +East"]). +bgfact("Kenya","ImportCommodities",["machinery and transportation = +equipment","petroleum and petroleum products","iron and steel","raw = +materials","food and consumer goods"]). +bgfact("Kenya","ImportPartners",["EC","Asia","Middle East","US"]). +bgfact("Kenya","Industries",["small-scale consumer goods","agricultural = +processing","oil refining","cement","tourism"]). +bgfact("Kenya","Agriculture",["most important = +sector","coffee","tea","sisal","food = +corn","wheat","sugarcane","fruit","vegetables","dairy = +products","beef","pork","poultry","food output not keeping pace with = +Population growth"]). +bgfact("Kingman Reef","LandBounderies",[]). +bgfact("Kingman Reef","NaturalResources",["none"]). +bgfact("Kingman Reef","Capital",["none; administered from Washington, = +DC"]). +bgfact("Kiribati","LandBounderies",[]). +bgfact("Kiribati","NaturalResources",["phosphate"]). +bgfact("Kiribati","Population",["77853"]). +bgfact("Kiribati","Capital",["Tarawa"]). +bgfact("Kiribati","MemberOf",["ACP","AsDB","C","ESCAP","IBRD","ICAO","ICF= +TU","IDA","IFC","IMF","INTELSAT","INTERPOL","ITU","SPARTECA","SPC","SPF",= +"UNESCO","UPU","WHO"]). +bgfact("Kiribati","ExportCommodities",["copra","seaweed","fish"]). +bgfact("Kiribati","ExportPartners",["Denmark","Fiji","US"]). +bgfact("Kiribati","ImportCommodities",["foodstuffs","machinery and = +equipment","miscellaneous manubgfactured goods","fuel"]). +bgfact("Kiribati","ImportPartners",["Australia","Japan","Fiji","NZ","US"]= +). +bgfact("Kiribati","Industries",["fishing","handicrafts"]). +bgfact("Kiribati","Agriculture",["food taro","breadfruit","sweet = +potatoes","not self-sufficient in food"]). +bgfact("Korea, North","LandBounderies",["China","South = +Korea","Russia"]). +bgfact("Korea, = +North","NaturalResources",["coal","lead","tungsten","zinc","graphite","ma= +gnesite","iron = +ore","copper","gold","pyrites","salt","fluorspar","hydropower"]). +bgfact("Korea, North","Population",["23066573"]). +bgfact("Korea, North","Capital",["P'yongyang"]). +bgfact("Korea, = +North","MemberOf",["ESCAP","FAO","G-77","ICAO","IFAD","IMF","IOC","ISO","= +ITU","LORCS","NAM","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WIP= +O","WMO","WTO"]). +bgfact("Korea, North","ExportCommodities",["minerals","metallurgical = +products","agricultural and fishery products","manubgfactures"]). +bgfact("Korea, North","ExportPartners",["China","Japan","Russia","South = +Korea","Germany","Hong Kong","Mexico"]). +bgfact("Korea, North","ImportCommodities",["petroleum","grain","coking = +coal","machinery and equipment","consumer goods"]). +bgfact("Korea, North","ImportPartners",["China","Russia","Japan","Hong = +Kong","Germany","Singapore"]). +bgfact("Korea, North","Industries",["machine building","military = +products","electric = +power","chemicals","mining","metallurgy","textiles","food processing"]). +bgfact("Korea, North","Agriculture",["principal = +rice","corn","potatoes","soybeans","livestock and livestock = +cattle","hogs","pork","not self-sufficient in grain"]). +bgfact("Korea, South","LandBounderies",["North Korea"]). +bgfact("Korea, = +South","NaturalResources",["coal","tungsten","graphite","molybdenum","lea= +d","hydropower"]). +bgfact("Korea, South","Population",["45082880"]). +bgfact("Korea, South","Capital",["Seoul"]). +bgfact("Korea, = +South","MemberOf",["AfDB","APEC","AsDB","CCC","COCOM","UN","UNCTAD","UNES= +CO","UNIDO","UNOSOM","UPU","WHO","WIPO","WMO","WTO"]). +bgfact("Korea, South","ExportCommodities",["electronic and electrical = +equipment","machinery","steel","automobiles","ships","textiles","clothing= +","footwear","fish"]). +bgfact("Korea, South","ExportPartners",["US","Japan","EC"]). +bgfact("Korea, South","ImportCommodities",["machinery","electronics and = +electronic equipment","oil","steel","transport = +equipment","textiles","organic chemicals","grains"]). +bgfact("Korea, South","ImportPartners",["Japan","US","EC"]). +bgfact("Korea, South","Industries",["electronics","automobile = +production","chemicals","shipbuilding","steel","textiles","clothing","foo= +twear","food processing"]). +bgfact("Korea, South","Agriculture",["principal rice","root = +crops","barley","vegetables","livestock and livestock = +cattle","hogs","chickens","milk","self-sufficient in food","fish catch = +of million metric tons","seventh-largest in world"]). +bgfact("Kuwait","LandBounderies",["Iraq","Saudi Arabia"]). +bgfact("Kuwait","NaturalResources",["petroleum","fish","shrimp","natural = +gas"]). +bgfact("Kuwait","Population",["1819322"]). +bgfact("Kuwait","Capital",["Kuwait"]). +bgfact("Kuwait","MemberOf",["ABEDA","AfDB","AFESD","AL","AMF","BDEAC","CA= +EU","ESCWA","FAO","G-77","GATT","GCC","IAEA","IBRD","ICAO","ICC","IDA","I= +DB","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC"= +,"ISO","ITU","LORCS","NAM","OAPEC","OIC","OPEC","UN","UNCTAD","UNESCO","U= +NIDO","UPU","WFTU","WHO","WMO","WTO"]). +bgfact("Kuwait","ExportCommodities",["oil"]). +bgfact("Kuwait","ExportPartners",["France","Italy","Japan","UK"]). +bgfact("Kuwait","ImportCommodities",["food","construction = +materials","vehicles and parts","clothing"]). +bgfact("Kuwait","ImportPartners",["US","Japan","UK","Canada"]). +bgfact("Kuwait","Industries",["petroleum","petrochemicals","desalination"= +,"food processing","building materials","salt","construction"]). +bgfact("Kuwait","Agriculture",["about of potable water must be = +distilled or imported"]). +bgfact("Kyrgyzstan","LandBounderies",["China","Kazakhstan","Tajikistan","= +Uzbekistan"]). +bgfact("Kyrgyzstan","NaturalResources",["locally exploitable = +coal","mercury","bismuth","lead","natural gas","oil","nepheline","rare = +earth metals","mercury","bismuth","gold","lead","zinc","hydroelectric = +power"]). +bgfact("Kyrgyzstan","Population",["4698108"]). +bgfact("Kyrgyzstan","Capital",["Bishkek"]). +bgfact("Kyrgyzstan","MemberOf",["CIS","CSCE","EBRD","ECE","ECO","ESCAP","= +IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","IOC","NACC","OIC","PCA= +","UN","UNCTAD","UNESCO","UNIDO","UPU","WHO"]). +bgfact("Kyrgyzstan","ExportCommodities",["wool","chemicals","cotton","fer= +rous and nonferrous metals","shoes","machinery","tobacco"]). +bgfact("Kyrgyzstan","ExportPartners",["Russia","Ukraine","Uzbekistan","Ka= +zakhstan"]). +bgfact("Kyrgyzstan","ImportCommodities",["grain","lumber","industrial = +products","ferrous metals","fuel","machinery","textiles","footwear"]). +bgfact("Kyrgyzstan","ImportPartners",[]). +bgfact("Kyrgyzstan","Industries",["small = +machinery","textiles","food-processing = +Industries","cement","shoes","sawn = +logs","refrigerators","furniture","electric motors","gold"]). +bgfact("Kyrgyzstan","Agriculture",["wool","tobacco","cotton","livestock",= +"vegetables","meat","grapes","fruits and = +berries","eggs","milk","potatoes"]). +bgfact("Laos","LandBounderies",["Burma","Cambodia","China","Thailand","Vi= +etnam"]). +bgfact("Laos","NaturalResources",["timber","hydropower","gypsum","tin","g= +old","gemstones"]). +bgfact("Laos","Population",["4701654"]). +bgfact("Laos","Capital",["Vientiane"]). +bgfact("Laos","MemberOf",["ACCT","AsDB","ASEAN","INTERPOL","IOC","ITU","L= +ORCS","NAM","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WMO"= +,"WTO"]). +bgfact("Laos","ExportCommodities",["electricity","wood = +products","coffee","tin"]). +bgfact("Laos","ExportPartners",["Thailand","Malaysia","Vietnam","FSU","US= +","China"]). +bgfact("Laos","ImportCommodities",["food","fuel oil","consumer = +goods","manubgfactures"]). +bgfact("Laos","ImportPartners",["Thailand","FSU","Japan","France","Vietna= +m","China"]). +bgfact("Laos","Industries",["tin and gypsum mining","timber","electric = +power","agricultural processing","construction"]). +bgfact("Laos","Agriculture",["principal rice","sweet = +potatoes","vegetables","corn","coffee","sugarcane","livestock - = +buffaloes","hogs","cattle","poultry"]). +bgfact("Latvia","LandBounderies",["Belarus","Estonia","Lithuania","Russia= +"]). +bgfact("Latvia","NaturalResources",["amber","peat","limestone","dolomite"= +]). +bgfact("Latvia","Population",["2749211"]). +bgfact("Latvia","Capital",["Riga"]). +bgfact("Latvia","MemberOf",["BIS","CBSS","CCC","CE","ITU","LORCS","NACC",= +"UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Latvia","ExportCommodities",["oil products","timber","ferrous = +metals","dairy products","furniture","textiles"]). +bgfact("Latvia","ExportPartners",["Russia","Western Europe"]). +bgfact("Latvia","ImportCommodities",["fuels","cars","ferrous = +metals","chemicals"]). +bgfact("Latvia","ImportPartners",["Russia","Western Europe"]). +bgfact("Latvia","Industries",["dependent on imports for energy","raw = +materials","produces buses","vans","street and railroad cars","synthetic = +fibers","agricultural machinery","fertilizers","washing = +machines","radios","electronics","pharmaceuticals","processed = +foods","textiles"]). +bgfact("Latvia","Agriculture",["meat","milk","eggs","grain","sugar = +beets","potatoes","fishing and fish packing"]). +bgfact("Lebanon","LandBounderies",["Israel","Syria"]). +bgfact("Lebanon","NaturalResources",["limestone","iron = +ore","salt","water-surplus state in a water-deficit region"]). +bgfact("Lebanon","Population",["3620395"]). +bgfact("Lebanon","Capital",["Beirut"]). +bgfact("Lebanon","MemberOf",["ABEDA","ACCT","AFESD","AL","AMF","CCC","ESC= +WA","FAO","G-24","G-77","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IDB","I= +FAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","N= +AM","OIC","PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNRWA","UPU","WFT= +U","WHO","WIPO","WMO","WTO"]). +bgfact("Lebanon","ExportCommodities",["agricultural = +products","chemicals","textiles","precious and semiprecious metals and = +jewelry","metals and metal products"]). +bgfact("Lebanon","ExportPartners",["Saudi = +Arabia","Switzerland","Jordan","Kuwait","US"]). +bgfact("Lebanon","ImportCommodities",["Consumer goods","machinery and = +transport equipment","petroleum products"]). +bgfact("Lebanon","ImportPartners",["Italy","France","US","Turkey","Saudi = +Arabia"]). +bgfact("Lebanon","Industries",["banking","food = +processing","textiles","cement","oil = +refining","chemicals","jewelry","some metal fabricating"]). +bgfact("Lebanon","Agriculture",["principal citrus = +fruits","vegetables","potatoes","olives","tobacco","hemp","sheep","not = +self-sufficient in grain"]). +bgfact("Lesotho","LandBounderies",["South Africa"]). +bgfact("Lesotho","NaturalResources",["water","agricultural and grazing = +land"]). +bgfact("Lesotho","Population",["1944493"]). +bgfact("Lesotho","Capital",["Maseru"]). +bgfact("Lesotho","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","G-77","G= +ATT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","INTELSAT","INT= +ERPOL","IOC","ITU","LORCS","NAM","OAU","SACU","SADC","UN","UNCTAD","UNESC= +O","UNHCR","UNIDO","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Lesotho","ExportCommodities",["wool","mohair","wheat","cattle","p= +eas","beans","corn","hides","skins","baskets"]). +bgfact("Lesotho","ExportPartners",["South Africa","EC","North and South = +America"]). +bgfact("Lesotho","ImportCommodities",["mainly corn","building = +materials","clothing","vehicles","machinery","medicines","petroleum"]). +bgfact("Lesotho","ImportPartners",["South Africa","Asia","EC"]). +bgfact("Lesotho","Industries",["food","beverages","textiles","handicrafts= +","tourism"]). +bgfact("Lesotho","Agriculture",["exceedingly primitive","principal crops = +corn","wheat","pulses","sorghum","barley"]). +bgfact("Liberia","LandBounderies",["Guinea","Cote d'Ivoire","Sierra = +Leone"]). +bgfact("Liberia","NaturalResources",["iron = +ore","timber","diamonds","gold"]). +bgfact("Liberia","Population",["2972766"]). +bgfact("Liberia","Capital",["Monrovia"]). +bgfact("Liberia","MemberOf",["ACP","AfDB","CCC","ECA","ECOWAS","FAO","G-7= +7","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INM= +ARSAT","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","UN","UNCTAD= +","UNESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO"]). +bgfact("Liberia","ExportCommodities",["iron = +ore","rubber","timber","coffee"]). +bgfact("Liberia","ExportPartners",["US","EC","Netherlands"]). +bgfact("Liberia","ImportCommodities",["rice","mineral = +fuels","chemicals","machinery","transportation equipment"]). +bgfact("Liberia","ImportPartners",["US","EC","Japan","China","Netherlands= +","ECOWAS"]). +bgfact("Liberia","Industries",["rubber processing","food = +processing","construction materials","furniture","palm oil = +processing","mining"]). +bgfact("Liberia","Agriculture",["principal = +rubber","timber","coffee","cocoa","rice","cassava","palm = +oil","sugarcane","bananas","sheep","not self-sufficient in = +food","imports of rice consumption"]). +bgfact("Libya","LandBounderies",["Algeria","Chad","Egypt","Niger","Sudan"= +,"Tunisia"]). +bgfact("Libya","NaturalResources",["petroleum","natural gas","gypsum"]). +bgfact("Libya","Population",["5057392"]). +bgfact("Libya","Capital",["Tripoli"]). +bgfact("Libya","MemberOf",["ABEDA","AfDB","AFESD","AL","AMF","AMU","CAEU"= +,"CCC","ECA","FAO","G-77","IAEA","IBRD","ICAO","IDA","IDB","IFAD","IFC","= +ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","O= +APEC","OAU","OIC","OPEC","UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WIPO= +","WMO","WTO"]). +bgfact("Libya","ExportCommodities",["crude","refined petroleum = +products","natural gas"]). +bgfact("Libya","ExportPartners",["Italy","Germany","Spain","France","UK",= +"Turkey","Greece","Egypt"]). +bgfact("Libya","ImportCommodities",["machinery","transport = +equipment","food","manubgfactured goods"]). +bgfact("Libya","ImportPartners",["Italy","Germany","UK","France","Spain",= +"Turkey","Tunisia","Eastern Europe"]). +bgfact("Libya","Industries",["petroleum","food = +processing","textiles","handicrafts","cement"]). +bgfact("Libya","Agriculture",["wheat","barley","olives","dates","citrus = +fruits","of food is imported"]). +bgfact("Liechtenstein","LandBounderies",["Austria","Switzerland"]). +bgfact("Liechtenstein","NaturalResources",["hydroelectric potential"]). +bgfact("Liechtenstein","Population",["30281"]). +bgfact("Liechtenstein","Capital",["Vaduz"]). +bgfact("Liechtenstein","MemberOf",["CE","CSCE","EBRD","ECE","EFTA","IAEA"= +,"INTELSAT","INTERPOL","IOC","ITU","LORCS","UN","UNCTAD","UPU","WCL","WIP= +O"]). +bgfact("Liechtenstein","ExportCommodities",["small specialty = +machinery","dental products","stamps","hardware","pottery"]). +bgfact("Liechtenstein","ExportPartners",["EFTA countries"]). +bgfact("Liechtenstein","ImportCommodities",["machinery","metal = +goods","textiles","foodstuffs","motor vehicles"]). +bgfact("Liechtenstein","ImportPartners",["NA"]). +bgfact("Liechtenstein","Industries",["electronics","metal = +manubgfacturing","textiles","ceramics","pharmaceuticals","food = +products","precision instruments","tourism"]). +bgfact("Liechtenstein","Agriculture",["livestock","vegetables","corn","wh= +eat","potatoes","grapes"]). +bgfact("Lithuania","LandBounderies",["Belarus","Latvia","Poland","Russia"= +]). +bgfact("Lithuania","NaturalResources",["peat"]). +bgfact("Lithuania","Population",["3848389"]). +bgfact("Lithuania","Capital",["Vilnius"]). +bgfact("Lithuania","MemberOf",["BIS","CBSS","CCC","CE","CSCE","EBRD","ECE= +","FAO","IBRD","ICAO","ILO","IMF","INTELSAT","ITU","LORCS","NACC","UN","U= +NCTAD","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Lithuania","ExportCommodities",["electronics","petroleum = +products","food","chemicals"]). +bgfact("Lithuania","ExportPartners",["Russia","Ukraine","West"]). +bgfact("Lithuania","ImportCommodities",["oil","machinery","chemicals","gr= +ain NA%"]). +bgfact("Lithuania","ImportPartners",["Russia","Belarus","West"]). +bgfact("Lithuania","Industries",["shipbuilding","furniture = +making","textiles","food processing","fertilizers","agricultural = +machinery","optical equipment","electronic components","computers"]). +bgfact("Lithuania","Agriculture",["sugar","grain","potatoes","sugar = +beets","vegetables","meat","milk","dairy products","eggs","most = +developed are the livestock and dairy branches","net exporter of = +meat","milk"]). +bgfact("Luxembourg","LandBounderies",["Belgium","France","Germany"]). +bgfact("Luxembourg","NaturalResources",["iron ore"]). +bgfact("Luxembourg","Population",["401900"]). +bgfact("Luxembourg","Capital",["Luxembourg"]). +bgfact("Luxembourg","MemberOf",["ACCT","Australia = +Group","Benelux","CCC","CE","COCOM","CSCE","EBRD","EC","ECE","EIB","FAO",= +"GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IEA","IFAD","IFC","ILO",= +"IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ITU","LORCS","MTCR","NACC"= +,"NATO","NEA","NSG","OECD","PCA","UN","UNCTAD","UNESCO","UNIDO","UNPROFOR= +","UPU","WCL","WEU","WHO","WIPO","WMO","ZC"]). +bgfact("Luxembourg","ExportCommodities",["finished steel = +products","chemicals","rubber products","glass","aluminum"]). +bgfact("Luxembourg","ExportPartners",["EC","US"]). +bgfact("Luxembourg","ImportCommodities",["minerals","metals","foodstuffs"= +,"quality consumer goods"]). +bgfact("Luxembourg","ImportPartners",["Belgium","FRG","France","US"]). +bgfact("Luxembourg","Industries",["banking","iron and steel","food = +processing","chemicals","metal = +products","engineering","tires","glass","aluminum"]). +bgfact("Luxembourg","Agriculture",["principal = +barley","oats","potatoes","wheat","fruits","cattle raising = +widespread"]). +bgfact("Macau","LandBounderies",["China"]). +bgfact("Macau","NaturalResources",["negligible"]). +bgfact("Macau","Population",["484557"]). +bgfact("Macau","Capital",["Macau"]). +bgfact("Macau","MemberOf",["ESCAP"]). +bgfact("Macau","ExportCommodities",["textiles","clothing","toys"]). +bgfact("Macau","ExportPartners",["US","Hong = +Kong","Germany","China","France"]). +bgfact("Macau","ImportCommodities",["raw = +materials","foodstuffs","Capital goods"]). +bgfact("Macau","ImportPartners",["Hong Kong","China","Japan"]). +bgfact("Macau","Industries",["clothing","textiles","toys","plastic = +products","furniture","tourism"]). +bgfact("Macau","Agriculture",["rice","food shortages - = +rice","vegetables","depends mostly on imports for food requirements"]). +bgfact("Madagascar","LandBounderies",[]). +bgfact("Madagascar","NaturalResources",["graphite","chromite","coal","bau= +xite","salt","quartz","tar sands","semiprecious stones","mica","fish"]). +bgfact("Madagascar","Population",["13427758"]). +bgfact("Madagascar","Capital",["Antananarivo"]). +bgfact("Madagascar","MemberOf",["ACCT","ACP","AfDB","CCC","ECA","FAO","G-= +77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IFAD","IFC","ILO","I= +MF","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","OAU","UN= +","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO"= +,"WTO"]). +bgfact("Madagascar","ExportCommodities",["coffee","vanilla","cloves","she= +llfish","sugar","petroleum products"]). +bgfact("Madagascar","ExportPartners",["France","Japan","Italy","Germany",= +"US"]). +bgfact("Madagascar","ImportCommodities",["intermediate = +manubgfactures","Capital goods","petroleum","consumer goods","food"]). +bgfact("Madagascar","ImportPartners",["France","Germany","UK","US"]). +bgfact("Madagascar","Industries",["agricultural = +processing","cement","automobile assembly plant","paper","petroleum"]). +bgfact("Madagascar","Agriculture",["coffee","vanilla","sugarcane","cloves= +","food rice","cassava","beans","bananas","almost self-sufficient in = +rice"]). +bgfact("Malawi","LandBounderies",["Mozambique","Tanzania","Zambia"]). +bgfact("Malawi","NaturalResources",["limestone","unexploited deposits of = +uranium","coal"]). +bgfact("Malawi","Population",["9732409"]). +bgfact("Malawi","Capital",["Lilongwe"]). +bgfact("Malawi","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","G-77","GA= +TT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT"= +,"INTERPOL","IOC","ISO","ITU","LORCS","NAM","OAU","SADC","UN","UNCTAD","U= +NESCO","UNIDO","UPU","WHO","WIPO","WMO","WTO"]). +bgfact("Malawi","ExportCommodities",["tobacco","tea","sugar","coffee","pe= +anuts","wood products"]). +bgfact("Malawi","ExportPartners",["US","UK","Zambia","South = +Africa","Germany"]). +bgfact("Malawi","ImportCommodities",["food","petroleum = +products","semimanubgfactures","consumer goods","transportation = +equipment"]). +bgfact("Malawi","ImportPartners",["South = +Africa","Japan","US","UK","Zimbabwe"]). +bgfact("Malawi","Industries",["agricultural = +processing","sawmilling","cement","consumer goods"]). +bgfact("Malawi","Agriculture",["tobacco","sugarcane","cotton","tea","subs= +istence potatoes","cassava","sorghum","livestock - cattle","goats"]). +bgfact("Malaysia","LandBounderies",["Brunei","Indonesia","Thailand"]). +bgfact("Malaysia","NaturalResources",["tin","petroleum","timber","copper"= +,"iron ore","natural gas","bauxite"]). +bgfact("Malaysia","Population",["19283157"]). +bgfact("Malaysia","Capital",["Kuala Lumpur"]). +bgfact("Malaysia","MemberOf",["APEC","AsDB","ASEAN","C","CCC","CP","ESCAP= +","FAO","G-15","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IDB","IF= +AD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","ISO",= +"ITU","LORCS","MINURSO","NAM","OIC","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNIKOM","UNOMOZ","UNOSOM","UNTAC","UPU","W= +CL","WHO","WIPO","WMO","WTO"]). +bgfact("Malaysia","ExportCommodities",["electronic equipment","petroleum = +and petroleum products","palm oil","wood and wood = +products","rubber","textiles"]). +bgfact("Malaysia","ExportPartners",["Singapore","US","Japan","UK","German= +y","Thailand"]). +bgfact("Malaysia","ImportCommodities",["machinery and = +equipment","chemicals","food","petroleum products"]). +bgfact("Malaysia","ImportPartners",["Japan","Singapore","US","Taiwan","Ge= +rmany","UK","Australia"]). +bgfact("Malaysia","Industries",[]). +bgfact("Malaysia","Agriculture",["accounts for of GDP"]). +bgfact("Maldives","LandBounderies",[]). +bgfact("Maldives","NaturalResources",["fish"]). +bgfact("Maldives","Population",["252077"]). +bgfact("Maldives","Capital",["Male"]). +bgfact("Maldives","MemberOf",["AsDB","C","CP","ESCAP","FAO","G-77","GATT"= +,"IBRD","ICAO","IDA","IDB","IFAD","IFC","IMF","IMO","INTELSAT","INTERPOL"= +,"IOC","ITU","NAM","OIC","SAARC","UN","UNCTAD","UNESCO","UNIDO","UPU","WH= +O","WIPO","WMO","WTO"]). +bgfact("Maldives","ExportCommodities",["fish","clothing"]). +bgfact("Maldives","ExportPartners",["US","UK","Sri Lanka"]). +bgfact("Maldives","ImportCommodities",["consumer goods","intermediate = +and Capital goods","petroleum products"]). +bgfact("Maldives","ImportPartners",["Singapore","Germany","Sri = +Lanka","India"]). +bgfact("Maldives","Industries",["fishing and fish = +processing","tourism","shipping","boat building","some coconut = +processing","garments","woven mats","coir","handicrafts"]). +bgfact("Maldives","Agriculture",["accounts for almost of GDP"]). +bgfact("Mali","LandBounderies",["Algeria","Burkina","Guinea","Cote = +d'Ivoire","Mauritania","Niger","Senegal"]). +bgfact("Mali","NaturalResources",["gold","phosphates","kaolin","salt","li= +mestone","uranium","bauxite","iron ore","manganese","tin"]). +bgfact("Mali","Population",["9112950"]). +bgfact("Mali","Capital",["Bamako"]). +bgfact("Mali","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOWAS"= +,"FAO","FZ","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IDB","IFAD"= +,"IFC","ILO","IMF","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM",= +"OAU","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL","WHO","WIPO= +","WMO","WTO"]). +bgfact("Mali","ExportCommodities",["cotton","livestock","gold"]). +bgfact("Mali","ExportPartners",["mostly franc zone and Western = +Europe"]). +bgfact("Mali","ImportCommodities",["machinery and = +equipment","foodstuffs","construction = +materials","petroleum","textiles"]). +bgfact("Mali","ImportPartners",["mostly franc zone and Western = +Europe"]). +bgfact("Mali","Industries",["small local consumer goods and = +processing","construction","phosphate","gold","fishing"]). +bgfact("Mali","Agriculture",["rice","corn","vegetables","livestock - = +cattle","sheep","goats"]). +bgfact("Malta","LandBounderies",[]). +bgfact("Malta","NaturalResources",["limestone","salt"]). +bgfact("Malta","Population",["366767"]). +bgfact("Malta","Capital",["Valletta"]). +bgfact("Malta","MemberOf",["C","CCC","CE","CSCE","EBRD","ECE","FAO","G-77= +","GATT","IBRD","ICAO","ICFTU","IFAD","ILO","IMF","IMO","INMARSAT","INTEL= +SAT","ITU","NAM","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","= +WIPO","WMO","WTO"]). +bgfact("Malta","ExportCommodities",["machinery and transport = +equipment","clothing and footware","printed matter"]). +bgfact("Malta","ExportPartners",["Italy","Germany","UK"]). +bgfact("Malta","ImportCommodities",["food","petroleum","machinery and = +semimanubgfactured goods"]). +bgfact("Malta","ImportPartners",["Italy","UK","Germany","US"]). +bgfact("Malta","Industries",["tourism","electronics","ship repair = +yard","construction","food = +manubgfacturing","textiles","footwear","clothing","beverages","tobacco"])= +. +bgfact("Malta","Agriculture",["overall","main = +potatoes","cauliflower","grapes","wheat","barley","tomatoes","citrus","cu= +t flowers","green peppers","hogs","poultry","generally adequate supplies = +of vegetables","poultry","milk","seasonal or periodic shortages in = +grain","animal fodder","fruits"]). +bgfact("Man, Isle of","LandBounderies",[]). +bgfact("Man, Isle of","NaturalResources",["lead","iron ore"]). +bgfact("Man, Isle of","Population",["72017"]). +bgfact("Man, Isle of","Capital",["Douglas"]). +bgfact("Man, Isle of","MemberOf",["none"]). +bgfact("Man, Isle of","ExportCommodities",["tweeds","herring","processed = +shellfish","meat"]). +bgfact("Man, Isle of","ExportPartners",["UK"]). +bgfact("Man, Isle = +of","ImportCommodities",["timber","fertilizers","fish"]). +bgfact("Man, Isle of","ImportPartners",["UK"]). +bgfact("Man, Isle of","Industries",["financial services","light = +manubgfacturing","tourism"]). +bgfact("Man, Isle = +of","Agriculture",["cattle","sheep","pigs","poultry"]). +bgfact("Marshall Islands","LandBounderies",[]). +bgfact("Marshall Islands","NaturalResources",["phosphate = +deposits","marine products","deep seabed minerals"]). +bgfact("Marshall Islands","Population",["54031"]). +bgfact("Marshall Islands","Capital",["Majuro"]). +bgfact("Marshall = +Islands","MemberOf",["AsDB","ESCAP","IBRD","ICAO","IDA","IFC","IMF","INTE= +LSAT","INTERPOL","SPARTECA","SPC","SPF","UN","UNCTAD","WHO"]). +bgfact("Marshall Islands","ExportCommodities",["coconut = +oil","fish","live animals","trichus shells"]). +bgfact("Marshall Islands","ExportPartners",["US","Japan","Australia"]). +bgfact("Marshall Islands","ImportCommodities",["foodstuffs","machinery = +and equipment","beverages and tobacco","fuels"]). +bgfact("Marshall Islands","ImportPartners",["US","Japan","Australia"]). +bgfact("Marshall Islands","Industries",["copra","fish","craft items from = +shell","wood","offshore banking"]). +bgfact("Marshall = +Islands","Agriculture",["coconuts","cacao","taro","breadfruit","fruits","= +pigs","chickens"]). +bgfact("Martinique","LandBounderies",[]). +bgfact("Martinique","NaturalResources",["coastal scenery and = +beaches","cultivable land"]). +bgfact("Martinique","Population",["392362"]). +bgfact("Martinique","Capital",["Fort-de-France"]). +bgfact("Martinique","MemberOf",["FZ","WCL","WFTU"]). +bgfact("Martinique","ExportCommodities",["refined petroleum = +products","bananas","rum","pineapples"]). +bgfact("Martinique","ExportPartners",["France","Guadeloupe","French = +Guiana"]). +bgfact("Martinique","ImportCommodities",["petroleum = +products","crude","foodstuffs","construction materials","vehicles"]). +bgfact("Martinique","ImportPartners",["France","UK","Italy","Germany","Ja= +pan","US"]). +bgfact("Martinique","Industries",["construction","rum","cement","oil = +refining","sugar","tourism"]). +bgfact("Martinique","Agriculture",["including fishing and = +forestry","principal = +pineapples","avocados","bananas","flowers","vegetables","dependent on = +imported food","particularly meat and vegetables"]). +bgfact("Mauritania","LandBounderies",["Algeria","Mali","Senegal","Western= + Sahara"]). +bgfact("Mauritania","NaturalResources",["iron = +ore","gypsum","fish","copper","phosphate"]). +bgfact("Mauritania","Population",["2192777"]). +bgfact("Mauritania","Capital",["Nouakchott"]). +bgfact("Mauritania","MemberOf",["ABEDA","ACCT","ACP","AfDB","AFESD","AL",= +"AMF","AMU","CAEU","CCC","CEAO","ECA","ECOWAS","FAO","G-77","GATT","IBRD"= +,"ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL",= +"IOC","ITU","LORCS","NAM","OAU","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU= +","WHO","WIPO","WMO","WTO"]). +bgfact("Mauritania","ExportCommodities",["iron ore","fish and fish = +products"]). +bgfact("Mauritania","ExportPartners",["Japan","Italy","Belgium","Luxembou= +rg"]). +bgfact("Mauritania","ImportCommodities",["foodstuffs","consumer = +goods","petroleum products","Capital goods"]). +bgfact("Mauritania","ImportPartners",["Algeria","China","US","France","Ge= +rmany","Spain","Italy"]). +bgfact("Mauritania","Industries",["fish processing","mining of iron ore = +and gypsum"]). +bgfact("Mauritania","Agriculture",["dates","millet","sorghum","large = +food deficit in years of drought"]). +bgfact("Mauritius","LandBounderies",[]). +bgfact("Mauritius","NaturalResources",["arable land","fish"]). +bgfact("Mauritius","Population",["1116923"]). +bgfact("Mauritius","Capital",["Port Louis"]). +bgfact("Mauritius","MemberOf",["ACCT","ACP","AfDB","C","CCC","ECA","FAO",= +"G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF"= +,"INMARSAT","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","= +OAU","PCA","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO"= +,"WMO","WTO"]). +bgfact("Mauritius","ExportCommodities",["textiles","sugar","light = +manubgfactures"]). +bgfact("Mauritius","ExportPartners",["EC and US have preferential = +treatment","EU","US"]). +bgfact("Mauritius","ImportCommodities",["manubgfactured goods","Capital = +equipment","foodstuffs","petroleum products","chemicals"]). +bgfact("Mauritius","ImportPartners",["EC","US","South Africa","Japan"]). +bgfact("Mauritius","Industries",["food processing","textiles","wearing = +apparel","chemicals","metal products","transport = +equipment","nonelectrical machinery","tourism"]). +bgfact("Mauritius","Agriculture",["corn","potatoes","bananas","pulses","c= +attle","goats","net food importer","especially rice and fish"]). +bgfact("Mayotte","LandBounderies",[]). +bgfact("Mayotte","NaturalResources",["negligible"]). +bgfact("Mayotte","Population",["93468"]). +bgfact("Mayotte","Capital",["Mamoutzou"]). +bgfact("Mayotte","MemberOf",["FZ"]). +bgfact("Mayotte","ExportCommodities",["ylang-ylang","vanilla"]). +bgfact("Mayotte","ExportPartners",["France","Comoros","Reunion"]). +bgfact("Mayotte","ImportCommodities",["building = +materials","transportation equipment","rice","clothing","flour"]). +bgfact("Mayotte","ImportPartners",["France","Kenya","South = +Africa","Pakistan"]). +bgfact("Mayotte","Industries",["newly created lobster and shrimp = +industry"]). +bgfact("Mayotte","Agriculture",["vanilla","ylang-ylang","coffee","imports= + major share of food needs"]). +bgfact("Mexico","LandBounderies",["Belize","Guatemala","US"]). +bgfact("Mexico","NaturalResources",["petroleum","silver","copper","gold",= +"lead","zinc","natural gas","timber"]). +bgfact("Mexico","Population",["92202199"]). +bgfact("Mexico","Capital",["Mexico"]). +bgfact("Mexico","MemberOf",["AG","OAS","OECD","ONUSAL","OPANAL","PCA","RG= +","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTI","WHO","WIPO","WMO","W= +TO"]). +bgfact("Mexico","ExportCommodities",["crude","oil = +products","coffee","silver","engines","motor = +vehicles","cotton","consumer electronics"]). +bgfact("Mexico","ExportPartners",["US","Japan","EC"]). +bgfact("Mexico","ImportCommodities",["metal-working machines","steel = +mill products","agricultural machinery","electrical equipment","car = +parts for assembly","repair parts for motor vehicles","aircraft"]). +bgfact("Mexico","ImportPartners",["US","Japan","EC"]). +bgfact("Mexico","Industries",["food and = +beverages","tobacco","chemicals","iron and = +steel","petroleum","mining","textiles","clothing","motor = +vehicles","consumer durables","tourism"]). +bgfact("Mexico","Agriculture",["major food = +corn","wheat","rice","cotton","coffee","fruit","tomatoes"]). +bgfact("Micronesia, Federated States of","LandBounderies",[]). +bgfact("Micronesia, Federated States = +of","NaturalResources",["forests","marine products","deep-seabed = +minerals"]). +bgfact("Micronesia, Federated States of","Population",["120347"]). +bgfact("Micronesia, Federated States of","Capital",["Kolonia"]). +bgfact("Micronesia, Federated States = +of","MemberOf",["AsDB","ESCAP","IBRD","ICAO","IDA","IFC","IMF","ITU","SPA= +RTECA","SPC","SPF","UN","UNCTAD","WHO"]). +bgfact("Micronesia, Federated States of","ExportCommodities",["copra"]). +bgfact("Micronesia, Federated States of","ExportPartners",["NA"]). +bgfact("Micronesia, Federated States of","ImportCommodities",["NA"]). +bgfact("Micronesia, Federated States of","ImportPartners",["NA"]). +bgfact("Micronesia, Federated States = +of","Industries",["tourism","construction","fish processing","craft = +items from shell","wood"]). +bgfact("Micronesia, Federated States of","Agriculture",["tropical fruits = +and vegetables","coconuts","cassava","sweet = +potatoes","pigs","chickens"]). +bgfact("Midway Islands","LandBounderies",[]). +bgfact("Midway Islands","NaturalResources",["fish","wildlife"]). +bgfact("Midway Islands","Population",["453"]). +bgfact("Midway Islands","Capital",["none; administered from Washington, = +DC"]). +bgfact("Moldova","LandBounderies",["Romania","Ukraine"]). +bgfact("Moldova","NaturalResources",["lignite","phosphorites","gypsum"]).= + +bgfact("Moldova","Population",["4473033"]). +bgfact("Moldova","Capital",["Chisinau"]). +bgfact("Moldova","MemberOf",["BSEC","CE","IOC","ITU","NACC","UN","UNCTAD"= +,"UNESCO","UNIDO","UPU","WHO","WIPO"]). +bgfact("Moldova","ExportCommodities",["foodstuffs","wine","tobacco","text= +iles and footwear","machinery","chemicals"]). +bgfact("Moldova","ExportPartners",["Russia","Kazakhstan","Ukraine","Roman= +ia","Germany"]). +bgfact("Moldova","ImportCommodities",["oil","gas","coal","steel = +machinery","foodstuffs","automobiles"]). +bgfact("Moldova","ImportPartners",["Russia","Ukraine","Uzbekistan","Roman= +ia","Germany"]). +bgfact("Moldova","Industries",["key products are canned = +food","agricultural machinery","foundry equipment","refrigerators and = +freezers","washing machines","hosiery","refined sugar","vegetable = +oil","shoes","textiles"]). +bgfact("Moldova","Agriculture",["products are = +vegetables","fruits","wine","grain","sugar beets","sunflower = +seed","meat","milk","tobacco"]). +bgfact("Monaco","LandBounderies",["France"]). +bgfact("Monaco","NaturalResources",["none"]). +bgfact("Monaco","Population",["31278"]). +bgfact("Monaco","Capital",["Monaco"]). +bgfact("Monaco","MemberOf",["ACCT","CSCE","ECE","IAEA","ICAO","IMF","IMO"= +,"INMARSAT","INTELSAT","INTERPOL","IOC","ITU","LORCS","UN","UNCTAD","UNES= +CO","UPU","WHO","WIPO"]). +bgfact("Monaco","Agriculture",["none"]). +bgfact("Mongolia","LandBounderies",["China","Russia"]). +bgfact("Mongolia","NaturalResources",["oil","coal","copper","molybdenum",= +"tungsten","phosphates","tin","nickel","zinc","wolfram","fluorspar","gold= +"]). +bgfact("Mongolia","Population",["2429762"]). +bgfact("Mongolia","Capital",["Ulaanbaatar"]). +bgfact("Mongolia","MemberOf",["AsDB","CCC","ESCAP","FAO","G-77","IAEA","I= +BRD","ICAO","IDA","IFC","ILO","IMF","INTELSAT","UN","UNCTAD","UNESCO","UN= +IDO","UPU","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Mongolia","ExportCommodities",["copper","livestock","animal = +products","cashmere","wool","hides","fluorspar"]). +bgfact("Mongolia","ExportPartners",["former CMEA = +countries","China","EC"]). +bgfact("Mongolia","ImportCommodities",["machinery and = +equipment","fuels","food products","industrial consumer = +goods","chemicals","building materials","sugar","tea"]). +bgfact("Mongolia","ImportPartners",["USSR","Austria","China"]). +bgfact("Mongolia","Industries",["copper","processing of animal = +products","building materials","food and beverage","mining"]). +bgfact("Mongolia","Agriculture",["wheat","barley","potatoes","forage"]). +bgfact("Montserrat","LandBounderies",[]). +bgfact("Montserrat","NaturalResources",["negligible"]). +bgfact("Montserrat","Population",["12701"]). +bgfact("Montserrat","Capital",["Plymouth"]). +bgfact("Montserrat","MemberOf",["CARICOM","CDB","ECLAC","OECS","WCL"]). +bgfact("Montserrat","ExportCommodities",["electronic parts","plastic = +bags","apparel","hot peppers","live plants","cattle"]). +bgfact("Montserrat","ExportPartners",["NA"]). +bgfact("Montserrat","ImportCommodities",["machinery and transportation = +equipment","foodstuffs","manubgfactured goods","fuels","lubricants"]). +bgfact("Montserrat","ImportPartners",["NA"]). +bgfact("Montserrat","Industries",["light manubgfacturing - = +rum","textiles","electronic appliances"]). +bgfact("Montserrat","Agriculture",["food tomatoes","onions","not = +self-sufficient in food","especially livestock products"]). +bgfact("Morocco","LandBounderies",["Algeria","Western Sahara"]). +bgfact("Morocco","NaturalResources",["phosphates","iron = +ore","manganese","lead","zinc","fish","salt"]). +bgfact("Morocco","Population",["28558635"]). +bgfact("Morocco","Capital",["Rabat"]). +bgfact("Morocco","MemberOf",["ABEDA","ACCT","NAM","OIC","UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNOSOM","UNTAC","UPU","WHO","WIPO"= +,"WMO","WTO"]). +bgfact("Morocco","ExportCommodities",["food and = +beverages","semiprocessed goods","consumer goods","phosphates"]). +bgfact("Morocco","ExportPartners",["EC","India","Japan","US"]). +bgfact("Morocco","ImportCommodities",["Capital goods","semiprocessed = +goods","raw materials","fuel and lubricants","food and = +beverages","consumer goods"]). +bgfact("Morocco","ImportPartners",["EC","US","Saudi = +Arabia","FSU","Japan"]). +bgfact("Morocco","Industries",["phosphate rock mining and = +processing","food processing","leather = +goods","textiles","construction","tourism"]). +bgfact("Morocco","Agriculture",["accounts for of GDP","of = +employment","barley","wheat","citrus = +fruit","wine","vegetables","olives"]). +bgfact("Mozambique","LandBounderies",["Malawi","South = +Africa","Swaziland","Tanzania","Zambia","Zimbabwe"]). +bgfact("Mozambique","NaturalResources",["coal","titanium"]). +bgfact("Mozambique","Population",["17346280"]). +bgfact("Mozambique","Capital",["Maputo"]). +bgfact("Mozambique","MemberOf",["ACP","AfDB","CCC","ECA","FAO","FLS","G-7= +7","GATT","IBRD","ICAO","IDA","IFAD","IFC","ILO","IMF","INMARSAT","IMO","= +INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","OIC","SADC","UN","U= +NCTAD","UNESCO","UNIDO","UPU","WHO","WMO"]). +bgfact("Mozambique","ExportCommodities",["shrimp","cashews","sugar","copr= +a","citrus"]). +bgfact("Mozambique","ExportPartners",["US","Western = +Europe","Germany","Japan"]). +bgfact("Mozambique","ImportCommodities",["food","clothing","farm = +equipment","petroleum"]). +bgfact("Mozambique","ImportPartners",["US","Western Europe","USSR"]). +bgfact("Mozambique","Industries",["food","beverages","chemicals","tobacco= +"]). +bgfact("Mozambique","Agriculture",["cotton","cashew = +nuts","sugarcane","tea","corn","rice","not self-sufficient in food"]). +bgfact("Namibia","LandBounderies",["Angola","Botswana","South = +Africa","Zambia"]). +bgfact("Namibia","NaturalResources",["diamonds","copper","uranium","gold"= +,"lead","tin","lithium","cadmium","zinc","salt","vanadium","natural = +gas","suspected deposits of oil","natural gas","coal","iron ore"]). +bgfact("Namibia","Population",["1595567"]). +bgfact("Namibia","Capital",["Windhoek"]). +bgfact("Namibia","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","FLS","G-= +77","GATT","IAEA","IBRD","ICAO","IFAD","IFC","ILO","IMF","INTELSAT","ITU"= +,"NAM","OAU","SACU","SADC","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","= +WCL","WFTU","WHO","WIPO","WMO"]). +bgfact("Namibia","ExportCommodities",["diamonds","copper","gold","zinc","= +lead","uranium","cattle","processed fish","karakul skins"]). +bgfact("Namibia","ExportPartners",["Switzerland","South = +Africa","Germany","Japan"]). +bgfact("Namibia","ImportCommodities",["foodstuffs","petroleum products = +and fuel","machinery and equipment"]). +bgfact("Namibia","ImportPartners",["South = +Africa","Germany","US","Switzerland"]). +bgfact("Namibia","Industries",["meatpacking","fish processing","dairy = +products","mining"]). +bgfact("Namibia","Agriculture",["millet","sorghum","fish catch = +potential of over million metric tons not being fulfilled","catch = +reaching only","not self-sufficient in food"]). +bgfact("Nauru","LandBounderies",[]). +bgfact("Nauru","NaturalResources",["phosphates"]). +bgfact("Nauru","Population",["10019"]). +bgfact("Nauru","Capital",["Yaren District"]). +bgfact("Nauru","MemberOf",["AsDB","C","INTERPOL","ITU","SPARTECA","SPC","= +SPF","UPU"]). +bgfact("Nauru","ExportCommodities",["phosphates"]). +bgfact("Nauru","ExportPartners",["Australia","NZ"]). +bgfact("Nauru","ImportCommodities",["food","fuel","manubgfactures","build= +ing materials","machinery"]). +bgfact("Nauru","ImportPartners",["Australia","UK","NZ","Japan"]). +bgfact("Nauru","Industries",["phosphate mining","financial = +services","coconut products"]). +bgfact("Nauru","Agriculture",["almost completely dependent on imports = +for food and water"]). +bgfact("Navassa Island","LandBounderies",[]). +bgfact("Navassa Island","NaturalResources",["guano"]). +bgfact("Navassa Island","Capital",["none; administered from Washington, = +DC"]). +bgfact("Nepal","LandBounderies",["China","India"]). +bgfact("Nepal","NaturalResources",["quartz","water","timber","hydroelectr= +ic potential","scenic beauty","small deposits of = +lignite","copper","cobalt","iron ore"]). +bgfact("Nepal","Population",["21041527"]). +bgfact("Nepal","Capital",["Kathmandu"]). +bgfact("Nepal","MemberOf",["AsDB","CCC","CP","ESCAP","FAO","G-77","IBRD",= +"ICAO","IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","= +ISO","ITU","LORCS","NAM","SAARC","UN","UNCTAD","UNESCO","UNIDO","UNIFIL",= +"UNPROFOR","UNTAC","UPU","WFTU","WHO","WMO","WTO"]). +bgfact("Nepal","ExportCommodities",["carpets","clothing","leather = +goods","jute goods","grain"]). +bgfact("Nepal","ExportPartners",["US","Germany","India","UK"]). +bgfact("Nepal","ImportCommodities",["petroleum = +products","fertilizer","machinery"]). +bgfact("Nepal","ImportPartners",["India","Singapore","Japan","Germany"]).= + +bgfact("Nepal","Industries",["small = +rice","jute","sugar","cigarette","textile","carpet","cement","tourism"]).= + +bgfact("Nepal","Agriculture",["farm = +rice","corn","wheat","sugarcane","root crops","milk","not = +self-sufficient in food","particularly in drought years"]). +bgfact("Netherlands","LandBounderies",["Belgium","Germany"]). +bgfact("Netherlands","NaturalResources",["natural = +gas","petroleum","fertile soil"]). +bgfact("Netherlands","Population",["15367928"]). +bgfact("Netherlands","Capital",["Amsterdam; The Hague is the seat of = +government"]). +bgfact("Netherlands","MemberOf",["AfDB","AG","OECD","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNHCR","UNIDO","UNOMUR","UNPROFOR","UNTAC","UNTSO"= +,"UPU","WCL","WEU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Netherlands","ExportCommodities",["metal = +products","chemicals","processed food and tobacco","agricultural = +products"]). +bgfact("Netherlands","ExportPartners",["EC"]). +bgfact("Netherlands","ImportCommodities",["raw materials and = +semifinished products","consumer goods","transportation = +equipment","crude","food products"]). +bgfact("Netherlands","ImportPartners",["EC"]). +bgfact("Netherlands","Industries",["agro Industries","metal and = +engineering products","electrical machinery and = +equipment","chemicals","petroleum","fishing","construction","microelectro= +nics"]). +bgfact("Netherlands","Agriculture",["grains","potatoes","sugar = +beets","fruits","shortages of grain","fats"]). +bgfact("Netherlands Antilles","LandBounderies",[]). +bgfact("Netherlands Antilles","NaturalResources",["phosphates"]). +bgfact("Netherlands Antilles","Population",["185790"]). +bgfact("Netherlands Antilles","Capital",["Willemstad"]). +bgfact("Netherlands Antilles","MemberOf",["CARICOM"]). +bgfact("Netherlands Antilles","ExportCommodities",["petroleum = +products"]). +bgfact("Netherlands = +Antilles","ExportPartners",["US","Brazil","Colombia"]). +bgfact("Netherlands Antilles","ImportCommodities",["crude = +petroleum","food","manubgfactures"]). +bgfact("Netherlands = +Antilles","ImportPartners",["Venezuela","US","Colombia","Netherlands","Ja= +pan"]). +bgfact("Netherlands Antilles","Industries",["tourism"]). +bgfact("Netherlands Antilles","Agriculture",["chief = +aloes","sorghum","peanuts","fresh vegetables","not self-sufficient in = +food"]). +bgfact("New Caledonia","LandBounderies",[]). +bgfact("New = +Caledonia","NaturalResources",["nickel","chrome","iron","cobalt","mangane= +se","silver","gold","lead","copper"]). +bgfact("New Caledonia","Population",["181309"]). +bgfact("New Caledonia","Capital",["Noumea"]). +bgfact("New = +Caledonia","MemberOf",["ESCAP","FZ","ICFTU","SPC","WFTU","WMO"]). +bgfact("New Caledonia","ExportCommodities",["nickel metal","nickel = +ore"]). +bgfact("New Caledonia","ExportPartners",["France","Japan","US"]). +bgfact("New = +Caledonia","ImportCommodities",["foods","fuels","minerals","machines","el= +ectrical equipment"]). +bgfact("New Caledonia","ImportPartners",["France","US","Australia"]). +bgfact("New Caledonia","Industries",["nickel mining and smelting"]). +bgfact("New = +Caledonia","Agriculture",["coffee","corn","wheat","self-sufficient in = +beef"]). +bgfact("New Zealand","LandBounderies",[]). +bgfact("New Zealand","NaturalResources",["natural gas","iron = +ore","sand","coal","timber","hydropower","gold","limestone"]). +bgfact("New Zealand","Population",["3388737"]). +bgfact("New Zealand","Capital",["Wellington"]). +bgfact("New = +Zealand","MemberOf",["ANZUS","OECD","PCA","SPARTECA","SPC","SPF","UN","UN= +AVEM = +II","UNCTAD","UNESCO","UNIDO","UNOSOM","UNPROFOR","UNTAC","UNTSO","UPU","= +WHO","WIPO","WMO"]). +bgfact("New = +Zealand","ExportCommodities",["wool","lamb","mutton","beef","fruit","fish= +","cheese","manubgfactures","chemicals","forestry products"]). +bgfact("New Zealand","ExportPartners",["Australia","Japan","US","South = +Korea"]). +bgfact("New Zealand","ImportCommodities",["petroleum","consumer = +goods","motor vehicles","industrial equipment"]). +bgfact("New = +Zealand","ImportPartners",["Australia","US","Japan","UK","Germany"]). +bgfact("New Zealand","Industries",["food processing","wood and paper = +products","textiles","machinery","transportation equipment","banking and = +insurance","tourism","mining"]). +bgfact("New Zealand","Agriculture",["livestock predominates - = +wool","meat","wheat","barley","potatoes","pulses","fruits","fish catch = +reached a record"]). +bgfact("Nicaragua","LandBounderies",["Costa Rica","Honduras"]). +bgfact("Nicaragua","NaturalResources",["gold","silver","copper","tungsten= +","lead","zinc","timber","fish"]). +bgfact("Nicaragua","Population",["4096689"]). +bgfact("Nicaragua","Capital",["Managua"]). +bgfact("Nicaragua","MemberOf",["BCIE","CACM","ECLAC","FAO","G-77","GATT",= +"IADB","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO",= +"INTELSAT","INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS","NAM","OAS"= +,"OPANAL","PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WCL","WFTU"= +,"WHO","WIPO","WMO","WTO"]). +bgfact("Nicaragua","ExportCommodities",["foodstuffs","cotton","coffee","c= +hemicals"]). +bgfact("Nicaragua","ExportPartners",["EC","US","Japan","Costa Rica","El = +Salvador","Mexico"]). +bgfact("Nicaragua","ImportCommodities",["petroleum","food","chemicals","m= +achinery","clothing"]). +bgfact("Nicaragua","ImportPartners",["US","Venezuela","Costa = +Rica","EC","Guatemala"]). +bgfact("Nicaragua","Industries",["food processing","chemicals","metal = +products","textiles","clothing","petroleum refining and = +distribution","beverages","footwear"]). +bgfact("Nicaragua","Agriculture",["export = +coffee","bananas","sugarcane","food rice","corn","cassava","citrus = +fruit","also produces a variety of animal = +beef","veal","pork","poultry","normally self-sufficient in food"]). +bgfact("Niger","LandBounderies",["Algeria","Benin","Burkina","Chad","Liby= +a","Mali","Nigeria"]). +bgfact("Niger","NaturalResources",["uranium","coal","iron = +ore","tin","phosphates"]). +bgfact("Niger","Population",["8971605"]). +bgfact("Niger","Capital",["Niamey"]). +bgfact("Niger","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOWAS= +","Entente","FAO","FZ","G-77","GATT","IAEA","IBRD","ICAO","IDA","IDB","IF= +AD","IFC","ILO","IMF","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OA= +U","OIC","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL","WHO","WIPO","= +WMO","WTO"]). +bgfact("Niger","ExportCommodities",["uranium ore","livestock = +products","cowpeas","onions"]). +bgfact("Niger","ExportPartners",["France","Nigeria","Cote = +d'Ivoire","Italy"]). +bgfact("Niger","ImportCommodities",["primary = +materials","machinery","vehicles and parts","electronic = +equipment","cereals","petroleum products","pharmaceuticals","chemical = +products","foodstuffs"]). +bgfact("Niger","ImportPartners",["Germany","Cote = +d'Ivoire","France","Italy","Nigeria"]). +bgfact("Niger","Industries",["cement","brick","textiles","food = +processing","chemicals","slaughterhouses","uranium mining began in"]). +bgfact("Niger","Agriculture",["cowpeas","cotton","food = +millet","sorghum","cassava","livestock - = +cattle","sheep","self-sufficient in food except in drought years"]). +bgfact("Nigeria","LandBounderies",["Benin","Cameroon","Chad","Niger"]). +bgfact("Nigeria","NaturalResources",["petroleum","tin","columbite","iron = +ore","coal","limestone","lead","zinc","natural gas"]). +bgfact("Nigeria","Population",["98091097"]). +bgfact("Nigeria","Capital",["Abuja"]). +bgfact("Nigeria","MemberOf",["ACP","AfDB","C","CCC","ECA","ECOWAS","FAO",= +"G-15","G-19","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICC","IDA","IFAD= +","IFC","ILO","IMO","IMF","INMARSAT","INTELSAT","INTERPOL","IOC","ITU","L= +ORCS","MINURSO","NAM","OAU","OIC","OPEC","PCA","UN","UNAVEM","UNCTAD","UN= +ESCO","UNHCR","UNIDO","UNIKOM","UNPROFOR","UNTAC","UPU","WCL","WHO","WMO"= +,"WTO"]). +bgfact("Nigeria","ExportCommodities",["oil","cocoa","rubber"]). +bgfact("Nigeria","ExportPartners",["US","EC"]). +bgfact("Nigeria","ImportCommodities",["machinery and = +equipment","manubgfactured goods","food and animals"]). +bgfact("Nigeria","ImportPartners",["EC","US","Japan"]). +bgfact("Nigeria","Industries",["crude","coal","tin","palm = +oil","peanut","cotton","rubber","wood","textiles","cement","building = +materials","food = +products","footwear","chemical","printing","ceramics","steel"]). +bgfact("Nigeria","Agriculture",["cocoa","peanuts","palm = +oil","corn","rice","sorghum","millet","cassava","livestock - = +cattle","sheep","goats","fishing and forestry resources extensively = +exploited"]). +bgfact("Niue","LandBounderies",[]). +bgfact("Niue","NaturalResources",["fish","arable land"]). +bgfact("Niue","Population",["1906"]). +bgfact("Niue","Capital",["Alofi"]). +bgfact("Niue","MemberOf",["ESCAP","SPARTECA","SPC","SPF"]). +bgfact("Niue","ExportCommodities",["canned coconut = +cream","copra","honey","passion fruit products","pawpaw","root = +crops","limes","footballs","stamps","handicrafts"]). +bgfact("Niue","ExportPartners",["NZ","Fiji","Cook = +Islands","Australia"]). +bgfact("Niue","ImportCommodities",["food","live animals","manubgfactured = +goods","machinery","fuels","lubricants","chemicals","drugs"]). +bgfact("Niue","ImportPartners",["NZ","Fiji","Japan","Western = +Samoa","Australia","US"]). +bgfact("Niue","Industries",["tourist","handicrafts","coconut = +products"]). +bgfact("Niue","Agriculture",["coconuts","passion = +fruit","honey","subsistence = +taro","yams","cassava","pigs","poultry","beef cattle"]). +bgfact("Norfolk Island","LandBounderies",[]). +bgfact("Norfolk Island","NaturalResources",["fish"]). +bgfact("Norfolk Island","Population",["2710"]). +bgfact("Norfolk Island","Capital",["Kingston"]). +bgfact("Norfolk Island","MemberOf",["none"]). +bgfact("Norfolk Island","ExportCommodities",["postage stamps","seeds of = +the Norfolk Island pine and Kentia palm","small quantities of = +avocados"]). +bgfact("Norfolk Island","ExportPartners",["Australia","Pacific = +Islands","NZ","Asia","Europe"]). +bgfact("Norfolk Island","ImportCommodities",["NA"]). +bgfact("Norfolk Island","ImportPartners",["Australia","Pacific = +Islands","NZ","Asia","Europe"]). +bgfact("Norfolk Island","Industries",["tourism"]). +bgfact("Norfolk Island","Agriculture",["Norfolk Island pine = +seed","Kentia palm = +seed","cereals","vegetables","fruit","cattle","poultry"]). +bgfact("Northern Mariana Islands","LandBounderies",[]). +bgfact("Northern Mariana Islands","NaturalResources",["arable = +land","fish"]). +bgfact("Northern Mariana Islands","Population",["49799"]). +bgfact("Northern Mariana Islands","Capital",["Saipan"]). +bgfact("Northern Mariana Islands","MemberOf",["ESCAP","SPC"]). +bgfact("Northern Mariana Islands","ExportCommodities",["manubgfactured = +goods","garments","bread","pastries","concrete blocks","light iron = +work"]). +bgfact("Northern Mariana Islands","ExportPartners",["NA"]). +bgfact("Northern Mariana = +Islands","ImportCommodities",["food","construction","equipment","material= +s"]). +bgfact("Northern Mariana Islands","ImportPartners",["NA"]). +bgfact("Northern Mariana = +Islands","Industries",["tourism","construction","light = +industry","handicrafts"]). +bgfact("Northern Mariana = +Islands","Agriculture",["coconuts","fruits","cattle","vegetables"]). +bgfact("Norway","LandBounderies",["Finland","Sweden","Russia"]). +bgfact("Norway","NaturalResources",["petroleum","copper","natural = +gas","pyrites","nickel","iron = +ore","zinc","lead","fish","timber","hydropower"]). +bgfact("Norway","Population",["4314604"]). +bgfact("Norway","Capital",["Oslo"]). +bgfact("Norway","MemberOf",["AfDB","AsDB","Australia = +Group","BIS","CBSS","CCC","CE","CERN","COCOM","CSCE","EBRD","ECE","EFTA",= +"ESA","FAO","GATT","IADB","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IEA",= +"IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IO= +M","ISO","ITU","LORCS","MTCR","NACC","NAM","WHO","WIPO","WMO","ZC"]). +bgfact("Norway","ExportCommodities",["petroleum and petroleum = +products","metals and products","fish and fish = +products","chemicals","natural gas","ships"]). +bgfact("Norway","ExportPartners",["EC","Nordic countries","developing = +countries","US","Japan"]). +bgfact("Norway","ImportCommodities",["machinery and = +equipment","manubgfactured consumer goods","foodstuffs"]). +bgfact("Norway","ImportPartners",["EC","Nordic countries","developing = +countries","US","Japan"]). +bgfact("Norway","Industries",["petroleum and gas","food = +processing","shipbuilding","pulp and paper = +products","metals","chemicals","timber","mining","textiles","fishing"]). +bgfact("Norway","Agriculture",["fish catch of million metric tons in"]). +bgfact("Oman","LandBounderies",["Saudi Arabia","UAE","Yemen"]). +bgfact("Oman","NaturalResources",["petroleum","copper","asbestos","some = +marble","limestone","chromium","gypsum","natural gas"]). +bgfact("Oman","Population",["1701470"]). +bgfact("Oman","Capital",["Muscat"]). +bgfact("Oman","MemberOf",["ABEDA","AFESD","AL","AMF","ESCWA","FAO","G-77"= +,"GCC","IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","IMO","INMARSAT= +","INTELSAT","INTERPOL","IOC","ISO","ITU","NAM","OIC","UN","UNCTAD","UNES= +CO","UNIDO","UPU","WFTU","WHO","WMO"]). +bgfact("Oman","ExportCommodities",["petroleum","re-exports","fish","proce= +ssed copper","textiles"]). +bgfact("Oman","ExportPartners",["UAE","Japan","South = +Korea","Singapore"]). +bgfact("Oman","ImportCommodities",["machinery","transportation = +equipment","manubgfactured goods","food","livestock","lubricants"]). +bgfact("Oman","ImportPartners",["Japan","UAE","UK","US"]). +bgfact("Oman","Industries",["crude production and refining","natural gas = +production","construction","cement","copper"]). +bgfact("Oman","Agriculture",["annual fish catch averages"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","LandBounderies",[]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","NaturalResources",["forests","minerals","marine = +products","deep-seabed minerals"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","Population",["16366"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","Capital",["Koror"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","MemberOf",["ESCAP"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","ExportCommodities",["trochus","tuna","copra","handicrafts"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","ExportPartners",["US","Japan"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","ImportCommodities",["NA"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","ImportPartners",["US"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","Industries",["tourism","craft items","Agriculture"]). +bgfact("Pacific Islands (Palau), Trust Territory of = +the","Agriculture",["coconut","copra","cassava","sweet potatoes"]). +bgfact("Pacific Ocean","NaturalResources",["oil and gas = +fields","polymetallic nodules","sand and gravel aggregates","placer = +deposits","fish"]). +bgfact("Pacific Ocean","Industries",["fishing","oil and gas = +production"]). +bgfact("Pakistan","LandBounderies",["Afghanistan","China","India","Iran"]= +). +bgfact("Pakistan","NaturalResources",["land","extensive natural gas = +reserves","limited petroleum","poor quality coal","iron = +ore","copper","salt","limestone"]). +bgfact("Pakistan","Population",["128855965"]). +bgfact("Pakistan","Capital",["Islamabad"]). +bgfact("Pakistan","MemberOf",["AsDB","C","CCC","CP","ECO","ESCAP","FAO","= +G-19","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IDB"= +,"IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","I= +OM","ISO","ITU","LORCS","MINURSO","NAM","OAS","OIC","PCA","SAARC","UN","U= +NCTAD","UNESCO","UNHCR","UNIDO","UNIKOM","UNOSOM","UNTAC","UPU","WCL","WF= +TU","WHO","WIPO","WMO","WTO"]). +bgfact("Pakistan","ExportCommodities",["cotton","textiles","clothing","ri= +ce","leather","carpets"]). +bgfact("Pakistan","ExportPartners",["US","Japan","Hong = +Kong","Germany","UK"]). +bgfact("Pakistan","ImportCommodities",["petroleum","petroleum = +products","machinery","transportation equipment","vegetable = +oils","animal fats","chemicals"]). +bgfact("Pakistan","ImportPartners",["Japan","US","Germany","UK","Saudi = +Arabia"]). +bgfact("Pakistan","Industries",["textiles","food = +processing","beverages","construction materials","clothing","paper = +products","shrimp"]). +bgfact("Pakistan","Agriculture",["of GDP","major = +cotton","wheat","rice","sugarcane","fruits","livestock = +milk","beef","mutton","self-sufficient in food grain"]). +bgfact("Palmyra Atoll","LandBounderies",[]). +bgfact("Palmyra Atoll","NaturalResources",["none"]). +bgfact("Palmyra Atoll","Capital",["none; administered from Washington, = +DC"]). +bgfact("Panama","LandBounderies",["Colombia","Costa Rica"]). +bgfact("Panama","NaturalResources",["copper","mahogany = +forests","shrimp"]). +bgfact("Panama","Population",["63"]). +bgfact("Panama","Capital",["Panama"]). +bgfact("Panama","MemberOf",["AG","LORCS","NAM","OAS","OPANAL","PCA","UN",= +"UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Panama","ExportCommodities",["bananas","shrimp","sugar","clothing= +","coffee"]). +bgfact("Panama","ExportPartners",["US","EC","Central America and = +Caribbean"]). +bgfact("Panama","ImportCommodities",["Capital = +goods","crude","foodstuffs","consumer goods","chemicals"]). +bgfact("Panama","ImportPartners",["US","EC","Central America and = +Caribbean","Japan"]). +bgfact("Panama","Industries",["manubgfacturing and construction = +activities","petroleum refining","brewing","sugar milling"]). +bgfact("Panama","Agriculture",["crops - = +bananas","rice","corn","coffee","importer of food = +grain","vegetables"]). +bgfact("Papua New Guinea","LandBounderies",["Indonesia"]). +bgfact("Papua New = +Guinea","NaturalResources",["gold","copper","silver","natural = +gas","timber","oil potential"]). +bgfact("Papua New Guinea","Population",["4196806"]). +bgfact("Papua New Guinea","Capital",["Port Moresby"]). +bgfact("Papua New = +Guinea","MemberOf",["ACP","APEC","AsDB","ASEAN","ITU","LORCS","NAM","SPAR= +TECA","SPC","SPF","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WMO"= +]). +bgfact("Papua New Guinea","ExportCommodities",["gold","copper = +ore","oil","logs","palm oil","coffee","cocoa","lobster"]). +bgfact("Papua New Guinea","ExportPartners",["Australia","Japan","South = +Korea","UK","US"]). +bgfact("Papua New Guinea","ImportCommodities",["machinery and transport = +equipment","manubgfactured goods","food","fuels","chemicals"]). +bgfact("Papua New = +Guinea","ImportPartners",["Australia","Japan","US","Singapore","New = +Zealand","UK"]). +bgfact("Papua New Guinea","Industries",["copra crushing","palm oil = +processing","plywood production","wood chip production","mining of = +gold","silver","construction","tourism"]). +bgfact("Papua New = +Guinea","Agriculture",["coffee","cocoa","coconuts","rubber","sweet = +potatoes","fruit","vegetables","poultry","net importer of food for urban = +centers"]). +bgfact("Paracel Islands","LandBounderies",[]). +bgfact("Paracel Islands","NaturalResources",["none"]). +bgfact("Paraguay","LandBounderies",["Argentina","Bolivia","Brazil"]). +bgfact("Paraguay","NaturalResources",["hydropower","timber","iron = +ore","manganese","limestone"]). +bgfact("Paraguay","Population",["5213772"]). +bgfact("Paraguay","Capital",["Asuncion"]). +bgfact("Paraguay","MemberOf",["AG","CCC","ECLAC","FAO","G-77","GATT","IAD= +B","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO","INT= +ELSAT","INTERPOL","IOC","IOM","ITU","LAES","LAIA","LORCS","MERCOSUR","OAS= +","OPANAL","PCA","RG","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","W= +IPO","WMO","WTO"]). +bgfact("Paraguay","ExportCommodities",["cotton","soybean","timber","veget= +able oils","meat products","coffee","tung oil"]). +bgfact("Paraguay","ExportPartners",["EC","Brazil","Argentina","Chile","US= +"]). +bgfact("Paraguay","ImportCommodities",["Capital = +goods","foodstuffs","consumer goods","raw materials","fuels"]). +bgfact("Paraguay","ImportPartners",["Brazil","EC","US","Argentina","Japan= +"]). +bgfact("Paraguay","Industries",["meat packing","oilseed = +crushing","milling","brewing","textiles","cement","construction"]). +bgfact("Paraguay","Agriculture",["cotton","sugarcane","wheat","tobacco","= +cassava","fruits","animal beef","pork","eggs","self-sufficient in most = +foods"]). +bgfact("Peru","LandBounderies",["Bolivia","Brazil","Chile","Colombia","Ec= +uador"]). +bgfact("Peru","NaturalResources",["copper","silver","gold","petroleum","t= +imber","fish","iron ore","coal","phosphate","potash"]). +bgfact("Peru","Population",["23650671"]). +bgfact("Peru","Capital",["Lima"]). +bgfact("Peru","MemberOf",["AG","CCC","ECLAC","FAO","G-11","G-15","G-19","= +G-24","G-77","GATT","IADB","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC= +","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","ISO","U= +N","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]= +). +bgfact("Peru","ExportCommodities",["copper","zinc","fishmeal","crude = +petroleum and byproducts","lead","refined silver","coffee","cotton"]). +bgfact("Peru","ExportPartners",["US","Japan","Italy","Germany"]). +bgfact("Peru","ImportCommodities",["machinery","transport = +equipment","foodstuffs","petroleum","iron and = +steel","chemicals","pharmaceuticals"]). +bgfact("Peru","ImportPartners",["US","Colombia","Argentina","Japan","Germ= +any","Brazil"]). +bgfact("Peru","Industries",["mining of = +metals","petroleum","fishing","textiles","clothing","food = +processing","cement","auto assembly","steel","shipbuilding","metal = +fabrication"]). +bgfact("Peru","Agriculture",["accounts for of GDP","commercial = +coffee","cotton","wheat","potatoes","plantains","animal poultry","red = +meats","dairy","fish catch of million metric tons"]). +bgfact("Philippines","LandBounderies",[]). +bgfact("Philippines","NaturalResources",["timber","petroleum","nickel","c= +obalt","silver","gold","salt","copper"]). +bgfact("Philippines","Population",["69808930"]). +bgfact("Philippines","Capital",["Manila"]). +bgfact("Philippines","MemberOf",["APEC","AsDB","ASEAN","CCC","CP","ESCAP"= +,"FAO","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IF= +C","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","ISO","= +ITU","LORCS","NAM","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNTAC","UPU","= +WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Philippines","ExportCommodities",["electronics","textiles","cocon= +ut products","cooper","fish"]). +bgfact("Philippines","ExportPartners",["US","Japan","Germany","UK","Hong = +Kong"]). +bgfact("Philippines","ImportCommodities",["raw materials","Capital = +goods","petroleum products"]). +bgfact("Philippines","ImportPartners",["Japan","US","Taiwan","Saudi = +Arabia","Hong Kong","South Korea"]). +bgfact("Philippines","Industries",["textiles","pharmaceuticals","chemical= +s","wood products","food processing","electronics assembly","petroleum = +refining","fishing"]). +bgfact("Philippines","Agriculture",["major = +rice","coconuts","corn","sugarcane","bananas","pineapples","animal = +pork","eggs","fish catch of million metric tons annually"]). +bgfact("Pitcairn Islands","LandBounderies",[]). +bgfact("Pitcairn Islands","NaturalResources",["miro trees","fish"]). +bgfact("Pitcairn Islands","Population",["71"]). +bgfact("Pitcairn Islands","Capital",["Adamstown"]). +bgfact("Pitcairn Islands","MemberOf",["SPC"]). +bgfact("Pitcairn = +Islands","ExportCommodities",["fruits","vegetables","curios"]). +bgfact("Pitcairn Islands","ExportPartners",["NA"]). +bgfact("Pitcairn Islands","ImportCommodities",["fuel = +oil","machinery","building materials","flour","sugar"]). +bgfact("Pitcairn Islands","ImportPartners",["NA"]). +bgfact("Pitcairn Islands","Industries",["postage stamp = +sales","handicrafts"]). +bgfact("Pitcairn Islands","Agriculture",["must import grain products"]). +bgfact("Poland","LandBounderies",["Belarus","Czech = +Republic","Germany","Lithuania","Russia","Slovakia","Ukraine"]). +bgfact("Poland","NaturalResources",["coal","sulfur","copper","natural = +gas","silver","lead","salt"]). +bgfact("Poland","Population",["38654561"]). +bgfact("Poland","Capital",["Warsaw"]). +bgfact("Poland","MemberOf",["BIS","BSEC","PCA","UN","UNCTAD","UNESCO","UN= +DOF","UNIDO","UNIFIL","UNIKOM","UNOMIG","UNPROFOR","UNTAC","UPU","WCL","W= +FTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Poland","ExportCommodities",["machinery","metals","chemicals","fu= +els and power","food"]). +bgfact("Poland","ExportPartners",["Germany","Netherlands","Italy","Russia= +"]). +bgfact("Poland","ImportCommodities",["fuels and = +power","machinery","chemicals","food"]). +bgfact("Poland","ImportPartners",["Germany","Russia","Italy","UK"]). +bgfact("Poland","Industries",["machine building","iron and = +steel","extractive Industries","chemicals","shipbuilding","food = +processing","glass","beverages","textiles"]). +bgfact("Poland","Agriculture",["of output from private farms","leading = +European producer of rye","rapeseed","normally self-sufficient in = +food"]). +bgfact("Portugal","LandBounderies",["Spain"]). +bgfact("Portugal","NaturalResources",["fish","forests","tungsten","iron = +ore","uranium ore","marble"]). +bgfact("Portugal","Population",["10524210"]). +bgfact("Portugal","Capital",["Lisbon"]). +bgfact("Portugal","MemberOf",["AfDB","Australian = +Group","BIS","CCC","CE","CERN","COCOM","CSCE","EBRD","EC","ECE","ECLAC","= +EIB","FAO","GATT","IADB","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IEA","= +IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","IOM= +","ISO","ITU","LAIA","OECD","PCA","UN","UNCTAD","UNESCO","UNIDO","UNOMOZ"= +,"UNPROFOR","UPU","WCL","WEU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Portugal","ExportCommodities",["cotton textiles","cork and paper = +products","canned fish","wine","timber and timber = +products","resin","machinery","appliances"]). +bgfact("Portugal","ExportPartners",["EC","US"]). +bgfact("Portugal","ImportCommodities",["machinery and transport = +equipment","agricultural products","chemicals","petroleum","textiles"]). +bgfact("Portugal","ImportPartners",["EC","US"]). +bgfact("Portugal","Industries",["wood pulp","paper","tourism"]). +bgfact("Portugal","Agriculture",["small","major = +grain","potatoes","olives","livestock sector - = +sheep","cattle","goats","poultry","meat","dairy products"]). +bgfact("Puerto Rico","LandBounderies",[]). +bgfact("Puerto Rico","NaturalResources",["some copper and = +nickel","potential for onshore and offshore crude"]). +bgfact("Puerto Rico","Population",["3801977"]). +bgfact("Puerto Rico","Capital",["San Juan"]). +bgfact("Puerto Rico","MemberOf",["CARICOM"]). +bgfact("Puerto = +Rico","ExportCommodities",["pharmaceuticals","electronics","apparel","can= +ned tuna","rum","beverage concentrates","medical = +equipment","instruments"]). +bgfact("Puerto Rico","ExportPartners",["US"]). +bgfact("Puerto = +Rico","ImportCommodities",["chemicals","clothing","food","fish","petroleu= +m products"]). +bgfact("Puerto Rico","ImportPartners",["US"]). +bgfact("Puerto Rico","Industries",["manubgfacturing accounts for of GDP: = +manubgfacturing of pharmaceuticals","electronics","apparel","food = +products","tourism"]). +bgfact("Puerto Rico","Agriculture",["accounts for only of labor force = +and less than of GDP: = +sugarcane","coffee","pineapples","plantains","livestock - = +cattle","imports a large share of food needs"]). +bgfact("Qatar","LandBounderies",["Saudi Arabia"]). +bgfact("Qatar","NaturalResources",["petroleum","natural gas","fish"]). +bgfact("Qatar","Population",["512779"]). +bgfact("Qatar","Capital",["Doha"]). +bgfact("Qatar","MemberOf",["ABEDA","AFESD","AL","AMF","CCC","ESCWA","FAO"= +,"G-77","GCC","IAEA","IBRD","ICAO","IDB","IFAD","ILO","IMF","IMO","INMARS= +AT","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAPEC","OIC","OPEC",= +"UN","UNCTAD","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Qatar","ExportCommodities",["petroleum = +products","steel","fertilizers"]). +bgfact("Qatar","ExportPartners",["Japan","Brazil","South = +Korea","UAE","Singapore"]). +bgfact("Qatar","ImportCommodities",["machinery and equipment","consumer = +goods","food","chemicals"]). +bgfact("Qatar","ImportPartners",["Japan","UK","US","Germany","France"]). +bgfact("Qatar","Industries",["crude production and = +refining","fertilizers","petrochemicals","steel","cement"]). +bgfact("Qatar","Agriculture",["farming and grazing on small scale","most = +food imported"]). +bgfact("Reunion","LandBounderies",[]). +bgfact("Reunion","NaturalResources",["fish","arable land"]). +bgfact("Reunion","Population",["652857"]). +bgfact("Reunion","Capital",["Saint-Denis"]). +bgfact("Reunion","MemberOf",["FZ","WFTU"]). +bgfact("Reunion","ExportCommodities",["sugar","rum and = +molasses","perfume essences","lobster","vanilla and tea"]). +bgfact("Reunion","ExportPartners",["France","Mauritius","Bahrain","South = +Africa","Italy"]). +bgfact("Reunion","ImportCommodities",["manubgfactured = +goods","food","beverages","tobacco","machinery and transportation = +equipment","raw materials"]). +bgfact("Reunion","ImportPartners",["France","Mauritius","Bahrain","South = +Africa","Italy"]). +bgfact("Reunion","Industries",["sugar","rum","cigarettes","several small = +shops producing handicraft items"]). +bgfact("Reunion","Agriculture",["sugarcane","vanilla","food tropical = +fruits","vegetables","imports large share of food needs"]). +bgfact("Romania","LandBounderies",["Bulgaria","Hungary","Moldova","Serbia= + and Montenegro"]). +bgfact("Romania","NaturalResources",["petroleum","timber","natural = +gas","coal","iron ore","salt"]). +bgfact("Romania","Population",["23181415"]). +bgfact("Romania","Capital",["Bucharest"]). +bgfact("Romania","MemberOf",["ACCT","PCA","UN","UNCTAD","UNESCO","UNIDO",= +"UNIKOM","UNOSOM","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Romania","ExportCommodities",["metals and metal = +products","mineral products","textiles","electric machines and = +equipment","transport materials"]). +bgfact("Romania","ExportPartners",["EC","developing countries","East and = +Central Europe","EFTA","Russia","Japan","US"]). +bgfact("Romania","ImportCommodities",["minerals","machinery and = +equipment","textiles","agricultural goods"]). +bgfact("Romania","ImportPartners",["EC","East and Central = +Europe","developing countries","Russia","EFTA","US","Japan"]). +bgfact("Romania","Industries",["mining","timber","construction = +materials","metallurgy","chemicals","machine building","food = +processing","petroleum production and refining"]). +bgfact("Romania","Agriculture",["sunflower = +seed","potatoes","milk","eggs","meat","grapes"]). +bgfact("Russia","LandBounderies",["Azerbaijan","Belarus","China","Ukraine= +"]). +bgfact("Russia","NaturalResources",["wide natural resource base = +including major deposits of oil","natural gas","coal","timber"]). +bgfact("Russia","Population",["149608953"]). +bgfact("Russia","Capital",["Moscow"]). +bgfact("Russia","MemberOf",["BSEC","CBSS","CCC","CE","PCA","UN","UNCTAD",= +"UNESCO","UNIDO","UNIKOM","UNOMOZ","UNPROFOR","UN Security = +Council","UNTAC","UN Trusteeship = +Council","UNTSO","UPU","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("Russia","ExportCommodities",["petroleum and petroleum = +products","natural gas","wood and wood products","metals","chemicals"]). +bgfact("Russia","ExportPartners",["Europe","North = +America","Japan","Third World countries","Cuba"]). +bgfact("Russia","ImportCommodities",["machinery and = +equipment","chemicals","consumer = +goods","grain","meat","sugar","semifinished metal products"]). +bgfact("Russia","ImportPartners",["Europe","North = +America","Japan","Third World countries","Cuba"]). +bgfact("Russia","Industries",["coal","oil","gas","chemicals","agricultura= +l machinery","tractors","consumer durables"]). +bgfact("Russia","Agriculture",["grain","sugar beet","sunflower = +seeds","meat","milk","vegetables","cotton","tea"]). +bgfact("Rwanda","LandBounderies",["Burundi","Tanzania","Uganda","Zaire"])= +. +bgfact("Rwanda","NaturalResources",["gold","cassiterite","natural = +gas","hydropower"]). +bgfact("Rwanda","Population",["8373963"]). +bgfact("Rwanda","Capital",["Kigali"]). +bgfact("Rwanda","MemberOf",["ACCT","ACP","AfDB","ECA","CCC","CEEAC","CEPG= +L","FAO","G-77","GATT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IM= +F","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","UN","UNCTAD","U= +NESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Rwanda","ExportCommodities",["coffee","tea","cassiterite","wolfra= +mite","pyrethrum"]). +bgfact("Rwanda","ExportPartners",["Germany","Belgium","Italy","Uganda","U= +K","France","US"]). +bgfact("Rwanda","ImportCommodities",["textiles","foodstuffs","machines = +and equipment","Capital goods","steel","petroleum products","cement and = +construction material"]). +bgfact("Rwanda","ImportPartners",["US","Belgium","Germany","Kenya","Japan= +"]). +bgfact("Rwanda","Industries",["mining of = +cassiterite","tin","cement","agricultural processing","small-scale = +beverage production","soap","furniture","shoes","plastic = +goods","textiles","cigarettes"]). +bgfact("Rwanda","Agriculture",["coffee","tea","bananas","beans","sorghum"= +]). +bgfact("Saint Helena","LandBounderies",[]). +bgfact("Saint Helena","NaturalResources",["no minerals"]). +bgfact("Saint Helena","Population",["6741"]). +bgfact("Saint Helena","Capital",["Jamestown"]). +bgfact("Saint Helena","MemberOf",["ICFTU"]). +bgfact("Saint Helena","ExportCommodities",["fish","handicrafts"]). +bgfact("Saint Helena","ExportPartners",["South Africa","UK"]). +bgfact("Saint = +Helena","ImportCommodities",["food","beverages","tobacco","fuel = +oils","animal feed","building materials","motor vehicles and = +parts","machinery and parts"]). +bgfact("Saint Helena","ImportPartners",["UK","South Africa"]). +bgfact("Saint Helena","Industries",["crafts","fishing"]). +bgfact("Saint Helena","Agriculture",["maize","potatoes","crawfishing on = +Tristan da Cunha"]). +bgfact("Saint Kitts and Nevis","LandBounderies",[]). +bgfact("Saint Kitts and Nevis","NaturalResources",["negligible"]). +bgfact("Saint Kitts and Nevis","Population",["40671"]). +bgfact("Saint Kitts and Nevis","Capital",["Basseterre"]). +bgfact("Saint Kitts and = +Nevis","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-77","IBRD",= +"ICFTU","IDA","IFAD","IMF","INTERPOL","LORCS","OAS","OECS","UN","UNCTAD",= +"UNESCO","UNIDO","UPU","WCL","WHO"]). +bgfact("Saint Kitts and = +Nevis","ExportCommodities",["sugar","clothing","electronics","postage = +stamps"]). +bgfact("Saint Kitts and Nevis","ExportPartners",["US","UK","Trinidad and = +Tobago","OECS"]). +bgfact("Saint Kitts and = +Nevis","ImportCommodities",["foodstuffs","intermediate = +manubgfactures","machinery","fuels"]). +bgfact("Saint Kitts and Nevis","ImportPartners",["US","UK","Trinidad and = +Tobago","Canada","Japan","OECS"]). +bgfact("Saint Kitts and Nevis","Industries",["sugar = +processing","tourism","cotton","salt","copra","clothing","footwear","beve= +rages"]). +bgfact("Saint Kitts and Nevis","Agriculture",["subsistence = +rice","yams","vegetables","most food imported"]). +bgfact("Saint Lucia","LandBounderies",[]). +bgfact("Saint Lucia","NaturalResources",["forests","sandy = +beaches","minerals","mineral springs"]). +bgfact("Saint Lucia","Population",["145090"]). +bgfact("Saint Lucia","Capital",["Castries"]). +bgfact("Saint = +Lucia","MemberOf",["ACCT","INTERPOL","LORCS","NAM","OAS","OECS","UN","UNC= +TAD","UNESCO","UNIDO","UPU","WCL","WHO","WIPO","WMO"]). +bgfact("Saint = +Lucia","ExportCommodities",["bananas","clothing","cocoa","vegetables","fr= +uits","coconut oil"]). +bgfact("Saint Lucia","ExportPartners",["UK","US","CARICOM"]). +bgfact("Saint Lucia","ImportCommodities",["manubgfactured = +goods","machinery and transportation equipment","food and live = +animals","chemicals","fuels"]). +bgfact("Saint = +Lucia","ImportPartners",["US","CARICOM","UK","Japan","Canada"]). +bgfact("Saint Lucia","Industries",["clothing","assembly of electronic = +components","beverages","corrugated cardboard boxes","tourism","lime = +processing","coconut processing"]). +bgfact("Saint = +Lucia","Agriculture",["bananas","coconuts","vegetables","citrus = +fruit","root crops","imports food for the tourist industry"]). +bgfact("Saint Pierre and Miquelon","LandBounderies",[]). +bgfact("Saint Pierre and Miquelon","NaturalResources",["fish","deepwater = +ports"]). +bgfact("Saint Pierre and Miquelon","Population",["6704"]). +bgfact("Saint Pierre and Miquelon","Capital",["Saint-Pierre"]). +bgfact("Saint Pierre and Miquelon","MemberOf",["FZ","WFTU"]). +bgfact("Saint Pierre and Miquelon","ExportCommodities",["fish and fish = +products","fox and mink pelts"]). +bgfact("Saint Pierre and = +Miquelon","ExportPartners",["US","France","UK","Canada","Portugal"]). +bgfact("Saint Pierre and = +Miquelon","ImportCommodities",["meat","clothing","fuel","electrical = +equipment","machinery","building materials"]). +bgfact("Saint Pierre and = +Miquelon","ImportPartners",["Canada","France","US","Netherlands","UK"]). +bgfact("Saint Pierre and Miquelon","Industries",["tourism"]). +bgfact("Saint Pierre and = +Miquelon","Agriculture",["vegetables","cattle","sheep","fish catch = +of"]). +bgfact("Saint Vincent and the Grenadines","LandBounderies",[]). +bgfact("Saint Vincent and the = +Grenadines","NaturalResources",["negligible"]). +bgfact("Saint Vincent and the Grenadines","Population",["115437"]). +bgfact("Saint Vincent and the Grenadines","Capital",["Kingstown"]). +bgfact("Saint Vincent and the = +Grenadines","MemberOf",["ACP","C","CARICOM","CDB","ECLAC","FAO","G-77","G= +ATT","IBRD","ICAO","ICFTU","IDA","IFAD","IMF","IMO","INTELSAT","INTERPOL"= +,"IOC","ITU","LORCS","OAS","OECS","OPANAL","UN","UNCTAD","UNESCO","UNIDO"= +,"UPU","WCL","WFTU","WHO"]). +bgfact("Saint Vincent and the = +Grenadines","ExportCommodities",["bananas","eddoes and = +dasheen","arrowroot starch","tennis racquets"]). +bgfact("Saint Vincent and the = +Grenadines","ExportPartners",["UK","CARICOM","US"]). +bgfact("Saint Vincent and the = +Grenadines","ImportCommodities",["foodstuffs","machinery and = +equipment","chemicals and fertilizers","minerals and fuels"]). +bgfact("Saint Vincent and the = +Grenadines","ImportPartners",["US","CARICOM","UK","Trinidad and = +Tobago"]). +bgfact("Saint Vincent and the Grenadines","Industries",["food = +processing","cement","furniture","clothing","starch"]). +bgfact("Saint Vincent and the = +Grenadines","Agriculture",["bananas","coconuts","sweet potatoes","small = +numbers of cattle","sheep","hogs","small fish catch used locally"]). +bgfact("San Marino","LandBounderies",["Italy"]). +bgfact("San Marino","NaturalResources",["building stone"]). +bgfact("San Marino","Population",["24091"]). +bgfact("San Marino","Capital",["San Marino"]). +bgfact("San = +Marino","MemberOf",["CE","CSCE","ECE","ICAO","ICFTU","ILO","IMF","IOC","I= +OM","UN","UNCTAD","UNESCO","UPU","WHO","WIPO","WTO"]). +bgfact("San Marino","Industries",["wine","olive = +oil","cement","leather","textile","tourism"]). +bgfact("San = +Marino","Agriculture",["wheat","grapes","maize","olives","meat","cheese",= +"small numbers of cattle","pigs","depends on Italy for food imports"]). +bgfact("Sao Tome and Principe","LandBounderies",[]). +bgfact("Sao Tome and Principe","NaturalResources",["fish"]). +bgfact("Sao Tome and Principe","Population",["136780"]). +bgfact("Sao Tome and Principe","Capital",["Sao Tome"]). +bgfact("Sao Tome and = +Principe","MemberOf",["ACP","AfDB","CEEAC","ECA","FAO","G-77","IBRD","ICA= +O","IDA","IFAD","ILO","IMF","IMO","INTELSAT","ITU","LORCS","NAM","OAU","U= +N","UNCTAD","UNESCO","UNIDO","UPU","WHO","WMO","WTO"]). +bgfact("Sao Tome and = +Principe","ExportCommodities",["cocoa","copra","coffee","palm oil"]). +bgfact("Sao Tome and = +Principe","ExportPartners",["Netherlands","Germany","China","Portugal"]).= + +bgfact("Sao Tome and Principe","ImportCommodities",["machinery and = +electrical equipment","food products","petroleum"]). +bgfact("Sao Tome and = +Principe","ImportPartners",["Portugal","Japan","Spain","France","Angola"]= +). +bgfact("Sao Tome and Principe","Industries",["light = +construction","shirts","soap","beer","fisheries","shrimp processing"]). +bgfact("Sao Tome and Principe","Agriculture",["dominant sector of = +economy","cocoa","coconuts","palm kernels","food = +bananas","papaya","beans","poultry","not self-sufficient in food grain = +and meat"]). +bgfact("Saudi = +Arabia","LandBounderies",["Iraq","Jordan","Kuwait","Oman","Qatar","UAE","= +Yemen"]). +bgfact("Saudi Arabia","NaturalResources",["petroleum","natural = +gas","iron ore","gold","copper"]). +bgfact("Saudi Arabia","Population",["18196783"]). +bgfact("Saudi Arabia","Capital",["Riyadh"]). +bgfact("Saudi = +Arabia","MemberOf",["ABEDA","AfDB","AFESD","AL","AMF","CCC","ESCWA","FAO"= +,"G-19","G-77","GCC","IAEA","IBRD","ICAO","ICC","IDA","IDB","IFAD","IFC",= +"ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","ISO","ITU","LOR= +CS","NAM","OAPEC","OAS","OIC","OPEC","UN","UNCTAD","UNESCO","UNIDO","UNOS= +OM","UPU","WFTU","WHO","WIPO","WMO"]). +bgfact("Saudi Arabia","ExportCommodities",["petroleum and petroleum = +products"]). +bgfact("Saudi = +Arabia","ExportPartners",["US","Japan","Singapore","France","Korea"]). +bgfact("Saudi Arabia","ImportCommodities",["machinery and = +equipment","chemicals","foodstuffs","motor vehicles","textiles"]). +bgfact("Saudi = +Arabia","ImportPartners",["US","UK","Japan","Germany","France"]). +bgfact("Saudi Arabia","Industries",["crude production","petroleum = +refining","basic petrochemicals","cement","two small steel-rolling = +mills","construction","fertilizer","plastics"]). +bgfact("Saudi Arabia","Agriculture",["accounts for about of = +GDP","wheat","barley","tomatoes","melons","dates","citrus = +fruit","mutton","chickens","eggs","approaching self-sufficiency in = +food"]). +bgfact("Senegal","LandBounderies",["The = +Gambia","Guinea","Guinea-Bissau","Mali","Mauritania"]). +bgfact("Senegal","NaturalResources",["fish","phosphates","iron ore"]). +bgfact("Senegal","Population",["8730508"]). +bgfact("Senegal","Capital",["Dakar"]). +bgfact("Senegal","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOW= +AS","FAO","FZ","G-15","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","I= +DA","IDB","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","IOM= +","ITU","LORCS","NAM","OAU","OIC","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNIKOM","UNOMUR","UNTAC","UPU","WADB","WCL= +","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Senegal","ExportCommodities",["fish","ground nuts","petroleum = +products","phosphates","cotton"]). +bgfact("Senegal","ExportPartners",["France","Cote d'Ivoire","Mali"]). +bgfact("Senegal","ImportCommodities",["foods and beverages","consumer = +goods","Capital goods","petroleum"]). +bgfact("Senegal","ImportPartners",["France","Nigeria","Cote = +d'Ivoire","Algeria","China","Japan"]). +bgfact("Senegal","Industries",["agricultural and fish = +processing","phosphate mining","petroleum refining","building = +materials"]). +bgfact("Senegal","Agriculture",["major = +peanuts","millet","corn","sorghum","rice","cotton","tomatoes","fish = +catch of"]). +bgfact("Serbia and = +Montenegro","LandBounderies",["Albania","Hungary","The Former Yugoslav = +Republic of Macedonia","Romania"]). +bgfact("Serbia and = +Montenegro","NaturalResources",["oil","gas","coal","antimony","copper","l= +ead","zinc","nickel","gold","pyrite","chrome"]). +bgfact("Serbia and Montenegro","Capital",["Belgrade"]). +bgfact("Serbia and Montenegro","ExportCommodities",["machinery and = +transport equipment","manubgfactured goods","miscellaneous = +manubgfactured articles","chemicals","food and live animals","raw = +materials","fuels and lubricants","beverages and tobacco"]). +bgfact("Serbia and Montenegro","ExportPartners",["Italy","Germany","the = +FSU countries","East European countries","US"]). +bgfact("Serbia and Montenegro","ImportCommodities",["machinery and = +transport equipment","fuels and lubricants","manubgfactured = +goods","chemicals","food and live animals","miscellaneous manubgfactured = +items","raw materials","including coking coal for the steel = +industry","beverages","tobacco"]). +bgfact("Serbia and Montenegro","ImportPartners",["the FSU countries","EC = +countries","East European countries","US"]). +bgfact("Serbia and Montenegro","Industries",["machine = +building","electronics","petroleum products","chemicals"]). +bgfact("Serbia and Montenegro","Agriculture",["the fertile plains of = +Vojvodina produce of the cereal production of the former Yugoslavia and = +most of the cotton","oilseeds","Serbia proper","although = +hilly","produces fruit","grapes","in this area","Kosovo produces = +fruits","vegetables","tobacco","mostly near the coast where a = +Mediterranean climate permits the culture of = +olives","citrus","grapes"]). +bgfact("Seychelles","LandBounderies",[]). +bgfact("Seychelles","NaturalResources",["fish","copra","cinnamon = +trees"]). +bgfact("Seychelles","Population",["72113"]). +bgfact("Seychelles","Capital",["Victoria"]). +bgfact("Seychelles","MemberOf",["ACCT","ACP","AfDB","C","ECA","FAO","G-77= +","IBRD","ICAO","ICFTU","IFAD","IFC","ILO","IMF","IMO","INTELSAT","NAM","= +OAU","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","WMO","WTO"]). +bgfact("Seychelles","ExportCommodities",["fish","copra","cinnamon = +bark","petroleum products"]). +bgfact("Seychelles","ExportPartners",["UK France","Reunion"]). +bgfact("Seychelles","ImportCommodities",["manubgfactured = +goods","food","petroleum products","tobacco","beverages","machinery and = +transportation equipment"]). +bgfact("Seychelles","ImportPartners",["South Africa","Singapore","UK"]). +bgfact("Seychelles","Industries",["tourism","processing of coconut and = +vanilla","fishing","coir rope bgfactory","boat = +building","printing","furniture","beverage"]). +bgfact("Seychelles","Agriculture",["accounts for of = +GDP","coconuts","cinnamon","cassava","expansion of tuna fishing under = +way"]). +bgfact("Sierra Leone","LandBounderies",["Guinea","Liberia"]). +bgfact("Sierra Leone","NaturalResources",["diamonds","titanium = +ore","bauxite","iron ore","gold","chromite"]). +bgfact("Sierra Leone","Population",["4630037"]). +bgfact("Sierra Leone","Capital",["Freetown"]). +bgfact("Sierra = +Leone","MemberOf",["ACP","AfDB","C","CCC","ECA","ECOWAS","FAO","G-77","GA= +TT","IAEA","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","IFC","ILO","IMF","IM= +O","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU","OIC","UN","UNCT= +AD","UNESCO","UNIDO","UNOMIG","UPU","WCL","WHO","WIPO","WMO","WTO"]). +bgfact("Sierra = +Leone","ExportCommodities",["rutile","bauxite","diamonds","coffee"]). +bgfact("Sierra Leone","ExportPartners",["US","UK","Belgium","Germany"]). +bgfact("Sierra Leone","ImportCommodities",["foodstuffs","machinery and = +equipment","fuels"]). +bgfact("Sierra Leone","ImportPartners",["US","EC = +countries","Japan","China","Nigeria"]). +bgfact("Sierra Leone","Industries",["mining","petroleum refinery"]). +bgfact("Sierra Leone","Agriculture",["coffee","cocoa","annual fish = +catch averages"]). +bgfact("Singapore","LandBounderies",[]). +bgfact("Singapore","NaturalResources",["fish","deepwater ports"]). +bgfact("Singapore","Population",["2859142"]). +bgfact("Singapore","Capital",["Singapore"]). +bgfact("Singapore","MemberOf",["APEC","AsDB","ASEAN","C","CCC","COCOM","C= +P","ESCAP","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","IFC","ILO","= +IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NA= +M","UN","UNAVEM = +II","UNCTAD","UNIKOM","UNTAC","UPU","WHO","WIPO","WMO"]). +bgfact("Singapore","ExportCommodities",["computer equipment","rubber and = +rubber products","petroleum products","telecommunications equipment"]). +bgfact("Singapore","ExportPartners",["US","Malaysia","Hong = +Kong","Japan","Thailand"]). +bgfact("Singapore","ImportCommodities",["aircraft","petroleum","chemicals= +","foodstuffs"]). +bgfact("Singapore","ImportPartners",["Japan","US","Malaysia","Saudi = +Arabia","Taiwan"]). +bgfact("Singapore","Industries",["petroleum refining","electronics","oil = +drilling equipment","rubber processing and rubber products","processed = +food and beverages","ship repair","entrepot trade","financial = +services","biotechnology"]). +bgfact("Singapore","Agriculture",["major = +rubber","copra","fruit","vegetables"]). +bgfact("Slovakia","LandBounderies",["Austria","Czech = +Republic","Hungary","Poland","Ukraine"]). +bgfact("Slovakia","NaturalResources",["small amounts of iron = +ore","salt"]). +bgfact("Slovakia","Population",["5403505"]). +bgfact("Slovakia","Capital",["Bratislava"]). +bgfact("Slovakia","MemberOf",["BIS","CCC","CE","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMUR","UNPROFOR","UPU","WFTU","WHO","WIP= +O","WMO","WTO","ZC"]). +bgfact("Slovakia","ExportCommodities",["fuels","minerals","agricultural = +products"]). +bgfact("Slovakia","ExportPartners",["Czech Republic","CIS = +republics","Germany","Poland","Austria","Hungary","Italy","France","US","= +UK"]). +bgfact("Slovakia","ImportCommodities",["agricultural products"]). +bgfact("Slovakia","ImportPartners",["Czech Republic","CIS = +republics","Germany","Austria","Poland","Switzerland","Hungary","UK","Ita= +ly"]). +bgfact("Slovakia","Industries",["brown coal = +mining","chemicals","metal-working","consumer = +appliances","fertilizer","plastics","armaments"]). +bgfact("Slovakia","Agriculture",["diversified crop and livestock = +production","including grains","potatoes","sugar = +beets","hops","fruit","hogs","cattle","exporter of forest products"]). +bgfact("Slovenia","LandBounderies",["Austria","Croatia","Italy","Hungary"= +]). +bgfact("Slovenia","NaturalResources",["lignite = +coal","lead","zinc","mercury","uranium","silver"]). +bgfact("Slovenia","Population",["1972227"]). +bgfact("Slovenia","Capital",["Ljubljana"]). +bgfact("Slovenia","MemberOf",["CCC","CE","CEI","CSCE","EBRD","ECE","IAEA"= +,"IBRD","ICAO","IDA","IFC","ILO","IMF","IMO","INTELSAT","UN","UNCTAD","UN= +ESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Slovenia","ExportCommodities",["machinery and transport = +equipment","chemicals","food and live animals","raw = +materials","beverages and tobacco less than"]). +bgfact("Slovenia","ExportPartners",["Germany","Croatia","Italy","France"]= +). +bgfact("Slovenia","ImportCommodities",["machinery and transport = +equipment","chemicals","raw materials","fuels and lubricants","food and = +live animals"]). +bgfact("Slovenia","ImportPartners",["Germany","Croatia","Italy","France",= +"Austria"]). +bgfact("Slovenia","Industries",["ferrous metallurgy and rolling mill = +products","aluminum reduction and rolled products","lead and zinc = +smelting","electronics","trucks","electric power equipment","wood = +products","textiles","chemicals","machine tools"]). +bgfact("Slovenia","Agriculture",["main potatoes","hops","hemp"]). +bgfact("Solomon Islands","LandBounderies",[]). +bgfact("Solomon = +Islands","NaturalResources",["fish","forests","gold","bauxite","phosphate= +s","lead","zinc","nickel"]). +bgfact("Solomon Islands","Population",["385811"]). +bgfact("Solomon Islands","Capital",["Honiara"]). +bgfact("Solomon = +Islands","MemberOf",["ACP","AsDB","C","ESCAP","FAO","G-77","IBRD","ICAO",= +"IDA","IFAD","IFC","ILO","IMF","IMO","INTELSAT","IOC","ITU","LORCS","SPAR= +TECA","SPC","SPF","UN","UNCTAD","UNESCO","UPU","WFTU","WHO","WMO"]). +bgfact("Solomon Islands","ExportCommodities",["fish","timber","palm = +oil","cocoa","copra"]). +bgfact("Solomon = +Islands","ExportPartners",["Japan","UK","Thailand","Australia","US"]). +bgfact("Solomon Islands","ImportCommodities",["plant and machinery = +manubgfactured goods","food and live animals","fuel"]). +bgfact("Solomon = +Islands","ImportPartners",["Australia","Japan","Singapore","NZ"]). +bgfact("Solomon Islands","Industries",["copra","fish"]). +bgfact("Solomon Islands","Agriculture",["including fishing and = +forestry","cocoa","beans","coconuts","palm = +kernels","potatoes","vegetables","fruit","cattle"]). +bgfact("Somalia","LandBounderies",["Djibouti","Ethiopia","Kenya"]). +bgfact("Somalia","NaturalResources",["uranium and largely unexploited = +reserves of iron ore","tin","gypsum","bauxite","copper","salt"]). +bgfact("Somalia","Population",["6666873"]). +bgfact("Somalia","Capital",["Mogadishu"]). +bgfact("Somalia","MemberOf",["ACP","AfDB","AFESD","AL","AMF","CAEU","ECA"= +,"FAO","G-77","IBRD","ICAO","IDA","IDB","IFAD","IFC","IGADD","ILO","IMF",= +"IMO","INTELSAT","INTERPOL","IOC","IOM","ITU","LORCS","NAM","OAU","OIC","= +UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Somalia","ExportCommodities",["bananas","live = +animals","fish","hides"]). +bgfact("Somalia","ExportPartners",["Saudi Arabia","Italy","FRG"]). +bgfact("Somalia","ImportCommodities",["petroleum = +products","foodstuffs","construction materials"]). +bgfact("Somalia","ImportPartners",["US","Italy","FRG","Kenya","UK","Saudi= + Arabia"]). +bgfact("Somalia","Industries",["sugar","textiles"]). +bgfact("Somalia","Agriculture",["dominant = +sector","bananas","sorghum","corn","mangoes","fishing potential largely = +unexploited"]). +bgfact("South = +Africa","LandBounderies",["Botswana","Lesotho","Mozambique","Namibia","Sw= +aziland","Zimbabwe"]). +bgfact("South = +Africa","NaturalResources",["gold","chromium","antimony","coal","iron = +ore","manganese","nickel","phosphates","tin","uranium","gem = +diamonds","platinum","copper","vanadium","salt","natural gas"]). +bgfact("South Africa","Population",["43930631"]). +bgfact("South Africa","Capital",["Pretoria"]). +bgfact("South = +Africa","MemberOf",["BIS","CCC","ECA","GATT","G-77","IAEA","IBRD","ICAO",= +"ZC"]). +bgfact("South Africa","ExportCommodities",["gold","food","chemicals"]). +bgfact("South = +Africa","ExportPartners",["Italy","Japan","US","Germany","UK","Hong = +Kong"]). +bgfact("South Africa","ImportCommodities",["machinery","transport = +equipment","chemicals","oil","textiles","scientific instruments"]). +bgfact("South = +Africa","ImportPartners",["Germany","US","Japan","UK","Italy"]). +bgfact("South Africa","Industries",["mining","automobile = +assembly","metalworking","machinery","textile","iron and = +steel","chemical","fertilizer","foodstuffs"]). +bgfact("South = +Africa","Agriculture",["cattle","poultry","sheep","wool","milk","beef","c= +orn","wheat","sugarcane","fruits","self-sufficient in food"]). +bgfact("South Georgia and the South Sandwich = +Islands","LandBounderies",[]). +bgfact("South Georgia and the South Sandwich = +Islands","NaturalResources",["fish"]). +bgfact("South Georgia and the South Sandwich Islands","Capital",["none; = +Grytviken on South Georgia is the garrison town"]). +bgfact("Spain","LandBounderies",["Andorra","France","Gibraltar","Portugal= +"]). +bgfact("Spain","NaturalResources",["coal","lignite","iron = +ore","uranium","mercury","pyrites","fluorspar","gypsum","zinc","lead","tu= +ngsten","copper","kaolin","potash","hydropower"]). +bgfact("Spain","Population",["39302665"]). +bgfact("Spain","Capital",["Madrid"]). +bgfact("Spain","MemberOf",["AG","OECD","ONUSAL","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMOZ","UNPROFOR","UPU","WCL","WEU","WHO"= +,"WIPO","WMO","WTO","ZC"]). +bgfact("Spain","ExportCommodities",["cars and trucks","semifinished = +manubgfactured goods","foodstuffs","machinery"]). +bgfact("Spain","ExportPartners",["EC","US"]). +bgfact("Spain","ImportCommodities",["machinery","transport = +equipment","fuels","semifinished goods","foodstuffs","consumer = +goods","chemicals"]). +bgfact("Spain","ImportPartners",["EC","US","Middle East"]). +bgfact("Spain","Industries",["textiles and apparel","food and = +beverages","metals and metal = +manubgfactures","chemicals","shipbuilding","automobiles","machine = +tools","tourism"]). +bgfact("Spain","Agriculture",["major grain","vegetables","olives","wine = +grapes","sugar beets","citrus fruit","beef","pork","poultry","fish = +catch of million metric tons is among top nations"]). +bgfact("Spratly Islands","LandBounderies",[]). +bgfact("Spratly = +Islands","NaturalResources",["fish","guano","undetermined oil and = +natural gas potential"]). +bgfact("Spratly Islands","Industries",["none"]). +bgfact("Sri Lanka","LandBounderies",[]). +bgfact("Sri Lanka","NaturalResources",["limestone","graphite","mineral = +sands","gems","phosphates","clay"]). +bgfact("Sri Lanka","Population",["18129850"]). +bgfact("Sri Lanka","Capital",["Colombo"]). +bgfact("Sri = +Lanka","MemberOf",["AsDB","C","CCC","CP","ESCAP","FAO","G-24","G-77","GAT= +T","IAEA","IBRD","ICAO","ICC","ICFTU","IDA","IFAD","IFC","ILO","IMF","IMO= +","INMARSAT","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","NAM",= +"PCA","SAARC","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WI= +PO","WMO","WTO"]). +bgfact("Sri Lanka","ExportCommodities",["garments and = +textiles","teas","gems","petroleum products","coconuts","rubber","marine = +products","graphite"]). +bgfact("Sri = +Lanka","ExportPartners",["US","Germany","UK","Netherlands","Japan","Franc= +e","Singapore"]). +bgfact("Sri Lanka","ImportCommodities",["food and beverages","textiles = +and textile materials","petroleum and petroleum products","machinery = +and equipment"]). +bgfact("Sri = +Lanka","ImportPartners",["Japan","India","US","UK","Singapore","Germany",= +"Hong King","Taiwan","South Korea"]). +bgfact("Sri Lanka","Industries",["processing of = +rubber","tea","coconuts","clothing","cement","petroleum = +refining","textiles","tobacco"]). +bgfact("Sri = +Lanka","Agriculture",["grains","pulses","oilseeds","roots","tea","rubber"= +,"animal milk","eggs","hides","not self-sufficient in rice = +production"]). +bgfact("Sudan","LandBounderies",["Central African = +Republic","Chad","Egypt","Eritrea","Ethiopia","Kenya","Libya","Uganda","Z= +aire"]). +bgfact("Sudan","NaturalResources",["small reserves of petroleum","iron = +ore","copper","chromium ore","zinc","tungsten","mica","silver"]). +bgfact("Sudan","Population",["29419798"]). +bgfact("Sudan","Capital",["Khartoum"]). +bgfact("Sudan","MemberOf",["ABEDA","ACP","AfDB","AFESD","AL","AMF","CAEU"= +,"CCC","ECA","FAO","G-77","IAEA","IBRD","ICAO","IDA","IFAD","IFC","IGADD"= +,"ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM","OAU",= +"PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WFTU","WHO","WIPO","W= +MO","WTO"]). +bgfact("Sudan","ExportCommodities",["cotton","sesame","gum = +arabic","peanuts"]). +bgfact("Sudan","ExportPartners",["Western Europe","Saudi = +Arabia","Eastern Europe","Japan","US"]). +bgfact("Sudan","ImportCommodities",["foodstuffs","petroleum = +products","manubgfactured goods","machinery and equipment","medicines = +and chemicals","textiles"]). +bgfact("Sudan","ImportPartners",["Western Europe","Africa and = +Asia","US","Eastern Europe"]). +bgfact("Sudan","Industries",["cotton = +ginning","textiles","cement","edible oils","sugar","soap = +distilling","shoes","petroleum refining"]). +bgfact("Sudan","Agriculture",["major = +cotton","oilseeds","sorghum","millet","wheat","gum arabic","marginally = +self-sufficient in most foods"]). +bgfact("Suriname","LandBounderies",["Brazil","French Guiana","Guyana"]). +bgfact("Suriname","NaturalResources",["timber","hydropower = +potential","fish","shrimp","bauxite","iron = +ore","copper","platinum","gold"]). +bgfact("Suriname","Population",["422840"]). +bgfact("Suriname","Capital",["Paramaribo"]). +bgfact("Suriname","MemberOf",["ACP","CARICOM","ITU","LAES","LORCS","NAM",= +"OAS","OPANAL","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WHO","WIPO","W= +MO"]). +bgfact("Suriname","ExportCommodities",["alumina","aluminum","shrimp and = +fish","rice","bananas"]). +bgfact("Suriname","ExportPartners",["Norway","Netherlands","US","Japan","= +Brazil","UK"]). +bgfact("Suriname","ImportCommodities",["Capital = +equipment","petroleum","foodstuffs","cotton","consumer goods"]). +bgfact("Suriname","ImportPartners",["US","Netherlands","Trinidad and = +Tobago","Brazil"]). +bgfact("Suriname","Industries",["bauxite mining","alumina and aluminum = +production","lumbering","food processing","fishing"]). +bgfact("Suriname","Agriculture",["palm = +kernels","coconuts","plantains","peanuts","beef","self-sufficient in = +most foods"]). +bgfact("Svalbard","LandBounderies",[]). +bgfact("Svalbard","NaturalResources",["coal","copper","iron = +ore","phosphate","zinc","wildlife","fish"]). +bgfact("Svalbard","Population",["3018"]). +bgfact("Svalbard","Capital",["Longyearbyen"]). +bgfact("Svalbard","MemberOf",["none"]). +bgfact("Swaziland","LandBounderies",["Mozambique","South Africa"]). +bgfact("Swaziland","NaturalResources",["asbestos","coal","clay","cassiter= +ite","hydropower","forests","small gold and diamond deposits","quarry = +stone"]). +bgfact("Swaziland","Population",["936369"]). +bgfact("Swaziland","Capital",["Mbabane"]). +bgfact("Swaziland","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","G-77",= +"GATT","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF","INTELSAT","I= +NTERPOL","IOC","ITU","LORCS","NAM","OAU","PCA","SACU","SADC","UN","UNCTAD= +","UNESCO","UNIDO","UPU","WHO","WIPO","WMO"]). +bgfact("Swaziland","ExportCommodities",["sugar","edible = +concentrates","wood pulp","canned fruit","citrus"]). +bgfact("Swaziland","ExportPartners",["South Africa","EC = +countries","Canada"]). +bgfact("Swaziland","ImportCommodities",["motor = +vehicles","machinery","transport equipment","petroleum = +products","foodstuffs","chemicals"]). +bgfact("Swaziland","ImportPartners",["South = +Africa","Switzerland","UK"]). +bgfact("Swaziland","Industries",["mining","wood pulp","sugar"]). +bgfact("Swaziland","Agriculture",["sugarcane","cotton","maize","tobacco",= +"rice","citrus fruit","sorghum","peanuts","cattle","goats","not = +self-sufficient in grain"]). +bgfact("Sweden","LandBounderies",["Finland","Norway"]). +bgfact("Sweden","NaturalResources",["zinc","iron = +ore","lead","copper","silver","timber","uranium","hydropower = +potential"]). +bgfact("Sweden","Population",["8778461"]). +bgfact("Sweden","Capital",["Stockholm"]). +bgfact("Sweden","MemberOf",["AfDB","AG","NC","NEA","NIB","NSG","OECD","ON= +USAL","PCA","UN","UNAVEM = +II","UNCTAD","UNESCO","UNFICYP","UNHCR","UNIDO","UNIFIL","UNIKOM","UNMOGI= +P","UNOMIG","UNOMOZ","UNOSOM","UNPROFOR","UNTAC","UNTSO","UPU","WFTU","WH= +O","WIPO","WMO","ZC"]). +bgfact("Sweden","ExportCommodities",["machinery","motor vehicles","paper = +products","pulp and wood","iron and steel = +products","chemicals","petroleum and petroleum products"]). +bgfact("Sweden","ExportPartners",["EC"]). +bgfact("Sweden","ImportCommodities",["machinery","petroleum and = +petroleum products","chemicals","motor vehicles","foodstuffs","iron and = +steel","clothing"]). +bgfact("Sweden","ImportPartners",["EC"]). +bgfact("Sweden","Industries",["iron and steel","precision = +equipment","wood pulp and paper products","processed foods","motor = +vehicles"]). +bgfact("Sweden","Agriculture",["animal husbandry predominates","main = +grains","sugar beets","farming accounted for of GDP and of jobs in"]). +bgfact("Switzerland","LandBounderies",["Austria","France","Italy","Liecht= +enstein","Germany"]). +bgfact("Switzerland","NaturalResources",["hydropower = +potential","timber","salt"]). +bgfact("Switzerland","Population",["7040119"]). +bgfact("Switzerland","Capital",["Bern"]). +bgfact("Switzerland","MemberOf",["AfDB","AG","UNCTAD","UNESCO","UNHCR","U= +NIDO","UNOMIG","UNPROFOR","UNTSO","UPU","WCL","WHO","WIPO","WMO","WTO","Z= +C"]). +bgfact("Switzerland","ExportCommodities",["machinery and = +equipment","precision instruments","metal = +products","foodstuffs","textiles and clothing"]). +bgfact("Switzerland","ExportPartners",["Western Europe","US","Japan"]). +bgfact("Switzerland","ImportCommodities",["agricultural = +products","machinery and transportation = +equipment","chemicals","textiles","construction materials"]). +bgfact("Switzerland","ImportPartners",["Western Europe","US"]). +bgfact("Switzerland","Industries",["machinery","chemicals","watches","tex= +tiles","precision instruments"]). +bgfact("Switzerland","Agriculture",["must import fish","refined = +sugar","fats and oils","grains","eggs","fruits","vegetables","meat"]). +bgfact("Syria","LandBounderies",["Iraq","Israel","Jordan","Lebanon","Turk= +ey"]). +bgfact("Syria","NaturalResources",["petroleum","phosphates","chrome and = +manganese ores","asphalt","iron ore","rock salt","marble","gypsum"]). +bgfact("Syria","Population",["14886672"]). +bgfact("Syria","Capital",["Damascus"]). +bgfact("Syria","MemberOf",["ABEDA","AFESD","AL","AMF","CAEU","CCC","ESCWA= +","FAO","G-24","G-77","IAEA","IBRD","ICAO","ICC","IDA","IDB","IFAD","IFC"= +,"ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM",= +"OAPEC","OIC","UN","UNCTAD","UNESCO","UNIDO","UNRWA","UPU","WFTU","WHO","= +WMO","WTO"]). +bgfact("Syria","ExportCommodities",["petroleum","textiles","cotton","frui= +ts and vegetables"]). +bgfact("Syria","ExportPartners",["EC","former CEMA countries","Arab = +countries"]). +bgfact("Syria","ImportCommodities",["foodstuffs","metal = +products","machinery"]). +bgfact("Syria","ImportPartners",["EC","former CEMA countries","US and = +Canada"]). +bgfact("Syria","Industries",["textiles","food = +processing","beverages","tobacco","phosphate rock mining","petroleum"]). +bgfact("Syria","Agriculture",["animal = +beef","lamb","eggs","poultry","not self-sufficient in grain or = +livestock products"]). +bgfact("Taiwan","LandBounderies",[]). +bgfact("Taiwan","NaturalResources",["small deposits of coal","natural = +gas","limestone","marble"]). +bgfact("Taiwan","Population",["21298930"]). +bgfact("Taiwan","Capital",["Taipei"]). +bgfact("Taiwan","MemberOf",["suspended from IAEA in","but still allows = +IAEA controls over extensive atomic = +development","APEC","AsDB","BCIE","ICC","IOC","COCOM","WCL"]). +bgfact("Taiwan","ExportCommodities",["electrical machinery","electronic = +products","textiles","footwear","foodstuffs","plywood and wood = +products"]). +bgfact("Taiwan","ExportPartners",["US","Hong Kong","EC = +countries","Japan"]). +bgfact("Taiwan","ImportCommodities",["machinery and = +equipment","electronic products","chemicals","iron and = +steel","crude","foodstuffs"]). +bgfact("Taiwan","ImportPartners",["Japan","US","EC countries"]). +bgfact("Taiwan","Industries",["electronics","textiles","chemicals","cloth= +ing","food processing","plywood","sugar = +milling","cement","shipbuilding","petroleum refining"]). +bgfact("Taiwan","Agriculture",["major = +vegetables","rice","fruit","livestock - hogs","poultry","beef","not = +self-sufficient in wheat","soybeans","fish catch increasing","reached = +million metric tons in"]). +bgfact("Tajikistan","LandBounderies",["Afghanistan","China","Kyrgyzstan",= +"Uzbekistan"]). +bgfact("Tajikistan","NaturalResources",["significant hydropower = +potential","some petroleum","uranium","mercury","brown = +coal","lead","zinc","antimony","tungsten"]). +bgfact("Tajikistan","Population",["5995469"]). +bgfact("Tajikistan","Capital",["Dushanbe"]). +bgfact("Tajikistan","MemberOf",["CIS","CSCE","EBRD","ECO","ESCAP","IBRD",= +"IDA","IDB","IMF","INTELSAT","IOC","NACC","OIC","UN","UNCTAD","UNESCO","U= +NIDO","WHO","WMO"]). +bgfact("Tajikistan","ExportCommodities",["cotton","aluminum","fruits","ve= +getable oil","textiles"]). +bgfact("Tajikistan","ExportPartners",["Russia","Kazakhstan","Ukraine","Uz= +bekistan","Turkmenistan"]). +bgfact("Tajikistan","ImportCommodities",["fuel","chemicals","machinery = +and transport equipment","textiles","foodstuffs"]). +bgfact("Tajikistan","ImportPartners",["Russia","Uzbekistan","Kazakhstan"]= +). +bgfact("Tajikistan","Industries",["aluminum","zinc","lead","chemicals = +and fertilizers","cement","vegetable oil","metal-cutting machine = +tools","refrigerators and freezers"]). +bgfact("Tajikistan","Agriculture",["cotton","grain","fruits","grapes","ca= +ttle","sheep and goats"]). +bgfact("Tanzania","LandBounderies",["Burundi","Kenya","Malawi","Mozambiqu= +e","Rwanda","Uganda","Zambia"]). +bgfact("Tanzania","NaturalResources",["hydropower = +potential","tin","phosphates","iron = +ore","coal","diamonds","gemstones","gold","natural gas","nickel"]). +bgfact("Tanzania","Population",["27985660"]). +bgfact("Tanzania","Capital",["Dar es Salaam"]). +bgfact("Tanzania","MemberOf",["ACP","AfDB","C","CCC","EADB","ECA","FAO","= +FLS","G-6","G-77","GATT","IAEA","IBRD","ICAO","IDA","IFAD","IFC","ILO","I= +MF","IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS","NAM","OAU","SA= +DC","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WCL","WHO","WIPO","WMO"= +,"WTO"]). +bgfact("Tanzania","ExportCommodities",["coffee","cotton","tobacco","tea",= +"cashew nuts","sisal"]). +bgfact("Tanzania","ExportPartners",["FRG","UK","Japan","Netherlands","Ken= +ya","Hong Kong","US"]). +bgfact("Tanzania","ImportCommodities",["manubgfactured goods","machinery = +and transportation equipment","cotton piece = +goods","crude","foodstuffs"]). +bgfact("Tanzania","ImportPartners",["FRG","UK","US","Japan","Italy","Denm= +ark"]). +bgfact("Tanzania","Industries",["primarily agricultural = +processing","diamond and gold mining","oil = +refinery","shoes","cement","textiles","wood products","fertilizer"]). +bgfact("Tanzania","Agriculture",["coffee","sisal","tea","cotton","food = +corn","wheat","cassava","bananas","fruits","small numbers of = +cattle","sheep","not self-sufficient in food grain production"]). +bgfact("Thailand","LandBounderies",["Burma","Cambodia","Laos","Malaysia"]= +). +bgfact("Thailand","NaturalResources",["tin","rubber","natural = +gas","tungsten","tantalum","timber","lead","fish","gypsum","lignite","flu= +orite"]). +bgfact("Thailand","Population",["59510471"]). +bgfact("Thailand","Capital",["Bangkok"]). +bgfact("Thailand","MemberOf",["APEC","AsDB","ASEAN","CCC","CP","ESCAP","F= +AO","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","= +IMF","IMO","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","NAM","P= +CA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNIKOM","UNTAC","UPU","WCL","= +WFTU","WHO","WIPO","WMO"]). +bgfact("Thailand","ExportCommodities",["machinery and = +manubgfactures","agricultural products","fisheries products"]). +bgfact("Thailand","ExportPartners",["US","Japan","Singapore","Hong = +Kong","Germany","Netherlands","UK","Malaysia","France","China"]). +bgfact("Thailand","ImportCommodities",["Capital goods","intermediate = +goods and raw materials","consumer goods","oil"]). +bgfact("Thailand","ImportPartners",["Japan","US","Singapore","Taiwan","Ge= +rmany","South Korea","Malaysia","China","Hong Kong","UK"]). +bgfact("Thailand","Industries",["textiles and garments","agricultural = +processing","beverages","tobacco","cement","light = +manubgfacturing","electric appliances and components","integrated = +circuits","furniture","world's second-largest tungsten producer and = +third-largest tin producer"]). +bgfact("Thailand","Agriculture",["corn","sugarcane","coconuts","except = +for wheat","self-sufficient in food"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","LandBounderies",["Albania","Bulgaria","Greece","Serbia and = +Montenegro"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","NaturalResources",["chromium","lead","zinc","manganese","tung= +sten","nickel","low-grade iron ore","asbestos","sulphur","timber"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","Population",["2213785"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","Capital",["Skopje"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","MemberOf",["CE","ITU","UN","UNCTAD","UNESCO","UNIDO","UPU","W= +HO","WIPO","WMO"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","ExportCommodities",["manubgfactured goods","machinery and = +transport equipment","miscellaneous manubgfactured articles","raw = +materials","food"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","ExportPartners",["Germany","Greece","Albania"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","ImportCommodities",["fuels and lubricants","manubgfactured = +goods","machinery and transport equipment","food and live = +animals","chemicals","raw materials","miscellaneous manubgfactured = +articles","beverages and tobacco"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","ImportPartners",["Greece","Albania","Germany","Bulgaria"]). +bgfact("The Former Yugoslav Republic of Macedonia","Industries",["low = +levels of technology predominate","such as","produces basic liquid = +fuels","coal","metallic chromium","lead","zinc","light industry = +produces basic textiles","wood products"]). +bgfact("The Former Yugoslav Republic of = +Macedonia","Agriculture",["principal crops are = +rice","tobacco","wheat","corn","also grown are = +cotton","sesame","mulberry leaves","citrus fruit","The Former Yugoslav = +Republic of Macedonia is one of the seven legal cultivators of the = +opium poppy for the world pharmaceutical industry","agricultural = +production is highly labor intensive"]). +bgfact("Togo","LandBounderies",["Benin","Burkina","Ghana"]). +bgfact("Togo","NaturalResources",["phosphates","limestone","marble"]). +bgfact("Togo","Population",["4255090"]). +bgfact("Togo","Capital",["Lome"]). +bgfact("Togo","MemberOf",["ACCT","ACP","AfDB","CCC","CEAO","ECA","ECOWAS"= +,"Entente","FAO","FZ","G-77","GATT","IBRD","ICAO","ICC","ICFTU","IDA","IF= +AD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","NA= +M","OAU","UN","UNCTAD","UNESCO","UNIDO","UPU","WADB","WCL","WHO","WIPO","= +WMO","WTO"]). +bgfact("Togo","ExportCommodities",["phosphates","cotton","cocoa","coffee"= +]). +bgfact("Togo","ExportPartners",["EC","Africa","US"]). +bgfact("Togo","ImportCommodities",["machinery and equipment","consumer = +goods","food","chemical products"]). +bgfact("Togo","ImportPartners",["EC","Africa","US","Japan"]). +bgfact("Togo","Industries",["phosphate mining","agricultural = +processing","cement","handicrafts","textiles","beverages"]). +bgfact("Togo","Agriculture",["coffee","cocoa","yams","cassava","corn","be= +ans","rice","millet","annual fish catch of"]). +bgfact("Tokelau","LandBounderies",[]). +bgfact("Tokelau","NaturalResources",["negligible"]). +bgfact("Tokelau","Population",["1523"]). +bgfact("Tokelau","Capital",["none; each atoll has its own administrative = +center"]). +bgfact("Tokelau","MemberOf",["SPC","WHO"]). +bgfact("Tokelau","ExportCommodities",["stamps","copra","handicrafts"]). +bgfact("Tokelau","ExportPartners",["NZ"]). +bgfact("Tokelau","ImportCommodities",["foodstuffs","building = +materials","fuel"]). +bgfact("Tokelau","ImportPartners",["NZ"]). +bgfact("Tokelau","Industries",["small-scale enterprises for copra = +production","wood work","stamps","fishing"]). +bgfact("Tokelau","Agriculture",["coconuts","basic subsistence = +breadfruit","papaya","pigs","poultry","goats"]). +bgfact("Tonga","LandBounderies",[]). +bgfact("Tonga","NaturalResources",["fish","fertile soil"]). +bgfact("Tonga","Population",["104778"]). +bgfact("Tonga","Capital",["Nuku'alofa"]). +bgfact("Tonga","MemberOf",["ACP","AsDB","C","ESCAP","FAO","G-77","IBRD","= +ICAO","ICFTU","IDA","IFAD","IFC","IMF","INTELSAT","INTERPOL","IOC","ITU",= +"LORCS","SPARTECA","SPC","SPF","UNCTAD","UNESCO","UNIDO","UPU","WHO"]). +bgfact("Tonga","ExportCommodities",["vanilla","fish","root = +crops","coconut oil","squash"]). +bgfact("Tonga","ExportPartners",["Japan","US","Australia","NZ"]). +bgfact("Tonga","ImportCommodities",["food products","machinery and = +transport equipment","manubgfactures","fuels","chemicals"]). +bgfact("Tonga","ImportPartners",["NZ","Australia","US","Japan"]). +bgfact("Tonga","Industries",["tourism","fishing"]). +bgfact("Tonga","Agriculture",["dominated by coconut","copra","vanilla = +beans","cocoa","coffee","ginger","black pepper"]). +bgfact("Trinidad and Tobago","LandBounderies",[]). +bgfact("Trinidad and Tobago","NaturalResources",["petroleum","natural = +gas","asphalt"]). +bgfact("Trinidad and Tobago","Population",["1328282"]). +bgfact("Trinidad and Tobago","Capital",["Port-of-Spain"]). +bgfact("Trinidad and = +Tobago","MemberOf",["ACP","C","CARICOM","CCC","CDB","ECLAC","FAO","G-24",= +"G-77","GATT","IADB","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO","IMF"= +,"IMO","INTELSAT","INTERPOL","IOC","ISO","ITU","LAES","LORCS","NAM","OAS"= +,"OPANAL","UN","UNCTAD","UNESCO","UNIDO","UPU","WFTU","WHO","WIPO","WMO"]= +). +bgfact("Trinidad and Tobago","ExportCommodities",["petroleum and = +petroleum products","chemicals","steel = +products","fertilizer","sugar","cocoa","coffee","citrus","flowers"]). +bgfact("Trinidad and Tobago","ExportPartners",["US","CARICOM","Latin = +America","EC"]). +bgfact("Trinidad and = +Tobago","ImportCommodities",["machinery","transportation = +equipment","manubgfactured goods","food","live animals"]). +bgfact("Trinidad and Tobago","ImportPartners",["US","Venezuela","UK"]). +bgfact("Trinidad and = +Tobago","Industries",["petroleum","chemicals","tourism","food = +processing","cement","beverage","cotton textiles"]). +bgfact("Trinidad and Tobago","Agriculture",["major cocoa","sugarcane = +acreage is being shifted into rice","citrus","coffee","must import large = +share of food needs"]). +bgfact("Tromelin Island","LandBounderies",[]). +bgfact("Tromelin Island","NaturalResources",["fish"]). +bgfact("Tromelin Island","Capital",["none; administered by France from = +Reunion"]). +bgfact("Tunisia","LandBounderies",["Algeria","Libya"]). +bgfact("Tunisia","NaturalResources",["petroleum","phosphates","iron = +ore","lead","zinc","salt"]). +bgfact("Tunisia","Population",["8726562"]). +bgfact("Tunisia","Capital",["Tunis"]). +bgfact("Tunisia","MemberOf",["ABEDA","ACCT","AfDB","AFESD","AL","AMF","AM= +U","CCC","ECA","FAO","G-77","GATT","IAEA","IBRD","ICAO","ICC","ICFTU","ID= +A","IDB","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT","INTERPOL",= +"IOC","ISO","ITU","LORCS","MINURSO","NAM","OAPEC","OAU","OIC","UN","UNCTA= +D","UNESCO","UNHCR","UNIDO","UNOSOM","UNPROFOR","UNTAC","UPU","WHO","WIPO= +","WMO","WTO"]). +bgfact("Tunisia","ExportCommodities",["hydrocarbons","agricultural = +products","phosphates and chemicals"]). +bgfact("Tunisia","ExportPartners",["EC countries","Middle = +East","Algeria","India","US"]). +bgfact("Tunisia","ImportCommodities",["industrial goods and = +equipment","hydrocarbons","food","consumer goods"]). +bgfact("Tunisia","ImportPartners",["EC countries","US","Middle = +East","Japan","Switzerland","Algeria"]). +bgfact("Tunisia","Industries",["petroleum","mining","tourism","textiles",= +"footwear","food","beverages"]). +bgfact("Tunisia","Agriculture",["export = +olives","dates","oranges","sugar beets","wine = +grapes","poultry","beef","not self-sufficient in food"]). +bgfact("Turkey","LandBounderies",["Armenia","Azerbaijan","Bulgaria","Geor= +gia","Greece","Iran","Iraq","Syria"]). +bgfact("Turkey","NaturalResources",["antimony","coal","chromium","mercury= +","copper","borate","sulphur","iron ore"]). +bgfact("Turkey","Population",["62153898"]). +bgfact("Turkey","Capital",["Ankara"]). +bgfact("Turkey","MemberOf",["AsDB","BIS","BSEC","CCC","CE","CERN","WFTU",= +"WHO","WIPO","WMO","WTO"]). +bgfact("Turkey","ExportCommodities",["manubgfactured = +products","foodstuffs","mining products"]). +bgfact("Turkey","ExportPartners",["EC countries","US","Russia","Saudi = +Arabia"]). +bgfact("Turkey","ImportCommodities",["manubgfactured = +products","fuels","foodstuffs"]). +bgfact("Turkey","ImportPartners",["EC countries","US","Saudi = +Arabia","Russia"]). +bgfact("Turkey","Industries",["textiles","food = +processing","mining","steel","petroleum","construction","lumber","paper"]= +). +bgfact("Turkey","Agriculture",["tobacco","cotton","grain","olives","sugar= + beets","pulses","citrus fruit","self-sufficient in food most years"]). +bgfact("Turkmenistan","LandBounderies",["Afghanistan","Iran","Kazakhstan"= +,"Uzbekistan"]). +bgfact("Turkmenistan","NaturalResources",["petroleum","natural = +gas","coal","sulphur","salt"]). +bgfact("Turkmenistan","Population",["3995122"]). +bgfact("Turkmenistan","Capital",["Ashgabat"]). +bgfact("Turkmenistan","MemberOf",["CIS","CSCE","EBRD","ECE","ECO","ESCAP"= +,"IBRD","ICAO","IDB","ILO","IMF","IMO","INTELSAT","IOC","ITU","NACC","OIC= +","UN","UNCTAD","UNESCO","UPU","WHO","WMO"]). +bgfact("Turkmenistan","ExportCommodities",["natural = +gas","cotton","petroleum products","textiles","carpets"]). +bgfact("Turkmenistan","ExportPartners",["Ukraine","Russia","Kazakhstan","= +Uzbekistan","Georgia","Eastern Europe","Turkey","Argentina"]). +bgfact("Turkmenistan","ImportCommodities",["machinery and parts","grain = +and food","plastics and rubber","consumer durables","textiles"]). +bgfact("Turkmenistan","ImportPartners",["Russia","Azerbaijan","Uzbekistan= +","Kazakhstan","Turkey"]). +bgfact("Turkmenistan","Industries",["natural gas","oil","petroleum = +products","textiles","food processing"]). +bgfact("Turkmenistan","Agriculture",["cotton","grain","animal = +husbandry"]). +bgfact("Turks and Caicos Islands","LandBounderies",[]). +bgfact("Turks and Caicos Islands","NaturalResources",["spiny = +lobster","conch"]). +bgfact("Turks and Caicos Islands","Population",["13552"]). +bgfact("Turks and Caicos Islands","Capital",["Grand Turk"]). +bgfact("Turks and Caicos Islands","MemberOf",["CARICOM"]). +bgfact("Turks and Caicos Islands","ExportCommodities",["lobster","dried = +and fresh conch","conch shells"]). +bgfact("Turks and Caicos Islands","ExportPartners",["US","UK"]). +bgfact("Turks and Caicos Islands","ImportCommodities",["food and = +beverages","tobacco","clothing","manubgfactures","construction = +materials"]). +bgfact("Turks and Caicos Islands","ImportPartners",["US","UK"]). +bgfact("Turks and Caicos = +Islands","Industries",["fishing","tourism","offshore financial = +services"]). +bgfact("Turks and Caicos Islands","Agriculture",["subsistence farming = +prevails","not self-sufficient in food"]). +bgfact("Tuvalu","LandBounderies",[]). +bgfact("Tuvalu","NaturalResources",["fish"]). +bgfact("Tuvalu","Population",["9831"]). +bgfact("Tuvalu","Capital",["Funafuti"]). +bgfact("Tuvalu","MemberOf",["ACP","AsDB","C","ITU","SPARTECA","SPC","SPF"= +,"UNESCO","UPU","WHO"]). +bgfact("Tuvalu","ExportCommodities",["copra"]). +bgfact("Tuvalu","ExportPartners",["Fiji","Australia","NZ"]). +bgfact("Tuvalu","ImportCommodities",["food","animals","mineral = +fuels","machinery","manubgfactured goods"]). +bgfact("Tuvalu","ImportPartners",["Fiji","Australia","NZ"]). +bgfact("Tuvalu","Industries",["fishing","tourism","copra"]). +bgfact("Tuvalu","Agriculture",["coconuts and fish"]). +bgfact("Uganda","LandBounderies",["Kenya","Rwanda","Sudan","Tanzania","Za= +ire"]). +bgfact("Uganda","NaturalResources",["copper","cobalt","limestone","salt"]= +). +bgfact("Uganda","Population",["19121934"]). +bgfact("Uganda","Capital",["Kampala"]). +bgfact("Uganda","MemberOf",["ACP","AfDB","C","CCC","EADB","ECA","FAO","G-= +77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IDB","IFAD","IFC","IGADD",= +"ILO","IMF","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","NAM","= +OAU","OIC","PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UNOSOM","UPU","W= +HO","WIPO","WMO","WTO"]). +bgfact("Uganda","ExportCommodities",["coffee","cotton","tea"]). +bgfact("Uganda","ExportPartners",["US","UK","France","Spain"]). +bgfact("Uganda","ImportCommodities",["petroleum = +products","machinery","cotton piece goods","metals","transportation = +equipment","food"]). +bgfact("Uganda","ImportPartners",["Kenya","UK","Italy"]). +bgfact("Uganda","Industries",["sugar","brewing","tobacco","cotton = +textiles","cement"]). +bgfact("Uganda","Agriculture",["coffee","tea","cotton","food = +cassava","potatoes","corn","millet","livestock beef","goat = +meat","milk","self-sufficient in food"]). +bgfact("Ukraine","LandBounderies",["Belarus","Hungary","Moldova","Poland"= +,"Romania","Russia","Slovakia"]). +bgfact("Ukraine","NaturalResources",["iron = +ore","coal","manganese","natural = +gas","oil","salt","sulphur","graphite","titanium","magnesium","kaolin","n= +ickel","mercury","timber"]). +bgfact("Ukraine","Population",["51846958"]). +bgfact("Ukraine","Capital",["Kiev"]). +bgfact("Ukraine","MemberOf",["BSEC","CBSS","INTERPOL","IOC","ITU","NACC",= +"PCA","UN","UNCTAD","UNESCO","UNIDO","UNPROFOR","UPU","WHO","WIPO","WMO"]= +). +bgfact("Ukraine","ExportCommodities",["coal","electric power","ferrous = +and nonferrous metals","chemicals","machinery and transport = +equipment","grain","meat"]). +bgfact("Ukraine","ExportPartners",["FSU = +countries","Germany","China","Austria"]). +bgfact("Ukraine","ImportCommodities",["machinery and = +parts","transportation equipment","chemicals","textiles"]). +bgfact("Ukraine","ImportPartners",["FSU = +countries","Germany","China","Austria"]). +bgfact("Ukraine","Industries",["coal","electric power","ferrous and = +nonferrous metals","machinery and transport = +equipment","chemicals","food-processing"]). +bgfact("Ukraine","Agriculture",["grain","vegetables","meat","milk","sugar= + beets"]). +bgfact("United Arab Emirates","LandBounderies",["Oman","Saudi Arabia"]). +bgfact("United Arab Emirates","NaturalResources",["petroleum","natural = +gas"]). +bgfact("United Arab Emirates","Population",["2791141"]). +bgfact("United Arab Emirates","Capital",["Abu Dhabi"]). +bgfact("United Arab = +Emirates","MemberOf",["ABEDA","AFESD","AL","AMF","CAEU","CCC","ESCWA","FA= +O","G-77","GATT","GCC","IAEA","IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO= +","IMF","IMO","INMARSAT","INTELSAT","INTERPOL","IOC","ISO","ITU","LORCS",= +"NAM","OAPEC","OIC","OPEC","UN","UNCTAD","UNESCO","UNIDO","UNOSOM","UPU",= +"WHO","WIPO","WMO","WTO"]). +bgfact("United Arab Emirates","ExportCommodities",["crude","natural = +gas","re-exports","dried fish","dates"]). +bgfact("United Arab = +Emirates","ExportPartners",["Japan","Singapore","Korea","Iran","India"]).= + +bgfact("United Arab Emirates","ImportCommodities",["manubgfactured = +goods","machinery and transport equipment","food"]). +bgfact("United Arab = +Emirates","ImportPartners",["Japan","UK","US","Germany"]). +bgfact("United Arab = +Emirates","Industries",["petroleum","fishing","petrochemicals","construct= +ion materials","some boat building","handicrafts","pearling"]). +bgfact("United Arab Emirates","Agriculture",["food = +vegetables","watermelons","poultry","eggs","dairy","only self-sufficient = +in food"]). +bgfact("United Kingdom","LandBounderies",["Ireland"]). +bgfact("United Kingdom","NaturalResources",["coal","petroleum","natural = +gas","tin","limestone","iron = +ore","salt","clay","chalk","gypsum","lead","silica"]). +bgfact("United Kingdom","Population",["58135110"]). +bgfact("United Kingdom","Capital",["London"]). +bgfact("United = +Kingdom","MemberOf",["AfDB","AG","ISO","ITU","LORCS","MINURSO","MTRC","NA= +CC","NATO","NEA","NSG","OECD","PCA","SPC","UN","UNCTAD","UNFICYP","UNHCR"= +,"UNIDO","UNIKOM","UNPROFOR","UNRWA","UN Security Council","UNTAC","UN = +Trusteeship Council","UPU","WCL","WEU","WHO","WIPO","WMO","ZC"]). +bgfact("United Kingdom","ExportCommodities",["manubgfactured = +goods","machinery","fuels","chemicals","semifinished goods","transport = +equipment"]). +bgfact("United Kingdom","ExportPartners",["EC countries","US"]). +bgfact("United Kingdom","ImportCommodities",["manubgfactured = +goods","machinery","semifinished goods","foodstuffs","consumer goods"]). +bgfact("United Kingdom","ImportPartners",["EC countries","US"]). +bgfact("United Kingdom","Industries",["production machinery including = +machine tools","electric power equipment","equipment for the automation = +of production","railroad equipment","shipbuilding","aircraft","motor = +vehicles and parts","electronics and communications = +equipment","metals","chemicals","coal","petroleum","paper and paper = +products","food processing","textiles","clothing"]). +bgfact("United Kingdom","Agriculture",["about self-sufficient in food = +and feed needs"]). +bgfact("United States","LandBounderies",["Canada","Mexico"]). +bgfact("United = +States","NaturalResources",["coal","copper","lead","molybdenum","phosphat= +es","uranium","bauxite","gold","iron","mercury","nickel","potash","silver= +","tungsten","zinc","petroleum","natural gas","timber"]). +bgfact("United States","Population",["260713585"]). +bgfact("United States","Capital",["Washington, DC"]). +bgfact("United = +States","MemberOf",["AfDB","AG","ANZUS","APEC","AsDB","Australian = +Group","BIS","CCC","COCOM","CP","CSCE","EBRD","ECE","ECLAC","FAO","ESCAP"= +,"G-2","G-5","G-7","G-8","G-10","GATT","IADB","IAEA","IBRD","ICAO","ICC",= +"ICFTU","IDA","IEA","IFAD","IFC","ILO","IMF","IMO","INMARSAT","INTELSAT",= +"INTERPOL","IOC","IOM","ISO","ITU","LORCS","MINURSO","MTCR","NACC","NATO"= +,"NEA","NSG","OAS","OECD","PCA","SPC","UN","UNCTAD","UNHCR","UNIDO","UNIK= +OM","UNOSOM","UNRWA","UN Security Council","UNTAC","UN Trusteeship = +Council","UNTSO","UPU","WCL","WHO","WIPO","WMO","WTO","ZC"]). +bgfact("United States","ExportCommodities",["Capital = +goods","automobiles","industrial supplies and raw materials","consumer = +goods","agricultural products"]). +bgfact("United States","ExportPartners",["Western = +Europe","Canada","Japan"]). +bgfact("United States","ImportCommodities",["crude and refined petroleum = +products","machinery","automobiles","consumer goods","industrial raw = +materials","food and beverages"]). +bgfact("United States","ImportPartners",["Canada","Western = +Europe","Japan"]). +bgfact("United States","Industries",["leading industrial power in the = +world","petroleum","steel","motor = +vehicles","aerospace","telecommunications","chemicals","electronics","foo= +d processing","consumer goods","lumber","mining"]). +bgfact("United States","Agriculture",["fish catch of million metric = +tons"]). +bgfact("Uruguay","LandBounderies",["Argentina","Brazil"]). +bgfact("Uruguay","NaturalResources",["soil","hydropower = +potential","minor minerals"]). +bgfact("Uruguay","Population",["3198910"]). +bgfact("Uruguay","Capital",["Montevideo"]). +bgfact("Uruguay","MemberOf",["AG","OAS","OPANAL","PCA","RG","UN","UNCTAD"= +,"UNESCO","UNIDO","UNIKOM","UNMOGIP","UNOMOZ","UNTAC","UPU","WCL","WFTU",= +"WHO","WIPO","WMO","WTO"]). +bgfact("Uruguay","ExportCommodities",["wool and textile = +manubgfactures","leather","rice"]). +bgfact("Uruguay","ExportPartners",["Brazil","Argentina","US","China","Ita= +ly"]). +bgfact("Uruguay","ImportCommodities",["machinery and = +equipment","vehicles","chemicals","minerals","plastics"]). +bgfact("Uruguay","ImportPartners",["Brazil","Argentina","US","Nigeria"]).= + +bgfact("Uruguay","Industries",["meat processing","wool and = +hides","sugar","textiles","footwear","leather = +apparel","tires","cement","fishing","petroleum refining","wine"]). +bgfact("Uruguay","Agriculture",["wheat","rice","corn","self-sufficient = +in most basic foodstuffs"]). +bgfact("Uzbekistan","LandBounderies",["Afghanistan","Kazakhstan","Kyrgyzs= +tan","Tajikistan","Turkmenistan"]). +bgfact("Uzbekistan","NaturalResources",["natural = +gas","petroleum","coal","gold","uranium","silver","copper","lead and = +zinc","tungsten","molybdenum"]). +bgfact("Uzbekistan","Population",["22608866"]). +bgfact("Uzbekistan","Capital",["Tashkent"]). +bgfact("Uzbekistan","MemberOf",["CCC","CIS","CSCE","EBRD","ECE","ECO","ES= +CAP","IBRD","ICAO","IDA","IFC","ILO","IMF","IOC","ITU","NACC","NAM","UN",= +"UNCTAD","WHO","WMO"]). +bgfact("Uzbekistan","ExportCommodities",["cotton","gold","natural = +gas","mineral fertilizers","ferrous metals","textiles","food = +products"]). +bgfact("Uzbekistan","ExportPartners",["Russia","Ukraine","Eastern = +Europe","US"]). +bgfact("Uzbekistan","ImportCommodities",["grain","machinery and = +parts","consumer durables"]). +bgfact("Uzbekistan","ImportPartners",["Czech Republic"]). +bgfact("Uzbekistan","Industries",["textiles","food processing","machine = +building","metallurgy","natural gas"]). +bgfact("Uzbekistan","Agriculture",["livestock","cotton","vegetables","fru= +its","grain"]). +bgfact("Vanuatu","LandBounderies",[]). +bgfact("Vanuatu","NaturalResources",["manganese","hardwood = +forests","fish"]). +bgfact("Vanuatu","Population",["169776"]). +bgfact("Vanuatu","Capital",["Port-Vila"]). +bgfact("Vanuatu","MemberOf",["ACCT","ACP","AsDB","C","ESCAP","FAO","G-77"= +,"IBRD","ICAO","IDA","IFC","IMF","IMO","INTELSAT","IOC","ITU","NAM","SPAR= +TECA","SPC","SPF","UN","UNCTAD","UNIDO","UPU","WHO","WMO"]). +bgfact("Vanuatu","ExportCommodities",["copra","beef","cocoa","timber","co= +ffee"]). +bgfact("Vanuatu","ExportPartners",["Netherlands","Japan","France","New = +Caledonia","Belgium"]). +bgfact("Vanuatu","ImportCommodities",["machines and vehicles","food and = +beverages","basic manubgfactures","raw materials and = +fuels","chemicals"]). +bgfact("Vanuatu","ImportPartners",["Australia","Japan","NZ","France","Fij= +i"]). +bgfact("Vanuatu","Industries",["food and fish freezing","wood = +processing","meat canning"]). +bgfact("Vanuatu","Agriculture",["export = +coconuts","cocoa","coffee","subsistence = +taro","yams","coconuts","fruits","vegetables"]). +bgfact("Venezuela","LandBounderies",["Brazil","Colombia","Guyana"]). +bgfact("Venezuela","NaturalResources",["petroleum","natural gas","iron = +ore","gold","bauxite","hydropower","diamonds"]). +bgfact("Venezuela","Population",["20562405"]). +bgfact("Venezuela","Capital",["Caracas"]). +bgfact("Venezuela","MemberOf",["AG","BCIE","CARICOM","CDB","CG","ECLAC","= +FAO","G-3","G-11","G-15","G-19","G-24","G-77","GATT","IADB","IAEA","IBRD"= +,"ICAO","ICC","ICFTU","IFAD","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL= +","IOC","IOM","ISO","ITU","LAES","LAIA","LORCS","MINURSO","NAM","OAS","ON= +USAL","OPANAL","OPEC","PCA","RG","UN","UNCTAD","UNESCO","UNHCR","UNIDO","= +UNIKOM","UNPROFOR","UPU","WCL","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Venezuela","ExportCommodities",["petroleum","bauxite and = +aluminum","steel","chemicals","agricultural products","basic = +manubgfactures"]). +bgfact("Venezuela","ExportPartners",["US and Puerto = +Rico","Japan","Netherlands","Italy"]). +bgfact("Venezuela","ImportCommodities",["raw materials","machinery and = +equipment","transport equipment","construction materials"]). +bgfact("Venezuela","ImportPartners",["US","Germany","Japan","Netherlands"= +,"Canada"]). +bgfact("Venezuela","Industries",["petroleum","iron-ore = +mining","construction materials","food = +processing","textiles","steel","aluminum","motor vehicle assembly"]). +bgfact("Venezuela","Agriculture",["corn","sorghum","sugarcane","rice","ba= +nanas","vegetables","coffee","beef","pork","milk","eggs"]). +bgfact("Vietnam","LandBounderies",["Cambodia","China","Laos"]). +bgfact("Vietnam","NaturalResources",["phosphates","coal","manganese","bau= +xite","chromate","offshore oil deposits","forests"]). +bgfact("Vietnam","Population",["73103898"]). +bgfact("Vietnam","Capital",["Hanoi"]). +bgfact("Vietnam","MemberOf",["ACCT","AsDB","ASEAN","ISO","ITU","LORCS","N= +AM","UN","UNCTAD","UNESCO","UNIDO","UPU","WCL","WFTU","WHO","WIPO","WMO",= +"WTO"]). +bgfact("Vietnam","ExportCommodities",["petroleum","rice","agricultural = +products","marine products","coffee"]). +bgfact("Vietnam","ExportPartners",["Japan","Hong = +Kong","Thailand","Germany","Indonesia"]). +bgfact("Vietnam","ImportCommodities",["petroleum products","steel = +products","railroad equipment","chemicals","medicines","raw = +cotton","fertilizer","grain"]). +bgfact("Vietnam","ImportPartners",["Hong = +Kong","Japan","Indonesia","South Korea","Taiwan"]). +bgfact("Vietnam","Industries",["food processing","textiles","machine = +building","mining","cement","chemical = +fertilizer","glass","tires","oil"]). +bgfact("Vietnam","Agriculture",["paddy rice","corn","commercial = +crops"]). +bgfact("Virgin Islands","LandBounderies",[]). +bgfact("Virgin Islands","NaturalResources",["sun","sand","sea","surf"]). +bgfact("Virgin Islands","Population",["97564"]). +bgfact("Virgin Islands","Capital",["Charlotte Amalie"]). +bgfact("Virgin Islands","MemberOf",["ECLAC","IOC"]). +bgfact("Virgin Islands","ExportCommodities",["refined petroleum = +products"]). +bgfact("Virgin Islands","ExportPartners",["US","Puerto Rico"]). +bgfact("Virgin = +Islands","ImportCommodities",["crude","foodstuffs","consumer = +goods","building materials"]). +bgfact("Virgin Islands","ImportPartners",["US","Puerto Rico"]). +bgfact("Virgin Islands","Industries",["tourism","petroleum = +refining","watch assembly","rum = +distilling","construction","pharmaceuticals","textiles","electronics"]). +bgfact("Virgin Islands","Agriculture",["truck gardens","food = +crops","fruit","sorghum","Senepol cattle"]). +bgfact("Wake Island","LandBounderies",[]). +bgfact("Wake Island","NaturalResources",["none"]). +bgfact("Wake Island","Population",["302"]). +bgfact("Wake Island","Capital",["none; administered from Washington, = +DC"]). +bgfact("Wallis and Futuna","LandBounderies",[]). +bgfact("Wallis and Futuna","NaturalResources",["negligible"]). +bgfact("Wallis and Futuna","Population",["14338"]). +bgfact("Wallis and Futuna","Capital",["Mata-Utu"]). +bgfact("Wallis and Futuna","MemberOf",["FZ","SPC"]). +bgfact("Wallis and Futuna","ExportCommodities",["copra","handicrafts"]). +bgfact("Wallis and Futuna","ExportPartners",["NA"]). +bgfact("Wallis and = +Futuna","ImportCommodities",["foodstuffs","manubgfactured = +goods","transportation equipment","fuel"]). +bgfact("Wallis and Futuna","ImportPartners",["France","Australia","New = +Zealand"]). +bgfact("Wallis and = +Futuna","Industries",["copra","handicrafts","fishing","lumber"]). +bgfact("Wallis and Futuna","Agriculture",["dominated by coconut = +production","with subsistence crops of yams","taro","bananas"]). +bgfact("West Bank","LandBounderies",["Israel","Jordan"]). +bgfact("West Bank","NaturalResources",["negligible"]). +bgfact("West Bank","Population",["1443790"]). +bgfact("West Bank","ExportCommodities",["olives","fruit","vegetables"]). +bgfact("West Bank","ExportPartners",["Jordan","Israel"]). +bgfact("West Bank","ImportCommodities",["food","consumer = +goods","construction materials"]). +bgfact("West Bank","ImportPartners",["Jordan","Israel"]). +bgfact("West Bank","Industries",[]). +bgfact("West Bank","Agriculture",["olives","vegetables","beef"]). +bgfact("Western = +Sahara","LandBounderies",["Algeria","Mauritania","Morocco"]). +bgfact("Western Sahara","NaturalResources",["phosphates","iron ore"]). +bgfact("Western Sahara","Population",["211877"]). +bgfact("Western Sahara","Capital",["none"]). +bgfact("Western Sahara","MemberOf",["none"]). +bgfact("Western Sahara","ExportCommodities",["phosphates"]). +bgfact("Western Sahara","ExportPartners",["Morocco claims and = +administers Western Sahara","so trade partners are included in overall = +Moroccan accounts"]). +bgfact("Western Sahara","ImportCommodities",["fuel for fishing = +fleet","foodstuffs"]). +bgfact("Western Sahara","ImportPartners",["Morocco claims and = +administers Western Sahara","so trade partners are included in overall = +Moroccan accounts"]). +bgfact("Western Sahara","Industries",["phosphate = +mining","fishing","handicrafts"]). +bgfact("Western Sahara","Agriculture",["camels","sheep","economy exists = +largely for the garrison forces"]). +bgfact("Western Samoa","LandBounderies",[]). +bgfact("Western Samoa","NaturalResources",["hardwood forests","fish"]). +bgfact("Western Samoa","Population",["204447"]). +bgfact("Western Samoa","Capital",["Apia"]). +bgfact("Western = +Samoa","MemberOf",["ACP","AsDB","C","ESCAP","FAO","G-77","IBRD","ICFTU","= +IDA","IFAD","IFC","IMF","INTELSAT","IOC","ITU","LORCS","SPARTECA","SPC","= +SPF","UN","UNCTAD","UNESCO","UPU","WHO"]). +bgfact("Western Samoa","ExportCommodities",["coconut oil and = +cream","taro","copra","cocoa"]). +bgfact("Western Samoa","ExportPartners",["New Zealand","American = +Samoa","Germany","Australia"]). +bgfact("Western Samoa","ImportCommodities",["intermediate = +goods","food","Capital goods"]). +bgfact("Western Samoa","ImportPartners",["New = +Zealand","Australia","Japan","Fiji"]). +bgfact("Western Samoa","Industries",["timber","tourism","food = +processing","fishing"]). +bgfact("Western Samoa","Agriculture",["coconuts","fruit"]). +bgfact("Yemen","LandBounderies",["Oman","Saudi Arabia"]). +bgfact("Yemen","NaturalResources",["petroleum","fish","rock = +salt","marble","small deposits of coal","gold","lead","nickel","fertile = +soil in west"]). +bgfact("Yemen","Population",["11105202"]). +bgfact("Yemen","Capital",["Sanaa"]). +bgfact("Yemen","MemberOf",["ACC","AFESD","AL","AMF","CAEU","ESCWA","FAO",= +"G-77","IBRD","ICAO","IDA","IDB","IFAD","IFC","ILO","IMF","IMO","INTELSAT= +","INTERPOL","IOC","ITU","LORCS","NAM","OIC","UN","UNCTAD","UNESCO","UNID= +O","UPU","WFTU","WHO","WIPO","WMO","WTO"]). +bgfact("Yemen","ExportCommodities",["crude","cotton","coffee","hides","ve= +getables","dried and salted fish"]). +bgfact("Yemen","ExportPartners",["Italy","US","Jordan"]). +bgfact("Yemen","ImportCommodities",["petroleum = +products","sugar","grain","flour","cement","machinery","chemicals"]). +bgfact("Yemen","ImportPartners",["UAE","Japan","Saudi = +Arabia","Kuwait","US"]). +bgfact("Yemen","Industries",["cement"]). +bgfact("Yemen","Agriculture",["grain","fruits","vegetables","qat","coffee= +","cotton","dairy","poultry","meat","not self-sufficient in grain"]). +bgfact("Zaire","LandBounderies",["Angola","Burundi","Central African = +Republic","Congo","Rwanda","Sudan","Uganda","Zambia"]). +bgfact("Zaire","NaturalResources",["cobalt","copper","cadmium","petroleum= +","industrial and gem = +diamonds","gold","silver","zinc","manganese","tin","germanium","uranium",= +"radium","bauxite","iron ore","coal","hydropower potential"]). +bgfact("Zaire","Population",["42684091"]). +bgfact("Zaire","Capital",["Kinshasa"]). +bgfact("Zaire","MemberOf",["ACCT","ACP","AfDB","CCC","CEEAC","CEPGL","ECA= +","FAO","G-19","G-24","G-77","GATT","IAEA","IBRD","ICAO","ICC","IDA","IFA= +D","IFC","ILO","IMF","IMO","INTELSAT","INTERPOL","IOC","ITU","LORCS","NAM= +","OAU","PCA","UN","UNCTAD","UNESCO","UNHCR","UNIDO","UPU","WCL","WFTU","= +WHO","WIPO","WMO","WTO"]). +bgfact("Zaire","ExportCommodities",["copper","coffee","diamonds","cobalt"= +,"crude"]). +bgfact("Zaire","ExportPartners",["US","Belgium","France","Germany","Italy= +","UK","Japan","South Africa"]). +bgfact("Zaire","ImportCommodities",["consumer = +goods","foodstuffs","transport equipment","fuels"]). +bgfact("Zaire","ImportPartners",["South = +Africa","US","Belgium","France","Germany","Italy","Japan","UK"]). +bgfact("Zaire","Industries",["mining","mineral processing","consumer = +products","processed foods and beverages","cement","diamonds"]). +bgfact("Zaire","Agriculture",["coffee","palm oil","rubber","food = +cassava","bananas","root crops","corn"]). +bgfact("Zambia","LandBounderies",["Angola","Malawi","Mozambique","Namibia= +","Tanzania","Zaire","Zimbabwe"]). +bgfact("Zambia","NaturalResources",["copper","cobalt","zinc","lead","coal= +","emeralds","gold","silver","uranium","hydropower potential"]). +bgfact("Zambia","Population",["9188190"]). +bgfact("Zambia","Capital",["Lusaka"]). +bgfact("Zambia","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","FLS","G-1= +9","G-77","GATT","IAEA","IBRD","ICAO","IDA","IFAD","IFC","IFTU","ILO","IM= +F","INTELSAT","INTERPOL","IOC","IOM","ITU","LORCS","NAM","OAU","SADC","UN= +","UNCTAD","UNESCO","UNIDO","UNOMOZ","UNOSOM","UPU","WCL","WHO","WIPO","W= +MO","WTO"]). +bgfact("Zambia","ExportCommodities",["copper","zinc","cobalt","lead","tob= +acco"]). +bgfact("Zambia","ExportPartners",["EC countries","Japan","South = +Africa","US","India"]). +bgfact("Zambia","ImportCommodities",["machinery","transportation = +equipment","foodstuffs","fuels","manubgfactures"]). +bgfact("Zambia","ImportPartners",["EC countries","Japan","Saudi = +Arabia","South Africa","US"]). +bgfact("Zambia","Industries",["copper mining and = +processing","construction","foodstuffs","beverages","chemicals","textiles= +"]). +bgfact("Zambia","Agriculture",["corn","sorghum","rice","peanuts","sunflow= +er","tobacco","cotton","sugarcane","cattle","goats","beef","eggs"]). +bgfact("Zimbabwe","LandBounderies",["Botswana","Mozambique","South = +Africa","Zambia"]). +bgfact("Zimbabwe","NaturalResources",["coal","chromium = +ore","asbestos","gold","nickel","copper","iron = +ore","vanadium","lithium","tin","platinum group metals"]). +bgfact("Zimbabwe","Population",["10975078"]). +bgfact("Zimbabwe","Capital",["Harare"]). +bgfact("Zimbabwe","MemberOf",["ACP","AfDB","C","CCC","ECA","FAO","FLS","G= +-15","G-77","GATT","IAEA","IBRD","ICAO","ICFTU","IDA","IFAD","IFC","ILO",= +"IMF","INTELSAT","INTERPOL","IOC","IOM","ISO","ITU","LORCS","NAM","OAU","= +PCA","SADC","UN","UNAVEM = +II","UNCTAD","UNESCO","UNIDO","UNOMUR","UNOSOM","UPU","WCL","WHO","WIPO",= +"WMO","WTO"]). +bgfact("Zimbabwe","ExportCommodities",["agricultural"]). +bgfact("Zimbabwe","ExportPartners",["UK","Germany","South = +Africa","Japan","US"]). +bgfact("Zimbabwe","ImportCommodities",["machinery and transportation = +equipment","chemicals","fuels"]). +bgfact("Zimbabwe","ImportPartners",["South = +Africa","UK","Germany","US","Japan"]). +bgfact("Zimbabwe","Industries",["mining","steel","clothing and = +footwear","chemicals","foodstuffs","fertilizer","beverage","transportatio= +n equipment","wood products"]). +bgfact("Zimbabwe","Agriculture",["of land area divided = +into","corn","cotton","tobacco","wheat","coffee","sugarcane","livestock = +- cattle","sheep","goats","self-sufficient in food"]). + + + diff --git a/src/test/data/reuters-21578/reut2-000.sgm b/src/test/data/reuters-21578/reut2-000.sgm new file mode 100644 index 00000000000..5cfb97b1b74 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-000.sgm @@ -0,0 +1,2032 @@ +<!DOCTYPE lewis SYSTEM "lewis.dtd"> +<REUTERS TOPICS="YES" LEWISSPLIT="TRAIN" CGISPLIT="TRAINING-SET" OLDID="5544" NEWID="1"> +<DATE>26-FEB-1987 15:01:01.79</DATE> +<TOPICS><D>cocoa</D></TOPICS> +<PLACES><D>el-salvador</D><D>usa</D><D>uruguay</D></PLACES> +<PEOPLE></PEOPLE> +<ORGS></ORGS> +<EXCHANGES></EXCHANGES> +<COMPANIES></COMPANIES> +<UNKNOWN> +C T +f0704reute +u f BC-BAHIA-COCOA-REVIEW 02-26 0105</UNKNOWN> +<TEXT> +<TITLE>BAHIA COCOA REVIEW + SALVADOR, Feb 26 - Showers continued throughout the week in +the Bahia cocoa zone, alleviating the drought since early +January and improving prospects for the coming temporao, +although normal humidity levels have not been restored, +Comissaria Smith said in its weekly review. + The dry period means the temporao will be late this year. + Arrivals for the week ended February 22 were 155,221 bags +of 60 kilos making a cumulative total for the season of 5.93 +mln against 5.81 at the same stage last year. Again it seems +that cocoa delivered earlier on consignment was included in the +arrivals figures. + Comissaria Smith said there is still some doubt as to how +much old crop cocoa is still available as harvesting has +practically come to an end. With total Bahia crop estimates +around 6.4 mln bags and sales standing at almost 6.2 mln there +are a few hundred thousand bags still in the hands of farmers, +middlemen, exporters and processors. + There are doubts as to how much of this cocoa would be fit +for export as shippers are now experiencing dificulties in +obtaining +Bahia superior+ certificates. + In view of the lower quality over recent weeks farmers have +sold a good part of their cocoa held on consignment. + Comissaria Smith said spot bean prices rose to 340 to 350 +cruzados per arroba of 15 kilos. + Bean shippers were reluctant to offer nearby shipment and +only limited sales were booked for March shipment at 1,750 to +1,780 dlrs per tonne to ports to be named. + New crop sales were also light and all to open ports with +June/July going at 1,850 and 1,880 dlrs and at 35 and 45 dlrs +under New York july, Aug/Sept at 1,870, 1,875 and 1,880 dlrs +per tonne FOB. + Routine sales of butter were made. March/April sold at +4,340, 4,345 and 4,350 dlrs. + April/May butter went at 2.27 times New York May, June/July +at 4,400 and 4,415 dlrs, Aug/Sept at 4,351 to 4,450 dlrs and at +2.27 and 2.28 times New York Sept and Oct/Dec at 4,480 dlrs and +2.27 times New York Dec, Comissaria Smith said. + Destinations were the U.S., Covertible currency areas, +Uruguay and open ports. + Cake sales were registered at 785 to 995 dlrs for +March/April, 785 dlrs for May, 753 dlrs for Aug and 0.39 times +New York Dec for Oct/Dec. + Buyers were the U.S., Argentina, Uruguay and convertible +currency areas. + Liquor sales were limited with March/April selling at 2,325 +and 2,380 dlrs, June/July at 2,375 dlrs and at 1.25 times New +York July, Aug/Sept at 2,400 dlrs and at 1.25 times New York +Sept and Oct/Dec at 1.25 times New York Dec, Comissaria Smith +said. + Total Bahia sales are currently estimated at 6.13 mln bags +against the 1986/87 crop and 1.06 mln bags against the 1987/88 +crop. + Final figures for the period to February 28 are expected to +be published by the Brazilian Cocoa Trade Commission after +carnival which ends midday on February 27. + Reuter + + + +26-FEB-1987 15:02:20.00 + +usa + + + + + +F Y +f0708reute +d f BC-STANDARD-OIL-<SRD>-TO 02-26 0082 + +STANDARD OIL <SRD> TO FORM FINANCIAL UNIT + CLEVELAND, Feb 26 - Standard Oil Co and BP North America +Inc said they plan to form a venture to manage the money market +borrowing and investment activities of both companies. + BP North America is a subsidiary of British Petroleum Co +Plc <BP>, which also owns a 55 pct interest in Standard Oil. + The venture will be called BP/Standard Financial Trading +and will be operated by Standard Oil under the oversight of a +joint management committee. + + Reuter + + + +26-FEB-1987 15:03:27.51 + +usa + + + + + +F A +f0714reute +d f BC-TEXAS-COMMERCE-BANCSH 02-26 0064 + +TEXAS COMMERCE BANCSHARES <TCB> FILES PLAN + HOUSTON, Feb 26 - Texas Commerce Bancshares Inc's Texas +Commerce Bank-Houston said it filed an application with the +Comptroller of the Currency in an effort to create the largest +banking network in Harris County. + The bank said the network would link 31 banks having +13.5 billion dlrs in assets and 7.5 billion dlrs in deposits. + + Reuter + + + +26-FEB-1987 15:07:13.72 + +usabrazil + + + + + +F +f0725reute +u f BC-TALKING-POINT/BANKAME 02-26 0105 + +TALKING POINT/BANKAMERICA <BAC> EQUITY OFFER + by Janie Gabbett, Reuters + LOS ANGELES, Feb 26 - BankAmerica Corp is not under +pressure to act quickly on its proposed equity offering and +would do well to delay it because of the stock's recent poor +performance, banking analysts said. + Some analysts said they have recommended BankAmerica delay +its up to one-billion-dlr equity offering, which has yet to be +approved by the Securities and Exchange Commission. + BankAmerica stock fell this week, along with other banking +issues, on the news that Brazil has suspended interest payments +on a large portion of its foreign debt. + The stock traded around 12, down 1/8, this afternoon, +after falling to 11-1/2 earlier this week on the news. + Banking analysts said that with the immediate threat of the +First Interstate Bancorp <I> takeover bid gone, BankAmerica is +under no pressure to sell the securities into a market that +will be nervous on bank stocks in the near term. + BankAmerica filed the offer on January 26. It was seen as +one of the major factors leading the First Interstate +withdrawing its takeover bid on February 9. + A BankAmerica spokesman said SEC approval is taking longer +than expected and market conditions must now be re-evaluated. + "The circumstances at the time will determine what we do," +said Arthur Miller, BankAmerica's Vice President for Financial +Communications, when asked if BankAmerica would proceed with +the offer immediately after it receives SEC approval. + "I'd put it off as long as they conceivably could," said +Lawrence Cohn, analyst with Merrill Lynch, Pierce, Fenner and +Smith. + Cohn said the longer BankAmerica waits, the longer they +have to show the market an improved financial outlook. + Although BankAmerica has yet to specify the types of +equities it would offer, most analysts believed a convertible +preferred stock would encompass at least part of it. + Such an offering at a depressed stock price would mean a +lower conversion price and more dilution to BankAmerica stock +holders, noted Daniel Williams, analyst with Sutro Group. + Several analysts said that while they believe the Brazilian +debt problem will continue to hang over the banking industry +through the quarter, the initial shock reaction is likely to +ease over the coming weeks. + Nevertheless, BankAmerica, which holds about 2.70 billion +dlrs in Brazilian loans, stands to lose 15-20 mln dlrs if the +interest rate is reduced on the debt, and as much as 200 mln +dlrs if Brazil pays no interest for a year, said Joseph +Arsenio, analyst with Birr, Wilson and Co. + He noted, however, that any potential losses would not show +up in the current quarter. + With other major banks standing to lose even more than +BankAmerica if Brazil fails to service its debt, the analysts +said they expect the debt will be restructured, similar to way +Mexico's debt was, minimizing losses to the creditor banks. + Reuter + + + +26-FEB-1987 15:10:44.60 +grainwheatcornbarleyoatsorghum +usa + + + + + +C G +f0738reute +u f BC-average-prices 02-26 0095 + +NATIONAL AVERAGE PRICES FOR FARMER-OWNED RESERVE + WASHINGTON, Feb 26 - The U.S. Agriculture Department +reported the farmer-owned reserve national five-day average +price through February 25 as follows (Dlrs/Bu-Sorghum Cwt) - + Natl Loan Release Call + Avge Rate-X Level Price Price + Wheat 2.55 2.40 IV 4.65 -- + V 4.65 -- + VI 4.45 -- + Corn 1.35 1.92 IV 3.15 3.15 + V 3.25 -- + X - 1986 Rates. + + Natl Loan Release Call + Avge Rate-X Level Price Price + Oats 1.24 0.99 V 1.65 -- + Barley n.a. 1.56 IV 2.55 2.55 + V 2.65 -- + Sorghum 2.34 3.25-Y IV 5.36 5.36 + V 5.54 -- + Reserves I, II and III have matured. Level IV reflects +grain entered after Oct 6, 1981 for feedgrain and after July +23, 1981 for wheat. Level V wheat/barley after 5/14/82, +corn/sorghum after 7/1/82. Level VI covers wheat entered after +January 19, 1984. X-1986 rates. Y-dlrs per CWT (100 lbs). +n.a.-not available. + Reuter + + + +26-FEB-1987 15:14:36.41 +veg-oillinseedlin-oilsoy-oilsun-oilsoybeanoilseedcornsunseedgrainsorghumwheat +argentina + + + + + +G +f0754reute +r f BC-ARGENTINE-1986/87-GRA 02-26 0066 + +ARGENTINE 1986/87 GRAIN/OILSEED REGISTRATIONS + BUENOS AIRES, Feb 26 - Argentine grain board figures show +crop registrations of grains, oilseeds and their products to +February 11, in thousands of tonnes, showing those for futurE +shipments month, 1986/87 total and 1985/86 total to February +12, 1986, in brackets: + Bread wheat prev 1,655.8, Feb 872.0, March 164.6, total +2,692.4 (4,161.0). + Maize Mar 48.0, total 48.0 (nil). + Sorghum nil (nil) + Oilseed export registrations were: + Sunflowerseed total 15.0 (7.9) + Soybean May 20.0, total 20.0 (nil) + The board also detailed export registrations for +subproducts, as follows, + SUBPRODUCTS + Wheat prev 39.9, Feb 48.7, March 13.2, Apr 10.0, total +111.8 (82.7) . + Linseed prev 34.8, Feb 32.9, Mar 6.8, Apr 6.3, total 80.8 +(87.4). + Soybean prev 100.9, Feb 45.1, MAr nil, Apr nil, May 20.0, +total 166.1 (218.5). + Sunflowerseed prev 48.6, Feb 61.5, Mar 25.1, Apr 14.5, +total 149.8 (145.3). + Vegetable oil registrations were : + Sunoil prev 37.4, Feb 107.3, Mar 24.5, Apr 3.2, May nil, +Jun 10.0, total 182.4 (117.6). + Linoil prev 15.9, Feb 23.6, Mar 20.4, Apr 2.0, total 61.8, +(76.1). + Soybean oil prev 3.7, Feb 21.1, Mar nil, Apr 2.0, May 9.0, +Jun 13.0, Jul 7.0, total 55.8 (33.7). REUTER + + + +26-FEB-1987 15:14:42.83 + +usa + + + + + +F +f0755reute +d f BC-RED-LION-INNS-FILES-P 02-26 0082 + +RED LION INNS FILES PLANS OFFERING + PORTLAND, Ore., Feb 26 - Red Lion Inns Limited Partnership +said it filed a registration statement with the Securities and +Exchange Commission covering a proposed offering of 4,790,000 +units of limited partnership interests. + The company said it expects the offering to be priced at 20 +dlrs per unit. + It said proceeds from the offering, along with a 102.5 mln +dlr mortgage loan, will be used to finance its planned +acquisition of 10 Red Lion hotels. + Reuter + + + +26-FEB-1987 15:15:40.12 + +usa + + + + + +F A RM +f0758reute +u f BC-USX-<X>-DEBT-DOWGRADE 02-26 0103 + +USX <X> DEBT DOWGRADED BY MOODY'S + NEW YORK, Feb 26 - Moody's Investors Service Inc said it +lowered the debt and preferred stock ratings of USX Corp and +its units. About seven billion dlrs of securities is affected. + Moody's said Marathon Oil Co's recent establishment of up +to one billion dlrs in production payment facilities on its +prolific Yates Field has significant negative implications for +USX's unsecured creditors. + The company appears to have positioned its steel segment +for a return to profit by late 1987, Moody's added. + Ratings lowered include those on USX's senior debt to BA-1 +from BAA-3. + Reuter + + + +26-FEB-1987 15:17:11.20 +earn +usa + + + + + +F +f0762reute +r f BC-CHAMPION-PRODUCTS-<CH 02-26 0067 + +CHAMPION PRODUCTS <CH> APPROVES STOCK SPLIT + ROCHESTER, N.Y., Feb 26 - Champion Products Inc said its +board of directors approved a two-for-one stock split of its +common shares for shareholders of record as of April 1, 1987. + The company also said its board voted to recommend to +shareholders at the annual meeting April 23 an increase in the +authorized capital stock from five mln to 25 mln shares. + Reuter + + + +26-FEB-1987 15:18:06.67 +acq +usa + + + + + +F +f0767reute +d f BC-COMPUTER-TERMINAL-SYS 02-26 0107 + +COMPUTER TERMINAL SYSTEMS <CPML> COMPLETES SALE + COMMACK, N.Y., Feb 26 - Computer Terminal Systems Inc said +it has completed the sale of 200,000 shares of its common +stock, and warrants to acquire an additional one mln shares, to +<Sedio N.V.> of Lugano, Switzerland for 50,000 dlrs. + The company said the warrants are exercisable for five +years at a purchase price of .125 dlrs per share. + Computer Terminal said Sedio also has the right to buy +additional shares and increase its total holdings up to 40 pct +of the Computer Terminal's outstanding common stock under +certain circumstances involving change of control at the +company. + The company said if the conditions occur the warrants would +be exercisable at a price equal to 75 pct of its common stock's +market price at the time, not to exceed 1.50 dlrs per share. + Computer Terminal also said it sold the technolgy rights to +its Dot Matrix impact technology, including any future +improvements, to <Woodco Inc> of Houston, Tex. for 200,000 +dlrs. But, it said it would continue to be the exclusive +worldwide licensee of the technology for Woodco. + The company said the moves were part of its reorganization +plan and would help pay current operation costs and ensure +product delivery. + Computer Terminal makes computer generated labels, forms, +tags and ticket printers and terminals. + Reuter + + + +26-FEB-1987 15:18:59.34 +earn +usa + + + + + +F +f0772reute +r f BC-COBANCO-INC-<CBCO>-YE 02-26 0058 + +COBANCO INC <CBCO> YEAR NET + SANTA CRUZ, Calif., Feb 26 - + Shr 34 cts vs 1.19 dlrs + Net 807,000 vs 2,858,000 + Assets 510.2 mln vs 479.7 mln + Deposits 472.3 mln vs 440.3 mln + Loans 299.2 mln vs 327.2 mln + Note: 4th qtr not available. Year includes 1985 +extraordinary gain from tax carry forward of 132,000 dlrs, or +five cts per shr. + Reuter + + + +26-FEB-1987 15:19:15.45 +earnacq +usa + + + + + +F +f0773reute +u f BC-OHIO-MATTRESS-<OMT>-M 02-26 0095 + +OHIO MATTRESS <OMT> MAY HAVE LOWER 1ST QTR NET + CLEVELAND, Feb 26 - Ohio Mattress Co said its first +quarter, ending February 28, profits may be below the 2.4 mln +dlrs, or 15 cts a share, earned in the first quarter of fiscal +1986. + The company said any decline would be due to expenses +related to the acquisitions in the middle of the current +quarter of seven licensees of Sealy Inc, as well as 82 pct of +the outstanding capital stock of Sealy. + Because of these acquisitions, it said, first quarter sales +will be substantially higher than last year's 67.1 mln dlrs. + Noting that it typically reports first quarter results in +late march, said the report is likely to be issued in early +April this year. + It said the delay is due to administrative considerations, +including conducting appraisals, in connection with the +acquisitions. + Reuter + + + +26-FEB-1987 15:20:13.09 +earn +usa + + + + + +F +f0775reute +r f BC-AM-INTERNATIONAL-INC 02-26 0065 + +AM INTERNATIONAL INC <AM> 2ND QTR JAN 31 + CHICAGO, Feb 26 - + Oper shr loss two cts vs profit seven cts + Oper shr profit 442,000 vs profit 2,986,000 + Revs 291.8 mln vs 151.1 mln + Avg shrs 51.7 mln vs 43.4 mln + Six mths + Oper shr profit nil vs profit 12 cts + Oper net profit 3,376,000 vs profit 5,086,000 + Revs 569.3 mln vs 298.5 mln + Avg shrs 51.6 mln vs 41.1 mln + NOTE: Per shr calculated after payment of preferred +dividends. + Results exclude credits of 2,227,000 or four cts and +4,841,000 or nine cts for 1986 qtr and six mths vs 2,285,000 or +six cts and 4,104,000 or 11 cts for prior periods from +operating loss carryforwards. + Reuter + + + +26-FEB-1987 15:20:27.17 +earn +usa + + + + + +F +f0776reute +u f BC-BROWN-FORMAN-INC-<BFD 02-26 0043 + +BROWN-FORMAN INC <BFD> 4TH QTR NET + LOUISVILLE, Ky., Feb 26 - + Shr one dlr vs 73 cts + Net 12.6 mln vs 15.8 mln + Revs 337.3 mln vs 315.2 mln + Nine mths + Shr 3.07 dlrs vs 3.08 dlrs + Net 66 mln vs 66.2 mln + Revs 1.59 billion vs 997.1 mln + Reuter + + + +26-FEB-1987 15:20:48.43 + +usa + + + + + +F +f0778reute +r f BC-NATIONAL-INTERGROUP<N 02-26 0047 + +NATIONAL INTERGROUP<NII> TO OFFER PERMIAN UNITS + PITTSBURGH, Feb 26 - National Intergroup Inc said it plans +to file a registration statement with the securities and +exchange commission for an offering of cumulative convertible +preferred partnership units in Permian Partners L.P. + The Permian Partners L.P. was recently formed by National +Intergroup to continue to business of Permian Corp, acquired by +the company in 1985. + The company said Permian will continue to manage the +business as a general partner, retaining a 35 pct stake in the +partnership in the form of common and general partnership +units. + It did not say how many units would be offered or what the +price would be. + Reuter + + + +26-FEB-1987 15:21:16.13 + +usabrazil + + + + + +RM +f0781reute +u f BC--ECONOMIC-SPOTLIGHT-- 02-26 0104 + +ECONOMIC SPOTLIGHT - BANKAMERICA <BAC> + by Janie Gabbett, Reuters + LOS ANGELES, Feb 26 - BankAmerica Corp is not under +pressure to act quickly on its proposed equity offering and +would do well to delay it because of the stock's recent poor +performance, banking analysts said. + Some analysts said they have recommended BankAmerica delay +its up to one-billion-dlr equity offering, which has yet to be +approved by the Securities and Exchange Commission. + BankAmerica stock fell this week, along with other banking +issues, on the news that Brazil has suspended interest payments +on a large portion of its foreign debt. + The stock traded around 12, down 1/8, this afternoon, +after falling to 11-1/2 earlier this week on the news. + Banking analysts said that with the immediate threat of the +First Interstate Bancorp <I> takeover bid gone, BankAmerica is +under no pressure to sell the securities into a market that +will be nervous on bank stocks in the near term. + BankAmerica filed the offer on January 26. It was seen as +one of the major factors leading the First Interstate +withdrawing its takeover bid on February 9. + A BankAmerica spokesman said SEC approval is taking longer +than expected and market conditions must now be re-evaluated. + "The circumstances at the time will determine what we do," +said Arthur Miller, BankAmerica's Vice President for Financial +Communications, when asked if BankAmerica would proceed with +the offer immediately after it receives SEC approval. + "I'd put it off as long as they conceivably could," said +Lawrence Cohn, analyst with Merrill Lynch, Pierce, Fenner and +Smith. + Cohn said the longer BankAmerica waits, the longer they +have to show the market an improved financial outlook. + Although BankAmerica has yet to specify the types of +equities it would offer, most analysts believed a convertible +preferred stock would encompass at least part of it. + Such an offering at a depressed stock price would mean a +lower conversion price and more dilution to BankAmerica stock +holders, noted Daniel Williams, analyst with Sutro Group. + Several analysts said that while they believe the Brazilian +debt problem will continue to hang over the banking industry +through the quarter, the initial shock reaction is likely to +ease over the coming weeks. + Nevertheless, BankAmerica, which holds about 2.70 billion +dlrs in Brazilian loans, stands to lose 15-20 mln dlrs if the +interest rate is reduced on the debt, and as much as 200 mln +dlrs if Brazil pays no interest for a year, said Joseph +Arsenio, analyst with Birr, Wilson and Co. + He noted, however, that any potential losses would not show +up in the current quarter. + With other major banks standing to lose even more than +BankAmerica if Brazil fails to service its debt, the analysts +said they expect the debt will be restructured, similar to way +Mexico's debt was, minimizing losses to the creditor banks. + Reuter + + + +26-FEB-1987 15:24:48.56 + +usa + + + + + +F +f0789reute +d f BC-NATIONAL-HEALTH-ENHAN 02-26 0076 + +NATIONAL HEALTH ENHANCEMENT <NHES> NEW PROGRAM + PHOENIX, Ariz., Feb 26 - National Health Enhancement +Systems Inc said it is offering a new health evaluation system +to its line of fitness assessment programs. + The company said the program, called The Health Test, will +be available in 60 days. + Customers who use the program will receive a +computer-generated report and recommendations for implementing +a program to improve their physical condition. + Reuter + + + +26-FEB-1987 15:26:26.78 +earn +usa + + + + + +F +f0796reute +r f BC-DEAN-FOODS-<DF>-SEES 02-26 0101 + +DEAN FOODS <DF> SEES STRONG 4TH QTR EARNINGS + CHICAGO, Feb 26 - Dean Foods Co expects earnings for the +fourth quarter ending May 30 to exceed those of the same +year-ago period, Chairman Kenneth Douglas told analysts. + In the fiscal 1986 fourth quarter the food processor +reported earnings of 40 cts a share. + Douglas also said the year's sales should exceed 1.4 +billion dlrs, up from 1.27 billion dlrs the prior year. + He repeated an earlier projection that third-quarter +earnings "will probably be off slightly" from last year's 40 +cts a share, falling in the range of 34 cts to 36 cts a share. + Douglas said it was too early to project whether the +anticipated fourth quarter performance would be "enough for us +to exceed the prior year's overall earnings" of 1.53 dlrs a +share. + In 1988, Douglas said Dean should experience "a 20 pct +improvement in our bottom line from effects of the tax reform +act alone." + President Howard Dean said in fiscal 1988 the company will +derive benefits of various dairy and frozen vegetable +acquisitions from Ryan Milk to the Larsen Co. + Dean also said the company will benefit from its +acquisition in late December of Elgin Blenders Inc, West +Chicago. + He said the company is a major shareholder of E.B.I. Foods +Ltd, a United Kingdom blender, and has licensing arrangements +in Australia, Canada, Brazil and Japan. + "It provides ann entry to McDonalds Corp <MCD> we've been +after for years," Douglas told analysts. + Reuter + + + +26-FEB-1987 15:26:54.12 +wheatgrain +yemen-arab-republicusa + + + + + +C G +f0798reute +u f BC-/BONUS-WHEAT-FLOUR-FO 02-26 0096 + +BONUS WHEAT FLOUR FOR NORTH YEMEN -- USDA + WASHINGTON, Feb 26 - The Commodity Credit Corporation, CCC, +has accepted an export bonus offer to cover the sale of 37,000 +long tons of wheat flour to North Yemen, the U.S. Agriculture +Department said. + The wheat four is for shipment March-May and the bonus +awarded was 119.05 dlrs per tonnes and will be paid in the form +of commodities from the CCC inventory. + The bonus was awarded to the Pillsbury Company. + The wheat flour purchases complete the Export Enhancement +Program initiative announced in April, 1986, it said. + Reuter + + + +26-FEB-1987 15:32:03.12 + +usa + + + + + +F A +f0804reute +d f BC-CREDIT-CARD-DISCLOSUR 02-26 0111 + +CREDIT CARD DISCLOSURE BILLS INTRODUCED + WASHINGTON, Feb 26 - Legislation to require disclosure of +credit card fees and interest rates before the cards are issued +have been introduced in the Senate and House. + Sen. Chris Dodd, D-Conn, a co-sponsor of the bill, said +many banks and financial institutions do not disclose all the +information about terms of their cards in promotional material +sent to prospective customers. + "By requiring card issuers to disclose the terms and +conditions of their cards at the time of solicitation, the +legislation is intended to arm consumers with enough +information to shop around for the best deal," Dodd said in a +statement. + Reuter + + + +26-FEB-1987 15:33:23.61 + +usa + + + + + +F +f0809reute +d f BC-HUGHES-CAPITAL-UNIT-S 02-26 0086 + +HUGHES CAPITAL UNIT SIGNS PACT WITH BEAR STEARNS + FORT LAUDERDALE, Fla., Feb 26 - Hughes/Conserdyne Corp, a +unit of <Hughes Capital Corp> said it made Bear Stearns and Co +Inc <BSC> its exclusive investment banker to develop and market +financing for the design and installation of its micro-utility +systems for municipalities. + The company said these systems are self-contained +electrical generating facilities using alternate power sources, +such as photovoltaic cells, to replace public utility power +sources. + Reuter + + + +26-FEB-1987 15:34:07.03 +copper +usa + + + + + +C M F +f0810reute +u f BC-magma-copper-price 02-26 0036 + +MAGMA LOWERS COPPER 0.75 CENT TO 66 CTS + NEW YORK, Feb 26 - Magma Copper Co, a subsidiary of Newmont +Mining Corp, said it is cutting its copper cathode price by +0.75 cent to 66 cents a lb, effective immediately. + Reuter + + + +26-FEB-1987 15:34:16.30 +earn +usa + + + + + +F +f0811reute +u f BC-BROWN-FORMAN-<BFDB>-S 02-26 0053 + +BROWN-FORMAN <BFDB> SETS STOCK SPLIT, UPS PAYOUT + LOUISVILLE, Ky., Feb 26 - Brown-Forman Inc said its board +has approved a three-for-two stock split and a 35 pct increase +in the company cash dividend. + The company cited its improved earnings outlook and +continued strong cash flow as reasons for raising the dividend. + Brown-Forman said the split of its Class A and Class B +common shares would be effective March 13. + The company said directors declared a quarterly cash +dividend on each new share of both classes of 28 cts, payable +April one to holders of record March 20. Prior to the split, +the company had paid 31 cts quarterly. + Brown-Forman today reported a 37 pct increase in third +quarter profits to 21.6 mln dlrs, or 1.00 dlr a share, on a +seven pct increase in sales to a record 337 mln dlrs. + Brown-Forman said nine month profits declined a bit to 66.0 +mln dlrs, or 3.07 dlrs a share, from 66.2 mln dlrs, or 3.08 +dlrs a share, a year earlier due to a second quarter charge of +37 cts a share for restructuring its beverage operations. + The company said lower corporate tax rates and the +restructuring "are expected to substantially improve +Brown-Forman's earnings and cash flow in fiscal 1988." + Reuter + + + +26-FEB-1987 15:35:16.67 +earn +usa + + + + + +F +f0814reute +h f BC-ESQUIRE-RADIO-AND-ELE 02-26 0072 + +ESQUIRE RADIO AND ELECTRONICS INC <EE> 4TH QTR + NEW YORK, Feb 26 - + Shr profit 15 cts vs profit four cts + Annual div 72 cts vs 72 cts prior yr + Net profit 72,000 vs profit 16,000 + Revs 7,075,000 vs 2,330,000 + 12 mths + Shr profit 42 cts vs loss 11 cts + Net profit 203,000 vs loss 55,000 + Revs 16.1 mln vs 3,971,000 + NOTE: annual dividend payable April 10, 1987, to +stockholders of record on March 27, 1987. + Reuter + + + +26-FEB-1987 15:35:39.38 + +usa + + + + + +F +f0815reute +h f BC-SHEARSON-LEHMAN-NAMES 02-26 0061 + +SHEARSON LEHMAN NAMES NEW MANAGING DIRECTOR + NEW YORK, Feb 26 - Shearson Lehman Brothers, a unit of +American Express Co <AXP>, said Robert Stearns has joined the +company as managing director of its merger and acquisition +department. + Shearson said Stearns formerly was part of Merrill Lynch +Pierce, Fenner and Smith Inc's <MER> merger and acquisitions +department. + Reuter + + + +26-FEB-1987 15:36:44.78 + +usabrazilvenezuela + + + + + +V RM +f0817reute +b f BC-/BANKERS-REPORT-BREAK 02-26 0092 + +BANKERS REPORT BREAKTHROUGH ON VENEZUELAN DEBT + NEW YORK, Feb 26 - Venezuela and its bank advisory +committee have agreed in principle on revisions to the terms of +a 21 billion dlr debt-rescheduling package signed last +February, bankers said. + They declined to disclose details because two or three +representatives on the panel have still to obtain the approval +of their senior management for the new terms. + The committee was meeting in New York this afternoon and +could put its final stamp of approval of the deal later today, +the bankers said. + "A number of details have still to be finalized, but the +broad details of the new amortization schedules and interest +rates are in place," one senior banker said. + The interest rate on the rescheduling was originally set at +1-1/8 pct over Eurodollar rates, but Venezuela requested easier +terms because of a 40 pct drop in oil income last year. + It also asked for a reduction in the repayments it was due +to make in 1987, 1988 and 1989 - after an earlier request that +it make no amortizations at all in those years was rebuffed - +and sought a commitment from the banks to finance new +investment in Venezuela. + The breakthrough in the Venezuelan talks, which have been +going on intermittently for several months, follows the +announcement earlier today of a 10.6 billion dlr debt +rescheduling pact between Chile and its bank advisory panel. + And last night Citibank said Mexico's financing package, +including a 7.7 billion dlr loan, will be signed on March 20. + While the sudden progress is to some extent coincidental, +bankers acknowledge a desire to chalk up some quick successes +after the shock of Brazil's unilateral interest suspension last +Friday. By striking swift deals, banks hope to reduce the +incentive for other debtors to emulate Brazil. + Reuter + + + +26-FEB-1987 15:36:53.42 +earn +usa + + + + + +F +f0818reute +d f BC-UNITED-PRESIDENTIAL-C 02-26 0073 + +UNITED PRESIDENTIAL CORP <UPCO> 4TH QTR NET + KOKOMO, Ind., Feb 26 - + Shr 39 cts vs 50 cts + Net 1,545,160 vs 2,188,933 + Revs 25.2 mln vs 19.5 mln + Year + Shr 1.53 dlrs vs 1.21 dlrs + Net 6,635,318 vs 5,050,044 + Revs 92.2 mln vs 77.4 mln + NOTE: Results include adjustment of 848,600 dlrs or 20 cts +shr for 1986 year and both 1985 periods from improvement in +results of its universal life business than first estimated. + Reuter + + + +26-FEB-1987 15:38:26.23 + +usa +reagan + + + + +V RM +f0823reute +r f AM-REAGAN-IMPACT-(NEWS-A NALYSIS) 02-26 0092 + +TOWER REPORT DIMINISHES REAGAN'S HOPES OF REBOUND + By Michael Gelb, Reuters + WASHINGTON, Feb 26 - The Tower Commission report, which +says President Reagan was ignorant about much of the Iran arms +deal, just about ends his prospects of regaining political +dominance in Washington, political analysts said. + "This is certification of incompetence," private political +analyst Stephen Hess told Reuters in commenting on the Tower +report made public today. + "It's as if he went before a professional licensing board +and was denied credentials." + In one of the most direct criticisms, board chairman John +Tower, a longtime Reagan supporter and former Republican +senator from Texas, told a press conference, "The president +clearly did not understand the nature of this operation." + The report, which lent credence to widespread opinion in +Washington that Reagan is not in full command of the +government, was particularly damaging because it was prepared +by a board of the Republican president's own choosing. + The three-member panel made up of Tower, former National +Security Adviser Brent Scowcroft and former Secretary of State +Edmund Muskie, does not carry the partisan taint of criticism +from a Congress controlled by the Democratic party. + "We're falling by our own hand," said one Republican +political strategist. "What can we say except 'we're sorry, we +won't do it again'?" + The strategist, who works for one of his party's top 1988 +presidential contenders and asked not to be identified, said +the report was like "an anvil falling on us." + Hess, with the Brookings Institution public policy study +group, said the report is the final blow to Reagan's hopes of +regaining the upper hand he once had in dealings with Congress, +the press and the Washington bureaucracy. + The report may also undermine the standing of Defense +Secretary Caspar Weinberger and Secretary of State George +Shultz, who the report suggests were more interested in keeping +their own skirts clean than supporting the president. + "They protected the record as to their own positions on this +issue. They were not energetic in attempting to protect the +president from the consequences," it said. + White House chief of staff Donald Regan and former Central +Intelligence Agency Director William Casey also received strong +criticism, but the blows were expected in their cases. + Regan, expected to resign or be fired shortly, was savaged +for allegedly failing both to help Reagan conduct the Iran +initiative and to avoid "chaos" in the disclosure process. + Casey, who underwent surgery for removal of a cancerous +brain tumor in December, had already resigned for health +reasons last month. + "This is a story about people who came up somewhat short of +being heroes," Tower told reporters. + While Reagan retains considerable constitutional powers, +including command of the armed forces and the right to veto +legislation, analysts say it will be difficult for him to +retake control of the country's policy agenda -- particularly +with Congress controlled by the Democrats. + The crucial remaining question, they said, is whether the +man in the street will forsake Reagan over the affair. + Although his job approval rating has fallen as much as +twenty percentage points in some opinion polls since the arms +deal with Iran became public last November, his personal +popularity is still relatively high. + A Los Angeles Times poll released earlier this week showed +that just 37 pct of those surveyed thought Reagan was in +control of the government, but 55 pct still thought he was +doing a good job as president. + American Enterprise Institute analyst William Schneider, a +Democrat, says Reagan's loss of support among Washington power +brokers could be offset by continued backing of the public. + "In the past, he has been able to go around the power elite +by appealing directly to the public," Schneider said. + Reagan will again plead his case that way in a televised +address next week. + But one top Republican strategist warned against expecting +a dramatic turnaround. + "The White House has to avoid building expectations that +cannot be met," said the strategist, who requested anonymity. +"They have to recognize there is no quick fix." + Analysts also point out that Reagan's personal popularity +has not always translated into public backing for his policies. + They note he was dramatically rebuffed in last November's +elections when voters rejected his appeals and restored control +of the Senate to the Democrats. + Reuter + + + +26-FEB-1987 15:39:41.92 +housing +usa + + + + + +F +f0827reute +r f BC-JANUARY-HOUSING-SALES 02-26 0103 + +JANUARY HOUSING SALES DROP, REALTY GROUP SAYS + WASHINGTON, Feb 26 - Sales of previously owned homes +dropped 14.5 pct in January to a seasonally adjusted annual +rate of 3.47 mln units, the National Association of Realtors +(NAR) said. + But the December rate of 4.06 mln units had been the +highest since the record 4.15 mln unit sales rate set in +November 1978, the group said. + "The drop in January is not surprising considering that a +significant portion of December's near-record pace was made up +of sellers seeking to get favorable capital gains treatment +under the old tax laws," said the NAR's John Tuccillo. + Reuter + + + +26-FEB-1987 15:41:56.54 +money-supply + + + + + + +A +f0835reute +f f BC-******ASSETS-OF-MONEY 02-26 0012 + +******ASSETS OF MONEY MARKET MUTUAL FUNDS ROSE 720.4 MLN DLRS IN LATEST WEEK +Blah blah blah. + + + + + +26-FEB-1987 15:43:14.36 + +usa + + + + + +A +f0840reute +b f BC-******U.S.-TAX-WRITER 02-26 0013 + +******U.S. TAX WRITERS SEEK ESTATE TAX CURBS, RAISING 6.7 BILLION DLRS THRU 1991 +Blah blah blah. + + + + + +26-FEB-1987 15:43:59.53 + +usa + + + + + +F +f0842reute +d f BC-SENATORS-INTRODUCE-EX 02-26 0110 + +SENATORS INTRODUCE EXPORT LICENSING REFORM BILL + WASHINGTON, Feb 26 - Sens. Alan Cranston (D-Cal.) and +Daniel Evans (R-Wash.) said they introduced export licensing +reform legislation that could save U.S. companies hundreds of +thousands of dollars annually. + "Our emphasis is two-fold: Decontrol and de-license items +where such actions will not endanger our national security, and +eliminate the Department of Defense's de facto veto authority +over the licensing process," Cranston said. + "Our reforms should reduce licensing requirements by 65 to +70 pct," he told reporters. "I am convinced that a more +rational...licensing process will boost exports." + U.S. export controls are intended to deny Eastern bloc +countries access to technology that could further their +military capabilities. + "By refocusing our control resources on higher levels of +technology, technology that is truly critical, we will do a +better job of preventing diversion of critical technology to +our adversaries while promoting more exports," Cranston said. + "We cannot expect to continue to play a leading role in new +technology development in the future if we unduly restrict the +activities of U.S. firms in the world market-place," Evans told +reporters. + Reuter + + + +26-FEB-1987 15:44:36.04 + +usa + + + + + +F +f0845reute +r f BC-EXCELAN-INC-SETS-INIT 02-26 0061 + +EXCELAN INC SETS INITIAL STOCK OFFER + SAN JOSE, Calif., Feb 26 - Excelan Inc said it is making an +initial public offering of 2,129,300 shares of common stock at +12 dlrs per share. + Excelan said 1.6 mln of the shares are being sold by the +company and 529,300 shares are being sold by stockholders. + Excelan designs and manufactures computer-related products. + Reuter + + + +26-FEB-1987 15:45:19.65 + +usa + + + + + +F +f0847reute +d f BC-CCX-NETWORK-<CCXN>-SE 02-26 0074 + +CCX NETWORK <CCXN> SECONDARY OFFERING UNDERWAY + CONWAY, Ark., Feb 26 - CCX Network Inc said it was offering +220,838 shares of stock at 15.75 dlrs a share though +underwriters Stephens Inc and Cazenove Inc. + The company said it was selling the stock on behalf of some +shareholders, including those who recently received shares +in the company in exchange for their businesses. + The company said it was receiving no proceeds from the +offering. + Reuter + + + +26-FEB-1987 15:45:26.55 + +usa + + + + + +F +f0848reute +r f BC-FIRST-UNION-<FUNC>-FI 02-26 0055 + +FIRST UNION <FUNC> FILES 100 MLN DLR NOTES ISSUE + NEW YORK, Feb 26 - First Union Corp said it has filed with +the Securities and Exchange Commission for a proposed offering +of 100 mln dlrs of fixed rate subordinated notes due 1997. + The notes will be sold nationwide through underwriters +managed by Shearson Lehman Brothers Inc. + Reuter + + + +26-FEB-1987 15:45:35.37 +earn +usa + + + + + +F +f0849reute +r f BC-OWENS-AND-MINOR-INC-< 02-26 0025 + +OWENS AND MINOR INC <OBOD> RAISES QTLY DIVIDEND + RICHMOND, Va. Feb 26 - + Qtly div eights cts vs 7.5 cts prior + Pay March 31 + Record March 13 + Reuter + + + +26-FEB-1987 15:45:39.20 +earn +usa + + + + + +F +f0850reute +r f BC-COMPUTER-LANGUAGE-RES 02-26 0070 + +COMPUTER LANGUAGE RESEARCH IN <CLRI> 4TH QTR + CARROLLTON, Texas, Feb 26 - + Shr loss 22 cts vs loss 18 cts + Net loss 3,035,000 vs loss 2,516,000 + Revs 20.9 mln vs 19.6 mln + Qtly div three cts vs three cts prior + Year + Shr profit two cts vs profit 34 cts + Net profit 215,000 vs profit 4,647,000 + Revs 93.4 mln vs 98.7 mln + NOTE: Dividend payable April one to shareholders of record +March 17. + Reuter + + + +26-FEB-1987 15:45:47.29 +earn +usa + + + + + +E F +f0851reute +d f BC-<CINRAM-LTD>-4TH-QTR 02-26 0051 + +<CINRAM LTD> 4TH QTR NET + Scarborough, Ontario, Feb 26 - + Shr 45 cts vs 58 cts + Net 1.1 mln vs 829,000 + Sales 7.9 mln vs 9.4 mln + Avg shrs 2,332,397 vs 1,428,000 + Year + Shr 1.22 dlrs vs 1.06 dlrs + Net 2.9 mln vs 1.5 mln + Sales 25.7 mln vs 22.2 mln + Avg shrs 2,332,397 vs 1,428,000 + Reuter + + + +26-FEB-1987 15:46:36.16 + +usa + + + + + +F +f0855reute +h f BC-DU-PONT-CO-<DD>-LAUNC 02-26 0105 + +DU PONT CO <DD> LAUNCHES IMPROVED ARAMID FIBERS + WILMINGTON, Del., Feb 26 - The Du Pont Co said it has +devloped a new generation of high-strength aramid fibers which +is stiffer and less absorbant than previous generations. + Du Pont said the new product, Kevlar 149, is up to 40 pct +stiffer than first generation aramids, and absorbs less than +half the moister of other similar aramid fibers. + Kevlar was invented by Du Pont in the late 1960s and is +five times stronger than steel and 10 times stronger than +aluminum on an equal wieght basis, and is used to replace +metals in a variety of products, according to the company. + Reuter + + + +26-FEB-1987 15:47:16.17 +earn +canada + + + + + +E F +f0859reute +r f BC-STANDARD-TRUSTCO-SEES 02-26 0099 + +STANDARD TRUSTCO SEES BETTER YEAR + Toronto, Feb 26 - Standard Trustco said it expects earnings +in 1987 to increase at least 15 to 20 pct from the 9,140,000 +dlrs, or 2.52 dlrs per share, recorded in 1986. + "Stable interest rates and a growing economy are expected to +provide favorable conditions for further growth in 1987," +president Brian O'Malley told shareholders at the annual +meeting. + Standard Trustco previously reported assets of 1.28 billion +dlrs in 1986, up from 1.10 billion dlrs in 1985. Return on +common shareholders' equity was 18.6 pct last year, up from 15 +pct in 1985. + Reuter + + + +26-FEB-1987 15:48:26.92 +earn +usa + + + + + +F +f0865reute +u f BC-HANDY-AND-HARMAN-<HNH 02-26 0068 + +HANDY AND HARMAN <HNH> 4TH QTR LOSS + NEW YORK, Feb 26 - + Shr loss 51 cts vs loss three cts + Net loss 7,041,000 vs loss 467,000 + Rev 138.9 mln vs 131.4 mln + 12 months + Shr loss 64 cts vs profit 46 cts + Net loss 8,843,000 vs profit 6,306,0000 + Rev 558.9 mln vs 556.7 mln + NOTE: Net loss for 4th qtr 1986 includes charge for +restructuring of 2.6 mln dlrs after tax, or 19 cts a share. + 1986 net loss includes after tax special charge of 2.7 mln +dlrs, or 20 cts a share. + + Reuter + + + +26-FEB-1987 15:49:27.16 +coffee +uk + +ico-coffee + + + +C T +f0871reute +b f BC-ICO-PRODUCERS-TO-PRES 02-26 0109 + +ICO PRODUCERS TO PRESENT NEW COFFEE PROPOSAL + LONDON, Feb 26 - International Coffee Organization, ICO, +producing countries will present a proposal for reintroducing +export quotas for 12 months from April 1 with a firm +undertaking to try to negotiate up to September 30 any future +quota distribution on a new basis, ICO delegates said. + Distribution from April 1 would be on an unchanged basis as +in an earlier producer proposal, which includes shortfall +redistributions totalling 1.22 mln bags, they said. + Resumption of an ICO contact group meeting with consumers, +scheduled for this evening, has been postponed until tomorrow, +delegates said. + Reuter + + + +26-FEB-1987 15:49:44.93 + +usairan + + + + + +V RM +f0873reute +u f AM-REAGAN-SHULTZ-1STLD 02-26 0108 + +SHULTZ SAYS NO RESIGNATION OVER IRAN REPORT + ANCHORAGE, Alaska, Feb 26 - Secretary of State George +Shultz acknowledged failings in the Iran arms affair but +declared he would not resign. + His role in the scandal that has scarred the Reagan +administration attracted harsh criticism from the Tower +commission in its report on the affair published today. + Shultz, travelling to China for a week-long visit, refused +to comment directly on the report, published after he had left +Washington. But he repeated -- as he has done since the crisis +broke last November -- that he was not going to resign. + "You can wipe that off your slate," he said. + Reuter + + + +26-FEB-1987 15:49:56.01 +acqship +usa + + + + + +F +f0874reute +r f BC-MCLEAN'S-<MII>-U.S.-L 02-26 0094 + +MCLEAN'S <MII> U.S. LINES SETS ASSET TRANSFER + CRANFORD, N.J., Feb 26 - McLean Industries Inc's United +States Lines Inc subsidiary said it has agreed in principle to +transfer its South American service by arranging for the +transfer of certain charters and assets to <Crowley Mariotime +Corp>'s American Transport Lines Inc subsidiary. + U.S. Lines said negotiations on the contract are expected +to be completed within the next week. Terms and conditions of +the contract would be subject to approval of various regulatory +bodies, including the U.S. Bankruptcy Court. + Reuter + + + +26-FEB-1987 15:51:17.84 +acq +usa + + + + + +F +f0881reute +u f BC-CHEMLAWN-<CHEM>-RISES 02-26 0106 + +CHEMLAWN <CHEM> RISES ON HOPES FOR HIGHER BIDS + By Cal Mankowski, Reuters + NEW YORK, Feb 26 - ChemLawn Corp <CHEM> could attract a +higher bid than the 27 dlrs per share offered by Waste +Management Inc <WNX>, Wall Street arbitrageurs said. + Shares of ChemLawn shot up 11-5/8 to 29-3/8 in +over-the-counter- trading with 3.8 mln of the company's 10.1 +mln shares changing hands by late afternoon. + "This company could go for 10 times cash flow or 30 dlrs, +maybe 32 dollars depending on whether there is a competing +bidder," an arbitrageur said. Waste Management's tender offer, +announced before the opening today, expires March 25. + "This is totally by surprise," said Debra Strohmaier, a +ChemLawn spokeswoman. The company's board held a regularly +scheduled meeting today and was discussing the Waste Management +announcement. She said a statement was expected but it was not +certain when it would be ready. + She was unable to say if there had been any prior contact +between Waste Management and ChemLawn officials. + "I think they will resist it," said Elliott Schlang, +analyst at Prescott, Ball and Turben Inc. "Any company that +doesn't like a surprise attack would." + Arbitrageurs pointed out it is difficult to resist tender +offers for any and all shares for cash. Schlang said ChemLawn +could try to find a white knight if does not want to be +acquired by Waste Management. + Analyst Rosemarie Morbelli of Ingalls and Snyder said +ServiceMaster Companies L.P. <SVM> or Rollins Inc <ROL> were +examples of companies that could be interested. + ChemLawn, with about two mln customers, is the largest U.S. +company involved in application of fertilizers, pesticides and +herbicides on lawns. Waste Management is involved in removal of +wastes. + Schlang said ChemLawn's customer base could be valuable to +another company that wants to capitalize on a strong +residential and commercial distribution system. + Both Schlang and Morbelli noted that high growth rates had +catapulted ChemLawn's share price into the mid-30's in 1983 but +the stock languished as the rate of growth slowed. + Schlang said the company's profits are concentrated in the +fourth quarter. In 1986 ChemLawn earned 1.19 dlrs per share for +the full year, and 2.58 dlrs in the fourth quarter. + Morbelli noted ChemLawn competes with thousands of +individual entrepreuers who offer lawn and garden care sevice. + Reuter + + + +26-FEB-1987 15:51:28.42 +sugar +usa + + + + + +C T +f0882reute +b f BC-sugar-imports 02-26 0120 + +U.S. SUGAR IMPORTS DOWN IN WEEK - USDA + WASHINGTON, Feb 26 - Sugar imports subject to the U.S. +sugar import quota during the week ended January 9, the initial +week of the 1987 sugar quota year, totaled 5,988 short tons +versus 46,254 tons the previous week, the Agriculture +Department said. + The sugar import quota for the 1987 quota year +(January-December) has been set at 1,001,430 short tons +compared with 1,850,000 tons in the 1986 quota year, which was +extended three months to December 31. + The department said the Customs Service has reported that +weekly and cumulative imports are reported on an actual weight +basis and when final polarizations are received, cumulative +import data are adjusted accordingly. + Reuter + + + +26-FEB-1987 15:51:51.24 +trade +brazil + + + + + +C G L M T +f0884reute +d f AM-CRUZADO 02-26 0114 + +BRAZIL ANTI-INFLATION PLAN LIMPS TO ANNIVERSARY + RIO DE JANEIRO, Feb 26 - Brazil's "Cruzado" anti- inflation +plan, initially hailed at home and abroad as the saviour of the +economy, is limping towards its first anniversary amid soaring +prices, widespread shortages and a foreign payments crisis. + Announced last February 28 the plan froze prices, fixed the +value of the new Cruzado currency and ended widespread +indexation of the economy in a bid to halt the country's 250 +pct inflation rate. + But within a year the plan has all but collapsed. + "The situation now is worse than it was. Although there was +inflation, at least the economy worked," a leading bank +economist said. + The crumbling of the plan has been accompanied by a +dramatic reversal in the foreign trade account. In 1984 and +1985 Brazil's annual trade surpluses had been sufficient to +cover the 12 billion dlrs needed to service its 109 billion dlr +foreign debt. + For the first nine months of 1986 all seemed to be on +target for a repeat, with monthly surpluses averaging one +billion dlrs. But as exports were diverted and imports +increased to avoid further domestic shortages the trade surplus +plunged to 211 mln dlrs in October and since then has averaged +under 150 mln. + Reuter + + + +26-FEB-1987 15:52:15.10 +reserves +new-zealand + + + + + +RM +f0886reute +u f BC-N.Z.-OFFICIAL-FOREIGN 02-26 0049 + +N.Z. OFFICIAL FOREIGN RESERVES FALL IN JANUARY + WELLINGTON, Feb 27 - New Zealand's official foreign +reserves fell to 7.15 billion N.Z. Dlrs in January from 7.20 +billion dlrs in December and compared with 3.03 billion a year +ago period, the Reserve Bank said in its weekly statistical +bulletin. + Reuter + + + +26-FEB-1987 15:52:25.60 +ship +usapanama + + + + + +G T M +f0888reute +d f BC-panama-canal-ships 02-26 0071 + +AGENCY REPORTS 39 SHIPS WAITING AT PANAMA CANAL + WASHINGTON, Feb 26 - The Panama Canal Commission, a U.S. +government agency, said in its daily operations report that +there was a backlog of 39 ships waiting to enter the canal +early today. Over the next two days it expects -- + 2/26 2/27 + Due: 27 35 + Scheduled to Transit: 35 41 + End-Day Backlog: 31 25 + Average waiting time tomorrow -- + Super Tankers Regular Vessels + North End: 13 hrs 15 hrs + South End: 4 hrs 26 hrs + Reuter + + + +26-FEB-1987 15:52:33.04 +earn +usa + + + + + +F +f0889reute +d f BC-AMERICA-FIRST-MORTGAG 02-26 0046 + +AMERICA FIRST MORTGAGE SETS SPECIAL PAYOUT + OMAHA, Neb., Feb 26 - <America First Federally Guaranteed +Mortgage Fund Two> said it is making a special distribution of +71.6 cts per exchangeable unit, which includes 67.62 cts from +return on capital and 3.98 cts from income gains. + Reuter + + + +26-FEB-1987 15:52:57.49 + +usa + + + + + +C G +f0894reute +d f BC-REPUBLICANS-EYE-BIGGE 02-26 0112 + +REPUBLICANS EYE BIGGER U.S. CONSERVATION RESERVE + WASHINGTON, Feb 26 - A group of Republican governors and +members of Congress said they intended to explore expanding the +conservation reserve program by up to 20 mln acres. + Under current law, between 40 and 45 mln acres of erodible +land must be enrolled in the program by the end of fiscal 1990. + The Republican Task Force on Farm and Rural America, headed +by Senate Majority Leader Robert Dole (Kan.), said they would +consider drafting legislation to increase the reserve by +between 15 and 20 mln acres. + Sen. Charles Grassley (R-Iowa) told Reuters he would offer +a bill to expand the reserve to 67 mln acres. + Reuter + + + +26-FEB-1987 15:53:05.48 + +usa + + + + + +F +f0895reute +h f BC-ARVIN-INDS-<ARV>-PROM 02-26 0037 + +ARVIN INDS <ARV> PROMOTES EVANS TO PRESIDENT + COLUMBUS, IND., Feb 26 - Arvin Industries Inc said L.K. +Evans has been elected president, succeeding James Baker who +remains chairman. Evans had been executive vice president. + Reuter + + + +26-FEB-1987 15:53:54.56 +earn +usa + + + + + +F +f0899reute +s f BC-EMHART-CORP-<EMH>-QTL 02-26 0024 + +EMHART CORP <EMH> QTLY DIVIDEND + FARMINGTON, Conn., FEb 26 - + Qtly div 35 cts vs 35 cts prior + Payable March 31 + Record March nine + + Reuter + + + +26-FEB-1987 15:54:55.20 + +usa + + + + + +V RM +f0901reute +u f BC-/U.S.-DATA-POINT-TO-C 02-26 0102 + +U.S. DATA POINT TO CAPITAL SPENDING SLOWDOWN + By Kathleen Hays, Reuters + NEW YORK, Feb 26 - A surprise 7.5 pct drop in U.S. January +durable goods orders points to a slowdown in capital spending +that could presage lackluster real growth in the U.S. economy +in the first quarter of 1987, economists said. + With total orders, excluding the volatile defense sector, +falling a record 9.9 pct, economists agreed that the report +painted a bleak picture for the U.S. economy. + But they stressed that the 1987 tax reform laws may be a +primary factor behind the drop in orders for business capital +investment. + "It's a rather gloomy outlook for the economy, said David +Wyss of Data Resources Inc. "I'm particularly impressed by the +19.7 pct drop in non-defense capital goods orders because it +may be a sign that businesses are reacting more adversely to +tax reform than we thought." + The Commerce Department pointed out that a record 14.8 pct +decline in new orders for machinery was led by declines in +office and computing equipment orders. + Economists said the drop in computer orders may have been a +response to the lengthening of depreciation schedules and the +end of the investment tax credit under the new tax laws. + "It's more expensive to invest than it used to be, so +people just aren't doing it as much," Wyss said. + Increases in durable goods orders at year's end reinforced +the view that businesses anticipated the changing tax laws, +economists said. + November durable goods orders rose 5.1 pct and December's +increased 1.5 pct, revised upwards from a previously reported +0.9 pct. + But most acknowledged that the huge January drop was caused +by more than tax reform. + "The wash-out that took place in January was far greater +than the actual gains that took place in November and +December," said Bill Sullivan of Dean Witter Reynolds Inc. "The +economy has a weakening bent to it early in the year." + "The report definitely points to very sluggish capital +spending over the next couple of quarters," said Donald Maude +of Midland Montagu Capital Markets Inc. + Maude pointed to a continuing decline in order backlogs as +evidence that the outlook for new orders is not improving. In +November, order backlogs rose 0.6 pct, but in December they +fell 0.6 pct and in January 0.7 pct, he said. + "It suggests orders in the pipeline are depleting, which +may quickly translate to a drop in production," Midland +Montagu's Maude said. + Wyss cautioned that too much should not be made of +January's report, given that other reports have reflected +strength. + But he acknowledged that the decline occurred despite a 51 +pct rise in defense orders, compared with a 57.7 pct decline in +December. + He also noted that there was a 6.9 pct drop in January +shipments, compared with a 5.4 pct rise in December. + "Given these numbers, there's no reason for the Fed to +tighten," Data Resources' Wyss said. + "But there's no reason to ease unless we see more numbers +like this. The Fed will wait and see," he added. + Sullivan predicted the Fed will ease by Easter. "People +aren't talking recession or Fed easing now, but the Fed will +have to ease to ensure global growth." + Reuter + + + +26-FEB-1987 15:56:00.50 + +usa + + + + + +C +f0903reute +d f BC-SENATORS-INTRODUCE-EX 02-26 0110 + +SENATORS INTRODUCE EXPORT LICENSING REFORM BILL + WASHINGTON, Feb 26 - Sens. Alan Cranston (D-Cal.) and +Daniel Evans (R-Wash.) said they introduced export licensing +reform legislation that could save U.S. companies hundreds of +thousands of dollars annually. + "Our emphasis is two-fold: Decontrol and de-license items +where such actions will not endanger our national security, and +eliminate the Department of Defense's de facto veto authority +over the licensing process," Cranston said. + "Our reforms should reduce licensing requirements by 65 to +70 pct," he told reporters. "I am convinced that a more +rational...licensing process will boost exports." + U.S. export controls are intended to deny Eastern bloc +countries access to technology that could further their +military capabilities. + "By refocusing our control resources on higher levels of +technology, technology that is truly critical, we will do a +better job of preventing diversion of critical technology to +our adversaries while promoting more exports," Cranston said. + "We cannot expect to continue to play a leading role in new +technology development in the future if we unduly restrict the +activities of U.S. firms in the world market-place," Evans told +reporters. + Reuter + + + +26-FEB-1987 15:57:48.22 +earn +usa + + + + + +F +f0906reute +r f BC-AM-INTERNATIONAL-<AM> 02-26 0092 + +AM INTERNATIONAL <AM> CITES STRONG PROSPECTS + CHICAGO, Feb 26 - AM International Inc, reporting an +operating loss for the January 31 second quarter, said +prospects for the balance of the fiscal year remain good. + It said orders at its Harris Graphics subsidiary, acquired +in June 1986, "continue to run at a strong pace." For the six +months, orders rose 35 pct over the corresponding prior-year +period, or on an annualized basis are running at about 630 mln +dlrs. + The backlog at Harris is up 30 pct from the beginning of +the fiscal year, AM said. + AM International said its old division are expected to +benefit from recent new product introductions and the decline +in the value of the dollar. + "Research, development and engineering expenditures in +fiscal 1987 will be in the 45-50 mln dlr range, and the company +said it has allocated another 30-40 mln dlrs for capital +expenditures. + Earlier AM reported a fourth quarter operating loss of two +cts a share compared to profits of seven cts a share a year +ago. Revenues rose to 291.8 mln dlrs from 151.1 mln dlrs. + Reuter + + + +26-FEB-1987 15:58:07.34 +graincorn +usahonduras + + + + + +C G +f0907reute +u f BC-CCC-CREDITS-FOR-HONDU 02-26 0097 + +CCC CREDITS FOR HONDURAS SWITCHED TO WHITE CORN + WASHINGTON, Feb 26 - The Commodity Credit Corporation (CCC) +announced 1.5 mln dlrs in credit guarantees previously +earmarked to cover sales of dry edible beans to Honduras have +been switched to cover sales of white corn, the U.S. +Agriculture Department said. + The department said the action reduces coverage for sales +of dry edible beans to 500,000 dlrs and creates the new line of +1.5 mln dlrs for sales of white corn. + All sales under the credit guarantee line must be +registered and shipped by September 30, 1987, it said. + Reuter + + + +26-FEB-1987 15:58:19.46 +money-supply +usa + + + + + +A RM +f0908reute +u f BC-ASSETS-OF-U.S.-MONEY 02-26 0072 + +ASSETS OF U.S. MONEY FUNDS ROSE IN WEEK + WASHINGTON, Feb 26 - Assets of money market mutual funds +increased 720.4 mln dlrs in the week ended yesterday to 236.90 +billion dlrs, the Investment Company Institute said. + Assets of 91 institutional funds rose 356 mln dlrs to 66.19 +billion dlrs, 198 general purpose funds rose 212.5 mln dlrs to +62.94 billion dlrs and 92 broker-dealer funds rose 151.9 mln +dlrs to 107.77 billion dlrs. + Reuter + + + +26-FEB-1987 15:58:47.73 +ship +usa + + + + + +G C +f0910reute +u f BC-gulf-grain-barge-frgt 02-26 0117 + +GULF BARGE FREIGHT RATES UP FURTHER ON CALL + ST LOUIS, Feb 26 - Gulf barge freight rates firmed again on +the outlook for steady vessel loadings at the Gulf, increasing +the demand for barges to supply those ships, dealers said. + No barges traded today on the St Louis Merchants' Exchange +call session, versus 29 yesterday. + Quotes included - + - Delivery this week on the Illinois River (Joliet) 135 pct of +tariff bid/140 offered, with next week same river (ex Chicago) +quoted the same - both up 2-1/2 percentage points. + - Next week Mississippi River (St Louis) 120 pct bid/127-1/2 +offered - up five points. + - Next week Ohio River (Owensboro/south) 125 pct bid/132-1/2 +offered - up 7-1/2 points. + - On station Illinois River (south Chicago) 135 pct bid/140 +offered - no comparison. + - March Illinois (ex Chicago) 132-1/2 pct bid/140 offered - up +2-1/2 points. + - March Ohio River bid at yesterday's traded level of 125 pct, +offered at 132-1/2. + - March lower Mississippi River (Memphis/Cairo) 112-1/2 pct +bid/120 offered - no comparison. + - May Illinois River (ex Chicago) 100 pct bid/107-1/2 offered +- no comparison. + - Sept/Nov Lower Mississippi River (Memphis/Cairo) 137-1/2 pct +bid/145 offered, with Sept/Dec same section 125 pct bid/135 +offered - no comparison. + Reuter + + + +26-FEB-1987 16:03:15.46 + +argentina + + + + + +C G L M T +f0923reute +u f BC-ARGENTINA-COULD-SUSPE 02-26 0110 + +ARGENTINA COULD SUSPEND DEBT PAYMENTS - DEPUTY + BUENOS AIRES, Feb 26 - Argentina could suspend payments on +its foreign debt if creditor banks reject a 2.15 billion dlr +loan request to meet 1987 growth targets, ruling Radical Party +Deputy Raul Baglini told a local radio station. + "Argentina does not discard the use of (a moratorium) if the +negotiations do not produce a result that guarantees the growth +of the country," he added. + Baglini, an observer at Argentina's negotiations in New +York with the steering committee for its 320 creditors banks, +told the Radio del Plata in a telephone interview that the +banks were divided on the loan request. + Baglini said that as a result, today's scheduled second day +of talks had been postponed. + He said Argentina was prepared to follow the example of +Brazil, which last week declared a moratorium on interest +payments of a large portion of its 108 billion dlr foreign +debt. + Argentina's prime objective in renegotiating the debt was +to maintain growth, which has been targeted at four pct in +1987, Baglini said. + "Debtor nations should not have to take from their own +pockets, that is their commercial balance, to meet interest +payments," he added. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-001.sgm b/src/test/data/reuters-21578/reut2-001.sgm new file mode 100644 index 00000000000..a0de9a9463a --- /dev/null +++ b/src/test/data/reuters-21578/reut2-001.sgm @@ -0,0 +1,2010 @@ + + + 3-MAR-1987 09:18:21.26 + +usaussr + + + + + +G T +f0288reute +d f BC-SANDOZ-PLANS-WEEDKILL 03-03 0095 + +SANDOZ PLANS WEEDKILLER JOINT VENTURE IN USSR + BASLE, March 3 - Sandoz AG said it planned a joint venture +to produce herbicides in the Soviet Union. + The company said it had signed a letter of intent with the +Soviet Ministry of Fertiliser Production to form the first +foreign joint venture the ministry had undertaken since the +Soviet Union allowed Western firms to enter into joint ventures +two months ago. + The ministry and Sandoz will each have a 50 pct stake, but +a company spokeswoman was unable to give details of the size of +investment or planned output. + Reuter + + + + 3-MAR-1987 09:19:31.96 + +usataiwan + + + + + +G +f0295reute +d f BC-TAIWAN-REJECTS-TEXTIL 03-03 0137 + +TAIWAN REJECTS TEXTILE MAKERS EXCHANGE RATE PLEA + TAIPEI, March 3 - Central bank governor Chang Chi-cheng +rejected a request by textile makers to halt the rise of the +Taiwan dollar against the U.S. Dollar to stop them losing +orders to South Korea, Hong Kong and Singapore, a spokesman for +the Taiwan Textile Federation said. + He quoted Chang as telling representatives of 19 textile +associations last Saturday the government could not fix the +Taiwan dollar exchange rate at 35 to one U.S. Dollar due to +U.S. Pressure for an appreciation of the local currency. + The Federation asked the government on February 19 to hold +the exchange rate at that level. + The federation said in its request that many local textile +exporters were operating without profit and would go out of +business if the rate continued to fall. + Reuter + + + + 3-MAR-1987 09:20:23.32 +earn +usa + + + + + +F +f0296reute +d f BC-NATIONAL-FSI-INC-<NFS 03-03 0080 + +NATIONAL FSI INC <NFSI> 4TH QTR LOSS + DALLAS, March 3 - + Shr loss six cts vs profit 19 cts + Net loss 166,000 vs profit 580,000 + Revs 3,772,000 vs 5,545,000 + Year + Shr loss 13 cts vs profit 52 cts + Net loss 391,000 vs profit 1,425,000 + Revs 15.4 mln vs 16.6 mln + NOTE: 1985 year figures pro forma for purchase accounting +adjustments resulting from March 1985 reeacquisition of company +by its original shareholders before August 1985 initial public +offering. + Reuter + + + + 3-MAR-1987 09:21:39.11 + +usa + + + + + +Y +f0301reute +r f BC-OCCIDENTAL-<OXY>-OFFI 03-03 0049 + +OCCIDENTAL <OXY> OFFICIAL RESIGNS + LOMBARD, Ill., March 3 - MidCon Corp, a subsidiary of +Occidental Petroleum Corp <OXY>, said William C. Terpstra has +resigned as president and chief operating officer and his +reponsibilities will be assumed by MidCon chairman O.C. Davis. + No reason was given. + Reuter + + + + 3-MAR-1987 09:25:48.88 + +italy + + + + + +RM +f0308reute +u f BC-ITALY'S-BNL-TO-ISSUE 03-03 0101 + +ITALY'S BNL TO ISSUE 120 MLN DLR CONVERTIBLE BOND + ROME, March 3 - Italy's state-owned <Banca Nazionale del +Lavoro - BNL> said it would issue 120 mln dlrs of five-year +convertible eurobonds, an operation to be lead-managed by +<Credit Suisse-First Boston Ltd>. + BNL president Nerio Nesi told a news conference that the +issue, to be placed on the main international markets and +listed in Luxembourg, would be the first equity linked issue by +an Italian bank on the Euromarket. + BNL officials said the issue is scheduled for mid-March and +additional financial details were not immediately available. + They said the operation would be through the issue of +depositary receipts by BNL's London branch. They said the bonds +would carry warrants issued by its <Efibanca> subsidiary and +convertible into BNL saving shares within five years. + The officials said a banking consortium led by Credit +Suisse-First Boston would at the same time arrange for the +private placing of an unspecified number of BNL savings shares +with foreign institutional investors. + The operation was to further its aim of obtaining a listing +on foreign stock exchanges with a view to future capital +increases through ordinary share issues, they said. + REUTER + + + + 3-MAR-1987 09:27:51.06 + +usa + + + + + +F +f0313reute +u f BC-GE-<GE>-SAYS-AMR-<AMR 03-03 0076 + +GE <GE> SAYS AMR <AMR> ORDER WORTH 650 MLN DLRS + EVENDALE, Ohio, March 3 - General Electric Co said AMR +Corp's oprder of GE CFG-80C2 engines to power 25 new <Airbus +Industrie> A300-600R and 15 Boeing Co <BA> 767-300ER twinjets +is worth over 650 mln dlrs. + The company said the order is the largest single one it has +ever received for commercial aircraft engines. + AMR announced the order earlier today. + GE said deliveries will start in early 1988. + Reuter + + + + 3-MAR-1987 09:30:07.60 +earn +canada + + + + + +E F +f0314reute +r f BC-precambrian-shield 03-03 0054 + +<PRECAMBRIAN SHIELD RESOURCES LTD> YEAR LOSS + CALGARY, Alberta, March 3 - + Shr loss 1.93 dlrs vs profit 16 cts + Net loss 53,412,000 vs profit 4,479,000 + Revs 24.8 mln vs 32.7 mln + Note: 1986 shr and net include 51,187,000 dlr writedown on +U.S. operations, uneconomic coal operations and other mineral +properties + Reuter + + + + 3-MAR-1987 09:30:48.45 +money-fxinterest +uk + + + + + +RM +f0316reute +b f BC-U.K.-MONEY-MARKET-GIV 03-03 0094 + +U.K. MONEY MARKET GIVEN FURTHER 437 MLN STG HELP + LONDON, March 3 - The Bank of England said it had provided the +money market with a further 437 mln stg assistance in the +afternoon session. This brings the Bank's total help so far +today to 461 mln stg and compares with its revised shortage +forecast of 450 mln stg. + The central bank made purchases of bank bills outright +comprising 120 mln stg in band one at 10-7/8 pct and 315 mln +stg in band two at 10-13/16 pct. + In addition, it also bought two mln stg of treasury bills +in band two at 10-13/16 pct. + REUTER + + + + 3-MAR-1987 09:32:34.04 +earn +usa + + + + + +F +f0323reute +d f BC-GREASE-MONKEY-HOLDING 03-03 0024 + +GREASE MONKEY HOLDING CORP <GMHC> YEAR NOV 30 + DENVER, March 3 - + Shr nil vs nil + Net 130,998 vs 30,732 + Revs 1,568,941 vs 1,0053,234 + Reuter + + + + 3-MAR-1987 09:33:32.98 +earn +usa + + + + + +F +f0331reute +d f BC-ACCEPTANCE-INSURANCE 03-03 0058 + +ACCEPTANCE INSURANCE HOLDINGS INC <ACPT> YEAR + OMAHA, March 3 - + Oper shr profit 1.80 dlrs vs loss 2.28 dlrs + Oper net profit 2,048,0000 vs loss 1,318,000 + Revs 25.4 mln vs 12.3 mln + Avg shrs 1,135,000 vs 576,000 + NOTE: Net excludes realized investment gains of 40,000 dlrs +vs 13,000 dlrs. + 1986 net excludes 729,000 dlr tax credit. + Reuter + + + + 3-MAR-1987 09:35:03.37 +earn +usa + + + + + +F +f0333reute +u f BC-MINSTAR-INC-<MNST>-4T 03-03 0064 + +MINSTAR INC <MNST> 4TH QTR NET + MINNEAPOLIS, MINN., March 3 - + Oper shr loss 31 cts vs loss 30 cts + Oper net loss 5,429,000 vs loss 5,216,000 + Revs 257.5 mln vs 243.6 mln + Avg shrs 17.5 mln vs 13.5 mln + Year + Oper shr loss eight cts vs profit 28 cts + Oper net loss 1,324,000 vs profit 4,067,000 + Revs 989.5 mln vs 747.9 mln + Avg shrs 17.6 mln vs 15.7 mln + + NOTE: 1986 operating net loss excludes income from +discontinued operations equal to 11 cts in the quarter and 66 +cts in the year compared with 1.07 dlrs in the quarter and 1.23 +dlrs in the respective periods of 1985. + 1986 operating net loss also excludes extraordinary charges +of 14 cts in the quarter and 54 cts in the year. + 1985 operating net profit excludes an extraordinary gain of +47 cts. + Reuter + + + + 3-MAR-1987 09:37:19.17 + +switzerland + + + + + +RM +f0338reute +u f BC-DAI-ICHI-HOTEL-SWISS 03-03 0080 + +DAI-ICHI HOTEL SWISS FRANC NOTES COUPON CUT + ZURICH, March 3 - The coupon on Dai-Ichi Hotel Ltd's 50 mln +Swiss franc issue of five-year notes with equity warrants has +been cut to 1-5/8 pct from the indicated 1-7/8 pct, lead +manager Swiss Volksbank said. + The warrants have an exercise price of 1,507 yen per share, +compared with the last traded price of 1,470 yen, it said. + The notes are guarantees by Long-Term Credit Bank of Japan +Ltd. Payment is due on March 25. + REUTER + + + + 3-MAR-1987 09:37:43.02 +earn +canada + + + + + +E F +f0339reute +r f BC-mark-resources-inc 03-03 0044 + +<MARK RESOURCES INC> YEAR LOSS + CALGARY, Alberta, March 3 - + Shr not given + Loss 54.9 mln + Revs 27.2 mln + Note: Prior year results not given. 1986 results include +accounts of 89 pct owned <Precambrian Shield Resources Ltd>, +acquired November 5, 1986 + Reuter + + + + 3-MAR-1987 09:37:53.73 + +uk + + + + + +A +f0340reute +r f BC-SAAB-SCANIA-ISSUES-15 03-03 0078 + +SAAB-SCANIA ISSUES 150 MLN DLR EUROBOND + LONDON, March 3 - Saab-Scania AB is issuing a 150 mln dlr +eurobond due April 2, 1992 paying 7-3/4 pct and priced at +101-3/4 pct, lead manager Morgan Guaranty Ltd said. + The bond is available in denominations of 5,000 and 50,000 +dlrs and will be listed in London. Payment date is April 2, +1992. + Fees comprise 1-1/4 pct selling concession and 5/8 pct +management and underwriting combined, and listing will be in +London. + REUTER + + + + 3-MAR-1987 09:38:16.31 +earn +usa + + + + + +F +f0341reute +d f BC-TRANSFORM-LOGIC-<TOOG 03-03 0133 + +TRANSFORM LOGIC <TOOG> REVISES RESULTS DOWNWARD + SCOTTSDALE, Ariz., March 3 - Transform Logic Corp said it +has revised downward its previously reported fourth quarter and +year, ended October 31, results to reflect compensation expense +for employee stock options. + The company said resolution of this disagreement with its +auditors came as a result of Securities and Exchange Commission +involvement. The company will amend its option-granting +procedure to conform to the SEC decision which will eliminate +future charges, it added. + Transform said its fourth quarter profit was revised to +305,082 dlrs, or two cts a share, from the previously reported +580,955 dlrs, which left the company with a fiscal 1986 loss of +249,814 dlrs, or two cts a share, instead of the reported +26,195 dlrs profit. + Reuter + + + + 3-MAR-1987 09:38:28.76 +earn +usa + + + + + +F +f0342reute +r f BC-AMERICAN-STORES-<ASC> 03-03 0061 + +AMERICAN STORES <ASC> SEES LOWER YEAR NET + SALT LAKE CITY, March 3 - American Stores Co said it +expects to report earnings per share of 3.70 to 3.85 dlrs per +share on sales of slightly over 14 billion dlrs for the year +ended January 31. + The supermarket chain earned 4.11 dlrs per share on sales +of 13.89 billion dlrs last year. + The company did not elaborate. + Reuter + + + + 3-MAR-1987 09:38:33.69 +earn +usa + + + + + +F +f0343reute +r f BC-KASLER-CORP-<KASL>-1S 03-03 0031 + +KASLER CORP <KASL> 1ST QTR JAN 31 NET + SAN BERNARDINO, Calif., March 3 - + Shr profit three cts vs loss seven cts + Net profit 161,000 vs loss 367,000 + Revs 24.3 mln vs 26.5 mln + Reuter + + + + 3-MAR-1987 09:41:45.44 + +usa + + + + + +F +f0346reute +r f BC-CARIBBEAN-SELECT-<CSE 03-03 0091 + +CARIBBEAN SELECT <CSEL> TO REDEEM WARRANTS + TAMPA, Fla., March 3 - Caribbean Select Inc said it has +elected to redeem on April 10 all its Class A warrants and all +Class B warrants at 0.01 ct each. + At the same time, it said its board has decided to reduce +the exercise price of the Class B warrants to 3.50 dlrs per +common share from four dlrs to encourage the exercise of the +warrants. Each Class B warrant allows the purchase of one +common share. + It said each Class A warrant is still exercisable into one +common share at two dlrs each. + Reuter + + + + 3-MAR-1987 09:45:18.22 +earn +uk + + + + + +F +f0356reute +d f BC-UNILEVER-HAS-IMPROVED 03-03 0099 + +UNILEVER HAS IMPROVED MARGINS, VOLUMES IN 1986 + LONDON, MARCH 3 - Unilever Plc <UN.A> and NV group reported +improvements in margins and underlying sales volume growth of +five pct in 1986 after stripping out the effects of falling +prices, disposals and currency movements, Unilever Plc chairman +Michael Angus said. + He told reporters that volumes in North America increased +some 10.5 pct while European consumer goods rose about 2.5 pct +after being flat for some years. + Much of the disposal strategy, aimed at concentrating +activities on core businesses, had now been completed, he +noted. + But the process of acquisitions would go on, with strategic +acquisitions taking place "from time to time," he said. + The company earlier reported a 20 pct rise in pre-tax +profits for 1986 to 1.14 billion stg from 953 mln previously. +In guilder terms, however, profits at the pre-tax level dropped +three pct to 3.69 billion from 3.81 billion. + Angus said the recent purchase of Chesebrough-Pond's Inc +<CBM.N> for 72.50 dlrs a share was unlikely to bring any +earnings dilution. + However, it would not add much to profits, with much of the +company's operating profits paying for the acquisition costs. + Finance director Niall Fitzgerald added that while gearing +- debt to equity plus debt - rose to about 60 pct at end 1986 +from 35 pct last year, this was expected to drop back to about +40 pct by end-1987. + The same divergence was made in full year dividend, with +Unilever NV's rising 3.4 pct to 15.33 guilders and Unilever +Plc's increasing 29.9 pct to 50.17p, approximately in line with +the change in attributable profit. + Angus said the prospectus for the sale of parts of +Chesebrough was due to be published shortly. However, he said +that there was no target date for completing the process. + He also declined to say what sort of sum Unilever hoped to +realise from the operation, beyond noting that Chesebrough had +paid around 1.25 billion dlrs for Stauffer Chemical Co, which +operates outside Unilever's core activities. + In the U.S., Organic growth from the Lipton Foods business, +considerable expansion in the household products business and +in margarine had been behind the overall sales increase. + However, he noted that the U.S. Household products business +had turned in a planned loss, with fourth quarter performance +better than expected despite the anticipated heavy launch costs +of its Surf detergents. + Reuter + + + + 3-MAR-1987 09:45:29.48 +acq +usa + + + + + +F +f0357reute +r f BC-SARA-LEE-<SLE>-TO-BUY 03-03 0096 + +SARA LEE <SLE> TO BUY 34 PCT OF DIM + CHICAGO, March 3 - Sara Lee Corp said it agreed to buy a 34 +pct interest in Paris-based DIM S.A., a subsidiary of BIC S.A., +at a cost of about 84 mln dlrs. + DIM S.A., a hosiery manufacturer, had 1985 sales of about +260 mln dlrs. + The investment includes the purchase of 360,537 newly +issued DIM shares valued at about 51 mln dlrs and a loan of +about 33 mln dlrs, it said. The loan is convertible into an +additional 229,463 DIM shares, it noted. + The proposed agreement is subject to approval by the French +government, it said. + Reuter + + + + 3-MAR-1987 09:45:54.32 + +usa + + + + + +F +f0358reute +r f BC-HOLIDAY-CORP-<HIA>-HO 03-03 0086 + +HOLIDAY CORP <HIA> HOTEL GROUP ADDS PROPERTIES + MEMPHIS, Tenn., March 3 - Holiday Corp's Holiday Inn Hotel +Group said it will add a record 17 hotels with 4,440 rooms to +its international division as part of its plan to double its +presence abroad by 1995. + The company said its international division will reach +50,000 rooms by this spring, classifying it as the eighth +largest hotel chain in the world. Holiday said by the end of +the year, there will be approximately 220 Holiday Inn hotels in +54 countries. + The company said it plans to expand from 28 to 55 hotels in +its Asia/Pacific region and to 192 in its Europe/Middle +East/Africa regionby 1995. + For 1987, the hotel group will focus on expansion on +Western Europe and Asia, citing China as an untapped source for +the international lodging industry. + Holiday also said it will concentrate on city center hotels +in key destination cities in Western Europe, catering primarily +to business travelers. + Some of those cities where Holiday said it will open new +properties this year include Amsterdam, Lyon/Atlas and Lisbon. + Reuter + + + + 3-MAR-1987 09:46:36.82 +trade +usachina + + + + + +G T M C +f0360reute +r f BC-CHINA-CALLS-FOR-BETTE 03-03 0140 + +CHINA CALLS FOR BETTER TRADE DEAL WITH U.S. + PEKING, March 3 - China called on the United States to +remove curbs on its exports, to give it favourable trading +status and ease restrictions on exports of high technology. + But the U.S. Embassy replied that Chinese figures showing +13 years of trade deficits with the U.S. Out of the last 15 are +inaccurate and said Peking itself would have to persuade +Congress to change laws which limit its exports. + The official International Business newspaper today +published China's demands in a editorial to coincide with the +visit of U.S. Secretary of State George Shultz. + "It is extremely important that the U.S. Market reduce its +restrictions on Chinese imports, provide the needed facilities +for them and businessmen from both sides help to expand Chinese +exports," the editorial said. + "The U.S. Should quickly discard its prejudice against +favourable tariff treatment for Chinese goods and admit China +into the Generalised System of Preference (GSP). + "Despite easing of curbs on U.S. Technology exports in +recent years, control of them is still extremely strict and +influences normal trade between the two countries," it added. + The paper also printed an article by China's commercial +counsellor in its Washington embassy, Chen Shibiao, who said +that "all kinds of difficulties and restrictions" were preventing +bilateral trade fulfilling its full potential. + He named them as U.S. Protectionist behaviour, curbs on +technology transfer and out-of-date trade legislation. + Reuter + + + + 3-MAR-1987 09:46:55.59 +lei +usa + + + + + +V RM +f0361reute +u f BC-/U.S.-COMMERCE-SECRET 03-03 0106 + +U.S. COMMERCE SECRETARY SAYS EXPORT RISE NEEDED + WASHINGTON, March 3 - Commerce Secretary Malcolm Baldrige +said after the release of a sharply lower January leading +indicator index that a pickup in exports is needed. + "The best tonic for the economy now would be a pickup in net +exports," he said in a statement after the department reported +the index fell 1.0 pct in January from December, the sharpest +drop since a 1.7 pct fall in July, 1984. + The main reasons for the January decline after a 2.3 pct +December rise were declines in building permits, new orders for +plant and equipment and for consumer and industrial goods. + Reuter + + + + 3-MAR-1987 09:47:47.16 +earn +canada + + + + + +E F +f0366reute +r f BC-precambrian-takes 03-03 0108 + +PRECAMBRIAN SHIELD TAKES 51 MLN DLR WRITEDOWN + CALGARY, Alberta, March 3 - <Precambrian Shield Resources +Ltd>, earlier reporting a large loss against year-ago profit, +said the 1986 loss was mainly due to a 51,187,000 dlr writedown +on its U.S. operations, uneconomic coal and other mineral +properties. + Precambrian, which is 89 pct owned by <Mark Resources Inc>, +said it took the writedown in accordance with new Canadian +Insititute of Chartered Accountants guidelines for full cost +method accounting by oil and gas companies. + Precambrian earlier reported a 1986 loss of 53.4 mln dlrs, +compared to profit of 4.5 mln dlrs in the prior year. + Reuter + + + + 3-MAR-1987 09:48:24.78 + +usa + + +nasdaq + + +F +f0367reute +r f BC-AERO-SERVICES-<AEROE> 03-03 0075 + +AERO SERVICES <AEROE> GETS NASDAQ EXCEPTION + TETERBORO, N.J., March 3 - Aero Services Inc said its +common stock will continue to be included for quotation in the +National Association of Securities Dealers' NASDAQ system due +to an exception from filing requiements, which it failed to +meet as of January 15. + The company said while it believes it can meet conditions +the NASD imposed for the exception, there can be no assurance +that it will do so. + Reuter + + + + 3-MAR-1987 09:49:23.53 +coffeecrude +kenya + + + + + +RM +f0373reute +r f BC-KENYAN-ECONOMY-FACES 03-03 0099 + +KENYAN ECONOMY FACES PROBLEMS, PRESIDENT SAYS + NAIROBI, March 3 - The Kenyan economy is heading for +difficult times after a boom last year, and the country must +tighten its belt to prevent the balance of payments swinging +too far into deficit, President Daniel Arap Moi said. + In a speech at the state opening of parliament, Moi said +high coffee prices and cheap oil in 1986 led to economic growth +of five pct, compared with 4.1 pct in 1985. + The same factors produced a two billion shilling balance of +payments surplus and inflation fell to 5.6 pct from 10.7 pct in +1985, he added. + "But both these factors are no longer in our favour ... As a +result, we cannot expect an increase in foreign exchange +reserves during the year," he said. + The price of coffee, Kenya's main source of foreign +exchange, fell in London today to about 94 cents a pound from a +peak of 2.14 dlrs in January 1986. + Crude oil, which early last year slipped below 10 dlrs a +barrel, has since crept back to over 18 dlrs. + Moi said the price changes, coupled with a general decline +in the flow of capital from the rest of the world, made it more +difficult to finance the government's budget deficit. + Kenya was already spending over 27 pct of its budget on +servicing its debts and last year it was a net exporter of +capital for the first time in its history, he added. + "This is a clear indication that we are entering a difficult +phase as regards our external debts, and it is imperative that +we raise the rate of domestic savings and rely less on foreign +sources to finance our development," he said. + "It will be necessary to maintain strict discipline on +expenditure ... And members of this house will have to take the +lead in encouraging wananchi (ordinary people) to be more +frugal in satisfying immediate needs," the president added. + REUTER + + + + 3-MAR-1987 09:49:45.02 + +usa + + + + + +F +f0375reute +r f BC-TRI-STAR-<TRSP>-CHANG 03-03 0079 + +TRI-STAR <TRSP> CHANGING FISCAL YEAR + NEW YORK, March 3 - Tri-Star Pictures Inc said it is +changing its fiscal year to year ending at the end of February +from a calendar year to reflect the traditional business cycles +of its two principal businesses, motion picture distribution +and motion picture exhibition. + It said it expects to file a report for the two-month +fiscal "year" ended February 28, 1987 by May 28 and to report +earnings for the new first quarter in June. + Reuter + + + + 3-MAR-1987 09:50:34.51 + +usa + + + + + +F +f0378reute +u f BC-LIFETIME-<LFT>-TO-MAK 03-03 0055 + +LIFETIME <LFT> TO MAKE ANNOUNCEMENT + NEW YORK, March 3 - Lifetime Corp said it will make an +announcement this morning between 1000 EST and 1030 EST. + A company spokesman said the company preferred not to +comment until that time. + The American Stock Exchange delayed trading in Lifetime +shares this morning for news pending. + Reuter + + + + 3-MAR-1987 09:53:44.44 +acq +usa + + + + + +E F +f0389reute +r f BC-scott's-hospitality 03-03 0071 + +SCOTT'S HOSPITALITY ACQUIRES CAPITAL FOOD + TORONTO, March 3 - <Scott's Hospitality Inc> said it +acquired all issued shares of Capital Food Services Ltd, of +Ottawa. Terms were not disclosed. + Scott's said Capital Food had 1986 sales of more than 20 +mln dlrs and will continue to operate under its present name +with existing management. + Capital Food provides food services to several Ottawa +institutions, the company said. + Reuter + + + + 3-MAR-1987 09:57:02.21 +coffee +zimbabwe + + + + + +C T +f0399reute +r f BC-ZIMBABWE-COFFEE-OUTPU 03-03 0099 + +ZIMBABWE COFFEE OUTPUT SET TO RISE + HARARE, March 3 - Zimbabwean coffee output will reach +13,000 tonnes this year, up on just over 11,000 tonnes produced +in 1986, the Commercial Coffee Growers Association said. + Administrative Executive Robin Taylor told the domestic +news agency ZIANA that Zimbabwe earned the equivalent of 33 mln +U.S. Dlrs from coffee exports last year. He would not say how +much the country would earn in 1987. + Taylor said the 173 commercial coffee growers under his +association had increased production from 5,632 tonnes in 1980 +to more than 11,000 tonnes in l986. + Reuter + + + + 3-MAR-1987 09:58:00.11 + +usa + + + + + +F +f0401reute +r f BC-YANKEE-<YNK>-SWAPS-ST 03-03 0048 + +YANKEE <YNK> SWAPS STOCK FOR DEBENTURES + COHASSET, Mass., March 3 - Yankee Cos Inc said it has +acquired 3,916,000 dlrs of 7-1/2 pct convertible subordinated +debentures due May 15, 1998 of its YFC International Finance NV +affiliate for 501,807 common shares from an institutional +investor. + Reuter + + + + 3-MAR-1987 10:00:52.96 +acq +usa + + + + + +F +f0408reute +d f BC-VIDEO-DISPLAY-<VIDE> 03-03 0082 + +VIDEO DISPLAY <VIDE> TO SELL CABLE TV UNIT + ATLANTA, March 3 - Video Display Corfp said it has reached +a tentiative agreement to sell its existing cable television +business for undisclosed terms and expects to report a gain on +the transaction. The buyer was not named. + The company said it will redeploy its service assets into +manufacturing and distribution. + It said the operations being sold accounted for about five +pct of revenues for the year ended February 28 and lost money. + Reuter + + + + 3-MAR-1987 10:00:57.16 +earn +usa + + + + + +F +f0409reute +d f BC-INTEK-DIVERSIFIED-COR 03-03 0041 + +INTEK DIVERSIFIED CORP <IDCC> 4TH QTR NET + LOS ANGELES, March 3 - + Shr three cts vs three cts + Net 98,20000 vs 91,898 + Revs 2,843,520 vs 2,372,457 + Year + Shr 13 cts vs 21 cts + Net 401,179 vs 681,374 + Revs 10.5 mln vs 9,699,535 + Reuter + + + + 3-MAR-1987 10:01:14.42 + +usa + + + + + +F +f0410reute +d f BC-BERYLLIUM-INT'L-SIGNS 03-03 0122 + +BERYLLIUM INT'L SIGNS JOINT VENTURE PACT + SALT LAKE CITY, Utah, March 3 - <Beryllium International +Corp> said it has signed a joint venture agreement with Cominco +American Inc, a unit of Cominco Ltd <CLT>, to develop a +beryllium mine and processing plant on Beryllium +International's property in the Topaz Mountains southwest of +Salt Lake City. + Beryllium said as a 49 pct owner of the venture iot would +be contributing the mine while Cominco, as operator and 51 pct +owner, would conduct drilling, metallurgical studies, process +testing and other preliminary work for a feasibility study. + Beryllium said the cost of the preliminary work in 1987, +which will start immediately, should be about 250,000 dlrs to +300,000 dlrs. + Reuter + + + + 3-MAR-1987 10:01:28.07 +housing +usa + + + + + +V RM +f0411reute +f f BC-******U.S.-SINGLE-FAM 03-03 0014 + +******U.S. SINGLE-FAMILY HOME SALES FELL 6.8 PCT IN JAN AFTER REVISED 12.1 PCT DEC GAIN +Blah blah blah. + + + + + + 3-MAR-1987 10:02:11.63 +housing +usa + + + + + +V RM +f0415reute +b f BC-/U.S.-HOME-SALES-FELL 03-03 0079 + +U.S. HOME SALES FELL 6.8 PCT IN JANUARY + WASHINGTON, March 3 - Sales of new single-family homes in +the United States fell 6.8 pct in January from December to a +seasonally adjusted annual rate of 716,000 units, the Commerce +Department said. + The department revised downward December's sales to a 12.1 +pct rise to 768,000 units from the previously reported 12.7 pct +increase. + The January decline in sales was the largest since last +October when sales fell 9.3 pct. + Before seasonal adjustment, the number of homes actually +sold in January was 53,000, up from 49,000 in December but down +from 59,000 in January, 1986. + The January fall brought home sales to a level 1.6 pct +below January, 1986, when they were a seasonally adjusted +728,000 units. + The average price was a record 127,100 dlrs, surpassing the +previous record 119,100 price set in December. + The median price of a home in January reached 100,700 dlrs +-- the first time the price has exceeded 100,000 dlrs. That +compared with a median price of 94,600 dlrs in December and +94,000 dlrs in January a year ago. + New homes available on the market in January totaled a +seasonally adjusted 362,000 units, unchanged from December and +equal to a 6.3 months' supply. + The supply in December was 5.9 months. + Reuter + + + + 3-MAR-1987 10:02:22.46 + +usa + + + + + +F +f0416reute +r f BC-DIMIS-<DMS>-EXTENDS-L 03-03 0070 + +DIMIS <DMS> EXTENDS LIFE OF WARRANTS BRIEFLY + EATONTOWN, N.J., March 3 - Dimis Inc said it has extended +by five business days the expiration of its common stock +purchase warrants until March Nine. + It said over one mln have already been exercised. The +warrants became effective February 17. + Holders exercising will receive a new warrant expiring +March 31 allowing the purchase of half a common share at one +dlr. + Reuter + + + + 3-MAR-1987 10:05:32.60 + +canadausa + + + + + +E F +f0441reute +r f BC-american-barrick 03-03 0046 + +AMERICAN BARRICK <ABX> UNIT COMPLETES ISSUE + TORONTO, March 3 - <American Barrick Resources Corp> said +wholly owned Barrick Resources (USA) Inc completed the +previously announced 50 mln U.S. dlr issue of two pct gold +indexed notes, which are guaranteed by American Barrick. + Reuter + + + + 3-MAR-1987 10:07:42.19 +acq +usa + + + + + +F +f0445reute +d f BC-COMMUNITY-BANK-<CBSI> 03-03 0060 + +COMMUNITY BANK <CBSI> TO MAKE ACQUISITION + SYRACUSE, N.Y., March 3 - Community Bank System Inc said it +has entered into a definitive agreement to acquire Nichols +Community Bank for 2,800,000 dlrs in common stock. + It said subject to approval by Nichols shareholders and +regulatory authorities, the transaction is expected to be +completed later this year. + Reuter + + + + 3-MAR-1987 10:08:28.26 +jobs +belgium + + + + + +RM +f0447reute +r f BC-BELGIAN-UNEMPLOYMENT 03-03 0086 + +BELGIAN UNEMPLOYMENT FALLS IN FEBRUARY + BRUSSELS, March 3 - Belgian unemployment, based on the +number of jobless drawing unemployment benefit, fell to 12.1 +pct of the working population at the end of February from 12.6 +pct at the end of January, the National Statistics Office said. + The rate compares with 12.4 pct at the end of February +1986. + The total number of jobless stood at 508,392, compared with +530,587 at the end of January and 521,219 at the end of +February 1986, the Statistics Office said. + REUTER + + + + 3-MAR-1987 10:12:44.89 + +usa + + + + + +F +f0456reute +r f BC-KODAK-<EK>-HAS-NEW-DA 03-03 0068 + +KODAK <EK> HAS NEW DATA STORAGE, USAGE SYSTEMS + NEW YORK, March 3 - Eastman Kodak Co said it is introducing +four information technology systems that will be led by today's +highest-capacity system for data storage and retrieval. + The company said information management products will be +the focus of a multi-mln dlr business-to-business +communications campaign under the threme "The New Vision of +Kodak." + Noting that it is well-known as a photographic company, +Kodak said its information technology sales exceeded four +billion dlrs in 1986. "If the Kodak divisions generating those +sales were independent, that company would rank among the top +100 of the Fortune 500," it pointed out. + The objective of Kodak's "new vision" communications +campaign, it added, is to inform others of the company's +commitment to the business and industrial sector. + Kodak said the campaign will focus in part on the +information management systems unveilded today -- + -- The Kodak optical disk system 6800 which can store more +than a terabyte of information (a tillion bytes). + - The Kodak KIMS system 5000, a networked information +management system using optical disks or microfilm or both. + -- The Kodak KIMS system 3000, an optical-disk-based system +that allows users to integrate optical disks into their current +information management systems. + -- The Kodak KIMS system 4500, a microfilm-based, +computer-assisted system which can be a starter system. + Kodak said the optical disy system 6800 is a +write-once/ready-many-times type its Mass Memory Division will +market on a limited basis later this year and in quantity in +1988. + Each system 6800 automated disk library can accommodate up +to 150, 14-inch optical disks. Each disk provides 6.8 gigabytes +of randomly accessible on-line storage. Thus, Kodak pointed +out, 150 disks render the more-than-a-terabyte capacity. + Kodak said it will begin deliveries of the KIMS system 5000 +in mid-1987. The open-ended and media-independent system +allows users to incorporate existing and emerging technologies, +including erasable optical disks, high-density magnetic media, +fiber optics and even artificial intelligence, is expected to +sell in the 700,000 dlr range. + Initially this system will come in a 12-inch optical disk +version which provides data storage and retrieval through a +disk library with a capacity of up to 121 disks, each storing +2.6 gigabytes. + Kodak said the KIMS system 3000 is the baseline member of +the family of KIMS systems. Using one or two 12-inch manually +loaded optical disk drives, it will sell for about 150,000 dlrs +with deliveries beginning in mid-year. + The company said the system 3000 is fulling compatibal with +the more powerful KIMS system 5000. + It said the KIMS system 4500 uses the same hardware and +software as the system 5000. It will be available in mid-1987 +and sell in the 150,000 dlr range. + Reuter + + + + 3-MAR-1987 10:14:49.98 + +usa + + + + + +F +f0467reute +r f BC-BANGOR-HYDRO-<BANG>-S 03-03 0081 + +BANGOR HYDRO <BANG> SEEKS RATE CUT + BANGOR, Maine, March 3 - Bangor Hydro-Electric Cor said it +has filed with the Maine Public Utilities Commission (MPUC) for +a two-stage base rate reduction. + Bangor Hydro said the first stage, which could take effect +on April 1 and would stay effective until the MPUC makes a +final decision on the filing, could cut revenues by 6.149 mln +dlrs, or 9.7 pct. + The company said lower federal income taxes and lower +capital costs prompted the filing. + The second stage, Bangor Hydro said, effective when the +MPUC makes a final decision, calls for an additional revenue +reduction of 712,000 dlrs, or 1.1 pct. + Bangor Hydro said, if approved, the cuts would reduce +residential base rates by 8.5 pct, with 7.5 pct cut by April 1. + The utility company also said it is seeking to increase its +fuel cost adjustment rate by April 1. + Bangor said if the increase is approved it could offset +much of the base rate cut and may cause a net increase in some +customers' rates. + Reuter + + + + 3-MAR-1987 10:15:06.95 + +usa + + + + + +F +f0469reute +d f BC-BROWNING-FERRIS-<BFI> 03-03 0105 + +BROWNING-FERRIS <BFI>WASTE DISPOSAL SITE CLEARED + HOUSTON, March 3 - Browning-Ferris Industries Inc said the +Colorado Department of Health and the U.S. Environmental +Protection Agency have awarded the company permits to build and +operate a hazardous waste disposal site near Last Chance, Colo. + The company said construction will start this year and take +about 12 months, costing about 14 to 16 mln dlrs. It said it +has already spent 10 mln dlrs on development costs. + The site will not accept materials that react rapidly with +air or water, explosives, shock sensitive materials or +radioactive wastes, the company said. + Reuter + + + + 3-MAR-1987 10:16:12.11 +earn +sweden + + + + + +F +f0472reute +d f BC-PHARMACIA-AB-<PHAB-ST 03-03 0028 + +PHARMACIA AB <PHAB ST> 1986 YEAR + STOCKHOLM, March 3 - Sales 3.65 billion crowns vs 3.40 +billion. + Profit after financial items 821.2 mln crowns vs 740.2 +mln. + The 1986 results include a once-off writedown of 520 mln +crowns for intangible assets, mainly the know-how paid for in +the takeover of a number of high-tech companies by the group, +Pharmacia said. + Earnings per share after real tax including the writedown: +1.94 crowns vs 12.05 crowns. + Earnings per share after real tax (not including the +writedown): 12.38 crowns vs 12.05 + Earnings per American Depository Receipt (ADR) according to +U.S. Accounting principles after real tax including the +writedown): 1.96 crowns vs 9.49 crowns. + Earnings per ADR according to U.S. Accounting principles +after real tax (without the writedown): 9.8 crowns vs 9.49. + One ADR represents 0.75 pct of one B Free share in +Pharmacia. + The board proposed a dividend of 1.55 crowns vs 1.25. + REUTER + + + +3-MAR-1987 10:16:24.19 + +usa + + + + + +F +f0473reute +d f BC-VWR-CORP-<VWRX>-FORMS 03-03 0069 + +VWR CORP <VWRX> FORMS NEW UNIT + SEATTLE, March 3 - VWR Corp said it has formed a new +subsidiary, Momentun Textiles, to handle the distribution of +upholstery fabrics, leathers and naugahyde to contract and +consumer furniture manufacturers. + It said its VWR Textiles and Supplies unit, which had +handled that business, will continue to distribute non-woven +textiles, construction fabrics and manufacturing supplies. + Reuter + + + + 3-MAR-1987 10:17:43.59 + +usa + + + + + +F +f0484reute +r f BC-HALLWOOD-GROUP-<HWG> 03-03 0091 + +HALLWOOD GROUP <HWG> OFFICIAL GET SAXON POST + DALLAS, March 3 - Saxon Oil Development Partners' Saxon Oil +Co said its chairman Bill Saxon and chief executive officer +Steven Saxon have resigned effective immediately. + Saxon said Anthony Gumbiner, chairman and chief executive +officer of The Hallwood Group Inc, succeeds Bill Saxon as +chairman. + Hallwood owns a substantial number of shares of preferred +stock in Saxon which, if converted into common stock, would +constitute approximately 37 pct of the company, according to a +source. + Hallwood specializes in bailing out financially troubled +companies and restructuring their debt, according to the +source. In exchange sometimes, the group receives a small +portion of the company's common stock. + At times, the group also receives a position in the +company, as was the case at Saxon, the source explained. + Reuter + + + + 3-MAR-1987 10:20:45.46 +earn +usa + + + + + +F +f0494reute +d f BC-PHARMACIA-FORECASTS-H 03-03 0101 + +PHARMACIA FORECASTS HIGHER 1987 EARNINGS + STOCKHOLM, March 3 - Pharmacia AB <PHAB ST> forecast +earnings after financial items of one billion crowns in 1987 vs +821.2 mln last year on condition that exchange rates remained +at their present parities. + Sales would in such circumstances go up to six billion +crowns from 3.65 billion in 1986, it said. + A weakening Dollar was mainly responsible for a five pct +negative impact on sales during 1986 which the company blamed +on currency movements. + Last year's results were also badly hit by a once-off +writedown of 520 mln crowns for intangible assets. + The company said mainly this represented the premium the +group had paid for the know-how of various high-tech firms it +had taken over. + The accounts also showed a financial deficit of 1.87 +billion crowns vs a deficit of 133 mln which was covered partly +by drawing down company liquidity to 738 mln vs one billion and +partly by increasing borrowing to 2.23 billion vs 621 mln. + Pharmacia said the financial deficit was caused by it +having used more funds than generated by group operations, +mainly because of the 1.36 billion it paid in cash for shares +in LKB-Produkter AB and the assets of Intermedics-Intraocular +Inc. + REUTER + + + + 3-MAR-1987 10:23:39.80 + +usa + + + + + +M +f0504reute +d f BC-BERYLLIUM-INT'L-SETS 03-03 0121 + +BERYLLIUM INT'L SETS JOINT VENTURE WITH COMINCO + SALT LAKE CITY, Utah, March 3 - Beryllium International +Corp said it has signed a joint venture agreement with Cominco +American Inc, a unit of Cominco Ltd, to develop a beryllium +mine and processing plant on Beryllium International's property +in the Topaz Mountains southwest of Salt Lake City. + Beryllium said as a 49 pct owner of the venture it would be +contributing the mine while Cominco, as operator and 51 pct +owner, would conduct drilling, metallurgical studies, process +testing, and other preliminary work for a feasibility study. + Beryllium said the cost of the preliminary work in 1987, +which will start immediately, should be about 250,000 dlrs to +300,000 dlrs. + Reuter + + + + 3-MAR-1987 10:26:35.62 +gnp +canada + + + + + +E V RM +f0508reute +f f BC-CANADA-REAL-4TH-QTR-G 03-03 0013 + +******CANADA REAL 4TH QTR GDP ROSE 1.1 PCT, AFTER 3RD QTR 1.1 PCT RISE - OFFICIAL +Blah blah blah. + + + + + + 3-MAR-1987 10:29:04.26 +bop +canada + + + + + +E V RM +f0518reute +f f BC-CANADA-4TH-QTR-CURREN 03-03 0017 + +******CANADA 4TH QTR CURRENT ACCOUNT DEFICIT 2.3 BILLION DLRS VS 3RD QTR 1.9 BILLION DEFICIT - OFFICIAL +Blah blah blah. + + + + + + 3-MAR-1987 10:29:32.44 + +usa + + + + + +F +f0519reute +h f BC-UNITED-GUARDIAN-<UNIR 03-03 0075 + +UNITED-GUARDIAN <UNIR>, <FEDERAL> SIGN CONTRACT + SMITHTOWN, N.Y., March 3 - United-Guardian Inc said it +signed a contract with <Federal Health Corp> covering the +exclusive marketing of Warexin, a disinfectant for kidney +dialysis machines, hospital equipment and instruments. + Under the contract, United-Guardian said Federal will +continue to supply Hospal, a subsidiary of <Sandoz Ltd> and +<Rhone Poulenc S.A.> with all its Warexin requirements. + Reuter + + + + 3-MAR-1987 10:31:10.05 +ship +usa + + + + + +F +f0524reute +r f BC-MCLEAN-INDUSTRIES-<MI 03-03 0082 + +MCLEAN INDUSTRIES <MII> UNIT TRANSERS SERVICE + CRANFORD, N.J., March 3 - McLean Industries Inc said its +shipping subsidiary, United States Lines Inc, reached an +agreement in principle to transfer its South American service +to American Transport Lines Inc, a subsidiary of <Crowley +Maritime Corp>. + Under the terms of the agreement, United States Lines will +lease five vessels to American Transport for 15 months with an +option to extend the period up to 10 years, the company said. + In return, U.S. Lines will receive a fixed payment and a +percentage of revenues for at least three years and possibly as +long as American Transport utilizes its vessels and conducts +trade in South America, the company said. + The companies will consummate the transactions as soon as +the required approvals are obtained, McLean said. + Reuter + + + + 3-MAR-1987 10:32:15.36 + +usa + + + + + +RM F A +f0528reute +u f BC-PROXMIRE-VOWS-QUICK-A 03-03 0108 + +PROXMIRE VOWS QUICK ACTION ON U.S. BANKING BILL + WASHINGTON, March 3 - Senate Banking Committee Chairman +William Proxmire said modified legislation to help a federal +deposit insurance fund and prohibit new limited-service banks +and thrifts could be ready for a Senate vote in two to three +weeks. + Proxmire said he agreed to demands from committee members +for a one-year moratorium on granting new business powers +sought by commercial banks to increase the bill's chances. + In its new form, the bill would proscribe regulators from +granting new powers to banks, Proxmire told reporters after a +speech to the U.S. League of Savings Institutions. + A vote on the bill by the committee is scheduled for +Thursday. If approved it will go to the full Senate. + "I have spoken to the majority leader and he has agreed to +bring it up promptly on the Senate floor in two or three weeks," +Proxmire told the thrift executives. + The bill would recapitalize the Federal Savings and Loan +Insurance Corp fund with 7.5 billion dlrs. + It also would prohibit establishment of new nonbank banks +and nonthrift thrifts, so-called because they provide financial +services but do not meet the regulatory definition of both +making loans and receiving deposits. + Reuter + + + + 3-MAR-1987 10:33:48.56 + +usa + + + + + +C G L +f0540reute +u f BC-lard-consumption 03-03 0107 + +U.S. LARD CONSUMPTION IN JANUARY + WASHINGTON, March 3 - U.S. factory usage of lard in the +production of both edible and inedible products during January +totaled 21.3 mln lbs, vs a revised 25.6 mln lbs in December, +according to Census Bureau figures. + In the year-earlier period, usage, which includes +hydrogenated vegetable and animal fats and other oils in +process, amounted to 33.3 mln lbs. + Usage in January comprised 15.7 mln lbs of edible products +and 5.6 mln lbs of inedible products. + Total lard usage in the 1986/87 marketing season, which +began October 1, amounted to 104.3 mln lbs, vs 154.2 mln lbs in +the year-ago period. + Reuter + + + + 3-MAR-1987 10:34:47.47 + +netherlands + + + + + +RM +f0546reute +u f BC-SOCIETE-GENERALE-DUTC 03-03 0097 + +SOCIETE GENERALE DUTCH UNIT LAUNCHES CD PROGRAMME + AMSTERDAM, March 3 - The Amsterdam unit of French bank +Societe Generale said it is launching a 50-mln guilder, five +month certificate of deposit programme starting March 6 and +ending September 7. + Denominations will be in one mln guilders. The price is to +be set on March 4, issue date is March 6 and redemption at par +is on September 7. + Subscriptions are to be placed with Societe Generale, +Oolders en de Jong C.V or Haighton en Ruth B.V. A global note +for the issue will be deposited with the Dutch central bank. + REUTER + + + + 3-MAR-1987 10:35:22.38 + +uk + + + + + +RM +f0548reute +b f BC-MONY-FUNDING-ISSUES-1 03-03 0087 + +MONY FUNDING ISSUES 125 MLN DLR EUROBOND + LONDON, March 3 - Mony Funding Inc is issuing a 125 mln dlr +eurobond due April 7, 1997 paying 8-1/8 pct and priced at +101-1/2 pct, sole lead manager Citicorp Investment Bank Ltd +said. + The non-callable bond is guaranteed by Mutual Life +Insurance Co of the U.S. And is available in denominations of +5,000 dlrs and will be listed in Luxembourg. The selling +concession is 1-3/8 pct while management and underwriting +combined pays 5/8 pct. + The payment date is April 7. + REUTER + + + + 3-MAR-1987 10:37:40.72 +grainwheat +uk + + + + + +G +f0559reute +u f BC-SMALL-QUANTITY-OF-U.K 03-03 0057 + +SMALL QUANTITY OF UK WHEAT SOLD TO HOME MARKET + LONDON, March 3 - A total of 2,435 tonnes of British +intervention feed wheat were sold at today's tender for the +home market out of requests for 3,435 tonnes, the Home Grown +Cereals Authority, HGCA, said. + Price details were not reported. + No bids were submitted for intervention barley. + Reuter + + + + 3-MAR-1987 10:38:18.98 +gnp +canada + + + + + +E V RM +f0564reute +f f BC-CANADA-DECEMBER-GDP-U 03-03 0013 + +******CANADA DECEMBER GDP UP 1.2 PCT AFTER NOVEMBER'S 0.2 PCT FALL - OFFICIAL +Blah blah blah. + + + + + + 3-MAR-1987 10:38:44.01 +earn +usa + + + + + +F +f0568reute +d f BC-FIRST-FEDERAL-SAVINGS 03-03 0052 + +FIRST FEDERAL SAVINGS <FFKZ> YEAR NET + KALAMAZOO, MICH., March 3 - + Shr 78 cts vs one dlr + Net 1,413,000 vs 1,776,000 + Assets 705.3 mln vs 597.3 mln + Deposits 495.6 mln vs 493.9 mln + Loans 260.0 mln vs 379.7 mln + Qtly div six cts vs six cts prior qtr + Pay April 1 + Record March 6 + NOTE: 1986 net includes charges from accounting changes, +from one-time expenses associated with a proxy contest and an +increase in loan reserves. + First Federal Savings and Loan Association of Kalamazoo is +full name of company. + Reuter + + + + 3-MAR-1987 10:39:00.13 + +usa + + + + + +F +f0569reute +u f BC-BOEING-<BA>-SAYS-ORDE 03-03 0088 + +BOEING <BA> SAYS ORDER WORTH ONE BILLION DLRS + SEATTLE, March 3 - Boeing Co said its order for 15 +extended-range 767-300's from AMR Corp <AMR> is worth over one +billion dlrs. + The company said AMR is its first customer for the +767-300ER twinjet, a derivative of its 767-200 designed for +increased passenger and cargo capability on flights of up to +6,600 miles. It said the first delivery is scheduled for +February 1988 and the jet will seat 215 in tri-class +configuration. + Boeing said it now has orders for 47 767-300's. + In New York, <Airbus Industrie> said AMR is also the launch +customer for its A300-600R widebody. + AMR today announced the order of 15 of the Boeing and 25 of +the Airbus twinjets. + Airbus said in AMR's configuration, the A300-600R will seat +16 in first class and 251 in economy. Deliveries will be made +bewtween April 1988 and June 1989. + Airbus did not disclose the value of the order. + Boeing said AMR will operate the 767's on North Atlantic +routes, while Airbus said AMR will operate the A300's on +Caribbean routes. + Reuter + + + + 3-MAR-1987 10:40:22.86 + +usa + + + + + +F +f0577reute +u f BC-INLAND-<IAD>-FILES-FO 03-03 0105 + +INLAND <IAD> FILES FOR 1.5 MLN SHARES OFF + CHICAGO, March 3 - Inland Steel Industries Inc said it +registered with the Securities and Exchange Commission for a +proposed public offering of 1.5 mln shares of Series C +cumulative convertible exchangeable preferred shares, 50 dlrs a +share liquidation value. + Goldman Sachs and Co and First Boston Corp are +underwriters. They have an option to buy 225,000 additional +shares to cover overallotments. + Proceeds are for general corporate purposes, including to +fund a portion of the investment needed for a continuous cold +mill joint venture under discussion with Nippon Steel Corp. + Reuter + + + + 3-MAR-1987 10:40:34.06 + +usa + + + + + +F +f0579reute +r f BC-<ACUSTAR-CORP>-HAS-UN 03-03 0067 + +<ACUSTAR CORP> HAS UNAUTHORIZED ACCOUNT ACTION + BLOOMINGTON, Minn., March 3 - Acustar Corp said it has +discovered significant unauthorized activity in its corporate +accounts but has not yet determined the full extent of the +problem. + It said it has requested that all over-the-counter trading +in its stock be halted until it can make a further +announcement. An investigation is underway, it said. + Reuter + + + + 3-MAR-1987 10:41:05.96 +earn +usa + + + + + +F +f0584reute +r f BC-TOLL-BROTHERS-INC-<TO 03-03 0046 + +TOLL BROTHERS INC <TOL> 1ST QTR JAN 31 NET + HORSHAM, Penn., March 3 - + Shr 22 cts vs 12 cts + Net 3,243,000 vs 1,656,000 + Revs 28.4 mln vs 21.5 mln + NOTE: All amts reflect 3-for-2 stock split of company's +common in form of 50 pct stock dividend paid Feb 26, 1987. + Reuter + + + + 3-MAR-1987 10:41:11.13 + +usa + + + + + +F +f0585reute +d f BC-UNICORP-AMERICAN-<UAC 03-03 0049 + +UNICORP AMERICAN <UAC> IN JOINT VENTURE + NEW YORK, March 3 - Unicorp American Corp said it has +formed a joint venture with Sybedon Corp, a New York real +estate investment banking firm, to pursue real estate projects. + It said a total of 20 mln dlrs is being committed to the +joint venture. + Reuter + + + + 3-MAR-1987 10:41:36.86 +earn +usa + + + + + +F +f0589reute +s f BC-PILLSBURY-CO-<PSY>-VO 03-03 0025 + +PILLSBURY CO <PSY> VOTES QUARTERLY DIVIDEND + MINNEAPOLIS, MINN., March 3 - + Qtly div 25 cts vs 25 cts prior qtr + Pay 31 May + Record 1 May + Reuter + + + + 3-MAR-1987 10:41:41.92 +earn +usa + + + + + +F +f0590reute +s f BC-BERKSHIRE-GAS-CO-<BGA 03-03 0025 + +BERKSHIRE GAS CO <BGAS> PAYS REGULAR QTLRY DIV + PITTSFIELD, Mass., March 3 - + Qtrly div 28.5 cts vs 28.5 cts + Pay April 15 + Record March 31 + Reuter + + + + 3-MAR-1987 10:44:50.56 +grainwheatbarley +ukussr + + + + + +G +f0601reute +d f BC-U.K.-WHEAT-AND-BARLEY 03-03 0096 + +U.K. WHEAT AND BARLEY EXPORTS ADJUSTED UPWARDS + LONDON, March 3 - The U.K. Exported 535,460 tonnes of wheat +and 336,750 tonnes of barley in January, the Home Grown Cereals +Authority (HGCA) said, quoting adjusted Customs and Excise +figures. + Based on the previous January figures issued on February 9, +wheat exports increased by nearly 64,000 tonnes and barley by +about 7,000 tonnes. + The new figures bring cumulative wheat exports for the +period July 1/February 13 to 2.99 mln tonnes, and barley to +2.96 mln compared with 1.25 and 1.89 mln tonnes respectively a +year ago. + January wheat exports comprised 251,000 tonnes to European +Community destinations and 284,000 tonnes to third countries. + The Soviet Union was prominent in third country +destinations, taking 167,700 tonnes while Poland was credited +with 54,500 and South Korea 50,000 tonnes. Italy was the +largest EC recipient with 75,000 tonnes followed by West +Germany with 55,200 and France 52,000 tonnes. + Barley exports for January comprised 103,700 tonnes to the +EC and 233,000 to third countries. The Soviet Union was the +largest single importer with 133,265 tonnes followed by Saudi +Arabia with 53,800 tonnes. + Reuter + + + + 3-MAR-1987 10:46:56.99 +gnp +canada + + + + + +E V RM +f0609reute +b f BC-CANADA-GDP-RISES-3.1 03-03 0085 + +CANADA GDP RISES 3.1 PCT IN 1986 + OTTAWA, March 3 - Canada's real gross domestic product, +seasonally adjusted, rose 1.1 pct in the fourth quarter of +1986, the same as the growth as in the previous quarter, +Statistics Canada said. + That left growth for the full year at 3.1 pct, which is +down from 1985's four pct increase. + The rise was also slightly below the 3.3 pct growth rate +Finance Minister Michael Wilson predicted for 1986 in +February's budget. He also forecast GDP would rise 2.8 pct in +1987. + Statistics Canada said final domestic demand rose 0.6 pct +in the final three months of the year after a 1.0 pct gain in +the third quarter. + Business investment in plant and equipment rose 0.8 pct in +the fourth quarter, partly reversing the cumulative drop of 5.8 +pct in the two previous quarters. + Reuter + + + + 3-MAR-1987 10:47:04.45 +grainwheat +ussrpolandczechoslovakiaromania + + + + + +C G T +f0610reute +u f BC-EAST-EUROPE-WHEAT-WIN 03-03 0099 + +EAST EUROPE WHEAT WINTERKILL POSSIBLE, ACCU SAYS + STATE COLLEGE, Pa., March 3 - Winter wheat crops in the +western Soviet Union, Poland and eastern Czechoslovakia through +northern Romania may suffer some winterkill over the next two +nights, private forecaster Accu-Weather Inc said. + Western USSR winter wheat areas have had only light and +spotty snow and winterkill is possible tonight and tomorrow +night as temperatures drop to minus 10 to 0 degrees F. + Snow cover is scant in Poland, with only about 50 pct of +the winter wheat areas reporting one to two inches of snow as +of this morning. + The remaining 50 pct of winter wheat crops do not have snow +cover, making winterkill possible on each of the next two +nights. Lowest temperatures will be minus 10 to 0 degrees F. + Winter wheat areas from eastern Czechoslovakia through +northern Romania had light snow flurries yesterday and last +night, but amounts were an inch or less. With temperatures +expected to fall to near 0 degrees F over the next two nights, +some light winterkill is possible, Accu-Weather added. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-002.sgm b/src/test/data/reuters-21578/reut2-002.sgm new file mode 100644 index 00000000000..3f9be0040c2 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-002.sgm @@ -0,0 +1,2013 @@ + + + 5-MAR-1987 09:07:54.17 +earn +uk + + + + + +F +f0986reute +d f BC-JAGUAR-SEES-STRONG-GR 03-05 0115 + +JAGUAR SEES STRONG GROWTH IN NEW MODEL SALES + LONDON, March 5 - Jaguar Plc <JAGR.L> is about to sell its +new XJ-6 model on the U.S. And Japanese markets and expects a +strong reception based on its success in the U.K., Chairman Sir +John Egan told a news conference. + Commenting on an 11 pct growth in 1986 group turnover to +830.4 mln stg and pre-tax profits at 120.8 mln stg, slightly +below 1985's 121.3 mln, Egan said Jaguar aimed at an average +profit growth of 15 pct per year. However, the introduction of +the new model had kept this year's pre-tax profit down. + Jaguar starts selling XJ-6 in the U.S. In May and plans to +sell 25,000 of its total 47,000 production there in 1987. + U.S. Sales now account for 65 pct of total turnover, +finance director John Edwards said. + A U.S. Price for the car has not been set yet, but Edwards +said the relatively high car prices in dollars of West German +competitors offered an "umbrella" for Jaguar. He added the XJ-6 +had also to compete with U.S. Luxury car producers which would +restrict the car's price. + Jaguar hedges a majority of its dollar receipts on a +12-month rolling basis and plans to do so for a larger part of +its receipts for longer periods, John Egan said. + In the longer term, capital expenditure will amount to 10 +pct of net sales. Research and development will cost four pct +of net sales and training two pct. + Jaguar builds half of its cars and buys components for the +other half. The firm is in early stages of considering the +building of an own press shop in Britain for about 80 mln stg, +but Egan said this would take at least another three years + On the London Stock Exchange, Jaguar's shares were last +quoted at 591p, down from 611p at yesterday's close, after +reporting 1986 results which were in line with market +expectations, dealers said. + REUTER... + + + + 5-MAR-1987 09:18:26.80 + + + + + + + +F +f0011reute +f f BC-******occidental-petr 03-05 0012 + +******OCCIDENTAL PETROLEUM COMMON STOCK OFFERING RAISED TO 36 MLN SHARES +Blah blah blah. + + + + + + 5-MAR-1987 09:19:43.22 +grainwheat +usairaq + + + + + +C G +f0012reute +u f BC-/CCC-ACCEPTS-BONUS-BI 03-05 0117 + +CCC ACCEPTS BONUS BID ON WHEAT FLOUR TO IRAQ + WASHINGTON, March 5 - The Commodity Credit Corporation, +CCC, has accepted bids for export bonuses to cover sales of +25,000 tonnes of wheat flour to Iraq, the U.S. Agriculture +Department said. + The department said the bonuses awarded averaged 116.84 +dlrs per tonne. + The shipment periods are March 15-April 20 (12,500 tonnes) +and April 1-May 5 (12,500 tonnes). + The bonus awards were made to Peavey Company and will be +paid in the form of commodities from CCC stocks, it said. + An additional 175,000 tonnes of wheat flour are still +available to Iraq under the Export Enhancement Program +initative announced January 7, 1987, the department said. + Reuter + + + + 5-MAR-1987 09:21:58.67 +crude + + + + + + +Y +f0017reute +f f BC-******DIAMOND-SHAMROC 03-05 0016 + +******DIAMOND SHAMROCK RAISES CRUDE POSTED PRICES ONE DLR, EFFECTIVE MARCH 4, WTI NOW 17.00 DLRS/BBL +Blah blah blah. + + + + + + 5-MAR-1987 09:22:57.75 +earn +usa + + + + + +F +f0019reute +r f BC-NORD-RESOURCES-CORP-< 03-05 0063 + +NORD RESOURCES CORP <NRD> 4TH QTR NET + DAYTON, Ohio, March 5 - + Shr 19 cts vs 13 cts + Net 2,656,000 vs 1,712,000 + Revs 15.4 mln vs 9,443,000 + Avg shrs 14.1 mln vs 12.6 mln + Year + Shr 98 cts vs 77 cts + Net 13.8 mln vs 8,928,000 + Revs 58.8 mln vs 48.5 mln + Avg shrs 14.0 mln vs 11.6 mln + NOTE: Shr figures adjusted for 3-for-2 split paid Feb 6, +1987. + Reuter + + + + 5-MAR-1987 09:23:44.74 +copper +chile + + + + + +C M +f0022reute +b f BC-NO-QUAKE-DAMAGE-AT-CH 03-05 0089 + +NO QUAKE DAMAGE AT CHUQUICAMATA - MINE SPOKESMAN + SANTIAGO, March 5 - The earthquake which hit northern Chile +today, registering 7.0 on the open-ended Richter scale, caused +no damage to the copper mine at Chuquicamata, a mine spokesman +said. + Chuquicamata public relations director Guillermo Barcelo +told Reuters by telephone from the mine that the quake had +caused no problems and operations continued as usual. + A spokesman for the state Chilean Copper Commission in +Santiago confirmed there had been no damage at Chuquicamata. + Reuter + + + + 5-MAR-1987 09:24:40.64 +crudenat-gas +canada + + + + + +E F Y +f0025reute +r f BC-orbit-oil-increases 03-05 0094 + +ORBIT INCREASES OIL AND GAS RESERVE VALUES + CALGARY, Alberta, March 5 - <Orbit Oil and Gas Ltd> said +the value of its oil and gas reserves increased by 19 pct to +52.6 mln dlrs from 44.2 mln dlrs reported at year-end 1985, +according to an independent appraisal. + Orbit said it has reserves of 2.4 mln barrels of oil and +natural gas liquids and 67.2 billion cubic feet of natural gas. + In addition, 75 pct owned <Sienna Resources Ltd> has +Canadian reserves of 173,000 barrels of oil and 1.6 bcf of +natural gas with a current value of 2.2 mln dlrs, Orbit said. + Reuter + + + + 5-MAR-1987 09:24:55.56 +grainwheat +usaegypt + + + + + +C G +f0026reute +u f BC-CCC-ACCEPTS-BONUS-BID 03-05 0105 + +CCC ACCEPTS BONUS BID ON SEMOLINA TO EGYPT + WASHINGTON, March 5 - The Commodity Credit Corporation, +CCC, has accepted a bid for an export bonus to cover a sale of +2,000 tonnes of semolina to Egypt, the U.S. Agriculture +Department said. + The department said the bonus was 233.91 dlrs per tonne and +was made to International Multifoods Corp. The bonus will be +paid in the form of commodities from CCC stocks. + The semolina is for shipment during June 1987, it said. + An additional 13,000 tonnes of semolina are still available +to Egypt under the Export Enhancement Program initiative +announced on August 6, 1986, it said. + Reuter + + + + 5-MAR-1987 09:26:07.38 + +france +balladur + + + + +F +f0032reute +d f BC-FRENCH-CGE-GROUP-LIKE 03-05 0099 + +FRENCH CGE GROUP LIKELY TO BE PRIVATISED IN MAY + PARIS, March 5 - France's state-owned Cie Generale +d'Electricite (CGE) is likely to be privatised during May this +year, sources close to Finance Minister Edouard Balladur said. + Although the Finance Ministry simply said that the group +would be privatised during the course of this year, when it +first announced the operation in early January, the May date is +earlier than the market had expected. + As a result it will follow close on the heels of the +privatisation of the TF1 television channel and the advertising +group <Agence Havas>. + Last month the government privatised the first of the state +financial groups, Cie Financiere de Paribas <PARI.P>, in a +floatation which was 40 times oversubscribed. + And in December the first of the industrial groups, glass +maker Cie de Saint-Gobain <SGEP.P>, returned to the private +sector. + CGE has interests ranging from telecommunications to +shipbuilding and nuclear engineering, and recently struck a +deal with ITT Corp <ITT.N> to create the world's second largest +telecommunications group under the Alcatel name. + REUTER + + + + 5-MAR-1987 09:26:17.58 +acq +franceusawest-germanynetherlandssweden + + + + + +F +f0033reute +d f BC-FIVE-GROUPS-APPLY-TO 03-05 0118 + +FIVE GROUPS APPLY TO BUY FRENCH TELEPHONE GROUP + PARIS, March 5 - Five consortia have applied to buy the +French state-owned telephone equipment manufacturer <Cie +Generale de Constructions Telephoniques (CGCT)>, which will +give the owners control of 16 pct of the French telephone +switching market, sources close to Finance Minister Edouard +Balladur said. + The French government has given itself until the end of +April to decide which applicant will be accepted, they added. + While several foreign groups have said they want to gain a +foothold in the French market, their potential stake in CGCT is +limited to 20 pct under privatisation laws passed last year, +with 80 pct to be left in French hands. + The Finance Ministry sources gave no details of the groups +interested in CGCT, but several have publicly announced their +candidacies. + U.S. Telecommunications giant American Telephone and +Telegraph Co <T.N> which has been at the centre of the two-year +battle for CGCT, has teamed up with the Dutch-based <Philips +Telecommunications Industrie B.V.>, a subsidiary of NV Philips +Gloeilampenfabriek <PGLO.AS> and <Societe Anonyme de +Telecommunications> (SAT) to present a joint bid, in +association with holding company Cie du Midi SA <MCDP.P> and +five French investment funds. + A second bid has come from the West German electronics +group Siemens AG <SIEG.F>, which hopes to take a 20 pct stake +in CGCT, with the French telecommunications <Jeumont-Schneider> +taking the remaining 80 pct. + Sweden's <AB LM Ericsson> has also submitted a bid for the +maximum 20 pct permitted, in association with French defence +electronics group <Matra>, which would hold between 40 and 49 +pct, and construction group <Bouygues>. + Matra has already acquired CGCT's private telephone +business. +REUTER... + + + + 5-MAR-1987 09:27:39.53 + +usa + + + + + +V RM +f0039reute +b f BC-/SPEAKER-SEEKING-SUPP 03-05 0112 + +SPEAKER SEEKING SUPPORT FOR U.S. TAX INCREASES + WASHINGTON, March 5 - House Speaker Jim Wright is lobbying +congressmen to support a plan to cut the 1988 budget deficit +about 40 billion dlrs, half through spending cuts and the +remainder through tax hikes, congressional sources said. + He is backing a half and half plan and has made the +suggestion to Democrats on the House Budget Committee +privately, committee sources said. + However, a committee source told Reuters that committee +Democrats already generally favor a plan to cut the deficit +about 40 billion dlrs, half through taxes and the Speaker's +move was seen as building support outside the committee. + Wright's 20 billion dlr revenue raising plan has no +specifics, although he has floated a stock transfer tax and +also has suggested deferring tax cuts due to the wealthy. + Neither of those plans has caught fire yet in Congress, and +some congressmen are cool to the idea of a stock tax. + The Budget committee is considering a 1988 budget aimed at +reducing the estimated deficit of 170 billion dlrs as estimated +by the nonpartisan Congressional Budget Office. + Committee Chairman William Gray has publicly backed a +budget cutting move of 40 billion dlrs but says that will not +reach the Gramm-Rudman deficit target for 1988 of 108 billion +dlrs, although he claims it will be in the spirit of it. + Reuter + + + + 5-MAR-1987 09:31:01.67 +ship +turkey + + + + + +C G T M +f0051reute +u f BC-BLIZZARD-CLOSES-BOSPH 03-05 0099 + +BLIZZARD CLOSES BOSPHORUS + ISTANBUL, March 5 - Blizzard conditions halted shipping +through the Bosphorus waterway and piled snow up to 70 cms deep +in central Istanbul, paralysing the city for the second day +running. + Snow whipped by 48 kph winds continued to fall on Istanbul +and northwest Anatolia after 36 hours and weather reports +predicted no relief for another two days. + Port officials said at least six large vessels in the Black +Sea and 13 in the Sea of Marmara were waiting for conditions to +improve. + Istanbul's Ataturk international airport has been closed +since yesterday. + Reuter + + + + 5-MAR-1987 09:33:06.03 +acq +usa + + + + + +F +f0060reute +u f BC-JAPAN-FUND-<JPN>-SEEK 03-05 0100 + +JAPAN FUND <JPN> SEEKERS CONFIDENT OF FINANCING + NEW YORK, March 5 - The <Sterling Grace Capital Management +L.P.> group said it is confident financing can be arranged if +The Japan Fund's board recommend's the group's acquisition +proposal. + The group, which also includes <Anglo American Security +Fund L.P.> and T.B. Pickens III, Tuesday proposed an entity it +controls acquire for cash all the assets of Japan Fund for 95 +pct of the fund's aggregate net asset value. + The group said it has had a number of meetings over the +past few days with domestic and overseas financial institutions. + The Sterling Grace Capital group said certain of these +institutions have expressed serious interest in providing +financing for the proposed acquisition of Japan Fund, "adding +we are reasonably confident that the financing can be quickly +arranged if the Japan Fund's board of directors is willing to +recommend the transaction to shareholders." + Reuter + + + + 5-MAR-1987 09:33:18.80 + + + + + + + +F +f0061reute +f f BC-******K-MART-CORP-FEB 03-05 0011 + +******K MART CORP FEBRUARY SALES UP 13.1 PCT ON COMPARABLE STORE BASIS +Blah blah blah. + + + + + + 5-MAR-1987 09:34:02.54 + +tanzaniacanadabelgiumwest-germanyukswedenitalydenmarkzambiasouth-africa + +worldbankadb-africaec + + + +G T M +f0066reute +r f BC-TANZANIAN-RAILWAYS-SE 03-05 0113 + +TANZANIAN RAILWAYS SECURE 25.6 MLN DLRS AID + DAR ES SALAAM, March 5 - State-run Tanzania Railway +Corporation (TRC) has secured 25.6 mln dlrs aid from banks and +European countries for a one-year emergency repair program, +Transport Minister Mustafa Nyang'anyi said. + Nyang'anyi told Reuters on his return from a World Bank +sponsored donors' conference in New York that the aid would +enable TRC to buy spares for 32 locomotives, overhaul 800 +wagons and replace 67,000 sleepers over the next 12 months. + The World Bank, African Development Bank, European +Community, Canada, Belgium, West Germany, Britain, Sweden, +Italy and Denmark had contributed to the package, he said. + TRC runs a rail network linking Dar es Salaam and the +northern port of Tanga with the coffee-growing area around +Mount Kilimanjaro and ports on Lake Victoria and Lake +Tanganyika. + It is under separate administration from the +Tanzania-Zambia railway linking Dar es Salaam with the Zambian +copperbelt and the railway system of southern Africa, which has +already received substantial aid as part of international +efforts to ease the dependence of landlocked African states on +trade routes through South Africa. + But this is the first international aid package for TRC, +which also carries cargo for Uganda, Zaire and Burundi. + Reuter + + + + 5-MAR-1987 09:34:13.71 +earn +canada + + + + + +E F +f0068reute +r f BC-pegasus-gold-inc 03-05 0053 + +PEGASUS GOLD INC <PGULF> 3RD QTR DEC 31 NET + VANCOUVER, British Columbia, March 5 - + Shr profit 20 cts vs loss two cts + Net profit 2,665,000 vs loss 202,000 + Revs 12,141,000 vs 5,993,000 + Nine mths + Shr profit 35 cts vs loss 11 cts + Net profit 4,653,000 vs loss 1,167,000 + Revs 35.1 mln vs 18.0 mln + Reuter + + + + 5-MAR-1987 09:34:57.56 + +usa + + + + + +F +f0072reute +u f BC-STOP-AND-SHOP'S-<SHP> 03-05 0083 + +STOP AND SHOP'S <SHP> BRADLEES FEBRUARY SALES UP + BOSTON, March 5 - Stop and Shop Cos Inc said sales for the +four weeks ended February 28 for its Bradlees Discount +Department Stores Division were up six pct to 104 mln dlrs from +98 mln dlrs a year before, with same-store sales up three pct. + The company said the modest comparable store sales increase +was due to a combination of difficult weather conditions in the +Northeast, a later Easter this year and a possible slowing in +consumer demand. + Reuter + + + + 5-MAR-1987 09:35:22.89 + +usa + + + + + +M +f0075reute +d f BC-GM-(GM)-LAYING-OFF-5, 03-05 0083 + +GM LAYING OFF 5,500 AT TWO MICHIGAN PLANTS + DETROIT, March 5 - General Motors Corp said it ordered +temporary layoffs of 5,500 hourly workers to cut production and +thereby reduce inventories of cars built at two plants later +this month. + A spokesman said 2,000 workers would be laid off one week +beginning March 9 at GM's Detroit-Hamtramck luxury car plant. + Another 3,500 will be laid off a week effective March 23 at +GM's Lansing, Mich, plant which builds the company's "N-body" +compact cars. + Reuter + + + + 5-MAR-1987 09:36:37.16 + +usa + + + + + +F +f0079reute +r f BC-MITSUBISHI-MOTOR/AMER 03-05 0103 + +MITSUBISHI MOTOR/AMERICA FEBRUARY SALES RISE + FOUNTAIN VALLEY, Calif., March 5 - Mitsubishi Motor Sales +of America Inc said sales of all vehicles rose 43.7 pct in +February to 9,735 units from 6,776 in February 1986. + Sales of passenger cars and wagons grew 11.7 pct to 5,314 +from 4,758 and truck and van sales more than doubled to 4,421 +from 2,018, the affiliate of Mitsubishi Motors Corp said. + Year-to-date total vehicle sales increased 16.5 pct to +14,966 from 12,842. + Car and wagon sales in the two months fell 13.7 pct to +7,640 from 8,848 but sales of trucks and vans grew 83.4 pct to +7,326 from 3,994. + Reuter + + + + 5-MAR-1987 09:38:14.93 +earn +canada + + + + + +E F +f0085reute +d f BC-keltic-inc 03-05 0036 + +<KELTIC INC> YEAR NET + TORONTO, March 5 - + Shr 99 cts vs 1.25 dlrs + Net 418,733 vs 235,572 + Revs 2,777,425 vs 2,024,116 + Note: 1986 shr after November, 1986 600,000 class A +subordinate floating share issue + Reuter + + + + 5-MAR-1987 09:39:13.96 + +usa + + + + + +F +f0086reute +u f BC-SUPERMARKETS-GENERAL 03-05 0043 + +SUPERMARKETS GENERAL <SGC> FEBRUARY SALES RISE + WOODBRIDGE, N.J. - Supermarkets General Corp reported sales +of 424.8 mln dlrs for the four-week period ended Feb 28, 1987, +A 7.2 pct increase over sales of 396.4 mln dlrs for the +comparable period last year. + Reuter + + + + 5-MAR-1987 09:40:41.79 +money-fxinterest +uk + + + + + +RM +f0087reute +b f BC-U.K.-MONEY-MARKET-GIV 03-05 0095 + +U.K. MONEY MARKET GIVEN HELP, OFFERED FACILITIES + LONDON, March 5 - The Bank of England said it had given the +money market 206 mln stg of assistance this afternoon and +offered the discount houses borrowing facilities to take out +the rest of the 1.10 billion stg shortage, revised down from an +initial 1.15 billion estimate. + It made no alteration to its established dealing rates, +buying 95 mln stg of band one bank bills at 10-7/8 pct and 111 +mln of band two bank bills at 10-13/16 pct. This brings the +Bank's total assistance so far today to 243 mln stg. + REUTER + + + + 5-MAR-1987 09:40:53.56 + +usa + + + + + +F +f0088reute +u f BC-SUPERMARKETS-GENERAL 03-05 0044 + +SUPERMARKETS GENERAL <SGC> FEBRUARY SALES RISE + WOODBRIDGE, N.J., March 5 - Supermarkets General Corp +reported sales of 424.8 mln dlrs for the four-week period ended +Feb 28, 1987, A 7.2 pct increase over sales of 396.4 mln dlrs +for the comparable period last year. + Reuter + + + + 5-MAR-1987 09:41:51.56 +acq +usa + + + + + +F +f0096reute +r f BC-E.F.-HUTTON-<EFH>-STA 03-05 0093 + +E.F. HUTTON <EFH> STARTS PUROLATOR <PCC> BID + NEW YORK, March 5 - E.F. Hutton Group Inc said it has +started its previously announced offer to purchase up to +6,332,471 common shares of Purolator Courier Corp at 35 dlrs +each. + In a newspaper advertisement, the company said the offer, +proration period and withdrfawal rights will expire April One +unless extended. The offer is conditioned on receipt of at +least 5,116,892 Purolator shares, or a 66.7 pct interest, and +is the first step in a merger agreement that has been approved +by the Purolator board. + Hutton said it reserves the right to buy more than +6,332,471 shares but has no present intention of doing so. It +said it may waive the condition that at least 5,116,892 shares +be tendered as long as it received at least a 50.1 pct +interest. If it were to receive fewer shares than that, it +said it would only purchase sharesd with the consent of +Purolator. + Reuter + + + + 5-MAR-1987 09:42:45.36 +money-fx +usataiwansouth-korea +yeutter + + + + +RM A +f0100reute +r f BC-YEUTTER-PUTS-CURRENCY 03-05 0101 + +YEUTTER PUTS CURRENCY BURDEN ON TAIWAN, KOREA + NEW YORK , March 5 - Responsibility for the appreciation of +the Taiwan dollar and the South Korean Won lies soley with +those countries, said U.S. trade representative Clayton Yeutter + Speaking to the Asia Society, Yeutter said that it is in +those countries' own long-term interest to raise the value of +their currencies against the dollar. + Yeutter was responding to a question about what the U.S. +could do to encourage appreciation of those currencies against +the dollar in order to reduce the large U.S. trade deficits +with Taiwain and Korea. + "An undervalued currency will help those countries' exports +in the short term, but in the long run they have to be +concerned about how they are perceived in the international +business community," Yeutter said. + For Taiwan, Yeutter said that with its per capita trade +surplus with the U.S., much larger than that of Japan's, and +with huge foreign exchange reserves, it was difficult to defend +the high import tarrifs and other barriers that prevail in that +country. + He also said that the south Korean Won should begin to move +to reflect underlying economic fundamentals, "otherwise in two +or three years' time, Korea will be in the same situation that +prevails in Taiwan." + Turning to the U.S. deficit with Japan of more than 50 +billion dlrs, Yeutter said that this situation was not +sustainable. + "Something must give soon. If not, there is a great threat +of U.S. legislative action to counteract that trend," Yeutter +said. + Reuter + + + + 5-MAR-1987 09:42:52.28 +earn +usa + + + + + +F +f0101reute +r f BC-PRINCEVILLE-DEVELOPME 03-05 0069 + +PRINCEVILLE DEVELOPMENT CORP <PVDC> YEAR LOSS + PRINCEVILLE, Hawaii, March 5 - + Shr diluted loss 31 cts vs profit 17 cts + Net loss 2,806,005 vs profit 1,513,395 + Revs 15.0 mln vs 10.4 mln + Avg shrs diluted 8,982,754 vs 8,804,899 + NOTE: Current year includes loss of 3.4 mln dlrs from +takeover defense expenses. Also includes losses of 1.8 mln dlrs +vs 332,000 dlrs from equity in limited partnerships. + Reuter + + + + 5-MAR-1987 09:44:47.86 +acq +usa + + + + + +F +f0112reute +r f BC-ORANGE-CO-<OJ>-HOLDER 03-05 0035 + +ORANGE-CO <OJ> HOLDER RAISES STAKE + LAKE HAMILTON, Fla., March 5 - Orange-Co Inc said its +largest shareholder, <Summit Resoureces Inc>, has increased its +stake to 15 pct from 14 pct and now owns 644,727 shares. + Reuter + + + + 5-MAR-1987 09:44:55.17 +earn +usa + + + + + +F +f0113reute +r f BC-HORIZON-CORP-<HZN>-4T 03-05 0075 + +HORIZON CORP <HZN> 4TH QTR NET + FOUNTAIN HILLS, Ariz., March 5 - + Oper shr profit 1.66 dlrs vs loss eight cts + Oper net profit 12.0 mln vs loss 572,000 + Revs 27.4 mln vs 4,311,000 + Year + Oper shr profit 1.36 dlrs vs loss 43 cts + Oper net profit 9,817,000 vs loss 2,433,000 + Revs 35.0 mln vs 13.8 mln + Avg shrs 7,224,000 vs 6,731,000 + NOTE: 1985 net includes tax credits of 492,000 dlrs in +quarter and 2,433,000 dlrs in year. + 1985 net both periods excludes 168,000 dlr loss from +discontinued operations. + 1986 net both periods includes pretax gain 21.8 mln dlrs +from sale of remaining interest in Paradise Hills, N.M., +development. + Reuter + + + + 5-MAR-1987 09:45:10.22 +earn +canada + + + + + +E F +f0115reute +r f BC-thomson 03-05 0046 + +<INTERNATIONAL THOMSON ORGANISATION LTD> YEAR + TORONTO, Mar 5 - + Shr 33p vs 38p + Net 97 mln vs 111 mln + Revs 1.71 billion vs 1.76 billion + NOTE: Figures in sterling. + Share results after deducting preferred share dividends of +one mln pounds sterling in 1986. + Reuter + + + + 5-MAR-1987 09:45:49.05 + +france + +ec + + + +C G +f0118reute +u f BC-FRENCH-FARMERS-STRONG 03-05 0108 + +FRENCH FARMERS STRONGLY CRITICISE EC MILK PACT + PARIS, March 5 - The EC agriculture ministers' agreement on +reducing dairy output puts milk producers in an impossible +situation, French farm unions said. + The accord to limit butter sales into intervention, part of +planned dairy output cuts of 9-1/2 pct over two years, will cut +milk producers' income, a spokeswoman for France's largest farm +union, the FNSEA, said. + The move has destroyed part of the Common Agricultural +Policy, French milk producers said in a press release. + But Agriculture Minister Francois Guillaume said +repercussions of the plan will affect dairies, not farmers. + "If there are negative repercussions, it will be at the +level of the dairies which have never looked for new outlets +for butter and milk," he told journalists during a visit to +Rouen. + FNSEA president Raymond Lacombe said on French radio the +milk sector needs restructuring by encouraging early retirement +and helping young farmers to start. But Commission proposals, +rejected by ministers, would have frozen land prices, he said. + The FNSEA says it will demonstrate over Commission +proposals to freeze most 1987/88 farm prices and cut supports. +Pig farmers have held violent demonstrations over falling pork +prices and milk producers blocked roads in protest at cuts in +milk output. + Reuter + + + + 5-MAR-1987 09:52:38.52 + +uk + + + + + +RM +f0137reute +b f BC-IBJ-ESTABLISHES-200-M 03-05 0074 + +IBJ ESTABLISHES 200 MLN STG CD PROGRAMME + LONDON, March 5 - The Industrial Bank of Japan Ltd (IBJ), +London Branch, said it is establishing a sterling certificate +of deposit (CD) issuance programme for up to 200 mln stg. + The arranger is LLoyds Merchant Bank Ltd and dealers are +LLoyds, Samuel Montagu and Co Ltd, Morgan Grenfell and Co Ltd +and S.G. Warburg and Co Ltd. + The paper will have maturities between seven and 365 days. + REUTER + + + + 5-MAR-1987 09:53:39.85 + + + + + + + +F +f0139reute +f f BC-******MOBIL'S-MONTGOM 03-05 0015 + +******MOBIL'S MONTGOMERY WARD AND CO FEBRUARY SALES UP 12.7 PCT ON COMPARABLE STORE BASIS +Blah blah blah. + + + + + + 5-MAR-1987 09:54:03.66 +earn +usa + + + + + +F +f0140reute +r f BC-EQUATORIAL-COMMUNICAT 03-05 0058 + +EQUATORIAL COMMUNICATIONS CO <EQUA> 4TH QTR LOSS + MOUNTAIN VIEW, Calif., March 4 - + Shr loss 3.84 dlrs vs nil + Net loss 56,879,000 vs profit 23,000 + Rev 10.3 mln vs 17.7 mln + Year + Shr loss 4.60 dlrs vs profit 14 cts + Net loss 67,818,000 vs profit 1,807,000 + Rev 50.9 mln vs 56.1 mln + Avg shares 14,734,000 vs 12,801,000 + NOTE: Fourth qtr net includes a one-time restructuring +charge of 45.2 mln dlrs. 1985 net income includes extraordinary +gain of 3.2 mln dlrs, or 25 cts. + Reuter + + + + 5-MAR-1987 09:55:41.23 + +iraniraq + + + + + +RM +f0142reute +u f BC-IRAQ-SAYS-IT-CRUSHES 03-05 0121 + +IRAQ SAYS IT CRUSHES NEW IRANIAN BASRA OFFENSIVE + BAGHDAD, March 5 - Iraq said its forces killed or wounded +15,000 Iranian Revolutionary Guards as they crushed a new +Iranian offensive near the strategic port city of Basra. + A high command war communique said four Revolutionary +Guards divisions attacked Iraqi positions east of Basra on the +Gulf War southern front, but they were fully crushed by noon +(0900 GMT). + Adbul-Jabbar Mohsen, chief of the defence ministry +political department, said the Iranians had 15,000 casualties. + Iran earlier today said its forces launched fresh attacks +near Basra last night, adding that 1,200 Iraqis were killed or +wounded in fighting near Fish Lake, 10 km east of Basra. + In its first reaction to Tehran reports of a new Iranian +offensive on the northern front, Iraq said fighting continues +around the strategic mountain peak of Kardamanend, overlooking +the Haj Omran-Rawandiz axis close to the Iranian border. + A military spokesman said Iran launched its attack in the +north "to (turn) Iraqi attention towards that area and relax +pressure in the south." + He added, "Iraq knows well that Iran's main goal is to +occupy Basra in the south and that was the reason why Iraq has +repelled their new offensive so decisively and firmly." + Iran reported heavy fighting on both fronts today. + REUTER + + + + 5-MAR-1987 09:55:46.08 +earn + + + + + + +E F +f0143reute +b f BC-thomson 03-05 0010 + +******INTERNATIONAL THOMSON ORGANISATION LTD YEAR SHR 33P VS 38P +Blah blah blah. + + + + + + 5-MAR-1987 09:56:03.54 + +usa + + + + + +F +f0144reute +b f BC-ENZON-<ENZN>-SAYS-DRU 03-05 0063 + +ENZON <ENZN> SAYS DRUG TREATS DISEASE + SOUTH PLAINFIELD, N.J., March 5 - Enzon Inc said a new +treatment using its investigational new drug PEG-ADA has +restored the functioning of the immune system in the first two +children that were born deficient in the enzyme adenosine +deaminase. + The disorder is known as severe combined immunodeficiency +disease, or "bubble boy disease" + Bubble Boy Disease is a rare but severe disease that +hampers the development of the immune system. It has killed +most of its victims before adulthood. + Children with the disease are consigned to live in a +sterile environment, such as a plastic bubble, to avoid +infection, the company said. + The study of Enzon's drug, conducted at Duke University, +showed that two children suffering from the disease were +treated for 11 and seven months, respectively, and were free of +serious infection during that time, the company said. The +results were published in the New England Journal of Medicine. + The disease is caused by a missing enzyme, called Adenosine +Deaminase, or ADA, that is crucial to the development of the +immune system. + Enzon said it has developed a technology to coat the enzyme +with a substance called polyethylene glycol, or PEG, serving to +disguise the enzyme when it is reintroduced into the body, +preventing rejection. + "Marked improvement in laboratory tests of immune function +occurred in each child, along with an increase in the number of +T-lymphocytes, the immune cells that were missing before +treatment with PEG-ADA had begun," the study said. + "The children are now more active and have begun to gain +weight and height. Before treatment their growth had been very +poor in comparison to normal children of the same age," the +study, conducted by Doctors Michael Hershfield and Rebecca +Buckley, said. + The PEG-ADA injections were given once a week. Victims of +the disease have traditionally been treated by bone marrow +transplants, but for most, donors are not available or +transplantation is unsuccessful, the company said. Other +diseases caused by a missing enzyme might also be treated by +introducing a PEG coated enzyme, the article noted. + Reuter + + + + 5-MAR-1987 09:57:00.61 + + + + + + + +F +f0149reute +f f BC-******MCI-COMMUNICATI 03-05 0011 + +******MCI COMMUNICATIONS CALLS FOR IMMEDIATE DEREGULATION OF ATT +Blah blah blah. + + + + + + 5-MAR-1987 09:58:35.61 + + + + + + + +F +f0154reute +b f BC-******F.W.-WOOLWORTH 03-05 0009 + +*****F.W. WOOLWORTH CO FEBRUARY SALES INCREASE 11.3 PCT +Blah blah blah. + + + + + + 5-MAR-1987 09:59:40.82 +acq +usa + + + + + +F +f0160reute +r f BC-TRIMEDYNE-<TMED>-TO-S 03-05 0066 + +TRIMEDYNE <TMED> TO SPIN OFF STAKE IN UNIT + SANTA ANA, Calif., March 5 - Trimedyne Inc said it will +distribute one Class B common share of <Automedix Sciences Inc> +for each four Trimedyne shares held of record on March Nine. + The company said in the spinoff it is distributing its +entire 44 pct interesdt in Automedix. The spun-off stock will +not be saleable for 13 months, the company said. + Reuter + + + + 5-MAR-1987 10:00:29.72 + +usa + + + + + +F +f0163reute +b f BC-K-MART-<KM>-FEBRUARY 03-05 0088 + +K MART <KM> FEBRUARY SALES UP 8.2 PCT + TROY, Mich., March 5 - K Mart Corp said February sales +rose 13.1 pct from a year ago and comparable store sales in the +four-week period ended February 25 rose 8.2 pct. + K Mart said consolidated sales in the period were 1.46 +billion dlrs compared with 1.29 billion last year. It said the +year-ago figures excluded sales for discontinued operations. + K Mart cited "favorable consumer response to our +merchandise programs" and said its specialty retailers had +"excellent February sales." + Reuter + + + + 5-MAR-1987 10:00:45.71 + + + + + + + +F +f0165reute +b f BC-*****HECK'S-INC-TO-RE 03-05 0006 + +*****HECK'S INC TO RELEASE NEWS SHORTLY . +Blah blah blah. + + + + + + 5-MAR-1987 10:01:44.44 +earn +usa + + + + + +F +f0171reute +r f BC-CASEY'S-GENERAL-STORE 03-05 0045 + +CASEY'S GENERAL STORES INC <CASY> 3RD QTR JAN 31 + DES MOINES, Iowa, March 5 - + Shr 16 cts vs 13 cts + Net 1,900,000 vs 1,600,000 + Sales 68.2 mln vs 69.6 mln + Nine mths + Shr 60 cts vs 43 cts + Net 7,100,000 vs 4,700,000 + Sales 214.0 mln vs 219.5 mln + Reuter + + + + 5-MAR-1987 10:02:32.72 + + + + + + + +F +f0176reute +f f BC-******J.C.-PENNEY-FEB 03-05 0010 + +******J.C. PENNEY FEBRUARY STORE AND CATALOG SALES UP 5.3 PCT +Blah blah blah. + + + + + + 5-MAR-1987 10:02:53.85 +grainwheatbarleycorn +france + +ec + + + +C G +f0179reute +u f BC-FRENCH-FREE-MARKET-CE 03-05 0092 + +FRENCH FREE MARKET CEREAL EXPORT BIDS DETAILED + PARIS, March 5 - French operators have requested licences +to export 40,000 tonnes of free market feed wheat, 32,500 +tonnes of soft bread wheat, 375,000 tonnes of barley and +465,000 tonnes of maize at today's European Community tender, +trade sources here said. + Rebates requested ranged between 134 and 136.50 European +currency units (Ecus) a tonne for the feed wheat, 137.39 and +141.50 Ecus a tonne for the bread wheat, 137.93 and 142.95 Ecus +for the barley and 133.75 and 140.25 Ecus for the maize. + Reuter + + + + 5-MAR-1987 10:03:24.09 + +usa + + + + + +F Y +f0183reute +b f BC-OCCIDENTAL-<OXY>-OFFE 03-05 0099 + +OCCIDENTAL <OXY> OFFERS OVER 37 MLN SHARES + NEW YORK, March 5 - Occidental Petroleum Corp said its +common stock offering has been further increased to a total of +37,950,000 shares. + The company explained that underwriters exercised in full +their option to increase tohe offering by buying an additional +4,950,000 shares over and above the 33 mln brought to market +yesterday. Originally, Occidental had planned to offer 30 mln +shares. It had 165 mln outstanding prior to the offering. + The underwriters are Drexel Burnham Lambert Inc, Kidder +Peabody and Co Inc and Salomon Brothers Inc. + At the public offering price of 30.50 dlrs a share, +Occidental said, the total value of the offering was nearly +1.16 billion dlrs, making it the largest underwritten common +equity offering by a U.S. natural resource company. + The company said the significant financial improvements +from applying the net proceeds of the offering, principally to +the reduction of debt, along with its 1986 restructuring of oil +and gas operations and the acquisition of Midcon Corp have +positioned Occidental to benefit from an improving oil and gas +industry environment. + Reuter + + + + 5-MAR-1987 10:03:43.41 +crude +usa + + + + + +F Y +f0186reute +u f BC-DIAMOND-SHAMROCK-<DIA 03-05 0073 + +DIAMOND SHAMROCK <DIA> RAISES CRUDE OIL POSTINGS + NEW YORK, MAR 5 - Diamond Shamrock said it raised its +posted prices for all grades of crude oil one dlr a barrel, +effective yesterday. + The one dlr increase brings West Texas Intermediate, WTI +the U.S. benchmark crude, to 17.00 dlrs a bbl, the company +said. + Diamond Shamrock joined Sun Co, Coastal, Citgo and Murphy +Oil in raising crude oil posted prices one dlr a barrel +yesterday. + Reuter + + + + 5-MAR-1987 10:04:23.59 +earn +usa + + + + + +F +f0190reute +r f BC-OAK-HILL-SPORTSWEAR-C 03-05 0047 + +OAK HILL SPORTSWEAR CORP <OHSC> 4TH QTR NET + NEW YORK, March 5 - + Shr 27 cts vs 28 cts + Net 1,026,000 vs 1,025,000 + Sales 27.8 mln vs 25.4 mln + Year + Shr 95 cts vs 16 cts + Net 3,682,000 vs 598,000 + Sales 102.1 mln vs 100.4 mln + Avg shrs 3,858,000 vs 3,700,000 + Reuter + + + + 5-MAR-1987 10:04:32.26 +earn +usa + + + + + +F +f0191reute +r f BC-OAK-INDUSTRIES-INC-<O 03-05 0068 + +OAK INDUSTRIES INC <OAK> 4TH QTR LOSS + SAN DIEGO, March 5 - + Oper shr loss five cts vs loss 50 cts + Oper net loss 3,862,000 vs loss 15,900,000 + Sales 42.6 mln vs 38.8 mln + Avg shr 72.1 mln vs 31.7 mln + Year + Oper shr loss 51 cts vs loss 2.10 dlrs + Oper net loss 30.3 mln vs 51.3 mln + Sales 151.7 mln vs 153.1 mln + Avg shrs 59.4 mln vs 24.4 mln + Backlog 57.1 mln vs 52.9 mln + NOTES: Operating losses exclude profits from discontinued +operationgs of 1,000,000 dlrs, or one cent a share, vs +2,493,000 dlrs, or eight cts a share, in quarter and 65.0 mln +dlrs, or 1.09 dlrs a share, vs 13.7 mln dlrs, or 56 cts a +share, in year + 1986 year operating loss also excludes extraordinary gain +of of 25.6 mln dlrs, or 43 cts a share + Backlog, which includes only orders to be shipped within 12 +mths, was 63.0 mln dlrs on January 31. Orders to be shipped +beyond 12 mths were 27.6 mln dlrs vs 17.1 mln dlrs at December +31 + Reuter + + + + 5-MAR-1987 10:04:36.77 +earn +usa + + + + + +F +f0192reute +s f BC-REGIS-CORP-<RGIS>-REG 03-05 0024 + +REGIS CORP <RGIS> REGULAR DIVIDEND SET + MINNEAPOLIS, March 5 - + Qtly div 4-1/2 cts vs 4-1/2 cts prior + Pay April 15 + Record March 24 + Reuter + + + + 5-MAR-1987 10:05:25.49 + +usa + + + + + +F +f0196reute +u f BC-JAMESWAY-<JMY>-FEBRUA 03-05 0068 + +JAMESWAY <JMY> FEBRUARY SALES UP 13 PCT + SECAUCUS, N.J., March 5 - Jamesway Corp said it had sales +for the four weeks ended February 28, excluding leased +departments, were 31.7 mln dlrs, up 13 pct from 28.0 mln dlrs +in the comperable four week period a year earlier. + On a store for store basis, the company said, sales +increased five pct. It operated 100 stores last month, up from +92 in February 1986. + Reuter + + + + 5-MAR-1987 10:09:59.43 + +usa + + + + + +F +f0209reute +u f BC-K-MART-<KM>-COMPARABL 03-05 0102 + +K MART <KM> COMPARABLE-STORE FEBRUARY SALES UP + TROY, Mich., March 5 - K Mart Corp said February sales +rose 13.1 pct from a year ago and comparable store sales in the +four-week period ended February 25 rose 8.2 pct. + K Mart said consolidated sales in the period were +1,459,193,000 dlrs compared with 1,289,635,000 dlrs last year. +It said the year-ago figures excluded sales for discontinued +operations such as Designer Depots, Furr's Cafeterias and +Bishop Buffets. + K Mart cited "favorable consumer response to our +merchandise programs" and said its specialty retailers had +"excellent February sales." + Reuter + + + + 5-MAR-1987 10:11:50.97 + +usa +james-baker +worldbank + + + +C G L M T +f0214reute +r f BC-Trade 03-05 0143 + +CONGRESS MAY CURB U.S. AID TO DEVELOPMENT BANKS + WASHINGTON, March 5 - Congressional ire is rising against +the multinational development banks which make loans to help +other countries produce goods in direct competition with +beleagured U.S. farmers and miners. + With a record U.S. trade deficit of 169 billion dlrs last +year and a farm economy in the doldrums, Congress is pressing +to hold back U.S. funds for the World Bank and other +development banks if the money is used to subsidize production +or to produce goods already in oversupply around the world. + "American tax dollars are being used to subsidize foreign +agriculture and mineral production that is often in direct +competition with our producers," Senator Don Nickles, an +Oklahoma Republican, said in a letter to fellow senators +seeking support for his legislation to limit these loans. + Nickles and Senator Steven Symms, a conservative Republican +from Idaho, have introduced legislation that would strictly +limit U.S. funding of multinational development banks if they +make any loans to help developing countries produce surplus +commodities or minerals. + Current law requires that the United States vote against +such loans but carries no reprisals if they are ultimately +approved by the banks. + Treasury Secretary James Baker's assurances that U.S. +policy is to oppose these loans did not satisfy concerns raised +at two Senate committee hearings last week. + Baker told a Senate Appropriations subcommittee on Foreign +Operations, "As a policy matter, we oppose loans for production +of commodities in oversupply." + The senators cited a 350-mln-dlr World Bank loan made to +Argentina last year to help it increase its agricultural +exports by one billion dlrs a year by 1989. + Nickles, Symms and others also have cited other loans such +as a 1985 World Bank loan to Hungary to expand livestock +exports and 500 mln dlrs lent to Thailand from 1981 to 1985 at +low interest rates for agriculture. + Last year the Republican-controlled Senate voted three +times over the objections of the administration to cut U.S. +funding of development banks by the amount of these loans. + But even with a 65 to 15 vote in favour of the proposal, +the restrictions were weakened in the final version. Only a +provision directing U.S. officials to vote disapproval cleared +Congress. + This year's version, called the Foreign Agricultural +Investment Reform (FAIR) Act would require the U.S. to vote +against loans designed to increase production of surplus +commodities and minerals. Also, the recipient countries would +have to prove that the production, marketing and export of the +commodities could be handled without government subsidy. + If the loan is approved over U.S. objections, the United +States would not increase or replenish funds for that +institution until it agrees to stop making such loans. + Objections to such loans have most often been raised by +conservative Republicans who have traditionally opposed U.S. +funding for these international development banks. + But the loss of many jobs to foreign competition has raised +similar concerns among more moderate senators. + The administration opposes any legislation that would tie +its hands in votes on the loans. It argues there might be +instances in which a country needed the money to continue its +moves toward U.S. policies in other areas. + Baker said the United States would continue to use its +leverage in the banks to require foreign trade liberalization +measures, often in the form of elimination of subsidies. + Two House Republicans, Representatives Larry Craig of Idaho +and Beau Bolter of Texas, have introduced the bill. But it +faces stiff opposition in the House Banking Committee which has +blocked its consideration by the House in the past. + Symms intends to offer the bill as an amendment to any +related legislation this year, an aide said. + Reuter + + + + 5-MAR-1987 10:13:13.34 + +usa + + + + + +F +f0219reute +d f BC-EQUATORIAL-<EQUA>-SIG 03-05 0094 + +EQUATORIAL <EQUA> SIGNS PACT WITH CONTEL UNIT + MOUNTAIN VIEW, Calif., March 5 - Equatorial Communications +Co, a satellite data network concern, said it has signed an +agreement with Contel Corp's <CTC>, Contel ASC, unit allowing +Contel ASC to buy 3.6 mln shares of Equatorial stock at 3.25 +dlrs per share. + In addition, Equatorial said under the agreement Contel ASC +would buy a minimum of 10 mln dlrs of equipment from +Equatorial, loan Equatorial up to six mln dlrs and assume a +portion of Equatorial's rights and obligations under a +satellite transponder lease. + Reuter + + + + 5-MAR-1987 10:13:54.12 +acq +west-germanyusa + + + + + +F +f0223reute +d f BC-MANNESMANN-SEEKS-STAK 03-05 0101 + +MANNESMANN SEEKS STAKE IN U.S. FIRM + DUESSELDORF, March 5 - Mannesmann AG <MMWG.F>, the +diversified engineering and pipe-making group, is interested in +taking a stake in a U.S. Company or companies but has not yet +found a suitable firm, a spokesman said in reply to questions. + Mannesmann managing board chairman Werner Dieter told the +business weekly Wirtschaftswoche in an interview that +Mannesmann wanted to invest in a U.S. Company in order to +strengthen its presence on the U.S. Market. + Dieter said Mannesmann would act quickly when and if it +found a firm in which it wanted to take a stake. + The Mannesmann spokesman declined to say in which +industrial sector the group may make a U.S. Acquisition or how +big the acquisition might be. + He also said the group had not yet completed taking over a +stake in car components firm <Fichtel und Sachs AG>. + Mannesmann had said in January it hoped to take a 37.5 pct +stake in Fichtel und Sachs's holding company, Sachs AG, in the +first quarter. The spokesman said Mannesmann had a letter of +intent on the takeover from the heirs of the company's late +owner but completion has been delayed by legal questions +concerning the inheritance. + REUTER + + + + 5-MAR-1987 10:15:44.63 +earn +usa + + + + + +F +f0228reute +u f BC-AMERICAN-INT'L-GROUP 03-05 0052 + +AMERICAN INT'L GROUP INC <AIG> 4TH QTR NET + NEW YORK, March 5 - + Shr 1.83 dlrs vs 77 cts + Net 296.6 mln vs 120.1 mln + Year + Shr 4.90 dlrs vs 2.76 dlrs + Net 795.8 mln vs 420.5 mln + NOTE: Includes gains of 139.2 mln vs 46.8 mln in year and +94.0 mln vs 11.6 mln from capital gains from investments. + Reuter + + + + 5-MAR-1987 10:17:54.70 +earn +usa + + + + + +F +f0241reute +r f BC-SYSTEMS-FOR-HEALTH-CA 03-05 0075 + +SYSTEMS FOR HEALTH CARE IN ONE-FOR-50 SPLIT + CHICAGO, March 5 - Systems for Health Care Inc said it +repositioned the company through a one-for-50 reverse stock +split. + It said there are now 3,002,500 common shares outstanding +with a quoted price of about 7/8 bid, compared to 150,125,000 +shares outstanding prior to the split. + In another recent development, Systems for Health Care +formally changed its name to its present form from Orcas Corp. + Reuter + + + + 5-MAR-1987 10:18:25.05 + +usa + + + + + +F +f0245reute +r f BC-FIRST-EXECUTIVE-CORP 03-05 0085 + +FIRST EXECUTIVE CORP <FEXC> GIVES UNIT FUNDS + LOS ANGELES, March 5 - First Executive Corp said that its +principal subsidiary contributed 152 mln dlrs to one of its +divisions to cover credits it wrongfully took on its 1983 to +1985 regulatory accounting statements. + The company said Executive Life Insurance Co gave the +capital infusion to its subsidiary, Executive Life Insurance Co +of New York. It said the new funds bring to 280 mln dlrs the +company has received from its parent the past three years. + Executive Life Insurance Co of New York admitted a +violation of state insurance law and paid a fine of 250,000 +dlrs levied by the New York Insurance Department, according to +the company. + Executive Life of New York took credits for reinsurance +agreements that provided less protection to the insurer and its +policyholders than New York rules require, according to +published reports. + Reuter + + + + 5-MAR-1987 10:18:32.34 + +usa + + + + + +F +f0246reute +r f BC-<HARD-ROCK-CAFE-PLC> 03-05 0087 + +<HARD ROCK CAFE PLC> SETS INITIAL U.S. OFFERING + NEW YORK, March 5 - Hard Rock Cafe PLC said it has filed +for an initial U.S. offering of 2,240,000 American Depositary +Shares representing 11.2 mln Class A ordinary shares. + It said 240,000 of the ADS's will be sold by a current +shareholder. + Lead underwriter is <Drexel Burnham Lambert Inc>. + The company said proceeds will be used for the financing of +additional restaurants, the expansion of existing restaurants +and retail operations and the repayment of debt. + Reuter + + + + 5-MAR-1987 10:18:46.99 + +belgium + + + + + +RM +f0247reute +b f BC-BELGIUM-TO-ISSUE-150 03-05 0093 + +BELGIUM TO ISSUE 150 BILLION FRANC STATE LOAN + BRUSSELS, March 5 - Belgium is to issue a 150 billion +franc, eight-year state loan carrying a coupon of eight pct, a +Finance Ministry spokesman said. + Pricing will be fixed next week. + The spokesman said the loan will feature a call option +after four years at a price also to be determined. + Some 120 billion francs of the loan will be taken up by +members of the issuing consortium, comprising major Belgian +commercial banks, and the remaining 30 billion by semi-state +owned financial institutions. + The most recent public authority loan stock issue, for the +state road building fund Fonds des Routes, was also for eight +years with an eight pct coupon. It was priced at par. + The issue also featured a call option after four years at +102, falling to 101-1/2 after five and by a half point each +year thereafter. + REUTER + + + + 5-MAR-1987 10:18:51.21 + + + + + + + +F +f0248reute +f f BC-******MAY-DEPARTMENT 03-05 0009 + +******MAY DEPARTMENT STORES CO FEBRUARY SALES RISE 15 PCT +Blah blah blah. + + + + + + 5-MAR-1987 10:20:40.73 +earncrude +ukusa + + + + + +F Y +f0253reute +d f BC-ROYAL-DUTCH/SHELL-U.S 03-05 0111 + +ROYAL DUTCH/SHELL U.S. EARNINGS SHARPLY LOWER + LONDON, March 5 - Royal Dutch/Shell Group <RD.AS> earnings +for 1986 from the U.S. Fell sharply because of difficult market +conditions, lower crude and gas prices and also due to +different accounting methods, Shell chairman Peter Holmes said. + The Shell Oil dollar net income fell 47 pct in the year, +while the additional effect of currency movements reduced the +contribution to group net income by 57 pct to 472 mln stg. + The group earlier reported a drop in net income for the +year to 2.54 billion stg from 3.03 billion previously, with +lower crude prices outweighing the effect of increased sales by +volume. + Although the figures were lower, they were nonetheless at +the top end of market forecasts. Shell Transport and Trading +Plc <SC.L> shares, the U.K. Arm of the group, rose to 11.39 stg +from a close last night of 11.06 stg. Analysts noted that a +general collapse in exploration and production volumes was +partially offset by earnings from chemicals rising to 462 mln +stg from 205 mln in 1985. + Also, a windfall tax credit and lower than expected +currency losses had added about 100 mln stg onto fourth quarter +results, which was the main reason for the figures exceeding +forecasts, industry analyst Chris Rowland of Barclays de Zoete +Wedd noted. + However, he added there could well be a sharp fall in +performance in the first quarter of 1987, due to the +improbability that the group would be able to repeat the high +refining and marketing margins of first quarter 1986. + The impact of recovering oil prices would come through +faster on the downstream side than on the upstream as such a +high proportion of upstream activity centred on gas, which +typically reacted to oil price changes with about a half-year +lag, analysts said. + Holmes said that in the upstream U.S. Sector the third +quarter of 1986 had been the worst of all. + Only two of the oil majors had managed to make a profit in +the period, with Shell Oil being one of them. The decrease in +U.S. Earnings had been accentuated by tax rates but the group +had increased share to become volume market leader, Holmes +added. + Continued low crude oil prices would continue to subdue +U.S. Exploration activity. "Exploration is currently pretty +flat. We are going to go on, but at 16-18 dlrs there will be no +massive upturn," he said. + A renewal of exploration in high cost areas of the North +Sea and the U.S. Requires prices of around 25 dlrs a barrel. + Ultimately this would lead to a rise in U.S. Imports. "If +you are not exploring you are not going to find anything," he +noted. + U.S. Oil production had dropped some half mln barrels a day +(bbd) in 1986 and would continue to fall if the price stayed +below 20 dlrs a barrel. + This favored OPEC's attempts to stabilise prices, as the +lower the price the more likelihood there was of non-OPEC +marginal production shutting down. "OPEC has done pretty +extraordinarily well...Everything is moving in (its) direction," +he added. + Reuter + + + + 5-MAR-1987 10:21:29.06 + +usa + + + + + +F +f0258reute +u f BC-J.C.-PENNEY-<JCP>-FEB 03-05 0069 + +J.C. PENNEY <JCP> FEBRUARY SALES 5.3 PCT + NEW YORK, March 5 - J.C. Penney co Inc said sales for the +four weeks ended February 28 for its JCPenney stores and +catalogs were up 5.3 pct to 780 mln dlrs from 741 mln dlrs a +year earlier, with comparable store sales up 5.5 pct. + The company said total company sales for the period were up +6.0 pct to 888 mln dlrs from 838 mln dlrs, with same-store +sales up 6.3 pct. + Reuter + + + + 5-MAR-1987 10:21:41.00 + +usa + + + + + +F +f0259reute +u f BC-F.W.-WOOLWORTH-<Z>-FE 03-05 0057 + +F.W. WOOLWORTH <Z> FEBRUARY SALES INCREASE + NEW YORK, March 5 - F.W. Woolworth Co said total sales for +the four weeks ended February 28 rose 11.3 pct to 416 mln, from +374 mln in the comparable 1986 period. + Woolworth said domestic sales increased 7.1 pct, to 249 mln +from 233 mln, while foreign sales rose 18.4 pct to 167 mln, +from 141 mln. + Reuter + + + + 5-MAR-1987 10:22:24.09 +interest +spain + + + + + +RM +f0266reute +r f BC-BANKERS-WELCOME-SPANI 03-05 0115 + +BANKERS WELCOME SPANISH RESERVE REQUIREMENT HIKE + MADRID, March 5 - Bankers welcomed the Bank of Spain's +decision to raise the reserve requirement for banks and savings +banks, saying it reflected the socialist government's +determination not to ease up in the fight against inflation +despite the painful social effects of four years of austerity. + The central bank last night raised the requirement by one +percentage point to 19 pct from March 13, saying that excess +liquidity threatened money supply and inflation targets. + Bankers said the move represented a change of tactic by the +Bank, which until now has relied on raising interest rates to +choke off money supply growth. + "I think it's a good measure," a senior foreign banker said. +"It's a faster way to get the job done than using interest rates +and avoids unpleasant effects on other areas of the economy." + "It shows that the political will is very strong. They know +that controlling inflation will make industry more competitive +and bring down unemployment in the long run," he added. + The head of another foreign bank said that only a month +ago, the Bank of Spain had dismissed his suggestion of a rise +in reserve requirements, preferring to pursue its strategy of +raising interest rates. + But bankers said the high real interest rates on offer now +-- around eight pct for overnight funds -- was attracting money +from abroad, strengthening the peseta and making Spanish +exports less competitive. + The government says industry's competitiveness is also +being hit hard by inflation. At 8.3 pct last year, the rate was +way above that of Spain's major trading partners in the +European Community, which it joined a year ago. + To help meet this year's target of five pct, it is +insisting pay rises stay at that level, setting the stage for +clashes with trade unions, who say they have made enough +sacrifices. + Demonstrations by workers, students and farmers, whose +demands essentially involve more government spending, have +become an almost daily occurrence. But Prime Minister Felipe +Gonzalez insists that the state is doing as much as it can. + Bankers said the reserve requirement increase could have +some impact on commercial lending rates but should not hit the +money market too hard. + The Bank of Spain, which only yesterday raised its key +overnight call money rate to 13.5 pct, left it unchanged at +today's auction. The rate has been increased nine times since +the start of the year, when it was below 12 pct. + Bankers said commercial lending rates were set to rise in +any case with the end of the six pct maximium interest rate +banks can offer for time deposits of up to six months. + The measure will take effect tomorrow, following the +publication of the decree in today's official gazette. Bankers +say the liberalisation will increase the cost of funds and, +inevitably, push lending rates higher. + A companion measure, reducing the proportion of funds which +banks must invest in specific areas, also takes effect +tomorrow. Officials said when the cut was approved last month +that it was aimed partly at compensating banks for higher +interest rates. + REUTER + + + + 5-MAR-1987 10:22:36.39 +earn +sweden + + + + + +F +f0268reute +d f BC-GAMBRO-AB-<GAMB-ST>-1 03-05 0035 + +GAMBRO AB <GAMB ST> 1986 YEAR + STOCKHOLM, Mar 5 - Group profit after net financial items -133.5 mln crowns vs 101 mln. + Sales 1.61 billion vs 1.51 billion. + Proposed dividend 0.80 crowns vs 0.40 crowns. + REUTER + + + + 5-MAR-1987 10:22:52.88 + +netherlands + + + + + +F +f0269reute +d f BC-KLM-LOAD-FACTOR-HIGHE 03-05 0100 + +KLM LOAD FACTOR HIGHER IN FEBRUARY + AMSTERDAM, March 5 - KLM Royal Dutch Airlines <KLM.AS> said +its load factor rose to 66.5 pct in February from 62.5 pct in +January and 65.7 pct in February 1986. + The load factor was 66.6 pct in the April/February period +of 1986/87 compared with 67.2 pct in the same period in +1985/86. + Traffic rose 18 pct and capacity rose 17 pct in February +versus 12 and 13 pct respectively in January. + In the April/February period of 1986/87 traffic rose nine +pct and capacity rose 10 pct compared with eight and nine pct +respectively in the same period in 1985/86. + REUTER + + + + diff --git a/src/test/data/reuters-21578/reut2-003.sgm b/src/test/data/reuters-21578/reut2-003.sgm new file mode 100644 index 00000000000..ac3024fdef9 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-003.sgm @@ -0,0 +1,2006 @@ + + + 9-MAR-1987 04:58:41.12 +money-fx +uk + + + + + +RM +f0416reute +b f BC-U.K.-MONEY-MARKET-SHO 03-09 0095 + +U.K. MONEY MARKET SHORTAGE FORECAST AT 250 MLN STG + LONDON, March 9 - The Bank of England said it forecast a +shortage of around 250 mln stg in the money market today. + Among the factors affecting liquidity, it said bills +maturing in official hands and the treasury bill take-up would +drain around 1.02 billion stg while below target bankers' +balances would take out a further 140 mln. + Against this, a fall in the note circulation would add 345 +mln stg and the net effect of exchequer transactions would be +an inflow of some 545 mln stg, the Bank added. + REUTER + + + + 9-MAR-1987 05:03:09.75 +money-fxinterest +france + + + + + +RM +f0423reute +u f BC-BANK-OF-FRANCE-SETS-M 03-09 0112 + +BANK OF FRANCE SETS MONEY MARKET TENDER + PARIS, March 9 - The Bank of France said it invited offers +of first category paper today for a money market intervention +tender. + Money market dealers said conditions seemed right for the +Bank to cut its intervention rate at the tender by a quarter +percentage point to 7-3/4 pct from eight, reflecting an easing +in call money rate last week, and the French franc's steadiness +on foreign exchange markets since the February 22 currency +stabilisation accord here by the Group of Five and Canada. + Intervention rate was last raised to eight pct from 7-1/4 +on January 2. Call money today was quoted at 7-11/16 7-3/4 pct. + REUTER + + + + 9-MAR-1987 05:03:38.51 +crude +china + + + + + +F +f0426reute +u f BC-AMOCO-REPORTS-SOUTH-C 03-09 0073 + +AMOCO REPORTS SOUTH CHINA SEA OIL FIND + PEKING, March 9 - The U.S. <Amoco Petroleum Corp> has +reported an offshore oil find at its Pearl River basin +concession in the South China Sea, the New China News Agency +said. + It said the Liu Hua 11-1-1 A well produced at around 2,240 +barrels per day at a depth of 305 metres. + The news agency said Amoco plans to drill a second well in +the area this year, but gave no further details. + REUTER + + + + 9-MAR-1987 05:12:17.12 + +south-korea + + + + + +F +f0437reute +u f BC-SOUTH-KOREA-DELAYS-CO 03-09 0110 + +SOUTH KOREA DELAYS CONTRACT FOR NUCLEAR PLANTS + SEOUL, March 9 - Technology transfer problems have delayed +the finalising of contracts between South Korea's state-owned +Korea Electric Power Corp (Kepco) and U.S. Firms for supplies +of equipment and services for Kepco's latest two 950-megawatt +nuclear power plants, a Kepco spokesman said. + He told Reuters the contracts for Kepco's tenth and +eleventh stations, costing between two and three billion dlrs, +were due for completion by the end of February. + Kepco has been negotiating with Combustion Engineering Inc +(CSP) for pressurised light-water reactors and General Electric +Co (GE) for turbines. + + KEPCO has also been negotiating with (Sargent and Lundy +Engineers) for engineering and design consultancy services. + "We have been waging a tug-of-war on the transfer of +advanced technology. But I am optimistic we will sign contracts +with them within this month," the spokesman said. + He said the transfer of advanced technology is vital for +South Korea, which wants to build future nuclear power plants +with its own technology. + Work on the two plants is due to start about June 1988 for +completion in 1995 and 1996, although the sites have yet to be +chosen, he said. + REUTER + + + + 9-MAR-1987 05:19:27.56 + +switzerland + + + + + +RM +f0442reute +u f BC-KEIAISHA-ISSUING-12-M 03-09 0060 + +KEIAISHA ISSUING 12 MLN SWISS FRANC NOTES + ZURICH, March 9 - Keiaisha Co Ltd of Tokyo is issuing 12 +mln Swiss francs of straight notes due March 26, 1992 with a +4-5/8 pct coupon, lead manager Gotthard Bank said. + The notes can be called from September 26, 1989 at 101-1/4, +declining semi-annually. + The issue is guaranteed by the Kyowa Bank Ltd. + REUTER + + + + 9-MAR-1987 07:59:05.79 +interest + + + + + + +RM +f0749reute +f f BC-NATIONAL-WESTMINSTER 03-09 0015 + +******NATIONAL WESTMINSTER BANK SAYS IT CUTTING BASE LENDING RATE TO 10.5 PCT FROM 11 PCT. +Blah blah blah. + + + + + + 9-MAR-1987 08:08:57.16 +interest +uk + + + + + +RM +f0776reute +b f BC-NATIONAL-WESTMINSTER 03-09 0029 + +NATIONAL WESTMINSTER BANK CUTS BASE RATE + LONDON, March 9 - National Westminster Bank Plc said it has +cut its base lending rate 0.5 percentage points to 10.5 pct +today. + National Westminster said that it was responding to general +easing in money market rates. + Its move followed a signal from the Bank of England earlier +this afternoon that it would endorse a half point cut in the +base rate, a surprise move following its strong signals last +week that such a move would be premature. + However, since then the pound has continued to gain +strongly. + REUTER + + + + 9-MAR-1987 08:11:20.25 +earn +usa + + + + + +F +f0792reute +s f BC-U.S.-FACILITIES-<USRE 03-09 0047 + +U.S. FACILITIES <USRE> SEMI-ANNUAL DIVIDEND + COSTA MESA, Calif., March 9 - + Semi-annual dividend 4 cts + Pay May 29 + Record April 14 +Note: full name is U.S. Facilities Corp. This is first dividend +declared since company completed its initial public offering on +November 7. + Reuter + + + + 9-MAR-1987 08:13:16.75 +acq +usa + + + + + +F A +f0805reute +r f BC-STANDARD-PACIFIC-<SPF 03-09 0134 + +STANDARD PACIFIC <SPF> ACQUIRES SOUTH BAY S/L + COSTA MESA, Calif, March 9 - Standard Pacific LP said it +has acquired substantially all of the assets and liabilities of +South Bay Savings and Loan Association of Newport Beach. + The firm said over the weekend that it will conduct its +savings and loan activities through Standard Pacific Savings +FA, a Federal stock association. + On Friday, the Federal Home Loan Bank Board in Washington +said it approved the acquisition of South Bay S and L, a 62.5 +mln dlr state-chartered stock association, by Standard Pacific, +which has 312.8 mln dlrs in assets. + The Bank Board said that the Federal Savings and Loan +Insurance Corp will make a cash contribution, provide capital +loss coverage and indemnify Standard Pacific against +undisclosed liabilities. + Reuter + + + + 9-MAR-1987 08:13:36.29 +strategic-metal +usasouth-africa + + + + + +A +f0808reute +d f AM-URANIUM 03-09 0135 + +U.S. TO ALLOW TEMPORARY IMPORTS OF S.A. URANIUM + WASHINGTON, March 9 - The Treasury Department said it would +temporarily permit imports of South African uranium ore and +oxide pending clarification of anti-apartheid sanctions laws +passed by Congress last fall. + The decision was announced late Friday. It applies, until +July 1, to uranium ore and oxide imported into the U.S. for +processing and re-export to third countries. + The Treasury said it took the action because it felt that +when Congress passed the comprehensive South African sanctions +bill last fall over President Reagan's veto it had not intended +to hurt U.S. industry. + In addition, the Treasury said it would permit U.S.-made +goods to be imported temporarily from South African +state-controlled organizations for repair or servicing. + + Reuter + + + + 9-MAR-1987 08:15:28.61 + +usairan + + + + + +V +f0812reute +u f BC-PAPER-SAYS-INDICTMENT 03-09 0115 + +PAPER SAYS INDICTMENTS IN IRAN CASE EXPECTED + NEW YORK, March 9 - The special prosecutor in the Iran arms +scandal is expected to bring indictments that could include +felony charges against senior Reagan administration officials, +the New York Times reported. + It quoted law enforcement officials with knowledge of the +investigation as saying special prosecutor Lawrence Walsh, who +is investigating the scandal, was focusing on three areas. + The paper identified these as conspiracy to defraud the +government, obstructing justice and making false statements to +the government. It said the prosecutor had not ruled out any +suspects, including current and former government officials. + MORE + + + + 9-MAR-1987 08:15:42.31 + +usauk + + +nyselse + + +F +f0814reute +r f BC-NYSE-RULE-COULD-AFFEC 03-09 0101 + +NYSE RULE COULD AFFECT TRADING IN LONDON + LONDON, March 9 - An existing New York Stock Exchange, +NYSE, rule might be used to limit the trading activities of its +members in London in stocks listed on both exchanges, sources +at the London Exchange said. + This could arise if the London Stock Exchange goes ahead +with plans to close its trading floor. + The London Exchange sources were commenting on press +reports that the NYSE would bar its members firms from trading +on the London Exchange in interlisted stocks during periods +when the NYSE was open. + The London exchange is seeking clarification. + London Exchange sources said the possibility of +restrictions on NYSE members appears to reflect a rule which +requires that exchanges recognised by the NYSE possess a +trading floor. + Last month, the London Exchange said in a statement that it +planned to close its floor in due course, apart from a floor +for traded options, because almost all business is now being +done by screen and telephone between brokerage offices. + This development stemmed from the Big Bang restructuring of +the market on October 27. The demise of the traditional Stock +Exchange floor has been widely expected, though no date has +been set as yet. + Market sources said a compromise over the NYSE rule could +well be reached, partly because the interests of U.S. +Securities dealers are not all identical. + Some of them could well start lobbying the NYSE, pointing +out, among other things, that the expansion of global trading +needs to be based on reciprocal arrangements. + NYSE brokerage firms which also trade on the London +Exchange would presumably be put at a disadvantage over +non-NYSE U.S. Firms, which have affiliates on the London +Exchange, market sources said. + REUTER + + + + 9-MAR-1987 08:16:35.37 +acq +usa + + + + + +F +f0816reute +u f BC-/PIEDMONT-<PIE>-AGREE 03-09 0113 + +PIEDMONT <PIE> AGREES TO USAIR <U> BUYOUT + NEW YORK, March 9 - USAir Group Inc said Piedmont Aviation +Inc has agreed to be acquired for 69 dlrs per share. + The company, in a newspaper advertisement, said it has +started a tender offer for all Piedmont shares at that price, +and the Piedmont board, with two directors absent, has +unanimously approved the bid. The offer and withdrawal rights +are to expire April Three unless extended, and the bid is to be +followed by a merger at the same price. + USAir said Piedmont has granted it an irrevocable option to +buy up to 3,491,030 new shares under certain circumstances. +Piedmont now has about 18.6 mln shares outstanding. + USAir said the tender is conditioned on receipt of enough +shares to give USAir at least a 50.1 pct interest in Piedmont +on a fully diluted basis and approval by the U.S. Department of +Transportation of a voting trust agreement permitting USAir to +buy and hold shares pending review of its application to gain +control of Piedmont. + The company said its merger agreement with Piedmont +provides that the offer is not to be amended without Piedmont's +prior written consent in any way that would be adverse to +Piedmont shareholders, but it said it could cut the number of +shares to be bought without Piedmont's consent. + USAir said it could reduce the number of Piedmont shares to +be purchased in the offer to no less than the minimum number +needed to cause the voting trust condition of the bid to be +satisfied. + In that case, it said if more than that minimum number of +shares were tendered, it would buy shares on a pro rata basis. + In February USAir had offered to pay 71 dlrs per share in +cash for 50 pct of Piedmont's stock and 1.55 to 1.90 USAir +shares for each remaining Piedmont share. + Last week, Carl C. Icahn-controlled Trans World Airlines +Inc <TWA> made a conditional offer to acquire USAir for 52 dlrs +per share, a bid that was rejected by the USAir board. + The Transportation Department on Friday rejected TWA's +application to acquire USAir on the grounds that the +application failed to comply with department regulations by +omitting necessary information. TWA said it would refile +today, providing the information needed. + On Friday TWA said it had already acquired four mln shares +or 15 pct of USAir. + Reuter + + + + 9-MAR-1987 08:21:01.71 + +usaussr + + + + + +V +f0832reute +r f BC-U.S.-AIDES-SEE-MOSCOW 03-09 0103 + +U.S. AIDES SEE MOSCOW AGREEING TO ARMS CHECK PACT + WASHINGTON, March 9 - Senior U.S. Arms control officials +said they were optimistic the United States and Soviet Union +could reach agreement on ways to verify a pact to eliminate +medium-range nuclear missiles in Europe. + Chief U.S. Arms control negotiator Max Kampelman said on +the NBC television network a fair pact would be hard to +negotiate, but, "We are determined to do it." + Assistant Secretary of Defence for international security +policy Richard Perle said he thought the two sides could agree +on a method to ensure each side was honouring a missile pact. + President Reagan said on Friday that Secretary of State +George Shultz would go to Moscow next month for talks on arms +control and a possible U.S.-Soviet summit meeting. + The decision to send Shultz to Moscow followed an +announcement by Soviet leader Mikhael Gorbachev that he was +willing to separate elimination of medium-range missiles in +Europe from his demand for curbs on U.S. Development of a +Strategic Defence Initiative (SDI) anti-missile system. + Kampelman said the United States and the Soviet Union both +had a general definition of so-called "intrusive" or on-site +inspection of a pact, but details would be tough to work out. + Reuter + + + + 9-MAR-1987 08:22:57.04 +crudenat-gas +usa + + + + + +Y F +f0839reute +d f BC-API-REPORTS-SHARP-FAL 03-09 0082 + +API REPORTS SHARP FALL IN DRILLINGS + WASHINGTON, March 9 - Estimated oil and gas drilling +completions in the United States dropped by almost 41 per cent +in 1986 from 1985, the American Petroleum Institute said. + API, an industry group, said that of the 42,387 wells +completed last year, a total of 19,741 were oil wells, 8,645 +were natural gas wells and 14,001 were dry holes. + In 1985, a total of 71,539 wells were drilled - 36,834 oil +wells, 13,036 gas wells and 21,669 dry holes. + reuter + + + + 9-MAR-1987 08:23:31.25 +instal-debt +uk + + + + + +RM +f0840reute +b f BC-U.K.-CREDIT-BUSINESS 03-09 0109 + +U.K. CREDIT BUSINESS FALLS IN JANUARY + LONDON, March 9 - New credit advanced by finance houses, +retailers, bank credit cards and other specialist providers of +credit slipped to 2.66 billion stg in January from 2.78 billion +in December - but remained close to the average level for +1986's fourth quarter, the Department of Trade and Industry +said. + Of the January total, 1.15 billion stg was advanced on bank +credit cards. + On a three-month basis, total advances in November to +January were 3.0 pct lower than in the previous three months. +Within this total, lending to consumers fell by 6.0 pct and +lending to businesses declined by 5.0 pct. + At end-January 1987, the total amount outstanding was 24.07 +billion stg, up from December's 23.77 billion stg and 3.0 pct +above the total three months earlier, the department said. + January saw a rise of 300 mln stg in amounts outstanding to +finance houses, other specialist credit grantors and retailers. + The department said advances on credit cards rose by 1.0 +pct between the latest two three-month periods. Retailers +advanced 3.0 pct less in the latest three months than in the +previous three months, it said. + REUTER + + + + 9-MAR-1987 08:27:14.06 +crudeship +brazil + + + + + +C G L M T +f0842reute +u f BC-BRAZILIAN-SEAFARERS' 03-09 0108 + +BRAZILIAN SEAFARERS' STRIKE DAMAGES OIL EXPORTS + SAO PAULO, March 9 - A strike by Brazil's 40,000 seafarers +who want pay rises of up to 180 pct may have cost the +state-owned oil company Petrobras 20 mln dlrs in lost export +orders, the company's commercial director Arthur de Carvalho +was quoted as saying in press reports. + More than 170 ships in Brazil, and about nine more in +foreign ports, have been halted by the strike, which began on +February 27. + Marines began blockading the ships on Friday after the +strike was ruled illegal, and some strikers are running short +of food, National Merchants Marine Union president Edson Areias +said. + Reuter + + + + 9-MAR-1987 08:38:11.68 + +usa + + + + + +F +f0875reute +u f BC-NEC-<NIPNY>-UNIT-INTR 03-09 0098 + +NEC <NIPNY> UNIT INTRODUCES NEW COMPUTERS + BOXBOROUGH, Mass., March 9 - NEC Corp's NEC Informational +Systems Inc said it introduced three advanced personal +computers that are fully compatible with the International +Business Machines Corp <IBM> PC AT. + The computers, the PowerMate 1, PowerMate 2 and +BusinessMate, are based on a chip made by Intel Corp <INTC>. + The PowerMate 1 and 2 are available immediately and sell +for 1,995 dlrs and 2,595 dlrs, respectively, the company said. + The BusinessMate, scheduled for April availability, will +sell for less than 6,000 dlrs, it said. + Reuter + + + + 9-MAR-1987 08:40:06.50 +tradegnpbopdlr +ukusawest-germanyjapan + +oecd + + + +A +f0886reute +d f BC-OECD-TRADE,-GROWTH-SE 03-09 0110 + +OECD TRADE, GROWTH SEEN SLOWING IN 1987 + LONDON, March 9 - The 24 nations of the Organisation for +Economic Cooperation and Development (OECD), hampered by +sluggish industrial output and trade, face slower economic +growth, and their joint balance of payments will swing into +deficit in 1987, the Economist Intelligence Unit (EIU ) said. + The EIU said in its World Trade Forecast it revised OECD +economic growth downwards to 2.5 pct this year, compared with a +2.8 pct growth forecast in December. + It said the new areas of weakness are West Germany and the +smaller European countries it influences, and Japan, hardest +hit by currency appreciation this year. + The independent research organisation cut its 1987 growth +rate forecasts for West Germany to 2.2 pct from 3.2 pct in +December and to 2.3 pct from three pct for Japan. + It said it expected the OECD to post a current account +deficit of some 13 billion dlrs in both 1987 and 1988, due in +large part to a 1.50 dlrs a barrel rise in 1987 oil prices. + It said the U.S. Current account deficit looked likely to +fall even more slowly than forecast, to 125 billion dlrs in +1987 and 115 billion in 1988 from 130 billion in 1986. + It said it expected West Germany to post a 31 billion dlr +payments surplus and Japan a 76 billion dlr surplus this year. + The EIU said it saw oil prices dropping to around 16.50 +dlrs a barrel by end-1987 and 15.50 dlrs in 1988 from about 18 +dlrs last year, as adherence to OPEC output policy becomes +increasingly ragged. + It said the dollar is poised to resume its decline in +foreign exchange markets, and will lose a further 13 pct on its +trade-weighted index this year and five pct in 1988 after last +year's 18.4 pct drop. The average mark/dollar rate is put at +1.80 marks this year and 1.70 in 1988 while the yen/dollar rate +is expected to break through the 150 yen barrier with an +average value of 150 yen in 1987 and 146 yen in 1988, it said. + "This is not a crash scenario but the dollar's steeper +angle of descent increases the risk of ending with a fireball +rather than a three-point landing," the EIU said. + "Talking will not stop the dollar's slide for long and the +February meeting (of finance ministers of the Group of Five and +Canada) produced scant promise of either a decisive shift to +more expansive policies in West Germany and Japan, or a tighter +U.S. Fsical policy," it said. + It said the key to the dollar's fortunes was the +willingness of Japanese institutions to buy U.S. Government +assets despite prospects of sustaining a currency loss. + "Thus far they have been willing," the EIC said, adding +that if Japan was deterred from buying U.S. bonds the dollar +would collapse. + To contain such a currency crisis, dollar interest rates +would have to soar, bringing recession and a Third World debt +crisis, it said. + On trade, the EIU said prospects for 1987 look +"increasingly sick." + Import growth, forecast in December at 4.5 pct, is now seen +slowing down to around 3.8 pct in 1987 with a recovery only to +4.2 pct in 1988, it said. + The weakness of the West German economy is the biggest +single factor, with import growth there expected to feature a +sluggish 3.5 pct growth in 1987 against the 6.5 pct forecast in +December, the EIU said. + On the export side, it said it saw weak demand in West +Germany affecting export prospects elsewhere in Europe, while +Japan's exports in 1987 would remain flat and sales by U.S. +Exporters would respond only marginally to a lower, more +competitively-priced dollar. + It said in most of Europe and in Japan, raw materials and +oil will cost less in domestic currency in 1987 than in 1986. + Reuter + + + + 9-MAR-1987 08:44:23.42 +interestmoney-fxdlr +usawest-germany +poehl + + + + +RM +f0895reute +u f BC-POEHL-SAYS-FURTHER-RA 03-09 0110 + +POEHL SAYS FURTHER RATE CUT POSSIBLE - SOURCES + By Allan Saunderson and Antonia Sharpe, Reuters + FRANKFURT, March 9 - Bundesbank president Karl Otto Poehl +told a closed investment symposium that West Germany could cut +leading interest rates again if the United States makes a +similar move, banking sources said. + The sources were reporting Poehl's remarks at a symposium +in Duesseldorf last week organised by Deutsche Bank Ag. Press +representatives were not invited. + The sources, speaking separately, said Poehl told about 200 +bankers in reply to questions that a cut in U.S. Interest rates +would give room for a matching measure in Germany. + "It was a definite hint at lower German interest rates," said +one banker who attended the symposium. + A Bundesbank spokesman said the central bank would have no +comment on the reported remarks, made at the private meeting. + But, according to a second source, who also declined to be +identified, Poehl's comments were seen by bankers present as a +direct pointer to further moves by the central bank to defend +German industry from an additional revaluation of the mark. + "He said if the Americans drop their interest rates then the +Bundesbank would also drop them. He said that quite clearly," +the second source said. + In reply to questions, Poehl also said the half-point cut +in the discount and Lombard rates on January 22 came after the +U.S. Had signalled it would be prepared to attend a meeting to +discuss the level of the dollar on condition Germany made such +a move in advance, the sources said. + Asked if American authorities could have been persuaded, by +cuts in German rates, to come to the bargaining table as early +as last September, one of the sources quoted Poehl as saying, +"No, they wouldn't have been. We checked that." + The Paris meeting of the Group of Six industrial nations +took place exactly one month after the German cut in rates. + Poehl emphasised in his comments the very close talks +between central banks before and after the G-6 meeting, saying +that financial markets had not fully realised the significance +of the Paris session and the U.S. Agreement to stem further +falls in the value of the dollar, the sources said. + For the first time all participants at the summit agreed +that a further fall in the dollar would be harmful for all +world economies, including the U.S., Poehl had said. + The sources said the tone of Poehl's comments boosted +growing sentiment that the dollar would be stabilised around +current levels by international central bank cooperation. + One source said Poehl's remarks also underlined the fact +that the Bundesbank was now more prepared to be accommodative +in monetary policy in order to prevent a further slowdown in +West Germany's economic growth. + Poehl and other Bundesbank officials have in the past +stressed that the German central bank had no direct +responsibility for growth and was solely concerned with +combatting inflation. + This led, for instance, to the introduction of a tighter +monetary stance from the beginning of December until the +half-point cut in rates in late January. + The sources quoted Poehl as saying that the current +overshooting of the German monetary target would not directly +respark inflation. The Bundesbank was not obliged to react +immediately whenever such overshooting occurs. + Latest data for central bank money stock, the Bundesbank's +main measure of money supply, showed the measure was growing at +7-1/2 pct in January, outside its three to six pct 1987 target. + Share prices rose in very active trading today, with +dealers reporting that Poehl's remarks, coupled with a bullish +outlook on stock prices from Deutsche at the same symposium, +brought in strong bargain hunting at current low levels. + REUTER + + + + 9-MAR-1987 08:44:51.73 + +ukcolombia + + + + + +F +f0897reute +u f BC-PLESSEY-TO-SELL-TELEP 03-09 0106 + +PLESSEY TO SELL TELEPHONE SYSTEM TO COLOMBIA + LONDON, March 9 - Plessey Co Plc <PLY.L> said it had won a +multi-million stg contract to supply Colombia with the System X +digital telephone exchange, the first major export contract for +the system. + Company sources said the deal was worth about 15 mln stg. +v A Plessey statement said the contract, awarded by the +National Telecommunications Authority of Colombia, was won +against competition from Telefon L M Ericsson AB, NEC Corp, +Fujitsu Ltd and Italtel of Italy. + "The award is regarded as a triumph for System X and a +breakthrough in the South American market," it said. + Plessey said the contract was one of the largest awarded by +Telecom Colombia for the past 10 years and involved supplying +13 telephone exchanges including 68,000 lines. + The award also includes transmission equipment for the +interconnection of the exchanges and the existing system. + The firm was actively marketing System X worldwide and +contract negotiations in certain countries had reached an +advanced stage, it said. + Plessey shares were down 5p at 235p, having gone +ex-dividend. + REUTER + + + + 9-MAR-1987 08:46:08.05 + +venezuela + + + + + +A +f0901reute +r f BC-VENEZUELA-REVEALS-DEB 03-09 0113 + +VENEZUELA REVEALS DEBT PAYMENT SCHEDULE DETAILS + CARACAS, March 8 - The 20.3 billion dlr debt rescheduling +accord Venezuela signed a week ago will reduce its payments +over the next three years by 64 pct, according to Finance +Ministry figures released this weekend. + A ministry statistical analysis said while the original +accord called for payments of 3.82 billion dlrs between 1987 +and 1989, the new agreement requires debt servicing of 1.35 +billion over the same period. In 1987, Venezuela will be +required to pay 250 mln dlrs instead of the 1.55 billion +originally agreed. Payments in 1988 were cut to 400 mln from +1.20 billion, and in 1989 to 700 mln from 1.11 billion. + The ministry's analysis said the reduction in debt +servicing during 1987-1989 amounts to an effective grace +period, something the Venezuelan negotiators sought from +creditor banks but were not granted. + Most of the rescheduling falls during 1994-1998, when 53.3 +pct, or some 11.25 billion dlrs, must be paid. Under the +February 27 accord, Venezuela will repay 20.3 billion dlrs of +public sector debt over 14 years at 7/8 of a percentage point +over London interbank offered rates (Libor). + This compares with the February 1986 accord which called +for a 12-year term and interest of 1-1/8 point over Libor. + REUTER + + + + 9-MAR-1987 08:48:26.10 +acq +usa + + + + + +F +f0909reute +r f BC-SOSNOFF-STARTS-BID-FO 03-09 0113 + +SOSNOFF STARTS BID FOR CAESARS WORLD <CAW> + NEW YORK, March 9 - <MTS Acquisition Corp>, a company +formed by Martin T. Sosnoff, said it has started a tender offer +for all shares of Caesars World Inc at 28 dlrs each. + In a newspaper advertisement, MTS said the offer and +withdrawal rights expire April Three unless extended. + Sosnoff, a New York investor, already owns about four mln +of Caesars' 30.3 mln shares outstanding, or about 13.3 pct, and +is Caesars' largest shareholder. Caesars owns casino hotels in +Nevada and honeymoon resorts in Pennsylvania's Pocono +Mountains. It also controls Caesars New Jersey Inc <CJN>, +which owns an Atlantic City, N.J., casino hotel. + For the second quarter ended January 31, Caesars World +earned 12.6 mln dlrs on revenues of 190.4 mln dlrs, up from +earnings of 7,500,000 dlrs and revenues of 163.8 mln dlrs a +year before. For all of fiscal 1986, the company earned 41.0 +mln dlrs on revenues of 694.4 mln dlrs. + MTS said the offer is conditioned on receipt of at least +enough shares to give Sosnoff a majority interest on a fully +diluted basis, the arrangement of sufficient financing to buy +all Caesars shares not already owned and pay related costs and +approval by the New Jersey Casino control Commission and the +NEvada Gaming Commission and State Gaming Control Board. + MTS said Marine Midland Banks Inc <MM> has committed to +lend it 100 mln dlrs for the acquisition and use its best +efforts to syndicate another 400 mln dlrs in senior financing +for the transaction. + It said its financial adviser, PaineWebber Group Inc <PWJ>, +has stated in writing that subject to market conditions, it is +highly confident that it can arrange commitments for up to 475 +mln dlrs in "mezzanine" financing. + MTS said it does not expect problems in obtaining New +Jersey and Nevada regulatory approval for the acquisition, +since ownership in a Caesars stake has already been cleared. + In June 1986, Sosnoff requested a seat on the Caesars World +board, a request that has not yet been granted. In September +1986, Sosnoff, who is chairman of <Atalanta/Sosnoff Capital +Corp>, filed for clearance under U.S. antitrust laws to raise +his interest in Caesars World to 25 pct. + Sosnoff said, in a letter to Caesars World chairman and +chief executive officer Henry Gluck, that "The decision to go +directly to the shareholders was made at the urging of may +financial and legal advisors, who repeatedly stressed to me the +lack of responsiveness of the management in the past." + Sosnoff, who said he has made numerous efforts to express +his views to management on ways of maximizing shareholder +values, said Caesars twicce refused his request for a board +seat. "My advisers felt that, had I given you advance notice, +you would have used the time to throw up obstacles to my offer +rather than giving it serious consideration," he said. + Sosnoff said he hopes that Caesars World management will be +willing to negotiate an acquisition agreement with him. + "As I have indicated publicly in the past, I believe +operating management of the company has performed well and that +appropriate consideration should be given to a significant +equity interest for them in the company following the +acquisition," Sosnoff said in the letter to Gluck. + MTS said Sosnoff has asked the company to fix March 27 as +the record date for the determination of shareholders entitled +to authorize action without a meeting -- including the election +or removal of directors. + Reuter + + + + 9-MAR-1987 08:51:35.60 +gnpjobscpibopdfl +netherlands + + + + + +RM +f0913reute +r f BC-DUTCH-PLANNING-AGENCY 03-09 0104 + +DUTCH PLANNING AGENCY FORECASTS LOWER GROWTH + THE HAGUE, March 9 - Dutch economic growth is slowing as a +firming guilder cuts competitiveness abroad and industries +reduce the pace of investment, the Dutch official planning +agency CPB said. + The Centraal Planbureau, publishing its 1987 economic +outlook, said Dutch Net National Income (NNI) was expected to +grow by one pct this year, down from two pct growth recorded in +1986 and 2.5 pct in 1985 and 1984. + Dutch Gross National Product is expected to rise to 432.20 +billion guilders in 1987 in constant prices, a two pct increase +from last year's 423.95 billion. + The CPB, forecasting an 8.5 pct increase in the value of +the guilder on a trade-weighted basis compared with 10.0 pct +last year, said the dollar was expected to trade at an average +of 2.0 guilders in 1987 compared with 2.45 guilders in 1986. + "The higher guilder is causing a substantial fall in unit +labour costs abroad, when measured in guilder terms, while +these are rising slightly in the Netherlands," the CPB said. + More of economic growth now depended on domestic +consumption, the CPB said, but noting that higher margins set +by domestic producers and importers mitigated the effect on +purchasing power of lower import costs and deflation. + Consumer prices were set to fall by 1.5 pct this year, the +CPB said. Inflation was zero last year. + Gross investment in industry was expected to grow by five +pct this year, a slowdown compared with 11.5 pct growth last +year, the CPB said. + Exchange rate and oil price fluctuations will continue to +condition the Dutch economy in the future as it has in recent +years, the CPB said, noting a continued depressing impact of +these factors on Dutch competitiveness. + In addition, it noted a slight rise in taxation and social +security costs to employers. + The CPB, forecasting a rise in the budget deficit to 7.2 +pct of Net National Income in 1987 from 6.3 pct last year, +urged the government to cut expenditure further to bring down +the deficit and reduce tax and social security payments in +future. + Dutch government revenue is being depressed further by +falling income from natural gas sales in 1987, the CPB said. + It said unemployment was expected to fall to 675,000 this +year from 710,000 last year. + While the two pct GDP growth forecast set by the CPB is +within its latest forecast, issued last month, of 1.5 to two +pct growth, the figure is well above recent market estimates. + Dutch merchant bank Pierson, Heldring en Pierson said in +its February economic outlook that GDP growth at constant +prices was expected to be 1.1 pct this year and market analysts +had expected the CPB's final forecast to be below its own +latest estimate. + "It is too early to comment because I haven't seen the whole +document yet, but it would seem we are more pessimistic in some +of our estimates," a Pierson economist said. + The CPB forecast 2.5 pct export growth in volume terms in +1987, after four pct growth last year. Excluding energy +exports, the 1987 figure would be two pct, it said. + Imports were set to rise by 4.5 pct this year compared with +four pct in 1986 in volume terms, the CPB said. + The balance of payments would see a sharp decline in the +surplus, to six billion guilders in 1987 compared with 12.1 +billion last year, the CPB forecast. + REUTER + + + + 9-MAR-1987 08:51:49.54 +acq +usa + + + + + +F +f0914reute +b f BC-TRUMP-MAKES-BID-FOR-C 03-09 0088 + +TRUMP MAKES BID FOR CONTROL OF RESORTS <RTB> + NEW YORK, March 9 - Casino owner and real estate developer +Donald Trump has offered to acquire all Class B common shares +of Resorts International Inc, a spokesman for Trump said. + The estate of late Resorts chairman James M. Crosby owns +340,783 of the 752,297 Class B shares. + Resorts also has about 6,432,000 Class A common shares +outstanding. Each Class B share has 100 times the voting power +of a Class A share, giving the Class B stock about 93 pct of +Resorts' voting power. + More + + + + 9-MAR-1987 08:54:12.02 +earn +usa + + + + + +F +f0922reute +u f BC-IOMEGA-<IOMG>-SETS-MA 03-09 0096 + +IOMEGA <IOMG> SETS MANAGEMENT, LABOR LAYOFFS + ROY, Utah, March 9 - Iomega Corp said it has laid off over +a quarter of its professional and management staff and nearly +half of its direct labor force as part of a restructuring and +downsizing of its business. + The company also said it will receive a qualified opinion +from the auditors of it 1986 financial statement subject to the +outcome of two suits. The company is a defendant in a +consolidated class action law suit which seeks damages in an +unspecified amount and is also a defendant in a related +shareholder action. + Iomega said the auditors state in their opinion letter that +both actions are in the early stages of discovery and the +likely outcome can not be determined at this time. + The company said a corporate wide reduction of its +professional, management and indirect labor will result in the +permanent elimination of 183 positions in all functional areas +of the company's business. This represents over 25 pct of +professional, management and indirect employees, it added. + In addition, Iomega announced layoff of about 182 +employees, principally from its manufacturing direct labor +force. Those affected represent about 46 pct of direct labor. + Commenting on the layoffs, Iomega said those from among the +direct labor force affects personnel building the Alpha Eight +Inch Disk Drive and Bernoulli Boxes. + "This action is required as we bring our finished goods +inventory and inventory in our distribution channels down to +acceptable levels," it explained. + The company stated this layoff does not affect the +production of its new 5-1/4 inch Beta 20 product which is +currently being built to a backlog of orders. + Reuter + + + + 9-MAR-1987 08:58:22.38 + +usa + + + + + +F +f0942reute +d f BC-TECHNOLOGY/NEW-ERA-FO 03-09 0109 + +TECHNOLOGY/NEW ERA FOR INFORMATION HANDLING + By Lawrence Edelman, Reuters + NEW YORK, March 9 - Ground-breaking new systems for storing +and retrieving information are ushering in a new era for +computer companies and computer users. + Within the past few weeks, International Business Machines +Corp <IBM>, Eastman Kodak Co <EK> and others have launched +products that radically increase the amount of data that can be +catalogued and shelved in computerized libraries. + "This flurry of new technology could yield systems that +handle a multimedia blitz of data," said Ian Warhaftig, a +senior analyst with International Data Corp, Framingham, Mass. + "We're developing new systems because our customers are +asking for them," Peter Giles, vice president and general +manager of Kodak's mass memory division, said in a recent +interview. + This demand is expected to soar in coming years. While +estimates vary, industry analysts project that providing +products and services geared for information storage and +retrieval could become a 20 billion dlr a year business by +1995. + A wide range of technologies will be needed to meet the +varying requirements of users. + For example, a large credit verification service would want +a system from which it could quickly retrieve credit data and +relay it to its clients. A law firm, however, may need a +computerized law library in which capacity, rather than speed, +is the key feature. For architects and engineers, the ability +to store photographs, sketches and other graphics would be +crucial. + Regardless of the specific application, the trend is toward +converting information - documents, video or film or even sound +recordings - into to the digital language of zeros and ones +understood by computers. + Saving space is the key goal in digitizing data for +storage. An optical disk the size of a standard compact disk +can store 550 megabytes of data, or about 250,000 pages of +typewritten text. + For this reason, the compact disk read-only memory, or +CD-ROM, is already a popular data storage media. Last week, +Microsoft introduced Microsoft Bookshelf, a 300 dlr program +that contains, on a single CD-ROM disk, a dictionary, +thesaurus, national ZIP code directory, Bartlett's Familiar +Quotations, the World Almanac and other reference works. + Scores of such products are already on the market, but most +are specialty items, such as Lotus Development Corp's <LOTS> +CD-ROM data base of stock information for financial analysts +and investors. "Microsoft Bookshelf is important because it +marks the arrival of CD-ROM packages for the general public," +said Ian Warhaftig of International Data Corp. + One drawback of the CD-ROM, which uses a laser to record +and read data, is that that it requires a special player. +CD-ROM players for the retail market will appear later this +year. + Moreover, IDC's Warhaftig said CD-ROM's will be integrated +with personal computers. + "Eventually, CD-ROM's will fit right inside the PC box," he +said. "Imagine the advantage of having a spelling checker and +thesaurus at your fingertips when you're writing with a word +processing program." + But CD-ROM's are just the beginning. Also last week, Kodak +unveiled several systems that use 12-inch optical disks. The +largest Kodak system uses a jukebox-like cabinet to hold up to +150 optical disks from which data can be retrieved in a matter +of seconds. + Kodak also announced a 14-inch optical disk with 6.8 +gigabytes of memory, five times the memory of a CD-ROM. The +Kodak disk, which will not be available until the middle of +1988, is designed for users who need quick access to very large +amounts of data, said Kodak's Giles. + Meanwhile, N.V. Philips <PGLO.AS>, the Dutch electronics +giant, is preparing to take optical disk technology a step +further with the first disk that can combine text, video and +sound. Philips said the system, called Called CD-Interactive, +will be ready next year. It will include a new kind of CD-ROM +player that can hook up with a television set and stereo. + Additional breakthroughs are expected as the next +generation of computer memory chips are introduced. Last month +IBM said it has made a four-megabyte chip, capable of storing +more data than eight CD-ROM's. Meantime, <Nippon Telegraph and +Telephone> of Japan said it has built a 16-megabyte chip. + Analysts say commercial versions of these chips are several +years away, though some suspect that IBM may start volume +production of its four-megabyte chip sometime this year. + Such chips will enable computer makers to build computers +with immense memory capacities. + + Reuter + + + + 9-MAR-1987 09:01:34.94 +ship +brazil + + + + + +C G L M T +f0951reute +u f BC-BRAZIL-SEAMEN-CONTINU 03-09 0114 + +BRAZIL SEAMEN CONTINUE STRIKE DESPITE COURT + RIO DE JANEIRO, March 9 - Hundreds of marines were on alert +at 11 key Brazilian ports after 40,000 seamen decided to remain +on indefinite strike, even after the Higher Labour Court +Saturday ruled it illegal, union leaders said. + The halt, the first national strike by seamen in 25 years, +started on February 27, and union leaders said they would not +return to work unless they got a 275 pct pay rise. Shipowners +have offered a 100 per cent raise, which the seamen rejected. + "We have nothing to lose. If they want to lay off the +workers, fine, but we are determined to carry on with our +protest until the end," a union leader said. + more + He said they had decided in a meeting that if the marines +take over the ships, the seamen would abandon the vessels and +let the marines handle the situation by themselves. + A spokesman for the Rio de Janeiro Port said the order to +send marines to take over the ports was given by Navy Minister +Henrique Saboya on grounds that ports are areas of national +security. But he said there were no incidents. The strike has +cut exports and imports and made an estimated 160 ships idle. + Petrol station owners in four states also continued their +shutdown and there were fears that the combination of the two +stoppages could lead to a serious fuel shortage. + Reuter + + + + 9-MAR-1987 09:06:39.94 + +usa + + + + + +F A +f0971reute +r f BC-BANKING-TRADE-GROUP-S 03-09 0098 + +BANKING TRADE GROUP SAYS BANK PROFITS DOWN + WASHINGTON, March 9 - The American Bankers Association said +the profitability of the nation's commercial banks declined by +12 pct during the first three quarters of 1986. + During the first nine months of last year, the industry's +annualized rate of return on assets dropped to 0.68 pct from +0.77 pct in the same period in 1985, the ABA said. Return on +equity fell to 10.8 pct from 12.3 pct the previous year. + Despite the decline in profits, the ABA said banks' capital +grew boosting the industry's capital ratio to 6.4 pct from 6.3 +pct. + The number and size of banks losing money during the period +increased significantly, the ABA said. + During the first nine months of 1986, 17.5 pct of banks, +holding 9.6 pct of banking assets, were unprofitable, the group +said. That compares with 13 pct of banks, holding 8.8 pct of +assets, during the same period in 1985, it said. + The industry's provisions for loan losses increased to 0.73 +pct of assets during the period, up from 0.59 pct of assets +during the same period in 1985, the group said. + Reuter + + + + 9-MAR-1987 09:08:09.30 + +usa + + + + + +F +f0975reute +r f BC-PAPER-INSTITUTE-SEES 03-09 0074 + +PAPER INSTITUTE SEES STRONG PAPER MARKET IN '87 + NEW YORK, March 9 - The American Paper Institute said the +industry is headed for another year of record volume in 1987, +with linerboard particularly strong. + "A pro-growth trade policy, continued attention to currency +management, a fairly low interest rate climate and no major tax +increases are the essential ingredients in this outlook," Red +Cavaney, American Paper Institute president said. + Cavaney said that so far this year the industry's +performance mimics last year's strength. + Last year, he said, paper and paperboard production hit a +record 71 mln tons, 5.9 pct above 1985's 67 mln tons, while +industry after-tax profits in 1986 exceeded 1985 profits. + Cavaney said that inventories will play a major role in +this year's performance. + "Inventories, which are generally low, are a positive +factor in the industry's outlook this year," he said, citing +market pulp stocks, which are currently at 21 days supply, at +the low end of the industry's long term average. + Cavaney added that as a result of slimmer inventories in +1986 and in the early part of this year, shipments for 1987 as +a whole will be higher than last year, even if demand slackens. + Cavaney said, however, he expects demand this year to be +strong, spurred by consumer spending. + The benefits of tax reform on individual after-tax income +and consumer goods companies' cash flow, he said, will increase +demand for both communications paper and packaging this year. + In addition, Cavaney said low mortgage rates should support +high levels of housing starts in 1987, increasing demand for +many kinds of packaged goods. + Inventory building should help demand for cartons and +corrugated containers this year, he added. + Cavaney said he expects exports to remain fairly high in +1987, as well, as a result of the recent declines in the dollar +against major world currencies. + But more importantly, he said, an improved balance of trade +in 1987 from the lower dollar would induce increased industrial +activity at home and thus higher packaging demand. + Cavaney said increased competitiveness, caused by lower +costs, higher productivity and improved efficiency would also +contribute to a strong showing from the industry this year. + Cavaney said, however, that the Tax Reform Act of 1986 +could have a negative impact on the industry this year. + "For manufacturers, the removal of the investment tax +credit creates an impediment to future investment," he said. + Also, he said API estimates the industry will lose three +billion dlrs in cash flow over a five year period as a result +of reforms. + "Adjustments to this loss will require time and careful +evaluation and will adversely affect the capital spending +decisions of individual companies," Cavaney said. + Reuter + + + + 9-MAR-1987 09:11:10.46 +money-fxgnp +belgiumwest-germany + +ec + + + +RM +f0984reute +r f BC-BONN-SERIOUS-ABOUT-CU 03-09 0090 + +BONN SERIOUS ABOUT CURRENCY PACT, SAYS TIETMEYER + BRUSSELS, March 9 - West Germany takes "very seriously" the +recent undertaking by major industrial countries to promote +exchange rate stability around current levels, Finance Ministry +State Secretary Hans Tietmeyer said. + Talking to journalists before a meeting of European +Community Economy and Finance Ministers here, Tietmeyer +declined to say whether the February 22 Paris accord by the +Group of Five countries plus Canada included secret agreements +for stabilising currencies. + But he noted the official communique said the participants +agreed to cooperate closely to foster stability of exchange +rates around current levels. "We're taking this sentence very +seriously," he said. + Tietmeyer remarked that the dollar had hardly moved against +the mark since the meeting. + He said a slowdown in West German economic growth had been +caused by sharp exchange rate swings and that the Paris +agreement should help in this respect. + Economics Ministry State Secretary Otto Schlecht said the +Bonn government saw no current need for measures to bolster the +economy but was paying close attention to the slower growth and +had not ruled out "appropriate and timely" action if necessary. + Schlecht and Tietmeyer were speaking ahead of a discussion +by the EC ministers of the latest EC Commission report on the +economic situation in the 12-nation bloc. + The Commission has sharply revised down expected German +gross national product growth this year to two pct from 3.2 pct +predicted last autumn and says Bonn has the most room of any EC +country to stimulate economic activity. + Schlecht said the upturn in West Germany's economy slowed +in the fourth quarter of last year and the first quarter of +1987. But he said there was no cumulative downwards trend in +view that would make quick remedial action necessary. + He said a number of favourable indicators such as high +level of investment and a good climate for consumption meant a +recovery could be expected, while exports would pick up +slightly during the course of the year. + REUTER + + + + 9-MAR-1987 09:11:41.38 + +saudi-arabia + + + + + +RM +f0986reute +r f BC-SAUDI-FRENCH-BANK-TO 03-09 0109 + +SAUDI-FRENCH BANK TO DOUBLE PAID-UP CAPITAL + JEDDAH, March 9 - <Al Bank Al Saudi Al Fransi>, also known +as Saudi-French, will double paid-up capital to 400 mln riyals +from 200 mln by converting reserves into equity, bank officials +said. + Jeddah-based Saudi-French, 40 pct owned by Banque Indosuez +and 60 pct by the Saudi public, will sign a technical services +agreement with Indosuez in Riyadh on Tuesday for management of +the bank over the next five years, they said. + The officials said the increase in paid-up capital, +doubling the number of shares held by shareholders, will add +depth to the market and extend trading to more investors. + REUTER + + + + 9-MAR-1987 09:12:08.15 + +usa + + + + + +F +f0988reute +u f BC-COMPAQ-COMPUTER-<CPQ> 03-09 0031 + +COMPAQ COMPUTER <CPQ> HAS NEW DESKTOP COMPUTER + HOUSTON, March 9 - Compaq Computer Corp said it has +introduced a new 12 megahertz desktop personal computer called +the Compaq Deskpro 286R. + More + + + + 9-MAR-1987 09:12:30.97 +coffee +uganda + +ico-coffee + + + +T C +f0990reute +u f BC-UGANDA-DISAPPOINTED-B 03-09 0129 + +UGANDA DISAPPOINTED BY COFFEE TALKS FAILURE + KAMPALA, March 9 - Uganda, Africa's second largest coffee +producer, was disappointed by the stalemate in recent coffee +talks in London, the chairman of the state-run Coffee Marketing +Board, CMB, said. + "This has not been good for coffee producers, more so in a +situation where the prices dropped by 200 pounds per tonne of +robusta coffee," J. Makumbi said when he returned from London on +Friday. + Producers and consumers failed to agree on a quota formula +to share the world's coffee production during International +Coffee Organisation, ICO, talks that ended last week. + Makumbi blamed the failure to set quotas, which were +suspended in Feburary last year, on Indonesian demands that its +quota be increased dramatically. + Uganda -- which earns about 400 mln dlrs annually from +coffee exports, over 95 pct of its foreign exchange earnings -- +had sought to raise its ICO quota to 3.0 mln from 2.45 mln +60-kilo bags, according to sources close to the CMB. + The CMB has estimated that production will rise 20 to 25 +pct in the current 1986/87 October-September season to over +three mln bags. + For several years Uganda had been unable to meet its ICO +export quota as rebel activity disrupted the coffee industry. + The Ugandan government depends on coffee export duties for +about 60 pct of its sales tax revenue and the industry employs +over half of salaried manpower. + In Dar es Salaam, Tanzania's Agriculture and Livestock +Development Minister Paul Bomani said today Third World +countries would suffer from the failure of the London coffee +talks. + "It is only the middlemen who will benefit, he said. + Bomani called on the ICO to convene another meeting within +two months, saying, "Once tempers have cooled and delegations +have had time to report back to their headquarters, common +sense will prevail." + Reuter + + + + 9-MAR-1987 09:17:04.78 +acq + + + + + + +F +f0001reute +f f BC-Chrysler-to-take-over 03-09 0012 + +****** Chrysler to take over Renault stake in American Motors, says Renault +Blah blah blah. + + + + + + 9-MAR-1987 09:17:44.88 +meal-feed +usahungary + + + + + +C G +f0005reute +r f BC-ADDITIONAL-CCC-CREDIT 03-09 0127 + +ADDITIONAL CCC CREDIT GUARANTEES FOR HUNGARY + WASHINGTON, March 9 - The Commodity Credit Corporation, +CCC, has authorized an additional 8.0 mln dlrs in credit +guarantees for sales of vegetable protein meals to Hungary for +fiscal year 1987, the U.S. Agriculture Department said. + The additional guarantees increase the vegetable protein +meal credit line to 16.0 mln dlrs and increases the cumulative +fiscal year 1987 program for agricultural products to 23.0 mln +dlrs from 15.0 mln, it said. + The department also announced an extension of the export +period from September 30, 1987, to December 31 for sales of +vegetable protein meals. + To be eligible for the credit guarantees all sales must be +registered before export but not later than September 30. + Reuter + + + + 9-MAR-1987 09:20:38.92 +earn + + + + + + +F +f0010reute +b f BC-******southern-co-to 03-09 0012 + +******SOUTHERN CO TO TAKE 226 MLN DLR CHARGE ON PROJECTED VOGTLE COST RISE +Blah blah blah. + + + + + + 9-MAR-1987 09:21:19.67 +acq +usa + + + + + +F +f0014reute +r f BC-APPLIED-CIRCUIT<ACRT> 03-09 0091 + +APPLIED CIRCUIT<ACRT> SELLS ELECTRONICS BUSINESS + ANAHEIM, Calif., March 9 - Applied Circuit Technology Inc +(ACT) said it has agreed in principal to sell its primary +computer electronics business to the <Sanpao Group> of San +Francisco. + ACT said it has not disclosed the deal's terms, but added +that 50 pct of the sale price is in cash, with the remainder to +be paid over a two year period. + The deal is expected to close on March 31, ACT said. + ACT said it made the move to concentrate resources on its +pharmaceuticals subsidiaries. + Reuter + + + + 9-MAR-1987 09:24:32.21 +acq +usa + + + + + +F +f0030reute +u f BC-USAIR-<U>-ACQUIRES-9. 03-09 0107 + +USAIR <U> ACQUIRES 9.9 PCT OF PIEDMONT <PIE> + WASHINGTON, D.C., March 9 - USAir Group Inc said it has +acquired 2,292,599 Piedmont Aviation Inc shares, about 9.9 pct +on a fully diluted basis, from Norfolk Southern Corp <NSC>. + The acquisition of Piedmont by USAir has been approved by +the directors of both companies. + USAir said it has been advised by Norfolk Southern that the +company supports the proposed merger and intends to tender all +of its remaining 1,477,829 Piedmont common shares in response +to USAir's tender offer which began today. This total includes +shares issuable upon conversion of Piedmont preferred, USAir +noted. + USAir said Piedmont has about 23.1 mln common shares on a +fully diluted basis, adding its offer is conditioned on the +tender of at least 9,309,394 shares, representing 40.2 pct of +the oustanding shares on a diluted basis. + USAir said the 3,491,030 new shares it has an option to buy +represent 18.5 pct of Piedmont's currently outstanding shares. + Reuter + + + + 9-MAR-1987 09:25:10.00 +coffee +brazil + + + + + +T C +f0031reute +r f BC-BRAZILIAN-COFFEE-RAIN 03-09 0059 + +BRAZILIAN COFFEE RAINFALL + SAO PAULO, MARCH 9 - THE FOLLOWING RAINFALL WAS RECORDED IN +THE AREAS OVER PAST 72 HOURS + PARANA STATE: UMUARAMA NIL, PARANAVAI 1.5 MILLIMETRES, +LONDRINA NIL, MARINGA NIL. + SAO PAULO STATE: PRESIDENTE PRUDENTE O.6 MM, VOTUPORANGA +12.0 MM, FRANCA 28.0 MM, CATANDUVA 10.0 MM, SAO CARLOS NIL, SAO +SIMAO NIL. REUTER11:43/VB + + + + 9-MAR-1987 09:25:41.63 +acq + + + + + + +F +f0033reute +f f BC-******GENCORP-TO-SELL 03-09 0011 + +******GENCORP TO SELL LOS ANGELES TELEVISION STATION TO WALT DISNEY CO +Blah blah blah. + + + + + + 9-MAR-1987 09:26:28.51 +acq +usa + + + + + +F +f0035reute +d f BC-NATIONWIDE-CELLULAR-< 03-09 0073 + +NATIONWIDE CELLULAR <NCEL> COMPLETES PURCHASE + VALLEY STREAM, N.Y., March 9 - Nationwide Cellular Service +Inc said it has completed the previously-announced acquisition +of privately-held Nova Cellular Co, a Chicago reseller of +mobile telephone service with 1,800 subscribers, for about +65,000 common shares. + Nova Cellular has an accumulated deficit of about 650,000 +dlrs and had revenues of about 2,600,000 dlrs for 1986, it +said. + Reuter + + + + 9-MAR-1987 09:27:57.44 +interest +uk + + + + + +C G T M +f0038reute +u f BC-NATIONAL-WESTMINSTER 03-09 0092 + +NATIONAL WESTMINSTER BANK CUTS BASE RATE + LONDON, March 9 - National Westminster Bank Plc said it has +cut its base lending rate 0.5 percentage points to 10.5 pct +today. + National Westminster said it was responding to general +easing in money market rates. + Its move followed a signal from the Bank of England earlier +this afternoon that it would endorse a half point cut in the +base rate, a surprise move following its strong signals last +week that such a move would be premature. + However, since then the pound has continued to gain +strongly. + Reuter + + + + 9-MAR-1987 09:30:35.65 +money-fxinterest +uk + + + + + +RM +f0039reute +b f BC-U.K.-MONEY-MARKET-GIV 03-09 0096 + +U.K. MONEY MARKET GIVEN FURTHER HELP AT NEW RATES + LONDON, March 9 - The Bank of England said it provided the +market with further assistance during the afternoon, buying +bills worth 166 mln stg at the lower rates introduced this +morning. + It bought 45 mln stg of local authority bills plus 27 mln +stg of bank bills in band one at 10-3/8 pct together with 94 +mln stg of band two bank bills at 10-5/16 pct. + The bank also revised its estimate of the market shortage +up to 300 mln stg from 250 mln this morning. It has given total +assistance of 213 mln stg today. + REUTER + + + + 9-MAR-1987 09:30:53.98 + +usa + + +cbtcme + + +C +f0040reute +u f BC-CBT,-CME-HEADS-TO-ADD 03-09 0125 + +CBT, CME HEADS TO ADDRESS CFTC COMMITTEE + WASHINGTON, March 9 - The heads of the Chicago Board of +Trade, CBT, and the Chicago Mercantile Exchange, CME, are to +address a meeting of the Commodity Futures Trading Commission's +financial products advisory committee March 11 in Chicago, CFTC +said. + CBT Chairman Karsten Mahlmann will present the objectives +and views of the CBT's ad hoc committee on off exchange trading +issues, CFTC said. + CME President William Brodsky is set to discuss current +issues involving equity index markets, including factors +affecting price volatility, changes in settlement procedures, +margin changes and price limits. + The CFTC committee, headed by Commissioner Robert Davis, +examines financial futures market issues. + Reuter + + + + 9-MAR-1987 09:31:21.09 +ship +hong-kongjapan + + + + + +F +f0043reute +r f BC-HUTCHISON-UNIT-BUYS-C 03-09 0075 + +HUTCHISON UNIT BUYS CONTAINER CRANES FROM JAPAN + HONG KONG, March 9 - Container port operator, <Hong Kong +International Terminals Ltd>, a 89 pct held unit of Hutchison +Whampoa Ltd <HWHH.HK>, said it has placed a 164 mln H.K. Dlr +order for seven quayside container cranes of 800 tons each with +Japan's Mitsui Engineering and Shipbuilding Co Ltd <MSET.T> for +May 1988 to August 1989 delivery. + Hong Kong International Terminals operates 32 cranes. + REUTER + + + + 9-MAR-1987 09:32:01.67 +ship +turkey + + + + + +C G T M +f0046reute +d f BC-BOSPHORUS-SHIPPING-MO 03-09 0111 + +BOSPHORUS SHIPPING MOVES, ISTANBUL OFFICES CLOSE + ISTANBUL, March 9 - Istanbul remained at a virtual +standstill today under snow up to a meter deep but shipping was +moving through the narrow Bosphorus waterway linking the Sea of +Marmara and the Black Sea, officials said. + The authorities ordered government offices closed until +Wednesday. Many banks, businesses and schools stayed shut as +workers struggled to keep main roads and supply lines open in +this city of 6.5 mln people. + The second blizzard to hit Istanbul in a week stopped +yesterday afternoon and the international airport reopened +today after a two-day closure. It was also shut earlier last +week. + Reuter + + + + 9-MAR-1987 09:32:40.79 +crude +ecuador + +opec + + + +V +f0048reute +u f BC-ECUADOR-TO-EXPORT-NO 03-09 0113 + +ECUADOR TO EXPORT NO OIL FOR 4 MONTHS, OFFICIAL + By WALKER SIMON, Reuters + QUITO, March 9 - The suspension of Ecuador's crude oil +shipments after an earthquake cut an oil pipeline will last at +least four months, a senior Energy Ministry official said. + The official said Ecuador could resume exports after +repairing a 40 km section of the 510 km pipeline, which links +jungle oil fields at Lago Agrio to Balao on the Pacific coast. +It would take about 100 mln U.S. Dlrs to repair the pipeline, +the official, who did not want to be named, told Reuters. +Ecuador had enough oil to meet domestic demand for about 35 +days and would have to import crude to supplement stocks. + The earthquake last Thursday night registered six on the +12-point international Mercalli scale. The damage to the +pipeline was a severe economic blow to Ecuador, where oil +accounts for up to two-thirds of total exports and as much as +60 pct of government revenues. + Financially pressed Ecuador, a member of the Organisation +of Petroleum Exporting Countries (OPEC), was recently pumping +about 260,000 barrels per day (bpd) of crude, about 50,000 bpd +above the output quota assigned by the cartel, another Energy +Ministry spokesman said. Last year, it exported an average of +173,500 bpd, according to the central bank. + However, Ecuador might build an emergency 25 km pipeline, +costing 15 to 20 mln dlrs, to hook up with a Colombian +pipeline, the first official said. He estimated it could take +about 60 days to build. + Ecuador, squeezed by the slide in world oil prices in 1986, +had only 138 mln dlrs in net international reserves at the end +of January, about equal to one month's imports. + It suspended interest payments in January on 5.4 billion +dlrs owed to about 400 private foreign banks. The country's +total foreign debt is 8.16 billion dlrs, the eighth largest in +Latin America. + In Caracas, President Jaime Lusinchi said Venezuela would +loan five mln barrels of crude to Ecuador over the next three +months to make up for losses from damage to the pipeline. + Ecuador asked for the loan to guarantee domestic supplies +and would ship an equivalent volume back to Venezuela in +repayment in May, Lusinchi said. + A commission headed by Venezuelan Investment Fund Minister +Hector Hurtado and including representatives from the interior +and defence ministries and the state oil company Petroleos de +Venezuela will travel to Ecuador Tuesday to evaluate and +co-ordinate an emergency relief program, he said. + REUTER + + + + 9-MAR-1987 09:33:35.86 +money-supply +france + + + + + +RM +f0056reute +f f BC-FRENCH-JAN-M-3-MONEY 03-09 0015 + +******FRENCH JAN M-3 MONEY SUPPLY ROSE PROV ADJUSTED ONE PCT (O.7 PCT FALL IN DEC) - OFFICIAL. +Blah blah blah. + + + + + + 9-MAR-1987 09:35:55.99 + +greeceitaly + + + + + +C G T M +f0067reute +d f PM-GREECE-BLIZZARDS 03-09 0109 + +HEAVY SNOWS HIT GREECE, ITALY + ATHENS, March 9 - Blizzards lashed Greece today, piling up +to 10 feet of snow in places and paralyzing transport in what +state radio called unprecedented weather conditions for this +time of year. + Except for a handful of flights of the national airline +Olympic Airways that took off before the blizzards started, all +air traffic in and out of the Athens international airport was +canceled, radio said. + The weather service said heavy snowfalls would continue for +several hours. + Cold weather also hit southern and eastern Italy. Heavy +snowfalls caused long delays and difficulties for road, rail +and air traffic. + Reuter + + + + 9-MAR-1987 09:39:30.30 +rubber +malaysia + + + + + +T +f0080reute +r f BC-MALAYSIA-SAYS-RUBBER 03-09 0138 + +MALAYSIA SAYS RUBBER PACT DEPENDS ON CONSUMERS + KUALA LUMPUR, March 9 - Malaysia said the success of talks +opening today on a new International Natural Rubber Agreement +(INRA) depends on how flexible consumer countries are. + Rubber producer and consumer countries meet for 12 days in +Geneva from tomorrow to try to hammer out a rubber pact after +they failed to reach agreement last November to replace the +current accord, which expires next October. + Primary Industries Minister Lim Keng Yaik said in a +statement that Malaysia wants to continue with a second INRA +and is prepared to accept modifications that would strengthen +the present agreement. + He said the second INRA would allow for an orderly disposal +of the accumulated buffer stock of 375,000 tonnes, since the +market is now capable of absorbing such releases. + Reuter + + + + 9-MAR-1987 09:39:45.70 + +sweden + + + + + +RM +f0081reute +u f BC-PHARMACIA-AB-LAUNCHES 03-09 0115 + +PHARMACIA AB LAUNCHES EUROCOMMERCIAL PAPER PROGRAMME + STOCKHOLM, March 9 - Pharmacia AB said it was launching a +200 mln dlr Eurocommercial paper programme as part of a move to +internationalise the company's financing. + Market makers will be Credit Suisse First Boston, Morgan +Stanley International and Svenska Handelsbanken PLC. + Pharmacia treasurer Bertil Tiusanen said gaining direct +access to the short term international capital market would +improve its ability to meet its dollar borrowing requirement. + He said it was a natural step for an internationally known +company whose shares are noted in Tokyo and Stockholm and are +traded over the counter in the United States. + REUTER + + + + 9-MAR-1987 09:40:54.41 +acq +usa + + + + + +F +f0084reute +u f BC-MCDOWELL-<ME>-TO-MERG 03-09 0103 + +MCDOWELL <ME> TO MERGER WITH <INTERPHARM INC> + NASHVILLE, Tenn., March 9 - McDowell Enterprises Inc said +it has signed a definitive agreement to acquire an 80 pct +interest in privately held Interpharm Inc for a 19.9 pct +interest in McDowell. + The company said subject to contigencies, including future +sales and profit levels, McDowell could over a four-year period +acquire 100 pct of Interpharm in exchange for up to 51 pct of +McDowell's voting stock. + It said the transaction is expected to be completed within +60 days, at which time the McDowell board would be restructured +to include Interpharm management. + Reuter + + + + 9-MAR-1987 09:41:09.67 + +usa + + + + + +F +f0085reute +r f BC-FEDERAL-HOME-MORTAGE 03-09 0108 + +FEDERAL HOME MORTAGE BUYS FUNDS FROM LENDER + CHARLOTTE, N.C., March 9 - The Federal Home Mortgage Corp +announced the sale of 400 mln dlrs for residential mortgages to +First Union Corp's mortgage subsidiary. + Freddie Mac said that First Union Mortgage Corp already +swapped 70 mln dlrs of new residential mortgages to Freddie Mac +in the first phase of the contract. + Freddie Mac said buy selling 400 mln dlrs worth of +mortages, it makes more mortgage money available. It said +through its guarantor program, First Union will be allowed to +convert its investment-quality mortgages into mortgage-backed +securities accepted in capital markets. + Freddie Mac explained that the securities can be used as +collateral for borrowings, sold to other investors, or employed +in a variety of cash management techniques. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-004.sgm b/src/test/data/reuters-21578/reut2-004.sgm new file mode 100644 index 00000000000..db8e4a71617 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-004.sgm @@ -0,0 +1,2023 @@ + + +11-MAR-1987 18:04:17.59 + +canada + + + + + +M +f0849reute +d f BC-INCO-SEES-NO-MAJOR-IM 03-11 0133 + +INCO SEES NO MAJOR IMPACT FROM DOW REMOVAL + TORONTO, March 11 - Inco Ltd said it did not expect its +earlier reported removal from the Dow Jones industrial index to +make a major impact on the company's stock. + "We don't think that individuals or institutions buy our +shares because we were one of the Dow Jones industrials," +spokesman Ken Cherney said in reply to a query. + Inco closed 1-3/8 lower at 19-3/8 in second most active +trading on the Toronto Stock Exchange. + The Wall Street Journal, which selects the index, said Inco +was dropped to make the index more representative of the +market. Inco, the non-Communist world's largest nickel +producer, was a member of the index since 1928. + Replacing Inco and Owens-Illinois Inc will be Coca-Cola Co +and Boeing Co, effective tomorrow. + Nickel analyst Ilmar Martens at Walwyn Stodgell Cochran +Murray Ltd said Inco's removal from the index would likely +spark short-term selling pressure on the stock. + "Some investors who have Inco may suddenly say, 'well, +because it's not now a Dow stock, we should eliminate that +investment,'" said Martens, although he added the move was +unlikely to have a serious long-term impact on Inco stock. + Inco has struggled in recent years against sharply lower +nickel prices. Its net earnings fell to 200,000 U.S. dlrs in +1986 from 52.2 mln dlrs the previous year. + Reuter + + + +11-MAR-1987 18:06:47.22 + +usa + + + + + +F +f0852reute +d f BC-FORMER-EMPIRE-OF-CARO 03-11 0107 + +FORMER EMPIRE OF CAROLINA <EMP> EXEC SENTENCED + NEW YORK, March 11 - Mason Benson, former president and +chief operating officer of Empire of Carolina Inc, a toy maker, +today was sentenced in Manhattan federal court to a year and +one day in jail for his involvement in a kickback scheme. + Benson pleaded guilty to charges of conspiracy, tax +evasion, filing false corporate tax returns and defrauding the +company's shareholders. He was also fined 5,000 dlrs. + Benson was charged with demanding kickbacks from sales +representatives who were asked to turn over a portion of their +commisisons as a condition for doing business with Empire. + Reuter + + + +11-MAR-1987 18:09:39.66 + +usa + + + + + +F +f0856reute +h f AM-AIDS 03-11 0095 + +DOCTORS FIND LINK BETWEEN AIDS, SMALLPOX VIRUS + BOSTON, March 11 - In a discovery that could complicate the +search for an AIDS vaccine, a team of U.S. Army doctors said +they have uncovered a potentially-fatal interaction between the +AIDS virus and a virus used to protect against smallpox. + Physicians at the Walter Reed Army Institute of Research +said a 19-year-old man, who apparently had been exposed to the +AIDS virus, developed a pox-like disease and died after +receiving the smallpox vaccine. The military now tests recruits +for AIDS before vaccinating them. + The findings, reported in The New England Journal of +Medicine, are significant because scientists have begun working +on an AIDS vaccine that relies on the smallpox vaccine. + "Our case report raises provocative questions concerning +the ultimate safety of such vaccines," said the group led by +Dr. Robert Redfield. + The report also throws into question the belief held by +some scientists that the smallpox vaccine, which exposes people +to a milder, protective form of the disease known as cowpox, +could be further modified to protect people against a host of +other diseases. + Reuter + + + +11-MAR-1987 18:13:59.93 + +usa + + + + + +F +f0860reute +d f AM-CANCER 03-11 0107 + +BIRTH CONTROL PILLS HELP PREVENT CANCER - STUDY + BOSTON, March 11 - Doctors at the Centers for Disease +Control in Atlanta said they have new evidence that birth +control pills can help provide long-term protection from cancer +of the ovary, even if the pills are only taken for a few +months. + The study, reported in the New England Journal of +Medicine, also found that all the various types of oral +contraceptives on the market were equally effective in lowering +the rate of ovarian cancer. + The researchers estimated that the use of birth control +pills in this country probably prevented about 1,700 cases of +ovarian cancer in 1982. + As more and more women who have taken oral contraceptives +"move into the age groups that are at highest risk for +epithelial ovarian cancer we may witness a declining incidence +of this serious disease," they said. + Specifically, the team led by Dr. Howard Ory found that +"oral contraceptive use, even for a few months, reduces the +risk of epithelial ovarian cancer by 40 percent for women 20 to +54 years of age. + "The effect probably takes from five to ten years to +become apparent, but it persists long after the use of oral +contraceptives ends. Moreover, protection exists regardless of +the formulation of oral contraceptive used," they said. + Reuter + + + +11-MAR-1987 18:14:49.93 +interestretailipi +usa + + + + + +RM C +f0861reute +u f BC-fin-futures-outlook 03-11 0103 + +U.S. ECONOMIC DATA KEY TO DEBT FUTURES OUTLOOK + By Brad Schade, Reuters + CHICAGO, March 11 - U.S. economic data this week could be +the key in determining whether U.S. interest rate futures break +out of a 3-1/2 month trading range, financial analysts said. + Although market expectations are for February U.S. retail +sales Thursday and industrial production Friday to show healthy +gains, figures within or slightly below expectations would be +positive for the market, the analysts said. + "You have to be impressed with the resiliency of bonds +right now," said Smith Barney Harris Upham analyst Craig +Sloane. + Treasury bond futures came under pressure today which +traders linked to a persistently firm federal funds rate and a +rise in oil prices. However, when sufficient selling interest +to break below chart support in the June contract failed to +materialize, participants who had sold bond futures early +quickly covered short positions, they said. + "Everyone is expecting strong numbers, and if they come in +as expected it won't be that bad for the market," Sloane said. + Sloane said the consensus estimate for the non-auto sector +of retail sales is for a rise of 0.6 to 0.7 pct. + Dean Witter analyst Karen Gibbs said a retail sales figure +below market forecasts would give a boost to debt futures, and +she put the range for the non-auto sector of retail sales at up +0.8 to 1.2 pct. + Industrial production and the producer price index Friday +both are expected to show increases of about 0.5 pct, she +added. + Retail sales "will tell us whether or not we will be able +to fill the gap," Gibbs said, referring to a chart gap in June +bonds between 100-26/32 and 101-3/32 created Friday. June bonds +closed at 100-4/32 today. + Also key to debt futures direction, in addition to the +federal funds rate, is the direction of crude oil prices, said +Carroll McEntee and McGinley Futures analyst Brian Singer. + "A higher fed funds rate and firm oil prices precluded the +market from breaking out of the trading range the last time the +market approached the top of the range," Singer said. + In order for bonds to break above the top of the range, +which is just below 102 in the June contract, "the crude oil +rally needs to run its course and pull back a little bit," +Singer said. "Fed funds are already easing back down toward the +six pct level." + The recent surge in oil prices has also been a concern to +Manufacturers Hanover Futures analyst Jim Rozich, but the rally +may be nearing a top around 18.50 dlrs per barrel, he said. + Rozich said he is looking for the June bond contract to +ease to 99-6/32 and find support. + "I'm not quite ready to jump on the bullish bandwagon yet. +The jury is still out this week," Rozich said. + Reuter + + + +11-MAR-1987 18:15:09.97 + +usa + + + + + +C G L M T +f0863reute +d f AM-AID 03-11 0106 + +U.S. "ACTION PROGRAM" FOR SUB-SAHARAN AFRICA + WASHINGTON, March 11 - The Reagan administration, +responding to last year's United Nations special session on +Africa, today outlined a U.S. "action program" for sub-Saharan +Africa focusing heavily on economic reform and self-help. + A White House statement announced establishment of "a +long-term U.S. goal for all U.S. economic programs and policies +in sub-Saharan Africa: to end hunger in the region through +economic growth, policy reform and private sector development." + The statement said the "program of action" was recommended by +a White House task force set up last September. + In a series of recommendations, the task force called for +new efforts to address Africa's heavy debt burden and said U.S. +food aid should stress production incentives to reinforce +African nations' economic reform and productivity. + It also said better African access to world markets should +be promoted to reward good performance and enable African +nations to earn their way toward economic growth. + The U.S. private sector should be mobilized to provide +"private, voluntary and corporate involvement of a humanitarian + It said donor countries "should negotiate, through the +existing International Monetary Fund/World Bank coordination +process, framework agreements with each sub-Saharan African +country to establish long-term structural adjustment and reform +programs." + The task force called for a separate budget account for +U.S. bilateral aid "in order to focus better on rewarding +economic performance and increasing the flexibility of U.S. +assistance programs for incentive economic reforms and private +sector development." + Reuter + + + +11-MAR-1987 18:16:09.87 + +usa + + + + + +F A RM +f0867reute +r f BC-UNUSUAL-TEXAS-INSTRUM 03-11 0091 + +UNUSUAL TEXAS INSTRUMENTS <TXN> PREFERRED PRICED + NEW YORK, March 11 - In a novel type of financing, Texas +Instruments Inc marketed a three-part, 225 mln dlr issue of +convertible money market preferred stock through Shearson +Lehman Brothers Inc as sole manager. + Shearson, which originated the new convertible concept, +said each of the three tranches totaled 75 mln dlrs. In the +first, a 2.85 pct dividend was set on the stock with a strike +price of 190 dlrs that represented a 15 pct premium over the +common stock price when terms were set. + Also included were 4.36 pct dividend preferred with a 220 +dlr strike price and 33 pct premium and 4.49 pct dividend +preferred with a 235 dlr strike price and 42 pct premium. + Texas Instruments common closed at 167.25 dlrs, up 2-1/8. + Ronald Gallatin, managing director at Shearson, said that +"demand for the offering was unbelievable, especially for the +first tranche." + He said that Shearson originated the concept of auction +money market preferred stock three years ago. The conversion +feature of this issue is the new wrinkle. + Commenting on the first tranche, Gallatin noted that the +original pricing talk called for a dividend in the four to 4.20 +pct area. This was gradually cut to 2.85 pct because of intense +demand, saving the issuer money in financing costs. + The Shearson official said that virtually all buyers of the +first tranche received less than they wanted. He said the +latter two tranches were less strongly oversubscribed. + Like non-convertible money market preferred stock, the new +version allows investors to redeem their holdings every seven +weeks. Investors then can maintain their holdings, sell them, +or offer to hold on to the securities if the auction +dividend is at least at a level they specify in advance. + Gallatin said the securities were sold to a broad range of +investors, including major insurance companies, banks, money +managers and pension funds. + Reuter + + + +11-MAR-1987 18:21:00.31 + +usacanada +james-bakerreagan + + + + +E +f0877reute +r f AM-CANADA-CLARK 03-11 0105 + +CLARK SAYS HE EXPECTS U.S. ACTION ON ACID RAIN + WASHINGTON, March 11 - Canadian Foreign Secretary Joe +Clark, winding up a two-day visit to Washington, said he +expected the Reagan administration to take some action on +reducing acid rain. + "My impression is there will be some movement by the United +States administration on acid rain (but) how much movement I +can't judge or predict," he told reporters. + The meetings with American officials are part of a routine +U.S.-Canada consultation but are also expected to lay the +groundwork for a summit in Ottawa next month between President +Reagan and Prime Minister Brian Mulroney. + Clark today held discussions with Treasury Secretary James +Baker and Democratic Sens. Patrick Moynihan of New York, +Christopher Dodd of Connecticut, Lloyd Bentsen of Texas and +George Mitchell of Maine. + Yesterday, he held talks with Vice President George Bush, +Secretary of State George Shultz and Commerce Secretary Malcolm +Baldrige. + Among its priorities, Canada is seeking evidence that +Reagan is prepared to live up to a commitment made last year to +implement in the United States a five-year 5 billion U.S. dlr +program to test cleaner ways of burning coal. + This issue was discussed at length with Baker and several +of the senators, including Mitchell who urged Canada to "keep +the heat on" the Reagan administration to force action, Canadian +officials said. + Also taken up with most of the senators and Baker were +trade issues, including the need for the United States and +Canada to establish a better mechanism for settling trade +disputes between the two countries, who are each other's major +trading partner, Canadian officials said. + Reuter + + + +11-MAR-1987 18:22:58.57 + +usa + + + + + +F +f0886reute +r f BC-FORD-MOTOR-<F>-DISTRI 03-11 0052 + +FORD MOTOR <F> DISTRIBUTES PROFIT SHARING + DALLAS, March 11 - Ford Motor COr said that profit-sharing +checks were distributed to employees in its U.S. facilities. + About 371 mln dlrs was distributed to 160,253 emplyees. The +average payment per employee was more than 2,100 dlrs compared +with 1,200 in 1985. + + Reuter + + + +11-MAR-1987 18:24:57.40 + +jamaica + + + + + +RM A +f0887reute +u f BC-jamaica-puts-cap-on-b 03-11 0079 + +JAMAICA PUTS CAP ON BORROWING + Kingston, march 11 - jamaica has put a cap on its 3.5 +billion dlr foreign debt and will reduce its obligations by 300 +mln dlrs this year, prime minister edward seaga said today. + Speaking at a news conference, seaga said jamaica has +reached its "maximum stock of debt" and will not undertake any +more borrowing until it is justified by economic growth. + "this year we'll be reducing the stock of debt by 300 +million dollars," he said. + He told reporters his government aims to reduce jamaica's +ratio of debt payments to foreign exchange earnings from the +current 50 pct to 25 pct within three years. + Debt payments this year are expected to total 287 mln +dollars, seaga said. + yesterday jamaica agreed with creditor banks to reschedule +over the next 12 years some 181 miln dlrs due in 1987-89. + The accord includes a grace period on principal payments +for eight and a half years and a reduction of interest rates +from 2.5 to 1.125 pct above libor. + Last week, jamaica obtained a 10-year rescheduling of 100 +pct of principal and 85 pct of interest on 125 mln dollars of +debt to the paris club nations the debt would have fallen due +over the next two years. + Reuter + + + +11-MAR-1987 18:26:24.22 + +usa + + + + + +F +f0888reute +d f AM-SICKLE 03-11 0114 + +FASTER TEST FOR SICKLE CELL ANEMIA DEVELOPED + BOSTON, March 11 - A team of California researchers said +that they have developed a better, faster test for detecting +sickle cell anemia in unborn children than existing procedures. + The test, developed by Cetus Corp <CTUS> researchers, +requires only a small amount of genetic material from a fetus +and produces a diagnosis within a day, unlike other tests that +require several days and can only be done in a few specialized +centers, they said. + Sickle cell anemia is a painful, inherited blood disease +that causes the normally-flexible red blood cells to stiffen +into a sickle-like shape. It is primarily found in blacks. + The researchers said in The New England Journal of Medicine +that their "procedure promises to be a rapid, sensitive and +reliable method for the prenatal diagnosis of sickle cell +disease." + In addition, they said, the technique might also be +adapted to detect other types of genetic disease. + Reuter + + + +11-MAR-1987 18:36:05.15 +earn +canada + + + + + +E F +f0900reute +r f BC-BANK-OF-BRITISH-COLUM 03-11 0060 + +BANK OF BRITISH COLUMBIA 1ST QTR JAN 31 NET + VANCOUVER, British Columbia, March 11 - + Oper shr loss two cts vs profit three cts + Oper net profit 273,000 dlrs vs profit 1,710,000 + YEAR - period ended October 31, 1986 + Oper shr loss 23 cts vs profit 14 cts + Oper net loss 4,397,000 vs profit 7,527,000 + Assets 2.67 billion vs 3.25 billion + Note: 1987 1st qtr net excludes extraordinary loss of 2.2 +mln dlrs or six cts shr. + 1986 yr net excludes extraordinary loss of 66 mln dlrs or +1.94 dlrs shr involving 22.1 mln dlrs of costs from sale of +bank assets to Hongkong Bank of Canada, eight mln dlrs for +contingent liabilities in respect of litigation and potential +tax reassessment by U.S. govt and 35.9 mln dlrs of deferred tax +debits. + Most bank assets sold to HongKong Bank of Canada, a unit of +<Hong Kong and Shanghai Banking Corp> in Nov, 1986. + Shr after preferred divs. + Reuter + + + +11-MAR-1987 18:37:48.60 + +usairan + + + + + +V +f0904reute +u f AM-REAGAN-HAKIM 03-11 0101 + +RAN SCANDAL PARTICIPANT TO GET IMMUNITY OFFER + WASHINGTON, March 11 - Albert Hakim, an arms merchant, is +the first top-ranked player in the Iran arms scandal who may be +enticed into testifying by the promise of immunity, +investigators said. + The House Select committee probing the Iran arms scandal +has voted to grant limited immunity from criminal prosecution +to Hakim in return for his testimony. + Hakim, 51, was said deeply involved from the start in the +attempt to trade arms to Iran for help in freeing American +hostages in Lebanon and the diversion of funds and arms to +rebels in Nicaragua. + + Reuter + + + +11-MAR-1987 18:38:02.32 +earn +usa + + + + + +F +f0905reute +r f BC-RESTAURANT-ASSOCIATES 03-11 0069 + +RESTAURANT ASSOCIATES INC <RA> 4TH QTR JAN 3 + NEW YORK, March 11 - + Shr 25 cts vs 36 cts + Net 1.4 mln vs 1.4 mln + Revs 56.9 mln vs 35.1 mln + Year + Shr 86 cts vs 75 cts + Net 4.7 mln vs 3.0 mln + REvs 201.4 mln vs 140.0 mln + NOTE:1985 4th qtr includes 99,000 loss from carryforward. +Shares restated to give effect to 1.4 to one stock split in the +form a 40 pct class A dividend in August 1985. + Reuter + + + +11-MAR-1987 18:41:59.82 +earn +usa + + + + + +F +f0907reute +r f BC-MICHIGAN-GENERAL-CORP 03-11 0077 + +MICHIGAN GENERAL CORP <MGL> 4TH QTR + SADDLE BROOK, N.J., March 11 - + Shr loss 1.02 dlrs vs 1.01 dlr + Net loss 18.1 mln vs 11.4 mln + Revs 96.0 mln vs 90.3 mln + Year + Shr loss 2.65 dlrs vs loss 3.06 dlrs + Net loss 39.3 mln vs 34.6 mln + Revs 386.0 mln vs 373.0 mln + NOTE:1986 4th qtr, year loss includes 14.4 mln dlrs, 4.6 +mln dlrs respectively from discontinued. 1985 4th qtr and year +include loss of 13.1 mln, 1.9 mln dlr respectively. + Reuter + + + +11-MAR-1987 18:45:36.66 +crudenat-gasiron-steel +usalibya + + + + + +F Y +f0908reute +u f BC-USX-<X>-PROVED-OIL,-G 03-11 0103 + +USX <X> PROVED OIL, GAS RESERVES FALL IN 1986 + NEW YORK, March 11 - USX Corp said proved reserves of oil +and natural gas liquids fell 28 pct to 802.8 mln barrels at the +end of 1986 from 1.12 billion barrels at year-end 1985. + The figures, in USX's just-released 1986 annual report, +indicate much of the drop resulted from the exclusion of 293.7 +mln barrels of Libyan reserves, after the U.S. government last +June directed U.S. oil companies to end Libyan operations. + USX, which owns Marathon Oil Co and Texas Oil and Gas Corp, +had 60 pct of its 1986 sales of 14.94 billion dlrs from its oil +and gas operations. + About 24 pct of total sales came from USX's USS steel unit +and 16 pct from diversified businesses, which include oilfield +services, raw materials, minerals, chemicals and real estate. + According to the report, domestic liquids reserves fell +slightly to 628.5 mln barrels from 628.9 mln and foreign +reserves fell to 174.3 mln from 486.4 mln barrels. The large +drop in foreign reserves was in the Middle East and Africa, +where they fell to about 9.3 mln barrels from 316.7 mln, +reflecting the exclusion of Libya. + Total natural gas reserves fell to 4.82 trillion cubic feet +at year-end 1986 from 5.18 trillion at the end of 1985. + Again, most of the drop came from the Middle East and +Africa, where reserves fell to zero from 71.9 billion cubic +feet, excluding Libyan reserves. + U.S. natural gas reserves fell to 3.44 trillion cubic feet +from 3.65 trillion and foreign reserves fell to 1.38 trillion +from 1.53 trillion. + In other areas, USX said total capital spending fell to 962 +mln dlrs in 1986 from 1.78 billion dlrs in 1985. The 1986 +audited figure is eight mln dlrs higher than the unaudited +figure the company reported on Jan 27. + USX also said it expects to record a gain of 150 mln dlrs +in 1988, representing 50 pct of previously existing investment +tax credits allowable under the new tax law. The loss of the +other half of the credits was reflected in the fourth quarter. + In a discussion of steel results, USX said plants that were +shut down last month and some previously idled plants may be +permanently closed. USX took a fourth quarter charge of 1.03 +billion dlrs to restructure its steel operations. The charge +included the "indefinite idling" last month of four plants in +Utah, Pennsylvania and Texas. + Other plants or parts of plants in Pennsylvania, Indiana, +Alabama, Ohio and Chicago had been previously idled. + "These operations are not permanently shut down. Improved +market conditions for the products from these plants may make +it feasible to reopen some of them," USX said in the report. + "On the other hand, a lack of any future market improvement +may necessitate their permanent closing," it added. + Reuter + + + +11-MAR-1987 18:50:05.96 + +usa + + + + + +F Y +f0914reute +r f BC-PHILLIPS<P>-SAYS-STOC 03-11 0099 + +PHILLIPS<P> SAYS STOCK UP ON STEPS TO PARE DEBT + NEW YORK, March 11 - Phillips Petroleum Co Chairman C. J. +"Pete" Silas said his company's stock, ranked fourth on the +most active list of stocks traded today, rose partly because of +steps it took to pare its debt. + Silas told Reuters in an interview today, "part of this +strength results from the rise in oil prices and also because +some of the analysts have been happy with the steps we've taken +in 1986 to pare our debt." + Phillips stocks rose 1/4 to 14 dlrs a share following +recommendations by some oil analysts, a company source said. + Phillips debt stood at 5.9 billion dlrs in December 1986 +down from a 1985 high of 8.6 billion dlrs, analysts said. + "At 14 dlrs a share, Phillips is priced closer to the actual +price of oil," he added. + Silas said, "if the analysts are right that oil prices will +rise to 20 dlrs or higher, then it seems to make sense to buy +Phillips." He is, however, more cautious about the strength in +crude prices, expecting the price to fluctuate between 16-18 +dlrs a barrel for the year. + Oil industry analysts said one reason for the stock's +popularity of the stock is that it traded at a strong discount +to its appraised value and was attractively priced for small +investors. + Charles Andrew, an analyst who follows Phillips for John S. +Herold Inc of Greenwich, Conn said that the appraised value of +the company, based on available data is 34.25 dlrs. + "The stock is trading at about 1/3 its appraised value. The +company has tremendous leverage and if it can get its act +together and if oil prices are steady to higher there is good +room for improvement," he said. + But, he added, "if oil prices turn lower, there will be a +lot of pressure on Phillips." + Phillips' shares fell as low as eight dlrs a share over the +last 52 weeks with a 1987 low of 11-3/4 dlrs in 1987. +Analysts say that the appraised value of the company could be +revised due to asset sales of their oil and gas reserves. + Silas told Reuters that the asset sales which amount to +about two billion dlrs for 1986 were completed and that none +were planned. + Reuter + + + +11-MAR-1987 18:50:57.36 + +usa + + + + + +F +f0915reute +u f BC-MICHIGAN-GENERAL-<MGL 03-11 0107 + +MICHIGAN GENERAL <MGL> BEGINS EXCHANGE OFFER + SADDLE BROOK, N.J., march 11 - Michigan General Corp said +it began an exchange offer for its 110 mln dlrs outstanding +principal amount of 10-3/4 pct senior subordinated debentures +due December 1, 1998. + Pursuant to the exchange offer, each 1,000 dlr principal +amount will receive 500 dlr principal amount of senior +subordinated notes due March 1, 1992, 200 dlr principal amount +of non-interest bearing convertible senior subordainted notes +due March 1, 1997 and 12 shares of delayed convertible +preferred stock, liquidation preference 25 dlrs per share. + The offer will expire April nine. + Michigan General said the exchange offer is crucial to is +attempt to restructure and reduce its risk from Chapter 11. + The principal purpose of the offer is to reduce its debt +service on the 10-3/4 pct debetures, increase stockholders' +equity and induce its lender to continue to fund. + Assuming a 90 pct acceptance of the offer, Michigan's +annual cash interest requirements will be reduced by about 10.6 +mln dlrs, it said. + Completion is subject to the tender of at least 90 pct of +the debentures and its lender to waive it from default under +its loan agreements. + + Reuter + + + +11-MAR-1987 18:53:18.49 +earn +canada + + + + + +E F +f0918reute +r f BC-BANK-OF-B.C.-REVISES 03-11 0108 + +BANK OF B.C. REVISES SHARE PAYOUT ESTIMATE + VANCOUVER, British Columbia, March 11 - Bank of British +Columbia said it revised its estimate of shareholder +distributions from last November's sale of most of the bank's +assets to HongKong Bank of Canada to between 65 cts and 1.15 +dlrs a share from 55 cts to 1.20 dlrs a share. + The bank said the estimate could rise to between 1.30 dlrs +and 1.80 dlrs a share if the full pension surplus is obtained. +It said it did not know when distributions would be made. + It earlier reported that operating profit for first quarter +ended January 31 fell to 273,000 dlrs from 1.7 mln dlrs the +previous year. + For full-year 1986 ended October 31, the bank posted an +operating loss of 4.4 mln dlrs against year-earlier profit of +7.5 mln dlrs. The bank also posted a 66 mln dlr extraordinary +loss in fiscal 1986. + Bank of British Columbia sold most of its assets last +November to HongKong Bank Canada, a unit of <HongKong and +Shanghai Banking Corp>, of Hong Kong, for 63.5 mln dlrs. + It said efforts to wind up the bank's affairs were +proceeding as quickly as possible. + The bank said it expected to report positive earnings in +future periods, barring unforeseen circumstances. + Loan losses, which the bank previously said figured in its +move to sell off most of its assets, rose to 105.7 mln dlrs in +fiscal 1986 from year-earlier 36.1 mln dlrs. The bank said 31.1 +mln dlrs of the 1986 total represented downward adjustments to +its portfolio of syndicated sovereign risk loans as required +under the sale to HongKong Bank. + Since November 27, the bank has confined activities to the +winding up of affairs, Bank of British Columbia said. + Reuter + + + +11-MAR-1987 18:54:46.18 + +usa +reagan + + + + +V +f0921reute +u f BC-HOUSE-VOTES-TO-BLOCK 03-11 0111 + +HOUSE VOTES TO BLOCK CONTRA AID FOR SIX MONTHS + WASHINGTON, March 11 - The House voted to block 40 mln dlrs +in military aid to the Nicaraguan rebels until President Reagan +accounts for past assistance, including money diverted from the +U.S. sale of arms to Iran. + The vote was seen as a temporary defeat for Reagan, who has +made aid to the "contras" a key initiative. + Congressional Democratic leaders have conceded that despite +today's vote, they can not muster a two-thirds majority to +override a certain Reagan veto. But they have said it is likely +they can win a battle expected this fall over 105 mln dlrs iin +new aid Reagan is requesting. + + Reuter + + + +11-MAR-1987 18:56:34.21 +earn +canada + + + + + +E F +f0924reute +d f BC-<KIENA-GOLD-MINES-LTD 03-11 0040 + +<KIENA GOLD MINES LTD> 4TH QTR NET + TORONTO, March 11 - + Shr 17 cts vs 16 cts + Net 1,019,000 vs 985,000 + Revs 7,997,000 vs 7,492,000 + YEAR + Shr 1.18 dlrs vs 64 cts + Net 6,959,000 vs 3,778,000 + Revs 36.5 mln vs 29.8 mln + Reuter + + + +11-MAR-1987 18:56:43.55 +carcasslivestock +argentina + + + + + +L +f0925reute +r f BC-ARGENTINE-MEAT-EXPORT 03-11 0117 + +ARGENTINE MEAT EXPORTS HIGHER IN JAN/FEB 1987 + BUENOS AIRES, March 11 - Argentine meat exports during +Jan/Feb 1987 totalled 39,714 tonnes, against 36,594 tonnes +shipped in the same 1986 period, National Meat board said. + Shipments in tonnes with comparative figures for the 1986 +period, in brackets, included: beef 26,945 (20,096), horse meat +3,257 (4,211) and beef offal 7,660 (10,502). + Argentine's meat exports totalled 20,243 tonnes in February +1987, against 19,217 tonnes shipped in the same 1986 month. + Shipments in tonnes, with comparative figures for February +1986, in brackets, included: beef 13,272 (11,464), horse meat +1,543 (2,083) and beef offal 4,476 (4,672), the board added. + Main destinations for refrigerated beef (bone in +equivalent) were as follows, in tonnes, with comparative +figures for 1986 in brackets - + EC 5,500 (7,900), Brazil 5,200 (unavailable), Israel 3,700 +(3,000), Peru 2,500 (800), Singapore 500 (300), Switzerland 500 +(400), Canary Islands 500 (300), Malta 500 (700), Aruba/Curazao +200 (300), Chile 100 (600). + Main destinations for canned meat and cooked beef (bone in +equivalent), in tonnes with comparative figures for Jan/Feb +1986, in brackets, were - + United States 11,200 (13,400), EC 4,700 (5,100). + Reuter + + + +11-MAR-1987 19:02:33.14 +earn +canada + + + + + +E F +f0940reute +r f BC-KIENA-PLANS-TWO-FOR-O 03-11 0056 + +KIENA PLANS TWO-FOR-ONE STOCK SPLIT + TORONTO, March 11 - <Kiena Gold Mines Ltd> said it planned +a two-for-one common stock split, pending shareholder approval +on April 7. + It said approval would require 66-2/3 pct of votes cast. +Kiena said 57 pct-owner Campbell Red Lake Mines Ltd <CRK> was +expected to vote in favor of the split. + Reuter + + + +11-MAR-1987 19:04:31.39 + +usa + + + + + +F +f0941reute +r f BC-VANZETTI-<VANZ>-INCRE 03-11 0053 + +VANZETTI <VANZ> INCREASE OF SHARES APPROVED + STOUGHTON, Mass, March 11 - vanzetti Systems INc said its +shareholders approved increasing the number of authorized +shares to five mln from three mln. + Shareholders also approved increasing the number of shares +reserved for options to employees to 300,000 from 150,000 + Reuter + + + +11-MAR-1987 19:04:38.26 +earn +usa + + + + + +F +f0942reute +s f BC-ROWE-FURNITURE-CORP-< 03-11 0025 + +ROWE FURNITURE CORP <ROWE> SETS QTLY DIVIDEND + SALEM, Va., March 11 - + Qtly div four cts vs four cts prior + Pay April 15 + Record March 20 + Reuter + + + +11-MAR-1987 19:05:21.41 +trade +usa +reaganyeutter + + + + +V RM +f0943reute +u f BC-U.S.-HOUSE-PANEL-TAKE 03-11 0092 + +U.S. HOUSE PANEL TAKES FIRST TRADE BILL VOTES + By Jacqueline Frank + WASHINGTON, March 11 - House trade lawmakers took their +first votes on measures designed to toughen U.S. trade laws but +held over until tomorrow the most difficult votes on +controversial plans to protect American industries. + Meeting in closed session, the House Ways and Means Trade +Subcommittee failed to resolve one of the most sensitive issues +in the bill--whether they will force major foreign trading +partners to severely cut their trade surpluses with the United +States. + The subcommittee is considering a toned-down version of +Democratic-sponsored trade legislation that aims to open +foreign markets but which drops last year's effort to force +President Reagan to retaliate with quotas or tariffs. + Congressional aides who asked not to be identified said the +lawmakers intend to wrap up their proposals tomorrow and will +consider a proposal to mandate retaliation without setting +specific trade penalties. + The legislation faces another hurdle in the full Ways and +Means Committee next week before the full House votes on it. + Rep. Richard Gephardt, a Missouri Democrat who is seeking +his party's 1988 presidential nomination, said he may offer an +amendment to call for reductions in the trade surpluses of +those countries with barriers to imports of U.S. goods. + This would be a moderated version of his earlier plan to +force a mandatory ten per cent annual cut in the trade surplus +with the United States by Japan, South Korea, Taiwan, West +Germany and other countries with the largest trade imbalances. + "My criteria for a good amendment sets a standard for +getting the trade deficit down," he told reporters. + The trade law changes are to become part of a major +congressional and administration effort to turn around the +record U.S. trade deficit of 169 billion dlrs last year by +opening up foreign markets and making U.S. products more +competitive. + House Speaker James Wright, a Texas Democrat, said again +today he expects the full House will approve the trade bill by +May and that Reagan will accept the final congressional bill. + "I expect whatever is reported (by the Ways and Means +Committee) will pass. We will have a good bill and an effective +bill," he told reporters. + The comprehensive trade bill will include work by other +committees to ease export controls on high technology, to aid +U.S. workers displaced by foreign competition, to stimulate +research and development, to remove foreign trade barriers and +to improve education and worker training. + The lawmakers agreed that for the first time a U.S. +industry could charge foreign producers with unfair competition +if they deny basic worker rights such as collective bargaining, +safety rules and payment of a minimum wage appropriate to the +country's economic development. + They transferred to U.S. Trade Representative Clayton +Yeutter the powers now held by Reagan to decide whether to +retaliate against foreign violations of fair trade rules and +whether an injured industry deserves import relief. + They agreed to make it easier for a company to get +temporary relief from import competition but agreed the +industry should provide a plan to become competitive. + The administration has not announced its support but +Yeutter said yesterday, "I am cautiously optimistic," that the +Democratic-led House will come up with an acceptable bill. + Reuter + + + +11-MAR-1987 19:06:36.56 +trade +franceussr + + + + + +C G L M T +f0945reute +r f BC-SOVIET-MINISTER-SAYS 03-11 0087 + +SOVIET MINISTER SAYS TRADE BOOST UP TO FRENCH + PARIS, March 11 - Soviet first deputy prime minister +Vsevolod Murakhovsky said at the end of a brief visit here his +country wanted to boost joint business with France, but that a +reduction of France's trade deficit with the Soviet Union +depended on the French. + Murakhovsky, who is also chairman of the State +Agro-Industrial Committee (GOSAGROPROM), told a news conference +he had discussed a variety of possible deals with French +companies Rhone-Poulenc, Pechiney and Imec. + Declining to put figures on possible contracts he said he +had discussed plant protection and the processing of highly +sulphuric gas with Rhone-Poulenc, packaging technology for +agricultural products with Pechiney, and fruit and vegetable +juice processing with Imec. + An official for Pechiney said an agreement of intent on +packaging could be signed soon, but could not give any other +details. The other two companies were not immediately available +for comment. + Asked whether he foresaw a reduction this year of France's +trade shortfall, at 7.6 billion francs in the first 11 months +of 1986 against 5.1 billion for the whole of 1985, Murakhovsky +told Reuters: "It all depends on France." + At a meeting in Paris last January French and Soviet +foreign trade ministers said they were committed to increased +efforts to reduce the deficit. Estimates at the time showed a +French 190 mln franc surplus for December 1986. + Murakhovsky said the Soviet Union was prepared to talk with +anybody with "interesting" proposals offering latest technology +and assuring "a mutual advantage." + He said the Soviet Union had many tasks ahead of it and +would deal rapidly with proposals it considered interesting. + He encouraged companies to take advantage of new laws +guaranteeing "the interests of foreign partners" in joint +ventures. + But he said no agreements had yet been finalised under the +new joint venture laws. + He said concrete deals had not yet been finalised as a +result of a one billion dollar accord signed in Moscow last +month with French businessman Jean-Baptiste Doumeng. + He said Doumeng's Interagra company was preparing proposals +for further examination by the Soviet Union. Doumeng last month +said the agreement was to exchange one billion dollars worth of +goods. + Murakhovsky said the agreement was one of intent, and +designed primarily to renew and increase the Soviet Union's +food production capacity. + Reuter + + + +11-MAR-1987 19:09:27.77 +crude +ecuadorvenezuela + + + + + +RM A Y +f0952reute +u f AM-ecuador-assistance 1stld 03-11 0103 + +VENEZUELA TO LEND OIL TO ECUADOR FOR EXPORT + Caracas, march 11 - venezuela will supply ecuador with an +as yet undetermined amount of crude oil to help it meet export +commitments, seriously affected by last week's earthquake, +energy and mines minister arturo hernandez grisanti said. + He gave few details about the deal, but said a crude oil +loan agreement will be made between state oil companies +petroleos de venezuela (pdvsa) and ecuador's cepe. + Ecuador was forced to suspend oil exports for an expected +four months after an earthquake damaged a pipeline. Oil +accounts for 60 per cent of its export income. + Hernandez was speaking to reporters at miraflores palace +on the results of talks with ecuador's deputy energy minister +fernando santos alvite, who arrived here last night. + "the volume lent to ecuador would be discounted from its +opec quota and would not affect venezuela's," he said. "we would +from august on produce our own quota and sell the additional +amounts that ecuador would be repaying us," he said. + He did not elaborate on the quota arrangements but did say +ecuador would notify opec by telex that venezuela would be +lending it a certain amount over so many days. + Venezuela's opec output quota is currently 1.495 million +barrels a day, and ecuador's has been set at 210,000 bpd. + Reuter + + + +11-MAR-1987 19:10:26.95 +earn +usa + + + + + +F +f0956reute +d f BC-EAGLE-CLOTHES-INC-<EG 03-11 0083 + +EAGLE CLOTHES INC <EGL> 2nD QTR JAN 31 + NEW YORK, March 11 - + Shr profit 17 cts vs profit 14 cts + Net profit 1.3 mln vs profit 901,000 + Revs 36.9 mln vs 36.2 mln + Six months + Shr profit 18 cts vs loss 11 cts + Net profit 1.4 mln vs loss 716,000 + Revs 63.6 mln vs 57.7 mln + NOTE:1986 six months includes increase in provision for +doubtful accounts to 1.5 mln dlrs. 1986 shares give effect to +issuance of 1.5 mln shares in exchange for outstanding Series 1 +preferred shares. + Reuter + + + +11-MAR-1987 19:11:19.94 + +iraniraq + + + + + +C G L M T +f0958reute +r f AM-GULF-IRAQ 03-11 0112 + +IRAQ SAYS IRAN ATTACK REPULSED ON SOUTHERN FRONT + BAGHDAD, March 11 - Iraq said it had repelled an Iranian +attack on positions held by its fourth army corps east of the +southern Iraqi town of Amarah on the Baghdad-Basra highway. + A Baghdad war communique said an Iranian infantry brigade, +backed by tanks, launched the overnight attack and fierce +fighting raged for more than six hours before Iranian troops +fled the battlefield, leaving 220 men killed and many wounded. + No major battles have been reported fought by the fourth +army corps for more than a year in the area, mainly swamplands +of the Hawizah marshes running eastward to the southern port +city of Basra. + Reuter + + + +11-MAR-1987 19:15:32.68 +trade +ukjapan + + + + + +C G L M T +f0961reute +r f AM-BRITAIN-JAPAN 03-11 0120 + +BRITAIN CALLS ON JAPAN TO INCREASE IMPORTS + LONDON, March 11 - Britain today called on Japan to +increase foreign imports or risk the rise of protectionism and +the harm it would bring to it and other trading nations. + British Trade and Industry Secretary Paul Channon said +Japan must heed a report issued by a Japanese government +advisory body in December calling for faster domestic demand to +help cut its trade surplus and restructure its economy. + "I recognise that the strong yen has brought problems to +Japan's domestic economy," he told a group of Japanese +businessmen in London. + "But these short term difficulties should not be allowed to +deflect Japan from the fundamental reforms necessary," he said. + "It is not just a domestic issue for Japan. If import +propensity does not expand very soon there is a real risk from +protectionist lobbies, particularly in the U.S. With whom Japan +has so massive a surplus," he said. + "They may well succeed in securing action by governments +which would be highly injurious to trading nations like Japan +and the U.K." + Channon said there had been substantial growth in the +volume of trade between Japan and Britain, amounting to 6.2 +billion sterling (9.8 billion dlrs) last year. + But he added: "Regrettably too much of it was in one +direction, with the Japanese selling us 3.7 billion sterling +(5.8 billion dlrs) more than we sold them." + Reuter + + + +11-MAR-1987 19:15:55.25 +acq + + + + + + +F +f0963reute +f f BC-******TAFT-BROADCASTI 03-11 0013 + +******TAFT BROADCASTING REJECTS 145 DLR PER SHARE BUYOUT OFFER FROM THETA CORP +Blah blah blah. + + + + + +11-MAR-1987 19:18:49.58 +acq +usa + + + + + +F +f0964reute +u f BC-TAFT-<TFB>-REJECTS-14 03-11 0098 + +TAFT <TFB> REJECTS 145 DLR/SHR OFFER + Cincinnati, March 11 - Taft Braodacasting Co said its board +of directors unanimously decided not to accept the pending +proposal of Theta Corp, an investor group led by Dudley Taft. + The decision was based on, among other things, the advise +of its financial advisors, goldman sachs and co, that the offer +of 145 dlrs per share was inadequate. + Taft said the board concluded that the offer failed to +recognize fully the future propsects of the company and +directed management to explore alternatives including possible +financial restructuring. + + Reuter + + + +11-MAR-1987 19:23:42.46 + +ecuador + + + + + +C G L M T +f0967reute +d f AM-ecuador-tremor 1stld 03-11 0120 + +ECUADOR DEBT TO BE HONOURED AFTER QUAKE SURVIVAL + QUITO, March 11 - Ecuador, stricken by a severe earthquake, +will honour its 8.16 billion dlr foreign debt but only after +ensuring the survival of the country after the tremor which +claimed at least 300 lives and caused 4,000 persons to +disappear. + "The government's position ... is to permit us to honour the +(debt) commitments but without sacrificing the country, because +first we have to survive and later we can comply," information +minister Marco Lara told reuters. + He said the nation would later announce definitive +measures on the foreign debt in the aftermath of the earthquake +which the government said will cause nearly a billion dlrs in +economic losses. + Reuter + + + +11-MAR-1987 19:26:43.72 +veg-oil +uk + +ec + + + +C G +f0968reute +r f AM-COMMUNITY-BRITAIN 03-11 0087 + +BRITISH MINISTER CRITICISES PROPOSED EC OILS TAX + LONDON, March 11 - A British minister said that a proposed +European Community tax on vegetable oils and fats would raise +the price of fish and chips and he pledged the government would +fight against it. + Lord Belstead, a junior agriculture minister, told the +House of Lords the tax would raise the price of raw materials +used in many processed foods by about 100 pct. + He said revenue should not be raised by taxing the consumer +and called the proposal "repugnant." + Reuter + + + +11-MAR-1987 20:04:55.06 +jobs +australia + + + + + +RM +f0981reute +b f BC-AUSTRALIAN-UNEMPLOYME 03-11 0091 + +AUSTRALIAN UNEMPLOYMENT EASES IN FEBRUARY + CANBERRA, March 12 - Australia's seasonally-adjusted +unemployment rate eased to 8.2 pct of the estimated workforce +in February from 8.3 pct in January, compared with 7.9 pct a +year earlier, the Statistics Bureau said. + The number of unemployed declined to 632,100 from 638,300 +in January, against 594,500 in February 1986, it said. + But unadjusted, the number of jobless rose to 699,800 or +9.1 pct of the workforce from 671,400 or 8.9 pct in January and +658,500 or 8.7 pct a year earlier. + REUTER + + + +11-MAR-1987 21:02:16.57 + +ecuador + + + + + +RM +f0996reute +u f BC-ECUADOR-SEEKS-HALT-TO 03-11 0106 + +ECUADOR SEEKS HALT TO PAYMENTS TO BANKS IN 1987 + QUITO, March 11 - Ecuador, stricken by a severe earthquake, +is seeking through negotiations with private foreign banks to +postpone all payments due to them for the rest of the year, +Finance Minister Domingo Cordovez said. + He said in a statement, "The idea with the foreign banks is +to obtain from them the best terms to give the Ecuadorean +economy a complete relief in the period of deferral of payments +on the foreign debt during the present year." + The statement referred only to payments due to private +foreign banks, a senior government finance official told +Reuters. + These creditors hold two-thirds of Ecuador's foreign debt +which totals 8.16 billion dlrs. + It did not refer to debts maturing to foreign governments +and multilateral lending agencies, accounting for the remainder +of Ecuador's foreign debt, the official said. + He said Ecuador owed the private foreign banks between 450 +and 500 mln dlrs in interest payments for the rest of 1987 and +about 66 mln in principal payments maturing this year. + Cordovez said Ecuador would seek new loans from +multilateral organisations. A World Bank mission was due here +soon to evaluate emergency loans, government officials said. + Ecuador has also appealed for emergency +aid from about 40 foreign governments. + Government officials have calculated losses to the 1987 +budget from last Thursday's earthquake at 926 mln dlrs. + In 1986, Ecuador's total service on the foreign debt was +about 996 mln dlrs to all creditors. + The quake ruptured Ecuador's main oil pipeline, suspending +crude exports for five months until the line is repaired. Oil +accounts for up to two-thirds of its total exports and up to 60 +pct of total revenues. Before the tremor, Ecuador suspended +interest payments on January 31 to private foreign banks. + Officials said they stopped interest payments due to a +cash-flow squeeze stemming from a slide in world oil prices, +which cut 1986 exports by about 25 pct to 2.18 billion dlrs. + Ecuadorean finance officials have been in telephone contact +every day this week with some of the banks who sit on its +14-bank advisory committee, the senior government finance +official said. The committee represents the country's 400 or so +private foreign bank creditors. + Cordovez also said in the statement, "The banks should +perceive that it is impossible at this moment to comply with +what was forseen." + Cordovez added, Ecuador must make a new proposal in line +with the reality since the earthquake by seeking better options +of deferment and of softening the negotiation conditions." + Interest payments fall due at least monthly to private +foreign banks. + Ecuador's initial proposal earlier this year was to make +only one semi-annual or one annual interest payment this year. + Under this proposal, it sought to defer interest payments +until June at the earliest, foreign bankers and government +officials here said. + Ecuadorean officials held their last formal meeting with +the advisory committee in New York in January, but the +negotiations were suspended on January 16 due to the 12-hour +kidnapping of President Leon Febres Cordero by air force +paratroopers. + The Red Cross says that least 300 people died and at least +4,000 are missing due to the earthquake. + REUTER + + + +11-MAR-1987 21:06:50.50 +money-fx +usa +james-baker + + + + +RM +f0002reute +u f BC-TREASURY-SECRETARY-BA 03-11 0096 + +TREASURY SECRETARY BAKER DECLINES COMMENT ON G-6 + NEW YORK, March 11 - U.S. Treasury Secretary James Baker +declined comment on the February 22 Paris accord between the +six major industrial nations under which they agreed to foster +exchange rate stability. + Asked by reporters after a speech before the National +Fitness Foundation banquet what, if any, currency intervention +levels had been set in Paris, Baker replied: "We never talk +about intervention." + Baker also declined to comment on his views about the +foreign exchange markets' reaction to the accord. + REUTER + + + +11-MAR-1987 21:32:41.13 +crude +venezuelaecuador + +opec + + + +RM +f0019reute +u f BC-ECUADOR-TO-ASK-OPEC-T 03-11 0104 + +ECUADOR TO ASK OPEC TO RAISE EXPORT QUOTA + CARACAS, March 11 - Ecuador will ask OPEC to raise its oil +export quota by 100,000 barrels per day to 310,000 to +compensate for lost output due to last week's earthquake, +deputy Energy Minister Fernando Santos Alvite said. + Santos Alvite, who arrived in Caracas last night to discuss +an aid plan for Ecuador, did not say when the Organisation of +Petroleum Exporting Countries (OPEC) would be approached. + The additional output would be related to plans now under +discussion for Venezuela and Mexico to lend Ecuador crude while +it repairs a pipeline damaged by the quake. + Earlier, Venezuelan Energy and Mines Minister Aturo +Hernandez Grisanti said his country would supply an unspecified +part of Ecuador's export commitments. + But Santos Alvite told reporters he hoped a first cargo of +300,000 barrels could leave Maracaibo this weekend to supply +refineries near Guayaquil. He added Ecuador also wanted to make +up for 50,000 bpd it shipped to Caribbean destinations. Mexico +might supply Ecuador's South Korean market. + Ecuador may be unable to export oil for up to five months +due to extensive damage to a 25 mile stretch of pipeline +linking jungle oilfields to the Pacific port of Balao. + REUTER + + + +11-MAR-1987 21:37:18.46 +oilseedrapeseed +china + + + + + +G C +f0024reute +u f BC-CHINA'S-RAPESEED-CROP 03-11 0097 + +CHINA'S RAPESEED CROP DAMAGED BY STORMS + PEKING, March 12 - The yield on 46,000 hectares (ha) of +rapeseed in central China will be cut by up to 70 pct by +hailstorms and tornadoes that swept across nearly 100,000 ha of +crops on March 6, the New China News Agency said today. + The storm, which lashed the Huai and Yangtze rivers and +eastern Anhui province, left two people dead and 800 others +injured. Some 800 houses were flattened and 19 boats sunk, it +said. + The Anhui provincial government has sent emergency relief +to the 19 counties affected, the news agency said. + REUTER + + + +11-MAR-1987 22:25:49.20 +crude +china + + + + + +F +f0040reute +u f BC-CHINA-CLOSES-SECOND-R 03-11 0112 + +CHINA CLOSES SECOND ROUND OF OFFSHORE OIL BIDS + PEKING, March 12 - China has closed the second round of +bidding by foreign firms for offshore oil exploration rights, +the China Daily has reported. + It quoted a spokesman for the China National Offshore Oil +Corp (CNOOC) as saying China signed eight contracts with 15 +foreign firms for blocks in the Pearl River mouth and south +Yellow Sea covering a total area of 44,913 sq km. + Second round bidding began at the end of 1984 and only one +well has so far produced results -- Lufeng 13-1-1, 250 km +south-east of Shenzhen, with an output of 6,770 barrels a day. +The well was drilled by a group of Japanese companies. + The spokesman added CNOOC was ready to enter into contracts +for offshore blocks before third round bidding began. He did +not say when this would be, but added the contracts would not +be bound by restrictions imposed during the second round. + China has signed 36 oil contracts and agreements with 37 +companies from 10 countries since 1979, when offshore +exploration was open to foreigners. Eleven contracts were +terminated after no oil was discovered. + Foreign firms have invested 2.1 billion dlrs on offshore +China since 1979. + REUTER + + + +11-MAR-1987 22:42:47.98 + +japan + + + + + +RM +f0046reute +b f BC-JAPAN-RELAXES-RULES-O 03-11 0097 + +JAPAN RELAXES RULES ON SECURITIES COMPANY OUTLETS + TOKYO, March 12 - Japan has relaxed its limit on the +establishment of securities company outlets in order to service +a growing number of individual investors, the Finance Ministry +said. + Japanese securities companies can now set up as many as 21 +new outlets in the two years before March 31, 1989, against the +previous maximum of 13. + The rules apply to outlets in department stores, +supermarkets and other locations convenient for individuals. + Foreign securities firms are not affected by the ruling, it +said. + REUTER + + + +11-MAR-1987 22:56:45.09 +acq +usa + + + + + +F +f0048reute +u f BC-AMC-IMPOSES-HIRING-FR 03-11 0097 + +AMC IMPOSES HIRING FREEZE DUE TO TAKEOVER BID + DETROIT, March 11 - American Motors Corp <AMO> management +has ordered a hiring freeze in view of Chrysler Corp's <C> 1.5 +billion dlr takeover bid, a spokesman for AMC said. + Analysts said the merger is virtually certain to go ahead. + American Motors directors met for five hours Wednesday to +review the takeover proposal. "The board ... Expects to be +meeting periodically over the next several weeks on the +Chrysler proposal," AMC said in its first formal statement since +it acknowledged the Chrysler proposal on Monday. + Chrysler, the number three U.S. Automaker, has said the +merger is motivated principally by its desire to acquire AMC's +profitable Jeep business and dealers, as well as a new modern +car assembly plant in Bramalea, Ontario. + That means a guaranteed future for much of AMC, but it +leaves in question the fate of many of its 19,000-plus +employees, according to industry analysts. AMC's Toledo, Ohio +Jeep plant has 1,850 hourly workers on indefinite layoff while +its Kenosha, Wisconsin, car plant has another 2,250 on layoff. + REUTER + + + +11-MAR-1987 22:57:31.32 + +china + + + + + +F +f0050reute +u f BC-ROTHMANS-CLOSE-TO-JOI 03-11 0108 + +ROTHMANS CLOSE TO JOINT VENTURE IN CHINA + PEKING, March 12 - Rothmans International plc <ROT.L> aims +to set up a joint venture with Jinan cigarette factory in +Shandong, China to produce high quality cigarettes, some for +export, Chinese newspapers said. + The China Daily said the factory has produced high-quality +"General" brand cigarettes using advanced machinery and technical +assistance worth 2.5 mln dlrs donated by Rothmans under a +co-operation agreement signed in 1985. + The Economic Daily newspaper said the high quality "General" +will help China's cigarettes enter the international market. +The two papers gave no more details. + REUTER + + + +11-MAR-1987 23:00:56.20 +bop +australia + + + + + +RM +f0052reute +u f BC-FOREIGN-INVESTMENT-IN 03-11 0113 + +FOREIGN INVESTMENT IN AUSTRALIA JUMPS IN LAST QTR + CANBERRA, March 12 - The net inflow of foreign investment +into Australia jumped to 7.3 billion dlrs in the fourth quarter +of 1986 from 4.32 billion in the third quarter and 4.55 billion +a year earlier, the Statistics Bureau said. + The Bureau attributed the increase to a turnaround of 2.08 +billion dlrs in official sector transactions and a 1.09 billion +turnaround in direct investment. + The turnaround in official transactions to a 1.52 billion +inflow from a 555 mln outflow in the third quarter, against a +520 mln inflow a year earlier, was largely on account of +government foreign currency borrowings, it said. + Direct investment recorded a turnaround to a 1.04 billion +dlr inflow in the fourth quarter from a 57 mln withdrawal in +the third quarter, against a 546 mln inflow in the fourth +quarter of 1985, the Bureau said. + It said the major part of the turnaround reflected an +injection of funds, estimated at around 700 mln dlrs, +associated with the previously reported restructuring of the +Australian operations of General Motors Corp <GM>. + GM used the funds to pay out or take over certain +Australian liabilities of its local unit <General +Motors-Holden's Ltd>, it said. + However, net borrowings remained the major part of total +inflow, accounting for 6.16 billion dlrs in the fourth quarter +against 3.88 billion in the third quarter and 4.03 billion a +year earlier, the Bureau said. + Net official borrowings comprised 1.52 billion dlrs against +a net outflow of 548 mln in the third quarter and a 516 mln +inflow a year earlier. + Total private and semi-public authority net borrowings rose +to 4.64 billion dlrs from 4.42 billion in the third quarter and +3.51 billion a year earlier. + REUTER + + + +11-MAR-1987 23:06:27.89 + +ukussr + + + + + +RM +f0055reute +u f BC-MOSCOW-CARRIES-OUT-NU 03-11 0094 + +MOSCOW CARRIES OUT NUCLEAR TEST + LONDON, March 12 - The Soviet Union carried out a nuclear +test early today, the official Tass news agency reported. + According to the report, monitored by the British +Broadcasting Corporation, the explosion was at 0200 gmt. + A blast on February 26 ended a 19-month unilateral test +moratorium declared by the Soviet Union. Moscow blamed the end +of the freeze on U.S. Refusal to join a total test ban. + Tass said the latest explosion, with a power of up to 20 +kilotonnes, had "the aim of improving military equipment." + REUTER + + + +11-MAR-1987 23:06:44.14 +graincorn +taiwan + + + + + +G C +f0058reute +u f BC-TAIWAN'S-FIRST-QUARTE 03-11 0086 + +TAIWAN'S FIRST QUARTER MAIZE IMPORTS SEEN RISING + TAIPEI, March 12 - Taiwan's maize import commitments are +expected to rise to 970,000 tonnes in the first four months of +1987 from 870,000 tonnes a year earlier, a spokesman for the +Joint Committee of Maize Importers told Reuters. + He said more than 75 pct of the imports come from the U.S. +And the rest from South Africa. + The maize import target for calendar 1987 is set at well +over 3.4 mln tonnes compared with an actual 3.07 mln in 1985, +he added. + REUTER + + + +11-MAR-1987 23:46:55.84 +trade +taiwan + + + + + +RM +f0077reute +u f BC-TAIWAN-FURTHER-RELAXE 03-11 0110 + +TAIWAN FURTHER RELAXES FOREIGN GOODS IMPORT CURBS + TAIPEI, March 12 - Taiwan said it would soon relax import +controls on some 400 foreign items, including stationery and +books, in a further effort to allow trading partners, +especially the U.S., Greater access to its markets. + Taiwan announced the easing of import curbs on some 600 +farm and industrial products last month, a Council for Economic +Planning and Development spokesman told Reuters. + He said the new move was intended to balance trade between +Taiwan and its trading partners. The island's trade surplus +reached a record 15.6 billion U.S. Dlrs last year, up from +10.62 billion in 1985. + In January, Taiwan cut import tariffs on some 1,700 foreign +products and allowed imports of U.S. Wine, beer and cigarettes. + "We hope the measures will help reduce our trade surplus +this year, especially with that of the U.S.," the spokesman +said. + Washington is pressing Taiwan to open its markets wider as +a way of cutting its trade deficit with the island, which rose +to 2.35 billion U.S. Dlrs in the first two months of 1987 from +1.87 billion in the year-earlier period. + REUTER + + + +12-MAR-1987 00:06:25.87 +shipiron-steel +japanusa + + + + + +F +f0081reute +u f BC-ECONOMIC-SPOTLIGHT-- 03-12 0111 + +ECONOMIC SPOTLIGHT - MITSUBISHI HEAVY FIGHTS BACK + By Fumiko Fujisaki, Reuters + TOKYO, March 12 - International efforts to redirect Japan's +export-driven economy toward domestic consumption face heavy +going if the country's largest defence contractor and world's +biggest shipbuilder is anything to go by. + Mitsubishi Heavy Industries Ltd <MITH.T> (MHI), which began +making ships and iron goods for Japan's military rulers 130 +years ago, is responding to the strong yen by redoubling its +efforts to maintain its share of export markets. + "If we sell the best quality and the cheapest products, +everyone will buy them," MHI president Yotaro Iida said. + Although two of MHI's main businesses, shipbuilding and +power plant construction, have been hit hard by the yen's 40 +pct rise against the dollar, the company has no plans to +abandon them, Iida told Reuters in an interview. + Its other big activity, aircraft component manufacture, has +performed so well that MHI now accounts for half of the money +Tokyo spends on defence procurement each year. + "We have made the utmost efforts among the world's +manufacturers to improve productivity," he said. "You may be +surprised if you come to see our plants. The outside is old but +the inside is ultra-modern, with robots and computers." + Securities analysts at major securities houses agreed that +MHI has pared costs more quickly than its competitors. The +company has slashed its workforce to 47,000 from 86,000 in +1976. + Despite its cost-cutting, MHI expects profits to drop 40 +pct to 30 billion yen in the current fiscal year ending March +31, from 1985/86's record 50.14 billion. + And that includes gains from the sale of MHI's stake in +Mitsubishi Motors Corp <MIMT.T> for 49 billion yen. + Iida is optimistic about the future, however. He said a +resurgence of demand from the Middle East following the recent +recovery in oil prices coupled with persistent demand for power +plants in developing countries will help MHI restore its +exports-to-sales ratio to the past decade's average of 30 pct. + MHI's exports-to-sales ratio fell to 25.9 pct in the +half-year ended last September, from 35 to 36 pct five years +ago. + China is the most promising market, although MHI also +considers other non-oil-producing developing countries as major +customers. + "Our customers are all seen as being in trouble due to a +lack of foreign currency," Iida said. But he added that he felt +MHI could sell to those markets with Japanese government +financial support. + It can also finance the plants itself and recover its +investment through product sales, a strategy Iida said could +prove popular in the future. + In shipping, MHI is fighting back against low-priced South +Korean competition by building more technologically advanced +carriers to carry liquefied natural gas and other products +difficult to transport. + Shipbuilders Association officials told Reuters MHI is the +world's largest shipbuilder in terms of orders and capacity. + Domestically, MHI is involved in 12 national projects, +including development of nuclear fusion reactors and launch +vehicles for man-made satellites. + It has been the biggest contractor for the Japan Defence +Agency's F-15 and F-14 jet fighters and missiles, although all +of these have been built under licence from U.S. Firms. + MHI is now heading up five Japanese companies seeking to +develop the country's own fighter plane to replace the +currently used F-1 support fighters in the late 1990s. + Military experts said Washington is putting strong pressure +on Tokyo to buy a U.S. Plane, either the McDonnell Douglas Corp +F-18 or General Dynamics Corp F-16, to reduce Japan's huge +trade surplus with the U.S. + "It might be a good idea to jointly produce planes with U.S. +Makers as Japan is supported by the U.S. Defence umbrella," Iida +said. + MHI also plans to cooperate with the U.S. In its Strategic +Defence Initiative space defence program by participating in +the project when it moves from the research stage, he said. + The U.S. Has been seeking Japan's technological support. + In fiscal 1985/86, aircraft accounted for 17.1 pct of MHI's +sales, shipbuilding 17 pct and power plants 27.9 pct. Iida said +the ideal ratio is power plants 30 pct, aircraft and special +vehicles 25 pct and shipbuilding 15 pct. + As for the remaining 30 pct, Iida said he wanted to shift +the domestic focus away from heavy machinery sold to +manufacturers and towards household goods, but he declined to +specify which products. + "By the end of this year, you may find our brand name on +your daily products, although this does not mean we will run +away from our mainstream business," he said. + REUTER + + + +12-MAR-1987 00:37:11.96 + +japan + + + + + +RM +f0096reute +u f BC-JAPANESE-BANKRUPTCIES 03-12 0091 + +JAPANESE BANKRUPTCIES DECLINE IN FEBRUARY + TOKYO, March 12 - Japan's corporate bankruptcies in +February fell 10.8 pct from January to 1,071 cases and total +debts dropped 49.4 pct to 149.40 billion yen, the Tokyo +Commerce and Industry Research Co said. + February bankruptcies fell 14.9 pct from a year earlier, +the 26th straight monthly decline, and debts fell 54.3 pct. + The lower number of bankruptcies in February reflected a +relaxation of money market conditions and reduced bill +settlements due to fewer operating days, it said. + Bankruptcies caused by the strength of the yen against the +dollar totalled 69, or 6.4 pct of those in February, with debts +of 25.52 billion yen, the research firm said. + This compared with 64 with debts of 125.59 billion yen in +January, it said. + Currency-linked bankruptcies since November 1985, when the +dollar's depreciation against the yen began to affect Japanese +export-linked firms, totalled 772, with cumulative debts of +660.53 billion yen, it said. + The value of the yen against the dollar rose to an average +153.49 yen per dollar in February from 184.62 a year earlier. + Bankruptcies usually decline in the first quarter of the +year due to fewer operating days and for seasonal reasons. + Bankruptcies are expected to increase in the quarter +starting April 1 due to expectations of slow consumer spending, +low wage increases for the 1987/88 fiscal year which starts in +April, and slow capital spending by manufacturers, the company +said. + Bankrupcties among export-linked subcontractors will rise +due to a recent shift by major manufacturers to overseas +production, it added. + REUTER + + + +12-MAR-1987 00:55:57.87 +ship +bangladesh + + + + + +G C +f0108reute +u f BC-BANGLADESH-PORT-WORKE 03-12 0089 + +BANGLADESH PORT WORKERS END STRIKE + CHITTAGONG, March 12 - Cargo handling resumed at +Bangladesh's Chittagong port today after 7,000 workers ended +their three day walk-out triggered by a pay dispute, port +officials said. + Loading and unloading of 14 ships stranded by the strike +started this morning and will be completed as quickly as +possible, they said. + The strikers returned to work after an agreement was +reached last night between port authorities and the Port +Workers Association, they said without giving details. + REUTER + + + +12-MAR-1987 01:01:34.13 +acq +uk +leigh-pemberton + + + + +RM +f0111reute +u f BC-LEIGH-PEMBERTON-OPPOS 03-12 0116 + +LEIGH-PEMBERTON OPPOSES TAKEOVER PROTECTION RULES + LONDON, March 11 - The Bank of England does not favour the +introduction of rules to shield companies from hostile takeover +attempts, its governor, Robin Leigh-Pemberton, said. + Instead, merchant banks advising bidding companies must +show restraint and responsibility to avoid the excesses that +have marred recent takeovers, he told the Yorkshire and +Humberside Regional Confederation of British Industries' annual +dinner. + Leigh-Pemberton also called on companies to improve ties +with institutional investors, suggesting representatives of +those institutions be granted seats on the boards of directors +of companies they invest in. + "Boards cannot expect protection from unwelcome predators, +for that is but a short step from saying that they should be +protected from their own shareholders -- who are, after all, +the proprietors of the company," Leigh-Pemberton said. + He added takeovers and mergers had an important role to +play in furthering economies of scale, integration and more +efficient market penetration. "The degree of success or failure +(of a takeover) has not in my experience depended on whether or +not the takeover was contested," he said. + Leigh-Pemberton noted there had been excesses in takeover +activity in the recent past. "The aim is to pressurise a +company's management into action dedicated solely to a +favourable impact on the share price in the short-term, partly +or even primarily at the expense of the future," he said. + Such bids "often depend for their success on creating a +highly-charged and artificial situation in the share market, +and give rise to temptations, on both sides of the battle, to +engage in aggressive, even manipulative tactics that are +immensely damaging to the interest of the shareholders," he +said. + In a clear reference recent events, he said "those in the +City who act for companies or individuals .. Must, I suggest, +be ready to accept a full measure of responsibility -- even if +it entails opprobrium -- for the transactions that may result." + They "should exercise the most careful judgment at the +outset with respect to the clients for whom they act and the +activities contenplated. Those who sow wind cannot expect the +whirlwind to visit elsewhere," he added. + REUTER + + + + diff --git a/src/test/data/reuters-21578/reut2-005.sgm b/src/test/data/reuters-21578/reut2-005.sgm new file mode 100644 index 00000000000..5d0e14587b5 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-005.sgm @@ -0,0 +1,2012 @@ + + +13-MAR-1987 15:05:02.92 +acq +usa + + + + + +F +f0215reute +d f BC-PLM-<PLMA>-UNIT-ENDS 03-13 0076 + +PLM <PLMA> UNIT ENDS MERGER TALKS + SAN FRANCISCO, March 13 - PLM Cos Inc said its PLM Power Co +unit broke off merger discussions with Sunlaw Energy Corp of +Beverly Hills, Calif. + In January PLM Power entered into a letter of intent to +negotiate a potential acquisition of Sunlaw, subject to +substantial due diligence, the company said. + But it also said the two companies were not able to agree +on mutually satisfactory final terms and conditions. + Reuter + + + +13-MAR-1987 15:08:53.08 +coffee +colombia + + + + + +C T +f0224reute +b f BC-colombia-opens-coffee 03-13 0086 + +COLOMBIA OPENS APRIL/MAY COFFEE REGISTRATIONS + BOGOTA, March 13 - Colombia opened coffee export +registrations for April and May with the National Coffee +Growers' Federation setting no limit, Gilberto Arango, +president of the private exporters' association, said. + He told Reuters the decision not to put any limit responded +to "new factors" which have emerged from recent International +Coffee Organisation talks in London, where producers and +consumers failed to agree on a re-introduction of export quotas. + Reuter + + + +13-MAR-1987 15:11:52.98 +graincorn +usa + + + + + +C G L +f0228reute +b f BC-/USDA-REPORTS-10.572 03-13 0098 + +USDA REPORTS 10.572 MLN ACRES IN CONSERVATION + WASHINGTON, March 13 - The U.S. Agriculture Department has +accepted 10,572,402 more acres of highly erodable cropland into +the Conservation Reserve Program, USDA announced. + In the latest signup, farmers on 101,020 farms submitted +bids on a total of 11,254,837 acres. + The accepted bids for annual rental payments ranged up to +90 dlrs per acre with an average of 51.17 dlrs per acre. + Land entered into the Conservation Reserve Program will be +ineligible for farming for ten years and must be planted with +permanent vegetative cover. + Producers enrolled 1,894,764 acres of corn base acreage in +the conservation program to take advantage of a corn "bonus" +rental payment that was offered by USDA. + The corn bonus, to be paid in generic comodity +certificates, amounts to two dlrs per bushel, based on the ASCS +program payment yield for corn, for each acre of corn based +accepted into the reserve. + The state showing the biggest enrollment in the +conservation program during this signup was Texas with +approximately 1.225 mln acres, followed by Iowa with 1.030 mln +acres, Minnesota with 890,000 acres, Montana 875,000 acres, and +Kansas with 842,000 acres. + Other states showing big enrollment were Missouri with +646,000 acres, North Dakota with 588,000 acres, and Nebraska +with 554,000 acres. + In the corn belt states of Illinois and Indiana, 217,000 +acres and 116,000 acres respectively were enrolled. + Farm land signed up to date in the conservation program +totals 19,488,587 acres. Bids on the previous signups ranged up +to 90 dlrs per acre with an average of 45.52 dlrs. + Reuter + + + +13-MAR-1987 15:13:01.16 + +usabrazil + + + + + +RM +f0233reute +u f BC-BRAZIL-DEBT-POSES-THO 03-13 0103 + +BRAZIL DEBT POSES THORNY ISSUE FOR U.S. BANKS + By Cal Mankowski, Reuters + NEW YORK, March 13 - CitiCorp <CCI> appears to be digging +in its heels for tough negotiations over the billions of +dollars in loans that Brazil owes to money center banks, Wall +Street analysts said. + "I view it as pre-negotiation posturing," said analyst +Carole Berger of Cyrus J. Lawrence Inc, referring to both +Brazil and Citicorp. Brazil recently stopped paying interest on +its commercial bank debt. Today, CitiCorp said its first +quarter income would be reduced by 50 mln dlrs after tax if it +lists the loans as non-performing status. + Citicorp filed an 8-K form with the Securities and Exchange +Commission, indicating a material change in its financial +situation. "Citicorp is saying you can't scare us with threats, +we'll make your loans non-performing right now," Berger said. + The loans have to be treated as non-performing after 90 +days without a payment. CitiCorp said only that the situation +will be reviewed at the end of the current quarter. + Berger asserted that Brazil is doing its own politicking by +talking to U.S. regulators and trying to drive a wedge between +U.S. and European banks. + Analyst Lawrence Cohn of Merrill Lynch and Co said it is +unlikely the situation will be resolved until the second half +of this year. + "Ultimately the Brazilians are going to have to pay up on +all the interest they owe," Cohn said. "The real issue is the +rescheduling of debt terms. + Another question is whether or not the International +Monetary Fund can help Brazil with a new austerity program. + Stocks of money center banks were mostly down fractions in +late dealings. One trader most stocks in the group bounced off +their lows by midday as investors took the news in stride. + Cohn said the bank stocks may be risky until numbers on +non-performing loans are reported for each bank. But he said +investors looking ahead six to 12 months might want to buy at +present levels for the "tremendous fundamental values" in the +group. + Analyst Robert Gordon of Shearson Lehman Brothers Inc said +Manufacturers Hanover Corp <MHC) has the greatest exposure to +Brazilian loans of any New York bank, in terms of percentage of +earnings. He said his only two recommendations currently among +New York banks are J.P. Morgan and Co <JPM> and Bankers Trust +Co <BT> which happen to have the least exposure. + Gordon said his positive opinion on J.P. Morgan and Bankers +Trust was not merely a response to the fact that the two have +lower exposure to Brazilian loans than other banks. + In fact he said there's a chance those banks could get more +involved in the future. He noted that Morgan has already set up +a brokerage subsidiary to deal in loans to less developed +countries. + "I don't see any reason to change full year earnings +estimates, said Frederick Meinke, analyst at E.F. Hutton Co. He +thinks the confrontation with Brazil could end in a replay of a +situation that occurred with Argentina in 1984 and 1985. + Meinke noted that in the case of Argentina the loans became +non-accruing for a couple of quarters but then when the banks +came to an agreement with Argentina all the back interest was +paid. "What it did was distort the quarterly earnings pattern," +he said. + He said in the case of Brazil write-offs of loans is a +worst-case outcome which is highly unlikely. He noted that +Brazil is a country with a diversified economy, going through +some economic upheaval after the transition from a military to +a civilian government. + "The countries of Latin America have too much debt relative +to their ability to service it," said John Mason of +Interstate Securities. "We've been fiddling around with these +problems for five years and the hour is growing late." + He said up to now the banks have reduced their spreads, cut +interest rates internally and extended maturities and none of +these measures has been enough. He expects re-classification of +as much as a third of the loans as non-accruing and he sees +partial write downs of some loans. + Nevertheless Mason thinks the money center bank stocks +could be poised for a short term rally. + A spokesman at First Chicago Corp <FNB> said it is +premature to put Brazil's loans on a cash basis. "It is our +expectation that economic development will allow Brazil to meet +its debt," a spokesman said. + Bankers Trust in New York said it would be premature to +make a decision. Several other banks queried by Reuters said +much the same thing. + A spokesman at Manufacturers Hanover noted that of 2.3 +billion dlrs in loan exposure to Brazil only 1.3 billion is +subject to Brazil's unilateral moratorium on repayment of +interest. + + Reuter + + + +13-MAR-1987 15:13:10.18 + +usa + + + + + +F +f0234reute +b f BC-ROCKWELL-<ROK>-TO-REP 03-13 0112 + +ROCKWELL <ROK> TO REPURCHASE MORE COMMON SHARES + PITTSBURGH, March 13 - Rockwell International Corp said its +board has authorized extension of the company's 500 mln dlr +stock repurchase program by an additional 500 mln dlrs. + Since the beginning of the present repurchase program in +March 1986, Rockwell said, it has bought 10.4 mln shares for +461 mln dlrs. At present prices, it said, the program would +reduce the presently outstanding 140 mln common shares by about +seven pct. Since November 1983, the company has repurchased +18.1 mln shares for 672 mln dlrs, it said. + Rockwell said the stock will be repurchased through open +market and private transactions. + Rockwell said the repurchased shares will be available for +potential acquisitions, stock options, employee benefit +programs, conversion of convertible securities and other +purposes. + The company said, "We continue to view our repurchase +program as an integral part of our long term goal of improving +shareholder values." + Rockwell said the program "complements our aggressive +program of support for the growth plans of our businesses with +capital investments, product and research development +resources, and acquisitions in support of our core businesses." + + Reuter + + + +13-MAR-1987 15:14:20.63 + +usa + + + + + +F Y +f0237reute +r f BC-VOGTLE-NUCLEAR-PLANT 03-13 0100 + +VOGTLE NUCLEAR PLANT GETS FULL-POWER LICENSE + ATLANTA, March 13 - The Nuclear Regulatory Commission +issued a full-power operating license for Unit 1 of the Vogtle +Electric Generating Plant, said Southern Co <SO> unit Georgia +Power, which is a co-owner of the plant. + Georgia Power said the license allows for completion of +pre-operational testing, which will be followed by full-power +operation. Unit 1 is scheduled to begin commerical operation by +June one, it said. + The other co-owners of the plant are <Olgethorpe Corp>, the +Municpal Electric Authority of Georgia and the city of Dalton. + Reuter + + + +13-MAR-1987 15:19:10.06 + +ukjapanusa + + + + + +F +f0255reute +r f BC-BRITISH-AIRWAYS-<BAB> 03-13 0081 + +BRITISH AIRWAYS <BAB> TO FLY TO TOKYO NON-STOP + NEW YORK, March 13 - British Airways said the British +government reached an agreement on new traffic rights with the +Japanese government which clears the way for non-stop flights +between London and Tokyo. + The flight is scheduled to cut across Siberia, shaving +almost six hours off the previous flight path to 11-1/2 hours, +British Airways said. + The trans-Siberian route is subject to approval by the +USSR, British Airways added. + Under the agreement, British Airways said it will continue +to leave Heathrow daily, but the new non-stop service will +operate on Thursdays and Saturdays starting early June. The +company said return flights will be on Fridays and Sundays. + Reuter + + + +13-MAR-1987 15:20:20.42 + +ukjapan + + + + + +A +f0260reute +h f BC-BRITAIN-WANTS-BANK-RE 03-13 0118 + +BRITAIN WANTS BANK REGULATION DEAL WITH JAPAN + LONDON, March 13 - Britain wants Japan to agree a timetable +for work towards joint rules on capital adequacy for banks +along the lines of a January outline agreement between the U.S +and the U.K., Corporate Affairs Minister Michael Howard said. + Howard told a Nikkei conference on Tokyo financial markets, +"I want to see an agreement between us on what progress is to be +made and the rate at which it will happen." + Japanese vice-minister of finance for international affairs +Toyoo Gyohten told the conference yesterday he was ready to +discuss capital adequacy, but no negotiations were planned and +he could not see how or when agreement would be reached. + Reuter + + + +13-MAR-1987 15:21:39.08 +livestockcarcass +usa + +ec + + + +C G L +f0264reute +u f BC-/U.S.-MEAT-GROUP-TO-F 03-13 0131 + +U.S. MEAT GROUP TO FILE TRADE COMPLAINTS + WASHINGTON, March 13 - The American Meat Institute, AME, +said it intended to ask the U.S. government to retaliate +against a European Community meat inspection requirement. + AME President C. Manly Molpus also said the industry would +file a petition challenging Korea's ban of U.S. meat products. + Molpus told a Senate Agriculture subcommittee that AME and +other livestock and farm groups intended to file a petition +under Section 301 of the General Agreement on Tariffs and Trade +against an EC directive that, effective April 30, will require +U.S. meat processing plants to comply fully with EC standards. + The meat industry will seek to have the U.S. government +retaliate against EC and Korean exports if their complaints are +upheld. + Reuter + + + +13-MAR-1987 15:21:47.30 + +usa + + + + + +F +f0265reute +r f BC-COMMERCE-BANCORP-<COB 03-13 0095 + +COMMERCE BANCORP <COBA> FILES FOR OFFERING + CHERRY HILL, N.J., March 13 - Commerce Bancorp Inc said it +has filed a registration statement with the Securities and +Exchange Commission for a 575,000 share Series B cumulative +preferred stock offering, including 75,000 shares to cover +allotments. + Commerce said it and its banking subsidiaries will use the +proceeds to support their planned growth and for general +corporate purposes. + The bank holding company said each share of preferred +stocks initially will be convertible into one share of Commerce +common stock. + Commerce said the preferred shares will be priced at a +range of 20-22 dlrs a share, with a proposed sale to the public +commencing in early-to-mid April. + Commerce said Butcher and Singer Inc will be the offering's +managing underwriter. + Reuter + + + +13-MAR-1987 15:21:53.56 + +usa + + + + + +F +f0266reute +d f BC-ADIA-SERVICES-<ADIA> 03-13 0080 + +ADIA SERVICES <ADIA> SELLS 500,000 SHARES + MENLO PARK, Calif., March 13 - Adia Services Inc said it +agreed to sell 500,000 shares of common stock to its principal +stockholder, Adia S.A., at a price based on the current market +price. + The sale will raise Adia S.A.'s ownership in the company to +74.7 pct from 72.7 pct, Adia said. + The company also said it intends to use proceeds from the +stock sale to retire debt, for working capital and for general +corporate purposes. + Reuter + + + +13-MAR-1987 15:22:36.13 +earn +usa + + + + + +F +f0268reute +s f BC-MET-PRO-CORP-<MPR>-TO 03-13 0024 + +MET-PRO CORP <MPR> TO PAY REGULAR DIVIDEND + HARLEYSVILLE, Pa., March 13 - + Qtrly 15 cts vs 15 cts prior + Pay May Eight + Record April 24 + Reuter + + + +13-MAR-1987 15:24:00.88 +earn +usa + + + + + +F +f0270reute +h f BC-AILEEN-INC-<AEE>-1SR 03-13 0028 + +AILEEN INC <AEE> 1SR QTR JAN 31 LOSS + NEW YORK, March 13 - + Shr loss 30 cts vs loss 20 cts + Net loss 1,553,000 vs loss 1,031,000 + Revs 10.0 mln vs 8,696,000 + Reuter + + + +13-MAR-1987 15:25:16.54 + +usa + + + + + +A RM +f0271reute +r f BC-INT'L-GAME-TECHNOLOGY 03-13 0065 + +INT'L GAME TECHNOLOGY <IGAM> TO SELL DEBT + NEW YORK, March 13 - International Game Technology said it +filed with the Securities and Exchange Commission a +registration statement covering a 35 mln dlr issue of senior +notes due 1995 and a 25 mln dlr issue of convertible senior +subordinated debentures due 2002. + The company named Drexel Burnham Lambert Inc as sole +manager of the offerings. + Reuter + + + +13-MAR-1987 15:32:32.81 +earn +usa + + + + + +F +f0285reute +u f BC-resending 03-13 0066 + +WOLVERINE WORLD WIDE INC <WWW> 4TH QTR LOSS + ROCKFORD, MICH., March 13 - + Shr loss six cts vs profit 55 cts + Net loss 414,000 vs profit 3,936,000 + Sales 109.4 mln vs 126.8 mln + Year + Shr loss 1.75 dlrs vs profit 55 cts + Net loss 12,589,000 vs profit 3,965,000 + Sales 341.7 mln vs 389.5 mln + NOTE: Year results include 14.0 mln dlr restructuring +charge in 2nd Qtr of 1986 + Reuter + + + +13-MAR-1987 15:32:42.51 + +usa + + + + + +F +f0286reute +r f BC-MEAD-<MEA>-FILES-150 03-13 0094 + +MEAD <MEA> FILES 150 MLN DLR SHELF REGISTRATION + DAYTON, Ohio, March 13 - Mead Corp said it filed a shelf +registration with the Securities and Exchange Commission +covering potential debt securities offerings of up to 150 mln +dlrs. + It said the underwriters for this offerings may include +Smith Barney, Harris Upham and Co Inc, Goldman Sachs and Co +and/or Salomon Brothers Inc. + Mead said proceeds will be used to retire short-term debt, +a portion of which was incurred to finance part of the recent +acquisitions of Ampad Corp and Zellerbach Distribution Group. + Reuter + + + +13-MAR-1987 15:33:15.31 +graincorn +usamexico + + + + + +C G +f0287reute +f f BC-ussr-export-sale 03-13 0012 + +******U.S. EXPORTERS REPORT 122,000 TONNES CORN SOLD TO MEXICO FOR 1986/87 +Blah blah blah. + + + + + +13-MAR-1987 15:34:07.21 +earn +usa + + + + + +F +f0290reute +r f BC-HURCO-COMPANIES-INC-< 03-13 0036 + +HURCO COMPANIES INC <HURC> FIRST QTR NET + INDIANAPOLIS, March 13 - + Shr profit three cts vs loss 18 cts + Net profit 124,000 vs loss 370,000 + Rev 11.3 mln vs 11.7 mln + Avg shares 3,673,000 vs 2,368,000 + Reuter + + + +13-MAR-1987 15:38:11.97 + +usa + + + + + +F +f0295reute +r f BC-ALCIDE'S-<ALCD>-SHELF 03-13 0036 + +ALCIDE'S <ALCD> SHELF REGISTRATION EFFECTIVE + NORWALK, Conn., March 13 - Alcide Corp said its shelf +registration of 4,500,000 shares of common has been declared +effective by the Securities and Exchange Commission. + Reuter + + + +13-MAR-1987 15:39:02.46 +acq +usa + + + + + +F +f0298reute +r f BC-MAXTOR-<MXTR>-AGREES 03-13 0107 + +MAXTOR <MXTR> AGREES TO ACQUIRE U.S. DESIGN + SAN JOSE, Calif., March 13 - Maxtor Corp and U.S. Design +Corp <USDC>, said they reached definitive agreement covering +the acquisition of U.S. Design by Maxtor. + They said the arrangement, which is subject to a number of +conditions including U.S. Design shareholder approval, calls +for Maxtor to issue 12 mln dlrs worth of its own common stock +in exchange for all of U.S. Design. + The number of Maxtor shares to be issued will be determined +by the average closing price of Maxtor stock over the 10 +trading day period prior to the day the acquisition becomes +effective, the companies also said. + Reuter + + + +13-MAR-1987 15:39:21.46 +earn +usa + + + + + +F +f0299reute +s f BC-SHARED-MEDICAL-SYSTEM 03-13 0024 + +SHARED MEDICAL SYSTEMS CORP <SMED> SETS PAYOUT + MALVERN, Pa., March 13 - + Qtly div 18 cts vs 18 cts prior + Pay April 15 + Record March 31 + Reuter + + + +13-MAR-1987 15:39:34.41 + +usa + + + + + +F +f0300reute +r f BC-INTERNATIONAL-LEASE-F 03-13 0064 + +INTERNATIONAL LEASE FINANCE <ILFC> PICKS ENGINE + EVENDALE, Ohio, March 13 - International Lease Finance Corp +said it picked the CFM International CFM56-5 high bypass +turbofan engine to power its three new Airbus Industries A320 +aircraft. + International Lease said it is negotiating to buy up to 27 +more A320s. Initial aircraft deliveries are planned for 1991, +the company said. + Reuter + + + +13-MAR-1987 15:40:26.67 + +usa + + + + + +A +f0301reute +d f BC-JWP-<JWP>-SELLS-30-ML 03-13 0053 + +JWP <JWP> SELLS 30 MLN DLRS OF NOTES + LAKE SUCCESS, N.Y., March 13 - JWP Inc said it sold 30 mln +dlrs principal amount of its 9.25 pct senior notes due 1996 to +certain institutional lenders. + The company said about 15 mln dlrs of the proceeds will be +used to pay debt and the balance for general corporate purposes. + Reuter + + + +13-MAR-1987 15:41:03.47 + + + + + + + +F RM +f0302reute +f f BC-******S/P-UPGRADES-UN 03-13 0010 + +******S/P UPGRADES UNION CARBIDE CORP'S 1.2 BILLION DLRS OF DEBT +Blah blah blah. + + + + + +13-MAR-1987 15:41:10.37 + + + + + + + +RM +f0303reute +f f BC-ELECTRICITE-DE-FRANCE 03-13 0014 + +******ELECTRICITE DE FRANCE SAYS IT WILL LAUNCH EURO-COMMERCIAL PAPER PROGRAM ON MONDAY +Blah blah blah. + + + + + +13-MAR-1987 15:41:31.04 + +usa + + + + + +F +f0304reute +d f BC-STORAGE-TECH-<STK>-IN 03-13 0104 + +STORAGE TECH <STK> IN DISCUSSIONS WITH IRS + VAIL, Colo., March 13 - Storage Technology Corp said it is +holding dicussions with the Internal Revenue Service that could +end their dispute over the amount of back taxes owed by the +company. + "We are currently pursuing discussions with the IRS that +could lead to a final solution," Stephen G. Jerritts, president +and chief operating officer said. "Simultaneously, we are +taking all necessary actions to try to expedite the court +appeal process, resolve these issues and allow final court +approval of the plan of reorganization, by our target date of +June 30, 1987," he said. + Last year, Storage Technology's bankruptcy court ruled that +the company owed about 25 mln dlrs in taxes, an amount much +lower than the IRS is seeking. + The IRS has appealed the court's decision. + Jerritts also said his company and <Siemens AG> of West +Germany extended an agreement under which Storage Technology +distributes a laser printer made by Siemens. + Reuter + + + +13-MAR-1987 15:41:46.52 + +usa + + + + + +C M +f0306reute +d f BC-U.S.-EARLY-MARCH-CAR 03-13 0128 + +U.S. EARLY MARCH CAR SALES OFF 2.2 PCT + DETROIT, March 13 - Retail sales of new cars by U.S. +automakers eased 2.2 pct in early March to the weakest levels +since 1983, with industry giant General Motors Corp down 9.3 +pct while Ford Motor Co and Chrysler Corp both had gains. + The decline by GM continued its trend of weaker sales since +the beginning of the 1987 model year, which has forced the +world's biggest corporation to cut its car production several +times through temporary and permanent layoffs at various +plants. + Consumer incentives apparently had some success, analysts +said, as the seasonally adjusted annualized sales rate improved +to 7.5 mln compared with about 7.0 mln in late February. The +eight domestic carmakers sold 8.2 mln units during 1986. + Reuter + + + +13-MAR-1987 15:42:09.99 + +usa + + + + + +F +f0310reute +h f BC-CAPITAL-INVESTMENTS-F 03-13 0038 + +CAPITAL INVESTMENTS FORMS UNIT + BOCA RATON, Fla., March 13 - <Capital Investments +Development Corp> said it formed Bradford-Taylor Clearing House +Inc, a unit that will compile mailing lists for use by the +direct mail industry. + Reuter + + + +13-MAR-1987 15:45:20.31 +earn +usa + + + + + +F +f0315reute +d f BC-WEIGH-TRONIX-INC-<WGH 03-13 0047 + +WEIGH-TRONIX INC <WGHT> 4TH QTR NET + FAIRMONT, MINN., March 13 - + Shr 18 cts vs 16 cts + Net 348,298 vs 308,927 + Sales 4,166,750 vs 3,740,970 + Year + Shr 72 cts vs 52 cts + Net 1,409,867 vs 1,020,096 + Sales 16.5 mln vs 15.0 mln + Avg shrs 1,974,529 vs 1,956,214 + Reuter + + + +13-MAR-1987 15:45:27.49 + +uk + + + + + +RM F A +f0316reute +r f BC-GOLDMAN-SACHS-GIVEN-B 03-13 0099 + +GOLDMAN SACHS GIVEN BOGUS EXXON BONDS IN TRADE + LONDON, March 13 - Goldman Sachs International Corp +received forged bonds of a unit of Exxon Corp <XON> in a trade, +a spokesman for Goldman Sachs and Co Inc said in a telephone +conversation from New York. + He said the transaction left Goldman Sachs International +with an exposure of about 2.2 mln dlrs but that it had +insurance to cover the loss. + The spokesman was responding to an enquiry about an item in +the London "Standard" newspaper, which said Goldman Sachs "is +feared to be the victim of a new multi-million pound City +scandal." + The newspaper also said, "The firm (Goldman Sachs) is +believed to be the paying agent for some 900 bonds issued in +the name of oil giant Exxon which were deposited at banks in +Brussels and have now been found to be forgeries." + The spokesman said that the bonds were delivered to the +firm by a man working on behalf of a third party. He said it +wasn't until the bonds were cleared through Euro-clear (a major +clearing house for the eurobond market) that it was discovered +they were forgeries. + The spokesman also said he believed that the intermediary +had been apprehended by police. However, a spokesman for the +City of London police said he was unaware of such an arrest and +could neither confirm nor deny it. + Last Friday, Exxon Corp said forgeries of a 20-year zero +coupon euronote issued by its Exxon Capital Corp subsidiary +have been discovered in the European market. It also said +Morgan Guaranty Trust Co was the fiscal agent and paying agent +and that Morgan, Euro-clear and Cedel (another major clearing +system) and police in London and Brussels were investigating +the case. + Reuter + + + +13-MAR-1987 15:45:35.38 +livestockcarcass +usa + +ec + + + +F +f0317reute +d f BC-U.S.-MEAT-GROUP-TO-FI 03-13 0109 + +U.S. MEAT GROUP TO FILE TRADE COMPLAINTS + WASHINGTON, March 13 - The American Meat Institute, AME, +said it intended to ask the U.S. government to retaliate +against a European Community meat inspection requirement. + AME President C. Manly Molpus also said the industry would +file a petition challenging Korea's ban of U.S. meat products. + Molpus told a Senate Agriculture subcommittee that AME and +other livestock and farm groups intended to file a petition +under Section 301 of the General Agreement on Tariffs and Trade +against an EC directive that, effective April 30, will require +U.S. meat processing plants to comply fully with EC standards. + + Reuter + + + +13-MAR-1987 15:47:27.24 + +uk + + + + + +A RM +f0322reute +u f BC-EDF-TO-LAUNCH-EURO-CP 03-13 0116 + +EDF TO LAUNCH EURO-CP PROGRAM MONDAY + LONDON, March 13 - <Electricite de France> (EdF) will make +its first offering of Euro-commercial paper in the +international market on Monday, EdF chief financial officer +Daniel Lallier said in a telephone call from Paris. + The program was announced in late January and dealers +expect the company will be pushing to maintain its ability to +obtain some of the finest terms available in the international +markets. + Lallier did not say how much would be offered, although he +has noted that EDF would be cautious because it believes the +market is still in its infancy. In January he said EdF may not +issue more than 300 to 500 mln dlrs of paper this year. + EdF plans to oversee the program itself, with Goldman Sachs +International Corp, Morgan Guaranty Ltd and Salomon Brothers +International Ltd acting as dealers for the general program, +which will be aimed at institutional and retail investors. + Union Bank of Switzerland will act as dealer for a specific +program, which is aimed at smaller retail investors. + Reuter + + + +13-MAR-1987 15:47:50.80 +graincorn +usa + + +cbt + + +C G +f0324reute +b f BC-/CBT-TRADERS-SAY-U.S. 03-13 0138 + +CBT TRADERS SAY U.S. CONSERVATION SIGNUP NEUTRAL + CHICAGO, March 13 - The 11,254,837 acres of highly erodable +farmland submitted to the U.S. Department of Agriculture for +the conservation reserve program was within trade guesses of +10-12 mln and should have an overall neutral impact on grain +and soybean prices Monday, grain traders said. + Farmers enrolled 1,894,764 acres of corn base acreage in +the conservation program to take advantage of a corn bonus +rental payment that was offered by the USDA, which may underpin +new crop futures, they said. + New crop corn prices firmed earlier this week on ideas of a +large sign-up in the program. But traders noted that the poor +yielding acres being set-aside will result in only a modest +decrease in final production figures, since farmers will +concentrate on high yielding land. + Of a total 11,254,837 erodoble acres submitted, usda +accepted 10,572,402 acres into the program at an average rental +payment of 51.17 dlrs per acre. + Farm land signed up to date now totals 19,488,587 acres. + Reuter + + + +13-MAR-1987 15:48:34.01 +earn +usa + + + + + +F +f0330reute +d f BC-MONARCH-AVALON-INC-<M 03-13 0064 + +MONARCH AVALON INC <MAHI> 3RD QTR JAN 31 LOSS + BALTIMORE, March 13 - + Shr loss 11 cts vs profit four cts + Net loss 199,000 vs profit 81,000 + Rev 1.9 mln vs 2.5 mln + Nine months + Shr loss 14 cts vs profit 15 cts + Net loss 261,000 vs profit 273,000 + Rev 6.4 mln vs 7.6 mln + NOTE: Per share information adjusted for three-for-two +stock split on January 31, 1986. + Reuter + + + +13-MAR-1987 15:52:33.91 + +canada + + + + + +E RM +f0336reute +r f BC-bcresources 03-13 0102 + +B.C. RESOURCES HAS NEW 360 MLN DLR CREDIT LINE + VANCOUVER, British Columbia, March 13 - British Columbia +Resources Investment Corp said it successfully concluded +refinancing negotiations with bankers for a new 360 mln dlr +restructured credit facility. + The credit line will be in place for four years to March +31, 1991, but is extendable up to 10 years under certain +circumstances which were not specified by the company. + B.C. Resources said subsidiaries Westar Timber and Westar +Petroleum have settled revised lending agreements, but debt +discussions regarding subsidiary Westar Mining are continuing. + + Reuter + + + +13-MAR-1987 15:53:40.40 + +argentina +machinea + + + + +RM F A +f0338reute +u f BC-ARGENTINE-DEBT-TALKS 03-13 0115 + +ARGENTINE DEBT TALKS DIFFICULT - CENTRAL BANK + BUENOS AIRES, March 13 - Central Bank President Jose Luis +Machinea said negotiations with creditor banks on Argentina's +30 billion dlr private sector foreign debt were difficult. + "There is considerable divergence with the banks. We must +try to get them to lower the spreads," Machinea told Reuter. + He said negotiations with the steering committee for the +country's creditor banks in New York would not end next week. + Machinea leaves for New York tomorrow with Treasury +Secretary Mario Brodersohn to complete Argentina's team at +negotiations with the steering committee for a 2.15 biilion dlr +loan to see the country through 1987. + Machinea said Argentina had World Bank support. He said he +and Economy Minister Juan Sourrouille had discussed Argentina's +loan request with World Bank Vice-President David Knox, who is +currently in Buenos Aires. + Argentina is aiming at four pct growth in 1987 and has said +this target is not negotiable. It has indicated that it would +not put payment of interest due on its foreign debt ahead of +its growth target if the loan was not granted. + The United States and 12 other industrial nations granted +Argentina a 500 mln dlr bridge which was received this week. + Talks on the 2.15 billion dlr lona began in January. + Reuter + + + +13-MAR-1987 15:54:21.09 +crudegasnat-gaswpi +usa + + + + + +C M +f0339reute +r f BC-U.S.-PRODUCER-ENERGY 03-13 0116 + +U.S. PRODUCER ENERGY PRICES RISE IN FEBRUARY + WASHINGTON, March 13 - Prices of wholesale finished energy +goods in the U.S. rose 4.0 pct in February after a 9.8 pct rise +in January, the Labor Department said. + The Producer Price Index for finished energy goods fell by +20.9 pct in the past 12 months. + Heating oil prices rose 3.0 pct in February after a 18.0 +pct rise in January, the department said. + Gasoline prices rose by 5.5 pct last month after a 15.7 +pct January rise, the department said. Natural gas prices rose +1.8 pct after a 4.2 pct rise in January. + Crude oil prices rose 4.4 pct in February, after a 19.7 pct +January rise and were off 21.3 pct from the year ago level. + Reuter + + + +13-MAR-1987 15:55:47.33 + +usa + + + + + +A RM +f0342reute +u f BC-UNION-CARBIDE-<UK>-DE 03-13 0103 + +UNION CARBIDE <UK> DEBT UPGRADED BY S/P + NEW YORK, March 13 - Standard and Poor's Corp said it +upgraded 1.2 billion dlrs of debt of Union Carbide Corp and its +affiliate, DCS Capital Corp. + Raised were the pair's senior debt to BB-plus from +BB-minus. Union Carbide's subordinated debt was upgraded to +BB-minus from B. + S and P said the action reflected several positive factors +which emerged over the past year, including a better balance of +supply and demand in the chemical industry. Union Carbide has +also benefitted from the turnaround in foreign exchange rates +and lower feedstock costs, the agency noted. + Standard and Poor's said the company's asset sales, and +subsequent use of the proceeds for debt reduction, exceeded the +corporate plan of a year ago. + The rating agency also pointed out that Union Carbide's +successful refinancing of more than 2.5 billion dlrs of +long-term debt has resulted in a substantially lower interest +burden. + Reuter + + + +13-MAR-1987 15:56:03.81 + +usa + + + + + +F +f0343reute +u f BC-U.S.-EARLY-MARCH-CAR 03-13 0095 + +U.S. EARLY MARCH CAR SALES OFF 2.2 PCT + By Richard Walker, Reuters + DETROIT, March 13 - Retail sales of new cars by U.S. +automakers eased 2.2 pct in early March to the weakest levels +since 1983, with industry giant General Motors Corp <GM> down +9.3 pct. + Ford Motor Co <F> and Chrysler Corp <C> both had gains. + The decline by GM continued its trend of weaker sales since +the beginning of the 1987 model year, which has forced the +world's biggest corporation to cut its car production several +times through temporary and permanent layoffs at various +plants. + Relatively weaker sales by all of the Detroit Big Three +carmakers have compelled the companies to offer a string of +sales incentives including cash rebates and below-market +interest loans in an effort to reignite the market. + Incentives apparently had some success, analysts said, as +the seasonally adjusted annualized sales rate improved to 7.5 +mln compared with about 7.0 mln in late February. The eight +domestic carmakers sold 8.2 mln units during 1986. + GM said its sales of domestic-built cars in the March 1-10 +period declined to 97,487 from 104,952 a year ago while truck +sales rose 14.4 pct to 40,131 from 35,081. There were eight +selling days in each period. + Despite the lower car sales, the giant automaker had a +bright spot as its Chevrolet division, which is launching a +national sales campaign this month for its new Corsica and +Beretta compact cars, was up almost 21 pct when only +domestic-built cars were counted. GM's Buick division was also +up, by 11.4 pct, while Cadillac was down 7.8 pct, Pontiac was +off 10.8 pct and Oldsmobile plunged 41 pct. + GM also showed an improvement in its market share to 53.6 +pct from 48.1 pct in late February, which analysts said was +partly due to the increasing sales for the new Chevrolets. + Meanwhile, Ford said its car sales rose 5.9 pct to 50,407 +compared with 47,592 a year ago while truck sales gained by +12.6 pct to 35,814 from 31,811. + Number three Chrysler's car sales gained to 0.4 pct to +25,286 from 25,191 while its truck sales gained 15 pct to +15,565 from 13,585. The truck sales were a record for the +period, the company said. + Among the smaller makers, Honda <HMC> said domestic car +sales rose 16 pct to 4,394 from 3,786 and Volkswagen of America +rose 4.9 pct to 849 from 809. + American Motors Corp <AMO> fell 57 pct to 760 from 1,780 +for cars but rose 18 pct in jeep sales to 4,500 from 3,800. + Nissan <NSANY> car sales rose 19.1 pct to 2,137 from 1,794 +and gained 3.6 pct on trucks to 1,686 from 1,628. Toyota +<TOYOY> said it sold 500 U.S.-built cars compared with none a +year ago. + Reuter + + + +13-MAR-1987 15:56:39.68 +cotton +usa + + + + + +C G +f0344reute +u f BC-/U.S.-COTTON-CERTIFIC 03-13 0137 + +U.S. COTTON CERTIFICATE EXPIRATION DATE EXTENDED + WASHINGTON, March 13 - Expiration dates on upland cotton +certificates issued under the 1986 upland cotton program are +being extended, the Agriculture Department announced. + The certificates are being extended because of a shortage +of Commodity Credit Corporation inventory available for +exchange with certificates, USDA undersecretary Danial Amstutz +said. + Presently, upland cotton commodity certificates expire nine +months from the last day of the month of issuance. + Under the new procedure, all current outstanding and all +new upland cotton certificates issued under the 1986 upland +cotton program will have an expiration date of either February +29, 1988, or nine months from the last day of the month in +which the certificate is issued, whichever is later. + Reuter + + + +13-MAR-1987 15:59:24.64 + +usa + + + + + +A RM +f0348reute +u f BC-S/P-DOWNGRADES-MICHIG 03-13 0113 + +S/P DOWNGRADES MICHIGAN GENERAL <MGL> DEBT + NEW YORK, March 13 - Standard and Poor's Corp said it cut +to C from CCC-minus Michigan General Corp's 110 mln dlrs of +10-3/4 pct senior subordinated debentures due 1998. + S and P said if Michigan General's exchange offer for the +debentures is not successful, the firm anticipates it will +default on the June 1 interest payment and will have to seek +protection from creditors under the Federal Bankruptcy Act. + The exchange offer faces numerous obstacles, including the +tender of at least 90 pct of the debentures and additional +financing from lenders, S and P noted. + The company's implied senior debt rating is CCC-minus. + Reuter + + + +13-MAR-1987 15:59:41.96 +earn +italy + + + + + +RM +f0349reute +u f BC-BNL-ANNOUNCES-NET-198 03-13 0083 + +BNL ANNOUNCES NET 1986 PROFITS IN BANK SECTOR + ROME, March 13 - State-owned <Banca Nazionale del Lavoro +BNL> said 1986 profits for its banking activities equalled 155 +billion lire against 146 billion lire in 1985. + Consolidated 1986 results for BNL, which also has interests +in tourism, public works, industrial credit and other sectors, +are expected to be announced later this year. + The results for the banking sector are to be presented at a +shareholders meeting scheduled for April 29. + Reuter + + + +13-MAR-1987 16:00:21.17 +earn +usa + + + + + +F +f0353reute +d f BC-APPLIED-DNA-SYSTEMS-I 03-13 0069 + +APPLIED DNA SYSTEMS INC <ADNA> 4TH QTR LOSS + NEW YORK, March 13 - + Shr loss one ct vs nil + Net loss 148,007 vs loss 58,863 + Revs 198,919 vs 133,071 + Avg shrs 7,476,433 vs 6,633,989 + Year + Shr loss three cts vs loss six cts + Net loss 230,949 vs 424,719 + Revs 666,626 vs 509,971 + NOTE: Amounts include losses of a 50 pct owned scientific +development affiliate, Analytical Biosystems Corp. + Reuter + + + +13-MAR-1987 16:05:31.61 +acq +usa + + + + + +F Y +f0366reute +r f BC-QED 03-13 0094 + +OILMAN HAS 8.7 PCT OF QED EXPLORATION <QEDX> + WASHINGTON, March 13 - Kansas oilman Nicholas Powell told +the Securities and Exchange Commission he has acquired 195,000 +shares of QED Exploration Inc, or 8.7 pct of the total +outstanding common stock. + Powell, who heads Prairie Resources Corp and Mack C. Colt +Inc, both Kansas oil and gas exploration companies, said he +bought the stock for investment purposes. + Powell, who said he has already spent 609,831 dlrs on his +QED stock, said he plans to buy more shares as long as he +considers them to be undervalued. + Reuter + + + +13-MAR-1987 16:05:38.71 + +usa + + + + + +F +f0367reute +d f BC-TEXAS-AIR-<TEX>-NAMES 03-13 0052 + +TEXAS AIR <TEX> NAMES BRITT AIRWAYS PRESIDENT + HOUSTON, March 13 - Texas Air Corp said it named Norman +McInnis as president of its Britt Airways unit, succeeding Bill +Britt, who retired March one. + McInnis, former president of Royale Airlines, most recently +was a consultant to the commuter airline industry. + + Reuter + + + +13-MAR-1987 16:05:59.28 +earn + + + + + + +E F +f0370reute +b f BC-labatt 03-13 0009 + +******JOHN LABATT LTD 3RD QTR SHR DILUTED 32 CTS VS 30 CTS +Blah blah blah. + + + + + +13-MAR-1987 16:06:21.90 + +usa + + + + + +F +f0373reute +d f BC-ARMATRON-<ART>-NEGOTI 03-13 0043 + +ARMATRON <ART> NEGOTIATES NEW CREDIT LINE + MELROSE, Mass., March 13 - Armatron International Inc said +it negotiated a new seasonal line of credit with three lenders +for 10 mln dlrs for working capital requirements to support its +lawn and garden product line. + Reuter + + + +13-MAR-1987 16:06:58.01 +earn +usa + + + + + +F +f0375reute +d f BC-LIFESTYLE-RESTAURANTS 03-13 0049 + +LIFESTYLE RESTAURANTS INC <LIF> 1ST QTR JAN 24 + NEW YORK, March 13 - + Shr loss 31 cts vs loss eight cts + Net loss 1,780,000 vs loss 449,000 + Revs 13.9 mln vs 17.8 mln + NOTE: Current 1st qtr loss included a gain of 870,000 dlrs +and 70,000 dlrs from the sale of restaurant leases. + Reuter + + + +13-MAR-1987 16:07:06.10 + +usa + + + + + +A RM +f0376reute +u f BC-TREASURY-BALANCES-AT 03-13 0085 + +TREASURY BALANCES AT FED ROSE ON MARCH 12 + WASHINGTON, March 13 - Treasury balances at the Federal +Reserve rose on March 12 to 3.038 billion dlrs on March 12 from +2.715 billion dlrs the previous business day, the Treasury said +in its latest budget statement. + Balances in tax and loan note accounts fell to 7.623 +billion dlrs from 8.870 billion dlrs on the same respective +days. + The Treasury's operating cash balance totaled 10.661 +billion dlrs on March 12 compared with 11.586 billion dlrs on +March 11. + Reuter + + + +13-MAR-1987 16:07:38.14 +earn +usa + + + + + +F +f0379reute +r f BC-SIERRA-HEALTH-SERVICE 03-13 0051 + +SIERRA HEALTH SERVICES INC <SIE> 4TH QTR LOSS + LAS VEGAS, Nev., March 13 - + Shr loss 52 cts vs profit six cts + Net loss 2,943,000 vs profit 334,000 + Revs 33.5 mln vs 18.5 mln + Year + Shr loss 1.57 dlrs vs profit 16 cts + Net loss 8,781,000 vs profit 792,000 + Revs 116.0 mln vs 56.5 mln + + Reuter + + + +13-MAR-1987 16:08:43.39 +earn +usa + + + + + +F +f0384reute +d f BC-FIRECOM-INC-<FRCM>-3R 03-13 0049 + +FIRECOM INC <FRCM> 3RD QTR JAN 31 LOSS + NEW YORK, March 13 - + Shr loss two cts vs profit two cts + Net loss 104,874 vs profit 90,470 + Sales 3,154,673 vs 1,666,313 + Nine mths + Shr loss one cent vs profit four cts + Net loss 39,169 vs profit 159,784 + Sales 8,250,003 vs 4,665,553 + Reuter + + + +13-MAR-1987 16:09:02.87 +ipi +brazil + + + + + +RM A +f0385reute +r f BC-BRAZIL-INDUSTRIAL-GRO 03-13 0106 + +BRAZIL INDUSTRIAL PRODUCTION SLOWED IN JANUARY + RIO DE JANEIRO, March 13 - Industrial output in January was +6.09 pct above the same 1986 month after rising 6.71 pct in +December, Brazilian Geography and Statistics Institute figures +show. + The result is in line with the declining trend in the +growth rate since October, the Institute said. + In the 12 months to end-January industrial production was +10.48 pct above the 12 months to end-January last year, while +in calendar 1986 output was 10.89 pct above 1985. + The biggest output rises in the 12 months to end-January +were 23.68 pct in pharmaceuticals and 22.12 pct in machinery. + Reuter + + + +13-MAR-1987 16:10:20.88 +earn +usa + + + + + +F +f0389reute +s f BC-WHEELING-AND-LAKE-ERI 03-13 0045 + +WHEELING AND LAKE ERIE RAILWAY CO <WLE> DIV + ROANAKE, Va., March 13 - + Qtly div 1.4375 dlrs vs 1.4375 dlrs + Pay May 1 + Record April 3 + Note: Dividend paid to all shareholders other than Norfolk +Southern Corp's <NSC> Norfolk and Western Railway Co. + Reuter + + + +13-MAR-1987 16:10:59.71 +earn +usa + + + + + +F +f0391reute +s f BC-GENERAL-CINEMA-CORP-< 03-13 0027 + +GENERAL CINEMA CORP <GCN> CLASS B DIVIDEND + CHESTNUT HILL, Mass., March 13 - + Qtly div class B 13.5 cts vs 13.5 cts + Pay April 30 + Record April 9 + + Reuter + + + +13-MAR-1987 16:11:18.64 +earn +canada + + + + + +E F +f0393reute +u f BC-labatt 03-13 0062 + +<JOHN LABATT LTD> 3RD QTR JAN 31 NET + TORONTO, March 13 - + Shr 36 cts vs 31 cts + Shr diluted 32 cts vs 30 cts + Net 26,158,000 vs 21,798,000 + Revs 1.05 billion vs 844.2 mln + Nine mths + Shr 1.28 dlrs vs 1.22 dlrs + Shr diluted 1.15 dlrs vs 1.08 dlrs + Net 92,779,000 vs 77,971,000 + Revs 3.16 billion vs 2.70 billion + Avg shrs 72.4 mln vs 64.0 mln + Reuter + + + +13-MAR-1987 16:12:28.42 +grainwheat +usasudan + + + + + +C G +f0394reute +u f BC-SUDAN-RECEIVES-50-MLN 03-13 0119 + +SUDAN RECEIVES 50 MLN DLRS IN PL480 AUTHORITY + WASHINGTON, March 13 - Authorizations to purchase 50 mln +dlrs worth of U.S. wheat and wheat flour under Public Law 480 +were issued to Sudan today, the Agriculture Department said. + The authorization provides for 34 mln dlrs -- about 309,000 +tonnes -- worth of wheat, grade U.S. number two or better +(except durum which shall be number three or better). + It also provides for 16 mln dlrs -- about 73,000 tonnes -- +worth of wheat flour. + The contracting period for both commodities is March 20 +through August 31, 1987. The delivery period for wheat is March +20 through September 30, 1987 and for wheat flour is April 10 +through SEptember 30, 1987, USDA said. + Reuter + + + +13-MAR-1987 16:14:48.69 +trade +usa + + + + + +F A +f0399reute +r f BC-TRADE-BILL-TO-CHANGE 03-13 0139 + +TRADE BILL TO CHANGE AGRICULTURE TRADE LAWS + WASHINGTON, March 13 - The House Ways and Means Committee +is moving toward passage of a trade bill that sponsors said was +intended to help open foreign markets to U.S. agricultural +goods and to modify some U.S. agricultural trade laws. + The trade subcommittee voted to require President Reagan to +take into account the potential harm to U.S. agricultural +exports of any trade retaliation he might impose for foreign +unfair trade practices against other domestic industries. + The bill would allow U.S. agricultural producers to seek +government monitoring of imports if there is a reasonable +chance the industry would be harmed by an import surge. + The full Ways and Means Committee is to consider the bill +next week and congressional sources said they expect it will be +approved. + In investigations involving a processed agricultural +product, trade associations of processors or producers would +have to petition for relief from foreign dumping or unfair +duties. + The bill sets out U.S. trade negotiating objectives for +the Uruguay round of talks under the General Agreement on +Tariffs and Trade. It would seek fair trade in agriculture, +seek to discipline restrictive or trade distorting import and +export practices, to eliminate tariffs, subsidies, quotas and +non-tariff barriers. + President Reagan's authority to negotiate a new GATT +agreement would be extended through January 1993 and authority +to negotiate a free trade zone with Canada would be extended +through January 3, 1991. + The bill extends Reagan's authority to negotiate an +international coffee agreement through October 31, 1989. + It allows a refund of import duties paid on raw sugar +imported from November 1, 1977 to March 31, 1985 for production +of sugar or products containing sugar and destined for +re-export. The export of the sugar or products must occur +before Octoer 1, 1991. + Presently, to qualify for the refund the sugar must be +processed within three years after import and exported within +five years. + Agriculture would also benefit from more rapid decisions in +complaints of unfair foreign trade practices or injury from +imports. + Reuter + + + +13-MAR-1987 16:15:15.79 +earn +usa + + + + + +F +f0400reute +r f BC-AMERICAN-CITY-<AMBJ> 03-13 0077 + +AMERICAN CITY <AMBJ> SETS INITIAL PREFERRED DIV + KANSAS CITY, Mo. - March 13 - American City Business +Journals Inc said it declared an initial dividend of 15.4 cts a +share on its recent issue of 1.6 mln shares of convertible +exchangeable preferred stock. + The dividend is payable March 31 to shareholders of record +March 20, American City said, adding that future dividends will +be paid on a quarterly basis. + The preferred stock was issued on February 23. + Reuter + + + +13-MAR-1987 16:16:39.20 +money-supply +usa + + + + + +RM V +f0405reute +f f BC-******U.S.-BUSINESS-L 03-13 0011 + +******U.S. BUSINESS LOANS RISE 377 MLN DLRS IN MARCH 4 WEEK, FED SAYS +Blah blah blah. + + + + + +13-MAR-1987 16:17:16.42 +money-supply +usa + + + + + +RM V +f0407reute +b f US-BUSINESS-LOAN-FULLOUT 03-13 0057 + +U.S. BUSINESS LOANS RISE 377 MLN DLRS + WASHINGTON, March 13 - Business loans on the books of major +U.S. banks, excluding acceptances, rose 377 mln dlrs to 279.085 +billion dlrs in the week ended March 4, the Federal Reserve +Board said. + The Fed said that business loans including acceptances +increased 484 mln dlrs to 281.546 billion dlrs. + Reuter + + + +13-MAR-1987 16:22:34.56 +wpigasnat-gascrudeheat +usa + + + + + +F A Y +f0420reute +r f BC-U.S.-PRODUCER-ENERGY 03-13 0099 + +U.S. PRODUCER ENERGY PRICES RISE IN FEBRUARY + WASHINGTON, March 13 - Prices of wholesale finished energy +goods in the United States were up in February, rising by 4.0 +pct after a 9.8 pct rise in January, the Labor Department said. + The Producer Price Index for finished energy goods has +fallen 20.9 pct in the past 12 months. + Heating oil prices rose 3.0 pct in February after a 18.0 +pct rise in January, the department said. + Gasoline prices rose by 5.5 pct last month after a 15.7 +pct January rise, the department said. Natural gas prices rose +1.8 pct after a 4.2 pct rise in January. + Energy goods at the intermediate stage of processing rose +2.7 pct in February after rising 3.5 pct in January and were +down 16.1 pct over the past 12 months, the Labor Department +said. + Prices for crude energy goods, such as crude oil, coal and +gas at the wellhead, rose 2.6 pct last month after a 10.0 pct +January rise. They were down 11.6 pct from February 1986, the +department said. + At the intermediate stage, liquefied petroleum gas prices +rose 10.1 pct last month after a 5.0 pct January rise and were +41.0 pct below prices a year earlier, the department said. + Residual fuel prices rose 16.7 pct in February after a 13.4 +pct rise a month earlier and were off 17.4 pct in 12 months. + Electric power prices fell 0.3 pct last month, after a 1.3 +pct January decline, and were down 3.6 pct from a year ago. + Crude oil prices rose 4.4 pct in February, after a 19.7 pct +January rise and were off 21.3 pct from the year ago level. + Prices of natural gas at the wellhead rose 1.8 pct in +February after rising 4.2 pct a month earlier and were 14.8 pct +lower than they were 12 months earlier, the department said. + Coal costs were down 0.3 pct last month after rising 0.4 +pct in January and were down 0.8 pct from a year ago. + Reuter + + + +13-MAR-1987 16:23:07.43 +earn + + + + + + +F +f0423reute +b f BC-******WEYERHAEUSER-CO 03-13 0012 + +******WEYERHAEUSER SAID IT SEES SIGNIFICANT INCREASES IN EARNINGS IN 1987 +Blah blah blah. + + + + + +13-MAR-1987 16:26:35.20 + +usaparaguay + + + + + +RM A +f0431reute +r f BC-BANK-OF-AMERICA-<BAC> 03-13 0105 + +BANK OF AMERICA <BAC> SEEKS TO QUIT PARAGUAY + NEW YORK, March 13 - BankAmerica Corp is seeking a buyer +for its branch in Asuncion, Paraguay, a spokesman in Miami for +the bank holding company said. + "We are in ongoing negotiations for the sale of our +Paraguay operations," the spokesman said. He declined to name +the possible buyer. + A sale of the Paraguayan operations, which employ about 80 +people, would be consistent with Bank of America's strategy of +concentrating its international efforts on wholesale banking, +he added. The bank has sold operations in a number of countries +recently, including Italy and Sri Lanka. + Reuter + + + +13-MAR-1987 16:27:23.99 + +usa + + + + + +F +f0437reute +r f '--GE-<GE>-GETS-474.5-ML 03-13 0034 + +GE <GE> GETS 474.5 MLN DLR CONTRACT + WASHINGTON, March 13 - General Electric Co has received a +474.5 mln dlr contract for 172 F-110-GE-100 fighter jet engines +and 32 other jet engines, the Air Force said. + REUTER + + + +13-MAR-1987 16:28:15.51 + +usa + + + + + +F +f0441reute +r f BC-GENERAL-HOST-<GH>-TO 03-13 0094 + +GENERAL HOST <GH> TO APPEAL COURT RULING + STAMFORD, Conn., March 13 - General Host Corp said a +federal district judge in Wichita, Kan., affirmed a preliminary +1984 ruling that the company's Amerian Salt Co unit polluted +groundwater near a plant in Lyons, Kan. + The company said it would appeal the ruling, which calls +for actual damages of 3.1 mln dlrs and punitive damages of 10 +mln dlrs. + General Host believes it has strong grounds for a reversal +of the ruling. It reiterated that it is not including a +provision for losses in its financial statements. + American Salt, part of General Host's AMS Industries Inc +unit, has agreed with the State of Kansas to carry out an +effective clean-up plan, the company said. + In the current ruling, Federal Judge Cecil Miller affirmed +his August 1984 preliminary ruling. + The suit was brought in 1977 by a group of local +landowners, a General Host spokesman said. + Reuter + + + +13-MAR-1987 16:29:46.00 + +usa + + + + + +F +f0448reute +d f BC-MOBIL-<MOB>-GETS-107. 03-13 0028 + +MOBIL <MOB> GETS 107.2 MLN DLR CONTRACT + WASHINGTON, March 13 - Mobil Oil Corp has received a 107.2 +mln dlr contract for jet fuel, the Defense Logistics Agency +said. + REUTER + + + +13-MAR-1987 16:31:43.02 + +usa + + + + + +F +f0454reute +h f BC-IOMEGA-<IMOG>-PRESIDE 03-13 0060 + +IOMEGA <IMOG> PRESIDENT RESIGNS FOR NEW POST + ROY, Utah, March 13 - Iomega Corp said its president, +Gabriel Fusco, resigned as president to become chairman and +chief executive officer of <Sequoia Systems>. + Fusco was president and chief executive officer of Iomega +between April 1983 and January 1987, and will remain on the +company's board of directors. + + Reuter + + + +13-MAR-1987 16:33:42.42 +earn + + + + + + +F +f0461reute +f f BC-varity 03-13 0010 + +******VARITY EXPECTS TO REPORT 4TH QTR AND FULL-YEAR 1986 LOSS +Blah blah blah. + + + + + +13-MAR-1987 16:36:20.34 + +usa + + + + + +A RM +f0467reute +r f BC-GUILFORD-MILLS-<GFD> 03-13 0087 + +GUILFORD MILLS <GFD> TO SELL CONVERTIBLE DEBT + NEW YORK, March 13 - Guilford Mills Inc said it filed with +the Securities and Exchange Commission a registration statement +covering a 60 mln dlr issue of convertible subordinated +debentures. + Proceeds will be used to repay certain indebtedness and +increase working capital, as well as for general corporate +purposes. + Guilford Mills said it expects the issue will be offered +later this month. The company named Bear, Stearns and Co as +lead underwriter of the offering. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-006.sgm b/src/test/data/reuters-21578/reut2-006.sgm new file mode 100644 index 00000000000..cdda17d6906 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-006.sgm @@ -0,0 +1,2012 @@ + + +17-MAR-1987 10:59:37.95 + +usa + + + + + +A RM Y +f5264reute +r f BC-VALERO-ENERGY-<VLO>-D 03-17 0110 + +VALERO ENERGY <VLO> DEBT UPGRADED BY MOODY'S + NEW YORK, March 17 - Moody's Investors Service Inc said it +upgraded Valero Energy Corp's 120 mln dlrs of debt. + Moody's cited an improved leverage position that will +result from Valero's sale of its Valero Natural Gas subsidiary +to Valero Natural Gas Partners L.P., the partial sale of units +of that partnership to the public, and the simultaneous sale of +first mortgage bonds to institutional investors. + Raised were Valero-backed tax-exempt economic development +revenue bonds of Vincennes, Ind, to Baa-3 from B-1, Valero's +subordinated debt to Ba-1 from B-2 and depository preferred +stock to Ba-1 from B-2. + Reuter + + + +17-MAR-1987 11:01:59.32 + +usa + + + + + +F +f5272reute +r f BC-NL-<NL>-FILES-SUITS-A 03-17 0107 + +NL <NL> FILES SUITS AGAINST UNITED CATALYSTS + HIGHTSTOWN, N.J., March 17 - NL Industries Inc's NL +Chemicals Inc subsidiary said it filed two complaints against +<United Catalysts Inc> for patent infringements and +misappropriation of confidential information. + NL said the patent infringement suit alleges that United's +product, Thixogel DSS, infringes on NL's patent protecting its +Bentone 128 product. + NL said it filed the patent complaint in the United States +District Court for the Western District of Kentucky, and the +misappropriation complaint in Circuit Court, Jefferson County, +Ky. United Catalysts is based in Louisville, Ky. + Reuter + + + +17-MAR-1987 11:02:40.56 +acq +usa + + + + + +A +f5277reute +d f BC-IRVING-TRUST-<V>-BUYS 03-17 0060 + +IRVING TRUST <V> BUYS GULF/WESTERN <GW> UNIT + NEW YORK, March 17 - Irving Bank Corp said it bought the +factoring division of Associates Commercial Corp, a unit of +Gulf and Western Co Inc's Associates Corp of North America. + The terms of the previously announced deal were not +disclosed. + It said the assets were transferred to Irving Commercial +Corp. + + Reuter + + + +17-MAR-1987 11:03:32.29 + +usa + + + + + +F +f5283reute +r f BC-DITTLER-BROTHERS-SEEK 03-17 0098 + +DITTLER BROTHERS SEEK LOTTERY INVESTIGATIONS + ATLANTA, March 17 - Dittler Brothers called for +investigations by the attorneys general of 24 states in +connection with possible violation of state lottery laws by +Bally Manufacturing Corp <BLY> and its subsidiary, Scientific +Games. + Dittler Brothers said it requested the states' law +enforcement chiefs to investigate the companies following last +week's determination by a court-appointed auditor that +Scientific furnished erroneous information to those 24 state +lottery officials. + The states named are spread throughout the country. + Reuter + + + +17-MAR-1987 11:07:22.82 +earn +usa + + + + + +F +f5302reute +d f BC-AMRE-INC-<AMRE>-3RD-Q 03-17 0039 + +AMRE INC <AMRE> 3RD QTR JAN 31 NET + DALLAS, MArch 17 - + Shr five cts vs one ct + Net 196,986 vs 37,966 + Revs 15.5 mln vs 8,900,000 + Nine mths + Shr 52 cts vs 22 cts + Net two mln vs 874,000 + Revs 53.7 mln vs 28.6 mln + Reuter + + + +17-MAR-1987 11:07:47.91 +grainwheat +usa + + + + + +C G +f5304reute +u f BC-KANSAS-LEGISLATOR-TO 03-17 0112 + +KANSAS LEGISLATOR TO OFFER U.S. 0/92 BILL TODAY + WASHINGTON, March 17 - U.S. Rep. Dan Glickman, D-Kan., +chairman of the House Agriculture subcommittee on wheat, +soybeans and feedgrains, said he would today introduce a bill +to apply the so-called 0/92 concept to wheat and feedgrains +producers. + Glickman told Reuters the measure would allow 1987 winter +wheat producers and 1988 feedgrains producers the possibility +of receiving no less than 92 pct of their income support +payments regardless of how much acreage they planted. + He also said his bill would protect program participants +from reduced income payments in the event market prices rose +above the loan rate. + Reuter + + + +17-MAR-1987 11:09:12.10 + +uk + + + + + +RM +f5308reute +b f BC-C.-ITOH-FINANCE-(EURO 03-17 0112 + +C. ITOH FINANCE (EUROPE) ISSUES EUROBOND + LONDON, March 17 - C. Itoh Finance (Europe) Ltd is issuing +a 30 mln dlr deferred coupon eurobond, due March 30, 1992 and +priced at 100.1 pct, Wako International (Europe) Ltd said as +lead manager. + From the third year the bonds will pay interest at a rate +of four pct over six month London interbank borrowed rate +(Libor). They will be issued in denominations of 50,000 dlrs +and will be listed in Luxembourg. Fees of 0.1 pct comprise two +basis points for management and underwriting and eight points +for selling. + Co-leads are Mitsui Trust International and Pru-Bache +Securities International. Pay date is March 30. + The transaction is guaranteed by C. Itoh and Co (Hong Kong) +Ltd, Wako International said. + REUTER + + + +17-MAR-1987 11:09:38.54 + +usa + + + + + +F +f5309reute +r f BC-INTERNATIONAL-LEASE-< 03-17 0083 + +INTERNATIONAL LEASE <ILFC> SELLS TWO JETS + BEVERLY HILLS, Calif., March 17 - International Lease +Finance Corp said it sold two Boeing 737-200 aircraft and +leased one 737-200 in two transactions valued at 28 mln dlrs. + It said the sales will result in a pre-tax gain for its +second fiscal quarter ending May 31. + The two jets were sold for 18 mln dlrs to an investor group +and the third was leased for five years to Pacific Western +Airlines Ltd of Calgary, Alberta, International Lease said. + Reuter + + + +17-MAR-1987 11:10:08.50 + +usa + + + + + +F +f5314reute +r f BC-HITECH-ENGINEERING-<T 03-17 0057 + +HITECH ENGINEERING <THEX> COMPLETES STOCK SALE + MCLEAN, Va., March 17 - HiTech Engineering Co said it +completed the private sale of 200,000 shares of its common +stock to its chairman and president, Francine Prokoski, for +37,500 dlrs. + The company said the proceeds will be used to develop +products under a contract with a private company. + Reuter + + + +17-MAR-1987 11:10:19.73 +earn +usa + + + + + +F +f5316reute +d f BC-PORTA-SYSTEMS-CORP-<P 03-17 0042 + +PORTA SYSTEMS CORP <PSI> 4TH QTR JAN 31 NET + SYOSSET, N.Y., March 17 - + Shr 10 cts vs 11 cts + Net 547,000 vs 579,000 + Sales 11.0 mln vs 11.1 mln + Year + Shr 46 cts vs 52 cts + Net 2,500,000 vs 2,841,000 + Sales 40.7 mln vs 40.5 mln + Reuter + + + +17-MAR-1987 11:14:30.93 + +usa + + + + + +F +f5335reute +r f BC-CALIFORNIA-ENERGY-<CE 03-17 0055 + +CALIFORNIA ENERGY <CECI> INITIAL OFFER STARTS + SANTA ROSA, Calif., March 17 - California Energy Co Inc +said an initial public offering of 1,900,000 common shares is +underway at 7.50 dlrs each through underwriters led by Laidlaw +Adams and Peck Inc. + The geothermal power company said the offering is expected +to close March 19. + Reuter + + + +17-MAR-1987 11:15:07.84 + +usa + + +amex + + +F +f5338reute +r f BC-DIVI-HOTELS-<DVH>-WAR 03-17 0027 + +DIVI HOTELS <DVH> WARRANTTRADE ON AMEX + NEW YORK, March 17 - Divi Hotels NV of Aruba said its +warrants have started trading today on the <American Stock +Exchange>. + Reuter + + + +17-MAR-1987 11:15:13.82 +earn + + + + + + +F +f5339reute +f f BC-******FEDERATED-DEPAR 03-17 0012 + +******FEDERATED DEPARTMENT STORES INC 4TH QTR SHR 3.64 DLRS VS 3.16 DLRS +Blah blah blah. + + + + + +17-MAR-1987 11:15:25.35 +earn +usa + + + + + +F +f5340reute +r f BC-<WARNACO-GROUP-INC>-E 03-17 0072 + +<WARNACO GROUP INC> EIGHT MTHS JAN THREE NET + NEW YORK, March 17 - + Oper net 46.6 mln + Revs 392 mln + 12 mths + Oper net 65 mln vs 47.1 mln + Revs 590 mln vs 591 mln + NOTE: Eight months represents earnings following +acquisition in May 1986 when company went private. + Period ending Jan. 3, 1987 excludes 42.3 mln dlrs of +interest expenses, 41.6 mln dlrs of acquisition adjusments, and +1.7 mln dlrs of income taxes. + Reuter + + + +17-MAR-1987 11:15:35.39 + +ukirelandusa + + + + + +RM +f5341reute +b f BC-BANK-OF-IRELAND-LAUNC 03-17 0099 + +BANK OF IRELAND LAUNCHES U.S. PAPER PROGRAM + LONDON, March 17 - Bank of Ireland said it launched in the +U.S. Market a commercial paper program for up to 200 mln dlrs, +becoming the first Irish issuer of paper in that market. + It said the first tranche of an undisclosed amount was sold +today through Goldman Sachs and Co Inc and that the paper last +week had received the top A-1/P-1 rating of Standard and Poor's +Corp and Moody's Investors Service Inc, respectively. + In a statement, the Bank of Ireland noted that the U.S. +Paper market will provide it with a new source of funding. + REUTER + + + +17-MAR-1987 11:15:43.66 + +ussrusa +james-baker +worldbankimf + + + +A RM +f5342reute +b f BC-BAKER-SAYS-U.S.-OPPOS 03-17 0077 + +BAKER SAYS U.S. OPPOSES SOVIET BANK MEMBERSHIP + WASHINGTON, March 17 - Treasury Secretary James Baker said +the U.S. opposes Soviet membership of the World Bank or the +International Monetary Fund. + Baker told a House foreign affairs subcommittee, "I think +our position is absolutely clear on that ... We do not support +and will not support Soviet membership in the World Bank or the +IMF." + Baker said the U.S. position was "unqualified and +unconditional." + The secretary observed that he has written to congressman +Jack Kemp, a New York Republican who is also a presidential +contender, outlining the U.S. position. + Baker was responding to a questioner who noted that World +Bank President Barber Conable has in the past suggested future +Soviet membership could take place. + Ever since Soviet leader Mikhail Gorbachev suggested Soviet +membership in the General Agreement on Tariffs and Trade -- +which was also rejected -- there has been speculation Moscow +was interested in joining the international institutions. + Reuter + + + +17-MAR-1987 11:16:02.24 +earn +usa + + + + + +F +f5345reute +d f BC-GANTOS-INC-<GTOS>-4TH 03-17 0053 + +GANTOS INC <GTOS> 4TH QTR JAN 31 NET + GRAND RAPIDS, MICH., March 17 - + Shr 43 cts vs 37 cts + Net 2,276,000 vs 1,674,000 + Sales 31.9 mln vs 23.9 mln + Avg shrs 5.3 mln vs 4.5 mln + Year + Shr 90 cts vs 69 cts + Net 4,508,000 vs 3,096,000 + Sales 98.4 mln vs 75.0 mln + Avg shrs 5.0 mln vs 4.5 mln + Reuter + + + +17-MAR-1987 11:16:08.19 +earn +usa + + + + + +F +f5346reute +d f BC-<ATLANTIC-EXPRESS-INC 03-17 0027 + +<ATLANTIC EXPRESS INC> 1ST HALF DEC 31 NET + NEW YORK, March 17 - + Shr not given + Net 788,099 + Revs 15.5 mln + NOTE: Company went public during 1986. + Reuter + + + +17-MAR-1987 11:16:42.57 + +netherlands + + + + + +RM +f5349reute +b f BC-RABOBANK-LAUNCHES-250 03-17 0083 + +RABOBANK LAUNCHES 250 MLN GUILDER BULLET + UTRECHT, Netherlands, March 17 - Rabobank Nederland B.A. +Said it is launching under its own management a 250 mln guilder +eight-year bullet bond with a 6-3/4 pct coupon and priced at +par. + No early redemption is permitted on the bond which will be +paid back in full on April 15, 1995. + Denominations are in 1,000 and five times 1,000 guilders. +Subscription closes March 23, payment is April 15. Listing will +be on the Amsterdam Stock Exchange. + REUTER + + + +17-MAR-1987 11:18:43.18 +acq +usa + + + + + +F +f5358reute +u f BC-SPENDTHRIFT-FARMS-<SF 03-17 0049 + +SPENDTHRIFT FARMS <SFI> GETS BID FOR CONTROL + LEXINGTON, Ky., March 17 - Spendthrift Farm Inc said it has +received three tentative proposals to acquyire control of the +company. + It said it is evaluating the proposals and will not comment +further unless a definitive agreement is reached. + Reuter + + + +17-MAR-1987 11:18:58.30 + +usa + + + + + +F +f5360reute +d f BC-BIOTECHNICA-<BIOT>-HA 03-17 0105 + +BIOTECHNICA <BIOT> HAS NEW AGRICULTURE UNIT + CAMBRIDGE, Mass., March 17 - BioTechnica International said +it established a new subsidiary, BioTechnica Agriculture, to +develop and commercialize microbial and plant products for +improving crops. It said the unit will be based in Overland +Park, Kansas. + It said Charles H. Baker, former president of Rohm and Haas +Co's <ROH> Rohm and Haas Seed Inc affiliate, has been named +president of the new agriculture unit. The company said Baker +will also act for a limited time as president of <Chaco +Enterprises Inc>, formed to acquire the Hybrex hybrid wheat +technology from Rohm and Haas. + Reuter + + + +17-MAR-1987 11:19:09.96 + +usa + + + + + +F +f5361reute +d f BC-SUNWORLD-<SUNA>-HAS-H 03-17 0103 + +SUNWORLD <SUNA> HAS HIGHER LOAD FACTOR + LAS VEGAS, Nev., March 17 - Sunworld International Airways +Inc said its February load factor rose to 53 pct from 46.1 pct +a year earlier and its year-to-date load factor was up to 52 +pct from the 51 pct posted for the same period last year. + February revenue passenger miles rose to 27.4 mln from 26.4 +mln, but year-to-date revenue miles declined to 59.7 mln from +60.4 mln. + Available seat miles for the month dropped to 51.7 mln from +57.2 mln and for the two month period available miles totaled +115.3 mln, down from last year's 119.2 mln, Sunworld +International said. + Reuter + + + +17-MAR-1987 11:22:34.18 +crude +usa + +opec + + + +F Y +f5371reute +u f BC-SHEARSON-LEHMAN-UPGRA 03-17 0109 + +SHEARSON LEHMAN UPGRADES U.S. OIL STOCKS + NEW YORK, March 17 - Analyst Sanford Margoshes of Shearson +Lehman Brothers said he recommended a number of oil stocks +today now that it is apparent that OPEC has succeeded in +holding to its prescribed production quotas. + "It is clear that OPEC, through jawboning and quota +restraint, will boost the price of oil," Margoshes said. + Prices of oil stocks rose sharply today in response to +higher oil prices and optimism about OPEC quotas. Margoshes +said he recommends Imperial Oil <IMO.A>, up 1/2 to 49-1/8, +Standard Oil Co <SRD>, 7/8 to 62-3/4, Exxon <XON> one to +83-1/8, and Chevron <CHV> 1-1/8 to 54-7/8. + In addition, Margoshes said he recommended Atlantic +Richfield <ARC> on a short-term basis, though he said he is +still suspect about its debt situation. Atlantic Richfield rose +1-3/4 to 77. + He said "the market could come down to test the 16 dlr a +barrel level again, but the main thrust of investing in oil is +positive right now. Before the year is out we will see higher +oil prices." + He noted that belief that the government is interested in +raising the strategic reserves is factored into the rise in oil +stocks today. + Reuter + + + +17-MAR-1987 11:24:30.25 + +belgiumwest-germany +kohldelors +ec + + + +RM +f5381reute +u f BC-EC-COMMISSION-TO-VISI 03-17 0104 + + EC COMMISSION TO VISIT BONN AT KOHL'S INVITATION + BRUSSELS, March 17 - West German Chancellor Helmut Kohl has +invited the European Community's 17-man Commission for talks in +Bonn next month in a bid to repair strained relations, EC +diplomats said. + The Commissioners, led by President Jacques Delors, will +pay a two-day visit to Bonn on April 1-2 when they were due for +a meeting with the principal West German cabinet members. + The meeting, the first of its kind between the Commission +and the government of a member state, was originally meant to +focus on problems posed by West Germany's federal constitution. + But they said the meeting was now likely to be dominated by +Commission plans to restructure the EC's exhausted finances and +its costly farm policy, which have provoked strong opposition +from Bonn. + Kohl has written two letters to Delors, complaining that +the plans would hit West German farmers hard. His farm +minister Ignaze Kiechle has publicly criticised the two German +members of the Commission for failing to oppose them. + This caused protest from Brussels where the Commission +tries to guard the independence of its members from the +governments that nominate them. + REUTER + + + +17-MAR-1987 11:25:02.06 +copper +zambiasouth-africa + + + + + +C M +f5382reute +u f BC-ZAMBIAN-MINISTER-CONF 03-17 0109 + +ZAMBIAN MINISTER CONFIRMS COPPER DIVERSION + LUSAKA, March 17 - Minister of Mines Patrick Chitambala +confirmed that Zambia had ended copper shipments through South +Africa and announced that its state-run mining company had +closed down its liaison office in the white-ruled republic. + He told the official Times of Zambia newspaper in an +interview the government was diverting all mineral exports +along rail routes to Dar es Salaam in Tanzania and Beira in +Mozambique. Chitambala declined to say what volume of copper +and other minerals were being shipped through these two ports, +but he said there had not been any problem with the new +arrangements. + "So far our copper has been reaching its destinations +without hindrance," he told the Times. + The Times of Zambia quoted unnamed sources as saying Zambia +exported 100,000 tonnes of copper through Dar es Salaam and +17,000 through Beira in the last quarter of 1986. Diplomatic +sources in Lusaka had earlier expressed doubts over Zambia's +ability to ship all its copper through Beira and Dar es Salaam +without causing massive bottlenecks at the ports. + Chitambala also said that the state-run Zambia Consolidated +Copper Mines (ZCCM) had closed its liaison office in +Johannesburg, since it was now redundant. + Reuter + + + +17-MAR-1987 11:25:49.37 +acq + + + + + + +F +f5385reute +f f BC-******TAFT-CHAIRMAN'S 03-17 0012 + +******TAFT CHAIRMAN'S GROUP RAISES TAFT BROADCASTING BID TO 150 DLRS/SHARE +Blah blah blah. + + + + + +17-MAR-1987 11:26:47.36 +acq +usa + + + + + +F +f5388reute +d f BC-DEVELOPMENT-CORP-OF-A 03-17 0078 + +DEVELOPMENT CORP OF AMERICA <DCA> MERGED + HOLLYWOOD, Fla., March 17 - Development Corp of America +said its merger with Lennar Corp <LEN> was completed and its +stock no longer existed. + Development Corp of America, whose board approved the +acquisition last November for 90 mln dlrs, said the merger was +effective today and its stock now represents the right to +receive 15 dlrs a share. + The American Stock Exchange said it would provide further +details later. + Reuter + + + +17-MAR-1987 11:27:21.25 + +usabrazil +james-baker + + + + +RM A +f5391reute +u f BC-TREASURY'S-BAKER-CALL 03-17 0090 + +TREASURY'S BAKER CALLS FOR NEW BRAZIL PLAN + WASHINGTON, March 17 - Treasury Secretary James Baker said +that Brazil should come up with a new economic plan if it hopes +to get additional assistance from commercial banks and others. + In testimony before a House appropriations subcommittee, +Baker said that he had given that message to Brazilian +officials earlier this month when they met for talks in +Washington. + He said that the so-called Cruzado Plan had worked for a +while, but that new efforts by the government are now required. + Baker made it clear that he backed the decision by the +Paris Club official creditors to reschedule loans to Brazil, +even though the country later froze its payments to commercial +bank creditors. + He said that the official loans are being serviced and that +this was a result of the rescheduling. + Reuter + + + +17-MAR-1987 11:27:51.45 + +usa + + +nasdaq + + +F +f5394reute +d f BC-CALIFORNIA-MICRO-<CAM 03-17 0031 + +CALIFORNIA MICRO <CAMD> TRADES ON NASDAQ + MILPITAS, Calif., March 17 - California Micro Devices Corp +said its stock was included in the March 17 expansion of the +NASDAQ market system. + Reuter + + + +17-MAR-1987 11:28:09.98 +acq +usa + + + + + +F +f5396reute +d f BC-TEVA-<TEVIY>-SELLS-PR 03-17 0067 + +TEVA <TEVIY> SELLS PROMEDICO SUBSIDIARY + NEW YORK, March 17 - Teva Pharmaceutical Industries Ltd, +based in Israel, said it sold its wholly owned Promedico +subsidiary, to foreign investors for four mln dlrs. + It said the book value of the unit is about 2.2 mln dlrs. + Teva said it will continue to market Promedico's products +through its wholly owned subsidiary, Salomon, Levin and Elstein +Ltd. + + Reuter + + + +17-MAR-1987 11:28:28.04 + +usa + + + + + +F +f5398reute +d f BC-ERC-<ERC>-GETS-THIRD 03-17 0083 + +ERC <ERC> GETS THIRD CONTRACT + FIARFAX, Va., March 17 - ERC International said its +Facilities Management Group subsidiary, ERCI Facilities Service +Corp, was awarded a 2.1 mln dlrs contract in the drug +repository field, the third such contract in nine months. + It said that under the five-year contract, it will manage +the National Cancer Institutes's pre-clinical drug repository +of more than 400,000 drugs and chemicals used to test antitumor +activity in animals and tissue culture systems. + Reuter + + + +17-MAR-1987 11:29:40.89 + +usa +james-baker + + + + +A RM +f5404reute +u f BC-BAKER-SAYS-U.S.-NOT-S 03-17 0096 + +BAKER SAYS U.S. NOT SEEKING IADB VETO + WASHINGTON, March 17 - Treasury Secretary James Baker said +that the United States was not seeking loan veto in its +negotiation for voting power at the Inter-American Development +Bank. + Discussing the ongoing negotiation, Baker said the U.S. +position is that the countries that pay in the most should have +the greatest say over the loan decisions. + The U.S. is seeking the power to block loan votes with one +other country, and the issue will be discussed in Miami later +this month at the annual meeting of the Latin development bank. + Reuter + + + +17-MAR-1987 11:31:47.85 +earn +usa + + + + + +F +f5409reute +r f BC-NEW-MILFORD-SAVINGS-B 03-17 0025 + +NEW MILFORD SAVINGS BANK <NMSB> RAISES PAYOUT + NEW MILFORD, Conn., March 17 - + Qtly div 25 cts vs 20 cts prior + Pay April 21 + Reord March 27 + Reuter + + + +17-MAR-1987 11:32:05.95 +acq +usa + + + + + +F +f5411reute +b f BC-K-MART-<KM>-ENDS-TALK 03-17 0057 + +K MART <KM> ENDS TALKS TO SELL STORES + CHICAGO, March 17 - K Mart Corp said recent talks to sell +65 remaining Kresge variety stores and their underlying real +estate to F.W. Woolworth Co <Z> have ended. + Robert Stevenson, K Mart vice president, told Reuters the +talks, which began about six weeks ago, ended. He declined to +give a reason. + Kresge is the forerunner of what is now the K Mart chain. +The name was changed to K Mart in 1977, Stevenson said. + "We're selling and buying real estate in our real estate +division, and Woolworth was interested in some of our +properties. The talks were of a casual nature," he said. + The 65 Kresge stores that are scattered around the country +in downtown and suburban locations, he said. + Stevenson said K Mart will continue to operate the stores. +"The stores are profitable. The only decision K Mart has made +is that we will continue to operate them," he said + Kresge had been a nationwide chain of 900 variety stores. + Reuter + + + +17-MAR-1987 11:32:21.74 +earn +usa + + + + + +F +f5413reute +d f BC-INSTITUTE-OF-CLINICAL 03-17 0081 + +INSTITUTE OF CLINICAL PHARM PLC <ICPYY> YEAR + NEW YORK, March 17 - + Shr 20 ct vs 27 cts + Net 1,048,000 vs 1,368,000 + Revs 9,457,000 vs 5,386,000 + NOTE: Dollar amounts converted from Irish pounds at noon +buying rate of the Federal Reserve Bank of New York at Dec 31, +1986, of 1.4105 dlr per one Irish pound. The equivalent rate at +Dec 31, 1985, was 1.2470 dlr equals one Irsh pound. Full name +of company is The Institute of Clinical Pharmacology PLC, based +in Dulbin, Ireland. + Reuter + + + +17-MAR-1987 11:33:26.98 + + +lawson + + + + +RM +f5419reute +f f BC-LAWSON-SAYS-U.K.-BASI 03-17 0012 + +******LAWSON SAYS U.K. BASIC RATE INCOME TAX TO BE CUT TO 27 PCT FROM 29 PCT +Blah blah blah. + + + + + +17-MAR-1987 11:36:40.54 +gnpbop +uk +lawson + + + + +C +f5431reute +b f BC-U.K.-GROWTH-RATE-SEEN 03-17 0113 + +U.K. GROWTH RATE SEEN AT THREE PCT THIS YEAR + LONDON, March 17 - Chancellor of the Exchequer Nigel +Lawson, presenting his budget for fiscal 1987/88 to parliament, +said U.K. Economic growth was forecast at three pct in calendar +1987. + He said the Treasury expected a current account balance of +payments deficit in 1987 of 2.5 billion stg, after a 1.1 +billion shortfall in 1986. Inflation is expected to be 4.0 pct +at the end of 1987, he said, adding it may exceed 4.5 pct by +the summer before falling back to 4.0 pct by the end of the +year. + The planned PSBR for 1987/88 was 4.0 billion stg unchanged +when compared with the likely outturn for fiscal 1986/87, +Lawson said. + Although no explicit target was set for the broad sterling +M3 money supply, Lawson said broad money will continue to be +taken into account in assessing monetary conditions as well as +the exchange rate. + The low outturn of the PSBR in 1986/87 was mainly due to +the buoyancy of non-oil tax revenues in general, and the +corporation tax paid by an increasingly profitable business +sector in particular. + On oil prices, Lawson said he was sticking to his earlier +assumption that North Sea crude prices will average 15 dlrs per +barrel in calendar 1987. The treasury would strive to keep the +PSBR at 1.0 pct of GDP in future, he said. + Reuter + + + +17-MAR-1987 11:39:54.35 + +usa + + + + + +F +f5452reute +r f BC-BUTLER-<BTLR>-TO-BUY 03-17 0061 + +BUTLER <BTLR> TO BUY BACK 600,000 SHARES + KANSAS CITY, MO., March 17 - Butler Manufacturing Co said +its board authorized the repurchase of up to 600,000 shares, or +12 pct of its outstanding common stock. + It said purchases will be made in open market and private +transactions through Kidder, Peabody and Co. + Butler currently has 5,001,848 shares outstanding. + Reuter + + + +17-MAR-1987 11:40:05.58 + +usa + + + + + +F +f5453reute +r f BC-ROYAL-PALM-<RPAL>-SAY 03-17 0105 + +ROYAL PALM <RPAL> SAYS RESTRICTIONS LIFTED + WEST PALM BEACH, Fla., March 16 - Royal Palm Savings +Association said it has entered into an agreement with the +Federal Home Loan Bank Board and the Florida Department of +Banking and Finance resulting in the removal of limitations +which had severely restricted its growth and lending. + The company said it will now be permitted to grow about 70 +mln dlrs in calendar 1987, or about 15 pct for this year, and +at the same rate thereafter. + Royal Palm said under the accord, it will resume commercial +and nonresidential lending but will place substantial emphasis +on residential loans. + The company said it agreed to adopt new policies and +procedures but did not elaborate. + Reuter + + + +17-MAR-1987 11:40:26.25 + +west-germany + + + + + +G +f5457reute +d f BC-WEST-GERMAN-FEED-OUTP 03-17 0102 + +WEST GERMAN FEED OUTPUT SEEN DECLINING + BONN, March 17 - West German feedstuffs production is +expected to decline further after it dropped to 16.5 mln tonnes +in 1986 from 16.7 mln the previous year, the West German Feed +Stuff Industry Association (MFI) said. + Association president Ulrich Wagner told a news conference +West Germany's rate of self sufficiency in the feedstuffs +sector is expected to fall below 70 pct this year from around +75 pct in 1986. + He attributed the expected decline to introduction of milk +quotas in 1984, aimed at curbing EC milk production, and to +cheaper imports from abroad. + "Our industry's output is not even close to stagnation," +Wagner said. "In the long term we expect annual production to +decline steadily." + The only sector which saw a slight increase last year, by +0.6 pct, was feed for poultry which rose to 3.25 mln tonnes +from 3.23 mln, he said. + Wagner predicted that the sales volume in feed for dairy +cattle will decline even more this year because of the further +cut in milk output from April. + Reuter + + + +17-MAR-1987 11:40:46.06 +earn +usa + + + + + +F +f5460reute +d f BC-ICN-BIOMEDICALS-INC-< 03-17 0034 + +ICN BIOMEDICALS INC <BIMD> 1ST QTR FEB 28 NET + COSTA MESA, Calif., March 17 - + Shr 10 cts vs eight cts + Net 856,000 vs 574,000 + Sales 9,593,000 vs 9,232,000 + Avg shrs 8,809,000 vs 6,969,000 + Reuter + + + +17-MAR-1987 11:40:52.10 +earn +usa + + + + + +F +f5461reute +d f BC-APPLIED-CIRCUIT-TECHN 03-17 0043 + +APPLIED CIRCUIT TECHNOLOGY <ACRT> 1ST QTR LOSS + ANAHEIM, Calif., March 17 - Period ended January 31. + Shr loss two cts vs loss 12 cts + Net loss 192,370 vs loss 1,494,146 + Revs 6,751,830 vs 2,278,842 + Note: Full name Applied Circuit Technology Inc. + Reuter + + + +17-MAR-1987 11:40:57.61 +earn +usa + + + + + +F +f5463reute +s f BC-FRISCH'S-RESTAURANTS 03-17 0025 + +FRISCH'S RESTAURANTS INC <FRS> SETS QUARTERLY + CINCINNATI, March 17 - + Qtly div 5-1/2 cts vs 5-1/2 cts prior + Pay April 16 + Record April Six + Reuter + + + +17-MAR-1987 11:42:11.71 +money-fxinterest + + + + + + +V RM +f5465reute +f f BC-******FED-SETS-TWO-BI 03-17 0010 + +******FED SETS TWO BILLION DLR CUSTOMER REPURCHASE, FED SAYS +Blah blah blah. + + + + + +17-MAR-1987 11:44:54.11 + +usa + + +nyse + + +F +f5478reute +u f BC-NYSE-REVIEWS-PROGRAM 03-17 0037 + +NYSE REVIEWS PROGRAM TRADING + NEW YORK, March 17 - The <New York Stock Exchange> said it +is undertaking a review of the long-term effects on securities +markets of computer-driven trading techniques known as program +trading. + The NYSE said, "The study will review major new trading +techniques involving programmed portfolio hedging and index +arbitrage for their potential benefits and risks to the +financial system. It will also explore the regulatory +implications of these trading techniques and whether their +increased use could possibly lead to market abuse." + The exchange said a final report is expected before the end +of 1987. It said program trading is becoming increasingly +important as a market factor. + Reuter + + + +17-MAR-1987 11:45:10.92 +money-fxinterest +usa + + + + + +V RM +f5479reute +b f BC-/-FED-ADDS-RESERVES-V 03-17 0061 + +FED ADDS RESERVES VIA CUSTOMER REPURCHASES + NEW YORK, March 17 - The Federal Reserve entered the U.S. +Government securities market to arrange two billion dlrs of +customer repurchase agreements, a Fed spokesman said. + Dealers said Federal funds were trading at 6-1/16 pct when +the Fed began its temporary and indirect supply of reserves to +the banking system. + Reuter + + + +17-MAR-1987 11:46:13.53 +earn +usa + + + + + +F +f5486reute +u f BC-FEDERATED-DEPARTMENT 03-17 0062 + +FEDERATED DEPARTMENT STORES INC <FDS> 4TH QTR + CINCINNATI, March 17 - Jan 31 end + Shr 3.64 dlrs vs 3.16 dlrs + Net 171.3 mln vs 154.0 mln + Sales 3.44 billion vs 3.23 billion + Avg shrs 47.1 mln vs 48.8 mln + Year + Oper shr 6.23 dlrs vs 5.88 dlrs + Oper net 301.9 mln vs 286.6 mln + Sales 10.51 billion vs 9.98 billion + Avg shrs 48.5 mln vs 48.8 mln + NOTE: Latest year net excludes 14.3 mln dlr charge from +loss on early debt extinguishment. + Net includes charges 15.7 mln dlrs in both periods of +latest year vs charges 23.9 mln dlrs in both periods of earlier +year from merger of divisions. + Investment tax credits three mln dlrs vs 8,900,000 dlrs in +quarter and 4,900,000 dlrs vs 16.4 mln dlrs in year. + Latest year net includes nine mln dlr provision for loss on +disposition of two Abraham and Strauss stores and preopening +expenses for another. + Latest year net includes gain from sale of interest in Fort +Worth, Texas, shopping center of 9,500,000 dlrs. + Latest year net both periods includes gain 9,100,000 dlrs +from sale of interest in Memphis, Tenn., shopping center. + Prior year net includes gain 6,600,000 dlrs on sale of +Boston Store division. + Reuter + + + +17-MAR-1987 11:46:42.56 +earn +usa + + + + + +F +f5492reute +r f BC-CLOTHESTIME-INC-<CTME 03-17 0042 + +CLOTHESTIME INC <CTME> 4TH QTR NET + ANAHEIM, Calif., March 17 - + Shr 12 cts vs 10 cts + Net 1,683,000 vs 1,407,000 + Sales 42.2 mln vs 28.8 mln + Year + Shr 83 cts vs 70 cts + Net 11,908,000 vs 10,005,000 + sales 160.3 mln vs 126.5 mln + Reuter + + + +17-MAR-1987 11:47:10.74 + +canada + + + + + +E F Y +f5496reute +r f BC-phoenix-canada-oil-to 03-17 0103 + +PHOENIX CANADA OIL TO APPEAL RULING + Toronto, March 17 - <Phoenix Canada Oil Co Ltd> said it +intends to appeal a ruling in U.S. Federal District Court of +Delaware on its suit against Texaco Inc <TX>, Chevron Corp +<CHV>, Chevron's Gulf Oil unit and their Ecuador subsidiaries. + The court ruled against Phoenix's claim that a royalty it +held should have entitled it to a share of the 160 mln U.S. +dlrs paid to the defendants when they sold 62.5 pct of their +working interest in Ecuador oil operations, Phoenix said. + However, the court did award Phoenix 1,250,000 Canadian +dlrs in underpayments, the company said. + Phoenix Canada Oil said the fiduciary relationship that +existed between Phoenix, as the royalty owner, and the +defendants, as the working interest operators, was fundamental +in the oil industry and was not reflected in the court's +ruling. + Reuter + + + +17-MAR-1987 11:47:33.87 + +usa + + + + + +F +f5500reute +r f BC-GANNETT-<GCI>-SEEKS-T 03-17 0046 + +GANNETT <GCI> SEEKS TO DOUBLE AUTHORIZED SHARES + WASHINGTON, March 17 - Gannett Co Inc said it will ask +shareholders at the May Seven annual meeting to approve a +doubling of authorized common shares to 400 mln and limitations +on the liability of directors under Delaware law. + Reuter + + + +17-MAR-1987 11:47:39.87 +earn +usa + + + + + +F +f5501reute +d f BC-VIDEO-LIBRARY-INC-<VL 03-17 0055 + +VIDEO LIBRARY INC <VLVL> 4TH QTR LOSS + SAN DIEGO, Calif.,March 17 - + Shr loss two cts vs profit three cts + Net loss 59,299 vs profit 88,843 + Revs 3,487,693 vs 2,123,488 + Year + Shr profit 25 cts vs loss two cts + Net profit 816,395 vs loss 44,541 + Revs 12.2 mln vs 7,413,328 + Avg shrs 3,208,472 vs 2,348,559 + Reuter + + + +17-MAR-1987 11:47:50.38 + +finland + + + + + +RM +f5502reute +r f BC-CONSERVATIVE-GAINS-MA 03-17 0112 + +CONSERVATIVE GAINS MAY SPEED FINNISH MARKET REFORM + By Simon Haydon, Reuters + HELSINKI, March 17 - Conservative gains in Finnish general +elections could speed liberalisation of financial markets, +though there will not be a radical economic restructuring, +conservative officials and economic analysts said. + The conservatives gained nine new seats in parliament after +the two-day elections, which ended yesterday, and political +commentators say social democrat Prime Minister Kalevi Sorsa is +likely to be replaced by a centre-right coalition. + International spokesman Pasi Natri told Reuters: "we are +willing to liberalise the economy as much as possible." + Helsinki analysts said the outgoing centre-left coalition +had introduced major reforms of money and stock markets in its +period of government between 1983 and 1987. + They said Finnish conservatives bore little resemblance to +other European conservative movements and had, for example, +shelved privatisation policies to increase their popularity. + Finnish trade affairs are dominated by its special ties +with its neighbour, The Soviet Union, and a new centre-right +coalition could alter this relationship, the analysts said. + The two countries have a long-term pact under which trade +must be balanced in value. The 1987 accord signed in January +agreed bilateral trade totalling about 30 billion markka. + Finland exports finished products to the USSR, with crude +oil accounting for 80 pct of imports. + The Centre Party said before the elections that Fenno- +Soviet trade would have to be cut because Finland had to trim +exports when the value of Moscow's oil exports to Finland fell. + Finnish financial markets reacted cautiously to the +election news, with little movement in the markka or on the +Helsinki stock exchange. + Securities analysts said the market would respond positively +if a centre-right coalition was formed, but added it was too +early to exclude the possibility that social democrats would +hang on to power. + The spokesman said conservatives favoured legislation +governing the stock market to prevent "casino-style behaviour." + He said the conservatives also favoured the establishment +of an internal market between the Nordic countries. + International capital markets were becoming more and more +important, he said, adding conservatives would speed up the +development of Finland's capial markets. + He said the conservatives supported the bilateral trade ties +with Moscow, but that links with western Europe should be +studied. Finland is a member of the European Free Trade +Association ( EFTA). + Negotiations between the major Finnish political parties +are likely to be protracted, and the shape of the new +government will probably not be established before the start of +April. + Conservatives hold 44 seats now, The Centre Party gained +three to 40 and the social democrats lost one, and now hold 56 +seats. + REUTER + + + +17-MAR-1987 11:47:58.01 + +usabrazil + + + + + +F A RM +f5503reute +b f BC-/BANKAMERICA-<BAC>-MA 03-17 0108 + +BANKAMERICA <BAC> MAY RECLASSIFY BRAZIL LOANS + WASHINGTON, March 17 - BankAmerica Corp may place its +long-term loans to Brazil on nonaccrual status if Brazil +continues to defer interest payments on the loans, the bank +holding company said in a filing with the Securities and +Exchange Commission. + BankAmerica said its outstanding loans to Brazil currently +total about 2.7 billion dlrs, including about 1.5 billion dlrs +in long-term loans and 1.2 billion dlrs in short-term loans. + The Brazilian government announced in February its +intention to stop paying interest temporarily on its long-term +public and private sector commercial bank debt. + "Continued deferral of interest payment on these obligations +could result in the loans being placed on nonaccrual status," +the banking firm said. + BankAmerica said its outstanding loans to Mexico currently +total about 2.5 billion dlrs, of which about 215 mln dlrs of +loans have been reported as either nonaccrual or past due 90 +days or more. + Outstanding loans to Venezuela currently total about 1.3 +billion dlrs, of which 241 mln dlrs of loans have been reported +as either nonaccrual or past due 90 days or more, it said. + Reuter + + + +17-MAR-1987 11:48:39.18 +earn +austria + + + + + +F +f5504reute +d f BC-CHEMIE-LINZ-EXPECTS-S 03-17 0116 + +CHEMIE LINZ EXPECTS SHARPLY HIGHER 1986 LOSS + LINZ, Austria, March 17 - State-owned <Chemie Linz AG> is +likely to record a 1986 loss of some 600 mln schillings +compared with a 340 mln loss in 1985, a company spokesman said. + Falling sales and lower world prices of fertilisers were +largely responsible for the sharp increase, along with the +effects of the dollar's fall which has helped to give U.S. +Fibre producers a competitive edge, he told Reuters. + The firm would have made a small profit in 1985 had it not +been for 456 mln schillings lost by subsidiary <Merx +HandelsgesmbH> on oil trading. Merx has since withdrawn from +the oil market. The firm will announce 1986 results in July. + Reuter + + + +17-MAR-1987 11:49:09.95 +earn +canada + + + + + +E F +f5506reute +d f BC-cabre-exploration-ltd 03-17 0026 + +<CABRE EXPLORATION LTD> SIX MTHS JAN 31 NET + CALGARY, Alberta, March 17 - + Shr 13 cts vs 13 cts + Net 617,000 vs 604,000 + Revs 1,889,000 vs 1,920,000 + Reuter + + + +17-MAR-1987 11:50:08.20 +acq +usa + + + + + +F +f5508reute +b f BC-DUDLEY-TAFT-RAISES-BI 03-17 0108 + +DUDLEY TAFT RAISES BID FOR TAFT BROADCASTING<TFB> + CINCINNATI, Ohio, March 17 - Dudley Taft and Narragansett +Capital Inc said it was prepared to raise its bid to acquire +Taft Broadcasting Co to more than 150 dlrs per share. + Taft, through Theta Co, sent and letter to Taft's board of +directors stating he was committed to purchasing the +broadcasting company and was ready to discuss all aspects of +the purchase. + The company said items to be discussed included price, +structure and form of consideration. Taft said he was prepared +to negotiate a transaction in which Taft Broadcast shareholders +would receive in excess of 150 dlrs per share. + Reuter + + + +17-MAR-1987 11:50:48.87 + +japan +james-baker + + + + +V RM +f5510reute +f f BC-******TREASURY'S-BAKE 03-17 0014 + +******TREASURY'S BAKER SAYS HE IS "QUITE CONFIDENT" JAPAN WILL STIMULATE ITS ECONOMY +Blah blah blah. + + + + + +17-MAR-1987 11:52:58.57 +veg-oil +west-germany + +ec + + + +C G +f5519reute +u f BC-EC-OILS-TAX-NO-LONGER 03-17 0107 + +EC OILS TAX NO LONGER MAJOR ISSUE - ASSOCIATION + BONN, March 17 - The proposed European Community (EC) tax +on vegetable oils and fats is no longer a major issue on the +agenda and the EC Commission merely used it as a threat, the +West German Feed Stuffs Industry Association (MFI) said. + Association chairman Ulrich Wagner told a news conference +the West German feed industry believes the EC does not +seriously contemplate the introduction of such a tax because it +would end in another transatlantic trade war. + "We have just avoided a trade conflict with the U.S. And the +Commission used the tax threat to calm national farm lobbies." + American Soybean Association (ASA) president-elect Wayne +Bennett said yesterday in The Hague that U.S. Soybean producers +were confident the tax would be rejected. + Bennett, who is leading one of three soybean delegations on +a lobbying tour of EC capitals, will also visit Bonn on +Thursday and Friday. + There are indications the Bonn government will also reject +the proposed tax, Wagner said. + Reuter + + + +17-MAR-1987 11:54:05.69 +acq +usa + + + + + +F +f5525reute +d f BC-ALLWASTE-<ALWS>-TO-BU 03-17 0083 + +ALLWASTE <ALWS> TO BUY RELATED COMPANY + HOUSTON, March 17 - Allwaste Inc said it entered into an +agreement in principle to acquire all the outstanding common of +a related air-moving and industrial services company. It did +not disclose the name of the company. + Allwaste, which preforms air-moving and related services, +said it will swap shares of its common, valued at 2.6 mln dlrs, +with the company it is acquiring. + It said the acquisition is subject to negotiation of a +final agreement. + Reuter + + + +17-MAR-1987 11:57:19.33 +crude +usafrance + + + + + +F Y +f5543reute +u f BC-EXXON-<XON>-MAY-CLOSE 03-17 0104 + +EXXON <XON> MAY CLOSE ONE FRENCH REFINERY + NEW YORK, MARCH 17 - Exxon Corp, the world's largest oil +company, said in a published interview today that it was +reviewing its worldwide refinery operations and might decide to +close on of its french refineries. + Lee R. Raymond, Exxon's new president, singled out the +possibility of a closure of one of Exxon's refineries in France +during the interview. + An Exxon spokeswoman confirmed that Raymond had +specifically mentioned refineries in France but said that no +specific refinery had been named. She also said that all of +Exxon's opertations were under constant review. + Exxon currently has two refineries in France, FOS in the +mediterranean with a capcity of 175,000 barrels per day and +Port Jerome west of paris with a similar capacity. + Petroleum Intelligence Weekly, an influential trade +journal, said, in its current issue, that they understood that +Exxon was looking at the possibility of refinery closures in +Antwerp, Southern France or possibly Italy. + Paul Mlotok, oil analyst with Salomon Brothers inc said +that with the closures Exxon made in 1986 in Europe and the +improvement in the European refining situation, its future +profits there should be good. + "Exxon and other major oil companies have closed a bunch of +refineries in Europe, upgraded the rest and shaken many of the +indepedents out of the market. Now with demand for products +rising and efficient operations, Exxon should show superior +earnings," Mlotok said. + "Just after Royal Dutch <RD>, they are seen as one of the +highest grade refiners in Europe," he added. + Industry sources said that the oil companies were likely to +feel greater pressure on their operations in Southern Europe +where competition from the OPEC countries is increasing as +these producers move further into downstream operations. + PIW said that refiners in the Mediterranean can expect +increased shipments from Saudi Arabia and other OPEC export +refineries. + PIW said "sales from Libya, Algeria and elsewhere are +expected to reclaim markets lost to Italian and other European +refiners as a result of the abundance of cheap netback oil last +year." + Reuter + + + +17-MAR-1987 11:58:19.93 + +ussrusa +james-baker +worldbankimf + + + +C +f5551reute +r f BC-BAKER-SAYS-U.S.-OPPOS 03-17 0105 + +BAKER SAYS U.S. OPPOSES SOVIET BANK MEMBERSHIP + WASHINGTON, March 17 - U.S. Treasury Secretary James Baker +said the U.S. opposes Soviet membership of the World Bank or +the International Monetary Fund. + Baker told a House foreign affairs subcommittee, "I think +our position is absolutely clear on that ... We do not support +and will not support Soviet membership in the World Bank or the +IMF." + Baker said the U.S. position was "unqualified and +unconditional." + Baker was responding to a questioner who noted that World +Bank President Barber Conable has in the past suggested future +Soviet membership could take place. + Reuter + + + +17-MAR-1987 11:58:36.43 +veg-oilsoybean +italyusa + +ec + + + +C G +f5552reute +u f BC-ITALY-STANCE-ON-EC-OI 03-17 0100 + +ITALY STANCE ON EC OILS TAX NOT ENCOURAGING-ASA + ROME, March 17 - Italy's response to protests by U.S. +Soybean producers about the proposed European Community (EC) +tax on vegetable oils and fats had not been encouraging, +American Soybean Association (ASA) board chairman George +Fluegel said. + Fluegel, heading one of three U.S. Soybean producer +delegations currently on a lobbying tour of EC countries, told +Reuters in an interview meetings with officials from the +Italian Foreign and Agricultural ministries had not yielded +much to encourage hopes that Italy would vote against the +proposed tax. + Fluegel said his delegation had received a negative +response from the Italian Agriculture Ministry, but that the +attitude of the Foreign Ministry appeared "more realistic." + He said the proposed tax was discriminatory against U.S. +Farmers since it was basically asking them to help finance the +EC's Common Agricultural Policy (CAP) on oilseeds. + Asked which EC countries might be expected to vote against +the proposed tax, he said, "Realistically, from the information +we're getting, it looks like the English, the Germans, +hopefully the Netherlands and Denmark." His delegation also +hoped to convince Belgium to vote against the issue, he added. + Asked what form he thought U.S. Retaliatory action might +take in the event of the EC tax proposal being approved, +Fluegel said industrial as well as agricultural products could +be involved. + U.S. Agriculture Secretary Richard Lyng warned the EC +yesterday it would face serious retaliation if it enacted the +tax. + ASA president-elect Wayne Bennett said yesterday in The +Hague American soybean producers were confident the proposed +tax would be rejected. + Reuter + + + +17-MAR-1987 11:59:00.09 +cotton +israel + + + + + +G +f5556reute +d f BC-ISRAEL'S-FIVE-YEAR-PL 03-17 0142 + +ISRAEL'S FIVE-YEAR PLAN TO BOOST AGRICULTURE + TEL AVIV, March 17 - Israel has drawn up a five-year plan +for 1987-1991 to raise agricultural production by 500 mln dlrs +to 2.7 billion dlrs, an annual rise of 3.4 pct, the Israeli +Ministry of Agriculture said. Agricultural exports are to be +increased by 180 mln dlrs, or 4.8 pct per year on average. + The area planted to cotton is to remain at the 1986 level +of 100,000 to 112,500 acres with exports expected to bring in +80 to 90 mln dlrs per year. The 34 pct decline from the 1985 +level reflects continued water rationing which will remain in +force, the ministry said. + Groundnut production is planned to increase by 13,000 +tonnes, or 57 pct, by 1991 and exports by 9,000 tonnes, or 82 +pct. Maize production is targetted to rise by 48,000 tonnes, or +48 pct, and exports by 34,000 tonnes, or 45 pct. + Reuter + + + +17-MAR-1987 12:02:53.79 + +usa + + + + + +RM A +f5571reute +r f BC-BRUNSWICK-<BC>-FILES 03-17 0078 + +BRUNSWICK <BC> FILES FOR 300 MLN DLR SHELF + SKOKIE, ILL., March 17 - Brunswick Corp said it filed a +registration statement with the Securities and Exchange +Commission on a shelf offering of 300 mln dlr in senior debt +securities. + It said proceeds from the sale will be used mainly for to +replace variable rate indebtedness, primarily privately placed +commercial paper, incurred in connection with the acquisitions +of Bayliner marine Corp and Ray Industries Inc. + Reuter + + + +17-MAR-1987 12:03:31.99 +acq +usa + + + + + +F +f5575reute +u f BC-SOROS-GROUP-HAS-B.F. 03-17 0100 + +SOROS GROUP HAS B.F. GOODRICH <GR> STAKE + WASHINGTON, March 17 - An investor group led by New York +investor George Soros said it acquired a 6.1 pct stake in B.F. +Goodrich Co common stock as an investment. + The group said it paid about 69 mln dlrs for the 1,389,600 +Goodrich shares, which are being held by Quantum Fund N.V., a +Netherlands Antilles investment firm advised by Soros. + It said all the shares were bought between Dec. 29 and +March 9. + The group said it reserved the future right to buy +additional shares and to formulate other purposes or plans +regarding its Goodrich investment. + Reuter + + + +17-MAR-1987 12:04:26.00 + +usa +james-baker + + + + +C +f5584reute +r f BC-BAKER-SAYS-U.S.-NOT-S 03-17 0095 + +BAKER SAYS U.S. NOT SEEKING IADB VETO + WASHINGTON, March 17 - Treasury Secretary James Baker said +the United States was not seeking loan veto in its negotiation +for voting power at the Inter-American Development Bank. + Discussing the ongoing negotiation, Baker said the U.S. +position is that the countries that pay in the most should have +the greatest say over the loan decisions. + The U.S. is seeking the power to block loan votes with one +other country, and the issue will be discussed in Miami later +this month at the annual meeting of the Latin development bank. + Reuter + + + +17-MAR-1987 12:04:41.09 +housing +usa + + + + + +C M +f5585reute +d f BC-BALDRIGE-PREDICTS-SOL 03-17 0111 + +BALDRIGE PREDICTS SOLID U.S. HOUSING GROWTH + WASHINGTON, March 17 - Commerce Secretary Malcolm Baldrige +predicted 1987 will be the fifth successive year for growth in +housing starts after a 2.6 pct rise overall in February starts +to a seasonally adjusted annual rate of 1.851 mln units. + "This year should be the fifth solid year in a row for +homebuilding activity -- with single-family units stronger than +multi-family units," he said in a statement. + Single-family starts rose last month from January levels by +5.6 pct to 1.317 mln units on a seasonally adjusted basis while +multi-family unit starts fell 4.1 pct to 534,000 units, the +department reported. + Reuter + + + +17-MAR-1987 12:05:06.31 +acq + + + + + + +F +f5587reute +f f BC-******TAFT-BROADCASTI 03-17 0014 + +******TAFT BROADCASTING SAYS IT WILL CONTINUE TO REVIEW OPTIONS IN RESPONSE TO LATEST BID +Blah blah blah. + + + + + +17-MAR-1987 12:05:12.02 +acq + + + + + + +F +f5588reute +b f BC-******COURT-ENJOINS-Z 03-17 0012 + +******COURT ENJOINS ZICO INVESTMENT'S TENDER FOR BANCROFT CONVERTIBLE FUND +Blah blah blah. + + + + + +17-MAR-1987 12:06:41.72 +acq +usa + + + + + +F +f5599reute +u f BC-STEINHARDT-GROUP-HAS 03-17 0106 + +STEINHARDT GROUP HAS 6.6 PCT OF HOLIDAY <HIA> + WASHINGTON, March 17 - A group led by New York investor +Michael Steinhardt told the Securities and Exchange Commission +it bought a 6.6 pct stake in Holiday Corp common stock as an +investment. + The group said it paid 114 mln dlrs for its 1.6 mln Holiday +shares, 530,000 of which were bought since Feb. 6. + At the same time, group members said they held short +positions in the stock totaling 830,000 shares. + In addition to Steinhardt himself, the group includes +Steinhardt Partners and Institutional Partners, two investment +firms of which Steinhardt is one of the general partners. + Reuter + + + +17-MAR-1987 12:08:46.37 + +usa + + + + + +V +f5612reute +u f AM-REAGAN-POINDEXTER 03-17 0093 + +POINDEXTER REFUSES TO TESTIFY BEFORE COMMITTEE + WASHINGTON, March 17 - Adm. John Poindexter, a former +National Security Adviser who resigned over the Iran arms +scandal, refused to testify before a House committee probing a +recent expansion of White House and military control over +unclassified information. + "On advice of counsel, I decline to answer that question +pursuant to my constitutional rights under the Fifth Amendment," +Poindexter said four times in response to questions from House +Government Operations Committee chairman Rep. Jack Brooks. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-007.sgm b/src/test/data/reuters-21578/reut2-007.sgm new file mode 100644 index 00000000000..292853fb8e3 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-007.sgm @@ -0,0 +1,2010 @@ + + +19-MAR-1987 06:17:22.36 +earn +australia + + + + + +F +f0363reute +u f BC-FAIRFAX-SAYS-HIGHER-T 03-19 0107 + +FAIRFAX SAYS HIGHER TAX HITS FIRST HALF EARNINGS + SYDNEY, March 19 - Media group John Fairfax Ltd <FFXA.S> +said that its flat first half net profit partly reflected the +impact of changes in the Australian tax system. + Fairfax earlier reported net earnings edged up 2.3 pct to +25.94 mln dlrs in the 26 weeks ended December 28 from 25.35 mln +a year earlier although pre-tax profit rose 9.1 pct to 48.30 +mln from 44.29 mln. + Net would have risen 10.1 pct but for the increase in +company tax to 49 pct from 46 and the imposition of the tax on +fringe benefits, paid by employers and not the recipients, the +company said in a statement. + Fairfax also pointed to the cyclical downturn in revenue +growth in the television industry as another reason for the +flat first half earnings. + It said it considered the result satisfactory in view of +these factors. + Fairfax said its flagship dailies, The Sydney Morning +Herald and the Melbourne Age, boosted advertising volume, as +did the Australian Financial Review, and posted extremely +satisfactory performances. Magazines also performed strongly. + But an 8.9 pct rise in television costs outweighed a 4.0 +pct rise in revenue, it said. + Fairfax said a fall in net interest also contributed to net +earnings because group borrowings were reduced following the +receipt of a 96.11 mln dlr capital dividend from <Australian +Associated Press Pty Ltd> (AAP) after the sale of AAP's "B" +shares in Reuters Holdings Plc <RTRS.L>. + This accounted for the 89.32 mln dlr extraordinary profit. + Fairfax said it is too early to predict results for the +full year. Increased borrowings after the recent 320 mln dlr +acquisition of the HSV-Seven television station in Melbourne +will hit earnings but networking with the Channel Sevens in +Sydney and Brisbane will produce some offsetting cost savings. + REUTER + + + +19-MAR-1987 06:20:33.63 + +france + + + + + +RM +f0367reute +b f BC-BANK-OF-FRANCE-SELLS 03-19 0095 + +BANK OF FRANCE SELLS 1.6 BILLION FRANCS CRH TAP + PARIS, March 19 - The Bank of France sold 1.6 billion +francs of 8.50 pct March 1987/99 Caisse de Refinancement +Hypothecaire (CRH) state-guaranteed tap stock at an auction, +the Bank said. + Demand totalled 6.82 billion francs and prices bid ranged +from 93.50 to 96.60 pct. The minimum accepted price was 95.50 +pct with a 9.13 pct yield, while the average price was 95.69. + At the last auction on February 19, two billion francs of +CRH tap stock was sold at a minimum price of 91.50 pct and +yield of 9.73 pct. + REUTER + + + +19-MAR-1987 06:21:45.34 +earn +uk + + + + + +F +f0370reute +b f BC-BRITOIL-PLC-<BTOL.L> 03-19 0045 + +BRITOIL PLC <BTOL.L> 1986 YR + LONDON, March 19 - + Shr 6.56p vs 50.31p + Final div 6p, making 8p vs 13p. + Pre-tax profit 134 mln stg vs 759 mln. + Net profit 33 mln vs 253 mln. + Turnover 978 mln stg vs 1.80 billion. + Extraordinary debit 50 mln vs nil. + Operating profit 149 mln stg vs 756 mln. + Exceptional debit on rationalisation programme 12 mln vs +nil + Petroleum Revenue Taxes 77 mln vs 319 mln, + U.K. Corporation tax and overseas tax 24 mln vs 187 mln, + Note - The net effect of accounting changes in 1986 was to +reduce after tax profits by 47 mln stg. Retained earnings for +prior years were increased by 209 mln. + Extraordinary debit of 50 mln stg related to the decision +to seek a buyer for the company's U.S. Assets. + REUTER + + + +19-MAR-1987 06:29:47.46 +jobs +uk + + + + + +RM +f0389reute +f f BC-(EMBARGOED-FOR-RELEAS 03-19 0023 + + (EMBARGOED FOR RELEASE AT 1130 GMT THURS MARCH 19) ******UK +FEB ADJUSTED UNEMPLOYMENT FELL 44,100 TOTAL 3.07 MLN OR 11.1 +PCT - OFFICIAL + + + + + +19-MAR-1987 06:31:34.81 +income +uk + + + + + +RM +f0391reute +f f BC-UK-UNIT-WAGE/LABOUR-C 03-19 0013 + +******UK UNIT WAGE/LABOUR COSTS ROSE 3.3 PCT IN THREE MONTHS ENDING JAN - OFFICIAL +Blah blah blah. + + + + + +19-MAR-1987 06:32:16.74 +income +uk + + + + + +RM +f0392reute +f f BC-UK-AVERAGE-EARNINGS-R 03-19 0014 + +******UK AVERAGE EARNINGS ROSE 7.6 PCT IN JANUARY, UNDERLYING RISE 7.5 PCT - OFFICIAL +Blah blah blah. + + + + + +19-MAR-1987 06:32:22.15 +money-supply +uk + + + + + +RM +f0393reute +f f BC-U.K.-FEBRUARY-ADJUSTE 03-19 0015 + +******U.K. FEBRUARY ADJUSTED STERLING M3 RISES 2-1/4 PCT, M0 DOWN 3/4 TO ONE PCT - OFFICIAL +Blah blah blah. + + + + + +19-MAR-1987 06:32:48.77 +earn +uk + + + + + +F +f0394reute +u f BC-LEGAL-AND-GENERAL-GRO 03-19 0037 + +LEGAL AND GENERAL GROUP PLC YEAR 1986 + LONDON, March 19 - + Shr 14.58p vs 7.86p + Div 6.5p making 9.75p, an increase of 19.4 pct + Pretax profit 83.2 mln stg vs 31.5 mln + Net after tax 68.6 mln stg vs 37.7 mln + Pretax profit 83.2 mln stg vs 31.5 +mln, consists of - + Long term business 45.9 mln stg vs 43.8 mln + U.S. Long term business 6.2 mln vs 8.9 mln + Fund management 4.7 mln vs 6.5 mln + Short term business 4.7 mln vs loss 29.0 mln + Associate companies 0.9 mln vs 0.8 mln + Shareholders other income and outgoings 0.4 mln debit vs +0.5 mln credit + Exceptional long-term business profit 21.4 mln vs nil + REUTER + + + +19-MAR-1987 06:33:49.51 +money-supply + + + + + + +RM +f0397reute +f f BC-FEB-STERLING-BANK-LEN 03-19 0014 + +******FEB STERLING BANK LENDING UP 2.9 BILLION STG AFTER 1.75 RISE IN JAN - OFFICIAL +Blah blah blah. + + + + + +19-MAR-1987 06:33:54.42 +jobs +uk + + + + + +RM +f0398reute +f f BC-UK-FEB-ADJUSTED-UNEMP 03-19 0014 + +******UK FEB ADJUSTED UNEMPLOYMENT FELL 44,100 TOTAL 3.07 MLN OR 11.1 PCT - OFFICIAL +Blah blah blah. + + + + + +19-MAR-1987 06:34:43.33 +trade +japanusa + + + + + +F +f0399reute +u f BC-JAPAN-TO-ASK-CHIP-MAK 03-19 0118 + +JAPAN TO ASK CHIP MAKERS TO SLASH OUTPUT FURTHER + TOKYO, March 19 - The Ministry of International Trade and +Industry will ask Japanese computer microchip makers to further +slash output in the second quarter in an effort to save its +semiconductor pact with the United States, MITI officials said. + The United States has accused Japan of reneging on the +semiconductor pact by failing to stop the flow of cut-price +Japanese chips to Asian markets. Washington has threatened to +take retaliatory action after April 1. + The pact, agreed last year, calls on Japan to stop selling +cut-price chips in world markets and to increase its imports of +American chips to reduce some of its huge trade surplus. + MITI, anxious to salvage the bilateral agreement, has been +pressing chip makers to limit production in the hope that will +boost domestic chip prices and reduce the incentive to export. + Last month, the ministry asked Japanese chip makers to +reduce first quarter output by 10 pct. To meet that request, +they had to slash production by 20 pct over the final six weeks +of the first quarter. + If that reduced production level were maintained through to +the end of June, second quarter output would come in 10 pct +below that of the first three months of the year. + MITI officials, who declined to be identified, said the +ministry has not yet decided on the extent of the second +quarter cutback. + One said that Japanese chip makers are losing ground in +Asia to South Korean and U.S. Competition just as markets there +are picking up. + MITI has been criticized privately by some Japanese +semiconductor makers for what they see as heavy-handed attempts +to ensure the success of the Japan/U.S. Chip pact. + REUTER + + + +19-MAR-1987 06:39:15.19 +money-supply +uk + + + + + +RM +f0402reute +b f BC-U.K.-CLEARING-BANK-LE 03-19 0067 + +U.K. CLEARING BANK LENDING RISES 1.6 BILLION STG + LONDON, March 19 - Clearing bank sterling lending to the +U.K. Private sector in February is estimated to have risen by +an underlying, seasonally-adjusted 1.6 billion stg after a 1.2 +billion stg rise in January, the Banking Information Service +said. + The unadjusted rise was 1.31 billion stg, compared with an +813 mln stg increase in January. + The Banking Information Service said the adjusted rise of +1.6 billion stg was well above the recent monthly average of +about 1.0 billion stg. + Of the increase, 297 mln stg was accounted for by personal +lending, which the Banking Information Service said was taken +up entirely by lending for home purchases. + Lending for consumption fell around 17 mln stg while about +182 mln stg of credit card debt was repaid during the month. + Lending to the manufacturing industry was up 370 mln stg, +and to leasing companies by 308 mln stg. + The Banking Information Service said February fell within +the governmemnt tax season, so much of the lending was probably +the result of industry's need to pay its tax bills. + Deposits by the private sector rose an unadjusted 1.1 +billion stg in February and by a seasonally-adjusted 1.75 +billion stg. + Deposits from the public sector rose 185 mln stg in +February while deposits from overseas residents rose by 43 mln. + REUTER + + + +19-MAR-1987 06:43:04.94 +jobs +uk + + + + + +RM +f0410reute +b f BC-U.K.-UNEMPLOYMENT-FAL 03-19 0084 + +U.K. UNEMPLOYMENT FALLS IN FEBRUARY + LONDON, March 19 - Unemployment in the U.K. Fell a +provisional seasonally-adjusted 44,100 in February, to total +3.07 mln or 11.1 pct of the workforce, the Employment +Department said. + In January, seasonally adjusted unemployment fell by a +revised 1,100 to 11.3 pct, it said. Initially the January +position was reported as flat. + The unadjusted jobless total, including school leavers, +fell to 3.23 mln, or 11.7 pct, from 3.30 mln, 11.9 pct, in +January. + February was the seventh successive month that seasonally +adjusted unemployment registered a fall. + It was at a peak of 11.7 pct last summer. + Lord Young, the Employment Minister, said there appeared +little doubt the monthly fall, which has been running at about +20,000, will continue. + A Department spokesman said the sharp fall in February +reflected some compensation for the flat figure in January and +continued the downward trend seen in the past six months. + He said the February fall was spread throughout the country +and among men and women. + REUTER + + + +19-MAR-1987 06:47:26.22 +money-supply +uk + + + + + +RM +f0415reute +b f BC-STERLING-M3-UP-2-1/4 03-19 0110 + +STERLING M3 UP 2-1/4 PCT IN FEBRUARY, M0 DOWN + LONDON, March 19 - The main measure of U.K. Broad money, +sterling M3, grew a provisional, seasonally adjusted 2-1/4 pct +in February after a rise of 1.1 pct in January, the Bank of +England said. + The narrow measure, M0, fell a provisional adjusted 3/4 to +one pct after a 0.6 pct drop in January, the Bank said. + Unadjusted annual growth in sterling M3 was 18-3/4 to 19 +pct in the 12 months to February against 17.6 pct in January +while M0 rose four to 4-1/4 pct after a 5.2 pct rise in +January. + Seasonally adjusted, sterling bank lending grew 2.9 billion +stg after a January rise of 1.75 billion. + Of the unadjusted counterparts to sterling M3, bank lending +to the private sector expanded 2.6 billion stg after a 1.4 +billion rise in January, the Bank said. + The public sector borrowing requirement (PSBR) contracted +by 300 mln stg after a contraction of 3.7 billion stg in +January. + Funding - debt sales to the non-bank private sector and +external flows to the public sector - rose by 300 mln stg after +a 1.5 billion stg rise in January. Of this, central government +debt sales to the public sector were expansionary by 400 mln +stg after a 1.3 billion expansion in January, the Bank said. + Other unadjusted counterparts to sterling M3 expanded by +300 mln stg in February after an expansion of 1.3 billion stg +in January, the Bank said. + Unadjusted figures showed a rise in sterling M3 by 1-3/4 to +two pct in February after a drop of 0.8 pct in January. + On the same basis, the figures showed a drop of about 1-1/2 +pct in MO in February after a sharp 6-1/2 pct fall in January. + The Bank said it would publish full, final figures on March +30. + The Bank said non-bank private sector holdings of public +sector debt fell by about 400 mln stg in February while +external flows to the public sector were about 100 mln stg. + Combined with a net PSBR repayment of about 300 mln stg, +the public sector contribution to the growth in sterling M3 was +therefore about flat, the Bank said. + It said seasonally adjusted bank lending, at about 2.9 +billion stg in February, compared with an average of about 2.6 +billion stg a month over the preceding six months. + REUTER + + + +19-MAR-1987 06:53:56.15 +income +uk + + + + + +RM +f0418reute +b f BC-U.K.-EARNINGS-RISE-7. 03-19 0094 + +U.K. EARNINGS RISE 7.6 PCT IN YEAR TO JANUARY + LONDON, March 19 - U.K. Average earnings rose a seasonally +adjusted 7.6 pct in the year to end-January after a 7.4 pct +rise in the year to December, the Department of Employment +said. + The underlying rise was 7.5 pct after 7.75 pct in December. + The January index, base 1980, was set at a provisional +seasonally adjusted 190.4, down from 193.4 in December. + The underlying rise, adjusted for factors such as back-pay +and timing variations, had been steady at 7.5 pct from October +1985 to October 1986. + Unit wage costs in U.K. Manufacturing industry rose 3.3 pct +in the three months to end January, on a year-on-year basis, +after a 3.1 pct rise in the three months to end December, the +Department of Employment said. + In January, the unit wage rise in manufacturing industries +was 3.6 pct, unchanged from the December rise. + The Department said the decline in the underlying rate of +rise in earnings reflected the reduced significance of bonus +payments in January compared with December. + The actual increase reflected teacher pay settlements and +industrial action in the transport and communications sectors +in January 1987. + REUTER + + + +19-MAR-1987 06:55:01.57 + +uk + + + + + +RM +f0419reute +b f BC-MEPC-ISSUES-PARTLY-PA 03-19 0088 + +MEPC ISSUES PARTLY PAID EUROSTERLING BOND + LONDON, March 19 - U.K. Property company MEPC Plc is +issuing a 75 mln stg eurobond due April 15, 2004 paying 9-7/8 +pct and priced at 99-5/8 pct, lead manager County Natwest +Capital Markets said. + The bond is in partly paid form with 25 pct due on April 15 +and the remainder on July 15. It will be available in +denominations of 1,000 and 10,000 stg and will be listed in +London. + Fees comprise 1-1/2 pct selling concession and 1/2 pct each +for management and underwriting. + REUTER + + + +19-MAR-1987 07:01:20.97 + +uk + + + + + +RM +f0426reute +b f BC-NOMURA-INTERNATIONAL 03-19 0108 + +NOMURA INTERNATIONAL FINANCE ISSUES EUROBOND + LONDON, March 19 - Nomura International Finance Plc is +issuing a 150 mln dlr eurobond due April 28, 1992 with a 7-1/4 +pct coupon and priced at 101-1/8 pct, Nomura International Ltd +said as lead manager. + The transaction carries the guarantee of Nomura Securities. +Bonds will be issued in denominations of 5,000 dlrs and will be +listed in London. Payment date is April 27. + Fees comprise 5/8 pct for management and underwriting, +including a 1/8 pct praecipuum, and 1-1/4 pct for selling. + Co-lead is Pru-Bache Securities. The issue is targeted at +Europe, with no Japanese co-managers. + REUTER + + + +19-MAR-1987 07:09:17.93 + +uk + + + + + +A +f0442reute +r f BC-VOLVO-ISSUES-70-BILLI 03-19 0078 + +VOLVO ISSUES 70 BILLION EUROLIRE BOND + LONDON, March 19 - AB Volvo is issuing a 70 billion +eurolire bond due May 31, 1990 paying 10-1/8 pct and priced at +100-1/2 pct, lead manager Banca Commerciale Italiana said. + The bond is available in denominations of two mln lire and +will be listed in London. + Fees comprise 7/8 pct selling concession with 1/2 pct for +management and underwriting combined. + Payment date is April 24 and there will be a long first +coupon. + REUTER + + + +19-MAR-1987 07:13:37.68 + +west-germany +stoltenberg + + + + +RM +f0450reute +u f BC-STOLTENBERG-CONSIDERS 03-19 0101 + +STOLTENBERG CONSIDERS RAISING SOME INDIRECT TAXES + BONN, March 19 - Finance Minister Gerhard Stoltenberg said +he was looking for ways to help finance a planned tax reform +without increasing value-added tax but could not rule out +raising some indirect taxes, for example, on tobacco. + Stoltenberg also told parliament that closing tax loopholes +would contribute towards the 19 billion marks the government is +seeking to finance part of its 44 billion mark tax reform +package for the 1990s. + He confirmed that a temporary and limited increase in the +borrowing requirement was also being considered. + Chancellor Helmut Kohl yesterday said a temporary rise in +borrowing was acceptable but stressed his government would +exercise strict discipline in spending. + New net borrowing was 23.0 billion marks in 1986 compared +with 37.2 billion in 1982. + REUTER + + + +19-MAR-1987 07:16:04.87 +money-fx +uk + + + + + +RM +f0456reute +b f BC-U.K.-MONEY-MARKET-SHO 03-19 0032 + +U.K. MONEY MARKET SHORTAGE FORECAST REVISED DOWN + LONDON, March 19 - The Bank of England said it revised down +its estimate of the deficit in the system today to 400 mln stg +from 450 mln. + REUTER + + + +19-MAR-1987 07:17:51.88 + +west-germany + + + + + +RM +f0457reute +u f BC-WESTLB-ISSUES-50-MLN 03-19 0115 + +WESTLB ISSUES 50 MLN AUSTRALIAN DLR EUROBOND + FRANKFURT, March 19 - A Westdeutsche Landesbank +Girozentrale (WestLB) unit is raising 50 mln Australian dlrs +through a five-year bullet eurobond with a 14-3/8 pct coupon +and priced at 101-1/2, co-lead manager WestLB said. + The bond, for WestLB Finance N.V., Is guaranteed by the +parent. Investors will pay for the bond on April 15, and the +bond pays annual interest on the same day. It matures on that +day in 1992. Fees total two pct, with 1-3/8 points for selling, +and 5/8 for management and underwriting combined. There is a +1/8 pct praecipuum. Listing is in Luxembourg. + Co-lead is Hambros Bank Ltd. Denomination is 1,000 dlrs. + REUTER + + + +19-MAR-1987 07:21:25.03 + +ecuador + + + + + +A +f0462reute +r f BC-DEBT-ECUADOR 03-19 0085 + +ECUADOR SEEKS 450 MLN DLRS IN EMERGENCY CREDIT + By Jorge Aguirre, Reuters + QUITO, March 18 - Ecuador is seeking between 437 and 450 +mln dlrs in loans this year from multilateral organisations and +foreign governments to grapple with economic losses from a +devastating earthquake 13 days ago, a presidential economic +adviser said. + Foreign governments and multilateral organisations hold +one-third of Ecuador's 8.16 billion dlrs total foreign debt, he +said in a news conference at the presidential palace. + But he added that the suspension of payments to private +foreign banks, who hold the rest of the foreign debt, would be +prolonged though the government hoped to negotiate an agreement +with these creditors. + President Leon Febres Cordero says the earthquake cost the +country one billion dlrs in losses and left 1,000 people dead +or missing. + Swett, who was Finance Minister of Ecuador between August +1984 to June 1986, added: "With the private foreign banks there +has been a ceasing of payments by Ecuador. + "We are bringing forward the respective negotiations whose +conclusion we hope finalises in the next few weeks." + Finance Minister Domingo Cordovez said last week that +quake-hit Ecuador sought through negotiations to postpone all +payments due to the private foreign banks in 1987 until next +year. + Although Swett gave no gave details on the latest plan for +negotiations with private foreign banks, he calculated the +suspension of payment to these creditors would save the +government 54.45 billion sucres. + This amount is equal to 363 mln dlrs at the free rate of +150 sucres to the dollar -- the rate Swett said reporters +should use in calculating the dollar equivalent. + The Ecuadorean central bank, which is the institution +remitting debt payments abroad, uses the official rate of 95 +sucres to the dollar for its accounting purposes. At the +official rate, the 54.45 billion sucres' sum equals 573 mln +dlrs. + Ecuador, squeezed by a slide last year in prices for crude, +its main export, suspended payments to private foreign banks in +January. + Swett said the government would also seek to refinance the +1.429 billion dlr section of the debt owed to the Paris Club +group of foreign governments, though it would continue to +service the debt with them. He gave no more details. + The government adopted a tough austerity program last +Friday intended to grapple with the tremor's economic costs. +But the country's labour unions have called a general strike +for Wednesday to press for a suspension of the program. + The 500,000-strong Unitary Workers' Front (FUT) and the +100,000-member General Union of Workers (UGT) called the strike +to cancel the measures, which include a rise in petrol prices +of up to 80 per cent and budget cuts of as much as 10 per cent. + The leftist-led FUT said it was also backing a call by the +Maoist Popular Movement for Democracy (MPD) party, to have +Congress impeach and oust Febres Cordero, a conservative, for +having adopted the austerity measures. + Reuter + + + +19-MAR-1987 07:23:33.05 +gold +south-africa + + + + + +A +f0474reute +r f BC-SOME-7,000-SOUTH-AFRI 03-19 0104 + +SOME 7,000 SOUTH AFRICAN MINERS RETURN TO WORK + JOHANNESBURG, March 19 - Some 7,000 black workers returned +to work after staging one-day strikes at two mines on Monday, +the National Union of Mineworkers and the companies that own +the mines said. + About 6,000 miners resumed work at the Grootvlei gold mine +east of Johannesburg after protesting the transfer of +colleagues to other jobs at the same mine, owners General +Mining Union Corp Ltd <GENM.J> said. + The union said about 1,000 mineworkers at a new coal +facility owned by Anglo American Corp of South Africa Ltd +<ANGL.J> also returned to their jobs on Tuesday. + The workers at Anglo's Vaal Colliery south of Johannesburg +had struck to protest the alleged refusal of officials of the +South African homeland of Transkei to allow miners to attend a +funeral in the homeland, a union spokesman said. + REUTER + + + +19-MAR-1987 07:27:17.84 +acq +japanusa + + + + + +F +f0490reute +r f BC-NIPPON-LIFE-SEEKING-T 03-19 0102 + +NIPPON LIFE SEEKING TIE WITH U.S. SECURITIES HOUSE + TOKYO, March 19 - <Nippon Life Insurance Co> is pursing a +possible link with an American securities house to expand its +overseas investment portfolio, a company spokesman said. + But he declined to comment on rumours the company would +take a 10 pct stake in <Shearson Lehman Brothers>, an +investment banking unit of American Express Co <AXP>. + He said the firm started to sound out several U.S. +Investment banks on capital participation about 18 months ago +and was narrowing the number of prospects, but he did not say +if it had set its sights on one firm. + Nippon Life, Japan's largest life insurer, also plans to +set up a wholly owned investment unit, <Nissei International +America>, in New York next month and subsidiaries in Canada, +Singapore, the Cayman Islands and Jersey this year, he said. + These moves are in line with its long-term strategy to put +more emphasis on overseas investment management as +opportunities at home are declining while the company's assets +are growing. + The company is especially attracted by the scale and depth +of U.S. Money and credit markets and wants to establish a firm +foothold there, the spokesman added. + REUTER + + + +19-MAR-1987 07:28:32.29 + + + + + + + +RM +f0495reute +f f BC-****** 03-19 0009 + +****** Bundesbank says it leaves credit policies unchanged +Blah blah blah. + + + + + +19-MAR-1987 07:28:41.74 + +west-germany + + + + + +F +f0496reute +u f BC-WEST-GERMAN-CAR-OUTPU 03-19 0107 + +WEST GERMAN CAR OUTPUT RISES IN FEBRUARY + FRANKFURT, March 19 - West German car and van production +rose to 389,900 in February from 380,900 in February 1986, the +German Automobile Industry Association VDA said in a statement. + Production of trucks of up to six tonnes fell sharply to +11,500 from 14,600, owing to a cut in production of small +delivery vans of up to two tonnes. Total vehicle output rose to +410,000 from 404,600. + Car and van exports eased to 222,000 in February from +225,000 one year earlier, and exports of trucks of up to six +tonnes dropped to 6,200 from 9.900. Total vehicle exports fell +to 233,200 from 240,300. + Car and van output in January and February eased to 758,700 +from 766,500 in the first two months of 1986. Production of +trucks up to six tonnes fell to 26,300 from 30,700, and total +vehicle production fell to 802,300 from 814,900. + Car and van exports in January and February fell to 424,700 +from 443,300 a year earlier and exports of trucks up to six +tonnes fell to 15,400 from 20,200. Total vehicle exports fell +to 449,200 from 473,500. + REUTER + + + +19-MAR-1987 07:28:55.45 +money-fx + + + + + + +RM +f0498reute +b f BC-U.K.-MONEY-MARKET-GIV 03-19 0083 + +U.K. MONEY MARKET GIVEN 181 MLN STG ASSISTANCE + LONDON, March 19 - The Bank of England said it provided the +money market with 181 mln stg in assistance this morning. + This compares with the Bank's revised shortage forecast of +around 400 mln stg. + The central bank purchased bank bills outright at the new +dealing rates established yesterday. + These comprised 65 mln stg in band one at 9-7/8 pct, 114 +mln stg in band two at 9-13/16 pct and two mln stg in band +three at 9-3/4 pct. + REUTER + + + +19-MAR-1987 07:29:03.46 + +japan + + + + + +F +f0499reute +d f BC-FUJI-BANK-ACCUSED-OF 03-19 0074 + +FUJI BANK ACCUSED OF MISUSE OF TAX FREE RESERVES + TOKYO, March 19 - The Tokyo Regional Taxation Bureau has +imposed a penalty tax on <Fuji Bank Ltd> for alleged improper +use of tax-free reserves, a bank spokeswoman told Reuters. + She declined to reveal the bank's planned response but +another bank official said it has not paid the penalty. + The bank said in a brief statement it believes that its use +of the tax-free reserves is legal. + Financial institutions can set aside 0.003 pct of their +risky loans as tax-free reserves. Fuji said a difference of +understanding exists between the bank and the tax bureau +regarding the use of tax-free reserves. It did not elaborate. + Fuji Bank reported a 72.1 billion yen net profit in the +1985/86 year. Lending totaled 16,120 billion yen. + REUTER + + + +19-MAR-1987 07:29:42.07 +money-supply +philippines + + + + + +A +f0505reute +h f BC-PHILIPPINES'-LIQUIDIT 03-19 0104 + +PHILIPPINES' LIQUIDITY RISES, LOAN DEMAND FALLS + MANILA, March 19 - Liquidity in the Philippines rose in +December while loan demand and short-term lending rates fell, +the Central Bank said. + A bank official said M-3 rose 9.72 pct to a provisional +149.80 billion pesos at the end of December from a month +earlier for a year-on-year gain of 12.72 pct. + She said short-term bank lending rates fell to an +annualised 13.88 pct at the end of December, from 14.58 pct a +month earlier and 19.82 pct at the end of December 1985. + Poor loan demand was illustrated by a rise in commercial +bank reserves, the official said. + The bank official said commercial bank reserves were 22.19 +billion pesos at the end of December, when reserves required +were 21.59 billion. + She said the surplus of 597 mln pesos, compared with a +deficit of 390 mln pesos a month earlier and a deficit of 1.64 +billion at the end of 1985, reflected political uncertainty in +the last quarter of 1986. + Reserve money, the total available to monetary authorities, +was a provisional 52.58 billion pesos at the end of 1986. This +was 5.19 pct up from 49.98 billion at the end of November and +41.85 pct up from 37.09 billion in December 1985. + The bank official noted M-3, which includes M-1 money +supply, plus savings, time deposits and deposit substitutes. +Was 132.88 billion pesos at the end of December 1985. + M-1 money supply rose a provisional 17.3 pct to 42.86 +billion pesos at the end of December 1986 from 36.52 billion a +month earlier. The year-on-year rise was 19.64 pct, up from +35.83 billion at the end of December 1985. + Reuter + + + +19-MAR-1987 07:31:01.10 +acq +japanportugal + + + + + +F +f0511reute +r f BC-SANWA-BANK-ACQUIRES-S 03-19 0103 + +SANWA BANK ACQUIRES SMALL STAKE IN PORTUGUESE BANK + TOKYO, March 19 - Sanwa Bank Ltd <ANWA.T> has agreed to buy +a two pct stake in Oporto-based <Banco Portugues de Investmento +Sarl> (BPI), Portugal's largest merchant bank, a Sanwa official +said. + Sanwa will purchase the shares from International Finance +Corp, a BPI shareholder and sister organisation of the World +Bank, for 351 mln yen, he said. + The acquisition will be completed this month as both the +Japanese and Portuguse governments are expected to give +permission soon. This is the first time a Japanese bank has +bought a stake in a Portuguese bank. + Sanwa plans to increase its stake in BPI to four pct, the +ceiling for foreign shareholders, the official said. + The bank has also agreed with <Banco Portugues do +Atlantico>, a state-owned merchant bank in Oporto, to exchange +information on customers and help accelerate Japanese +investment and technological transfers to Portugal, he said. + REUTER + + + +19-MAR-1987 07:41:42.61 +interest +west-germany + + + + + +A +f0527reute +u f BC-BUNDESBANK-LEAVES-CRE 03-19 0051 + +BUNDESBANK LEAVES CREDIT POLICIES UNCHANGED + FRANKFURT, March 19 - The Bundesbank left credit policies +unchanged after today's regular meeting of its council, a +spokesman said in answer to enquiries. + The West German discount rate remains at 3.0 pct, and the +Lombard emergency financing rate at 5.0 pct. + REUTER + + + +19-MAR-1987 07:44:43.08 +gnp +france +balladur + + + + +RM +f0534reute +u f BC-NO-FRENCH-REFLATION, 03-19 0103 + +NO FRENCH REFLATION, SOURCES CLOSE TO BALLADUR SAY + PARIS, March 19 - There is no question of stimulating +consumption or relying on a systematic budget deficit or other +reflationary policies to boost the French economy, sources +close to finance minister Edouard Balladur said. + Their comments followed remarks by prime minister Jacques +Chirac's spokesman Denis Baudouin, who said on Monday ministers +were agreed on the desirability of "relaunching" the economy. + This sparked speculation the government was preparing for a +reflationary U-turn, but the finance ministry immediately ruled +out any such move. + The sources today said the government's policy remained one +of "recovery," or sound finances and greater efficiency. + They said that while 8.6 billion of the 30 billion franc +revenues expected for 1987 from a sweeping privatisation +program will go to providing public companies with fresh +capital, 21.4 billion francs, or two-thirds, will go toward +paying off national debt. + Any further privatisation revenue this year above the 30 +billion would be distributed between repayment of national +internal debt and public companies in similar proportions, they +added. + The sources said it was absurd to talk of reflation when +the country's internal debt, expected to grow by 10 pct this +year from 1,300 billion francs in 1986 was growing twice as +fast as gross domestic product. + Nominal GDP is expected to grow by roughly five pct this +year from 5,000 billion francs last year, broadly in line with +earlier forecasts. Real GDP will grow by up to 2.5 pct. + The sources said that with France's economic targets for +1987 roughly in line with its main trading partners, the +government had no intention of pushing the economy to grow at +an artificial pace out of step with neighbouring economies. + REUTER + + + +19-MAR-1987 07:55:53.04 + +hong-kong + + + + + +RM +f0557reute +u f BC-H.K.-REVIEWS-BANKING 03-19 0100 + +H.K. REVIEWS BANKING STRUCTURE, CAPITAL RATIO + HONG KONG, March 19 - The Banking Commission is reviewing +the present three-tier banking system and its newly established +capital adequacy ratio, banking commissioner Robert Fell said. + He told a news conference his office has had talks with the +Bank of England and the U.S. Federal Reserve Board on +risk-based capital ratios, following an agreement on such +standards between the two central banks early this year. + The Bank of England and the Fed are trying to persuade the +Bank of Japan and European central banks to accept their +standards. + "We welcome international standards," Fell said. "It means a +level playing field for all." + Under a new banking rule that came into effect last year, +banks in Hong Kong are given a two-year grace period to meet a +five pct capital adequacy requirement. + "The difference between us (Hong Kong and the U.K.) is +really not that great," he said. + Fell said the majority of banks are comfortable with the +required capital ratio, though some are under-capitalised. + Some banks, mostly Japanese, want a lower capital ratio +because of the special nature of their business, mainly +offshore banking operations. These institutions have proposed +the creation of a limited service bank category. + Financial institutions in Hong Kong are now classified into +three types -- banks, registered and licensed deposit-taking +companies. + Fell said the Commission is reviewing the three-tier +structure in light of the possible changes in capital ratio and +the growing trend towards securitisation of debt. + Fell said the Commission is also studying a set of +guidelines on loan loss provisions with the help of the Society +of Accountants. + Other planned guidelines relate to securitisation of debt +and business that banks and deposit taking companies can +conduct. + REUTER + + + +19-MAR-1987 08:01:10.70 + +ukaustria + + + + + +RM +f0571reute +u f BC-AUSTRIA-INCREASES-BON 03-19 0059 + +AUSTRIA INCREASES BOND TO 75 MLN AUSTRALIAN DLRS + LONDON, March 19 - The Australian dollar eurobond launched +yesterday for the Republic of Austria has been increased to 75 +mln dlrs from the original 50 mln, Credit Suisse First Boston +Ltd said as lead manager. + The five year transaction has a 14-1/4 pct coupon and was +priced at 101-3/4 pct. + REUTER + + + +19-MAR-1987 08:02:36.22 + +uk + + + + + +RM +f0577reute +u f BC-U.K.-BUILDING-SOCIETY 03-19 0078 + +U.K. BUILDING SOCIETY TAPS EUROSTERLING MARKET + LONDON, March 19 - Cheltenham and Gloucester Building +Society is issuing a 50 mln stg eurobond due April 22, 1992, +paying 9-1/4 pct and priced at 101-1/4 pct, lead manager Union +Bank of Switzerland (Securities) Ltd said. + The bond will be available in denominations of 1,000 stg +and will be listed in Luxembourg. + Fees comprise 1-1/4 pct selling concession and 5/8 pct +management and underwriting combined. + REUTER + + + +19-MAR-1987 08:04:29.56 +money-fxincomemoney-supply +usa + + + + + +A +f0587reute +u f BC--U.S.-CREDIT-MARKET-O 03-19 0111 + +U.S. CREDIT MARKET OUTLOOK - SPENDING, M-1 + NEW YORK, March 19 - Brisk increases in personal income and +consumption are to appear in February data released today, but +the bond market's recent sluggishness suggests there will be no +major price reaction unless the rises are much larger than +expected, economists said. + Personal income is forecast to rise by 0.6 to 0.8 pct, +compared with no change in January, while consumption +expenditures are projected to increase 1.4 to 1.6 pct, +reversing most of the two pct drop recorded in January. + M-1 money supply data for the March 9 week will also be +released. An increase of some 2.3 billion dlrs is expected. + Peter Greenbaum of Smith Barney, Harris Upham and Co Inc +expects a one pct rise in income, led by a strong gain in wage +and salary disbursements in February. + Nonfarm payrolls expanded by 337,000 jobs in February, the +average workweek lengthened by 0.6 pct and hourly wages rose by +four cts, he noted in a report. Vigorous spending on durable +goods last month, especially cars, foreshadow a rise of at +least 1.5 pct in consumption, he added. + The prospect of bearish data did not trouble the bond +market much yesterday, with the 30-year Treasury bond slipping +just 7/32 to 99-28/32 for a yield of 7.51 pct. + Analysts said the market is still trapped in a narrow +range, desperately seeking direction. + "Seasonally adjusted, it's already December in the bond +market," quipped Robert Brusca of Nikko Securities Co +International Inc. + Paul Boltz of T. Rowe Price Associates Inc said the +steadiness of long bond yields around 7.5 pct, despite some +signs of a stronger economy, probably reflects expectations +that inflation will remain subdued. + But he warned that this assumption might not be justified. + "It took the bond market a long while to see that inflation +was not returning to double digits, and now that it has learned +that lesson, it may be a little slow to see that a four to five +pct inflation is a real possibility ahead," Boltz said in a +report. + After trading late yesterday at 5-15/16 pct, Fed funds were +indicated by brokers to open comfortably at 5-15/16, six pct. + Reuter + + + +19-MAR-1987 08:07:29.71 +veg-oiloilseedsoybean +west-germanyusa + +ec + + + +C G +f0595reute +r f BC-U.S.-DELEGATION-HOPES 03-19 0115 + +U.S. DELEGATION HOPES FOR VEG OILS TAX DEFEAT + BONN, March 19 - American soybean producers and processors +are hoping the proposed EC tax on vegetable oils and fats will +not be imposed, but say the U.S. Is prepared to retaliate if it +is introduced. + Wayne Bennett, the American Soybean Association's first +vice president, told a news conference the U.S. Administration +would not hesitate to retaliate, but both producers and +processors were trying to solve the issue through negotiation. + U.S. Secretary of Agriculture Richard Lyng said in a letter +to EC officials that U.S. Retaliatory measures would cover more +than agricultural products if the tax was imposed, Bennett +said. + The ASA and National Soybean Processors Association (NSPA) +delegations will meet top West German government officials +today and tomorrow to lobby for support. + Bennett said West Germany, Britain, the Netherlands, +Denmark and Portugal oppose the tax, but Italy and Belgium seem +to have taken a hardline view on the issue. + "Europeans in favour of the tax say it would be to their +advantage economically, but that is not correct because we +would hit back," NSPA chairman Jack Reed said. + This step would be very expensive for all and no one would +emerge as a winner if the tax were introduced, he said. + Reed pointed out the U.S. Administration and the soybean +industry view the EC proposal as violating the General +Agreement on Tariffs and Trade. + The proposed tax also violates the zero duty bindings +agreed between the EC and U.S. In 1962, he said. + Under the zero duty bindings pact U.S. Soybeans and +products can be exported to the Community duty-free. + REUTER + + + +19-MAR-1987 08:08:32.15 + +hong-kong + + + + + +RM +f0600reute +u f BC-H.K.-BANKING-SECTOR-S 03-19 0100 + +H.K. BANKING SECTOR STABLE, OFFICIAL SAYS + HONG KONG, March 19 - The banking sector has regained its +stability after a protracted period of difficulty, banking +commissioner Robert Fell said. + "The banking climate has dramatically changed from a year +ago," he said at a news conference to present his annual report +on the banking sector for 1986. + "We've got confidence back. We've got profitability back." he +said. + A three-year shake out in the local banking sector forced +the government to take over three banks and arrange for the +acquisition of four others by the private sector. + Fell said that in many cases the bank problems stemmed from +management fraud which he linked partly to dramatic swings in +the stock and property markets in the early 1980s. + "We've got it out of the system now," he said. "Fraud is no +longer a systemic problem." + But he acknowledged there may still be problems. + "Deliberate fraud is difficult to detect especially where +collusion and senior management are involved," he said. +"Prudential supervision cannot give complete protection. The +(new banking) ordinance is designed to give a "measure" of +protection." + Fell said a number of banks want to set up operations in +Hong Kong, adding the government approved three banking +licences this week. He did not give details. + At the end of 1986, there were 151 licenced banks, 25 of +which were locally incorporated, compared with 143 a year ago. +Another 134 foreign banks had representative offices compared +with 131 a year ago. + There were 34 licensed deposit-taking companies (DTCs) and +254 registered DTCs at the end of 1986, compared with 35 and +278 respectively a year ago, he said. + Foreign banks seeking banking licences in Hong Kong must +have assets of 14 billion U.S. Dlrs. But Financial Secretary +Piers Jacobs said yesterday the asset criteria are flexible. + A high asset threshold has worked in the favour of banks +incorporated in countries with relatively large economies, he +noted. + "No licences in the last few years have been granted to +banks from any of the smaller countries in the Asia-Pacific +region," he said. + REUTER + + + +19-MAR-1987 08:13:16.72 +acq + + + + + + +F +f0621reute +f f BC-******AMERICAN-EXPRES 03-19 0014 + +******AMERICAN EXPRESS SAYS IT'S HOLDING TALKS ON SALE OF SHEARSON STAKE TO NIPPON LIFE +Blah blah blah. + + + + + +19-MAR-1987 08:13:36.39 + +usa + + + + + +F +f0623reute +r f AM-SAVINGS 03-19 0103 + +SAVINGS BANK CLOSED, 15TH TROUBLED U.S. S&L OF YEAR + WASHINGTON, March 18 - The Federal Home Loan Bank Board +(FHLBB) announced today the replacement of a closed Santa Ana, +Calif., savings bank in the 15th federal action assisting +troubled U.S. savings institutions this year. + The FHLBB said Perpetual Savings Bank in Santa Ana was put +into receivorship because it was insolvent and was replaced by +a new federally chartered Perpetual Savings Association. + It said the savings bank's insolvency "was a direct result +of losses on speculative investments in real estate which were +not supported by appraisals." + The FHLBB said it appointed Great American First Savings +Bank <GTA> of San Diego to manage Perpetual Savings. + It said as of January 31, Perpetual had assets of 61.9 mln +dlrs. + Reuter + + + +19-MAR-1987 08:15:06.00 +acq +usajapan + + + + + +F +f0627reute +u f BC-/AMERICAN-EXPRESS-<AX 03-19 0044 + +AMERICAN EXPRESS <AXP> MAY SELL SHEARSON STAKE + NEW YORK, March 19 - American Express Co said it and its +Shearson Lehman Brothers Inc subsidiary have been holding talks +on the possible equity investment in Shearson Lehman by <Nippon +Life Insurance Co> of Japan. + The company said, "The discussions have led to a general +understanding by which Nippon Life would purchase a 13 pct +equity investment in Shearson Lehman for approximately 530 mln +dlrs and American Express, Shearson Lehman and Nippon Life +would explore mutually advantageous, nonexclusive business and +investment opportunities." + The company said a definitive agreement on the matter is +subject to a number of conditions, including approval of the +American Express board and the Japanese Ministry of Finance. + The company said its board is scheduled to meet March 27 +for its regular monthly sessions. + American Express said it is continuing to evaluate various +courses of action of strategic importance to Shearson Lehman in +addition to the possible investment by Nippon Life. + It said the options range from expanding Shearson's +capacity to meet international competition, to broadening +further its access to capital. + The company also said, "All the courses of action under +study reflect the continuing integral role of Shearson Lehman +in American Express' worldwide financial services strategy." + Reuter + + + +19-MAR-1987 08:15:21.69 + +usa + + + + + +F +f0629reute +r f BC-XEROX-<XRX>-TO-STOP-S 03-19 0092 + +XEROX <XRX> TO STOP SELLING PC'S BY THEMSELVES + NEW YORK, March 19 - Xerox Corp has decided to stop selling +personal computers as standalone products, a company spokesman +said. + The spokesman said "As a first priority, we're selling PC's +as part of preconfigured systems, mostly desktop publishing +systems, and not by themselves anymore." + He said Xerox does not expect to take any material charge +from changing its marketing of personal computers. He said for +the past five years, Xerox has sold most of its PC's as +components of larger systems. + Another Xerox spokesman said the company actually stopped +selling personal computers alone on February 16 but never +announced the move. + Reuter + + + +19-MAR-1987 08:16:10.53 +money-fxrand +south-africa + + + + + +RM +f0630reute +r f BC-S.AFRICA'S-FINANCIAL 03-19 0093 + +S.AFRICA'S FINANCIAL RAND SEEN HEADED HIGHER + JOHANNESBURG, March 19 - The financial rand, widely viewed +as a direct reflection of foreign investor confidence in South +Africa, appears headed above 30 U.S. Cents, dealers and bank +economists said. + The currency has risen about 25 pct in the past three +months to its current rate of 29.50 cents, due partly to signs +of a possible power shift with the appearance of a number of +independent candidates in the whites-only election on May 6, +they added. + It has risen about two cents this week alone. + "Another factor is that banks in London, where the main +market is based, are going long in the currency because of a +general feeling that it will rise in the future," one economist +said. + Dealers described 30 cents as a psychological barrier that +was expected to be broken soon after a brief consolidation +phase from recent gains. + After reaching 30 cents, "There is a chance of appreciation +to 32 cents in the next several weeks," one dealer said. + There was a widespread feeling that both the commercial +rand, holding stable at 48 cents, and the financial rand were +staying firm, banking sources said. + A Barclays National Bank executive who asked not to be +identified said: "The rise of the independents appears to be +indicative of a potential shift of power in the National Party +and has created a favourable sentiment overseas." + One dealer said growing business and investor interest from +West Germany and Switzerland were behind the financial rand's +rise. + Economists said foreigners also were being attracted by +South Africa's long-term government bonds and "semi-gilts" or +securities in partly government-owned firms, many with yields +as high as 30 pct. They could be purchased with financial rands +with interest paid in commercial rands. + "This has had a definite influence on the financial form of +the rand," a dealer said, adding that at present demand is +slightly in excess of supply. + The financial rand was reintroduced in September 1985 to +help end capital flight from South Africa during a period of +severe political unrest in the country. + REUTER + + + +19-MAR-1987 08:22:06.66 + +usa + + + + + +A +f0648reute +r f BC-EX-REAGAN-AIDE-DEAVER 03-19 0113 + +EX-REAGAN AIDE DEAVER INDICTED ON PERJURY CHARGES + WASHINGTON, March 19 - Former White House aide Michael +Deaver, a long-time confidant of President Reagan, has been +indicted on charges of lying about his contacts as a Washington +lobbyist with top U.S. Government officials. + The five-count perjury indictment charged that Deaver lied +in sworn testimony to Congress and before the grand jury +investigating his business affairs. + Deaver, who resigned as deputy White House chief of staff +in 1985 to open a lobbying firm, faces a maximum penalty of 25 +years in prison if convicted. Immediately after the indictment +was announced Reagan issued a statement wishing Deaver well. + Reuter + + + +19-MAR-1987 08:22:21.02 +acq +usa + + + + + +F +f0649reute +d f BC-<FI-TEK-CORP>-TO-MAKE 03-19 0094 + +<FI-TEK CORP> TO MAKE ACQUISITION + DENVER, March 19 - Fi-Tek Corp said it has signed a letter +of intent to acquire <Voice Systems and Services Inc> for an +undisclosed amount of stock. + It said on completion of the acquisition it would change +its name to Voice Systems and Services Inc. It said VBoice +Systems has received a 3,600,000 dlr contract to provide FLP +Communications of Dallas with voicemail systems through service +bureaus located throughout the U.S. and has also contracted to +provide voicemail systems and administration to M and S +Communications. + Reuter + + + +19-MAR-1987 08:22:28.01 +acq +usa + + + + + +F +f0650reute +r f BC-FIRST-WISCONSIN-<FWB> 03-19 0062 + +FIRST WISCONSIN <FWB> TO MAKE ACQUISITION + MILWAUKEE, March 19 - First Wisconsin Corp said it has +agreed to acquire North Shore Bancorp Inc of Northbrook, Ill., +for 6,160,000 dlrs in cash, or slightly more than twice book +value, subject to approval by North Shore shareholders and +regulatory authorities. + The company said completion is expected in the third +quarter. + Reuter + + + +19-MAR-1987 08:26:32.47 +bop +italy + + + + + +RM +f0656reute +b f BC-ITALY'S-FEBRUARY-PAYM 03-19 0085 + +ITALY'S FEBRUARY PAYMENTS BALANCE IN SURPLUS + ROME, March 19 - Italy's overall balance of payments showed +a surplus of 1,461 billion lire in February 1987 compared with +a deficit of 1,145 billion in January, provisional Bank of +Italy figures show. + The February surplus compared with a deficit of 1,578 +billion lire in the same month for 1986. + For the first two months of 1987, the balance of payments +showed a surplus of 302 billion lire against a deficit of 4,622 +billion in the same 1986 period. + The Bank of Italy said the cumulative balance for the first +two months of 1987 does not match the total calculated on the +individual monthly figures because of the provisional nature of +certain data. + REUTER + + + +19-MAR-1987 08:26:43.13 +earn +usa + + + + + +F +f0658reute +d f BC-BELVEDERE-CORP-<BLV> 03-19 0073 + +BELVEDERE CORP <BLV> 4TH QTR LOSS + NEW YORK, March 19 - + Oper shr loss 21 cts vs loss 95 cts + Oper net loss 666,000 vs loss 2,184,000 + Avg shrs 3,181,805 vs 2,310,200 + Year + Oper shr loss 30 cts vs loss 23 cts + Oper net loss 823,000 vs loss 606,000 + Avg shrs 2,757,040 vs 2,614,225 + NOTE: Net excludes realized investment gains of 666,000 +dlrs vs 289,000 dlrs in quarter and 2,274,000 dlrs vs 1,468,000 +dlrs in year. + Reuter + + + +19-MAR-1987 08:27:00.64 +reserves +italy + + + + + +RM +f0659reute +b f BC-ITALIAN-NET-RESERVES 03-19 0081 + +ITALIAN NET RESERVES RISE IN FEBRUARY + ROME, March 19 - Italy's net official reserves rose to +66,172 billion lire in February 1987 from a previously reported +62,174 billion in January, the Bank of Italy said. + Gold holdings at end-February totalled 35,203 billion lire, +unchanged on January. + Convertible currencies totalled 18,467 billion lire, up +from 14,899 billion in January, while European Currency Unit +(ECU) holdings were 10,156 billion lire against 10,133 billion. + REUTER + + + +19-MAR-1987 08:31:00.91 + +usa + + + + + +F +f0665reute +r f BC-SJNB-<SJNB>-SAYS-CHIE 03-19 0071 + +SJNB <SJNB> SAYS CHIEF EXECUTIVE RESIGNS + SAN JOSE, Calif., March 19 - SJNB Financial Corp said +Douglas McLendon has resigned as president and chief executive +officer of the holding company and its San Jose National Bank +subsidiary and as a director of its Tri-Valley National Bank +subsidiary to pursue other interests. + It said vice chairman William Pfeifle, 68, will act as +interim president and chjief executive officer. + Reuter + + + +19-MAR-1987 08:33:10.94 + +west-germany + + + + + +RM +f0671reute +r f BC-GERMAN-INVESTORS-SLOW 03-19 0109 + +GERMAN INVESTORS SLOW TO ACCEPT BOND INNOVATIONS + By Franz-Josef Ebel, Reuters + WEST BERLIN, March 19 - The liberalization of West German +capital markets in May 1985 led to a flood of financial +innovations but the lack of a secondary market for these has +diminished their acceptance, Deutsche Girozentrale - Deutsche +Kommunalbank management board member Wiegand Hennicke said. + While innovations may be intellectualy stimulating, they +lack transparency, he told an investors' forum in West Berlin. + "Properly functioning markets require standardized products. +This (condition) has not been met by some of the innovations," +Hennicke said. + The volume of zero coupon bonds and floating rate notes, +the most widely used financial innovations in Germany, stands +at four billion and 16 billion marks, respectively, a tiny +proportion of the 1,000 billion marks of bonds in circulation. + Even for zero-coupon bonds and floating rate notes, a +secondary market had not developed, Hennicke said. One +important reason for this was the bourse turnover tax, which +was reducing the rate of return to the investors. + West German Finance Minister Gerhard Stoltenberg said this +week he believed the tax could still be removed, even if its +abolition was not decided during recent coalition discussions. + Karl-Herbert Schneider-Gaedicke, deputy management board +chairman of DG Bank Deutsche Genossenschaftsbank, said German +domestic and institutional investors had also shown +reservations about investing in participation shares. + One of the reasons was the widely varying terms and +conditions of participation shares in West Germany. "The +investor has to scrutinize (participation shares) carefully, +before making an investment decision," Schneider-Gaedicke said. + He added the attractiveness of participation shares could +be increased by limiting the combination possibilities of terms +and conditions and increasing safeguards for investors. + He also urged publicizing the comparative advantage of +participation shares over ordinary shares for foreigners. + Foreigners do not receive the corporation tax bonus granted +to domestic investors for share dividends. + Karl Thomas, head of the Bundesbank's credit department, +said the domestic investor had missed earnings opportunities +over the last four years by failing to invest in German bonds. + Domestic investors did not believe interest rates would +decline and stay at low levels for such a long time, because +expectations were determined by sharp interest rate +fluctuations at the start of the decade. + The Bundesbank has a natural interest in seeing domestic +savings channelled into bonds and shares, Thomas said. + A shift of savings into long-term assets would dampen +monetary expansion and foster a stable rise of the money +supply, he said. + REUTER + + + +19-MAR-1987 08:34:53.72 +earn + + + + + + +F +f0681reute +f f BC-******CARTER-HAWLEY-H 03-19 0013 + +******CARTER HAWLEY HALE STORES INC 4TH QTR SHR LOSS 1.58 DLRS VS PROFIT 58 CTS +Blah blah blah. + + + + + +19-MAR-1987 08:40:55.05 + +usa + + +cbt + + +C G +f0698reute +u f BC-CBT-HEAD-CONFIDENT-OF 03-19 0142 + +CBT HEAD CONFIDENT OF SEPARATE CBT, MCE LIMITS + BOCA RATON, Fla., March 19 - Chicago Board of Trade, CBT, +President Thomas Donovan said he was confident the Commodity +Futures Trading Commission, CFTC, would not force the CBT and +the MidAmerica Commodity Exchange, MCE, to merge speculative +position limits on futures contracts traded on the two +exchanges. + Last month CFTC proposed combining CBT and MCE contracts on +corn, wheat, soybeans, soybean meal and oats for the purposes +of applying speculative position limits. + Donovan told Reuters he had spoken to CFTC officials about +the matter and believed they would modify the proposal. + CBT officials have complained the CFTC was reneging on a +commitment made when the two exchanges formed an affiliation, +and proposing to decrease spot month limits on the MCE contrary +to congressional intent. + Reuter + + + +19-MAR-1987 08:45:33.50 + +usa + + +cbt + + +C +f0705reute +u f BC-CBT-LEADERS-PLAN-TRIP 03-19 0125 + +CBT LEADERS PLAN APRIL TRIP TO FAR EAST + BOCA RATON, Fla., March 19 - The two top officials of the +Chicago Board of Trade, CBT, are planning to visit three +countries in the Far East next month to drum up support for the +exchange's proposed night trading session, CBT President Thomas +Donovan told Reuters. + Donovan said he and CBT Chairman Karsten Mahlmann will +leave April 3 and spend two weeks in Hong Kong, Tokyo and +Sydney discussing the night trading session with brokerage +firms, regulators and exchanges. + CBT hopes to launch the first U.S. night trading session at +the end of April, offering Treasury-bond and T-note futures and +options on the two futures contracts between 1700 and 2100 hrs +central U.S. time (2300 to 0300 hrs GMT). + Reuter + + + +19-MAR-1987 08:49:57.02 + +switzerland + + + + + +F +f0709reute +u f BC-SWISSAIR-PLANE-ORDER 03-19 0112 + +SWISSAIR PLANE ORDER FOR 1.2 BILLION SWISS FRANCS + ZURICH, March 19 - Swissair <SWSZ.Z> said that the order +for McDonnell Douglas Corp <MD> MD-11 long haul jets confirmed +this morning was worth a total 1.2 billion Swiss francs. + President Robert Staubli told a news conference it had not +yet been decided whether the planes would have General Electric +Co <GE.N>, Pratt and Whitney <UTX> or Rolls Royce engines. + The airline said it chose the U.S. Plane rather than the +rival A-340 of the European Airbus consortium because it met +better the Swissair requirements and would be able to enter +service in 1990 giving a smooth transition from the DC-10s it +replaces. + Staubli said Swissair planned to have replaced its whole +fleet of 11 DC10s by 1992 at the latest, entailing the order of +five more long-haul planes in addition to the six announced +today. He said it would decide on the basis of the development +of traffic whether these five would be MD-11s or Boeing 747s. + However, Staubli ruled out the possibility that Swissair +might eventually choose A-340s. "We cannot afford to operate +three different types of aircraft," he said. + Swissair also had no short term plans to exercise its +option to buy Airbus A-310s, of which it already operates nine, +officials said. But it would still hold the options open. + Staubli declined to say how much it paid for each of the +MD-11s. The total 1.2 billion franc figure was not only for the +planes but also for spare parts and other related expenditure. + Company officials said that Swissair intended to cover +around 75 pct of the costs of its entire DC-10 replacement +programme with internally generated funds. It hopes to raise +the remaining 25 pct on the Swiss and other capital markets +through issuing straight or equity related bonds and/or through +a capital increase. + The first such bond issue would likely come this year, they +predicted. + REUTER + + + +19-MAR-1987 08:56:16.58 + +uk + + + + + +A +f0726reute +d f BC-BP-SALE-WAS-IN-UK-198 03-19 0115 + +BP SALE WAS IN UK 1987/88 BUDGET MATHS - TREASURY + LONDON, March 19 - The U.K. Treasury said its 1987/88 +budget arithmetic which was unveiled on Tuesday "took full +account of likely proceeds" from the sale of the government's +remaining 31.7 pct stake in British Petroleum Co PLC (BP.L). + A statement issued by the Treasury said "the BP announcement +therefore makes no difference to our estimate of privatisation +proceeds in 1987/88, or to subsequent years, which remains 5.0 +billion stg a year." + "It makes no difference to the PSBR (Public Sector Borrowing +Requirement) which the Chancellor set in the budget," it said. + "It has nothing to do with the future scope for tax cuts." + The Treasury's move was prompted by press speculation, +officials said, which followed last night's surprise +announcement by the government. It currently holds about 578.5 +mln shares in BP. + The Treasury statement said that the sell-off "is simply a +part of the government's continuing privatisation programme, +the overall size of which was announced in the Autumn +(economic) Statement" (last November). + It said the BP proceeds "will be received in installments, +of which the first will be in 1987/88." + News of the privatisation weighed down both BP's share +price in London and the equity market overall, market sources +said. + The prospect of so much more BP paper in circulation had +cut BP shares at 1340 GMT to 824 pence from yesterday's London +close of 828 pence. The company's shares had been down as low +as 802 pence before rebounding, stock market sources said. + Worries over the ability of the London stock market to +digest the BP and other privatisation issues sent the Financial +Times/Stock Exchange 100 Share Index down 9.1 points by 1340 +GMT to 1997.5 from last night's close. At one point the index +was as low as 1989.1, the sources said. + REUTER + + + +19-MAR-1987 08:59:17.90 +acq + + + + + + +F +f0733reute +b f BC-******WASTE-MANAGEMEN 03-19 0015 + +******WASTE MANAGEMENT SAYS IT IS PREPARED TO RAISE ITS BID FOR CHEMLAWN TO 33 DLRS A SHARE +Blah blah blah. + + + + + +19-MAR-1987 09:00:53.32 +earn +usa + + + + + +F +f0736reute +u f BC-TRANSAMERICA-<TA>-TO 03-19 0090 + +TRANSAMERICA <TA> TO HAVE GAIN ON UNIT SALE + LOS ANGELES, MArch 19 - Transamerica Corp said it expects +to realize a gain of about 75 mln dlrs on the +previously-announced sale of the group life and health +operations of its Transamerican Occidental Life Insurance Co +subsidiary to Provident Life and Accident Co <PACC>. + But it said its Transamerica Life Cos unit plans to change +to a more conservative method of amortizing deferred policy +acquisition costs, resulting in a one-time charge that will +offset most of the gain from the sale. + Transamerica said it has now signed a definitive agreement +for the sale, which will be structured as a reinsurance +transaction involving about 400 mln dlrs of reserve +liabilities. + It said the 75 mln dlr gain from the sale and about 125 mln +dlrs of statutory surplus that previously supported operations +of the group being sold will be used to support Transamerica +Life Cos' efforts to accelerate the growth of its remaining +businesses. It said closing is expected by May One, subject to +regulatory approvals. + Reuter + + + +19-MAR-1987 09:01:39.59 + +usa + + + + + +F +f0738reute +u f BC-COCA-COLA-<KO>-IN-FIL 03-19 0046 + +COCA-COLA <KO> IN FILM COLORING VENTURE + MARINA DEL RAY, Calif., March 19 - Color Systems Technology +Inc <CLST> said it has completed formation of a joint venture +called Screen Gems Classicolor with Coca-Cola Co to color and +distribute feature films and television programs. + Color Systems said it and Coca-Cola will share profits from +worldwide television, basic cable, pay television and home +video distribution, and Color Systems will also be paid by the +venture to convert to color the black and white material +involved. + The company said Coca-Cola has initially contributed a +number of its Screen Gems television series and Color Systems +its library of more than 100 feature films and television +series. It said the venture expects to acquire more black and +white material for color conversion and will start generating +revenues by distributing the combined library initially as-is. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-008.sgm b/src/test/data/reuters-21578/reut2-008.sgm new file mode 100644 index 00000000000..4eb70da8ff6 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-008.sgm @@ -0,0 +1,2019 @@ + + +20-MAR-1987 16:54:10.55 +earn +usa + + + + + +F +f2479reute +r f BC-GANTOS-INC-<GTOS>-4TH 03-20 0056 + +GANTOS INC <GTOS> 4TH QTR JAN 31 NET + GRAND RAPIDS, MICH., March 20 - + Shr 43 cts vs 37 cts + Net 2,276,000 vs 1,674,000 + Revs 32.6 mln vs 24.4 mln + Year + Shr 90 cts vs 69 cts + Net 4,508,000 vs 3,096,000 + Revs 101.0 mln vs 76.9 mln + Avg shrs 5,029,000 vs 4,464,000 + NOTE: 1986 fiscal year ended Feb 1, 1986 + Reuter + + + +20-MAR-1987 16:57:13.73 +acq + + + + + + +F +f2484reute +f f BC-******CHEMLAWN-CORP, 03-20 0010 + +******CHEMLAWN CORP, ECHOLAB INC SIGN DEFINITIVE MERGER AGREEMENT +Blah blah blah. + + + + + +20-MAR-1987 16:57:26.14 +grainwheatoilseedsoybeanveg-oil +usa + + + + + +C G +f2485reute +r f BC-LDC-FOOD-AID-NEEDS-DE 03-20 0124 + +LDC FOOD AID NEEDS DECLINE IN 1986/87 - USDA + WASHINGTON, March 20 - Total food aid needs in 69 of the +least developed countries declined in 1986/87, as requirments +fell in many countries in Africa, the Middle East and Asia, the +U.S. Agriculture Department said. + In a summary of its World Agriculture Report, the +department said grain production in sub-Saharan Africa was a +record high in 1986, with gains in almost every country. + However, food needs in Central America rose, worsened by +drought-reduced crops and civil strife. + Record wheat production in 1986/87 is pushing global wheat +consumption for food to a new high, and higher yielding +varieties have been particularly effective where spring wheat +is a common crop, it said. + However, may developing countries in tropical climates, +such as Sub-Saharan Africa, Southeast Asia, and Central +America, are not well adapted for wheat production, and +improved varieties are not the answer to rising food needs, the +department said. + World per capita consumption of vegetable oil will rise in +1986/87 for the third straight year. + Soybean oil constitutes almost 30 pct of vegetable oil +consumption, while palm oil is the most traded, the department +said. + Reuter + + + +20-MAR-1987 17:00:29.12 +sugargraincorn +usa + + + + + +C G T +f2491reute +b f BC-/U.S.-SUGAR-PROGRAM-C 03-20 0130 + +U.S. SUGAR PROGRAM CUT SENT TO CONGRESS BY USDA + WASHINGTON, MARCH 20 - The U.S. Agriculture Department +formally transmitted to Congress a long-awaited proposal to +drastically slash the sugar loan rate and compensate growers +for the cut with targeted income payments. + In a letter to the Congressional leadership accompanying +the "Sugar Program Improvements Act of 1987", Peter Myers, +Deputy Agriculture Secretary, said the Reagan administration +wants the sugar loan rate cut to 12 cents per pound beginning +with the 1987 crop, down from 18 cts now. + Sugarcane and beet growers would be compensated by the +government for the price support cut with targeted income +payments over the four years 1988 to 1991. The payments would +cost an estimated 1.1 billion dlrs, Myers said. + The administration sugar proposal is expected to be +introduced in the House of Representatives next week by Rep. +John Porter, R-Ill. + Congressional sources said the program cut is so drastic it +is unlikely to be adopted in either the House or Senate because +politically-influential sugar and corn growers +and high fructose corn syrup producers will strongly resist. + The direct payment plan outlined by the administration +targets subsidies to small cane and beet growers and gradually +lowers payments over four years. It also excludes from payment +any output exceeding 20,000 short tons raw sugar per grower. + For example, on the first 350 tons of production, a grower +would receive 6 cts per lb in fiscal 1988, 4.5 cts in 1989, 3 +cts in 1990 and 1.5 cts in 1991. + The income payments would be based on the amount of +commercially recoverable sugar produced by a farmer in the 1985 +or 1986 crop years, whichever is less, USDA said. + Myers said the administration is proposing drastic changes +in the sugar program because the current high price support is +causing adverse trends in the sugar industry. + He said the current program has artificially stimulated +domestic sugar and corn sweetener production which has allowed +corn sweeteners to make market inroads. + U.S. sugar consumption has declined which has resulted in a +"progressive contraction" of the sugar import quota to only one +mln short tons this year, he said. This has hurt cane sugar +refiners who rely on imported sugar processing. + Furthermore, USDA said the current sugar program gives +overseas manufacturers of sugar-containing products a +competitive advantage. The result has been higher imports of +sugar-containing products and a flight of U.S. processing +facilities overseas to take advantage of cheaper sugar. + USDA also said the current program imposes a heavy cost on +U.S. consumers and industrial users. In fiscal 1987, USDA said +consumers are paying nearly two billion dlrs more than +necessary for sugar. + "Enactment of this bill will reduce the price gap between +sweeteners and help to correct or stabilize the many adverse +impacts and trends which the sugar industry is currently +facing," Myers said. + The following table lists the rate of payments, in cts per +lb, to growers and the quantity covered, in short tons +recoverable raw sugar, under the administration's proposal to +compensate sugar growers with targeted payments. + QUANTITY 1988 1989 1990 1991 +First 350 tons 6.000 4.500 3.000 1.500 +Over 350 to 700 5.750 4.313 2.875 1.438 +Over 700 to 1,000 5.500 4.125 2.750 1.375 +Over 1,000 to 1,500 5.000 3.750 2.500 1.250 +Over 1,500 to 3,000 4.500 3.375 2.250 1.125 +Over 3,000 to 6,000 3.500 2.625 1.750 0.875 +Over 6,000 to 10,000 2.250 1.688 1.125 0.563 +Over 10,000 to 20,000 0.500 0.375 0.250 0.125 +Over 20,000 tons nil nil nil nil + Reuter + + + +20-MAR-1987 17:00:52.39 +earn +canada + + + + + +E +f2494reute +d f BC-oink 03-20 0042 + +<OE INC> 4TH QTR NET + MONTREAL, March 20 - + Shr 24 cts vs 26 cts + Net 1.5 mln vs 1.3 mln + Revs 40.5 mln vs 33.5 mln + Year + Shr 80 cts vs 82 cts + Net 4.9 mln vs 4.1 mln + Revs 143.0 mln vs 121.1 mln + Avg shrs 6.1 mln vs 5.0 mln + Reuter + + + +20-MAR-1987 17:01:28.16 + +usa + + + + + +F +f2497reute +r f BC-TEXAS-INSTRUMENTS-<TX 03-20 0106 + +TEXAS INSTRUMENTS <TXN> BEGINS BUILDING PLANT + DALLAS, March 20 - Texas Instruments Inc said construction +will begin in April on a new plant near Denton, Texas, on 193 +acres owned by the company. + It said the plant will initially employ between 1,000 and +1,500 people, and will be used by its Defense Systems and +Electronics Group for producing electronic equipemnt. The plant +is expected to be operational in late 1988. + Separately, the company said it leased about 185,000 square +feet of a complex in Texas for its Defense Systems group. It +plans to transfer about 700 employees to work at the site by +the third quarter of 1987. + Reuter + + + +20-MAR-1987 17:06:31.28 +earn +usa + + + + + +F +f2510reute +w f BC-VMS-MORTGAGE-LP-<VMLP 03-20 0037 + +VMS MORTGAGE LP <VMLPZ> MONTHLY CASH PAYOUT + CHICAGO, March 20 - VMS Mortgage L.P. said it declared a +regular monthly cash distribution of nine cts a depositary unit +for the month of March, payable May 14, record April One. + Reuter + + + +20-MAR-1987 17:06:47.92 +livestockpork-belly +usa + + +cme + + +C L +f2512reute +u f BC-LITTLE-EFFECT-SEEN-FR 03-20 0117 + +LITTLE EFFECT SEEN FROM COLD STORAGE REPORT + CHICAGO, March 20 - The USDA monthly cold storage report +for meats is expected to have little, if any, effect on +livestock and meat futures at the Chicago Mercantile Exchange +Monday and daily fundamentals will likely provide the bulk of +direction, livestock analysts said. + The increase of 66.4 mln lbs in total poultry offsets the +22.6 mln lbs decline in total red meats. Fundamentals may +provide most of the direction in futures on Monday, they said. + "I think the market is going to be looking at some other +things and accentuate whatever the action of cash markets might +be early next week," Jerry Gidel, livestock analyst for GH +Miller, said. + Shearson Lehman livestock analyst Chuck Levitt said futures +will be in the shadow of a little larger seasonal hog +marketings pace next week. Also, Easter ham business was +completed this week and there may be less aggressive interest +for pork in general next week. + "We needed some help from the cold storage report to avert +a possible setback next week in the pork complex," Levitt said. + Analysts agreed with CME floor traders and called the belly +figure neutral to slightly negative. Although belly stocks were +down 33 pct from last year, they exceeded the average +expectation and actually showed a lighter than expected decline +from last month due to an adjustment to last month's holdings, +they said. + However, analysts noted that the amount of bellies put in +storage has been light since the beginning of March and this is +a potentially bullish situation. + Glenn Grimes, agronomist at the University of Missouri, +said, "I would not look for (belly) storage during the next +month or two to be heavier than a year ago - I think it will be +less." + Reuter + + + +20-MAR-1987 17:07:44.99 +shipgrain +canada + + + + + +E F +f2515reute +h f BC-SEAWAY (PIX-EXPECTED) 03-20 0130 + +STRIKE THREAT, LOWER TRAFFIC MAR SEAWAY OPENING + By Jane Arraf, Reuters + MONTREAL, March 20, Reuter - The St. Lawrence Seaway, set +to reopen March 31 after the winter, faces another tough year +because of depressed traffic levels and the possibility of the +first strike in 20 years on the Great Lakes, seaway officials +said. + Depressed grain exports, rising costs, and competing modes +of transportation are all expected to result in only a marginal +increase over last year's traffic levels -- and revenues -- on +the 2,300 mile waterway, officials said. + In 1986, a season that ran from April 3 to December 27, the +seaway moved 37.6 mln metric tons of freight between Montreal +and Lake Ontario and 41.6 mln tons on the Welland Canal, +linking Lake Erie and Lake Ontario. + By comparison, in 1985 about 37 mln tons of cargo traveled +through the Montreal-Lake Ontario section and 42 mln through +the eight-lock canal. + The waterway is expected to lose 9-10 mln Canadian dlrs +this year, about the same as the estimated deficit for fiscal +1986-87 ending March 31, said William Blair, an executive +member of Canada's St Lawrence Seaway Authority. + The seaway moves about one-half of Canada's exported grain. +Those exports of the single most important commodity carried on +the waterway have been depressed by world surpluses. + The Seafarers' International Union, which represents about +2,300 workers on the Great Lakes and the ocean coasts, has said +it will likely go on strike this spring to protest employers' +demands for wage rollbacks and other concessions. + "It's 99.9 pct (certain)--I guarantee you a strike," Roman +Gralewicz, head of the Seafarers' Canadian branch, has said. + The Canadian government has called in a labor conciliator +to try to hammer out a contract agreement between the two +sides. The seaway authority said a walkout tying up ships on +the Great Lakes would badly hurt traffic. + "We haven't had a strike on the seaway for years...a +prolonged strike would have a disasterous effect," Seaway +Authority spokeswoman Gay Hemsley said. + "These are the heaviest contract talks in the history of the +St Lawrence Seaway," George Miller, vice-president of the +Canadian Lake Carriers Association, an association of major +Canadian shipping companies, said recently. + The workers' current contract expires May 31. The +association said it is asking for a five per cent cut in wages +for the next three years, reduced crew levels and the power to +restructure crew dispatching. + The association said its members recorded about a 6 mln dlrs +(U.S.) loss in each of 1985 and 1986 due to lower traffic and +freight rates and increasing competition. The seaway said 1985 +was its worst year in two decades. + Hemsley said the seaway authority plans to raise tolls on +the Welland Canal by eight pct this year, compared to last +year's 15 pct rise, while maintaining a freeze on tolls +throughout the rest of the waterway. + Canada is responsible for 13 of the seaway's 15 locks and +about 85 pct of its revenues and maintenance costs. + "We may see and hope for a steady upward climb...but we +won't see a major increase for a number of years," Hemsley said. + A Canada-U.S. delegation to promote the seaway to shippers +in Western Europe should result in some increased traffic this +season but the full benefits won't be felt for several years, +Blair said. + Reuter + + + +20-MAR-1987 17:07:50.76 +acq +usa + + + + + +F +f2516reute +u f BC-CHEMLAWN-<CHEM>,-ECOL 03-20 0065 + +CHEMLAWN <CHEM>, ECOLAB <ECON> IN MERGER PACT + COLUMBUS, Ohio, March 20 - Chemlawn Corp and Ecolab Inc +said they signed a definitive merger agreement under which +Ecolab will buy all outstanding Chemlawn common stock for 36.50 +dlrs a share in cash, for a total of about 370 mln dlrs. + Under terms of the agreement, Chemlawn said it rescinded +its previously announced rights dividend plan. + Chemlawn previously rejected a 27 dlr a share offer from +Waste Management Inc <WMX>. + Yesterday, the Oak Brook, Ill.-based waste disposal company +said it was prepared to offer 33 dlrs a share, or about 330 mln +dlrs, for Chemlawn, a lawn-care company. + Chemlawn had said last week that it was negotiating with +other possible suitors, which it did not identify. + A Chemlawn spokesman said further details on the merger +would be issued later. + Ecolab is a maker of commercial laundry detergent based in +St. Paul, Minn. For its first six months ended December 31, the +company earned 20.4 mln dlrs, or 76 cts a share, on sales of +421.8 mln dlrs. + Officials at Waste Management could not be reached for +immediate comment. + Reuter + + + +20-MAR-1987 17:10:14.07 +earn + + + + + + +F +f2524reute +b f BC-******LILCO-REVISES-1 03-20 0011 + +******LILCO REVISES 1986 NET TO INCLUDE 16 MLN DLR LOSS PROVISION +Blah blah blah. + + + + + +20-MAR-1987 17:12:06.51 +earn +usa + + + + + +F +f2527reute +h f BC-FALCON-CABLE-<FAL>-SE 03-20 0073 + +FALCON CABLE <FAL> SETS INITIAL DISTRIBUTION + PASADENA, Calif., March 20 - Falcon Cable Systems Co said +its set an initial quarterly cash distribution of 53.75 cts per +unit, payable May 15 to unitholders of record March 31. + The partnership made its initial public offering in +December, 1986. + Falcon said it expects to pay cash distributions to limited +partners at an annual rate of 2.15 dlrs per unit, through +December 31, 1989. + Reuter + + + +20-MAR-1987 17:12:35.20 + +usa + + + + + +F +f2530reute +u f BC-GENERAL-DYNAMICS-<GD> 03-20 0064 + +GENERAL DYNAMICS <GD> GETS 67.9 MLN DLR CONTRACT + WASHINGTON, March 20 - The Electric Boat Division of +General Dynamics Corp is being awarded a 67.9 mln dlr +modification to a Navy contract for architectural, engineering +and hardware development work for a submarine improvement +program, the Defense Department said. + It said the work is expected to be completed September 30, +1987. + Reuter + + + +20-MAR-1987 17:15:01.04 + +usa + + + + + +A RM +f2533reute +r f BC-SONAT-<SNT>-UNIT-FILE 03-20 0090 + +SONAT <SNT> UNIT FILES FOR DEBENTURE OFFERING + NEW YORK, March 20 - Southern Natural Gas Co, a unit of +Sonat Inc, said it filed with the Securities and Exchange +Commission a registration statement covering a 100 mln dlr +issue of debentures due 1999. + Proceeds will be used, together with funds from the +company's operations, to redeem Southern Natural's 15 pct +sinking fund debentures of 1991. + The company named Goldman, Sachs and Co, Lazard Freres and +Co and Merrill Lynch Capital Markets as managing underwriters +of the offering. + Reuter + + + +20-MAR-1987 17:16:21.60 +crude +usa + + + + + +Y +f2536reute +r f BC-BIDS-AWARDED-FOR-ELK 03-20 0104 + +BIDS AWARDED FOR ELK HILLS CRUDE OIL + LOS ANGELES, March 20 - The U.S. Department of Energy said +it has awarded bids for about 90,000 barrels per day, bpd, of +crude oil from the Elk Hills Naval Petroleum Reserve in +California. The contract period runs from April one through +July one, the DOE said. + Successful bidders, the amount of crude oil and the price +per bbl according to the DOE are as follows - + Texaco Inc's <TX> Texaco Trading and Transport 15,000 bpd +at 15.79 dlrs and 2,200 bpd at 15.19 dlrs, Beacon Oil Co 7,000 +bpd at 15.66 dlrs and 2,500 bpd at 16.04 dlrs, Golden West +Refining 8,110 bpd at 15.42 dlrs. + Successful bidders, the amount of oil and price per bbl, +according to the DOE continue as follows - + Chevron's <CHV> Chevron USA Inc 3,000 bpd at 14.51 dlrs and +4,000 bpd at 14.61 dlrs, Chevron International Oil Co 2,600 bpd +at 14.41 dlrs and 2,800 bpd at 14.51 dlrs, Newhall Refining Co +6,000 bpd at 15.82 dlrs, Caljet Inc 4,000 bpd at 15.32 dlrs, +Casey Co 4,000 bpd at 15.45 dlrs. + Also, Cryssen Refining Inc 4,000 bpd at 15.47 dlrs, +Edgington Oil Co 4,000 bpd at 15.54 dlrs, Sound Refining Inc +3,100 bpd at 15.51 dlrs, Atlantic Richfield Co <ARC> 3,000 bpd +at 15.75 dlrs. + Successful bidders, the amount of crude oil and the price +per bbl according to the DOE continue as follows - + Orkin Inc 2,679 bpd at 15.24 dlrs, Lunday-Thagard Co 2,511 +bpd at 15.27 dlrs, Golden Eagle Refining 2,500 bpd at 15.37 +dlrs, MacMillan Ring-Free Oil Co 1,000 bpd at 15.81 dlrs, 1,000 +bpd at 15.71 dlrs and 230 bpd at 16.02 dlrs, Mock Resources +2,000 bpd at 15.76 dlrs, Petro-Diamond 2,000 bpd at 15.46 dlrs. + Reuter + + + +20-MAR-1987 17:20:28.92 +earn +usa + + + + + +F +f2544reute +s f BC-MONTGOMERY-STREET-INC 03-20 0024 + +MONTGOMERY STREET INCOME <MTS> MONTHLY DIVIDEND + SAN FRANCISCO, March 20 - + Mthly div 15 cts vs 15 cts + Pay April 15 + Record April 1 + Reuter + + + +20-MAR-1987 17:20:54.85 +earn +canada + + + + + +E +f2545reute +r f BC-sullivan-mines-inc 03-20 0056 + +<SULLIVAN MINES INC> YEAR LOSS + MONTREAL, March 20 - + Oper shr loss 12 cts vs profit four cts + Oper loss 1,069,000 vs profit 339,000 + Revs 12.8 mln vs 10.9 mln + Note: 1986 shr and net exclude extraordinary gain of +382,000 dlrs or four cts share. 1985 shr and net exclude +extraordinary gain of 183,000 dlrs or two cts share + Reuter + + + +20-MAR-1987 17:21:38.85 + +usa + + + + + +F +f2547reute +u f BC-GRUMMAN-<GQ>-GETS-109 03-20 0051 + +GRUMMAN <GQ> GETS 109.1 MLN DLR NAVY CONTRACT + WASHINGTON, March 20 - Grumman Aerospace Corp is being +awarded a 109.1 mln dlr increment of funds to a Navy contract +for 12 EA-6B Prowler Electronic Warfare aircraft, the Defense +Department said. + It said the work is expected to be completed in July 1989. + Reuter + + + +20-MAR-1987 17:23:12.99 + +usa + + + + + +F +f2549reute +r f BC-MORTON-THIOKOL-<MTI> 03-20 0061 + +MORTON THIOKOL <MTI> GETS 61.4 MLN DLR CONTRACT + WASHINGTON, March 20 - Morton Thiokol Inc's Wasatch +Operations is being awarded a 61.4 mln dlr contract +modification finalizing a previously awarded contract for +missile rocket motors for Terrier, Tarter and Aegis ships, the +Defense Department said. + It said the work is expected to be completed in October +1987. + Reuter + + + +20-MAR-1987 17:26:53.43 +acq +usa + + + + + +F +f2560reute +u f BC-CYCLOPS 03-20 0106 + +INVESTMENT FIRM HAS 7.1 PCT OF CYCLOPS <CYL< + WASHINGTON, March 20 - Halcyon Investments, a New York risk +arbitrage and securities dealing partnership, told the +Securities and Exchange Commission it has acquired 288,000 +shares of Cyclops Corp, or 7.1 pct of the total outstanding. + Halcyon said it bought the stake for 26.1 mln dlrs as part +of its ordinary risk arbitrage and securities trading business. +Other than that, the firm said there was no specific purpose in +its purchases. + Halcyon said it might buy more stock or sell some or all of +its current stake. It said it bought the bulk of its stake +between Feb 6 and March 13. + Reuter + + + +20-MAR-1987 17:27:19.61 +acq +canada + + + + + +E A +f2561reute +d f BC-chrysler-credit-canad 03-20 0107 + +CHRYSLER'S <C> CREDIT CANADA PLACED ON CREDITWATCH + Montreal, March 20 - Canadian Bond Rating Service said it +placed Chrysler Credit Canada Ltd, a subsidiary of Chrysler +Corp <C>, on creditwatch until all financial details concerning +the proposed acquisition of American Motors Corp <AMO> are +finalized. + The creditwatch affects Chrysler Credit Canada's short term +notes, guaranteed notes, debentures and the recently completed +75 mln dlr 9.25 Eurobond issue due April 15, 1993. + Canadian Bond Rating Service said that, based on facts +currently available on the proposed transaction, it does not +anticipate the necessity of a downgrade. + Canadian Bond Rating Service said Chrysler Credit Canada +short term notes are now rated A-2 (high) and guaranteed notes +and debentures are rated B plus plus (high). + Reuter + + + +20-MAR-1987 17:27:55.93 +earn +usa + + + + + +F +f2565reute +u f BC-LILCO-<LIL>-REVISES-1 03-20 0089 + +LILCO <LIL> REVISES 1986 NET TO INCLUDE LOSS + HICKSVILLE, N.Y., March 20 - Long Island Lighting Co said +it revised its preliminary 1986 net income to include a 16 mln +dlrs after tax provision for its investment in the Jamesport +Nuclear units. + Due to the provision, it said its revised 1986 net income +was 316.7 mln dlrs or 2.13 dlrs per share after deducting for +preferred stock dividend requirements, which were not paid in +either 1986 or 1985. + It had earlier reported 1986 income of 332.7 mln dlrs or +2.28 dlrs per share. + LILCO also said its board authorized contracts for its +corporate officers calling for payment of one year's salary, +and continuation of insurance and retirement benefits if the +company changes hands and these officers lose their jobs. + LILCO said none of these contracts will result in +additional costs to its customers. + Lilco said the downward revision in its 1986 earnings is a +reserve established to reflect a settlement agreement with the +staff of New York State's Public Service Commission respecting +the utility's spending on a nuclear power station planned for, +but never built at, Jamestown, N.Y. + The company declined to detail the settlement, explaining +the settlement has not been approved by the commission. Lilco +was seeking to include costs totaling 118 mln dlrs for the +abandoned nuclear power plant project in its rate base, a +spokeswoman said. + Reuter + + + +20-MAR-1987 17:29:58.63 +acq +usa + + + + + +F +f2571reute +d f BC-ROGERS-<ROG>-ADOPTS-R 03-20 0104 + +ROGERS <ROG> ADOPTS RIGHTS PLAN + ROGERS, Conn., March 20 - Rogers Corp said its board +approved a shareholder rights plan designed to protect its +shareholders in the event of an attempted hostile takeover. + Rogers said the plan is not being adopted in response to +any specific takeover attempt. + Under the plan, shareholders may buy one share of common +stock at 65 dlrs for each share held. The rights will be +exercisable only if a person or group acquires 20 pct or more +of Rogers' shares or announces an offer for 30 pct or more. + The dividend distribution will be made March 30 to holders +or record on that date. + Reuter + + + +20-MAR-1987 17:32:18.21 + +usa + + +nyse + + +F +f2575reute +u f BC-WALL-STREET-SURVIVES 03-20 0102 + +WALL STREET SURVIVES TRIPLE EXPIRATIONS + By Cal Mankowski, Reuters + NEW YORK, March 20 - The four-times-a-year "triple +witching hour" did not jolt Wall Street as much as it has in +the past. + Market averages finished sharply higher as stock index +futures, index options and options on individual stocks expired +simultaenously. Some analysts warned part of the gain may be +retraced next week. But there were signs Wall Street is getting +used to the phenomeon which causes a huge burst of activity in +the final minutes. Officials of the New York Stock Exchange +said the day went smoothly and efficiently. + "This has been one of the few times that the consensus has +been right," said Jim Creber, trader at Miller, Tabak, Hirsch +and Co. + He expects a "follow-through" Monday and Tuesday to the +advance which lifted the Dow Jones Industrial Average 34 points +for the day and 75 points for the entire week. + Creber, whose firm was one of the first to get involved in +arbitrage activity involving index futures and options, said +the general trend of the market has been upward for months. +"Every time the market comes in, somebody comes along with more +money," he said. + He said investors adding to Individual Retirement Accounts +prior to a mid-April tax deadline and buying from Japanese +investors are apparently helping push stocks higher. + Ron Feinstein, an analyst with Dean Witter Reynolds Inc, +said reports of heavy Japanese buying, just prior to the end of +the fiscal year in Japan, fueled bullish sentiment. + He said investors who had long positions in stocks hedged +with short positions in index futures rolled the expiring March +futures over into June contracts. But he added different +players with other goals also were active and there was no +simple explanation of the market's gyrations. + For example, Feinstein noted the June contract for the June +Standard and Poor's 500 stock index future hit 300 about 15 +minutes prior to the close of NYSE trading. In 12 minutes, the +contracted dipped to 297.50. "That could have been a wave of +selling from institutional people making a roll," he said. + It was the first time a nearby contract of the S and P 500 +hit 300. The cash index closed at a record 298.17. "It looks +like the market is going to continue to go higher," he said. + "Triple expirations didn't really mean that much, it was a +strong day for stocks," said Steve Chronowitz of Smith Barney, +Harris Upham and Co. + Chronowitz said the stock market has been underpinned by +"good solid buying interest" which will cushion any pullback. + Other investors who were long futures and short stocks +bought stocks on the close today instead of rolling over, said +Mark Zurack of Goldman, Sachs and Co. He cautioned against +"over-dramatizing" the day's activity, which said was more a +reflection of fundamental strength in the markets. + Leigh Stevens of PaineWebber Group Inc said what he saw was +mostly covering of short positions in stocks as index options +and individual options expired. He said there could be a +decline early next week in the stock market. + "It looked like it worked well today," said Howard Kramer, +asssistant director of market regulation for the Securities and +Exchange Commission. But he said all of the data will have to +be analyzed next week. + He said there was relatively little commotion at the close, +with about 50 mln shares changing hands in the final minute +compared to 85 mln in the triple expirations three months +earlier. He noted the Dow industrials jumped about 12 points in +the closing minutes, a modest move for a 2333-point index. + Kramer pointed out an SEC-NYSE measure to curb volatility, +disclosure of "market-on-close" orders in 50 major stocks 30 +minutes prior to the end of trading, showed imbalances of +modest proportions. The disclosures are aimed at evening out +volatility by attracting orders on the opposite side of the +imbalance. + The data showed more buy orders than sell orders for 47 +stocks, a preponderance of sell orders for only one stock, and +no significant imbalance for two stocks. The NYSE had tightened +a rule governing what type of market on close orders can be +accepted in the final half hour. + Reuter + + + +20-MAR-1987 17:39:14.71 +earn +usa + + + + + +F +f2586reute +s f BC-EASTGROUP-PROPERTIES 03-20 0037 + +EASTGROUP PROPERTIES <EGP> DIVIDEND + JACKSON, MISS., May 20 + Qtly div 65 cts vs 65 cts prior + Payable APril 22 + REcord April 10 + NOTE:Company paid 30 cts special dividend along with prior +quarter's dividend + Reuter + + + + + +20-MAR-1987 17:40:10.54 +earn +usa + + + + + +F +f2588reute +r f BC-SUNBELT-NURSERY-GROUP 03-20 0050 + +SUNBELT NURSERY GROUP INC <SBN> 2ND QTR FEB 28 + FORT WORTH, Texas, March 20 - + Shr loss 40 cts vs loss 29 cts + Net loss 1.5 mln vs loss 1.1 mln + Revs 28.9 mln vs 28.5 mln + Six months + Shr loss 99 cts vs loss 69 cts + Net loss 3.7 mln vs loss 2.6 mln + Revs 52.5 mln vs 51.7 mln + + Reuter + + + +20-MAR-1987 17:41:26.30 +earn +usa + + + + + +F +f2590reute +d f BC-MARCOM-TELECOMMUNICAT 03-20 0067 + +MARCOM TELECOMMUNICATIONS <MRCM> 2ND QTR JAN 31 + WEST PALM BEACH, Fla., March 20 - + Oper shr loss five cts vs loss six cts + Oper net loss 157,688 vs loss 96,573 + Revs 1,094,331 vs 1,378,973 + Avg shrs 3,315,654 vs 1,661,023 + Six mths + Oper shr loss seven cts vs loss 24 cts + Oper net loss 198,555 vs loss 394,589 + Net 2,243,377 vs 2,440,850 + Avg shrs 2,796,848 vs 1,637,592 + NOTE: Current year 2nd qtr and six mths excludes a loss +10,767 dlrs for discontinued operations. + Prior year 2nd qtr and six mths excludes a loss of 54,686 +dlrs and 112,565 dlrs for discontinued operations. + Full name of company is Marcom Telecommunications Inc. + Reuter + + + +20-MAR-1987 17:43:13.77 +earn +usa + + + + + +F +f2600reute +s f BC-EASTPARK-REALTY-TRUST 03-20 0024 + +EASTPARK REALTY TRUST <ERT> QTLY DIV + JACKSON, MISS, March 20 - + Qlty div 25 cts vs 25 cts prior + Payable April 22 + Record April 10 + Reuter + + + +20-MAR-1987 17:44:23.79 +trade +canadausa + + + + + +E +f2604reute +h f AM-TRADE 03-20 0138 + +CANADA'S CLARK SEES TRADE AS MOST URGENT PROBLEM + By Dean Lokken, Reuters + SAN FRANCISCO, March 20 - Trade is the most urgent problem +facing U.S.-Canadian relations because of a pressing need to +reach a new bilateral pact within the coming months, Joe Clark, +Canadian secretary of state for external affairs, said. + Negotiators for the two countries have been meeting for +more than a year in an effort to work out an agreement. + "The most urgent problem now is the trade question because +that has to be decided within the next 10 months," Clark told +the Commonwealth Club of California. "We have a fast track +authority from your Congress for approval or rejection of +whatever the negotiators achieve." + Clark said that, as a practical matter, an initial +agreement must be reached by late September or early October. + He listed environmental questions, particularly acid rain, +and defense as the second and third most important bilateral +issues facing Ottawa and Washington. + On Wednesday, President Reagan announced that he will seek +2.5 billion dlrs from Congress to address the acid rain +problem. Some interpreted the move as a goodwill gesture in +advance of his annual meeting, on April 5-6 in Ottawa, with +Prime Minister Brian Mulroney. + In a question-and-answer session with the public affairs +group, Clark said that the two countries must find better +mechanisms for resolving their trade disputes. + "This rash of countervailing actions, where we acted on +corn and you acted on soft wood and we both said they were +quasijudicial -- the dispute resolution mechanisims in place +now are not working adequately in either of our interests," he +said. + Ottawa also is seeking to change some of Washington's rules +on government procurement that penalize Canadian businesses, he +said. + "There are a number of Canadian companies that, in order to +secure substantial contracts in the United States, have had to +move their head offices out of our country into your country +because you have national procurement requirements," he said. + In turn, he added, the United States would like to change +some of the procurement requirements that exist at the +provincial government level in Canada. + Clark declined to forecast the outcome of the discussions. + "What will come out of it remains for the negotiators, in +the first instance, to propose, and then governments and +congresses will have judge," he said. + In his prepared remarks, Clark said that the United States +has tended to take Canada for granted, although it exports to +its northern neighbor more than twice what it exports to Japan. +"Yet you bought almost 10 per cent more from Japan last year +than you bought from Canada," he said. REUTER + Reuter + + + +20-MAR-1987 17:45:15.30 +earn +usa + + + + + +F +f2605reute +h f BC-ESSEX-CORP-<ESEX>-YEA 03-20 0056 + +ESSEX CORP <ESEX> YEAR END LOSS + ALEXANDRIA, Va., March 20 - + Oper shr loss 11 cts vs profit 33 cts + Oper net loss 132,000 vs profit 408,000 + Revs 25.2 mln vs 23.0 mln + NOTE: 1986 and 1985 oper net excludes a loss of 636,000 +dlrs or 52 cts per share and a loss of 994,000 dlrs or 80 cts +per share for discontinued operations. + Reuter + + + +20-MAR-1987 17:45:24.11 + +usaindonesia + + + + + +F +f2606reute +r f BC-DELTA- 03-20 0078 + +U.S. LAUNCHES INDONESIAN COMMUNICATIONS SATELLITE + CAPE CANAVERAL, March 20 - NASA launched an Indonesian +communications satellite aboard a Delta rocket, marking the +first international payload to be put into orbit since the +Challenger disaster more than a year ago. + The 43 mln dlr satellite, the Palapa B2-P, was launched as +the result of an agreement reached last year between President +Ronald Reagan and Indonesia's President Suharto when they met +on Bali. + + Reuter + + + +20-MAR-1987 17:50:45.11 +earn +canada + + + + + +E F Y +f2617reute +r f BC-sulpetro 03-20 0093 + +<SULPETRO LTD> YEAR OCT 31 LOSS + CALGARY, Alberta, March 20 - + Shr loss 19.22 dlrs vs loss 3.90 dlrs + Net loss 276.4 mln vs loss 45.6 mln + Revs 85.4 mln vs 113.3 mln + NOTE: Shr results after deducting preferred share dividends +of 13.1 mln dlrs in both periods. + Current loss includes a 125 mln dlr writedown of oil and +gas properties, a 67 mln dlr writeoff of deferred charges, a +22.5 mln dlr loss on disposal of U.K. properties, a 21.2 mln +dlr equity loss from affiliate Sulbath Exploration ltd and a +4.6 mln dlr loss on other investments. + Reuter + + + +20-MAR-1987 17:51:40.27 + +canada + + + + + +E +f2619reute +d f BC-alberta-budget-sets 03-20 0097 + +ALBERTA BUDGET SETS TAX INCREASE, LOWER DEFICIT + EDMONTON, Alberta, March 20 - The Alberta provincial +government will increase its general corporate tax rate on +April 1 to 15 pct from 11 pct under its 1987-88 budget +announced today, provincial treasurer Dick Johnston said. + The budget forecasts the 1987-88 provincial deficit to be +1.90 billion dlrs, compared to a forecast deficit of 3.30 +billion dlrs for fiscal 1987, which ends March 31, Johnston +said. + The budget forecasts fiscal 1988 revenues of 8.63 billion +dlrs and expenditures of 10.42 billion dlrs, Johnston said. + The provincial budget raises combined personal and +corporate income taxes by about 20 pct, Johnston said. + Johnston told a news conference taxes were increased after +revenues from oil and gas taxes fell by 64 pct last year and +are not expected to increase sharply in the short term. + The provincial government expects resource tax revenues for +fiscal 1987 to fall to 1.30 billion dlrs from a previously +estimated 2.20 billion dlrs, compared to 3.60 billion dlrs +collected in fiscal 1986 before the collapse in oil prices. + Johnston told reporters he needed to raise taxes in order +to begin moving towards a balanced budget in 1990-91. + Johnston said the personal income tax increase takes three +forms. The basic provincial tax rate rises to 46.5 pct from +43.5 pct of the basic federal income tax rate. + The provincial budget also imposed a temporary eight pct +surtax on individuals with taxable income of more than 36,000 +dlrs, he said. + In addition, the government levied a flat one pct surtax on +all individuals with taxable income. + Johnston said overall government spending of 10.42 billion +dlrs represents a cut of 4.4 pct, but various grants and tax +credits for agriculture and energy industries will remain. + Reuter + + + +20-MAR-1987 17:54:04.61 + +usa + + + + + +F +f2622reute +d f BC-WISCONSIN-ELECTRIC-<W 03-20 0085 + +WISCONSIN ELECTRIC <WTC> OFFERS PREFERRED + NEW YORK, March 20 - Wisconsin Electric Power Co said it +began a public offering of 700,000 shares of serial preferred +stock, 6-3/4 pct series, 100 dlrs par value, at a price of 100 +dlrs per share. + The shares are being offered pursuant to a shelf +registration covering 700,000 sahres of serial preferred stock +which the company filed on February 19, 1987. + Proceeds will be used to redeem outstanding preferred stock +or for repayment of short-term indebtedness. + Reuter + + + +20-MAR-1987 17:55:02.25 + +usa + + + + + +A RM +f2623reute +r f BC-TEXAS-AIR-<TEX>-UNIT 03-20 0116 + +TEXAS AIR <TEX> UNIT SELLS EQUIPMENT-BACKED DEBT + NEW YORK, March 20 - Continental Airlines Inc, a unit of +Texas Air Corp, is offering 350 mln dlrs of equipment-backed +debt securities in three tranches and another 150 mln dlrs of +senior notes due 1997, said lead manager Drexel Burnham. + A 100 mln dlr offering of first priority secured equipment +certificates due 1992 was given a 10 pct coupon and par +pricing. This tranche is non-callable to maturity. + A 125 mln dlr issue of second priority secured equipment +certificates due 1995 has an 11 pct coupon and par pricing and +an equal-sized offering of third priority certificates due 1999 +was given an 11-3/8 pct coupon and par pricing. + The second two tranches of the equipment-backed deal are +non-callable for five years, Drexel said. + Continental's 10-year notes were assigned an 11-1/2 pct +coupon and priced at par. They are non-callable for five years. +Texas Air has guaranteed the scheduled payments of interest and +principal for the senior notes. + The securities are rated B-2 by Moody's and B by Standard +and Poor's. Kidder Peabody, Merrill Lynch and Smith Barney +co-managed the issues. Proceeds, estimated at 486 mln dlrs, +will be used to repay about 254 mln dlrs of bank debt, with the +remainder added to working capital, Continental said. + Reuter + + + +20-MAR-1987 18:00:25.76 +earn +usa + + + + + +F +f2628reute +r f BC-STANWOOD-CORP-<SNW>-4 03-20 0073 + +STANWOOD CORP <SNW> 4TH QTR JAN 3 + NEW YORK, March 30 - + Shr loss 1.12 dlrs vs profit one cts + Net loss 1.7 mln vs profit 8,000 dlrs + Revs 31.8 mln vs 42.1 mln + Year + Shr loss 51 cts vs profit 57 cts + NEt loss 780,000 vs profit 876,000 + Revs 117.8 mln vs 117.3 mln + NOTE:1986 4th qtr includes loss of 911,000 for termination +of licensing agreement and loss of 319,000 dlr for termination +of womens wear operation. + Reuter + + + +20-MAR-1987 18:01:38.04 + +usa + + + + + +F +f2630reute +r f BC-GUEST-SUPPLY-<GEST>-G 03-20 0059 + +GUEST SUPPLY <GEST> GETS SHAREHOLDER SUIT + NORTH BRUNSWICK, N.J., March 20 - Guest Supply INc said a +shareholder sued it and certain officers and directors, +alleging misrepresentations and omissions in the prospectus for +the company's September 1986 public offering. + Guest said the complaint is without merit and will defend +the action vigorously. + Reuter + + + +20-MAR-1987 18:01:49.51 + +usabraziljapan +conable +worldbankimf + + + +A RM +f2631reute +r f BC-CONABLE-SAYS-BRAZIL-D 03-20 0106 + +CONABLE SAYS BRAZIL DEBT MORATORIUM IS TEMPORARY + WASHINGTON, March 20 - World Bank President Barber Conable +said he believed Brazil's decision to suspend foreign debt +interest payments is temporary. + Conable in a wide-ranging television interview to be shown +on public broadcasting tomorrow said Brazil now has the +attention of its creditors and must come up with a plan +designed to reform its economy. + "I think the Brazilians have the attention of many of their +creditors, but they must come up with a plan that will persuade +people that the Brazilian economy is going to be put on a +course that will result in some growth." + Turning to Japan, Conable said the role of that country has +been increasing in the World Bank and is expected to continue +to do so. + He said that Japan had made an additional 450 mln dlr +pledge to the International Development Association, an +indication that it agrees that it must provide more help in +line with its economic position. + Conable said there was no indication that the Soviet Union +was serious about joining the International Monetary Fund and +World Bank. He said they would have to get convertible currency +and open their books and the Soviets "don't usually do that." + REUTER + + + +20-MAR-1987 18:06:35.19 +earn +canada + + + + + +E F Y +f2635reute +r f BC-sulpetro-loss-due-to 03-20 0116 + +SULPETRO LOSS DUE TO WRITEDOWNS, ASSET DISPOSALS + Calgary, Alberta, March 20 - <Sulpetro Ltd> said its 1986 +fiscal year net loss of 276.4 mln dlrs, or 19.22 dlrs per +share, was due to several factors, the largest of which was a +writedown of 125.0 mln dlrs of oil and gas properties. + Sulpetro also recorded a writeoff of deferred charges +amounting to 67.0 mln dlrs, a loss of 22.5 mln dlrs on the +disposal of all properties in the United Kingdom and an equity +loss of 21.2 mln dlrs from affiliate Sulbath Exploration Ltd. + There was also a loss on other investments of 4.6 mln dlrs +and a loss on operations of 36.1 mln dlrs after interest, +depletion, depreciation and income tax recoveries. + In the fiscal year ended October 31, 1985, Sulpetro had a +net loss of 45.6 mln dlrs, or 3.90 dlrs per share. + The company also said its non-recourse project financing +for the Irish-Lindergh heavy oil field remains in default due +to continuing low oil prices. + Reuter + + + +20-MAR-1987 18:07:55.50 +acq +usa + + + + + +F +f2636reute +u f BC-AMERICAN-EXPRESS-<AXP 03-20 0099 + +AMERICAN EXPRESS <AXP> TO DISCUSS SHEARSON DEAL + New York, March 20 - American Express Co's board of +directors Monday will discuss the company's arrangement to sell +13 pct of Shearson Lehman Brothers Inc to Nippon Life Insurance +Co, a company spokesman said. + The spokesman would not say whether the board is planning +to vote on the understanding between American Express and +Nippon Life. The Shearson stake is to be sold for 530 mln dlrs, +American Express has said. + The spokesman also would not comment on speculation that +the board was to discuss a sale of securities to the public. + Monday's board meeting is a regular monthly meeting. The +plan to sell part of Shearson to Nippon Life must be approved +by the American Express board and Japan's Ministry of Finance. + Earlier, American Express and Shearson said they were +subpoenaed by the Securities and Exchange Commission. American +Express said it was subpoenaed for documents pertaining to +securities transactions of American Express and Fireman's Fund. +Shearson was subpoenaed for documents related to transactions +with Jefferies and Co and others. + The American Express spokesman said he could not comment on +whether any officials of the firm were subpoenaed. + Reuter + + + +20-MAR-1987 18:11:31.62 +crudenat-gasfuel +usa + + + + + +Y +f2642reute +r f BC-NATURAL-GAS-SEEN-RECA 03-20 0107 + +NATURAL GAS SEEN RECAPTURING SOME MARKET SHARE + By NAILENE CHOU-WIEST, Reuters + NEW YORK, March 17 - Higher crude oil prices will raise +demand for natural gas, helping it to reclaim market share lost +to heavy oil when prices plunged in 1986, analysts said. + The analysts said that these efforts will be most +successful in the industrial sectors of the economy with large +and growing energy requirements. + "Natural gas stands a good chance to recapture the share of +oil supplied to electric utilities that it lost to the residual +fuel industry last year," Michael Smolinski, an energy +economist with Data Resources Inc, told Reuters. + An estimated 200,000 barrels per day of residual fuel went +into the utilities market at the expense of natural gas last +year when world oil prices plunged, Smolinski said. + Assuming oil prices hold above 15 dlrs a barrel, national +average gas prices delivered to the utilities at a projected +2.10 to 2.25 dlrs per mln Btu would be very competitive, +Michael German, vice president of economic analysis at American +Gas Association said. + The average delivered prices at the end of January were +2.10 dlrs per mln Btu, compared with 3.26 dlrs a year ago. + "We expect natural gas to regain 250 to 400 billion cubic +feet (of demand) in the overall energy market in the second and +third quarter (1987)," he said. + In addition to price competitiveness, availability will be +an important factor persuading energy users to switch to gas, +Frank Spadine, senior energy economist with Bankers Trust Corp. +in New York noted. + Spadine said the mild winter in many parts of the North +American continent has led to a build up of gas inventories and +less would be necessary to replenish underground storage this +spring freeing gas for spot sales. + These forecasts develop a strong counterpoint to the fears +that natural gas suplies would be tight and prices +significantly higher given a sharp decline in drilling last +year. + AGA's German contended that despite the drilling decline, +much of U.S. proved reserves could be brought to production +quickly through developments such as the infill drilling which +permits more wells to be drilled in proved reserve basins. + Citing recent EIA statistics, German said, the gas surplus +was likely to contract from three trillion cubic feet in 1986 +to two trillion cubic feet in 1987, but the surplus would not +go away until 1990. + Smolinski of Data Resources agreed that the surplus would +persist until 1990. While gas supplies may tighten in certain +consuming areas, notably in California and in the Northeast +U.S., an overall shortfall appeared remote. + Reuter + + + +20-MAR-1987 18:14:24.22 + +usa + + + + + +F +f2647reute +r f BC-LOUISIANA-LAND-<LLX> 03-20 0064 + +LOUISIANA LAND <LLX> ASSUMES INEXCO'S DEBT + NEW ORLEANS, March 20 - Louisiana Land and Exploration Co +said it assumed the obligation to pay the principal and +interest on the 8-1/2 pct convertible subordinated debentures +due September 1, 2000 of Inexco Oil Co, a unit of Louisiana +Land. + Effective March 23, the debentures will be listed as the +debentures of Louisiana Land, LLXOO. + Reuter + + + +20-MAR-1987 18:16:46.86 + +canada + + + + + +E A +f2653reute +r f BC-macmillan-bloedel-to 03-20 0063 + +MACMILLAN BLOEDEL <MMBLF> TO REDEEM DEBENTURES + VANCOUVER, British Columbia, March 20 - MacMillan Bloedel +Ltd said it will redeem all outstanding nine pct series J +debentures on April 27, 1987 for 34.9 mln U.S. dlrs, plus a +premium of one pct and accrued and unpaid interest. + The series J debentures were issued in Europe in 1977 and +were due February 1992, the company said. + Reuter + + + +20-MAR-1987 18:19:27.03 +trade +usajapan + + + + + +F A RM +f2659reute +r f AM-TRADE-COMPUTERS 03-20 0106 + +U.S. SENATORS SAY SANCTIONS LIKELY ON MICROCHIPS + By Jacqueline Frank, Reuters + WASHINGTON, March 20 - The United States will likely impose +sanctions soon on imports of Japanese microchips, senators said +today after a private meeting with Commerce Secretary Malcolm +Baldrige. + Although the senators said Baldrige told them no decision +would be taken until a final determination is made on whether +Japanese microchips were dumped in the United States, they said +they were virtually sure Japan would face penalties. + President Reagan's trade policy advisory group, of which +Baldrige is a member, will meet on the issue Wednesday. + "I am confident we will see action taken," Sen. John McCain, +an Arizona Republican, told reporters. + "I am expecting sanctions at least, and even more than +sanctions," Sen. Pete Domenici, a New Mexico Republican, said. + The senators, several congressmen and U.S. semiconductor +industry representatives met with Baldrige and State Department +officials to discuss Japan's alleged violations of a September +1986 agreement to stop dumping its microchips in the United +States and other countries. + They recommended Japanese firms be penalized through +tariffs or import duties over the next six to 12 months for +continuing to dump microchips. The violations were worth 100 +mln dls to the Japanese semiconductor industry, they said. + Asked if Baldrige intended to recommend sanctions, Sen. +Pete Wilson told reporters, "The clear import of what he said is +that there will be." + "Japan can't just say they will comply. We think sanctions +must be applied," for past violations of the agreement, the +California Republican said. + The semiconductor industry produces microprocessor chips +which are used in high technology products ranging from radios +to defence missile guidance systems. + Sen. James McClure, an Idaho Republican, said Baldrige told +them the administration had not made a final determination that +Japanese companies had dumped semiconductor microchips below +the cost of production in the United States or other countries. + But McClure said senators told him, "There is no doubt +dumping is going on," based on evidence such as invoices of +purchases of the Japanese products. + The two countries signed a pact last September in which +Japan agreed to stop selling its microchips in the United +States and other countries below production costs and to allow +the U.S. semiconductor industry access to the Japanese market. + In return, the United States waived its right to impose +import duties on the Japanese microchips. + Japanese officials have said they have lived up to the pact +and have asked Japanese chip-makers to further slash output to +save the pact. + Japan has frequently been the target of congressional +discouragement over last year's record 169-billion-dlr trade +deficit. Tokyo had a 59-billion-dlr surplus with the United +States last year and had large surpluses with other countries. + The Senate yesterday unanimously passed a resolution +calling for action against Japan for violations of the pact +since September. The resolution will be introduced in the House +next week by Rep. Bob Matsui, a California Democrat. + Reuter + + + +20-MAR-1987 18:20:01.80 +earn +usa + + + + + +F +f2661reute +d f BC-MULTI-MEDIA-SEES-YEAR 03-20 0093 + +MULTI-MEDIA SEES YEAR END LOSS + NEW YORK, March 20 - Multi-Media Barter Ltd said it expects +to report a net loss of 820,000 dlrs or 17 cts a share for the +year ended December 31, compared to a loss of 553,000 or 11 cts +a share in the prior year. + The fourth quarter resulted in a net loss of 227,000 or +four cts compared to a loss of 330,000 or six cts a shares last +year. + It said it is currently in the process of restructuring by +reducing expenses and streamlining operations and has cut +expenses from 50,000 dlrs to less than 15,000 dlrs a month. + Reuter + + + +20-MAR-1987 18:25:06.34 + +usa + + + + + +F +f2670reute +d f BC-WIEBOLDT'S-TO-CLOSE-E 03-20 0110 + +WIEBOLDT'S TO CLOSE EIGHT STORES + CHICAGO, March 20 - Wieboldt's Department Stores, in +Chapter 11 bankruptcy since September 1986, said as part of an +agreement with creditors it will operate its four largest and +most productive stores but close the remaining eight stores. + It said 341 employees of its remaining 885 employees will +be laid off or terminated as a result. + The company also said it established a fund of about 12 mln +dlrs to be available for payment of creditors' claims. + The retailer said it would continue to operate its four +largest and most productive Chicago area outlets - State +Street, Randhurst, Harlem-Irving and Ford City. + Reuter + + + +20-MAR-1987 18:26:27.13 +earn +usa + + + + + +F +f2673reute +w f BC-NATIONAL-HMO-CORP-<NH 03-20 0058 + +NATIONAL HMO CORP <NHMO> 2ND QTR JAN 31 + MELBOURNE, Fla, March 20 - + Shr loss nine cts vs profit nine cts + Net loss 478,000 vs profit 371,000 + Revs 3.4 mln vs 2.6 mln + Six months + Net loss 466,000 vs profit 685,000 + Revs 6.2 mln vs 5.0 mln + NOTE:1987 net loss includes writeoff of deferred start up +costs totaling 490,000 dlrs. + Reuter + + + +20-MAR-1987 18:39:41.65 +earn +canada + + + + + +F +f2685reute +r f BC-MINORCO-<MNRCY>-HALF 03-20 0038 + +MINORCO <MNRCY> HALF YEAR DEC 31 + TORONTO, ONtario, March 20 - + Shr 26 cts vs 38 cts + Net 44.0 mln vs 65.0 mln + NOTE:1986 net includes one mln dlr extraordinary gain and +1985 net icludes four mln dlrs extraordinary loss. + Reuter + + + +20-MAR-1987 18:41:04.26 + +usaphilippines + + + + + +RM A +f2686reute +u f BC-PHILIPPINE-DEBT-TALKS 03-20 0110 + +PHILIPPINE DEBT TALKS TO CONTINUE ON SATURDAY + NEW YORK, March 20 - The Philippines and its bank advisory +committee completed another round of debt rescheduling talks +and will meet again on Saturday, a senior banker said. + Although today's negotiations did not produce a final +agreement, the decision to meet at the weekend appears to be a +signal that the two sides are making progress. + The Philippines seeks to restructure 9.4 billion dlr of its +27.2 billion dlr foreign debt. The interest rate to be charged +on the debt and Manila's proposal to pay interest partly with +investment notes instead of cash have been the main sticking +points in the talks. + Reuter + + + +20-MAR-1987 18:41:09.81 +earn +usa + + + + + +F +f2687reute +r f BC-MINORCO-<MNRCY>-SEES 03-20 0069 + +MINORCO <MNRCY> SEES IMPROVED SECOND HALF + TORONTO, Ontario, March 20 - Minorco said it expects net +earnings to be substantially stronger than the 44.0 mln dlrs +reported for the first half. + In reporting that first half results declined from 65.0 mln +dlrs, Minorco said the contributions from its 50 pct investment +in December 1985 in Adobe Resources Corp was negative as a +result of low oil and gas prices. + Reuter + + + +20-MAR-1987 18:41:20.90 +earn +usa + + + + + +E +f2688reute +r f BC-MINORCO-<MNRCY>-SEES 03-20 0069 + +MINORCO <MNRCY> SEES IMPROVED SECOND HALF + TORONTO, Ontario, March 20 - Minorco said it expects net +earnings to be substantially stronger than the 44.0 mln dlrs +reported for the first half. + In reporting that first half results declined from 65.0 mln +dlrs, Minorco said the contributions from its 50 pct investment +in December 1985 in Adobe Resources Corp was negative as a +result of low oil and gas prices. + Reuter + + + +20-MAR-1987 18:44:31.15 + +usa + + + + + +A +f2691reute +r f BC-FDIC-SAYS-INDIANA-BAN 03-20 0091 + +FDIC SAYS INDIANA BANK BECOMES 48TH TO FAIL + WASHINGTON, March 20 - The Federal Deposit Insurance Corp +said state banking regulators closed the Morocco State Bank in +Morrocco, Indiana, bringing the total number of banks to fail +so far this year to 48. + The failed bank's 14.1 mln dlrs in deposits and 9.9 mln +dlrs of its loans and other assets will be assumed by DeMotte +State Bank in DeMotte, Ind, the FDIC said. + The FDIC said it will advance 3.7 mln dlrs to help the +transaction and would retain 5.1 mln dlrs in the failed banks +assets. + Reuter + + + +20-MAR-1987 18:48:35.54 + +usa + + + + + +V RM +f2693reute +u f AM-ARMS-KAMPELMAN 03-20 0112 + +U.S. ARMS NEGOTIATOR SAID TO HAVE HEART ATTACK + WASHINGTON, March 20 - U.S. arms negotiator Max Kampelman +suffered a mild heart attack, an aide said. + Nancy Tackett, Kampleman's staff assistant, told Reuters +Kampelman was doing well and was expected to leave George +Washington Hospital in about a week. + "A full recovery is expected," she said. + Kampelman did not feel well yesterday and may have +sufffered the heart attack then, Tackett said. He had a +regularly-scheduled physical this morning and entered the +hospital after that, on his doctor's advice, she said. + A hospital spokesman confirmed that Kampelman was a +patient in the coronary care unit. + + Reuter + + + +20-MAR-1987 18:49:16.73 + +usa + + + + + +A +f2695reute +u f BC-DALLAS-BASED-THRIFT-C 03-20 0103 + +DALLAS-BASED THRIFT CLOSED BY REGULATORS + WASHINGTON, March 20 - The Federal Home Loan Bank Board +said Dallas-based Vernon Savings and Loan Association, the 15th +largest thrift in Texas, was closed by state authorities and +its assets, deposits and liabilities were transfered to a new +federally chartered association. + Vernon, with 1.35 billion dlrs of assets and nine offices +in Texas and Oklahoma, was closed after state regulators +concluded it was in unsafe and unsound condition. + The thrift was owned by Texas businessman Donald Dixon, who +bought it in early 1982, when it had only 120 mln dlrs in +assets. + The bank board said growth was accomplished largely through +the purchase of brokered deposits and the sale of jumbo +certificates of deposit, which totaled 29 pct of total deposits +at the end of 1986. + The bank board also said that 96 pct of its loan portfolio +was nonperforming as a result of sloppy loan practices. + It said Vernon also paid excessive salaries and dividends +to officers and directors and bought a beach house and five +airplances for the use of thrift executives and stockholders. + The bank board ousted the thrift's officers and directors +and hired another Texas association to run it. + The bank board also said it closed First Federal of +Maryland, a federal savings association that had 115.2 mln dlrs +in assets. It said its 118 mln dlrs in insured deposits were +transferred to Columbia First Federal Savings and Loan +Association of Washington, D.C. + The bank board said First Federal had engaged in unsound +loan underwriting practices and many of the loans are now +deliquent. The institution experienced heavy and continuing +losses and became insolvent, the bank board said. + Reuter + + + +20-MAR-1987 18:50:54.45 +tin +bolivia + +imfworldbank + + + +RM A +f2699reute +r f BC-BOLIVIA-PREPARES-FOR 03-20 0108 + +ECONOMIC SPOTLIGHT - BOLIVIA + By Paul Iredale, Reuters + LA PAZ, March 20 - Bolivia, once Latin America's most +delinquent debtor, is preparing for a second International +Monetary Fund agreement after an economic stabilisation program +has effectively slowed inflation and reduced public spending. + A fund spokesman said an IMF team would visit La Paz +shortly to discuss terms of the new agreement. + He said the IMF had disbursed 130 mln dlrs here and 20 mln +dlrs are pending under the one year agreement that ends this +month. The accord provided for a stand-by loan, a compensatory +financing facility and a structural adjustment facility. + The spokesman said that if the agreement is renewed, +Bolivia can expect a further 60-mln-dlr stand-by loan over the +next 12 months. + Bolivia's agreement with the IMF, its first since 1980, +opened the door to rescheduling negotiations with the Paris +Club and Argentina and Brazil, which hold 2.5 billion dlrs of +Bolivia's 4.0-billion-dlr foreign debt. + Central Bank President Javier Nogales told Reuters the +negotiations with the Paris Club, which have yet to be +finalised, had been extremely successful. + Nogales said the Paris Club had agreed to reschedule +Bolivia's debt over 10 years with five to six years grace and +had waived all interest payments until the end of 1988. + Bilateral discussions on interest rates continue, he said. + Nogales said Bolivia was expecting some 400 mln dlrs in +disbursements this year from lender countries and international +agencies, including the World Bank and the Inter-American +Development Bank, although diplomatic and banking sources put +the figure at closer to 300 mln dlrs. + Nogales said Bolivia's net international reserves are +around 250 mln dlrs, up from one mln dlrs when President Ictor +Paz Estenssoro took office in august 1985. Nogales said the +capital flow on Bolivia's debt servicing versus new credits had +changed from a net outflow of 200 mln dlrs in 1985 to a net +inflow of 130 mln dlrs in 1986. + Bolivia's return from the financial wilderness follows paz +estenssoro's economic stabilisation program. He inherited +inflation of 23,000 pct a year, state enterprises that were +losing hundreds of mlns of dlrs and a currency that traded on +the black market at up to 16 times its official rate. + Paz estenssoro froze public sector wages, set a market- +related rate for the peso, introduced tax reforms and laid off +thousands of workers in state corporations. + Inflation has been running at 10 pct a year for the past +six months, according to the Central Bank, and the government +expects the economy to grow three pct this year after a 14 pct +contraction over the last six years. + The government is also proposing a novel solution to its +debt to commercial banks, some 900 mln dlrs, on which interest +has not been paid since March, 1984. + Nogales said that over the next few months Bolivia would +make a one-time offer to buy back all its commercial debt at +the price it trades on the international secondary market -- +10-15 cents on the dlr. He said Bolivia's commercial bank +steering committee agreed at a meeting in New York to consider +the proposal, but it is still unclear what proportion of the +country's creditor banks will take up the offer. + One foreign banker speculated that Bolivia might be able to +buy back up to 30 pct of its commercial debt paper under the +deal, mostly from small banks who have written off their loans +to the country. + But he said the larger creditors were more interested in a +scheme of debt-equity swaps, similar to that which has operated +in Chile for the past two years. + The Bolivian government has yet to draw up proposals for +debt-equity swaps, but the banker said it was planning to +privatise more than 100 state companies and these could serve +as a basis for such a scheme. + Foreign bankers said this type of proposal might prove +attractive to Bolivia in the long run, especially as the +government realises that it will have to attract a large amount +of new capital in order to grow. + Planning Minister Gonzalo Sanchez de Lozada told Reuters +that Bolivia was hoping for five to six billion dlrs in new +investment over the next 10 to 12 years. + The government realises that in order to remain viable, +Bolivia will need to develop new exports. + The price of tin, which accounted for some 45 pct of +Bolivia's exports in 1984, has collapsed on the world markets, +and gas, the country's major revenue earner, is in abundant +supply in the region. + Reuter + + + +20-MAR-1987 18:51:57.82 +earn +usa + + + + + +F +f2703reute +r f BC-NEOAX-INC-<NOAX>-4TH 03-20 0046 + +NEOAX INC <NOAX> 4TH QTR + LAWRENCEVILLE, N.J., March 20 - + Shr loss 13 cts vs loss six cts + Net loss 1.4 mln vs loss 635,000 + Revs 40.3 mln vs 28.5 mln + Year + Shr profit 40 cts vs profit 26 cts + Net profit 4.2 mln vs 2.6 mln + Revs 166.4 mln vs 94.6 mln + NOTE:1986 4th qtr and year net reflects dividend +requirements of 1.5 mln dlrs and 3.3 mln dlrs, and charges of +257,000 dlrs and 4.6 mln dlrs respectively which is not +accruable or payable because of pre-reorganization tax loss +carryforwards. + 1985 4th qtr and year net reflects dividend requirement of +1.1 mln dlrs and 2.3 mln dlrs, respectively, and charges of +472,000 dlrs and 2.9 mln dlrs respectively which is not +accruable or payable because of pre-organization tax loss +carryforwards. + Reuter + + + +20-MAR-1987 18:57:24.80 + +usa + + + + + +F +f2706reute +r f BC-PACIFIC-STOCK-EXCHANG 03-20 0083 + +PACIFIC STOCK EXCHANGE SHORT INTEREST UP + SAN FRANCISCO, March 20 - The Pacific Stock Exchange said +there was a total short interest of 1,413,674 shares of stock +exclusively traded on the Exchange as of March 13, an increase +of 102,486 shares from last month's restated total of +1,311,188. + The Exchange said the short interest ratio rose to 1.42 +from last month's ratio of 1.25. + The ratio is based on an average daily trading volume of +994,545 shares in the 47 issues included in the report. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-009.sgm b/src/test/data/reuters-21578/reut2-009.sgm new file mode 100644 index 00000000000..838ee844ff2 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-009.sgm @@ -0,0 +1,2003 @@ + + +24-MAR-1987 15:59:17.10 + +usa + + + + + +F +f2412reute +u f BC-ADVANCED-MAGNETICS-<A 03-24 0066 + +ADVANCED MAGNETICS <ADMG> IN AGREEMENT + CAMBRIDGE, Mass., March 24 - Advanced Magnetics Inc said it +reached a four mln dlrs research and development agreement with +ML TEchnolgy Ventures LP, a limited partnership sponsored by +Merrill LYnch Capital Markets. + Under the agreement, Advanced Magnetics will develop and +conducts clinical trials of its contrast agents for magnetic +resonance imaging. + The agreement includes a warrant permitting MLTV to buy up +to 380,000 shares of Advanced Magnetics common stock through +February 1994 at 10.50 dlrs per sahre. + Reuter + + + +24-MAR-1987 15:59:39.63 + +usa + + + + + +F +f2414reute +d f BC-HEALTH-RESEARCH-FILES 03-24 0108 + +HEALTH RESEARCH FILES FOR BANKRUPTCY + MINNEAPOLIS, Minn., March 24 - <Health Research and +Management Group> said it has filed for protection under +Chapter 11 of the federal bankruptcy law. + The company said it filed the petitions to reorganize debt +and eliminate contingent liabilities it incurred while +attempting to expand nationally. + Health Research also said it owes about 750,000 dlrs of its +1.1 mln dlrs in debt to <MedPro Group Inc>, a former jont +venture partner. + The company added it has asked the Minnesota Department of +Commerce to suspend trading of its common stock pending +dissemination of current financial information. + Also, the company said George Frisch has been elected +chairman of the board, president and chief executive officer, +replacing Daniel Zismer, who resigned as chairman of the board +and O. Frederick Kiel, who resigned as president and chief +executive officer. + Reuter + + + +24-MAR-1987 16:00:01.29 +earn +usa + + + + + +F +f2415reute +h f BC-NUMEREX-CORP-<NMRX>-2 03-24 0052 + +NUMEREX CORP <NMRX> 2ND QTR JAN 31 LOSS + MINNEAPOLIS, MINN., March 24 - + Shr loss seven cts vs profit five cts + Net loss 149,421 vs profit 103,120 + Sales 1,698,345 vs 1,920,010 + Six Mths + Shr loss five cts vs profit nine cts + Net loss 100,472 vs profit 191,614 + Sales 3,836,794 vs 3,650,322 + Reuter + + + +24-MAR-1987 16:01:25.88 + + + + + + + +V RM +f2419reute +f f BC-******U.S.-SELLING-12 03-24 0015 + +******U.S. SELLING 12.8 BILLION DLRS OF 3 AND 6-MO BILLS MARCH 30 TO PAY DOWN 1.2 BILLION DLRS +Blah blah blah. + + + + + +24-MAR-1987 16:02:17.95 + + + + + + + +V RM +f2423reute +f f BC-******U.S.-2-YEAR-NOT 03-24 0015 + +******U.S. 2-YEAR NOTE AVERAGE YIELD 6.43 PCT, STOP 6.44 PCT, AWARDED AT HIGH YIELD 85 PCT +Blah blah blah. + + + + + +24-MAR-1987 16:03:55.80 + +usa + + + + + +F +f2426reute +u f BC-COMMODORE-<CBU>,-ATAR 03-24 0056 + +COMMODORE <CBU>, ATARI IN SETTLEMENT + NEW YORK, March 24 - Commodore International Ltd said it +settled and discontinued all pending litigation with Atari +Corp. + The company issued a statement which said the case had been +settled on terms satisfactory to both sides. + Company officials were not immediately available for +comment. + Reuter + + + +24-MAR-1987 16:04:42.31 +trademoney-fx +usataiwanjapansouth-korea + + + + + +RM A +f2428reute +b f BC-/BALDRIGE-SUPPORTS-NI 03-24 0088 + +BALDRIGE SUPPORTS NIC TALKS ON CURRENCIES + WASHINGTON, March 24 - Commerce Secretary Malcolm Baldrige +said he supported efforts to persuade newly-industrialized +countries (NICS) to revalue currencies that are tied to the +dollar in order to help the United States cut its massive trade +deficit. + "We do need to do something with those currencies or we +will be substituting Japanese products for Taiwanese products," +or those of other nations with currencies tied to the dollar, +Baldrige told a House banking subcommittee. + The U.S. dollar has declined in value against the Yen and +European currencies, but has changed very little against the +currencies of some developing countries such as South Korea and +Taiwan because they are linked to the value of the dollar. + As a result, efforts to reduce the value of the dollar over +the past year and a half have done little to improve the trade +deficits with those countries. + Baldrige told a House Banking subcommittee that the +Treasury Department was attempting to persuade those countries +to reach agreement with the United States on exchange rates. + + Reuter + + + +24-MAR-1987 16:05:14.04 + +usa + + + + + +F +f2431reute +u f BC-TRIANGLE-<TRI>-BEGINS 03-24 0044 + +TRIANGLE <TRI> BEGINS EXCHANGE OFFER + NEW YORK, March 24 - Triangle Industries Inc said it began +a previously announced offer to exchange one share of Triangle +common stock for each share of participating preferred stock. + The offer will expire April 21. + Triangle said that sales in 1987 will exceed four billion +dlrs. + For the year ended December 31, 1986, Triangle reported +sales of 2.7 billion dlrs and net income of 47.6 mln dlrs. + + Reuter + + + +24-MAR-1987 16:05:42.34 + +usa + + + + + +F +f2435reute +r f BC-SOUTHMARK-<SM>-UNIT-I 03-24 0108 + +SOUTHMARK <SM> UNIT IN PUBLIC OFFERING OF STOCK + DALLAS, March 24 - Southmark Corp's National Heritage Inc +said it has started the initial public offering of 2,000,000 +shares of common stock at 9.50 dlrs per share. + It said all shares are being traded though NASDAQ under +the symbol <NHER>. + The lead underwriter for the offering is Drexel Burnham +Lambert Inc, with Bear, Stearns and Co Inc., and E.F. Hutton +and Co Inc acting as co-underwriters, the company said. + Proceeds will be used to augment working capital, complete +scheduled renovations at some National Heritage leased +facilities and repay certain debts to Southmark, it said. + Reuter + + + +24-MAR-1987 16:06:25.01 +acq + + + + + + +F +f2438reute +f f BC-******EASTMAN-KODAK-C 03-24 0013 + +******EASTMAN KODAK CO TO SELL HOLDINGS IN ICN PHARMACEUTICALS AND VIRATEK INC +Blah blah blah. + + + + + +24-MAR-1987 16:07:44.11 + +usa + + + + + +A +f2442reute +r f BC-FEUD-PERSISTS-AT-U.S. 03-24 0105 + +FEUD PERSISTS AT U.S. HOUSE BUDGET COMMITTTEE + WASHINGTON, March 24 - A feud among Democrats and +Republicans persisted at the House Budget Committee, stalling +the writing of a fiscal 1988 U.S. budget plan. + Republicans failed to appear at a drafting session called +by Democratic committee chairman William Gray as a make-up +meeting to end bickering that has delayed budget activity for +a week and threatens the ability of Congress meeting an April +15 deadline for completing the deficit-cutting budget. + Republicans told Gray yesterday they would appear today and +participate if the meeting was held behind closed doors. + + He said the Republicans were prepared to make a "good faith" +effort to cooperate if the budget deliberations were held +behind closed doors and not in public as is the normal +procedure. + However, they failed to appear today and Gray said he had +been told they wanted House Speaker Jim Wright to answer a +series of budget questions posed by House Republican leader Bob +Michel before they would cooperate in budget matters. + The budget feuding led the Washington Post today to +editorialize that it was childish, similar to an eraser fight +among fourth grade students. + Reuter + + + +24-MAR-1987 16:07:51.39 +interest +usa + + + + + +A RM +f2443reute +u f BC-TREASURY-BALANCES-AT 03-24 0084 + +TREASURY BALANCES AT FED ROSE ON MARCH 23 + WASHINGTON, March 24 - Treasury balances at the Federal +Reserve rose on March 23 to 3.332 billion dlrs from 3.062 +billion dlrs on the previous business day, the Treasury said in +its latest budget statement. + Balances in tax and loan note accounts fell to 15.513 +billion dlrs from 17.257 billion dlrs on the same respective +days. + The Treasury's operating cash balance totaled 18.845 +billion dlrs on March 23 compared with 20.318 billion dlrs on +March 20. + Reuter + + + +24-MAR-1987 16:08:11.64 + +usa + + + + + +A +f2444reute +r f BC-FARM-CREDIT-SYSTEM-SE 03-24 0112 + +FARM CREDIT SYSTEM SEEN NEEDING 800 MLN DLRS AID + WASHINGTON, MARCH 24 - A member of the board which +regulates the farm credit system said Congress should plan to +provide at least 800 mln dlrs in fiscal 1988 to bailout the +troubled system, but other members of the board differed. + Jim Billington, Farm Credit Administration (FCA) board +member told a House Agriculture Appropriations subcommittee +hearing "I feel your subcommittee should plan on providing at +least 800 mln next year to assist the Farm Credit System." + However, FCA board member Marvin Duncan differed, saying +"it is premature to talk about the cost of a solution until we +know what kind of solution." + Chairman of the FCA board, Frank Naylor, said it might be +possible to structure a rescue of the system with government +guarantees or a line of credit which requires little or no +upfront government money. + However, Billington said Congress must provide help +immediately because "this system needs some assurance that it +will get some help." + The FCA estimates the system could lose up to 1.4 billion +dlrs in 1987, exhausting the remainder of its working capital, +Naylor said. + The farm credit system is expected to present its own +proposals for government aid to a Senate Agriculture +subcommittee hearing on Thursday. + Naylor said the Treasury Department is continuing to refine +Reagan administration ideas on how a rescue should be +structured. + Congressional sources said they hope to begin drafting a +rescue bill for the farm credit system as early as next week. + Reuter + + + +24-MAR-1987 16:09:09.08 +iron-steel +usa + + + + + +F +f2445reute +u f BC-USX-<X>-USS-UNIT-RAIS 03-24 0068 + +USX <X> USS UNIT RAISES PRICES + LORAIN, Ohio, March 24 - USX Corp's USS subsidiary said +that effective with shipments beginning July 1 prices for all +leaded grades and 1200-series grades of hot rolled bar and +semi-finished products from its Lorain, Ohio, facility will be +increased by 15 dlrs a ton over the prices in effect June 1. + It said the increase is being made to reflect current +market conditions. + Reuter + + + +24-MAR-1987 16:10:06.45 +trade +japanusa + + + + + +F +f2447reute +d f BC-UNIONIST-URGES-RETALI 03-24 0108 + +UNIONIST URGES RETALIATION AGAINST JAPAN + WASHINGTON, March 24 - William Bywater, president of the +International Union of Electronic Workers, called on President +Reagan to retaliate against Japan for unfair practices in +semiconductor trade. + He said in a statement a crash program was needed in the +semiconductor industry to prevent the United States from +becoming "one of the world's industrial lightweights." + Bywater's remarks came as the White House Economic Policy +Council prepared for a Thursday meeting to decide what +sanctions if any should be taken against Japan for alleged +violations of a U.S.-Japanese semiconductors agreement. + The pact, agreed to last July, called for Tokyo to end +selling semiconductors at below cost and to open its home +market to U.S. goods. In return, Washington agreed to forego +antidumping duties on Japanese semiconductors. + But U.S. officials have said that while Japan has stopped +dumping in the U.S. market, it has not ended third country +dumping; nor has it opened its market to U.S. semiconductors. + Japan yesterday, in an effort to ward off U.S. action, +ordered a cutback in semiconductors production as a way to +force prices up and end the dumping. + Bywater, in his statement, said he backed a Defense Science +Board task force proposal to set up a consortium to develop new +electronic products and manufacturing processes and make the +U.S. industory more competitive. + But he added the industry could not wait for legislation to +pass and that action was required now to help the depressed +electronic industry. + Bywater said, "I urge the Reagan Administration to take full +and severe action immediately against Japan by invoking the +retaliatory steps that are permitted under U.S. law and GATT +(General Agreement on Tariffs and Trade)." + Reuter + + + +24-MAR-1987 16:12:10.73 + +usa + + + + + +F +f2454reute +u f BC-EXXON-(XON)-GETS-99.2 03-24 0030 + +EXXON (XON) GETS 99.2 MLN DLR CONTRACT + WASHINGTON, March 24 - Exxon Co USA of Houston has been +awarded a 99.2 mln dlr contract for jet fuel, the Defense +Logistics Agency said. + Reuter + + + +24-MAR-1987 16:12:45.97 + +usa + + + + + +F +f2456reute +u f BC-EATON-(ETN)-GETS-53.0 03-24 0035 + +EATON (ETN) GETS 53.0 MLN DLR CONTRACT + WASHINGTON, March 24 - Eaton Corp's AIL Division has +received a 53.0 mln dlr contract for jamming system work for +the EA-6B electronic warfare aircraft, the Navy said. + Reuter + + + +24-MAR-1987 16:12:53.77 +grainrice +usazaire + + + + + +C G +f2457reute +u f BC-ZAIRE-AUTHORIZED-TO-B 03-24 0077 + +ZAIRE AUTHORIZED TO BUY PL 480 RICE - USDA + WASHINGTON, March 24 - Zaire has been authorized to +purchase about 30,000 tonnes of U.S. rice under an existing PL +480 agreement, the U.S. Agriculture Department said. + It may buy the rice, valued at 5.5 mln dlrs, between March +31 and August 31, 1987, and ship it from U.S. ports by +September 30, the department said. + The purchase authorization covers the entire quantity of +rice provided under the agreement. + Reuter + + + +24-MAR-1987 16:13:26.14 + +usa + + + + + +F +f2459reute +u f BC-MCDONNELL-DOUGLAS-GET 03-24 0036 + +MCDONNELL DOUGLAS GETS 30.6 MLN DLR CONTRACT + WASHINGTON, March 24 - McDonnell Douglas Corp (MD) has +received a 30.6 mln dlr contract for work on development of the +standoff land attack missile (SLAM), the Navy said. + REUTER + + + +24-MAR-1987 16:15:17.01 +acq +usa + + + + + +F +f2463reute +r f BC-MIDIVEST-ACQUIRES-ASS 03-24 0080 + +MIDIVEST ACQUIRES ASSETS OF BUSINESS AVIATION + ROANOKE, Va., March 24 - <Midivest Inc> said it acquired +all the assets of <Business Aviation Inc> of Sioux Falls, S.D., +for an undisclosed amount of stock. + Midivest said it expects to sell 10 to 20 of the renovated +Beechcraft planes next year. It said management will also lease +these airborne intensive care units to hospitals and government +subdivisions through Metropolitan Leasing, a wholly-owned +subsidiary of Midivest. + Reuter + + + +24-MAR-1987 16:15:59.31 +grainwheat +usajordan + + + + + +C G +f2464reute +u f BC-U.S.-WHEAT-CREDITS-FO 03-24 0113 + +U.S. WHEAT CREDITS FOR JORDAN SWITCHED + WASHINGTON, March 24 - The Commodity Credit Corporation +(CCC) has switched 25.0 mln dlrs in wheat credit guarantees to +Jordan under the Export Credit Guarantee Program to the +Intermediate Export Credit Guarantee Program, the U.S. +Agriculture Department said. + The switch reduces the total value of GSM-102 guarantees +for the current fiscal year to 30.0 mln dlrs. + The credit terms extended for export sales under the +Intermediate Export Credit Guarantee Program (GSM-103) must be +in excess of three years but not more than seven years. + All sales must be registered and exports completed by +September 30, 1987, the department said. + Reuter + + + +24-MAR-1987 16:17:44.35 +money-fxdlr +usajapanuk + + + + + +V RM +f2474reute +r f BC-DOLLAR-EXPECTED-TO-FA 03-24 0108 + +DOLLAR EXPECTED TO FALL DESPITE INTERVENTION + By Claire Miller, Reuters + NEW YORK, March 24 - Central bank intervention in the +foreign exchange markets succeeded in staunching the dollar's +losses today, but senior dealers here believe the U.S. currency +is headed for a further retreat. + Although the intervention was widespread, dealers perceive +that the six major industrial nations have differing levels of +commitment to their recent accord to stabilize currencies. + Moreover, hard economic realities hold greater sway over +the currency market than central bank intervention and these +argue for a further dollar decline, dealers said. + "The market can be bigger than the central banks. And +economic fundamentals will always come to the fore," said a +dealer at one major U.S. bank. + As the dollar dropped to post-World War II lows against the +yen today foreign exchange traders said the Bank of Japan, +Federal Reserve Board and Bank of England intervened in the +markets on behalf of the U.S. currency. + Reports of the authorities' actions helped the dollar +recover to about 149.45 yen in New York this afternoon from +the post-war low of 148.20 yen in the Far East. But it still +failed to regain Monday's U.S. closing level of 150.00/05 yen. + Tokyo dealers said the Bank of Japan bought one to 1.5 +billion dlrs in Tokyo today and may also have purchased dollars +yesterday in the U.S. via the Federal Reserve. + Meanwhile, there were strong rumors in New York that the +Fed also bought a modest amount of dollars around 148.50 yen +today. Talk also circulated that the Bank of England purchased +a small amount of dollars for yen. + The Fed's last confirmed intervention was on January 28 +when it bought 50 mln dlrs in coordination with the Bank of +Japan. But on March 11 the Fed also was rumored to have +signalled displeasure with a dollar surge above 1.87 marks. + The authorities' actions appeared to back up the February +22 Paris pact between the U.S., Japan, West Germany, Britain, +France and Canada under which the nations agreed to cooperate +to foster exchange rate stability around prevailing levels. + But foreign exchange dealers were not overly impressed by +the authorities' intervention which they said can only soften +extreme moves in the market. + For one thing, some dealers believed that the Fed's +purchases were done on behalf of the Bank of Japan rather than +for the U.S. central bank's own account, suggesting a rather +watered-down American commitment to the currency accord. + The Bank of England's action also was thought to be +completed on behalf of the Japanese central bank, reinforcing +the market's view that Japan is the most resolute of the six +nations in its support of the currency pact. + "No-one doubts the Bank of Japan is serious. But the other +two central banks seem to be making more token gestures than +anything else," said Chris Bourdain of BankAmerica Corp. + "I'm not convinced the intervention was concerted," said +Earl Johnson of Harris Trust and Savings Bank in Chicago. +"It's a yen problem more than anything else." + Some dealers said a rising wave of trade protectionist +sentiment in the U.S. limits the extent to which the American +authorities can endorse a stronger dollar against the yen. + "The dollar's break below the key 150 yen level ties the +Treasury's hands behind its back. The U.S. cannot intervene on +its own account because of the strength of protectionism here," +said Albert Soria of Swiss Bank Corp. + Such comments reflect the view that the currency markets +are becoming increasingly politicized. Despite official +denials, some traders still feel the U.S. would countenance a +lower dollar to help trim the nation's trade deficit. + The majority of the 170 billion dlr merchandise trade +deficit in 1986 was with Japan. + Indeed U.S. Treasury secretary James Baker's comment on +Sunday that the February currency pact had not established +dollar targets was read by the market as a signal to sell the +U.S. currency and kicked off the latest retreat. + "The dollar still has more room on the downside against the +yen based on the frictions in trade and financial services. The +currency market is becoming very political," said Natsuo Okada +of Sumitomo Bank Ltd. + Okada expects the dollar to trade between 148 and 150 yen +this week but sees the chance of a drop to 140 yen by the end +of April or early May. + Even if West Germany and Japan succeed in stimulating their +economies, it may not be enough to solve structural economic +imbalances in the near future, dealers said. + "Even if Japan and West Germany do expand this year, it +won't be enough to help the trade situation much," said +Bourdain of BankAmerica, who also expects the dollar to drop to +148 yen in the next couple of days. + Reuter + + + +24-MAR-1987 16:17:58.20 + +usa + + + + + +RM V +f2475reute +u f BC-/U.S.-TO-SELL-12.8-BI 03-24 0066 + +U.S. TO SELL 12.8 BILLION DLRS IN BILLS + WASHINGTON, March 24 - The U.S. Treasury said it will sell +12.8 billion dlrs of three and six-month bills at its regular +auction next week. + The March 30 sale, to be evenly divided between the three +and six month issues, will result in a paydown of 1.2 billion +dlrs as maturing bills total 13.99 billion dlrs. + The bills will be issued April 2. + Reuter + + + +24-MAR-1987 16:22:32.09 + +usa + + + + + +F +f2482reute +r f BC-INLAND-STEEL-<IAD>-TO 03-24 0081 + +INLAND STEEL <IAD> TO BUILD NEW PLANT IN INDIANA + SOUTH BEND, Ind., March 24 - Inland Steel Industries and +Governor Robert Orr of Indiana said the new joint venture cold- +rolled steel plant between Inland Steel and Nippon Steel Corp +will be built on a site in St. Joseph County Indiana. + Inland Steel said yesterday that the joint venture, to be +named I/N Tek, will cost more than 400 mln dlrs and will employ +over 200 people by the time the companies complete the project +in 1990. + Reuter + + + +24-MAR-1987 16:22:41.79 +acq +usa + + + + + +F +f2483reute +b f BC-******EASTMAN-KODAK-C 03-24 0093 + +EASTMAN KODAK <EK> TO SELL HOLDINGS + ROCHESTER, N.Y., March 24 - Eastman Kodak Co said it plans +to sell its 2.3 pct holding in ICN Pharmaceuticals <ICN> and +part of its nine pct holdings in Viratek <VIRA>. + It said the purpose of the investments had been to lay the +groundwork for the creation of its Nucleic Acid Research +Institute. + Since that has been achieved, there is no longer any reason +to maintain the equity positions, Kodak said. + Kodak holds 470,000 sahres of ICN, currently trading at +about 18-3/4 and 700,000 of Viratek, trading at 44. + Reuter + + + +24-MAR-1987 16:23:12.76 + +usa +boesky + + + + +F +f2485reute +u f BC-GUINNESS 03-24 0094 + +GUINNESS SUES BOESKY IN FEDERAL COURT + NEW YORK, March 24 - <Guinness PLC> has joined investors +suing former Wall Street speculator Ivan Boesky, alleging it +was deceived into putting money into his one billion dlr +investment partnership in 1986. + Guinness, the largest limited partner in Ivan F. Boeksy and +Co. L.P., is the latest to file suit in federal court in +Manhattan against Boesky, court papers show. + About 40 other investors have also filed suit over similar +allegations, including that Boesky did not reveal his illegal +insider trading activities. + Guinness is charging it was induced to join in the Boesky +partnership through a prospectus that contained "material untrue +statements and omissions." + The suit also alleged that the Boesky Corporation, which +became a part in the formation of the investment partnership, +Ivan F. Boesky and Co., L.P., "had achieved its extraordinary +rates of return as a result of trading on inside information +and other violations of the securities laws." + In addition, the suit charged that Boesky and other +defendants unlawfully "schemed with and provided substantial +assistance to one another to evade the registration provisions" +of securities law. + Reuter + + + +24-MAR-1987 16:23:23.82 +acq +usacanada + + + + + +F E +f2486reute +r f BC-FIRM-REDUCES-SCEPTRE 03-24 0078 + +FIRM REDUCES SCEPTRE RESOURCES <SRL> HOLDINGS + WASHINGTON, March 24 - Montreal-based Noverco Inc told the +Securities and Exchange Commission it reduced its stake in +Sceptre Resources Ltd to 1,232,200 shares or 4.8 pct of the +total outstanding. + Noverco said it sold off 400,500 shares "to reduce the +investment of Noverco in Sceptre." + "Additional common shares of Sceptre may be sold or +purchased by Noverco, depending upon market conditions," Noverco +said. + Reuter + + + +24-MAR-1987 16:23:35.03 + + + + + + + +F +f2487reute +b f BC-******GENCORP-BOARD-W 03-24 0011 + +******GENCORP BOARD WITHDRAWS PROPOSALS TO STAGGER DIRECTORS TERMS +Blah blah blah. + + + + + +24-MAR-1987 16:26:21.04 +earn +canada + + + + + +E +f2496reute +d f BC-<ACKLANDS-LTD>-1ST-QT 03-24 0029 + +<ACKLANDS LTD> 1ST QTR FEB 28 NET + TORONTO, March 24 - + Shr three cts vs 11 cts + Net 126,000 vs 434,000 + Revs 84.0 mln vs 80.2 mln + Avg shrs 4,948,731 vs 3,870,511 + Reuter + + + +24-MAR-1987 16:30:25.13 +earn +usa + + + + + +F +f2511reute +d f BC-BULL-AND-BEAR-GROUP-A 03-24 0078 + +BULL AND BEAR GROUP A <BNBGA> CUTS FUND PAYOUTS + NEW YORK, March 24 - Bull and Bear Group A said it lowered +its monthly dividends on three of its funds. + It said it lowered its Tax Free Income Fund <BLTFX> to 10.3 +cts from 10.6 cts; its U.S. Government Guaranteed Securities +Fund <BBUSX> to 11.5 cts from 11.8 cts; and its High Yield Fund +<BULHX> to 14 cts from 14.2 cts. + All dividends are payable March 31 to shareholders of +record March 25, the company said. + Reuter + + + +24-MAR-1987 16:30:42.93 +crude +usa + + + + + +Y +f2513reute +r f BC-CALTEX-TO-RAISE-BAHRA 03-24 0107 + +CALTEX TO RAISE BAHRAIN OIL PRODUCT PRICES + NEW YORK, March 24 - Caltex Petroleum Corp said it will +raise +posted prices for naphtha and several grades of residual fuel +in Bahrain, effective March 25. + Caltex, a joint venture of Chevron Corp <CHV> and Texaco +INC <TX>, said its naphtha posting is up four cts a gallon to +43 cts. It said it is raising its marine diesel oil posting by +30 cts a barrel to 20.24 dlrs a barrel. + Light, medium, and heavy fuel oil postings are up 1.50 dlrs +a barrel, the company said. This will bring the light fuel oil +price to 16.90 dlrs, medium to 15.50 dlrs, and heavy to 14.60 +dlrs, the company said. + Reuter + + + +24-MAR-1987 16:31:01.12 +pet-chem +usa + + + + + +F +f2515reute +u f BC-CHARTER-CO-<QCHR>-TO 03-24 0093 + +CHARTER CO <QCHR> TO COMPLETE REORGANIZATION + JACKSONVILLE, Fla., March 24 - Charter Co, the huge +petrochemical concern in bankruptcy proceedings stemming from +hundreds of dioxin-related claims, said it and all of its +subsidiaries, except the Independent Petrochemical Corp, will +complete their reorganization on March 31. + It said that on that date, it will deposit with an escrow +agent 288.8 mln dlrs in cash, 66.7 mln dlrs in notes and 31 mln +shares of its common for distribution. + Company officials were not immediately available for +comment. + As previously reported, Charter settled dioxin-related +claims for about 1,200 individuals and the state of Missouri, +resolving claims against it and all subsidiaries except +Independent Petrochemical. + Charter said some of the settlements remain subject to +appeals and final court approvals and resolve claims against +charter and its subsidiaries except Independent Petrochemical. + It said about 500 individual claims against it and certain +of its units remain pending as disputed claims in bankruptcy +court. It said about 300 of these claims have been filed since +confirmation of the joint plan of reorganization. + Charter said its two creditors, an equity committee in its +bankruptcy proceedings and <American Financial Corp>, which +will own 50.5 pct of its common after the reorganization, have +waived the requirement that Charter resolve all dioxin-related +claims against it prior to completing its reorganization. + That requirement excludes claims against Independent +Petrochemical. Charter also said a plan for liquidation of +Independent has been approved by the bankruptcy court and will +be completed after March 31. + Earlier, Charter reported net income for the year of 153.2 +mln dlrs, which included a gain of 28.5 mln dlrs for +discontinued operations and 114.8 mln dlrs for the settlement +of claims in its reorganization proceedings. + In 1985, it reported earnings of 1,274,000 dlrs, which +included a loss of 36.3 mln dlrs for discontinued operations +and 29.4 mln dlrs for extraordinary items. + For the fourth quarter, it reported earnings of 118.8 mln +dlrs, including a gain of 28.6 mln dlrs for discontinued +operations and 90.5 mln dlrs mainly for claims settlements. In +the year-ago period, Charter reported a loss of 13 mln dlrs. + Reuter + + + +24-MAR-1987 16:32:07.68 +acq +usa + + + + + +F +f2518reute +r f BC-NASHUA-<NSH>-TO-PURCH 03-24 0083 + +NASHUA <NSH> TO PURCHASE PRIVATE DISC MAKER + NASHUA, N.H., March 24 - Nashua Corp said it signed a +letter of intent to purchase <Lin Data Corp>, a private +manufacturer of high-capacity rigid discs for storage of +computer data. + Under the terms of the letter, Nashua said it will acquire +all classes of Lin stock for 24 mln dlrs. In addition, it said +it will loan Lin 1,200,000 dlrs to support its operations. + The closing of the sale is set for the second quarter of +1987, the company said. + Reuter + + + +24-MAR-1987 16:34:49.02 +earn +usa + + + + + +F +f2522reute +r f BC-ALTRON-INC-<ALRN>-4TH 03-24 0072 + +ALTRON INC <ALRN> 4TH QTR JAN 3 + WILMINGTON, Mass, March 24 - + Shr loss 56 cts vs loss five cts + Net loss 1.9 mln vs loss 164,000 + revs 6.9 mln vs 5.4 mln + Year + Shr loss 1.15 dlrs vs profit 52 cts + Net loss 3.8 mln vs profit 1.7 mln + Revs 25.6 mln vs 29.8 mln + NOTE: 1987 net loss includes loss 6.5 mln dlrs for +nonrecurring reserve for closing costs of facility, writeoffs +and sales of real estate. + + Reuter + + + +24-MAR-1987 16:38:19.15 + +usa + + + + + +F +f2534reute +r f BC-COLLINS-FOODS-<CF>-MO 03-24 0077 + +COLLINS FOODS <CF> MOVES UP WARRANT CONVERSION + LOS ANGELES, March 24 - Collins Foods International Inc +said it moved up the conversion date for its warrants to +purchase common stock to April 24. + There are currently 2,160,000 warrants outstanding, the +company said. It said each warrant entitles the holder to buy +one Collins common share at 12.11 dlrs per share. + Collins also said the warrants were originally scheduled to +expire on December 15, 1988. + But the agreement under which the warrants were issued +permits the company to accelerate the date if the closing price +of its common stock equals or exceeds 21.78 dlrs per share for +10 consecutive trading days, the company said. + It also pointed out that the stock price closed at 22.75 +dlrs per share on March 23. + Reuter + + + +24-MAR-1987 16:38:34.38 +earnacq +usa + + + + + +F +f2535reute +u f BC-GENCORP-<GY>-PROPOSAL 03-24 0098 + +GENCORP <GY> PROPOSALS WITHDRAWN FROM MEETING + AKRON, Ohio, March 24 - GenCorp Inc said it withdrew from +consideration at its annual meeting on March 31 proposals aimed +at providing for a stock split and an increased dividend so +that it could focus its energies on responding to the takeover +offer made last week by a partnership of AFG Industries Inc +<AFG> and Wagner and Brown. + In addition to proposing an increase in the number of its +outstanding common shares, GenCorp had suggested the adoption +of a classified or "staggered" board and the elimination of +cumulative voting. + GenCorp said these proposals could "distract energy and +attention from the real task at hand -- to respond to the +tender offer in a manner which is in the best interests of the +company, its shareholders and its other constituencies." + GenCorp said the proposal to increase its outstanding +shares was made with the aim of declaring a stock split and a +dividend increase. + The other proposals, it said, would provide for greater +long-term stability and cohesiveness for the GenCorp board. + The company did not indicate when it might resubmit the +proposals for approval by its shareholders. + Reuter + + + +24-MAR-1987 16:39:39.76 + +usa + + + + + +Y +f2540reute +r f BC-WEEKLY-ELECTRIC-OUTPU 03-24 0073 + +WEEKLY ELECTRIC OUTPUT UP 2.4 PCT FROM 1986 + WASHINGTON, March 24 - U.S. power companies generated a net +47.47 billion kilowatt-hours of electrical energy in the week +ended March 21, up 2.4 pct from 46.36 billion a year earlier, +the Edison Electric Institute (EEI) said. + In its weekly report on electric output, the electric +utility trade association said electric output in the week +ended March 14 was 48.31 billion kilowatt-hours. + The EEI said power production in the 52 weeks ended March +21 was 2,557.44 billion kilowatt hours, up 2.1 pct from the +year-ago period. + Electric output so far this year was 602.26 billion +kilowatt hours, up 2.2 pct from 589.51 billion last year, the +EEI said. + Reuter + + + +24-MAR-1987 16:40:00.41 + +usa + + + + + +F +f2541reute +r f BC-MONOLITHIC-<MMIC>-TO 03-24 0096 + +MONOLITHIC <MMIC> TO DROP GATE ARRAY LINE + SANTA CLARA, Calif., March 24 - Monolithic Memories Inc +said it plans to discontinue marketing its gate array +integrated circuit product line and focus efforts on the market +for field-programmable products. + It said the current market dynamics will hinder +profitability in the gate array market for some time. + Monolithic also said it does not expect the move to have a +negative impact on earnings, adding, the company has estimated +that the gate array products would have contributed only one +pct of revenues in fiscal 1987. + Reuter + + + +24-MAR-1987 16:40:32.83 +crudegas + + + + + + +Y +f2543reute +u f BC-******API-SAYS-DISTIL 03-24 0015 + +******API SAYS DISTILLATE STOCKS OFF 4.07 MLN BBLS, GASOLINE OFF 2.69 MLN, CRUDE UP 8.53 MLN +Blah blah blah. + + + + + +24-MAR-1987 16:41:16.33 +earn +usa + + + + + +F +f2547reute +r f BC-VERMONT-FINANCIAL-SER 03-24 0038 + +VERMONT FINANCIAL SERVICES <VFSC> SETS PAYOUT + BRATTLEBORO, Vermont, March 24 - Vermont Financial Services +Corp said its board approved a regular 20 cts per share cash +dividend payable April 25 to shareholders of record March 26. + Reuter + + + +24-MAR-1987 16:41:51.89 +acq + + + + + + +F +f2551reute +f f BC-******RESORTS-INTERNA 03-24 0011 + +******RESORTS INTERNATIONAL GETS BUYOUT PROPOSAL FROM KSZ CO INC +Blah blah blah. + + + + + +24-MAR-1987 16:42:09.41 + +usa + + + + + +F +f2554reute +d f BC-VR-BUSINESS-BROKERS-E 03-24 0073 + +VR BUSINESS BROKERS EXPANDS OPERATIONS + BOSTON, March 24 - <VR Business Brokers> said it sold a +master franchise license to one of the largest independent +groups of management consultants in the Caribbean. + It said that under the master license the group will +operate under the name VR Caribbean Inc and will cover +countries of the Caribbean basin and Central America and Dade +County, Fla. + Terms of the sale were not disclosed. + Reuter + + + +24-MAR-1987 16:42:29.98 + +usa + + + + + +F +f2556reute +u f BC-CORRECTED---ATT-<T>-F 03-24 0112 + +CORRECTED - ATT <T> FORMS COMPUTER SALES GROUPS + NEW YORK, March 24 - American Telephone and Telegraph Co +said it formed a 600-member sales force dedicated exclusively +to its computers and other data systems products. + Separately, ATT denied reports that it plans to buy back a +large chunk of its stock. ATT's stock is up 1/4 points at +25-1/8 in heavy trading. + The company said it also created a separate 500-member team +that will educate the computer sales force and its other sales +groups on ATT's computer products. This group, ATT said, +reports directly to Vittorio Cassoni, senior vice president of +its computer unit. (Corrects sales support team size to 500) + +REUTER + + + +24-MAR-1987 16:44:02.04 +earn +usa + + + + + +F +f2558reute +s f BC-GREAT-ATLANTIC-AND-PA 03-24 0024 + +GREAT ATLANTIC AND PACIFIC TEA CO INC <GAP> DIV + NEW YORK, March 24 - + Qtly div 10 cts vs 10 cts prior + Payable May one + Record April 15 + Reuter + + + +24-MAR-1987 16:44:47.92 +acq +usa + + + + + +F +f2559reute +d f BC-GARTNER-GROUP-<GART> 03-24 0077 + +GARTNER GROUP <GART> ACQUIRES COMTEC PROGRAM + STAMFORD, Conn., March 24 - Gartner Group Inc said it +acquired sole ownership of the COMTEC Market Research Program. + Gartner said its wholly-owned subsidiary purchased the +interests of its former partners for an aggregate price of +1,125,000 plus a percentage of net sales proceeds on future +sales of certain products. + Prior to the acquisition, Gartner Group owned one-third in +the COMTEC partnership, it said. + Reuter + + + +24-MAR-1987 16:48:46.78 + +usa + + + + + +F +f2569reute +r f BC-U.S.-CAR-SALES-DOWN-3 03-24 0117 + +U.S. CAR SALES DOWN 3.9 PCT IN MID-MARCH + Detroit, March 24 - Sales of U.S.-made cars during +mid-March, the traditional start of the spring selling season, +dropped 3.9 pct behind last year's level, analysts say. + Automakers sold about 204,000 cars in the March 11-20 +selling period, 10,000 fewer than last year. Analysts said the +decline may auger poorly for the rest of the spring season. + Buyers shied away from the showrooms of American Motors +Corp <AMO>, the target of a 1.5 billion dlr takeover bid from +Chrysler Corp <C>. Analysts said consumers were anxious about +the whether Chrysler will retain some American Motors models, +causing a 62 pct drop in American Motors sales in mid-March. + Chrysler's mid-March sales fell 3.6 pct. + "During the spring selling season, you usually look for +some kind of seasonal uplift in sales. It doesn't look like +it's happening," said Joseph Philippi, analyst with E.F. Hutton +and Co. + "There may be less bloom to the spring selling season this +year than last," one auto company official conceded. + General Motors Corp <GM>, still working to regain consumer +interest in its cars, led the drop with a 14.8 pct decline. + Ford Motor Co's <F> sales increased 15.2 pct for the +period. But analysts said the rise compares to a 1986 period +for Ford, leaving it down 10 pct in two years. + "The total industry (mid-March sales) was slightly less +than expected," the company official said. + American Motors' decline caught analysts eye. "American +Motors took it on the chin--big," said Philippi. + Given the prospective takeover by Chrysler, "people might +be a little leary about going to (American Motors) dealers," he +said. + American Motors sold 790 domestic cars in the period, +meaning each of American Motors 1,050 dealers "is selling a car +about every other day," Philippi said. + Potential American Motors buyers are afraid their car +models "might disappear," he said. + Chrysler, in its purchase agreement with American Motors' +majority stockholder <Renault>, has agreed not to undercut +sales of American Motors' new Medallion and Premier cars, made +by Renault. + On a company by company basis, sales of U.S. made cars from +the March 11 to 20 period were--GM 105,438, down 14.8 pct, Ford +67,672, up 15.2 pct, Chrysler 30,909, down 3.6 pct, American +Motors 790, down 6.2 pct, American Honda 7,447 compared with +5,031, Nissan Motor Corp, 3,358, up 10.7 pct, Volkswagon U.S. +Inc 1,330, down 35 pct. + Reuter + + + +24-MAR-1987 16:54:19.43 +acq +usa + + + + + +F +f2583reute +u f BC-RESORTS-INT'L-<RT.A> 03-24 0079 + +RESORTS INT'L <RT.A> RECEIVES TAKEOVER OFFER + ATLANTIC CITY, N.J., March 24 - Resorts International Inc +said it received a proposal from <KSZ Co Inc> under which +holders of Resorts class B stock would receive 140 dlrs a share +in cash and one share of common stock in a new company to be +formed through the takeover. + Under the offer, Resorts said holders of its class A shares +would receive 15 dlrs a share in cash and three shares of +common stock in the new company. + Resorts said the offer from KSZ calls for a merger of +Resorts with RI Acquisition Co Inc, a newly formed Delaware +corporation. + Resorts said that prior to the merger, RI Acquisition would +be capitalized with about 100 mln dlrs of debt and about 220 +mln dlrs of equity. + It said 200 mln dlrs of the equity would be in the form of +special preferred stock. + The KSZ offer, Resorts said, indicates that KSZ has a +commitment from <M. Davies Cos> to buy all of the special +preferred stock. + Resorts said the offer will expire at 1700 EST on March 27. +It said it asked its investment advisor, Bear, Stearns and Co, +to advise its board on the offer. + Earlier this month, the estate of James M. Crosby and +certian members of his family agreed to sell their class B +shares to New York real estate tycoon Donald Trump for 135 dlrs +a share. The estate and family members hold 78 pct of the +752,297 class B shares outstanding. + Trump also agreed to pay 135 dlrs a share for the remaining +class B shares outstanding. + Resorts also has about 5,680,000 shares of outstanding +class A stock. These shares carry one one-hundredth the voting +power of the class B shares. + Trump's offer beat out a rival bid of 135 dlrs a share made +by Pratt Hotel Corp <PRAT>. + Resorts said that under the proposal made by KSZ, existing +class A and class B shareholders would control about 96 pct of +the outstanding common of the new company formed to acquire +Resorts. + Resorts said the new company, upon completion of the +merger, would hold the 220 mln dlrs of debt and that the +special preferred stock would immediately be converted into +exchangeable participating preferred of the new company. + This preferred, Resorts said, would pay a dividend based on +the net cash flows from the new company's Paradise Island +operations. + A Resorts spokesman said the KSZ offer was made in a +two-page letter and that Resorts could not comment on it +because it did not contain enough information. Resorts has +asked Bear, Sterns to obtain complete data, he said. + The spokesman said Resorts is not familiar with KSZ but +that it believes the company is controlled by Marvin Davis, the +Denver oilman. + Calls to Davis were referred to Lee Solters, who handles +public relations for Davis. Solters, said to be travelling, was +not immediately available for comment. + Donald Trump was also unavailable for comment, as was a +spokesman for the Crosby estate. + Reuter + + + +24-MAR-1987 16:56:59.34 +earn +usa + + + + + +A F RM +f2588reute +r f BC-CITICORP-<CCI>-SEES-D 03-24 0111 + +CITICORP <CCI> SEES DOUBLING IN RETAIL BANK NET + NEW YORK, March 24 - Citicorp expects net income in its +individual banking sector to top one billion dlrs by 1993, +compared with 462 mln dlrs in 1986, said Richard Braddock, head +of Citicorp's individual banking division. + "We can double our earnings over the next five to seven +years," he told a banking analysts meeting, adding that this +forecast may be on the conservative side. + He said that bank card operations and the New York branch +system would continue to turn in hefty profits but also picked +out other developing areas, such as U.S. mortgage and +international consumer, as major potential earners. + Braddock and his sector heads made the following more +specific predictions: + - Cost of funds and net credit loss levels in the U.S. +bankcard unit will taper off in coming years from 1986's +relatively inflated levels. + - Customer net revenue in the mortgage banking area will +rise to 464.7 mln dlrs in 1987 from 374.3 mln in 1986. + - The international consumer business will show 22 pct +compound annual growth in earnings between 1986 and 1992. + - Private banking earnings will hit 100 mln dlrs in 1987 +and top 200 mln dlrs in 1992. + Reuter + + + +24-MAR-1987 16:58:33.67 +earn +usa + + + + + +F +f2593reute +d f BC-WD-40-CO-<WDFC>-2ND-Q 03-24 0042 + +WD-40 CO <WDFC> 2ND QTR FEB 28 NET + SAN DIEGO, Calif., March 24 - + Shr 35 cts vs 40 cts + Net 2,642,000 vs 3,017,000 + Sales 19.1 mln vs 18.9 mln + Six Mths + Shr 69 cts vs 70 cts + Net 5,178,000 vs 5,299,000 + Sales 35.6 mln vs 33.8 mln + Reuter + + + +24-MAR-1987 16:59:02.01 + +usa + + +nasdaq + + +F +f2594reute +u f BC-NASD-TO-BEGIN-SEARCH 03-24 0105 + +NASD TO BEGIN SEARCH FOR NEW PRESIDENT + NEW YORK, March 24 - The National Association of Securities +Dealers, which will launch a search for a new president later +this week, will probably concentrate on candidates with an +extensive background in the financial markets, officials of the +organization said today. + Gordon Macklin, 58, who has served as president for 17 +years, today announced his decision to leave the organization +of 6,658 broker-dealers. Macklin will join Hambrecht and Quist +as chairman and co-chief executive officer. + Association chairman Joseph Hardiman will appoint a search +committee later this week. + The committee will have its first meeting as early as next +week. The new president is expected to be someone knowledgable +about the over-the-counter markets and committed to the concept +of self-regulation. + Macklin joined the association as president in 1970, +leaving a position at McDonald and Co. + The National Association of Securities Dealers Automated +Quotations System, which currently lists 5200 securities of +4400 companies, was ushered in 10 months after Macklin's +arrival. + Reuter + + + +24-MAR-1987 17:00:51.46 +trade +brazilusa + + + + + +C G L M T +f2599reute +d f AM-BRAZIL-COMPUTER 03-24 0136 + +BRAZIL COMPUTER MARKET TO REMAIN CLOSED-MINISTER + RIO DE JANEIRO, MARCH 24 - Brazilian Science and Technology +Minister Renato Archer said Brazil will keep its computer +market closed to foreign goods in order to give its own infant +industry time to develop. + "Every country establishes laws to protect its interests. +The United States closed their borders at a certain stage to +some foreign goods and therefore protected its industrial +development. Now it is time for Brazil to do likewise," Archer +said at the opening of a national software conference. + After several meetings, Brazil and the U.S. Have made no +major progress in their computer row, which they have been +trying to resolve for the past 18 months. + The Reagan administration has objected to Brazil protecting +its computer industry from imports. + Reuter + + + +24-MAR-1987 17:02:09.20 + +usa + + + + + +F +f2603reute +d f BC-METALBANC-IN-OFFERING 03-24 0053 + +METALBANC IN OFFERING + MIAMI, March 24 - Metalbanc Corp said signed a letter of +intent for a proposed public offering of one mln units, +consisting of four shares of common stock and stock purchase +warrants for two additional shares. + The units are expected to be sold at between five dlrs and +6.50 dlrs per unit. + Reuter + + + +24-MAR-1987 17:03:05.68 +earn +usa + + + + + +F +f2608reute +d f BC-NORTHERN-INDIANA-PUBL 03-24 0071 + +NORTHERN INDIANA PUBLIC SVC <NI> AGAIN OMITS DIV + HAMMIND, Ind., March 24 - Northern Indiana Public Service +Company said it again omitted its quarterly common stock +dividend which would have been payable in May. + NIPSCO said it has not paid a qtly dividend since December +1985 following an adverse decision by the Indiana Supreme Court +denying amortization of about 191 mln dlrs NIPSCO invested in +its Bailly N-1 project. + Reuter + + + +24-MAR-1987 17:03:18.88 +money-fxdlr + + + + + + +A RM +f2610reute +f f BC-******FED'S-JOHNSON-S 03-24 0013 + +******FED'S JOHNSON SAYS DOLLAR STABILIZED AFTER FED TOOK APPROPRIATE ACTION +Blah blah blah. + + + + + +24-MAR-1987 17:05:30.74 +money-fxtrade +usajapan +volcker + + + + +A RM +f2612reute +r f BC-FED-CHAIRMAN-VOLCKER 03-24 0108 + +FED CHAIRMAN VOLCKER SAYS BANK PROPOSALS A WORRY + WASHINGTON, March 24 - The chairman of the Federal Reserve +Board, Paul Volcker, has written to the chairman of the House +Banking Committee to raise concerns about legislative proposals +scheduled for consideration Wednesday. + Volcker told committee chairman Fernand St. Germain a +proposal to deny primary dealer status to firms from countries +that do not grant U.S. firms equal access to their government +debt markets might invite retaliation against U.S. firms +abroad. + He added, "even Japan, against whom this proposal seems to +be particularly directed," has started opening its markets. + In his letter, made available at the Treasury, Volcker also +said a proposal to ease debt problems of developing countries +by setting up a public facility to buy their debts owed to +commercial banks, was a problem. + "I believe that the prospect of debt relief would undermine +the difficult internal efforts of the borrowing countries to +achieve the structural reform that is needed regardless of the +policies that are followed on servicing external debt," Volcker +said. + It might also cause private lenders to become reluctant to +extend more credit to the borrowing countries, he said. + Volcker said he endorsed comments by Treasury Secretary +James Baker "about the inappropriateness of using public +resources for purchasing private commercial bank debt, which we +both see as an inherent aspect of the proposed international +debt facility." + He also said a proposal for establishing formal procedures +for international negotiations on currency exchange rates "is +unrealistic and could well have damaging effects." + "For example, the bill's directive to intitiate negotiations +in order to achieve a competitive exchange rate for the dollar +-- a matter upon which there can be considerable difference +among analysts -- runs the risk of building up potentially +destabilizing market expectations," Volcker said. + He recommended "we should not lock ourselves into formalized +procedures for international negotiations" on exchange rates but +instead use other, more flexible means like the recent mmeting +in Paris between U.S. treasury and central bank representatives +and those of major trade allies. + Reuter + + + +24-MAR-1987 17:08:30.83 +earn +usa + + + + + +F +f2615reute +s f BC-BORMAN'S-INC-<BRF>-DE 03-24 0024 + +BORMAN'S INC <BRF> DECLARES QTLY DIVIDEND + DETROIT, Mich., March 24 - + Qtly div five cts vs five cts prior + Pay June 15 + Record May 18 + Reuter + + + +24-MAR-1987 17:08:39.15 + +usa + + + + + +F +f2616reute +r f BC-INTERLEUKIN-2-<ILTO> 03-24 0057 + +INTERLEUKIN-2 <ILTO> DETAILS WARRANT CONVERSION + WASHINGTON, March 24 - Interleukin-2 Inc said the +registration of warrants became effective March 20 and that 3.5 +mln warrants will be convertible into 1.75 mln shares of the +company's common stock, giving the company a maximum of 2.4 mln +dlrs. + The warrants must be exercised by June 22. + Reuter + + + +24-MAR-1987 17:10:19.66 +graincornoilseedsoybean +usa + + + + + +C G +f2618reute +u f BC-/U.S.-CORN-ACREAGE-SE 03-24 0134 + +U.S. CORN ACREAGE SEEN NEAR RECORD LOW + by Maggie McNeil, Reuters + WASHINGTON, March 24 - U.S. corn acreage this year is +likely to drop to the lowest level since the unsurpassed +acreage reductions of the 1983 PIK year and could rank as one +of the lowest corn plantings in the United States in sixty +years, Agriculture Department officials said. + USDA releases its official plantings report on March 31. +Agriculture Department analysts said next week's figures will +likely show a sharp drop in acreage to as low as 65 mln acres, +down 22 pct from last year's plantings of 83.3 mln acres. + Assuming an 18 mln acre drop in plantings, U.S. corn +production will also decrease significantly. Analysts said 1987 +corn production could drop by over one billion bushels to +around seven billion bushels. + Expected signup of up to 90 pct in the 1987 feed grains +program, along with 1.9 mln acres enrolled in the conservation +program, will cause acreage to plummet, Department feedgrain +analysts said. + "There's no question that there will be a sharp decrease in +corn acreage," one said. "It's difficult for any farmer to not +go along with the program this year." + Soybean acreage is also expected to decline this year but +at a much slower rate of around four pct, USDA analysts said. + Soybean plantings could drop to 59 mln acres or below, they +said, compared to last year's level of 61.5 mln acres. + If analysts' unofficial estimates prove correct then the +drop in u.s. corn acreage will be the largest since 1983 when +farmers idled 22 mln acres in the Payment-In-Kind program. + Farmers planted only around 60 mln acres of corn in 1983. A +severe drought that summer in major producing states caused +yields to tumble and final crop production to total only 4.2 +billion bushels. + Given normal weather conditions this year, USDA analysts +said the 1987 corn crop could end up around seven billion +bushels, down from last year's crop of 8.3 billion bushels. + "This kind of acreage reduction will mean a significant +reduction in production," an analyst said. + A crop of seven billion bushels is close to the annual U.S. +corn usage, so surplus stocks, while not decreasing, would not +increase significantly, a specialist said. + High producing corn belt states are expected to show the +greatest acreage reductions, based upon historical +participation in government programs, analysts said. + In contrast, soybean acreage is likely to be cut the most +in marginal producing areas of the southeast and the western +corn belt, a USDA soybean analyst said. + "Soybean acreage in the eastern corn belt will not budge," +he said. Neither does he expect any significant acreage cuts in +higher-producing delta areas. + Soybean production could drop fractionally from last year's +2.0 billion bushels to 1.8 to 1.9 billion, he said. + U.S. soybean acreage, after soaring to 71.4 mln acres in +1979 from only 52 mln acres five years prior to that, has +steadily declined in the 1980's. + U.S. corn acreage, with the exception of 1983, has been in +the low to mid 80-mln acre range for the past 10 years. The +highest corn plantings reported in the 60 years that USDA has +kept such records was in 1932 when farmers planted 113 mln +acres and obtained average yields of 26.5 bushels per acre. + Last year U.S. farmers obtained record corn yields +averaging 119.3 bushels per acre. + "We have absolutely no trouble producing an eight billion +bushel crop on only 80 mln acres or so," an analyst said. + Corn acreage will probably level at around 65 mln acres as +long as government program provisions remain the same, analysts +said. + Currently farmers enrolling in the program are required to +set aside 20 pct of their base acreage and then are eligible +for payments of two dlrs per bushel by idling an additional 15 +pct of their acreage. + "To get to the PIK level of 60 mln acres, we would have to +provide more incentives," an analyst said. + Reuter + + + +24-MAR-1987 17:10:32.59 +acq +usa + + + + + +F +f2620reute +r f BC-KIRSCHNER-<KMDC>-COMP 03-24 0065 + +KIRSCHNER <KMDC> COMPLETES PURCHASE + TIMONIUM, Md., March 24 - Kirschner Medical corp said it +completed the acquisition of Minnesota Mining and +Manufacturing's <MMM> orthopedic metal implant line division. + The acquisition price is 12.0 mln dlrs in cash, a six mln +dlr three year note and 100,000 shares of Kirschner common +stock. + The division had sales of 11.3 mln dlrs in 1986. + Reuter + + + +24-MAR-1987 17:10:45.15 +tradehogcarcasslivestock +usaussr + + + + + +C G L +f2621reute +r f BC-U.S.-SENATORS-SEEK-TO 03-24 0126 + +U.S. SENATORS SEEK TO EXPAND USDA EXPORT BONUS + WASHINGTON, March 24 - Leading U.S. farm state senators are +seeking to insert into the Senate's omnibus trade bill a +provision that would broaden eligibility requirements under the +U.S. Agriculture Department's export enhancement program, EEP, +to include traditional buyers of U.S. farm products, including +the Soviet Union, Senate staff said. + Under existing criteria, USDA can offer EEP subsidies to +recoup export markets lost to competing nations' unfair trading +practices. + Senate Agriculture Committee Chairman Patrick Leahy (D-Vt.) +is leading a group of farm state senators in an effort to +broaden the criteria in such a way as to enable Moscow to be +eligible for the subsidies, sources said. + The senators -- including Senate Finance Committee Chairman +Lloyd Bentsen (D-Tex.), Max Baucus (D-Mont.), David Pryor +(D-Ark.), John Melcher (D-Mont.) and Thad Cochran (R-Miss.) -- +also may fold into the trade bill a measure to shield pork +producers and processors from Canadian imports. + The measure, sponsored by Sen. Charles Grassley (R-Iowa), +would clarify the definition of "industry" in determining whether +or not imports were causing injury to U.S. producers. + Grassley's bill stems from a 1985 decision by the +International Trade Commission that imports from Canada of live +swine -- but not fresh, chilled and frozen pork -- were harming +U.S. producers. + The bill's proponents have argued Canada has simply +replaced shipments of live hogs with fresh pork. + Reuter + + + +24-MAR-1987 17:11:15.09 +money-fxdlr +usa + + + + + +A RM +f2623reute +b f BC-/FED'S-JOHNSON-SAYS-F 03-24 0088 + +FED'S JOHNSON SAYS FED ACTED TO STABILIZE DOLLAR + WASHINGTON, March 24 - Federal Reserve Board Vice Chairman +Manuel Johnson said the dollar has stabilized against other +currencies after action taken by the Fed. + "We have taken the appropriate action and the dollar has +stabilized," Johnson said after testifying to a House Banking +subcommittee. + He did not elaborate on the nature of the action nor when +it was taken, but said that it was in the spirit of the +agreement reached by six industrial nations in Paris recently. + Johnson said the dollar's decline against other currencies +such as the Japanese yen has been gradual. + Since the accord by the United States, Britain, West +Germany, Japan, France and Canada, foreign exchange markets +have been closely watching for indications of intervention by +central banks to determine the committment by those nations to +their agreement. + The nations agreed that currency exchange rates were at +about the correct levels when the pact was signed earlier this +year. + Reuter + + + +24-MAR-1987 17:11:23.20 + +usa + + + + + +F +f2624reute +r f BC-XOMA-<XOMA>-FILES-FOR 03-24 0098 + +XOMA <XOMA> FILES FOR PUBLIC OFFERING + BERKELEY, Calif., March 24 - Xoma Corp said it filed a +registration statement with the Securities and Exchange +Commission covering a proposed public offering of 1.3 mln +common shares. + Xoma, a biotechnology company which produces monoclonal +antibody-based products to treat some forms of cancer, said +proceeds will be used to fund research and product development, +human clinical trials and the expansion of manufacturing +capacity and working capital. + It said Dillon Read and Co Inc and Alex Brown and Sons Inc +will manage the underwriting. + Reuter + + + +24-MAR-1987 17:12:51.35 + +usa + + + + + +F +f2625reute +r f BC-REPUBLIC-AMERICAN-<RA 03-24 0088 + +REPUBLIC AMERICAN <RAWC> PLANS EXCHANGE OFFER + ENCINO, Calif., March 24 - Republic American Corp said it +began an offer to exchange a new issue of 9-1/2 pct +subordinated debentures due 2002 for a portion of its common +stock. + Republic said it is offering to acquire its stock at a rate +of 17.50 dlrs principal amount of debentures per common share. + The offering, which expires on April 27 unless extended, is +for up to 2,250,000 shares, with the company reserving the +right to accept three mln shares, Republic also said. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-010.sgm b/src/test/data/reuters-21578/reut2-010.sgm new file mode 100644 index 00000000000..04227d866b2 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-010.sgm @@ -0,0 +1,2002 @@ + + +26-MAR-1987 12:12:57.76 + +usa + + + + + +F +f1727reute +d f BC-AMOCO-<AN>-UNIT-EXPAN 03-26 0094 + +AMOCO <AN> UNIT EXPANDS CARPET YARN PLANT + CHICAGO, March 26 - Amoco Corp said its Amoco Fabrics Co +will expand the capacity of its polypropylene carpet face yarn +facility by 55 pct to support its successful penetration of the +commercial and residential carpet markets. + It said the expansion of the plant in Andalusia, Ala., will +bring Amoco's total face yarn capacity to nearly 140 mln pounds +a year, with Andalusia capacity at 85 mln pounds. + Amoco Fabrics is part of Amoco Chemicals Co, the chemical +manufacturing and marketing subsidiary of Amoco Corp. + Reuter + + + +26-MAR-1987 12:13:39.63 +earn +usa + + + + + +E F +f1730reute +d f BC-island-telephone 03-26 0038 + +ISLAND TELEPHONE SHARE SPLIT APPROVED + CHARLOTTETOWN, Prince Edward Island, March 26 - <Island +Telephone Co Ltd> said the previously announced two-for-one +common share split was approved by shareholders at the annual +meeting. + Reuter + + + +26-MAR-1987 12:15:35.31 + +usaukswitzerlandbelgiumluxembourg + + + + + +F +f1735reute +r f BC-BIOGEN-<BGNF>-GETS-PA 03-26 0103 + +BIOGEN <BGNF> GETS PATENT FROM EUROPEAN OFFICE + CAMBRIDGE, Mass., March 26 - Biogen Inc said the European +Patent Office granted it a patent covering certain proteins +used to produce a hepatitis B vaccine through genetic +engineering techniques. + Robert Gottlieb, Biogen spokesman, said the company has +licensed the vaccine on a nonexclusive basis to <Wellcome PLC>, +the British pharmaceutical firm, and is discussing licensing +with other companies. + Biogen said the patent gives it the right to exclude others +from marketing hepatitis B vaccine in the 11 member countries +of the European Patent Convention. + Gottlieb said the company has also filed a patent in other +markets, including the U.S. The vaccine is in clinical tests. + Patents in the biotechnology field are particularly +important as the company with an exclusive patent can reap +large rewards. Recently many of the products of genetic +engineering have become the target of patent lawsuits. + Merck and Co Inc <MRK> already sells a genetically +engineered hepatitis B vaccine in the U.S. called Recombivax +HB. A subsidiary of <SmithKline Beckman Corp>, SmithKline +Biologicals, based in Belgium, is selling a hepatitis B +vaccine, called Engerix-B, in Belgium. + A SmithKline spokesman said the vaccine has also been +formally approved in Switzerland and Luxembourg and has been +authorized for market in a number of Far East countries. + Hepatitis B is a serious liver infection common in many +parts of Africa and southeast Asia where about five pct to 15 +pct of the population carry the virus. In the U.S. about +200,000 new cases occur each year. + Last December the European Patent Ofice rejected Biogen's +patent for alpha-interferon, which Biogen said it will appeal +once it receives a formal written opinion from the office. + + Reuter + + + +26-MAR-1987 12:17:26.37 + +usa + + + + + +C +f1745reute +d f BC-KEY-HOUSE-MEMBER-OPPO 03-26 0113 + +KEY U.S. HOUSE MEMBER OPPOSES CFTC USER PLAN + WASHINGTON, March 26 - A key U.S. House member said he +opposed a Reagan administration plan to shift the cost of +surveillance of futures exchanges to the private sector. + "I just think user fees are the wrong way to attack a +problem of this sort," said Rep. Ed Jones (D-Tenn.), chairman +of the House Agriculture Subcommittee on Conservation, Credit +and Rural Development. + The White House budget office has asked the Commodity +Futures Trading Commission, CFTC, to draw up a plan for +transferring the three-mln dlr cost of monitoring futures +trading to either exchanges, futures commission merchants or +users of the markets. + CFTC Commissioner William Seale said the proposal was a +move in the wrong direction. "I would prefer to see +(surveillance) paid for through the appropriations process +rather than through taxation of market participants," he said. + CFTC Chairman Susan Phillips told the panel the commission +was preparing the proposal, due to be completed April 15, at +the request of the Office of Management and Budget. + Reuter + + + +26-MAR-1987 12:19:18.42 +tradeacq +ukjapan +thatcher + + + + +RM +f1749reute +u f BC-U.K.-GROWING-IMPATIEN 03-26 0119 + +U.K. GROWING IMPATIENT WITH JAPAN - THATCHER + LONDON, March 26 - Prime Minister Margaret Thatcher said +the U.K. Was growing more impatient with Japanese trade +barriers and warned that it would soon have new powers against +countries not offering reciprocal access to their markets. + She told Parliament that the bid by the U.K.'s Cable and +Wireless Plc <CAWL.L> to enter the Japanese telecommunications +market was being regarded by her government as a test case. + "I wrote to the prime minister of Japan, Mr Nakasone, on the +fourth of March to express our interest on the Cable and +Wireless bid. I have not yet had a reply. We see this as a test +on how open the Japanese market really is," Thatcher said. + Thatcher told Parliament that "shortly ... We shall have +more powers than we have now, when, for example the powers +under the Financial Services Act and the Banking Act become +available, then we shall be able to take action in cases where +other countries do not offer the same full access to financial +services as we do." + Cable and Wireless is seeking a stake in the proposed +Japanese telecommunications rival to Kokusai Denshin Denwa. + But the Japanese minister for post and telecommunications +was reported as saying that he opposed Cable and Wireless +having a managerial role in the new company. + REUTER + + + +26-MAR-1987 12:20:34.41 + +usa + + + + + +F +f1755reute +u f BC-GENCORP<GY>-TO-BUILD 03-26 0107 + +GENCORP<GY> TO BUILD 50 MLN DLR PLANT IN INDIANA + AKRON, Ohio, March 26 - GenCorp said it plans to build a 50 +mln dlr manufacturing facility in Shelbyville, Ind. + The company said it will begin building the plant, where it +will produce reinforced plastic components for cars and trucks, +this May with an expected completion date in mid-1988. + GenCorp said its DiversiTech General unit will operate the +plant through its reinforced plastics division. + "We believe the use of reinforced plastics in cars and +trucks will grow," A. William Reynolds, GenCorp chairman and +chief executive officer said as the reason for building the +plant. + "Our investment in the Shelbyville plant reflects the +confidence we have in the future of this product line," +Reynolds added. + GenCorp said the plant will create 500 new jobs. + Reuter + + + +26-MAR-1987 12:21:18.81 + +usa + + + + + +F +f1761reute +r f BC-JONES-INTERNATIONAL-R 03-26 0090 + +JONES INTERNATIONAL REALIGNS SUBSIDIARIES + ENGLEWOOD, Colo., March 26 - <Jones International Ltd> said +it realigned several subsidiaries to accommodate corporate +strategy. + Jones said ultimate control of the subsidiaries will remain +unchanged under the realignment. + Jones said it will exchange approximately 97 pct of its +holdings of the common stock of Jones Intercable Inc <JOIN> for +Class A common stock of Jones Spacelink Ltd <SPLK>. The company +said the move will enable Spacelink to elect 75 pct of +Intercable's directors. + In addition, Jones said 60 pct of the common stock of its +subsidiary, <The Jones Group Ltd>, will be exchanged for Class +A common stock of Jones Spacelink Ltd. + Following the exchange, Jones International's ownership of +Spacelink Class A voting stock will increase to approximately +89 pct. + Jones International said it will retain approximately two +pct of the common stock and approximately four pct of the Class +A common stock of Jones Intercable as well as the remaining 40 +pct of the Jones Group stock. + Reuter + + + +26-MAR-1987 12:21:42.19 +earn +usa + + + + + +F +f1764reute +d f BC-QUESTECH-INC-<QTEC>-Y 03-26 0062 + +QUESTECH INC <QTEC> YEAR NET + MCLEAN, Va., March 26 - + Shr loss nil vs profit 19 cts + Net loss 3,175 vs profit 284,945 + Revs 13.6 mln vs 10.6 mln + Year + Shr profit 13 cts vs profit 56 cts + Net profit 195,202 vs profit 857,006 + Revs 47.5 mln vs 42.9 mln + Note: Current year net includes charge against discontinued +operations of 1,060,848 dlrs. + Reuter + + + +26-MAR-1987 12:22:10.06 + +usa + + + + + +RM +f1766reute +u f BC-ASLK-CGER-FINANCE-ISS 03-26 0094 + +ASLK-CGER FINANCE ISSUES 10 BILLION YEN BOND + LONDON, March 26 - ASLK-CGER Finance NV is issuing a 10 +billion yen eurobond due April 10, 1994 with a 5-1/2 pct coupon +and priced at 101-1/2 pct, lead manager IBJ International Ltd +said. + The bonds are guaranteed by Belgian savings bank ASLK-CGER +Bank and have all been pre-placed. They will be issued in +denominations of one mln yen and listed in Luxembourg. + Fees comprise 5/8 pct for management and underwriting +combined, with a 1/8 pct praecipuum, and 1-1/4 pct for selling. +Pay date is April 10. + REUTER + + + +26-MAR-1987 12:23:03.99 + + + + + + + +F +f1768reute +f f BC-******UAW-STRIKES-GM 03-26 0009 + +******UAW STRIKES GM TRUCK AND BUS PLANT AT PONTIAC, MICH +Blah blah blah. + + + + + +26-MAR-1987 12:26:06.29 +crudenat-gas +canada + + + + + +E Y +f1773reute +u f BC-CANADA-OIL-EXPORTS-RI 03-26 0077 + +CANADA OIL EXPORTS RISE 20 PCT IN 1986 + OTTAWA, March 26 - Canadian oil exports rose 20 pct in 1986 +over the previous year to 33.96 mln cubic meters, while oil +imports soared 25.2 pct to 20.58 mln cubic meters, Statistics +Canada said. + Production, meanwhile, was unchanged from the previous year +at 91.09 mln cubic feet. + Natural gas exports plunged 19.4 pct to 21.09 billion cubic +meters, while Canadian sales slipped 4.1 pct to 48.09 billion +cubic meters. + The federal agency said that in December oil production +fell 4.0 pct to 7.73 mln cubic meters, while exports rose 5.2 +pct to 2.84 mln cubic meters and imports rose 12.3 pct to 2.1 +mln cubic meters. + Natural gas exports fell 16.3 pct in the month 2.51 billion +cubic meters and Canadian sales eased 10.2 pct to 5.25 billion +cubic meters. + Reuter + + + +26-MAR-1987 12:26:42.65 + +usa + + + + + +F +f1775reute +u f BC-PRU-BACHE-ANALYST-REA 03-26 0138 + +PRU BACHE ANALYST REAFFIRMS BULLISH MARKET CALL + NEW YORK, March 26 - Joseph Feshbach, chief market analyst +at Prudential-Bache Securities, said the stock market is poised +to climb above Dow Jones Industrial 2500 level by June. + The Dow average is around 2380 today. + "Liquidity is the biggest fundamental factor in the market +and money coming out of fixed income funds and flowing into +equities will propel the market sharply higher," Feshbach said, +noting that the market's peak will occur in June. + Feshbach said that in early January he predicted that the +Dow Jones Industrial average, the most closely watched market +barometer, would reach the 2400 level by April and the 2500 +level by June. He said he is now even more optimistic, saying +"the market is ready for a 150 point rise from current levels +any day now." + Reuter + + + +26-MAR-1987 12:27:23.14 + +uk + + + + + +RM +f1779reute +u f BC-LLOYD'S-APPOINTS-NEW 03-26 0117 + +LLOYD'S APPOINTS NEW OUTSIDE COUNCIL MEMBERS + LONDON, March 26 - Four new outsiders were appointed to the +policy-making Council of the Lloyd's of London insurance +market, shifting the voting balance on the Council away from +Lloyd's professionals, Lloyd's said. + It said in a statement the appointments of the new members, +none of them previously involved in the insurance market, were +made to comply with the core recommendation in the Neill report +into regulation at Lloyd's, which was published on January 22. + The recommendation, one of 70 to improve investor +protection in the Lloyd's market, was to reduce the number of +elected working members, Lloyd's professionals, from 16 to 12. + Simultaneously, the number of outsiders would be increased +by four while the number of external Council members, usually +Lloyd's investors without an active role in the market, would +remain unchanged at eight. + Lloyd's said the four newly-appointed Council members were +barrister Elizabeth Mary Freeman, Sir Maurice Hodgson, +non-executive chairman of British Home Stores Plc, Lloyd's Bank +Plc chairman Sir Jeremy Morse, and Brian Pomeroy, an accountant +who sat on the three-member Neill enquiry panel. + They replace the four Lloyd's professionals who resigned on +April 4 after Lloyd's agreed to implement the recommendation. + REUTER + + + +26-MAR-1987 12:27:45.45 +coffeecocoasugar + + + +nycsce + + +C T +f1783reute +d f BC-COFFEE,-SUGAR-AND-COC 03-26 0126 + +COFFEE, SUGAR AND COCOA EXCHANGE NAMES CHAIRMAN + NEW YORK, March 26 - The New York Coffee, Sugar and Cocoa +Exchange (CSCE) elected former first vice chairman Gerald +Clancy to a two-year term as chairman of the board of managers, +replacing previous chairman Howard Katz. + Katz, chairman since 1985, will remain a board member. + Clancy currently serves on the Exchange board of managers +as chairman of its appeals, executive, pension and political +action committees. + The CSCE also elected Charles Nastro, executive vice +president of Shearson Lehman Bros, as first vice chairman. +Anthony Maccia, vice president of Woodhouse, Drake and Carey, +was named second vice chairman, and Clifford Evans, president +of Demico Futures, was elected treasurer. + Reuter + + + +26-MAR-1987 12:28:11.69 +veg-oil +belgium + +ec + + + +C G +f1785reute +u f BC-MOST-EC-STATES-SAID-T 03-26 0121 + +MOST EC STATES SAID TO BE AGAINST OILS/FATS TAX + BRUSSELS, March 26 - A majority of European Community (EC) +member states are either against or have strong reservations +over a tax on both imported and domestically-produced oils and +fats proposed by the European Commission, senior diplomats +said. + They said a special committee of agricultural experts from +EC member states had voiced strong objections over the measure +during a meeting charged with preparing the ground for the +annual EC farm price-fixing which begins next Monday. + They added that only France and Italy had indicated they +would support the Commission proposal which would lead to a tax +initially of 330 Ecus per tonne during the 1987/88 price round. + Reuter + + + +26-MAR-1987 12:30:59.51 + +uk + + + + + +RM +f1797reute +u f BC-ROWNTREE-SEEKS-200-ML 03-26 0110 + +ROWNTREE SEEKS 200 MLN STG FACILITY, CP PROGRAM + LONDON, March 26 - Rowntree Mackintosh Plc is seeking a 200 +mln stg, five year multiple option facility, of which 150 mln +stg will be committed, and a 200 mln stg commercial paper +program, County Natwest Capital Markets Ltd said as arranger. + The facility includes options for sterling acceptances, +multi-currency advances, sterling and dollar notes via tender +panels and there is also a sterling swingline. + The committed portion carries a facility fee of five basis +points and a margin of ten. A 2-1/2 basis point utilisation +fee is payable on drawings of more than half the committed +portion. + The 200 mln stg commercial paper program will include a +dollar option, County Natwest said. + A County Natwest official said the facility, launched +earlier this week, seemed to be progressing well in +syndication. + REUTER + + + +26-MAR-1987 12:33:25.04 + +usa + + + + + +F +f1813reute +u f BC-TALKING-POINT/CONRAIL 03-26 0109 + +TALKING POINT/CONRAIL <CRR> + By Cal Mankowski, Reuters + NEW YORK, March 26 - Private investors eagerly snapped up +shares of Consolidated Rail Corp, the biggest initial stock +offering in U.S. history, but some analysts warned they could +be in a for a bumpy ride at least in the near term. + Analyst James Voytko of PaineWebber Group Inc believes some +investors who bought at the offering price of 28 dlrs will be +tempted to sell. The shares climbed 3-3/8 to 31-3/8 by midday. +Voytko said profit-taking pressure could become severe at the +35 dlr level. Others say Conrail, a combination of previously +bankrupt railroads, has good long term potential. + "Conrail is in the best position to weather the current +tremendous price competition in the transportation industry in +general," said Drew Robertson, analyst at Atlantic Systems Inc, +a research firm. + "It will survive and do damn well," said another analyst +who declined to be identified. He noted that Conrail's freight +trains serve heavy industry including steel and autos in major +U.S. cities in the northeast U.S. and midwest. + Robertson noted that Conrail's traffic is less dependent on +coal than other railroads based in the east. He expects Conrail +to earn 2.85 dlrs per share in 1987. + Voytko of PaineWebber sees another problem six months down +the road when more than 10 mln Conrail shares will be +distributed to current and former employees. He believes many +of these indivdiuals will be inclined to sell the stock. + Robertson says it's hard to determine the psychology of the +average employe, but even if a lot of stock is sold, it would +would not hit the market as one big block. He doubts it would +create a big downward push on the price. + "It's hard to call," said the analyst who requested +anonymity. In some cases employe loyalty may motivate +individuals to keep their shares, he said. + Steven Lewins, analyst for Citicorp Investment Management, +believes the key to Conrail's long term outlook is how it is +able to invest surplus cash. He expects Conrail to earn 3.00 +dlrs per share this year, flat in comparison with 1986, but by +1991 the picture could change dramatically if money not needed +for rail operations is invested wisely. + By 1991, earnings could reach 4.30 dlrs per share, Lewins +said, factoring in reinvestment of free cash flow at +conservative rates. + He believes motor freight will be one area of +diversification Conrail will explore. + Elizabeth Dole, U.S. Secretary of Transportation, whose +department was responsible for the sale of Conrail, noted that +Conrail is required to reinvest in its rail system and cannot +defer necessary maintenance. + For the historic offering of Conrail shares, Dole visited +the New York Stock Exchange and was photographed on the floor +wearing a locomotive engineer's cap, which she presented to +Stanley Crane, Conrail chairman and chief executive. + The U.S. government is expected to receive about 1.88 +billion dlrs for Conrail after factoring in underwriting fees +and other adjustments. + The possibility of a recession at some time in the next +five years is another issue troubling some investors. + Lewins says revenue-ton-miles, which he believes will climb +from 68.7 mln miles last year to 69.5 mln this year and 70.5 +mln in 1988, will grow to 71.5 mln in 1991, but in a recession +year, perhaps 1989, the figure could dip to 64.2 mln. + On the revenue side, he believes revenue per ton-mile will +be 4.7 cts in 1991, little changed from present levels and +exactly the same as in 1981. + "Their basic business isn't going anywhere," he says, +explaining why emphasizes investment of cash flow. + Voytko thinks Conrail can remain profitable in a recession +year. He points out his firm, PaineWebber, is not forecasting a +recession in any specific year, but as an example a 1990 +recession of modest degree could knock earnings down to 2.20 +dlrs per share. He estimated 3.00 dlrs per share this year and +3.35 dlrs next year. His 1988 figure reflects mostly a lowering +of the tax rate to 34 pct from 40 pct this year. + Voytko believes the Conrail shares merit purchase at the 26 +dlr level. + Goldman, Sachs and Co was lead manager for the offering. A +total of 148 firms took part in the U.S. syndicate. + Reuter + + + +26-MAR-1987 12:33:57.01 +acq +usa + + + + + +F +f1818reute +r f BC-GOULD<GLD>-COMPLETES 03-26 0077 + +GOULD<GLD> COMPLETES SALE OF FRENCH BATTERY UNIT + ROLLING MEADOWS, Ill., March 26 - Gould Inc said it has +completed the sale of its French battery business, Compagnie +Francaise D'Electro Chimie, to a group of investors including +the unit's employees and <GNB Inc> of Minnesota. + Gould did not disclose terms of the deal. + Gould said the move is part of its previously announced +plan to divest assets unrelated to its computer and electronics +businesses. + Reuter + + + +26-MAR-1987 12:34:24.39 + +usa + + + + + +F +f1823reute +r f BC-CMS-ENHANCEMENTS-<ACM 03-26 0054 + +CMS ENHANCEMENTS <ACMS> GETS CREDIT LINE + TUSTIN, Calif., March 26 - CMS Enhancements Inc said it has +obtained a ten mln dlr line of credit from Bank of the West, +effective immediately. + The credit line will be used in part to fund additional +growth, including research and development of new products, the +company said. + Reuter + + + +26-MAR-1987 12:37:48.01 + +usa + + + + + +F +f1836reute +d f BC-EXOVIR-<XOVR>-TO-GET 03-26 0108 + +EXOVIR <XOVR> TO GET EUROPEAN PATENT + GREAT NECK, N.Y., March 26 - Exovir Inc said the European +Patent Office notified it that its application covering +combinations of nonionic surfactants and all forms of +interferon has been approved and a patent will be issued in +about six months. + Exovir is completing trials of a gel combining alpha +interferon and nonoxynol-9, an antiviral surfactant, as a +treatment for genital and oral herpes and genital warts. The +gel was given a U.S. patent in 1985. + It said clinical tests will begin shortly to test whether +the gel is effective in preventing transmission of the AIDS +virus when used with a condom. + Reuter + + + +26-MAR-1987 12:38:09.30 + +usa + + + + + +F +f1839reute +d f BC-resending 03-26 0082 + +HIGHER U.S. WEEKLY CAR OUTPUT ESTIMATED + DETROIT, March 26 - U.S. automakers are expected to build +167,236 cars this week, up from 133,067 in the same year-ago +period, said the trade publication Ward's Automotive Reports. + It said year-to-date car production would reach 2,012,093 +compared to 2,126,954 in the 1986 period. + Domestic truck production for the week was seen as rising +to 70,033 from 58,506. Year to date, it was projected at +937,163 compared to 882,230 in the 1986 period. + Reuter + + + +26-MAR-1987 12:38:22.02 + +usa + + + + + +F +f1840reute +r f BC-CIRCLE-K-<CKP>-OFFICI 03-26 0071 + +CIRCLE K <CKP> OFFICIAL INCREASES HOLDINGS + PHOENIX, Ariz., March 26 - Circle K Corp said its chairman, +Karl Eller, will buy 750,000 shares of Circle K common stock +from the company's founder and Vice Chairman, Fred Hervey, in a +private transaction. + After the sale, Hervey will directly or beneficially own +6,764,004 shares, or 13.61 pct of Circle K stock and Eller will +hold 2,873,300 shares, of 5.78 pct of the stock. + Reuter + + + +26-MAR-1987 12:40:02.47 +earn +usa + + + + + +F +f1852reute +d f BC-SHOE-TOWN-INC-<SHU>-Y 03-26 0060 + +SHOE TOWN INC <SHU> YEAR ENDED JAN THREE 1987 + TOTOWA, N.J., March 26 - + Shr 51 cts vs 75 cts + Net 5,524,000 vs 8,094,000 + Revs 142.4 mln vs 137.2 mln + NOTE: 1986 and 1985 year net includes loss 785,000 dlrs or +eight cts a share and 59,000 dlrs or one ct a share, +respectively, for discontinued operations. + 1985 year ended December 28, 1985. + Reuter + + + +26-MAR-1987 12:40:16.38 + +usaargentina + + + + + +F +f1854reute +d f BC-EASTERN-AIR-<TXN>-SEE 03-26 0102 + +EASTERN AIR <TXN> SEEKS MORE ARGENTINA FLIGHTS + MIAMI, March 26 - Texas Air Corp's Eastern Airlines Inc +said it asked the U.S. Department of Transportation to approve +an increase in the number of its weekly roundtrip flights to +Buenos Aires to 11 from five. + It said if several of Pan Am Corp's <PN> one-stop flights +to Buenos Aires were terminated in Rio de Janeiro, Eastern +could add four non-stop flights from the U.S. + The expanded weekly schedule would include seven nonstop +flights from Miami, two from New York, and two one-stop flights +from Los Angeles via Lima. It asked for the change by June 12. + Reuter + + + +26-MAR-1987 12:40:43.84 +acq +usa + + + + + +F A +f1858reute +r f BC-FIRST-WISCONSIN-<FWB> 03-26 0055 + +FIRST WISCONSIN <FWB> TO BUY MINNESOTA BANK + MILWAUKEE, Wis., March 26 - First Wisconsin Corp said it +plans to acquire Shelard Bancshares Inc for about 25 mln dlrs +in cash, its first acquisition of a Minnesota-based bank. + First Wisconsin said Shelard is the holding company for two +banks with total assets of 168 mln dlrs. + First Wisconsin, which had assets at yearend of 7.1 billion +dlrs, said the Shelard purchase price is about 12 times the +1986 earnings of the bank. + It said the two Shelard banks have a total of five offices +in the Minneapolis-St. Paul area. + Reuter + + + +26-MAR-1987 12:40:52.65 + +usa + + + + + +F +f1859reute +r f BC-IMRE-<IMRE>-COMPLETES 03-26 0107 + +IMRE <IMRE> COMPLETES PRIVATE STOCK PLACEMENT + SEATTLE, March 26 - IMRE Corp said it completed a private +placement of about 400,000 shares of its securities with a +group of European institutions for 2.5 mln dlrs. + The company said proceeds will be used for working capital +and to implement the company's business plan. + IMRE also said it has established a light manufacturing +facility in Richmond, Washington that makes raw material +components for Prosorba column, a medical device that removes +disease-related immune components from the human bloodstream. + The company is awaiting Food and Drug Administration +approval on the device. + Reuter + + + +26-MAR-1987 12:41:04.85 +earn +usa + + + + + +F +f1860reute +d f BC-AMERICAN-NURSERY-PROD 03-26 0070 + +AMERICAN NURSERY PRODUCTS <ANSY> 3RD QTR NET + TAHLEQUAH, OKLA., March 26 - Period ended Feb 28 + Shr profit five cts vs profit four cts + Net profit 191,000 vs profit 108,000 + Sales 6,561,000 vs 5,896,000 + Nine mths + Shr loss 28 cts vs loss 40 cts + Net loss 871,000 vs loss 990,000 + Sales 9,310,000 vs 8,894,000 + Avg shrs 3,086,386 vs 2,465,996 + NOTE: Full name is American Nursery Products Inc + Reuter + + + +26-MAR-1987 12:41:30.21 + +usa + + + + + +F +f1864reute +h f BC-CLINICAL-DATA-<CLDA> 03-26 0050 + +CLINICAL DATA <CLDA> AWARDED RESEARCH CONTRACTS + BOSTON, March 26 - Clinical Data Inc said it has contracts +with four major pharmaceutical firms to analyze certain data in +research studies evaluating the efficacy and safety of new +cardiovascular drugs. + It said the contracts exceed 500,000 dlrs. + Reuter + + + +26-MAR-1987 12:43:18.88 + + + + + + + +F +f1871reute +f f BC-******DUN/BRADSTREET 03-26 0011 + +******DUN/BRADSTREET SAYS BUSINESS FAILURES UP 10.8 PCT IN FEBRUARY +Blah blah blah. + + + + + +26-MAR-1987 12:44:43.83 + +usa + + + + + +F +f1875reute +u f BC-UAW-STRIKES-GENERAL-M 03-26 0097 + +UAW STRIKES GENERAL MOTORS <GM> PLANT + PONTIAC, Mich., March 26 - The United Auto Workers struck +General Motors Corp's truck and bus plants at Pontiac, Mich, +General Motors said. + General Motors' truck and bus group failed to reach an +agreement on local issues with UAW Local 594 by the union's +deadline of noon today, causing a strike by 9,000 hourly +workers at the facility, the company said. + General Motors said it was "eager" to continue meeting with +union officials on the dispute. It was not immediately clear +whether contract talks were continuing at the facility. + General Motors spokesman Frank Cronin said the three plants +at Pontiac stopped working "as of noon today." + He said talks will resume Friday at 1000 EST in Pontiac. +"We're hoping (the strike) will be of very brief duration," +Cronin said. + Bus-manufacturing operations at one of the three +plants--the Pontiac Central facility--are being sold to +Greyhound Corp <G>, although GM will retain the facility. + Cronin said about 400 workers on the bus line will be laid +off "whenever we fulfill production commitments" on the buses, +"possibly in May." + The Pontiac Central plant also makes medium- and heavy-duty +trucks. Assembly of the medium trucks is scheduled to move to +Janesville, Wis., in 1990, Chronin said. + Heavy truck operations at the plant will be taken over by +GM's joint venture with Volvo AB, and all vehicle assembly +operations at the facility will eventually be ended, Chronin +said. The plant also has sheet metal operations, which are so +far unaffected, he said. + The other two plants at Pontiac--Pontiac East and Pontiac +West--make full-size pickups and sport utility vehicles. + Reuter + + + +26-MAR-1987 12:46:03.72 + +usa + + + + + +F +f1880reute +r f BC-S.P.I.-SUSPENSION-<SP 03-26 0046 + +S.P.I. SUSPENSION <SPILF> WINS CONTRACT + NEW YORK, March 26 - S.P.I. Suspension and Parts Industries +Ltd said it won four multi-year contracts from the U.S. Army +worth 34.5 mln dlrs. + The contracts, for wheels on U.S. Army vehicles, will run +for five years beginning 1987. + Reuter + + + +26-MAR-1987 12:46:20.26 +earn +usa + + + + + +F +f1881reute +d f BC-DISCUS-CORP-<DISC>-4T 03-26 0046 + +DISCUS CORP <DISC> 4TH QTR LOSS + BLOOMINGTON, Minn., March 26 - + Shr loss six cts vs loss seven cts + Net loss 125,000 vs loss 140,000 + Rev 2.4 mln vs 2.2 mln + Year + Shr loss 13 cts vs loss 14 cts + Net loss 271,000 vs loss 211,000 + Rev 10.1 mln vs 8.2 mln + Reuter + + + +26-MAR-1987 12:48:35.24 + + + + + + + +F +f1886reute +b f BC-******ENTERTAINMENT-P 03-26 0009 + +******ENTERTAINMENT PUBLICATIONS DISCONTINUES THREE UNITS +Blah blah blah. + + + + + +26-MAR-1987 12:49:18.15 + +usa + + + + + +C +f1887reute +d f BC-CFTC-OFFICIALS-SEE-NO 03-26 0106 + +CFTC OFFICIALS SEE NO MERGER WITH SEC + WASHINGTON, March 26 - Officials of the Commodity Futures +Trading Commission (CFTC) said merging the agency with the +Securities and Exchange Commission (SEC) would not help +regulation of commodities and securities markets. + "I don't think that a merger would solve regulatory +problems," CFTC chairman Susan Phillips told the House +Subcommittee on Conservation, Credit and Rural Development. + "I think what does solve our problems would be working with +other agencies in a strong capacity," she said in response to a +question. "We don't want agencies to trample on our +jurisdiction either." + CFTC Commissioner Fowler West said, "We ... do not have the +expertise to regulate securities markets. I don't think the SEC +has the expertise to regulate the futures markets." + Increased attention to price volatility in stock index +futures markets and reports of alleged futures trading abuses +have raised concerns Congress may adopt a radically different +regulatory structure for securities and futures markets. + Rep. John Dingell (D-Mich.), chairman of the House Energy +and Commerce Committee, which has jurisdiction over securities +regulation, has said he will hold hearings on the questions of +market volatility and alleged trading abuses. + Reuter + + + +26-MAR-1987 12:49:31.85 +earn + + + + + + +F +f1889reute +b f BC-*****ENTERTAINMENT-PU 03-26 0013 + +*****ENTERTAINMENT PUBLICATIONS SEES 31 CTS/SHR 3RD QTR LOSS ON UNITS DISPOSAL +Blah blah blah. + + + + + +26-MAR-1987 12:50:43.81 + +poland +jaruzelski + + + + +RM +f1894reute +u f BC-POLAND-FIRM-ON-ECONOM 03-26 0092 + +POLAND FIRM ON ECONOMY DESPITE CONCESSIONS + By Irena Czekierska, Reuters + WARSAW, March 26 - The Polish government has backed down +from some proposed price rises in the face of strong opposition +from trade unions, but has restated its commitment to economic +reforms entailing tougher discipline and austerity measures. + Following a warning from the officially-backed OPZZ unions +that sharp price hikes could spark confrontation, the +government has agreed that food prices this year will rise an +average 9.6 pct instead of the planned 13 pct. + A statement last night said the government had "partially +accepted" demands for the protection of the low-paid and agreed +to extend some social benefits. + But Polish leader Wojciech Jaruzelski, at a separate +meeting yesterday, sharply criticised the slow pace of reforms. + He told an economic commission that tougher discipline and +austerity measures, greater efficiency and initiative should +replace waste, red tape and inertia. He announced cost-cutting +measures affecting central administrative bodies. + OPZZ economic expert Zbigniew Kochan welcomed the move on +food prices. "This decrease was considerable," Kochan told +Reuters today. "Also important is the fact that the government +admitted we were right and agreed to consult us over prices +from now on," he added. + The communique made no mention of curbs on wage increases, +or price rises in sectors including transport and energy. + The authorities have said prices could go up by as much as +26 pct as state subsidies are sharply reduced in an effort to +make the market more free and to improve efficiency. + The OPZZ unions are officially recognised by the government +and replaced the Solidarity movement suppressed under martial +law. They claim a membership of seven million. + Western diplomats said today the climb-down on food prices +was a limited concession. "This is a small price to pay if they +can push through the other price rises," one said, adding that +fuel and energy rises would have a more significant effect. + He noted that there had been a concerted media campaign to +prepare people for price rises, including a major article in a +mass-circulation women's magazine, "clearly aimed at those who +do the shopping," he said. + Other articles in the official press this week have focused +on coal, which sells to both industrial and private consumers +at far less than either the production or export costs. + Countering scepticism from opposition sources and former +Solidarity activists as to OPZZ's role, Kochan said "It was +definitely not a question of gaining credibility, but true +concern for people's living standards." + Deputy Prime Minister Jozef Koziol said the authorities' +main aim was not to harm workers' living standards. But he was +also quoted by the official PAP news agency as saying the +government had to take current economic realities into account. + REUTER + + + +26-MAR-1987 12:50:49.04 +earn +usa + + + + + +F +f1895reute +r f BC-PAY-'N-PAK-STORES-INC 03-26 0043 + +PAY 'N PAK STORES INC <PNP> 4TH QTR FEB 28 NET + KENT, Wash., March 26 - + Shr 11 cts vs 13 cts + Net 1,129,000 vs 1,301,000 + Revs 83.2 mln vs 74.5 mln + Year + Shr 57 cts vs 82 cts + Net 5,686,000 vs 8,168,000 + Revs 398.4 mln vs 333.8 mln + Reuter + + + +26-MAR-1987 12:50:57.93 +gas +usa + + + + + +F Y +f1896reute +r f BC-corrected---mobil 03-26 0119 + +(CORRECTED) - MOBIL <MOB> TO UPGRADE REFINERY UNIT + NEW YORK, March 26 - Mobil Corp said it will spend over 30 +mln dlrs to upgrade a gasoline-producing unit at its Beaumont, +Texas, refinery. + It said the unit is a catalytic reformer, which converts +low-octane components of gasoline into high-octane components +for use in Super Unleaded gasoline. + The company said the modernization will allow the unit to +regenerate catalysts on a continuous basis without shutdown. +Currently, it must be shut twice a year. The unit produces +46,000 barrels of gasoline components a day. Construction will +start late this year, with completion set for mid-1989. + (Correcting unit's output to barrels/day from barrels/year) + Reuter + + + +26-MAR-1987 12:59:20.16 + +usa + + +cbt + + +C +f1921reute +d f BC-CFTC-SPECULATIVE-LIMI 03-26 0141 + +CFTC LIMIT PLAN MAY NOT REVERSE LIQUIDITY DROP + WASHINGTON, March 26 - A proposal by the Commodity Futures +Trading Commission, CFTC, to raise federal limits on futures +speculative positions for certain agricultural commodity +contracts would not reverse a decline in liquidity in those +markets that started in 1981, two CFTC commissioners said. + Commissioners William Seale and Kalo Hineman told a House +Agriculture subcommittee a recent proposal that would have the +effect of raising deferred month speculative position limits on +several agricultural commodity contracts would not +substantially increase liquidity in those months. + "I seriously doubt that increasing speculative limits will +create a great deal of liquidity in the back months," Seale +told the House Agriculture Subcommittee on Conservation, Credit +and Rural Development. + Analysts have attributed much of the liquidity squeeze to a +1981 tax law change, which by changing the treatment of +so-called straddles limited the ability of futures commission +merchants to roll positions forward for tax purposes. + CFTC Chairman Susan Phillips said only that the commission +would take into account Congress' recommendation that federal +speculative limits be raised. + The Chicago Board of Trade and the MidAmerica Commodity +Exchange have expressed concern that the CFTC plan would +decrease spot month limits for certain of their contracts. + Reuter + + + +26-MAR-1987 13:00:01.51 +earn +usa + + + + + +F +f1926reute +d f BC-AMERICAN-NURSERY-PROD 03-26 0073 + +AMERICAN NURSERY PRODUCTS <ANSY> 3RD QTR NET + TAHLEQUAH, Okla., March 26 - Qtr ends Feb 28 + Shr profit five cts vs profit four cts + Net profit 191,000 vs profit 108,000 + Revs 6,561,000 vs 5,896,000 + Avg shrs 3.6 mln vs 2.5 mln + Nine mths + Shr loss 28 cts vs loss 40 cts + Net loss 871,000 vs loss 990,000 + Revs 9,310,000 vs 8,894,000 + Avg shrs 3.1 mln vs 2.5 mln + NOTE: Full name American Nursery Products Inc. + Reuter + + + +26-MAR-1987 13:00:14.13 +earn +sweden + + + + + +F +f1927reute +d f BC-VOLVO-FINAL-RESULT-IM 03-26 0124 + +VOLVO 1986 RESULT OFF SLIGHTLY FROM 1985 + STOCKHOLM, March 26 - AB Volvo <VOLV.ST> said the weakening +dollar caused the drop in its 1986 profits, but company chief +executive Pehr Gyllenhammar said 1986 was one of Volvo's best +years ever. + In its final report released earlier, the company said the +group's 1986 profits before allocations and taxes was 7.53 +billion crowns compared with 1985's 7.60 billion. + Despite the fall, Gyllenhammar said, "Sales of industrial +products have never been higher, and Volvo Cars and Volvo +Trucks were both completely sold out at year-end. Operating +income was slightly higher than a year earlier." + He said the company's financial strength gave it +exceptional opportunities to invest for the future. + Although industrial sales were up, the company's yearend +report said total sales were 84.09 billion crowns against +1985's 86.19 billion. + Reuter + + + +26-MAR-1987 13:00:46.83 +acq +usa + + + + + +F +f1929reute +h f BC-<MERIDIAN-ENERGY>,-CA 03-26 0045 + +<MERIDIAN ENERGY>, CASTONE END LETTER OF INTENT + CHICAGO, March 26 - <Meridian Energy Inc> and Castone +Development Corp, a privately-held company, jointly announced +that they have decided to terminate the letter of intent under +which Meridian would have acquired Castone. + Reuter + + + +26-MAR-1987 13:06:17.40 +iron-steelship +taiwansouth-koreajapanchinauk + +ec + + + +M +f1955reute +r f BC-REPORT-EXPECTS-SHARP 03-26 0107 + +REPORT EXPECTS SHARP DROP IN WORLD IRON IMPORTS + LONDON, March 26 - World seaborne iron ore imports will +fall sharply by the year 2000 with declining imports to the EC +and Japan only partially offset by increased demand from South +East Asia, a report by Ocean Shipping Consultants said. + The report predicts annual world seaborne iron ore imports +of 267.7 mln tonnes by 2000 versus 312.4 mln tonnes in 1985. + It estimates that total bulk shipping demand from the iron +ore sector will fall by almost 10 pct, or 200 billion tonne +miles, with shipping demand associated with the coking trade +down about 17 pct or 130 billion tonne miles. + The report sees EC imports falling to 91.7 mln tonnes in +2000 from 123.6 mln in 1985 with Japanese imports falling to 89 +mln from 124.6 mln tonnes. Imports to South East Asia are seen +rising to 58.6 mln from 32.6 mln tonnes in 1985. + It predicts that EC steel production will fall to 109 mln +tonnes in 2000 from 135.7 mln in 1985 with Japanese production +falling to 92 mln from 105.3 mln. + South Korea and Taiwan are expected to double their output +to 40 mln tonnes with Chinese production increasing by 25 mln +tonnes to 80 mln, it added. + Reuter + + + +26-MAR-1987 13:06:50.85 + +usa + + + + + +F +f1960reute +d f BC-ROYCE-<RLAB>-TO-REDEE 03-26 0056 + +ROYCE <RLAB> TO REDEEM WARRANTS + MIAMI, March 26 - Royce Laboratories Inc said it is calling +for redemption its redeemable common purchase warrants on April +30 at 2.5 cts per warrant. + It said warrant holders retain the right to purchase one +share of its common at an exercise price of three dlrs per +share until 1700 EST April 29. + Reuter + + + +26-MAR-1987 13:07:08.34 + +usa + + + + + +F +f1961reute +b f BC-DUN/BRADSTREET-<DB>-S 03-26 0056 + +DUN/BRADSTREET <DB> SAYS BUSINESS FAILURES UP + NEW YORK, March 26 - Dun and Bradstreet Corp said business +failures in February increased 10.8 pct, to 5,390, from 4,864 +in February 1986. + "The national level of business failures continues to be +driven upward by substantial increases in the oil and +agricultural states," Dun said. + Dun said that of the nine U.S. Bureau of the Census +regions, three reported a decrease in the number of failures +and two had gains of less than 3.0 pct. + The largest increase was reported in the West South Central +states, Dun said, with business failures rising 47.8 pct, to +1,218. + The East South Central states posted a 44 pct rise, to 298, +Dun said, while the West North Central states recorded a 27.3 +pct gain, to 489. + The greatest decline, Dun reported, was registered by the +Middle Atlantic states, down 8.2 pct in February, to 324. + The Pacific states also reported a large decline in failing +businesses, off 6.8 pct, to 1,028, Dun said. + In the smokestack region of the East North Central states, +there was a negligible decline of 0.6 pct, to 794, Dun said. + Dun said the Mountain states recorded a gain in business +failures of 1.5 pct, to 530. + Business failures in the New England states rose 23.5 pct, +to 105. + By industry segment, Dun said the largest gain was recorded +by the agricultural, forestry and fishing sector, up 62.7 pct, +to 345. + Year to date, Dun said business failures rose to 11,004, an +increase of 5.3 pct over 1986. + Reuter + + + +26-MAR-1987 13:08:21.86 +earn +australia + + + + + +F +f1966reute +d f BC-GOLDFIELD-CORP-<GV>-4 03-26 0080 + +GOLDFIELD CORP <GV> 4TH QTR NET LOSS + MELBOURNE, Fla., March 26 - + Shr loss four cts vs loss five cts + Net loss 527,065 vs loss 1,204,080 + Revs 622,470 vs 613,205 + Year + Shr profit four cts vs loss 13 cts + Net profit 1,099,778 vs loss 3,282,478 + Revs 7,579,547 vs 6,068,254 + NOTE: 1985 excludes loss from discontinued operations of +four cts per share in the quarter and loss 10 cts in the year. +1986 year excludes extraordinary gain of two cts a share. + + Reuter + + + +26-MAR-1987 13:08:52.54 + + + + + + + +A F RM +f1970reute +f f BC-******FED'S-HELLER-UR 03-26 0015 + +******FED'S HELLER URGES FORMING FINANCIAL SERVICES HOLDING COMPANIES TO STRENGTHEN BANKING +Blah blah blah. + + + + + +26-MAR-1987 13:09:45.98 +money-fx +ukfrance +balladurlawson +ec + + + +RM +f1973reute +r f BC-BRITISH,-FRENCH-MINIS 03-26 0115 + +BRITISH, FRENCH MINISTERS DISCUSS PUBLIC SPENDING + LONDON, March 26 - French Finance Minister Edouard Balladur +discussed the need to control public spending in talks here +today with British Chancellor of the Exchequer Nigel Lawson, a +Treasury spokesman said. + The spokesman said the ministers reviewed their economies, +and public spending, domestic and European Community-wide. + He declined to comment on whether the subject of concerted +action to shore up the dollar had arisen. The U.S. Currency +dipped sharply earlier this week after a month of relative +stability after an agreement by six major industrialised +nations in Paris on February 22 to stabilise their currencies. +REUTER + + + +26-MAR-1987 13:09:57.13 +acq +usa + + + + + +F A RM +f1974reute +b f BC-FED'S-HELLER-URGES-BR 03-26 0091 + +FED'S HELLER URGES BROAD REFORM TO AID BANKING + WASHINGTON, March 26 - Federal Reserve Board Governor +Robert Heller said the banking system could be strengthened by +permitting formation of financial services holding companies +involved in areas like banking, insurance, real estate and +securities. + In a speech prepared for delivery in New York to the Bank +and Financial Analysts' Association, Heller said, "I believe +that increased diversification along geographic and product +lines is the key to strengthening the American banking system." + He said he supported the idea of financial services holding +companies advocated by the Association of Bank Holding +Companies in which regulation of various bank, thrift, +insurance, investment, securities and real estate subsidiaries +would be handled on functional lines. + "Limits would be placed on the extension of credit by the +bank to the associated institutions, and all transactions would +have to be on an arms-length basis," Heller said. + Measures would be necessary to avoid abuse of the banks' +special position by such holding companies or subsidiaries. + Heller said he "would require the holding company to serve +as a 'source of strength' to the bank by making a commitment to +maintain the bank's capital. + "In other words, the bank would not be allowed to fail as +long as the holding company has a positive net worth." + Heller also said commercial enterprises should be permitted +to own a financial services holding company, again with the +provision that capital would flow to the financial enterprise +if necessary. + Heller said the effects of these actions "would be banks +that are at least as strong as the corporations holding them" in +which customer deposits were assured while any incentive to +"loot the bank" was removed. + Such diversification would give access to national and +international financial services to corporations across the +United States. + Heller said that would mean "the steady decline of America's +banks in the world financial league tables would be arrested" by +permitting them to become more competitive. + Reuter + + + +26-MAR-1987 13:11:37.69 +earn + + + + + + +F +f1977reute +f f BC-******FEDERATED-DEPAR 03-26 0014 + +******FEDERATED DEPARTMENT STORES INC UPS QTLY DIV BY 10.5 PCT, SETS 2-FOR-1 STOCK SPLIT +Blah blah blah. + + + + + +26-MAR-1987 13:14:17.73 + +usa + + + + + +A RM +f1990reute +r f BC-OUTBOARD-MARINE-<OM> 03-26 0116 + +OUTBOARD MARINE <OM> SELLS 9.15 PCT DEBENTURES + NEW YORK, March 26 - Outboard Marine Corp is raising 100 +mln dlrs via an offering of sinking fund debentures due 2017 +yielding 9.15 pct, said lead manager Salomon Brothers Inc. + The debentures have a 9-1/8 pct coupon and were priced at +99.75 to yield 146 basis points over comparable Treasury bonds. +Morgan Stanley co-managed the deal. + The issue is non-refundable for 10 years. A sinking fund +beginning in 1998 to retire annually five pct of the debt may +be increased by 200 pct at the company's option, giving it an +estimated minimum life of 13.85 years and maximum of 20.5 +years. The debt is rated Baa-2 by Moody's and BBB-plus by S/P. + Reuter + + + +26-MAR-1987 13:15:04.62 +acq +usa + + + + + +F +f1992reute +r f BC-GOULD-<GLD>-SELLS-FRE 03-26 0052 + +GOULD <GLD> SELLS FRENCH BATTERY UNIT + ROLLING MEADOWS, March 26 - Gould Inc said it sold its +French Battery unit, Cie Francaise d'Electro Chimie, to a group +of investors including the unit's employees and <GNB Inc> of +Minnesota. + Terms of the sale were not disclosed. The unit had 1986 +sales of 65 mln dlrs. + Reuter + + + +26-MAR-1987 13:17:32.95 +earn +usa + + + + + +F +f2003reute +r f BC-ADVANCED-GENETIC-SCIE 03-26 0036 + +ADVANCED GENETIC SCIENCES <AGSI> YEAR LOSS + OAKLAND, Calif., March 26 - + Shr loss 30 cts vs loss 73 cts + Net loss 3,895,267 vs loss 8,250,222 + Revs 3,237,235 vs 234,745 + Note: 4th qtr data not available + Reuter + + + +26-MAR-1987 13:25:26.95 +earn +usa + + + + + +F +f2025reute +u f BC-FEDERATED-DEPARTMENT 03-26 0077 + +FEDERATED DEPARTMENT <FDS> RAISES QTLY DIVIDEND + CINCINNATI, March 26 - Federated Department Stores Inc said +it raised its quarterly common stock dividend to 74 cts a +share, from 67 cts, an increase of 10.5 pct. + The company said it also approved a two-for-one stock split +in the form of a 100 pct stock dividend. + At the same time, Federated said it will ask shareholders +to approve an increase in the number of authorized shares to +400 mln, from 200 mln. + Federated said the dividend is payable on a pre-split basis +on April 24 to shareholders of record April 10. + New shares from the stock split will be distributed May 11, +it said. + + Reuter + + + +26-MAR-1987 13:29:49.49 + +usa + + + + + +F +f2040reute +r f BC-CFTC-SEES-NO-TRADING, 03-26 0087 + +CFTC SEES NO TRADING, TRIPLE WITCHING RULES + WASHINGTON, March 26 - The chairman of the CFTC, Susan +Phillips, said she does not expect the CFTC to restrict dual +trading or to intervene in the quarterly expiration of stock +index futures and their options. + "At this time we have no plans to reexamine our policy (on +dual trading)," she told the House Subcommittee on +Conservation, Credit and Rural Development. + She said it would not be appropriate to ban dual trading +because it would decrease market liquidity. + Dual trading refers to the ability of futures commission +merchants to trade for their own as well as their clients' +accounts. Exchange rules prohibit a broker from attempting to +benefit from the market impact of a client's order by trading +on his own account before placing the client's order. + CFTC has required all futures exchanges by July 1 to have +implemented audit trails permitting the reconstruction of all +trades to the nearest minute. The move was designed in part to +discourage abuse of dual trading. + The board of directors of the Chicago Mercantile Exchange +has proposed limiting but not banning dual trading in the +Standard and Poor's 500 stock index future pit. + Phillips indicated the CFTC would not move beyond requiring +improved audit trails in its effort to allay concerns about +dual trading abuses. + "It would be inappropriate at this point until we see how +the audit trail will work," she said in response to a question. + On triple-witching, Phillips said recent experiments by +markets to quell price fluctuations have been quite successful +and that users of securities and derivative instruments were +still learning how to deal with the quarterly phenomenon. + Triple-witching refers to the simultaneous expiration of +stock index futures, options on those futures and options on +certain individual stocks. + The CFTC chairman noted the commission has heightened +surveillance of markets on triple-witching day. + "We aren't sure any other regulatory changes are needed at +this point," Phillips said. + Reuter + + + +26-MAR-1987 13:30:19.72 + +usa + + + + + +A RM +f2041reute +r f BC-TRINITY-INDUSTRIES-<T 03-26 0104 + +TRINITY INDUSTRIES <TRN> AND UNIT CUT BY S/P + NEW YORK, March 26 - Standard and Poor's Corp said it cut +to BB-minus from BB-plus Trinity Industries Inc's 275 mln dlrs +of liquid yield option notes. + Also downgraded were the unit Trinity Industries Leasing +Co's 60 mln dlrs of convertible debentures due 2006 to BB-plus +from BBB-minus. + S and P said the actions reflected Trinity's weakened +earnings due to depressed demand in several key markets, the +likelihood that a significant sustained improvement would not +occur in the near-term, as well as heightened financial risk +from a series of debt-financed acquisitions. + Reuter + + + +26-MAR-1987 13:32:52.55 +earn +usa + + + + + +F +f2054reute +u f BC-DANZAR-INVESTMENT-<DN 03-26 0079 + +DANZAR INVESTMENT <DNZR> SETS SPECIAL DIVIDEND + DALLAS, March 26 - Danzar Investment Group Inc said it +received 60 mln shares of <Commonwealth Capital Ltd> in +settlement of a debt and that it will distribute the shares to +its stockholders as a dividend. + Danzar said the dividend will also include 18,750,000 +Commonwealth shares it already holds. + The dividend of 39.9 shares per Danzar share held will be +paid to shareholders of record April 15, the company said. + Reuter + + + +26-MAR-1987 13:38:15.46 +acq +usa + + + + + +F +f2069reute +d f BC-FIDELITY-<FNF>-UNIT-A 03-26 0058 + +FIDELITY <FNF> UNIT ACQUIRES CALIFORNIA CONCERN + SCOTTSDALE, Ariz., March 26 - Fidelity National Financial +Inc said its Fidelity National Title Insurance Co subsidiary +acquired the operations of Safeco Title Insurance Co in the +northern California counties of Alameda, Contra Costa and San +Mateo. + Terms of the acquisition were not disclosed. + Reuter + + + +26-MAR-1987 13:40:37.69 + +usa + + + + + +F +f2070reute +d f AM-LIABILITY 03-26 0113 + +ADMINISTRATION SAYS INSURANCE CRISIS EASED + WASHINGTON, March 26 - The Reagan administration said the +national crisis in liability insurance eased during the past +year as the insurance industry's profits more than doubled to +11.5 billion dlrs, but some problems still persist. + An administration working group, in an update of its report +a year ago, found that insurance premiums generally have +stabilized, but at high levels, as the crisis has abated. + After severe financial difficulties in 1984 and 1985, the +insurance industry's rate of return last year recovered to the +same level as the performace of U.S. corporations in general, +the group said in a 98-page study. + While the crisis has eased, the study found that liability +insurance will likely remain expensive and continue to be +difficult to obtain for some lines of coverage and for some +sectors of the American economy. + Some types of insurance, especially associated with +environmental liability, remain unavailable for many companies +at any price, it said. + The increased availability and the price stability for +insurance the past year has been accompanied by higher +deductibles, lower coverage limits and additional policy +restrictions, the study said. + The administration last year unveiled a wide range of +recommendations aimed at dealing with the crisis, including +limits on punitive damages and awards for pain, suffering and +mental anguish at 100,000 dlrs. + Attorney General Edwin Meese told a news conference today +that the administration still supports state efforts to place +limits on damage awards and to enact other reforms of the tort +laws. + Assistant Attorney General Richard Willard denied charges +by consumer groups that the insurance crisis was caused by +industry collusion to raise rates in violation of the antitrust +laws. Willard, the head of the working group, said excessive +jury damage awards was the main reason for the insurance +liability problem. + Reuter + + + +26-MAR-1987 13:44:20.98 + + + + + + + +RM +f2081reute +f f BC-Saint-Gobain-U.S.-sub 03-26 0015 + +******Saint Gobain U.S. Subsidiary seeks 150 mln dlr, five year facility - arranger Chemical +Blah blah blah. + + + + + +26-MAR-1987 13:45:13.45 +earn +usa + + + + + +F +f2082reute +u f BC-HOME-SAVINGS-BANK-<HM 03-26 0022 + +HOME SAVINGS BANK <HMSB> SETS INITIAL DIVIDEND + NEW YORK, March 26 - + Qtly div nine cts + Pay April 30 + Record April six + Reuter + + + +26-MAR-1987 13:46:09.82 +cotton +usa + + + + + +C G +f2085reute +u f BC-cotton-ginnings 03-26 0093 + +FINAL 1986 CROP U.S. COTTON GINNINGS + WASHINGTON, March 26 - Final 1986 crop U.S. cotton ginnings +totaled 9,438,425 running bales, vs 12,987,834 bales at the end +of the 1985 season and 12,544,866 bales at end-1984 season, the +U.S. Census Bureau said. + The bureau said upland cotton ginnings from the final 1986 +crop totaled 9,237,296 bales, vs 12,837,088 bales in 1985 and +12,418,749 bales in 1984. + American Pima ginnings from the final 1986 crop totaled +201,129 bales, vs 150,746 bales in the 1985 crop and 126,117 +bales in 1984, the bureau said. + REUTER + + + +26-MAR-1987 13:48:02.47 + +usa + + + + + +F A +f2087reute +d f AM-ANDERSON 03-26 0119 + +FORMER TREASURY SECRETARY PLEADS GUILTY TO TAX EVASION + NEW YORK, March 26 - Former Secretary of the Treasury +Robert Anderson, whom Dwight Eisenhower once said deserved to +be president, pleaded guilty to income tax evason charges and +illegally running an offshore bank. + Anderson, declaring that he was "deeply regretful," admitted +to evading tax on 127,500 dlrs in undeclared income. Much of +the money was paid to him for lobbying for controversial South +Korean evangelist Sun Myung Moon's Unification Church. + The 77-year-old Anderson was President Eisenhower's +treasury secretary from 1957 to 1961 and a prominent +businessman afterwards. In his memoirs, Eisenhower said +Anderson deserved to be president. + Standing before Federal Court Judge Edmund Palmieri, +Anderson, who faces up to 10 years in jail, said he had +recently undergone two operations and treatment for alcoholism. + The judge set May 7 for sentencing and U.S. Attorney +Rudolph Giuliani declared the government would ask that +Anderson be sent to jail. + According to the indictment, Anderson was a prinicipal of +the Commercial Exchange Bank and Trust Ltd of Anguilla in the +British West Indies for two years ending in 1985. + During that time, government prosecutors said the bank +conducted operations in New York city but failed to register +with state and federal banking authorities. Depositors have +lost at least 4 mln dlrs. + Anderson pleaded gulity only for the tax year 1984 but +admitted other tax transgressions for the previous year and +faces civil fines for both years. + Among other things, he said he received 80,000 dlrs in 1983 +from a shell corporation for lobbying for the Unification +Church. The money was given to him as a no-interest loan +repayable in 1990 but the government said it should have been +reported as income. + Reuter + + + +26-MAR-1987 13:53:17.71 +earn + + + + + + +F +f2104reute +f f BC-******american-brankd 03-26 0009 + +******AMERICAN BRANDS SEES RECORD FIRST QUARTER RESULTS +Blah blah blah. + + + + + + diff --git a/src/test/data/reuters-21578/reut2-011.sgm b/src/test/data/reuters-21578/reut2-011.sgm new file mode 100644 index 00000000000..7e2f984c80d --- /dev/null +++ b/src/test/data/reuters-21578/reut2-011.sgm @@ -0,0 +1,2010 @@ + + +30-MAR-1987 14:22:36.87 + +usa + + + + + +F A RM +f2192reute +u f BC-FIDATA-<FID>-ANNOUNCE 03-30 0086 + +FIDATA <FID> ANNOUNCES PRELIMINARY ESM SETTLEMENT + NEW YORK, March 30 - Fidata Corp <FID> and its subsidiary, +Fidata Trust Company New York <FTCNY>, announced that they have +reached a preliminary settlement agreement in principle in the +lawsuits filed by major parties arising out of the E.S.M. +Government Securities, Inc bankruptcy. + Fidata Corp said that it anticipates that the cost of the +proposed settlement, after anticipated recoveries, will be less +than 4 mln dlrs, and possibly significantly less. + The major terms of the settlement agreement, applicable to +Fidata and FTCNY, provide for the release by Fidata of its +claims to 1.125 mln dlrs held by the ESM estate, and the +further payment of 8.425 mln dlrs for distribution to the +public body plaintiffs and Home State Savings Bank. + Fidata said it expects to recover along with its subsidiary +at least half of the sums to be paid under the terms of the +agreement, and potentially amounts substantially in excess of +that. + Reuter + + + +30-MAR-1987 14:23:25.56 + +usa + + + + + +F +f2194reute +w f BC-LOUISVILLE-GAS<LOU>-T 03-30 0084 + +LOUISVILLE GAS<LOU> TO ASK PROTECTIVE MEASURES + LOUISVILLE, KY., March 30 - Louisville Gas and Electric Co +said it will ask stockholders at its May 12 annual meeting to +approve several anti-takeover proposals. + It said the measures include staggered terms for directors +and a fair price provision that would require a potential +purchaser to make the same offer to all stockholders. + Louisville Gas said the amendments are not in response to +any specific effort to obtain control of the company. + Reuter + + + +30-MAR-1987 14:23:31.58 + +usa + + + + + +F +f2195reute +h f BC-TRACOR-<TRR>-UNIT-WIN 03-30 0064 + +TRACOR <TRR> UNIT WINS NAVY CONTRACT + AUSTIN, March 30 - Tracor Inc said its Tracor Applied +Sciences unit was awarded a 1.9 mln dlr contract by the U.S. +Navy's Naval Underwater Systems Center. + Under the contract, Tracor said the unit will provide +analytical, experimental, engineering and technical services to +the Navy's Surface Ships Antisubmarine Warefare Development +Program. + Reuter + + + +30-MAR-1987 14:23:38.33 + +usa + + + + + +F +f2196reute +r f BC-CAMPBELL-SOUP-<CPB>-T 03-30 0056 + +CAMPBELL SOUP <CPB> TO SELL PLANT IN DELAWARE + CAMDEN, N.J., March 30 - Campbell Soup co said it will sell +its W.L. Wheatley ingredients plant in Clayton, Del., as a +going operation. + It said it will continue to operate the plant until a buyer +is found. The sale is aimed at improving Campbell's return on +assets, the company said. + Reuter + + + +30-MAR-1987 14:28:03.38 + +usaindia + + + + + +F +f2207reute +h f BC-VIDEO-DISPLAY-<VIDE> 03-30 0065 + +VIDEO DISPLAY <VIDE> IN INDIAN JOINT VENTURE + STONE MOUNTAIN, Ga., March 30 - Video Display Corp said it +signed agreements with <Glowtronics <Ltd> to jointly build a +manufacturing plant in the state of Karnatake, India. + Video Display said the plant, in which it will own a 40 pct +equity interest, will make cathodes, filament heatrers and +electron gun assembles for television sets. + Reuter + + + +30-MAR-1987 14:28:16.03 +acq + + + + + + +F +f2208reute +f f BC-TAFT 03-30 0013 + +******BASS GROUP SAYS IT HAS HAD TALKS ON SEEKING CONTROL OF TAFT BROADCASTING +Blah blah blah. + + + + + +30-MAR-1987 14:29:14.28 +crude +usa + + + + + +Y +f2209reute +u f BC-REFINE- 03-30 0103 + +LOWER REFINERY OPERATIONS SEEN PRODUCING PROFITS + By BERNICE NAPACH, Reuters + SAN ANTONIO, TEXAS, March 30 - U.S. refiners will have to +reduce operations if they want to be profitable this year, said +industry officials attending the National Petroleum Refiners +Association meeting here. + "If the refining sector can discipline itself to refine +about 12 mln barrels of crude oil a day, we have a chance to +pull down inventories to acceptable levels by the second +quarter, said Archie Dunham, executive vice president of +petroluem products at Conoco Inc + "If not, the industry will have a tough 1987," he added. + Last week's American Petroleum Institute report said that +U.S. refining capacity rose three pct to 78.7 pct of capacity, +with crude oil runs at 12.2 mln barrels per day for the week +ended March 20. + The API said that with the higher crude oil runs, +distillate and gasoline inventories were sharply above year-ago +levels. Gasoline stocks were at 245.6 mln barrels, some 17.2 +mln barrels above year-ago levels. Distillate stocks, at 108.7 +mln barrels, are 10.9 mln barrels above last year's level, the +API said. + Henry Rosenberg, chairman of Crown Central Petroleum Corp +<CNP> told Reuters that unless refining and marketing return to +profitability, oil companies will have to rely on downstream +operations to produce an acceptable level of earnings. + "The jump in refining capacity is a concern if it +continues," said Kenneth Buckler, executive vice president of +refining and marketing at <Total Petroleum Co>, a U.S. +subsidiary of Cie Francaise Des Petroles of France. + Refineries should operate near 75 pct of capacity given +the current level of demand but the operating level should +increase as gasoline demand picks up in the next quarter, +Buckler said. + Dunham said the potential operable capacity of U.S. +refineries should also be cut about 500,000 barrels of crude +per day. "I expect to see the shutdown of more small refineries +over the next five years," he said, adding that these +facilities refine between 10,000 and 30,000 barrels of crude +oil per day. The API said U.S. operations have the capacity to +refine 15.6 mln bpd of crude. + Reuter + + + +30-MAR-1987 14:29:24.83 + +usa + + + + + +F +f2210reute +r f BC-NYNEX 03-30 0103 + +NYNEX <NYN> UNIT FILES 500 MLN DLR DEBT OFFERING + WASHINGTON, March 30 - New York Telephone Co, a subsidiary +of NYNEX Corp, filed with the Securities and Exchange +Commission for a shelf offering of up to 500 mln dlrs of debt +securities on terms to be determined at the time of the sale. + Proceeds from the offering, which is in addition to 50 mln +dlrs of debt securities already registered with the SEC but +unsold, will be used to refinance outstanding long-term debt, +to repay short-term debt and for other general corporate +purposes, the company said. + The company did not name an underwriter for the sale. + Reuter + + + +30-MAR-1987 14:29:34.81 + +usa + + + + + +F +f2212reute +d f BC-HALIFAX-ENGINEERING-< 03-30 0101 + +HALIFAX ENGINEERING <HX> GETS CONTRACTS + ALEXANDRIA, Va., March 30 - Halifax Engineering Inc said it +has received a fixed-price contract woirth 6,700,000 dlrs for +one year, plus two option years, to provide security services +for the U.S. Embassy in Tegucigalpa. + The company said it has also received a three-year U.S. +Army contract, including two option years, for +telecommunications installation support. The contract is worth +a total of 7,500,000 dlrs, it said. + Halifax said its backlog as of tomorrow, the end of its +fiscal year, will be about 53 mln dlrs, up from 27 mln dlrs a +year before. + Reuter + + + +30-MAR-1987 14:29:58.53 + +usasweden + + + + + +F +f2213reute +d f BC-<ELECTROLUX-AB>-UNIT 03-30 0095 + +<ELECTROLUX AB> UNIT TO BUILD WAREHOUSE + ASHEVILLE, N.C., March 30 - The North Carolina Department +of Commerce said Electrolux AB of Sweden's White Consolidated +Industries subsidiary will locate a new 15 mln dlr 352,000 +square foot national appliance parts distribution center at +Asheville, N.C. + It said the center will handle parts for Frigidaire, +Tappan, Kelvinator, Gibson, Vesta and White-Westinghouse +product lines. Each now has a separate distribution center. + The department said construction will start immediately and +should be finished in late 1987. + Reuter + + + +30-MAR-1987 14:30:15.88 + +ukfrance + + + + + +RM +f2215reute +u f BC-SALOMON-SA-EURO-CP/CR 03-30 0106 + +SALOMON SA EURO-CP/CREDIT TERMS DETAILED + LONDON, March 30 - A seven-year credit facility for Salomon +SA, the French ski bindings and boots maker, will have a +facility fee of 7.5 basis point, banking sources said. + The financing involves a 75 mln dlr euro-commercial paper +program which will be supported by a 75 mln dlr committed +syndicated revolving credit. Morgan Guaranty Ltd is the +arranger. + Drawings on the revolving credit will be at a margin of 10 +basis points over the London Interbank Offered Rate (LIBOR). +Banks are being invited to join at 7.5 mln dlrs for 10 basis +points and at five mln dlrs for eight basis points. + Reuter + + + +30-MAR-1987 14:32:12.01 +grainwheatcornoilseedsoybean +usa + + + + + +C G +f2221reute +f f BC-export-inspections 03-30 0015 + +******U.S. EXPORT INSPECTIONS, IN THOUS BUSHELS SOYBEANS 17,683 WHEAT 20,717 CORN 36,581 +Blah blah blah. + + + + + +30-MAR-1987 14:32:29.52 + +usa + + +cbtnyce + + +F RM +f2222reute +u f BC-REGULATORS-TO-CONSIDE 03-30 0112 + +REGULATORS TO CONSIDER CBT EVENING SESSION + WASHINGTON, March 30 - The Commodity Futures Trading +Commission, CFTC, said that on April 15 it will consider the +Chicago Board of Trade's proposal to establish night trading. + The Chicago exchange hopes to begin night trading at the +end of the month. The proposed trading session -- which would +be the first in the United States -- would extend from 1700 to +2100 local time (2300 to 0300 GMT). + CFTC also said that on April 22 it will consider the +Philadelphia Board of Trade's application to trade futures on +the Australian dollar and the New York Cotton Exchange's +application to trade the five-year U.S. Treasury Index. + Reuter + + + +30-MAR-1987 14:35:33.56 + +west-germanyjapan + + + + + +F +f2239reute +r f BC-SONY-INCREASING-PRODU 03-30 0099 + +SONY INCREASING PRODUCTION ABROAD + BONN, March 30 - Sony Corp <SNE.T> will increase production +abroad to overcome falling profits caused by the yen's rise +against the dollar, managing board chairman Akio Morita told +the West German newspaper Die Welt. + He was quoted as saying that Sony, whose latest profit +figures had been affected strongly by dollar fluctuations, +would increase production in the U.S. And Europe. + Several production facilities were being built, he added. +"At the same time we are also investing capital in order to +modernise our locations and raise our productivity." + Morita said that to overcome the same currency problems, +Japan needs to restructure its economy in order to live less +from exports and more from domestic demand. + He said U.S. And European companies had made the mistake of +not investing enough in the future, which was why they had lost +their lead in consumer electronics. + "They may spend a lot of money on research and development," +he said. "But planning and marketing are very important sectors +in developing a marketable product." + "If they don't spend money on these, they can't build up new +business lines." + Speaking of difficulties foreign firms experience in +penetrating the Japanese market, Morita said "Naturally, I have +to admit that there are still many obstacles in Japan." + On the other hand, many foreign firms were too interested +in short-term success, he said. + "If, therefore, a company comes to Japan and wants to make a +profit at once on this market, it is not so simple." + "These people then complain, while the successful firms keep +their mouths shut," Morita said. + Reuter + + + +30-MAR-1987 14:36:52.17 +earn +usa + + + + + +F +f2244reute +u f BC-NEWMONT-MINING-<NEM> 03-30 0084 + +NEWMONT MINING <NEM> PLANS 2-FOR-1 STOCK SPLIT + NEW YORK, March 30 - Newmont Mining Corp's board has +proposed a two-for-one stock split subject to shareholder +approval of an increase to 120 mln from 60 mln in authorized +common shares, the proxy for the company's annual meeting said. + If holdings voting at the May six meeting in Wilmington, +Del., approve the increase in authorized shares the split will +be paid in the form of a stock dividend on June 10 to holders +of record May 20, the proxy said. + Newmont said it will also ask shareholders to approve +amendments to its certificate of incorporation limiting certain +liabilities of its directors. + Reuter + + + +30-MAR-1987 14:38:10.07 + +mexico + + + + + +F +f2254reute +u f BC-MEXICO-FUND-<MFX>-TO 03-30 0086 + +MEXICO FUND <MFX> TO BUY BACK TWO MLN SHARES + MEXICO CITY, March 30 - The Mexico Fund Inc said its board +authorized an offer to purchase two mln shares, or about 10.2 +pct, of its common stock at 6.75 dlrs a share cash. + The fund, at a special board meeting, said the offer is not +conditioned on any minimum number of shares being tendered. + The fund has issued and outstanding 19,513,200 shares of +common stock, it said. As of March 26, 1987, the fund said the +net asset value of its shares was 8.13 dlrs. + The fund said it intends to commence the offer by a mailing +to its shareholders as soon as possible. + It said it purchased shares of its stock in open market +transactions prior to the proposed cash tender and intends to +purchase additional shares at prevailing market prices after +completion of the offer. + The fund's last price per share on the New York Stock +Exchange at the halt was 5-3/4. + Reuter + + + +30-MAR-1987 14:42:08.80 + +usa + + + + + +F +f2265reute +d f BC-QUARTZ-ENGINEERING-<Q 03-30 0046 + +QUARTZ ENGINEERING <QRTZ> GETS SIEMENS ORDER + TEMPE, Ariz., March 30 - Quartz Engineering and Materials +Inc said it has received a 500,000 dlr order from <Siemens AG> +of West Germany for its ATMOSCAN automated environmentally +controlled semiconductor wafer processing system. + Reuter + + + +30-MAR-1987 14:43:54.75 +earn +usa + + + + + +F +f2273reute +d f BC-DENPAC-CORP-<DNPC>-YE 03-30 0043 + +DENPAC CORP <DNPC> YEAR LOSS + HACKENSACK, N.J., March 30 - + Shr loss one ct vs loss one ct + Net loss 483,518 vs loss 220,582 + Sales 381,841 vs 400,518 + NOTE: 1985 net includes 196,868 dlr gain from forgiveness o +accrued interest due to affiliates. + Reuter + + + +30-MAR-1987 14:44:06.64 +earn +usa + + + + + +F +f2275reute +d f BC-<AIN-LEASING-CORP>-3R 03-30 0049 + +<AIN LEASING CORP> 3RD QTR JAN 31 LOSS + GREAT NECK, N.Y., March 30 - + Shr loss six cts vs profit 22 cts + Net loss 133,119 vs profit 496,391 + Revs 136,918 vs 737,917 + Nine mths + Shr loss 21 cts vs profit 15 cts + Net loss 478,991 vs profit 340,210 + Revs 324,011 vs 841,908 + Reuter + + + +30-MAR-1987 14:47:20.29 + +usa + + + + + +F +f2282reute +r f BC-WARNER-LAMBERT-<WLA> 03-30 0097 + +WARNER-LAMBERT <WLA> WINS PACKAGING SUIT + MORRIS PLAINS, N.J., March 30 - Warner-Lambert Co said a +federal court judgment resulted in <My-K Laboratories Inc> +agreeing to discontinue the sale of cough syrup and a +children's allergy elixir because it imitates Warner-Lambert +packaging. + Warner-Lambert said the final consent judgment was entered +in the U.S. District Court of the Northern District of +Illinois. It also said the packaging in question imitated its +own packaging of Benylin and Benadryl products. + My-K agreed to adopt different packaging, Warner-Lambert +said. + Reuter + + + +30-MAR-1987 14:47:40.85 + +usa + + + + + +F +f2284reute +d f BC-HARTMARX-<HMX>-UNIT-P 03-30 0094 + +HARTMARX <HMX> UNIT PRESIDENT RESIGNS + CHICAGO, March 30 - Hartmarx Corp said Geoffrey Bloom +resigned as president and chief executive officer of its +Jaymar-Ruby Inc subsidiary to accept the position of president +and chief operating officer of Wolverine World Wide Inc <WWW>. + It said Elbert Hand, president and chief operating officer +of Hartmarx, and president and chief executive officer of the +Hartmarx Men's Apparel Group, was named chief executive officer +of Jaymar-Ruby Inc. Burton Ruby, son of the Jaymar-Ruby +founder, remains as chairman. + + Reuter + + + +30-MAR-1987 14:48:20.82 + +usa + + + + + +A +f2286reute +u f BC-SENATE-BILL-WOULD-ALL 03-30 0102 + +SENATE BILL WOULD ALLOW FARM LOAN WRITE-DOWNS + WASHINGTON, March 30 - The U.S. Senate has approved a +measure that would allow an estimated 4,200 agricultural banks +to write off loan losses over ten years. + The measure, offered by Sen. Alan Dixon (D-Ill.), was +attached to a bill to recapitalize the Federal Savings and Loan +Insurance Corp that the Senate approved March 27. + Dixon's amendment would permit agricultural banks -- banks +with assets of 100 mln dlrs or less and at least 25 pct of +total loans in farm loans -- to write down over ten years +agricultural loan losses incurred between 1984 and 1992. + Reuter + + + +30-MAR-1987 14:49:29.53 + +usa + + + + + +C G +f2291reute +r f BC-U.S.-SENATE-BUDGET-CH 03-30 0131 + +U.S. SENATE BUDGET CHIEF EYES FARM POLICY CHANGE + WASHINGTON, March 30 - U.S. Senate Budget Committee +Chairman Lawton Chiles' (D-Fla.) fiscal 1988 budget plan would +cut farm spending by about two billion dlrs, primarily by +making unspecified changes in price and income support +programs, Senate staff members said. + Chiles presented his budget blueprint late last week and +said he would like to begin voting on it this week. + Senate Republican staff members said Chiles was +recommending that policy changes be adopted for 1988 crops. + While savings from the changes would accrue mainly in +fiscal 1989, Chiles said his income and price support proposals +would trim about two billion dlrs from advance deficiency +payments, most of which would be made in the spring of next +year. + It was not clear how the Senate Budget panel head would +achieve the savings in Commodity Credit Corp outlays. Aides to +Chiles would not comment on how the CCC savings would be made. + Recently the Congressional Budget Office released a report +listing possible price and income support program savings. + The options included lowering target prices, increasing +unpaid acreage reduction programs, targeting income support +payments to specific groups of producers, limiting the use of +generic commodity certificates, raising loan rates and +"decoupling" income support payments from production decisions. + Chiles proposed saving about 100 mln dlrs by freezing the +U.S. Agriculture Department's discretionary spending functions +which include research and credit programs, Senate staff said. + The Florida senator's plan also would provide 30 mln dlrs +for organic farming research and 20 mln dlrs for homeless aid. + Reuter + + + +30-MAR-1987 14:54:12.48 + +usasouth-africa + + + + + +F +f2301reute +u f BC-newmont-mining-<nem> 03-30 0112 + +NEWMONT MINING <NEM> SEEKS SOUTH AFRICAN SALE + NEW YORK, March 10 - Newmont Mining Corp will seek +favorable terms for sale of its South African investments, the +proxy statement for its annual meeting said. + Recommending that shareholders vote against a proposal +calling expeditious withdrawal from South Africa, the proxy +said "a quick sale could be akin to abandonment" because of the +depressed state of metal mining stocks and exchange rates on +capital withdrawals from South Africa. + The proxy said the company gave close consideration to +alternatives to the continued holdings of four existing South +African metal mining investments during the past year. + Pointing out "a measurable number of investors incline to +support" resolutions calling for South African divestment as +part of their effort to avoid pressure to sell a given stock, +the company said "this largely unspoken agenda of many +supporters of disinvestment does receive attention by the +corporation." + Because of this, Newmont Mining said it "is prepared to +consider, and will seek, favorable terms for sale of its South +African investments," but asked stockholders to reject the +resolution calling for withdrawal and leave the matter to the +continuing judgment of management. + Reuter + + + +30-MAR-1987 15:00:51.14 +crude +venezuela + + + + + +Y +f2311reute +u f BC-VENEZ- 03-30 0109 + +VENEZUELA WANTS TO BOOST ITS REFINING CAPACITY + SAN ANTONIO, TEXAS, March 30 - Venezuela's state oil +company Petroleos de Venezuela S.A. wants to raise its +worldwide refining capacity by 150,000 barrels of per day, a +company official attending the National Petroleum Refiners +Association meeting here said. + He declined to be identified but said PdVSA has the +capacity to refine about 650,000 bpd of crude oil from refining +centers +in Venezuela, Sweden, West Germany, Belgium, and the United +States. The company recently purchased a 50 pct stake in the +Corpus Christi, Texas refinery of Champlin Petroleum Co, a +subsidiary of Union Pacific Corp <UNP>. + Earlier it bought a similar stake in the Lake Charles, La +refinery owned by Citgo Petroleum Corp, a unit of Southland +Corp <SLC>. + According to the official, Venezuela is searching +worldwide for the additional refining capacity but he did not +mention where the company was looking. + Refineries abroad, he said, guarantee a refining outlet for +Venezuelan crude oil while ensuring stability of supply to +refiners. + He said Venezuela currently produces about 1.4 mln bpd of +crude oil, which is in line with its 1.495 bpd OPEC ceiling. + Reuter + + + +30-MAR-1987 15:02:17.84 + +usa + + + + + +F +f2316reute +r f BC-AUDI-OFFERS-CASH-INCE 03-30 0132 + +AUDI OFFERS CASH INCENTIVE TO CURRENT OWNERS + TROY, MICH., March 30 - Audi of America Inc said it +introduced the "Audi Private Purchase Plan" in which it will +offer 5,000 dlr purchase certificates exclusively to current +owners of 1984-86 Audi 5000 vehicles. + It said owners must apply the certificates toward purchase +or lease of any new 1987 Audi 5000 series vehicle. + The program will run between April 1 and June 30, and more +than 150,000 certificates will be mailed. + A company spokesman said eligible owners need not trade in +their old cars to take advantage of the offer. + He also said the scheme was not prompted by the fact that +Audi had to recall thousands of its cars earlier this year to +correct a possible defect that caused some of the cars to +accelerate suddenly. + Reuter + + + +30-MAR-1987 15:05:58.06 +earn +usa + + + + + +F +f2335reute +r f BC-PRIMEBANK-<PMBK>-SETS 03-30 0037 + +PRIMEBANK <PMBK> SETS 10 PCT STOCK DIVIDEND + GRAND RAPIDS, Mich., March 30 - PrimeBank Federal Savings +Bank said its board declared a 10 pct stock dividend to be +distributed about April 15 to holders or record March 31. + Reuter + + + +30-MAR-1987 15:06:30.04 +earn +usa + + + + + +F +f2336reute +d f BC-AMERICAN-LOCKER-GROUP 03-30 0074 + +AMERICAN LOCKER GROUP INC <ALGI> 4TH QTR NET + JAMESTOWN, N.Y., March 30 - + Shr profit 23 cts vs loss six cts + Net profit 319,564 vs loss 84,203 + Sales 6,419,230 vs 5,583,560 + Year + Shr profit 1.11 dlrs vs profit 43 cts + Net profit 1,582,125 vs profit 654,083 + Sales 26.2 mln vs 22.6 mln + NOTE: Full year 1985 includes gains of two cts per share +from discontinued operations and four cts per share from +disposal of assets. + Reuter + + + +30-MAR-1987 15:15:20.33 +acq +usa + + + + + +F +f2351reute +b f BC-TAFT 03-30 0087 + +BASS GROUP SAYS IT HAS HAD TALKS ON TAFT <TFB> + WASHINGTON, March 30 - A group led by members of the +wealthy Bass family of Fort Worth, Texas, which holds a 24.9 +pct stake in Taft Broadcasting Co, said it has had talks about +taking part in a move to take control of the company. + In a filing with the Securities and Exchange Commission, +the group said it has had discussions with other Taft +stockholders and some company managers and directors +"concerning participation in a group to acquire control" of the +company. + The Bass group, which did not identify any of the other +people with whom it said it has had talks, said it plans to +continue evaluating Taft and "will be involved in further +discussions relating to the future control and direction" of +the company. + The group, which holds 2,291,210 Taft common shares, said +its members may buy more shares of Taft common stock, or may +decide to sell some or all of its stake. + On Friday Taft said it would negotiate with a group led by +its vice chairman, Dudley Taft, and a Rhode Island investment +firm, which had offered 150 dlrs a share for the company. + The Dudley Taft group, Theta Corp, which also includes +Narragansett Capital Corp, a Providence, R.I., investment firm, +is seeking to take the company private in a leveraged buyout +valued at 1.38 billion dlrs. + Besides the Bass group, another major Taft shareholder, +Cincinnati, Ohio, financier Carl Lindner, has also said he has +had talks about increasing his stake in the company, taking +part in a takeover effort, or launching one himself. + Lindner controls 1,489,298 shares of Taft common stock, or +16.2 pct of the total. + Reuter + + + +30-MAR-1987 15:16:34.99 +iron-steel +usa + + + + + +MQ FQ +f2355reute +u f BC-us-steel-production 03-30 0077 + +U.S. STEEL PRODUCTION ROSE 1.3 PCT IN WEEK + New York, March 30 - Steel production rose +1.3 pct to 1,696,000 short tons in the +week ended March 28 from 1,675,000 short +tons, the American Iron and Steel Institute +reported + Production so far this year was 18,810,000 tons adjusted off +14.6 pct from 22,016,000 tons +produced by the nations mills a year ago. + Utilization for the week of March 28 was 78.7 pct and for +the week of March 21 was was 77.8 pct. + Reuter + + + +30-MAR-1987 15:17:57.62 +earn +usa + + + + + +F +f2366reute +r f BC-NORTH-AMERICAN-GROUP 03-30 0070 + +NORTH AMERICAN GROUP <NAMG> 4TH QTR OPER LOSS + CHICAGO, March 30 - + Oper shr loss 12 cts vs loss 10 cts + Oper net loss 474,270 vs loss 369,848 + Revs 202,500 vs 111,210 + Avg shrs 3,904,373 vs 3,495,579 + Year + Oper shr loss 28 cts vs loss 46 cts + Oper net loss 1,069,550 vs loss 893,612 + Revs 408,031 vs 438,933 + Avg shrs 3,785,607 vs 1,944,627 + NOTE: Full name is North American Group Ltd + Earnings exclude losses on reorganization expenses of +33,453 dlrs, or one ct a share vs 59,520 dlrs, or two cts a sh +are in the quarter and losses of 237,859 dlrs, or six cts a +share vs 413,444 dlrs, or 21 cts a share for the year + Earnings exclude gains on discontinued operations of +147,671, or four cts a share in the 1985 quarter and gains of +760,603 dlrs, or 20 cts a share vs 520,200 dlrs, or 27 cts a +share for the year + Reuter + + + +30-MAR-1987 15:18:39.33 + +usa + + + + + +F +f2371reute +u f BC-PAY-'N-PAK-<PNP>-TO-E 03-30 0079 + +PAY 'N PAK <PNP> TO EXPLORE ITS ALTERNATIVES + KENT, Wash., March 30 - Pay 'N Pak Stores Inc said it +intends to explore all alternatives for the purpose of +maximizing its value to stockholders. + The company said it also retained Salomon Brothers Inc as +its financial advisor to assist it in this regard. + Last week investor Paul Bilzerian reported that he holds a +7.2 pct stake in Pay 'N Pak and is considering seeking control +of the retail building materials firm. + In a filing with the Securities and Exchange Commission +Bilzerian said he and a Tampa, Fla., investment firm he +controls called Bicoastal Financial Corp, may acquire +additional Pay 'N Pak shares, or they may seek to acquire one +or more positions on the company's board. + He also said in the filing that he may attempt to obtain a +controlling interest through a tender offer or otherwise. + Reuter + + + +30-MAR-1987 15:20:25.66 + +usa + + + + + +RM A +f2377reute +r f BC-SOCIETY-FOR-SAVINGS-< 03-30 0111 + +SOCIETY FOR SAVINGS <SOCS> TO OFFER NOTES + NEW YORK, March 30 - Society for Savings said it will offer +up to 100 mln dlrs of medium-term notes with maturites of one +to five years through Goldman, Sachs and Co and Shearson Lehman +Brothers Inc. + The notes will be supported by an irrevocable letter of +credit by the Federal Home Loan Bank of Boston. Each note will +bear interest at a fixed-rate or variable rate formula +established at the time of issuance, Society for Savings said. + Bankers Trust Co will act as fiscal and paying agent. +Non-redeemable to maturity, the notes will be issued only in +registered form and in minimum denomiations of 100,000 dlrs. + Reuter + + + +30-MAR-1987 15:20:32.84 +earn +usa + + + + + +F +f2378reute +r f BC-<OXOCO-INC>-YEAR-LOSS 03-30 0072 + +<OXOCO INC> YEAR LOSS + HOUSTON, March 30 - + Oper shr loss 6.68 dlrs vs loss 9.95 dlrs + Oper net loss 53.9 mln vs loss 69.8 mln + Revs 16.5 mln vs 33.2 mln + Avg shrs 8,329,492 vs 7,271,668 + NOTE: 1986 excludes loss 12.9 mln for discontinued +compressor operations vs loss 14.9 mln year prior. + 1986 excludes gain of 98.7 mln for extinguishment of debt +from company's chapter 11 filing and subsequent reorganization. + Reuter + + + +30-MAR-1987 15:20:48.00 +earn +usa + + + + + +F +f2380reute +d f BC-TEECO-PROPERTIES-L.P. 03-30 0094 + +TEECO PROPERTIES L.P. OPER INCOME DOWN + NEW YORK, March 30 - <Teeco Properties L.P.> said the +partnership recorded income from operations for 1986 of 140,000 +dlrs, or two cts a unit. + The partnerhsip said this compared to 1985 figures of +660,000 dlrs, or 10 cts a unit. + Results of operations between both years is not comparable +since the partnership's principle objective is to sell or +dispose of its assets and distribute proceeds to unit holders, +according to the partnership. + It said the number of units outstanding for both years is +6,479,516. + + Reuter + + + +30-MAR-1987 15:20:52.65 +earn +usa + + + + + +F +f2381reute +d f BC-BROUGHER-INSURANCE-GR 03-30 0042 + +BROUGHER INSURANCE GROUP INC<BIGI> 4TH QTR LOSS + GREENWOOD, Ind., March 30 - + Shr loss nine cts vs profit 20 cts + Net loss 257,157 vs profit 414,890 + Year + Shr profit 54 cts vs profit 1.05 dlrs + Net profit 1,295,104 vs profit 2,140,673 + Reuter + + + +30-MAR-1987 15:22:33.92 + +usa + + + + + +F +f2385reute +d f AM-COURT-CARS 03-30 0099 + +HIGH COURT DECLINES TO REVIEW AIR BAG RULE + WASHINGTON, March 30 - The Supreme Court declined to review +a federal regulation requiring automobile manufacturers to +phase in automatic seat belts or air bags for new cars sold in +the United States. + The Department of Transportation (DOT) rule required that +the safety devices be installed, for the first time, on 10 pct +of this year's model cars. All new cars must have the devices +by the 1990-model year. + The regulation, however, can be rescinded if states with +two-thirds of the U.S. population adopt mandatory seat belt-use +laws by 1989. + Reuter + + + +30-MAR-1987 15:24:34.95 + +uk + + + + + +A +f2395reute +w f BC-TRADE-BODY-SETS-NEW-R 03-30 0105 + +TRADE BODY SETS NEW RULES FOR EURODLR MANAGERS + London, March 30 - The International Primary Market Makers +Association, a trade organisation, said its board last week +adopted new rules recommending lead managers of eurodollar bond +issues make a market in that security for 12 months. + Currently, while there is an implied obligation on the part +of firms to make markets in issues they underwrite, there is no +formal obligation to do so. + Christopher Sibson, secretary general of IPMA, in +explaining why the recommendation was adopted, said "It is aimed +at the problem of the lead manager who does a deal and +disappears." + Sibson said the organization cannot force its members to +adhere to the rule. "We're under no illusions about the legal +binding force of these recommendations," he said. + Lead managers have occasionally abandoned efforts to +support an unprofitable issue just a short while after it has +been offered, leaving investors and smaller firms with no one +to buy it back from them. + Most recently, when prices of perpetual floating rates +notes (FRNs) suddenly plunged, most market makers abandoned the +securities altogether, leaving investors stuck with about 17 +billion dlrs worth of unmarketable securities on their books. + Sibson noted that the recommendation adopted by the board +only applies to fixed-rate dollar issues and would not have +helped the floating rate sector out of its current crisis. + Among other measures, the IPMA also decided that the +criteria for membership should be tightened to exclude some of +the smaller firms. + Under the new rules, a firm must be the book running lead +manager during the two preceding years of 12 internationally +distributed debt issues denominated in U.S. Dlrs or in one of +eight other major currencies. + The former requirement called for three lead-managed +issues. Sibson said he expects the tighter entrance +requirements to pare 3he current list of 67 members down by six +to 10 members. + Smaller firms have criticized IPMA's efforts to restrict +membership to the larger firms, saying it is anti-competitive +and that it reinforces the big firms' already large market +share. + "Belonging to IPMA carries a certain amount of prestige with +borrowers," said a dealer at a small foreign bank. "The borrower +says to himself, "Well I can travel economy or I can travel +first class,'" he said. + Reuter + + + +30-MAR-1987 15:26:11.53 +iron-steel +usa + + + + + +F +f2401reute +r f BC-CSC-INDUSTRIES-UNIT-T 03-30 0091 + +CSC INDUSTRIES UNIT TO INCREASE PRICES + WARREN, Ohio, March 30 - Copperweld Steel Co <CPSL>, a +subsidiary of CSC Industries Inc., said it will increase from +market price levels its bar, semi-finished and leaded products +effective July One. + Hot rolled and cold finished bar wil be increase 25 dlrs +per net ton, while semi-finished products will be increased 15 +dlrs per net ton, the company said. + Anticipated higher energy and raw material costs, combined +with current market trends, were cited by the company as +reasons for the increases. + Reuter + + + +30-MAR-1987 15:26:25.70 +grainwheat +usa + + + + + +C G +f2402reute +u f BC-USDA-TO-UPDATE-WINTER 03-30 0098 + +USDA TO UPDATE WINTER WHEAT ACREAGE TOMORROW + WASHINGTON, March 30 - The U.S. Agriculture Department said +it will update its estimate of winter wheat seeded acreage in +the prospective planting report, scheduled for release at 1500 +est (2100 gmt) tomorrow, March 31. + The original estimate of seedings of winter wheat was +published in January. + It said the new survey is possible because of the new +integrated nationwide survey program that uses probability +sampling procedures that combine information from farmers +operating in selected areas and farmers identified on special +lists. + Reuter + + + +30-MAR-1987 15:27:02.85 +acq +usa + + + + + +F +f2404reute +b f BC-SANTA-FE-<SFX>-AWARE 03-30 0121 + +SANTA FE <SFX> AWARE OF HENLEY <HENG> STAKE + CHICAGO, March 30 - Santa Fe Southern Pacific Corp said it +has discussed with Henley Group that company's almost five pct +stake and was told the holdings are for investment purposes. + "We have confirmed with the Henley Group that they own +approximately 7.9 mln shares of Santa Fe Southern Pacific +common stock. They have informed me that they like our company +and purchased the stock last year for investment purposes," +Santa Fe chairman John Schmidt said in a statement. + Henley late Friday filed a 10-K report with the Securities +and Exchange Commission concerning the Santa Fe stake. + Earlier Santa Fe's stock was up 4-7/8 to 41 before slipping +to be up 1-7/8 at 38. + Reuter + + + +30-MAR-1987 15:29:30.70 + +usa + + + + + +F +f2406reute +r f BC-OXOCO-CONCLUDES-PRIVA 03-30 0097 + +OXOCO CONCLUDES PRIVATE SALE OF NEW COMMON + HOUSTON, March 30 - Oxoco Inc said it concluded the private +placement of 3,906,250 shares of its new common stock at an +average purchase price of 1.28 dlrs per share for a cash +payment of five mln dlrs. + Oxoco said the sale was to a group of venture capital +investors led by Hambrecht and Quist of San Francisco. + It said the venture capitalists now own 71.6 pct of the +outstanding stock of the company. + In addition, Andrew Loomis and Michael McGovern were +elected chairman and co-chairman, respectively, of the company, +it said. + Reuter + + + +30-MAR-1987 15:29:47.66 +sugar +usa + + + + + +C T +f2407reute +b f BC-sugar-imports 03-30 0122 + +U.S. SUGAR IMPORTS DOWN IN LATEST WEEK - USDA + WASHINGTON, March 30 - Sugar imports subject to the U.S. +sugar import quota during the week ended March 6 totaled 25,192 +short tons versus 29,043 tons the previous week, the +Agriculture Department said. + Cumulative imports now total 130,804 tons, it said. + The sugar import quota for the 1987 quota year +(January-December) has been set at 1,001,430 short tons +compared with 1,850,000 tons in the 1986 quota year, which was +extended three months to December 31. + The department said the Customs Service reported that +weekly and cumulative imports are reported on an actual weight +basis and when final polarizations are received, cumulative +import data are adjusted accordingly. + Reuter + + + +30-MAR-1987 15:39:21.47 + +usa + + + + + +F +f2427reute +u f BC-TRANSAMERICAN-FILES-A 03-30 0092 + +TRANSAMERICAN FILES AMENDED REORGANIZATION PLAN + HOUSTON, March 30 - TransAmerican Natural Gas Corp, which +has been operating under Chapter 11 bankruptcy protection since +January 1983, said it filed an amended and restated negotiated +plan of reorganization. + A hearing on the adequacy of the disclosure statement is +scheduled for April 29 in the U.S. Bankruptcy Court for the +Southern District of Texas. + Basic terms of the amended and restated negotiated plan +have not changed from the original plan filed last October, the +company said. + The amended filing reflects adding ancillary documents to +the plan filed in October, it said. + Assuming the plan is found adequate on April 29, +TransAmerican would then seek acceptance from creditors which +is relatively assured since they participated in the +negotiations, the company said. + Liabilities in excess of one billion dlrs are being +reorganized under the amended plan which provides for full +debt-repayment to secured bank lenders. + Unsecured creditors would receive either 100 pct repayment, +secured by liens on assets, or one-time lump sum payments of 25 +to 35 cts on the dollar, in cash, shortly after confirmation of +the plan by the court. + TransAmerican is vigorously resisting efforts by Coastal +Corp <CGP> to acquire its assets through a subsequent plan of +liquidation. + The spokesman said the company is confident its plan will +be confirmed and is optimistic that it will emerge from Chapter +11 as early ninety days after the April 29 confirmation. + A Coastal spokesman said it will file a plan in April with +the court and will request the court to review its plan. + On March 17, the company said that as a creditor, which is +owed 625,000 dlrs, it has a right to file its own plan which +will better serve the other creditors in a shorter time. + A TransAmerican spokesman said the net worth of Coastal's +offer is less than 25 pct of the fair market value of +Transamerican's assets which are in excess of one billion dlrs. + + Reuter + + + +30-MAR-1987 15:44:23.25 + +usa + + + + + +F +f2434reute +r f BC-TEXTRON-<TXT>-TO-REPA 03-30 0114 + +TEXTRON <TXT> TO REPAY DEBT THROUGH ASSET SALES + PROVIDENCE, R.I., March 30 - Texton Inc said it intends to +repay a substantial portion of the debt generated to acquire +Ex-Cell-O Corp last year through internally generated cash and +proceeds from the sale of assets. + Textron financed the acquisition by borrowing about one +billion dlrs under promissory notes, subsequently refinanced +through the sale of commercial paper and bank borrowings. + The large diversified conglomerate with operations ranging +from defense to consumer and financial services, said in its +annual report that it has not yet identified the units, other +than its Gorham division, it expects to sell. + Textron said it did expect to identify the units it intends +to sell during the next year. It said the sales are expected to +reduce income from continuing operations as the units' earnings +will exceed the interest on the debt retired with the proceeds +of the sales. + It also said it plans to "return to a more conservative +balance sheet ratio of debt-to-capital," through asset sales +and increasing cash flow from continuing operations. + It also said it will continue to examine "large acquisition +opportunities," while "pruning" operations no longer expected +to meet its strategic requirements. + Reuter + + + +30-MAR-1987 15:51:12.26 +earn +usa + + + + + +F +f2449reute +r f BC-TEMPLETON-ENERGY-INC 03-30 0064 + +TEMPLETON ENERGY INC <TMPL> 4TH QTR NET + HOUSTON, March 30 - + Shr profit four cts vs loss six cts + Net profit 967,000 vs loss 1,219,000 + Revs 10.1 mln vs 4.5 mln + Year + Shr profit three cts vs loss five cts + Net profit 688,000 vs 982,000 + Revs 24.6 mln vs 16.3 mln + NOTE: 1986 includes results of Louisiana Energy and +Development Corp acquired in November 1986. + Reuter + + + +30-MAR-1987 15:52:04.99 +earn +usa + + + + + +F +f2450reute +r f BC-AEL-INDUSTRIES-<AELNA 03-30 0063 + +AEL INDUSTRIES <AELNA> 4TH QTR FEB 27 NET + LANSDALE, Pa., March 30 - + Shr 66 cts vs 33 cts + Net 2,955,000 vs 1,563,000 + Revs 26.1 mln vs 23.9 mln + 12 mths + Shr 74 cts vs 1.01 dlrs + Net 3,321,000 vs 4,739,000 + Revs 108.4 mln vs 104.9 mln + NOTE: year 1987 includes charge of 818,000 dlrs, or 18 cts +per share, for sale of Elisra Electronic Systems Ltd. + Reuter + + + +30-MAR-1987 15:54:36.57 +acq +usa + + + + + +F +f2452reute +r f BC-AMOSKEAG-<AMKG>-TAKEO 03-30 0084 + +AMOSKEAG <AMKG> TAKEOVER BLOCKED BY COURT + MANCHESTER, N.H., March 30 - Amoskeag Bank Shares Inc said +the New Hampshire Supreme Court overturned its proposed +acquisition of Portsmouth Savings Bank in a three-two vote. + The acquisition had been opposed by some depositors, who +filed an action to block the takeover. + "We will respond to this news as soon as we have had an +opportunity to analyze the decision, and any and all options +available to us," chairman William Bushnell said in a +statement. + Reuter + + + +30-MAR-1987 15:55:50.23 +earn +usa + + + + + +F +f2454reute +d f BC-METROMAIL-<MTMA>-PRED 03-30 0117 + +METROMAIL <MTMA> PREDICTS FLAT EARNINGS + LINCOLN, Neb., March 30 - Metromail Corp said it expects +flat operating profits for its 1987 fiscal year ending May 31 +with last fiscal year's earnings from operations of 9,943,000 +dlrs, or 1.05 dlrs a share. + The company said the flat results will be due to higher +than normal expenditures during the fourth quarter for +expansion of its data processing capabilities. + Earlier, Metromail reported fiscal 1987 third quarter +earnings of 2.4 mln dlrs, or 25 cts a share, versus three mln +dlrs, or 32 cts a share, the prior third quarter, and nine +months net of 7.2 mln dlrs, or 76 cts a share, versus 7.8 mln +dlrs, or 82 cts a share the prior nine months. + Reuter + + + +30-MAR-1987 15:56:28.52 + +usa + + + + + +F +f2455reute +r f BC-APPLE-<AAPL>-EXPANDS 03-30 0088 + +APPLE <AAPL> EXPANDS NETWORK CAPABILITIES + CUPERTINO, Calif., March 30 - Apple Computer Inc said it +has extended the ability of the Apple MacIntosh personal +computer family to commmunicate over <Northern Telecom Ltd's> +Meridian SL-1 integrated services network. + The new capabilities include linking separate AppleTalk +networks, dial-up remote use of LaserWriter printers, one step +file transfer and conversion and Memorybank 485, a new 485 +megabyte storage subsystem for use with MacIntosh personal +computers, Apple said. + Reuter + + + +30-MAR-1987 15:58:33.75 +acq +usa + + + + + +F +f2457reute +u f BC-BALL-<BLL>-ENDS-TALKS 03-30 0056 + +BALL <BLL> ENDS TALKS WITH MONSANTO <MTC> + MUNCIE, IND., March 30 - Ball Corp said it was unable to +complete negotiations to acquire the plastic container business +of Monsanto Co. + It said the two companies had entered into exclusive +negotiations last October. + Neither company provided details on why the talks were +terminated. + Reuter + + + +30-MAR-1987 15:58:44.17 +oilseedrapeseed +japancanada + + + + + +C G +f2458reute +u f BC-JAPAN-BUYS-CANADIAN-R 03-30 0030 + +JAPAN BUYS CANADIAN RAPESEED + WINNIPEG, March 30 - Japanese crushers bought 2,000 tonnes +of Canadian rapeseed in export business overnight for May +shipment, trade sources said. + Reuter + + + +30-MAR-1987 15:59:18.08 + +usa + + + + + +F +f2459reute +u f BC-NEWMONT-MINING-<NEM> 03-30 0107 + +NEWMONT MINING <NEM> SETS HIGHER SPENDING IN 1987 + NEW YORK, March 30 - Newmont Mining Corp estimates its 1987 +capital spending at 137 mln dlrs, its annual report said. + A company spokesman said this figure excludes <Magma Copper +Co> and compares to spending of about 80 mln dlrs in 1986 +excluding the 45 mln dlrs spent on Magma operations. As +previously announced, Newmont is distributing 80 pct of Magma's +stock to its shareholders in the form of a dividend. + The report also said Newmont Mining increased its ownership +of Du Pont Co <DD> stock during 1986 to 5,970,141 shares at +year end from 5,250,376 shares a year earlier. + Newmont's annual report said the company held 2.5 pct of Du +Pont's stock at the end of 1986, up from 2.2 pct a year +earlier. + The report also said Newmont's proven oil reserves declined +to 7,970,000 barrels at the end of 1986 from 8,530,000 barrels +a year earlier and its natural gas reserves declined to 271.48 +billion cubic feet from 274.82 billion at the end of 1985. + Reuter + + + +30-MAR-1987 15:59:24.50 + +usa + + + + + +F +f2460reute +r f BC-3COM-CORP-<COMS>-INTR 03-30 0085 + +3COM CORP <COMS> INTRODUCES NEW WORKSTATION + SANTA CLARA, Calif., March 30 - 3Com Corp said it +introduced a new network workstation for business applications. + The product, called 3Station, is the first in a family of +network workstations, which will later include a Token Ring +version, the company said. + It said the 3Station is an IBM-compatible 80286-based +Ethernet product which can be integrated with personal +computers on a network. + The company also said it plans to begin shipments on May +15. + Reuter + + + +30-MAR-1987 16:00:03.76 + +usa + + + + + +A RM +f2462reute +r f BC-S/P-AFFIRMS-BANNER-<B 03-30 0110 + +S/P AFFIRMS BANNER <BNR>, LOWERS REXNORD <REX> + NEW YORK, March 30 - Standard and Poor's Corp said it +affirmed Banner Industries Inc's 135 mln dlrs of B-minus +subordinated debt following its purchase of Rexnord Inc. + Rexnord's 50 mln dlrs of 12-3/4 pct debentures of 1994 were +cut to B from A-minus to reflect the merger with Banner. + While increasing Banner's size and diversity, S and P said +the transaction heightens financial risk, with debt to capital +rising to more than 90 pct. + Near-term earnings and cash flow protection will weaken +from the acquisition, though Banner's plans to sell some +Rexnord assets will reduce debt for the medium term. + Reuter + + + +30-MAR-1987 16:00:28.68 +acq +usa + + + + + +F +f2463reute +d f BC-REEF-ENERGY-<RFEN>-EN 03-30 0098 + +REEF ENERGY <RFEN> ENTERS PIPELINE AGREEMENT + TRAVERSE CITY, MICH., March 30 - Reef Energy Corp said its +board entered into agreements with Penteco Corp, a private +Tulsa-based company, to buy a 12-pct interest in the general +partnership of Penteco East Central Pipeline and a 10-pct +interest in Lincoln Gas and Marketing Corp. + Penteco East is a gas gathering and transmission system in +southern Kansas and northern Oklahoma. + It said Penteco in turn has purchased one mln shares of +Reef common and taken options for the purchase of another two +mln shares over the next 36 months. + Reuter + + + +30-MAR-1987 16:00:33.29 +earn +usa + + + + + +F +f2464reute +s f BC-AMERON-INC-<AMN>-QTLY 03-30 0025 + +AMERON INC <AMN> QTLY DIVIDEND + MONTEREY PARK, Calif., March 30 - + Shr 24 cts vs 24 cts prior qtr + Pay May 15 + Record April 24 + + Reuter + + + +30-MAR-1987 16:00:39.33 +earn +usa + + + + + +F +f2465reute +d f BC-JOHNSON-ELECTRONICS-I 03-30 0070 + +JOHNSON ELECTRONICS INC <JHSN> 4TH QTR LOSS + WINTER PARK, Fla., March 30 - + Shr loss three cts vs profit eight cts + Net loss 35,000 vs profit 128,000 + Revs 1,133,000 vs 1,528,000 + Year + Shr profit four cts vs profit 21 cts + Net profit 72,000 vs profit 339,000 + Revs 4,837,000 vs 4,500,000 + NOTE: 1985 net income included an after tax gain of 195,000 +or 12 cts per share on sale of real property. + Reuter + + + +30-MAR-1987 16:01:55.85 +money-fx +usa + + + + + +A RM +f2469reute +u f BC-TREASURY-BALANCES-AT 03-30 0084 + +TREASURY BALANCES AT FED FELL ON MARCH 27 + WASHINGTON, March 30 - Treasury balances at the Federal +Reserve fell on March 27 to 2.424 billion dlrs from 2.508 +billion dlrs on the previous business day, the Treasury said in +its latest budget statement. + Balances in tax and loan note accounts fell to 9.706 +billion dlrs from 10.786 billion dlrs on the same respective +days. + The Treasury's operating cash balance totaled 12.131 +billion dlrs on March 27 compared with 13.283 billion dlrs on +March 26. + Reuter + + + +30-MAR-1987 16:06:38.27 +earn +usa + + + + + +F +f2480reute +r f BC-MORRISON-INC-<MORR>-3 03-30 0049 + +MORRISON INC <MORR> 3RD QTR FEB 28 NET + MOBILE, Ala., March 30 - + Shr 35 cts vs 29 cts + Qtly div 12 cts vs 12 cts prior qtr + Net 5,036,000 vs 4,165,000 + Revs 147.6 mln vs 132.4 mln + Nine mths + Shr 1.12 dlrs vs one dlr + Net 16.1 mln vs 14.4 mln + Revs 433.4 mln vs 385 mln + NOTE: Per share data reflect March 1986 five pct stock +distribution. Cash dividend is payable April 30 to holders of +record April 15. + Reuter + + + +30-MAR-1987 16:06:53.63 + +usa + + + + + +C G +f2481reute +d f BC-FOREIGN-OWNERSHIP-OF 03-30 0127 + +FOREIGN OWNERSHIP OF U.S. FARMLAND UP -- USDA + WASHINGTON, March 30 - Non-U.S. citizens held 12.4 mln +acres of privately owned U.S. agricultural land as of December +31, slightly less than one pct of the total agricultural land, +but 369,000 acres above the foreign ownership at the end of +1985, the U.S. Agriculture Department said. + The department said forest land accounted for 52 pct of all +foreign-owned acreage, cropland 17 pct, pastures and other +agricultural land 26 pct and non-agricultural and unreported +uses, five pct. + Corporations owned 79 pct of the foreign-held acreage, +parternships 11 pct, and individuals eight pct, the department +said. The remaining two pct was held by estates, trusts, +associations, institutions and others, it said. + Reuter + + + +30-MAR-1987 16:07:10.68 + +usasouth-africa + + + + + +F +f2483reute +u f BC-U.S.-GROUP-ASKS-SPECI 03-30 0101 + +U.S. GROUP ASKS SPECIAL ROYAL DUTCH<RD> MEETING + NEW YORK, March 30 - A group of U.S. investors opposed to +Royal Dutch Shell Petroleum Co's South African policies plans +to seek a special shareholders meeting to discuss their +complaints. + Representatives of the American Baptist Churches and the +New York City Teachers Retirement System said the company has +refused to include their proposals in proxy material prepared +for the annual meeting in May. + The group said its proposals call for an end to sales by +Royal Dutch to the South African police and military and +withdrawal from South Africa. + + Reuter + + + +30-MAR-1987 16:08:25.90 +acq +usa + + + + + +F +f2488reute +r f BC-VANDERBILT-<VAGO>-TO 03-30 0116 + +VANDERBILT <VAGO> TO RAISE COMMON, MERGE + LAS VEGAS, March 30 - Vanderbilt Gold Corp said +shareholders at a special meeting approved its reincorporation +in Delaware, an increase in authorized common to 25 mln shares +from 12 mln shares, and a non-qualified stock option plan. + It also said shareholders approved the merger of Morning +Star Mine interests held by six corporations in exchange for +issuing 2,098,602 shares of its common. It said the acquisition +brings its ownership in Morning to over 94 pct and it intends +to acquire the remaining interests before mid year. + It said its plans call for 1987 production of 30,000 ounces +of gold with product costs per ounce at about 200 dlrs. + Reuter + + + +30-MAR-1987 16:10:35.89 +cotton +usa + + + + + +C G +f2491reute +u f BC-/LITTLE-RISK-SEEN-FOR 03-30 0142 + +LITTLE RISK SEEN FOR TEXAS COTTON FROM COLD + New York, March 30 - Texas' cotton crop stands little +chance of damage from frigid temperatures expected tonight in +that state, as very little cotton has been planted, according +to Texas agricultural sources and cotton market analysts. + "It's still pretty early for cotton planting. Only six pct +of the crop was planted as of last week," said Doug Stillmann, +a statistician at the Texas Agricultural Statistic Service in +Austin, a division of the U.S. Agriculture Department. + Stillmann and other cotton market sources said planting had +begun in the Rio Grande Valley and South Texas areas only, with +planting in the crucial high and low plains areas not slated to +begin until next month. The high and low plains accounted for +60 pct of the 2.5 mln bales produced in Texas last year, +Stillmann said. + Temperatures tonight in most of Texas are expected to drop +to freezing to the low 20s, although the lower Rio Grande +Valley may see more moderate readings in the middle 30s, +according to meteorologists at Accu-Weather Inc. + The price of new-crop cotton on the New York cotton futures +market rallied today on weather-related fears. + Reuter + + + +30-MAR-1987 16:11:45.14 +grain +usa + + + + + +C G +f2493reute +u f BC-REPORT-ON-EXPORT-MARK 03-30 0054 + +REPORT ON EXPORT MARKETS FOR U.S. GRAIN DELAYED + WASHINGTON, March 30 - The U.S. Agriculture Department's +report on Export Markets for U.S. Grain, scheudled for release +today, has been delayed until Wednesday, April 1, a department +spokeswoman said. + No reason was given for the delay in releasing the monthly +report. + Reuter + + + +30-MAR-1987 16:12:16.53 +acq + + + + + + +F +f2497reute +b f BC-******BILZERIAN-TELLS 03-30 0010 + +******BILZERIAN TELLS SEC HE UPS PAY 'N PAK STAKE TO 9.9 PCT +Blah blah blah. + + + + + +30-MAR-1987 16:13:10.33 + +usa + + + + + +F +f2501reute +d f BC-ALLIED-SIGNAL-<ALD>-G 03-30 0037 + +ALLIED-SIGNAL <ALD> GETS 38.6 MLN DLR CONTRACT + WASHINGTON, March 30 - Allied Corp, a division of +Allied-Signal Inc, has received a 38.6 mln dlr contract for +work on F-15 aircraft avionics maintenance, the Air Force said. + reuter + + + +30-MAR-1987 16:16:09.66 + +usa + + + + + +F +f2503reute +r f BC-MORRISON-<MORR>-SETS 03-30 0055 + +MORRISON <MORR> SETS SHAREHOLDER RIGHTS PLAN + MOBILE, Ala., March 30 - Morrison Inc said its board +adopted a shareholder rights plan to deter any possible hostile +takeover of the company. + It said details of the plan will be released shortly. A +record date of April 10 was set for the distribution of the +rights to shareholders. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-012.sgm b/src/test/data/reuters-21578/reut2-012.sgm new file mode 100644 index 00000000000..4c1d7385683 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-012.sgm @@ -0,0 +1,2010 @@ + + + 1-APR-1987 11:04:07.01 +earn +usa + + + + + + +F +f1288reute +s f BC-REPUBLIC-SAVINGS-AND 04-01 0039 + +REPUBLIC SAVINGS AND LOAN <RSLA> SETS DIVIDEND + MILWAUKEE, Wis., April 1 - + Qtly div 30 cts vs 30 cts prior + Pay April 27 + Record April 13 + NOTE: Company's full name is Republic Savings and Loan +Association of Wisconsin. + Reuter + + + + 1-APR-1987 11:04:40.35 +wheatcornsoybeangrainoilseed +usaussr + + + + + + +C G +f1292reute +u f BC-/SHULTZ-USSR-TRIP-FUE 04-01 0108 + +SHULTZ USSR TRIP FUELS TALK OF EEP WHEAT OFFER + By Nelson Graves, Reuters + WASHINGTON, April 1 - Speculation the United States will +offer subsidized wheat to the Soviet Union appears to have +reached a new level of intensity in the run-up to Secretary of +State George Shultz' visit later this month to Moscow. + Rumors of an impending deal have coursed through wheat +markets since officials from the two countries held their +customary, semi-annual grain talks in February. Moscow's +decision at that time to reenter the U.S. corn market +strengthened the perception of warming farm trade prospects. + Shultz is set to arrive in Moscow April 13. + Shultz' statement two weeks ago that he would not stand in +the way of a wheat subsidy offer under the Export Enhancement +Program, EEP, coupled with the announcement of his visit to +Moscow, was interpreted by many grain trade representatives +here as a clear signal that the Reagan administration was +preparing an offer. + Administration officials -- in and out of the U.S. +Agriculture Department -- have been extremely tight-lipped +about the prospects of a subsidy offer. + But USDA officials for the most part have abandoned the +contention the proposal is dormant, suggesting that an offer, +while not a "done deal," is a live possibility. + Prominent U.S. grain trade representatives -- many of whom +asked not to be identified -- continue to maintain that an +offer to subsidize four mln tonnes of wheat is imminent. + Others, who one month ago claimed a deal was not possible, +are saying they would not rule one out. + Rep. Pat Roberts, R-Kan., yesterday went so far as to +predict a subsidy offer would be made within the next ten days +to two weeks. + Aides to Roberts said he had spoken to Republican leaders +who had been in contact with administration officials. + Richard Fritz, director of international marketing at U.S. +Wheat Associates, said he was confident an export enhancement +offer would be made by the middle of this month. + Fritz also said he thought the value of the bonus would end +up being close to the offer Washington made Peking earlier this +year when USDA approved subsidies to China of around 36 dlrs +per tonne on one mln tonnes of wheat. + Some grain trade representatives say a four-mln-tonne wheat +subsidy offer might help stimulate more Soviet purchases of +U.S. corn and open the door to U.S. sales of soybeans. + As ever, one of the crucial sticking points in a wheat deal +would appear to be price. + Last summer the administration took the controversial step +of offering the Soviets subsidized wheat -- but were +embarrassed when Moscow spurned the proposal on the grounds +that the 15-dlr-per-tonne subsidy still left U.S. wheat prices +far above world market prices. + The administration's decision to set the subsidy level up +front instead of accepting bids from exporters appeared to be a +means of controlling the price while attempting to dampen +criticism, grain trade sources said. + Nonetheless, the pricing procedure did not prevent Shultz +from saying the Soviets were "chortling" because Washington was +offering Soviet housewives cheaper grain than that available to +U.S. housewives. + The conventional wisdom among grain trade representatives +here is that a general warming of relations between the two +countries since last summer, combined with continued hard times +in the U.S. grain belt, would favor a subsidy offer. + In addition, the USSR has made it clear it would consider +buying U.S. wheat if it were priced more competitively. + However, observers have not forgotten the circumstances +surrounding the administration's announcement of the wheat +subsidy offer last summer. + Up until the time of the announcment, congressional and +industry leaders were led to believe the White House had +decided to expand the Export Enhancement Program to include not +only the Soviets, but also a much broader list of countries. + Instead, the administration scaled back the offer to +include only the Soviets. + That last-minute change of heart adds a measure of +uncertainty even to the predictions of those most convinced +that the administration will not now pass up the opportunity to +sell four mln tonnes of wheat to the Soviet Union. + Reuter + + + + 1-APR-1987 11:05:07.78 +sugar +ukindia + + + + + + +C T +f1295reute +b f BC-KAINES-CONFIRMS-WHITE 04-01 0062 + +KAINES CONFIRMS WHITE SUGAR SALES TO INDIA + LONDON, April 1 - London-based sugar operator Kaines Ltd +confirmed it sold two cargoes of white sugar to India out of an +estimated overall sales total of four or five cargoes in which +other brokers participated. + The sugar, for April/May and April/June shipment, was sold +at between 214 and 218 dlrs a tonne cif, it said. + Reuter + + + + 1-APR-1987 11:09:07.45 + +usa + + + + + + +F +f1325reute +r f BC-LUXTEC-<LUXT>-CUTS-WA 04-01 0037 + +LUXTEC <LUXT> CUTS WARRANT EXERCISE PRICE + STURBRIDGE, Mass., April 1 - Luxtec Corp said it has +reduced the exercise price of its Class B common stock purchase +warrants to one dlr from two dlrs from today through June 30. + Reuter + + + + 1-APR-1987 11:09:11.43 +earn +usa + + + + + + +F +f1326reute +r f BC-<THL-HOLDINGS-INC>-YE 04-01 0038 + +<THL HOLDINGS INC> YEAR JAN 31 NET + CANTON, Mass., April 1 - + Oper net 94.4 mln vs 74.1 mln + Revs 1.3 bilion vs 1.2 billion + NOTE: THL is parent to SCOA Industries Inc, acquired in a +leveraged buyout in December 1985. + Reuter + + + + 1-APR-1987 11:09:19.56 + +uk + + + + + + +F +f1327reute +d f BC-GUARDIAN-ROYAL-SEES-E 04-01 0111 + +GUARDIAN ROYAL SEES EXPANSION IN LIFE ASSURANCE + LONDON, April 1 - Insurance group Guardian Royal Exchange +Plc <GREX.L> said it would expand its life assurance business +and push further into European markets, but that U.K. +Underwriting losses remained a heavy drag on profits. + Earlier, the group had announced sharply increased pre-tax +profits of 143.8 mln stg for calendar 1986, versus 3.5 mln the +previous year. + "We are anxious to develop our life assurance business," +group managing director Peter Dugdale told a news conference. +"If we have a thrust for the coming years, it is probably best +to spend more time on life in the U.K. And abroad," he said. + Reuter + + + + 1-APR-1987 11:09:50.05 +acqstrategic-metal +usa + + + + + + +M +f1330reute +d f BC-MOUNTAIN-STATES-ADDS 04-01 0090 + +MOUNTAIN STATES ADDS TWO MINERALS PROPERTIES + SALT LAKE CITY, April 1 - Mountain States Resources Corp +said it acquired two properties to add to its strategic +minerals holdings. + The acquisitions include a total of 5,100 acres of +titanium, zirconium and rare earth resources, the company said. + Both properties, located in southern Utah, consist of +approximately 1,430 acres of unpatented mining claims and one +state lease, it said. + The company also announced the formation of Rare Tech +Minerals Inc, a wholly-owned subsidiary. + Reuter + + + + 1-APR-1987 11:10:45.38 +coffee + + +ico-coffee + + + + +C T +f1333reute +b f BC-Restoration-of-coffee 04-01 0016 + +******RESTORATION OF COFFEE EXPORT QUOTAS BEFORE + OCTOBER SEEMS UNLIKELY - ICO PRODUCER DELEGATES + + + + + + 1-APR-1987 11:11:41.60 +wheatgrain +usaussr + + + + + + +F +f1337reute +d f BC-SHULTZ-USSR-TRIP-FUEL 04-01 0103 + +SHULTZ USSR TRIP FUELS TALK OF EEP WHEAT OFFER + WASHINGTON, April 1 - Speculation the United States will +offer subsidized wheat to the Soviet Union appears to have +reached a new level of intensity in the run-up to Secretary of +State George Shultz' visit later this month to Moscow. + Rumors of an impending deal have coursed through wheat +markets since officials from the two countries held their +customary, semi-annual grain talks in February. Moscow's +decision at that time to reenter the U.S. corn market +strengthened the perception of warming farm trade prospects. + Shultz is set to arrive in Moscow April 13. + Reuter + + + + 1-APR-1987 11:11:46.21 +interest +usa + + + + + + +RM A +f1338reute +r f BC-FREDDIE-MAC-ADJUSTS-S 04-01 0043 + +FREDDIE MAC ADJUSTS SHORT-TERM DISCOUNT RATES + WASHINGTON, April 1 - The Federal Home Loan Mortgage Corp +adjusted the rates on its short-term discount notes as follows: + MATURITY RATE OLD RATE MATURITY + 32 days 6.00 pct 6.10 pct 1 day + + Reuter + + + + 1-APR-1987 11:12:00.71 +coffee +ukbrazilguatemalacolombia + +ico-coffee + + + + +C T +f1340reute +b f BC-COFFEE-QUOTAS-BEFORE 04-01 0082 + +ICO QUOTAS BEFORE OCTOBER UNLIKELY - DELEGATES + LONDON, April 1 - The restoration of coffee export quotas +before the end of the current 1986/87 coffee year (Oct 1/Sept +30) now seems unlikely, given reluctance by International +Coffee Organization, ICO, producers and consumers to resume +negotiations on an interim quota accord, producer delegates +told reporters. + Consumers and most producers see no point in reopening the +quota dialogue while Brazil's position remains unchanged, they +said. + Brazil's refusal to accept a reduction in its previous 30 +pct share of the ICO's global export quota effectively +torpedoed talks here last month aimed at restoring quotas +before October, the delegates noted. + Disappointment at the lack of progress on quotas forced +coffee futures in London and New York to new lows today, +traders here said. Near May in New York fell below one dlr in +early trading at around 99.10 cents per pound, traders said. + Producer delegates said that while the possibility of +reimposing quotas before October remained on the ICO agenda, in +practice the idea had effectively been discarded. + The ICO's executive board session here this week has so far +barely touched on the quota debate, demonstrating general +unwillingness to revive talks while chances of success are +still remote, producer delegates said. + Some producers are in no hurry to see quotas restored, +despite the price collapse seen since the failure of last +month's negotiations, they said. + "With Brazil's frost season approaching, who wants to +negotiate quotas," one leading producer delegate said. + Coffee prices normally rise during Brazil's frost season +(mainly June-August) as dealers and roasters build up stocks as +insurance against possible severe frost damage to Brazil's +crop. + Many producers are more interested in working towards +reimposing quotas from October 1, based on a new system of +quota allocations valid until the International Coffee +Agreement expires in 1989, they said. + Guatemala has already proposed the "other oilds" producer +group should meet in the next two months to begin talks on how +to allocate quota shares. + Producers still seem divided on how to overhaul the quota +distribution system, with some producer delegates reporting +growing support for a radical reallocation, based on the +principle of "objective criteria" favoured by consumers. + At last month's council session a splinter group of small +producers backed consumer demands for new quota shares based on +exportable production and stocks, while Brazil, Colombia and +the rest of the producers favoured leaving quota allocations +unchanged, except for some temporary adjustments. + A delegate from one of the eight said more producers now +supported their cause. + The delegate said unless major producers like Brazil showed +readiness to negotiate new quota shares, prospects for a quota +accord in October also looked bleak. + The U.S. and most other consumers are still determined to +make reimposition of quotas conditional on a redistribution of +quota shares based on "objective criteria." + ICO observers remained sceptical that Brazil would be +prepared to accept a quota reduction when the ICO council meets +in September. + Brazil has adopted a tough stance with banks on external +debt negotiations and is likely to be just as tough on coffee, +they said. + They said Brazil's reluctance to open coffee export +registrations might reflect fears this would provoke another +price slide and force an emergency ICO council session, which +would most likely end in failure. + Producers met this afternoon to review the market situation +but had only a general discussion about how further +negotiations should proceed, a producer delegate said. + Producers plan to hold consultations on quotas, and then +may set a date for a formal producer meeting, but plans are not +fixed, he said. + The ICO executive board reconvened at 1650 hours local time +to hear a report from consultants on ICO operations. The board +meeting looks set to end today, a day earlier than scheduled, +delegates said. + Reuter + + + + 1-APR-1987 11:13:10.37 + +usa + + + + + + +F +f1346reute +f f BC-******AMERICAN-MOTORS 04-01 0011 + +******AMERICAN MOTORS MARCH U.S. CAR OUTPUT DOWN TO 2,578 FROM +5,922 + + + + + + 1-APR-1987 11:16:02.05 + +yugoslavia +mikulic + + + + + +A +f1350reute +h f BC-YUGOSLAVIA-WINS-TIME 04-01 0108 + +YUGOSLAVIA WINS TIME IN PARIS CLUB REFINANCING + BELGRADE, April 1 - Yugoslavia has won breathing space from +its major official creditors through yesterday's Paris Club +refinancing agreement but it will take time for it to resolve +its economic crisis, economists at western embassies said. + Yugoslav delegation chief Finance Minister Svetozar +Rikanovic said a refinancing was agreed for 475 mln dlrs of +debt falling due between May 16 this year and May 31, 1988. + The agreement was the second multi-year Yugoslav debt +refinancing, based on a protocol signed last May which ushered +in "enhanced monitoring" of Yugoslavia's economy by the IMF. + Western economists who follow Yugoslav financial affairs +said a similar deal would probably emerge from talks with +commercial creditors at the end of this month. But they said +the refinancings would only provide a breathing space, because +Yugoslavia has to repay 5.5 billion dlrs in 1987. + And the country is still struggling to reverse a dramatic +decline in export earnings, which have fallen 12.5 pct so far +this year, continuing a downward spiral of the past 18 months. + The Yugoslav hard currency debt has grown from 1.2 billion +dlrs in 1965 to stand at 19.7 billion dlrs at the end of 1986 +and is one of the country's most dire economic problems. + The debt began to snowball in the 1960s and 1970s due to an +excessive investment rate exceeding the growth of the Gross +Social Product and necessitating additional foreign borrowing. + Rising international oil prices in the 1970s proved to be a +serious blow to the country's balance of payments. + Deputy Prime Minister Milos Milosavljevic said this month +that Yugoslavia had repaid 640 mln dlrs of principal and 325 +mln dlrs of interest so far this year. + According to official Yugoslav figures, Yugoslavia repaid a +record 5.97 billion dlrs in capital and interest in 1986, +reducing overall indebtedness by 996 mln dlrs. + Mikulic is trying to rein in rampant retail inflation of +almost 100 pct a year through price and incomes controls. + Janez Zemljaric, also a Deputy Prime Minister, said +recently Yugoslavia expected a "definite measure of +understanding" from its 16 major western creditor nations. + Western economists said Yugoslavia has had its way with the +Paris Club creditors but that not all creditors were satisfied +with its economic performance last year. They said the Paris +discussions were heated and emotional. + "Economic factors were balanced by political realities," an +economist at one of the main embassies here said, but added +that creditors had no complaints regarding Yugoslavia's +repayment record because it had so far always repaid debts on +time. + Yugoslavia has refinanced its debt regularly since 1983. + In December 1985, it signed a deal with the International +Coordinating Committee of 600 commercial banks to refinance +maturities arising between January 1, 1985 and end-1988. + It had signed bilateral refinancing agreements in March of +that year for maturities arising from January 1, 1985 to March +25, 1986, following an agreement in Paris on March 25, 1985. + Government ministers told Reuters this month that +Yugoslavia had made too great an effort to repay its debts in +1986, at great cost to the economy, and that this was +regretted. + Mikulic has said Yugoslavia is unlikely to follow Brazil's +lead and suspend its debt repayments "but we have understanding +for what that country did." + Western economists said, however, that Mikulic's remarks, +taken with those of his ministers, could be a signal that some +problems were seen ahead in refinancing debt repayments. + Before the Paris talks, some Yugoslav officials had hinted +that Yugoslavia could start to look to the Soviet Bloc for +financial support if Belgrade failed to secure the necessary +refinancing from western creditors. + Sources close to the western creditors, however, said they +did not view the threat as serious. + REUTER + + + + 1-APR-1987 11:16:55.25 +earn +usa + + + + + + +E +f1353reute +u f BC-(GEOFFRION-LECLERC-IN 04-01 0031 + +(GEOFFRION LECLERC INC) SIX MTHS NET + MONTREAL, April 1 - + Shr 39 cts vs 26 cts + Net 3,466,000 vs 1,913,000 + Revs 27.7 mln vs 19.4 mln + Note: period ended February 28. REUTER + Reuter + + + + 1-APR-1987 11:19:36.90 + +usa + + + + + + +A RM +f1358reute +r f BC-ALLIED-SUPERMARKETS-< 04-01 0093 + +ALLIED SUPERMARKETS <ASU> FILES FOR OFFERING + NEW YORK, April 1 - Allied Supermarkets Inc said it filed +with the Securities and Exchange Commission a registration +statement covering 240 mln dlrs of debt securities. + The company plans to offer 140 mln dlrs of senior +subordinated discount debentures and 100 mln dlrs of +subordinated debentures. + Proceeds will be used to finance Allied's acquisition of +Vons Cos Inc. + Allied named Drexel Burnham Lambert Inc and Donaldson, +Lufkin and Jenrette Securities Corp as co-underwriters of both +offerings. + Reuter + + + + 1-APR-1987 11:19:44.38 +interest +usa + + + + + + +RM A +f1359reute +r f BC-FHLBB-CHANGES-SHORT-T 04-01 0083 + +FHLBB CHANGES SHORT-TERM DISCOUNT NOTE RATES + WASHINGTON, April 1 - The Federal Home Loan Bank Board +adjusted the rates on its short-term discount notes as follows: + MATURITY NEW RATE OLD RATE MATURITY + 5.00 pct 30-69 days + 5.92 pct 70-88 days + 30-123 days 5.00 pct 5.00 pct 89-123 days + 124-150 days 5.93 pct 5.93 pct 124-150 days + 151-349 days 5.00 pct 5.00 pct 151-349 days + 350-360 days 5.98 pct 5.98 pct 350-360 days + Reuter + + + + 1-APR-1987 11:20:01.59 +earn +usa + + + + + + +F +f1361reute +r f BC-TOWLE-MANUFACTURING-C 04-01 0044 + +TOWLE MANUFACTURING CO <QTOW> YEAR LOSS + BOSTON, April 1 - + Oper shr loss 4.71 dlrs vs loss 14.09 dlrs + Oper loss 22 mln vs loss 67.2 mln + NOTE: 1986 loss excludes gain on the sale of Gold Lance +Corp of 12.1 mln dlrs. Company is operating under chapter 11. + Reuter + + + + 1-APR-1987 11:21:36.73 +acq + + + + + + + +F +f1366reute +f f BC-******DELTA-AIR-LINES 04-01 0009 + +******DELTA AIR LINES COMPLETES ACQUISITION OF WESTERN AIR + + + + + + 1-APR-1987 11:22:14.20 +interest + +james-baker + + + + + +V RM +f1370reute +f f BC-******TREASURY'S-BAKE 04-01 0011 + +******TREASURY'S BAKER SAYS HE HOPES PRIME RATE INCREASES +TEMPORARY + + + + + + 1-APR-1987 11:23:07.19 + +canada + + + + + + +E +f1371reute +u f BC-NEW-MONTREAL-NEWSPAPE 04-01 0103 + +NEW MONTREAL NEWSPAPER FOLDS + MONTREAL, April 1 - Le Matin, the French-language tabloid +launched here in February, said it is shutting down its +operations because it can no longer get financing. + The paper, launched by private investors, was Montreal's +fourth French-language newspaper and was aimed at readers with +above average incomes and educations. It had a daily +circulation of about 20,000 copies. + Le Matin was printed and distributed by (Southam Inc)'s +Montreal Gazette newspaper. A Gazette spokesman said his +newspaper is Le Matin's biggest creditor but he declined to +reveal the amount of debt + Acting publisher Jean-Pierre Bordua said the newspaper's +bank blocked its lines of credit after three of the paper's +senior managers resigned Friday. + Reuter + + + + 1-APR-1987 11:24:00.34 + +usa + + + + + + +F +f1377reute +r f BC-TOWLE-<QTOW>-STOCK-MA 04-01 0103 + +TOWLE <QTOW> STOCK MAY BE DILUTED, CANCELED + BOSTON, Mass., April 1 - Towle Manufacturing Co, in Chapter +11 of the U.S. bankruptcy code, said any plan of reorganization +would likely lead to a dilution or cancellation of its common +and preferred stock. + The company also said claims for subordinated debentures +would likely be paid at less than their 100 pct of their face +value, and general unsecured claims would likely be paid +without interest. The company has not yet filed a plan of +reorganization. + The company said it lost 22 mln dlrs from operations in +1986 against a loss of 67.2 mln dlrs a year ago. + The company also said its independent accountants +disclaimed an opinion on the financial statements for 1986 +because of questions about its contination as a going concern. + The company said, however, it substantially restructured +its business, reducing borrowings on an outstanding credit line +to 16.5 mln dlrs in 1986 from 57 mln dlrs a year ago. The +company also cut its staff to 820 employees at the end of 1986 +from 2,500 a year earlier. + Reuter + + + + 1-APR-1987 11:24:06.95 +earn +usa + + + + + + +F +f1378reute +d f BC-SOUTH-ATLANTIC-FINANC 04-01 0045 + +SOUTH ATLANTIC FINANCIAL CORP <SOAF> 4TH QTR + STAMFORD, Conn., April 1 - + Shr 12 cts vs 33 cts + Net 699,037 vs 1,349,077 + Year + Shr 54 cts vs 55 cts + Net 2,748,280 vs 1,833,766 + NOTE: Per shr amounts reported after preferred stock +dividend requirements. + Reuter + + + + 1-APR-1987 11:25:07.00 + +usa + + + + + + +F +f1381reute +r f BC-AMERICAN-MOTORS-<AMO> 04-01 0085 + +AMERICAN MOTORS <AMO> MARCH OUTPUT FALLS + SOUTHFIELD, Mich., April 1 - American Motors Corp said it +produced 2,578 U.S. cars in March, down from 5,922 in the same +1986 month. + The automaker's March U.S. Jeep output was 21,390, up from +16,215 in the same month last year. + Year-to-date U.S. car production by American Motors through +the end of March was 8,647 vehicles compared to 12,553 in the +same 1986 period. Year-to-date Jeep output was 58,597 compared +to 56,801. + + Reuter + + + + 1-APR-1987 11:26:18.58 +copper +usa + + + + + + +C M F +f1385reute +u f BC-CYPRUS-LOWERS-COPPER 04-01 0035 + +CYPRUS LOWERS COPPER PRICE 1.25 CTS TO 67 CTS + DENVER, April 1 - Cyprus Minerals Company said it is +decreasing its electrolytic copper cathode price by 1.25 cents +to 67.0 cents a pound, effective immediately. + Reuter + + + + 1-APR-1987 11:27:55.71 + +ukjapan +thatcherlawson + +lse + + + +RM +f1393reute +u f BC-TOSHIBA-COULD-BE-FIRS 04-01 0113 + +TOSHIBA COULD BE FIRST TO FEEL U.K. TRADE ANGER + By Sten Stovall, Reuters + LONDON, April 1 - Toshiba Corp <TSBA.T>, the Japanese +electronics group which plans to enter Britain's liberalised +telecommunications equipment market, risks becoming the first +casualty in the current war of words over trade between Japan +and the U.K., Government and industry sources said. + U.K. Authorities have lost patience with Japanese trading +practices and said they are seeking ways to retaliate without +unleashing a damaging trade war. "Toshiba's timing seems most +unfortunate for the company, as it comes exactly when we are +looking for someone to punch," one official told Reuters. + Earlier, <Toshiba Information Systems (U.K.) Ltd> said it +wanted to enter the British business facsimile and key +telephone market. A facsimile machine sends printed data over +telephone lines, while a key telephone system is used for +switching calls within a business, industry sources said. + The move by Toshiba comes in the middle of a dispute over +Japan's refusal to open up its telecommunications market to +foreign companies. "Toshiba's timing is most extraordinary," one +official at the Department of Trade and Industry (DTI) said. + Tomorrow, the U.K. Government will consider what legal +action it can possible take to press for Japanese reform. + Prime Minister Margaret Thatcher has given notice that the +U.K. Would fight the Japanese government's attempt to prevent +Cable and Wireless Plc <CAWL.L> from taking a significant +position in a new Japanese international telecommunications +venture. "We regard this as a test case," she told Parliament. + But while the U.K. Is keen to see some movement on the +issue by Japan, it is also worried that recent anti-Japanese +rhetoric may cause developments to get out of hand, officials +said. + Japanese officials in Tokyo today reiterated that Japan had +no plans to bow to U.K. And U.S. Pressure to give foreign +telecommunications firms a bigger role there. + The government, for which competition and the deregulation +of markets are major political themes, is unlikely to make +final decisions tomorrow on how to act against Japan, officials +said. + Detailed consideration of the issue has been shelved during +Thatcher's official visit to the Soviet Union, which ends +today. + "We are waiting for the Prime Minister to decide what to do. +The DTI will pass the ball to her as soon as she returns +tonight," a DTI official said. + He said Toshiba's application would be considered by the +Office of Telecommunications (OFTEL). An OFTEL spokeswoman said +"a decision on this application will take weeks, maybe months." + Asked whether Toshiba's bid would fall victim to British +retaliation, the OFTEL spokeswoman said: "Who knows what's going +to happen given the current situation!" + A Toshiba executive, who asked not to be named, told +Reuters: "We do not anticipate any special problems." + Some analysts queried by Reuters questioned the basis of +Britain's strong stand on the Cable and Wireless bid. One said +that the company's proposal was equivalent to a Japanese +company wanting to take a stake in Mercury International, the +subsidiary of Cable and Wireless that is the only real +competitor of British Telecommunications Plc <BTY.L>. + British Corporate Affairs minister Michael Howard leaves +for Japan on Saturday. + The minister will seek a clear timetable from Japan for +easier access for British institutions to Japanese financial +markets, reciprocating the easy access Japanese securities +houses and banks have to the City of London. + Britain has threatened to use its new Financial Services +Act to revoke or deny licences to Japanese brokerage houses if +it does not get satisfaction. + But British authorities would be far from happy if forced +to use that weapon, government sources said. + Sir Nicholas Goodison, Chairman of the London Stock +Exchange, said in New York yesterday that sanctions against +Japanese financial institutions operating in the U.K. Would set +back London's ambition to become a leading centre for corporate +financing and securities trading. + Chancellor of the Exchequer Nigel Lawson also warned +yesterday of the negative effects that a trade war could have +on the British economy. Such a development could hit U.K. +Exports and sharply alter the outlook for the next general +election in which economic recovery will be one of the +government's main themes, political analysts said. + REUTER + + + + 1-APR-1987 11:28:34.96 + +uk + + + + + + +RM +f1395reute +u f BC-DOLLAR-EUROBONDS-END 04-01 0114 + +DOLLAR EUROBONDS END EASIER ON PRIME RATE RISES + By Christopher Pizzey, Reuters + LONDON, April 1 - The dollar straight sector of the +eurobond market ended easier after a subdued day's trading as +U.S. Banks began to match yesterday's surprise 1/4 point prime +rate hikes by Citibank and Chase Manhattan Bank, dealers said. + The prime rates were raised to 7-3/4 from 7-1/2 pct and the +timing of the moves puzzled many dealers. However, reaction +here was limited, with shorter dated paper ending steady to 1/4 +point easier, while longer dates dipped by 1/4 to 1/2 point. + In the primary market, activity again centred on currencies +other than the U.S. Dollar, dealers noted. + One dollar straight dealer at a U.S. Securities house +commented "There was, in fact, the odd retail buyer today, but +only in small sizes." He added that, ironically, the prime rate +rises may help the market to stabilise since the dollar rose on +the back of the news. + The only U.S. Dollar deal launched during the day was, as +has been the case recently, equity linked. The 15-year +convertible bond was for the Bank of Tokyo Ltd and has an +indicated coupon of two pct. One source at a house involved in +the deal said, "It's got to be a blow-out. With a name like this +you're talking about Japan Inc." + The lead manager was the Bank of Tokyo International (BOTI) +and the deal ended far above the par issue price at 108 109 +pct. A BOTI official said "We've had worldwide interest in the +deal." + She noted the Tokyo stock market had experienced a mild +correction at the beginning of the week but that bank stocks +were hardly affected. + The yen sector edged slightly firmer and one new straight +deal was launched, a 20 billion yen bond for France's Caisse +Nationale des Telecommunications. The state guaranteed five +year bond pays 4-3/8 pct and was priced at 101-1/2 pct. + The issue was lead managed by IBJ International Ltd and was +quoted on the grey market at less 1-7/8 less 1-3/4 pct compared +with the total fees of 1-7/8 pct. One syndicate official at a +firm not involved in the deal said "It's tight, but overall I +would say its fairly priced." + Also launched was a five-year zero coupon bond with a total +redemption amount of 19 billion yen for Rural Banking and +Finance Corp of New Zealand. It was priced at 81.22 pct and +lead managed by Nomura International. + In the Australian dollar sector, GMAC (Australia) Finance +Ltd issued a 50 mln Australian dlr bond. + Hambros Bank Ltd was lead manager for the four-year deal +which pays 14-1/4 pct and was priced at 101 pct. It was +guranteed by General Motors Acceptance Corp and was quoted on +the 1-3/4 pct fees at less 1-3/4 pct bid. + McDonalds Corp issued a 75 mln Canadian dlr bond paying +8-1/2 pct over five years and priced at 101-5/8 pct. It was +quoted around the 1-7/8 pct fees at less two less 1-3/4 and was +led by Morgan Guaranty Ltd. + The European Investment Bank launched a 300 mln Danish +Crown, seven-year, bond withan 11 pct coupon and pricing of 101 +pct. It was lead managed by Den Danske Bank. + The floating rate note sector basically ended easier +following the increase in period eurodollar deposit rates +prompted by the prime rate increases, dealers said. But they +noted that mis-match deals - issues whereby the coupon is +re-fixed on a monthly basis - were firmer. + REUTER + + + + 1-APR-1987 11:30:48.69 +interest +usa +james-baker + + + + + +V RM +f1401reute +b f BC-TREASURY'S-BAKER-HOPE 04-01 0080 + +TREASURY'S BAKER HOPES PRIME RATE RISE TEMPORARY + WASHINGTON, April 1 - Treasury Secretary James Baker said +he hopes yesterday's small increase in two major money center +banks' prime rate was a temporary phenomenon. + "I hope it was a temporary blip upward," he told a House +Appropriations subcommittee. + He said the decline in interest rates since President +Reagan took office remains "one of the significant +accomplishments, in the economic area, of this administration." + Reuter + + + + 1-APR-1987 11:31:43.99 +acq +usa + + + + + + +F +f1403reute +u f BC-DELTA-<DAL>-COMPLETES 04-01 0064 + +DELTA <DAL> COMPLETES WESTERN AIR <WAL> BUY + ATLANTA, April 1 - Delta Air Lines Inc said it completed +the acquisition of Western Air Lines Inc this morning. + The action follows U.S. Supreme Court Justice Sandra Day +O'Connor's overnight granting of Delta and Western's request to +stay an earlier injunction against the deal issued by the U.S. +Court of Appeals for the Ninth Circuit. + More + + + + 1-APR-1987 11:33:36.12 + +usa + + + + + + +F +f1412reute +r f BC-NATIONAL-DISTILLERS-A 04-01 0099 + +NATIONAL DISTILLERS AND CHEMICAL <DR> EXPANDING + NEW YORK, April 1 - National Distillers and Chemical Corp +said its board approved a modernization and expansion program +from its petrochemical division, USI Chemical Co, its +polyethylene producer. + The program will add 600 mln pounds per year to USI's +existing capacity of 3.2 billion pounds, the company said. The +increase will result from the addition of two linear reactors +based on fluid bed gas phase technology for the production of +linear low density or high density polyethylene at locations in +the Midwest and Gulf Coast, it said. + Plans are in the engineering stage with completion expected +in mid 1989, the company said. In addition, USI is presently +constructing a 300 mln pound linear low density polyethylene +facility, scheduled to come on stream in early 1988 at its Port +Author, Texas, plant. + Reuter + + + + 1-APR-1987 11:34:07.33 + +usa + + + + + + +F +f1417reute +r f BC-BALDWIN-PIANO-<BPAO> 04-01 0056 + +BALDWIN PIANO <BPAO> FILES FOR SECONDARY + CINCINNATI, April 1 - Baldwin Piano and Organ Co said it +has filed for a secondary offering of 630,000 common shares, +including 490,000 to be sold by General Electric Co <GE> and +140,000 by other shareholders. + Lead underwriters are William Blair and Co and McDonald and +Co Investments <MDD>. + Reuter + + + + 1-APR-1987 11:34:12.41 +earn +usa + + + + + + +F +f1418reute +r f BC-AMERICAN-OIL-AND-GAS 04-01 0049 + +AMERICAN OIL AND GAS CORP <AOG> 4TH QTR LOSS + HOUSTON, April 1 - + Shr loss 34 cts vs loss 2.14 dlrs + Net loss 2,275,000 vs loss 9,560,000 + Revs 17.0 mln vs 19.9 mln + Year + Shr loss 49 cts vs loss 2.11 dlrs + Net loss 2,661,000 vs loss 9,283,000 + Revs 73.5 mln vs 93.6 mln + + NOTE: Results have been restated to reflects equity +investment in WellTech Inc for one month ended Dec 31, 1986 and +its investment in American Well Servicing for the 11 months +ended Nov 30, 1986 and full year 1985. + 1986 and 1985 net include loss of 3,512,000 dlrs and +5,944,000 dlrs, respectively, for equity in WellTech and +predecessor operations. + Reuter + + + + 1-APR-1987 11:35:12.00 +acq + + + + + + + +F +f1425reute +f f BC-MACANDREWS/FORBES-UNI 04-01 0014 + +******MACANDREWS/FORBES UNIT BEGINS OFFER TO BUY ALL REVLON +GROUP NOT ALREADY OWNED + + + + + + 1-APR-1987 11:36:11.38 +earn +usa + + + + + + +F +f1433reute +r f BC-<NEWPARK-RESOURCES-IN 04-01 0076 + +<NEWPARK RESOURCES INC> YEAR ENDED DEC 31 LOSS + NEW ORLEANS, April 1 - + Oper shr loss 1.99 dlr vs loss 4.88 dlrs + Oper net loss 29.1 mln vs 70.8 mln + Revs 34.8 mln vs 84.8 mln + NOTE: 1986 and 1985 oper net excludes a loss of 5.5 mln +dlrs or 37 cts a share and 64.6 mln dlrs or 4.43 dlrs a share, +respectively, for discontinued operations. + 1986 net also excludes a gain of 66.4 mln dlrs or 4.50 dlrs +a share for credit on debt restructuring. + Reuter + + + + 1-APR-1987 11:36:30.26 + +usa + + + + + + +F +f1435reute +u f BC-CARDIS-<CDS>-EXPECTS 04-01 0096 + +CARDIS <CDS> EXPECTS SIGNIFICANT YEAR LOSS + BEVERLY HILLS, Calif., April 1 - Cardis Corp said it +anticipates reporting a loss from continuing operations of +approximately 17.7 mln dlrs on revenues of 228 mln dlrs for +fiscal year 1986. + In addition, the company said it expects to report a +year-end loss on the discontinued operations of its engine +rebuilding divisions of approximately 1,100,000 mln dlrs. + Cardis also said it expects to report a loss in excess of +five mln dlrs for its first fiscal quarter ended Jan 31, 1987, +on approximate revenues of 58 mlns dlrs. + For fiscal 1985 Cardis reported operating income of +8,680,000 and net income of 1,150,000 dlrs, and in the first +quarter of fiscal 1986, it reported a 495,000 dlr loss from +continuing operations. + The company said its auditor, Touche Ross and Co, has +indicated to it that any opinion it issues on the company's +soon-to-be completed year-end audit will be qualified. + The company also said it expects to conclude soon its +current negotiations with its primary lenders for extension of +its loan agreements and expansion of its credit lines. + Reuter + + + + 1-APR-1987 11:36:57.32 +earn +usa + + + + + + +F +f1439reute +d f BC-TIERCO-GROUP-INC-<TIE 04-01 0031 + +TIERCO GROUP INC <TIER> YEAR ENDED DEC 31 LOSS + OKLAHOMA CITY, April 1 - + Shr loss 72 cts vs loss 1.57 dlr + Net loss 1,526,359 vs loss 3,315,834 + Revs 8,032,798 vs 7,276,517 + Reuter + + + + 1-APR-1987 11:37:00.45 +earn +usa + + + + + + +F +f1440reute +s f BC-MICRODYNE-CORP-<MCDY> 04-01 0022 + +MICRODYNE CORP <MCDY> SETS PAYOUT + OCALA, Fla., April 1 - + Semi div three cts vs three cts prior + Pay June 12 + Record May 15 + Reuter + + + + 1-APR-1987 11:37:26.62 + +usa +james-baker + + + + + +V RM +f1442reute +f f BC-******U.S.-TREASURY'S 04-01 0012 + +******U.S. TREASURY'S BAKER SAYS JAPAN TARIFF ACTION NOT START +OF TRADE WAR + + + + + + 1-APR-1987 11:37:46.98 + +brazil + + + + + + +RM +f1443reute +u f BC-BRAZIL-CONFIRMS-RENEW 04-01 0098 + +BRAZIL CONFIRMS RENEWAL OF SHORT-TERM CREDIT LINES + BRASILIA, April 1 - Brazilian economic officials confirmed +a renewal of short-range credit lines by commercial creditors, +bringing optimism that renegotiation of the 109 billion dlrs +foreign debt is possible. + Finance Ministry sources said a "large majority" of foreign +banks had accepted to extend Brazil's credit lines before the +midnight deadline of March 31 for payment of 15 billion dlrs +servicing expired. + Finance Minister Dilson Funaro told reporters all short +range credit lines were renewed, "without exception." + Central Bank sources, although incapable of confirming that +100 pct of the banks had renewed the credit lines, said that +there was a massive affirmative reply. + The credit lines were extended in their majority by 30 +days, but there were banks which renewed the deadline by 90 +days and, sometimes, by 180 days, Funaro told reporters. + Brazil is pledging for an extension of the deadlines for an +indefinite period, until its economic officials seek a global +renegotiation of the debt. + Last week Brazil had suggested to creditors an extension of +the deadline for another two months, until May 31. + REUTER + + + + 1-APR-1987 11:38:11.26 + +ukjapan +thatcher + + + + + +F +f1446reute +d f BC-TOSHIBA-COULD-BE-FIRS 04-01 0112 + +TOSHIBA COULD BE FIRST TO FEEL U.K. TRADE ANGER + By Sten Stovall, Reuters + LONDON, April 1 - Toshiba Corp <TSBA.T>, the Japanese +electronics group which plans to enter Britain's liberalised +telecommunications equipment market, risks becoming the first +casualty in the current war of words over trade between Japan +and the U.K., Government and industry sources said. + U.K. Authorities have lost patience with Japanese trading +practices and said they are seeking ways to retaliate without +unleashing a damaging trade war. "Toshiba's timing seems most +unfortunate for the company, as it comes exactly when we are +looking for someone to punch," one official told Reuters. + Earlier, <Toshiba Information Systems (U.K.) Ltd> said it +wanted to enter the British business facsimile and key +telephone market. A facsimile machine sends printed data over +telephone lines, while a key telephone system is used for +switching calls within a business, industry sources said. + The move by Toshiba comes in the middle of a dispute over +Japan's refusal to open up its telecommunications market to +foreign companies. "Toshiba's timing is most extraordinary," one +official at the Department of Trade and Industry (DTI) said. + Tommorrow, the U.K. Government will consider what legal +action it can possible take to press for Japanese reform. + Prime Minister Margaret Thatcher has given notice that the +U.K. Would fight the Japanese government's attempt to prevent +Cable and Wireless Plc <CAWL.L> from taking a significant +position in a new Japanese international telecommunications +venture. "We regard this as a test case," she told Parliament. + But while the U.K. Is keen to see some movement on the +issue by Japan, it is also worried that recent anti-Japanese +rhetoric may cause developments to get out of hand, officials +said. + Japanese officials in Tokyo today reiterated that Japan had +no plans to bow to U.K. And U.S. Pressure to give foreign +telecommunications firms a bigger role there. +reuter^M + + + + 1-APR-1987 11:38:19.87 +interest +usa + + + + + + +RM A +f1447reute +r f BC-FHLBB-CHANGES-SHORT-T 04-01 0082 + +FHLBB CHANGES SHORT-TERM DISCOUNT NOTE RATES + WASHINGTON, April 1 - The Federal Home Loan Bank Board +adjusted the rates on its short-term discount notes as follows: + MATURITY NEW RATE OLD RATE MATURITY + + 30-123 days 5.00 pct 5.00 pct +30-123 days + 124-150 days 5.90 pct 5.93 pct 124-150 days + 151-349 days 5.00 pct 5.00 pct 151-349 days + 350-360 days 5.96 pct 5.98 pct 350-360 days + Reuter + + + + 1-APR-1987 11:39:28.49 + +brazil + + + + + + +A +f1452reute +r f BC-BRAZIL-CONFIRMS-RENEW 04-01 0097 + +BRAZIL CONFIRMS RENEWAL OF SHORT-TERM CREDIT LINES + BRASILIA, April 1 - Brazilian economic officials confirmed +a renewal of short-range credit lines by commercial creditors, +bringing optimism that renegotiation of the 109 billion dlrs +foreign debt is possible. + Finance Ministry sources said a "large majority" of foreign +banks had accepted to extend Brazil's credit lines before the +midnight deadline of March 31 for payment of 15 billion dlrs +servicing expired. + Finance Minister Dilson Funaro told reporters all short +range credit lines were renewed, "without exception." + Central Bank sources, although incapable of confirming that +100 pct of the banks had renewed the credit lines, said that +there was a massive affirmative reply. + The credit lines were extended in their majority by 30 +days, but there were banks which renewed the deadline by 90 +days and, sometimes, by 180 days, Funaro told reporters. + Brazil is pledging for an extension of the deadlines for an +indefinite period, until its economic officials seek a global +renegotiation of the debt. + Last week Brazil had suggested to creditors an extension of +the deadline for another two months, until May 31. + Reuter + + + + 1-APR-1987 11:40:15.71 +earn +usa + + + + + + +F +f1457reute +r f BC-CROWNAMERICA-INC-<CRN 04-01 0050 + +CROWNAMERICA INC <CRNA> 2ND QTR ENDED FEB 28 + DALTON, Ga., April 1 - + Shr two cts vs 29 cts + Net 23,000 vs 338,000 + Revs 20.2 mln vs 21.5 mln + Six mths + Shr 64 cts vs 97 cts + Net 741,000 vs 1,113,000 + Revs 43.2 mln vs 44.3 mln + NOTE: 1986 2nd qtr and six mths ended March one. + Reuter + + + + 1-APR-1987 11:40:30.77 + +usa + + + + + + +F +f1458reute +d f BC-QUANTUM-DIAGNOSTICS-< 04-01 0057 + +QUANTUM DIAGNOSTICS <QTMCU> GETS PATENT + HAUPPAUGE, N.Y., April 1 - Quantum Diagnostics Ltd said it +has been granted a patent for a new imaging technology it has +developed that uses electrmagnetic radiation. + It said it sees applications in airport security screening +devices, medical diagnostic imaging systems and quality control +devices. + Reuter + + + + 1-APR-1987 11:45:57.96 +earn +usa + + + + + + +F Y +f1471reute +u f BC-DIAMOND-SHAMROCK-<DIA 04-01 0112 + +DIAMOND SHAMROCK <DIA> SEES BETTER 1987 EARNINGS + NEW YORK, APRIL 1 - Diamond Shamrock Corp, which will split +this month into two separate companies, expects to show +improved earnings in 1987 over last year, executives of the new +company told Reuters. + Charles Blackburn, president and chief executive officer of +Diamond Shamrock and the new company, which will emphasize +exploration and production, said, "Earnings wil be better than +in 1986." He declined to say how much better. + In 1986 Diamond Shamrock reported a loss of 115.6 mln dlrs +on total revenues of 2.543 billion dlrs. Exploration and +production lost 18.5 mln dlrs on revenues of 593.5 mln dlrs. + Roger Hemminghaus, Diamond Shamrock vice president and +soon-to-be chief executive of the spin-off Diamond Shamrock +Refining and Marketing Co, said, "Refining and marketing is a +margin business. The margins will return and this will be a +better year than 1986." + In 1986, refining and marketing showed operating profits of +40.1 mln dlrs on revenues of 1.636 billion dlrs. + "We are also expecting to be in the black in the first +quarter (1987)," Heminghaus added. In the first quarter of 1986, +the refining and marketing segment showed a loss of 27.1 mln +dlrs on revenues of 492.1 mln dlrs. + + The executives were in New york for meetings with +institutional investors aimed at increasing interest in the +company's stock. + On the New York Stock Exchange, Diamond Shamrock was +trading at 16-1/4, down 1/4. + Earlier this year, T. Boone Pickens offered 15 dlrs a share +for Diamond Shamrock, and management countered with an offer at +17 dlrs and a decision to split off the refining and marketing +operation to its shareholders. + "Our advisors convinced us the market would give higher +multiples for pure plays," Blackburn said. + Reuter + + + + 1-APR-1987 11:46:53.00 +earn +usa + + + + + + +F +f1474reute +r f BC-VMS-STRATEGIC-<VLANS> 04-01 0054 + +VMS STRATEGIC <VLANS> SETS INITIAL DIVIDEND + CHICAGO, April 1 - VMS Strategic Land Trust said it +delcared an initial quarterly cash dividend of 30 cts a share, +payable May 15 to shareholders of record April 20. + The company also said that effective today it will be +trading on the NASDAQ system under the symbol <VLANS>. + Reuter + + + + 1-APR-1987 11:47:47.24 +iron-steel +usa + + + + + + +F +f1479reute +u f BC-BETHLEHEM-STEEL-<BS> 04-01 0087 + +BETHLEHEM STEEL <BS> SETS PLATE PRICE INCREASES + BETHLEHEM, Pa., April 1 - Bethlehem Steel Corp said its +base price for carbon plates and high-strength and low-alloy +plates will be increased by 25 dlrs to 405 dlrs a short ton, +effective July one. + The company said its composite prices for alloy plates will +also be increased 25 dlrs per ton on the same date, adding it +does not publish its prices for this product. + Bethlehem Steel said its composite prices for strip mill +plates will be increased 15 dlrs a ton. + Reuter + + + + 1-APR-1987 11:48:38.72 + +usajapan +james-baker + + + + + +V RM +f1482reute +b f BC-/TRREASURY'S-BAKER-SE 04-01 0099 + +TRREASURY'S BAKER SEES NO TRADE WAR OVER TARIFFS + WASHINGTON, April 1 - Treasury Secretary James Baker said +the U.S. imposition of tariffs on Japanese goods over +semiconductor trade does not signal the start of a trade war. + He also played down the significance of the precipitous +stock market decline earlier this week. + "I don't think this action should be interpreted in any way +as the start of a trade war," he said in response to a question +from a House Appropriations subcommittee. + He said a drop in stock market prices of the magnitude +experienced Monday was not so unusual. + "I don't think it is particularly unusual to see those kinds +of days" on Wall Street, Baker said. + Since Monday, he added, "The stock market has rebounded +rather vigorously." + He urged lawmakers to move cautiously on trade legislation +to avoid overly protectionist moves which might aggravate world +trade tensions. + "You're not going to legislate this (trade) deficit away," he +told the panel. + + Reuter + + + + 1-APR-1987 11:50:44.93 +earn +usa + + + + + + +F +f1490reute +d f BC-EQUICOR-SEES-YEAR-REV 04-01 0115 + +EQUICOR SEES YEAR REVENUES TO TOP TWO BILLION + NASHVILLE, Tenn., April 1 - Equicor, Equitable HCA Corp, +said that the company will likely attain revenues in excess of +two billion dlrs in its first year of operations. + The company, created last October with initial equity of +400 mln dlrs, is owned equally by the Equitable Life Assurance +Society of the U.S. and Hospital Corp of America <HCA>. + Financial results for the first six months of the company's +operations were not disclosed. Equicor provides employee group +plans to 1,500 corporations nationwide. It said it aims to +double its marketshare in five years from the about 3.5 pct of +the employee benefits industry it controls. + Reuter + + + + 1-APR-1987 11:50:55.18 +acq +usa + + + + + + +F +f1491reute +b f BC-MACANDREWS/FORBES-UNI 04-01 0110 + +MACANDREWS/FORBES BEGINS REVLON <REV> OFFER + NEW YORK, April 1 - MacAndrews and Forbes Group Inc said it +began an 18.50-dlr-a-share cash offer for all common stock of +Revlon Group Inc it does not already own. + The offer, which is being made by a wholly owned +subsidiary, Revmac Acquisition Corp, is subject to financing +and at least 28.5 mln shares being tendered, the company said. + MacAndrews and Forbes, wholly owned by Ronald Perelman, +chairman of Revlon Group, held about 31.8 pct of the voting +power of Revlon as of March 27, a spokesman said. The stake +includes about 15.1 pct of Revlon common and 95 pct of its +series A preferred stock, he said. + More + + + + 1-APR-1987 11:51:56.55 +earn +usa + + + + + + +F +f1494reute +u f BC-ARCO-<ARC>-UP-ON-HIGH 04-01 0109 + +ARCO <ARC> UP ON HIGHER EARNINGS ESTIMATE + NEW YORK, April 1 - Atlantic Richfield Co's stock rose +sharply after analyst Eugene Nowak of Dean Witter Reynolds Inc +raised his earnings estmates of the company, traders said. + ARCO jumped 1-3/4 to 81-3/4. + Nowak said that based on an average oil price of 17 dlrs a +barrel in 1987, the company should earn about 4.50 dlrs a +share. Next year, based on an average oil price of 18 dlrs a +barrel, ARCO should earn about five dlrs a share. The company +earned 3.38 dlrs a share in 1986. "If oil prices should rise to +an average of 20 dlrs a barrel," he said, "ARCO could record +earnings of 6.50 dlrs a share. + Nowak said his increased estimates come after the company +told analysts yesterday that its first quarter earnings will +comfortably cover its quarterly dividend requirement of one dlr +a share. + Nowak said, "The company has done an outstanding job +reducing expenses, and ARCO is poised to generate greater +earnings power." He said first quarter earnings will likely +exceed the company's expectations stated yesterday and be in +the 1.15-1.20 dlr-a-share range. + Reuter + + + + 1-APR-1987 11:53:49.16 + +usa +reagan + + + + + +V RM +f1505reute +b f BC-/SENATE-UPHOLDS-REAGA 04-01 0088 + +SENATE UPHOLDS REAGAN'S VETO BUT WILL REVOTE + WASHINGTON, April 1 - The Senate voted to sustain President +Reagan's veto of an 88 billion dlr highway and mass transit +funding bill, but Senate Democratic leader Robert Byrd of West +Virginia called for a second vote to reconsider the outcome. + The first vote ended with 65 Senators voting for the bill +and 35 voting to sustain the veto, two short of the two-thirds +majority needed to override. One of those voting to sustain the +veto was North Carolina Democrat Terry Sanford. + Reuter + + + + 1-APR-1987 11:53:59.16 +cornsorghumgrain +usabelgiumspain + +ec + + + + +C G +f1506reute +b f BC-EC-PROMISED-U.S.-BULK 04-01 0096 + +U.S. SAID PROMISED BULK OF MAIZE EXPORT TO SPAIN + BRUSSELS, April 1 - The U.S. Has been promised a near +monopoly of maize exports to Spain from third countries +guaranteed under an agreement with the European Community, an +EC official said. + The official, who asked not to be named, told Reuters that +the guarantee was given in an unpublished clause of the +agreement. + Under the accord, which began in January, third countries +were guaranteed access for the next four years for two mln +tonnes a year of maize to the Spanish market, as well as +300,000 tonnes of sorghum. + However, the official said the U.S. Had been assured that +almost all the exports would be reserved for its traders. + The EC Commission is to ask member states to agree either a +tender system to fix reduced import levies for the maize or to +authorise direct imports by the Spanish intervention board. + EC sources noted that under a tender system maize from +outside the U.S. Would sometimes be offered on more favourable +terms than that from the U.S. + No Commission spokesman was immediately available for +comment. + Reuter + + + + 1-APR-1987 11:54:45.49 +acq +usauk + + + + + + +F +f1511reute +d f BC-DEAK-INTERNATIONAL-BU 04-01 0114 + +DEAK INTERNATIONAL BUYS JOHNSON MATTHEY + NEW YORK, APRIL 1 - Deak International, a foreign currency +and precious metals firm, announced the acquisition of Johnson +Matthey Commodities of New York from Minories Finance Limited, +a unit of the Bank of England. + The purchase valued at 14.8 mln dlrs follows the recent +acquisition of London's Johnson Matthey Commodities Limited, +Deak said. + The New York firm will be known as Deak International +Trading Ltd, the company said. + Arkadi Kuhlmann, president and chief executive officer of +Deak International said the purchase will expand Deak's +operations into the precious metals and wholesale non-ferrous +metals trading arenas. + Reuter + + + + 1-APR-1987 11:56:02.30 +acq +usa + + + + + + +F +f1516reute +u f BC-WALL-STREET-STOCKS/PU 04-01 0095 + +WALL STREET STOCKS/PUROLATOR COURIER <PCC> + NEW YORK, April 1 - Purolator Courier Corp stock jumped +5-3/8 on a 40 dlr per share takeover offer from Emery Air +Freight Corp <EAF>, traders said. + Purolator was trading at 40-1/4, 1/4 above the offer price. +The Emery offer tops a 35 dlr per share buyout agreement E.F. +Hutton LBO Inc reached with Purolator February 27. + That offer was to have expired today. Neither Hutton nor +Purolator had any immediate comment. + "There's probably some speculation out there that there +might be another offer," said one analyst. + Reuter + + + + 1-APR-1987 11:57:09.82 +corngrain +usaargentinaussr + + + + + + +C G +f1518reute +b f BC-/ARGENTINE-CORN-SALES 04-01 0125 + +ARGENTINE CORN SALES TO USSR LOWER - USDA REPORT + WASHINGTON, April 1 - Total corn sales by Argentina to the +Soviet Union are only 1.5 to 1.8 mln tonnes, with delivery +spread out from March to June, the U.S. Agriculture +Department's Counselor in Buenos Aires said in a field report. + The report, dated March 27, said many sources have stated +that the Soviet Union was initially interested in purchasing +2.3 mln tonnes lof corn from Argentina. + However, Soviet purchases from the United States have +tended to displace additional Argentine purchases, the report +said. + The USDA has to date reported USSR purchases of 2.6 mln +tonnes of U.S. corn for delivery in the current U.S.-USSR grain +agreement year, which ends this September 30, it said. + Reuter + + + + 1-APR-1987 11:57:23.68 + +usa + + + + + + +F Y +f1519reute +r f BC-GPU'S-<GPU>-THREE-MIL 04-01 0085 + +GPU'S <GPU> THREE MILE ISLAND POWER REDUCED + MIDDLETOWN, Pa., April 1 - General Public Utilities corp +said its Three Mile Island Unit One's power output has been cut +to 81 pct of reactor power, or 730 megawatts of electricity, +due to mineral deposits on the secondary or non-nuclear side of +its two steam generators. + The company said the deposits do not affect the safe +operation of the plant but interfere with the production of +steam. + It said the unit was similarly limited in power in late +1985. + Reuter + + + + 1-APR-1987 11:58:09.69 + +usa + + + + + + +F +f1524reute +r f BC-CYPRUS-MINERALS-<CYPM 04-01 0064 + +CYPRUS MINERALS <CYPM> WINS COAL CONTRACT + DENVER, April 1 - Cyprus Minerals Co said it was awarded a +five year contract to supply 360,000 tons of steam coal to +Niagara Mohawk Power Co <NMK>. + The company is currently shipping 240,000 tons of steam +coal a year to Niagara Mohawk under a contract signed in 1985. +The coal comes from the Emerald mine in Southwestern +Pennsylvania. + + Reuter + + + + 1-APR-1987 11:58:19.48 + +usa + + + + + + +F +f1525reute +r f BC-QUANTECH-<QANT>-SAYS 04-01 0103 + +QUANTECH <QANT> SAYS THREE DIRECTORS RESIGN + LEVITTOWN, N.Y., April 1, Quantech Electronics Corp said +Leonard N. Hecht, Jack Goldfarb and Harold V. Wallace resigned +as directors. + On March 26, the company announced the resignations of +Bernard Weinblatt as president and a director, and Hecht as +chief executive officer. It said Hecht will serve as a +consultant for an interim period. + Quantech said its remaining directors are Henry Ginsberg +and David Siegel. Ginsberg, who is chairman, has been named +president and chief executive officer, and Siegel has been +named chief operating officer, the company said. + Reuter + + + + + + 1-APR-1987 11:58:27.08 +earn +usa + + + + + + +F +f1526reute +r f BC-BARNES-GROUP-<B>-EXPE 04-01 0104 + +BARNES GROUP <B> EXPECTS SALES TO GROW MODESTLY + HARTFORD, Conn., April 1 - Barnes Group said it expects +sales and net income for 1987 will be up slightly over 1986. + Without supplying specific figures, Barnes told +shareholders at its annual meeting it expected net income to +improve at a rate exceeding its growth in sales, which was two +pct higher than 1985. + The company said it recorded income from continuing +operations of 16.6 mln dlrs, or 2.57 dlrs per share, on sales +of 440 mln dlrs in 1986. It said it recorded income from +continuing operations of 16.4 mln dlrs, or 2.27 dlrs per share, +in the previous year. + Reuter + + + + 1-APR-1987 11:58:33.10 + +usa + + + + + + +A RM +f1527reute +r f BC-UNITED-CITIES-<UCIT> 04-01 0078 + +UNITED CITIES <UCIT> PRIVATELY PLACES BONDS + NEW YORK, April 1 - United Cities Gas Co said it placed +privately on March 18 20 mln dlrs of 8.69 pct first mortgage +bonds. + Proceeds will be used to retire short-term debt and fund +the company's current construction program, United Cities said. + The company said more than 30 lending institutions +participated in the bidding for the bonds and that 25 pct of +the issue was placed with the U.S. unit of a Canadian firm. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-013.sgm b/src/test/data/reuters-21578/reut2-013.sgm new file mode 100644 index 00000000000..de710e121bf --- /dev/null +++ b/src/test/data/reuters-21578/reut2-013.sgm @@ -0,0 +1,2011 @@ + + + 3-APR-1987 12:41:43.18 + +usa + + + + + + +F +f1680reute +b f BC-CHRYSLER-<C>-LATE-MAR 04-03 0085 + +CHRYSLER <C> LATE MARCH U.S. CAR SALES UP + DETROIT, April 3 - Chrysler Corp said car sales for the +March 21-31 period rose 20.2 pct to 40,454 from 33,669 a year +earlier. + For the month of March, it said auto sales increased 6.3 +pct to 96,649 from 90,945. + Chrysler said U.S. truck sales in late March jumped 65.2 +pct to 28,698 from 17,372 a year ago. For the entire month, +truck sales advanced 28.9 pct to 63,283 from 49,102, it said. + The company said it was still tabulating year-to-date +figures. + Reuter + + + + 3-APR-1987 12:42:15.79 + +usa + + + + + + +F +f1682reute +u f BC-WALL-STREET-STOCKS/CO 04-03 0085 + +WALL STREET STOCKS/COMPAQ COMPUTER <CPQ> + NEW YORK, April 3 - Compaq Computer Corp, IBM's chief +rival in the personal computer market, scored a big gain on +Wall Street today. Compaq's stock rose 1-3/8 to 32-1/4 on +volume of 1.3 mln shares. + "The rationale for the move," one trader said, "is that the +damage from the IBM announcement yesterday was less than +expected." He said Compaq's stock had been under pressure +recently because of anticipation of IBM's unveiling of a new +line of personal computers. + International Business Machines <IBM> introduced four new +personal computers and more than 100 new peripheral products. +But analysts said the new computers, though they do contain a +lot of proprietary concepts, will not be as hard to copy as +some other PC makers had feared. + "The long range issue here is who wins and who loses in the +PC business, and that issue was not resolved yesterday and is +unlikely to be decided any time soon," analyst Mark Stahlman of +Sanford C. Bernstein and Co said. + Stahlman reaffirmed his recommendation of Compaq and Apple +Computer Inc <AAPL>. + Stahlman said "The critical investment question now is who +will have a pickup in sales in the near term. We expect to see +a strong demand setting for PCs for the rest of this year, and +that will boost the revenues for all of the major PC vendors." + "The first quarter was the strongest PC sales period on +record for Compaq, Apple and IBM," Stahlman said, "and I don't +think the IBM announcement is going to change that trend soon." + "In anticipating the IBM announcement, Compaq has made +pricing adjustments necessary to compete for its immediate +purposes," he said. + Reuter + + + + 3-APR-1987 12:43:33.42 +copper +canada + + + + + + +E F +f1686reute +r f BC-noranda-sets-temporar 04-03 0090 + +NORANDA SETS TEMPORARY MINE SHUTDOWN + Murdochville, Quebec, April 3 - <Noranda Inc> said +production will remain shut down at its fire-damaged copper +mine here until it can completely examine the mine. + The fire, which started Wednesday and burned itself out +late yesterday, killed one miner and trapped 56 others +underground for about 24 hours. The 56 were eventually brought +safely out of the mine. + Company spokesman Dale Coffin said the investigation could +take from a few days to several weeks, but would not be more +specific. + Noranda said that, when it resumes production, it plans to +operate the mine at about one-third of the normal 72,000 metric +tons annual finished capacity. + The fire weakened part of the mine's support structure, +Coffin said. + Noranda said if it decides to keep the mine open, it would +take four or five months before it could resume full +production. + Reuter + + + + 3-APR-1987 12:48:00.50 + +canada + + + + + + +E A RM +f1694reute +u f BC-CANADA-BUDGET-DEFICIT 04-03 0115 + +CANADA BUDGET DEFICIT RISES IN JANUARY + OTTAWA, April 3 - The Canadian government's budget deficit +rose to 1.78 billion dlrs in January from 1.67 billion dlrs in +the same month last year, the finance department said. + But the deficit in the first 10 months of the fiscal year +which began on April 1, 1986, fell to 22.36 billion dlrs from +25.74 billion dlrs in the same period a year ago. + January revenues rose to 7.96 billion dlrs from 7.56 +billion dlrs while expenditures grew to 9.74 billion dlrs from +9.23 billion dlrs. Revenues in the first 10 months increased to +70.06 billion dlrs from 62.30 billion while expenditures grew +to 92.42 billion dlrs from 88.05 billion. + Reuter + + + + 3-APR-1987 12:49:26.47 +acq +usaswitzerland + + + + + + +F +f1697reute +r f BC-CIS-TECHNOLOGIES<CIH> 04-03 0099 + +CIS TECHNOLOGIES<CIH> TO SELL SHARES TO SWISS CO + TULSA, Okla, April 3 - CIS Technologies Inc said it +executed a formal share purchase agreement with Swiss +Reinsurance Co of Zurich, Switzerland. + Under terms of the agreement, Swiss Re will acquire 5.5 mln +newly issued CIS stock at 2.50 dlrs a share, or 13.8 mln dlrs. +This purchase represents 30 pct of the outstanding shares. + Swiss Re will acuqire 500,000 of the shares immediately and +remaining shares will be bought after a due diligence report is +completed by auditors. + The transaction is expected to be complete by June 11. + Reuter + + + + 3-APR-1987 12:51:05.81 +earn +usa + + + + + + +F +f1701reute +r f BC-COPLEY-PROPERTIES-INC 04-03 0025 + +COPLEY PROPERTIES INC <COP> INCREASES DIVIDEND + BOSTON, Mass, APril 3 - + Qtly div 42 cts vs 41.5 cts prior + Payable APril 28 + Record April 14 + Reuter + + + + 3-APR-1987 12:52:18.65 +cpi +colombia + + + + + + +RM +f1705reute +r f BC-COLOMBIAN-INFLATION-S 04-03 0085 + +COLOMBIAN INFLATION STABLE AT AROUND 20 PCT + BOGOTA, April 3 - Colombia's cost of living index rose 2.71 +pct in March, after a 2.03 pct increase in February and a 2.21 +pct rise in March 1986, the government statistics institute +said. + The result brought year-on-year inflation to 20.36 pct +compared with 22.65 pct at end-March 1986 and 19.77 pct for the +year ending February 1987. + The government has predicted that inflation this year would +be slightly lower than in 1986 when it reached 20.9 pct. + REUTER + + + + 3-APR-1987 12:52:47.08 +interest +usa + + + + + + +A RM +f1708reute +r f BC-FHLBB-SAYS-MORTGAGE-R 04-03 0103 + +FHLBB SAYS MORTGAGE RATES CONTINUE DECLINE + WASHINGTON, April 3 - The Federal Home Loan Bank Board said +home mortgage rates fell from early February to early March to +their lowest point in nine years, but the rate of decline was +slower than it had been in recent months. + The bank board said the average effective commitment rate +for fixed-rate mortgages for single family homes and a 25 pct +loan-to-price ratio with a maturity of at least 15 years was +9.48 pct in early March. + The rate was four basis points lower than a month ago, only +one-eighth the size of decline in the previous month, the bank +board said. + Rates for adjustable-rate mortgages decline eight basis +points from early February to 8.43 pct in early March, the bank +board said. The drop was far less than the 15 basis point +decline in the previous period, the agency said. + The average effective interest rate on all loans closed by +major mortgage lenders declined nine basis points from early +February to early March, the agency said. The fall brought the +rate to 9.14 pct was the lowest since December 1977, it said. + The effective rate for ARMS was 8.39 pct, 15 basis points +below a month earlier. For fixed-rate loans it was 9.36 pct, 14 +basis points below a month earlier, the agency said. + Reuter + + + + 3-APR-1987 12:56:19.95 + +usa + + +nyse + + + +F +f1713reute +d f BC-NYFE-SEAT-SELLS-FOR-1 04-03 0048 + +NYFE SEAT SELLS FOR 1,500 DLRS + NEW YORK, April 3 - The New York Stock Exchange said a seat +on the New York Futures Exchange sold for 1,500 dlrs, which is +up 250 dlrs from the previous sale yesterday. + The Exchange said the current bid is 1,250 and the current +offer is 1,500 dlrs. + Reuter + + + + 3-APR-1987 12:56:53.22 +money-supply +canada + + + + + + +E RM +f1716reute +f f BC-CANADIAN-MONEY-SUPPLY 04-03 0014 + +******CANADIAN MONEY SUPPLY M-1 FALLS 291 MLN DLRS IN WEEK, BANK OF CANADA SAID +Blah blah blah. + + + + + + 3-APR-1987 12:58:50.26 +acq +usa + + + + + + +F +f1722reute +r f BC-BENEFICIAL-<BNL>-UNIT 04-03 0100 + +BENEFICIAL <BNL> UNIT SALE APPROVED + NEW YORK, April 3 - Beneficial Corp said the sale of its +American Centennial Insurance Co subsidiary to <First Delaware +Holdings Inc> was approved by the Delaware Insurance +Department. + Under the transaction, American Centennial will receive a +cash infusion of 200 mln dlrs, including the settlement of tax +sharing agreements with Beneficial Corp, Beneficial said. + It will also receive 25 mln dlrs from Beneficial +International Insurance Co, another Beneficial subsidiary being +purchased by the management-led group of First Delaware, the +company said. + Reuter + + + + 3-APR-1987 12:59:13.76 + +netherlands + + +asecboe + + + +C +f1724reute +d f BC-LARGER-VOLUME-SEEN-ON 04-03 0114 + +LARGER VOLUME SEEN ON EUROPEAN OPTIONS EXCHANGES + AMSTERDAM, April 3 - European options exchanges will see +spectacular growth over the next five years as more +professional investors discover the options markets, Bernard +Reed, manager of the London options exchange said. + At an options outlook seminar to mark tomorrow's official +opening of a new Amsterdam options exchange (EOE) building, he +forecast increasing interest from banks and institutional +investors, using options for portfolio insurance. + "But the dominance by the professionals should not make us +neglect private clients," he noted. "Successful exploitation of +retail business has been one of the keys to success." + Reed said derived option products in particular will become +a popular instrument for managing equity risks. On the Chicago +Board Options Exchange (CBOE), the cash-settled S&P 100 index +option is the most traded in the world. + Dutch Stock Index Fund options to be relaunched on May 18 +and the upcoming options on London's FTSE 100 index will see a +30 pct yearly turnover growth until 1990, Reed estimated. + The CBOE and the Chicago Mercantile Exchange have agreed +with Morgan Stanley to trade options and futures on the capital +international EAFE index which will let investors participate +in worldwide market moves. + Reed said he did not believe in globalising the option +business by introducing international products, because this +would intensify competition among the exchanges, but he did see +a future for global rules and regulations. + Reuter + + + + 3-APR-1987 13:05:49.54 + +usa + + + + + + +F +f1749reute +r f BC-TIERCO-<TIER>-SELLS-N 04-03 0057 + +TIERCO <TIER> SELLS NOTE + OKLAHOMA CITY, April 3 - Tierco Group INc said it sold at +par to the Kuwait Real Estate INvestment and Management Co its +10 mln dlrs 75. pct senior subordinated note due 1997, together +with warrants to buy 1.1 mln shares of common stock. + The warrant may be exercised within five years at 9.50 dlrs +per share. + Reuter + + + + 3-APR-1987 13:05:53.71 +earn +canada + + + + + + +E F +f1750reute +r f BC-itt-canada-ltd 04-03 0040 + +<ITT CANADA LTD> YEAR NET + TORONTO, April 3 - + Shr 5.56 dlrs vs 3.88 dlrs + Net 47.5 mln vs 33.2 mln + Revs 254.5 mln vs 243.5 mln + Note: shr after preferred dividends + ITT Corp <ITT> owns 100 pct of ITT Canada common shares + Reuter + + + + 3-APR-1987 13:06:02.09 + +usa + + + + + + +F +f1751reute +d f BC-******ALLIED-SIGNAL-T 04-03 0089 + +CALIFORNIA MICRO DEVICES <CAMD> IN DEFENSE DEAL + MILPITAS, Calif, April 3 - California Micro Devices Corp +said an additional 3.2 mln dlrs contract was received from +General Dynamics Corp <GD> to supply electronic components +contained in the guidance control for Defense Electronics +Systems. + This contract follows a 750,000 dlrs contract awarded last +year. + Shipments will begin in APril 1987. + The company also disclosed that Fuji Photo Film Co Ltd is +the licensee of a one mln dlrs technology agreement announced +last fall. + Reuter + + + + 3-APR-1987 13:06:05.40 + +usa + + + + + + +F +f1752reute +d f BC-STEWART-INFORMATION-R 04-03 0032 + +STEWART INFORMATION RESCHEDULES ANNUAL MEETING + HOUSTON, APRIL 3 - Stewart INformation Services Corp said +it rescheduled its annual meeting to May 18. + It had been scheduled for APril 24. + Reuter + + + + 3-APR-1987 13:06:11.03 + +usa + + + + + + +F +f1753reute +h f BC-FISERVE-<FISV>-GETS-B 04-03 0061 + +FISERVE <FISV> GETS BUSINESS WORTH ONE MLN DLRS + WEST ALLIS, Wis., April 3 - FIserve Inc said 14 savings and +loans with 1.5 billion dlrs in cumulative assets will transfer +their data processing to FIserve from Midwest Commerce Data +Corp, a unit of Midwest Commerce Corp. + About one mln dlrs a year in new recurring revenues will be +generated for FIserve, it said. + Reuter + + + + 3-APR-1987 13:14:52.25 + +usa + + + + + + +F +f1764reute +r f BC-MONY-REAL-<MYM>-REPOR 04-03 0086 + +MONY REAL <MYM> REPORTS PORTFOLIO + NEW YORK, April 3 - Mony Real Estate Investors Trust said +its investment portfolio consists of 137.1 mln dlrs of +mortgages with an average maturity of less than six years, 43.7 +mln dlrs of real estate equities and 2.7 mln dlrs of foreclosed +real estate. + The trust's exposure to oil-dependent regions is limited to +2.2 mln dlrs, it said. + It said it accepted an offer to sell foreclosed property +and increased its loss reserve by 750,000 dlrs in anticipation +of the sale. + Reuter + + + + 3-APR-1987 13:17:05.48 +money-supply +canada + + + + + + +E A RM +f1768reute +u f BC-CANADIAN-MONEY-SUPPLY 04-03 0099 + +CANADIAN MONEY SUPPLY FALLS IN WEEK + OTTAWA, April 3 - Canadian narrowly-defined money supply +M-1 fell 291 mln dlrs to 32.44 billion dlrs in the week ended +March 25, Bank of Canada said. + M-1-A, which is M-1 plus daily interest chequable and +non-personal deposits, fell 7 mln dlrs to 75.14 billion dlrs +and M-2, which is M-1-A plus other notice and personal +fixed-term deposits, fell 56 mln dlrs to 177.54 billion dlrs. + M-3, which is non-personal fixed term deposits and foreign +currency deposits of residents booked at chartered banks in +Canada, rose 321 mln dlrs to 216.67 billion dlrs. + Chartered bank general loans outstanding fell 169 mln dlrs +to 126.03 billion dlrs. + Canadian liquid plus short term assets rose 72 mln dlrs to +36.47 billion dlrs and total Canadian dollar major assets of +the chartered banks rose 507 mln dlrs to 224.22 billion dlrs. + Chartered bank net foreign currency assets fell 231 mln +dlrs to minus 2.00 billion dlrs. + Notes in circulation totalled 16.16 billion dlrs, up 50 mln +dlrs from the week before. + Government cash balances fell 1.17 billion dlrs to 4.63 +billion dlrs in week ended April 1. + Government securities outstanding rose 1.09 billion dlrs to +226.42 billion dlrs in week ended April 1, treasury bills rose +1.35 billion dlrs to 76.95 billion dlrs and Canada Savings +Bonds fell 47 mln dlrs to 43.87 billion dlrs. + Reuter + + + + 3-APR-1987 13:17:16.61 + +usa + + + + + + +F +f1769reute +r f BC-COPLEY-PROPERTIES-<CO 04-03 0072 + +COPLEY PROPERTIES <COP> TO INVEST IN JOINT PACT + BOSTON, April 3 - Copley Properties Inc said the company +will invest 9,500,000 dlrs in a joint venture to acquire and +develop 33.4 acres of industrial land in Hayward, Calif. + Copley said it will own 60 pct of the project and be +entitled to a 10 pct preferential return on its investment plus +60 pct of all excess cash from operations, refinancings and +other capital transactions. + Reuter + + + + 3-APR-1987 13:18:53.02 +acq +usa + + + + + + +F +f1775reute +r f BC-UNION-TO-PROTEST-DART 04-03 0103 + +UNION TO PROTEST DART'S SUPERMARKETS <SGL> BID + LANDOVER, MD., April 3 - The United Food And Commercial +Workers said that more than 1,000 rank-and-file members of the +union will demonstrate Monday at Dart Group Corp's headquarters +protesting Dart's proposed 1.73 billion dlr takover of +Supermarkets General <SGL>. + Supermarkets is best known for its Pathmark chain of +supermarket drug stores in the New York and New Jersey area and +also owns Rickels home centers. + The union said that it is firmly against the Dart bid +because "workers have always ended up with a raw deal in the +current takeover mania." + A Union statement said: "We do not intend to allow our +members to pick up the tab for Supermarket General's executives +and the bankers or the Dart Group who stand to make millions." + Dart is controlled by the Haft family of Washington, which +last year made a bid for California-based Safeway Stores Inc. +The Hafts lost, but walked away with at least 100 mln dlrs in +profits, analysts estimate. + The union said that Dart's Safeway bid forced a major +restructuring at Safeway to pay the Hafts and their lawyers and +caused a loss of thousands of jobs. + Reuter + + + + 3-APR-1987 13:19:08.87 + +usa + + + + + + +F +f1776reute +u f BC-PAN-AM-<PN>-MARCH-LOA 04-03 0086 + +PAN AM <PN> MARCH LOAD FACTOR ROSE TO 60.6 PCT + NEW YORK, April 3 - Pan Am Corp's Pan American World +Airways said its load factor rose to 60.6 pct last month from +54.9 pct in March 1986. + The airline said its scheduled March traffic increased 14.6 +pct to 1.94 billion revenue passenger miles from 1.70 billion +last year as available seat miles rose 3.8 pct to 3.21 billion +from 3.09 billion. + It said the March traffic increase was the third +consecutive month of year over year traffic growth for Pan Am. + For the first quarter, Pan Am said, its load factor +increased to 56.3 pct from 53.4 pct as scheduled traffic +increased 10.2 pct to 5.25 billion miles and available seat +miles increased 4.5 pct to 9.32 billion. + The airlines said its March scheduled freight ton miles +increased 1.5 pct to 53.3 mln from 52.5 mln and was up 0.4 pct +for the first quarter to 134.6 mln. + Reuter + + + + 3-APR-1987 13:21:48.58 +acq +usa + + + + + + +F +f1785reute +u f BC-FCS-LABORATORIES-<FCS 04-03 0099 + +FCS LABORATORIES <FCSI> TERMINATES DEAL TALKS + TEMPE, Ariz., April 3 - FCS Laboratories Inc said merger +discussions with an unnamed privately-held company in the +health care field have ended without an agreement. + The previously announced negotiations began last August, +the company said. + "It's disappointing to spend so much time on these +negotiations and have them fail," said FCS chairman Nicholas +Gallo III. "But the discussions could not produce a deal +acceptable to our board in the context of the company's +stronger financial position today as compared to six months +ago." + Gallo said FCS will stop actively seeking potential merger +partners, but will respond to serious inquiries. + "We are determined to follow our plan to restore this +company to profitability," he said. "To continue actively +searching for potential acquirers inherently forces us to +postpone the implementation of critical decisions which are +part of the plan." + The company, which has 4,475,930 common shares outstanding, +reaffirmed it expects to be profitable in the second half of +the fiscal year ending September 30, 1987. + Reuter + + + + 3-APR-1987 13:23:23.58 +interest +usa + + + + + + +A RM +f1794reute +u f BC-WHITE-HOUSE-SAYS-INTE 04-03 0090 + +WHITE HOUSE SAYS INTEREST RATES REFLECT MARKET + WASHINGTON, April 3 - The White House said the rise in +interest rates was "unfortunate in a general sense" but reflected +market forces. + "There's always movement up and down and the basic fact is +that we believe the economy is strong and growing and there +will always be fluctuations in the interest rate, but the +economy is sound and in good shape," spokesman Marlin Fitzwater +said. + Citibank raised its prime rate by one quarter of a point +and the move was followed by other banks. + Reuter + + + + 3-APR-1987 13:25:20.85 +earn +usa + + + + + + +F +f1799reute +d f BC-REGAL-PETROLEUM-LTD-< 04-03 0049 + +REGAL PETROLEUM LTD <RPLO> YEAR + THE WOODLANDS, TExas, April 3 - + Shr loss nine cts + Net loss 1.4 mln + Revs 630,118 dlrs + NOTE:Due to change in fiscal year, prior 4th qth and year +cannot be presented on comparable basis. 1986 loss includes +writedowns approximating 1.4 mln dlrs. + Reuter + + + + 3-APR-1987 13:26:03.77 +earn +usa + + + + + + +F +f1801reute +w f BC-CANTERBURY-PRESS-INC 04-03 0042 + +CANTERBURY PRESS INC YEAR NOV 30 + MEDFORD, N.J., April 3 - + Shr 1.1 cts vs 1.7 cts + Net 26,708 vs 35,084 + Revs 447,548 vs 243,161 + NOTE:1986 net includes 4,300 dlrs gain from tax credit and +1985 includes gain of 8,300 dlrs gain from credit. + Reuter + + + + 3-APR-1987 13:26:44.58 +earn +usa + + + + + + +F +f1803reute +d f BC-GRAPHIC-MEDIA-INC-<GM 04-03 0044 + +GRAPHIC MEDIA INC <GMED> YEAR + FAIRFIELD, N.J., April 3 - + Shr nine cts vs 19 cts + Net 188,000 vs 362,000 + Revs 20.4 mln vs 11.3 mln + NOTE:1985 restated for reversal of certain tax benefits. +1986 and 1985 reflects preferred stock dividend requirements. + Reuter + + + + 3-APR-1987 13:27:04.11 + + + + + + + + +CQ MQ +f1804reute +r f BC-cbt-silver-vol-oi 04-03 0080 + +CBT SILVER VOLUME/OPEN INTEREST FOR APRIL 2 + VOLUME OPEN-INT CHANGE + Apr 714 684 up 516 + May 14 36 dn 1 + Jun 3097 7109 dn 140 + Aug 86 537 up 20 + Oct 12 157 up 7 + Dec 215 3125 up 56 + Feb 3 252 up 1 + Apr 28 1275 dn 2 + Jun 54 103 up 49 + Aug 0 9 unch + TTL 4223 13287 up 506 + Reuter + + + + + + 3-APR-1987 13:27:08.42 + + + + + + + + +FQ EQ +f1805reute +u f BC-WALL-STREET-INDICES-1 04-03 0040 + +WALL STREET INDICES 1300 + + NYSE COMPOSITE 168.38 UP 1.62 + NYSE INDUSTRIALS 203.81 UP 2.34 + S AND P COMPOSITE 296.94 UP 3.31 + + NYSE-A VOLUME 154525400 + + AMEX INDEX 338.30 UP 3.06 + + AMEX-B VOLUME 11343900 + + + + + + 3-APR-1987 13:27:38.57 + +usa + + + + + + +F A +f1806reute +r f BC-BURLINGTON-<BNI>-UNIT 04-03 0082 + +BURLINGTON <BNI> UNIT SETTLES BONDHOLDER SUIT + SEATTLE, April 3 - Burlington Northern Inc said its +Burlington Northern Railroad Co unit reached an agreement in +principle to settle a class action lawsuit filed against the +company in May 1985 by holders of two series of the company's +bonds. + It said the settlement arrangement calls for the company to +establish a cash settlement fund of 35.5 mln dlrs, which would +be distributed to the bondholders after deductions for +attorney's fees. + The lawsuit, filed by holders of its four pct Prior Lien +bonds due January 1, 1997 and its three pct General Lien Bonds +due January 1, 2047, sought to prevent the release of +collateral, the company said. + If the settlement agreement is approved, the trading prices +of the bonds will decline substantially because they will no +longer reflect the speculative premiums at which the bonds +currently trade, Burlington Northern also said. + It said the settlement is subject to negotiation by +Burlington Northern, the Citibank N.A. unit of Citicorp <CCI> +and Bankers Trust Co <BT>, the bonds' trustees. + Reuter + + + + 3-APR-1987 13:27:46.34 +earn +usa + + + + + + +F +f1807reute +r f BC-RICHARDSON-ELECTRONIC 04-03 0073 + +RICHARDSON ELECTRONICS <RELL> 3RD QTR FEB 28 NET + LaFox, Ill., April 3 - + Shr 20 cts vs 20 cts + Net 1,981,000 vs 1,689,000 + Rev 24.7 mln vs 19.6 mln + Nine months + Shr 59 cts vs 53 cts + Net 5,855,000 vs 4,360,000 + Rev 70.9 mln vs 51.9 mln + NOTE: Fiscal 1986 per share data reflects dilutive effect +of shares issued for April 1986 convertible debenture +conversion. Company's full name is Richarson Electronics Ltd. + Reuter + + + + 3-APR-1987 13:29:07.38 +earn +usa + + + + + + +F +f1812reute +d f BC-DIVERSIFIED-HUMAN-RES 04-03 0038 + +DIVERSIFIED HUMAN RESROUCES GROUP <HIRE> YEAR + DALLAS, APril 3 - + Shr loss five cts vs profit 72 cts + Net loss 79,069 vs profit 829,737 + Revs 14.4 mln vs 14.1 mln + NOTE:1985 includes extraordainy credit of 11 cts. + Reuter + + + + 3-APR-1987 13:30:04.51 + +usa + + + + + + +F +f1813reute +r f BC-ALASKA-AIR-<ALK>-UNIT 04-03 0110 + +ALASKA AIR <ALK> UNIT HAS HIGHER LOAD FACTOR + SEATTLE, April 3 - The Alaska Airlines unit of Alaska Air +Group Inc said its March load factor rose to 58.1 pct from 57.3 +pct a year earlier, but its year-to-date load factor dropped to +51.8 pct from 52.6 pct last year. + March revenue passenger miles rose five pct to 225.9 mln +from 215.6 mln, but year-to-date revenue miles fell one pct to +586.7 mln from 593 mln. + Available seat miles for the month totaled 389.1 mln, a +three pct increase over the 376.1 mln posted for March 1986, +and for the year-to-date available miles totaled 1.132 billion +compared with 1.128 billion a year earlier, Alaska Air said. + Reuter + + + + 3-APR-1987 13:30:26.85 + +ukjapan +nakasonethatcher + + + + + +RM +f1815reute +u f BC-UK-MINISTER-LOOKS-TO 04-03 0112 + +UK MINISTER LOOKS TO EASE TENSION ON TOKYO TRIP + By Sten Stovall, Reuters + LONDON, April 3 - The U.K. Government hopes for a +breakthrough on the deadlock with Japan over trade policies +during next week's visit to Tokyo by Corporate Affairs Minister +Michael Howard, political sources said. + Howard, who leaves for Japan tomorrow, told Reuters he will +try to promote understanding on trade issues during his visit. + Meanwhile, Britain will re-examine a letter from Japanese +Prime Minister Yasuhiro Nakasone promising personal help in +solving the row over a U.K. Firm's bid to win a significant +role in Japan's telecommunications market, government sources +said. + Tensions have risen following Britain's decision to arm +itself early with new statutory powers which it says could be +used against certain Japanese financial institutions. + Britain reacted optimistically at first to the letter from +Nakasone to Prime Minister Margaret Thatcher, seeing it as a +signal that he would work towards ensuring a satisfactory +outcome to the bid launched by Cable and Wireless Plc <CAWL.L>, +government officials said. + But this view has since been clouded by reports from Tokyo +that Nakasone's assurances really constituted little more than +politeness in the face of British anger, they added. + Howard said he would use his trip to push for a bigger role +in Japan's telecommunications industry for Cable and Wireless +Plc. The U.K. Government has made the issue a test case for +Japan's willingness to open its markets adequately to outside +competition. + Asked whether the letter from Nakasone was a rejection of +attempts by Britain to achieve that, Howard said "I am not sure +it is correct to regard Mr Nakasone's letter as a rejection of +Mrs Thatcher's request of him - and it says he is taking a +personal interest in this problem. + "I don't understand it to be closed at all." + Howard added that during his Tokyo visit he would be +"talking to them about it (the letter), finding out exactly what +they do mean about it, and making it plain that we take a very +serious view of the fact that access to Japanese markets is not +as free as we allow access to our markets to be." + He noted that under the new Financial Services Act, Britain +could revoke or deny licences to Japanese banking and insurance +institutions in London if U.K. Firms fail to receive similar +treatment in financial markets in Japan soon. + "I hope it won't come to that, and I don't think it will," +Howard added. + During the trip Howard will meet officials in the Tokyo +Stock Exchange, the Ministry of Finance, the Trade Ministry, +and Posts and Telecommunications Minister Shunjiro Karasawa. + Karasawa is regarded as behind opposition to any +significant role for Cable and Wireless in the Japanese +telecommunications industry. + Share prices on the London Stock Exchange were undermined +again today by fears of a possible U.K./Japanese trade war. +This was despite denials by Trade and Industry Secretary Paul +Channon that Britain was on the verge of a trade war. + He told a meeting of insurance brokers today that Britain +believed a "sensible solution" could be found which would open +Japanese markets to British goods. + Government officials were at pains today to deny that +Britain had set a deadline of three weeks for Japan to promise +similar access to its financial markets to U.K.-based financial +firms as that enjoyed in London by equivalent Japanese firms. + They said that Department of Trade and Industry officials +had said yesterday that the measures against Japanese financial +institutions could be imposed from then but that this did not +necessarily constitute a deadline. + Experts believe Britain would lose out by acting against +Japanese banks, insurance and investment institutions. But +despite the danger of Japanese firms taking their trade +elsewhere in Europe, Howard said he did not expect the move to +backfire. + He said in a radio interview today "it is true that we +benefit from their presence - but they would not want to lose +those advantages. And I am sure they are making their views +plain to the Japanese government on this matter." + Howard, who will also be visiting South Korea before +returning to London on April 11, said his trip to Tokyo was +planned well before the current trade row. + Howard said his talks with Japanese officials would also +include ways of jointly combating financial fraud in global +markets with Japanese officials. This would be done through a +cooperation between national regulatory bodies. + He said a memorandum of understanding for exchanging +information to combat financial fraud would be sought with +Japan on terms similar to one signed last autumn between +Britain and the United States. + REUTER + + + + 3-APR-1987 13:33:25.31 + +usa + + + + + + +F +f1828reute +d f BC-PACIFIC-GAS-<PCG>-PLA 04-03 0103 + +PACIFIC GAS <PCG> PLANT TO BEGIN REFUELING + SAN FRANCISCO, April 3 - Pacific Gas and Electric Co said +its Diablo Canyon Unit 2 nuclear power plant will begin its +first refueling today after about 13 months of operation. + The refueling outage is expected to last about 12 weeks and +will include a variety of maintenance as well as the +replacement of about one-third of Unit 2's fuel, the company +said. + Pacific Gas said Unit 2 generated power about 93.7 pct of +the time during its first year of operation. + Pacific Gas' two Diablo Canyon units generate about 2.2 mln +kilowatts of electricity in full operation. + Reuter + + + + 3-APR-1987 13:34:29.36 +acq +usa + + + + + + +F +f1833reute +d f BC-MID-STATE-<MSSL>,-FIR 04-03 0067 + +MID-STATE <MSSL>, FIRST FEDERAL IN DEAL + OCALA, Fla, April 3 - Mid-State Federal Savings and Loan +Association said it and First Federal Savings and Loan +Association of Brooksville <FFBV> reached a definitive merger +agreement. + As previously announced, Brooksville shareholders will get +cash and stock in exchange for their shares. The transaction is +expected to be completed during the summer 1987. + Reuter + + + + 3-APR-1987 13:34:50.83 +acq +canada + + + + + + +E F +f1835reute +r f BC-memotec-data-complete 04-03 0110 + +MEMOTEC DATA COMPLETES TELEGLOBE ACQUISITION + MONTREAL, April 3 - <Memotec Data Inc> said it completed +the previously announced 488.3 mln dlr acquisition of Teleglobe +Canada from the federal government. + Memotec Data said Teleglobe, which has provided Canada's +overseas telecommunications services since 1950, now becomes +Teleglobe Canada Inc, a unit of Memotec. + Teleglobe president and chief executive Jean-Claude Delorme +will continue in the same post, the company said. + In addition to the sale price, the government will receive +Teleglobe's accumulated cash of 102 mln dlrs and a special 18 +mln dlr dividend, making total proceeds 608.3 mln dlrs. + Reuter + + + + 3-APR-1987 13:37:55.73 + +usa + + + + + + +F +f1839reute +d f BC-CITIZENS-FIRST-BANCOR 04-03 0133 + +CITIZENS FIRST BANCORP <CFB> RECEIVES FINE + GLEN ROCK, N.J., April 3 - Citizens First Bancorp Inc said +its banking subsidiary pleaded guilty to two technical +violations of the Bank Secrecy Act and was fined 2,000 dlrs. + The subsidiary, Citizens First National Bank of New Jersey, +pleaded guilty to two misdemeanors in Federal District Court +for the District of New Jersey. Charges had been brought by the +U.S. Attorney's office. + The company said no additional charges will be brought +against it and that it has instituted additional procedures to +reduce the possibility of future violations. It cooperated with +authorities in the investigation. + The violations occurred on Aug 12, 1982, and May 25, 1984, +when the bank failed to report currency transactions involving +more than 10,000 dlrs. + Reuter + + + + 3-APR-1987 13:40:10.81 +trade +usajapan + + + + + + +F +f1844reute +u f AM-TRADE-AMERICAN 04-03 0100 + +U.S., JAPANESE OPEN TALKS ON SEMICONDUCTORS + WASHINGTON, April 5 - U.S. and Japanese officials meet +tomorrow to try to settle a dispute over semiconductor trade +and to cut short the 300 mln dlr penalty tariffs President +Reagan has ordered imposed on Japanese exports. + But U.S. officials held out little hope that any accord +could be reached before the tariffs of 100 per cent - up from +about five per cent - are to take effect on April 17. + The Customs Bureau last week started to levy a bond on the +Japanese goods that Reagan ordered penalized. The penalties +would be retroactive to March 31. + Reagan said on March 27 when ordering the tariffs that he +hoped the Japanese would soon end their unfair practices in +semiconductor trade and that sanctions could be lifted. + Technical meetings are to be held today and tomorrow, with +meetings at a more senior level scheduled for Thursday and +Friday. Public hearings on the sanctions are set for April 13. + The Japanese aides here for the technical talks include +Shigeru Muraoka, director-general of international trade policy +of the Ministry of International Trade and Industry (MITI), and +Masashi Yamamoto, deputy director-general of the information +and machinery bureau. + Meeting with them will Glen Fukushima, director of the +Japan office of the U.S. Trade Representative's Office, and Jim +Gradoville, of trade representative's office of industry and +services. + The two sides in the Thursday and Friday talks will be +headed by Deputy U.S. Trade Representative Michael Smith and +MITI vice minister Makoto Kuroda. + + Reuter + + + + 3-APR-1987 13:41:26.38 + +usa + + + + + + +F +f1847reute +r f BC-TRIBUNE-<TRB>-FILES-3 04-03 0051 + +TRIBUNE <TRB> FILES 300 MLN DLR SHELF REGISTRATION + CHICAGO, April 3 - Tribune Co said it filed a shelf +registration with the Securities and Exchange Commission for +300 mln dlrs in debt securities. + Underwriters may include Salomon Bros Inc and Merrill +Lynch, it said. Proceeds will be for general needs. + Reuter + + + + 3-APR-1987 13:42:58.60 +acq +usa + + + + + + +F +f1854reute +d f BC-AMERON-<AMN>-ADOPTS-S 04-03 0107 + +AMERON <AMN> ADOPTS SHAREHOLDER RIGHTS PLAN + MONTEREY PARK, Calif., April 3 - Ameron Inc said its board +adopted a rights plan designed to protect shareholders from +potentially unfair takeover tactics. + The plan calls for distribution of one right for each of +its outstanding common shares and each right entitles the +holder to buy one/one-hundredth of a share of newly authorized +Series A Junior Participating cumulative Preferred stock at an +exercise price of 55 dlrs, Ameron said. + It said the rights are exercisable if a group acquires 20 +pct or more of its common stock or announces a tender offer for +30 pct or more of its shares. + Reuter + + + + 3-APR-1987 13:43:34.67 + +uknigeria + + + + + + +RM +f1856reute +u f BC-BRITAIN'S-ECGD-DISCUS 04-03 0102 + +BRITAIN'S ECGD DISCUSSING NEW COVER FOR NIGERIA + LONDON, April 3 - Britain's Export Credits Guarantee +Department (ECGD) is holding talks with Nigeria aimed at +resuming insurance cover for British exporters to Nigeria, the +head of ECGD's international debt division, Gerry Breach, said. + The ECGD suspended cover on Nigeria in 1984 after the +country fell into arrears on payments of insured and uninsured +debts. + Following last week's bilateral accord between Britain and +Nigeria to reschedule the country's insured trade debts, +bankers had hoped that talks would commence on a resumption of +cover. + Breach made his comments in an address to a private meeting +of businessmen, a copy of which was made available to the +press. + Breach noted that for the ECGD to consider "a gradual +introduction of a package of new support" certain criteria would +have to be met. + This would involve the Nigerian economic structural +adjustment program being put into effect and being endorsed by +the International Monetary Fund, the program remaining on +course and continuing to be endorsed by the IMF and a +satisfactory level of acceptance by the Nigerian government of +the ECGD insured short-term trade arrears. + Breach said that these criteria are now beginning to be +satisfied, adding that while the ECGD could not yet formally +announce new cover, it was holding discussions with Nigeria on +priorities for new credits. + He said an announcement would be made "as soon as possible" +on an agreement and the ECGD would create a package for Nigeria +that would include the department's normal range of export +trade support facilities. + British exports to Nigeria exceeded 550 mln stg in 1986. + Breach noted that since cover was removed, the ECGD has +maintained a limited amount of short-term trade cover for +Nigeria, which was backed by letters of credit from the +Nigerian Central Bank. + While the ECGD would initially continue to use this +structure under a new package, it would also hope to expand the +volume of coverage in the short-term area and relax the terms +it is prepared to underwrite towards the commonly accepted +maximum of 180 days. + REUTER + + + + 3-APR-1987 13:44:08.77 +acq +usa + + + + + + +F +f1857reute +d f BC-FCS-LABORATORIES-<FCS 04-03 0062 + +FCS LABORATORIES <FCSI> ENDS MERGER TALKS + TEMPE, Ariz., April 3 - FCS Laboratories said its merger +talks with another unidentified company in the health care +field ended without agreement. + The talks began last August, the company said. + The company also said it will no longer actively seek out +potential merger partners, but will respond to serious +inquiries. + Reuter + + + + 3-APR-1987 13:45:46.93 + +usa + + + + + + +F +f1860reute +u f BC-******IBM-SECRETARY-J 04-03 0091 + +IBM <IBM> NEWLY NAMED SECRETARY DIES IN FIRE + ARMONK, N.Y., APril 3 - International Business Machines +Corp said recently elected secretary, John Manningham, and his +wife, Patricia, died early this morning in a fire at their +Reidgefield, Conn home. + Manningham, 53, began his IBM career in 1959 as a marketing +representative. His election would have been effective July 1. + Tom Irwin is the current secretary. + IBM Chairman John Akers said "this is a great loss to the +IBM Company and to the Manningham's family, friends and +community. + Reuter + + + + 3-APR-1987 13:46:44.30 +trade +ukjapan + + + + + + +C +f1863reute +d f BC-UK-MINISTER-LOOKS-TO 04-03 0106 + +UK MINISTER LOOKS TO EASE TENSION WITH JAPAN + LONDON, April 3 - The U.K. government hopes for a +breakthrough on the deadlock with Japan over trade policies +during next week's visit to Tokyo by Corporate Affairs Minister +Michael Howard, political sources said. + Howard, who leaves for Japan tomorrow, told Reuters he will +try to promote understanding on trade issues during his visit. + Meanwhile, Britain will re-examine a letter from Japanese +Prime Minister Yasuhiro Nakasone promising personal help in +solving the row over a U.K. firm's bid to win a significant +role in Japan's telecommunications market, government sources +said. + Tensions have risen following Britain's decision to arm +itself early with new statutory powers which it says could be +used against certain Japanese financial institutions. + Britain reacted optimistically at first to the letter from +Nakasone to Prime Minister Margaret Thatcher, seeing it as a +signal that he would work towards ensuring a satisfactory +outcome to the bid launched by Cable and Wireless Plc, +government officials said. + But this view has since been clouded by reports from Tokyo +that Nakasone's assurances really constituted little more than +politeness in the face of British anger, they added. + Reuter + + + + 3-APR-1987 13:54:45.70 +trade +usajapan +conable +imfworldbank + + + + +F RM A +f1876reute +u f BC-CONABLE-WARNS-PROTECT 04-03 0082 + +CONABLE WARNS PROTECTIONISM MIGHT SPREAD + By Alver Carlson, Reuters + WASHINGTON, April 3 - World Bank President Barber Conable +expressed concern that trade protectionism, at the heart of a +new showdown between the United States and Japan, might spread +throughout the industrial world. + But in an interview with Reuters, Conable said the action +by the United States to slap tariffs on certain electronic +goods from Japan did not mean the countries were heading for a +full-scale trade war. + Conable said the World Bank has been pressing developing +countries to open their markets, arguing that a free trading +environment increased the possibility of global economic +growth. + "We have, in fact, been making adjustment loans to many +countries in the developing world which have encouraged the +opening of their markets and we want to be sure that the +developed world doesn't close at the same time," he said. + He said the U.S. action against Japan was "a significant +retaliatory step but it did not constitute a basic change in +trade policy." + The interview came just before next week's semi-annual +meetings of the Bank and the International Monetary Fund. + Referring to Brazil's recent interest payments moratorium, +Conable also said the global debt situation was very serious +and must be closely watched. + He said the Bank, which in the past has concentrated on +making loans that assist the basic underpinnings in the +developing world such as dams, roads and sewers, will +increasingly make assistance available for economic reform. + The Bank has increased these loans, in part because of the +debt crisis that has found countries desperately in need of new +funds for balance of payments adjustment and economic reforms +aimed at opening their markets, encouraging foreign investment +and reducing government's role in the economy. + "We're comfortable with adjustment lending, we expect, +however, that it will never reach a majority of our portfolio," +Conable said. + He made clear, however, that adjustment lending would +continue to increase as a proportion of overall Bank lending +for some time. + He noted, "the problem of debt was a severe one and many +countries are asking for adjustment assistance because of the +problem of debt." + Conable, is a a former Republican Congressman from New York +chosen by President Reagan for the Bank position last year. He +is an associate of Treasury Secertary James Baker who launched +the U.S. strategy for shoring up indebted nations in October, +1985 which included a call for increased adjustment lending by +the World Bank. + Conable also said that he expected the result of a major +study of the Bank's organization to be completed in the next +several weeks. + He said the decision to seek a reorganization was based, in +part, on the fact that the Bank had come under fire from the +poorest countries for not doing enough to help and from the +richest countries because of inefficiency. + the reorganization is considered a major initiative by +Conable, and is being closely-watched by the agency's 151 +member-countries as an indication of his management style and +priorities. + "I want to be sure this institution is viewed by those who +must support it as soundly constituted so that it will be +permitted to grow," Conable said. + However, he said "I don't believe there is anything +basically wrong with this institution and I don't believe it +has to have any redefinition of its purpose." + He said, however, that it was apparent that the debt +initiative proposed by Baker has given the Bank a central role +in dealing with the debt crisis. + Conable added that cooperation between the Bank and its +sister agency, the International Monetary Fund, was good and +that he talked often with IMF Managing Director Michel +Camdessus on a variety of issues. + On a personal level, Conable said that he not feel a need +to put his personal stamp on the Bank noting that "I don't have +a particular mission here except to be useful to the +institution and to the process of development." + He added, "so I don't feel a great calling to personalize +the institution." + On the development needs of sub-Sahara Africa, Conable said +that the Bank was constantly reviewing new ways for assisting +the region, noting that half of the recently agreed financing +of 12.4 billion dlrs for Bank's International Development +Association was earmarked for Africa. + Leading industrial nations are expected to consider new +forms of debt relief for the very poorest nations, like those +in the Sub-Sahara, during next week's meetings. + Reuter + + + + 3-APR-1987 13:55:17.71 + +usa + + + + + + +F +f1877reute +r f BC-AMERICAN-SAVINGS-<AMS 04-03 0080 + +AMERICAN SAVINGS <AMSB> SEEKS STATE CHARTER + TACOMA, Wash., April 3 - American Savings Bank F.S.B. said +it applied for a state charter and it intends to change its +depositor insurance coverage to the Federal Deposit Insurance +Corp and to withdraw from coverage by the Federal Savings and +Loan Insurance Corp. + The savings bank also said state chartered institutions +have broader banking powers and the conversion will be in the +best interest of both shareholders and depositors. + Reuter + + + + 3-APR-1987 13:55:26.39 + +usa + + + + + + +F +f1878reute +r f BC-LTV-<QLTV>-UNIT-WINS 04-03 0063 + +LTV <QLTV> UNIT WINS TWO ARMY CONTRACTS + SOUTH BEND, Ind., April 3 - LTV Corp said its AM General +division received two contracts valued at 11.7 mln dlrs from +the U.S. Army to make special equipment kits for Hummer troop +and cargo vehicles. + Deliveries are set for May 1987 through November 1988, the +company said. AM General is part of LTV Missiles and +Electronics Group. + Reuter + + + + 3-APR-1987 13:57:12.03 + +usajapan + + + + + + +F +f1882reute +r f AM-PLANE-BOEING 04-03 0112 + +BOEING SEEKS CAUSE OF JAL ENGINE PROBLEM + SEATTLE, April 3 - Boeing Co. <BA> is trying to find out +what caused an engine brace to snap on one of Japan Air Line's +747-SR jumbo jets, a spokesman for the airplane manufacturer +said. + "We know about the problem and we have provided a service +advisory to operators of 747s," said the spokesman. "We are not +advising any massive inspections at this time." + The advisory alerts operators of the jumbo jets that a +problem has occurred and under what circumstances, but it does +not recommend any action. + "A 'service bulletin' would be sent out if there is +anything they should be concerned about," the spokesman said. + A JAL spokesman in Toyko said inspectors making a routine +check found one of three diagonal braces attaching an engine to +the wing of a 747-SR had snapped due to metal fatigue. + The airlines said it had ordered an inspection of all 11 of +its 747-SR's. The plane is a full-sized jumbo jet that has been +modified slightly to handle short-haul routes in Japan, mainly +between Tokyo and Osaka. + The jetliners have beefed-up landing gear to accommodate a +higher-than-normal number of landings and takeoffs. + Boeing's spokesman said only JAL and All Nippon Airlines +use the 747-SR. JAL took delivery of its first 747-SR in 1973 +and purchased two more last year. He said the braces had been +shipped to a Boeing plant near Seattle where they were being +inspected. + Reuter + + + + 3-APR-1987 13:58:59.52 + +uknigeria + + + + + + +C G T M +f1886reute +d f BC-BRITAIN'S-ECGD-DISCUS 04-03 0101 + +BRITAIN'S ECGD DISCUSSING NEW COVER FOR NIGERIA + LONDON, April 3 - Britain's Export Credits Guarantee +Department (ECGD) is holding talks with Nigeria aimed at +resuming insurance cover for British exporters to Nigeria, the +head of ECGD's international debt division, Gerry Breach, said. + The ECGD suspended cover on Nigeria in 1984 after the +country fell into arrears on payments of insured and uninsured +debts. + Following last week's bilateral accord between Britain and +Nigeria to reschedule the country's insured trade debts, +bankers had hoped that talks would commence on a resumption of +cover. + Breach told a businessmen's meeting that for the ECGD to +consider "a gradual introduction of a package of new support" +certain criteria would have to be met. + This would involve the Nigerian economic structural +adjustment program being put into effect and being endorsed by +the International Monetary Fund, the program remaining on +course and continuing to be endorsed by the IMF and a +satisfactory level of acceptance by the Nigerian government of +the ECGD insured short-term trade arrears. + British exports to Nigeria exceeded 550 mln stg in 1986. + Reuter + + + + 3-APR-1987 14:02:56.83 + +uk + + + + + + +RM F +f1899reute +u f BC-BP-CREDIT-FACILITY-SU 04-03 0115 + +BP CREDIT FACILITY SUBSTANTIALLY OVERSUBSCRIBED + LONDON, April 3 - A five billion dlr credit facility being +arranged for two units of British Petroleum Co Plc <BP.L> +attracted over 15 billion dlrs in syndication but will not be +increased, Morgan Guaranty Ltd said on behalf of Morgan +Guaranty Trust Co of New York, the arranger. + It said that 64 of BP's relationship banks will be joining +the facility, although their participations will be cut back +dramatically. Banks had been invited as lead managers at 200 +mln dlrs, managers at 125 mln and co-managers at 75 mln. + BP will make the final decision on the allotments broadly +based on relationships rather than on the amounts offered. + The facility is being arranged for BP International and BP +North America in conjunction with the company's planned tender +offer for the 45 pct of Standard Oil Co it does not already +own. + Because of the purpose of the facility, Morgan only had +five business days to arrange the facility. As a result, it +carried terms that bankers considered relatively favourable +when compared with those on most other recent credits. The +facility fee, for example, was 1/8 pct compared with the 1/16 +pct BP paid on a recent 1.5 billion dlr refinancing. + REUTER + + + + 3-APR-1987 14:04:13.24 +strategic-metal +spain + + + + + + +C M +f1903reute +u f BC-MINAS-DE-ALMADEN-RAIS 04-03 0113 + +MINAS DE ALMADEN RAISES MERCURY PRICE + MADRID, April 3 - Spain's Minas de Almaden y Arrayanes S.A. +has agreed with Algerian producer ENOF to establish a minimum +price of 300 dlrs per flask for spot mercury sales, Almaden +spokesman Jesus Gallego said. + In response to enquiries from Reuters, he said his company +had raised the minimum price for its spot sales from 240 dlrs +per flask following talks with ENOF. + In a separate press release, the company said that ENOF and +Almaden held talks in Istanbul a week ago with Turkish mercury +producers on ways to improve prices, but Gallego said he was +not in a position to say what action the Turkish companies +would be taking. + Reuter + + + + 3-APR-1987 14:04:52.21 +money-fx +usa + + + + + + +F A RM +f1907reute +u f BC-U.S.-JOBS-DATA-SAID-T 04-03 0099 + +U.S. JOBS DATA SAID TO RULE OUT FED TIGHTENING + By Kathleen Hays, Reuters + NEW YORK, April 3 - A steep drop in goods-producing jobs +detracted from U.S. March non-farm payroll employment and makes +it unlikely that the Federal Reserve will tighten monetary +policy to defend the dollar, economists said. + U.S. March non-farm payroll employment rose 164,000, less +than the gain of 220,000 to 290,000 the financial markets +expected. Manufacturing employment fell 25,000, compared with +February's 50,000 gain, while March construction employment +dropped 45,000 after being unchanged in February. + "The momentum of industrial activity is tapering off as we +end the first quarter," said Stephen Roach of Morgan Stanley +and Co Inc. "This sets the stage for more sluggish growth in +the second and third quarters." + "The Fed will view this as a caution flag on the economy," +he said. "They will not ease as long the dollar is weak, but +clearly they can't tighten." + David Wyss of Data Resources Inc said that the downward +revision in February non-farm payroll employment to 236,000 +from 337,000 means that employment gains in the first quarter +were weaker than expected. + While Wyss left his first-quarter forecast of real U.S. +gross national product growth at 3.5 pct, he said the March +jobs data suggested a downward revision in his second-quarter +growth forecast to 2.5 pct from 2.8 pct. + Bill Sullivan of Dean Witter Reynolds Inc said the average +monthly gain in non-farm jobs in the first quarter was only +237,000, compared with 254,000 in the fourth quarter of 1986. + "There's momentum in first quarter labor force activity, +but less than assumed," he said. "Gains in goods-producing jobs +were subdued at best. This rules out any possibilty of the Fed +tightening for exchange-related purposes." + In March, the average workweek fell back to its January +level of 34.8 hours from 35.0 hours in February. Manufacturing +hours also fell back to their January level, totalling 40.9 +hours in March compared with 41.2 hours in February. + The Commerce Department noted that loss of manufacturing +jobs in March was concentrated in automobile, electrical and +electronic manufacturing. + Robert Brusca of Nikko Securities International said that a +13,000 decline in auto manufacturing employment accounted for +nearly half of the total drop in manufacturing jobs. + Economists said that a build-up in auto inventories +resulting from a steep drop in sales has finally caught up with +the labor force and may point to slower growth ahead. + Most expect an increase in inventories of as much as five +pct to offset a steep four to five pct drop in final sales in +the first-quarter GNP accounts. + Roach said he expects first quarter U.S. GNP to rise two +pct, to be followed by a gain of 1.0-1.5 pct at best in the +second and third quarters. He said the March drop in industrial +activity "is a reasonable response in light of the inordinate +contribution inventory accumulation made to GNP." + Economists said the employment data also suggest weak gains +in industrial production and personal income for March. +They expect only marginal gains, if not small declines, for +these indicators, compared with a February increases of 0.5 pct +in industrial production and 0.9 pct in personal income. + Steve Slifer of Lehman Government Securities said the drop +in March construction employment may also signal a drop in +March housing starts, which rose 2.6 pct in February to 1.851 +million units at an annual rate from 1.804 million units in +January. + The rate of unemployment fell to 6.6 pct, its lowest level +since March 1980, from 6.7 pct in February. But Wyss pointed +out that this resulted from a drop in the labor force, which +fell to 119.2 mln in March from 119.35 mln in February. + "This just means that there were fewer people looking for +work, so the drop in unemployment doesn't mean much," he said. + He said the latest employment report will not concern the +Fed because it does points to GNP growth in the first half of +2.5-3.0 pct, but "it does suggest they can't afford to tighten +to quickly either." + The statistical factors used to smooth out seasonal +fluctuations in the jobs data may have understated March labor +force gains, just as seasonal factors probably overstated them +in January and February, Slifer said, but are consistent with +his forecast of 1.8 pct first quarter GNP growth. + Economic growth remains sluggish, but Silfer does not think +that the Federal Open Market Committee changed policy at their +meeting this week. "At some point they will be more inclined to +ease," he said. For the time being, however, the March +employment report "increases the likelihood they won't tighten, +regardless of the dollar." + + Reuter + + + + 3-APR-1987 14:06:26.28 +acq +usa + + + + + + +F +f1912reute +u f BC-BRISTOL-MYERS-<BMY>-R 04-03 0096 + +BRISTOL-MYERS <BMY> REVIEWING SCIMED MERGER + MINNEAPOLIS, April 3 - SciMed Life Systems Inc <SMLS> said +Bristol-Myers Co is analyzing the pending lawsuit brought +against SciMed by <Advanced Cardiovascular Systems Inc> to +determine whether to consummate its previously announced plans +to merge with SciMed. + The company said its was served the suit in Minneapolis on +March 31, the day after it announced its definitive merger +agreement with Bristol-Myers. + SciMed said the suit, which alleges that SciMed infringed +on Advanced Cardiovascular patents, is without merit. + Reuter + + + + 3-APR-1987 14:07:59.28 + +ukjapan + + + + + + +F +f1919reute +d f BC-UK-SEEKS-PACT-WITH-JA 04-03 0095 + +UK SEEKS PACT WITH JAPAN FOR INFORMATION EXCHANGE + LONDON, April 3 - Corporate Affairs Minister Michael Howard +said he will use a coming trip to Tokyo to seek a memorandum of +understanding between Britain and Japan on the exchange of +information to fight fraud in world financial markets. + He told journalists that he would be seeking an agreement +with Japan similar to one struck last autumn between the U.K. +Department of Trade and Industry, on the one hand, and the +Securities and Exchange Commission (SEC) and the Commodity +Futures Trading Commission on the other. + Market sources have persistently speculated that it was +information passed on to the U.K. By the SEC through their pact +that triggered the DTI's investigations into (Guinness Plc's) +<GUIN.L> takeover of <Distillers Co Plc> last year. + The probe, launched in December, triggered the resignation +of some of Guinness' senior management, including Chairman +Ernest Saunders. + The Trade department, however, has never confirmed this and +has yet to state what its investigation actually concerns. + REUTER + + + + 3-APR-1987 14:08:38.07 +crude +iraqiran + + + + + + +C +f1921reute +d f AM-GULF-IRAQ 04-03 0075 + +IRAQ SAYS ITS FORCES SINK THREE IRANIAN VESSELS + BAGHDAD, April 3 - Iraq said its forces sank three Iranian +boats which tried to approach its disused deep water oil +terminal in the northern Gulf today. + A military spokesman, quoted by the official Iraqi news +agency, said other Iranian boats fled. He did not identify the +vessels. + Iraq's major oil outlets in the northern Gulf were closed +shortly after the war with Iran started in late 1980. + Reuter + + + + 3-APR-1987 14:09:38.75 + +france + + + + + + +RM +f1924reute +r f BC-FRANCE-HLM-LAUNCHES-7 04-03 0083 + +FRANCE HLM LAUNCHES 750 MLN FRANC BOND + PARIS, April 3 - Housing group France HLM is launching a +750 mln French franc 8.40 pct 15-year bond with an issue price +of 95.36 pct and denominated in 5,000 franc units, lead manager +Banque Paribas said. + The issue is being co-led by Credit Lyonnais. + Payment date is April 20 and redemption will be in 12 equal +annual instalments starting after the first three years of the +issue's life. It will be listed in the Official Bulletin (BALO) +on April 6. + REUTER + + + + 3-APR-1987 14:12:09.91 + +usa + + + + + + +F +f1928reute +u f BC-******TEXAS-AIR'S-CON 04-03 0078 + +TEXAS AIR'S <TEX> CONTINENTAL MARCH TRAFFIC UP + HOUSTON, April 3 - Texas Air Corp'S Continental Airlines +said its March 1987 load factor rose to 65.6 pct from 64.3 pct +last year. Available seat miles rose to 5.1 mln from 2.5 mln +and revenues passenger miles rose to 3.3 mln from 1.6 mln + For the year to date, load factor fell to 61.8 pct from +61.9 pct, available seat miles rose to 13.2 mln from 7.3 mln +and revenue passenger miles rose to 8.2 mln from 4.5 mln + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-014.sgm b/src/test/data/reuters-21578/reut2-014.sgm new file mode 100644 index 00000000000..320474cc15f --- /dev/null +++ b/src/test/data/reuters-21578/reut2-014.sgm @@ -0,0 +1,2029 @@ + + + 7-APR-1987 11:02:35.07 + + + + + + + +E +f1137reute +b f BC-JOHANNESBURG-GOLD-SHA 04-07 0120 + +JOHANNESBURG GOLD SHARES CLOSE MIXED TO FIRMER + JOHANNESBURG, April 7 - Gold share prices closed mixed to +slightly firmer in quiet and cautious trading, showing little +reaction to a retreat in the bullion price back to below 420 +dlrs and a firmer financial rand, dealers said. + Heavyweight Vaal Reefs ended eight rand higher at 398 rand +but Grootvlei eased 40 cents at 16.60 rand, while mining +financials had Gold Fields up a rand at 63 rand despite weaker +quarterly results. Other minings were firm but platinums eased. + Industrials also closed mixed to firmer, the index once +again hitting a new high of 1757 from Friday's 1753 finish. The +overall index also hit a new high of 2188 versus 2179 on +Friday. + REUTER + + + + 7-APR-1987 11:02:40.82 + + + + + + + +TQ +f1138reute +u f BC-NY-SUGAR-11-1100 04-07 0024 + +NY SUGAR 11 1100 + + MAY7 662 OFF 17 + JUL7 678 OFF 15 + SEP7 696 OFF 12 + OCT7 699 OFF 14 + JAN8 UNTRD + MAR8 739 OFF 16 + MAY8 UNTRD + JUL8 780 OFF 3 + + + + + + 7-APR-1987 11:03:03.68 + + + + + + + +CQ TQ +f1140reute +u f BC-NY-COFFEE-11-00 04-07 0026 + +NY COFFEE 11:00 + + MAY7 10200 OFF 4 + JUL7 10390 OFF 10 + SEP7 10580 OFF 25 + DEC7 10900 UNCH + MAR8 11100 UP 50 + MAY8 11300 UP 50 + JUL8 UNTRD + SEP8 UNTRD + + + + + + 7-APR-1987 11:03:30.55 + + + + + + + +CQ LQ +f1143reute +u f BC-peoria-actual-rcpts 04-07 0023 + +PEORIA ACTUAL LIVESTOCK RECEIPTS - USDA + CATTLE HOGS + For April 8 + WEEK AGO 200 2,000 + YEAR AGO 100 2,400 + Reuter + + + + + + 7-APR-1987 11:04:03.63 + + + + + + + +C L +f1145reute +u f BC-feeder-cattle-report 04-07 0106 + +FEEDER CATTLE FUTURES SET NEW HIGHS, TURN MIXED + CHICAGO, April 7 - Feeder Cattle futures advanced 0.20 to +0.30 cent at the start and posted new season's highs in April +through August and October before slipping to trade 0.10 cent +lower to 0.20 higher in latest trade. + Futures ran up to new highs at the start on general demand +prompted by continued strong cattle fundamentals. Posting of +another 10 cent gain in the latest reported average feeder +steer price added to support, traders said. + However, prices retreated on profit-taking following the +lead of other meat pits. Stotler notably sold April on the +decline, they said. + Reuter + + + + 7-APR-1987 11:04:12.58 + + + + + + + +FQ EQ +f1146reute +u f BC-AMEX-CONSOLIDATED-110 04-07 0050 + +AMEX-CONSOLIDATED 1100 ACTIVES + + 364,200 WESTERN DIG 25 7/8 UP 1 1/4 + 230,200 WANG LAB B 15 1/2 UP 1/8 + 223,800 WICKES COS 4 1/8 OFF 1/8 + 190,600 ALZA CP 37 1/2 UP 1 7/8 + 187,900 TEXAS AIR 41 1/2 OFF 1 + + ADVANCES 247 DECLINES 152 + + + + + + 7-APR-1987 11:04:23.94 + + + + + + + +M +f1147reute +b f BC-LME-LEAD-AFT-2ND-RING 04-07 0025 + +LME LEAD AFT 2ND RING 1602 - APR 7 + LAST BUYER SELLER + Cash 308.0 -- -- + 3 Months 301.5 301.0 302.0 + + + + + + 7-APR-1987 11:04:29.67 + + + + + + + +GQ +f1148reute +u f BC-cbt-corn-spreads 04-07 0058 + +CBT CORN SPREADS + APRIL 7 - 1000 hrs cdt + MONTHS LAST DIFFERENCE + Jul/May 3-1/4 over 3-1/2 over + Dec/Jul 12-3/4 over 13 over + Jul/Sep 4-3/4 under 5 under + Sep/May no quote 8-1/4 over + Sep/Dec no quote 8-1/4 under + Dec/Mar8 no quote no quote + May/Dec 16 under 16-1/2 under + Reuter + + + + 7-APR-1987 11:04:47.19 + + + + + + + +FQ EQ +f1150reute +u f BC-NYSE-CONSOLIDATED-110 04-07 0090 + +NYSE-CONSOLIDATED 1100 ACTIVES + +4,969,500 GCA CP 7/32 OFF 1/32 +2,163,900 BELLSOUTH 39 3/8 OFF 1/8 +2,058,500 TEXACO 34 1/8 UP 1/2 +1,152,200 OKLAHO G&E 32 1/2 OFF 3/4 + 939,700 UNITED AIR 65 OFF 3/4 + 929,900 USX CORP 29 5/8 UP 3/8 + 918,100 GEN MOTORS 83 5/8 UP 2 1/8 + 917,500 FORD MOTOR 91 1/4 UP 1 1/8 + 755,700 DELMARVA 30 1/4 OFF 1/8 + 732,200 CAESARS 31 1/4 UP 5/8 + + ADVANCES 636 DECLINES 525 + + + + + + 7-APR-1987 11:05:05.48 + + + + + + + +C L +f1151reute +u f BC-TEXAS-PANHANDLE/W-OKL 04-07 0098 + +TEXAS PANHANDLE/W OKLA FEEDLOT ROUNDUP - USDA + Amarillo, April 7 - Cattle in the panhandle area monday +were 0.50 to 1.50 dlr higher. Trading was very active. + Feedlots reported very good interest and inquiry from +buying sources. Confirmed sales of 22,700 steers and heifers +8,100 head. There were 37,900 head sold for the week to date. + Steers - good and mostly choice 2-3, 70-85 pct choice, +1025-1150 lb 69.00-70.00, late mostly 69.50-70.00. + Heifers - near 350 head mostly choice 2-3 1000 lb 68.25. +Good and mostly choice 2-3 950-100 lb 66.50-68.00, late mostly +67.00-68.00. + Reuter + + + + 7-APR-1987 11:05:17.86 + + + + + + + +CQ +f1152reute +u f BC-MIDWEST-GRAIN-FUTURES 04-07 0061 + +MIDWEST GRAIN FUTURES 11:00 EDT +KANSAS CITY WHEAT + MAY7 274 1/2 UP 1/2 + JUL7 263 1/2 UP 1/2 + SEP7 265 1/2 UP 1/4 + DEC7 270 1/2 OFF 1/4 + MAR8 -- --MINNEAPOLIS WHEAT + MAY7 284 3/4 UP 1 1/4 + JUL7 280 1/4 OFF 1/2 + SEP7 277 UP 1 + DEC7 -- -- + MAR8 -- -- + + + + 7-APR-1987 11:05:28.64 +trade +usa +volcker + + + + +V RM +f1153reute +b f BC-VOLCKER-PUSHES-SPENDI 04-07 0080 + +VOLCKER PUSHES SPENDING CUTS OVER TRADE BILL + WASHINGTON, April 7 - Federal Reserve Board Chairman Paul +Volcker said reducing the federal budget deficit was a more +important goal for Congress than drafting trade legislation. + "Reduce the budget deficit," Volcker responded when asked by +a member of the Senate Banking Committee about trade +legislation priorities. + "If you don't deal with the budget deficit, everything else +you do is going to be counterproductive," he said. + Reuter + + + + 7-APR-1987 11:05:35.43 + + + + + + + +M +f1154reute +u f BC-cbt-metals-registns 04-07 0032 + +CBT METALS REGISTRATIONS - APRIL 7 + AS OF 0945 CDT + SILVER 1,000 OZ 13,943 UNC + 5,000 OZ 203 UNC + GOLD 100 OZ 42 UNC + 3-KG 42 UNC + 1-KG 658 UNC + Reuter + + + + + + 7-APR-1987 11:05:44.09 + + + + + + + +GQ +f1155reute +u f BC-MIDWEST-GRAIN-FUTURES 04-07 0061 + +MIDWEST GRAIN FUTURES 11:01 EDT +KANSAS CITY WHEAT + MAY7 274 1/2 UP 1/2 + JUL7 263 1/2 UP 1/2 + SEP7 265 1/2 UP 1/4 + DEC7 270 1/2 OFF 1/4 + MAR8 -- --MINNEAPOLIS WHEAT + MAY7 284 3/4 UP 1 1/4 + JUL7 280 1/4 OFF 1/2 + SEP7 277 UP 1 + DEC7 -- -- + MAR8 -- -- + + + + 7-APR-1987 11:05:53.61 + + + + + + + +GQ +f1156reute +u f BC-cbt-soybean-spreads 04-07 0074 + +CBT SOYBEAN SPREADS + APRIL 7 - 1000 hrs cdt + MONTHS LAST DIFFERENCE + May/Jul 1 under 1 under + Jul/Aug even even + Sep/Nov 1-1/2 under 2-1/2 under + May/Nov 2-1/2 over 2-1/4 over + Jul/Nov 3-1/2 over 3-1/2 over + Nov/Jan 6-3/4 under 6-3/4 under + Aug/Sep no quote 5 over + Mar/May8 no quote no quote + Jan/Mar8 no quote no quote + Reuter + + + + 7-APR-1987 11:06:07.52 + + + + + + + +GQ +f1157reute +u f BC-CBT-11-01-EDT 04-07 0105 + +CBT 11:01 EDT +WHEAT +MAY7 288 UP 1 3/4 +JUL7 273 UP 1/4 +SEP7 273 1/2 UP 1/2 +DEC7 279 UP 1 +MAR8 278 1/4 UP 1 +CORN +MAY7 159 3/4 UP 1 1/2 +JUL7 163 UP 1 1/4 +SEP7 167 1/2 UP 1 1/4 +DEC7 176 UP 1 1/4 +MAR8 183 UP 1 1/4 +OATS +MAY7 150 UNCH +JUL7 138 OFF 1/2 +SEP7 128 1/4 UNCH +DEC7 134 1/2 UP 1/2 +MAR8 UNTRD +BEANS +MAY7 501 1/4 UP 1 1/2 +JUL7 502 1/4 UP 2 +AUG7 502 1/2 UP 3 +SEP7 497 UP 3 +NOV7 498 3/4 UP 2 3/4 +JAN8 505 1/4 UP 2 3/4 +MEAL +MAY7 1456 UP 3 +JUL7 1457 UP 6 +AUG7 1455 UP 5 +SEP7 UNTRD +OCT7 1455 UP 4 +OIL +MAY7 1554 UP 11 +JUL7 1589 UP 11 +AUG7 1605 UP 10 +SEP7 1620 UP 9 +OCT7 1635 UP 10 + + + + + + 7-APR-1987 11:06:13.18 + + + + + + + +C G +f1158reute +u f BC-cbt-registrations 04-07 0063 + +CBT REGISTRATIONS - APRIL 7 + AS OF 0945 CDT + SOYOIL 7,099 UNC + SILVER 1,000 OZ 13,943 UNC + 5,000 OZ 203 UNC + GOLD 100 OZ 42 UNC 3-KG 42 UNC 1-KG 658 UNC + CERTIFICATES OUTSTANDING + SOYBEAN MEAL 0 UNC + CENTRAL 0 + MID-SOUTH 0 + MISSOURI 0 + EASTERN IOWA 0 + NORTHEAST 0 + NORTHERN 0 + Reuter + + + + + + 7-APR-1987 11:06:16.90 + + + + + + + +L +f1159reute +u f BC-SIOUX-FALLS-CATTLE-UP 04-07 0044 + +SIOUX FALLS CATTLE UP 0.50 DLR - USDA + sioux falls, april 7 - slaughter cattle rose 0.50 dlr in +active trade, the usda said. + stees - choice 2-4 1100-1400 lbs 66.00-67.00. + heifers - load choice 3 near 1225 lbs 66.50. choice 2-4 +950-1125 lbs 64.00-66.00. + Reuter + + + + 7-APR-1987 11:06:31.29 + + + + + + + +GQ +f1161reute +u f BC-CME-11-01--EDT 04-07 0053 + +CME 11:01 EDT + +L-CATTLE +APR7 69.57 UP 0.17 +JUN7 64.92 OFF 0.10 +AUG7 60.75 OFF 0.12 +F-CATTLE +APR7 69.00 OFF 0.10 +MAY7 68.05 OFF 0.17 +AUG7 66.50 UP 0.10 +HOGS +APR7 50.10 UP 0.28 +JUN7 48.75 UP 0.28 +JUL7 47.25 UP 0.38 +BELLIES +MAY7 66.15 OFF 0.25 +JUL7 64.70 OFF 0.15 +AUG7 61.65 UP 0.05 +FEB8 56.00 UP 0.40 + + + + + + 7-APR-1987 11:06:39.38 + + + + + + + +GQ +f1162reute +u f BC-cbt-soyoil-report 04-07 0060 + +CBT SOYBEAN OIL SPREADS + APRIL 7 - 1000 hrs cdt + MONTHS LAST DIFFERENCE + May/Jul 0.34 under 0.35 under + Jul/Aug 0.16 under 0.17 under + Jul/Dec 0.78 under 0.77 under + Aug/Sep 0.16 under 0.16 under + May/Aug no quote 0.52 under + May/Dec no quote 1.12 under + Dec/Jan no quote no quote + Reuter + + + + 7-APR-1987 11:06:45.97 + + + + + + + +MQ +f1163reute +u f BC-NY-COMEX-ALUMINUM-11- 04-07 0040 + +NY COMEX ALUMINUM 11:01 + LAST CHANGE +APR7 UNTRD +MAY7 6150 UNCH +JUN7 UNTRD +JUL7 UNTRD +SEP7 UNTRD +DEC7 UNTRD +JAN8 UNTRD +FEB8 UNTRD +MAR8 UNTRD +MAY8 UNTRD +JUL8 UNTRD +SEP8 UNTRD +DEC8 UNTRD +JAN9 UNTRD + + + + + + 7-APR-1987 11:06:50.37 + + + + + + + +LQ +f1164reute +u f BC-FLASH-SIOUX-FALLS-HOG 04-07 0027 + +FLASH SIOUX FALLS HOGS UP 1.75 DLR - USDA + sioux falls, april 7 - barrows and gilts rose 1.75 dlr in +active trade, the usda said. us 1-3 220-250 lbs 51.75-52.00. + Reuter + + + + 7-APR-1987 11:06:58.55 + + + + + + + +MQ CQ +f1165reute +u f BC-NY-COMEX-GOLD-11-01 04-07 0036 + +NY COMEX GOLD 11:01 + APR7 4199 UP 14 + MAY7 UNTRD + JUN7 4237 UP 11 + AUG7 4288 UP 15 + OCT7 4327 UP 10 + DEC7 4370 UP 9 + FEB8 4415 UP 8 + APR8 UNTRD + JUN8 UNTRD + AUG8 UNTRD + OCT8 UNTRD + DEC8 UNTRD + FEB9 UNTRD + + + + + + 7-APR-1987 11:07:09.81 + + + + + + + +FQ +f1167reute +u f BC-NASDAQ-COMP-11-01 04-07 0007 + +NASDAQ COMP 11:01 +COMP 437.49 OFF 0.29 + + + + + + 7-APR-1987 11:07:18.11 + + + + + + + +GQ +f1168reute +u f BC-cbt-soymeal-spreads 04-07 0052 + +CBT SOYBEAN MEAL SPREADS + APRIL 7 - 1000 hrs cdt + MONTHS LAST DIFFERENCE + May/Jul 0.10 over 0.10 over + Jul/Aug no quote even + Jul/Dec no quote 1.40 under + Oct/Dec no quote 1.40 under + Dec/Jan no quote 0.60 under + Oct/Jan no quote 2.00 under + Reuter + + + + 7-APR-1987 11:07:22.81 + + + + + + + +C G L M T RM +f1169reute +b f BC-LONDON-DOLLAR-FLUCTUA 04-07 0027 + +LONDON DOLLAR FLUCTUATIONS 1600 - APRIL 7 + STG 1.6177/82 + DMK 1.8235/45 + SFR 1.5120/30 + DFL 2.0578/88 + FFR 6.0650/0700 + YEN 145.20/30 + LIT 1299/1301 + BFC 37.76/81 + + + + + + 7-APR-1987 11:07:28.63 + + + + + + + +G +f1170reute +r f BC-PRSFRENCH-GRAINS---AP 04-07 0069 + +PRSFRENCH GRAINS - APR 07 + Prices in ff per 100 kilos. Cumulative monthly supplements of +17.40 ff per ton to be added from august 1986 onwards. + Soft wheat- dlvd ROUEN APR 130.50 PAID, MAY 130.25 PAID. +LA PALLICE APR/MAY 129.50 BYR. DUNKIRK APR 129.50 PAID. + SOFT WHEAT - EX REGION EURE ET LOIR APR/OCT 126 PAID. +CHALONS/MODANE APR/JUNE 122 BYR. + SOFT WHEAT - FOB REGION METZ APR/JUNE 127 BYR/127.50 SLR. + Feed barley - dlvd ROUEN APR/MAY 118.50 BYR/119 SLR. + FEED BARLEY - EX REGION EURE ET LOIR APR/MAY 114.50 SLR. +CHALONS/MODANE APR/MAY 112.50 BYR. + FEED BARLEY - FOB REGION METZ APR/MAY 116 BYR. + CORN - DLVD BAYONNE APR/JUNE 132.50 BYR. BORDEAUX APR/JUNE +134 BYR. TONNAY/CHARENTES APR/JUNE 131.75 BYR. + CORN - EX REGION EURE ET LOIR 126 TO 127 NOMINAL. MARNE +APR/JUNE 127 NOMINAL. + CORN - FOB REGION METZ APR/JUNE 132.50 BYR. CREIL +APR/MAY/JUNE 128 PAID, JUL/AUG/SEP 129/129.50 PAID. REUTER + + + + + + 7-APR-1987 11:07:45.56 +acq +usa + + + + + +F +f1172reute +d f BC-AMERICAN-SPORTS-ADVIS 04-07 0071 + +AMERICAN SPORTS ADVISORS <PIKS> TO LIQUIDATE + CARFLE PLACE, N.Y., April 7 - American sports Advisors Inc +said it has agreed to sell its sports handicapping and +publication business to Professor Enterprises for about +1,650,000 dlrs and intends to liquidate after closing. + The transaction is subject to shareholder approval. + Professor is owned by American Sports president Edward C. +Horowitz and Mike Warren, it said. + Reuter + + + + 7-APR-1987 11:08:01.92 + + + + + + + +C T +f1173reute +u f BC-ny-coffee-opg-report 04-07 0106 + +N.Y. COFFEE FUTURES SLIGHTLY HIGHER, THIN EARLY + NEW YORK, April 7 - N.Y. coffee futures were marginally +firmer midmorning, trading in ranges of no more than 0.50 cent. + May was up 0.16 cent at 102.20 cents at 1052 hrs EST, in a +range of 102.00 to 102.50 cents. July was up 0.15 at 104.15 +cents in a 35-point range. + Traders said reports that the U.S. State Department does +not forsee a meeting with Brazil prior to the next +International Coffee Organization session in September did not +affect the market as the news was expected. + Operators are watching the cash market for indications of +roaster interest or producer selling. + Reuter + + + + 7-APR-1987 11:08:12.19 + +uk +thatcher + + + + +V +f1174reute +u f AM-BRITAIN 1STLD 04-07 0124 + +THATCHER FIRM AS PRESSURE MOUNTS FOR ELECTIONS + By Colin McIntyre, Reuters + LONDON, April 7 - As pressure mounted on British Prime +Minister Margaret Thatcher to call a June election, she said +today that the decision on when to go to the county was hers +and hers alone. + She was speaking to parliament after senior members of the +ruling Conservative Party urged her to call elections due in +June 1988 a year early in the wake of two more opinion polls +giving her party a commanding lead. + Asked by a Conservative back-bencher for an assurance that +the decision was hers alone, and did not depend on "media hype, +pressure and speculation," she replied: "The date of the next +election will be decided by Downing Street, not Fleet Street." + Downing Street is the Prime Minister's official residence, +Fleet Street the traditional home of the British national +press. + A Harris poll for the breakfast-time program TV-AM gave the +Tories 43 pct of the vote, representing a majority of 132 seats +in parliament, their biggest lead since the party's landslide +victory in the 1983 elections. + In The Times of London, a MORI poll gave the Tories a 92 +seat majority. It was the sixth poll to show the ruling party +with a big lead over the opposition Labour Party and the +fast-improving centrist Alliance. + Leading the chorus urging Thatcher to go to the polls in +June, Sir Marcus Fox, vice-chairman of the influential 1922 +committee of Conservative back-benchers, said: "I have always +felt that it would be June, and this reinforces my view. + "I always thought June was right. We have got most of our +legislation through and to go beyond that I do not think would +be in the national interest." + Another Tory back-bencher, Anthony Beaumont-Dark, said: "I +have always been an October man, but I think it would be good +to get it out of the way now." + Their comments came as government officials dismissed +speculation about a snap election to coincide with local polls +in May, timed to reap maximum advantage from the recent +popularity surge, Thatcher's successful trip to Moscow and +Labour's current popularity slump. + Calls for a May poll were also prompted by Tory concern +over a steady advance by the Alliance, and the possibility that +if it continues it could rob the Conservatives of an overall +majority in parliament. + Today's MORI poll showed an Alliance gain of eight points +over the past month in around 100 key marginal seats where the +outcome of the next election is likely to be decided. + Reuter + + + + 7-APR-1987 11:08:21.35 + +ukportugal + + + + + +F +f1175reute +d f BC-PORTUGUESE-AIRLINE-CO 04-07 0122 + +PORTUGUESE AIRLINE CONFIRMS AIRBUS A310 ORDER + LONDON, April 7 - Portugal's "flag carrier" airline TAP has +confirmed an order for three Airbus Industrie <AINP.PA> +A310-300 passenger aircraft, British Aerospace Plc <BAEL.L> +(BAe), one of four shareholders in the international Airbus +consortium, said. + BAe said in a statement TAP had also taken options on +another two Airbus aircraft, either the existing A310-300 +medium range craft or the long-range four-engined A340 which +Airbus hopes to launch in 1992, depending on the airline's +needs. + BAe said the firm order confirmed a commitment taken by TAP +in January. Details of the value of the contract, delivery +dates or which engine would power the aircraft were not +available. + Reuter + + + + 7-APR-1987 11:08:49.00 + + + + + + + +G +f1177reute +r f BC-LONDON-EC-BARLEY/WHEA 04-07 0053 + +LONDON EC BARLEY/WHEAT CLOSING - APR 7 + BARLEY WHEAT + May 114.65 May 122.80 + Sep 99.85 Jul 125.50 + Nov 102.45 Sep 101.20 + Jan 105.05 Nov 103.40 + Mar 107.50 Jan 106.35 + May 109.40 Mar 108.75 + May 111.40 + ALL VALUES + SALES + BARLEY 24 + WHEAT 197 + + + + + + 7-APR-1987 11:09:35.39 + + + + + + + +LQ +f1178reute +b f BC-FLASH-ST-PAUL-HOGS-UP 04-07 0030 + +FLASH ST PAUL HOGS UP 1.00/2.00 DLRS - USDA + st paul, april 7 - barrow and gilt prices rose 1.00 to 2.00 +dlrs in very active trade, the usda said. us 1-3 220-260 lbs +51.50-52.00. + Reuter + + + + 7-APR-1987 11:09:39.16 +money-fx + +volcker + + + + +V +f1179reute +f f BC-******VOLCKER-SAYS-RE 04-07 0011 + +******VOLCKER SAYS RESTRICTIVE MONETARY POLICY WOULD HURT INVESTMENT +Blah blah blah. + + + + + + 7-APR-1987 11:09:46.42 + + + + + + + +M +f1180reute +b f BC-LME-ZINC-AFT-2ND-RING 04-07 0025 + +LME ZINC AFT 2ND RING 1607 - APR 7 + LAST BUYER SELLER + Hg Cash -- -- -- + 3 Months -- 456.0 457.0 + + + + + + 7-APR-1987 11:09:52.58 + + + + + + + +MQ +f1181reute +u f BC-ny-metals-est-vols 04-07 0035 + +N.Y. METALS FUTURES ESTIMATED VOLUMES- APRIL 7 + Time 10.00 11.00 + Silver 8000 13000 + Copper 900 1700 + Gold 4500 8000 + Aluminum 0 1 + Palladium ---- 190 + Platinum ---- 2226 + Reuter + + + + + + 7-APR-1987 11:10:01.59 + + + + + + + +C T +f1182reute +u f BC-ny-sugar-mids-report 04-07 0102 + +WORLD SUGAR FUTURES TUMBLE IN EARLY TRADING + NEW YORK, April 7 - World sugar futures tumbled early when +sell stops were triggered at 6.60 and 6.55 cents basis the spot +contract, traders said. + Spot May dropped 0.27 cent to 6.52 cents a lb. It opened at +6.72 cents. + Trade houses worked both sides of the market, analysts +said. + The decline may have been a continued reaction to the +market's inability yesterday to breach resistance around 6.93 +cents basis May, which unsettled traders, analysts said. + The market should draw support from buying tenders slated +for tomorrow and Saturday, they said. + Reuter + + + + 7-APR-1987 11:10:11.23 + + + + + + + +RM C M +f1183reute +u f BC-GOLD-AND-SILVER-CLOSE 04-07 0111 + +GOLD AND SILVER CLOSE OFF HIGHS IN ZURICH + ZURICH, April 7 - Gold and silver closed off the day's +highs on profit-taking, but silver, which continued to set the +pace, remained well up on yesterday's close, dealers said. + Underlying speculative demand for silver remained strong +but profit-taking eroded the gains, taking the metal off +indicated highs at around 6.80 dlrs to close at 6.64/66 dlrs an +ounce. Yesterday's close was 6.52/54 dlrs. + Some investors were noted selling gold and switching into +silver. This combined with profit-taking to push gold down to a +close of 418.50/419.00 dlrs from its opening 421.80/422.20 and +yesterday's 421.50/422.00. + Dealers said it was unclear if the silver rally had peaked +or if fresh gains could be achieved in New York. + "A lot depends on the Dow Jones index," one dealer commented. +"Further gains in stock prices would take away a lot of the +support for silver and gold." + Platinum ended 50 cents higher at 563/567 dlrs. + REUTER + + + + 7-APR-1987 11:10:21.78 + +swedenusa + + + + + +F +f1184reute +d f BC-SWEDEN'S-ERICSSON-WIN 04-07 0081 + +SWEDEN'S ERICSSON WINS U.S. ORDER + STOCKHOLM, April 7 - Sweden's Telefon AB L.M. Ericsson +<ERIC.ST> said it has won its third contract from U.S. West Co +Inc <WST> for digital exchange equipment to be supplied in the +state of Idaho over the next five years. + No financial details were available. The company said the +contract provided for the replacement of more than 50 older +exchanges run by <Mountain Bell>, one of U.S. West's three +operating companies, with Ericsson's AXE system. + Reuter + + + + 7-APR-1987 11:10:24.80 + + + + + + + +LQ CQ +f1185reute +b f BC-FLASH-OMAHA-HOGS-UP-1 04-07 0026 + +FLASH OMAHA HOGS UP 1.00 DLR - USDA + omaha, april 7 - barrow and gilt prices rose 1.00 dlr in +active trade, the usda said. us 1-3 220-260 lbs 51.00-51.50. + Reuter + + + + 7-APR-1987 11:10:27.07 + + + + + + + +RM C +f1186reute +u f BC-BANK-OF-ENGLAND-STERL 04-07 0016 + +BANK OF ENGLAND STERLING INDEX - CLOSING APRIL 7 + 72.3 AFTER NOON 72.3 + (PREVIOUS CLOSE 72.4 ) + + + + + + 7-APR-1987 11:11:03.67 + + + + + + + +C G +f1188reute +u f BC-cbt-wheat-opg-report 04-07 0130 + +CBT WHEAT FUTURES OPEN FIRMER, SET NEW HIGHS + CHICAGO, April 7 - CBT wheat futures opened firmer to again +set new contract highs in new crop, then back off those highs +to hold gains of 1-1/4 cents per bushel in May, with new crop +July unchanged in light early dealings. + Steady speculative buying after yesterday's strong close +kept the chart picture very bullish and supported initial +values, traders said. + Rumors that exporters are planning to ship SRW wheat out of +Toledo and/or Chicago, further tightening already low +deliverable stocks, kept May firm relative to new crop months, +they added. + However, the rally failed to follow-through due to the lack +of confirmed export sales of significant quantities of U.S. +wheat so far this week, as some traders expected. + + Reuter + + + + 7-APR-1987 11:11:10.86 + + + + + + + +RM +f1189reute +u f BC-DOLLAR-CLOSES-LITTLE 04-07 0103 + +DOLLAR CLOSES LITTLE CHANGED IN FRANKFURT + FRANKFURT, April 7 - The dollar closed virtually unchanged +from yesterday's finish, but near the day's high after another +extremely quiet session. + With the G-5 meeting in Washington ahead of this week's IMF +interim committee, traders remained reluctant to open any large +positions. Towards the end of the day the dollar firmed after +failing earlier to hold beneath 1.82 marks. Some dealers said +Senate testimony from Fed Chairman Paul Volcker also lent +support. + The dollar closed at 1.8265/75 marks after opening at +1.8200/15 and closing yesterday at 1.8260/70. + Volcker said that a further sizeable dollar decline could +be counter-productive, and that exchange rate adjustments have +been enough to narrow the U.S. Trade deficit. + Such remarks in the past might have moved the dollar +sharply, today they only pushed it up 20 or 30 basis points +when it was already firming for technical reasons. + The dollar in any case held in a narrow range today, +trading early in the morning just below 1.82 marks and rising +to a high of 1.8270. + Dealers said they were awaiting comments after the G-5 +meeting from U.S. Treasury Secretary James Baker. + Looking slightly further ahead, the market is awaiting U.S. +February trade data, due on April 14. + Another set of disappointing figures could push the dollar +below its recent 1.80-85 mark range if there have been no +supportive statements from G-5 officials in Washington in the +meantime, dealers said. + Sterling closed slightly easier at 2.950/954 marks, after +opening at 2.951/955 and closing yesterday at 2.954/958. + The pound has been buoyed by expectations the ruling +Conservatives will win the next U.K. Election. + But dealers said sterling now looks high against the mark +and room for further gains must be limited. + Many dealers believe sterling will enter the EMS joint +float after a U.K. Election. In this case, its ceiling could +well be at or near 2.95 marks, dealers said. + The yen closed at 1.2550/70 marks per 100 after closing +yesterday at 1.2490/2510, and the Swiss franc firmed to +120.55/70 marks per 100 from 120.10/50. + The French franc ended unchanged at 30.04/07 marks per 100. + REUTER + + + + 7-APR-1987 11:11:20.04 + + + + + + + +YQ +f1190reute +u f BC-U.S.-POSTED-PRICES-RE 04-07 0104 + +U.S. POSTED PRICES REPORT (DLRS/BBL) + COMPANY....EFFECTIVE DATE..W.T.I.....W.T.S...LT LOUISIANA + AMOCO.......2/23/87........17.50.....16.60....17.85 + ARCO........4/06/87........18.00.....17.10....18.35 + CHAMPLIN....1/12/87........17.50.....17.00....17.85 + CHEVRON.....2/04/87... ....17.50.....17.50....17.85 + CITGO.......3/12/87........17.50.....17.50....17.85 + COASTAL.....3/12/87........17.50.....16.60......... + CONOCO......3/09/87........17.50.....16.60....17.85 + DIAMOND.SH..3/12/87........17.50................... + EXXON.......3/12/87........17.50.....16.60....17.85 + MARATHON....3/12/87........17.50.....17.50....17.85 + COMPANY....EFFECTIVE DATE..W.T.I.....W.T.S....LT LOUISIANA + MOBIL......2/10/87.........17.50.....17.50....17.85 + MURPHY.....3/12/87.........17.50.....17.50....17.85 + PERMIAN....3/12/87.........17.50.....17.50....17.85 + PHILLIPS...3/12/87.........17.50.....17.50......... + SHELL......1/20/87.........18.11.....17.23....17.89 + SUN........3/12/87.........17.50.....17.50....17.85 + TEXACO*....4/01/87............................17.85 + UNION......3/12/87.........17.50.....17.50....17.85 + * Deleted West Texas-New Mexico postings. + + + + + + 7-APR-1987 11:12:10.97 + + + + + + + +C L +f1193reute +u f BC-live-hog-report 04-07 0127 + +LIVE HOG FUTURES HIGHER EARLY + CHICAGO, April 7 - Live Hog futures ran up for gains of +0.57 to 0.07 cent in eary trade paced by April and June. + Fairly active demand reflected strength in cash hogs and +the continued discount of futures to cash. The start of +fieldwork limited farmer movement of hogs to market and +prompted packers to bid up for hogs. Mostly steady to firm cash +pork products added to support, traders said. + However, prices slipped from the highs in latest trade as +commercial profit-taking developed. Some selling was also +attributed to expectations that cash ham prices will be falling +soon on a seasonal basis, they said. + Thomson and RBH bought while Packers Trading and Refco +sold. Stotler spread long June/short April, they added. + Reuter + + + + 7-APR-1987 11:12:32.96 + + + + + + + +GQ +f1194reute +u f BC-MIDWEST-GRAIN-FUTURES 04-07 0060 + +MIDWEST GRAIN FUTURES 11:10 EDT +KANSAS CITY WHEAT + MAY7 274 1/2 UP 1/2 + JUL7 263 1/2 UP 1/2 + SEP7 265 1/2 UP 1/4 + DEC7 270 1/2 OFF 1/4 + MAR8 -- --MINNEAPOLIS WHEAT + MAY7 285 UP 1 1/2 + JUL7 280 3/4 UNCH + SEP7 277 UP 1 + DEC7 -- -- + MAR8 -- -- + + + + 7-APR-1987 11:12:47.66 + + + + + + + +RM +f1196reute +u f BC-LONDON-LIFFE-YEN-CLOS 04-07 0024 + +LONDON LIFFE YEN CLOSE 1610 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun 6918 6928 6918 6878 + Sep 6964 6964 6962 6923 + + + + + + 7-APR-1987 11:12:56.28 + + + + + + + +RM +f1197reute +u f BC-LONDON-LIFFE-EURODOLL 04-07 0064 + +LONDON LIFFE EURODOLLAR CLOSE 1610 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun 9333 9334 9330 9336 + Sep 9326 9328 9325 9330 + Dec 9318 9319 9317 9322 + Mar 9304 9305 9300 9308 + Jun 9284 9285 9283 9288 + Sep 9262 9262 9260 9267 + Dec 9240 9240 9238 9245 + Mar 9219 9219 9218 9224 + + + + + + 7-APR-1987 11:13:07.76 + + + + + + + +GQ +f1198reute +u f BC-CBT-11-10-EDT 04-07 0108 + +CBT 11:10 EDT +WHEAT +MAY7 287 1/2 UP 1 1/4 +JUL7 273 UP 1/4 +SEP7 273 1/2 UP 1/2 +DEC7 279 1/4 UP 1 1/4 +MAR8 278 1/4 UP 1 +CORN +MAY7 160 UP 1 3/4 +JUL7 163 1/2 UP 1 3/4 +SEP7 168 1/4 UP 2 +DEC7 176 3/4 UP 2 +MAR8 183 1/4 UP 1 1/2 +OATS +MAY7 149 1/2 OFF 1/2 +JUL7 138 OFF 1/2 +SEP7 128 3/4 UP 1/2 +DEC7 134 UNCH +MAR8 UNTRD +BEANS +MAY7 501 1/4 UP 1 1/2 +JUL7 502 1/4 UP 2 +AUG7 502 1/2 UP 3 +SEP7 497 1/2 UP 3 1/2 +NOV7 499 UP 3 +JAN8 505 1/2 UP 3 +MEAL +MAY7 1455 UP 2 +JUL7 1455 UP 4 +AUG7 1455 UP 5 +SEP7 1458 UP 7 +OCT7 1457 UP 6 +OIL +MAY7 1556 UP 13 +JUL7 1591 UP 13 +AUG7 1608 UP 13 +SEP7 1623 UP 12 +OCT7 1635 UP 10 + + + + + + 7-APR-1987 11:13:21.62 + + + + + + + +F +f1200reute +f f BC-******HONEYWELL-BULL 04-07 0013 + +******HONEYWELL BULL INTRODUCES HIGH PERFORMANCE COMPUTERS FOR MEDIUM, LARGE FIRMS +Blah blah blah. + + + + + + 7-APR-1987 11:13:32.95 + + + + + + + +C L +f1201reute +u f BC-PORK-BELLY-FUTURES-ST 04-07 0128 + +PORK BELLY FUTURES START HIGHER, THEN EASE + CHICAGO, April 7 - Pork belly (bacon) futures ran up for +gains of 0.55 to 0.30 cent at the start and then eased to trade +0.15 cent lower to 0.15 higher in early dealings. + Active local carryover demand and mixed commission house +buying lifted futures at the start. Higher cash hog markets on +light runs and spillover from other meat pits prompted support, +traders said. + However, locals turned sellers along with Saul Stone and +Paine Webber and prices turned mostly lower. Trimming of gains +in other pits and expectations of possibly negative out of town +storage report this afternoon weighed on the market. Guesses on +the report ranged from in 1.0 to 2.25 mln lbs with most +indications on the high side, they noted. + Reuter + + + + 7-APR-1987 11:13:39.69 + + + + + + + +L +f1202reute +u f BC-miss-direct-hogs 04-07 0079 + +MISSOURI DIRECT HOGS UP 1.00-1.50 DLR - USDA + JEFFERSON CITY, April 7 - Barrow and gilts in the east and +west were 1.00 to 1.50 dlr higher than monday's midsession. Top +50.50 dlrs per cwt. + EAST WEST +U.S. 1-2 210-250 LB 49.50-50.50 49.50-50.50 +U.S. 1-3 210-250 LB 49.50-50.50 49.50-50.50 +U.S. 1-2 200-210 LB 48.50-49.50 48.50-49.50 + SOWS - steady/up 2.00 dlrs. Top 46.00 dlrs. +US 1-3 300-500 lb 42.00-43.00, over 500 lb 43.00-46.00 dlrs. + Reuter + + + + 7-APR-1987 11:14:21.32 + + + + + + + +RM +f1205reute +u f BC-LOMDON-LIFFE-STERLING 04-07 0064 + +LOMDON LIFFE STERLING-DP CLOSE 1612 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun 9071 9079 9070 9078 + Sep 9096 9104 9096 9104 + Dec 9051 9056 9051 9051 + Mar 9089 9097 9089 9098 + Jun 9076 9076 9076 9083 + Sep 9055 9055 9055 9061 + Dec 9055 9055 9055 9061 + Mar 9027 9027 9027 9030 + + + + + + 7-APR-1987 11:14:26.83 + + + + + + + +RM +f1206reute +u f BC-LONDON-LIFFE-STERLING 04-07 0038 + +LONDON LIFFE STERLING CLOSE 1612 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun 16100 16100 16100 16085 + Sep --- --- --- 15985 + Dec --- --- --- 15885 + Mar --- --- --- 15784 + + + + + + 7-APR-1987 11:14:36.23 +money-fx +usa +volcker + + + + +V RM +f1207reute +b f BC-VOLCKER-SEES-TIGHT-PO 04-07 0076 + +VOLCKER SEES TIGHT POLICY HURTING INVESTMENT + WASHINGTON, April 7 - Federal Reserve Board Chairman Paul +Volcker said a restrictive monetary policy would be damaging to +investment and that a better course would be to restrain +spending. + "A restrictive monetary policy would hit investment. You +don't want to put interest rates up unless you have to," Volcker +told the Senate Banking Committee. + "That is not a constructive way to proceed," he said. + Volcker said that given a choice between squeezing the +budget deficit or squeezing investment, he would favor +squeezing the budget deficit. + In response to a question about banks, Volcker said he +would be pleased if Congress decided to give banks a tax +writeoff as an incentive for them to take greater reserves +against loans to debtor countries. + "If you give a tax writeoff for reserving against loans, +then we will see more reserving and that would make me happy," +Volcker told Committee Chairman Sen William Proxmire (D-Wisc). + Reuter + + + + 7-APR-1987 11:14:55.96 + +usa + + + + + +F +f1209reute +d f BC-REUTERS-<RtrSY>-UNIT 04-07 0108 + +REUTERS <RtrSY> UNIT COMPLETES TRADING SYSTEM + NEW YORK, April - Rich Inc, a wholly-owned subsidiary of +Reuters Holdings PLC of London, said it completed installation +of a 20 mln dlr trading system for Merrill Lynch and Co Inc +<MER> in New York. + The company said its Composite Information System was +designed and installed for Merrill Lynch in the investment +firm's World Financial Center offices in downtown Manhattan. + The system, which offers access to financial news, in-house +computers, commercial television and other services, includes +479 equity positions, 614 in the debt area and 152 municipal +markets positions, the company said. + Reuter + + + + 7-APR-1987 11:15:52.09 + + + + + + + +RM +f1211reute +u f BC-LONDON-LIFFE-D.MARK-C 04-07 0025 + +LONDON LIFFE D.MARK CLOSE 1614 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun --- --- --- 5507 + Sep --- --- --- 4885 + + + + 7-APR-1987 11:17:29.61 + + + + + + + +GQ +f1215reute +u f BC-CME-11-15--EDT 04-07 0053 + +CME 11:15 EDT + +L-CATTLE +APR7 69.60 UP 0.20 +JUN7 64.97 OFF 0.05 +AUG7 60.75 OFF 0.12 +F-CATTLE +APR7 69.00 OFF 0.10 +MAY7 68.12 OFF 0.10 +AUG7 66.50 UP 0.10 +HOGS +APR7 50.12 UP 0.30 +JUN7 48.80 UP 0.33 +JUL7 47.30 UP 0.43 +BELLIES +MAY7 66.25 OFF 0.15 +JUL7 64.77 OFF 0.08 +AUG7 61.75 UP 0.15 +FEB8 56.10 UP 0.50 + + + + + + 7-APR-1987 11:18:01.28 + + + + + + + +RM +f1216reute +u f BC-LONDON-LIFFE-S.FRANC 04-07 0025 + +LONDON LIFFE S.FRANC CLOSE 1616 - APR 7 + MTH LAST HIGH LOW PR.SET + Jun --- --- --- 6627 + Sep --- --- --- 6041 + + + + 7-APR-1987 11:18:17.62 + + + + + + + +RM +f1217reute +r f BC-stockholm-exchanges-c 04-07 0049 + +Stockholm exchanges clsg apr 6 stg 10.2807 10.2872 us 6.3540 +6.3560 dmk 348.3170 348.4840 ffr 104.6787 104.7981 sfr 419.8216 +420.2314 bfr con 16.8139 16.8281 dfl 308.7313 308.9186 dkr +92.4016 92.4643 nkr 93.1262 93.1965 lit 0.4889 0.4893 aus sch +49.5438 49.5788 can 4.8611 4.8645 yen 4.3730 4.3774 + + + + + + 7-APR-1987 11:18:33.41 + + + + + + + +F +f1219reute +u f BC-HOSPITAL-CORP-OF-AMER 04-07 0017 + +HOSPITAL CORP OF AMERICA, 100,000 AT 38-1/2, UNCH, ALL BUYSIDE +BY ABD SECURITIES ON THE BOSTON EXCHANGE + + + + + + 7-APR-1987 11:18:44.72 + + + + + + + +C G +f1220reute +u f BC-cbt-s'bean-opg-report 04-07 0102 + +CBT SOYBEAN FUTURES OPEN SLIGHTLY FIRMER + CHICAGO, April 7 - CBT soybean futures opened steady, with +new crop slightly firmer, then rallied further to hold gains of +one cent to three cents per bushel higher in light early +dealings. + A firmer Gulf soybean basis this morning, strength in corn +futures and delays in the Brazilian soybean harvest supported +soybean futures, despite a disappointing drop in the weekly +soybean export figure yesterday afternoon, traders said. + A local professional house and a local house were the +featured buyers of July, with sellers scattered and small-lot, +pit brokers said. + Reuter + + + + 7-APR-1987 11:18:57.30 + + + + + + + +RM C G L M T +f1221reute +u f BC-DOLLAR-REMAINS-IN-NAR 04-07 0096 + +DOLLAR REMAINS IN NARROW RANGE IN QUIET ZURICH + ZURICH, April 7 - The dollar remained confined in the same +narrow range in quiet trading, benefitting only slightly from +comments by Fed Chairman Paul Volcker that further sizeable +dollar losses would be counter-productive, dealers said. + It finished at 1.5140/50 Swiss francs after opening at +1.5128/38 and closing yesterday at 1.5185/95. + "Volcker's remarks produced some buying interest but most +people were still waiting to see what comes out of the finance +ministers' meetings in Washington," one dealer said. + Other currencies lost ground against the Swiss franc. + Sterling eased after advancing sharply yesterday on +expectations of an early U.K. General election. The pound ended +at 2.4469/4501 francs compared with 2.4547/4578 yesterday. + The mark slipped to 82.83/93 centimes from 83.11/21 and the +French franc dipped to 24.90/94 from 24.98/25.02. + REUTER + + + + 7-APR-1987 11:19:14.60 + + + + + + + +M +f1223reute +b f BC-LME-COPPER-AFT-2ND-RI 04-07 0026 + +LME COPPER AFT 2ND RING 1617 - APR 7 + LAST BUYER SELLER + Std Cash -- -- -- + 3 Months -- -- -- + + + + + + 7-APR-1987 11:19:21.24 + + + + + + + +TQ +f1224reute +u f BC-ny-comms-est-vols 04-07 0053 + +N.Y. COMMODITY FUTURES ESTIMATED VOLUMES - APRIL 7 + Time 11.00 + Coffee 825 + Cocoa 756 + Sugar 11 7040 + Sugar 14 16 + Orange ---- + Cotton ---- + Sugar 11 options calls 364 + Sugar 11 options puts 115 + Reuter + + + + + + 7-APR-1987 11:19:24.46 + + + + + + + +M +f1225reute +b f BC-LME-COPPER-AFT-2ND-RI 04-07 0026 + +LME COPPER AFT 2ND RING 1617 - APR 7 + LAST BUYER SELLER + Hg Cash 909.5 909.5 910.0 + 3 Months 879.0 879.0 879.5 + + + + + + 7-APR-1987 11:19:32.58 + + + + + + + +L +f1226reute +u f BC-ST-LOUIS-CATTLE-STEAD 04-07 0054 + +ST LOUIS CATTLE STEADY/UP 0.50 DLR - USDA + st louis, april 7 - slaughter steers were firm to 0.50 dlr +higher in active trade and heifers fully steady amid limited +supply, the usda said. + steers - choice 2-4 975-1250 lbs 64.00-65.50, package 2-3 +1230 lbs 66.00. + heifers - few lots choice 2-4 900-1075 lbs 61.50-63.00. + Reuter + + + + 7-APR-1987 11:19:42.99 + +uk + + +liffe + + +RM +f1227reute +u f BC-LIFFE,-AFTER-RECORD-V 04-07 0111 + +LIFFE, AFTER RECORD VOLUMES, SEES MORE GROWTH + LONDON, April 7 - The records in turnover set by the London +International Financial Futures Exchange (LIFFE) in March could +be surpassed in the coming months, Liffe Chief Executive +Michael Jenkins said. + Last month, Liffe saw record monthly futures volume at 1.15 +mln lots, and record monthly options volume at 97,700. Total +Liffe volume in first quarter 1987 rose to 2.8 mln contracts, +or 89 pct up on the same 1986 period. + Long gilt turnover in first quarter 1987 was 300 pct up on +the year-ago period at 1.63 mln lots versus 409,500. But T-bond +volume fell by 38 pct to 244,500 in first three months 1987. + Jenkins told Reuters the higher volumes for gilts reflected +in part the volatility in the U.K. Markets in recent months, +while the falloff in T-bonds was an indication of the relative +stability of U.S. Credit markets. + Jenkins said he saw room for the whole financial futures +sector to grow further in the coming months. In particular, FT- +SE 100 futures had great scope for expansion, and turnover in +them should be much higher by end 1987. + FT-SE futures volume was 62,700 in first quarter 1987, an +increase of 124 pct over the 28,000 contracts recorded in the +same months of 1986. + Institutions here had been slow to find out about the use +of stock exchange futures, but they would now learn more, +Jenkins predicted. + Commenting on the difference in popularity between gilts +and bonds, Jenkins said Liffe had designed the widest possible +variety of contracts so that at any given time, at least one +sector would be volatile enough to attract trading. The current +situation of U.S. Markets being steady, and U.K. Ones +changeable, might alter completely in coming months. + A further boost to Liffe's volume and attractiveness should +come with the introduction of yen bond futures, he added. + REUTER + + + + 7-APR-1987 11:20:07.42 +earn +usa + + + + + +F +f1230reute +r f BC-NEW-BEDFORD-INSTITUTI 04-07 0025 + +NEW BEDFORD INSTITUTION FOR SAVINGS <NBBS> YEAR + NEW BEDFORD, Mass., April 7 - + Net 12.3 mln vs 6,438,000 + NOTE: Company went public in March. + Reuter + + + + 7-APR-1987 11:20:16.05 + +usa + + + + + +F +f1231reute +b f BC-HONEYWELL-BULL-UNVEIL 04-07 0077 + +HONEYWELL BULL UNVEILS FIVE NEW COMPUTERS + MINNEAPOLIS, April 7 - Honeywell Bull, a 1.9 billion dlr +computer systems company formed March 27 by Honeywell Inc +<HON>, Compagnie des Machines Bull of France and NEC Corp of +Japan, said it introduced a line of high-performance computers +for medium and large companies. + The company also unveiled software for the new systems to +facilitate patient care in hospitals and control inventory and +production in factories. + Honeywell Bull said its new line includes five models in +the DPS 7000 family of 32-bit virtual memory systems that +support as many as 600 terminals and perform between 9,000 and +52,000 transactions an hour. + Prices for the systems will range from 127,000 dlrs to more +than 1.0 mln dlrs. + It said two integrated, modular software packages +introduced are specifically for operation on DPS 7000 +computers. + Reuter + + + + 7-APR-1987 11:20:25.56 + +usa + + + + + +F +f1232reute +r f BC-OXFORD-ENERGY-CO-<OEN 04-07 0095 + +OXFORD ENERGY CO <OEN> TO BUILD ENRGY PLANT + NEW YORK , APri 7 - The Oxford Energy Co said it received +final approval from the Connecticut Department of Public Utiliy +Control of a power contract for the company's tire burning +energy plant to be located in Sterling, Conn. + The Oxford facility has an estimated total cost of +approximately 70 mln dlrs, and is expected to start +construction during the second half of 1987. Construction of +the project is subject to the receipt of various state and +local permits, the company said, and the arrangement of +financing. + Under the terms of the order, issued by the Connecticut +Department of Publc Utility Control, Connecticut Light and +Power Co will be required to purchase the output of the +Sterling facility under a 25-year power purchase aagreemnt at +prices fixed by the contract formulas, the company said. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-015.sgm b/src/test/data/reuters-21578/reut2-015.sgm new file mode 100644 index 00000000000..ddd453fa0ef --- /dev/null +++ b/src/test/data/reuters-21578/reut2-015.sgm @@ -0,0 +1,2003 @@ + + + 8-APR-1987 10:08:12.27 +acq +usa + + + + + +F +f1041reute +d f BC-PAXAR-CORP-<PAKS>-MAK 04-08 0032 + +PAXAR CORP <PAKS> MAKES ACQUISITION + PEARL RIVER, N.Y., April 8 - Paxar Corp said it has +acquired Thermo-Print GmbH of Lohn, West Germany, a distributor +of Paxar products, for undisclosed terms. + Reuter + + + + 8-APR-1987 10:08:15.55 +earn +canada + + + + + +E F +f1042reute +d f BC-<mark's-work-wearhous 04-08 0027 + +<MARK'S WORK WEARHOUSE LTD> YEAR JAN 31 NET + Calgary, Alberta, April 8 - + Shr 10 cts vs 32 cts + Net 975,000 vs 3,145,000 + Sales 159.1 mln vs 147.3 mln + Reuter + + + + 8-APR-1987 10:08:21.25 + +usa + + + + + +F +f1043reute +d f BC-KEY-TRONIC-<KTCC>-GET 04-08 0068 + +KEY TRONIC <KTCC> GETS NEW BUSINESS + SPOKANE, Wash., April 8 - Key Tronic corp said it has +received contracts to provide seven original equipment +manufacturers with which it has not done business recently with +over 300,000 computer keyboards for delivery within the next 12 +months. + The company said "The new contracts represent an annual +increase of approximately 25 pct in unit volume over last +year." + Reuter + + + + 8-APR-1987 10:08:26.93 +acq +canada + + + + + +E F Y +f1044reute +d f BC-canadian-bashaw,-ersk 04-08 0061 + +CANADIAN BASHAW, ERSKINE RESOURCES TO MERGE + Edmonton, Alberta, April 8 - Canadian Bashaw Leduc Oil and +Gas Ltd said it agreed to merge with Erskine Resources Ltd. +Terms were not disclosed. + Ownership of the combined company with 18.8 pct for the +current shareholders of Canadian Bashaw and 81.2 pct to the +current shareholders of Erskine, the companies said. + Reuter + + + + 8-APR-1987 10:11:16.60 +earn +usa + + + + + +F +f1055reute +d f BC-ENTOURAGE-<ENTG>-HAS 04-08 0097 + +ENTOURAGE <ENTG> HAS FIRST QUARTER LOSS + HOUSTON, April 8 - Entourage International Inc said it had +a first quarter loss of 104,357 dlrs, after incurring 70,000 +dlrs in costs for an internal audit, a report for shareholders +and proxy soliciation and 24,000 dlrs in startup expenses for +opening London offices. + The company went public during 1986. + Entourage also said it has started marketing a solid +perfume packaged in a lipstick tube called "Amadeus," retailing +at 15 dlrs. + The company also said it has acquired North Country Media +Group, a video productions company. + Reuter + + + + 8-APR-1987 10:11:26.26 +earn +canada + + + + + +E F +f1056reute +d f BC-<mr.-jax-fashions-inc 04-08 0028 + +<MR. JAX FASHIONS INC> YEAR FEB 28 NET + Vancouver, British Columbia, April 8 - + Shr 58 cts vs 29 cts + Net 3,141,000 vs 1,440,000 + Sales 24.7 mln vs 13.0 mln + Reuter + + + + 8-APR-1987 10:11:53.50 + +usa + + + + + +F +f1060reute +d f BC-DIGITAL-COMMUNICATION 04-08 0058 + +DIGITAL COMMUNICATIONS<DCAI> NAMES NEW PRESIDENT + ALPHARETTA, Ga., April 8 - Digital Communications +Associates Inc said its board has named James Ottinger +president and chief operating officer. + The company said Ottinger replaces Bertil Nordin as +president. Nordin will become chairman and chief executive +officer, Digital Communications added. + Reuter + + + + 8-APR-1987 10:11:58.32 + +usa + + + + + +F +f1061reute +d f BC-DIGITAL-<DEC>-IN-TERA 04-08 0054 + +DIGITAL <DEC> IN TERADYNE <TER> LICENSING PACT + BOSTON, April 8 - Teradyne Inc said Digital Equipment Corp +signed a multi-license purchase agreement valed at over one mln +dlrs for Teradyne's Lasar Version Six Simulation System. + The company said the agreement includes the option for +futrue lasar purchases by Digital. + Reuter + + + + 8-APR-1987 10:12:18.53 + +usa + + + + + +F +f1064reute +d f BC-HOME-INTENSIVE-<KDNY> 04-08 0032 + +HOME INTENSIVE <KDNY> EXTENDS DIALYSIS AT HOME + NORTH MIAMI BEACH, Fla., April 8 - Home Intensive Care Inc +said it has opened a Dialysis at Home office in Philadelphia, +its 12th nationwide. + Reuter + + + + 8-APR-1987 10:14:36.24 + +canada + + +tose + + +E F +f1071reute +u f BC-bache-canada-buys 04-08 0113 + +BACHE CANADA BUYS TORONTO STOCK EXCHANGE SEAT + TORONTO, April 8 - Bache Securities Inc, 80 pct owned by +Prudential Bache Securities Inc, said it acquired its third +Toronto Stock Exchange seat for 301,000 Canadian dlrs. + The company said the price was the highest yet paid for an +exchange seat. A Toronto Stock Exchange spokesman said an +exchange seat last sold for 195,000 dlrs in March, which was +acquired by <Toronto Dominion Bank>. + Bache Securities said it needed a third exchange seat as +part of an extensive plan to provide an enhanced level of +service to clients. The seat will be used to further build its +professional trading area, the investment dealer said. + Reuter + + + + 8-APR-1987 10:17:29.78 +earn + + + + + + +F +f1081reute +f f BC-******F.W.-WOOLWORTH 04-08 0012 + +******F.W. WOOLWORTH CO SAYS IT HIKES DIVIDEND TO 33 CTS A SHARE FROM 28 CTS +Blah blah blah. + + + + + + 8-APR-1987 10:19:42.41 +earn +usa + + + + + +F +f1088reute +b f BC-F.W.-WOOLWORTH-CO-<Z> 04-08 0021 + +F.W. WOOLWORTH CO <Z> HIKES DIVIDEND + NEW YORK, April 8 - + Qtly div 33 cts vs 28 cts prior + Pay June 1 + Record May 1 + Reuter + + + + 8-APR-1987 10:20:02.86 +sugar +netherlands + + + + + +C T +f1089reute +u f BC-DUTCH-SUGAR-BEET-PLAN 04-08 0103 + +DUTCH SUGAR BEET PLANTING HALF FINISHED + ROTTERDAM, April 8 - Roughly half of this year's expected +130,000 hectare Dutch sugar beet crop is already in the ground, +a spokesman for Suiker Unie, the largest sugar processor in the +Netherlands, told Reuters. + Conditions are generally good and the average sowing date +for the crop is expected to be around April 11, against April +23 last year, and a 10-year average of April 14, the spokesman +added. + "It is far too early yet to say what kind of output we can +expect when it comes to harvest in September, but at least the +crop is off to a very good start," he said. + Last year, the Netherlands planted a record 137,600 +hectares of sugar beet and produced a record 1.2 mln tonnes of +white sugar, substantially more than the country's combined "A" +and "B" quota of 872,000 tonnes. + This year, however, a self-imposed quota system has been +introduced with the aim of cutting plantings to 130,000 +hectares and reducing white sugar output to around 915,000 +tonnes to minimise the amount of non-quota "C" sugar produced. + Only farmers with a record of growing suger beet have been +allotted quotas. This is expected to prevent the area being +boosted by dairy or cereal farmers moving into sugar. + Reuter + + + + 8-APR-1987 10:20:14.11 + +uk + + + + + +F +f1090reute +d f BC-U.K.-EXPECTS-SUBSTANT 04-08 0121 + +U.K. EXPECTS SUBSTANTIAL DEMAND FOR ROLLS SHARES + LONDON, April 8 - Demand for shares in state-owned engine +maker <Rolls Royce Plc> is expected to be substantial when the +government privatises it at the end of April, Christopher Clark +of the group's bankers Samuel Montagu and Sons Ltd said. + He told a press conference after the release of an initial +prospectus for the float that the issue would be offered to +U.K. Institutions, company employees and the general public. + As in previous flotations, clawback arrangements would be +made if public subscriptions exceeded initial allocations. + He declined to say how the shares would be allocated beyond +saying that a "significant proportion" would go to institutions. + A decision on what percentage would go to each sector would +be made shortly before the sale price was announced on April +28. + Minimum subscription would be for 400 shares with payment +in two tranches, again a method broadly in line with previous +privatisations. + Chairman Sir Francis Tombs denied suggestions that Rolls +was a stock that should be left to the institutions. He noted +that although the aircraft industry was cyclical, Rolls had +several operations -- such as spare parts and military +equipment -- that evened out the swings. + Rolls' 1986 research and development expenditure in 1986 +was 255 mln stg and could be expected in the future to vary +according to changes in turnover. + He noted that net research and development expenditure was +written off in the year it occurred, a policy that received +"inadequate recognition in one or two of the more extravagant +forecasts of future profits." He made no forecast himself. + In 1986, Rolls reported that pretax profit rose 48 pct to +120 mln stg on turnover 12 pct higher at 1.8 billion. + Reuter + + + + 8-APR-1987 10:25:01.82 + +netherlands + + +nyse + + +F +f1109reute +r f BC-NV-PHILIPS-SHARES-GET 04-08 0097 + +NV PHILIPS SHARES GET NYSE QUOTE FROM APRIL 14 + EINDHOVEN, NETHERLANDS, APRIL 8 - NV Philips +Gloeilampenfabrieken <PGLO.AS> shares are due to start trading +on the New York Stock Exchange on April 14, Philips chairman +Cor van der Klugt told the annual shareholders meeting. + In March, the Dutch electronics group announced it would +end its current over the counter listing on the New York NASDAQ +system and move to the NYSE. + Philips said the "big board" listing in New York is expected +to boost its profile in the U.S., Where 10 pct of all +outstanding Philips shares are held. + Reuter + + + + 8-APR-1987 10:25:54.05 +earn + + + + + + +F +f1110reute +f f BC-******J.P.-MORGAN-AND 04-08 0010 + +******J.P. MORGAN AND CO INC 1ST QTR SHR 1.22 DLRS VS 1.28 DLRS +Blah blah blah. + + + + + + 8-APR-1987 10:28:08.79 +sugar +belgiumfrancewest-germanyspaindenmark + +ec + + + +T C +f1117reute +b f BC-EC-COMMISSION-DETAILS 04-08 0069 + +EC COMMISSION DETAILS SUGAR TENDER + BRUSSELS, April 8 - The EC Commission confirmed it granted +export licences for 118,350 tonnes of current series white +sugar at a maximum export rebate of 46.496 European Currency +Units (ECUs) per 100 kilos. + Out of this, traders in France received 34,500 tonnes, in +the U.K. 37,800, in West-Germany 20,000, in Belgium 18,500, in +Spain 5,800 and in Denmark 1,750 tonnes. + REUTER + + + + 8-APR-1987 10:30:36.41 + +canada + + + + + +E Y +f1126reute +r f BC-pancontinental-oil-ha 04-08 0093 + +PANCONTINENTAL OIL HAS PRIVATE FINANCING + Calgary, Alberta, April 8 - <Pancontinental Oil Ltd> said +it arranged a 10 mln dlr private financing with Pemberton +Houston Willoughby Bell Gouinlock Inc. + The private placement consists of special warrants to +purchase seven pct convertible redeemable preferred shares. + The shares will be convertible for five years into common +shares at five dlrs per share. The preferred shares are not +redeemable for 2-1/2 years. Net proceeds will be used to +increase working capital and finance exploration and +development. + Reuter + + + + 8-APR-1987 10:30:58.28 + +uk + + + + + +RM +f1128reute +b f BC-FEDERAL-REALTY-CONVER 04-08 0102 + +FEDERAL REALTY CONVERTIBLE INCREASED, PRICED + LONDON, April 8 - Today's dollar convertible eurobond for +Federal Realty Investment Trust has been increased to 100 mln +dlrs from the initial 75 mln, lead manager Salomon Brothers +International said. + The coupon has been fixed at 5-1/4 pct compared with the +indicated range of 5-1/4 to 5-1/2 pct. The conversion price has +been fixed at 30-5/8 dlrs compared with last night's close in +the U.S. Of 25-1/2 dlrs. This represents a premium of 20 pct. + The put option after seven years was priced at 120 pct to +give the investor a yield to the put of 7.53 pct. + REUTER + + + + 8-APR-1987 10:34:45.43 +earn +west-germany + + + + + +F +f1147reute +r f BC-VOLKSWAGEN-DIVIDEND-D 04-08 0114 + +VOLKSWAGEN DIVIDEND DECISION DUE TOMORROW + WOLFSBURG, West Germany, April 8 - Volkswagen AG <VOWG.F>, +VW, is due to make a formal announcement about its 1986 +dividend tomorrow after saying the 1985 level of 10 marks per +ordinary share would be held, despite massive losses because of +a suspected foreign currency fraud. + A spokesman said VW's supervisory board will meet tomorrow +to discuss the payout. A statement will be made afterwards. + VW has also said disclosed profits for 1986 will reach +their 1985 level, despite provisions of a possible 480 mln +marks linked to the currency affair. The figure is virtually +the same as the 477 mln mark 1985 parent company net profit. + When VW first confirmed the currency scandal on March 10 it +said the management board would propose an unchanged 10-mark +dividend to the supervisory board. A dividend of 11 marks would +be proposed for the company's new preference shares. + Share analysts said they saw supervisory board approval of +the management board proposal as virtually a formality. +"Anything else would be more than a surprise," one said. + Company sources said VW would have to dig into reserves to +maintain the disclosed profit. Parent company reserves stood at +around three billion marks at end-1985. + Reuter + + + + 8-APR-1987 10:35:24.55 + +uk + + + + + +RM +f1152reute +b f BC-TORONTO-DOMINION-UNIT 04-08 0082 + +TORONTO DOMINION UNIT ISSUES AUSTRALIAN DLR BOND + LONDON, April 8 - Toronto Dominion Bank, Nassau Branch is +issuing a 40 mln Australian dlr eurobond due May 15, 1990 +paying 14-1/2 pct and priced at 101-3/8 pct, lead manager +Hambros Bank Ltd said. + The non-callable bond is available in denominations of +1,000 Australian dlrs and will be listed in London. The selling +concession is one pct, while management and underwriting +combined will pay 1/2 pct. + The payment date is May 15. + REUTER + + + + 8-APR-1987 10:36:31.07 + +uk + + + + + +E +f1160reute +b f BC-TORONTO-DOMINION-UNIT 04-08 0081 + +TORONTO DOMINION UNIT ISSUES AUSTRALIAN DLR BOND + LONDON, April 8 - Toronto Dominion Bank, Nassau Branch is +issuing a 40 mln Australian dlr eurobond due May 15, 1990 +paying 14-1/2 pct and priced at 101-3/8 pct, lead manager +Hambros Bank Ltd said. + The non-callable bond is available in denominations of +1,000 Australian dlrs and will be listed in London. The selling +concession is one pct, while management and underwriting +combined will pay 1/2 pct. + The payment date is May 15. + Reuter + + + + 8-APR-1987 10:37:10.01 +earn +usa + + + + + +F +f1167reute +r f BC-CITYTRUST-BANCORP-INC 04-08 0028 + +CITYTRUST BANCORP INC <CITR> 1ST QTR NET + BRIDGEPORT, Conn., April 8 - + Shr 1.40 dlrs vs 1.16 dlrs + Net 5,776,000 vs 4,429,000 + Avg shrs 4,132,828 vs 3,834,117 + Reuter + + + + 8-APR-1987 10:37:30.96 +acq +usa + + + + + +F +f1170reute +r f BC-SOUTHMARK-<SM>-ACQUIR 04-08 0071 + +SOUTHMARK <SM> ACQUIRES 28 NURSING HOMES + DALLAS, April 8 - Southmark Corp said it acquired 28 +long-term care facilities containing for approximately 70 mln +dlrs in cash. + It said the facilities, which contain approximately 2,500 +beds in seven western states, were bought from Don Bybee and +Associates, of Salem,Ore. + The acquistion brings to 57 health care facilities acquired +in the last three months, the company said. + Reuter + + + + 8-APR-1987 10:38:13.19 + +usa + + + + + +A RM +f1175reute +r f BC-HELEN-OF-TROY-<HELE> 04-08 0084 + +HELEN OF TROY <HELE> FILES CONVERTIBLE OFFERING + NEW YORK, April 8 - Helen of Troy Corp said it filed with +the Securities and Exchange Commission a registration statement +covering a 20 mln dlr issue of covertible subordinated +debentures due 2007. + Proceeds will be used for general corporate purposes, +including possible repayment of bank debt, product development +and possible acquisitions, Helen of Troy said. + The company named Drexel Burnham Lambert Inc as sole +underwriter of the offering. + Reuter + + + + 8-APR-1987 10:38:19.91 +earn +usa + + + + + +F +f1176reute +b f BC-/J.P.-MORGAN-AND-CO-I 04-08 0088 + +J.P. MORGAN AND CO INC <JPM> 1ST QTR NET + NEW YORK, April 8 - + shr 1.22 dlrs vs 1.28 dlrs + net 226.4 mln vs 233.9 mln + assets 80.45 billion vs 70.23 billion + loans 35.16 billion vs 35.99 billion + deposits 45.22 billion vs 39.68 billion + return on assets 1.14 pct vs 1.35 pct + return on common equity 18.20 pct vs 22.08 pct + NOTE: 1987 qtr net was reduced by 20 mln dlrs because 1.3 +billion dlrs of loans to Brazil were placed on non-accrual. + loan loss provision 35 mln dlrs vs 70 mln year earlier. + Reuter + + + + 8-APR-1987 10:38:37.99 +earn +usa + + + + + +F +f1179reute +r f BC-FIRSTBANC-CORP-OF-OHI 04-08 0021 + +FIRSTBANC CORP OF OHIO <FBOH> 1ST QTR NET + AKRON, Ohio, April 8 - + Shr 74 cts vs 67 cts + Net 8,067,000 vs 7,317,000 + + Reuter + + + + 8-APR-1987 10:39:08.80 +earn +usa + + + + + +F +f1183reute +r f BC-MAYFAIR-SUPER-MARKETS 04-08 0063 + +MAYFAIR SUPER MARKETS INC <MYFRA> 2ND QTR NET + ELIZABETH, N.J., April 8 -Qtr ends Feb 28 + Shr Class A 61 cts vs 48 cts + Shr Class B 59 cts vs 46 cts + Net 2,358,000 vs 1,876,000 + Revs 122,508,000 vs 105,871,000 + Six mths + Shr Class A 1.15 dlrs vs 86 cts + Shr Class B 1.13 dlrs vs 84 cts + Net 4,485,000 vs 3,378,000 + Revs 242,453,000 vs 210,117,000 + NOTE: qtr and six mths prior figures reflect two-for-one +stock split in August 1986. + Reuter + + + + 8-APR-1987 10:39:16.52 +earn +usa + + + + + +F +f1184reute +r f BC-HANOVER-INSURANCE-<HI 04-08 0074 + +HANOVER INSURANCE <HINS> GET SPLIT APPROVAL + WORCESTER, Mass., April 8 - Hanover Insurance Co said its +stockholders approved a two-for-one stock split. + As a result of the split, Hanover said it increases the +number of authorized shares of capital stock from 10.4 mln, +having a par value of one dlr, to 20.9 mln, also having a par +value of one dlr. + The stock split is payable April 30 to stockholders of +record April 10, Hanover said. + Reuter + + + + 8-APR-1987 10:39:22.31 + +usajapan + + + + + +F +f1185reute +d f BC-FEDERAL-PAPERBOARD-<F 04-08 0057 + +FEDERAL PAPERBOARD <FBO> ENTERS AGREEMENT + MONTVALE, N.J., April 8 - Federal Paperboard Co Inc said it +has entered into an agreement with Ozaki Trading Co Ltd of +Osaka, Japan, allowing Ozaki to represent Federal Paperboard's +bleached paperboard sales in Japan. + Federal added it will be opening an office in Japan in the +near future. + + Reuter + + + + 8-APR-1987 10:39:29.93 +acq +usa + + + + + +F +f1186reute +d f BC-NATIONAL-GUARDIAN-<NA 04-08 0099 + +NATIONAL GUARDIAN <NATG> MAKES ACQUISITIONS + GREENWICH, Conn., April 8 - National Guardian Corp said it +has acquired a number of security services companies recently, +with aggregate revenues of about 3,500,000 dlrs, for an +aggregate cost of about 2,700,000 dlrs. + It said it acquired guard service companies C.S.C. Security +Gaurd Service of Paramus, N.J., from Cartel Security +Consultants Inc, the Guard Services Division of Security +Services of America of Wayne, N.J., Capital Investigations and +Protective Agency of Hackensack, N.J., and Meyer Detective +Agency Inc of National Park, N.J. + The company said it bought alarm service operations +Certified Security Services Inc of Key West, Fla., Custom +Security Services of Myrtle Beach, S.C., A-T-E Security Group +Inc of Houston and the Louisville, Kent and Nashville, Tenn, +offices of Wells Fargo Alarm Services. + Reuter + + + + 8-APR-1987 10:40:25.85 +earn +usa + + + + + +F +f1194reute +s f BC-resending 04-08 0041 + +UNIVERSAL MEDICAL <UMBIZ> DISTRIBUTION SET + MILWAUKEE, WIS., April 8 - + Qtly distribution 7-1/2 cts vs 7-1/2 cts prior (excluding +2-1/2 cts special) + Pay April 30 + Record April 22 + NOTE: Full name is Universal Medical Buildings L.P. + Reuter + + + + 8-APR-1987 10:43:34.24 +graincorn +zambia + +imf + + + +G C +f1209reute +u f BC-ZAMBIA-DOES-NOT-PLAN 04-08 0097 + +ZAMBIA DOES NOT PLAN RETAIL MAIZE PRICE HIKE + LUSAKA, April 8 - The Zambian government has no immediate +plans to follow last week's increase in the producer price of +maize with a hike in the retail price of maize meal, an +official of the ruling party said. + Last December, a 120 pct increase in the consumer price for +refined maize meal, a Zambian staple, led to food riots in +which at least 15 people died. + That price increase, which President Kenneth Kaunda later +revoked, followed pressure by the International Monetary Fund +(IMF) to reduce the government's subsidy bill. + However, if the producer price rise, from 6.10 dlrs to 8.67 +dlrs per 90-kg bag, is not accompanied by a retail price +increase, the government will have to spend more on subsidies, +a practice discouraged by the IMF. + "There is no way out but to raise the subsidy levels of +meal. It (the government) would have to choose between the +demands of the IMF and those of the people," a Ministry of +Agriculture economist said. + Reuter + + + + 8-APR-1987 10:45:27.04 + +usa + + + + + +F +f1218reute +r f BC-BLOCKER-ENERGY-<BLK> 04-08 0065 + +BLOCKER ENERGY <BLK> SHARE OFFERING UNDERWAY + HOUSTON, April 8 - Blocker Energy corp said an offering of +20 mln common shares is underway at 2.625 dlrs per share +through underwriters led by <Drexel Burnham Lambert Inc> and +Alex. Brown and Sons Inc <ABSB>. + The company is offering 19.7 mln shares and shareholders +the rest. Before the offering it had about 33.6 mln shares +outstanding. + Reuter + + + + 8-APR-1987 10:45:36.01 + +usa + + + + + +F +f1219reute +r f BC-ASARCO-<AR>-COMPLETES 04-08 0082 + +ASARCO <AR> COMPLETES SHARE OFFERING + NEW YORK, April 8 - Asarco Inc said it completed the sale +of four mln shares of Asarco common stock to an underwriting +group led by First Boston Corp. + The underwriters sold the shares to the public at a price +of 22.50 dlrs a share, the minerals and energy company said. + Proceeds of about 86 mln dlrs will be used to reduce +outstanding debt, it said. + The offering included 3.5 mln shares announced April 1 and +500,000 to cover overallotments. + Reuter + + + + 8-APR-1987 10:45:44.23 + +usa + + + + + +F +f1220reute +r f BC-AMERICAN-MIDLAND-<AMC 04-08 0088 + +AMERICAN MIDLAND <AMCO> SETS OPERATOR FOR CASINO + ENGLEWOOD CLIFFS, N.J., April 8 - American Midland Corp +said <Braodway Casinos Inc> has entered into a letter of intent +for a new company to be formed by <Carnival Cruise Lines Inc> +and <Continental Hotel Cos> to operate Broadway's planned +hotel/casino in the Marina area of Atlantic City, N.J. + American Midland has agreed to spin off its 8.2 acre +Atlantic City property to Broadway, a new company in which +American Midland shareholders would initially own an 85 pct +interest. + Reuter + + + + 8-APR-1987 10:45:50.03 +acq +usa + + + + + +F +f1221reute +r f BC-WEDGESTONE-REALTY-<WD 04-08 0046 + +WEDGESTONE REALTY <WDG> ACQUISITION APPROVED + NEWTON, Mass., April 8 - Wedgestone Realty Investors Trust +said shareholkders have approved the acquisition of its +advisor, Wedgestone Advisory Corp, for 600,000 shares. + It said completion is expected to take place April 10. + Reuter + + + + 8-APR-1987 10:51:43.03 +heat +usa + + + + + +Y +f1239reute +u f BC-SUN-<SUN>-CUTS-HEATIN 04-08 0062 + +SUN <SUN> CUTS HEATING OIL BARGE PRICE + NEW YORK, April 8 - Sun Co's Sun Refining and Marketing Co +subsidiary said it is decreasing the price it charges contract +barge customers for heating oil in ny harbor by 0.50 cent a +gallon, effective today. + The 0.50 cent a gallon price reduction brings Sun's heating +oil contract barge price to 50 cts a gallon, the company said. + Reuter + + + + 8-APR-1987 10:52:38.11 + + + + + + + +A RM +f1241reute +f f BC-******MOODY'S-AFFIRMS 04-08 0012 + +******MOODY'S AFFIRMS AVCO FINANCIAL'S LONG-TERM DEBT, CUTS COMMERCIAL PAPER +Blah blah blah. + + + + + + 8-APR-1987 10:56:40.19 + +usa + + + + + +F +f1250reute +u f BC-MEDICAL-JOURNAL-REPOR 04-08 0106 + +MEDICAL JOURNAL REPORTS NEW INTERLEUKIN PROMISE + WASHINGTON, April 8 - Promising new findings in the use of +a controversial experimental drug called Interleukin-2 as a +cure for cancer will be published in the April 9 issue of the +prestigious New England Journal of Medicine, according to a +Wall Street analyst who has obtained an advance copy of the +magazine. + Among interleukin's principal U. S. makers are Cetus Corp +<CTUS>, headquartered in Emeryville, Calif., and Immunex Corp +<IMNX>, based in Seattle, Wash. + The journal, to be released late today, contains two +articles reporting high remission rates several cancer types. + The journal also contains a signed editorial concluding +that the new results mark a significant milestone in the search +for a successful immunotherapy for cancer. + Interleukin-2, also known as IL-2, is a substance naturally +produced by living cells in the laboratory. + The drug is controversial because it was widely praised as +a promising cancer treatment in early reports on its +effectiveness in late 1985, only to come under criticism a year +later for its failure to live up to its promise and due to its +ravaging side effects. + One of the new studies, conducted by Dr. William West of +Biotherapeutics Inc of Franklin, Tenn., is particularly +significant because it found far fewer harsh side effects after +it changed the way in which the drug is administered. + In that study, researchers administered IL-2 to 48 cancer +patients and found a 50-pct remission rate for kidney cancers +and a 50 pct remission rate for melanoma, a type of skin +cancer, according to Prudential-Bache Securities' Stuart +Weisbrod, who obtained the advance copy of the magazine. + For rectal and colon cancer, the researchers found no +remissions, but none of the 48 patients treated had side +effects serious enough to be placed under intensive hospital +care, according to the article. + In the second study, whose principal author is Dr. Steven +Rosenberg of the National Cancer Institute, researchers +administered IL-2 to 157 cancer patients and found a 33 pct +remission rate in cancers of the kidney, a 27 pct rate in +melanomas and a 15 pct rate in cancers of the colon and rectum. + In the National Cancer Institute trials, a total of four +patients died, the magazine reported, confirming the harshness +of the drug's side effects as originally administered. + "Perhaps we are at the end of the beginning of the search +for successful immunotherapy for cancer," said the editorial, +signed by John Durant of Philadelphia's Chase Cancer Center. + "These observations reported by Rosenberg and West surely +did not describe successful practical approaches ready for +widespread applications in the therapy of cancer patients," the +editorial said. + "On the other hand, if they reflect, as seems possible, a +successful manipulation of the cellular immune system, then we +may be near the end of our search for a meaningful direction in +the immunuotherapy of cancer," the editorial concluded. + Reuter + + + + 8-APR-1987 10:58:23.92 + +usa + + + + + +F +f1260reute +u f BC-report-recommends-dis 04-08 0096 + +REPORT SEEKS TO DISALLOW SOUTHERN <SO> COSTS + ATALANTA, April 8 - An audit submitted to the Georgia +Public Service Commission claims that between 944 mln dlrs and +1.8 billion dlrs of the costs of the Plant Vogtle nuclear power +station should be disallowed, a Southern Co spokeswoman said. + Southern's Georgia Power Co subsidiary has a 45.7 pct +interest in the plant and estimated earlier this year it would +cost a total of 8.87 billion dlrs. Last year, the plant's +owners pledged to Georgia regulators they would limit the cost +passed on to rate payers to 8.4 billion dlrs. + The Southern spokeswoman said the company feels the report +by O'Brien-Kreitzberg is "flawed and biased." She said the +report was released yesterday by the state attorney general. + Responding to the report today, Georgia Power Chairman +Robert W. Scherer told a news conference the conclusions drawn +by the firm "are not only wrong -- they also reflect the same +bias against nuclear power that these auditors have +demonstrated in similar cases accross the country." + Saying he was not suggesting Georgia power was without +fault, Scherer said "the audit identified several things I wish +we had done differently." + Scherer pointed out a report O'Brien-Kreitzberg submitted +to Georgia regulators in March 1986 projected Georgia Power +would not finish Plant Vogtle unit one before the end of 1987. + Noting "unit one is finished, and we expect it to be in +commercial operationg by June," he said the firm's latest +report ignored the earlier projection, gave the utility no +credit for the completion and "actually penalized us by +suggesting that costs to maintain t he schedule be disallowed." + Scherer said the latest audit alleges Georgia Power could +have saved 95 mln dlrs if it had stopped using four shifts, +seven days a week to speed construction three years sooner. + He said this would have delayed completion of the plant for +another year "and it would have cost several hunderd million +dlrs more." + Noting the audit said costs were increased 600 mln dlrs by +schedule delays totaling 20.5 months, he said "First, we have +the best concrete placement record in the industry, Second new +government regulations after the Three Mile Island incident +significantly increased construction time. + + Reuter + + + + 8-APR-1987 10:58:52.50 + +uk + + + + + +A +f1263reute +r f BC-FINAL-TERMS-SET-ON-AT 04-08 0067 + +FINAL TERMS SET ON ATARI CORP CONVERTIBLE EUROBOND + LONDON, April 8 - The coupon on the 75 mln dlr, 15-year, +convertible eurobond for Atari Corp has been set at 5-1/4 pct +compared with indicated range of five to 5-1/4 pct, lead +manager Paine Webber International said. + The conversion price was set at 32-5/8 dlrs, representing a +premium of 20.38 pct over yesterday's Atari share close of 27 +dlrs. + REUTER + + + + 8-APR-1987 11:00:51.15 +graincornsorghumsunseedwheatoilseedsoybean +argentina + + + + + +C G +f1271reute +r f BC-FURTHER-ARGENTINE-COA 04-08 0112 + +FURTHER ARGENTINE COARSE GRAIN LOSSES FEARED + By Manuel Villanueva + BUENOS AIRES, April 8 - Argentine grain producers adjusted +their yield estimates for the 1986/87 coarse grain crop +downward in the week to yesterday after the heavy rains at the +end of March and beginning of April, trade sources said. + They said sunflower, maize and sorghum production estimates +had been reduced despite some later warm, dry weather, which +has allowed a return to harvesting in some areas. + However, as showers fell intermittently after last weekend, +producers feared another spell of prolonged and intense rain +could cause more damage to crops already badly hit this season. + Rains in the middle of last week reached an average of 27 +millimetres in parts of Buenos Aires province, 83 mm in +Cordoba, 41 in Santa Fe, 50 in Entre Rios and Misiones, 95 in +Corrientes, eight in Chaco and 35 in Formosa. + There was no rainfall in the same period in La Pampa. + Producers feared continued damp conditions could produce +rotting and lead to still lower yield estimates for all the +crops, including soybean. + However, as the lands began drying later in the week +harvesting advanced considerably, reaching between 36 and 40 +pct of the area sown in the case of sunflower. + Deterioration of the sunflower crop evident in harvested +material in Cordoba, La Pampa and Buenos Aires forced yield +estimates per hectare to be adjusted down again. + The season's sunflowerseed production is now forecast at +2.1 mln to 2.3 mln tonnes, against 2.2 mln to 2.4 mln forecast +last week and down 43.9 to 48.8 pct on the 1985/86 record of +4.1 mln. + Area sown to sunflowers was two to 2.2 mln hectares, 29.9 +to 36.3 pct below the record 3.14 mln hectares last season. + Maize harvesting has also reached 36 to 40 pct of the area +sown. It is near completion in Cordoba and Santa Fe and will +begin in La Pampa and southern Buenos Aires later in April. + Production estimates for maize were down from last week at +9.5 mln to 9.8 mln tonnes, against 9.6 mln to 9.9 mln estimated +previously. + This is 22.2 to 23.4 pct below the 12.4 mln to 12.6 mln +tonnes estimated by private sources for the 1985/86 crop and +21.9 to 25.8 pct down on the official figure of 12.8 mln +tonnes. + Maize was sown on 3.58 mln to 3.78 mln hectares, two to +seven pct down on last season's 3.85 mln. + Sorghum was harvested on 23 to 25 pct of the area sown in +Cordoba, Santa Fe and Chaco. Harvest will start in La Pampa and +Buenos Aires in mid-April. + The total area sown was 1.23 mln to 1.30 mln hectares, 10.3 +to 15.2 pct down on the 1.45 mln sown last season. + The new forecast for the sorghum crop is 2.9 mln to 3.2 mln +tonnes compared with three mln to 3.3 mln forecast last week, +and is 23.8 to 29.3 pct down on last season's 4.1 mln to 4.2 +mln tonne crop. + The soybean crop for this season was not adjusted, +remaining at a record 7.5 mln to 7.7 mln tonnes, up 4.2 to 5.5 +pct on the 7.2 mln to 7.3 mln estimated by private sources for +1985/86 and 5.6 to 8.5 pct higher than the official figure of +7.1 mln. + The area sown to soybeans this season was a record 3.7 mln +to 3.8 mln hectares, 10.8 to 13.8 pct up on the record 3.34 mln +sown in 1985/86. + The soybean crop is showing excessive moisture in some +areas and producers fear they may discover more damage. Some +experimental harvesting was carried out in Santa Fe on areas +making up only about one pct of the total crop but details on +this were not available. + Preparation of the fields for the 1987/88 wheat crop, which +will be sown between May and August or September, has so far +not been as intense as in previous years. + Reuter + + + + 8-APR-1987 11:04:45.96 + + + + + + + +V RM +f1297reute +f f BC-******TOP-OFFICIALS-A 04-08 0012 + +******TOP OFFICIALS ARRIVE AT U.S. TREASURY TO BEGIN GROUP OF FIVE MEETING +Blah blah blah. + + + + + + 8-APR-1987 11:05:28.33 +jobs +netherlands + + + + + +RM +f1304reute +r f BC-DUTCH-ADJUSTED-UNEMPL 04-08 0082 + +DUTCH ADJUSTED UNEMPLOYMENT RISES IN MARCH + THE HAGUE, April 8 - Dutch seasonally adjusted unemployment +rose in the month to end-March to a total 693,000 from 690,600 +at end-February, but was well down from 730,100 at end-March +1986, Social Affairs Ministry figures show. + The figure for male jobless rose by 2,000 in the month to +436,500 compared with 470,700 a year earlier. The figure for +women was 256,500 at end-March against 256,100 a month earlier +and 259,400 at end-March 1986. + On an unadjusted basis total unemployment fell by 16,500 in +the month to end-March to 692,200. In March 1986 the figure was +725,000. + A ministry spokesman said the unadjusted figures showed a +smaller than usual seasonal decrease for the time of year, +because of particularly cold weather delaying work in the +building industry. He said this explained the increase in the +adjusted statistics. + Total vacancies available rose by 1,900 to 26,300 at +end-March. A year earlier the figure was 28,763. + REUTER + + + + 8-APR-1987 11:06:39.06 +earn +usa + + + + + +F +f1309reute +u f BC-HARTMARX-CORP-<HMX>-B 04-08 0021 + +HARTMARX CORP <HMX> BOOSTS DIVIDEND + CHICAGO, April 8 + Qtly div 25 cts vs 23 cts prior qtr + Pay 15 May + Record 1 May + + + + + + 8-APR-1987 11:11:12.33 + +usa + + + + + +A RM F +f1329reute +b f BC-MOODY'S-AFFIRMS-AVCO 04-08 0107 + +MOODY'S AFFIRMS AVCO UNIT'S LONG-TERM DEBT + NEW YORK, April 8 - Moody's Investors Service Inc said it +affirmed the long-term debt ratings but cut the commercial +paper to Prime-2 from Prime-1 of Avco Financial Services Inc, a +unit of Avco Corp. + Avco Financial has 2.5 billion dlrs of debt outstanding. + For the paper cut, Moody's cited a higher risk profile +inherent in the company's core business. Moody's said the +affirmation reflected its assessment of a less diversified risk +profile in the company's receivables. + Affirmed were Avco Financial's A-3 senior debt, Baa-2 +senior subordinated debt and Baa-3 junior subordinated debt. + Reuter + + + + 8-APR-1987 11:12:13.98 +money-fx +usa +stoltenbergpoehlballadurde-larosieremiyazawasumitaleigh-pembertongoriajames-baker + + + + +V RM +f1335reute +b f BC-TOP-OFFICIALS-ARRIVE 04-08 0108 + +TOP OFFICIALS ARRIVE AT TREASURY FOR G-5 TALKS + WASHINGTON, April 8 - Top officials of leading industrial +nations arrived at the U.S. Treasury main building to begin a +meeting of the Group of Five. + Officials seen arriving by Reuter correspondents included +West German Finance Minister Gerhard Stoltenberg and Bundesbank +President Karl Otto Poehl, French Finance Minister Edouard +Balladur and his central banker Jacques de Larosiere. + Also seen arriving were Japanese Finance Minister Kiichi +Miyazawa and Japan's central bank governor Satoshi Sumita and +British Chancellor of the Exchequer and central bank governor +Robin Leigh Pemberton. + There was no immediate sign of Italian or Canadian +officials. Monetary sources have said a fully blown meeting of +the Group of Seven is expected to begin around 3 p.m. local +time (1900 gmt) and last at least until 6 p.m. (2200 gmt), when +a communique is expected to be issued. + Italian sources said Italian acting Finance Minister +Giovanni Goria met Treasury Secretary James Baker last night. + At those talks Baker apparently convinced Goria, who +declined to attend the February meeting of the Group of Seven +in Paris, that Italy would participate fully in any meaningful +decisions. + Reuter + + + + 8-APR-1987 11:12:43.58 +interest +usa + + + + + +V RM +f1338reute +b f BC-/-FED-EXPECTED-TO-SET 04-08 0110 + +FED EXPECTED TO SET CUSTOMER REPURCHASES + NEW YORK, April 8 - The Federal Reserve is expected to +intervene in the government securities market to supply +temporary reserves indirectly via customer repurchase +agreements, economists said. + Economists expect the Fed to execute 2.0-2.5 billion dlrs +of customer repos to offset pressures from the end of the +two-week bank reserve maintenance period today. Some also look +for a permanent reserve injection to offset seasonal pressures +via an outright purchase of bills or coupons this afternoon. + The Federal funds rate opened at 6-3/8 pct and remained at +that level, up from yesterday's 6.17 pct average. + Reuter + + + + 8-APR-1987 11:15:23.93 + +usa + + + + + +F +f1352reute +r f BC-BEST-BUY-<BBUY>-MARCH 04-08 0063 + +BEST BUY <BBUY> MARCH SALES RISE + MINNEAPOLIS, April 8 - Best Buy Co Inc said its sales for +March rose to 26.1 mln dlrs from 11.9 mln dlrs in the +comparable 1986 period. + It said sales for the fiscal year ended March 31 rose to +329.5 mln dlrs from 113.1 mln dlrs a year earlier. + The company said sales performance was based on the +addition of 12 new retail facilities. + Reuter + + + + 8-APR-1987 11:15:28.57 + +usa + + + + + +F +f1353reute +r f BC-AUTOSPA-<LUBE>-TO-RED 04-08 0041 + +AUTOSPA <LUBE> TO REDEEM WARRANTS + NEW YORK, April 8 - AutoSpa corp said it will redeem all +its common stock purchase warrants on May Five at 7.5 cts each. + Through May Four, each warrant may be exercised into one +common share at 1.75 dlrs. + Reuter + + + + 8-APR-1987 11:15:35.75 +acq +usa + + + + + +F +f1354reute +r f BC-READER'S-DIGEST-ASSOC 04-08 0071 + +READER'S DIGEST ASSOCIATION SELLS UNIT + PLEASANTVILLE, N.Y., April 8 - <The Reader's Digest +Association Inc> said it sold its subsidiary, Source +Telecomputing Corp, to the venture capital firm of <Welsh, +Carson, Anderson and Stowe>. + The purchase price was not disclosed, Reader's Digest said. + It said it purchased an 80 pct stake in Source in 1980 and +earned an unspecified profit on 14 mln dlrs in revenues in +1986. + Reuter + + + + 8-APR-1987 11:15:38.86 +earn +usa + + + + + +F +f1355reute +r f BC-WEIS-MARKETS-INC-<WMK 04-08 0026 + +WEIS MARKETS INC <WMK> 1ST QTR MARCH 28 NET + SUNBURY, Pa., April 8 - + Shr 59 cts vs 51 cts + Net 18.0 mln vs 15.6 mln + Revs 278.6 mln vs 272.2 mln + Reuter + + + + 8-APR-1987 11:15:46.20 + +usa + + + + + +F +f1356reute +r f BC-AVNET-INC-<AVT>-FILES 04-08 0093 + +AVNET INC <AVT> FILES FOR DEBENTURE OFFERING + NEW YORK, April 8 - Anvet Inc said it filed with the +Securities and Exchange Commission a registration statement for +a proposed public offering of 150 mln dlrs of convertible +subordinated debentures due 2012. + Avnet said it will use the net proceeds for general working +capital purposes and the anticipated domestic and foreign +expansion of its distribution, assembly and manufacturing +businesses. + The company said an investment banking group managed by +Dillon Read and Co Inc will handle the offering. + Reuter + + + + 8-APR-1987 11:15:53.12 +earn +canada + + + + + +E F +f1357reute +r f BC-CONTINENTAL-BANK-INIT 04-08 0100 + +CONTINENTAL BANK INITIAL DISTRIBUTION APPROVED + TORONTO, April 8 - Continental Bank of Canada said +shareholders approved a capital reorganization to allow an +initial payout by the end of May to common shareholders from +last year's 200 mln Canadian dlr sale of most Continental +assets to <Lloyds Bank PLC>'s Lloyds Bank Canada. + The bank said the initial distribution would take the form +of a stock dividend of cumulative redeemable retractable class +A series two preferred shares entitling holders to monthly +floating rate dividends at 72 pct of prime and to 12.75 dlrs a +share on retraction. + Continental said the initial payout was subject to Canadian +government approval. + The bank reiterated that total distributions to common +shareholders would range from 16.50 dlrs a share to 17.25 dlrs +including the initial stock dividend and a final distribution +in late 1988 or early 1989. + The payout of existing preferred shareholders will be +completed just before next month's initial distribution to +common shareholders, Continental added. + + Reuter + + + + 8-APR-1987 11:15:58.96 +earn +usa + + + + + +F +f1358reute +r f BC-ATLAS-CONSOLIDATED-MI 04-08 0060 + +ATLAS CONSOLIDATED MINING AND DEVELOPMENT <ACMB> + NEW YORK, April 8 - 4th qtr + Shr loss 17 cts vs loss 22 cts + Net loss 14.5 mln vs loss 18.0 mln + Revs 27.3 mln vs 23.7 mln + Year + Shr 58 cts vs 1.01 dlrs + Net loss 48.3 mln vs loss 84.2 mln + Revs 111.7 mln vs 141.9 mln + NOTE: Atlas Consolidated Mining and Development Corp of +Manila. + Translated from Philippine pesos at 20.3489 pesos to dollar +vs 18.5571 in quarter and 20.2315 vs 18.2743 in year. + Reuter + + + + 8-APR-1987 11:16:31.73 + +usa + + + + + +F +f1362reute +r f BC-FORD-<F>-EXTENDS-INCE 04-08 0119 + +FORD <F> EXTENDS INCENTIVES ON LIGHT TRUCKS + DEARBORN, Mich., April 8 - Ford Motor Co said it extended +its buyer incentive program on light trucks to April 30 from +April 6, the program's previous expiration date. + Ford, which saw a 23 pct rise in its March truck sales over +the March 1986 level, said the incentives were extended to +"maintain its truck sales momentum." + The program itself was not changed. Customers have a choice +of 3.9 to 9.9 annual percentage rate financing or a cash rebate +of 300 dlrs or 600 dlrs, depending on the type of transmission +chosen. + Ford last week extended to April 30 from March 12 its +incentive program on its compact trucks and the Ford Taurus and +Mercury Sable cars. + Reuter + + + + 8-APR-1987 11:16:47.23 + +italy + +fao + + + +C G T +f1364reute +d f BC-FAO-REPORTS-BETTER-CR 04-08 0104 + +FAO REPORTS BETTER CROPS IN DEVELOPING COUNTRIES + ROME, April 8 - World output of staple foods maintained +growth in 1986, following a record harvest the year before, and +most of the increase was in developing countries, the director +general of the U.N.'s Food and Agriculture Organisation (FAO) +said. + Speaking to FAO's committee on world food security, Edouard +Saouma said sub-Saharan Africa registered a cereal production +increase of 3.6 pct in 1986 and the Far East also continued to +increase production. + Despite ample supplies worldwide, many countries face +problems in paying for all the food they need, he said. + Saouma said many of the developing world's food problems +were the result of "chaotic" world trade. + He said it was vital to promote employment to improve the +"food-security situation" of the poor, with policy reforms in +developing countries to remove existing disincentives to +production so that agriculture could play a greater role in +stimulating economic growth. + Reuter + + + + 8-APR-1987 11:16:54.96 + +usa + + + + + +F +f1365reute +r f BC-AVX-CORP-<AVX>-FILES 04-08 0061 + +AVX CORP <AVX> FILES FOR DEBENTURE OFFERING + GREAT NECK, N.Y., April 8 - AVX Corp said it has filed a +registration statement with the Securities and Exchange +Commission for a proposed public offering of 75 mln dlrs +prinicipal amount of convertible subordinated debentures. + AVX said a syndicate managed by Shearson Lehman Brothers +Inc will underwrite the offering. + Reuter + + + + 8-APR-1987 11:17:19.96 +acq +usa + + + + + +F +f1367reute +u f BC-SCI-MED-<SMLS>-BOARD 04-08 0100 + +SCI-MED <SMLS> BOARD AGREES TO BRISTOL<BMY>DEAL + MINNEAPOLIS, MINN., April 8 - Sci-Med Life Systems Inc said +its directors approved a previously proposed agreement of +merger with Bristol-Myers Co. + The proposed transaction is subject to completion of a due +diligence investigation, including a review by Bristol-Myers of +a patent infringement suit served on Sci-Med by Advanced +Cardiovascular Systems Inc on March 31, 1987. + Bristol-Myers has the right to call off the agreement under +certain circumstances, it said. + Sci-Med said it continues to believe the patent suit is +without merit. + Reuter + + + + 8-APR-1987 11:18:14.40 +acq +usa + + + + + +F +f1371reute +r f BC-FIDELCOR-<FICR>-COMPL 04-08 0059 + +FIDELCOR <FICR> COMPLETES SALE OF UNIT + PHILADELPHIA, April 8 - Fidelcor Inc said it has completed +the sale of its Industrial Valley Title Insurance Co subsidiary +to a group of investors including the unit's management for +undisclosed terms. + Industrial Valley has assets of about 37.6 mln dlrs and was +acquired last year along with IVB Financial Corp. + Reuter + + + + 8-APR-1987 11:18:20.11 +earn +usa + + + + + +F +f1372reute +d f BC-DATA-TRANSLATION-INC 04-08 0033 + +DATA TRANSLATION INC <DATX> 1ST QTR FEB 28 NET + MARLBORO, Mass., April 8 - + Shr 18 cts vs 13 cts + Net 575,000 vs 379,000 + Sales 6,625,000 vs 4,537,000 + Avg shrs 3,173,000 vs 2,977,000 + Reuter + + + + 8-APR-1987 11:18:37.67 +pet-chemcrudeacqearn +usa + + + + + +F Y +f1375reute +d f BC-petrochemical 04-08 0098 + +ENERGY/U.S. PETROCHEMICAL INDUSTRY + By JULIE VORMAN, Reuters + HOUSTON, April 8 - Cheap oil feedstocks, the weakened U.S. +dollar and a plant utilization rate approaching 90 pct will +propel the streamlined U.S. petrochemical industry to record +profits this year, with growth expected through at least 1990, +major company executives predicted. + This bullish outlook for chemical manufacturing and an +industrywide move to shed unrelated businesses has prompted GAF +Corp <GAF>, privately-held Cain Chemical Inc, and other firms +to aggressively seek acquisitions of petrochemical plants. + Oil companies such as Ashland Oil Inc <ASH>, the +Kentucky-based oil refiner and marketer, are also shopping for +money-making petrochemical businesses to buy. + "I see us poised at the threshold of a golden period," said +Paul Oreffice, chairman of giant Dow Chemical Co <DOW>, adding, +"There's no major plant capacity being added around the world +now. The whole game is bringing out new products and improving +the old ones." + Analysts say the chemical industry's biggest customers, +automobile manufacturers and home builders that use a lot of +paints and plastics, are expected to buy quantities this year. + U.S. petrochemical plants are currently operating at about +90 pct capacity, reflecting tighter supply that could hike +product prices by 30 to 40 pct this year, said John Dosher, +managing director of Pace Consultants Inc of Houston. Demand +for some products such as styrene could push profit margins up +by as much as 300 pct, he said. + Oreffice, speaking at a meeting of chemical engineers in +Houston, said Dow would easily top the 741 mln dlrs it earned +last year and predicted it would have the best year in its +history. + In 1985, when oil prices were still above 25 dlrs a barrel +and chemical exports were adversely affected by the strong U.S. +dollar, Dow had profits of 58 mln dlrs. "I believe the entire +chemical industry is headed for a record year or close to it," +Oreffice said. + GAF chairman Samuel Heyman estimated that the U.S. chemical +industry would report a 20 pct gain in profits during 1987. +Last year, the domestic industry earned a total of 13 billion +dlrs, a 54 pct leap from 1985. + The turn in the fortunes of the once-sickly chemical +industry has been brought about by a combination of luck and +planning, said Pace's John Dosher. + Dosher said last year's fall in oil prices made feedstocks +dramatically cheaper and at the same time the American dollar +was weakening against foreign currencies. That helped boost +U.S. chemical exports. + Also helping to bring supply and demand into balance has +been the gradual market absorption of the extra chemical +manufacturing capacity created by Middle Eastern oil producers +in the early 1980s. + Finally, virtually all major U.S. chemical manufacturers +have embarked on an extensive corporate restructuring program +to mothball inefficient plants, trim the payroll and eliminate +unrelated businesses. The restructuring touched off a flurry of +friendly and hostile takeover attempts. + GAF, which made an unsuccessful attempt in 1985 to acquire +Union Carbide Corp <UK>, recently offered three billion dlrs +for Borg Warner Corp <BOR>, a Chicago manufacturer of plastics +and chemicals. Another industry powerhouse, W.R. Grace <GRA> +has divested its retailing, restaurant and fertilizer +businesses to raise cash for chemical acquisitions. + But some experts worry that the chemical industry may be +headed for trouble if companies continue turning their back on +the manufacturing of staple petrochemical commodities, such as +ethylene, in favor of more profitable specialty chemicals that +are custom-designed for a small group of buyers. + "Companies like DuPont <DD> and Monsanto Co <MTC> spent the +past two or three years trying to get out of the commodity +chemical business in reaction to how badly the market had +deteriorated," Dosher said. "But I think they will eventually +kill the margins on the profitable chemicals in the niche +market." Some top chemical executives share the concern. + "The challenge for our industry is to keep from getting +carried away and repeating past mistakes," GAF's Heyman +cautioned. "The shift from commodity chemicals may be +ill-advised. Specialty businesses do not stay special long." + Houston-based Cain Chemical, created this month by the +Sterling investment banking group, believes it can generate 700 +mln dlrs in annual sales by bucking the industry trend. + Chairman Gordon Cain, who previously led a leveraged buyout +of Dupont's Conoco Inc's chemical business, has spent 1.1 +billion dlrs since January to buy seven petrochemical plants +along the Texas Gulf Coast. + The plants produce only basic commodity petrochemicals that +are the building blocks of specialty products. + "This kind of commodity chemical business will never be a +glamorous, high-margin business," Cain said, adding that demand +is expected to grow by about three pct annually. + Garo Armen, an analyst with Dean Witter Reynolds, said +chemical makers have also benefitted by increasing demand for +plastics as prices become more competitive with aluminum, wood +and steel products. Armen estimated the upturn in the chemical +business could last as long as four or five years, provided the +U.S. economy continues its modest rate of growth. + Reuter + + + + 8-APR-1987 11:20:27.61 + +usa + + + + + +F +f1387reute +d f BC-FEDERAL-PAPER-BOARD-< 04-08 0047 + +FEDERAL PAPER BOARD <FBO> IN MARKETING DEAL + MONTVALE, N.J., April 8 - Federal Paper Board Co Inc said +it has named Ozaki Trading Co Ltd of Osaka to represent it it +Japan on the sale of bleached paperboard. + Federal said it plans to open its own Japanese office in +the near future. + Reuter + + + + 8-APR-1987 11:21:05.09 +earn +usa + + + + + +F +f1390reute +d f BC-FIDATA-CORP-<FID>-4TH 04-08 0094 + +FIDATA CORP <FID> 4TH QTR LOSS + NEW YORK, April 8 - + Shr loss two cts vs profit 38 cts + Net loss 90,000 vs profit 1,685,000 + Revs 1,826,000 vs 29.3 mln + Year + Shr profit 3.37 dlrs vs profit 46 cts + Net profit 15.0 mln vs profit 2,047,000 + Revs 26.2 mln vs 123.6 mln + NOTE: Net includes pretax securities sale gain 10,000 dlrs +vs loss 1,000 dlrs in quarter and gain 486,000 dlrs vs loss +112,000 dlrs in year. + Net includes pretax gains on sale of businesses of nil vs +4,656,000 dlrs in quarter and 26.0 mln dlrs vs 4,656,000 dlrs +in year. + Net includes pretax losses on disposition of product line +of nil vs 3,150,000 dlrs in quarter and 3,300,000 dlrs vs +3,150,000 dlrs in year. + Quarter net includes tax credits of 102,000 dlrs vs 736,000 +dlrs. + Net includes reversal of tax loss carryforwards of 259,000 +dlrs vs 264,000 dlrs in quarter and tax loss carryforwards of +8,635,000 dlrs vs 579,000 dlrs in year. + Reuter + + + + 8-APR-1987 11:21:19.09 + +usa + + + + + +F +f1392reute +d f BC-CMS-<ACMS>-UNVEILS-FI 04-08 0111 + +CMS <ACMS> UNVEILS FIRST IBM SYSTEM/2 ADD ONS + TUSTIN, Calif., April 8 - CMS Enhancements Inc said it has +introduced the first add-on mass storage products for the new +International Business Machines Corp <IBM> IBM Personal +System/2 Model 30 personal computers. + CMS said the products are available immediately and include +hard disk drives, tape backup subsystems and a hard disk drive +on an expansion card. + It added it plans to introduce more products for higher- +end models of the IBM personal computers within the next two +months. + Prices for the new products range from 795 dlrs for a tape +backup subsystem, to 5,695 dlrs for a mass storage subsystem. + Reuter + + + + 8-APR-1987 11:21:24.56 +earn +usa + + + + + +F +f1393reute +d f BC-MARBLE-FINANCIAL-CORP 04-08 0042 + +MARBLE FINANCIAL CORP <MRBL> 1ST QTR NET + RUTLAND, Vt., April 8 - + Oper shr 26 cts vs not given + Oper net 866,000 vs 480,000 + NOTE: 1987 net excludes 157,000 dlr gain from termination +of pension plan. + Company went public in August 1986. + Reuter + + + + 8-APR-1987 11:22:35.93 + +usa + + + + + +F +f1402reute +d f BC-NANTUCKET-<NAN>-NAMES 04-08 0055 + +NANTUCKET <NAN> NAMES NEW HEAD FOR UNIT + NEW YORK, April 8 - Nantucket Industries Inc said James +Adams has been named president of its hosiery division, +replacing John Wineapple, and Terry Hampton has been named vice +president of manufacturing for the division, replacing Howard +Fromkin. + No reason was given for the changes. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-016.sgm b/src/test/data/reuters-21578/reut2-016.sgm new file mode 100644 index 00000000000..bff8315d89f --- /dev/null +++ b/src/test/data/reuters-21578/reut2-016.sgm @@ -0,0 +1,2030 @@ + + + 9-APR-1987 16:55:59.00 + + +james-baker + + + + +V RM +f2652reute +f f BC-******TREASURY'S-BAKE 04-09 0013 + +******TREASURY'S BAKER SAYS MACROECONOMIC INDICATORS NEED MORE PROMINENT ROLE +Blah blah blah. + + + + + + 9-APR-1987 16:56:03.23 +acq + + + + + + +F +f2653reute +b f BC-******HOSPITAL-CORP-O 04-09 0012 + +******HOSPITAL CORP SAYS IT RECEIVED 47 DLR A SHARE OFFER FROM INVESTOR GROUP +Blah blah blah. + + + + + + 9-APR-1987 16:56:14.45 +earn +usa + + + + + +F +f2654reute +s f BC-BEVERLY-ENTERPRISES-< 04-09 0026 + +BEVERLY ENTERPRISES <BEV> SETS REGULAR DIVIDEND + PASEDENA, Calif., April 9 - + Qtly div five cts vs five cts prior + Pay July 13 + Record June 30 + Reuter + + + + 9-APR-1987 16:59:15.05 +money-fx + +james-baker + + + + +V RM +f2662reute +f f BC-******TREASURY'S-BAKE 04-09 0013 + +******TREASURY'S BAKER SAYS FLOATING EXCHANGE RATE SYSTEM NEEDS GREATER STABILITY +Blah blah blah. + + + + + + 9-APR-1987 17:03:06.18 +crude +usa + + + + + +Y +f2669reute +r f BC-/CRUDE-OIL-NETBACKS-U 04-09 0110 + +CRUDE OIL NETBACKS UP SHARPLY IN EUROPE, U.S. + NEW YORK, April 9 - Crude oil netback values in complex +refineries rose sharply in Europe and firmed in the U.S. last +Friday from the previous week but fell sharply in Singapore, +according to calculations by Reuters Pipeline. + The firmer tone to refining margins in Europe and the U.S. +relected higher prices for petroleum products, particularly +gasoline, and support from crude oil prices. + Netback values for crude oil refined in Northern Europe +rose substantially following strong gains in gasoline prices +there. Brent is valued at 19.45 dlrs, up 56 cts a barrel or +three pct from the previous week. + In the U.S. Gulf, sweet crudes rose in value by 14 cts to +19.33 dlrs for West Texas Intermediate, up about 0.7 pct. + Sour grades in the U.S. Gulf showed an increase of 33 cts a +barrel for Alaska North Slope, up 1.7 pct. + But netbacks for crude oil refined in Singapore fell +sharply, down 15 cts to as much as 68 cts a barrel as ample +distillate supplies weighed on petroleum product prices. + Attaka in Singapore is valued at 18.55 dlrs, a decline of +68 cts a barrel or 3.5 pct from the previous week. + For refineries in the Mediterranean, netback values were +mostly lower, with declines of seven to 14 cts. The value of +Kuwait crude fell 14 cts to 18.37 dlrs, while Iranian Light +fell 11 cts to 19.14 dlrs. + On the U.S. West Coast, netback values for ANS CIF L.A. +also jumped sharply, up 40 cts a barrel or 2.2 pct to 18.82 +dlrs on higher gasoline prices. + Reuter + + + + 9-APR-1987 17:04:00.71 +money-fx +usa +james-baker +imf + + + +V RM +f2670reute +b f BC-TREASURY'S-BAKER-SAYS 04-09 0098 + +TREASURY'S BAKER SAYS SYSTEM NEEDS STABILITY + WASHINGTON, April 9 - Treasury Secretary James Baker said +the floating exchange rate system has not been as effective as +had been hoped in promoting stability and preventing imbalances +from emerging in the global economy. + In remarks before the afternoon session of the +International Monetary Fund's Interim Committee, Baker said he +was not suggesting that the system should be abandoned. + "But I do suggest," he said, "that we need something to give +it more stability and to keep it headed in the right direction +when the wind shifts." + He said that indicators can serve "as a kind of compass" but +added that structural indicators can help focus attention on +some policies. + Baker, however, said the IMF "needs to move beyond +macroeconomic indicators and find structural indicators that +can help focus attention on some of the policies of specific +relevance to the imbalances we face today." + The Treasury Secretary said that indicators should be given +a more prominent role in the annual economic reviews -- Article +IV consultations -- that the Fund performs. + Baker also told the policy making group that it was time +for the IMF to adopt earlier recommendations making IMF +surveillance more relevant to national policymakers and the +public. + "In particular, we urge increased publicity for IMF +appraisals developed in Article IV consultations, the use of +follow-up reports on country actions to implement IMF +recommendations, and greater use of special consultation +procedures," he said. + Baker emphasized that indicators were a device "for moving +beyond rhetoric to action." + He said they provide "more structure to the system, and +induce more discipline and peer pressure into the process of +policy coordination." + He said the Fund's procedures for surveillance need to be +reviewed and updated to reflect the use of indicators. + "This should be matter of priority for the executive board," +he said. + Baker also urged the Fund to develop alternative +medium-term economic scenarios for countries that "can help us +focus even more clearly on the most important imbalances, by +identifying options for addressing them and analyzing the +implications of these options." + He said also that further work should be done on finding +paths that lead toward possible medium-term objectives. + "If we are to take effective remedial action when there are +significant deviations from an intended course, then we must +have more definitive ways of indentifying the right course for +key variables," he said. + Reuter + + + + 9-APR-1987 17:07:18.35 +acqcrudenat-gas +usa + + + + + +F +f2677reute +r f BC-NERCI-<NER>-UNIT-CLOS 04-09 0083 + +NERCI <NER> UNIT CLOSES OIL/GAS ACQUISITION + PORTLAND, Ore., April 9 - Nerco Inc said its oil and gas +unit closed the acquisition of a 47 pct working interest in the +Broussard oil and gas field from <Davis Oil Co> for about 22.5 +mln dlrs in cash. + Nerco said it estimates the field's total proved developed +and undeveloped reserves at 24 billion cubic feet, or +equivalent, of natural gas, which more than doubles the +company's previous reserves. + The field is located in southern Louisiana. + Reuter + + + + 9-APR-1987 17:10:03.66 + +usauksouth-africanamibia + +un + + + +C M +f2679reute +d f AM-TERRITORY-COUNCIL-1ST LD'*'*'* 04-09 0131 + +U.S. AND BRITAIN VETO SANCTIONS AGAINST S.AFRICA + UNITED NATIONS, April 9 - For the second time in seven +weeks, the United States and Britain vetoed a Security Council +resolution to impose mandatory sanctions against South Africa. + Nine of the Council's 15 members voted for the draft, aimed +at forcing South Africa to implement an eight-year-old U.N. +independence plan for Namibia (South West Africa), a vast, +sparsely populated territory rich in minerals. + The U.S. and Britain were joined by West Germany in casting +negative votes. France, Italy and Japan abstained. + The resolution called for comprehensive mandatory sanctions +because Pretoria insists on making Namibian independence +conditional on the withdrawal of more than 30,000 Cuban troops +from neighbouring Angola. + Reuter + + + + 9-APR-1987 17:14:55.93 +money-fxgraincottonlivestockgoldsilver +usa + + + + + +F C G L M T +f2692reute +r f BC-media-summary 04-09 0127 + +U.S. DOLLAR LOSSES PROPEL BROAD COMMODITY GAINS + by Keith Leighty, Reuters + CHICAGO, April 9 - Commodities from gold to grains to +cotton posted solid gains in a flurry of buying today as losses +in the U.S. dollar and rising interest rates kindled fears of +inflation and economic instability. + Gains were most pronounced on the Commodity Exchange in New +York, where gold jumped 12.40 dlrs and closed at 436.50 dlrs a +troy ounce, and silver 22.5 cents to 6.86 dlrs a troy ounce. + A key factor behind the advance was anticipation that +inflation will be the only way for the major industrial nations +to halt the slide in the value of the U.S. dollar, said Steve +Chronowitz, director of commodity research with Smith Barney, +Harris Upham and Co., in New York. + The dollar tumbled one day after top finance officials from +the seven largest industrial nations reaffirmed their +commitment to support its value, and despite reports of +intervention by the U.S. Federal Reserve Bank, traders said. + Traders said it appears that the industrial nations, known +as the Group of Seven, lack the ability to change the long-term +direction of the currency markets. + "Maybe they have some ideas or plans," said Chronowitz. "If +they do, it's not evident." + "It looks like there's no cure but to let the free market +take values to where they should be. + "One way or another, we will force our major trading +partners to stimulate their economies," as a measure to correct +the mounting U.S. trade deficit, Chronowitz said. + "I think the markets believe, and have believed for a long +time, that the only recourse is to reflate at some point. It's +going to be a long and tedious process, but that's what's +happening," he said. + The falling value of the dollar makes U.S. commodities +cheaper for foreign buyers, stimulating demand. + At the same time, traders who are holding stocks and bonds +saw the value of their investments falling and many are turning +to commodities such as precious metals as a hedge, said Marty +McNeill, a metals analyst in New York with the trading house of +Dominick and Dominick. + The reaction in the metal markets reverberated throughout +the commodities markets, as grains, livestock, and cotton +posted broad gains. + Traders at the Chicago Board of Trade said attention in the +grain markets has shifted from concern about burdensome +supplies to the outlook that a lower dollar will stimulate +export demand. + After the close of trading, the Agriculture Department +raised its estimate for grain imports by the Soviet Union by +two mln tonnes from the month-earlier report. + Live hogs and frozen pork bellies posted sharp gains on the +Chicago Mercantile Exchange, while live cattle were moderately +higher. + Analysts said several factors boosted hog prices. They said +hogs haven't been making the weight gains that are normal at +this time of year, and farmers have been too busy with field +work to market animals. + Reuter + + + + 9-APR-1987 17:15:43.34 + +usa + + + + + +F +f2694reute +u f BC-GENERAL-MOTORS-<GM>-T 04-09 0052 + +GENERAL MOTORS <GM> TO IDLE 9,800 WORKERS + DETROIT, April 9 - General Motors Corp said it will +temporarily lay off 9,800 workers at two plants next week. + The layoffs will bring to 11,900 the number of General +Motors workers temporarily let go by the company. + Indefinite layoffs remain unchanged at 37,000. + General Motors said its Chevrolet-Pontiac-GM of Canada +plant at Okalhoma City, Okla., will be shut down April 13 +through April 20 for inventory adjustment. Some 5,500 workers +will be idled at the plant. + General Motors' Chevrolet-Pontiac-GM of Canada plant at +Doraville, Ga., will be closed for the same period for +inventory adjustment, with 4,300 workers affected. + The company's Lakewood, Ga., plant has been shut since +December, with 2,100 workers on temporary layoff. + General Motors said it will have one car plant and five +truck plants working on on overtime Saturday, April 11. + Reuter + + + + 9-APR-1987 17:16:11.81 + +usa + + + + + +F +f2695reute +d f BC-TENNEX-INDUSTRIES-TO 04-09 0076 + +TENNEX INDUSTRIES TO BUILD PLANT IN TENNESSEE + NASHVILLE, Tenn., April 9 - <Tennex Industries Inc>, a +Japanese owned supplier of air cleaners for the automotive +industry, said it will build a seven mln dlr plant in +Munfreesboro, Tenn. + The company said the 37,500-square-foot plant will +initially supply parts to <Nissan Motor Manufacturing Corp USA> +in nearby Smyna. + The company said it hopes to eventually produce parts for +other U.S. car makers. + Reuter + + + + 9-APR-1987 17:16:58.84 +graincorn +usaegypt + + + + + +C G +f2697reute +u f BC-EGYPT-SEEKING-500,000 04-09 0034 + +EGYPT SEEKING 500,000 TONNES CORN - U.S. TRADERS + KANSAS CITY, April 9 - Egypt is expected to tender April 22 +for 500,000 tonnes of corn for May through September shipments, +private export sources said. + Reuter + + + + 9-APR-1987 17:20:34.87 +earn +usa + + + + + +F +f2704reute +r f BC-TRUSTCORP-INC-<TTCO> 04-09 0048 + +TRUSTCORP INC <TTCO> 1ST QTR NET + TOLEDO, Ohio, April 9 - + Shr 67 cts vs 62 cts + Net 9,160,000 vs 7,722,000 + Assets 4.5 billion vs four billion + Note: Shr and net data are before accounting change +announced in 1986, which added 30 cts a share to year-ago 1st +qtr results. + Reuter + + + + 9-APR-1987 17:28:02.76 +grainship +usa + + + + + +G +f2720reute +r f BC-ny-grain-freights 04-09 0065 + +N.Y. GRAIN FREIGHTS - April 9 + Nidera took TBN 12,000 tonnes HSS Toledo to Casablanca +April 29-May 5 25.00 dlrs three days load 1,000 discharge + Comanav took Radnik 20,000 tonnes Lakehead to Morocco April +15-25 22.00 dlrs 5,000 load 3,000 discharge + Krohn took Akron 75,000 tonnes anygrains on 55 feet stowage +Mississippi River to Rotterdam May 1-10 8.05 dlrs 12 days all +purposes + Continental took Legionario 40,000 tonnes River Plate to +Japan April 25-May 10 22.50 dlrs 2,000 load 5,000 free +discharge + Garnac took Sokorri 30,000 tonnes U.S. Gulf to Constanza +April 15-25 17.00 dlrs load terms unknown 3,000 discharge + reuter + + + + + + 9-APR-1987 17:28:46.65 +earn +usa + + + + + +F +f2724reute +h f BC-NAPA-VALLEY-BANCORP-< 04-09 0019 + +NAPA VALLEY BANCORP <NVBC> 1ST QTR NET + NAPA, Calif, April 9 - + Shr 20 cts vs 25 cts + Net 487,000 vs 435,000 + Reuter + + + + 9-APR-1987 17:29:59.20 +earn +usa + + + + + +F +f2728reute +h f BC-INTERNATIONAL-POWER-M 04-09 0078 + +INTERNATIONAL POWER MACHINES <PWR> 4TH QTR LOSS + MESQUITE, Texas, April 9 - + Shr loss 21 cts vs loss 28 cts + Net loss 817,000 vs loss 1,058,000 + Revs 5,627,000 vs 7,397,000 + Year + Shr loss 75 cts vs loss 1.36 dlrs + Net loss 2,872,000 vs loss 5,200,000 + Revs 23.3 mln vs 21.1 mln + Note: 1985 net includes 1,255,000 adjustment in inventory +valuations and 486,000 in cost-reduction expenses. + Full name is International Power Machines Corp. + Reuter + + + + 9-APR-1987 17:33:46.96 + +usa + + +cboe + + +F RM +f2736reute +u f BC-CBOE-TO-LIST-NEW-S-AN 04-09 0112 + +CBOE TO LIST NEW S AND P OPTIONS <NSX> APRIL 20 + CHICAGO, April 9 - The Chicago Board Options Exchange, +CBOE, said it will list new Standard and Poor 500 stock index +options beginning April 20 that will trade side-by-side with +the existing S and P 500 options <SPX>. + The new S and P 500 option contract differs from the +existing contract in that settlement of the new contract will +be based on the opening value of the index on expiration +Friday. Settlement of the existing contract is based on the +closing value of the index on expiration Friday. + The new opening settlement S and P 500 options will be +offered only in months in which there are S and P 500 futures. + Initial months to be listed in the new options will be +June, September and December, the CBOE said. + Dissemination of the settlement of price of the new options +will be made through a special ticker symbol -- <SET>, the +exchange said. + There will initially be seven series of strike prices for +each contract month of the new options -- one strike price "at +the money," or near to the actual spot index value, and three +above and three below the spot index. + Position limits in any combination of both the new and +existing S and P 500 options will be 15,000 contracts. + The exchange said in the rare event that a stock does not +open on expiration Friday, the previous day's closing price of +that stock will be used to calculate the settlement value of +the index. + Reuter + + + + 9-APR-1987 17:35:06.68 + +usa + +ec + + + +F A RM +f2743reute +r f BC-EC-WARNS-AGAINST-PASS 04-09 0111 + +EC WARNS AGAINST PASSAGE OF TEXTILE BILL + WASHINGTON, April 9 - The European Community has told +Congress that if textile legislation injuring EC interests is +approved, there was no doubt the community would retaliate +against U.S. exports. + Roy Denmam, head of the EC delegation here, issued the +warning in a letter to Senator Lloyd Bentsen, chairman of the +Finance Committee. A copy of the letter was provided Reuters. + Denmam told Bentsen, a Texas Democrat, that if the textile +legislation passed on its own or was included in an omnibus +trade bill and injured EC interests, "there should be no doubt +that the EC will retaliate against the United States." + He added that "at a time when U.S. textile exports to the EC +are growing rapidly, one result of such retaliation would be a +substantial reduction of U.S. exports and jobs." + The textile legislation, backed strongly by the industry, +hard hit by imports, and by senators from textile-producing +states would impose new tough global quotas on textile imports +and for the first time include Europe in the quotas. + Reagan Administration officials have also opposed the +textile legislation, saying that if it passed it would likely +prompt a presidential veto. + Denman made his comments on the textile issue in a general +assessment of the Senate trade bill, titled S.490. + He said he was concerned about provisions in the Senate +bill that would limit, if not eliminate, the president's +discretion if retaliating against nations for keeping their +home markets closed to foreign goods. + U.S. Trade Representative Clayton Yeutter has also opposed +those provisions, arguing that presidential flexibility was +needed in order to be able to negotiate with countries to open +their markets, with retaliation being retained as a final, but +discretionary, weapon. + The pending overall trade legislation would force the +Administration to consult often with Congress and seek its +approval during step-by-step GATT negotiations. + He said "enactment of S. 490 would reduce the confidence of +other governments in America's commitment to multinational +trade." + Summing up the senate legislation, Denman said "a number of +provisions of that bil may achieve the opposite of what is +intended and lead to dangerous consequences for the world and +the U.S. economy." + Reuter + + + + 9-APR-1987 17:39:34.36 + +usa + + +cboe + + +C +f2752reute +u f BC-CBOE-TO-LIST-NEW-S-AN 04-09 0110 + +CBOE TO LIST NEW S AND P OPTIONS APRIL 20 + CHICAGO, April 9 - The Chicago Board Options Exchange, +CBOE, said it will list new Standard and Poor 500 stock index +options beginning April 20 that will trade side-by-side with +the existing S and P 500 options. + The new S and P 500 option contract differs from the +existing contract in that settlement of the new contract will +be based on the opening value of the index on expiration +Friday. Settlement of the existing contract is based on the +closing value of the index on expiration Friday. + The new opening settlement S and P 500 options will be +offered only in months in which there are S and P 500 futures. + Initial months to be listed in the new options will be +June, September and December, the CBOE said. + Dissemination of the settlement price of the new options +will be made through a special ticker symbol -- <SET>, the +exchange said. + There will initially be seven series of strike prices for +each contract month of the new options -- one strike price "at +the money," or near to the actual spot index value, and three +above and three below the spot index. + Position limits in any combination of both the new and +existing S and P 500 options will be 15,000 contracts. + The exchange said in the rare event that a stock does not +open on expiration Friday, the previous day's closing price of +that stock will be used to calculate the settlement value of +the index. + Reuter + + + + 9-APR-1987 17:39:43.66 + +usa + + + + + +F +f2753reute +u f BC-THREE-TRADERS-INDICTE 04-09 0111 + +THREE TRADERS INDICTED FOR INSIDER TRADING + NEW YORK, April 9 - A Grand Jury in Manhattan Federal Court +indicted three arbitrageurs, charging they swapped inside +information between their firms, Goldman Sachs and Co and +Kidder Peabody and Co, court documents showed. + Robert Freeman, head of risk arbitrage at Goldman +Sachs and Co, Richard Wigton, an employee of Kidder Peabody Co +Inc, and Timothy Tabor, also formerly with Kidder, were charged +with trading on inside information between June 1984 and +January 1986. They were arrested in February. + The indictments also alledged that Goldman Sachs and +Freeman made money on the insider trading scheme. + According to the indictment, Freeman exchanged inside +information with Martin Siegel, who at the time was a vice +president of Kidder Peabody. + Siegel pleaded guilty last February 13 to charges he +participated in the conspiracy. The indictment charged Siegel +passed on non-public information to both Wigton and Tabor from +Freeman. + Reuter + + + + 9-APR-1987 17:41:35.88 +acq +usa + + + + + +F +f2762reute +r f BC-GREAT-AMERICAN-MGMT<G 04-09 0102 + +GREAT AMERICAN MGMT<GAMI> HAS ATCOR<ATCO> STAKE + WASHINGTON, April 9 - Great American Management and +Investment Inc told the Securities and Exchange Commission it +acquired a 7.7 pct stake in Atcor Inc. + Great American said it bought the stake for investment. + It added that it has also considered--but not yet +decided--to buy additional Atcor shares, either in the open +market, in private transactions, through a tender offer or +otherwise. + Great American said it paid about 6.1 mln dlrs for its +462,400 Atcor shares. It said its most recent purchases +included 191,400 shares bought March 18-April 6. + Reuter + + + + 9-APR-1987 17:42:26.40 +earn +usa + + + + + +F +f2764reute +h f BC-RAI-RESEARCH-CORP-<RA 04-09 0072 + +RAI RESEARCH CORP <RAC> 3RD QTR FEB 28 NET + HAUPPAUGE, N.Y., April 9 - + Oper shr one ct vs 13 cts + Oper net 17,806 vs 312,692 + Revs 1,318,165 vs 2,239,349 + Nine mths + Oper shr 27 cts cs 28 cts + Oper net 640,156 vs 671,291 + Revs 5,612,818 vs 5,632,044 + Note: Oper excludes gain from discontinued operations of +15,598 for year-ago qtr and loss from discontinued operations +of 49,040 for year-ago nine mths. + Reuter + + + + 9-APR-1987 17:42:36.85 +earn +canada + + + + + +E F +f2765reute +r f BC-moore 04-09 0110 + +MOORE <MCL> SEES SUBSTANTIAL 1987 PROFIT GAIN + TORONTO, April 9 - Moore Corp Ltd expects 1987 profits from +continuing operations will exceed 1986 results and recover to +1985 levels when the company earned 152 mln U.S. dlrs or 1.70 +dlrs a share, president M. Keith Goodrich said. + "We'll have a substantial increase in earnings from +continuing operations," he told reporters after the annual +meeting. He said he expected profits would recover last year's +lost ground and reach 1985 results. + In 1986, profits from continuing operations slumped to +139.5 mln dlrs or 1.54 dlrs a share. The total excluded losses +of 30 mln dlrs on discontinued operations. + Goodrich said Moore is still actively looking for +acquisitions related to its core areas of business forms +manufacturing or handling. + "We could do a large acquisition," he said when asked if +the company could raise as much as one billion dlrs for this +purpose. + Chairman Judson Sinclair, answering a shareholder's +question, told the annual meeting that a special resolution +passed by shareholders to create a new class of preferred +shares would allow Moore to move quickly if it decided to +pursue an acquisition. + "If we were to make a major acquisition ... it means we can +move with a certain expediency," Sinclair said. + Asked if the resolution was designed to give Moore +protection from a possible hostile takeover, Sinclair said +only, "I know of no threat to the corporation at this time." + + Reuter + + + + 9-APR-1987 17:47:39.74 + +usa + + + + + +F +f2772reute +r f BC-ARVIN-<ARV>-RAISES-NU 04-09 0081 + +ARVIN <ARV> RAISES NUMBER OF AUTHORIZED SHARES + COLUMBUS, Ind., April 9 - Arvin Industries Inc said its +shareholders at the annual meeting voted to increase authorized +common shares to 50 mln from 30 mln. + The company told shareholders that the offering of 1.7 mln +common shares in January raised 50 mln dlrs, and the 500 shares +of variable rated preferred stock offered in February also +raised 50 mln dlrs. The company said it also placed 150 mln +dlrs in long-term debt in March. + Reuter + + + + 9-APR-1987 17:49:07.93 + +usa + + + + + +F +f2775reute +r f BC-RAYTHEON-<RTN>-WINS-U 04-09 0085 + +RAYTHEON <RTN> WINS U.S. NAVY CONTRACT + LEXINGTON, Mass., April 9 - Raytheon Co said the United +States Navy awarded it a 215.3 mln dlr contract to produce +1,927 AIM/RIM-7M Sparrow Missile Guidance and Control Sections +and associated hardware. + Under the contract, the company said it will provide +missiles and associated hardware to the U.S. Navy and Air Force +and to several U.S. allies. + Raytheon said the contract represents the major share of +the fiscal 1987 competitive Sparrow missile procurement. + Reuter + + + + 9-APR-1987 17:50:16.86 +acq +usa + + + + + +F +f2777reute +r f BC-FIRM-HAS-14.8-PCT-OF 04-09 0102 + +FIRM HAS 14.8 PCT OF DECISION/CAPITAL FUND<DCF> + WASHINGTON, April 9 - Gabelli Group Inc said it and two +subsidiaries held a total of 295,800 Decision/Capital Fund Inc +shares or 14.8 pct of the total outstanding. + It said the shares were held on behalf of investment +clients and it said it had no intention of seeking control of +the fund. + Gabelli said its most recent purchases of Decision/Capital +Fund stock included 95,800 shares bought April 3-6 on the +Philadelphia Stock Exchange. + Gabelli is an investment firm headquartered in New York +City. Its Gabelli and Co subsidiary is a brokerage firm. + Reuter + + + + 9-APR-1987 17:51:34.88 + +usa + + + + + +A RM +f2779reute +r f BC-CONSUMERS-POWER-<CMS> 04-09 0077 + +CONSUMERS POWER <CMS> TO REDEEM BONDS + JACKSON, Mich., April 9 - Consumers Power Co said it has 56 +mln dlrs available to be used to redeem at par any 15 pct +series first mortgage bonds that are not exchanged under an +outstanding bond exchange program. + The utility on March 17 offered to exchange its 15 pct +first mortgage bonds due March 1, 1994 for a new series of +first mortgage bonds, 9-1/4 pct due April 1, 1997. The offer +will expire April 14, 1987. + Reuter + + + + 9-APR-1987 17:52:21.04 + +usa + + + + + +F +f2782reute +u f BC-SEMICONDUCTOR-BOOK-TO 04-09 0110 + +SEMICONDUCTOR BOOK TO BILL RATIO AT 1.21 PCT + CUPERTINO, Calif., April 9 - The Semiconductor Industry +Association put the three-month average book-to-bill ratio at +1.21, which was above analysts' expectations and reflects the +sixth straight increase in this indicator of computer industry +activity. + Average booking in the three month period ended in March +totaled 910.8 mln dlrs, up 15.6 pct from a month ago and the +highest bookings since September, 1984. March billings, or +computer chip sales in the month, totaled 912.1 mln dlrs, up +34.6 pct from a month ago, the association said. The three +month average billings totaled 751.3 mln dlrs, up 6.5 pct. + March billings were the strongest recorded since November, +1984, the association said. The book to bill ratio, at 1.21, +was the highest since May, 1984, it noted. + Preliminary total solid state shipments for the first +quarter of 1987 totaled 2.25 billion dlrs, up 4.9 pct from last +quarter and up 15.9 pct from last year's first quarter. + Semiconductor Industry Association President Andrew +Procassini said the rise in the book to bill was due to a +substantial increase in U.S. bookings during March. + "We believe that the bookings increase reflects growing +confidence by electronic equipment manufacturers that some +end-equipment market segments have improved substantially +during the first quarter," Procassini said in a statement. + The association also revised its book-to-bill ratio +estimate for the three months ended in February to 1.12, from +1.13 earlier. It further revised the January book-to-bill +figure to 1.09 from 1.12 estimated earlier. + The three-month average book-to-bill ratio of 1.21 for +March means for every 100 dlrs worth of product shipped, +computer chip maker received 121 dlrs in new orders. + Drexel Burnham Lambert Inc analyst Michael Gumport said +association numbers indicate March orders were up 20 pct above +the normal seasonal level. + The association does not break out March orders from its +three-month average, which it put at 910.8 mln dlrs. + Gumport noted the three-month average bookings were well +above the 800-865 mln dlrs anticipated by the industry. + He said semiconductor stock could rise five to ten pct on +the stock market open tomorrow, due to the positive numbers. + "Skeptics are going to have to have some pretty strong +reasons not to like this group (of stocks)," Gumport said. + Kidder Peabody and Co analyst Michael Kubiak said the ratio +indicates March orders at about one billion dlrs, which would +be the highest monthly order rate since April, 1984. + He predicted at least a five pct rise in semiconductor +stocks on the open, and said the stock group could soar as high +as 15 pct during the session. + "One month does not a boom-time make, but this is very good +news," he said. + Kubiak attributed the stong semiconductor orders to +strength in the personal computer market, inventory restocking +and strong buying by distributors. + Purchasing managers had been keeping computer chip +inventories low, due to the overcapacity in the industry and +the slow growth of the economy in general, analysts noted. + The semiconductor industry has been in a slump for the past +three years. + The analysts said the March order and sales numbers are the +strongest evidence yet that the trend may be turning. + Nevertheless, they do not expect the Administration to +retreat from proposed sanctions against Japanese chip makers. + They added, however, if the industry continues to improve, +it could mean the sanctions will be short term. + Jack Beedle, President of In-Stat, an electronics industry +research firm, called the March numbers "excellent", but also +cautioned against excessive optimism. + "I still believe caution should be the word, rather than +euphoria," said Beedle, adding that he has yet to see strong +indications from the general economy or the computer industry +that support a solid, long-term recovery. + Beedle said while he thinks the semiconductor industry will +have a very good second quarter, he still thinks positive +shifts in exports and industrial production are needed to +sustain a recovery. + Reuter + + + + 9-APR-1987 17:54:38.77 +acq +usa + + + + + +F +f2786reute +u f BC-PARTNERSHIP-BUYS-IPCO 04-09 0097 + +PARTNERSHIP BUYS IPCO <IHS> STAKE OF 6.8 PCT + WASHINGTON, April 9 - MP Co, a New York investment +partnership, told the Securities and Exchange Commission it +bought a 6.8 pct stake in IPCO Corp common stock. + The partnership said it acquired 346,600 IPCO shares, +paying 4.9 mln dlrs, because it believed the securities to be +"an attractive investment opportunity." + It said it planned to regularly review its investment and +may in the future recommend business strategies or an +extraordinary corporate transaction such as a merger, +reorganization, liquidation or asset sale. + The partnership is controlled by Marcus Schloss and Co Inc, +a New York brokerage firm, and Prime Medical Products Inc, a +Greenwood, S.C., medical supplies firm. + Reuter + + + + 9-APR-1987 17:56:18.18 +earn +usa + + + + + +F +f2792reute +d f BC-DELMED-INC-<DMD>-YEAR 04-09 0081 + +DELMED INC <DMD> YEAR LOSS + FREEHOLD, N.J., April 9 - + Oper shr loss 30 cts vs loss 1.27 dlrs + Oper net loss 8,648,000 vs loss 25.6 mln + Revs 27.4 mln vs 33.3 mln + Avg shrs 29.1 mln vs 20.1 mln + Note: Oper excludes loss on provision for discontinued +operations of 971,000 vs 12.2 mln and loss from conversion of +debt 587,000 vs gain of 1,734,000. + 1985 oper excludes loss from pension plan liquidation of +631,000 and loss from discontinued operations of 1,015,000. + + Reuter + + + + 9-APR-1987 17:56:55.34 + +usa + + + + + +F +f2793reute +r f BC-MARCH-TRUCK-SALES-SAI 04-09 0058 + +MARCH TRUCK SALES SAID UP 16.4 PCT + DETROIT, April 9 - Retail sales of trucks in March rose +16.4 pct over the same month last year, said the Motor Vehicle +Manufacturers Association. + The trade group said dealers sold 377,617 trucks in March, +up from 324,327 last year. + Year-to-date truck sales were up 3.6 pct at 934,074 from +1986's 901,757. + Reuter + + + + 9-APR-1987 18:01:43.61 + +usa + + + + + +F +f2798reute +r f AM-ASPIRIN (EMBARGOED) 04-09 0097 + +DRUG INDUSTRY ATTACKED ON ASPIRIN ISSUE + CHICAGO, April 9 - Elements of the drug industry endangered +the lives of children by pressuring the government to delay a +now common warning on the link between aspirin and an often +fatal disease, a doctor said. + The warning involving Reye's Syndrome has since been +required on aspirin products under a Food and Drug +Administration (FDA) directive of one year ago, and now appears +on the labels of aspirin and aspirin-containing products. + The industry under government coaxing began voluntarily +printing warning labels in mid-1985. + + But in an editorial in this week's Journal of the +American Medical Association, Dr Edward Mortimer of Case +Western Reserve University in Cleveland said some aspirin +manufacturers misled physicians and acted irresponsibly in +opposing the warning for several years before then. + Mortimer's criticism was prompted by a new government study +published in the same issue of the Journal which said it had +found a "strong association" between aspirin and Reye's Syndrome. + Reye's Syndrome, which kills about 20 per cent of its +victims, strikes following chicken pox, influenza and other +illnesses. Symptoms include lethargy, belligerence and +excessive vomiting. Those who survive sometimes suffer brain +damage. + + Reuter + + + + 9-APR-1987 18:04:04.54 +acq + + + + + + +E F +f2802reute +b f BC-cadillac-fairview-say 04-09 0011 + +******CADILLAC FAIRVIEW SAYS IT HAS RECEIVED SOME ACQUISITION PROPOSALS +Blah blah blah. + + + + + + 9-APR-1987 18:04:24.13 + +usa + + + + + +F +f2803reute +r f BC-GM-<GM>-UNIT-GETS-BOE 04-09 0053 + +GM <GM> UNIT GETS BOEING <BA> CONTRACT + IRVINE, Calif., April 9 - General Motors Corp's Hughes +Aircraft Co said it received a contract worth more than 20 mln +dlrs from Boeing Co's Boeing Commercial Airplane Co. + Hughes will supply a cabin entertainment and service system +for Boeing's new 747-4000 jumbo jetliners. + Reuter + + + + 9-APR-1987 18:05:37.57 + +usa + + + + + +F +f2804reute +d f BC-AUDEC-IN-PRIVATE-PLAC 04-09 0057 + +AUDEC IN PRIVATE PLACEMENT OF STOCK, WARRANTS + SADDLEBROOK, N.J., April 9 - <Audec Corp> said it sold +privately 24 units, each consisting of 40,000 common shares and +40,000 redeemable common share purchase warrants, for a total +of 480,000 dlrs. + Audec said the sale was part of its plan to place a total +of 28 units at 20,000 dlrs each. + Reuter + + + + 9-APR-1987 18:09:50.90 + +usafrance + +worldbankimf + + + +RM A +f2808reute +u f BC-FRENCH-PROPOSE-NEW-WO 04-09 0109 + +FRENCH PROPOSE NEW WORLD BANK DEBT FACILITY + WASHINGTON, April 9 - The French government said it +proposed the creation of a new facility for development and for +debt reduction under the framework of the World Bank. + In a statement issued in conjunction with the meeting of +the International Monetary Fund's policy-making Interim +Committee, the French said the "multilateral resources thus +collected would permit a partial refinancing on highly +concessional terms of previously rescheduled official debts." + The statement said the "French government believes it is +necessary to take new steps to deal with the issue of the +poorest countries' debt." + The French statement said that Paris club reschedulings +should have a lengthening of the repayment period up to between +15 and 20 years instead of the current limit of 10 years. + And grace periods would be extended. + "These measures would be confined to the poorest, heavily +indebted countries and would be decided on a case-by-case +basis," it said. + The French also called for making the IMF's compensatory +financing facility for export shortfalls more concessional. + Reuter + + + + 9-APR-1987 18:10:34.32 +acq +canada + + + + + +E F +f2810reute +r f BC-cadillac-fairview-say 04-09 0066 + +CADILLAC FAIRVIEW SAYS IT RECEIVED TAKEOVER BIDS + Toronto, April 9 - <Cadillac Fairview Corp Ltd> said it +received proposals to acquire the company, following its +announcement last August that it had retained investment +dealers to solicit offers for all outstanding common shares. + Cadillac Fairview said the offers are subject to +clarification and negotiation and offered no further details. + Reuter + + + + 9-APR-1987 18:16:05.61 + +usa + + + + + +F +f2816reute +r f BC-ONE-CHRYSLER-<C>-PLAN 04-09 0083 + +ONE CHRYSLER <C> PLANT TO WORK OVERTIME + DETROIT, April 9 - Chrysler Corp said one of its U.S. car +and truck assembly plants will work overtime next week. + Six of its seven U.S. facilities will work during the week. +The plant on overtime, both during the week and on Saturday, +April 11, is the company's Sterling Heights, Mich., factory. + The company's U.S. plants and offices will be closed +Friday, April 17, and Monday, April 20, for the Good Friday and +Martin Luther King Jr. holidays. + Reuter + + + + 9-APR-1987 18:19:25.11 + +usa + +ec + + + +C G +f2817reute +d f BC-EC-WARNS-AGAINST-PASS 04-09 0131 + +EC WARNS AGAINST PASSAGE OF TEXTILE BILL + WASHINGTON, April 9 - The European Community (EC) will +retaliate against U.S. textile exports if Congress passes trade +legislation damaging European interests, an EC official warned +today. + Roy Denman, head of the EC delegation here, issued the +warning in a letter to Senator Lloyd Bentsen, chairman of the +Finance Committee. A copy was provided to Reuters. + The bill, backed by the textile industry and senators from +textile-producing states, would impose global quotas on textile +imports and for the first time include Europe. + Denman said he was concerned about provisions in the bill +that would limit, if not eliminate, the president's discretion +in retaliating against nations that keep their home markets +closed to foreign goods. + Reuter + + + + 9-APR-1987 18:20:35.91 +shipcrude +usa + + + + + +C +f2818reute +u f BC-ny-tankers 04-09 0084 + +N.Y. TANKERS - April 9 + Tennaco took Nicopolis part cargo 50,000 tons dirty April +12 Caribbean to U.S. Gulf worldscale 130 + Exxon took Brazil Glory 77,000 tons dirty April 17 East +Coast Mexico to U.S. Atlantic Coast worldscale 75 + Champlin took Tamba Maru part cargo 57,000 tons crude April +18 Caribbean to U.S. Gulf worldscale 105 + Pecten took World Cliff part cargo 74,500 tons dirty April +14 Sullom Voe to U.S. Atlantic Coast/U.S. Gulf worldscale 70 +for Atlantic Coast worldscale 67.5 for Gulf + Crown Petroleum took British Skill (Gotco relet) part cargo +100,000 tons dirty April 18 West Africa to U.S. Gulf worldscale +63 + Oroleum took Marika P. part cargo 59,000 tons dirty April +16 Caribbean to U.S. Atlantic Coast/U.S. Gulf rate not reported + Reuter + + + + + + 9-APR-1987 18:21:04.22 +acq +usa + + + + + +F +f2819reute +d f BC-WINTERHALTER-<WNTLC> 04-09 0044 + +WINTERHALTER <WNTLC> HOLDERS OKAY TAKEOVER + ANN ARBOR, Mich., April 9 - Winterhalter Inc said its +shareholders approved the 525,000 dlr acquisition of +Winterhalter by Interface Systems Inc <INTF>. + The acquisition would be for 15 cts per Winterhalter share. + Reuter + + + + 9-APR-1987 18:24:01.68 + +usa + + + + + +F +f2822reute +d f BC-LIBERTY-FINANCIAL-<LF 04-09 0078 + +LIBERTY FINANCIAL <LFG> PRESIDENT TO RESIGN + HORSHAM, Pa., April 9 - Harold H. Kline, 48, will resign on +May one as president of Liberty Financial Group Inc and its +Liberty Savings Bank unit to pursue other business +opportunties, the company said. + The company said Kline's post will be filled by Charles G. +Cheleden, chairman and chief executive officer. + Kline will continue to serve on the boards of Liberty +Financial and Liberty Savings, the company added. + Reuter + + + + 9-APR-1987 18:25:31.98 + +usa + + + + + +F +f2824reute +r f BC-IMMUNOMEDICS-<IMMU>-T 04-09 0105 + +IMMUNOMEDICS <IMMU> TO SELL COMMON STOCK + NEWARK, N.J., April 9 - Immunomedics Inc said it filed a +registration statement with the Securities and Exchange +Commission for the proposed sale of 2,500,000 shares of common +stock. + The company said it will sell 2,100,000 shares and that +certain stockholders will sell the remaining 400,000 shares. + Proceeds from the offering will be used for product +development, basic research, staff expansion, prepayment of +debt, capital expenditures and working capital, the company +said. The offering will be co-managed by E.F. Hutton and Co Inc +and First Boston Corp, Immunomedics said. + Reuter + + + + 9-APR-1987 18:29:26.90 + +usa + + + + + +F Y +f2826reute +u f BC-MOBIL-(MOB)-WILL-NOT 04-09 0095 + +MOBIL <MOB> WILL NOT INCREASE BUDGET + DALLAS, April 9 - Mobil Corp Chairman Allen E. Murray said +the company's exploration and production budget would not be +increased in the foreseeable future as it is "operating on the +assumption that (oil) prices will remain on the lower end of +the spectrum. + "Our budget is at about the same level as it was last year +and I think it is the right amount," said Murray who was in +town for ceremonies celebrating the consolidation of Mobil's +domestic exploration and production operations into a new, +locally-based subsidiary. + Last year, Mobil spent a total of 2.13 billion dlrs on +exploration and production, 341 mln dlrs in the United States +and 1.79 billion overseas. + Murray said the new subsidiary, Mobil Exploration and +Production U.S. Inc., was not created as "part of any cost +saving effort" but instead to "increase our efficiency and +ability to stay ahead of the pack." + The consolidation will, however, save Mobil about 15 mln +dlrs annually once relocation and reorganization costs have +been absorbed, according to A.F. Stancell, vice president of +U.S. producing operations for the company. + Mobil, the nation's second largest oil company, responded +to the collapse of oil prices last year -- from 30 dlrs a +barrel at end-1985 to as low as 10 dlrs in mid-1986 -- by +laying off 5,500 people and cutting its budget in midyear by 27 +percent, or 1.1 billion dlrs. + Of that amount, more than 900 mln dlrs was eliminated from +its exploration and spending spending plans. + But the company reported an increase in profits in 1986 +over 1985 and a jump in per share earnings to 3.45 dlrs a share +from 2.55 dlrs. + Reuter + + + + 9-APR-1987 18:31:32.77 +earn +canada + + + + + +E F +f2833reute +d f BC-<american-eagle-petro 04-09 0030 + +<AMERICAN EAGLE PETROLEUMS LTD> YEAR LOSS + Calgary, Alberta, April 9 - + Shr loss 10 cts vs profit 17 cts + Net loss 1,546,000 vs profit 4,078,000 + Revs 22.6 mln vs 38.9 mln + Reuter + + + + 9-APR-1987 18:33:20.67 + + +james-baker + + + + +V RM +f2836reute +f f BC-******TREASURY'S-BAKE 04-09 0011 + +******TREASURY'S BAKER SAYS DEBTOR NATIONS NEED TIMELY DISBURSEMENTS +Blah blah blah. + + + + + + 9-APR-1987 18:36:11.47 + +usa + + + + + +F +f2837reute +r f BC-GM'S<GM>-HUGHES-AIRCR 04-09 0091 + +GM'S<GM> HUGHES AIRCRAFT HAS BOEING<BA> CONTRACT + IRVINE, Calif, April 9 - General Motors' Hughes Aircraft Co +said it was awarded a contract worth more than 20 mln dlrs by +Boeing's Boeing Commercial Airplane Co to provide an advanced +cabin entertainment and service system for Boeing's new 747-400 +airliners. + Hughes said the new system uses advanced digital electronic +techniques and also adds cabin lighting control, cabin advisory +signs and seat information. + Hughes said the first 747-400 is scheduled to be completed +in early 1988. + + Reuter + + + + 9-APR-1987 18:36:43.22 + +usa +reagan + + + + +V +f2838reute +u f BC-REAGAN-HITS-HOUSE-PAS 04-09 0070 + +REAGAN HITS HOUSE-PASSED BUDGET + WEST LAFAYETTE, Ind, April 9 - President Reagan criticized +the House-passed budget by saying the Democratic budget plan +was just business as usual. + The budget cut defense by eight billion dlrs and called for +18 billion dlrs in new taxes. + He said the defense cut potentially theratened national +security and was asking the American taxpayers to pay for the +Democrats' excesses. + Reuter + + + + 9-APR-1987 18:36:56.22 + +usa + + + + + +RM A +f2839reute +r f BC-S/P-DOWNGRADES-ZENITH 04-09 0053 + +S/P DOWNGRADES ZENITH ELECTRONIC <ZE> + NEW YORK, April 9 - Standard and Poor's said it lowered its +rating on 190 mln dlrs of Zenith Electronic Corp debt because +of continued poor earnings results and increased debt leverage. + Among the rating changes, the company's senior debt was +lowered to BB-plus from BBB-plus. + Reuter + + + + 9-APR-1987 18:39:02.17 + +usa + + + + + +RM A +f2841reute +r f BC-MOODY'S-DOWNGRADES-RE 04-09 0102 + +MOODY'S DOWNGRADES REPUBLICBANK <RPT> + NEW YORK, April 9 - Moody's Investors Service said it +lowered the ratings on 464 mln dlrs of long-term debt issued by +RepublicBank Corp and its two principal subsidiaries but +upgraded 451 mln dlrs of securities of Interfirst Corp <IFC>. + The rating adjustments are based on the likelihood that the +proposed merger of the two Texas banks will be consummated. +Moody's said Interfirst is considerably the weaker of the two +institutions. + Among the rating changes, RepublicBank's senior debt was +downgraded to BA-1 from BAA-1 while Interfirst's was raised to +BA-1 from B-1. + Reuter + + + + 9-APR-1987 18:39:51.11 + +usa +james-baker +imf + + + +V RM +f2842reute +b f BC-TREASURY'S-BAKER-CALL 04-09 0092 + +TREASURY'S BAKER CALLS FOR MORE BANK FLEXIBILITY + WASHINGTON, April 9 - Treasury Secretary James Baker said +that commercial banks need to develop more flexibility in their +concerted lending mechanisms "to help assure continued +participation in new money packages." + He said that major debtor nations need to be able to count +on receiving timely disbursements on new loans essential to +support well-conceived economic programs. + His remarks were made to the afternoon session of the +International Monetary Fund's policy making Interim Committee. + Baker said, "The sense of urgency and willingness to +cooperate in support of a larger general interest that helped +to carry us through the difficult crisis period of 1982 and +1983 is now less evident." + He said to address this problem, it is important for the +commercial banks to "develop a menu of alternative new money +options from which all banks with debt exposure can choose in +providing continuing support for debtor reforms." + He said the "continued implementation of the debt strategy +may well rest on their doing so." + Baker also said that growth prospects for the lowest income +countries remain an issue of "critical concern to the United +States." + He said that he intended to address the problem of poor +country prospects in greater detail at tomorrow's meeting of +the joint IMF-World Bank Devlopment Committee. + Baker said, however, that ministers should guard against +what appear to be magical solutions to the complex debt +problem. + "I want to stress the need for all to guard against the +ephemeral attraction of magical solutions, which may appear as +tantalizing alternatives to the rigorous realities of grappling +with our debt problems," he said. + But he emphasized that the only lasting progress is to +approach each situation on a case-by-case basis, "bringing to +bear the policies and financing needed to bring the economy +back to sustained economic growth." + Reuter + + + + 9-APR-1987 18:41:59.03 +trade +chile + + + + + +RM A +f2844reute +u f BC-chilean-trade-surplus 04-09 0107 + +CHILEAN TRADE SURPLUS NARROWS SLIGHTLY IN FEBRUARY + Santiago, april 9 - chile's trade surplus narrowed to 102.2 +mln dlrs in february, from 105.4 mln dlrs in the same month +last year, but it was above the 18.2-mln-dlr surplus recorded +in january 1987, the central bank said. + Exports in february totalled 379.4 mln dlrs, 17.2 pct above +the january figure. Imports fell 9.2 pct from the previous +month to 277.2 mln dlrs. The figures for the same month last +year were 314 mln and 208.6 mln dlrs, respectively. + The accumulated trade surplus over the first two months of +1987 stands at 120.4 mln dlrs against 132.8 mln dlrs the +previous year. + Reuter + + + + 9-APR-1987 18:42:19.11 +interestmoney-fxdlr +usa + + + + + +RM A +f2845reute +u f BC-ANALYSTS-DOUBT-FED-FI 04-09 0112 + +ANALYSTS DOUBT FED FIRMED DESPITE BORROWING RISE + By Martin Cherrin, Reuters + NEW YORK, April 9 - Economists said that they doubt the +Federal Reserve is firming policy to aid the dollar, despite +higher discount window borrowings in the latest two-week +statement period and very heavy borrowings Wednesday. + Data out today show net borrowings from the Fed averaged +393 mln dlrs in the two weeks to Wednesday, up from 265 mln +dlrs in the prior statement period. Wednesday borrowings were +1.4 billion dlrs as Federal funds averaged a high 6.45 pct. + "One could make a case that the Fed is firming, but it +probably isn't," said William Sullivan of Dean Witter Reynolds. + Sullivan said some may assume the Fed has firmed policy +modestly to support the dollar because net borrowings in the +two-weeks to Wednesday were nearly 400 mln dlrs after averaging +around 250 mln dlrs over the previous two months. + However, the Dean Witter economist noted that the latest +two-week period included a quarter end when seasonal demand +often pushes up borrrowings. + "Some might argue that the Fed was firming policy, but it +looks like it tried to play catchup with reserve provisions +late in the statement period and didn't quite make it," said +Ward McCarthy of Merrill Lynch Capital Markets. + A Fed spokesman told a press press conference today that +the Fed had no large net one-day miss of two billion dlrs or +more in its reserve projections in the week ended Wednesday. + Still, McCarthy said it may have had a cumulative miss in +its estimates over the week that caused it to add fewer +reserves earlier in the week than were actually needed. + The Fed took no market reserve management action last +Thursday and Friday, the first two days of the week. It added +temporary reserves indirectly on Monday via two billion dlrs of +customer repurchase agreements and then supplied reserves +directly via System repurchases on Tuesday and Wednesday. + Based on Fed data out today, economists calculated that the +two-day System repurchase agreements the Fed arrranged on +Tuesday totaled around 5.9 billion dlrs. They put Wednesday's +overnight System repos at approximately 3.4 billion dlrs. + "It is quite clear that the Fed is not firming policy at +this time," said Larry Leuzzi of S.G. Warburg and Co Inc. + Citing the view shared by the other two economists, Leuzzi +said the Fed cannot really afford to seriously lift interest +rates to help the dollar because that would harm already weak +economies in the United States and abroad and add to the +financial stress of developing countries and their lenders. + "Those who believe the Fed tightened policy in the latest +statement period have to explain why it acted before the dollar +tumbled," said McCarthy of Merrill Lynch. + He said the dollar staged a precipitous drop as a new +statement period began today on disappointment yesterday's +Washington meetings of international monetary officials failed +to produce anything that would offer substantive dollar aid. + In fact, currency dealers said there was nothing in +Wednesday's G-7 communique to alter the prevailing view that +the yen needs to rise further to redress the huge trade +imbalance between the United States and Japan. + The economists generally agreed that the Fed is aiming for +steady policy now that should correspond to a weekly average +Fed funds rate between six and 6-1/8 pct. This is about where +the rate has been since early November. + "I'm not so sure that the Fed is engineering a tighter +policy to help the dollar, as some suspect," said Sullivan of +Dean Witter. + If it is, however, he said that Fed probably has just +nudged up its funds rate goal to around 6.25 to 6.35 pct from +six to 6.10 pct previously. + Reuter + + + + 9-APR-1987 18:45:25.86 + +usapakistan + +worldbank + + + +RM +f2848reute +r f BC-PAKISTAN-GETS-70-MLN 04-09 0105 + +PAKISTAN GETS 70 MLN DLR WORLD BANK LOAN + WASHINGTON, April 9 - The World Bank said it approved a 70-mln-dlr, 20-year loan to assist Pakistan in a project designed +to improve power plant efficiency. + Noting that a shortage of power constrains Pakistan's +economic development, the Bank said one objective of the +project is to provide at least 200 megawatts of additional +generating capacity. + Another objective is to improve the efficiency with which +hydrocarbons are used by Pakistan's Water and Power Development +Authority (WAPDA) in power production, it said. One effect of +this would be reduced atmospheric pollution. + Reuter + + + + 9-APR-1987 18:47:26.32 +earn +usa + + + + + +F +f2853reute +h f BC-VALEX-PETROLEUM-INC-< 04-09 0042 + +VALEX PETROLEUM INC <VALP> YEAR DEC 31 + DENVER, Colo, April 9 - + Shr loss six cts vs loss 84 cts + Net loss 219,632 vs loss 16.3 mln + Revs 1.4 mln vs 2.8 mln + NOTE:1985 net includes 15.5 mln dlrs of writedowns and tax +benefit of 51,294. + + Reuter + + + + 9-APR-1987 18:50:11.20 + +usa + + + + + +F +f2855reute +h f BC-VALEX-PETROLEUM-<VALP 04-09 0052 + +VALEX PETROLEUM <VALP> RECLASSIFIES DEBT + DENVER, Colo, April 9 - Valex Petroleum Inc said its 1.3 +mln dlrs in long-term debt with a commercial bank was +reclassified as a current liability, which resulted in its +auditors giving it a qualified opinion. + Earlier, Valex reported a net loss 219,632 for 1986. + Reuter + + + + 9-APR-1987 18:52:32.99 + +usa + + + + + +F +f2856reute +h f BC-DATA-ARCHITECTS-<DRCH 04-09 0052 + +DATA ARCHITECTS <DRCH> TO MAKE OFFERING + WALTHAM, Mass, April 9 - Data Architects inc said it +intends to make a public offering of 850,000 shares of its +common stock, of which 672,000 shares will be sold by the +company and 178,000 by certain shareholders. + Proceeds will be used for general corporate purposes. + Reuter + + + + 9-APR-1987 18:58:51.24 + +usa + + + + + +F +f2860reute +h f BC-FIVE-DIRECTORS-OF-TER 04-09 0051 + +FIVE DIRECTORS OF TERRAPET ENERGY RESIGN + DALLAS, April 9 - <Terrapet Energy Corp> said five +directors resigned because they could not obtain directors and +officers liability insurance. + It said the directors are Dean R. Fellows, Frederick B. +Hegi Jr, W.D. Masterson, Thomas Sturgess and John C. Thomas. + Reuter + + + + 9-APR-1987 19:03:16.01 + +usa + + + + + +F +f2863reute +u f BC-GOLDMAN,-SACHS-COMMEN 04-09 0109 + +GOLDMAN, SACHS COMMENTS ON FREEMAN INDICTMENT + NEW YORK, April 9 - Goldman, Sachs and Co, responding to +the indictment earlier today of Robert M. Freeman, who remains +head of its risk arbitrage unit, said it believes the +44-year-old executive did not violate insider trading laws. + "Based on all we now know, we continue to believe in him +and to believe that he did not act illegally," the company said +in a statement. + Freeman was indicated by a federal grand jury along with +two other top Wall Street executives, Richard Wigton and +Timothy Tabor, for allegedly swapping insider information in a +scheme that produced millions in illegal profits. + The company said it based in belief in Freeman's innocence +on an investigation conducted by its independent outside +counsel after Freeman was arrested in February. + Reuter + + + + 9-APR-1987 19:05:53.65 + +usamauritius + +worldbank + + + +A RM +f2867reute +r f BC-MAURITIUS-GETS-25-MLN 04-09 0091 + +MAURITIUS GETS 25 MLN DLR WORLD BANK LOAN + WASHINGTON, April 9 - The World Bank said it approved a 25 +mln dlr structural adjustment loan for Mauritius to aid that +country's industrial sector. + The Bank said the 17-year loan will support policy reforms +designed to help increase the efficiency of the country's +manufacturing sector, develop export enterprises and encourage +efficient use of resources. + It added, "The increased availability of foreign exchange +for imports is expected to help the expansion of industrial +output and exports." + Reuter + + + + 9-APR-1987 19:24:29.96 + +canada + + +tose + + +E +f2871reute +r f BC-power 04-09 0119 + +TORONTO FINANCIAL DISTRICT HIT BY POWER OUTAGE + TORONTO, April 9 - Toronto's financial district, the +business heart of Canada, slowed to a near halt this afternoon +after being struck by a power blackout, utility and business +officials said. + The blackout occurred around 1515 EDT in about an +eight-square-block section of the city's downtown core, home to +most of the city's skyscrapers, containing the headquarters of +many of Canada's major corporations and financial institutions. + Ontario Hydro spokeswoman Christina Warren told Reuters the +blackout occurred when a transformer cable went down during +routine maintenance at a downtown hydroelectricity station. +Power was restored after 10 minutes. + The power loss halted floor trading for 15 minutes on the +Toronto Stock Exchange, Canada's largest equity market, +although computerized trading - accounting for about 20 per +cent of the Exchange's normal volume - continued, Toronto Stock +Exchange official John Kolosky said. + Bank operations were also affected. The headquarters or +major offices of Canada's six major banks line a small section +of Bay Street, the Wall Street of Canada. + Bank of Montreal spokesman Brian Smith told Reuters the +blackout shut down electronic banking machines and caused a +minor slowdown in money trading operations, although "all in all +we were not seriously affected." + Officials at various downtown skyscrapers said the blackout +also briefly shut down elevators and disrupted business in the +downtown core's extensive network of underground shopping +malls. + Workers at some of the buildings said several people were +briefly trapped on elevators, but police and firefighters +reported no serious problems. + Reuter + + + + 9-APR-1987 19:36:34.99 + +usa + + + + + +A RM +f2876reute +r f BC-U.S.-THRIFT-OFFICIAL 04-09 0119 + +U.S. THRIFT OFFICIAL URGES MORE LENDER INSURANCE + NEW YORK, April 9 - The Administration's 15 billion dlr +plan to recapitalize the Federal Savings and Loan Insurance +Corporation is needed to ensure the future profitablity of the +U.S. thrift industry, according to a top industry regulator. + "Today thrifts in overwhelming numbers are profitable," +Shannon Fairbanks, executive chief of staff of the Federal Home +Loan Bank Board told a thrift industry conference. + "But every thrift is paying a market tax for the inabliity +of regulators to deal with problems carried forward from the +past," she said, referring to the premium that thrifts have to +pay in the marketplace to entice deposits away from banks. + "The industry wants to see a five billion dlr plan passed +now, and then to wait and see what happens," Fairbanks said. +"They're saying, 'we don't want to pay more right away.' The +argument is that it's a drain on the industry." + "But the dollars paid out can be recaptured in the +reduction in the market tax differential," she said. "The cost +of recapitalization to the industry would be recaptured in +bottom line profitability." + Fairbanks said that the public's confidence in thrift +instititutions eroded with the financial difficulties of +savings and loan associations in Ohio and Maryland in 1985. + As thrift institutions in economically distressed areas +like Texas have continued to fall on hard times, this has +increased depositors' demand for a higher premium on deposits +in savings and loans compared with premiums paid on deposits in +commercial banks, she said. + Before 1983, thrift institutions paid a 25 basis point +yield differential on savings deposits over that offered by +commercial banks as mandated by U.S. financial regulations. + With the elimination in 1983 of regulations that had drawn +strict lines between savings and loans and commercial banks, +the gap widened to as much as 50 to 75 basis points as wary +depositors demanded a higher premium to place their funds in +thrift institutions, Fairbanks said. + "The market tax paid by today's thrift industry is the most +significant impediment to future profits," she said. + Depositor confidence is also eroded by the existence of +thrifts that are failing but manage to stay in business by +paying deposit rates well above prevailing market rates. + Presently, the FHLBB cannot afford to close failing +institiutions "because we can't afford it with the current +FSLIC fund," she said. + Fairbanks estimated that the high market tax differential +paid by thrifts will drop by at least 10 to 20 basis points +with an adequate recapitalization of FSLIC because it will help +restore this lost confidence. + Reuter + + + + diff --git a/src/test/data/reuters-21578/reut2-017.sgm b/src/test/data/reuters-21578/reut2-017.sgm new file mode 100644 index 00000000000..a14fb397e3e --- /dev/null +++ b/src/test/data/reuters-21578/reut2-017.sgm @@ -0,0 +1,2014 @@ + + +21-APR-1987 11:35:01.50 +coffee +ukbrazil +dauster + + + + +C T +f1400reute +b f BC-IBC-COFFEE-AUCTIONS-T 04-21 0115 + +IBC COFFEE AUCTIONS TO START SOON - DAUSTER + LONDON, April 21 - The Brazilian Coffee Institute, IBC, +plans to sell in a series of auctions over the next few weeks +robusta coffee purchased in London last year, but details of +where and when auctions will take place are still to be +finalised, IBC president Jorio Dauster told reporters. + The sales of 630,000 bags of robusta and an unspecified +amount of Brazilian arabica coffee will take place over a +minimum of six months but it is not decided where sales will +take place or whether they will be held weekly or monthly. + The amount offered at each sale has also not been set, but +could be in the order of 100,000 bags, Dauster said. + Reuter + + + +21-APR-1987 11:37:33.52 + +canada + + + + + +E +f1416reute +u f BC-AMCA-(AIL)-NAMES-NEW 04-21 0054 + +AMCA (AIL) NAMES NEW CHAIRMAN + TORONTO, April 21 - AMCA International Ltd said it +appointed president and chief executive officer WIlliam Holland +to succeed Kenneth Barclay as chairman. + Barclay, who is 60 years old, decided not to stand for +reappointment as chairman this year but will continue as a +director, AMCA said. + Reuter + + + +21-APR-1987 11:38:04.12 +crude +usa + + + + + +Y +f1418reute +u f BC-API-OIL-INVENTORY-REP 04-21 0081 + +API OIL INVENTORY REPORT TO BE ISSUED TONIGHT + NEW YORK, APRIL 21 - The American Petroleum Institute, API, +said its weekly U.S. petroleum inventory report will be issued +tonight, despite many company closures on Friday of last week +for the Easter holiday. + The API report is usually released around 1700 EDT on +Tuesday nights. + The Energy Information Administration said it also expects +its weekly oil statistic report to be released as usual, on +Wednesday night at about 1700 EDT. + Reuter + + + +21-APR-1987 11:44:00.53 +acq +usa + + + + + +F +f1442reute +u f BC-FAIRCHILD 04-21 0095 + +SORO GROUP TO LIMIT FAIRCHILD <FEN> STOCK BUYS + WASHINGTON, April 21 - Quantum Fund N.V., a Netherlands +Antilles mutual fund for which New York investor George Soros +is investment adviser, said it has agreed to limit further +purchases of Fairchild Industries Inc stock. + In a filing with the Securities and Exchange Commission, +Quantum, which already holds 1,647,481 Fairchild common shares, +or 11.5 pct of the total outstanding, said it agreed to the +restriction after Fairchild said its security clearance might +be jeopardized if Quantum acquires a major stake in it. + But Quantum said Fairchild management was told that Soros, +acting either individually or through entities other than +Quantum that he controls, may decide to buy common stock in the +company on his own behalf. + Quantum had recently notified the Federal Trade Commission +under the Hart-Scott-Rodino Antitrust Improvements Act of 1976 +that it might buy up to 49.9 pct of Fairchild's voting stock. +Unless the FTC had objected, Quantum would have been free, but +not obligated, to buy up to 49.9 pct of Fairchild stock. + Fairchild management, however, warned that if Quantum, a +foreign entity, raises its stake in the company to 49.9 pct, it +could "impair" the government security clearances Fairchild +needs to carry out its its defense contract work. + In response, Quantum said it told Fairchild it will not +make "significant additional purchases" of its common or +preferred stock without giving Fairchild enough prior notice to +enable it to consult with Quantum over the impact of action. + Quantum also said it has withdrawn its notification request +to the FTC and the antitrust division of the Justice Department +of its intent to buy up to 49.9 pct of Fairchild. + Quantum also said it told the FTC and the Justice +Department that it does not expect to resubmit any further +notifications of intent to significantly raise its stake in +Fairchild at this time. + The restrictions Quantum has agreed to follow regarding +further dealings in Fairchild stock do not apply to Soros as an +individual investor. + Fairchild's annual shareholders meeting is scheduled to be +held tomorrow. + Reuter + + + +21-APR-1987 11:45:56.03 +money-fx +usa + + + + + +V RM +f1446reute +b f BC-/-FED-ADDS-RESERVES-V 04-21 0059 + +FED ADDS RESERVES VIA TWO-DAY REPURCHASES + NEW YORK, April 21 - The Federal Reserve entered the U.S. +Government securities market to arrange two-day System +repurchase agreements, a Fed spokesman said. + Dealers said that Federal funds were trading at 6-7/16 pct +when the Fed began its temporary and direct supply of reserves +to the banking system. + Reuter + + + +21-APR-1987 11:49:31.32 + +usa + + +nasdaq + + +F +f1466reute +d f BC-CAPITAL-ASSOCIATES-<C 04-21 0053 + +CAPITAL ASSOCIATES <CAII.O> TO TRADE ON NASDAQ + COLORADO SPRINGS, Colo., April 21 - Capital Associates Inc +said its common stock will be included in NASDAQ's national +market system, starting today. + Capital Associates is an equipment leasing and financial +service company with headquarters in Colorado Springs, Colo. + Reuter + + + +21-APR-1987 11:52:37.63 +copper +usa + + + + + +C M +f1486reute +u f BC-/MINT-REVIEWS-OFFERS 04-21 0105 + +MINT REVIEWS OFFERS ON 3,701,000 LBS COPPER + WASHINGTON, April 21 - The U.S. Mint received 17 offers +from seven firms at prices ranging from 0.66845-0.6840 dlrs per +lb for payment by standard check and 0.66695-0.68 dlrs per lb +for wire transfer payment in a review of offers on 3,701,000 +lbs of electrolytic copper it is seeking to purchase. + Philipp Brothers, N.Y., led with the lowest offers of +0.66695 for wire transfer payment and 0.66845 dlrs per lb to be +paid by check, followed by Cerro Sales Corp, N.Y., with 0.6684 +dlrs per lb on one mln lbs for wire payment, and 0.6713 dlrs +per lb on one mln lbs for standard payment. + Firms, in submitting offers, elect to be paid by standard +check or wire transfer, with awards based on whichever of the +two methods is more cost advantageous at that time. + Cerro Sales also offered prices for wire payment of 0.6689 +dlrs per lb on one mln lbs and 0.6693 dlrs per lb on 1,701,000 +lbs. Cerro's standard payment offers included 0.6719 dlrs per +lb on one mln lbs and 0.6723 dlrs per lb on 1,701,000 lbs. + Cargill Metals, Minneapolis, offered 0.67025 dlrs per lb +for wire payment and 0.67275 dlrs per lb for standard payment, +while Elders Raw Materials, Darien, Ct., offered 0.6718 dlrs +per lb for wire payment and 0.6735 dlrs per lb for standard +payment on increments of 950,000 lbs each. + Other offers for wire transfer payment include 0.6759 dlrs +per lb on 380,000 lbs, submitted by Deak International, N.Y., +0.6789 dlrs per lb on the entire quantity by Diversified Metals +Corp, St. Louis, and 0.68 dlrs per lb by Gerald Metals, +Stamford, Ct. + Other standard payment offers include 0.6819 dlrs per lb on +950,000 lbs by Diversified Metals, and 0.6840 dlrs per lb on +the entire quantity by Gerald Metals. + The Mint said the copper is for delivery the week of May 11 +to Olin Corp, East Alton, Ill. + The offers have a minimum acceptance period of three +calendar days, it said. + Reuter + + + +21-APR-1987 11:55:33.03 + +canada + + + + + +E F +f1500reute +r f BC-ahed-<aHM.TO>-may-iss 04-21 0076 + +AHED <AHM.TO> MAY ISSUE ONE MLN SHARES + Toronto, April 21 - Ahed Corp said it began discussions +with an investment dealer about issuing an additional one mln +treasury shares in the near future. + Ahed also said it believes recent increases in its stock +price could be attributable to a published report describing +the activities of the company. + Ahed said no other events are known to have taken place +which would cause these recent price increases. + Reuter + + + +21-APR-1987 11:55:57.82 + +usa + + + + + +F +f1503reute +r f BC-U.S.-WEST-<USW>-INTRO 04-21 0082 + +U.S. WEST <USW> INTRODUCES DATA NETWORK PRODUCT + NEW YORK, April 21 - U.S. WEST INC said it introduced its +first product for managing data networks, called the NETCENTER +graphic network monitor. + The product was developed by U.S. WEST Network Systems Inc, +a subsidiary of U.S. WEST INC, it said. It will be distributed +in the third quarter of 1987. + The company said the product is aimed at companies with IBM +SNA networks, and will allow customers control over their own +networks. + + The initial license fee for a typical configuration will be +in the 100,000 dlr to 300,000 dlr range, depending on the size +of the network, the company said. + Reuter + + + +21-APR-1987 12:04:11.03 +grainwheatbarleyoilseedrapeseed +france + + + + + +C G +f1537reute +u f BC-FRENCH-WINTER-CEREAL 04-21 0106 + +FRENCH WINTER CEREAL SOWING SEEN LITTLE CHANGED + PARIS, April 21 - The Ministry of Agriculture left its +estimates of French winter cereal sowings for the 1986/87 +campaign barely changed at 6.606 mln hectares compared with its +previous forecast of 6.601 mln. + This compared with the 6.41 mln ha of winter cereals +harvested in the 1985/86 campaign. + Winter soft wheat sowings were put at 4.647 mln ha compared +with its previous estimate of 4.651 mln and 4.57 mln ha +harvested last campaign. Winter barley plantings were forecast +at 1.46 mln ha, unchanged from its previous estimate and +compared with 1.41 mln harvested last season. + The ministry put hard winter wheat sowings at 246,000 ha +versus a February 1 estimate of 236,000 and actual area +harvested last campaign of 217,000. + Winter rape plantings were forecast at 627,000 ha against a +previous estimate of 621,000 and 375,000 rpt 375,000 harvested +in 1985/86. + Reuter + + + +21-APR-1987 12:11:18.43 +gold +canada + + + + + +F +f1591reute +r f BC-ENERGEX-MINERALS-<EGX 04-21 0101 + +ENERGEX MINERALS <EGX> MAY RUN UP TO THREE PITS + VANCOUVER, British Columbia, April 21 - Energex Minerals +Ltd said economic evaluation of reserves indicates high-grade +operation from three open pits may be feasable based on +five-year operation at 100 tons a day, a payback of less than +1-1/2 years. + An increase in the project's life, profitability and scale +is anticipated as additional reserves are developed in 1987, +the company said. + Current reserves are one mln long tons at 0.20 ounce gold +per ton, all categories; proven-probable 262,242 long tons at +0.25 ounce gold per ton, the company said. + Reuter + + + +21-APR-1987 12:13:27.73 +acq +canada + + + + + +E F Y +f1605reute +r f BC-dome-<dmp>-executives 04-21 0083 + +TURNER TO MEET WITH DOME <DMP> EXECUTIVES + Ottawa, April 21 - Liberal Party leader John Turner said he +will meet with senior executives of Dome Petroleum Ltd in +Calgary tomorrow to discuss the proposed sale of Dome. + Turner's office said he will hold a news conference +tomorrow at 1400 MDT (1600 EDT) in Calgary. + Turner, who is opposition leader in Parliament, has +criticized Dome's acceptance of a 5.1 billion dlr takeover bid +from Amoco Corp <AN> as a sell-out of Canada's oil industry. + Reuter + + + +21-APR-1987 12:13:34.25 + +usa + + + + + +F +f1606reute +r f BC-NEW-YORK-TIMES-<NYT> 04-21 0079 + +NEW YORK TIMES <NYT> SEES UNEVEN GAINS IN 1987 + HUNTSVILLE, Ala., April 21 - The New York Times Co said +that if prevailing business conditions continue, the company +sees "another outstanding year, although the remaining quarters +of 1987 will probably not show uniform gains." + The company's first quarter earnings rose 21 pct to 41.1 +mln dlrs or 50 cts a share compared to 33.9 mln dlrs or 42 cts +a share in the year-ago quarter restated for a two-for-one +stock split. + + The company also said its newspaper division, which +includes the New York Times and 32 regional newspapers, had a +first quarter operating profit of 69.8 mln dlrs compared with +60.7 mln dlrs in the year-ago first quarter mainly due to +advertising volume and rate increases. + The company's magazine division, which includes "Family +Circle," had a first quarter profit of 9.7 mln dlrs compared to +7.4 mln dlrs in the year ago quarter. + The company's broadcasting and cable tv group reported an +operating profit of 2.9 mln dlrs compared to 2.6 mln dlrs in +the year-ago first quarter. + Reuter + + + +21-APR-1987 12:14:27.18 + +usa + + + + + +F A RM +f1611reute +u f BC-BANKERS-TRUST-<BT>-TI 04-21 0115 + +BANKERS TRUST <BT> TIES NET TO CURRENCY EARNINGS + NEW YORK, April 21 - Bankers Trust New York Corp said its +first quarter foreign exchange trading income rose to 82.8 mln +dlrs from 20.9 mln dlrs in the first qtr of 1986, offsetting +the bank's 7.4 mln dlr loss incurred from placing 540 mln dlrs +of Brazilian loans on a non-accrual status. + Earlier, the bank reported that first quarter net income +increased to 124.2 mln dlrs, or 1.77 dlrs a share, from 115.9 +mln dlrs, or 1.64 dlrs a share, a year ago. + Bankers Trust chairman Alfred Brittain III said increased +non-interest income, a lower provision for loan-losses and +increased net interest income also helped first quarter net. + + Bankers Trust previously announced that the 540 mln dlrs in +non-accruable Brazilian loans would cut its first quarter +earnings by 7.4 mln dlrs, and could slice about 30 mln dlrs +from the full year's net. + Bankers Trust said non-interest income in the first quarter +equaled 275.4 mln dlrs, up 37.1 mln dlrs from a year ago. + Loan losses fell in the quarter to 22 mln dlrs, versus 40 +mln dlrs a year ago while taxable net interest income remained +flat at 266 mln dlrs, the bank said. + Reuter + + + +21-APR-1987 12:15:12.80 +acq +usa + + + + + +F Y +f1618reute +r f BC-ALTEX-<AII>-TO-SELL-O 04-21 0072 + +ALTEX <AII> TO SELL OILFIELD SERVICES ASSETS + DENVER, April 21 - Altex Industries Inc said it agreed to +sell the assets of its wholly-owned oilfield service +subsidiary, Parrish Oil Tools Inc. + The price and buyer were not disclosed. + Altex said Parrish had a loss from operations of 428,000 +dlrs on revenues of 881,000 dlrs in fiscal 1986 and a loss from +operations of 48,000 dlrs on revenues of two mln dlrs in fiscal +1985. + Reuter + + + +21-APR-1987 12:17:02.35 + +usa + + + + + +F +f1633reute +r f BC-IMARK-INDS-<IMAR.O>-V 04-21 0041 + +IMARK INDS <IMAR.O> VOTES ANNUAL 25 CT DIVIDEND + GENESEO, ILL., April 21 - Imark Industries Inc said its +directors approved payment of an annual dividend of 25 cts on +May 21, record May seven. + The company paid the same dividend last year. + Reuter + + + +21-APR-1987 12:17:09.99 + +usa + + + + + +F +f1634reute +r f BC-DUQUESNE-LIGHT-<DQU> 04-21 0083 + +DUQUESNE LIGHT <DQU> HURT BY LEGISLATION + PITTSBURGH, APril 21 - Duquesne Light Co president Wesley +von Schack told shareholders that current state law and +regulatory policies will result in higher capital rates and +higher rates for customers. + "Pennsylvania's recently enacted excess capacity +legislation denies shareholders the opportunity to earn a fair +return on their investment and undermines economic development +in Pennsylvania," von Schack told shareholders at the annual +meeting. + + Von Schack said two major bond rating agencies have recently +downgraded Duquesne's credit rating due to regulatory +uncertainty. The action will result in higher capital rates and +higher rates for customers, he said. + He said the Pennsylvania Utility commission indicated in +its most recent rate case decision that even if newly +constructed Perry No. 1 nuclear plant was in commercial +operation, shareholders would be denied a return on their +investment in the plant. Von Schack called on shareholders to +join it and certain legislators' efforts to create a +partnership to fight these issues and resolve these problems. + + Reuter + + + +21-APR-1987 12:17:49.31 +interestmoney-fxgnp +kuwait + + + + + +RM +f1638reute +r f BC-CREATIVE-MONETARY-POL 04-21 0109 + +CREATIVE MONETARY POLICY TO SPUR KUWAITI ECONOMY + By Rory Channing, Reuters + KUWAIT, April 21 - Kuwait, a major oil producer hit by last +year's price slump, is leaning towards a more creative monetary +policy to help spur its economy, banking sources said. + "There is a clear emphasis on encouraging the use of money +in productive ventures, rather than having it all tied up in +interest bearing investments which have no direct productive +outlet," one banker said. + Kuwait's Central Bank yesterday cut one key money market +rate and abandoned another which had been used since February +1986 to direct inter-bank borrowing and lending costs. + The bank reduced to six pct from 6-1/2 pct the rate at +which it will offer funds of one month to one year in the +inter-bank market. This, in turn, affected retail rates. + The cut, the third this year, followed a major overhaul of +interest rate policy last month which Central Bank Governor +Sheikh Salem Abdul-Aziz al-Sabah said was designed to revive +the economy. + One banker said "There is growing flexibility, creativity, +in interest rate policy, amid an awareness of the need to +diversify the economy by stimulating the non-oil sector." + For the first time in nearly three years domestic interest +rates are now significantly below those for the U.S. Dollar, a +favourite haven for Gulf speculative and investor funds in the +past, banking sources said. + Despite uncertainties generated by the 6-1/2 year old Iran- +Iraq war on Kuwait's northern doorstep, bankers play down the +prospect of any significant capital flight. + The Kuwaiti dinar, whose value is set by the Central Bank +and was fixed today at 0.27095/129 to the dollar, is stronger +now than for several years. + Fears that the dollar may fall further will prompt second +thoughts among Kuwaiti investors prepared to consider switching +funds into the U.S. Currency, the sources said. + "There is a distinct exchange rate risk," they added. + Bankers said the dollar slump hurt many investors behind +the last major capital outflow in 1984, encouraged then by 18 +pct U.S. Interest rates and the start of Iranian attacks on +neutral shipping in the Gulf. + The Central Bank calculates its dinar exchange rate against +a basket of currencies. Bankers do not know the basket's exact +make-up but say it is weighted heavily in favour of the dollar. + Some bankers believe any strengthening of the dinar beyond +0.27000 to the dollar might provoke investors into shifting +funds into the U.S. Currency. "They may ask:When will the dollar +be so cheap again?" one said. + And with dinar interest rates now roughly one pct below +those for the dollar, they say the Central Bank faces a +delicate balancing role requiring further flexibility. + Bankers said the current, expansionary interest rate policy +is only part of a broader attempt to encourage local investment +and strengthen the backbone of the economy. + They estimate the economy, measured in terms of GDP and +allowing for inflation, shrank 19 pct in 1986 after an 8.1 pct +contraction the previous year. + Bankers also noted recent measures to stimulate stock +market activity, capped today by sharp cuts in brokerage fees +to make it cheaper for investors to trade. + REUTER + + + +21-APR-1987 12:23:33.91 + +usa + + + + + +F +f1672reute +r f BC-CSX-<CSX>-UNIT-CHAIRM 04-21 0065 + +CSX <CSX> UNIT CHAIRMAN RETIRES + WHITE SULPHUR SPRINGS, W. Va., April 21 - CSX Corp said +that Joseph Abely, chairman and chief executive officer of +CSX's Sea-Land Corp unit, will retire by the end of the month. + The company said he will be replaced by Robert Hintz, +executive vice president of CSX and president and chief +executive officer of the company's energy and properties +groups. + Reuter + + + +21-APR-1987 12:28:08.02 + +brazil + + + + + +F +f1702reute +d f BC-BRAZIL-FUND-SHOULD-ST 04-21 0095 + +BRAZIL FUND SHOULD START OPERATING SOON + SAO PAULO, April 21 - A Brazil Fund through which foreign +investors will be able to buy stocks in Brazilian companies +should start operating in about two months, the Securities and +Exchange Commission said. + A spokesman told Reuters that four institutions in the +United States were interested in participating in the Fund -- +Merrill Lynch and Co Inc, Salomon Brothers Inc, the IFC and the +First Boston Corp. + The spokesman said the Fund, approved last December, was +expected to attract about 100 mln dlrs of investments. + Reuter + + + +21-APR-1987 12:36:27.62 +oilseedrapeseed +japancanada + + + + + +C G +f1756reute +u f BC-JAPAN-BUYS-4,000-TONN 04-21 0043 + +JAPAN BUYS 4,000 TONNES OF CANADIAN RAPESEED + WINNIPEG, April 21 - Japan bought 4,000 tonnes of Canadian +rapeseed for last-half May/first-half June shipment, nearly +completing buying for May needs, trade sources said. + Price details were not available. + + Reuter + + + +21-APR-1987 12:39:08.68 +grainwheat +south-koreacanada + + + + + +C G +f1763reute +u f BC-SOUTH-KOREA-BUYS-50,0 04-21 0038 + +SOUTH KOREA BUYS 50,000 TONNES CANADIAN WHEAT + WINNIPEG, April 21 - South Korea yesterday bought 50,000 +tonnes of Canadian feed wheat for late June/early July shipment +at 95.00 dlrs per tonne FOB Vancouver, trade sources said. + Reuter + + + +21-APR-1987 12:39:55.30 +trade +usa +reagan + + + + +RM A +f1766reute +r f BC-WASHINGTON-BUDGET 04-21 0106 + +SENATE PREPARING FOR NEW U.S. BUDGET BATTLE + By Michael Posner, Reuters + WASHINGTON, April 21 - Congress returned from its Easter +recess ready for the annual Spring budget battle that promises +to be a partisan dispute. + The budget fight pitting Democrats against President Reagan +and Republicans is expected to get underway this week in the +Senate late this week and last at least another week. It is +taking on new prominence because of current trade woes. + That is because the budget problems and its associated huge +deficits are said to be at the root of related international +trade friction currently worrying financiers. + As the dollar slides downward on global markets and stock +exchanges gyrate wildly, the trade dispute involving the United +States and Japan once again is spreading fears of a major trade +war between the two trading giants for the first time since +World War II. + Ostensibly that dispute is over U.S. charges that Japan is +refusing to open its markets to semi-conductor chips and the +resulting U.S. tariffs doubling prices of Japanese televisions +and small computers. + Behind the elements of a brewing trade war which neither +side wants, is the dilemma of the U.S. budget and its deficit. + Some analysts say the financial markets may be waking up to +the economic realities that the huge debt cannot continue to +grow without repercussions. + A large portion of the U.S. debt has been financed by +foreigners from their accumulated trade surpluses. But if they +withdraw this support the result can only be further problems, +including higher interest rates for Americans. + In a nutshell, the U.S. budget process has now moved to the +showdown stages in Congress. Reagan's own trillion dollar +spending budget for the government year 1988, starting Oct. 1, +was trounced badly in the House on April 9. + The Senate takes up a plan similar to one that passed the +House, calling for slashing the deficit from its estimated 171 +billion dlr level next year to about 134 billion dlrs, through +defense and domestic spending cuts and about 18.5 billion dlrs +in new, unspecified, taxes. As the Senate prepares to take up +its own budget plan, majority Democrats predict there will be +passage of a bill, only after a protracted partisan battle. + In the House, not one Republican voted for the budget, +which passed by 230 to 192. In the Senate, none of Reagan's +Republicans voted for the budget as it passed out of the Senate +Budget Committee for full Senate consideration. + A key Senate Budget Committee source told Reuters he +believes this very unusual unanimous opposition was by design +among congressional Republicans, perhaps with the tacit +approval of the White House. + "Republicans want Democrats to take the heat for any tax +hikes and defense cuts," he said. + In the coming weeks, the source said, Democrats will press +for a bipartisan budget and seek a negotiated budget with +Reagan -- who already is opposed to the idea. But "it is not +clear how the Republicans will act," he added. + He said Republicans may propose their own plan for lower +taxes and more defense spending, which they did not offer after +Reagan's budget was clobbered in an early vote in the House. + When Reagan entered the White House in 1981, he inherited +what was labelled a huge deficit from Jimmy Carter that wound +up to be nearly 79 billion dlrs that year. + Despite Reagan's promise to balance the budget by 1983, +critics note that his administration's record of accumulated +debt is estimated over one trillion dlrs, or 1,100 billion +dlrs. + That is money the government must borrow, and pay back, and +many analysts say it is what kept the dollar high and caused +the worst U.S. trade deficit ever. + Last year the United States bought goods from the world +worth 169.8 billion dlrs more than what it sold, including +purchases of 58.6 billion dlrs in Japanese goods. + While Congress is trying to attack the trade deficit on one +front through a get-tough trade bill promising retaliatory +measures unless all markets are opened, its success so far +against the budget deficit has been marked by limited progress. + Congress, which controls the pursestrings, has put the +deficit on a downward path from its record high of 220.7 +billion dlrs accumulated in fiscal 1986, which ended Sept. 30. + Because of the Gramm-Rudman-Hollings balanced budget law +enacted in late 1985, there has been pressure on Congress to do +more than talk about deficits. + That law, named after Republican Senators Phil Gramm of +Texas, Warren Rudman of New Hampshire and Democrat Ernest +Hollings of South Carolina, calls for a balanced budget by 1991 +through a series of set deficit targets that Congress must meet. + The law has been followed, even though an enforcement +mechanism to mandate automatic across-the-board cuts if +Congress misses its goal was stricken by the Supreme Court. + The legislators have followed the targets -- on paper. But +in reality, the goal has actually been missed. For example, +Congress last year approved legislation to meet the 1987 target +of a 144 billion dlr deficit. But even after approving the +numbers, the deficit for 1987 is estimated at over 170 billion +dlrs -- far off the target. + This year the target is 108 billion dlrs and that goal is +expected to be missed widely. + Reuter + + + +21-APR-1987 12:42:37.02 + +usa + + + + + +A RM +f1778reute +r f BC-COMMONWEALTH-EDISON-< 04-21 0112 + +COMMONWEALTH EDISON <CWE> SELLS MORTGAGE BONDS + NEW YORK, April 21 - Commonwealth Edison Co is raising 360 +mln dlrs via a two-tranche offering of first and refunding +mortgage bonds, said lead manager Morgan Stanley and Co Inc. + A 200 mln dlr issue of bonds due 1990 has an 8-1/8 pct +coupon and was priced at 99.775 to yield 8.21 pct, or 65 basis +points over comparable Treasury securities. + A 160 mln dlr offering of bonds due 1992 has an 8-5/8 pct +coupon and was priced at 99.85 to yield 8.661 pct, or 78 basis +points more than Treasuries. Both tranches are non-callable for +life and rated A-3 by Moody's and A by S and P. Salomon +Brothers Inc co-managed the deal. + Reuter + + + +21-APR-1987 12:47:33.66 +acq +usa + + + + + +F +f1796reute +r f BC-ROYAL-RESOURCES 04-21 0058 + +BUSINESSMAN HAS ROYAL RESOURCES <RRCO.O> STAKE + WASHINGTON, April 21 - James Stuckert, a Louisville, Ky., +businessman, told the Securities and Exchange Commission he has +acquired 380,000 shares of Royal Resources Corp, or 5.7 pct of +the total outstanding common stock. + Stuckert said he bought the stake for 600,000 dlrs solely as +an investment. + Reuter + + + +21-APR-1987 12:48:28.99 + +usa + + + + + +F +f1800reute +d f BC-ATT-<T>-LAUNCHES-SYST 04-21 0091 + +ATT <T> LAUNCHES SYSTEMS FOR SMALL BUSINESSES + NEW YORK, April 21 - American Telephone and Telegraph Co +introduced two communications systems, Spirit and Merlin, and +other products, in a bid to strengthen its position with small +businesses, the company said. + The Spirit system, with a basic price tag of 1,500 dlrs, +can handle up to six lines and 16 telephones and a more +advanced line which can handle up to 24 lines and 48 +tlelphones. + ATT said the Merlin line, which starts at 2,500 dlrs, can +handle up to 32 lines and 72 telephones. + ATT said the new products will eventually replace the +current Merlin product family. Some of the systems will be +available in May and others in the third quarter. + ATT also introduced software enhancements for the System +25, for business that require PBX voice and data communications +and need up to 150 phones. These and other enhancements will be +available in the third quarter, the company said. + Reuter + + + +21-APR-1987 12:53:58.04 +cpi +spain + + + + + +RM +f1823reute +r f BC-SPAIN-MAINTAINS-FIVE 04-21 0091 + +SPAIN MAINTAINS FIVE PCT INFLATION TARGET + MADRID, April 21 - Spanish Secretary of State for the +economy Guillermo de la Dehesa said the government maintained +its five pct inflation target for this year although a 0.6 pct +increase in March pushed the rise in the year on year consumer +price index to 6.3 pct. + De la Dehesa said the March rise, announced today by the +National Statistics Institute, was not entirely satisfactory +but acceptable. + The year on year rate at the end of February was six pct. +Prices rose 8.3 pct last year. + The March rise included a 0.05 pct increase correcting an +error in last January's consumer price index. Economists had +earlier said the error could have been as high as 0.2 pct. + De la Dehesa said seasonal increases in food prices pushed +the index up in March and he expected the rate to be lower in +April. + The Communist-led Workers Commissions union said the March +price rise showed inflation was going up again and the +government looked increasingly unlikely to meet its five pct +target. + The Workers Commissions said the inflation trend fuelled +unions's claims to wage increases beyond the government's +recomendation to limit wage rises at around five pct. + Spain is being affected by a two-month-old wave of strikes +for wage rises. Government officials note wage settlements so +far this year have yielded average increases upwards of six +pct, while unions say the figure is higher then seven pct. + REUTER + + + +21-APR-1987 13:00:06.84 +crude +usa + + + + + +Y +f1842reute +u f BC-API-SAID-STATISTICS-T 04-21 0036 + +API SAID STATISTICS TO BE RELEASED TONIGHT + NEW YORK, April 21 - The American Petroleum Institute said +it plans to release its weekly report on U.S. oil inventories +tonight, even though last Friday was a holiday. + Reuter + + + +23-APR-1987 18:32:18.42 + +usa + + + + + + +F +f3036reute +r f BC-GCA-<GCA>-COMPLETES-F 04-23 0102 + +GCA <GCA> COMPLETES FINANCIAL RESTRUCTURING + ANDOVER, Mass., April 23 - GCA Corp said it completed its +previously announced plan of financial restructuring under +which Hallwood Group Inc <HWG> took a 14 pct interest in the +company, a maker of semiconductor manufacturing equipment. + The company said it also implemented a one-for-50 reverse +stock split. + Under terms of the plan, the company exchanged about 109 +mln dlrs in debt to creditors and suppliers for 43 mln dlrs in +cash, and warrants to purchase 2.2 mln shares of its common +stock. GCA also raised 71.7 mln dlrs through the sale of common +stock. + Reuter + + + +23-APR-1987 18:34:33.58 + +usa + + + + + + +F +f3040reute +u f BC-SEC 04-23 0098 + +SEC WARNS SECURITIES DEALERS ON HIGH MARK-UPS + WASHINGTON, April 23 - The Securities and Exchange +Commission reminded securities dealers that its mark-up +disclosure requirements also applies to transactions on +zero-coupon securities. + Dealers and brokers are required by U.S. securities law to +disclose their mark-ups if they are excessive, the SEC said in +a public notice. + Further, excessive mark-ups on securities transactions, +whether disclosed or not, violate the rules of the national +Association of Securities Dealers Inc and Municipal Securities +Rulemaking Board, it said. + In a separate action, the SEC filed a friend-of-the-court +brief in a private civil case involving a complaint against +Merrill Lynch over excessive mark-ups on zero-coupon bonds. The +case is being appealed to the U.S. Appeals Court. + The lower court dismissed the complaint, finding antifraud +provisions of securities laws do not prohibit undisclosed +excessive mark-ups on securities transactions. + The SEC is urging the appeals court to reverse the +decision, citing its nearly 50 year-old position that +undisclosed excessive mark-ups by securities dealers violate +the general antifraud provisions of securities laws. + Reuter + + + +23-APR-1987 18:37:03.79 +earn +canada + + + + + + +E F +f3044reute +u f BC-SOUTHAM-INC-<STM.TO> 04-23 0043 + +SOUTHAM INC <STM.TO> 1ST QTR NET + TORONTO, April 23 - + Oper shr 32 cts vs 37 cts + Oper net 18.9 mln vs 21.6 mln + Revs 352.1 mln vs 323.0 mln + Note: 1987 net excludes extraordinary gain of 2.8 mln dlrs +or five cts shr from sale of surplus property. + Reuter + + + +23-APR-1987 18:45:40.42 +earn +usa + + + + + + +F +f3052reute +r f BC-LOCTITE-CORP-<LOC>-3R 04-23 0044 + +LOCTITE CORP <LOC> 3RD QTR MARCH 31 NET + NEWINGTON, Conn., April 23 - + Shr 96 cts vs 53 cts + Net 8,663,000 vs 4,798,000 + Revs 89.7 m ln vs 66.8 mln + Nine mths + Shr 2.33 dlrs vs 1.67 dlrs + Net 21.1 mln vs 15.1 mln + Revs 241.3 mln vs 192.8 mln + Reuter + + + +23-APR-1987 18:56:03.00 + +usajapan + + + + + + +RM V +f3056reute +u f BC-U.S.-CONGRESS-STILL-A 04-23 0104 + +U.S. CONGRESS STILL ANGRY WITH JAPAN - ABE + NEW YORK, April 23 - Special Japanese envoy Shintaro Abe +said in a brief interview with Reuters that the feeling in the +U.S. congress is "very severe" against Japan. + However, Abe said he believed that neither Congress nor the +Reagan administration wants to undermine relations with Japan. + He said the Reagan administration showed "relative +understanding" of how Japan is trying to alleviate its U.S. +trade imbalance. Abe said he was convinced "Congress and the +administration had the same view that the relationship between +Tokyo and Washington should not be undermined." + Reuter + + + +23-APR-1987 18:59:23.50 +earn +usa + + + + + + +F +f3060reute +u f BC-GLENFED-INC-<GLN>-3RD 04-23 0070 + +GLENFED INC <GLN> 3RD QTR MARCH 31 NET + GLENDALE, Calif., April 23 - + Oper shr 1.54 dlrs vs 82 cts + Oper net 33.7 mln vs 17.66 mln + Revs 473.1 mln vs 419.0 mln + Nine mths + Oper shr 4.60 dlrs vs 2.39 dlrs + Oper net 100.4 mln vs 51.0 mln + Revs 1.38 billion vs 1.21 billion + Assets 18.5 billion vs 15.5 billion + Deposits 13.00 billion vs 11.29 billion + Loans 15.04 billion vs 12.56 billion + Note: Oper net excludes extraordinary loss 6,636,000 and +11.9 mln for 1987 qtr and nine mths on prepayment of borrowings +from the Federal Home Loan Bank Board. + Oper also excludes tax credits of 15.8 mln vs 5,954,000 for +qtr and 17.8 mln vs 11.6 mln for nine mths. + + Reuter + + + +23-APR-1987 19:00:51.40 +earn +usa + + + + + + +F +f3062reute +r f BC-HORIZON-INDUSTRIES-IN 04-23 0053 + +HORIZON INDUSTRIES INC <HRZN> 2ND QTR NET + CALHOUN, Ga., April 23 - Qtr ended April four + Shr profit eight cts vs loss 22 cts + Net profit 341,000 vs loss 903,000 + Revs 58.4 mln vs 46.3 mln + Six mths + Shr profit 35 cts vs loss 19 cts + Net profit 1,466,000 vs loss 767,000 + Revs 121.4 ln vs 95.9 mln + Reuter + + + +23-APR-1987 19:02:27.01 +money-supply +usa + + + + + + +RM V +f3063reute +u f BC-/FED-DATA-PROVIDE-NEW 04-23 0097 + +FED DATA PROVIDE NEW EVIDENCE OF TIGHTER POLICY + By Alan Wheatley, Reuters + NEW YORK, April 23 - U.S. banking data released today are +too distorted to draw sweeping conclusions about monetary +policy, but they do support the market's assumption that the +Federal Reserve has started to tighten its grip on credit, +economists said. + "It's clear that the Fed has firmed somewhat. Discount +window borrowings, net free reserves, the Fed funds rate +average and the pattern of reserve additions are all consistent +with a modest tightening," said Dana Johnson of First Chicago +Corp. + Johnson, and several other economists, now estimate that +the Fed funds rate should trade between 6-1/4 and 6-3/8 pct. + Discount window borrowings in the week to Wednesday were +935 mln dlrs a day, producing a daily average for the two-week +statement period of 689 mln dlrs, the highest since the week of +December 31, 1986, and up from 393 mln dlrs previously. + Moreover, banks were forced to borrow a huge 5.2 billion +dlrs from the Fed on Wednesday - the highest daily total this +year - even though unexpectedly low Treasury balances at the +Fed that day left banks with over two billion dlrs more in +reserves than the Fed had anticipated. + However, economists said it is almost certain that the Fed +is aiming for much lower discount window borrowings than +witnessed this week. They pointed to two factors that may have +forced banks to scramble for reserves at the end of the week. + First, economists now expect M-1 money supply for the week +ended April 29 to rise by a staggering 15 to 20 billion dlrs, +partly reflecting the parking in checking accounts of the +proceeds from stock market sales and mutual fund redemptions to +pay annual income taxes. + As banks' checking-account liabilities rise, so do the +reserves that they are required to hold on deposit at the Fed. + Required reserves did indeed rise sharply by 2.5 billion +dlrs a day in the two weeks ended Wednesday, but economists +said the Fed may not have believed in the magnitude of the +projected M-1 surge until late in the week and so started to +add reserves too late. + Second, an apparent shortage of Treasury bills apparently +left Wall Street dealers with too little collateral with which +to enagage in repurchase agreements with the Fed, economists +said. Thus, although there were 10.3 billion dlrs of repos +outstanding on Wednesday night, the Fed may have wanted to add +even more reserves but was prevented from doing so. + "It's not at all inconceivable that the Fed didn't add as +much as they wanted to because of the shortage of collateral," +said Ward McCarthy of Merrill Lynch Economics Inc. + McCarthy estimated that the Fed is now targetting +discount-window borrowings of about 400 mln dlrs a day, +equivalent to a Fed funds rate of around 6-3/8 pct. + After citing the reasons why the Fed probably has not +tightened credit to the degree suggested by the data, +economists said the fact that the Fed delayed arranging +overnight injections of reserves until the last day of the +statement period was a good sign of a more restrictive policy. + Jeffrey Leeds of Chemical Bank had not been convinced that +the Fed was tightening policy. But after reviewing today's +figures, he said, "It's fair to say that the Fed may be moving +toward a slightly less accommodative reserve posture." + Leeds expects Fed funds to trade between 6-1/4 and 6-3/8 +pct and said the Fed is unlikely to raise the discount rate +unless the dollar's fall gathers pace. + Johnson at First Chicago agreed, citing political +opposition in Washington to a dollar-defense package at a time +when Congress sees further dollar depreciation as the key to +reducing the U.S. trade surplus with Japan. + Reuter + + + +23-APR-1987 19:08:09.42 +earn +usa + + + + + + +F +f3066reute +r f BC-RORER-GROUP-INC-<ROR> 04-23 0072 + +RORER GROUP INC <ROR> 1ST QTR NET + FORT WASHINGTON, Pa., April 23 - + Oper shr profit 34 cts vs loss 78 cts + Oper net profit 7,434,000 vs loss 17.0 mln + Revs 201.2 mln vs 171.7 mln + Note: Year-ago oper exludes gain on sale of businesses of +139.6 mln. + Year-ago oper includes charges of 27.8 mln resulting from +allocation of the purchase price of Revlon's businesses to +inventory and 7.1 mln for restructuring costs. + Reuter + + + +23-APR-1987 19:36:56.77 +coffee +costa-ricaguatemala + +ico-coffee + + + + +T +f3073reute +u f AM-centam-coffee 04-23 0088 + +MILD COFFEE GROWERS TO MEET IN GUATEMALA + SAN JOSE, April 23 - A large group of "other milds" +coffee-growing nations will hold talks in Guatemala next month +to map their strategy for next September's meeting of the +International Coffee Organisation (ICO). + Mario Fernandez, executive director of the Costa Rican +coffee institute, said delegates from Mexico, the Dominican +Republic, Peru, Ecuador, India, Papua New Guinea and five +central american nations will participate in the two-day +strategy session beginning May 4. + The main topic will be reform of what many producing +countries perceive as the ICO's unfair distribution of export +quotas, Fernandez said. + He said Costa Rica would press for quotas "based on the +real production and export potential of each country in the +past few years" and to distribute quotas based on "historic" +production levels rather than recent harvests and crop +estimates. + Reuter + + + +23-APR-1987 19:48:08.94 +acq +usa + + + + + + +F +f3076reute +u f AM-COMSAT 04-23 0107 + +US STUDY DISCUSSES DROPPED COMSAT-CONTEL MERGER + WASHINGTON, April 23 - A congressional study today said the +proposed, but now apparently abandoned, merger of the +Communications Satellite Corp <CQ> and Contel Corp <CTC> +would technically be legal but could violate the spirt of the +law setting up COMSAT. + Two weeks ago before the study was completed, Contel +announced it would seek to terminate the proposed merger. + The study by the non partisan Congressional Research +Service (CRS) said "the proposed merger appears to comply, +technically, with the mandates or letter of statutes, if may +nevertheless violate the spirit of the law." + Comsat, created by a 1962 act of Congress, and Contel, a +corporation of local telephone and communications firms, filed +with the Federal Communications Commission last November 3 an +application for merger. Several firms had protested the +proposed merger. + In an analysis of the law, the research service issued +several critical comments about the structure of the new firm +and said apparent domination by Contel of a restructured COMSAT +would have broken the spirit of the law setting up +COMSAT.COMSAT is the U.S. arm of Intelstat, the international +satellite communications firm. + +Reuter...^M + + + +23-APR-1987 19:48:47.25 + +japanusa +nakasone + + + + + +C +f3077reute +u f BC-JAPANESE-PARLIAMENT-P 04-23 0138 + +SETBACK SEEN FOR NAKASONE IN JAPANESE PARLIAMENT + TOKYO, April 24 - Japan's Lower House passed the 1987 +budget after the ruling Liberal Democratic Party agreed to a +mediation proposal that could kill its plan to introduce a +controversial sales tax, political analysts said. + The move was seen as a major blow to Prime Minister +Yasuhiro Nakasone, the leading advocate of the five pct tax. + Some analysts predicted Nakasone might be forced to step +down just after the June summit of leaders from major +industrial democracies, well before his one-year term is due to +expire at the end of October. + The ruling party though was anxious to pass the budget +before Nakasone leaves next week for the U.S. so that he could +tell Washington the Japanese government was doing its utmost to +boost the sagging economy and imports. + Reuter + + + +23-APR-1987 20:21:46.09 +money-fxdlr + + + + + + + +RM +f3091reute +b f BC-BANK-OF-JAPAN-INTERVE 04-23 0086 + +BANK OF JAPAN INTERVENES IN TOKYO MARKET + TOKYO, April 24 - The Bank of Japan intervened just after +the Tokyo market opened to support the dollar from falling +below 140.00 yen, dealers said. + The central bank bought a moderate amount of dollars to +prevent its decline amid bearish sentiment for the U.S. +Currency, they said. + The dollar opened at a record Tokyo low of 140.00 yen +against 140.70/80 in New York and 141.15 at the close here +yesterday. The previous Tokyo low was 140.55 yen set on April +15. + REUTER + + + +23-APR-1987 20:24:10.50 +money-supply +australia + + + + + + +RM +f3092reute +b f BC-AUSTRALIA'S-M-3-MONEY 04-23 0101 + +AUSTRALIA'S M-3 MONEY SUPPLY RISE 1.5 PCT IN MARCH + SYDNEY, April 24 - Australia's M-3 money supply growth was +1.5 pct in March and 11.3 pct in the 12 months to March, the +Reserve Bank said. + This compared with a revised rise of 0.5 pct in February +and 11.1 pct in the year to end-February. + The Reserve Bank said the M-3 data for March was affected +by the start of the operations of <National Mutual Royal +Savings Bank Ltd>, which has resulted in the transfer of +deposits (equivalent to around 1.5 pct of m-3) from the United +Permanent Building Society to National Mutual Royal Savings +Bank Ltd. + The Reserve Bank said M-3 money supply in March was 110.77 +billion Australian dlrs compared with a revised 109.11 billion +in February and 99.48 billion in March, 1986. + M-3 is deposits of the private sector held by trading and +savings banks plus holdings of notes and coins. + REUTER + + + +23-APR-1987 20:30:17.87 + +japan + + + + + + +RM +f3094reute +b f BC-JAPANESE-PARLIAMENT-P 04-23 0111 + +JAPANESE PARLIAMENT PASSES 1987 BUDGET + TOKYO, April 24 - Parliament's Lower House passed the 1987 +budget shortly before midnight local time, official +parliamentary sources said. + The move followed agreement by the ruling Liberal +Democratic Party to a proposal that could kill its plan to +introduce a controversial sales tax, political analysts said. +The move was seen as a major blow to Prime Minister Yasuhiro +Nakasone, the leading advocate of the five pct tax, they said. + Some analysts said Nakasone may be forced to step down +after the June summit of heads of major industrial democracies +and before his one-year term is due to expire at end-October. + Under the compromise agreed by the LDP and opposition +parties, Lower House Speaker Kenzaburo Hara will take charge of +the sales tax bill, appoint a ruling/opposition party council +to debate it and allow opposition leaders to review the present +tax system, analysts said. + Hara also verbally agreed to scrap the sales tax plan +entirely if the joint council fails to reach agreement on how +to handle the tax. + The opposition parties, who have been vociferously +attacking the sales tax plan for months, hailed the decision as +a great victory. + The opposition parties had already delayed passage of the +budget for three weeks after the April 1 start of the fiscal +year by intermittent parliamentary boycotts. + Although the LDP had more than enough votes to ram the +budget through parliament, it had been reluctant to do so for +fear of a backlash of public opinion, especially after its +setback in recent local elections due to the sales tax issue. + The ruling party though was anxious to pass the budget +before Nakasone leaves next week for the U.S. So that he could +tell Washington the Japanese government was doing its utmost to +boost the sagging economy and imports. + According to Kyodo News Service, Nakasone told reporters he +did not think the sales tax was dead. + If the sales tax is dropped, it could prove a major boost +to the economy because it would increase the government budget +deficit, economists said. + The sales tax was originally scheduled to be introduced +next January to help offset the loss of government revenues +stemming from a cut in income and corporate taxes due to go +into effect this month. + REUTER + + + +23-APR-1987 20:35:24.14 +money-fxdlr +usajapan + + + + + + +RM +f3095reute +f f BC-Dollar-trades-at-post 04-23 0011 + +******Dollar trades at post-war low of 139.50 yen in Tokyo - brokers +Blah blah blah. + + + + + +23-APR-1987 21:19:18.12 +dlr + + + + + + + +RM +f3111reute +f f BC-Many-major-nations-ye 04-23 0012 + +******Many major nations yesterday intervened heavily to aid dlr - Miyazawa +Blah blah blah. + + + + + +23-APR-1987 21:25:22.52 +acq +uk + + + + + + +F +f3114reute +f f BC-STANDARD-OIL-SAYS-BRI 04-23 0012 + +******STANDARD OIL SAYS BRITISH PETROLEUM SHARE TENDER EXTENDED UNTIL MAY 4 +Blah blah blah. + + + + + +23-APR-1987 21:28:14.05 +money-fxdlr +usajapan +miyazawa + + + + + +RM +f3115reute +b f BC-JAPAN-HAS-NO-PLANS-FO 04-23 0110 + +JAPAN HAS NO PLANS FOR NEW MEASURES TO AID DLR + TOKYO, April 24 - Finance Minister Kiichi Miyazawa said +Japan has no plans to take new emergency measures to support +the dollar, other than foreign exchange intervention. + He also told reporters that many major nations yesterday +intervened heavily to support the dollar against the yen. + Yesterday's intervention was large in terms of the +countries involved and the amounts expended, he said. + With the continued fall of the dollar against the yen, +0speculation had arisen in currency markets here that Japan +might take new measures to support the U.S. Currency, such as +curbing capital outflows. + Miyazawa said that yesterday's news of a 4.3 pct rise in +U.S. Gnp in the first quarter had been expected. Although the +growth looks robust on the surface, the figures in reality are +not that good, he said. + He said the ruling Liberal Democratic Party (LDP) is +expected to come up with a final set of recommendations of ways +to stimulate the Japanese economy before Prime Minister +Yasuhiro Nakasone leaves for Washington next week. + Commenting on yesterday's report on economic restructuring +by a high-level advisory panel to Nakasone, Miyazawa said it +was important to put the panel's recommendations into effect. + REUTER + + + +23-APR-1987 21:34:36.89 +acq +usauk + + + + + + +F +f3117reute +b f BC-STANDARD-OIL-SAYS-BP 04-23 0082 + +STANDARD OIL SAYS BP EXTENDS TENDER + NEW YORK, April 23 - Standard Oil Co <SRD> said in a brief +announcement issued after a meeting of its board of directors +that British Petroleum Co PLC <BP.L> (BP) has extended its 70 +dlr per share tender offer until midnight May 4. + The offer for the 45 pct of Standard shares not owned by BP +had been due to expire midnight April 28. + Standard Oil said discussions with BP concerning the tender +were continuing but provided no further details. + "So long as those discussions continue, no recommendation +will be made to Standard Oil shareholders regarding the offer," +Standard said. + Standard directors met at the company's Cleveland +headquarters on Thursday in a regularly scheduled meeting. The +spokesman was unable to say if the meeting would continue on +Friday. + A committee of independent directors previously obtained an +opinion from First Boston Corp that the Standard shares were +worth 85 dlrs each, 15 dlrs more than the BP offer. + REUTER + + + +23-APR-1987 21:38:26.85 + +usa + + + + + + +F +f3120reute +u f BC-QANTAS-TO-BUY-EXTENDE 04-23 0104 + +QANTAS TO BUY EXTENDED RANGE BOEING 767 AIRCRAFT + SYDNEY, April 24 - State-owned <Qantas Airways Ltd> said it +has placed a firm order for a single Boeing Co <BA.N> 767-300ER +(extended range) aircraft for delivery in August 1988 at a cost +of 150 mln Australian dlrs, including spares. + A statement said it also has options to buy six more and +will decide in mid-1987 whether to use engines made by United +Technologies Corp <UTX> unit Pratt and Whitney or General +Electric Co <GE>. + The 767-300ER can carry more cargo and passengers and is +more fuel-efficient than the 767-200, six of which Qantas has +in service. + REUTER + + + +23-APR-1987 21:40:47.37 + +usajapan + + + + + + +RM +f3123reute +u f BC-JAPAN-AGENCY-URGES-WA 04-23 0115 + +JAPAN AGENCY URGES WATCH ON YEN RISE EFFECTS + TOKYO, April 24 - Japan should look out for possible +effects of the yen's recent sharp rise on Japan's economy as +growth remains slow, the government's Economic Planning Agency +said in a monthly report submitted to cabinet ministers. + EPA officials told reporters the underlying trend of the +economy is firm but growth is slow due to sluggish exports. + Customs-cleared exports by volume fell 4.9 pct +month-on-month in February after a 2.8 pct fall in March. + The government must take adequate economic measures to +expand domestic demand and stabilise exchange rates in a bid to +ensure sustained econonic growth, the report said. + The report made a special reference to the yen's renewed +rise and its effect on the economy, the officials said, adding +the agency's judgement of current economic conditions has not +changed since last month. + The EPA said last month Japan's economy is beginning to +show signs of bottoming out, conditional upon exchange rates. + The dollar fell below 139 yen in early trading today - a +post-war low. + REUTER + + + +23-APR-1987 22:03:13.44 +money-supplyinterest +japan + + + + + + +RM +f3135reute +b f BC-JAPAN-DOES-NOT-INTEND 04-23 0108 + +JAPAN DOES NOT INTEND TO EASE CREDIT - OFFICIALS + TOKYO, April 24 - The Bank of Japan does not intend to ease +credit policy further, bank officials told Reuters. + They were responding to rumours in the Japanese bond market +that the central bank was planning to cut its 2.5 pct discount +rate soon, possibly before Prime Minister Yasuhiro Nakasone +leaves for Washington on April 29. + Bank of Japan governor Satoshi Sumita will be in Osaka, +western Japan on April 27 and 28 for the annual meeting of the +Asian Development Bank, making a rate cut announcement early +next week a virtual impossibility, they said. April 29 is a +holiday here. + REUTER + + + +23-APR-1987 22:49:55.57 +interest +australia + + + + + + +RM +f3162reute +u f BC-NATIONAL-MUTUAL-CUTS 04-23 0068 + +NATIONAL MUTUAL CUTS AUSTRALIAN PRIME TO 17.75 PCT + MELBOURNE, April 24 - National Mutual Royal Bank Ltd said +it would cut its prime rate to 17.75 pct from 18.25, effective +April 27. + The cut follows a trend toward lower rates started last +month and accelerated by Westpac Banking Corp, which yesterday +cut its prime to 17.50 pct from 18.25 pct. Westpac's 17.50 pct +is the lowest prevailing rate. + REUTER + + + +23-APR-1987 23:12:19.63 +acq +australiacanada + + + + + + +F +f3171reute +u f BC-ELDERS-PURCHASE-OF-CA 04-23 0102 + +ELDERS PURCHASE OF CANADIAN BREWER APPROVED + SYDNEY, April 24 - Elders IXL Ltd <ELXA.S> said the +Canadian government approved its bid for <Carling O'Keefe Ltd>. + Elders earlier announced it was buying 10.9 mln shares, or +50.1 pct of Carling, from the Canadian subsidiary of Rothmans +International Plc <ROT.L> for 18 Canadian dlrs each. + Elders chairman John Elliott said in a statement when the +offer for the ordinary shares closed on April 23, that +acceptances representing over 93 pct of outstanding shares had +been received. <IXL Holdings> would proceed to acquire the rest +compulsorily, he said. + REUTER + + + +23-APR-1987 23:51:21.93 +crude +ecuadorcolombia + +opec + + + + +RM +f3186reute +u f BC-ECUADOR-TO-USE-COLOMB 04-23 0106 + +ECUADOR TO USE COLOMBIA OIL LINK FOR FIVE YEARS + BOGOTA, April 23 - Ecuador will use a new pipeline link +with Colombia to export crude oil for the next five years, +Colombian mines and energy minister Guillermo Perry said. + The link will be inaugurated on May 8. It was built to +allow Ecuador to resume exports of crude oil halted on March 5 +by earthquake damage to its Lago Agrio to Balao pipeline, + Once that pipeline is repaired, Ecuador will exceed its +OPEC quota in order to offset lost income and pay debts +contracted with Venezuela and Nigeria since the quake, Ecuador +mines and energy minister Javier Espinosa said. + The two ministers were speaking at a news conference after +signing an agreement for joint oil exploration and exploitation +of the jungle border zone between the two nations. Drilling +will begin in September. + "The agreement to transport Ecuadorean crude oil is not only +for this emergency period but for the next five years, with +possibility of an extension. Between 20,000 and 50,000 barrels +per day (bpd) will be pumped along it," Perry said. + Espinosa said Ecuador planned to pump 35 mln barrels +through the link in the next five years, at a cost of 75 cents +per barrel during the first year. + The 43-km link, with a maximum capacity of 50,000 bpd, will +run from Lago Agrio, the centre of of Ecuador's jungle +oilfields, to an existing Colombian pipeline that runs to the +Pacific port of Tumaco. + Espinosa said the 32-km stretch of the link built on the +Ecuadorean side cost 10.5 mln dlrs. Perry gave no figures for +Colombia's 11 km segment but said it was "insignificant compared +with what we are going to earn." + OPEC member Ecuador was pumping around 250,000 bpd before +the quake. Lost exports of 185,000 bpd are costing it 90 mln +dlrs per month, Espinosa said. + REUTER + + + +23-APR-1987 23:57:39.18 + +indonesia + + + + + + +RM +f0001reute +u f BC-SUHARTO-PARTY-SET-FOR 04-23 0107 + +SUHARTO PARTY SET FOR EASY WIN IN INDONESIA POLLS + JAKARTA, April 24 - President Suharto's ruling Golkar party +appears to have made substantial gains with over 75 pct of the +votes counted in Indonesia's national elections. + Figures released by the election commission showed Golkar +on target to take 70 pct of the vote. + Provisional figures indicate that with results of 68.9 mln +ballots announced, Golkar had won 50.29 mln, the Moslem-based +United Development Party 10.93 mln and the nationalist +Democratic Party 7.69 mln. + The total electorate is 94 mln and officials said they +thought about 90 pct of the votes had been counted. + + + +24-APR-1987 06:10:35.04 + +denmark + + +zse + + +F +f0368reute +r f BC-DENMARK'S-NOVO-INDUST 04-24 0108 + +DENMARK'S NOVO INDUSTRI GETS SWISS SHARE LISTING + COPENHAGEN, April 24 - Danish-based insulin and enzymes +producer Novo Industri A/S <NVO.CO> said in a statement that +its "B" shares would be listed on stock exchanges in Zurich, +Basel and Geneva from May 4. + The aim is to create broader European interest in Novo +stock, currently listed in Copenhagen, London and New York, +said the statement issued after yesterday's ordinary general +meeting. + Novo said more than 50 pct of its B shares were owned by +U.S. Investors. The new listings, the first by a Danish company +on the Swiss exchanges, will not involve issuing of new share +capital. + REUTER + + + +24-APR-1987 06:16:49.25 +graincorn +taiwanusa + + + + + +G C +f0376reute +u f BC-TAIWAN-TO-TENDER-UP-T 04-24 0088 + +TAIWAN TO TENDER UP TO 87,000 TONNES OF U.S. MAIZE + TAIPEI, April 24 - The joint committee of Taiwan's maize +importers will tender on April 29 for two cargoes of U.S. +Maize, totalling between 54,000 and 87,000 tonnes for delivery +between May 21 and June 25, a committee spokesman told Reuters. + Taiwan has set a calendar 1987 import target of 2.92 mln +tonnes compared with imports of 3.05 mln in 1986. About 80 pct +of the imports are expected to come from the U.S. And the rest +from South Africa, the spokesman said. + REUTER + + + +24-APR-1987 06:18:18.37 +money-fx +switzerland +languetin + + + + +RM +f0379reute +u f BC-SWISS-COMMITTED-TO-JO 04-24 0106 + +SWISS COMMITTED TO JOINT CURRENCY INTERVENTION + BERNE, April 24 - The Swiss National Bank will continue to +take part in concerted intervention on currency markets as +necessary, president Pierre Languetin told the bank's annual +meeting. + He said the dollar had on occasion hit highs or lows which +bore no relation to economic fundamentals and cooperation +between all monetary authorities was necessary to prevent it +breaching thresholds that would damage everyone. + "We are resolved -- as we have done in the past -- to take +part in concerted intervention to the extent that this is +possible and desirable," Languetin said. + Languetin said Switzerland had noted with satisfaction the +six nation Paris accord on currency stabilisation measures in +February, adding that it had anchored the principle of +strengthened international cooperation. + He said measures such as recent concerted intervention were +useful in the short term. + But he added, "The (Paris) Louvre accord can produce no +lasting effects without a correction of the fundamental +imbalances, without a reduction of the American budget deficit +and without stronger growth in Europe and Japan." + Languetin said certain changes would probably be necessary +in the "too expansive" monetary policy of the United States, +adding that there was a prevailing view that U.S. Money supply +was expanding too strongly. + "If this should last long the dollar could only be +stabilised at the cost of a substantial easing in monetary +policy on the part of the other central banks, which would in +turn create the basis for a new wave of world-wide inflation," +he said. One positive factor was that monetary authorities in +the most important countries had not relinquished their +anti-inflation policies. + REUTER + + + +24-APR-1987 06:34:22.72 +sugar +japancuba + + + + + +C T +f0409reute +u f BC-JAPANESE-BUYERS-ACCEP 04-24 0103 + +JAPANESE BUYERS ACCEPT CUBA SUGAR DELAY - TRADERS + TOKYO, April 24 - Several Japanese buyers have accepted +postponement of between 150,000 and 200,000 tonnes of Cuban raw +sugar scheduled for delivery in calendar 1987 until next year +following a request from Cuba, trade sources said. + Cuba had sought delays for some 300,000 tonnes of +deliveries, they said. It made a similar request in January +when Japanese buyers agreed to postpone some 200,000 tonnes of +sugar deliveries for 1987 until 1988. + Some buyers rejected the Cuban request because they have +already sold the sugar on to refiners, they added. + Japanese buyers are believed to have contracts to buy some +950,000 tonnes of raw sugar from Cuba for 1987 shipment. + But Japan's actual raw sugar imports from Cuba are likely +to total only some 400,000 to 450,000 tonnes this year, against +576,990 in 1986, reflecting both the postponements and sales +earlier this year by Japanese traders of an estimated 150,000 +tonnes of Cuban sugar to the USSR for 1987 shipment, they said. + They estimated Japan's total sugar imports this year at 1.8 +mln tonnes, against 1.81 mln in 1986, of which Australia is +expected to supply 550,000, against 470,000, South Africa +350,000, against 331,866, and Thailand 400,000, after 390,776. + REUTER + + + + diff --git a/src/test/data/reuters-21578/reut2-018.sgm b/src/test/data/reuters-21578/reut2-018.sgm new file mode 100644 index 00000000000..c76821e7baa --- /dev/null +++ b/src/test/data/reuters-21578/reut2-018.sgm @@ -0,0 +1,2004 @@ + + + 2-JUN-1987 10:04:07.81 +cpi +brazil +sarney + + + + +C +f1027reute +u f BC-BRAZIL'S-SARNEY-DECLA 06-02 0092 + +BRAZIL'S SARNEY RENEWS CALL FOR WAR ON INFLATION + BRASILIA, June 2 - President Jose Sarney today declared "a +war without quarter" on inflation and said the government would +watch every cent of public expenditure. + Sarney, addressing his cabinet live on television, also +reiterated that he intended to remain in power for five years, +until 1990. There has been a long-running political debate +about how long his mandate should be. + Brazil is currently suffering from the worst inflation of +its history. In April monthly inflation reached 21 pct. + Reuter + + + + 2-JUN-1987 10:04:26.11 + + +reaganvolckergreenspan + + + + +V RM +f1030reute +f f BC-******REAGAN-SAYS-VOL 06-02 0014 + +******REAGAN SAYS VOLCKER WILL NOT ACCEPT 3rd TERM AS FED CHAIRMAN, NOMINATES GREENSPAN +Blah blah blah. + + + + + + 2-JUN-1987 10:05:19.67 + +usa + + + + + +V RM +f1034reute +b f BC-/U.S.-HOME-SALES-ROSE 06-02 0079 + +U.S. HOME SALES ROSE 7.6 PCT IN APRIL + WASHINGTON, June 2 - Sales of new, single-family homes rose +7.6 pct in April from March to a seasonally adjusted annual +rate of 777,000 units, the Commerce Department said. + The department revised March sales to show a 2.7 pct +decrease from the previous month to 722,000 units instead of +the previously reported 3.6 pct drop in March. + The April increase brought home sales 12.0 pct below the +April, 1986, level of 883,000 units. + The April increase brought home sales to the highest level +since last April's 883,000 units. + The Commerce Department said that before seasonal +adjustment, the number of homes actually sold in April was +76,000, up from 71,000 in March but down from 84,000 in April, +1986. + The average price was 118,800 dlrs in April, down from +121,200 dlrs in March but up from 110,300 dlrs a year ago. + The median price was unchanged from March at 99,000 dlrs +but up from 92,500 dlrs in April, 1986, the department said. + Reuter + + + + 2-JUN-1987 10:06:06.42 + +uk + + + + + +RM +f1036reute +b f BC-BRIXTON-ESTATE-LAUNCH 06-02 0075 + +BRIXTON ESTATE LAUNCHES UNLIMITED STG CP PROGRAM + LONDON, June 2 - Brixton Estate Plc is establishing a +sterling commercial paper program for an unlimited amount, J. +Henry Schroder Wagg and Co Ltd said as arranger. + Dealers will be Schroder Wagg, S.G. Warburg and Co Ltd and +County Natwest Capital Markets Ltd. + The paper will be issued in denominations of 500,000 and +one mln stg and will have maturities between seven and 364 +days. + REUTER + + + + 2-JUN-1987 10:06:53.99 + +usa +reaganvolckergreenspanjames-baker + + + + +V RM +f1037reute +b f BC-REAGAN-FED 06-02 0043 + +REAGAN SAYS VOLCKER WILL NOT SERVE NEW TERM + WASHINGTON, June 2 - President Reagan said Paul Volcker has +declined to serve another term as chairman of the Federal +Reserve Board, the U.S. central bank. Reagan +nominated economist Alan Greenspan in his place. + Volcker's term expires in August. + Reagan, in a brief announcement in the White House briefing +room, said he accepted Volcker's decision "with great reluctance +and regret." + Volcker, first appointed to the Fed post by President Jimmy +Carter in 1979, said "there is a time to leave and a time to +come ... I have no feeling I was being pushed." + Volcker, appearing with Reagan, Greenspan, and Treasury +Secretary James Baker in the briefing room, said he will remain +on the job until Greenspan's nomination is approved by the +Senate. + In a tribute to a smiling Volcker standing beside him, +Greenspan told reporters that one of the departing chairman's +greatest achievements was reducing inflation. + "It will be up to those of us who follow him to be certain +that those very hard won gains will not be lost. Assuring that +will be one of my primary goals," Greenspan said. + Financial markets reacted with dismay at the departure of +Volcker, who has been widely credited with holding the line on +inflation and seeking to maintain stability in currency values. + Immediately following Reagan's announcement, the U.S. +dollar weakened sharply against all major currencies and both +the bond and stock markets declined. + But Greenspan told reporters he thought the dollar, which +has fallen sharply over the past year, has reached its low +point. + + "There certainly is evidence in that direction," Greenspan +said when reporters asked if the dollar has bottomed out. + The market reaction was probably exaggerated by surprise +because the announcement followed a number of published reports +that the White House had decided to reappoint Volcker. + Volcker's tenure at the Fed began under the cloud of major +inflation under Carter with consumer prices rising more than 10 +per cent annually and the prime interest rate exceeding 20 per +cent. + + With Reagan's backing, Volcker pursued a tight money policy +that cut inflation to about three per cent annually and reduced +interest rates to their lowest level in nearly a decade. + The tight money policies were also blamed for producing +a deep recession in 1981 and 1982 that caused major political +problems for Reagan. + Reagan reappointed Volcker to the chairmanship in 1983. + + Greenspan, who heads his own Wall Street consulting firm, +was chairman of President Ford's Council of Economic Advisers +from September 1974 until January 1977. + Greenspan, a Republican, is considered a traditional +conservative economist and has been an adviser to several +presidents. + Reuter + + + + 2-JUN-1987 10:11:04.12 + +belgium + + + + + +RM +f1051reute +u f BC-BELGIAN-PUBLIC-SPENDI 06-02 0106 + +BELGIAN PUBLIC SPENDING DEFICIT FALLS IN MAY + BRUSSELS, June 2 - Belgium's public expenditure deficit +fell sharply to 59.5 billion francs in May from 96.7 billion in +the same month last year, the first major sign of the effects +of the government's public spending curbs, the Budget Ministry +said. + During the first five months of this year, the net +government financing requirement was down by 44.1 billion +francs from year ago levels at 345.8 billion francs, it said in +a statement. + The government is aiming to cut this year's financing +requirement to below 420 billion francs this year from around +560 billion in 1986. + The Ministry said it was expected that more than half the +projected cut should have been achieved by the end of July. + Ministry sources noted that for technical reasons, the +financing requirement is always highest in the early months of +the year. + REUTER + + + + 2-JUN-1987 10:11:37.96 + +switzerland + + + + + +RM +f1055reute +u f BC-CHRISTIANIA-RAISES-AM 06-02 0091 + +CHRISTIANIA RAISES AMOUNT OF GOLD LINKED BOND + ZURICH, June 2 - Norway's Christiania Bank <CHBO.OL> is +increasing the size of its 2-1/2 pct seven year bond issue with +gold call and put warrants to 75 mln Swiss francs from 50 mln, +lead manager Bank Gutzwiller, Kurz, Bungener Ltd said. + The issue is priced at par. + Each 5,000 franc bond carries three 18 month call warrants +with a strike price of 490 dlrs and four three year put +warrants with a strike price of 420 dlrs. + Subscriptions close on June 22 and payment date is July 8. + REUTER + + + + 2-JUN-1987 10:13:22.63 + +usa + + + + + +V RM +f1060reute +b f BC-/U.S.-FACTORY-ORDERS 06-02 0107 + +U.S. FACTORY ORDERS ROSE 0.2 PCT IN APRIL + WASHINGTON, June 2 - New orders for manufactured goods rose +401 mln dlrs, or 0.2 pct, in April to a seasonally adjusted +199.8 billion dlrs, the Commerce Department said. + The slight April gain followed a revised orders increase in +March of 2.6 pct. The department originally reported a March +increase of 2.3 pct. Excluding defense, factory orders fell 0.2 +pct in April after rising 1.1 pct in March. + Orders for durable goods were virtually unchanged in April, +up only 13 mln dlrs to 106.2 billion dlrs. The department had +estimated on May 22 that April durable goods orders rose 0.1 +pct. + The department said defense capital goods orders were up +808 mln dlrs, or 8.1 pct, in April to 10.8 billion dlrs. +Defense orders had risen 43.2 pct in March. + New orders for non-durable goods were up 388 mln dlrs, or +0.4 pct, in April to 93.6 billion dlrs. + These figures compared with a March increase of 4.2 pct in +durables orders and a 0.8 pct rise in non-durables orders. + Orders for non-defense capital goods were up 0.8 pct in +April after rising 2.0 pct in March. + Within major industry categories orders for transportation +equipment fell 7.6 pct in April after rising 10.8 pct in March. + Primary metals gained 5.4 pct in April after a 6.8 pct +March orders increase. + Orders for non-electrical machinery were down 0.9 pct in +April after rising 2.3 pct in March. Electrical machinery +orders rose during April by 19.3 pct after falling in March by +3.4 pct. + Reuter + + + + 2-JUN-1987 10:13:44.37 +gnp +pakistan + + + + + +RM +f1062reute +r f BC-PAKISTAN-SAYS-GOOD-EC 06-02 0107 + +PAKISTAN SAYS GOOD ECONOMIC GROWTH CONTINUES + ISLAMABAD, June 2 - Pakistan says its economy has continued +its recent outstanding performance during the financial year +1986/87 ending on June 30 but areas like balance of payments, +investments and energy were causing concern. + GDP grew in line with the average growth rate since 1980 +and the inflation rate was the lowest since 1969/70, according +to a government economic survey. + The reform of economic regulation had gathered momentum +and there was an impressive performance in a five point +government program for rural uplift, education and poverty +alleviation, said the survey. + Ministry Economic Adviser Qazi Alimullah told a news +conference that before recent unseasonal rains and hailstorms +damaged the wheat crop, GDP growth was calculated at 7.04 pct +compared to 7.25 pct in 1985/86.He said the figure might now +slide down a little to around 6.8 or 6.9 pct. + The survey said monetary expansion was estimated to be nine +pct to date but might rise to around 12 pct by the year-end. + Alimullah said exports rose 18 pct to 3.5 billion dlrs from +2.9 billion dlrs in 1985/86. But the at the same time, home +remittances by Pakistanis abroad dropped to 2.3 billion dlrs +from the 1985/86 level of 2.595 billion. + More exports and an improvement in the balance of payments +situation will be required to overcome this declining trend in +home remittances, he said. + The survey said the trade deficit was expected to fall to +2.4 billion dlrs from three billion dlrs in 1985/86 because of +the boost in exports. + He said national investment continued to be small because +of a poor rate of savings, about 14 pct of GDP. He said more +savings were required to maintain or possibly step up the +present growth rate and to finance the country's seventh +five-year development plan to be launched in July 1988. + REUTER + + + + 2-JUN-1987 10:18:10.62 +money-fxdlr + +greenspan + + + + +V RM +f1077reute +f f BC-******GREENSPAN-SAYS 06-02 0010 + +******GREENSPAN SAYS THERE IS EVIDENCE DOLLAR HAS BOTTOMED OUT +Blah blah blah. + + + + + + 2-JUN-1987 10:20:19.41 +interest + + + + + + +RM +f1084reute +f f BC-BANK-OF-FRANCE-LEAVES 06-02 0013 + +******BANK OF FRANCE LEAVES INTERVENTION RATE UNCHANGED AT 7-3/4 PCT - OFFICIAL +Blah blah blah. + + + + + + 2-JUN-1987 10:21:40.24 +money-fxdlr +usa +greenspan + + + + +V RM +f1090reute +u f BC-/GREENSPAN-SEES-EVIDE 06-02 0060 + +GREENSPAN SEES EVIDENCE DOLLAR FALL OVER + WASHINGTON, June 2 - Newly-nominated Federal Reserve Board +chairman Alan Greenspan said there was evidence the dollar +finally had bottomed out. + In a White House briefing Greenspan was asked by reporters +if he thought the dollar had bottomed out. + "There certainly is evidence in that direction," he replied. + Reuter + + + + 2-JUN-1987 10:22:29.78 +goldsilverplatinum + +volcker + + + + +V RM +f1091reute +f f BC-******U.S.-GOLD,-SILV 06-02 0012 + +******U.S. GOLD, SILVER, PLATINUM SOAR ON VOLCKER REJECTION OF 3RD TERM +Blah blah blah. + + + + + + 2-JUN-1987 10:25:00.56 +cocoa +uk + +icco + + + +C T +f1106reute +b f BC-ICCO-BUYS-5,000-TONNE 06-02 0063 + +ICCO BUYS 5,000 TONNES COCOA FOR BUFFER STOCK + LONDON, June 2 - The International Cocoa Organization +(ICCO) buffer stock manager bought 5,000 tonnes of cocoa today +for the buffer stock, traders said. + The cocoa is believed to have been entirely made up of +second hand material, they added. + Such a purchase would bring cumulative buffer stock +purchases to 26,000 tonnes. + Reuter + + + + 2-JUN-1987 10:27:58.21 + +usa + + + + + +F +f1123reute +u f BC-YANKEE-COS-<YNK>-SEEK 06-02 0063 + +YANKEE COS <YNK> SEEKS DEBT RESTRUCTURING + COHASSET, Mass., June 2 - Yankee Cos Inc said it will be +working with the holders of substantially all of its 12-5/8 pct +senior secured notres due 1996 to develop and overall debt and +asset restructuring program, and as a first step, the +noteholder has agreed to the deferral of the June One interest +payment on the notes until June 30. + Yankee said interest was paid to other noteholders +yesterday. + The company said it plans to meet and work with all +interest parties, including the holders of its three debt +issues and federal banking authorities, over the next several +weeks to formulate and implement a restructuring plan. + Reuter + + + + 2-JUN-1987 10:29:27.94 + +usa + + + + + +F +f1132reute +u f BC-Q-MED-<QEKG.O>-SEES-S 06-02 0106 + +Q-MED <QEKG.O> SEES SHARPLY HIGHER REVENUES + CLARK, N.J., June 2 - Q-Med Inc said preliminary results +show its second quarter, ended May 31, revenues exceeded 4.2 +mln dlrs. A year earlier revenues were nearly 1.4 mln dlrs. + The company also said it had appointed Coopers and Lybrand +as its auditors. Chairman Michael Cox declined any comment on +this appointment. + The company said its preliminary second quarter revenues +are consistent with management's expectations and represent a +greater than 40 pct increase in sales over those reported for +the first quarter. Earnings should show a similar growth +pattern, the company added. + Reuter + + + + 2-JUN-1987 10:29:31.47 +acq +usa + + + + + +F +f1133reute +u f BC-ACME-PRECISION-<ACL> 06-02 0028 + +ACME PRECISION <ACL> BUYOUT BID DROPPED + DETROIT, June 2 - Acme Precision Products Inc said a +management group has withdrawn a six dlr per share leveraged +buyout offer. + Acme said the management group dropped its bid due to +continued weakness in the machine tool industry and in Acme +Precision's operating results and to the inability of the +management group to obtain modifications to terms of its +financing commitment. + It said, "The effect of these factors led the management +group to conclude that the six dlr per share price was +excessive under current conditions." + Reuter + + + + 2-JUN-1987 10:29:53.30 + +usa + + + + + +A RM +f1136reute +r f BC-DOMINION-<D>-UNIT-SEL 06-02 0111 + +DOMINION <D> UNIT SELLS 30-YEAR BONDS + NEW YORK, June 2 - Virginia Electric and Power Co, a unit +of Dominion Resources Inc, is raising 100 mln dlrs via an +offering of first and refunding mortgage bonds due 2017 +yielding 9.89 pct, said sole manager E.F. Hutton and Co Inc. + Hutton led a group that won the bonds in competitive +bidding. It bid them at 99.376, representing a net interest +charge to the company of 9.94 pct. + The underwriter set a 9-7/8 pct coupon and reoffering price +of 99.85 to yield 123 basis points more than comparable +Treasury securities. Non-refundable for five years, the bonds +are rated A-1 by Moody's and A-plus by Standard and Poor's. + The gross spread is four dlrs and the reallowance is 2.50 +dlrs, bookrunner Hutton said of the Virginia Electric deal. + Virginia Electric last visited the domestic debt market in +October 1986 when it sold 100 mln dlrs of same-rated, +same-maturity 9-1/4 pct bonds. That issue was priced to yield +9.27 pct, or 141 basis points over Treasuries. + Reuter + + + + 2-JUN-1987 10:30:02.50 + +usa + + + + + +F +f1137reute +r f BC-GENERAL-SIGNAL-<GSX> 06-02 0073 + +GENERAL SIGNAL <GSX> LOW BIDDER ON RADIO JOB + STAMFORD, Conn., June 2 - General Signal Corp said its +General Railway Signal Co unit is the apparent low bidder at +32.5 mln dlrs on a transit radio system contract for the +Southern California Rapid Transit District in Los Angeles. + The company also said its General Farebox Inc subsidiary +received a 3.1 mln dlr farebox system contract from the Greater +Cleveland Regional Transit Authority. + Reuter + + + + 2-JUN-1987 10:30:24.62 + +usa + + + + + +F +f1141reute +r f BC-WILLIAMS-<WMB>-REINCO 06-02 0034 + +WILLIAMS <WMB> REINCORPORATES IN DELAWARE + TULSA, June 2- Williams Cos said it has been reincorporated +in Delaware as Williams Cos Inc following approval by +shareholders at the annual meeting last month. + Reuter + + + + 2-JUN-1987 10:30:58.70 + +usa + + + + + +A RM +f1142reute +r f BC-NOBLE-AFFILIATES-<NBL 06-02 0112 + +NOBLE AFFILIATES <NBL> SELLS CONVERTIBLE DEBT + NEW YORK, June 2 - Noble Affiliates Inc is raising 100 mln +dlrs via an offering of convertible subordinated debentures due +2012 with a 7-1/4 pct coupon and par pricing, said lead +underwriter Morgan Stanley and Co Inc. + The debentures can be converted into the company's common +stock at 19.625 dlrs per share, representing a premium of 25.6 +pct over the stock price when terms on the debt were set. + Non-callable for three years, the issue is rated Baa-3 by +Moody's and BBB-plus by Standard and Poor's. Noble Affiliates +is also offering 125 mln dlrs of 10-1/8 pct notes due 1997 +through a group led by Morgan Stanley. + Reuter + + + + 2-JUN-1987 10:31:26.20 + +usa + + +nasdaq + + +F +f1146reute +r f BC-MERIDIAN-INSURANCE-<M 06-02 0033 + +MERIDIAN INSURANCE <MIGI.O> IN NASDAQ EXPANSION + INDIANAPOLIS, June 2 - Meridian Insurance Group Inc said +its common stock has been included in the NASDAQ National +Market System, effective today. + Reuter + + + + 2-JUN-1987 10:33:30.27 + +uk + + + + + +RM +f1161reute +b f BC-CANON-SALES-ISSUES-10 06-02 0104 + +CANON SALES ISSUES 100 MLN DLR WARRANT BOND + LONDON, June 2 - Canon Sales Co Inc is issuing a 100 mln +dlr equity warrant bond due June 30, 1992 with an indicated +coupon of 1-5/8 pct and par pricing, lead manager Yamaichi +International (Europe) Ltd said. + The issue is guaranteed by Fuji Bank Ltd and final terms +will be set on June 9. The selling concession is 1-1/2 pct +while management and underwriting combined pays 3/4 pct. The +deal is available in denominations of 5,000 dlrs and will be +listed in Luxembourg. + The warrants are exercisable from July 15, until June 23, +1992. The payment date is June 30. + REUTER + + + + 2-JUN-1987 10:35:06.58 +grainbarley +italy + + + + + +G +f1173reute +d f BC-ITALIAN-BARLEY-CROP-R 06-02 0085 + +ITALIAN BARLEY CROP REPORTED IN GOOD CONDITION + ROME, June 2 - Italy's barley crop is generally in good +condition and harvesting is expected to begin shortly, the +agricultural marketing information and research board Irvam +said. + First consignments were expected to be available around +mid-June. + Excellent weather, characterised by alternating periods of +sunshine and rain, has encouraged growth except in Sardinia, +which was expected to lose a large part of its barley crop +because of extreme dryness. + Irvam said yields are expected higher than last year's low +levels if favourable weather continues in the next few weeks. + Given an average yield of 3.5 tonnes per hectare, national +production would be around two pct higher than in the previous +season at just above 1.6 mln tonnes, it said. + If yields reach the record 3.78 tonnes per hectare achieved +in 1984, production would be around 1.75 mln tonnes, an +increase of 11 pct compared to 1986. + Reuter + + + + 2-JUN-1987 10:35:41.13 + +uk + + + + + +RM +f1176reute +b f BC-ASIAN-DEVELOPMENT-BAN 06-02 0082 + +ASIAN DEVELOPMENT BANK ISSUES 50 MLN STG EUROBOND + LONDON, June 2 - The Asian Development Bank is issuing a 50 +mln stg eurobond due July 1, 1997 paying 9-1/2 pct and priced +at 101-7/8 pct, lead manager County Natwest Capital Markets Ltd +said. + The non-callable bond is available in denominations of +1,000 and 10,000 stg and will be listed in Luxembourg. + The selling concession is 1-3/8 pct while management and +underwriting combined pays 5/8 pct. + Payment date is July 1. + REUTER + + + + 2-JUN-1987 10:38:09.89 + +usa + + + + + +F +f1191reute +r f BC-DATA-GENERAL-<DGN>-OF 06-02 0095 + +DATA GENERAL <DGN> OFFERS NEW NETWORK PRODUCTS + NEW YORK, June 2 - Data General Corp said it introduced +several new hardware and software products that link +International Business Machines Corp <IBM> and IBM-compatible +personal computers into mainframe and minicomputer systems. + Data General said the products include three local area +networks that conform to industry standards. It said it is now +offering a Starlan network, which was originally introduced by +American telephone and Telegraph Co <t>, a thin Ethernet and a +PC interface for the standard Ethernet. + + In addition, Data General said it will offer several +software packages for PC networks, including MS Net, a product +developed by Microsoft Corp <MSFT.O> that allows PCs to share +printers, data files and other peripherals. + The company said it also introduced a PC version of its +popular CEO office automation software. + Data General said the new products allow computer users to +divide work among a collection of PCs and larger computers. + + "Data General is the first vendor to offer three different +local area networks for personal computer integration," said +Colin Crook, senior vice president of the company's +communications systems group. + "We're really giving users freedom of choice with industry +standard products," added J. David Lyons, vice president of +group marketing. + In addition to the new products, which were expected, Data +General announced a joint product development agreement with +<Gold Hill Computers>, a Cambridge, Mass.,-based artificial +intelligence software company. + + The company also announced the formation of a new network +services group that will help customers plan and design +computer networks. + The group will also provide service and maintenance for +Data General and other vendors' equipment, the company said. + Reuter + + + + 2-JUN-1987 10:38:33.20 + +usa + + + + + +F +f1194reute +r f BC-PERPETUAL-SAVINGS-<PA 06-02 0067 + +PERPETUAL SAVINGS <PASB.O> SETS HOLDING COMPANY + ALEXANDRIA, Va., June 2 - Perpetual Savings Bank said its +board has approved formation of a holding company to be +incorporated in Virginia, subject to Federal Home Loan Bank +Board and shareholder approval. + It said its common and prefered shares would be exchanged +on a one-for-one basis for shares of the holding company, +Perpetual Financial corp. + Reuter + + + + 2-JUN-1987 10:39:23.41 +earn +usa + + + + + +F +f1200reute +u f BC-PEP-BOYS---MANNY,-MOE 06-02 0046 + +PEP BOYS - MANNY, MOE AND JACK INC <PBY> 1ST QTR + PHILADELPHIA, June 2 - May Two net + Shr 11 cts vs eight cts + Net 5,895,000 vs 3,896,000 + Sales 127.3 mln vs 110.5 mln + NOTE: Share adjusted for three-for-one stock split payable +July 27 to holders of record July One. + Reuter + + + + 2-JUN-1987 10:40:26.29 +acq +canada + + + + + +E F +f1202reute +r f BC-elders-says-bid-made 06-02 0100 + +ELDERS HAPPY TO LEAVE CARLING SHARES OUTSTANDING + TORONTO, June 2 - Elders IXL Ltd <ELXA.S> says it is happy +to leave preferences shares of brewer Carling O'Keefe Ltd +outstanding after an undisclosed bidder made an offer to +acquire all of Carling's outstanding preferred stock. + Elders, which owns 100 pct of Carling's outstanding common +shares, previously proposed to redeem the 433,745 Carling +series A preferred shares at 33.50 Canadian dlrs each and +redeem the 386,662 series B preferreds at 40 dlrs a share. + The series A and B preferred shares carry no vote while +dividends are paid. + + Elders says neither it nor Carling knows the identity of +the bidder for Carling's preferred shares. + On May 29, the bidder offered to acquire the Carling +preferred for 36 dlrs for each series A and 40.50 dlrs for each +series B share. + Elders said leaving the Carling preferred shares +outstanding will not affect ongoing plans of the company. + Series B preferred shareholders had previously rejected +Carling's proposal to redeem the shares and a series A +preferred shareholders meeting was adjourned to June 12. + Reuter + + + + 2-JUN-1987 10:40:39.77 + +belgium + +ec + + + +C G T +f1203reute +r f BC-EC-FARM-MINISTERS-DIS 06-02 0116 + +EC FARM MINISTERS DISAGREE ON DIRECT INCOME AIDS + GENVAL, Belgium, June 2 - Plans to provide direct income +aids for European Community (EC) small farmers to help them +face deep cuts in guaranteed crop prices received a mixed +reception from EC agriculture ministers, EC officials said. + The plans were discussed at an informal meeting of the +ministers hosted in the village of Genval by the Council of +Ministers' current chairman, Belgium's Paul de Keersmaeker. + The EC Executive Commission has proposed that the richer +member states be allowed to make direct payments to their +farmers in special difficulties, while the EC itself would +finance a similar scheme in the poorer EC countries. + However, EC officials said only the Netherlands and +Luxembourg supported this idea at today's meeting, and France, +Denmark and Belgium showed marked hostility to it. + French minister Francois Guillaume told reporters, "Farmers +should not become recipients of public assistance -- their +survival should be assured by price mechanisms and the market." + The officials said the ministers had not sought to resolve +their more urgent differences over guaranteed farm prices for +1987/88 at this meeting. + The ministers will resume talks on the price fixing issue +in Luxembourg on June 15. + Reuter + + + + 2-JUN-1987 10:44:13.90 + +usa + + + + + +F +f1226reute +d f BC-ONE-OF-TWO-SARA-LEE-< 06-02 0098 + +ONE OF TWO SARA LEE <SLE> STRIKES SETTLED + DEERFIELD, ILL., June 2 - Sara Lee Corp said 500 workers at +its Kitchens of Sara Lee bakery operation in Deerfield, Ill., +have returned to work this week after ratifying a contract. + A company spokesman said members of Local Two of the +Bakery, Confectionery and Tobacco Workers, who had walked out +May 10, reached "mutually agreeable terms" in a new two-year +contract. + Meanwhile, about 100 Teamster drivers and warehouse +employees, whose contract expired May 16, remained out, the +company said. No new talks were scheduled, Sara Lee said. + Details of the new contract were not immediately available, +but a company spokesman said it "maintained benefits and called +for no sacrifices from current employees." + Union sources reported that the contract freezes wages and +introduces a sharply lower starting rate for new hires. They +said it also gives Sara Lee concessions on a workplace issue +involving excused absences. + Reuter + + + + 2-JUN-1987 10:44:26.34 + +usa + + + + + +F +f1228reute +d f BC-CRAY-<CYR>-GETS-3.6-M 06-02 0051 + +CRAY <CYR> GETS 3.6 MLN DLR COMPUTER ORDER + MINNEAPOLIS, June 2 - Cray Research Inc said Aerospatiale, +a French aerospace company, ordered a Cray X-MP/14se computer +system valued at about 3.6 mln dlrs. + It said the leased system will be installed in the fourth +quarter, pending export license approval. + Reuter + + + + 2-JUN-1987 10:48:49.65 + +portugal + + + + + +RM +f1246reute +u f BC-PORTUGAL-CONTRACTS-FO 06-02 0105 + +PORTUGAL CONTRACTS FOR 150 MLN ECU LOAN + LISBON, June 2 - Portugal has contracted a six-year, 150 +mln ECU loan from a group of foreign banks led by Daiwa Europe +Ltd to finance investment projects, the finance ministry said. + Interest of 7.75 pct is to be paid in annual instalments +starting in 1988, ministry spokesman Luis Vilhena de Cunha +said. + The loan will first be in the form of a temporary global +note and be replaced later by subscriptions of 1,000 and 10,000 +ECUs. The issue price was set at 101.75 pct. + Banque Generale du Luxembourg SA will act as listing agent +and fiscal agent, the spokesman added. + REUTER + + + + 2-JUN-1987 10:50:08.18 +carcass +usa + + + + + +C G L +f1251reute +b f BC-CHICKEN-NOT-MAIN-SALM 06-02 0140 + +CHICKEN NOT MAIN SALMONELLA CAUSE, OFFICIAL SAYS + WASHINGTON, June 2 - A representative of the poultry +industry said statistics showed that chicken is less frequently +the cause of salmonella poisoning than beef, dairy products or +salads and other mixed foods. + Kenneth May, President of Holly Farms Poultry Industries +and a director of the National Broiler Council, told a House +Agriculture subcommittee the incidence of salmonella in chicken +has not increased in recent years and that chicken is neither +the major source of the bacterial poisoning nor the cause of an +increase in outbreaks of the disease. + May said the Center for Disease Control figures showed that +between 1978 and 1982, chicken was involved in four pct of all +U.S. salmonellosis outbreaks, while beef accounted for ten pct +of outbreaks and dairy products six pct. + May said the remaining outbreaks were caused by salads and +mixed food, turkey, seafood, pork, eggs and other foods. + May said the chicken industry favored moving away from +bird-by-bird inspection procedures to a risk assessment system +better able to identify microbial and bacterial contamination +of poultry. + However, Ellen Haas, executive director of Public Voice for +Food and Health Policy, said bird-by-bird inspection should be +retained and labels should be attached to each ready-to-cook +chicken to remind consumers about preparation procedures +necessary to avoid illness. + Haas also called for a review of present chicken industry +inspection methods that she said can worsen poultry hazards. + Reuter + + + + 2-JUN-1987 10:51:10.96 +graincorn +usa + + + + + +C G +f1254reute +u f BC-/U.S.-HOUSE-PANEL-VOT 06-02 0110 + +U.S. HOUSE PANEL VOTES TO SPEED UP CORN PAYMENTS + WASHINGTON, June 2 - The House Agriculture Committee voted +to make approximately 2.8 billion dlrs of feedgrains deficiency +payments immediately instead of in the late fall. + A similar measure was decisively defeated on the Senate +floor last week. + The bill, which passed by a voice vote, would allow +so-called Findley payments to be made immediately rather than +late this year. Payments for 1987-90 feedgrains crops would not +be changed. + Because the bill would move 2.8 billion dlrs of spending +into fiscal 1987 from fiscal 1988, the measure is expected to +meet stiff resistance in the full House. + + Reuter + + + + 2-JUN-1987 10:51:16.67 +acq +usa + + + + + +F +f1255reute +u f BC-JONES-AND-VINING-<JNS 06-02 0031 + +JONES AND VINING <JNSV.O> STARTS BID FOR SHARES + BRAINTREE, Mass., June 2 - Jones and Vining Inc said it has +started a tender offer for all of its own shares at five dlrs +per share. + The company said it will hold a special meeting on July 10 +for a vote on approval of a merger at the tender price. + It said the price to be paid in the tender and merger could +be reduced by any fees and expenses the court may award to +counsel for the plaintiffs in the class action suit brought +against it in Delaware Chancery Court by Ronda Inc. The +plaintfiffs' counsel are seeking fees of up to 10 cts per +share, Jones and Vining said. + The company said the court has scheduled a hearing on the +proposed settlement of the suit for July Eight. + The company said the start of the tender offer and the +calling of the special meeting are conditions of the +settlement, and completion of the tender and merger are +conditioned on final approval of the settlement. + Reuter + + + + 2-JUN-1987 10:51:48.40 +acq +usa + + + + + +F +f1258reute +d f BC-HEALTHSOUTH-<HSRC.O> 06-02 0064 + +HEALTHSOUTH <HSRC.O> MAKES ACQUISITION + BIRMINGHAM, Ala., June 2 - HEALTHSOUTH Rehabilitation Corp +said it has acquired Pine Island Sports Medicine Center in Fort +Lauderdale, Fla., and will incorporate the facility into its +HEALTHSOUTH Rehabilitation Center of Fort Lauderdale, which is +now under construction and should be in operation by +mid-summer. + Terms were not disclosed. + Reuter + + + + 2-JUN-1987 10:51:55.69 +acq +usa + + + + + +F +f1259reute +d f BC-BANC-ONE-<ONE>-MAKES 06-02 0033 + +BANC ONE <ONE> MAKES INDIANA ACQUISITION + COLUMBUS, Ohio, June 2 - Banc One Corp said it has +completed the acquisition of First National Bank of +Bloomington, Ind, which has assets of 271 mln dlrs. + Reuter + + + + 2-JUN-1987 10:53:42.76 + +usa + + + + + +F +f1265reute +r f BC-PENTLAND-INDUSTRIES-P 06-02 0062 + +PENTLAND INDUSTRIES PLC HOLDERS APPROVE SPLIT + NEW YORK, June 2 - Pentland Industries PLC said +shareholders at the annual meeting approved an increase in +authorized share capital to 36 mln stg to 12 mln stg by +creation of another 240 mln ordinary shares, allowing for a +three-for-one stock split. + It said dealings in the new shares are expected to start on +June 15. + Reuter + + + + 2-JUN-1987 10:54:40.06 +acq +usa + + + + + +F +f1270reute +d f BC-ORION-BROADCAST-<OBGI 06-02 0079 + +ORION BROADCAST <OBGI.O> BUYS FORD <F> UNIT + DENVER, June 2 - Orion Broadcast Group Inc said its +majority-owned Orion Financial Services Corp subsidiary has +agreed to purchase FN Realty Services Inc from Ford Motor Co +for 1,200,000 to 1,500,000 dlrs in cash and notes. + It said closing is expected within 45 days after receipt of +regulatory approvals. + FN provides loan collection, accounting, data processing +and administrative services to the real estate industry. + Reuter + + + + 2-JUN-1987 10:54:52.48 + +luxembourg + +ec + + + +C G T +f1271reute +r f BC-EC-BUDGET-MINISTERS-S 06-02 0100 + +EC BUDGET MINISTERS SET TO REFUSE PLEA FOR CASH + LUXEMBOURG, June 2 - A plea for extra cash to bail the +European Community (EC) out of its latest financial crisis was +likely to be rejected at a meeting today of EC budget +ministers, diplomats said. + The ministers were meeting for the first time since the EC +Executive Commission unveiled an emergency budget for 1987 +aimed at plugging a deficit caused by soaring farm spending and +falling revenues. + The emergency package includes a demand for member states +to pay an extra 1.5 billion European currency units (Ecus) to +help meet the deficit. + Officials said Britain and West Germany were expected to +lead opposition to contributing any extra cash, with the U.K +insisting instead on a clampdown on runaway farm spending. + The Commission says there will be a shortfall of at least +five billion Ecus this year, more than 1/8 of total spending. + It hopes to make up much of the shortfall in a one-time +accounting exercise by paying member states in arrears rather +than in advance for their spending on Community farm policies. + But if member states do not make up the rest of the gap, +the Commission has warned that spending on regional and social +projects could be slashed by half. + Reuter + + + + 2-JUN-1987 10:55:50.84 + +usa + + + + + +F +f1273reute +h f BC-ORBIT-<ORBT.O>-UNIT-I 06-02 0083 + +ORBIT <ORBT.O> UNIT INCREASES BACKLOG + HAUPPAUGE, N.Y., June 2 - Orbit Instrument Corp said its +unit, Orbit Semiconductor Inc, has received orders totalling +about 2.5 mln dlrs which puts its backlog at a record level of +about 4.7 mln dlrs. + Additionally, the company said it will now offer two Micron +CMOS processes that can withstand Megarad total dose radiation. + Applications for the processes include products +manufactured for military, medical and power industry market, +the company said. + Reuter + + + + 2-JUN-1987 10:57:14.48 + +south-africa + + + + + +C M +f1281reute +u f BC-SOUTH-AFRICA-NAMES-1, 06-02 0100 + +SOUTH AFRICA SAYS 1,500 STILL DETAINEES + CAPE TOWN, June 2 - South Africa said the number of people +it was detaining without trial has dropped to 1,500, far fewer +than previous official figures during the past year of +emergency rule. + A government spokesman said the latest set of names, +presented to parliament, included all current detainees who had +been held for over a month. Previous lists have named up to +8,500 people. + The official figure was supported by civil rights groups +who said many detainees had been freed in recent weeks, +possibly to empty cells for a new government crackdown. + Reuter + + + + 2-JUN-1987 11:02:51.01 + +japan + + + + + +C G T +f1297reute +d f BC-JAPANESE-FARMERS-MARC 06-02 0098 + +JAPANESE FARMERS PROTEST OPENING MARKETS + TOKYO, June 2 - Thousands of farmers gathered in central +Tokyo to urge the government to stand firm against foreign +pressure for further opening up of Japan's markets to foreign +agricultural products, union officials said. + Officials of the Central Union of Agricultural Cooperatives +said about 5,000 representatives from 4,200 farming groups +joined the demonstration. + The organisers said the farmers demanded that the +government should avoid easy compromises on liberalising +agricultural imports at next week's economic summit in Venice. + The United States and the European Community want Japan to +remove tariffs and quotas to help cut their trade deficits with +Japan. + Under a banner reading "The government and parliament must +not sacrifice farmers," the demonstrators adopted a declaration +saying they would fight any unreasonable moves to open Japanese +markets to foreign agricultural products. + An agriculture ministry official said Japan and the United +States were expected to hold talks on Japanese import ceilings +for U.S. Beef and citrus fruit in September. + Reuter + + + + 2-JUN-1987 11:04:44.51 + + + + + + + +RM C G L M T F +f1303reute +b f BC-LONDON-GOLD-1500-FIX 06-02 0008 + +******LONDON GOLD 1500 FIX - JUNE 2 - 455.00 DLRS +Blah blah blah. + + + + + + 2-JUN-1987 11:07:06.07 + +norway +de-clercq +ec + + + +C G L M T +f1316reute +d f BC-FRESH-DEBATE-ON-NORWA 06-02 0091 + +FRESH DEBATE ON NORWAY'S EC MEMBERSHIP WELCOMED + OSLO, June 2 - European Community officials welcomed +Norway's recent move to renew a public debate on Community +membership but said Norway should not expect special trade +advantages as long as it stays outside the EC. + Belgian Willy de Clercq, EC Commissioner on external +affairs and trade policy, said high level talks this week with +Norway's minority Labour government had helped clarify several +misconceptions that led to Norway's narrow rejection of EC +membership in a 1972 referendum. + "But you (Norway) cannot be in the club and remain outside +the club. You can expect equal footing in the club, but not out +of it," de Clercq added, referring to Norway's attempts to adapt +its EC trade ties in the face of Community moves to launch an +internal trade market from 1992. + The government, worried that the internal market will +hamper trade with the EC, which takes about two-thirds of +Norway's exports, last month sent a report to parliament asking +political parties and the public to reassess the country's +relationship to the EC. + Reuter + + + + 2-JUN-1987 11:08:09.27 + + + + + + + +F +f1321reute +f f BC-******GULF-AND-WESTER 06-02 0009 + +******GULF AND WESTERN INC 2ND QTR SHR 86 CTS VS 73 CTS +Blah blah blah. + + + + + + 2-JUN-1987 11:08:48.90 +earn +usa + + + + + +F +f1325reute +u f BC-PHH-GROUP-INC-<PHH>-4 06-02 0057 + +PHH GROUP INC <PHH> 4TH QTR APRIL 30 NET + HUNT VALLEY, Md., June 2 - + Shr 71 cts vs 47 cts + Net 12.1 mln vs 7.8 mln + Revs 369.8 mln vs 307.9 mln + 12 mths + Shr 2.35 dlrs vs 2.33 dlrs + Net 39.5 mln vs 39 mln + Revs 1.36 billion vs 1.24 billion + NOTE: Prior year restated to reflect results from current +year acquisitions. + + Reuter + + + + 2-JUN-1987 11:10:13.59 + +usa +volcker + + + + +V RM +f1330reute +u f AM-VOLCKER-TEXT 06-02 0062 + +VOLCKER IN LETTER DECLINES NEW FED TERM + WASHINGTON, June 2 - Following is the full text of Federal +Reserve Board Chairman Paul Volcker's letter to President +Reagan declining reappointment to the Fed: + Dear Mr. President, + As the end of my term as chairman of the Federal Reserve +Board approaches, you naturally have to consider an appropriate +new appointment. + + In that connection, you will recall that, upon my +reappointment as chairman in 1983, I felt unable to make a firm +commitment to you or to the Congress to remain in office for a +second full four-year term. Despite my reservations at the +time, that term is in fact now almost finished. However, I do +think, after eight years as chairman, a natural time has now +come for me to return to private life as soon as reasonably +convenient and consistent with an orderly transition. +Consequently, I do not desire reappointment as chairman and I +plan to resign as governor when a new chairman is prepared to +assume office. + + I will be leaving with a sense of great appreciation for +your unfailing courtesy to me personally. More broadly, your +consistent support of the work of the Federal Reserve during a +particularly challenging period for it, for the financial +system, and for the economy has been critical to whatever +success we have had. + + Without doubt, strong challenges remain for all of those +involved in economic policy. In that effort, I believe the +nation will continue to be well served by a strong Federal +Reserve System -- a system firmly dedicated to fostering +economic and financial strength and stability and able to bring +to that effort a combination of sound and independent +professional judgement and continuity beyond any partisan +considerations. + + May I add, too, my personal best wishes for the remainder +of your own term in office during which you have done so much +to restore a sense of confidence and self-reliance among the +American people. + Faithfully yours, + Paul A Volcker + Reuter + + + + 2-JUN-1987 11:18:53.04 +money-fx +uk +lawson + + + + +RM +f1373reute +u f BC-LAWSON-CALLS-INTERVEN 06-02 0120 + +LAWSON CALLS INTERVENTION PROOF OF STABILITY GOAL + LONDON, June 2 - The scale of foreign exchange intervention +the Bank of England has carried out recently is clear proof of +Britain's determination to stabilise exchange rates as agreed +between the Group of Seven industrialised countries in Paris in +February, Chancellor of the Exchequer Nigel Lawson said. + Saying he was "content" with sterling's current value, Lawson +told reporters he wanted "to maintain the exchange rate +stability we have all signed up for." He declined to say if he +favoured a rise or a fall from present sterling levels. + May currency reserves, out today, showed a record 4.8 billion +stg rise, pointing to massive currency intervention. + In April, reserves rose a hefty 2.9 billion stg. + Pointing to the reserves data, Lawson said, "We have been +playing a very full part ourselves" in meeting our commitments +toward exchange rate stability as agreed in Paris. + "We wish to see it (stability) continuing," he added. + Asked which techniques were available to preserve +stability, Lawson said both central bank intervention and +interest rate changes could be used to tackle "the market +pressures there are from time to time." + "Interest rate stability is not an objective in that +sense...Rates have to be moved up and down at times," he added. + Lawson said he expected intervention to be "sterilised" by +draining excess sterling liquidity from the market through new +issues of government securities and foreign currency sales, +when the market allowed. + This would limit the inflationary impact of intervention, +he said. + "Sterilisation will be dictated by market tactics...Not +necessarily in the month in which intervention occurs," Lawson +said. "I am confident that we can sterilise on this scale." + REUTER + + + + 2-JUN-1987 11:19:19.10 +money-fxinterest +usa + + + + + +V RM +f1376reute +b f BC-/-FED-NOT-EXPECTED-TO 06-02 0071 + +FED NOT EXPECTED TO TAKE MONEY MARKET ACTION + NEW YORK, June 2 - The Federal Reserve is not expected to +intervene in the government securities market to add or drain +reserves at its usual intervention time this morning, +economists said. + With the Federal funds rate trading comfortably at 6-9/16 +pct, down from yesterday's 6.74 pct average, economists said +the Fed did not need to take reserve management action today. + Reuter + + + + 2-JUN-1987 11:19:50.44 +earn +usa + + + + + +F +f1379reute +b f BC-******GULF-AND-WESTER 06-02 0044 + +GULF AND WESTERN INC <GW> 2ND QTR APRIL 30 NET + NEW YORK, June 2 - + Shr 86 cts vs 73 cts + Net 52.7 mln vs 45.7 mln + Revs 989.9 mln vs 863.9 mln + Six mths + Shr 1.97 dlrs vs 1.28 dlrs + Net 122 mln vs 79.9 mln + Revs 2.078 billion vs 1.726 billion + Reuter + + + + 2-JUN-1987 11:20:12.43 + + + + + + + +F E +f1382reute +b f BC-******ALLEGIS-SAID-IT 06-02 0014 + +******ALLEGIS SAID IT IS CREATING A LIMITED PARTNERSHIP TO SELL SOME CANADIAN HOTELS +Blah blah blah. + + + + + + 2-JUN-1987 11:22:06.08 + + + + + + + +F +f1395reute +b f BC-******BROWN-GROUP-INC 06-02 0008 + +******BROWN GROUP INC 1ST QTR SHR 56 CTS VS 42 CTS +Blah blah blah. + + + + + + 2-JUN-1987 11:22:55.99 + + + + + + + +F E +f1402reute +b f BC-******ALLEGIS-SAID-IT 06-02 0013 + +******ALLEGIS SAID IT SEES PROCEEDS OF 350 MLN CANADIAN DLRS WHEN HOTELS ARE SOLD +Blah blah blah. + + + + + + 2-JUN-1987 11:23:12.29 + + + +icco + + + +T +f1404reute +f f BC-ICCO-BUFFER-STOCK-MAN 06-02 0010 + +******ICCO BUFFER STOCK MANAGER BUYS 5,000 TONNES - OFFICIAL +Blah blah blah. + + + + + + 2-JUN-1987 11:24:34.77 + +switzerland +volckergreenspan + + + + +RM +f1415reute +u f BC-CSFB-ECONOMIST-SAYS-V 06-02 0104 + +CSFB ECONOMIST SAYS VOCLKER'S RESIGNATION A SHOCK + ZURICH, June 2 - The decision by Paul Volcker not to serve +a third term as chairman of the U.S. Federal Reserve Board is a +shock for financial markets and the world economy, Hans Mast, +senior economic adviser to Credit Suisse First Boston, said. + "The markets will believe there will be pressure for a more +expansive policy (in the United States)," he said. + "I would say this is quite a shock for the world economy," he +added. "He always stood for an anti-inflationary policy and +tight fiscal discipline. He was one of the best central bankers +America has had." + Mast said the markets would now be trying to assess what +sort of direction the Fed would be taking under Alan Greenspan, +designated to succeed Volcker. + "Greenspan is more of a politician than an academician, but +the most important thing is that he has little experience in +banking," Mast said. + Greenspan's first comments on being named were that the +dollar appeared to have bottomed out but Mast said that +conviction would have to be backed by policy. "How can you say +the dollar has bottomed out with the present level of current +account deficits?" he said. "I would be sceptical." + REUTER + + + + 2-JUN-1987 11:24:48.49 + +usa +volcker + + + + +A RM +f1417reute +u f BC-SHEARSON-ECONOMIST-SA 06-02 0109 + +SHEARSON ECONOMIST SAYS VOLCKER EFFECT SHORT-TERM + NEW YORK, June 2 - Alan Sinai, chief economist of Shearson +Lehman Brothers Inc, said news that Federal Reserve Chairman +Paul Volcker declined to accept reappointment would have only a +short-term effect on financial markets. + "The markets should not go into a panic," Sinai told a +fixed-income conference in New York sponsored by the Institute +for International Research. + Sinai said he thought that Volcker was one of the best Fed +governors in the country's history. Still, he predicted that +the markets would calm after today's tremors. + Alan Greenspan has been nominated to replace Volcker. + Reuter + + + + 2-JUN-1987 11:25:21.16 + +usa + + + + + +F +f1421reute +r f BC-PERRY-DRUG-STORES-<PD 06-02 0068 + +PERRY DRUG STORES <PDS> NAMES NEW PRESIDENT + PONTIAC, Mich., June 2 - Perry Drug Stores Inc said it has +elected David Schwartz as president and chief executive +officer, effective immediately. + Perry said Schwartz, who will also serve on the board, +replaced Donald Fox, who resigned January 12. + Previously, Schwartz was vice president of drug and general +merchandise for Kroger Co <KR>, Perry said. + Reuter + + + + 2-JUN-1987 11:25:35.88 + +usa + + + + + +F +f1423reute +r f BC-MICRO-D-<MCRD.O>-IN-A 06-02 0088 + +MICRO D <MCRD.O> IN AGREEMENT WITH ZENITH <ZE> + GLENVIEW, ILL., June 2 - Zenith Electronics Corp said its +computer subsidiary signed an agreement under which Micro D Inc +will market the new Zenith Data Systems monitor, which uses the +flat tension mask color video display. + The monitor offers more than 50 pct greater brightness and +contrast performance than conventional high-revolution computer +monitors, Zenith said. It is compatible with the new IBM +Personal System/2 computers and will be available later this +summer. + Reuter + + + + 2-JUN-1987 11:25:47.87 +trade +turkey + + + + + +RM +f1425reute +r f BC-TURKISH-TRADE-DEFICIT 06-02 0083 + +TURKISH TRADE DEFICIT WIDENS IN APRIL + ANKARA, June 2 - Turkey's trade deficit widened to 382 mln +dlrs in April from 275 mln in March and 273 mln in April 1986, +the State Statistics Institute said. + The deficit for the first quarter of 1987 widened to 1.23 +billion dlrs from 1.20 billion a year earlier. + April exports totalled 702 mln dlrs compared with imports +of 1.08 billion. + Exports in the first four months were worth 2.69 billion +dlrs compared with imports of 3.92 billion. + REUTER + + + + 2-JUN-1987 11:25:57.77 +earn +usa + + + + + +F +f1427reute +r f BC-UNITED-FINANCIAL-BANK 06-02 0039 + +UNITED FINANCIAL BANKING <UFBC.O> 1ST QTR NET + VIENNA, Va., June 2 - + Shr four cts vs 21 cts + Net 29,862 vs 152,826 + NOTE: Full name is United Financial Banking Cos Inc. Net +includes loan loss provision nil vs 40,000 dlrs. + Reuter + + + + 2-JUN-1987 11:26:37.03 + +usa + + + + + +F +f1432reute +d f BC-DREYFUS-<DRY>-INTRODU 06-02 0099 + +DREYFUS <DRY> INTRODUCES STOCK INDEX FUND + NEW YORK, June 2 - Dreyfus Corp said it introduced a stock +index mutual fund designed primarily for use by bank trust +departments in managing their corporate pension accounts. + Dreyfus said the fund is keyed to matching the performance +of Standard and Poor's 500 Composite Stock Price Index, and in +addition to purchasing stock of the S and P index, the fund may +also deal in index futures. + The company said the fund will be managed by <Wells Fargo +Investment Advisors>. + Minimum investment requirement is one mln dlrs, the company +said. + Reuter + + + + 2-JUN-1987 11:27:37.15 + +usa +greenspanvolcker + + + + +A RM +f1437reute +u f BC-SEN-DOLE-SAYS-GREENSP 06-02 0113 + +SEN DOLE SAYS GREENSPAN WILL BE GOOD FED CHAIRMAN + WASHINGTON, June 2 - Senate Republican Leader Robert Dole +of Kansas said Alan Greenspan would be a good replacement for +Paul Volcker as Federal Reserve Chairman. + "While Paul Volcker's retirement is a real loss, this +country is very fortunate to have a man of Alan Greenspan's +caliber to take his place," Dole said in a statement. + "Alan's knowledge of the economy, coupled with his +experience at the top levels of government, means that the +leadership of the Federal Reserve Board will be in good hands. +Alan, literally, has some big shoes to fill. But I haven't any +doubts he's more than equal to the task," Dole said. + Reuter + + + + 2-JUN-1987 11:27:45.10 +earn +usa + + + + + +F +f1438reute +u f BC-BROWN-GROUP-INC-<BG> 06-02 0032 + +BROWN GROUP INC <BG> 1ST QTR MAY 2 NET + ST. LOUIS, Junee 2 - + Shr 56 cts vs 42 cts + Net 10,030,000 vs 7,833,000 + Sales 392.1 mln vs 339.6 mln + Avg shrs 17,966,000 vs 18,709,000 + Reuter + + + + 2-JUN-1987 11:28:11.97 +crude +usa + + + + + +C +f1439reute +d f BC-U.S.-ENERGY-SECRETARY 06-02 0141 + +U.S. ENERGY SECRETARY SEES HIGHER OIL PRICES + WASHINGTON, June 2 - Energy Secretary Donald Hodel said he +expects oil prices to rise significantly by the year 2000, +probably to around 33 dlrs a barrel in current dollars. + "I do anticipate a significant increase (by 2000). +Thirty-three dlrs a barrel is not unreasonable," Hodel told the +Senate Energy Committee. + Hodel said the loss of some domestic oil production through +the shutdown of stripper (10 barrels a day or less) wells +because of low prices was probably permanent. He said he was +also concerned by the decline in domestic oil exploration. + Hodel urged Congress to approve oil exploration in section +1002 of the Arctic National Wildlife Refuge in Alaska. He said +geologic condtions in the area were favorable for the discovery +of oil fields equal to those in nearby Prudhoe Bay. + Reuter + + + + 2-JUN-1987 11:28:46.97 + +usa + + + + + +F +f1444reute +s f BC-MUTUAL-OF-OMAHA-INTER 06-02 0024 + +MUTUAL OF OMAHA INTEREST SHARES INC <MUO> PAYOUT + OMAHA, Neb., June 2 - + Qtly div 36 cts vs 36 cts prior + Payable July 1 + Record June 12 + Reuter + + + + 2-JUN-1987 11:29:35.72 +earn +usa + + + + + +F +f1445reute +r f BC-NORTHWEST-TELEPRODUCT 06-02 0043 + +NORTHWEST TELEPRODUCTIONS <NWTL.O> 4TH QTR NET + MINNEAPOLIS, MINN., June 2 - + Shr 15 cts vs 16 cts + Net 239,034 vs 264,485 + Sales 2,932,782 vs 2,664,853 + Year + Shr 57 cts vs 45 cts + Net 929,524 vs 741,121 + Sales 10.9 mln vs 9,708,792 + + Reuter + + + + 2-JUN-1987 11:31:07.63 + + + + + + + +F +f1451reute +b f BC-******U.S.-JUDGE-SAYS 06-02 0014 + +******U.S. JUDGE SAYS TO DECIDE BURLINGTON REQUEST FOR SAMJENS INJUNCTION IN "FEW DAYS" +Blah blah blah. + + + + + + diff --git a/src/test/data/reuters-21578/reut2-019.sgm b/src/test/data/reuters-21578/reut2-019.sgm new file mode 100644 index 00000000000..982ec023787 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-019.sgm @@ -0,0 +1,2013 @@ + + +18-JUN-1987 18:46:13.14 + +usa + + + + + +F +f4966reute +u f BC-BEVERLY-HILLS-COP-II 06-18 0074 + +BEVERLY HILLS COP II TOPS 100 MLN AT BOX OFFICE + NEW YORK, June 18 - Gulf and Western Inc's <GW> Paramount +Pictures Corp division said its movie "Beverly Hills Cop II" +has topped the 100 mln dlr mark at the box office on the 29th +day of its North American release. + Paramount said the the movie has become the fastest movie +to hit the 100 mln dlr mark with an "R" rating, which means +that anyone under 17 must be accompanied by their parents. + Reuter + + + +18-JUN-1987 18:46:33.73 + +usa + + + + + +F +f4968reute +s f BC-TRANSAMERICA-CORP-<TA 06-18 0022 + +TRANSAMERICA CORP <TA> QUARTERLY DIVIDEND + SAN FRANCISCO, June 18 - + Qtly div 44 cts vs 44 cts + Pay July 31 + Record July 3 + Reuter + + + +18-JUN-1987 18:48:35.56 + +usajapan + + + + + +F A +f4972reute +d f AM-POLICY 06-18 0078 + +U.S. HOUSE CALLS HIGHER JAPAN DEFENSE SPENDING + WASHINGTON, June 18 - The House today supported a call for +Japan to boost its defense spending to help share the burden of +protecting Western interests in sensitive areas around the +world, including in the Gulf. + House member approved a measure that would require +Secretary of State George Shultz to enter into talks with Japan +on increasing Japanese defense spending to at least 3 pct of +its gross national product. + The measure, passed during consideration of the 1988-89 +State Department funding bill would not require an increase, +but legislators called on Japan to spend more on defense. The +Senate must approve the measure before it becomes law. + "We don't have to bash the Japanese. We have to show them +how to share the burden of the defense of the free world," said +Rep. Robert Dornan, a California Republican. + The amendment calls on Shultz to enter into talks with +Japan with the aim of reaching agreement on one of two +alternatives: either Japan can spend 3 pct of its GNP on +defense by itself or give the equivalent amount of money to the +United States as a kind of security fee. + Reuter + + + +18-JUN-1987 18:55:48.68 +gnp + + +oecd + + + +RM +f4988reute +f f BC-OECD-SEES-1.5-PCT-WES 06-18 0010 + +****** OECD SEES 1.5 PCT WEST GERMAN REAL GNP GROWTH IN 1987 + + + + + +18-JUN-1987 18:56:07.09 +gnpcpibop +franceaustralia + +oecd + + + +RM +f4990reute +u f BC-AUSTRALIA-SET-TO-GROW 06-18 0117 + +AUSTRALIA SET TO GROW, BUT UNEMPLOYMENT MAY RISE + PARIS, June 19 - Australia's economy should manage modest +growth over the next two years after a sharp slowdown but +unemployment could still edge upwards, the Organisation for +Economic Cooperation and Development (OECD) said. + The organisation's latest half-yearly report says Gross +Domestic Product will grow by 2.5 pct this year and by 2.75 pct +in 1988 compared with only 1.4 pct in 1986. The growth will be +helped by higher stockbuilding and stronger domestic demand +following tax cuts and higher real wages, it added. + The report forecasts a decline in inflation, with consumer +prices increasing by 8.5 pct this year and 6.25 pct in 1988. + The current account deficit shows signs of easing slightly +and could narrow to 12 billion dlrs by the end of 1988. + While predicting slightly stronger growth than last year, +however, the report revises downwards the OECD's earlier growth +forecast for 1987 of 3.75 pct. + The OECD predicts a similar combination of modest economic +growth and rising unemployment for New Zealand, which is +struggling to recover from a major economic crisis. + The country's GDP, which contracted by 0.6 pct last year, +should again show growth over the next two years, rising by +0.25 pct this year and a more substantial 2.75 pct in 1988. + Reuter + + + +18-JUN-1987 19:03:26.58 +acq +usa + + + + + +F +f4996reute +u f BC-/SQUIBB-<SQB>-SAID-NO 06-18 0104 + +SQUIBB <SQB> SAID NOT INTERESTED IN BUYING CETUS + BY MARJORIE SHAFFER, REUTERS + NEW YORK, June 18 - Robert Fildes, president and chief +executive of Cetus Corp <CTUS.O>, told Reuters that Squibb Corp +is not interested in buying Cetus. + Earlier the companies said Squibb would buy from Cetus a +five pct equity postion in Cetus for about 40 mln dlrs. + "This is not an attempt by Squibb to become a major +majority holder in Cetus," Fildes told Reuters in an interview. +"Squibb has not approached us with any indication that they +want to acquire us and we wouldn't be interested in that kind +of arrangement," said Fildes. + Squibb could not be reached to comment on the late comments +by Fildes. + Squibb is Cetus' first pharmaceutical partner and the only +one to own an equity position in Cetus. Eastman Kodak Co <EK> +and W.R. Grace <WR> both have joint ventures with Cetus, but +neither owns an equity position in the company, said Fildes. + Cetus has a venture with Kodak to develp diagnostic +products and with Grace to develop agricultural products. + Earlier, Squibb and Cetus announced in a joint statement +an agreement in principle to form a joint venture to develop +new biotechnology products in several fields. + + As part of the deal Squibb will license several of Cetus' +anticancer agents, including interleukin-2, in development. +Squibb will sell the drugs only in Japan and other markets but +not in North American and Western Europe. + "We wouldn't have done this deal had it not been understood +that Cetus wants to build its own fully integrated business in +North America and Europe," said Fildes. + He said Squibb was the good partner because Squibb has a +major joint venture in Japan and has sales capabilities of its +own in that market. + + Fildes said Cetus has shunned licensing arrangements with +pharmaceutical companies because it wanted to build its own +business. Many large corporations have invested in small +biotech firms. + But Squibb's investment in Cetus is the first it has made +in biotechnology. Fildes said that was attractive to Cetus +because it wanted a partner that didn't have a relationship +with a large number of other biotechnology companies." + + Fildes said his strategy was to have partners in non drug +areas like diagnostics and agriculture, but to "keep the +biggest developments in anticancer drugs to ourselves." + Fildes said the partnership with Squibb would be used to +broaden the company's reach in such big money making areas +as the cardiovascular, anti-infective and the anti-inflammatory +markets. + Squibb is also investming 75 mln dlrs in Cetus' research +over the next five years. + + "Squibb is putting up over 75 mln dlrs in research and +development to make it happen, while the equity position part +of the package is simply to demonstrate the seriousness of this +partnership," said Fildes. + Reuter + + + +18-JUN-1987 19:44:15.31 + +usa + + + + + +F +f5022reute +b f BC-NBC-SAYS-IT-WILL-IMPL 06-18 0116 + +NBC SAYS IT WILL IMPLEMENT CONTRACT JUNE 29 + NEW YORK, June 29 - The National Broadcasting Co, a unit of +General Electric Co <GE>, said it intends to implement on June +29 a labor contract rejected by union represenatives. + A spokesman for the National Association of Broadcast +Employees and Technicians, represening 2,800 workers, said its +negotiating committee adopted a formal resolution today stating +it will inform NBC it will strike upon implementation. + "The union will have to decide what action it thinks is +appropriate," said Day Krolik, NBC's vice president for labor +relations. A union spokesman said NBC has until the day of +implemetation to peacefully negotiate a contract. + Reuter + + + +18-JUN-1987 19:50:03.10 + +usa + + + + + +F +f5025reute +u f BC-FORMER-SHEARSON-<SHE> 06-18 0099 + +FORMER SHEARSON <SHE> OFFICIAL PLEADS GUILTY + NEW YORK, June 18 - Mark Stahl, 45, who was a former senior +vice president of Shearson Lehman Brothers, until his +suspension on April 16, today admitted in U.S. District court +here, embezzling almost 19 mln dlrs from his firm over the past +year. + He entered a guilty plea before United States District +Court Judge Vincent Broderick to four specific charges totaling +1,031,000 dlrs on wire fraud. + Stahl, who was a senior vice president for finance, told +the judge that the total embezzlement amounted to "a little +less than" 19 mln dlrs. + + Through an attorney, Stahl agreed to make restitution to +Shearson Lehman of all the embezzled funds if possible. However +his guilty pleas today to the four counts will cover all +criminal liability of the embezzlement that occurred between +April 1986 to last April. + Judge Broderick scheduled sentencing for December nine. + Stahl faces a maximum sentence of 20 years in jail and one +mln dlrs in fines, or both. + Reuter + + + +18-JUN-1987 19:53:55.04 +earn +usa + + + + + +F +f5027reute +u f BC-TRI-STAR-PICTURES-INC 06-18 0083 + +TRI-STAR PICTURES INC <TRSP.O> 1ST QTR MAY 31 + NEW YORK, June 18 - + Shr four cts vs four cts + Net 1,180,000 vs 902,000 + Revs 146.9 mln vs 37.0 mln + Avg shrs 33 mln vs 23.9 mln + NOTE: Company changed its fiscal year from December 31 to +the last day of February, thus results of operations for the +year-ago period have been restated to reflect this change. + Current first quarter includes results of operations of +Loews Theatre Management Corp which Tri-Star acquired December +31. + Reuter + + + +18-JUN-1987 20:07:05.93 + + + + + + + +E F RM +f5035reute +f f BC-CANADA-BUDGET-DEFICIT 06-18 0013 + +******CANADA BUDGET DEFICIT DECLINE TO SLOW IN LATE 1980S - +OFFICIAL + Reuter + + + + + +18-JUN-1987 20:07:10.18 + + + + + + + +V RM E +f5036reute +f f BC-CANADA-UPS-CORPORATE 06-18 0014 + +******CANADA LIFTS CORPORATE TAX REVENUES BY FIVE BILLION DLRS +OVER FIVE YEARS - OFFICIAL + + + + + +18-JUN-1987 20:07:45.08 + + +wilson + + + + +E F RM +f5037reute +f f BC-WILSON-CUTS-PERSONAL 06-18 0011 + +******WILSON CUTS PERSONAL TAX RATES, LIMITS CAPITAL GAINS +EXEMPTIONS + Reuter + + + + + +18-JUN-1987 20:08:00.01 + + + + + + + +V RM E +f5038reute +f f BC-CANADA-UPS-FINANCIAL 06-18 0015 + +******CANADA LIFTS FINANCIAL INSTITUTION AVERAGE TAX RATE TO +21.3 PCT FROM 14.5 PCT - OFFICIAL + + + + + +18-JUN-1987 20:12:23.11 + +canada +wilson + + + + +V E RM +f5040reute +u f BC-WILSON-TO-HIKE-CORPOR 06-18 0085 + +CANADA TO INCREASE CORPORATE TAX REVENUES + OTTAWA, June 18 - Canada will increase corporate tax +revenues by about five billion dlrs over the next five years by +broadening the tax base and allowing fewer exemptions, finance +minister Michael Wilson said. + As Wilson previously promised, he said corporations will +bear an increased tax burden, despite new measures to lower +overall tax rates. + Increased corporate revenues will result from broadening +the tax base and eliminating special tax exemptions. + "The jobs of many Canadians depend on a corporate income +tax system that is competitive with other countries, +particularly the United States," Wilson said in a prepared +speech to the House of Commons. + "And it (tax reform) will ensure that profitable +corporations carry a bigger share of the total tax burden," he +added. + Federal tax revenue from corporations will increase by 470 +mln dlrs in the fiscal year ending March 31, 1988, 410 mln dlrs +in fiscal 1989 and 1.19 billion dlrs in fiscal 1990, according +to documents tabled with Wilson's speech. + Reuter + + + +18-JUN-1987 20:15:24.21 + +canada +wilson + + + + +V E RM +f5041reute +u f BC-CANADA-FINANCIAL-TAX 06-18 0074 + +CANADA FINANCIAL TAX RATE INCREASED + OTTAWA, June 18 - The average tax rate for Canadian +financial insitutions will increase to 21.3 pct from 14.5 pct +under the new tax reform package, the federal finance +department said. + The amount of financial institutions' income that is taxed +will also increase to 74.0 pct from 48.7 pct, it said in +documents tabled with finance minister Michael Wilson's +prepared speech to the House of Commons. + Under Wilson's plan, the federal government will collect +1.36 billion dlrs more over the next five years from financial +insitutions, including banks, trust mortgage and life insurance +companies, according to finance department documents. + Financial institutions "are going to complain, but we +believe the changes are appropriate and affordable," said one +finance department official who asked not to be identified. + Ottawa will collect more revenue from financial +institutions by reducing the amount of reserves they can deduct +from taxes, which "will broaden the tax base for this low tax +paying sector," the finance department said. + Among the changes, chartered banks will no longer be able +to use a five-year averaging formula to calculate loan losses +that may be deducted for tax purposes. + Effective June 17, 1987, banks will deduct bad or doubtful +loans during the year they are incurred. + The finance department said the impact of the new +provisions will be cushioned over a period of five years. + The changes are needed to ensure that all financial +companies are taxed fairly under deregulation of the financial +services industry. + "It would be inconsistent for the tax system to continue +to provide different reserves for tax purposes for institutions +competing in the same marketplace," the finance department +said. + Reuter + + + +18-JUN-1987 20:20:39.69 + +canada +wilson + + + + +V E RM +f5048reute +u f BC-OTTAWA-WIDENS-SALES-T 06-18 0089 + +OTTAWA WIDENS SALES TAX, STUDIES REPLACEMENT + OTTAWA, June 18 - Canada will broaden a federal sales tax +levied on manufacturers before scrapping the system in favor of +a broad based, multi-staged sales tax, finance minister Michael +Wilson said. + As expected, Wilson did not include a new sales tax system +as part of his wide-ranging tax reforms tabled in the House of +Commons today. + Instead, the federal government will make interim changes +to the existing sales tax to make it more fair for low and +middle income Canadians. + "The present (sales) tax is fundamentally flawed. It is a +hidden, arbitrary and capricious tax," Wilson told the House of +Commons. + The existing federal sales tax system hurts the Canadian +economy by putting more tax on Canadian produced goods than +imported goods and adding a hidden tax on Canadian exports that +makes them less competitive, Wilson said. + Interim changes effective January 1, 1988 will include: + -- applying the federal sales tax to marketing companies +related to manufacturers + -- levying the tax at the wholesale level instead of the +manufacturer for a selected range of products + -- applying a 10 pct sales tax to telecommunication +services, except for residential telephone lines + -- quicker collection of federal sales taxes. + To offset these changes for low income Canadians, +refundable tax credits will be increased to 70 dlrs from 50 +dlrs for adults and to 35 dlrs from 25 dlrs for children, the +finance department said. + Ottawa is considering three alternative forms for a new +sales tax, including a goods and services tax, a value added +tax and a national sales tax that would combine existing +federal and provincial levies into one system, Wilson told the +House of Commons. + He said the federal government will explore the +possibility of one national sales tax with Canada's 10 +provincial governments. All provinces except Albeta now levy a +provincial sales of tax of varying amounts. + Wilson said one joint system would be simpler for +taxpayers and maximize economic benefits of tax reform. + If Ottawa and the provinces can't agree on a national +sales tax system, Wilson said the federal government will +consider either a goods and services tax or a value-added tax. + A goods and services tax would apply at one rate to +virtually all goods and services in Canada and would include +further increases in refundable tax credits for low and middle +income Canadians, the finance department said in documents +accompanying Wilson's speech. + A federal value-added tax, similar to European tax +systems, would also be broad based but would allow more +flexibility to exempt selected goods and services, the +department said. The finance deparment said the main drawback +of a value added tax is that it would be more complex and +costly to implement than the other two proposals. + Reuter + + + +18-JUN-1987 20:28:39.01 +gnp +canada +wilson + + + + +V E RM +f5055reute +u f BC-CANADIAN-BUDGET-DEFIC 06-18 0088 + +FALL IN CANADIAN BUDGET DEFICIT TO SLOW + OTTAWA, June 18 - Finance Minister Michael Wilson said tax +reform will not affect his determination to reign in +expenditures, but his forecasts show a slowing of the decline +in the budget deficit in the late 1980s. + "Responsible tax reform must be fiscally responsible," +Wilson said in a speech prepared for the House of Commons. + Wilson estimated the deficit will fall to 29.3 billion dlrs +in the year ending March 31, 1988, the same level as he +forecast in the February budget. + And in the year ended this past March, the deficit was +expected to have been one billion dlrs lower than the 32 +billion dlr shortfall originally forecast, Wilson said. + Wilson said in the current 1988 fiscal year +higher-than-anticipated spending, particularly in farm income +support programs, will be offset by higher-than-anticipated +revenues. + But finance department documents show the pace of deficit +reduction was expected to slow temporarily in fiscal 1989 and +1990 as a result of lower oil and grain prices and the +transition to the reformed taxation system. + The deficit is expected to total 28.9 billion dlrs in +fiscal 1989 and 28.6 billion dlrs in 1989 and then fall to 26.1 +billion dlrs in 1991. + Wilson was optimistic about the outlook for the Canadian +economy, forcasting gross domestic product would expand 2.8 pct +this year and 3.0 pct in 1988. In 1986 the economy grew by an +actual 3.1 pct. + Inflation, meanwhile, is expected to stabilize at around +the current four pct level over the next two years. + Reuter + + + +18-JUN-1987 20:33:47.78 + +canada +wilson + + + + +V E RM +f5060reute +u f BC-CANADA'S-WILSON-SETS 06-18 0106 + +CANADA'S WILSON SETS NEW PREFERRED SHARE TAX + OTTAWA, June 18 - Finance Minister Michael Wilson tabled a +ways and means motion to immediately impose a special tax on +preferred share dividends to eliminate a significant loss of +corporate tax revenue. + Under the motion, which is used to introduce most financial +tax changes, dividends on all preferred shares issued after +June 18 will be taxable. + The issuing corporation will be able to choose between two +forms of tax, one that imposes a 25 pct tax on dividends with a +subsequent additional 10 pct tax paid by the shareholder, and +one that imposes a flat 40 pct tax on dividends. + "Measures to reduce the tax advantages of after-tax +financing arrangements using preferred shares are a critical +step in achieving the broadened corporate tax base required to +fund personal income tax reductions," Wilson explained. + The minister said many profitable corporations, using +various deductions built up over the years, pay no taxes, +although they are in a position to pay dividends out of their +profits. + Reuter + + + +18-JUN-1987 20:35:36.77 + +canada +wilson + + + + +V E RM +f5063reute +u f BC-CANADA-SETS-WIDE-RANG 06-18 0089 + +CANADA SETS WIDE-RANGING PERSONAL TAX CHANGES + OTTAWA, June 18 - Finance Minister Michael Wilson unveiled +a wide-ranging reform of the personal tax system that includes +limiting the capital gains exemption and a sharp cut in the +dividend tax credit. + With most changes effective at the first of next year, +Wilson also announced he was cutting the number of tax brackets +from 10 to three. + He said the changes will cut personal tax revenues by two +billion dlrs in 1988 and by more than 11 billion dlrs over the +next five years. + "Most Canadians will pay lower taxes because of two +far-reaching changes. A new structure of federal income tax +rates and the conversion of exemptions and deductions to tax +credits," Wilson told the House of Commons. + The new tax brackets will be 17 pct on the first 27,500 +dlrs of taxable income, 26 pct on the next 27,500 dlrs and 29 +pct on taxable income in excess of 55,000 dlrs. The maximum tax +rate is 34 pct under the current system. + In a major reversal of his own initiative, Wilson said the +controversial 500,000 dlrs capital gains exemption will be +reduced to 100,000 dlrs over an investors' lifetime. + Wilson introduced the exemption shortly after taking office +in 1984 as a a way of stimulating investment, but it was +sharply criticized by the opposition as over-generous to +wealthy investors. + The 500,000 dlr lifetime exemption will be kept on the +sale of farm land and for small businesess, however. + Also, the taxable portion of a capital gain will increase +from 50 pct currently to 66-2/3 pct in 1988 and 75 pct in 1990. + The dividend tax credit will be reduced from 33-1/3 pct to +25 pct and the deduction for up to 1,000 dlrs of interest and +dividend income will be eliminated in 1988. + Wilson said tax treatment for registered retirement savings +plan contributions will be maintained but the phase in of the +increase in the maximum limit to 15,500 dlrs will be delayed +four years to 1994. + Reuter + + + +18-JUN-1987 20:48:32.87 +interest + + + + + + +RM +f5072reute +f f BC-ANZ-BANKING-GROUP-SAY 06-18 0014 + +******ANZ BANKING GROUP SAYS IT WILL CUT PRIME RATE TO 16.00 +PCT FROM 16.50 ON JUNE 22 + + + + + +18-JUN-1987 21:07:33.30 +money-fxdlr + +miyazawa + + + + +RM AI +f5083reute +f f BC-Japan-still-asking-in 06-18 0013 + +******Japan still asking institutions to limit speculative dlr +deals - Miyazawa + + + + + +18-JUN-1987 21:09:30.49 +interest +australia + + + + + +RM AI +f5084reute +b f BC-ANZ-BANKING-GROUP-CUT 06-18 0092 + +ANZ BANKING GROUP CUTS PRIME RATE TO 16.00 PCT + MELBOURNE, June 19 - The Australia and New Zealand Banking +Group Ltd <ANZA.S> said it will cut its prime rate to 16.00 pct +from 16.50, effective June 22. + The cut takes the ANZ's prime to the lower end of the range +of prime rates being offered by Australian trading banks. The +highest rate is 17.50 pct. + The cut follows announcements of cuts yesterday by +<Citibank Ltd> to 16.00 pct from 16.5, effective today, and +<Commonwealth Bank of Australia> to 15.75 pct from 16.25, +effective June 24. + REUTER + + + +18-JUN-1987 21:15:11.47 +money-fxdlr +japan +miyazawa + + + + +RM AI +f5087reute +b f BC-JAPAN-STILL-WANTS-SPE 06-18 0069 + +JAPAN STILL WANTS SPECULATIVE DLR DEALS LIMITED + TOKYO, June 19 - The Finance Ministry is still asking +financial institutions to limit speculative dollar dealings, +Finance Minister Kiichi Miyazawa told reporters. + He was responding to rumours in the New York currency +market overnight that the Ministry was reducing its pressure on +institutions to refrain from excessively speculative dollar +dealings. + REUTER + + + +18-JUN-1987 21:32:28.55 + +india +gandhi + + + + +RM V +f5094reute +u f BC-GANDHI-PARTY-BADLY-DE 06-18 0108 + +GANDHI PARTY BADLY DEFEATED IN INDIA STATE POLL + NEW DELHI, June 19 - Prime Minister Rajiv Gandhi's Congress +(I) party was swept from power in the northern state of Haryana +by an opposition landslide. + The loss was a major personal setback for Gandhi whose +vote-winning ability was on trial after political scandals in +Delhi and a string of electoral losses since he took command of +the party in 1984. + With 53 results in for Haryana's 90-seat assembly, Congress +had won only two seats against 63 previously. Before the poll, +Congress politicians in Delhi said privately that a loss in +Haryana could open a party leadership debate. + REUTER + + + +18-JUN-1987 21:34:55.99 + +south-korea + + + + + +RM V +f5096reute +u f BC-SOUTH-KOREA-THREATENS 06-18 0107 + +SOUTH KOREA THREATENS EMERGENCY MEASURES + SEOUL, June 19 - The government will take emergency +measures if the present wave of violent protest demonstrations +continues, state radio said. + The radio, which did not specify the measures, said the +decision was taken today at a meeting of top ministers and +security officials attended by Prime Minister Lee Han-key. It +said a special statement would be made shortly. + Thousands of demonstrators took to the streets of Seoul and +other cities yesterday, battling riot police and demanding the +resignation of President Chun Doo Hwan. It was the ninth +successive day of violent protests. + REUTER + + + +18-JUN-1987 21:56:40.46 + +usa + + + + + +F +f5107reute +r f BC-COURT-ORDERS-INT'L-ME 06-18 0107 + +COURT ORDERS INT'L MEDICAL INSURER TO SHOW CAUSE + TALLAHASSEE, Fla., June 18 - A Circuit Court judge ordered +the company that insured the solvency of International Medical +Centres Inc to show cause why it should not honour its contract +with International, according to Florida's Department of +Insurance, which had filed a petition on the matter. + As previously reported, International, the largest health +maintenance organisation in Florida was declared insolvent on +May 14. Federal regulators had also told the company its +Medicare contract would be terminated on July 31 because of the +company's financial and management problems. + Michelle McLawhorn, Florida Department spokeswoman, said +International's insurer, State Mutual Life Assurance Co of +America, had made clear it would fight activation of the policy +because International did not provide it with accurate +financial records. State Mutual could not be reached for +comment. + McLawhorn said it was not yet known how many creditors +International had or how big its debt was. The court gave State +Mutual 20 days to show why it should not be obliged to pay +claims against the solvency policy. + REUTER + + + +18-JUN-1987 22:26:37.58 + +brazil +sarney + + + + +RM AI +f5137reute +u f BC-BRAZIL-RULING-PARTY-T 06-18 0101 + +BRAZIL RULING PARTY TO DECIDE ON PRESIDENTIAL TERM + BRASILIA, June 18 - The ruling Brazilian Democratic +Movement Party (PMDB) will hold a national convention on July +18 and 19 to discuss the length of the Presidential term, a +PMDB spokesman said. + Although the country's constitution allows for a six-year +term, Sarney said he would remain only five years after he came +to power in 1984. + The Constituent Assembly is drawing up a new constitution +and severe economic problems have increased the pressure on it +to call early elections. A faction of the PMDB favours a poll +in November next year. + REUTER + + + +18-JUN-1987 22:33:01.85 +money-supplymoney-fxdlr +usa + + + + + +RM AI +f5141reute +u f BC-FED-DATA-SUGGEST-NO-C 06-18 0086 + +FED DATA SUGGEST NO CHANGE IN MONETARY POLICY + By Kathleen Hays, Reuters + NEW YORK, June 18 - New U.S. Banking data suggest the +Federal Reserve is guiding monetary policy along a steady path +and is not signalling any imminent change of course, economists +said. + But they also said that if money supply growth remains +weak, as this week's unexpected eight billion dlr M-1 decline +suggests it may, this could influence the Fed to loosen its +credit reins and move toward a more accommodative monetary +policy. + A Reuter survey of 17 money market economists produced a +forecast of a 600 mln dlr M-1 decline for the week ended June +8, with estimates ranging from a gain of one billion dlrs to a +decline of four billion. Instead, M-1 fell eight billion dlrs +to 745.7 billion dlrs at a seasonally adjusted annual rate. + Coming on the heels of a 4.3 billion decrease in M-1 for +the week ended June 1, this means the nation's money supply has +fallen more than 12 billion dlrs in the past two weeks, +economists said. + "M-1 has hit an air pocket of weakness," said Bill Sullivan +of Dean Witter Reynolds Inc. + While M-1 may have lost its significance as an indicator of +economic growth, Sullivan said Fed officials might be concerned +the latest drop in M-1 means another month of sluggish growth +in the broader monetary aggregates, M-2 and M-3, which are seen +as better gauges of economic growth. + Latest monthly M-2 and M-3 data showed that as of May, both +measures were growing at rates below the bottom of the Fed's +5-1/2 to 8-1/2 pct target ranges. + If money growth does not accelerate, Fed officials, +concerned that this indicates economic growth is flagging, +could turn toward easier monetary policy, economists said. + "Does this mean that the Fed abandons its current open +market position? No," Sullivan said. "But does this mean the end +of tightening for the time being? Definitely yes." + Economists said average adjusted discount window borrowings +of 385 mln dlrs for the latest two-week bank statement period +were lower than they had expected. Most believed the Fed had +targetted a two-week borrowings average of around 500 mln dlrs. + But they said that if it had not been for a large one-day +net miss in the Fed's reserve projections, the higher +borrowings target would probably have been reached. + A drop in May U.S. Housing starts and continued weakness in +auto sales show key sectors of the U.S. Economy are lagging, +while a recent modest 0.3 pct gain in May producer prices has +helped dispel inflation fears, Slifer said. + "If this continues, we can entertain the notion of Fed +easing at some point," he said. + Other economists said the Fed would probably pay little +attention to weak money supply growth. "It has been a number of +years since M-1 has given good signs of what's going on in the +economy," one said. "I don't think M-1 shows that the economy is +falling apart and the Fed should ease." + Economists agreed a stable dollar will continue to be a +prerequisite for any move by the Fed toward easier monetary +policy. + They said the Fed is reluctant to lower short-term rates +for fear this would spur expectations of a weaker dollar and +higher inflation which would push up long-term yields and choke +off econmomic growth. + But Sullivan said the dollar has been steady since late +April. "The Fed has to determine if this represents a +fundamental change for the dollar. If it does, then this gives +them more room to ease," he said. + REUTER + + + +18-JUN-1987 22:34:58.79 +earn +usa + + + + + +F +f5142reute +b f BC-NATIONAL-SEMICONDUCTO 06-18 0067 + +NATIONAL SEMICONDUCTOR CORP <NSM> FOURTH QUARTER + SANTA CLARA, Calif., June 18 - + Shr profit six cents vs loss 10 + Net profit 8.1 mln dlrs vs loss 7.1 mln + Sales 511.9 mln vs 397.8 mln + Avg shrs 97.0 mln vs 90.5 mln + YEAR + Shr loss 38 cents vs loss 1.10 dlrs + Net loss 24.6 mln dlrs vs loss 91.5 mln + Sales 1.87 billion vs 1.48 billion + Avg shrs 91.7 mln vs 89.8 mln + NOTE - Current year figure includes previously announced 15 +mln dlr restructuring charge. + Figures include extraordinary credit from tax benefit of +4.2 mln dlrs in quarter vs 2.3 mln a year earlier and 4.2 mln +for year vs 5.6 mln year earlier. + The 1986 year net reflects 51.2 mln dlr gain from +cumulative effect of accounting change. + REUTER + + + +18-JUN-1987 23:12:09.91 + +usa + + + + + +F +f5168reute +u f BC-NATIONAL-SEMICONDUCTO 06-18 0104 + +NATIONAL SEMICONDUCTOR <NSM> SEES IMPROVED YEAR + SANTA CLARA, Calif., June 18 - National SemiConductor Corp, +which earlier reported a profitable fiscal fourth quarter after +a year ago loss, said it expects improved financial performance +during its new fiscal year. + The company reported a profit of 8.1 mln dlrs in the +quarter ended May 31, after a loss of 7.1 mln dlrs in the year +ago period. + The company said orders for its core businesses have +improved, adding "Our strong balance sheet and the improved +business environment should enable us to improve our financial +performance during our new fiscal year." + The company said that during the fourth quarter both its +semiconductor group and its information systems group had +higher sales and improved operating performance than in the +prior quarter and the year-earlier quarter. + REUTER + + + +18-JUN-1987 23:19:19.77 + +usa + + + + + +RM AI +f5172reute +u f BC-OKLAHOMA-THRIFT-PLACE 06-18 0117 + +OKLAHOMA THRIFT PLACED UNDER RECEIVERSHIP + WASHINGTON, June 18 - The Federal Home Loan Bank Board +(FHLBB) today placed <Investors Federal Bank> of El Reno, +Oklahoma under receivership and transferred its 97.8 mln dlrs +in assets to the <Investors Savings and Loan Association>. + An FHLBB statement said the thrift was insolvent and "had +substantially dissipated its assets," mainly by participating in +large commercial real estate developments. It said it violated +federal laws and regulations on loan documentation, loans to +directors and conflict of interest. The sucessor organisation +is a federal savings and loan to be managed under contract by +Sunwood Management Corp of Parker, Colorado. + REUTER + + + +18-JUN-1987 23:26:43.72 + +japanusa + + + + + +F +f5175reute +u f BC-MITSUBISHI-ELECTRIC-T 06-18 0114 + +MITSUBISHI ELECTRIC TO ASSEMBLE PC'S IN U.S. + TOKYO, June 19 - Mitsubishi Electric Corp <MIET.T> plans to +assemble personal computers in the U.S. To counteract the +imposition of a 100 pct import tax in April and a drop in +profits due to the yen's appreciation against the dollar, a +company spokesman told Reuters. + It will assemble 16-bit MP-286 and 32-bit MP-386 desk-top +computers at its wholly-owned computer and computer-related +equipment sales unit <Mitsubishi Electronics America Inc> in +Torrance, California at a rate if 10,000 a month, he said. This +will include 2,000 TO 3,000 to be sold in the U.S. Under the +Mitsubishi name, he said without giving more details. + REUTER + + + +18-JUN-1987 23:30:02.35 +trade +usasingaporebruneiindonesiamalaysiaphilippinesthailand + + + + + +RM V +f5177reute +u f BC-SHULTZ-WARNS-ASEAN-OF 06-18 0100 + +SHULTZ WARNS ASEAN OF LOOMING TRADE PROBLEM + SINGAPORE, June 19 - U.S. Secretary of State George Shultz +warned members of the Association of Southeast Asian Nations +(ASEAN) they could no longer rely on increased exports to the +U.S. For growth. + "Given the importance of exports, particularly export +manufactures, to all of your countries, you are going to have +to work hard to diversify your markets," he said. + "While you may be able to maintain your current market share +in the U.S., You clearly will not be able to look to the U.S. +To take major increases in your exports," he added. + Shultz told the foreign ministers of Brunei, Indonesia, +Malaysia, the Philippines, Singapore and Thailand the U.S. +Would cut its huge foreign trade deficit more rapidly than many +now believed. + He said ASEAN's looming trade problems would not +necessarily stem from protectionist legislation now being +contemplated by Congress, "but simply because of the adjustments +the U.S. Economy will have to make in order to service our +large and growing external debt." + Shultz said the U.S. Deficit had resulted not from falling +exports but from higher imports that had fuelled world growth. + REUTER + + + +18-JUN-1987 23:52:30.35 + +australia +keatinghawke + + + + +RM AI +f5192reute +u f BC-AUSTRALIA'S-OPPOSITIO 06-18 0107 + +AUSTRALIA'S OPPOSITION FACES SETBACK ON TAX PLAN + By Francis Daniel, Reuters + SYDNEY, June 19 - The conservative opposition, already +fighting an uphill election battle, now faces controversy in +its own ranks over a possible error in its major tax cutting +program, economists said. + Professor Michael Porter, architect of the tax plan, +declined to refute Treasurer Paul Keating's charge that the +opposition miscalculated tax and expenditure cuts by several +billion dollars. Economists said the opposition, trailing +behind Labour in opinion polls, would find its chances further +diminished if its tax policy was a miscalculation. + The tax plan, unveiled by opposition leader John Howard +last week, is the cornerstone of the Liberal Party's economic +strategy to oust the Labour Party in the July 11 poll. + Keating has said the Howard tax plan would sharply increase +the budget deficit to more than nine billion dlrs and severely +damage Australia's economy, already overburdened with balance +of payments and foreign debt problems. + In his mini-budget on May 13, Keating said the budget +deficit for the year ending June 1988 would be between two and +three billion dlrs. + Porter, a key member of the opposition economic think tank, +said he played a leading role in formulating the tax plan but +not Howard's proposed expenditure savings, which Keating +claimed were distorted through double counting. + Some opposition members said there appeared to be errors, +but a Liberal Party spokesman refused comment, saying the +package was being reexamined. + "The whole thing is so deceitful," Prime Minister Bob Hawke +said in a radio interview. "Howard has made a mess of it. If +they can't govern themselves, how can they expect to govern the +country?" + Hawke, who is seeking a third term, said the opposition had +made the election one of the easiest for him. + "I've never felt more physically and mentally relaxed +(during an election). We've no problems at all," he said. + The latest public opinion poll, published in the Melbourne +Sun newspaper, showed Labour was leading the opposition by 12 +points, indicating a 66-seat majority for Hawke in parliament. + The Election Commission announced last night that 613 +candidates would contest the 148-seat House of Representatives, +while 255 candidates would fight for the 76 Senate seats. + REUTER + + + +18-JUN-1987 23:58:21.89 + +japan + + + + + +F +f0001reute +u f BC-FUJITSU,-FUJIAN-PROVI 06-18 0108 + +FUJITSU, FUJIAN PROVINCE FORM JOINT VENTURE + TOKYO, June 19 - Fujitsu Ltd <ITSU.T> said it signed a +joint venture agreement with the Post and Telecommunication +Administration Bureau of Fujian Province (PTABF), China to +develop and sell software for the Fujitsu-designed digital +telephone switching machine FETEX-150. + It said in a statement the joint company, <Fujian Fujitsu +Communications Software Ltd> located in Fuzhou city, was +capitalised at about 10 mln yuan and was owned 51 pct by PTABF +and 49 pct by Fujitsu. + It would create about 20 local jobs and has a target of +annual software sales of 330 mln yen in 1992, Fujitsu said. + REUTER + + + +18-JUN-1987 23:59:08.26 + +japan + + + + + +F +f0002reute +u f BC-MITSUI,-ALLIANCE-IN-F 06-18 0116 + +MITSUI, ALLIANCE IN FUND MANAGEMENT TIE-UP + TOKYO, June 19 - <Mitsui Investment Management Co Ltd> +(MIMCL) and <Alliance Capital Management International Inc> +(ACMII) will sign an agreement late this month to cooperate in +international fund management, a ACMII spokesman said. + MIMCL, 55-pct controlled by affiliated companies of Mitsui +Bank Ltd <MIBT.T>, will reconsign some of its foreign +securities investment orders to ACMII, he told Reuters. + ACMII, the London-based 100 pct-owned subsidiary of +<Alliance Capital Management Corp> of New York, will reconsign +some of its foreign orders to MIMCL and instruct MIMCL in +international fund management techniques, the spokesman said. + Both firms were among 56 investment advisory companies +granted Japanese government approval for discretionary fund +management on June 10, the Mitsui spokesman said. + Alliance Capital Management Corp is the world's biggest +firm devoted exclusively to fund management and has 35 billion +dlrs in funds, he said. + Mitsui Investment Co Ltd, established two years ago, +controls about 800 mln dlrs, 80 pct of which is invested in +Japanese equities. + REUTER + + + +19-JUN-1987 00:05:03.32 +alum +indonesia + + + + + +F M C +f0006reute +u f BC-INDONESIA-RAISES-STAK 06-19 0107 + +INDONESIA RAISES STAKE IN ALUMINIUM PLANT + JAKARTA, June 19 - Indonesia has increased its share in a +434-billion-yen aluminium smelter joint venture with Japan from +25 to 37 pct, Asahan Project Authority director A.R. Suhud +said. + The Japanese Export-Import Bank said Indonesia had raised +its share of (P.T. Indonesia Asahan Aluminium) company, +capitalised in 1975 at 91 billion, by swapping 32 billion yen +in government loans to the company for an equity stake. + The Japanese shareholders, the Overseas Economic +Cooperation Fund and 12 companies, are to invest another 24 +billion yen raising capitalisation to 147 billion yen. + Asahan reported total losses of 97.6 billion rupiah between +1982 and 1985. Suhud said much of the company's 320 billion yen +debt had been caused by falling tin prices and the appreciation +of the yen against the U.S. Dollar. Aluminium is sold in +dollars. + Prices improved from 1,150 dlrs a tonne six months ago to +about 1,450 dlrs today. The plant is supposed to break even if +prices stay at 1,500 dlrs a tonne. + Sahud said the plant, with a capacity of 220,000 tonnes a +year, would probably lose money again in 1987. The plant, +situated in North Sumatra, produces mostly for Japan. + REUTER + + + +19-JUN-1987 00:12:36.11 + +philippines + + + + + +F +f0010reute +u f BC-PHILIPPINE-STOCKS-SOA 06-19 0094 + +PHILIPPINE STOCKS SOAR TO NEW HIGHS, RECORD VOLUME + By Greg Hutchinson, Reuters + MANILA, June 19 - Investors on Philippine stock markets +have shrugged off growing communist activity in the cities to +push share prices to all-time highs on record turnover, brokers +said. + Regularly heavy trading of more than one billion shares a +day has sent the Manila exchange's composite index soaring to +775.9 from 577.2 points in just over three weeks. + Brokers described recent trading as "frantic" and "hectic" as +trading records were smashed day after day. + A total 2.6 billion shares worth 259.4 million pesos +changed hands on the main Manila and the less important Makati +exchanges yesterday, with much of the activity among centavo +priced stocks, brokers said. The turnover was more than double +the record of 1.1 billion shares worth 118.1 million pesos set +on Wednesday. + Brokers said rising gold prices caused mining shares to +shoot up three weeks ago, and other sectors followed. Share +prices continued their rise even when the gold price fell back +to 450 dlrs an ounce, due to rising confidence in President +Corazon Aquino's handling of the economy, they said. + Brokers said Aquino's handling of the 18-year-old communist +insurgency and the maintenance of relatively low interest rates +also contributed to the rise. + Blue chip stocks, such as those of San Miguel Corp and +Philippine Long Distance Telephone Co (PLDT), have risen 25 pct +in three weeks, and the trend is upward in the medium term +although a temporary correction is overdue, they said. + Since the surge began on May 26, Manila's Mining index has +risen to 5,700.4 points from 4,042.4, its commercial and +industrial index has shot up to 881.0 from 694.9 points, and +the oils indicator has increased to 4.1 from 2.9 points. + Market activity has been rising in spurts since Ferdinand +Marcos was replaced by Aquino 16 months ago. + One broker said he thought the Philippine stock market "may +at last have come of age." + Wilson Sy, president of Prudential Securities, a local +stockbroking firm with Hong Kong affiliations, told Reuters, +"Barring any unforeseen political events you can bet on the +Philippine market. It has shrugged off the communist inroads +into Manila." + Assassins have killed 52 policemen, soldiers and security +guards in the capital this year. + Communist hitmen known as sparrows have claimed they killed +22 of them. + Sy said Philippine stocks were undervalued in world terms +with price-earnings ratios often half those in Hong Kong and +one-sixth those in Japan. He said PLDT, which is also U.S. +Listed, has a price-earnings ratio of about nine. + Sy predicted Manila's composite index would rise beyond +1,000 points from its current 775.9 mark by year-end. + Other brokers were more cautious, saying Aquino had to +improve peace and order before investors could treat the +Philippines as they would Hong Kong or Tokyo. + One broker said he believed about 30 pct of the money going +into stocks was now foreign, much of it from fund managers and +their agents based in Hong Kong and New York. + Manila Stock Exchange chairman Robert Coyuito told Reuters, +"If the peace and order situation really improved the market +could move beyond a price-earnings ratio of 20 times." + "But all depends on how Congress performs and the local +elections go," he said. + A new two-chamber legislature was elected last month and is +due to sit on July 27. Local elections are scheduled for +November. + PLDT shares closed at 630 pesos a share yesterday, 30 pesos +above Wednesday's record close. PLDT share prices have risen +about nine-fold in 18 months. + San Miguel shares closed at 190 pesos, also a historic +high, brokers said. + REUTER + + + +19-JUN-1987 01:04:05.45 + +canada + + + + + +RM AI +f0043reute +u f BC-CANADIAN-TAX-REFORM-C 06-19 0103 + +CANADIAN TAX REFORM CALLED AN IMPORTANT STEP + By Larry Welsh, Reuters + OTTAWA, June 18 - Canada's sweeping tax reform package, +announced today, is an important step towards a fairer system, +but is not as bold a revamp of the tax structure as some had +expected, economists and business leaders said. + "It's the biggest step towards tax reform we've taken in a +great many years," Merrill Lynch Canada Inc chief economist +Michael Manford told Reuters. + "But the system is the same old system with a lot of +important changes, as opposed to a brand new system," he added. +(See spotlight index page on ECRA) + Manford said changes introduced by Finance Minister Michael +Wilson did not go far enough in simplifying the federal tax +system. They represent evolutionary rather than revolutionary +reform. + "Overall, I thought that it was a more timid step than we +were led to believe," he said. + Wilson's move to increase money collected from corporations +while cutting individual taxes "is probably an acceptable shift," +said Bill James, president of Falconbridge Ltd, an +international mining company. + Wilson spread corporate tax increases fairly evenly across +the corporate sector, James said. "So it's not going to hit +anyone too hard and we will remain competitive." + Wilson said in his speech to the House of Commons that +Canada's tax system needed to be changed to compete with +sweeping reforms in the United States last year. + "The critical thing on the corporate side is that Wilson +moved most of the taxes much closer to the U.S. System," Manford +said. + The federal government increased taxes paid by corporations +by about five billion dlrs over the next five years, but +lowered personal taxes by 11 billion dlrs in the same period. + Despite collecting more corporate taxes, Wilson was able to +lower the tax rate on individual companies by removing many +special tax exemptions and broadening the tax base. + Wilson's plan also reduced the capital cost allowance, used +by companies to write off major investments, which some +business spokesmen said will hurt business in the long run. + "That will affect some investment decisions negatively," said +Laurent Thiebeault, Canadian Manufacturers Association +president. + Tax analysts said for some industries it will take several +days to assess the impact of the capital cost allowance +reductions that will be made over a number of years. + As anticipated, Canada's opposition parties signalled they +intend to fight the new tax measures as they are introduced in +Parliament over the next few months. + "It's not tax reform, it's a tax grab," said Liberal leader +John Turner. + Turner labelled changes to the federal sales tax "a money +machine for the minister of finance." + Wilson broadened the federal sales tax to include +additional products and also promised to introduce a +broad-based, multi-staged sales tax. + "It's not at all a fair package and Canadians are going to +see that very quickly," New Democratic Party leader Ed Broadbent +said. + However, economist Manford said Wilson acted wisely to +protect lower income Canadians by providing tax credits that +will cut 850,000 people from the tax rolls. + REUTER + + + +19-JUN-1987 01:07:20.73 +money-fxreserves +taiwan + + + + + +RM AI +f0050reute +u f BC-TAIWAN-DOLLAR-AND-RES 06-19 0086 + +TAIWAN DOLLAR AND RESERVES SEEN RISING MORE SLOWLY + By Chen Chien-Kuo, Reuters + TAIPEI, June 19 - Recent government moves to curb capital +inflow have temporarily helped to slow the rise of Taiwan's +foreign exchange reserves and to stabilise the local dollar +against the U.S. Currency, officials and bankers said. + Central bank governor Chang Chi-Cheng told reporters the +reserves rose only about 500 mln U.S. Dlrs in the past two +weeks and the local dollar appreciated more slowly against the +U.S. Dollar. + Chang said, "The pace of increase in our reserves is much +slower now than before and our currency is getting more stable." +He said the reserves, mainly the result of the trade surplus +with the U.S., Rose at the rate of two to three billion U.S. +Dlrs a month between January and May. + The reserves, the world's third largest after Japan and +West Germany, now total well over 60 billion U.S. Dlrs. + On June 2 the central bank froze overseas borrowings of +local and foreign banks and cut the limit on central bank +purchases of forward U.S. Dollars from banks to 40 pct from 90 +pct of the value of a contract. + Local and foreign bankers said the June 2 measures had +drastically limited their ability to lend foreign exchange to +importers and exporters. + They said their overseas borrowings and forward dollar +transactions showed a drastic decline with some banks +registering a fall of up to 30 pct. + Bank dealers said the Taiwan dollar has stabilised against +the U.S. Currency this week after rising two to five Taiwanese +cents a day between June 2 and 13 compared with a rise of five +to eight cents in May. + The bank dealers said the central bank, which had +previously bought U.S. Dollars heavily, sold at least 1.1 +billion U.S. Dlrs in the past two weeks to meet commercial +demand. + They said they expected the government to keep the local +dollar stable in the near term to give breathing space to +businesses experiencing slower exports because of the rise of +more than 23 pct in the value of the Taiwan dollar since +September 1985. + The Taiwan dollar opened at 31.09 to the U.S. Dollar today, +unchanged from yesterday. + Keh Fei-Lo, vice president of First Commercial Bank, said, +"It appears the central bank's move to curb the capital inflow +is quite successful." + Vice economic minister Wang Chien-Shien said the slower +rise in foreign exchange reserves would help ease pressure from +Washington over the large U.S. Trade deficit with Taiwan. + Over the past year Taiwanese businessmen have delayed +imports of machinery and production equipment because of +exchange rate uncertainty, he said. The stable exchange rate +would help boost imports, particularly from the United States. + REUTER + + + +19-JUN-1987 01:23:58.25 +alum +japanindonesiabrazil + + + + + +RM AI +f0063reute +u f BC-JAPAN-APPROVES-AID-FO 06-19 0112 + +JAPAN APPROVES AID FOR INDONESIA, BRAZIL ALUMINIUM + TOKYO, June 19 - Japan's cabinet approved a plan to help +financially-troubled aluminium ventures in Indonesia and +Brazil, an official at the Ministry of International and Trade +Industry (MITI) said. + Japan will invest 24 billion yen in <PT Indonesia Asahan +Aluminium> in addition to the 68.3 billion yen already invested +in the company. The government and private interests will +equally share the additional investment, he said. + They will also provide equal shares in 6.3 billion yen in +new investment in the Albras Amazon aluminium project in +Brazil, in addition to the 45.7 billion yen already invested. + The Japan Export-Import Bank will cut its rates on loans to +Asahan and Albras to about five pct from about seven pct, the +official said. + Interest rates on loans by Japan's private banks to the two +projects are expected to be reduced to around five pct from the +current seven to eight pct, but an agreement has yet to be +reached, industry sources said. + Under the rescue scheme for Asahan, in which 91.1 billion +yen has been invested, Indonesia will also extend another 32 +billion yen to the company. This will raise Indonesia's +investment ratio to about 40 pct from the current 25 pct. + The Brazilian government has already agreed to invest an +additional 6.5 billion yen in Albras, in which investment now +totals 93.2 billion yen, but its stake will not change from 51 +pct, the official said. + The sources said the rescue programs for the two projects +were larger than earlier expected, reflecting Japan's desire to +help develop the economies of Indonesia and Brazil and to +stabilise sources of aluminium. + Japan depends on imports for more than 90 pct of its +aluminium demand, which totals some 1.8 mln tonnes a year, they +said. + REUTER + + + +19-JUN-1987 01:38:31.06 +acq +japanusa + + + + + +F +f0069reute +u f BC-MITSUI-BUYS-FIVE-PCT 06-19 0104 + +MITSUI BUYS FIVE PCT STAKE IN U.S. CHIP MAKER + TOKYO, June 19 - Mitsui and Co Ltd <MITS.T> paid 1.5 mln +dlrs in early May for a five pct stake in <Zoran Corp>, a +California-based maker of large scale integrated circuits (LSI) +with computer graphic, communications and medical applications, +a Mitsui spokesman told Reuters. + He said the two firms will form a marketing company in +Japan as early as next year, although details of the joint +venture are not yet fixed. Mitsui expects last year's 10 +billion yen Japanese LSI market to grow quickly. + Zoran was founded in 1981 and now has about 100 employees, +he said. + REUTER + + + +19-JUN-1987 01:59:21.71 + +japan + + + + + +F +f0081reute +u f BC-JAPAN-REPORT-SAYS-FAU 06-19 0100 + +JAPAN REPORT SAYS FAULTY REPAIRS CAUSED JAL CRASH + TOKYO, June 19 - Faulty repairs and inadequate inspection +caused the 1985 crash of a Japan Airlines Co Ltd <JAPN.T> (JAL) +Boeing 747 which killed 520 people, the Japanese government +said in a final official report. + The clear cause of the crash was faulty repair work by the +Boeing Co <BA>, said Shun Takeda, the ministry of transport +official leading the accident investigation committee. + But the report also criticised the ministry's inspectors +for failing to carry out a full check of the repairs before +signing the clearance sheet. + The aircraft hit Mount Osutaka, north of Tokyo, on August +12, 1985, after a bulkhead separating the pressurised cabin +from the unpressurised tail suddenly burst, fracturing key +navigation systems. Only four people survived. + A Japan Air Lines spokesman declined comment on the report. +Boeing is expected to release a statement later today. + The report cleared the JAL crew of all responsibility. + In a separate set of recommendations, the investigators +said large aircraft operating in Japan should have fail-safe +systems, but did not say how this should be done. + A press statement by a group of lawyers representing +victims of the crash criticised the report for not dealing in +greater depth with the fail-safe aspect. + The lawyers said Boeing had showed it believed the crash +was due to design defects by specifying two design +modifications to prevent a recurrence in a memorandum filed in +King County, Washington, Superior Court last March 24. + They said similar official recommendations for fail-safe +systems following two air disasters involving DC-10 aircraft, +near Paris in 1974 and at Chicago in 1979, had been rejected +after objections from aircraft manufacturers. + The government investigators asked the ministry to +formulate concrete guidelines for its inspectors. An internal +ministry memo earlier this year complained that inspectors were +left too much on their own when making aircraft checks. + A Boeing team made repairs to the aircraft's aft bulkhead +under JAL supervision, and Transport Ministry inspectors +approved the repairs without actually seeing them, today's +report said. + The inspectors were unable to check Boeing's work because +the part repaired had been covered by a seal, the report said. + Over time, cabin pressurisation speeded up the process of +metal fatigue in the repaired bulkhead. + Boeing issued an official statement on September 6, 1985, +saying the 1978 repairs it had carried out were faulty. It did +not link them with the crash. + REUTER + + + +19-JUN-1987 02:05:48.53 +trade +japan + + + + + +RM AI +f0088reute +u f BC-JAPAN'S-JUNE-INTERIM 06-19 0095 + +JAPAN'S JUNE INTERIM TRADE SURPLUS NARROWS + TOKYO, June 19 - Japan's custom-cleared trade surplus +narrowed to 1.61 billion dlrs in the first 10 days of June from +1.97 billion a year earlier, the Finance Ministry said. + The June interim surplus compares with a 1.76 billion dlr +surplus in the same May period. + FOB exports in the first 10 days of June rose 17.6 pct from +a year earlier to 6.05 billion dlrs while CIF imports rose 39.6 +pct to 4.44 billion. + The average yen/dollar rate used for the figures was 141.04 +yen against 169.03 a year earlier. + REUTER + + + +19-JUN-1987 02:45:16.79 +earn +japan + + + + + +F +f0106reute +u f BC-C.-ITOH-AND-CO-LTD-<C 06-19 0046 + +C. ITOH AND CO LTD <CITT.T> + TOKYO, June 19 - Year ended March 31 + Group shr 18.83 yen vs 18.73 + Net 20.07 billion vs 18.47 billion + Pretax 22.14 billion vs 25.36 billion + Operating 37.57 billion vs 51.57 billion + Sales 14,762 billion vs 15,900 billion + REUTER + + + +19-JUN-1987 03:01:42.04 + +japan + + + + + +RM AI +f0119reute +u f BC-JAPAN-MACHINERY-ORDER 06-19 0103 + +JAPAN MACHINERY ORDERS FALL IN APRIL + TOKYO, June 19 - Japan's private sector machinery orders, +excluding shipbuilding, fell 10.4 pct in April from March to a +seasonally adjusted 663.8 billion yen, after rising 17.6 pct in +March, the government's Economic Planning Agency said. + April orders rose 2.0 pct from a year earlier after a 22.6 +pct year-on-year rise in March, an agency spokesman told +Reuters. + Seasonally adjusted private sector orders, excluding those +for shipbuilding and electric power firms, fell 7.5 pct in +April from March to 517.4 billion yen, after a 5.7 pct rise in +March from February. + April orders fell 1.3 pct from a year earlier after being +unchanged in March. + The April drop was due mainly to a 12.9 pct decrease in +orders from machine tool industries and a 15.3 pct drop in +orders from car makers, the spokesman said. + REUTER + + + +19-JUN-1987 03:53:39.82 + +japanusa + + + + + +RM AI +f0189reute +u f BC-U.S.-SEEKS-JAPAN-HELP 06-19 0090 + +U.S. SEEKS JAPAN HELP IN EVENT OF 1988 RECESSION + By Rich Miller, Reuters + TOKYO, June 19 - Senior U.S. Officials are looking to Japan +for help in buttressing the world economy in the event of an +American recession next year, Japanese government sources said. + During a visit to the U.S. Earlier this month, Economic +Planning Minister Tetsuo Kondo was asked by both U.S. Federal +Reserve chairman Paul Volcker and Council of Economic Advisers +chairman Beryl Sprinkel what Japan could do if the U.S. Enters +recession next year. + Although Sprinkel indicated that he personally did not +expect a recession next year, Volcker seemed to acknowledge +that an economic downturn was at least a possibility, the +sources said. + Faced with with a huge budget deficit, the U.S. Has little +room to manoeuvre on fiscal policy to counteract any downturn +that might occur in 1988. + It is also hamstrung as far as monetary policy is concerned +because U.S. Inflation is already showing some signs of picking +up, one source said. + But Japan is also limited in what action it could take to +help counteract a U.S. Recession without running the risk of +overstimulating its domestic economy and pushing up inflation, +the sources said. + Money supply growth is accelerating and interest rates are +at record low levels. In May, M-2 money supply plus +certificates of deposit grew at a year-on-year rate of 10.2 +pct, well above nominal GNP growth of four to five pct. + Some government sources are also worried that the recently +announced 6,000 billion yen emergency economic package could +push up land prices and the construction sector's inflation. + Public investment spending grew at a year-on-year rate of +about 10 pct in April, but that could accelerate to 20 pct +later this year under the impact of the emergency package, one +source said. + The 6,000 billion yen package was generally well received +in the U.S., Although U.S. Congressmen and businessmen told +Kondo they wanted the measures implemented quickly, sources +said. + The Japanese minister explained that the acceleration of +public works spending in the package was taking place +immediately, they said. + U.S. Congressmen were particularly interested in how much +impact the package would have on reducing the bilateral trade +imbalance, a question which Kondo was unable to answer clearly, +given the many economic uncertainties involved, the sources +said. + While recognizing that Japan's trade surplus is falling in +terms of volume, some Congressmen expressed concern that it was +not falling fast enough. + But the sources said no one pressed Kondo for a further +rise of the yen as a solution to correcting the bilateral trade +imbalance. + REUTER + + + +19-JUN-1987 03:59:02.90 +acq + + + + + + +F +f0194reute +f f BC-Sainsbury's-says-it-t 06-19 0013 + +******Sainsbury's says it taking control of Shaw's Supermarkets +for 30 dlrs a share + + + + + +19-JUN-1987 04:08:37.39 + +japanindonesiabolivia + + + + + +RM AI +f0206reute +u f BC-JAPAN-TO-MAKE-LOANS-T 06-19 0085 + +JAPAN TO MAKE LOANS TO INDONESIA AND BOLIVIA + TOKYO, June 19 - Japan will lend 27.17 billion yen to +Indonesia and will share equally with the World Bank a 7.25 +billion yen loan to Bolivia as part of its efforts to help +Third World countries, a Foreign Ministry spokesman said. + The lending is in line with Japan's plan to contribute 20 +billion dlrs over the next three years to developing countries. + Both loans will be used for development, the spokesman told +Reuters. He declined to name terms. + REUTER + + + +19-JUN-1987 04:11:27.72 +acq +uk + + + + + +F +f0207reute +b f BC-SAINSBURY'S-TAKING-CO 06-19 0104 + +SAINSBURY'S TAKING CONTROL OF SHAW'S SUPERMARKETS + LONDON, June 19 - J Sainsbury Plc<SNB.L> said it agreed to +take control of the U.S. Shaw's Supermarkets Inc through a +combination of share purchases and a tender offer at 30 dlrs a +share. + Sainsbury bought about 21 pct of the stock in 1983. It said +its U.S. Subsidiary, Chene Investments Inc, bought 2.55 mln +common shares from the controlling Davis family yesterday at 30 +dlrs a share for 76.5 mln dlrs, lifting its stake to 49.4 pct. + A tender offer for the outstanding shares will be launched, +also at 30 dlrs a share for a maximum further cost of 184.4 +mln. + The Shaw's Board and the Davis family has agreed to accept +the offer, thus assuring Sainsbury's a total holding of 74.0 +pct. + The company had allotted 20.18 mln new ordinary shares to +<Warburg Securities Ltd> which it said would be sufficient to +finance about 188 mln dlrs of the maximum 261 mln dlrs payable. + Shaw's operates a chain of 49 supermarkets in +Massachusetts, Maine and New Hampshire which in 1986 produced +sales of 1.1 billiob dlrs and pretax profit of 31.1 mln. At the +end of 1986 it had net assets of 88 mln dlrs. + Last September, Sainsbury's increased its stake in Shaw's +to 28.5 pct. In the year to March 21, it reported a rise in +pretax profit to 246.9 mln stg from 192.7 mln on sales that +increased to 4.04 billion from 3.58 billion. + Sainsbury shares had fallen five pence before the +announcement to 590p from last night's close but were unmoved +by news of the deal. + REUTER + + + +19-JUN-1987 04:20:47.11 + +japan + + + + + +F +f0223reute +u f BC-C.-ITOH-SEES-NO-GROWT 06-19 0108 + +C. ITOH SEES NO GROWTH IN 1987/88 GROUP PROFIT + TOKYO, June 19 - C. Itoh and Co Ltd <CITT.T> said its group +net profit in the year ending March 31, 1988, is expected to be +unchanged from a year earlier. + The prediction assumes a yen/dollar rate of 140 yen and a +crude oil price of 18 dlrs a barrel, a company spokesman told +Reuters. Sales in 1987/88 are estimated at 15,100 billion yen, +up 2.3 pct from a year earlier. + The company earlier reported group net profit of 20.07 +billion yen in the year ended March 31, 1987, up 8.6 pct from a +year earlier, helped by a drop in sales and administration +costs and reduced interest charges. + REUTER + + + +19-JUN-1987 04:25:32.92 + +uk + + + + + +F +f0231reute +r f BC-UBS-TO-SELL-25,000-SA 06-19 0065 + +UBS TO SELL 25,000 SANDOZ SHARES + LONDON, June 19 - Union Bank of Switzerland (Securities) +Ltd said it is lead managing the sale of 25,000 new bearer +shares of Sandoz Ltd. + The shares closed in Zurich yesterday at 12,100 Swiss +francs each. Final terms will be set on, or before, June 25. + The selling concession is two pct while management and +underwriting each pays 3/4 pct. + REUTER + + + +19-JUN-1987 04:25:41.52 +earn +japan + + + + + +F +f0232reute +u f BC-ISUZU-MOTORS-LTD-<ISU 06-19 0066 + +ISUZU MOTORS LTD <ISUM.T> SIX MONTHS TO APRIL 30 + TOKYO, June 19 - + Parent shr loss 15.85 yen vs profit 2.02 + Interim div nil vs nil + Net loss 12.92 billion vs profit 1.65 billion + Current loss 12.52 billion vs profit 4.44 billion + Operating loss 8.76 billion vs profit 6.52 billion + Sales 443.90 billion vs 528.03 billion + Outstanding shrs 815.10 mln vs 814.97 mln + REUTER + + + +19-JUN-1987 04:31:03.46 + +japan + + + + + +F +f0237reute +u f BC-ISUZU-DENIES-PLANS-TO 06-19 0091 + +ISUZU DENIES PLANS TO IMPORT GM CARS TO JAPAN + TOKYO, June 19 - Isuzu Motors Ltd <ISUM.T> has no plans to +import cars made by General Motors Corp <GM.N> to Japan, an +Isuzu spokesman told Reuters. + The Japanese daily Yomiuri Shimbun reported that Isuzu had +decided to import cars directly from GM. + Each month Isuzu's domestic distributors sell five to 10 +cars from GM's Buick, Chevrolet, and Oldsmobile range. + The cars are supplied by Yanase and Co Ltd, a Japanese +importer and distributor. + Isuzu is owned 38.6 pct by GM. + REUTER + + + + diff --git a/src/test/data/reuters-21578/reut2-020.sgm b/src/test/data/reuters-21578/reut2-020.sgm new file mode 100644 index 00000000000..d6af5248bad --- /dev/null +++ b/src/test/data/reuters-21578/reut2-020.sgm @@ -0,0 +1,2041 @@ + + +19-OCT-1987 23:49:31.45 +money-fx +japanusa + + + + + +RM AI +f0001reute +u f BC-IF-DOLLAR-FOLLOWS-WAL 10-19 0105 + +IF DOLLAR FOLLOWS WALL STREET JAPANESE WILL DIVEST + By Yoshiko Mori + TOKYO, Oct 20 - If the dollar goes the way of Wall Street, +Japanese will finally move out of dollar investments in a +serious way, Japan investment managers say. + The Japanese, the dominant foreign investors in U.S. Dollar +securities, have already sold U.S. Equities. + But "if the dollar falls steeply, which did not happen +yesterday, Japanese investors will definitely try to withdraw +significant funds from U.S. Shares," said Akira Kawakami, deputy +manager of Nomura Investment Trust and Management Co Ltd's +international investment department. + An unstable, lower dollar would also affect Japanese +investment in U.S. Bonds. "Japan-U.S. Interest rate +differentials, which currently look wide enough, mean nothing +in the absence of dollar stability," said Kawakami. + U.S. Bonds could benefit due to a gloomy economic picture +following the estimated huge losses in stocks by major U.S. +Institutional and individual investors, he said. The effect +should be to rule out any U.S. Interest rate rise. + But most Japanese investors in U.S. Bonds are still wiating +to see if the dollar really is stable, he said. The dollar was +holding firm at above 142 yen on Tuesday morning. + "Although Japanese investors sold huge amounts of stocks in +New York yesterday, most are still looking for chances to +lighten their U.S. Stock inventories," Hiromitsu Sunada, manager +of Meiji Mutual Life Insurance Co's international investment +department said. + Their sales helped send Wall Street stocks down 508 points +to 1,738, the market's biggest percentage drop since 1914. + "Investment in U.S. Stocks and bonds is difficult, +considering the dangers," said Katsuhiko Okiyama, deputy general +manager and chief adviser of Yamaichi Securities Co Ltd's fixed +income securities marketing group. + Japanese investment at home could start to pick up once +markets have stopped reacting to Wall Street, the managers +said. The Tokyo yen bond market is likely to stabilise in one +or two weeks, which is what investors have been waiting for. +The bottom for yen bonds should be around a 6.3 pct yield for +the 5.1 pct 89th bond, they said. + "The basic background which has supported the stocks and +bonds markets has not changed," said Norio Okutsu, assistant +general manager of Nikko Securities' bond department. "But new +outflows of funds to the U.S. Will be decreasing." However, +this was already evident three months ago, he said. + REUTER + + + +19-OCT-1987 23:58:39.11 + +japanfrance + + + + + +F +f0012reute +u f BC-NEC-TO-SUPPLY-CHIP-TE 10-19 0085 + +NEC TO SUPPLY CHIP TECHNOLOGY TO FRANCE + TOKYO, Oct 20 - NEC Corp <NIPN.T> will supply <Matra-Harris +Semiconducteurs SA(A)> (MHS) of France with manufacturing +technology for 16-bit microchips used in microcomputers, an NEC +spokesman said. + MHS, a joint venture between France's MATRA <MATR.PA> and +Harris Corp <HRS> of the U.S., Will manufacture and market +globally a microcomputer based on NEC's Micron PD 78312 and +Micron PD78310 chips. + MHS will pay NEC an undisclosed sum for the technology. + REUTER + + + +19-OCT-1987 23:59:09.79 + +japan + + +tse + + +RM AI +f0013reute +b f BC-JAPAN-TAKES-WAIT-AND- 10-19 0107 + +JAPAN TAKES WAIT-AND-SEE STANCE ON STOCKS-OFFICIAL + TOKYO, Oct 20 - The Finance Ministry will take a +wait-and-see stance on Tokyo Stock Exchange movement, although +it is gravely concerned about the sharp fall in stock prices, a +senior Ministry official said. + The official, who declined to be identified, told reporters +the 7.3 pct drop in Tokyo stock prices this morning was caused +primarily by psychological factors following the 22.5 pct fall +in New York stock prices overnight. + He said the Ministry is in close contact with the Tokyo +Stock Exchange, but has no plans yet to take any specific +measures regarding the fall. + REUTER + + + +20-OCT-1987 00:08:10.16 + +mexico + + + + + +RM +f0017reute +u f BC-MEXICAN-STOCKMARKET-H 10-20 0112 + +MEXICAN STOCKMARKET HEAD SEES NO CRISIS AFTER FALL + MEXICO CITY, Oct 19 - The outlook for Mexico's economy and +stockmarket remains optimistic despite the market's worst-ever +fall of 52,671.56 points on Monday, the president of the +Mexican stock exchange, Manuel Somoza, said. + He said the 16.51 pct drop in the exchange's index +reflected a "totally emotional" reaction to Monday's fall on the +New York stock exchange and was not a reflection of a new +crisis for the Mexican economy or the stockmarket." + He was speaking at a news conference here on Monday. + "We think that after the psycological effect the market will +tend to stabilize itself," Somoza said. + Somoza said he based his optimism on the relatively bright +outlook of the Mexican economy due to increased income from oil +and non-petroleum exports, record high foreign reserves and +government efforts to promote a modernization of the industrial +sector. + "The U.S. Economy is not the same as the Mexican," he said. +He did not say when he thought the market would stabilize. + He said traders had originally expected the market to level +out on Monday after last week's profit taking pulled the index +down 44,207 points. + News of the "enormous problems" in New York, which reached +Mexico City before the local market opened, caused a flurry of +selling on the Mexican exchange, Somoza said. + The stockmarket had risen 629 pct over the year by the end +of September. + Somoza said Monday's light volume of 15.3 mln shares +compared to an average of 53 mln was an indication the day's +drop was not a sign of a major collapse. + He also denied rumours that the day's loss was the result +of government and brokerage house manipulation. + REUTER + + + +20-OCT-1987 00:15:04.00 +cocoa +indonesiaukmalaysiausapapua-new-guineawest-germanynetherlands + + + + + +T +f0021reute +u f BC-ASIAN-COCOA-PRODUCERS 10-20 0097 + +ASIAN COCOA PRODUCERS EXPAND DESPITE CRITICS + By Jeremy Clift + JAKARTA, Oct 20 - Asian cocoa producers are expanding +output despite depressed world prices and they dismiss +suggestions in the London market that their cocoa is inferior. + "Leading cocoa producers are trying to protect their market +from our product," said a spokesman for Indonesia's directorate +general of plantations. "We're happy about our long-term future." + Malaysian growers said they would try to expand sales in +Asia and the United States if Malaysian cocoa was not suitable +for European tastes. + They were responding to comments by London traders that +large tonnages of unwanted cocoa beans from Malaysia, Indonesia +and Papua New Guinea (PNG) were helping to depress cocoa +prices. + London traders said the Asian cocoa was considered +unsuitable for western palates because of an acrid odour and a +high level of free fatty acids. + Ng Siew Kee, the chairman of Malaysia's Cocoa Growers' +Council, said Malaysia should expand its sales to Asia and the +United States if it did not produce a type suitable for Western +Europe. + A spokesman for the PNG Cocoa Industry Board said the +London market was mistaken if it linked PNG cocoa with +high-acid Malaysian and Indonesian beans. + "When the market is declining, buyers seize on anything to +talk down prices," the spokesman said. + He said that PNG could sell whatever cocoa it produces. + PNG exported 33,000 tonnes of cocoa in the 1986/87 cocoa +year ending September 30, of which nearly 50 pct was exported +to West Germany, 16 pct to the U.S. And the rest to the +Netherlands and Britain. + The Indonesia spokesman, an Agriculture Ministry official +who wished not to be identified, said Indonesia had no problem +with quality and would continue to expand sales. He described +criticism of the quality of Indonesian beans as "trade politics" +and said Jakarta's traditional links with Dutch buyers meant it +did not have any difficulty with exports. + Indonesia and Malaysia, Asia's two biggest commodity +producers, are expanding cocoa output and are both outside the +International Cocoa Organization (ICCO). + Officials have said Malaysian production is expected to +total 150,000 to 155,000 tonnes in calendar 1987. + This is up from 131,000 tonnes in 1986, partly because of +the end of a three-year drought in Sabah, the country's largest +cocoa growing area. + Production of Indonesian cocoa beans tripled to 31,600 +tonnes in calendar 1986 from 10,284 tonnes in 1980. Output is +projected to rise to 50,000 tonnes in 1988 from 38,000 tonnes +this year as young trees mature. + Both Malaysia and Indonesia are low cost producers and +traders said they could last out low prices longer than West +African countries. + According to one Kuala Lumpur trader, world prices would +have to fall another 1,000 ringgit per tonne (about 250 stg) to +make cocoa production in Malaysia uneconomic. + Some traders believe the main quality problem is with +harvesting and fermentation techniques. + One trader said Malaysian cocoa is virtually +indistinguishable from West African output if treated in the +same way but this is not possible on the larger Malaysian +estates. + REUTER + + + +20-OCT-1987 00:20:44.23 + + + + +tse + + +RM AI +f0029reute +f f BC-Tokyo-stock-index-dow 10-20 0012 + +******Tokyo stock index down 2,210.19 points to 23,536.37 in early afternoon +Blah blah blah. + + + + + +20-OCT-1987 00:30:35.73 + +japan +nakasone + + + + +RM AI +f0036reute +b f BC-JAPANESE-PREMIER-SAYS 10-20 0110 + +JAPANESE PREMIER SAYS HE WATCHING STOCK SITUATION + TOKYO, Oct 20 - Japanese Prime Minister Yasuhiro Nakasone +was quoted by Kyodo News Service as saying he was watching the +stock market situation. + "We must watch things a little longer. New York is down 22 +pct, London 10 pct, while compared to this Japan is seven pct +down," Kyodo quoted him as telling reporters. + Asked if he agreed with analysts who called the stock +sell-off "Black Monday," Nakasone said: "Compared with times past, +economics have changed completely." He rejected a comparison +between the present situation and the stock market collapse of +1929 and the recession which followed. + REUTER + + + +20-OCT-1987 00:48:57.47 +crude +malaysia + +opec + + + +Y +f0049reute +u f BC-MALAYSIA-ADVISED-TO-R 10-20 0116 + +MALAYSIA ADVISED TO RAISE CRUDE OIL OUTPUT IN 1988 + KUALA LUMPUR, Oct 20 - Malaysia's national oil company, +Petronas, has advised the government to raise crude oil output +to 540,000 barrels a day (bpd) in 1988 from a current 500,000 +bpd, a senior company official said. + "We have the capacity to produce the amount," Rastam Hadi, +Petronas's Vice-President for Upstream Sector said. + The government will announce its decision on Friday when it +unveils the country's budget. Malaysia raised output this month +to current levels from 420,000 bpd after reviewing the world +oil market. In May, Malaysia cut output to 420,000 bpd from +459,000 in response to a call by OPEC to boost prices. + REUTER + + + +20-OCT-1987 02:15:10.98 +money-fx +usawest-germany +sumita + + + + +RM AI +f0103reute +f f BC-Sumita-welcomes-U.S.- 10-20 0012 + +******Sumita welcomes U.S.-West German joint confirmation of Louvre accord +Blah blah blah. + + + + + +20-OCT-1987 02:18:33.93 + + + + +tse + + +RM AI +f0105reute +f f BC-Tokyo-stock-index-slu 10-20 0010 + +******Tokyo stock index slumps 14.9 pct to close at 21,910.08 +Blah blah blah. + + + + + +20-OCT-1987 02:20:31.11 + + +sumita + + + + +RM AI +f0106reute +f f BC-Sumita-says-world-sto 10-20 0013 + +******Sumita says world stockmarkets excessively concerned about economic future +Blah blah blah. + + + + + +20-OCT-1987 02:29:24.58 +money-fx +japanusawest-germany +sumita + + + + +RM AI +f0111reute +b f BC-SUMITA-WELCOMES-U.S.- 10-20 0109 + +SUMITA WELCOMES U.S.-JAPAN AGREEMENT ON LOUVRE + TOKYO, Oct 20 - Bank of Japan governor Satoshi Sumita said +he welcomed Monday's U.S. And West German joint confirmation of +their commitment to the Louvre accord. + Sumita said in a statement that world stockmarkets were +excessively concerned about the economic future. + The Bank of Japan will continue to adhere to a system of +policy coordination based upon the Louvre accord of February, +he said. The accord called for stability in foreign exchange +rates. Exchange rates generally are regaining stability and the +economies of industrialised nations are heading for a steady +recovery, he said. + REUTER + + + +20-OCT-1987 02:31:05.43 +money-fx +new-zealand + + + + + +RM +f0112reute +u f BC-NEW-ZEALAND-WILL-CONT 10-20 0074 + +NEW ZEALAND WILL CONTINUE FIRM MONETARY POLICY + WELLINGTON, Oct 20 - The Reserve Bank of New Zealand said +there was no evidence to suggest the fall in share prices had +affected financial stability and it would maintain its firm +monetary policy. + Governor Spencer Russell said in a statement the central +bank did not accept arguments that the battle against inflation +should now take a low second priority after the sharemarket's +plunge. + Russell said the bank had two statutory responsibilities -- +to implement the government's monetary policy to bring down +inflation, and to ensure the financial sector's stability. + "Unless the bank is directed otherwise, the firm monetary +policy will continue because it is very much in the national +interest that it do so," he said. + "And there is yet no evidence available to the bank to +suggest that the fall in share prices has affected the +stability of the financial sector." + The Barclays share index fell a record 504.75 points to +2,925,26 on Tuesday, a decline of 14.7 pct. + REUTER + + + +20-OCT-1987 02:51:54.24 + + + + +tse + + +RM AI +f0126reute +f f BC-Tokyo-Stock-Exchange 10-20 0013 + +******Tokyo Stock Exchange has no plan to suspend trading on Wednesday-president +Blah blah blah. + + + + + +20-OCT-1987 02:52:04.37 + + + + +tse + + +F +f0127reute +f f BC-Tokyo-Stock-Exchange 10-20 0013 + +******Tokyo Stock Exchange to ease margin requirements, exchange president says +Blah blah blah. + + + + + +20-OCT-1987 03:02:08.52 +money-supply +japan + + + + + +RM AI +f0132reute +f f BC-Japan-September-M-2-p 10-20 0014 + +******Japan September M-2 plus CD money supply rises 11.1 pct year on year (Aug 11.0) +Blah blah blah. + + + + + +20-OCT-1987 03:12:36.51 + + +james-baker + + + + +RM V +f0146reute +f f BC-BAKER-HEADS-HOME-AFTE 10-20 0013 + +******BAKER HEADS HOME AFTER CUTTING SHORT EUROPE TRIP - SWEDISH FINANCE MINISTRY +Blah blah blah. + + + + + +20-OCT-1987 03:14:08.12 +graincorn +tanzaniamalawimozambiquezaire + + + + + +G +f0147reute +u f BC-TANZANIA-SELLS-MAIZE 10-20 0075 + +TANZANIA SELLS MAIZE TO MALAWI, MOZAMBIQUE, ZAIRE + DAR ES SALAAM, Oct 20 - Tanzania has arranged to sell +53,000 tonnes of maize to Malawi, Mozambique and Zaire, radio +Tanzania said. + The radio said the grain would be delivered soon, but gave +no details about the value of the sales. + Tanzania is expecting a record maize harvest of 2.3 mln +tonnes in the 1987/88 financial year ending June, up from a +bumper crop of 2.1 mln in 1986/87. + REUTER + + + +20-OCT-1987 03:14:33.15 +cotton +tanzania + + + + + +G +f0148reute +u f BC-TANZANIAN-COTTON-THRE 10-20 0100 + +TANZANIAN COTTON THREATENED BY LACK OF STORAGE + DAR ES SALAAM, Oct 20 - About 60,000 tonnes of harvested +raw cotton may be spoiled by rain in Tanzania's northern +Shinyanga region because it is stored in the open or in crude +village sheds, radio Tanzania reported. + The cotton, worth one billion shillings, cannot be moved to +ginneries in the region because most mill warehouses are full. +Many mills are not working because of a lack of spare parts, it +added. + Agriculture Ministry officials have forecast a 1987/88 +cotton harvest of about 200,000 tonnes, down from 215,000 in +1986/87. + REUTER + + + +20-OCT-1987 03:17:41.87 + +japan + + +tse + + +RM AI +f0153reute +b f BC-TOKYO-STOCK-EXCHANGE 10-20 0082 + +TOKYO STOCK EXCHANGE WILL NOT SUSPEND TRADING + TOKYO, Oct 20 - Tokyo Stock Exchange president Michio +Takeuchi said the exchange has no immediate plans to suspend +trading to cool off panic stock selling. + However, he said Tokyo may consider such a measure if the +London and New York exchanges are closed overnight. + "I don't think it will happen," he added. + He also told reporters the exchange will relax margin +requirements effective on Wednesday to encourage stock buying. + Takeuchi said the sharp fall in stock prices was mostly due +to psychological factors. + "We need to keep close watch on market movement but we +expect the market will stabilise soon," he said, adding that +individual investors should remain calm. "It is advisable to +wait for an autonomous recovery of the market," he said. + The margin requirement in cash will be reduced to 50 pct +from 70 pct while the margin collateral requirement in equity +will rise to 70 pct from 60 pct, effective on Wednesday, he +said. + Takeuchi also said the exchange has no specific plan to +take coordinated action with the New York and London exchanges +to help stabilise stock prices. + The drop on Wall Street was caused by various factors but +was primarily the result of a correction of overvalued share +prices, he said. The current stock price plunge cannot compare +with the Great Depression as the economic environment is very +different, he added. + The exchange has not changed plans to introduce stock +futures trading next year despite press reports that the Wall +Street fall was linked with futures trading, he said. + REUTER + + + +20-OCT-1987 03:26:57.39 +interest +philippines + + + + + +RM +f0166reute +u f BC-AQUINO-SAYS-MANILA-WA 10-20 0111 + +AQUINO SAYS MANILA WATCHING INTEREST RATES CLOSELY + MANILA, Oct 20 - President Corazon Aquino said the +Philippines was closely monitoring interest rates in the wake +of Monday's record drop on Wall Street and steep declines in +Manila and other Asian stock markets. + "We will monitor these developments closely and will +continue to hope that they do not precipitate large declines in +economic activity around the world," Aquino told a meeting of 13 +major Philippine business groups. + "The Philippines, as a trading country in the world economy, +depends on the continued health and growth of both the world +economy and the world trading system," she said. + The Manila Stock Exchange composite index plunged 105.49 +points or 11.79 pct by the midday close to 789.54, depressed by +the record 508 point fall of the Dow Jones industrial average +on Monday. + "The Philippines, in addition, as a large borrower nation, +is affected by developments in interest rate levels around the +world and will carefully monitor the impact of these +developments on interest rates, on gold and on commodity +prices," Aquino said. + "We welcome the statements from world leaders that urge calm +in the present difficult situation," she added. + REUTER + + + +20-OCT-1987 03:36:58.94 + +japan + + + + + +F +f0181reute +u f BC-NISSAN-STARTS-TO-MARK 10-20 0101 + +NISSAN STARTS TO MARKET REMODELLED 4WD VEHICLES + TOKYO, Oct 20 - Nissan Motor Co Ltd <NSAN.T> said it has +started to market a remodelled version of its four wheel drive +(4WD) Safari vehicle in Japan. + Nissan said in a statement it hopes to sell 250 vehicles a +month in Japan. + It also plans soon to start exporting 3,400 vehicles a +month to the Australian, Middle East and Asian markets under +the name Patrol, a spokesman said. + It will sell the vehicle in Europe sometime in the future, +with shipments from <Motor Iberica S.A.>, its Spanish unit. The +volume for Europe will be set later. + REUTER + + + +20-OCT-1987 03:38:14.97 + +japan + + + + + +RM +f0182reute +u f BC-JAPAN-TO-SCRUTINISE-L 10-20 0113 + +JAPAN TO SCRUTINISE LIFE INSURERS' CAPITAL GAINS + TOKYO, Oct 20 - The Finance Ministry plans to examine how +life insurance companies realised capital gains through +transactions undertaken in June, just before the yen bond +market began to fall sharply, a senior Ministry official said. + The move is aimed at cooling fierce competition in the +field and will pave the way for a Ministry system to check that +insurers do not inflate investment returns on the accounts to +attract investors, he said. + Some insurers transfer part of their unrealised gains from +general accounts to the variable life accounts, violating their +internal regulations, industry sources said. + The eight major local life-insurers which offer variable +life policies here realised an average return of 21.01 pct on +such policies in the year ended September. + The Ministry will scrutinise the policies of 17 local and +foreign life insurers which offer the variable life schemes. + Japan has 23 major local life insurers, none of which is +listed on the stock market. + REUTER + + + +20-OCT-1987 04:03:13.28 + + + + +lse + + +RM V +f0211reute +f f BC-FTSE-100-share-index 10-20 0013 + +******FTSE 100 share index opens 186.0 down at 1,866.3 - London Stock Exchange +Blah blah blah. + + + + + +20-OCT-1987 04:10:11.01 +money-supply +japan + + + + + +RM AI +f0223reute +b f BC-JAPAN-MONEY-GROWTH-TO 10-20 0110 + +JAPAN MONEY GROWTH TO STAY AT 11-12 PCT - OFFICIAL + TOKYO, Oct 20 - Growth in Japan's M-2 plus certificates of +deposit (CD) money supply in the October to December period is +not expected to accelerate, but will remain at high levels +between 11 and 12 pct, a senior Bank of Japan official said. + The central bank will keep a watch on high growth in +liquidity because this is a factor that may cause rises in +prices of goods, he said. + The September growth of 11.1 pct year on year announced +earlier today should not be taken as implying that the money +supply has started to expand very rapidly, he said. In August +the rate of increase was 11.0 pct. + REUTER + + + +20-OCT-1987 04:11:39.73 + +west-germany + + + + + +F +f0225reute +u f BC-W.GERMAN-CAR-OUTPUT, 10-20 0093 + +W.GERMAN CAR OUTPUT, EXPORTS RISES IN SEPTEMBER + FRANKFURT, Oct 20 - West German car and van production rose +in September to 407,600 from 386,000 in September 1986, while +exports climbed to 226,300 from 218,200, the German Automobile +Industry Association VDA said. + The association added that incoming domestic orders in +September were above, and foreign orders roughly equal, to +those in September last year. + Car and van production rose in the first nine months of the +year to 3.25 mln from 3.19 mln. But exports fell to 1.80 mln +from 1.85 mln + Output of light trucks fell in September to 13,200 from +14,700, while heavy truck production was unchanged at 10,100. + Over the nine month period, light truck production fell to +109,300 from 129,200, while heavy truck production dipped to +83,800 from 84,700. + Exports of light trucks fell in September to 7,800 from +9,000 and to 66,600 from 84,300 in the first nine months. + Exports of heavy trucks rose to 5,500 in September from +4,600 in September last year and to 47,800 from 45,300 in the +first nine months. + REUTER + + + +20-OCT-1987 04:19:37.24 + +new-zealand +douglas + + + + +RM +f0240reute +u f BC-DOUGLAS-SAYS-N.Z.-NOT 10-20 0099 + +DOUGLAS SAYS N.Z. NOT ISOLATED FROM WORLD MARKETS + WELLINGTON, Oct 20 - Finance Minister Roger Douglas said +the fall in share prices on local and world markets +demonstrated that New Zealand could not be isolated from global +trends. + "We can't expect to isolate ourselves from developments +around the world," Douglas told reporters. + "I think above all what today's problems illustrate is that +the sort of policies that we have been putting in place the +last three years are absolutely essential so that New Zealand's +economic performance improves, relative to the rest of the +world." + The New Zealand share market fell 14.7 pct on Tuesday in a +record one-day fall. + Douglas told a news conference, at which the government +announced plans to sell its 89 pct stake in <New Zealand Steel +Ltd>, that the sharemarket fall would not affect plans to sell +parts of state-owned corporations such as <Air New Zealand>, +<DFC New Zealand Ltd> and <Petroleum Corp of New Zealand Ltd>. +Asked if the government considered acting to close the +sharemarket for a period, Douglas said: "No. I'm not sure it +would have been my job to do so." + REUTER + + + +20-OCT-1987 04:21:55.55 + +japanusa + + + + + +RM V +f0243reute +u f BC-WILL-WORLD-RECESSION 10-20 0086 + +WILL WORLD RECESSION FOLLOW STOCK MARKET PLUNGE? + By Linda Sieg + TOKYO, Oct 20 - Some economists fear a world recession if +stock exchanges continue to plunge. Others are more sanguine. + The pessimists say the stocks shakeout is destroying +personal assets and dampening consumption. + "The real economic effects can be significant -- the +destruction of wealth and a deflationary impact on the economy," +said an economist at a U.S. Securities house. + But other economists said such fears were overblown. + "Because of lower appreciation of corporate or personal +assets, that much negative impact could be observed (in the +U.S.)," said Keikichi Honda, general manager of economic +research at the Bank of Tokyo Ltd. + "But the appreciation of stock prices has not been playing +such a major role in the entire U.S. Gross national product +(GNP)," Honda said. + The pessimists noted that the record fall on Wall Street on +Monday was sparked by fears the U.S. Economy is heading for a +recession or serious slowdown much earlier than expected. + But the optimists said a dampening effect on consumption +due to stock market losses was less likely in Japan. + "In Japan the weight of stocks in individuals' total assets +is less than in the U.S., And the total weight of individuals' +holdings in the stock market is less, so there will be less +damage than in the U.S.," said an economist at one of Japan's +major brokerage houses. + "Japan is taking strong measures to stimulate domestic +demand, so while there could be some impact from the reduction +of assets value, it would not be a major impact," said the Bank +of Tokyo's Honda. + Optimists also pointed to incipient declines in U.S. +Interest rates as a positive sign for the U.S. Economy. + "U.S. Interest rates are coming down so there is a feeling +that interest rates have hit their ceiling, and the U.S. +Economy is strong, so there should be no direct impact from the +collapse of share prices," said Toshiaki Kakimoto, Sumitomo Bank +Ltd chief economist. + Some economists suggested that should markets continue to +slump, the major industrial nations may have to discuss +possible joint lowering of official discount rates. + "Until last week, a discussion of lower rates was +unthinkable, now it's not," said the Japanese brokerage house +economist. + "There has been a move from the purely rational to the +emotional -- it's a central bankers' nightmare," said the +foreign economist. "It will require strong global leadership by +politicians to snuff out," he said. + However, "previously, the stocks correction was due to fears +of higher interest rates, a possible resurgence of inflation +and the depreciation of the dollar," said Nobuyuki Ueda, senior +economist at the Long-Term Credit Bank Ltd. + "Now some people have an uneasy feeling about the outlook of +the U.S. Economy," Ueda said. + "If the stock market is a leading indicator of the future +movement of the economy, this decline will have very +significant implications for the U.S. Economy," he said. + "If the low levels hold, those who were keeping consumption +high because of unrealised gains could curb consumption," said +Salomon Brothers (Asia) Ltd economist Ron Napier. "If the paper +gains aren't there, people won't spend." + A U.S. Recession could then trigger similar declines in +other economies, some economists said. + "I don't know if a possible recession in the U.S. Would +trigger a world recession because other nations, such as Japan, +are showing good economic performance," LTCB's Ueda said. "But we +can't rule out the possibility because the U.S. Is still +playing a very dominant role in the world economy." + REUTER + + + +20-OCT-1987 04:25:26.49 + +japan +nakasonemiyazawa + +tse + + +RM V +f0246reute +u f BC-JAPAN-TRIES-TO-STEM-S 10-20 0097 + +JAPAN TRIES TO STEM STOCKS DIVE + By Linda Sieg + TOKYO, Oct 20 - Government and monetary authorities today +staged a concerted effort to calm spreading panic on Japanese +stock exchanges but market analysts said there were limits to +their ability to succeed. + "The ability of the Big Four (Japanese securities houses) +and the Finance Ministry is limited," said Barclays de Zoete +Wedd economist Peter Morgan. + Finance Ministry officials asked the big four securities +companies this afternoon to help calm panic selling on the +Tokyo Stock Exchange, ministry officials said. + Prime Minister Yasuhiro Nakasone was quoted by Kyodo News +Service as saying he was watching the stock market situation. + But he rejected comparisons with the 1929 stock market +collapse and subsequent recession. + Finance Minister Kiichi Miyazawa said the Tokyo stock +market should not be gravely affected by downturns in New York +and London because there are clear signs of a Japanese economic +recovery and exchange rate stability. + Bank of Japan Governor Satoshi Sumita also tried to calm +the panic, saying in a statement that world stock markets were +excessively concerned about the economic future. + Traditionally, the four big houses -- Nomura Securities Co +Ltd, Yamaichi Securities Co Ltd, Daiwa Securities Co Ltd, and +Nikko Securities Co Ltd -- have influenced the market because +of their sheer size and overwhelming market share. + This strength has in the past made it possible for the +brokerages to calm down markets under guidance from the Finance +Ministry, analysts said. + But the analysts questioned whether the brokerages, which +have already suffered heavy losses from falling bond markets +over the past year, would have the strength this time to turn +things around. + "The question is, are the Japanese brokerages strong enough +to force investors to buy," said Johsen Takahashi, research +director at the Mitsubishi Research Institute. + "If we consider that they have suffered serious losses in +the bond markets and in their U.S. Investments, it is debatable +whether they they could support buying," he said. + "We can support things to some extent, but we can't +completely suppress selling," said one Japanese broker. + Some analysts said the high percentage of shares cross-held +by financial institutions and other corporations could have a +stabilising effect on the market. + Some 80 pct of shares are held by corporate shareholders, +said Keikichi Honda, general manager of the Bank of Tokyo Ltd's +economic research division. "This is a tightly woven textile. In +its own way it is stronger than Wall Street." + But other analysts expressed doubt about this argument. + "If a high percent of shares is cross held, everything +happens at the edges and the relative moves can be larger," said +Kleinwort Benson Ltd financial analyst Simon Smithson. "Selling +will drive prices down an enormous distance because of no +liquidity." + "You don't need big volume to get big declines in the market +-- you just need a huge imbalance between sellers and buyers," +said Barclay's Morgan. + Shares held by what are termed "stable shareholders," or +banks and other companies with which a firm does business, +might also find their way onto the market if the outlook gets +bad enough, some analsyst said. + "Closely held shares could become unclosely held," said +Morgan. But he said such a prospect is unlikely right now +because companies, with their improved earnings prospects, do +not need to sell shares for cash flow reasons. + REUTER + + + +20-OCT-1987 04:30:24.90 +crudeship +indonesia +subroto +opec + + + +RM V Y +f0257reute +u f BC-WORLD-COULD-COPE-WITH 10-20 0105 + +WORLD COULD COPE WITH HORMUZ CLOSURE, SUBROTO SAYS + JAKARTA, Oct 20 - Oil prices would skyrocket for a time if +conflict in the Gulf closed the Strait of Hormuz, but oil +supplies could be adjusted to take care of world demand, +Indonesian Energy Minister Subroto said. + He made no explicit reference to the latest U.S. Military +action in the Gulf. + But in an address to a conference of the Indonesian +Petroleum Association, he said, "If worst comes to worst and say +the flow of oil through the Straits of Hormuz is completely +shut off, I believe the world oil supply, given time to adjust, +can take care of the situation." + "But this is not to say that prices, at least for a short +duration, will not skyrocket as speculators take advantage of +the situation," he declared. + Tensions in the Gulf, however, usually had a relatively +short-term impact on prices, he added. + Assessing future price trends, he said, "Short-term spot +prices will probably still fluctuate, but they will most likely +hover around the official Opec price basket of 18 dlrs per +barrel. + "The upward deviations, however, are likely to be greater +than the downward ones." + "The balance between supply and demand in the short term +will still be delicate," he added. "Non-Opec production may still +go up, competing with Opec for the expected additional increase +in world demand." + Subroto, a member of Opec's three-man quota committee which +has been touring cartel members, said speculation may play +havoc with spot prices, but Opec was trying to stabilize the +situation by urging cooperation by non-Opec producers. + In the medium term, non-Opec production would reach a +plateau in the early 1990s, leaving Opec much stronger, he +said. + REUTER + + + +20-OCT-1987 04:34:41.19 +jet +bangladesh + + + + + +Y +f0264reute +u f BC-BANGLADESH-TENDERS-FO 10-20 0059 + +BANGLADESH TENDERS FOR TWO MLN BARRELS PETROLEUM + DHAKA, Oct 20 - Bangladesh Petroleum Corp said it floated +an international tender for imports of two mln barrels of Jet +Kero, Superior Kero and High Speed Diesel for shipment during +January-June 1988. + It said the offer for the petroleum products would be open +until 0600 gmt on November 19. + REUTER + + + +20-OCT-1987 04:48:51.01 +interest + +poehl + + + + +RM V +f0286reute +f f BC-Poehl-says-German-and 10-20 0014 + +****** Poehl says German and international interest rate rises are cause for concern +Blah blah blah. + + + + + +20-OCT-1987 04:49:48.44 + + +poehl + + + + +RM V +f0287reute +f f BC-Bundesbank-has-no-int 10-20 0012 + +****** Bundesbank has no interest in higher capital market rates - Poehl +Blah blah blah. + + + + + +20-OCT-1987 04:53:02.87 +ship +bahrainiran + + + + + +Y +f0289reute +u f BC-IRANIAN-TANKER-REPORT 10-20 0079 + +IRANIAN TANKER REPORTS SIGHTING MINE IN GULF + BAHRAIN, Oct 20 - An Iranian shuttle tanker reported +spotting a floating mine in the central Gulf on Tuesday about +50 miles west of Lavan Island, regional shipping sources said. + The Khark III, owned by the National Iranian Tanker Co, +gave the position of the mine as 27 degrees 14 minutes north, +52.06 east. + There was no indication of measures being taken against the +mine, which is in Iranian territorial waters. + REUTER + + + +20-OCT-1987 04:54:40.64 +acq +uk + + + + + +F +f0290reute +r f BC-FABER-OPEN-FOR-OFFERS 10-20 0093 + +FABER OPEN FOR OFFERS ON MORGAN GRENFELL STAKE + LONDON, Oct 20 - Willis Faber Plc <WIFL.L> chairman and +chief executive David Palmer said the company would consider +any bid for its 20.8 pct shareholding in Morgan Grenfell Group +Plc <MGFL.L> but had not yet received any offers. + "We will entertain any approaches," he told Reuters in reply +to questions, following U.K. Press speculation. + In an earlier statement, Faber said that if an offer were +to be received for its stake in the merchant banking group, "it +would be considered on its merits." + REUTER + + + +20-OCT-1987 04:58:56.26 + + +poehl + + + + +RM V +f0293reute +f f BC-Inflationary-fears-ar 10-20 0011 + +****** Inflationary fears are unjustified and exaggerated, Poehl says +Blah blah blah. + + + + + +20-OCT-1987 04:59:07.79 +acq +ukcanada + + + + + +F +f0294reute +u f BC-CORBY-DISTILLERIES-TO 10-20 0107 + +CORBY DISTILLERIES TO EXPAND IN CANADA + LONDON, Oct 20 - <Corby Distilleries Ltd>, 52 pct owned by +Allied Lyons Plc <ALLD.L> subsidiary <Hiram Walker-Goodman & +Worts> is to buy the spirits business of <McGuinness Distillers +Ltd> of Toronto for 45 mln Canadian dlrs. + McGuinness is a producer and marketer of spirits and also +has exclusive agencies for some imported wines and spirits. + The sale is subject to the approval of the Bureau of +Competition Policy. Michael Jackaman, president and chief +executive officer of Hiram Walker and Allied Vintners, said, +"The acquisition is an excellent one both commercially and +financially." + REUTER + + + +20-OCT-1987 04:59:48.03 +interest +west-germany +poehljames-bakerstoltenberg + + + + +RM V +f0295reute +b f BC-POEHL-SAYS-RATE-RISES 10-20 0088 + +POEHL SAYS RATE RISES ARE CAUSE FOR CONCERN + FRANKFURT, Oct 20 - Rises in West German and international +interest rates are a cause for concern and the Bundesbank has +no interest in higher capital market rates, Bundesbank +President Karl Otto Poehl said. + "We consider the interest rate increase that has occurred +here and internationally to be a problem and cause for concern," +Poehl told an investment conference. + "I would like to stress that the Bundesbank has no interest +in higher capital market rates," he said. + Shortly after Poehl spoke, the Bundesbank announced a +tender for a securities repurchase pact at a fixed rate of 3.80 +pct. + Previous tenders over the last month by interest rate have +seen the allocation rate on these facilities rise to 3.85 pct +at last week's pact from 3.60 on the last fixed-rate tender in +late September. + The Bundesbank's reduction of the key allocation rate to +3.80 from 3.85 pct was heralded Monday by repeated injections +of money market liquidity at between 3.70 and 3.80 pct. + These moves to cap interest rates followed a meeting +between Poehl, Finance Minister Gerhard Stoltenberg and U.S. +Treasury Secretary James Baker Monday in Frankfurt. + Officials said afterwards the three men had reaffirmed +their commitment to the Louvre accord on currency stability. + Over the weekend, criticism by Baker of the tightening in +West German monetary policy had prompted a sharp fall of the +dollar on speculation that Louvre cooperation had ended. + But the dollar rallied on news of Monday's meeting in +nervous trading to trade above 1.79 marks Tuesday. + Poehl said that the recent rise in interest rates was not +due to central bank policy, but to markets' expectations, and +currency developments. + Commenting on the inflationary expectations, Poehl said "You +have to get to the root of the problem, you have to pursue a +policy which reveals that there are no grounds for such fears." + The inflationary fears were unjustified and exaggerated, he +said. + Poehl rebuffed recent U.S. Criticism of West Germany, +saying the Bundesbank had made a substantial contribution to +international cooperation in interest and monetary policy. + The Bundesbank has tolerated an overshooting of its money +supply target, arousing criticism from other quarters, he said. + "Today we still have lower interest rates than at the end of +1986... Quite the contrary of other countries, where interest +rates have risen substantially more," Poehl said. + This had to be taken into account when considering recent +rises in repurchase pact allocation rates, which were due to +rising international money market rates that had spilled over +into the German market, he said. + Poehl expressed surprise that financial markets had so far +ignored improvements in the U.S. Deficits. + "The adjustment process in the U.S. Trade balance is +definitely underway," he said, noting that this was not so +noticeable in absolute figures. + The spectacular improvement in the budget deficit had also +attracted little attention, he said. + REUTER + + + +20-OCT-1987 05:00:49.66 +acq +uk +lawson + + + + +RM +f0296reute +b f BC-LAWSON-SAYS-BP-SHARE 10-20 0108 + +LAWSON SAYS BP SHARE OFFER GOING AHEAD + LONDON, Oct 20 - U.K. Chancellor of the Exchequer Nigel +Lawson said the Government was going ahead with this month's +flotation of British Petroleum Co Plc <BP.L> shares despite the +collapse on international stock markets. + "We are going ahead because the whole issue has been +underwritten - we had it underwritten because there is always a +risk of this sort of thing happening," Lawson said in a BBC +radio interview. + Lawson's remarks came as renewed selling on the London +stock market took BP shares down a further 33p to 283, well +below the 330p price set for the around seven billion stg +issue. + Lawson said the U.K. Economy is fundamentally sound and +added that stock markets had reflected that recently. + "I profoundly believe in the market system as the best way +for securing economic prosperity (but) that does not mean to +say the markets are infallible." + "My advice to small investors...Is to remain calm. There is +absolutely no reason not to do so," Lawson said. + REUTER + + + +20-OCT-1987 05:01:49.86 + + + + + + + +RM +f0300reute +f f BC- 10-20 0014 + +****** Bundesbank sets 35-day securities repurchase tender at fixed rpt fixed 3.80 pct +Blah blah blah. + + + + + +20-OCT-1987 05:03:42.33 + + + + +pse + + +F +f0303reute +f f BC-Paris-share-price-ind 10-20 0010 + +******Paris share price indicator opens 2.31 pct down - official +Blah blah blah. + + + + + +20-OCT-1987 05:05:18.65 + +ukusa +lawson + +lse + + +F +f0305reute +u f BC-LAWSON-CALLS-DEGREE-O 10-20 0114 + +LAWSON CALLS DEGREE OF SHARE FALL ABSURD + LONDON, Oct 20 - U.K. Chancellor of the Exchequer Nigel +Lawson said the severity of the current rout on world stock +markets was an absurd over-reaction sparked on Wall Street by a +spreading lack of confidence in the U.S. Economy. + Lawson said in a BBC radio interview, "This began on Wall +Street. It has a lot to do with the American stock market (and) +a lack of confidence in the U.S. - and some careless talk by +those who should have known better." + In a further wave of selling this morning in London, the +FTSE 100 index had lost a further 233.2 points only 50 minutes +after the official 0800 GMT opening to stand at 1,819.1. + Lawson said a correction on world stock markets was to have +been expected after the bull markets of recent years. "What was +not expected was the severity of the downturn, which quite +frankly is rather absurd." + He said he saw no fundamental signs why the U.S. Economy +should go into recession, adding, "Indeed the possibility of +higher (U.S.) interest rates would certainly in my judgment not +lead the American economy into a recession." + "The only way in which the American economy would go into +recession was if it actually talks itself into recession," he +said. + REUTER + + + +20-OCT-1987 05:06:25.13 + +japan + + + + + +RM AI +f0308reute +u f BC-BANK-OF-JAPAN-SEES-ST 10-20 0114 + +BANK OF JAPAN SEES STEADY ECONOMIC RECOVERY + TOKYO, Oct 20 - The Japanese economy is firmly on the +recovery path, supported by robust domestic demand, the Bank of +Japan said in a regular monthly report. + The report said industrial production is strengthening as +manufacturing companies have almost completed adjustments of +their plant and equipment investment while non-manufacturing +firms have continued to be positive in their capital spending. + Strong domestic demand, such as consumer spending and +housing investment, will more than offset declining exports, +the central bank report said. It also noted the continued rise +in domestic wholesale prices and money supply. + REUTER + + + +20-OCT-1987 05:07:16.01 + + + + +lse + + +RM V +f0311reute +f f BC-London's-FTSE-100-sha 10-20 0011 + +******London's FTSE 100 share index falls below 1,800 - Stock Exchange +Blah blah blah. + + + + + +20-OCT-1987 05:08:54.04 +coconut +philippinesusa + + + + + +G +f0315reute +u f BC-PHILIPPINES-APPLAUDS 10-20 0108 + +PHILIPPINES APPLAUDS DEFEAT OF U.S. LABELLING BILL + By Diane Stormont + MANILA, Oct 20 - The Philippine coconut industry has +greeted with relief the defeat in the U.S. Senate of a bill +requiring some edible oils to be labelled as saturated fats. + The bill, which was defeated by the Senate Agriculture +Committee on Monday, could have cost about 60 mln dlrs a year +in lost exports, the Philippine Coconut Authority (PCA) said. + "Naturally, we welcomed the defeat but there is a chance the +bill will be resurrected and attached as a rider to another +Senate bill," a spokesman for the United Coconut Association of +the Philippines (UCAP). + PCA chairman Jose Romero noted the vote was close, with +eight senators voting for it, 10 against and one abstaining. + The UCAP spokesman said the American Soybean Association +(ASA) had spent about 25 mln dlrs lobbying for the bill. + He said the ASA also had obscured the health issue during +the debate. + "Coconut oil is high in saturated fats, but unlike saturated +animal fats, they do not enter the blood and lymph systems +leaving fatty deposits connected to heart disease," he said. + U.S. Soybean and cottonseed producers had argued that +saturated fats cause heart disease and that the labels would +discourage consumption by health conscious consumers in favour +of domestic unsaturated alternatives. + Opponents of the bill said the proposal discriminated +against imports and would damage the Philippines, Malaysia and +Indonesia. + The Philippines earned 488 mln dlrs from coconut products +in 1986, up from 477 mln in 1985, UCAP figures show. + Exports to the United States for edible and non-edible use +account for about half of that total, PCA's Romero said. + REUTER + + + +20-OCT-1987 05:17:40.79 + +thailand + + + + + +F +f0331reute +u f BC-THAI-STOCKS-PLUNGE-IN 10-20 0091 + +THAI STOCKS PLUNGE IN REACTION TO WORLDWIDE TREND + By Vithoon Amorn + BANGKOK, Oct 20 - Thai stock prices plunged on Tuesday as +nervous investors unloaded shares on reports of steep declines +on major world stock markets. + Brokers said the Securities Exchange of Thailand Index fell +a record 36.64 points, or nearly eight pct, to close at 422.37. + "It's impossible to halt the slide in this situation. The +market just doesn't behave logically," said Sirivat +Voravetvuthikun, executive vice president of Asian Securities +Trading Co Ltd. + But Sirivat said he did not believe the fall would mark the +end of the SET's 16 month bull run, which has accelerated +during the last two months. He expected Thai stocks to +fluctuate widely in the next few weeks. + The slide on Tuesday followed a 13.85 point decline of the +97-stock index on Monday when it closed at 459.01. + Brokers said they were flooded with sell orders when the +market opened this morning and a SET announcement urging +investors not to panic was ignored. + The index reached a record 472.86 last Friday, up 57.7 pct +from end-June and 128.2 pct higher than last December. + SET officials said 77 issues were traded on Tuesday, of +which all but two declined. Of the losers, 68 plummeted the +daily maximum 10 pct allowed by the exchange. Prices on the +special foreign column also fell sharply. + SET vice president Suthichai Chitvanich told reporters the +10 pct floor serves as a restraint, making it unnecessary to +suspend trading should the panic continue. + The Thai exchange has lately been gaining on its own +strength with most buying coming from local investors. + Investors should not be unduly influenced by foreign market +reports, he added. + Suthichai said sound local fundamentals, including low +interest rates and promising economic growth, favoured +investment in the stock market. + The SET also announced it would release third quarter +corporate earnings earlier than expected as part of efforts to +shore up public confidence. + REUTER + + + +20-OCT-1987 05:28:05.60 + + + + +mise + + +F +f0355reute +f f BC-Milan-bourse-opening 10-20 0011 + +******Milan bourse opening delayed one hour to 1200 GMT - official +Blah blah blah. + + + + + +20-OCT-1987 05:31:21.81 +interest +japan + + + + + +RM V +f0357reute +u f BC-TOKYO-STOCK-PLUNGE-CO 10-20 0106 + +TOKYO STOCK PLUNGE COULD FORCE EASIER MONEY POLICY + By Rich Miller + TOKYO, Oct 20 - Plunging Tokyo stock prices will prevent +the Bank of Japan from raising its discount rate and could even +force it to ease monetary policy if the collapse continues, +government and private economists said. + A rise in interest rates now would only serve to spark +further selling of shares that could ultimately have a major +deflationary impact on the real economy, they said. + Although Bank of Japan officials have consistently +maintained that they had no plans to raise the 2.5 pct discount +rate, many in the markets have thought otherwise. + Fears of a rise in the discount rate were fanned by the +central bank's apparent decision last week to countenance +higher rates on commercial bills, dealers said. + But today's stock market collapse -- prices fell nearly 15 +pct -- means that the Bank of Japan would be hard pressed to +raise the discount rate now, despite its concerns about a +renewed outbreak of inflation, dealers and economists said. + Japanese government bond prices rose sharply today as the +markets concluded that the stock market's collapse precluded +the central bank from carrying out the widely-rumoured discount +rate increase. + A senior government economist suggested that both the U.S. +And Japan needed to ease monetary policy now to prevent a +further drop in New York and Tokyo stock prices. "They need to +support the stock and security markets," he said. + But Bank of Japan officials said they saw no need to change +policy for the moment, although one admitted that the central +bank may have to rethink its strategy if Tokyo stock prices +continue to plunge during the rest of the week. + Both government and Bank of Japan economists agreed the +economy is better placed now to cope with the deflationary +impact of plunging stock prices than it was a few months ago. + With the economy recovering strongly, the steep drop in +stock prices is not likely to put a major dent in consumer and +business confidence, one government economist said. + "There will be some impact on the real economy, but it won't +be that big," said another. + Individuals are not heavily invested in stocks on their +own, although they do participate through trust funds and other +investment vehicles. And while many manufacturing firms turned +to financial market investments for profits during last year's +economic downturn, the recent rebound has allowed them to +refocus their attention on their core businesses, he said. + Paradoxically, it is the pick-up in the economy that is +partly to blame for the stock market collapse as companies have +shifted funds away from financial investments to increase +inventories and step up capital spending, one government +economist said. + In deciding what response to make to the steep stock price +drop, the Bank of Japan must first determine whether prices +will continue to fall further and then decide if they pose a +greater economic danger than the threat of higher inflation, +one central bank official said. "That will at least take a +couple of days, if not weeks," he said. + REUTER + + + +20-OCT-1987 05:34:04.54 + + + + +mise + + +F +f0363reute +f f BC-CORRECTED-Milan-Bours 10-20 0014 + +******CORRECTED-Milan Bourse opening delayed an hour to 1000 GMT (NOT 1200 GMT)-official +Blah blah blah. + + + + + +20-OCT-1987 05:43:10.09 + +philippines +aquino + + + + +RM AI +f0379reute +u f BC-AQUINO-SAYS-GROWTH-HA 10-20 0098 + +AQUINO SAYS GROWTH HAS PRIORITY OVER DEBT PAYMENTS + MANILA, Oct 20 - President Corazon Aquino said economic +growth took priority over debt repayments but she sought to +dispel fears that the Philippines would not honour a July +agreement rescheduling 13.2 billion dlrs of debt. + In a speech to 13 major business groups, Aquino said, "Our +policy has been very clear fm the start -- growth must take +priority, for the plain and simple reason that if we have no +money to pay, we can't. And if we starve the nation of +essential services, there may be no one around to honour the +debt." + Aquino said her officials would try to get all 483 creditor +banks to sign the debt rescheduling pact by the November 15 +effective date. + "That should end speculation and remove at least one excuse +for hoarding dollars," Aquino said. + Violent fluctuations in the peso's exchange rate and the +end of a 17-month bull run in local stock markets have +triggered dollar-hoarding. + Aquino said the country's foreign debt, which rose to +nearly 29 billion dlrs in April, was growing even without fresh +borrowing. + Debt servicing took up 40 pct of the budget and 45 pct of +export earnings, Aquino said. Over the next six years, the +Philippines would be paying its creditors 20 billion dlrs while +getting only four billion dlrs in new loans. + Aquino acknowledged there were grave doubts about her +government's ambitious privatisation program. + "There is always an excuse for government not to sell," she +said, but she added: "I want government to get out of business." +She said non-performing assets would be sold in open bidding +and Filipinos and foreigners would compete on equal terms. + REUTER + + + +20-OCT-1987 05:43:53.22 + +ukusa + + + + + +RM +f0380reute +b f BC-E.F.-HUTTON-DENIES-RU 10-20 0113 + +E.F. HUTTON DENIES RUMOURED SOLVENCY PROBLEMS + LONDON, Oct 20 - Brokerage firm E.F. Hutton Group Inc <EFH> +is not facing liquidity problems as a result of the fall on +Wall Street, nor is the firm on the brink of insolvency, London +joint managing director Harry Romney said. + He was replying to Reuter questions about market rumours +that Hutton could be in financial difficulties. + Romney noted the New York-based firm employs 16,000 to +17,000 people worldwide. Questioned on whether Hutton might be +considering cutbacks in line with some other big U.S. +Securities houses, he said Hutton's operations were under +contuous review, but no announcements were imminent. + REUTER + + + +20-OCT-1987 05:46:18.76 +grainrice +philippines + + + + + +G +f0386reute +u f BC-RICE-RESEARCH-INSTITU 10-20 0100 + +RICE RESEARCH INSTITUTE NAMES NEW HEAD + MANILA, Oct 20 - The Manila-based International Rice +Research Institute (IRRI) said West German agricultural +scientist Klaus Lampe will take over as its director-general in +early 1988, succeeding M.S. Swaminathan. + An IRRI statement said Lampe, 56, is currently senior +adviser to the German Agency for Technical Cooperation at +Eschborn and was a former head of the agriculture section of +the Federal Ministry for Economic Cooperation. + It said Swaminathan, who has headed IRRI since 1982, will +concentrate on environmental and agricultural issues. + REUTER + + + +20-OCT-1987 05:46:54.39 + + + + +mise + + +F +f0392reute +b f BC-CONSOB-DELAYS-MILAN-B 10-20 0089 + +CONSOB DELAYS MILAN BOURSE OPENING ONE HOUR + MILAN, Oct 20 - The opening of the Milan bourse and Italy's +nine other stock exchanges has been delayed one hour to 1000 +GMT by stock market regulatory agency Consob. + A Consob spokesman told Reuters the action was taken "to +give operators time to reflect on the agreement between +Treasury Secretary James Baker and West German officials on the +Louvre accord." He did not elaborate. + The Milan Stock Index (MIB), base January 2 equals 1000, +closed down 6.26 pct yesterday. + REUTER + + + +20-OCT-1987 06:07:59.83 + +uk + + +lse + + +RM V +f0436reute +b f BC-STOCK-EXCHAGE-SAYS-NO 10-20 0093 + +STOCK EXCHAGE SAYS NO QUESTION OF HALTING TRADING + LONDON, Oct 20 - A spokeswoman for the London Stock +Exchange said there was no question of trading being suspended +because of the unprecedented three-day drop in prices, which +has seen almost 23 pct wiped off share values. + Trading on the Hong Kong market has been called off until +Monday because of the steep slide on Wall Street amid panic +selling on all the world's stock exchanges. + The Tokyo market was 14.9 pct off last night after a huge +508 point (22.5 pct) fall on Wall Street yesterday. + The Stock Exchange said although the Stock Exchange +Automated Quotation (SEAQ) system was working perfectly, "fast +market" conditions may pevail periodically. + A "fast market" indicator is displayed at the bottom of the +SEAQ screen when the huge volume of activity is delaying prices +from entering the system, making screen prices lag behind the +prevailing market. + Such conditions are reviewed every 30 minutes and at 1000 +GMT were withdrawn and all on screen prices became firm. + The Exchange said the mandatory quote period will still end +at 1600 GMT but depending upon trading activity the market +indices may again be calculated up to 1630 GMT instead of the +usual 1600 GMT. + At 0945 GMT the FTSE 100 share index was down 259.1 points +at 1,793.2, 12.6 pct lower so far today. + REUTER + + + +20-OCT-1987 06:12:19.69 +alum + + + + + + +C M +f0446reute +f f BC-Sept-daily-ave-primar 10-20 0013 + +****** Sept daily ave primary aluminium output 34,900 tonnes, up 400 tonnes, IPAI. +Blah blah blah. + + + + + +20-OCT-1987 06:14:40.08 + + + + + + + +F +f0447reute +f f BC-Blue-Arrow-says-Conse 10-20 0012 + +******Blue Arrow says Conservative Party Chairman Norman Tebbit to join board +Blah blah blah. + + + + + +20-OCT-1987 06:18:31.24 + +south-korea + + + + + +RM +f0462reute +u f BC-SAMSUNG-BOND-GOES-CON 10-20 0118 + +SAMSUNG BOND GOES CONVERTIBLE BUT NO SHARE DEMAND + SEOUL, Oct 20 - The first convertible bond issued by a +South Korean firm overseas -- by Samsung Electronics Co Ltd +<SAMS.SE> -- became eligible for conversion but there was no +demand for shares as the government still bans direct share +ownership by foreigners, a Samsung official said. + "There was no demand from holders, so the lead managers made +no approach to us to issue shares," the official said. + The five pct bond, co-lead managed by S.G. Warburg and +Goldman Sachs Co, raised 20 mln dlrs when issued in 1985. The +only other Korean convertible bonds were issued by Daewoo Heavy +Industries Ltd <DAEW.SE> and <Yukong Ltd>, both in 1986. + REUTER + + + +20-OCT-1987 06:20:40.59 +alum +ukbrazilcuba + + + + + +M +f0470reute +r f BC-GROUNDED-BRITISH-BAUX 10-20 0060 + +GROUNDED BRITISH BAUXITE VESSEL REFLOATED IN ORINOCO + LONDON, Oct 20 - The British bulk carrier Envoy, which ran +aground in the Orinoco river on October 16, was refloated +without lightening on October 19, Lloyds Shipping Intelligence +service said. + The Envoy, 75,453 tonnes dw, was carrying a cargo of 50,000 +tonnes of bauxite from Brazil to Cuba. + REUTER + + + +20-OCT-1987 06:21:43.60 + + + + +zse + + +F +f0472reute +f f BC-Swiss-Stock-Index-fal 10-20 0013 + +******Swiss Stock Index falls 3.7 pct or 38.4 points at opening to 989.5 - official +Blah blah blah. + + + + + +20-OCT-1987 06:27:57.36 + +austriausaussrjapan + +ec + + + +Y +f0483reute +u f BC-EAST,-WEST-APPROVE-NU 10-20 0118 + +EAST, WEST APPROVE NUCLEAR FUSION ENERGY PROJECT + VIENNA, Oct 20 - East and West on Monday decided to go +ahead with an ambitious nuclear fusion project billed as +possibly providing an inexhaustible source of energy, the +International Atomic Energy Agency (IAEA) said. + Representatives of the U.S., The Soviet Union, the European +Community and Japan agreed to develop plans for a revolutionary +thermonuclear reactor, to produce energy not from splitting +atoms as in today's nuclear plants, but by joining them. + Work is due to begin next year at the Institute for Plasma +Physics at the Max Planck Foundation near Munich, West Germany, +and is scheduled for completion by 1990, an IAEA statement +said. + Research into fusion's scientific feasibility has been +under way for many years but the project approved on Monday, +known as International Thremonuclear Experimental Reactor +(ITER) will study if an actual plant could be built. + The project represents an unprecedented display of +East-West scientific cooperation, but a decision will not be +made until its completion on whether an actual reactor would be +jointly constructed or by individual participant countries. + Dieter Sigmar, a leading U.S. Fusion researcher, said last +month that the development of a demonstration plant would cost +several billion dlrs and need at least another 10 years. + Fusion plants would produce little radioactive waste. + While today's nuclear power plants need uranium, mined in +only a few countries and producing dangerous waste, fusion +plants would eventually run only on deuterium, an element +related to hydrogen and available from almost limitless +supplies of sea water, according to experts. + REUTER + + + +20-OCT-1987 06:28:03.88 + +japan +takeshita + + + + +RM +f0484reute +u f BC-TAKESHITA-FACES-TOUGH 10-20 0098 + +TAKESHITA FACES TOUGH ECONOMIC MANAGEMENT JOB + By Tsukasa Maekawa + TOKYO, Oct 20 - Former Finance Minister Noboru Takeshita, +chosen on Monday to be Japan's next prime minister, will face a +tough test in managing Japan's economy from the very start of +his two-year term, economists and businessmen said. + Takeshita told a news conference on Tuesday that he would +do his best to continue the domestic reforms and external +policies of Prime Minister Yasuhiro Nakasone. + However, leading Japanese businessmen called on Takeshita +to outdo Nakasone by showing stronger leadership. + "Takeshita should not merely follow the Nakasone policies +but should cope with mounting economic issues with a new vision +and policies," Takashi Ishihara, chairman of the Japan Committee +for Economic Development, said in a statement. + Economists generally agreed that there will be no major +changes in Japan's economic policies under a new leader. + However, expectations are high among major industries for +new initiatives by Takeshita for immediate and effective +measures to solve economic problems such as trade friction with +the U.S., Administrative and tax reforms, and soaring land +prices. + Eishiro Saito, chairman of the Federation of Economic +Organisations (Keidanren), urged Takeshita to succeed in +unifying the ruling Liberal Democratic Party as soon as +possible to tackle difficult tasks. + Regarding foreign economic polices, Yoshitoki Chino, +chairman of the Japan Securities Dealers Association, said +Takeshita should come up with economic measures well before +economic issues develop into problems. + Behind those calls on Takeshita for prompt action are +doubts about his capability in handling international issues +due to his lack of experience in diplomacy, economists said. + Economists said foreign countries should be patient with +Takeshita, who is widely known as an ultra-cautious politician. + Takeshita has repeatedly said, "There should be consensus +before taking action." + Takeshita has so far failed to unveil specific measures to +reduce Japan's huge trade surplus, economists said. + He has said Japan will continue to stimulate the economy +and to open the market wider to foreign products. + REUTER + + + + diff --git a/src/test/data/reuters-21578/reut2-021.sgm b/src/test/data/reuters-21578/reut2-021.sgm new file mode 100644 index 00000000000..863a69ea707 --- /dev/null +++ b/src/test/data/reuters-21578/reut2-021.sgm @@ -0,0 +1,2002 @@ + + +19-OCT-1987 15:37:46.03 + + + + + + + +F +f2882reute +f f BC-CITYFED-FINANCI 10-19 0013 + +******CITYFED FINANCIAL CORP SAYS IT CUT QTRLY DIVIDEND TO ONE CENT FROM 10 CTS/SHR +Blah blah blah. + + + + + +19-OCT-1987 15:35:53.55 +crudeship +bahrainiranusa + + + + + +Y +f2873reute +r f AM-GULF-PLATFORM 10-19 0101 + +HUGE OIL PLATFORMS DOT GULF LIKE BEACONS + By ASHRAF FOUAD + BAHRAIN, Oct 19 - Huge oil platforms dot the Gulf like +beacons -- usually lit up like Christmas trees at night. + One of them, sitting astride the Rostam offshore oilfield, +was all but blown out of the water by U.S. Warships on Monday. + The Iranian platform, an unsightly mass of steel and +concrete, was a three-tier structure rising 200 feet (60 +metres) above the warm waters of the Gulf until four U.S. +Destroyers pumped some 1,000 shells into it. + The U.S. Defense Department said just 10 pct of one section +of the structure remained. + U.S. helicopters destroyed three Iranian gunboats after an +American helicopter came under fire earlier this month and U.S. +forces attacked, seized, and sank an Iranian ship they said had +been caught laying mines. + But Iran was not deterred, according to U.S. defense +officials, who said Iranian forces used Chinese-made Silkworm +missiles to hit a U.S.-owned Liberian-flagged ship on Thursday +and the Sea Isle City on Friday. + Both ships were hit in the territorial waters of Kuwait, a +key backer of Iraq in its war with Iran. + Henry Schuler, a former U.S. diplomat in the Middle East +now with CSIS said Washington had agreed to escort Kuwaiti +tankers in order to deter Iranian attacks on shipping. + But he said the deterrence policy had failed and the level +of violence and threats to shipping had increased as a result +of U.S. intervention and Iran's response. + The attack on the oil platform was the latest example of a +U.S. "tit-for-tat" policy that gave Iran the initiative, said +Harlan Ullman, an ex-career naval officer now with CSIS. + He said with this appraoch America would suffer "the death +of one thousand cuts." + But for the United States to grab the initiative +militarily, it must take warlike steps such as mining Iran's +harbors or blockading the mouth of the Gulf through which its +shipping must pass, Schuler said. + He was among those advocating mining as a means of bringing +Iran to the neogtiating table. If vital supplies were cut off, +Tehran could not continue the war with Iraq. + Ullman said Washington should join Moscow in a diplomatic +initiative to end the war and the superpowers should impose an +arms embargo against Tehran if it refused to negotiate. + He said the United States should also threaten to mine and +blockade Iran if it continued fighting and must press Iraq to +acknowledge responsibility for starting the war as part of a +settlement. + Iranian and Western diplomats say Iraq started the war by +invading Iran's territory in 1980. Iraq blames Iran for the +outbreak of hostilities, which have entailed World War I-style +infantry attacks resulting in horrific casualties. + Each side has attacked the others' shipping. + Reuter + + + +19-OCT-1987 15:34:40.05 +acq + + + + + + +F +f2863reute +b f BC-CCR-VIDEO-SAYS 10-19 0015 + +******CCR VIDEO SAYST RECEIVED OFFER TO NEGOTIATE A TAKEOVER BY INTERCEP INVESTMENT CORP +Blah blah blah. + + + + + +19-OCT-1987 15:32:25.38 + +canada + + + + + +E F +f2855reute +b f BC-GM-<GM>-CANADA-UNIT-M 10-19 0096 + +GM <GM> CANADA UNIT MAJOR OFFER ACCEPTED BY UNION + TORONTO, Oct 19 - The Canadian Auto Workers' Union said it +accepted an economic offer from the Canadian division of +General Motors Corp <GM> in contract negotiations. + But union president Bob White said many local issues at the +11 plants in Ontario and Quebec still remained unresolved ahead +of Thursday's deadline for a strike by 40,000 workers. + "It minimizes the possibility of a strike," White told +reporters. + However, "if we don't have local agreements settled by +Thursday, there will be a strike," he said. + The local issues still unresolved involved health care, +skilled trades and job classifications, White said. + GM Canada negotiator Rick Curd said he believed a strike +would be avoided. + "Even though there are some tough issues to be resolved +we're on the right schedule to meet the target," Curd said. + "I'm very pleased with the state of the negotiations," he +said. + Union membership meetings have been scheduled for the +weekend in case a tentative settlement, said White. + White said the union has also received assurances that a +job protection pact negotiated with GM workers in the U.S. does +not threaten Canadian jobs. + The economic offer for a three-year pact largely matches +agreements at Ford <F> and Chrysler <C> in Canada, which +include inflation-indexed payments for future retirees and +fixed annual payments for current retirees. + It also gives workers wage increases of three pct +immediately and 1.5 pct in each of the second and third years. + Reuter + + + +19-OCT-1987 15:32:11.59 + +canada + + + + + +E F +f2854reute +u f BC-CANADA-DEVELOPMENT-UN 10-19 0092 + +CANADA DEVELOPMENT UNIT <CDC.TO> REFINANCES + SARNIA, Ontario, Oct 19 - Canada Development Corp said its +<Polysar Ltd> unit completed a refinancing package worth about +830 mln Canadian dlrs. + The company said the financing, which involves 24 banks +and four syndicated loans, consists of a 380 mln Canadian dlr +revolver, a 200 mln Canadian dlr European medium term loan, a +149 mln Canadian dlr revolver and a 100 mln Canadian dlr +operating loan. + The company said the refinancing will reduce borrowing +costs, in addition to having other benefits. + Reuter + + + +19-OCT-1987 15:31:35.28 +crudeship +bahrainusairan + + + + + +C +f2849reute +u f BC-/DIPLOMATS-CALL-U.S. 10-19 0110 + +DIPLOMATS CALL U.S. ATTACK ON OIL RIG RESTRAINED + By Ian MacKenzie + BAHRAIN, Oct 19 - A U.S. attack on an Iranian oil platform +in the Gulf on Monday appeared to be a tit-for-tat raid +carefully orchestrated not to be too provocative or upset Arab +allies, Western diplomats in the region said. + U.S. Defence Secretary Caspar Weinberger said Monday that +U.S. Warships destroyed the oil platform in the southern Gulf +in response to a missile strike on the American-registered +Kuwaiti tanker Sea Isle City in Kuwaiti waters on Friday. + "We consider the matter closed," he said, a signal the U.S. +administration did not want the Gulf crisis to escalate. + Iran had warned the United States earlier in the day +against exacerbating the Gulf crisis, saying military action +would endanger American interests. + Following the raid, a okesman for Tehran's War +Information Headquarters vowed to avenge the attack with a +"crushing blow." + "The United States has entered a swamp from which it can in +no way get out safely," Tehran Radio quoted him as saying. + Diplomats noted, however, Iran was also seeking to avoid +ostracism by Arab states due to meet at a summit in Amman on +November 8 and discuss the Iran-Iraq war. + Iranian Prime Minister Mir-Hossein Mousavi is currently in +Damascus, and diplomats said he would seek Syrian help in +preventing a total Arab breach with Tehran. + Further escalation of the war threatening the Gulf Arab +states could work against Tehran at the Amman gathering, they +said. + "The ball is in Iran's court now. It's up to Tehran to +respond one way or the other," a diplomat said. + President Ronald Reagan warned Iran of stronger American +countermeasures if the military escalation continued. + Western diplomats and military sources in the area said +shelling the platform appeared to be the least provocative act +the United States could have taken once it had decided to +retaliate for the tanker attack, blamed by both the Americans +and Kuwaitis on Iran. + "It's interesting that they chose something in international +waters because it doesn't implicate any other nation," one +diplomat said. "This was better for U.S. Relations with the Gulf +Arab states, particularly Kuwait." + Commented another diplomat: "Kuwait must be happy that the +U.S. Has done something, but relieved that Faw was not attacked +on its doorstep." + One source said of the attack on the oil platform: "They +managed to warn off the crew and hit something that was the +least nuisance to everybody." + A diplomat commented: "They were very clever in the place +they chose. It gets attention, but it hasn't devastated +anything because it wasn't working in the first place." + A senior Arab banker in the area said after the news broke: +"This was a good, measured response without risking a flare-up +... It is a face-saving response (for the Americans)." + Reuter + + + +19-OCT-1987 15:30:22.56 +acq +usafrance + + + + + +F +f2842reute +r f BC-BROWN-DISC-TO-BUY-RHO 10-19 0076 + +BROWN DISC TO BUY RHONE-POULENC <RHON.PA> UNIT + COLORADO SPRINGS, Colo., Oct 19 - Brown Disc Products Co +Inc, a unit fo Genevar Enterprises Inc, said it has purchased +the ongoing business, trademarks and certain assets of +Rhone-Poulenc's Brown Disc Manufacturing unit, for undisclosed +terms. + Rhone-Poulenc is a French-based chemical company. + Under the agreement, Rhone-Poulenc will supply magnetic +tape and media products to Brown Disc Products. + Reuter + + + +19-OCT-1987 15:28:27.68 + + + + + + + +V RM +f2834reute +f f BC-DOW-SINKS-TO-LO 10-19 0011 + +******DOW SINKS TO LOWEST LEVEL OF THE YEAR, DOWN 370 POINTS TO 1876 +Blah blah blah. + + + + + +19-OCT-1987 15:27:23.12 + +usa + + + + + +F +f2832reute +h f BC-LANE-TELECOMMUNICATIO 10-19 0080 + +LANE TELECOMMUNICATIONS PRESIDENT RESIGNS + HOUSTON, Oct 19 - Lane Telecommunications Inc <LNTL.O> said +Richard Lane, its president and chief operating officer, +resigned effective Oct 23. + Lane founded the company in 1976 and has been its president +since its inception, the company said. + He said he resigned to pursue other business interests. + Kirk Weaver, chairman and chief executive officer, said +Lane's resignation was amicable. + No replacement has been named. + Reuter + + + +19-OCT-1987 15:24:34.02 + +usa + + + + + +F +f2824reute +d f BC-PERKIN-ELMER-<PKN>-WI 10-19 0072 + +PERKIN-ELMER <PKN> WINS EPA CONTRACT + NORWALK, Conn., Oct 19 - Perkin-Elmer Corp said it won a +contract to provide laboratory information management systems +to the Enviromental Protection Agency's 10 regional +laboratories. + The value and the exact duration of the contract was not +disclosed. + The company said the contract will include hardware, +software, installation, support services, and software analyst +consultations. + Reuter + + + +19-OCT-1987 15:23:44.84 + +usa + + + + + +F +f2822reute +s f BC-WHIRLPOOL-CORP-<WHR> 10-19 0026 + +WHIRLPOOL CORP <WHR> REG QTLY DIV + BENTON HARBOR, MICH., Oct 19 - + Qtly div 27-1/2 cts vs 27-1/2 cts prior + Pay December 31 + Record December Four + Reuter + + + +19-OCT-1987 15:23:41.70 +earn +usa + + + + + +F +f2821reute +d f BC-CONSOLIDATED-FREIGHTW 10-19 0045 + +CONSOLIDATED FREIGHTWAYS INC <CNF> 3RD QTR NET + PALO ALTO, Calif., Oct 19 - + Shr 43 cts vs 63 cts + Net 16,362,000 vs 24,325,000 + Revs 589.3 mln vs 549.1 mln + Nine Mths + Shr 1.40 dlrs vs 1.73 dlrs + Net 54,011,000 66,591,000 + Revs 1.68 1.58 billion + Reuter + + + +19-OCT-1987 15:23:36.33 +crudeship +usairaniraqkuwait + + + + + +Y RM +f2820reute +u f AM-GULF-FUTURE 10-19 0081 + +LATEST ATTACK SEEN POINTING UP DILEMMAS FOR US + By CHRISTOPHER HANSON + WASHINGTON, Oct 19 - Military experts say the United States +faces a dilemma in the Gulf following U.S. destruction of an +Iranian oil platform in retaliation for an attack on a +U.S.-flagged tanker. + The experts told Reuters Tehran holds the initiative and is +likely to control the tempo and direction of the conflict as +long as America simply reacts to Iranian attacks by launching +limited retaliatory strikes. + But if Washington seizes the initiative with bolder steps +-- such as mining Iran's harbors, blockading its shipping, or +destroying key bases -- it could find itself in a major war. + "Iran is in the driver's seat in an absolute sense as the +cycle of attack and retaliation continues," said Fred Axelgard, +a Gulf War expert with the private Center for Strategic and +International Studies (CSIS). + "It's like a Greek tragedy," said retired Adm. Eugene Carroll +of Washington's private Center for Defense Information (CDI) +think tank. + Some Middle East experts say the only way out is for +Washington to join forces with Moscow in pressing for an end to +the war between Iran and Iraq. + They say it is not feasible for America to withdraw its +30-ship force from the Gulf area, where the Navy began +escorting U.S.-flagged Kuwaiti tankers in July. Withdrawal +would give the appearance of being chased away by Iran, which +President Reagan could never accept. + U.S. Defense Secretary Caspar Weinberger told a Pentagon +news conference the destroyers Kidd, Young, Leftwich and Hoel +fired about 1,000 rounds of five-inch shells at Iran's Rostam +oil rig 120 miles east of Bahrain beginning at about 1400 Gulf +time (0700 EDT) on Monday. + Weinberger said the platform had been used as a military +base by Iran and that the attack responded to an Iranian +Silkworm missile strike on the U.S.-flagged Kuwaiti tanker Sea +Isle City on Friday. + Iranians manning the platform were warned in advance and +allowed to escape. + "We do not seek further confrontation with Iran, but we will +be prepared to meet any escalation of military action by Iran +with stronger countermeasures," Weinberger said. + "We consider this matter closed," he said. + Analysts ranging from the liberal CDI to conservatives +agreed the U.S. reaction was measured, reasonable and did not +escalate the conflict unduly. But they said the question was +whether Iran would consider the matter closed. It had not taken +this view after earlier clashes. + Reuter + + + +19-OCT-1987 15:23:02.47 +earn +usa + + + + + +F +f2817reute +d f BC-ROCHESTER-TELEPHONE-C 10-19 0044 + +ROCHESTER TELEPHONE CORP <RTC> 3RD QTR NET + ROCHESTER, N.Y., Oct 19 - + Shr 96 cts vs 87 cts + Net 10.8 mln vs 9,671,000 + Revs 103.9 mln vs 97.5 mln + Nine mths + Shr 2.73 dlrs vs 2.62 dlrs + Net 30.7 mln vs 29.3 mln + Revs 325.7 mln vs 302.8 mln + Reuter + + + +19-OCT-1987 15:21:54.33 + +usa + + + + + +F +f2815reute +h f BC-NATIONAL-CITY-<NCTY.O 10-19 0106 + +NATIONAL CITY <NCTY.O> UNIT BEGINS NEW SERVICE + CLEVELAND, Oct 19 - National City Corp's National City Bank +unit said it has begun a personal computer-based financial +management service for small businesses. + The service, the InTouch Financial Manager, is based on a +personal computer system develoed by <Harbinger Comput +Services> of Atlanta, and is licensed in Ohio by <Money Station +Inc>, an electronic funds transfer network. + National City said the service will allow businesses to use +a personal computer and a local telephone call to communicate +with their bank to initiate transactions and to receive data +anmessages. + Reuter + + + +19-OCT-1987 15:20:42.71 +earn +usa + + + + + +F +f2813reute +r f BC-SOUTH-CAROLINA-NATION 10-19 0054 + +SOUTH CAROLINA NATIONAL CORP <SCNC.O> 3RD QTR + COLUMBIA, S.C., Oct 19 - + Shr 64 cts vs 55 cts + Net 14.0 mln vs 11.8 mln + Nine mths + Shr 1.83 dlrs vs 1.53 dlrs + Net 39.7 mln vs 32.7 mln + Assets 4.65 billion vs 4.53 billion + Loans 3.24 billion vs 2.92 billion + Deposits 3.32 billion vs 3.15 billion + Reuter + + + +19-OCT-1987 15:19:34.63 +earn +usa + + + + + +F +f2809reute +u f BC-MARINE-CORP-<MCOR.O> 10-19 0056 + +MARINE CORP <MCOR.O> 3RD QTR NET + SPRINGFIELD, Ill., Oct 19 - + Shr 30 cts vs 30 cts + Net 1,804,000 vs 1,800,000 + Nine mths + Shr 89 cts vs 79 cts + Net 5,334,00 vs 4,496,000 + NOTE: Earnings per share reflect initial public offering of +534,750 common shares in March 1986 and 2-for-1 stock splits in +January and June 1986. + Reuter + + + +19-OCT-1987 15:18:52.46 +crude +uknorway + + + + + +F Y +f2807reute +r f BC-STATOIL-AWARDS-VESLEF 10-19 0110 + +STATOIL AWARDS VESLEFRIKK OIL FIELD CONTRACTS + LONDON, Oct 19 - Norwegian state oil company Den Norske +Stats Oljeselskap (Statoil) signed contracts worth a total of +1.5 billion Norwegian crowns in connection with the development +of the Veslefrikk oil field, Statoil said. + Moss Rosenberg Verft of Stavanger has been awarded a +contract to convert the the drilling platform West Vision to a +floating production platform. The work is to be completed in +the summer of 1989. + Aker Verdal has been awarded a contract for the +engineering, purchasing and construction of the steel jacket +for the wellhead platform, also to be completed in 1989, +Statoil said. + Reuter + + + +19-OCT-1987 15:17:20.73 +acq +uk + + + + + +F Y +f2798reute +h f BC-U.K.-TREASURY-CONFIRM 10-19 0106 + +U.K. TREASURY CONFIRMS BP SALE TO GO AHEAD + LONDON, Oct 19 - The British Treasury confirmed that the +sale of British Petroleum Co Plc will go ahead as planned, +despite Monday's stock market crash which forced BP below the +330p a share set for the 7.2 billion stg issue. + "The government are not considering terminating the BP +offer. The offer has been fully underwritten," a Treasury +spokesman said. + The issue, which remains open until October 28, was fully +underwritten last week when the issue price was set. + BP shares closed down 33p at 317p as the FT-SE 100 share +index crashed a record 249.6 points, more than 10 pct. + Reuter + + + +19-OCT-1987 15:14:42.04 + +ugandaegypt + + + + + +RM +f2787reute +r f AM-UGANDA-EGYPT 10-19 0108 + +EGYPT TO BUILD HOUSING ESTATES AND ROADS FOR UGANDA + KAMPALA, Oct 19 - Egypt has agreed to build two housing +estates and two new roads in Uganda worth a total of 295 +million dollars, Egyptian commercial attache Muhammud el Tahan +said. + He said Egyptian companies will build 8,000 housing units +in Kampala and reconstruct the roads between Fort Portal and +Bundibugyo near the Zaire border in western Uganda and between +Kapchorwa and Swam near Mount Elgon in the east of the country. +Uganda would repay 70 per cent of the Egyptian Government +credit to finance the projects in the form of barter goods and +30 per cent in hard currency, Tahan said. + Reuter + + + +19-OCT-1987 15:12:27.51 + + + + + + + +E F +f2781reute +f f BC-UNION-ACCEPTS-G 10-19 0013 + +******UNION ACCEPTS GM CANADA'S ECONOMIC OFFER - MANY LOCAL ISSUES UNRESOLVED +Blah blah blah. + + + + + +19-OCT-1987 15:10:34.40 +earn +usa + + + + + +F +f2773reute +d f BC-HARMAN-INTERNATIONAL 10-19 0044 + +HARMAN INTERNATIONAL <HIII.O> 1ST QTR SEPT 30 + WASHINGTON, Oct 19 - + Shr 30 cts vs 26 cts + Net 2,534,000 vs 1,695,000 + Revs 98.8 mln vs 67.1 mln + Avg shrs 8,447,000 vs 6,563,000 + NOTE: full name of company is harman international +industries inc. + Reuter + + + +19-OCT-1987 15:10:11.16 +money-fx +west-germany + + + + + +RM A +f2771reute +u f BC-GERMAN-BANKER-CALLS-F 10-19 0107 + +GERMAN BANKER CALLS FOR SPECIAL MONETARY MEETING + BONN, Oct 19 - Finance ministers from major industrial +nations should hold a special meeting to deal with the U.S. +Dollar's sharp decline, Helmut Geiger, president of the West +German savings bank association, said. + Geiger told Reuters: "Finance ministers should meet soon to +take confidence-building measures to limit the damage caused by +the dollar's fall." + Separately, Geiger told Bild newspaper in an interview +released ahead of publication on Tuesday that the lower dollar, +which had been artificially talked down by U.S. officials, +would damage West German exports and cost jobs. + Reuter + + + +19-OCT-1987 15:07:16.28 + +usa + + + + + +F A RM +f2754reute +r f BC-FIRST-BOSTON-<FBC>-ST 10-19 0092 + +FIRST BOSTON <FBC> STRATEGIC REVIEW IS UNDERWAY + NEW YORK, Oct 19 - First Boston Inc said it is conducting a +strategic review of its operations as part of a general policy +to periodically evaluate its business plans. + The company said it is too early to predict the outcome of +the review, although it does not expect radical changes in its +organization. + Salomon Inc <SB> last week completed a strategic review +that resulted in substantial layoffs. + Other brokerage firms are either engaged in reviews or have +made major personnel cutbacks. + Reuter + + + +19-OCT-1987 15:07:01.53 + + + + +nyse + + +V RM +f2752reute +f f BC-NYSE-TRADES-MOR 10-19 0010 + +******NYSE TRADES MORE THAN 500 MLN SHARES IN RECORD VOLUME +Blah blah blah. + + + + + +19-OCT-1987 15:06:04.62 + +usa + + + + + +F +f2750reute +s f BC-FEDERAL-SIGNAL-CORP-< 10-19 0025 + +FEDERAL SIGNAL CORP <FSS> REG QTLY DIV + OAK BROOK, ILL., Oct 19 - + Qtly div 20 cts vs 20 cts prior + Pay January Seven + Record December 17 + Reuter + + + +19-OCT-1987 15:06:01.13 + +usa + + + + + +F +f2749reute +d f BC-ENTERTAINMENT-MARKETI 10-19 0061 + +ENTERTAINMENT MARKETING <EM> HEAD TO BUY SHARES + HOUSTON, Oct 19 - Elias Zinn, chairman and chief executive +of Entertainment Marketing Inc, said he planned to personally +purchase up to 500,000 shares of Entertaiment Marketing common +stock from time to time in the open market. + Zinn said his purchases would be subject to availability +and acceptable price levels. + Reuter + + + +19-OCT-1987 15:05:55.95 +earn +usa + + + + + +F +f2748reute +r f BC-THE-BANKING-CENTER-<T 10-19 0053 + +THE BANKING CENTER <TBCX.O> 3RD QTR NET + WATERBURY, Conn., Oct 19 - + Shr 25 cts + Net 3,081,000 vs 2,063,000 + Nine months + Shr 86 cts + Net 10.5 mln vs 6,966,000 + Assets 1.43 billion vs 1.30 billion + Deposits 912.5 mln vs 875.8 mln + NOTE: Company converted to a stock savings bank on Aug 13, +1986. + 1986 results include operations of Realtech Realtors, which +was acquired in 1986. + 1987 results include operations of Burgdorff Realtors, +acquired in December 1986; Cornerstone Mortgage Co, acquired in +July 1987; Centerbank Mortgage Co, acquired in July 1987; and +Center Capital Corp, formed in August 1987. + Reuter + + + +19-OCT-1987 15:05:50.99 + +usa + + + + + +F +f2747reute +r f BC-ROTO-ROOTER-<ROTO.O> 10-19 0072 + +ROTO-ROOTER <ROTO.O> SEES IMPROVED 4TH QTR NET + CINCINNATI, Ohio, Oct 16 - Roto-Rooter Inc said it expects +fourth quarter profits to exceed the 22 cts a share reported +for the final quarter of 1986 and the 23 cts earned in 1987's +third quarter. + It reported the third quarter profit was up pct from the +20 cts a share earned during the quarter in 1986. Nine month +profits were up 23 pct to 64 cts a share from 52 cts last year. + Reuter + + + +19-OCT-1987 15:05:42.30 +acq +usa + + + + + +F +f2745reute +u f BC-CALMAT-<CZM>-SUES-IND 10-19 0082 + +CALMAT <CZM> SUES INDUSTRIAL EQUITY + LOS ANGELES, Oct 19 - CalMat Co said it filed suit in Los +Angeles Superior Court against Industrial Equity (Pacific) Ltd, +against certain of its affiliates and against Ronald Langley, +president of Industrial Equity's North American operations. + The company said its sut charges that Langley +missapropriated material non-public information acquired in his +capacity as a CalMat director and used the information for the +benefit of Industrial Equity. + According to its more recent amendment to its Schedule 13D, +Industrial Equity owned about 19.17 pct of CalMat's stock at +October 14, CalMat said. + It said Industrial has also stated that it intends to +pursue a possible business combination in the near future. + Reuter + + + +19-OCT-1987 15:05:31.45 +trade +usaussr +reaganverity + + + + +F A RM +f2743reute +r f AM-REAGAN-VERITY 10-19 0104 + +REAGAN CALLS FOR VIGILANCE ON CERTAIN EXPORTS + WASHINGTON, Oct 19 - President Reagan said the Commerce +Department should be vigilant in preventing the flow of +strategic technology from reaching the the Soviet Union and +other communist countries. + He was speaking at the swearing in of C. William Verity as +Secretary of the Commerce Department. + Verity said the U.S. should make certain that militarily +sensitive high technology does not wind up in communist +nations. But he also said the U.S. must reduce the list of +products of a nontechnological nature, thereby allowing +manufacturers to increase exports and jobs. + Reuter + + + +19-OCT-1987 15:02:51.54 +earn +usa + + + + + +F +f2726reute +d f BC-WATTS-INDUSTRIES-INC 10-19 0032 + +WATTS INDUSTRIES INC <WATTA.O> 1ST QTR SEPT 27 + ANDOVER, Mass., Oct 19 - + Shr 36 cts vs 27 cts + Net 4,538,000 vs 3,160,000 + Sales 41.8 mln vs 32.8 mln + Avg shrs 12.6 mln vs 11.9 mln + Reuter + + + +19-OCT-1987 15:01:06.27 + +usa + + + + + +F +f2712reute +h f BC-WHIRLPOOL-<WHR>-NAMES 10-19 0070 + +WHIRLPOOL <WHR> NAMES NEW CHAIRMAN + BENTON HARBOR, MICH., Oct 19 - Whirlpool Corp said it named +David Whitwam to the additional position of chairman, effective +December One, replacing Jack Sparks, who retires November 30. + It said Whitwam was elected president and chief executive +officer effective July One. + Sparks will continue to serve on Whirlpool's board of +directors as chairman of the finance committee. + Reuter + + + +19-OCT-1987 14:59:03.82 +earn +usa + + + + + +F +f2706reute +h f BC-MONITERM-CORP-<MTRM.O 10-19 0084 + +MONITERM CORP <MTRM.O> 3RD QTR OPER NET + MINNETONKA, MINN., Oct 19 - + Oper shr profit 13 cts vs nil + Oper net profit 612,806 vs profit 2,363 + Sales 8,317,933 vs 2,823,243 + Nine mths + Oper shr profit 32 cts vs loss four cts + Oper net profit 1,464,338 vs loss 161,315 + Sales 20.3 mln vs 8,241,463 + NOTE: 1987 earnings exclude gains from utilization of tax +loss carryforwards of 321,980 dlrs, or seven cts a share in the +quarter and 772,285 dlrs, or 17 cts a share for the nine months + Reuter + + + +19-OCT-1987 14:57:51.62 + +usa + + + + + +F +f2700reute +h f BC-SEEQ-<SEEQD.O>,-NATIO 10-19 0082 + +SEEQ <SEEQD.O>, NATIONAL SEMI <NSM> IN ACCORD + SANTA CLARA, Calif., Oct 19 - Seeq Technology Corp and +National Semiconductor Corp said they signed a four-year +exclusive technology licensing and manufacturing agreement. + The agreement allows the two companies to share technology +and marketing rights to Seeq's 512-kilobit and one-megabit +semiconductors and for National Semiconductor's 256-Kb FLASH +EEPROMs, the companies said. + Financial terms of the arrangement were not disclosed. + Reuter + + + +19-OCT-1987 14:57:12.59 +earn +usa + + + + + +F +f2697reute +d f BC-ERIE-LACKAWANNA-INC-< 10-19 0047 + +ERIE LACKAWANNA INC <ERIE.O> 3RD QTR NET + CLEVELAND, Oct 19 - + Shr 1.32 dlrs vs 1.59 dlrs + Net 1,217,649 vs 1,471,824 + Total income 1,896,018 vs 2,278,642 + Nine mths + Shr 4.92 dlrs vs 5.38 dlrs + Net 4,553,380 vs 4,979,626 + Total income 6,918,266 vs 8,134,313 + Reuter + + + +19-OCT-1987 14:56:58.45 +earn +usa + + + + + +F +f2696reute +h f BC-QUANTUM-CORP-<QNTM.O> 10-19 0043 + +QUANTUM CORP <QNTM.O> 2ND QTR SEPT 27 NET + MILPITAS, Calif., Oct 19 - + Shr 44 cts vs 30 cts + Net 4,057,000 vs 2,716,000 + Sales 49.5 mln vs 29.6 mln + Six Mths + Shr six cts vs 55 cts + Net 518,000 vs 5,167,000 + Sales 89.7 mln vs 54.9 mln + Reuter + + + +19-OCT-1987 14:56:46.00 +earn +usa + + + + + +F +f2695reute +w f BC-TERMIFLEX-CORP-<TFLX. 10-19 0038 + +TERMIFLEX CORP <TFLX.O> 1ST QTR SEPT 30 NET + MERRIMACK, N.H., Oct 19 - + Shr five cts vs seven cts + Net 64,652 vs 96,157 + Sales 1,205,321 vs 1,499,591 + NOTE: Backlog three mln dlrs vs 2,600,000 as of June 30, +1987. + Reuter + + + +19-OCT-1987 14:56:31.92 +acq +usa + + + + + +F +f2692reute +s f BC-DURAKON-<DRKN.O>-TO-M 10-19 0050 + +DURAKON <DRKN.O> TO MAKE ACQUISITION + LAPEER, Mich., Oct 19 - Durakon Industries Inc said it has +entered into a definitive agreement to acquire DFM Corp, a +maker of bug and gravel protective shields for trucks and cars, +for an undisclosed amount of cash and debentures, retroactive +to September One. + Reuter + + + +19-OCT-1987 14:56:25.95 +acq +usa + + + + + +F +f2691reute +r f BC-CHARTER-CRELLIN 10-19 0089 + +ATLANTIS <AGH> MAY BID FOR CHARTER-CRELLIN<CRTR.O> + WASHINGTON, Oct 19 - Atlantis Group Inc said it bought +100,000 shares of Charter-Crellin Inc common stock, or 6.3 pct +of the total outstanding, and may seek control in a negotiated +transaction. + In a filing with the Securities and Exchange Commission, +Atlantis said it has informally discussed a business +combination with Charter-Crellin management. + But the company said it has not held negotiations with +Charter-Crellin and does not intend to initiate further +discussions. + Pending development of specific proposals, Atlantis said it +will continue to purchase additional Charter-Crellin shares in +private or open market transactions depending on a range of +factors including the market price of the stock. + Atlantis said it bought its Charter-Crellin common stock in +open market transactions between September 22 and October 7 at +14.91 dlrs to 15.62 dlrs a share, or for a total of about 1.51 +mln dlrs. + Reuter + + + +19-OCT-1987 14:56:02.82 +acq +usa + + + + + +F +f2690reute +s f BC-ALLWASTE-<ALWS.O>-TO 10-19 0066 + +ALLWASTE <ALWS.O> TO MAKE ACQUISITION + HOUSTON, Oct 19 - Allwaste Inc said it has agreed in +principle to acquire a privately-held firm that performs +interior cleaning services for tank-trailers for 1,300,000 +common shares. + It said the firm, which it did not name, earned about +1,500,000 dlrs pretax for the first nine mons of 1987. + The company said closing is expected by October 31. + Reuter + + + +19-OCT-1987 14:55:53.51 +earn +usa + + + + + +F +f2689reute +d f BC-TRAVELERS-REAL-ESTATE 10-19 0051 + +TRAVELERS REAL ESTATE <TRAT.O> 3RD QTR NET + BOSTON, Oct 19 - + Shr 18 cts vs 27 cts + Net 444,387 vs 676,593 + Revs 549,437 vs 764,901 + Nine mths + Shr 67 cts vs 81 cts + Net 1,690,670 vs 2,031,937 + Revs 1,986,938 vs 2,302,278 + NOTE: Full name is Travelers Real Estate Investment Trust + Reuter + + + +19-OCT-1987 14:55:34.56 + +usa + + + + + +F +f2687reute +d f BC-SAFEGUARD-<SFGD.O>-TO 10-19 0070 + +SAFEGUARD <SFGD.O> TO BUY BACK MORE SHARES + ANAHEIM, Calif., Oct 19 - Safeguard Health Enterprises Inc +said its board authorized management to step up its stock +repurchase program by doubling the repurchase ceiling to 1.6 +mln shares. + The company also said it has already purchased 691,000 +shares through September 30 under the previous authorization to +buy 800,000 shares, or 10 pct of the stock then outstanding. + Reuter + + + +19-OCT-1987 14:55:26.31 +earn +usa + + + + + +F +f2686reute +u f BC-NEW-YORK-TIMES-CO-<NY 10-19 0042 + +NEW YORK TIMES CO <NYT> 3RD QTR NET + NEW YORK, Oct 19 - + Shr 40 cts vs 33 cts + Net 32.6 mln vs 26.7 mln + Revs 406.5 mln vs 370.1 mln + Nine months + Shr 1.44 dlrs vs 1.20 dls + Net 117.8 mln vs 97.5 mln + Revs 1.2 billion vs 1.1 billion + Reuter + + + +19-OCT-1987 14:55:10.41 +earn +usa + + + + + +F +f2685reute +d f BC-SAFEGUARD-HEALTH-<SFG 10-19 0051 + +SAFEGUARD HEALTH <SFGD.O> 3RD QTR NET + ANAHEIM, Calif., Oct 19 - + Shr 11 cts vs five cts + Net 806,000 vs 384,000 + Revs 18.0 mln vs 15.6 mln + Nine Mths + Shr 28 cts vs 17 cts + Net 2,105,000 vs 1,320,000 + Revs 51.9 mln vs 46.1 mln + Note: Full name Safeguard Health Enterprises Inc. + Reuter + + + +19-OCT-1987 14:55:01.65 +acq +usa + + + + + +F +f2684reute +u f BC-HENLEY-<HENG.O>-ENDS 10-19 0084 + +HENLEY <HENG.O> ENDS TALKS WITH SANTE FE + LA JOLLA, Calif., Oct 19 - Henley Group Inc said it ended +talks with Sante Fe Southern Pacific Corp concerning the +possible acquisition of Sante Fe's Southern Pacific +Transportation Co subsidiary. + The company also said it is reviewing its investment in +Santa Fe Southern Pacific in light of Sante Fe's announcement +that it recieved several bids ranging from 750 mln dlrs to more +than one billion dlrs for its Southern Pafific Transportation +subsidiary. + + Henley said it held discussions with Sante Fe concerning +the acquisition by Henley of Bankers Leasing and Financial Corp +and certain Sante Fe transportation and real estate assets. + Henley said it began talks with Sante Fe after it announced +its restructuring program in August 1987. + As previously disclosed, Henley made necessary filings +under the Hart-Scott-Rodino Antitrust Improvement Acts to +permit Henley to increase its investment in Sante Fe to 24.9 +pct of the outstanding common stock from 5.03 pct. + + Henley said that depending on prevailing conditions, +including price and availability of Sante Fe stock, substantial +developments affecting Sante Fe, other investment and business +opportunities available to Henley, Henley may additional Sante +Fe shares, or sell all or part of its investment in Sante Fe. + Reuter + + + +19-OCT-1987 14:54:15.03 +earn +usa + + + + + +F +f2683reute +d f BC-MERCURY-SAVINGS-AND-L 10-19 0053 + +MERCURY SAVINGS AND LOAN <MSL> 3RD QTR LOSS + HUNTINGTON BEACH, Calif., Oct 19 - + Shr loss 39 cts vs profit 44 cts + Net loss 2,169,000 vs profit 2,417,000 + Nine Mths + Shr profit 56 cts vs profit 1.68 dlrs + Net profit 3,111,000 vs profit 9,317,000 + Note: Full name Mercury Savings and Loan Association +' + Reuter + + + +19-OCT-1987 14:53:33.35 + +usa + + + + + +F +f2679reute +a f BC-CARMIKE-<CMIKA.O>-OPE 10-19 0028 + +CARMIKE <CMIKA.O> OPENS SIX-SCREEN THEATER + COLUMBUS, Ga., Oct 19 - Carmike Cinemas Inc said it has +opened a six-screen theter called Carmike Six in Milledgeville, +Ga. + Reuter + + + +19-OCT-1987 14:53:09.31 +earn +usa + + + + + +F +f2677reute +d f BC-BURNHAM-SERVICE-CORP 10-19 0043 + +BURNHAM SERVICE CORP <BSCO.O> 3RD QTR NET + COLUMBUS, Ga., Oct 19 - + Shr 45 cts vs 36 cts + Net 2,554,000 vs 1,954,000 + Revs 44.4 mln vs 32.5 mln + Nine mths + Shr 1.00 dlrs vs 75 cts + Net 5,461,000 vs 3,756,000 + Revs 109.5 mln vs 89.9 mln + Reuter + + + +19-OCT-1987 14:52:58.11 +acq +usa + + + + + +F +f2676reute +d f BC-TEXAS-AMERICAN-BANCSH 10-19 0087 + +TEXAS AMERICAN BANCSHARES <TXA> TO SELL UNIT + FORT WORTH, Texas, Oct 19 - Texas American Bancshares Inc +said it agreed to sell its Texas American Bank/Levelland unit +to <First American Bancorp Inc> for about 12 mln dlrs in cash. + Texas American said regulatory approval ofthe transaction +is expected in December, and the sale will close shortly +thereafter. + Once the sale is completed, the unit's name will change to +First American Bank of Texas. The unit reported total assets of +196.7 mln dlrs on Juen 30, 1987. + Reuter + + + +19-OCT-1987 14:52:34.06 +acq +usa + + + + + +F +f2675reute +d f BC-SUPERMARKETS-GENERAL 10-19 0113 + +SUPERMARKETS GENERAL <SGL> SELLS 11 DRUG STORES + CARTERET, N.J., Oct 19 - Supermarkets General Corp said it +agreed to sell 11 super drug stores to <F and M Distributors>. + The nine existing and two unopened stores are located in +Maryland, Virginia and upstate New York and are operated under +the Pathmark Super Drug trade name, the company said. + Terms of the transaction were not disclosed. + The nine existing stores generated approximately 34.8 mln +dlrs of Supermarkets General's total sales of 2.9 billion +during the six-month period ended Aug One, 1987. + F and M Distributors operates 42 discount drug stores in +Michigan, Ohio, Illinois, Indiana and Wisconsin. + Reuter + + + +19-OCT-1987 14:51:53.39 + +usa + + + + + +F +f2673reute +r f BC-TRAVELERS-REAL-ESTATE 10-19 0077 + +TRAVELERS REAL ESTATE <TRAT.O> PAYOUT CUT + BOSTON, Oct 19 - Travelers Real Estate Investment Trust + Qtly div 17 cts vs 23 cts in prior qtr + Payable November 25 + Record October 30 + It said the lower dividend reflects the reduction in cash +flow from a mortgage secured by a motel in Covington, La. + The trust said an appraisal is being made of the Covington +property to determine whether an increase in loss reserve will +be required at year end. + + Travelers REIT said its investment adviser, Keystone Realty +Advisers has committed to lend the trust up to 500,000 dlrs for +a term of two years to cover past due payables and capital +improvements on the Covington motel. + Keystone Realty is an affiliate of the Keystone Group, a +Traverlers Corp <TIC> subsidiary. + Reuter + + + +19-OCT-1987 14:51:34.80 +earn +usa + + + + + +F +f2671reute +r f BC-ERC-INTERNATIONAL-INC 10-19 0070 + +ERC INTERNATIONAL INC <ERC> 3RD QTR NET + FAIRFAX, Va., Oct 19 - + Shr 31 cts vs nine cts + Net 1,345,000 vs 368,000 + Revs 31.9 mln vs 26.4 mln + Nine mths + Shr 91 cts vs 40 cts + Net 3,890,000 vs 3,556,000 + Revs 89.3 mln vs 71.7 mln + NOTE: 1986 qtr and nine mths include loss 831,000 dlrs, or +19 cts per share, and loss 1,872,000 dlrs, or 44 cts per share, +respectively, from discontinued operations. + Reuter + + + +19-OCT-1987 14:51:26.65 + +usa + + + + + +F +f2670reute +r f BC-KING-WORLD-<KWP>-SAYS 10-19 0049 + +KING WORLD <KWP> SAYS SHOW EXTENDED + NEW YORK, Oct 19 - King World Productions Inc said its +syndicated television series "The Oprah Winfrey Show" has been +extended through the 1989-90 broadcast season. + It said six of the top 10 markets have renewed the series +through the end of the decade. + Reuter + + + +19-OCT-1987 14:50:41.28 +earn +usa + + + + + +F +f2666reute +u f BC-/PAINEWEBBER-GROUP-IN 10-19 0056 + +PAINEWEBBER GROUP INC <PWG> 3RD QTR NET + NEW YORK, Oct 19 - + Shr 44 cts vs 71 cts + Net 14.8 mln vs 21.1 mln + Revs 628.6 mln vs 605.6 mln + Avg shrs 30,743,000 vs 26,969,000 + Nine mths + Shr 2.01 dlrs vs 1.93 dlrs + Net 65.0 mln vs 57.4 mln + Revs 1.89 billion vs 1.81 billion + Avg shrs 30,782,000 vs 26,619,000 + Reuter + + + +19-OCT-1987 14:49:20.85 + + + + + + + +E RM +f2661reute +f f BC-CANADA-JUNE-BUDGET-DE 10-19 0016 + +*****CANADA JUNE BUDGET DEFICIT 2.66 BILLION DLRS VS YEAR AGO 2.80 BILLION DLRS - OFFICIAL +Blah blah blah. + + + + + +19-OCT-1987 14:47:08.40 + +usa + + + + + +F +f2647reute +d f BC-COUNTRYWIDE-<CCR>-SEE 10-19 0106 + +COUNTRYWIDE <CCR> SEES 3RD QTR NET OF 20 CTS + NEW YORK, Oct 19 - Countrywide Credit Industries Inc said +it expects fiscal third quarter earnings of 20 or 21 cents per +fully diluted share, based on 18 mln shares outstanding. + The company posted net income of 31 cents per fully diluted +share in the previous third quarter ended November 30 last +year, based on 12 mln shares outstanding. + Angelo Mozilo, vice chairman and executive vice president, +also told security analysts that that company should have a +total loan servicing portfolio of 11 billion or 12 billion dlrs +by the end of the current fiscal year, in February 1988. + Countrywide Credit, a financial service company primarily +involved in mortgage banking, reported 4.5 billion dlrs in its +loan servicing portfolio for the last fiscal year. + In addition, Mozilo said the company was continuing to +reduce expenses by one mln dlrs a month and should bring total +costs down by three mln dlrs at the end of the quarter. + He said about 55 pct of the cost cuts were in personnel, +and that the company had reduced the number of its offices +nationwide by 11 in recent months. + Reuter + + + +19-OCT-1987 14:45:58.06 +crude +venezuela + +opec + + + +Y +f2641reute +u f BC-VENEZUELA-SAYS-OPEC-O 10-19 0105 + +VENEZUELA SAYS OPEC OIL OUTPUT 0VER 18 MLN BPD CARACAS, Oct 19 +- The current OPEC oil production is above 18 mln barrels per +day (bpd) and this level threatens the precarious equilibrium +of the of oil market, Venezuelan Energy and Mines Minister +Arturo Hernandez Grisanti said on Monday. + He told reporters three or four countries out of OPEC's 13 +members were mainly responsible for the overproduction, but +declined to identify them. + OPEC's production ceiling for the second half of 1987 is +16.6 mln bpd. The Venezuelan minister said OPEC's production +reached a peak this year when it went over 19 mln bpd in +August. + Hernandez Grisanti, together with the oil ministers of +Nigeria and Indonesia, met the heads of state of six Mideast +Gulf countries earlier this month to urge OPEC members to +comply with assigned production quotas. + He said some of the countries which were complying as +Venezuela, Indonesia, Libya, Algeria, Ecuador, Saudi Arabia and +Iran. + Hernandez declined to say whether the three or four +countries he said were overproducing bordered the Mideast Gulf. + REUTER + + + + + +19-OCT-1987 14:45:13.72 +acq +usa + + + + + +F +f2638reute +b f BC-ATLANTIS-GROUP 10-19 0013 + +****ATLANTIS GROUP TELLS SEC IT SEEKS NEGOTIATED PURCHASE OF CHARTER-CRELLIN +Blah blah blah. + + + + + +19-OCT-1987 14:44:27.84 +acq +usa + + + + + +F +f2634reute +d f BC-DYNASCAN-<DYNA.O>-COM 10-19 0109 + +DYNASCAN <DYNA.O> COMPLETES MANAGEMENT BUYOUT + CHICAGO, Oct 19 - Dynascan Corp said it completed the sale +of its industrial electronic products group and expects to +recognize about a 3.0 mln dlr pretax gain on the transaction in +the fourth quarter. + It said the group was sold October 15 for 13.5 mln dlrs to +Maxtec International Corp, a privately held company created by +the company's management team. + It said the purchase price was 12 mln dlrs in cash and 1.5 +mln dlrs in five-year notes plus warrants to buy 7.0 pct of the +stock of Maxtec. + Dynascan said the group was projected to provide about 12 +pct of its consolidated sales in 1987. + Reuter + + + +19-OCT-1987 14:43:45.78 +acq + + + + + + +F +f2633reute +f f BC-HENLEY-GROUP-RE 10-19 0011 + +******HENLEY GROUP REVIEWING INVESTMENT IN SANTA FE SOUTHERN PACIFIC +Blah blah blah. + + + + + +19-OCT-1987 14:43:38.56 + +usa + + + + + +F +f2632reute +s f BC-PALL-CORP-<PLL>-SETS 10-19 0022 + +PALL CORP <PLL> SETS QUARTERLY + GLEN COVE, N.Y., Oct 19 - + Qtly div 8-1/2 cts vs 8-1/2 cts prior + Pay Nov 13 + Record Oct 30 + Reuter + + + +19-OCT-1987 14:42:48.01 +acq + + + + + + +F +f2628reute +f f BC-HENLEY-GROUP-SA 10-19 0015 + +******HENLEY GROUP SAID IT ENDED TALKS ON BUYING SOUTHERN PACIFIC FROM SANTA FE SOUTHERN +Blah blah blah. + + + + + +19-OCT-1987 14:42:12.65 + + + + + + + +F +f2627reute +f f BC-PAINEWEBBER-GRO 10-19 0009 + +******PAINEWEBBER GROUP INC 3RD QTR SHARE 44 CTS VS 71 CTS +Blah blah blah. + + + + + +19-OCT-1987 14:42:08.28 +acq +spainukusa + + + + + +F +f2626reute +r f BC-RENTA-INMOBILIARIA-SE 10-19 0099 + +RENTA INMOBILIARIA SEEKS CANNON GROUP <CAN> ASSETS + MADRID, Oct 19 - Spanish property firm <Renta Inmobiliaria +SA> is negotiating to buy the property assets of U.S. media +company Cannon Group Inc <CAN>, Renta's finance director Jose +Luis Sanchez said. + Sanchez told Reuters that Renta's chairman Juan Antonio +Robles was currently in the U.S. to negotiate the deal but +declined to give other details. + Interpart, a Luxembourg-based holding company chaired by +Italian financier Giancarlo Paretti, payed around 12.2 billion +pesetas in July to acquire a 63.5 pct stake in Renta +Inmobiliaria. + The Spanish daily newspaper El Pais said the Cannon +property assets sought by Renta included the Elstree film +studios in Britain and a chain of movie-theaters in Europe and +the U.S. + + Reuter + + + +19-OCT-1987 14:41:38.02 + +usa + + + + + +F +f2625reute +r f BC-STOP-AND-SHOP-<SHP>-T 10-19 0035 + +STOP AND SHOP <SHP> TO REPURCHASE SHARES + BOSTON, Oct 19 - Stop and Shop Cos Inc said its board has +authorized the repurchase of up to five pct of its common +shares from time to time at prevailing market prices. + Reuter + + + +19-OCT-1987 14:41:28.16 +crude +usa + + + + + +F Y +f2623reute +u f BC-SOUTHLAND-<SLC>-UNIT 10-19 0078 + +SOUTHLAND <SLC> UNIT RAISES CRUDE OIL PRICES + New York, Oct 19 - Citgo Petroleum Corp, a subsidiary of +Southland Corp, said it raised the contract price it will pay +for all grades of crude oil by 50 cts a barrel, effective Oct +16 + The increase brings Citgo's postings for the West Texas +Intermediate and West Texas Sour grades to 19.00 dlrs/barrel, +while Light Louisiana SWeet is now priced at 19.35 dlrs. + Citgo last changed it crude oil postings on Sept 9. + Reuter + + + +19-OCT-1987 14:41:09.93 + + + + + + + +F +f2621reute +f f BC-NEW-YORK-TIMES 10-19 0008 + +******NEW YORK TIMES CO 3RD QTR SHR 40 CTS VS 33 CTS +Blah blah blah. + + + + + +19-OCT-1987 14:40:54.90 + +usa + + + + + +F +f2619reute +d f BC-<THERMASCAN-INC>-RECE 10-19 0110 + +<THERMASCAN INC> RECEIVES FDA APPROVAL ON DRUG + NEW YORK, Oct 19 - Thermascan Inc said the U.S. Food and +Drug Administration has approved clinical trials of a new, +advanced AIDS confirmation test developed by the company. + Thermascan said that about 10,000 trials will be taken on +the the new test, called Fluorognost in the next three months +through blood banks, hospitals and health centers as well as by +individual physicians. + The trials will be conducted in New York at the Beth Israel +Medical Centre, the Sacremento Medical foundation Blood Center, +the Karolinska Institute, Stockholm, and the Institute of +Hygiene at the University of Innspruck. + Reuter + + + +19-OCT-1987 14:40:47.20 + +usa + + + + + +F +f2618reute +d f BC-GOTTSCHALKS-<GOT>-TO 10-19 0061 + +GOTTSCHALKS <GOT> TO BUY BACK STOCK + FRESCalif., Oct 19 - Gottschalks Inc said its board +authorized management to purchase up to 300,000 of the +company's outstanding shares, or about 3.5 pct of the stock +outstanding, because the company believes its shares are +currently undervalued. + It said the purchases will be made from time to time on the +open market. + Reuter + + + +19-OCT-1987 14:40:42.14 +acq +usa + + + + + +F +f2617reute +r f BC-CCX-INC 10-19 0083 + +GROUP SELLS MOST OF STAKE IN CCX INC <CCX> + WASHINGTON, Oct 19 - A shareholder group including Far +Hills, N.J. attorney Natalie Koether said it reduced its stake +in CCX Inc common stock to 10,000 shares, or less than one pct +of the company's common stock outstanding, from a previous +stake of about ten pct. + In a filing with the Securities and Exchange Commission, +the group said it sold 380,000 CCX common shares on October 15 +at four dlrs a share. + The group gave no reason for the sales. + Reuter + + + +19-OCT-1987 14:40:07.34 + +usa + + + + + +A RM +f2612reute +d f BC-LEISURE-AND-TECHNOLOG 10-19 0070 + +LEISURE AND TECHNOLOGY <LVX> SELLS NOTES + NEW YORK, Oct 19 - Leisure and Technology In is raising +40 mln dlrs through an offering of notes due 1999, said sole +manager Merrill Lynch Capital Markets. + The notes have a 15-3/4 pct coupon and were priced at par. + Non-callable for three years and non-refundable for five +years, the issue is rated B-2 by Moody's Investors Service Inc +and B by Standard and Poor's Corp. + Reuter + + + +19-OCT-1987 14:39:55.20 +acq +usa + + + + + +F +f2611reute +r f BC-TWIN-DISC 10-19 0106 + +ORION <OC> HAS 5.2 PCT TWIN DISC <TDI> STAKE + WASHINGTON, Oct 19 - Orion Capital Corp said it acquired +163,000 shares of Twin Disc Inc common stock, or 5.2 pct of the +company's common stock outstanding. + In a filing with the Securities and Exchange Commission, +Orion Capital said the stock represents "a favorable investment +opportunity at current market prices." + In open market transactions between August 21 and October +16, an Orion Capital subsidiary bought 56,200 Twin Disc common +shares at 21.06 dlrs to 22.43 dlrs a share. The entire 5.2 pct +stake was purchased at a cost of 3.2 mln dlrs, Orion Capital +told the SEC. + + Reuter + + + + diff --git a/src/test/data/utf8text/arabic_utf8.txt b/src/test/data/utf8text/arabic_utf8.txt new file mode 100644 index 00000000000..36efbf59555 --- /dev/null +++ b/src/test/data/utf8text/arabic_utf8.txt @@ -0,0 +1,15 @@ +ﻞﻴﻤﻳﺭ + +استبعدت تونس كابتن منتخبها القومي خالد بدرة من المجموعة الخامسة في كأس العالم أمام ملاوي في 26 مارس/ آذار. + +وكان كابتن المنتخب القومي روجر ليمير قد استبعد بدرة، 32 عاما، والذي قاد فريق بلاده في كأس الأمم الإفريقية، من الفريق الذي يضم 23 لاعبا يوم الثلاثاء. + +وقد تم استبدال بدرة بالمهاجم علاء الدين يحيى المعار حاليا إلى فريق سان اتيان الفرنسي من فريقه الإنجليزي ساوثامبتون. + +كما سيلعب منتخب تونس المعروف باسم نسور قرطاج دون لاعب الوسط عادل شيلدي الذي أوقف عن اللعب. + +ومن المقرر أن تمثل المباراة فرصة لتونس لاستعادة اللاعب الفرنسي المولد حامد ناموتشي. + +وكان ناموتشي، 20 عاما، لاعب الوسط والذي يلعب لصالح الفريق الاسكتلندي رينجرز يلعب مع الفريق القومي في فبراير/ شباط في المباراة الودية أمام تركيا غير أن المباراة ألغيت بسبب سوء الأحوال الجوية. + +ووفقا لقوانين الاتحاد الدولي لكرة القدم (الفيفا) يسمح للاعب كرة القدم تمثيل دولة أخرى طالما يحمل جنسية مزدوجة ويطلب تغيير الجنسية قبل سن 21. diff --git a/src/test/data/utf8text/chinese_utf8.txt b/src/test/data/utf8text/chinese_utf8.txt new file mode 100644 index 00000000000..f572690b18c --- /dev/null +++ b/src/test/data/utf8text/chinese_utf8.txt @@ -0,0 +1,32 @@ +啤酒 +酒 +青島啤酒與美國釀酒商合作 + + + +百威啤酒是安海斯-布希公司產品之一 +中國青島啤酒集團和世界最大釀酒商美國安海斯-布希公司(Anheuser-Busch)達成協議,組成商業策略聯盟。 + +安海斯-布希公司是生產百威啤酒(Budweiser Beer)的公司。 + +安海斯-布希和青島兩家公司將結合雙方的資源,進一步拓展中國的市場。 + +青島啤酒表示,兩家公司合資的詳情仍有待商討。 + +安海斯-布希已經持有青島4.5%的股權。 + +青島對安海斯-布希來說,吸引力非常大,主要是由於青島遍及龐大中國市場的每個角落。 + +青島一直收購小型釀酒商,提高其市場佔有率。青島目前的市場佔有率是11%。該公司表示,市場佔有率每年增長6%。 + +預料該公司在2002年1月到6月的盈利增長了50%,即超過1億元人民幣。 + +世界上30多個國家均有出售青島啤酒。 + +来 +《译员》下月将全球同步上映 妮可将有望来华 + +更新 来源:千龙新闻网 第1页/共1页 << 上一页 | 下一页 + +因为将参演王家卫的《从上海来的女人》,好莱坞著名女星妮可·基德曼在中国内地的人气激增。记者昨天了解到,由她主演的好莱坞大片《国家翻译员》作为今年内地首部全球同步引进大片,将于4月22日公映,而妮可本人将有望来华参加该片的宣传活动 + diff --git a/src/test/data/utf8text/czech_utf8.txt b/src/test/data/utf8text/czech_utf8.txt new file mode 100644 index 00000000000..54ff2a20c7e --- /dev/null +++ b/src/test/data/utf8text/czech_utf8.txt @@ -0,0 +1,78 @@ +Budějovický +Základní +informace Naše mise + +Tradice: Při výrobě originálního budějovického ležáku Budweiser Budvar používáme tradiční postupy a stavíme na znalostech a vědomostech, které nám zanechaly generace sládků. + +Kvalita: Naše pivo vaříme z nejkvalitnějších surovin, žateckého chmelu, moravského sladu a vody z našich vlastních artéských studní. + +Jedinečnost:Díky lahodné chuti a jedinečnému složení a charakteru vyhledávají náš ležák tisíce milovníků kvalitních piv prakticky po celém světě. + +Originalita: Kdekoli na světě si koupíte Budweiser Budvar, můžete si být jisti, že byl vyroben v místě svého původu Českých Budějovicích (dříve Budweis). Proto se můžeme v rámci přístupu České republiky do Evropské unie pyšnit "ochranou podle místa původu" pro naše výrobky. + +Pivovar Budějovický Budvar + +Kvalita a věhlas budějovického piva, jehož historie sahá až do 13. století, vedly k tomu, že originální receptura i jeho jméno byly často předmětem napodobování a kopírování. + +Pivovar Budějovický Budvar je dlouhodobě jedním z nejúspěšnějších potravinářských podniků v České republice. Téměř polovina produkce je úspěšně prodávána ve více než 60 zemích celého světa. + +Novodobá historie pivovaru se datuje do roku 1967, kdy Ministerstvo zemědělství České republiky založilo národní podnik Budějovický Budvar jako přímého nástupce Českého akciového pivovaru, který vařil pivo v Českých Budějovicích již od roku 1895. Ten byl založen českými právovárečníky, kteří navázali na více než 700 let starou historii vaření piva v Českých Budějovicích (dříve Budweis). + +Budějovický Budvar vlastní cenné duševní vlastnictví v podobě více než 380 ochranných známek registrovaných ve 101 zemích světa. Mezi nejznámější patří Budweiser, Budvar, Budweiser Budvar, Bud, Budějovický Budvar a Czechvar. Toto ohromné duševní bohatství souvisí s místem svého původu, městem České Budějovice, dříve Budiwoyz či Budweis. + +Postupnou a cílevědomou expanzí na zahraniční trhy a posilováním prodejů doma dosáhl Budějovický Budvar pozice klíčového hráče na trhu piva nejen v České republice. Objem exportovaného výstavu řadí prémiový originální ležák Budweiser Budvar k jedné z nejexportovanějších pivních značek České republiky. V Budějovickém Budvaru, n. p., dnes pracuje přes 670 zaměstnanců. + +Hlavní představitelé pivovaru + +Ing. Jiří Boček – ředitel +Ing. Josef Tolar – sládek +Ing. Petr Jánský – finanční a ekonomický manager +Ing. Robert Chrt – obchodní manager +česky english deutsche Úvod Mapa stránek + +Katalog výrobků +Katalog výrobků +To nejvzácnější, co máme … + +Naše vlastní vyšlechtěná kultura kvasinek (Saccharomyces cerevisiae subsp. uvarum), která dozrává pod pečlivým dohledem sládků, otváří tu nejjemnější součást lahodné chuti našeho piva. + +K výrobě našeho piva jsou použity jen ty nejkvalitnější suroviny a každá z nich je pro jeho unikátní chuť neméně důležitá. + +Panensky čistá přírodní voda, která čekala téměř 10 000 let na vysvobození z našich 300 m hlubokých artéských studní, dotváří jeho nezaměnitelnou lahodnou chuť, kterou oceníte pokaždé, když se napijete. + +Naše pivo vyniká dokonalou harmonickou chutí. Její základ tvoří kombinace těch nejkvalitnějších domácích surovin a dlouholetá +zkušenost generací sládků. + +K výrobě jsou použity jen ty nejmodernější technologie, zároveň se však úzkostlivě dbá na dodržování tradičních výrobních postupů, aby byla zachována stále stejná, vysoká kvalita. Velký důraz je kladen na zrání („ležení“) piva, které u prémiového originálního ležáku dosahuje minimálně 90 dní, u speciálního piva Bud Super Strong až 200 dní. + +Samičí hlávky vysoce kvalitního žateckého chmele (Humulus lupulus) dělají z našeho piva opravdovou vzácnost. Dodávají mu totiž jeho nenapodobitelný, vysoce ceněný, jemný chmelový charakter. + +Zrnka unikátní odrůdy moravského ječmene (Hordeum vulgaris), která každoročně přednostně vybíráme z prvotřídních sklizní, dodávají našemu pivu jeho nenapodobitelnou zlatavou barvu. + + + +Seznam produktů + + + +Budweiser Budvar prémiový ležák + + +Budweiser Budvar prémiový ležák + + +Budějovický Budvar světlé výčepní pivo + + +Bud Super Strong + + +Budweiser Budvar Free nealkoholické pivo + + +Budweiser Budvar Free nealkoholické pivo + + +Budweiser Budvar tmavý ležák + +© 2003 Všechna práva vyhrazena, Budějovický Budvar n.p. Maintenance by Český Web, a.s. diff --git a/src/test/data/utf8text/english_utf8.txt b/src/test/data/utf8text/english_utf8.txt new file mode 100644 index 00000000000..1ff2b690b9f --- /dev/null +++ b/src/test/data/utf8text/english_utf8.txt @@ -0,0 +1,70 @@ +MSN vs. Google and Yahoo, Round 3 +Published: March 15, 2005, 7:41 PM PST +By Stefanie Olsen +Staff Writer, CNET News.com + +TrackBack +Print +E-mail +TalkBack + +Microsoft CEO Steve Ballmer is expected to show off a new paid-search service +on Wednesday that will eventually go toe-to-toe with rival Google and supplant +partner Yahoo's advertising. + +As previously reported, Microsoft's Internet group is developing a +pay-per-click ad-bidding system that pairs search results with sponsored text +messages from advertisers. Yahoo's Overture Services currently supplies MSN +with sponsored search links, which complement MSN-sold "featured sites." + +But the new MSN service, called AdCenter and set to roll out in Singapore and +France in the coming months, will bump Overture ads in the long run and let MSN +own a major source of its advertising revenue. (Microsoft splits fees collected +from marketers with Overture.) + +News.context + +What's new: +MSN is set to show off its version of a system for selling text ads linked to +search queries and results, a direct challenge to market leaders Google and +Yahoo. + +Bottom line: + +Microsoft's Internet group is hungry for a bigger piece of the +multibillion-dollar ad business related to search, and the new service will +eventually allow it to jettison a deal with Yahoo's Overture Services. That +agreement provides ad revenue but requires MSN to split the money with Yahoo. + +More stories on this topic +Microsoft does not have a specific date for a U.S. launch, but it envisions +operating the ad network globally, said Adam Sohn, an MSN spokesman. + +"Call this the third leg of the search stool," said Sohn. "First, we introduced +algorithmic search, then desktop (search), which is still in beta, and now the +advertising platform." + +With the product, Microsoft will move into the mother lode of a +multibillion-dollar ad business dominated by Google and Yahoo. Search-engine +marketing is expected to be worth as much as $5 billion this year, and nearly +$9 billion annually within four years, according to Jupiter Research. +Microsoft's piece of the pie is smaller than the shares enjoyed by market +leaders Yahoo and Google, and the software giant is hungry for more. + +Google fields 35.1 percent of the searches online, followed by Yahoo at 31.8 +percent and MSN at 16 percent, according to ComScore QSearch. If the number of +searches translates to the percentage of the ad market, MSN generates roughly +$1.6 billion annually from search, minus the portion shared with Overture. + +MSN's product is far from fully baked, according to Sohn, but it could +eventually crowd rivals, search engine watchers say. Given that there is a +finite number of searches conducted on the Internet, and hence a limited number +of opportunities to display search-related ads, MSN will grab ad dollars away +from Yahoo and Google, they say. According to data from ComScore QSearch, there +were roughly 4.9 billion search queries in the United States during the month +of January. + +"The big pie of searches out there isn't getting any bigger" because of MSN's +ad platform, said industry expert Danny Sullivan. "All that's + +Continued ... diff --git a/src/test/data/utf8text/french_utf8.txt b/src/test/data/utf8text/french_utf8.txt new file mode 100644 index 00000000000..f3de07a9bce --- /dev/null +++ b/src/test/data/utf8text/french_utf8.txt @@ -0,0 +1,30 @@ +réputé +comédie +Hitch - expert en séduction + +Alex Hitchens est un entremetteur (marieur) professionnel qui utilise des moyens peu orthodoxes pour coacher ses clients et jouer avec le destin. Il réussit ainsi avec succès à unir des hommes ordinaires avec des femmes extraordinaires. Malgré tout cela, Hitch ne croit pas en l'amour. +Pourtant sa rencontre avec Sara, une jeune journaliste sexy qui partage les mêmes points de vue cyniques sur les relations amoureuses va les amener sur un territoire inconnu... + + Vidéos : bande annonce + +Interviews + +Amber Valletta +Kevin James +Eva Mendes +Andy Tennant + +À propos du film +Notes de production : + +WILL SMITH COMME JAMAIS… + +Will Smith est l’une des plus célèbres stars de Hollywood. Héros d’action réputé pour son charme et son humour, il n’avait cependant encore jamais joué dans une comédie romantique. James Lassiter, producteur de HITCH et associé de Will Smith dans leur société de production, Overbrook Entertainment, explique : « Cela faisait des années que nous cherchions un bon scénario de comédie romantique pour Will. Ce n’est pas aussi facile que ça en a l’air. Ce genre de scénario est finalement assez rare, et les bons le sont encore plus ! » +James Lassiter et Teddy Zee ont été séduits par le scénario de Kevin Bisch, qui semblait fait pour Smith. Un « conseiller en séduction », un homme cool et sûr de lui aide, contre un peu d’argent, des hommes timides et qui ne brillent pas en société à gagner le cœur de n’importe quelle femme. James Lassiter explique : « C’est la légende urbaine parfaite : l’histoire d’un homme si charismatique qu’il peut enseigner aux autres comment s’y prendre pour séduire. + +« Selon la philosophie de Hitch, poursuit-il, trois jours suffisent pour mettre en lumière le « vrai vous » et conquérir la femme de vos rêves. » Teddy Zee, également producteur chez Overbrook, a lui aussi vu tout de suite le potentiel de l’histoire. « Il y a à la fois quelque chose de très urbain et de très raffiné dans ce scénario ; c’est contemporain, chic et très humain. Il faut aussi noter que l’histoire est racontée du point de vue masculin, ce qui est extrêmement rare dans les comédies romantiques. » + +Le scénariste Kevin Bisch a puisé son inspiration dans ses expériences personnelles à l’université. Après une suite de rendez-vous plus ou moins réussis avec différentes jeunes filles, il a réalisé qu’il finissait généralement assis au bord du lit avec elles, à feuilleter longuement des albums photos… « J’ai eu une révélation, confie-t-il en souriant. Comment avais-je pu être aussi bête ? Elles ne faisaient que tuer le temps en attendant que je les embrasse. Après ça, je me suis intéressé de près à la mécanique et au timing des débuts d’une relation avec une femme, et aux petits détails infimes… » + + + diff --git a/src/test/data/utf8text/german_utf8.txt b/src/test/data/utf8text/german_utf8.txt new file mode 100644 index 00000000000..4f6fca5d02b --- /dev/null +++ b/src/test/data/utf8text/german_utf8.txt @@ -0,0 +1,20 @@ +Damit +können +führt + +Damit Sie sich aus allgemein zugänglichen Quellen ungehindert "unterrichten" können und tagesaktuell informiert sind, bieten wir Ihnen in Zusammenarbeit mit nationalen und internationalen Redaktionen einen Schlagzeilenservice der Sie direkt zum jeweiligen Artikel des Herausgeber führt. + +Grundgesetz der Bundesrepublik Deutschland +Artikel 5 +Meinungs-, Informations-, Pressefreiheit; Kunst und Wissenschaft +(1) Jeder hat das Recht, seine Meinung in Wort, Schrift und Bild frei zu äußern und zu verbreiten und sich aus allgemein zugänglichen Quellen ungehindert zu unterrichten. Die Pressefreiheit und die Freiheit der Berichterstattung durch Rundfunk und Film werden gewährleistet. Eine Zensur findet nicht statt. + +(2) Diese Rechte finden ihre Schranken in den Vorschriften der allgemeinen Gesetze, den gesetzlichen Bestimmungen zum Schutze der Jugend und in dem Recht der persönlichen Ehre. + +(3) Kunst und Wissenschaft, Forschung und Lehre sind frei. Die Freiheit der Lehre entbindet nicht von der Treue zur Verfassung. + + +Anmerkung: Jeder veröffentlichte Artikel wird von Journalisten mehr oder weniger gut recherchiert. Kein Journalist ist frei von Fehlern und frei von Subjektivität seine eigene Sicht zum jeweiligen Thema darzustellen. Aus diesem Grund sollten Sie zur Meinungsbildung immer mehrere Medien nutzen. Wir hoffen Ihnen mit diesem Service dabei helfen zu können. + +Auf die Auswahl der Schlagzeilen hat die German News Redaktion keinen Einfluss. Alle publizierten Schlagzeilen und Einführungstexte (teaser) geben nicht unbedingt die Meinung der German News Redaktion wieder. Eine weitere Verwendung der Schlagzeilen aus German News ist nicht gestattet und kann nur durch Einwilligung des jeweiligen Herausgeber erfolgen. Die Zuordnung zur Themenauswahl erfolgt frei. + diff --git a/src/test/data/utf8text/greek_utf8.txt b/src/test/data/utf8text/greek_utf8.txt new file mode 100644 index 00000000000..3334b4b5dc4 --- /dev/null +++ b/src/test/data/utf8text/greek_utf8.txt @@ -0,0 +1,14 @@ +στείλτε + + +Ελληνικό Yahoo!: Εργαλεία Επικοινωνίας + Yahoo! Mail - Διαβάστε και στείλτε emails από οπουδήποτε στον κόσμο με το Yahoo! Mail. Μπορείτε να έχετε πρόσβαση ακόμα και στον POP3 mail λογαριασμό σας, μέσω του Web. + Yahoo! Ημερολόγιο - Κάνει εύκολη την οργάνωση της ημέρας σας με τις υπενθυμίσεις, τις e-mail προσκλήσεις, και τη λίστα εκκρεμοτήτων. + Yahoo! Ατζέντα - Οργανώστε τις διευθύνσεις των φίλων σας. Μπορείτε να μεταφέρετε όλες τις πληροφορίες για τους φίλους σας από το Microsoft Outlook, από το Netscape Address Book ή από το Palmtop σας. + Yahoo! Messenger - Στείλτε άμεσα μηνύματα στους φίλους σας ή στους συνεργάτες σας. Σας στέλνει υπενθυμίσεις σε συνεργασία με το Yahoo! Ημερολόγιο, ώστε να μη χάνετε κανένα σημαντικό ραντεβού. + Yahoo! Σημειώσεις - Αποθηκεύστε όλες τις σημειώσεις σας στο Web. Τώρα μπορείτε να έχετε πρόσβαση στις σημειώσεις σας από οπουδήποτε, οποιαδήποτε στιγμή. + + + +Τώρα στο Ελληνικό Yahoo! όλα αυτά τα εργαλεία είναι εντελώς δωρεάν. Και μπορείτε να τα έχετε για πάντα! + diff --git a/src/test/data/utf8text/hebrew_utf8.txt b/src/test/data/utf8text/hebrew_utf8.txt new file mode 100644 index 00000000000..ee27e74bf3d --- /dev/null +++ b/src/test/data/utf8text/hebrew_utf8.txt @@ -0,0 +1,408 @@ +בארצות +Ale + + + בירה נפוצה מאד בעיקר בארצות אנגלוסקסיות, צבעה כהה ולייצורה משתמשים בשמרי תסיסה עילית. בירה קילקני היא בירה מסוג זה. + + + +CO2 + + + גז פחמן דו חמצני הנוצר על ידי השמרים בתהליך התסיסה. זהו הגז אותו אנו חשים בעת שתיית הבירה. + + + +Lager + + + + הבירה הנפוצה ביותר בעולם, צבעה בהיר, קלה לשתיה, בעלת ארומה קלה ונעימה, ידועה גם בשם Pilsner על-שם הבירה הצ'כית המפורסמת ולייצורה משתמשים בשמרי תסיסה תחתית. קרלסברג, טובורג רד וטובורג גרין הן בירה מסוג זה. + + + +Stout + + + צבעה כהה ולייצורה משתמשים בשמרי תסיסה עילית. בירה גינס היא בירה מסוג זה. + + Widget + + + התקן מיוחד שהינו למעשה מיכלון קטן המכיל גז חנקן ומוחדר בעת המילוי לבקבוק או לפחית של גינס Draught. כשפותחים את הבקבוק או הפחית, המיכלון מתבקע ומשחרר את החנקן היוצר את הקצף העשיר והסמיך המיוחד של גינס. + + + +אלכוהול + + + אתנול, או כוהל אתילי. נוצר בזמן התסיסה של השמרים. + + + + +באלטיקה + + + באלטיקה הינה המבשלה הגדולה ביותר לייצור בירה ברוסיה ואחת מהמובילות באירופה. + +למבשלות בירה באלטיקה סוגים רבים ומגוונים של בירה כאשר העיקרון המנחה את המבשלה הוא בישול בירה המבוססת על מרכיבים איכותיים ביותר. + +מבשלות בירה ישראל משווקת בקבוקי באלטיקה 0.5 ליטר מספר 3, 4, 6 ו-9 ופחיות 0.5 ליטר מספר 5 ו-7. + + + +בירה + + + הבירה הינה משקה מוגז בדרך-כלל אלכוהולי עשוי מדגנים שונים. במשך אלפי שנות קיומה הבירה פשטה ולבשה טעמים, ריחות וצבעים בהתאם למסורות, יכולות טכנולוגיות והתקדמות מדעית. הבירה נחשבת למשקה פופולרי בכל היבשות ובקרב כל העמים. + + + +בירה ללא אלכוהול +בירה שתססה בתהליך רגיל אך האלכוהול הורחק ממנה בתהליכי זיקוק או בעזרת ממברנות דוגמת Reverse Osmosis. + + בירה מאלט + + + בירה לא כוהלית המכילה כמות של סוכרים ועל כן מתוקה. הבירה יכולה לתסוס זמן קצר על מנת לסלק טעמים וריחות אופייניים לתירוש. הבירה כהה לרוב בגין הוספת כמות נכבדת של לתת קלוי כהה מאד. + + + + +בירה מתסיסה פראית + + +בירה שאינה מוססת על ידי זן שמרים מוגדר אלא על ידי שמרים הנמצאים באווירת המבשלה. זוהי תסיסה ספונטנית המקובלת בעיקר בבלגיה. + + + + +גינס + + +בירה מסוג Stout, איכותית ביותר. בעלת צבע כהה מאד שמקורו בלתת קלוי היטב. בירה מרירה מאד ובעלת קצף מיוחד ועשיר הנובע מהתערובת הייחודית של חנקן ו-CO2. גינס ייחודית בבקבוק מהפכני. באמצעות התקן מיוחד בתוך הבקבוק משתחררים הגזים עם הפתיחה וכך נוצר קצף עשיר וסמיך וטעם הזהים לבירה הנמזגת מהחבית. + + + +דיאט מאלטי + בירה שחורה דיאט מאלטי בה הוחלף חלק גדול מהסוכרים שבה בממתיקים מלאכותיים כך שכמות הקלוריות בה הינה כמחצית מכמות הקלוריות של בירה מאלטי רגילה ובכל מקרה לא יותר מ 20 קלוריות ל 100 מ"ל. + + + +הלתתה + + + תהליך יצור לתת במהלכו השעורה עוברת הנבטה בתהליך מבוקר של רטיבות וטמפרטורה. תוך כדי נביטת הגרעין מיוצרים בו, מסונתזים, אנזימים המסייעים לפרק את מאגר האנרגיה שבו, העמילנים הנמצאים באנדוספרם. + + +בשלב ראשון מסונתזים האנזימים המאפשרים גישה לתוך תאי העמילן והם מפרקים את דופן התאים המכילים עמילן. בשלב שני מסונתזים אנזימים המסייעים לפרק את העמילנים עצמם, אנזימים עמילוליטיים. + +בשלב זה מופסקת הנביטה בתהליך קלייה. תהליך זה מייבש את הגרעין ו"מקפיא" למעשה את מצבם של האנזימים. למרות החום הרב אליו נחשף הגרעין בתהליך הייבוש, חיוניות האנזימים נשמרת אך הם אינם פעילים. +אנזימים אלה משמשים אותנו בתהליך בתחילת תהליך מיצוי הסוכרים בבית הבישול במבשלת הבירה. + +בתחילת תהליך זה אנו גורסים הלתת ומרטיבים את הלתת במים חמימים. תהליכים אלו מעוררים את האנזימים לפעולה והם מתחילים בתהליכי פירוק העמילנים לסוכרים. סוכרים אלו ישמשו את שמרי הבירה במהלך תסיסתה. + +משטרים שונים של הנבטה וקליה יוצרים סוגים שונים של לתת הנבדלים בצבעם ובטעמם ומאפשרים ליצור מגוון של בירות. + + + +ווינשטפן + + +מבשלה בדרום מזרח גרמניה הנחשבת למבשלה העתיקה בעולם אשר החלה לייצר בירה בשנת 1040. + +הבירה עשויה מתערובת של לתת שעורה ולתת חיטה. הבירה קלה חמצמצה וארומטית. + + + +בירת חיטה הינה בירה שבתהליך הבישול המיוחד שלה מוסיפים לה חיטה ושמרים באיכות הטובה ביותר ומבדלים את הבירה בתכונות הסנסוריות שלה שאותן מזהים דרך החושים: + +טעם מיוחד עם ארומות וניחוחות פירותיים +ראש קצף אחיד ומיוחד +בירה לבנה ומעוננת בעלת עכירות טבעית +אחוז אלכוהול גבוה יחסית, 5.4% + + + +חבית + + + למה בירה מהחבית? + +בגלל הטעם: החשיפה הקצרה לחום בתהליך הפסטור משאירה את טעם הבירה קרוב מאד לטעמה המקורי. בנוסף, כתוצאה מהמזיגה נוזל הבירה משחרר CO2 המשביח את טעם הבירה. הטעם פחות מריר, יותר קליל ופחות מוגז. בירה מהחבית תמיד מוגשת בטמפרטורה הנכונה + +בגלל הטריות: מחזור החביות בשוק קצר ביותר ומרבית החביות נמזגות בתוך שבועיים עד חודש מיום המילוי כך שהבירה טרייה מאד. + + + +חומרי גלם + +חומרי הגלם המשמשים לייצור בירה כוללים: מים, לתת, לתת קלוי, חומרים עמילניים, סוכר (לעתים), כשות, שמרים, חום, CO2. + + + +חומרים עמילניים וסוכר + +עמילן ממקורות צמחיים אחרים משמש כחומר גלם נוסף לייצור בירה יחד עם הלתת. במערב אירופה משתמשים בתירס, במזרח אירופה נעשה שימוש בתירס ובניגריה ובמצריים סורגום הוא העמילן שבשימוש. + +בסוגים מיוחדים של בירה משתמשים בחיטה (דוגמת בירה ווינשטפן). החיטה תורמת סמיכות וקצף בעיקר בבירות מסוג Ale. ניתן להוסיף סוכר ממקורות שונים אך סוכר זה אינו תורם טעם וצבע. תירס ואורז משמשים בייצור בירות איכותיות, קלות וחזקות בעיקר מסוג Lager. + +חוק טוהר הבירה הגרמני משנת 1564 לא מרשה שימוש בחומרים אחרים זולת לתת שעורה. אולם חוק זה אינו מחייב במדינות אחרות. + + + +חיי מדף + + + חיי מדף של בירה מתחלק לשלוש האריזות הקיימות בשוק. + +חבית: שישה חודשים מיום המילוי + +בקבוק: שנים עשר חודשים מיום המילוי + +פחית: שנים עשר חודשים מיום המילוי + + + +טובורג רד + + +בירה כהה מסוג בירה Lager. הבירה מכילה 5.2% אלכוהול, צבעה עמוק וטעמה עשיר. + + + +טובורג גרין + +בירה בהירה, עדינה וטעימה מסוג בירה Lager. הבירה מכילה 4.6% אלכוהול. + + + +טעימות בירה + את הבירות טועמים בטמפרטורה של 15 מע"צ ובטמפרטורה המומלצת שלהן כאשר כוס הטעימה שקופה ונקייה ובדומה לכוס היין, גם מעט מעוגלת בכדי שהארומה לא תברח. + + + +טעימת בירה מזכירה במקצת טעימת יין: + +התרשמות ויזואלית: מתבוננים בבירה ובוחנים את צבע, השקיפות, המראה והקצף. + +הרחה: מריחים ומתרשמים מהארומות השונות. + +לגימה: טועמים ומגלגלים את הבירה בחלל הפה ומניחים ללשון לטעום את קשת הטעמים תוך כדי בליעתה. + + + +כוהל בנפח + + + אחוז הכוהל בבירה מבוטא ביחידות נפח (מ"ל לליטר) + + + +כשות (Hops) + + + כשות הינו צמח מטפס הגדל באירופה וזקוק לקור. בן דודו גדל בארץ כמטפס טפיל. באירופה בארה"ב ובמדינות נוספות מגדלים אותו במיוחד כחומר חשוב ליצור בירה. לכשות תפרחת קטנה בצבע ירוק ובצורת חרוט. בתחתית עלי הכותרת הירוקים מצויות בלוטות קטנות המייצרות חומצת אלפא היא החומר הנותן את הטעם המר לבירה, וגם שמנים אתריים ארומטיים התורמים גם ארומה לבירה. + + + +קיימים זנים שונים של כשות ולכל אחד הריחות והטעמים שלו. הברומאסטר בוחר את הכשות שמתאימה לבירה שברצונו לייצר. + +לבד מארומה לכשות תכונה המעכבת גידול של חיידקים. + +בעבר הוסיפו את שיחי הכשות למיכל ההרתחה אולם כיום עם התפתחות התעשייה מוסיפים כופתיות העשויות מהתפרחת או מיצוי מרוכז שלהן. + + + +לתת (Malt) + + + גרעיני שעורה שעברו תהליך הלתתה בבתי הלתתה מיוחדים. העמילן שבלתת קל לפירוק לסוכר הדרוש לשמרים לתסיסה. שלבי ייצור הלתת: השריית השעורה במים, נביטה, קלייה וייבוש, ניפוי ואחסון. + + + +לתת קלוי + + + לתת שתהליך הקלייה הסופי שלו מתבצע בטמפרטורה גבוהה במיוחד הגורמת להיווצרות צבע כהה וטעם קלייה אופייני. + + + +מאלטי + + + בירה שחורה ללא אלכוהול. מיוצרת מלתת קלוי המקנה לה את צבעה השחור ואת טעמה המיוחד. אינה מכילה אלכוהול בזכות תהליך ייצור מיוחד השונה מייצור בירה רגילה. למאלטי תכונות בריאותיות רבות ומגוונות: מאלטי הוא משקה איזוטוני הנספג במהירות במערכת העיכול ונוזלי הגוף, מאלטי מעשיר את הגוף במגוון סוכרים המתפרקים לאורך זמן וכן מכילה ויטמינים ומינרלים המסייעים לתפקוד מערכות הגוף. + + + +מילוי אספטי + + + + תהליך מילוי ייחודי של משקה לתוך האריזה בצורה המונעת זיהום המשקה האריזה או הפקק, לקבלת אריזה סטרילית. + + + +מילוי קר + + + מילוי של משקאות לתוך אריזתם בטמפרטורה נמוכה. משקאות מוגזים חייבים למלא בטמפרטורה נמוכה כדי למנוע "בריחת" הגז במהלך המילוי. + + + +מים + + + מים הם לכאורה חומר גלם פשוט ביותר אך לא כך הדבר. יש חשיבות להרכב המים ולמומסים המצויים בהם. + +מים רכים, המכילים כמות קטנה של סידן מתאימים ליצור בירות מסוג Lager ו-Pilsner (בירות של תסיסה עילית). העיר פילזן שבצ'כיה ידועה בכל העולם במים הטובים שלה המתאימים מאד ליצור בירות מסוג זה (ומכאן גם השם Pilsner). + +מים קשים, המכילים הרבה סידן מתאימים ליצור הבירות מסוג Ale ו-Stout (בירות של תסיסה עילית הנפוצות באיים הבריטיים). + + + +ערך בריאותי + לבירה ערך בריאותי בשני תחומים חשובים: + +1. זירוז פעילות מערכת השתן והכליות בגוף האדם. + +2. מניעת מחלות בכל הדם והלב. + + + +ערך קלורי + + + + בירה אינה משמינה יותר ממשקה קל רגיל וברוב המקרים אף מכילה פחות קלוריות. + + + +השוואת ערך קלורי של משקאות ל-100 מ"ל משקה: + +בירה קרלסברג: 43 + +בירה טובורג גרין: 39 + +בירה מאלטי: 35 + +בירה מאלטי דיאט: 18 + +חלב 1% שומן: 41 + +חלב 3% שומן: 57 + +משקאות קלים ומיצים: 40-50 + +נקטרים שונים: 45-55 + + + + + +ערך תזונתי + + + + בירה מיוצרת מחומרים טבעיים בלבד! אין בה חומרים מלאכותיים וחומרים משמרים. בירה מכילה מינרלים וויטמינים רבים כגון אשלגן, סידן מגנזיום וזרחן. כולם חומרים חיוניים לגוף האדם. + + + +הרכב תזונתי ל-100 מ"ל בירה + +קלוריות: 43 + +שומנים: 0 + +חלבונים (גרם): 0.1 + +פחמימות (גרם): 4 + +אלכוהול (גרם): 3.9 + + + +פסטור + + פסטור בירה בבקבוקים ובפחיות נועד לשמר את הבירה לתקופת חיי המדף שלה על-ידי השמדת כל המיקרואורגניזמים הנמצאים באריזה. תהליך הפסטור הומצא על-ידי לואי פסטר ועיקרו חימום הבירה לטמפרטורה של 60-70 מעלות צלזיוס למשך מספר דקות. מכיוון שחום פוגע בטעם הבירה, על החימום להיות קצר ככל האפשר. + +פסטור בירה בבקבוקים/פחיות מתבצע במנהרת פסטור מיוחדת על-ידי התזת מים חמים על האריזות לאחר המילוי והפיקוק. המים מחממים את הבירה עד לפסטורה ולאחר מכן מקררים אותה על-ידי התזת מים קרים. + + + +פרוקטוז + + + +סוכר פירות + + + +צלילות + + + שקיפות הבירה. בגמר תהליך התסיסה הבירה עכורה בשל השמרים שבה. השמרים מופרדים לקבלת בירה צלולה. + + + +קילקני + + + +בירה אירית מסוג Ale, עדינה מאד וקלה לשתיה. מבית גינס העולמית. צבעה אדום עמוק והיא מיוצרת מ-100% מאלט אירי משובח. טמפרטורת ההגשה שלה נמוכה (4-6 מעלות). מאפייני הבירה הם מזיגתה הייחודית ושילוב הגזים, חנקן ו-CO2 מעניק לבירה ראש קצף עדין הנשמר לאורך זמן. + + + +קצף +הקצף הינו תכונה חשובה של הבירה ותורם למראה ולהנאה ממנה. הקצף נוצר על ידי החלבונים שבבירה וגז ה-CO2. + + + +קרלסברג +בירה בהירה ומשובחת ביותר מסוג בירה Lager. בעלת טעם ואיכות מיוחדים שהקנו לה שם עולמי בשוק הבירות. מיוצרת עפ"י המסורת הדנית הידועה ומכילה 5.0% אלכוהול. + + + +קרמל + + + סוכר שרוף המקנה למשקאות צבע כהה וטעם ייחודי (קרמלי) + + + +שמרי בירה + + + +השמרים הם אותם מיקרואורגניזמים המסוגלים להתסיס סוכר לגז ולאלכוהול. + +השמרים מתסיסים את הסוכר לצורך הפקת אנרגיה לגדילתם והתרבותם. אולם תוך כדי תהליך התסיסה הם גם מייצרים ומפרישים מאות רבות של חומרים הנותנים ביחד את הטעם האופייני לבירה. + +ישנם זנים שונים ורבים של שמרים. לכל מבשלה השמרים המיוחדים שלה. כל השמרים משתייכים למשפחת שמרים הנקראת Saccharomyces על שום יכולתם להתסיס סוכר. + + + +במבשלות קרלסברג שבקופנהגן, דנמרק, פותחה לראשונה בעולם, לפני כ 150 שנה, שיטת "התרבית הנקיה" (Pure Culture) שהיא אבן יסוד למיקרוביולוגיה המודרנית. השמר הראשון שבודד בשיטה זו נקרא על כן Saccharomyces Carlsbergnesis והוא השמר המשמש עד היום ליצור בירה קרלסברג בעולם כולו וגם במבשלות בירה ישראל בע"מ שבאשקלון. + + + +שעורה + +סוג של דגן ממנו עושים לתת המשמש לייצור בירה. + + + +תסיסה עילית + +בסוג תסיסה זה השמרים עולים לראש מיכל התסיסה בגמר התהליך. טמפרטורת התסיסה גבוהה בין 15-22 מעלות, משך התסיסה קצר בין 3-8 ימים וארומת הבירה היא של פירות. הבירות ממשפחה זו מקורם באיים הבריטים, אנגליה, אירלנד וסקוטלנד וכן בירות מיוחדות מבלגיה, הולנד וגרמניה. סוגי בירות אלו נקראים Ale ו-Stout. גינס וקילקני נמנות על הבירות המיוצרות מסוג תסיסה זה. + + + +תסיסה תחתית + + + +בסוג תסיסה זה השמרים שוקעים לתחתית מיכל התסיסה בגמר התהליך. טמפרטורת התסיסה נמוכה בין 5-15 מעלות, משך התסיסה ארוך בין 2-12 שבועות וארומת הבירה היא של פרחים. בירות אלה נפוצות בעולם ומקורן בצ'כיה, גרמניה, דנמרק והולנד. הבירות הנפוצות ממשפחה זו הן בירה ה-Lager וה-Pilsner. בירות בהירות, קלות לשתיה ובעלות ארומה קלה ונעימה. קרלסברג, טובורג רד וטובורג גרין נמנות על הבירות המיוצרות מסוג תסיסה זה. + + diff --git a/src/test/data/utf8text/japanese_utf8.txt b/src/test/data/utf8text/japanese_utf8.txt new file mode 100644 index 00000000000..1123fdcea4b --- /dev/null +++ b/src/test/data/utf8text/japanese_utf8.txt @@ -0,0 +1,28 @@ +見学 +1 ページ / 2 ページ +次へ + + 7月22・23日を利用して,Plzen にいってきました.メインはこのビール博物館&工場見学.ついでに味見も.とても興味深い日を過ごすことが出来ました. + + 多くの方がご存じと思いますが,このPlzensky Prazdroj (プルゼーニュスキー・プラズドロイ)は,ドイツ・ミュンヘンから1842年に導入された低温下における「下面発酵」という醸造技術が,この土地の麦・ホップ・水・風土とうまく調和し,また人々の大きな努力によってまさに花開いたその元祖のビールです.今日「ピルスナービール」と呼ばれるビールが,世界の大きな勢力となっていますが,その「ピルスナー」とはこのPlzen(プルゼーニュ)という街のドイツ名,Pilsen(ピルゼン)の,という意味です. + + その重厚な,しかし爽やかで飲み越しのいいビールは,飲んだ人すべてが世界最高のビールであるというでしょう.麦と水とホップだけから繰り出されるこの味は本当に忘れられないものです. + + ちなみに,このビール,特にバリング度(最初にモルトからとる麦汁を水でわったときの麦汁濃度)が12%のもの(Prazdroj ではその下は10%,一般に12%を越えるものは少ない)は,のどが渇いたから一気に飲む,というような飲み方はもはや出来ず,むしろパンの代わりに少しずつごくごく飲む,というのがちょうどいいようです.たくさん飲むとものすごくのどが渇くので,のどを潤すにはむしろ良くないかもしれません.しかし歴史的に見ると,キリスト教では「ビールは液体のパン」として重要な役割をしています.ワインはキリストの血,パンはキリストの肉,ビールは液体のパン,です.実際,修道院などでは断食期間に水の代わりのビールで栄養を補給していたという話もあり,時代によっては醸造の許可が教会関係だけに与えられていたり,また教会が免許の交付権を持っていたり,というもありました. + + 工場に行ってみると,一面モルトを煮出している匂いがして,あ~あ,麦だぁ,という感じがします.世界中から年間5万人もの人が訪れるというこのビール博物館共々,我々ビールのみにも,またそうでない人にとっても大変興味深いものだと思います. + +  + +このページの写真も,クリックすると大きな原版が見られるようになっています.ものすごく大きいですが,良かったらそちらもご覧下さい. + + + + +これが Plzen 旧市街にある「ビール醸造博物館」です.昔実際にビールの醸造所であり,パブとして使われたこともある建物で,ビールの醸造の道具から昔の衣装,ビアホールの内装,また地下にはその昔氷を入れて冷蔵庫にしていた貯蔵倉もあり,とにかく見るところはたくさんあります. これは Plzensky Prazdroj (Pilsner Urquell) の会社のバックアップで運営されています.中にはいると解説書を貸してくれます.日本語の解説書もあります. + +この入り口を見ると,いかにも醸造所かパブですね.中には Urquell の日本での広告もあります.はっきりはわかりませんが,印刷の感じからすると1960年代ではないかと思います.日本での商標登録証ということで Urquell の商標登録の証書があるのですが,ちょっと意味の分からないところがあって,若干謎です. 残念! Plzensky Prazdroj の工場の正門(Historical gate)です.ちょうど改装工事中で肝腎の所が見られませんでした.旧市街の中心から5分ぐらいのところです. + +この Gate が壁画にしてありました. これがあの工場です.大きな写真をご覧下されば,左の方に Prazdroj と書いてあることがわかります. + +これは前の写真の右側に当たるところです.今は使っているのかどうかわかりませんが,Gate を通ってこの屋根の下まで鉄道の線路が引かれており,昔はそれを使って各地へ輸送していたことがわかります. 12時半集合で,ビデオ上映の後工場内の見学ツアーがあります.最初に大きなボードで Prazdroj の製法について説明があり,その後工場内の見学,ついで地下の発酵貯蔵用の倉を見学です.とても寒かった.でもその温度の下であのようなリッチなビールができあがるのです.まさかいいといわれるとは思わなかったので,全然写真を撮りませんでしたが,他の人が聞いたらOKが出たのでついでにとって見ました.この中でちょうどビールが発酵中です.. diff --git a/src/test/data/utf8text/korean_utf8.txt b/src/test/data/utf8text/korean_utf8.txt new file mode 100644 index 00000000000..ef5433317c1 --- /dev/null +++ b/src/test/data/utf8text/korean_utf8.txt @@ -0,0 +1,51 @@ +10 일부터 7일간 독일 +금 +융 +포 +커스 + + +세계를 정복할 한국기업 + + + +세계일류를 꿈꾸는 삼성전자 + +삼성전자는 1988 년 하드디스크드라이브(HDD) 사업을 시작한 이래 지난해 처음으로.. + + '세빗2005' 한국관 중소업체 눈부신 성과- 머니투데이 03/16 16:07 + '세빗 2005' 한국공동관에 참가한 중소업체들이 선전을 거뒀다. 지난 + 10 일부터 7일간 독일 + + + 하노버 '세빗 2005' 에서 한국관에 참가한 중소 IT 벤처업체들은 잠정 집계 결과, 수출상담액은 12 억 5000 만달러, 계약금액은 2 억5000 만달러를 넘은 것으로 ... + + [세빗 2005] 거원시스템, 유럽 MP3 공략 본격화- 아이뉴스 03/16 13:20 + <아이뉴스24> 거원시스템이 유럽 MP3 기기 시장 공략을 본격화한다. 박남규 거원시스템 사장은 15일(현지시간) 독일 하노버에서 열리고 있는 세빗 2005 전시회에서 "이번처럼 세빗에 대형 부스를 마련하기는 처음"이라며 "유럽에 지사를 설립, ... + + LS그룹 "세계 일류기업 발돋움"- 디지탈타임즈 03/15 11:07 + CI선포식 가져… 국내외 브랜드 홍보 적극 나서 LS그룹(회장 구자홍ㆍ구 LG전선그룹)은 14일 그랜드인터콘티넨탈호텔에서 가진 CI(통합기업이미지)선포식을 통해 LS브랜드를 대내외에 공포하고, 산업용 전기ㆍ전자ㆍ소재분야의 세계일류그룹으로 도... + + [세빗2005]레인콤ㆍ삼성전자, MP3P시장 넘버3 경쟁- 디지탈타임즈 03/15 03:57 + 대형 단독부스 설치 공격적 마케팅 올 판매목표 상향… 수성ㆍ탈환 총력전 레인콤과 삼성전자가 MP3플레이어 세계시장 3위자리를 놓고 격돌한다.애플과 크리에이티브가 1, 2위를 차지하고 있는 가운데 두 회사는 올해 판매대수 목표를 대폭 상향조... + + 세빗에서 확인한 양극화- 이데일리 03/14 16:56 + 세계 최대 규모의 정보통신 박람회인 `세빗(CeBIT)2005` 가 지난주부터 독일 하노버에서 열리고 있습니다. 지난 1월 미국 라스베가스에서 열린 CES에 이어 우리나라 기업들이 세계인의 주목을 받아 IT강국의 위상을 재차 확인하는 자리였습니다. 하... + + + + + LG전자 "2010년 세계톱3 기필코 달성"- 머니투데이 03/14 15:41 + "올해 매출을 30조원으로 늘려 글로벌 톱5 기업에 들고 이를 바탕으로 2010년에는 글로벌 톱3가 된다" LG전자의 중장기 비젼이다.막연하게 1등 기업이 되겠다는 선언에 그치는 게 아니라 구체적인 시기와 목표를 제시하고 있다. 도전 역시 만만치 ... + + IT산업 미래는 한국이다 <美일간지>- 연합뉴스 03/14 09:38 + =실리콘 밸리 "한국은 미래로 가는 타임머신" 워싱턴 박노황 특파원 = 미국의 일간 샌프란시스코 크로니클은 13일 '미래는 한국'이라는 제하의 기사를 통해 세계 제일의 광대역 인터넷망및 휴대 전화 보급률을 누리고 있는 IT 강국 한국의 현황을 ... + + 자기만족에 빠진 소니, 삼성에 패배- 동아일보 03/12 09:09 + ‘한국 삼성전자와 일본 소니(Sony)의 역전.’ 뉴욕타임스는 10일 1997년 이후 7년 만에 삼성전자와 소니의 위상이 뒤바뀌었다고 전했다.1997년은 삼성전자가 한국에 몰아닥친 외환위기에서 벗어나기 위해 사투를 벌이던 때이자 7일 소니 최고경영... + + [기획특집 - 글로벌 리더기업Ⅲ]LG필립스LCD- 헤럴드경제 03/11 11:41 + 앞선 투자ㆍ기술…LCD 최강자로 지난 2004년 7월, LG필립스LCD는 한국 기업으로는 최초로 한국과 미국 증시 동시 상장에 성공했다.이는 남들보다 한발 앞선 적기 투자와 기술개발로 세계 TFT-LCD 업계를 이끌어온 리더로서의 기업가치를 다시 한번 ... + + [기획특집 - 글로벌 리더기업Ⅰ] 일등만이 산다- 헤럴드경제 03/11 11:41 + 세계 초일류 기업으로의 도약을 위한 글로벌 경영은 이미 대기업들의 선택이 아닌 필수로 자리잡았다.국내 대기업들도 글로벌 경영에 박차를 가해 이젠 글로벌 리더 기업으로 자리매김하고 있거나 자리를 굳혀가고 있는 기업들이 상당수에 이른다.... diff --git a/src/test/data/utf8text/polish_utf8.txt b/src/test/data/utf8text/polish_utf8.txt new file mode 100644 index 00000000000..e5ee12c7de9 --- /dev/null +++ b/src/test/data/utf8text/polish_utf8.txt @@ -0,0 +1,65 @@ +spółka +Fermentacja to proces, w wyniku którego wytworzona w warzelni brzeczka staje się piwem. Do ochłodzonej brzeczki dodawane są drożdże, które zamieniają cukier w dwutlenek węgla i alkohol. Oprócz tego drożdże formują tysiące innych komponentów, które podczas fermentacji nadają piwu określony smak. + + +Proces fermentacji prowadzimy w ogromnych, cylindrycznych, nowoczesnych zbiornikach fermentacyjnych zwanych tankofermentorami. Największe z nich mogą pomieścić po 3 600 hektolitrów piwa czyli 720 000 półlitrowych butelek np. piwa Frater. + +W celu zapewnienia optymalnych temperatur dla procesu fermentacji tanki muszą być chłodzone. Po procesie fermentacji piwo zwane "piwem młodym" musi otrzymać swój pełny smak. Odbywa się to podczas następnego cyklu produkcyjnego, jakim jest leżakowanie (dojrzewanie) w temperaturach minusowych. + +Cały proces fermentacji i dojrzewania zajmuje około dwóch - trzech tygodni. + + + + +drożdży +spółka + +3 marca 2004 roku Browar Belgia i spółka Dominium, reprezentująca Opactwo o.o. Cystersów w Szczyrzycu, podpisali kontrakt na produkcję piwa. Umowa jest zwieńczeniem kilkuletnich działań obu stron, zmierzających do wykorzystania unikalnej receptury. Wprowadzenie piwa Frater, warzonego według starego przepisu oznacza kontynuację kulturowego dziedzictwa klasztoru. Tradycyjna, wielowiekowa receptura dająca podstawy unikalnego piwa, została połączona z nowoczesną technologią. + + + + + + + +Piwo warzone przez cystersów ze Szczyrzyca ma wielowiekową tradycję. Lata praktyki i wnikliwych obserwacji pozwoliły zakonnikom stworzyć niepowtarzalną recepturę, będącą idealnym połączeniem czterech składników (słodu, wody, chmielu i drożdży). Została ona przywrócona do życia w postaci Fratera, a poprzez wykorzystani + + + + + + +Jak wskazują zachowane dokumenty, browar w Szczyrzycu powstał w 1623 roku i jest jednym z najstarszych browarów w Polsce. Wedle starych kronik od początku XVII wieku mnisi w Szczyrzycu produkowali napój nazywany "cerewizją", robiony z palonego ziarna, cykorii, wody i chmielu. Cerewizja zawierała do 1 % alkoholu i była pita zamiast kawy i herbaty, chłodząc gardła spragnionych rolników i mnichów pracujących na terenach należących do opactwa. Mury w klasztorze postawiono w 1824 r., wcześniej zabudowania były drewniane. + + +Do 1948 r. cała produkcja prowadzona była ręcznie, co pozwalało rozlewać rocznie 250 tys. hektolitrów złocistego napoju. Przez ponad sto lat piwo leżakujące w beczkach chłodzono potężnymi blokami lodowymi wycinanymi zimą z pobliskiego stawu. Lód nie roztapiał się nawet latem, bo w podziemiach browaru przez cały rok temperatura nie przekraczała 2 stopni C. + +Najlepsze czasy browaru przypadają na okres między 1925 a 1945 rokiem. W 1925 roku Eugeniusz Czerny wydzierżawił browar. Warzono wówczas piwo "Złoty zdrój" słynące z wyjątkowego smaku i rozsławione sloganem "Mocne jak głos kuryera, słodkie jak głos Kiepury". Zachowało się wiele pamiątek z tego okresu jak specjalne kufle z pokrywkami i etykiety. Można je obejrzeć w przyklasztornym muzeum. Czerny kontynuował produkcję do końca II wojny światowej. W 1939 r. zakład przejęli Niemcy, pozwalając na kontynuowanie nadal produkcji pod okiem Czernego. +W 1951 roku większość majątku browaru przejęło państwo. Wówczas był to jedyny klasztorny browar między Łabą a Władywostokiem. + + +W latach powojennych browar podupadł. Piwo, sprzedawane pod najróżniejszymi wymyślnymi nazwami ("Czarny Mnich", "Pils Klasztorny", "Eliksir", "Dama Pik", "Gryf"), nie cieszyło się uznaniem smakoszy. Piwo produkowane w Szczyrzycu, można było kupić tylko w okolicznych miejscowościach: Limanowej, Myślenicach, Rabce. W 1993 r. Opactwo Ojców Cystersów odzyskało browar i kontynuowało produkcję piwa. Pomieszczenia zakładu, choć nie były zdewastowane, wymagały gruntownego remontu. Podobnie jak i urządzenia. Nie dało się na nich produkować dobrej jakości piwa, a szczególnie tego, jakie było warzone w przeszłości. Opactwo, nie chcąc firmować swoim wizerunkiem tak złej jakości produktu, nie posiadając środków na remont urządzeń i obiektu, postanowiło zaprzestać produkcji. W 1996 r. browar, po 373 (!) latach nieprzerwanej pracy, zakończył produkcję piwa, a wkrótce potem został zamknięty. + + + + + + +Piwo jest jednym z najstarszych napojów znanych ludzkości. Warzono je już w starożytnym Egipcie. Pierwsze piwa o niewielkiej zawartości alkoholu przyrządzano z wieloma dodatkami, a ich głównym przeznaczeniem było gaszenie pragnienia. +Napój ten nierozerwalnie wiąże się z tradycjami religijnymi. W starożytnym Egipcie był warzony przez kapłanów, a w średniowiecznej Europie przez mnichów zakonnych. Od XI wieku piwo było warzone przez setki mnichów z całego świata. W Polsce warzelnictwo na dużą skalę zapoczątkowali cystersi w XIII w. +W Europie wielkim powodzeniem cieszą się od dziesięcioleci tzw. piwa klasztorne. W wielu zakonach założonych w średniowieczu mnisi instalowali warzelnie, w których produkowali piwo według własnych receptur cieszące się powodzeniem. Niektóre po wielu latach działania z powodu problemów finansowych oddawały licencję innym, nie klasztornym browarom, i w ten sposób "religijne" piwo trafiło na komercyjny rynek. +Najbardziej znane marki klasztorne to Leffe, Grimbergen i Steenbrugge (współpracujący z Palm Breweries). + + + + + + + + +Chwila, na którą czekasz przez cały dzień. Ciche westchnienie, towarzyszące otwarciu chłodnej butelki. Głęboki, złocisty kolor, przyjemny, naturalny aromat, a już po chwili lekki, szlachetny smak. Na tę chwilę warto było czekać. + +Frater. Piwo, którego duch wywodzi się z głębi cysterskich manuskryptów, a charakter nadaje mu współczesne pojmowanie szlachetnej sztuki warzenia. +W początkach minionego milennium na ziemie polskie przybyli z zachodu pierwsi mnisi. Wśród rozlicznych praktykowanych w zakonach nauk i sztuk poczesne miejsce zajmowała sztuka warzenia piwa. Wraz z zakapturzonymi braćmi przybył do Polski ten znakomity, złocisty napój oraz pnące się po zakonnych murach szlachetne odmiany chmielu. +W XIII wieku w malowniczej podbeskidzkiej miejscowości Szczyrzyc powstało cysterskie opactwo. Zgodnie z regułą część czasu mnisi poświęcali na wytężoną pracę, której efektem było słynące z niezrównanego smaku, starannie warzone złociste piwo. Mądrość gromadzona przez stulecia pozwoliła stworzyć szlachetny, złocisty napój, który prócz barwy, smaku iaromatu prawdziwego pilsnera, ma również duszę. Tajemnicę, którą odkrywasz z każdym jego łykiem. Spróbuj w pełni docenić tę chwilę prawdziwej, pełnej, głębokiej przyjemności. + diff --git a/src/test/data/utf8text/russian_utf8.txt b/src/test/data/utf8text/russian_utf8.txt new file mode 100644 index 00000000000..4eee4a33ea9 --- /dev/null +++ b/src/test/data/utf8text/russian_utf8.txt @@ -0,0 +1,11 @@ +Великие + +тайны наших любимцев + +Источник: ПРАВДА.Ру +Постоянный адрес: http://www.pravda.ru/science/2004/6/20/55/18599_animals.html + +Чудят не только люди, но и домашние питомцы. Мы решили пополнить «каталог историй» о странных выходках кошек, собак, птичек и другой живности, обитающей по соседству с человечеством + +Когда зоопсихологов просят объяснить странности в поведении животных или их неожиданно фантастическую прозорливость, они честно признаются, что не в силах дать разумное истолкование даже сравнительно часто встречающимся и описанным в соответствующей литературе отклонениям в поведении домашних животных. + diff --git a/src/test/debug/TestError.cpp b/src/test/debug/TestError.cpp new file mode 100644 index 00000000000..45d4b99c402 --- /dev/null +++ b/src/test/debug/TestError.cpp @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +//#include "CLucene/util/_ThreadLocal.h" +#include "CLucene/util/Equators.h" + +void testError ( CuTest *tc ) +{ + const char* msg = "test"; + CLuceneError err ( 0,msg,false ); + CLuceneError err2 = err; + CuAssert ( tc,_T ( "Error did not copy properly" ),err.what() !=err2.what() ); + CuAssert ( tc,_T ( "Error values did not correspond" ),strcmp ( err.what(),err2.what() ) ==0 ); + + IndexReader* reader = NULL; + try + { + RAMDirectory dir; _CL_LDECREF(& dir); + reader = IndexReader::open ( &dir,true ); + } + catch ( CLuceneError& ) + { + _CLDELETE ( reader ); + } + catch ( ... ) + { + _CLDELETE ( reader ); + CuAssert ( tc,_T ( "Error did not catch properly" ),false ); + } +} + +/* +typedef CL_NS(util)::ThreadLocal tlTest; +struct Data{ + tlTest* tl; + CuTest *tc; +}; +_LUCENE_THREAD_FUNC ( threadLocalTest, arg ) +{ + Data* data = (Data*)arg; + CuTest *tc = data->tc; + tlTest* tl = data->tl; + + char* val = tl->get(); + + CLUCENE_ASSERT(val == NULL); + + tl->set(STRDUP_AtoA("test")); + tl->setNull(); + + val = _CL_NEWARRAY(char, 50); + _snprintf(val, 50, "hello from thread %d", (int)_LUCENE_CURRTHREADID); + + tl->set(val); + + CLUCENE_ASSERT(tl->get() != NULL); + + //wait a bit until thread local deleted our data... + Misc::sleep(1000); + + CLUCENE_ASSERT(tl->get() == NULL); +} +void testThreadLocal ( CuTest *tc ) +{ + + const int threadsCount = 10; + + //read using multiple threads... + _LUCENE_THREADID_TYPE threads[threadsCount]; + + Data data; + data.tc = tc; + data.tl = _CLNEW tlTest; + + int i; + for ( i=0;i + +//an in memory input stream for testing binary data +class MemReader : public CL_NS(util)::Reader { + signed char *value; + size_t len; + int64_t pos; + +public: + MemReader(const char *value, const int32_t length = -1) { + if (length >= 0) + this->len = length; + else + this->len = strlen(value); + this->pos = 0; + this->value = _CL_NEWARRAY(signed char, this->len); + memcpy(this->value, value, this->len); + } + virtual ~MemReader() { + _CLDELETE_ARRAY(this->value); + } + + int32_t read(const signed char *&start, int32_t min, int32_t max) { + start = this->value + pos; + int32_t r = max > min ? max : min; + if (len - pos < r) + r = len - pos; + pos += r; + return r; + } + int64_t position() { + return pos; + } + int64_t skip(int64_t ntoskip) { + int64_t s = ntoskip; + if (len - pos < s) + s = len - pos; + + this->pos += s; + return s; + } + size_t size() { + return len; + } +}; + +void TestReaderValueField(CuTest *tc) { + RAMDirectory dir; + + SimpleAnalyzer analyzer; + IndexWriter w(&dir, &analyzer, true); + auto field_name = lucene::util::Misc::_charToWide("f3"); + + Document doc; + auto field = _CLNEW Field(field_name, Field::INDEX_TOKENIZED | Field::STORE_NO); + auto value1 = lucene::util::Misc::_charToWide("value1"); + + auto stringReader = _CLNEW StringReader(value1, wcslen(value1), false); + field->setValue(stringReader); + doc.add(*field); + + w.addDocument(&doc); + w.close(); + + IndexSearcher searcher(&dir); + Term *t1 = _CLNEW Term(_T("f3"), _T("value1")); + auto *query1 = _CLNEW TermQuery(t1); + Hits *hits1 = searcher.search(query1); + CLUCENE_ASSERT(1 == hits1->length()); +} + +void TestMultiSetValueField(CuTest *tc) { + RAMDirectory dir; + + SimpleAnalyzer analyzer; + IndexWriter w(&dir, &analyzer, true); + auto field_name = lucene::util::Misc::_charToWide("f3"); + + Document doc; + auto field = _CLNEW Field(field_name, Field::INDEX_TOKENIZED | Field::STORE_NO); + + auto value1 = lucene::util::Misc::_charToWide("value1"); + field->setValue(value1, false); + auto value2 = lucene::util::Misc::_charToWide("value2"); + field->setValue(value2, false); + doc.add(*field); + + w.addDocument(&doc); + w.close(); + + IndexSearcher searcher(&dir); + Term *t1 = _CLNEW Term(_T("f3"), _T("value1")); + auto *query1 = _CLNEW TermQuery(t1); + Hits *hits1 = searcher.search(query1); + CLUCENE_ASSERT(0 == hits1->length()); + Term *t2 = _CLNEW Term(_T("f3"), _T("value2")); + auto *query2 = _CLNEW TermQuery(t2); + Hits *hits2 = searcher.search(query2); + CLUCENE_ASSERT(1 == hits2->length()); + + doc.clear(); + //_CLDELETE(field) +} + +void TestMultiAddValueField(CuTest *tc) { + RAMDirectory dir; + auto field_name = lucene::util::Misc::_charToWide("f3"); + + SimpleAnalyzer analyzer; + IndexWriter w(&dir, &analyzer, true); + + Document doc; + doc.add(*_CLNEW Field(field_name, _T("value1"), Field::INDEX_TOKENIZED | Field::STORE_NO)); + doc.add(*_CLNEW Field(field_name, _T("value2"), Field::INDEX_TOKENIZED | Field::STORE_NO)); + + w.addDocument(&doc); + w.close(); + + Term *t1 = _CLNEW Term(_T("f3"), _T("value1")); + auto *query1 = _CLNEW TermQuery(t1); + IndexSearcher searcher(&dir); + Hits *hits1 = searcher.search(query1); + + CLUCENE_ASSERT(1 == hits1->length()); + Term *t2 = _CLNEW Term(_T("f3"), _T("value2")); + auto *query2 = _CLNEW TermQuery(t2); + Hits *hits2 = searcher.search(query2); + CLUCENE_ASSERT(1 == hits2->length()); + doc.removeFields(_T("f3")); + CLUCENE_ASSERT(doc.getFields()->size() == 0); + + + _CLDELETE(query1); + _CLDELETE(query2); + _CLDELETE(t1); + _CLDELETE(t2); + _CLDELETE(hits1); + _CLDELETE(hits2); +} + +void TestFields(CuTest *tc) { + Field *f = _CLNEW Field(_T("test"), _T("value"), Field::INDEX_TOKENIZED); + CLUCENE_ASSERT(f->isIndexed() && f->isTokenized()); + CLUCENE_ASSERT(!f->isStored() && !f->isBinary() && !f->getOmitNorms()); + _CLDELETE(f); + + f = _CLNEW Field(_T("test"), _T("value"), Field::STORE_YES | Field::INDEX_NONORMS); + //CLUCENE_ASSERT(f->isIndexed()); + //CLUCENE_ASSERT(!f->isTokenized()); + CLUCENE_ASSERT(f->getOmitNorms()); + CLUCENE_ASSERT(f->isStored() && !f->isBinary()); + _CLDELETE(f); + + Document doc; + doc.add(*_CLNEW Field(_T("f1"), _T("value"), Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f2"), _T("value"), Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f3"), _T("value1"), Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f3"), _T("value2"), Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f4"), _T("value"), Field::INDEX_TOKENIZED)); + CLUCENE_ASSERT(doc.getFields()->size() == 5); + + _CLLDELETE(doc.fields());//just fetch the fields (to test deprecated loads) + + doc.removeField(_T("f3")); + CLUCENE_ASSERT(doc.getFields()->size() == 4); + + //test deprecated enumerator + DocumentFieldEnumeration *e = doc.fields(); + int count = 0; + while (e->hasMoreElements()) { + Field *field4 = e->nextElement(); + CLUCENE_ASSERT(field4 != NULL); + count++; + } + CLUCENE_ASSERT(count == 4); + _CLDELETE(e); + + doc.add(*_CLNEW Field(_T("f3"), _T("value3"), Field::INDEX_TOKENIZED)); + CLUCENE_ASSERT(doc.getFields()->size() == 5); + + //test deprecated enumerator + e = doc.fields(); + count = 0; + while (e->hasMoreElements()) { + Field *field5 = e->nextElement(); + CLUCENE_ASSERT(field5 != NULL); + count++; + } + CLUCENE_ASSERT(count == 5); + _CLDELETE(e); + + doc.removeFields(_T("f3")); + CLUCENE_ASSERT(doc.getFields()->size() == 3); + + doc.removeFields(_T("f4")); + CLUCENE_ASSERT(doc.getFields()->size() == 2); + + doc.removeFields(_T("f1")); + CLUCENE_ASSERT(doc.getFields()->size() == 1); + + doc.removeFields(_T("f2")); + CLUCENE_ASSERT(doc.getFields()->size() == 0); +} + +/* + void TestDateTools(CuTest *tc) { + TCHAR* t = CL_NS(document)::DateTools::timeToString( Misc::currentTimeMillis() , CL_NS(document)::DateTools::MILLISECOND_FORMAT); + _CLDELETE_ARRAY(t); + + TCHAR buf[30]; + const TCHAR* xpt = _T("19700112102054321"); + int64_t vv = (int64_t)987654321; + CL_NS(document)::DateTools::timeToString( vv , CL_NS(document)::DateTools::MILLISECOND_FORMAT, buf, 30); + + if ( _tcscmp(buf,xpt) != 0 ) { + CuFail(tc, _T("timeToString failed\n"), buf, xpt); + } + _CLDELETE_ARRAY(t); + } + */ + +void TestFieldSelectors(CuTest *tc) { + RAMDirectory dir; + const TCHAR *longStrValue = _T("too long a field..."); + { + WhitespaceAnalyzer a; + IndexWriter w(&dir, &a, true); + for (int i = 0; i < 3; i++) { + Document doc; + doc.add(*_CLNEW Field(_T("f1"), _T("value1"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f2"), _T("value2"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f3"), _T("value3"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f4"), _T("value4"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + doc.add(*_CLNEW Field(_T("f5"), longStrValue, Field::STORE_NO | Field::INDEX_TOKENIZED)); + + w.addDocument(&doc); + } + w.flush(); + } + + IndexReader *reader = IndexReader::open(&dir); + MapFieldSelector fieldsToLoad; + fieldsToLoad.add(_T("f2"), FieldSelector::LOAD); + fieldsToLoad.add(_T("f3"), FieldSelector::LAZY_LOAD); + fieldsToLoad.add(_T("f5"), FieldSelector::SIZE); + Document doc; + CLUCENE_ASSERT(reader->document(0, doc, &fieldsToLoad)); + CLUCENE_ASSERT(doc.getFields()->size() == 3); + CuAssertStrEquals(tc, _T("check f2"), _T("value2"), doc.get(_T("f2"))); + CuAssertStrEquals(tc, _T("check f3"), _T("value3"), doc.get(_T("f3"))); + + Field *byteField = doc.getField(_T("f5")); + const ValueArray &bytes = *byteField->binaryValue(); + uint32_t shouldBeInt = 2 * _tcslen(longStrValue); + ValueArray shouldBe(4); + shouldBe[0] = (uint8_t) (shouldBeInt >> 24); + shouldBe[1] = (uint8_t) (shouldBeInt >> 16); + shouldBe[2] = (uint8_t) (shouldBeInt >> 8); + shouldBe[3] = (uint8_t) shouldBeInt; + CLUCENE_ASSERT(byteField != NULL); + CLUCENE_ASSERT(memcmp(shouldBe.values, bytes.values, 4) == 0); + + _CLDELETE(reader); + _CL_LDECREF(&dir);//derefence since we are on the stack... +} + +void _TestDocumentWithOptions(CuTest *tc, int storeBit, FieldSelector::FieldSelectorResult fieldSelectorBit) { + char factbook[1024]; + strcpy(factbook, clucene_data_location); + strcat(factbook, "/reuters-21578/feldman-cia-worldfactbook-data.txt"); + CuAssert(tc, _T("Factbook file does not exist"), Misc::dir_Exists(factbook)); + + Document doc; + Field *f; + const TCHAR *_ts, *_ts2; + const ValueArray *strm; + RAMDirectory ram; + + const char *areaderString = "a binary field"; + const TCHAR *treaderString = _T("a string reader field"); + size_t readerStringLen = strlen(areaderString); + + SimpleAnalyzer an; + IndexWriter writer(&ram, &an, true);//no analyzer needed since we are not indexing... + + ValueArray b((uint8_t *) strdup(areaderString), strlen(areaderString)); + //use binary utf8 + doc.add(*_CLNEW Field(_T("binaryField"), &b, + Field::TERMVECTOR_NO | storeBit | Field::INDEX_NO, true)); + writer.addDocument(&doc); + doc.clear(); + + //use reader + doc.add(*_CLNEW Field(_T("readerField"), _CLNEW StringReader(treaderString), + Field::TERMVECTOR_NO | storeBit | Field::INDEX_NO)); + writer.addDocument(&doc); + doc.clear(); + + //done adding a few documents, now try and add a few more... + //writer.optimize(); + + //use big file + doc.add(*_CLNEW Field(_T("fileField"), + _CLNEW FileReader(factbook, SimpleInputStreamReader::ASCII), + Field::TERMVECTOR_NO | storeBit | Field::INDEX_NO)); + writer.addDocument(&doc); + doc.clear(); + + //another optimise... + //writer.optimize(); + writer.close(); + + IndexReader *reader = IndexReader::open(&ram); + + MapFieldSelector fieldsToLoad; + fieldsToLoad.add(_T("fileField"), fieldSelectorBit); + fieldsToLoad.add(_T("readerField"), fieldSelectorBit); + fieldsToLoad.add(_T("binaryField"), fieldSelectorBit); + + //now check binary field + reader->document(0, doc); + f = doc.getField(_T("binaryField")); + strm = f->binaryValue(); + + CuAssertIntEquals(tc, _T("Check binary length is correct"), readerStringLen, b.length); + for (size_t i = 0; i < readerStringLen; i++) { + CuAssertIntEquals(tc, _T("Check binary values are the same"), (*strm)[i], areaderString[i]); + } + doc.clear(); + + //and check reader stream + reader->document(1, doc); + f = doc.getField(_T("readerField")); + _ts = f->stringValue(); + CuAssertStrEquals(tc, _T("Check readerField length is correct"), treaderString, _ts); + doc.clear(); + + //now check the large field field + reader->document(2, doc); + f = doc.getField(_T("fileField")); + _ts = f->stringValue(); + FileReader fbStream(factbook, FileReader::ASCII); + + int i = 0; + _ts2 = NULL; + do { + int32_t rd = fbStream.read((const void**)&_ts2, 1, 1); + if (rd == -1) + break; + CLUCENE_ASSERT(rd == 1); + CLUCENE_ASSERT(_ts[i] == *_ts2); + i++; + } while (true); + CLUCENE_ASSERT(i == _tcslen(_ts)); + doc.clear(); + + reader->close(); + _CLDELETE(reader); + _CL_LDECREF(&ram);//this is in the stack... +} + + +void TestBinaryDocument(CuTest *tc) { + _TestDocumentWithOptions(tc, Field::STORE_YES, FieldSelector::LOAD); +} +void TestCompressedDocument(CuTest *tc) { + _TestDocumentWithOptions(tc, Field::STORE_COMPRESS, FieldSelector::LOAD); +} +void TestLazyBinaryDocument(CuTest *tc) { + _TestDocumentWithOptions(tc, Field::STORE_YES, FieldSelector::LAZY_LOAD); +} +void TestLazyCompressedDocument(CuTest *tc) { + _TestDocumentWithOptions(tc, Field::STORE_COMPRESS, FieldSelector::LAZY_LOAD); +} + +void TestSetFieldBench(CuTest *tc) { + + ankerl::nanobench::Bench().epochIterations(1).run("TestSetFieldBench", [&] { + RAMDirectory dir; + + SimpleAnalyzer analyzer; + IndexWriter w(&dir, &analyzer, true); + Document doc; + auto field_name = lucene::util::Misc::_charToWide("f3"); + + auto field = _CLNEW Field(field_name, Field::INDEX_TOKENIZED | Field::STORE_NO); + doc.add(*field); + + for (int i = 0; i < 10000; ++i) { + auto value1 = lucene::util::Misc::_charToWide("value1"); + field->setValue(value1, false); + w.addDocument(&doc); + } + w.close(); + doc.clear(); + }); +} + +void TestAddDocument(CuTest *tc) { + RAMDirectory dir; + SimpleAnalyzer sanalyzer; + IndexWriter w(&dir, NULL, true); + w.setUseCompoundFile(false); + w.setDocumentWriter(_CLNEW SDocumentsWriter(w.getDirectory(), &w)); + Document doc; + auto field_name = lucene::util::Misc::_charToWide("f3"); + auto value1 = "value1"; + auto stringReader = _CLNEW lucene::util::SStringReader( + value1, strlen(value1), false); + auto stream = sanalyzer.reusableTokenStream(field_name, stringReader); + + auto field = _CLNEW Field(field_name, Field::INDEX_TOKENIZED | Field::STORE_NO); + field->setValue(stream); + doc.add(*field); + w.addDocument(&doc, &sanalyzer); + doc.clear(); + w.close(); +} + +void TestNewFieldBench(CuTest *tc) { + + ankerl::nanobench::Bench().epochIterations(1).run("TestNewFieldBench", [&] { + RAMDirectory dir; + //std::string value = "value1"; + //std::string field_name = "f3"; + //auto field_name_w = std::wstring(field_name.begin(), field_name.end()); + auto field_name = lucene::util::Misc::_charToWide("f3"); + + //auto field_name_w = lucene::util::Misc::_charToWide(field_name.c_str()); + + SimpleAnalyzer analyzer; + IndexWriter w(&dir, &analyzer, true); + Document doc; + for (int i = 0; i < 10000; ++i) { + //wchar_t value1[value.length()]; + //lucene::util::Misc::_cpycharToWide(value.c_str(), value1, value.length()); + //auto value1 = std::wstring(value).c_str(); + auto value1 = lucene::util::Misc::_charToWide("value1"); + auto field = _CLNEW Field(field_name, value1, Field::INDEX_TOKENIZED | Field::STORE_NO, false); + doc.add(*field); + w.addDocument(&doc); + doc.clear(); + //_CLDELETE_ARRAY(value1); + } + w.close(); + //_CLDELETE(field); + //_CLDELETE_ARRAY(field_name_w); + //doc.add(*); + }); +} + +CuSuite *testdocument(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Document Test")); + + //SUITE_ADD_TEST(suite, TestCompressedDocument); + //SUITE_ADD_TEST(suite, TestBinaryDocument); + //SUITE_ADD_TEST(suite, TestLazyCompressedDocument); + //SUITE_ADD_TEST(suite, TestLazyBinaryDocument); + // SUITE_ADD_TEST(suite, TestFieldSelectors); + SUITE_ADD_TEST(suite, TestFields); + SUITE_ADD_TEST(suite, TestMultiSetValueField); + SUITE_ADD_TEST(suite, TestMultiAddValueField); + SUITE_ADD_TEST(suite, TestSetFieldBench); + SUITE_ADD_TEST(suite, TestNewFieldBench); + SUITE_ADD_TEST(suite, TestReaderValueField); + SUITE_ADD_TEST(suite, TestAddDocument); + //SUITE_ADD_TEST(suite, TestDateTools); + return suite; +} diff --git a/src/test/document/TestField.cpp b/src/test/document/TestField.cpp new file mode 100644 index 00000000000..24391291e91 --- /dev/null +++ b/src/test/document/TestField.cpp @@ -0,0 +1,35 @@ +#include "test.h" +#include "CLucene/_SharedHeader.h" + +CL_NS_USE(document); + + void testFieldConfig(CuTest* tc) { + Field termVector(_T("name"), _T("value"), Field::INDEX_TOKENIZED | Field::TERMVECTOR_YES); + Field termVectorPositions(_T("name"), _T("value"), Field::INDEX_TOKENIZED | Field::TERMVECTOR_WITH_POSITIONS); + Field termVectorOffsets(_T("name"), _T("value"), Field::INDEX_TOKENIZED | Field::TERMVECTOR_WITH_OFFSETS); + Field termVectorPositionsOffsets(_T("name"), _T("value"), Field::INDEX_TOKENIZED | Field::TERMVECTOR_WITH_POSITIONS_OFFSETS); + + CuAssertTrue(tc, termVector.isTermVectorStored(), _T("Term vector is not stored!")); + CuAssertTrue(tc, !termVector.isStoreOffsetWithTermVector(), _T("Term vector with offset is stored!")); + CuAssertTrue(tc, !termVector.isStorePositionWithTermVector(), _T("Term vector with position is stored!")); + + CuAssertTrue(tc, termVectorPositions.isTermVectorStored(), _T("Term vector is not stored!")); + CuAssertTrue(tc, !termVectorPositions.isStoreOffsetWithTermVector(), _T("Term vector with offset is stored!")); + CuAssertTrue(tc, termVectorPositions.isStorePositionWithTermVector(), _T("Term vector with position is not stored!")); + + CuAssertTrue(tc, termVectorOffsets.isTermVectorStored(), _T("Term vector is not stored!")); + CuAssertTrue(tc, termVectorOffsets.isStoreOffsetWithTermVector(), _T("Term vector with offset is not stored!")); + CuAssertTrue(tc, !termVectorOffsets.isStorePositionWithTermVector(), _T("Term vector with position is stored!")); + + CuAssertTrue(tc, termVectorPositionsOffsets.isTermVectorStored(), _T("Term vector is not stored!")); + CuAssertTrue(tc, termVectorPositionsOffsets.isStoreOffsetWithTermVector(), _T("Term vector with offset is not stored!")); + CuAssertTrue(tc, termVectorPositionsOffsets.isStorePositionWithTermVector(), _T("Term vector with position is not stored!")); + } + +CuSuite *testField(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene Field Test")); + + SUITE_ADD_TEST(suite, testFieldConfig); + + return suite; +} diff --git a/src/test/document/TestNumberTools.cpp b/src/test/document/TestNumberTools.cpp new file mode 100644 index 00000000000..8dbf5183722 --- /dev/null +++ b/src/test/document/TestNumberTools.cpp @@ -0,0 +1,80 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + void subtestTwoLongs(CuTest *tc, int64_t i, int64_t j) { + // convert to strings + TCHAR* a = NumberTools::longToString(i); + TCHAR* b = NumberTools::longToString(j); + + // are they the right length? + CuAssertTrue(tc, NumberTools::STR_SIZE == _tcslen(a)); + CuAssertTrue(tc, NumberTools::STR_SIZE == _tcslen(b)); + + // are they the right order? + if (i < j) { + CuAssertTrue(tc, _tcscmp(a,b) < 0); + } else if (i > j) { + CuAssertTrue(tc, _tcscmp(a,b) > 0); + } else { + CuAssertTrue(tc, _tcscmp(a,b) == 0); + } + + // can we convert them back to longs? + int64_t i2 = NumberTools::stringToLong(a); + int64_t j2 = NumberTools::stringToLong(b); + + CuAssertTrue(tc, i == i2); + CuAssertTrue(tc, j == j2); + + _CLDELETE_CARRAY(a); + _CLDELETE_CARRAY(b); + } + + void testNearZero(CuTest *tc) { + for (int32_t i = -100; i <= 100; i++) { + for (int32_t j = -100; j <= 100; j++) { + subtestTwoLongs(tc, i, j); + } + } + } + + void testMin(CuTest *tc) { + // make sure the constants convert to their equivelents + CuAssertTrue(tc, LUCENE_INT64_MIN_SHOULDBE == NumberTools::stringToLong(const_cast(NumberTools::MIN_STRING_VALUE))); + TCHAR* actual = NumberTools::longToString(LUCENE_INT64_MIN_SHOULDBE); + CuAssertStrEquals(tc, _T("Min value"), NumberTools::MIN_STRING_VALUE, actual); + _CLDELETE_LCARRAY(actual); + + // test near MIN, too + for (int64_t l = LUCENE_INT64_MIN_SHOULDBE; l < LUCENE_INT64_MIN_SHOULDBE + 10000; l++) { + subtestTwoLongs(tc,l, l + 1); + } + } + + void testMax(CuTest *tc) { + // make sure the constants convert to their equivelents + CuAssertTrue(tc, LUCENE_INT64_MAX_SHOULDBE == NumberTools::stringToLong(const_cast(NumberTools::MAX_STRING_VALUE))); + TCHAR* actual = NumberTools::longToString(LUCENE_INT64_MAX_SHOULDBE); + CuAssertStrEquals(tc, _T("Max value"), NumberTools::MAX_STRING_VALUE, actual); + _CLDELETE_LCARRAY(actual); + + // test near MAX, too + for (int64_t l = LUCENE_INT64_MAX_SHOULDBE; l > LUCENE_INT64_MAX_SHOULDBE - 10000; l--) { + subtestTwoLongs(tc,l, l - 1); + } + } + +CuSuite *testNumberTools(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Number Tools Test")); + + SUITE_ADD_TEST(suite, testNearZero); + SUITE_ADD_TEST(suite, testMin); + SUITE_ADD_TEST(suite, testMax); + return suite; +} diff --git a/src/test/index/IndexWriter4Test.cpp b/src/test/index/IndexWriter4Test.cpp new file mode 100644 index 00000000000..d51e472785e --- /dev/null +++ b/src/test/index/IndexWriter4Test.cpp @@ -0,0 +1,44 @@ +#include "CLucene/_ApiHeader.h" +#include "IndexWriter4Test.h" +#include "CLucene/index/_SegmentInfos.h" + +CL_NS_DEF(index) + +IndexWriter4Test::IndexWriter4Test(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, const bool create) : + IndexWriter(d, a, create) +{ +} + +IndexWriter4Test::IndexWriter4Test(CL_NS(store)::Directory* d, bool autoCommit, CL_NS(analysis)::Analyzer* a, const bool create) : + IndexWriter(d, autoCommit, a, create) +{ +} + +// for test purpose +int32_t IndexWriter4Test::getDocCount(int32_t i) { + return IndexWriter::getDocCount(i); +} + +// for test purpose +int32_t IndexWriter4Test::getNumBufferedDocuments(){ + return IndexWriter::getNumBufferedDocuments(); +} + +// for test purpose +int32_t IndexWriter4Test::getSegmentCount(){ + return IndexWriter::getSegmentCount(); +} + +int32_t IndexWriter4Test::getBufferedDeleteTermsSize() { + return IndexWriter::getBufferedDeleteTermsSize(); +} + +int32_t IndexWriter4Test::getNumBufferedDeleteTerms() { + return IndexWriter::getNumBufferedDeleteTerms(); +} + +SegmentInfo* IndexWriter4Test::newestSegment() { + return IndexWriter::newestSegment(); +} + +CL_NS_END diff --git a/src/test/index/IndexWriter4Test.h b/src/test/index/IndexWriter4Test.h new file mode 100644 index 00000000000..c89f7a4b329 --- /dev/null +++ b/src/test/index/IndexWriter4Test.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2010 Borivoj Kostka and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_test_index_IndexWriter4Test_ +#define _lucene_test_index_IndexWriter4Test_ + +#include "CLucene/index/IndexWriter.h" + +CL_NS_DEF(index) + +/* + * Derived from IndexWriter, contains methods used only for testing purposes. + * + */ +class IndexWriter4Test : public IndexWriter { + +public: + + IndexWriter4Test(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, const bool create); + IndexWriter4Test(CL_NS(store)::Directory* d, bool autocommit, CL_NS(analysis)::Analyzer* a, const bool create); + + int32_t getDocCount(int32_t i); + int32_t getNumBufferedDocuments(); + int32_t getSegmentCount(); + int32_t getBufferedDeleteTermsSize(); + int32_t getNumBufferedDeleteTerms(); + SegmentInfo* newestSegment(); + +}; + +CL_NS_END +#endif diff --git a/src/test/index/TestAddIndexesNoOptimize.cpp b/src/test/index/TestAddIndexesNoOptimize.cpp new file mode 100644 index 00000000000..01d392b0f91 --- /dev/null +++ b/src/test/index/TestAddIndexesNoOptimize.cpp @@ -0,0 +1,592 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2010 Borivoj Kostka and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/RAMDirectory.h" +#include "CLucene/index/MergeScheduler.h" +#include "../store/MockRAMDirectory.h" +#include "IndexWriter4Test.h" + +CL_NS_USE(store) +CL_NS_USE(index) +CL_NS_USE(document) +CL_NS_USE2(analysis,standard) + +static IndexWriter4Test * newWriter(Directory * dir, WhitespaceAnalyzer * analyzer, bool create) { + + IndexWriter4Test * writer = _CLNEW IndexWriter4Test(dir, analyzer, create); + writer->setMergePolicy(_CLNEW LogDocMergePolicy()); + return writer; +} + +static void addDocs(IndexWriter4Test * writer, int numDocs) { + + for (int i = 0; i < numDocs; i++) { + Document doc; + doc.add(* _CLNEW Field(_T("content"), _T("aaa"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); + } +} + +static void addDocs2(IndexWriter4Test * writer, int numDocs) { + + for (int i = 0; i < numDocs; i++) { + Document doc; + doc.add(* _CLNEW Field(_T("content"), _T("bbb"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); + } +} + +static void verifyNumDocs(CuTest *tc, Directory * dir, int numDocs) { + + IndexReader * reader = IndexReader::open(dir); + assertEquals(numDocs, reader->maxDoc()); + assertEquals(numDocs, reader->numDocs()); + reader->close(); + _CLLDELETE(reader); +} + +static void verifyTermDocs(CuTest *tc, Directory * dir, Term * term, int numDocs) { + + IndexReader * reader = IndexReader::open(dir); + TermDocs * termDocs = reader->termDocs(term); + int count = 0; + while (termDocs->next()) + count++; + assertEquals(numDocs, count); + termDocs->close(); + _CLLDELETE(termDocs); + reader->close(); + _CLLDELETE(reader); +} + +void setUpDirs(CuTest *tc, Directory * dir, Directory * aux) { + + IndexWriter4Test * writer = NULL; + WhitespaceAnalyzer analyzer; + + writer = newWriter(dir, &analyzer, true); + writer->setMaxBufferedDocs(1000); + // add 1000 documents in 1 segment + addDocs(writer, 1000); + assertEquals(1000, writer->docCount()); + assertEquals(1, writer->getSegmentCount()); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(aux, &analyzer, true); + writer->setUseCompoundFile(false); // use one without a compound file + writer->setMaxBufferedDocs(100); + writer->setMergeFactor(10); + // add 30 documents in 3 segments + for (int i = 0; i < 3; i++) { + addDocs(writer, 10); + writer->close(); + _CLLDELETE(writer); + writer = newWriter(aux, &analyzer, false); + writer->setUseCompoundFile(false); // use one without a compound file + writer->setMaxBufferedDocs(100); + writer->setMergeFactor(10); + } + assertEquals(30, writer->docCount()); + assertEquals(3, writer->getSegmentCount()); + writer->close(); + _CLLDELETE(writer); +} + +void testSimpleCase(CuTest *tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // two auxiliary directories + Directory * aux = _CLNEW RAMDirectory(); + Directory * aux2 = _CLNEW RAMDirectory(); + + IndexWriter4Test * writer = NULL; + + WhitespaceAnalyzer analyzer; + + writer = newWriter(dir, &analyzer, true); + + // add 100 documents + addDocs(writer, 100); + assertEquals(100, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(aux, &analyzer, true); + writer->setUseCompoundFile(false); // use one without a compound file + // add 40 documents in separate files + addDocs(writer, 40); + assertEquals(40, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(aux2, &analyzer, true); + // add 40 documents in compound files + addDocs2(writer, 50); + assertEquals(50, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + // test doc count before segments are merged + writer = newWriter(dir, &analyzer, false); + assertEquals(100, writer->docCount()); + { + ValueArray dirs(2); + dirs[0] = aux; + dirs[1] = aux2; + writer->addIndexesNoOptimize( dirs ); + } + assertEquals(190, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + // make sure the old index is correct + verifyNumDocs(tc, aux, 40); + + // make sure the new index is correct + verifyNumDocs(tc, dir, 190); + + // now add another set in. + Directory * aux3 = _CLNEW RAMDirectory(); + writer = newWriter(aux3, &analyzer, true); + // add 40 documents + addDocs(writer, 40); + assertEquals(40, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + // test doc count before segments are merged/index is optimized + writer = newWriter(dir, &analyzer, false); + assertEquals(190, writer->docCount()); + { + ValueArray dirs(1); + dirs[0] = aux3; + writer->addIndexesNoOptimize( dirs ); + } + assertEquals(230, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + // make sure the new index is correct + verifyNumDocs(tc, dir, 230); + + Term t1(_T("content"), _T("aaa")); + Term t2(_T("content"), _T("bbb")); + + verifyTermDocs(tc, dir, &t1, 180); + verifyTermDocs(tc, dir, &t2, 50); + + // now optimize it. + writer = newWriter(dir, &analyzer, false); + writer->optimize(); + writer->close(); + _CLLDELETE(writer); + + // make sure the new index is correct + verifyNumDocs(tc, dir, 230); + + verifyTermDocs(tc, dir, &t1, 180); + verifyTermDocs(tc, dir, &t2, 50); + + // now add a single document + Directory * aux4 = _CLNEW RAMDirectory(); + writer = newWriter(aux4, &analyzer, true); + addDocs2(writer, 1); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(dir, &analyzer, false); + assertEquals(230, writer->docCount()); + + { + ValueArray dirs(1); + dirs[0] = aux4; + writer->addIndexesNoOptimize( dirs ); + } + + assertEquals(231, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + verifyNumDocs(tc, dir, 231); + + verifyTermDocs(tc, dir, &t2, 51); + + dir->close(); + _CLLDELETE(dir); + aux->close(); + _CLLDELETE(aux); + aux2->close(); + _CLLDELETE(aux2); + aux3->close(); + _CLLDELETE(aux3); + aux4->close(); + _CLLDELETE(aux4); +} + +// case 0: add self or exceed maxMergeDocs, expect exception +void testAddSelf(CuTest * tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory * aux = _CLNEW RAMDirectory(); + + IndexWriter4Test * writer = NULL; + WhitespaceAnalyzer analyzer; + + writer = newWriter(dir, &analyzer, true); + // add 100 documents + addDocs(writer, 100); + assertEquals(100, writer->docCount()); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(aux, &analyzer, true); + writer->setUseCompoundFile(false); // use one without a compound file + writer->setMaxBufferedDocs(1000); + // add 140 documents in separate files + addDocs(writer, 40); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(aux, &analyzer, true); + writer->setUseCompoundFile(false); // use one without a compound file + writer->setMaxBufferedDocs(1000); + addDocs(writer, 100); + writer->close(); + _CLLDELETE(writer); + + writer = newWriter(dir, &analyzer, false); + try { + // cannot add self + ValueArray dirs(2); + dirs[0] = aux; + dirs[1] = dir; + writer->addIndexesNoOptimize( dirs ); + assertTrue(false); + } + catch (CLuceneError&) { + assertEquals(100, writer->docCount()); + } + writer->close(); + _CLLDELETE(writer); + + // make sure the index is correct + verifyNumDocs(tc, dir, 100); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); +} + + // in all the remaining tests, make the doc count of the oldest segment + // in dir large so that it is never merged in addIndexesNoOptimize() + // case 1: no tail segments +void testNoTailSegments(CuTest * tc) { + + // main directory + Directory *dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory *aux = _CLNEW RAMDirectory(); + + WhitespaceAnalyzer analyzer; + + setUpDirs(tc, dir, aux); + + IndexWriter4Test * writer = newWriter(dir, &analyzer, false); + writer->setMaxBufferedDocs(10); + writer->setMergeFactor(4); + addDocs(writer, 10); + + ValueArray dirs(1); + dirs[0] = aux; + writer->addIndexesNoOptimize(dirs); + + assertEquals(1040, writer->docCount()); + assertEquals(2, writer->getSegmentCount()); + assertEquals(1000, writer->getDocCount(0)); + writer->close(); + _CLLDELETE(writer); + + // make sure the index is correct + verifyNumDocs(tc, dir, 1040); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); +} + +// case 2: tail segments, invariants hold, no copy +void testNoCopySegments(CuTest * tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory * aux = _CLNEW RAMDirectory(); + + WhitespaceAnalyzer an; + + setUpDirs(tc, dir, aux); + + IndexWriter4Test * writer = newWriter(dir, &an, false); + writer->setMaxBufferedDocs(9); + writer->setMergeFactor(4); + addDocs(writer, 2); + + ValueArray dirs(1); + dirs[0] = aux; + writer->addIndexesNoOptimize(dirs); + + assertEquals(1032, writer->docCount()); + assertEquals(2, writer->getSegmentCount()); + assertEquals(1000, writer->getDocCount(0)); + writer->close(); + _CLLDELETE(writer); + + // make sure the index is correct + verifyNumDocs(tc, dir, 1032); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); +} + +// case 3: tail segments, invariants hold, copy, invariants hold +void testNoMergeAfterCopy(CuTest * tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory * aux = _CLNEW RAMDirectory(); + + WhitespaceAnalyzer an; + + setUpDirs(tc, dir, aux); + + IndexWriter4Test * writer = newWriter(dir, &an, false); + writer->setMaxBufferedDocs(10); + writer->setMergeFactor(4); + + ValueArray dirs(2); + dirs[0] = aux; + dirs[1] = aux; + writer->addIndexesNoOptimize(dirs); + + assertEquals(1060, writer->docCount()); + assertEquals(1000, writer->getDocCount(0)); + writer->close(); + _CLLDELETE(writer); + + // make sure the index is correct + verifyNumDocs(tc, dir, 1060); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); +} + +// case 4: tail segments, invariants hold, copy, invariants not hold +void testMergeAfterCopy(CuTest * tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory * aux = _CLNEW RAMDirectory(); + + WhitespaceAnalyzer an; + + setUpDirs(tc, dir, aux); + + IndexReader * reader = IndexReader::open(aux); + for (int i = 0; i < 20; i++) { + reader->deleteDocument(i); + } + assertEquals(10, reader->numDocs()); + reader->close(); + _CLLDELETE(reader); + + IndexWriter4Test * writer = newWriter(dir, &an, false); + writer->setMaxBufferedDocs(4); + writer->setMergeFactor(4); + + ValueArray dirs(2); + dirs[0] = aux; + dirs[1] = aux; + writer->addIndexesNoOptimize(dirs); + + assertEquals(1020, writer->docCount()); + assertEquals(1000, writer->getDocCount(0)); + writer->close(); + _CLLDELETE(writer); + + // make sure the index is correct + verifyNumDocs(tc, dir, 1020); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); +} + +// case 5: tail segments, invariants not hold +void testMoreMerges(CuTest * tc) { + + // main directory + Directory * dir = _CLNEW RAMDirectory(); + // auxiliary directory + Directory * aux = _CLNEW RAMDirectory(); + Directory * aux2 = _CLNEW RAMDirectory(); + + WhitespaceAnalyzer an; + + setUpDirs(tc, dir, aux); + + IndexWriter4Test * writer = newWriter(aux2, &an, true); + writer->setMaxBufferedDocs(100); + writer->setMergeFactor(10); + + ValueArray dirs(1); + dirs[0] = aux; + writer->addIndexesNoOptimize(dirs); + + assertEquals(30, writer->docCount()); + assertEquals(3, writer->getSegmentCount()); + writer->close(); + _CLLDELETE(writer); + + IndexReader * reader = IndexReader::open(aux); + for (int i = 0; i < 27; i++) { + reader->deleteDocument(i); + } + assertEquals(3, reader->numDocs()); + reader->close(); + _CLLDELETE(reader); + + reader = IndexReader::open(aux2); + for (int i = 0; i < 8; i++) { + reader->deleteDocument(i); + } + assertEquals(22, reader->numDocs()); + reader->close(); + _CLLDELETE( reader ); + + writer = newWriter(dir, &an, false); + writer->setMaxBufferedDocs(6); + writer->setMergeFactor(4); + + ValueArray dirs2(2); + dirs2[0] = aux; + dirs2[1] = aux2; + writer->addIndexesNoOptimize(dirs2); + + assertEquals(1025, writer->docCount()); + assertEquals(1000, writer->getDocCount(0)); + writer->close(); + _CLLDELETE( writer ); + + // make sure the index is correct + verifyNumDocs(tc, dir, 1025); + + dir->close(); + _CLLDELETE(dir); + + aux->close(); + _CLLDELETE(aux); + + aux2->close(); + _CLLDELETE(aux2); +} + +// LUCENE-1270 +void testHangOnClose(CuTest * tc) { + + WhitespaceAnalyzer an; + MockRAMDirectory * dir = _CLNEW MockRAMDirectory(); + dir->setRandomIOExceptionRate(0.0, 0); + IndexWriter4Test * writer = _CLNEW IndexWriter4Test(dir, false, &an, true); + writer->setMergePolicy(_CLNEW LogByteSizeMergePolicy()); + writer->setMaxBufferedDocs(5); + writer->setUseCompoundFile(false); + writer->setMergeFactor(100); + + Document doc; + doc.add(* _CLNEW Field(_T("content"), _T("aaa bbb ccc ddd eee fff ggg hhh iii"), + Field::STORE_YES | Field::INDEX_TOKENIZED | Field::TERMVECTOR_WITH_POSITIONS_OFFSETS)); + for(int i=0;i<60;i++) + writer->addDocument(&doc); + writer->setMaxBufferedDocs(200); + Document doc2; + doc2.add(* _CLNEW Field(_T("content"), _T("aaa bbb ccc ddd eee fff ggg hhh iii"), + Field::STORE_YES | Field::INDEX_NO)); + doc2.add(* _CLNEW Field(_T("content"), _T("aaa bbb ccc ddd eee fff ggg hhh iii"), + Field::STORE_YES | Field::INDEX_NO)); + doc2.add(* _CLNEW Field(_T("content"), _T("aaa bbb ccc ddd eee fff ggg hhh iii"), + Field::STORE_YES | Field::INDEX_NO)); + doc2.add(* _CLNEW Field(_T("content"), _T("aaa bbb ccc ddd eee fff ggg hhh iii"), + Field::STORE_YES | Field::INDEX_NO)); + for(int i=0;i<10;i++) + writer->addDocument(&doc2); + writer->close(); + _CLLDELETE(writer); + + MockRAMDirectory * dir2 = _CLNEW MockRAMDirectory(); + dir2->setRandomIOExceptionRate(0.0, 0); + writer = _CLNEW IndexWriter4Test(dir2, false, &an, true); + + LogByteSizeMergePolicy * lmp = _CLNEW LogByteSizeMergePolicy(); + lmp->setMinMergeMB(0.0001); + writer->setMergePolicy(lmp); + writer->setMergeFactor(4); + writer->setUseCompoundFile(false); + writer->setMergeScheduler(_CLNEW SerialMergeScheduler()); + + + ValueArray dirs(1); + dirs[0] = dir; + writer->addIndexesNoOptimize(dirs); + + writer->close(); + _CLLDELETE(writer); + + dir->close(); + _CLLDELETE(dir); + + dir2->close(); + _CLLDELETE(dir2); + +} + +CuSuite *testAddIndexesNoOptimize(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene AddIndexesNoOptimize Test")); + SUITE_ADD_TEST(suite, testSimpleCase); + SUITE_ADD_TEST(suite, testAddSelf); + SUITE_ADD_TEST(suite, testNoTailSegments); + SUITE_ADD_TEST(suite, testNoCopySegments); + SUITE_ADD_TEST(suite, testNoMergeAfterCopy); + SUITE_ADD_TEST(suite, testMergeAfterCopy); + SUITE_ADD_TEST(suite, testMoreMerges); + SUITE_ADD_TEST(suite, testHangOnClose); + + return suite; +} diff --git a/src/test/index/TestHighFreqTerms.cpp b/src/test/index/TestHighFreqTerms.cpp new file mode 100644 index 00000000000..de7fd24c393 --- /dev/null +++ b/src/test/index/TestHighFreqTerms.cpp @@ -0,0 +1,86 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + class TestTermInfo: LUCENE_BASE { + public: + int32_t docFreq; + Term* term; + + TestTermInfo(Term* t, int32_t df) { + term = _CL_POINTER(t); + docFreq = df; + } + ~TestTermInfo(){ + _CLDECDELETE(term); + } + }; + + class TermInfoQueue: public PriorityQueue > { + public: + TermInfoQueue(int32_t size) { + initialize(size,true); + } + bool lessThan(TestTermInfo* A, TestTermInfo* B) { + return A->docFreq < B->docFreq; + + } + }; + + void _TestHighFreqTerms(const char* index, size_t numTerms) { + + IndexReader* reader = IndexReader::open(index); + + TermInfoQueue* tiq = _CLNEW TermInfoQueue(100); + TermEnum* terms = reader->terms(); + int32_t c=0; + int32_t minFreq = 0; + while (terms->next()) { + if (terms->docFreq() > minFreq) { + Term* term = terms->term(false); + tiq->put(_CLNEW TestTermInfo(term, terms->docFreq())); + c++; + if (tiq->size() >= numTerms) { // if tiq overfull + TestTermInfo* tti=tiq->pop(); + _CLLDELETE(tti); // remove lowest in tiq + c--; + minFreq = ((TestTermInfo*)tiq->top())->docFreq; // reset minFreq + } + } + } + + while (tiq->size() != 0) { + TestTermInfo* termInfo = (TestTermInfo*)tiq->pop(); + _CLLDELETE(termInfo); + c--; + } + + terms->close(); + _CLDELETE(terms); + _CLDELETE(tiq); + + reader->close(); + _CLDELETE( reader ); + + //CuMessageA(tc,"%d milliseconds\n",(int32_t)(Misc::currentTimeMillis()-start)); + } + void TestHighFreqTerms(CuTest *tc){ + char loc[1024]; + strcpy(loc, clucene_data_location); + strcat(loc, "/reuters-21578-index"); + + CuAssert(tc,_T("Index does not exist"),Misc::dir_Exists(loc)); + _TestHighFreqTerms(loc,100); + } + +CuSuite *testhighfreq(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene High Frequencies Test")); + + SUITE_ADD_TEST(suite, TestHighFreqTerms); + return suite; +} diff --git a/src/test/index/TestIndexModifier.cpp b/src/test/index/TestIndexModifier.cpp new file mode 100644 index 00000000000..2a0d60698f0 --- /dev/null +++ b/src/test/index/TestIndexModifier.cpp @@ -0,0 +1,215 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/index/IndexModifier.h" +#include + +CL_NS_USE(store) +CL_NS_USE(index) +CL_NS_USE(document) +CL_NS_USE2(analysis,standard) + +void IndexModifierExceptionTest(CuTest *tc) +{ + class LockedLock : public LuceneLock + { + public: + LockedLock() : LuceneLock() {}; + virtual bool obtain() {return obtain(0);}; + virtual void release() {}; + virtual bool isLocked() {return true;}; + bool obtain(int64_t lockWaitTimeout) {return false;}; + virtual std::string toString() {return "LockedLock";}; + virtual const char* getObjectName() const {return "LockedLock";}; + }; + + class LockedDirectory : public RAMDirectory + { + public: + bool errOn; + + LockedDirectory() : RAMDirectory(), errOn(false) {}; + + // this simulates locking problem, only if errOn is true + LuceneLock* makeLock(const char* name) { + if (errOn) + return _CLNEW LockedLock(); + else + return RAMDirectory::makeLock(name); + }; + }; + + LockedDirectory directory; + StandardAnalyzer analyzer; + Document doc; + IndexModifier * pIm = NULL; + + try + { + doc.add(* _CLNEW Field(_T("text"), _T("Document content"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + pIm = _CLNEW IndexModifier(&directory, &analyzer, true); + + pIm->addDocument(&doc); + pIm->deleteDocument(0); + } + catch (CLuceneError & err) + { + CuFail(tc, _T("Exception thrown upon startup")); + return; + } + + try + { + // switch on locking timeout simulation + directory.errOn = true; + + // throws lock timeout exception + pIm->addDocument(&doc); + CuFail(tc, _T("Exception was not thrown during addDocument")); + } + catch (CLuceneError & err) + { + } + + // this produces Access Violation exception + try { + _CLLDELETE(pIm); + } catch (...) + { + CuFail(tc, _T("Exception thrown upon deletion")); + } +} + +class bulk_modification { +public: + void modify_index(CuTest *tc, IndexModifier& ndx); +}; + +class incremental_modification { +public: + void modify_index(CuTest *tc, IndexModifier& ndx); +}; + +template +class IMinsertDelete_tester : public modification { +public: + void invoke(Directory& storage, CuTest *tc); +}; + +void bulk_modification::modify_index(CuTest *tc, IndexModifier& ndx){ + std::basic_stringstream field; + for ( int i=0;i<1000;i++ ){ + field.str(_T("")); + field << _T("fielddata") << i; + + Document doc; + + doc.add ( + *_CLNEW Field( + _T("field0"), + field.str().c_str(), + Field::STORE_YES | Field::INDEX_UNTOKENIZED + ) + ); + ndx.addDocument(&doc); + } + for ( int i=0;i<1000;i+=2 ){ + field.str(_T("")); + field << _T("fielddata") << i; + + Term deleted( + _T("field0"), + field.str().c_str(), + true + ); + CLUCENE_ASSERT(ndx.deleteDocuments(&deleted) > 0); + } +} + +void incremental_modification::modify_index(CuTest *tc, IndexModifier& ndx){ + std::basic_stringstream field; + for ( int i=0;i<1000;i++ ){ + field.str(_T("")); + field << _T("fielddata") << i; + + Document doc; + + doc.add ( + *_CLNEW Field( + _T("field0"), + field.str().c_str(), + Field::STORE_YES | Field::INDEX_UNTOKENIZED + ) + ); + ndx.addDocument(&doc); + if ( 0 == i % 2 ) { + Term deleted( + _T("field0"), + field.str().c_str(), + true + ); + CLUCENE_ASSERT(ndx.deleteDocuments(&deleted) > 0); + } + } +} + +template +void IMinsertDelete_tester::invoke( + Directory& storage, + CuTest *tc +){ + SimpleAnalyzer a; + + IndexModifier ndx2(&storage,&a,true); + ndx2.close(); + IndexModifier ndx(&storage,&a,false); + + ndx.setUseCompoundFile(false); + ndx.setMergeFactor(2); + + this->modify_index(tc, ndx); + + ndx.optimize(); + ndx.close(); + + //test the ram loading + RAMDirectory ram2(&storage); + IndexReader* reader2 = IndexReader::open(&ram2); + Term* term = _CLNEW Term(_T("field0"),_T("fielddata1")); + TermDocs* en = reader2->termDocs(term); + CLUCENE_ASSERT(en->next()); + _CLDELETE(en); + _CLDECDELETE(term); + term = _CLNEW Term(_T("field0"),_T("fielddata0")); + en = reader2->termDocs(term); + CLUCENE_ASSERT(!en->next()); + _CLDELETE(en); + _CLDECDELETE(term); + _CLDELETE(reader2); +} + +void testIMinsertDelete(CuTest *tc){ + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir,CL_MAX_PATH,"%s/%s",cl_tempDir, "test.search"); + RAMDirectory ram; + FSDirectory* disk = FSDirectory::getDirectory(fsdir); + IMinsertDelete_tester().invoke(ram, tc); + IMinsertDelete_tester().invoke(ram, tc); + IMinsertDelete_tester().invoke(*disk, tc); + IMinsertDelete_tester().invoke(*disk, tc); + disk->close(); + _CLDECDELETE(disk); +} + +CuSuite *testIndexModifier(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene IndexModifier Test")); + SUITE_ADD_TEST(suite, IndexModifierExceptionTest); + SUITE_ADD_TEST(suite, testIMinsertDelete); + + return suite; +} diff --git a/src/test/index/TestIndexReader.cpp b/src/test/index/TestIndexReader.cpp new file mode 100644 index 00000000000..852a3160222 --- /dev/null +++ b/src/test/index/TestIndexReader.cpp @@ -0,0 +1,309 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include +#include "CLucene/index/_SegmentHeader.h" +#include "CLucene/index/_MultiSegmentReader.h" +#include "CLucene/index/MultiReader.h" + +typedef IndexReader* (*TestIRModifyIndex)(CuTest* tc, IndexReader* reader, int modify); +DEFINE_MUTEX(createReaderMutex) + + +void createDocument(Document& doc, int n, int numFields) { + doc.clear(); + StringBuffer sb; + sb.append( _T("a")); + sb.appendInt(n); + doc.add(* _CLNEW Field( _T("field1"), sb.getBuffer(), Field::STORE_YES | Field::INDEX_TOKENIZED)); + sb.append(_T(" b")); + sb.appendInt(n); + for (int i = 1; i < numFields; i++) { + TCHAR buf[10]; + _sntprintf(buf,10,_T("field%d"), i+1); + doc.add(* _CLNEW Field(buf, sb.getBuffer(), Field::STORE_YES | Field::INDEX_TOKENIZED)); + } +} + +void createIndex(CuTest* tc, Directory* dir, bool multiSegment) { + WhitespaceAnalyzer whitespaceAnalyzer; + IndexWriter w(dir, &whitespaceAnalyzer, true); + + w.setMergePolicy(_CLNEW LogDocMergePolicy()); + Document doc; + for (int i = 0; i < 100; i++) { + createDocument(doc, i, 4); + w.addDocument(&doc); + if (multiSegment && (i % 10) == 0) { + w.flush(); + } + } + + if (!multiSegment) { + w.optimize(); + } + + w.close(); + + IndexReader* r = IndexReader::open(dir); + if (multiSegment) { + CuAssert(tc,_T("check is multi"), strcmp(r->getObjectName(),"MultiSegmentReader")==0); + } else { + CuAssert(tc,_T("check is segment"), strcmp(r->getObjectName(),"SegmentReader")==0); + } + r->close(); + _CLDELETE(r); +} + +struct ReaderCouple{ + IndexReader* newReader; + IndexReader* refreshedReader; +}; + +void assertReaderClosed(CuTest* tc, IndexReader* reader, bool checkSubReaders, bool checkNormsClosed) { + //TODO: CuAssertIntEquals(tc, _T("Check refcount is zero"), 0, reader->getRefCount()); + +/* can't test internal... if (checkNormsClosed && reader->instanceOf(SegmentReader::getClassName())) { + CuAssertTrue(tc, ((SegmentReader*) reader)->normsClosed()); + }*/ + + if (checkSubReaders) { + /* can't test internal... + if (reader->instanceOf(MultiSegmentReader::getClassName())) { + const CL_NS(util)::ArrayBase& subReaders = *((MultiSegmentReader*) reader)->getSubReaders(); + for (int i = 0; i < subReaders.length; i++) { + assertReaderClosed(tc, subReaders[i], checkSubReaders, checkNormsClosed); + } + }*/ + + if (reader != NULL && reader->instanceOf(MultiReader::getClassName())) { + const CL_NS(util)::ArrayBase& subReaders = *((MultiReader*) reader)->getSubReaders(); + for (size_t i = 0; i < subReaders.length; i++) { + assertReaderClosed(tc, subReaders[i], checkSubReaders, checkNormsClosed); + } + } + } +} + +void assertReaderOpen(CuTest* /*tc*/, IndexReader* reader) { + Document doc; + reader->document(0, doc);//hack to call ensureOpen... + +/* can't test internal... if (reader->instanceOf(MultiSegmentReader::getClassName())) { + const CL_NS(util)::ArrayBase& subReaders = *((MultiSegmentReader*) reader)->getSubReaders(); + for (int i = 0; i < subReaders.length; i++) { + assertReaderOpen(tc, subReaders[i]); + } + }*/ +} + +Directory* defaultModifyIndexTestDir1 = NULL; +IndexReader* defaultModifyIndexTest(CuTest* /*tc*/, IndexReader* reader, int i){ + WhitespaceAnalyzer whitespaceAnalyzer; + switch (i) { + case 0: { + IndexWriter w(defaultModifyIndexTestDir1, &whitespaceAnalyzer, false); + Term* t1 = _CLNEW Term(_T("field2"), _T("a11")); + w.deleteDocuments(t1); + Term* t2 = _CLNEW Term(_T("field2"), _T("b30")); + w.deleteDocuments(t2); + _CLDECDELETE(t1); + _CLDECDELETE(t2); + w.close(); + break; + } + case 1: { + IndexReader* reader = IndexReader::open(defaultModifyIndexTestDir1); + reader->setNorm(4, _T("field1"), (uint8_t)123); + reader->setNorm(44, _T("field2"), (uint8_t)222); + reader->setNorm(44, _T("field4"), (uint8_t)22); + reader->close(); + _CLDELETE(reader); + break; + } + case 2: { + IndexWriter w(defaultModifyIndexTestDir1, &whitespaceAnalyzer, false); + w.optimize(); + w.close(); + break; + } + case 3: { + IndexWriter w(defaultModifyIndexTestDir1, &whitespaceAnalyzer, false); + Document doc; + createDocument(doc, 101, 4); + w.addDocument(&doc); + w.optimize(); + createDocument(doc,102, 4); + w.addDocument(&doc); + createDocument(doc,103, 4); + w.addDocument(&doc); + w.close(); + break; + } + case 4: { + IndexReader* reader = IndexReader::open(defaultModifyIndexTestDir1); + reader->setNorm(5, _T("field1"), (uint8_t)123); + reader->setNorm(55, _T("field2"), (uint8_t)222); + reader->close(); + _CLDELETE(reader); + break; + } + + } + return IndexReader::open(defaultModifyIndexTestDir1); +} + + +Directory* defaultModifyIndexTestDir2 = NULL; +IndexReader* defaultModifyIndexTestMulti(CuTest* tc, IndexReader* reader, int i){ + IndexReader* x = defaultModifyIndexTest(tc,reader,i); //call main test + _CLDELETE(x); + + + Directory* tmp = defaultModifyIndexTestDir1; + defaultModifyIndexTestDir1 = defaultModifyIndexTestDir2; + x = defaultModifyIndexTest(tc,reader,i); //call main test + _CLDELETE(x); + defaultModifyIndexTestDir1 = tmp; + + ValueArray readers(2); + readers[0] = IndexReader::open(defaultModifyIndexTestDir1); + readers[1] = IndexReader::open(defaultModifyIndexTestDir2); + return _CLNEW MultiReader(&readers, true); +} + +ReaderCouple refreshReader(CuTest* tc, IndexReader* reader, TestIRModifyIndex test, int modify, bool hasChanges) { + SCOPED_LOCK_MUTEX(createReaderMutex) + + IndexReader* r = NULL; + if (test != NULL) { + r = (*test)(tc, reader, modify); + } + + IndexReader* refreshed = reader->reopen(); + if (hasChanges) { + CuAssert(tc, _T("No new IndexReader instance created during refresh."), refreshed != reader ); + } else { + CuAssert(tc, _T("New IndexReader instance created during refresh even though index had no changes."), refreshed == reader); + } + + ReaderCouple ret = {r, refreshed}; + return ret; +} +ReaderCouple refreshReader(CuTest* tc, IndexReader* reader, bool hasChanges) { + return refreshReader(tc,reader, NULL, -1, hasChanges); +} +void performDefaultIRTests(CuTest *tc, IndexReader* index1, IndexReader* index2, IndexReader* index2B, TestIRModifyIndex test){ + TestAssertIndexReaderEquals(tc, index1, index2); + + // verify that reopen() does not return a new reader instance + // in case the index has no changes + ReaderCouple couple = refreshReader(tc, index2, false); + CuAssertTrue(tc, couple.refreshedReader == index2); + + couple = refreshReader(tc, index2, test, 0, true); + index1 = couple.newReader; + IndexReader* index2_refreshed = couple.refreshedReader; + index2->close(); + assertReaderClosed(tc, index2, true, true); + if ( index2_refreshed != index2 ){ + _CLDELETE(index2); + } + + // test if refreshed reader and newly opened reader return equal results + TestAssertIndexReaderEquals(tc, index1, index2_refreshed); + + index1->close(); + _CLDELETE(index1); + index2_refreshed->close(); + assertReaderClosed(tc, index2_refreshed, true, true); + _CLDELETE(index2_refreshed); + + index2 = index2B; + + for (int i = 1; i < 4; i++) { + couple = refreshReader(tc, index2, test, i, true); + // refresh IndexReader + index2->close(); + if ( couple.refreshedReader != index2 ){ + _CLDELETE(index2); + } + + index2 = couple.refreshedReader; + index1 = couple.newReader; + TestAssertIndexReaderEquals(tc, index1, index2); + index1->close(); + assertReaderClosed(tc, index1, true, true); + _CLDELETE(index1); + } + + index2->close(); + assertReaderClosed(tc, index2, true, true); + _CLDELETE(index2); +} + + + +void testIndexReaderReopen(CuTest *tc){ + RAMDirectory dir; + createIndex(tc, &dir, false); + IndexReader* index1 = IndexReader::open(&dir); + IndexReader* index2 = IndexReader::open(&dir); + IndexReader* index2B = IndexReader::open(&dir); + + defaultModifyIndexTestDir1 = &dir; + performDefaultIRTests(tc, index1, index2, index2B, defaultModifyIndexTest); + defaultModifyIndexTestDir1 = NULL; + + index1->close(); + _CLDELETE(index1); + //_CLDELETE(index2);this one gets deleted... + //_CLDELETE(index2B); +} + + +void testMultiReaderReopen(CuTest *tc){ + RAMDirectory dir1; + createIndex(tc, &dir1, true); + RAMDirectory dir2 ; + createIndex(tc, &dir2, true); + + ValueArray readers1(2); + readers1[0] = IndexReader::open(&dir1); + readers1[1] = IndexReader::open(&dir2); + IndexReader* index1 = _CLNEW MultiReader(&readers1, true); + + ValueArray readers2(2); + readers2[0] = IndexReader::open(&dir1); + readers2[1] = IndexReader::open(&dir2); + IndexReader* index2 = _CLNEW MultiReader(&readers2, true); + + ValueArray readers2b(2); + readers2b[0] = IndexReader::open(&dir1); + readers2b[1] = IndexReader::open(&dir2); + IndexReader* index2b = _CLNEW MultiReader(&readers2b, true); + + defaultModifyIndexTestDir1 = &dir1; + defaultModifyIndexTestDir2 = &dir2; + performDefaultIRTests(tc, index1, index2, index2b, defaultModifyIndexTestMulti); + defaultModifyIndexTestDir1 = NULL; + defaultModifyIndexTestDir2 = NULL; + + _CLDELETE(index1); + //_CLDELETE(index2);this one gets deleted... + //_CLDELETE(index2B); +} + +CuSuite *testindexreader(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene IndexReader Test")); + SUITE_ADD_TEST(suite, testIndexReaderReopen); + SUITE_ADD_TEST(suite, testMultiReaderReopen); + + return suite; +} +// EOF diff --git a/src/test/index/TestIndexWriter.cpp b/src/test/index/TestIndexWriter.cpp new file mode 100644 index 00000000000..81c80870a81 --- /dev/null +++ b/src/test/index/TestIndexWriter.cpp @@ -0,0 +1,668 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include +#include + +//checks if a merged index finds phrases correctly +void testIWmergePhraseSegments(CuTest *tc){ + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir, CL_MAX_PATH, "%s/%s",cl_tempDir, "test.indexwriter"); + SimpleAnalyzer a; + Directory* dir = FSDirectory::getDirectory(fsdir); + + IndexWriter ndx2(dir,&a,true); + ndx2.setUseCompoundFile(false); + Document doc0; + doc0.add( + *_CLNEW Field( + _T("field0"), + _T("value0 value1"), + Field::STORE_YES | Field::INDEX_TOKENIZED + ) + ); + ndx2.addDocument(&doc0); + ndx2.optimize(); + ndx2.close(); + + IndexWriter ndx(fsdir,&a,false); + ndx.setUseCompoundFile(false); + Document doc1; + doc1.add( + *_CLNEW Field( + _T("field0"), + _T("value1 value0"), + Field::STORE_YES | Field::INDEX_TOKENIZED + ) + ); + ndx.addDocument(&doc1); + ndx.optimize(); + ndx.close(); + + //test the index querying + IndexSearcher searcher(fsdir); + Query* query0 = QueryParser::parse( + _T("\"value0 value1\""), + _T("field0"), + &a + ); + Hits* hits0 = searcher.search(query0); + CLUCENE_ASSERT(hits0->length() > 0); + Query* query1 = QueryParser::parse( + _T("\"value1 value0\""), + _T("field0"), + &a + ); + Hits* hits1 = searcher.search(query1); + CLUCENE_ASSERT(hits1->length() > 0); + _CLDELETE(query0); + _CLDELETE(query1); + _CLDELETE(hits0); + _CLDELETE(hits1); + _CLDECDELETE(dir); +} + +//checks that adding more than the min_merge value goes ok... +//checks for a mem leak that used to occur +void testIWmergeSegments1(CuTest *tc){ + RAMDirectory ram; + SimpleAnalyzer a; + + IndexWriter ndx2(&ram,&a,true); + ndx2.close(); //test immediate closing bug reported + + IndexWriter ndx(&ram,&a,true); //set create to false + + ndx.setUseCompoundFile(false); + ndx.setMergeFactor(2); + TCHAR fld[1000]; + for ( int i=0;i<1000;i++ ){ + English::IntToEnglish(i,fld,1000); + + Document doc; + + doc.add ( *_CLNEW Field(_T("field0"),fld,Field::STORE_YES | Field::INDEX_TOKENIZED) ); + doc.add ( *_CLNEW Field(_T("field1"),fld,Field::STORE_YES | Field::INDEX_TOKENIZED) ); + doc.add ( *_CLNEW Field(_T("field2"),fld,Field::STORE_YES | Field::INDEX_TOKENIZED) ); + doc.add ( *_CLNEW Field(_T("field3"),fld,Field::STORE_YES | Field::INDEX_TOKENIZED) ); + ndx.addDocument(&doc); + } + //ndx.optimize(); //optimize so we can read terminfosreader with segmentreader + ndx.close(); + + //test the ram loading + RAMDirectory ram2(&ram); + IndexReader* reader2 = IndexReader::open(&ram2); + Term* term = _CLNEW Term(_T("field0"),fld); + TermEnum* en = reader2->terms(term); + CLUCENE_ASSERT(en->next()); + _CLDELETE(en); + _CLDECDELETE(term); + _CLDELETE(reader2); +} + +//checks if appending to an index works correctly +void testIWmergeSegments2(CuTest *tc){ + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir, CL_MAX_PATH, "%s/%s",cl_tempDir, "test.indexwriter"); + SimpleAnalyzer a; + Directory* dir = FSDirectory::getDirectory(fsdir); + + IndexWriter ndx2(dir,&a,true); + ndx2.setUseCompoundFile(false); + Document doc0; + doc0.add( + *_CLNEW Field( + _T("field0"), + _T("value0"), + Field::STORE_YES | Field::INDEX_TOKENIZED + ) + ); + ndx2.addDocument(&doc0); + ndx2.optimize(); + ndx2.close(); + + IndexWriter ndx(fsdir,&a,false); + ndx.setUseCompoundFile(false); + Document doc1; + doc1.add( + *_CLNEW Field( + _T("field0"), + _T("value1"), + Field::STORE_YES | Field::INDEX_TOKENIZED + ) + ); + ndx.addDocument(&doc1); + ndx.optimize(); + ndx.close(); + + //test the ram querying + IndexSearcher searcher(fsdir); + Term* term0 = _CLNEW Term(_T("field0"),_T("value1")); + Query* query0 = QueryParser::parse(_T("value0"),_T("field0"),&a); + Hits* hits0 = searcher.search(query0); + CLUCENE_ASSERT(hits0->length() > 0); + Term* term1 = _CLNEW Term(_T("field0"),_T("value0")); + Query* query1 = QueryParser::parse(_T("value1"),_T("field0"),&a); + Hits* hits1 = searcher.search(query1); + CLUCENE_ASSERT(hits1->length() > 0); + _CLDELETE(query0); + _CLDELETE(query1); + _CLDELETE(hits0); + _CLDELETE(hits1); + _CLDECDELETE(term0); + _CLDECDELETE(term1); + dir->close(); + _CLDECDELETE(dir); +} + +void testAddIndexes(CuTest *tc){ + char reuters_origdirectory[1024]; + strcpy(reuters_origdirectory, clucene_data_location); + strcat(reuters_origdirectory, "/reuters-21578-index"); + + { + RAMDirectory dir; + WhitespaceAnalyzer a; + IndexWriter w(&dir, &a, true); + ValueArray dirs(2); + dirs[0] = FSDirectory::getDirectory(reuters_origdirectory); + dirs[1] = FSDirectory::getDirectory(reuters_origdirectory); + w.addIndexesNoOptimize(dirs); + w.flush(); + CLUCENE_ASSERT(w.docCount()==62); //31 docs in reuters... + + // TODO: Currently there is a double ref-counting mechanism in place for Directory objects, + // so we need to dec them both + dirs[1]->close();_CLDECDELETE(dirs[1]); + dirs[0]->close();_CLDECDELETE(dirs[0]); + } + { + RAMDirectory dir; + WhitespaceAnalyzer a; + IndexWriter w(&dir, &a, true); + ValueArray dirs(2); + dirs[0] = FSDirectory::getDirectory(reuters_origdirectory); + dirs[1] = FSDirectory::getDirectory(reuters_origdirectory); + w.addIndexes(dirs); + w.flush(); + CLUCENE_ASSERT(w.docCount()==62); //31 docs in reuters... + + // TODO: Currently there is a double ref-counting mechanism in place for Directory objects, + // so we need to dec them both + dirs[1]->close();_CLDECDELETE(dirs[1]); + dirs[0]->close();_CLDECDELETE(dirs[0]); + } +} + +void testHashingBug(CuTest* /*tc*/){ + //Manuel Freiholz's indexing bug + + CL_NS(document)::Document doc; + CL_NS(document)::Field* field; + CL_NS(analysis::standard)::StandardAnalyzer analyzer; + CL_NS(store)::RAMDirectory dir; + CL_NS(index)::IndexWriter writer(&dir, &analyzer, true, true ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VERSION"), _T("1"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_PID"), _T("5"), CL_NS(document)::Field::STORE_YES | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_DATE"), _T("20090722"), CL_NS(document)::Field::STORE_YES | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_SEARCHDATA"), _T("all kind of data"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_TOKENIZED ); + doc.add( (*field) ); + + writer.addDocument( &doc ); // ADDING FIRST DOCUMENT. -> this works! + + doc.clear(); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VERSION"), _T("1"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_PID"), _T("5"), CL_NS(document)::Field::STORE_YES | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_LINEID"), _T("20"), CL_NS(document)::Field::STORE_YES | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VT_ORDER"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_H"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_HF"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_D"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_OD"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_P1"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); + + field = _CLNEW CL_NS(document)::Field( _T("CNS_VN_H1"), _T("456033000"), CL_NS(document)::Field::STORE_NO | CL_NS(document)::Field::INDEX_UNTOKENIZED ); + doc.add( (*field) ); // the problematic field! + + writer.addDocument( &doc ); // ADDING SECOND DOCUMENT - will never return from this function + writer.optimize(); // stucks in line 222-223 + writer.close(); + _CL_LDECREF(&dir); +} + +class IWlargeScaleCorrectness_tester { +public: + void invoke(Directory& storage, CuTest *tc); +}; + +void IWlargeScaleCorrectness_tester::invoke( + Directory& storage, + CuTest *tc +){ + SimpleAnalyzer a; + + IndexWriter* ndx = _CLNEW IndexWriter(&storage,&a,true); + + ndx->setUseCompoundFile(false); + + const long documents = 200; + const long step = 23; + const long inverted_step = 113; + const long repetitions = 5; + + CLUCENE_ASSERT(0 == (step * inverted_step + 1) % documents); + + long value0; + long value1 = 0; + + long block_size = 1; + long reopen = 1; + + for (value0 = 0; value0 < documents * repetitions; value0++) { + if (reopen == value0) { + ndx->optimize(); + ndx->close(); + _CLDELETE(ndx); + ndx = _CLNEW IndexWriter(&storage,&a,false); + ndx->setUseCompoundFile(false); + reopen += block_size; + block_size++; + } + + TCHAR* value0_string = NumberTools::longToString(value0 % documents); + TCHAR* value1_string = NumberTools::longToString(value1); + + Document doc; + + doc.add ( + *_CLNEW Field( + _T("field0"), + value0_string, + Field::STORE_YES | Field::INDEX_UNTOKENIZED + ) + ); + doc.add ( + *_CLNEW Field( + _T("field1"), + value1_string, + Field::STORE_YES | Field::INDEX_UNTOKENIZED + ) + ); + ndx->addDocument(&doc); + + _CLDELETE_ARRAY(value0_string); + _CLDELETE_ARRAY(value1_string); + value1 = (value1 + step) % documents; + } + + ndx->optimize(); + ndx->close(); + + IndexSearcher searcher(&storage); + Query* query0 = _CLNEW MatchAllDocsQuery; + Sort by_value1( + _CLNEW SortField( + _T("field1"), + SortField::STRING, + true + ) + ); + Hits* hits0 = searcher.search(query0, &by_value1); + long last = 0; + for (long i = 0; i < hits0->length(); i++) { + Document& retrieved = hits0->doc(i); + TCHAR const* value = retrieved.get(_T("field0")); + long current = NumberTools::stringToLong(value); + long delta = (current + documents - last) % documents; + if (0 == (i % repetitions)) { + CLUCENE_ASSERT(inverted_step == delta); + } else { + CLUCENE_ASSERT(0 == delta); + } + last = current; + } + _CLDELETE(query0); + _CLDELETE(hits0); + _CLDELETE(ndx); +} + +void testIWlargeScaleCorrectness(CuTest *tc){ + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir,CL_MAX_PATH,"%s/%s",cl_tempDir, "test.search"); + RAMDirectory ram; + FSDirectory* disk = FSDirectory::getDirectory(fsdir); + IWlargeScaleCorrectness_tester().invoke(ram, tc); + IWlargeScaleCorrectness_tester().invoke(*disk, tc); + disk->close(); + _CLDECDELETE(disk); +} + +void testExceptionFromTokenStream(CuTest *tc) { + + class TokenFilterWithException : public TokenFilter + { + private: + int count; + + public: + TokenFilterWithException(TokenStream * in) : + TokenFilter(in, true), count(0) {}; + + Token* next(Token * pToken) { + if (count++ == 5) { + _CLTHROWA(CL_ERR_IO, "TokenFilterWithException testing IO exception"); + } + return input->next(pToken); + }; + }; + + class AnalyzerWithException : public Analyzer + { + TokenStream* lastStream; + public: + AnalyzerWithException() { lastStream = NULL; } + virtual ~AnalyzerWithException() { _CLDELETE( lastStream ); } + TokenStream* tokenStream(const TCHAR * fieldName, Reader * reader) { + return _CLNEW TokenFilterWithException(_CLNEW WhitespaceTokenizer(reader)); + }; + + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) + { + _CLDELETE( lastStream ); + lastStream = _CLNEW TokenFilterWithException(_CLNEW WhitespaceTokenizer(reader)); + return lastStream; + } + }; + + RAMDirectory * dir = _CLNEW RAMDirectory(); + AnalyzerWithException a; + IndexWriter * writer = _CLNEW IndexWriter(dir, &a, true); + + Document* doc = _CLNEW Document(); + doc->add(* _CLNEW Field(_T("content"), _T("aa bb cc dd ee ff gg hh ii"), + Field::STORE_NO | Field::INDEX_TOKENIZED)); + try { + writer->addDocument(doc); + CuFail(tc, _T("did not hit expected exception")); + } catch (CLuceneError&) { + } + _CLLDELETE(doc); + + // Make sure we can add another normal document + doc = _CLNEW Document(); + doc->add(* _CLNEW Field(_T("content"), _T("aa bb cc dd"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + + // Make sure we can add another normal document + doc = _CLNEW Document(); + doc->add(* _CLNEW Field(_T("content"), _T("aa bb cc dd"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + + writer->close(); + _CLLDELETE(writer); + + IndexReader* reader = IndexReader::open(dir); + Term* t = _CLNEW Term(_T("content"), _T("aa")); + assertEquals(reader->docFreq(t), 3); + + // Make sure the doc that hit the exception was marked + // as deleted: + TermDocs* tdocs = reader->termDocs(t); + int count = 0; + while(tdocs->next()) { + count++; + } + _CLLDELETE(tdocs); + assertEquals(2, count); + + t->set(_T("content"), _T("gg")); + assertEquals(reader->docFreq(t), 0); + _CLDECDELETE(t); + + reader->close(); + _CLLDELETE(reader); + + dir->close(); + _CLDECDELETE(dir); +} + +/** +* Make sure we skip wicked long terms. +*/ +void testWickedLongTerm(CuTest *tc) { + RAMDirectory* dir = _CLNEW RAMDirectory(); + StandardAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter(dir, &a, true); + + TCHAR bigTerm[16383]; + for (int i=0; i<16383; i++) + bigTerm[i]=_T('x'); + bigTerm[16382] = 0; + + Document* doc = _CLNEW Document(); + + // Max length term is 16383, so this contents produces + // a too-long term: + TCHAR* contents = _CL_NEWARRAY(TCHAR, 17000); + _tcscpy(contents, _T("abc xyz x")); + _tcscat(contents, bigTerm); + _tcscat(contents, _T(" another term")); + doc->add(* _CLNEW Field(_T("content"), contents, Field::STORE_NO | Field::INDEX_TOKENIZED)); + _CLDELETE_CARRAY(contents); + writer->addDocument(doc); + _CLLDELETE(doc); + + // Make sure we can add another normal document + doc = _CLNEW Document(); + doc->add(* _CLNEW Field(_T("content"), _T("abc bbb ccc"), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + writer->close(); + _CLDELETE(writer); + + IndexReader* reader = IndexReader::open(dir); + + // Make sure all terms < max size were indexed + Term* t = _CLNEW Term(_T("content"), _T("abc"), true); + assertEquals(2, reader->docFreq(t)); + t->set(_T("content"), _T("bbb"), true); + assertEquals(1, reader->docFreq(t)); + t->set(_T("content"), _T("term"), true); + assertEquals(1, reader->docFreq(t)); + t->set(_T("content"), _T("another"), true); + assertEquals(1, reader->docFreq(t)); + + // Make sure position is still incremented when + // massive term is skipped: + t->set(_T("content"), _T("another"), true); + TermPositions* tps = reader->termPositions(t); + assertTrue(tps->next()); + assertEquals(1, tps->freq()); + assertEquals(3, tps->nextPosition()); + _CLLDELETE(tps); + + // Make sure the doc that has the massive term is in + // the index: + assertEqualsMsg(_T("document with wicked long term should is not in the index!"), 1, reader->numDocs()); + + reader->close(); + _CLLDELETE(reader); + + // Make sure we can add a document with exactly the + // maximum length term, and search on that term: + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("content"), bigTerm, Field::STORE_NO | Field::INDEX_TOKENIZED)); + StandardAnalyzer sa; + sa.setMaxTokenLength(100000); + writer = _CLNEW IndexWriter(dir, &sa, true); + writer->addDocument(doc); + _CLLDELETE(doc); + writer->close(); + reader = IndexReader::open(dir); + t->set(_T("content"), bigTerm); + assertEquals(1, reader->docFreq(t)); + reader->close(); + + _CLDECDELETE(t); + + _CLLDELETE(writer); + _CLLDELETE(reader); + + dir->close(); + _CLDECDELETE(dir); +} + + +void testDeleteDocument(CuTest* tc) { + const int size = 205; + RAMDirectory* dir = _CLNEW RAMDirectory(); + StandardAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter(dir, &a, true); + + // build an index that is big enough that a deletion files is written + // in the DGaps format + for (int i = 0; i < size; i++) { + Document* doc = _CLNEW Document(); + TCHAR* contents = _CL_NEWARRAY(TCHAR, (size / 10) + 1); + _i64tot(i, contents, 10); + doc->add(* _CLNEW Field(_T("content"), contents, Field::STORE_NO | Field::INDEX_TOKENIZED)); + _CLDELETE_CARRAY(contents); + writer->addDocument(doc); + _CLDELETE_ARRAY( contents ); + _CLLDELETE(doc); + } + + // assure that the index has only one segment + writer->optimize(); + // close and flush index + writer->close(); + _CLLDELETE( writer ); + + // reopen the index and delete the document next to last + writer = _CLNEW IndexWriter(dir, &a, false); + TCHAR* contents = _CL_NEWARRAY(TCHAR, (size / 10) + 1); + _i64tot(size - 2, contents, 10); + Term* t = _CLNEW Term(_T("content"), contents); + _CLDELETE_LARRAY( contents ); + writer->deleteDocuments(t); + writer->close(); + + // now the index has a deletion file in the DGaps format + + _CLLDELETE(writer); + _CLDECDELETE(t); + + // open this index with a searcher to read the deletions file again + IndexReader* reader = IndexReader::open(dir); + IndexSearcher* searcher = _CLNEW IndexSearcher(reader); + searcher->close(); + reader->close(); + _CLLDELETE(searcher); + _CLLDELETE(reader); + + dir->close(); + _CLLDELETE( dir ); +} + +void testMergeIndex(CuTest* tc) { + + // A crash depends on the following: + // - The first document needs two differently named fields that set TERMVECTOR_YES. + // - The IndexWriter needs to reopen an existing index. + // - The reopened IndexWriter needs to call optimize() to force a merge + // on term vectors. This merging causes the crash. + // Submitted by McCann + + RAMDirectory* dir = _CLNEW RAMDirectory(); + + // open a new lucene index + SimpleAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter( dir, false, &a, true ); + writer->setUseCompoundFile( false ); + + // add two fields to document + Document* doc = _CLNEW Document(); + doc->add ( *_CLNEW Field(_T("field0"), _T("value0"), Field::STORE_NO | Field::TERMVECTOR_YES | Field::INDEX_TOKENIZED) ); + doc->add ( *_CLNEW Field(_T("field1"), _T("value1"), Field::STORE_NO | Field::TERMVECTOR_YES | Field::INDEX_TOKENIZED) ); + writer->addDocument(doc); + _CLLDELETE(doc); + + // close and flush index + writer->close(); + _CLLDELETE( writer ); + + // open the previous lucene index + writer = _CLNEW IndexWriter( dir, false, &a, false ); + writer->setUseCompoundFile( false ); + + // add a field to document + // note: the settings on this field don't seem to affect the crash + doc = _CLNEW Document(); + doc->add ( *_CLNEW Field(_T("field"), _T("value"), Field::STORE_NO | Field::TERMVECTOR_YES | Field::INDEX_TOKENIZED) ); + writer->addDocument(doc); + _CLLDELETE(doc); + + // optimize index to force a merge + writer->optimize(); + // close and flush index + writer->close(); + _CLLDELETE( writer ); + + // Close directory + dir->close(); + _CLLDELETE( dir ); +} + +CuSuite *testindexwriter(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene IndexWriter Test")); + SUITE_ADD_TEST(suite, testHashingBug); + SUITE_ADD_TEST(suite, testAddIndexes); + SUITE_ADD_TEST(suite, testIWmergeSegments1); + SUITE_ADD_TEST(suite, testIWmergeSegments2); + SUITE_ADD_TEST(suite, testIWmergePhraseSegments); + SUITE_ADD_TEST(suite, testIWlargeScaleCorrectness); + + // TODO: This test fails due to differences between CLucene's StandardTokenizer and JLucene's; this test + // should work when the tokenizer will be brought up-to-date, + //SUITE_ADD_TEST(suite, testWickedLongTerm); + + SUITE_ADD_TEST(suite, testExceptionFromTokenStream); + SUITE_ADD_TEST(suite, testDeleteDocument); + SUITE_ADD_TEST(suite, testMergeIndex); + + return suite; +} +// EOF diff --git a/src/test/index/TestReuters.cpp b/src/test/index/TestReuters.cpp new file mode 100644 index 00000000000..a1f57dc532c --- /dev/null +++ b/src/test/index/TestReuters.cpp @@ -0,0 +1,234 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/util/dirent.h" +#include "CLucene/util/CLStreams.h" +#include "CLucene/LuceneThreads.h" +#include "CLucene/search/Explanation.h" +CL_NS_USE(search) + +#ifdef _CL_HAVE_SYS_STAT_H +#include +#endif +#include +#include +using namespace std; + +CL_NS_USE(util) + + //an extremelly simple analyser. this eliminates differences + //caused by differences in character classifications functions + class ReutersTokenizer:public CharTokenizer { + public: + // Construct a new LetterTokenizer. + ReutersTokenizer(CL_NS(util)::Reader* in): + CharTokenizer(in) {} + + ~ReutersTokenizer(){} + protected: + bool isTokenChar(const TCHAR c) const{ + if ( c == ' ' || c == '\t' || + c == '-' || c == '.' || + c == '\n' || c == '\r' || + c == ',' || c == '<' || + c == '>' || c<=9){ + return false; + }else + return true; + } + TCHAR normalize(const TCHAR c) const{ + return c; + } + }; + + class ReutersAnalyzer: public Analyzer { + public: + TokenStream* tokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader){ + return _CLNEW ReutersTokenizer(reader); + } + TokenStream* reusableTokenStream(const TCHAR* fieldName, CL_NS(util)::Reader* reader) + { + Tokenizer* tokenizer = static_cast(getPreviousTokenStream()); + if (tokenizer == NULL) { + tokenizer = _CLNEW ReutersTokenizer(reader); + setPreviousTokenStream(tokenizer); + } else + tokenizer->reset(reader); + return tokenizer; + } + virtual ~ReutersAnalyzer(){} + }; + + bool stringLowercaseCompare( const string &left, const string &right ){ + for( string::const_iterator lit = left.begin(), rit = right.begin(); lit != left.end() && rit != right.end(); ++lit, ++rit ) + if( tolower( *lit ) < tolower( *rit ) ) + return true; + else if( tolower( *lit ) > tolower( *rit ) ) + return false; + if( left.size() < right.size() ) + return true; + return false; + } + + + + +char reuters_fsdirectory[CL_MAX_PATH]; +bool reuters_ready = false; + +char reuters_srcdirectory[1024]; +char reuters_origdirectory[1024]; + +//indexes the reuters-21578 data. +void testReuters(CuTest *tc) { + strcpy(reuters_srcdirectory, clucene_data_location); + strcat(reuters_srcdirectory, "/reuters-21578"); + CuAssert(tc,_T("Data does not exist"),Misc::dir_Exists(reuters_srcdirectory)); + + strcpy(reuters_origdirectory, clucene_data_location); + strcat(reuters_origdirectory, "/reuters-21578-index"); + CuAssert(tc,_T("Index does not exist"),Misc::dir_Exists(reuters_origdirectory)); + + FSDirectory* fsdir = FSDirectory::getDirectory(reuters_fsdirectory); + ReutersAnalyzer a; + + IndexWriter writer(fsdir,&a,true); + writer.setUseCompoundFile(false); + //NOTE: when comparing against indexes created <~= 1.9, there was always 1 more field + //added then the actual limit... + writer.setMaxFieldLength(10001); + + vector files; + CuAssertTrue(tc, Misc::listFiles(reuters_srcdirectory, files,false)); + sort(files.begin(), files.end(), stringLowercaseCompare); + + char tmppath[CL_MAX_DIR]; + strncpy(tmppath,reuters_srcdirectory,CL_MAX_DIR); + strcat(tmppath,"/"); + char* tmppathP = tmppath + strlen(tmppath); + TCHAR tpath[CL_MAX_PATH]; + struct cl_stat_t buf; + + vector::iterator fl = files.begin(); + while ( fl != files.end() ){ + strcpy(tmppathP,fl->c_str()); + STRCPY_AtoT(tpath,fl->c_str(),CL_MAX_PATH); + fileStat(tmppath,&buf); + if ( buf.st_mode & S_IFREG){ + Document* doc = _CLNEW Document; + doc->add(*_CLNEW Field(_T("path"),tpath,Field::INDEX_UNTOKENIZED | Field::STORE_YES)); + doc->add(*_CLNEW Field(_T("contents"), _CLNEW FileReader(tmppath, "ASCII"),Field::INDEX_TOKENIZED)); + + writer.addDocument( doc ); + _CLDELETE(doc); + + } + fl++; + } + + writer.close(); + fsdir->close(); + _CLDECDELETE(fsdir); + + //note: for those comparing 0.9.16 to later, the optimize() has been removed so + //we can do certain tests with the multi-* classes (reader,etc) + //performance will naturally be worse + + reuters_ready = true; +} + +void testBySection(CuTest* tc){ + IndexReader* reader1 = IndexReader::open(reuters_origdirectory); + IndexReader* reader2 = IndexReader::open(reuters_fsdirectory); + + TestAssertIndexReaderEquals(tc,reader1,reader2); + reader1->close(); + reader2->close(); + _CLDELETE(reader1); + _CLDELETE(reader2); +} + +#define threadsCount 10 + +void threadSearch(IndexSearcher* searcher, const TCHAR* qry, StandardAnalyzer* threadAnalyzer){ + Query* q = NULL; + Hits* h = NULL; + try{ + q = QueryParser::parse(qry , _T("contents"), threadAnalyzer); + if ( q != NULL ){ + h = searcher->search( q ); + + if ( h->length() > 0 ){ + //check for explanation memory leaks... + CL_NS(search)::Explanation expl1; + searcher->explain(q, h->id(0), &expl1); + TCHAR* tmp = expl1.toString(); + _CLDELETE_CARRAY(tmp); + if ( h->length() > 1 ){ //do a second one just in case + CL_NS(search)::Explanation expl2; + searcher->explain(q, h->id(1), &expl2); + tmp = expl2.toString(); + _CLDELETE_CARRAY(tmp); + } + } + } + }_CLFINALLY( + _CLDELETE(h); + _CLDELETE(q); + ); +} +_LUCENE_THREAD_FUNC(threadedSearcherTest, arg){ + IndexSearcher* searcher = (IndexSearcher*)(((void**)arg)[0]); + StandardAnalyzer* threadAnalyzer = (StandardAnalyzer*)(((void**)arg)[1]); + + for ( int i=0;i<100;i++ ){ + threadSearch(searcher, _T("test"), threadAnalyzer ); + threadSearch(searcher, _T("reuters"), threadAnalyzer ); + threadSearch(searcher, _T("data"), threadAnalyzer ); + } + _LUCENE_THREAD_FUNC_RETURN(0); +} + +void testThreaded(CuTest* tc){ + CLUCENE_ASSERT(reuters_ready); + IndexSearcher searcher(reuters_origdirectory); + + //read using multiple threads... + _LUCENE_THREADID_TYPE threads[threadsCount]; + + int i; + StandardAnalyzer threadAnalyzer; + void* args[2]; + args[0] = &searcher; + args[1] = &threadAnalyzer; + + for ( i=0;i +#include + +CL_NS_USE(analysis); +CL_NS_USE(index); +CL_NS_USE(util); + + //Must be lexicographically sorted, will do in setup, versus trying to maintain here + const TCHAR* testFields_values[] = {_T("f1"), _T("f2"), _T("f3"), _T("f4")}; + const bool testFieldsStorePos_values[] = {true, false, true, false}; + const bool testFieldsStoreOff_values[] = {true, false, false, true}; + const TCHAR* testTerms_values[] = {_T("this"), _T("is"), _T("a"), _T("test")}; + + CL_NS(store)::MockRAMDirectory dir; + std::string seg; + FieldInfos *fieldInfos = NULL; + const int TERM_FREQ = 3; + + struct TestToken { + const TCHAR* text; + int pos; + int startOffset; + int endOffset; + }; + + std::vector testFields(testFields_values, testFields_values + sizeof(testFields_values) / sizeof(TCHAR*)); + std::vector testTerms(testTerms_values, testTerms_values + sizeof(testTerms_values) / sizeof(TCHAR*)); + std::vector testFieldsStorePos(testFieldsStorePos_values, testFieldsStorePos_values + sizeof(testFieldsStorePos_values) / sizeof(bool)); + std::vector testFieldsStoreOff(testFieldsStoreOff_values, testFieldsStoreOff_values + sizeof(testFieldsStoreOff_values) / sizeof(bool)); + std::vector tokens; + std::vector< std::vector > positions(4); + std::vector< std::vector > offsets(4); + + class MyTokenStream : public TokenStream { + private: + std::vector::size_type tokenUpto; + public: + MyTokenStream() : + tokenUpto(0) + { + } + virtual Token* next(Token *token) { + if (tokenUpto >= tokens.size()) + return NULL; + else { + if (token == NULL) { + token = _CLNEW Token(); + } + const TestToken* testToken = tokens[tokenUpto++]; + token->setText(testToken->text, _tcslen(testToken->text)); + if (tokenUpto > 1) + token->setPositionIncrement(testToken->pos - tokens[tokenUpto-2]->pos); + else + token->setPositionIncrement(testToken->pos+1); + token->setStartOffset(testToken->startOffset); + token->setEndOffset(testToken->endOffset); + return token; + } + } + virtual void close() { + } + }; + + class MyAnalyzer : public CL_NS(analysis)::Analyzer { + public: + virtual TokenStream* tokenStream(const TCHAR* fieldName, Reader* reader) { + return _CLNEW MyTokenStream(); + } + }; + + class MyIndexWriter : public IndexWriter { + public: + MyIndexWriter(CL_NS(store)::Directory* d, CL_NS(analysis)::Analyzer* a, const bool create) : + IndexWriter(d, a, create) { + } + virtual SegmentInfo* newestSegment() { + return IndexWriter::newestSegment(); + } + }; + + struct MyTCharCompare : + public std::binary_function + { + bool operator () (const TCHAR* v1, const TCHAR* v2) const { + return _tcscmp(v1, v2) < 0; + } + }; + + struct TestTokenCompare : + public std::binary_function + { + bool operator () (const TestToken* t1, const TestToken* t2) const { + return t1->pos < t2->pos; + } + }; + + void setUp() { + + tokens.clear(); + std::sort(testTerms.begin(), testTerms.end(), MyTCharCompare()); + int tokenUpto = 0; + for (std::vector::size_type i = 0; i < testTerms.size(); i++) { + positions[i] = std::vector(TERM_FREQ); + offsets[i] = std::vector(TERM_FREQ); + // first position must be 0 + for (int j = 0; j < TERM_FREQ; j++) { + // positions are always sorted in increasing order + positions[i][j] = (int) (j * 10 + (rand() % 10)); + // offsets are always sorted in increasing order + offsets[i][j] = _CLNEW TermVectorOffsetInfo(j * 10, j * 10 + _tcslen(testTerms[i])); + TestToken* token = _CLNEW TestToken(); + tokens.push_back(token); + tokenUpto++; + token->text = testTerms[i]; + token->pos = positions[i][j]; + token->startOffset = offsets[i][j]->getStartOffset(); + token->endOffset = offsets[i][j]->getEndOffset(); + } + } + + std::sort(tokens.begin(), tokens.end(), TestTokenCompare()); + + MyAnalyzer analyzer; + MyIndexWriter writer(&dir, &analyzer, true); + writer.setUseCompoundFile(false); + Document* doc = _CLNEW Document(); + for(std::vector::size_type i=0;iadd(* _CLNEW Field(testFields[i], _T(""), Field::STORE_NO | Field::INDEX_TOKENIZED | tv)); + } + + //Create 5 documents for testing, they all have the same + //terms + for(int j=0;j<5;j++) + writer.addDocument(doc); + _CLLDELETE(doc); + writer.flush(); + seg = writer.newestSegment()->name; + writer.close(); + + std::string tmp = seg; + tmp.append("."); + tmp.append(IndexFileNames::FIELD_INFOS_EXTENSION); + fieldInfos = _CLNEW FieldInfos(&dir, tmp.c_str()); + } + + + void test(CuTest* tc) { + //Check to see the files were created properly in setup + std::string tmp = seg; + tmp.append("."); + tmp.append(IndexFileNames::VECTORS_DOCUMENTS_EXTENSION); + CuAssertTrue(tc, dir.fileExists(tmp.c_str()), _T("Missing file!")); + + tmp = seg; + tmp.append("."); + tmp.append(IndexFileNames::VECTORS_INDEX_EXTENSION); + CuAssertTrue(tc, dir.fileExists(tmp.c_str()), _T("Missing file!")); + } + + void testTermVectorsReader(CuTest* tc) { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + for (int j = 0; j < 5; j++) { + TermFreqVector* vector = reader.get(j, testFields[0]); + CuAssertTrue(tc, vector != NULL, _T("Expected term frequency vector!")); + const ArrayBase* terms = vector->getTerms(); + CuAssertTrue(tc, terms != NULL, _T("Array of terms expected!")); + CuAssertTrue(tc, terms->length == testTerms.size()); + for (int i = 0; i < terms->length; i++) { + const TCHAR* term = (*terms)[i]; + CuAssertStrEquals(tc, _T(""), testTerms[i], (TCHAR*)term, false); + } + } + } + + void testPositionReader(CuTest* tc) { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + TermPositionVector* vector; + const ArrayBase* terms; + vector = dynamic_cast(reader.get(0, testFields[0])); + CuAssertTrue(tc, vector != NULL, _T("Term position vector expected!")); + terms = vector->getTerms(); + CuAssertTrue(tc, terms != NULL, _T("Terms expected!")); + CuAssertTrue(tc, terms->length == testTerms.size(), _T("Unexpected number of terms!")); + for (int i = 0; i < terms->length; i++) { + const TCHAR* term = (*terms)[i]; + CuAssertStrEquals(tc, _T(""), testTerms[i], (TCHAR*)term, false); + const ArrayBase* termPositions = vector->getTermPositions(i); + CuAssertTrue(tc, termPositions != NULL, _T("Term positions expected!")); + CuAssertTrue(tc, termPositions->length == positions[i].size(), _T("Unexpected number of term positions!")); + for (int j = 0; j < termPositions->length; j++) { + int position = (*termPositions)[j]; + CuAssertTrue(tc, position == positions[i][j], _T("Postion not equal!")); + } + const ArrayBase* termOffset = vector->getOffsets(i); + CuAssertTrue(tc, termOffset != NULL, _T("Term vector offset info expected!")); + CuAssertTrue(tc, termOffset->length == offsets[i].size(), _T("Unexpected length of term positions!")); + for (int j = 0; j < termOffset->length; j++) { + TermVectorOffsetInfo* termVectorOffsetInfo = (*termOffset)[j]; + CuAssertTrue(tc, termVectorOffsetInfo->equals(offsets[i][j]), _T("Term vector offset info not equal!")); + } + } + + TermFreqVector* freqVector = reader.get(0, testFields[1]); //no pos, no offset + CuAssertTrue(tc, freqVector != NULL, _T("Term frequency vector expected!")); + CuAssertTrue(tc, dynamic_cast(freqVector) == NULL, _T("Unepexcted term position vector!")); + terms = freqVector->getTerms(); + CuAssertTrue(tc, terms != NULL, _T("Terms expected!")); + CuAssertTrue(tc, terms->length == testTerms.size(), _T("Unexpected length of term positions!")); + for (int i = 0; i < terms->length; i++) { + const TCHAR* term = (*terms)[i]; + CuAssertStrEquals(tc, _T(""), testTerms[i], (TCHAR*)term, false); + } + } + + class DocNumAwareMapper : public TermVectorMapper { + private: + + int documentNumber; + + public: + + DocNumAwareMapper() : documentNumber(-1) { + } + + virtual ~DocNumAwareMapper() { + } + + virtual void setExpectations(const TCHAR* _field, const int32_t numTerms, const bool storeOffsets, const bool storePositions) { + if (documentNumber == -1) { + _CLTHROWA(CL_ERR_Runtime, "Documentnumber should be set at this point!"); + } + } + + virtual void map(const TCHAR* term, const int32_t termLen, const int32_t frequency, CL_NS(util)::ArrayBase* offsets, CL_NS(util)::ArrayBase* positions) { + if (documentNumber == -1) { + _CLTHROWA(CL_ERR_Runtime, "Documentnumber should be set at this point!"); + } + } + + int getDocumentNumber() const { + return documentNumber; + } + + virtual void setDocumentNumber(const int32_t documentNumber) { + this->documentNumber = documentNumber; + } + }; + + void testOffsetReader(CuTest* tc) { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + TermPositionVector* vector = dynamic_cast(reader.get(0, testFields[0])); + CuAssertTrue(tc, vector != NULL, _T("Term position vector expected!")); + const CL_NS(util)::ArrayBase* terms = vector->getTerms(); + CuAssertTrue(tc, terms != NULL, _T("Terms expected")); + CuAssertTrue(tc, terms->length == testTerms.size(), _T("Unexpected number of terms!")); + for (int i = 0; i < terms->length; i++) { + const TCHAR* term = (*terms)[i]; + CuAssertStrEquals(tc, _T(""), testTerms[i], (TCHAR*)term, false); + const ArrayBase* termPositions = vector->getTermPositions(i); + CuAssertTrue(tc, termPositions != NULL, _T("Term positions expected!")); + CuAssertTrue(tc, termPositions->length == positions[i].size()); + for (int j = 0; j < termPositions->length; j++) { + int position = (*termPositions)[j]; + CuAssertTrue(tc, position == positions[i][j], _T("Unexpected position!")); + } + const ArrayBase* termOffset = vector->getOffsets(i); + CuAssertTrue(tc, termOffset != NULL, _T("Term vector offset info expected!")); + CuAssertTrue(tc, termOffset->length == offsets[i].size(), _T("Unexpected number of term positions!")); + for (int j = 0; j < termOffset->length; j++) { + TermVectorOffsetInfo* termVectorOffsetInfo = (*termOffset)[j]; + CuAssertTrue(tc, termVectorOffsetInfo->equals(offsets[i][j]), _T("Term vector offset info not equal!")); + } + } + } + + //void testMapper(CuTest* tc) { + // TermVectorsReader reader(&dir, seg, fieldInfos); + // SortedTermVectorMapper mapper = new SortedTermVectorMapper(new TermVectorEntryFreqSortedComparator()); + // reader.get(0, mapper); + // SortedSet set = mapper.getTermVectorEntrySet(); + // CuAssertTrue(tc, set != NULL, "set is null and it shouldn't be"); + // //three fields, 4 terms, all terms are the same + // CuAssertTrue(set.size() == 4, _T("set Size: " + set.size() + " is not: 4"); + // //Check offsets and positions + // for (Iterator iterator = set.iterator(); iterator.hasNext();) { + // TermVectorEntry* tve = (TermVectorEntry) iterator.next(); + // CuAssertTrue(tc, tve != NULL, _T("tve is null and it shouldn't be")); + // CuAssertTrue(tc, tve->getOffsets() != NULL, _T("tve.getOffsets() is null and it shouldn't be")); + // CuAssertTrue(tc, tve->getPositions() != NULL, _T("tve.getPositions() is null and it shouldn't be")); + // } + + // mapper = new SortedTermVectorMapper(new TermVectorEntryFreqSortedComparator()); + // reader.get(1, mapper); + // set = mapper.getTermVectorEntrySet(); + // assertTrue("set is null and it shouldn't be", set != null); + // //three fields, 4 terms, all terms are the same + // assertTrue("set Size: " + set.size() + " is not: " + 4, set.size() == 4); + // //Should have offsets and positions b/c we are munging all the fields together + // for (Iterator iterator = set.iterator(); iterator.hasNext();) { + // TermVectorEntry tve = (TermVectorEntry) iterator.next(); + // assertTrue("tve is null and it shouldn't be", tve != null); + // assertTrue("tve.getOffsets() is null and it shouldn't be", tve.getOffsets() != null); + // assertTrue("tve.getPositions() is null and it shouldn't be", tve.getPositions() != null); + + // } + + + // FieldSortedTermVectorMapper fsMapper = new FieldSortedTermVectorMapper(new TermVectorEntryFreqSortedComparator()); + // reader.get(0, fsMapper); + // Map map = fsMapper.getFieldToTerms(); + // assertTrue("map Size: " + map.size() + " is not: " + testFields.length, map.size() == testFields.length); + // for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + // Map.Entry entry = (Map.Entry) iterator.next(); + // SortedSet sortedSet = (SortedSet) entry.getValue(); + // assertTrue("sortedSet Size: " + sortedSet.size() + " is not: " + 4, sortedSet.size() == 4); + // for (Iterator inner = sortedSet.iterator(); inner.hasNext();) { + // TermVectorEntry tve = (TermVectorEntry) inner.next(); + // assertTrue("tve is null and it shouldn't be", tve != null); + // //Check offsets and positions. + // assertTrue("tve is null and it shouldn't be", tve != null); + // String field = tve.getField(); + // if (field.equals(testFields[0])) { + // //should have offsets + + // assertTrue("tve.getOffsets() is null and it shouldn't be", tve.getOffsets() != null); + // assertTrue("tve.getPositions() is null and it shouldn't be", tve.getPositions() != null); + // } + // else if (field.equals(testFields[1])) { + // //should not have offsets + + // assertTrue("tve.getOffsets() is not null and it shouldn't be", tve.getOffsets() == null); + // assertTrue("tve.getPositions() is not null and it shouldn't be", tve.getPositions() == null); + // } + // } + // } + // //Try mapper that ignores offs and positions + // fsMapper = new FieldSortedTermVectorMapper(true, true, new TermVectorEntryFreqSortedComparator()); + // reader.get(0, fsMapper); + // map = fsMapper.getFieldToTerms(); + // assertTrue("map Size: " + map.size() + " is not: " + testFields.length, map.size() == testFields.length); + // for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + // Map.Entry entry = (Map.Entry) iterator.next(); + // SortedSet sortedSet = (SortedSet) entry.getValue(); + // assertTrue("sortedSet Size: " + sortedSet.size() + " is not: " + 4, sortedSet.size() == 4); + // for (Iterator inner = sortedSet.iterator(); inner.hasNext();) { + // TermVectorEntry tve = (TermVectorEntry) inner.next(); + // assertTrue("tve is null and it shouldn't be", tve != null); + // //Check offsets and positions. + // assertTrue("tve is null and it shouldn't be", tve != null); + // String field = tve.getField(); + // if (field.equals(testFields[0])) { + // //should have offsets + + // assertTrue("tve.getOffsets() is null and it shouldn't be", tve.getOffsets() == null); + // assertTrue("tve.getPositions() is null and it shouldn't be", tve.getPositions() == null); + // } + // else if (field.equals(testFields[1])) { + // //should not have offsets + + // assertTrue("tve.getOffsets() is not null and it shouldn't be", tve.getOffsets() == null); + // assertTrue("tve.getPositions() is not null and it shouldn't be", tve.getPositions() == null); + // } + // } + // } + + // // test setDocumentNumber() + // IndexReader ir = IndexReader.open(&dir); + // DocNumAwareMapper docNumAwareMapper = new DocNumAwareMapper(); + // assertEquals(-1, docNumAwareMapper.getDocumentNumber()); + + // ir.getTermFreqVector(0, docNumAwareMapper); + // assertEquals(0, docNumAwareMapper.getDocumentNumber()); + // docNumAwareMapper.setDocumentNumber(-1); + + // ir.getTermFreqVector(1, docNumAwareMapper); + // assertEquals(1, docNumAwareMapper.getDocumentNumber()); + // docNumAwareMapper.setDocumentNumber(-1); + + // ir.getTermFreqVector(0, "f1", docNumAwareMapper); + // assertEquals(0, docNumAwareMapper.getDocumentNumber()); + // docNumAwareMapper.setDocumentNumber(-1); + + // ir.getTermFreqVector(1, "f2", docNumAwareMapper); + // assertEquals(1, docNumAwareMapper.getDocumentNumber()); + // docNumAwareMapper.setDocumentNumber(-1); + + // ir.getTermFreqVector(0, "f1", docNumAwareMapper); + // assertEquals(0, docNumAwareMapper.getDocumentNumber()); + + // ir.close(); + + //} + + /** + * Make sure exceptions and bad params are handled appropriately + */ + void testBadParams(CuTest* tc) { + try { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + //Bad document number, good field number + reader.get(50, testFields[0]); + CuFail(tc, _T("Expected an IO exception!")); + } catch (CLuceneError& e) { + if (e.number() != CL_ERR_IO) { + CuFail(tc, e.twhat()); + } + } + try { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + //Bad document number, no field + reader.get(50); + CuFail(tc, _T("")); + } catch (CLuceneError& e) { + if (e.number() != CL_ERR_IO) { + CuFail(tc, e.twhat()); + } + } + try { + TermVectorsReader reader(&dir, seg.c_str(), fieldInfos); + //good document number, bad field number + TermFreqVector* vector = reader.get(0, _T("f50")); + CuAssertTrue(tc, vector == NULL, _T("")); + } catch (CLuceneError& e) { + CuFail(tc, e.twhat()); + } + } + + +CuSuite *testTermVectorsReader(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene TermVectorsReader Test")); + + setUp(); + + SUITE_ADD_TEST(suite, test); + SUITE_ADD_TEST(suite, testTermVectorsReader); + SUITE_ADD_TEST(suite, testPositionReader); + SUITE_ADD_TEST(suite, testOffsetReader); + //SUITE_ADD_TEST(suite, testMapper); + SUITE_ADD_TEST(suite, testBadParams); + + return suite; +} diff --git a/src/test/index/TestThreading.cpp b/src/test/index/TestThreading.cpp new file mode 100644 index 00000000000..88013da52af --- /dev/null +++ b/src/test/index/TestThreading.cpp @@ -0,0 +1,161 @@ +/*------------------------------------------------------------------------------ + * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team + * + * Distributable under the terms of either the Apache License (Version 2.0) or + * the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include +#include "CLucene/index/_SegmentHeader.h" +#include "CLucene/index/_MultiSegmentReader.h" +#include "CLucene/index/MultiReader.h" +#include + + +_LUCENE_THREADID_TYPE* atomicSearchThreads = NULL; +bool atomicSearchFailed = false; +#define ATOMIC_SEARCH_RUN_TIME_SEC 3 +_LUCENE_THREAD_FUNC(atomicIndexTest, _writer){ + IndexWriter* writer= (IndexWriter*)_writer; + uint64_t stopTime = Misc::currentTimeMillis() + 1000*ATOMIC_SEARCH_RUN_TIME_SEC; + int count = 0; + try { + while(Misc::currentTimeMillis() < stopTime && !atomicSearchFailed) { + // Update all 100 docs... + TCHAR buf[30]; + StringBuffer sb; + for(int i=0; i<100; i++) { + Document d; + _i64tot(rand(), buf, 10); + + sb.clear(); + English::IntToEnglish(i+10*count, &sb); + d.add(*_CLNEW Field(_T("contents"), sb.getBuffer() , Field::STORE_NO | Field::INDEX_TOKENIZED)); + + _i64tot(i,buf,10); + d.add(*_CLNEW Field(_T("id"), buf, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + Term* t = _CLNEW Term(_T("id"), buf); + writer->updateDocument(t, &d); + _CLDECDELETE(t); + } + + count++; + } + } catch (CLuceneError& e) { + fprintf(stderr, "err 1: #%d: %s\n", e.number(), e.what()); + atomicSearchFailed = true; + } + + _LUCENE_THREAD_FUNC_RETURN(0); +} + +_LUCENE_THREAD_FUNC(atomicSearchTest, _directory){ + Directory* directory = (Directory*)_directory; + + uint64_t stopTime = Misc::currentTimeMillis() + 1000*ATOMIC_SEARCH_RUN_TIME_SEC; + int count = 0; + try { + while(Misc::currentTimeMillis() < stopTime && !atomicSearchFailed) { + IndexReader* r = IndexReader::open(directory); + + try { + if ( 100 != r->numDocs() ){ + fprintf(stderr, "err 2: 100 != %d \n", r->numDocs()); + atomicSearchFailed = true; + } + } catch (CLuceneError& e) { + fprintf(stderr, "err 3: %d:%s\n", e.number(), e.what()); + atomicSearchFailed = true; + break; + } + r->close(); + _CLDELETE(r); + + count++; + } + } catch (CLuceneError& e) { + fprintf(stderr, "err 4: #%d: %s\n", e.number(), e.what()); + atomicSearchFailed = true; + } + + _LUCENE_THREAD_FUNC_RETURN(0); +} + +/* + Run one indexer and 2 searchers against single index as + stress test. + */ +void runThreadingTests(CuTest* tc, Directory& directory){ + + SimpleAnalyzer ANALYZER; + IndexWriter writer(&directory, &ANALYZER, true); + + // Establish a base index of 100 docs: + StringBuffer sb; + TCHAR buf[10]; + for(int i=0;i<100;i++) { + Document d; + _i64tot(i,buf,10); + d.add(*_CLNEW Field(_T("id"), buf, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + + sb.clear(); + English::IntToEnglish(i, &sb); + d.add(*_CLNEW Field(_T("contents"), sb.getBuffer(), Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer.addDocument(&d); + } + writer.flush(); + + //read using multiple threads... + atomicSearchThreads = _CL_NEWARRAY(_LUCENE_THREADID_TYPE, 4); + atomicSearchThreads[0] = _LUCENE_THREAD_CREATE(&atomicIndexTest, &writer); + atomicSearchThreads[1] = _LUCENE_THREAD_CREATE(&atomicIndexTest, &writer); + atomicSearchThreads[2] = _LUCENE_THREAD_CREATE(&atomicSearchTest, &directory); + atomicSearchThreads[3] = _LUCENE_THREAD_CREATE(&atomicSearchTest, &directory); + + for ( int i=0;i<4;i++ ){ + _LUCENE_THREAD_JOIN(atomicSearchThreads[i]); + } + _CLDELETE_ARRAY(atomicSearchThreads); + + writer.close(); + + CuAssert(tc, _T("hit unexpected exception in one of the threads\n"), !atomicSearchFailed); +} + +/* + Run above stress test against RAMDirectory and then + FSDirectory. + */ +void testRAMThreading(CuTest *tc){ + // First in a RAM directory: + RAMDirectory directory; //todo: use MockRAMDirectory? + runThreadingTests(tc,directory); + directory.close(); +} + +/* + Run above stress test against FSDirectory. + */ +void testFSThreading(CuTest *tc){ + //setup some variables + char tmpfsdirectory[1024]; + strcpy(tmpfsdirectory,cl_tempDir); + strcat(tmpfsdirectory,"/threading-index"); + + // Second in an FSDirectory: + Directory* directory = FSDirectory::getDirectory(tmpfsdirectory); + runThreadingTests(tc,*directory); + directory->close(); + _CLDECDELETE(directory); +} + +CuSuite *testatomicupdates(void) +{ + srand ( (unsigned int)Misc::currentTimeMillis() ); + CuSuite *suite = CuSuiteNew(_T("CLucene Atomic Updates Test")); + SUITE_ADD_TEST(suite, testRAMThreading); + SUITE_ADD_TEST(suite, testFSThreading); + + return suite; +} +// EOF diff --git a/src/test/index/TestUtf8.cpp b/src/test/index/TestUtf8.cpp new file mode 100644 index 00000000000..20a71f68378 --- /dev/null +++ b/src/test/index/TestUtf8.cpp @@ -0,0 +1,189 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/util/dirent.h" +#include "CLucene/util/CLStreams.h" + +CL_NS_USE(util) + +#ifdef _UCS2 + void _Index(CuTest *tc, IndexWriter* ndx, const char* file){ + char path[CL_MAX_PATH]; + TCHAR tlang[20]; + + strcpy(path,clucene_data_location); + strcat(path,"/utf8text"); + CuAssert(tc,_T("Utf8 directory does not exist"),Misc::dir_Exists(path)); + strcat(path,"/"); + strcat(path,file); + strcat(path,"_utf8.txt"); + CuAssert(tc,_T("Language file does not exist"),Misc::dir_Exists(path)); + + STRCPY_AtoT(tlang,file,CL_MAX_PATH); + + Document doc; + doc.add(* _CLNEW Field(_T("language"),tlang,Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + + doc.add(* _CLNEW Field(_T("contents"),_CLNEW FileReader(path, "UTF-8",1024), Field::INDEX_TOKENIZED)); + + ndx->addDocument(&doc); + } + void _Search(CuTest *tc, IndexSearcher* srch, Analyzer* analyzer, const char* file, const char* query){ + TCHAR tlang[20]; + STRCPY_AtoT(tlang,file,CL_MAX_PATH); + + TCHAR tquery[80]; + lucene_utf8towcs(tquery,query,80); + + Query* q = QueryParser::parse(tquery,_T("contents"), analyzer); + Hits* h = srch->search(q); + CLUCENE_ASSERT( h->length() == 1 ); + + Document& doc = h->doc(0); + CLUCENE_ASSERT( _tcscmp(doc.get(_T("language")), tlang)==0 ); + + _CLDELETE(q); + _CLDELETE(h); + } + + void testUTF8(CuTest *tc) { + RAMDirectory ram; + StandardAnalyzer a; + IndexWriter ndx(&ram,&a,true); + _Index(tc, &ndx,"arabic"); + _Index(tc, &ndx,"chinese"); + _Index(tc, &ndx,"czech"); + _Index(tc, &ndx,"english"); + _Index(tc, &ndx,"french"); + _Index(tc, &ndx,"german"); + _Index(tc, &ndx,"greek"); + _Index(tc, &ndx,"hebrew"); + _Index(tc, &ndx,"japanese"); + _Index(tc, &ndx,"korean"); + _Index(tc, &ndx,"polish"); + _Index(tc, &ndx,"russian"); + ndx.close(); + + IndexSearcher srch(&ram); + _Search(tc,&srch,&a,"arabic", "\xef\xbb\x9e\xef\xbb\xb4\xef\xbb\xa4\xef\xbb\xb3\xef\xba\xad"); //????? - arabic + _Search(tc,&srch,&a,"chinese", "\xe5\x95\xa4\xe9\x85\x92"); //?? - chinese + _Search(tc,&srch,&a,"czech", "Bud\xc4\x9bjovick\xc3\xbd" ); //Budejovick� - czech + + _Search(tc,&srch,&a,"english", "google"); //English - google + _Search(tc,&srch,&a,"french", "r\xc3\xa9put\xc3\xa9"); //r�put� - french + _Search(tc,&srch,&a,"german", "k\xc3\xb6nnen"); //k�nnen - german + _Search(tc,&srch,&a,"greek", "\xcf\x83\xcf\x84\xce\xb5\xce\xaf\xce\xbb\xcf\x84\xce\xb5"); //ste??te - greek + _Search(tc,&srch,&a,"hebrew", "\xd7\x91\xd7\x90\xd7\xa8\xd7\xa6\xd7\x95\xd7\xaa" ); //?????? - hebrew + _Search(tc,&srch,&a,"japanese", "\xe8\xa6\x8b\xe5\xad\xa6" ); //?? - japanese + _Search(tc,&srch,&a,"korean", "\xea\xb8\x88" ); //? - korean + _Search(tc,&srch,&a,"polish", "sp\xc3\xb3\xc5\x82ka"); ;//sp�lka - polish + _Search(tc,&srch,&a,"russian", "\xd0\x92\xd0\xb5\xd0\xbb\xd0\xb8\xd0\xba\xd0\xb8\xd0\xb5\x20"); //??????? - russian + + srch.close(); + } + + void readBuffered(CuTest* tc, Reader& utf8, Reader& unicode, int readLen){ + const TCHAR* buf1; + const TCHAR* buf2; + int32_t s; + size_t p, p1, p2; + p = p1 = p2 = 0; + while(true){ + s = utf8.read((const void**)&buf1, 1, readLen); + if ( s == -1 ) + break; + p1+=s; + + s = unicode.read((const void**)&buf2, 1, readLen); + if (s == -1) + break; + p2+=s; + + CLUCENE_ASSERT(p1==p2); //make sure both readers read the same amount. todo: i guess this is not strictly required... + for ( int32_t i=0;i. +// SPDX-License-Identifier: MIT +// Copyright (c) 2019-2022 Martin Ankerl +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef ANKERL_NANOBENCH_H_INCLUDED +#define ANKERL_NANOBENCH_H_INCLUDED + +// see https://semver.org/ +#define ANKERL_NANOBENCH_VERSION_MAJOR 4 // incompatible API changes +#define ANKERL_NANOBENCH_VERSION_MINOR 3 // backwards-compatible changes +#define ANKERL_NANOBENCH_VERSION_PATCH 7 // backwards-compatible bug fixes + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// public facing api - as minimal as possible +/////////////////////////////////////////////////////////////////////////////////////////////////// + +#include // high_resolution_clock +#include // memcpy +#include // for std::ostream* custom output target in Config +#include // all names +#include // holds all results + +#define ANKERL_NANOBENCH(x) ANKERL_NANOBENCH_PRIVATE_##x() + +#define ANKERL_NANOBENCH_PRIVATE_CXX() __cplusplus +#define ANKERL_NANOBENCH_PRIVATE_CXX98() 199711L +#define ANKERL_NANOBENCH_PRIVATE_CXX11() 201103L +#define ANKERL_NANOBENCH_PRIVATE_CXX14() 201402L +#define ANKERL_NANOBENCH_PRIVATE_CXX17() 201703L + +#if ANKERL_NANOBENCH(CXX) >= ANKERL_NANOBENCH(CXX17) +# define ANKERL_NANOBENCH_PRIVATE_NODISCARD() [[nodiscard]] +#else +# define ANKERL_NANOBENCH_PRIVATE_NODISCARD() +#endif + +#if defined(__clang__) +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_PUSH() \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wpadded\"") +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_POP() _Pragma("clang diagnostic pop") +#else +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_PUSH() +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_PADDED_POP() +#endif + +#if defined(__GNUC__) +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_PUSH() _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Weffc++\"") +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_POP() _Pragma("GCC diagnostic pop") +#else +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_PUSH() +# define ANKERL_NANOBENCH_PRIVATE_IGNORE_EFFCPP_POP() +#endif + +#if defined(ANKERL_NANOBENCH_LOG_ENABLED) +# include +# define ANKERL_NANOBENCH_LOG(x) \ + do { \ + std::cout << __FUNCTION__ << "@" << __LINE__ << ": " << x << std::endl; \ + } while (0) +#else +# define ANKERL_NANOBENCH_LOG(x) \ + do { \ + } while (0) +#endif + +#define ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS() 0 +#if defined(__linux__) && !defined(ANKERL_NANOBENCH_DISABLE_PERF_COUNTERS) +# include +# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) +// PERF_COUNT_HW_REF_CPU_CYCLES only available since kernel 3.3 +// PERF_FLAG_FD_CLOEXEC since kernel 3.14 +# undef ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS +# define ANKERL_NANOBENCH_PRIVATE_PERF_COUNTERS() 1 +# endif +#endif + +#if defined(__clang__) +# define ANKERL_NANOBENCH_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__))) +#else +# define ANKERL_NANOBENCH_NO_SANITIZE(...) +#endif + +#if defined(_MSC_VER) +# define ANKERL_NANOBENCH_PRIVATE_NOINLINE() __declspec(noinline) +#else +# define ANKERL_NANOBENCH_PRIVATE_NOINLINE() __attribute__((noinline)) +#endif + +// workaround missing "is_trivially_copyable" in g++ < 5.0 +// See https://stackoverflow.com/a/31798726/48181 +#if defined(__GNUC__) && __GNUC__ < 5 +# define ANKERL_NANOBENCH_IS_TRIVIALLY_COPYABLE(...) __has_trivial_copy(__VA_ARGS__) +#else +# define ANKERL_NANOBENCH_IS_TRIVIALLY_COPYABLE(...) std::is_trivially_copyable<__VA_ARGS__>::value +#endif + +// declarations /////////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + + using Clock = std::conditional::type; + class Bench; + struct Config; + class Result; + class Rng; + class BigO; + + /** + * @brief Renders output from a mustache-like template and benchmark results. + * + * The templating facility here is heavily inspired by [mustache - logic-less templates](https://mustache.github.io/). + * It adds a few more features that are necessary to get all of the captured data out of nanobench. Please read the + * excellent [mustache manual](https://mustache.github.io/mustache.5.html) to see what this is all about. + * + * nanobench output has two nested layers, *result* and *measurement*. Here is a hierarchy of the allowed tags: + * + * * `{{#result}}` Marks the begin of the result layer. Whatever comes after this will be instantiated as often as + * a benchmark result is available. Within it, you can use these tags: + * + * * `{{title}}` See Bench::title(). + * + * * `{{name}}` Benchmark name, usually directly provided with Bench::run(), but can also be set with Bench::name(). + * + * * `{{unit}}` Unit, e.g. `byte`. Defaults to `op`, see Bench::title(). + * + * * `{{batch}}` Batch size, see Bench::batch(). + * + * * `{{complexityN}}` Value used for asymptotic complexity calculation. See Bench::complexityN(). + * + * * `{{epochs}}` Number of epochs, see Bench::epochs(). + * + * * `{{clockResolution}}` Accuracy of the clock, i.e. what's the smallest time possible to measure with the clock. + * For modern systems, this can be around 20 ns. This value is automatically determined by nanobench at the first + * benchmark that is run, and used as a static variable throughout the application's runtime. + * + * * `{{clockResolutionMultiple}}` Configuration multiplier for `clockResolution`. See Bench::clockResolutionMultiple(). + * This is the target runtime for each measurement (epoch). That means the more accurate your clock is, the faster + * will be the benchmark. Basing the measurement's runtime on the clock resolution is the main reason why nanobench is so fast. + * + * * `{{maxEpochTime}}` Configuration for a maximum time each measurement (epoch) is allowed to take. Note that at least + * a single iteration will be performed, even when that takes longer than maxEpochTime. See Bench::maxEpochTime(). + * + * * `{{minEpochTime}}` Minimum epoch time, defaults to 1ms. See Bench::minEpochTime(). + * + * * `{{minEpochIterations}}` See Bench::minEpochIterations(). + * + * * `{{epochIterations}}` See Bench::epochIterations(). + * + * * `{{warmup}}` Number of iterations used before measuring starts. See Bench::warmup(). + * + * * `{{relative}}` True or false, depending on the setting you have used. See Bench::relative(). + * + * Apart from these tags, it is also possible to use some mathematical operations on the measurement data. The operations + * are of the form `{{command(name)}}`. Currently `name` can be one of `elapsed`, `iterations`. If performance counters + * are available (currently only on current Linux systems), you also have `pagefaults`, `cpucycles`, + * `contextswitches`, `instructions`, `branchinstructions`, and `branchmisses`. All the measuers (except `iterations`) are + * provided for a single iteration (so `elapsed` is the time a single iteration took). The following tags are available: + * + * * `{{median()}}` Calculate median of a measurement data set, e.g. `{{median(elapsed)}}`. + * + * * `{{average()}}` Average (mean) calculation. + * + * * `{{medianAbsolutePercentError()}}` Calculates MdAPE, the Median Absolute Percentage Error. The MdAPE is an excellent + * metric for the variation of measurements. It is more robust to outliers than the + * [Mean absolute percentage error (M-APE)](https://en.wikipedia.org/wiki/Mean_absolute_percentage_error). + * @f[ + * \mathrm{MdAPE}(e) = \mathrm{med}\{| \frac{e_i - \mathrm{med}\{e\}}{e_i}| \} + * @f] + * E.g. for *elapsed*: First, @f$ \mathrm{med}\{e\} @f$ calculates the median by sorting and then taking the middle element + * of all *elapsed* measurements. This is used to calculate the absolute percentage + * error to this median for each measurement, as in @f$ | \frac{e_i - \mathrm{med}\{e\}}{e_i}| @f$. All these results + * are sorted, and the middle value is chosen as the median absolute percent error. + * + * This measurement is a bit hard to interpret, but it is very robust against outliers. E.g. a value of 5% means that half of the + * measurements deviate less than 5% from the median, and the other deviate more than 5% from the median. + * + * * `{{sum()}}` Sums of all the measurements. E.g. `{{sum(iterations)}}` will give you the total number of iterations +* measured in this benchmark. + * + * * `{{minimum()}}` Minimum of all measurements. + * + * * `{{maximum()}}` Maximum of all measurements. + * + * * `{{sumProduct(, )}}` Calculates the sum of the products of corresponding measures: + * @f[ + * \mathrm{sumProduct}(a,b) = \sum_{i=1}^{n}a_i\cdot b_i + * @f] + * E.g. to calculate total runtime of the benchmark, you multiply iterations with elapsed time for each measurement, and + * sum these results up: + * `{{sumProduct(iterations, elapsed)}}`. + * + * * `{{#measurement}}` To access individual measurement results, open the begin tag for measurements. + * + * * `{{elapsed}}` Average elapsed wall clock time per iteration, in seconds. + * + * * `{{iterations}}` Number of iterations in the measurement. The number of iterations will fluctuate due + * to some applied randomness, to enhance accuracy. + * + * * `{{pagefaults}}` Average number of pagefaults per iteration. + * + * * `{{cpucycles}}` Average number of CPU cycles processed per iteration. + * + * * `{{contextswitches}}` Average number of context switches per iteration. + * + * * `{{instructions}}` Average number of retired instructions per iteration. + * + * * `{{branchinstructions}}` Average number of branches executed per iteration. + * + * * `{{branchmisses}}` Average number of branches that were missed per iteration. + * + * * `{{/measurement}}` Ends the measurement tag. + * + * * `{{/result}}` Marks the end of the result layer. This is the end marker for the template part that will be instantiated + * for each benchmark result. + * + * + * For the layer tags *result* and *measurement* you additionally can use these special markers: + * + * * ``{{#-first}}`` - Begin marker of a template that will be instantiated *only for the first* entry in the layer. Use is only + * allowed between the begin and end marker of the layer allowed. So between ``{{#result}}`` and ``{{/result}}``, or between + * ``{{#measurement}}`` and ``{{/measurement}}``. Finish the template with ``{{/-first}}``. + * + * * ``{{^-first}}`` - Begin marker of a template that will be instantiated *for each except the first* entry in the layer. This, + * this is basically the inversion of ``{{#-first}}``. Use is only allowed between the begin and end marker of the layer allowed. + * So between ``{{#result}}`` and ``{{/result}}``, or between ``{{#measurement}}`` and ``{{/measurement}}``. + * + * * ``{{/-first}}`` - End marker for either ``{{#-first}}`` or ``{{^-first}}``. + * + * * ``{{#-last}}`` - Begin marker of a template that will be instantiated *only for the last* entry in the layer. Use is only + * allowed between the begin and end marker of the layer allowed. So between ``{{#result}}`` and ``{{/result}}``, or between + * ``{{#measurement}}`` and ``{{/measurement}}``. Finish the template with ``{{/-last}}``. + * + * * ``{{^-last}}`` - Begin marker of a template that will be instantiated *for each except the last* entry in the layer. This, + * this is basically the inversion of ``{{#-last}}``. Use is only allowed between the begin and end marker of the layer allowed. + * So between ``{{#result}}`` and ``{{/result}}``, or between ``{{#measurement}}`` and ``{{/measurement}}``. + * + * * ``{{/-last}}`` - End marker for either ``{{#-last}}`` or ``{{^-last}}``. + * + @verbatim embed:rst + + For an overview of all the possible data you can get out of nanobench, please see the tutorial at :ref:`tutorial-template-json`. + + The templates that ship with nanobench are: + + * :cpp:func:`templates::csv() ` + * :cpp:func:`templates::json() ` + * :cpp:func:`templates::htmlBoxplot() ` + * :cpp:func:`templates::pyperf() ` + + @endverbatim + * + * @param mustacheTemplate The template. + * @param bench Benchmark, containing all the results. + * @param out Output for the generated output. + */ + void render(char const* mustacheTemplate, Bench const& bench, std::ostream& out); + void render(std::string const& mustacheTemplate, Bench const& bench, std::ostream& out); + + /** + * Same as render(char const* mustacheTemplate, Bench const& bench, std::ostream& out), but for when + * you only have results available. + * + * @param mustacheTemplate The template. + * @param results All the results to be used for rendering. + * @param out Output for the generated output. + */ + void render(char const* mustacheTemplate, std::vector const& results, std::ostream& out); + void render(std::string const& mustacheTemplate, std::vector const& results, std::ostream& out); + + // Contains mustache-like templates + namespace templates { + + /*! + @brief CSV data for the benchmark results. + + Generates a comma-separated values dataset. First line is the header, each following line is a summary of each benchmark run. + + @verbatim embed:rst + See the tutorial at :ref:`tutorial-template-csv` for an example. + @endverbatim + */ + char const* csv() noexcept; + + /*! + @brief HTML output that uses plotly to generate an interactive boxplot chart. See the tutorial for an example output. + + The output uses only the elapsed wall clock time, and displays each epoch as a single dot. + @verbatim embed:rst + See the tutorial at :ref:`tutorial-template-html` for an example. + @endverbatim + + @see ankerl::nanobench::render() + */ + char const* htmlBoxplot() noexcept; + + /*! + @brief Output in pyperf compatible JSON format, which can be used for more analyzation. + @verbatim embed:rst + See the tutorial at :ref:`tutorial-template-pyperf` for an example how to further analyze the output. + @endverbatim + */ + char const* pyperf() noexcept; + + /*! + @brief Template to generate JSON data. + + The generated JSON data contains *all* data that has been generated. All times are as double values, in seconds. The output can get + quite large. + @verbatim embed:rst + See the tutorial at :ref:`tutorial-template-json` for an example. + @endverbatim + */ + char const* json() noexcept; + + } // namespace templates + + namespace detail { + + template + struct PerfCountSet; + + class IterationLogic; + class PerformanceCounters; + +#if ANKERL_NANOBENCH(PERF_COUNTERS) + class LinuxPerformanceCounters; +#endif + + } // namespace detail + } // namespace nanobench +} // namespace ankerl + +// definitions //////////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + namespace detail { + + template + struct PerfCountSet { + T pageFaults{}; + T cpuCycles{}; + T contextSwitches{}; + T instructions{}; + T branchInstructions{}; + T branchMisses{}; + }; + + } // namespace detail + + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + struct Config { + // actual benchmark config + std::string mBenchmarkTitle = "benchmark"; + std::string mBenchmarkName = "noname"; + std::string mUnit = "op"; + double mBatch = 1.0; + double mComplexityN = -1.0; + size_t mNumEpochs = 11; + size_t mClockResolutionMultiple = static_cast(1000); + std::chrono::nanoseconds mMaxEpochTime = std::chrono::milliseconds(100); + std::chrono::nanoseconds mMinEpochTime = std::chrono::milliseconds(1); + uint64_t mMinEpochIterations{1}; + uint64_t mEpochIterations{0}; // If not 0, run *exactly* these number of iterations per epoch. + uint64_t mWarmup = 0; + std::ostream* mOut = nullptr; + std::chrono::duration mTimeUnit = std::chrono::nanoseconds{1}; + std::string mTimeUnitName = "ns"; + bool mShowPerformanceCounters = true; + bool mIsRelative = false; + + Config(); + ~Config(); + Config& operator=(Config const&); + Config& operator=(Config&&); + Config(Config const&); + Config(Config&&) noexcept; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + // Result returned after a benchmark has finished. Can be used as a baseline for relative(). + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class Result { + public: + enum class Measure : size_t { + elapsed, + iterations, + pagefaults, + cpucycles, + contextswitches, + instructions, + branchinstructions, + branchmisses, + _size + }; + + explicit Result(Config const& benchmarkConfig); + + ~Result(); + Result& operator=(Result const&); + Result& operator=(Result&&); + Result(Result const&); + Result(Result&&) noexcept; + + // adds new measurement results + // all values are scaled by iters (except iters...) + void add(Clock::duration totalElapsed, uint64_t iters, detail::PerformanceCounters const& pc); + + ANKERL_NANOBENCH(NODISCARD) Config const& config() const noexcept; + + ANKERL_NANOBENCH(NODISCARD) double median(Measure m) const; + ANKERL_NANOBENCH(NODISCARD) double medianAbsolutePercentError(Measure m) const; + ANKERL_NANOBENCH(NODISCARD) double average(Measure m) const; + ANKERL_NANOBENCH(NODISCARD) double sum(Measure m) const noexcept; + ANKERL_NANOBENCH(NODISCARD) double sumProduct(Measure m1, Measure m2) const noexcept; + ANKERL_NANOBENCH(NODISCARD) double minimum(Measure m) const noexcept; + ANKERL_NANOBENCH(NODISCARD) double maximum(Measure m) const noexcept; + + ANKERL_NANOBENCH(NODISCARD) bool has(Measure m) const noexcept; + ANKERL_NANOBENCH(NODISCARD) double get(size_t idx, Measure m) const; + ANKERL_NANOBENCH(NODISCARD) bool empty() const noexcept; + ANKERL_NANOBENCH(NODISCARD) size_t size() const noexcept; + + // Finds string, if not found, returns _size. + static Measure fromString(std::string const& str); + + private: + Config mConfig{}; + std::vector> mNameToMeasurements{}; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + /** + * An extremely fast random generator. Currently, this implements *RomuDuoJr*, developed by Mark Overton. Source: + * http://www.romu-random.org/ + * + * RomuDuoJr is extremely fast and provides reasonable good randomness. Not enough for large jobs, but definitely + * good enough for a benchmarking framework. + * + * * Estimated capacity: @f$ 2^{51} @f$ bytes + * * Register pressure: 4 + * * State size: 128 bits + * + * This random generator is a drop-in replacement for the generators supplied by ````. It is not + * cryptographically secure. It's intended purpose is to be very fast so that benchmarks that make use + * of randomness are not distorted too much by the random generator. + * + * Rng also provides a few non-standard helpers, optimized for speed. + */ + class Rng final { + public: + /** + * @brief This RNG provides 64bit randomness. + */ + using result_type = uint64_t; + + static constexpr uint64_t(min)(); + static constexpr uint64_t(max)(); + + /** + * As a safety precausion, we don't allow copying. Copying a PRNG would mean you would have two random generators that produce the + * same sequence, which is generally not what one wants. Instead create a new rng with the default constructor Rng(), which is + * automatically seeded from `std::random_device`. If you really need a copy, use copy(). + */ + Rng(Rng const&) = delete; + + /** + * Same as Rng(Rng const&), we don't allow assignment. If you need a new Rng create one with the default constructor Rng(). + */ + Rng& operator=(Rng const&) = delete; + + // moving is ok + Rng(Rng&&) noexcept = default; + Rng& operator=(Rng&&) noexcept = default; + ~Rng() noexcept = default; + + /** + * @brief Creates a new Random generator with random seed. + * + * Instead of a default seed (as the random generators from the STD), this properly seeds the random generator from + * `std::random_device`. It guarantees correct seeding. Note that seeding can be relatively slow, depending on the source of + * randomness used. So it is best to create a Rng once and use it for all your randomness purposes. + */ + Rng(); + + /*! + Creates a new Rng that is seeded with a specific seed. Each Rng created from the same seed will produce the same randomness + sequence. This can be useful for deterministic behavior. + + @verbatim embed:rst + .. note:: + + The random algorithm might change between nanobench releases. Whenever a faster and/or better random + generator becomes available, I will switch the implementation. + @endverbatim + + As per the Romu paper, this seeds the Rng with splitMix64 algorithm and performs 10 initial rounds for further mixing up of the + internal state. + + @param seed The 64bit seed. All values are allowed, even 0. + */ + explicit Rng(uint64_t seed) noexcept; + Rng(uint64_t x, uint64_t y) noexcept; + Rng(std::vector const& data); + + /** + * Creates a copy of the Rng, thus the copy provides exactly the same random sequence as the original. + */ + ANKERL_NANOBENCH(NODISCARD) Rng copy() const noexcept; + + /** + * @brief Produces a 64bit random value. This should be very fast, thus it is marked as inline. In my benchmark, this is ~46 times + * faster than `std::default_random_engine` for producing 64bit random values. It seems that the fastest std contender is + * `std::mt19937_64`. Still, this RNG is 2-3 times as fast. + * + * @return uint64_t The next 64 bit random value. + */ + inline uint64_t operator()() noexcept; + + // This is slightly biased. See + + /** + * Generates a random number between 0 and range (excluding range). + * + * The algorithm only produces 32bit numbers, and is slightly biased. The effect is quite small unless your range is close to the + * maximum value of an integer. It is possible to correct the bias with rejection sampling (see + * [here](https://lemire.me/blog/2016/06/30/fast-random-shuffling/), but this is most likely irrelevant in practices for the + * purposes of this Rng. + * + * See Daniel Lemire's blog post [A fast alternative to the modulo + * reduction](https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/) + * + * @param range Upper exclusive range. E.g a value of 3 will generate random numbers 0, 1, 2. + * @return uint32_t Generated random values in range [0, range(. + */ + inline uint32_t bounded(uint32_t range) noexcept; + + // random double in range [0, 1( + // see http://prng.di.unimi.it/ + + /** + * Provides a random uniform double value between 0 and 1. This uses the method described in [Generating uniform doubles in the + * unit interval](http://prng.di.unimi.it/), and is extremely fast. + * + * @return double Uniformly distributed double value in range [0,1(, excluding 1. + */ + inline double uniform01() noexcept; + + /** + * Shuffles all entries in the given container. Although this has a slight bias due to the implementation of bounded(), this is + * preferable to `std::shuffle` because it is over 5 times faster. See Daniel Lemire's blog post [Fast random + * shuffling](https://lemire.me/blog/2016/06/30/fast-random-shuffling/). + * + * @param container The whole container will be shuffled. + */ + template + void shuffle(Container& container) noexcept; + + /** + * Extracts the full state of the generator, e.g. for serialization. For this RNG this is just 2 values, but to stay API compatible + * with future implementations that potentially use more state, we use a vector. + * + * @return Vector containing the full state: + */ + std::vector state() const; + + private: + static constexpr uint64_t rotl(uint64_t x, unsigned k) noexcept; + + uint64_t mX; + uint64_t mY; + }; + + /** + * @brief Main entry point to nanobench's benchmarking facility. + * + * It holds configuration and results from one or more benchmark runs. Usually it is used in a single line, where the object is + * constructed, configured, and then a benchmark is run. E.g. like this: + * + * ankerl::nanobench::Bench().unit("byte").batch(1000).run("random fluctuations", [&] { + * // here be the benchmark code + * }); + * + * In that example Bench() constructs the benchmark, it is then configured with unit() and batch(), and after configuration a + * benchmark is executed with run(). Once run() has finished, it prints the result to `std::cout`. It would also store the results + * in the Bench instance, but in this case the object is immediately destroyed so it's not available any more. + */ + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class Bench { + public: + /** + * @brief Creates a new benchmark for configuration and running of benchmarks. + */ + Bench(); + + Bench(Bench&& other); + Bench& operator=(Bench&& other); + Bench(Bench const& other); + Bench& operator=(Bench const& other); + ~Bench() noexcept; + + /*! + @brief Repeatedly calls `op()` based on the configuration, and performs measurements. + + This call is marked with `noinline` to prevent the compiler to optimize beyond different benchmarks. This can have quite a big + effect on benchmark accuracy. + + @verbatim embed:rst + .. note:: + + Each call to your lambda must have a side effect that the compiler can't possibly optimize it away. E.g. add a result to an + externally defined number (like `x` in the above example), and finally call `doNotOptimizeAway` on the variables the compiler + must not remove. You can also use :cpp:func:`ankerl::nanobench::doNotOptimizeAway` directly in the lambda, but be aware that + this has a small overhead. + + @endverbatim + + @tparam Op The code to benchmark. + */ + template + ANKERL_NANOBENCH(NOINLINE) + Bench& run(char const* benchmarkName, Op&& op); + + template + ANKERL_NANOBENCH(NOINLINE) + Bench& run(std::string const& benchmarkName, Op&& op); + + /** + * @brief Same as run(char const* benchmarkName, Op op), but instead uses the previously set name. + * @tparam Op The code to benchmark. + */ + template + ANKERL_NANOBENCH(NOINLINE) + Bench& run(Op&& op); + + /** + * @brief Title of the benchmark, will be shown in the table header. Changing the title will start a new markdown table. + * + * @param benchmarkTitle The title of the benchmark. + */ + Bench& title(char const* benchmarkTitle); + Bench& title(std::string const& benchmarkTitle); + ANKERL_NANOBENCH(NODISCARD) std::string const& title() const noexcept; + + /// Name of the benchmark, will be shown in the table row. + Bench& name(char const* benchmarkName); + Bench& name(std::string const& benchmarkName); + ANKERL_NANOBENCH(NODISCARD) std::string const& name() const noexcept; + + /** + * @brief Sets the batch size. + * + * E.g. number of processed byte, or some other metric for the size of the processed data in each iteration. If you benchmark + * hashing of a 1000 byte long string and want byte/sec as a result, you can specify 1000 as the batch size. + * + * @tparam T Any input type is internally cast to `double`. + * @param b batch size + */ + template + Bench& batch(T b) noexcept; + ANKERL_NANOBENCH(NODISCARD) double batch() const noexcept; + + /** + * @brief Sets the operation unit. + * + * Defaults to "op". Could be e.g. "byte" for string processing. This is used for the table header, e.g. to show `ns/byte`. Use + * singular (*byte*, not *bytes*). A change clears the currently collected results. + * + * @param unit The unit name. + */ + Bench& unit(char const* unit); + Bench& unit(std::string const& unit); + ANKERL_NANOBENCH(NODISCARD) std::string const& unit() const noexcept; + + /** + * @brief Sets the time unit to be used for the default output. + * + * Nanobench defaults to using ns (nanoseconds) as output in the markdown. For some benchmarks this is too coarse, so it is + * possible to configure this. E.g. use `timeUnit(1ms, "ms")` to show `ms/op` instead of `ns/op`. + * + * @param tu Time unit to display the results in, default is 1ns. + * @param tuName Name for the time unit, default is "ns" + */ + Bench& timeUnit(std::chrono::duration const& tu, std::string const& tuName); + ANKERL_NANOBENCH(NODISCARD) std::string const& timeUnitName() const noexcept; + ANKERL_NANOBENCH(NODISCARD) std::chrono::duration const& timeUnit() const noexcept; + + /** + * @brief Set the output stream where the resulting markdown table will be printed to. + * + * The default is `&std::cout`. You can disable all output by setting `nullptr`. + * + * @param outstream Pointer to output stream, can be `nullptr`. + */ + Bench& output(std::ostream* outstream) noexcept; + ANKERL_NANOBENCH(NODISCARD) std::ostream* output() const noexcept; + + /** + * Modern processors have a very accurate clock, being able to measure as low as 20 nanoseconds. This is the main trick nanobech to + * be so fast: we find out how accurate the clock is, then run the benchmark only so often that the clock's accuracy is good enough + * for accurate measurements. + * + * The default is to run one epoch for 1000 times the clock resolution. So for 20ns resolution and 11 epochs, this gives a total + * runtime of + * + * @f[ + * 20ns * 1000 * 11 \approx 0.2ms + * @f] + * + * To be precise, nanobench adds a 0-20% random noise to each evaluation. This is to prevent any aliasing effects, and further + * improves accuracy. + * + * Total runtime will be higher though: Some initial time is needed to find out the target number of iterations for each epoch, and + * there is some overhead involved to start & stop timers and calculate resulting statistics and writing the output. + * + * @param multiple Target number of times of clock resolution. Usually 1000 is a good compromise between runtime and accuracy. + */ + Bench& clockResolutionMultiple(size_t multiple) noexcept; + ANKERL_NANOBENCH(NODISCARD) size_t clockResolutionMultiple() const noexcept; + + /** + * @brief Controls number of epochs, the number of measurements to perform. + * + * The reported result will be the median of evaluation of each epoch. The higher you choose this, the more + * deterministic the result be and outliers will be more easily removed. Also the `err%` will be more accurate the higher this + * number is. Note that the `err%` will not necessarily decrease when number of epochs is increased. But it will be a more accurate + * representation of the benchmarked code's runtime stability. + * + * Choose the value wisely. In practice, 11 has been shown to be a reasonable choice between runtime performance and accuracy. + * This setting goes hand in hand with minEpochIterations() (or minEpochTime()). If you are more interested in *median* runtime, + * you might want to increase epochs(). If you are more interested in *mean* runtime, you might want to increase + * minEpochIterations() instead. + * + * @param numEpochs Number of epochs. + */ + Bench& epochs(size_t numEpochs) noexcept; + ANKERL_NANOBENCH(NODISCARD) size_t epochs() const noexcept; + + /** + * @brief Upper limit for the runtime of each epoch. + * + * As a safety precausion if the clock is not very accurate, we can set an upper limit for the maximum evaluation time per + * epoch. Default is 100ms. At least a single evaluation of the benchmark is performed. + * + * @see minEpochTime(), minEpochIterations() + * + * @param t Maximum target runtime for a single epoch. + */ + Bench& maxEpochTime(std::chrono::nanoseconds t) noexcept; + ANKERL_NANOBENCH(NODISCARD) std::chrono::nanoseconds maxEpochTime() const noexcept; + + /** + * @brief Minimum time each epoch should take. + * + * Default is zero, so we are fully relying on clockResolutionMultiple(). In most cases this is exactly what you want. If you see + * that the evaluation is unreliable with a high `err%`, you can increase either minEpochTime() or minEpochIterations(). + * + * @see maxEpochTime(), minEpochIterations() + * + * @param t Minimum time each epoch should take. + */ + Bench& minEpochTime(std::chrono::nanoseconds t) noexcept; + ANKERL_NANOBENCH(NODISCARD) std::chrono::nanoseconds minEpochTime() const noexcept; + + /** + * @brief Sets the minimum number of iterations each epoch should take. + * + * Default is 1, and we rely on clockResolutionMultiple(). If the `err%` is high and you want a more smooth result, you might want + * to increase the minimum number or iterations, or increase the minEpochTime(). + * + * @see minEpochTime(), maxEpochTime(), minEpochIterations() + * + * @param numIters Minimum number of iterations per epoch. + */ + Bench& minEpochIterations(uint64_t numIters) noexcept; + ANKERL_NANOBENCH(NODISCARD) uint64_t minEpochIterations() const noexcept; + + /** + * Sets exactly the number of iterations for each epoch. Ignores all other epoch limits. This forces nanobench to use exactly + * the given number of iterations for each epoch, not more and not less. Default is 0 (disabled). + * + * @param numIters Exact number of iterations to use. Set to 0 to disable. + */ + Bench& epochIterations(uint64_t numIters) noexcept; + ANKERL_NANOBENCH(NODISCARD) uint64_t epochIterations() const noexcept; + + /** + * @brief Sets a number of iterations that are initially performed without any measurements. + * + * Some benchmarks need a few evaluations to warm up caches / database / whatever access. Normally this should not be needed, since + * we show the median result so initial outliers will be filtered away automatically. If the warmup effect is large though, you + * might want to set it. Default is 0. + * + * @param numWarmupIters Number of warmup iterations. + */ + Bench& warmup(uint64_t numWarmupIters) noexcept; + ANKERL_NANOBENCH(NODISCARD) uint64_t warmup() const noexcept; + + /** + * @brief Marks the next run as the baseline. + * + * Call `relative(true)` to mark the run as the baseline. Successive runs will be compared to this run. It is calculated by + * + * @f[ + * 100\% * \frac{baseline}{runtime} + * @f] + * + * * 100% means it is exactly as fast as the baseline + * * >100% means it is faster than the baseline. E.g. 200% means the current run is twice as fast as the baseline. + * * <100% means it is slower than the baseline. E.g. 50% means it is twice as slow as the baseline. + * + * See the tutorial section "Comparing Results" for example usage. + * + * @param isRelativeEnabled True to enable processing + */ + Bench& relative(bool isRelativeEnabled) noexcept; + ANKERL_NANOBENCH(NODISCARD) bool relative() const noexcept; + + /** + * @brief Enables/disables performance counters. + * + * On Linux nanobench has a powerful feature to use performance counters. This enables counting of retired instructions, count + * number of branches, missed branches, etc. On default this is enabled, but you can disable it if you don't need that feature. + * + * @param showPerformanceCounters True to enable, false to disable. + */ + Bench& performanceCounters(bool showPerformanceCounters) noexcept; + ANKERL_NANOBENCH(NODISCARD) bool performanceCounters() const noexcept; + + /** + * @brief Retrieves all benchmark results collected by the bench object so far. + * + * Each call to run() generates a Result that is stored within the Bench instance. This is mostly for advanced users who want to + * see all the nitty gritty details. + * + * @return All results collected so far. + */ + ANKERL_NANOBENCH(NODISCARD) std::vector const& results() const noexcept; + + /*! + @verbatim embed:rst + + Convenience shortcut to :cpp:func:`ankerl::nanobench::doNotOptimizeAway`. + + @endverbatim + */ + template + Bench& doNotOptimizeAway(Arg&& arg); + + /*! + @verbatim embed:rst + + Sets N for asymptotic complexity calculation, so it becomes possible to calculate `Big O + `_ from multiple benchmark evaluations. + + Use :cpp:func:`ankerl::nanobench::Bench::complexityBigO` when the evaluation has finished. See the tutorial + :ref:`asymptotic-complexity` for details. + + @endverbatim + + @tparam T Any type is cast to `double`. + @param b Length of N for the next benchmark run, so it is possible to calculate `bigO`. + */ + template + Bench& complexityN(T b) noexcept; + ANKERL_NANOBENCH(NODISCARD) double complexityN() const noexcept; + + /*! + Calculates [Big O](https://en.wikipedia.org/wiki/Big_O_notation>) of the results with all preconfigured complexity functions. + Currently these complexity functions are fitted into the benchmark results: + + @f$ \mathcal{O}(1) @f$, + @f$ \mathcal{O}(n) @f$, + @f$ \mathcal{O}(\log{}n) @f$, + @f$ \mathcal{O}(n\log{}n) @f$, + @f$ \mathcal{O}(n^2) @f$, + @f$ \mathcal{O}(n^3) @f$. + + If we e.g. evaluate the complexity of `std::sort`, this is the result of `std::cout << bench.complexityBigO()`: + + ``` + | coefficient | err% | complexity + |--------------:|-------:|------------ + | 5.08935e-09 | 2.6% | O(n log n) + | 6.10608e-08 | 8.0% | O(n) + | 1.29307e-11 | 47.2% | O(n^2) + | 2.48677e-15 | 69.6% | O(n^3) + | 9.88133e-06 | 132.3% | O(log n) + | 5.98793e-05 | 162.5% | O(1) + ``` + + So in this case @f$ \mathcal{O}(n\log{}n) @f$ provides the best approximation. + + @verbatim embed:rst + See the tutorial :ref:`asymptotic-complexity` for details. + @endverbatim + @return Evaluation results, which can be printed or otherwise inspected. + */ + std::vector complexityBigO() const; + + /** + * @brief Calculates bigO for a custom function. + * + * E.g. to calculate the mean squared error for @f$ \mathcal{O}(\log{}\log{}n) @f$, which is not part of the default set of + * complexityBigO(), you can do this: + * + * ``` + * auto logLogN = bench.complexityBigO("O(log log n)", [](double n) { + * return std::log2(std::log2(n)); + * }); + * ``` + * + * The resulting mean squared error can be printed with `std::cout << logLogN`. E.g. it prints something like this: + * + * ```text + * 2.46985e-05 * O(log log n), rms=1.48121 + * ``` + * + * @tparam Op Type of mapping operation. + * @param name Name for the function, e.g. "O(log log n)" + * @param op Op's operator() maps a `double` with the desired complexity function, e.g. `log2(log2(n))`. + * @return BigO Error calculation, which is streamable to std::cout. + */ + template + BigO complexityBigO(char const* name, Op op) const; + + template + BigO complexityBigO(std::string const& name, Op op) const; + + /*! + @verbatim embed:rst + + Convenience shortcut to :cpp:func:`ankerl::nanobench::render`. + + @endverbatim + */ + Bench& render(char const* templateContent, std::ostream& os); + Bench& render(std::string const& templateContent, std::ostream& os); + + Bench& config(Config const& benchmarkConfig); + ANKERL_NANOBENCH(NODISCARD) Config const& config() const noexcept; + + private: + Config mConfig{}; + std::vector mResults{}; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + /** + * @brief Makes sure none of the given arguments are optimized away by the compiler. + * + * @tparam Arg Type of the argument that shouldn't be optimized away. + * @param arg The input that we mark as being used, even though we don't do anything with it. + */ + template + void doNotOptimizeAway(Arg&& arg); + + namespace detail { + +#if defined(_MSC_VER) + void doNotOptimizeAwaySink(void const*); + + template + void doNotOptimizeAway(T const& val); + +#else + + // These assembly magic is directly from what Google Benchmark is doing. I have previously used what facebook's folly was doing, but + // this seemed to have compilation problems in some cases. Google Benchmark seemed to be the most well tested anyways. + // see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark.h#L307 + template + void doNotOptimizeAway(T const& val) { + // NOLINTNEXTLINE(hicpp-no-assembler) + asm volatile("" : : "r,m"(val) : "memory"); + } + + template + void doNotOptimizeAway(T& val) { +# if defined(__clang__) + // NOLINTNEXTLINE(hicpp-no-assembler) + asm volatile("" : "+r,m"(val) : : "memory"); +# else + // NOLINTNEXTLINE(hicpp-no-assembler) + asm volatile("" : "+m,r"(val) : : "memory"); +# endif + } +#endif + + // internally used, but visible because run() is templated. + // Not movable/copy-able, so we simply use a pointer instead of unique_ptr. This saves us from + // having to include , and the template instantiation overhead of unique_ptr which is unfortunately quite significant. + ANKERL_NANOBENCH(IGNORE_EFFCPP_PUSH) + class IterationLogic { + public: + explicit IterationLogic(Bench const& config) noexcept; + ~IterationLogic(); + + ANKERL_NANOBENCH(NODISCARD) uint64_t numIters() const noexcept; + void add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept; + void moveResultTo(std::vector& results) noexcept; + + private: + struct Impl; + Impl* mPimpl; + }; + ANKERL_NANOBENCH(IGNORE_EFFCPP_POP) + + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class PerformanceCounters { + public: + PerformanceCounters(PerformanceCounters const&) = delete; + PerformanceCounters& operator=(PerformanceCounters const&) = delete; + + PerformanceCounters(); + ~PerformanceCounters(); + + void beginMeasure(); + void endMeasure(); + void updateResults(uint64_t numIters); + + ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& val() const noexcept; + ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& has() const noexcept; + + private: +#if ANKERL_NANOBENCH(PERF_COUNTERS) + LinuxPerformanceCounters* mPc = nullptr; +#endif + PerfCountSet mVal{}; + PerfCountSet mHas{}; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + // Gets the singleton + PerformanceCounters& performanceCounters(); + + } // namespace detail + + class BigO { + public: + using RangeMeasure = std::vector>; + + template + static RangeMeasure mapRangeMeasure(RangeMeasure data, Op op) { + for (auto& rangeMeasure : data) { + rangeMeasure.first = op(rangeMeasure.first); + } + return data; + } + + static RangeMeasure collectRangeMeasure(std::vector const& results); + + template + BigO(char const* bigOName, RangeMeasure const& rangeMeasure, Op rangeToN) + : BigO(bigOName, mapRangeMeasure(rangeMeasure, rangeToN)) {} + + template + BigO(std::string const& bigOName, RangeMeasure const& rangeMeasure, Op rangeToN) + : BigO(bigOName, mapRangeMeasure(rangeMeasure, rangeToN)) {} + + BigO(char const* bigOName, RangeMeasure const& scaledRangeMeasure); + BigO(std::string const& bigOName, RangeMeasure const& scaledRangeMeasure); + ANKERL_NANOBENCH(NODISCARD) std::string const& name() const noexcept; + ANKERL_NANOBENCH(NODISCARD) double constant() const noexcept; + ANKERL_NANOBENCH(NODISCARD) double normalizedRootMeanSquare() const noexcept; + ANKERL_NANOBENCH(NODISCARD) bool operator<(BigO const& other) const noexcept; + + private: + std::string mName{}; + double mConstant{}; + double mNormalizedRootMeanSquare{}; + }; + std::ostream& operator<<(std::ostream& os, BigO const& bigO); + std::ostream& operator<<(std::ostream& os, std::vector const& bigOs); + + } // namespace nanobench +} // namespace ankerl + +// implementation ///////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + + constexpr uint64_t(Rng::min)() { + return 0; + } + + constexpr uint64_t(Rng::max)() { + return (std::numeric_limits::max)(); + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + uint64_t Rng::operator()() noexcept { + auto x = mX; + + mX = UINT64_C(15241094284759029579) * mY; + mY = rotl(mY - x, 27); + + return x; + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + uint32_t Rng::bounded(uint32_t range) noexcept { + uint64_t r32 = static_cast(operator()()); + auto multiresult = r32 * range; + return static_cast(multiresult >> 32U); + } + + double Rng::uniform01() noexcept { + auto i = (UINT64_C(0x3ff) << 52U) | (operator()() >> 12U); + // can't use union in c++ here for type puning, it's undefined behavior. + // std::memcpy is optimized anyways. + double d; + std::memcpy(&d, &i, sizeof(double)); + return d - 1.0; + } + + template + void Rng::shuffle(Container& container) noexcept { + auto size = static_cast(container.size()); + for (auto i = size; i > 1U; --i) { + using std::swap; + auto p = bounded(i); // number in [0, i) + swap(container[i - 1], container[p]); + } + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + constexpr uint64_t Rng::rotl(uint64_t x, unsigned k) noexcept { + return (x << k) | (x >> (64U - k)); + } + + template + ANKERL_NANOBENCH_NO_SANITIZE("integer") + Bench& Bench::run(Op&& op) { + // It is important that this method is kept short so the compiler can do better optimizations/ inlining of op() + detail::IterationLogic iterationLogic(*this); + auto& pc = detail::performanceCounters(); + + while (auto n = iterationLogic.numIters()) { + pc.beginMeasure(); + Clock::time_point before = Clock::now(); + while (n-- > 0) { + op(); + } + Clock::time_point after = Clock::now(); + pc.endMeasure(); + pc.updateResults(iterationLogic.numIters()); + iterationLogic.add(after - before, pc); + } + iterationLogic.moveResultTo(mResults); + return *this; + } + + // Performs all evaluations. + template + Bench& Bench::run(char const* benchmarkName, Op&& op) { + name(benchmarkName); + return run(std::forward(op)); + } + + template + Bench& Bench::run(std::string const& benchmarkName, Op&& op) { + name(benchmarkName); + return run(std::forward(op)); + } + + template + BigO Bench::complexityBigO(char const* benchmarkName, Op op) const { + return BigO(benchmarkName, BigO::collectRangeMeasure(mResults), op); + } + + template + BigO Bench::complexityBigO(std::string const& benchmarkName, Op op) const { + return BigO(benchmarkName, BigO::collectRangeMeasure(mResults), op); + } + + // Set the batch size, e.g. number of processed bytes, or some other metric for the size of the processed data in each iteration. + // Any argument is cast to double. + template + Bench& Bench::batch(T b) noexcept { + mConfig.mBatch = static_cast(b); + return *this; + } + + // Sets the computation complexity of the next run. Any argument is cast to double. + template + Bench& Bench::complexityN(T n) noexcept { + mConfig.mComplexityN = static_cast(n); + return *this; + } + + // Convenience: makes sure none of the given arguments are optimized away by the compiler. + template + Bench& Bench::doNotOptimizeAway(Arg&& arg) { + detail::doNotOptimizeAway(std::forward(arg)); + return *this; + } + + // Makes sure none of the given arguments are optimized away by the compiler. + template + void doNotOptimizeAway(Arg&& arg) { + detail::doNotOptimizeAway(std::forward(arg)); + } + + namespace detail { + +#if defined(_MSC_VER) + template + void doNotOptimizeAway(T const& val) { + doNotOptimizeAwaySink(&val); + } + +#endif + + } // namespace detail + } // namespace nanobench +} // namespace ankerl + +#if defined(ANKERL_NANOBENCH_IMPLEMENT) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// implementation part - only visible in .cpp +/////////////////////////////////////////////////////////////////////////////////////////////////// + +# include // sort, reverse +# include // compare_exchange_strong in loop overhead +# include // getenv +# include // strstr, strncmp +# include // ifstream to parse proc files +# include // setw, setprecision +# include // cout +# include // accumulate +# include // random_device +# include // to_s in Number +# include // throw for rendering templates +# include // std::tie +# if defined(__linux__) +# include //sysconf +# endif +# if ANKERL_NANOBENCH(PERF_COUNTERS) +# include // map + +# include +# include +# include +# include +# endif + +// declarations /////////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + + // helper stuff that is only intended to be used internally + namespace detail { + + struct TableInfo; + + // formatting utilities + namespace fmt { + + class NumSep; + class StreamStateRestorer; + class Number; + class MarkDownColumn; + class MarkDownCode; + + } // namespace fmt + } // namespace detail + } // namespace nanobench +} // namespace ankerl + +// definitions //////////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + + uint64_t splitMix64(uint64_t& state) noexcept; + + namespace detail { + + // helpers to get double values + template + inline double d(T t) noexcept { + return static_cast(t); + } + inline double d(Clock::duration duration) noexcept { + return std::chrono::duration_cast>(duration).count(); + } + + // Calculates clock resolution once, and remembers the result + inline Clock::duration clockResolution() noexcept; + + } // namespace detail + + namespace templates { + + char const* csv() noexcept { + return R"DELIM("title";"name";"unit";"batch";"elapsed";"error %";"instructions";"branches";"branch misses";"total" +{{#result}}"{{title}}";"{{name}}";"{{unit}}";{{batch}};{{median(elapsed)}};{{medianAbsolutePercentError(elapsed)}};{{median(instructions)}};{{median(branchinstructions)}};{{ +median(branchmisses)}};{{sumProduct(iterations, elapsed)}} +{{/result}})DELIM"; + } + + char const* htmlBoxplot() noexcept { + return R"DELIM( + + + + + + +

+ + + +)DELIM"; + } + + char const* pyperf() noexcept { + return R"DELIM({ + "benchmarks": [ + { + "runs": [ + { + "values": [ +{{#measurement}} {{elapsed}}{{^-last}}, +{{/last}}{{/measurement}} + ] + } + ] + } + ], + "metadata": { + "loops": {{sum(iterations)}}, + "inner_loops": {{batch}}, + "name": "{{title}}", + "unit": "second" + }, + "version": "1.0" +})DELIM"; + } + + char const* json() noexcept { + return R"DELIM({ + "results": [ +{{#result}} { + "title": "{{title}}", + "name": "{{name}}", + "unit": "{{unit}}", + "batch": {{batch}}, + "complexityN": {{complexityN}}, + "epochs": {{epochs}}, + "clockResolution": {{clockResolution}}, + "clockResolutionMultiple": {{clockResolutionMultiple}}, + "maxEpochTime": {{maxEpochTime}}, + "minEpochTime": {{minEpochTime}}, + "minEpochIterations": {{minEpochIterations}}, + "epochIterations": {{epochIterations}}, + "warmup": {{warmup}}, + "relative": {{relative}}, + "median(elapsed)": {{median(elapsed)}}, + "medianAbsolutePercentError(elapsed)": {{medianAbsolutePercentError(elapsed)}}, + "median(instructions)": {{median(instructions)}}, + "medianAbsolutePercentError(instructions)": {{medianAbsolutePercentError(instructions)}}, + "median(cpucycles)": {{median(cpucycles)}}, + "median(contextswitches)": {{median(contextswitches)}}, + "median(pagefaults)": {{median(pagefaults)}}, + "median(branchinstructions)": {{median(branchinstructions)}}, + "median(branchmisses)": {{median(branchmisses)}}, + "totalTime": {{sumProduct(iterations, elapsed)}}, + "measurements": [ +{{#measurement}} { + "iterations": {{iterations}}, + "elapsed": {{elapsed}}, + "pagefaults": {{pagefaults}}, + "cpucycles": {{cpucycles}}, + "contextswitches": {{contextswitches}}, + "instructions": {{instructions}}, + "branchinstructions": {{branchinstructions}}, + "branchmisses": {{branchmisses}} + }{{^-last}},{{/-last}} +{{/measurement}} ] + }{{^-last}},{{/-last}} +{{/result}} ] +})DELIM"; + } + + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + struct Node { + enum class Type { tag, content, section, inverted_section }; + + char const* begin; + char const* end; + std::vector children; + Type type; + + template + // NOLINTNEXTLINE(hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-avoid-c-arrays) + bool operator==(char const (&str)[N]) const noexcept { + return static_cast(std::distance(begin, end) + 1) == N && 0 == strncmp(str, begin, N - 1); + } + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + static std::vector parseMustacheTemplate(char const** tpl) { + std::vector nodes; + + while (true) { + auto begin = std::strstr(*tpl, "{{"); + auto end = begin; + if (begin != nullptr) { + begin += 2; + end = std::strstr(begin, "}}"); + } + + if (begin == nullptr || end == nullptr) { + // nothing found, finish node + nodes.emplace_back(Node{*tpl, *tpl + std::strlen(*tpl), std::vector{}, Node::Type::content}); + return nodes; + } + + nodes.emplace_back(Node{*tpl, begin - 2, std::vector{}, Node::Type::content}); + + // we found a tag + *tpl = end + 2; + switch (*begin) { + case '/': + // finished! bail out + return nodes; + + case '#': + nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::section}); + break; + + case '^': + nodes.emplace_back(Node{begin + 1, end, parseMustacheTemplate(tpl), Node::Type::inverted_section}); + break; + + default: + nodes.emplace_back(Node{begin, end, std::vector{}, Node::Type::tag}); + break; + } + } + } + + static bool generateFirstLast(Node const& n, size_t idx, size_t size, std::ostream& out) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + bool matchFirst = n == "-first"; + bool matchLast = n == "-last"; + if (!matchFirst && !matchLast) { + return false; + } + + bool doWrite = false; + if (n.type == Node::Type::section) { + doWrite = (matchFirst && idx == 0) || (matchLast && idx == size - 1); + } else if (n.type == Node::Type::inverted_section) { + doWrite = (matchFirst && idx != 0) || (matchLast && idx != size - 1); + } + + if (doWrite) { + for (auto const& child : n.children) { + if (child.type == Node::Type::content) { + out.write(child.begin, std::distance(child.begin, child.end)); + } + } + } + return true; + } + + static bool matchCmdArgs(std::string const& str, std::vector& matchResult) { + matchResult.clear(); + auto idxOpen = str.find('('); + auto idxClose = str.find(')', idxOpen); + if (idxClose == std::string::npos) { + return false; + } + + matchResult.emplace_back(str.substr(0, idxOpen)); + + // split by comma + matchResult.emplace_back(std::string{}); + for (size_t i = idxOpen + 1; i != idxClose; ++i) { + if (str[i] == ' ' || str[i] == '\t') { + // skip whitespace + continue; + } + if (str[i] == ',') { + // got a comma => new string + matchResult.emplace_back(std::string{}); + continue; + } + // no whitespace no comma, append + matchResult.back() += str[i]; + } + return true; + } + + static bool generateConfigTag(Node const& n, Config const& config, std::ostream& out) { + using detail::d; + + if (n == "title") { + out << config.mBenchmarkTitle; + return true; + } else if (n == "name") { + out << config.mBenchmarkName; + return true; + } else if (n == "unit") { + out << config.mUnit; + return true; + } else if (n == "batch") { + out << config.mBatch; + return true; + } else if (n == "complexityN") { + out << config.mComplexityN; + return true; + } else if (n == "epochs") { + out << config.mNumEpochs; + return true; + } else if (n == "clockResolution") { + out << d(detail::clockResolution()); + return true; + } else if (n == "clockResolutionMultiple") { + out << config.mClockResolutionMultiple; + return true; + } else if (n == "maxEpochTime") { + out << d(config.mMaxEpochTime); + return true; + } else if (n == "minEpochTime") { + out << d(config.mMinEpochTime); + return true; + } else if (n == "minEpochIterations") { + out << config.mMinEpochIterations; + return true; + } else if (n == "epochIterations") { + out << config.mEpochIterations; + return true; + } else if (n == "warmup") { + out << config.mWarmup; + return true; + } else if (n == "relative") { + out << config.mIsRelative; + return true; + } + return false; + } + + static std::ostream& generateResultTag(Node const& n, Result const& r, std::ostream& out) { + if (generateConfigTag(n, r.config(), out)) { + return out; + } + // match e.g. "median(elapsed)" + // g++ 4.8 doesn't implement std::regex :( + // static std::regex const regOpArg1("^([a-zA-Z]+)\\(([a-zA-Z]*)\\)$"); + // std::cmatch matchResult; + // if (std::regex_match(n.begin, n.end, matchResult, regOpArg1)) { + std::vector matchResult; + if (matchCmdArgs(std::string(n.begin, n.end), matchResult)) { + if (matchResult.size() == 2) { + auto m = Result::fromString(matchResult[1]); + if (m == Result::Measure::_size) { + return out << 0.0; + } + + if (matchResult[0] == "median") { + return out << r.median(m); + } + if (matchResult[0] == "average") { + return out << r.average(m); + } + if (matchResult[0] == "medianAbsolutePercentError") { + return out << r.medianAbsolutePercentError(m); + } + if (matchResult[0] == "sum") { + return out << r.sum(m); + } + if (matchResult[0] == "minimum") { + return out << r.minimum(m); + } + if (matchResult[0] == "maximum") { + return out << r.maximum(m); + } + } else if (matchResult.size() == 3) { + auto m1 = Result::fromString(matchResult[1]); + auto m2 = Result::fromString(matchResult[2]); + if (m1 == Result::Measure::_size || m2 == Result::Measure::_size) { + return out << 0.0; + } + + if (matchResult[0] == "sumProduct") { + return out << r.sumProduct(m1, m2); + } + } + } + + // match e.g. "sumProduct(elapsed, iterations)" + // static std::regex const regOpArg2("^([a-zA-Z]+)\\(([a-zA-Z]*)\\s*,\\s+([a-zA-Z]*)\\)$"); + + // nothing matches :( + throw std::runtime_error("command '" + std::string(n.begin, n.end) + "' not understood"); + } + + static void generateResultMeasurement(std::vector const& nodes, size_t idx, Result const& r, std::ostream& out) { + for (auto const& n : nodes) { + if (!generateFirstLast(n, idx, r.size(), out)) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case Node::Type::inverted_section: + throw std::runtime_error("got a inverted section inside measurement"); + + case Node::Type::section: + throw std::runtime_error("got a section inside measurement"); + + case Node::Type::tag: { + auto m = Result::fromString(std::string(n.begin, n.end)); + if (m == Result::Measure::_size || !r.has(m)) { + out << 0.0; + } else { + out << r.get(idx, m); + } + break; + } + } + } + } + } + + static void generateResult(std::vector const& nodes, size_t idx, std::vector const& results, std::ostream& out) { + auto const& r = results[idx]; + for (auto const& n : nodes) { + if (!generateFirstLast(n, idx, results.size(), out)) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case Node::Type::inverted_section: + throw std::runtime_error("got a inverted section inside result"); + + case Node::Type::section: + if (n == "measurement") { + for (size_t i = 0; i < r.size(); ++i) { + generateResultMeasurement(n.children, i, r, out); + } + } else { + throw std::runtime_error("got a section inside result"); + } + break; + + case Node::Type::tag: + generateResultTag(n, r, out); + break; + } + } + } + } + + } // namespace templates + + // helper stuff that only intended to be used internally + namespace detail { + + char const* getEnv(char const* name); + bool isEndlessRunning(std::string const& name); + bool isWarningsEnabled(); + + template + T parseFile(std::string const& filename); + + void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations); + void printStabilityInformationOnce(std::ostream* os); + + // remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. + uint64_t& singletonHeaderHash() noexcept; + + // determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. + Clock::duration calcClockResolution(size_t numEvaluations) noexcept; + + // formatting utilities + namespace fmt { + + // adds thousands separator to numbers + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class NumSep : public std::numpunct { + public: + explicit NumSep(char sep); + char do_thousands_sep() const override; + std::string do_grouping() const override; + + private: + char mSep; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + // RAII to save & restore a stream's state + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class StreamStateRestorer { + public: + explicit StreamStateRestorer(std::ostream& s); + ~StreamStateRestorer(); + + // sets back all stream info that we remembered at construction + void restore(); + + // don't allow copying / moving + StreamStateRestorer(StreamStateRestorer const&) = delete; + StreamStateRestorer& operator=(StreamStateRestorer const&) = delete; + StreamStateRestorer(StreamStateRestorer&&) = delete; + StreamStateRestorer& operator=(StreamStateRestorer&&) = delete; + + private: + std::ostream& mStream; + std::locale mLocale; + std::streamsize const mPrecision; + std::streamsize const mWidth; + std::ostream::char_type const mFill; + std::ostream::fmtflags const mFmtFlags; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + // Number formatter + class Number { + public: + Number(int width, int precision, double value); + Number(int width, int precision, int64_t value); + std::string to_s() const; + + private: + friend std::ostream& operator<<(std::ostream& os, Number const& n); + std::ostream& write(std::ostream& os) const; + + int mWidth; + int mPrecision; + double mValue; + }; + + // helper replacement for std::to_string of signed/unsigned numbers so we are locale independent + std::string to_s(uint64_t s); + + std::ostream& operator<<(std::ostream& os, Number const& n); + + class MarkDownColumn { + public: + MarkDownColumn(int w, int prec, std::string const& tit, std::string const& suff, double val); + std::string title() const; + std::string separator() const; + std::string invalid() const; + std::string value() const; + + private: + int mWidth; + int mPrecision; + std::string mTitle; + std::string mSuffix; + double mValue; + }; + + // Formats any text as markdown code, escaping backticks. + class MarkDownCode { + public: + explicit MarkDownCode(std::string const& what); + + private: + friend std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); + std::ostream& write(std::ostream& os) const; + + std::string mWhat{}; + }; + + std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode); + + } // namespace fmt + } // namespace detail + } // namespace nanobench +} // namespace ankerl + +// implementation ///////////////////////////////////////////////////////////////////////////////// + +namespace ankerl { + namespace nanobench { + + void render(char const* mustacheTemplate, std::vector const& results, std::ostream& out) { + detail::fmt::StreamStateRestorer restorer(out); + + out.precision(std::numeric_limits::digits10); + auto nodes = templates::parseMustacheTemplate(&mustacheTemplate); + + for (auto const& n : nodes) { + ANKERL_NANOBENCH_LOG("n.type=" << static_cast(n.type)); + switch (n.type) { + case templates::Node::Type::content: + out.write(n.begin, std::distance(n.begin, n.end)); + break; + + case templates::Node::Type::inverted_section: + throw std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'"); + + case templates::Node::Type::section: + if (n == "result") { + const size_t nbResults = results.size(); + for (size_t i = 0; i < nbResults; ++i) { + generateResult(n.children, i, results, out); + } + } else if (n == "measurement") { + if (results.size() != 1) { + throw std::runtime_error( + "render: can only use section 'measurement' here if there is a single result, but there are " + + detail::fmt::to_s(results.size())); + } + // when we only have a single result, we can immediately go into its measurement. + auto const& r = results.front(); + for (size_t i = 0; i < r.size(); ++i) { + generateResultMeasurement(n.children, i, r, out); + } + } else { + throw std::runtime_error("render: unknown section '" + std::string(n.begin, n.end) + "'"); + } + break; + + case templates::Node::Type::tag: + if (results.size() == 1) { + // result & config are both supported there + generateResultTag(n, results.front(), out); + } else { + // This just uses the last result's config. + if (!generateConfigTag(n, results.back().config(), out)) { + throw std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'"); + } + } + break; + } + } + } + + void render(std::string const& mustacheTemplate, std::vector const& results, std::ostream& out) { + render(mustacheTemplate.c_str(), results, out); + } + + void render(char const* mustacheTemplate, const Bench& bench, std::ostream& out) { + render(mustacheTemplate, bench.results(), out); + } + + void render(std::string const& mustacheTemplate, const Bench& bench, std::ostream& out) { + render(mustacheTemplate.c_str(), bench.results(), out); + } + + namespace detail { + + PerformanceCounters& performanceCounters() { +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +# endif + static PerformanceCounters pc; +# if defined(__clang__) +# pragma clang diagnostic pop +# endif + return pc; + } + +// Windows version of doNotOptimizeAway +// see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark.h#L307 +// see https://github.com/facebook/folly/blob/master/folly/Benchmark.h#L280 +// see https://docs.microsoft.com/en-us/cpp/preprocessor/optimize +# if defined(_MSC_VER) +# pragma optimize("", off) + void doNotOptimizeAwaySink(void const*) {} +# pragma optimize("", on) +# endif + + template + T parseFile(std::string const& filename) { + std::ifstream fin(filename); + T num{}; + fin >> num; + return num; + } + + char const* getEnv(char const* name) { +# if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4996) // getenv': This function or variable may be unsafe. +# endif + return std::getenv(name); +# if defined(_MSC_VER) +# pragma warning(pop) +# endif + } + + bool isEndlessRunning(std::string const& name) { + auto endless = getEnv("NANOBENCH_ENDLESS"); + return nullptr != endless && endless == name; + } + + // True when environment variable NANOBENCH_SUPPRESS_WARNINGS is either not set at all, or set to "0" + bool isWarningsEnabled() { + auto suppression = getEnv("NANOBENCH_SUPPRESS_WARNINGS"); + return nullptr == suppression || suppression == std::string("0"); + } + + void gatherStabilityInformation(std::vector& warnings, std::vector& recommendations) { + warnings.clear(); + recommendations.clear(); + + bool recommendCheckFlags = false; + +# if defined(DEBUG) + warnings.emplace_back("DEBUG defined"); + recommendCheckFlags = true; +# endif + + bool recommendPyPerf = false; +# if defined(__linux__) + auto nprocs = sysconf(_SC_NPROCESSORS_CONF); + if (nprocs <= 0) { + warnings.emplace_back("couldn't figure out number of processors - no governor, turbo check possible"); + } else { + + // check frequency scaling + for (long id = 0; id < nprocs; ++id) { + auto idStr = detail::fmt::to_s(static_cast(id)); + auto sysCpu = "/sys/devices/system/cpu/cpu" + idStr; + auto minFreq = parseFile(sysCpu + "/cpufreq/scaling_min_freq"); + auto maxFreq = parseFile(sysCpu + "/cpufreq/scaling_max_freq"); + if (minFreq != maxFreq) { + auto minMHz = static_cast(minFreq) / 1000.0; + auto maxMHz = static_cast(maxFreq) / 1000.0; + warnings.emplace_back("CPU frequency scaling enabled: CPU " + idStr + " between " + + detail::fmt::Number(1, 1, minMHz).to_s() + " and " + detail::fmt::Number(1, 1, maxMHz).to_s() + + " MHz"); + recommendPyPerf = true; + break; + } + } + + auto currentGovernor = parseFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"); + if ("performance" != currentGovernor) { + warnings.emplace_back("CPU governor is '" + currentGovernor + "' but should be 'performance'"); + recommendPyPerf = true; + } + + if (0 == parseFile("/sys/devices/system/cpu/intel_pstate/no_turbo")) { + warnings.emplace_back("Turbo is enabled, CPU frequency will fluctuate"); + recommendPyPerf = true; + } + } +# endif + + if (recommendCheckFlags) { + recommendations.emplace_back("Make sure you compile for Release"); + } + if (recommendPyPerf) { + recommendations.emplace_back("Use 'pyperf system tune' before benchmarking. See https://github.com/psf/pyperf"); + } + } + + void printStabilityInformationOnce(std::ostream* outStream) { + static bool shouldPrint = true; + if (shouldPrint && outStream && isWarningsEnabled()) { + auto& os = *outStream; + shouldPrint = false; + std::vector warnings; + std::vector recommendations; + gatherStabilityInformation(warnings, recommendations); + if (warnings.empty()) { + return; + } + + os << "Warning, results might be unstable:" << std::endl; + for (auto const& w : warnings) { + os << "* " << w << std::endl; + } + + os << std::endl << "Recommendations" << std::endl; + for (auto const& r : recommendations) { + os << "* " << r << std::endl; + } + } + } + + // remembers the last table settings used. When it changes, a new table header is automatically written for the new entry. + uint64_t& singletonHeaderHash() noexcept { + static uint64_t sHeaderHash{}; + return sHeaderHash; + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + inline uint64_t hash_combine(uint64_t seed, uint64_t val) { + return seed ^ (val + UINT64_C(0x9e3779b9) + (seed << 6U) + (seed >> 2U)); + } + + // determines resolution of the given clock. This is done by measuring multiple times and returning the minimum time difference. + Clock::duration calcClockResolution(size_t numEvaluations) noexcept { + auto bestDuration = Clock::duration::max(); + Clock::time_point tBegin; + Clock::time_point tEnd; + for (size_t i = 0; i < numEvaluations; ++i) { + tBegin = Clock::now(); + do { + tEnd = Clock::now(); + } while (tBegin == tEnd); + bestDuration = (std::min)(bestDuration, tEnd - tBegin); + } + return bestDuration; + } + + // Calculates clock resolution once, and remembers the result + Clock::duration clockResolution() noexcept { + static Clock::duration sResolution = calcClockResolution(20); + return sResolution; + } + + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + struct IterationLogic::Impl { + enum class State { warmup, upscaling_runtime, measuring, endless }; + + explicit Impl(Bench const& bench) + : mBench(bench) + , mResult(bench.config()) { + printStabilityInformationOnce(mBench.output()); + + // determine target runtime per epoch + mTargetRuntimePerEpoch = detail::clockResolution() * mBench.clockResolutionMultiple(); + if (mTargetRuntimePerEpoch > mBench.maxEpochTime()) { + mTargetRuntimePerEpoch = mBench.maxEpochTime(); + } + if (mTargetRuntimePerEpoch < mBench.minEpochTime()) { + mTargetRuntimePerEpoch = mBench.minEpochTime(); + } + + if (isEndlessRunning(mBench.name())) { + std::cerr << "NANOBENCH_ENDLESS set: running '" << mBench.name() << "' endlessly" << std::endl; + mNumIters = (std::numeric_limits::max)(); + mState = State::endless; + } else if (0 != mBench.warmup()) { + mNumIters = mBench.warmup(); + mState = State::warmup; + } else if (0 != mBench.epochIterations()) { + // exact number of iterations + mNumIters = mBench.epochIterations(); + mState = State::measuring; + } else { + mNumIters = mBench.minEpochIterations(); + mState = State::upscaling_runtime; + } + } + + // directly calculates new iters based on elapsed&iters, and adds a 10% noise. Makes sure we don't underflow. + ANKERL_NANOBENCH(NODISCARD) uint64_t calcBestNumIters(std::chrono::nanoseconds elapsed, uint64_t iters) noexcept { + auto doubleElapsed = d(elapsed); + auto doubleTargetRuntimePerEpoch = d(mTargetRuntimePerEpoch); + auto doubleNewIters = doubleTargetRuntimePerEpoch / doubleElapsed * d(iters); + + auto doubleMinEpochIters = d(mBench.minEpochIterations()); + if (doubleNewIters < doubleMinEpochIters) { + doubleNewIters = doubleMinEpochIters; + } + doubleNewIters *= 1.0 + 0.2 * mRng.uniform01(); + + // +0.5 for correct rounding when casting + // NOLINTNEXTLINE(bugprone-incorrect-roundings) + return static_cast(doubleNewIters + 0.5); + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") void upscale(std::chrono::nanoseconds elapsed) { + if (elapsed * 10 < mTargetRuntimePerEpoch) { + // we are far below the target runtime. Multiply iterations by 10 (with overflow check) + if (mNumIters * 10 < mNumIters) { + // overflow :-( + showResult("iterations overflow. Maybe your code got optimized away?"); + mNumIters = 0; + return; + } + mNumIters *= 10; + } else { + mNumIters = calcBestNumIters(elapsed, mNumIters); + } + } + + void add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { +# if defined(ANKERL_NANOBENCH_LOG_ENABLED) + auto oldIters = mNumIters; +# endif + + switch (mState) { + case State::warmup: + if (isCloseEnoughForMeasurements(elapsed)) { + // if elapsed is close enough, we can skip upscaling and go right to measurements + // still, we don't add the result to the measurements. + mState = State::measuring; + mNumIters = calcBestNumIters(elapsed, mNumIters); + } else { + // not close enough: switch to upscaling + mState = State::upscaling_runtime; + upscale(elapsed); + } + break; + + case State::upscaling_runtime: + if (isCloseEnoughForMeasurements(elapsed)) { + // if we are close enough, add measurement and switch to always measuring + mState = State::measuring; + mTotalElapsed += elapsed; + mTotalNumIters += mNumIters; + mResult.add(elapsed, mNumIters, pc); + mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); + } else { + upscale(elapsed); + } + break; + + case State::measuring: + // just add measurements - no questions asked. Even when runtime is low. But we can't ignore + // that fluctuation, or else we would bias the result + mTotalElapsed += elapsed; + mTotalNumIters += mNumIters; + mResult.add(elapsed, mNumIters, pc); + if (0 != mBench.epochIterations()) { + mNumIters = mBench.epochIterations(); + } else { + mNumIters = calcBestNumIters(mTotalElapsed, mTotalNumIters); + } + break; + + case State::endless: + mNumIters = (std::numeric_limits::max)(); + break; + } + + if (static_cast(mResult.size()) == mBench.epochs()) { + // we got all the results that we need, finish it + showResult(""); + mNumIters = 0; + } + + ANKERL_NANOBENCH_LOG(mBench.name() << ": " << detail::fmt::Number(20, 3, static_cast(elapsed.count())) << " elapsed, " + << detail::fmt::Number(20, 3, static_cast(mTargetRuntimePerEpoch.count())) + << " target. oldIters=" << oldIters << ", mNumIters=" << mNumIters + << ", mState=" << static_cast(mState)); + } + + void showResult(std::string const& errorMessage) const { + ANKERL_NANOBENCH_LOG(errorMessage); + + if (mBench.output() != nullptr) { + // prepare column data /////// + std::vector columns; + + auto rMedian = mResult.median(Result::Measure::elapsed); + + if (mBench.relative()) { + double d = 100.0; + if (!mBench.results().empty()) { + d = rMedian <= 0.0 ? 0.0 : mBench.results().front().median(Result::Measure::elapsed) / rMedian * 100.0; + } + columns.emplace_back(11, 1, "relative", "%", d); + } + + if (mBench.complexityN() > 0) { + columns.emplace_back(14, 0, "complexityN", "", mBench.complexityN()); + } + + columns.emplace_back(22, 2, mBench.timeUnitName() + "/" + mBench.unit(), "", + rMedian / (mBench.timeUnit().count() * mBench.batch())); + columns.emplace_back(22, 2, mBench.unit() + "/s", "", rMedian <= 0.0 ? 0.0 : mBench.batch() / rMedian); + + double rErrorMedian = mResult.medianAbsolutePercentError(Result::Measure::elapsed); + columns.emplace_back(10, 1, "err%", "%", rErrorMedian * 100.0); + + double rInsMedian = -1.0; + if (mBench.performanceCounters() && mResult.has(Result::Measure::instructions)) { + rInsMedian = mResult.median(Result::Measure::instructions); + columns.emplace_back(18, 2, "ins/" + mBench.unit(), "", rInsMedian / mBench.batch()); + } + + double rCycMedian = -1.0; + if (mBench.performanceCounters() && mResult.has(Result::Measure::cpucycles)) { + rCycMedian = mResult.median(Result::Measure::cpucycles); + columns.emplace_back(18, 2, "cyc/" + mBench.unit(), "", rCycMedian / mBench.batch()); + } + if (rInsMedian > 0.0 && rCycMedian > 0.0) { + columns.emplace_back(9, 3, "IPC", "", rCycMedian <= 0.0 ? 0.0 : rInsMedian / rCycMedian); + } + if (mBench.performanceCounters() && mResult.has(Result::Measure::branchinstructions)) { + double rBraMedian = mResult.median(Result::Measure::branchinstructions); + columns.emplace_back(17, 2, "bra/" + mBench.unit(), "", rBraMedian / mBench.batch()); + if (mResult.has(Result::Measure::branchmisses)) { + double p = 0.0; + if (rBraMedian >= 1e-9) { + p = 100.0 * mResult.median(Result::Measure::branchmisses) / rBraMedian; + } + columns.emplace_back(10, 1, "miss%", "%", p); + } + } + + columns.emplace_back(12, 2, "total", "", mResult.sumProduct(Result::Measure::iterations, Result::Measure::elapsed)); + + // write everything + auto& os = *mBench.output(); + + // combine all elements that are relevant for printing the header + uint64_t hash = 0; + hash = hash_combine(std::hash{}(mBench.unit()), hash); + hash = hash_combine(std::hash{}(mBench.title()), hash); + hash = hash_combine(std::hash{}(mBench.timeUnitName()), hash); + hash = hash_combine(std::hash{}(mBench.timeUnit().count()), hash); + hash = hash_combine(std::hash{}(mBench.relative()), hash); + hash = hash_combine(std::hash{}(mBench.performanceCounters()), hash); + + if (hash != singletonHeaderHash()) { + singletonHeaderHash() = hash; + + // no result yet, print header + os << std::endl; + for (auto const& col : columns) { + os << col.title(); + } + os << "| " << mBench.title() << std::endl; + + for (auto const& col : columns) { + os << col.separator(); + } + os << "|:" << std::string(mBench.title().size() + 1U, '-') << std::endl; + } + + if (!errorMessage.empty()) { + for (auto const& col : columns) { + os << col.invalid(); + } + os << "| :boom: " << fmt::MarkDownCode(mBench.name()) << " (" << errorMessage << ')' << std::endl; + } else { + for (auto const& col : columns) { + os << col.value(); + } + os << "| "; + auto showUnstable = isWarningsEnabled() && rErrorMedian >= 0.05; + if (showUnstable) { + os << ":wavy_dash: "; + } + os << fmt::MarkDownCode(mBench.name()); + if (showUnstable) { + auto avgIters = static_cast(mTotalNumIters) / static_cast(mBench.epochs()); + // NOLINTNEXTLINE(bugprone-incorrect-roundings) + auto suggestedIters = static_cast(avgIters * 10 + 0.5); + + os << " (Unstable with ~" << detail::fmt::Number(1, 1, avgIters) + << " iters. Increase `minEpochIterations` to e.g. " << suggestedIters << ")"; + } + os << std::endl; + } + } + } + + ANKERL_NANOBENCH(NODISCARD) bool isCloseEnoughForMeasurements(std::chrono::nanoseconds elapsed) const noexcept { + return elapsed * 3 >= mTargetRuntimePerEpoch * 2; + } + + uint64_t mNumIters = 1; + Bench const& mBench; + std::chrono::nanoseconds mTargetRuntimePerEpoch{}; + Result mResult; + Rng mRng{123}; + std::chrono::nanoseconds mTotalElapsed{}; + uint64_t mTotalNumIters = 0; + + State mState = State::upscaling_runtime; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + IterationLogic::IterationLogic(Bench const& bench) noexcept + : mPimpl(new Impl(bench)) {} + + IterationLogic::~IterationLogic() { + if (mPimpl) { + delete mPimpl; + } + } + + uint64_t IterationLogic::numIters() const noexcept { + ANKERL_NANOBENCH_LOG(mPimpl->mBench.name() << ": mNumIters=" << mPimpl->mNumIters); + return mPimpl->mNumIters; + } + + void IterationLogic::add(std::chrono::nanoseconds elapsed, PerformanceCounters const& pc) noexcept { + mPimpl->add(elapsed, pc); + } + + void IterationLogic::moveResultTo(std::vector& results) noexcept { + results.emplace_back(std::move(mPimpl->mResult)); + } + +# if ANKERL_NANOBENCH(PERF_COUNTERS) + + ANKERL_NANOBENCH(IGNORE_PADDED_PUSH) + class LinuxPerformanceCounters { + public: + struct Target { + Target(uint64_t* targetValue_, bool correctMeasuringOverhead_, bool correctLoopOverhead_) + : targetValue(targetValue_) + , correctMeasuringOverhead(correctMeasuringOverhead_) + , correctLoopOverhead(correctLoopOverhead_) {} + + uint64_t* targetValue{}; + bool correctMeasuringOverhead{}; + bool correctLoopOverhead{}; + }; + + ~LinuxPerformanceCounters(); + + // quick operation + inline void start() {} + + inline void stop() {} + + bool monitor(perf_sw_ids swId, Target target); + bool monitor(perf_hw_id hwId, Target target); + + bool hasError() const noexcept { + return mHasError; + } + + // Just reading data is faster than enable & disabling. + // we subtract data ourselves. + inline void beginMeasure() { + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP); + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = -1 == ioctl(mFd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP); + } + + inline void endMeasure() { + if (mHasError) { + return; + } + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + mHasError = (-1 == ioctl(mFd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP)); + if (mHasError) { + return; + } + + auto const numBytes = sizeof(uint64_t) * mCounters.size(); + auto ret = read(mFd, mCounters.data(), numBytes); + mHasError = ret != static_cast(numBytes); + } + + void updateResults(uint64_t numIters); + + // rounded integer division + template + static inline T divRounded(T a, T divisor) { + return (a + divisor / 2) / divisor; + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + static inline uint32_t mix(uint32_t x) noexcept { + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return x; + } + + template + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + void calibrate(Op&& op) { + // clear current calibration data, + for (auto& v : mCalibratedOverhead) { + v = UINT64_C(0); + } + + // create new calibration data + auto newCalibration = mCalibratedOverhead; + for (auto& v : newCalibration) { + v = (std::numeric_limits::max)(); + } + for (size_t iter = 0; iter < 100; ++iter) { + beginMeasure(); + op(); + endMeasure(); + if (mHasError) { + return; + } + + for (size_t i = 0; i < newCalibration.size(); ++i) { + auto diff = mCounters[i]; + if (newCalibration[i] > diff) { + newCalibration[i] = diff; + } + } + } + + mCalibratedOverhead = std::move(newCalibration); + + { + // calibrate loop overhead. For branches & instructions this makes sense, not so much for everything else like cycles. + // marsaglia's xorshift: mov, sal/shr, xor. Times 3. + // This has the nice property that the compiler doesn't seem to be able to optimize multiple calls any further. + // see https://godbolt.org/z/49RVQ5 + uint64_t const numIters = 100000U + (std::random_device{}() & 3); + uint64_t n = numIters; + uint32_t x = 1234567; + + beginMeasure(); + while (n-- > 0) { + x = mix(x); + } + endMeasure(); + detail::doNotOptimizeAway(x); + auto measure1 = mCounters; + + n = numIters; + beginMeasure(); + while (n-- > 0) { + // we now run *twice* so we can easily calculate the overhead + x = mix(x); + x = mix(x); + } + endMeasure(); + detail::doNotOptimizeAway(x); + auto measure2 = mCounters; + + for (size_t i = 0; i < mCounters.size(); ++i) { + // factor 2 because we have two instructions per loop + auto m1 = measure1[i] > mCalibratedOverhead[i] ? measure1[i] - mCalibratedOverhead[i] : 0; + auto m2 = measure2[i] > mCalibratedOverhead[i] ? measure2[i] - mCalibratedOverhead[i] : 0; + auto overhead = m1 * 2 > m2 ? m1 * 2 - m2 : 0; + + mLoopOverhead[i] = divRounded(overhead, numIters); + } + } + } + + private: + bool monitor(uint32_t type, uint64_t eventid, Target target); + + std::map mIdToTarget{}; + + // start with minimum size of 3 for read_format + std::vector mCounters{3}; + std::vector mCalibratedOverhead{3}; + std::vector mLoopOverhead{3}; + + uint64_t mTimeEnabledNanos = 0; + uint64_t mTimeRunningNanos = 0; + int mFd = -1; + bool mHasError = false; + }; + ANKERL_NANOBENCH(IGNORE_PADDED_POP) + + LinuxPerformanceCounters::~LinuxPerformanceCounters() { + if (-1 != mFd) { + close(mFd); + } + } + + bool LinuxPerformanceCounters::monitor(perf_sw_ids swId, LinuxPerformanceCounters::Target target) { + return monitor(PERF_TYPE_SOFTWARE, swId, target); + } + + bool LinuxPerformanceCounters::monitor(perf_hw_id hwId, LinuxPerformanceCounters::Target target) { + return monitor(PERF_TYPE_HARDWARE, hwId, target); + } + + // overflow is ok, it's checked + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + void LinuxPerformanceCounters::updateResults(uint64_t numIters) { + // clear old data + for (auto& id_value : mIdToTarget) { + *id_value.second.targetValue = UINT64_C(0); + } + + if (mHasError) { + return; + } + + mTimeEnabledNanos = mCounters[1] - mCalibratedOverhead[1]; + mTimeRunningNanos = mCounters[2] - mCalibratedOverhead[2]; + + for (uint64_t i = 0; i < mCounters[0]; ++i) { + auto idx = static_cast(3 + i * 2 + 0); + auto id = mCounters[idx + 1U]; + + auto it = mIdToTarget.find(id); + if (it != mIdToTarget.end()) { + + auto& tgt = it->second; + *tgt.targetValue = mCounters[idx]; + if (tgt.correctMeasuringOverhead) { + if (*tgt.targetValue >= mCalibratedOverhead[idx]) { + *tgt.targetValue -= mCalibratedOverhead[idx]; + } else { + *tgt.targetValue = 0U; + } + } + if (tgt.correctLoopOverhead) { + auto correctionVal = mLoopOverhead[idx] * numIters; + if (*tgt.targetValue >= correctionVal) { + *tgt.targetValue -= correctionVal; + } else { + *tgt.targetValue = 0U; + } + } + } + } + } + + bool LinuxPerformanceCounters::monitor(uint32_t type, uint64_t eventid, Target target) { + *target.targetValue = (std::numeric_limits::max)(); + if (mHasError) { + return false; + } + + auto pea = perf_event_attr(); + std::memset(&pea, 0, sizeof(perf_event_attr)); + pea.type = type; + pea.size = sizeof(perf_event_attr); + pea.config = eventid; + pea.disabled = 1; // start counter as disabled + pea.exclude_kernel = 1; + pea.exclude_hv = 1; + + // NOLINTNEXTLINE(hicpp-signed-bitwise) + pea.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID | PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + + const int pid = 0; // the current process + const int cpu = -1; // all CPUs +# if defined(PERF_FLAG_FD_CLOEXEC) // since Linux 3.14 + const unsigned long flags = PERF_FLAG_FD_CLOEXEC; +# else + const unsigned long flags = 0; +# endif + + auto fd = static_cast(syscall(__NR_perf_event_open, &pea, pid, cpu, mFd, flags)); + if (-1 == fd) { + return false; + } + if (-1 == mFd) { + // first call: set to fd, and use this from now on + mFd = fd; + } + uint64_t id = 0; + // NOLINTNEXTLINE(hicpp-signed-bitwise) + if (-1 == ioctl(fd, PERF_EVENT_IOC_ID, &id)) { + // couldn't get id + return false; + } + + // insert into map, rely on the fact that map's references are constant. + mIdToTarget.emplace(id, target); + + // prepare readformat with the correct size (after the insert) + auto size = 3 + 2 * mIdToTarget.size(); + mCounters.resize(size); + mCalibratedOverhead.resize(size); + mLoopOverhead.resize(size); + + return true; + } + + PerformanceCounters::PerformanceCounters() + : mPc(new LinuxPerformanceCounters()) + , mVal() + , mHas() { + + mHas.pageFaults = mPc->monitor(PERF_COUNT_SW_PAGE_FAULTS, LinuxPerformanceCounters::Target(&mVal.pageFaults, true, false)); + mHas.cpuCycles = mPc->monitor(PERF_COUNT_HW_REF_CPU_CYCLES, LinuxPerformanceCounters::Target(&mVal.cpuCycles, true, false)); + mHas.contextSwitches = + mPc->monitor(PERF_COUNT_SW_CONTEXT_SWITCHES, LinuxPerformanceCounters::Target(&mVal.contextSwitches, true, false)); + mHas.instructions = mPc->monitor(PERF_COUNT_HW_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.instructions, true, true)); + mHas.branchInstructions = + mPc->monitor(PERF_COUNT_HW_BRANCH_INSTRUCTIONS, LinuxPerformanceCounters::Target(&mVal.branchInstructions, true, false)); + mHas.branchMisses = mPc->monitor(PERF_COUNT_HW_BRANCH_MISSES, LinuxPerformanceCounters::Target(&mVal.branchMisses, true, false)); + // mHas.branchMisses = false; + + mPc->start(); + mPc->calibrate([] { + auto before = ankerl::nanobench::Clock::now(); + auto after = ankerl::nanobench::Clock::now(); + (void)before; + (void)after; + }); + + if (mPc->hasError()) { + // something failed, don't monitor anything. + mHas = PerfCountSet{}; + } + } + + PerformanceCounters::~PerformanceCounters() { + if (nullptr != mPc) { + delete mPc; + } + } + + void PerformanceCounters::beginMeasure() { + mPc->beginMeasure(); + } + + void PerformanceCounters::endMeasure() { + mPc->endMeasure(); + } + + void PerformanceCounters::updateResults(uint64_t numIters) { + mPc->updateResults(numIters); + } + +# else + + PerformanceCounters::PerformanceCounters() = default; + PerformanceCounters::~PerformanceCounters() = default; + void PerformanceCounters::beginMeasure() {} + void PerformanceCounters::endMeasure() {} + void PerformanceCounters::updateResults(uint64_t) {} + +# endif + + ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::val() const noexcept { + return mVal; + } + ANKERL_NANOBENCH(NODISCARD) PerfCountSet const& PerformanceCounters::has() const noexcept { + return mHas; + } + + // formatting utilities + namespace fmt { + + // adds thousands separator to numbers + NumSep::NumSep(char sep) + : mSep(sep) {} + + char NumSep::do_thousands_sep() const { + return mSep; + } + + std::string NumSep::do_grouping() const { + return "\003"; + } + + // RAII to save & restore a stream's state + StreamStateRestorer::StreamStateRestorer(std::ostream& s) + : mStream(s) + , mLocale(s.getloc()) + , mPrecision(s.precision()) + , mWidth(s.width()) + , mFill(s.fill()) + , mFmtFlags(s.flags()) {} + + StreamStateRestorer::~StreamStateRestorer() { + restore(); + } + + // sets back all stream info that we remembered at construction + void StreamStateRestorer::restore() { + mStream.imbue(mLocale); + mStream.precision(mPrecision); + mStream.width(mWidth); + mStream.fill(mFill); + mStream.flags(mFmtFlags); + } + + Number::Number(int width, int precision, int64_t value) + : mWidth(width) + , mPrecision(precision) + , mValue(static_cast(value)) {} + + Number::Number(int width, int precision, double value) + : mWidth(width) + , mPrecision(precision) + , mValue(value) {} + + std::ostream& Number::write(std::ostream& os) const { + StreamStateRestorer restorer(os); + os.imbue(std::locale(os.getloc(), new NumSep(','))); + os << std::setw(mWidth) << std::setprecision(mPrecision) << std::fixed << mValue; + return os; + } + + std::string Number::to_s() const { + std::stringstream ss; + write(ss); + return ss.str(); + } + + std::string to_s(uint64_t n) { + std::string str; + do { + str += static_cast('0' + static_cast(n % 10)); + n /= 10; + } while (n != 0); + std::reverse(str.begin(), str.end()); + return str; + } + + std::ostream& operator<<(std::ostream& os, Number const& n) { + return n.write(os); + } + + MarkDownColumn::MarkDownColumn(int w, int prec, std::string const& tit, std::string const& suff, double val) + : mWidth(w) + , mPrecision(prec) + , mTitle(tit) + , mSuffix(suff) + , mValue(val) {} + + std::string MarkDownColumn::title() const { + std::stringstream ss; + ss << '|' << std::setw(mWidth - 2) << std::right << mTitle << ' '; + return ss.str(); + } + + std::string MarkDownColumn::separator() const { + std::string sep(static_cast(mWidth), '-'); + sep.front() = '|'; + sep.back() = ':'; + return sep; + } + + std::string MarkDownColumn::invalid() const { + std::string sep(static_cast(mWidth), ' '); + sep.front() = '|'; + sep[sep.size() - 2] = '-'; + return sep; + } + + std::string MarkDownColumn::value() const { + std::stringstream ss; + auto width = mWidth - 2 - static_cast(mSuffix.size()); + ss << '|' << Number(width, mPrecision, mValue) << mSuffix << ' '; + return ss.str(); + } + + // Formats any text as markdown code, escaping backticks. + MarkDownCode::MarkDownCode(std::string const& what) { + mWhat.reserve(what.size() + 2); + mWhat.push_back('`'); + for (char c : what) { + mWhat.push_back(c); + if ('`' == c) { + mWhat.push_back('`'); + } + } + mWhat.push_back('`'); + } + + std::ostream& MarkDownCode::write(std::ostream& os) const { + return os << mWhat; + } + + std::ostream& operator<<(std::ostream& os, MarkDownCode const& mdCode) { + return mdCode.write(os); + } + } // namespace fmt + } // namespace detail + + // provide implementation here so it's only generated once + Config::Config() = default; + Config::~Config() = default; + Config& Config::operator=(Config const&) = default; + Config& Config::operator=(Config&&) = default; + Config::Config(Config const&) = default; + Config::Config(Config&&) noexcept = default; + + // provide implementation here so it's only generated once + Result::~Result() = default; + Result& Result::operator=(Result const&) = default; + Result& Result::operator=(Result&&) = default; + Result::Result(Result const&) = default; + Result::Result(Result&&) noexcept = default; + + namespace detail { + template + inline constexpr typename std::underlying_type::type u(T val) noexcept { + return static_cast::type>(val); + } + } // namespace detail + + // Result returned after a benchmark has finished. Can be used as a baseline for relative(). + Result::Result(Config const& benchmarkConfig) + : mConfig(benchmarkConfig) + , mNameToMeasurements{detail::u(Result::Measure::_size)} {} + + void Result::add(Clock::duration totalElapsed, uint64_t iters, detail::PerformanceCounters const& pc) { + using detail::d; + using detail::u; + + double dIters = d(iters); + mNameToMeasurements[u(Result::Measure::iterations)].push_back(dIters); + + mNameToMeasurements[u(Result::Measure::elapsed)].push_back(d(totalElapsed) / dIters); + if (pc.has().pageFaults) { + mNameToMeasurements[u(Result::Measure::pagefaults)].push_back(d(pc.val().pageFaults) / dIters); + } + if (pc.has().cpuCycles) { + mNameToMeasurements[u(Result::Measure::cpucycles)].push_back(d(pc.val().cpuCycles) / dIters); + } + if (pc.has().contextSwitches) { + mNameToMeasurements[u(Result::Measure::contextswitches)].push_back(d(pc.val().contextSwitches) / dIters); + } + if (pc.has().instructions) { + mNameToMeasurements[u(Result::Measure::instructions)].push_back(d(pc.val().instructions) / dIters); + } + if (pc.has().branchInstructions) { + double branchInstructions = 0.0; + // correcting branches: remove branch introduced by the while (...) loop for each iteration. + if (pc.val().branchInstructions > iters + 1U) { + branchInstructions = d(pc.val().branchInstructions - (iters + 1U)); + } + mNameToMeasurements[u(Result::Measure::branchinstructions)].push_back(branchInstructions / dIters); + + if (pc.has().branchMisses) { + // correcting branch misses + double branchMisses = d(pc.val().branchMisses); + if (branchMisses > branchInstructions) { + // can't have branch misses when there were branches... + branchMisses = branchInstructions; + } + + // assuming at least one missed branch for the loop + branchMisses -= 1.0; + if (branchMisses < 1.0) { + branchMisses = 1.0; + } + mNameToMeasurements[u(Result::Measure::branchmisses)].push_back(branchMisses / dIters); + } + } + } + + Config const& Result::config() const noexcept { + return mConfig; + } + + inline double calcMedian(std::vector& data) { + if (data.empty()) { + return 0.0; + } + std::sort(data.begin(), data.end()); + + auto midIdx = data.size() / 2U; + if (1U == (data.size() & 1U)) { + return data[midIdx]; + } + return (data[midIdx - 1U] + data[midIdx]) / 2U; + } + + double Result::median(Measure m) const { + // create a copy so we can sort + auto data = mNameToMeasurements[detail::u(m)]; + return calcMedian(data); + } + + double Result::average(Measure m) const { + using detail::d; + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // create a copy so we can sort + return sum(m) / d(data.size()); + } + + double Result::medianAbsolutePercentError(Measure m) const { + // create copy + auto data = mNameToMeasurements[detail::u(m)]; + + // calculates MdAPE which is the median of percentage error + // see https://www.spiderfinancial.com/support/documentation/numxl/reference-manual/forecasting-performance/mdape + auto med = calcMedian(data); + + // transform the data to absolute error + for (auto& x : data) { + x = (x - med) / x; + if (x < 0) { + x = -x; + } + } + return calcMedian(data); + } + + double Result::sum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + return std::accumulate(data.begin(), data.end(), 0.0); + } + + double Result::sumProduct(Measure m1, Measure m2) const noexcept { + auto const& data1 = mNameToMeasurements[detail::u(m1)]; + auto const& data2 = mNameToMeasurements[detail::u(m2)]; + + if (data1.size() != data2.size()) { + return 0.0; + } + + double result = 0.0; + for (size_t i = 0, s = data1.size(); i != s; ++i) { + result += data1[i] * data2[i]; + } + return result; + } + + bool Result::has(Measure m) const noexcept { + return !mNameToMeasurements[detail::u(m)].empty(); + } + + double Result::get(size_t idx, Measure m) const { + auto const& data = mNameToMeasurements[detail::u(m)]; + return data.at(idx); + } + + bool Result::empty() const noexcept { + return 0U == size(); + } + + size_t Result::size() const noexcept { + auto const& data = mNameToMeasurements[detail::u(Measure::elapsed)]; + return data.size(); + } + + double Result::minimum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // here its save to assume that at least one element is there + return *std::min_element(data.begin(), data.end()); + } + + double Result::maximum(Measure m) const noexcept { + auto const& data = mNameToMeasurements[detail::u(m)]; + if (data.empty()) { + return 0.0; + } + + // here its save to assume that at least one element is there + return *std::max_element(data.begin(), data.end()); + } + + Result::Measure Result::fromString(std::string const& str) { + if (str == "elapsed") { + return Measure::elapsed; + } else if (str == "iterations") { + return Measure::iterations; + } else if (str == "pagefaults") { + return Measure::pagefaults; + } else if (str == "cpucycles") { + return Measure::cpucycles; + } else if (str == "contextswitches") { + return Measure::contextswitches; + } else if (str == "instructions") { + return Measure::instructions; + } else if (str == "branchinstructions") { + return Measure::branchinstructions; + } else if (str == "branchmisses") { + return Measure::branchmisses; + } else { + // not found, return _size + return Measure::_size; + } + } + + // Configuration of a microbenchmark. + Bench::Bench() { + mConfig.mOut = &std::cout; + } + + Bench::Bench(Bench&&) = default; + Bench& Bench::operator=(Bench&&) = default; + Bench::Bench(Bench const&) = default; + Bench& Bench::operator=(Bench const&) = default; + Bench::~Bench() noexcept = default; + + double Bench::batch() const noexcept { + return mConfig.mBatch; + } + + double Bench::complexityN() const noexcept { + return mConfig.mComplexityN; + } + + // Set a baseline to compare it to. 100% it is exactly as fast as the baseline, >100% means it is faster than the baseline, <100% + // means it is slower than the baseline. + Bench& Bench::relative(bool isRelativeEnabled) noexcept { + mConfig.mIsRelative = isRelativeEnabled; + return *this; + } + bool Bench::relative() const noexcept { + return mConfig.mIsRelative; + } + + Bench& Bench::performanceCounters(bool showPerformanceCounters) noexcept { + mConfig.mShowPerformanceCounters = showPerformanceCounters; + return *this; + } + bool Bench::performanceCounters() const noexcept { + return mConfig.mShowPerformanceCounters; + } + + // Operation unit. Defaults to "op", could be e.g. "byte" for string processing. + // If u differs from currently set unit, the stored results will be cleared. + // Use singular (byte, not bytes). + Bench& Bench::unit(char const* u) { + if (u != mConfig.mUnit) { + mResults.clear(); + } + mConfig.mUnit = u; + return *this; + } + + Bench& Bench::unit(std::string const& u) { + return unit(u.c_str()); + } + + std::string const& Bench::unit() const noexcept { + return mConfig.mUnit; + } + + Bench& Bench::timeUnit(std::chrono::duration const& tu, std::string const& tuName) { + mConfig.mTimeUnit = tu; + mConfig.mTimeUnitName = tuName; + return *this; + } + + std::string const& Bench::timeUnitName() const noexcept { + return mConfig.mTimeUnitName; + } + + std::chrono::duration const& Bench::timeUnit() const noexcept { + return mConfig.mTimeUnit; + } + + // If benchmarkTitle differs from currently set title, the stored results will be cleared. + Bench& Bench::title(const char* benchmarkTitle) { + if (benchmarkTitle != mConfig.mBenchmarkTitle) { + mResults.clear(); + } + mConfig.mBenchmarkTitle = benchmarkTitle; + return *this; + } + Bench& Bench::title(std::string const& benchmarkTitle) { + if (benchmarkTitle != mConfig.mBenchmarkTitle) { + mResults.clear(); + } + mConfig.mBenchmarkTitle = benchmarkTitle; + return *this; + } + + std::string const& Bench::title() const noexcept { + return mConfig.mBenchmarkTitle; + } + + Bench& Bench::name(const char* benchmarkName) { + mConfig.mBenchmarkName = benchmarkName; + return *this; + } + + Bench& Bench::name(std::string const& benchmarkName) { + mConfig.mBenchmarkName = benchmarkName; + return *this; + } + + std::string const& Bench::name() const noexcept { + return mConfig.mBenchmarkName; + } + + // Number of epochs to evaluate. The reported result will be the median of evaluation of each epoch. + Bench& Bench::epochs(size_t numEpochs) noexcept { + mConfig.mNumEpochs = numEpochs; + return *this; + } + size_t Bench::epochs() const noexcept { + return mConfig.mNumEpochs; + } + + // Desired evaluation time is a multiple of clock resolution. Default is to be 1000 times above this measurement precision. + Bench& Bench::clockResolutionMultiple(size_t multiple) noexcept { + mConfig.mClockResolutionMultiple = multiple; + return *this; + } + size_t Bench::clockResolutionMultiple() const noexcept { + return mConfig.mClockResolutionMultiple; + } + + // Sets the maximum time each epoch should take. Default is 100ms. + Bench& Bench::maxEpochTime(std::chrono::nanoseconds t) noexcept { + mConfig.mMaxEpochTime = t; + return *this; + } + std::chrono::nanoseconds Bench::maxEpochTime() const noexcept { + return mConfig.mMaxEpochTime; + } + + // Sets the maximum time each epoch should take. Default is 100ms. + Bench& Bench::minEpochTime(std::chrono::nanoseconds t) noexcept { + mConfig.mMinEpochTime = t; + return *this; + } + std::chrono::nanoseconds Bench::minEpochTime() const noexcept { + return mConfig.mMinEpochTime; + } + + Bench& Bench::minEpochIterations(uint64_t numIters) noexcept { + mConfig.mMinEpochIterations = (numIters == 0) ? 1 : numIters; + return *this; + } + uint64_t Bench::minEpochIterations() const noexcept { + return mConfig.mMinEpochIterations; + } + + Bench& Bench::epochIterations(uint64_t numIters) noexcept { + mConfig.mEpochIterations = numIters; + return *this; + } + uint64_t Bench::epochIterations() const noexcept { + return mConfig.mEpochIterations; + } + + Bench& Bench::warmup(uint64_t numWarmupIters) noexcept { + mConfig.mWarmup = numWarmupIters; + return *this; + } + uint64_t Bench::warmup() const noexcept { + return mConfig.mWarmup; + } + + Bench& Bench::config(Config const& benchmarkConfig) { + mConfig = benchmarkConfig; + return *this; + } + Config const& Bench::config() const noexcept { + return mConfig; + } + + Bench& Bench::output(std::ostream* outstream) noexcept { + mConfig.mOut = outstream; + return *this; + } + + ANKERL_NANOBENCH(NODISCARD) std::ostream* Bench::output() const noexcept { + return mConfig.mOut; + } + + std::vector const& Bench::results() const noexcept { + return mResults; + } + + Bench& Bench::render(char const* templateContent, std::ostream& os) { + ::ankerl::nanobench::render(templateContent, *this, os); + return *this; + } + + Bench& Bench::render(std::string const& templateContent, std::ostream& os) { + ::ankerl::nanobench::render(templateContent, *this, os); + return *this; + } + + std::vector Bench::complexityBigO() const { + std::vector bigOs; + auto rangeMeasure = BigO::collectRangeMeasure(mResults); + bigOs.emplace_back("O(1)", rangeMeasure, [](double) { + return 1.0; + }); + bigOs.emplace_back("O(n)", rangeMeasure, [](double n) { + return n; + }); + bigOs.emplace_back("O(log n)", rangeMeasure, [](double n) { + return std::log2(n); + }); + bigOs.emplace_back("O(n log n)", rangeMeasure, [](double n) { + return n * std::log2(n); + }); + bigOs.emplace_back("O(n^2)", rangeMeasure, [](double n) { + return n * n; + }); + bigOs.emplace_back("O(n^3)", rangeMeasure, [](double n) { + return n * n * n; + }); + std::sort(bigOs.begin(), bigOs.end()); + return bigOs; + } + + Rng::Rng() + : mX(0) + , mY(0) { + std::random_device rd; + std::uniform_int_distribution dist; + do { + mX = dist(rd); + mY = dist(rd); + } while (mX == 0 && mY == 0); + } + + ANKERL_NANOBENCH_NO_SANITIZE("integer", "undefined") + uint64_t splitMix64(uint64_t& state) noexcept { + uint64_t z = (state += UINT64_C(0x9e3779b97f4a7c15)); + z = (z ^ (z >> 30U)) * UINT64_C(0xbf58476d1ce4e5b9); + z = (z ^ (z >> 27U)) * UINT64_C(0x94d049bb133111eb); + return z ^ (z >> 31U); + } + + // Seeded as described in romu paper (update april 2020) + Rng::Rng(uint64_t seed) noexcept + : mX(splitMix64(seed)) + , mY(splitMix64(seed)) { + for (size_t i = 0; i < 10; ++i) { + operator()(); + } + } + + // only internally used to copy the RNG. + Rng::Rng(uint64_t x, uint64_t y) noexcept + : mX(x) + , mY(y) {} + + Rng Rng::copy() const noexcept { + return Rng{mX, mY}; + } + + Rng::Rng(std::vector const& data) + : mX(0) + , mY(0) { + if (data.size() != 2) { + throw std::runtime_error("ankerl::nanobench::Rng::Rng: needed exactly 2 entries in data, but got " + + detail::fmt::to_s(data.size())); + } + mX = data[0]; + mY = data[1]; + } + + std::vector Rng::state() const { + std::vector data(2); + data[0] = mX; + data[1] = mY; + return data; + } + + BigO::RangeMeasure BigO::collectRangeMeasure(std::vector const& results) { + BigO::RangeMeasure rangeMeasure; + for (auto const& result : results) { + if (result.config().mComplexityN > 0.0) { + rangeMeasure.emplace_back(result.config().mComplexityN, result.median(Result::Measure::elapsed)); + } + } + return rangeMeasure; + } + + BigO::BigO(std::string const& bigOName, RangeMeasure const& rangeMeasure) + : mName(bigOName) { + + // estimate the constant factor + double sumRangeMeasure = 0.0; + double sumRangeRange = 0.0; + + for (size_t i = 0; i < rangeMeasure.size(); ++i) { + sumRangeMeasure += rangeMeasure[i].first * rangeMeasure[i].second; + sumRangeRange += rangeMeasure[i].first * rangeMeasure[i].first; + } + mConstant = sumRangeMeasure / sumRangeRange; + + // calculate root mean square + double err = 0.0; + double sumMeasure = 0.0; + for (size_t i = 0; i < rangeMeasure.size(); ++i) { + auto diff = mConstant * rangeMeasure[i].first - rangeMeasure[i].second; + err += diff * diff; + + sumMeasure += rangeMeasure[i].second; + } + + auto n = static_cast(rangeMeasure.size()); + auto mean = sumMeasure / n; + mNormalizedRootMeanSquare = std::sqrt(err / n) / mean; + } + + BigO::BigO(const char* bigOName, RangeMeasure const& rangeMeasure) + : BigO(std::string(bigOName), rangeMeasure) {} + + std::string const& BigO::name() const noexcept { + return mName; + } + + double BigO::constant() const noexcept { + return mConstant; + } + + double BigO::normalizedRootMeanSquare() const noexcept { + return mNormalizedRootMeanSquare; + } + + bool BigO::operator<(BigO const& other) const noexcept { + return std::tie(mNormalizedRootMeanSquare, mName) < std::tie(other.mNormalizedRootMeanSquare, other.mName); + } + + std::ostream& operator<<(std::ostream& os, BigO const& bigO) { + return os << bigO.constant() << " * " << bigO.name() << ", rms=" << bigO.normalizedRootMeanSquare(); + } + + std::ostream& operator<<(std::ostream& os, std::vector const& bigOs) { + detail::fmt::StreamStateRestorer restorer(os); + os << std::endl << "| coefficient | err% | complexity" << std::endl << "|--------------:|-------:|------------" << std::endl; + for (auto const& bigO : bigOs) { + os << "|" << std::setw(14) << std::setprecision(7) << std::scientific << bigO.constant() << " "; + os << "|" << detail::fmt::Number(6, 1, bigO.normalizedRootMeanSquare() * 100.0) << "% "; + os << "| " << bigO.name(); + os << std::endl; + } + return os; + } + + } // namespace nanobench +} // namespace ankerl + +#endif // ANKERL_NANOBENCH_IMPLEMENT +#endif // ANKERL_NANOBENCH_H_INCLUDED \ No newline at end of file diff --git a/src/test/queryParser/TestMultiFieldQueryParser.cpp b/src/test/queryParser/TestMultiFieldQueryParser.cpp new file mode 100644 index 00000000000..ecf8c65772f --- /dev/null +++ b/src/test/queryParser/TestMultiFieldQueryParser.cpp @@ -0,0 +1,171 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +class MQPTestFilter: public TokenFilter { +public: + + bool inPhrase; + int32_t savedStart, savedEnd; + + /** + * Filter which discards the token 'stop' and which expands the + * token 'phrase' into 'phrase1 phrase2' + */ + MQPTestFilter(TokenStream* in): + TokenFilter(in,true), + inPhrase(false), + savedStart(0), + savedEnd(0) + { + } + + CL_NS(analysis)::Token* next(CL_NS(analysis)::Token* token) { + if (inPhrase) { + inPhrase = false; + token->set( _T("phrase2"), savedStart, savedEnd); + return token; + }else{ + while( input->next(token) ){ + if ( _tcscmp(token->termBuffer (), _T("phrase")) == 0 ) { + inPhrase = true; + savedStart = token->startOffset(); + savedEnd = token->endOffset(); + token->set( _T("phrase1"), savedStart, savedEnd); + return token; + }else if ( _tcscmp(token->termBuffer (), _T("stop") ) !=0 ){ + return token; + } + } + } + return NULL; + } +}; + +class MQPTestAnalyzer: public Analyzer { +public: + MQPTestAnalyzer() { + } + + /** Filters LowerCaseTokenizer with StopFilter. */ + TokenStream* tokenStream(const TCHAR* /*fieldName*/, Reader* reader) { + return _CLNEW MQPTestFilter(_CLNEW LowerCaseTokenizer (reader)); + } +}; + +void assertQueryEquals(CuTest *tc,const TCHAR* result, Query* q) { + if ( q == NULL ) + return; + + TCHAR* s = q->toString(); + int ret = _tcscmp(s,result); + _CLDELETE(q); + if ( ret != 0 ) { + TCHAR buf[HUGE_STRING_LEN]; + _sntprintf(buf, HUGE_STRING_LEN, _T("FAILED Query yielded /%s/, expecting /%s/\n"), s, result); + _CLDELETE_LCARRAY(s); + CuFail(tc, buf); + return; + } + _CLDELETE_LCARRAY(s); +} + +// verify parsing of query using a stopping analyzer +void assertStopQueryEquals(CuTest *tc, const TCHAR* qtxt, const TCHAR* expectedRes) { + const TCHAR* fields[] = {_T("b"), _T("t"), NULL }; + const uint8_t occur[] = {BooleanClause::SHOULD, BooleanClause::SHOULD, NULL}; + MQPTestAnalyzer *a = _CLNEW MQPTestAnalyzer(); + MultiFieldQueryParser mfqp(fields, a); + + Query *q = mfqp.parse(qtxt); + assertQueryEquals(tc, expectedRes, q); + + q = MultiFieldQueryParser::parse(qtxt, reinterpret_cast(&fields), + reinterpret_cast(&occur), a); + assertQueryEquals(tc, expectedRes, q); + _CLDELETE(a); +} + +/** test stop words arsing for both the non static form, and for the +* corresponding static form (qtxt, fields[]). */ +void tesStopwordsParsing(CuTest *tc) { + assertStopQueryEquals(tc, _T("one"), _T("b:one t:one")); + assertStopQueryEquals(tc, _T("one stop"), _T("b:one t:one")); + assertStopQueryEquals(tc, _T("one (stop)"), _T("b:one t:one")); + assertStopQueryEquals(tc, _T("one ((stop))"), _T("b:one t:one")); + assertStopQueryEquals(tc, _T("stop"), _T("")); + assertStopQueryEquals(tc, _T("(stop)"), _T("")); + assertStopQueryEquals(tc, _T("((stop))"), _T("")); +} + +void testMFQPSimple(CuTest *tc) { + const TCHAR* fields[] = {_T("b"), _T("t"), NULL}; + Analyzer* a = _CLNEW StandardAnalyzer(); + MultiFieldQueryParser mfqp(fields, a); + + Query *q = mfqp.parse(_T("one")); + assertQueryEquals(tc, _T("b:one t:one"), q); + + q = mfqp.parse(_T("one two")); + assertQueryEquals(tc, _T("(b:one t:one) (b:two t:two)"),q); + + q = mfqp.parse(_T("+one +two")); + assertQueryEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); + + q = mfqp.parse(_T("+one -two -three")); + assertQueryEquals(tc, _T("+(b:one t:one) -(b:two t:two) -(b:three t:three)"), q); + + q = mfqp.parse(_T("one^2 two")); + assertQueryEquals(tc, _T("((b:one t:one)^2.0) (b:two t:two)"), q); + + q = mfqp.parse(_T("one~ two")); + assertQueryEquals(tc, _T("(b:one~0.5 t:one~0.5) (b:two t:two)"), q); + + q = mfqp.parse(_T("one~0.8 two^2")); + assertQueryEquals(tc, _T("(b:one~0.8 t:one~0.8) ((b:two t:two)^2.0)"), q); + + q = mfqp.parse(_T("one* two*")); + assertQueryEquals(tc, _T("(b:one* t:one*) (b:two* t:two*)"), q); + + q = mfqp.parse(_T("[a TO c] two")); + assertQueryEquals(tc, _T("(b:[a TO c] t:[a TO c]) (b:two t:two)"), q); + + q = mfqp.parse(_T("w?ldcard")); + assertQueryEquals(tc, _T("b:w?ldcard t:w?ldcard"), q); + + q = mfqp.parse(_T("\"foo bar\"")); + assertQueryEquals(tc, _T("b:\"foo bar\" t:\"foo bar\""), q); + + q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); + assertQueryEquals(tc, _T("(b:\"aa bb cc\" t:\"aa bb cc\") (b:\"dd ee\" t:\"dd ee\")"), q); + + q = mfqp.parse(_T("\"foo bar\"~4")); + assertQueryEquals(tc, _T("b:\"foo bar\"~4 t:\"foo bar\"~4"), q); + + // make sure that terms which have a field are not touched: + q = mfqp.parse(_T("one f:two")); + assertQueryEquals(tc, _T("(b:one t:one) f:two"), q); + + // AND mode: + mfqp.setDefaultOperator(QueryParser::AND_OPERATOR); + q = mfqp.parse(_T("one two")); + assertQueryEquals(tc, _T("+(b:one t:one) +(b:two t:two)"), q); + q = mfqp.parse(_T("\"aa bb cc\" \"dd ee\"")); + assertQueryEquals(tc, _T("+(b:\"aa bb cc\" t:\"aa bb cc\") +(b:\"dd ee\" t:\"dd ee\")"), q); + + _CLDELETE(a); +} + +CuSuite *testMultiFieldQueryParser(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Multi-Field QP Test")); + + SUITE_ADD_TEST(suite, tesStopwordsParsing); + SUITE_ADD_TEST(suite, testMFQPSimple); + + return suite; +} diff --git a/src/test/queryParser/TestQueryParser.cpp b/src/test/queryParser/TestQueryParser.cpp new file mode 100644 index 00000000000..5a730a352fc --- /dev/null +++ b/src/test/queryParser/TestQueryParser.cpp @@ -0,0 +1,885 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + +/// Java QueryParser tests +/// Helper functions and classes + +class QPTestFilter: public TokenFilter { +public: + + bool inPhrase; + int32_t savedStart, savedEnd; + + /** + * Filter which discards the token 'stop' and which expands the + * token 'phrase' into 'phrase1 phrase2' + */ + QPTestFilter(TokenStream* in): + TokenFilter(in,true), + inPhrase(false), + savedStart(0), + savedEnd(0) + { + } + + CL_NS(analysis)::Token* next(CL_NS(analysis)::Token* token) { + if (inPhrase) { + inPhrase = false; + token->set( _T("phrase2"), savedStart, savedEnd); + return token; + }else{ + while( input->next(token) != NULL ){ + if ( _tcscmp(token->termBuffer (), _T("phrase")) == 0 ) { + inPhrase = true; + savedStart = token->startOffset(); + savedEnd = token->endOffset(); + token->set( _T("phrase1"), savedStart, savedEnd); + return token; + }else if ( _tcscmp(token->termBuffer (), _T("stop") ) !=0 ){ + return token; + } + } + } + return NULL; + } +}; + +class QPTestAnalyzer: public Analyzer { +public: + QPTestAnalyzer() { + } + + /** Filters LowerCaseTokenizer with StopFilter. */ + TokenStream* tokenStream(const TCHAR* /*fieldName*/, Reader* reader) { + return _CLNEW QPTestFilter(_CLNEW LowerCaseTokenizer (reader)); + } +}; + +class QPTestParser : public QueryParser { +public: + QPTestParser(TCHAR* f, Analyzer* a) : QueryParser(f, a){ + } + virtual ~QPTestParser(){ + } + +protected: + Query* getFuzzyQuery(TCHAR* /*field*/, TCHAR* /*termStr*/, float_t /*minSimilarity*/) { + _CLTHROWA(CL_ERR_Parse,"Fuzzy queries not allowed"); + } + + Query* getWildcardQuery(TCHAR* /*field*/, TCHAR* /*termStr*/) { + _CLTHROWA(CL_ERR_Parse,"Wildcard queries not allowed"); + } +}; + +QueryParser* getParser(Analyzer* a) { + if (a == NULL) + return NULL; + QueryParser* qp = _CLNEW QueryParser(_T("field"), a); + qp->setDefaultOperator(QueryParser::OR_OPERATOR); + return qp; +} + +Query* getQuery(CuTest *tc,const TCHAR* query, Analyzer* a, int ignoreCLError=0) { + bool del = (a==NULL); + QueryParser* qp = NULL; + try{ + if (a == NULL) + a = _CLNEW SimpleAnalyzer (); + + qp = getParser(a); + Query* ret = qp->parse(query); + + _CLLDELETE(qp); + if ( del ) + _CLLDELETE(a); + return ret; + }catch(CLuceneError& e){ + _CLLDELETE(qp); + if ( del ) _CLLDELETE(a); + if (ignoreCLError != e.number()) + CuFail(tc,e); + else + throw e; + return NULL; + }catch(...){ + _CLLDELETE(qp); + if ( del ) _CLLDELETE(a); + CuFail(tc,_T("/%s/ threw an error.\n"),query); + return NULL; + } +} + +void assertQueryEquals(CuTest* tc, QueryParser* qp, const TCHAR* field, const TCHAR* query, const TCHAR* result) { + Query* q = qp->parse(query); + TCHAR* s = q->toString(field); + _CLLDELETE(q); + if (_tcscmp(s,result)!=0){ + TCHAR str[CL_MAX_PATH]; + _tcscpy(str,s); + _CLDELETE_LCARRAY(s); + _CLLDELETE(qp); + CuFail(tc, _T("Query /%s/ yielded /%s/, expecting /%s/\n"), query, str, result); + return; + } + _CLDELETE_LCARRAY(s); +} + +void assertQueryEquals(CuTest *tc,const TCHAR* query, Analyzer* a, const TCHAR* result) { + + Query* q = getQuery(tc,query, a); + if ( q == NULL ){ + CuFail(tc, _T("getQuery returned NULL unexpectedly for query /%s/\n"), query); + return; + } + + TCHAR* s = q->toString(_T("field")); + int ret = _tcscmp(s,result); + _CLDELETE(q); + if ( ret != 0 ) { + TCHAR str[CL_MAX_PATH]; + _tcscpy(str,s); + _CLDELETE_LCARRAY(s); + CuFail(tc, _T("FAILED Query /%s/ yielded /%s/, expecting /%s/\n"), query, str, result); + } + _CLDELETE_CARRAY(s); +} + +void assertWildcardQueryEquals(CuTest *tc, const TCHAR* query, bool lowercase, const TCHAR* result, bool allowLeadingWildcard=false){ + SimpleAnalyzer a; + QueryParser* qp = getParser(&a); + qp->setLowercaseExpandedTerms(lowercase); + qp->setAllowLeadingWildcard(allowLeadingWildcard); + Query* q = qp->parse(query); + _CLLDELETE(qp); + + TCHAR* s = q->toString(_T("field")); + _CLLDELETE(q); + if (_tcscmp(s,result) != 0) { + TCHAR str[CL_MAX_PATH]; + _tcscpy(str,s); + _CLDELETE_CARRAY(s); + CuFail(tc,_T("WildcardQuery /%s/ yielded /%s/, expecting /%s/"),query, str, result); + } + _CLDELETE_CARRAY(s); +} + +void assertCorrectQuery(CuTest *tc,const TCHAR* query, Analyzer* a, const char* inst, const TCHAR* msg){ + Query* q = getQuery(tc,query,a); + bool success = q->instanceOf(inst); + _CLDELETE(q); + CuAssert(tc,msg,success); +} + +void assertCorrectQuery(CuTest *tc,Query* q, const char* inst, bool bDeleteQuery = false){ + bool ret = q->instanceOf(inst); + if (bDeleteQuery) _CLLDELETE(q); + CuAssertTrue(tc,ret); +} + +void assertParseException(CuTest *tc,const TCHAR* queryString) { + try { + getQuery(tc,queryString, NULL, CL_ERR_Parse); + } catch (CLuceneError&){ + return; + } + CuFail(tc,_T("ParseException expected, not thrown")); +} + +void assertEscapedQueryEquals(CuTest *tc,const TCHAR* query, Analyzer* a, const TCHAR* result){ + TCHAR* escapedQuery = QueryParser::escape(query); + if (_tcscmp(escapedQuery, result) != 0) { + TCHAR str[CL_MAX_PATH]; + _tcscpy(str,escapedQuery); + _CLDELETE_LCARRAY(escapedQuery); + CuFail(tc, _T("Query /%s/ yielded /%s/, expecting /%s/\n"), query, escapedQuery, result); + } + _CLDELETE_LCARRAY(escapedQuery); +} + +Query* getQueryDOA(const TCHAR* query, Analyzer* a=NULL) { + bool bOwnsAnalyzer=false; + if (a == NULL){ + a = _CLNEW SimpleAnalyzer (); + bOwnsAnalyzer=true; + } + QueryParser* qp = _CLNEW QueryParser(_T("field"), a); + qp->setDefaultOperator(QueryParser::AND_OPERATOR); + Query* q = qp->parse(query); + _CLLDELETE(qp); + if (bOwnsAnalyzer) _CLLDELETE(a); + return q; +} + +void assertQueryEqualsDOA(CuTest *tc,const TCHAR* query, Analyzer* a, const TCHAR* result){ + Query* q = getQueryDOA(query, a); + TCHAR* s = q->toString(_T("field")); + _CLLDELETE(q); + if (_tcscmp(s,result)!=0) { + TCHAR str[CL_MAX_PATH]; + _tcscpy(str,s); + _CLDELETE_LCARRAY(s); + CuFail(tc,_T("Query /%s/ yielded /%s/, expecting /%s/"),query, str, result); + } + _CLDELETE_LCARRAY(s); +} + +/// END Helper functions and classes + +void testSimple(CuTest *tc) { + StandardAnalyzer a; + KeywordAnalyzer b; + assertQueryEquals(tc,_T("term term term"), NULL, _T("term term term")); + +#ifdef _UCS2 + TCHAR tmp1[100]; + + lucene_utf8towcs(tmp1,"t\xc3\xbcrm term term",100); + assertQueryEquals(tc,tmp1, NULL, tmp1); + assertQueryEquals(tc,tmp1, &a, tmp1); + + lucene_utf8towcs(tmp1,"\xc3\xbcmlaut",100); + assertQueryEquals(tc,tmp1, NULL, tmp1); + assertQueryEquals(tc,tmp1, &a, tmp1); +#endif + + assertQueryEquals(tc, _T("\"\""), &b, _T("")); + assertQueryEquals(tc, _T("foo:\"\""), &b, _T("foo:")); + + assertQueryEquals(tc,_T("a AND b"), NULL, _T("+a +b")); + assertQueryEquals(tc,_T("(a AND b)"), NULL, _T("+a +b")); + assertQueryEquals(tc,_T("c OR (a AND b)"), NULL, _T("c (+a +b)")); + assertQueryEquals(tc,_T("a AND NOT b"), NULL, _T("+a -b")); + assertQueryEquals(tc,_T("a AND -b"), NULL, _T("+a -b")); + assertQueryEquals(tc,_T("a AND !b"), NULL, _T("+a -b")); + assertQueryEquals(tc,_T("a && b"), NULL, _T("+a +b")); + assertQueryEquals(tc,_T("a && ! b"), NULL, _T("+a -b")); + + assertQueryEquals(tc,_T("a OR b"), NULL, _T("a b")); + assertQueryEquals(tc,_T("a || b"), NULL, _T("a b")); + assertQueryEquals(tc,_T("a OR !b"), NULL, _T("a -b")); + assertQueryEquals(tc,_T("a OR ! b"), NULL, _T("a -b")); + assertQueryEquals(tc,_T("a OR -b"), NULL, _T("a -b")); + + assertQueryEquals(tc,_T("+term -term term"), NULL, _T("+term -term term")); + assertQueryEquals(tc,_T("foo:term AND field:anotherTerm"), NULL, + _T("+foo:term +anotherterm")); + assertQueryEquals(tc,_T("term AND \"phrase phrase\""), NULL, + _T("+term +\"phrase phrase\"") ); + assertQueryEquals(tc,_T("\"hello there\""), NULL, _T("\"hello there\"") ); + + assertCorrectQuery(tc, _T("a AND b"), NULL,"BooleanQuery",_T("a AND b") ); + assertCorrectQuery(tc, _T("hello"), NULL,"TermQuery", _T("hello")); + assertCorrectQuery(tc, _T("\"hello there\""), NULL,"PhraseQuery", _T("\"hello there\"")); + + assertQueryEquals(tc,_T("germ term^2.0"), NULL, _T("germ term^2.0")); + assertQueryEquals(tc,_T("(term)^2.0"), NULL, _T("term^2.0")); + assertQueryEquals(tc,_T("(germ term)^2.0"), NULL, _T("(germ term)^2.0")); + assertQueryEquals(tc,_T("term^2.0"), NULL, _T("term^2.0")); + assertQueryEquals(tc,_T("term^2"), NULL, _T("term^2.0")); + assertQueryEquals(tc,_T("term^2.3"), NULL, _T("term^2.3")); + assertQueryEquals(tc,_T("\"germ term\"^2.0"), NULL, _T("\"germ term\"^2.0")); + assertQueryEquals(tc,_T("\"germ term\"^2.02"), NULL, _T("\"germ term\"^2.0")); + assertQueryEquals(tc,_T("\"term germ\"^2"), NULL, _T("\"term germ\"^2.0") ); + + assertQueryEquals(tc,_T("(foo OR bar) AND (baz OR boo)"), NULL, + _T("+(foo bar) +(baz boo)")); + assertQueryEquals(tc,_T("((a OR b) AND NOT c) OR d"), NULL, + _T("(+(a b) -c) d")); + assertQueryEquals(tc,_T("+(apple \"steve jobs\") -(foo bar baz)"), NULL, + _T("+(apple \"steve jobs\") -(foo bar baz)") ); + assertQueryEquals(tc,_T("+title:(dog OR cat) -author:\"bob dole\""), NULL, + _T("+(title:dog title:cat) -author:\"bob dole\"") ); + + QueryParser* qp = _CLNEW QueryParser(_T("field"), &a); + // make sure OR is the default: + CLUCENE_ASSERT(QueryParser::OR_OPERATOR == qp->getDefaultOperator()); + qp->setDefaultOperator(QueryParser::AND_OPERATOR); + CLUCENE_ASSERT(QueryParser::AND_OPERATOR == qp->getDefaultOperator()); + + // try creating a query and make sure it uses AND + Query* bq = qp->parse(_T("term1 term2")); + CLUCENE_ASSERT( bq != NULL ); + TCHAR* s = bq->toString(_T("field")); + if ( _tcscmp(s,_T("+term1 +term2")) != 0 ) { + CuFail(tc, _T("FAILED Query /term1 term2/ yielded /%s/, expecting +term1 +term2\n"), s); + } + _CLDELETE_CARRAY(s); + _CLDELETE(bq); + + qp->setDefaultOperator(QueryParser::OR_OPERATOR); + CLUCENE_ASSERT(QueryParser::OR_OPERATOR == qp->getDefaultOperator()); + _CLDELETE(qp); +} + +void testPunct(CuTest *tc) { + WhitespaceAnalyzer a; + assertQueryEquals(tc,_T("a&b"), &a, _T("a&b")); + assertQueryEquals(tc,_T("a&&b"), &a, _T("a&&b")); + assertQueryEquals(tc,_T(".NET"), &a, _T(".NET")); +} + +void testSlop(CuTest *tc) { + assertQueryEquals(tc,_T("\"term germ\"~2"), NULL, _T("\"term germ\"~2") ); + assertQueryEquals(tc,_T("\"term germ\"~2 flork"), NULL, _T("\"term germ\"~2 flork") ); + assertQueryEquals(tc,_T("\"term\"~2"), NULL, _T("term")); + assertQueryEquals(tc,_T("\" \"~2 germ"), NULL, _T("germ")); + assertQueryEquals(tc,_T("\"term germ\"~2^2"), NULL, _T("\"term germ\"~2^2.0") ); + + /* + ### These do not work anymore with the new QP, and they do not exist in the official Java tests + assertQueryEquals(tc,_T("term~2"), NULL, _T("term")); + assertQueryEquals(tc,_T("term~0.5"), NULL, _T("term")); + assertQueryEquals(tc,_T("term~0.6"), NULL, _T("term")); + */ +} + +void testNumber(CuTest *tc) { + // The numbers go away because SimpleAnalzyer ignores them + assertQueryEquals(tc,_T("3"), NULL, _T("")); + assertQueryEquals(tc,_T("term 1.0 1 2"), NULL, _T("term")); + assertQueryEquals(tc,_T("term term1 term2"), NULL, _T("term term term")); + + StandardAnalyzer a; + assertQueryEquals(tc,_T("3"), &a, _T("3")); + assertQueryEquals(tc,_T("term 1.0 1 2"), &a, _T("term 1.0 1 2")); + assertQueryEquals(tc,_T("term term1 term2"), &a, _T("term term1 term2")); +} + +void testWildcard(CuTest *tc) +{ + assertQueryEquals(tc,_T("term*"), NULL, _T("term*")); + assertQueryEquals(tc,_T("term*^2"), NULL, _T("term*^2.0")); + assertQueryEquals(tc,_T("term~"), NULL, _T("term~0.5")); + assertQueryEquals(tc,_T("term~0.7"), NULL, _T("term~0.7")); + assertQueryEquals(tc,_T("term~^2"), NULL, _T("term~0.5^2.0")); + assertQueryEquals(tc,_T("term^2~"), NULL, _T("term~0.5^2.0")); + assertQueryEquals(tc,_T("term*germ"), NULL, _T("term*germ")); + assertQueryEquals(tc,_T("term*germ^3"), NULL, _T("term*germ^3.0")); + + assertCorrectQuery(tc, _T("term*"), NULL,"PrefixQuery", _T("term*")); + assertCorrectQuery(tc, _T("term*^2"), NULL,"PrefixQuery", _T("term*^2.0")); + assertCorrectQuery(tc, _T("term~"), NULL,"FuzzyQuery", _T("term~0.5")); + assertCorrectQuery(tc, _T("term~0.7"), NULL,"FuzzyQuery", _T("term~0.7")); + assertCorrectQuery(tc, _T("t*"), NULL,"PrefixQuery", _T("t*")); + + FuzzyQuery* fq = (FuzzyQuery*)getQuery(tc,_T("term~0.7"), NULL); + float_t simDiff = fq->getMinSimilarity() - 0.7; + if ( simDiff < 0 ) simDiff *= -1; + CuAssertTrue(tc, simDiff < 0.1); + CuAssertTrue(tc, FuzzyQuery::defaultPrefixLength == fq->getPrefixLength()); + _CLLDELETE(fq); + fq = (FuzzyQuery*)getQuery(tc, _T("term~"), NULL); + + simDiff = fq->getMinSimilarity() - 0.5; + if ( simDiff < 0 ) simDiff *= -1; + CuAssertTrue(tc, simDiff < 0.1); + CuAssertTrue(tc, FuzzyQuery::defaultPrefixLength == fq->getPrefixLength()); + _CLDELETE(fq); + + assertParseException(tc,_T("term~1.1")); // value > 1, throws exception + + assertCorrectQuery(tc, _T("term*germ"), NULL,"WildcardQuery", _T("term*germ")); + + /* Tests to see that wild card terms are (or are not) properly + * lower-cased with propery parser configuration + */ + // First prefix queries: + // by default, convert to lowercase: + assertWildcardQueryEquals(tc,_T("Term*"), true, _T("term*")); + // explicitly set lowercase: + assertWildcardQueryEquals(tc,_T("term*"), true, _T("term*")); + assertWildcardQueryEquals(tc,_T("Term*"), true, _T("term*")); + assertWildcardQueryEquals(tc,_T("TERM*"), true, _T("term*")); + // explicitly disable lowercase conversion: + assertWildcardQueryEquals(tc,_T("term*"), false, _T("term*")); + assertWildcardQueryEquals(tc,_T("Term*"), false, _T("Term*")); + assertWildcardQueryEquals(tc,_T("TERM*"), false, _T("TERM*")); + // Then 'full' wildcard queries: + // by default, convert to lowercase: + assertQueryEquals(tc,_T("Te?m"), NULL,_T("te?m")); + // explicitly set lowercase: + assertWildcardQueryEquals(tc,_T("te?m"), true, _T("te?m")); + assertWildcardQueryEquals(tc,_T("Te?m"), true, _T("te?m")); + assertWildcardQueryEquals(tc,_T("TE?M"), true, _T("te?m")); + assertWildcardQueryEquals(tc,_T("Te?m*gerM"), true, _T("te?m*germ")); + // explicitly disable lowercase conversion: + assertWildcardQueryEquals(tc,_T("te?m"), false, _T("te?m")); + assertWildcardQueryEquals(tc,_T("Te?m"), false, _T("Te?m")); + assertWildcardQueryEquals(tc,_T("TE?M"), false, _T("TE?M")); + assertWildcardQueryEquals(tc,_T("Te?m*gerM"), false, _T("Te?m*gerM")); + // Fuzzy queries: + assertQueryEquals(tc,_T("Term~"), NULL,_T("term~0.5")); + assertWildcardQueryEquals(tc,_T("Term~"), true, _T("term~0.5")); + assertWildcardQueryEquals(tc,_T("Term~"), false, _T("Term~0.5")); + // Range queries: + assertQueryEquals(tc,_T("[A TO C]"), NULL,_T("[a TO c]")); + assertWildcardQueryEquals(tc,_T("[A TO C]"), true, _T("[a TO c]")); + assertWildcardQueryEquals(tc,_T("[A TO C]"), false, _T("[A TO C]")); + // Test suffix queries: first disallow + assertParseException(tc,_T("*Term")); + assertParseException(tc,_T("?Term")); + + // Test suffix queries: then allow + assertWildcardQueryEquals(tc,_T("*Term"), true, _T("*term"), true); + assertWildcardQueryEquals(tc,_T("?Term"), true, _T("?term"), true); + + // ### not in the Java tests + // assertQueryEquals(tc,_T("term~0.5"), NULL, _T("term")); +} + +void testLeadingWildcardType(CuTest *tc) { + SimpleAnalyzer a; + QueryParser* qp = getParser(&a); + qp->setAllowLeadingWildcard(true); + assertCorrectQuery(tc, qp->parse(_T("t*erm*")), WildcardQuery::getClassName(), true); + assertCorrectQuery(tc, qp->parse(_T("?t*erm*")), WildcardQuery::getClassName(), true); // should not throw an exception + assertCorrectQuery(tc, qp->parse(_T("*t*erm*")), WildcardQuery::getClassName(), true); + _CLLDELETE(qp); +} + +void testQPA(CuTest *tc) { + QPTestAnalyzer qpAnalyzer; + assertQueryEquals(tc,_T("term term^3.0 term"), &qpAnalyzer, _T("term term^3.0 term") ); + assertQueryEquals(tc,_T("term stop^3.0 term"), &qpAnalyzer, _T("term term") ); + + assertQueryEquals(tc,_T("term term term"), &qpAnalyzer, _T("term term term") ); + assertQueryEquals(tc,_T("term +stop term"), &qpAnalyzer, _T("term term") ); + assertQueryEquals(tc,_T("term -stop term"), &qpAnalyzer, _T("term term") ); + + assertQueryEquals(tc,_T("drop AND (stop) AND roll"), &qpAnalyzer, _T("+drop +roll") ); + assertQueryEquals(tc,_T("term +(stop) term"), &qpAnalyzer, _T("term term") ); + assertQueryEquals(tc,_T("term -(stop) term"), &qpAnalyzer, _T("term term") ); + + assertQueryEquals(tc,_T("drop AND stop AND roll"), &qpAnalyzer, _T("+drop +roll") ); + assertQueryEquals(tc,_T("term phrase term"), &qpAnalyzer, + _T("term \"phrase1 phrase2\" term") ); + assertQueryEquals(tc,_T("term AND NOT phrase term"), &qpAnalyzer, + _T("+term -\"phrase1 phrase2\" term") ); + assertQueryEquals(tc,_T("stop^3"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("stop"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("(stop)^3"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("((stop))^3"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("(stop^3)"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("((stop)^3)"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("(stop)"), &qpAnalyzer, _T("") ); + assertQueryEquals(tc,_T("((stop))"), &qpAnalyzer, _T("") ); + assertCorrectQuery(tc, _T("term term term"), &qpAnalyzer,"BooleanQuery", _T("term term term")); + assertCorrectQuery(tc, _T("term +stop"), &qpAnalyzer,"TermQuery", _T("term +stop")); +} + +void testRange(CuTest *tc) { + StandardAnalyzer a; + + assertQueryEquals(tc, _T("[ a TO z]"), NULL, _T("[a TO z]")); + assertCorrectQuery(tc, _T("[ a TO z]"), NULL, "ConstantScoreRangeQuery", _T("[a TO z]")); + + QueryParser* qp = _CLNEW QueryParser(_T("field"), &a); + qp->setUseOldRangeQuery(true); + Query* q = qp->parse(_T("[ a TO z]")); + _CLLDELETE(qp); + CLUCENE_ASSERT(q->instanceOf("RangeQuery")); + _CLLDELETE(q); + + assertQueryEquals(tc, _T("[ a TO z ]"), NULL, _T("[a TO z]")); + assertQueryEquals(tc, _T("{ a TO z}"), NULL, _T("{a TO z}")); + assertQueryEquals(tc, _T("{ a TO z }"), NULL, _T("{a TO z}")); + assertQueryEquals(tc, _T("{ a TO z }^2.0"), NULL, _T("{a TO z}^2.0")); + assertQueryEquals(tc, _T("[ a TO z] OR bar"), NULL, _T("[a TO z] bar")); + assertQueryEquals(tc, _T("[ a TO z] AND bar"), NULL, _T("+[a TO z] +bar")); + assertQueryEquals(tc, _T("( bar blar { a TO z}) "), NULL, _T("bar blar {a TO z}")); + assertQueryEquals(tc, _T("gack ( bar blar { a TO z}) "), NULL, _T("gack (bar blar {a TO z})")); + + // Old CLucene tests - check this is working without TO as well + assertQueryEquals(tc,_T("[ a z]"), NULL, _T("[a TO z]")); + assertCorrectQuery(tc, _T("[ a z]"), NULL, "ConstantScoreRangeQuery", _T("[ a z]") ); + assertQueryEquals(tc,_T("[ a z ]"), NULL, _T("[a TO z]")); + assertQueryEquals(tc,_T("{ a z}"), NULL, _T("{a TO z}")); + assertQueryEquals(tc,_T("{ a z }"), NULL, _T("{a TO z}")); + assertQueryEquals(tc,_T("{ a z }^2.0"), NULL, _T("{a TO z}^2.0")); + assertQueryEquals(tc,_T("[ a z] OR bar"), NULL, _T("[a TO z] bar")); + assertQueryEquals(tc,_T("[ a z] AND bar"), NULL, _T("+[a TO z] +bar")); + assertQueryEquals(tc,_T("( bar blar { a z}) "), NULL, _T("bar blar {a TO z}")); + assertQueryEquals(tc,_T("gack ( bar blar { a z}) "), NULL, _T("gack (bar blar {a TO z})")); + + // ### Incompatiable with new QP, and does not appear in the Java tests; use the format below instead + // assertQueryEquals(tc,_T("[050-070]"), &a, _T("[050 TO -070]")); + assertQueryEquals(tc,_T("[050 -070]"), &a, _T("[050 TO -070]")); +} + +/// TODO: Complete missing date tests here + +/** for testing DateTools support */ +TCHAR* getDate(int64_t d, DateTools::Resolution resolution) { + if (resolution == DateTools::NO_RESOLUTION) { + return DateField::timeToString(d); + } else { + return DateTools::timeToString(d, resolution); + } +} + +/** for testing DateTools support */ +TCHAR* getDate(const TCHAR* s, DateTools::Resolution resolution) { + return getDate(DateTools::stringToTime(s), resolution); +} + +void assertDateRangeQueryEquals(CuTest* tc, QueryParser* qp, const TCHAR* field, + const TCHAR* startDate, const TCHAR* endDate, + int64_t endDateInclusive, DateTools::Resolution resolution) +{ + StringBuffer query; + query.append(field); + query.append(_T(":[")); + query.append(startDate); + query.append(_T(" TO ")); + query.append(endDate); + query.appendChar(_T(']')); + + StringBuffer result; + result.appendChar(_T('[')); + TCHAR* tmp = getDate(startDate, resolution); + result.append(tmp); + _CLDELETE_LCARRAY(tmp); + result.append(_T(" TO ")); + tmp = getDate(endDateInclusive, resolution); + result.append(tmp); + _CLDELETE_LCARRAY(tmp); + result.appendChar(_T(']')); + + assertQueryEquals(tc, qp, field, query.getBuffer(), result.getBuffer()); + + query.clear(); + result.clear(); + + query.append(field); + query.append(_T(":{")); + query.append(startDate); + query.append(_T(" TO ")); + query.append(endDate); + query.appendChar(_T('}')); + + result.appendChar(_T('{')); + tmp = getDate(startDate, resolution); + result.append(tmp); + _CLDELETE_LCARRAY(tmp); + result.append(_T(" TO ")); + tmp = getDate(endDate, resolution); + result.append(tmp); + _CLDELETE_LCARRAY(tmp); + result.appendChar(_T('}')); + + assertQueryEquals(tc, qp, field, query.getBuffer(), result.getBuffer()); +} + +TCHAR* getLocalizedDate(int32_t year, int32_t month, int32_t day, bool extendLastDate) { + if (extendLastDate) + return CL_NS(document)::DateTools::getISOFormat(year, month, day, 11, 59, 59, 999); + else + return CL_NS(document)::DateTools::getISOFormat(year, month, day); + +} + +void testDateRange(CuTest* tc) { + + TCHAR* startDate = getLocalizedDate(2002, 1, 1, false); + TCHAR* endDate = getLocalizedDate(2002, 1, 4, false); + const int64_t endDateExpected = CL_NS(document)::DateTools::getTime(2002,1,4,23,59,59,999); + const TCHAR* defaultField = _T("default"); + const TCHAR* monthField = _T("month"); + const TCHAR* hourField = _T("hour"); + + SimpleAnalyzer a; + QueryParser* qp = _CLNEW QueryParser(_T("field"), &a); + + // Don't set any date resolution and verify if DateField is used + assertDateRangeQueryEquals(tc, qp, defaultField, startDate, endDate, + endDateExpected, DateTools::NO_RESOLUTION); + + // set a field specific date resolution + qp->setDateResolution(monthField, DateTools::MONTH_FORMAT); + + // DateField should still be used for defaultField + assertDateRangeQueryEquals(tc, qp, defaultField, startDate, endDate, + endDateExpected, DateTools::NO_RESOLUTION); + + // set default date resolution to MILLISECOND + qp->setDateResolution(DateTools::MILLISECOND_FORMAT); + + // set second field specific date resolution + qp->setDateResolution(hourField, DateTools::HOUR_FORMAT); + + // for this field no field specific date resolution has been set, + // so verify if the default resolution is used + assertDateRangeQueryEquals(tc, qp, defaultField, startDate, endDate, + endDateExpected, DateTools::MILLISECOND_FORMAT); + + // verify if field specific date resolutions are used for these two fields + assertDateRangeQueryEquals(tc, qp, monthField, startDate, endDate, + endDateExpected, DateTools::MONTH_FORMAT); + + assertDateRangeQueryEquals(tc, qp, hourField, startDate, endDate, + endDateExpected, DateTools::HOUR_FORMAT); + + _CLDELETE_LCARRAY(startDate); + _CLDELETE_LCARRAY(endDate); +} + +void testEscaped(CuTest *tc) { + WhitespaceAnalyzer a; + /*assertQueryEquals(tc, _T("\\[brackets"), &a, _T("[brackets") ); + assertQueryEquals(tc, _T("\\\\\\[brackets"), &a, _T("\\[brackets") ); + assertQueryEquals(tc,_T("\\[brackets"), NULL, _T("brackets") );*/ + + assertQueryEquals(tc,_T("\\a"), &a, _T("a") ); + + assertQueryEquals(tc,_T("a\\-b:c"), &a, _T("a-b:c") ); + assertQueryEquals(tc,_T("a\\+b:c"), &a, _T("a+b:c") ); + assertQueryEquals(tc,_T("a\\:b:c"), &a, _T("a:b:c") ); + assertQueryEquals(tc,_T("a\\\\b:c"), &a, _T("a\\b:c") ); + + assertQueryEquals(tc,_T("a:b\\-c"), &a, _T("a:b-c") ); + assertQueryEquals(tc,_T("a:b\\+c"), &a, _T("a:b+c") ); + assertQueryEquals(tc,_T("a:b\\:c"), &a, _T("a:b:c") ); + assertQueryEquals(tc,_T("a:b\\\\c"), &a, _T("a:b\\c") ); + + assertQueryEquals(tc,_T("a:b\\-c*"), &a, _T("a:b-c*") ); + assertQueryEquals(tc,_T("a:b\\+c*"), &a, _T("a:b+c*") ); + assertQueryEquals(tc,_T("a:b\\:c*"), &a, _T("a:b:c*") ); + + assertQueryEquals(tc,_T("a:b\\\\c*"), &a, _T("a:b\\c*") ); + + assertQueryEquals(tc,_T("a:b\\-?c"), &a, _T("a:b-?c") ); + assertQueryEquals(tc,_T("a:b\\+?c"), &a, _T("a:b+?c") ); + assertQueryEquals(tc,_T("a:b\\:?c"), &a, _T("a:b:?c") ); + + assertQueryEquals(tc,_T("a:b\\\\?c"), &a, _T("a:b\\?c") ); + + assertQueryEquals(tc,_T("a:b\\-c~"), &a, _T("a:b-c~0.5") ); + assertQueryEquals(tc,_T("a:b\\+c~"), &a, _T("a:b+c~0.5") ); + assertQueryEquals(tc,_T("a:b\\:c~"), &a, _T("a:b:c~0.5") ); + assertQueryEquals(tc,_T("a:b\\\\c~"), &a, _T("a:b\\c~0.5") ); + + assertQueryEquals(tc,_T("[ a\\- TO a\\+ ]"), &a, _T("[a- TO a+]") ); + assertQueryEquals(tc,_T("[ a\\: TO a\\~ ]"), &a, _T("[a: TO a~]") ); + assertQueryEquals(tc,_T("[ a\\\\ TO a\\* ]"), &a, _T("[a\\ TO a*]") ); + + assertQueryEquals(tc, _T("[\"c\\:\\\\temp\\\\\\~foo0.txt\" TO \"c\\:\\\\temp\\\\\\~foo9.txt\"]"), &a, + _T("[c:\\temp\\~foo0.txt TO c:\\temp\\~foo9.txt]")); + + assertQueryEquals(tc, _T("a\\\\\\+b"), &a, _T("a\\+b")); + + assertQueryEquals(tc, _T("a \\\"b c\\\" d"), &a, _T("a \"b c\" d")); + assertQueryEquals(tc, _T("\"a \\\"b c\\\" d\""), &a, _T("\"a \"b c\" d\"")); + assertQueryEquals(tc, _T("\"a \\+b c d\""), &a, _T("\"a +b c d\"")); + + assertQueryEquals(tc, _T("c\\:\\\\temp\\\\\\~foo.txt"), &a, _T("c:\\temp\\~foo.txt")); + + assertParseException(tc, _T("XY\\")); // there must be a character after the escape char + + // test unicode escaping + assertQueryEquals(tc,_T("a\\u0062c"), &a, _T("abc")); + assertQueryEquals(tc,_T("XY\\u005a"), &a, _T("XYZ")); + assertQueryEquals(tc,_T("XY\\u005A"), &a, _T("XYZ")); + assertQueryEquals(tc,_T("\"a \\\\\\u0028\\u0062\\\" c\""), &a, _T("\"a \\(b\" c\"")); + + assertParseException(tc,_T("XY\\u005G")); // test non-hex character in escaped unicode sequence + assertParseException(tc,_T("XY\\u005")); // test incomplete escaped unicode sequence + + // Tests bug LUCENE-800 + assertQueryEquals(tc,_T("(item:\\\\ item:ABCD\\\\)"), &a, _T("item:\\ item:ABCD\\")); + assertParseException(tc,_T("(item:\\\\ item:ABCD\\\\))")); // unmatched closing paranthesis + assertQueryEquals(tc,_T("\\*"), &a, _T("*")); + assertQueryEquals(tc,_T("\\\\"), &a, _T("\\")); // escaped backslash + + assertParseException(tc,_T("\\")); // a backslash must always be escaped +} + +void testQueryStringEscaping(CuTest *tc) { + WhitespaceAnalyzer a; + + assertEscapedQueryEquals(tc, _T("a-b:c"), &a, _T("a\\-b\\:c")); + assertEscapedQueryEquals(tc,_T("a+b:c"), &a, _T("a\\+b\\:c")); + assertEscapedQueryEquals(tc, _T("a:b:c"), &a, _T("a\\:b\\:c")); + assertEscapedQueryEquals(tc, _T("a\\b:c"), &a, _T("a\\\\b\\:c")); + + assertEscapedQueryEquals(tc,_T("a:b-c"), &a, _T("a\\:b\\-c")); + assertEscapedQueryEquals(tc,_T("a:b+c"), &a, _T("a\\:b\\+c")); + assertEscapedQueryEquals(tc,_T("a:b:c"), &a, _T("a\\:b\\:c")); + assertEscapedQueryEquals(tc,_T("a:b\\c"), &a, _T("a\\:b\\\\c")); + + assertEscapedQueryEquals(tc,_T("a:b-c*"), &a, _T("a\\:b\\-c\\*")); + assertEscapedQueryEquals(tc,_T("a:b+c*"), &a, _T("a\\:b\\+c\\*")); + assertEscapedQueryEquals(tc,_T("a:b:c*"), &a, _T("a\\:b\\:c\\*")); + + assertEscapedQueryEquals(tc,_T("a:b\\\\c*"), &a, _T("a\\:b\\\\\\\\c\\*")); + + assertEscapedQueryEquals(tc,_T("a:b-?c"), &a, _T("a\\:b\\-\\?c")); + assertEscapedQueryEquals(tc,_T("a:b+?c"), &a, _T("a\\:b\\+\\?c")); + assertEscapedQueryEquals(tc,_T("a:b:?c"), &a, _T("a\\:b\\:\\?c")); + + assertEscapedQueryEquals(tc,_T("a:b?c"), &a, _T("a\\:b\\?c")); + + assertEscapedQueryEquals(tc,_T("a:b-c~"), &a, _T("a\\:b\\-c\\~")); + assertEscapedQueryEquals(tc,_T("a:b+c~"), &a, _T("a\\:b\\+c\\~")); + assertEscapedQueryEquals(tc,_T("a:b:c~"), &a, _T("a\\:b\\:c\\~")); + assertEscapedQueryEquals(tc,_T("a:b\\c~"), &a, _T("a\\:b\\\\c\\~")); + + assertEscapedQueryEquals(tc,_T("[ a - TO a+ ]"), NULL, _T("\\[ a \\- TO a\\+ \\]")); + assertEscapedQueryEquals(tc,_T("[ a : TO a~ ]"), NULL, _T("\\[ a \\: TO a\\~ \\]")); + assertEscapedQueryEquals(tc,_T("[ a\\ TO a* ]"), NULL, _T("\\[ a\\\\ TO a\\* \\]")); + + // LUCENE-881 + assertEscapedQueryEquals(tc,_T("|| abc ||"), &a, _T("\\|\\| abc \\|\\|")); + assertEscapedQueryEquals(tc,_T("&& abc &&"), &a, _T("\\&\\& abc \\&\\&")); +} + +void testTabNewlineCarriageReturn(CuTest *tc){ + assertQueryEqualsDOA(tc,_T("+weltbank +worlbank"), NULL, + _T("+weltbank +worlbank")); + + assertQueryEqualsDOA(tc,_T("+weltbank\n+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \n+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \n +worlbank"), NULL, + _T("+weltbank +worlbank")); + + assertQueryEqualsDOA(tc,_T("+weltbank\r+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \r+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \r +worlbank"), NULL, + _T("+weltbank +worlbank")); + + assertQueryEqualsDOA(tc,_T("+weltbank\r\n+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \r\n+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \r\n +worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \r \n +worlbank"), NULL, + _T("+weltbank +worlbank")); + + assertQueryEqualsDOA(tc,_T("+weltbank\t+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \t+worlbank"), NULL, + _T("+weltbank +worlbank")); + assertQueryEqualsDOA(tc,_T("weltbank \t +worlbank"), NULL, + _T("+weltbank +worlbank")); +} + +void testSimpleDAO(CuTest *tc){ + assertQueryEqualsDOA(tc,_T("term term term"), NULL, _T("+term +term +term")); + assertQueryEqualsDOA(tc,_T("term +term term"), NULL, _T("+term +term +term")); + assertQueryEqualsDOA(tc,_T("term term +term"), NULL, _T("+term +term +term")); + assertQueryEqualsDOA(tc,_T("term +term +term"), NULL, _T("+term +term +term")); + assertQueryEqualsDOA(tc,_T("-term term term"), NULL, _T("-term +term +term")); +} + +void testBoost(CuTest *tc){ + const TCHAR* stopWords[] = {_T("on"), NULL}; + StandardAnalyzer* oneStopAnalyzer = _CLNEW StandardAnalyzer(reinterpret_cast(&stopWords)); + QueryParser* qp = _CLNEW QueryParser(_T("field"), oneStopAnalyzer); + Query* q = qp->parse(_T("on^1.0")); + CLUCENE_ASSERT(q != NULL); + _CLLDELETE(q); + q = qp->parse(_T("\"hello\"^2.0")); + CLUCENE_ASSERT(q != NULL); + CLUCENE_ASSERT(q->getBoost() == 2.0f); + _CLLDELETE(q); + q = qp->parse(_T("hello^2.0")); + CLUCENE_ASSERT(q != NULL); + CLUCENE_ASSERT(q->getBoost() == 2.0f); + _CLLDELETE(q); + q = qp->parse(_T("\"on\"^1.0")); + CLUCENE_ASSERT(q != NULL); + _CLLDELETE(q); + _CLLDELETE(qp); + _CLLDELETE(oneStopAnalyzer); + + StandardAnalyzer a; + QueryParser* qp2 = _CLNEW QueryParser(_T("field"), &a); + q = qp2->parse(_T("the^3")); + // "the" is a stop word so the result is an empty query: + CLUCENE_ASSERT(q != NULL); + TCHAR* tmp = q->toString(); + CLUCENE_ASSERT( _tcscmp(tmp, _T("")) == 0 ); + _CLDELETE_LCARRAY(tmp); + CLUCENE_ASSERT(1.0f == q->getBoost()); + _CLLDELETE(q); + _CLLDELETE(qp2); +} + +/// TODO: Port tests starting from assertParseException + +void testMatchAllDocs(CuTest *tc) { + WhitespaceAnalyzer a; + QueryParser* qp = _CLNEW QueryParser(_T("field"), &a); + assertCorrectQuery(tc,qp->parse(_T("*:*")),"MatchAllDocsQuery",true); + assertCorrectQuery(tc,qp->parse(_T("(*:*)")),"MatchAllDocsQuery",true); + + BooleanQuery* bq = (BooleanQuery*)qp->parse(_T("+*:* -*:*")); + BooleanClause** clauses = _CL_NEWARRAY(BooleanClause*, bq->getClauseCount() + 1); + bq->getClauses(clauses); + assertCorrectQuery(tc, clauses[0]->getQuery(), "MatchAllDocsQuery"); + assertCorrectQuery(tc, clauses[1]->getQuery(), "MatchAllDocsQuery"); + _CLDELETE_LARRAY(clauses); + _CLLDELETE(bq); + _CLLDELETE(qp); +} + +// Tracker Bug ID 2870826 by Veit Jahns +void testDefaultField(CuTest* tc){ + WhitespaceAnalyzer a; + QueryParser* qp = _CLNEW QueryParser(_T("field"), &a); + Query* bq = qp->parse(_T("term1 author:term2 term3")); + CLUCENE_ASSERT( bq != NULL ); + TCHAR* s = bq->toString(_T("field")); + _CLLDELETE(bq); + if ( _tcscmp(s,_T("term1 author:term2 term3")) != 0 ) + CuFail(tc, _T("FAILED Query /term1 author:term2 term3/ yielded /%s/, expecting term1 author:term2 term3\n"), s); + _CLDELETE_LCARRAY(s); + + bq = qp->parse(_T("term1 *:term2 term3")); + s = bq->toString(_T("field")); + if ( _tcscmp(s,_T("term1 *:term2 term3")) != 0 ) + CuFail(tc, _T("FAILED Query /term1 *:term2 term3/ yielded /%s/, expecting term1 *:term2 term3\n"), s); + + _CLDELETE_LCARRAY(s); + _CLLDELETE(bq); + + _CLLDELETE(qp); +} + +CuSuite *testQueryParser(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Query Parser Test")); + + SUITE_ADD_TEST(suite, testSimple); + SUITE_ADD_TEST(suite, testPunct); + SUITE_ADD_TEST(suite, testSlop); + SUITE_ADD_TEST(suite, testNumber); + SUITE_ADD_TEST(suite, testWildcard); + SUITE_ADD_TEST(suite, testLeadingWildcardType); + SUITE_ADD_TEST(suite, testQPA); + SUITE_ADD_TEST(suite, testRange); + //SUITE_ADD_TEST(suite, testDateRange); + SUITE_ADD_TEST(suite, testEscaped); + SUITE_ADD_TEST(suite, testQueryStringEscaping); + SUITE_ADD_TEST(suite, testTabNewlineCarriageReturn); + SUITE_ADD_TEST(suite, testSimpleDAO); + SUITE_ADD_TEST(suite, testBoost); + + SUITE_ADD_TEST(suite, testMatchAllDocs); + + SUITE_ADD_TEST(suite, testDefaultField); + + return suite; +} +// EOF diff --git a/src/test/search/BaseTestRangeFilter.cpp b/src/test/search/BaseTestRangeFilter.cpp new file mode 100644 index 00000000000..f7cb8fab52f --- /dev/null +++ b/src/test/search/BaseTestRangeFilter.cpp @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "BaseTestRangeFilter.h" + +#include + +static const size_t getMaxIntLength() +{ + TCHAR buf[40]; + _itot(std::numeric_limits::max(), buf, 10); + return _tcslen(buf); +} + +BaseTestRangeFilter::BaseTestRangeFilter(CuTest* _tc) + : index(new RAMDirectory()) + , maxR(std::numeric_limits::min()), minR(std::numeric_limits::max()) + , minId(0), maxId(10000), intLength(getMaxIntLength()) + , tc(_tc) +{ + srand ( 101 ); // use a set seed to test is deterministic + build(); +} + +BaseTestRangeFilter::~BaseTestRangeFilter() +{ + index->close(); + _CLLDECDELETE(index); +} + +std::tstring BaseTestRangeFilter::pad(int n) +{ + std::tstring b; + if (n < 0) { + b = _T("-"); + n = std::numeric_limits::max() + n + 1; + } + else + b = _T("0"); + + TCHAR buf[40]; + _itot(n, buf, 10); + for (size_t i = _tcslen(buf); i <= intLength; i++) { + b += _T("0"); + } + b += buf; + + return b; +} + +void BaseTestRangeFilter::build() +{ + try + { + /* build an index */ + SimpleAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter(index, + &a, T); + + for (int32_t d = minId; d <= maxId; d++) { + Document doc; + std::tstring paddedD = pad(d); + doc.add(* _CLNEW Field(_T("id"),paddedD.c_str(), Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + int r= rand(); + if (maxR < r) { + maxR = r; + } + if (r < minR) { + minR = r; + } + std::tstring paddedR = pad(r); + doc.add( * _CLNEW Field(_T("rand"),paddedR.c_str(), Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + doc.add( * _CLNEW Field(_T("body"),_T("body"), Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + writer->addDocument(&doc); + } + + writer->optimize(); + writer->close(); + _CLLDELETE(writer); + } catch (CLuceneError&) { + _CLTHROWA(CL_ERR_Runtime, "can't build index"); + } +} + +void BaseTestRangeFilter::testPad() +{ + const int32_t tests[] = { + -9999999, -99560, -100, -3, -1, 0, 3, 9, 10, 1000, 999999999 + }; + const size_t testsLen = 11; + + for (size_t i = 0; i < testsLen - 1; i++) { + const int32_t a = tests[i]; + const int32_t b = tests[i+1]; + const TCHAR* aa = pad(a).c_str(); + const TCHAR* bb = pad(b).c_str(); + + StringBuffer label(50); + label << a << _T(':') << aa << _T(" vs ") << b << _T(':') << bb; + + std::tstring tmp(_T("length of ")); + tmp += label.getBuffer(); + assertEqualsMsg(tmp.c_str(), _tcslen(aa), _tcslen(bb)); + + tmp = _T("compare less than "); + tmp += label.getBuffer(); + assertTrueMsg(tmp.c_str(), _tcscmp(aa, bb) < 0); + } +} + +// EOF diff --git a/src/test/search/BaseTestRangeFilter.h b/src/test/search/BaseTestRangeFilter.h new file mode 100644 index 00000000000..0b0640387c1 --- /dev/null +++ b/src/test/search/BaseTestRangeFilter.h @@ -0,0 +1,47 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_BaseTestRangeFilter +#define _lucene_search_BaseTestRangeFilter + +#include "test.h" + +class BaseTestRangeFilter +{ +public: + static const bool F = false; + static const bool T = true; + + RAMDirectory* index; + + int32_t maxR; + int32_t minR; + + int32_t minId; + int32_t maxId; + + const size_t intLength; + + CuTest* tc; + + BaseTestRangeFilter(CuTest* _tc); + virtual ~BaseTestRangeFilter(); + + /** + * a simple padding function that should work with any int + */ + std::tstring pad(int32_t n); + +private: + void build(); + +public: + void testPad(); +}; + + +#endif + diff --git a/src/test/search/CheckHits.cpp b/src/test/search/CheckHits.cpp new file mode 100644 index 00000000000..9170b4ca633 --- /dev/null +++ b/src/test/search/CheckHits.cpp @@ -0,0 +1,542 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CheckHits.h" +#include "QueryUtils.h" + + +///////////////////////////////////////////////////////////////////////////// +float_t CheckHits::EXPLAIN_SCORE_TOLERANCE_DELTA = 0.00005f; + + +///////////////////////////////////////////////////////////////////////////// +/** +* Asserts that the score explanation for every document matching a +* query corresponds with the true score. +* +* NOTE: this HitCollector should only be used with the Query and Searcher +* specified at when it is constructed. +* +* @see CheckHits#verifyExplanation +*/ +class ExplanationAsserter : public HitCollector +{ +private: + Query * q; + Searcher * s; + TCHAR * d; + bool deep; + CuTest * tc; + +public: + /** Constructs an instance which does shallow tests on the Explanation */ + ExplanationAsserter( Query * q, const TCHAR * defaultFieldName, Searcher * s, CuTest * tc ) + { + this->q = q; + this->s = s; + this->d = q->toString( defaultFieldName ); + this->deep = false; + this->tc = tc; + } + + ExplanationAsserter( Query * q, const TCHAR * defaultFieldName, Searcher * s, bool deep, CuTest * tc ) + { + this->q = q; + this->s = s; + this->d = q->toString( defaultFieldName ); + this->deep = deep; + this->tc = tc; + } + + virtual ~ExplanationAsserter() + { + _CLDELETE_LARRAY( d ); + } + + void collect( const int32_t doc, const float_t score ) + { + Explanation exp; + s->explain( q, doc, &exp ); + + if( exp.getDetailsLength() == 0 ) // ToDo: Fix IndexSearcher::explain() method + { + StringBuffer buffer; + buffer.append( _T( "Explanation of [[" )); + buffer.append( d ); + buffer.append( _T( "]] for #" )); + buffer.appendInt( doc ); + buffer.append( _T( " is null" )); + assertTrueMsg( buffer.getBuffer(), false ); + } + + assertTrue( exp.getDetailsLength() == 1 ); + CheckHits::verifyExplanation( tc, d, doc, score, deep, exp.getDetail( 0 ) ); // ToDo: Fix IndexSearcher::explain() method + } +}; + +///////////////////////////////////////////////////////////////////////////// +/** +* an IndexSearcher that implicitly checks hte explanation of every match +* whenever it executes a search. +* +* @see ExplanationAsserter +*/ +class ExplanationAssertingSearcher : public CL_NS(search)::IndexSearcher +{ +private: + CuTest * tc; +public: + ExplanationAssertingSearcher( Directory * d, CuTest * tc ) : IndexSearcher( d ) { this->tc = tc; } + ExplanationAssertingSearcher( IndexReader * r, CuTest * tc ) : IndexSearcher( r ) { this->tc = tc; } + virtual ~ExplanationAssertingSearcher() {} + + Hits * search( Query * query, Filter * filter ) + { checkExplanations( query ); return IndexSearcher::search( query, filter ); } + + Hits * search( Query * query, Sort * sort ) + { checkExplanations( query ); return IndexSearcher::search( query, sort ); } + + Hits * search( Query * query, Filter * filter, Sort * sort ) + { checkExplanations( query ); return IndexSearcher::search( query, filter, sort ); } + + TopFieldDocs * _search( Query * query, Filter * filter, int32_t n, Sort * sort ) + { checkExplanations( query ); return IndexSearcher::_search( query, filter, n, sort ); } + + void _search( Query * query, HitCollector * results ) + { checkExplanations( query ); IndexSearcher::_search( query, NULL, results ); } + + void _search( Query * query, Filter * filter, HitCollector * results ) + { checkExplanations( query ); IndexSearcher::_search( query, filter, results ); } + + TopDocs * search_( Query * query, Filter * filter, int32_t n ) + { checkExplanations( query ); return IndexSearcher::_search( query, filter, n ); } + +protected: + void checkExplanations( Query * q ) + { IndexSearcher::_search( q, NULL, _CLNEW ExplanationAsserter( q, NULL, this, tc )); } +}; + +///////////////////////////////////////////////////////////////////////////// +class HitSetCollector : public HitCollector +{ +public: + set actual; + +public: + HitSetCollector() : HitCollector() {}; + virtual ~HitSetCollector() {}; + + virtual void collect( const int32_t doc, const float_t score ) { actual.insert( doc ); } +}; + + +///////////////////////////////////////////////////////////////////////////// +bool CheckHits::setEquals( set& s1, set& s2 ) +{ + bool bEquals = ( s1.size() == s2.size() ); + + set::iterator iS1 = s1.begin(); + set::iterator iS2 = s2.begin(); + for( ; bEquals && ( iS1 != s1.end() ); iS1++, iS2++ ) + bEquals = ( *iS1 == *iS2 ); + + return bEquals; +} + +bool CheckHits::stringEndsWith( const TCHAR* tszStr, const TCHAR * tszEnd ) +{ + if( ! tszStr || ! tszEnd ) + return false; + + size_t lenStr = _tcslen( tszStr ); + size_t lenEnd = _tcslen( tszEnd ); + if( lenEnd > lenStr ) + return false; + + const TCHAR * tszReadEnd = tszEnd + lenEnd; + const TCHAR * tszReadStr = tszStr + lenStr; + while( tszEnd != tszReadEnd ) + { + if( *tszReadEnd-- != *tszReadStr-- ) + return false; + } + + return true; +} + +void CheckHits::checkNoMatchExplanations( CuTest* tc, Query * q, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ) +{ + TCHAR * d = q->toString( defaultFieldName ); + + set ignore; + for( size_t i = 0; i < resultsCount; i++ ) + ignore.insert( results[ i ] ); + + int32_t maxDoc = searcher->maxDoc(); + for( int32_t doc = 0; doc < maxDoc; doc++ ) + { + if( ignore.find( doc ) != ignore.end() ) + continue; + + Explanation exp; + searcher->explain( q, doc, &exp ); + + if( 0.0f != exp.getValue() ) + { + StringBuffer buffer; + TCHAR * tszExp = exp.toString(); + + buffer.append( _T( "Explanation of [[" )); + buffer.append( d ); + buffer.append( _T( "]] for #" )); + buffer.appendInt( doc ); + buffer.append( _T( " doesn't indicate non-match: " )); + + buffer.append( tszExp ); + _CLDELETE_LARRAY( tszExp ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + } + + _CLDELETE_LARRAY( d ); +} + +void CheckHits::checkHitCollector( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ) +{ + set correct; + for( size_t i = 0; i < resultsCount; i++ ) + correct.insert( results[ i ] ); + + HitSetCollector hitSet; + searcher->_search( query, &hitSet ); + + if( ! setEquals( correct, hitSet.actual )) + { + TCHAR * tszQry = query->toString( defaultFieldName ); + assertTrueMsg( tszQry, false ); + _CLDELETE_LARRAY( tszQry ); + } + + QueryUtils::check( tc, query, searcher ); +} + +///////////////////////////////////////////////////////////////////////////// +void CheckHits::checkHits( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ) +{ + if( searcher->getObjectName() == IndexSearcher::getClassName() ) + QueryUtils::check( tc, query, (IndexSearcher *) searcher ); + +// Hits * hits = searcher->search( query ); +// +// set correct; +// for( size_t i = 0; i < resultsCount; i++ ) +// correct.insert( results[ i ] ); +// +// set actual; +// for( size_t i = 0; i < hits->length(); i++ ) +// actual.insert( hits->id( i )); +// +// _CLLDELETE( hits ); +// +// if( ! setEquals( correct, actual )) +// { +// TCHAR * tszQry = query->toString( defaultFieldName ); +// assertTrueMsg( tszQry, false ); +// _CLDELETE_LARRAY( tszQry ); +// } +// +// QueryUtils::check( tc, query, searcher ); +} + +void CheckHits::checkDocIds( CuTest* tc, const TCHAR * mes, int32_t * results, size_t resultsCount, Hits * hits ) +{ + StringBuffer buffer; + + if( resultsCount != hits->length() ) + { + buffer.append( mes ); + buffer.append( _T( " nr of hits" )); + assertTrueMsg( buffer.getBuffer(), false ); + } + + for( size_t i = 0; i < resultsCount; i++ ) + { + if( results[ i ] != hits->id( i )) + { + buffer.clear(); + buffer.append( mes ); + buffer.append( _T( " doc nrs for hit " )); + buffer.appendInt( i ); + assertTrueMsg( buffer.getBuffer(), false ); + } + } +} + +void CheckHits::checkHitsQuery( CuTest* tc, Query * query, Hits * hits1, Hits * hits2, int32_t * results, size_t resultsCount ) +{ + checkDocIds( tc, _T( "hits1" ), results, resultsCount, hits1 ); + checkDocIds( tc, _T( "hits2" ), results, resultsCount, hits2 ); + checkEqual( tc, query, hits1, hits2 ); +} + +void CheckHits::checkEqual( CuTest* tc, Query * query, Hits * hits1, Hits * hits2 ) +{ + float_t scoreTolerance = 1.0e-6f; + assertTrueMsg( _T( "Unequal lengths of supplied hits." ), hits1->length() == hits2->length() ); + + for( size_t i = 0; i < hits1->length(); i++ ) + { + if( hits1->id( i ) != hits2->id( i )) + { + StringBuffer buffer; + buffer.append( _T( "Hit " )); + buffer.appendInt( i ); + buffer.append( _T( " docnumbers don't match\n" )); + appendHits( buffer, hits1, hits2, 0, 0 ); + buffer.append( _T( "for query:" )); + TCHAR * tszQry = query->toString(); + buffer.append( tszQry ); + _CLDELETE_LARRAY( tszQry ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + + float_t sd = hits1->score( i ) - hits2->score( i ); + if ( sd < 0 ) sd *= -1; + + if(( hits1->id( i ) != hits2->id( i )) + || sd > scoreTolerance ) + { + StringBuffer buffer; + buffer.append( _T( "Hit " )); + buffer.appendInt( i ); + buffer.append( _T( ", doc nrs " )); + buffer.appendInt( hits1->id( i )); + buffer.append( _T( " and " )); + buffer.appendInt( hits2->id( i )); + buffer.append( _T( "\nunequal : " )); + buffer.appendFloat( hits1->score( i ), 2 ); + buffer.append( _T( "\n and: " )); + buffer.appendFloat( hits2->score( i ), 2 ); + buffer.append( _T( "\nfor query:" )); + TCHAR *tszQry = query->toString(); + buffer.append( tszQry ); + _CLDELETE_LARRAY( tszQry ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + } +} + +void CheckHits::appendHits( StringBuffer& buffer, Hits * hits1, Hits * hits2, size_t start, size_t end ) +{ + size_t len1 = hits1 ? hits1->length() : 0; + size_t len2 = hits2 ? hits2->length() : 0; + if( end <= 0 ) + end = len1 < len2 ? len2 : len1; // max + + buffer.append( _T( "Hits length1=" )); + buffer.appendInt( len1 ); + buffer.append( _T( "\tlength2=" )); + buffer.appendInt( len2 ); + + buffer.append( _T( "\n" )); + for( size_t i = start; i < end; i++ ) + { + buffer.append( _T( "hit=" )); + buffer.appendInt( i ); + buffer.append( _T( ":" )); + if( i < len1 ) + { + buffer.append( _T( " doc" )); + buffer.appendInt( hits1->id( i ) ); + buffer.append( _T( "=" )); + buffer.appendFloat( hits1->score( i ), 2); + } + else + { + buffer.append( _T( " " )); + } + + buffer.append( _T( ",\t" )); + if( i < len2 ) + { + buffer.append( _T( " doc" )); + buffer.appendInt( hits2->id( i )); + buffer.append( _T( "= ")); + buffer.appendFloat( hits2->score( i ), 2 ); + } + + buffer.append( _T( "\n" )); + } +} + +void CheckHits::appendTopdocs( StringBuffer& buffer, TopDocs * docs, size_t start, size_t end ) +{ + buffer.append( _T( "TopDocs totalHits=" )); + buffer.appendInt( docs->totalHits ); + buffer.append( _T( " top=" )); + buffer.appendInt( docs->scoreDocsLength ); + buffer.append( _T( "\n" )); + if( end <= 0 ) + end = docs->scoreDocsLength; + else + end = end < (size_t)docs->scoreDocsLength ? end : (size_t)docs->scoreDocsLength; // min + + for( size_t i = start; i < end; i++ ) + { + buffer.append( _T( "\t" )); + buffer.appendInt( i ); + buffer.append( _T( ") doc=" )); + buffer.appendInt( docs->scoreDocs[ i ].doc ); + buffer.append( _T( "\tscore=" )); + buffer.appendFloat( docs->scoreDocs[ i ].score, 2 ); + buffer.append( _T( "\n" )); + } +} + +void CheckHits::checkExplanations( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher ) +{ + checkExplanations( tc, query, defaultFieldName, searcher, false ); +} + +void CheckHits::checkExplanations( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, bool deep ) +{ + ExplanationAsserter asserter( query, defaultFieldName, searcher, deep, tc ); + searcher->_search( query, &asserter ); +} + + +void CheckHits::verifyExplanation( CuTest* tc, const TCHAR * q, int32_t doc, float_t score, bool deep, Explanation * expl ) +{ + StringBuffer buffer; + TCHAR * tmp; + + float_t value = expl->getValue(); + + if( ( score > value ? score - value : value - score ) > EXPLAIN_SCORE_TOLERANCE_DELTA ) + { + buffer.append( q ); + buffer.append( _T( ": score(doc=" )); + buffer.appendInt( doc ); + buffer.append( _T( ")=" )); + buffer.appendFloat( score, 2 ); + buffer.append( _T( " != explanationScore=" )); + buffer.appendFloat( value, 2 ); + buffer.append( _T( " Explanation: " )); + tmp = expl->toString(); + buffer.append( tmp ); + _CLDELETE_LARRAY( tmp ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + + if( ! deep ) + return; + + Explanation ** detail = _CL_NEWARRAY( Explanation *, expl->getDetailsLength() + 1 ); + expl->getDetails( detail ); + if( expl->getDetailsLength() > 0 ) + { + if( expl->getDetailsLength() == 1 ) + { + // simple containment, no matter what the description says, + // just verify contained expl has same score + verifyExplanation( tc, q, doc, score, deep, detail[ 0 ] ); + } + else + { + // explanation must either: + // - end with one of: "product of:", "sum of:", "max of:", or + // - have "max plus times others" (where is float). + float_t x = 0; + const TCHAR* descr = expl->getDescription(); + TCHAR* descrLwr = STRDUP_TtoT( descr ); + _tcslwr( descrLwr ); + + bool productOf = stringEndsWith( descr, _T( "product of:" )); + bool sumOf = stringEndsWith( descr, _T( "sum of:" )); + bool maxOf = stringEndsWith( descr, _T( "max of:" )); + bool maxTimesOthers = false; + if( ! ( productOf || sumOf || maxOf )) + { + // maybe 'max plus x times others' + const TCHAR * k1 = _tcsstr( descr, _T( "max plus " )); + if( k1 ) + { + k1 += 9; // "max plus ".length(); + const TCHAR * k2 = _tcsstr( k1, _T( " " )); + + x = _tcstod( k1, NULL ); // Float::parseFloat( descr.substring(k1,k2).trim()); + + if( k2 && 0 == _tcscmp( k2, _T( " times others of:" ))) + maxTimesOthers = true; + } + } + + if( ! ( productOf || sumOf || maxOf || maxTimesOthers )) + { + buffer.clear(); + buffer.append( q ); + buffer.append( _T( ": multi valued explanation description=\"" )); + buffer.append( descrLwr ); + buffer.append( _T( "\" must be 'max of plus x times others' or end with 'product of' or 'sum of:' or 'max of:' - " )); + tmp = expl->toString(); + buffer.append( tmp ); + _CLDELETE_LARRAY( tmp ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + + float_t sum = 0; + float_t product = 1; + float_t max = 0; + for( size_t i = 0; i < expl->getDetailsLength(); i++ ) + { + float_t dval = detail[ i ]->getValue(); + verifyExplanation( tc, q, doc, dval, deep, detail[ i ] ); + product *= dval; + sum += dval; + max = max > dval ? max : dval; // max + } + float_t combined = 0; + + if( productOf ) + combined = product; + else if( sumOf ) + combined = sum; + else if( maxOf ) + combined = max; + else if( maxTimesOthers ) + combined = max + x * (sum - max); + else + { + assertTrueMsg( _T( "should never get here!" ), false ); + } + + if( ( combined > value ? combined - value : value - combined ) > EXPLAIN_SCORE_TOLERANCE_DELTA ) + { + buffer.clear(); + buffer.append( q ); + buffer.append( _T( ": actual subDetails combined==" )); + buffer.appendFloat( combined, 2 ); + buffer.append( _T( " != value=" )); + buffer.appendFloat( value, 2 ); + buffer.append( _T( " Explanation: " )); + tmp = expl->toString(); + buffer.append( tmp ); + _CLDELETE_LARRAY( tmp ); + + assertTrueMsg( buffer.getBuffer(), false ); + } + + _CLDELETE_LARRAY( descrLwr ); + } + } + + _CLDELETE_ARRAY_ALL( detail ); +} diff --git a/src/test/search/CheckHits.h b/src/test/search/CheckHits.h new file mode 100644 index 00000000000..5cd563f186a --- /dev/null +++ b/src/test/search/CheckHits.h @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_CheckHits +#define _lucene_search_CheckHits + +#include "test.h" + +class CheckHits +{ +public: + /** + * Some explains methods calculate their values though a slightly + * different order of operations from the actaul scoring method ... + * this allows for a small amount of variation + */ + static float_t EXPLAIN_SCORE_TOLERANCE_DELTA; + +public: + /** + * Tests that all documents up to maxDoc which are *not* in the + * expected result set, have an explanation which indicates no match + * (ie: Explanation value of 0.0f) + */ + static void checkNoMatchExplanations( CuTest* tc, Query * q, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ); + + /** + * Tests that a query matches the an expected set of documents using a + * HitCollector. + * + *

+ * Note that when using the HitCollector API, documents will be collected + * if they "match" regardless of what their score is. + *

+ * @param query the query to test + * @param searcher the searcher to test the query against + * @param defaultFieldName used for displaing the query in assertion messages + * @param results a list of documentIds that must match the query + * @see Searcher#search(Query,HitCollector) + * @see #checkHits + */ + static void checkHitCollector( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ); + + /** + * Tests that a query matches the an expected set of documents using Hits. + * + *

+ * Note that when using the Hits API, documents will only be returned + * if they have a positive normalized score. + *

+ * @param query the query to test + * @param searcher the searcher to test the query against + * @param defaultFieldName used for displaing the query in assertion messages + * @param results a list of documentIds that must match the query + * @see Searcher#search(Query) + * @see #checkHitCollector + */ + static void checkHits( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, int32_t * results, size_t resultsCount ); + + /** Tests that a Hits has an expected order of documents */ + static void checkDocIds( CuTest* tc, const TCHAR * mes, int32_t * results, size_t resultsCount, Hits * hits ); + + /** Tests that two queries have an expected order of documents, + * and that the two queries have the same score values. + */ + static void checkHitsQuery( CuTest* tc, Query * query, Hits * hits1, Hits * hits2, int32_t * results, size_t resultsCount ); + + static void checkEqual( CuTest* tc, Query * query, Hits * hits1, Hits * hits2 ); + static void appendHits( StringBuffer& buffer, Hits * hits1, Hits * hits2, size_t start, size_t end ); + static void appendTopdocs( StringBuffer& buffer, TopDocs * docs, size_t start, size_t end ); + + /** + * Asserts that the explanation value for every document matching a + * query corresponds with the true score. + * + * @see ExplanationAsserter + * @see #checkExplanations(Query, String, Searcher, boolean) for a + * "deep" testing of the explanation details. + * + * @param query the query to test + * @param searcher the searcher to test the query against + * @param defaultFieldName used for displaing the query in assertion messages + */ + static void checkExplanations( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher ); + + /** + * Asserts that the explanation value for every document matching a + * query corresponds with the true score. Optionally does "deep" + * testing of the explanation details. + * + * @see ExplanationAsserter + * @param query the query to test + * @param searcher the searcher to test the query against + * @param defaultFieldName used for displayng the query in assertion messages + * @param deep indicates whether a deep comparison of sub-Explanation details should be executed + */ + static void checkExplanations( CuTest* tc, Query * query, const TCHAR * defaultFieldName, Searcher * searcher, bool deep ); + + /** + * Assert that an explanation has the expected score, and optionally that its + * sub-details max/sum/factor match to that score. + * + * @param q String representation of the query for assertion messages + * @param doc Document ID for assertion messages + * @param score Real score value of doc with query q + * @param deep indicates whether a deep comparison of sub-Explanation details should be executed + * @param expl The Explanation to match against score + */ + static void verifyExplanation( CuTest* tc, const TCHAR * q, int32_t doc, float_t score, bool deep, Explanation * expl ); + + static bool setEquals( set& s1, set& s2 ); + static bool stringEndsWith( const TCHAR* tszStr, const TCHAR * tszEnd ); + +}; + +#endif + diff --git a/src/test/search/MockHitCollector.h b/src/test/search/MockHitCollector.h new file mode 100644 index 00000000000..85129f314c2 --- /dev/null +++ b/src/test/search/MockHitCollector.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2011 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_search_MockHitCollector +#define _lucene_search_MockHitCollector + +#include "CLucene/search/SearchHeader.h" + +CL_NS_DEF(search) + +class MockHitCollector : public HitCollector +{ +public: + + MockHitCollector() : HitCollector(), collectCalls(0) {} + + virtual ~MockHitCollector() {} + + virtual void collect(const int32_t doc, const float_t score) + { + collectCalls++; + } + + int32_t getCollectCalls() const + { + return collectCalls; + } + +private: + + int32_t collectCalls; +}; + +CL_NS_END + +#endif // _lucene_search_MockHitCollector diff --git a/src/test/search/MockScorer.h b/src/test/search/MockScorer.h new file mode 100644 index 00000000000..0c2aeb2bd4d --- /dev/null +++ b/src/test/search/MockScorer.h @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2011 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_search_MockScorer +#define _lucene_search_MockScorer + +#include "CLucene/search/Scorer.h" + +CL_NS_DEF(search) + +class MockScorer : public Scorer +{ +public: + + MockScorer(Similarity* similarity) : + Scorer(similarity), nextCalls(0), skipToCalls(0), scoreHitCollectorCalls(0), scoreCalls(0) + { + /* empty */ + } + + virtual bool next() + { + nextCalls++; + return false; + } + + virtual int32_t doc() const + { + return 0; + } + + virtual bool skipTo(int32_t target) + { + skipToCalls++; + return true; + } + + virtual Explanation* explain(int32_t doc) + { + return NULL; + } + + virtual TCHAR* toString() + { + return NULL; + } + + virtual float_t score() + { + scoreCalls++; + return 0; + } + + virtual void score(HitCollector* hc) + { + scoreHitCollectorCalls++; + } + + int32_t getNextCalls() const + { + return nextCalls; + } + + int32_t getSkipToCalls() const + { + return skipToCalls; + } + + int32_t getScoreCalls() const + { + return scoreCalls; + } + + int32_t getScoreHitCollectorCalls() const + { + return scoreHitCollectorCalls; + } + +private: + + int32_t nextCalls; + int32_t skipToCalls; + int32_t scoreHitCollectorCalls; + int32_t scoreCalls; +}; + +CL_NS_END + +#endif // _lucene_search_MockScorer diff --git a/src/test/search/QueryUtils.cpp b/src/test/search/QueryUtils.cpp new file mode 100644 index 00000000000..7fe94a80d07 --- /dev/null +++ b/src/test/search/QueryUtils.cpp @@ -0,0 +1,376 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "QueryUtils.h" +#include "CLucene/search/Scorer.h" +#include "CheckHits.h" + +///////////////////////////////////////////////////////////////////////////// +int32_t QueryUtils::skip_op = 0; +int32_t QueryUtils::next_op = 1; +float_t QueryUtils::maxDiff = 1e-5f; + + +///////////////////////////////////////////////////////////////////////////// +class WhackyQuery : public CL_NS(search)::Query +{ +public: + WhackyQuery() {}; + virtual ~WhackyQuery() {} + + Query * clone() const + { + return _CLNEW WhackyQuery(); + } + + static const char * getClassName() + { + return "WhackyQuery"; + } + + const char * getObjectName() const + { + return getClassName(); + } + + TCHAR* toString(const TCHAR* field) const + { + return STRDUP_TtoT( _T( "My Whacky Query" )); + } + + bool equals(Query* other) const + { + if( this == other ) return true; + if( other == NULL || !( other->instanceOf( WhackyQuery::getClassName() ))) + return false; + + return true; + } + + size_t hashCode() const + { + size_t result = Similarity::floatToByte( getBoost() ) ^ 0x97AF937F; + return result; + } +}; + +///////////////////////////////////////////////////////////////////////////// +class QueryUtilsHitCollector1 : public CL_NS(search)::HitCollector +{ +public: + int32_t * order; + int32_t * opidx; + int32_t orderLength; + int32_t * sdoc; + Scorer * scorer; + Query * q; + CuTest * tc; + +public: + void collect( const int32_t doc, const float_t score ) + { + int32_t op = order[ (opidx[ 0 ]++ ) % orderLength ]; + bool more = ( op == QueryUtils::skip_op ) ? scorer->skipTo( sdoc[ 0 ] + 1 ) : scorer->next(); + sdoc[ 0 ] = scorer->doc(); + float_t scorerScore = scorer->score(); + float_t scorerScore2 = scorer->score(); + float_t scoreDiff = score > scorerScore ? score - scorerScore : scorerScore - score; + float_t scorerDiff = scorerScore2 > scorerScore2 ? scorerScore2 - scorerScore : scorerScore - scorerScore2; + if( ! more || doc != sdoc[ 0 ] || scoreDiff > QueryUtils::maxDiff || scorerDiff > QueryUtils::maxDiff ) + { + StringBuffer buffer; + buffer.append( _T( "ERROR matching docs:\n\t" )); + + buffer.append( doc != sdoc[ 0 ] ? _T( "--> doc=" ) : _T( "doc=" )); + buffer.appendInt( sdoc[ 0 ] ); + + buffer.append( ! more ? _T( "\n\t--> tscorer.more=" ) : _T( "\n\ttscorer.more=" )); + buffer.appendBool( more ); + + buffer.append( scoreDiff > QueryUtils::maxDiff ? _T( "\n\t--> scorerScore=" ) : _T( "\n\tscorerScore=" )); + buffer.appendFloat( scorerScore, 2 ); + buffer.append( _T( " scoreDiff=" )); + buffer.appendFloat( scoreDiff, 2 ); + buffer.append( _T( " maxDiff=" )); + buffer.appendFloat( QueryUtils::maxDiff, 2 ); + + buffer.append( scorerDiff > QueryUtils::maxDiff ? _T( "\n\t--> scorerScore2=" ) : _T( "\n\tscorerScore2=" )); + buffer.appendFloat( scorerScore2, 2 ); + buffer.append( _T( " scorerDiff=" )); + buffer.appendFloat( scorerDiff, 2 ); + + buffer.append( _T( "\n\thitCollector.doc=" )); + buffer.appendInt( doc ); + buffer.append( _T( " score=" )); + buffer.appendFloat( score, 2 ); + + buffer.append( _T( "\n\t Scorer=" )); + TCHAR * tmp = scorer->toString(); + buffer.append( tmp ); + _CLDELETE_LARRAY( tmp ); + + buffer.append( _T( "\n\t Query=" )); + tmp = q->toString(); + buffer.append( tmp ); + _CLDELETE_ARRAY( tmp ); + + buffer.append( _T( "\n\t Order=" )); + for( int32_t i = 0; i < orderLength; i++) + buffer.append( order[ i ] == QueryUtils::skip_op ? _T( " skip()" ): _T( " next()" )); + + buffer.append( _T( "\n\t Op=" )); + buffer.append( op == QueryUtils::skip_op ? _T( " skip()" ) : _T( " next()" )); + + assertTrueMsg( buffer.getBuffer(), false ); + } + } +}; + +///////////////////////////////////////////////////////////////////////////// +class QueryUtilsHitCollector2 : public CL_NS(search)::HitCollector +{ +public: + int32_t * lastDoc; + Query * q; + IndexSearcher * s; + CuTest * tc; + +public: + void collect( const int32_t doc, const float_t score ) + { + for( int32_t i = lastDoc[ 0 ] + 1; i <= doc; i++ ) + { + Weight * w = q->weight( s ); + Scorer * scorer = w->scorer( s->getReader() ); + + if( ! scorer->skipTo( i ) ) + { + StringBuffer buffer; + buffer.append( _T( "query collected " )); + buffer.appendInt( doc ); + buffer.append( _T( " but skipTo(" )); + buffer.appendInt( i ); + buffer.append( _T( ") says no more docs!" )); + assertTrueMsg( buffer.getBuffer(), false ); + } + + if( doc != scorer->doc() ) + { + StringBuffer buffer; + buffer.append( _T( "query collected " )); + buffer.appendInt( doc ); + buffer.append( _T( " but skipTo(" )); + buffer.appendInt( i ); + buffer.append( _T( ") got to " )); + buffer.appendInt( scorer->doc() ); + assertTrueMsg( buffer.getBuffer(), false ); + } + + float_t skipToScore = scorer->score(); + float_t sd = skipToScore - scorer->score(); + if( ( sd < 0 ? sd * -1 : sd ) > QueryUtils::maxDiff ) + { + StringBuffer buffer; + buffer.append( _T( "unstable skipTo(" )); + buffer.appendInt( i ); + buffer.append( _T( ") score: " )); + buffer.appendFloat( skipToScore, 2 ); + buffer.append( _T( "/") ); + buffer.appendFloat( QueryUtils::maxDiff, 2 ); + assertTrueMsg( buffer.getBuffer(), false ); + } + + if( ( skipToScore > score ? skipToScore - score : score - skipToScore ) > QueryUtils::maxDiff ) + { + StringBuffer buffer; + buffer.append( _T( "query assigned doc " )); + buffer.appendInt( doc ); + buffer.append( _T( " a score of <" )); + buffer.appendFloat( score, 2 ); + buffer.append( _T( "> but skipTo(" )); + buffer.appendInt( i ); + buffer.append( _T( ") has <" )); + buffer.appendFloat( skipToScore, 2 ); + buffer.append( _T( ">!" )); + assertTrueMsg( buffer.getBuffer(), false ); + } + + _CLLDELETE( scorer ); + _CLLDELETE( w ); + } + lastDoc[ 0 ] = doc; + } +}; + +///////////////////////////////////////////////////////////////////////////// +void QueryUtils::check( CuTest* tc, Query * q ) +{ + checkHashEquals( tc, q ); +} + +void QueryUtils::checkHashEquals( CuTest* tc, Query * q ) +{ + Query * q2 = q->clone(); + checkEqual( tc, q, q2 ); + + Query * q3 = q->clone(); + q3->setBoost( 7.21792348f ); + checkUnequal( tc, q, q3 ); + + // test that a class check is done so that no exception is thrown + // in the implementation of equals() + Query * whacky = _CLNEW WhackyQuery(); + whacky->setBoost( q->getBoost() ); + checkUnequal( tc, q, whacky ); + + _CLLDELETE( q2 ); + _CLLDELETE( q3 ); + _CLLDELETE( whacky ); +} + +void QueryUtils::checkEqual( CuTest* tc, Query * q1, Query * q2 ) +{ + assertTrue( q1->equals( q2 )); + assertTrue( q2->equals( q1 )); + assertTrue( q1->hashCode() == q2->hashCode() ); +} + +void QueryUtils::checkUnequal( CuTest* tc, Query * q1, Query * q2 ) +{ + assertTrue( ! q1->equals( q2 )); + assertTrue( ! q2->equals( q1 )); + + // possible this test can fail on a hash collision... if that + // happens, please change test to use a different example. + assertTrue( q1->hashCode() != q2->hashCode()); +} + +void QueryUtils::checkExplanations( CuTest* tc, Query * q, Searcher * s ) +{ + CheckHits::checkExplanations( tc, q, NULL, s, true ); +} + +void QueryUtils::check( CuTest* tc, Query * q1, Searcher * s ) +{ + check( tc, q1 ); + if( s ) + { + if( s->getObjectName() == IndexSearcher::getClassName()) + { + IndexSearcher * is = (IndexSearcher*) s; + checkFirstSkipTo( tc, q1, is ); + checkSkipTo( tc, q1, is ); + } + + checkExplanations( tc, q1, s ); + checkSerialization( tc, q1, s ); + } +} + +void QueryUtils::checkSerialization( CuTest* tc, Query * q, Searcher * s ) +{ + Weight * w = q->weight( s ); + // TODO: Port this test +// try { +// ByteArrayOutputStream bos = new ByteArrayOutputStream(); +// ObjectOutputStream oos = new ObjectOutputStream(bos); +// oos.writeObject(w.); +// oos.close(); +// ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())); +// ois.readObject(); +// ois.close(); +// +// //skip rquals() test for now - most weights don't overide equals() and we won't add this just for the tests. +// //TestCase.assertEquals("writeObject(w) != w. ("+w+")",w2,w); +// +// } catch (Exception e) { +// IOException e2 = new IOException("Serialization failed for "+w); +// e2.initCause(e); +// throw e2; +// } + _CLLDELETE( w ); +} + +void QueryUtils::checkSkipTo( CuTest* tc, Query * q, IndexSearcher * s ) +{ + if( BooleanQuery::getAllowDocsOutOfOrder()) + return; // in this case order of skipTo() might differ from that of next(). + + int32_t order0[] = {next_op}; + int32_t order1[] = {skip_op}; + int32_t order2[] = {skip_op, next_op}; + int32_t order3[] = {next_op, skip_op}; + int32_t order4[] = {skip_op, skip_op, next_op, next_op}; + int32_t order5[] = {next_op, next_op, skip_op, skip_op}; + int32_t order6[] = {skip_op, skip_op, skip_op, next_op, next_op}; + int32_t ordersLength[] = { 1, 1, 2, 2, 4, 4, 5 }; + int32_t * orders[] = { order0, order1, order2, order3, order4, order5, order6 }; + size_t ordersCount = 7; + + for( size_t k = 0; k < ordersCount; k++ ) + { + int32_t * order = orders[ k ]; + int32_t opidx[] = { 0 }; + + Weight * w = q->weight( s ); + Scorer * scorer = w->scorer( s->getReader() ); + + // FUTURE: ensure scorer.doc()==-1 + + int32_t * sdoc = _CL_NEWARRAY( int32_t, 1 ); + sdoc[ 0 ] = -1; + + QueryUtilsHitCollector1 hitCollector; + hitCollector.order = order; + hitCollector.opidx = opidx; + hitCollector.orderLength = ordersLength[ k ]; + hitCollector.sdoc = sdoc; + hitCollector.scorer = scorer; + hitCollector.q = q; + hitCollector.tc = tc; + + s->_search( q, NULL, &hitCollector ); + + // make sure next call to scorer is false. + int32_t op = order[ (opidx[ 0 ]++ ) % ordersLength[ k ] ]; + bool more = ( op == skip_op ) ? scorer->skipTo( sdoc[ 0 ] + 1 ) : scorer->next(); + assertTrue( ! more ); + + _CLDELETE_LARRAY( sdoc ); + _CLLDELETE( scorer ); + _CLLDELETE( w ); + } +} + +void QueryUtils::checkFirstSkipTo( CuTest* tc, Query * q, IndexSearcher * s ) +{ + int32_t lastDoc[] = {-1}; + QueryUtilsHitCollector2 hitCollector; + hitCollector.lastDoc = lastDoc; + hitCollector.q = q; + hitCollector.s = s; + hitCollector.tc = tc; + + s->_search( q, NULL, &hitCollector ); + + Weight * w = q->weight( s ); + Scorer * scorer = w->scorer( s->getReader() ); + bool more = scorer->skipTo( lastDoc[ 0 ] + 1 ); + if( more ) + { + StringBuffer buffer; + buffer.append( _T( "query's last doc was " )); + buffer.appendInt( lastDoc[ 0 ] ); + buffer.append( _T( " but skipTo(" )); + buffer.appendInt( lastDoc[ 0 ] + 1 ); + buffer.append( _T( ") got to " )); + buffer.appendInt( scorer->doc() ); + assertTrueMsg( buffer.getBuffer(), false ); + } + + _CLLDELETE( scorer ); + _CLLDELETE( w ); +} diff --git a/src/test/search/QueryUtils.h b/src/test/search/QueryUtils.h new file mode 100644 index 00000000000..4fb0650e41c --- /dev/null +++ b/src/test/search/QueryUtils.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_QueryUtils +#define _lucene_search_QueryUtils + +#include "test.h" + +class QueryUtils +{ +public: + static int32_t skip_op; + static int32_t next_op; + static float_t maxDiff; + +public: + /** Check the types of things query objects should be able to do. */ + static void check( CuTest* tc, Query * q ); + + /** check very basic hashCode and equals */ + static void checkHashEquals( CuTest* tc, Query * q ); + static void checkEqual( CuTest* tc, Query * q1, Query * q2 ); + static void checkUnequal( CuTest* tc, Query * q1, Query * q2); + + /** deep check that explanations of a query 'score' correctly */ + static void checkExplanations( CuTest* tc, Query * q, Searcher * s ); + + /** + * various query sanity checks on a searcher, including explanation checks. + * @see #checkExplanations + * @see #checkSkipTo + * @see #check(Query) + */ + static void check( CuTest* tc, Query * q1, Searcher * s ); + + /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc + * and ensure a hitcollector receives same docs and scores + */ + static void checkSkipTo( CuTest* tc, Query * q, IndexSearcher * s ); + +private: + /** check that the query weight is serializable. + * @throws IOException if serialization check fail. + */ + static void checkSerialization( CuTest* tc, Query * q, Searcher * s ); + + // check that first skip on just created scorers always goes to the right doc + static void checkFirstSkipTo( CuTest* tc, Query * q, IndexSearcher * s ); +}; +#endif + diff --git a/src/test/search/TestBoolean.cpp b/src/test/search/TestBoolean.cpp new file mode 100644 index 00000000000..215fceb2c41 --- /dev/null +++ b/src/test/search/TestBoolean.cpp @@ -0,0 +1,197 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/search/_BooleanScorer2.h" +#include "CLucene/search/Similarity.h" +#include "MockScorer.h" +#include "MockHitCollector.h" + +/// TestBooleanQuery.java, ported 5/9/2009 +void testEquality(CuTest *tc) { + BooleanQuery* bq1 = _CLNEW BooleanQuery(); + Term* t = _CLNEW Term(_T("field"), _T("value1")); + bq1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + t = _CLNEW Term(_T("field"), _T("value2")); + bq1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + BooleanQuery* nested1 = _CLNEW BooleanQuery(); + t = _CLNEW Term(_T("field"), _T("nestedvalue1")); + nested1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + t = _CLNEW Term(_T("field"), _T("nestedvalue2")); + nested1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + bq1->add(nested1, true, BooleanClause::SHOULD); + + BooleanQuery* bq2 = _CLNEW BooleanQuery(); + t = _CLNEW Term(_T("field"), _T("value1")); + bq2->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + t = _CLNEW Term(_T("field"), _T("value2")); + bq2->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + BooleanQuery* nested2 = _CLNEW BooleanQuery(); + t = _CLNEW Term(_T("field"), _T("nestedvalue1")); + nested2->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + t = _CLNEW Term(_T("field"), _T("nestedvalue2")); + nested2->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + bq2->add(nested2, true, BooleanClause::SHOULD); + + CLUCENE_ASSERT(bq1->equals(bq2)); + + _CLLDELETE(bq1); + _CLLDELETE(bq2); +} +void testException(CuTest *tc) { + try { + BooleanQuery::setMaxClauseCount(0); + CuFail(tc, _T("setMaxClauseCount(0) did not throw an exception")); + } catch (CLuceneError&) { + // okay + } +} + +/// TestBooleanScorer.java, ported 5/9/2009 +void testBooleanScorer(CuTest *tc) { + const TCHAR* FIELD = _T("category"); + RAMDirectory directory; + + const TCHAR* values[] = { _T("1"), _T("2"), _T("3"), _T("4"), NULL}; + + try { + WhitespaceAnalyzer a; + IndexWriter* writer = _CLNEW IndexWriter(&directory, &a, true); + for (size_t i = 0; values[i]!=NULL; i++) { + Document* doc = _CLNEW Document(); + doc->add(*_CLNEW Field(FIELD, values[i], Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + } + writer->close(); + _CLLDELETE(writer); + + BooleanQuery* booleanQuery1 = _CLNEW BooleanQuery(); + Term *t = _CLNEW Term(FIELD, _T("1")); + booleanQuery1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + t = _CLNEW Term(FIELD, _T("2")); + booleanQuery1->add(_CLNEW TermQuery(t), true, BooleanClause::SHOULD); + _CLDECDELETE(t); + + BooleanQuery* query = _CLNEW BooleanQuery(); + query->add(booleanQuery1, true, BooleanClause::MUST); + t = _CLNEW Term(FIELD, _T("9")); + query->add(_CLNEW TermQuery(t), true, BooleanClause::MUST_NOT); + _CLDECDELETE(t); + + IndexSearcher *indexSearcher = _CLNEW IndexSearcher(&directory); + Hits *hits = indexSearcher->search(query); + CLUCENE_ASSERT(2 == hits->length()); // Number of matched documents + _CLLDELETE(hits); + _CLLDELETE(indexSearcher); + + _CLLDELETE(query); + } + catch (CLuceneError& e) { + CuFail(tc, e.twhat()); + } +} + +/// TestBooleanPrefixQuery.java, ported 5/9/2009 +void testBooleanPrefixQuery(CuTest* tc) { + RAMDirectory directory; + WhitespaceAnalyzer a; + + const TCHAR* categories[] = {_T("food"), _T("foodanddrink"), + _T("foodanddrinkandgoodtimes"), _T("food and drink"), NULL}; + + Query* rw1 = NULL; + Query* rw2 = NULL; + try { + IndexWriter* writer = _CLNEW IndexWriter(&directory, &a, true); + for (size_t i = 0; categories[i]!=NULL; i++) { + Document* doc = new Document(); + doc->add(*_CLNEW Field(_T("category"), categories[i], Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + } + writer->close(); + _CLLDELETE(writer); + + IndexReader* reader = IndexReader::open(&directory); + Term* t = _CLNEW Term(_T("category"), _T("foo")); + PrefixQuery* query = _CLNEW PrefixQuery(t); + _CLDECDELETE(t); + + rw1 = query->rewrite(reader); + + BooleanQuery* bq = _CLNEW BooleanQuery(); + bq->add(query, true, BooleanClause::MUST); + + rw2 = bq->rewrite(reader); + + reader->close(); // TODO: check necessity (_CLLDELETE(reader) alone will not do the same cleanup) + + _CLLDELETE(reader); + _CLLDELETE(bq); + } catch (CLuceneError& e) { + CuFail(tc, e.twhat()); + } + + BooleanQuery* bq1 = NULL; + if (rw1->instanceOf(BooleanQuery::getClassName())) { + bq1 = (BooleanQuery*) rw1; + } + + BooleanQuery* bq2 = NULL; + if (rw2->instanceOf(BooleanQuery::getClassName())) { + bq2 = (BooleanQuery*) rw2; + } else { + CuFail(tc, _T("Rewrite")); + } + + bool bClausesMatch = bq1->getClauseCount() == bq2->getClauseCount(); + + _CLLDELETE(rw1); + _CLLDELETE(rw2); + + if (!bClausesMatch) { + CuFail(tc, _T("Number of Clauses Mismatch")); + } +} + +void testBooleanScorer2WithProhibitedScorer(CuTest* tc) { + CL_NS(search)::DefaultSimilarity similarity; + BooleanScorer2 scorer(&similarity, 0, true); + MockScorer prohibitedScorer(&similarity); + scorer.add(&prohibitedScorer, false, true); + CL_NS(search)::MockHitCollector collector; + scorer.score(&collector); + + CuAssertIntEquals(tc, _T("Unexpected calls of next()!"), 1, prohibitedScorer.getNextCalls()); +} + +CuSuite *testBoolean(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Boolean Tests")); + + SUITE_ADD_TEST(suite, testEquality); + SUITE_ADD_TEST(suite, testException); + + SUITE_ADD_TEST(suite, testBooleanScorer); + + SUITE_ADD_TEST(suite, testBooleanPrefixQuery); + SUITE_ADD_TEST(suite, testBooleanScorer2WithProhibitedScorer); + + //_CrtSetBreakAlloc(1179); + + return suite; +} +// EOF diff --git a/src/test/search/TestConstantScoreRangeQuery.cpp b/src/test/search/TestConstantScoreRangeQuery.cpp new file mode 100644 index 00000000000..d2c5897f4fc --- /dev/null +++ b/src/test/search/TestConstantScoreRangeQuery.cpp @@ -0,0 +1,533 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +* +------------------------------------------------------------------------------*/ + +#include "test.h" + +#include "QueryUtils.h" +#include "BaseTestRangeFilter.h" +#include "CLucene/search/ConstantScoreQuery.h" + + +/*------------------------------------------------------------------------------ +* Test based on JLucene-2.3.2 (06/08/2010) +------------------------------------------------------------------------------*/ +class TestConstantScoreRangeQuery : public BaseTestRangeFilter +{ +private: + Directory * m_pSmall; + +public: + TestConstantScoreRangeQuery( CuTest * _tc ) : BaseTestRangeFilter( _tc ), m_pSmall( NULL ) {} + ~TestConstantScoreRangeQuery() + { + if( m_pSmall ) + { + m_pSmall->close(); + _CLLDECDELETE( m_pSmall ); + } + } + + ///////////////////////////////////////////////////////////////////////////// + void setUp() + { + TCHAR tbuffer[16]; + const TCHAR* data[] = + { + _T( "A 1 2 3 4 5 6" ), + _T( "Z 4 5 6" ), + NULL, + _T( "B 2 4 5 6" ), + _T( "Y 3 5 6" ), + NULL, + _T( "C 3 6" ), + _T( "X 4 5 6" ) + }; + + m_pSmall = _CLNEW RAMDirectory(); + Analyzer * pAnalyzer = _CLNEW WhitespaceAnalyzer(); + IndexWriter * pWriter = _CLNEW IndexWriter( m_pSmall, pAnalyzer, true ); + + for( size_t i = 0; i < sizeof( data ) / sizeof( data[0] ); i++ ) + { + _itot( i, tbuffer, 10 ); + Document doc; + doc.add( * _CLNEW Field( _T( "id" ), tbuffer, Field::STORE_YES | Field::INDEX_UNTOKENIZED )); + doc.add( * _CLNEW Field( _T( "all" ), _T( "all" ), Field::STORE_YES | Field::INDEX_UNTOKENIZED )); + if( data[ i ] ) + doc.add( * _CLNEW Field( _T( "data" ), data[ i ], Field::STORE_YES | Field::INDEX_TOKENIZED )); + + pWriter->addDocument( &doc ); + } + + pWriter->optimize(); + pWriter->close(); + _CLDELETE( pWriter ); + _CLDELETE( pAnalyzer ); + } + + + ///////////////////////////////////////////////////////////////////////////// + Query * csrq(const TCHAR* f, const TCHAR* l, const TCHAR* h, bool il, bool ih) + { + return _CLNEW ConstantScoreRangeQuery( f, l, h, il, ih ); + } + + + ///////////////////////////////////////////////////////////////////////////// + void testBasics() + { + Query * q1 = csrq( _T( "data" ), _T( "1" ), _T( "6" ), true, true ); + Query * q2 = csrq( _T( "data" ), _T( "A" ) ,_T( "Z" ), true, true ); + QueryUtils::check( tc, q1 ); + QueryUtils::check( tc, q2 ); + QueryUtils::checkUnequal( tc, q1, q2 ); + _CLLDELETE( q2 ); + _CLLDELETE( q1 ); + } + + ///////////////////////////////////////////////////////////////////////////// + void testEqualScores() + { + // NOTE: uses index build in *this* setUp + + IndexReader * pReader = IndexReader::open( m_pSmall ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + + Hits * pResult; + + // some hits match more terms then others, score should be the same + Query * q = csrq( _T( "data" ), _T( "1" ), _T( "6" ), true, true ); + pResult = pSearch->search( q ); + size_t numHits = pResult->length(); + assertEqualsMsg( _T( "wrong number of results" ), 6, numHits ); + float_t score = pResult->score( 0 ); + for( size_t i = 1; i < numHits; i++ ) + { + assertTrueMsg( _T( "score was not the same" ), score == pResult->score( i )); + } + _CLDELETE( pResult ); + _CLDELETE( q ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + + ///////////////////////////////////////////////////////////////////////////// + void testBoost() + { + // NOTE: uses index build in *this* setUp + + IndexReader * pReader = IndexReader::open( m_pSmall ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + Hits * pResult; + + // test for correct application of query normalization + // must use a non score normalizing method for this. + Query * q = csrq( _T( "data" ), _T( "1" ), _T( "6" ), true, true ); + q->setBoost( 100 ); + pResult = pSearch->search( q ); + for( size_t i = 1; i < pResult->length(); i++ ) + { + assertTrueMsg( _T( "score was not was not correct" ), 1.0f == pResult->score( i )); + } + _CLDELETE( pResult ); + _CLDELETE( q ); + + + // + // Ensure that boosting works to score one clause of a query higher + // than another. + // + Query * q1 = csrq( _T( "data" ), _T( "A" ), _T( "A" ), true, true ); // matches document #0 + q1->setBoost( .1f ); + Query * q2 = csrq( _T( "data" ), _T( "Z" ), _T( "Z" ), true, true ); // matches document #1 + BooleanQuery * bq = _CLNEW BooleanQuery( true ); + bq->add( q1, true, BooleanClause::SHOULD ); + bq->add( q2, true, BooleanClause::SHOULD ); + + pResult = pSearch->search( bq ); + assertEquals( 1, pResult->id( 0 )); + assertEquals( 0, pResult->id( 1 )); + assertTrue( pResult->score( 0 ) > pResult->score( 1 )); + _CLDELETE( pResult ); + _CLDELETE( bq ); + + q1 = csrq( _T( "data" ), _T( "A" ), _T( "A" ), true, true ); // matches document #0 + q1->setBoost( 10.0f ); + q2 = csrq( _T( "data" ), _T( "Z" ), _T( "Z" ), true, true ); // matches document #1 + bq = _CLNEW BooleanQuery( true ); + bq->add( q1, true, BooleanClause::SHOULD ); + bq->add( q2, true, BooleanClause::SHOULD ); + + pResult = pSearch->search( bq ); + assertEquals( 0, pResult->id( 0 )); + assertEquals( 1, pResult->id( 1 )); + assertTrue( pResult->score( 0 ) > pResult->score( 1 )); + _CLDELETE( pResult ); + _CLDELETE( bq ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + + ///////////////////////////////////////////////////////////////////////////// + void testBooleanOrderUnAffected() + { + // NOTE: uses index build in *this* setUp + + IndexReader * pReader = IndexReader::open( m_pSmall ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + + // first do a regular RangeQuery which uses term expansion so + // docs with more terms in range get higher scores + Term * pLower = _CLNEW Term( _T( "data" ), _T( "1" )); + Term * pUpper = _CLNEW Term( _T( "data" ), _T( "4" )); + Query * rq = _CLNEW RangeQuery( pLower, pUpper, true ); + _CLLDECDELETE( pUpper ); + _CLLDECDELETE( pLower ); + + Hits * pExpected = pSearch->search( rq ); + size_t numHits = pExpected->length(); + + // now do a boolean where which also contains a + // ConstantScoreRangeQuery and make sure the order is the same + + BooleanQuery * q = _CLNEW BooleanQuery(); + q->add( rq, true, BooleanClause::MUST ); + q->add( csrq( _T( "data" ), _T( "1" ), _T( "6" ), true, true ), true, BooleanClause::MUST ); + + Hits * pActual = pSearch->search( q ); + assertEqualsMsg( _T( "wrong number of hits" ), numHits, pActual->length() ); + for( size_t i = 0; i < numHits; i++ ) + { + assertEqualsMsg( _T( "Mismatch in docid for a hit" ), pExpected->id( i ), pActual->id( i )); + } + _CLDELETE( pActual ); + _CLDELETE( pExpected ); + _CLDELETE( q ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + ///////////////////////////////////////////////////////////////////////////// + void testRangeQueryId() + { + // NOTE: uses index build in *super* setUp + + IndexReader * pReader = IndexReader::open( index ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + + int32_t medId = ((maxId - minId) / 2); + + std::tstring sMinIP = pad(minId); + std::tstring sMaxIP = pad(maxId); + std::tstring sMedIP = pad(medId); + const TCHAR* minIP = sMinIP.c_str(); + const TCHAR* maxIP = sMaxIP.c_str(); + const TCHAR* medIP = sMedIP.c_str(); + + size_t numDocs = static_cast( pReader->numDocs() ); + assertEqualsMsg( _T("num of docs"), numDocs, static_cast(1+ maxId - minId)); + + Hits * pResult; + Query * q; + // test id, bounded on both ends + + q = csrq( _T( "id" ), minIP, maxIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "find all" ), numDocs, pResult->length() ); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, maxIP, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but last" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, maxIP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but first" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, maxIP, false,false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but ends" ), numDocs-2, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), medIP, maxIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "med and up" ), 1+maxId-medId, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, medIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "up to med" ), 1+medId-minId, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + // unbounded id + + q = csrq( _T( "id" ), minIP, NULL, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "min and up" ), numDocs, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), NULL, maxIP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max and down" ), numDocs, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, NULL, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "not min, but up" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), NULL, maxIP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "not max, but down" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), medIP, maxIP, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "med and up, not max" ), maxId-medId, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, medIP, false,true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "not min, up to med" ), medId-minId, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + // very small sets + + q = csrq( _T( "id" ), minIP, minIP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "min,min,F,F" ), 0, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), medIP, medIP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "med,med,F,F" ), 0, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id") , maxIP, maxIP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,max,F,F" ), 0, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), minIP, minIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "min,min,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), NULL, minIP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "nul,min,F,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), maxIP, maxIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,max,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), maxIP, NULL, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,nul,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "id" ), medIP, medIP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "med,med,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + + ///////////////////////////////////////////////////////////////////////////// + void testRangeQueryRand() + { + // NOTE: uses index build in *super* setUp + + IndexReader * pReader = IndexReader::open( index ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + + std::tstring sMinRP = pad(minR); + std::tstring sMaxRP = pad(maxR); + const TCHAR* minRP = sMinRP.c_str(); + const TCHAR* maxRP = sMaxRP.c_str(); + + size_t numDocs = static_cast( pReader->numDocs() ); + assertEqualsMsg( _T("num of docs"), numDocs, static_cast(1+ maxId - minId)); + + Hits * pResult; + Query * q; + + // test extremes, bounded on both ends + + q = csrq( _T( "rand" ), minRP, maxRP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "find all" ), numDocs, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), minRP, maxRP, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but biggest" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), minRP, maxRP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but smallest" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), minRP, maxRP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "all but extremes" ), numDocs-2, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + // unbounded + + q = csrq( _T( "rand" ), minRP, NULL, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "smallest and up" ), numDocs, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), NULL, maxRP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "biggest and down" ), numDocs, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), minRP, NULL, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "not smallest, but up" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), NULL, maxRP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "not biggest, but down" ), numDocs-1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + // very small sets + + q = csrq( _T( "rand" ), minRP, minRP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "min,min,F,F" ), 0, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), maxRP, maxRP, false, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,max,F,F" ), 0, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), minRP, minRP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "min,min,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), NULL, minRP, false, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "nul,min,F,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), maxRP, maxRP, true, true ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,max,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + q = csrq( _T( "rand" ), maxRP, NULL, true, false ); + pResult = pSearch->search( q ); + assertEqualsMsg( _T( "max,nul,T,T" ), 1, pResult->length()); + _CLDELETE( pResult ); _CLDELETE( q ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + + ///////////////////////////////////////////////////////////////////////////// + // CLucene specific + // Visual Studio 2005 shows memory leaks for this test, but some other + // tools do not detect any memory leaks. So what is right? + // IN VC80 shows memory leaks ONLY if both sub-queries are added as + // MUST BooleanClauses. + void testBooleanMemLeaks() + { + IndexReader * pReader = IndexReader::open( m_pSmall ); + IndexSearcher * pSearch = _CLNEW IndexSearcher( pReader ); + + Query * q1 = csrq( _T( "data" ), _T( "A" ), _T( "A" ), true, true ); // matches document #0 + Query * q2 = csrq( _T( "data" ), _T( "Z" ), _T( "Z" ), true, true ); // matches document #1 + BooleanQuery * bq = _CLNEW BooleanQuery( true ); + bq->add( q1, true, BooleanClause::MUST ); + bq->add( q2, true, BooleanClause::MUST ); + + Hits * pResult = pSearch->search( bq ); + + _CLDELETE( pResult ); + _CLDELETE( bq ); + + pSearch->close(); + _CLDELETE( pSearch ); + + pReader->close(); + _CLDELETE( pReader ); + } + + + ///////////////////////////////////////////////////////////////////////////// + void runTests() + { + setUp(); + testBasics(); + testEqualScores(); + testBoost(); + testBooleanOrderUnAffected(); + testRangeQueryId(); + testRangeQueryRand(); + testBooleanMemLeaks(); + } +}; + + +///////////////////////////////////////////////////////////////////////////// +void testConstantScoreRangeQuery( CuTest * pTc ) +{ + /// Run Java Lucene tests + TestConstantScoreRangeQuery tester( pTc ); + tester.runTests(); +} + + +///////////////////////////////////////////////////////////////////////////// +CuSuite *testConstantScoreQueries(void) +{ + CuSuite *suite = CuSuiteNew( _T( "CLucene ConstScoreQuery Test" )); + + SUITE_ADD_TEST(suite, testConstantScoreRangeQuery); + + return suite; +} + + +// EOF diff --git a/src/test/search/TestDateFilter.cpp b/src/test/search/TestDateFilter.cpp new file mode 100644 index 00000000000..ac12fa5dae5 --- /dev/null +++ b/src/test/search/TestDateFilter.cpp @@ -0,0 +1,201 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + void testBefore(CuTest *tc) { + // create an index + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir,CL_MAX_PATH,"%s/%s",cl_tempDir, "dfindex"); + + FSDirectory* indexStore = FSDirectory::getDirectory( fsdir); + Analyzer* a = _CLNEW SimpleAnalyzer (); + IndexWriter* writer = _CLNEW IndexWriter(indexStore, a, true); + int64_t now = Misc::currentTimeMillis()/1000; + + Document doc; + // add time that is in the past + TCHAR* tn = DateField::timeToString(now - 1000); + doc.add(*_CLNEW Field(_T("datefield"), tn,Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + _CLDELETE_CARRAY(tn); + doc.add(*_CLNEW Field(_T("body"), _T("Today is a very sunny day in New York City"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); + writer->close(); + _CLDELETE( writer ); + + IndexReader* reader = IndexReader::open(indexStore); + IndexSearcher* searcher = _CLNEW IndexSearcher(reader); + + // filter that should preserve matches + DateFilter* df1 = DateFilter::Before(_T("datefield"), now); + + // filter that should discard matches + DateFilter* df2 = DateFilter::Before(_T("datefield"), now - 999999); + + // search something that doesn't exist with DateFilter + Term* term = _CLNEW Term(_T("body"), _T("NoMatchForThis")); + Query* query1 = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + // search for something that does exists + term=_CLNEW Term(_T("body"), _T("sunny")); + Query* query2 = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + Hits* result = NULL; + + // ensure that queries return expected results without DateFilter first + result = searcher->search(query1); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2); + CLUCENE_ASSERT(1 == result->length()); + _CLDELETE(result); + + // run queries with DateFilter + result = searcher->search(query1, df1); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query1, df2); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2, df1); + CLUCENE_ASSERT(1 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2, df2); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + reader->close(); + searcher->close(); + _CLDELETE(a) + _CLDELETE(reader); + _CLDELETE(searcher); + _CLDELETE(query1); + _CLDELETE(query2); + _CLDELETE(df1); + _CLDELETE(df2); + + indexStore->close(); + _CLDECDELETE(indexStore); + } + + void testAfter(CuTest *tc) { + // create an index + RAMDirectory* indexStore = _CLNEW RAMDirectory; + Analyzer* a = _CLNEW SimpleAnalyzer (); + IndexWriter* writer = _CLNEW IndexWriter(indexStore, a, true); + int64_t now = Misc::currentTimeMillis()/1000; + + // add time that is in the future + TCHAR* tf = DateField::timeToString(now + 888888); + + Document* doc = _CLNEW Document; + doc->add(*_CLNEW Field(_T("datefield"), tf,Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + _CLDELETE_CARRAY(tf); + + doc->add(*_CLNEW Field(_T("body"), _T("Today is a very sunny day in New York City"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + + writer->close(); + _CLDELETE( writer ); + + //read the index + IndexReader* reader = IndexReader::open(indexStore); + IndexSearcher* searcher = _CLNEW IndexSearcher(reader); + + // filter that should preserve matches + DateFilter* df1 = DateFilter::After(_T("datefield"), now); + + // filter that should discard matches + DateFilter* df2 = DateFilter::After(_T("datefield"), now + 999999); + + // search something that doesn't exist with DateFilter + Term* term = _CLNEW Term(_T("body"), _T("NoMatchForThis")); + Query* query1 = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + // search for something that does exists + term=_CLNEW Term(_T("body"), _T("sunny")); + Query* query2 = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + Hits* result = NULL; + + // ensure that queries return expected results without DateFilter first + result = searcher->search(query1); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2); + CLUCENE_ASSERT(1 == result->length()); + _CLDELETE(result); + + // run queries with DateFilter + result = searcher->search(query1, df1); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query1, df2); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2, df1); + CLUCENE_ASSERT(1 == result->length()); + _CLDELETE(result); + + result = searcher->search(query2, df2); + CLUCENE_ASSERT(0 == result->length()); + _CLDELETE(result); + + reader->close(); + searcher->close(); + + _CLDELETE(query1); + _CLDELETE(query2); + _CLDELETE(df1); + _CLDELETE(df2); + _CLDELETE(reader); + _CLDELETE(searcher); + _CLDELETE(a); + indexStore->close(); + _CLDECDELETE(indexStore); + } + + void testDateFilterDestructor(CuTest *tc){ + char loc[1024]; + strcpy(loc, clucene_data_location); + strcat(loc, "/reuters-21578-index"); + + CuAssert(tc,_T("Index does not exist"),Misc::dir_Exists(loc)); + IndexReader* reader = IndexReader::open(loc); + int64_t now = Misc::currentTimeMillis()/1000; + DateFilter* df1 = DateFilter::After(_T("datefield"), now); + BitSet* bs = df1->bits(reader); + _CLDELETE(bs); + _CLDELETE(df1); + + reader->close(); + _CLDELETE(reader); + } + + +CuSuite *testdatefilter(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene DateFilter Test")); + + SUITE_ADD_TEST(suite, testDateFilterDestructor); + SUITE_ADD_TEST(suite, testBefore); + SUITE_ADD_TEST(suite, testAfter); + + return suite; +} +// EOF diff --git a/src/test/search/TestExplanations.cpp b/src/test/search/TestExplanations.cpp new file mode 100644 index 00000000000..5a773d006d1 --- /dev/null +++ b/src/test/search/TestExplanations.cpp @@ -0,0 +1,237 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestExplanations.h" +#include "CheckHits.h" +#include "CLucene/search/spans/SpanQuery.h" +#include "CLucene/search/spans/SpanOrQuery.h" +#include "CLucene/search/spans/SpanTermQuery.h" +#include "CLucene/search/spans/SpanNotQuery.h" +#include "CLucene/search/spans/SpanNearQuery.h" +#include "CLucene/search/spans/SpanFirstQuery.h" + + +///////////////////////////////////////////////////////////////////////////// +const TCHAR * TestExplanations::field = _T( "field" ); +const TCHAR * TestExplanations::docFields[] = +{ + _T( "w1 w2 w3 w4 w5" ), + _T( "w1 w3 w2 w3 zz" ), + _T( "w1 xx w2 yy w3" ), + _T( "w1 w3 xx w2 yy w3 zz" ) +}; + + +///////////////////////////////////////////////////////////////////////////// +TestExplanations::ItemizedFilter::ItemizedFilter( int32_t * docs, size_t docsCount ) +{ + this->docs = _CL_NEWARRAY( int32_t, docsCount ); + memcpy( this->docs, docs, docsCount * sizeof( int32_t )); + this->docsCount = docsCount; +} +TestExplanations::ItemizedFilter::~ItemizedFilter() +{ + _CLDELETE_LARRAY( docs ); + docsCount = 0; +} + +CL_NS(util)::BitSet * TestExplanations::ItemizedFilter::bits( CL_NS(index)::IndexReader * r ) +{ + CL_NS(util)::BitSet * b = _CLNEW CL_NS(util)::BitSet( r->maxDoc() ); + for( size_t i = 0; i < docsCount; i++ ) + b->set( docs[ i ] ); + return b; +} + +///////////////////////////////////////////////////////////////////////////// +TestExplanations::TestExplanations( CuTest* tc ) +{ + this->searcher = NULL; + this->directory = NULL; + this->qp = NULL; + this->qpAnalyzer = NULL; + this->tc = tc; +} + +TestExplanations::~TestExplanations() +{ + if( searcher ) + { + searcher->close(); + _CLDELETE( searcher ); + } + + if( directory ) + { + directory->close(); + _CLDELETE( directory ); + } + + if( qp ) + { + _CLDELETE( qp ); + } + + if( qpAnalyzer ) + { + _CLDELETE( qpAnalyzer ); + } +} + +void TestExplanations::setUp() +{ + directory = _CLNEW RAMDirectory(); + qpAnalyzer = _CLNEW WhitespaceAnalyzer(); + qp = _CLNEW QueryParser( field, qpAnalyzer ); + + IndexWriter * writer= _CLNEW IndexWriter( directory, qpAnalyzer, true ); + for( size_t i = 0; i < sizeof( docFields ) / sizeof( docFields[0] ); i++ ) + { + Document doc; + doc.add( * _CLNEW Field( field, docFields[ i ], Field::STORE_NO | Field::INDEX_TOKENIZED )); + writer->addDocument( &doc ); + } + writer->close(); + _CLDELETE( writer ); + + searcher = _CLNEW IndexSearcher( directory ); +} + +Query * TestExplanations::makeQuery( const TCHAR * queryText ) +{ + return qp->parse( queryText ); +} + +void TestExplanations::qtest( const TCHAR * queryText, int32_t * expDocNrs, size_t expDocNrsCount ) +{ + Query * q = makeQuery( queryText ); + qtest( q , expDocNrs, expDocNrsCount ); + _CLLDELETE( q ); +} + +void TestExplanations::qtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ) +{ + CheckHits::checkHitCollector( tc, q, field, searcher, expDocNrs, expDocNrsCount ); +} + +void TestExplanations::bqtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ) +{ + qtest( reqB( q ), expDocNrs, expDocNrsCount ); + qtest( optB( q ), expDocNrs, expDocNrsCount ); +} + +void TestExplanations::bqtest( const TCHAR * queryText, int32_t * expDocNrs, size_t expDocNrsCount ) +{ + Query * q = makeQuery( queryText ); + bqtest( q, expDocNrs, expDocNrsCount ); + _CLLDELETE( q ); +} + +Term ** TestExplanations::ta( const TCHAR ** s, size_t count ) +{ + Term ** t = _CL_NEWARRAY( Term *, count ); + for( size_t i = 0; i < count; i++ ) + t[ i ] = _CLNEW Term( field, s[ i ] ); + + return t; +} + +SpanTermQuery * TestExplanations::st( const TCHAR * s ) +{ + Term * t = _CLNEW Term( field, s ); + SpanTermQuery * q = _CLNEW SpanTermQuery( t ); + _CLLDECDELETE( t ); + return q; +} + +SpanNotQuery * TestExplanations::snot( SpanQuery * i, SpanQuery * e ) +{ + return _CLNEW SpanNotQuery( i, e, true ); +} + +SpanOrQuery * TestExplanations::sor( const TCHAR * s, const TCHAR * e ) +{ + return sor( st( s ), st( e )); +} + +SpanOrQuery * TestExplanations::sor( SpanQuery * s, SpanQuery * e ) +{ + SpanQuery * clauses[] = { s, e }; + return _CLNEW SpanOrQuery( clauses, clauses+2, true ); +} + +SpanOrQuery * TestExplanations::sor( const TCHAR * s, const TCHAR * m, const TCHAR * e) +{ + return sor(st(s), st(m), st(e)); +} + +SpanOrQuery * TestExplanations::sor( SpanQuery * s, SpanQuery * m, SpanQuery * e ) +{ + SpanQuery * clauses[] = { s, m, e }; + return _CLNEW SpanOrQuery( clauses, clauses+3, true ); +} + +SpanNearQuery * TestExplanations::snear( const TCHAR * s, const TCHAR * e, int32_t slop, bool inOrder ) +{ + return snear( st(s), st(e), slop, inOrder ); +} + +SpanNearQuery * TestExplanations::snear( SpanQuery * s, SpanQuery * e, int32_t slop, bool inOrder ) +{ + SpanQuery * clauses[] = { s, e }; + return _CLNEW SpanNearQuery( clauses, clauses+2, slop, inOrder, true ); +} + +SpanNearQuery * TestExplanations::snear( const TCHAR * s, const TCHAR * m, const TCHAR * e, int32_t slop, bool inOrder ) +{ + return snear( st( s ), st( m ), st( e ), slop, inOrder ); +} + +SpanNearQuery * TestExplanations::snear( SpanQuery * s, SpanQuery * m, SpanQuery * e, int32_t slop, bool inOrder ) +{ + SpanQuery * clauses[] = { s, m, e }; + return _CLNEW SpanNearQuery( clauses, clauses+3, slop, inOrder, true ); +} + +SpanFirstQuery * TestExplanations::sf( const TCHAR * s, int32_t b ) +{ + return _CLNEW SpanFirstQuery( st( s ), b, true ); +} + +Query * TestExplanations::optB( const TCHAR * q ) +{ + return optB( makeQuery( q )); +} + +Query * TestExplanations::optB( Query * q ) +{ + Term * t = _CLNEW Term( _T( "NEVER" ), _T( "MATCH" )); + TermQuery * tq = _CLNEW TermQuery( t ); + _CLLDECDELETE( t ); + + BooleanQuery * bq = _CLNEW BooleanQuery( true ); + bq->add( q, true, BooleanClause::SHOULD ); + bq->add( tq, true, BooleanClause::MUST_NOT ); + return bq; +} + +Query * TestExplanations::reqB( const TCHAR * q ) +{ + return reqB( makeQuery( q )); +} + +Query * TestExplanations::reqB( Query * q ) +{ + Term * t = _CLNEW Term( field, _T( "w1" )); + TermQuery * tq = _CLNEW TermQuery( t ); + _CLLDECDELETE( t ); + + BooleanQuery * bq = _CLNEW BooleanQuery( true ); + bq->add( q, BooleanClause::MUST ); + bq->add( tq, BooleanClause::SHOULD ); + return bq; +} + diff --git a/src/test/search/TestExplanations.h b/src/test/search/TestExplanations.h new file mode 100644 index 00000000000..bca6fcd640d --- /dev/null +++ b/src/test/search/TestExplanations.h @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_TestExplanations +#define _lucene_search_TestExplanations + +#include "test.h" + +CL_CLASS_DEF2(search,spans,SpanQuery); +CL_CLASS_DEF2(search,spans,SpanOrQuery); +CL_CLASS_DEF2(search,spans,SpanTermQuery); +CL_CLASS_DEF2(search,spans,SpanNotQuery); +CL_CLASS_DEF2(search,spans,SpanNearQuery); +CL_CLASS_DEF2(search,spans,SpanFirstQuery); + +CL_NS_USE2(search,spans); + +/** + * Tests primative queries (ie: that rewrite to themselves) to + * insure they match the expected set of docs, and that the score of each + * match is equal to the value of the scores explanation. + * + *

+ * The assumption is that if all of the "primative" queries work well, + * then anythingthat rewrites to a primative will work well also. + *

+ * + * @see "Subclasses for actual tests" + */ +class TestExplanations +{ +public: + /** A filter that only lets the specified document numbers pass */ + class ItemizedFilter : public CL_NS(search)::Filter + { + public: + int32_t * docs; + size_t docsCount; + + public: + ItemizedFilter( int32_t * docs, size_t docsCount ); + virtual ~ItemizedFilter(); + CL_NS(util)::BitSet * bits( CL_NS(index)::IndexReader * r ); + }; + +protected: + CL_NS(search)::IndexSearcher * searcher; + CL_NS(store)::RAMDirectory * directory; + CL_NS(queryParser)::QueryParser * qp; + CL_NS(analysis)::Analyzer * qpAnalyzer; + + static const TCHAR * docFields[]; + static const TCHAR * field; + + CuTest * tc; + +public: + TestExplanations( CuTest* tc ); + virtual ~TestExplanations(); + + void setUp(); + + Query * makeQuery( const TCHAR * queryText ); + + /** check the expDocNrs first, then check the query (and the explanations) */ + virtual void qtest( const TCHAR * queryText, int32_t * expDocNrs, size_t expDocNrsCount ); + + /** check the expDocNrs first, then check the query (and the explanations) */ + virtual void qtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ); + + /** + * Tests a query using qtest after wrapping it with both optB and reqB + * @see #qtest + * @see #reqB + * @see #optB + */ + virtual void bqtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ); + + /** + * Tests a query using qtest after wrapping it with both optB and reqB + * @see #qtest + * @see #reqB + * @see #optB + */ + virtual void bqtest( const TCHAR * queryText, int32_t * expDocNrs, size_t expDocNrsCount ); + + /** helper for generating MultiPhraseQueries */ + static Term ** ta( const TCHAR ** s, size_t count ); + + /** MACRO for SpanTermQuery */ + CL_NS2(search,spans)::SpanTermQuery * st( const TCHAR * s); + + /** MACRO for SpanNotQuery */ + SpanNotQuery * snot( SpanQuery * i, SpanQuery * e); + + /** MACRO for SpanOrQuery containing two SpanTerm queries */ + SpanOrQuery * sor( const TCHAR * s, const TCHAR * e ); + + /** MACRO for SpanOrQuery containing two SpanQueries */ + SpanOrQuery * sor( SpanQuery * s, SpanQuery * e ); + + /** MACRO for SpanOrQuery containing three SpanTerm queries */ + SpanOrQuery * sor( const TCHAR * s, const TCHAR * m, const TCHAR * e ); + + /** MACRO for SpanOrQuery containing two SpanQueries */ + SpanOrQuery * sor( SpanQuery * s, SpanQuery * m, SpanQuery * e ); + + /** MACRO for SpanNearQuery containing two SpanTerm queries */ + SpanNearQuery * snear( const TCHAR * s, const TCHAR * e, int32_t slop, bool inOrder ); + + /** MACRO for SpanNearQuery containing two SpanQueries */ + SpanNearQuery * snear( SpanQuery * s, SpanQuery * e, int32_t slop, bool inOrder ); + + /** MACRO for SpanNearQuery containing three SpanTerm queries */ + SpanNearQuery * snear( const TCHAR * s, const TCHAR * m, const TCHAR * e, int32_t slop, bool inOrder ); + + /** MACRO for SpanNearQuery containing three SpanQueries */ + SpanNearQuery * snear( SpanQuery * s, SpanQuery * m, SpanQuery * e, int32_t slop, bool inOrder ); + + /** MACRO for SpanFirst(SpanTermQuery) */ + SpanFirstQuery * sf( const TCHAR * s, int32_t b ); + + /** + * MACRO: Wraps a Query in a BooleanQuery so that it is optional, along + * with a second prohibited clause which will never match anything + */ + Query * optB( const TCHAR * q ); + + /** + * MACRO: Wraps a Query in a BooleanQuery so that it is optional, along + * with a second prohibited clause which will never match anything + */ + Query * optB( Query * q ); + + /** + * MACRO: Wraps a Query in a BooleanQuery so that it is required, along + * with a second optional clause which will match everything + */ + Query * reqB( const TCHAR * q ); + + /** + * MACRO: Wraps a Query in a BooleanQuery so that it is required, along + * with a second optional clause which will match everything + */ + Query * reqB( Query * q ); +}; +#endif + diff --git a/src/test/search/TestExtractTerms.cpp b/src/test/search/TestExtractTerms.cpp new file mode 100644 index 00000000000..4348e8c7aac --- /dev/null +++ b/src/test/search/TestExtractTerms.cpp @@ -0,0 +1,309 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Jiri Splichal and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + +///////////////////////////////////////////////////////////////////////////// +Directory * setUpIndex() +{ + TCHAR tbuffer[16]; + const TCHAR* data[] = + { + _T( "aaaaa aaaab aaabb aabbb abbbb bbbbb" ), + _T( "aaaaa aaaac aaacc aaccc acccc ccccc" ) + }; + + RAMDirectory * pDirectory = _CLNEW RAMDirectory(); + WhitespaceAnalyzer analyzer; + IndexWriter writer( pDirectory, &analyzer, true ); + for( int i = 0; i < sizeof( data ) / sizeof( data[0] ); i++ ) + { + _itot( i, tbuffer, 10 ); + Document doc; + doc.add( * _CLNEW Field( _T( "id" ), tbuffer, Field::STORE_YES | Field::INDEX_UNTOKENIZED )); + doc.add( * _CLNEW Field( _T( "data" ), data[ i ], Field::STORE_YES | Field::INDEX_TOKENIZED )); + writer.addDocument( &doc ); + } + + writer.optimize(); + writer.close(); + return pDirectory; +} + + +///////////////////////////////////////////////////////////////////////////// +void closeIndex( Directory * pDirectory ) +{ + if( pDirectory ) + { + pDirectory->close(); + _CLLDECDELETE( pDirectory ); + } +} + + +///////////////////////////////////////////////////////////////////////////// +void clearTermSet( TermSet& termSet ) +{ + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + _CLLDECDELETE( pTerm ); + } + termSet.clear(); +} + + +///////////////////////////////////////////////////////////////////////////// +void testExtractFromTermQuery( CuTest * tc ) +{ + Directory * pIndex = setUpIndex(); + IndexReader * pReader = IndexReader::open( pIndex ); + TermSet termSet; + + Term * t1 = _CLNEW Term( _T("data"), _T("aaaaa") ); + Term * t2 = _CLNEW Term( _T("data"), _T("bbbbb") ); + Query * q1 = _CLNEW TermQuery( t1 ); + Query * q2 = _CLNEW TermQuery( t2 ); + Query * rewrite1 = q1->rewrite( pReader ); + Query * rewrite2 = q2->rewrite( pReader ); + + rewrite1->extractTerms( &termSet ); + assertEqualsMsg( _T( "wrong number of terms" ), 1, termSet.size() ); + assertEqualsMsg( _T( "wrong term" ), 0, t1->compareTo( *(termSet.begin())) ); + clearTermSet( termSet ); + + rewrite2->extractTerms( &termSet ); + assertEqualsMsg( _T( "wrong number of terms" ), 1, termSet.size() ); + assertEqualsMsg( _T( "wrong term" ), 0, t2->compareTo( *(termSet.begin())) ); + clearTermSet( termSet ); + + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); + + if( q1 != rewrite1 ) + _CLDELETE( rewrite1 ); + _CLDELETE( q1 ); + + if( q2 != rewrite2 ) + _CLDELETE( rewrite2 ); + _CLDELETE( q2 ); + + pReader->close(); + _CLDELETE( pReader ); + + closeIndex( pIndex ); + pIndex = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +void testExtractFromPhraseQuery( CuTest * tc ) +{ + Directory * pIndex = setUpIndex(); + IndexReader * pReader = IndexReader::open( pIndex ); + TermSet termSet; + + Term * t1 = _CLNEW Term( _T("data"), _T("aaaab") ); + Term * t2 = _CLNEW Term( _T("data"), _T("ccccc") ); + Term * t3 = _CLNEW Term( _T("data"), _T("aaaab") ); + PhraseQuery * phrase = _CLNEW PhraseQuery(); + phrase->add( t1 ); + phrase->add( t2 ); + phrase->add( t3 ); + + Query * rewrite = phrase->rewrite( pReader ); + + rewrite->extractTerms( &termSet ); + assertEqualsMsg( _T( "wrong number of terms" ), 2, termSet.size() ); + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + assertTrueMsg( _T( "wrong term" ), ( 0 == t1->compareTo( pTerm ) || 0 == t2->compareTo( pTerm ))); + } + clearTermSet( termSet ); + + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); + _CLLDECDELETE( t3 ); + + if( rewrite != phrase ) + _CLDELETE( rewrite ); + _CLDELETE( phrase ); + + pReader->close(); + _CLDELETE( pReader ); + + closeIndex( pIndex ); + pIndex = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +void testExtractFromBooleanQuery( CuTest * tc ) +{ + Directory * pIndex = setUpIndex(); + IndexReader * pReader = IndexReader::open( pIndex ); + TermSet termSet; + + Term * t1 = _CLNEW Term( _T("data"), _T("aaaab") ); + Term * t2 = _CLNEW Term( _T("data"), _T("aaabb") ); + Term * t3 = _CLNEW Term( _T("data"), _T("aaabb") ); + BooleanQuery * bq = _CLNEW BooleanQuery(); + bq->add( _CLNEW TermQuery( t1 ), true, BooleanClause::SHOULD ); + bq->add( _CLNEW TermQuery( t2 ), true, BooleanClause::SHOULD ); + bq->add( _CLNEW TermQuery( t3 ), true, BooleanClause::SHOULD ); + + Query * rewrite = bq->rewrite( pReader ); + + rewrite->extractTerms( &termSet ); + assertEqualsMsg( _T( "wrong number of terms" ), 2, termSet.size() ); + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + assertTrueMsg( _T( "wrong term" ), ( 0 == t1->compareTo( pTerm ) || 0 == t2->compareTo( pTerm ))); + } + clearTermSet( termSet ); + + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); + _CLLDECDELETE( t3 ); + + if( rewrite != bq ) + _CLDELETE( rewrite ); + _CLDELETE( bq ); + + pReader->close(); + _CLDELETE( pReader ); + + closeIndex( pIndex ); + pIndex = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +void testExtractFromWildcardQuery( CuTest * tc ) +{ + Directory * pIndex = setUpIndex(); + IndexReader * pReader = IndexReader::open( pIndex ); + TermSet termSet; + WildcardQuery * wildcard; + Term * t1; + Query * rewrite; + + + t1 = _CLNEW Term( _T("data"), _T("aaaa?") ); + wildcard = _CLNEW WildcardQuery( t1 ); + rewrite = wildcard->rewrite( pReader ); + rewrite->extractTerms( &termSet ); + _CLLDECDELETE( t1 ); + + assertEqualsMsg( _T( "wrong number of terms" ), 3, termSet.size() ); + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + if( 0 != _tcscmp( _T( "aaaaa" ), pTerm->text()) + && 0 != _tcscmp( _T( "aaaab" ), pTerm->text()) + && 0 != _tcscmp( _T( "aaaac" ), pTerm->text())) + { + assertTrueMsg( _T( "wrong term" ), false ); + } + } + + clearTermSet( termSet ); + if( rewrite != wildcard ) + _CLDELETE( rewrite ); + _CLDELETE( wildcard ); + + + t1 = _CLNEW Term( _T("data"), _T("aaa*") ); + wildcard = _CLNEW WildcardQuery( t1 ); + rewrite = wildcard->rewrite( pReader ); + rewrite->extractTerms( &termSet ); + _CLLDECDELETE( t1 ); + + assertEqualsMsg( _T( "wrong number of terms" ), 5, termSet.size() ); + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + assertTrueMsg( _T( "wrong term" ), ( 0 == _tcsncmp( _T( "aaa" ), pTerm->text(), 3 ))); + } + + clearTermSet( termSet ); + if( rewrite != wildcard ) + _CLDELETE( rewrite ); + _CLDELETE( wildcard ); + + + pReader->close(); + _CLDELETE( pReader ); + + closeIndex( pIndex ); + pIndex = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +void testExtractFromFuzzyQuery( CuTest * tc ) +{ + Directory * pIndex = setUpIndex(); + IndexReader * pReader = IndexReader::open( pIndex ); + TermSet termSet; + FuzzyQuery * fuzzy; + Term * t1; + Query * rewrite; + + + t1 = _CLNEW Term( _T("data"), _T("aaaab") ); + fuzzy = _CLNEW FuzzyQuery( t1, 0.7f ); + rewrite = fuzzy->rewrite( pReader ); + rewrite->extractTerms( &termSet ); + _CLLDECDELETE( t1 ); + + assertEqualsMsg( _T( "wrong number of terms" ), 4, termSet.size() ); + for( TermSet::iterator itTerms = termSet.begin(); itTerms != termSet.end(); itTerms++ ) + { + Term * pTerm = *itTerms; + if( 0 != _tcscmp( _T( "aaaaa" ), pTerm->text()) + && 0 != _tcscmp( _T( "aaaab" ), pTerm->text()) + && 0 != _tcscmp( _T( "aaabb" ), pTerm->text()) + && 0 != _tcscmp( _T( "aaaac" ), pTerm->text())) + { + assertTrueMsg( _T( "wrong term" ), false ); + } + } + + clearTermSet( termSet ); + if( rewrite != fuzzy ) + _CLDELETE( rewrite ); + _CLDELETE( fuzzy ); + + pReader->close(); + _CLDELETE( pReader ); + + closeIndex( pIndex ); + pIndex = NULL; +} + + +///////////////////////////////////////////////////////////////////////////// +// Custom CLucene tests +CuSuite *testExtractTerms(void) +{ + CuSuite *suite = CuSuiteNew( _T( "CLucene ExtractTerms Test" )); + + SUITE_ADD_TEST( suite, testExtractFromTermQuery ); + SUITE_ADD_TEST( suite, testExtractFromPhraseQuery ); + SUITE_ADD_TEST( suite, testExtractFromBooleanQuery ); + SUITE_ADD_TEST( suite, testExtractFromWildcardQuery ); + SUITE_ADD_TEST( suite, testExtractFromFuzzyQuery ); + + return suite; +} + + +// EOF diff --git a/src/test/search/TestForDuplicates.cpp b/src/test/search/TestForDuplicates.cpp new file mode 100644 index 00000000000..3e915b394db --- /dev/null +++ b/src/test/search/TestForDuplicates.cpp @@ -0,0 +1,164 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + + static void print_tHits( CuTest *tc, Hits* hits ) { + CuMessageA(tc,"%d total results\n\n", hits->length()); + for (size_t i = 0 ; i < hits->length(); i++) { + if ( i < 10 || (i > 94 && i < 105) ) { + const Document& d = hits->doc(i); + CuMessage(tc, _T("%d %s\n"), i, d.get(_T("id")) ); + } + } + } + void testSearchTestForDuplicatesRaw(CuTest *tc){ + const int MAX_DOCS=1500; + const char *strBody[10] = {"test", "value", "why not", "computer", "clucene", + "sun", "program", "main", "database", "code"}; + RAMDirectory ram; + + //--- + WhitespaceAnalyzer an; + IndexWriter* writer = _CLNEW IndexWriter(&ram, &an, true); + Document *doc = 0; + + //--- + TCHAR strDb[1024]; + //printf("Indexing, please wait...\n"); + for (int32_t i = 0; i < MAX_DOCS; i++) { + //**** + //printf("%d/%d=%s\n", i, MAX_DOCS,strBody[i%10]); + doc = _CLNEW Document(); + + //--- + _sntprintf(strDb, 1024, _T("%d"), i); + doc->add( *_CLNEW Field(_T("id"), strDb,Field::STORE_YES | Field::INDEX_UNTOKENIZED) ); + + STRCPY_AtoT(strDb, strBody[i%10], 1022); + + doc->add(*_CLNEW Field(_T("body"), strDb,Field::STORE_NO | Field::INDEX_TOKENIZED) ); + //--- + writer->addDocument(doc); + _CLDELETE(doc); + //**** + } + //printf("\nDone.\n"); + + //--- + writer->close(); + _CLDELETE(writer); + + + + IndexSearcher searcher(&ram); + //--- + int32_t dupl = 0; + Query* query = QueryParser::parse(_T("test"), _T("body"), &an); + Hits* result = searcher.search(query); + + CLUCENE_ASSERT(result->length()==((int)MAX_DOCS/10)); + + //printf("Building result map...\n"); + std::map resMap; + int32_t id; + for (size_t j = 0; j < result->length(); j++) { + doc = &result->doc(j); + + id = _ttoi(doc->get(_T("id"))); + if ( resMap.find(id) ==resMap.end() ) { + resMap.insert( std::pair(id, 1)); + //printf("Inserted $d\n",id); + } else { + TCHAR tmp[2048]; + _sntprintf(tmp,2048,_T("Duplicated result found - Id: %d\n"), id); + CuAssert(tc,tmp,false); + dupl++; + } + } + //printf("Total duplicated found: %d\n", dupl); + + //--- + _CLDELETE(result); + _CLDELETE(query); + searcher.close(); + ram.close(); + } + + void testSearchTestForDuplicates(CuTest *tc) { + RAMDirectory directory; + SimpleAnalyzer analyzer; + IndexWriter* writer = _CLNEW IndexWriter(&directory, &analyzer, true); + const int32_t MAX_DOCS = 255; + + for (int32_t j = 0; j < MAX_DOCS; j++) { + Document* d = _CLNEW Document(); + d->add(*_CLNEW Field(_T("priority"), _T("high"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + TCHAR buf[80]; + _i64tot(j,buf,10); + + d->add(*_CLNEW Field(_T("id"), buf,Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(d); + + _CLDELETE(d); + } + writer->close(); + _CLDELETE(writer); + + // try a search without OR + Searcher* searcher = _CLNEW IndexSearcher( &directory ); + QueryParser* parser = _CLNEW QueryParser(_T("priority"), &analyzer); + Hits* hits = NULL; + + Query* query = parser->parse(_T("high")); + TCHAR* tmp = query->toString(_T("priority")); + CuMessage(tc, _T("Query: %s\n"), tmp ); + _CLDELETE_CARRAY(tmp); + + hits = searcher->search(query); + print_tHits(tc, hits); + _CLDELETE(hits); + _CLDELETE(query); + _CLDELETE(parser); + + searcher->close(); + _CLDELETE(searcher); + + + + // try a new search with OR + searcher = _CLNEW IndexSearcher( &directory ); + parser = _CLNEW QueryParser(_T("priority"), &analyzer); + hits = NULL; + + query = parser->parse(_T("high OR medium")); + tmp = query->toString(_T("priority")); + CuMessage(tc, _T("Query: %s\n"), tmp ); + _CLDELETE_CARRAY(tmp); + + hits = searcher->search(query); + print_tHits(tc, hits); + _CLDELETE(hits); + _CLDELETE(query); + _CLDELETE(parser); + + searcher->close(); + _CLDELETE(searcher); + + directory.close(); + } + + + CuSuite *testduplicates(void) + { + CuSuite *suite = CuSuiteNew(_T("CLucene Duplicates Test")); + + SUITE_ADD_TEST(suite, testSearchTestForDuplicates); + SUITE_ADD_TEST(suite, testSearchTestForDuplicatesRaw); + + return suite; + } +// EOF diff --git a/src/test/search/TestIndexSearcher.cpp b/src/test/search/TestIndexSearcher.cpp new file mode 100644 index 00000000000..4650a15712e --- /dev/null +++ b/src/test/search/TestIndexSearcher.cpp @@ -0,0 +1,99 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2010 the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +DEFINE_MUTEX(searchMutex); +DEFINE_CONDITION(searchCondition); + +DEFINE_MUTEX(deleteMutex); +DEFINE_CONDITION(deleteCondition); + +_LUCENE_THREAD_FUNC(searchDocs, _searcher) { + + WhitespaceAnalyzer an; + IndexSearcher * searcher = (IndexSearcher *)_searcher; + Query * query = QueryParser::parse(_T("one"), _T("content"), &an); + Hits * hits = searcher->search(query); + + //usleep(9999); //make sure that searchMutex is being waited on... + + CONDITION_NOTIFYALL(searchCondition); + SCOPED_LOCK_MUTEX(deleteMutex); + + _CLLDELETE(hits); + _CLLDELETE(query); + + CONDITION_WAIT(deleteMutex, deleteCondition); + _LUCENE_THREAD_FUNC_RETURN(0); +} + +void testEndThreadException(CuTest *tc) { + + const int MAX_DOCS=1500; + RAMDirectory ram; + WhitespaceAnalyzer an; + IndexWriter* writer = _CLNEW IndexWriter(&ram, &an, true); + + // add some documents + Document doc; + for (int i = 0; i < MAX_DOCS; i++) { + TCHAR * tmp = English::IntToEnglish(i); + doc.add(* new Field(_T("content"), tmp, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + writer->addDocument(&doc); + doc.clear(); + _CLDELETE_ARRAY( tmp ); + } + + CuAssertEquals(tc, MAX_DOCS, writer->docCount()); + + writer->close(); + _CLLDELETE(writer); + + // this sequence is OK: delete searcher after search thread finish + { + IndexSearcher * searcher = _CLNEW IndexSearcher(&ram); + _LUCENE_THREADID_TYPE thread = _LUCENE_THREAD_CREATE(&searchDocs, searcher); + SCOPED_LOCK_MUTEX(searchMutex); + + CONDITION_WAIT(searchMutex, searchCondition); + //usleep(9999); //make sure that deleteMutex is being waited on... + CONDITION_NOTIFYALL(deleteCondition); + + _LUCENE_THREAD_JOIN(thread); + + searcher->close(); + _CLLDELETE(searcher); + } + + // this produces memory exception: delete searcher after search finish but before thread finish + { + IndexSearcher * searcher = _CLNEW IndexSearcher(&ram); + _LUCENE_THREADID_TYPE thread = _LUCENE_THREAD_CREATE(&searchDocs, searcher); + SCOPED_LOCK_MUTEX(searchMutex); + + CONDITION_WAIT(searchMutex, searchCondition); + searcher->close(); + _CLLDELETE(searcher); + CONDITION_NOTIFYALL(deleteCondition); + + _LUCENE_THREAD_JOIN(thread); + } + + + ram.close(); +} + + +CuSuite *testIndexSearcher(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene IndexSearcher Test")); + + SUITE_ADD_TEST(suite, testEndThreadException); + + return suite; + } +// EOF diff --git a/src/test/search/TestQueries.cpp b/src/test/search/TestQueries.cpp new file mode 100644 index 00000000000..c6bae0f5915 --- /dev/null +++ b/src/test/search/TestQueries.cpp @@ -0,0 +1,384 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/search/MultiPhraseQuery.h" +#include "QueryUtils.h" + +/// Java PrefixQuery test, 2009-06-02 +void testPrefixQuery(CuTest *tc){ + WhitespaceAnalyzer analyzer; + RAMDirectory directory; + const TCHAR* categories[] = {_T("/Computers"), _T("/Computers/Mac"), _T("/Computers/Windows")}; + + IndexWriter writer( &directory, &analyzer, true); + for (int i = 0; i < 3; i++) { + Document *doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("category"), categories[i], Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + writer.addDocument(doc); + _CLDELETE(doc); + } + writer.close(); + + Term* t = _CLNEW Term(_T("category"), _T("/Computers")); + PrefixQuery *query = _CLNEW PrefixQuery(t); + IndexSearcher searcher(&directory); + Hits *hits = searcher.search(query); + CLUCENE_ASSERT(3 == hits->length()); // All documents in /Computers category and below + _CLDELETE(query); + _CLDELETE(t); + _CLDELETE(hits); + + t = _CLNEW Term(_T("category"), _T("/Computers/Mac")); + query = _CLNEW PrefixQuery(t); + hits = searcher.search(query); + CLUCENE_ASSERT(1 == hits->length()); // One in /Computers/Mac + _CLDELETE(query); + _CLDELETE(t); + _CLDELETE(hits); +} + +#ifndef NO_FUZZY_QUERY + +/// Java FuzzyQuery test, 2009-06-02 +class TestFuzzyQuery { +private: + CuTest *tc; + + void addDoc(const TCHAR* text, IndexWriter* writer) { + Document* doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("field"), text, Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLLDELETE(doc); + } + + Hits* searchQuery(IndexSearcher* searcher, const TCHAR* field, const TCHAR* text, + float_t minSimilarity=FuzzyQuery::defaultMinSimilarity, size_t prefixLen=0){ + + Term* t = _CLNEW Term(field, text); + FuzzyQuery* query = _CLNEW FuzzyQuery(t, minSimilarity, prefixLen); + Hits* hits = searcher->search(query); + _CLLDELETE(query); + _CLLDECDELETE(t); + return hits; + } + + size_t getHitsLength(IndexSearcher* searcher, const TCHAR* field, const TCHAR* text, + float_t minSimilarity=FuzzyQuery::defaultMinSimilarity, size_t prefixLen=0){ + + Hits* hits = searchQuery(searcher, field, text, minSimilarity, prefixLen); + size_t ret = hits->length(); + _CLLDELETE(hits); + return ret; + } +public: + TestFuzzyQuery(CuTest *_tc):tc(_tc){ + } + ~TestFuzzyQuery(){ + } + + void testFuzziness() { + RAMDirectory directory; + WhitespaceAnalyzer a; + IndexWriter writer(&directory, &a, true); + addDoc(_T("aaaaa"), &writer); + addDoc(_T("aaaab"), &writer); + addDoc(_T("aaabb"), &writer); + addDoc(_T("aabbb"), &writer); + addDoc(_T("abbbb"), &writer); + addDoc(_T("bbbbb"), &writer); + addDoc(_T("ddddd"), &writer); + writer.optimize(); + writer.close(); + IndexSearcher searcher(&directory); + + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa")) == 3); + + // same with prefix + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,1) == 3); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,2) == 3); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,3) == 3); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,4) == 2); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,5) == 1); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaaaa"),FuzzyQuery::defaultMinSimilarity,6) == 1); + + // not similar enough: + CuAssertTrue(tc, getHitsLength(&searcher, _T("field"), _T("xxxxx")) == 0); + CuAssertTrue(tc, getHitsLength(&searcher, _T("field"), _T("aaccc")) == 0); // edit distance to "aaaaa" = 3 + + // query identical to a word in the index: + Hits* hits = searchQuery(&searcher, _T("field"), _T("aaaaa")); + CLUCENE_ASSERT( hits->length() == 3); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + // default allows for up to two edits: + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaabb"), hits->doc(2).get(_T("field"))); + _CLLDELETE(hits); + + // query similar to a word in the index: + hits = searchQuery(&searcher, _T("field"), _T("aaaac")); + CLUCENE_ASSERT( hits->length() == 3); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaabb"), hits->doc(2).get(_T("field"))); + _CLLDELETE(hits); + + // now with prefix + hits = searchQuery(&searcher, _T("field"), _T("aaaac"), FuzzyQuery::defaultMinSimilarity, 1); + CLUCENE_ASSERT( hits->length() == 3); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaabb"), hits->doc(2).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("aaaac"), FuzzyQuery::defaultMinSimilarity, 2); + CLUCENE_ASSERT( hits->length() == 3); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaabb"), hits->doc(2).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("aaaac"), FuzzyQuery::defaultMinSimilarity, 3); + CLUCENE_ASSERT( hits->length() == 3); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaabb"), hits->doc(2).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("aaaac"), FuzzyQuery::defaultMinSimilarity, 4); + CLUCENE_ASSERT( hits->length() == 2); + CuAssertStrEquals(tc, NULL, _T("aaaaa"), hits->doc(0).get(_T("field"))); + CuAssertStrEquals(tc, NULL, _T("aaaab"), hits->doc(1).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("aaaac"), FuzzyQuery::defaultMinSimilarity, 5); + CLUCENE_ASSERT( hits->length() == 0); + _CLLDELETE(hits); + + + hits = searchQuery(&searcher, _T("field"), _T("ddddX")); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("ddddd"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + // now with prefix + hits = searchQuery(&searcher, _T("field"), _T("ddddX"), FuzzyQuery::defaultMinSimilarity, 1); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("ddddd"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("ddddX"), FuzzyQuery::defaultMinSimilarity, 2); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("ddddd"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("ddddX"), FuzzyQuery::defaultMinSimilarity, 3); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("ddddd"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("ddddX"), FuzzyQuery::defaultMinSimilarity, 4); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("ddddd"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + hits = searchQuery(&searcher, _T("field"), _T("ddddX"), FuzzyQuery::defaultMinSimilarity, 5); + CLUCENE_ASSERT( hits->length() == 0); + _CLLDELETE(hits); + + // different field = no match: + hits = searchQuery(&searcher, _T("anotherfield"), _T("ddddX")); + CLUCENE_ASSERT( hits->length() == 0); + _CLLDELETE(hits); + + searcher.close(); + directory.close(); + } + + void testFuzzinessLong() { + RAMDirectory directory; + WhitespaceAnalyzer a; + IndexWriter writer(&directory, &a, true); + addDoc(_T("aaaaaaa"), &writer); + addDoc(_T("segment"), &writer); + writer.optimize(); + writer.close(); + IndexSearcher searcher(&directory); + + // not similar enough: + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("xxxxx")) == 0); + + // edit distance to "aaaaaaa" = 3, this matches because the string is longer than + // in testDefaultFuzziness so a bigger difference is allowed: + Hits* hits = searchQuery(&searcher, _T("field"), _T("aaaaccc")); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("aaaaaaa"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + + // now with prefix + hits = searchQuery(&searcher, _T("field"), _T("aaaaccc"), FuzzyQuery::defaultMinSimilarity, 1); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("aaaaaaa"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + hits = searchQuery(&searcher, _T("field"), _T("aaaaccc"), FuzzyQuery::defaultMinSimilarity, 4); + CLUCENE_ASSERT( hits->length() == 1); + CuAssertStrEquals(tc, NULL, _T("aaaaaaa"), hits->doc(0).get(_T("field"))); + _CLLDELETE(hits); + hits = searchQuery(&searcher, _T("field"), _T("aaaaccc"), FuzzyQuery::defaultMinSimilarity, 5); + CLUCENE_ASSERT( hits->length() == 0); + _CLLDELETE(hits); + + // no match, more than half of the characters is wrong: + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaacccc")) == 0); + + // now with prefix + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("aaacccc"), FuzzyQuery::defaultMinSimilarity, 2) == 0); + + // "student" and "stellent" are indeed similar to "segment" by default: + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("student")) == 1); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("stellent")) == 1); + + // now with prefix + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("student"), FuzzyQuery::defaultMinSimilarity, 1) == 1); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("stellent"), FuzzyQuery::defaultMinSimilarity, 1) == 1); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("student"), FuzzyQuery::defaultMinSimilarity, 2) == 0); + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("stellent"), FuzzyQuery::defaultMinSimilarity, 2) == 0); + + // "student" doesn't match anymore thanks to increased minimum similarity: + CLUCENE_ASSERT( getHitsLength(&searcher, _T("field"), _T("student"), 0.6f, 0) == 0); + + try { + new FuzzyQuery(_CLNEW Term(_T("field"), _T("student")), 1.1f); + CuFail(tc, _T("Expected IllegalArgumentException")); + } catch (CLuceneError& /*e*/) { + // expecting exception + } + try { + new FuzzyQuery(_CLNEW Term(_T("field"), _T("student")), -0.1f); + CuFail(tc, _T("Expected IllegalArgumentException")); + } catch (CLuceneError& /*e*/) { + // expecting exception + } + + searcher.close(); + directory.close(); + } +}; + +void testFuzzyQuery(CuTest *tc){ + + /// Run Java Lucene tests + TestFuzzyQuery tester(tc); + tester.testFuzziness(); + + /// Legacy CLucene tests + RAMDirectory ram; + + //--- + WhitespaceAnalyzer an; + IndexWriter* writer = _CLNEW IndexWriter(&ram, &an, true); + + //--- + Document *doc = 0; + //**** + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("body"),_T("test"),Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + //**** + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("body"),_T("home"),Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + //**** + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("body"), _T("pc linux"),Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + //**** + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("body"), _T("tested"),Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + //**** + doc = _CLNEW Document(); + doc->add(*_CLNEW Field(_T("body"), _T("source"),Field::STORE_NO | Field::INDEX_TOKENIZED)); + writer->addDocument(doc); + _CLDELETE(doc); + + //--- + writer->close(); + _CLDELETE(writer); + + //--- + IndexSearcher searcher (&ram); + + //--- + Term* term = _CLNEW Term(_T("body"), _T("test~")); + Query* query = _CLNEW FuzzyQuery(term); + Hits* result = searcher.search(query); + + CLUCENE_ASSERT(result && result->length() > 0); + + //--- + _CLDELETE(result); + _CLDELETE(query); + _CLDECDELETE(term); + searcher.close(); + ram.close(); +} +#else + void _NO_FUZZY_QUERY(CuTest *tc){ + CuNotImpl(tc,_T("Fuzzy")); + } +#endif + +void testMultiPhraseQuery( CuTest * tc ) +{ + MultiPhraseQuery * pQuery = _CLNEW MultiPhraseQuery(); + + Term * t1 = _CLNEW Term( _T( "field" ), _T( "t1" )); + Term * t2 = _CLNEW Term( _T( "field" ), _T( "t2" )); + Term * t3 = _CLNEW Term( _T( "field" ), _T( "t3" )); + Term * t4 = _CLNEW Term( _T( "field" ), _T( "t4" )); + + CL_NS(util)::ValueArray terms( 3 ); + terms[ 0 ] = t2; + terms[ 1 ] = t3; + terms[ 2 ] = t4; + + pQuery->add( t1 ); + pQuery->add( &terms ); + + Query * pClone = pQuery->clone(); + + QueryUtils::checkEqual( tc, pQuery, pClone ); + + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); + _CLLDECDELETE( t3 ); + _CLLDECDELETE( t4 ); + _CLLDELETE( pQuery ); + _CLLDELETE( pClone ); +} + +CuSuite *testqueries(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Queries Test")); + + SUITE_ADD_TEST(suite, testPrefixQuery); + SUITE_ADD_TEST(suite, testMultiPhraseQuery); + #ifndef NO_FUZZY_QUERY + SUITE_ADD_TEST(suite, testFuzzyQuery); + #else + SUITE_ADD_TEST(suite, _NO_FUZZY_QUERY); + #endif + + + return suite; +} +//EOF + diff --git a/src/test/search/TestRangeFilter.cpp b/src/test/search/TestRangeFilter.cpp new file mode 100644 index 00000000000..1c26ab5bde6 --- /dev/null +++ b/src/test/search/TestRangeFilter.cpp @@ -0,0 +1,342 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +#include "CLucene/search/RangeFilter.h" +#include "BaseTestRangeFilter.h" + + +class TestRangeFilter : BaseTestRangeFilter { +public: + TestRangeFilter(CuTest* _tc) + : BaseTestRangeFilter(_tc) + { + } + + void testRangeFilterId() { + + IndexReader* reader = IndexReader::open(index); + IndexSearcher* search = new IndexSearcher(reader); + + int medId = ((maxId - minId) / 2); + + std::tstring minIPstr = pad(minId); + const TCHAR* minIP = minIPstr.c_str(); + + std::tstring maxIPstr = pad(maxId); + const TCHAR* maxIP = maxIPstr.c_str(); + + std::tstring medIPstr = pad(medId); + const TCHAR* medIP = medIPstr.c_str(); + + size_t numDocs = static_cast(reader->numDocs()); + + assertEqualsMsg(_T("num of docs"), numDocs, static_cast(1+ maxId - minId)); + + Hits* result; + Term* term = _CLNEW Term(_T("body"),_T("body")); + Query* q = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + // test id, bounded on both ends + + Filter* f = _CLNEW RangeFilter(_T("id"),minIP,maxIP,T,T); + result = search->search(q, f); + assertEqualsMsg(_T("find all"), numDocs, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,maxIP,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("all but last"), numDocs-1, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f =_CLNEW RangeFilter(_T("id"),minIP,maxIP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("all but first"), numDocs-1, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,maxIP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("all but ends"), numDocs-2, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),medIP,maxIP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("med and up"), 1+ maxId-medId, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,medIP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("up to med"), 1+ medId-minId, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + // unbounded id + + f=_CLNEW RangeFilter(_T("id"),minIP,NULL,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("min and up"), numDocs, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),NULL,maxIP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("max and down"), numDocs, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,NULL,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("not min, but up"), numDocs-1, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),NULL,maxIP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("not max, but down"), numDocs-1, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),medIP,maxIP,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("med and up, not max"), maxId-medId, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,medIP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("not min, up to med"), medId-minId, result->length()); + _CLLDELETE(result); + _CLLDELETE(f); + + // very small sets + + f=_CLNEW RangeFilter(_T("id"),minIP,minIP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("min,min,F,F"), 0, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("id"),medIP,medIP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("med,med,F,F"), 0, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("id"),maxIP,maxIP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("max,max,F,F"), 0, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),minIP,minIP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("min,min,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("id"),NULL,minIP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("nul,min,F,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),maxIP,maxIP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("max,max,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("id"),maxIP,NULL,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("max,nul,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("id"),medIP,medIP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("med,med,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + search->close(); + _CLLDELETE(search); + + reader->close(); + _CLLDELETE(reader); + + _CLLDELETE(q); + } + + void testRangeFilterRand() + { + IndexReader* reader = IndexReader::open(index); + IndexSearcher* search = _CLNEW IndexSearcher(reader); + + std::tstring minRPstr = pad(minR); + const TCHAR* minRP = minRPstr.c_str(); + + std::tstring maxRPstr = pad(maxR); + const TCHAR* maxRP = maxRPstr.c_str(); + + size_t numDocs = static_cast(reader->numDocs()); + + assertEqualsMsg(_T("num of docs"), numDocs, 1+ maxId - minId); + + Hits* result; + Term* term = _CLNEW Term(_T("body"),_T("body")); + Query* q = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + // test extremes, bounded on both ends + + Filter* f = _CLNEW RangeFilter(_T("rand"),minRP,maxRP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("find all"), numDocs, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),minRP,maxRP,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("all but biggest"), numDocs-1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),minRP,maxRP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("all but smallest"), numDocs-1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),minRP,maxRP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("all but extremes"), numDocs-2, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + // unbounded + + f=_CLNEW RangeFilter(_T("rand"),minRP,NULL,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("smallest and up"), numDocs, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),NULL,maxRP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("biggest and down"), numDocs, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),minRP,NULL,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("not smallest, but up"), numDocs-1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),NULL,maxRP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("not biggest, but down"), numDocs-1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + // very small sets + + f=_CLNEW RangeFilter(_T("rand"),minRP,minRP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("min,min,F,F"), 0, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("rand"),maxRP,maxRP,F,F); + result = search->search(q,f); + assertEqualsMsg(_T("max,max,F,F"), 0, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),minRP,minRP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("min,min,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("rand"),NULL,minRP,F,T); + result = search->search(q,f); + assertEqualsMsg(_T("nul,min,F,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + f=_CLNEW RangeFilter(_T("rand"),maxRP,maxRP,T,T); + result = search->search(q,f); + assertEqualsMsg(_T("max,max,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + f=_CLNEW RangeFilter(_T("rand"),maxRP,NULL,T,F); + result = search->search(q,f); + assertEqualsMsg(_T("max,nul,T,T"), 1, result->length()); + _CLLDELETE(result); _CLLDELETE(f); + + search->close(); + _CLLDELETE(search); + + reader->close(); + _CLLDELETE(reader); + + _CLLDELETE(q); + } +}; + +void testRangeFilterTrigger(CuTest* tc) +{ + TestRangeFilter trf(tc); + trf.testRangeFilterId(); + trf.testRangeFilterRand(); +} + +void testIncludeLowerTrue(CuTest* tc) +{ + WhitespaceAnalyzer a; + RAMDirectory* index = _CLNEW RAMDirectory(); + IndexWriter* writer = _CLNEW IndexWriter(index, + &a, true); + + Document doc; + doc.add(*_CLNEW Field(_T("Category"), _T("a 1"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); doc.clear(); + + doc.add(*_CLNEW Field(_T("Category"), _T("a 2"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); doc.clear(); + + doc.add(*_CLNEW Field(_T("Category"), _T("a 3"), Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc); doc.clear(); + + writer->close(); + _CLLDELETE(writer); + + IndexSearcher* s = _CLNEW IndexSearcher(index); + Filter* f = _CLNEW RangeFilter(_T("Category"), _T("3"), _T("3"), true, true); + + Term* t = _CLNEW Term(_T("Category"), _T("a")); + Query* q1 = _CLNEW TermQuery(t); + _CLLDECDELETE(t); + + t = _CLNEW Term(_T("Category"), _T("3")); + Query* q2 = _CLNEW TermQuery(t); + _CLLDECDELETE(t); + + Hits* h = s->search(q1); + assertTrue(h->length() == 3); + _CLLDELETE(h); + + h = s->search(q2); + assertTrue(h->length() == 1); + _CLLDELETE(h); + + h = s->search(q1, f); + assertTrue(h->length() == 1); + _CLLDELETE(h); + + s->close(); + _CLLDELETE(s); + _CLLDELETE(q1); + _CLLDELETE(q2); + _CLLDELETE(f); + + index->close(); + _CLLDECDELETE(index); +} + +CuSuite *testRangeFilter(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene RangeFilter Test")); + + SUITE_ADD_TEST(suite, testRangeFilterTrigger); + SUITE_ADD_TEST(suite, testIncludeLowerTrue); + + return suite; +} + + +// EOF diff --git a/src/test/search/TestSearch.cpp b/src/test/search/TestSearch.cpp new file mode 100644 index 00000000000..14676ca7337 --- /dev/null +++ b/src/test/search/TestSearch.cpp @@ -0,0 +1,483 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include +#include "test.h" +#include + +#include "CLucene/search/MultiPhraseQuery.h" + + SimpleAnalyzer a; + StandardAnalyzer aStd; + WhitespaceAnalyzer aWS; + IndexSearcher* s=NULL; + + void _TestSearchesRun(CuTest *tc, Analyzer* analyzer, Searcher* search, const TCHAR* qry){ + Query* q = NULL; + Hits* h = NULL; + try{ + q = QueryParser::parse(qry , _T("contents"), analyzer); + if ( q != NULL ){ + h = search->search( q ); + + if ( h->length() > 0 ){ + //check for explanation memory leaks... + CL_NS(search)::Explanation expl1; + search->explain(q, h->id(0), &expl1); + TCHAR* tmp = expl1.toString(); + _CLDELETE_CARRAY(tmp); + if ( h->length() > 1 ){ //do a second one just in case + CL_NS(search)::Explanation expl2; + search->explain(q, h->id(1), &expl2); + tmp = expl2.toString(); + _CLDELETE_CARRAY(tmp); + } + } + } + }catch(CLuceneError& err){ + CuFail(tc,_T("Error: %s\n"), err.twhat()); + }catch(...){ + CuFail(tc,_T("Error: unknown\n")); + } + _CLDELETE(h); + _CLDELETE(q); + } + + void testSrchOpenIndex(CuTest *tc ){ + char loc[1024]; + strcpy(loc, clucene_data_location); + strcat(loc, "/reuters-21578-index"); + + CuAssert(tc,_T("Index does not exist"), Misc::dir_Exists(loc)); + s=_CLNEW IndexSearcher(loc); + } + void testSrchCloseIndex(CuTest* /*tc*/ ){ + if ( s!=NULL ){ + s->close(); + _CLDELETE(s); + } + } + + void testSrchPunctuation(CuTest *tc ){ + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + + //test punctuation + _TestSearchesRun(tc, &a,s, _T("a&b") ); + _TestSearchesRun(tc, &a,s, _T("a&&b") ); + _TestSearchesRun(tc, &a,s, _T(".NET") ); + } + + void testSrchSlop(CuTest *tc ){ +#ifdef NO_FUZZY_QUERY + CuNotImpl(tc,_T("Fuzzy")); +#else + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + //test slop + _TestSearchesRun(tc, &a,s, _T("\"term germ\"~2") ); + _TestSearchesRun(tc, &a,s, _T("\"term germ\"~2 flork") ); + _TestSearchesRun(tc, &a,s, _T("\"term\"~2") ); + _TestSearchesRun(tc, &a,s, _T("\" \"~2 germ") ); + _TestSearchesRun(tc, &a,s, _T("\"term germ\"~2^2") ); +#endif + } + + void testSrchNumbers(CuTest *tc ){ + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + + // The numbers go away because SimpleAnalzyer ignores them + _TestSearchesRun(tc, &a,s, _T("3") ); + _TestSearchesRun(tc, &a,s, _T("term 1.0 1 2") ); + _TestSearchesRun(tc, &a,s, _T("term term1 term2") ); + + _TestSearchesRun(tc, &aStd,s, _T("3") ); + _TestSearchesRun(tc, &aStd,s, _T("term 1.0 1 2") ); + _TestSearchesRun(tc, &aStd,s, _T("term term1 term2") ); + } + + void testSrchWildcard(CuTest *tc ){ +#ifdef NO_WILDCARD_QUERY + CuNotImpl(tc,_T("Wildcard")); +#else + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + //testWildcard + _TestSearchesRun(tc, &a,s, _T("term*") ); + _TestSearchesRun(tc, &a,s, _T("term*^2") ); + _TestSearchesRun(tc, &a,s, _T("term~") ); + _TestSearchesRun(tc, &a,s, _T("term^2~") ); + _TestSearchesRun(tc, &a,s, _T("term~^2") ); + _TestSearchesRun(tc, &a,s, _T("term*germ") ); + _TestSearchesRun(tc, &a,s, _T("term*germ^3") ); + + //test problem reported by Gary Mangum + BooleanQuery* bq = _CLNEW BooleanQuery(); + Term* upper = _CLNEW Term(_T("contents"),_T("0105")); + Term* lower = _CLNEW Term(_T("contents"),_T("0105")); + RangeQuery* rq=_CLNEW RangeQuery(lower,upper,true); + bq->add(rq,true,true,false); + _CLDECDELETE(upper); + _CLDECDELETE(lower); + + Term* prefix = _CLNEW Term(_T("contents"),_T("reuters21578")); + PrefixQuery* pq = _CLNEW PrefixQuery(prefix); + _CLDECDELETE(prefix); + bq->add(pq,true,true,false); + + Hits* h = NULL; + try{ + h = s->search( bq ); + }_CLFINALLY( + _CLDELETE(h); + _CLDELETE(bq); + ); +#endif + } + + void testSrchEscapes(CuTest *tc ){ + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + //testEscaped + _TestSearchesRun(tc, &aWS,s, _T("\\[brackets") ); + _TestSearchesRun(tc, &a,s, _T("\\[brackets") ); + _TestSearchesRun(tc, &aWS,s, _T("\\\\") ); + _TestSearchesRun(tc, &aWS,s, _T("\\+blah") ); + _TestSearchesRun(tc, &aWS,s, _T("\\(blah") ); + } + + void testSrchRange(CuTest *tc ){ +#ifdef NO_RANGE_QUERY + CuNotImpl(tc,_T("Range")); +#else + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + //testRange + _TestSearchesRun(tc, &a,s, _T("[ j m]") ); + _TestSearchesRun(tc, &a,s, _T("[ j m ]") ); + _TestSearchesRun(tc, &a,s, _T("{ j m}") ); + _TestSearchesRun(tc, &a,s, _T("{ j m }") ); + _TestSearchesRun(tc, &a,s, _T("{a TO b}") ); + _TestSearchesRun(tc, &a,s, _T("{ j m }^2.0") ); + _TestSearchesRun(tc, &a,s, _T("[ j m] OR bar") ); + _TestSearchesRun(tc, &a,s, _T("[ j m] AND bar") ); + _TestSearchesRun(tc, &a,s, _T("( bar blar { j m}) ") ); + _TestSearchesRun(tc, &a,s, _T("gack ( bar blar { j m}) ") ); +#endif + } + + void testSrchSimple(CuTest *tc ){ + CuAssert(tc,_T("Searcher was not open"),s!=NULL); + //simple tests + _TestSearchesRun(tc, &a,s, _T("a AND b") ); + + _TestSearchesRun(tc, &a,s, _T("term term term") ); + +#ifdef _UCS2 + TCHAR tmp1[100]; + lucene_utf8towcs(tmp1,"t\xc3\xbcrm term term",100); + _TestSearchesRun(tc, &a,s, tmp1 ); + + lucene_utf8towcs(tmp1,"\xc3\xbcmlaut",100); + _TestSearchesRun(tc, &a,s, tmp1 ); +#endif + + _TestSearchesRun(tc, &a,s, _T("(a AND b)") ); + _TestSearchesRun(tc, &a,s, _T("c OR (a AND b)") ); + _TestSearchesRun(tc, &a,s, _T("a AND NOT b") ); + _TestSearchesRun(tc, &a,s, _T("a AND -b") ); + _TestSearchesRun(tc, &a,s, _T("a AND !b") ); + _TestSearchesRun(tc, &a,s, _T("a && b") ); + _TestSearchesRun(tc, &a,s, _T("a && ! b") ); + + _TestSearchesRun(tc, &a,s, _T("a OR b") ); + _TestSearchesRun(tc, &a,s, _T("a || b") ); + _TestSearchesRun(tc, &a,s, _T("a OR !b") ); + _TestSearchesRun(tc, &a,s, _T("a OR ! b") ); + _TestSearchesRun(tc, &a,s, _T("a OR -b") ); + + _TestSearchesRun(tc, &a,s, _T("+term -term term") ); + _TestSearchesRun(tc, &a,s, _T("foo:term AND field:anotherTerm") ); + _TestSearchesRun(tc, &a,s, _T("term AND \"phrase phrase\"") ); + _TestSearchesRun(tc, &a,s, _T("search AND \"meaningful direction\"") ); + _TestSearchesRun(tc, &a,s, _T("\"hello there\"") ); + + _TestSearchesRun(tc, &a,s, _T("a AND b") ); + _TestSearchesRun(tc, &a,s, _T("hello") ); + _TestSearchesRun(tc, &a,s, _T("\"hello there\"") ); + + _TestSearchesRun(tc, &a,s, _T("germ term^2.0") ); + _TestSearchesRun(tc, &a,s, _T("term^2.0") ); + _TestSearchesRun(tc, &a,s, _T("term^2") ); + _TestSearchesRun(tc, &a,s, _T("term^2.3") ); + _TestSearchesRun(tc, &a,s, _T("\"germ term\"^2.0") ); + _TestSearchesRun(tc, &a,s, _T("\"term germ\"^2") ); + + _TestSearchesRun(tc, &a,s, _T("(foo OR bar) AND (baz OR boo)") ); + _TestSearchesRun(tc, &a,s, _T("((a OR b) AND NOT c) OR d") ); + _TestSearchesRun(tc, &a,s, _T("+(apple \"steve jobs\") -(foo bar baz)") ); + + _TestSearchesRun(tc, &a,s, _T("+title:(dog OR cat) -author:\"bob dole\"") ); + + + _TestSearchesRun(tc, &a,s, _T(".*") ); + _TestSearchesRun(tc, &a,s, _T("<*") ); + _TestSearchesRun(tc, &a,s, _T("/*") ); + _TestSearchesRun(tc, &a,s, _T(";*") ); + } + +void SearchTest(CuTest *tc, bool bram) { + uint64_t start = Misc::currentTimeMillis(); + + SimpleAnalyzer analyzer; + + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir,CL_MAX_PATH,"%s/%s",cl_tempDir, "test.search"); + Directory* ram = (bram?(Directory*)_CLNEW RAMDirectory():(Directory*)FSDirectory::getDirectory(fsdir) ); + + IndexWriter writer( ram, &analyzer, true); + writer.setUseCompoundFile(false); + writer.setMaxBufferedDocs(3); + + const TCHAR* docs[] = { _T("a b c d e asdf"), + _T("a b c d e a b c d e asdg"), + _T("a b c d e f g h i j"), + _T("a c e"), + _T("e c a"), + _T("a c e a c e asef"), + _T("a c e a b c") + }; + + for (int j = 0; j < 7; j++) { + Document* d = _CLNEW Document(); + //no need to delete fields... document takes ownership + d->add(*_CLNEW Field(_T("contents"),docs[j],Field::STORE_YES | Field::INDEX_TOKENIZED)); + + writer.addDocument(d); + _CLDELETE(d); + } + writer.close(); + + if (!bram){ + ram->close(); + _CLDECDELETE(ram); + ram = (Directory*)FSDirectory::getDirectory(fsdir); + } + + IndexReader* reader = IndexReader::open(ram); + IndexSearcher searcher(reader); + + const TCHAR* queries[] = { + _T("a AND NOT b"), + _T("+a -b"), + _T("\"a b\""), + _T("\"a b c\""), + _T("a AND b"), + _T("a c"), + _T("\"a c\""), + _T("\"a c e\"") + }; + int shouldbe[] = {3,3,4,4,4,7,3,3}; + Hits* hits = NULL; + QueryParser parser(_T("contents"), &analyzer); + + for (int k = 0; k < 8; k++) { + Query* query = parser.parse(queries[k]); + + TCHAR* qryInfo = query->toString(_T("contents")); + hits = searcher.search(query); + CLUCENE_ASSERT( hits->length() == shouldbe[k] ); + _CLDELETE_CARRAY(qryInfo); + _CLDELETE(hits); + _CLDELETE(query); + } + + //test MultiPositionQuery... + { + MultiPhraseQuery* query = _CLNEW MultiPhraseQuery(); + RefCountArray terms(3); + Term* termE = _CLNEW Term(_T("contents"), _T("e")); + terms[0] = _CLNEW Term(_T("contents"), _T("asdf")); + terms[1] = _CLNEW Term(_T("contents"), _T("asdg")); + terms[2] = _CLNEW Term(_T("contents"), _T("asef")); + + query->add(termE); + _CLDECDELETE(termE); + + query->add(&terms); + terms.deleteValues(); + + TCHAR* qryInfo = query->toString(_T("contents")); + hits = searcher.search(query); + CLUCENE_ASSERT( hits->length() == 3 ); + _CLDELETE_CARRAY(qryInfo); + _CLDELETE(hits); + _CLDELETE(query); + } + + searcher.close(); + reader->close(); + _CLDELETE( reader ); + + ram->close(); + _CLDECDELETE(ram); + + CuMessageA (tc,"took %d milliseconds\n", (int32_t)(Misc::currentTimeMillis()-start)); +} + +void testNormEncoding(CuTest *tc) { + //just a quick test of the default similarity + CLUCENE_ASSERT(CL_NS(search)::Similarity::getDefault()->queryNorm(1)==1.0); + + float_t f = CL_NS(search)::Similarity::getDefault()->queryNorm(9); + f -= (1.0/3.0); + if ( f < 0 ) + f *= -1; + CLUCENE_ASSERT(f < 0.1); + + //test that div by zero is handled + float_t tmp = CL_NS(search)::Similarity::getDefault()->lengthNorm(_T("test"),0); + tmp = CL_NS(search)::Similarity::getDefault()->queryNorm(0); + + //test that norm encoding is working properly + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(-1)==0 ); + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(0)==0 ); + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(1)==124 ); + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(1)==124 ); + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(7516192768.0 )==255); + + + CLUCENE_ASSERT( CL_NS(search)::Similarity::decodeNorm(124)==1 ); + CLUCENE_ASSERT( CL_NS(search)::Similarity::decodeNorm(255)==7516192768.0 ); + + //well know value: + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(0.5f) == 120 ); + + //can decode self + CLUCENE_ASSERT( CL_NS(search)::Similarity::encodeNorm(CL_NS(search)::Similarity::decodeNorm(57)) == 57 ); +} + +void testSrchManyHits(CuTest* /*tc*/) { + SimpleAnalyzer analyzer; + RAMDirectory ram; + IndexWriter writer( &ram, &analyzer, true); + + const TCHAR* docs[] = { _T("a b c d e"), + _T("a b c d e a b c d e"), + _T("a b c d e f g h i j"), + _T("a c e"), + _T("e c a"), + _T("a c e a c e"), + _T("a c e a b c") + }; + + for (int j = 0; j < 140; j++) { + Document* d = _CLNEW Document(); + //no need to delete fields... document takes ownership + int x = j%7; + d->add(*_CLNEW Field(_T("contents"),docs[x],Field::STORE_YES | Field::INDEX_TOKENIZED)); + + writer.addDocument(d); + _CLDELETE(d); + } + writer.close(); + + IndexSearcher searcher(&ram); + + BooleanQuery query; + Term* t = _CLNEW Term(_T("contents"), _T("a")); + query.add(_CLNEW TermQuery(t),true,false, false); + _CLDECDELETE(t); + Hits* hits = searcher.search(&query); + for ( size_t x=0;xlength();x++ ){ + hits->doc(x); + } + _CLDELETE(hits); + searcher.close(); +} + +void testSrchMulti(CuTest *tc) { + SimpleAnalyzer analyzer; + RAMDirectory ram0; + IndexWriter writer0( &ram0, &analyzer, true); + + const TCHAR* docs0[] = { + _T("a") + }; + + Document* d = _CLNEW Document(); + //no need to delete fields... document takes ownership + d->add(*_CLNEW Field(_T("contents"),docs0[0],Field::STORE_YES | Field::INDEX_TOKENIZED)); + + writer0.addDocument(d); + _CLDELETE(d); + writer0.close(); + + RAMDirectory ram1; + IndexWriter writer1( &ram1, &analyzer, true); + + const TCHAR* docs1[] = { + _T("e") + }; + + d = _CLNEW Document(); + //no need to delete fields... document takes ownership + d->add(*_CLNEW Field(_T("contents"),docs1[0],Field::STORE_YES | Field::INDEX_TOKENIZED)); + + writer1.addDocument(d); + _CLDELETE(d); + writer1.close(); + + IndexSearcher searcher0(&ram0); + IndexSearcher searcher1(&ram1); + + Searchable* searchers[3]; + + searchers[0] = &searcher0; + searchers[1] = &searcher1; + searchers[2] = NULL; + + MultiSearcher searcher(searchers); + + Term* termA = _CLNEW Term(_T("contents"), _T("a")); + Term* termC = _CLNEW Term(_T("contents"), _T("c")); + RangeQuery query(termA, termC, true); + _CLDECDELETE(termA); + _CLDECDELETE(termC); + + Query* rewritten = searcher.rewrite(&query); + Hits* hits = searcher.search(rewritten); + for ( size_t x=0;xlength();x++ ){ + hits->doc(x); + } + CLUCENE_ASSERT(hits->length() == 1); + if (&query != rewritten) { + _CLDELETE(rewritten); + } + _CLDELETE(hits); + searcher.close(); +} + +void ramSearchTest(CuTest *tc) { SearchTest(tc, true); } +void fsSearchTest(CuTest *tc) { SearchTest(tc, false); } + +CuSuite *testsearch(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Search Test")); + SUITE_ADD_TEST(suite, ramSearchTest); + SUITE_ADD_TEST(suite, fsSearchTest); + + SUITE_ADD_TEST(suite, testNormEncoding); + SUITE_ADD_TEST(suite, testSrchManyHits); + SUITE_ADD_TEST(suite, testSrchMulti); + SUITE_ADD_TEST(suite, testSrchOpenIndex); + SUITE_ADD_TEST(suite, testSrchPunctuation); + SUITE_ADD_TEST(suite, testSrchSlop); + SUITE_ADD_TEST(suite, testSrchNumbers); + SUITE_ADD_TEST(suite, testSrchWildcard); + SUITE_ADD_TEST(suite, testSrchEscapes); + SUITE_ADD_TEST(suite, testSrchRange); + SUITE_ADD_TEST(suite, testSrchSimple); + SUITE_ADD_TEST(suite, testSrchCloseIndex); + + return suite; +} +// EOF diff --git a/src/test/search/TestSort.cpp b/src/test/search/TestSort.cpp new file mode 100644 index 00000000000..fdccffc30e3 --- /dev/null +++ b/src/test/search/TestSort.cpp @@ -0,0 +1,552 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +/** + * Unit tests for sorting code. + * + */ + +__asm__(".symver log,log@GLIBC_2.2.5"); +__asm__(".symver pow,pow@GLIBC_2.2.5"); +__asm__(".symver logf,logf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); + +Searcher* sort_full; +Searcher* sort_searchX; +Searcher* sort_searchY; +Query* sort_queryX; +Query* sort_queryY; +Query* sort_queryA; +Query* sort_queryF; +Sort* _sort; +SimpleAnalyzer sort_analyser; + +typedef StringMap sortScores; +typedef std::pair scorePair; + +// document data: +// the tracer field is used to determine which document was hit +// the contents field is used to search and _sort by relevance +// the int field to _sort by int +// the float field to _sort by float +// the string field to _sort by string +const TCHAR* data1[11][6] = { + // tracer contents int float string custom + { _T("A"), _T("x a"), _T("5"), _T("4f"), _T("c"), _T("A-3") }, + { _T("B"), _T("y a"), _T("5"), _T("3.4028235E38"), _T("i"), _T("B-10") }, + { _T("C"), _T("x a b c"), _T("2147483647"), _T("1.0"), _T("j"), _T("A-2") }, + { _T("D"), _T("y a b c"), _T("-1"), _T("0.0f"), _T("a"), _T("C-0") }, + { _T("E"), _T("x a b c d"), _T("5"), _T("2f"), _T("h"), _T("B-8") }, + { _T("F"), _T("y a b c d"), _T("2"), _T("3.14159f"), _T("g"), _T("B-1") }, + { _T("G"), _T("x a b c d"), _T("3"), _T("-1.0"), _T("f"), _T("C-100") }, + { _T("H"), _T("y a b c d"), _T("0"), _T("1.4E-45"), _T("e"), _T("C-88") }, + { _T("I"), _T("x a b c d e f"), _T("-2147483648"), _T("1.0e+0"), _T("d"), _T("A-10") }, + { _T("J"), _T("y a b c d e f"), _T("4"), _T(".5"), _T("b"), _T("C-7") }, + { _T("Z"), _T("f"), NULL, NULL, NULL, NULL } + }; + +Searcher* sort_getIndex (bool even, bool odd){ + RAMDirectory* indexStore = _CLNEW RAMDirectory; + IndexWriter writer(indexStore, &sort_analyser, true); + for (int i=0; i<11; ++i) { + if (((i%2)==0 && even) || ((i%2)==1 && odd)) { + Document doc; + doc.add (*_CLNEW Field ( _T("tracer"), data1[i][0], Field::STORE_YES)); + doc.add (*_CLNEW Field ( _T("contents"), data1[i][1], Field::INDEX_TOKENIZED)); + if (data1[i][2] != NULL) + doc.add (*_CLNEW Field (_T("int"), data1[i][2], Field::INDEX_UNTOKENIZED)); + if (data1[i][3] != NULL) + doc.add (*_CLNEW Field (_T("float"), data1[i][3], Field::INDEX_UNTOKENIZED)); + if (data1[i][4] != NULL) + doc.add (*_CLNEW Field (_T("string"), data1[i][4], Field::INDEX_UNTOKENIZED)); + if (data1[i][5] != NULL) + doc.add (*_CLNEW Field (_T("custom"), data1[i][5], Field::INDEX_UNTOKENIZED)); + writer.addDocument (&doc); + } + } + writer.close (); + IndexSearcher* res = _CLNEW IndexSearcher(indexStore); + _CLDECDELETE(indexStore); + return res; +} + +void testSortSetup(CuTest* /*tc*/) { + sort_full = sort_getIndex (true, true); + sort_searchX = sort_getIndex (true, false); + sort_searchY = sort_getIndex (false, true); + + Term* tmp; + + tmp = _CLNEW Term (_T("contents"), _T("x")); + sort_queryX = _CLNEW TermQuery (tmp); + _CLDECDELETE(tmp); + + tmp = _CLNEW Term (_T("contents"), _T("y")); + sort_queryY = _CLNEW TermQuery (tmp); + _CLDECDELETE(tmp); + + tmp = _CLNEW Term (_T("contents"), _T("a")); + sort_queryA = _CLNEW TermQuery (tmp); + _CLDECDELETE(tmp); + + tmp = _CLNEW Term (_T("contents"), _T("f")); + sort_queryF = _CLNEW TermQuery (tmp); + _CLDECDELETE(tmp); + + _sort = _CLNEW Sort(); +} + +void testSortCleanup(CuTest* /*tc*/) { + _CLDELETE(sort_full); + _CLDELETE(sort_searchX); + _CLDELETE(sort_searchY); + _CLDELETE(sort_queryX); + _CLDELETE(sort_queryY); + _CLDELETE(sort_queryA); + _CLDELETE(sort_queryF); + _CLDELETE(_sort); +} + +// make sure the documents returned by the search match the expected list +void sortMatches (CuTest *tc, Searcher* searcher, Query* query, Sort* sort, const TCHAR* expectedResult){ + Hits* result = searcher->search (query, sort); + StringBuffer buff(10); + int32_t n = result->length(); + for (int i=0; idoc(i); + TCHAR** v = doc.getValues(_T("tracer")); //todo: should be const??? + for (int j=0; v[j]!=NULL; ++j) { + buff.append (v[j]); + } + _CLDELETE_CARRAY_ALL(v); + } + CuAssertStrEquals (tc, _T("tracer value"), expectedResult, buff.getBuffer()); + + _CLDELETE(result); +} +void sortSameValues (CuTest* tc, sortScores* m1, sortScores* m2, bool deleteM1=false, bool deleteM2=true) { + CuAssertIntEquals (tc, _T("sortScores size not equal"),m1->size(), m2->size()); + sortScores::iterator iter = m1->begin(); + float_t m=pow(10.0,-8); + while (iter != m1->end()) { + TCHAR* key = iter->first; + + sortScores::iterator i1 = m1->find(key); + sortScores::iterator i2 = m2->find(key); + + float_t f1 = i1->second; + float_t f2 = i2->second; + + float_t diff = f1-f2; + if ( diff < 0 ) + diff *= -1; + if ( diff>m ) + CuAssert(tc,_T("sortSameValue f1!=f2"),false); + iter++; + } + + if ( deleteM1 ) + _CLDELETE(m1); + if ( deleteM2 ) + _CLDELETE(m2); +} +// make sure the documents returned by the search match the expected list pattern +void sortMatchesPattern (CuTest* tc, Searcher* searcher, Query* query, Sort* sort, const TCHAR* pattern){ + Hits* result = searcher->search (query, sort); + int32_t n = result->length(); + StringBuffer buff; + for (int i=0; idoc(i); + TCHAR** v = doc.getValues(_T("tracer")); + for (int j=0; v[j]!=NULL; ++j) { + buff.append (v[j]); + } + _CLDELETE_CARRAY_ALL(v); + } + + //todo:need to actually test these matches... don't have regexp... + CuMessage(tc,_T("\nmatching \"%s\" against pattern \"%s\""),buff.getBuffer(),pattern); + // System.out.println ("matching \""+buff+"\" against pattern \""+pattern+"\""); + //assertTrue (Pattern.compile(pattern).matcher(buff.toString()).matches()); + + _CLDELETE(result); +} + +// runs a variety of sorts useful for multisearchers +void sort_runMultiSorts (CuTest* tc, Searcher* multi) { + _sort->setSort (SortField::FIELD_DOC()); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("[AB]{2}[CD]{2}[EF]{2}[GH]{2}[IJ]{2}")); + + _sort->setSort (_CLNEW SortField (_T("int"), SortField::INT, false)); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("IDHFGJ[ABE]{3}C")); + + SortField* sorts1[3]= {_CLNEW SortField (_T("int"), SortField::INT, false), SortField::FIELD_DOC(), NULL}; + _sort->setSort ( sorts1 ); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("IDHFGJ[AB]{2}EC")); + + _sort->setSort (_T("int")); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("IDHFGJ[AB]{2}EC")); + + SortField* sorts2[3] = { _CLNEW SortField (_T("float"), SortField::FLOAT, false), SortField::FIELD_DOC(), NULL}; + _sort->setSort (sorts2); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("GDHJ[CI]{2}EFAB")); + + _sort->setSort (_T("float")); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("GDHJ[CI]{2}EFAB")); + + _sort->setSort (_T("string")); + sortMatches (tc, multi, sort_queryA, _sort, _T("DJAIHGFEBC")); + + _sort->setSort (_T("int"), true); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("C[AB]{2}EJGFHDI")); + + _sort->setSort (_T("float"), true); + sortMatchesPattern (tc, multi, sort_queryA, _sort, _T("BAFE[IC]{2}JHDG")); + + _sort->setSort (_T("string"), true); + sortMatches (tc, multi, sort_queryA, _sort, _T("CBEFGHIAJD")); + + //_sort->setSort (_CLNEW SortField[] { _CLNEW SortField (_T("string"), Locale.US) }); + //sortMatches (tc, multi, sort_queryA, _sort, _T("DJAIHGFEBC")); + + //_sort->setSort (_CLNEW SortField[] { _CLNEW SortField (_T("string"), Locale.US, true) }); + //sortMatches (tc, multi, sort_queryA, _sort, _T("CBEFGHIAJD")); + + const TCHAR* sorts3[3] = {_T("int"),_T("float"),NULL}; + _sort->setSort ( sorts3 ); + sortMatches (tc, multi, sort_queryA, _sort, _T("IDHFGJEABC")); + + const TCHAR* sorts4[3] = {_T("float"),_T("string"),NULL}; + _sort->setSort (sorts4); + sortMatches (tc, multi, sort_queryA, _sort, _T("GDHJICEFAB")); + + _sort->setSort (_T("int")); + sortMatches (tc, multi, sort_queryF, _sort, _T("IZJ")); + + _sort->setSort (_T("int"), true); + sortMatches (tc, multi, sort_queryF, _sort, _T("JZI")); + + _sort->setSort (_T("float")); + sortMatches (tc, multi, sort_queryF, _sort, _T("ZJI")); + + _sort->setSort (_T("string")); + sortMatches (tc, multi, sort_queryF, _sort, _T("ZJI")); + + _sort->setSort (_T("string"), true); + sortMatches (tc, multi, sort_queryF, _sort, _T("IJZ")); +} + + sortScores* sort_getScores (CuTest* tc, Hits* hits, bool deleteHits=true){ + sortScores* scoreMap = _CLNEW sortScores(true); + int n = hits->length(); + float_t m=pow(10.0,-8); + + for (int i=0; idoc(i); + TCHAR** v = doc.getValues( _T("tracer")); + + int vLength=0; + while(v[vLength]!=NULL) + vLength++; + + CuAssertIntEquals (tc, _T("tracer values"), vLength, 1); + + if ( scoreMap->find(v[0]) != scoreMap->end () ){ + //this (should) be a multi search... the document will be double, so here we check that + //the existing value is the same as this value... and then delete and ignore it. + float_t diff = scoreMap->find(v[0])->second - hits->score(i); + if ( diff < 0 ) + diff *= -1; + if ( diff>m ) + CuAssert(tc,_T("sort_getScores(multi or incorrect) f1!=f2"),false); + + _CLDELETE_CARRAY_ALL(v); + }else{ + scoreMap->insert ( scorePair(v[0], hits->score(i)) ); + _CLDELETE_ARRAY(v); + } + } + if ( deleteHits ) + _CLDELETE(hits); + return scoreMap; +} + + + +////////////////////////////////////////////////////////////////////// +// The actual tests +////////////////////////////////////////////////////////////////////// +void testBuiltInSorts(CuTest *tc) { + _CLDELETE(_sort); + _sort = _CLNEW Sort(); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("ACEGI")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("BDFHJ")); + + _sort->setSort(SortField::FIELD_DOC()); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("ACEGI")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("BDFHJ")); +} + +// test sorts where the type of field is specified +void testTypedSort(CuTest *tc){ + SortField* sorts1[3] = { _CLNEW SortField (_T("int"), SortField::INT,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts1); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("IGAEC")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DHFJB")); + + SortField* sorts2[3] = { _CLNEW SortField (_T("float"), SortField::FLOAT,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts2); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("GCIEA")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DHJFB")); + + SortField* sorts3[3] = { _CLNEW SortField (_T("string"), SortField::STRING,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts3); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("AIGEC")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DJHFB")); +} + +// test sorts when there's nothing in the index +void testEmptyIndex(CuTest *tc) { + Searcher* empty = sort_getIndex(false,false); + + _CLDELETE(_sort); + _sort = _CLNEW Sort(); + sortMatches (tc, empty, sort_queryX, _sort, _T("")); + + _sort->setSort(SortField::FIELD_DOC()); + sortMatches (tc, empty, sort_queryX, _sort, _T("")); + + SortField* sorts1[3] = { _CLNEW SortField (_T("int"), SortField::INT,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts1); + sortMatches (tc, empty, sort_queryX, _sort, _T("")); + + SortField* sorts3[3] = { _CLNEW SortField (_T("string"), SortField::STRING,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts3); + sortMatches (tc, empty, sort_queryX, _sort, _T("")); + + SortField* sorts2[3] = { _CLNEW SortField (_T("float"), SortField::FLOAT,false), SortField::FIELD_DOC(), NULL }; + _sort->setSort (sorts2); + sortMatches (tc, empty, sort_queryX, _sort, _T("")); + + _CLDELETE(empty); +} + +// test sorts where the type of field is determined dynamically +void testAutoSort(CuTest *tc) { + _sort->setSort(_T("int")); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("IGAEC")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DHFJB")); + + _sort->setSort(_T("float")); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("GCIEA")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DHJFB")); + + _sort->setSort(_T("string")); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("AIGEC")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("DJHFB")); +} + +// test sorts in reverse +void testReverseSort(CuTest *tc){ + /*SortField* sorts[3] = { _CLNEW SortField (NULL, SortField::INT,true), SortField::FIELD_DOC, NULL }; + _sort->setSort (sorts); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("IEGCA")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("JFHDB"));*/ + + _sort->setSort (_CLNEW SortField (NULL, SortField::DOC, true)); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("IGECA")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("JHFDB")); + + _sort->setSort (_T("int"), true); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("CAEGI")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("BJFHD")); + + _sort->setSort (_T("float"), true); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("AECIG")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("BFJHD")); + + _sort->setSort (_T("string"), true); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("CEGIA")); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("BFHJD")); +} + +void testEmptyFieldSort(CuTest *tc) { + _sort->setSort ( _T("string")); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("ZJI")); + + _sort->setSort ( _T("string"), true); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("IJZ")); + + _sort->setSort ( _T("int")); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("IZJ")); + + _sort->setSort ( _T("int"), true); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("JZI")); + + _sort->setSort ( _T("float")); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("ZJI")); + + _sort->setSort ( _T("float"), true); + sortMatches (tc, sort_full, sort_queryF, _sort, _T("IJZ")); +} + + +// test sorts using a series of fields +void testSortCombos(CuTest *tc) { + const TCHAR* sorts1[3]= {_T("int"),_T("float"), NULL}; + _sort->setSort ( sorts1 ); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("IGEAC")); + + SortField* sorts2[3] = { _CLNEW SortField (_T("int"), SortField::AUTO, true), + _CLNEW SortField (NULL, SortField::DOC, true), NULL }; + _sort->setSort ( sorts2); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("CEAGI")); + + const TCHAR* sorts3[3]= {_T("float"),_T("string"), NULL}; + _sort->setSort (sorts3); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("GICEA")); +} + +// test a custom _sort function +/*void testCustomSorts(CuTest *tc) { + _sort->setSort (_CLNEW SortField (_T("custom"), SampleComparable.getComparatorSource())); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("CAIEG")); + + _sort->setSort (_CLNEW SortField (_T("custom"), SampleComparable.getComparatorSource(), true)); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("HJDBF")); + + SortComparator custom = SampleComparable.getComparator(); + _sort->setSort (_CLNEW SortField (_T("custom"), custom)); + sortMatches (tc, sort_full, sort_queryX, _sort, _T("CAIEG")); + + _sort->setSort (_CLNEW SortField (_T("custom"), custom, true)); + sortMatches (tc, sort_full, sort_queryY, _sort, _T("HJDBF")); +}*/ + +// test a variety of sorts using more than one searcher +void testMultiSort(CuTest *tc) { + Searchable* searchables[3] ={ sort_searchX, sort_searchY, NULL }; + MultiSearcher searcher(searchables); + + sort_runMultiSorts (tc, &searcher); + searcher.close(); +} + + +// test that the relevancy scores are the same even if +// hits are sorted +void testNormalizedScores(CuTest *tc) { + + // capture relevancy scores + sortScores* scoresX = sort_getScores (tc, sort_full->search (sort_queryX)); + sortScores* scoresY = sort_getScores (tc, sort_full->search (sort_queryY)); + sortScores* scoresA = sort_getScores (tc, sort_full->search (sort_queryA)); + + // we'll test searching locally, remote and multi + // note: the multi test depends on each separate index containing + // the same documents as our local index, so the computed normalization + // will be the same. so we make a multi searcher over two equal document + // sets - not realistic, but necessary for testing. + //MultiSearcher remote(_CLNEW Searchable[] { getRemote() }); + Searchable* searchables[3] = { sort_full, sort_full,NULL }; + MultiSearcher multi( searchables ); + + // change sorting and make sure relevancy stays the same + + _CLDELETE(_sort); + _sort = _CLNEW Sort(); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + _sort->setSort(SortField::FIELD_DOC()); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + _sort->setSort (_T("int")); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + _sort->setSort (_T("float")); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + _sort->setSort (_T("string")); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + const TCHAR* sorts1[3] = { _T("int"),_T("float"),NULL}; + _sort->setSort ( sorts1 ); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + SortField* sorts2[3] = { _CLNEW SortField (_T("int"), SortField::AUTO, true), _CLNEW SortField (NULL, SortField::DOC, true), NULL }; + _sort->setSort ( sorts2 ); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + const TCHAR* sorts3[3] = { _T("float"),_T("string"),NULL}; + _sort->setSort (sorts3); + sortSameValues (tc, scoresX, sort_getScores(tc, sort_full->search(sort_queryX,_sort))); + sortSameValues (tc, scoresX, sort_getScores(tc, multi.search(sort_queryX,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, sort_full->search(sort_queryY,_sort))); + sortSameValues (tc, scoresY, sort_getScores(tc, multi.search(sort_queryY,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, sort_full->search(sort_queryA,_sort))); + sortSameValues (tc, scoresA, sort_getScores(tc, multi.search(sort_queryA,_sort))); + + _CLDELETE(scoresX); + _CLDELETE(scoresY); + _CLDELETE(scoresA); +} + +CuSuite *testsort(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Sort Test")); + SUITE_ADD_TEST(suite, testSortSetup); + + SUITE_ADD_TEST(suite, testBuiltInSorts); + SUITE_ADD_TEST(suite, testTypedSort); + SUITE_ADD_TEST(suite, testEmptyIndex); + SUITE_ADD_TEST(suite, testAutoSort); + SUITE_ADD_TEST(suite, testEmptyFieldSort); + SUITE_ADD_TEST(suite, testSortCombos); + //SUITE_ADD_TEST(suite, testCustomSorts); + SUITE_ADD_TEST(suite, testMultiSort); + SUITE_ADD_TEST(suite, testNormalizedScores); + SUITE_ADD_TEST(suite, testReverseSort); + + SUITE_ADD_TEST(suite, testSortCleanup); + return suite; +} +// EOF diff --git a/src/test/search/TestTermVector.cpp b/src/test/search/TestTermVector.cpp new file mode 100644 index 00000000000..2de9a3ad616 --- /dev/null +++ b/src/test/search/TestTermVector.cpp @@ -0,0 +1,272 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +IndexSearcher* tv_searcher = NULL; +RAMDirectory* tv_directory = NULL; + +void testTermPositionVectors(CuTest *tc) { + CLUCENE_ASSERT(tv_searcher!=NULL); + + Term* term = _CLNEW Term(_T("field"), _T("fifty")); + TermQuery query(term); + _CLDECDELETE(term); + try { + Hits* hits = tv_searcher->search(&query); + CuAssert (tc,_T("hits.length != 100"), 100 == hits->length()); + + for (size_t i = 0; i < hits->length(); i++) + { + ArrayBase* vector = tv_searcher->getReader()->getTermFreqVectors(hits->id(i)); + CLUCENE_ASSERT(vector != NULL); + CLUCENE_ASSERT(vector->length== 1); + vector->deleteValues(); + _CLLDELETE(vector); + } + + _CLDELETE(hits); + } catch (CLuceneError& e) { + if ( e.number() == CL_ERR_IO ) + CuAssert(tc, _T("IO Error"),false); + + throw e; + } +} +void testTermVectors(CuTest *tc) { + CLUCENE_ASSERT(tv_searcher!=NULL); + + Term* term = _CLNEW Term(_T("field"), _T("seventy")); + TermQuery query(term); + _CLDECDELETE(term); + + try { + Hits* hits = tv_searcher->search(&query); + CuAssertIntEquals(tc,_T("hits!=100"), 100, hits->length()); + + for (size_t i = 0; i < hits->length(); i++) + { + ArrayBase* vector = tv_searcher->getReader()->getTermFreqVectors(hits->id(i)); + CLUCENE_ASSERT(vector != NULL); + CLUCENE_ASSERT(vector->length == 1); + vector->deleteValues(); + _CLLDELETE(vector); + } + + //test mem leaks with vectors + CL_NS(search)::Explanation expl; + tv_searcher->explain(&query, hits->id(50), &expl); + TCHAR* tmp = expl.toString(); + _CLDELETE_CARRAY(tmp); + + _CLDELETE(hits); + + } catch (CLuceneError& e) { + if ( e.number() == CL_ERR_IO ) + CuAssert(tc,_T("IO Exception"),false); + else + throw e; + } +} + +void testTVSetup(CuTest* /*tc*/) { + SimpleAnalyzer a; + tv_directory = _CLNEW RAMDirectory(); + IndexWriter writer(tv_directory, &a, true); + writer.setUseCompoundFile(false); + + TCHAR buf[200]; + for (int32_t i = 0; i < 1000; i++) { + Document doc; + English::IntToEnglish(i,buf,200); + + int mod3 = i % 3; + int mod2 = i % 2; + int termVector = 0; + if (mod2 == 0 && mod3 == 0) + termVector = Field::TERMVECTOR_WITH_POSITIONS_OFFSETS; + else if (mod2 == 0) + termVector = Field::TERMVECTOR_WITH_POSITIONS; + else if (mod3 == 0) + termVector = Field::TERMVECTOR_WITH_OFFSETS; + else + termVector = Field::TERMVECTOR_YES; + + doc.add(*new Field(_T("field"), buf, Field::STORE_YES | Field::INDEX_TOKENIZED | termVector )); + writer.addDocument(&doc); + } + writer.close(); + tv_searcher = _CLNEW IndexSearcher(tv_directory); +} +void testTVCleanup(CuTest* /*tc*/) { + _CLDELETE(tv_searcher); + tv_directory->close(); + _CLDELETE(tv_directory); +} + +void setupDoc(Document& doc, const TCHAR* text) +{ + doc.add(*new Field(_T("field"), text, Field::STORE_YES | + Field::INDEX_TOKENIZED | Field::TERMVECTOR_YES)); +} +struct __TCharCompare +{ + bool operator()(const TCHAR* s1, const TCHAR* s2) const + { + return _tcscmp(s1, s2) < 0; + } +}; + +void testKnownSetOfDocuments(CuTest *tc) { + const TCHAR* test1 = _T("eating chocolate in a computer lab"); //6 terms + const TCHAR* test2 = _T("computer in a computer lab"); //5 terms + const TCHAR* test3 = _T("a chocolate lab grows old"); //5 terms + const TCHAR* test4 = _T("eating chocolate with a chocolate lab in an old chocolate colored computer lab"); //13 terms + + typedef std::map test4MapType; + test4MapType test4Map; + test4Map.insert( std::pair(_T("chocolate"), 3) ); + test4Map.insert( std::pair(_T("lab"), 2) ); + test4Map.insert( std::pair(_T("eating"), 1) ); + test4Map.insert( std::pair(_T("computer"), 1) ); + test4Map.insert( std::pair(_T("with"), 1) ); + test4Map.insert( std::pair(_T("a"), 1) ); + test4Map.insert( std::pair(_T("colored"), 1) ); + test4Map.insert( std::pair(_T("in"), 1) ); + test4Map.insert( std::pair(_T("an"), 1) ); + test4Map.insert( std::pair(_T("computer"), 1) ); + test4Map.insert( std::pair(_T("old"), 1) ); + + Document testDoc1; + setupDoc(testDoc1, test1); + Document testDoc2; + setupDoc(testDoc2, test2); + Document testDoc3; + setupDoc(testDoc3, test3); + Document testDoc4; + setupDoc(testDoc4, test4); + + RAMDirectory dir; + + try { + SimpleAnalyzer a; + IndexWriter writer(&dir, &a, true); + + writer.addDocument(&testDoc1); + writer.addDocument(&testDoc2); + writer.addDocument(&testDoc3); + writer.addDocument(&testDoc4); + writer.close(); + + IndexSearcher knownSearcher(&dir); + TermEnum* termEnum = knownSearcher.getReader()->terms(); + TermDocs* termDocs = knownSearcher.getReader()->termDocs(); + + CL_NS(search)::Similarity* sim = knownSearcher.getSimilarity(); + while (termEnum->next() == true) + { + Term* term = termEnum->term(true); + //System.out.println("Term: " + term); + termDocs->seek(term); + + while (termDocs->next()) + { + int32_t docId = termDocs->doc(); + int32_t freq = termDocs->freq(); + //System.out.println("Doc Id: " + docId + " freq " + freq); + TermFreqVector* vector = knownSearcher.getReader()->getTermFreqVector(docId, _T("field")); + float_t tf = sim->tf(freq); + float_t idf = sim->idf(term, &knownSearcher); + //float_t qNorm = sim.queryNorm() + idf += tf; //remove warning + + const ArrayBase* terms = vector->getTerms(); + CLUCENE_ASSERT(vector != NULL); + int termsCount=terms != NULL ? terms->length : 0; + + //This is fine since we don't have stop words + float_t lNorm = sim->lengthNorm(_T("field"), termsCount); + lNorm ++;//remove warning + + //float_t coord = sim.coord() + //System.out.println("TF: " + tf + " IDF: " + idf + " LenNorm: " + lNorm); + const ArrayBase* vTerms = vector->getTerms(); + const ArrayBase* freqs = vector->getTermFrequencies(); + size_t i=0; + while ( vTerms && i < vTerms->length ) + { + if ( _tcscmp(term->text(), vTerms->values[i]) == 0 ) + { + CLUCENE_ASSERT((*freqs)[i] == freq); + } + i++; + } + + _CLDELETE(vector); + } + _CLDECDELETE(term); + //System.out.println("--------"); + } + _CLDELETE(termEnum); + _CLDELETE(termDocs); + + + Term* tqTerm = _CLNEW Term(_T("field"), _T("chocolate")); + TermQuery query(tqTerm); + _CLDECDELETE(tqTerm); + + Hits* hits = knownSearcher.search(&query); + //doc 3 should be the first hit b/c it is the shortest match + CLUCENE_ASSERT(hits->length() == 3); + float_t score = hits->score(0); + score++; + + CLUCENE_ASSERT(2==hits->id(0) ); + CLUCENE_ASSERT(3==hits->id(1) ); + CLUCENE_ASSERT(0==hits->id(2) ); + + TermFreqVector* vector = knownSearcher.getReader()->getTermFreqVector(hits->id(1), _T("field")); + CLUCENE_ASSERT(vector != NULL); + //_tprintf(_T("Vector: %s\n"),vector); + const ArrayBase* terms = vector->getTerms(); + const ArrayBase* freqs = vector->getTermFrequencies(); + CLUCENE_ASSERT(terms != NULL); + + int termsLength = terms->length; + CLUCENE_ASSERT(termsLength == 10); + + for (int32_t i = 0; i < termsLength; i++) { + const TCHAR* term = terms->values[i]; + //_tprintf(_T("Term: %s, test4map.size()=%d\n"),term, test4Map.size()); + int32_t freq = (*freqs)[i]; + CLUCENE_ASSERT( _tcsstr(test4,term) != NULL ); + test4MapType::const_iterator itr = test4Map.find(term); + CLUCENE_ASSERT( itr != test4Map.end() ); + int32_t freqInt = itr->second; + CLUCENE_ASSERT(freqInt == freq); + } + _CLDELETE(vector); + _CLDELETE(hits); + knownSearcher.close(); + + } catch (CLuceneError& e) { + CuAssert(tc, e.twhat(),false); + } +} + +CuSuite *testtermvector(void) +{ + tv_searcher = NULL; + CuSuite *suite = CuSuiteNew(_T("CLucene Term Vector Test")); + SUITE_ADD_TEST(suite, testTVSetup); + SUITE_ADD_TEST(suite, testKnownSetOfDocuments); + SUITE_ADD_TEST(suite, testTermVectors); + SUITE_ADD_TEST(suite, testTermPositionVectors); + SUITE_ADD_TEST(suite, testTVCleanup); + + return suite; +} +// EOF diff --git a/src/test/search/TestWildcard.cpp b/src/test/search/TestWildcard.cpp new file mode 100644 index 00000000000..b9f364d3881 --- /dev/null +++ b/src/test/search/TestWildcard.cpp @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +#ifndef NO_WILDCARD_QUERY + +void _testWildcard(CuTest* tc, IndexSearcher* searcher, const TCHAR* qt, int expectedLen){ + Term* term = _CLNEW Term(_T("body"), qt); + Query* query = _CLNEW WildcardQuery(term); + + //test the wildcardquery + Hits* result = searcher->search(query); + CLUCENE_ASSERT(expectedLen == result->length()); + _CLDELETE(result); + _CLDELETE(query); + + + //now test wildcardfilter + Filter* filter = _CLNEW WildcardFilter(term); + BitSet* bits = filter->bits(searcher->getReader()); + CLUCENE_ASSERT(expectedLen == bits->count()); + _CLDELETE(filter); + _CLDELETE(bits); + + _CLDECDELETE(term); +} + + + + + void testAsterisk(CuTest *tc){ + RAMDirectory indexStore; + SimpleAnalyzer an; + IndexWriter* writer = _CLNEW IndexWriter(&indexStore, &an, true); + Document doc1; + Document doc2; + doc1.add(*_CLNEW Field(_T("body"), _T("metal"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + doc2.add(*_CLNEW Field(_T("body"), _T("metals"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + + writer->addDocument(&doc1); + writer->addDocument(&doc2); + writer->close(); + _CLDELETE(writer); + ////////////////////////////////////////////////// + + IndexReader* reader = IndexReader::open(&indexStore); + IndexSearcher* searcher = _CLNEW IndexSearcher(reader); + + _testWildcard(tc, searcher, _T("metal*"), 2); + _testWildcard(tc, searcher, _T("m*tal"), 1); + _testWildcard(tc, searcher, _T("m*tal*"), 2); + + + Term* term = _CLNEW Term(_T("body"), _T("metal")); + Query* query1 = _CLNEW TermQuery(term); + _CLDECDELETE(term); + + Hits* result = searcher->search(query1); + CLUCENE_ASSERT(1 == result->length()); + _CLDELETE(result); + _CLDELETE(query1); + + + indexStore.close(); + searcher->close(); + reader->close(); + _CLDELETE(reader); + _CLDELETE(searcher); + } + + void testQuestionmark(CuTest *tc){ + RAMDirectory indexStore; + SimpleAnalyzer an; + IndexWriter* writer = _CLNEW IndexWriter(&indexStore, &an, true); + Document doc1; + Document doc2; + Document doc3; + Document doc4; + doc1.add(*_CLNEW Field(_T("body"), _T("metal"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + doc2.add(*_CLNEW Field(_T("body"), _T("metals"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + doc3.add(*_CLNEW Field(_T("body"), _T("mXtals"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + doc4.add(*_CLNEW Field(_T("body"), _T("mXtXls"),Field::STORE_YES | Field::INDEX_TOKENIZED)); + writer->addDocument(&doc1); + writer->addDocument(&doc2); + writer->addDocument(&doc3); + writer->addDocument(&doc4); + writer->close(); + _CLDELETE(writer); + ////////////////////////////////////////////////////// + + IndexReader* reader = IndexReader::open(&indexStore); + IndexSearcher* searcher = _CLNEW IndexSearcher(reader); + + + _testWildcard(tc, searcher, _T("m?tal"), 1); + _testWildcard(tc, searcher, _T("metal?"), 1); + _testWildcard(tc, searcher, _T("metal??"), 0); + _testWildcard(tc, searcher, _T("meta??"), 1); //metals + _testWildcard(tc, searcher, _T("metals?"), 0); + _testWildcard(tc, searcher, _T("m?t?ls"), 3); + + indexStore.close(); + reader->close(); + searcher->close(); + _CLDELETE(reader); + _CLDELETE(searcher); + } +#else + void _NO_WILDCARD_QUERY(CuTest *tc){ + CuNotImpl(tc,_T("Wildcard")); + } +#endif + + +CuSuite *testwildcard(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Wildcard Test")); + + #ifndef NO_WILDCARD_QUERY + SUITE_ADD_TEST(suite, testQuestionmark); + SUITE_ADD_TEST(suite, testAsterisk); + #else + SUITE_ADD_TEST(suite, _NO_WILDCARD_QUERY); + #endif + + return suite; +} +// EOF diff --git a/src/test/search/spans/TestBasics.cpp b/src/test/search/spans/TestBasics.cpp new file mode 100644 index 00000000000..3c5677d9f5d --- /dev/null +++ b/src/test/search/spans/TestBasics.cpp @@ -0,0 +1,588 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "../QueryUtils.h" +#include "../CheckHits.h" +#include "TestBasics.h" +#include "CLucene/search/spans/SpanQuery.h" +#include "CLucene/search/spans/SpanTermQuery.h" +#include "CLucene/search/spans/SpanNearQuery.h" +#include "CLucene/search/spans/SpanNotQuery.h" +#include "CLucene/search/spans/SpanOrQuery.h" +#include "CLucene/search/spans/SpanFirstQuery.h" + +CL_NS_USE2(search,spans); + +TestBasics::TestBasics( CuTest* tc ) +{ + this->tc = tc; + this->searcher = NULL; + this->directory = NULL; +} + +TestBasics::~TestBasics() +{ + if( searcher ) + { + searcher->close(); + _CLDELETE( searcher ); + } + + if( directory ) + { + directory->close(); + _CLDELETE( directory ); + } +} + +void TestBasics::setUp() +{ + directory = _CLNEW RAMDirectory(); + Analyzer * analyzer = _CLNEW SimpleAnalyzer(); + IndexWriter * writer = _CLNEW IndexWriter( directory, analyzer, true ); + TCHAR buffer[ 200 ]; + + for( int32_t i = 0; i < 1000; i++ ) + { + Document doc; + English::IntToEnglish( i, buffer, 200 ); + doc.add( * _CLNEW Field( _T( "field" ), buffer, Field::STORE_YES | Field::INDEX_TOKENIZED )); + writer->addDocument( &doc ); + } + + writer->close(); + _CLDELETE( writer ); + _CLDELETE( analyzer ); + + searcher = _CLNEW IndexSearcher( directory ); +} + +void TestBasics::testTerm() +{ + int32_t expectedDocs[] = + { + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 570, 571, 572, 573, 574, 575, 576, 577, + 578, 579, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 770, 771, + 772, 773, 774, 775, 776, 777, 778, 779, 870, 871, 872, 873, 874, 875, + 876, 877, 878, 879, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979 + }; + + Term * term = _CLNEW Term( _T( "field" ), _T( "seventy" )); + Query * query = new TermQuery( term ); + _CLLDECDELETE( term ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( query ); +} + +void TestBasics::testTerm2() +{ + Term * term = _CLNEW Term( _T( "field" ), _T( "seventish" )); + Query * query = new TermQuery( term ); + _CLLDECDELETE( term ); + + checkHits( query, NULL, 0 ); + _CLLDELETE( query ); +} + +void TestBasics::testPhrase() +{ + int32_t expectedDocs[] = { 77, 177, 277, 377, 477, 577, 677, 777, 877, 977 }; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "seventy" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "seven" )); + + PhraseQuery * query = _CLNEW PhraseQuery(); + query->add( term1 ); + query->add( term2 ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( query ); +} + +void TestBasics::testPhrase2() +{ + Term * term1 = _CLNEW Term( _T( "field" ), _T( "seventish" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "sevenon" )); + + PhraseQuery * query = _CLNEW PhraseQuery(); + query->add( term1 ); + query->add( term2 ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, NULL, 0 ); + _CLLDELETE( query ); +} + +void TestBasics::testBoolean() +{ + int32_t expectedDocs[] = {77, 777, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 778, 779, 877, 977}; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "seventy" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "seven" )); + + BooleanQuery * query = _CLNEW BooleanQuery(); + query->add( _CLNEW TermQuery( term1 ), true, BooleanClause::MUST ); + query->add( _CLNEW TermQuery( term2 ), true, BooleanClause::MUST ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( query ); +} + +void TestBasics::testBoolean2() +{ + Term * term1 = _CLNEW Term( _T( "field" ), _T( "sevento" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "sevenly" )); + + BooleanQuery * query = _CLNEW BooleanQuery(); + query->add( _CLNEW TermQuery( term1 ), true, BooleanClause::MUST ); + query->add( _CLNEW TermQuery( term2 ), true, BooleanClause::MUST ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, NULL, 0 ); + _CLLDELETE( query ); +} + +void TestBasics::testSpanNearExact() +{ + int32_t expectedDocs[] = {77, 177, 277, 377, 477, 577, 677, 777, 877, 977}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "seventy" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "seven" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 77, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 977, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + QueryUtils::check( tc, clauses[ 0 ] ); + QueryUtils::check( tc, clauses[ 1 ] ); + QueryUtils::checkUnequal( tc, clauses[ 0 ], clauses[ 1 ] ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDELETE( query ); +} + +void TestBasics::testSpanNearUnordered() +{ + int32_t expectedDocs[] = {609, 629, 639, 649, 659, 669, 679, 689, 699, 906, 926, 936, 946, 956, 966, 976, 986, 996}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "nine" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "six" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 4, false, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( query ); +} + +void TestBasics::testSpanNearOrdered() +{ + int32_t expectedDocs[] = {906, 926, 936, 946, 956, 966, 976, 986, 996}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "nine" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "six" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 4, true, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( query ); +} + +void TestBasics::testSpanNot() +{ + int32_t expectedDocs[] = {801, 821, 831, 851, 861, 871, 881, 891}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "eight" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "one" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "forty" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near = _CLNEW SpanNearQuery( clauses, clauses+2, 4, true, true ); + + SpanNotQuery * query = _CLNEW SpanNotQuery( near, _CLNEW SpanTermQuery( term3 ), true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( term3 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 801, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 891, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testSpanWithMultipleNotSingle() +{ + int32_t expectedDocs[] = {801, 821, 831, 851, 861, 871, 881, 891}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "eight" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "one" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "forty" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near = _CLNEW SpanNearQuery( clauses, clauses+2, 4, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term3 ); + SpanOrQuery * orQuery = _CLNEW SpanOrQuery( clauses, clauses+1, true ); + + SpanNotQuery * query = _CLNEW SpanNotQuery( near, orQuery, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( term3 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 801, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 891, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testSpanWithMultipleNotMany() +{ + int32_t expectedDocs[] = {801, 821, 831, 851, 871, 891}; + SpanQuery * clauses[ 3 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "eight" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "one" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "forty" )); + Term * term4 = _CLNEW Term( _T( "field" ), _T( "sixty" )); + Term * term5 = _CLNEW Term( _T( "field" ), _T( "eighty" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near = _CLNEW SpanNearQuery( clauses, clauses+2, 4, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term3 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term4 ); + clauses[ 2 ] = _CLNEW SpanTermQuery( term5 ); + SpanOrQuery * orQuery = _CLNEW SpanOrQuery( clauses, clauses+3, true ); + + SpanNotQuery * query = _CLNEW SpanNotQuery( near, orQuery, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( term3 ); + _CLLDECDELETE( term4 ); + _CLLDECDELETE( term5 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 801, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 891, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testNpeInSpanNearWithSpanNot() +{ + int32_t expectedDocs[] = {801, 821, 831, 851, 861, 871, 881, 891}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "eight" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "one" )); + Term * hun = _CLNEW Term( _T( "field" ), _T( "hundred" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "forty" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near = _CLNEW SpanNearQuery( clauses, clauses+2, 4, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( hun ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term3 ); + SpanNearQuery * exclude = _CLNEW SpanNearQuery( clauses, clauses+2, 1, true, true ); + + SpanNotQuery * query = _CLNEW SpanNotQuery( near, exclude, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( hun ); + _CLLDECDELETE( term3 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 801, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 891, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testNpeInSpanNearInSpanFirstInSpanNot() +{ + int32_t expectedDocs[] = {40,41,42,43,44,45,46,47,48,49}; + SpanQuery * clauses[ 2 ]; + int32_t n = 5; + + Term * hun = _CLNEW Term( _T( "field" ), _T( "hundred" )); + Term * term40 = _CLNEW Term( _T( "field" ), _T( "forty" )); + + SpanTermQuery * termQry40 = _CLNEW SpanTermQuery( term40 ); + clauses[ 0 ] = _CLNEW SpanTermQuery( hun ); + clauses[ 1 ] = (SpanTermQuery *) termQry40->clone(); + + SpanFirstQuery * include = _CLNEW SpanFirstQuery( termQry40, n, true ); + SpanNearQuery * near = _CLNEW SpanNearQuery( clauses, clauses+2, n-1, true, true ); + SpanFirstQuery * exclude = _CLNEW SpanFirstQuery( near, n-1, true ); + SpanNotQuery * q = _CLNEW SpanNotQuery( include, exclude, true ); + + _CLLDECDELETE( hun ); + _CLLDECDELETE( term40 ); + + checkHits( q, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + _CLLDELETE( q ); +} + +void TestBasics::testSpanFirst() +{ + int32_t expectedDocs[] = + { + 5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, + 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, + 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, + 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, + 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, + 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, + 598, 599 + }; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "five" )); + SpanFirstQuery * query = _CLNEW SpanFirstQuery( _CLNEW SpanTermQuery( term1 ), 1, true ); + _CLLDECDELETE( term1 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 5, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 599, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testSpanOr() +{ + int32_t expectedDocs[] = {33, 47, 133, 147, 233, 247, 333, 347, 433, 447, 533, 547, 633, 647, 733, 747, 833, 847, 933, 947}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "thirty" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "three" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "forty" )); + Term * term4 = _CLNEW Term( _T( "field" ), _T( "seven" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near1 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term3 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term4 ); + SpanNearQuery * near2 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = near1; + clauses[ 1 ] = near2; + SpanOrQuery * query = _CLNEW SpanOrQuery( clauses, clauses+2, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( term3 ); + _CLLDECDELETE( term4 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 33, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + Explanation explanation2; + searcher->explain( query, 947, &explanation2 ); + assertTrue( explanation2.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testSpanExactNested() +{ + int32_t expectedDocs[] = {333}; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "three" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "hundred" )); + Term * term3 = _CLNEW Term( _T( "field" ), _T( "thirty" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanNearQuery * near1 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term3 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term1 ); + SpanNearQuery * near2 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = near1; + clauses[ 1 ] = near2; + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + _CLLDECDELETE( term3 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + Explanation explanation1; + searcher->explain( query, 333, &explanation1 ); + assertTrue( explanation1.getDetail( 0 )->getValue() > 0.0f ); // ToDo: Fix IndexSearcher::explain() method + + _CLLDELETE( query ); +} + +void TestBasics::testSpanNearOr() +{ + int32_t expectedDocs[] = + { + 606, 607, 626, 627, 636, 637, 646, 647, + 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, + 706, 707, 726, 727, 736, 737, 746, 747, + 756, 757, 766, 767, 776, 777, 786, 787, 796, 797 + }; + SpanQuery * clauses[ 2 ]; + + Term * term1 = _CLNEW Term( _T( "field" ), _T( "six" )); + Term * term2 = _CLNEW Term( _T( "field" ), _T( "seven" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term2 ); + SpanOrQuery * to1 = _CLNEW SpanOrQuery( clauses, clauses+2, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( term2 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( term1 ); + SpanOrQuery * to2 = _CLNEW SpanOrQuery( clauses, clauses+2, true ); + + clauses[ 0 ] = to1; + clauses[ 1 ] = to2; + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 10, true, true ); + + _CLLDECDELETE( term1 ); + _CLLDECDELETE( term2 ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + _CLLDELETE( query ); +} + +void TestBasics::testSpanComplex1() +{ + int32_t expectedDocs[] = + { + 606, 607, 626, 627, 636, 637, 646, 647, + 656, 657, 666, 667, 676, 677, 686, 687, 696, 697, + 706, 707, 726, 727, 736, 737, 746, 747, + 756, 757, 766, 767, 776, 777, 786, 787, 796, 797 + }; + SpanQuery * clauses[ 2 ]; + + Term * termSix = _CLNEW Term( _T( "field" ), _T( "six" )); + Term * termHun = _CLNEW Term( _T( "field" ), _T( "hundred" )); + Term * termSev = _CLNEW Term( _T( "field" ), _T( "seven" )); + + clauses[ 0 ] = _CLNEW SpanTermQuery( termSix ); + clauses[ 1 ] = _CLNEW SpanTermQuery( termHun ); + SpanNearQuery * tt1 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( termSev ); + clauses[ 1 ] = _CLNEW SpanTermQuery( termHun ); + SpanNearQuery * tt2 = _CLNEW SpanNearQuery( clauses, clauses+2, 0, true, true ); + + clauses[ 0 ] = tt1; + clauses[ 1 ] = tt2; + SpanOrQuery * to1 = _CLNEW SpanOrQuery( clauses, clauses+2, true ); + + clauses[ 0 ] = _CLNEW SpanTermQuery( termSev ); + clauses[ 1 ] = _CLNEW SpanTermQuery( termSix ); + SpanOrQuery * to2 = _CLNEW SpanOrQuery( clauses, clauses+2, true ); + + clauses[ 0 ] = to1; + clauses[ 1 ] = to2; + SpanNearQuery * query = _CLNEW SpanNearQuery( clauses, clauses+2, 100, true, true ); + + _CLLDECDELETE( termSix ); + _CLLDECDELETE( termHun ); + _CLLDECDELETE( termSev ); + + checkHits( query, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + + _CLLDELETE( query ); +} + +void TestBasics::checkHits( Query * query, int32_t * results, size_t resultsCount ) +{ + CheckHits::checkHits( tc, query, _T( "field" ), searcher, results, resultsCount ); +} diff --git a/src/test/search/spans/TestBasics.h b/src/test/search/spans/TestBasics.h new file mode 100644 index 00000000000..b4b0340ab60 --- /dev/null +++ b/src/test/search/spans/TestBasics.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestBasics +#define _lucene_search_spans_TestBasics + +#include "test.h" + +/** + * Tests basic search capabilities. + * + *

Uses a collection of 1000 documents, each the english rendition of their + * document number. For example, the document numbered 333 has text "three + * hundred thirty three". + * + *

Tests are each a single query, and its hits are checked to ensure that + * all and only the correct documents are returned, thus providing end-to-end + * testing of the indexing and search code. + * + * @author Doug Cutting + */ +class TestBasics +{ +private: + CL_NS(search)::IndexSearcher * searcher; + CL_NS(store)::RAMDirectory * directory; + +public: + CuTest * tc; + +public: + TestBasics( CuTest* tc ); + virtual ~TestBasics(); + + void setUp(); + + void testTerm(); + void testTerm2(); + void testPhrase(); + void testPhrase2(); + void testBoolean(); + void testBoolean2(); + void testSpanNearExact(); + void testSpanNearUnordered(); + void testSpanNearOrdered(); + void testSpanNot(); + void testSpanWithMultipleNotSingle(); + void testSpanWithMultipleNotMany(); + void testNpeInSpanNearWithSpanNot(); + void testNpeInSpanNearInSpanFirstInSpanNot(); + void testSpanFirst(); + void testSpanOr(); + void testSpanExactNested(); + void testSpanNearOr(); + void testSpanComplex1(); + +private: + void checkHits( Query * query, int32_t * results, size_t resultsCount ); +}; +#endif + diff --git a/src/test/search/spans/TestNearSpansOrdered.cpp b/src/test/search/spans/TestNearSpansOrdered.cpp new file mode 100644 index 00000000000..ccc892e12db --- /dev/null +++ b/src/test/search/spans/TestNearSpansOrdered.cpp @@ -0,0 +1,221 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestNearSpansOrdered.h" +#include "../CheckHits.h" +#include "CLucene/search/spans/SpanQuery.h" +#include "CLucene/search/spans/SpanTermQuery.h" +#include "CLucene/search/spans/SpanNearQuery.h" +#include "CLucene/search/spans/Spans.h" +#include "CLucene/search/Scorer.h" + +CL_NS_USE2(search,spans); +CL_NS_USE(search); + +const TCHAR * TestNearSpansOrdered::field = _T( "field" ); +const TCHAR * TestNearSpansOrdered::docFields[] = +{ + _T( "w1 w2 w3 w4 w5" ), + _T( "w1 w3 w2 w3 zz" ), + _T( "w1 xx w2 yy w3" ), + _T( "w1 w3 xx w2 yy w3 zz" ) +}; + + +TestNearSpansOrdered::TestNearSpansOrdered( CuTest* tc ) +{ + this->tc = tc; + this->searcher = NULL; + this->directory = NULL; +} + +TestNearSpansOrdered::~TestNearSpansOrdered() +{ + if( searcher ) + { + searcher->close(); + _CLDELETE( searcher ); + } + + if( directory ) + { + directory->close(); + _CLDELETE( directory ); + } +} + +void TestNearSpansOrdered::setUp() +{ + directory = _CLNEW RAMDirectory(); + Analyzer * analyzer = _CLNEW WhitespaceAnalyzer(); + IndexWriter * writer= _CLNEW IndexWriter( directory, analyzer, true ); + + for( size_t i = 0; i < sizeof( docFields ) / sizeof( docFields[0] ); i++ ) + { + Document doc; + doc.add( * _CLNEW Field( field, docFields[ i ], Field::STORE_NO | Field::INDEX_TOKENIZED )); + writer->addDocument( &doc ); + } + + writer->close(); + _CLDELETE( writer ); + _CLDELETE( analyzer ); + + searcher = _CLNEW IndexSearcher( directory ); +} + +SpanNearQuery * TestNearSpansOrdered::makeQuery( const TCHAR * s1, const TCHAR * s2, const TCHAR * s3, int32_t slop, bool inOrder ) +{ + SpanTermQuery * clauses[ 3 ]; + Term * t1 = _CLNEW Term( field, s1 ); + Term * t2 = _CLNEW Term( field, s2 ); + Term * t3 = _CLNEW Term( field, s3 ); + clauses[ 0 ] = _CLNEW SpanTermQuery( t1 ); + clauses[ 1 ] = _CLNEW SpanTermQuery( t2 ); + clauses[ 2 ] = _CLNEW SpanTermQuery( t3 ); + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); + _CLLDECDELETE( t3 ); + return _CLNEW SpanNearQuery( clauses, clauses+3, slop, inOrder, true ); +} + +SpanNearQuery * TestNearSpansOrdered::makeQuery() +{ + return makeQuery( _T( "w1" ), _T( "w2" ), _T( "w3" ), 1, true ); +} + +bool TestNearSpansOrdered::checkSpans( CL_NS2(search,spans)::Spans * spans, int32_t doc, int32_t start, int32_t end ) +{ + return spans && spans->doc() == doc && spans->end() == end && spans->start() == start; +} + +void TestNearSpansOrdered::testSpanNearQuery() +{ + int32_t expectedDocs[] = {0,1}; + + SpanNearQuery * q = makeQuery(); + CheckHits::checkHits( tc, q, field, searcher, expectedDocs, sizeof( expectedDocs ) / sizeof( expectedDocs[ 0 ] )); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansNext() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->next()); + assertTrue( checkSpans( spans, 0, 0 ,3 )); + assertTrue( spans->next() ); + assertTrue( checkSpans( spans, 1, 0, 4 )); + assertTrue( ! spans->next() ); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +/** + * test does not imply that skipTo(doc+1) should work exactly the + * same as next -- it's only applicable in this case since we know doc + * does not contain more than one spans + */ +void TestNearSpansOrdered::testNearSpansSkipToLikeNext() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->skipTo(0) ); + assertTrue( checkSpans( spans, 0, 0, 3 )); + assertTrue( spans->skipTo(1) ); + assertTrue( checkSpans( spans, 1, 0, 4 )); + assertTrue( ! spans->skipTo(2) ); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansNextThenSkipTo() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->next() ); + assertTrue( checkSpans( spans, 0, 0, 3 )); + assertTrue( spans->skipTo( 1 )); + assertTrue( checkSpans( spans, 1, 0, 4 )); + assertTrue( ! spans->next() ); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansNextThenSkipPast() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->next() ); + assertTrue( checkSpans( spans, 0, 0, 3 )); + assertTrue( ! spans->skipTo( 2 )); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansSkipPast() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( ! spans->skipTo( 2 )); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansSkipTo0() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->skipTo( 0 )); + assertTrue( checkSpans( spans, 0, 0, 3 )); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +void TestNearSpansOrdered::testNearSpansSkipTo1() +{ + SpanNearQuery * q = makeQuery(); + Spans * spans = q->getSpans( searcher->getReader() ); + assertTrue( spans->skipTo(1) ); + assertTrue( checkSpans( spans, 1, 0, 4 )); + _CLLDELETE( spans ); + _CLLDELETE( q ); +} + +/** + * not a direct test of NearSpans, but a demonstration of how/when + * this causes problems + */ +void TestNearSpansOrdered::testSpanNearScorerSkipTo1() +{ + SpanNearQuery * q = makeQuery(); + Weight * w = q->_createWeight( searcher ); + Scorer * s = w->scorer( searcher->getReader() ); + assertTrue( s->skipTo( 1 )); + assertTrue( 1 == s->doc()); + _CLLDELETE( s ); + _CLLDELETE( w ); + _CLLDELETE( q ); +} + +/** + * not a direct test of NearSpans, but a demonstration of how/when + * this causes problems + */ +void TestNearSpansOrdered::testSpanNearScorerExplain() +{ + SpanNearQuery * q = makeQuery(); + Weight * w = q->_createWeight( searcher ); + Scorer * s = w->scorer( searcher->getReader() ); + Explanation * e = s->explain( 1 ); + + assertTrueMsg( _T( "Scorer explanation value for doc#1 isn't positive." ), 0.0f < e->getValue() ); + + _CLLDELETE( e ); + _CLLDELETE( s ); + _CLLDELETE( w ); + _CLLDELETE( q ); +} diff --git a/src/test/search/spans/TestNearSpansOrdered.h b/src/test/search/spans/TestNearSpansOrdered.h new file mode 100644 index 00000000000..890cfde01ce --- /dev/null +++ b/src/test/search/spans/TestNearSpansOrdered.h @@ -0,0 +1,50 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestNearSpansOrdered +#define _lucene_search_spans_TestNearSpansOrdered + +#include "test.h" + +CL_CLASS_DEF2(search,spans,SpanNearQuery); +CL_CLASS_DEF2(search,spans,Spans); + +class TestNearSpansOrdered +{ +private: + CL_NS(search)::IndexSearcher * searcher; + CL_NS(store)::RAMDirectory * directory; + static const TCHAR * docFields[]; + static const TCHAR * field; + +public: + CuTest * tc; + +public: + TestNearSpansOrdered( CuTest* tc ); + virtual ~TestNearSpansOrdered(); + + void setUp(); + + void testSpanNearQuery(); + void testNearSpansNext(); + void testNearSpansSkipToLikeNext(); + void testNearSpansNextThenSkipTo(); + void testNearSpansNextThenSkipPast(); + void testNearSpansSkipPast(); + void testNearSpansSkipTo0(); + void testNearSpansSkipTo1(); + void testSpanNearScorerSkipTo1(); + void testSpanNearScorerExplain(); + +private: + CL_NS2(search,spans)::SpanNearQuery * makeQuery( const TCHAR * s1, const TCHAR * s2, const TCHAR * s3, int32_t slop, bool inOrder ); + CL_NS2(search,spans)::SpanNearQuery * makeQuery(); + + bool checkSpans( CL_NS2(search,spans)::Spans * spans, int32_t doc, int32_t start, int32_t end ); +}; +#endif + diff --git a/src/test/search/spans/TestSpanExplanations.cpp b/src/test/search/spans/TestSpanExplanations.cpp new file mode 100644 index 00000000000..a30f041cf55 --- /dev/null +++ b/src/test/search/spans/TestSpanExplanations.cpp @@ -0,0 +1,269 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestSpanExplanations.h" +#include "CLucene/search/spans/SpanQuery.h" +#include "CLucene/search/spans/SpanOrQuery.h" +#include "CLucene/search/spans/SpanTermQuery.h" +#include "CLucene/search/spans/SpanNotQuery.h" +#include "CLucene/search/spans/SpanNearQuery.h" +#include "CLucene/search/spans/SpanFirstQuery.h" + +TestSpanExplanations::TestSpanExplanations( CuTest * tc ) +: TestExplanations( tc ) +{ +} + +TestSpanExplanations::~TestSpanExplanations() +{ +} + +void TestSpanExplanations::testST1() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = st( _T( "w1" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testST2() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = st( _T( "w1" )); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testST4() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = st( _T( "xx" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testST5() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = st( _T( "xx" )); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSF1() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = sf(( _T( "w1" )),1); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSF2() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = sf(( _T( "w1" )),1); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSF4() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = sf(( _T( "xx" )),2); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSF5() +{ + SpanQuery * q = sf(( _T( "yy" )),2); + qtest( q, NULL, 0 ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSF6() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = sf(( _T( "yy" )),4); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSO1() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = sor( _T( "w1" ), _T( "QQ" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSO2() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = sor( _T( "w1" ), _T( "w3" ), _T( "zz" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSO3() +{ + int32_t expDocs[] = {0,2,3}; + SpanQuery * q = sor( _T( "w5" ), _T( "QQ" ), _T( "yy" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSO4() +{ + int32_t expDocs[] = {0,2,3}; + SpanQuery * q = sor( _T( "w5" ), _T( "QQ" ), _T( "yy" )); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear1() +{ + SpanQuery * q = snear( _T( "w1" ), _T( "QQ" ),100,true); + qtest( q, NULL, 0 ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear2() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ),100,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear3() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ),0,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear4() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ),1,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear5() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = snear( _T( "xx" ), _T( "w1" ),0,false); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear6() +{ + SpanQuery * q = snear( _T( "w1" ), _T( "w2" ), _T( "QQ" ),100,true); + qtest( q, NULL, 0 ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear7() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ), _T( "w2" ),100,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear8() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ), _T( "w2" ),0,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear9() +{ + int32_t expDocs[] = {2,3}; + SpanQuery * q = snear( _T( "w1" ), _T( "xx" ), _T( "w2" ),1,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear10() +{ + int32_t expDocs[] = {2}; + SpanQuery * q = snear( _T( "xx" ), _T( "w1" ), _T( "w2" ),0,false); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNear11() +{ + int32_t expDocs[] = {0,1}; + SpanQuery * q = snear( _T( "w1" ), _T( "w2" ), _T( "w3" ),1,true); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot1() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = snot(sf( _T( "w1" ),10),st( _T( "QQ" ))); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot2() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = snot(sf( _T( "w1" ),10),st( _T( "QQ" ))); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot4() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = snot(sf( _T( "w1" ),10),st( _T( "xx" ))); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot5() +{ + int32_t expDocs[] = {0,1,2,3}; + SpanQuery * q = snot(sf( _T( "w1" ),10),st( _T( "xx" ))); + q->setBoost(1000); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot7() +{ + int32_t expDocs[] = {0,1,3}; + SpanQuery * f = snear( _T( "w1" ), _T( "w3" ),10,true); + f->setBoost(1000); + SpanQuery * q = snot(f, st( _T( "xx" ))); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} + +void TestSpanExplanations::testSNot10() +{ + int32_t expDocs[] = {0,1,3}; + SpanQuery * t = st( _T( "xx" )); + t->setBoost(10000); + SpanQuery * q = snot(snear( _T( "w1" ), _T( "w3" ),10,true), t); + qtest( q, expDocs, sizeof(expDocs)/sizeof(expDocs[0]) ); + _CLLDELETE( q ); +} diff --git a/src/test/search/spans/TestSpanExplanations.h b/src/test/search/spans/TestSpanExplanations.h new file mode 100644 index 00000000000..de13b365cdc --- /dev/null +++ b/src/test/search/spans/TestSpanExplanations.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestSpanExplanations +#define _lucene_search_spans_TestSpanExplanations + +#include "../TestExplanations.h" + +/** + * TestExplanations subclass focusing on span queries + */ +class TestSpanExplanations : public TestExplanations +{ +public: + TestSpanExplanations( CuTest * tc ); + virtual ~TestSpanExplanations(); + + void testST1(); + void testST2(); + void testST4(); + void testST5(); + + void testSF1(); + void testSF2(); + void testSF4(); + void testSF5(); + void testSF6(); + + void testSO1(); + void testSO2(); + void testSO3(); + void testSO4(); + + void testSNear1(); + void testSNear2(); + void testSNear3(); + void testSNear4(); + void testSNear5(); + void testSNear6(); + void testSNear7(); + void testSNear8(); + void testSNear9(); + void testSNear10(); + void testSNear11(); + + void testSNot1(); + void testSNot2(); + void testSNot4(); + void testSNot5(); + void testSNot7(); + void testSNot10(); +}; +#endif + diff --git a/src/test/search/spans/TestSpanExplanationsOfNonMatches.cpp b/src/test/search/spans/TestSpanExplanationsOfNonMatches.cpp new file mode 100644 index 00000000000..bdaf6b0a21b --- /dev/null +++ b/src/test/search/spans/TestSpanExplanationsOfNonMatches.cpp @@ -0,0 +1,22 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestSpanExplanationsOfNonMatches.h" +#include "../CheckHits.h" + +TestSpanExplanationsOfNonMatches::TestSpanExplanationsOfNonMatches( CuTest * tc ) +: TestSpanExplanations( tc ) +{ +} + +TestSpanExplanationsOfNonMatches::~TestSpanExplanationsOfNonMatches() +{ +} + +void TestSpanExplanationsOfNonMatches::qtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ) +{ + CheckHits::checkNoMatchExplanations( tc, q, field, searcher, expDocNrs, expDocNrsCount ); +} diff --git a/src/test/search/spans/TestSpanExplanationsOfNonMatches.h b/src/test/search/spans/TestSpanExplanationsOfNonMatches.h new file mode 100644 index 00000000000..c5078e4604b --- /dev/null +++ b/src/test/search/spans/TestSpanExplanationsOfNonMatches.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestSpanExplanationsOfNonMatches +#define _lucene_search_spans_TestSpanExplanationsOfNonMatches + +#include "TestSpanExplanations.h" + +/** + * subclass of TestSimpleExplanations that verifies non matches. + */ +class TestSpanExplanationsOfNonMatches : public TestSpanExplanations +{ +public: + TestSpanExplanationsOfNonMatches( CuTest * tc ); + virtual ~TestSpanExplanationsOfNonMatches(); + + /** + * Overrides superclass to ignore matches and focus on non-matches + * @see CheckHits#checkNoMatchExplanations + */ + virtual void qtest( Query * q, int32_t * expDocNrs, size_t expDocNrsCount ); +}; +#endif + diff --git a/src/test/search/spans/TestSpanQueries.cpp b/src/test/search/spans/TestSpanQueries.cpp new file mode 100644 index 00000000000..6000dd3ae28 --- /dev/null +++ b/src/test/search/spans/TestSpanQueries.cpp @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestBasics.h" +#include "TestSpans.h" +#include "TestNearSpansOrdered.h" +#include "TestSpansAdvanced2.h" +#include "TestSpanExplanationsOfNonMatches.h" + +///////////////////////////////////////////////////////////////////////////// +void testBasics( CuTest * tc ) +{ + TestBasics basicsTest( tc ); + basicsTest.setUp(); + basicsTest.testTerm(); + basicsTest.testTerm2(); + basicsTest.testPhrase(); + basicsTest.testPhrase2(); + basicsTest.testBoolean(); + basicsTest.testBoolean2(); + basicsTest.testSpanNearExact(); + basicsTest.testSpanNearUnordered(); + basicsTest.testSpanNearOrdered(); + basicsTest.testSpanNot(); + basicsTest.testSpanWithMultipleNotSingle(); + basicsTest.testSpanWithMultipleNotMany(); + basicsTest.testNpeInSpanNearWithSpanNot(); + basicsTest.testNpeInSpanNearInSpanFirstInSpanNot(); + basicsTest.testSpanFirst(); + basicsTest.testSpanOr(); + basicsTest.testSpanExactNested(); + basicsTest.testSpanNearOr(); + basicsTest.testSpanComplex1(); +} + +///////////////////////////////////////////////////////////////////////////// +void testSpans( CuTest * tc ) +{ + TestSpans spansTest( tc ); + spansTest.setUp(); + spansTest.testSpanNearOrdered(); + spansTest.testSpanNearOrderedEqual(); + spansTest.testSpanNearOrderedEqual1(); + spansTest.testSpanNearOrderedOverlap(); + + // CLucene specific: SpanOr query with no clauses are not allowed + // spansTest.testSpanOrEmpty(); + + spansTest.testSpanOrSingle(); + spansTest.testSpanOrDouble(); + spansTest.testSpanOrDoubleSkip(); + spansTest.testSpanOrUnused(); + spansTest.testSpanOrTripleSameDoc(); +} + +///////////////////////////////////////////////////////////////////////////// +void testNearSpansOrdered( CuTest * tc ) +{ + TestNearSpansOrdered test( tc ); + test.setUp(); + test.testSpanNearQuery(); + test.testNearSpansNext(); + test.testNearSpansSkipToLikeNext(); + test.testNearSpansNextThenSkipTo(); + test.testNearSpansNextThenSkipPast(); + test.testNearSpansSkipPast(); + test.testNearSpansSkipTo0(); + test.testNearSpansSkipTo1(); + test.testSpanNearScorerSkipTo1(); + test.testSpanNearScorerExplain(); +} + +///////////////////////////////////////////////////////////////////////////// +void testSpansAdvanced( CuTest * tc ) +{ + TestSpansAdvanced test( tc ); + test.setUp(); + test.testBooleanQueryWithSpanQueries(); +} + +///////////////////////////////////////////////////////////////////////////// +void testSpansAdvanced2( CuTest * tc ) +{ + TestSpansAdvanced2 test( tc ); + test.setUp(); + test.testVerifyIndex(); + test.testSingleSpanQuery(); + test.testMultipleDifferentSpanQueries(); + test.testBooleanQueryWithSpanQueries(); +} + +///////////////////////////////////////////////////////////////////////////// +void testSpanExplanations( CuTest * tc ) +{ + TestSpanExplanations test( tc ); + test.setUp(); + test.testST1(); + test.testST2(); + test.testST4(); + test.testST5(); + test.testSF1(); + test.testSF2(); + test.testSF4(); + test.testSF5(); + test.testSF6(); + test.testSO1(); + test.testSO2(); + test.testSO3(); + test.testSO4(); + test.testSNear1(); + test.testSNear2(); + test.testSNear3(); + test.testSNear4(); + test.testSNear5(); + test.testSNear6(); + test.testSNear7(); + test.testSNear8(); + test.testSNear9(); + test.testSNear10(); + test.testSNear11(); + test.testSNot1(); + test.testSNot2(); + test.testSNot4(); + test.testSNot5(); + test.testSNot7(); + test.testSNot10(); +} + +///////////////////////////////////////////////////////////////////////////// +void testSpanExplanationsOfNonMatches( CuTest * tc ) +{ + TestSpanExplanationsOfNonMatches test( tc ); + test.setUp(); + test.testST1(); + test.testST2(); + test.testST4(); + test.testST5(); + test.testSF1(); + test.testSF2(); + test.testSF4(); + test.testSF5(); + test.testSF6(); + test.testSO1(); + test.testSO2(); + test.testSO3(); + test.testSO4(); + test.testSNear1(); + test.testSNear2(); + test.testSNear3(); + test.testSNear4(); + test.testSNear5(); + test.testSNear6(); + test.testSNear7(); + test.testSNear8(); + test.testSNear9(); + test.testSNear10(); + test.testSNear11(); + test.testSNot1(); + test.testSNot2(); + test.testSNot4(); + test.testSNot5(); + test.testSNot7(); + test.testSNot10(); +} + + +///////////////////////////////////////////////////////////////////////////// +// Test suite for all tests of span queries +CuSuite *testSpanQueries(void) +{ + CuSuite *suite = CuSuiteNew( _T( "CLucene SpanQuery Tests" )); + + SUITE_ADD_TEST( suite, testBasics ); + SUITE_ADD_TEST( suite, testSpans ); + SUITE_ADD_TEST( suite, testNearSpansOrdered ); + SUITE_ADD_TEST( suite, testSpansAdvanced ); + SUITE_ADD_TEST( suite, testSpansAdvanced2 ); + SUITE_ADD_TEST( suite, testSpanExplanations ); + SUITE_ADD_TEST( suite, testSpanExplanationsOfNonMatches ); + + return suite; +} + diff --git a/src/test/search/spans/TestSpans.cpp b/src/test/search/spans/TestSpans.cpp new file mode 100644 index 00000000000..f9a0e0e89ac --- /dev/null +++ b/src/test/search/spans/TestSpans.cpp @@ -0,0 +1,300 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "../CheckHits.h" +#include "TestSpans.h" +#include "CLucene/search/spans/Spans.h" +#include "CLucene/search/spans/SpanNearQuery.h" +#include "CLucene/search/spans/SpanOrQuery.h" + +const TCHAR * TestSpans::field = _T( "field" ); +const TCHAR * TestSpans::docFields[] = +{ + _T( "w1 w2 w3 w4 w5" ), + _T( "w1 w3 w2 w3" ), + _T( "w1 xx w2 yy w3" ), + _T( "w1 w3 xx w2 yy w3" ), + _T( "u2 u2 u1" ), + _T( "u2 xx u2 u1" ), + _T( "u2 u2 xx u1" ), + _T( "u2 xx u2 yy u1" ), + _T( "u2 xx u1 u2" ), + _T( "u2 u1 xx u2" ), + _T( "u1 u2 xx u2" ), + _T( "t1 t2 t1 t3 t2 t3" ) +}; + +TestSpans::TestSpans( CuTest* tc ) +{ + this->tc = tc; + this->searcher = NULL; + this->directory = NULL; +} + +TestSpans::~TestSpans() +{ + if( searcher ) + { + searcher->close(); + _CLDELETE( searcher ); + } + + if( directory ) + { + directory->close(); + _CLDELETE( directory ); + } +} + +void TestSpans::setUp() +{ + directory = _CLNEW RAMDirectory(); + Analyzer * analyzer = _CLNEW WhitespaceAnalyzer(); + IndexWriter * writer = _CLNEW IndexWriter( directory, analyzer, true ); + + for( size_t i = 0; i < sizeof( docFields ) / sizeof( docFields[0] ); i++ ) + { + Document doc; + doc.add( * _CLNEW Field( field, docFields[ i ], Field::STORE_YES | Field::INDEX_TOKENIZED )); + writer->addDocument( &doc ); + } + + writer->close(); + _CLDELETE( writer ); + _CLDELETE( analyzer ); + + searcher = _CLNEW IndexSearcher( directory ); +} + +SpanTermQuery * TestSpans::makeSpanTermQuery( const TCHAR * text ) +{ + Term * term = _CLNEW Term( field, text ); + SpanTermQuery * query = _CLNEW SpanTermQuery( term ); + _CLDECDELETE( term ); + return query; +} + +void TestSpans::checkHits( Query * query, int32_t * results, size_t resultsCount ) +{ + CheckHits::checkHits( tc, query, field, searcher, results, resultsCount ); +} + +void TestSpans::orderedSlopTest3SQ( SpanQuery * q1, SpanQuery * q2, SpanQuery * q3, int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ) +{ + bool ordered = true; + SpanQuery ** clauses = _CL_NEWARRAY( SpanQuery *, 3 ); + clauses[ 0 ] = q1; + clauses[ 1 ] = q2; + clauses[ 2 ] = q3; + + SpanNearQuery * snq = _CLNEW SpanNearQuery( clauses, clauses+3, slop, ordered, true ); + checkHits( snq, expectedDocs, expectedDocsCount ); + + _CLLDELETE( snq ); + _CLDELETE_LARRAY( clauses ); +} + +void TestSpans::orderedSlopTest3( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ) +{ + orderedSlopTest3SQ( + makeSpanTermQuery( _T( "w1" )), + makeSpanTermQuery( _T( "w2" )), + makeSpanTermQuery( _T( "w3" )), + slop, + expectedDocs, + expectedDocsCount ); +} + +void TestSpans::orderedSlopTest3Equal( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ) +{ + orderedSlopTest3SQ( + makeSpanTermQuery( _T( "w1" )), + makeSpanTermQuery( _T( "w3" )), + makeSpanTermQuery( _T( "w3" )), + slop, + expectedDocs, + expectedDocsCount ); +} + +void TestSpans::orderedSlopTest1Equal( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ) +{ + orderedSlopTest3SQ( + makeSpanTermQuery( _T( "u2" )), + makeSpanTermQuery( _T( "u2" )), + makeSpanTermQuery( _T( "u1" )), + slop, + expectedDocs, + expectedDocsCount ); +} + +void TestSpans::testSpanNearOrdered() +{ + int32_t expectedDocs[] = { 0, 1, 2, 3 }; + + orderedSlopTest3( 0, expectedDocs, 1 ); + orderedSlopTest3( 1, expectedDocs, 2 ); + orderedSlopTest3( 2, expectedDocs, 3 ); + orderedSlopTest3( 3, expectedDocs, 4 ); + orderedSlopTest3( 4, expectedDocs, 4 ); +} + +void TestSpans::testSpanNearOrderedEqual() +{ + int32_t expectedDocs[] = { 1, 3 }; + + orderedSlopTest3Equal( 0, expectedDocs, 0 ); + orderedSlopTest3Equal( 1, expectedDocs, 1 ); + orderedSlopTest3Equal( 2, expectedDocs, 1 ); + orderedSlopTest3Equal( 3, expectedDocs, 2 ); +} + +void TestSpans::testSpanNearOrderedEqual1() +{ + int32_t expectedDocs[] = { 4, 5, 6, 7 }; + + orderedSlopTest1Equal( 0, expectedDocs, 1 ); + orderedSlopTest1Equal( 0, expectedDocs, 1 ); + orderedSlopTest1Equal( 1, expectedDocs, 3 ); + orderedSlopTest1Equal( 2, expectedDocs, 4 ); + orderedSlopTest1Equal( 3, expectedDocs, 4 ); +} + +void TestSpans::testSpanNearOrderedOverlap() +{ + bool ordered = true; + int32_t slop = 1; + + SpanQuery ** clauses = _CL_NEWARRAY( SpanQuery *, 3 ); + clauses[ 0 ] = makeSpanTermQuery( _T( "t1" )); + clauses[ 1 ] = makeSpanTermQuery( _T( "t2" )); + clauses[ 2 ] = makeSpanTermQuery( _T( "t3" )); + + SpanNearQuery * snq = _CLNEW SpanNearQuery( clauses, clauses+3, slop, ordered, true ); + Spans * spans = snq->getSpans( searcher->getReader() ); + + assertTrueMsg( _T( "first range" ), spans->next() ); + assertEqualsMsg( _T( "first doc" ), 11, spans->doc()); + assertEqualsMsg( _T( "first start" ), 0, spans->start()); + assertEqualsMsg( _T( "first end" ), 4, spans->end()); + + assertTrueMsg( _T( "second range" ), spans->next()); + assertEqualsMsg( _T( "second doc" ), 11, spans->doc()); + assertEqualsMsg( _T( "second start" ), 2, spans->start()); + assertEqualsMsg( _T( "second end" ), 6, spans->end()); + + assertTrueMsg( _T( "third range" ), ! spans->next()); + + _CLLDELETE( spans ); + _CLLDELETE( snq ); + _CLDELETE_LARRAY( clauses ); +} + +void TestSpans::orSpans( const TCHAR ** terms, size_t termsCount, Spans *& spans, Query *& query ) +{ + SpanQuery ** clauses = _CL_NEWARRAY( SpanQuery *, termsCount ); + + for( size_t i = 0; i < termsCount; i++ ) + clauses[ i ] = makeSpanTermQuery( terms[ i ]); + + SpanOrQuery * soq = _CLNEW SpanOrQuery( clauses, clauses + termsCount, true ); + _CLDELETE_LARRAY( clauses ); + + spans = soq->getSpans( searcher->getReader() ); + query = soq; +} + +void TestSpans::tstNextSpans( Spans * spans, int32_t doc, int32_t start, int32_t end ) +{ + assertTrueMsg( _T( "next" ), spans->next()); + assertEqualsMsg( _T( "doc" ), doc, spans->doc()); + assertEqualsMsg( _T( "start" ), start, spans->start()); + assertEqualsMsg( _T( "end" ), end, spans->end()); +} + +void TestSpans::testSpanOrEmpty() +{ + Spans * spans; + Query * query; + orSpans( NULL, 0, spans, query ); + assertTrueMsg( _T( "empty next" ), ! spans->next()); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} + +void TestSpans::testSpanOrSingle() +{ + Spans * spans; + Query * query; + const TCHAR* terms[] = { _T( "w5" ) }; + orSpans( terms, 1, spans, query ); + tstNextSpans( spans, 0, 4, 5 ); + assertTrueMsg( _T( "final next" ), ! spans->next()); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} + +void TestSpans::testSpanOrDouble() +{ + Spans * spans; + Query * query; + const TCHAR* terms[] = { _T( "w5" ), _T( "yy" ) }; + orSpans( terms, 2, spans, query ); + tstNextSpans( spans, 0, 4, 5 ); + tstNextSpans( spans, 2, 3, 4 ); + tstNextSpans( spans, 3, 4, 5 ); + tstNextSpans( spans, 7, 3, 4 ); + assertTrueMsg( _T( "final next" ), ! spans->next()); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} + +void TestSpans::testSpanOrDoubleSkip() +{ + Spans * spans; + Query * query; + const TCHAR* terms[] = { _T( "w5" ), _T( "yy" ) }; + orSpans( terms, 2, spans, query ); + assertTrueMsg( _T( "initial skipTo" ), spans->skipTo( 3 )); + assertEqualsMsg( _T( "doc" ), 3, spans->doc() ); + assertEqualsMsg( _T( "start" ), 4, spans->start() ); + assertEqualsMsg( _T( "end" ), 5, spans->end() ); + tstNextSpans( spans, 7, 3, 4 ); + assertTrueMsg( _T( "final next" ), ! spans->next() ); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} + +void TestSpans::testSpanOrUnused() +{ + Spans * spans; + Query * query; + const TCHAR* terms[] = { _T( "w5" ), _T( "unusedTerm" ), _T( "yy" ) }; + orSpans( terms, 3, spans, query ); + tstNextSpans( spans, 0, 4, 5 ); + tstNextSpans( spans, 2, 3, 4 ); + tstNextSpans( spans, 3, 4, 5 ); + tstNextSpans( spans, 7, 3, 4 ); + assertTrueMsg( _T( "final next" ), ! spans->next()); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} + +void TestSpans::testSpanOrTripleSameDoc() +{ + Spans * spans; + Query * query; + const TCHAR* terms[] = { _T( "t1" ), _T( "t2" ), _T( "t3" ) }; + orSpans( terms, 3, spans, query ); + tstNextSpans( spans, 11, 0, 1 ); + tstNextSpans( spans, 11, 1, 2 ); + tstNextSpans( spans, 11, 2, 3 ); + tstNextSpans( spans, 11, 3, 4 ); + tstNextSpans( spans, 11, 4, 5 ); + tstNextSpans( spans, 11, 5, 6 ); + assertTrueMsg( _T( "final next" ), ! spans->next()); + _CLLDELETE( spans ); + _CLLDELETE( query ); +} diff --git a/src/test/search/spans/TestSpans.h b/src/test/search/spans/TestSpans.h new file mode 100644 index 00000000000..8440ecdbef7 --- /dev/null +++ b/src/test/search/spans/TestSpans.h @@ -0,0 +1,60 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestSpans +#define _lucene_search_spans_TestSpans + +#include "test.h" + +#include "CLucene/search/spans/SpanTermQuery.h" +CL_NS_USE2(search,spans) + +class TestSpans +{ +private: + CL_NS(search)::IndexSearcher * searcher; + CL_NS(store)::RAMDirectory * directory; + + static const TCHAR * docFields[]; + +public: + static const TCHAR * field; + CuTest * tc; + + +public: + TestSpans( CuTest* tc ); + virtual ~TestSpans(); + + void setUp(); + SpanTermQuery * makeSpanTermQuery( const TCHAR* text ); + + void orderedSlopTest3( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ); + void orderedSlopTest3Equal( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ); + void orderedSlopTest1Equal( int32_t slop, int32_t * expectedDocs, size_t expectedDocsCount ); + + void testSpanNearOrdered(); + void testSpanNearOrderedEqual(); + void testSpanNearOrderedEqual1(); + + void testSpanNearOrderedOverlap(); + + void testSpanOrEmpty(); + void testSpanOrSingle(); + void testSpanOrDouble(); + void testSpanOrDoubleSkip(); + void testSpanOrUnused(); + void testSpanOrTripleSameDoc(); + +private: + void checkHits( Query * query, int32_t * results, size_t resultsCount ); + void orderedSlopTest3SQ( SpanQuery * q1, SpanQuery * q2, SpanQuery * q3, int32_t slop, int32_t * expectedDocs, size_t expectedDocCount ); + + void orSpans( const TCHAR ** terms, size_t termsCount, Spans *& spans, Query *& query ); + void tstNextSpans( Spans * spans, int32_t doc, int32_t start, int32_t end ); +}; +#endif + diff --git a/src/test/search/spans/TestSpansAdvanced.cpp b/src/test/search/spans/TestSpansAdvanced.cpp new file mode 100644 index 00000000000..eec0bea9180 --- /dev/null +++ b/src/test/search/spans/TestSpansAdvanced.cpp @@ -0,0 +1,136 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestSpansAdvanced.h" +#include "../QueryUtils.h" +#include "CLucene/search/spans/SpanTermQuery.h" + +CL_NS_USE2(search,spans); +CL_NS_USE(search); + +const TCHAR * TestSpansAdvanced::field_id = _T( "ID" ); +const TCHAR * TestSpansAdvanced::field_text = _T( "TEXT" ); + +TestSpansAdvanced::TestSpansAdvanced( CuTest* tc ) +{ + this->tc = tc; + this->searcher = NULL; + this->directory = NULL; +} + +TestSpansAdvanced::~TestSpansAdvanced() +{ + if( searcher ) + { + searcher->close(); + _CLDELETE( searcher ); + } + + if( directory ) + { + directory->close(); + _CLDELETE( directory ); + } +} + +void TestSpansAdvanced::setUp() +{ + directory = _CLNEW RAMDirectory(); + Analyzer * analyzer = _CLNEW StandardAnalyzer(); + IndexWriter * writer = _CLNEW IndexWriter( directory, analyzer, true ); + + addDocuments( writer ); + + writer->close(); + _CLDELETE( writer ); + _CLDELETE( analyzer ); + + searcher = _CLNEW IndexSearcher( directory ); +} + +void TestSpansAdvanced::addDocuments( IndexWriter * writer ) +{ + addDocument( writer, _T( "1" ), _T( "I think it should work." )); + addDocument( writer, _T( "2" ), _T( "I think it should work." )); + addDocument( writer, _T( "3" ), _T( "I think it should work." )); + addDocument( writer, _T( "4" ), _T( "I think it should work." )); +} + + +void TestSpansAdvanced::addDocument( IndexWriter * writer, const TCHAR * id, const TCHAR * text ) +{ + Document document; + document.add( * _CLNEW Field( field_id, id, Field::STORE_YES | Field::INDEX_UNTOKENIZED )); + document.add( * _CLNEW Field( field_text, text, Field::STORE_YES | Field::INDEX_TOKENIZED )); + writer->addDocument( &document ); +} + +void TestSpansAdvanced::testBooleanQueryWithSpanQueries() +{ + doTestBooleanQueryWithSpanQueries( 0.3884282f ); +} + +void TestSpansAdvanced::doTestBooleanQueryWithSpanQueries( const float_t expectedScore ) +{ + Term * t1 = _CLNEW Term( field_text, _T( "work" )); + Query * spanQuery = _CLNEW SpanTermQuery( t1 ); + BooleanQuery * query = _CLNEW BooleanQuery(); + + query->add( spanQuery, false, BooleanClause::MUST ); + query->add( spanQuery, false, BooleanClause::MUST ); + + const TCHAR * expectedIds[] = { _T( "1" ), _T( "2" ), _T( "3" ), _T( "4" ) }; + float_t expectedScores[] = { expectedScore, expectedScore, expectedScore, expectedScore }; + + assertHits( query, _T( "two span queries" ), expectedIds, expectedScores, 4 ); + + _CLLDECDELETE( t1 ); + _CLLDELETE( spanQuery ); + _CLLDELETE( query ); +} + +void TestSpansAdvanced::assertHits( Query * query, const TCHAR * description, const TCHAR ** expectedIds, float_t * expectedScores, size_t expectedCount ) +{ + float_t tolerance = 1e-5f; + + QueryUtils::check( tc, query, searcher ); + + // Hits hits = searcher.search(query); + // hits normalizes and throws things off if one score is greater than 1.0 + TopDocs * topdocs = searcher->_search( query, NULL, 10000 ); + + /***** + // display the hits + System.out.println(hits.length() + " hits for search: \"" + description + '\"'); + for (int i = 0; i < hits.length(); i++) { + System.out.println(" " + FIELD_ID + ':' + hits.doc(i).get(FIELD_ID) + " (score:" + hits.score(i) + ')'); + } + *****/ + + // did we get the hits we expected + assertEquals( expectedCount, topdocs->totalHits ); + for( size_t i = 0; i < expectedCount; i++ ) + { + //System.out.println(i + " exp: " + expectedIds[i]); + //System.out.println(i + " field: " + hits.doc(i).get(FIELD_ID)); + + int32_t id = topdocs->scoreDocs[ i ].doc; + float_t score = topdocs->scoreDocs[ i ].score; + Document doc; + searcher->doc( id, doc ); + assertTrueMsg( _T( "actual document does not match the expected one" ), 0 == _tcscmp( expectedIds[ i ], doc.get( field_id ))); + assertTrueMsg( _T( "score does not match" ), ( expectedScores[ i ] > score ? expectedScores[ i ] - score : score - expectedScores[ i ] ) < tolerance ); + + Explanation exp; + searcher->explain( query, id, &exp ); + + float_t sd = exp.getDetail( 0 )->getValue() - score; + if ( sd < 0 ) sd *= -1; + assertTrueMsg( _T( "explained score does not match" ), sd < tolerance ); + } + + _CLLDELETE( topdocs ); +} diff --git a/src/test/search/spans/TestSpansAdvanced.h b/src/test/search/spans/TestSpansAdvanced.h new file mode 100644 index 00000000000..7cd397d6e9e --- /dev/null +++ b/src/test/search/spans/TestSpansAdvanced.h @@ -0,0 +1,59 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestSpansAdvanced +#define _lucene_search_spans_TestSpansAdvanced + +#include "test.h" + +/******************************************************************************* + * Tests the span query bug in Lucene. It demonstrates that SpanTermQuerys don't + * work correctly in a BooleanQuery. + * + * @author Reece Wilton + */ +class TestSpansAdvanced +{ +protected: + CL_NS(search)::IndexSearcher * searcher; + CL_NS(store)::RAMDirectory * directory; + + static const TCHAR * field_id; + static const TCHAR * field_text; + +public: + CuTest * tc; + +public: + TestSpansAdvanced( CuTest* tc ); + virtual ~TestSpansAdvanced(); + + void setUp(); + void testBooleanQueryWithSpanQueries(); + +protected: + virtual void addDocuments( IndexWriter * writer ); + void addDocument( IndexWriter * writer, const TCHAR * id, const TCHAR * text ); + + /** + * Tests two span queries. + */ + void doTestBooleanQueryWithSpanQueries( const float_t expectedScore ); + + /** + * Checks to see if the hits are what we expected. + * + * @param query the query to execute + * @param description the description of the search + * @param expectedIds the expected document ids of the hits + * @param expectedScores the expected scores of the hits + * + * @throws IOException + */ + void assertHits( Query * query, const TCHAR * description, const TCHAR ** expectedIds, float_t * expectedScores, size_t expectedCount ); +}; +#endif + diff --git a/src/test/search/spans/TestSpansAdvanced2.cpp b/src/test/search/spans/TestSpansAdvanced2.cpp new file mode 100644 index 00000000000..f049dc634c8 --- /dev/null +++ b/src/test/search/spans/TestSpansAdvanced2.cpp @@ -0,0 +1,85 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "TestSpansAdvanced2.h" +#include "CLucene/search/spans/SpanTermQuery.h" + +CL_NS_USE2(search, spans); +CL_NS_USE(search); + +TestSpansAdvanced2::TestSpansAdvanced2( CuTest* tc ) : TestSpansAdvanced( tc ) +{ +} + +TestSpansAdvanced2::~TestSpansAdvanced2() +{ +} + +void TestSpansAdvanced2::addDocuments( IndexWriter * writer ) +{ + TestSpansAdvanced::addDocuments( writer ); + addDocument( writer, _T( "A" ), _T( "Should we, could we, would we?" )); + addDocument( writer, _T( "B" ), _T( "It should. Should it?" )); + addDocument( writer, _T( "C" ), _T( "It shouldn't." )); + addDocument( writer, _T( "D" ), _T( "Should we, should we, should we." )); +} + +/** + * Verifies that the index has the correct number of documents. + */ +void TestSpansAdvanced2::testVerifyIndex() +{ + IndexReader * reader = IndexReader::open( directory ); + assertEquals( 8, reader->numDocs() ); + reader->close(); + _CLDELETE( reader ); +} + +/** + * Tests a single span query that matches multiple documents. + */ +void TestSpansAdvanced2::testSingleSpanQuery() +{ + Term * t1 = _CLNEW Term( field_text, _T( "should" )); + Query * spanQuery = _CLNEW SpanTermQuery( t1 ); + const TCHAR * expectedIds[] = { _T( "B" ), _T( "D" ), _T( "1" ), _T( "2" ), _T( "3" ), _T( "4" ), _T( "A" ) }; + float_t expectedScores[] = { 0.625f, 0.45927936f, 0.35355338f, 0.35355338f, 0.35355338f, 0.35355338f, 0.26516503f, }; + assertHits( spanQuery, _T( "single span query" ), expectedIds, expectedScores, 7 ); + _CLLDELETE( spanQuery ); + _CLLDECDELETE( t1 ); +} + +/** + * Tests a single span query that matches multiple documents. + */ +void TestSpansAdvanced2::testMultipleDifferentSpanQueries() +{ + Term * t1 = _CLNEW Term( field_text, _T( "should" )); + Term * t2 = _CLNEW Term( field_text, _T( "we" )); + Query * spanQuery1 = _CLNEW SpanTermQuery( t1 ); + Query * spanQuery2 = _CLNEW SpanTermQuery( t2 ); + BooleanQuery * query = _CLNEW BooleanQuery(); + query->add( spanQuery1, true, BooleanClause::MUST ); + query->add( spanQuery2, true, BooleanClause::MUST ); + + const TCHAR * expectedIds[] = { _T( "D" ), _T( "A" ) }; + // these values were pre LUCENE-413 + // final float[] expectedScores = new float[] { 0.93163157f, 0.20698164f }; + float_t expectedScores[] = { 1.0191123f, 0.93163157f }; + assertHits( query, _T( "multiple different span queries" ), expectedIds, expectedScores, 2 ); + + _CLDELETE( query ); + _CLLDECDELETE( t1 ); + _CLLDECDELETE( t2 ); +} + +/** + * Tests two span queries. + */ +void TestSpansAdvanced2::testBooleanQueryWithSpanQueries() +{ + doTestBooleanQueryWithSpanQueries( 0.73500174f ); +} diff --git a/src/test/search/spans/TestSpansAdvanced2.h b/src/test/search/spans/TestSpansAdvanced2.h new file mode 100644 index 00000000000..1aaafca96f1 --- /dev/null +++ b/src/test/search/spans/TestSpansAdvanced2.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef _lucene_search_spans_TestSpansAdvanced2 +#define _lucene_search_spans_TestSpansAdvanced2 + +#include "TestSpansAdvanced.h" + +/******************************************************************************* + * Some expanded tests to make sure my patch doesn't break other SpanTermQuery + * functionality. + * + * @author Reece Wilton + */ +class TestSpansAdvanced2 : public TestSpansAdvanced +{ +public: + TestSpansAdvanced2( CuTest* tc ); + virtual ~TestSpansAdvanced2(); + + void testVerifyIndex(); + void testSingleSpanQuery(); + void testMultipleDifferentSpanQueries(); + void testBooleanQueryWithSpanQueries(); + +protected: + virtual void addDocuments( IndexWriter * writer ); +}; +#endif + diff --git a/src/test/store/MockRAMDirectory.cpp b/src/test/store/MockRAMDirectory.cpp new file mode 100644 index 00000000000..2138e521ef7 --- /dev/null +++ b/src/test/store/MockRAMDirectory.cpp @@ -0,0 +1,326 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "MockRAMDirectory.h" + +#include +#include +#include "CLucene/_ApiHeader.h" + +CL_NS_DEF(store) + +MockRAMDirectory::MockRAMDirectory() : + RAMDirectory(), + noDeleteOpenFile(true), maxSize(0) { + // empty +} + +MockRAMDirectory::MockRAMDirectory(const char* dir) : + RAMDirectory(dir), + noDeleteOpenFile(true), maxSize(0) { + // empty +} + +MockRAMDirectory::MockRAMDirectory(Directory* dir) : + RAMDirectory(dir), + noDeleteOpenFile(true), maxSize(0) { + // empty +} + +MockRAMDirectory::~MockRAMDirectory() { + while (!failures.empty()) { + delete failures.back(); + failures.pop_back(); + } +} + +IndexOutput* MockRAMDirectory::createOutput(const char* name) { + MockRAMFile* file = new MockRAMFile(this); + + { + SCOPED_LOCK_MUTEX(openFiles_mutex); + + if (noDeleteOpenFile && openFiles.find(name) != openFiles.end()) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: file %s is still open: cannot overwrite", name); + _CLTHROWA(CL_ERR_IO, buffer); + } + } + + SCOPED_LOCK_MUTEX(files_mutex); + + MockRAMFile* existing = static_cast(files->get((char*)name)); + + if (existing != NULL && strcmp(name, "segments.gen") != 0) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: file %s already exist", name); + _CLTHROWA(CL_ERR_IO, buffer); + } else { + if (existing != NULL) { + SCOPED_LOCK_MUTEX(THIS_LOCK); + sizeInBytes -= existing->getSizeInBytes(); + existing->setDirectory(NULL); + } + + files->put(STRDUP_AtoA(name), file); + } + + return _CLNEW MockRAMOutputStream(this, file); +} + +bool MockRAMDirectory::openInput(const char* name, IndexInput*& ret, CLuceneError& error, int32_t buffferSize) { + SCOPED_LOCK_MUTEX(files_mutex); + MockRAMFile* file = static_cast(files->get((char*)name)); + + if (file == NULL) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: file %s not found", name); + error.set(CL_ERR_IO, buffer); + return false; + } else { + SCOPED_LOCK_MUTEX(openFiles_mutex); + + if (openFiles.find(name) != openFiles.end()) { + ++openFiles[name]; + } else { + openFiles.insert(std::make_pair(name, 1)); + } + } + + ret = _CLNEW MockRAMInputStream(this, name, file); + return true; +} + +void MockRAMDirectory::close() { + SCOPED_LOCK_MUTEX(openFiles_mutex); + if (noDeleteOpenFile && !openFiles.empty()) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: cannot close: there are still open files: %d", (int)openFiles.size()); + _CLTHROWA(CL_ERR_IO, buffer); + } +} + +bool MockRAMDirectory::deleteFile(const char* name, const bool throwError) { + SCOPED_LOCK_MUTEX(openFiles_mutex); + if (noDeleteOpenFile && openFiles.find(name) != openFiles.end() && throwError) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: file %s is still open: cannot delete", name); + _CLTHROWA(CL_ERR_IO, buffer); + } + + return RAMDirectory::deleteFile(name, throwError); +} + +void MockRAMDirectory::setNoDeleteOpenFile(bool value) { + noDeleteOpenFile = value; +} + +void MockRAMDirectory::setMaxUsedSize(int64_t value) { + maxUsedSize = value; +} + +int64_t MockRAMDirectory::getMaxUsedSize(void) const { + return maxUsedSize; +} + +void MockRAMDirectory::resetMaxUsedSize(void) { + maxUsedSize = getRecomputedActualSizeInBytes(); +} + +void MockRAMDirectory::setMaxSizeInBytes(int64_t value) { + maxSize = value; +} + +int64_t MockRAMDirectory::getMaxSizeInBytes() const { + return maxSize; +} + +void MockRAMDirectory::setRandomIOExceptionRate(float_t rate, int32_t seed) { + srand(seed); + randomIOExceptionRate = rate; +} + +float_t MockRAMDirectory::getRandomIOExceptionRate(void) const { + return randomIOExceptionRate; +} + +bool MockRAMDirectory::getNoDeleteOpenFile() const { + return noDeleteOpenFile; +} + +std::map& MockRAMDirectory::getOpenFiles() { + return openFiles; +} + +void MockRAMDirectory::maybeThrowIOException(void) { + if (randomIOExceptionRate > 0.0) { + // don't use low bits from rand() + // (see http://en.wikipedia.org/wiki/Linear_congruential_generator#Advantages_and_disadvantages_of_LCGs) + int32_t number = ((rand() >> 4) % 1000); + if (number < randomIOExceptionRate * 1000) { + char buffer[200]; + _snprintf(buffer, 200, "MockRAMDirectory: a random IOException"); + _CLTHROWA(CL_ERR_IO, buffer); + } + } +} + +int64_t MockRAMDirectory::getRecomputedSizeInBytes(void) { + SCOPED_LOCK_MUTEX(files_mutex); + int64_t size = 0; + RAMDirectory::FileMap::iterator it = files->begin(); + + while (it != files->end()) { + size += (*it).second->getSizeInBytes(); + it++; + } + + return size; +} + +int64_t MockRAMDirectory::getRecomputedActualSizeInBytes(void) { + SCOPED_LOCK_MUTEX(files_mutex); + int64_t size = 0; + RAMDirectory::FileMap::iterator it = files->begin(); + + while (it != files->end()) { + size += (*it).second->getLength(); + it++; + } + + return size; +} + +void MockRAMDirectory::failOn(Failure* fail) { + failures.push_back(fail); +} + +void MockRAMDirectory::maybeThrowDeterministicException(void) { + std::vector::iterator it = failures.begin(); + + while (it != failures.end()) { + (*it)->eval(this); + it++; + } +} + +// +// MockRAMOutputStream +// + +MockRAMOutputStream::MockRAMOutputStream() : + RAMOutputStream(), + dir(NULL), + first(true) { + // empty +} + +MockRAMOutputStream::MockRAMOutputStream(MockRAMDirectory* d, MockRAMFile* f) : + RAMOutputStream(f), + dir(d), + first(true) { + // empty +} + +void MockRAMOutputStream::close() { + RAMOutputStream::close(); + + int64_t size = dir->getRecomputedActualSizeInBytes(); + + if (size > dir->getMaxUsedSize()) { + dir->setMaxUsedSize(size); + } +} + +void MockRAMOutputStream::flush() { + dir->maybeThrowDeterministicException(); + RAMOutputStream::flush(); +} + +void MockRAMOutputStream::writeByte(const uint8_t b) { + singleByte[0] = b; + writeBytes(singleByte, 1); +} + +void MockRAMOutputStream::writeBytes(const uint8_t* b, const int32_t length) { + int64_t freeSpace = dir->getMaxSizeInBytes() - dir->sizeInBytes; + int64_t realUsage = 0; + + // Enforce disk full + if (dir->getMaxSizeInBytes() != 0 && freeSpace < length) { + // Compute the real disk free. This will greatly slow + // down our test but makes it more accurate: + realUsage = dir->getRecomputedActualSizeInBytes(); + freeSpace = dir->getMaxSizeInBytes() - realUsage; + } + + if (dir->getMaxSizeInBytes() != 0 && freeSpace <= length) { + if (freeSpace > 0 && freeSpace < length) { + realUsage += freeSpace; + RAMOutputStream::writeBytes(b, freeSpace); + } + + if (realUsage > dir->getMaxUsedSize()) { + dir->setMaxUsedSize(realUsage); + } + + char buffer[200]; + _snprintf(buffer, 200, "MockRAMOutputStream: fake disk full at %d bytes", (int)dir->getRecomputedActualSizeInBytes()); + _CLTHROWA(CL_ERR_IO, buffer); + } else { + RAMOutputStream::writeBytes(b, length); + } + + dir->maybeThrowDeterministicException(); + + if (first) { + // Maybe throw random exception; only do this on first + // write to a new file: + first = false; + dir->maybeThrowIOException(); + } +} + +int64_t MockRAMOutputStream::length() const { + return RAMOutputStream::length(); +} + +// +// MockRAMInputStream +// + +MockRAMInputStream::MockRAMInputStream(const MockRAMInputStream& clone) : + RAMInputStream(clone), + isClone(true) { + dir = clone.dir; + name = clone.name; +} + +MockRAMInputStream::MockRAMInputStream(MockRAMDirectory* d, const char* n, MockRAMFile* f) : + RAMInputStream(f), + dir(d), + name(n), + isClone(false) { + // empty +} + +void MockRAMInputStream::close() { + RAMInputStream::close(); + + if (!isClone) { + SCOPED_LOCK_MUTEX(openFiles_mutex); + int v = dir->getOpenFiles()[name.c_str()]; + + if (v == 1) { + dir->getOpenFiles().erase(name.c_str()); + } else { + --dir->getOpenFiles()[name.c_str()]; + } + } +} + +CL_NS_END diff --git a/src/test/store/MockRAMDirectory.h b/src/test/store/MockRAMDirectory.h new file mode 100644 index 00000000000..912569d04d2 --- /dev/null +++ b/src/test/store/MockRAMDirectory.h @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#ifndef _lucene_store_MockRAMDirectory_ +#define _lucene_store_MockRAMDirectory_ + +#include "CLucene.h" +#include "CLucene/_clucene-config.h" +#include +#include +#include + +#include "CLucene/store/RAMDirectory.h" +#include "CLucene/store/_RAMDirectory.h" + +CL_NS_DEF(store) + +/** + * This is a subclass of RAMDirectory that adds methods + * intented to be used only by unit tests. + */ +class MockRAMDirectory : public RAMDirectory { +public: + + /** + * Objects that represent fail-able conditions. Objects of a derived + * class are created and registered with the mock directory. After + * register, each object will be invoked once for each first write + * of a file, giving the object a chance to throw an IOException. + */ + class Failure { + public: + Failure() { doFail = false; } + + void eval(MockRAMDirectory* dir) {} + /** + * reset should set the state of the failure to its default + * (freshly constructed) state. Reset is convenient for tests + * that want to create one failure object and then reuse it in + * multiple cases. This, combined with the fact that Failure + * subclasses are often anonymous classes makes reset difficult to + * do otherwise. + * + * A typical example of use is + * Failure* failure = new Failure(); + * ... + * mock.failOn(failure->reset()) + */ + Failure* reset() { return this; } + void setDoFail() { doFail = true; }; + void clearDoFail() { doFail = false; } + + private: + bool doFail; + }; + + MockRAMDirectory(); + MockRAMDirectory(const char* dir); + MockRAMDirectory(Directory* dir); + virtual ~MockRAMDirectory(); + virtual IndexOutput* createOutput(const char* name); + virtual bool openInput(const char* name, IndexInput*& ret, CLuceneError& error, int32_t bufferSize = -1); + virtual void close(); + virtual bool deleteFile(const char* name, const bool throwError=true); + + /** + * Emulate windows whereby deleting an open file is not + * allowed (raise IOException). + */ + void setNoDeleteOpenFile(bool value); + bool getNoDeleteOpenFile() const; + + void setMaxUsedSize(int64_t value); + int64_t getMaxUsedSize() const; + void resetMaxUsedSize(); + + void setMaxSizeInBytes(int64_t value); + int64_t getMaxSizeInBytes() const; + + /** + * If 0.0, no exceptions will be thrown. Else this should + * be a double 0.0 - 1.0. We will randomly throw an + * IOException on the first write to an OutputStream based + * on this probability. + */ + void setRandomIOExceptionRate(float_t rate, int32_t seed); + float_t getRandomIOExceptionRate() const; + + void maybeThrowIOException(); + + /** Provided for testing purposes. Use sizeInBytes() instead. */ + int64_t getRecomputedSizeInBytes(); + /** + * Like getRecomputedSizeInBytes(), but, uses actual file + * lengths rather than buffer allocations (which are + * quantized up to nearest + * RAMOutputStream.BUFFER_SIZE (now 1024) bytes. + */ + int64_t getRecomputedActualSizeInBytes(); + + void failOn(Failure* fail); + void maybeThrowDeterministicException(); + + std::map& getOpenFiles(); + + DEFINE_MUTABLE_MUTEX(openFiles_mutex); + +private: + std::map openFiles; + std::vector failures; + bool noDeleteOpenFile; + int64_t maxUsedSize; + int64_t maxSize; + float_t randomIOExceptionRate; +}; + +/** + * Subclass of RAMFile to access RAMFile::directory without making it public in RAMFile. + */ +class MockRAMFile : public RAMFile { + +public: + + MockRAMFile(RAMDirectory* directory) : RAMFile(directory) { + // empty + } + + virtual ~MockRAMFile() { + // empty + } + + void setDirectory(RAMDirectory* value) { + directory = value; + } +}; + +class MockRAMOutputStream : public RAMOutputStream { + +public: + MockRAMOutputStream(); + MockRAMOutputStream(MockRAMDirectory* d, MockRAMFile* f); + virtual void close(void); + virtual void flush(void); + virtual void writeByte(const uint8_t b); + virtual void writeBytes(const uint8_t* b, const int32_t length); + virtual int64_t length() const; + +private: + MockRAMDirectory* dir; + bool first; + uint8_t singleByte[1]; +}; + +class MockRAMInputStream : public RAMInputStream { + +public: + MockRAMInputStream(const MockRAMInputStream& clone); + MockRAMInputStream(MockRAMDirectory* d, const char* n, MockRAMFile* f); + void close(void); + + DEFINE_MUTABLE_MUTEX(openFiles_mutex); + +private: + MockRAMDirectory* dir; + std::string name; + bool isClone; +}; + + +CL_NS_END + +#endif // _lucene_store_MockRAMDirectory_ diff --git a/src/test/store/TestRAMDirectory.cpp b/src/test/store/TestRAMDirectory.cpp new file mode 100644 index 00000000000..e5c9c9adc12 --- /dev/null +++ b/src/test/store/TestRAMDirectory.cpp @@ -0,0 +1,218 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2010 Borivoj Kostka and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include +#include + +#include "CLucene.h" +#include "CLucene/_clucene-config.h" + +#include "CLucene/analysis/Analyzers.h" +#include "CLucene/document/Document.h" +#include "CLucene/document/Field.h" +#include "CLucene/index/IndexReader.h" +#include "CLucene/index/IndexWriter.h" +#include "CLucene/search/IndexSearcher.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/store/RAMDirectory.h" +#include "MockRAMDirectory.h" + +/** + * JUnit testcase to test RAMDirectory. RAMDirectory itself is used in many testcases, + * but not one of them uses an different constructor other than the default constructor. + * + * @author Bernhard Messer + * + * @version $Id: RAMDirectory.java 150537 2004-09-28 22:45:26 +0200 (Di, 28 Sep 2004) cutting $ + */ + +static int docsToAdd = 500; +static char indexDir[CL_MAX_PATH] = ""; + +struct ThreadData +{ + MockRAMDirectory * dir; + IndexWriter * writer; + int num; + CuTest * tc; +}; + +// setup the index +void testRAMDirectorySetUp (CuTest *tc) { + + if (strlen(cl_tempDir) + 13 > CL_MAX_PATH) + CuFail(tc, _T("Not enough space in indexDir buffer")); + + sprintf(indexDir, "%s/RAMDirIndex", cl_tempDir); + WhitespaceAnalyzer analyzer; + IndexWriter * writer = new IndexWriter(indexDir, &analyzer, true); + + // add some documents + TCHAR * text; + for (int i = 0; i < docsToAdd; i++) { + Document doc; + text = English::IntToEnglish(i); + doc.add(* new Field(_T("content"), text, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + writer->addDocument(&doc); + _CLDELETE_ARRAY(text); + } + + CuAssertEquals(tc, docsToAdd, writer->docCount(), _T("document count")); + writer->close(); + _CLDELETE( writer ); +} + +// BK> all test functions are the same except RAMDirectory constructor, so shared code moved here +void checkDir(CuTest *tc, MockRAMDirectory * ramDir) { + + // Check size + CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size")); + + // open reader to test document count + IndexReader * reader = IndexReader::open(ramDir); + CuAssertEquals(tc, docsToAdd, reader->numDocs(), _T("document count")); + + // open search to check if all doc's are there + IndexSearcher * searcher = _CLNEW IndexSearcher(reader); + + // search for all documents + Document doc; + for (int i = 0; i < docsToAdd; i++) { + searcher->doc(i, doc); + CuAssertTrue(tc, doc.getField(_T("content")) != NULL, _T("content is NULL")); + } + + // cleanup + reader->close(); + searcher->close(); + _CLLDELETE(reader); + _CLLDELETE(searcher); +} + +void testRAMDirectory (CuTest *tc) { + + Directory * dir = FSDirectory::getDirectory(indexDir); + MockRAMDirectory * ramDir = _CLNEW MockRAMDirectory(dir); + + // close the underlaying directory + dir->close(); + _CLDELETE( dir ); + + checkDir(tc, ramDir); + + ramDir->close(); + _CLLDELETE(ramDir); +} + +void testRAMDirectoryString (CuTest *tc) { + + MockRAMDirectory * ramDir = _CLNEW MockRAMDirectory(indexDir); + + checkDir(tc, ramDir); + + ramDir->close(); + _CLLDELETE(ramDir); +} + +static int numThreads = 50; +static int docsPerThread = 40; + +_LUCENE_THREAD_FUNC(indexDocs, _data) { + + ThreadData * data = (ThreadData *)_data; + int cnt = 0; + TCHAR * text; + for (int j=1; jnum*docsPerThread+j); + doc.add(*new Field(_T("sizeContent"), text, Field::STORE_YES | Field::INDEX_UNTOKENIZED)); + data->writer->addDocument(&doc); + _CLDELETE_ARRAY(text); + { + SCOPED_LOCK_MUTEX(data->dir->THIS_LOCK); + CuAssertTrue(data->tc, data->dir->sizeInBytes == data->dir->getRecomputedSizeInBytes()); + } + } + _LUCENE_THREAD_FUNC_RETURN( 0 ); +} + +void testRAMDirectorySize(CuTest * tc) { + + MockRAMDirectory * ramDir = _CLNEW MockRAMDirectory(indexDir); + WhitespaceAnalyzer analyzer; + IndexWriter * writer = _CLNEW IndexWriter(ramDir, &analyzer, false); + writer->optimize(); + + CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size")); + + _LUCENE_THREADID_TYPE* threads = _CL_NEWARRAY(_LUCENE_THREADID_TYPE, numThreads); + ThreadData * tdata = _CL_NEWARRAY(ThreadData, numThreads); + + for (int i=0; ioptimize(); + CuAssertTrue(tc, ramDir->sizeInBytes == ramDir->getRecomputedSizeInBytes(), _T("RAMDir size")); + + CuAssertEquals(tc, docsToAdd + (numThreads * (docsPerThread-1)), writer->docCount(), _T("document count")); + + writer->close(); + _CLLDELETE(writer); + + ramDir->close(); + _CLLDELETE(ramDir); +} + +#if 0 + public void testSerializable() throws IOException { + Directory dir = new RAMDirectory(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); + assertEquals("initially empty", 0, bos.size()); + ObjectOutput out = new ObjectOutputStream(bos); + int headerSize = bos.size(); + out.writeObject(dir); + out.close(); + assertTrue("contains more then just header", headerSize < bos.size()); + } +#endif + +void testRAMDirectoryTearDown(CuTest * tc) { + // cleanup + if (*indexDir) { + // delete index dir + all files in it (portable way!) + } + +} + +CuSuite *testRAMDirectory(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene RAMDirectory Test")); + + SUITE_ADD_TEST(suite, testRAMDirectorySetUp); + + SUITE_ADD_TEST(suite, testRAMDirectory); + SUITE_ADD_TEST(suite, testRAMDirectoryString); + SUITE_ADD_TEST(suite, testRAMDirectorySize); + + SUITE_ADD_TEST(suite, testRAMDirectoryTearDown); + + return suite; +} + diff --git a/src/test/store/TestStore.cpp b/src/test/store/TestStore.cpp new file mode 100644 index 00000000000..b73acb269a5 --- /dev/null +++ b/src/test/store/TestStore.cpp @@ -0,0 +1,123 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" +#include + + +void StoreTest(CuTest *tc,int32_t count, int mode){ + srand(1251971); + int32_t i; + + uint64_t veryStart = Misc::currentTimeMillis(); + uint64_t start = Misc::currentTimeMillis(); + + char fsdir[CL_MAX_PATH]; + _snprintf(fsdir, CL_MAX_PATH, "%s/%s",cl_tempDir, "test.store"); + Directory* store = NULL; + if ( mode == 1 ) + store = _CLNEW RAMDirectory(); + else{ + store = (Directory*)FSDirectory::getDirectory(fsdir); + ((FSDirectory*)store)->setUseMMap(mode == 3); + } + int32_t LENGTH_MASK = 0xFFF; + char name[260]; + + for (i = 0; i < count; i++) { + _snprintf(name,260,"%d.dat",i); + + int32_t length = rand() & LENGTH_MASK; + uint8_t b = (uint8_t)(rand() & 0x7F); + + IndexOutput* file = store->createOutput(name); + + for (int32_t j = 0; j < length; j++) + file->writeByte(b); + + file->close(); + _CLDELETE(file); + } + CuMessageA(tc, "%d total milliseconds to create\n", (int32_t)(Misc::currentTimeMillis() - start)); + + if (mode != 1){ + store->close(); + _CLDECDELETE(store); + store = (Directory*)FSDirectory::getDirectory(fsdir); + }else{ + CuMessageA(tc, "Memory used at end: %l", ((RAMDirectory*)store)->sizeInBytes); + } + + srand(1251971); + start = Misc::currentTimeMillis(); + + for (i = 0; i < count; i++) { + _snprintf(name,260,"%d.dat",i); + size_t length = rand() & LENGTH_MASK; + uint8_t b = (uint8_t)(rand() & 0x7F); + IndexInput* file = store->openInput(name); + + if (file->length() != length) + _CLTHROWA(CL_ERR_Runtime, "length incorrect" ); + + for (size_t j = 0; j < length; j++){ + if (file->readByte() != b){ + TCHAR buf[100]; + _tprintf(buf,_T("contents incorrect in file %d.dat"),i); + _CLTHROWT(CL_ERR_Runtime, buf); + } + } + + file->close(); + _CLDELETE(file); + } + + CuMessageA(tc,"%d total milliseconds to read\n", (int32_t)(Misc::currentTimeMillis() - start)); + + srand(1251971); + start = Misc::currentTimeMillis(); + + for (i = 0; i < count; i++) { + _snprintf(name,260,"%d.dat",i); + store->deleteFile(name); + } + + CuMessageA(tc, "%d total milliseconds to delete\n",(int32_t)(Misc::currentTimeMillis() - start)); + CuMessageA(tc, "%d total milliseconds \n", (int32_t)(Misc::currentTimeMillis() - veryStart)); + + //test makeLock::toString + CL_NS(store)::LuceneLock* lf = store->makeLock("testlock"); + std::string ts = lf->toString(); + CLUCENE_ASSERT( ts.compare("fail") != 0 ); + _CLDELETE(lf); + + store->close(); + _CLDECDELETE(store); +} + +void ramtest(CuTest *tc){ + StoreTest(tc,1000,1); +} +void fstest(CuTest *tc){ + StoreTest(tc,100,2); +} +void mmaptest(CuTest *tc){ + StoreTest(tc,100,3); +} + +CuSuite *teststore(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Store Test")); + + SUITE_ADD_TEST(suite, ramtest); + SUITE_ADD_TEST(suite, fstest); + SUITE_ADD_TEST(suite, mmaptest); + + return suite; +} +// EOF diff --git a/src/test/test.h b/src/test/test.h new file mode 100644 index 00000000000..777e7538a1b --- /dev/null +++ b/src/test/test.h @@ -0,0 +1,159 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#ifndef TEST_H +#define TEST_H +#include "CLucene.h" +#include "CLucene/_clucene-config.h" +#include "CLucene/config/repl_tchar.h" +#include "CLucene/config/repl_wchar.h" +#include "CLucene/debug/_condition.h" +#include "CLucene/util/StringBuffer.h" +#include "CLucene/util/Misc.h" + +#include "CLucene/store/RAMDirectory.h" +#include "CLucene/store/Lock.h" +#include "CLucene/index/TermVector.h" +#include "CLucene/queryParser/MultiFieldQueryParser.h" + +#include +#include +#include +#include + +using namespace std; + +#define LUCENE_INT64_MAX_SHOULDBE _ILONGLONG(0x7FFFFFFFFFFFFFFF) +#define LUCENE_INT64_MIN_SHOULDBE (-LUCENE_INT64_MAX_SHOULDBE - _ILONGLONG(1) ) + +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(store) +CL_NS_USE(search) +CL_NS_USE(document) +CL_NS_USE(queryParser) +CL_NS_USE(analysis) +CL_NS_USE2(analysis,standard) + +#include "CuTest.h" + +CuSuite *testatomicupdates(void); +CuSuite *testRAMDirectory(void); +CuSuite *testindexwriter(void); +CuSuite *testIndexModifier(void); +CuSuite *testindexreader(void); +CuSuite *testIndexSearcher(void); +CuSuite *testAddIndexesNoOptimize(void); +CuSuite *teststore(void); +CuSuite *testanalysis(void); +CuSuite *testanalyzers(void); +CuSuite *testhighfreq(void); +CuSuite *testhighlight(void); +CuSuite *testpriorityqueue(void); +CuSuite *testQueryParser(void); +CuSuite *testMultiFieldQueryParser(void); +CuSuite *testqueries(void); +CuSuite *testConstantScoreQueries(void); +CuSuite *testsearch(void); +CuSuite *testtermvector(void); +CuSuite *testsort(void); +CuSuite *testduplicates(void); +CuSuite *testRangeFilter(void); +CuSuite *testdatefilter(void); +CuSuite *testwildcard(void); +CuSuite *testdebug(void); +CuSuite *testutf8(void); +CuSuite *testreuters(void); +CuSuite *testdocument(void); +CuSuite *testField(void); +CuSuite *testNumberTools(void); +CuSuite *testDateTools(void); +CuSuite *testBoolean(void); +CuSuite *testBitSet(void); +CuSuite *testBKD(void); +CuSuite *testMSBRadixSorter(void); +CuSuite *testExtractTerms(void); +CuSuite *testSpanQueries(void); +CuSuite *testStringBuffer(void); +CuSuite *testTermVectorsReader(void); + +#ifdef TEST_CONTRIB_LIBS +CuSuite *testGermanAnalyzer(void); +#endif + +class English{ +public: + static void IntToEnglish(int32_t i, CL_NS(util)::StringBuffer* result); + static TCHAR* IntToEnglish(int32_t i); + static void IntToEnglish(int32_t i, TCHAR* buf, int32_t buflen); +}; + + +class TCharCompare{ +public: + bool operator()( const TCHAR* val1, const TCHAR* val2 ) const{ + if ( val1==val2) + return false; + bool ret = (_tcscmp( val1,val2 ) < 0); + return ret; + } +}; +class CharCompare{ +public: + bool operator()( const char* val1, const char* val2 ) const{ + if ( val1==val2) + return false; + bool ret = (strcmp( val1,val2 ) < 0); + return ret; + } +}; + +template +class StringMap : public std::map<_K,_T,_Comparator>{ + bool delKey; +public: + StringMap(bool delKey){ + this->delKey = delKey; + } + + void remove(_K val){ + std::iterator<_K,_T,_Comparator> itr; + itr = this->find(val); + if ( itr == this->end() ) + return; + _K v = itr->first; + this->erase(itr); + if ( delKey ){ + _CLDELETE_CARRAY(v); + } + } + virtual ~StringMap(){ + while ( this->begin() != this->end() ){ + _K v = this->begin()->first; + this->erase(this->begin()); + if ( delKey ){ + _CLDELETE_CARRAY(v); + } + } + } + void add(_K k, _T v){ + this->insert ( std::pair<_K,_T>(k,v) ); + } +}; + +void TestAssertIndexReaderEquals(CuTest *tc, IndexReader* reader1, IndexReader* reader2); + + +extern unittest tests[]; + +#define CLUCENE_DATA_LOCATION1 "../../src/test/data/" +#define CLUCENE_DATA_LOCATION2 "../src/test/data/" +#define CLUCENE_DATA_LOCATION3 "../../../src/test/data/" +#define CLUCENE_DATA_LOCATIONENV "srcdir" + +extern const char* cl_tempDir; + +#endif diff --git a/src/test/testall.cpp b/src/test/testall.cpp new file mode 100644 index 00000000000..77392b99207 --- /dev/null +++ b/src/test/testall.cpp @@ -0,0 +1,345 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +//msvc test for memory leaks: +#ifdef _MSC_VER + #ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include + #endif +#endif + +#include "test.h" +#include +#include + +#include +#ifdef _CL_HAVE_DIRECT_H + #include +#endif +#ifdef _CL_HAVE_SYS_STAT_H + #include +#endif +#ifdef _CL_HAVE_IO_H + #include +#endif + +std::string cl_tempDirS; +const char* cl_tempDir; +bool cl_quiet; +char clucene_data_location[1024]; + +int main(int argc, char *argv[]) +{ + #ifdef _MSC_VER + #ifdef _DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // | _CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_CHECK_CRT_DF + _crtBreakAlloc=-1; + #endif + #endif + + #ifdef DMALLOC + if ( getenv("DMALLOC_OPTIONS") == NULL ){ + dmalloc_debug_setup("low,log=dmalloc.log.txt"); + }else{ + //apparently cygwin has to have this code.... + dmalloc_debug_setup(getenv("DMALLOC_OPTIONS")); + } + #endif + + + int ret_result = 0; + int i=0; + int exclude = 0; + int list_provided = 0; + CuSuiteList *alltests = NULL; + CuString *output = CuStringNew(); + bool silent = false; + bool verbose = false; + bool times = true; + uint64_t startTime=0; + + if ( Misc::dir_Exists("/tmp") ) + cl_tempDirS = "/tmp"; + if ( getenv("TEMP") != NULL ) + cl_tempDirS = getenv("TEMP"); + else if ( getenv("TMP") != NULL ) + cl_tempDirS = getenv("TMP"); + + if ( Misc::dir_Exists( (cl_tempDirS + "/clucene").c_str() ) ) + cl_tempDirS += "/clucene"; + cl_tempDir = cl_tempDirS.c_str(); + + clucene_data_location[0]=0; + if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION1 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION1); + else if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION2 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION2); + else if ( CL_NS(util)::Misc::dir_Exists(CLUCENE_DATA_LOCATION3 "/reuters-21578-index/segments") ) + strcpy(clucene_data_location, CLUCENE_DATA_LOCATION3); + else if ( getenv(CLUCENE_DATA_LOCATIONENV) != NULL ){ + strcpy(clucene_data_location,getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location,"/data/reuters-21578-index/segments"); + if ( CL_NS(util)::Misc::dir_Exists( clucene_data_location ) ){ + strcpy(clucene_data_location, getenv(CLUCENE_DATA_LOCATIONENV)); + strcat(clucene_data_location, "/data"); + }else + clucene_data_location[0]=0; + } + + /* first check that we are running the test for the correct position */ + //todo: make this configurable + if ( !*clucene_data_location ){ + fprintf(stderr,"%s must be run from a subdirectory of the application's root directory\n",argv[0]); + fprintf(stderr,"ensure that the test data exists in %s or %s or %s\n",CLUCENE_DATA_LOCATION1, CLUCENE_DATA_LOCATION2, CLUCENE_DATA_LOCATION3); + if ( getenv(CLUCENE_DATA_LOCATIONENV) != NULL ) + fprintf(stderr,"%s/data was also checked because of the " CLUCENE_DATA_LOCATIONENV " environment variable", getenv(CLUCENE_DATA_LOCATIONENV)); + ret_result = 1; + goto exit_point; + } + + CuInit(argc, argv); + + /* see if we're in exclude mode, see if list of testcases provided */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i],"-h") || !strcmp(argv[i],"--help") || !strcmp(argv[i],"/?")){ + printf("%s [-l list] [-q quiet] [-v verbose] [-t show times] [-p printf messages immediatelly] [-x exclude] [tests...]\n",argv[0]); + goto exit_point; + } + if (!strcmp(argv[i], "-v")) { + verbose = true; + continue; + } + if (!strcmp(argv[i], "-p")) { //used in CuInit + continue; + } + if (!strcmp(argv[i], "-q")) { + silent = true; + continue; + } + if (!strcmp(argv[i], "-x")) { + exclude = 1; + continue; + } + if (!strcmp(argv[i], "-t")) { + times = true; + continue; + } + if (!strcmp(argv[i], "-l")) { + for (i = 0; tests[i].func != NULL; i++) { + printf("%s\n", tests[i].testname); + } + ret_result = 0; + goto exit_point; + } + if (argv[i][0] == '-') { + fprintf(stderr, "invalid option: `%s'\n", argv[i]); + ret_result = 1; + goto exit_point; + } + list_provided = 1; + } + + if (!list_provided) { + /* add everything */ + alltests = CuSuiteListNew(_T("All CLucene Tests")); + for (i = 0; tests[i].func != NULL; i++) { + CuSuiteListAdd(alltests, tests[i].func()); + } + } + else if (exclude) { + /* add everything but the tests listed */ + alltests = CuSuiteListNew(_T("Partial CLucene Tests")); + for (i = 0; tests[i].func != NULL; i++) { + int this_test_excluded = 0; + int j; + + for (j = 1; j < argc && !this_test_excluded; j++) { + if (!strcmp(argv[j], tests[i].testname)) { + this_test_excluded = 1; + } + } + if (!this_test_excluded) { + CuSuiteListAdd(alltests, tests[i].func()); + } + } + } + else { + /* add only the tests listed */ + alltests = CuSuiteListNew(_T("Partial CLucene Tests")); + for (i = 1; i < argc; i++) { + int j; + int found = 0; + + if (argv[i][0] == '-') { + continue; + } + for (j = 0; tests[j].func != NULL; j++) { + if (!strcmp(argv[i], tests[j].testname)) { + CuSuiteListAdd(alltests, tests[j].func()); + found = 1; + } + } + if (!found) { + fprintf(stderr, "invalid test name: `%s'\n", argv[i]); + ret_result = 1; + goto exit_point; + } + } + } + + startTime = Misc::currentTimeMillis(); + + printf("Key: .= pass N=not implemented F=fail\n"); + if ( silent ) + CuSuiteListRun(alltests); + else + CuSuiteListRunWithSummary(alltests,verbose,times); + i = CuSuiteListDetails(alltests, output); + _tprintf(_T("%s\n"), output->buffer); + + if ( times ) + printf("Tests run in %dms\n\n", (int32_t)(CL_NS(util)::Misc::currentTimeMillis()-startTime)); + +exit_point: + if ( alltests != NULL ) + CuSuiteListDelete(alltests); + CuStringFree(output); + + _lucene_shutdown(); //clears all static memory + + if ( ret_result != 0 ) + return ret_result; + else + return i > 0 ? 1 : 0; + + //Debuggin techniques: + //For msvc, use this for breaking on memory leaks: + // _crtBreakAlloc + //for linux, use valgrind +} + + +void TestAssertIndexReaderEquals(CuTest *tc, IndexReader* index1, IndexReader* index2){ + const Document::FieldsType* fields1, *fields2; + Document::FieldsType::const_iterator it1, it2; + + CuAssertPtrNotNull(tc, _T("check index1!=null"), index1); + CuAssertPtrNotNull(tc, _T("check index1!=null"), index2); + + //misc + CuAssertIntEquals(tc,_T("IndexReaders have different values for numDocs"), index1->numDocs(), index2->numDocs()); + CuAssertIntEquals(tc,_T("IndexReaders have different values for maxDoc"), index1->maxDoc(), index2->maxDoc()); + CuAssertIntEquals(tc,_T("Only one IndexReader has deletions"), index1->hasDeletions(), index2->hasDeletions()); + CuAssertIntEquals(tc,_T("Only one IndexReader is optimized"), index1->isOptimized(), index2->isOptimized()); + + //test field names + StringArrayWithDeletor fn1; + StringArrayWithDeletor fn2; + index1->getFieldNames(IndexReader::ALL, fn1); + index2->getFieldNames(IndexReader::ALL, fn2); + + //make sure field length is the same + int fn1count = fn1.size(); + int fn2count = fn2.size(); + CuAssertIntEquals(tc, _T("reader fieldnames count not equal"), fn1count, fn2count ); + for (int n=0;nnorms(fn1[n]); + uint8_t* norms2 = index2->norms(fn1[n]); + if ( norms1 != NULL ){ + CLUCENE_ASSERT(norms2 != NULL); + for ( int i=0;imaxDoc();i++ ){ + int diff = norms1[i]-norms2[i]; + if ( diff < 0 ) + diff *= -1; + if ( diff > 16 ){ + TCHAR tmp[1024]; + _sntprintf(tmp,1024,_T("Norms are off by more than the threshold! %d, should be %d"), (int32_t)norms2[i], (int32_t)norms1[i]); + CuAssert(tc,tmp,false); + } + } + }else + CLUCENE_ASSERT(norms2 == NULL); + //////////////////// + } + fn1.clear(); //save memory + fn2.clear(); //save memory + + + // check deletions + for (int i = 0; i < index1->maxDoc(); i++) { + CuAssertIntEquals( tc, _T("only deleted in one index."), index1->isDeleted(i), index2->isDeleted(i)); + } + + + // check stored fields + Document doc1; + Document doc2; + for (int i = 0; i < index1->maxDoc(); i++) { + if (!index1->isDeleted(i)) { + doc1.clear(); doc2.clear(); + index1->document(i, doc1); + index2->document(i, doc2); + fields1 = doc1.getFields(); + fields2 = doc2.getFields(); + CuAssertIntEquals(tc, _T("Different numbers of fields for doc "), fields1->size(), fields2->size()); + it1 = fields1->begin(); + it2 = fields2->begin(); + while ( it1 != fields1->end() ) { + Field* curField1 = *it1; + Field* curField2 = *it2; + CuAssertStrEquals( tc, _T("Different fields names for doc "), curField1->name(), curField2->name()); + CuAssertStrEquals( tc, _T("Different field values for doc "), curField1->stringValue(), curField2->stringValue()); + it1++; + it2++; + } + } + } + + + // check dictionary and posting lists + TermEnum* enum1 = index1->terms(); + TermEnum* enum2 = index2->terms(); + TermPositions* tp1 = index1->termPositions(); + TermPositions* tp2 = index2->termPositions(); + while(enum1->next()) { + + CuAssertTrue(tc,enum2->next()); + CuAssertStrEquals(tc, _T("Different term field in dictionary."), enum1->term(false)->field(), enum2->term(false)->field() ); + CuAssertStrEquals(tc, _T("Different term field in dictionary."), enum1->term(false)->text(), enum2->term(false)->text() ); + CuAssert(tc, _T("Different term in dictionary."), enum1->term(false)->equals(enum2->term(false)) ); + + tp1->seek(enum1->term(false)); + tp2->seek(enum1->term(false)); + while(tp1->next()) { + CuAssertTrue(tc, tp2->next()); + CuAssertIntEquals(tc,_T("Different doc id in postinglist of term"), tp1->doc(), tp2->doc()); + CuAssertIntEquals(tc,_T("Different term frequence in postinglist of term"), tp1->freq(), tp2->freq()); + for (int i = 0; i < tp1->freq(); i++) { + CuAssertIntEquals(tc,_T("Different positions in postinglist of term"), tp1->nextPosition(), tp2->nextPosition()); + } + } + } + _CLDELETE(enum1); + _CLDELETE(enum2); + _CLDELETE(tp1); + _CLDELETE(tp2); +} + diff --git a/src/test/tests.cpp b/src/test/tests.cpp new file mode 100644 index 00000000000..c8c20998778 --- /dev/null +++ b/src/test/tests.cpp @@ -0,0 +1,51 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" + +unittest tests[] = { +// {"threads", testatomicupdates}, +// {"indexreader", testindexreader}, +// {"indexsearcher", testIndexSearcher}, +// {"reuters", testreuters}, + {"analysis", testanalysis}, + {"analyzers", testanalyzers}, + {"document", testdocument}, + {"field", testField}, +// {"numbertools", testNumberTools}, +// {"debug", testdebug}, +// {"ramdirectory", testRAMDirectory}, +// {"indexwriter", testindexwriter}, +// {"indexmodifier", testIndexModifier}, +// {"addIndexesNoOptimize", testAddIndexesNoOptimize}, +// {"highfreq", testhighfreq}, +// {"priorityqueue", testpriorityqueue}, +// {"datetools", testDateTools}, +// {"queryparser", testQueryParser}, +// {"mfqueryparser", testMultiFieldQueryParser}, +// {"boolean", testBoolean}, +// {"search", testsearch}, +// {"rangefilter", testRangeFilter}, +// {"queries", testqueries}, +// {"csrqueries", testConstantScoreQueries}, +// {"termvector", testtermvector}, +// {"sort", testsort}, +// {"duplicates", testduplicates}, +// {"datefilter", testdatefilter}, +// {"wildcard", testwildcard}, +// {"store", teststore}, +// {"utf8", testutf8}, +// {"bitset", testBitSet}, + {"bkd", testBKD}, +// {"MSBRadixSorter",testMSBRadixSorter}, +// {"extractterms", testExtractTerms}, +// {"spanqueries", testSpanQueries}, +// {"stringbuffer", testStringBuffer}, +// {"termvectorsreader", testTermVectorsReader}, +#ifdef TEST_CONTRIB_LIBS + {"germananalyzer", testGermanAnalyzer}, +#endif + {"LastTest", NULL}}; diff --git a/src/test/util/English.cpp b/src/test/util/English.cpp new file mode 100644 index 00000000000..8f00aba5f61 --- /dev/null +++ b/src/test/util/English.cpp @@ -0,0 +1,134 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +CL_NS_USE(util) + +void English::IntToEnglish(int32_t i, StringBuffer* result) +{ + if (i == 0) + { + result->append(_T("zero")); + return ; + } + if (i < 0) + { + result->append(_T("minus ")); + i = - i; + } + if (i >= 1000000000) + { + // billions + IntToEnglish(i / 1000000000, result); + result->append(_T("billion, ")); + i = i % 1000000000; + } + if (i >= 1000000) + { + // millions + IntToEnglish(i / 1000000, result); + result->append(_T("million, ")); + i = i % 1000000; + } + if (i >= 1000) + { + // thousands + IntToEnglish(i / 1000, result); + result->append(_T("thousand, ")); + i = i % 1000; + } + if (i >= 100) + { + // hundreds + IntToEnglish(i / 100, result); + result->append(_T("hundred ")); + i = i % 100; + } + if (i >= 20) + { + switch (i / 10) + { + + case 9: result->append(_T("ninety")); break; + + case 8: result->append(_T("eighty")); break; + + case 7: result->append(_T("seventy")); break; + + case 6: result->append(_T("sixty")); break; + + case 5: result->append(_T("fifty")); break; + + case 4: result->append(_T("forty")); break; + + case 3: result->append(_T("thirty")); break; + + case 2: result->append(_T("twenty")); break; + } + i = i % 10; + if (i == 0) + result->append(_T(" ")); + else + result->append(_T("-")); + } + switch (i) + { + + case 19: result->append(_T("nineteen ")); break; + + case 18: result->append(_T("eighteen ")); break; + + case 17: result->append(_T("seventeen ")); break; + + case 16: result->append(_T("sixteen ")); break; + + case 15: result->append(_T("fifteen ")); break; + + case 14: result->append(_T("fourteen ")); break; + + case 13: result->append(_T("thirteen ")); break; + + case 12: result->append(_T("twelve ")); break; + + case 11: result->append(_T("eleven ")); break; + + case 10: result->append(_T("ten ")); break; + + case 9: result->append(_T("nine ")); break; + + case 8: result->append(_T("eight ")); break; + + case 7: result->append(_T("seven ")); break; + + case 6: result->append(_T("six ")); break; + + case 5: result->append(_T("five ")); break; + + case 4: result->append(_T("four ")); break; + + case 3: result->append(_T("three ")); break; + + case 2: result->append(_T("two ")); break; + + case 1: result->append(_T("one ")); break; + + case 0: result->append(_T("")); break; + } +} + +TCHAR* English::IntToEnglish(int32_t i) +{ + StringBuffer result; + IntToEnglish(i, &result); + return result.toString(); +} +void English::IntToEnglish(int32_t i, TCHAR* buf, int32_t buflen) +{ + StringBuffer result; + IntToEnglish(i, &result); + _tcsncpy(buf,result.getBuffer(),buflen); +} + diff --git a/src/test/util/TestBKD.cpp b/src/test/util/TestBKD.cpp new file mode 100644 index 00000000000..4c43216d96c --- /dev/null +++ b/src/test/util/TestBKD.cpp @@ -0,0 +1,960 @@ +#include "CLucene/util/FutureArrays.h" +#include "CLucene/util/NumericUtils.h" +#include "CLucene/util/bkd/bkd_reader.h" +#include "CLucene/util/bkd/bkd_writer.h" + +#include "CLucene/store/Directory.h" +#include "CLucene/store/FSDirectory.h" +#include "CLucene/store/IndexInput.h" +#include "TestBKD.h" + +#include "test.h" +#include + +CL_NS_USE(util) +CL_NS_USE(store) + +TestVisitor1::TestVisitor1( + int queryMin, int queryMax, + shared_ptr &hits) { + this->queryMin = queryMin; + this->queryMax = queryMax; + this->hits = hits; +} + +void TestVisitor1::visit(Roaring &docIDs) { + for (auto docID: docIDs) { + //wcout << L"visit docID=" << docID << endl; + hits->set(docID); + } +} + +void TestVisitor1::visit(int docID) { + hits->set(docID); + if (0) { + wcout << L"visit docID=" << docID << endl; + } +} + +bool TestVisitor1::matches(uint8_t *packedValue) { + std::vector result(4); + std::copy(packedValue, packedValue + 4, result.begin()); + int x = NumericUtils::sortableBytesToInt(result, 0); + if (x >= queryMin && x <= queryMax) { + return true; + } + return false; +} + +void TestVisitor1::visit(Roaring *docID, std::vector &packedValue) { + if (!matches(packedValue.data())) { + return; + } + visit(*docID); +} + +void TestVisitor1::visit(bkd::bkd_docID_set_iterator *iter, std::vector &packedValue) { + if (!matches(packedValue.data())) { + return; + } + int32_t docID = iter->docID_set->nextDoc(); + while (docID != lucene::util::bkd::bkd_docID_set::NO_MORE_DOCS) { + hits->set(docID); + docID = iter->docID_set->nextDoc(); + } +} + +void TestVisitor1::visit( + int docID, std::vector &packedValue) { + int x = NumericUtils::sortableBytesToInt(packedValue, 0); + if (0) { + wcout << L"visit docID=" << docID << L" x=" << x << endl; + } + if (x >= queryMin && x <= queryMax) { + //wcout << L"visit docID=" << docID << L" x=" << x << endl; + hits->set(docID); + } +} + +lucene::util::bkd::relation TestVisitor1::compare( + std::vector &minPacked, std::vector &maxPacked) { + int min = NumericUtils::sortableBytesToInt(minPacked, 0); + int max = NumericUtils::sortableBytesToInt(maxPacked, 0); + assert(max >= min); + if (0) { + wcout << L"compare: min=" << min << L" max=" << max << L" vs queryMin=" + << queryMin << L" queryMax=" << queryMax << endl; + } + + if (max < queryMin || min > queryMax) { + return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY; + } else if (min >= queryMin && max <= queryMax) { + return lucene::util::bkd::relation::CELL_INSIDE_QUERY; + } else { + return lucene::util::bkd::relation::CELL_CROSSES_QUERY; + } +} + +TestVisitor::TestVisitor(const uint8_t *qMin, const uint8_t *qMax, + BitSet *h, predicate p) { + queryMin = qMin; + queryMax = qMax; + hits = h; + pred = p; +} + +bool TestVisitor::matches(uint8_t *packedValue) { + for (int dim = 0; dim < reader->num_data_dims_; dim++) { + int offset = dim * reader->bytes_per_dim_; + if (pred == L) { + if (lucene::util::FutureArrays::CompareUnsigned( + packedValue, offset, offset + reader->bytes_per_dim_, queryMax, offset, + offset + reader->bytes_per_dim_) >= 0) { + // Doc's value is too high, in this dimension + return false; + } + } else if (pred == G) { + if (lucene::util::FutureArrays::CompareUnsigned( + packedValue, offset, offset + reader->bytes_per_dim_, queryMin, offset, + offset + reader->bytes_per_dim_) <= 0) { + // Doc's value is too high, in this dimension + return false; + } + } else { + if (lucene::util::FutureArrays::CompareUnsigned( + packedValue, offset, offset + reader->bytes_per_dim_, queryMin, offset, + offset + reader->bytes_per_dim_) < 0) { + // Doc's value is too low, in this dimension + return false; + } + if (lucene::util::FutureArrays::CompareUnsigned( + packedValue, offset, offset + reader->bytes_per_dim_, queryMax, offset, + offset + reader->bytes_per_dim_) > 0) { + // Doc's value is too high, in this dimension + return false; + } + } + } + return true; +} + +void TestVisitor::visit(int rowID) { + hits->set(rowID); + if (0) { + std::wcout << L"visit docID=" << rowID << std::endl; + } +} + +void TestVisitor::visit(int rowID, std::vector &packedValue) { + if (0) { + int x = lucene::util::NumericUtils::sortableBytesToLong(packedValue, 0); + std::wcout << L"visit docID=" << rowID << L" x=" << x << std::endl; + } + if (matches(packedValue.data())) { + hits->set(rowID); + } +} + +lucene::util::bkd::relation TestVisitor::compare(std::vector &minPacked, + std::vector &maxPacked) { + bool crosses = false; + + for (int dim = 0; dim < reader->num_data_dims_; dim++) { + int offset = dim * reader->bytes_per_dim_; + + if (pred == L) { + if (lucene::util::FutureArrays::CompareUnsigned( + minPacked.data(), offset, offset + reader->bytes_per_dim_, queryMax, offset, + offset + reader->bytes_per_dim_) >= 0) { + return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY; + } + } else if (pred == G) { + if (lucene::util::FutureArrays::CompareUnsigned( + maxPacked.data(), offset, offset + reader->bytes_per_dim_, queryMin, offset, + offset + reader->bytes_per_dim_) <= 0) { + return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY; + } + } else { + if (lucene::util::FutureArrays::CompareUnsigned( + minPacked.data(), offset, offset + reader->bytes_per_dim_, queryMax, offset, + offset + reader->bytes_per_dim_) > 0 || + lucene::util::FutureArrays::CompareUnsigned( + maxPacked.data(), offset, offset + reader->bytes_per_dim_, queryMin, offset, + offset + reader->bytes_per_dim_) < 0) { + return lucene::util::bkd::relation::CELL_OUTSIDE_QUERY; + } + } + + crosses |= lucene::util::FutureArrays::CompareUnsigned( + minPacked.data(), offset, offset + reader->bytes_per_dim_, queryMin, + offset, offset + reader->bytes_per_dim_) <= 0 || + lucene::util::FutureArrays::CompareUnsigned( + maxPacked.data(), offset, offset + reader->bytes_per_dim_, queryMax, + offset, offset + reader->bytes_per_dim_) >= 0; + } + + if (crosses) { + return lucene::util::bkd::relation::CELL_CROSSES_QUERY; + } else { + return lucene::util::bkd::relation::CELL_INSIDE_QUERY; + } +} + +Directory *getDirectory(int numPoints) { + Directory *dir; + if (numPoints > 100000) { + //dir = newFSDirectory(createTempDir(L"TestBKDTree")); + } else { + dir = FSDirectory::getDirectory("TestBKDTree"); + } + return dir; +} + +void testSameInts1DWrite(CuTest *tc) { + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTreeSame")); + shared_ptr w = + make_shared(N, 1, 1, 4, 512, 100.0f, N, true); + w->docs_seen_ = N; + + for (int docID = 0; docID < N; docID++) { + std::vector scratch(4); + + //auto x = docID / 10000; + if (docID > 500000) { + NumericUtils::intToSortableBytes(200, scratch, 0); + + } else { + NumericUtils::intToSortableBytes(100, scratch, 0); + } + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), docID); + } + + int64_t indexFP; + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexOutput out = + // dir.createOutput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + std::unique_ptr out(dir->createOutput("bkd")); + std::unique_ptr meta_out(dir->createOutput("bkd_meta")); + std::unique_ptr index_out(dir->createOutput("bkd_index")); + + //auto metaOffset = w->MetaInit(out.get()); + try { + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } catch (...) { + printf("something wrong\n"); + //printf("clucene error: %s\n",r.what()); + } + } + dir->close(); + _CLDECDELETE(dir); +} + +void testSameInts1DRead(CuTest *tc) { + uint64_t str = Misc::currentTimeMillis(); + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTreeSame")); + //Directory *dir = new FSDirectory("TestBKDTree"); + { + IndexInput *in_(dir->openInput("bkd")); + IndexInput *meta_in_(dir->openInput("bkd_meta")); + IndexInput *index_in_(dir->openInput("bkd_index")); + shared_ptr r = make_shared(in_); + + // Simple 1D range query: + constexpr int queryMin = 200; + constexpr int queryMax = 200; + + //std::shared_ptr hits; + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + try { + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + for (int docID = 0; docID < N; docID++) { + bool expected = docID >= queryMin && docID <= queryMax; + bool actual = hits->get(N - docID - 1); + //printf("%d %d\n",expected,actual); + CuAssertEquals(tc, expected, actual); + + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + printf("\nFirst search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + auto hits1 = std::make_shared(N); + auto v1 = std::make_unique(queryMin, queryMax, hits1); + str = Misc::currentTimeMillis(); + + r->intersect(v1.get()); + for (int docID = 0; docID < N; docID++) { + bool expected = docID >= queryMin && docID <= queryMax; + bool actual = hits1->get(N - docID - 1); + //printf("%d %d\n",expected,actual); + CuAssertEquals(tc, expected, actual); + + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + printf("\nSecond search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } + dir->close(); + _CLDECDELETE(dir); +} + +void testBug1Write(CuTest *tc) { + const int N = 8; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + shared_ptr w = + make_shared(N, 1, 1, 4, 4, 100.0f, N, true); + w->docs_seen_ = N; + std::vector scratch(4); + + for (int i = 0; i < 6; i++) { + NumericUtils::intToSortableBytes(0, scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), i); + } + + for (int i = 6; i < N; i++) { + NumericUtils::intToSortableBytes(1, scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), i); + } + + int64_t indexFP; + { + std::unique_ptr out(dir->createOutput("bkd3")); + std::unique_ptr meta_out(dir->createOutput("bkd3_meta")); + std::unique_ptr index_out(dir->createOutput("bkd3_index")); + try { + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } catch (...) { + printf("something wrong\n"); + //printf("clucene error: %s\n",r.what()); + } + } + dir->close(); + _CLDECDELETE(dir); +} + +void testBug1Read(CuTest *tc) { + uint64_t str = Misc::currentTimeMillis(); + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + { + IndexInput *in_(dir->openInput("bkd3")); + IndexInput *meta_in_(dir->openInput("bkd3_meta")); + IndexInput *index_in_(dir->openInput("bkd3_index")); + + shared_ptr r = make_shared(in_); + // Simple 1D range query: + int value = 0; + auto result = std::make_unique(10); + std::vector value_bytes(4); + + lucene::util::NumericUtils::intToSortableBytes(value, value_bytes, 0); + const auto *max = reinterpret_cast(value_bytes.data()); + const auto *min = reinterpret_cast(value_bytes.data()); + + auto v = std::make_unique(min, max, result.get(), EQ); + try { + v->setReader(r); + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + printf("hits count=%d\n", result->count()); + CuAssertEquals(tc, result->count(), 6); + printf("\nFirst search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } +} + +void testLowCardinalInts1DWrite(CuTest *tc) { + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + shared_ptr w = + make_shared(N, 1, 1, 4, 512, 100.0f, N, true); + w->docs_seen_ = N; + + for (int docID = 0; docID < N; docID++) { + std::vector scratch(4); + + NumericUtils::intToSortableBytes(docID % (1024 * 8), scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), docID); + } + + int64_t indexFP; + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexOutput out = + // dir.createOutput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + std::unique_ptr out(dir->createOutput("bkd2")); + std::unique_ptr meta_out(dir->createOutput("bkd2_meta")); + std::unique_ptr index_out(dir->createOutput("bkd2_index")); + + //auto metaOffset = w->MetaInit(out.get()); + try { + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } catch (...) { + printf("something wrong\n"); + //printf("clucene error: %s\n",r.what()); + } + } + dir->close(); + _CLDECDELETE(dir); +} + +void testLowCardinalInts1DRead2(CuTest *tc) { + uint64_t str = Misc::currentTimeMillis(); + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + { + IndexInput *in_(dir->openInput("bkd2")); + IndexInput *meta_in_(dir->openInput("bkd2_meta")); + IndexInput *index_in_(dir->openInput("bkd2_index")); + + shared_ptr r = make_shared(in_); + // Simple 1D range query: + constexpr int queryMin = 0; //std::numeric_limits::min(); + constexpr int queryMax = 100;//std::numeric_limits::max(); + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + try { + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + printf("hits count=%d\n", hits->count()); + CuAssertEquals(tc, hits->count(), 12928); + printf("\nFirst search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } +} + +void testLowCardinalInts1DRead(CuTest *tc) { + uint64_t str = Misc::currentTimeMillis(); + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + { + IndexInput *in_(dir->openInput("bkd2")); + IndexInput *meta_in_(dir->openInput("bkd2_meta")); + IndexInput *index_in_(dir->openInput("bkd2_index")); + + shared_ptr r = make_shared(in_); + // Simple 1D range query: + constexpr int queryMin = 0;//std::numeric_limits::min(); + constexpr int queryMax = 1;//std::numeric_limits::max(); + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + try { + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + printf("hits count=%d\n", hits->count()); + CuAssertEquals(tc, hits->count(), 256); + printf("\nFirst search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } +} + +void testBasicsInts1DWrite(CuTest *tc) { + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + shared_ptr w = + make_shared(N, 1, 1, 4, 512, 100.0f, N, true); + w->docs_seen_ = N; + + for (int docID = 0; docID < N; docID++) { + std::vector scratch(4); + + NumericUtils::intToSortableBytes(N - docID - 1, scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), docID); + } + + int64_t indexFP; + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexOutput out = + // dir.createOutput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + std::unique_ptr out(dir->createOutput("bkd")); + std::unique_ptr meta_out(dir->createOutput("bkd_meta")); + std::unique_ptr index_out(dir->createOutput("bkd_index")); + //auto metaOffset = w->MetaInit(out.get()); + try { + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } catch (...) { + printf("something wrong\n"); + //printf("clucene error: %s\n",r.what()); + } + } + dir->close(); + _CLDECDELETE(dir); +} + +void testBasicsInts1DRead(CuTest *tc) { + uint64_t str = Misc::currentTimeMillis(); + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + { + IndexInput *in_(dir->openInput("bkd")); + IndexInput *meta_in_(dir->openInput("bkd_meta")); + IndexInput *index_in_(dir->openInput("bkd_index")); + shared_ptr r = make_shared(in_); + // Simple 1D range query: + constexpr int queryMin = 1024; + constexpr int queryMax = std::numeric_limits::max(); + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + try { + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + for (int docID = 0; docID < N; docID++) { + bool expected = docID >= queryMin && docID <= queryMax; + bool actual = hits->get(N - docID - 1); + if (expected != actual) { + wcout << docID << " " << expected << " " << actual; + } + CuAssertEquals(tc, expected, actual); + + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + printf("\nFirst search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + auto hits1 = std::make_shared(N); + auto v1 = std::make_unique(queryMin, queryMax, hits1); + str = Misc::currentTimeMillis(); + + r->intersect(v1.get()); + for (int docID = 0; docID < N; docID++) { + bool expected = docID >= queryMin && docID <= queryMax; + bool actual = hits1->get(N - docID - 1); + if (expected != actual) { + wcout << "failed to equal: " << docID << " " << expected << " " << actual; + } + CuAssertEquals(tc, expected, actual); + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + printf("\nSecond search time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } + dir->close(); + _CLDECDELETE(dir); +} + +void testHttplogsRead(CuTest *tc) { + uint64_t str = 0;//Misc::currentTimeMillis(); + const int N = 100; + Directory *dir(FSDirectory::getDirectory("/mnt/disk1/jiangkai/workspace/bin/selectdb/output/be/storage/data/0/10356/151990979/0200000000000003834799d9978e0299cb61196d147f3ba8_0_3")); + + //Directory *dir(FSDirectory::getDirectory("/mnt/disk1/jiangkai/tmp/test_log/bkd")); + //Directory *dir = new FSDirectory("TestBKDTree"); + { + IndexInput *in_(dir->openInput("bkd")); + IndexInput *meta_in_(dir->openInput("bkd_meta")); + IndexInput *index_in_(dir->openInput("bkd_index")); + + shared_ptr r = make_shared(in_); + std::vector scratch(4); + std::vector scratch2(4); + + NumericUtils::intToSortableBytes(200, scratch, 0); + NumericUtils::intToSortableBytes(800, scratch2, 0); + auto result = std::make_unique(1000000000); + + const auto *max = reinterpret_cast(scratch2.data()); + const auto *min = reinterpret_cast(scratch.data()); + + auto v = std::make_unique(min, max, result.get(), G); + v->setReader(r); + try { + str = Misc::currentTimeMillis(); + r->read_meta(meta_in_); + //auto type = r->read_type(); + //CuAssertEquals(tc, 0, type); + r->read_index(index_in_); + r->intersect(v.get()); + printf("\ntry query result:%ld\n", r->estimate_point_count(v.get())); + printf("\nsearch time taken: %d ms\n\n", (int32_t) (Misc::currentTimeMillis() - str)); + } catch (CLuceneError &r) { + //printf("something wrong in read\n"); + printf("clucene error: %s\n", r.what()); + } + printf("result size = %d\n", result->count()); + CuAssertEquals(tc, result->count(), 8445); + printf("stats=%s\n", r->stats.to_string().c_str()); + } + dir->close(); + _CLDECDELETE(dir); +} + +void testBasicInts1D(CuTest *tc) { + + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.Directory dir = + // getDirectory(100)) + { + //std::shared_ptr dir{getDirectory(10001)}; + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + shared_ptr w = + make_shared(N, 1, 1, 4, 512, 100.0f, N, true); + + for (int docID = 0; docID < N; docID++) { + std::vector scratch(4); + + NumericUtils::intToSortableBytes(docID, scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), docID); + } + + int64_t indexFP; + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexOutput out = + // dir.createOutput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + std::unique_ptr out(dir->createOutput("bkd")); + std::unique_ptr meta_out(dir->createOutput("bkd_meta")); + std::unique_ptr index_out(dir->createOutput("bkd_index")); + + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } + + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexInput in = + // dir.openInput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + IndexInput *in_(dir->openInput("bkd")); + IndexInput *meta_in_(dir->openInput("bkd_meta")); + IndexInput *index_in_(dir->openInput("bkd_index")); + //in_->seek(indexFP); + shared_ptr r = make_shared(in_); + + // Simple 1D range query: + constexpr int queryMin = 4; + constexpr int queryMax = 8; + + //std::shared_ptr hits; + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + + for (int docID = 0; docID < N; docID++) { + bool expected = (docID >= queryMin && docID <= queryMax); + bool actual = hits->get(docID); + //printf("%d %d\n",expected,actual); + CuAssertEquals(tc, expected, actual); + + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + } + dir->close(); + _CLDECDELETE(dir); + } +} + +void testSame(CuTest *tc) { + + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.Directory dir = + // getDirectory(100)) + { + //std::shared_ptr dir{getDirectory(10001)}; + const int N = 1024 * 1024; + Directory *dir(FSDirectory::getDirectory("TestBKDTree")); + shared_ptr w = + make_shared(N, 1, 1, 4, 512, 100.0f, N, true); + + for (int docID = 0; docID < N; docID++) { + std::vector scratch(4); + + NumericUtils::intToSortableBytes(100, scratch, 0); + //w->Add(scratch, docID); + w->add(scratch.data(), scratch.size(), docID); + } + + int64_t indexFP; + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexOutput out = + // dir.createOutput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + std::unique_ptr out(dir->createOutput("bkd")); + std::unique_ptr meta_out(dir->createOutput("bkd_meta")); + std::unique_ptr index_out(dir->createOutput("bkd_index")); + indexFP = w->finish(out.get(), index_out.get()); + w->meta_finish(meta_out.get(), indexFP, 0); + } + + // C++ NOTE: The following 'try with resources' block is replaced by its C++ + // equivalent: ORIGINAL LINE: try (org.apache.lucene.store.IndexInput in = + // dir.openInput("bkd", org.apache.lucene.store.IOContext.DEFAULT)) + { + IndexInput *in_(dir->openInput("bkd")); + IndexInput *meta_in_(dir->openInput("bkd_meta")); + IndexInput *index_in_(dir->openInput("bkd_index")); + //in_->seek(indexFP); + shared_ptr r = make_shared(in_); + + // Simple 1D range query: + constexpr int queryMin = 100; + constexpr int queryMax = 100; + + //std::shared_ptr hits; + auto hits = std::make_shared(N); + auto v = std::make_unique(queryMin, queryMax, hits); + r->read_meta(meta_in_); + //auto type = r->read_type(); + CuAssertEquals(tc, 0, r->type); + r->read_index(index_in_); + r->intersect(v.get()); + + for (int docID = 0; docID < N; docID++) { + bool expected = (100 >= queryMin && 100 <= queryMax); + bool actual = hits->get(docID); + if (expected != actual) { + wcout << "failed to equal: " << docID << " " << expected << " " << actual; + } + CuAssertEquals(tc, expected, actual); + //assertEquals(L"docID=" + to_wstring(docID), expected, actual); + } + } + dir->close(); + _CLDECDELETE(dir); + } +} + +void equal_predicate(std::shared_ptr r) { + long value = 20220324090000; + auto result = std::make_unique(r->point_count_); + + const auto *max = reinterpret_cast(&value); + const auto *min = reinterpret_cast(&value); + + auto v = std::make_unique(min, max, result.get(), EQ); + v->setReader(r); + r->intersect(v.get()); + printf("count: %d\n", result->count()); +} + +void less_equal_predicate(std::shared_ptr r) { + try { + long value = 20220427000000; + auto result = std::make_unique(r->point_count_); + std::vector min(r->bytes_per_dim_); + + switch (r->bytes_per_dim_) { + case 4: + lucene::util::NumericUtils::intToSortableBytes(std::numeric_limits::min(), min, 0); + case 8: + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::min(), min, 0); + case 16: + //TODO: need longlongToSortableBytes + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::min(), min, 0); + } + const auto *max = reinterpret_cast(&value); + + auto v = std::make_unique(min.data(), max, result.get(), LE); + v->setReader(r); + r->intersect(v.get()); + printf("\ncount: %d\n", result->count()); + } catch (...) { + printf("something wrong\n"); + //printf("clucene error: %s\n",r.what()); + } +} + +void less_predicate(std::shared_ptr r) { + long value = 20220427000000; + auto result = std::make_unique(r->point_count_); + std::vector min(r->bytes_per_dim_); + + switch (r->bytes_per_dim_) { + case 4: + lucene::util::NumericUtils::intToSortableBytes(std::numeric_limits::min(), min, 0); + case 8: + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::min(), min, 0); + case 16: + //TODO: need longlongToSortableBytes + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::min(), min, 0); + } + const auto *max = reinterpret_cast(&value); + + auto v = std::make_unique(min.data(), max, result.get(), L); + v->setReader(r); + r->intersect(v.get()); + printf("count: %d\n", result->count()); +} + +void greater_equal_predicate(std::shared_ptr r) { + long value = 20220427000000; + auto result = std::make_unique(r->point_count_); + std::vector max(r->bytes_per_dim_); + + switch (r->bytes_per_dim_) { + case 4: + lucene::util::NumericUtils::intToSortableBytes(std::numeric_limits::max(), max, 0); + case 8: + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::max(), max, 0); + case 16: + //TODO: need longlongToSortableBytes + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::max(), max, 0); + } + const auto *min = reinterpret_cast(&value); + + auto v = std::make_unique(min, max.data(), result.get(), GE); + v->setReader(r); + r->intersect(v.get()); + printf("count: %d\n", result->count()); +} + +void greater_predicate(std::shared_ptr r) { + long value = 20220324090000; + auto result = std::make_unique(r->point_count_); + std::vector max(r->bytes_per_dim_); + + switch (r->bytes_per_dim_) { + case 4: + lucene::util::NumericUtils::intToSortableBytes(std::numeric_limits::max(), max, 0); + case 8: + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::max(), max, 0); + case 16: + //TODO: need longlongToSortableBytes + lucene::util::NumericUtils::longToSortableBytes(std::numeric_limits::max(), max, 0); + } + const auto *min = reinterpret_cast(&value); + + auto v = std::make_unique(min, max.data(), result.get(), G); + v->setReader(r); + r->intersect(v.get()); + printf("count: %d\n", result->count()); +} + +std::shared_ptr testBKDReadInit(const std::string &index_full_path) { + lucene::store::Directory *dir = + lucene::store::FSDirectory::getDirectory(index_full_path.c_str()); + + lucene::store::IndexInput *in_(dir->openInput("bkd")); + std::unique_ptr meta_in_(dir->openInput("bkd_meta")); + + auto indexFP = meta_in_->readVLong(); + in_->seek(indexFP); + std::shared_ptr r = + make_shared(in_); + dir->close(); + _CLDECDELETE(dir); + return r; +} + +void testBKDRead(CuTest *tc) { + try { + printf("Location of files indexed: "); + char ndx[250] = ""; + + char *tmp = fgets(ndx, 250, stdin); + if (tmp == nullptr) return; + ndx[strlen(ndx) - 1] = 0; + printf("Location to store the clucene index: %s", ndx); + + //IndexFiles(files,ndx,true); + vector files; + std::sort(files.begin(), files.end()); + Misc::listDirs(ndx, files, true); + auto itr = files.begin(); + while (itr != files.end()) { + if (!IndexReader::indexExists(itr->c_str())) { + vector in_files; + + Misc::listDirs(itr->c_str(), in_files, true); + for (auto &file: in_files) { + //printf("file %s:%d\n", file.c_str(), IndexReader::indexExists(file.c_str())); + if (IndexReader::indexExists(file.c_str())) { + auto r = testBKDReadInit(file); + //equal_predicate(r); + //greater_predicate(r); + //greater_equal_predicate(r); + less_equal_predicate(r); + //less_predicate(r); + } + } + + //printf("directory %s:%d\n", itr->c_str(), IndexReader::indexExists(itr->c_str())); + itr++; + continue; + } + itr++; + } + } catch (...) { + printf("Exception\n"); + } +} + +void testBKDWrite(CuTest *tc) { + testBasicsInts1DWrite(tc); + testBasicsInts1DRead(tc); + //testSameInts1DWrite(tc); + //testSameInts1DRead(tc); + //testBasicInts1D(tc); + //testSame(tc); +} + +void testBKDWriteSame(CuTest *tc) { + //testBasicInts1D(tc); + testSame(tc); +} + +void testBKDWriteLowCardinality(CuTest *tc) { + testLowCardinalInts1DWrite(tc); + testLowCardinalInts1DRead(tc); + testLowCardinalInts1DRead2(tc); +} + +void testBKDBug1(CuTest *tc) { + testBug1Write(tc); + testBug1Read(tc); +} + +CuSuite *testBKD() { + CuSuite *suite = CuSuiteNew(_T("CLucene BKD Test")); + + SUITE_ADD_TEST(suite, testBKDWrite); + SUITE_ADD_TEST(suite, testBKDWriteSame); + //SUITE_ADD_TEST(suite, testHttplogsRead); + SUITE_ADD_TEST(suite, testBKDWriteLowCardinality); + SUITE_ADD_TEST(suite, testBKDBug1); + return suite; +} diff --git a/src/test/util/TestBKD.h b/src/test/util/TestBKD.h new file mode 100644 index 00000000000..8a79552cc68 --- /dev/null +++ b/src/test/util/TestBKD.h @@ -0,0 +1,110 @@ +#include "CLucene/util/BitSet.h" +#include "CLucene/util/bkd/bkd_reader.h" +#include "CLucene/util/croaring/roaring.hh" + +#include +#include + +class TestVisitor1 : public lucene::util::bkd::bkd_reader::intersect_visitor { +private: + int queryMin = 0; + int queryMax = 0; + std::shared_ptr hits; + +public: + TestVisitor1(int queryMin, int queryMax, + std::shared_ptr &hits); + + void visit(int docID) override; + void visit(Roaring &docID) override; + void visit(Roaring &&docIDs) override { + { + for (auto docID : docIDs) { + //wcout << L"visit docID=" << docID << endl; + hits->set(docID); + } + } + } + void visit(std::vector& docID, std::vector &packedValue) override { + if (!matches(packedValue.data())) { + return; + } + visit(Roaring::read(docID.data(), false)); + } + void visit(Roaring *docID, std::vector &packedValue) override; + void visit(int docID, std::vector &packedValue) override; + void visit(lucene::util::bkd::bkd_docID_set_iterator *iter, std::vector &packedValue) override; + + bool matches(uint8_t *packedValue); + + lucene::util::bkd::relation compare(std::vector &minPacked, + std::vector &maxPacked) override; +}; + +enum predicate { + L, + G, + LE, + GE, + EQ +}; + +class TestVisitor : public lucene::util::bkd::bkd_reader::intersect_visitor { +private: + const uint8_t *queryMin; + const uint8_t *queryMax; + //int queryMin = 0; + //int queryMax = 0; + lucene::util::BitSet *hits; + //std::shared_ptr hits; + std::shared_ptr reader; + predicate pred; + +public: + TestVisitor(const uint8_t *queryMin, const uint8_t *queryMax, lucene::util::BitSet *hits, predicate p); + virtual ~TestVisitor() = default; + + void setReader(std::shared_ptr &r) { reader = r; }; + + void visit(int rowID) override; + void visit(std::vector& docID, std::vector &packedValue) override { + if (!matches(packedValue.data())) { + return; + } + visit(Roaring::read(docID.data(), false)); + } + void visit(Roaring &docIDs) override { + for (auto docID: docIDs) { + //std::wcout << L"visit docID=" << docID << endl; + hits->set(docID); + } + }; + void visit(Roaring &&docIDs) override { + for (auto docID: docIDs) { + //std::wcout << L"visit docID=" << docID << endl; + hits->set(docID); + } + }; + void visit(Roaring *docID, std::vector &packedValue) override { + if (!matches(packedValue.data())) { + return; + } + visit(*docID); + }; + void visit(lucene::util::bkd::bkd_docID_set_iterator *iter, std::vector &packedValue) override { + if (!matches(packedValue.data())) { + return; + } + int32_t docID = iter->docID_set->nextDoc(); + while (docID != lucene::util::bkd::bkd_docID_set::NO_MORE_DOCS) { + hits->set(docID); + docID = iter->docID_set->nextDoc(); + } + }; + bool matches(uint8_t *packedValue); + + void visit(int rowID, std::vector &packedValue) override; + + lucene::util::bkd::relation compare(std::vector &minPacked, + std::vector &maxPacked) override; +}; \ No newline at end of file diff --git a/src/test/util/TestBitSet.cpp b/src/test/util/TestBitSet.cpp new file mode 100644 index 00000000000..99be78c8261 --- /dev/null +++ b/src/test/util/TestBitSet.cpp @@ -0,0 +1,266 @@ +#include "test.h" +#include "CLucene/store/Directory.h" +#include "CLucene/store/IndexInput.h" +#include "CLucene/util/BitSet.h" + +CL_NS_USE(util) +CL_NS_USE(store) + +/** + * Compare two BitVectors. + * This should really be an equals method on the BitVector itself. + * @param bv One bit vector + * @param compare The second to compare + */ +bool doCompare(BitSet& bv, BitSet& compare) { + bool equal = true; + for(int i=0;isize();i++) { + CLUCENE_ASSERT(!bv->get(i)); + CLUCENE_ASSERT(i==bv->count()); + bv->set(i); + CLUCENE_ASSERT(bv->get(i)); + CLUCENE_ASSERT(i+1==bv->count()); + } + + _CLLDELETE(bv); + bv = _CLNEW BitSet(n); + // test count when setting then clearing bits + for(int i=0;isize();i++) { + CLUCENE_ASSERT(!bv->get(i)); + CLUCENE_ASSERT(0==bv->count()); + bv->set(i, true); + CLUCENE_ASSERT(bv->get(i)); + CLUCENE_ASSERT(1==bv->count()); + bv->set(i, false); + CLUCENE_ASSERT(!bv->get(i)); + CLUCENE_ASSERT(0==bv->count()); + } + + _CLLDELETE(bv); +} + +/** + * Test the count() method on BitVectors of various sizes. + * @throws Exception + */ +void testCount(CuTest* tc) { + doTestCountVectorOfSize(tc, 8); + doTestCountVectorOfSize(tc, 20); + doTestCountVectorOfSize(tc, 100); + doTestCountVectorOfSize(tc, 1000); +} + +void doTestWriteRead(CuTest* tc, int n) { + Directory* d = new RAMDirectory(); + + BitSet bv(n); + // test count when incrementally setting bits + for(int i=0;iset(i); + CLUCENE_ASSERT(i+1==bv->count()); + } + bv->write(d, "TESTBV"); + // gradually increase number of set bits + for (int i=count1; iset(i, true); + CLUCENE_ASSERT(i+1==bv->count()); + bv->write(d, "TESTBV"); + } + // now start decreasing number of set bits + for (int i=count2-1; i>=count1; i--) { + BitVector* bv2 = _CLNEW BitSet(d, "TESTBV"); + CLUCENE_ASSERT(doCompare(*bv,*bv2)); + _CLLDELETE(bv); + bv = bv2; + bv->set(i, false); + CLUCENE_ASSERT(i==bv->count()); + bv->write(d, "TESTBV"); + } + _CLLDELETE(bv); + _CLLDECDELETE( d ); +} + +/** + * Test r/w when size/count cause switching between bit-set and d-gaps file formats. + * @throws Exception + */ +void testDgaps(CuTest* tc) { + doTestDgaps(tc, 1,0,1); + doTestDgaps(tc, 10,0,1); + doTestDgaps(tc, 100,0,1); + doTestDgaps(tc, 202,0,1); + doTestDgaps(tc, 1000,4,7); + doTestDgaps(tc, 10000,40,43); + doTestDgaps(tc, 100000,415,418); + doTestDgaps(tc, 1000000,3123,3126); +} + +void doTestBitAtEndOfBitSet(CuTest* tc, int size, int pos) { + Directory* d = _CLNEW RAMDirectory(); + BitSet* bv = _CLNEW BitSet(size); + + bv->set(pos, true); + bv->write(d, "TESTBV"); + _CLLDELETE(bv); + bv = _CLNEW BitSet(d, "TESTBV"); + CLUCENE_ASSERT(bv->get(pos)); + _CLLDELETE( bv ); + _CLLDECDELETE( d ); +} + +void testBitAtEndOfBitSet(CuTest* tc) { + doTestBitAtEndOfBitSet(tc, 202, 200); +} + +void doTestNextSetBit(CuTest* tc, int nSize) +{ + BitSet bv( nSize ); + int nIdx; + int nExpectedIdx; + + // initialize bit set by setting every second bit starting with 0 + for( int32_t i = 0; i < bv.size(); i+=2 ) + bv.set(i); + + // iterate the bits + nIdx = 0; + nExpectedIdx = 0; + while( (nIdx = bv.nextSetBit( nIdx )) != -1 ) + { + assertEquals( nExpectedIdx, nIdx ); + nExpectedIdx += 2; + nIdx++; + } +} + +/** + * Test the nextSetBit() method on BitVectors of various sizes. + * CLucene specific + * @throws Exception + */ +void testNextSetBit(CuTest* tc) +{ + doTestNextSetBit(tc, 8); + doTestNextSetBit(tc, 20); + doTestNextSetBit(tc, 100); +} + +CuSuite *testBitSet(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene BitSet Test")); + + SUITE_ADD_TEST(suite, testConstructSize); + SUITE_ADD_TEST(suite, testGetSet); + SUITE_ADD_TEST(suite, testClear); + SUITE_ADD_TEST(suite, testCount); + SUITE_ADD_TEST(suite, testWriteRead); + SUITE_ADD_TEST(suite, testDgaps); + SUITE_ADD_TEST(suite, testBitAtEndOfBitSet); + + SUITE_ADD_TEST(suite, testNextSetBit); + + return suite; +} + diff --git a/src/test/util/TestMSBRadixSorter.cpp b/src/test/util/TestMSBRadixSorter.cpp new file mode 100644 index 00000000000..d817e11833e --- /dev/null +++ b/src/test/util/TestMSBRadixSorter.cpp @@ -0,0 +1,123 @@ +#include "TestMSBRadixSorter.h" +#include "CLucene/util/NumericUtils.h" +#include "test.h" + +#include +#include +void TestMSBRadixSorter::test(std::vector &refs, + std::vector &refs2, + int len) { + std::vector expected; + + for (auto ref : refs) { + //printf("expected %x %x\n",ref.bytes.at(2), ref.bytes.at(3)); + expected.push_back(ref); + } + //std::sort(expected.begin(), expected.end()); + + int maxLength = 0; + for (int i = 0; i < len; ++i) { + auto ref = refs[i]; + maxLength = max(maxLength, ref.length); + } + + int finalMaxLength = maxLength; + make_shared(shared_from_this(), maxLength, + &refs2, finalMaxLength)->sort(0, len); + std::vector> actual; + for (const auto& ref : refs2) { + //printf("actual %x %x\n",ref.bytes.at(2), ref.bytes.at(3)); + actual.push_back(std::make_shared(ref)); + } + CuAssertEquals(tc, actual.size(), expected.size()); + + for (auto i=0; i< actual.size();i++) { + CuAssertEquals(tc, actual[i]->bytes.size(), expected[i].bytes.size()); + //printf("%x %x\n",actual[i]->bytes.at(3), expected[i].bytes.at(3)); + CuAssertEquals(tc,actual[i]->bytes.at(3), expected[i].bytes.at(3)); + } + + + //assertArrayEquals(expected, actual); +} + +TestMSBRadixSorter::MSBRadixSorterAnonymousInnerClass:: + MSBRadixSorterAnonymousInnerClass( + shared_ptr outerInstance, int maxLength, + vector *refs, + int finalMaxLength) + : MSBRadixSorter(maxLength) +{ + this->outerInstance = outerInstance; + this->refs = refs; + this->finalMaxLength = finalMaxLength; +} + +int TestMSBRadixSorter::MSBRadixSorterAnonymousInnerClass::byteAt(int i, int k) +{ + auto ref = (*refs)[i]; + if (ref.length <= k) { + return -1; + } + return ref.bytes.at(ref.offset + k) & 0xff; +} + +void TestMSBRadixSorter::MSBRadixSorterAnonymousInnerClass::swap(int i, int j) +{ + //printf("swap %d %d\n",i,j); + /*if (i >= refs.size()||j >= refs.size()){ + printf("bang\n"); + return; + }*/ + auto tmp = (*refs)[i]; + (*refs)[i] = (*refs)[j]; + (*refs)[j] = tmp; +} + +void TestMSBRadixSorter::testOneValue() +{ + std::vector scratch(4); + NumericUtils::intToSortableBytes(1, scratch, 0); + + BytesRef x1(scratch); + + std::vector y; + y.emplace_back(x1); + test(y, y, 1); +} + +void TestMSBRadixSorter::testNValues() +{ + const int n = 1000; + std::vector scratch(4); + auto y = std::vector(); + auto z = std::vector(); + + for (int docID = 0; docID < n; docID++) { + NumericUtils::intToSortableBytes(docID, scratch, 0); + BytesRef x1(scratch); + y.emplace_back(x1); + } + //for (int docID = 0; docID = 0; docID--) { + NumericUtils::intToSortableBytes(docID, scratch, 0); + BytesRef x1(scratch); + z.emplace_back(x1); + } + + test(y,z, n); +} + +void testSorter(CuTest *tc) { + auto test = std::make_shared(tc); + test->testOneValue(); + test->testNValues(); +} + +CuSuite *testMSBRadixSorter() { + CuSuite *suite = CuSuiteNew(_T("CLucene MSBRadixSorter Test")); + + SUITE_ADD_TEST(suite, testSorter); + + return suite; +} \ No newline at end of file diff --git a/src/test/util/TestMSBRadixSorter.h b/src/test/util/TestMSBRadixSorter.h new file mode 100644 index 00000000000..e7656944215 --- /dev/null +++ b/src/test/util/TestMSBRadixSorter.h @@ -0,0 +1,71 @@ +#pragma once +#include +#include +#include +#include + +// C++ NOTE: Forward class declarations: +#include "CLucene/util/BytesRef.h" +#include "CLucene/util/MSBRadixSorter.h" +#include "test.h" + +using namespace std; +using namespace lucene::util; +class TestMSBRadixSorter : public enable_shared_from_this { +public: + TestMSBRadixSorter(CuTest *tc):tc(tc){} + ~TestMSBRadixSorter() = default; + +private: + CuTest *tc; + +public: + void test(std::vector &refs, std::vector &refs2, int len); + +private: + class MSBRadixSorterAnonymousInnerClass : public MSBRadixSorter { + private: + std::shared_ptr outerInstance; + + std::vector* refs; + int finalMaxLength = 0; + + public: + MSBRadixSorterAnonymousInnerClass( + std::shared_ptr outerInstance, int maxLength, + std::vector *refs, + int finalMaxLength); + + protected: + int byteAt(int i, int k) override; + + void swap(int i, int j) override; + + protected: + std::shared_ptr shared_from_this() { + return std::static_pointer_cast( + MSBRadixSorter::shared_from_this()); + } + }; + +public: + //virtual void testEmpty(); + + virtual void testOneValue(); + + virtual void testNValues(); + +/*private: + void testRandom(int commonPrefixLen, int maxLen); + +public: + virtual void testRandom(); + + virtual void testRandomWithLotsOfDuplicates(); + + virtual void testRandomWithSharedPrefix(); + + virtual void testRandomWithSharedPrefixAndLotsOfDuplicates(); + + virtual void testRandom2();*/ +}; diff --git a/src/test/util/TestPriorityQueue.cpp b/src/test/util/TestPriorityQueue.cpp new file mode 100644 index 00000000000..c01519979bf --- /dev/null +++ b/src/test/util/TestPriorityQueue.cpp @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "test.h" +#include +#include + + //test string buffer + //StringBuffer sb; + //sb.appendFloat(0.02f,2); + //CuAssertStrEquals(tc, _T("appendFloat failed"), _T("0.02"), sb.getBuffer()); + + + class integerQueue: public CL_NS(util)::PriorityQueue{ + public: + integerQueue(int32_t count) + { + initialize(count,false); + } + protected: + bool lessThan(int32_t a, int32_t b) { + return (a < b); + } + }; + + void _test_PriorityQueue(CuTest *tc,int32_t count){ + integerQueue pq(count); + srand ( (unsigned)time(NULL) ); + int32_t sum = 0, sum2 = 0; + + uint64_t start = CL_NS(util)::Misc::currentTimeMillis(); + + for (int32_t i = 0; i < count; i++) { + int32_t next = -rand(); + //int32_t next = (count+1)-i; + sum += next; + pq.put( next ); + } + CuMessageA(tc,"%d milliseconds/", (int32_t)(CL_NS(util)::Misc::currentTimeMillis()-start)); + CuMessageA(tc,"%d puts\n",count); + start = CL_NS(util)::Misc::currentTimeMillis(); + + int32_t last = -0x7FFFFFFF; + for (int32_t j = 0; j < count; j++) { + int32_t next = pq.pop(); + + if ( next < last ){ + TCHAR buf[1024]; + _sntprintf(buf,1024,_T("next < last at %d (last: %d, next: %d)"),j,last,next); + CuAssert(tc,buf,false); + } + last = next; + sum2 += last; + } + + CuMessageA(tc,"%d milliseconds", (int32_t)(CL_NS(util)::Misc::currentTimeMillis()-start)); + CuMessageA(tc,"/%d pops\n",count); + + CLUCENE_ASSERT(sum == sum); + } + void testPriorityQueue(CuTest *tc){ + _test_PriorityQueue(tc,100000); + } + + +CuSuite *testpriorityqueue(void) +{ + CuSuite *suite = CuSuiteNew(_T("CLucene Priority Queue Test")); + + SUITE_ADD_TEST(suite, testPriorityQueue); + + return suite; +} +// EOF diff --git a/src/test/util/TestStringBuffer.cpp b/src/test/util/TestStringBuffer.cpp new file mode 100644 index 00000000000..fa95edc9b13 --- /dev/null +++ b/src/test/util/TestStringBuffer.cpp @@ -0,0 +1,116 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2010 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ + +#include "test.h" +#include "CLucene/util/StringBuffer.h" +#include + +CL_NS_USE(util) + +void testStringBufferConstruct(CuTest *tc) { + StringBuffer sb; + CuAssertEquals(tc, 0, sb.length()); + + StringBuffer sb1(10); + CuAssertEquals(tc, 0, sb1.length()); + + StringBuffer sb2(_T("test")); + CuAssertEquals(tc, 4, sb2.length()); + CuAssertStrEquals(tc, _T(""), _T("test"), sb2.getBuffer()); +} + +void testStringBufferCharAt(CuTest *tc) { + StringBuffer sb(_T("test abcd")); + + CuAssertTrue(tc, sb.charAt(0) == _T('t'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(1) == _T('e'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(2) == _T('s'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(3) == _T('t'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(4) == _T(' '), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(5) == _T('a'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(6) == _T('b'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(7) == _T('c'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(8) == _T('d'), _T("unexpected character")); + + sb.setCharAt(4, _T('-')); + + CuAssertTrue(tc, sb.charAt(0) == _T('t'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(1) == _T('e'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(2) == _T('s'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(3) == _T('t'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(4) == _T('-'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(5) == _T('a'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(6) == _T('b'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(7) == _T('c'), _T("unexpected character")); + CuAssertTrue(tc, sb.charAt(8) == _T('d'), _T("unexpected character")); +} + +void testStringBufferClear(CuTest *tc) { + StringBuffer sb(_T("test abcd wxyz")); + sb.clear(); + CuAssertEquals(tc, 0, sb.length()); + CuAssertStrEquals(tc, _T(""), _T("\0"), sb.getBuffer()); +} + +void testStringBufferInsert(CuTest *tc) { + StringBuffer sb(_T("test abcd")); + + sb.insert(5, _T('X')); + CuAssertStrEquals(tc, _T(""), _T("test Xabcd"), sb.getBuffer()); + + sb.insert(7, _T("YY")); + CuAssertStrEquals(tc, _T(""), _T("test XaYYbcd"), sb.getBuffer()); + + sb.insert(7, _T("")); + CuAssertStrEquals(tc, _T(""), _T("test XaYYbcd"), sb.getBuffer()); + + sb.insert(12, _T("ZZZ")); + CuAssertStrEquals(tc, _T(""), _T("test XaYYbcdZZZ"), sb.getBuffer()); + + sb.insert(15, _T('_')); + CuAssertStrEquals(tc, _T(""), _T("test XaYYbcdZZZ_"), sb.getBuffer()); + + sb.insert(0, _T('_')); + CuAssertStrEquals(tc, _T(""), _T("_test XaYYbcdZZZ_"), sb.getBuffer()); + + sb.insert(0, _T("123")); + CuAssertStrEquals(tc, _T(""), _T("123_test XaYYbcdZZZ_"), sb.getBuffer()); +} + +void testStringBufferDelete(CuTest *tc) { + StringBuffer sb(_T("test abcd")); + + sb.deleteCharAt(4); + CuAssertStrEquals(tc, _T(""), _T("testabcd"), sb.getBuffer()); + + sb.deleteChars(4, 7); + CuAssertStrEquals(tc, _T(""), _T("testd"), sb.getBuffer()); + + sb.deleteChars(3, 3); + CuAssertStrEquals(tc, _T(""), _T("testd"), sb.getBuffer()); +} + +void testSubstringEquals(CuTest *tc) { + StringBuffer sb(_T("test abcd")); + + CuAssertTrue(tc, sb.substringEquals(3, 6, _T("t a"))); + CuAssertTrue(tc, sb.substringEquals(3, 6, _T("t a"), 3)); + CuAssertTrue(tc, !sb.substringEquals(3, 6, _T("t-a"), 3)); +} + +CuSuite *testStringBuffer(void) { + CuSuite *suite = CuSuiteNew(_T("CLucene StringBuffer Test")); + + SUITE_ADD_TEST(suite, testStringBufferConstruct); + SUITE_ADD_TEST(suite, testStringBufferCharAt); + SUITE_ADD_TEST(suite, testStringBufferClear); + SUITE_ADD_TEST(suite, testStringBufferInsert); + SUITE_ADD_TEST(suite, testStringBufferDelete); + SUITE_ADD_TEST(suite, testSubstringEquals); + + return suite; +} diff --git a/src/tokenizer/CMakeLists.txt b/src/tokenizer/CMakeLists.txt new file mode 100644 index 00000000000..79662abaf48 --- /dev/null +++ b/src/tokenizer/CMakeLists.txt @@ -0,0 +1,23 @@ +PROJECT(clucene-mmseg) + +include(${ClickHouse_SOURCE_DIR}/cmake/dbms_glob_sources.cmake) + +add_headers_and_sources(clucene-mmseg include) +add_headers_and_sources(clucene-mmseg src) + +add_library(clucene-mmseg-static STATIC ${clucene-mmseg_headers} ${clucene-mmseg_sources}) +target_include_directories (clucene-mmseg-static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +#original make +#set(TOKENIZER_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + +#include_directories( +# ${TOKENIZER_DIR} +# ${TOKENIZER_DIR}/include +#) + +#file(GLOB TOKENIZER_SRC_PATH ./src/*.cpp ./src/*.c) + +#add_library(tokenizer STATIC ${TOKENIZER_SRC_PATH}) + +#target_link_libraries(tokenizer) \ No newline at end of file diff --git a/src/tokenizer/etc/unigram.txt b/src/tokenizer/etc/unigram.txt new file mode 100644 index 00000000000..aec76860714 --- /dev/null +++ b/src/tokenizer/etc/unigram.txt @@ -0,0 +1,218464 @@ +真功 1 +x:1 +铅锌 1 +x:1 +不学无术 1 +x:1 +奸险 1 +x:1 +楼兰 1 +x:1 +踏步 1 +x:1 +考察队员 1 +x:1 +岗上 1 +x:1 +洪武 1 +x:1 +小腿 1 +x:1 +编译 1 +x:1 +蝶泳 1 +x:1 +空竹 1 +x:1 +小腹 1 +x:1 +营造林 1 +x:1 +流光溢彩 1 +x:1 +让座 1 +x:1 +让度 1 +x:1 +绞刑架 1 +x:1 +蕉麻 1 +x:1 +踏歌 1 +x:1 +供应部 1 +x:1 +专门法 1 +x:1 +黄鸟 1 +x:1 +苏库尔 1 +x:1 +河 187 +x:187 +造假者 1 +x:1 +台北队 1 +x:1 +湖边 1 +x:1 +追随 1 +x:1 +编读 1 +x:1 +否定者 1 +x:1 +看作 1 +x:1 +信仰主义 1 +x:1 +巾帼 1 +x:1 +好色 1 +x:1 +芦根 1 +x:1 +凳子 1 +x:1 +反 1205 +x:1205 +作战股 1 +x:1 +先人后己 1 +x:1 +传媒者 1 +x:1 +畅叙 1 +x:1 +福利会 1 +x:1 +须知 1 +x:1 +用心 1 +x:1 +枯木朽株 1 +x:1 +发射场 1 +x:1 +看似 1 +x:1 +阴宅 1 +x:1 +非正义 1 +x:1 +编订 1 +x:1 +悲号 1 +x:1 +鹿角队 1 +x:1 +二郎 1 +x:1 +集粹 1 +x:1 +悲叹 1 +x:1 +有理有据 1 +x:1 +赊购 1 +x:1 +麻省 1 +x:1 +外姓 1 +x:1 +小脚 1 +x:1 +防化兵 1 +x:1 +悚然 1 +x:1 +凹底镇 1 +x:1 +麻石 1 +x:1 +安盛 1 +x:1 +毛瑟枪 1 +x:1 +查哨 1 +x:1 +安盟 1 +x:1 +牧牛颂 1 +x:1 +五彩湾 1 +x:1 +书款 1 +x:1 +百忙之中 1 +x:1 +苏丹港 1 +x:1 +知法犯法 1 +x:1 +应 3692 +x:3692 +空空 1 +x:1 +古刹 1 +x:1 +空穴 1 +x:1 +视觉美 1 +x:1 +羊爬式 1 +x:1 +站貌 1 +x:1 +装配工 1 +x:1 +坦途 1 +x:1 +份餐 1 +x:1 +岗亭 1 +x:1 +新疆班 1 +x:1 +小臂 1 +x:1 +奸雄 1 +x:1 +以远 1 +x:1 +捉摸不定 1 +x:1 +市价 1 +x:1 +须眉 1 +x:1 +管闲事 1 +x:1 +九二六 1 +x:1 +直拨 1 +x:1 +亚型 1 +x:1 +身残 1 +x:1 +身殉 1 +x:1 +套鞋 1 +x:1 +战表 1 +x:1 +富家区 1 +x:1 +贺函 1 +x:1 +骇异 1 +x:1 +份饭 1 +x:1 +无可奉告 1 +x:1 +手术学 1 +x:1 +锯齿草 1 +x:1 +标准级 1 +x:1 +没法儿 1 +x:1 +后手 1 +x:1 +势力 1 +x:1 +中国科 1 +x:1 +本周末 1 +x:1 +遂溪 1 +x:1 +保级 1 +x:1 +外头 1 +x:1 +安的列斯 1 +x:1 +身段 1 +x:1 +纵横 1 +x:1 +潮阳 1 +x:1 +含金量 1 +x:1 +战壕 1 +x:1 +鹿 71 +x:71 +供应量 1 +x:1 +伶俐 1 +x:1 +时至今日 1 +x:1 +上 23705 +x:23705 +古县 1 +x:1 +眠山 1 +x:1 +用之不竭 1 +x:1 +蹦蹦车 1 +x:1 +职能 1 +x:1 +欢闹 1 +x:1 +县团级 1 +x:1 +份额 1 +x:1 +服用者 1 +x:1 +工具书 1 +x:1 +枯 17 +x:17 +达标赛 1 +x:1 +外壳 1 +x:1 +情真词切 1 +x:1 +小聚 1 +x:1 +安睡 1 +x:1 +独行客 1 +x:1 +后排 1 +x:1 +文化法 1 +x:1 +落脚点 1 +x:1 +多会儿 1 +x:1 +地动仪 1 +x:1 +国有 1 +x:1 +电信业者 1 +x:1 +音像版 1 +x:1 +岗位 1 +x:1 +九泉瞑目 1 +x:1 +气色 1 +x:1 +空管 1 +x:1 +看中 1 +x:1 +壑 3 +x:3 +虎口脱险 1 +x:1 +蜜蜂 1 +x:1 +福利业 1 +x:1 +平滑肌 1 +x:1 +外墙 1 +x:1 +古史 1 +x:1 +多疑 1 +x:1 +武昌站 1 +x:1 +郁郁葱葱 1 +x:1 +孤行 1 +x:1 +诉讼法 1 +x:1 +奥运会 1 +x:1 +血气方刚 1 +x:1 +吴家窑乡 1 +x:1 +看上 1 +x:1 +票子 1 +x:1 +小考 1 +x:1 +胜任 1 +x:1 +裱 1 +x:1 +次子 1 +x:1 +两头在外 1 +x:1 +计委 1 +x:1 +安眠 1 +x:1 +封建残余 1 +x:1 +人微言轻 1 +x:1 +开路先锋 1 +x:1 +贫血 1 +x:1 +清偿力 1 +x:1 +他向化 1 +x:1 +增减 1 +x:1 +水落石出 1 +x:1 +太公 1 +x:1 +猛丁 1 +x:1 +暴发户 1 +x:1 +唐家庄 1 +x:1 +壶流河 1 +x:1 +寒潮 1 +x:1 +旱船 1 +x:1 +慢条斯理 1 +x:1 +埋三怨四 1 +x:1 +错讹 1 +x:1 +高低杠 1 +x:1 +小胜 1 +x:1 +哲思 1 +x:1 +纵步 1 +x:1 +次官 1 +x:1 +陵园路 1 +x:1 +气节 1 +x:1 +治军 1 +x:1 +新老交替 1 +x:1 +其次 1 +x:1 +缕儿 1 +x:1 +八角楼 1 +x:1 +铅铁 1 +x:1 +小肠 1 +x:1 +独占资本 1 +x:1 +错话 1 +x:1 +至情至性 1 +x:1 +警卫队 1 +x:1 +人类学 1 +x:1 +铃虫 1 +x:1 +训练班 1 +x:1 +不育症 1 +x:1 +冰壶 1 +x:1 +错误 1 +x:1 +今年底 1 +x:1 +千次率 1 +x:1 +意识 1 +x:1 +街名 1 +x:1 +房舍 1 +x:1 +悲剧 1 +x:1 +e##e 825857 +x:825857 +缅甸 1 +x:1 +拨改贷 1 +x:1 +遮阳 1 +x:1 +总商会 1 +x:1 +邹庄镇 1 +x:1 +短撅撅 1 +x:1 +集结 1 +x:1 +枯木逢春 1 +x:1 +溜滑 1 +x:1 +依依 1 +x:1 +后患 1 +x:1 +祛痰活血 1 +x:1 +左膝 1 +x:1 +升赏 1 +x:1 +贺匾 1 +x:1 +缓坡 1 +x:1 +花生饼 1 +x:1 +传播点 1 +x:1 +货运界 1 +x:1 +辩论声 1 +x:1 +连跑带跳 1 +x:1 +仔细 1 +x:1 +炊帚 1 +x:1 +赏月 1 +x:1 +贺兰 1 +x:1 +披 61 +x:61 +好者 1 +x:1 +承德 1 +x:1 +法治论 1 +x:1 +祝家庄镇 1 +x:1 +好耍 1 +x:1 +轻歌曼舞 1 +x:1 +后悔 1 +x:1 +无异者 1 +x:1 +麻田 1 +x:1 +风中之烛 1 +x:1 +气腹 1 +x:1 +摸索 1 +x:1 +谈道 1 +x:1 +浩气长存 1 +x:1 +婚介所 1 +x:1 +贺卡 1 +x:1 +九三学社 1 +x:1 +拖住 1 +x:1 +肩摩毂击 1 +x:1 +配音 1 +x:1 +诘问 1 +x:1 +悲凉 1 +x:1 +校长 1 +x:1 +银灰 1 +x:1 +外客 1 +x:1 +兢 22 +x:22 +供货商 1 +x:1 +棋友 1 +x:1 +城关乡 1 +x:1 +修养论 1 +x:1 +自愿性 1 +x:1 +陬 1 +x:1 +石壕吏 1 +x:1 +践 6 +x:6 +集约 1 +x:1 +演示厅 1 +x:1 +外宾 1 +x:1 +咱村 1 +x:1 +轻骑兵 1 +x:1 +楼台 1 +x:1 +可怜相 1 +x:1 +千难万劫 1 +x:1 +麻痹 1 +x:1 +巾帕 1 +x:1 +藏医科 1 +x:1 +单干户 1 +x:1 +运动感 1 +x:1 +豫港队 1 +x:1 +风情万种 1 +x:1 +外存 1 +x:1 +外孙 1 +x:1 +单人滑 1 +x:1 +拆迁房 1 +x:1 +江河行地 1 +x:1 +圣路易斯 1 +x:1 +晴到少云 1 +x:1 +须生 1 +x:1 +羊册镇 1 +x:1 +套间 1 +x:1 +概 7 +x:7 +后怕 1 +x:1 +赏析 1 +x:1 +视而不见 1 +x:1 +切齿痛恨 1 +x:1 +嘉奖 1 +x:1 +婚恋 1 +x:1 +校门 1 +x:1 +麻疹 1 +x:1 +配 324 +x:324 +燕窝镇 1 +x:1 +演剧队 1 +x:1 +楼厦 1 +x:1 +真假 1 +x:1 +指事 1 +x:1 +赊账 1 +x:1 +婿乡 1 +x:1 +锐角 1 +x:1 +风风光光 1 +x:1 +维族舞 1 +x:1 +拨乱反正 1 +x:1 +好胜 1 +x:1 +棋协 1 +x:1 +岸站 1 +x:1 +折款 1 +x:1 +小脑 1 +x:1 +信奉者 1 +x:1 +绝对数 1 +x:1 +鸡冠花 1 +x:1 +可燃物 1 +x:1 +撅 2 +x:2 +石化部 1 +x:1 +揣摩 1 +x:1 +太史 1 +x:1 +至死不渝 1 +x:1 +方方正正 1 +x:1 +烩面 1 +x:1 +棋势 1 +x:1 +豆乳 1 +x:1 +钥 1 +x:1 +小艇 1 +x:1 +眼镜店 1 +x:1 +镇尺 1 +x:1 +吹风会 1 +x:1 +阴谋诡计 1 +x:1 +棋力 1 +x:1 +活字版 1 +x:1 +近程 1 +x:1 +大前提 1 +x:1 +伊川县 1 +x:1 +鄢家河 1 +x:1 +将近 1 +x:1 +打擂台 1 +x:1 +安生 1 +x:1 +我家 1 +x:1 +仉 1 +x:1 +萝卜 1 +x:1 +轰动一时 1 +x:1 +刁羊 1 +x:1 +无水硝 1 +x:1 +足球狂 1 +x:1 +次女 1 +x:1 +小船 1 +x:1 +特殊教育 1 +x:1 +不景气 1 +x:1 +次好 1 +x:1 +集美 1 +x:1 +太原 1 +x:1 +绩 10 +x:10 +真凶 1 +x:1 +小舅 1 +x:1 +另谋高就 1 +x:1 +小井庄 1 +x:1 +小舟 1 +x:1 +潭影 1 +x:1 +强弩之末 1 +x:1 +油灯壶 1 +x:1 +寻 108 +x:108 +咽喉 1 +x:1 +古刻 1 +x:1 +杏核眼 1 +x:1 +陷落地震 1 +x:1 +外婆 1 +x:1 +侈 1 +x:1 +外套 1 +x:1 +甏 1 +x:1 +短时期 1 +x:1 +真切 1 +x:1 +扫黄办 1 +x:1 +公平交易 1 +x:1 +鸡冠菜 1 +x:1 +刑警 1 +x:1 +点播 1 +x:1 +清凄寂冷 1 +x:1 +决非偶然 1 +x:1 +军事志 1 +x:1 +莲子酱 1 +x:1 +立体声 1 +x:1 +卢布 1 +x:1 +包罗万象 1 +x:1 +以一警百 1 +x:1 +拥有权 1 +x:1 +耕种人 1 +x:1 +胸怀祖国 1 +x:1 +书标 1 +x:1 +小苗 1 +x:1 +贴紧 1 +x:1 +终南山 1 +x:1 +阳离子 1 +x:1 +错觉 1 +x:1 +夜壶 1 +x:1 +坐舱 1 +x:1 +泡沫塑料 1 +x:1 +太医 1 +x:1 +珍藏卡 1 +x:1 +坐船 1 +x:1 +当 2786 +x:2786 +古典 1 +x:1 +截瘫 1 +x:1 +户主 1 +x:1 +古共 1 +x:1 +幸事 1 +x:1 +幸亏 1 +x:1 +玉戈 1 +x:1 +绞丝儿 1 +x:1 +太化 1 +x:1 +小节 1 +x:1 +外地人 1 +x:1 +情窦初开 1 +x:1 +明码 1 +x:1 +书案 1 +x:1 +握力 1 +x:1 +将军级 1 +x:1 +书桌 1 +x:1 +胜似 1 +x:1 +春花作物 1 +x:1 +自主 1 +x:1 +八节 1 +x:1 +零散 1 +x:1 +交易点 1 +x:1 +国台办 1 +x:1 +次席 1 +x:1 +库银 1 +x:1 +零数 1 +x:1 +上海滩 1 +x:1 +用药者 1 +x:1 +砝码 1 +x:1 +狮子 1 +x:1 +可控性 1 +x:1 +傣 4 +x:4 +次帅 1 +x:1 +总纲 1 +x:1 +卫生部 1 +x:1 +百科 1 +x:1 +外差 1 +x:1 +锶 4 +x:4 +护旗手 1 +x:1 +刀削面 1 +x:1 +新疆省 1 +x:1 +胃 21 +x:21 +中书令 1 +x:1 +瞻仰厅 1 +x:1 +海胆 1 +x:1 +类型学 1 +x:1 +编辑 1 +x:1 +鲅鱼圈 1 +x:1 +古国 1 +x:1 +次年 1 +x:1 +峥 3 +x:3 +立体式 1 +x:1 +保税 1 +x:1 +汉字机 1 +x:1 +电表费 1 +x:1 +多伦多市 1 +x:1 +嫡堂 1 +x:1 +配重 1 +x:1 +孪 1 +x:1 +端正 1 +x:1 +聂桥镇 1 +x:1 +其源 1 +x:1 +银元 1 +x:1 +中关园 1 +x:1 +铅酸 1 +x:1 +票幅 1 +x:1 +摘掉 1 +x:1 +压力表 1 +x:1 +运动服 1 +x:1 +雁过拔毛 1 +x:1 +不顾流俗 1 +x:1 +乳胶 1 +x:1 +干椰枣 1 +x:1 +昆布 1 +x:1 +特色菜 1 +x:1 +绢花 1 +x:1 +发射台 1 +x:1 +象形文字 1 +x:1 +十渡 1 +x:1 +风情园 1 +x:1 +燕头镇 1 +x:1 +小伙伴 1 +x:1 +竟陵 1 +x:1 +战袍 1 +x:1 +次序 1 +x:1 +贺喜 1 +x:1 +缓减 1 +x:1 +正常率 1 +x:1 +六盘山区 1 +x:1 +满湾 1 +x:1 +镇宫 1 +x:1 +脑科 1 +x:1 +廉洁勤政 1 +x:1 +后景 1 +x:1 +康定东路 1 +x:1 +缓冲 1 +x:1 +格日寺 1 +x:1 +一语双关 1 +x:1 +冰川 1 +x:1 +用途林 1 +x:1 +噬人鲨 1 +x:1 +载客 1 +x:1 +鼻化元音 1 +x:1 +上海港 1 +x:1 +昏昏欲睡 1 +x:1 +折椅 1 +x:1 +赤塔 1 +x:1 +开门见山 1 +x:1 +觞 1 +x:1 +后晌 1 +x:1 +欢送 1 +x:1 +太君 1 +x:1 +摩加迪沙 1 +x:1 +良 53 +x:53 +格陵兰 1 +x:1 +贫贱 1 +x:1 +访 617 +x:617 +阿拉斯加 1 +x:1 +虾洞村 1 +x:1 +耍花腔 1 +x:1 +东道国 1 +x:1 +历经沧桑 1 +x:1 +姑爷 1 +x:1 +姑父 1 +x:1 +承诺额 1 +x:1 +人生如梦 1 +x:1 +心高气傲 1 +x:1 +秀水河子 1 +x:1 +卫辉市 1 +x:1 +戚 53 +x:53 +后架 1 +x:1 +包装厂 1 +x:1 +查克 1 +x:1 +医术 1 +x:1 +顽者 1 +x:1 +最高点 1 +x:1 +电抗器 1 +x:1 +后果 1 +x:1 +房产处 1 +x:1 +为民除害 1 +x:1 +逗人 1 +x:1 +辞书 1 +x:1 +寒冬腊月 1 +x:1 +麻醉枪 1 +x:1 +读书节 1 +x:1 +只字不提 1 +x:1 +长远性 1 +x:1 +现钞 1 +x:1 +小营 1 +x:1 +流水处 1 +x:1 +辞世 1 +x:1 +冰层 1 +x:1 +乌拉尔州 1 +x:1 +外岗 1 +x:1 +次役 1 +x:1 +变幻莫测 1 +x:1 +劲风 1 +x:1 +空架子 1 +x:1 +建安风骨 1 +x:1 +古城 1 +x:1 +冰山 1 +x:1 +气虚 1 +x:1 +押金 1 +x:1 +错车 1 +x:1 +怨声载道 1 +x:1 +党总支 1 +x:1 +萨勃隆街 1 +x:1 +目不窥园 1 +x:1 +采莲歌 1 +x:1 +唏嗒唏嗒 1 +x:1 +战败者 1 +x:1 +交响乐队 1 +x:1 +鱼龙混杂 1 +x:1 +浑然 1 +x:1 +冰岛 1 +x:1 +香料厂 1 +x:1 +外屋 1 +x:1 +古圣 1 +x:1 +摘抄 1 +x:1 +神灵 1 +x:1 +根系 1 +x:1 +婚期 1 +x:1 +西路军 1 +x:1 +查出 1 +x:1 +放像厅 1 +x:1 +在逃犯 1 +x:1 +石寨铺乡 1 +x:1 +配送 1 +x:1 +中饱私囊 1 +x:1 +医托 1 +x:1 +传道授业 1 +x:1 +尼科西亚 1 +x:1 +小蓟 1 +x:1 +后期 1 +x:1 +内政部 1 +x:1 +辞令 1 +x:1 +举目望去 1 +x:1 +二道 1 +x:1 +舰体 1 +x:1 +绩效高者 1 +x:1 +麻醉术 1 +x:1 +中草药 1 +x:1 +一站式 1 +x:1 +燕山 1 +x:1 +标准箱 1 +x:1 +后来 1 +x:1 +错过 1 +x:1 +一走了之 1 +x:1 +戒除 1 +x:1 +现钱 1 +x:1 +空缺 1 +x:1 +逗乐 1 +x:1 +欢喜岭 1 +x:1 +灌包机 1 +x:1 +喊道 1 +x:1 +减色 1 +x:1 +乌恰乡 1 +x:1 +寄读费 1 +x:1 +内在化 1 +x:1 +冰峰 1 +x:1 +十五日 1 +x:1 +搞鬼 1 +x:1 +和顺县 1 +x:1 +刺目 1 +x:1 +石化队 1 +x:1 +保管 1 +x:1 +技艺 1 +x:1 +个位数 1 +x:1 +诉讼案 1 +x:1 +正比例 1 +x:1 +极 661 +x:661 +闸门 1 +x:1 +外心 1 +x:1 +悲喜 1 +x:1 +靖 17 +x:17 +后撤 1 +x:1 +死难 1 +x:1 +水洛镇 1 +x:1 +以西 1 +x:1 +开封 1 +x:1 +劫富济贫 1 +x:1 +清醒剂 1 +x:1 +自投罗网 1 +x:1 +二难 1 +x:1 +些 651 +x:651 +厩肥 1 +x:1 +电管员 1 +x:1 +八股 1 +x:1 +幻灯机 1 +x:1 +治蝗 1 +x:1 +错谬 1 +x:1 +外快 1 +x:1 +牛耕图 1 +x:1 +反面人物 1 +x:1 +野豌豆 1 +x:1 +天命 1 +x:1 +纵波 1 +x:1 +宜林 1 +x:1 +心绪 1 +x:1 +铁二院 1 +x:1 +猜谜 1 +x:1 +当代人 1 +x:1 +零本 1 +x:1 +戊寅 1 +x:1 +真品 1 +x:1 +另起炉灶 1 +x:1 +艺术学系 1 +x:1 +燥 1 +x:1 +不可理喻 1 +x:1 +宗祠 1 +x:1 +鼎篆 1 +x:1 +情面 1 +x:1 +阜康市 1 +x:1 +风油量 1 +x:1 +周记 1 +x:1 +进退守舍 1 +x:1 +不安全感 1 +x:1 +棋圣 1 +x:1 +月轮 1 +x:1 +溴化银 1 +x:1 +永兴镇 1 +x:1 +升官进爵 1 +x:1 +布兰卡 1 +x:1 +内藏式 1 +x:1 +和 72601 +x:72601 +真名 1 +x:1 +凯姆拉港 1 +x:1 +岸线 1 +x:1 +诊病 1 +x:1 +菠萝园 1 +x:1 +弥勒佛 1 +x:1 +南泥湾 1 +x:1 +茅塞顿开 1 +x:1 +外形 1 +x:1 +会晤站 1 +x:1 +追逐 1 +x:1 +水路 1 +x:1 +庚臣 1 +x:1 +风信子 1 +x:1 +查勘 1 +x:1 +如法炮制 1 +x:1 +循环圈 1 +x:1 +坛坛罐罐 1 +x:1 +奸邪 1 +x:1 +镇委 1 +x:1 +书海 1 +x:1 +入选国 1 +x:1 +阁下 1 +x:1 +蠢笨 1 +x:1 +预报表 1 +x:1 +陆川县 1 +x:1 +供品 1 +x:1 +花原头 1 +x:1 +外引 1 +x:1 +亚军 1 +x:1 +批复 1 +x:1 +昆山 1 +x:1 +犬吠 1 +x:1 +外弦 1 +x:1 +外弧 1 +x:1 +遭逢 1 +x:1 +真味 1 +x:1 +耳边风 1 +x:1 +鹤岗市 1 +x:1 +气藏 1 +x:1 +孤远 1 +x:1 +查办 1 +x:1 +棋坛 1 +x:1 +外强 1 +x:1 +誓言 1 +x:1 +湖西 1 +x:1 +大连市 1 +x:1 +账目单 1 +x:1 +柠檬素 1 +x:1 +村务公开 1 +x:1 +既是 1 +x:1 +刑法学家 1 +x:1 +鼐 1 +x:1 +血循环 1 +x:1 +外廓 1 +x:1 +搔首弄姿 1 +x:1 +誓语 1 +x:1 +春运办 1 +x:1 +琢 8 +x:8 +三十七分 1 +x:1 +凋残 1 +x:1 +鞭长莫及 1 +x:1 +蜜腺 1 +x:1 +我心 1 +x:1 +蘑菇 1 +x:1 +嫡孙 1 +x:1 +保票 1 +x:1 +如沐春风 1 +x:1 +切磋会 1 +x:1 +指甲钳 1 +x:1 +自下而上 1 +x:1 +昆州 1 +x:1 +打转转 1 +x:1 +悲哀 1 +x:1 +拙 4 +x:4 +愿望 1 +x:1 +带头羊 1 +x:1 +整妆 1 +x:1 +一番话 1 +x:1 +鼎立 1 +x:1 +书法 1 +x:1 +大清白日 1 +x:1 +缓刑 1 +x:1 +安然 1 +x:1 +再生父母 1 +x:1 +具体化 1 +x:1 +技能 1 +x:1 +坦露 1 +x:1 +孤身 1 +x:1 +江陵区 1 +x:1 +足金 1 +x:1 +非线性 1 +x:1 +遭遇 1 +x:1 +领路人 1 +x:1 +藏书量 1 +x:1 +汇率 1 +x:1 +校院 1 +x:1 +电热水壶 1 +x:1 +麻烦 1 +x:1 +响当当 1 +x:1 +冰床 1 +x:1 +掘 16 +x:16 +金子山 1 +x:1 +内罗毕 1 +x:1 +陕西团 1 +x:1 +引狼入室 1 +x:1 +学海无涯 1 +x:1 +标准科 1 +x:1 +绝对性 1 +x:1 +政法委 1 +x:1 +日积月累 1 +x:1 +根绝 1 +x:1 +两户一企 1 +x:1 +忧难 1 +x:1 +涿州 1 +x:1 +壮志未酬 1 +x:1 +山药蛋 1 +x:1 +夜夜 1 +x:1 +鳖精 1 +x:1 +有用之才 1 +x:1 +看守费 1 +x:1 +外市 1 +x:1 +读书者 1 +x:1 +校部 1 +x:1 +营销点 1 +x:1 +有益无害 1 +x:1 +表面层 1 +x:1 +撞击声 1 +x:1 +死面 1 +x:1 +演唱家 1 +x:1 +号音 1 +x:1 +太冲 1 +x:1 +甘心情愿 1 +x:1 +雷阵雨 1 +x:1 +外带 1 +x:1 +规划数 1 +x:1 +永往直前 1 +x:1 +文安县 1 +x:1 +遮障 1 +x:1 +煞车 1 +x:1 +归侨界 1 +x:1 +十一届 1 +x:1 +摄政官 1 +x:1 +唐宁街 1 +x:1 +二踢脚 1 +x:1 +票制 1 +x:1 +艾滋病毒 1 +x:1 +好气儿 1 +x:1 +履任 1 +x:1 +多糖 1 +x:1 +咸水歌 1 +x:1 +攻关战 1 +x:1 +亚当 1 +x:1 +驻守 1 +x:1 +焦 69 +x:69 +后援 1 +x:1 +不寒而栗 1 +x:1 +举世瞩目 1 +x:1 +不欢而散 1 +x:1 +空箱 1 +x:1 +腼腆 1 +x:1 +筛选机 1 +x:1 +酒池肉林 1 +x:1 +坐视 1 +x:1 +好言 1 +x:1 +垂直面 1 +x:1 +外出 1 +x:1 +优化 1 +x:1 +达特茅思 1 +x:1 +桀 1 +x:1 +楼头 1 +x:1 +防弹服 1 +x:1 +幼龄林 1 +x:1 +啤酒花 1 +x:1 +老虎皮 1 +x:1 +饶平县 1 +x:1 +做活儿 1 +x:1 +烈军属 1 +x:1 +双庙乡 1 +x:1 +近照 1 +x:1 +校际 1 +x:1 +佚 1 +x:1 +果子盐 1 +x:1 +猕猴桃 1 +x:1 +共和国 1 +x:1 +宛城区 1 +x:1 +争先 1 +x:1 +无可挽回 1 +x:1 +配送业 1 +x:1 +语 101 +x:101 +离间计 1 +x:1 +介词 1 +x:1 +运输诗 1 +x:1 +竞驰 1 +x:1 +意大利 1 +x:1 +程途 1 +x:1 +一泻而下 1 +x:1 +还贷率 1 +x:1 +份量 1 +x:1 +啤酒节 1 +x:1 +小者 1 +x:1 +岸炮 1 +x:1 +狮城 1 +x:1 +新景点 1 +x:1 +依存度 1 +x:1 +保盟 1 +x:1 +滏临庄 1 +x:1 +这时候 1 +x:1 +中断 1 +x:1 +石材厂 1 +x:1 +表面化 1 +x:1 +冰冰 1 +x:1 +经科委 1 +x:1 +弥 13 +x:13 +冰冷 1 +x:1 +夜大 1 +x:1 +冰冻 1 +x:1 +醒悟 1 +x:1 +外公 1 +x:1 +架子工 1 +x:1 +受教育者 1 +x:1 +鱼贯而入 1 +x:1 +法卢斯村 1 +x:1 +小觑 1 +x:1 +印色 1 +x:1 +自选市场 1 +x:1 +浮价款 1 +x:1 +日夜操劳 1 +x:1 +阑尾 1 +x:1 +辐射量 1 +x:1 +减轻 1 +x:1 +冰凉 1 +x:1 +晟 6 +x:6 +科幻画 1 +x:1 +气话 1 +x:1 +渔业部 1 +x:1 +哨 19 +x:19 +门诊费 1 +x:1 +骚客 1 +x:1 +积雨云 1 +x:1 +其成 1 +x:1 +效用 1 +x:1 +隐者 1 +x:1 +仪表盘 1 +x:1 +昆剧 1 +x:1 +时不时 1 +x:1 +西甜瓜 1 +x:1 +黎寨 1 +x:1 +真实 1 +x:1 +棒球队 1 +x:1 +身手 1 +x:1 +电热水器 1 +x:1 +西兰花 1 +x:1 +张金镇 1 +x:1 +净摊款国 1 +x:1 +横纹肌 1 +x:1 +芝 1 +x:1 +院方 1 +x:1 +雌老虎 1 +x:1 +真容 1 +x:1 +巴西节 1 +x:1 +假公济私 1 +x:1 +瘪 8 +x:8 +清华园 1 +x:1 +碧空 1 +x:1 +孤老 1 +x:1 +折桂 1 +x:1 +在朝党 1 +x:1 +安置 1 +x:1 +小街 1 +x:1 +风平浪静 1 +x:1 +家务事 1 +x:1 +保真 1 +x:1 +填筑量 1 +x:1 +人类史 1 +x:1 +机务 1 +x:1 +美联储 1 +x:1 +一石多鸟 1 +x:1 +八运 1 +x:1 +古寺 1 +x:1 +万古常青 1 +x:1 +错荐 1 +x:1 +八连 1 +x:1 +护理院 1 +x:1 +后母 1 +x:1 +用电权 1 +x:1 +我军 1 +x:1 +购票款 1 +x:1 +当权者 1 +x:1 +悲切 1 +x:1 +具结 1 +x:1 +刑诉法 1 +x:1 +打打停停 1 +x:1 +瑾 15 +x:15 +麻绳 1 +x:1 +指 591 +x:591 +障人眼目 1 +x:1 +忏悔书 1 +x:1 +书房 1 +x:1 +导购员 1 +x:1 +破门而入 1 +x:1 +不分伯仲 1 +x:1 +劳役 1 +x:1 +挂一漏万 1 +x:1 +再生之恩 1 +x:1 +平湖一镜 1 +x:1 +分界线 1 +x:1 +野狐禅 1 +x:1 +侄儿女 1 +x:1 +昆区 1 +x:1 +我党 1 +x:1 +柠檬王 1 +x:1 +极目四顾 1 +x:1 +为时已晚 1 +x:1 +无辜者 1 +x:1 +建设部长 1 +x:1 +麻织 1 +x:1 +治装 1 +x:1 +奉献日 1 +x:1 +注销 1 +x:1 +华夏鳗 1 +x:1 +试验车 1 +x:1 +好说 1 +x:1 +麻纱 1 +x:1 +计入 1 +x:1 +麻纺 1 +x:1 +票台 1 +x:1 +白癜风 1 +x:1 +后步 1 +x:1 +演播稿 1 +x:1 +矿物纤维 1 +x:1 +竹茹 1 +x:1 +询价 1 +x:1 +秦川牛 1 +x:1 +太太 1 +x:1 +将口镇 1 +x:1 +淹 36 +x:36 +有所不同 1 +x:1 +中试部 1 +x:1 +集热管 1 +x:1 +忤 1 +x:1 +枪膛 1 +x:1 +孤胆 1 +x:1 +办案权 1 +x:1 +干堤 1 +x:1 +正月初七 1 +x:1 +好评 1 +x:1 +世锦赛 1 +x:1 +化学会 1 +x:1 +蒋家堰 1 +x:1 +古字 1 +x:1 +外债 1 +x:1 +溜皮树 1 +x:1 +凋敝 1 +x:1 +责人者 1 +x:1 +抠门 1 +x:1 +走者 1 +x:1 +评介 1 +x:1 +治警 1 +x:1 +花生酱 1 +x:1 +纵情 1 +x:1 +承租人 1 +x:1 +黧黑 1 +x:1 +冰区 1 +x:1 +读书路 1 +x:1 +后引法 1 +x:1 +速记 1 +x:1 +外史 1 +x:1 +一技之长 1 +x:1 +大道理 1 +x:1 +坐诊 1 +x:1 +常 683 +x:683 +古墓 1 +x:1 +计办 1 +x:1 +空炮 1 +x:1 +不可企及 1 +x:1 +深情厚谊 1 +x:1 +申请表 1 +x:1 +塞纳河畔 1 +x:1 +吨/年 1 +x:1 +纯收入 1 +x:1 +滚瓜流油 1 +x:1 +证明 1 +x:1 +冰协 1 +x:1 +引水人 1 +x:1 +奢 14 +x:14 +防化学 1 +x:1 +多级 1 +x:1 +父老乡亲 1 +x:1 +贵耳贱目 1 +x:1 +新泽西 1 +x:1 +改扩建 1 +x:1 +彩墨画 1 +x:1 +阑干 1 +x:1 +大公无私 1 +x:1 +走调儿 1 +x:1 +书橱 1 +x:1 +多口相声 1 +x:1 +古堡 1 +x:1 +炮战 1 +x:1 +惊心掉胆 1 +x:1 +消力塘 1 +x:1 +吃得开 1 +x:1 +缴费人 1 +x:1 +液化气 1 +x:1 +空灵 1 +x:1 +越级 1 +x:1 +小说 1 +x:1 +龛 3 +x:3 +外卡 1 +x:1 +鸣 86 +x:86 +裁撤 1 +x:1 +民主国 1 +x:1 +计分 1 +x:1 +采茶调 1 +x:1 +漆画 1 +x:1 +自由泳 1 +x:1 +减负 1 +x:1 +没法子 1 +x:1 +计划 1 +x:1 +白头鹰 1 +x:1 +费加罗 1 +x:1 +小议 1 +x:1 +炮手 1 +x:1 +外包 1 +x:1 +邀兑 1 +x:1 +一举三得 1 +x:1 +医派 1 +x:1 +布达佩斯 1 +x:1 +吉祥物 1 +x:1 +外化 1 +x:1 +穿天杨 1 +x:1 +方正县 1 +x:1 +干部团 1 +x:1 +小记 1 +x:1 +冰台 1 +x:1 +方解石 1 +x:1 +减资 1 +x:1 +致引起 1 +x:1 +楼宇 1 +x:1 +领航员 1 +x:1 +日资 1 +x:1 +缓征 1 +x:1 +钢骨水泥 1 +x:1 +汇编 1 +x:1 +退票费 1 +x:1 +沅 2 +x:2 +奶茶 1 +x:1 +保畜 1 +x:1 +揉搓 1 +x:1 +邮票史 1 +x:1 +保留 1 +x:1 +效益 1 +x:1 +援藏 1 +x:1 +冰刀 1 +x:1 +倒 358 +x:358 +修车 1 +x:1 +生辰 1 +x:1 +兑付期 1 +x:1 +灌装线 1 +x:1 +纱 17 +x:17 +汇缴 1 +x:1 +外勤 1 +x:1 +贫苦 1 +x:1 +年深日久 1 +x:1 +钻孔 1 +x:1 +调节税 1 +x:1 +拾遗 1 +x:1 +孤舟 1 +x:1 +湖北省籍 1 +x:1 +放水沟 1 +x:1 +基希讷乌 1 +x:1 +捐资助学 1 +x:1 +小道理 1 +x:1 +身怀 1 +x:1 +沙埠镇 1 +x:1 +三四月份 1 +x:1 +医治 1 +x:1 +海事局 1 +x:1 +呼吸与共 1 +x:1 +电算化 1 +x:1 +我县 1 +x:1 +委派 1 +x:1 +多用 1 +x:1 +供奉 1 +x:1 +外力 1 +x:1 +外办 1 +x:1 +外功 1 +x:1 +外加 1 +x:1 +外务 1 +x:1 +轻声细语 1 +x:1 +保甲 1 +x:1 +八路 1 +x:1 +自虐史观 1 +x:1 +计发 1 +x:1 +不列颠 1 +x:1 +太守 1 +x:1 +究 46 +x:46 +包装工 1 +x:1 +悲壮 1 +x:1 +真丝绸 1 +x:1 +成教处 1 +x:1 +气血 1 +x:1 +外势 1 +x:1 +否定论 1 +x:1 +养鸡户 1 +x:1 +院本 1 +x:1 +年深月久 1 +x:1 +养鸡房 1 +x:1 +折扇 1 +x:1 +死鬼 1 +x:1 +歼灭战 1 +x:1 +三点水 1 +x:1 +租税 1 +x:1 +有法必依 1 +x:1 +房补 1 +x:1 +许西 1 +x:1 +逻辑学 1 +x:1 +麻糖 1 +x:1 +折扣 1 +x:1 +绥化市 1 +x:1 +金顶 1 +x:1 +裁断 1 +x:1 +正北街 1 +x:1 +印子钱 1 +x:1 +够本 1 +x:1 +东阳市 1 +x:1 +家庭设备 1 +x:1 +抱头大哭 1 +x:1 +趋势性 1 +x:1 +大杂院 1 +x:1 +编者 1 +x:1 +招待券 1 +x:1 +孤苦 1 +x:1 +外刊 1 +x:1 +古奥 1 +x:1 +翩翩飞舞 1 +x:1 +民主型 1 +x:1 +新堡市 1 +x:1 +文教部 1 +x:1 +地球村 1 +x:1 +身患 1 +x:1 +宣武籍 1 +x:1 +琼枝玉叶 1 +x:1 +统计局长 1 +x:1 +护林站 1 +x:1 +疑难案 1 +x:1 +交易网 1 +x:1 +消防法 1 +x:1 +泥水匠 1 +x:1 +河阳镇 1 +x:1 +四合院儿 1 +x:1 +忧闷 1 +x:1 +后溪 1 +x:1 +公布于世 1 +x:1 +排洪道 1 +x:1 +减让 1 +x:1 +电弧焊接 1 +x:1 +民心向背 1 +x:1 +大人 1 +x:1 +踏板 1 +x:1 +身材 1 +x:1 +灭火筒 1 +x:1 +调查队 1 +x:1 +无缘无故 1 +x:1 +镜框费 1 +x:1 +庞各庄 1 +x:1 +巡捕房 1 +x:1 +大亨 1 +x:1 +祠堂 1 +x:1 +新疆棉 1 +x:1 +身条 1 +x:1 +B 222 +x:222 +进价 1 +x:1 +油葫芦 1 +x:1 +书林 1 +x:1 +非僧非俗 1 +x:1 +山鸡椒 1 +x:1 +折旧 1 +x:1 +新化县 1 +x:1 +披金戴银 1 +x:1 +古庙 1 +x:1 +江海堤防 1 +x:1 +大于 1 +x:1 +西藏路 1 +x:1 +类型化 1 +x:1 +大事 1 +x:1 +空盒 1 +x:1 +恭贺 1 +x:1 +大件 1 +x:1 +撒手不管 1 +x:1 +导购册 1 +x:1 +小贩 1 +x:1 +动力 1 +x:1 +补交 1 +x:1 +晨练者 1 +x:1 +大任 1 +x:1 +揣 35 +x:35 +近畿 1 +x:1 +太岳 1 +x:1 +盗窃者 1 +x:1 +小费 1 +x:1 +查堵 1 +x:1 +自然主义 1 +x:1 +火炬办 1 +x:1 +零活 1 +x:1 +周期表 1 +x:1 +堤坝 1 +x:1 +补亏 1 +x:1 +校魂 1 +x:1 +运气 1 +x:1 +白体 1 +x:1 +通川 1 +x:1 +安稳 1 +x:1 +答卷者 1 +x:1 +书柜 1 +x:1 +苕子 1 +x:1 +重残人 1 +x:1 +大仇 1 +x:1 +假惺惺 1 +x:1 +廷 4 +x:4 +欢颜 1 +x:1 +太岁 1 +x:1 +小路 1 +x:1 +外商 1 +x:1 +供应 1 +x:1 +镇原 1 +x:1 +大举 1 +x:1 +补习 1 +x:1 +让利 1 +x:1 +空白 1 +x:1 +养鸡 1 +x:1 +稍事 1 +x:1 +橙子 1 +x:1 +大中 1 +x:1 +黎平 1 +x:1 +书本 1 +x:1 +大个 1 +x:1 +南京东路 1 +x:1 +霍普镇 1 +x:1 +龙舟队 1 +x:1 +劈脸 1 +x:1 +大专 1 +x:1 +总工会 1 +x:1 +共和制 1 +x:1 +大东 1 +x:1 +大业 1 +x:1 +古币 1 +x:1 +祠墓 1 +x:1 +大一 1 +x:1 +集火 1 +x:1 +可再生性 1 +x:1 +兴衰史 1 +x:1 +作手脚 1 +x:1 +职责 1 +x:1 +劳而无功 1 +x:1 +治荒 1 +x:1 +砾石 1 +x:1 +草马湖村 1 +x:1 +登科录 1 +x:1 +标定 1 +x:1 +揉揉 1 +x:1 +小趾 1 +x:1 +贤人 1 +x:1 +配饰 1 +x:1 +刘马家 1 +x:1 +镇反 1 +x:1 +经常性 1 +x:1 +我向 1 +x:1 +赶到 1 +x:1 +补丁 1 +x:1 +气运 1 +x:1 +青龙乡 1 +x:1 +白俄 1 +x:1 +新闻网 1 +x:1 +名菜馆 1 +x:1 +居危治危 1 +x:1 +马铃薯 1 +x:1 +大义 1 +x:1 +谦称 1 +x:1 +多种 1 +x:1 +公布于众 1 +x:1 +区公所 1 +x:1 +大便 1 +x:1 +暗地里 1 +x:1 +招投标制 1 +x:1 +简化字 1 +x:1 +大侠 1 +x:1 +江山市 1 +x:1 +共和县 1 +x:1 +创汇率 1 +x:1 +白专 1 +x:1 +小豆 1 +x:1 +锅边糊 1 +x:1 +古往 1 +x:1 +拙见 1 +x:1 +肺活量 1 +x:1 +白丁 1 +x:1 +配额 1 +x:1 +周一 1 +x:1 +赤忱 1 +x:1 +允许值 1 +x:1 +进修 1 +x:1 +用人费率 1 +x:1 +加挂 1 +x:1 +兴头 1 +x:1 +灶马 1 +x:1 +踏春 1 +x:1 +雨滴 1 +x:1 +炮旅 1 +x:1 +自诉人 1 +x:1 +财政部长 1 +x:1 +耍贫嘴 1 +x:1 +双孢菇 1 +x:1 +相对性 1 +x:1 +大修 1 +x:1 +角斗场 1 +x:1 +真心 1 +x:1 +今年初 1 +x:1 +蜂巢 1 +x:1 +查处 1 +x:1 +小调 1 +x:1 +十一大 1 +x:1 +瞬变码型 1 +x:1 +校长学 1 +x:1 +闯祸 1 +x:1 +货币主义 1 +x:1 +古志 1 +x:1 +汤尤杯赛 1 +x:1 +其枝 1 +x:1 +汇票 1 +x:1 +福荫 1 +x:1 +征询卡 1 +x:1 +十月 1 +x:1 +百灵 1 +x:1 +刘砦镇 1 +x:1 +白人 1 +x:1 +荤油 1 +x:1 +大伯 1 +x:1 +起解 1 +x:1 +借阅 1 +x:1 +大众 1 +x:1 +古式 1 +x:1 +白云 1 +x:1 +摩洛哥 1 +x:1 +招待员 1 +x:1 +立体图 1 +x:1 +大会 1 +x:1 +大伙 1 +x:1 +副科级 1 +x:1 +范文 1 +x:1 +货运站 1 +x:1 +周二 1 +x:1 +辰溪 1 +x:1 +势必 1 +x:1 +溴化锂 1 +x:1 +医方 1 +x:1 +白事 1 +x:1 +气躁 1 +x:1 +滂 1 +x:1 +煎熬 1 +x:1 +大使 1 +x:1 +楼区 1 +x:1 +白令 1 +x:1 +岩石圈 1 +x:1 +漆片 1 +x:1 +周代 1 +x:1 +燃料部 1 +x:1 +越城岭 1 +x:1 +创收奖 1 +x:1 +农历 1 +x:1 +棋局 1 +x:1 +大体 1 +x:1 +好运 1 +x:1 +大佐 1 +x:1 +赫 5 +x:5 +大作 1 +x:1 +大佛 1 +x:1 +大余 1 +x:1 +多礼 1 +x:1 +好过 1 +x:1 +援 54 +x:54 +玻璃钢 1 +x:1 +红星村 1 +x:1 +瘦瘦的 1 +x:1 +瓦拉纳西 1 +x:1 +修整费 1 +x:1 +身故 1 +x:1 +小车 1 +x:1 +中下旬 1 +x:1 +风云人物 1 +x:1 +海事处 1 +x:1 +凸出 1 +x:1 +徇情 1 +x:1 +凸凹 1 +x:1 +读书角 1 +x:1 +气质 1 +x:1 +身教 1 +x:1 +后河 1 +x:1 +迄今为止 1 +x:1 +外域 1 +x:1 +外埠 1 +x:1 +缓存 1 +x:1 +格陵兰岛 1 +x:1 +嫩江 1 +x:1 +草木 1 +x:1 +冰场 1 +x:1 +理财机 1 +x:1 +什物 1 +x:1 +多年生 1 +x:1 +候车站 1 +x:1 +穹丘 1 +x:1 +错落 1 +x:1 +激光灯 1 +x:1 +导购台 1 +x:1 +电管局 1 +x:1 +拉下马 1 +x:1 +假仁假义 1 +x:1 +通布岛 1 +x:1 +武侠迷 1 +x:1 +博览 1 +x:1 +冰块 1 +x:1 +猪肝 1 +x:1 +扈 13 +x:13 +太康 1 +x:1 +规划法 1 +x:1 +飞人赛 1 +x:1 +集纳 1 +x:1 +导航连 1 +x:1 +套餐 1 +x:1 +趣味 1 +x:1 +效率 1 +x:1 +自由区 1 +x:1 +固阳 1 +x:1 +盈尺 1 +x:1 +二黄 1 +x:1 +苦事 1 +x:1 +养鳗 1 +x:1 +太庙 1 +x:1 +舌剑唇枪 1 +x:1 +景泰蓝 1 +x:1 +亚大 1 +x:1 +猴拳 1 +x:1 +抽取量 1 +x:1 +邮票展 1 +x:1 +抒情曲 1 +x:1 +敲 99 +x:99 +天花乱坠 1 +x:1 +势将 1 +x:1 +冰坨 1 +x:1 +拾遗补阙 1 +x:1 +泄露 1 +x:1 +辐射面 1 +x:1 +旱路 1 +x:1 +责难 1 +x:1 +干瘪 1 +x:1 +身旁 1 +x:1 +高花乡 1 +x:1 +拾闲 1 +x:1 +介质 1 +x:1 +宁绍 1 +x:1 +岌 1 +x:1 +太平 1 +x:1 +十里铺村 1 +x:1 +猴戏 1 +x:1 +老虎灶 1 +x:1 +坐车 1 +x:1 +总局 1 +x:1 +古尸 1 +x:1 +缺阵 1 +x:1 +憬悟 1 +x:1 +以至 1 +x:1 +业余队 1 +x:1 +皮家营村 1 +x:1 +欲先取之 1 +x:1 +死鸟 1 +x:1 +压低 1 +x:1 +银白 1 +x:1 +交易税 1 +x:1 +同心协力 1 +x:1 +近瞅 1 +x:1 +晋州市 1 +x:1 +猪肉 1 +x:1 +克尽职守 1 +x:1 +房费 1 +x:1 +折服 1 +x:1 +外圈 1 +x:1 +养鱼 1 +x:1 +输送机 1 +x:1 +汗 79 +x:79 +冰城 1 +x:1 +古山 1 +x:1 +次品 1 +x:1 +后汉 1 +x:1 +服理 1 +x:1 +霍尔果斯 1 +x:1 +古屋 1 +x:1 +小辈 1 +x:1 +外在 1 +x:1 +阳谷 1 +x:1 +预断 1 +x:1 +外地 1 +x:1 +曰 79 +x:79 +增压 1 +x:1 +执法必严 1 +x:1 +浑穆 1 +x:1 +外场 1 +x:1 +主持人 1 +x:1 +八要 1 +x:1 +并立 1 +x:1 +共和军 1 +x:1 +安神 1 +x:1 +基础 1 +x:1 +迎宾曲 1 +x:1 +碰撞性 1 +x:1 +炕 19 +x:19 +其时 1 +x:1 +此价 1 +x:1 +深受其害 1 +x:1 +利润税 1 +x:1 +醒木 1 +x:1 +标准煤 1 +x:1 +外因 1 +x:1 +管扳子 1 +x:1 +写字楼区 1 +x:1 +喧 4 +x:4 +弥漫性 1 +x:1 +乒坛 1 +x:1 +发射塔 1 +x:1 +外围 1 +x:1 +翻天覆地 1 +x:1 +纰缪 1 +x:1 +外国 1 +x:1 +普件 1 +x:1 +途程 1 +x:1 +让出 1 +x:1 +压产 1 +x:1 +好走 1 +x:1 +裹足不前 1 +x:1 +矿泉水瓶 1 +x:1 +遂意 1 +x:1 +根瘤 1 +x:1 +八角 1 +x:1 +滑溜溜 1 +x:1 +贺年 1 +x:1 +防总办 1 +x:1 +新闻纸 1 +x:1 +气象 1 +x:1 +人所共知 1 +x:1 +好赖 1 +x:1 +十日 1 +x:1 +满陇桂雨 1 +x:1 +坐等式 1 +x:1 +归根结底 1 +x:1 +冷食品 1 +x:1 +凑趣 1 +x:1 +减裁 1 +x:1 +楼市 1 +x:1 +非遗传性 1 +x:1 +贺幛 1 +x:1 +钢铁量 1 +x:1 +遂愿 1 +x:1 +反函数 1 +x:1 +汇算 1 +x:1 +嗜好 1 +x:1 +芦柴 1 +x:1 +布木格村 1 +x:1 +蠢物 1 +x:1 +来者不拒 1 +x:1 +查对 1 +x:1 +差距 1 +x:1 +查寻 1 +x:1 +编著 1 +x:1 +白天鹅 1 +x:1 +各洲 1 +x:1 +辰河 1 +x:1 +少不更事 1 +x:1 +九二年 1 +x:1 +半成品 1 +x:1 +圆桌会议 1 +x:1 +曼妙 1 +x:1 +坐药 1 +x:1 +昱 2 +x:2 +主任委员 1 +x:1 +医案 1 +x:1 +楼廊 1 +x:1 +刷牙 1 +x:1 +干部司 1 +x:1 +分列式 1 +x:1 +共和党 1 +x:1 +惊 72 +x:72 +服用 1 +x:1 +摇摇摆摆 1 +x:1 +护理部 1 +x:1 +安福 1 +x:1 +岸石 1 +x:1 +销烟 1 +x:1 +卸掉 1 +x:1 +贫水国 1 +x:1 +山樱桃 1 +x:1 +处置权 1 +x:1 +书摘 1 +x:1 +消委会 1 +x:1 +旱象 1 +x:1 +查实 1 +x:1 +驸马巷 1 +x:1 +书摊 1 +x:1 +自由民 1 +x:1 +书箱 1 +x:1 +新密市 1 +x:1 +沪宁线 1 +x:1 +大势 1 +x:1 +燃料费 1 +x:1 +殖 1 +x:1 +舌 4 +x:4 +白区 1 +x:1 +非正常 1 +x:1 +既然 1 +x:1 +溧水 1 +x:1 +神父 1 +x:1 +镇企 1 +x:1 +大加 1 +x:1 +稽 2 +x:2 +白匪 1 +x:1 +上海站 1 +x:1 +白化 1 +x:1 +生态学家 1 +x:1 +朔州市 1 +x:1 +大功 1 +x:1 +大办 1 +x:1 +大力 1 +x:1 +岸标 1 +x:1 +设若 1 +x:1 +西山街 1 +x:1 +小菜 1 +x:1 +迎春会 1 +x:1 +斯宁根 1 +x:1 +合 282 +x:282 +指代 1 +x:1 +牛倌 1 +x:1 +潮州市 1 +x:1 +倾倒区 1 +x:1 +白卷 1 +x:1 +补助 1 +x:1 +二胡 1 +x:1 +人字形 1 +x:1 +缉毒署 1 +x:1 +籼稻 1 +x:1 +截断 1 +x:1 +镇住 1 +x:1 +坚 27 +x:27 +知己者 1 +x:1 +二重性 1 +x:1 +冷柜 1 +x:1 +根植 1 +x:1 +检字表 1 +x:1 +混混沌沌 1 +x:1 +竿子 1 +x:1 +糨糊 1 +x:1 +补办 1 +x:1 +南川县 1 +x:1 +文史界 1 +x:1 +金钱松 1 +x:1 +保温 1 +x:1 +灭火机 1 +x:1 +轻音乐 1 +x:1 +出人意料 1 +x:1 +腰椎间盘 1 +x:1 +杂文选 1 +x:1 +广听博纳 1 +x:1 +圣马力诺 1 +x:1 +青龙刀 1 +x:1 +后爹 1 +x:1 +五 2471 +x:2471 +大别 1 +x:1 +萤石 1 +x:1 +纵穿 1 +x:1 +二者 1 +x:1 +安曼 1 +x:1 +大刑 1 +x:1 +二老 1 +x:1 +减震 1 +x:1 +守株待兔 1 +x:1 +定计 1 +x:1 +具有 1 +x:1 +白厅 1 +x:1 +最新 1 +x:1 +经营部 1 +x:1 +曾孙女儿 1 +x:1 +死者 1 +x:1 +大刀 1 +x:1 +待援 1 +x:1 +瘦削 1 +x:1 +琐碎 1 +x:1 +古龙乡 1 +x:1 +台湾籍 1 +x:1 +供应者 1 +x:1 +截收 1 +x:1 +书签 1 +x:1 +刁民 1 +x:1 +教育型 1 +x:1 +火箭筒 1 +x:1 +白口 1 +x:1 +大副 1 +x:1 +周口 1 +x:1 +其稿 1 +x:1 +服用量 1 +x:1 +热电偶 1 +x:1 +白发 1 +x:1 +物理科 1 +x:1 +看待 1 +x:1 +标准源 1 +x:1 +米行街 1 +x:1 +侵权性 1 +x:1 +廉政办 1 +x:1 +加查县 1 +x:1 +情致 1 +x:1 +长寿县 1 +x:1 +蹿 10 +x:10 +进发 1 +x:1 +调节性 1 +x:1 +精通 1 +x:1 +蛛蛛 1 +x:1 +中石化 1 +x:1 +周到 1 +x:1 +分布图 1 +x:1 +后八里庄 1 +x:1 +大厦 1 +x:1 +废寝忘食 1 +x:1 +小说性 1 +x:1 +裁缝 1 +x:1 +补台 1 +x:1 +天都峰 1 +x:1 +折磨 1 +x:1 +非正式 1 +x:1 +多日 1 +x:1 +一次性 1 +x:1 +号脉 1 +x:1 +小百货 1 +x:1 +幻境 1 +x:1 +百泉 1 +x:1 +大厅 1 +x:1 +弃文就武 1 +x:1 +大厂 1 +x:1 +服毒 1 +x:1 +剧协 1 +x:1 +能动性 1 +x:1 +多时 1 +x:1 +爪哇 1 +x:1 +补发 1 +x:1 +大号 1 +x:1 +计算连 1 +x:1 +专业乡 1 +x:1 +弹性模量 1 +x:1 +蛟龙 1 +x:1 +指甲花 1 +x:1 +博雅 1 +x:1 +墨梅图 1 +x:1 +急需者 1 +x:1 +太行山麓 1 +x:1 +步骑炮兵 1 +x:1 +根根 1 +x:1 +白剧 1 +x:1 +戟立 1 +x:1 +待战 1 +x:1 +长短枪 1 +x:1 +交易日 1 +x:1 +碍于情面 1 +x:1 +属 441 +x:441 +大叔 1 +x:1 +刃量具 1 +x:1 +进去 1 +x:1 +韵致 1 +x:1 +间断 1 +x:1 +霓虹灯 1 +x:1 +促进会 1 +x:1 +摘登 1 +x:1 +筒子院 1 +x:1 +缅方 1 +x:1 +多方 1 +x:1 +舞蹈界 1 +x:1 +书立 1 +x:1 +宁愿 1 +x:1 +外来户 1 +x:1 +韵脚 1 +x:1 +大区 1 +x:1 +书稿 1 +x:1 +好奇心 1 +x:1 +并蒂莲 1 +x:1 +雁同东路 1 +x:1 +棉红铃虫 1 +x:1 +对比度 1 +x:1 +亮堂堂 1 +x:1 +大年夜 1 +x:1 +速送 1 +x:1 +猿人 1 +x:1 +大化 1 +x:1 +弹道式 1 +x:1 +顽钝 1 +x:1 +原酒 1 +x:1 +剧变 1 +x:1 +标准粉 1 +x:1 +阴雨雪 1 +x:1 +丙种射线 1 +x:1 +多数 1 +x:1 +回心转意 1 +x:1 +一字之差 1 +x:1 +八里庄 1 +x:1 +荣耀人 1 +x:1 +撞车 1 +x:1 +进化 1 +x:1 +大印 1 +x:1 +农牧民 1 +x:1 +野战军 1 +x:1 +防盗网 1 +x:1 +化学场 1 +x:1 +大卡 1 +x:1 +需氧量 1 +x:1 +零点 1 +x:1 +祛 7 +x:7 +北洞山 1 +x:1 +韵腹 1 +x:1 +长短期 1 +x:1 +舞蹈病 1 +x:1 +压倒 1 +x:1 +让位 1 +x:1 +大半 1 +x:1 +兴山区 1 +x:1 +养育 1 +x:1 +普及 1 +x:1 +护理费 1 +x:1 +外嫁 1 +x:1 +城建费 1 +x:1 +公益性 1 +x:1 +刁滑 1 +x:1 +孤鬼 1 +x:1 +当政 1 +x:1 +集训队 1 +x:1 +科教兴国 1 +x:1 +最末 1 +x:1 +差遣 1 +x:1 +化学品 1 +x:1 +西扬庄村 1 +x:1 +马斯河 1 +x:1 +小球藻 1 +x:1 +绿条 1 +x:1 +宗派 1 +x:1 +民主乡 1 +x:1 +镞 1 +x:1 +梅花山站 1 +x:1 +虹膜 1 +x:1 +众志成城 1 +x:1 +勤勤恳恳 1 +x:1 +白关 1 +x:1 +发生量 1 +x:1 +红五星 1 +x:1 +周全 1 +x:1 +周六 1 +x:1 +气酣 1 +x:1 +茁实 1 +x:1 +白兔 1 +x:1 +天兴里 1 +x:1 +蓖麻 1 +x:1 +医疗 1 +x:1 +百般无奈 1 +x:1 +蒲柳 1 +x:1 +孤魂 1 +x:1 +柠檬桉 1 +x:1 +调查表 1 +x:1 +语言部 1 +x:1 +锣鼓喧天 1 +x:1 +南村镇 1 +x:1 +甚至于 1 +x:1 +书种 1 +x:1 +笑影 1 +x:1 +铜模 1 +x:1 +端午节 1 +x:1 +空档 1 +x:1 +挂果 1 +x:1 +补偿 1 +x:1 +满坑满谷 1 +x:1 +老大爷 1 +x:1 +东陵区 1 +x:1 +验证台 1 +x:1 +沙河口区 1 +x:1 +筵席税 1 +x:1 +浅陋 1 +x:1 +贴水 1 +x:1 +天王殿 1 +x:1 +党小组长 1 +x:1 +石门县 1 +x:1 +根毛 1 +x:1 +油棕榈 1 +x:1 +新界埠乡 1 +x:1 +无遮无挡 1 +x:1 +空置房 1 +x:1 +如是者 1 +x:1 +辐射计 1 +x:1 +医界 1 +x:1 +慢慢 1 +x:1 +篆 2 +x:2 +先锋号 1 +x:1 +空格 1 +x:1 +油料处 1 +x:1 +港人制港 1 +x:1 +嫡亲 1 +x:1 +栋梁之材 1 +x:1 +臭乎乎 1 +x:1 +医用 1 +x:1 +普化 1 +x:1 +桧 1 +x:1 +详 7 +x:7 +医生 1 +x:1 +内忧外患 1 +x:1 +扼 4 +x:4 +气量 1 +x:1 +普区 1 +x:1 +石门口 1 +x:1 +白净 1 +x:1 +抓耳挠腮 1 +x:1 +购票点 1 +x:1 +米山镇 1 +x:1 +幸得 1 +x:1 +集港 1 +x:1 +大冶 1 +x:1 +拖布 1 +x:1 +老外 1 +x:1 +冗 1 +x:1 +热电厂 1 +x:1 +廉政关 1 +x:1 +净水剂 1 +x:1 +床头柜 1 +x:1 +干部会 1 +x:1 +蝶翅 1 +x:1 +拖带 1 +x:1 +哨所里 1 +x:1 +进击 1 +x:1 +进出 1 +x:1 +浮价烟 1 +x:1 +大军 1 +x:1 +编导演 1 +x:1 +大写 1 +x:1 +幅宽 1 +x:1 +大内 1 +x:1 +竟自 1 +x:1 +猴群 1 +x:1 +嫡传 1 +x:1 +指引 1 +x:1 +克拉别克 1 +x:1 +廉 67 +x:67 +乱石滩 1 +x:1 +多极 1 +x:1 +泽泻 1 +x:1 +响尾蛇 1 +x:1 +铃铛 1 +x:1 +保洁 1 +x:1 +大凡 1 +x:1 +剖 3 +x:3 +踏破 1 +x:1 +直接选举 1 +x:1 +幻灯片 1 +x:1 +蕤 1 +x:1 +力不胜任 1 +x:1 +滩 11 +x:11 +芦笙 1 +x:1 +气道 1 +x:1 +导购人 1 +x:1 +定位点 1 +x:1 +雄才伟略 1 +x:1 +扶 139 +x:139 +压力 1 +x:1 +氮化合物 1 +x:1 +化工界 1 +x:1 +芦笋 1 +x:1 +八闽 1 +x:1 +啤酒馆 1 +x:1 +金睛火眼 1 +x:1 +慢性 1 +x:1 +浑朴 1 +x:1 +很 6590 +x:6590 +拖床 1 +x:1 +存储器 1 +x:1 +依仗 1 +x:1 +情节 1 +x:1 +猛将 1 +x:1 +补养 1 +x:1 +相关者 1 +x:1 +和平共处 1 +x:1 +进关 1 +x:1 +半梦半醒 1 +x:1 +统计法 1 +x:1 +免税额 1 +x:1 +进兵 1 +x:1 +补充 1 +x:1 +身手不凡 1 +x:1 +姊妹花 1 +x:1 +人才篇 1 +x:1 +四十分 1 +x:1 +进入 1 +x:1 +剧减 1 +x:1 +左不过 1 +x:1 +握别 1 +x:1 +肺循环 1 +x:1 +大兵 1 +x:1 +大兴 1 +x:1 +大关 1 +x:1 +蝙蝠侠 1 +x:1 +四突破 1 +x:1 +二药 1 +x:1 +大典 1 +x:1 +芦管 1 +x:1 +体 51 +x:51 +普创 1 +x:1 +压制 1 +x:1 +胜局 1 +x:1 +炮筒 1 +x:1 +大公 1 +x:1 +浪卡子县 1 +x:1 +大全 1 +x:1 +涡流 1 +x:1 +⑥ 6 +x:6 +压分 1 +x:1 +胜山 1 +x:1 +鹞鹰 1 +x:1 +有所不为 1 +x:1 +闭目养神 1 +x:1 +科西嘉 1 +x:1 +征服力 1 +x:1 +望穿秋水 1 +x:1 +醋栗 1 +x:1 +医理 1 +x:1 +孤高 1 +x:1 +交易权 1 +x:1 +鼎湖 1 +x:1 +嫌隙 1 +x:1 +加的夫 1 +x:1 +白地 1 +x:1 +多情 1 +x:1 +入户率 1 +x:1 +贵州厅 1 +x:1 +新疆村 1 +x:1 +南石冲 1 +x:1 +将领 1 +x:1 +幸好 1 +x:1 +工艺学 1 +x:1 +鼠腹 1 +x:1 +变法维新 1 +x:1 +独行人 1 +x:1 +言而有信 1 +x:1 +诗言志 1 +x:1 +豆奶 1 +x:1 +一唱一和 1 +x:1 +小镇 1 +x:1 +找寻 1 +x:1 +汇总 1 +x:1 +刑讯 1 +x:1 +加拿大 1 +x:1 +近洋 1 +x:1 +算术级数 1 +x:1 +昆仑 1 +x:1 +偏硅酸 1 +x:1 +舶来 1 +x:1 +近海 1 +x:1 +眼捷手快 1 +x:1 +零用 1 +x:1 +江道 1 +x:1 +大国 1 +x:1 +小锣 1 +x:1 +当涂县 1 +x:1 +介音 1 +x:1 +汐 1 +x:1 +小舌 1 +x:1 +后盾 1 +x:1 +泸沽 1 +x:1 +救球手 1 +x:1 +科社 1 +x:1 +六经者 1 +x:1 +并称 1 +x:1 +纵线 1 +x:1 +维护税 1 +x:1 +纯属 1 +x:1 +次之 1 +x:1 +大四 1 +x:1 +供养 1 +x:1 +鼠脑 1 +x:1 +欺诈案 1 +x:1 +惊涛拍岸 1 +x:1 +追 172 +x:172 +出弦度 1 +x:1 +后盖 1 +x:1 +文人佳士 1 +x:1 +栽植 1 +x:1 +供气量 1 +x:1 +降雨带 1 +x:1 +时间廊 1 +x:1 +显性 1 +x:1 +皮夹克 1 +x:1 +账册 1 +x:1 +巴甫洛夫 1 +x:1 +发芽势 1 +x:1 +马拉若岛 1 +x:1 +套菜 1 +x:1 +存在主义 1 +x:1 +谦恭 1 +x:1 +盗窃风 1 +x:1 +趣事 1 +x:1 +累累的 1 +x:1 +遮荫 1 +x:1 +热毛子马 1 +x:1 +护 85 +x:85 +行骗 1 +x:1 +待查 1 +x:1 +快感 1 +x:1 +犬马之劳 1 +x:1 +得意之笔 1 +x:1 +群工部 1 +x:1 +火狐狸 1 +x:1 +坐镇 1 +x:1 +姊妹节 1 +x:1 +欢聚 1 +x:1 +看客 1 +x:1 +安抚 1 +x:1 +充电器 1 +x:1 +评报稿 1 +x:1 +策马飞驰 1 +x:1 +哀嚎 1 +x:1 +分布区 1 +x:1 +气韵 1 +x:1 +大歌大哭 1 +x:1 +大邑县 1 +x:1 +户头 1 +x:1 +养生之道 1 +x:1 +看家 1 +x:1 +以诚相待 1 +x:1 +工艺室 1 +x:1 +嘲风咏月 1 +x:1 +大器 1 +x:1 +注意者 1 +x:1 +堆存费 1 +x:1 +皮夹儿 1 +x:1 +看守 1 +x:1 +安抵 1 +x:1 +户外 1 +x:1 +潘寨村 1 +x:1 +镇海村 1 +x:1 +军民航 1 +x:1 +无为而治 1 +x:1 +白城 1 +x:1 +意乱情迷 1 +x:1 +笑声 1 +x:1 +石材业 1 +x:1 +配股 1 +x:1 +甜丝丝 1 +x:1 +是非黑白 1 +x:1 +纳章乡 1 +x:1 +妄自尊大 1 +x:1 +十美 1 +x:1 +巴中市 1 +x:1 +天造地设 1 +x:1 +书纪 1 +x:1 +进城 1 +x:1 +推诚相见 1 +x:1 +循环制 1 +x:1 +蟋蟀草 1 +x:1 +槲寄生 1 +x:1 +剧坛 1 +x:1 +圬 1 +x:1 +协调性 1 +x:1 +库藏 1 +x:1 +套色 1 +x:1 +血汗钱 1 +x:1 +硬汉 1 +x:1 +独行侠 1 +x:1 +大型 1 +x:1 +门诊部 1 +x:1 +殿 5 +x:5 +品 82 +x:82 +县市长 1 +x:1 +监理办 1 +x:1 +大惑不解 1 +x:1 +科教兴农 1 +x:1 +体弱多病 1 +x:1 +缴纳处 1 +x:1 +中技校 1 +x:1 +剧场 1 +x:1 +节约箱 1 +x:1 +裹脚布 1 +x:1 +岗子 1 +x:1 +大埯 1 +x:1 +注解 1 +x:1 +行驶 1 +x:1 +大埔 1 +x:1 +政策 1 +x:1 +平平安安 1 +x:1 +票体 1 +x:1 +履历 1 +x:1 +经济效益 1 +x:1 +痛痛快快 1 +x:1 +非传统 1 +x:1 +大城 1 +x:1 +注视 1 +x:1 +填 107 +x:107 +喀 7 +x:7 +摇摆不定 1 +x:1 +质疑 1 +x:1 +大地 1 +x:1 +岩石体 1 +x:1 +安插 1 +x:1 +五行镇 1 +x:1 +目不斜视 1 +x:1 +候 6 +x:6 +欢腾 1 +x:1 +记名式 1 +x:1 +大圪 1 +x:1 +镇海港 1 +x:1 +责问 1 +x:1 +羽联 1 +x:1 +气肥 1 +x:1 +鼠胆 1 +x:1 +危机感 1 +x:1 +龙山集 1 +x:1 +走麦城 1 +x:1 +养蜂 1 +x:1 +桂林市 1 +x:1 +非亲非故 1 +x:1 +陶公府 1 +x:1 +用心良苦 1 +x:1 +阳面 1 +x:1 +曾祖母 1 +x:1 +公益林 1 +x:1 +启示 1 +x:1 +普吉 1 +x:1 +扶贫济困 1 +x:1 +促膝交谈 1 +x:1 +搬走 1 +x:1 +作祟 1 +x:1 +安排 1 +x:1 +弹道学 1 +x:1 +周围 1 +x:1 +物理系 1 +x:1 +使劲儿 1 +x:1 +根治 1 +x:1 +信仰者 1 +x:1 +接报案 1 +x:1 +夏鲁派 1 +x:1 +古稀之年 1 +x:1 +小钱 1 +x:1 +零担 1 +x:1 +大块 1 +x:1 +镇康县 1 +x:1 +双重人格 1 +x:1 +大坑 1 +x:1 +背日性 1 +x:1 +进场 1 +x:1 +大坝 1 +x:1 +比绍市 1 +x:1 +资讯 1 +x:1 +迷离扑朔 1 +x:1 +心灵 1 +x:1 +化学化 1 +x:1 +养蝎 1 +x:1 +豆子 1 +x:1 +移机 1 +x:1 +逄 12 +x:12 +汇成 1 +x:1 +房间 1 +x:1 +鼠药 1 +x:1 +中山王 1 +x:1 +追肥 1 +x:1 +自治县 1 +x:1 +光机电 1 +x:1 +房门 1 +x:1 +气锤 1 +x:1 +开庭 1 +x:1 +依安 1 +x:1 +我们 1 +x:1 +看好 1 +x:1 +三合房 1 +x:1 +方括号 1 +x:1 +鸣鞭 1 +x:1 +乒乒 1 +x:1 +唱经声 1 +x:1 +模模糊糊 1 +x:1 +幅度 1 +x:1 +补品 1 +x:1 +服法 1 +x:1 +襄樊站 1 +x:1 +狼头山 1 +x:1 +坐观成败 1 +x:1 +安恬 1 +x:1 +安息 1 +x:1 +空泛 1 +x:1 +气锅 1 +x:1 +红宝石 1 +x:1 +杂文集 1 +x:1 +笑容 1 +x:1 +汨罗市 1 +x:1 +博采 1 +x:1 +桔农 1 +x:1 +陆相沉积 1 +x:1 +大哥 1 +x:1 +计价 1 +x:1 +看头 1 +x:1 +此致 1 +x:1 +大哭 1 +x:1 +多抗 1 +x:1 +减量 1 +x:1 +楣上 1 +x:1 +疑难症 1 +x:1 +外侧 1 +x:1 +外侨 1 +x:1 +多报 1 +x:1 +软性化 1 +x:1 +外侮 1 +x:1 +梭梭 1 +x:1 +计付 1 +x:1 +办税厅 1 +x:1 +失主 1 +x:1 +沧州市 1 +x:1 +荨麻 1 +x:1 +赏玩 1 +x:1 +造船量 1 +x:1 +从业员 1 +x:1 +新生面 1 +x:1 +油盐酱醋 1 +x:1 +本固枝荣 1 +x:1 +大国家党 1 +x:1 +埠头 1 +x:1 +长青林 1 +x:1 +净产值 1 +x:1 +贤哲 1 +x:1 +卑怯 1 +x:1 +大言不惭 1 +x:1 +效死 1 +x:1 +气胸 1 +x:1 +凶相毕露 1 +x:1 +加积镇 1 +x:1 +流通量 1 +x:1 +舰尾 1 +x:1 +钬 1 +x:1 +特快专递 1 +x:1 +一言为定 1 +x:1 +汇报 1 +x:1 +年近花甲 1 +x:1 +补员 1 +x:1 +大吏 1 +x:1 +大名 1 +x:1 +大同 1 +x:1 +洽 12 +x:12 +大吉 1 +x:1 +酬对 1 +x:1 +外企 1 +x:1 +幻影 1 +x:1 +岸滩 1 +x:1 +运动界 1 +x:1 +阔叶 1 +x:1 +气闷 1 +x:1 +配药 1 +x:1 +趣 34 +x:34 +知味馆 1 +x:1 +气门 1 +x:1 +着陆器 1 +x:1 +警视厅 1 +x:1 +外传 1 +x:1 +夏县 1 +x:1 +圆心角 1 +x:1 +外伤 1 +x:1 +价码 1 +x:1 +商品经济 1 +x:1 +丽岛 1 +x:1 +教职 1 +x:1 +服气 1 +x:1 +壳舾装 1 +x:1 +琐细 1 +x:1 +酬宾 1 +x:1 +欢舞 1 +x:1 +交易所 1 +x:1 +肉色 1 +x:1 +串联式 1 +x:1 +外甥女 1 +x:1 +指使 1 +x:1 +猛增 1 +x:1 +丽水庄 1 +x:1 +端砚 1 +x:1 +徇私 1 +x:1 +蜜丸子 1 +x:1 +冰上 1 +x:1 +库车县 1 +x:1 +快人快语 1 +x:1 +安慰 1 +x:1 +大喜 1 +x:1 +炮群 1 +x:1 +阳间 1 +x:1 +岗头 1 +x:1 +头 906 +x:906 +白吃 1 +x:1 +广征博采 1 +x:1 +大喊 1 +x:1 +贡缎布 1 +x:1 +直选 1 +x:1 +书系 1 +x:1 +差错 1 +x:1 +套耕 1 +x:1 +裕中西里 1 +x:1 +楔 1 +x:1 +狙 1 +x:1 +姑息 1 +x:1 +外交 1 +x:1 +折纯 1 +x:1 +书 1372 +x:1372 +法老 1 +x:1 +劳心 1 +x:1 +褶皱 1 +x:1 +恭陪 1 +x:1 +小队 1 +x:1 +折纹 1 +x:1 +折线 1 +x:1 +坍塌 1 +x:1 +苹 1 +x:1 +外人 1 +x:1 +沾亲带故 1 +x:1 +持枪者 1 +x:1 +种羊场 1 +x:1 +漳平市 1 +x:1 +漆树 1 +x:1 +海秀路 1 +x:1 +旌德县 1 +x:1 +雌性 1 +x:1 +丽水市 1 +x:1 +奸臣 1 +x:1 +辖 45 +x:45 +眼科史 1 +x:1 +招兵买马 1 +x:1 +通权达变 1 +x:1 +现任 1 +x:1 +奉献篇 1 +x:1 +外乡 1 +x:1 +季节性 1 +x:1 +勇武 1 +x:1 +指导 1 +x:1 +减退 1 +x:1 +减速 1 +x:1 +线长面广 1 +x:1 +付家寨镇 1 +x:1 +亚洲区 1 +x:1 +后生 1 +x:1 +莸 1 +x:1 +配舞 1 +x:1 +千 776 +x:776 +看海者 1 +x:1 +定位球 1 +x:1 +磊 270 +x:270 +摇旗呐喊 1 +x:1 +指定 1 +x:1 +洞井乡 1 +x:1 +蹑 1 +x:1 +烟台山 1 +x:1 +达姆弹 1 +x:1 +膏粱子弟 1 +x:1 +舞蹈班 1 +x:1 +辞岁 1 +x:1 +外业 1 +x:1 +荣枯变幻 1 +x:1 +捣 7 +x:7 +龙舟赛 1 +x:1 +聚氯乙稀 1 +x:1 +拉力器 1 +x:1 +百衲衣 1 +x:1 +物理组 1 +x:1 +空洞 1 +x:1 +不亦乐乎 1 +x:1 +伊斯兰教 1 +x:1 +萨马拉 1 +x:1 +纸质 1 +x:1 +根源 1 +x:1 +萨克管 1 +x:1 +淼 5 +x:5 +督查员 1 +x:1 +浑河 1 +x:1 +彩釉砖 1 +x:1 +迟滞不前 1 +x:1 +诊法 1 +x:1 +极端 1 +x:1 +嵘 6 +x:6 +阁僚 1 +x:1 +摘编 1 +x:1 +百日 1 +x:1 +闪光弹 1 +x:1 +衙役 1 +x:1 +辞却 1 +x:1 +带路人 1 +x:1 +滴水瓦 1 +x:1 +遗址 1 +x:1 +达布逊湖 1 +x:1 +开发区热 1 +x:1 +毯子 1 +x:1 +浑沌 1 +x:1 +监造组 1 +x:1 +后窗 1 +x:1 +础 2 +x:2 +琴技 1 +x:1 +指向 1 +x:1 +校车 1 +x:1 +普鲁士 1 +x:1 +南蔡乡 1 +x:1 +冬闲田 1 +x:1 +蓓 5 +x:5 +刷新 1 +x:1 +豪华型 1 +x:1 +指名 1 +x:1 +一气呵成 1 +x:1 +过户费 1 +x:1 +直岗拉卡 1 +x:1 +梅花桩 1 +x:1 +白字 1 +x:1 +白子 1 +x:1 +诊治 1 +x:1 +施家湖村 1 +x:1 +交易法 1 +x:1 +逗号 1 +x:1 +大嫂 1 +x:1 +内在于 1 +x:1 +零整 1 +x:1 +气魄 1 +x:1 +嫩竹 1 +x:1 +口香糖 1 +x:1 +团藻 1 +x:1 +栋 85 +x:85 +四节制 1 +x:1 +固能 1 +x:1 +获胜 1 +x:1 +无房者 1 +x:1 +白宫 1 +x:1 +跑单帮 1 +x:1 +吕勒奥 1 +x:1 +周官 1 +x:1 +后程 1 +x:1 +保温房 1 +x:1 +破烂儿 1 +x:1 +空手 1 +x:1 +警卫车 1 +x:1 +大娘 1 +x:1 +金沙镇 1 +x:1 +楚布寺 1 +x:1 +漆木 1 +x:1 +贪婪者 1 +x:1 +团市委 1 +x:1 +辞句 1 +x:1 +高寿 1 +x:1 +引路人 1 +x:1 +大婶 1 +x:1 +保暖 1 +x:1 +福利型 1 +x:1 +旱魔 1 +x:1 +安源 1 +x:1 +履带 1 +x:1 +主楼 1 +x:1 +舞蹈系 1 +x:1 +土皇帝 1 +x:1 +弈友 1 +x:1 +空房 1 +x:1 +重操旧业 1 +x:1 +其父 1 +x:1 +人民性 1 +x:1 +普天 1 +x:1 +湖面 1 +x:1 +辞去 1 +x:1 +延解 1 +x:1 +捉弄 1 +x:1 +目击人 1 +x:1 +欢谈 1 +x:1 +浑江 1 +x:1 +安溪 1 +x:1 +空战 1 +x:1 +珙县 1 +x:1 +炮灰 1 +x:1 +周密 1 +x:1 +咽下 1 +x:1 +分布式 1 +x:1 +爵士队 1 +x:1 +大家 1 +x:1 +可想而知 1 +x:1 +婉劝 1 +x:1 +激光束 1 +x:1 +栏杆 1 +x:1 +锈 5 +x:5 +擀杖 1 +x:1 +大客 1 +x:1 +小项 1 +x:1 +西山腰 1 +x:1 +大宫 1 +x:1 +从一而终 1 +x:1 +搜括有方 1 +x:1 +大宗 1 +x:1 +横加指责 1 +x:1 +山旮旯 1 +x:1 +欢跃 1 +x:1 +天下 1 +x:1 +阔少 1 +x:1 +穷奢极侈 1 +x:1 +豪华团 1 +x:1 +入户线 1 +x:1 +静冈县 1 +x:1 +大宁 1 +x:1 +本末倒置 1 +x:1 +军需 1 +x:1 +扬汤止沸 1 +x:1 +标准杆 1 +x:1 +大安 1 +x:1 +午餐会 1 +x:1 +斗门镇 1 +x:1 +打圆场 1 +x:1 +追述 1 +x:1 +大寿 1 +x:1 +保期 1 +x:1 +如是说 1 +x:1 +忘情 1 +x:1 +亚东 1 +x:1 +滚水 1 +x:1 +汇流 1 +x:1 +遵章率 1 +x:1 +保有 1 +x:1 +大寨 1 +x:1 +压境 1 +x:1 +死角 1 +x:1 +激光机 1 +x:1 +大寒 1 +x:1 +急如星火 1 +x:1 +贼溜溜 1 +x:1 +氨化 1 +x:1 +蟹黄 1 +x:1 +鹤发童颜 1 +x:1 +褶子 1 +x:1 +绒毛状 1 +x:1 +辞别 1 +x:1 +固脚 1 +x:1 +多晶体 1 +x:1 +别来无恙 1 +x:1 +幻像 1 +x:1 +恭顺 1 +x:1 +活到老 1 +x:1 +后患无穷 1 +x:1 +花甲之年 1 +x:1 +忘怀 1 +x:1 +练武 1 +x:1 +降雨区 1 +x:1 +气骨 1 +x:1 +贴有 1 +x:1 +贮药瓶 1 +x:1 +所有者 1 +x:1 +满腹珠玑 1 +x:1 +集数 1 +x:1 +足迹 1 +x:1 +角闪石 1 +x:1 +茧 6 +x:6 +仁果 1 +x:1 +镇子 1 +x:1 +味同嚼蜡 1 +x:1 +忘性 1 +x:1 +耸人听闻 1 +x:1 +压塑 1 +x:1 +劲 94 +x:94 +够用 1 +x:1 +近悉 1 +x:1 +组装车 1 +x:1 +利润法 1 +x:1 +亚于 1 +x:1 +耐火砖 1 +x:1 +安澜 1 +x:1 +百感丛生 1 +x:1 +喜悦感 1 +x:1 +工装架 1 +x:1 +空挡 1 +x:1 +大学 1 +x:1 +拒 106 +x:106 +大季 1 +x:1 +收支额 1 +x:1 +好好先生 1 +x:1 +概言之 1 +x:1 +白嫩 1 +x:1 +逼真感 1 +x:1 +差额选举 1 +x:1 +本专科生 1 +x:1 +大字 1 +x:1 +辐射能 1 +x:1 +忘恩 1 +x:1 +大子 1 +x:1 +压力锅 1 +x:1 +户名 1 +x:1 +零碎 1 +x:1 +哼 19 +x:19 +石河 1 +x:1 +小额 1 +x:1 +号角 1 +x:1 +花土沟 1 +x:1 +谨而慎之 1 +x:1 +腻 8 +x:8 +浑浊 1 +x:1 +中低产 1 +x:1 +白头 1 +x:1 +忘掉 1 +x:1 +编采 1 +x:1 +格罗兹尼 1 +x:1 +北水南调 1 +x:1 +鞍马劳顿 1 +x:1 +周天 1 +x:1 +质量课 1 +x:1 +原生动物 1 +x:1 +白天 1 +x:1 +采访团 1 +x:1 +丞相 1 +x:1 +浑源 1 +x:1 +反贪局 1 +x:1 +大增 1 +x:1 +府发 1 +x:1 +然而 1 +x:1 +申 95 +x:95 +大墙 1 +x:1 +拖地 1 +x:1 +亮点 1 +x:1 +东北方 1 +x:1 +盗窃险 1 +x:1 +丸 11 +x:11 +继承性 1 +x:1 +递送 1 +x:1 +石门子 1 +x:1 +超党派 1 +x:1 +金质奖 1 +x:1 +香客 1 +x:1 +效果 1 +x:1 +测试题 1 +x:1 +安民 1 +x:1 +普宁 1 +x:1 +督造 1 +x:1 +农牧林 1 +x:1 +结算处 1 +x:1 +进境 1 +x:1 +小鬼 1 +x:1 +语焉不详 1 +x:1 +两用林 1 +x:1 +人民报 1 +x:1 +沿线 1 +x:1 +宗教 1 +x:1 +侗家人 1 +x:1 +加佳队 1 +x:1 +温湿度 1 +x:1 +套购 1 +x:1 +铮铮铁骨 1 +x:1 +户型 1 +x:1 +脑癌 1 +x:1 +戒规 1 +x:1 +闵 106 +x:106 +赏罚 1 +x:1 +压宝 1 +x:1 +受用终身 1 +x:1 +使不得 1 +x:1 +私生活 1 +x:1 +纸箱厂 1 +x:1 +编配 1 +x:1 +编印者 1 +x:1 +杀富济贫 1 +x:1 +大堤 1 +x:1 +仲裁 1 +x:1 +硬科学 1 +x:1 +吨/人 1 +x:1 +炜 24 +x:24 +大谬不然 1 +x:1 +幻化 1 +x:1 +栽绒 1 +x:1 +套路 1 +x:1 +卓奥友峰 1 +x:1 +糊涂人 1 +x:1 +拖垮 1 +x:1 +坦言 1 +x:1 +大堆 1 +x:1 +蠢材 1 +x:1 +大堂 1 +x:1 +纵火 1 +x:1 +销方 1 +x:1 +攻关点 1 +x:1 +气馁 1 +x:1 +假 557 +x:557 +宗族 1 +x:1 +竞争力部 1 +x:1 +物美 1 +x:1 +化工系 1 +x:1 +卑污 1 +x:1 +差额 1 +x:1 +通宵 1 +x:1 +科教兴市 1 +x:1 +情诗 1 +x:1 +标准电阻 1 +x:1 +箔条 1 +x:1 +最高潮 1 +x:1 +带头户 1 +x:1 +万无一失 1 +x:1 +剧增 1 +x:1 +鼠辈 1 +x:1 +醋意 1 +x:1 +中厂乡 1 +x:1 +大塘 1 +x:1 +危 29 +x:29 +禾草 1 +x:1 +片甲不留 1 +x:1 +报考者 1 +x:1 +死记 1 +x:1 +供应证 1 +x:1 +大妹 1 +x:1 +辰砂 1 +x:1 +摸摸 1 +x:1 +勇气 1 +x:1 +民间文学 1 +x:1 +安济 1 +x:1 +安流 1 +x:1 +永续 1 +x:1 +四家屯村 1 +x:1 +死讯 1 +x:1 +苔衣 1 +x:1 +院校 1 +x:1 +司长级 1 +x:1 +后福 1 +x:1 +鼠蹊 1 +x:1 +近战 1 +x:1 +欢迎 1 +x:1 +铲运机 1 +x:1 +以小见大 1 +x:1 +静乐县 1 +x:1 +防空兵 1 +x:1 +家庭剧 1 +x:1 +麻醉科 1 +x:1 +左路 1 +x:1 +查体 1 +x:1 +大妈 1 +x:1 +车马坑 1 +x:1 +监理岗 1 +x:1 +国是 1 +x:1 +寻亲者 1 +x:1 +祝酒辞 1 +x:1 +后移 1 +x:1 +奸贼 1 +x:1 +鹞雀 1 +x:1 +坐骨 1 +x:1 +大姨 1 +x:1 +白钨矿 1 +x:1 +坐骑 1 +x:1 +大姓 1 +x:1 +安洼 1 +x:1 +大姑 1 +x:1 +大姐 1 +x:1 +重重的 1 +x:1 +坦诚 1 +x:1 +禾苗 1 +x:1 +韵语 1 +x:1 +滞重 1 +x:1 +鸡瘟 1 +x:1 +二话 1 +x:1 +存款人 1 +x:1 +年三十 1 +x:1 +空间科学 1 +x:1 +大头 1 +x:1 +穷形尽相 1 +x:1 +零时 1 +x:1 +台湾省 1 +x:1 +房顶 1 +x:1 +香功 1 +x:1 +民不聊生 1 +x:1 +标准时 1 +x:1 +争创 1 +x:1 +大大 1 +x:1 +集权 1 +x:1 +刘家峡 1 +x:1 +十二指肠 1 +x:1 +忘我 1 +x:1 +大夫 1 +x:1 +保时 1 +x:1 +拂扬 1 +x:1 +评点家 1 +x:1 +大多 1 +x:1 +婚礼 1 +x:1 +复色光 1 +x:1 +运算量 1 +x:1 +镇守 1 +x:1 +工艺品 1 +x:1 +潮起 1 +x:1 +智能机 1 +x:1 +追赶 1 +x:1 +半自给 1 +x:1 +试用品 1 +x:1 +挖墙脚 1 +x:1 +编选 1 +x:1 +大好 1 +x:1 +宝汤村 1 +x:1 +走嘴 1 +x:1 +推斥力 1 +x:1 +够格 1 +x:1 +净胜球 1 +x:1 +贤妻 1 +x:1 +错金 1 +x:1 +编造 1 +x:1 +大奖 1 +x:1 +鹰爪毛儿 1 +x:1 +交口县 1 +x:1 +足足 1 +x:1 +自足村 1 +x:1 +保方 1 +x:1 +汰劣 1 +x:1 +靳 53 +x:53 +追赃 1 +x:1 +装修物 1 +x:1 +龙宝区 1 +x:1 +拒假者 1 +x:1 +大康 1 +x:1 +身着 1 +x:1 +感情式 1 +x:1 +天井 1 +x:1 +第一夫人 1 +x:1 +大度 1 +x:1 +邓小平 1 +x:1 +古人 1 +x:1 +镇容 1 +x:1 +欺诈性 1 +x:1 +养身 1 +x:1 +阔大 1 +x:1 +骚体 1 +x:1 +琐琐 1 +x:1 +情质 1 +x:1 +幸免 1 +x:1 +婚约 1 +x:1 +笑凝 1 +x:1 +大庆 1 +x:1 +纵目 1 +x:1 +间苗 1 +x:1 +斯瓦诺 1 +x:1 +慧心 1 +x:1 +涿鹿县 1 +x:1 +古井 1 +x:1 +婚纱 1 +x:1 +硬梆梆 1 +x:1 +享有盛誉 1 +x:1 +后续 1 +x:1 +岗前 1 +x:1 +刁悍 1 +x:1 +古代 1 +x:1 +款物 1 +x:1 +沉潜 1 +x:1 +督阵 1 +x:1 +保户 1 +x:1 +走时 1 +x:1 +古今 1 +x:1 +铁汉 1 +x:1 +古体诗 1 +x:1 +空暇 1 +x:1 +代培 1 +x:1 +平弦 1 +x:1 +亮相 1 +x:1 +进度 1 +x:1 +价 162 +x:162 +配角 1 +x:1 +鸡霍乱 1 +x:1 +基地带 1 +x:1 +乡巴佬 1 +x:1 +雍容大度 1 +x:1 +瘦干 1 +x:1 +难以成眠 1 +x:1 +嫩绿 1 +x:1 +神经错乱 1 +x:1 +烙铁 1 +x:1 +校训 1 +x:1 +看台 1 +x:1 +阁员 1 +x:1 +套话 1 +x:1 +户养 1 +x:1 +黑斑病 1 +x:1 +宁波 1 +x:1 +真主 1 +x:1 +紫泥泉 1 +x:1 +双刃剑 1 +x:1 +青杨 1 +x:1 +大帝 1 +x:1 +情趣 1 +x:1 +悲伤 1 +x:1 +珐琅质 1 +x:1 +大市 1 +x:1 +袍笏登场 1 +x:1 +持枪证 1 +x:1 +宅急送 1 +x:1 +截然 1 +x:1 +大师 1 +x:1 +后蟠桃村 1 +x:1 +大年 1 +x:1 +大干 1 +x:1 +近时 1 +x:1 +古书 1 +x:1 +工具厂 1 +x:1 +大幸 1 +x:1 +近日 1 +x:1 +幅员 1 +x:1 +丽人 1 +x:1 +戒石铭 1 +x:1 +大幕 1 +x:1 +依兰 1 +x:1 +涡扇 1 +x:1 +百感 1 +x:1 +协税护税 1 +x:1 +驯 4 +x:4 +近旁 1 +x:1 +保护 1 +x:1 +大幅 1 +x:1 +这样 1 +x:1 +高坑田 1 +x:1 +真书 1 +x:1 +多样 1 +x:1 +姑母 1 +x:1 +箪食壶浆 1 +x:1 +古乐 1 +x:1 +学前 1 +x:1 +大德 1 +x:1 +盈余 1 +x:1 +聚氯乙烯 1 +x:1 +编集 1 +x:1 +情谊 1 +x:1 +白帽 1 +x:1 +情调 1 +x:1 +自主权 1 +x:1 +腻虫 1 +x:1 +白带 1 +x:1 +枪法 1 +x:1 +依傍 1 +x:1 +追讨 1 +x:1 +安歇 1 +x:1 +惩一儆百 1 +x:1 +高庙村 1 +x:1 +学院奖 1 +x:1 +八不要 1 +x:1 +白帝 1 +x:1 +没成想 1 +x:1 +八运会 1 +x:1 +塞维利亚 1 +x:1 +试用制 1 +x:1 +以牙还牙 1 +x:1 +白布 1 +x:1 +岗区 1 +x:1 +供体 1 +x:1 +宜兴埠镇 1 +x:1 +白干 1 +x:1 +周年 1 +x:1 +岗南 1 +x:1 +门头沟 1 +x:1 +看到 1 +x:1 +保持 1 +x:1 +追询 1 +x:1 +化学家 1 +x:1 +死路 1 +x:1 +扭亏增盈 1 +x:1 +基律纳 1 +x:1 +泡 61 +x:61 +宁津 1 +x:1 +思想 1 +x:1 +消费资料 1 +x:1 +绒毛皮 1 +x:1 +补征 1 +x:1 +黏合剂 1 +x:1 +确 186 +x:186 +凳 14 +x:14 +守护 1 +x:1 +福利制 1 +x:1 +赐予 1 +x:1 +大忌 1 +x:1 +追诉 1 +x:1 +熔 12 +x:12 +氨基 1 +x:1 +八角田 1 +x:1 +捧捧场 1 +x:1 +死账 1 +x:1 +漫无际涯 1 +x:1 +嫩翠 1 +x:1 +紫光阁 1 +x:1 +幻听 1 +x:1 +注脚 1 +x:1 +奸诈 1 +x:1 +后缀 1 +x:1 +新线 1 +x:1 +搬迁 1 +x:1 +太后 1 +x:1 +胜券 1 +x:1 +闭口不谈 1 +x:1 +后缘 1 +x:1 +白庄 1 +x:1 +巴西队 1 +x:1 +捐赠者 1 +x:1 +根 301 +x:301 +石门岩 1 +x:1 +山绵羊 1 +x:1 +周庄 1 +x:1 +胜利 1 +x:1 +瘦弱 1 +x:1 +南川市 1 +x:1 +奸计 1 +x:1 +长久性 1 +x:1 +盈门 1 +x:1 +遗留 1 +x:1 +主材 1 +x:1 +劝学篇 1 +x:1 +贤德 1 +x:1 +小鲵 1 +x:1 +依偎 1 +x:1 +光化作用 1 +x:1 +编队 1 +x:1 +识破 1 +x:1 +陈吴乡 1 +x:1 +中低收入 1 +x:1 +文陂乡 1 +x:1 +躁动 1 +x:1 +规划署 1 +x:1 +骚人 1 +x:1 +岗台 1 +x:1 +赐与 1 +x:1 +古体 1 +x:1 +惨白色 1 +x:1 +胡琴 1 +x:1 +羁 2 +x:2 +知识 1 +x:1 +户口 1 +x:1 +搬运 1 +x:1 +非计算机 1 +x:1 +艾基莱镇 1 +x:1 +行路人 1 +x:1 +谈谈 1 +x:1 +沫子 1 +x:1 +根杰 1 +x:1 +大岭 1 +x:1 +大岗 1 +x:1 +猛冲 1 +x:1 +医科 1 +x:1 +款款 1 +x:1 +握住 1 +x:1 +太仓 1 +x:1 +摘示 1 +x:1 +喜上眉梢 1 +x:1 +一块儿 1 +x:1 +向量 1 +x:1 +根本 1 +x:1 +苏皖区 1 +x:1 +版 268 +x:268 +小鼠 1 +x:1 +近来 1 +x:1 +豆包 1 +x:1 +数学题 1 +x:1 +户县 1 +x:1 +成塑机 1 +x:1 +将要 1 +x:1 +猛击 1 +x:1 +乌尔禾 1 +x:1 +畲 2 +x:2 +卷帙 1 +x:1 +深泽县 1 +x:1 +复印费 1 +x:1 +穹幕 1 +x:1 +动眼神经 1 +x:1 +书田 1 +x:1 +鱼游釜中 1 +x:1 +心狠 1 +x:1 +进展 1 +x:1 +大尾 1 +x:1 +皮夹子 1 +x:1 +书画 1 +x:1 +实业界 1 +x:1 +忽左忽右 1 +x:1 +秉公执法 1 +x:1 +进屋 1 +x:1 +安检 1 +x:1 +送审稿 1 +x:1 +截止 1 +x:1 +新威路 1 +x:1 +来得及 1 +x:1 +隐蔽所 1 +x:1 +连轴转 1 +x:1 +忘本 1 +x:1 +修船 1 +x:1 +背斜层 1 +x:1 +保龄球热 1 +x:1 +爪子 1 +x:1 +男人味 1 +x:1 +书生 1 +x:1 +大将 1 +x:1 +小葱 1 +x:1 +乌饭树 1 +x:1 +大小 1 +x:1 +奥伦堡 1 +x:1 +大尉 1 +x:1 +集成 1 +x:1 +海葬 1 +x:1 +大山 1 +x:1 +战略物资 1 +x:1 +热辣辣 1 +x:1 +贺信 1 +x:1 +太师渊路 1 +x:1 +喜剧式 1 +x:1 +红军团 1 +x:1 +压强 1 +x:1 +四邻八乡 1 +x:1 +户区 1 +x:1 +倾城倾国 1 +x:1 +百炼成钢 1 +x:1 +被统治者 1 +x:1 +循环体 1 +x:1 +吉林市 1 +x:1 +补射 1 +x:1 +博格腾 1 +x:1 +鸿儒 1 +x:1 +猛兽 1 +x:1 +贴息 1 +x:1 +实物地租 1 +x:1 +易者 1 +x:1 +大局 1 +x:1 +戒赌 1 +x:1 +书界 1 +x:1 +外交界 1 +x:1 +青龙山 1 +x:1 +指南 1 +x:1 +祝酒词 1 +x:1 +补差 1 +x:1 +东不拉 1 +x:1 +醒眼 1 +x:1 +打得火热 1 +x:1 +拜拜 1 +x:1 +小萝卜 1 +x:1 +辞呈 1 +x:1 +压延 1 +x:1 +冰洲石 1 +x:1 +扎纳若尔 1 +x:1 +空旷 1 +x:1 +雕虫小技 1 +x:1 +太保 1 +x:1 +氢 16 +x:16 +指印 1 +x:1 +汇款 1 +x:1 +保国村 1 +x:1 +门面房 1 +x:1 +赤峰 1 +x:1 +狐死首丘 1 +x:1 +大巴 1 +x:1 +白山 1 +x:1 +可读性 1 +x:1 +公理式 1 +x:1 +穹形 1 +x:1 +金钱案 1 +x:1 +小鸡 1 +x:1 +识相 1 +x:1 +素质型 1 +x:1 +锡铁山 1 +x:1 +泽惠 1 +x:1 +四书五经 1 +x:1 +养路 1 +x:1 +近景 1 +x:1 +编钟 1 +x:1 +快 1205 +x:1205 +空文 1 +x:1 +干部处 1 +x:1 +辽阔无涯 1 +x:1 +重 981 +x:981 +非人化 1 +x:1 +二连 1 +x:1 +户办 1 +x:1 +楼上 1 +x:1 +陕南 1 +x:1 +楼价 1 +x:1 +套装 1 +x:1 +隆 8 +x:8 +劲舞 1 +x:1 +鱼苗场 1 +x:1 +防治法 1 +x:1 +瘫子 1 +x:1 +赣鄂皖 1 +x:1 +笑剧 1 +x:1 +拂晓 1 +x:1 +计工 1 +x:1 +白岩 1 +x:1 +库车 1 +x:1 +套裙 1 +x:1 +分寸感 1 +x:1 +套裤 1 +x:1 +天使 1 +x:1 +纸卡 1 +x:1 +管材 1 +x:1 +选拔关 1 +x:1 +查无实据 1 +x:1 +炮眼 1 +x:1 +端点 1 +x:1 +许 656 +x:656 +周岁 1 +x:1 +丽江县 1 +x:1 +必读 1 +x:1 +五常镇 1 +x:1 +小麦 1 +x:1 +袖筒 1 +x:1 +热胀冷缩 1 +x:1 +狗熊 1 +x:1 +虑 8 +x:8 +套袖 1 +x:1 +落脚湖 1 +x:1 +婉告 1 +x:1 +三角蚌 1 +x:1 +二门 1 +x:1 +马兰草 1 +x:1 +专业对口 1 +x:1 +岸柳 1 +x:1 +悍匪 1 +x:1 +邮运网 1 +x:1 +嗜 7 +x:7 +体操房 1 +x:1 +正 2464 +x:2464 +额数 1 +x:1 +绅士 1 +x:1 +吉祥村 1 +x:1 +浮思翩翩 1 +x:1 +青尼罗河 1 +x:1 +土石堤 1 +x:1 +贴慰 1 +x:1 +倒计时 1 +x:1 +酬劳 1 +x:1 +嘿嘿嘿 1 +x:1 +站办所 1 +x:1 +曲意奉承 1 +x:1 +大抵 1 +x:1 +多哈 1 +x:1 +风情片 1 +x:1 +护胸 1 +x:1 +不问 1 +x:1 +岸堤 1 +x:1 +主流 1 +x:1 +劈裂 1 +x:1 +大报 1 +x:1 +冤家对头 1 +x:1 +豆浆 1 +x:1 +外秘 1 +x:1 +共命运 1 +x:1 +汇合 1 +x:1 +仙女型 1 +x:1 +贤才 1 +x:1 +藏医学 1 +x:1 +九冬会 1 +x:1 +多哥 1 +x:1 +皮包骨头 1 +x:1 +空嫂 1 +x:1 +大亚湾 1 +x:1 +批斗者 1 +x:1 +透镜 1 +x:1 +得意忘形 1 +x:1 +近处 1 +x:1 +众怒 1 +x:1 +外移 1 +x:1 +荞麦 1 +x:1 +消暑 1 +x:1 +登记者 1 +x:1 +补报 1 +x:1 +触须 1 +x:1 +珍 12 +x:12 +包装盒 1 +x:1 +责编 1 +x:1 +拉齐奥队 1 +x:1 +自然人 1 +x:1 +单门独户 1 +x:1 +安溪县 1 +x:1 +刷 25 +x:25 +让给 1 +x:1 +十月革命 1 +x:1 +三等奖 1 +x:1 +车水马龙 1 +x:1 +枣强镇 1 +x:1 +演播厅 1 +x:1 +谦和 1 +x:1 +多咱 1 +x:1 +大户 1 +x:1 +指法 1 +x:1 +大戳 1 +x:1 +重钢 1 +x:1 +婿水 1 +x:1 +高新区 1 +x:1 +充电房 1 +x:1 +图书馆学 1 +x:1 +厦门 1 +x:1 +嫡系 1 +x:1 +建祠尸祝 1 +x:1 +格鲁吉亚 1 +x:1 +前半年 1 +x:1 +安国 1 +x:1 +供状 1 +x:1 +大我 1 +x:1 +安图 1 +x:1 +管理学家 1 +x:1 +马塞马拉 1 +x:1 +大战 1 +x:1 +医技 1 +x:1 +遮眼法 1 +x:1 +宠爱者 1 +x:1 +挖掘机 1 +x:1 +大戏 1 +x:1 +圣餐 1 +x:1 +霜雪 1 +x:1 +麻城 1 +x:1 +阁栅 1 +x:1 +古物 1 +x:1 +大批 1 +x:1 +黔 39 +x:39 +伙食 1 +x:1 +老虎帽 1 +x:1 +多向 1 +x:1 +也 18777 +x:18777 +起根由头 1 +x:1 +铭记在心 1 +x:1 +保康 1 +x:1 +票站 1 +x:1 +靥 1 +x:1 +交易员 1 +x:1 +引逗 1 +x:1 +岸壁 1 +x:1 +高塘 1 +x:1 +管庄站 1 +x:1 +抚孤 1 +x:1 +冲浪者 1 +x:1 +缆车 1 +x:1 +无怨无悔 1 +x:1 +音像司 1 +x:1 +白描 1 +x:1 +盐舍 1 +x:1 +不错 1 +x:1 +引退 1 +x:1 +亚癌 1 +x:1 +冰砖 1 +x:1 +玉山闸 1 +x:1 +古玩 1 +x:1 +安坐 1 +x:1 +渊 12 +x:12 +最后 1 +x:1 +次第 1 +x:1 +额定 1 +x:1 +豆汁 1 +x:1 +翻译家 1 +x:1 +真率 1 +x:1 +先锋性 1 +x:1 +好好好 1 +x:1 +经贸工委 1 +x:1 +活扣 1 +x:1 +对验 1 +x:1 +愁苦 1 +x:1 +压惊 1 +x:1 +遥遥地 1 +x:1 +空寂 1 +x:1 +灭火器 1 +x:1 +马拉喀什 1 +x:1 +穿越 1 +x:1 +博湖县 1 +x:1 +玄庙镇 1 +x:1 +笼 12 +x:12 +直快 1 +x:1 +依法 1 +x:1 +神学家 1 +x:1 +秘书长库 1 +x:1 +叙言 1 +x:1 +香精 1 +x:1 +空客 1 +x:1 +默不作声 1 +x:1 +协调员 1 +x:1 +凸纹 1 +x:1 +传播台 1 +x:1 +无林地 1 +x:1 +暖暖和和 1 +x:1 +裂隙 1 +x:1 +汞 7 +x:7 +计分牌 1 +x:1 +普及面 1 +x:1 +重镇 1 +x:1 +霜露 1 +x:1 +高塬 1 +x:1 +点到为止 1 +x:1 +次等 1 +x:1 +指派 1 +x:1 +引蛇出洞 1 +x:1 +蹉跎村 1 +x:1 +维护会 1 +x:1 +待制 1 +x:1 +重病缠身 1 +x:1 +统计师 1 +x:1 +通婚 1 +x:1 +票箱 1 +x:1 +鉴定者 1 +x:1 +农牧展 1 +x:1 +古猿 1 +x:1 +漆布 1 +x:1 +粮囤子 1 +x:1 +大振 1 +x:1 +官店镇 1 +x:1 +农牧局 1 +x:1 +如鱼得水 1 +x:1 +宗庙 1 +x:1 +周报 1 +x:1 +安培 1 +x:1 +周折 1 +x:1 +冰碴 1 +x:1 +于营村 1 +x:1 +番木瓜 1 +x:1 +一片汪洋 1 +x:1 +滴虫 1 +x:1 +空子 1 +x:1 +爬行动物 1 +x:1 +百褶裙 1 +x:1 +大捷 1 +x:1 +公债券 1 +x:1 +钕铁硼 1 +x:1 +刁庄村 1 +x:1 +豆沙 1 +x:1 +钢芯 1 +x:1 +联防 1 +x:1 +我社 1 +x:1 +待办 1 +x:1 +钢花 1 +x:1 +门岗 1 +x:1 +音信 1 +x:1 +联队 1 +x:1 +保德 1 +x:1 +哑巴 1 +x:1 +豆油 1 +x:1 +豪华游 1 +x:1 +通心粉 1 +x:1 +时间段 1 +x:1 +交易商 1 +x:1 +傲睨一世 1 +x:1 +舾装 1 +x:1 +地尽其利 1 +x:1 +摸底 1 +x:1 +超前 1 +x:1 +隐花植物 1 +x:1 +鄂州市 1 +x:1 +棋后 1 +x:1 +古巴队 1 +x:1 +踢腿舞 1 +x:1 +港监局 1 +x:1 +冰笋 1 +x:1 +标价签 1 +x:1 +直径 1 +x:1 +伞 41 +x:41 +百忙 1 +x:1 +保山 1 +x:1 +磕头碰脑 1 +x:1 +大悟 1 +x:1 +顾不得 1 +x:1 +浪头港 1 +x:1 +神甫 1 +x:1 +银款 1 +x:1 +瘸 4 +x:4 +标准局 1 +x:1 +猛涨 1 +x:1 +夏鲁寺 1 +x:1 +谈话费 1 +x:1 +星星点点 1 +x:1 +辉绿岩 1 +x:1 +益寿 1 +x:1 +俯首帖耳 1 +x:1 +擎旗人 1 +x:1 +或多或少 1 +x:1 +安吉 1 +x:1 +心肠 1 +x:1 +阅览厅 1 +x:1 +透露 1 +x:1 +万洲 1 +x:1 +表面积 1 +x:1 +衷情 1 +x:1 +刑警局 1 +x:1 +泽州 1 +x:1 +镜花水月 1 +x:1 +粗豪 1 +x:1 +倒不如 1 +x:1 +剩余劳动 1 +x:1 +漆工 1 +x:1 +终身性 1 +x:1 +足球史 1 +x:1 +政法系 1 +x:1 +借钱者 1 +x:1 +颠荡 1 +x:1 +拉动经济 1 +x:1 +勾笔 1 +x:1 +法航 1 +x:1 +贤惠 1 +x:1 +叩门 1 +x:1 +特困证 1 +x:1 +合而为一 1 +x:1 +遒壮 1 +x:1 +党史部 1 +x:1 +叙文 1 +x:1 +超新星 1 +x:1 +冰箱 1 +x:1 +集并 1 +x:1 +I 2 +x:2 +慢藏诲盗 1 +x:1 +步兵团 1 +x:1 +剧情 1 +x:1 +对劲儿 1 +x:1 +悲观失望 1 +x:1 +查盖 1 +x:1 +陈曹乡 1 +x:1 +对饮 1 +x:1 +怒气冲冲 1 +x:1 +看涨 1 +x:1 +三座大山 1 +x:1 +即墨市 1 +x:1 +宗州 1 +x:1 +调节司 1 +x:1 +坐落 1 +x:1 +奇崛壮阔 1 +x:1 +大恩 1 +x:1 +昌乐县 1 +x:1 +狠 47 +x:47 +肝功能 1 +x:1 +阅览区 1 +x:1 +标准岗 1 +x:1 +权能 1 +x:1 +多嘴 1 +x:1 +神界 1 +x:1 +供热 1 +x:1 +赴会 1 +x:1 +宴会桌 1 +x:1 +审美观 1 +x:1 +蛊惑 1 +x:1 +蜂王 1 +x:1 +宁南 1 +x:1 +珙桐 1 +x:1 +四部曲 1 +x:1 +帮 402 +x:402 +候车室 1 +x:1 +重霄 1 +x:1 +搌布 1 +x:1 +宜都 1 +x:1 +库锦 1 +x:1 +由衷之言 1 +x:1 +科技部 1 +x:1 +布尔卡 1 +x:1 +冷 148 +x:148 +统计局 1 +x:1 +中下游 1 +x:1 +空姐 1 +x:1 +吊白块 1 +x:1 +微凸阵 1 +x:1 +溃不成军 1 +x:1 +摊点儿 1 +x:1 +三分制 1 +x:1 +效应 1 +x:1 +势焰 1 +x:1 +直板高手 1 +x:1 +经理部 1 +x:1 +人民宫 1 +x:1 +插种 1 +x:1 +位能 1 +x:1 +若尔盖 1 +x:1 +熊猫馆 1 +x:1 +不难 1 +x:1 +履新 1 +x:1 +闯关东 1 +x:1 +调节剂 1 +x:1 +渴盼 1 +x:1 +查看 1 +x:1 +日短日稀 1 +x:1 +压抑 1 +x:1 +弹子锁 1 +x:1 +浅一脚 1 +x:1 +证券界 1 +x:1 +宗山 1 +x:1 +穿过 1 +x:1 +八里罕镇 1 +x:1 +额外 1 +x:1 +冰窖 1 +x:1 +古黄河 1 +x:1 +百年 1 +x:1 +冰窟 1 +x:1 +交易地 1 +x:1 +稻草人 1 +x:1 +聊城 1 +x:1 +鸣门 1 +x:1 +降尘器 1 +x:1 +福利法 1 +x:1 +平年 1 +x:1 +先锋报 1 +x:1 +额头 1 +x:1 +空中客车 1 +x:1 +汗珠 1 +x:1 +身故金 1 +x:1 +具名 1 +x:1 +宁可 1 +x:1 +里脚手 1 +x:1 +重组型 1 +x:1 +包装用 1 +x:1 +看法 1 +x:1 +浑圆 1 +x:1 +大意 1 +x:1 +透雕 1 +x:1 +一显身手 1 +x:1 +外稃 1 +x:1 +狂言 1 +x:1 +秸秆量 1 +x:1 +这一来 1 +x:1 +迈 111 +x:111 +东北局 1 +x:1 +苋菜 1 +x:1 +潜心斋 1 +x:1 +社科界 1 +x:1 +课程表 1 +x:1 +线络 1 +x:1 +改频点 1 +x:1 +岸导 1 +x:1 +三分球 1 +x:1 +空头 1 +x:1 +瓜亚基尔 1 +x:1 +枯草热 1 +x:1 +法纪星 1 +x:1 +俯仰自如 1 +x:1 +权臣 1 +x:1 +延安东路 1 +x:1 +棋牌 1 +x:1 +象草 1 +x:1 +协调国 1 +x:1 +计策 1 +x:1 +装配线 1 +x:1 +铺 151 +x:151 +蓄芳 1 +x:1 +行得通 1 +x:1 +以假当真 1 +x:1 +汇倒 1 +x:1 +截击 1 +x:1 +狂跌 1 +x:1 +军事部长 1 +x:1 +收起 1 +x:1 +歇脚 1 +x:1 +惨淡经营 1 +x:1 +身体 1 +x:1 +统计学 1 +x:1 +卑劣 1 +x:1 +混日子 1 +x:1 +皮下组织 1 +x:1 +巩义市 1 +x:1 +回程票 1 +x:1 +贺电 1 +x:1 +真的 1 +x:1 +失 183 +x:183 +白朗 1 +x:1 +鸿毛 1 +x:1 +周期 1 +x:1 +大暑 1 +x:1 +周朝 1 +x:1 +百姓 1 +x:1 +监测站 1 +x:1 +准格尔 1 +x:1 +白河县 1 +x:1 +真皮 1 +x:1 +额度 1 +x:1 +其他 1 +x:1 +东山岛 1 +x:1 +转瞬即逝 1 +x:1 +货运单 1 +x:1 +红骨髓 1 +x:1 +空廓 1 +x:1 +穷苦 1 +x:1 +迎刃而解 1 +x:1 +大曲 1 +x:1 +神学系 1 +x:1 +最先 1 +x:1 +九一三 1 +x:1 +指标 1 +x:1 +书信 1 +x:1 +销子 1 +x:1 +白条 1 +x:1 +宿命论 1 +x:1 +保 391 +x:391 +白杨 1 +x:1 +安分 1 +x:1 +穗闻站 1 +x:1 +须发 1 +x:1 +线组 1 +x:1 +真相 1 +x:1 +挑挑拣拣 1 +x:1 +虎头虎脑 1 +x:1 +其二 1 +x:1 +霸州 1 +x:1 +白杆 1 +x:1 +其五 1 +x:1 +麻包 1 +x:1 +涨幅 1 +x:1 +搽脂抹粉 1 +x:1 +线线 1 +x:1 +抄 57 +x:57 +次级 1 +x:1 +十三 1 +x:1 +索赔期 1 +x:1 +洒扫庭除 1 +x:1 +予取予夺 1 +x:1 +盈盈 1 +x:1 +华山论剑 1 +x:1 +烂兮兮 1 +x:1 +空幻 1 +x:1 +亮丑 1 +x:1 +泸山 1 +x:1 +印史 1 +x:1 +檀香 1 +x:1 +政通人和 1 +x:1 +不配 1 +x:1 +白果 1 +x:1 +感光纸 1 +x:1 +化学所 1 +x:1 +金丝边 1 +x:1 +防城港市 1 +x:1 +水利部 1 +x:1 +亮丽 1 +x:1 +可亲可敬 1 +x:1 +大明 1 +x:1 +并未 1 +x:1 +禾 3 +x:3 +截儿 1 +x:1 +慢坡 1 +x:1 +无限公司 1 +x:1 +其中 1 +x:1 +众口难调 1 +x:1 +查点 1 +x:1 +索赔权 1 +x:1 +鹏程万里 1 +x:1 +吊民伐罪 1 +x:1 +穿衣 1 +x:1 +农牧处 1 +x:1 +百大 1 +x:1 +其一 1 +x:1 +发射率 1 +x:1 +书体 1 +x:1 +其三 1 +x:1 +其下 1 +x:1 +训练团 1 +x:1 +棋界 1 +x:1 +穿行 1 +x:1 +包装物 1 +x:1 +阀门界 1 +x:1 +座背 1 +x:1 +冬候鸟 1 +x:1 +贴实 1 +x:1 +灭火剂 1 +x:1 +潘生丁 1 +x:1 +白昼 1 +x:1 +西边 1 +x:1 +保存 1 +x:1 +二二八 1 +x:1 +大枣 1 +x:1 +长短句 1 +x:1 +大枪 1 +x:1 +严肃性 1 +x:1 +旦夕 1 +x:1 +垂柳 1 +x:1 +安危 1 +x:1 +新绿 1 +x:1 +本 2116 +x:2116 +空心 1 +x:1 +城池 1 +x:1 +正长石 1 +x:1 +呵叻府 1 +x:1 +泸州 1 +x:1 +训练场 1 +x:1 +东安 1 +x:1 +利泽千秋 1 +x:1 +单项赛 1 +x:1 +安卧 1 +x:1 +乌漆 1 +x:1 +汇兑 1 +x:1 +书价 1 +x:1 +身下 1 +x:1 +二重唱 1 +x:1 +怀乡思亲 1 +x:1 +坌 1 +x:1 +安化 1 +x:1 +大动干戈 1 +x:1 +身世 1 +x:1 +麻利 1 +x:1 +剧本 1 +x:1 +诟 1 +x:1 +闯入 1 +x:1 +高密市 1 +x:1 +瘦果 1 +x:1 +补助款 1 +x:1 +自治区 1 +x:1 +汇入 1 +x:1 +粉煤灰砖 1 +x:1 +械斗 1 +x:1 +身为 1 +x:1 +真知 1 +x:1 +企管站 1 +x:1 +腹心 1 +x:1 +冰粒 1 +x:1 +进村 1 +x:1 +舅 4 +x:4 +虚无飘渺 1 +x:1 +近岸 1 +x:1 +相投 1 +x:1 +怒火中烧 1 +x:1 +多元 1 +x:1 +一呼百诺 1 +x:1 +肃静 1 +x:1 +保密 1 +x:1 +服役 1 +x:1 +令人不安 1 +x:1 +纵使 1 +x:1 +县令 1 +x:1 +卫生队 1 +x:1 +老儿子 1 +x:1 +延胡索 1 +x:1 +书业 1 +x:1 +摄美部 1 +x:1 +觥筹交错 1 +x:1 +深有所思 1 +x:1 +铁山乡 1 +x:1 +折射角 1 +x:1 +进来 1 +x:1 +五磷 1 +x:1 +噼噼啪啪 1 +x:1 +其余 1 +x:1 +矩型坯 1 +x:1 +身份 1 +x:1 +空当 1 +x:1 +冰糖 1 +x:1 +邵阳市 1 +x:1 +集外 1 +x:1 +冰糕 1 +x:1 +辞源 1 +x:1 +红旗招展 1 +x:1 +畋 1 +x:1 +交易关 1 +x:1 +红五军 1 +x:1 +保定 1 +x:1 +发射状 1 +x:1 +第一国际 1 +x:1 +家电展 1 +x:1 +笤帚头 1 +x:1 +指挥仪 1 +x:1 +粗话 1 +x:1 +保安 1 +x:1 +保守 1 +x:1 +隐蔽处 1 +x:1 +放气门 1 +x:1 +身亡 1 +x:1 +体育馆 1 +x:1 +机修工 1 +x:1 +火箭乡 1 +x:1 +不适 1 +x:1 +干部科 1 +x:1 +专业化 1 +x:1 +重量 1 +x:1 +襄阳 1 +x:1 +兵戈相见 1 +x:1 +大权 1 +x:1 +夜市 1 +x:1 +木质茎 1 +x:1 +不通 1 +x:1 +飞速 1 +x:1 +空峭 1 +x:1 +毫不客气 1 +x:1 +座舱 1 +x:1 +氟化物 1 +x:1 +卡口 1 +x:1 +座船 1 +x:1 +猎 13 +x:13 +木变石 1 +x:1 +橡皮饼 1 +x:1 +杂拌 1 +x:1 +八角亭 1 +x:1 +桃林镇 1 +x:1 +协调化 1 +x:1 +拖欠 1 +x:1 +汇制 1 +x:1 +涑水河 1 +x:1 +乒乓台 1 +x:1 +截取 1 +x:1 +正间房 1 +x:1 +太监 1 +x:1 +辞海 1 +x:1 +龟鹤遐龄 1 +x:1 +福利楼 1 +x:1 +摸奖 1 +x:1 +近影 1 +x:1 +丽水 1 +x:1 +陕西省 1 +x:1 +足球城 1 +x:1 +七姑八姨 1 +x:1 +意见书 1 +x:1 +此职 1 +x:1 +氨水 1 +x:1 +悲痛 1 +x:1 +强加于人 1 +x:1 +污言秽语 1 +x:1 +训练员 1 +x:1 +升学率 1 +x:1 +开学 1 +x:1 +流行色 1 +x:1 +炎陵 1 +x:1 +饮泣吞声 1 +x:1 +炮仗 1 +x:1 +一本万利 1 +x:1 +根式 1 +x:1 +慎言 1 +x:1 +氨气 1 +x:1 +芦丁 1 +x:1 +统计处 1 +x:1 +金钱关 1 +x:1 +拖欠额 1 +x:1 +空岗 1 +x:1 +架子猪 1 +x:1 +太白 1 +x:1 +上确村 1 +x:1 +娇揉造作 1 +x:1 +吊脚 1 +x:1 +群芳争艳 1 +x:1 +褒贬不一 1 +x:1 +防空法 1 +x:1 +脏腑 1 +x:1 +先农坛 1 +x:1 +立筒式 1 +x:1 +真理 1 +x:1 +古琴 1 +x:1 +凭着 1 +x:1 +白斑 1 +x:1 +队日 1 +x:1 +三十日 1 +x:1 +外罩 1 +x:1 +白文 1 +x:1 +厌食症 1 +x:1 +依次 1 +x:1 +非接触型 1 +x:1 +刷子 1 +x:1 +乐呵呵 1 +x:1 +崽 3 +x:3 +闯劲 1 +x:1 +亮泽 1 +x:1 +愕然 1 +x:1 +出售者 1 +x:1 +保墒 1 +x:1 +化学性 1 +x:1 +沧海一粟 1 +x:1 +临界点 1 +x:1 +铌 3 +x:3 +白日 1 +x:1 +清教徒 1 +x:1 +折伞 1 +x:1 +查当乡 1 +x:1 +外缘 1 +x:1 +鸡栅 1 +x:1 +柬埔寨 1 +x:1 +赝 1 +x:1 +不倒翁 1 +x:1 +周日 1 +x:1 +下基层 1 +x:1 +白旗 1 +x:1 +在理会 1 +x:1 +多利 1 +x:1 +普及部 1 +x:1 +压服 1 +x:1 +仰 17 +x:17 +质押人 1 +x:1 +韶 1 +x:1 +白族 1 +x:1 +人民币 1 +x:1 +搂 16 +x:16 +乡闾 1 +x:1 +不严肃性 1 +x:1 +四射 1 +x:1 +正常值 1 +x:1 +大方 1 +x:1 +外经 1 +x:1 +硝烟弥漫 1 +x:1 +大鹏湾 1 +x:1 +多变 1 +x:1 +活性染料 1 +x:1 +白搭 1 +x:1 +补时 1 +x:1 +多发 1 +x:1 +最初 1 +x:1 +科技链 1 +x:1 +供电 1 +x:1 +江轮 1 +x:1 +明晰性 1 +x:1 +浑厚 1 +x:1 +大料 1 +x:1 +待命 1 +x:1 +安全 1 +x:1 +换岗 1 +x:1 +指正 1 +x:1 +追逼 1 +x:1 +发电机组 1 +x:1 +茶文化 1 +x:1 +交易厅 1 +x:1 +五三乡 1 +x:1 +财阀式 1 +x:1 +白石灰 1 +x:1 +叙谈 1 +x:1 +保外 1 +x:1 +吃大锅饭 1 +x:1 +近年 1 +x:1 +大旱 1 +x:1 +木棉花 1 +x:1 +调节器 1 +x:1 +半流体 1 +x:1 +大城县 1 +x:1 +轩辕庙 1 +x:1 +集宁 1 +x:1 +哈工大 1 +x:1 +奔 197 +x:197 +联邦 1 +x:1 +防空洞 1 +x:1 +杨士乡 1 +x:1 +大早 1 +x:1 +大旨 1 +x:1 +大旗 1 +x:1 +中庄乡 1 +x:1 +激光头 1 +x:1 +驻场式 1 +x:1 +利润率 1 +x:1 +风情画 1 +x:1 +大族 1 +x:1 +岗楼 1 +x:1 +拒人千里 1 +x:1 +外线 1 +x:1 +集子 1 +x:1 +罗彻斯特 1 +x:1 +多半 1 +x:1 +大政 1 +x:1 +廉政日 1 +x:1 +最高分 1 +x:1 +编导家 1 +x:1 +砾岩 1 +x:1 +保姆 1 +x:1 +古画 1 +x:1 +砍饼 1 +x:1 +供货点 1 +x:1 +古田 1 +x:1 +楼盖 1 +x:1 +谦卑 1 +x:1 +冲昏 1 +x:1 +泽库县 1 +x:1 +麦 46 +x:46 +慎证 1 +x:1 +躬身 1 +x:1 +楼盘 1 +x:1 +蒙古国 1 +x:1 +西沙里村 1 +x:1 +显山露水 1 +x:1 +刁孽 1 +x:1 +御史中丞 1 +x:1 +冰结 1 +x:1 +炮位 1 +x:1 +大数 1 +x:1 +乒羽 1 +x:1 +灌阳 1 +x:1 +施救 1 +x:1 +发射点 1 +x:1 +沙文主义 1 +x:1 +联通 1 +x:1 +范市镇 1 +x:1 +诊区 1 +x:1 +折中 1 +x:1 +进攻 1 +x:1 +自相残害 1 +x:1 +披肩 1 +x:1 +收割期 1 +x:1 +卧床 1 +x:1 +枣园镇 1 +x:1 +竹布 1 +x:1 +大敌 1 +x:1 +根底 1 +x:1 +联退 1 +x:1 +蒜苗 1 +x:1 +重婚 1 +x:1 +弗吉尼亚 1 +x:1 +看来 1 +x:1 +长途费 1 +x:1 +空勤 1 +x:1 +闯将 1 +x:1 +铿锵 1 +x:1 +漏洞百出 1 +x:1 +指摘 1 +x:1 +贺礼 1 +x:1 +试用期 1 +x:1 +箜篌 1 +x:1 +看板 1 +x:1 +材积 1 +x:1 +花招儿 1 +x:1 +包装纸 1 +x:1 +登记表 1 +x:1 +安平 1 +x:1 +供稿 1 +x:1 +墨玉县 1 +x:1 +激光器 1 +x:1 +销地 1 +x:1 +见义勇为 1 +x:1 +富春江 1 +x:1 +披载 1 +x:1 +古窑 1 +x:1 +汇展 1 +x:1 +自鸣得意 1 +x:1 +服务 1 +x:1 +关铝 1 +x:1 +腆 1 +x:1 +磁强计 1 +x:1 +压榨 1 +x:1 +请罪信 1 +x:1 +农经所 1 +x:1 +开源节流 1 +x:1 +演播室 1 +x:1 +根儿 1 +x:1 +另悉 1 +x:1 +樵者 1 +x:1 +周正 1 +x:1 +碾子乡 1 +x:1 +镇海寺 1 +x:1 +大喜大悲 1 +x:1 +颠覆 1 +x:1 +笑料 1 +x:1 +主仆 1 +x:1 +黑松驿乡 1 +x:1 +茸毛 1 +x:1 +依旧 1 +x:1 +看望 1 +x:1 +引领 1 +x:1 +词尾 1 +x:1 +邋遢 1 +x:1 +武昌区 1 +x:1 +近况 1 +x:1 +岳父 1 +x:1 +押韵 1 +x:1 +微电机 1 +x:1 +户数 1 +x:1 +标准团 1 +x:1 +沥水 1 +x:1 +抗旱剂 1 +x:1 +电管站 1 +x:1 +空前 1 +x:1 +保国 1 +x:1 +扎耶尼 1 +x:1 +城雕委 1 +x:1 +胜机 1 +x:1 +炒冷饭 1 +x:1 +古稀 1 +x:1 +涮 1 +x:1 +收生婆 1 +x:1 +胳肢 1 +x:1 +勇争 1 +x:1 +烟草 1 +x:1 +硫磺石 1 +x:1 +柳河县 1 +x:1 +施放 1 +x:1 +遒劲 1 +x:1 +根冠 1 +x:1 +解放鞋 1 +x:1 +念道 1 +x:1 +辞掉 1 +x:1 +历年来 1 +x:1 +待定 1 +x:1 +集合 1 +x:1 +多少 1 +x:1 +安庆 1 +x:1 +驯致 1 +x:1 +真空 1 +x:1 +历朝历代 1 +x:1 +粗蛮 1 +x:1 +空分 1 +x:1 +安康 1 +x:1 +待客 1 +x:1 +外焰 1 +x:1 +阎家庄 1 +x:1 +服刑 1 +x:1 +汗碱 1 +x:1 +生物质 1 +x:1 +干爷娘 1 +x:1 +深浅 1 +x:1 +吊车 1 +x:1 +交易局 1 +x:1 +安度 1 +x:1 +绽破 1 +x:1 +大殿 1 +x:1 +昊 114 +x:114 +两用品 1 +x:1 +泰山北斗 1 +x:1 +立体片 1 +x:1 +躬耕 1 +x:1 +美工区 1 +x:1 +卑微 1 +x:1 +血燥型 1 +x:1 +锨 7 +x:7 +阔气 1 +x:1 +侯 229 +x:229 +奥运村 1 +x:1 +± 16 +x:16 +半生不熟 1 +x:1 +二重奏 1 +x:1 +幻想 1 +x:1 +瓜苗 1 +x:1 +在岗者 1 +x:1 +解放阁 1 +x:1 +泽国 1 +x:1 +协调局 1 +x:1 +保土 1 +x:1 +婉拒 1 +x:1 +学院派 1 +x:1 +宁夏 1 +x:1 +皮包 1 +x:1 +翻译史 1 +x:1 +三思而行 1 +x:1 +产方 1 +x:1 +穷追 1 +x:1 +摞 25 +x:25 +好好儿 1 +x:1 +关闸 1 +x:1 +人民军 1 +x:1 +劣行 1 +x:1 +润州区 1 +x:1 +麻布 1 +x:1 +关门 1 +x:1 +关闭 1 +x:1 +朝城县 1 +x:1 +最高峰 1 +x:1 +冰灯 1 +x:1 +线衣 1 +x:1 +虎尾春冰 1 +x:1 +大款 1 +x:1 +保育院 1 +x:1 +胳膊 1 +x:1 +引证 1 +x:1 +留言条 1 +x:1 +阕 1 +x:1 +医书 1 +x:1 +钻牛角尖 1 +x:1 +阎王爷 1 +x:1 +安心 1 +x:1 +断口 1 +x:1 +余暇 1 +x:1 +犀鸟 1 +x:1 +人民党 1 +x:1 +剧毒 1 +x:1 +效命 1 +x:1 +太祖 1 +x:1 +冰点 1 +x:1 +宜 67 +x:67 +我市 1 +x:1 +白檀 1 +x:1 +河南队 1 +x:1 +口出怨言 1 +x:1 +实收率 1 +x:1 +传播学 1 +x:1 +随处可闻 1 +x:1 +本周一 1 +x:1 +破袭战 1 +x:1 +缉私处 1 +x:1 +牛肉饼 1 +x:1 +包装罐 1 +x:1 +泥河镇 1 +x:1 +坦陈 1 +x:1 +大步 1 +x:1 +勒 19 +x:19 +大正 1 +x:1 +扶上马 1 +x:1 +胳臂 1 +x:1 +压根 1 +x:1 +关镇 1 +x:1 +医专 1 +x:1 +镇直 1 +x:1 +安徽 1 +x:1 +进款 1 +x:1 +机言巧语 1 +x:1 +受让人 1 +x:1 +百合 1 +x:1 +标准型 1 +x:1 +瓷雕 1 +x:1 +古筝 1 +x:1 +漆器 1 +x:1 +汇差 1 +x:1 +嗅神经 1 +x:1 +硝酸甘油 1 +x:1 +关隘 1 +x:1 +肇 2 +x:2 +可逆 1 +x:1 +胆识过人 1 +x:1 +守擂 1 +x:1 +独此一家 1 +x:1 +推销部 1 +x:1 +汇市 1 +x:1 +低价位 1 +x:1 +蜂窝 1 +x:1 +安居 1 +x:1 +拖期 1 +x:1 +洋洋得意 1 +x:1 +证件费 1 +x:1 +偏关县 1 +x:1 +安山 1 +x:1 +请愿信 1 +x:1 +毛遂自荐 1 +x:1 +夏令时 1 +x:1 +莱 4 +x:4 +产油井 1 +x:1 +慧眼识珠 1 +x:1 +笑柄 1 +x:1 +大梁 1 +x:1 +咱俩 1 +x:1 +减肥 1 +x:1 +持有额 1 +x:1 +两用型 1 +x:1 +步兵师 1 +x:1 +奥地利队 1 +x:1 +葵花仁 1 +x:1 +青面獠牙 1 +x:1 +缓缴 1 +x:1 +怒气冲天 1 +x:1 +痕 3 +x:3 +关雎 1 +x:1 +剧校 1 +x:1 +指明 1 +x:1 +对外司 1 +x:1 +科技馆 1 +x:1 +门阀 1 +x:1 +祢 8 +x:8 +大棒 1 +x:1 +鼎城 1 +x:1 +榧子 1 +x:1 +缓缓 1 +x:1 +权衡 1 +x:1 +爷们儿 1 +x:1 +大棚 1 +x:1 +泯 8 +x:8 +遇险者 1 +x:1 +瘦梅 1 +x:1 +姑娘儿 1 +x:1 +从严治政 1 +x:1 +赐福 1 +x:1 +信号枪 1 +x:1 +大样 1 +x:1 +玉龙 1 +x:1 +七 637 +x:637 +向军北里 1 +x:1 +太空 1 +x:1 +缕空 1 +x:1 +伊斯兰堡 1 +x:1 +狂草 1 +x:1 +鱼目混珠 1 +x:1 +农用车 1 +x:1 +欢叫声 1 +x:1 +大校 1 +x:1 +日光 1 +x:1 +多幕 1 +x:1 +不齿 1 +x:1 +包钢 1 +x:1 +根号 1 +x:1 +用户数 1 +x:1 +宾馆化 1 +x:1 +大树 1 +x:1 +猛攻 1 +x:1 +关防 1 +x:1 +咸镜南道 1 +x:1 +多年 1 +x:1 +查结 1 +x:1 +计征 1 +x:1 +乱石坡 1 +x:1 +冬虫夏草 1 +x:1 +宜阳县 1 +x:1 +镇痛 1 +x:1 +公示制 1 +x:1 +大桥 1 +x:1 +奋笔直书 1 +x:1 +进栏 1 +x:1 +树墩子 1 +x:1 +地勘处 1 +x:1 +农牧场 1 +x:1 +倡议者 1 +x:1 +豆架 1 +x:1 +安岳 1 +x:1 +吊起 1 +x:1 +劫款 1 +x:1 +捱 1 +x:1 +家务活 1 +x:1 +进校 1 +x:1 +结对联手 1 +x:1 +社科类 1 +x:1 +忘却 1 +x:1 +大案 1 +x:1 +家弦户诵 1 +x:1 +候车厅 1 +x:1 +纵深 1 +x:1 +多心 1 +x:1 +岸区 1 +x:1 +山丘区 1 +x:1 +坏分子 1 +x:1 +东山县 1 +x:1 +脸皮薄 1 +x:1 +吹风机 1 +x:1 +不足以 1 +x:1 +野鹤闲云 1 +x:1 +蔚然成风 1 +x:1 +效国 1 +x:1 +标价牌 1 +x:1 +过敏性 1 +x:1 +空气层 1 +x:1 +大概 1 +x:1 +栾老 1 +x:1 +咱们 1 +x:1 +三网一榜 1 +x:1 +凯歌 1 +x:1 +外延 1 +x:1 +仰头 1 +x:1 +指望 1 +x:1 +麻尾 1 +x:1 +城步 1 +x:1 +座车 1 +x:1 +白桦 1 +x:1 +冰片 1 +x:1 +积蓄量 1 +x:1 +城关村 1 +x:1 +雷鸣电闪 1 +x:1 +大雪纷飞 1 +x:1 +隐蔽型 1 +x:1 +智能型 1 +x:1 +偷漏税 1 +x:1 +麻将 1 +x:1 +空军 1 +x:1 +铸币厂 1 +x:1 +近前 1 +x:1 +白案 1 +x:1 +李子酒 1 +x:1 +登记证 1 +x:1 +推力器 1 +x:1 +拉郎配 1 +x:1 +正科级 1 +x:1 +丝绵被 1 +x:1 +东山区 1 +x:1 +眼中钉 1 +x:1 +药理系 1 +x:1 +苏和区 1 +x:1 +白梨 1 +x:1 +握竿 1 +x:1 +遮遮掩掩 1 +x:1 +辛辛那提 1 +x:1 +多彩 1 +x:1 +三等功 1 +x:1 +贯 8 +x:8 +策划者 1 +x:1 +酒窝儿 1 +x:1 +大楷 1 +x:1 +多式 1 +x:1 +致富机 1 +x:1 +岗旁 1 +x:1 +一储到底 1 +x:1 +大楼 1 +x:1 +裁谈会 1 +x:1 +来鸿 1 +x:1 +空儿 1 +x:1 +思绪万千 1 +x:1 +敲山震虎 1 +x:1 +索赔案 1 +x:1 +供种 1 +x:1 +医患 1 +x:1 +靠山吃山 1 +x:1 +萨瓦河 1 +x:1 +篓子 1 +x:1 +笑星 1 +x:1 +采访服 1 +x:1 +拖曳 1 +x:1 +犹犹豫豫 1 +x:1 +梦牵魂绕 1 +x:1 +公共性 1 +x:1 +白棉 1 +x:1 +里庄镇 1 +x:1 +白棋 1 +x:1 +薛套村 1 +x:1 +硬座票 1 +x:1 +劣质 1 +x:1 +先锋派 1 +x:1 +婚事 1 +x:1 +出人意外 1 +x:1 +劣货 1 +x:1 +骏 23 +x:23 +大概其 1 +x:1 +无悔无怨 1 +x:1 +后人 1 +x:1 +片纸只字 1 +x:1 +单层次 1 +x:1 +霍布逊湖 1 +x:1 +凌驾 1 +x:1 +管窥 1 +x:1 +排龙乡 1 +x:1 +大溪 1 +x:1 +碣 1 +x:1 +巴拉那河 1 +x:1 +后于 1 +x:1 +宗匠 1 +x:1 +大溜 1 +x:1 +石河村 1 +x:1 +常务委员 1 +x:1 +前世 1 +x:1 +销区 1 +x:1 +辞条 1 +x:1 +西大山 1 +x:1 +上皮组织 1 +x:1 +出口成章 1 +x:1 +握紧 1 +x:1 +婚介 1 +x:1 +标注值 1 +x:1 +栈道 1 +x:1 +后代 1 +x:1 +不拘小节 1 +x:1 +呐 10 +x:10 +后任 1 +x:1 +成事 1 +x:1 +兰摧玉折 1 +x:1 +查破 1 +x:1 +分兵把口 1 +x:1 +姑子 1 +x:1 +撒手锏 1 +x:1 +艺能 1 +x:1 +树隙 1 +x:1 +树障 1 +x:1 +断垣残壁 1 +x:1 +臭皮囊 1 +x:1 +毛收入 1 +x:1 +擀制 1 +x:1 +精神焕发 1 +x:1 +绷 17 +x:17 +泳衣 1 +x:1 +玉门关 1 +x:1 +标准分 1 +x:1 +刷写 1 +x:1 +泽及 1 +x:1 +百兽 1 +x:1 +体育部 1 +x:1 +外界 1 +x:1 +统计司 1 +x:1 +室长 1 +x:1 +鲤鱼 1 +x:1 +戒断率 1 +x:1 +膘肥体壮 1 +x:1 +大港 1 +x:1 +贴切 1 +x:1 +制皮厂 1 +x:1 +招投标率 1 +x:1 +朋友 1 +x:1 +罪人 1 +x:1 +精子库 1 +x:1 +华达呢 1 +x:1 +漆匠 1 +x:1 +保安科 1 +x:1 +后业 1 +x:1 +披读 1 +x:1 +劳燕分飞 1 +x:1 +后世 1 +x:1 +浮来山 1 +x:1 +退化 1 +x:1 +货运室 1 +x:1 +供给 1 +x:1 +对面 1 +x:1 +埃因霍温 1 +x:1 +看样子 1 +x:1 +职工部 1 +x:1 +棘 2 +x:2 +成份 1 +x:1 +高能所 1 +x:1 +红11团 1 +x:1 +泳装 1 +x:1 +外生 1 +x:1 +继承国 1 +x:1 +大湖 1 +x:1 +须子 1 +x:1 +外甥 1 +x:1 +外用 1 +x:1 +婚书 1 +x:1 +短巴巴 1 +x:1 +连丰 1 +x:1 +统计厅 1 +x:1 +石库门 1 +x:1 +呼叫器 1 +x:1 +零星 1 +x:1 +原子球宫 1 +x:1 +笑意 1 +x:1 +保单 1 +x:1 +周游 1 +x:1 +白面儿 1 +x:1 +大澳 1 +x:1 +崇山峻岭 1 +x:1 +芭蕾舞界 1 +x:1 +冰球 1 +x:1 +宜黄 1 +x:1 +充耳不闻 1 +x:1 +透顶 1 +x:1 +保协 1 +x:1 +普法 1 +x:1 +定位仪 1 +x:1 +迟误 1 +x:1 +打家劫舍 1 +x:1 +软骨 1 +x:1 +洪家拳 1 +x:1 +姑娘 1 +x:1 +包装箱 1 +x:1 +婚侣 1 +x:1 +小不点儿 1 +x:1 +多姿 1 +x:1 +多彩多姿 1 +x:1 +寒风料峭 1 +x:1 +保卫 1 +x:1 +保北 1 +x:1 +蓄谋 1 +x:1 +理论界 1 +x:1 +流言蜚语 1 +x:1 +伊拜尔 1 +x:1 +核技术 1 +x:1 +雪片 1 +x:1 +婚俗 1 +x:1 +政研室 1 +x:1 +峡 16 +x:16 +调解队 1 +x:1 +歧途 1 +x:1 +登记账 1 +x:1 +有隙可乘 1 +x:1 +婉曲 1 +x:1 +标准化 1 +x:1 +转 549 +x:549 +可靠 1 +x:1 +看成 1 +x:1 +聊天 1 +x:1 +姑婆 1 +x:1 +登记费 1 +x:1 +制海权 1 +x:1 +规划会 1 +x:1 +新义州 1 +x:1 +粮经型 1 +x:1 +标准台 1 +x:1 +窍门 1 +x:1 +神经衰弱 1 +x:1 +日成交额 1 +x:1 +江原道 1 +x:1 +大漠 1 +x:1 +板房沟 1 +x:1 +不顾 1 +x:1 +对阵 1 +x:1 +透风 1 +x:1 +凸版 1 +x:1 +月弯残雪 1 +x:1 +查私 1 +x:1 +肉食鸡 1 +x:1 +大漆 1 +x:1 +成仁 1 +x:1 +付款部 1 +x:1 +擦屁股 1 +x:1 +新式 1 +x:1 +销势 1 +x:1 +计生 1 +x:1 +猛打 1 +x:1 +猛扑 1 +x:1 +安定 1 +x:1 +深信不疑 1 +x:1 +看报 1 +x:1 +多多许 1 +x:1 +浅见 1 +x:1 +反中子 1 +x:1 +行色匆匆 1 +x:1 +投放量 1 +x:1 +评估费 1 +x:1 +多多 1 +x:1 +安宁 1 +x:1 +大潮 1 +x:1 +空地 1 +x:1 +依恋 1 +x:1 +八一队 1 +x:1 +补漏 1 +x:1 +冰瓶 1 +x:1 +查禁 1 +x:1 +跌破 1 +x:1 +安家 1 +x:1 +姑嫂 1 +x:1 +多头 1 +x:1 +勇涉 1 +x:1 +权谋 1 +x:1 +卫星赛 1 +x:1 +月钱 1 +x:1 +大河 1 +x:1 +小道儿 1 +x:1 +安塞 1 +x:1 +空哥 1 +x:1 +畸轻畸重 1 +x:1 +大油 1 +x:1 +东北军 1 +x:1 +装疯卖傻 1 +x:1 +婚介业 1 +x:1 +维文 1 +x:1 +姑夫 1 +x:1 +查究 1 +x:1 +泪人儿 1 +x:1 +灭鼠 1 +x:1 +硬板板的 1 +x:1 +十五中 1 +x:1 +民办公助 1 +x:1 +零位 1 +x:1 +我盟 1 +x:1 +保健 1 +x:1 +仿制 1 +x:1 +引黄 1 +x:1 +至极 1 +x:1 +回肠荡气 1 +x:1 +俚歌 1 +x:1 +慢工 1 +x:1 +昼间 1 +x:1 +稀有金属 1 +x:1 +标准值 1 +x:1 +家电城 1 +x:1 +变温动物 1 +x:1 +大泽 1 +x:1 +钢质 1 +x:1 +西药店 1 +x:1 +训练局 1 +x:1 +混淆黑白 1 +x:1 +逢场作戏 1 +x:1 +屈光度 1 +x:1 +金龟子 1 +x:1 +阔步 1 +x:1 +光密媒质 1 +x:1 +白浪 1 +x:1 +佛山市 1 +x:1 +大法 1 +x:1 +遭难 1 +x:1 +现名 1 +x:1 +相见恨晚 1 +x:1 +沉香亭 1 +x:1 +保值 1 +x:1 +进油 1 +x:1 +多晶硅 1 +x:1 +协调学 1 +x:1 +蚌雕 1 +x:1 +周济 1 +x:1 +魔芋 1 +x:1 +专递 1 +x:1 +紫橄榄菜 1 +x:1 +蒙特卡洛 1 +x:1 +大泊 1 +x:1 +亚种 1 +x:1 +大水 1 +x:1 +周转金 1 +x:1 +瓜蔓 1 +x:1 +大幅让利 1 +x:1 +八一镇 1 +x:1 +腱鞘 1 +x:1 +根基 1 +x:1 +流行歌曲 1 +x:1 +幻术 1 +x:1 +具备 1 +x:1 +大气 1 +x:1 +待工 1 +x:1 +联络员 1 +x:1 +鼻咽癌 1 +x:1 +截子 1 +x:1 +借款者 1 +x:1 +对错 1 +x:1 +大氅 1 +x:1 +倾心吐胆 1 +x:1 +标准像 1 +x:1 +姑妈 1 +x:1 +土堤仓 1 +x:1 +作代会 1 +x:1 +抽象劳动 1 +x:1 +外省 1 +x:1 +托斯卡纳 1 +x:1 +积劳成疾 1 +x:1 +泽兰 1 +x:1 +触雷 1 +x:1 +盛况空前 1 +x:1 +农牧化 1 +x:1 +鳌 2 +x:2 +劣迹 1 +x:1 +空吸 1 +x:1 +比格尔 1 +x:1 +戈梅里 1 +x:1 +合议厅 1 +x:1 +集刊 1 +x:1 +探路者 1 +x:1 +包门 1 +x:1 +姑姑 1 +x:1 +古籍 1 +x:1 +大江 1 +x:1 +股金款 1 +x:1 +大汛 1 +x:1 +追查 1 +x:1 +水涨船高 1 +x:1 +监管部门 1 +x:1 +浩然之气 1 +x:1 +依据 1 +x:1 +大汉 1 +x:1 +多味斋 1 +x:1 +白水 1 +x:1 +诊察 1 +x:1 +小辫子 1 +x:1 +拦阻 1 +x:1 +我矿 1 +x:1 +五步蛇 1 +x:1 +大涧 1 +x:1 +零乱 1 +x:1 +老虎凳 1 +x:1 +对比性 1 +x:1 +交易室 1 +x:1 +逆定理 1 +x:1 +蜂群 1 +x:1 +进深 1 +x:1 +安好 1 +x:1 +角色 1 +x:1 +彻头彻尾 1 +x:1 +权责 1 +x:1 +大涝 1 +x:1 +意见本 1 +x:1 +多寡 1 +x:1 +保养 1 +x:1 +鼎力 1 +x:1 +自传体 1 +x:1 +外相 1 +x:1 +大醇小疵 1 +x:1 +上星期 1 +x:1 +保全 1 +x:1 +次生 1 +x:1 +瞪眼 1 +x:1 +效力 1 +x:1 +安多 1 +x:1 +检漏仪 1 +x:1 +淤积量 1 +x:1 +学术团体 1 +x:1 +岸坡 1 +x:1 +蠢动 1 +x:1 +庙滩镇 1 +x:1 +船舶业 1 +x:1 +安外 1 +x:1 +软食 1 +x:1 +白汤 1 +x:1 +兔 29 +x:29 +吊装 1 +x:1 +石榴庄村 1 +x:1 +柳堡 1 +x:1 +腊月十六 1 +x:1 +流程图 1 +x:1 +空喊 1 +x:1 +福利性 1 +x:1 +效劳 1 +x:1 +零上 1 +x:1 +取巧 1 +x:1 +板房沟乡 1 +x:1 +集县 1 +x:1 +碾子 1 +x:1 +亭子间 1 +x:1 +腴 1 +x:1 +诊室 1 +x:1 +肄业 1 +x:1 +宁心 1 +x:1 +打前站 1 +x:1 +拖把 1 +x:1 +白油 1 +x:1 +丽日 1 +x:1 +技术奖 1 +x:1 +低收入者 1 +x:1 +保准 1 +x:1 +零件 1 +x:1 +多孔 1 +x:1 +难辞其咎 1 +x:1 +地勘局 1 +x:1 +多子 1 +x:1 +大洪 1 +x:1 +白沫 1 +x:1 +经典性 1 +x:1 +保函 1 +x:1 +大洞 1 +x:1 +白沟 1 +x:1 +松子糖 1 +x:1 +白沙 1 +x:1 +泄洪洞 1 +x:1 +割晒机 1 +x:1 +砭石 1 +x:1 +巧取豪夺 1 +x:1 +旁岔儿 1 +x:1 +农神节 1 +x:1 +大洋 1 +x:1 +大义灭亲 1 +x:1 +贤淑 1 +x:1 +大海 1 +x:1 +歃 1 +x:1 +流行语 1 +x:1 +冰盖 1 +x:1 +拖拉 1 +x:1 +瓜葛 1 +x:1 +念青 1 +x:1 +岸基 1 +x:1 +近因 1 +x:1 +汇寄 1 +x:1 +心病 1 +x:1 +煦煦 1 +x:1 +周波 1 +x:1 +待岗 1 +x:1 +幻景 1 +x:1 +大浪 1 +x:1 +三边四荒 1 +x:1 +季 183 +x:183 +酬报 1 +x:1 +粉末状 1 +x:1 +缕缕 1 +x:1 +智能化 1 +x:1 +我省 1 +x:1 +滇池 1 +x:1 +宁德 1 +x:1 +眼镜片 1 +x:1 +百分 1 +x:1 +遥感 1 +x:1 +作文本 1 +x:1 +挣断 1 +x:1 +规划办 1 +x:1 +梅花山 1 +x:1 +引论 1 +x:1 +主动权 1 +x:1 +农委 1 +x:1 +港西港池 1 +x:1 +远华队 1 +x:1 +身子 1 +x:1 +鹅毛雪 1 +x:1 +身孕 1 +x:1 +平原 1 +x:1 +后劲 1 +x:1 +对讲 1 +x:1 +永康市 1 +x:1 +白猫 1 +x:1 +悖晦 1 +x:1 +非线型 1 +x:1 +外交官 1 +x:1 +东北侧 1 +x:1 +秘鲁海 1 +x:1 +潭水 1 +x:1 +岳 66 +x:66 +突击队 1 +x:1 +遂平 1 +x:1 +薹 1 +x:1 +驻京办 1 +x:1 +供货期 1 +x:1 +罪不容赦 1 +x:1 +大狱 1 +x:1 +小曹娥镇 1 +x:1 +后勤 1 +x:1 +缓收 1 +x:1 +合霉素 1 +x:1 +阔略 1 +x:1 +发射机 1 +x:1 +零儿 1 +x:1 +纠察队 1 +x:1 +物理奖 1 +x:1 +对证 1 +x:1 +保举 1 +x:1 +生吞活咽 1 +x:1 +披露 1 +x:1 +对话 1 +x:1 +实业家 1 +x:1 +古拙 1 +x:1 +风烛残年 1 +x:1 +运动史 1 +x:1 +蝶岛 1 +x:1 +风吹雨淋 1 +x:1 +菠菜 1 +x:1 +大爷 1 +x:1 +良辰美景 1 +x:1 +升班马 1 +x:1 +标准件 1 +x:1 +标准价 1 +x:1 +寸步不让 1 +x:1 +柚树 1 +x:1 +逗笑 1 +x:1 +让渡 1 +x:1 +腊月十五 1 +x:1 +信誉度 1 +x:1 +无会周 1 +x:1 +保价 1 +x:1 +引聘 1 +x:1 +医坛 1 +x:1 +麻醉剂 1 +x:1 +狂饮 1 +x:1 +日本籍 1 +x:1 +天晓得 1 +x:1 +成也萧何 1 +x:1 +后刘 1 +x:1 +聊城市 1 +x:1 +月票 1 +x:1 +石湾 1 +x:1 +传真电报 1 +x:1 +白玉 1 +x:1 +玩味 1 +x:1 +婚前 1 +x:1 +岗组 1 +x:1 +通天河 1 +x:1 +因循守旧 1 +x:1 +值长 1 +x:1 +农经站 1 +x:1 +分离主义 1 +x:1 +无足轻重 1 +x:1 +发射架 1 +x:1 +制高点 1 +x:1 +大牢 1 +x:1 +外交学 1 +x:1 +白班 1 +x:1 +炮塔 1 +x:1 +闻讯而来 1 +x:1 +发射极 1 +x:1 +注 75 +x:75 +滴露 1 +x:1 +大牙 1 +x:1 +保人 1 +x:1 +大片 1 +x:1 +踏实 1 +x:1 +身家 1 +x:1 +韵味儿 1 +x:1 +演出者 1 +x:1 +大牌 1 +x:1 +三居室 1 +x:1 +折头 1 +x:1 +次次 1 +x:1 +保佑 1 +x:1 +形骸 1 +x:1 +值钱 1 +x:1 +引致 1 +x:1 +后厢 1 +x:1 +收订 1 +x:1 +东北亚 1 +x:1 +滋养 1 +x:1 +马鼻疽 1 +x:1 +不容乐观 1 +x:1 +保住 1 +x:1 +不明不白 1 +x:1 +狂飙 1 +x:1 +生物链 1 +x:1 +冰样 1 +x:1 +放像机 1 +x:1 +行李牌 1 +x:1 +落沙坡 1 +x:1 +标准体 1 +x:1 +个 17171 +x:17171 +购票卡 1 +x:1 +据理力争 1 +x:1 +效果图 1 +x:1 +土政策 1 +x:1 +诺瓦拉市 1 +x:1 +款式 1 +x:1 +堵车 1 +x:1 +大王 1 +x:1 +漫人 1 +x:1 +生物钟 1 +x:1 +狐假虎威 1 +x:1 +贵阳市 1 +x:1 +灌肠 1 +x:1 +瓷花瓶 1 +x:1 +鹊 2 +x:2 +的话 1 +x:1 +婚变 1 +x:1 +后台 1 +x:1 +大班 1 +x:1 +查收 1 +x:1 +嫡派 1 +x:1 +规划司 1 +x:1 +南社村 1 +x:1 +纵容 1 +x:1 +民主派 1 +x:1 +图腾物 1 +x:1 +号子声 1 +x:1 +依存权 1 +x:1 +苦功夫 1 +x:1 +土堡子村 1 +x:1 +端平 1 +x:1 +古提 1 +x:1 +胜绩 1 +x:1 +以假乱真 1 +x:1 +真挚 1 +x:1 +时间篇 1 +x:1 +遂心 1 +x:1 +原汁原味 1 +x:1 +端庄 1 +x:1 +悲戚 1 +x:1 +登记量 1 +x:1 +和衷共济 1 +x:1 +立体化 1 +x:1 +钡核 1 +x:1 +关贸 1 +x:1 +左中方 1 +x:1 +氩 1 +x:1 +吞云吐雾 1 +x:1 +户籍 1 +x:1 +遥遥相对 1 +x:1 +低气压区 1 +x:1 +帮助者 1 +x:1 +宗亲 1 +x:1 +辞章 1 +x:1 +且末县 1 +x:1 +保修 1 +x:1 +十一时 1 +x:1 +款待 1 +x:1 +沙场路 1 +x:1 +冰棒 1 +x:1 +医嘱 1 +x:1 +吨/日 1 +x:1 +文史哲 1 +x:1 +豆粕 1 +x:1 +妻妾 1 +x:1 +南塘镇 1 +x:1 +十字 1 +x:1 +豆粉 1 +x:1 +查新 1 +x:1 +冰棍 1 +x:1 +触角 1 +x:1 +冰棱 1 +x:1 +白狐 1 +x:1 +农妇 1 +x:1 +主创 1 +x:1 +杏林镇 1 +x:1 +喊叫声 1 +x:1 +北空 1 +x:1 +销价 1 +x:1 +农八师 1 +x:1 +官渡人声 1 +x:1 +营盘镇 1 +x:1 +触觉 1 +x:1 +油渣果 1 +x:1 +八国联军 1 +x:1 +十五分 1 +x:1 +票根 1 +x:1 +颇 451 +x:451 +私生子 1 +x:1 +什么 1 +x:1 +瓷质 1 +x:1 +风雷 1 +x:1 +大炮 1 +x:1 +义利 1 +x:1 +院庆 1 +x:1 +外军 1 +x:1 +剑齿象 1 +x:1 +心惊胆战 1 +x:1 +劫 17 +x:17 +主义者 1 +x:1 +多糖类 1 +x:1 +雷雨云 1 +x:1 +零卖 1 +x:1 +采访组 1 +x:1 +膨胀 1 +x:1 +电讯部 1 +x:1 +饿死事小 1 +x:1 +可行 1 +x:1 +窥探者 1 +x:1 +探矿权 1 +x:1 +黄狮村 1 +x:1 +他乡人 1 +x:1 +拖网 1 +x:1 +物理学 1 +x:1 +身外 1 +x:1 +养痈成患 1 +x:1 +产油国 1 +x:1 +明 429 +x:429 +外因论 1 +x:1 +镇海 1 +x:1 +蜂拥 1 +x:1 +查明 1 +x:1 +缓期 1 +x:1 +贴膜车 1 +x:1 +胎婴儿 1 +x:1 +大烟 1 +x:1 +产后风 1 +x:1 +对视 1 +x:1 +潮州籍 1 +x:1 +色织布 1 +x:1 +圣诞 1 +x:1 +对角 1 +x:1 +势态 1 +x:1 +维棉布 1 +x:1 +平台 1 +x:1 +古怪 1 +x:1 +渴望 1 +x:1 +粗鲁 1 +x:1 +仅次于 1 +x:1 +查封 1 +x:1 +亮堂 1 +x:1 +一塌糊涂 1 +x:1 +小褂 1 +x:1 +撑紧轮 1 +x:1 +磁山镇 1 +x:1 +万众一心 1 +x:1 +供货方 1 +x:1 +云霄县 1 +x:1 +折子 1 +x:1 +人工费 1 +x:1 +吊销 1 +x:1 +大炮仗 1 +x:1 +虚晃一枪 1 +x:1 +解放路 1 +x:1 +渲染性 1 +x:1 +妆饰 1 +x:1 +灌草 1 +x:1 +悲愤 1 +x:1 +十堰 1 +x:1 +办学者 1 +x:1 +婚债 1 +x:1 +真性 1 +x:1 +蜂房 1 +x:1 +身姿 1 +x:1 +白熊 1 +x:1 +冰毒 1 +x:1 +大灶 1 +x:1 +单人床 1 +x:1 +密 32 +x:32 +灭菌 1 +x:1 +婚假 1 +x:1 +枣 28 +x:28 +包销 1 +x:1 +掌声 1 +x:1 +保育费 1 +x:1 +舞蹈团 1 +x:1 +持有者 1 +x:1 +崆岭群 1 +x:1 +园艺系 1 +x:1 +大火 1 +x:1 +赋青镇 1 +x:1 +厚墩墩 1 +x:1 +书套 1 +x:1 +长远型 1 +x:1 +指纹 1 +x:1 +筱 1 +x:1 +地铁口 1 +x:1 +亚方 1 +x:1 +对襟 1 +x:1 +绝对观念 1 +x:1 +无凭无据 1 +x:1 +集中 1 +x:1 +现如今 1 +x:1 +指数函数 1 +x:1 +后冬 1 +x:1 +惊蛰 1 +x:1 +神经中枢 1 +x:1 +输 186 +x:186 +吊针 1 +x:1 +巴里巴里 1 +x:1 +余晖 1 +x:1 +顾不了 1 +x:1 +产品链 1 +x:1 +妻子 1 +x:1 +效仿 1 +x:1 +悲悼 1 +x:1 +握手 1 +x:1 +吊钩 1 +x:1 +∶ 17 +x:17 +履痕 1 +x:1 +非住宅 1 +x:1 +悲悯 1 +x:1 +依纪 1 +x:1 +关进 1 +x:1 +十一月 1 +x:1 +白灰 1 +x:1 +石棺 1 +x:1 +笑纹 1 +x:1 +楼房 1 +x:1 +指缝 1 +x:1 +促进派 1 +x:1 +非技术 1 +x:1 +金牌数 1 +x:1 +冰橇 1 +x:1 +失明 1 +x:1 +其妻 1 +x:1 +姜李村 1 +x:1 +蠢人 1 +x:1 +内阁制 1 +x:1 +吊链 1 +x:1 +曹市镇 1 +x:1 +吊铺 1 +x:1 +公垂线 1 +x:1 +蠢事 1 +x:1 +救苦救难 1 +x:1 +哈尔霍马 1 +x:1 +戟士 1 +x:1 +辅助 1 +x:1 +皂白 1 +x:1 +悲惨 1 +x:1 +畅想 1 +x:1 +行道树 1 +x:1 +狮泉 1 +x:1 +蝶形 1 +x:1 +集体 1 +x:1 +深指 1 +x:1 +工艺系 1 +x:1 +查查 1 +x:1 +白点 1 +x:1 +后进生 1 +x:1 +真意 1 +x:1 +蝶影 1 +x:1 +悲怆 1 +x:1 +瘦煤 1 +x:1 +迎宾松 1 +x:1 +钢都 1 +x:1 +不白之冤 1 +x:1 +喜剧片 1 +x:1 +浪迹天涯 1 +x:1 +戡 2 +x:2 +古意 1 +x:1 +票务 1 +x:1 +耍排场 1 +x:1 +伙计 1 +x:1 +侨 33 +x:33 +引荐 1 +x:1 +锯 13 +x:13 +豆绿 1 +x:1 +书堆 1 +x:1 +融资额 1 +x:1 +乱石丛 1 +x:1 +手风琴 1 +x:1 +棋战 1 +x:1 +了无生趣 1 +x:1 +毫微米 1 +x:1 +农牧业 1 +x:1 +冻结室 1 +x:1 +导表演 1 +x:1 +对衬 1 +x:1 +权重 1 +x:1 +同心县 1 +x:1 +集会 1 +x:1 +科技史 1 +x:1 +可观 1 +x:1 +可见 1 +x:1 +白热 1 +x:1 +告别游 1 +x:1 +卢湾 1 +x:1 +联营 1 +x:1 +报盘 1 +x:1 +中外运 1 +x:1 +百业 1 +x:1 +潞西 1 +x:1 +棋手 1 +x:1 +悲恸 1 +x:1 +野人 1 +x:1 +白烛 1 +x:1 +楚门镇 1 +x:1 +小视 1 +x:1 +聚变 1 +x:1 +硫磺泉 1 +x:1 +赦免 1 +x:1 +对街 1 +x:1 +百万 1 +x:1 +运动型 1 +x:1 +芦山 1 +x:1 +操作系统 1 +x:1 +来自 1 +x:1 +白眼 1 +x:1 +弓腰 1 +x:1 +冰洞 1 +x:1 +生物量 1 +x:1 +不致 1 +x:1 +蒜黄 1 +x:1 +不至 1 +x:1 +无精打采 1 +x:1 +缓慢 1 +x:1 +篮联 1 +x:1 +迁安市 1 +x:1 +重者 1 +x:1 +身形 1 +x:1 +凼仔 1 +x:1 +在校 1 +x:1 +狗急跳墙 1 +x:1 +冻裂 1 +x:1 +暗箭伤人 1 +x:1 +服从 1 +x:1 +陡然生凉 1 +x:1 +大华府 1 +x:1 +三番五次 1 +x:1 +坦佩雷 1 +x:1 +身影 1 +x:1 +巍山县 1 +x:1 +鸿篇 1 +x:1 +大同道 1 +x:1 +谈锋 1 +x:1 +院墙 1 +x:1 +玉汝于成 1 +x:1 +守山人 1 +x:1 +自由日 1 +x:1 +流于形式 1 +x:1 +后园 1 +x:1 +泳道 1 +x:1 +泛非大 1 +x:1 +老大哥 1 +x:1 +零售 1 +x:1 +院士 1 +x:1 +堪培拉市 1 +x:1 +恢 1 +x:1 +小进即满 1 +x:1 +树身 1 +x:1 +权限 1 +x:1 +忝 1 +x:1 +端子 1 +x:1 +隆尧县 1 +x:1 +冰海 1 +x:1 +蒙在鼓里 1 +x:1 +大盐 1 +x:1 +测评票 1 +x:1 +歪 25 +x:25 +不一会 1 +x:1 +猴声 1 +x:1 +大盘 1 +x:1 +对进 1 +x:1 +字体 1 +x:1 +妻小 1 +x:1 +志留纪 1 +x:1 +司马台 1 +x:1 +锁 68 +x:68 +豆科 1 +x:1 +供暖 1 +x:1 +铸锅厂 1 +x:1 +战俘 1 +x:1 +喇叭沟门 1 +x:1 +宣传月 1 +x:1 +圣贤 1 +x:1 +补白 1 +x:1 +单科 1 +x:1 +其干 1 +x:1 +方寸已乱 1 +x:1 +蛰居 1 +x:1 +弧光灯 1 +x:1 +剧目 1 +x:1 +潭峪沟 1 +x:1 +豆种 1 +x:1 +绝对化 1 +x:1 +氏族 1 +x:1 +空乏 1 +x:1 +修脚师 1 +x:1 +继承人 1 +x:1 +布底鞋 1 +x:1 +票源 1 +x:1 +新莱昂州 1 +x:1 +晌午 1 +x:1 +真是 1 +x:1 +歧视 1 +x:1 +空乘 1 +x:1 +邵东县 1 +x:1 +歧见 1 +x:1 +外海 1 +x:1 +洋河弄 1 +x:1 +火箭弹 1 +x:1 +书影 1 +x:1 +看管 1 +x:1 +查当山 1 +x:1 +白矾 1 +x:1 +氨纶 1 +x:1 +瘦瘠 1 +x:1 +跃至 1 +x:1 +书形 1 +x:1 +胚盘 1 +x:1 +十堰市 1 +x:1 +烘 3 +x:3 +摘发 1 +x:1 +摘取 1 +x:1 +空串 1 +x:1 +拦路 1 +x:1 +沙巴州 1 +x:1 +书录 1 +x:1 +工人党 1 +x:1 +霜花 1 +x:1 +正职 1 +x:1 +皇道吉日 1 +x:1 +贴饼子 1 +x:1 +片甲不存 1 +x:1 +光明正大 1 +x:1 +贪者 1 +x:1 +上海市 1 +x:1 +外派 1 +x:1 +真果 1 +x:1 +外泄 1 +x:1 +储能技术 1 +x:1 +只知其然 1 +x:1 +指南针 1 +x:1 +风狂雨骤 1 +x:1 +防空网 1 +x:1 +熟识 1 +x:1 +刚 810 +x:810 +看穿 1 +x:1 +双湖 1 +x:1 +弱不禁风 1 +x:1 +优良 1 +x:1 +冰水 1 +x:1 +书店 1 +x:1 +冰凌 1 +x:1 +舰群 1 +x:1 +不胜 1 +x:1 +博大精深 1 +x:1 +砧板 1 +x:1 +婉约 1 +x:1 +古柯 1 +x:1 +亲水性 1 +x:1 +大石 1 +x:1 +白白 1 +x:1 +扶危救困 1 +x:1 +医务 1 +x:1 +白癣 1 +x:1 +存储点 1 +x:1 +缓急 1 +x:1 +古柏 1 +x:1 +空调车 1 +x:1 +零吃 1 +x:1 +疵点 1 +x:1 +服侍 1 +x:1 +面目一新 1 +x:1 +指示 1 +x:1 +革新里 1 +x:1 +挖槽 1 +x:1 +商务部 1 +x:1 +不肖 1 +x:1 +渔养 1 +x:1 +长沙路 1 +x:1 +古本 1 +x:1 +百米赛 1 +x:1 +联艺 1 +x:1 +耳旁风 1 +x:1 +古木 1 +x:1 +外汇 1 +x:1 +亮开 1 +x:1 +分局长 1 +x:1 +卡其 1 +x:1 +鸭行鹅步 1 +x:1 +后场 1 +x:1 +动容 1 +x:1 +新庄村 1 +x:1 +识假 1 +x:1 +古朴 1 +x:1 +裁定 1 +x:1 +外江 1 +x:1 +冰河 1 +x:1 +约制 1 +x:1 +可辨 1 +x:1 +直升机 1 +x:1 +猴头 1 +x:1 +白皙 1 +x:1 +熟语 1 +x:1 +发芽率 1 +x:1 +吉普赛人 1 +x:1 +化工厂 1 +x:1 +空余 1 +x:1 +后土 1 +x:1 +项群 1 +x:1 +超纪录 1 +x:1 +加拉加斯 1 +x:1 +愈来愈 1 +x:1 +作曲法 1 +x:1 +圣谕 1 +x:1 +重臣 1 +x:1 +且末城 1 +x:1 +军功章 1 +x:1 +陆勤分队 1 +x:1 +多领化 1 +x:1 +折射 1 +x:1 +古松 1 +x:1 +古板 1 +x:1 +月台票 1 +x:1 +汗斑 1 +x:1 +法国队 1 +x:1 +让步 1 +x:1 +宁夏区 1 +x:1 +白盔 1 +x:1 +驾驶镜 1 +x:1 +关西 1 +x:1 +锃亮 1 +x:1 +大石头村 1 +x:1 +来者 1 +x:1 +折尺 1 +x:1 +外水 1 +x:1 +后坐 1 +x:1 +随处可见 1 +x:1 +软膏 1 +x:1 +潜水衣 1 +x:1 +田径场 1 +x:1 +主枢纽 1 +x:1 +楼板 1 +x:1 +近似 1 +x:1 +查扣 1 +x:1 +挎 13 +x:13 +酬答 1 +x:1 +查找 1 +x:1 +不菲 1 +x:1 +有令不行 1 +x:1 +木质部 1 +x:1 +保国乡 1 +x:1 +腾格里 1 +x:1 +岸上 1 +x:1 +岸下 1 +x:1 +柳泉村 1 +x:1 +昆河 1 +x:1 +负笈归来 1 +x:1 +候车亭 1 +x:1 +麻醉品 1 +x:1 +志留系 1 +x:1 +猛禽 1 +x:1 +与世隔绝 1 +x:1 +端头 1 +x:1 +绥靖主义 1 +x:1 +形而上学 1 +x:1 +渔事 1 +x:1 +灰林鹗 1 +x:1 +椿芽 1 +x:1 +潜水表 1 +x:1 +休闲者 1 +x:1 +对路 1 +x:1 +钢锭 1 +x:1 +钢锯 1 +x:1 +以质取胜 1 +x:1 +查房 1 +x:1 +黛 1 +x:1 +芦席 1 +x:1 +心目 1 +x:1 +握有 1 +x:1 +带头人 1 +x:1 +近作 1 +x:1 +霸王别姬 1 +x:1 +假大空 1 +x:1 +卢比 1 +x:1 +攻城略地 1 +x:1 +贺村 1 +x:1 +书报 1 +x:1 +包衣率 1 +x:1 +对质 1 +x:1 +婚后 1 +x:1 +充装站 1 +x:1 +炮市 1 +x:1 +医典 1 +x:1 +钢门 1 +x:1 +软脂 1 +x:1 +近便 1 +x:1 +嗲声嗲气 1 +x:1 +如沐春雨 1 +x:1 +零基 1 +x:1 +堪萨斯州 1 +x:1 +身怀绝技 1 +x:1 +跳皮筋儿 1 +x:1 +直销员 1 +x:1 +餐饮部 1 +x:1 +缉私科 1 +x:1 +圯桥 1 +x:1 +赐教 1 +x:1 +工艺科 1 +x:1 +虎口拔牙 1 +x:1 +灰褐色 1 +x:1 +穷途 1 +x:1 +架 357 +x:357 +指端 1 +x:1 +白痴 1 +x:1 +焦家湾村 1 +x:1 +监督厅 1 +x:1 +瑞气盈门 1 +x:1 +阴文 1 +x:1 +护理队 1 +x:1 +凶残 1 +x:1 +进球 1 +x:1 +新闻记者 1 +x:1 +火炬树 1 +x:1 +呗 6 +x:6 +白痢 1 +x:1 +高峰 1 +x:1 +笑笑 1 +x:1 +如若 1 +x:1 +软腭 1 +x:1 +青灰色 1 +x:1 +陇川县 1 +x:1 +对赌 1 +x:1 +查抄 1 +x:1 +人才库 1 +x:1 +罪不容诛 1 +x:1 +存单联 1 +x:1 +故地重游 1 +x:1 +身居 1 +x:1 +满满的 1 +x:1 +贺春 1 +x:1 +打杂儿 1 +x:1 +开启 1 +x:1 +硬灌式 1 +x:1 +古方 1 +x:1 +甘草店乡 1 +x:1 +早年间 1 +x:1 +甲亢病 1 +x:1 +配置率 1 +x:1 +一心一意 1 +x:1 +多棱镜 1 +x:1 +涧 9 +x:9 +近世 1 +x:1 +五三年 1 +x:1 +古文 1 +x:1 +大连港 1 +x:1 +缓手 1 +x:1 +赤眼蜂 1 +x:1 +挖掘点 1 +x:1 +可贺 1 +x:1 +产品部 1 +x:1 +可贵 1 +x:1 +裁夺 1 +x:1 +空调费 1 +x:1 +折床 1 +x:1 +冰湖 1 +x:1 +专门家 1 +x:1 +分布点 1 +x:1 +担纲挑梁 1 +x:1 +优者 1 +x:1 +外源 1 +x:1 +科连特斯 1 +x:1 +重荷 1 +x:1 +零嘴 1 +x:1 +看破 1 +x:1 +古时 1 +x:1 +高加索 1 +x:1 +厦航 1 +x:1 +低靡 1 +x:1 +外溢 1 +x:1 +不劳而获 1 +x:1 +犯愁 1 +x:1 +矫 2 +x:2 +笑窝 1 +x:1 +电脑系 1 +x:1 +表面波 1 +x:1 +同心圆 1 +x:1 +炸药包 1 +x:1 +漆皮 1 +x:1 +大连湾 1 +x:1 +太极 1 +x:1 +近乎 1 +x:1 +逍遥 1 +x:1 +近亲 1 +x:1 +八面玲珑 1 +x:1 +溜子 1 +x:1 +大田 1 +x:1 +不良 1 +x:1 +近人 1 +x:1 +萍 43 +x:43 +冰溜 1 +x:1 +预算司 1 +x:1 +计程器 1 +x:1 +依稀 1 +x:1 +优胜 1 +x:1 +厘 4 +x:4 +体育课 1 +x:1 +闪光点 1 +x:1 +棍法 1 +x:1 +匹夫之勇 1 +x:1 +钢铁 1 +x:1 +核苷酸 1 +x:1 +对调 1 +x:1 +缴费率 1 +x:1 +剧痛 1 +x:1 +宾馆业 1 +x:1 +瓜那雷斯 1 +x:1 +炮弹 1 +x:1 +安曼市 1 +x:1 +传导 1 +x:1 +半自动 1 +x:1 +后唐 1 +x:1 +刀茅巷 1 +x:1 +铺天盖地 1 +x:1 +菠萝 1 +x:1 +白瓷 1 +x:1 +城里人 1 +x:1 +对象 1 +x:1 +狮梁 1 +x:1 +查控 1 +x:1 +帕拉瓜纳 1 +x:1 +猴子 1 +x:1 +失落 1 +x:1 +大略 1 +x:1 +运动员 1 +x:1 +来船 1 +x:1 +钢钳 1 +x:1 +八角形 1 +x:1 +纯形码 1 +x:1 +照叶林 1 +x:1 +穷酸 1 +x:1 +权门 1 +x:1 +书展 1 +x:1 +吉林省 1 +x:1 +穿云破雾 1 +x:1 +钢针 1 +x:1 +习题集 1 +x:1 +绘影绘色 1 +x:1 +书局 1 +x:1 +院子 1 +x:1 +褶痕 1 +x:1 +优育 1 +x:1 +雪灾区 1 +x:1 +书屋 1 +x:1 +产加销 1 +x:1 +洗牙器 1 +x:1 +来路 1 +x:1 +通讯卫星 1 +x:1 +机械式 1 +x:1 +埋藏量 1 +x:1 +安乐 1 +x:1 +进站 1 +x:1 +校服者 1 +x:1 +演奏 1 +x:1 +安义 1 +x:1 +狙击手 1 +x:1 +缴费簿 1 +x:1 +卢方 1 +x:1 +摘引 1 +x:1 +恶性肿瘤 1 +x:1 +令人满意 1 +x:1 +主任医师 1 +x:1 +皂素 1 +x:1 +树苗 1 +x:1 +匈牙利 1 +x:1 +缨子 1 +x:1 +联运 1 +x:1 +正要 1 +x:1 +咳 4 +x:4 +盖家峪村 1 +x:1 +大跃进 1 +x:1 +氟化氢 1 +x:1 +安丘 1 +x:1 +外交史 1 +x:1 +医德 1 +x:1 +实业厅 1 +x:1 +书号 1 +x:1 +三板斧 1 +x:1 +干旱区 1 +x:1 +履约 1 +x:1 +母 93 +x:93 +婚嫁 1 +x:1 +大竹 1 +x:1 +顺天镇 1 +x:1 +维里 1 +x:1 +安上 1 +x:1 +零头 1 +x:1 +不足 1 +x:1 +大端 1 +x:1 +主刀 1 +x:1 +罚 176 +x:176 +奇功伟业 1 +x:1 +端坐 1 +x:1 +看看 1 +x:1 +采油井 1 +x:1 +大站 1 +x:1 +顺乎潮流 1 +x:1 +幸甚 1 +x:1 +伍珀塔尔 1 +x:1 +折冲 1 +x:1 +佺 1 +x:1 +页面 1 +x:1 +荡然无存 1 +x:1 +折光 1 +x:1 +田垄 1 +x:1 +急若流星 1 +x:1 +十分 1 +x:1 +征文组 1 +x:1 +水解液 1 +x:1 +脑 83 +x:83 +过错制 1 +x:1 +身强力壮 1 +x:1 +安仁 1 +x:1 +外展神经 1 +x:1 +龚 310 +x:310 +智多星 1 +x:1 +打假治劣 1 +x:1 +大暴雨 1 +x:1 +院名 1 +x:1 +发横财 1 +x:1 +鞭毛藻 1 +x:1 +左臂右膀 1 +x:1 +泗州戏 1 +x:1 +后娘 1 +x:1 +古樟 1 +x:1 +不赖 1 +x:1 +警备部 1 +x:1 +投石问路 1 +x:1 +半私用 1 +x:1 +多极化 1 +x:1 +楼堂 1 +x:1 +卑下 1 +x:1 +不贤 1 +x:1 +够呛 1 +x:1 +水土不服 1 +x:1 +在理儿 1 +x:1 +书卷 1 +x:1 +查没 1 +x:1 +非线形 1 +x:1 +宜城市 1 +x:1 +吐根素 1 +x:1 +语文科 1 +x:1 +实业化 1 +x:1 +疑心病 1 +x:1 +安于 1 +x:1 +悲歌 1 +x:1 +脉动电流 1 +x:1 +高居 1 +x:1 +外感 1 +x:1 +软软 1 +x:1 +补税 1 +x:1 +校史展 1 +x:1 +防盗器 1 +x:1 +日耳曼 1 +x:1 +细毛羊 1 +x:1 +安享 1 +x:1 +具体 1 +x:1 +纳斯尔队 1 +x:1 +不负 1 +x:1 +脂油 1 +x:1 +中堡岛 1 +x:1 +细菌性 1 +x:1 +书协 1 +x:1 +补篮 1 +x:1 +镇星 1 +x:1 +鞭 5 +x:5 +醒儿 1 +x:1 +矗立 1 +x:1 +身前 1 +x:1 +中北部 1 +x:1 +炮军 1 +x:1 +音容宛在 1 +x:1 +十五大 1 +x:1 +躬逢 1 +x:1 +姑且 1 +x:1 +老大妈 1 +x:1 +狂轰滥炸 1 +x:1 +阻行杆 1 +x:1 +宜春 1 +x:1 +蓄须 1 +x:1 +婚宴 1 +x:1 +姑丈 1 +x:1 +重负 1 +x:1 +芽 14 +x:14 +避风港 1 +x:1 +泥水选种 1 +x:1 +伤心惨目 1 +x:1 +高家湾 1 +x:1 +清迈府 1 +x:1 +祛除 1 +x:1 +妻儿 1 +x:1 +惑 10 +x:10 +缠绕茎 1 +x:1 +票据 1 +x:1 +不伦不类 1 +x:1 +安企 1 +x:1 +活疫苗 1 +x:1 +定然 1 +x:1 +瑞 68 +x:68 +黯淡 1 +x:1 +树莓 1 +x:1 +外患 1 +x:1 +统战部 1 +x:1 +汝阳 1 +x:1 +历尽艰辛 1 +x:1 +麻业 1 +x:1 +重赏 1 +x:1 +后天性 1 +x:1 +大篆 1 +x:1 +核桃树 1 +x:1 +货运业 1 +x:1 +赛车队 1 +x:1 +光闪闪 1 +x:1 +袖箭 1 +x:1 +老大姐 1 +x:1 +安莎社 1 +x:1 +安保 1 +x:1 +车海 1 +x:1 +正常人 1 +x:1 +麻醉学 1 +x:1 +拆封 1 +x:1 +樵采 1 +x:1 +看相 1 +x:1 +眼皮子 1 +x:1 +亮化 1 +x:1 +钞 3 +x:3 +大笔 1 +x:1 +大笑 1 +x:1 +梳妆台 1 +x:1 +款型 1 +x:1 +踏勘 1 +x:1 +运箱费 1 +x:1 +火炬松 1 +x:1 +贪赃 1 +x:1 +谬种 1 +x:1 +压砧 1 +x:1 +人寿年丰 1 +x:1 +钢骨 1 +x:1 +后学 1 +x:1 +羊痫风 1 +x:1 +流里流气 1 +x:1 +阎三囤 1 +x:1 +冰情 1 +x:1 +楼梯 1 +x:1 +休养所 1 +x:1 +幻灯 1 +x:1 +贪财 1 +x:1 +缦帐 1 +x:1 +试衣间 1 +x:1 +圣职 1 +x:1 +葩 1 +x:1 +五华县 1 +x:1 +维管束 1 +x:1 +洇 3 +x:3 +脖根 1 +x:1 +渴汤 1 +x:1 +传出神经 1 +x:1 +不谙 1 +x:1 +炮兵 1 +x:1 +甜酸苦辣 1 +x:1 +帝国主义 1 +x:1 +尧舜 1 +x:1 +交易人 1 +x:1 +会做人 1 +x:1 +周礼 1 +x:1 +树胶 1 +x:1 +科技角 1 +x:1 +踏入 1 +x:1 +眼镜架 1 +x:1 +冰挂 1 +x:1 +破烂王 1 +x:1 +协调会 1 +x:1 +化学系 1 +x:1 +武侯区 1 +x:1 +医工 1 +x:1 +大雅之堂 1 +x:1 +科技观 1 +x:1 +夫妻间 1 +x:1 +茶余饭后 1 +x:1 +大碗 1 +x:1 +不过 1 +x:1 +影赛 1 +x:1 +大碟 1 +x:1 +书写 1 +x:1 +折叠 1 +x:1 +古梅 1 +x:1 +职衔 1 +x:1 +老玉米 1 +x:1 +主粮 1 +x:1 +游离电子 1 +x:1 +延绵不断 1 +x:1 +现代舞团 1 +x:1 +可耻 1 +x:1 +武英殿 1 +x:1 +军事法庭 1 +x:1 +游 216 +x:216 +多价 1 +x:1 +舰炮 1 +x:1 +多于 1 +x:1 +多亏 1 +x:1 +连根拔起 1 +x:1 +多事 1 +x:1 +计拨 1 +x:1 +立体感 1 +x:1 +热电站 1 +x:1 +书函 1 +x:1 +裁员 1 +x:1 +浑仪 1 +x:1 +沟壑区 1 +x:1 +供桌 1 +x:1 +深一脚 1 +x:1 +涞源县 1 +x:1 +下者 1 +x:1 +不辍 1 +x:1 +在所不辞 1 +x:1 +浦 5 +x:5 +瞥见 1 +x:1 +难胞 1 +x:1 +糯 2 +x:2 +最佳 1 +x:1 +化工局 1 +x:1 +同安区 1 +x:1 +冰排 1 +x:1 +布 72 +x:72 +多么 1 +x:1 +走村入户 1 +x:1 +霉 3 +x:3 +多久 1 +x:1 +亮节高风 1 +x:1 +官话 1 +x:1 +不轨 1 +x:1 +二房东 1 +x:1 +琴音 1 +x:1 +古格 1 +x:1 +幸存 1 +x:1 +恩平市 1 +x:1 +烘漆厂 1 +x:1 +奴颜媚骨 1 +x:1 +真格 1 +x:1 +联赛 1 +x:1 +看病 1 +x:1 +透过 1 +x:1 +后堂 1 +x:1 +夭 3 +x:3 +并排 1 +x:1 +甜 66 +x:66 +截住 1 +x:1 +老大娘 1 +x:1 +聊以 1 +x:1 +光阴似箭 1 +x:1 +善莫大焉 1 +x:1 +粉妆玉琢 1 +x:1 +既定 1 +x:1 +古树 1 +x:1 +食利者 1 +x:1 +细菌战 1 +x:1 +外挂 1 +x:1 +草垫子 1 +x:1 +圣药 1 +x:1 +兵火 1 +x:1 +一股就灵 1 +x:1 +芋艿 1 +x:1 +麻线 1 +x:1 +贸工部 1 +x:1 +票号 1 +x:1 +联贯 1 +x:1 +大棚菜 1 +x:1 +鸡犬升天 1 +x:1 +待价而沽 1 +x:1 +多业 1 +x:1 +哈斯科沃 1 +x:1 +联责 1 +x:1 +汇价 1 +x:1 +经济杂交 1 +x:1 +融资量 1 +x:1 +千呼万唤 1 +x:1 +婺源 1 +x:1 +矢量 1 +x:1 +赏心 1 +x:1 +透辟 1 +x:1 +可能 1 +x:1 +四九年 1 +x:1 +翰林院 1 +x:1 +引言 1 +x:1 +起色 1 +x:1 +赵村乡 1 +x:1 +大禾 1 +x:1 +民主村 1 +x:1 +三危山 1 +x:1 +腰板 1 +x:1 +引语 1 +x:1 +怒 5 +x:5 +精确度 1 +x:1 +开门揖盗 1 +x:1 +尾矿库 1 +x:1 +补种 1 +x:1 +徐水县 1 +x:1 +赢利性 1 +x:1 +药捻子 1 +x:1 +比比划划 1 +x:1 +九一八 1 +x:1 +懂行 1 +x:1 +氩气 1 +x:1 +斥力 1 +x:1 +大福 1 +x:1 +外借 1 +x:1 +鞭毛虫 1 +x:1 +东渐史 1 +x:1 +逗点 1 +x:1 +援军 1 +x:1 +水鸪鸪 1 +x:1 +本本主义 1 +x:1 +摆阔气 1 +x:1 +家庭式 1 +x:1 +分外夺目 1 +x:1 +剧社 1 +x:1 +酞酸酯 1 +x:1 +规划委 1 +x:1 +重载 1 +x:1 +策划部 1 +x:1 +再加之 1 +x:1 +其内 1 +x:1 +孝直镇 1 +x:1 +好话 1 +x:1 +座上客 1 +x:1 +魔鞋 1 +x:1 +婚姻 1 +x:1 +调解者 1 +x:1 +征收月 1 +x:1 +后委 1 +x:1 +古槐 1 +x:1 +后天 1 +x:1 +补票 1 +x:1 +大礼 1 +x:1 +多余 1 +x:1 +骖 1 +x:1 +根本性 1 +x:1 +审慎 1 +x:1 +汗毛 1 +x:1 +慧眼识才 1 +x:1 +商贸司 1 +x:1 +模 5 +x:5 +交易会 1 +x:1 +缓滞 1 +x:1 +心肝儿 1 +x:1 +票友 1 +x:1 +抗诉量 1 +x:1 +信天翁 1 +x:1 +表面性 1 +x:1 +技巧赛 1 +x:1 +后备 1 +x:1 +炮区 1 +x:1 +协调人 1 +x:1 +弃甲曳兵 1 +x:1 +剧种 1 +x:1 +院土 1 +x:1 +凄风冷雨 1 +x:1 +亮光 1 +x:1 +融资部 1 +x:1 +竖挑眼 1 +x:1 +折刀 1 +x:1 +数术史 1 +x:1 +河蟹 1 +x:1 +阔绰 1 +x:1 +大祸 1 +x:1 +重述 1 +x:1 +居里夫人 1 +x:1 +外戚 1 +x:1 +传帮带 1 +x:1 +加洛普 1 +x:1 +占便宜 1 +x:1 +姬 18 +x:18 +重返 1 +x:1 +裂谷 1 +x:1 +联谊 1 +x:1 +款款深情 1 +x:1 +院坝 1 +x:1 +绥中县 1 +x:1 +对联 1 +x:1 +忧心如焚 1 +x:1 +杭嘉湖 1 +x:1 +其因 1 +x:1 +大纲 1 +x:1 +不解 1 +x:1 +冉 43 +x:43 +十五小 1 +x:1 +婚庆 1 +x:1 +信誉制 1 +x:1 +语族 1 +x:1 +官亭乡 1 +x:1 +查档 1 +x:1 +后座 1 +x:1 +大约 1 +x:1 +多多马 1 +x:1 +被控人 1 +x:1 +大红 1 +x:1 +包金 1 +x:1 +崖 19 +x:19 +人造卫星 1 +x:1 +穷 283 +x:283 +周缘 1 +x:1 +不见 1 +x:1 +裁判 1 +x:1 +安工办 1 +x:1 +尸骨未寒 1 +x:1 +不觉 1 +x:1 +天下第一 1 +x:1 +违纪者 1 +x:1 +补给 1 +x:1 +蒙特卡罗 1 +x:1 +清锅冷灶 1 +x:1 +等闲视之 1 +x:1 +星毛虫 1 +x:1 +其四 1 +x:1 +肾透析器 1 +x:1 +炮响 1 +x:1 +端午 1 +x:1 +警标 1 +x:1 +热哄哄 1 +x:1 +批判 1 +x:1 +联训 1 +x:1 +查核 1 +x:1 +正反方 1 +x:1 +宣传车 1 +x:1 +埝 1 +x:1 +发电量 1 +x:1 +甘石桥站 1 +x:1 +昆曲 1 +x:1 +不要 1 +x:1 +绘声绘影 1 +x:1 +宋史 1 +x:1 +商城县 1 +x:1 +玉石片 1 +x:1 +断头台 1 +x:1 +裁剪 1 +x:1 +临场感 1 +x:1 +研发 1 +x:1 +征文稿 1 +x:1 +汗水 1 +x:1 +博厚镇 1 +x:1 +外方 1 +x:1 +民主性 1 +x:1 +书城 1 +x:1 +沉湎 1 +x:1 +奋斗以成 1 +x:1 +前人栽树 1 +x:1 +拉家带口 1 +x:1 +窄 52 +x:52 +素宣 1 +x:1 +白羽 1 +x:1 +到头来 1 +x:1 +外敌 1 +x:1 +堪萨斯城 1 +x:1 +规划师 1 +x:1 +医学 1 +x:1 +机械局 1 +x:1 +法制观 1 +x:1 +遣电驱雷 1 +x:1 +九一四 1 +x:1 +昆明 1 +x:1 +依然 1 +x:1 +进退维谷 1 +x:1 +谬以千里 1 +x:1 +透视 1 +x:1 +后市 1 +x:1 +莪 1 +x:1 +查检 1 +x:1 +落荒而逃 1 +x:1 +穿透 1 +x:1 +名中药 1 +x:1 +剧组 1 +x:1 +书店业 1 +x:1 +车马炮 1 +x:1 +西岗镇 1 +x:1 +盈满 1 +x:1 +豆角儿 1 +x:1 +传播业 1 +x:1 +憾 4 +x:4 +护假者 1 +x:1 +线型 1 +x:1 +包衣种 1 +x:1 +形意拳 1 +x:1 +关联 1 +x:1 +无强力 1 +x:1 +后年 1 +x:1 +冬奥会 1 +x:1 +你中有我 1 +x:1 +麻醉师 1 +x:1 +贫水区 1 +x:1 +书坛 1 +x:1 +水平面 1 +x:1 +指点 1 +x:1 +永年县 1 +x:1 +依照 1 +x:1 +升班队 1 +x:1 +月球仪 1 +x:1 +重重叠叠 1 +x:1 +抛弃物 1 +x:1 +监理站 1 +x:1 +极而言之 1 +x:1 +趋 145 +x:145 +聊城县 1 +x:1 +草籽儿 1 +x:1 +引路 1 +x:1 +团干部 1 +x:1 +养颜 1 +x:1 +廉政署 1 +x:1 +买账 1 +x:1 +院内 1 +x:1 +更生霉素 1 +x:1 +红黄牌 1 +x:1 +渺渺茫茫 1 +x:1 +猛犸 1 +x:1 +受礼者 1 +x:1 +胆破心惊 1 +x:1 +斜长石 1 +x:1 +上海城 1 +x:1 +印尼队 1 +x:1 +维持 1 +x:1 +沦肌浃髓 1 +x:1 +褶缝 1 +x:1 +债权人 1 +x:1 +业余组 1 +x:1 +冰态水 1 +x:1 +街头诗 1 +x:1 +我方 1 +x:1 +外号 1 +x:1 +慢件 1 +x:1 +外交团 1 +x:1 +海滦河 1 +x:1 +信号工 1 +x:1 +票条 1 +x:1 +信誉卡 1 +x:1 +瓷艺 1 +x:1 +言之凿凿 1 +x:1 +督查组 1 +x:1 +人浮于事 1 +x:1 +溜冰 1 +x:1 +战斗舰 1 +x:1 +黔驴之技 1 +x:1 +亚美尼亚 1 +x:1 +人称 1 +x:1 +引起 1 +x:1 +白纸 1 +x:1 +灵台 1 +x:1 +便民利民 1 +x:1 +强手如林 1 +x:1 +不衰 1 +x:1 +掉话率 1 +x:1 +计收 1 +x:1 +格拉茨市 1 +x:1 +成绩单 1 +x:1 +溜光 1 +x:1 +消释 1 +x:1 +猴儿 1 +x:1 +银行法 1 +x:1 +手纸 1 +x:1 +底格里斯 1 +x:1 +慎重 1 +x:1 +终身 1 +x:1 +不行 1 +x:1 +转业退伍 1 +x:1 +亲骨肉 1 +x:1 +畅游 1 +x:1 +辞目 1 +x:1 +权宜之计 1 +x:1 +次果 1 +x:1 +折合 1 +x:1 +金丝雀 1 +x:1 +测 23 +x:23 +白绸 1 +x:1 +计数 1 +x:1 +鸿爪 1 +x:1 +补缺 1 +x:1 +价廉质优 1 +x:1 +补缴 1 +x:1 +蝶儿 1 +x:1 +百读不厌 1 +x:1 +重视 1 +x:1 +大网 1 +x:1 +奴隶 1 +x:1 +溜儿 1 +x:1 +待产 1 +x:1 +冀东区 1 +x:1 +迸射 1 +x:1 +树蜂 1 +x:1 +汉字库 1 +x:1 +汗液 1 +x:1 +待人 1 +x:1 +语文系 1 +x:1 +斑豹一窥 1 +x:1 +征 100 +x:100 +不详 1 +x:1 +盈江 1 +x:1 +供气 1 +x:1 +中外船 1 +x:1 +戎马生涯 1 +x:1 +冰期 1 +x:1 +识察 1 +x:1 +不说 1 +x:1 +大咧咧 1 +x:1 +芳菲苑 1 +x:1 +摇曳 1 +x:1 +关节 1 +x:1 +中外航 1 +x:1 +苏州码子 1 +x:1 +大粪 1 +x:1 +缓步 1 +x:1 +宁乡 1 +x:1 +百叶窗 1 +x:1 +县衙署 1 +x:1 +重言 1 +x:1 +供水 1 +x:1 +右上角 1 +x:1 +心气儿 1 +x:1 +拖车队 1 +x:1 +墉 6 +x:6 +汗湿 1 +x:1 +太滆 1 +x:1 +滚打 1 +x:1 +穷而后工 1 +x:1 +农家 1 +x:1 +道经圣 1 +x:1 +吟诗 1 +x:1 +汗渍 1 +x:1 +黄骅港 1 +x:1 +大系 1 +x:1 +犀角 1 +x:1 +供求 1 +x:1 +来访 1 +x:1 +节电费 1 +x:1 +击落 1 +x:1 +不讳 1 +x:1 +鹊巢鸠占 1 +x:1 +自选区 1 +x:1 +不许 1 +x:1 +不论 1 +x:1 +端公 1 +x:1 +钾盐 1 +x:1 +炮团 1 +x:1 +恒等式 1 +x:1 +灌输 1 +x:1 +安曼城 1 +x:1 +兔死狐悲 1 +x:1 +芾 1 +x:1 +自在阶级 1 +x:1 +显像管 1 +x:1 +渴念 1 +x:1 +休闲装 1 +x:1 +识字 1 +x:1 +养鸡场 1 +x:1 +银川市 1 +x:1 +瓜德罗普 1 +x:1 +否极泰来 1 +x:1 +长林乡 1 +x:1 +树葬 1 +x:1 +李沧区 1 +x:1 +大前年 1 +x:1 +疙瘩 1 +x:1 +既往 1 +x:1 +猛然 1 +x:1 +法制课 1 +x:1 +供油 1 +x:1 +后尘 1 +x:1 +汗滴 1 +x:1 +岗点 1 +x:1 +大米 1 +x:1 +过敏症 1 +x:1 +畅流 1 +x:1 +冰柜 1 +x:1 +大肠杆菌 1 +x:1 +医大 1 +x:1 +腰果 1 +x:1 +规划局 1 +x:1 +平凡 1 +x:1 +逗留 1 +x:1 +体育节 1 +x:1 +冰柱 1 +x:1 +其后 1 +x:1 +秆儿 1 +x:1 +困 43 +x:43 +拉锁儿 1 +x:1 +副神经 1 +x:1 +书商 1 +x:1 +羞于启齿 1 +x:1 +黎民 1 +x:1 +外县 1 +x:1 +灭迹 1 +x:1 +夜以继日 1 +x:1 +中直机关 1 +x:1 +日月经天 1 +x:1 +沙边子村 1 +x:1 +到达 1 +x:1 +台湾厅 1 +x:1 +引述 1 +x:1 +化工大 1 +x:1 +看得过儿 1 +x:1 +树藤 1 +x:1 +炯炯有神 1 +x:1 +村支书 1 +x:1 +深蓝色 1 +x:1 +劳动改造 1 +x:1 +粗鄙 1 +x:1 +蚊香 1 +x:1 +溜号 1 +x:1 +端倪 1 +x:1 +斧 10 +x:10 +临猗县 1 +x:1 +邵 157 +x:157 +蔓衍 1 +x:1 +中低档 1 +x:1 +黑发 1 +x:1 +白米 1 +x:1 +票数 1 +x:1 +身后 1 +x:1 +坂下 1 +x:1 +岩溶 1 +x:1 +阿斯塔纳 1 +x:1 +虎踞龙盘 1 +x:1 +院史 1 +x:1 +后已 1 +x:1 +外协 1 +x:1 +户政处长 1 +x:1 +脖子 1 +x:1 +冰晶 1 +x:1 +铁算盘 1 +x:1 +当务之急 1 +x:1 +冷加工 1 +x:1 +大武村 1 +x:1 +神妙 1 +x:1 +大张旗鼓 1 +x:1 +悲泣 1 +x:1 +宗祧 1 +x:1 +联袂 1 +x:1 +圆明园者 1 +x:1 +悲泪 1 +x:1 +大义凛然 1 +x:1 +月光花 1 +x:1 +译注 1 +x:1 +阶级性 1 +x:1 +浏览器 1 +x:1 +条件反射 1 +x:1 +统配电 1 +x:1 +玲珑剔透 1 +x:1 +主动性 1 +x:1 +阔老板 1 +x:1 +披风 1 +x:1 +五中全会 1 +x:1 +戊戌 1 +x:1 +助学岗 1 +x:1 +款冬 1 +x:1 +书吧 1 +x:1 +次方 1 +x:1 +官 353 +x:353 +裁军 1 +x:1 +大紫 1 +x:1 +校委会 1 +x:1 +行善积德 1 +x:1 +处置场 1 +x:1 +金牌榜 1 +x:1 +人才城 1 +x:1 +冰暴 1 +x:1 +左证 1 +x:1 +躁热 1 +x:1 +定中结构 1 +x:1 +外景 1 +x:1 +嘱 5 +x:5 +联行 1 +x:1 +台湾区 1 +x:1 +反贪科 1 +x:1 +公主岭市 1 +x:1 +晋侯墓 1 +x:1 +白粉 1 +x:1 +书名 1 +x:1 +书后 1 +x:1 +书吏 1 +x:1 +鹤庆县 1 +x:1 +缆道 1 +x:1 +次日 1 +x:1 +冠军杯赛 1 +x:1 +零度 1 +x:1 +粗野 1 +x:1 +粗重 1 +x:1 +小词 1 +x:1 +裁减 1 +x:1 +调节价 1 +x:1 +掷地有声 1 +x:1 +葵花子 1 +x:1 +食少便溏 1 +x:1 +重读 1 +x:1 +巧笑倩兮 1 +x:1 +犹豫不决 1 +x:1 +白糖 1 +x:1 +风吹雨打 1 +x:1 +独树一帜 1 +x:1 +专门化 1 +x:1 +连脚裤 1 +x:1 +瓷胎 1 +x:1 +武昌起义 1 +x:1 +妖术 1 +x:1 +来言 1 +x:1 +色织厂 1 +x:1 +灵 70 +x:70 +这一下 1 +x:1 +痛快淋漓 1 +x:1 +小木凳 1 +x:1 +骇怪 1 +x:1 +等深线 1 +x:1 +马兰草纸 1 +x:1 +垂青 1 +x:1 +题词 1 +x:1 +经济院 1 +x:1 +村务 1 +x:1 +岛礁 1 +x:1 +确保 1 +x:1 +朝服 1 +x:1 +毛囊 1 +x:1 +解困 1 +x:1 +立法权 1 +x:1 +题诗 1 +x:1 +交货值 1 +x:1 +发售 1 +x:1 +购入 1 +x:1 +解囊 1 +x:1 +张村乡 1 +x:1 +确信 1 +x:1 +输入国 1 +x:1 +般 368 +x:368 +村办 1 +x:1 +彭水 1 +x:1 +计算机所 1 +x:1 +涪陵 1 +x:1 +加进 1 +x:1 +场 1903 +x:1903 +襄曲 1 +x:1 +汗流满面 1 +x:1 +计算机房 1 +x:1 +聚光镜 1 +x:1 +门柱 1 +x:1 +臣 9 +x:9 +中下 1 +x:1 +今译 1 +x:1 +爆米花 1 +x:1 +海林镇 1 +x:1 +中专 1 +x:1 +时样 1 +x:1 +永曲 1 +x:1 +中东 1 +x:1 +太婆 1 +x:1 +实用型 1 +x:1 +眼睑炎 1 +x:1 +固定点 1 +x:1 +合金钢 1 +x:1 +一触即发 1 +x:1 +译介 1 +x:1 +等级观 1 +x:1 +甘蓝型 1 +x:1 +慰问品 1 +x:1 +题记 1 +x:1 +中举 1 +x:1 +门机 1 +x:1 +耳塞 1 +x:1 +产钳 1 +x:1 +走法 1 +x:1 +》 13013 +x:13013 +廊子 1 +x:1 +中介 1 +x:1 +伸伸 1 +x:1 +执勤 1 +x:1 +沉着 1 +x:1 +洪泽湖 1 +x:1 +绉布 1 +x:1 +毒辣辣 1 +x:1 +期房 1 +x:1 +编订馆 1 +x:1 +撤案 1 +x:1 +消防 1 +x:1 +同贺 1 +x:1 +三环路 1 +x:1 +乌拉山 1 +x:1 +印刷局 1 +x:1 +烟摊儿 1 +x:1 +争议 1 +x:1 +类毒素 1 +x:1 +并非 1 +x:1 +南彩镇 1 +x:1 +改良种 1 +x:1 +门板 1 +x:1 +野角马 1 +x:1 +心旷神怡 1 +x:1 +铸造 1 +x:1 +京山 1 +x:1 +乌拉尔 1 +x:1 +大真大实 1 +x:1 +中云 1 +x:1 +财务局 1 +x:1 +下脚 1 +x:1 +教 295 +x:295 +瞥 12 +x:12 +廉正 1 +x:1 +多道程序 1 +x:1 +宰汶村 1 +x:1 +复兴门外 1 +x:1 +中产 1 +x:1 +劳工科 1 +x:1 +简洁性 1 +x:1 +桂皮 1 +x:1 +先头 1 +x:1 +烂漫 1 +x:1 +先夫 1 +x:1 +先天 1 +x:1 +装修业 1 +x:1 +发明型 1 +x:1 +冬季圈 1 +x:1 +中人 1 +x:1 +瑶池 1 +x:1 +腾出 1 +x:1 +训练队 1 +x:1 +暂名 1 +x:1 +中低 1 +x:1 +故技 1 +x:1 +焦距 1 +x:1 +物资部 1 +x:1 +脑门儿 1 +x:1 +吸毒史 1 +x:1 +俚俗 1 +x:1 +帽子 1 +x:1 +表演家 1 +x:1 +前车之鉴 1 +x:1 +先声 1 +x:1 +带工头 1 +x:1 +科队 1 +x:1 +梁山 1 +x:1 +露营 1 +x:1 +欲 130 +x:130 +大桥镇 1 +x:1 +产销 1 +x:1 +流离 1 +x:1 +该奖 1 +x:1 +私事 1 +x:1 +尾 46 +x:46 +留守 1 +x:1 +导流洞 1 +x:1 +村史 1 +x:1 +园林节 1 +x:1 +崇明岛 1 +x:1 +中伏 1 +x:1 +分级 1 +x:1 +村口 1 +x:1 +中休 1 +x:1 +荷花坪 1 +x:1 +佩斯 1 +x:1 +双停 1 +x:1 +中伤 1 +x:1 +痣 4 +x:4 +彭浦 1 +x:1 +川田 1 +x:1 +长辛店 1 +x:1 +该处 1 +x:1 +榜山镇 1 +x:1 +艰难性 1 +x:1 +妖孽 1 +x:1 +亚布力镇 1 +x:1 +开窍宁心 1 +x:1 +留宿 1 +x:1 +博罗县 1 +x:1 +大做文章 1 +x:1 +晋江 1 +x:1 +梁峁 1 +x:1 +劳有所得 1 +x:1 +建造界 1 +x:1 +后继乏人 1 +x:1 +大干一场 1 +x:1 +印度 1 +x:1 +村医 1 +x:1 +细瞧 1 +x:1 +集中地 1 +x:1 +都柳江 1 +x:1 +留存 1 +x:1 +媒 10 +x:10 +侧目而视 1 +x:1 +不合格品 1 +x:1 +中保 1 +x:1 +封存 1 +x:1 +蹦蹦跳跳 1 +x:1 +仰光 1 +x:1 +下痿 1 +x:1 +着呢 1 +x:1 +齿舞 1 +x:1 +片段 1 +x:1 +中信 1 +x:1 +白兰地 1 +x:1 +商号 1 +x:1 +溃散 1 +x:1 +丛林区 1 +x:1 +留学 1 +x:1 +申请方 1 +x:1 +故房 1 +x:1 +棋子 1 +x:1 +科隆 1 +x:1 +昙花 1 +x:1 +毛坯 1 +x:1 +竞买价 1 +x:1 +活石灰 1 +x:1 +干涧村 1 +x:1 +柄 13 +x:13 +汉学史 1 +x:1 +七星草 1 +x:1 +改恶从善 1 +x:1 +发运人 1 +x:1 +大明村 1 +x:1 +岳西县 1 +x:1 +洞察力 1 +x:1 +盈余额 1 +x:1 +产门 1 +x:1 +爪哇虎 1 +x:1 +输入地 1 +x:1 +原告席 1 +x:1 +工商联 1 +x:1 +电离层 1 +x:1 +撑门面 1 +x:1 +忍受 1 +x:1 +八拜之交 1 +x:1 +商厦 1 +x:1 +军火案 1 +x:1 +减速器 1 +x:1 +号召书 1 +x:1 +椰子汁 1 +x:1 +见仁见智 1 +x:1 +北三环路 1 +x:1 +拜见 1 +x:1 +军官法 1 +x:1 +极限 1 +x:1 +远东司 1 +x:1 +绝缘纸 1 +x:1 +孰轻孰重 1 +x:1 +红旗手 1 +x:1 +恼羞成怒 1 +x:1 +呐喊声 1 +x:1 +嬉闹 1 +x:1 +癌症 1 +x:1 +完善 1 +x:1 +癌病 1 +x:1 +蜘蛛网 1 +x:1 +银坑 1 +x:1 +先导 1 +x:1 +概况 1 +x:1 +妙法 1 +x:1 +朝政 1 +x:1 +竞逐 1 +x:1 +辉耀乡 1 +x:1 +涵 11 +x:11 +谴 1 +x:1 +农工部 1 +x:1 +白绒绒 1 +x:1 +乔迁 1 +x:1 +悦耳 1 +x:1 +牛头刨 1 +x:1 +懈怠成习 1 +x:1 +检定所 1 +x:1 +哏 1 +x:1 +微山县 1 +x:1 +针对 1 +x:1 +产院 1 +x:1 +临时工 1 +x:1 +见面费 1 +x:1 +慰问团 1 +x:1 +产险 1 +x:1 +泱泱 1 +x:1 +罗汉豆 1 +x:1 +私人 1 +x:1 +非常态 1 +x:1 +客 82 +x:82 +北流 1 +x:1 +泳联 1 +x:1 +斜边 1 +x:1 +事业观 1 +x:1 +汗孔 1 +x:1 +波尔卡 1 +x:1 +投标法 1 +x:1 +等级证 1 +x:1 +培 14 +x:14 +门旁 1 +x:1 +硼 1 +x:1 +湘竹 1 +x:1 +故意 1 +x:1 +建纬所 1 +x:1 +诱使 1 +x:1 +使然 1 +x:1 +流程 1 +x:1 +领悟 1 +x:1 +豪横 1 +x:1 +朝令夕改 1 +x:1 +侦察连 1 +x:1 +池边 1 +x:1 +波纹 1 +x:1 +一氧化碳 1 +x:1 +竞争线 1 +x:1 +申请量 1 +x:1 +朝方 1 +x:1 +篮球架 1 +x:1 +字贴儿 1 +x:1 +先公后私 1 +x:1 +印泥 1 +x:1 +妄自演绎 1 +x:1 +加赛 1 +x:1 +发型 1 +x:1 +邓东村 1 +x:1 +操纵台 1 +x:1 +曲终人散 1 +x:1 +包公祠 1 +x:1 +主线 1 +x:1 +猪鬃草 1 +x:1 +稻地村 1 +x:1 +嘉峪市 1 +x:1 +领情 1 +x:1 +常绿树 1 +x:1 +聘金 1 +x:1 +雪豆 1 +x:1 +点贷 1 +x:1 +创意人 1 +x:1 +赶潮流 1 +x:1 +逆流 1 +x:1 +齿腔 1 +x:1 +风雨与共 1 +x:1 +朝日 1 +x:1 +封堵 1 +x:1 +傲慢 1 +x:1 +军营学 1 +x:1 +椰子油 1 +x:1 +聘选 1 +x:1 +嬉戏 1 +x:1 +储蓄箱 1 +x:1 +海鹰 1 +x:1 +阎 159 +x:159 +巡山 1 +x:1 +贯家堡 1 +x:1 +着重号 1 +x:1 +滩涂地 1 +x:1 +付诸实践 1 +x:1 +万宝镇 1 +x:1 +便道砖 1 +x:1 +宜章县 1 +x:1 +烂泥 1 +x:1 +农产品 1 +x:1 +野战 1 +x:1 +步炮 1 +x:1 +航路 1 +x:1 +村农 1 +x:1 +南清园 1 +x:1 +一元论 1 +x:1 +村内 1 +x:1 +制 169 +x:169 +一网打尽 1 +x:1 +身单力薄 1 +x:1 +不可忘者 1 +x:1 +商儒 1 +x:1 +版权法 1 +x:1 +运销处 1 +x:1 +早间 1 +x:1 +消声器 1 +x:1 +毛 1173 +x:1173 +老城区 1 +x:1 +力行 1 +x:1 +再者 1 +x:1 +乒协 1 +x:1 +脉冲星 1 +x:1 +消闲 1 +x:1 +忍辱求全 1 +x:1 +设法 1 +x:1 +求助信 1 +x:1 +务工青年 1 +x:1 +购到 1 +x:1 +晶莹碧透 1 +x:1 +硫磺 1 +x:1 +衔铁 1 +x:1 +凡事 1 +x:1 +中甸县 1 +x:1 +胸佩 1 +x:1 +字迹 1 +x:1 +薄 133 +x:133 +咸鸭蛋 1 +x:1 +忍冬 1 +x:1 +肤阴洁 1 +x:1 +故态 1 +x:1 +单色光 1 +x:1 +协定 1 +x:1 +一笔抹煞 1 +x:1 +封套 1 +x:1 +该寺 1 +x:1 +繁荣区 1 +x:1 +吕剧 1 +x:1 +圆法 1 +x:1 +轮番 1 +x:1 +一家子 1 +x:1 +夏湾村 1 +x:1 +背井离乡 1 +x:1 +名落孙山 1 +x:1 +漳 1 +x:1 +都柏林 1 +x:1 +注音 1 +x:1 +分析会 1 +x:1 +雷同者 1 +x:1 +代销商 1 +x:1 +势头 1 +x:1 +驾到 1 +x:1 +条理性 1 +x:1 +脑体 1 +x:1 +蜷缩 1 +x:1 +有机肥料 1 +x:1 +琼剧 1 +x:1 +历练 1 +x:1 +时段 1 +x:1 +龙寺镇 1 +x:1 +料子 1 +x:1 +二级化 1 +x:1 +仞 3 +x:3 +出口处 1 +x:1 +招风惹草 1 +x:1 +每时每刻 1 +x:1 +静电 1 +x:1 +涝灾 1 +x:1 +当家作主 1 +x:1 +党乡 1 +x:1 +平坦村 1 +x:1 +城址 1 +x:1 +佩服 1 +x:1 +具 333 +x:333 +深情 1 +x:1 +绾 5 +x:5 +亲亲切切 1 +x:1 +蜂 7 +x:7 +白水城 1 +x:1 +三伏天 1 +x:1 +病歪歪 1 +x:1 +重版率 1 +x:1 +作废票 1 +x:1 +二级品 1 +x:1 +谣传 1 +x:1 +委员长 1 +x:1 +义务兵 1 +x:1 +三溪口镇 1 +x:1 +恐怖主义 1 +x:1 +瓦板房 1 +x:1 +依 114 +x:114 +徒刑 1 +x:1 +扈家庄 1 +x:1 +郁郁苍苍 1 +x:1 +四增四减 1 +x:1 +铸铁 1 +x:1 +露脸 1 +x:1 +点评 1 +x:1 +缴款单 1 +x:1 +昌都寺 1 +x:1 +塔位 1 +x:1 +横加干涉 1 +x:1 +加试 1 +x:1 +过渡带 1 +x:1 +封建 1 +x:1 +羽 28 +x:28 +参观者 1 +x:1 +制造者 1 +x:1 +加计 1 +x:1 +村围 1 +x:1 +觉 82 +x:82 +魏都区 1 +x:1 +菩萨心肠 1 +x:1 +审查会 1 +x:1 +铁道线 1 +x:1 +问清 1 +x:1 +脂粉 1 +x:1 +锹 14 +x:14 +帽带 1 +x:1 +封底 1 +x:1 +冲毁 1 +x:1 +以至于 1 +x:1 +留底 1 +x:1 +酣畅淋漓 1 +x:1 +产道 1 +x:1 +胆石病 1 +x:1 +羊坊店 1 +x:1 +瞬息 1 +x:1 +主干渠 1 +x:1 +过渡年 1 +x:1 +老面子 1 +x:1 +独联体队 1 +x:1 +时气 1 +x:1 +解劝 1 +x:1 +发光 1 +x:1 +舞钢 1 +x:1 +亳州 1 +x:1 +发冷 1 +x:1 +徒劳 1 +x:1 +集中制 1 +x:1 +斜襟 1 +x:1 +店貌 1 +x:1 +茶艺馆 1 +x:1 +茄鲞 1 +x:1 +成活关 1 +x:1 +曈曈 1 +x:1 +危殆 1 +x:1 +痢疾 1 +x:1 +事务员 1 +x:1 +该峰 1 +x:1 +锡 14 +x:14 +爱尔兰岛 1 +x:1 +斯拉夫 1 +x:1 +勾连 1 +x:1 +豪气 1 +x:1 +劳资政 1 +x:1 +轮牧 1 +x:1 +略作 1 +x:1 +商团 1 +x:1 +鼎盛 1 +x:1 +条法部 1 +x:1 +物理所 1 +x:1 +迁离 1 +x:1 +界牌镇 1 +x:1 +欢呼声 1 +x:1 +腋窝 1 +x:1 +隐患区 1 +x:1 +怦然心动 1 +x:1 +祛暑 1 +x:1 +实用化 1 +x:1 +北约 1 +x:1 +走私船 1 +x:1 +追问 1 +x:1 +发出 1 +x:1 +发函 1 +x:1 +不愧于 1 +x:1 +碉堡 1 +x:1 +针孔 1 +x:1 +有序性 1 +x:1 +光身汉 1 +x:1 +运送 1 +x:1 +叻 1 +x:1 +思潮 1 +x:1 +兔业 1 +x:1 +受伤者 1 +x:1 +改革面 1 +x:1 +毛刺 1 +x:1 +受益者 1 +x:1 +等级赛 1 +x:1 +大学法 1 +x:1 +埃博拉 1 +x:1 +该岛 1 +x:1 +角球 1 +x:1 +家政班 1 +x:1 +毛利 1 +x:1 +预冷肉 1 +x:1 +着儿 1 +x:1 +避难就易 1 +x:1 +磨砖对缝 1 +x:1 +毛发 1 +x:1 +贼窝 1 +x:1 +燕南园 1 +x:1 +铲吸量 1 +x:1 +缓建 1 +x:1 +留心 1 +x:1 +发债 1 +x:1 +淡泊明志 1 +x:1 +冬笋 1 +x:1 +有偿转让 1 +x:1 +吹牛话 1 +x:1 +搜求 1 +x:1 +德和园 1 +x:1 +封志 1 +x:1 +高打 1 +x:1 +领有 1 +x:1 +救助金 1 +x:1 +四有 1 +x:1 +以防 1 +x:1 +锻炼者 1 +x:1 +徐徐 1 +x:1 +轮班 1 +x:1 +巡查制 1 +x:1 +蝇头小利 1 +x:1 +击球 1 +x:1 +岗南镇 1 +x:1 +总裁室 1 +x:1 +乔装 1 +x:1 +吉日 1 +x:1 +真真切切 1 +x:1 +园田 1 +x:1 +卵细胞核 1 +x:1 +肉制品 1 +x:1 +二轻企字 1 +x:1 +神笔 1 +x:1 +雍 4 +x:4 +廊庑 1 +x:1 +守望者 1 +x:1 +姓 166 +x:166 +此种 1 +x:1 +玩忽职守 1 +x:1 +四仙桌 1 +x:1 +暂停 1 +x:1 +人寿险 1 +x:1 +遗像 1 +x:1 +一口一声 1 +x:1 +村埭 1 +x:1 +龙口夺食 1 +x:1 +吉方 1 +x:1 +巡逻舰 1 +x:1 +奉承 1 +x:1 +撤消 1 +x:1 +塑造 1 +x:1 +北方话 1 +x:1 +操纵员 1 +x:1 +遵章守纪 1 +x:1 +溢价 1 +x:1 +裁决书 1 +x:1 +梁庄乡 1 +x:1 +彭楼 1 +x:1 +异党 1 +x:1 +寻刺 1 +x:1 +环环相扣 1 +x:1 +久已 1 +x:1 +养壶笔 1 +x:1 +期望 1 +x:1 +濒危 1 +x:1 +春耕大忙 1 +x:1 +发傻 1 +x:1 +佃农 1 +x:1 +方略 1 +x:1 +门户 1 +x:1 +极量 1 +x:1 +财务处 1 +x:1 +烟蚜 1 +x:1 +勋位 1 +x:1 +中枢神经 1 +x:1 +解危 1 +x:1 +台怀镇寺 1 +x:1 +天台县 1 +x:1 +商城 1 +x:1 +义愤 1 +x:1 +如期而至 1 +x:1 +讨教 1 +x:1 +相对真理 1 +x:1 +糖度 1 +x:1 +众星拱月 1 +x:1 +池袋 1 +x:1 +污染费 1 +x:1 +烂肠瘟 1 +x:1 +大谱儿 1 +x:1 +贫困乡 1 +x:1 +楼庄乡 1 +x:1 +该州 1 +x:1 +期末 1 +x:1 +留影 1 +x:1 +密密匝匝 1 +x:1 +席篾 1 +x:1 +复印机 1 +x:1 +猊糖 1 +x:1 +北沙滩 1 +x:1 +无拘无束 1 +x:1 +海基会 1 +x:1 +组织生活 1 +x:1 +铸锭 1 +x:1 +帽徽 1 +x:1 +朝拜 1 +x:1 +占有量 1 +x:1 +噍 1 +x:1 +便民店 1 +x:1 +电信号 1 +x:1 +略为 1 +x:1 +饮水管 1 +x:1 +期权 1 +x:1 +贴画 1 +x:1 +埤城镇 1 +x:1 +找找 1 +x:1 +铸锅 1 +x:1 +门扉 1 +x:1 +瓶 97 +x:97 +产量 1 +x:1 +非驴非马 1 +x:1 +门扇 1 +x:1 +火烧火燎 1 +x:1 +离乱 1 +x:1 +茧花 1 +x:1 +饲草料 1 +x:1 +太子 1 +x:1 +涝河桥 1 +x:1 +褊 1 +x:1 +沈阳城 1 +x:1 +增光添彩 1 +x:1 +硝锵水 1 +x:1 +离乡 1 +x:1 +炒货 1 +x:1 +爱康工程 1 +x:1 +屋椽 1 +x:1 +使用价值 1 +x:1 +冥 1 +x:1 +诺基亚 1 +x:1 +意义 1 +x:1 +春上 1 +x:1 +溪畔 1 +x:1 +见面礼 1 +x:1 +并重 1 +x:1 +吐丝 1 +x:1 +杜尔伯特 1 +x:1 +鹦鹉螺 1 +x:1 +吕城 1 +x:1 +发包 1 +x:1 +浮水印 1 +x:1 +商周 1 +x:1 +方盒 1 +x:1 +藏而不露 1 +x:1 +流线 1 +x:1 +张挂 1 +x:1 +政治权利 1 +x:1 +客运部 1 +x:1 +流经 1 +x:1 +地保 1 +x:1 +发卡 1 +x:1 +上索恩省 1 +x:1 +咖啡色 1 +x:1 +印制法 1 +x:1 +苍松 1 +x:1 +天鹅座 1 +x:1 +迈皋桥 1 +x:1 +增效 1 +x:1 +装配图 1 +x:1 +发单 1 +x:1 +终结者 1 +x:1 +离业 1 +x:1 +故旧 1 +x:1 +谬语 1 +x:1 +危楼 1 +x:1 +该市 1 +x:1 +谬说 1 +x:1 +洋灰 1 +x:1 +购地 1 +x:1 +穿山越谷 1 +x:1 +巡夜 1 +x:1 +叶蛋白 1 +x:1 +经济部 1 +x:1 +改良羊 1 +x:1 +消逝 1 +x:1 +离任 1 +x:1 +事业费 1 +x:1 +留居 1 +x:1 +陆川 1 +x:1 +信任度 1 +x:1 +商品 1 +x:1 +下狱 1 +x:1 +乍浦 1 +x:1 +颈椎 1 +x:1 +使用 1 +x:1 +消退 1 +x:1 +松岗 1 +x:1 +净菜 1 +x:1 +冲击伤 1 +x:1 +沿边 1 +x:1 +春事 1 +x:1 +中小幼 1 +x:1 +咖啡节 1 +x:1 +驱邪灭鬼 1 +x:1 +有机体 1 +x:1 +保龄球馆 1 +x:1 +封山 1 +x:1 +吉普 1 +x:1 +望仙坡 1 +x:1 +最终 1 +x:1 +贸易界 1 +x:1 +扶老助孤 1 +x:1 +冷配点 1 +x:1 +我区 1 +x:1 +帆张网 1 +x:1 +蓓蕾 1 +x:1 +练市镇 1 +x:1 +成本额 1 +x:1 +团拜会 1 +x:1 +佩戴 1 +x:1 +完全 1 +x:1 +协调组 1 +x:1 +学府路 1 +x:1 +地位 1 +x:1 +睡 141 +x:141 +俱乐部 1 +x:1 +监督法 1 +x:1 +框架 1 +x:1 +舞阳 1 +x:1 +贝叶树 1 +x:1 +射击 1 +x:1 +脱产 1 +x:1 +永恒 1 +x:1 +消遣 1 +x:1 +该店 1 +x:1 +万家灯火 1 +x:1 +消遥 1 +x:1 +纪录片 1 +x:1 +招摇撞骗 1 +x:1 +旁切圆 1 +x:1 +制衡性 1 +x:1 +表面张力 1 +x:1 +迅猛 1 +x:1 +水翼船 1 +x:1 +历程 1 +x:1 +脱位 1 +x:1 +专题讨论 1 +x:1 +这里 1 +x:1 +食品袋 1 +x:1 +俄勒冈州 1 +x:1 +东河塘 1 +x:1 +新村港 1 +x:1 +财务室 1 +x:1 +穗轴 1 +x:1 +地产 1 +x:1 +扼杀 1 +x:1 +犹 56 +x:56 +风湿病 1 +x:1 +降香 1 +x:1 +非行政 1 +x:1 +糖尿 1 +x:1 +小黄鱼 1 +x:1 +巩固率 1 +x:1 +事务型 1 +x:1 +领教 1 +x:1 +埋 109 +x:109 +压抑感 1 +x:1 +吉林 1 +x:1 +解冻 1 +x:1 +舞鞋 1 +x:1 +慢支炎 1 +x:1 +解决 1 +x:1 +着力 1 +x:1 +新召苏木 1 +x:1 +导演铃 1 +x:1 +超度 1 +x:1 +离休 1 +x:1 +俏立 1 +x:1 +地价 1 +x:1 +仓储业 1 +x:1 +至高无上 1 +x:1 +黑名单 1 +x:1 +问津 1 +x:1 +客运量 1 +x:1 +性情 1 +x:1 +打饱嗝儿 1 +x:1 +意会 1 +x:1 +代代红 1 +x:1 +万丈深渊 1 +x:1 +天鹅径 1 +x:1 +载歌行 1 +x:1 +归结点 1 +x:1 +磨漆画 1 +x:1 +能矿部长 1 +x:1 +脱俗 1 +x:1 +毛兔 1 +x:1 +哪里话 1 +x:1 +细片 1 +x:1 +青浦县 1 +x:1 +下班 1 +x:1 +信访件 1 +x:1 +集成块 1 +x:1 +地上 1 +x:1 +地下 1 +x:1 +其意 1 +x:1 +关节炎 1 +x:1 +不复存在 1 +x:1 +匣 1 +x:1 +妖娆 1 +x:1 +毛兴 1 +x:1 +地主 1 +x:1 +关节点 1 +x:1 +营私舞弊 1 +x:1 +主办人 1 +x:1 +春供 1 +x:1 +耗尽 1 +x:1 +还原染料 1 +x:1 +合成染料 1 +x:1 +春修 1 +x:1 +核心组 1 +x:1 +蛋汤 1 +x:1 +冬种 1 +x:1 +第一流 1 +x:1 +形态学 1 +x:1 +唐海镇 1 +x:1 +陶然亭 1 +x:1 +驱护舰 1 +x:1 +期效 1 +x:1 +珙泉镇 1 +x:1 +菘 1 +x:1 +富裕型 1 +x:1 +廊尾 1 +x:1 +手指尖 1 +x:1 +持外汇者 1 +x:1 +认清 1 +x:1 +纵横交错 1 +x:1 +期数 1 +x:1 +一喷三防 1 +x:1 +宋初 1 +x:1 +交费 1 +x:1 +大张挞伐 1 +x:1 +地价税 1 +x:1 +一命呜呼 1 +x:1 +烂根 1 +x:1 +红花油 1 +x:1 +领率课 1 +x:1 +贷学金 1 +x:1 +道贺 1 +x:1 +借东风 1 +x:1 +波尔多 1 +x:1 +能上能下 1 +x:1 +论点 1 +x:1 +川籍 1 +x:1 +药理学 1 +x:1 +刊文 1 +x:1 +钢丝锯 1 +x:1 +书架 1 +x:1 +便民卡 1 +x:1 +射弩 1 +x:1 +危机 1 +x:1 +整整齐齐 1 +x:1 +滥杀 1 +x:1 +敬老养老 1 +x:1 +印刷品 1 +x:1 +荡秋千 1 +x:1 +强 1735 +x:1735 +五代同堂 1 +x:1 +中组部 1 +x:1 +沙色乡 1 +x:1 +北仑河口 1 +x:1 +碧螺春 1 +x:1 +参知政事 1 +x:1 +台港澳 1 +x:1 +便民化 1 +x:1 +孝肃亭 1 +x:1 +留办 1 +x:1 +塔桥村 1 +x:1 +高教法 1 +x:1 +五洲四海 1 +x:1 +时态 1 +x:1 +拉贾斯坦 1 +x:1 +置身 1 +x:1 +椒盐 1 +x:1 +去世 1 +x:1 +村干部 1 +x:1 +先决 1 +x:1 +咖啡豆 1 +x:1 +营房 1 +x:1 +代销店 1 +x:1 +用电户 1 +x:1 +孩子家 1 +x:1 +晴 46 +x:46 +豪情 1 +x:1 +制度化 1 +x:1 +射影 1 +x:1 +表扬稿 1 +x:1 +糖厂 1 +x:1 +长岭县 1 +x:1 +诚如 1 +x:1 +锡耶那一 1 +x:1 +再说 1 +x:1 +商嫂 1 +x:1 +屋架 1 +x:1 +污染者 1 +x:1 +竹阳村 1 +x:1 +旦角儿 1 +x:1 +锂业 1 +x:1 +糖原 1 +x:1 +开拓力 1 +x:1 +换季 1 +x:1 +白炽灯 1 +x:1 +渊远流长 1 +x:1 +永清 1 +x:1 +设有 1 +x:1 +既往不咎 1 +x:1 +知法 1 +x:1 +三角镇 1 +x:1 +点名册 1 +x:1 +西餐厅 1 +x:1 +一码事 1 +x:1 +第一手 1 +x:1 +医史学者 1 +x:1 +毛布 1 +x:1 +理发员 1 +x:1 +当头一棒 1 +x:1 +豪情壮志 1 +x:1 +啸 11 +x:11 +浙 23 +x:23 +向导员 1 +x:1 +顺顺当当 1 +x:1 +炒菜 1 +x:1 +故此 1 +x:1 +威风凛凛 1 +x:1 +贻贝 1 +x:1 +趁亮 1 +x:1 +视听型 1 +x:1 +不折不扣 1 +x:1 +猿猴 1 +x:1 +水葫芦 1 +x:1 +托管费 1 +x:1 +原作者 1 +x:1 +糖分 1 +x:1 +介绍所 1 +x:1 +村容 1 +x:1 +马来西亚 1 +x:1 +基准价 1 +x:1 +选赛 1 +x:1 +镇区 1 +x:1 +封发 1 +x:1 +右肘 1 +x:1 +框框 1 +x:1 +会议费 1 +x:1 +低高型 1 +x:1 +藏族人 1 +x:1 +封口 1 +x:1 +川芎 1 +x:1 +果敢性 1 +x:1 +冬眠 1 +x:1 +国光村 1 +x:1 +村官 1 +x:1 +门源 1 +x:1 +徒弟 1 +x:1 +申办人 1 +x:1 +短池赛 1 +x:1 +领款 1 +x:1 +铤而走险 1 +x:1 +悱 1 +x:1 +刊播 1 +x:1 +董塘 1 +x:1 +村宅 1 +x:1 +发射 1 +x:1 +封号 1 +x:1 +该党 1 +x:1 +留史 1 +x:1 +口口声声 1 +x:1 +吾 22 +x:22 +南侧 1 +x:1 +小卖 1 +x:1 +策勒县 1 +x:1 +迫降 1 +x:1 +山沟沟 1 +x:1 +学前班 1 +x:1 +村寨 1 +x:1 +针刺麻醉 1 +x:1 +毒死 1 +x:1 +蜡板 1 +x:1 +发展 1 +x:1 +鹰嘴 1 +x:1 +身板 1 +x:1 +陪 99 +x:99 +缸盆 1 +x:1 +市话局 1 +x:1 +慰 10 +x:10 +随波逐流 1 +x:1 +当局者迷 1 +x:1 +大象者 1 +x:1 +题花 1 +x:1 +射干 1 +x:1 +任免 1 +x:1 +印染 1 +x:1 +苍梧 1 +x:1 +诱虫灯 1 +x:1 +借读费 1 +x:1 +间歇泉 1 +x:1 +执导 1 +x:1 +信任带 1 +x:1 +事半功倍 1 +x:1 +磐安县 1 +x:1 +酉阳县 1 +x:1 +乡统筹费 1 +x:1 +准儿 1 +x:1 +角票 1 +x:1 +死皮赖脸 1 +x:1 +走私轮 1 +x:1 +香化 1 +x:1 +胡萝卜 1 +x:1 +乘其不备 1 +x:1 +至关重要 1 +x:1 +元首 1 +x:1 +虐杀 1 +x:1 +内宾 1 +x:1 +不折不挠 1 +x:1 +料儿 1 +x:1 +龙塘坝乡 1 +x:1 +勤工助学 1 +x:1 +核心点 1 +x:1 +蜡果 1 +x:1 +钾 8 +x:8 +徭役地租 1 +x:1 +事务处 1 +x:1 +积存数 1 +x:1 +商定 1 +x:1 +背水一战 1 +x:1 +浓度值 1 +x:1 +豁然开朗 1 +x:1 +形式主义 1 +x:1 +轮缘 1 +x:1 +明瓦 1 +x:1 +村学 1 +x:1 +北科大 1 +x:1 +勾芡 1 +x:1 +任凭 1 +x:1 +赴任 1 +x:1 +村子 1 +x:1 +草儿 1 +x:1 +灯红酒绿 1 +x:1 +解开 1 +x:1 +原配 1 +x:1 +交换价值 1 +x:1 +假释犯 1 +x:1 +蜡染 1 +x:1 +工商行 1 +x:1 +古建 1 +x:1 +仰天 1 +x:1 +风筝会 1 +x:1 +趁便 1 +x:1 +阜宁县 1 +x:1 +修葺一新 1 +x:1 +设施 1 +x:1 +该剧 1 +x:1 +针线活 1 +x:1 +根由 1 +x:1 +两控区 1 +x:1 +洞见 1 +x:1 +红红火火 1 +x:1 +旧俗 1 +x:1 +危改 1 +x:1 +日思夜想 1 +x:1 +森警 1 +x:1 +五福涧村 1 +x:1 +钢城 1 +x:1 +碗厂乡 1 +x:1 +上方岁贡 1 +x:1 +发式 1 +x:1 +淑女 1 +x:1 +完工 1 +x:1 +日程表 1 +x:1 +加薪 1 +x:1 +残墙断壁 1 +x:1 +清河区 1 +x:1 +遵义城 1 +x:1 +呼啸 1 +x:1 +难于登天 1 +x:1 +卸下 1 +x:1 +畅快 1 +x:1 +该刊 1 +x:1 +折断 1 +x:1 +长方形 1 +x:1 +后则腰村 1 +x:1 +稀奇古怪 1 +x:1 +时或 1 +x:1 +版权日 1 +x:1 +单雄蕊 1 +x:1 +灼 4 +x:4 +执壶 1 +x:1 +北赵村 1 +x:1 +加强型 1 +x:1 +新秀队 1 +x:1 +热市镇 1 +x:1 +列伊 1 +x:1 +支取额 1 +x:1 +碎步儿 1 +x:1 +诚实 1 +x:1 +灵璧县 1 +x:1 +鉴定 1 +x:1 +助建 1 +x:1 +蓬莱市 1 +x:1 +发微 1 +x:1 +小负 1 +x:1 +旧体 1 +x:1 +久别 1 +x:1 +列传 1 +x:1 +第一性 1 +x:1 +下绊 1 +x:1 +旧作 1 +x:1 +羽绒布 1 +x:1 +西柏坡村 1 +x:1 +色素性 1 +x:1 +料到 1 +x:1 +室内剧 1 +x:1 +科教企 1 +x:1 +刨土问食 1 +x:1 +加工费 1 +x:1 +江西 1 +x:1 +下级 1 +x:1 +冰啤 1 +x:1 +桑葚儿 1 +x:1 +清河县 1 +x:1 +永庆 1 +x:1 +陆军 1 +x:1 +夹克 1 +x:1 +村塾 1 +x:1 +卑 4 +x:4 +力臂 1 +x:1 +新加坡元 1 +x:1 +昆明市 1 +x:1 +七星街 1 +x:1 +出口值 1 +x:1 +冬瓜 1 +x:1 +下线 1 +x:1 +胜 531 +x:531 +方程 1 +x:1 +亳县 1 +x:1 +琼子 1 +x:1 +邱北县 1 +x:1 +唁电 1 +x:1 +孩子头 1 +x:1 +川红 1 +x:1 +喀拉和顺 1 +x:1 +大曲虫 1 +x:1 +掖县 1 +x:1 +朝气 1 +x:1 +脂膏 1 +x:1 +该卡 1 +x:1 +加蓬 1 +x:1 +檐沟 1 +x:1 +湘东 1 +x:1 +有加利 1 +x:1 +火钳 1 +x:1 +印数 1 +x:1 +发帖 1 +x:1 +文化财 1 +x:1 +再行 1 +x:1 +毛巾 1 +x:1 +宜丰县 1 +x:1 +左权县 1 +x:1 +储蓄率 1 +x:1 +发布 1 +x:1 +解州 1 +x:1 +村妇 1 +x:1 +娶 31 +x:31 +托举 1 +x:1 +流通领域 1 +x:1 +运煤车 1 +x:1 +搀杂 1 +x:1 +延展性 1 +x:1 +峭壁 1 +x:1 +倦容 1 +x:1 +石家庄 1 +x:1 +四化建设 1 +x:1 +击穿 1 +x:1 +旧人 1 +x:1 +大为 1 +x:1 +高墩台 1 +x:1 +旧交 1 +x:1 +笋岗路 1 +x:1 +危若累卵 1 +x:1 +该区 1 +x:1 +村姑 1 +x:1 +源文件 1 +x:1 +长话局 1 +x:1 +村委 1 +x:1 +撤掉 1 +x:1 +过目不忘 1 +x:1 +坨 1 +x:1 +湘乡 1 +x:1 +封冰 1 +x:1 +鏖兵 1 +x:1 +封冻 1 +x:1 +试飞员 1 +x:1 +旧事 1 +x:1 +风花雪月 1 +x:1 +一时间 1 +x:1 +柔情蜜意 1 +x:1 +商委 1 +x:1 +村头 1 +x:1 +址 7 +x:7 +消耗量 1 +x:1 +立法法 1 +x:1 +撤换 1 +x:1 +旧书 1 +x:1 +辅导性 1 +x:1 +炒股 1 +x:1 +泥石流 1 +x:1 +旧习 1 +x:1 +村夫 1 +x:1 +湘云 1 +x:1 +该台 1 +x:1 +题联 1 +x:1 +罗湖桥 1 +x:1 +性气 1 +x:1 +急人之难 1 +x:1 +国王队 1 +x:1 +完小 1 +x:1 +梁园 1 +x:1 +书札 1 +x:1 +封关 1 +x:1 +岁岁 1 +x:1 +教三楼 1 +x:1 +并非易事 1 +x:1 +一年半载 1 +x:1 +绕梁 1 +x:1 +列为 1 +x:1 +方策 1 +x:1 +少数民族 1 +x:1 +缩衣节食 1 +x:1 +回头见 1 +x:1 +虐政 1 +x:1 +溴氰菊 1 +x:1 +徒工 1 +x:1 +该县 1 +x:1 +著书立说 1 +x:1 +走私货 1 +x:1 +雅宝路 1 +x:1 +出口儿 1 +x:1 +大营子镇 1 +x:1 +永济 1 +x:1 +文化路 1 +x:1 +讲演团 1 +x:1 +乌拉圭 1 +x:1 +舒缓 1 +x:1 +旧业 1 +x:1 +该厂 1 +x:1 +不堪入耳 1 +x:1 +设摊 1 +x:1 +发廊 1 +x:1 +盾 39 +x:39 +疥疮 1 +x:1 +发夹 1 +x:1 +徐鹰牌 1 +x:1 +申购量 1 +x:1 +传奇性 1 +x:1 +健壮 1 +x:1 +红花村 1 +x:1 +出口国 1 +x:1 +封四 1 +x:1 +牛头山 1 +x:1 +熟能生巧 1 +x:1 +友邦 1 +x:1 +光碟 1 +x:1 +拮据 1 +x:1 +扇贝笼 1 +x:1 +李庄乡 1 +x:1 +推广车 1 +x:1 +四郎探母 1 +x:1 +村庄 1 +x:1 +煊赫 1 +x:1 +藏语系 1 +x:1 +失窃案 1 +x:1 +施业区 1 +x:1 +成组技术 1 +x:1 +白菜心 1 +x:1 +问明 1 +x:1 +蜡扦 1 +x:1 +榆荚 1 +x:1 +妮儿 1 +x:1 +任命 1 +x:1 +杂草 1 +x:1 +意向性 1 +x:1 +连续不断 1 +x:1 +联网化 1 +x:1 +乌梅 1 +x:1 +赖 74 +x:74 +吃苦头 1 +x:1 +射孔 1 +x:1 +吃苦耐劳 1 +x:1 +惩恶扬善 1 +x:1 +优待证 1 +x:1 +发套 1 +x:1 +发奖 1 +x:1 +琼州 1 +x:1 +库 86 +x:86 +评为 1 +x:1 +普照寺 1 +x:1 +昌都县 1 +x:1 +发奋 1 +x:1 +方粒 1 +x:1 +期满 1 +x:1 +工商费 1 +x:1 +事务局 1 +x:1 +石刁柏 1 +x:1 +祸端 1 +x:1 +桦甸 1 +x:1 +捕头 1 +x:1 +发妻 1 +x:1 +陆域 1 +x:1 +划伤 1 +x:1 +三棵树 1 +x:1 +变化无常 1 +x:1 +廊坊 1 +x:1 +柱 20 +x:20 +阿拉善旗 1 +x:1 +辖内 1 +x:1 +琼崖 1 +x:1 +缝补 1 +x:1 +新城市 1 +x:1 +优先级 1 +x:1 +沐浴 1 +x:1 +陆基 1 +x:1 +排风扇 1 +x:1 +樯 1 +x:1 +轮空 1 +x:1 +大安市 1 +x:1 +政务司 1 +x:1 +产草量 1 +x:1 +评价 1 +x:1 +桂竹 1 +x:1 +种子 1 +x:1 +村平 1 +x:1 +村干 1 +x:1 +不平衡性 1 +x:1 +商店 1 +x:1 +运动神经 1 +x:1 +安吉县 1 +x:1 +航速 1 +x:1 +暂委 1 +x:1 +齿轮 1 +x:1 +监控 1 +x:1 +爷儿 1 +x:1 +游迹 1 +x:1 +蛋松 1 +x:1 +智牙 1 +x:1 +南南合作 1 +x:1 +奥卢市 1 +x:1 +席位数 1 +x:1 +八面来风 1 +x:1 +退居二线 1 +x:1 +后人乘凉 1 +x:1 +碑文 1 +x:1 +印报 1 +x:1 +非常设 1 +x:1 +吃喝玩乐 1 +x:1 +村徽 1 +x:1 +时数 1 +x:1 +愈合 1 +x:1 +壮年人 1 +x:1 +蒯 5 +x:5 +贴片 1 +x:1 +站里 1 +x:1 +古铜色 1 +x:1 +时效 1 +x:1 +圪塔村 1 +x:1 +解密 1 +x:1 +处理不当 1 +x:1 +林场村 1 +x:1 +哲言 1 +x:1 +魂灵 1 +x:1 +柳木 1 +x:1 +流传日盛 1 +x:1 +土建工程 1 +x:1 +全彩印 1 +x:1 +划价 1 +x:1 +轮箍 1 +x:1 +引诱 1 +x:1 +平陆县 1 +x:1 +黍 1 +x:1 +圆舞曲 1 +x:1 +评优 1 +x:1 +托莱多城 1 +x:1 +幡然醒悟 1 +x:1 +时政 1 +x:1 +千秋万代 1 +x:1 +月亮门儿 1 +x:1 +大郑镇 1 +x:1 +苜蓿 1 +x:1 +着墨 1 +x:1 +稀有元素 1 +x:1 +徒孙 1 +x:1 +评传 1 +x:1 +出口型 1 +x:1 +宅门 1 +x:1 +满招损 1 +x:1 +使绊 1 +x:1 +党校 1 +x:1 +调处员 1 +x:1 +评估 1 +x:1 +豪放 1 +x:1 +痱子粉 1 +x:1 +时日 1 +x:1 +今文经 1 +x:1 +怒吼 1 +x:1 +花媳妇儿 1 +x:1 +骤然 1 +x:1 +时时 1 +x:1 +下移 1 +x:1 +封坛 1 +x:1 +存在 1 +x:1 +组织部长 1 +x:1 +岁寒三友 1 +x:1 +红 434 +x:434 +速滑界 1 +x:1 +白菜帮 1 +x:1 +下种 1 +x:1 +开拓型 1 +x:1 +划一 1 +x:1 +三里河 1 +x:1 +W 9 +x:9 +用心险恶 1 +x:1 +先君 1 +x:1 +九州岛 1 +x:1 +讲解员 1 +x:1 +琼山 1 +x:1 +滥报 1 +x:1 +武状元 1 +x:1 +心劲儿 1 +x:1 +日射角 1 +x:1 +出口地 1 +x:1 +启动点 1 +x:1 +到位数 1 +x:1 +留在 1 +x:1 +忍心 1 +x:1 +时文 1 +x:1 +李营镇 1 +x:1 +孝昌县 1 +x:1 +平坦 1 +x:1 +封地 1 +x:1 +文化课 1 +x:1 +纪事 1 +x:1 +项 3595 +x:3595 +村级 1 +x:1 +站段 1 +x:1 +卿 12 +x:12 +犹为未晚 1 +x:1 +云和县 1 +x:1 +爆裂声 1 +x:1 +数以亿计 1 +x:1 +民主党 1 +x:1 +竹椅 1 +x:1 +脊 3 +x:3 +老有所乐 1 +x:1 +野菜 1 +x:1 +临渊羡鱼 1 +x:1 +反作用力 1 +x:1 +言多语失 1 +x:1 +驮篓 1 +x:1 +贻误 1 +x:1 +商山 1 +x:1 +妥 18 +x:18 +出口品 1 +x:1 +言 231 +x:231 +众将 1 +x:1 +傀儡戏 1 +x:1 +驴年马月 1 +x:1 +介身 1 +x:1 +鸥鸟 1 +x:1 +窗玻璃 1 +x:1 +哥德堡市 1 +x:1 +无记名 1 +x:1 +索饵场 1 +x:1 +冬灌 1 +x:1 +圣母院 1 +x:1 +法新社 1 +x:1 +舆情 1 +x:1 +着实 1 +x:1 +文化街 1 +x:1 +惟 14 +x:14 +双刃 1 +x:1 +门槛 1 +x:1 +集成度 1 +x:1 +老有所为 1 +x:1 +崇明县 1 +x:1 +红旗渠 1 +x:1 +峻拔秀逸 1 +x:1 +搀扶 1 +x:1 +德安县 1 +x:1 +碑柱 1 +x:1 +繁荣带 1 +x:1 +风湿类 1 +x:1 +波兹南 1 +x:1 +理发刀 1 +x:1 +归档 1 +x:1 +非焦油 1 +x:1 +该团 1 +x:1 +该国 1 +x:1 +黑黝黝 1 +x:1 +格威特杯 1 +x:1 +鲭江 1 +x:1 +一般而言 1 +x:1 +暂定 1 +x:1 +完备 1 +x:1 +农场主 1 +x:1 +自卸船 1 +x:1 +桶子 1 +x:1 +总星系 1 +x:1 +国语课 1 +x:1 +西敏司寺 1 +x:1 +调三斡四 1 +x:1 +松林区 1 +x:1 +医疗组 1 +x:1 +象素 1 +x:1 +空山坝 1 +x:1 +留名 1 +x:1 +单身汉 1 +x:1 +门楼 1 +x:1 +自家人 1 +x:1 +顶坪村 1 +x:1 +诚心 1 +x:1 +盐 30 +x:30 +购得 1 +x:1 +一事无成 1 +x:1 +即便 1 +x:1 +完好 1 +x:1 +羁縻 1 +x:1 +冬烘 1 +x:1 +料器 1 +x:1 +一展才华 1 +x:1 +碑林 1 +x:1 +小院儿 1 +x:1 +测距标 1 +x:1 +银河 1 +x:1 +多幕剧 1 +x:1 +乙种射线 1 +x:1 +热核反应 1 +x:1 +生橡胶 1 +x:1 +固镇 1 +x:1 +统计学家 1 +x:1 +轮种 1 +x:1 +文 523 +x:523 +正直 1 +x:1 +贸易系 1 +x:1 +直贡派 1 +x:1 +直挺挺 1 +x:1 +新针疗法 1 +x:1 +沉痛 1 +x:1 +冬训制 1 +x:1 +理发厅 1 +x:1 +吹号者 1 +x:1 +贴现 1 +x:1 +哺养 1 +x:1 +纸包 1 +x:1 +百科辞典 1 +x:1 +海岛县 1 +x:1 +一般而论 1 +x:1 +毫无来由 1 +x:1 +软件业 1 +x:1 +出国梦 1 +x:1 +下等 1 +x:1 +峭岩 1 +x:1 +点破 1 +x:1 +北京猿人 1 +x:1 +购并 1 +x:1 +危急 1 +x:1 +祸祟 1 +x:1 +陕甘宁 1 +x:1 +楼层 1 +x:1 +门梁 1 +x:1 +舞龙 1 +x:1 +负债国 1 +x:1 +五岭 1 +x:1 +加码 1 +x:1 +平遥城 1 +x:1 +萍踪浪迹 1 +x:1 +良言 1 +x:1 +该地 1 +x:1 +秧苗 1 +x:1 +时段性 1 +x:1 +接驳端子 1 +x:1 +温血动物 1 +x:1 +领海 1 +x:1 +时月 1 +x:1 +开箱费 1 +x:1 +娇丽 1 +x:1 +临建棚 1 +x:1 +重头 1 +x:1 +财务司 1 +x:1 +汤圆粉 1 +x:1 +绥滨县 1 +x:1 +保龄球道 1 +x:1 +时期 1 +x:1 +傲气 1 +x:1 +专心 1 +x:1 +性格 1 +x:1 +商州 1 +x:1 +苍溪 1 +x:1 +双勾 1 +x:1 +过人之处 1 +x:1 +妓院 1 +x:1 +汾阳市 1 +x:1 +男女老少 1 +x:1 +知母 1 +x:1 +无线电话 1 +x:1 +出口商 1 +x:1 +该城 1 +x:1 +下篇 1 +x:1 +理发匠 1 +x:1 +检察官法 1 +x:1 +朽烂 1 +x:1 +苍溟 1 +x:1 +沈阳市 1 +x:1 +取水口 1 +x:1 +老有所依 1 +x:1 +文化观 1 +x:1 +搭桥术 1 +x:1 +豪杰 1 +x:1 +全省性 1 +x:1 +偕 8 +x:8 +文化角 1 +x:1 +锉刀 1 +x:1 +祸福 1 +x:1 +回头路 1 +x:1 +毛头 1 +x:1 +义愤填膺 1 +x:1 +闭门谢客 1 +x:1 +自限性 1 +x:1 +虱 1 +x:1 +山西路 1 +x:1 +天秤座 1 +x:1 +拉吊型 1 +x:1 +门框 1 +x:1 +东南 1 +x:1 +滑动摩擦 1 +x:1 +通力 1 +x:1 +潮田乡 1 +x:1 +渤西 1 +x:1 +沓 19 +x:19 +苍然 1 +x:1 +忽喇喇 1 +x:1 +针头 1 +x:1 +好转 1 +x:1 +架式 1 +x:1 +麟 10 +x:10 +哺乳 1 +x:1 +怠 2 +x:2 +高保真 1 +x:1 +中幡 1 +x:1 +下摆 1 +x:1 +越岭 1 +x:1 +评剧 1 +x:1 +铜氨丝 1 +x:1 +赖皮 1 +x:1 +贝叶经 1 +x:1 +滚烫滚烫 1 +x:1 +中年 1 +x:1 +专利品 1 +x:1 +公园式 1 +x:1 +袁庄 1 +x:1 +棍术 1 +x:1 +旭日 1 +x:1 +存放点 1 +x:1 +深恶痛绝 1 +x:1 +地委 1 +x:1 +评分 1 +x:1 +虬曲挺秀 1 +x:1 +名酒 1 +x:1 +中师 1 +x:1 +鞠躬 1 +x:1 +徐官屯村 1 +x:1 +篮球界 1 +x:1 +朝着 1 +x:1 +遴选 1 +x:1 +翘角 1 +x:1 +称誉 1 +x:1 +梅树 1 +x:1 +浓烟滚滚 1 +x:1 +评判 1 +x:1 +脂肪酸 1 +x:1 +德化 1 +x:1 +竞折腰 1 +x:1 +咣当 1 +x:1 +营业室 1 +x:1 +滥编 1 +x:1 +滴溜溜转 1 +x:1 +利益者 1 +x:1 +药草 1 +x:1 +邀 58 +x:58 +钢笔套 1 +x:1 +松散型 1 +x:1 +伸张 1 +x:1 +财综 1 +x:1 +挡住 1 +x:1 +地处 1 +x:1 +屈才 1 +x:1 +蜡纸 1 +x:1 +唱响 1 +x:1 +木头人儿 1 +x:1 +振拔 1 +x:1 +印绶 1 +x:1 +地头 1 +x:1 +缺残 1 +x:1 +诤言 1 +x:1 +堡垒 1 +x:1 +老中青少 1 +x:1 +油子 1 +x:1 +螺 1 +x:1 +烟霭霞影 1 +x:1 +鄱阳湖 1 +x:1 +地契 1 +x:1 +岭澳 1 +x:1 +减收增支 1 +x:1 +奢侈品 1 +x:1 +店风 1 +x:1 +聋 13 +x:13 +注重 1 +x:1 +莫衷一是 1 +x:1 +评功 1 +x:1 +迫近 1 +x:1 +兵器史 1 +x:1 +设置 1 +x:1 +焊工 1 +x:1 +留 420 +x:420 +残采 1 +x:1 +名片簿 1 +x:1 +唱和 1 +x:1 +上岗率 1 +x:1 +中度 1 +x:1 +内营力 1 +x:1 +印纹 1 +x:1 +意境 1 +x:1 +离境 1 +x:1 +汪家寨 1 +x:1 +苯基 1 +x:1 +固定性 1 +x:1 +北部湾 1 +x:1 +体魄 1 +x:1 +生猪业 1 +x:1 +颗粒肥料 1 +x:1 +来集镇 1 +x:1 +春天 1 +x:1 +朗读声 1 +x:1 +歌唱家 1 +x:1 +抄报 1 +x:1 +病死率 1 +x:1 +自各儿 1 +x:1 +咸涩 1 +x:1 +消融 1 +x:1 +倚仗 1 +x:1 +问答 1 +x:1 +旧金山 1 +x:1 +牧奎村 1 +x:1 +老有所养 1 +x:1 +米黄色 1 +x:1 +矿泉壶 1 +x:1 +碱 27 +x:27 +春夜 1 +x:1 +豪福 1 +x:1 +离奇 1 +x:1 +胶州市 1 +x:1 +评卷 1 +x:1 +救灾办 1 +x:1 +岚山 1 +x:1 +马约 1 +x:1 +马集镇 1 +x:1 +老顽固 1 +x:1 +掘坟鞭尸 1 +x:1 +空白行 1 +x:1 +中式 1 +x:1 +波浪 1 +x:1 +工商部 1 +x:1 +波海 1 +x:1 +拾零 1 +x:1 +下放 1 +x:1 +林业局 1 +x:1 +笔耕墨耘 1 +x:1 +脱失 1 +x:1 +地壳 1 +x:1 +象话 1 +x:1 +极贫村 1 +x:1 +步履艰难 1 +x:1 +翳翳 1 +x:1 +贡酒 1 +x:1 +意外 1 +x:1 +包容力 1 +x:1 +中弹 1 +x:1 +民族情绪 1 +x:1 +中心 1 +x:1 +斜纹布 1 +x:1 +列名 1 +x:1 +下旬 1 +x:1 +时称 1 +x:1 +电源线 1 +x:1 +三角铁 1 +x:1 +人为性 1 +x:1 +安乃近 1 +x:1 +稳操胜券 1 +x:1 +桦树 1 +x:1 +镇静剂 1 +x:1 +切乔维奇 1 +x:1 +上规模 1 +x:1 +兔子 1 +x:1 +明电 1 +x:1 +划分 1 +x:1 +地堡 1 +x:1 +南方局 1 +x:1 +茵陈蒿 1 +x:1 +淡水鱼 1 +x:1 +余杭 1 +x:1 +波涛 1 +x:1 +待续 1 +x:1 +历法 1 +x:1 +烟嘴儿 1 +x:1 +衣食父母 1 +x:1 +碑碣 1 +x:1 +桂林 1 +x:1 +言多必失 1 +x:1 +智胜 1 +x:1 +横倒竖歪 1 +x:1 +桂枝 1 +x:1 +下方 1 +x:1 +感同身受 1 +x:1 +屈指 1 +x:1 +个头儿 1 +x:1 +辅导费 1 +x:1 +故物 1 +x:1 +飘飘摇摇 1 +x:1 +鬼子 1 +x:1 +贸易战 1 +x:1 +原子量 1 +x:1 +坯 5 +x:5 +峨嵋 1 +x:1 +轮机 1 +x:1 +老婆儿 1 +x:1 +癌星 1 +x:1 +领班 1 +x:1 +海地图 1 +x:1 +中层 1 +x:1 +抬高 1 +x:1 +外语片 1 +x:1 +死有余辜 1 +x:1 +贺岁 1 +x:1 +德兴 1 +x:1 +周五 1 +x:1 +肥田粉 1 +x:1 +雷暴雨 1 +x:1 +名郡 1 +x:1 +时空 1 +x:1 +海魂衫 1 +x:1 +党徒 1 +x:1 +讲演会 1 +x:1 +算账 1 +x:1 +缥缈 1 +x:1 +露露 1 +x:1 +离婚 1 +x:1 +铬铁 1 +x:1 +牟平 1 +x:1 +合凤裙 1 +x:1 +党徽 1 +x:1 +中山 1 +x:1 +地宫 1 +x:1 +相仿 1 +x:1 +纪元 1 +x:1 +下调 1 +x:1 +中将 1 +x:1 +中小 1 +x:1 +中尉 1 +x:1 +党心 1 +x:1 +译 51 +x:51 +艳阳天 1 +x:1 +竖井 1 +x:1 +冬汛 1 +x:1 +三从四德 1 +x:1 +收集量 1 +x:1 +镇政府 1 +x:1 +去向 1 +x:1 +撞击力 1 +x:1 +伺奉 1 +x:1 +彩泉 1 +x:1 +囚牢 1 +x:1 +保龄球赛 1 +x:1 +性病 1 +x:1 +露面 1 +x:1 +大轧厂 1 +x:1 +面面土 1 +x:1 +钢笔字 1 +x:1 +审查委 1 +x:1 +手掌心 1 +x:1 +) 23886 +x:23886 +挨斗者 1 +x:1 +筒子楼 1 +x:1 +补税额 1 +x:1 +理发业 1 +x:1 +创例 1 +x:1 +新陈代谢 1 +x:1 +禀帖 1 +x:1 +字眼儿 1 +x:1 +中华门 1 +x:1 +傲然 1 +x:1 +囚犯 1 +x:1 +方才 1 +x:1 +门生 1 +x:1 +降调 1 +x:1 +梁子湖 1 +x:1 +衢州站 1 +x:1 +桥头堡 1 +x:1 +波源 1 +x:1 +中峰 1 +x:1 +旧址 1 +x:1 +击掌 1 +x:1 +拉丁字母 1 +x:1 +连珠炮 1 +x:1 +旧地 1 +x:1 +煤化工 1 +x:1 +呕尽心血 1 +x:1 +划入 1 +x:1 +留春岛 1 +x:1 +风雨飘摇 1 +x:1 +渠系化 1 +x:1 +面黄肌瘦 1 +x:1 +倾巢出动 1 +x:1 +老爷儿 1 +x:1 +勘查车 1 +x:1 +神仙下凡 1 +x:1 +外向 1 +x:1 +加官进爵 1 +x:1 +椒江 1 +x:1 +印刷业 1 +x:1 +走红 1 +x:1 +地学 1 +x:1 +冬泳 1 +x:1 +中岳 1 +x:1 +孩提 1 +x:1 +德军 1 +x:1 +合作化 1 +x:1 +摇臂 1 +x:1 +同校 1 +x:1 +铝线 1 +x:1 +云山雾罩 1 +x:1 +下来 1 +x:1 +湘阴县 1 +x:1 +右舷 1 +x:1 +旧国 1 +x:1 +宋元 1 +x:1 +和田河 1 +x:1 +民脂民膏 1 +x:1 +烂糊 1 +x:1 +盗车人 1 +x:1 +良计 1 +x:1 +营养元素 1 +x:1 +发行人 1 +x:1 +木勺舞 1 +x:1 +华澳 1 +x:1 +执法不严 1 +x:1 +交租 1 +x:1 +亩 1369 +x:1369 +宿舍楼 1 +x:1 +间养 1 +x:1 +高山仰止 1 +x:1 +兴妖作怪 1 +x:1 +垛音 1 +x:1 +铅 45 +x:45 +再造 1 +x:1 +春季 1 +x:1 +缺档 1 +x:1 +黢 1 +x:1 +应酬性 1 +x:1 +认受性 1 +x:1 +滴翠峡 1 +x:1 +胸徽 1 +x:1 +挖补 1 +x:1 +击打 1 +x:1 +并蒂 1 +x:1 +吐字 1 +x:1 +下月 1 +x:1 +僭 1 +x:1 +成本费 1 +x:1 +三原县 1 +x:1 +益智楼 1 +x:1 +党建 1 +x:1 +领照 1 +x:1 +公园局 1 +x:1 +蜕 1 +x:1 +桂花姜 1 +x:1 +下期 1 +x:1 +元大都 1 +x:1 +改革者 1 +x:1 +感冒药 1 +x:1 +小吃摊 1 +x:1 +晋级 1 +x:1 +春宫 1 +x:1 +洞道 1 +x:1 +受益面 1 +x:1 +明畅 1 +x:1 +巩固村 1 +x:1 +罗锅子 1 +x:1 +有问题者 1 +x:1 +真影 1 +x:1 +港下镇 1 +x:1 +春宴 1 +x:1 +博闻强记 1 +x:1 +梅毒 1 +x:1 +中工 1 +x:1 +特勤连 1 +x:1 +扫毒战 1 +x:1 +在握 1 +x:1 +茶碗 1 +x:1 +印刷体 1 +x:1 +小兄弟 1 +x:1 +冬 160 +x:160 +违反者 1 +x:1 +永生 1 +x:1 +波澜 1 +x:1 +门球 1 +x:1 +会员国 1 +x:1 +推广部 1 +x:1 +勇敢 1 +x:1 +抢救室 1 +x:1 +汾河 1 +x:1 +离家 1 +x:1 +晋绥 1 +x:1 +俄文 1 +x:1 +马楼乡 1 +x:1 +知识面 1 +x:1 +党政军民 1 +x:1 +独女户 1 +x:1 +贸易性 1 +x:1 +伪足 1 +x:1 +定货会 1 +x:1 +公司部 1 +x:1 +核查组 1 +x:1 +优质品 1 +x:1 +东台 1 +x:1 +汉福德厂 1 +x:1 +博闻强识 1 +x:1 +苍狗 1 +x:1 +旋子 1 +x:1 +兽足类 1 +x:1 +钥匙孔 1 +x:1 +俄方 1 +x:1 +夷贝 1 +x:1 +伸展 1 +x:1 +为什么 1 +x:1 +站牌 1 +x:1 +工笔画 1 +x:1 +站牛 1 +x:1 +一大二公 1 +x:1 +门环 1 +x:1 +一窝蜂 1 +x:1 +流沙 1 +x:1 +蛋羹 1 +x:1 +百女节 1 +x:1 +轮拖 1 +x:1 +缺漏 1 +x:1 +伺弄 1 +x:1 +背信弃义 1 +x:1 +第一线 1 +x:1 +改良派 1 +x:1 +定林寺 1 +x:1 +若非 1 +x:1 +优质化 1 +x:1 +苍生 1 +x:1 +卡片盒 1 +x:1 +略微 1 +x:1 +露酒 1 +x:1 +流泉 1 +x:1 +同义词 1 +x:1 +雨过天晴 1 +x:1 +秘书处 1 +x:1 +确定 1 +x:1 +买气 1 +x:1 +盗 41 +x:41 +镖 1 +x:1 +细菌武器 1 +x:1 +倡导者 1 +x:1 +出口人 1 +x:1 +驶往 1 +x:1 +下怀 1 +x:1 +留召村 1 +x:1 +故知 1 +x:1 +流注 1 +x:1 +凹凸不平 1 +x:1 +满足感 1 +x:1 +印稿 1 +x:1 +边缘性 1 +x:1 +己 96 +x:96 +留人 1 +x:1 +软件商 1 +x:1 +铆钉枪 1 +x:1 +流泻 1 +x:1 +列出 1 +x:1 +油彩 1 +x:1 +牺牲主义 1 +x:1 +靶档 1 +x:1 +旧关 1 +x:1 +相国寺 1 +x:1 +垫支 1 +x:1 +怡然 1 +x:1 +净重 1 +x:1 +惊慌 1 +x:1 +竞销 1 +x:1 +流氓 1 +x:1 +登临意 1 +x:1 +流气 1 +x:1 +金鱼缸 1 +x:1 +党外 1 +x:1 +储备金 1 +x:1 +贪婪无厌 1 +x:1 +饲草 1 +x:1 +安居镇 1 +x:1 +蔡 375 +x:375 +下情 1 +x:1 +储备量 1 +x:1 +德城 1 +x:1 +嘘寒问暖 1 +x:1 +剪纸儿 1 +x:1 +片约 1 +x:1 +印章 1 +x:1 +医管局 1 +x:1 +鬼市 1 +x:1 +流水 1 +x:1 +发行价 1 +x:1 +嘘声 1 +x:1 +原子钟 1 +x:1 +监评会 1 +x:1 +封一 1 +x:1 +留下 1 +x:1 +碳化物 1 +x:1 +封三 1 +x:1 +惊愕 1 +x:1 +产能 1 +x:1 +创可贴 1 +x:1 +综合性 1 +x:1 +徐乡 1 +x:1 +管灯 1 +x:1 +流汗 1 +x:1 +三五成群 1 +x:1 +还是 1 +x:1 +港口法 1 +x:1 +概率论 1 +x:1 +树袋熊 1 +x:1 +列入 1 +x:1 +划块 1 +x:1 +离岗 1 +x:1 +点心店 1 +x:1 +起草人 1 +x:1 +支炉儿 1 +x:1 +一如既往 1 +x:1 +列兵 1 +x:1 +季节洄游 1 +x:1 +断钻 1 +x:1 +东周村 1 +x:1 +夜光表 1 +x:1 +出口业 1 +x:1 +性状 1 +x:1 +般的 1 +x:1 +数学迷 1 +x:1 +小气候 1 +x:1 +走神 1 +x:1 +殷鉴 1 +x:1 +经贸部 1 +x:1 +白尼罗河 1 +x:1 +糖业 1 +x:1 +主干网 1 +x:1 +问罪 1 +x:1 +楚河大街 1 +x:1 +浑金璞玉 1 +x:1 +绣花枕头 1 +x:1 +惊惶 1 +x:1 +农科院 1 +x:1 +地貌学 1 +x:1 +高技术 1 +x:1 +撒刁 1 +x:1 +糖丸 1 +x:1 +脸 223 +x:223 +加高 1 +x:1 +惊惧 1 +x:1 +局域网络 1 +x:1 +优先权 1 +x:1 +虱子 1 +x:1 +辛苦 1 +x:1 +惊悚 1 +x:1 +缸瓦 1 +x:1 +流淌 1 +x:1 +坪上村 1 +x:1 +方方 1 +x:1 +惊悉 1 +x:1 +陆上 1 +x:1 +陆丰 1 +x:1 +角斗 1 +x:1 +席次 1 +x:1 +纪录性 1 +x:1 +扶绥县 1 +x:1 +鼓 71 +x:71 +梅派 1 +x:1 +囊中羞涩 1 +x:1 +拱门 1 +x:1 +奢侈关 1 +x:1 +菊苣 1 +x:1 +诿 3 +x:3 +高感 1 +x:1 +中密 1 +x:1 +地震烈度 1 +x:1 +留住 1 +x:1 +一笔抹杀 1 +x:1 +风光带 1 +x:1 +走私 1 +x:1 +小辫儿 1 +x:1 +左家庄 1 +x:1 +液晶 1 +x:1 +德国 1 +x:1 +打瞌睡 1 +x:1 +奶油色 1 +x:1 +白龟池 1 +x:1 +琉璃寺 1 +x:1 +轮换 1 +x:1 +邮 13 +x:13 +极至 1 +x:1 +党政工 1 +x:1 +冰坛 1 +x:1 +中导 1 +x:1 +糖人 1 +x:1 +流派 1 +x:1 +钢笔尖 1 +x:1 +自留地 1 +x:1 +略带 1 +x:1 +未名湖 1 +x:1 +三严四自 1 +x:1 +象是 1 +x:1 +苛性碱 1 +x:1 +脚痛医脚 1 +x:1 +加的夫市 1 +x:1 +比 3265 +x:3265 +屈服 1 +x:1 +下水工 1 +x:1 +劳工法 1 +x:1 +门牙 1 +x:1 +中宣 1 +x:1 +中客 1 +x:1 +新手机 1 +x:1 +留传 1 +x:1 +渐变 1 +x:1 +流浪 1 +x:1 +贫困帽 1 +x:1 +走禽 1 +x:1 +举止端庄 1 +x:1 +门牌 1 +x:1 +朴实无华 1 +x:1 +再障 1 +x:1 +连接处 1 +x:1 +糖份 1 +x:1 +搜罗 1 +x:1 +渍害 1 +x:1 +烂种 1 +x:1 +该书 1 +x:1 +该乡 1 +x:1 +成熟 1 +x:1 +剪纸厂 1 +x:1 +钗 1 +x:1 +版本学家 1 +x:1 +湘北 1 +x:1 +比什凯克 1 +x:1 +玉蜀黍 1 +x:1 +会员卡 1 +x:1 +烂秧 1 +x:1 +消肿 1 +x:1 +走穴 1 +x:1 +下手 1 +x:1 +旋床 1 +x:1 +搭班子 1 +x:1 +历次 1 +x:1 +任一 1 +x:1 +骨瘦如柴 1 +x:1 +合成石油 1 +x:1 +调处会 1 +x:1 +支付款 1 +x:1 +湘华 1 +x:1 +地志 1 +x:1 +中堂 1 +x:1 +三闾大夫 1 +x:1 +先例 1 +x:1 +浒 1 +x:1 +平等性 1 +x:1 +见兔顾犬 1 +x:1 +川戏 1 +x:1 +湘南 1 +x:1 +盲动性 1 +x:1 +梅港 1 +x:1 +亚太 1 +x:1 +脱帽 1 +x:1 +班房 1 +x:1 +旧历 1 +x:1 +优待金 1 +x:1 +豪绅 1 +x:1 +农负 1 +x:1 +久仰 1 +x:1 +大堰河 1 +x:1 +认罪 1 +x:1 +骈 1 +x:1 +下拨 1 +x:1 +消耗 1 +x:1 +自作聪明 1 +x:1 +吗 720 +x:720 +类同 1 +x:1 +兑现奖 1 +x:1 +伸头 1 +x:1 +席棚 1 +x:1 +中士 1 +x:1 +心明如镜 1 +x:1 +成矿作用 1 +x:1 +蒸气浴 1 +x:1 +地价款 1 +x:1 +平流层 1 +x:1 +平行作业 1 +x:1 +膨胀系数 1 +x:1 +服刑犯 1 +x:1 +禄劝县 1 +x:1 +秘书官 1 +x:1 +保密性 1 +x:1 +瓦屋山 1 +x:1 +撕心裂肺 1 +x:1 +条 3372 +x:3372 +职工股 1 +x:1 +文化部 1 +x:1 +追风 1 +x:1 +常设性 1 +x:1 +政协会 1 +x:1 +姜堰市 1 +x:1 +地形 1 +x:1 +再见 1 +x:1 +又是 1 +x:1 +地库 1 +x:1 +门点 1 +x:1 +地底 1 +x:1 +缺氧 1 +x:1 +负债人 1 +x:1 +斜高 1 +x:1 +平安无恙 1 +x:1 +中奖 1 +x:1 +方柱 1 +x:1 +农委会 1 +x:1 +一时 1 +x:1 +提个醒 1 +x:1 +痹痛平 1 +x:1 +邱 202 +x:202 +讲解人 1 +x:1 +神农架 1 +x:1 +旋律 1 +x:1 +蛋粉 1 +x:1 +电导率 1 +x:1 +记账式 1 +x:1 +科考 1 +x:1 +抹 63 +x:63 +先代 1 +x:1 +虾子镇 1 +x:1 +北界城村 1 +x:1 +先令 1 +x:1 +战勤 1 +x:1 +医疗网 1 +x:1 +筒子河 1 +x:1 +降解 1 +x:1 +下挫 1 +x:1 +并肩 1 +x:1 +性能奖 1 +x:1 +中外 1 +x:1 +先于 1 +x:1 +佩环 1 +x:1 +达喀尔 1 +x:1 +苍白 1 +x:1 +百货商店 1 +x:1 +中大 1 +x:1 +灰头土脸 1 +x:1 +任何 1 +x:1 +角果 1 +x:1 +彩霞 1 +x:1 +阡陌 1 +x:1 +佩玉 1 +x:1 +离异 1 +x:1 +离开 1 +x:1 +领略 1 +x:1 +蛋糕 1 +x:1 +会员制 1 +x:1 +迅捷 1 +x:1 +方枕 1 +x:1 +车辚马啸 1 +x:1 +迁善改过 1 +x:1 +乳品厂 1 +x:1 +地市 1 +x:1 +波段 1 +x:1 +贫困层 1 +x:1 +善解人意 1 +x:1 +祛病 1 +x:1 +以致 1 +x:1 +波伦亚 1 +x:1 +意念 1 +x:1 +蛏田 1 +x:1 +薛村乡 1 +x:1 +卢瑟福 1 +x:1 +油层 1 +x:1 +惊扰 1 +x:1 +摩擦学 1 +x:1 +开原 1 +x:1 +离心 1 +x:1 +并联 1 +x:1 +著述 1 +x:1 +意志 1 +x:1 +辘轳 1 +x:1 +粗饲料 1 +x:1 +旧制 1 +x:1 +女神像 1 +x:1 +核弹头 1 +x:1 +方术 1 +x:1 +先世 1 +x:1 +卸去 1 +x:1 +始言 1 +x:1 +进一步 1 +x:1 +蛋类 1 +x:1 +类星体 1 +x:1 +软件园 1 +x:1 +哈尼族 1 +x:1 +血淤型 1 +x:1 +检阅台 1 +x:1 +驮戥 1 +x:1 +春心 1 +x:1 +狮 12 +x:12 +下排 1 +x:1 +春忙 1 +x:1 +各行其道 1 +x:1 +耳刮子 1 +x:1 +选管会 1 +x:1 +撤编 1 +x:1 +芪 1 +x:1 +堀 1 +x:1 +去年 1 +x:1 +川江 1 +x:1 +常青乡 1 +x:1 +围湖造田 1 +x:1 +榴花 1 +x:1 +公租户 1 +x:1 +冬春 1 +x:1 +刹住 1 +x:1 +灌输式 1 +x:1 +口琴课 1 +x:1 +箭 29 +x:29 +划定 1 +x:1 +翠绿 1 +x:1 +貌合神离 1 +x:1 +三角债 1 +x:1 +烂石 1 +x:1 +并进 1 +x:1 +著者 1 +x:1 +梳子 1 +x:1 +勇 216 +x:216 +惊涛 1 +x:1 +图尔库市 1 +x:1 +篆刻家 1 +x:1 +加鞭 1 +x:1 +片片 1 +x:1 +略去 1 +x:1 +下水 1 +x:1 +变化莫测 1 +x:1 +朽木 1 +x:1 +站务员 1 +x:1 +历数 1 +x:1 +油压 1 +x:1 +拧 27 +x:27 +垂钓园 1 +x:1 +吉碱 1 +x:1 +领空 1 +x:1 +油厂 1 +x:1 +贫困县 1 +x:1 +滚水坝 1 +x:1 +升结肠 1 +x:1 +铳 1 +x:1 +缺损 1 +x:1 +濒于 1 +x:1 +战火纷飞 1 +x:1 +十八罗汉 1 +x:1 +纪寿 1 +x:1 +缅 21 +x:21 +奥斯陆 1 +x:1 +并轨 1 +x:1 +启动日 1 +x:1 +下注 1 +x:1 +方桥 1 +x:1 +苦心孤诣 1 +x:1 +发行体 1 +x:1 +储蓄性 1 +x:1 +城台 1 +x:1 +往昔 1 +x:1 +下泻 1 +x:1 +小辫 1 +x:1 +虎背熊腰 1 +x:1 +嘟 1 +x:1 +德寇 1 +x:1 +方案 1 +x:1 +方桌 1 +x:1 +断指裂肤 1 +x:1 +门缝 1 +x:1 +装配厂 1 +x:1 +地儿 1 +x:1 +方框 1 +x:1 +专利局 1 +x:1 +礼贤下士 1 +x:1 +下法 1 +x:1 +奠基人 1 +x:1 +中国 1 +x:1 +代际人 1 +x:1 +濒临 1 +x:1 +生物武器 1 +x:1 +支付方 1 +x:1 +贫困化 1 +x:1 +第一版 1 +x:1 +油匠 1 +x:1 +方根 1 +x:1 +骨髓库 1 +x:1 +油区 1 +x:1 +方格 1 +x:1 +总会 1 +x:1 +时点 1 +x:1 +地光 1 +x:1 +纪实 1 +x:1 +划子 1 +x:1 +历时 1 +x:1 +拱顶 1 +x:1 +狂风暴雨 1 +x:1 +轮渡 1 +x:1 +狂风暴雪 1 +x:1 +娇妻 1 +x:1 +站级 1 +x:1 +领章 1 +x:1 +他用 1 +x:1 +味 109 +x:109 +开发 1 +x:1 +出租地 1 +x:1 +聘请 1 +x:1 +手抄本 1 +x:1 +植棉 1 +x:1 +下浮 1 +x:1 +野心家 1 +x:1 +不假思索 1 +x:1 +聂荣县 1 +x:1 +下海 1 +x:1 +聂村 1 +x:1 +脱光 1 +x:1 +毛俊 1 +x:1 +醛 1 +x:1 +意兴 1 +x:1 +列岛 1 +x:1 +猜 19 +x:19 +中坚 1 +x:1 +完了 1 +x:1 +超凡脱俗 1 +x:1 +没出息 1 +x:1 +陵水 1 +x:1 +完事 1 +x:1 +单口相声 1 +x:1 +江阴籍 1 +x:1 +撒布 1 +x:1 +海泡石 1 +x:1 +镜春园 1 +x:1 +无边无际 1 +x:1 +五言诗 1 +x:1 +投手 1 +x:1 +杞人之忧 1 +x:1 +衣兜 1 +x:1 +张口即来 1 +x:1 +淡水钓 1 +x:1 +院所 1 +x:1 +海勃湾区 1 +x:1 +污染量 1 +x:1 +下派 1 +x:1 +弃耕 1 +x:1 +傲立 1 +x:1 +火把节 1 +x:1 +日用瓷 1 +x:1 +春光 1 +x:1 +审查制 1 +x:1 +区际 1 +x:1 +盐井 1 +x:1 +齿髓 1 +x:1 +送人情 1 +x:1 +投标者 1 +x:1 +字里行间 1 +x:1 +旧岁 1 +x:1 +一字不差 1 +x:1 +中场 1 +x:1 +临邛村 1 +x:1 +角楼 1 +x:1 +波斯 1 +x:1 +囚禁 1 +x:1 +不拘一格 1 +x:1 +养心 1 +x:1 +势不两立 1 +x:1 +中华民族 1 +x:1 +侦查队 1 +x:1 +大桥路 1 +x:1 +波方 1 +x:1 +流感 1 +x:1 +屈死 1 +x:1 +乘人之危 1 +x:1 +平庸者 1 +x:1 +主潮 1 +x:1 +脱出 1 +x:1 +田 729 +x:729 +旧居 1 +x:1 +渣滓洞 1 +x:1 +唱工 1 +x:1 +解体 1 +x:1 +吉祥 1 +x:1 +城厢 1 +x:1 +生命攸关 1 +x:1 +自治省 1 +x:1 +拥有国 1 +x:1 +党政军 1 +x:1 +中型 1 +x:1 +开绿灯 1 +x:1 +评定 1 +x:1 +点阵 1 +x:1 +春凳 1 +x:1 +二职教 1 +x:1 +往来 1 +x:1 +绕脖子 1 +x:1 +墨旱莲 1 +x:1 +下消 1 +x:1 +报废品 1 +x:1 +评审 1 +x:1 +一元酸 1 +x:1 +去往 1 +x:1 +增产菌 1 +x:1 +罗锅儿 1 +x:1 +玉音 1 +x:1 +称体裁衣 1 +x:1 +塑料布 1 +x:1 +题量 1 +x:1 +荆棘丛 1 +x:1 +唯物主义 1 +x:1 +食杂店 1 +x:1 +有名有姓 1 +x:1 +不以为耻 1 +x:1 +历朝 1 +x:1 +拣佛烧香 1 +x:1 +灿若云霞 1 +x:1 +农研所 1 +x:1 +亲历性 1 +x:1 +蜷曲 1 +x:1 +旱涝保收 1 +x:1 +相亲 1 +x:1 +地压 1 +x:1 +桂江 1 +x:1 +游轮 1 +x:1 +胸围 1 +x:1 +沃野 1 +x:1 +细胞核 1 +x:1 +欧锦赛 1 +x:1 +审查关 1 +x:1 +反腐者 1 +x:1 +经史子集 1 +x:1 +囿于 1 +x:1 +笔耕不辍 1 +x:1 +最高处 1 +x:1 +地县 1 +x:1 +交纳 1 +x:1 +疵 1 +x:1 +孝衣 1 +x:1 +榔榆 1 +x:1 +紫花苜蓿 1 +x:1 +塌陷区 1 +x:1 +滥用 1 +x:1 +改革观 1 +x:1 +川渝 1 +x:1 +波普 1 +x:1 +暂住 1 +x:1 +闪闪地 1 +x:1 +聚头 1 +x:1 +真真实实 1 +x:1 +区长 1 +x:1 +方家见笑 1 +x:1 +离别 1 +x:1 +下游 1 +x:1 +韩国籍 1 +x:1 +停 360 +x:360 +祸水 1 +x:1 +非 793 +x:793 +地史 1 +x:1 +屠杀 1 +x:1 +孕育 1 +x:1 +中听 1 +x:1 +不卑不亢 1 +x:1 +发作 1 +x:1 +按察使 1 +x:1 +话剧团 1 +x:1 +吒 1 +x:1 +历来 1 +x:1 +龙马潭区 1 +x:1 +压价 1 +x:1 +恼 3 +x:3 +豪爽 1 +x:1 +驶入 1 +x:1 +历 33 +x:33 +老婆婆 1 +x:1 +自由自在 1 +x:1 +植 97 +x:97 +围棋王 1 +x:1 +列弗 1 +x:1 +缺憾 1 +x:1 +雅正 1 +x:1 +连接器 1 +x:1 +降落 1 +x:1 +欹曲 1 +x:1 +宣汉县 1 +x:1 +加长 1 +x:1 +油光 1 +x:1 +纪委 1 +x:1 +经不住 1 +x:1 +烦杂 1 +x:1 +委员证 1 +x:1 +下滑 1 +x:1 +耍赖 1 +x:1 +论战 1 +x:1 +平平凡凡 1 +x:1 +列强 1 +x:1 +直臂 1 +x:1 +迎来送往 1 +x:1 +西客站 1 +x:1 +省建 1 +x:1 +双向 1 +x:1 +并购 1 +x:1 +空头支票 1 +x:1 +发信 1 +x:1 +列当 1 +x:1 +声名鹊立 1 +x:1 +滚木 1 +x:1 +前车之覆 1 +x:1 +力量 1 +x:1 +郜 15 +x:15 +植树节 1 +x:1 +击毙 1 +x:1 +重奖 1 +x:1 +饭 227 +x:227 +中咨 1 +x:1 +二田村 1 +x:1 +反问句 1 +x:1 +击毁 1 +x:1 +彩电业 1 +x:1 +娇客 1 +x:1 +储蓄所 1 +x:1 +旧式 1 +x:1 +上游 1 +x:1 +夜光虫 1 +x:1 +无核试验 1 +x:1 +地力 1 +x:1 +对/日 1 +x:1 +撒尿 1 +x:1 +东外环路 1 +x:1 +区直 1 +x:1 +湘帘 1 +x:1 +腰痛穴 1 +x:1 +会厌软骨 1 +x:1 +评奖 1 +x:1 +主赛场 1 +x:1 +增殖腺 1 +x:1 +印界 1 +x:1 +冲击力 1 +x:1 +橡皮 1 +x:1 +池阁 1 +x:1 +飒飒 1 +x:1 +扑灭 1 +x:1 +象棋 1 +x:1 +发丝 1 +x:1 +地势 1 +x:1 +囚笼 1 +x:1 +赞成键 1 +x:1 +经久不息 1 +x:1 +伺候 1 +x:1 +老有所学 1 +x:1 +碑版 1 +x:1 +发上 1 +x:1 +病从口入 1 +x:1 +发乳 1 +x:1 +两工 1 +x:1 +马奶子 1 +x:1 +地勘 1 +x:1 +染化厂 1 +x:1 +何坊村 1 +x:1 +意匠 1 +x:1 +十方 1 +x:1 +娇娃 1 +x:1 +伏尔加河 1 +x:1 +慰问信 1 +x:1 +连绵不绝 1 +x:1 +春卷 1 +x:1 +附属物 1 +x:1 +钢骨架 1 +x:1 +令郎 1 +x:1 +可乘之机 1 +x:1 +春华 1 +x:1 +往日 1 +x:1 +所在国 1 +x:1 +力避 1 +x:1 +党团 1 +x:1 +影剧院 1 +x:1 +往时 1 +x:1 +地勤 1 +x:1 +波束 1 +x:1 +发乎 1 +x:1 +脱发 1 +x:1 +旧年 1 +x:1 +过磷酸钙 1 +x:1 +耙犁 1 +x:1 +轮流 1 +x:1 +方正 1 +x:1 +喉风 1 +x:1 +方步 1 +x:1 +麟角凤觜 1 +x:1 +少不得 1 +x:1 +豪猪 1 +x:1 +湛江舰 1 +x:1 +评委 1 +x:1 +逝 19 +x:19 +发亮 1 +x:1 +榆钱 1 +x:1 +消费 1 +x:1 +挑三窝四 1 +x:1 +维港 1 +x:1 +列席 1 +x:1 +凝心聚力 1 +x:1 +电影剧本 1 +x:1 +蜡疗 1 +x:1 +高等教育 1 +x:1 +疹子 1 +x:1 +地利 1 +x:1 +唐人街 1 +x:1 +娇嫩 1 +x:1 +大处着眼 1 +x:1 +论据 1 +x:1 +居 461 +x:461 +如胶似漆 1 +x:1 +离去 1 +x:1 +娇媚 1 +x:1 +赏 47 +x:47 +民主化 1 +x:1 +旋即 1 +x:1 +信用社 1 +x:1 +香河 1 +x:1 +发语词 1 +x:1 +发令 1 +x:1 +竹材 1 +x:1 +靶机 1 +x:1 +回 1040 +x:1040 +狮豹头乡 1 +x:1 +冬日 1 +x:1 +斜阳 1 +x:1 +刊登 1 +x:1 +创办者 1 +x:1 +光华村 1 +x:1 +玩儿命 1 +x:1 +旧币 1 +x:1 +期票 1 +x:1 +言行不一 1 +x:1 +有益于 1 +x:1 +曾 2845 +x:2845 +优胜者杯 1 +x:1 +双响 1 +x:1 +烤花窑 1 +x:1 +摩肩接踵 1 +x:1 +党内 1 +x:1 +晨练点 1 +x:1 +集合式 1 +x:1 +超时空 1 +x:1 +兔园 1 +x:1 +泡沫橡胶 1 +x:1 +吸存量 1 +x:1 +古巴 1 +x:1 +名士者 1 +x:1 +胸像 1 +x:1 +油城 1 +x:1 +纪录 1 +x:1 +甲烷量 1 +x:1 +某市 1 +x:1 +沙捞越 1 +x:1 +齿龈 1 +x:1 +走火 1 +x:1 +群英荟萃 1 +x:1 +方法 1 +x:1 +复印纸 1 +x:1 +患病率 1 +x:1 +语源学 1 +x:1 +釉 1 +x:1 +围棋界 1 +x:1 +油垢 1 +x:1 +汛期 1 +x:1 +波恩 1 +x:1 +算草 1 +x:1 +美姑县 1 +x:1 +红嘴鸥 1 +x:1 +空疏 1 +x:1 +专页 1 +x:1 +炒面 1 +x:1 +吸毒人 1 +x:1 +脏乎乎 1 +x:1 +增容费 1 +x:1 +春味 1 +x:1 +供水量 1 +x:1 +高山 1 +x:1 +蜡版 1 +x:1 +执业 1 +x:1 +珠圆玉润 1 +x:1 +站稳 1 +x:1 +意向 1 +x:1 +刹风整纪 1 +x:1 +站立 1 +x:1 +挂毯 1 +x:1 +内坛 1 +x:1 +重离子 1 +x:1 +纪念 1 +x:1 +风度翩翩 1 +x:1 +捡便宜 1 +x:1 +说老实话 1 +x:1 +科计 1 +x:1 +机鸣声 1 +x:1 +门第 1 +x:1 +董塘镇 1 +x:1 +斜路 1 +x:1 +特一连 1 +x:1 +贡 5 +x:5 +囚粮 1 +x:1 +任劳任怨 1 +x:1 +下棋 1 +x:1 +巧劲儿 1 +x:1 +联席会 1 +x:1 +村东 1 +x:1 +四个一 1 +x:1 +商代 1 +x:1 +办事者 1 +x:1 +科教处 1 +x:1 +村上 1 +x:1 +股份化 1 +x:1 +领结 1 +x:1 +特遣队 1 +x:1 +摇荡 1 +x:1 +光 454 +x:454 +有功者 1 +x:1 +国力式微 1 +x:1 +热呼呼 1 +x:1 +老爷式 1 +x:1 +贯前村 1 +x:1 +大安乡 1 +x:1 +商事 1 +x:1 +神工鬼斧 1 +x:1 +部党组 1 +x:1 +南街村 1 +x:1 +用作 1 +x:1 +划归 1 +x:1 +舞谱 1 +x:1 +商人 1 +x:1 +城区 1 +x:1 +层递式 1 +x:1 +纪律 1 +x:1 +吐哈 1 +x:1 +急先锋 1 +x:1 +好戏连台 1 +x:1 +保本 1 +x:1 +气概不凡 1 +x:1 +长坪镇 1 +x:1 +号召力 1 +x:1 +稍逊风骚 1 +x:1 +纪年 1 +x:1 +相处 1 +x:1 +轮毂 1 +x:1 +中华 1 +x:1 +中午 1 +x:1 +汪伪政权 1 +x:1 +燕语莺声 1 +x:1 +市民林 1 +x:1 +美满姻缘 1 +x:1 +迁怒 1 +x:1 +应酬话 1 +x:1 +贡税 1 +x:1 +勾除 1 +x:1 +商住 1 +x:1 +中卡 1 +x:1 +大学生 1 +x:1 +巴不得 1 +x:1 +力阻 1 +x:1 +溪湖 1 +x:1 +论文 1 +x:1 +门窗 1 +x:1 +中卫 1 +x:1 +撒娇 1 +x:1 +故纸 1 +x:1 +地质队 1 +x:1 +牢不可破 1 +x:1 +夷为平地 1 +x:1 +击汰 1 +x:1 +彭阳 1 +x:1 +住院部 1 +x:1 +西营镇 1 +x:1 +商会 1 +x:1 +死刑犯 1 +x:1 +商企 1 +x:1 +干熄焦 1 +x:1 +主办员 1 +x:1 +娇小 1 +x:1 +力陈 1 +x:1 +经贸额 1 +x:1 +暗娼 1 +x:1 +唱头 1 +x:1 +无标准 1 +x:1 +评弹 1 +x:1 +店长 1 +x:1 +发奋图强 1 +x:1 +寿光鸡 1 +x:1 +普九 1 +x:1 +盆腔 1 +x:1 +营业场 1 +x:1 +湖光山色 1 +x:1 +年轻有为 1 +x:1 +稻瘟病 1 +x:1 +价值千金 1 +x:1 +吃败仗 1 +x:1 +多球制 1 +x:1 +屡教不改 1 +x:1 +缸房 1 +x:1 +核查点 1 +x:1 +地名 1 +x:1 +中古 1 +x:1 +处女膜 1 +x:1 +溢 35 +x:35 +科幻片 1 +x:1 +紫 18 +x:18 +咖啡馆 1 +x:1 +尊老 1 +x:1 +称孤道寡 1 +x:1 +中号 1 +x:1 +中叶 1 +x:1 +花落花开 1 +x:1 +中右 1 +x:1 +象湖 1 +x:1 +峭丽 1 +x:1 +击沉 1 +x:1 +性激素 1 +x:1 +流放 1 +x:1 +破罐破摔 1 +x:1 +兔场 1 +x:1 +芦柑 1 +x:1 +截止期 1 +x:1 +八带鱼 1 +x:1 +时疫 1 +x:1 +乍 34 +x:34 +中压 1 +x:1 +确切 1 +x:1 +清凉剂 1 +x:1 +下榻 1 +x:1 +申购者 1 +x:1 +消法 1 +x:1 +饮弹 1 +x:1 +类 790 +x:790 +围场路 1 +x:1 +净额 1 +x:1 +流散 1 +x:1 +速腐剂 1 +x:1 +祸殃 1 +x:1 +卸妆 1 +x:1 +中厨 1 +x:1 +忍俊 1 +x:1 +摘梢 1 +x:1 +诸城市 1 +x:1 +绕组 1 +x:1 +灯罩子 1 +x:1 +唱片儿 1 +x:1 +防灾费 1 +x:1 +无纺织物 1 +x:1 +钵盘 1 +x:1 +列宁 1 +x:1 +刈 2 +x:2 +认知 1 +x:1 +长一智 1 +x:1 +北方邦 1 +x:1 +风景如画 1 +x:1 +海蓝色 1 +x:1 +廉者 1 +x:1 +大呼隆 1 +x:1 +钵盂 1 +x:1 +摩松楼 1 +x:1 +宁波市 1 +x:1 +莫须有 1 +x:1 +分割肉 1 +x:1 +体贴入微 1 +x:1 +加里 1 +x:1 +加重 1 +x:1 +青黄不接 1 +x:1 +炒锅 1 +x:1 +烘云托月 1 +x:1 +确凿 1 +x:1 +经久不散 1 +x:1 +神农溪 1 +x:1 +仙果神木 1 +x:1 +区界 1 +x:1 +翱翔 1 +x:1 +大喊大叫 1 +x:1 +珠宝 1 +x:1 +塌陷地 1 +x:1 +地域 1 +x:1 +党参 1 +x:1 +暖暖地 1 +x:1 +地埂 1 +x:1 +祸根 1 +x:1 +爱丁堡 1 +x:1 +桂树 1 +x:1 +地埋 1 +x:1 +下一场 1 +x:1 +烂熟 1 +x:1 +泡沫者 1 +x:1 +行李卷儿 1 +x:1 +盆花 1 +x:1 +茶褐色 1 +x:1 +地基 1 +x:1 +历史组 1 +x:1 +曲沃 1 +x:1 +旧宅 1 +x:1 +百万富翁 1 +x:1 +牟利 1 +x:1 +勾销 1 +x:1 +细纺 1 +x:1 +党史 1 +x:1 +沼渣 1 +x:1 +碑石 1 +x:1 +去声 1 +x:1 +走狗 1 +x:1 +龙旺村 1 +x:1 +计算机系 1 +x:1 +袖子 1 +x:1 +舞蹈 1 +x:1 +旧学 1 +x:1 +截稿 1 +x:1 +迷彩色 1 +x:1 +折子戏 1 +x:1 +林业厅 1 +x:1 +互补性 1 +x:1 +流星 1 +x:1 +郾城县 1 +x:1 +脱困 1 +x:1 +小梁乡 1 +x:1 +胸前 1 +x:1 +跨步电压 1 +x:1 +养鳗业 1 +x:1 +华尔街 1 +x:1 +降耗 1 +x:1 +毽球 1 +x:1 +德州 1 +x:1 +波折 1 +x:1 +齿科 1 +x:1 +槐荫耆宿 1 +x:1 +冬情 1 +x:1 +地块 1 +x:1 +铝型材 1 +x:1 +地坛 1 +x:1 +广开言路 1 +x:1 +淘气包 1 +x:1 +溪涧 1 +x:1 +区里 1 +x:1 +五·一七 1 +x:1 +降职 1 +x:1 +钮扣 1 +x:1 +诚信 1 +x:1 +认真 1 +x:1 +淫靡 1 +x:1 +蜡烛 1 +x:1 +石经寺 1 +x:1 +七星鱼 1 +x:1 +望而止步 1 +x:1 +设点 1 +x:1 +陇西县 1 +x:1 +梅李 1 +x:1 +积习难改 1 +x:1 +齿鲸 1 +x:1 +中免 1 +x:1 +审查员 1 +x:1 +德人联 1 +x:1 +盆菜 1 +x:1 +镀镀 1 +x:1 +党办 1 +x:1 +屠户 1 +x:1 +近世以降 1 +x:1 +小姐 1 +x:1 +站票 1 +x:1 +购书 1 +x:1 +姆尼布区 1 +x:1 +贸易法 1 +x:1 +油品 1 +x:1 +减头去尾 1 +x:1 +党务 1 +x:1 +舞迷 1 +x:1 +大奖赛 1 +x:1 +截止日 1 +x:1 +交费率 1 +x:1 +中共 1 +x:1 +购买 1 +x:1 +苑 13 +x:13 +少东家 1 +x:1 +文代会 1 +x:1 +论析 1 +x:1 +脱坯 1 +x:1 +碘仿 1 +x:1 +封官许愿 1 +x:1 +下次 1 +x:1 +下欠 1 +x:1 +复姓 1 +x:1 +意在 1 +x:1 +溪水 1 +x:1 +离场 1 +x:1 +行货 1 +x:1 +寒心 1 +x:1 +雅名 1 +x:1 +一大家子 1 +x:1 +存 255 +x:255 +土坯棚 1 +x:1 +下款 1 +x:1 +空空如也 1 +x:1 +豢 1 +x:1 +店面 1 +x:1 +文化饭 1 +x:1 +一二年期 1 +x:1 +地图 1 +x:1 +黯然神伤 1 +x:1 +塑化剂 1 +x:1 +汊涧镇 1 +x:1 +酱厂 1 +x:1 +原发性 1 +x:1 +去处 1 +x:1 +必由之路 1 +x:1 +消解 1 +x:1 +动情 1 +x:1 +岛景 1 +x:1 +共通性 1 +x:1 +大关村 1 +x:1 +嵊州市 1 +x:1 +昌黎县 1 +x:1 +孳生 1 +x:1 +党刊 1 +x:1 +兆比/秒 1 +x:1 +牟取 1 +x:1 +胸卡 1 +x:1 +文化馆 1 +x:1 +阿拉善盟 1 +x:1 +大智若愚 1 +x:1 +孤军奋战 1 +x:1 +净高 1 +x:1 +甲万那端 1 +x:1 +卢浮宫 1 +x:1 +黑云母 1 +x:1 +钥匙圈 1 +x:1 +莫名其妙 1 +x:1 +并行 1 +x:1 +老姑娘 1 +x:1 +击溃 1 +x:1 +助词 1 +x:1 +购价 1 +x:1 +溪泉 1 +x:1 +盈利性 1 +x:1 +露骨 1 +x:1 +草木皆兵 1 +x:1 +激进党 1 +x:1 +中册 1 +x:1 +驾临 1 +x:1 +轮椅 1 +x:1 +溪河 1 +x:1 +梅枝 1 +x:1 +螺线管 1 +x:1 +刊版 1 +x:1 +郸城县 1 +x:1 +电焊工 1 +x:1 +梅林 1 +x:1 +装饰橱 1 +x:1 +紧急灯 1 +x:1 +中军 1 +x:1 +董事 1 +x:1 +春城 1 +x:1 +通信法 1 +x:1 +汲汲 1 +x:1 +农工贸 1 +x:1 +光洁度 1 +x:1 +总计 1 +x:1 +勾针 1 +x:1 +白垩纪 1 +x:1 +涝池 1 +x:1 +马缨花 1 +x:1 +耀华力路 1 +x:1 +饲料块 1 +x:1 +加速 1 +x:1 +旧时 1 +x:1 +发电 1 +x:1 +岛外 1 +x:1 +油毡 1 +x:1 +内资 1 +x:1 +吐根 1 +x:1 +旋梯 1 +x:1 +抓走 1 +x:1 +浮想联翩 1 +x:1 +旧日 1 +x:1 +社团办 1 +x:1 +轮回 1 +x:1 +蜡丸 1 +x:1 +盐坨子 1 +x:1 +科伦坡 1 +x:1 +旁征博引 1 +x:1 +跃动 1 +x:1 +反毒局 1 +x:1 +暂用 1 +x:1 +卢森堡市 1 +x:1 +发生 1 +x:1 +劈风斩浪 1 +x:1 +技术课 1 +x:1 +诚然 1 +x:1 +眺 3 +x:3 +先秦 1 +x:1 +颈侧 1 +x:1 +惊喜 1 +x:1 +评戏 1 +x:1 +年久失修 1 +x:1 +恬不知耻 1 +x:1 +马连曲村 1 +x:1 +孩子王 1 +x:1 +驮轿 1 +x:1 +老虎滩 1 +x:1 +紫荆村 1 +x:1 +离校 1 +x:1 +传记性 1 +x:1 +去春 1 +x:1 +侄儿 1 +x:1 +喷射船 1 +x:1 +其端 1 +x:1 +新良庄 1 +x:1 +嘘气 1 +x:1 +中渚 1 +x:1 +图曼斯基 1 +x:1 +金堂县 1 +x:1 +流声 1 +x:1 +五掌握 1 +x:1 +内贸 1 +x:1 +监听器 1 +x:1 +贸易厅 1 +x:1 +赏梅节 1 +x:1 +戚戚者 1 +x:1 +经济法 1 +x:1 +毛皮 1 +x:1 +眼观六路 1 +x:1 +风洞 1 +x:1 +祸因 1 +x:1 +春梦 1 +x:1 +先祖 1 +x:1 +虚应 1 +x:1 +帽章 1 +x:1 +解剖学 1 +x:1 +蜡人 1 +x:1 +发疯 1 +x:1 +驾照 1 +x:1 +风烟 1 +x:1 +列支 1 +x:1 +常秘 1 +x:1 +进学街 1 +x:1 +党派 1 +x:1 +俄国 1 +x:1 +缩手缩脚 1 +x:1 +设伏 1 +x:1 +排字盘 1 +x:1 +战技术 1 +x:1 +往常 1 +x:1 +见分晓 1 +x:1 +千古兴亡 1 +x:1 +尾大不掉 1 +x:1 +苞菜 1 +x:1 +无可争议 1 +x:1 +设使 1 +x:1 +贸易区 1 +x:1 +南方派 1 +x:1 +次生矿物 1 +x:1 +出省证 1 +x:1 +波峰 1 +x:1 +聚聚 1 +x:1 +长舌妇 1 +x:1 +去暑 1 +x:1 +发痒 1 +x:1 +眼珠 1 +x:1 +印人 1 +x:1 +打井热 1 +x:1 +绝缘层 1 +x:1 +失聪者 1 +x:1 +管理观 1 +x:1 +发病 1 +x:1 +干薪 1 +x:1 +便民箱 1 +x:1 +虚度 1 +x:1 +娇憨 1 +x:1 +糖稀 1 +x:1 +往往 1 +x:1 +敌忾同仇 1 +x:1 +灵岩涧 1 +x:1 +召见 1 +x:1 +貉 1 +x:1 +使劲 1 +x:1 +战斗不止 1 +x:1 +石河子 1 +x:1 +资江轮 1 +x:1 +兔毫 1 +x:1 +黄梁美梦 1 +x:1 +方凳 1 +x:1 +社会制度 1 +x:1 +击倒 1 +x:1 +赝鼎 1 +x:1 +兔毛 1 +x:1 +陆空 1 +x:1 +历尽 1 +x:1 +迁就 1 +x:1 +发球 1 +x:1 +地梨 1 +x:1 +编导演职 1 +x:1 +迁居 1 +x:1 +屈原 1 +x:1 +一饱眼福 1 +x:1 +背搭子 1 +x:1 +胶州湾 1 +x:1 +需水量 1 +x:1 +鸟尽弓藏 1 +x:1 +红一团 1 +x:1 +入木三分 1 +x:1 +紧急令 1 +x:1 +党法 1 +x:1 +历届 1 +x:1 +划拨 1 +x:1 +少 1709 +x:1709 +嗣 2 +x:2 +耗竭 1 +x:1 +产成品 1 +x:1 +弯曲 1 +x:1 +佳味 1 +x:1 +统筹部长 1 +x:1 +敦煌市 1 +x:1 +俄城 1 +x:1 +若明若暗 1 +x:1 +管乐队 1 +x:1 +指尖 1 +x:1 +后空翻 1 +x:1 +祭 31 +x:31 +自身 1 +x:1 +慰问电 1 +x:1 +概预算 1 +x:1 +少年装 1 +x:1 +地标 1 +x:1 +数理化 1 +x:1 +惊呆 1 +x:1 +静坐 1 +x:1 +观光台 1 +x:1 +惊呼 1 +x:1 +运管所 1 +x:1 +名权位 1 +x:1 +圣诞节 1 +x:1 +水河滩 1 +x:1 +论处 1 +x:1 +地核 1 +x:1 +通例 1 +x:1 +莱城区 1 +x:1 +危亡 1 +x:1 +印信 1 +x:1 +密集型 1 +x:1 +庆功酒 1 +x:1 +踢打 1 +x:1 +娇惯 1 +x:1 +传动轴 1 +x:1 +光缆 1 +x:1 +不打自招 1 +x:1 +冬忆 1 +x:1 +非农产业 1 +x:1 +倔犟 1 +x:1 +金门岛 1 +x:1 +角儿 1 +x:1 +跃升 1 +x:1 +腾然 1 +x:1 +惊吓 1 +x:1 +乖乖 1 +x:1 +婢女 1 +x:1 +大出风头 1 +x:1 +灵巧 1 +x:1 +与其 1 +x:1 +冬忙 1 +x:1 +鄂托克旗 1 +x:1 +食物链 1 +x:1 +个案 1 +x:1 +那波里 1 +x:1 +自觉自醒 1 +x:1 +油樟 1 +x:1 +假恶丑 1 +x:1 +奠基石 1 +x:1 +中小站 1 +x:1 +巩乃斯 1 +x:1 +撒放 1 +x:1 +会诊队 1 +x:1 +意向书 1 +x:1 +跨国公司 1 +x:1 +热热身 1 +x:1 +缺头 1 +x:1 +行贿 1 +x:1 +蔚 36 +x:36 +诺福克郡 1 +x:1 +基准日 1 +x:1 +麻木 1 +x:1 +临泉县 1 +x:1 +地段 1 +x:1 +凸透镜 1 +x:1 +续辨 1 +x:1 +万金油 1 +x:1 +不可胜数 1 +x:1 +射电 1 +x:1 +射界 1 +x:1 +岛子 1 +x:1 +天女散花 1 +x:1 +周家沟 1 +x:1 +不等量 1 +x:1 +素质 1 +x:1 +身兼多职 1 +x:1 +中气 1 +x:1 +月光如水 1 +x:1 +斗争史 1 +x:1 +苯教 1 +x:1 +水圳 1 +x:1 +波幅 1 +x:1 +传世之作 1 +x:1 +装聋作哑 1 +x:1 +茫无头绪 1 +x:1 +菜籽粕 1 +x:1 +角力 1 +x:1 +脱模 1 +x:1 +偎 4 +x:4 +大堡礁 1 +x:1 +卡肖 1 +x:1 +棚顶 1 +x:1 +地毯 1 +x:1 +石经板 1 +x:1 +卡拉当格 1 +x:1 +济宁市 1 +x:1 +电汽车 1 +x:1 +独到之处 1 +x:1 +殆 1 +x:1 +双困户 1 +x:1 +西开普省 1 +x:1 +自不待言 1 +x:1 +漫天要价 1 +x:1 +隐隐约约 1 +x:1 +中监委 1 +x:1 +诺诺 1 +x:1 +咽头 1 +x:1 +迁徙 1 +x:1 +下图 1 +x:1 +唱曲 1 +x:1 +销售站 1 +x:1 +光荣席 1 +x:1 +砧 1 +x:1 +桫椤 1 +x:1 +保密员 1 +x:1 +方剂 1 +x:1 +施工者 1 +x:1 +峭然 1 +x:1 +该站 1 +x:1 +下回 1 +x:1 +换车 1 +x:1 +臂 29 +x:29 +要领 1 +x:1 +古藤蔓 1 +x:1 +目瞪口呆 1 +x:1 +阔叶树 1 +x:1 +筑 81 +x:81 +撒旦 1 +x:1 +弃旧图新 1 +x:1 +扫 87 +x:87 +天安门 1 +x:1 +言不由衷 1 +x:1 +敲锣打鼓 1 +x:1 +大好河山 1 +x:1 +大雅大俗 1 +x:1 +地步 1 +x:1 +名牌机 1 +x:1 +锅碗瓢盆 1 +x:1 +旧有 1 +x:1 +完璧 1 +x:1 +下坡 1 +x:1 +渔钩 1 +x:1 +方可 1 +x:1 +抓阄儿 1 +x:1 +湘昆 1 +x:1 +晋中 1 +x:1 +前仰后合 1 +x:1 +执照 1 +x:1 +保护层 1 +x:1 +万水千山 1 +x:1 +毛病 1 +x:1 +走低 1 +x:1 +梅子 1 +x:1 +仰珍 1 +x:1 +唤 18 +x:18 +坐席 1 +x:1 +清凉油 1 +x:1 +金泉乡 1 +x:1 +购物 1 +x:1 +复兴门站 1 +x:1 +先端 1 +x:1 +盲人瞎马 1 +x:1 +父 59 +x:59 +佳趣 1 +x:1 +经济林片 1 +x:1 +衣冠冢 1 +x:1 +心力衰竭 1 +x:1 +油棕 1 +x:1 +德性 1 +x:1 +荀 9 +x:9 +封禅 1 +x:1 +晋书 1 +x:1 +流寇 1 +x:1 +嗜书如渴 1 +x:1 +祖祖辈辈 1 +x:1 +下地 1 +x:1 +论对 1 +x:1 +恩尽义绝 1 +x:1 +激浊扬清 1 +x:1 +方向舵 1 +x:1 +下场 1 +x:1 +火地岛省 1 +x:1 +行业性 1 +x:1 +宿鸟 1 +x:1 +春歌 1 +x:1 +击剑 1 +x:1 +桐城市 1 +x:1 +历年 1 +x:1 +唱机 1 +x:1 +惭 2 +x:2 +软件所 1 +x:1 +解疑 1 +x:1 +唱本 1 +x:1 +草草收场 1 +x:1 +西柏坡乡 1 +x:1 +私领 1 +x:1 +汕头 1 +x:1 +脱毛 1 +x:1 +饲料款 1 +x:1 +余货 1 +x:1 +牛黄 1 +x:1 +旧景 1 +x:1 +晋人 1 +x:1 +中高考 1 +x:1 +油桶 1 +x:1 +终霜 1 +x:1 +趁早 1 +x:1 +油桃 1 +x:1 +专利权 1 +x:1 +复国主义 1 +x:1 +请求权 1 +x:1 +黑土地 1 +x:1 +油桐 1 +x:1 +瓜亚斯省 1 +x:1 +晋代 1 +x:1 +野鸭 1 +x:1 +包容性 1 +x:1 +野鸡 1 +x:1 +论学 1 +x:1 +剩余价值 1 +x:1 +凌 64 +x:64 +贸易值 1 +x:1 +野鸽 1 +x:1 +液压 1 +x:1 +流存 1 +x:1 +名队 1 +x:1 +油样 1 +x:1 +滞 10 +x:10 +下垂 1 +x:1 +孺子牛 1 +x:1 +海兰江 1 +x:1 +吃饭型 1 +x:1 +志怪书 1 +x:1 +公园法 1 +x:1 +跃入 1 +x:1 +来不及 1 +x:1 +陵园 1 +x:1 +阻力 1 +x:1 +迁延 1 +x:1 +宋干节 1 +x:1 +迁建 1 +x:1 +卖国贼 1 +x:1 +老掉牙 1 +x:1 +屠夫 1 +x:1 +代顿 1 +x:1 +埋骨 1 +x:1 +公安局长 1 +x:1 +留给 1 +x:1 +管理费 1 +x:1 +该类 1 +x:1 +明光透亮 1 +x:1 +春水 1 +x:1 +语无伦次 1 +x:1 +科森察省 1 +x:1 +漫话 1 +x:1 +敦煌学 1 +x:1 +衙门 1 +x:1 +红红绿绿 1 +x:1 +桂剧 1 +x:1 +合纵连横 1 +x:1 +养牛场 1 +x:1 +芯 8 +x:8 +水产品 1 +x:1 +多病在身 1 +x:1 +城运会 1 +x:1 +春气 1 +x:1 +片中 1 +x:1 +入射点 1 +x:1 +梅山 1 +x:1 +世界主义 1 +x:1 +朱鹮 1 +x:1 +重重地 1 +x:1 +正多角形 1 +x:1 +旧憾 1 +x:1 +众星捧月 1 +x:1 +承保 1 +x:1 +朱鸟 1 +x:1 +救灾柴 1 +x:1 +光照度 1 +x:1 +如诗似画 1 +x:1 +汉川市 1 +x:1 +灵草 1 +x:1 +发照 1 +x:1 +介绍会 1 +x:1 +问世 1 +x:1 +下岗者 1 +x:1 +脱水 1 +x:1 +伥鬼 1 +x:1 +特二连 1 +x:1 +轻飘 1 +x:1 +桦川 1 +x:1 +留级 1 +x:1 +深 910 +x:910 +写信 1 +x:1 +灵药 1 +x:1 +脱氧 1 +x:1 +镶 25 +x:25 +贸易型 1 +x:1 +意气 1 +x:1 +德望 1 +x:1 +轻风 1 +x:1 +瞿家湾村 1 +x:1 +地洞 1 +x:1 +与否 1 +x:1 +等号 1 +x:1 +该系 1 +x:1 +寒峭 1 +x:1 +求知欲 1 +x:1 +吐沫 1 +x:1 +缺德 1 +x:1 +绝尘而去 1 +x:1 +内角 1 +x:1 +可发展性 1 +x:1 +节肢动物 1 +x:1 +自选集 1 +x:1 +购车者 1 +x:1 +介绍信 1 +x:1 +全唐诗 1 +x:1 +嘛尼 1 +x:1 +聚落 1 +x:1 +文昌鱼 1 +x:1 +水玻璃 1 +x:1 +德育课 1 +x:1 +炸 67 +x:67 +吸毒癖 1 +x:1 +无可争辩 1 +x:1 +玩艺 1 +x:1 +保密制 1 +x:1 +涝坝 1 +x:1 +诊 8 +x:8 +古隆中 1 +x:1 +定海区 1 +x:1 +优选法 1 +x:1 +左权籍 1 +x:1 +过往客 1 +x:1 +袁头 1 +x:1 +梅岭 1 +x:1 +信号灯 1 +x:1 +片酬 1 +x:1 +春泉 1 +x:1 +腹评 1 +x:1 +哑然失笑 1 +x:1 +套印本 1 +x:1 +边裁 1 +x:1 +员司 1 +x:1 +散剂 1 +x:1 +方向 1 +x:1 +缸子 1 +x:1 +别有洞天 1 +x:1 +婉言谢绝 1 +x:1 +内行 1 +x:1 +旋涡 1 +x:1 +剧务 1 +x:1 +电焊机 1 +x:1 +依赖性 1 +x:1 +拥戴者 1 +x:1 +地沟 1 +x:1 +贸易国 1 +x:1 +下关 1 +x:1 +桂南 1 +x:1 +席子 1 +x:1 +率尔 1 +x:1 +李庄村 1 +x:1 +单兵作战 1 +x:1 +老中青 1 +x:1 +紫藤花 1 +x:1 +洪势 1 +x:1 +下元 1 +x:1 +介绍书 1 +x:1 +深棕色 1 +x:1 +一日三餐 1 +x:1 +中止 1 +x:1 +地油 1 +x:1 +台州湾畔 1 +x:1 +总裁 1 +x:1 +内衣 1 +x:1 +民运会 1 +x:1 +旧情 1 +x:1 +骤变 1 +x:1 +轮台 1 +x:1 +月环食 1 +x:1 +藏剧团 1 +x:1 +核心层 1 +x:1 +外研所 1 +x:1 +郁滞 1 +x:1 +总装 1 +x:1 +佳话 1 +x:1 +箭垛子 1 +x:1 +负隅顽抗 1 +x:1 +所剩无多 1 +x:1 +西罗马 1 +x:1 +桂北 1 +x:1 +蛋价 1 +x:1 +渎职 1 +x:1 +发火 1 +x:1 +纳税额 1 +x:1 +羊皮鼓 1 +x:1 +电焊条 1 +x:1 +叹叹气 1 +x:1 +中欧 1 +x:1 +不失为 1 +x:1 +冬季 1 +x:1 +冲击波 1 +x:1 +岛屿 1 +x:1 +大手笔 1 +x:1 +用途 1 +x:1 +地波 1 +x:1 +增支减利 1 +x:1 +夜宿 1 +x:1 +金石为开 1 +x:1 +撒手 1 +x:1 +灵芝 1 +x:1 +下凡 1 +x:1 +暂 63 +x:63 +地气 1 +x:1 +饮誉 1 +x:1 +陶马 1 +x:1 +奕阳 1 +x:1 +用电量 1 +x:1 +人丛 1 +x:1 +梅州 1 +x:1 +中毒 1 +x:1 +公事公办 1 +x:1 +联网站 1 +x:1 +轮南 1 +x:1 +祸及 1 +x:1 +申办户 1 +x:1 +药草园 1 +x:1 +留置 1 +x:1 +内裤 1 +x:1 +切实 1 +x:1 +琼琚 1 +x:1 +冬宫 1 +x:1 +访问量 1 +x:1 +糖纸 1 +x:1 +重构 1 +x:1 +陆续 1 +x:1 +发炎 1 +x:1 +谋计 1 +x:1 +油港 1 +x:1 +油渣 1 +x:1 +大烩菜 1 +x:1 +川军 1 +x:1 +郎 105 +x:105 +冬寒 1 +x:1 +轮匝 1 +x:1 +发烧 1 +x:1 +发货部 1 +x:1 +天花病 1 +x:1 +发热 1 +x:1 +评析 1 +x:1 +平柴车 1 +x:1 +换血 1 +x:1 +观光型 1 +x:1 +纣棍 1 +x:1 +矿泉水 1 +x:1 +下册 1 +x:1 +中段 1 +x:1 +复音词 1 +x:1 +发烂 1 +x:1 +单幅 1 +x:1 +毛猪 1 +x:1 +去掉 1 +x:1 +耳朵眼 1 +x:1 +介绍人 1 +x:1 +击响 1 +x:1 +乌鱼蛋 1 +x:1 +心连心 1 +x:1 +解热 1 +x:1 +毛烟 1 +x:1 +源自 1 +x:1 +回话者 1 +x:1 +春游 1 +x:1 +明线光谱 1 +x:1 +脱贫致富 1 +x:1 +进取 1 +x:1 +轻骑 1 +x:1 +惊叹 1 +x:1 +中档 1 +x:1 +陵区 1 +x:1 +串门子 1 +x:1 +地峡 1 +x:1 +有限元 1 +x:1 +川剧 1 +x:1 +洲 45 +x:45 +岛弧 1 +x:1 +惊叫 1 +x:1 +完熟 1 +x:1 +给惠国 1 +x:1 +代销点 1 +x:1 +久经 1 +x:1 +专员署 1 +x:1 +囫囵吞枣 1 +x:1 +通什 1 +x:1 +中栏 1 +x:1 +赃物 1 +x:1 +计时工资 1 +x:1 +登程 1 +x:1 +革委会 1 +x:1 +廉政卡 1 +x:1 +德政 1 +x:1 +双文明 1 +x:1 +效法 1 +x:1 +硬纸壳 1 +x:1 +巡礼 1 +x:1 +唱戏 1 +x:1 +中校 1 +x:1 +成活率 1 +x:1 +苞蕾 1 +x:1 +重武器 1 +x:1 +时下 1 +x:1 +骑龙村 1 +x:1 +淮北区 1 +x:1 +舞步 1 +x:1 +下划 1 +x:1 +下列 1 +x:1 +正气凛然 1 +x:1 +由上至下 1 +x:1 +中核 1 +x:1 +发现 1 +x:1 +豪举 1 +x:1 +时代 1 +x:1 +时令 1 +x:1 +中检 1 +x:1 +迁安 1 +x:1 +透 118 +x:118 +不咎既往 1 +x:1 +内话 1 +x:1 +隔雾看花 1 +x:1 +债台高筑 1 +x:1 +栅栏门 1 +x:1 +时价 1 +x:1 +时任 1 +x:1 +击垮 1 +x:1 +陵县 1 +x:1 +直勾勾 1 +x:1 +行政处分 1 +x:1 +澳大利亚 1 +x:1 +油流 1 +x:1 +殚思竭虑 1 +x:1 +镇上 1 +x:1 +纪录史 1 +x:1 +悲欢离合 1 +x:1 +认作 1 +x:1 +捕猎 1 +x:1 +玩耍 1 +x:1 +宣教部 1 +x:1 +亟需 1 +x:1 +电机界 1 +x:1 +燕玲 1 +x:1 +卷面 1 +x:1 +梅庄 1 +x:1 +乙亚胺 1 +x:1 +痰厥 1 +x:1 +红帽 1 +x:1 +不合格率 1 +x:1 +佛节 1 +x:1 +发行部 1 +x:1 +家禽场 1 +x:1 +时人 1 +x:1 +德方 1 +x:1 +德文 1 +x:1 +字眼 1 +x:1 +求救信 1 +x:1 +昌里 1 +x:1 +时事 1 +x:1 +蓬 7 +x:7 +通令 1 +x:1 +内设 1 +x:1 +老铁山 1 +x:1 +流年 1 +x:1 +合江县 1 +x:1 +出 7495 +x:7495 +本职工作 1 +x:1 +川南 1 +x:1 +原始 1 +x:1 +妇运 1 +x:1 +松桃县 1 +x:1 +油泥 1 +x:1 +工作母机 1 +x:1 +大堰川 1 +x:1 +下卷 1 +x:1 +织女星 1 +x:1 +翘 12 +x:12 +冬夜 1 +x:1 +茁壮 1 +x:1 +豪侠 1 +x:1 +进口 1 +x:1 +套交情 1 +x:1 +三品 1 +x:1 +方城 1 +x:1 +剥削者 1 +x:1 +下午 1 +x:1 +五十分 1 +x:1 +冬天 1 +x:1 +下南 1 +x:1 +埋首 1 +x:1 +下单 1 +x:1 +安宁区 1 +x:1 +讲演稿 1 +x:1 +播音室 1 +x:1 +花架子 1 +x:1 +缺少 1 +x:1 +俄共 1 +x:1 +散热量 1 +x:1 +鬼混 1 +x:1 +川北 1 +x:1 +春潮 1 +x:1 +卷叶蛾 1 +x:1 +本级 1 +x:1 +陵前 1 +x:1 +齐 315 +x:315 +荆笆 1 +x:1 +发物 1 +x:1 +夭亡 1 +x:1 +认亲 1 +x:1 +织布鸟 1 +x:1 +射灯 1 +x:1 +冬奥 1 +x:1 +注册税 1 +x:1 +全球通 1 +x:1 +小道 1 +x:1 +省政府 1 +x:1 +蔚成风气 1 +x:1 +芮城县 1 +x:1 +惊动 1 +x:1 +苹果树 1 +x:1 +汉学界 1 +x:1 +卸 45 +x:45 +时会 1 +x:1 +糖类 1 +x:1 +迷彩服 1 +x:1 +迅即 1 +x:1 +电吹风 1 +x:1 +野马 1 +x:1 +高高在上 1 +x:1 +油污 1 +x:1 +同土同根 1 +x:1 +流弊 1 +x:1 +嬉水 1 +x:1 +下台 1 +x:1 +不要紧 1 +x:1 +百转千回 1 +x:1 +野驴 1 +x:1 +雇车 1 +x:1 +明明灭灭 1 +x:1 +合家欢 1 +x:1 +池盐 1 +x:1 +靶子 1 +x:1 +下发 1 +x:1 +轮养 1 +x:1 +谜团 1 +x:1 +昌邑 1 +x:1 +流弹 1 +x:1 +三开门 1 +x:1 +地温 1 +x:1 +型录展 1 +x:1 +糖精 1 +x:1 +阳春市 1 +x:1 +使命 1 +x:1 +三十分 1 +x:1 +核导弹 1 +x:1 +旧房 1 +x:1 +造型各异 1 +x:1 +辈子 1 +x:1 +下厨 1 +x:1 +风云突变 1 +x:1 +中立主义 1 +x:1 +发狠 1 +x:1 +认为 1 +x:1 +俄军 1 +x:1 +下去 1 +x:1 +昌都 1 +x:1 +油水 1 +x:1 +襟 3 +x:3 +借鉴性 1 +x:1 +波密 1 +x:1 +流形 1 +x:1 +桂冠 1 +x:1 +杨柏乡 1 +x:1 +下压 1 +x:1 +方圆 1 +x:1 +臆造 1 +x:1 +发行量 1 +x:1 +发狂 1 +x:1 +召集 1 +x:1 +举重赛 1 +x:1 +绝缘子 1 +x:1 +书童 1 +x:1 +栀 3 +x:3 +辅 35 +x:35 +智利队 1 +x:1 +高钒铁 1 +x:1 +必要性 1 +x:1 +赤身裸体 1 +x:1 +下山 1 +x:1 +黑云山 1 +x:1 +踢毽 1 +x:1 +取悦 1 +x:1 +轮廓 1 +x:1 +野营地 1 +x:1 +方壶 1 +x:1 +下层 1 +x:1 +渐渐 1 +x:1 +在位 1 +x:1 +曲线图 1 +x:1 +赶集 1 +x:1 +完美 1 +x:1 +风流人物 1 +x:1 +中景 1 +x:1 +工程浩大 1 +x:1 +购票 1 +x:1 +艺徒 1 +x:1 +图谋不轨 1 +x:1 +户政处 1 +x:1 +内蕴 1 +x:1 +缺 206 +x:206 +下属 1 +x:1 +比翼双飞 1 +x:1 +侍者 1 +x:1 +站上 1 +x:1 +立法会 1 +x:1 +老工人 1 +x:1 +解约 1 +x:1 +花扦儿 1 +x:1 +改良党 1 +x:1 +党旗 1 +x:1 +往回 1 +x:1 +溜之乎也 1 +x:1 +赖以 1 +x:1 +春恋 1 +x:1 +毛纺 1 +x:1 +毛线 1 +x:1 +吸水纸 1 +x:1 +道道 1 +x:1 +意思 1 +x:1 +孤家寡人 1 +x:1 +青稞酒 1 +x:1 +灵车 1 +x:1 +非对抗 1 +x:1 +妇联 1 +x:1 +唱法 1 +x:1 +泛旅 1 +x:1 +禁而不止 1 +x:1 +概貌 1 +x:1 +确权 1 +x:1 +超时令 1 +x:1 +凸凹不平 1 +x:1 +高才生 1 +x:1 +硫化 1 +x:1 +岛内 1 +x:1 +背影 1 +x:1 +轻于鸿毛 1 +x:1 +救灾款 1 +x:1 +摸清 1 +x:1 +大专班 1 +x:1 +星 159 +x:159 +光疏媒质 1 +x:1 +原子炸弹 1 +x:1 +颠 16 +x:16 +党支 1 +x:1 +过眼云烟 1 +x:1 +山清水秀 1 +x:1 +永不 1 +x:1 +常青组 1 +x:1 +戏水区 1 +x:1 +脱 119 +x:119 +方塘 1 +x:1 +党政 1 +x:1 +欧里乡 1 +x:1 +笑眯眯 1 +x:1 +工艺师 1 +x:1 +永世 1 +x:1 +嘿 8 +x:8 +瓦头村 1 +x:1 +黄铜色 1 +x:1 +恪尽职守 1 +x:1 +通人 1 +x:1 +播音员 1 +x:1 +旧派 1 +x:1 +拒贿 1 +x:1 +川岛 1 +x:1 +缺口 1 +x:1 +光阴荏苒 1 +x:1 +清运车 1 +x:1 +中暑 1 +x:1 +展览部 1 +x:1 +桂庙 1 +x:1 +兴山县 1 +x:1 +印鉴 1 +x:1 +茫茫 1 +x:1 +门体 1 +x:1 +雷亚尔 1 +x:1 +采花节 1 +x:1 +轮带 1 +x:1 +永久 1 +x:1 +靶向 1 +x:1 +马克思 1 +x:1 +下岗 1 +x:1 +银杉 1 +x:1 +夏阳乡 1 +x:1 +永乐 1 +x:1 +鬼才 1 +x:1 +门人 1 +x:1 +站位 1 +x:1 +站住 1 +x:1 +学业 1 +x:1 +勒勒车 1 +x:1 +便民牌 1 +x:1 +总动员 1 +x:1 +过路车 1 +x:1 +习非成是 1 +x:1 +救亡图存 1 +x:1 +发簪 1 +x:1 +改弦更张 1 +x:1 +汛前 1 +x:1 +华蓥山 1 +x:1 +橡胶 1 +x:1 +春意 1 +x:1 +鹅湖 1 +x:1 +管理者 1 +x:1 +地中海港 1 +x:1 +梅兹 1 +x:1 +兵站部 1 +x:1 +工学院 1 +x:1 +梅关 1 +x:1 +骨量 1 +x:1 +俄式 1 +x:1 +骨里 1 +x:1 +中服 1 +x:1 +虚开 1 +x:1 +洋香瓜 1 +x:1 +峭立 1 +x:1 +意愿 1 +x:1 +主教练 1 +x:1 +驶抵 1 +x:1 +税务所长 1 +x:1 +甘耐 1 +x:1 +症状 1 +x:1 +小吃店 1 +x:1 +治沙站 1 +x:1 +执笔 1 +x:1 +挡水面 1 +x:1 +集流 1 +x:1 +宿舍区 1 +x:1 +毛羽 1 +x:1 +昼 5 +x:5 +原貌 1 +x:1 +完结 1 +x:1 +纳税钱 1 +x:1 +繁枝茂叶 1 +x:1 +流出 1 +x:1 +肋膜 1 +x:1 +聊以解嘲 1 +x:1 +寓示 1 +x:1 +下工 1 +x:1 +戊戌政变 1 +x:1 +管理股 1 +x:1 +老面皮 1 +x:1 +牛铃 1 +x:1 +下巴 1 +x:1 +酱肉 1 +x:1 +购车费 1 +x:1 +评比 1 +x:1 +真确 1 +x:1 +长话线 1 +x:1 +莜 1 +x:1 +攀升 1 +x:1 +往圣 1 +x:1 +冲击性 1 +x:1 +发粘 1 +x:1 +章回体 1 +x:1 +门下 1 +x:1 +行军床 1 +x:1 +日日夜夜 1 +x:1 +红一师 1 +x:1 +盐田港 1 +x:1 +禄丰 1 +x:1 +裴 44 +x:44 +优生学 1 +x:1 +乃东县 1 +x:1 +俄 1446 +x:1446 +轮式 1 +x:1 +缺勤 1 +x:1 +甘肃 1 +x:1 +观光客 1 +x:1 +图灵机 1 +x:1 +卷须 1 +x:1 +解缴 1 +x:1 +用血者 1 +x:1 +流入 1 +x:1 +忧虑 1 +x:1 +烦 16 +x:16 +昌黎 1 +x:1 +纤维管 1 +x:1 +工缴费 1 +x:1 +香烛 1 +x:1 +安立路 1 +x:1 +绳之以法 1 +x:1 +外交部长 1 +x:1 +朝代 1 +x:1 +行行 1 +x:1 +英气 1 +x:1 +脑细胞 1 +x:1 +甘草 1 +x:1 +打浆机 1 +x:1 +渔霸 1 +x:1 +虎耳草 1 +x:1 +毛糙 1 +x:1 +馍 2 +x:2 +诚笃 1 +x:1 +啄食 1 +x:1 +要道 1 +x:1 +临危授命 1 +x:1 +卵细胞 1 +x:1 +下年 1 +x:1 +屠场 1 +x:1 +丘 26 +x:26 +脱手 1 +x:1 +奖状 1 +x:1 +古田四路 1 +x:1 +危旧房屋 1 +x:1 +早班车 1 +x:1 +岛区 1 +x:1 +该片 1 +x:1 +拒还 1 +x:1 +这笔 1 +x:1 +水刷石 1 +x:1 +暖色 1 +x:1 +会客 1 +x:1 +猪圈 1 +x:1 +核心区 1 +x:1 +入射线 1 +x:1 +暂缺 1 +x:1 +稀落 1 +x:1 +溪头 1 +x:1 +评标 1 +x:1 +油茶面儿 1 +x:1 +自相残杀 1 +x:1 +政府学 1 +x:1 +轮岗 1 +x:1 +发网 1 +x:1 +内涵式 1 +x:1 +湘潭 1 +x:1 +三角裤 1 +x:1 +满汉全席 1 +x:1 +江湾镇 1 +x:1 +申请书 1 +x:1 +字正腔圆 1 +x:1 +西康路 1 +x:1 +下帖 1 +x:1 +扎堆儿 1 +x:1 +恣肆汪洋 1 +x:1 +上街口 1 +x:1 +慰问组 1 +x:1 +试题 1 +x:1 +腾空 1 +x:1 +操纵箱 1 +x:1 +创始者 1 +x:1 +本科段 1 +x:1 +榔头 1 +x:1 +复 68 +x:68 +东南角 1 +x:1 +歌唱性 1 +x:1 +鬼怪 1 +x:1 +自谦 1 +x:1 +保优汰劣 1 +x:1 +以色列国 1 +x:1 +厦 8 +x:8 +流利 1 +x:1 +保密局 1 +x:1 +莫不是 1 +x:1 +申请人 1 +x:1 +自由峰 1 +x:1 +党课日 1 +x:1 +省政协 1 +x:1 +呼市 1 +x:1 +论列 1 +x:1 +鉴 42 +x:42 +观棋室 1 +x:1 +钥匙扣 1 +x:1 +观 119 +x:119 +中侨委 1 +x:1 +必须 1 +x:1 +促销队 1 +x:1 +五大连池 1 +x:1 +使女 1 +x:1 +不畏难辛 1 +x:1 +道德村 1 +x:1 +下庵 1 +x:1 +知人 1 +x:1 +存在论 1 +x:1 +壮丽 1 +x:1 +惊异 1 +x:1 +象鼻虫 1 +x:1 +消油剂 1 +x:1 +陶锅 1 +x:1 +知事 1 +x:1 +桦南 1 +x:1 +劳作室 1 +x:1 +参与性 1 +x:1 +选课 1 +x:1 +种蛋 1 +x:1 +员工 1 +x:1 +车辙 1 +x:1 +姑妄听之 1 +x:1 +扭送 1 +x:1 +望江路 1 +x:1 +以歌当哭 1 +x:1 +不连沟村 1 +x:1 +宠爱有加 1 +x:1 +科森察 1 +x:1 +策鞭 1 +x:1 +大汗淋漓 1 +x:1 +方寸 1 +x:1 +居功至伟 1 +x:1 +白菜碑 1 +x:1 +私通 1 +x:1 +中教 1 +x:1 +撒气 1 +x:1 +卡规 1 +x:1 +中散 1 +x:1 +时来运转 1 +x:1 +罪大恶极 1 +x:1 +左右手 1 +x:1 +港口区 1 +x:1 +玉宇 1 +x:1 +昧心话 1 +x:1 +平成十年 1 +x:1 +轻音 1 +x:1 +河运 1 +x:1 +结发夫妻 1 +x:1 +圆柱 1 +x:1 +住址 1 +x:1 +临河市 1 +x:1 +抓痒式 1 +x:1 +承租商 1 +x:1 +淮北市 1 +x:1 +行贿者 1 +x:1 +怒狮 1 +x:1 +化淤通络 1 +x:1 +布条条 1 +x:1 +酱色 1 +x:1 +论及 1 +x:1 +睨 1 +x:1 +深究 1 +x:1 +轩辕 1 +x:1 +商社 1 +x:1 +技术股 1 +x:1 +胎死率 1 +x:1 +苦味酸 1 +x:1 +争风吃醋 1 +x:1 +份餐制 1 +x:1 +症瘕 1 +x:1 +稀薄 1 +x:1 +分科 1 +x:1 +保管部 1 +x:1 +高陵县 1 +x:1 +要量 1 +x:1 +应当 1 +x:1 +东城 1 +x:1 +中旗 1 +x:1 +发红 1 +x:1 +核心办 1 +x:1 +轩车 1 +x:1 +波谲云诡 1 +x:1 +毒液 1 +x:1 +中旬 1 +x:1 +甘苦 1 +x:1 +马关条约 1 +x:1 +行政区队 1 +x:1 +无恶不作 1 +x:1 +方子 1 +x:1 +官僚式 1 +x:1 +上国村 1 +x:1 +纪检 1 +x:1 +包销商 1 +x:1 +方字 1 +x:1 +泪如泉涌 1 +x:1 +棚里 1 +x:1 +海震 1 +x:1 +中文 1 +x:1 +泾阳 1 +x:1 +间隔期 1 +x:1 +窦段 1 +x:1 +滋补 1 +x:1 +撒泼 1 +x:1 +此伏彼起 1 +x:1 +车轮赛 1 +x:1 +油性 1 +x:1 +急三火四 1 +x:1 +摆谱儿 1 +x:1 +储蓄卡 1 +x:1 +大明湖 1 +x:1 +靶场 1 +x:1 +划桨 1 +x:1 +中少社 1 +x:1 +迁回 1 +x:1 +干粮袋 1 +x:1 +兵强马壮 1 +x:1 +履 5 +x:5 +啜 3 +x:3 +靶圈 1 +x:1 +赭红 1 +x:1 +预研性 1 +x:1 +篓 5 +x:5 +扭秧歌 1 +x:1 +椒商 1 +x:1 +概述 1 +x:1 +注资 1 +x:1 +祷 2 +x:2 +油管 1 +x:1 +中方 1 +x:1 +街混儿 1 +x:1 +抚育 1 +x:1 +图 1202 +x:1202 +和田县 1 +x:1 +居住权 1 +x:1 +甘蕉 1 +x:1 +栗于坪乡 1 +x:1 +最最 1 +x:1 +琐 1 +x:1 +彼此 1 +x:1 +伺机 1 +x:1 +封盘 1 +x:1 +冬初 1 +x:1 +枝 69 +x:69 +模棱两可 1 +x:1 +畅通无阻 1 +x:1 +综合大学 1 +x:1 +且不说 1 +x:1 +使得 1 +x:1 +毛竹 1 +x:1 +地方 1 +x:1 +使徒 1 +x:1 +一个半个 1 +x:1 +油柑 1 +x:1 +重感冒 1 +x:1 +云台山 1 +x:1 +冲击方 1 +x:1 +流星雨 1 +x:1 +内脏 1 +x:1 +理想主义 1 +x:1 +串门儿 1 +x:1 +梁庄村 1 +x:1 +固定岗 1 +x:1 +缸口 1 +x:1 +中戏 1 +x:1 +温润 1 +x:1 +口 490 +x:490 +死去活来 1 +x:1 +印刷点 1 +x:1 +发祥 1 +x:1 +院纪 1 +x:1 +仗 42 +x:42 +发票 1 +x:1 +天下大治 1 +x:1 +甘蔗 1 +x:1 +象征 1 +x:1 +金环蛇 1 +x:1 +迁入 1 +x:1 +斐济队 1 +x:1 +期价 1 +x:1 +且不论 1 +x:1 +计算机业 1 +x:1 +府邸 1 +x:1 +封皮 1 +x:1 +旱 52 +x:52 +家政学 1 +x:1 +村组 1 +x:1 +蹁跹 1 +x:1 +魂儿 1 +x:1 +春播 1 +x:1 +贫困村 1 +x:1 +故伎 1 +x:1 +徽饰 1 +x:1 +下士 1 +x:1 +推土机手 1 +x:1 +列植 1 +x:1 +料理 1 +x:1 +流向 1 +x:1 +朱雀 1 +x:1 +口诛笔伐 1 +x:1 +天花粉 1 +x:1 +偏口鱼 1 +x:1 +优质段 1 +x:1 +油松 1 +x:1 +方山 1 +x:1 +惊奇 1 +x:1 +找水 1 +x:1 +非常任 1 +x:1 +油杉 1 +x:1 +帽盔 1 +x:1 +糠油 1 +x:1 +执结 1 +x:1 +禀性 1 +x:1 +卡萨内 1 +x:1 +东五路 1 +x:1 +地政 1 +x:1 +期中 1 +x:1 +方言土语 1 +x:1 +龙生九子 1 +x:1 +管线路 1 +x:1 +地支 1 +x:1 +发福 1 +x:1 +集水区 1 +x:1 +先生 1 +x:1 +姜格庄村 1 +x:1 +菊 111 +x:111 +角尺 1 +x:1 +内膜 1 +x:1 +油机 1 +x:1 +执红 1 +x:1 +一鸣惊人 1 +x:1 +连接性 1 +x:1 +葛 132 +x:132 +执纪 1 +x:1 +中报 1 +x:1 +持之以恒 1 +x:1 +游戏厅 1 +x:1 +甘薯 1 +x:1 +胸怀 1 +x:1 +求职人 1 +x:1 +细砂 1 +x:1 +储蓄员 1 +x:1 +文化站 1 +x:1 +商约 1 +x:1 +迁出 1 +x:1 +任由 1 +x:1 +用项 1 +x:1 +种族主义 1 +x:1 +射程 1 +x:1 +故事 1 +x:1 +领会 1 +x:1 +尼泊尔 1 +x:1 +屈志 1 +x:1 +支农办 1 +x:1 +纷起 1 +x:1 +渐次 1 +x:1 +可庆可贺 1 +x:1 +方巾 1 +x:1 +任用 1 +x:1 +绿荫蔽日 1 +x:1 +单晶河乡 1 +x:1 +储备头寸 1 +x:1 +故交 1 +x:1 +执罚 1 +x:1 +装焊 1 +x:1 +支离破碎 1 +x:1 +席卷 1 +x:1 +搋子 1 +x:1 +故人 1 +x:1 +果心儿 1 +x:1 +固定工 1 +x:1 +忏悔 1 +x:1 +招徕声 1 +x:1 +中指 1 +x:1 +娇气 1 +x:1 +纪游 1 +x:1 +坟丘 1 +x:1 +久病 1 +x:1 +稳拿把攥 1 +x:1 +阔叶林 1 +x:1 +河边 1 +x:1 +波兰 1 +x:1 +染化料 1 +x:1 +内耗 1 +x:1 +廉正无私 1 +x:1 +辈出 1 +x:1 +行话 1 +x:1 +足球 1 +x:1 +波光 1 +x:1 +普罗比登 1 +x:1 +呐喊 1 +x:1 +安检门 1 +x:1 +轻重 1 +x:1 +傲世 1 +x:1 +楚雄州 1 +x:1 +概要 1 +x:1 +卡车 1 +x:1 +促销 1 +x:1 +陵墓 1 +x:1 +讲面子 1 +x:1 +汩汩 1 +x:1 +广交会 1 +x:1 +甘蓝 1 +x:1 +轮子 1 +x:1 +完稿 1 +x:1 +方便面 1 +x:1 +渡人 1 +x:1 +辈儿 1 +x:1 +陆相 1 +x:1 +原始社会 1 +x:1 +党性 1 +x:1 +内能 1 +x:1 +吃官司 1 +x:1 +全过程 1 +x:1 +新兴北里 1 +x:1 +遵义县 1 +x:1 +野芪 1 +x:1 +旧案 1 +x:1 +无济于事 1 +x:1 +概观 1 +x:1 +毛笔 1 +x:1 +春日 1 +x:1 +概览 1 +x:1 +橱柜 1 +x:1 +风 468 +x:468 +新民日报 1 +x:1 +久留 1 +x:1 +叔 17 +x:17 +意方 1 +x:1 +中排 1 +x:1 +地摊 1 +x:1 +祸害 1 +x:1 +春旱 1 +x:1 +力矩 1 +x:1 +雁群 1 +x:1 +发审委 1 +x:1 +又惊又喜 1 +x:1 +党恩 1 +x:1 +政党 1 +x:1 +故乡 1 +x:1 +桂宫 1 +x:1 +冬叶 1 +x:1 +意料 1 +x:1 +桂花村 1 +x:1 +鹰犬 1 +x:1 +氟橡胶 1 +x:1 +痉挛 1 +x:1 +拒请 1 +x:1 +西马家 1 +x:1 +戈 18 +x:18 +讨价 1 +x:1 +吉他 1 +x:1 +炒黄豆 1 +x:1 +鞋脸 1 +x:1 +滹沱 1 +x:1 +担惊受怕 1 +x:1 +员外 1 +x:1 +低人一等 1 +x:1 +发笑 1 +x:1 +鄂钢 1 +x:1 +禀报 1 +x:1 +刨 29 +x:29 +购置 1 +x:1 +砂石土 1 +x:1 +佳肴 1 +x:1 +逆料 1 +x:1 +吊脚状 1 +x:1 +干活儿 1 +x:1 +唁函 1 +x:1 +先知 1 +x:1 +问答题 1 +x:1 +春景 1 +x:1 +保水 1 +x:1 +拍案叫好 1 +x:1 +步谈机 1 +x:1 +动物学家 1 +x:1 +爱屋及乌 1 +x:1 +陆生 1 +x:1 +角度 1 +x:1 +心上 1 +x:1 +阻抗 1 +x:1 +翻沉 1 +x:1 +楚雄市 1 +x:1 +中性 1 +x:1 +华而不实 1 +x:1 +陶醉 1 +x:1 +方庄 1 +x:1 +大专生 1 +x:1 +油料 1 +x:1 +木木的 1 +x:1 +春晖 1 +x:1 +腹腔 1 +x:1 +霍去病泉 1 +x:1 +液化气船 1 +x:1 +鼎湖山 1 +x:1 +著作等身 1 +x:1 +雪里送炭 1 +x:1 +波动 1 +x:1 +赤条条 1 +x:1 +种花 1 +x:1 +历历 1 +x:1 +驮子 1 +x:1 +断送 1 +x:1 +华阴市 1 +x:1 +辈分 1 +x:1 +五彩斑斓 1 +x:1 +屈居 1 +x:1 +梅园 1 +x:1 +通风管 1 +x:1 +发行额 1 +x:1 +评注 1 +x:1 +嘉荫县 1 +x:1 +冬储 1 +x:1 +耗用 1 +x:1 +天纵不羁 1 +x:1 +忍饥挨饿 1 +x:1 +耗电 1 +x:1 +腹膜 1 +x:1 +集合论 1 +x:1 +粉底 1 +x:1 +滚筒机 1 +x:1 +印刷版 1 +x:1 +陵寝 1 +x:1 +万恶 1 +x:1 +文昌阁 1 +x:1 +梁王 1 +x:1 +换药 1 +x:1 +结合膜 1 +x:1 +跃居 1 +x:1 +汉学系 1 +x:1 +地权 1 +x:1 +话剧所 1 +x:1 +陆疆 1 +x:1 +旧欠 1 +x:1 +紫丁香 1 +x:1 +第三产业 1 +x:1 +加强班 1 +x:1 +历史 1 +x:1 +受害者 1 +x:1 +破镜重圆 1 +x:1 +解码 1 +x:1 +屈就 1 +x:1 +金门县 1 +x:1 +北回归线 1 +x:1 +专管员 1 +x:1 +松花湖畔 1 +x:1 +来访者 1 +x:1 +登 342 +x:342 +禀承 1 +x:1 +委 64 +x:64 +字条 1 +x:1 +并肩作战 1 +x:1 +下学 1 +x:1 +党务案 1 +x:1 +银盐 1 +x:1 +发稿 1 +x:1 +差不离 1 +x:1 +外面儿光 1 +x:1 +夜游神 1 +x:1 +唱歌 1 +x:1 +舞 109 +x:109 +流域性 1 +x:1 +屠刀 1 +x:1 +负心人 1 +x:1 +共享税 1 +x:1 +巨细胞 1 +x:1 +党报 1 +x:1 +被转载率 1 +x:1 +苞谷 1 +x:1 +奠基礼 1 +x:1 +明珠杯 1 +x:1 +下子 1 +x:1 +童车轮 1 +x:1 +德江 1 +x:1 +扼住 1 +x:1 +储蓄型 1 +x:1 +方志 1 +x:1 +坎上乡 1 +x:1 +白衣战士 1 +x:1 +中意 1 +x:1 +书社 1 +x:1 +怒目 1 +x:1 +莫斯科城 1 +x:1 +得道多助 1 +x:1 +流域 1 +x:1 +划法 1 +x:1 +教教 1 +x:1 +华而不媚 1 +x:1 +艺术片 1 +x:1 +多来咪 1 +x:1 +解禁 1 +x:1 +脱机 1 +x:1 +该省 1 +x:1 +防空壕 1 +x:1 +播音台 1 +x:1 +艺术周 1 +x:1 +缺员 1 +x:1 +料石 1 +x:1 +肯特郡 1 +x:1 +谋臣 1 +x:1 +不耐烦 1 +x:1 +港口型 1 +x:1 +望而却步 1 +x:1 +达产期 1 +x:1 +谶纬 1 +x:1 +复合量词 1 +x:1 +象山 1 +x:1 +该矿 1 +x:1 +终结符 1 +x:1 +如雷轰顶 1 +x:1 +下岗证 1 +x:1 +棋类室 1 +x:1 +自高自大 1 +x:1 +谭 227 +x:227 +结合能 1 +x:1 +续航 1 +x:1 +轮奸 1 +x:1 +事务署 1 +x:1 +来不得 1 +x:1 +草坪 1 +x:1 +百鸟朝凤 1 +x:1 +朱门 1 +x:1 +要闻 1 +x:1 +毛票 1 +x:1 +疼 39 +x:39 +概论 1 +x:1 +门外汉 1 +x:1 +谜底 1 +x:1 +代省长 1 +x:1 +永生永世 1 +x:1 +欧姆定律 1 +x:1 +云龙区 1 +x:1 +眉清目朗 1 +x:1 +固定式 1 +x:1 +草坡 1 +x:1 +德河 1 +x:1 +下家 1 +x:1 +田螺 1 +x:1 +由此可见 1 +x:1 +德治 1 +x:1 +发端 1 +x:1 +留用 1 +x:1 +唱段 1 +x:1 +方式 1 +x:1 +腹胀 1 +x:1 +讨伐 1 +x:1 +岛国 1 +x:1 +概说 1 +x:1 +神经细胞 1 +x:1 +怨鬼 1 +x:1 +论坛 1 +x:1 +下定 1 +x:1 +高增值 1 +x:1 +岛园 1 +x:1 +破路战 1 +x:1 +诚意 1 +x:1 +鞅 2 +x:2 +蠢蠢欲动 1 +x:1 +礼节性 1 +x:1 +该桥 1 +x:1 +往事 1 +x:1 +金合欢花 1 +x:1 +发放 1 +x:1 +广河县 1 +x:1 +激战 1 +x:1 +领到 1 +x:1 +档案系 1 +x:1 +该案 1 +x:1 +机动船 1 +x:1 +养老 1 +x:1 +观摩课 1 +x:1 +中外合资 1 +x:1 +旧病 1 +x:1 +朝圣 1 +x:1 +助动词 1 +x:1 +大学堂 1 +x:1 +脱硫 1 +x:1 +机 108 +x:108 +天长地久 1 +x:1 +小是小非 1 +x:1 +夏练三伏 1 +x:1 +碑头 1 +x:1 +故友 1 +x:1 +商战 1 +x:1 +野趣 1 +x:1 +该校 1 +x:1 +地租 1 +x:1 +射杀 1 +x:1 +整体 1 +x:1 +发散 1 +x:1 +油箱 1 +x:1 +杂和面儿 1 +x:1 +新奇 1 +x:1 +海边防 1 +x:1 +知名 1 +x:1 +沙朗河 1 +x:1 +骨髓瘤 1 +x:1 +商户 1 +x:1 +运土车 1 +x:1 +不无遗憾 1 +x:1 +岁月如流 1 +x:1 +野花 1 +x:1 +离心离德 1 +x:1 +年 15535 +x:15535 +地秤 1 +x:1 +工人阶级 1 +x:1 +有害物 1 +x:1 +解暑 1 +x:1 +喜不自胜 1 +x:1 +黄岛区 1 +x:1 +地积 1 +x:1 +合订本 1 +x:1 +期初 1 +x:1 +伸缩 1 +x:1 +大石镇 1 +x:1 +村户 1 +x:1 +酱香 1 +x:1 +德班 1 +x:1 +领办 1 +x:1 +曲棍球 1 +x:1 +期刊 1 +x:1 +溶点 1 +x:1 +中统 1 +x:1 +解放北路 1 +x:1 +心绪难平 1 +x:1 +执拗 1 +x:1 +肠 15 +x:15 +中继 1 +x:1 +永嘉 1 +x:1 +拜年法儿 1 +x:1 +镰 4 +x:4 +蜡床 1 +x:1 +海雕 1 +x:1 +脊梁 1 +x:1 +辛酸苦辣 1 +x:1 +着数 1 +x:1 +幕后 1 +x:1 +电子游戏 1 +x:1 +发文 1 +x:1 +别无分店 1 +x:1 +私访 1 +x:1 +私设 1 +x:1 +罗湖区 1 +x:1 +播出 1 +x:1 +地祗 1 +x:1 +积恶成习 1 +x:1 +核选择 1 +x:1 +维和费 1 +x:1 +内债 1 +x:1 +小飞虎牌 1 +x:1 +非战斗性 1 +x:1 +发旧 1 +x:1 +印床 1 +x:1 +私话 1 +x:1 +师心自用 1 +x:1 +流传千古 1 +x:1 +涵闸 1 +x:1 +冬令 1 +x:1 +事务性 1 +x:1 +帽檐 1 +x:1 +减速板 1 +x:1 +苍凉 1 +x:1 +碍事 1 +x:1 +倦态 1 +x:1 +米 1779 +x:1779 +拒销 1 +x:1 +揿 1 +x:1 +缸体 1 +x:1 +条理化 1 +x:1 +向荣里 1 +x:1 +晋州 1 +x:1 +缉私战 1 +x:1 +趁着 1 +x:1 +纪特 1 +x:1 +讹误 1 +x:1 +席位 1 +x:1 +站址 1 +x:1 +高尔基市 1 +x:1 +低寒带 1 +x:1 +走走看看 1 +x:1 +乡里 1 +x:1 +该楼 1 +x:1 +倒戈 1 +x:1 +高潮期 1 +x:1 +眉清目秀 1 +x:1 +植树日 1 +x:1 +惹火烧身 1 +x:1 +王营子 1 +x:1 +讹诈 1 +x:1 +出入证 1 +x:1 +领区 1 +x:1 +艺研所 1 +x:1 +米粉丝 1 +x:1 +吉凶 1 +x:1 +高性能 1 +x:1 +艳红 1 +x:1 +潇潇洒洒 1 +x:1 +素鸡 1 +x:1 +中缀 1 +x:1 +片子 1 +x:1 +妨害 1 +x:1 +南浔区 1 +x:1 +峭拔 1 +x:1 +地磁 1 +x:1 +地磅 1 +x:1 +中缝 1 +x:1 +同龄人 1 +x:1 +排字机 1 +x:1 +防霉剂 1 +x:1 +计算机化 1 +x:1 +建档立卡 1 +x:1 +罪案率 1 +x:1 +拒钓 1 +x:1 +昌虎 1 +x:1 +囚入 1 +x:1 +有机肥场 1 +x:1 +襄垣 1 +x:1 +上岗制 1 +x:1 +安哥拉 1 +x:1 +印张 1 +x:1 +站场 1 +x:1 +虐待 1 +x:1 +或许 1 +x:1 +脚手架 1 +x:1 +解析 1 +x:1 +瓦工活 1 +x:1 +印染布 1 +x:1 +诚恳 1 +x:1 +要诀 1 +x:1 +轻贱 1 +x:1 +地砖 1 +x:1 +赶车 1 +x:1 +仰慕 1 +x:1 +尉 304 +x:304 +熔炼炉 1 +x:1 +果庄乡 1 +x:1 +乙级 1 +x:1 +嘛呢堆 1 +x:1 +中介费 1 +x:1 +吉兆 1 +x:1 +卫星 1 +x:1 +耀武扬威 1 +x:1 +单季稻 1 +x:1 +无人过问 1 +x:1 +寓意 1 +x:1 +要说 1 +x:1 +佛门 1 +x:1 +供应船 1 +x:1 +党籍 1 +x:1 +杯盘狼藉 1 +x:1 +领取 1 +x:1 +领受 1 +x:1 +紫竹院 1 +x:1 +图鲁兹 1 +x:1 +骡马 1 +x:1 +咨询部 1 +x:1 +美若天仙 1 +x:1 +湿乎乎 1 +x:1 +彭州 1 +x:1 +天菩萨 1 +x:1 +梁沟 1 +x:1 +春种 1 +x:1 +聚酯 1 +x:1 +毽子 1 +x:1 +春秋 1 +x:1 +老爷爷 1 +x:1 +钵头 1 +x:1 +脱离 1 +x:1 +休息厅 1 +x:1 +划片 1 +x:1 +华北局 1 +x:1 +要论 1 +x:1 +倦意 1 +x:1 +四朵金花 1 +x:1 +种鸡 1 +x:1 +吉汗加 1 +x:1 +盖棺论定 1 +x:1 +一匡天下 1 +x:1 +佛陀 1 +x:1 +妒忌心 1 +x:1 +诚挚 1 +x:1 +碑学 1 +x:1 +种鸽 1 +x:1 +嘘 3 +x:3 +锚 4 +x:4 +妈湾港 1 +x:1 +筋疲力尽 1 +x:1 +篮球场 1 +x:1 +要衢 1 +x:1 +见利思义 1 +x:1 +总控室 1 +x:1 +党群 1 +x:1 +自给自足 1 +x:1 +脱空 1 +x:1 +腊尔山 1 +x:1 +针状焦 1 +x:1 +冷水滩区 1 +x:1 +党羽 1 +x:1 +旋窑 1 +x:1 +传记片 1 +x:1 +牛车 1 +x:1 +蓖麻子 1 +x:1 +通风机 1 +x:1 +种鸟 1 +x:1 +红杉树 1 +x:1 +扼制 1 +x:1 +菜籽油 1 +x:1 +射敌 1 +x:1 +站名 1 +x:1 +技术馆 1 +x:1 +肋骨 1 +x:1 +发条 1 +x:1 +商态 1 +x:1 +实用文 1 +x:1 +铲刀 1 +x:1 +止住 1 +x:1 +装卸费 1 +x:1 +耙子 1 +x:1 +驶离 1 +x:1 +香草醛 1 +x:1 +天天 1 +x:1 +Ⅲ 9 +x:9 +吐穗 1 +x:1 +辈份 1 +x:1 +鹰派 1 +x:1 +脱稿 1 +x:1 +苍南 1 +x:1 +没劲 1 +x:1 +认定 1 +x:1 +非本土 1 +x:1 +饲料站 1 +x:1 +象溪乡 1 +x:1 +秋夜 1 +x:1 +浠水县 1 +x:1 +事务所 1 +x:1 +售楼价 1 +x:1 +冬菇 1 +x:1 +唱盘 1 +x:1 +虽败犹荣 1 +x:1 +开发署 1 +x:1 +常委会 1 +x:1 +制造地 1 +x:1 +商情 1 +x:1 +走廊 1 +x:1 +庞各庄镇 1 +x:1 +学历者 1 +x:1 +种麻 1 +x:1 +刹时 1 +x:1 +飞流直下 1 +x:1 +俄罗斯队 1 +x:1 +永吉 1 +x:1 +潭柘寺 1 +x:1 +灯草 1 +x:1 +神气活现 1 +x:1 +搜寻 1 +x:1 +洛阳纸贵 1 +x:1 +认字 1 +x:1 +苍原 1 +x:1 +本科率 1 +x:1 +莽草 1 +x:1 +吉剧 1 +x:1 +排排坐 1 +x:1 +逡巡 1 +x:1 +苍古 1 +x:1 +外资委 1 +x:1 +托词 1 +x:1 +战旗展 1 +x:1 +麝牛 1 +x:1 +别连科 1 +x:1 +本科班 1 +x:1 +笃笃定定 1 +x:1 +砚池街 1 +x:1 +溆浦县 1 +x:1 +对局室 1 +x:1 +超导电性 1 +x:1 +留校 1 +x:1 +组团社 1 +x:1 +投之以桃 1 +x:1 +奥肯淖尔 1 +x:1 +吉利 1 +x:1 +保险业界 1 +x:1 +冶金部 1 +x:1 +申请国 1 +x:1 +车胎 1 +x:1 +催化剂 1 +x:1 +卡通 1 +x:1 +易如反掌 1 +x:1 +捕杀 1 +x:1 +拘束 1 +x:1 +专业部 1 +x:1 +朝向 1 +x:1 +甄 6 +x:6 +租赁金 1 +x:1 +逻辑思维 1 +x:1 +佳肴珍馐 1 +x:1 +果味香型 1 +x:1 +哭丧着脸 1 +x:1 +地窟 1 +x:1 +赶路 1 +x:1 +该死 1 +x:1 +暂星 1 +x:1 +豪客 1 +x:1 +国民党员 1 +x:1 +坝体 1 +x:1 +春笋 1 +x:1 +提款权 1 +x:1 +阴谋家 1 +x:1 +佛面 1 +x:1 +兔种 1 +x:1 +陆桥 1 +x:1 +抚顺 1 +x:1 +传奇式 1 +x:1 +党纲 1 +x:1 +发明 1 +x:1 +党组 1 +x:1 +毛料 1 +x:1 +蛋壳 1 +x:1 +危局 1 +x:1 +走开 1 +x:1 +该款 1 +x:1 +历久 1 +x:1 +领先 1 +x:1 +北太平庄 1 +x:1 +秉性难移 1 +x:1 +哈桑区 1 +x:1 +信以为真 1 +x:1 +发晕 1 +x:1 +赶超 1 +x:1 +红旗区 1 +x:1 +领养 1 +x:1 +热 329 +x:329 +娱乐区 1 +x:1 +豪富 1 +x:1 +历书 1 +x:1 +工龄 1 +x:1 +执意 1 +x:1 +购房 1 +x:1 +促请 1 +x:1 +营救者 1 +x:1 +赶趟 1 +x:1 +刁 25 +x:25 +协办员 1 +x:1 +司局长 1 +x:1 +双声 1 +x:1 +入侵者 1 +x:1 +累西腓市 1 +x:1 +陆棚 1 +x:1 +领军 1 +x:1 +春管 1 +x:1 +秘书组 1 +x:1 +赶走 1 +x:1 +俏丽 1 +x:1 +赶赴 1 +x:1 +直到 1 +x:1 +赶赶 1 +x:1 +超纯水 1 +x:1 +一反常态 1 +x:1 +由来已久 1 +x:1 +粗制品 1 +x:1 +地税 1 +x:1 +下水管 1 +x:1 +鹭岛 1 +x:1 +刊布 1 +x:1 +羽绒服 1 +x:1 +韩食 1 +x:1 +越棉寮 1 +x:1 +苦熬 1 +x:1 +前后排 1 +x:1 +熬 53 +x:53 +医院法 1 +x:1 +进军 1 +x:1 +用人不疑 1 +x:1 +解救 1 +x:1 +斯人 1 +x:1 +扶危救难 1 +x:1 +有两下子 1 +x:1 +轻轻 1 +x:1 +雾水 1 +x:1 +性命 1 +x:1 +轻轿 1 +x:1 +吉化 1 +x:1 +陆梁 1 +x:1 +腾挪 1 +x:1 +兴安路街 1 +x:1 +解放 1 +x:1 +非营利 1 +x:1 +该段 1 +x:1 +段位差 1 +x:1 +绞 7 +x:7 +军乐团 1 +x:1 +腹鳍 1 +x:1 +地穴 1 +x:1 +鬼神 1 +x:1 +鬼祟 1 +x:1 +历任 1 +x:1 +秘书级 1 +x:1 +发掘地 1 +x:1 +历代 1 +x:1 +公证费 1 +x:1 +慷 5 +x:5 +钨 4 +x:4 +小叶杨 1 +x:1 +鄂西 1 +x:1 +时宜 1 +x:1 +绝缘体 1 +x:1 +饲料粮 1 +x:1 +小到中雨 1 +x:1 +站前 1 +x:1 +理解力 1 +x:1 +设宴 1 +x:1 +党禁 1 +x:1 +发愿 1 +x:1 +血管瘤 1 +x:1 +发愣 1 +x:1 +叉脚 1 +x:1 +发愤 1 +x:1 +谍报员 1 +x:1 +故垒 1 +x:1 +时局 1 +x:1 +设定 1 +x:1 +本科生 1 +x:1 +天姿国色 1 +x:1 +重如泰山 1 +x:1 +时届 1 +x:1 +脱籽 1 +x:1 +怒涛 1 +x:1 +发愁 1 +x:1 +针线包 1 +x:1 +中长期 1 +x:1 +内饰 1 +x:1 +门厅 1 +x:1 +故城 1 +x:1 +玉山 1 +x:1 +问市 1 +x:1 +门号 1 +x:1 +中程 1 +x:1 +依从 1 +x:1 +门口 1 +x:1 +种质型 1 +x:1 +茂名市 1 +x:1 +缺位 1 +x:1 +坟场 1 +x:1 +幕僚 1 +x:1 +扭转 1 +x:1 +时时刻刻 1 +x:1 +安放 1 +x:1 +诗词选 1 +x:1 +坟地 1 +x:1 +皮岛 1 +x:1 +轻装 1 +x:1 +平壤城 1 +x:1 +发慌 1 +x:1 +地覆天翻 1 +x:1 +访问者 1 +x:1 +门区 1 +x:1 +牛角 1 +x:1 +春粮 1 +x:1 +门匾 1 +x:1 +发憷 1 +x:1 +荆棘 1 +x:1 +雕刻件 1 +x:1 +中立 1 +x:1 +五间坊 1 +x:1 +故土 1 +x:1 +俯瞰 1 +x:1 +省略句 1 +x:1 +素养 1 +x:1 +秘书科 1 +x:1 +六亲无靠 1 +x:1 +追随者 1 +x:1 +妞 3 +x:3 +默坐 1 +x:1 +危害 1 +x:1 +娇痴 1 +x:1 +屋宇 1 +x:1 +非卖品 1 +x:1 +刊头 1 +x:1 +施工队 1 +x:1 +立法史 1 +x:1 +旋风 1 +x:1 +素菜馆 1 +x:1 +该法 1 +x:1 +油罐 1 +x:1 +刊大 1 +x:1 +故地 1 +x:1 +封湾 1 +x:1 +蛋形 1 +x:1 +点心纸 1 +x:1 +发懵 1 +x:1 +祉 1 +x:1 +两专一区 1 +x:1 +故址 1 +x:1 +门卫 1 +x:1 +防晒霜 1 +x:1 +情哥哥 1 +x:1 +檀香扇 1 +x:1 +新津县 1 +x:1 +党票 1 +x:1 +磋商 1 +x:1 +布谷鸟 1 +x:1 +站务 1 +x:1 +饱和色 1 +x:1 +打吊针 1 +x:1 +装载机 1 +x:1 +勒紧 1 +x:1 +演唱会 1 +x:1 +血脉相通 1 +x:1 +余韵缭绕 1 +x:1 +点燃 1 +x:1 +印子 1 +x:1 +确立 1 +x:1 +发怵 1 +x:1 +总领事馆 1 +x:1 +绕嘴 1 +x:1 +再而三 1 +x:1 +共享性 1 +x:1 +领土 1 +x:1 +纸币 1 +x:1 +辫子 1 +x:1 +发急 1 +x:1 +片式 1 +x:1 +敲门砖 1 +x:1 +埋设 1 +x:1 +浏河镇 1 +x:1 +领地 1 +x:1 +泰铢 1 +x:1 +发怒 1 +x:1 +谦 75 +x:75 +站卡 1 +x:1 +不为所动 1 +x:1 +南腔北调 1 +x:1 +代收 1 +x:1 +着想 1 +x:1 +吐沙拉乡 1 +x:1 +内项 1 +x:1 +划不来 1 +x:1 +差强人意 1 +x:1 +大法院 1 +x:1 +护身法 1 +x:1 +果能如此 1 +x:1 +正史 1 +x:1 +射手 1 +x:1 +中医系 1 +x:1 +商朝 1 +x:1 +跑冒滴漏 1 +x:1 +书画展 1 +x:1 +自掘坟墓 1 +x:1 +离索 1 +x:1 +有性生殖 1 +x:1 +主厨 1 +x:1 +政调会长 1 +x:1 +耳软心活 1 +x:1 +商服 1 +x:1 +故园 1 +x:1 +皮茄克 1 +x:1 +缺乏 1 +x:1 +负债累累 1 +x:1 +先河 1 +x:1 +棚车 1 +x:1 +贫困线 1 +x:1 +故国 1 +x:1 +呈奉 1 +x:1 +见猎心喜 1 +x:1 +成武县 1 +x:1 +凶多吉少 1 +x:1 +溃决 1 +x:1 +有意者 1 +x:1 +艺 48 +x:48 +辛烷值 1 +x:1 +表里山河 1 +x:1 +用者 1 +x:1 +红帽子 1 +x:1 +胶鞋 1 +x:1 +正义路 1 +x:1 +时差 1 +x:1 +正襟危坐 1 +x:1 +心如刀割 1 +x:1 +陆军省 1 +x:1 +佛释 1 +x:1 +日环食 1 +x:1 +钵池乡 1 +x:1 +怒气 1 +x:1 +夏格庄镇 1 +x:1 +收敛式 1 +x:1 +站口 1 +x:1 +溃入 1 +x:1 +帕米尔 1 +x:1 +完成 1 +x:1 +站台 1 +x:1 +松散状 1 +x:1 +前后文 1 +x:1 +陆源 1 +x:1 +四小龙 1 +x:1 +天鹅洲 1 +x:1 +旖旎 1 +x:1 +领域 1 +x:1 +自由化 1 +x:1 +小崽子 1 +x:1 +成立 1 +x:1 +襄北 1 +x:1 +名片夹 1 +x:1 +偷奸耍滑 1 +x:1 +村村 1 +x:1 +品德课 1 +x:1 +下星期 1 +x:1 +着急 1 +x:1 +怒江 1 +x:1 +导护 1 +x:1 +吊脚楼 1 +x:1 +发情 1 +x:1 +专业队 1 +x:1 +门前 1 +x:1 +追悼会 1 +x:1 +从免 1 +x:1 +闭门不出 1 +x:1 +吉四 1 +x:1 +愤恨 1 +x:1 +供养人 1 +x:1 +论交 1 +x:1 +小学部 1 +x:1 +腕足 1 +x:1 +链轨 1 +x:1 +发挥 1 +x:1 +更新换代 1 +x:1 +唱片 1 +x:1 +纪略 1 +x:1 +旋纽 1 +x:1 +流亡 1 +x:1 +琼林 1 +x:1 +私财 1 +x:1 +封泥 1 +x:1 +论争 1 +x:1 +流产 1 +x:1 +陆海 1 +x:1 +徽菜 1 +x:1 +奠基性 1 +x:1 +褪 12 +x:12 +徽菇 1 +x:1 +涨风 1 +x:1 +屋外 1 +x:1 +兴旺庄村 1 +x:1 +诚朴 1 +x:1 +解惑 1 +x:1 +发行者 1 +x:1 +敷料 1 +x:1 +该港 1 +x:1 +驻马店 1 +x:1 +糖浆 1 +x:1 +莱索托 1 +x:1 +聚集 1 +x:1 +震动力 1 +x:1 +地心说 1 +x:1 +印堂 1 +x:1 +卡钳 1 +x:1 +直贡呢 1 +x:1 +瓢泼大雨 1 +x:1 +保管费 1 +x:1 +快照 1 +x:1 +抱拳礼 1 +x:1 +划痕 1 +x:1 +痛不欲生 1 +x:1 +精品展 1 +x:1 +城建 1 +x:1 +素餐 1 +x:1 +操纵杆 1 +x:1 +孙岗乡 1 +x:1 +失常 1 +x:1 +足联 1 +x:1 +认得 1 +x:1 +食品部 1 +x:1 +愤怒 1 +x:1 +惊讶 1 +x:1 +购机 1 +x:1 +吐纳 1 +x:1 +强行性 1 +x:1 +解恨 1 +x:1 +门儿 1 +x:1 +徐水 1 +x:1 +鲁布革 1 +x:1 +地缘 1 +x:1 +无燃煤区 1 +x:1 +地缆 1 +x:1 +撤并 1 +x:1 +船坚炮利 1 +x:1 +燃耗 1 +x:1 +马达声 1 +x:1 +山丹丹花 1 +x:1 +抢救组 1 +x:1 +发排 1 +x:1 +碑志 1 +x:1 +黑液碱 1 +x:1 +佩剑 1 +x:1 +发掘 1 +x:1 +发牢骚 1 +x:1 +平声 1 +x:1 +天鹅湖 1 +x:1 +迹象 1 +x:1 +一针一线 1 +x:1 +论丛 1 +x:1 +茹 6 +x:6 +流丽 1 +x:1 +设备 1 +x:1 +睁 34 +x:34 +驾机 1 +x:1 +杭城 1 +x:1 +讹谬 1 +x:1 +骨髓炎 1 +x:1 +吐绿 1 +x:1 +代称 1 +x:1 +任满 1 +x:1 +爆裂性 1 +x:1 +春绸 1 +x:1 +衡山路 1 +x:1 +滋长 1 +x:1 +复印员 1 +x:1 +流乞 1 +x:1 +销售部 1 +x:1 +种粮区 1 +x:1 +捕捞 1 +x:1 +西双版纳 1 +x:1 +素馅 1 +x:1 +累加器 1 +x:1 +铬 7 +x:7 +时序 1 +x:1 +吸水性 1 +x:1 +捕捉 1 +x:1 +徐汇 1 +x:1 +横须贺 1 +x:1 +划界 1 +x:1 +佩刀 1 +x:1 +党政纪 1 +x:1 +留水 1 +x:1 +下探 1 +x:1 +富裕村 1 +x:1 +愤慨 1 +x:1 +灵通 1 +x:1 +用色 1 +x:1 +民俗学 1 +x:1 +荸荠 1 +x:1 +横眉怒目 1 +x:1 +神枪手 1 +x:1 +泽及千秋 1 +x:1 +岛上 1 +x:1 +商数 1 +x:1 +胡搅蛮缠 1 +x:1 +樟家乡 1 +x:1 +南联北开 1 +x:1 +闪速炉 1 +x:1 +地线 1 +x:1 +可见光 1 +x:1 +地级 1 +x:1 +红花山 1 +x:1 +核实 1 +x:1 +交货期 1 +x:1 +耗油 1 +x:1 +执收 1 +x:1 +基准点 1 +x:1 +压倒性 1 +x:1 +穿衣镜 1 +x:1 +执政 1 +x:1 +愤愤 1 +x:1 +胴体 1 +x:1 +促进 1 +x:1 +外资局 1 +x:1 +一介书生 1 +x:1 +流俗 1 +x:1 +无米之炊 1 +x:1 +内参 1 +x:1 +申请单 1 +x:1 +发扬 1 +x:1 +脱缰 1 +x:1 +萨伊德 1 +x:1 +雅司病 1 +x:1 +贴心人 1 +x:1 +村旗 1 +x:1 +碑帖 1 +x:1 +饶有兴味 1 +x:1 +夫子庙 1 +x:1 +时弊 1 +x:1 +惟命是从 1 +x:1 +党章 1 +x:1 +时式 1 +x:1 +瞬即 1 +x:1 +因陋就简 1 +x:1 +有求必应 1 +x:1 +泽 14 +x:14 +勃长期 1 +x:1 +粗言秽语 1 +x:1 +豪强 1 +x:1 +大人物 1 +x:1 +着手 1 +x:1 +中秋 1 +x:1 +丑 33 +x:33 +危境 1 +x:1 +发报 1 +x:1 +商旅 1 +x:1 +寸白虫 1 +x:1 +封浜 1 +x:1 +旧物 1 +x:1 +严家岗 1 +x:1 +流传 1 +x:1 +挣 143 +x:143 +发抖 1 +x:1 +子规划 1 +x:1 +灵邱 1 +x:1 +局地 1 +x:1 +框图 1 +x:1 +线性规划 1 +x:1 +彭家 1 +x:1 +高溪村 1 +x:1 +碑廊 1 +x:1 +繁荣期 1 +x:1 +甜甜 1 +x:1 +开价 1 +x:1 +榛子 1 +x:1 +留洋 1 +x:1 +烟波浩淼 1 +x:1 +拖延 1 +x:1 +销售量 1 +x:1 +腾云驾雾 1 +x:1 +仰望 1 +x:1 +马萨西县 1 +x:1 +走私贩私 1 +x:1 +壶中 1 +x:1 +吐翠 1 +x:1 +碑座 1 +x:1 +能源部 1 +x:1 +陆河 1 +x:1 +上机 1 +x:1 +踢球 1 +x:1 +罗斯滕 1 +x:1 +有序化 1 +x:1 +品头论足 1 +x:1 +一九九八 1 +x:1 +赡养费 1 +x:1 +党政群 1 +x:1 +捕手 1 +x:1 +一九九六 1 +x:1 +回龙山畔 1 +x:1 +科教片 1 +x:1 +擎天柱 1 +x:1 +歌行 1 +x:1 +砀 1 +x:1 +闹市区 1 +x:1 +大姨子 1 +x:1 +超人眼 1 +x:1 +故宅 1 +x:1 +危陋平房 1 +x:1 +苍天 1 +x:1 +花边饺 1 +x:1 +不速之客 1 +x:1 +内镜 1 +x:1 +双增长 1 +x:1 +洗脸池 1 +x:1 +故官 1 +x:1 +法官 1 +x:1 +鏖战 1 +x:1 +屋场 1 +x:1 +尧治河 1 +x:1 +祸乱 1 +x:1 +茯苓 1 +x:1 +西北欧 1 +x:1 +步行者队 1 +x:1 +过渡房 1 +x:1 +划算 1 +x:1 +万景台区 1 +x:1 +故宫 1 +x:1 +门徒 1 +x:1 +片刻 1 +x:1 +高比 1 +x:1 +刘庄村 1 +x:1 +环球网 1 +x:1 +三乙醇胺 1 +x:1 +返还金 1 +x:1 +抛荒 1 +x:1 +用费 1 +x:1 +四通桥 1 +x:1 +成功率 1 +x:1 +腹面 1 +x:1 +内销 1 +x:1 +对不对头 1 +x:1 +营业线 1 +x:1 +片剂 1 +x:1 +没头没尾 1 +x:1 +贫困率 1 +x:1 +桂东 1 +x:1 +极贫乡 1 +x:1 +红外技术 1 +x:1 +时值 1 +x:1 +春灌 1 +x:1 +荷枪跃马 1 +x:1 +撒网 1 +x:1 +正义者 1 +x:1 +手艺人 1 +x:1 +狱中 1 +x:1 +救心丹 1 +x:1 +救心丸 1 +x:1 +上会 1 +x:1 +弃瑕录用 1 +x:1 +闸蟹 1 +x:1 +时候 1 +x:1 +料想 1 +x:1 +呀呀 1 +x:1 +妇道 1 +x:1 +士多店 1 +x:1 +庆云 1 +x:1 +磋商会 1 +x:1 +搀和 1 +x:1 +设在 1 +x:1 +凛冽 1 +x:1 +锡永 1 +x:1 +发涨 1 +x:1 +歧化酶 1 +x:1 +门诊量 1 +x:1 +嫌弃 1 +x:1 +阳雀 1 +x:1 +锑矿石 1 +x:1 +负债感 1 +x:1 +立传 1 +x:1 +中直 1 +x:1 +扭获 1 +x:1 +色 107 +x:107 +吉岗村 1 +x:1 +纷飞 1 +x:1 +疑神疑鬼 1 +x:1 +可见度 1 +x:1 +军民品 1 +x:1 +野蔬 1 +x:1 +同行业 1 +x:1 +浅水区 1 +x:1 +哈 221 +x:221 +哮喘 1 +x:1 +助兴 1 +x:1 +应聘卡 1 +x:1 +审查率 1 +x:1 +耗损 1 +x:1 +留成 1 +x:1 +闹市口 1 +x:1 +永年 1 +x:1 +解渴 1 +x:1 +祸事 1 +x:1 +个人主义 1 +x:1 +外资司 1 +x:1 +受人牵制 1 +x:1 +抵赖 1 +x:1 +毛渠 1 +x:1 +任情 1 +x:1 +崇敬感 1 +x:1 +影调剧 1 +x:1 +彬县 1 +x:1 +联影业 1 +x:1 +谋面 1 +x:1 +朗海村 1 +x:1 +发水 1 +x:1 +地炕 1 +x:1 +钉 31 +x:31 +托老 1 +x:1 +踩踩 1 +x:1 +冤枉路 1 +x:1 +撤出 1 +x:1 +换钱 1 +x:1 +促膝 1 +x:1 +门庭 1 +x:1 +聚首 1 +x:1 +地炉 1 +x:1 +永德 1 +x:1 +天师 1 +x:1 +时光 1 +x:1 +地点 1 +x:1 +门店 1 +x:1 +食物谱 1 +x:1 +相形之下 1 +x:1 +胸痛 1 +x:1 +多瑙河 1 +x:1 +轻薄 1 +x:1 +任意 1 +x:1 +糖房 1 +x:1 +领子 1 +x:1 +背心 1 +x:1 +种蝎场 1 +x:1 +鲜亮亮 1 +x:1 +基准线 1 +x:1 +完满 1 +x:1 +陆战 1 +x:1 +签证费 1 +x:1 +房产证 1 +x:1 +精炼铜 1 +x:1 +中看 1 +x:1 +精雅细巧 1 +x:1 +日用品 1 +x:1 +宿营 1 +x:1 +伸直 1 +x:1 +灵鹿 1 +x:1 +咎由自取 1 +x:1 +汗流浃背 1 +x:1 +发汗 1 +x:1 +事随时变 1 +x:1 +门廊 1 +x:1 +兰 111 +x:111 +撤军 1 +x:1 +纪程 1 +x:1 +豆腐脑 1 +x:1 +珍藏品 1 +x:1 +核查员 1 +x:1 +含绒率 1 +x:1 +香附子 1 +x:1 +地热 1 +x:1 +师范大学 1 +x:1 +问及 1 +x:1 +约旦 1 +x:1 +讨好 1 +x:1 +吉 214 +x:214 +有为 1 +x:1 +刊名 1 +x:1 +抒 11 +x:11 +轮作 1 +x:1 +贫困片 1 +x:1 +野葱 1 +x:1 +撤兵 1 +x:1 +聚餐 1 +x:1 +决一胜负 1 +x:1 +门帘 1 +x:1 +等差 1 +x:1 +铮铮 1 +x:1 +素雅 1 +x:1 +中短 1 +x:1 +人机会话 1 +x:1 +问句 1 +x:1 +愤激 1 +x:1 +准军事 1 +x:1 +野葛 1 +x:1 +阵 51 +x:51 +短笛 1 +x:1 +中石 1 +x:1 +门市 1 +x:1 +校经楼 1 +x:1 +问号 1 +x:1 +针刺 1 +x:1 +天干 1 +x:1 +立法委员 1 +x:1 +记大过 1 +x:1 +豪兴 1 +x:1 +野营 1 +x:1 +有何不可 1 +x:1 +发泡 1 +x:1 +上来 1 +x:1 +驾校 1 +x:1 +沿循 1 +x:1 +话剧界 1 +x:1 +危困 1 +x:1 +朝廷 1 +x:1 +惦 4 +x:4 +领导 1 +x:1 +风光片 1 +x:1 +医教研 1 +x:1 +柳河 1 +x:1 +牛蒡 1 +x:1 +发泄 1 +x:1 +徽调 1 +x:1 +春燕 1 +x:1 +地火 1 +x:1 +高氧水 1 +x:1 +专署 1 +x:1 +蛏子 1 +x:1 +框子 1 +x:1 +认可 1 +x:1 +人劳处长 1 +x:1 +王石凹矿 1 +x:1 +兜圈子 1 +x:1 +留情 1 +x:1 +要职 1 +x:1 +啧啧称奇 1 +x:1 +小巧玲珑 1 +x:1 +牛蝇 1 +x:1 +帘 4 +x:4 +用车 1 +x:1 +开拓性 1 +x:1 +章节 1 +x:1 +幕府 1 +x:1 +蚊蝇 1 +x:1 +射洪 1 +x:1 +蒙特雷市 1 +x:1 +该所 1 +x:1 +客货港 1 +x:1 +百老汇街 1 +x:1 +虎字头儿 1 +x:1 +过渡性 1 +x:1 +解法 1 +x:1 +舒柔 1 +x:1 +奂 1 +x:1 +会城镇 1 +x:1 +石景山区 1 +x:1 +川东 1 +x:1 +慎之又慎 1 +x:1 +反季节 1 +x:1 +立眉瞪眼 1 +x:1 +射流 1 +x:1 +问候 1 +x:1 +该房 1 +x:1 +商标 1 +x:1 +该户 1 +x:1 +时刻 1 +x:1 +发潮 1 +x:1 +蒙蒙 1 +x:1 +名牌群 1 +x:1 +坟头 1 +x:1 +姜湾村 1 +x:1 +商校 1 +x:1 +陪同团 1 +x:1 +川中 1 +x:1 +计票员 1 +x:1 +乡宁县 1 +x:1 +昆明湖 1 +x:1 +留恋 1 +x:1 +宁化县 1 +x:1 +灞桥区 1 +x:1 +下令 1 +x:1 +没关系 1 +x:1 +琼山市 1 +x:1 +村校 1 +x:1 +列编 1 +x:1 +印品 1 +x:1 +长中短篇 1 +x:1 +监督权案 1 +x:1 +购毒 1 +x:1 +下任 1 +x:1 +应用量 1 +x:1 +造谣惑众 1 +x:1 +安邦富民 1 +x:1 +伯南布哥 1 +x:1 +性 26 +x:26 +纸口袋 1 +x:1 +全面性 1 +x:1 +入土为安 1 +x:1 +眷眷之情 1 +x:1 +面面相觑 1 +x:1 +漫长 1 +x:1 +幕布 1 +x:1 +老粗儿 1 +x:1 +时务 1 +x:1 +碳塑纤维 1 +x:1 +或者 1 +x:1 +该报 1 +x:1 +族谱 1 +x:1 +纸板箱 1 +x:1 +埋葬 1 +x:1 +内蒙古团 1 +x:1 +惆怅 1 +x:1 +下人 1 +x:1 +蛐蛐儿 1 +x:1 +鬼火 1 +x:1 +站岗 1 +x:1 +佩带 1 +x:1 +沫儿 1 +x:1 +私自 1 +x:1 +晋城 1 +x:1 +喧宾夺主 1 +x:1 +伸畅 1 +x:1 +横空出世 1 +x:1 +知府 1 +x:1 +唱红 1 +x:1 +知底 1 +x:1 +按兵不动 1 +x:1 +落实率 1 +x:1 +乌珠石 1 +x:1 +骁 1 +x:1 +铲子 1 +x:1 +野蛮 1 +x:1 +发行费 1 +x:1 +内陆 1 +x:1 +钥匙环 1 +x:1 +中华草龟 1 +x:1 +工商业户 1 +x:1 +泰晤士河 1 +x:1 +信宜 1 +x:1 +全托制 1 +x:1 +似仙非仙 1 +x:1 +立法局 1 +x:1 +领头 1 +x:1 +技术部 1 +x:1 +牛虻 1 +x:1 +领夹 1 +x:1 +下低 1 +x:1 +下位 1 +x:1 +临河乡 1 +x:1 +下体 1 +x:1 +刀把 1 +x:1 +油烟 1 +x:1 +磷钾肥 1 +x:1 +凯旋门 1 +x:1 +擞 1 +x:1 +火星车 1 +x:1 +紫黑色 1 +x:1 +方面军 1 +x:1 +现阶段 1 +x:1 +蒿草 1 +x:1 +领奖 1 +x:1 +灯海火市 1 +x:1 +碑刻 1 +x:1 +七九年 1 +x:1 +内阁 1 +x:1 +积聚型 1 +x:1 +吉安 1 +x:1 +旧约 1 +x:1 +棉织品 1 +x:1 +铁厂沟镇 1 +x:1 +彗星 1 +x:1 +坟堆 1 +x:1 +叛 1 +x:1 +言归正传 1 +x:1 +不约而同 1 +x:1 +地狱 1 +x:1 +惊人 1 +x:1 +杨 1834 +x:1834 +霍利节 1 +x:1 +埋藏 1 +x:1 +中用 1 +x:1 +褒义词 1 +x:1 +永州 1 +x:1 +内阻 1 +x:1 +木乃伊 1 +x:1 +川贝母 1 +x:1 +江阴市 1 +x:1 +大正六年 1 +x:1 +吊脚柱 1 +x:1 +剧团 1 +x:1 +威 33 +x:33 +濒海 1 +x:1 +油灯 1 +x:1 +叽叽唧唧 1 +x:1 +牛蛙 1 +x:1 +义务人 1 +x:1 +含饴弄孙 1 +x:1 +先手 1 +x:1 +换防 1 +x:1 +磅 6 +x:6 +岚 10 +x:10 +毒瓦斯 1 +x:1 +农行奖 1 +x:1 +私股 1 +x:1 +发源 1 +x:1 +囚室 1 +x:1 +合欢花 1 +x:1 +知心 1 +x:1 +项目组 1 +x:1 +峨眉 1 +x:1 +溢出 1 +x:1 +传呼电话 1 +x:1 +门封 1 +x:1 +耽 1 +x:1 +核查团 1 +x:1 +岚皋 1 +x:1 +佛龛 1 +x:1 +观摩者 1 +x:1 +坟墓 1 +x:1 +工矿企业 1 +x:1 +内障 1 +x:1 +舒兰市 1 +x:1 +印刷术 1 +x:1 +垂线足 1 +x:1 +晋国 1 +x:1 +天府 1 +x:1 +点点 1 +x:1 +舅父 1 +x:1 +商榷 1 +x:1 +湘绣 1 +x:1 +章草 1 +x:1 +医疗界 1 +x:1 +地牢 1 +x:1 +豪华 1 +x:1 +内难 1 +x:1 +无息贷款 1 +x:1 +楷 6 +x:6 +行赏 1 +x:1 +技工贸 1 +x:1 +地物 1 +x:1 +燃起 1 +x:1 +扼守 1 +x:1 +体育运动 1 +x:1 +境 35 +x:35 +段位制 1 +x:1 +传记类 1 +x:1 +裤褂 1 +x:1 +怒斥 1 +x:1 +屈从 1 +x:1 +棉织厂 1 +x:1 +油矿 1 +x:1 +油石 1 +x:1 +次于 1 +x:1 +滥印 1 +x:1 +仰泳 1 +x:1 +草裙舞 1 +x:1 +幕墙 1 +x:1 +信用联社 1 +x:1 +治疗法 1 +x:1 +廊柱 1 +x:1 +产品化 1 +x:1 +巡捕 1 +x:1 +领带 1 +x:1 +胆壮山河 1 +x:1 +绕开 1 +x:1 +制皂厂 1 +x:1 +门对 1 +x:1 +连苍接翠 1 +x:1 +搀假 1 +x:1 +狠心 1 +x:1 +侠骨 1 +x:1 +半 993 +x:993 +地痞 1 +x:1 +兑现率 1 +x:1 +大歌剧 1 +x:1 +兔皮 1 +x:1 +舒服 1 +x:1 +坦陈己见 1 +x:1 +弹簧门 1 +x:1 +粗略 1 +x:1 +灵魂 1 +x:1 +夜不出户 1 +x:1 +蓬门荜户 1 +x:1 +印制 1 +x:1 +印刷 1 +x:1 +刊出 1 +x:1 +独一性 1 +x:1 +亲如弟兄 1 +x:1 +版权司 1 +x:1 +小妞 1 +x:1 +发楞 1 +x:1 +孚日山 1 +x:1 +赶 228 +x:228 +怒族 1 +x:1 +话剧热 1 +x:1 +商港 1 +x:1 +内里 1 +x:1 +攻关组 1 +x:1 +反光 1 +x:1 +怒放 1 +x:1 +凉丝丝 1 +x:1 +政府部门 1 +x:1 +作奸犯科 1 +x:1 +空港 1 +x:1 +团脐 1 +x:1 +外资型 1 +x:1 +糖果 1 +x:1 +期市 1 +x:1 +课题费 1 +x:1 +发榜 1 +x:1 +判若天壤 1 +x:1 +举重队 1 +x:1 +滥发 1 +x:1 +琼海 1 +x:1 +下海者 1 +x:1 +暗影 1 +x:1 +红旗岗 1 +x:1 +亲英派 1 +x:1 +黄粱美梦 1 +x:1 +缅怀 1 +x:1 +卷起 1 +x:1 +尽享清福 1 +x:1 +耗材 1 +x:1 +轿车 1 +x:1 +危及 1 +x:1 +蛏干 1 +x:1 +地界 1 +x:1 +葫芦蔓 1 +x:1 +陶范 1 +x:1 +陆架 1 +x:1 +性子 1 +x:1 +众学生 1 +x:1 +评级 1 +x:1 +门子 1 +x:1 +长白山区 1 +x:1 +万博省 1 +x:1 +琼浆 1 +x:1 +金湖县 1 +x:1 +辽远 1 +x:1 +间谍案 1 +x:1 +怎么得了 1 +x:1 +宪制性 1 +x:1 +药剂拌种 1 +x:1 +慧中北里 1 +x:1 +过渡期 1 +x:1 +购汇 1 +x:1 +拖油瓶 1 +x:1 +国学家 1 +x:1 +抛物面 1 +x:1 +划线 1 +x:1 +结核菌 1 +x:1 +点火 1 +x:1 +枢纽 1 +x:1 +优质稻 1 +x:1 +期待 1 +x:1 +讨巧 1 +x:1 +料斗 1 +x:1 +没 1716 +x:1716 +永安 1 +x:1 +酸式盐 1 +x:1 +萦 1 +x:1 +走兽 1 +x:1 +拱北石 1 +x:1 +毛毡 1 +x:1 +入选者 1 +x:1 +灵邱县 1 +x:1 +走入 1 +x:1 +唱票 1 +x:1 +用血 1 +x:1 +鞍前马后 1 +x:1 +军代表 1 +x:1 +商潮 1 +x:1 +在所难免 1 +x:1 +商演 1 +x:1 +防撬门 1 +x:1 +批转交办 1 +x:1 +暖锋 1 +x:1 +内退 1 +x:1 +地瓜 1 +x:1 +想法 1 +x:1 +前堵后追 1 +x:1 +苍山 1 +x:1 +公约数 1 +x:1 +月下老人 1 +x:1 +牛耳 1 +x:1 +灵驾 1 +x:1 +歪打正着 1 +x:1 +三里屯 1 +x:1 +任教 1 +x:1 +屋前 1 +x:1 +名片册 1 +x:1 +组织科学 1 +x:1 +洪泽县 1 +x:1 +机动车 1 +x:1 +主客观 1 +x:1 +发案 1 +x:1 +上辈人 1 +x:1 +碑名 1 +x:1 +失效率 1 +x:1 +封杀 1 +x:1 +多性 1 +x:1 +饲料用 1 +x:1 +苍岭 1 +x:1 +削平 1 +x:1 +社会部 1 +x:1 +苍岩 1 +x:1 +濒死 1 +x:1 +地球 1 +x:1 +发梢 1 +x:1 +地理 1 +x:1 +享乐主义 1 +x:1 +7 1025 +x:1025 +无耻之徒 1 +x:1 +陶艺 1 +x:1 +袒胸露臂 1 +x:1 +宁冈县 1 +x:1 +履坦镇 1 +x:1 +封条 1 +x:1 +印台 1 +x:1 +亢 13 +x:13 +坚苦 1 +x:1 +内部 1 +x:1 +出口权 1 +x:1 +中班 1 +x:1 +贪赃枉法 1 +x:1 +香槟酒 1 +x:1 +车公庄 1 +x:1 +铲工 1 +x:1 +辽中县 1 +x:1 +宽于待人 1 +x:1 +平壤市 1 +x:1 +厂籍 1 +x:1 +造册 1 +x:1 +海平线 1 +x:1 +留有 1 +x:1 +纳税者 1 +x:1 +巡护 1 +x:1 +湍 1 +x:1 +桐子 1 +x:1 +内贸部 1 +x:1 +原则层 1 +x:1 +印厂 1 +x:1 +蜡台 1 +x:1 +蜡叶 1 +x:1 +呆账率 1 +x:1 +牛肉 1 +x:1 +认同 1 +x:1 +徐村 1 +x:1 +倒闭年 1 +x:1 +贸易业 1 +x:1 +列确 1 +x:1 +圆周率 1 +x:1 +五指耙 1 +x:1 +气势汹汹 1 +x:1 +百股胜和 1 +x:1 +站容 1 +x:1 +不合时宜 1 +x:1 +稠油田 1 +x:1 +粉笔字 1 +x:1 +豪商 1 +x:1 +巡抚 1 +x:1 +朝夕 1 +x:1 +罄竹难书 1 +x:1 +朝外 1 +x:1 +小河子村 1 +x:1 +薪金 1 +x:1 +相似性 1 +x:1 +击伤 1 +x:1 +枣阳 1 +x:1 +片名 1 +x:1 +功在千秋 1 +x:1 +山茶花 1 +x:1 +颈内 1 +x:1 +大洞尺五 1 +x:1 +清河村 1 +x:1 +撤回 1 +x:1 +春瘟 1 +x:1 +甲 47 +x:47 +晋北 1 +x:1 +硫化物质 1 +x:1 +宿草 1 +x:1 +蠕虫状 1 +x:1 +未能免俗 1 +x:1 +恒齿 1 +x:1 +徽记 1 +x:1 +刊发 1 +x:1 +可利用率 1 +x:1 +掌骨 1 +x:1 +甘霖 1 +x:1 +该当何论 1 +x:1 +吉庆 1 +x:1 +有去无归 1 +x:1 +晋升 1 +x:1 +针线活儿 1 +x:1 +方位词 1 +x:1 +刊号 1 +x:1 +地矿 1 +x:1 +孤雌生殖 1 +x:1 +成熟度 1 +x:1 +哈拉伊卜 1 +x:1 +晋南 1 +x:1 +甘露 1 +x:1 +内丘县 1 +x:1 +常青树 1 +x:1 +奴颜婢膝 1 +x:1 +五四年 1 +x:1 +商法 1 +x:1 +略略 1 +x:1 +碑基 1 +x:1 +戍守 1 +x:1 +毛桃 1 +x:1 +销售额 1 +x:1 +用语 1 +x:1 +糖料 1 +x:1 +想像力 1 +x:1 +膂力 1 +x:1 +村民 1 +x:1 +野草 1 +x:1 +执法 1 +x:1 +脱盲 1 +x:1 +生产能力 1 +x:1 +门外 1 +x:1 +瑁洲 1 +x:1 +有意识 1 +x:1 +斗争会 1 +x:1 +妙曼 1 +x:1 +街上 1 +x:1 +脚腕子 1 +x:1 +毛栗 1 +x:1 +先期 1 +x:1 +娇羞 1 +x:1 +三足乌 1 +x:1 +私藏 1 +x:1 +贫困生 1 +x:1 +油画 1 +x:1 +卷轴 1 +x:1 +娇美 1 +x:1 +发放点 1 +x:1 +先机 1 +x:1 +方丈 1 +x:1 +赶考 1 +x:1 +毛样 1 +x:1 +负债村 1 +x:1 +发毛 1 +x:1 +鸣金收兵 1 +x:1 +刊印 1 +x:1 +埃德蒙顿 1 +x:1 +二道贩子 1 +x:1 +邓选 1 +x:1 +撒种 1 +x:1 +走动 1 +x:1 +沉淀物 1 +x:1 +中点 1 +x:1 +枝繁花茂 1 +x:1 +脱皮 1 +x:1 +拉脱维亚 1 +x:1 +喇 1 +x:1 +渔船 1 +x:1 +校舍 1 +x:1 +救灾粮 1 +x:1 +逐字逐句 1 +x:1 +双周刊 1 +x:1 +商流 1 +x:1 +玉溪市 1 +x:1 +阳韵 1 +x:1 +击中 1 +x:1 +介绍员 1 +x:1 +渔舟 1 +x:1 +门墙 1 +x:1 +私营 1 +x:1 +商海 1 +x:1 +机动费 1 +x:1 +顺之者 1 +x:1 +德籍 1 +x:1 +傲岸 1 +x:1 +坟山 1 +x:1 +技术链 1 +x:1 +两杂一薯 1 +x:1 +验证员 1 +x:1 +地皮 1 +x:1 +风云际会 1 +x:1 +晋剧 1 +x:1 +不容置疑 1 +x:1 +地盘 1 +x:1 +商洛 1 +x:1 +春睡 1 +x:1 +方便 1 +x:1 +该机 1 +x:1 +大茴香 1 +x:1 +荐骨 1 +x:1 +物价指数 1 +x:1 +盛名难负 1 +x:1 +蛋品 1 +x:1 +中焦 1 +x:1 +发病率 1 +x:1 +地直 1 +x:1 +五五年 1 +x:1 +佳音频传 1 +x:1 +着魔 1 +x:1 +因企制宜 1 +x:1 +地盾 1 +x:1 +商洽 1 +x:1 +动检站 1 +x:1 +马场坪 1 +x:1 +气阀 1 +x:1 +交响诗 1 +x:1 +乖僻 1 +x:1 +工农联盟 1 +x:1 +音美 1 +x:1 +离石 1 +x:1 +千古功臣 1 +x:1 +结完婚 1 +x:1 +慰问款 1 +x:1 +了无踪迹 1 +x:1 +炊 1 +x:1 +身体力行 1 +x:1 +漫道 1 +x:1 +工业型 1 +x:1 +白水江 1 +x:1 +东胜市 1 +x:1 +流放地 1 +x:1 +临时性 1 +x:1 +印花法 1 +x:1 +宁陵县 1 +x:1 +陈官乡 1 +x:1 +世纪钟 1 +x:1 +永夏 1 +x:1 +醇厚 1 +x:1 +局内 1 +x:1 +影碟机 1 +x:1 +成龙配套 1 +x:1 +与会 1 +x:1 +鲷科 1 +x:1 +结合部 1 +x:1 +煽动性 1 +x:1 +彭县 1 +x:1 +永外 1 +x:1 +养蟹 1 +x:1 +交相为用 1 +x:1 +腹部 1 +x:1 +私蓄 1 +x:1 +集 361 +x:361 +故居 1 +x:1 +印军 1 +x:1 +访问记 1 +x:1 +傲居 1 +x:1 +轻荡 1 +x:1 +恕 18 +x:18 +溯根求源 1 +x:1 +孩子气 1 +x:1 +课征 1 +x:1 +黄洋界 1 +x:1 +耿耿于怀 1 +x:1 +长管状 1 +x:1 +拾金不昧 1 +x:1 +佳酿 1 +x:1 +造血型 1 +x:1 +领巾 1 +x:1 +化疗药 1 +x:1 +先是 1 +x:1 +诸 135 +x:135 +暖暖的 1 +x:1 +领工员 1 +x:1 +略语 1 +x:1 +耀 30 +x:30 +寓邸 1 +x:1 +购配 1 +x:1 +卸甲庄 1 +x:1 +眉来眼去 1 +x:1 +该项 1 +x:1 +毛集 1 +x:1 +略读 1 +x:1 +农林牧渔 1 +x:1 +亟 16 +x:16 +劈山 1 +x:1 +青伊湖 1 +x:1 +荣国府 1 +x:1 +灵机 1 +x:1 +钦州港 1 +x:1 +文曲星 1 +x:1 +英俊 1 +x:1 +事务部 1 +x:1 +解雇 1 +x:1 +兴衰存亡 1 +x:1 +鞋材 1 +x:1 +产后 1 +x:1 +内海 1 +x:1 +户籍室 1 +x:1 +线 488 +x:488 +地角 1 +x:1 +鱼肝油 1 +x:1 +愧不可当 1 +x:1 +凄怆 1 +x:1 +牌 191 +x:191 +辎车 1 +x:1 +用电 1 +x:1 +拒斥 1 +x:1 +用用 1 +x:1 +月虹 1 +x:1 +横断山脉 1 +x:1 +略论 1 +x:1 +区位 1 +x:1 +群防群治 1 +x:1 +一连串 1 +x:1 +科坛 1 +x:1 +前后道 1 +x:1 +伸进 1 +x:1 +吐血 1 +x:1 +改革史 1 +x:1 +卡折 1 +x:1 +见面会 1 +x:1 +筏子 1 +x:1 +极品 1 +x:1 +呆若木鸡 1 +x:1 +托福 1 +x:1 +妓女 1 +x:1 +五毒 1 +x:1 +感应电流 1 +x:1 +看轻 1 +x:1 +丙璜舒 1 +x:1 +活报剧 1 +x:1 +暖棚 1 +x:1 +褐棕色 1 +x:1 +点位 1 +x:1 +三不主义 1 +x:1 +擦鞋嫂 1 +x:1 +岗位数 1 +x:1 +试点县 1 +x:1 +陶罐 1 +x:1 +留驻 1 +x:1 +换洗 1 +x:1 +党费 1 +x:1 +国籍法 1 +x:1 +虚假性 1 +x:1 +拒收 1 +x:1 +长岭岗乡 1 +x:1 +长春站 1 +x:1 +制成品 1 +x:1 +攸关 1 +x:1 +发问 1 +x:1 +降幅 1 +x:1 +无轨电车 1 +x:1 +降幂 1 +x:1 +漫漫 1 +x:1 +涌水量 1 +x:1 +种法 1 +x:1 +风机厂 1 +x:1 +毒性 1 +x:1 +灵柩 1 +x:1 +滴 72 +x:72 +产品 1 +x:1 +内涵 1 +x:1 +惶恐滩 1 +x:1 +科城 1 +x:1 +掠夺式 1 +x:1 +秦南镇 1 +x:1 +划花 1 +x:1 +加以 1 +x:1 +沉 59 +x:59 +佛教 1 +x:1 +鹰鹞 1 +x:1 +调委会 1 +x:1 +并日而食 1 +x:1 +余 2289 +x:2289 +内江 1 +x:1 +加价 1 +x:1 +怖 2 +x:2 +枣椰 1 +x:1 +誊写版 1 +x:1 +中车 1 +x:1 +唐海县 1 +x:1 +奏者 1 +x:1 +负债额 1 +x:1 +加仑 1 +x:1 +本科者 1 +x:1 +离 576 +x:576 +射阳 1 +x:1 +朱笔 1 +x:1 +方向性 1 +x:1 +银河系 1 +x:1 +精湛不磨 1 +x:1 +泡沫式 1 +x:1 +稀罕物 1 +x:1 +皲裂 1 +x:1 +吉布提 1 +x:1 +树立 1 +x:1 +经济圈 1 +x:1 +鬼话 1 +x:1 +口腹 1 +x:1 +俄罗斯族 1 +x:1 +概数 1 +x:1 +即景生情 1 +x:1 +卷烟 1 +x:1 +内水 1 +x:1 +阳起石 1 +x:1 +旅团长 1 +x:1 +灌木丛 1 +x:1 +狰狞 1 +x:1 +诚邀 1 +x:1 +划船 1 +x:1 +戎马一生 1 +x:1 +涨潮 1 +x:1 +蓟镇 1 +x:1 +中远 1 +x:1 +超一流 1 +x:1 +节度使 1 +x:1 +自相矛盾 1 +x:1 +无会月 1 +x:1 +轩敞 1 +x:1 +加之 1 +x:1 +一怀愁绪 1 +x:1 +下岗族 1 +x:1 +房院 1 +x:1 +腹足类 1 +x:1 +中心区 1 +x:1 +丝虫病 1 +x:1 +漫湾 1 +x:1 +拉起呱来 1 +x:1 +安平县 1 +x:1 +小肚子 1 +x:1 +禀赋 1 +x:1 +私立 1 +x:1 +视频流 1 +x:1 +健全率 1 +x:1 +预制板 1 +x:1 +滋扰 1 +x:1 +清风店 1 +x:1 +玉树 1 +x:1 +北方佬 1 +x:1 +专业户 1 +x:1 +命令句 1 +x:1 +私章 1 +x:1 +柳州 1 +x:1 +换汇 1 +x:1 +雅各宾派 1 +x:1 +加上 1 +x:1 +该馆 1 +x:1 +主导型 1 +x:1 +地衣 1 +x:1 +划艇 1 +x:1 +中辽 1 +x:1 +牛粪 1 +x:1 +地表 1 +x:1 +漫游 1 +x:1 +昌盛 1 +x:1 +内河 1 +x:1 +寡头 1 +x:1 +安居乐业 1 +x:1 +帽顶 1 +x:1 +瑶寨 1 +x:1 +轻纺 1 +x:1 +纷扬 1 +x:1 +见风转舵 1 +x:1 +自卑感 1 +x:1 +偃师 1 +x:1 +二道河 1 +x:1 +评聘 1 +x:1 +纷扰 1 +x:1 +沙矶头村 1 +x:1 +谋求 1 +x:1 +氧气包 1 +x:1 +素昧平生 1 +x:1 +得名 1 +x:1 +木菠萝 1 +x:1 +府绸 1 +x:1 +治愈率 1 +x:1 +发霉 1 +x:1 +范式 1 +x:1 +盆底 1 +x:1 +党政机关 1 +x:1 +廊首 1 +x:1 +安检站 1 +x:1 +领军人 1 +x:1 +灵敏 1 +x:1 +发面 1 +x:1 +魄力 1 +x:1 +瑶家 1 +x:1 +承债式 1 +x:1 +弛懈 1 +x:1 +慎始敬终 1 +x:1 +素洁 1 +x:1 +聚拢 1 +x:1 +渔网 1 +x:1 +舞动 1 +x:1 +推动力 1 +x:1 +糖饴 1 +x:1 +农林水 1 +x:1 +夙兴夜寐 1 +x:1 +出口额 1 +x:1 +晓庄 1 +x:1 +纷拥 1 +x:1 +素淡 1 +x:1 +三花脸 1 +x:1 +瑶学 1 +x:1 +舞剑 1 +x:1 +逆来顺受 1 +x:1 +敌对者 1 +x:1 +荣辱感 1 +x:1 +捉刀 1 +x:1 +踢腿 1 +x:1 +蓬莱阁 1 +x:1 +双组元 1 +x:1 +氧气厂 1 +x:1 +倡导国 1 +x:1 +江家场村 1 +x:1 +春潮秋闹 1 +x:1 +说白了 1 +x:1 +高才高学 1 +x:1 +弩 4 +x:4 +章程 1 +x:1 +托管 1 +x:1 +商都 1 +x:1 +应和 1 +x:1 +种源 1 +x:1 +封顶 1 +x:1 +歙砚师 1 +x:1 +加碘盐 1 +x:1 +自办厂 1 +x:1 +舞剧 1 +x:1 +发音 1 +x:1 +懂 292 +x:292 +纷披 1 +x:1 +返还款 1 +x:1 +可溶性 1 +x:1 +舞刀 1 +x:1 +珠江口 1 +x:1 +协商团 1 +x:1 +曲径 1 +x:1 +癣 2 +x:2 +射门 1 +x:1 +稀泥 1 +x:1 +城墙史 1 +x:1 +商标法 1 +x:1 +返老还童 1 +x:1 +鹿角菜 1 +x:1 +打照面 1 +x:1 +下雨天 1 +x:1 +点将台 1 +x:1 +心慌意乱 1 +x:1 +牛群 1 +x:1 +客运员 1 +x:1 +轩昂 1 +x:1 +内径 1 +x:1 +中资 1 +x:1 +烈火 1 +x:1 +产地 1 +x:1 +撒落 1 +x:1 +休止符 1 +x:1 +嘎 3 +x:3 +解闷 1 +x:1 +完钻 1 +x:1 +娇艳 1 +x:1 +池上 1 +x:1 +围观者 1 +x:1 +常青镇 1 +x:1 +油裙 1 +x:1 +澳 290 +x:290 +怒骂 1 +x:1 +算尺 1 +x:1 +弃婴 1 +x:1 +无会旬 1 +x:1 +斜井 1 +x:1 +评功摆好 1 +x:1 +坏死症 1 +x:1 +取信 1 +x:1 +极圈 1 +x:1 +维和 1 +x:1 +淡水井 1 +x:1 +先验 1 +x:1 +泾渭不分 1 +x:1 +热带鱼 1 +x:1 +舞厅 1 +x:1 +茄子 1 +x:1 +笑嘻嘻 1 +x:1 +内窥镜 1 +x:1 +话剧迷 1 +x:1 +恶狠狠 1 +x:1 +科员 1 +x:1 +夏都 1 +x:1 +极地 1 +x:1 +陶粒 1 +x:1 +殿下 1 +x:1 +出海口 1 +x:1 +一鼓作气 1 +x:1 +廉耻感 1 +x:1 +监理制 1 +x:1 +村野 1 +x:1 +油表 1 +x:1 +大一统 1 +x:1 +着陆 1 +x:1 +结合法 1 +x:1 +农工党 1 +x:1 +成品率 1 +x:1 +发难 1 +x:1 +夜风 1 +x:1 +航线 1 +x:1 +纵览 1 +x:1 +准确无误 1 +x:1 +愤闷 1 +x:1 +商量 1 +x:1 +燃用 1 +x:1 +米洛斯岛 1 +x:1 +疤 4 +x:4 +康庄镇 1 +x:1 +压腿 1 +x:1 +中路 1 +x:1 +此物 1 +x:1 +户兰村 1 +x:1 +气象系 1 +x:1 +销售方 1 +x:1 +腹沟 1 +x:1 +钢丝床 1 +x:1 +无放射性 1 +x:1 +脱误 1 +x:1 +好人好事 1 +x:1 +赶紧 1 +x:1 +代代相承 1 +x:1 +故事集 1 +x:1 +专业性 1 +x:1 +腹泻 1 +x:1 +创见性 1 +x:1 +德育 1 +x:1 +怒马 1 +x:1 +轻罪 1 +x:1 +素油 1 +x:1 +糖食 1 +x:1 +丢卒保车 1 +x:1 +知恩图报 1 +x:1 +制糖术 1 +x:1 +酷 2 +x:2 +春试 1 +x:1 +奋起 1 +x:1 +吐诉 1 +x:1 +谬种流传 1 +x:1 +并吞 1 +x:1 +抨击 1 +x:1 +确诊 1 +x:1 +蒸汽轮机 1 +x:1 +可视性 1 +x:1 +确证 1 +x:1 +产值 1 +x:1 +意象 1 +x:1 +着重 1 +x:1 +瓜皮帽 1 +x:1 +寒冬 1 +x:1 +相生相克 1 +x:1 +草木犀 1 +x:1 +终审制 1 +x:1 +吉林团 1 +x:1 +筏式 1 +x:1 +累见不鲜 1 +x:1 +屯溪 1 +x:1 +驶过 1 +x:1 +归真村 1 +x:1 +并发 1 +x:1 +晶体 1 +x:1 +种树 1 +x:1 +前移 1 +x:1 +养分 1 +x:1 +陶管 1 +x:1 +离谱 1 +x:1 +发酵 1 +x:1 +购销 1 +x:1 +甘洌 1 +x:1 +党规 1 +x:1 +仓储费 1 +x:1 +谷家峪村 1 +x:1 +艳诗 1 +x:1 +力作 1 +x:1 +甘洛 1 +x:1 +暖气 1 +x:1 +野禽 1 +x:1 +真情实感 1 +x:1 +链索 1 +x:1 +第三世界 1 +x:1 +脸上无光 1 +x:1 +算学 1 +x:1 +风筝节 1 +x:1 +秩 2 +x:2 +确认 1 +x:1 +虎头蛇尾 1 +x:1 +韧皮纤维 1 +x:1 +产假 1 +x:1 +宝塔形 1 +x:1 +习焉不察 1 +x:1 +发配 1 +x:1 +电务处 1 +x:1 +科协 1 +x:1 +舞员 1 +x:1 +三确保 1 +x:1 +透视片 1 +x:1 +珞巴族 1 +x:1 +油轮 1 +x:1 +盆塘 1 +x:1 +暖泉 1 +x:1 +羚牛 1 +x:1 +顺流而下 1 +x:1 +燃爆 1 +x:1 +车轮战 1 +x:1 +岐 4 +x:4 +屯口村 1 +x:1 +炎热 1 +x:1 +漫步 1 +x:1 +诤臣 1 +x:1 +连平县 1 +x:1 +迫害 1 +x:1 +袭扰 1 +x:1 +邸 3 +x:3 +地质 1 +x:1 +目迷五色 1 +x:1 +火种刀耕 1 +x:1 +盼头 1 +x:1 +卓有远见 1 +x:1 +贡唐金塔 1 +x:1 +包工头 1 +x:1 +中国籍 1 +x:1 +力保 1 +x:1 +力促 1 +x:1 +集资费 1 +x:1 +孝子贤孙 1 +x:1 +留鸟 1 +x:1 +汛 3 +x:3 +清山秀水 1 +x:1 +言言 1 +x:1 +剽取 1 +x:1 +勤 89 +x:89 +古色古香 1 +x:1 +百舸争流 1 +x:1 +乒乓 1 +x:1 +种棉 1 +x:1 +行头 1 +x:1 +腹毛 1 +x:1 +朱红 1 +x:1 +泸溪县 1 +x:1 +雨量站 1 +x:1 +暖流 1 +x:1 +唱腔 1 +x:1 +产儿 1 +x:1 +理发馆 1 +x:1 +离心力 1 +x:1 +来电 1 +x:1 +甘汞 1 +x:1 +华屋豪宅 1 +x:1 +地貌 1 +x:1 +钡 1 +x:1 +老城镇 1 +x:1 +弘扬 1 +x:1 +力主 1 +x:1 +来由 1 +x:1 +斫 1 +x:1 +纠错者 1 +x:1 +发送 1 +x:1 +倒淌河乡 1 +x:1 +极其 1 +x:1 +竞选人 1 +x:1 +社科院 1 +x:1 +药政科 1 +x:1 +末班车 1 +x:1 +走钢丝 1 +x:1 +消受 1 +x:1 +巴拉哈斯 1 +x:1 +经济区 1 +x:1 +农工型 1 +x:1 +崇州市 1 +x:1 +平方英里 1 +x:1 +拖挂车 1 +x:1 +宝顶山 1 +x:1 +慰问金 1 +x:1 +舞钢市 1 +x:1 +霓 1 +x:1 +行进 1 +x:1 +陶窑 1 +x:1 +酱汤 1 +x:1 +能源所 1 +x:1 +萨尔瓦多 1 +x:1 +脱贫 1 +x:1 +并力 1 +x:1 +汗珠子 1 +x:1 +寿 20 +x:20 +展卷 1 +x:1 +甘泉 1 +x:1 +中词 1 +x:1 +村霸 1 +x:1 +消化 1 +x:1 +气象站 1 +x:1 +廉政节 1 +x:1 +中试 1 +x:1 +瑶山 1 +x:1 +零七八碎 1 +x:1 +竞赛 1 +x:1 +租赁权 1 +x:1 +黄梅戏 1 +x:1 +经济史 1 +x:1 +中南海 1 +x:1 +力争 1 +x:1 +无店铺 1 +x:1 +浮筒 1 +x:1 +草鞋岭 1 +x:1 +遮放 1 +x:1 +国音 1 +x:1 +酱油 1 +x:1 +施工期 1 +x:1 +办事处 1 +x:1 +讴 1 +x:1 +自行其是 1 +x:1 +内棺 1 +x:1 +事务长 1 +x:1 +崔庄乡 1 +x:1 +官运亨通 1 +x:1 +石榴庄 1 +x:1 +饮食 1 +x:1 +炊烟 1 +x:1 +洋嗓子 1 +x:1 +租赁期 1 +x:1 +水冲港乡 1 +x:1 +降 465 +x:465 +产出 1 +x:1 +价轻字 1 +x:1 +压垮 1 +x:1 +锋芒毕露 1 +x:1 +消协 1 +x:1 +除害兴利 1 +x:1 +聚敛 1 +x:1 +重复性 1 +x:1 +水花生 1 +x:1 +山岗子 1 +x:1 +极冠 1 +x:1 +人心不古 1 +x:1 +三合院儿 1 +x:1 +翻悔 1 +x:1 +不甘 1 +x:1 +氢气 1 +x:1 +甘油 1 +x:1 +并列 1 +x:1 +印刷机 1 +x:1 +管理法 1 +x:1 +艾尔河 1 +x:1 +直截了当 1 +x:1 +凉水河 1 +x:1 +罪有应得 1 +x:1 +中论 1 +x:1 +抗虫棉 1 +x:1 +灵感 1 +x:1 +油路 1 +x:1 +过村镇 1 +x:1 +骗税 1 +x:1 +计件 1 +x:1 +建房款 1 +x:1 +中街 1 +x:1 +稀树 1 +x:1 +佛手 1 +x:1 +宛平县 1 +x:1 +枚马 1 +x:1 +成功路 1 +x:1 +招远市 1 +x:1 +以怨报德 1 +x:1 +分散化 1 +x:1 +饱和点 1 +x:1 +虎视眈眈 1 +x:1 +上网者 1 +x:1 +中表 1 +x:1 +燃点 1 +x:1 +贲 2 +x:2 +命令名 1 +x:1 +太白山 1 +x:1 +店主 1 +x:1 +转来额 1 +x:1 +去职 1 +x:1 +非标准件 1 +x:1 +浮签 1 +x:1 +疑难病 1 +x:1 +互促互动 1 +x:1 +党证 1 +x:1 +功夫服 1 +x:1 +极刑 1 +x:1 +局务 1 +x:1 +优质品率 1 +x:1 +子目录 1 +x:1 +敛息屏声 1 +x:1 +燃烧 1 +x:1 +堑沟 1 +x:1 +据 5989 +x:5989 +困人 1 +x:1 +党课 1 +x:1 +弘愿 1 +x:1 +去者 1 +x:1 +产前 1 +x:1 +茄干 1 +x:1 +助养金 1 +x:1 +择偶 1 +x:1 +中装 1 +x:1 +忧念 1 +x:1 +并入 1 +x:1 +发行点 1 +x:1 +不解之缘 1 +x:1 +白水镇 1 +x:1 +打击乐 1 +x:1 +一扫而空 1 +x:1 +体联 1 +x:1 +拒捕 1 +x:1 +库蚊 1 +x:1 +商铺 1 +x:1 +周秦汉唐 1 +x:1 +千了百当 1 +x:1 +茶艺室 1 +x:1 +狡辩 1 +x:1 +辟 85 +x:85 +湘莲 1 +x:1 +饺子 1 +x:1 +油质 1 +x:1 +消停 1 +x:1 +燃油箱 1 +x:1 +牙粉袋 1 +x:1 +磷灰石 1 +x:1 +极力 1 +x:1 +瘙痒 1 +x:1 +地轴 1 +x:1 +原子序数 1 +x:1 +概括 1 +x:1 +死硬派 1 +x:1 +积水场 1 +x:1 +凉水澡 1 +x:1 +旧范 1 +x:1 +技术活 1 +x:1 +脱身 1 +x:1 +赵巷镇 1 +x:1 +用率 1 +x:1 +征订期 1 +x:1 +粤剧团 1 +x:1 +原发癌 1 +x:1 +消费品 1 +x:1 +草鸡 1 +x:1 +施工方 1 +x:1 +产区 1 +x:1 +蚕子 1 +x:1 +县级 1 +x:1 +著录 1 +x:1 +毛重 1 +x:1 +解释 1 +x:1 +厣 1 +x:1 +晴好 1 +x:1 +日月食 1 +x:1 +见贤思齐 1 +x:1 +香烟盒 1 +x:1 +两劳 1 +x:1 +估 7 +x:7 +脱轨 1 +x:1 +灵性 1 +x:1 +产卵 1 +x:1 +哲盟 1 +x:1 +喀麦隆队 1 +x:1 +子堤 1 +x:1 +弃市 1 +x:1 +浮法 1 +x:1 +计件工资 1 +x:1 +罐 13 +x:13 +壕 1 +x:1 +撂挑子 1 +x:1 +极化 1 +x:1 +艳装 1 +x:1 +小中见大 1 +x:1 +要素 1 +x:1 +呢 1068 +x:1068 +要紧 1 +x:1 +宽舒 1 +x:1 +麦秸灰 1 +x:1 +租赁方 1 +x:1 +进退观 1 +x:1 +晴天 1 +x:1 +绕阳河 1 +x:1 +华尔兹 1 +x:1 +舞坛 1 +x:1 +远见卓识 1 +x:1 +中观 1 +x:1 +误解 1 +x:1 +大材小用 1 +x:1 +三重奏 1 +x:1 +打工仔 1 +x:1 +本票 1 +x:1 +农工商 1 +x:1 +战略学 1 +x:1 +楼厦村 1 +x:1 +晶体管 1 +x:1 +诊所 1 +x:1 +白色 1 +x:1 +搭 197 +x:197 +第二国际 1 +x:1 +干巴 1 +x:1 +仰面 1 +x:1 +极右 1 +x:1 +濯田镇 1 +x:1 +玩意 1 +x:1 +酸酸的 1 +x:1 +体肤 1 +x:1 +即兴之作 1 +x:1 +司令官 1 +x:1 +伸长率 1 +x:1 +金鸡山 1 +x:1 +泽城乡 1 +x:1 +刹那 1 +x:1 +柳铁局 1 +x:1 +村长 1 +x:1 +旋转 1 +x:1 +登高望远 1 +x:1 +言之有理 1 +x:1 +沈阳队 1 +x:1 +尧治河村 1 +x:1 +舞场 1 +x:1 +股东会 1 +x:1 +中医科 1 +x:1 +天台里 1 +x:1 +燃煤 1 +x:1 +大安镇 1 +x:1 +苯胺 1 +x:1 +村镇 1 +x:1 +府第 1 +x:1 +博闻强志 1 +x:1 +春运 1 +x:1 +抚河 1 +x:1 +素来 1 +x:1 +五内俱裂 1 +x:1 +法律案 1 +x:1 +粮管所 1 +x:1 +地膜 1 +x:1 +苔藓 1 +x:1 +交款日 1 +x:1 +古代人 1 +x:1 +内敛 1 +x:1 +连锁反应 1 +x:1 +月薪 1 +x:1 +换文 1 +x:1 +腾飞 1 +x:1 +甲亢丸 1 +x:1 +续断 1 +x:1 +状态者 1 +x:1 +卓然而立 1 +x:1 +素材 1 +x:1 +大桥局 1 +x:1 +油菜 1 +x:1 +蛮不讲理 1 +x:1 +春耕 1 +x:1 +出尔反尔 1 +x:1 +任选 1 +x:1 +中建协 1 +x:1 +换料 1 +x:1 +乐施会 1 +x:1 +岐山县 1 +x:1 +用料 1 +x:1 +界限 1 +x:1 +苇 5 +x:5 +如丧考妣 1 +x:1 +八八年 1 +x:1 +经济带 1 +x:1 +素朴 1 +x:1 +行迹 1 +x:1 +强货币 1 +x:1 +老一套 1 +x:1 +沙龙 1 +x:1 +经济师 1 +x:1 +抢救者 1 +x:1 +斗心眼 1 +x:1 +杨庄村 1 +x:1 +睹物伤情 1 +x:1 +白喉 1 +x:1 +摄像管 1 +x:1 +氯霉素 1 +x:1 +内政 1 +x:1 +弃儿 1 +x:1 +甘愿 1 +x:1 +冠亚军 1 +x:1 +会员费 1 +x:1 +春联 1 +x:1 +水针剂 1 +x:1 +司令员 1 +x:1 +辅导员 1 +x:1 +缺德事 1 +x:1 +该部 1 +x:1 +佛法 1 +x:1 +金玉良言 1 +x:1 +春肥 1 +x:1 +征服者 1 +x:1 +德语 1 +x:1 +牛痘 1 +x:1 +行业语 1 +x:1 +离心式 1 +x:1 +地脉 1 +x:1 +鞋帽 1 +x:1 +脱胎 1 +x:1 +工业性 1 +x:1 +脱胶 1 +x:1 +尚巴涅 1 +x:1 +遗传病 1 +x:1 +倚靠 1 +x:1 +文化人 1 +x:1 +方便牌 1 +x:1 +驻地 1 +x:1 +自流灌溉 1 +x:1 +旬中 1 +x:1 +盆周 1 +x:1 +大难不死 1 +x:1 +游手好闲 1 +x:1 +宿疾 1 +x:1 +经济庭 1 +x:1 +脱肛 1 +x:1 +该邦 1 +x:1 +株连 1 +x:1 +老式 1 +x:1 +旧货 1 +x:1 +旧账 1 +x:1 +置业 1 +x:1 +弃农 1 +x:1 +新书区 1 +x:1 +三合土 1 +x:1 +耍弄 1 +x:1 +名牌货 1 +x:1 +办事员 1 +x:1 +火工品 1 +x:1 +笑貌 1 +x:1 +葳 1 +x:1 +更 7014 +x:7014 +倨 1 +x:1 +灌阳县 1 +x:1 +袖 5 +x:5 +彻悟 1 +x:1 +鸡毛信 1 +x:1 +稀有 1 +x:1 +八哥儿 1 +x:1 +假以时日 1 +x:1 +凄楚 1 +x:1 +属于 1 +x:1 +栖 11 +x:11 +积雨云团 1 +x:1 +孤家子 1 +x:1 +二轻局 1 +x:1 +姨太太 1 +x:1 +谋杀 1 +x:1 +深交所 1 +x:1 +安塔拉 1 +x:1 +置信 1 +x:1 +临洮县 1 +x:1 +跪丐 1 +x:1 +各行其事 1 +x:1 +高个子 1 +x:1 +跪下 1 +x:1 +灵渠 1 +x:1 +油苗 1 +x:1 +庆回归 1 +x:1 +跃 102 +x:102 +仰首 1 +x:1 +料量 1 +x:1 +感恩图报 1 +x:1 +效 26 +x:26 +阿瑟港 1 +x:1 +卸货 1 +x:1 +暖意 1 +x:1 +长岗岭 1 +x:1 +脱脂 1 +x:1 +种数 1 +x:1 +抗干扰 1 +x:1 +相对而言 1 +x:1 +油花 1 +x:1 +小鞋 1 +x:1 +安全线 1 +x:1 +阶下囚 1 +x:1 +诤友 1 +x:1 +渔人之利 1 +x:1 +男耕女织 1 +x:1 +噪 6 +x:6 +命令字 1 +x:1 +俯 12 +x:12 +发行网 1 +x:1 +维度 1 +x:1 +三并举 1 +x:1 +旧貌 1 +x:1 +稀松 1 +x:1 +商标权 1 +x:1 +严以律人 1 +x:1 +佳期 1 +x:1 +依依不舍 1 +x:1 +卓荦不凡 1 +x:1 +白发人 1 +x:1 +评话 1 +x:1 +炭坑 1 +x:1 +肥头 1 +x:1 +联汇丰队 1 +x:1 +画片儿 1 +x:1 +喷气式 1 +x:1 +弦乐 1 +x:1 +竞猜卡 1 +x:1 +评语 1 +x:1 +极左 1 +x:1 +舞女 1 +x:1 +轻生 1 +x:1 +脱臼 1 +x:1 +埃雷迪亚 1 +x:1 +蝼蛄 1 +x:1 +昵 1 +x:1 +消弭 1 +x:1 +荆门 1 +x:1 +先遣 1 +x:1 +评说 1 +x:1 +链烃 1 +x:1 +争斤论两 1 +x:1 +早茶 1 +x:1 +捕鱼 1 +x:1 +购领 1 +x:1 +宗主国 1 +x:1 +博通古今 1 +x:1 +妇科病 1 +x:1 +为尊者讳 1 +x:1 +试岗制 1 +x:1 +工商业部 1 +x:1 +油船 1 +x:1 +空气 1 +x:1 +满目疮痍 1 +x:1 +信任感 1 +x:1 +料酒 1 +x:1 +蒸汽锤 1 +x:1 +评议 1 +x:1 +喜结连理 1 +x:1 +渐进 1 +x:1 +岫岩 1 +x:1 +软 71 +x:71 +一家村 1 +x:1 +评论 1 +x:1 +舒同体 1 +x:1 +蝼蚁 1 +x:1 +扰动 1 +x:1 +宗教改革 1 +x:1 +维州 1 +x:1 +胃蛋白酶 1 +x:1 +臭烘烘 1 +x:1 +需 635 +x:635 +表决器 1 +x:1 +阿维西奥 1 +x:1 +旧迹 1 +x:1 +湖中 1 +x:1 +四残 1 +x:1 +素数 1 +x:1 +循环系统 1 +x:1 +产业革命 1 +x:1 +廉吏 1 +x:1 +离任者 1 +x:1 +文武全才 1 +x:1 +净余 1 +x:1 +萤火 1 +x:1 +迪斯科 1 +x:1 +灵活 1 +x:1 +经济局 1 +x:1 +佛湾 1 +x:1 +虚妄 1 +x:1 +肉丝面 1 +x:1 +三字一话 1 +x:1 +西青区 1 +x:1 +趔趄 1 +x:1 +抚慰 1 +x:1 +茧价 1 +x:1 +吐艳 1 +x:1 +国难 1 +x:1 +善歌者 1 +x:1 +破口大骂 1 +x:1 +超支 1 +x:1 +小院 1 +x:1 +发 1095 +x:1095 +白芍 1 +x:1 +受益人 1 +x:1 +永乐二年 1 +x:1 +春色 1 +x:1 +中营 1 +x:1 +雷暴云 1 +x:1 +元曲选 1 +x:1 +好生生 1 +x:1 +轩然大波 1 +x:1 +经济作物 1 +x:1 +石女 1 +x:1 +实习员 1 +x:1 +列述 1 +x:1 +鬼胎 1 +x:1 +轻盈 1 +x:1 +通货膨胀 1 +x:1 +村风 1 +x:1 +夫权 1 +x:1 +托管人 1 +x:1 +兴化州 1 +x:1 +无本万利 1 +x:1 +素日 1 +x:1 +利哈乔夫 1 +x:1 +杂质 1 +x:1 +尚志市 1 +x:1 +靠不住 1 +x:1 +惊世骇俗 1 +x:1 +春芽 1 +x:1 +油腻 1 +x:1 +退避三舍 1 +x:1 +海里凡 1 +x:1 +瞳仁 1 +x:1 +北河沿 1 +x:1 +献词 1 +x:1 +通共 1 +x:1 +肠胃炎 1 +x:1 +叙永县 1 +x:1 +圩 2 +x:2 +续本 1 +x:1 +茧丝 1 +x:1 +素族 1 +x:1 +春节 1 +x:1 +青菜萝卜 1 +x:1 +产床 1 +x:1 +乃 88 +x:88 +胆囊炎 1 +x:1 +玻璃墙 1 +x:1 +掠夺品 1 +x:1 +现浇塔机 1 +x:1 +极值 1 +x:1 +晴和 1 +x:1 +脱节 1 +x:1 +扫地出门 1 +x:1 +拗口 1 +x:1 +销售法 1 +x:1 +列车 1 +x:1 +越剧 1 +x:1 +极度 1 +x:1 +闪 35 +x:35 +女孩儿 1 +x:1 +总堤 1 +x:1 +阿维亚诺 1 +x:1 +饼肥 1 +x:1 +输油管线 1 +x:1 +导演奖 1 +x:1 +侠气 1 +x:1 +欠税款 1 +x:1 +要点 1 +x:1 +春苗 1 +x:1 +内架 1 +x:1 +纪要 1 +x:1 +涨落不一 1 +x:1 +农工委 1 +x:1 +结核病 1 +x:1 +选聘 1 +x:1 +灵气 1 +x:1 +卸车 1 +x:1 +封里 1 +x:1 +处女地 1 +x:1 +试映式 1 +x:1 +二产 1 +x:1 +海林市 1 +x:1 +春茶 1 +x:1 +世纪性 1 +x:1 +因材施教 1 +x:1 +内景 1 +x:1 +断章取义 1 +x:1 +瞒上欺下 1 +x:1 +抚恤 1 +x:1 +出口量 1 +x:1 +公驴 1 +x:1 +纪行 1 +x:1 +错别字 1 +x:1 +圣诞树 1 +x:1 +治吏 1 +x:1 +春茗 1 +x:1 +永磁 1 +x:1 +菩萨 1 +x:1 +河道化 1 +x:1 +趋长避短 1 +x:1 +走马看花 1 +x:1 +牛瘟 1 +x:1 +一把子 1 +x:1 +监评部 1 +x:1 +双拥办 1 +x:1 +千夫所指 1 +x:1 +春草 1 +x:1 +艰苦朴素 1 +x:1 +管理所 1 +x:1 +算命 1 +x:1 +歪风邪气 1 +x:1 +春荒 1 +x:1 +致电 1 +x:1 +渗 11 +x:11 +心慈面软 1 +x:1 +笋 3 +x:3 +鬼脸 1 +x:1 +补天浴日 1 +x:1 +驾驭 1 +x:1 +鳌峰 1 +x:1 +置诸高阁 1 +x:1 +去路 1 +x:1 +弘法 1 +x:1 +物化室 1 +x:1 +彬彬有礼 1 +x:1 +沃尔特 1 +x:1 +盐场 1 +x:1 +净价 1 +x:1 +防弹车 1 +x:1 +爱尔兰队 1 +x:1 +小吃摊儿 1 +x:1 +范围 1 +x:1 +机动科 1 +x:1 +用纸 1 +x:1 +外事 1 +x:1 +用线 1 +x:1 +全运会 1 +x:1 +俄新社 1 +x:1 +成功者 1 +x:1 +链状 1 +x:1 +贫困者 1 +x:1 +状元楼 1 +x:1 +温和派 1 +x:1 +云贵川 1 +x:1 +沧桑史 1 +x:1 +假酒案 1 +x:1 +发黑 1 +x:1 +乡镇 1 +x:1 +春菊 1 +x:1 +商务部长 1 +x:1 +技术性 1 +x:1 +春菇 1 +x:1 +示踪原子 1 +x:1 +父辈 1 +x:1 +少年报 1 +x:1 +发黄 1 +x:1 +翁布里亚 1 +x:1 +牛皮 1 +x:1 +油耗 1 +x:1 +手头紧 1 +x:1 +自贸区 1 +x:1 +台港澳侨 1 +x:1 +托克托县 1 +x:1 +清漆 1 +x:1 +重力场 1 +x:1 +刘少奇 1 +x:1 +世纪末 1 +x:1 +托生 1 +x:1 +料钟 1 +x:1 +宋人 1 +x:1 +泡沫剂 1 +x:1 +北固碾村 1 +x:1 +雏鸟 1 +x:1 +机械车 1 +x:1 +腾鳌 1 +x:1 +旧观 1 +x:1 +中色 1 +x:1 +深褐色 1 +x:1 +挨整 1 +x:1 +七星人 1 +x:1 +油菜花 1 +x:1 +科长 1 +x:1 +发饰 1 +x:1 +背运 1 +x:1 +玛卡鲁峰 1 +x:1 +风雪交加 1 +x:1 +著名 1 +x:1 +强迫症 1 +x:1 +推广会 1 +x:1 +华石镇 1 +x:1 +阳光厅 1 +x:1 +发货票 1 +x:1 +创意者 1 +x:1 +凭证式 1 +x:1 +救亡 1 +x:1 +宝林乡 1 +x:1 +盐城市 1 +x:1 +炼油厂 1 +x:1 +重力坝 1 +x:1 +脱落 1 +x:1 +中航 1 +x:1 +湘西 1 +x:1 +非公司制 1 +x:1 +财务部 1 +x:1 +再会 1 +x:1 +吵闹声 1 +x:1 +屯昌 1 +x:1 +昇 3 +x:3 +白庄村 1 +x:1 +杉竹林片 1 +x:1 +名记者 1 +x:1 +决一雌雄 1 +x:1 +基藏书库 1 +x:1 +张北县 1 +x:1 +凿子 1 +x:1 +封妻荫子 1 +x:1 +围困战 1 +x:1 +筏型 1 +x:1 +执黑 1 +x:1 +毛驴 1 +x:1 +烟草业 1 +x:1 +沼地 1 +x:1 +原由 1 +x:1 +素描 1 +x:1 +卸装 1 +x:1 +超大型 1 +x:1 +低洼地 1 +x:1 +疲劳感 1 +x:1 +义捐 1 +x:1 +并存 1 +x:1 +契合 1 +x:1 +吸墨纸 1 +x:1 +有哭有闹 1 +x:1 +救灾车 1 +x:1 +轻灵 1 +x:1 +娄山关 1 +x:1 +主食品 1 +x:1 +更戛乡 1 +x:1 +新福村 1 +x:1 +猛士 1 +x:1 +剧联 1 +x:1 +黄梅歌 1 +x:1 +筏基 1 +x:1 +划转 1 +x:1 +为时尚早 1 +x:1 +欲哭无泪 1 +x:1 +月儿 1 +x:1 +抛石 1 +x:1 +发行站 1 +x:1 +运管员 1 +x:1 +油气井 1 +x:1 +扭矩 1 +x:1 +草屋 1 +x:1 +谐调性 1 +x:1 +理所应当 1 +x:1 +千秋万载 1 +x:1 +迫切 1 +x:1 +念念不忘 1 +x:1 +单耳刀儿 1 +x:1 +经济学 1 +x:1 +铸工 1 +x:1 +盖世太保 1 +x:1 +隐秘性 1 +x:1 +小雪 1 +x:1 +不动声色 1 +x:1 +成绩 1 +x:1 +水流声 1 +x:1 +序号 1 +x:1 +琦 29 +x:29 +乌斯怀亚 1 +x:1 +该镇 1 +x:1 +小雨 1 +x:1 +胸臆 1 +x:1 +降压 1 +x:1 +动脉硬化 1 +x:1 +陆院 1 +x:1 +命令式 1 +x:1 +教卫委 1 +x:1 +子孙后代 1 +x:1 +夸 35 +x:35 +再也 1 +x:1 +透风窗 1 +x:1 +爆炸案 1 +x:1 +社会性 1 +x:1 +临管线 1 +x:1 +泡沫化 1 +x:1 +无隙可乘 1 +x:1 +渔灯 1 +x:1 +春蕾 1 +x:1 +意 335 +x:335 +界牌岭 1 +x:1 +照明灯 1 +x:1 +扶摇直上 1 +x:1 +捕食 1 +x:1 +放飞 1 +x:1 +极大 1 +x:1 +再不 1 +x:1 +西学东渐 1 +x:1 +用砖 1 +x:1 +新蔡县 1 +x:1 +吐蕃 1 +x:1 +竹帘画 1 +x:1 +大肉 1 +x:1 +胸膜 1 +x:1 +此症 1 +x:1 +吐蕊 1 +x:1 +空 156 +x:156 +人情费 1 +x:1 +此病 1 +x:1 +内情 1 +x:1 +胸腹 1 +x:1 +不瞒您说 1 +x:1 +鬼蜮 1 +x:1 +常规战争 1 +x:1 +相待 1 +x:1 +浪涛不再 1 +x:1 +封面 1 +x:1 +陶片 1 +x:1 +产妇 1 +x:1 +献血 1 +x:1 +无价之宝 1 +x:1 +锚泊点 1 +x:1 +撰稿人 1 +x:1 +副厅级 1 +x:1 +评述 1 +x:1 +义正辞严 1 +x:1 +评比式 1 +x:1 +胸脯 1 +x:1 +踢踢 1 +x:1 +快门儿 1 +x:1 +绑架者 1 +x:1 +私盐 1 +x:1 +炭化 1 +x:1 +苹果花 1 +x:1 +中猪 1 +x:1 +星工场 1 +x:1 +联络处 1 +x:1 +天水市 1 +x:1 +少先队 1 +x:1 +列表 1 +x:1 +久长 1 +x:1 +维也纳 1 +x:1 +全神贯注 1 +x:1 +托瓶 1 +x:1 +优生 1 +x:1 +倚重 1 +x:1 +旧说 1 +x:1 +糖锅 1 +x:1 +少年村 1 +x:1 +副高 1 +x:1 +该院 1 +x:1 +劳动模范 1 +x:1 +自治 1 +x:1 +科大 1 +x:1 +点火率 1 +x:1 +时间差 1 +x:1 +批驳 1 +x:1 +加油添醋 1 +x:1 +旧诗 1 +x:1 +神木 1 +x:1 +馥 1 +x:1 +油藏 1 +x:1 +驻军法 1 +x:1 +私用 1 +x:1 +真知灼见 1 +x:1 +久久 1 +x:1 +词谱 1 +x:1 +阿维尼翁 1 +x:1 +邗江县 1 +x:1 +廊门 1 +x:1 +热农大 1 +x:1 +龙凤丹 1 +x:1 +觅子店乡 1 +x:1 +德赛 1 +x:1 +纳税率 1 +x:1 +中考 1 +x:1 +凄清 1 +x:1 +北南方 1 +x:1 +毛额 1 +x:1 +中耕 1 +x:1 +鳌头 1 +x:1 +海事 1 +x:1 +有幸 1 +x:1 +战略办 1 +x:1 +料事如神 1 +x:1 +素愿 1 +x:1 +低龄化 1 +x:1 +出栏数 1 +x:1 +港森牌 1 +x:1 +隐隐作痛 1 +x:1 +管理权 1 +x:1 +产婆 1 +x:1 +该队 1 +x:1 +解题 1 +x:1 +中耳 1 +x:1 +井冈山市 1 +x:1 +解颐 1 +x:1 +花天酒地 1 +x:1 +贤者 1 +x:1 +排他性 1 +x:1 +申购单 1 +x:1 +巴尔扎克 1 +x:1 +勘察者 1 +x:1 +浑源县 1 +x:1 +谗 2 +x:2 +神乎其神 1 +x:1 +岩浆岩 1 +x:1 +引人注目 1 +x:1 +工商会 1 +x:1 +闲来之笔 1 +x:1 +相去甚远 1 +x:1 +返还权 1 +x:1 +入选率 1 +x:1 +春蚕 1 +x:1 +内援 1 +x:1 +衙署 1 +x:1 +火眼金睛 1 +x:1 +嫂夫人 1 +x:1 +机动粮 1 +x:1 +韩方 1 +x:1 +野猪 1 +x:1 +小学校 1 +x:1 +换换 1 +x:1 +悲天悯人 1 +x:1 +用箱 1 +x:1 +纵情山水 1 +x:1 +编撰者 1 +x:1 +痒 3 +x:3 +暖暖 1 +x:1 +癸 1 +x:1 +觚 1 +x:1 +耍笔杆 1 +x:1 +秕糠 1 +x:1 +个性化 1 +x:1 +建议书 1 +x:1 +神清气爽 1 +x:1 +木椁 1 +x:1 +并处 1 +x:1 +科委 1 +x:1 +酩酊大醉 1 +x:1 +内陆海 1 +x:1 +中肯 1 +x:1 +铸币 1 +x:1 +线装书 1 +x:1 +此理 1 +x:1 +暗送秋波 1 +x:1 +范县 1 +x:1 +液化气所 1 +x:1 +明眼人 1 +x:1 +善意 1 +x:1 +天文社 1 +x:1 +理财组 1 +x:1 +中腔 1 +x:1 +汗珠儿 1 +x:1 +野狼 1 +x:1 +数不胜数 1 +x:1 +如梦如幻 1 +x:1 +月子病 1 +x:1 +尊师重教 1 +x:1 +姬百合塔 1 +x:1 +大篷车 1 +x:1 +情随事迁 1 +x:1 +封门 1 +x:1 +封闭 1 +x:1 +缩砂密 1 +x:1 +泄密 1 +x:1 +巡道 1 +x:1 +盆口 1 +x:1 +抚摸 1 +x:1 +绿油油 1 +x:1 +中腹 1 +x:1 +喝酒钱 1 +x:1 +野狗 1 +x:1 +奉贤县 1 +x:1 +素性 1 +x:1 +值机 1 +x:1 +黄冈市 1 +x:1 +中脑 1 +x:1 +内战 1 +x:1 +一波又起 1 +x:1 +萨尔瓦区 1 +x:1 +新名词 1 +x:1 +更衣室 1 +x:1 +拆穿 1 +x:1 +解馋 1 +x:1 +老关山 1 +x:1 +产子 1 +x:1 +森严 1 +x:1 +锦囊妙计 1 +x:1 +行云 1 +x:1 +擂台赛 1 +x:1 +野物 1 +x:1 +肋条 1 +x:1 +我会 1 +x:1 +取暖费 1 +x:1 +极富 1 +x:1 +课堂 1 +x:1 +动量矩 1 +x:1 +消夏 1 +x:1 +陶灶 1 +x:1 +解饱 1 +x:1 +换房 1 +x:1 +唱词 1 +x:1 +封镜 1 +x:1 +工商业 1 +x:1 +吊袜带 1 +x:1 +客运处 1 +x:1 +直接税 1 +x:1 +极目眺望 1 +x:1 +舞影 1 +x:1 +消失 1 +x:1 +画中画 1 +x:1 +火箭炮 1 +x:1 +佝偻 1 +x:1 +野牛 1 +x:1 +枣林 1 +x:1 +封锁 1 +x:1 +拱体 1 +x:1 +矽肺病 1 +x:1 +发髻 1 +x:1 +肋木 1 +x:1 +吊放 1 +x:1 +另有所指 1 +x:1 +托盘 1 +x:1 +从容就义 1 +x:1 +结算科 1 +x:1 +牛犊 1 +x:1 +票额 1 +x:1 +佛殿 1 +x:1 +肠胃病 1 +x:1 +马后炮 1 +x:1 +战略区 1 +x:1 +闻风而动 1 +x:1 +退 254 +x:254 +老八龙桥 1 +x:1 +瞅 22 +x:22 +店堂 1 +x:1 +专业班 1 +x:1 +加快 1 +x:1 +轻油 1 +x:1 +旧闻 1 +x:1 +咖啡吧 1 +x:1 +推销商 1 +x:1 +未饥先食 1 +x:1 +督查室 1 +x:1 +去除 1 +x:1 +制度法 1 +x:1 +废 58 +x:58 +渔洞 1 +x:1 +该行 1 +x:1 +邕江 1 +x:1 +佳纸 1 +x:1 +胸鳍 1 +x:1 +点心 1 +x:1 +山林田土 1 +x:1 +私欲 1 +x:1 +侠盗 1 +x:1 +音响版 1 +x:1 +亚龙湾 1 +x:1 +洞口 1 +x:1 +枣研 1 +x:1 +贱民 1 +x:1 +摩文仁 1 +x:1 +使馆区 1 +x:1 +刘家塔镇 1 +x:1 +词调 1 +x:1 +显示屏 1 +x:1 +两口儿 1 +x:1 +降价 1 +x:1 +佛理 1 +x:1 +金缕玉衣 1 +x:1 +柳新乡 1 +x:1 +算作 1 +x:1 +幸运卡 1 +x:1 +种类 1 +x:1 +克里特岛 1 +x:1 +指示剂 1 +x:1 +校内外 1 +x:1 +商船 1 +x:1 +催化剂液 1 +x:1 +素缎 1 +x:1 +府治 1 +x:1 +处警 1 +x:1 +怒视 1 +x:1 +力学 1 +x:1 +牛津 1 +x:1 +误车 1 +x:1 +会议员 1 +x:1 +迫使 1 +x:1 +中黄 1 +x:1 +炒家 1 +x:1 +列销 1 +x:1 +种粮 1 +x:1 +用时 1 +x:1 +精彩绝伦 1 +x:1 +降临 1 +x:1 +盐花 1 +x:1 +混水摸鱼 1 +x:1 +考勤钟 1 +x:1 +题字 1 +x:1 +鸟 142 +x:142 +成本价 1 +x:1 +悠 1 +x:1 +卡片 1 +x:1 +经纶天下 1 +x:1 +油魁 1 +x:1 +抗灾力 1 +x:1 +聚氨乙烯 1 +x:1 +毛虾 1 +x:1 +琼脂 1 +x:1 +周至 1 +x:1 +毛虫 1 +x:1 +村舍 1 +x:1 +港人 1 +x:1 +扎加洛 1 +x:1 +脱颖 1 +x:1 +敷药 1 +x:1 +留言 1 +x:1 +轻汽 1 +x:1 +舟子 1 +x:1 +正前方 1 +x:1 +奸 2 +x:2 +加强 1 +x:1 +唱针 1 +x:1 +临沂市 1 +x:1 +砖房 1 +x:1 +春风 1 +x:1 +阿城县 1 +x:1 +马刺队 1 +x:1 +文化园 1 +x:1 +复写 1 +x:1 +廉价 1 +x:1 +浑沌一片 1 +x:1 +维 25 +x:25 +阿劳龟 1 +x:1 +幽幽森森 1 +x:1 +基层司 1 +x:1 +池州 1 +x:1 +歧视性 1 +x:1 +南水峪村 1 +x:1 +公司制 1 +x:1 +文化圈 1 +x:1 +从业者 1 +x:1 +妇科 1 +x:1 +粉 17 +x:17 +区带 1 +x:1 +发落 1 +x:1 +趁热打铁 1 +x:1 +主河道 1 +x:1 +年轻气盛 1 +x:1 +发行期 1 +x:1 +啧有烦言 1 +x:1 +耷拉 1 +x:1 +渔民 1 +x:1 +操纵者 1 +x:1 +封诰 1 +x:1 +稀缺 1 +x:1 +榻 1 +x:1 +沃尔 1 +x:1 +宿将 1 +x:1 +加座 1 +x:1 +牛气 1 +x:1 +戚戚然 1 +x:1 +结算权 1 +x:1 +金口河区 1 +x:1 +骨质增生 1 +x:1 +诚聘 1 +x:1 +白菜苔 1 +x:1 +穿甲弹 1 +x:1 +蕴藏量 1 +x:1 +牙石 1 +x:1 +概略 1 +x:1 +诋毁 1 +x:1 +狂欢 1 +x:1 +大洼县 1 +x:1 +旧钞 1 +x:1 +全球星 1 +x:1 +龙舟节 1 +x:1 +核弹 1 +x:1 +青铜峡路 1 +x:1 +凄然 1 +x:1 +再则 1 +x:1 +再创 1 +x:1 +卡尔多夫 1 +x:1 +尼日尔河 1 +x:1 +合法性 1 +x:1 +揭发者 1 +x:1 +打气筒 1 +x:1 +腾腾 1 +x:1 +轻活 1 +x:1 +迫于 1 +x:1 +少存少贷 1 +x:1 +先行 1 +x:1 +社会系 1 +x:1 +行辈 1 +x:1 +极负盛誉 1 +x:1 +信任票 1 +x:1 +缝制者 1 +x:1 +聚焦 1 +x:1 +金銮殿 1 +x:1 +五笔字 1 +x:1 +空心板梁 1 +x:1 +臭名远扬 1 +x:1 +燃机 1 +x:1 +伊塞克湖 1 +x:1 +利欲熏心 1 +x:1 +首钢队 1 +x:1 +檀香木 1 +x:1 +面 504 +x:504 +文化城 1 +x:1 +印刷费 1 +x:1 +斜射 1 +x:1 +专机组 1 +x:1 +大苏打 1 +x:1 +羊道 1 +x:1 +轻浮 1 +x:1 +恶作剧 1 +x:1 +租售房 1 +x:1 +三缺一 1 +x:1 +鬼魔 1 +x:1 +歧 2 +x:2 +迫令 1 +x:1 +降低 1 +x:1 +过目成诵 1 +x:1 +称 857 +x:857 +鬼魅 1 +x:1 +鬼魂 1 +x:1 +置地 1 +x:1 +风吹草动 1 +x:1 +一班人 1 +x:1 +埋没 1 +x:1 +云鹤乡 1 +x:1 +封装 1 +x:1 +聚碳酸酯 1 +x:1 +加工 1 +x:1 +党龄 1 +x:1 +要案 1 +x:1 +办事人 1 +x:1 +施工点 1 +x:1 +发蜡 1 +x:1 +厢房 1 +x:1 +受益国 1 +x:1 +甚 175 +x:175 +专储粮 1 +x:1 +技术科 1 +x:1 +殷商 1 +x:1 +高温作业 1 +x:1 +非工业 1 +x:1 +赊销 1 +x:1 +用材 1 +x:1 +卸磨杀驴 1 +x:1 +汉学者 1 +x:1 +忍耐 1 +x:1 +机动性 1 +x:1 +用权 1 +x:1 +加州 1 +x:1 +工商司 1 +x:1 +和平新党 1 +x:1 +评选 1 +x:1 +保险费率 1 +x:1 +创史人 1 +x:1 +邦政府 1 +x:1 +交响曲 1 +x:1 +内缘 1 +x:1 +稍纵即逝 1 +x:1 +梅坡村 1 +x:1 +缆沟 1 +x:1 +欺行霸市 1 +x:1 +净土 1 +x:1 +无关紧要 1 +x:1 +文化周 1 +x:1 +小米面 1 +x:1 +无利可图 1 +x:1 +清扫率 1 +x:1 +巾帼英雄 1 +x:1 +利显性 1 +x:1 +油香 1 +x:1 +左邻右舍 1 +x:1 +刺儿 1 +x:1 +克拉苏 1 +x:1 +蟹 5 +x:5 +发货权 1 +x:1 +臆断 1 +x:1 +择善而用 1 +x:1 +生死荣辱 1 +x:1 +北导堤 1 +x:1 +续编 1 +x:1 +油饼 1 +x:1 +伦敦 1 +x:1 +倚赖 1 +x:1 +集中营 1 +x:1 +秘不示人 1 +x:1 +应运而起 1 +x:1 +显示度 1 +x:1 +德量 1 +x:1 +拱券 1 +x:1 +德里 1 +x:1 +珠海 1 +x:1 +规章制度 1 +x:1 +作品选 1 +x:1 +寓舍 1 +x:1 +辅导书 1 +x:1 +范例 1 +x:1 +桅杆 1 +x:1 +咖啡园 1 +x:1 +咖啡因 1 +x:1 +凄苦 1 +x:1 +双程证 1 +x:1 +加强连 1 +x:1 +肠绒毛 1 +x:1 +瓦房店市 1 +x:1 +空投 1 +x:1 +悬置 1 +x:1 +刘家圪瘩 1 +x:1 +大涧村 1 +x:1 +吸毒者 1 +x:1 +离骚 1 +x:1 +跪 44 +x:44 +六 995 +x:995 +抄写 1 +x:1 +北方局 1 +x:1 +题头 1 +x:1 +刘营村 1 +x:1 +犁 52 +x:52 +圆滚滚 1 +x:1 +锄 10 +x:10 +校名 1 +x:1 +存在物 1 +x:1 +留观 1 +x:1 +苯 4 +x:4 +殷周 1 +x:1 +渔港 1 +x:1 +燃料 1 +x:1 +前思后想 1 +x:1 +踉跄 1 +x:1 +经贸团 1 +x:1 +旧雨 1 +x:1 +非工会 1 +x:1 +勿忘草 1 +x:1 +绩效 1 +x:1 +糯稻 1 +x:1 +荒秽 1 +x:1 +至理名言 1 +x:1 +冶金焦 1 +x:1 +下榻地 1 +x:1 +湘阴 1 +x:1 +遭到 1 +x:1 +力塑 1 +x:1 +氟哌酸 1 +x:1 +无穷小 1 +x:1 +血块 1 +x:1 +神差鬼使 1 +x:1 +专业点 1 +x:1 +甜滋滋 1 +x:1 +关东军 1 +x:1 +偶然性 1 +x:1 +高潮 1 +x:1 +伤风败俗 1 +x:1 +钻心 1 +x:1 +屯积 1 +x:1 +处女作 1 +x:1 +糖衣 1 +x:1 +续续 1 +x:1 +轨 18 +x:18 +点心餐 1 +x:1 +郭 631 +x:631 +德选 1 +x:1 +醋酸纤维 1 +x:1 +协会化 1 +x:1 +酸厂 1 +x:1 +区属 1 +x:1 +冰天雪地 1 +x:1 +乔庄 1 +x:1 +种群 1 +x:1 +政工部 1 +x:1 +善 108 +x:108 +拱北 1 +x:1 +苦瓜 1 +x:1 +防洪渠 1 +x:1 +钢性 1 +x:1 +茶几 1 +x:1 +内绘 1 +x:1 +赶海 1 +x:1 +列队 1 +x:1 +嫌少者 1 +x:1 +勘查业 1 +x:1 +泰西村 1 +x:1 +姊妹饭 1 +x:1 +斤 116 +x:116 +水洼地 1 +x:1 +令堂 1 +x:1 +红海州 1 +x:1 +种羊 1 +x:1 +店家 1 +x:1 +燃放 1 +x:1 +轻印刷 1 +x:1 +灵璧 1 +x:1 +金家庄区 1 +x:1 +栽 119 +x:119 +小榄镇 1 +x:1 +属员 1 +x:1 +入网证号 1 +x:1 +运筹学 1 +x:1 +鹊桥相会 1 +x:1 +侦查局 1 +x:1 +五星 1 +x:1 +野渡 1 +x:1 +任课 1 +x:1 +巨浪区 1 +x:1 +德城区 1 +x:1 +猛地 1 +x:1 +发行日 1 +x:1 +名鸟 1 +x:1 +御用 1 +x:1 +胜地 1 +x:1 +俨 1 +x:1 +点射 1 +x:1 +依归 1 +x:1 +点将 1 +x:1 +足不出户 1 +x:1 +内线 1 +x:1 +棒棒军 1 +x:1 +管理站 1 +x:1 +力士 1 +x:1 +小学生 1 +x:1 +巡警 1 +x:1 +湘鄂 1 +x:1 +雅意 1 +x:1 +来兴府 1 +x:1 +谐 5 +x:5 +实用菌 1 +x:1 +党首 1 +x:1 +西敏寺 1 +x:1 +齿垢 1 +x:1 +加密 1 +x:1 +白兰花 1 +x:1 +应诺 1 +x:1 +勾当 1 +x:1 +犯 161 +x:161 +华盛顿 1 +x:1 +维吾尔 1 +x:1 +舌下神经 1 +x:1 +托派 1 +x:1 +源源不绝 1 +x:1 +灵猫 1 +x:1 +长方脸 1 +x:1 +超强度 1 +x:1 +不易之论 1 +x:1 +做梦 1 +x:1 +发腻 1 +x:1 +滑翔机 1 +x:1 +来日方长 1 +x:1 +枣泥 1 +x:1 +加害 1 +x:1 +科技点 1 +x:1 +五彩纷呈 1 +x:1 +绕远儿 1 +x:1 +置办 1 +x:1 +啖 3 +x:3 +素笺 1 +x:1 +加宽 1 +x:1 +微型 1 +x:1 +海平面 1 +x:1 +渔火 1 +x:1 +批号 1 +x:1 +金銮湾 1 +x:1 +勾引 1 +x:1 +忏悔录 1 +x:1 +事业心 1 +x:1 +擦鞋业 1 +x:1 +用意 1 +x:1 +边疆史 1 +x:1 +木栓 1 +x:1 +行辕门 1 +x:1 +作品集 1 +x:1 +褥子 1 +x:1 +点燃者 1 +x:1 +陆运 1 +x:1 +连续性 1 +x:1 +笔录 1 +x:1 +慢步 1 +x:1 +竹凉席 1 +x:1 +内秀 1 +x:1 +沟沟卡卡 1 +x:1 +文化力 1 +x:1 +对口相声 1 +x:1 +私开滥挖 1 +x:1 +高天行云 1 +x:1 +自然力 1 +x:1 +内科 1 +x:1 +中高 1 +x:1 +毛色 1 +x:1 +淡青色 1 +x:1 +特产税 1 +x:1 +住院处 1 +x:1 +巡诊 1 +x:1 +先起 1 +x:1 +牛槽 1 +x:1 +安琪儿 1 +x:1 +城建局 1 +x:1 +九屋乡 1 +x:1 +小至中雨 1 +x:1 +点子 1 +x:1 +慰问者 1 +x:1 +山茶树 1 +x:1 +边疆区 1 +x:1 +后半夜 1 +x:1 +泊宅编 1 +x:1 +原料粮 1 +x:1 +画像石 1 +x:1 +新桥村 1 +x:1 +玩物 1 +x:1 +双幅 1 +x:1 +抛物线 1 +x:1 +卷数 1 +x:1 +新增 1 +x:1 +发自 1 +x:1 +发臭 1 +x:1 +教工委 1 +x:1 +贡品 1 +x:1 +大自在图 1 +x:1 +环绕速度 1 +x:1 +工农红军 1 +x:1 +摄像机 1 +x:1 +孵 5 +x:5 +玩牌 1 +x:1 +先贤 1 +x:1 +押解 1 +x:1 +临川市 1 +x:1 +周转房 1 +x:1 +将 15137 +x:15137 +一·二八 1 +x:1 +混委会 1 +x:1 +玩玩 1 +x:1 +掏腰包 1 +x:1 +旧郡 1 +x:1 +留连 1 +x:1 +冬至线 1 +x:1 +大鼓子 1 +x:1 +扰乱 1 +x:1 +常青草 1 +x:1 +氦 5 +x:5 +一传手 1 +x:1 +相辅而行 1 +x:1 +疫 1 +x:1 +糊墙纸 1 +x:1 +逮 11 +x:11 +文化区 1 +x:1 +睫状体 1 +x:1 +死区 1 +x:1 +油黑 1 +x:1 +络腮胡子 1 +x:1 +故态复萌 1 +x:1 +党风 1 +x:1 +宿根 1 +x:1 +神风洞 1 +x:1 +铀矿 1 +x:1 +生气盎然 1 +x:1 +油麦 1 +x:1 +灵牌 1 +x:1 +不合格者 1 +x:1 +炮火 1 +x:1 +创办人 1 +x:1 +新闻办 1 +x:1 +朱漆 1 +x:1 +头盔厂 1 +x:1 +古代史 1 +x:1 +五交化 1 +x:1 +你来我往 1 +x:1 +殷切 1 +x:1 +叙谈会 1 +x:1 +有意思 1 +x:1 +示 38 +x:38 +资格赛 1 +x:1 +莽撞 1 +x:1 +重点课 1 +x:1 +池塘 1 +x:1 +首长 1 +x:1 +糯米 1 +x:1 +殿堂 1 +x:1 +净值 1 +x:1 +中标者 1 +x:1 +该路 1 +x:1 +发育 1 +x:1 +绿林好汉 1 +x:1 +牛棚 1 +x:1 +畅通 1 +x:1 +销售率 1 +x:1 +文化厅 1 +x:1 +催花量 1 +x:1 +音译词 1 +x:1 +三十三分 1 +x:1 +种禽 1 +x:1 +西海镇 1 +x:1 +灵犀 1 +x:1 +农科园 1 +x:1 +谋篇 1 +x:1 +农民起义 1 +x:1 +座位号 1 +x:1 +趣味性 1 +x:1 +翻整 1 +x:1 +狱政 1 +x:1 +光电磁 1 +x:1 +力度 1 +x:1 +勿庸置疑 1 +x:1 +钻机 1 +x:1 +排练室 1 +x:1 +葵花籽 1 +x:1 +云岭乡 1 +x:1 +幸喜 1 +x:1 +捍疆卫国 1 +x:1 +油鸡 1 +x:1 +镗床 1 +x:1 +独奏家 1 +x:1 +管理系 1 +x:1 +岷县 1 +x:1 +重力仪 1 +x:1 +五女峰 1 +x:1 +满怀信心 1 +x:1 +安得拉邦 1 +x:1 +发胖 1 +x:1 +种种 1 +x:1 +桔红色 1 +x:1 +风疹块 1 +x:1 +水肿病 1 +x:1 +红薯田 1 +x:1 +穗状花序 1 +x:1 +坎帕拉 1 +x:1 +文化史 1 +x:1 +抛洒 1 +x:1 +要求 1 +x:1 +垂 30 +x:30 +沙捞越州 1 +x:1 +鸿图 1 +x:1 +奠基者 1 +x:1 +捕获 1 +x:1 +蒂罗尔 1 +x:1 +生老病死 1 +x:1 +相敬如宾 1 +x:1 +庆功曲 1 +x:1 +墨如寺 1 +x:1 +园艺型 1 +x:1 +单句 1 +x:1 +战和 1 +x:1 +著书 1 +x:1 +方顺桥乡 1 +x:1 +酱缸 1 +x:1 +贡嘎 1 +x:1 +工商型 1 +x:1 +污染度 1 +x:1 +下决心 1 +x:1 +官室长 1 +x:1 +潮田街 1 +x:1 +哀思 1 +x:1 +胸骨 1 +x:1 +致富梦 1 +x:1 +木棍 1 +x:1 +先辈 1 +x:1 +净化 1 +x:1 +苯酚 1 +x:1 +笑呵呵 1 +x:1 +开阔地 1 +x:1 +巴尔各扎 1 +x:1 +无穷大 1 +x:1 +钺 3 +x:3 +佛爷 1 +x:1 +年运量 1 +x:1 +江津市 1 +x:1 +咕咚咕咚 1 +x:1 +山穷水尽 1 +x:1 +池子 1 +x:1 +任 1934 +x:1934 +卷柜 1 +x:1 +株洲县 1 +x:1 +成井 1 +x:1 +坐卧不安 1 +x:1 +侦查处 1 +x:1 +愁怀 1 +x:1 +契丹 1 +x:1 +长盛不衰 1 +x:1 +缪家村 1 +x:1 +春麦 1 +x:1 +卷末 1 +x:1 +两菜一油 1 +x:1 +洋缎 1 +x:1 +素称 1 +x:1 +实务性 1 +x:1 +厚此薄彼 1 +x:1 +匙 2 +x:2 +引潜 1 +x:1 +瞿家湾镇 1 +x:1 +骨膜炎 1 +x:1 +专业界 1 +x:1 +解职 1 +x:1 +福音 1 +x:1 +坐卧不宁 1 +x:1 +划锄 1 +x:1 +形象群 1 +x:1 +解聘 1 +x:1 +绽开 1 +x:1 +杜菜园 1 +x:1 +奥克兰港 1 +x:1 +引以为荣 1 +x:1 +滋生 1 +x:1 +耗费 1 +x:1 +陆路 1 +x:1 +哼唷 1 +x:1 +耗资 1 +x:1 +甘美 1 +x:1 +加大 1 +x:1 +原子团 1 +x:1 +多才多艺 1 +x:1 +罗马尼亚 1 +x:1 +报案人 1 +x:1 +党魁 1 +x:1 +党魂 1 +x:1 +一板一眼 1 +x:1 +私淑 1 +x:1 +玩火 1 +x:1 +中频 1 +x:1 +受益券 1 +x:1 +强台风 1 +x:1 +大鼓墩 1 +x:1 +点头 1 +x:1 +最强音 1 +x:1 +穿山越岭 1 +x:1 +露台 1 +x:1 +双港镇 1 +x:1 +惩办 1 +x:1 +淘气鬼 1 +x:1 +发菜 1 +x:1 +乌兰察布 1 +x:1 +恋爱观 1 +x:1 +力工 1 +x:1 +殿宇 1 +x:1 +暗蓝色 1 +x:1 +撒野 1 +x:1 +续签 1 +x:1 +种站 1 +x:1 +代销者 1 +x:1 +哼哼 1 +x:1 +出口路 1 +x:1 +李庄镇 1 +x:1 +吸贩毒 1 +x:1 +脑缺氧性 1 +x:1 +甘井子 1 +x:1 +著作 1 +x:1 +双泾村 1 +x:1 +无极县 1 +x:1 +臆想 1 +x:1 +中饭 1 +x:1 +二不休 1 +x:1 +陈屋村 1 +x:1 +巡行 1 +x:1 +封路 1 +x:1 +铁冲乡 1 +x:1 +总队长 1 +x:1 +咸咸的 1 +x:1 +代社长 1 +x:1 +残疾率 1 +x:1 +用房 1 +x:1 +大二环 1 +x:1 +鼻窦炎 1 +x:1 +洞庭湖畔 1 +x:1 +论证费 1 +x:1 +用户 1 +x:1 +久违 1 +x:1 +久远 1 +x:1 +体育场馆 1 +x:1 +卷曲 1 +x:1 +地黄 1 +x:1 +在校生 1 +x:1 +高丽纸 1 +x:1 +弃世 1 +x:1 +挤压 1 +x:1 +要津 1 +x:1 +净利 1 +x:1 +杖头木偶 1 +x:1 +帮倒忙 1 +x:1 +爽利 1 +x:1 +自愧不如 1 +x:1 +留足 1 +x:1 +发花 1 +x:1 +瑶乡 1 +x:1 +概率 1 +x:1 +万死一生 1 +x:1 +升任 1 +x:1 +颊 1 +x:1 +发芽 1 +x:1 +小金人 1 +x:1 +重孝 1 +x:1 +赵庄镇 1 +x:1 +张宅乡 1 +x:1 +黄兴路 1 +x:1 +蜜里调油 1 +x:1 +谋私 1 +x:1 +令尊 1 +x:1 +会议厅 1 +x:1 +统治权 1 +x:1 +埋植 1 +x:1 +咖啡厅 1 +x:1 +着色 1 +x:1 +该连 1 +x:1 +技术类 1 +x:1 +抗日救亡 1 +x:1 +人防办 1 +x:1 +驻留 1 +x:1 +续稿 1 +x:1 +土坷垃 1 +x:1 +大团圆 1 +x:1 +德钦 1 +x:1 +椒江区 1 +x:1 +私泄 1 +x:1 +细 201 +x:201 +拱坝 1 +x:1 +多汗症 1 +x:1 +择要 1 +x:1 +受益区 1 +x:1 +变 1115 +x:1115 +风媒花 1 +x:1 +专家号 1 +x:1 +用报 1 +x:1 +睦村 1 +x:1 +程控机 1 +x:1 +舟山 1 +x:1 +留学生司 1 +x:1 +伯利兹籍 1 +x:1 +收集员 1 +x:1 +电唱头 1 +x:1 +沙溪口组 1 +x:1 +渔政 1 +x:1 +分文不取 1 +x:1 +洞察 1 +x:1 +重孙 1 +x:1 +租赁站 1 +x:1 +刹车 1 +x:1 +发财 1 +x:1 +发货 1 +x:1 +敷设 1 +x:1 +兽药 1 +x:1 +技术班 1 +x:1 +疑团 1 +x:1 +小学组 1 +x:1 +中院 1 +x:1 +朱批 1 +x:1 +变化多端 1 +x:1 +星状灯 1 +x:1 +年长者 1 +x:1 +科企 1 +x:1 +大昭寺 1 +x:1 +棚房 1 +x:1 +埋暗 1 +x:1 +秘书长 1 +x:1 +流行性 1 +x:1 +实事求是 1 +x:1 +棚户 1 +x:1 +咿呀 1 +x:1 +夏候鸟 1 +x:1 +粳稻 1 +x:1 +红锌矿 1 +x:1 +正义性 1 +x:1 +发起 1 +x:1 +情急之下 1 +x:1 +毛躁 1 +x:1 +环流 1 +x:1 +中队 1 +x:1 +司局级 1 +x:1 +松墙子 1 +x:1 +倒手 1 +x:1 +咖啡屋 1 +x:1 +炒卖 1 +x:1 +心有余悸 1 +x:1 +目不交睫 1 +x:1 +胭脂红 1 +x:1 +下水道 1 +x:1 +全能运动 1 +x:1 +内画 1 +x:1 +宣明会 1 +x:1 +帽舌 1 +x:1 +峨铁 1 +x:1 +德雷克 1 +x:1 +任职 1 +x:1 +殷忧 1 +x:1 +墀 1 +x:1 +养老者 1 +x:1 +褥垫 1 +x:1 +工号牌 1 +x:1 +洞子 1 +x:1 +上半时 1 +x:1 +妙手 1 +x:1 +缓冲区 1 +x:1 +经不起 1 +x:1 +相形见绌 1 +x:1 +确非 1 +x:1 +内痔 1 +x:1 +军代表室 1 +x:1 +队 777 +x:777 +毋庸 1 +x:1 +阿特拉斯 1 +x:1 +溶解度 1 +x:1 +中雨 1 +x:1 +党锢 1 +x:1 +中雪 1 +x:1 +焱 6 +x:6 +客运业 1 +x:1 +并作 1 +x:1 +石膏矿 1 +x:1 +临川县 1 +x:1 +功莫大焉 1 +x:1 +臊 1 +x:1 +牛斗 1 +x:1 +丝瓜藤 1 +x:1 +大石桥 1 +x:1 +暖炉 1 +x:1 +徽派 1 +x:1 +经济人 1 +x:1 +舰只 1 +x:1 +绩溪 1 +x:1 +消乏 1 +x:1 +教导队 1 +x:1 +累死累活 1 +x:1 +商誉 1 +x:1 +赣县 1 +x:1 +内格罗河 1 +x:1 +进不起 1 +x:1 +含血喷人 1 +x:1 +询 2 +x:2 +副伤寒 1 +x:1 +滴滴涕 1 +x:1 +红血球 1 +x:1 +俄罗斯籍 1 +x:1 +题匾 1 +x:1 +直 253 +x:253 +顺口溜 1 +x:1 +物权法 1 +x:1 +装修队 1 +x:1 +狠狠心 1 +x:1 +兼并者 1 +x:1 +薪尽火传 1 +x:1 +八五年 1 +x:1 +麝香 1 +x:1 +科举 1 +x:1 +仰观 1 +x:1 +执警 1 +x:1 +极大值 1 +x:1 +种田 1 +x:1 +砖 86 +x:86 +加固 1 +x:1 +军 525 +x:525 +中非 1 +x:1 +村训 1 +x:1 +凿岩机 1 +x:1 +玉米饼 1 +x:1 +工商业者 1 +x:1 +排练场 1 +x:1 +恒久 1 +x:1 +地邻 1 +x:1 +重灾县 1 +x:1 +征粮 1 +x:1 +经济体 1 +x:1 +用汇 1 +x:1 +私房 1 +x:1 +陆良 1 +x:1 +盐山 1 +x:1 +维亚 1 +x:1 +咿唷 1 +x:1 +畈 2 +x:2 +缓酌 1 +x:1 +同树异枝 1 +x:1 +选民册 1 +x:1 +喜融融的 1 +x:1 +扭打 1 +x:1 +销售网 1 +x:1 +补充性 1 +x:1 +要挟 1 +x:1 +昂首挺胸 1 +x:1 +聚积 1 +x:1 +转接 1 +x:1 +毛边 1 +x:1 +美满村 1 +x:1 +喀麦隆 1 +x:1 +种畜 1 +x:1 +连战连捷 1 +x:1 +贵池市 1 +x:1 +抚爱 1 +x:1 +引人注意 1 +x:1 +净尽 1 +x:1 +率 192 +x:192 +赶来 1 +x:1 +八次全会 1 +x:1 +盘锦 1 +x:1 +环资委 1 +x:1 +力劝 1 +x:1 +限速 1 +x:1 +不来梅州 1 +x:1 +三维空间 1 +x:1 +旷世名作 1 +x:1 +纸马 1 +x:1 +艳阳 1 +x:1 +内瓤 1 +x:1 +勾勒 1 +x:1 +给付金 1 +x:1 +红九连 1 +x:1 +前臼齿 1 +x:1 +用法 1 +x:1 +负债者 1 +x:1 +中音 1 +x:1 +西吉县 1 +x:1 +北师大 1 +x:1 +维业 1 +x:1 +升 263 +x:263 +群艺馆 1 +x:1 +下屯乡 1 +x:1 +分党支部 1 +x:1 +科任 1 +x:1 +炒勺 1 +x:1 +护目镜 1 +x:1 +着重点 1 +x:1 +并举 1 +x:1 +立足未稳 1 +x:1 +捧 147 +x:147 +连续流 1 +x:1 +并不 1 +x:1 +总参谋部 1 +x:1 +簧片 1 +x:1 +商计 1 +x:1 +中东欧 1 +x:1 +并且 1 +x:1 +城外 1 +x:1 +商讨 1 +x:1 +准噶尔 1 +x:1 +商训 1 +x:1 +击鼓督阵 1 +x:1 +轻敌 1 +x:1 +推广奖 1 +x:1 +商街 1 +x:1 +捂住 1 +x:1 +调戏 1 +x:1 +腐蚀剂 1 +x:1 +炒买炒卖 1 +x:1 +手底下 1 +x:1 +岷山 1 +x:1 +炽热 1 +x:1 +李时珍 1 +x:1 +商行 1 +x:1 +矮寨镇 1 +x:1 +重灾 1 +x:1 +私愤 1 +x:1 +勾兑 1 +x:1 +见棱见角 1 +x:1 +棒垒球 1 +x:1 +产业 1 +x:1 +燃油 1 +x:1 +集散 1 +x:1 +吴 1929 +x:1929 +破碗 1 +x:1 +狂涛 1 +x:1 +炽烈 1 +x:1 +两口子 1 +x:1 +开拓者 1 +x:1 +随呼随到 1 +x:1 +千古不变 1 +x:1 +文化层 1 +x:1 +文化局 1 +x:1 +献县 1 +x:1 +内省 1 +x:1 +出乱子 1 +x:1 +轻曼 1 +x:1 +题写 1 +x:1 +有难必帮 1 +x:1 +摔 72 +x:72 +发车 1 +x:1 +力克 1 +x:1 +发轫 1 +x:1 +诏示 1 +x:1 +坞 1 +x:1 +上半期 1 +x:1 +营口市 1 +x:1 +现已 1 +x:1 +显示器 1 +x:1 +详详细细 1 +x:1 +山盟海誓 1 +x:1 +渔村 1 +x:1 +助跑 1 +x:1 +一发千钧 1 +x:1 +野果 1 +x:1 +上半月 1 +x:1 +迹 11 +x:11 +极为 1 +x:1 +电化学 1 +x:1 +松 142 +x:142 +张铁锤村 1 +x:1 +柳辛庄 1 +x:1 +七高八低 1 +x:1 +古雅 1 +x:1 +振振有词 1 +x:1 +留职 1 +x:1 +卷次 1 +x:1 +小时候 1 +x:1 +佛统 1 +x:1 +歼击 1 +x:1 +会议庭 1 +x:1 +发达 1 +x:1 +油酸 1 +x:1 +高鼻深目 1 +x:1 +毛豆 1 +x:1 +装饰性 1 +x:1 +中铝 1 +x:1 +后半场 1 +x:1 +促成 1 +x:1 +佛经 1 +x:1 +燃气 1 +x:1 +轻易 1 +x:1 +报界 1 +x:1 +汰 3 +x:3 +谈话 1 +x:1 +偕同 1 +x:1 +中银 1 +x:1 +原阳县 1 +x:1 +斜坡 1 +x:1 +架势 1 +x:1 +咖啡店 1 +x:1 +中铺 1 +x:1 +炕单儿 1 +x:1 +拈花惹草 1 +x:1 +资产阶级 1 +x:1 +极了 1 +x:1 +腐蚀力 1 +x:1 +掺假使杂 1 +x:1 +喋喋不休 1 +x:1 +谶语 1 +x:1 +文史系 1 +x:1 +久拖未决 1 +x:1 +伸长 1 +x:1 +杜仲树 1 +x:1 +出口者 1 +x:1 +参众两院 1 +x:1 +抚熨 1 +x:1 +解调 1 +x:1 +发还 1 +x:1 +地拉那 1 +x:1 +话剧院 1 +x:1 +腹痛 1 +x:1 +茫然 1 +x:1 +杜康酒 1 +x:1 +主教堂 1 +x:1 +辫 1 +x:1 +突 44 +x:44 +麻雀虽小 1 +x:1 +该药 1 +x:1 +试映会 1 +x:1 +谋略 1 +x:1 +邮展 1 +x:1 +赶早 1 +x:1 +搪瓷 1 +x:1 +错事 1 +x:1 +与 19851 +x:19851 +石首鱼 1 +x:1 +装修间 1 +x:1 +书物 1 +x:1 +协商会 1 +x:1 +油气业 1 +x:1 +冬至点 1 +x:1 +骗术 1 +x:1 +拒绝 1 +x:1 +夜工 1 +x:1 +画像砖 1 +x:1 +黑窝点 1 +x:1 +含绒量 1 +x:1 +浮翼 1 +x:1 +中长 1 +x:1 +寨子口 1 +x:1 +化学式 1 +x:1 +量力而行 1 +x:1 +信任率 1 +x:1 +中锋 1 +x:1 +做事 1 +x:1 +蜡渣子 1 +x:1 +悬灌梁 1 +x:1 +酋长 1 +x:1 +续盘 1 +x:1 +泥 49 +x:49 +力偶 1 +x:1 +客货车 1 +x:1 +上栗县 1 +x:1 +巴士式 1 +x:1 +单孔目 1 +x:1 +客货轮 1 +x:1 +微冻室 1 +x:1 +昌江 1 +x:1 +耗能 1 +x:1 +谋生 1 +x:1 +露底 1 +x:1 +点点头 1 +x:1 +寿宁县 1 +x:1 +党阀 1 +x:1 +扛回 1 +x:1 +一元化 1 +x:1 +一推双考 1 +x:1 +涤 3 +x:3 +污染区 1 +x:1 +产供 1 +x:1 +红巾起义 1 +x:1 +包庇罪 1 +x:1 +龙蛇混杂 1 +x:1 +承租者 1 +x:1 +私情 1 +x:1 +怒色 1 +x:1 +党际 1 +x:1 +有目共睹 1 +x:1 +能源系 1 +x:1 +池园 1 +x:1 +客货运 1 +x:1 +增订 1 +x:1 +献身 1 +x:1 +保险装置 1 +x:1 +核武器库 1 +x:1 +谵妄 1 +x:1 +湘黔 1 +x:1 +禁令 1 +x:1 +干干净净 1 +x:1 +大好人 1 +x:1 +内皮 1 +x:1 +点名 1 +x:1 +来历不明 1 +x:1 +外婆桥 1 +x:1 +订立 1 +x:1 +灰不溜秋 1 +x:1 +煤仓 1 +x:1 +日感迫切 1 +x:1 +毛货 1 +x:1 +店史 1 +x:1 +正气歌 1 +x:1 +少年犯 1 +x:1 +毛质 1 +x:1 +校园 1 +x:1 +胸部 1 +x:1 +异 45 +x:45 +属实 1 +x:1 +销售税 1 +x:1 +私有 1 +x:1 +店名 1 +x:1 +旋钮 1 +x:1 +加号 1 +x:1 +区区 1 +x:1 +糖蜜 1 +x:1 +露头 1 +x:1 +郭家乡 1 +x:1 +经贸委 1 +x:1 +蓝 143 +x:143 +根据 1 +x:1 +侦察兵 1 +x:1 +慰问袋 1 +x:1 +死鸡率 1 +x:1 +事业型 1 +x:1 +托收 1 +x:1 +露天 1 +x:1 +违章 1 +x:1 +宿愿 1 +x:1 +题型 1 +x:1 +偏安一隅 1 +x:1 +凉 23 +x:23 +跃身而起 1 +x:1 +桑给巴尔 1 +x:1 +托故 1 +x:1 +贡山 1 +x:1 +港上镇 1 +x:1 +石岩镇 1 +x:1 +甘甜 1 +x:1 +打哆嗦 1 +x:1 +聚糖 1 +x:1 +救难 1 +x:1 +茭道乡 1 +x:1 +店员 1 +x:1 +管理界 1 +x:1 +购货 1 +x:1 +愁眉锁眼 1 +x:1 +氛围 1 +x:1 +加压 1 +x:1 +虚套 1 +x:1 +懒汉 1 +x:1 +向着 1 +x:1 +汾阳路 1 +x:1 +加厚 1 +x:1 +地门 1 +x:1 +皮开肉绽 1 +x:1 +内焰 1 +x:1 +弛缓 1 +x:1 +素珠 1 +x:1 +点卯 1 +x:1 +地锚 1 +x:1 +判若两样 1 +x:1 +越共 1 +x:1 +赞成者 1 +x:1 +加印 1 +x:1 +区县 1 +x:1 +峨冠博带 1 +x:1 +轻轻松松 1 +x:1 +归置 1 +x:1 +舟山市 1 +x:1 +弦子 1 +x:1 +明察暗访 1 +x:1 +紫玉米 1 +x:1 +岔河镇 1 +x:1 +圣周末 1 +x:1 +森工 1 +x:1 +啄木鸟 1 +x:1 +贫困面 1 +x:1 +亢进症 1 +x:1 +视为畏途 1 +x:1 +太阳黑子 1 +x:1 +鸟市 1 +x:1 +空想 1 +x:1 +三苯锡 1 +x:1 +养老送终 1 +x:1 +天候 1 +x:1 +老气横秋 1 +x:1 +原委 1 +x:1 +难能可贵 1 +x:1 +火焰山 1 +x:1 +拒礼 1 +x:1 +珊 3 +x:3 +羽绒衣 1 +x:1 +初来者 1 +x:1 +伦次 1 +x:1 +钢枪 1 +x:1 +加区 1 +x:1 +自变量 1 +x:1 +瑛 21 +x:21 +户政科 1 +x:1 +彩扩部 1 +x:1 +顺 79 +x:79 +殿军 1 +x:1 +距平 1 +x:1 +就坡下驴 1 +x:1 +或是 1 +x:1 +恒产 1 +x:1 +卵 6 +x:6 +空情 1 +x:1 +发觉 1 +x:1 +殷实 1 +x:1 +殿内 1 +x:1 +吃偏饭 1 +x:1 +点化 1 +x:1 +发行款 1 +x:1 +真主党 1 +x:1 +佛祖 1 +x:1 +吆 1 +x:1 +村边 1 +x:1 +政策局 1 +x:1 +解读 1 +x:1 +气象所 1 +x:1 +雪连纸 1 +x:1 +解说 1 +x:1 +小人书 1 +x:1 +竹簧 1 +x:1 +制售者 1 +x:1 +桶装 1 +x:1 +吵醒 1 +x:1 +效能型 1 +x:1 +区分 1 +x:1 +南召县 1 +x:1 +商载 1 +x:1 +专业组 1 +x:1 +耳熟能详 1 +x:1 +瑞典化 1 +x:1 +题图 1 +x:1 +中高级 1 +x:1 +腾跃 1 +x:1 +崩决 1 +x:1 +区划 1 +x:1 +冲击钻 1 +x:1 +犯规 1 +x:1 +暂行 1 +x:1 +妇道人家 1 +x:1 +洞库 1 +x:1 +仍 2054 +x:2054 +农七师 1 +x:1 +入射角 1 +x:1 +脱销 1 +x:1 +地铁 1 +x:1 +雪莲 1 +x:1 +毒杂草 1 +x:1 +宿怨 1 +x:1 +阿城市 1 +x:1 +发表 1 +x:1 +婚 13 +x:13 +寿光市 1 +x:1 +万应灵丹 1 +x:1 +赠 76 +x:76 +党部 1 +x:1 +地铺 1 +x:1 +四十三分 1 +x:1 +峨金 1 +x:1 +文化学 1 +x:1 +赶排 1 +x:1 +按劳分配 1 +x:1 +牛性 1 +x:1 +洞庭 1 +x:1 +加力 1 +x:1 +惩处 1 +x:1 +宿怀 1 +x:1 +执迷 1 +x:1 +仰赖 1 +x:1 +加剧 1 +x:1 +离间 1 +x:1 +差不多 1 +x:1 +册亨县 1 +x:1 +老将队 1 +x:1 +临阵磨枪 1 +x:1 +不哼不哈 1 +x:1 +排练厅 1 +x:1 +同行 1 +x:1 +钥匙锁 1 +x:1 +文化宫 1 +x:1 +奥斯卡 1 +x:1 +可靠性 1 +x:1 +创巨痛深 1 +x:1 +玩笑 1 +x:1 +大声 1 +x:1 +文化室 1 +x:1 +盗车者 1 +x:1 +雷州市 1 +x:1 +鼓足干劲 1 +x:1 +棚架 1 +x:1 +红绳系足 1 +x:1 +莽汉 1 +x:1 +心海 1 +x:1 +恐慌 1 +x:1 +奶豆腐 1 +x:1 +再度 1 +x:1 +加利 1 +x:1 +酱瓜 1 +x:1 +野性 1 +x:1 +评比会 1 +x:1 +由明转暗 1 +x:1 +罗 1139 +x:1139 +鳖 9 +x:9 +血热型 1 +x:1 +净增 1 +x:1 +建房热 1 +x:1 +略阳 1 +x:1 +结构式 1 +x:1 +喘喘气 1 +x:1 +贻笑大方 1 +x:1 +遗传学家 1 +x:1 +假戏真做 1 +x:1 +与会国 1 +x:1 +聘任 1 +x:1 +徽标 1 +x:1 +雇用率 1 +x:1 +阳春砂 1 +x:1 +林业部 1 +x:1 +扭曲 1 +x:1 +工商局 1 +x:1 +总卡量 1 +x:1 +列项 1 +x:1 +堆龙德庆 1 +x:1 +油门 1 +x:1 +南林大 1 +x:1 +信访量 1 +x:1 +泡蘑菇 1 +x:1 +截瘫病 1 +x:1 +拜谒者 1 +x:1 +岗 147 +x:147 +苹果酱 1 +x:1 +链条 1 +x:1 +拉丁美州 1 +x:1 +用武 1 +x:1 +绿叶儿 1 +x:1 +春阳 1 +x:1 +春防 1 +x:1 +购车 1 +x:1 +跟 413 +x:413 +纷繁 1 +x:1 +河流乡 1 +x:1 +锲 9 +x:9 +毛裤 1 +x:1 +脱险 1 +x:1 +宅邸 1 +x:1 +喜从天降 1 +x:1 +村貌 1 +x:1 +人代会 1 +x:1 +贻害 1 +x:1 +防渗渠 1 +x:1 +金科玉律 1 +x:1 +亲临 1 +x:1 +比目鱼 1 +x:1 +草芙蓉 1 +x:1 +毛袜 1 +x:1 +一树了之 1 +x:1 +中途 1 +x:1 +商谈 1 +x:1 +中速 1 +x:1 +拱廊 1 +x:1 +常宁市 1 +x:1 +濡 1 +x:1 +舞人 1 +x:1 +砖坝 1 +x:1 +大开大合 1 +x:1 +离队 1 +x:1 +原子能部 1 +x:1 +委员会 1 +x:1 +加冕 1 +x:1 +消基会 1 +x:1 +黄金水道 1 +x:1 +同苦 1 +x:1 +三塔集镇 1 +x:1 +自主性 1 +x:1 +枣皮 1 +x:1 +加入 1 +x:1 +劈 20 +x:20 +埋怨 1 +x:1 +高血糖 1 +x:1 +栏 50 +x:50 +丹佛市 1 +x:1 +地震 1 +x:1 +溶雪剂 1 +x:1 +购进 1 +x:1 +滑雪服 1 +x:1 +加元 1 +x:1 +封闭疗法 1 +x:1 +星象学 1 +x:1 +抨 1 +x:1 +地霸 1 +x:1 +露宿 1 +x:1 +中部 1 +x:1 +满面红光 1 +x:1 +毛衣 1 +x:1 +瘪嘴 1 +x:1 +老相识 1 +x:1 +心灵手巧 1 +x:1 +欹 2 +x:2 +边缘科学 1 +x:1 +易地做官 1 +x:1 +白花蛇 1 +x:1 +牛排 1 +x:1 +垂头丧气 1 +x:1 +春雨 1 +x:1 +春雪 1 +x:1 +敲门声 1 +x:1 +纷纭 1 +x:1 +佛窟 1 +x:1 +轧花厂 1 +x:1 +纷纷 1 +x:1 +旒 1 +x:1 +运销 1 +x:1 +点儿 1 +x:1 +振振有辞 1 +x:1 +权术 1 +x:1 +春雷 1 +x:1 +灵秀 1 +x:1 +哺育 1 +x:1 +如日中天 1 +x:1 +辎重 1 +x:1 +经侦处 1 +x:1 +发话 1 +x:1 +渐食 1 +x:1 +取食机 1 +x:1 +地面 1 +x:1 +留落 1 +x:1 +荆芥 1 +x:1 +放大器 1 +x:1 +净宽 1 +x:1 +吐露 1 +x:1 +汤那屯 1 +x:1 +足印 1 +x:1 +高抬贵手 1 +x:1 +皇亲国戚 1 +x:1 +虚名 1 +x:1 +解解 1 +x:1 +渔户 1 +x:1 +包产户 1 +x:1 +意面 1 +x:1 +文化处 1 +x:1 +瞳孔 1 +x:1 +暑 5 +x:5 +超范围 1 +x:1 +再山 1 +x:1 +脔 1 +x:1 +污染型 1 +x:1 +滇剧 1 +x:1 +总决赛 1 +x:1 +遗传所 1 +x:1 +制锁业 1 +x:1 +地 15342 +x:15342 +棚改 1 +x:1 +安新县 1 +x:1 +水仙花头 1 +x:1 +关停并转 1 +x:1 +题咏 1 +x:1 +店址 1 +x:1 +阴阳历 1 +x:1 +亚利桑那 1 +x:1 +材 11 +x:11 +桂香新村 1 +x:1 +云遮雾障 1 +x:1 +卸任 1 +x:1 +私摘 1 +x:1 +颗颗 1 +x:1 +黑钙土 1 +x:1 +消毒学 1 +x:1 +地雷 1 +x:1 +商贸 1 +x:1 +苞米 1 +x:1 +郁山镇 1 +x:1 +商贾 1 +x:1 +并条机 1 +x:1 +活脱脱 1 +x:1 +芝麻油 1 +x:1 +商贩 1 +x:1 +调整 1 +x:1 +横膈膜 1 +x:1 +干饭 1 +x:1 +买空卖空 1 +x:1 +夹层玻璃 1 +x:1 +乌拉草 1 +x:1 +漫灌 1 +x:1 +概算 1 +x:1 +中金 1 +x:1 +以谬袭谬 1 +x:1 +梁四村 1 +x:1 +b##b 825857 +x:825857 +艰苦处 1 +x:1 +要旨 1 +x:1 +无声 1 +x:1 +麝鼠 1 +x:1 +见风使舵 1 +x:1 +宁馨儿 1 +x:1 +屯田 1 +x:1 +安福县 1 +x:1 +户均 1 +x:1 +舞会 1 +x:1 +轻捷 1 +x:1 +锡林郭勒 1 +x:1 +盆 81 +x:81 +航程 1 +x:1 +殿中房 1 +x:1 +应承担 1 +x:1 +挡雨棚 1 +x:1 +残次林 1 +x:1 +屯留 1 +x:1 +都市型 1 +x:1 +春韵 1 +x:1 +取齐 1 +x:1 +茧子 1 +x:1 +结合点 1 +x:1 +舞伴 1 +x:1 +加倍 1 +x:1 +素炒 1 +x:1 +纳税户 1 +x:1 +拱形 1 +x:1 +冠心病 1 +x:1 +殷墟 1 +x:1 +错作 1 +x:1 +道班长 1 +x:1 +驻足 1 +x:1 +降级 1 +x:1 +结合体 1 +x:1 +骤雨 1 +x:1 +涨价 1 +x:1 +稀世 1 +x:1 +回旋度 1 +x:1 +片言 1 +x:1 +行草 1 +x:1 +角部 1 +x:1 +食团问卜 1 +x:1 +卷内 1 +x:1 +追根溯源 1 +x:1 +市俗化 1 +x:1 +储蓄额 1 +x:1 +余风 1 +x:1 +溧阳县 1 +x:1 +古音 1 +x:1 +直立茎 1 +x:1 +论题 1 +x:1 +号志灯 1 +x:1 +争论不休 1 +x:1 +池洞 1 +x:1 +白闪闪 1 +x:1 +非均衡 1 +x:1 +协会性 1 +x:1 +机降 1 +x:1 +好自为之 1 +x:1 +坟茔 1 +x:1 +漂泊 1 +x:1 +剌 1 +x:1 +马哲史 1 +x:1 +私存 1 +x:1 +华北路 1 +x:1 +流食 1 +x:1 +工控机 1 +x:1 +深沟高垒 1 +x:1 +汾河湾 1 +x:1 +泳 15 +x:15 +桂阳 1 +x:1 +不等号 1 +x:1 +原审 1 +x:1 +幕落 1 +x:1 +服务区 1 +x:1 +私宅 1 +x:1 +罪恶滔天 1 +x:1 +因地制宜 1 +x:1 +夸大其辞 1 +x:1 +命令状 1 +x:1 +着笔 1 +x:1 +播放点 1 +x:1 +鱿鱼 1 +x:1 +检票口 1 +x:1 +下铺 1 +x:1 +私定 1 +x:1 +研修班 1 +x:1 +本世纪 1 +x:1 +冬麦 1 +x:1 +宿州 1 +x:1 +骤降 1 +x:1 +时装 1 +x:1 +佳丽 1 +x:1 +茱萸 1 +x:1 +涿州市 1 +x:1 +手儿 1 +x:1 +温暖如春 1 +x:1 +个顶个 1 +x:1 +小解 1 +x:1 +徽商 1 +x:1 +私家 1 +x:1 +青森县 1 +x:1 +消瘦 1 +x:1 +鸿 60 +x:60 +卷入 1 +x:1 +保管室 1 +x:1 +近水楼台 1 +x:1 +药政局 1 +x:1 +白矮星 1 +x:1 +蕙 1 +x:1 +中线 1 +x:1 +扬中市 1 +x:1 +乡规 1 +x:1 +白皑皑 1 +x:1 +情话 1 +x:1 +角逐 1 +x:1 +散热器 1 +x:1 +谋事 1 +x:1 +赠者 1 +x:1 +腕子 1 +x:1 +府尹 1 +x:1 +题款 1 +x:1 +加演 1 +x:1 +阴阳水 1 +x:1 +低幼儿 1 +x:1 +临海市 1 +x:1 +五指峰 1 +x:1 +腹中 1 +x:1 +庄家沟村 1 +x:1 +赶快 1 +x:1 +农科所 1 +x:1 +牌坊村 1 +x:1 +超短裙 1 +x:1 +俯拾即是 1 +x:1 +苍耳 1 +x:1 +元首会 1 +x:1 +榛 3 +x:3 +皎娇 1 +x:1 +点滴 1 +x:1 +牛山 1 +x:1 +扼腕 1 +x:1 +苍老 1 +x:1 +迷宫式 1 +x:1 +德育乡 1 +x:1 +产生 1 +x:1 +霍尔木兹 1 +x:1 +小人物 1 +x:1 +晋谒 1 +x:1 +击退 1 +x:1 +团员证 1 +x:1 +赶忙 1 +x:1 +妻 53 +x:53 +得人心 1 +x:1 +植绿护绿 1 +x:1 +乔治 1 +x:1 +晋豫 1 +x:1 +文化权 1 +x:1 +尊长 1 +x:1 +轻巧 1 +x:1 +圣战者 1 +x:1 +轻工 1 +x:1 +克格勃 1 +x:1 +桂霞 1 +x:1 +棚子 1 +x:1 +以太网 1 +x:1 +赶往 1 +x:1 +速滑馆 1 +x:1 +小夜曲 1 +x:1 +浮想 1 +x:1 +恧 1 +x:1 +座右铭 1 +x:1 +超大穗 1 +x:1 +柯 54 +x:54 +中纺 1 +x:1 +片警 1 +x:1 +二期 1 +x:1 +管乐团 1 +x:1 +陶庙 1 +x:1 +丹江口 1 +x:1 +问诊 1 +x:1 +洪流滚滚 1 +x:1 +素以 1 +x:1 +安丘市 1 +x:1 +各行其是 1 +x:1 +五七年 1 +x:1 +下门 1 +x:1 +窖藏 1 +x:1 +池河 1 +x:1 +问话 1 +x:1 +岗哨 1 +x:1 +同业公会 1 +x:1 +及格线 1 +x:1 +池沼 1 +x:1 +特异性 1 +x:1 +安身之地 1 +x:1 +渔岙 1 +x:1 +棚室 1 +x:1 +般般 1 +x:1 +印迹 1 +x:1 +户籍警 1 +x:1 +老奸巨猾 1 +x:1 +动脑筋 1 +x:1 +傩戏 1 +x:1 +盗用 1 +x:1 +储水柜 1 +x:1 +糟粕 1 +x:1 +精 153 +x:153 +贷存比 1 +x:1 +科盲 1 +x:1 +保释金 1 +x:1 +歇 23 +x:23 +佳作 1 +x:1 +凯雷什镇 1 +x:1 +加温 1 +x:1 +勒马尔歇 1 +x:1 +球墨铸铁 1 +x:1 +要官 1 +x:1 +立宪派 1 +x:1 +科目 1 +x:1 +慈云寺 1 +x:1 +洞房 1 +x:1 +米泉市 1 +x:1 +管乐器 1 +x:1 +政权机关 1 +x:1 +思绪 1 +x:1 +共治 1 +x:1 +下院 1 +x:1 +五六月份 1 +x:1 +照明弹 1 +x:1 +再 5272 +x:5272 +苍茫 1 +x:1 +圣砾砚斋 1 +x:1 +汇演 1 +x:1 +下陷 1 +x:1 +轻度 1 +x:1 +蜥蜴 1 +x:1 +遮天蔽日 1 +x:1 +要塞 1 +x:1 +发话器 1 +x:1 +安民济世 1 +x:1 +生产资料 1 +x:1 +碧 14 +x:14 +文盲率 1 +x:1 +认识 1 +x:1 +野心 1 +x:1 +下降 1 +x:1 +认证 1 +x:1 +扭头 1 +x:1 +下限 1 +x:1 +植物纤维 1 +x:1 +水 1300 +x:1300 +舞狮 1 +x:1 +不容忽视 1 +x:1 +贸易量 1 +x:1 +种业 1 +x:1 +用场 1 +x:1 +交响团 1 +x:1 +认认 1 +x:1 +私奔 1 +x:1 +续保 1 +x:1 +整场 1 +x:1 +托子 1 +x:1 +体贴 1 +x:1 +潞 1 +x:1 +出入境 1 +x:1 +印谱 1 +x:1 +用土 1 +x:1 +发行员 1 +x:1 +乌石乡 1 +x:1 +变本加厉 1 +x:1 +莽原 1 +x:1 +羊卓雍湖 1 +x:1 +西奈山 1 +x:1 +分流率 1 +x:1 +洋媳妇 1 +x:1 +降糖 1 +x:1 +办事组 1 +x:1 +宿弊 1 +x:1 +下阕 1 +x:1 +屏气凝神 1 +x:1 +炭精 1 +x:1 +荷重 1 +x:1 +欧溪乡 1 +x:1 +下雪 1 +x:1 +下雨 1 +x:1 +内保 1 +x:1 +本垒打 1 +x:1 +凉爽呢 1 +x:1 +整地 1 +x:1 +访问团 1 +x:1 +加时赛 1 +x:1 +期考 1 +x:1 +潘杰维 1 +x:1 +绕膝 1 +x:1 +剃发易制 1 +x:1 +下集 1 +x:1 +法立特 1 +x:1 +新近性 1 +x:1 +缩 19 +x:19 +感冒片 1 +x:1 +无边无涯 1 +x:1 +自力更生 1 +x:1 +杀鸡取卵 1 +x:1 +极目 1 +x:1 +艄板 1 +x:1 +合法化 1 +x:1 +达拉斯 1 +x:1 +鳗鱼 1 +x:1 +豪言 1 +x:1 +曲辞 1 +x:1 +契税 1 +x:1 +碑记 1 +x:1 +晃 20 +x:20 +愤愤不平 1 +x:1 +内侄 1 +x:1 +和风细雨 1 +x:1 +千锤百炼 1 +x:1 +警组制 1 +x:1 +荡人心魄 1 +x:1 +拱手 1 +x:1 +刊载 1 +x:1 +烂账 1 +x:1 +心声 1 +x:1 +短剑 1 +x:1 +饱食终日 1 +x:1 +超大规模 1 +x:1 +珍闻 1 +x:1 +换位 1 +x:1 +内侧 1 +x:1 +各有千秋 1 +x:1 +永葆 1 +x:1 +在野党派 1 +x:1 +饶有兴致 1 +x:1 +外房 1 +x:1 +配偶 1 +x:1 +舟楫 1 +x:1 +波黑 1 +x:1 +和龙市 1 +x:1 +拂拭 1 +x:1 +带伤 1 +x:1 +书道会 1 +x:1 +止痛 1 +x:1 +妥当 1 +x:1 +下面 1 +x:1 +老年病学 1 +x:1 +菊酯类 1 +x:1 +口服心服 1 +x:1 +赶工 1 +x:1 +赶巧 1 +x:1 +蜡质 1 +x:1 +加注 1 +x:1 +上半年 1 +x:1 +气象局 1 +x:1 +三加大 1 +x:1 +换亲 1 +x:1 +俯首称臣 1 +x:1 +贸易部 1 +x:1 +炉灶 1 +x:1 +轻微 1 +x:1 +换人 1 +x:1 +钩沉 1 +x:1 +锤 20 +x:20 +经济界 1 +x:1 +撤诉 1 +x:1 +继电器 1 +x:1 +内乡 1 +x:1 +炉火 1 +x:1 +豆瓣儿酱 1 +x:1 +长山村 1 +x:1 +加法 1 +x:1 +有司 1 +x:1 +内乱 1 +x:1 +区民 1 +x:1 +沙发椅子 1 +x:1 +擅 12 +x:12 +掌中宝 1 +x:1 +换代 1 +x:1 +停车楼 1 +x:1 +国骂 1 +x:1 +豪语 1 +x:1 +轻快 1 +x:1 +加油 1 +x:1 +死而后已 1 +x:1 +死而后己 1 +x:1 +国政系 1 +x:1 +潮涨潮落 1 +x:1 +哥 26 +x:26 +危象 1 +x:1 +推广性 1 +x:1 +友舰 1 +x:1 +巡视员 1 +x:1 +职高 1 +x:1 +化学厂 1 +x:1 +修身砺德 1 +x:1 +夫人 1 +x:1 +加沙 1 +x:1 +购种卡 1 +x:1 +私塾 1 +x:1 +主客场 1 +x:1 +故而 1 +x:1 +走运 1 +x:1 +走近 1 +x:1 +密云 1 +x:1 +走进 1 +x:1 +窑洞式 1 +x:1 +工商户 1 +x:1 +淡水湖 1 +x:1 +晚礼服 1 +x:1 +走过 1 +x:1 +中美洲 1 +x:1 +泪如雨下 1 +x:1 +若想 1 +x:1 +军歌声 1 +x:1 +韦驮殿 1 +x:1 +塑胶 1 +x:1 +换上 1 +x:1 +缺额 1 +x:1 +惊险 1 +x:1 +状 47 +x:47 +防腐败法 1 +x:1 +妥帖 1 +x:1 +钢丝绳 1 +x:1 +狱卒 1 +x:1 +内争 1 +x:1 +内事 1 +x:1 +程控化 1 +x:1 +透光度 1 +x:1 +里 4580 +x:4580 +畏 11 +x:11 +等效电路 1 +x:1 +爱莫能助 1 +x:1 +牛庄 1 +x:1 +反复性 1 +x:1 +分道扬镳 1 +x:1 +热问题 1 +x:1 +渣子 1 +x:1 +驰援 1 +x:1 +安居房 1 +x:1 +苍苍 1 +x:1 +内交 1 +x:1 +中铁建 1 +x:1 +米歇尔 1 +x:1 +席地而坐 1 +x:1 +方铅矿 1 +x:1 +工商所 1 +x:1 +舟桥 1 +x:1 +换乘 1 +x:1 +内亲 1 +x:1 +闵行区 1 +x:1 +肃 19 +x:19 +会议性 1 +x:1 +切实用 1 +x:1 +私弊 1 +x:1 +盲目性 1 +x:1 +用具 1 +x:1 +用兵 1 +x:1 +抛弃 1 +x:1 +迅速 1 +x:1 +婺绿 1 +x:1 +肥乎乎 1 +x:1 +本州岛 1 +x:1 +包谷壳 1 +x:1 +设计 1 +x:1 +意向表 1 +x:1 +一传十 1 +x:1 +晴空 1 +x:1 +丰衣足食 1 +x:1 +碰 56 +x:56 +经济片 1 +x:1 +铸成大错 1 +x:1 +榆次 1 +x:1 +气象学 1 +x:1 +角铁 1 +x:1 +创始人 1 +x:1 +坎坷不平 1 +x:1 +吉普车 1 +x:1 +文化户 1 +x:1 +凯隆堡 1 +x:1 +牌子 1 +x:1 +白塔 1 +x:1 +比赛场 1 +x:1 +惊醒 1 +x:1 +小汽车 1 +x:1 +角钢 1 +x:1 +敖 2 +x:2 +玻璃舱 1 +x:1 +晋西 1 +x:1 +围棋赛 1 +x:1 +赤 11 +x:11 +方针 1 +x:1 +孵化场 1 +x:1 +上半夜 1 +x:1 +全球化 1 +x:1 +意见卡 1 +x:1 +苇叶 1 +x:1 +牛头 1 +x:1 +娓娓 1 +x:1 +炊具 1 +x:1 +再有 1 +x:1 +掌上明珠 1 +x:1 +血毒症 1 +x:1 +辞赋 1 +x:1 +救助点 1 +x:1 +宿处 1 +x:1 +丹麦王国 1 +x:1 +万 2473 +x:2473 +氧化硫 1 +x:1 +希阿岛 1 +x:1 +下部 1 +x:1 +接线柱 1 +x:1 +算算 1 +x:1 +电性能 1 +x:1 +恃才傲物 1 +x:1 +为官一任 1 +x:1 +慢棋 1 +x:1 +狱吏 1 +x:1 +甡 1 +x:1 +点歌 1 +x:1 +天时地利 1 +x:1 +护士长 1 +x:1 +桂皮树 1 +x:1 +三义庙 1 +x:1 +转机 1 +x:1 +腕式 1 +x:1 +铁交椅 1 +x:1 +私德 1 +x:1 +前锋线 1 +x:1 +金桥区 1 +x:1 +鹿冈乡 1 +x:1 +私心 1 +x:1 +认购 1 +x:1 +认账 1 +x:1 +龙蟠里 1 +x:1 +增生 1 +x:1 +方头鞋 1 +x:1 +夸大其词 1 +x:1 +火腿肠 1 +x:1 +科班 1 +x:1 +苦槠 1 +x:1 +结果 1 +x:1 +渔姑 1 +x:1 +火腿肉 1 +x:1 +认负 1 +x:1 +私念 1 +x:1 +极点 1 +x:1 +织锦缎 1 +x:1 +野外 1 +x:1 +专用道 1 +x:1 +转速比 1 +x:1 +夹克衫 1 +x:1 +之间 1 +x:1 +约旦河 1 +x:1 +达卡 1 +x:1 +内敛性 1 +x:1 +军官证 1 +x:1 +全色片 1 +x:1 +角门 1 +x:1 +东躲西藏 1 +x:1 +诊疗费 1 +x:1 +刀把儿 1 +x:1 +沙荒 1 +x:1 +矢志不移 1 +x:1 +财价字 1 +x:1 +舆论 1 +x:1 +诗会 1 +x:1 +孵化器 1 +x:1 +吕梁山 1 +x:1 +地摊儿 1 +x:1 +刃儿 1 +x:1 +托尼 1 +x:1 +帏幕 1 +x:1 +露怯 1 +x:1 +若是 1 +x:1 +时贤 1 +x:1 +锚固 1 +x:1 +勇猛 1 +x:1 +集安市 1 +x:1 +小山子镇 1 +x:1 +演出队 1 +x:1 +盐环定 1 +x:1 +珊瑚礁 1 +x:1 +川鄂 1 +x:1 +匹俦 1 +x:1 +战乱 1 +x:1 +信天游 1 +x:1 +火星儿 1 +x:1 +救危排险 1 +x:1 +公证室 1 +x:1 +元山市 1 +x:1 +提高型 1 +x:1 +消石灰 1 +x:1 +人行横道 1 +x:1 +聚光灯 1 +x:1 +结构 1 +x:1 +火 302 +x:302 +硬邦邦 1 +x:1 +兵役制 1 +x:1 +夯砣 1 +x:1 +自力图强 1 +x:1 +信封 1 +x:1 +印证 1 +x:1 +焕彩 1 +x:1 +蜘蛛抱蛋 1 +x:1 +仓储式 1 +x:1 +撤走 1 +x:1 +犯难 1 +x:1 +蔫 5 +x:5 +圣胡安岛 1 +x:1 +下野 1 +x:1 +聚光点 1 +x:1 +象限 1 +x:1 +博望镇 1 +x:1 +泣不成声 1 +x:1 +天文台 1 +x:1 +隐身草 1 +x:1 +发行史 1 +x:1 +赴汤蹈火 1 +x:1 +刊行 1 +x:1 +缓付 1 +x:1 +氧气瓶 1 +x:1 +宿墨 1 +x:1 +原子 1 +x:1 +空降兵 1 +x:1 +跪拜 1 +x:1 +印记 1 +x:1 +林盘地 1 +x:1 +扼腕叹息 1 +x:1 +朱德 1 +x:1 +行贿人 1 +x:1 +念经 1 +x:1 +线绳 1 +x:1 +银 121 +x:121 +磺胺脒 1 +x:1 +走卒 1 +x:1 +魂魄 1 +x:1 +徽号 1 +x:1 +辅导站 1 +x:1 +自始至终 1 +x:1 +遗传学 1 +x:1 +信道 1 +x:1 +引水渠 1 +x:1 +阜新市 1 +x:1 +炊烟袅袅 1 +x:1 +农科教 1 +x:1 +后半段 1 +x:1 +契约 1 +x:1 +炸子儿 1 +x:1 +印行 1 +x:1 +聘用 1 +x:1 +弃置 1 +x:1 +靖远县 1 +x:1 +跌跌撞撞 1 +x:1 +盆竹 1 +x:1 +沟王寨村 1 +x:1 +文化性 1 +x:1 +齿斑 1 +x:1 +枣业 1 +x:1 +妥实 1 +x:1 +非工程 1 +x:1 +输精管 1 +x:1 +回嗔作喜 1 +x:1 +占优 1 +x:1 +角雉 1 +x:1 +求谋问计 1 +x:1 +市政府办 1 +x:1 +棚屋 1 +x:1 +两高一优 1 +x:1 +乖觉 1 +x:1 +徽县 1 +x:1 +行径 1 +x:1 +孝里镇 1 +x:1 +冻猪肉 1 +x:1 +骗婚 1 +x:1 +产物 1 +x:1 +燃放点 1 +x:1 +苍蝇 1 +x:1 +卧床不起 1 +x:1 +白剧团 1 +x:1 +惩戒 1 +x:1 +葬 7 +x:7 +永胜 1 +x:1 +蔚为大观 1 +x:1 +议价粮 1 +x:1 +认输 1 +x:1 +介绍费 1 +x:1 +熟食 1 +x:1 +门脸 1 +x:1 +强迫式 1 +x:1 +渔家 1 +x:1 +软锰矿 1 +x:1 +夺目 1 +x:1 +倏 2 +x:2 +重版 1 +x:1 +暖色调 1 +x:1 +多宝港 1 +x:1 +李四光 1 +x:1 +妃子 1 +x:1 +仙客来 1 +x:1 +笆篓 1 +x:1 +大朴大拙 1 +x:1 +巴士拉 1 +x:1 +液 3 +x:3 +匹 43 +x:43 +麻油 1 +x:1 +连续剧 1 +x:1 +形神各异 1 +x:1 +马兰 1 +x:1 +航海学家 1 +x:1 +贼头贼脑 1 +x:1 +叶块繁殖 1 +x:1 +文昌市 1 +x:1 +西平乐乡 1 +x:1 +性腺 1 +x:1 +董家山村 1 +x:1 +钉子户 1 +x:1 +武术馆校 1 +x:1 +问 1092 +x:1092 +无线电报 1 +x:1 +方阵 1 +x:1 +刑事 1 +x:1 +森林 1 +x:1 +靡 2 +x:2 +布尔奇科 1 +x:1 +遗赠 1 +x:1 +注意力 1 +x:1 +私己 1 +x:1 +屋角 1 +x:1 +方队 1 +x:1 +消灭 1 +x:1 +追赠 1 +x:1 +榆树 1 +x:1 +瑶绣 1 +x:1 +出站口 1 +x:1 +红光光 1 +x:1 +托市 1 +x:1 +妇保 1 +x:1 +盈利额 1 +x:1 +私小 1 +x:1 +轮采 1 +x:1 +庑 1 +x:1 +宽银幕 1 +x:1 +陶壶 1 +x:1 +插秧 1 +x:1 +铸石 1 +x:1 +方音 1 +x:1 +陈屋坡 1 +x:1 +小吃部 1 +x:1 +检票员 1 +x:1 +找事 1 +x:1 +渔娘 1 +x:1 +监事会 1 +x:1 +宋古乡 1 +x:1 +积不相能 1 +x:1 +昏庸辈 1 +x:1 +悲伤欲绝 1 +x:1 +管理业 1 +x:1 +独联体 1 +x:1 +海产品 1 +x:1 +章则 1 +x:1 +性能 1 +x:1 +耗资量 1 +x:1 +力求 1 +x:1 +磕 4 +x:4 +骗子 1 +x:1 +鄂州 1 +x:1 +非盈利 1 +x:1 +点电荷 1 +x:1 +炒汇 1 +x:1 +豪迈 1 +x:1 +托幼 1 +x:1 +结算关 1 +x:1 +奖学金 1 +x:1 +村民会 1 +x:1 +库马西 1 +x:1 +方面 1 +x:1 +化学变化 1 +x:1 +一定之规 1 +x:1 +徽剧 1 +x:1 +管理人 1 +x:1 +埋头 1 +x:1 +相控阵 1 +x:1 +崂山区 1 +x:1 +托底 1 +x:1 +西丫口 1 +x:1 +急火火 1 +x:1 +骗客 1 +x:1 +问路 1 +x:1 +贝 21 +x:21 +阴阳步 1 +x:1 +对手戏 1 +x:1 +外文课 1 +x:1 +话剧院团 1 +x:1 +性者 1 +x:1 +唯利是图 1 +x:1 +赶奔 1 +x:1 +大北窑 1 +x:1 +章 360 +x:360 +原子能局 1 +x:1 +属性 1 +x:1 +甘于 1 +x:1 +廉租 1 +x:1 +仆 1 +x:1 +点校 1 +x:1 +房产商 1 +x:1 +时辰 1 +x:1 +物态 1 +x:1 +转战 1 +x:1 +四环东路 1 +x:1 +碑身 1 +x:1 +大运河 1 +x:1 +用力 1 +x:1 +待就业 1 +x:1 +用功 1 +x:1 +越位 1 +x:1 +卖身契 1 +x:1 +走访 1 +x:1 +门联 1 +x:1 +吨公里 1 +x:1 +司 87 +x:87 +燃具 1 +x:1 +搜身 1 +x:1 +接班人 1 +x:1 +图腾式 1 +x:1 +炭盆 1 +x:1 +防寒屋 1 +x:1 +北齐人 1 +x:1 +红旗街 1 +x:1 +垂花门 1 +x:1 +红花草 1 +x:1 +核磁检查 1 +x:1 +钓 32 +x:32 +萍乡市 1 +x:1 +原子核 1 +x:1 +妥善 1 +x:1 +徽州 1 +x:1 +训 54 +x:54 +大瓦窑村 1 +x:1 +公证团 1 +x:1 +卢森堡队 1 +x:1 +走回头路 1 +x:1 +冬防 1 +x:1 +托儿 1 +x:1 +饱和度 1 +x:1 +短短的 1 +x:1 +点染 1 +x:1 +圆圆的 1 +x:1 +赶回 1 +x:1 +奥斯曼 1 +x:1 +北河乡 1 +x:1 +篮球赛 1 +x:1 +再次 1 +x:1 +棱台 1 +x:1 +团结友爱 1 +x:1 +蜡虫 1 +x:1 +拱棚 1 +x:1 +私协 1 +x:1 +灵位 1 +x:1 +景洪 1 +x:1 +毛纺织厂 1 +x:1 +要则 1 +x:1 +无穷期 1 +x:1 +陆陆续续 1 +x:1 +预制件 1 +x:1 +风电场 1 +x:1 +此案 1 +x:1 +煦 13 +x:13 +名节 1 +x:1 +时而 1 +x:1 +摄像室 1 +x:1 +囚衣 1 +x:1 +范画 1 +x:1 +腐蚀性 1 +x:1 +扩浇 1 +x:1 +婚外恋 1 +x:1 +榆林 1 +x:1 +衡山县 1 +x:1 +印纹陶 1 +x:1 +独奏曲 1 +x:1 +产粮 1 +x:1 +流通 1 +x:1 +流逝 1 +x:1 +流速 1 +x:1 +用工 1 +x:1 +加权 1 +x:1 +撤职 1 +x:1 +有所失 1 +x:1 +E 29 +x:29 +大葱 1 +x:1 +片花 1 +x:1 +侠义 1 +x:1 +一元性 1 +x:1 +俏销 1 +x:1 +临渴掘井 1 +x:1 +蒋家王朝 1 +x:1 +条块分割 1 +x:1 +碳化硅 1 +x:1 +才子佳人 1 +x:1 +阿 256 +x:256 +拉关系 1 +x:1 +惩治 1 +x:1 +闷闷地 1 +x:1 +赙 1 +x:1 +精算业 1 +x:1 +真人 1 +x:1 +要务 1 +x:1 +恐吓 1 +x:1 +白藤 1 +x:1 +玩乐 1 +x:1 +妥商 1 +x:1 +冬雪 1 +x:1 +冬雨 1 +x:1 +轿子 1 +x:1 +人如海 1 +x:1 +出粉率 1 +x:1 +梅州市 1 +x:1 +拱桥 1 +x:1 +月镜 1 +x:1 +小道消息 1 +x:1 +销售价 1 +x:1 +论道 1 +x:1 +出入口 1 +x:1 +宿命 1 +x:1 +神河 1 +x:1 +顺治元年 1 +x:1 +灵丘 1 +x:1 +私分 1 +x:1 +断壁残垣 1 +x:1 +问荆 1 +x:1 +光纤通信 1 +x:1 +茜 5 +x:5 +露水 1 +x:1 +红海村 1 +x:1 +叶纹 1 +x:1 +腕力 1 +x:1 +西工区 1 +x:1 +私利 1 +x:1 +测电笔 1 +x:1 +焕发 1 +x:1 +水乳交融 1 +x:1 +衰老期 1 +x:1 +疙瘩腔 1 +x:1 +祖先 1 +x:1 +耙耱 1 +x:1 +日新月异 1 +x:1 +冻 67 +x:67 +携带品 1 +x:1 +后悔莫及 1 +x:1 +伊朗 1 +x:1 +用尽 1 +x:1 +想方设法 1 +x:1 +流量 1 +x:1 +流金 1 +x:1 +自给性 1 +x:1 +起点处 1 +x:1 +冬青 1 +x:1 +昌平 1 +x:1 +罗汉松 1 +x:1 +波长 1 +x:1 +并线 1 +x:1 +无依无靠 1 +x:1 +文化潮 1 +x:1 +株洲市 1 +x:1 +维纶 1 +x:1 +捉迷藏式 1 +x:1 +谷斑皮蠹 1 +x:1 +不够意思 1 +x:1 +秕子 1 +x:1 +濯 4 +x:4 +腰 80 +x:80 +林芝县 1 +x:1 +净水 1 +x:1 +特伦托省 1 +x:1 +讨要 1 +x:1 +麻黄素 1 +x:1 +抗灾歌 1 +x:1 +安居梦 1 +x:1 +力抓 1 +x:1 +腹股沟 1 +x:1 +嵌入 1 +x:1 +陶器 1 +x:1 +千磨百折 1 +x:1 +类别 1 +x:1 +眉开眼笑 1 +x:1 +鄂北 1 +x:1 +客畅其行 1 +x:1 +科级 1 +x:1 +拖拉机厂 1 +x:1 +择善而从 1 +x:1 +野味 1 +x:1 +野病毒 1 +x:1 +推委会 1 +x:1 +方便卡 1 +x:1 +上层建筑 1 +x:1 +卖羊人 1 +x:1 +自怜 1 +x:1 +照镜子 1 +x:1 +千年一遇 1 +x:1 +乱葬岗 1 +x:1 +扭动 1 +x:1 +花花绿绿 1 +x:1 +力护 1 +x:1 +制鞋厂 1 +x:1 +罗汉果 1 +x:1 +狠心肠 1 +x:1 +庞各庄乡 1 +x:1 +骗保案 1 +x:1 +迄 8 +x:8 +园子 1 +x:1 +理由 1 +x:1 +试点站 1 +x:1 +多云间晴 1 +x:1 +知趣 1 +x:1 +西罗园 1 +x:1 +缎子 1 +x:1 +鄂南 1 +x:1 +赶场 1 +x:1 +地带 1 +x:1 +知足 1 +x:1 +算盘 1 +x:1 +鸥种 1 +x:1 +中介商 1 +x:1 +音序器 1 +x:1 +卧 45 +x:45 +点明 1 +x:1 +方便化 1 +x:1 +溃败 1 +x:1 +力拼 1 +x:1 +锻炼法 1 +x:1 +电唱机 1 +x:1 +扼要 1 +x:1 +脏源 1 +x:1 +伦巴 1 +x:1 +一整套 1 +x:1 +骋 2 +x:2 +妍 66 +x:66 +分业制 1 +x:1 +时艰 1 +x:1 +郁郁寡欢 1 +x:1 +发展党 1 +x:1 +胶东 1 +x:1 +温暖 1 +x:1 +倒好儿 1 +x:1 +王道 1 +x:1 +早餐 1 +x:1 +溶解氧 1 +x:1 +雨夹雪 1 +x:1 +卷宗 1 +x:1 +参加方 1 +x:1 +钗头凤 1 +x:1 +聘礼 1 +x:1 +岷江 1 +x:1 +使馆 1 +x:1 +德里市 1 +x:1 +横纲级 1 +x:1 +医药费 1 +x:1 +领衔 1 +x:1 +上半场 1 +x:1 +鹌鹑 1 +x:1 +贪根种心 1 +x:1 +珑 3 +x:3 +傲视 1 +x:1 +高新技术 1 +x:1 +李店乡 1 +x:1 +踏看 1 +x:1 +私党 1 +x:1 +间接选举 1 +x:1 +集合体 1 +x:1 +杞 1 +x:1 +斜架 1 +x:1 +百白破 1 +x:1 +好端端 1 +x:1 +彰显 1 +x:1 +牛场 1 +x:1 +池杉 1 +x:1 +释藏 1 +x:1 +甲天下 1 +x:1 +独个儿 1 +x:1 +气息奄奄 1 +x:1 +加料 1 +x:1 +侦察机 1 +x:1 +汗青 1 +x:1 +生地黄 1 +x:1 +氧气管 1 +x:1 +德新社 1 +x:1 +领袖 1 +x:1 +暴跌 1 +x:1 +色香味美 1 +x:1 +经济系 1 +x:1 +加数 1 +x:1 +瑶沟 1 +x:1 +公证员 1 +x:1 +角马 1 +x:1 +点数 1 +x:1 +牛城 1 +x:1 +性质 1 +x:1 +语音 1 +x:1 +眩 1 +x:1 +黑非洲 1 +x:1 +发展性 1 +x:1 +深知 1 +x:1 +闹饥荒 1 +x:1 +后半期 1 +x:1 +可乘之隙 1 +x:1 +湃 1 +x:1 +织布厂 1 +x:1 +题意 1 +x:1 +九时 1 +x:1 +加收 1 +x:1 +乔木 1 +x:1 +佛事 1 +x:1 +惜 30 +x:30 +圣玛丽亚 1 +x:1 +时节 1 +x:1 +缺量 1 +x:1 +城郊型 1 +x:1 +质量奖 1 +x:1 +打退堂鼓 1 +x:1 +寄兴寓情 1 +x:1 +酒瓶子 1 +x:1 +鼻洼子 1 +x:1 +卷子 1 +x:1 +硫酸 1 +x:1 +托叶 1 +x:1 +摄像头 1 +x:1 +气冲牛斗 1 +x:1 +前中期 1 +x:1 +吃里扒外 1 +x:1 +不以为然 1 +x:1 +壮行会 1 +x:1 +真丝 1 +x:1 +鼓囊囊 1 +x:1 +校订 1 +x:1 +侄外孙 1 +x:1 +白鹿泉乡 1 +x:1 +府城 1 +x:1 +一字师 1 +x:1 +中欣队 1 +x:1 +弃物 1 +x:1 +维系 1 +x:1 +冲扩点 1 +x:1 +拒付 1 +x:1 +实习生 1 +x:1 +′ 6 +x:6 +轻型 1 +x:1 +楚王陵 1 +x:1 +质优量足 1 +x:1 +贸易风 1 +x:1 +公里 1 +x:1 +讨论 1 +x:1 +泅 1 +x:1 +军规 1 +x:1 +章句 1 +x:1 +铸管 1 +x:1 +庆功宴 1 +x:1 +付诸实施 1 +x:1 +文城镇 1 +x:1 +门环子 1 +x:1 +里挑外撅 1 +x:1 +阿西西城 1 +x:1 +红七师 1 +x:1 +姑表亲 1 +x:1 +贸易额 1 +x:1 +绕行 1 +x:1 +炭疽 1 +x:1 +历险 1 +x:1 +埃及王国 1 +x:1 +斜晖 1 +x:1 +优抚对象 1 +x:1 +棚内 1 +x:1 +成瘾性 1 +x:1 +封丘县 1 +x:1 +事业性 1 +x:1 +无愧于心 1 +x:1 +意中人 1 +x:1 +自言自语 1 +x:1 +思 132 +x:132 +非常规 1 +x:1 +无性杂交 1 +x:1 +赖账 1 +x:1 +安检区 1 +x:1 +泡沫痰 1 +x:1 +事事处处 1 +x:1 +欣然 1 +x:1 +外语课 1 +x:1 +席间 1 +x:1 +邕城 1 +x:1 +章化 1 +x:1 +装作 1 +x:1 +尖头 1 +x:1 +降生 1 +x:1 +总罢工 1 +x:1 +考佬佬 1 +x:1 +赵李桥镇 1 +x:1 +快餐馆 1 +x:1 +荐举 1 +x:1 +接气 1 +x:1 +波音 1 +x:1 +用度 1 +x:1 +偷香窃玉 1 +x:1 +装装样子 1 +x:1 +粗细有致 1 +x:1 +冬间 1 +x:1 +要冲 1 +x:1 +冬闲 1 +x:1 +好榜样 1 +x:1 +七二年 1 +x:1 +性别 1 +x:1 +套语 1 +x:1 +炭画 1 +x:1 +雾 58 +x:58 +漂 15 +x:15 +促和 1 +x:1 +霞光 1 +x:1 +诺贝尔 1 +x:1 +消火栓 1 +x:1 +厕 12 +x:12 +坐山雕 1 +x:1 +防盗打器 1 +x:1 +前途无量 1 +x:1 +耕翻 1 +x:1 +冷热病 1 +x:1 +那波尔 1 +x:1 +议事日程 1 +x:1 +裤脚 1 +x:1 +大鼓手 1 +x:1 +医疗所 1 +x:1 +苗木费 1 +x:1 +真个 1 +x:1 +不进则退 1 +x:1 +拜天地 1 +x:1 +即席 1 +x:1 +东线组 1 +x:1 +渔具 1 +x:1 +喜读者 1 +x:1 +管弦高奏 1 +x:1 +军代处 1 +x:1 +书眉 1 +x:1 +拐角处 1 +x:1 +武夷山市 1 +x:1 +牛儿 1 +x:1 +亓 2 +x:2 +会议桌 1 +x:1 +门诊 1 +x:1 +有警必出 1 +x:1 +故迹 1 +x:1 +口出狂言 1 +x:1 +客运站 1 +x:1 +发轫期 1 +x:1 +用处 1 +x:1 +残次品 1 +x:1 +同日而语 1 +x:1 +不等式 1 +x:1 +登记本 1 +x:1 +其味无穷 1 +x:1 +言传 1 +x:1 +三水市 1 +x:1 +圆筒 1 +x:1 +科管 1 +x:1 +排浪式 1 +x:1 +隐蔽性 1 +x:1 +狼尾草 1 +x:1 +野兽 1 +x:1 +赣中南 1 +x:1 +题材 1 +x:1 +豪华化 1 +x:1 +要因 1 +x:1 +渔农 1 +x:1 +梅里达市 1 +x:1 +气象台 1 +x:1 +沼泽地 1 +x:1 +下风 1 +x:1 +豆酥糖 1 +x:1 +癌魔 1 +x:1 +蒲城县 1 +x:1 +湖北团 1 +x:1 +石榴石 1 +x:1 +造价款 1 +x:1 +最佳者 1 +x:1 +野兔 1 +x:1 +启动金 1 +x:1 +要图 1 +x:1 +车骑 1 +x:1 +嬉笑 1 +x:1 +安检员 1 +x:1 +蝶形花冠 1 +x:1 +复仇 1 +x:1 +沟沟峁峁 1 +x:1 +气象厅 1 +x:1 +改邪归正 1 +x:1 +赶制 1 +x:1 +奖助学 1 +x:1 +阴柔气 1 +x:1 +门警 1 +x:1 +武邑黄口 1 +x:1 +印花 1 +x:1 +神汉 1 +x:1 +酩 6 +x:6 +世外桃源 1 +x:1 +麻黄碱 1 +x:1 +双班制 1 +x:1 +下颌 1 +x:1 +健全度 1 +x:1 +威县 1 +x:1 +含泪 1 +x:1 +下颚 1 +x:1 +绕过 1 +x:1 +卡业 1 +x:1 +入乡随俗 1 +x:1 +盈亏 1 +x:1 +点拨 1 +x:1 +德西尔吉 1 +x:1 +棚圈 1 +x:1 +桂魂 1 +x:1 +托名 1 +x:1 +雄赳赳 1 +x:1 +过渡内阁 1 +x:1 +五四路 1 +x:1 +否 12 +x:12 +滋事 1 +x:1 +就地取材 1 +x:1 +府函 1 +x:1 +屋檐 1 +x:1 +太阳神队 1 +x:1 +固沙林 1 +x:1 +高点 1 +x:1 +裤腰 1 +x:1 +聚宝盆 1 +x:1 +井然有序 1 +x:1 +宿债 1 +x:1 +鄂城 1 +x:1 +绍 1 +x:1 +空明 1 +x:1 +港口镇 1 +x:1 +天文学 1 +x:1 +计其所短 1 +x:1 +咖啡楼 1 +x:1 +营业日 1 +x:1 +缺陷 1 +x:1 +徽墨 1 +x:1 +会议楼 1 +x:1 +走脱 1 +x:1 +声名鹊起 1 +x:1 +心静如水 1 +x:1 +导演组 1 +x:1 +蛋蛋 1 +x:1 +永诀 1 +x:1 +无鬼论 1 +x:1 +晋职 1 +x:1 +要地 1 +x:1 +鼓子词 1 +x:1 +签证处 1 +x:1 +一统天 1 +x:1 +梅山镇 1 +x:1 +暖 118 +x:118 +汗浸浸 1 +x:1 +羌 1 +x:1 +交际处 1 +x:1 +溧阳市 1 +x:1 +人心叵测 1 +x:1 +斑纹 1 +x:1 +卡塔赫纳 1 +x:1 +安慰话 1 +x:1 +旭日椅 1 +x:1 +马尼拉 1 +x:1 +透视学 1 +x:1 +煮饭 1 +x:1 +贫 53 +x:53 +聘约 1 +x:1 +经济篇 1 +x:1 +卡住 1 +x:1 +四色菊府 1 +x:1 +液态水 1 +x:1 +锹镐柄 1 +x:1 +掩人耳目 1 +x:1 +送礼者 1 +x:1 +店方 1 +x:1 +碎骨粉身 1 +x:1 +金鱼虫 1 +x:1 +轻兵 1 +x:1 +苛捐杂税 1 +x:1 +设色 1 +x:1 +私囊 1 +x:1 +相得益彰 1 +x:1 +用墨 1 +x:1 +陶制 1 +x:1 +肥田草 1 +x:1 +燕化 1 +x:1 +孤零零 1 +x:1 +特一级 1 +x:1 +产科 1 +x:1 +秉笔直书 1 +x:1 +鹳雀楼 1 +x:1 +铣刀 1 +x:1 +纷纭斑驳 1 +x:1 +军国主义 1 +x:1 +三孝口 1 +x:1 +扭困 1 +x:1 +一目十行 1 +x:1 +拍照费 1 +x:1 +量子 1 +x:1 +迁都 1 +x:1 +流长 1 +x:1 +私图 1 +x:1 +渔区 1 +x:1 +有所得 1 +x:1 +肠套叠 1 +x:1 +啧啧称赞 1 +x:1 +晋冀鲁豫 1 +x:1 +梅陇 1 +x:1 +下马 1 +x:1 +李先念 1 +x:1 +纷乱 1 +x:1 +要员 1 +x:1 +野史 1 +x:1 +追记 1 +x:1 +击鼓 1 +x:1 +题旨 1 +x:1 +浅水藕 1 +x:1 +屋脊 1 +x:1 +圆窗 1 +x:1 +汉语拼音 1 +x:1 +大象村 1 +x:1 +琼楼玉宇 1 +x:1 +七星河 1 +x:1 +一传奖 1 +x:1 +卡贝略港 1 +x:1 +天地 1 +x:1 +俄顷 1 +x:1 +歼敌 1 +x:1 +懋功 1 +x:1 +抛售 1 +x:1 +抗震救灾 1 +x:1 +刊 38 +x:38 +巴里坤县 1 +x:1 +府办 1 +x:1 +哇哇 1 +x:1 +出谋献策 1 +x:1 +金鱼藻 1 +x:1 +陶冶 1 +x:1 +吡啶 1 +x:1 +音板 1 +x:1 +残协委 1 +x:1 +上岗费 1 +x:1 +追认 1 +x:1 +水位站 1 +x:1 +论集 1 +x:1 +录入卡 1 +x:1 +勤学苦练 1 +x:1 +消磨 1 +x:1 +创建 1 +x:1 +令旗 1 +x:1 +玄乎 1 +x:1 +租建 1 +x:1 +盛怒 1 +x:1 +上半叶 1 +x:1 +建筑物 1 +x:1 +徽学 1 +x:1 +代代相传 1 +x:1 +轻判 1 +x:1 +陶养 1 +x:1 +凛若冰霜 1 +x:1 +惊魂 1 +x:1 +苏门答腊 1 +x:1 +控制论 1 +x:1 +梯田化 1 +x:1 +梅雨 1 +x:1 +千古不朽 1 +x:1 +动 317 +x:317 +金蝉脱壳 1 +x:1 +土尔其 1 +x:1 +风韵犹存 1 +x:1 +异军突起 1 +x:1 +作曲系 1 +x:1 +原 1363 +x:1363 +饶有兴趣 1 +x:1 +皮筋儿 1 +x:1 +宿县 1 +x:1 +缺门 1 +x:1 +朝觐 1 +x:1 +节本降耗 1 +x:1 +房产局 1 +x:1 +朝见 1 +x:1 +侦察排 1 +x:1 +成安县 1 +x:1 +妥协 1 +x:1 +芒果园 1 +x:1 +加意 1 +x:1 +纷争 1 +x:1 +唆使 1 +x:1 +煤都 1 +x:1 +拉丁美洲 1 +x:1 +胜势 1 +x:1 +速滑队 1 +x:1 +蒋管区 1 +x:1 +跑龙套 1 +x:1 +贪污案 1 +x:1 +薇 22 +x:22 +客座率 1 +x:1 +解放碑 1 +x:1 +扭合 1 +x:1 +女强人 1 +x:1 +命意 1 +x:1 +顶风 1 +x:1 +渔利 1 +x:1 +明文 1 +x:1 +复习 1 +x:1 +讨还 1 +x:1 +科研 1 +x:1 +铲车 1 +x:1 +辅导班 1 +x:1 +保管员 1 +x:1 +殿房 1 +x:1 +诚心实意 1 +x:1 +左近 1 +x:1 +新生事物 1 +x:1 +刀把子 1 +x:1 +坐 690 +x:690 +经济社 1 +x:1 +勾搭 1 +x:1 +舞美 1 +x:1 +择址 1 +x:1 +导演系 1 +x:1 +备足 1 +x:1 +惊骇 1 +x:1 +增盈 1 +x:1 +轻取 1 +x:1 +吉达 1 +x:1 +驮骡 1 +x:1 +囚车 1 +x:1 +平鱼 1 +x:1 +娇骄二气 1 +x:1 +仓仓囤囤 1 +x:1 +骚乱 1 +x:1 +深水港区 1 +x:1 +府南 1 +x:1 +灿若明霞 1 +x:1 +非正规 1 +x:1 +杂活儿 1 +x:1 +站规 1 +x:1 +可鉴赏性 1 +x:1 +阑 2 +x:2 +鸡尸牛从 1 +x:1 +逢年过节 1 +x:1 +聚会 1 +x:1 +员额 1 +x:1 +滋阴壮阳 1 +x:1 +聚众 1 +x:1 +增殖症 1 +x:1 +黄白色 1 +x:1 +驮马 1 +x:1 +释放者 1 +x:1 +邪 25 +x:25 +流露 1 +x:1 +期货 1 +x:1 +经济科 1 +x:1 +力挽颓势 1 +x:1 +卷帘 1 +x:1 +苦不堪言 1 +x:1 +糙米饭 1 +x:1 +加急 1 +x:1 +追悔莫及 1 +x:1 +特一粉 1 +x:1 +同龄 1 +x:1 +骗取 1 +x:1 +雄威 1 +x:1 +北冰洋 1 +x:1 +加总 1 +x:1 +薄利多销 1 +x:1 +宿务 1 +x:1 +牛劲 1 +x:1 +公司法 1 +x:1 +挣脸 1 +x:1 +区情 1 +x:1 +滥肆 1 +x:1 +龙腾虎跃 1 +x:1 +习用语 1 +x:1 +寸 46 +x:46 +性行 1 +x:1 +祸首 1 +x:1 +蓖麻蚕 1 +x:1 +领路 1 +x:1 +嘉山县 1 +x:1 +令箭 1 +x:1 +钦州市 1 +x:1 +朝霞 1 +x:1 +联盟杯赛 1 +x:1 +韩国队 1 +x:1 +下葬 1 +x:1 +波谷 1 +x:1 +出国潮 1 +x:1 +波谱 1 +x:1 +瞎婆子 1 +x:1 +合计数 1 +x:1 +专储库 1 +x:1 +朝露 1 +x:1 +管理处 1 +x:1 +真心实意 1 +x:1 +永隆 1 +x:1 +爬 137 +x:137 +水汽量 1 +x:1 +陶俑 1 +x:1 +继承权 1 +x:1 +古已有之 1 +x:1 +亿 334 +x:334 +换工 1 +x:1 +黄皮书 1 +x:1 +转角处 1 +x:1 +邢家梁村 1 +x:1 +圣诞卡 1 +x:1 +驱逐舰长 1 +x:1 +独特性 1 +x:1 +站队 1 +x:1 +濮县 1 +x:1 +改扮 1 +x:1 +椅子 1 +x:1 +癞病 1 +x:1 +下落 1 +x:1 +行凶 1 +x:1 +欢乐开怀 1 +x:1 +册封 1 +x:1 +楦 3 +x:3 +专业厂 1 +x:1 +技术室 1 +x:1 +加美 1 +x:1 +说说笑笑 1 +x:1 +自馁 1 +x:1 +范派 1 +x:1 +公证人 1 +x:1 +急刹 1 +x:1 +疑难重症 1 +x:1 +叉车 1 +x:1 +漠然视之 1 +x:1 +百川归海 1 +x:1 +俏货 1 +x:1 +降温 1 +x:1 +大忙 1 +x:1 +唯理论 1 +x:1 +维权 1 +x:1 +英气逼人 1 +x:1 +素心 1 +x:1 +尽其所长 1 +x:1 +航机 1 +x:1 +降渍 1 +x:1 +公证书 1 +x:1 +说空话 1 +x:1 +离心机 1 +x:1 +经贸界 1 +x:1 +盆汤 1 +x:1 +素志 1 +x:1 +暖壶 1 +x:1 +长春市 1 +x:1 +酒食征逐 1 +x:1 +缘何 1 +x:1 +狮头鹅 1 +x:1 +偷合苟容 1 +x:1 +流血 1 +x:1 +非国有制 1 +x:1 +恋 18 +x:18 +流行 1 +x:1 +推广率 1 +x:1 +缺课 1 +x:1 +再现 1 +x:1 +门面 1 +x:1 +技侦 1 +x:1 +众怒难犯 1 +x:1 +宣言书 1 +x:1 +租赁制 1 +x:1 +从江县 1 +x:1 +蜡黄 1 +x:1 +飞翔式 1 +x:1 +点缀 1 +x:1 +赶上 1 +x:1 +骡子 1 +x:1 +锐降 1 +x:1 +嫌多者 1 +x:1 +急切 1 +x:1 +死胡同 1 +x:1 +大相径庭 1 +x:1 +算清 1 +x:1 +妇委 1 +x:1 +内屋 1 +x:1 +橡皮圈 1 +x:1 +健跳镇 1 +x:1 +议论文 1 +x:1 +小品 1 +x:1 +种崽 1 +x:1 +鹭鸟 1 +x:1 +消极 1 +x:1 +元/公斤 1 +x:1 +盖茨堡镇 1 +x:1 +牙牌 1 +x:1 +历谱 1 +x:1 +朝阳 1 +x:1 +洞庭湖区 1 +x:1 +驱虫剂 1 +x:1 +一是一 1 +x:1 +再版 1 +x:1 +科星 1 +x:1 +蜡鼓 1 +x:1 +鹭鸶 1 +x:1 +睢宁县 1 +x:1 +横加干预 1 +x:1 +忧心 1 +x:1 +转关 1 +x:1 +使节 1 +x:1 +消毒器 1 +x:1 +紫竹园 1 +x:1 +施工史 1 +x:1 +拦道木 1 +x:1 +怒耸 1 +x:1 +素席 1 +x:1 +经济机 1 +x:1 +加纳 1 +x:1 +愁肠百结 1 +x:1 +光华路 1 +x:1 +往返 1 +x:1 +绢丝 1 +x:1 +素常 1 +x:1 +处之泰然 1 +x:1 +友爱新党 1 +x:1 +科普 1 +x:1 +属相 1 +x:1 +观棋者 1 +x:1 +经世致用 1 +x:1 +内贸局 1 +x:1 +改朝换代 1 +x:1 +角膜 1 +x:1 +终审权 1 +x:1 +饰 23 +x:23 +这就是说 1 +x:1 +行为权 1 +x:1 +层次感 1 +x:1 +何如 1 +x:1 +学杂费 1 +x:1 +蓄势待发 1 +x:1 +凄凉 1 +x:1 +凄凄 1 +x:1 +区级 1 +x:1 +伊拉克 1 +x:1 +回头率 1 +x:1 +施工区 1 +x:1 +在用车 1 +x:1 +改革战 1 +x:1 +啼笑皆非 1 +x:1 +阅兵式 1 +x:1 +妇女 1 +x:1 +飞雷炮 1 +x:1 +埋伏 1 +x:1 +笨鸟先飞 1 +x:1 +半吊子 1 +x:1 +科沙拉村 1 +x:1 +碾坊乡 1 +x:1 +弘图 1 +x:1 +肃然起敬 1 +x:1 +铁板钉钉 1 +x:1 +月子 1 +x:1 +沾 46 +x:46 +拥军 1 +x:1 +日射病 1 +x:1 +飒爽 1 +x:1 +土容重 1 +x:1 +高血压 1 +x:1 +如虎添翼 1 +x:1 +豪饮 1 +x:1 +湘潭县 1 +x:1 +镇静 1 +x:1 +冬运 1 +x:1 +返销粮 1 +x:1 +遭遇战 1 +x:1 +凯旋式 1 +x:1 +屯子 1 +x:1 +苍郁 1 +x:1 +非国有化 1 +x:1 +商住楼 1 +x:1 +碑额 1 +x:1 +选矿厂 1 +x:1 +换届 1 +x:1 +后车斗 1 +x:1 +瞬间 1 +x:1 +口岸 1 +x:1 +凄冷 1 +x:1 +饭铺 1 +x:1 +经济林 1 +x:1 +贴心话 1 +x:1 +仓琼玛 1 +x:1 +钟灵毓秀 1 +x:1 +先锋岗 1 +x:1 +维族 1 +x:1 +稀少 1 +x:1 +口岸办 1 +x:1 +甘孜 1 +x:1 +执行主席 1 +x:1 +失窃险 1 +x:1 +命令性 1 +x:1 +定襄县 1 +x:1 +妩媚 1 +x:1 +堑壕 1 +x:1 +指名道姓 1 +x:1 +金石桥 1 +x:1 +问项 1 +x:1 +府令 1 +x:1 +遥测 1 +x:1 +喜吟吟 1 +x:1 +真伪 1 +x:1 +故里 1 +x:1 +老龄委 1 +x:1 +复修 1 +x:1 +压展 1 +x:1 +凄切 1 +x:1 +管理学 1 +x:1 +饲料 1 +x:1 +销售员 1 +x:1 +门门 1 +x:1 +门闩 1 +x:1 +一把手 1 +x:1 +五指 1 +x:1 +舞技 1 +x:1 +可防性 1 +x:1 +林吉特 1 +x:1 +桥函 1 +x:1 +捉拿 1 +x:1 +科教 1 +x:1 +观光者 1 +x:1 +维新 1 +x:1 +碳化铁 1 +x:1 +质检权 1 +x:1 +真传 1 +x:1 +商标局 1 +x:1 +龙宫洞 1 +x:1 +流言 1 +x:1 +协奏团 1 +x:1 +变戏法 1 +x:1 +批办 1 +x:1 +时髦 1 +x:1 +科方 1 +x:1 +小三马 1 +x:1 +脍 3 +x:3 +内心 1 +x:1 +降水 1 +x:1 +见缝插针 1 +x:1 +无降雨期 1 +x:1 +环科所 1 +x:1 +历辈 1 +x:1 +铁靠山 1 +x:1 +兵谏亭 1 +x:1 +妇婴 1 +x:1 +单纯林 1 +x:1 +讦 1 +x:1 +下蛋 1 +x:1 +内忧 1 +x:1 +开镰 1 +x:1 +佛国 1 +x:1 +心绞痛 1 +x:1 +管理官 1 +x:1 +猫儿州村 1 +x:1 +门锁 1 +x:1 +骗人 1 +x:1 +丧权辱国 1 +x:1 +飒然 1 +x:1 +矢志不渝 1 +x:1 +玩命 1 +x:1 +加紧 1 +x:1 +库贷 1 +x:1 +技术处 1 +x:1 +般配 1 +x:1 +问题 1 +x:1 +终身大事 1 +x:1 +月季 1 +x:1 +方舱 1 +x:1 +迁进 1 +x:1 +观澜湖 1 +x:1 +府上 1 +x:1 +夫妻林 1 +x:1 +伊方 1 +x:1 +时不再来 1 +x:1 +可回收式 1 +x:1 +贱人 1 +x:1 +项城市 1 +x:1 +方舟 1 +x:1 +郴县 1 +x:1 +疯杈 1 +x:1 +铸成 1 +x:1 +少年宫 1 +x:1 +城郊乡 1 +x:1 +设施处 1 +x:1 +篮球队 1 +x:1 +疲劳度 1 +x:1 +轻便 1 +x:1 +贡献 1 +x:1 +乞讨者 1 +x:1 +忘我工作 1 +x:1 +鼎城区 1 +x:1 +廉洁 1 +x:1 +曲麻莱县 1 +x:1 +心室 1 +x:1 +军乐队 1 +x:1 +牛乳 1 +x:1 +暖季 1 +x:1 +渔业 1 +x:1 +邓州 1 +x:1 +产期 1 +x:1 +开玩笑 1 +x:1 +经久不衰 1 +x:1 +乔绒 1 +x:1 +扁锉 1 +x:1 +站长 1 +x:1 +可控硅 1 +x:1 +含混 1 +x:1 +份儿 1 +x:1 +极板 1 +x:1 +知青 1 +x:1 +宿主 1 +x:1 +分配器 1 +x:1 +文化界 1 +x:1 +屈膝 1 +x:1 +牛业 1 +x:1 +志得意满 1 +x:1 +销售商 1 +x:1 +轻信 1 +x:1 +护士节 1 +x:1 +石榴树 1 +x:1 +置疑 1 +x:1 +水豆腐 1 +x:1 +嬗变 1 +x:1 +地广人稀 1 +x:1 +转危为安 1 +x:1 +酋长国 1 +x:1 +同母兄弟 1 +x:1 +终结点 1 +x:1 +加油站 1 +x:1 +斜线 1 +x:1 +组织科长 1 +x:1 +故郡 1 +x:1 +论证 1 +x:1 +绕道 1 +x:1 +斜纹 1 +x:1 +故都 1 +x:1 +产权 1 +x:1 +广开门路 1 +x:1 +护养 1 +x:1 +门铃 1 +x:1 +枣子 1 +x:1 +纳税人 1 +x:1 +纺织染厂 1 +x:1 +续建 1 +x:1 +渔人 1 +x:1 +方药 1 +x:1 +牛仔 1 +x:1 +仪张村 1 +x:1 +日月星辰 1 +x:1 +飒爽英姿 1 +x:1 +外资额 1 +x:1 +三插溪 1 +x:1 +格恩济岛 1 +x:1 +卡具 1 +x:1 +轻伤 1 +x:1 +渔产 1 +x:1 +聚化 1 +x:1 +钚 3 +x:3 +椒贩 1 +x:1 +知音 1 +x:1 +发掘面 1 +x:1 +冬趣 1 +x:1 +早产儿 1 +x:1 +筚路蓝缕 1 +x:1 +水火难容 1 +x:1 +妇孺 1 +x:1 +航天飞机 1 +x:1 +击节 1 +x:1 +溢洪道 1 +x:1 +布里特 1 +x:1 +宿仇 1 +x:1 +使者 1 +x:1 +让开 1 +x:1 +仗势欺人 1 +x:1 +基础层 1 +x:1 +郑铁局 1 +x:1 +名建筑 1 +x:1 +凄厉 1 +x:1 +搜肠刮肚 1 +x:1 +盐酸盐 1 +x:1 +积炭 1 +x:1 +敏 95 +x:95 +算法 1 +x:1 +东挪西借 1 +x:1 +螳螂 1 +x:1 +童车厂 1 +x:1 +故道 1 +x:1 +集体主义 1 +x:1 +内庭 1 +x:1 +产中 1 +x:1 +池组 1 +x:1 +野外队 1 +x:1 +全额 1 +x:1 +姊夫 1 +x:1 +消散 1 +x:1 +癞癣 1 +x:1 +一医大 1 +x:1 +私企 1 +x:1 +医科院 1 +x:1 +邃 3 +x:3 +要义 1 +x:1 +要么 1 +x:1 +刊首 1 +x:1 +截瘫康 1 +x:1 +能源区 1 +x:1 +领队 1 +x:1 +聘期 1 +x:1 +软脂酸 1 +x:1 +心寒 1 +x:1 +吉铁 1 +x:1 +渤海 1 +x:1 +吉林街 1 +x:1 +制鞋业 1 +x:1 +资金量 1 +x:1 +西华县 1 +x:1 +黄梅县 1 +x:1 +经济所 1 +x:1 +新宅 1 +x:1 +纷呈 1 +x:1 +并提 1 +x:1 +内奸 1 +x:1 +改良费 1 +x:1 +下联 1 +x:1 +对答如流 1 +x:1 +辽 39 +x:39 +知道 1 +x:1 +隐秘处 1 +x:1 +试点村 1 +x:1 +夫妇 1 +x:1 +秉 2 +x:2 +施工图 1 +x:1 +要不 1 +x:1 +私住 1 +x:1 +夸—纳省 1 +x:1 +苦难感 1 +x:1 +付家坪 1 +x:1 +牵衣顿足 1 +x:1 +献花 1 +x:1 +乱纷纷 1 +x:1 +转接点 1 +x:1 +内外 1 +x:1 +团团圆圆 1 +x:1 +行贿式 1 +x:1 +走私犯 1 +x:1 +过日子 1 +x:1 +高瞻远瞩 1 +x:1 +极性 1 +x:1 +北伐军 1 +x:1 +州长 1 +x:1 +笑口 1 +x:1 +经济战 1 +x:1 +青丝 1 +x:1 +夫妻 1 +x:1 +聋哑症 1 +x:1 +梅谱 1 +x:1 +白日升天 1 +x:1 +武进 1 +x:1 +聚合 1 +x:1 +力大无比 1 +x:1 +宝清县 1 +x:1 +动态平衡 1 +x:1 +沐 14 +x:14 +公主岭 1 +x:1 +鄂东 1 +x:1 +挑 123 +x:123 +佛像 1 +x:1 +劫机犯 1 +x:1 +悦目 1 +x:1 +棚亭 1 +x:1 +杨浦区 1 +x:1 +德岛县 1 +x:1 +孰 27 +x:27 +金石滩 1 +x:1 +要塞区 1 +x:1 +论调 1 +x:1 +包头市 1 +x:1 +灭种 1 +x:1 +加筑 1 +x:1 +议论性 1 +x:1 +后脑勺子 1 +x:1 +溶解状 1 +x:1 +要件 1 +x:1 +神山 1 +x:1 +老爹 1 +x:1 +下肢 1 +x:1 +木条桌 1 +x:1 +综合征 1 +x:1 +溃逃 1 +x:1 +角落 1 +x:1 +要事 1 +x:1 +溃退 1 +x:1 +塘厦镇 1 +x:1 +期限 1 +x:1 +机场路 1 +x:1 +观摩会 1 +x:1 +足底 1 +x:1 +疫区 1 +x:1 +历览 1 +x:1 +镭射气 1 +x:1 +毁伤 1 +x:1 +私信 1 +x:1 +捉摸 1 +x:1 +德育室 1 +x:1 +制表符 1 +x:1 +佳婿 1 +x:1 +稃皮 1 +x:1 +救助性 1 +x:1 +盆栽 1 +x:1 +总体战 1 +x:1 +轮船 1 +x:1 +工商界 1 +x:1 +桂花 1 +x:1 +轮舱 1 +x:1 +要人 1 +x:1 +时鲜 1 +x:1 +养畜热 1 +x:1 +并拢 1 +x:1 +专业团 1 +x:1 +私下 1 +x:1 +柠檬 1 +x:1 +故障 1 +x:1 +十滴水 1 +x:1 +单纯性 1 +x:1 +马兰花 1 +x:1 +捐血者 1 +x:1 +磁盘 1 +x:1 +云龙纹 1 +x:1 +下腹 1 +x:1 +冷暖不定 1 +x:1 +闹情绪 1 +x:1 +佳宾 1 +x:1 +文化学术 1 +x:1 +周详 1 +x:1 +数字网 1 +x:1 +预制厂 1 +x:1 +敞亮亮 1 +x:1 +中央邦 1 +x:1 +炭子冲 1 +x:1 +垂直型 1 +x:1 +下腔 1 +x:1 +住校生 1 +x:1 +玉洁冰清 1 +x:1 +往访 1 +x:1 +抚平 1 +x:1 +万宝山 1 +x:1 +问鼎 1 +x:1 +纪录者 1 +x:1 +灵前 1 +x:1 +大头鱼 1 +x:1 +彩蝶 1 +x:1 +技术库 1 +x:1 +铺架 1 +x:1 +没着没落 1 +x:1 +达拉特 1 +x:1 +蛋黄 1 +x:1 +管理局 1 +x:1 +管理层 1 +x:1 +白话 1 +x:1 +尘嚣 1 +x:1 +韩币 1 +x:1 +命令权 1 +x:1 +维护 1 +x:1 +新翟村 1 +x:1 +下臣 1 +x:1 +蛋鸡 1 +x:1 +兼容性 1 +x:1 +梅花瓣型 1 +x:1 +私了 1 +x:1 +扭亏 1 +x:1 +内壁 1 +x:1 +蛋鸭 1 +x:1 +淅淅沥沥 1 +x:1 +虚像 1 +x:1 +要言不烦 1 +x:1 +深水 1 +x:1 +电脑凳 1 +x:1 +稀客 1 +x:1 +油炸摊 1 +x:1 +布拉格宫 1 +x:1 +波及面 1 +x:1 +私产 1 +x:1 +崖壁画 1 +x:1 +低中放 1 +x:1 +流质 1 +x:1 +勾结 1 +x:1 +露点 1 +x:1 +炮 35 +x:35 +科技 1 +x:1 +灵动 1 +x:1 +腕上 1 +x:1 +查阅者 1 +x:1 +局外人 1 +x:1 +速滑赛 1 +x:1 +内壳 1 +x:1 +消损 1 +x:1 +私仇 1 +x:1 +中共中央 1 +x:1 +讹传 1 +x:1 +中国式 1 +x:1 +谋害 1 +x:1 +内墙 1 +x:1 +诔 1 +x:1 +块 762 +x:762 +保管人 1 +x:1 +色香味 1 +x:1 +雪龙 1 +x:1 +无 2035 +x:2035 +陆源性 1 +x:1 +金鸡湖 1 +x:1 +文化班 1 +x:1 +民俗馆 1 +x:1 +枫树 1 +x:1 +瑶民 1 +x:1 +种姓 1 +x:1 +佳季 1 +x:1 +谋定 1 +x:1 +韩庄 1 +x:1 +补语 1 +x:1 +弘光 1 +x:1 +社会学 1 +x:1 +轮胎 1 +x:1 +产房 1 +x:1 +盘账 1 +x:1 +缺货 1 +x:1 +供水管 1 +x:1 +豺狼 1 +x:1 +内存 1 +x:1 +发扬踔厉 1 +x:1 +佳境 1 +x:1 +甘当 1 +x:1 +凯旋声 1 +x:1 +安凹镇 1 +x:1 +点种 1 +x:1 +舞曲 1 +x:1 +放大纸 1 +x:1 +铲除 1 +x:1 +一拥而入 1 +x:1 +暖干 1 +x:1 +苍松翠柏 1 +x:1 +走马 1 +x:1 +主导性 1 +x:1 +穿心莲 1 +x:1 +经济性 1 +x:1 +如意算盘 1 +x:1 +结合处 1 +x:1 +牧野 1 +x:1 +下船 1 +x:1 +顺水村 1 +x:1 +食 88 +x:88 +吉隆 1 +x:1 +格但斯克 1 +x:1 +冬衣 1 +x:1 +上方剑 1 +x:1 +核禁试 1 +x:1 +卮 1 +x:1 +急急火火 1 +x:1 +号头 1 +x:1 +碱性岩 1 +x:1 +苍青 1 +x:1 +再生 1 +x:1 +栩栩然 1 +x:1 +桐城县 1 +x:1 +谋士 1 +x:1 +甘心 1 +x:1 +马六甲 1 +x:1 +抚州 1 +x:1 +夫子 1 +x:1 +少年心 1 +x:1 +降格 1 +x:1 +罗布泊湖 1 +x:1 +南张家村 1 +x:1 +卷舌元音 1 +x:1 +含泥量 1 +x:1 +意粉 1 +x:1 +拒卖 1 +x:1 +祸胎 1 +x:1 +视盘机 1 +x:1 +尼洋河 1 +x:1 +妇幼 1 +x:1 +报春花 1 +x:1 +纤维管网 1 +x:1 +枣庄 1 +x:1 +宋都 1 +x:1 +抗菌素 1 +x:1 +章丘 1 +x:1 +冬装 1 +x:1 +冷笑 1 +x:1 +舞星 1 +x:1 +恍 3 +x:3 +妄下雌黄 1 +x:1 +电务段 1 +x:1 +玩偶 1 +x:1 +普拉多 1 +x:1 +优势 1 +x:1 +内定 1 +x:1 +喀土穆 1 +x:1 +朝野 1 +x:1 +氢弹 1 +x:1 +申购款 1 +x:1 +中生代 1 +x:1 +内室 1 +x:1 +漫天 1 +x:1 +施工员 1 +x:1 +死魂灵 1 +x:1 +自惭形秽 1 +x:1 +曲港勾连 1 +x:1 +内容 1 +x:1 +不得而知 1 +x:1 +桑榆暮景 1 +x:1 +润肤 1 +x:1 +轮转机 1 +x:1 +内家 1 +x:1 +辞色 1 +x:1 +亚硝胺 1 +x:1 +独立师 1 +x:1 +论辩 1 +x:1 +少言寡语 1 +x:1 +观察团 1 +x:1 +云 275 +x:275 +播放机 1 +x:1 +掣 7 +x:7 +尼日尔 1 +x:1 +核垄断 1 +x:1 +蓼蓝 1 +x:1 +鄂尔多斯 1 +x:1 +缰 3 +x:3 +独生子女 1 +x:1 +影像 1 +x:1 +南浔镇 1 +x:1 +芹 17 +x:17 +互利性 1 +x:1 +农作 1 +x:1 +袭击 1 +x:1 +扰民 1 +x:1 +稀奇 1 +x:1 +流过 1 +x:1 +炒米 1 +x:1 +攀龙附凤 1 +x:1 +佐 6 +x:6 +陶庙乡 1 +x:1 +棕 2 +x:2 +屋顶 1 +x:1 +癌肿 1 +x:1 +论述 1 +x:1 +流连 1 +x:1 +怀古 1 +x:1 +葡萄秧 1 +x:1 +期间 1 +x:1 +等级组 1 +x:1 +供水站 1 +x:1 +灵川县 1 +x:1 +销售业 1 +x:1 +搭架子 1 +x:1 +窃听器 1 +x:1 +明显 1 +x:1 +玩儿 1 +x:1 +联线 1 +x:1 +川菜 1 +x:1 +技术局 1 +x:1 +风雨剥蚀 1 +x:1 +撰文 1 +x:1 +看出 1 +x:1 +说实话 1 +x:1 +技术展 1 +x:1 +腰刀 1 +x:1 +搪塞 1 +x:1 +佛台 1 +x:1 +中体西用 1 +x:1 +吭 2 +x:2 +青稞麦 1 +x:1 +托人 1 +x:1 +剽悍 1 +x:1 +无懈可击 1 +x:1 +夫婿 1 +x:1 +贾宪三角 1 +x:1 +嗤笑 1 +x:1 +神游 1 +x:1 +语助词 1 +x:1 +波诡 1 +x:1 +召开 1 +x:1 +妇弟 1 +x:1 +雕塑系 1 +x:1 +佳奖 1 +x:1 +玩具 1 +x:1 +滋味 1 +x:1 +搜寻队 1 +x:1 +托付 1 +x:1 +无私奉献 1 +x:1 +佛历 1 +x:1 +形同虚设 1 +x:1 +房租费 1 +x:1 +狗屁不通 1 +x:1 +苍雄 1 +x:1 +颈项 1 +x:1 +版权页 1 +x:1 +腹壁 1 +x:1 +门道 1 +x:1 +雅室净几 1 +x:1 +岗位制 1 +x:1 +韩岗 1 +x:1 +促使 1 +x:1 +玄武区 1 +x:1 +雄纠纠 1 +x:1 +消遥自在 1 +x:1 +元元本本 1 +x:1 +军事科学 1 +x:1 +潜心 1 +x:1 +待 258 +x:258 +太平店村 1 +x:1 +内商 1 +x:1 +礼拜天 1 +x:1 +廉明 1 +x:1 +救助法 1 +x:1 +腹地 1 +x:1 +受害国 1 +x:1 +收集箱 1 +x:1 +莆田 1 +x:1 +佛山 1 +x:1 +发型师 1 +x:1 +发行业 1 +x:1 +燃亮 1 +x:1 +算术 1 +x:1 +于是 1 +x:1 +小户人家 1 +x:1 +尖头蝗 1 +x:1 +湍急 1 +x:1 +技术史 1 +x:1 +插图 1 +x:1 +屋面 1 +x:1 +时逢 1 +x:1 +苦活 1 +x:1 +表侄女 1 +x:1 +天遂人愿 1 +x:1 +挥之即去 1 +x:1 +到课率 1 +x:1 +轻世傲物 1 +x:1 +选装型 1 +x:1 +管线处 1 +x:1 +穹庐 1 +x:1 +使手机 1 +x:1 +结合地 1 +x:1 +讣告 1 +x:1 +译审员 1 +x:1 +洞箫 1 +x:1 +宗主权 1 +x:1 +由弱到强 1 +x:1 +大话 1 +x:1 +时速 1 +x:1 +老龄化 1 +x:1 +迄今 1 +x:1 +气盛 1 +x:1 +客运港 1 +x:1 +笊篱 1 +x:1 +小生产者 1 +x:1 +水光山色 1 +x:1 +目无全牛 1 +x:1 +销售店 1 +x:1 +锅盖 1 +x:1 +方尖碑 1 +x:1 +论者 1 +x:1 +消渴 1 +x:1 +总装厂 1 +x:1 +追忆 1 +x:1 +二传 1 +x:1 +输氧管 1 +x:1 +大法官 1 +x:1 +后半生 1 +x:1 +冷箭 1 +x:1 +女招待 1 +x:1 +社会学家 1 +x:1 +柠条 1 +x:1 +门齿 1 +x:1 +主焦点 1 +x:1 +澳抗 1 +x:1 +精算师 1 +x:1 +定军山 1 +x:1 +文化组 1 +x:1 +大学部 1 +x:1 +惩前毖后 1 +x:1 +技术化 1 +x:1 +增色添彩 1 +x:1 +诗词集 1 +x:1 +收费员证 1 +x:1 +滕州市 1 +x:1 +孝直村 1 +x:1 +首车 1 +x:1 +读书人 1 +x:1 +撤退 1 +x:1 +围 208 +x:208 +掩蔽部 1 +x:1 +爵士乐队 1 +x:1 +贴现率 1 +x:1 +板房 1 +x:1 +佛得角 1 +x:1 +辏 1 +x:1 +川资 1 +x:1 +营销员 1 +x:1 +枣儿 1 +x:1 +阳关大道 1 +x:1 +稀土 1 +x:1 +耕种 1 +x:1 +角角 1 +x:1 +釉质 1 +x:1 +算是 1 +x:1 +默克莱市 1 +x:1 +米坪镇 1 +x:1 +沧桑感 1 +x:1 +核爆炸 1 +x:1 +实习期 1 +x:1 +耍滑 1 +x:1 +炼焦厂 1 +x:1 +礼拜堂 1 +x:1 +打斋醮 1 +x:1 +傲骨 1 +x:1 +加盟 1 +x:1 +同水平 1 +x:1 +窝里斗 1 +x:1 +肌肉节 1 +x:1 +洞窟 1 +x:1 +川贝 1 +x:1 +晴朗 1 +x:1 +泔水 1 +x:1 +记数器 1 +x:1 +大展 1 +x:1 +吉首 1 +x:1 +下贱 1 +x:1 +卡宴 1 +x:1 +药单 1 +x:1 +危陋 1 +x:1 +内向 1 +x:1 +微 29 +x:29 +校规 1 +x:1 +手指字母 1 +x:1 +内含 1 +x:1 +另辟蹊径 1 +x:1 +金马河 1 +x:1 +红海省 1 +x:1 +非经济 1 +x:1 +收集站 1 +x:1 +进尺 1 +x:1 +危险 1 +x:1 +背静 1 +x:1 +纪念馆 1 +x:1 +愉悦 1 +x:1 +心急情切 1 +x:1 +灵府 1 +x:1 +选题 1 +x:1 +内哄 1 +x:1 +设防 1 +x:1 +讨饶 1 +x:1 +浮光掠影 1 +x:1 +推广站 1 +x:1 +流脑 1 +x:1 +泥盆纪 1 +x:1 +讨饭 1 +x:1 +走私罪 1 +x:1 +参差不一 1 +x:1 +镇委会 1 +x:1 +令爱 1 +x:1 +轮轨 1 +x:1 +轮转 1 +x:1 +洞穿 1 +x:1 +降服 1 +x:1 +洞穴 1 +x:1 +明晚 1 +x:1 +危难 1 +x:1 +卡子 1 +x:1 +换向 1 +x:1 +枣农 1 +x:1 +求全责备 1 +x:1 +毫米数 1 +x:1 +轮轴 1 +x:1 +玩弄 1 +x:1 +苛性钠 1 +x:1 +无穷的 1 +x:1 +无庸赘述 1 +x:1 +殷红 1 +x:1 +蜂乳 1 +x:1 +阴阳生 1 +x:1 +半身像 1 +x:1 +土沟村 1 +x:1 +夫君 1 +x:1 +苛性钾 1 +x:1 +金桥乡 1 +x:1 +证管办 1 +x:1 +雪泥鸿爪 1 +x:1 +妇儿 1 +x:1 +明白人 1 +x:1 +暖冬 1 +x:1 +打铁者 1 +x:1 +十四时 1 +x:1 +凰 2 +x:2 +千古不灭 1 +x:1 +外耳门 1 +x:1 +命根子 1 +x:1 +瘦小 1 +x:1 +阻劝 1 +x:1 +藏垢纳污 1 +x:1 +形象化 1 +x:1 +投袂而起 1 +x:1 +判若两人 1 +x:1 +左云 1 +x:1 +凄婉 1 +x:1 +助耕 1 +x:1 +首义路 1 +x:1 +卡壳 1 +x:1 +消沉 1 +x:1 +管理区 1 +x:1 +主干道 1 +x:1 +问道 1 +x:1 +他山之石 1 +x:1 +茶艺术 1 +x:1 +药膳 1 +x:1 +彝族乡 1 +x:1 +用药 1 +x:1 +簿籍 1 +x:1 +商法典 1 +x:1 +换型 1 +x:1 +象角 1 +x:1 +琴 74 +x:74 +亲历者 1 +x:1 +抚养 1 +x:1 +韩元 1 +x:1 +妻儿老小 1 +x:1 +增殖性 1 +x:1 +科海 1 +x:1 +天王星 1 +x:1 +天南海北 1 +x:1 +管理卡 1 +x:1 +茧绸 1 +x:1 +圣冈丹 1 +x:1 +资溪 1 +x:1 +佳品 1 +x:1 +甘化 1 +x:1 +接合部 1 +x:1 +埃特纳 1 +x:1 +内在 1 +x:1 +范本 1 +x:1 +颈间 1 +x:1 +障碍性 1 +x:1 +算数 1 +x:1 +内地 1 +x:1 +闹肚子 1 +x:1 +褥疮 1 +x:1 +遣词造句 1 +x:1 +噬 6 +x:6 +理屈辞穷 1 +x:1 +一共 1 +x:1 +福绥境 1 +x:1 +祛风 1 +x:1 +亚大地区 1 +x:1 +物质损耗 1 +x:1 +管理厅 1 +x:1 +缩微金报 1 +x:1 +德农厅 1 +x:1 +纰漏 1 +x:1 +喇嘛教 1 +x:1 +锄强扶弱 1 +x:1 +起床号 1 +x:1 +谜语 1 +x:1 +张本 1 +x:1 +盆景 1 +x:1 +灵川 1 +x:1 +下身 1 +x:1 +屋门 1 +x:1 +点画 1 +x:1 +管理司 1 +x:1 +闹店乡 1 +x:1 +杨桃 1 +x:1 +狼奔豕突 1 +x:1 +天子 1 +x:1 +波澜壮阔 1 +x:1 +韩军 1 +x:1 +混世魔王 1 +x:1 +方言 1 +x:1 +斜眼 1 +x:1 +发票款 1 +x:1 +盼望 1 +x:1 +猪栏 1 +x:1 +交响乐 1 +x:1 +彝族人 1 +x:1 +网球场 1 +x:1 +隐晦 1 +x:1 +污染物 1 +x:1 +恽城 1 +x:1 +梅花 1 +x:1 +下车 1 +x:1 +大钟寺 1 +x:1 +套衫 1 +x:1 +晋阳 1 +x:1 +排放量 1 +x:1 +轮距 1 +x:1 +管理制 1 +x:1 +歼灭 1 +x:1 +用书 1 +x:1 +专才 1 +x:1 +下载 1 +x:1 +译制片 1 +x:1 +表决权 1 +x:1 +佛影 1 +x:1 +惩罚 1 +x:1 +周末 1 +x:1 +贤 39 +x:39 +廉政 1 +x:1 +音响奖 1 +x:1 +普建 1 +x:1 +自行火炮 1 +x:1 +试点校 1 +x:1 +一句话 1 +x:1 +十一二点 1 +x:1 +准销证 1 +x:1 +纽瓦克 1 +x:1 +联合王国 1 +x:1 +攻关田 1 +x:1 +离心法 1 +x:1 +亮光光 1 +x:1 +糅 2 +x:2 +胶版纸 1 +x:1 +点炮手 1 +x:1 +辽中镇 1 +x:1 +朝发夕至 1 +x:1 +百日维新 1 +x:1 +佛开 1 +x:1 +乐施米 1 +x:1 +保健食品 1 +x:1 +半决赛 1 +x:1 +离心泵 1 +x:1 +肖形石 1 +x:1 +灵山 1 +x:1 +站牌点 1 +x:1 +降旗 1 +x:1 +歃血为盟 1 +x:1 +低级趣味 1 +x:1 +恩公 1 +x:1 +流转税 1 +x:1 +客座教授 1 +x:1 +知己知彼 1 +x:1 +洼地 1 +x:1 +形象办 1 +x:1 +朝鲜 1 +x:1 +赵畈村 1 +x:1 +下述 1 +x:1 +领馆 1 +x:1 +炊事 1 +x:1 +妇协 1 +x:1 +骤起 1 +x:1 +奖优罚劣 1 +x:1 +园区 1 +x:1 +用以 1 +x:1 +垛口 1 +x:1 +枳机草 1 +x:1 +下迄 1 +x:1 +力点 1 +x:1 +内因 1 +x:1 +表演会 1 +x:1 +护身符 1 +x:1 +顶骨 1 +x:1 +工商税 1 +x:1 +晴日 1 +x:1 +莫索罗 1 +x:1 +急变 1 +x:1 +用人 1 +x:1 +国家所有 1 +x:1 +邻角 1 +x:1 +兴平市 1 +x:1 +畜科所 1 +x:1 +名义工资 1 +x:1 +枝枝节节 1 +x:1 +租赁处 1 +x:1 +总编室 1 +x:1 +蛤蜊 1 +x:1 +下边 1 +x:1 +下达 1 +x:1 +契据 1 +x:1 +鹏城 1 +x:1 +武宁县 1 +x:1 +竹歧 1 +x:1 +点球 1 +x:1 +下辈 1 +x:1 +维加岛 1 +x:1 +国富民安 1 +x:1 +咳嗽 1 +x:1 +概念 1 +x:1 +呆呆板板 1 +x:1 +靖宇县 1 +x:1 +用于 1 +x:1 +下辖 1 +x:1 +复合性 1 +x:1 +屯兵 1 +x:1 +煤黑 1 +x:1 +食洋不化 1 +x:1 +走道 1 +x:1 +互通有无 1 +x:1 +佛塔 1 +x:1 +内兄 1 +x:1 +清扫工 1 +x:1 +加班 1 +x:1 +站 1071 +x:1071 +击败 1 +x:1 +小规模 1 +x:1 +税费卡 1 +x:1 +走遍 1 +x:1 +南戴河 1 +x:1 +焕然一新 1 +x:1 +纷纷扬扬 1 +x:1 +永无止境 1 +x:1 +下行 1 +x:1 +谈资 1 +x:1 +贝鲁特 1 +x:1 +社会党 1 +x:1 +阳宗海 1 +x:1 +换写 1 +x:1 +眼外伤 1 +x:1 +外耳道 1 +x:1 +技术型 1 +x:1 +谋利 1 +x:1 +言之谆谆 1 +x:1 +佛堂 1 +x:1 +贡米 1 +x:1 +太白星 1 +x:1 +农六师 1 +x:1 +最高 1 +x:1 +政治系 1 +x:1 +湘潭市 1 +x:1 +游客量 1 +x:1 +创始国 1 +x:1 +谋划 1 +x:1 +紧接着 1 +x:1 +小便宜 1 +x:1 +幽谷 1 +x:1 +游弋 1 +x:1 +匹兹堡市 1 +x:1 +口传心授 1 +x:1 +灵官 1 +x:1 +丑态百出 1 +x:1 +哀 7 +x:7 +畜舍 1 +x:1 +咖啡碱 1 +x:1 +腋芽 1 +x:1 +小鸟 1 +x:1 +流萤 1 +x:1 +下装 1 +x:1 +艺术家卷 1 +x:1 +萎靡不振 1 +x:1 +翻翻 1 +x:1 +油椰子 1 +x:1 +漫卷 1 +x:1 +贫穷线 1 +x:1 +房产主 1 +x:1 +韩城 1 +x:1 +舞池 1 +x:1 +流落 1 +x:1 +寰岛队 1 +x:1 +灵寝 1 +x:1 +荞面圪 1 +x:1 +少体校 1 +x:1 +作巢生卵 1 +x:1 +聚居 1 +x:1 +及 4596 +x:4596 +暖和 1 +x:1 +自卑心 1 +x:1 +密西西比 1 +x:1 +泡泡糖 1 +x:1 +作者群 1 +x:1 +动迁房 1 +x:1 +行贿型 1 +x:1 +呛 10 +x:10 +好听话 1 +x:1 +动迁户 1 +x:1 +若羌 1 +x:1 +灵寿 1 +x:1 +战略性 1 +x:1 +不变价格 1 +x:1 +时针 1 +x:1 +有鉴于此 1 +x:1 +音响库 1 +x:1 +楼下 1 +x:1 +巴别塔 1 +x:1 +认错 1 +x:1 +力矫 1 +x:1 +闷子车 1 +x:1 +论著 1 +x:1 +颀长 1 +x:1 +时钟 1 +x:1 +发热量 1 +x:1 +理 134 +x:134 +席草 1 +x:1 +玩家 1 +x:1 +敲骨吸髓 1 +x:1 +空军队 1 +x:1 +客运段 1 +x:1 +洞经 1 +x:1 +仪容 1 +x:1 +相机行事 1 +x:1 +题目 1 +x:1 +聂荣 1 +x:1 +屯垦 1 +x:1 +川西 1 +x:1 +不堪入目 1 +x:1 +L 6 +x:6 +技术图 1 +x:1 +契文 1 +x:1 +死理儿 1 +x:1 +下襟 1 +x:1 +须根 1 +x:1 +侠客 1 +x:1 +屯城 1 +x:1 +邓县 1 +x:1 +消毒 1 +x:1 +跃过 1 +x:1 +跃进 1 +x:1 +通间 1 +x:1 +糊糊饭 1 +x:1 +豪门 1 +x:1 +种养 1 +x:1 +点状 1 +x:1 +汕头市 1 +x:1 +洞纺 1 +x:1 +轮训 1 +x:1 +屈辱 1 +x:1 +范性 1 +x:1 +种兔 1 +x:1 +管理员 1 +x:1 +共振 1 +x:1 +期待值 1 +x:1 +声乐系 1 +x:1 +支付者 1 +x:1 +专业店 1 +x:1 +佳句 1 +x:1 +韩国 1 +x:1 +弈和 1 +x:1 +佩饰 1 +x:1 +夜静更深 1 +x:1 +不无关系 1 +x:1 +公司级 1 +x:1 +时间 1 +x:1 +表叔 1 +x:1 +续借 1 +x:1 +碑铭 1 +x:1 +一个样儿 1 +x:1 +辨别力 1 +x:1 +精算学 1 +x:1 +俄语 1 +x:1 +中资企业 1 +x:1 +谋反 1 +x:1 +忍不住 1 +x:1 +谋取 1 +x:1 +商标厂 1 +x:1 +俗话说 1 +x:1 +著文 1 +x:1 +卡张 1 +x:1 +结合力 1 +x:1 +大牧场 1 +x:1 +彗 1 +x:1 +代主席 1 +x:1 +姨夫 1 +x:1 +冬菜 1 +x:1 +角质 1 +x:1 +巡回展 1 +x:1 +召唤 1 +x:1 +云西新村 1 +x:1 +云海 1 +x:1 +小礼拜 1 +x:1 +撤销 1 +x:1 +备考 1 +x:1 +比重计 1 +x:1 +灰鼠皮 1 +x:1 +人工流产 1 +x:1 +燧石 1 +x:1 +交款台 1 +x:1 +浪漫主义 1 +x:1 +弃权 1 +x:1 +承购人 1 +x:1 +焊 15 +x:15 +种别 1 +x:1 +林农业 1 +x:1 +碑面 1 +x:1 +大团结 1 +x:1 +粗 58 +x:58 +召回 1 +x:1 +铝制品 1 +x:1 +关东糖 1 +x:1 +不弃前诺 1 +x:1 +黄金分割 1 +x:1 +滥配 1 +x:1 +勾留 1 +x:1 +澳大利队 1 +x:1 +自卫队 1 +x:1 +内卫 1 +x:1 +保外就医 1 +x:1 +掠夺性 1 +x:1 +茅台酒 1 +x:1 +盟辞 1 +x:1 +慕名而来 1 +x:1 +时限 1 +x:1 +榛鸡 1 +x:1 +惊诧 1 +x:1 +胡柚 1 +x:1 +肝素 1 +x:1 +翁 38 +x:38 +勾画 1 +x:1 +飘然欲仙 1 +x:1 +扰攘 1 +x:1 +择优汰劣 1 +x:1 +欢庆 1 +x:1 +显示牌 1 +x:1 +斜率 1 +x:1 +豪雨 1 +x:1 +小锅饭 1 +x:1 +春风得意 1 +x:1 +管线式 1 +x:1 +流蛘 1 +x:1 +酱坊 1 +x:1 +信 531 +x:531 +谦受益 1 +x:1 +无原则 1 +x:1 +叉腰 1 +x:1 +频率段 1 +x:1 +作恶多端 1 +x:1 +漫决 1 +x:1 +沙打旺 1 +x:1 +换取 1 +x:1 +社会化 1 +x:1 +明朗 1 +x:1 +香云纱 1 +x:1 +草帽缏 1 +x:1 +原子级 1 +x:1 +甘城 1 +x:1 +李埝乡 1 +x:1 +撤除 1 +x:1 +脆弱性 1 +x:1 +迭部 1 +x:1 +社会史 1 +x:1 +所得者 1 +x:1 +笙 1 +x:1 +任人宰割 1 +x:1 +起点价 1 +x:1 +素净 1 +x:1 +察微知晓 1 +x:1 +沁人肺腑 1 +x:1 +管理型 1 +x:1 +腹内 1 +x:1 +轮补 1 +x:1 +非鞅 1 +x:1 +八里庄桥 1 +x:1 +疲 11 +x:11 +泡泡纱 1 +x:1 +谷 130 +x:130 +改革派 1 +x:1 +苍龙 1 +x:1 +系统工程 1 +x:1 +旨趣 1 +x:1 +枣园 1 +x:1 +降息 1 +x:1 +龙亭区 1 +x:1 +永顺 1 +x:1 +愈发 1 +x:1 +打 1617 +x:1617 +呓语 1 +x:1 +犬齿 1 +x:1 +后脑勺儿 1 +x:1 +卡尺 1 +x:1 +危重 1 +x:1 +卡尼 1 +x:1 +点焊 1 +x:1 +腾飞型 1 +x:1 +昂扬斗志 1 +x:1 +佳偶 1 +x:1 +冲积扇 1 +x:1 +盲文 1 +x:1 +时隔 1 +x:1 +翘板 1 +x:1 +音像法 1 +x:1 +九泉之下 1 +x:1 +熟地黄 1 +x:1 +贵德县 1 +x:1 +全封闭 1 +x:1 +书名号 1 +x:1 +销售处 1 +x:1 +加热 1 +x:1 +周武王 1 +x:1 +围棋队 1 +x:1 +灵堂 1 +x:1 +大建福 1 +x:1 +植树权 1 +x:1 +人心如面 1 +x:1 +敏感性 1 +x:1 +贡缎 1 +x:1 +补补 1 +x:1 +前往者 1 +x:1 +佛学 1 +x:1 +汪洋恣肆 1 +x:1 +净空 1 +x:1 +桂西 1 +x:1 +碑阴 1 +x:1 +陆 244 +x:244 +苍鹭 1 +x:1 +灵塔 1 +x:1 +溪谷 1 +x:1 +人勤地沃 1 +x:1 +改革法 1 +x:1 +缔造者 1 +x:1 +中队部 1 +x:1 +苍鹰 1 +x:1 +怡情 1 +x:1 +伯诺尼 1 +x:1 +马楼 1 +x:1 +国富民强 1 +x:1 +销售奖 1 +x:1 +吸附状 1 +x:1 +颈部 1 +x:1 +冒 253 +x:253 +门风 1 +x:1 +基本工资 1 +x:1 +翘曲 1 +x:1 +条件者 1 +x:1 +姑奶奶 1 +x:1 +蓝幽幽 1 +x:1 +不眠之夜 1 +x:1 +点灯 1 +x:1 +短柄 1 +x:1 +契机 1 +x:1 +石膏像 1 +x:1 +搜集 1 +x:1 +侠女 1 +x:1 +技术员 1 +x:1 +甜椒 1 +x:1 +管弦乐 1 +x:1 +下课 1 +x:1 +杨楼 1 +x:1 +问问 1 +x:1 +有所为 1 +x:1 +佛寺 1 +x:1 +热机 1 +x:1 +粗墩墩 1 +x:1 +并发症 1 +x:1 +甜津津 1 +x:1 +川语 1 +x:1 +触犯 1 +x:1 +分割感 1 +x:1 +玩处 1 +x:1 +专业展 1 +x:1 +新乐市 1 +x:1 +松果体素 1 +x:1 +绽白 1 +x:1 +趋之若鹜 1 +x:1 +腋臭 1 +x:1 +内功 1 +x:1 +内力 1 +x:1 +加尔各答 1 +x:1 +下访 1 +x:1 +下设 1 +x:1 +严密性 1 +x:1 +内助 1 +x:1 +佛家 1 +x:1 +内务 1 +x:1 +屠苏 1 +x:1 +吐绶鸡 1 +x:1 +实质性 1 +x:1 +救助款 1 +x:1 +苍黑 1 +x:1 +冬至 1 +x:1 +酱园 1 +x:1 +庆功会 1 +x:1 +贤良 1 +x:1 +肥分 1 +x:1 +反腐纠风 1 +x:1 +闸口 1 +x:1 +洋橄榄 1 +x:1 +亚非 1 +x:1 +以资村 1 +x:1 +奥地利籍 1 +x:1 +能大则大 1 +x:1 +造物 1 +x:1 +收信人 1 +x:1 +公共课 1 +x:1 +城下之盟 1 +x:1 +镀铬钢 1 +x:1 +迭部县 1 +x:1 +现形 1 +x:1 +吊架 1 +x:1 +魔法 1 +x:1 +闭月羞花 1 +x:1 +工具车 1 +x:1 +鸿运 1 +x:1 +寤寐思之 1 +x:1 +大节 1 +x:1 +活字典 1 +x:1 +补苗 1 +x:1 +拉犁山 1 +x:1 +千山万水 1 +x:1 +谈判 1 +x:1 +吊柜 1 +x:1 +蓄意 1 +x:1 +商报 1 +x:1 +碍手碍脚 1 +x:1 +动物油 1 +x:1 +篮球 1 +x:1 +兵临城下 1 +x:1 +胜过 1 +x:1 +值日 1 +x:1 +福人 1 +x:1 +身分证 1 +x:1 +白药 1 +x:1 +汽油桶 1 +x:1 +关系 1 +x:1 +校址 1 +x:1 +蛆虫 1 +x:1 +校均 1 +x:1 +外科 1 +x:1 +穿法 1 +x:1 +追回 1 +x:1 +树窝 1 +x:1 +黄色炸药 1 +x:1 +金刘寨村 1 +x:1 +胜迹 1 +x:1 +思维会 1 +x:1 +逍林 1 +x:1 +二娘 1 +x:1 +电讯报 1 +x:1 +有日子 1 +x:1 +幻觉 1 +x:1 +付店乡 1 +x:1 +独脚戏 1 +x:1 +白莲 1 +x:1 +圆柱形 1 +x:1 +配售 1 +x:1 +大船 1 +x:1 +招待饭 1 +x:1 +质量关 1 +x:1 +胪溪 1 +x:1 +查铺 1 +x:1 +欢呼 1 +x:1 +长寿菜 1 +x:1 +木头疙瘩 1 +x:1 +枚 347 +x:347 +产品权 1 +x:1 +著作者 1 +x:1 +补色 1 +x:1 +贵族化 1 +x:1 +炎炎 1 +x:1 +不畏 1 +x:1 +硝化细菌 1 +x:1 +半地穴式 1 +x:1 +大舅 1 +x:1 +辞语 1 +x:1 +桃源县 1 +x:1 +情况 1 +x:1 +冬常服 1 +x:1 +不顾死活 1 +x:1 +云消雾散 1 +x:1 +注射 1 +x:1 +泉州籍 1 +x:1 +并非如此 1 +x:1 +依赖 1 +x:1 +斗山 1 +x:1 +魔水 1 +x:1 +套型 1 +x:1 +不用 1 +x:1 +日日月月 1 +x:1 +怡香院 1 +x:1 +大轴子 1 +x:1 +偏南 1 +x:1 +以便 1 +x:1 +不由 1 +x:1 +大良 1 +x:1 +吊杆 1 +x:1 +生命主义 1 +x:1 +不远千里 1 +x:1 +对等 1 +x:1 +苔原 1 +x:1 +辞讼 1 +x:1 +轮廓灯 1 +x:1 +白菜 1 +x:1 +土雷子 1 +x:1 +曲塘镇 1 +x:1 +刘家村 1 +x:1 +来生 1 +x:1 +租借地 1 +x:1 +骑士队 1 +x:1 +贺金 1 +x:1 +广 403 +x:403 +对策 1 +x:1 +足坛 1 +x:1 +棉兰老 1 +x:1 +玻璃厂 1 +x:1 +劣性 1 +x:1 +重用 1 +x:1 +莱斯特 1 +x:1 +财委会 1 +x:1 +水利界 1 +x:1 +豆豆 1 +x:1 +豆豉 1 +x:1 +挣钱 1 +x:1 +顶梁柱 1 +x:1 +可笑 1 +x:1 +作业本 1 +x:1 +车马费 1 +x:1 +联盟 1 +x:1 +毋宁 1 +x:1 +突击月 1 +x:1 +楼道 1 +x:1 +七连冠 1 +x:1 +警卫团 1 +x:1 +美滋滋 1 +x:1 +行医 1 +x:1 +办学率 1 +x:1 +触礁 1 +x:1 +鲁夸省 1 +x:1 +大秧歌 1 +x:1 +鬼 23 +x:23 +引燃 1 +x:1 +挤兑 1 +x:1 +大街 1 +x:1 +残困户 1 +x:1 +营业 1 +x:1 +爵士乐 1 +x:1 +号兵 1 +x:1 +音乐系 1 +x:1 +尤为 1 +x:1 +援例 1 +x:1 +软盘 1 +x:1 +化油器 1 +x:1 +酣然 1 +x:1 +行旅如织 1 +x:1 +对立 1 +x:1 +酬谢 1 +x:1 +以下 1 +x:1 +以上 1 +x:1 +租赁费 1 +x:1 +大菜 1 +x:1 +乌克兰队 1 +x:1 +灭火 1 +x:1 +阿司匹林 1 +x:1 +垂直带 1 +x:1 +指责 1 +x:1 +欢喜 1 +x:1 +后援团 1 +x:1 +连带关系 1 +x:1 +库内 1 +x:1 +补药 1 +x:1 +查问 1 +x:1 +白花 1 +x:1 +联合党 1 +x:1 +职业道德 1 +x:1 +因势利导 1 +x:1 +低毒级 1 +x:1 +劲射 1 +x:1 +科技版 1 +x:1 +律政司 1 +x:1 +挤出 1 +x:1 +新政协 1 +x:1 +立碑为铭 1 +x:1 +婉言 1 +x:1 +湖东 1 +x:1 +短期 1 +x:1 +调查官 1 +x:1 +轻飘飘 1 +x:1 +软瘫 1 +x:1 +心烦意乱 1 +x:1 +噌噌 1 +x:1 +配合 1 +x:1 +库克 1 +x:1 +宜牧 1 +x:1 +戒刀 1 +x:1 +穷期 1 +x:1 +外项 1 +x:1 +组合式 1 +x:1 +熬心 1 +x:1 +综合奖 1 +x:1 +按键 1 +x:1 +初装费 1 +x:1 +谈及 1 +x:1 +纷至沓来 1 +x:1 +关怀备至 1 +x:1 +欢唱 1 +x:1 +被开方数 1 +x:1 +成林 1 +x:1 +重病 1 +x:1 +指挥棒 1 +x:1 +重症 1 +x:1 +不理 1 +x:1 +二元 1 +x:1 +死党 1 +x:1 +闸刀 1 +x:1 +语文课 1 +x:1 +有章可循 1 +x:1 +哲布拉山 1 +x:1 +笑谈 1 +x:1 +坦克 1 +x:1 +本本 1 +x:1 +穿流 1 +x:1 +不知 1 +x:1 +斩假石 1 +x:1 +寻短见 1 +x:1 +墨水池 1 +x:1 +自找 1 +x:1 +办学点 1 +x:1 +前月 1 +x:1 +吹沙居 1 +x:1 +裂痕 1 +x:1 +大肥 1 +x:1 +粗气 1 +x:1 +伪证罪 1 +x:1 +尔 6 +x:6 +大肠 1 +x:1 +油头粉面 1 +x:1 +灰口铁 1 +x:1 +邮政所 1 +x:1 +披散 1 +x:1 +补胎 1 +x:1 +渔业法 1 +x:1 +死力 1 +x:1 +时间表 1 +x:1 +合宪性 1 +x:1 +抗诉案 1 +x:1 +大肆 1 +x:1 +三角学 1 +x:1 +一体式 1 +x:1 +群雄逐鹿 1 +x:1 +无源之水 1 +x:1 +假赔案 1 +x:1 +勋 5 +x:5 +尘封 1 +x:1 +控球技术 1 +x:1 +冰魂 1 +x:1 +巴拉圭 1 +x:1 +古都 1 +x:1 +广播剧 1 +x:1 +厚重感 1 +x:1 +石渠县 1 +x:1 +对称 1 +x:1 +铅块 1 +x:1 +重百 1 +x:1 +明末 1 +x:1 +猛跌 1 +x:1 +雨点子 1 +x:1 +粗衣淡食 1 +x:1 +自寻短见 1 +x:1 +拖车 1 +x:1 +查阅 1 +x:1 +廉政者 1 +x:1 +大胜 1 +x:1 +拖轮 1 +x:1 +大胆 1 +x:1 +递 48 +x:48 +将令 1 +x:1 +篾刀 1 +x:1 +瘦肉 1 +x:1 +寸步不离 1 +x:1 +大农场 1 +x:1 +质量卡 1 +x:1 +漉 1 +x:1 +胜负 1 +x:1 +赤霉素 1 +x:1 +如皋 1 +x:1 +贤能 1 +x:1 +核力量 1 +x:1 +外国人 1 +x:1 +粗沙 1 +x:1 +二分 1 +x:1 +低牌子 1 +x:1 +死刑 1 +x:1 +克音村 1 +x:1 +计算尺 1 +x:1 +不像话 1 +x:1 +普药 1 +x:1 +倒春寒 1 +x:1 +来着 1 +x:1 +羽坛 1 +x:1 +低声波 1 +x:1 +西湖洞村 1 +x:1 +大者 1 +x:1 +胜败 1 +x:1 +大考 1 +x:1 +烛形灯 1 +x:1 +大老 1 +x:1 +幸运 1 +x:1 +门脸儿 1 +x:1 +二则 1 +x:1 +胚胎 1 +x:1 +二副 1 +x:1 +免 155 +x:155 +周致 1 +x:1 +再贷款 1 +x:1 +拖运 1 +x:1 +丁点儿 1 +x:1 +情变 1 +x:1 +联用 1 +x:1 +七甲路 1 +x:1 +进而 1 +x:1 +的确 1 +x:1 +弃渔 1 +x:1 +份子 1 +x:1 +来看 1 +x:1 +走弯路 1 +x:1 +补考 1 +x:1 +无男孩 1 +x:1 +余香 1 +x:1 +供应券 1 +x:1 +引爆 1 +x:1 +古道 1 +x:1 +情史 1 +x:1 +调查处 1 +x:1 +陈笪村 1 +x:1 +六亲不认 1 +x:1 +死去 1 +x:1 +情分 1 +x:1 +座机 1 +x:1 +挤占 1 +x:1 +集电极 1 +x:1 +辞行 1 +x:1 +兖州市 1 +x:1 +顺理成章 1 +x:1 +灿若群星 1 +x:1 +奸商 1 +x:1 +供应司 1 +x:1 +守夜人 1 +x:1 +磁电 1 +x:1 +长坂坡 1 +x:1 +粗活 1 +x:1 +性骚扰 1 +x:1 +粗浅 1 +x:1 +大致 1 +x:1 +肥厚 1 +x:1 +瓜棚 1 +x:1 +烟灰 1 +x:1 +硒 1 +x:1 +大臣 1 +x:1 +真释 1 +x:1 +篾匠 1 +x:1 +张弓镇 1 +x:1 +滤色片 1 +x:1 +绕弯子 1 +x:1 +深得人心 1 +x:1 +不为人知 1 +x:1 +补助费 1 +x:1 +二双 1 +x:1 +本条 1 +x:1 +可疑人 1 +x:1 +谈兴 1 +x:1 +大丰县 1 +x:1 +惨境 1 +x:1 +折旧费 1 +x:1 +出售方 1 +x:1 +裂殖菌 1 +x:1 +先锋艇 1 +x:1 +裂璺 1 +x:1 +座架 1 +x:1 +赢家 1 +x:1 +超负荷 1 +x:1 +仪表堂堂 1 +x:1 +辈 34 +x:34 +警卫员 1 +x:1 +获益匪浅 1 +x:1 +桂 71 +x:71 +粒子束 1 +x:1 +抖 18 +x:18 +冷冷清清 1 +x:1 +拉格斯 1 +x:1 +勘误表 1 +x:1 +俳人 1 +x:1 +听天由命 1 +x:1 +大脑 1 +x:1 +誓作 1 +x:1 +秘鲁队 1 +x:1 +大脚 1 +x:1 +支 1140 +x:1140 +树神 1 +x:1 +自谋 1 +x:1 +情势 1 +x:1 +中农信 1 +x:1 +妄想型 1 +x:1 +广播厅 1 +x:1 +贴补率 1 +x:1 +全集观 1 +x:1 +上月份 1 +x:1 +库区 1 +x:1 +广播台 1 +x:1 +南塘村 1 +x:1 +养兵 1 +x:1 +大腿 1 +x:1 +码洋 1 +x:1 +号召 1 +x:1 +配器 1 +x:1 +南山村 1 +x:1 +证书费 1 +x:1 +库克斯区 1 +x:1 +重石 1 +x:1 +孟店桥村 1 +x:1 +愁思 1 +x:1 +大腕 1 +x:1 +回形针 1 +x:1 +固守 1 +x:1 +固安 1 +x:1 +大成 1 +x:1 +不即不离 1 +x:1 +龇牙咧嘴 1 +x:1 +幔帐 1 +x:1 +佳 181 +x:181 +二单 1 +x:1 +灰指甲 1 +x:1 +固定 1 +x:1 +仲冬 1 +x:1 +仪轨 1 +x:1 +孤伶伶 1 +x:1 +肃然 1 +x:1 +夜半更深 1 +x:1 +老好人 1 +x:1 +钢条 1 +x:1 +软玉 1 +x:1 +李家沟 1 +x:1 +楼长 1 +x:1 +死咸 1 +x:1 +穿梭 1 +x:1 +诸君 1 +x:1 +白蜡 1 +x:1 +追加 1 +x:1 +软糖 1 +x:1 +东南风 1 +x:1 +校医 1 +x:1 +钢板 1 +x:1 +石化城 1 +x:1 +那 2963 +x:2963 +仲夏 1 +x:1 +科教兴林 1 +x:1 +龟鹤延年 1 +x:1 +号名 1 +x:1 +刚巧 1 +x:1 +竹山县 1 +x:1 +当事人 1 +x:1 +谰 1 +x:1 +钢材 1 +x:1 +套印 1 +x:1 +维尼龙 1 +x:1 +附着力 1 +x:1 +太铁 1 +x:1 +披挂 1 +x:1 +套包 1 +x:1 +二哥 1 +x:1 +独具只眼 1 +x:1 +航站区 1 +x:1 +情商 1 +x:1 +钢木 1 +x:1 +轻工业局 1 +x:1 +恶语 1 +x:1 +外祸 1 +x:1 +羽冠 1 +x:1 +背道而驰 1 +x:1 +苏伊士 1 +x:1 +太钢 1 +x:1 +胜诉 1 +x:1 +突击手 1 +x:1 +修车店 1 +x:1 +丹麦队 1 +x:1 +牛刀小试 1 +x:1 +颁奖会 1 +x:1 +州选 1 +x:1 +重钙 1 +x:1 +广播员 1 +x:1 +叙说 1 +x:1 +研论会 1 +x:1 +普遍性 1 +x:1 +雷 923 +x:923 +节育器 1 +x:1 +错乱 1 +x:1 +观众群 1 +x:1 +猜中 1 +x:1 +忽 49 +x:49 +豆角 1 +x:1 +总府路 1 +x:1 +中幔 1 +x:1 +收杆 1 +x:1 +青城镇 1 +x:1 +重炮 1 +x:1 +早期 1 +x:1 +滑行道 1 +x:1 +套取 1 +x:1 +倚坐 1 +x:1 +舒卷 1 +x:1 +电介质 1 +x:1 +白螭 1 +x:1 +编余 1 +x:1 +铜业 1 +x:1 +重点 1 +x:1 +楼门 1 +x:1 +颧骨 1 +x:1 +劲头 1 +x:1 +施工处 1 +x:1 +核能力 1 +x:1 +美联社 1 +x:1 +鱼贯 1 +x:1 +潮剧 1 +x:1 +缓释 1 +x:1 +心底 1 +x:1 +鹅毛扇 1 +x:1 +拄 20 +x:20 +高感光度 1 +x:1 +大虾 1 +x:1 +死命 1 +x:1 +更鼓 1 +x:1 +捐献卡 1 +x:1 +钢架 1 +x:1 +不然 1 +x:1 +孕 6 +x:6 +故步自封 1 +x:1 +大虫 1 +x:1 +小朋友 1 +x:1 +谈固 1 +x:1 +啤酒业 1 +x:1 +杂面 1 +x:1 +牧歌式 1 +x:1 +医学界 1 +x:1 +共有性 1 +x:1 +注塑 1 +x:1 +东台市 1 +x:1 +韵味 1 +x:1 +戒坛 1 +x:1 +出线权 1 +x:1 +老妪能解 1 +x:1 +哲蚌寺 1 +x:1 +五爱星 1 +x:1 +弦乐器 1 +x:1 +中转地 1 +x:1 +害人虫 1 +x:1 +劳役地租 1 +x:1 +交易周 1 +x:1 +山野菜 1 +x:1 +枪击 1 +x:1 +不胫而走 1 +x:1 +狂泉 1 +x:1 +供需 1 +x:1 +足协 1 +x:1 +关禁 1 +x:1 +众声 1 +x:1 +生物学家 1 +x:1 +发证 1 +x:1 +昏惨惨 1 +x:1 +校刊 1 +x:1 +信访人 1 +x:1 +酣畅 1 +x:1 +登记数 1 +x:1 +娇嫩嫩 1 +x:1 +改制面 1 +x:1 +逐块 1 +x:1 +刺 62 +x:62 +阔老 1 +x:1 +一年期 1 +x:1 +错位 1 +x:1 +平平直直 1 +x:1 +羊毛衫裤 1 +x:1 +非全国性 1 +x:1 +感应圈 1 +x:1 +严明 1 +x:1 +指标性 1 +x:1 +树群 1 +x:1 +古韵 1 +x:1 +权杖 1 +x:1 +以攻为守 1 +x:1 +岗警 1 +x:1 +三角尺 1 +x:1 +编审科 1 +x:1 +空气型 1 +x:1 +对练 1 +x:1 +追叙 1 +x:1 +空置 1 +x:1 +套制 1 +x:1 +雪峰 1 +x:1 +序列 1 +x:1 +酣甜 1 +x:1 +歇息 1 +x:1 +软舌螺 1 +x:1 +白虎 1 +x:1 +情味 1 +x:1 +交响乐团 1 +x:1 +校务 1 +x:1 +℃ 62 +x:62 +裂片 1 +x:1 +普及率 1 +x:1 +哥白尼 1 +x:1 +供应商 1 +x:1 +不灵 1 +x:1 +函件 1 +x:1 +扑火队 1 +x:1 +耙 7 +x:7 +泪脂质 1 +x:1 +客房部 1 +x:1 +督促 1 +x:1 +针灸师 1 +x:1 +彩花 1 +x:1 +白蚁 1 +x:1 +敬谢不敏 1 +x:1 +尘寰 1 +x:1 +对局费 1 +x:1 +校办 1 +x:1 +告特叶 1 +x:1 +追印 1 +x:1 +快板儿 1 +x:1 +软片 1 +x:1 +引申 1 +x:1 +权柄 1 +x:1 +狂气 1 +x:1 +幻象 1 +x:1 +古典文学 1 +x:1 +引用 1 +x:1 +公务机 1 +x:1 +恙 1 +x:1 +犀牛 1 +x:1 +吊扇 1 +x:1 +团 441 +x:441 +情哥 1 +x:1 +电渣炉 1 +x:1 +舰载 1 +x:1 +白蛇 1 +x:1 +生物性 1 +x:1 +校勘 1 +x:1 +杀人如麻 1 +x:1 +晾晒 1 +x:1 +吊扣 1 +x:1 +拉合尔市 1 +x:1 +羽叶 1 +x:1 +约通社 1 +x:1 +奴隶主 1 +x:1 +谈吐 1 +x:1 +关窗 1 +x:1 +潮头 1 +x:1 +辐射式 1 +x:1 +化学能 1 +x:1 +通经 1 +x:1 +楼面 1 +x:1 +翔实 1 +x:1 +笑语 1 +x:1 +哥儿们 1 +x:1 +佐剂 1 +x:1 +联合国 1 +x:1 +逗趣 1 +x:1 +腰果汁 1 +x:1 +大蒜 1 +x:1 +笑话 1 +x:1 +口若悬河 1 +x:1 +中南局 1 +x:1 +蒜泥 1 +x:1 +佐治亚 1 +x:1 +三角形 1 +x:1 +事业有成 1 +x:1 +潜心者 1 +x:1 +游说 1 +x:1 +调查局 1 +x:1 +阳性植物 1 +x:1 +沂源 1 +x:1 +千难万险 1 +x:1 +重物 1 +x:1 +稽核 1 +x:1 +妆奁 1 +x:1 +配号 1 +x:1 +死因 1 +x:1 +狂澜 1 +x:1 +宗师 1 +x:1 +皂荚 1 +x:1 +清莱府 1 +x:1 +拦网 1 +x:1 +死囚 1 +x:1 +质量型 1 +x:1 +草场村 1 +x:1 +古铜 1 +x:1 +批示 1 +x:1 +配发 1 +x:1 +赶集会 1 +x:1 +解放社 1 +x:1 +防雨布 1 +x:1 +铅印 1 +x:1 +遮光 1 +x:1 +大农区 1 +x:1 +爪尖儿 1 +x:1 +重犯 1 +x:1 +畅销 1 +x:1 +』 4051 +x:4051 +学者型 1 +x:1 +周薪 1 +x:1 +大营 1 +x:1 +关税 1 +x:1 +科技界 1 +x:1 +白薯 1 +x:1 +泳技 1 +x:1 +千难万难 1 +x:1 +快班车 1 +x:1 +看见 1 +x:1 +开立 1 +x:1 +狂潮 1 +x:1 +鸿鹄之志 1 +x:1 +项链坠 1 +x:1 +李家渡 1 +x:1 +羽协 1 +x:1 +忙不迭 1 +x:1 +程度 1 +x:1 +红模子 1 +x:1 +太阳 1 +x:1 +砍头 1 +x:1 +位数 1 +x:1 +歧管 1 +x:1 +剩余油 1 +x:1 +寻求 1 +x:1 +大著 1 +x:1 +羽化 1 +x:1 +太行山 1 +x:1 +犀照 1 +x:1 +魔术 1 +x:1 +瓷种 1 +x:1 +程序 1 +x:1 +保和殿 1 +x:1 +供货量 1 +x:1 +马店镇 1 +x:1 +检字法 1 +x:1 +呷 4 +x:4 +药剂科 1 +x:1 +不独 1 +x:1 +酣睡 1 +x:1 +水平沟 1 +x:1 +供销 1 +x:1 +劣者 1 +x:1 +主流程 1 +x:1 +熬夜 1 +x:1 +白头发 1 +x:1 +注定 1 +x:1 +九二零 1 +x:1 +狒狒 1 +x:1 +行刺 1 +x:1 +万绿湖 1 +x:1 +奸党 1 +x:1 +瓷砖 1 +x:1 +秀山 1 +x:1 +表决 1 +x:1 +铅制 1 +x:1 +活火山 1 +x:1 +隐身术 1 +x:1 +功成身退 1 +x:1 +山高水低 1 +x:1 +霞云岭乡 1 +x:1 +来犯 1 +x:1 +僵化 1 +x:1 +双眸 1 +x:1 +联点 1 +x:1 +义勇军 1 +x:1 +不犯 1 +x:1 +采访记 1 +x:1 +追击 1 +x:1 +鞭辟入里 1 +x:1 +运用裕如 1 +x:1 +初时 1 +x:1 +联合型 1 +x:1 +薄弱校 1 +x:1 +刑侦 1 +x:1 +改天换地 1 +x:1 +古间 1 +x:1 +千家万户 1 +x:1 +三角帆 1 +x:1 +圣经 1 +x:1 +教学法 1 +x:1 +刚度 1 +x:1 +程式 1 +x:1 +默化潜移 1 +x:1 +楼阁 1 +x:1 +大藏 1 +x:1 +死地 1 +x:1 +教育社 1 +x:1 +证据法 1 +x:1 +了 76178 +x:76178 +贫乏 1 +x:1 +协理 1 +x:1 +配制 1 +x:1 +泪腺 1 +x:1 +重现 1 +x:1 +小不点 1 +x:1 +拟定 1 +x:1 +视同儿戏 1 +x:1 +搞好 1 +x:1 +库坝 1 +x:1 +约 1311 +x:1311 +保安厅 1 +x:1 +号型 1 +x:1 +棉研所 1 +x:1 +叙利亚 1 +x:1 +瓷碗 1 +x:1 +汉口站 1 +x:1 +哑口无言 1 +x:1 +马爬犁 1 +x:1 +婉谢 1 +x:1 +棋队 1 +x:1 +挤垮 1 +x:1 +棋院 1 +x:1 +荃 7 +x:7 +违禁物品 1 +x:1 +醪糟 1 +x:1 +煞住 1 +x:1 +泄底 1 +x:1 +猪草机 1 +x:1 +大合唱 1 +x:1 +关卡税 1 +x:1 +配剂 1 +x:1 +古镇 1 +x:1 +搞头 1 +x:1 +闹灾荒 1 +x:1 +壅塞 1 +x:1 +环抱 1 +x:1 +供应地 1 +x:1 +肃立 1 +x:1 +铜管乐器 1 +x:1 +队委会 1 +x:1 +走牛 1 +x:1 +脆 13 +x:13 +放热反应 1 +x:1 +狞笑 1 +x:1 +扭亏转盈 1 +x:1 +能者多劳 1 +x:1 +预备役团 1 +x:1 +中寒武世 1 +x:1 +钾肥 1 +x:1 +平均分 1 +x:1 +长大成人 1 +x:1 +基西米市 1 +x:1 +情夫 1 +x:1 +分校 1 +x:1 +槐荫区 1 +x:1 +泄入 1 +x:1 +车户 1 +x:1 +平均制 1 +x:1 +副科 1 +x:1 +大同江 1 +x:1 +然则 1 +x:1 +扶手椅 1 +x:1 +可爱 1 +x:1 +总经理 1 +x:1 +用人关 1 +x:1 +豆庄镇 1 +x:1 +闸室 1 +x:1 +初战 1 +x:1 +索赔证 1 +x:1 +花边新闻 1 +x:1 +医务室 1 +x:1 +建筑业 1 +x:1 +八仙 1 +x:1 +特里尔市 1 +x:1 +石化安 1 +x:1 +午托部 1 +x:1 +乡霸 1 +x:1 +天不作美 1 +x:1 +卫星舱 1 +x:1 +百里洲镇 1 +x:1 +蕉园 1 +x:1 +胸中无数 1 +x:1 +包围圈 1 +x:1 +泳池 1 +x:1 +牛郎星 1 +x:1 +八一 1 +x:1 +位次 1 +x:1 +眼睫毛 1 +x:1 +脸子 1 +x:1 +情妇 1 +x:1 +联署 1 +x:1 +肃穆 1 +x:1 +执笔者 1 +x:1 +打字员 1 +x:1 +米/秒 1 +x:1 +隔 144 +x:144 +黑白胶片 1 +x:1 +校徽 1 +x:1 +整军 1 +x:1 +路途 1 +x:1 +贸工技 1 +x:1 +检委会 1 +x:1 +河南省 1 +x:1 +木鼓舞 1 +x:1 +舰船 1 +x:1 +拾取 1 +x:1 +联网 1 +x:1 +红灵酊 1 +x:1 +黑竹 1 +x:1 +粗暴 1 +x:1 +洋枪 1 +x:1 +呼家楼 1 +x:1 +消毒剂 1 +x:1 +优美 1 +x:1 +塞翁失马 1 +x:1 +鸭场 1 +x:1 +落花生 1 +x:1 +滴漏 1 +x:1 +进言 1 +x:1 +舰艇 1 +x:1 +号声 1 +x:1 +冰释 1 +x:1 +裂缝 1 +x:1 +生意盎然 1 +x:1 +汗颜 1 +x:1 +读书会 1 +x:1 +软网 1 +x:1 +减低 1 +x:1 +欢欢喜喜 1 +x:1 +铨 1 +x:1 +内华达州 1 +x:1 +淮 41 +x:41 +冷水澡 1 +x:1 +膏剂 1 +x:1 +计算器 1 +x:1 +调解率 1 +x:1 +真珠 1 +x:1 +木材 1 +x:1 +联缀 1 +x:1 +豆薯 1 +x:1 +楼顶 1 +x:1 +劣株 1 +x:1 +科技站 1 +x:1 +养家 1 +x:1 +减产 1 +x:1 +大正八年 1 +x:1 +铅封 1 +x:1 +橙黄 1 +x:1 +纸笺 1 +x:1 +奴才 1 +x:1 +装移机 1 +x:1 +减人 1 +x:1 +大计 1 +x:1 +挤奶 1 +x:1 +交接处 1 +x:1 +几何图形 1 +x:1 +减亏 1 +x:1 +军运股 1 +x:1 +联络 1 +x:1 +橘柑 1 +x:1 +道里区 1 +x:1 +太谷县 1 +x:1 +外部 1 +x:1 +用 5303 +x:5303 +滴滴 1 +x:1 +联结 1 +x:1 +体育界 1 +x:1 +引种 1 +x:1 +号外 1 +x:1 +庆典型 1 +x:1 +联组 1 +x:1 +调查区 1 +x:1 +针砭时弊 1 +x:1 +粗杆 1 +x:1 +药材店 1 +x:1 +编印发 1 +x:1 +魔方 1 +x:1 +脖颈 1 +x:1 +大课 1 +x:1 +冰锥 1 +x:1 +郑 719 +x:719 +冷寂 1 +x:1 +造船业 1 +x:1 +清水衙门 1 +x:1 +尘土 1 +x:1 +白寺口沟 1 +x:1 +减价 1 +x:1 +优雅 1 +x:1 +泯灭 1 +x:1 +精彩纷呈 1 +x:1 +镂雕 1 +x:1 +外邪 1 +x:1 +先锋街 1 +x:1 +计量 1 +x:1 +拖沓 1 +x:1 +搞垮 1 +x:1 +超群 1 +x:1 +与世隔膜 1 +x:1 +树王 1 +x:1 +戒律 1 +x:1 +铅山 1 +x:1 +裂纹 1 +x:1 +谈定 1 +x:1 +二大 1 +x:1 +外遇 1 +x:1 +造化物 1 +x:1 +尘埃 1 +x:1 +貉绒 1 +x:1 +铜管乐 1 +x:1 +娱乐片 1 +x:1 +情境 1 +x:1 +稽查 1 +x:1 +太煤 1 +x:1 +外道 1 +x:1 +书卷气 1 +x:1 +豆蓉 1 +x:1 +中世纪 1 +x:1 +革新派 1 +x:1 +季季 1 +x:1 +撞 121 +x:121 +土包子 1 +x:1 +抗尘走俗 1 +x:1 +校庆 1 +x:1 +刚健 1 +x:1 +钟鸣鼎食 1 +x:1 +路遇 1 +x:1 +纪念碑 1 +x:1 +渣土 1 +x:1 +缘份 1 +x:1 +有林地 1 +x:1 +圣火 1 +x:1 +六汪镇 1 +x:1 +缘于 1 +x:1 +供应处 1 +x:1 +铁力市 1 +x:1 +自卖自夸 1 +x:1 +计酬 1 +x:1 +二奶 1 +x:1 +江永县 1 +x:1 +丢人现眼 1 +x:1 +构词法 1 +x:1 +置评 1 +x:1 +组装式 1 +x:1 +油井架 1 +x:1 +猛虎 1 +x:1 +死契 1 +x:1 +养子 1 +x:1 +局管内 1 +x:1 +透粉 1 +x:1 +尘垢 1 +x:1 +苦木素 1 +x:1 +工业气压 1 +x:1 +瓷盒 1 +x:1 +贴心 1 +x:1 +亚麻 1 +x:1 +奸徒 1 +x:1 +仪表 1 +x:1 +养 400 +x:400 +配属 1 +x:1 +沉默寡言 1 +x:1 +瓷盘 1 +x:1 +智谋超人 1 +x:1 +各尽其责 1 +x:1 +针锋相对 1 +x:1 +误认为 1 +x:1 +敌酋 1 +x:1 +厘米波 1 +x:1 +人贫志坚 1 +x:1 +通知单 1 +x:1 +触爪 1 +x:1 +镇纸 1 +x:1 +拦海大坝 1 +x:1 +辐射区 1 +x:1 +放卫星 1 +x:1 +念珠菌性 1 +x:1 +公切线 1 +x:1 +俘获 1 +x:1 +停产令 1 +x:1 +欢度 1 +x:1 +屠 17 +x:17 +异乎寻常 1 +x:1 +张夏镇 1 +x:1 +似是而非 1 +x:1 +镇镇 1 +x:1 +烛台 1 +x:1 +板柜 1 +x:1 +乘 262 +x:262 +两码事 1 +x:1 +古风 1 +x:1 +三角区 1 +x:1 +不羁 1 +x:1 +普训 1 +x:1 +镇长 1 +x:1 +赤霉病 1 +x:1 +适销对路 1 +x:1 +放空炮 1 +x:1 +阁楼 1 +x:1 +雁荡山 1 +x:1 +宝贝疙瘩 1 +x:1 +演唱队 1 +x:1 +进袭 1 +x:1 +质量学 1 +x:1 +月影 1 +x:1 +后进村 1 +x:1 +有 30901 +x:30901 +追尾 1 +x:1 +英姿勃勃 1 +x:1 +义务教育 1 +x:1 +翻然悔悟 1 +x:1 +通勤车 1 +x:1 +房山区 1 +x:1 +进行 1 +x:1 +如约 1 +x:1 +扑克迷 1 +x:1 +发电机 1 +x:1 +补血 1 +x:1 +改道 1 +x:1 +东阳镇 1 +x:1 +剧装 1 +x:1 +戒备 1 +x:1 +荡魂摄魄 1 +x:1 +凸镜 1 +x:1 +计票 1 +x:1 +邮友 1 +x:1 +记叙文 1 +x:1 +流行源 1 +x:1 +保护人 1 +x:1 +联阵 1 +x:1 +重续 1 +x:1 +再就业者 1 +x:1 +出线楼 1 +x:1 +非业务 1 +x:1 +对照 1 +x:1 +说明性 1 +x:1 +有借有还 1 +x:1 +大衣 1 +x:1 +能工巧匠 1 +x:1 +传声器 1 +x:1 +重富欺贫 1 +x:1 +慢棋赛 1 +x:1 +光景儿 1 +x:1 +重组 1 +x:1 +永常村 1 +x:1 +畅饮 1 +x:1 +子午胎 1 +x:1 +另 1134 +x:1134 +埽 1 +x:1 +穷汉 1 +x:1 +无关痛痒 1 +x:1 +保育生 1 +x:1 +医务处 1 +x:1 +妒嫉 1 +x:1 +不祥 1 +x:1 +鹊起 1 +x:1 +联系 1 +x:1 +二审 1 +x:1 +西西里 1 +x:1 +小汤山 1 +x:1 +五彩 1 +x:1 +欢快 1 +x:1 +葙 1 +x:1 +借款方 1 +x:1 +辞职 1 +x:1 +潮州 1 +x:1 +动荡期 1 +x:1 +一贫如洗 1 +x:1 +鲜嫩嫩 1 +x:1 +笠 1 +x:1 +腊月三十 1 +x:1 +校射 1 +x:1 +欢心 1 +x:1 +篾子 1 +x:1 +逍遥法外 1 +x:1 +暖湿气流 1 +x:1 +新泾乡 1 +x:1 +北古村 1 +x:1 +谈天 1 +x:1 +大要 1 +x:1 +粗放 1 +x:1 +死守 1 +x:1 +灾难史 1 +x:1 +补角 1 +x:1 +库容 1 +x:1 +书生之见 1 +x:1 +前奏曲 1 +x:1 +重罪 1 +x:1 +砖瓦房 1 +x:1 +大解 1 +x:1 +天主教会 1 +x:1 +白衣 1 +x:1 +弄虚作假 1 +x:1 +令人堪忧 1 +x:1 +兴隆村 1 +x:1 +被纪念者 1 +x:1 +钢栅 1 +x:1 +叶红素 1 +x:1 +护理员 1 +x:1 +鸿蒙 1 +x:1 +供应室 1 +x:1 +精神病 1 +x:1 +夏威夷 1 +x:1 +死寂 1 +x:1 +大观 1 +x:1 +号子 1 +x:1 +尾水门机 1 +x:1 +固化 1 +x:1 +资深 1 +x:1 +念珠 1 +x:1 +刚劲 1 +x:1 +重罚 1 +x:1 +英姿勃发 1 +x:1 +以礼相待 1 +x:1 +配带 1 +x:1 +辐射力 1 +x:1 +警卫局 1 +x:1 +亲近感 1 +x:1 +胶印机 1 +x:1 +广播室 1 +x:1 +库存 1 +x:1 +梁五铢 1 +x:1 +蛋清 1 +x:1 +魔杖 1 +x:1 +超凡入圣 1 +x:1 +欲晓 1 +x:1 +瘫软 1 +x:1 +岗薪 1 +x:1 +所有制 1 +x:1 +超额利润 1 +x:1 +莽莽苍苍 1 +x:1 +大褂 1 +x:1 +白袍 1 +x:1 +跃动感 1 +x:1 +养女 1 +x:1 +圣物 1 +x:1 +变动不居 1 +x:1 +大西 1 +x:1 +可燃 1 +x:1 +后天门 1 +x:1 +瓷瓶 1 +x:1 +千枚岩 1 +x:1 +刚刚 1 +x:1 +共和镇 1 +x:1 +蝇拍 1 +x:1 +决计 1 +x:1 +禁捕期 1 +x:1 +急进派 1 +x:1 +精神界 1 +x:1 +钢梁 1 +x:1 +大襟 1 +x:1 +蒙达利亚 1 +x:1 +滴水 1 +x:1 +泥汊镇 1 +x:1 +固原 1 +x:1 +效尤 1 +x:1 +畅顺 1 +x:1 +遁世者 1 +x:1 +训练台 1 +x:1 +泄劲 1 +x:1 +夏令营 1 +x:1 +码放 1 +x:1 +豆腐 1 +x:1 +海州区 1 +x:1 +优等 1 +x:1 +稠油 1 +x:1 +武汉段 1 +x:1 +瓜果 1 +x:1 +太上皇 1 +x:1 +神力 1 +x:1 +欢声 1 +x:1 +套子 1 +x:1 +胰淀粉酶 1 +x:1 +凌空 1 +x:1 +茶厂 1 +x:1 +浑然天成 1 +x:1 +有根有据 1 +x:1 +斧凿声 1 +x:1 +软管 1 +x:1 +南河村 1 +x:1 +船夫曲 1 +x:1 +战斗班 1 +x:1 +测试仪 1 +x:1 +寄售库 1 +x:1 +骨子里 1 +x:1 +好不 1 +x:1 +黎黑 1 +x:1 +无障碍 1 +x:1 +流峪镇 1 +x:1 +冰镐 1 +x:1 +杠 9 +x:9 +外文局 1 +x:1 +释惑 1 +x:1 +好书 1 +x:1 +周转 1 +x:1 +花生地 1 +x:1 +热效应 1 +x:1 +树皮 1 +x:1 +不禁 1 +x:1 +位置图 1 +x:1 +开门见喜 1 +x:1 +承诺函 1 +x:1 +橡皮筏子 1 +x:1 +气体 1 +x:1 +农学系 1 +x:1 +好久 1 +x:1 +甲鱼 1 +x:1 +广播局 1 +x:1 +鸭绿江 1 +x:1 +好事 1 +x:1 +呢绒 1 +x:1 +戒心 1 +x:1 +进身 1 +x:1 +合二而一 1 +x:1 +中经信 1 +x:1 +冰镩 1 +x:1 +串通一气 1 +x:1 +洗涤品 1 +x:1 +洁 52 +x:52 +周边 1 +x:1 +重阳 1 +x:1 +法制科 1 +x:1 +死尸 1 +x:1 +类木行星 1 +x:1 +好人 1 +x:1 +差事 1 +x:1 +登记法 1 +x:1 +口服 1 +x:1 +士兵证 1 +x:1 +她家 1 +x:1 +木板 1 +x:1 +配备 1 +x:1 +韵尾 1 +x:1 +彰 6 +x:6 +枳壳 1 +x:1 +二小 1 +x:1 +劲儿 1 +x:1 +杂然 1 +x:1 +好些 1 +x:1 +介休 1 +x:1 +凹透镜 1 +x:1 +校官 1 +x:1 +空壳 1 +x:1 +脑震荡 1 +x:1 +差价 1 +x:1 +外销 1 +x:1 +傻瓜相机 1 +x:1 +淮城镇 1 +x:1 +笑脸 1 +x:1 +城建司 1 +x:1 +科技编 1 +x:1 +干部部 1 +x:1 +勤俭建国 1 +x:1 +单 269 +x:269 +先锋路 1 +x:1 +动物性 1 +x:1 +拉力赛 1 +x:1 +裘 14 +x:14 +蚯蚓 1 +x:1 +循规蹈矩 1 +x:1 +重磅 1 +x:1 +国际共运 1 +x:1 +淤积物 1 +x:1 +调查团 1 +x:1 +走投无路 1 +x:1 +吊死 1 +x:1 +洞井镇 1 +x:1 +文理科 1 +x:1 +棋王 1 +x:1 +配套 1 +x:1 +关灯 1 +x:1 +采访者 1 +x:1 +魔怪 1 +x:1 +空洞无物 1 +x:1 +温甜幽远 1 +x:1 +黄绿色 1 +x:1 +旱井 1 +x:1 +触电 1 +x:1 +真龙 1 +x:1 +进进 1 +x:1 +好似 1 +x:1 +苔干 1 +x:1 +稳定率 1 +x:1 +阁藏 1 +x:1 +校对 1 +x:1 +乡镇企业 1 +x:1 +科技组 1 +x:1 +补过 1 +x:1 +介于 1 +x:1 +持续性 1 +x:1 +遗诏 1 +x:1 +座椅 1 +x:1 +白帝城 1 +x:1 +钢铁厂 1 +x:1 +注册 1 +x:1 +差使 1 +x:1 +阳信 1 +x:1 +扶残解困 1 +x:1 +镂空 1 +x:1 +讲求 1 +x:1 +小浪底 1 +x:1 +钢渣 1 +x:1 +好使 1 +x:1 +座楼 1 +x:1 +对比色 1 +x:1 +追寻 1 +x:1 +同甘苦 1 +x:1 +根子 1 +x:1 +帕塔亚 1 +x:1 +效忠 1 +x:1 +外钞 1 +x:1 +成就感 1 +x:1 +瓷片 1 +x:1 +一叶障目 1 +x:1 +幸而 1 +x:1 +大运 1 +x:1 +大连 1 +x:1 +大远 1 +x:1 +声光电 1 +x:1 +大过 1 +x:1 +至 4088 +x:4088 +房事 1 +x:1 +一贯制 1 +x:1 +颠沛 1 +x:1 +蓄水 1 +x:1 +龙岩坡 1 +x:1 +因祸得福 1 +x:1 +伎俩 1 +x:1 +偷拿者 1 +x:1 +计算化 1 +x:1 +水利科 1 +x:1 +周身 1 +x:1 +玻璃品 1 +x:1 +众 92 +x:92 +不置一词 1 +x:1 +木枕 1 +x:1 +冰钎 1 +x:1 +考茨基 1 +x:1 +小曲儿 1 +x:1 +配角儿 1 +x:1 +脱口而出 1 +x:1 +气井 1 +x:1 +怪象 1 +x:1 +我镇 1 +x:1 +煨 3 +x:3 +房主 1 +x:1 +阳伞 1 +x:1 +冰铜 1 +x:1 +大轧 1 +x:1 +大车 1 +x:1 +对白 1 +x:1 +五峰 1 +x:1 +受贿人 1 +x:1 +福特车 1 +x:1 +注入 1 +x:1 +盘丝洞 1 +x:1 +房东 1 +x:1 +砍刀 1 +x:1 +以人为本 1 +x:1 +可知 1 +x:1 +触痛 1 +x:1 +蹭 9 +x:9 +介乎 1 +x:1 +半身不遂 1 +x:1 +奖台 1 +x:1 +闲情逸致 1 +x:1 +联程 1 +x:1 +休养院 1 +x:1 +劈天盖地 1 +x:1 +关照 1 +x:1 +特困村 1 +x:1 +返销 1 +x:1 +压迫 1 +x:1 +豆荚 1 +x:1 +白费 1 +x:1 +软禁 1 +x:1 +套套 1 +x:1 +白货 1 +x:1 +孝顺镇 1 +x:1 +持锨者 1 +x:1 +库布其 1 +x:1 +白质 1 +x:1 +御 4 +x:4 +聚四氟 1 +x:1 +呼兰河域 1 +x:1 +探鱼仪 1 +x:1 +真鲷 1 +x:1 +体育版 1 +x:1 +训导 1 +x:1 +坚定不移 1 +x:1 +大新乡 1 +x:1 +然后 1 +x:1 +眼睁睁 1 +x:1 +房价 1 +x:1 +校外 1 +x:1 +高峰村 1 +x:1 +成文 1 +x:1 +黑板报 1 +x:1 +过江龙 1 +x:1 +规格化 1 +x:1 +蚊帐 1 +x:1 +小传 1 +x:1 +歇歇 1 +x:1 +由不得 1 +x:1 +职便 1 +x:1 +铅字 1 +x:1 +配对 1 +x:1 +调查员 1 +x:1 +锄草 1 +x:1 +虎踞龙蟠 1 +x:1 +现成饭 1 +x:1 +花鸟画家 1 +x:1 +冰面 1 +x:1 +史论家 1 +x:1 +高峰期 1 +x:1 +小伙 1 +x:1 +正选赛 1 +x:1 +判若云泥 1 +x:1 +粗枝大叶 1 +x:1 +当务之重 1 +x:1 +小修 1 +x:1 +履险如夷 1 +x:1 +水利站 1 +x:1 +打酒 1 +x:1 +惊异感 1 +x:1 +优秀 1 +x:1 +穿戴 1 +x:1 +正反面 1 +x:1 +奇里诺奇 1 +x:1 +新乡市 1 +x:1 +处心积虑 1 +x:1 +辐射型 1 +x:1 +义无返顾 1 +x:1 +军烈属 1 +x:1 +压轴 1 +x:1 +冰鞋 1 +x:1 +字幕 1 +x:1 +蜂鸟 1 +x:1 +穷根 1 +x:1 +凄 3 +x:3 +履行 1 +x:1 +外面 1 +x:1 +辞藻 1 +x:1 +坦帕 1 +x:1 +长寿路 1 +x:1 +职位 1 +x:1 +不等 1 +x:1 +酒嗉子 1 +x:1 +矗起 1 +x:1 +戳 13 +x:13 +魔手 1 +x:1 +月底 1 +x:1 +辞退制 1 +x:1 +记事本 1 +x:1 +坐位 1 +x:1 +联社 1 +x:1 +不符 1 +x:1 +子午仪 1 +x:1 +警卫处 1 +x:1 +大丰市 1 +x:1 +口袋罪 1 +x:1 +小便 1 +x:1 +南庄村 1 +x:1 +色彩斑斓 1 +x:1 +欢娱 1 +x:1 +大象 1 +x:1 +千年问题 1 +x:1 +情志 1 +x:1 +镇里 1 +x:1 +满目狼藉 1 +x:1 +触目 1 +x:1 +钻探队 1 +x:1 +念白 1 +x:1 +俚语 1 +x:1 +让道 1 +x:1 +我队 1 +x:1 +大豆 1 +x:1 +楼龄 1 +x:1 +辩护士 1 +x:1 +批销 1 +x:1 +十恶不赦 1 +x:1 +趾高气扬 1 +x:1 +盆景型 1 +x:1 +殃 1 +x:1 +联磺 1 +x:1 +万语千言 1 +x:1 +不竭 1 +x:1 +不端 1 +x:1 +一鼻子灰 1 +x:1 +新生代 1 +x:1 +劲力 1 +x:1 +汽油机 1 +x:1 +芦山乡 1 +x:1 +套塑 1 +x:1 +篮筐 1 +x:1 +果木园 1 +x:1 +大连队 1 +x:1 +红色素 1 +x:1 +可用 1 +x:1 +夫妻情 1 +x:1 +职介 1 +x:1 +死胎 1 +x:1 +重笔 1 +x:1 +满目苍凉 1 +x:1 +树病 1 +x:1 +应急款 1 +x:1 +院中 1 +x:1 +拖船 1 +x:1 +奸夫 1 +x:1 +求 508 +x:508 +小丫 1 +x:1 +小个 1 +x:1 +空调界 1 +x:1 +麒麟山 1 +x:1 +太行山区 1 +x:1 +职业高中 1 +x:1 +钢水 1 +x:1 +野食儿 1 +x:1 +治丧 1 +x:1 +大路 1 +x:1 +补足 1 +x:1 +西八道街 1 +x:1 +二心 1 +x:1 +商补 1 +x:1 +迫 19 +x:19 +滦 1 +x:1 +穿插 1 +x:1 +除此而外 1 +x:1 +死心 1 +x:1 +叫好不绝 1 +x:1 +塞罕坝 1 +x:1 +三滩乡 1 +x:1 +小丘 1 +x:1 +大跌 1 +x:1 +遗训 1 +x:1 +小丑 1 +x:1 +打小算盘 1 +x:1 +保值率 1 +x:1 +豆苗 1 +x:1 +大贾 1 +x:1 +打蔫儿 1 +x:1 +小令 1 +x:1 +平玉县 1 +x:1 +戒尺 1 +x:1 +大败 1 +x:1 +胜者 1 +x:1 +渣儿 1 +x:1 +盆景园 1 +x:1 +篮篓 1 +x:1 +可疑 1 +x:1 +承诺制 1 +x:1 +科技类 1 +x:1 +外院 1 +x:1 +缺乏症 1 +x:1 +已知数 1 +x:1 +物化劳动 1 +x:1 +补赛 1 +x:1 +首日封 1 +x:1 +宸 7 +x:7 +小仓 1 +x:1 +传达室 1 +x:1 +俘虏 1 +x:1 +李家村 1 +x:1 +冰雕 1 +x:1 +平空 1 +x:1 +商市场 1 +x:1 +职中 1 +x:1 +同行间 1 +x:1 +趣闻 1 +x:1 +大赦 1 +x:1 +来稿 1 +x:1 +马不停蹄 1 +x:1 +左家塘 1 +x:1 +灭绝 1 +x:1 +补贴 1 +x:1 +心影 1 +x:1 +豆花 1 +x:1 +软硬 1 +x:1 +小事 1 +x:1 +吊桶 1 +x:1 +冰雹 1 +x:1 +大赛 1 +x:1 +豆芽 1 +x:1 +果洛州 1 +x:1 +进贡 1 +x:1 +进货 1 +x:1 +进账 1 +x:1 +进贤 1 +x:1 +冰雪 1 +x:1 +吊桥 1 +x:1 +冰雨 1 +x:1 +大赋 1 +x:1 +水利管 1 +x:1 +含氧量 1 +x:1 +不日 1 +x:1 +外观 1 +x:1 +小公 1 +x:1 +气区 1 +x:1 +不无 1 +x:1 +速写 1 +x:1 +房号 1 +x:1 +感恩戴德 1 +x:1 +潇洒不羁 1 +x:1 +凌晨 1 +x:1 +炎性 1 +x:1 +房产 1 +x:1 +外角 1 +x:1 +不时 1 +x:1 +倒汇者 1 +x:1 +喙 1 +x:1 +小兵 1 +x:1 +联查 1 +x:1 +纱布 1 +x:1 +捡拾 1 +x:1 +瓷漆 1 +x:1 +驾 34 +x:34 +速冻 1 +x:1 +气化 1 +x:1 +治党 1 +x:1 +奥科辛弋 1 +x:1 +主流派 1 +x:1 +看齐 1 +x:1 +包身契 1 +x:1 +试验园 1 +x:1 +方 746 +x:746 +编导 1 +x:1 +要求者 1 +x:1 +透支 1 +x:1 +上蔡县 1 +x:1 +博城 1 +x:1 +湖心 1 +x:1 +闪光面 1 +x:1 +外借库 1 +x:1 +不断 1 +x:1 +小儿 1 +x:1 +志愿者 1 +x:1 +尘世 1 +x:1 +编审 1 +x:1 +本色调 1 +x:1 +差别 1 +x:1 +后妻 1 +x:1 +撬杠 1 +x:1 +此愿 1 +x:1 +嘀里嘟噜 1 +x:1 +来文 1 +x:1 +书籍 1 +x:1 +叭 5 +x:5 +战国 1 +x:1 +造船场 1 +x:1 +关注 1 +x:1 +奖牌榜 1 +x:1 +不料 1 +x:1 +对比 1 +x:1 +纲要 1 +x:1 +唐三彩 1 +x:1 +冷热战 1 +x:1 +凸轮 1 +x:1 +副标题 1 +x:1 +丧魂落魄 1 +x:1 +枪声 1 +x:1 +亚俱杯 1 +x:1 +分布面 1 +x:1 +生物界 1 +x:1 +氆氇 1 +x:1 +叶子烟 1 +x:1 +好动 1 +x:1 +优柔 1 +x:1 +将就 1 +x:1 +软木 1 +x:1 +旱区 1 +x:1 +钢铁业 1 +x:1 +韶关市 1 +x:1 +联村 1 +x:1 +争霸赛 1 +x:1 +新生党 1 +x:1 +气压 1 +x:1 +粗纱 1 +x:1 +调节 1 +x:1 +圆柱体 1 +x:1 +认同感 1 +x:1 +我行 1 +x:1 +浑浑噩噩 1 +x:1 +粗细 1 +x:1 +太爷 1 +x:1 +联机 1 +x:1 +烟台市 1 +x:1 +余部 1 +x:1 +喜极而涕 1 +x:1 +堵源 1 +x:1 +新生儿 1 +x:1 +龙山县 1 +x:1 +巾身 1 +x:1 +滔 2 +x:2 +洋为中用 1 +x:1 +噢 14 +x:14 +表弟 1 +x:1 +安卡拉 1 +x:1 +对歌 1 +x:1 +富塘村 1 +x:1 +散兵线 1 +x:1 +两用衫 1 +x:1 +芒刺在背 1 +x:1 +集市 1 +x:1 +小农 1 +x:1 +砍伐 1 +x:1 +小写 1 +x:1 +计算书 1 +x:1 +差劲 1 +x:1 +编年史式 1 +x:1 +陆海潘江 1 +x:1 +特服号 1 +x:1 +纯血马 1 +x:1 +督学 1 +x:1 +砍价 1 +x:1 +兴旺发达 1 +x:1 +湖底 1 +x:1 +轻机关枪 1 +x:1 +独轮车 1 +x:1 +恭候 1 +x:1 +影壁山乡 1 +x:1 +三为主 1 +x:1 +短线产品 1 +x:1 +借酒消愁 1 +x:1 +特供券 1 +x:1 +成品房 1 +x:1 +我见 1 +x:1 +物理疗法 1 +x:1 +秀雅 1 +x:1 +可欺 1 +x:1 +军分区 1 +x:1 +汗腺 1 +x:1 +垃圾猪肉 1 +x:1 +可歌 1 +x:1 +适度性 1 +x:1 +弱肉强食 1 +x:1 +霜期 1 +x:1 +东杜村 1 +x:1 +情韵 1 +x:1 +铱金笔 1 +x:1 +堵漏 1 +x:1 +真菌 1 +x:1 +爪钩 1 +x:1 +依安县 1 +x:1 +啤酒客 1 +x:1 +孜 1 +x:1 +错字 1 +x:1 +织补业 1 +x:1 +千儿八百 1 +x:1 +缆绳 1 +x:1 +丹凤朝阳 1 +x:1 +手持式 1 +x:1 +承担者 1 +x:1 +悲苦 1 +x:1 +如数 1 +x:1 +贺联 1 +x:1 +重教 1 +x:1 +歼 2 +x:2 +科技报 1 +x:1 +气势 1 +x:1 +普遍 1 +x:1 +咋舌 1 +x:1 +懒散 1 +x:1 +外行 1 +x:1 +珍贵性 1 +x:1 +披盖 1 +x:1 +气动 1 +x:1 +督导 1 +x:1 +冰袋 1 +x:1 +尘俗 1 +x:1 +气功 1 +x:1 +赛车组 1 +x:1 +外衣 1 +x:1 +疯颠颠 1 +x:1 +气力 1 +x:1 +险金 1 +x:1 +外表 1 +x:1 +固原县 1 +x:1 +发祥地 1 +x:1 +房前 1 +x:1 +督察 1 +x:1 +壁垒森严 1 +x:1 +狗东西 1 +x:1 +南京籍 1 +x:1 +鸿鹄 1 +x:1 +喜极而泣 1 +x:1 +普选 1 +x:1 +凯里 1 +x:1 +一改了之 1 +x:1 +建制镇 1 +x:1 +援引 1 +x:1 +扎扎实实 1 +x:1 +夜间 1 +x:1 +嘴把式 1 +x:1 +槐 6 +x:6 +普通 1 +x:1 +敏锐性 1 +x:1 +重旱 1 +x:1 +楼股 1 +x:1 +可比 1 +x:1 +谷氨酸 1 +x:1 +谋势篇 1 +x:1 +熟人 1 +x:1 +试验场 1 +x:1 +宜兴市 1 +x:1 +好受 1 +x:1 +租下 1 +x:1 +心田 1 +x:1 +联手 1 +x:1 +试验地 1 +x:1 +牛仔衫 1 +x:1 +跌伤 1 +x:1 +科技户 1 +x:1 +养殖区 1 +x:1 +人工湖 1 +x:1 +联销 1 +x:1 +棋联 1 +x:1 +泰厄罗阿 1 +x:1 +票证 1 +x:1 +寄放在 1 +x:1 +荠菜 1 +x:1 +上港村 1 +x:1 +坐台 1 +x:1 +辗转难眠 1 +x:1 +传真机 1 +x:1 +大邱 1 +x:1 +盐肤木 1 +x:1 +登记牌 1 +x:1 +旱农 1 +x:1 +塄 1 +x:1 +贫富 1 +x:1 +贫寒 1 +x:1 +优教 1 +x:1 +编委 1 +x:1 +猪体 1 +x:1 +旱冰 1 +x:1 +金园区 1 +x:1 +大邑 1 +x:1 +戊辰 1 +x:1 +外语 1 +x:1 +削足适履 1 +x:1 +开天窗 1 +x:1 +箱 78 +x:78 +酸枝木 1 +x:1 +囟 1 +x:1 +黎胞 1 +x:1 +侧面图 1 +x:1 +蘸 13 +x:13 +保加利亚 1 +x:1 +小卒 1 +x:1 +栖息处 1 +x:1 +右上方 1 +x:1 +大都 1 +x:1 +西藏厅 1 +x:1 +树梢 1 +x:1 +小区 1 +x:1 +噘 3 +x:3 +无价宝 1 +x:1 +湖州 1 +x:1 +供职 1 +x:1 +八哥 1 +x:1 +白酒 1 +x:1 +瓜秧 1 +x:1 +酣战 1 +x:1 +灌排 1 +x:1 +行员 1 +x:1 +高屋建瓴 1 +x:1 +糊涂虫 1 +x:1 +外设 1 +x:1 +西贝卡 1 +x:1 +挑衅性 1 +x:1 +立体角 1 +x:1 +气冷 1 +x:1 +虚有其表 1 +x:1 +粗粗 1 +x:1 +伪 13 +x:13 +将帅 1 +x:1 +鹞式 1 +x:1 +树桩 1 +x:1 +小叶 1 +x:1 +劈开 1 +x:1 +凸起 1 +x:1 +账务 1 +x:1 +粗粮 1 +x:1 +随 381 +x:381 +大通 1 +x:1 +古老 1 +x:1 +缆索 1 +x:1 +七八月份 1 +x:1 +鹿溪河 1 +x:1 +辣椒堆 1 +x:1 +补遗 1 +x:1 +积病 1 +x:1 +大选 1 +x:1 +行情期 1 +x:1 +迎春路 1 +x:1 +乌兰浩特 1 +x:1 +千难万苦 1 +x:1 +介入 1 +x:1 +树根 1 +x:1 +询问 1 +x:1 +孤寡 1 +x:1 +小县 1 +x:1 +冗长 1 +x:1 +护肤品 1 +x:1 +进退 1 +x:1 +狂笑 1 +x:1 +编外 1 +x:1 +不朽 1 +x:1 +鳏寡孤独 1 +x:1 +八员 1 +x:1 +糊涂蛋 1 +x:1 +粗糙 1 +x:1 +贤达 1 +x:1 +超然 1 +x:1 +补选 1 +x:1 +画脂镂冰 1 +x:1 +圣歌 1 +x:1 +不服 1 +x:1 +福将 1 +x:1 +孤寂 1 +x:1 +供能 1 +x:1 +进逼 1 +x:1 +退而结网 1 +x:1 +誓师 1 +x:1 +市中区 1 +x:1 +精英赛 1 +x:1 +半制品 1 +x:1 +白釉 1 +x:1 +嫔妃 1 +x:1 +计计 1 +x:1 +匀 5 +x:5 +集训场 1 +x:1 +错处 1 +x:1 +集训地 1 +x:1 +计议 1 +x:1 +亲疏好恶 1 +x:1 +还政于民 1 +x:1 +做生日 1 +x:1 +谈心 1 +x:1 +婚纱照 1 +x:1 +不曾 1 +x:1 +位点 1 +x:1 +与人为善 1 +x:1 +南坪村 1 +x:1 +金发者 1 +x:1 +挠 3 +x:3 +气候 1 +x:1 +参联会 1 +x:1 +吐故纳新 1 +x:1 +福州 1 +x:1 +杀伤力 1 +x:1 +篮板 1 +x:1 +错失 1 +x:1 +贾斯珀镇 1 +x:1 +航海 1 +x:1 +计算 1 +x:1 +缺房户 1 +x:1 +有史可鉴 1 +x:1 +刻字机 1 +x:1 +疤瘌 1 +x:1 +楼船 1 +x:1 +氢氟酸 1 +x:1 +太和庄 1 +x:1 +联播 1 +x:1 +动物群 1 +x:1 +化州市 1 +x:1 +让路 1 +x:1 +周遭 1 +x:1 +砷黄铁矿 1 +x:1 +优等生 1 +x:1 +透明 1 +x:1 +自卫权 1 +x:1 +邮包 1 +x:1 +小分 1 +x:1 +吊瓶 1 +x:1 +逼近 1 +x:1 +哈哈 1 +x:1 +小刀 1 +x:1 +浩淼无涯 1 +x:1 +大量 1 +x:1 +大野 1 +x:1 +读 822 +x:822 +楼舍 1 +x:1 +爆发星 1 +x:1 +周邻 1 +x:1 +水资源量 1 +x:1 +去夏 1 +x:1 +苇湖梁 1 +x:1 +媚俗阿世 1 +x:1 +把儿 1 +x:1 +兄弟 1 +x:1 +太药 1 +x:1 +绿豆粥 1 +x:1 +如果 1 +x:1 +让贤 1 +x:1 +次要 1 +x:1 +歪七扭八 1 +x:1 +大模大样 1 +x:1 +边陲 1 +x:1 +交响音乐 1 +x:1 +被收购方 1 +x:1 +劲健 1 +x:1 +阳关 1 +x:1 +咬咬 1 +x:1 +化学镀 1 +x:1 +栀角 1 +x:1 +S 3 +x:3 +潭边 1 +x:1 +工作餐 1 +x:1 +剁 10 +x:10 +登记率 1 +x:1 +职别 1 +x:1 +顽固 1 +x:1 +治劣 1 +x:1 +深有感触 1 +x:1 +洪江 1 +x:1 +上月底 1 +x:1 +好几 1 +x:1 +徒劳无功 1 +x:1 +棋艺 1 +x:1 +横逆 1 +x:1 +剃刀鲸 1 +x:1 +面前坡 1 +x:1 +绿豆糕 1 +x:1 +白龙乡 1 +x:1 +雌雄同株 1 +x:1 +不明 1 +x:1 +承诺书 1 +x:1 +力所不及 1 +x:1 +选士学 1 +x:1 +不易 1 +x:1 +减员 1 +x:1 +埋头苦干 1 +x:1 +名满天下 1 +x:1 +沥青 1 +x:1 +庚午 1 +x:1 +房基 1 +x:1 +大有人在 1 +x:1 +白露 1 +x:1 +彰山 1 +x:1 +绢制 1 +x:1 +程度者 1 +x:1 +柳州市 1 +x:1 +剧院 1 +x:1 +野鸽子 1 +x:1 +拦洪 1 +x:1 +调查业 1 +x:1 +压力壳 1 +x:1 +开工量 1 +x:1 +减压 1 +x:1 +长寿面 1 +x:1 +白霜 1 +x:1 +补集 1 +x:1 +豆饼 1 +x:1 +不懈 1 +x:1 +外路 1 +x:1 +旱垣 1 +x:1 +吊环 1 +x:1 +情操 1 +x:1 +泼墨 1 +x:1 +眼巴巴 1 +x:1 +剧降 1 +x:1 +擅权 1 +x:1 +重伤员 1 +x:1 +代代木 1 +x:1 +鸿沟 1 +x:1 +大雾 1 +x:1 +颐年堂 1 +x:1 +东耿村 1 +x:1 +郭家庄 1 +x:1 +冰霜 1 +x:1 +白面 1 +x:1 +减号 1 +x:1 +联控 1 +x:1 +博取 1 +x:1 +联接 1 +x:1 +友好街 1 +x:1 +大雪 1 +x:1 +大雨 1 +x:1 +代数方程 1 +x:1 +汝阳县 1 +x:1 +沁出 1 +x:1 +应急灯 1 +x:1 +枪尖 1 +x:1 +查考 1 +x:1 +大集 1 +x:1 +大雅 1 +x:1 +颁奖式 1 +x:1 +房型 1 +x:1 +大雁 1 +x:1 +将士 1 +x:1 +违纪案 1 +x:1 +瞒天过海 1 +x:1 +外资 1 +x:1 +贫煤区 1 +x:1 +闭目塞听 1 +x:1 +五常市 1 +x:1 +共有 1 +x:1 +分晓 1 +x:1 +气垫 1 +x:1 +守备师 1 +x:1 +恭喜 1 +x:1 +挣脱 1 +x:1 +大阪 1 +x:1 +旱地 1 +x:1 +旅游业界 1 +x:1 +煞尾 1 +x:1 +沧源 1 +x:1 +大队 1 +x:1 +九泉 1 +x:1 +计谋 1 +x:1 +不慎 1 +x:1 +城市化 1 +x:1 +劈头 1 +x:1 +歌咏队 1 +x:1 +豆渣 1 +x:1 +坐商 1 +x:1 +发生地 1 +x:1 +汤加队 1 +x:1 +贤愚 1 +x:1 +小嗓 1 +x:1 +发生场 1 +x:1 +权益 1 +x:1 +不愧 1 +x:1 +征收 1 +x:1 +狄 6 +x:6 +难舍难分 1 +x:1 +造船厂 1 +x:1 +丢丢的 1 +x:1 +技协 1 +x:1 +压锭 1 +x:1 +房地 1 +x:1 +杞人忧天 1 +x:1 +大院 1 +x:1 +补阵 1 +x:1 +松香水 1 +x:1 +来意 1 +x:1 +减半 1 +x:1 +外货 1 +x:1 +崇义县 1 +x:1 +不意 1 +x:1 +元珠笔 1 +x:1 +博卡 1 +x:1 +副 6967 +x:6967 +中下等 1 +x:1 +猜度 1 +x:1 +大陆 1 +x:1 +刺客 1 +x:1 +外贸 1 +x:1 +昆剧团 1 +x:1 +结构件 1 +x:1 +重税 1 +x:1 +淹没 1 +x:1 +笔划 1 +x:1 +斋 9 +x:9 +如意 1 +x:1 +福寿 1 +x:1 +冰调 1 +x:1 +树凉儿 1 +x:1 +爪部 1 +x:1 +阳城 1 +x:1 +圣河 1 +x:1 +焘 8 +x:8 +调查会 1 +x:1 +取报 1 +x:1 +温暖车 1 +x:1 +参谋长 1 +x:1 +试验台 1 +x:1 +粗笨 1 +x:1 +水平线 1 +x:1 +不惑 1 +x:1 +不惜 1 +x:1 +不惟 1 +x:1 +如愿 1 +x:1 +铁 150 +x:150 +自变数 1 +x:1 +不悦 1 +x:1 +化学药品 1 +x:1 +外貌 1 +x:1 +拼拼凑凑 1 +x:1 +证件牌 1 +x:1 +古文化 1 +x:1 +寸草不留 1 +x:1 +试验厂 1 +x:1 +懒得 1 +x:1 +大韩 1 +x:1 +孤山 1 +x:1 +小名 1 +x:1 +福安 1 +x:1 +讲义夹 1 +x:1 +一丝一毫 1 +x:1 +小吃 1 +x:1 +笑颜 1 +x:1 +一国两制 1 +x:1 +爱国至诚 1 +x:1 +消癜丸 1 +x:1 +好坏 1 +x:1 +归根结蒂 1 +x:1 +烟花弹 1 +x:1 +周际 1 +x:1 +减利 1 +x:1 +小哨 1 +x:1 +富强 1 +x:1 +收养证 1 +x:1 +不息 1 +x:1 +肃杀 1 +x:1 +引线 1 +x:1 +番石榴 1 +x:1 +计费 1 +x:1 +帕里奥利 1 +x:1 +猜忌 1 +x:1 +小北山 1 +x:1 +牛鬼蛇神 1 +x:1 +零散者 1 +x:1 +勇敢者 1 +x:1 +炊事员 1 +x:1 +花生仁 1 +x:1 +增殖 1 +x:1 +记事簿 1 +x:1 +泯没 1 +x:1 +免税店 1 +x:1 +钢盔 1 +x:1 +阳坪 1 +x:1 +编年 1 +x:1 +孤岛 1 +x:1 +眼下 1 +x:1 +残损币 1 +x:1 +橙色 1 +x:1 +减刑 1 +x:1 +恢宏博大 1 +x:1 +持有期 1 +x:1 +外调 1 +x:1 +节电办 1 +x:1 +种植园主 1 +x:1 +联户 1 +x:1 +炎日 1 +x:1 +优抚 1 +x:1 +普扫 1 +x:1 +大面 1 +x:1 +宜昌 1 +x:1 +金丝绒 1 +x:1 +气团 1 +x:1 +恻 1 +x:1 +白雪 1 +x:1 +试验区 1 +x:1 +霸权主义 1 +x:1 +八卦 1 +x:1 +职名 1 +x:1 +联成 1 +x:1 +发生器 1 +x:1 +不怕 1 +x:1 +宇航界 1 +x:1 +白集 1 +x:1 +气囊 1 +x:1 +油郭乡 1 +x:1 +一衰俱衰 1 +x:1 +提心吊胆 1 +x:1 +外迁 1 +x:1 +胡里胡涂 1 +x:1 +大钱 1 +x:1 +芜湖市 1 +x:1 +立足点 1 +x:1 +茎 10 +x:10 +外运 1 +x:1 +五花大绑 1 +x:1 +压韵 1 +x:1 +好听 1 +x:1 +可气 1 +x:1 +中立国 1 +x:1 +孤弱 1 +x:1 +普及性 1 +x:1 +余量 1 +x:1 +农牧 1 +x:1 +二建 1 +x:1 +吹喇叭 1 +x:1 +潞河 1 +x:1 +铁心轮 1 +x:1 +收听率 1 +x:1 +匮 1 +x:1 +一毛不拔 1 +x:1 +好吃 1 +x:1 +居高难下 1 +x:1 +小坐 1 +x:1 +杨柳池镇 1 +x:1 +舒筋活血 1 +x:1 +济济一堂 1 +x:1 +元书纸 1 +x:1 +制造厂 1 +x:1 +果壳箱 1 +x:1 +大而言之 1 +x:1 +捎 34 +x:34 +我等 1 +x:1 +衬衫业 1 +x:1 +目击者 1 +x:1 +可汗 1 +x:1 +登月舱 1 +x:1 +绛 5 +x:5 +值班 1 +x:1 +外空 1 +x:1 +魔窟 1 +x:1 +教导处 1 +x:1 +燃油泵 1 +x:1 +大江南北 1 +x:1 +重手 1 +x:1 +抢者 1 +x:1 +内绘壶 1 +x:1 +一五一十 1 +x:1 +外边 1 +x:1 +以外 1 +x:1 +冰轮 1 +x:1 +重托 1 +x:1 +橡实 1 +x:1 +阎王账 1 +x:1 +萨瓦金 1 +x:1 +困难 1 +x:1 +漠然置之 1 +x:1 +双喜盈门 1 +x:1 +义无反顾 1 +x:1 +刮目相待 1 +x:1 +三江队 1 +x:1 +东邻西舍 1 +x:1 +主办国 1 +x:1 +当政者 1 +x:1 +垦殖场 1 +x:1 +情形 1 +x:1 +塔哈尔省 1 +x:1 +刚体 1 +x:1 +运用自如 1 +x:1 +坐坐 1 +x:1 +放责 1 +x:1 +发射臂 1 +x:1 +气喘 1 +x:1 +潞水 1 +x:1 +咬 52 +x:52 +外轮 1 +x:1 +健智牌 1 +x:1 +稳 196 +x:196 +铃儿 1 +x:1 +间断性 1 +x:1 +初观者 1 +x:1 +菜青虫 1 +x:1 +格雷罗州 1 +x:1 +车贩子 1 +x:1 +鹞子 1 +x:1 +恭城 1 +x:1 +古董 1 +x:1 +灌木 1 +x:1 +技巧性 1 +x:1 +根堆群培 1 +x:1 +社科联 1 +x:1 +放空气 1 +x:1 +群众运动 1 +x:1 +花果山 1 +x:1 +重担 1 +x:1 +地市委 1 +x:1 +减免 1 +x:1 +开快车 1 +x:1 +麦地那 1 +x:1 +弈棋 1 +x:1 +对流 1 +x:1 +萨摩亚 1 +x:1 +可泣 1 +x:1 +总统令 1 +x:1 +贫弱 1 +x:1 +让行 1 +x:1 +吉林队 1 +x:1 +磷矿石 1 +x:1 +誉满全球 1 +x:1 +志在千里 1 +x:1 +重音 1 +x:1 +次货 1 +x:1 +洁白丸 1 +x:1 +将官 1 +x:1 +引柴 1 +x:1 +次贫 1 +x:1 +联想 1 +x:1 +伐 22 +x:22 +票贩 1 +x:1 +都庞岭 1 +x:1 +谐音字 1 +x:1 +东寨港 1 +x:1 +犹豫不定 1 +x:1 +红树区 1 +x:1 +计较 1 +x:1 +解放桥 1 +x:1 +通知书 1 +x:1 +先锋队 1 +x:1 +优种 1 +x:1 +子公司 1 +x:1 +奴隶式 1 +x:1 +好景不长 1 +x:1 +西藏团 1 +x:1 +鸢尾花 1 +x:1 +不拘 1 +x:1 +固体 1 +x:1 +沧海 1 +x:1 +高能耗 1 +x:1 +枪弹 1 +x:1 +油溪镇 1 +x:1 +玻璃丝 1 +x:1 +夸大性 1 +x:1 +禹州 1 +x:1 +赵村 1 +x:1 +气味 1 +x:1 +钢琴 1 +x:1 +邮政省 1 +x:1 +大门 1 +x:1 +蹦 18 +x:18 +菠萝蜜 1 +x:1 +韫 12 +x:12 +战鼓 1 +x:1 +照本宣科 1 +x:1 +杂项 1 +x:1 +拖驳 1 +x:1 +袖头 1 +x:1 +冠冕堂皇 1 +x:1 +刑律 1 +x:1 +微乎其微 1 +x:1 +普降 1 +x:1 +庆 115 +x:115 +普陀 1 +x:1 +领货单 1 +x:1 +生而知之 1 +x:1 +索贿 1 +x:1 +瘦长 1 +x:1 +植物油 1 +x:1 +滴灌 1 +x:1 +明丽朗润 1 +x:1 +蜂蜜 1 +x:1 +监控程序 1 +x:1 +够 310 +x:310 +自命不凡 1 +x:1 +婚生子 1 +x:1 +协奏曲 1 +x:1 +安化县 1 +x:1 +蜂蜡 1 +x:1 +好喝 1 +x:1 +高村乡 1 +x:1 +优惠 1 +x:1 +罗斯托夫 1 +x:1 +桑地诺 1 +x:1 +库瓦斯 1 +x:1 +大锅 1 +x:1 +斗志昂扬 1 +x:1 +重排 1 +x:1 +反串 1 +x:1 +一马平川 1 +x:1 +不能不 1 +x:1 +洪水期 1 +x:1 +白银 1 +x:1 +瞻仰者 1 +x:1 +室温 1 +x:1 +援外 1 +x:1 +知过必改 1 +x:1 +通史类 1 +x:1 +小九九 1 +x:1 +特供品 1 +x:1 +执法如山 1 +x:1 +压阵 1 +x:1 +信访局 1 +x:1 +湖塘 1 +x:1 +铸造厂 1 +x:1 +查获 1 +x:1 +南城县 1 +x:1 +困陷 1 +x:1 +架子花 1 +x:1 +拓蓝纸 1 +x:1 +白铜 1 +x:1 +吊灰 1 +x:1 +花点子 1 +x:1 +门罗主义 1 +x:1 +迭起 1 +x:1 +吊灯 1 +x:1 +白铁 1 +x:1 +辐射仪 1 +x:1 +玻璃亭 1 +x:1 +难分仲伯 1 +x:1 +屈子祠 1 +x:1 +关爱 1 +x:1 +十之八九 1 +x:1 +免税区 1 +x:1 +海缉处 1 +x:1 +长舒广袖 1 +x:1 +隐讳 1 +x:1 +对接 1 +x:1 +坐姿 1 +x:1 +返祖现象 1 +x:1 +编发 1 +x:1 +无穷无尽 1 +x:1 +叙旧 1 +x:1 +浮动汇率 1 +x:1 +拖锚 1 +x:1 +错划 1 +x:1 +小女 1 +x:1 +茫然不解 1 +x:1 +乒联 1 +x:1 +触怒 1 +x:1 +八度 1 +x:1 +重逢 1 +x:1 +汗衫 1 +x:1 +错判 1 +x:1 +减征 1 +x:1 +钢筋 1 +x:1 +巴克夏猪 1 +x:1 +看青 1 +x:1 +人工林 1 +x:1 +钢筒 1 +x:1 +编号 1 +x:1 +跑马梁 1 +x:1 +金丝猴 1 +x:1 +滴翠 1 +x:1 +三黄鸡 1 +x:1 +宜于 1 +x:1 +官面儿 1 +x:1 +胥浦 1 +x:1 +瓷杯 1 +x:1 +岚山头 1 +x:1 +词 115 +x:115 +中古史 1 +x:1 +足下 1 +x:1 +西安城 1 +x:1 +房室 1 +x:1 +房客 1 +x:1 +贫农 1 +x:1 +耐久性 1 +x:1 +战斗机 1 +x:1 +粗大动脉 1 +x:1 +气孔 1 +x:1 +小处 1 +x:1 +欢欢实实 1 +x:1 +不消 1 +x:1 +应考 1 +x:1 +钢笔 1 +x:1 +查谟 1 +x:1 +消铄精明 1 +x:1 +休闲游 1 +x:1 +中波 1 +x:1 +二十四日 1 +x:1 +毛茸茸 1 +x:1 +% 145 +x:145 +亘古未有 1 +x:1 +贬幅 1 +x:1 +与力甚焉 1 +x:1 +户长 1 +x:1 +老伴儿 1 +x:1 +羚 2 +x:2 +亚运 1 +x:1 +贪污 1 +x:1 +减弱 1 +x:1 +真言 1 +x:1 +蓄积 1 +x:1 +辩护人 1 +x:1 +进驻 1 +x:1 +不济 1 +x:1 +不测 1 +x:1 +房子 1 +x:1 +编印 1 +x:1 +孤军 1 +x:1 +编卷 1 +x:1 +气宇 1 +x:1 +贪求 1 +x:1 +暖空气 1 +x:1 +她俩 1 +x:1 +纠察线 1 +x:1 +梅西村 1 +x:1 +坐失 1 +x:1 +钢管 1 +x:1 +实打实 1 +x:1 +酣梦 1 +x:1 +奸人 1 +x:1 +清华大学 1 +x:1 +小妹 1 +x:1 +慎行 1 +x:1 +大马 1 +x:1 +住区 1 +x:1 +媒体化 1 +x:1 +反日会 1 +x:1 +农迁农 1 +x:1 +翻版 1 +x:1 +亮亮 1 +x:1 +劣种 1 +x:1 +港戊己 1 +x:1 +诊断书 1 +x:1 +如注 1 +x:1 +极右翼 1 +x:1 +神出鬼没 1 +x:1 +旱季 1 +x:1 +耳朵眼儿 1 +x:1 +胜面 1 +x:1 +督办 1 +x:1 +凌源 1 +x:1 +冰峰雪岭 1 +x:1 +瓦楞纸 1 +x:1 +顺手牵羊 1 +x:1 +迟到者 1 +x:1 +打转儿 1 +x:1 +被执行人 1 +x:1 +弓箭 1 +x:1 +混淆是非 1 +x:1 +信访办 1 +x:1 +囤积 1 +x:1 +外胎 1 +x:1 +劫掠一空 1 +x:1 +锐利 1 +x:1 +劝 111 +x:111 +重活 1 +x:1 +出冷门 1 +x:1 +套书 1 +x:1 +赞佩 1 +x:1 +生物系 1 +x:1 +狂热 1 +x:1 +摧枯拉朽 1 +x:1 +福利院 1 +x:1 +重洋 1 +x:1 +卡尔梅克 1 +x:1 +不法 1 +x:1 +糊涂账 1 +x:1 +奸佞 1 +x:1 +抽 78 +x:78 +对抗 1 +x:1 +慎用 1 +x:1 +吊楼 1 +x:1 +真话 1 +x:1 +古语 1 +x:1 +汗褂 1 +x:1 +查验 1 +x:1 +查账 1 +x:1 +中老年人 1 +x:1 +俏 13 +x:13 +城关镇 1 +x:1 +阳安 1 +x:1 +好学 1 +x:1 +忠心 1 +x:1 +白马 1 +x:1 +分期 1 +x:1 +卜 51 +x:51 +飞砂走石 1 +x:1 +龙舟节赛 1 +x:1 +塞内加尔 1 +x:1 +植物所 1 +x:1 +兰溪市 1 +x:1 +集成电路 1 +x:1 +古话 1 +x:1 +硅酸盐 1 +x:1 +古诗 1 +x:1 +啤酒厂 1 +x:1 +免不得 1 +x:1 +外肾 1 +x:1 +卫星站 1 +x:1 +救国图强 1 +x:1 +教导团 1 +x:1 +潮位 1 +x:1 +刑具 1 +x:1 +时宽时窄 1 +x:1 +胜队 1 +x:1 +技师 1 +x:1 +络腮胡 1 +x:1 +全军性 1 +x:1 +江克村 1 +x:1 +蜘蛛 1 +x:1 +念意 1 +x:1 +以图 1 +x:1 +外联 1 +x:1 +好客 1 +x:1 +啤酒卡 1 +x:1 +孤傲 1 +x:1 +白骨 1 +x:1 +滤色镜 1 +x:1 +庚 9 +x:9 +直接经验 1 +x:1 +编剧 1 +x:1 +个别化 1 +x:1 +兴仁县 1 +x:1 +战斗曲 1 +x:1 +外露 1 +x:1 +冰 162 +x:162 +供认 1 +x:1 +惊恐不安 1 +x:1 +资质 1 +x:1 +负荷率 1 +x:1 +观赛 1 +x:1 +动物界 1 +x:1 +皓月当空 1 +x:1 +校委 1 +x:1 +她们 1 +x:1 +室性 1 +x:1 +承诺卡 1 +x:1 +敌分我袭 1 +x:1 +颁 13 +x:13 +老太爷 1 +x:1 +瓜片 1 +x:1 +招架不住 1 +x:1 +孤僻 1 +x:1 +来水 1 +x:1 +白髯 1 +x:1 +编创 1 +x:1 +颖果 1 +x:1 +供词 1 +x:1 +福地 1 +x:1 +对手 1 +x:1 +摩 16 +x:16 +减幅 1 +x:1 +地下铁道 1 +x:1 +坐堂 1 +x:1 +钢窗 1 +x:1 +编制 1 +x:1 +蚍蜉撼树 1 +x:1 +对打 1 +x:1 +月工 1 +x:1 +队阵 1 +x:1 +民主联盟 1 +x:1 +誓图 1 +x:1 +小孩 1 +x:1 +中控室 1 +x:1 +小学 1 +x:1 +循环论 1 +x:1 +奴隶制 1 +x:1 +进食 1 +x:1 +治乱 1 +x:1 +顽强 1 +x:1 +拦挡 1 +x:1 +衣裳襟 1 +x:1 +可怜 1 +x:1 +密云县 1 +x:1 +大足 1 +x:1 +可怕 1 +x:1 +译者 1 +x:1 +大额 1 +x:1 +豆面 1 +x:1 +架子车 1 +x:1 +小康小平 1 +x:1 +伙房 1 +x:1 +小字 1 +x:1 +驴肝肺 1 +x:1 +三分王 1 +x:1 +唇干舌燥 1 +x:1 +同行者 1 +x:1 +票者 1 +x:1 +贤明 1 +x:1 +编内 1 +x:1 +特藏部 1 +x:1 +马山县 1 +x:1 +藕 10 +x:10 +悲观 1 +x:1 +房管所 1 +x:1 +白饭 1 +x:1 +编写 1 +x:1 +技法学 1 +x:1 +速寄 1 +x:1 +邯郸 1 +x:1 +位移 1 +x:1 +透漏 1 +x:1 +红光满面 1 +x:1 +技巧 1 +x:1 +技工 1 +x:1 +坐定 1 +x:1 +古装 1 +x:1 +职守 1 +x:1 +伊莫河 1 +x:1 +蒽环类 1 +x:1 +烙刻 1 +x:1 +断层地震 1 +x:1 +拖靶 1 +x:1 +大风 1 +x:1 +生物群 1 +x:1 +摁 11 +x:11 +如 2684 +x:2684 +凌波 1 +x:1 +韵律 1 +x:1 +眉 12 +x:12 +山口县 1 +x:1 +拖鞋 1 +x:1 +美利坚 1 +x:1 +墨水瓶 1 +x:1 +笑靥 1 +x:1 +法治化 1 +x:1 +试验局 1 +x:1 +人缘儿 1 +x:1 +健脾灵 1 +x:1 +动人肺腑 1 +x:1 +解放日 1 +x:1 +编入 1 +x:1 +披荆斩棘 1 +x:1 +钢种 1 +x:1 +进项 1 +x:1 +款款而动 1 +x:1 +换脑筋 1 +x:1 +房契 1 +x:1 +洛河畔 1 +x:1 +欢乐 1 +x:1 +联测 1 +x:1 +可悲 1 +x:1 +吊索 1 +x:1 +治家 1 +x:1 +遇 213 +x:213 +洋女婿 1 +x:1 +电极法 1 +x:1 +大顺 1 +x:1 +大项 1 +x:1 +一高一低 1 +x:1 +可惜 1 +x:1 +洗碗池 1 +x:1 +小宴 1 +x:1 +金丝燕 1 +x:1 +预报员 1 +x:1 +贺词 1 +x:1 +栲胶 1 +x:1 +白营村 1 +x:1 +轻车熟路 1 +x:1 +点收款 1 +x:1 +榜上有名 1 +x:1 +国税局 1 +x:1 +浍南 1 +x:1 +大碗茶 1 +x:1 +依靠 1 +x:1 +古街 1 +x:1 +治安 1 +x:1 +初愿 1 +x:1 +转让金 1 +x:1 +好头 1 +x:1 +不满 1 +x:1 +映入眼帘 1 +x:1 +港务局 1 +x:1 +行囊 1 +x:1 +雀形目 1 +x:1 +冰舞 1 +x:1 +普高 1 +x:1 +凌海 1 +x:1 +耒 1 +x:1 +馗 1 +x:1 +鸡冠子 1 +x:1 +页理 1 +x:1 +保值期 1 +x:1 +冰舌 1 +x:1 +煤焦厂 1 +x:1 +晾盘 1 +x:1 +欠 192 +x:192 +树懒 1 +x:1 +十万 1 +x:1 +种子选手 1 +x:1 +好多 1 +x:1 +突尼斯市 1 +x:1 +好处 1 +x:1 +吊梯 1 +x:1 +铅丹 1 +x:1 +返贫率 1 +x:1 +指靠 1 +x:1 +烙印 1 +x:1 +油料部 1 +x:1 +教导员 1 +x:1 +岗镇 1 +x:1 +拜把兄弟 1 +x:1 +掷弹筒 1 +x:1 +雉 5 +x:5 +进香 1 +x:1 +羽人 1 +x:1 +介壳 1 +x:1 +配件 1 +x:1 +转向器 1 +x:1 +计财司 1 +x:1 +辞退 1 +x:1 +冰川所 1 +x:1 +来复枪 1 +x:1 +满载率 1 +x:1 +降雨量 1 +x:1 +午餐费 1 +x:1 +以后 1 +x:1 +消摆 1 +x:1 +钢砂 1 +x:1 +造纸业 1 +x:1 +食蚁兽 1 +x:1 +小娃 1 +x:1 +钢研 1 +x:1 +周旋 1 +x:1 +好奇 1 +x:1 +乖巧 1 +x:1 +电子元件 1 +x:1 +宣武区 1 +x:1 +眼镜蛇 1 +x:1 +来源 1 +x:1 +可憎 1 +x:1 +大修费 1 +x:1 +早霜 1 +x:1 +粗疏 1 +x:1 +安家堡乡 1 +x:1 +敌群 1 +x:1 +代理 1 +x:1 +逗逗 1 +x:1 +不久以后 1 +x:1 +浓妆艳抹 1 +x:1 +因特网 1 +x:1 +枪口 1 +x:1 +减小 1 +x:1 +关机 1 +x:1 +冰花 1 +x:1 +大餐 1 +x:1 +科尔多凡 1 +x:1 +带路费 1 +x:1 +累 170 +x:170 +白领 1 +x:1 +古为今用 1 +x:1 +我院 1 +x:1 +城东 1 +x:1 +芜湖县 1 +x:1 +软水 1 +x:1 +冰芯 1 +x:1 +减少 1 +x:1 +初等教育 1 +x:1 +畅行 1 +x:1 +进餐 1 +x:1 +昆腔 1 +x:1 +月牙泉 1 +x:1 +关村 1 +x:1 +大饼 1 +x:1 +心惊肉跳 1 +x:1 +宗教党 1 +x:1 +靠得住 1 +x:1 +木质素 1 +x:1 +舴艋 1 +x:1 +永清县 1 +x:1 +肉中刺 1 +x:1 +天主教徒 1 +x:1 +记事牌 1 +x:1 +圣手 1 +x:1 +欢宴 1 +x:1 +兵贵神速 1 +x:1 +工具钢 1 +x:1 +外航 1 +x:1 +电讯社 1 +x:1 +易燃易爆 1 +x:1 +督军 1 +x:1 +用水 1 +x:1 +配乐 1 +x:1 +穿着 1 +x:1 +不经济性 1 +x:1 +职工 1 +x:1 +查补 1 +x:1 +水月庵 1 +x:1 +大麻 1 +x:1 +生物科 1 +x:1 +南四湖 1 +x:1 +谁料 1 +x:1 +辛迪加 1 +x:1 +采访部 1 +x:1 +冤大头 1 +x:1 +浊水溪 1 +x:1 +寻呼网 1 +x:1 +法学界 1 +x:1 +有线电 1 +x:1 +庚子 1 +x:1 +运算器 1 +x:1 +可是 1 +x:1 +豆酱 1 +x:1 +赠券 1 +x:1 +受话器 1 +x:1 +自不必说 1 +x:1 +畅达 1 +x:1 +真身 1 +x:1 +次长 1 +x:1 +俨如 1 +x:1 +统治者 1 +x:1 +以南 1 +x:1 +国仪 1 +x:1 +小区划 1 +x:1 +丁二烯 1 +x:1 +圣旨 1 +x:1 +触摸 1 +x:1 +棋路 1 +x:1 +天主教堂 1 +x:1 +斗批改 1 +x:1 +楚鲁松杰 1 +x:1 +咬字 1 +x:1 +攘攘 1 +x:1 +叙述 1 +x:1 +箭不虚发 1 +x:1 +眼底病 1 +x:1 +演唱者 1 +x:1 +钢缆 1 +x:1 +湖口 1 +x:1 +当事国 1 +x:1 +绛县 1 +x:1 +监禁率 1 +x:1 +罗得岛 1 +x:1 +痔瘘 1 +x:1 +博导 1 +x:1 +栖息地 1 +x:1 +堵截 1 +x:1 +蒜皮 1 +x:1 +谦逊 1 +x:1 +以北 1 +x:1 +守备团 1 +x:1 +空芯板 1 +x:1 +就职辞 1 +x:1 +小差 1 +x:1 +排土场 1 +x:1 +对本 1 +x:1 +小巧 1 +x:1 +泊南村 1 +x:1 +小工 1 +x:1 +舰队 1 +x:1 +献殷勤 1 +x:1 +撑住 1 +x:1 +酬金 1 +x:1 +缓解 1 +x:1 +奖牌数 1 +x:1 +君 67 +x:67 +关怀 1 +x:1 +咬定 1 +x:1 +综合园 1 +x:1 +大鸨 1 +x:1 +灌浆 1 +x:1 +狂暴 1 +x:1 +毛将焉附 1 +x:1 +西安区 1 +x:1 +以及 1 +x:1 +阳平 1 +x:1 +如梭 1 +x:1 +白龟 1 +x:1 +措 2 +x:2 +道义 1 +x:1 +粗犷 1 +x:1 +枪响 1 +x:1 +小东 1 +x:1 +科技潮 1 +x:1 +属地 1 +x:1 +闹革命 1 +x:1 +中远景 1 +x:1 +湖区 1 +x:1 +早车 1 +x:1 +党总支部 1 +x:1 +茁长 1 +x:1 +统战界 1 +x:1 +福利 1 +x:1 +引水 1 +x:1 +等效声 1 +x:1 +位置 1 +x:1 +肃清 1 +x:1 +成树 1 +x:1 +文牍主义 1 +x:1 +高分低能 1 +x:1 +矢石 1 +x:1 +飘 110 +x:110 +材质 1 +x:1 +取经 1 +x:1 +联欢 1 +x:1 +现成话 1 +x:1 +联次 1 +x:1 +真诚 1 +x:1 +对杀 1 +x:1 +博学 1 +x:1 +循环赛 1 +x:1 +重棉 1 +x:1 +椿树 1 +x:1 +六盘水市 1 +x:1 +尼古丁 1 +x:1 +大鹏 1 +x:1 +昆虫 1 +x:1 +焊管厂 1 +x:1 +行云流水 1 +x:1 +龙潭虎穴 1 +x:1 +房建 1 +x:1 +白鸽 1 +x:1 +吊窗 1 +x:1 +灌注 1 +x:1 +户部 1 +x:1 +雁来红 1 +x:1 +可望 1 +x:1 +古文字 1 +x:1 +君不见 1 +x:1 +取给 1 +x:1 +谆谆教诲 1 +x:1 +旱床 1 +x:1 +小山 1 +x:1 +以前 1 +x:1 +马尔萨斯 1 +x:1 +谁知 1 +x:1 +文武百官 1 +x:1 +亲亲热热 1 +x:1 +愁绪 1 +x:1 +欧乒赛 1 +x:1 +大龙 1 +x:1 +黄毛丫头 1 +x:1 +差役 1 +x:1 +大龄 1 +x:1 +好异 1 +x:1 +瓜皮 1 +x:1 +悬心吊胆 1 +x:1 +八宿 1 +x:1 +空调机 1 +x:1 +博爱县 1 +x:1 +繁荣党 1 +x:1 +以利 1 +x:1 +白鹳 1 +x:1 +碱式盐 1 +x:1 +差异 1 +x:1 +沉浮 1 +x:1 +内在论 1 +x:1 +白鹤 1 +x:1 +司寨村 1 +x:1 +农电 1 +x:1 +灌河 1 +x:1 +狮舞 1 +x:1 +古迹 1 +x:1 +白鹭 1 +x:1 +进退得失 1 +x:1 +曼切斯特 1 +x:1 +小小 1 +x:1 +添马舰 1 +x:1 +树林 1 +x:1 +本影 1 +x:1 +虎彪彪 1 +x:1 +烂漫多姿 1 +x:1 +狗尾续貂 1 +x:1 +生物碱 1 +x:1 +敕勒 1 +x:1 +凝血酶 1 +x:1 +白鹇 1 +x:1 +看守型 1 +x:1 +厂长室 1 +x:1 +保护牌 1 +x:1 +重箱 1 +x:1 +念旧 1 +x:1 +试验室 1 +x:1 +隐性 1 +x:1 +粗率 1 +x:1 +丽音 1 +x:1 +戒严 1 +x:1 +棋谱 1 +x:1 +弗 1 +x:1 +小件 1 +x:1 +穿凿附会 1 +x:1 +速射 1 +x:1 +水头乡 1 +x:1 +迎春花 1 +x:1 +袖口 1 +x:1 +大鼓 1 +x:1 +揭短会 1 +x:1 +群 278 +x:278 +观礼台 1 +x:1 +华舍镇 1 +x:1 +服帖 1 +x:1 +新镇 1 +x:1 +美食佳肴 1 +x:1 +富贵浮云 1 +x:1 +竟会 1 +x:1 +对景 1 +x:1 +爱国同胞 1 +x:1 +赋 21 +x:21 +化学战 1 +x:1 +来校 1 +x:1 +灰黄色 1 +x:1 +八字 1 +x:1 +散花坞 1 +x:1 +引洪 1 +x:1 +树木 1 +x:1 +颠簸 1 +x:1 +黄泥河镇 1 +x:1 +钢纸 1 +x:1 +贷款项 1 +x:1 +回味无穷 1 +x:1 +解放报 1 +x:1 +表现主义 1 +x:1 +湖剧 1 +x:1 +房帖 1 +x:1 +筷子巷 1 +x:1 +鹭 1 +x:1 +劳而无获 1 +x:1 +孤品 1 +x:1 +探亲访友 1 +x:1 +思维力 1 +x:1 +蜂起 1 +x:1 +清静庵 1 +x:1 +死劲儿 1 +x:1 +好心 1 +x:1 +小岗 1 +x:1 +光滑度 1 +x:1 +房市 1 +x:1 +转弯抹角 1 +x:1 +市中心 1 +x:1 +凌桥 1 +x:1 +穷乡僻壤 1 +x:1 +征文 1 +x:1 +死人 1 +x:1 +二京 1 +x:1 +对方 1 +x:1 +死亡 1 +x:1 +包装袋 1 +x:1 +尤其 1 +x:1 +山娃子 1 +x:1 +小影 1 +x:1 +以免 1 +x:1 +小弓棚 1 +x:1 +关押 1 +x:1 +乌迪内 1 +x:1 +不比 1 +x:1 +月岩 1 +x:1 +蒜瓣 1 +x:1 +小弯 1 +x:1 +争执 1 +x:1 +济钢队 1 +x:1 +钢索 1 +x:1 +千钧之重 1 +x:1 +劈叉 1 +x:1 +棋迷 1 +x:1 +乙炔 1 +x:1 +红军院 1 +x:1 +掉落 1 +x:1 +盛 167 +x:167 +粤菜馆 1 +x:1 +奇形怪状 1 +x:1 +汽油费 1 +x:1 +死仗 1 +x:1 +猩猩草 1 +x:1 +太和县 1 +x:1 +特勤局 1 +x:1 +天怒人怨 1 +x:1 +小弟 1 +x:1 +孤坟 1 +x:1 +建造业 1 +x:1 +车膜 1 +x:1 +小引 1 +x:1 +耳挖子 1 +x:1 +真谛 1 +x:1 +拖车费 1 +x:1 +不止 1 +x:1 +共勉共励 1 +x:1 +老框框 1 +x:1 +二中 1 +x:1 +貌 10 +x:10 +对攻 1 +x:1 +康保县 1 +x:1 +初学者 1 +x:1 +尹稼坞村 1 +x:1 +二为 1 +x:1 +阿韦龙省 1 +x:1 +塔山堡 1 +x:1 +二七 1 +x:1 +瓜田 1 +x:1 +封育区 1 +x:1 +博大 1 +x:1 +小心 1 +x:1 +稳定性 1 +x:1 +看重 1 +x:1 +书亭 1 +x:1 +贺辞 1 +x:1 +古谚 1 +x:1 +重檐 1 +x:1 +传入神经 1 +x:1 +团会后 1 +x:1 +线切割 1 +x:1 +城市处 1 +x:1 +库主 1 +x:1 +读书处 1 +x:1 +号令 1 +x:1 +决赛权 1 +x:1 +湖光 1 +x:1 +闹哄哄 1 +x:1 +大鱼 1 +x:1 +塔希主义 1 +x:1 +泌 1 +x:1 +无形之中 1 +x:1 +合理化 1 +x:1 +赫尔辛基 1 +x:1 +魔爪 1 +x:1 +存史 1 +x:1 +中介人 1 +x:1 +对数 1 +x:1 +鲶鱼 1 +x:1 +跟趟儿 1 +x:1 +耐用品 1 +x:1 +程式化 1 +x:1 +烤红薯 1 +x:1 +对敌 1 +x:1 +口蜜腹剑 1 +x:1 +以内 1 +x:1 +小径 1 +x:1 +拦柜 1 +x:1 +太和区 1 +x:1 +以军 1 +x:1 +零声母 1 +x:1 +俳句 1 +x:1 +小人 1 +x:1 +博览群书 1 +x:1 +盒装酒 1 +x:1 +邮政网 1 +x:1 +以身作则 1 +x:1 +情丝 1 +x:1 +逆反心理 1 +x:1 +关掉 1 +x:1 +一棉厂 1 +x:1 +小年 1 +x:1 +主席团 1 +x:1 +神武门 1 +x:1 +软梯 1 +x:1 +挤位 1 +x:1 +直露无余 1 +x:1 +颖慧 1 +x:1 +小幅 1 +x:1 +包圆儿 1 +x:1 +邮政署 1 +x:1 +耗油率 1 +x:1 +贫困 1 +x:1 +供货 1 +x:1 +读书声 1 +x:1 +对撞 1 +x:1 +速度 1 +x:1 +套筒机 1 +x:1 +不容小视 1 +x:1 +联检 1 +x:1 +退票处 1 +x:1 +聚餐会 1 +x:1 +情义 1 +x:1 +必不可缺 1 +x:1 +小于 1 +x:1 +让利酬宾 1 +x:1 +心切 1 +x:1 +清房办 1 +x:1 +宜沙 1 +x:1 +死信 1 +x:1 +刑警队 1 +x:1 +走边 1 +x:1 +澎 11 +x:11 +村农民 1 +x:1 +如此 1 +x:1 +可敬 1 +x:1 +旧 673 +x:673 +福冈 1 +x:1 +技士 1 +x:1 +情书 1 +x:1 +看透 1 +x:1 +灌溉 1 +x:1 +管道局 1 +x:1 +宿 25 +x:25 +坐庄 1 +x:1 +人才外流 1 +x:1 +战斗性 1 +x:1 +炭精棒 1 +x:1 +铃声 1 +x:1 +可数 1 +x:1 +补助金 1 +x:1 +此时此刻 1 +x:1 +畅谈 1 +x:1 +情事 1 +x:1 +法国籍 1 +x:1 +倒针法 1 +x:1 +联合体 1 +x:1 +栉孔 1 +x:1 +房山 1 +x:1 +查询 1 +x:1 +交恶 1 +x:1 +稳定感 1 +x:1 +死伤 1 +x:1 +授课人 1 +x:1 +劈刀 1 +x:1 +郑州 1 +x:1 +种豆得豆 1 +x:1 +棉兰老岛 1 +x:1 +临界角 1 +x:1 +八大 1 +x:1 +视黄醇 1 +x:1 +育新街 1 +x:1 +福利部 1 +x:1 +成品油 1 +x:1 +援兵 1 +x:1 +查证 1 +x:1 +无甲醛 1 +x:1 +柏柏尔 1 +x:1 +房屋 1 +x:1 +身上 1 +x:1 +登龙有术 1 +x:1 +起吊机 1 +x:1 +斗门县 1 +x:1 +树敌 1 +x:1 +愿 789 +x:789 +职专 1 +x:1 +联格 1 +x:1 +至乐 1 +x:1 +联合会 1 +x:1 +查讫 1 +x:1 +情仇 1 +x:1 +撬棍 1 +x:1 +安肃镇 1 +x:1 +薄弱点 1 +x:1 +编后 1 +x:1 +妒忌 1 +x:1 +查访 1 +x:1 +撬棒 1 +x:1 +坐下 1 +x:1 +小康 1 +x:1 +冰蛋 1 +x:1 +钢精 1 +x:1 +毛笔字 1 +x:1 +联校 1 +x:1 +折射率 1 +x:1 +白鳗 1 +x:1 +白鳝 1 +x:1 +巴东县 1 +x:1 +小庄 1 +x:1 +舰长 1 +x:1 +劣绅 1 +x:1 +幅面 1 +x:1 +遵 13 +x:13 +贫嘴 1 +x:1 +免税品 1 +x:1 +压力化 1 +x:1 +油柿 1 +x:1 +喜洋洋 1 +x:1 +书记 1 +x:1 +塔前村 1 +x:1 +软型 1 +x:1 +铁十六局 1 +x:1 +守礼门 1 +x:1 +二炮 1 +x:1 +重听 1 +x:1 +书论 1 +x:1 +肉食厂 1 +x:1 +借款人 1 +x:1 +截门 1 +x:1 +茄子干 1 +x:1 +料 59 +x:59 +通川郡 1 +x:1 +言简语拙 1 +x:1 +安陆 1 +x:1 +錱 1 +x:1 +科技司 1 +x:1 +软垫 1 +x:1 +交际舞 1 +x:1 +防火罩费 1 +x:1 +大云镇 1 +x:1 +有法不依 1 +x:1 +好战 1 +x:1 +张家港 1 +x:1 +通存通兑 1 +x:1 +门诊日 1 +x:1 +来日 1 +x:1 +桂东县 1 +x:1 +结构篇 1 +x:1 +枪案 1 +x:1 +干打垒 1 +x:1 +测量学家 1 +x:1 +足癣 1 +x:1 +垂杨柳 1 +x:1 +妊娠 1 +x:1 +一草一木 1 +x:1 +裂 28 +x:28 +不结盟 1 +x:1 +四部备要 1 +x:1 +通过 1 +x:1 +携儿带女 1 +x:1 +好找 1 +x:1 +刻舟求剑 1 +x:1 +植物学 1 +x:1 +蚌壳 1 +x:1 +铮铮如铁 1 +x:1 +铁石心肠 1 +x:1 +低磁钢 1 +x:1 +不善 1 +x:1 +综合 1 +x:1 +养狐 1 +x:1 +谣风 1 +x:1 +治愚 1 +x:1 +安阳 1 +x:1 +揭 55 +x:55 +娱乐室 1 +x:1 +枪栓 1 +x:1 +英气耿介 1 +x:1 +暮鼓晨钟 1 +x:1 +上段村 1 +x:1 +书评 1 +x:1 +供应点 1 +x:1 +顽敌 1 +x:1 +上行下效 1 +x:1 +护林员 1 +x:1 +好手 1 +x:1 +福建 1 +x:1 +凋谢 1 +x:1 +养父 1 +x:1 +交际花 1 +x:1 +玄妙 1 +x:1 +配用 1 +x:1 +悬壶于市 1 +x:1 +诉讼费 1 +x:1 +配电 1 +x:1 +融为一体 1 +x:1 +氧化物 1 +x:1 +反光镜 1 +x:1 +博望 1 +x:1 +后舱 1 +x:1 +鱼舱 1 +x:1 +亿吨级 1 +x:1 +狂轰烂炸 1 +x:1 +室女 1 +x:1 +不啻 1 +x:1 +来时 1 +x:1 +对话性 1 +x:1 +辉县市 1 +x:1 +阖家欢乐 1 +x:1 +溴 2 +x:2 +珂罗版 1 +x:1 +阳城县 1 +x:1 +桃林口 1 +x:1 +宁都 1 +x:1 +树龄 1 +x:1 +宜化 1 +x:1 +死灰 1 +x:1 +嫩芽 1 +x:1 +世家 1 +x:1 +小憩 1 +x:1 +国家机器 1 +x:1 +鼠疫 1 +x:1 +四中全会 1 +x:1 +账房 1 +x:1 +科技化 1 +x:1 +软坚 1 +x:1 +债权国 1 +x:1 +圣女 1 +x:1 +援建 1 +x:1 +调查站 1 +x:1 +云莺 1 +x:1 +吟啸 1 +x:1 +养牛 1 +x:1 +党史办 1 +x:1 +福清 1 +x:1 +立党 1 +x:1 +虎视鹰瞵 1 +x:1 +螺丝垫 1 +x:1 +调节金 1 +x:1 +盖帽王 1 +x:1 +室外 1 +x:1 +对子 1 +x:1 +折褶 1 +x:1 +牛郎乡 1 +x:1 +安静 1 +x:1 +真真 1 +x:1 +肃反 1 +x:1 +经五路 1 +x:1 +绢本 1 +x:1 +前因后果 1 +x:1 +罗甸县 1 +x:1 +铅球 1 +x:1 +吟咏 1 +x:1 +根须 1 +x:1 +斩断 1 +x:1 +左摆舵 1 +x:1 +蜜李 1 +x:1 +篮里 1 +x:1 +遮盖 1 +x:1 +伙夫 1 +x:1 +多门 1 +x:1 +药剂师 1 +x:1 +大气圈 1 +x:1 +嫩草 1 +x:1 +进行性 1 +x:1 +冻豆腐 1 +x:1 +其诗 1 +x:1 +受术者 1 +x:1 +大作品 1 +x:1 +河南店 1 +x:1 +穆索马 1 +x:1 +麻阳 1 +x:1 +科技力 1 +x:1 +玻璃砖 1 +x:1 +妙高峰 1 +x:1 +空置量 1 +x:1 +蝇营狗苟 1 +x:1 +外籍 1 +x:1 +校区 1 +x:1 +试验团 1 +x:1 +灭火队 1 +x:1 +比赛灯 1 +x:1 +粗作 1 +x:1 +自我批评 1 +x:1 +气鼓鼓 1 +x:1 +蜜月 1 +x:1 +绘声绘色 1 +x:1 +看人眉睫 1 +x:1 +吵吵闹闹 1 +x:1 +不和 1 +x:1 +这么点儿 1 +x:1 +发委会 1 +x:1 +棱 4 +x:4 +分步法 1 +x:1 +篓里 1 +x:1 +惊险万状 1 +x:1 +参与人员 1 +x:1 +嫁接 1 +x:1 +跋涉者 1 +x:1 +房县 1 +x:1 +壮胆 1 +x:1 +麻醉药 1 +x:1 +謇 1 +x:1 +蜜柑 1 +x:1 +普及型 1 +x:1 +八月 1 +x:1 +蜜柚 1 +x:1 +不周 1 +x:1 +其乐无穷 1 +x:1 +限产压锭 1 +x:1 +帕 2 +x:2 +强权政治 1 +x:1 +节育率 1 +x:1 +养猪 1 +x:1 +前列腺素 1 +x:1 +肃南 1 +x:1 +刚硬 1 +x:1 +踌躇 1 +x:1 +心气平和 1 +x:1 +溜走 1 +x:1 +人才观 1 +x:1 +内驱动力 1 +x:1 +横躺竖卧 1 +x:1 +麻雀 1 +x:1 +摸黑 1 +x:1 +农膜 1 +x:1 +挨家挨户 1 +x:1 +安海镇 1 +x:1 +优胜队 1 +x:1 +试验期 1 +x:1 +各显神通 1 +x:1 +汉 159 +x:159 +休闲型 1 +x:1 +长大成材 1 +x:1 +粗俗 1 +x:1 +保龄 1 +x:1 +新疆团 1 +x:1 +蝴蝶 1 +x:1 +清障车 1 +x:1 +初记 1 +x:1 +闯闯 1 +x:1 +玻璃碴 1 +x:1 +村村组组 1 +x:1 +江湖义气 1 +x:1 +不同 1 +x:1 +垂直线 1 +x:1 +且慢派 1 +x:1 +溪乾村 1 +x:1 +蜜枣 1 +x:1 +至亲 1 +x:1 +不吝 1 +x:1 +状态值 1 +x:1 +湖湾 1 +x:1 +邮差 1 +x:1 +表尺 1 +x:1 +贪图 1 +x:1 +西瓜界 1 +x:1 +和稀泥 1 +x:1 +打字组 1 +x:1 +缘故 1 +x:1 +气愤 1 +x:1 +领袖群伦 1 +x:1 +福泉 1 +x:1 +小试 1 +x:1 +涪城区 1 +x:1 +寂无人声 1 +x:1 +愈加 1 +x:1 +采莲调 1 +x:1 +商城路 1 +x:1 +身价 1 +x:1 +篾片 1 +x:1 +错案 1 +x:1 +好恶 1 +x:1 +宣武门 1 +x:1 +空气锤 1 +x:1 +购票者 1 +x:1 +两不适 1 +x:1 +抗毒血清 1 +x:1 +喷水池 1 +x:1 +修旧利废 1 +x:1 +骨伤病 1 +x:1 +引动 1 +x:1 +气慨 1 +x:1 +尧天舜日 1 +x:1 +树墩 1 +x:1 +后背 1 +x:1 +的士 1 +x:1 +引力 1 +x:1 +小指 1 +x:1 +风平乡 1 +x:1 +职掌 1 +x:1 +兴隆乡 1 +x:1 +套用 1 +x:1 +空额 1 +x:1 +多难 1 +x:1 +歧异 1 +x:1 +小声 1 +x:1 +奥林匹克 1 +x:1 +同归于尽 1 +x:1 +吉家坪村 1 +x:1 +中断点 1 +x:1 +伉 13 +x:13 +楼脚 1 +x:1 +你咯 1 +x:1 +泉州市 1 +x:1 +二爷 1 +x:1 +山口镇 1 +x:1 +凯旋 1 +x:1 +规划者 1 +x:1 +袜 6 +x:6 +截面 1 +x:1 +触媒 1 +x:1 +冢 2 +x:2 +孤残 1 +x:1 +通辽 1 +x:1 +圭臬 1 +x:1 +昼夜 1 +x:1 +介意 1 +x:1 +低收入 1 +x:1 +武平坪坑 1 +x:1 +上海街 1 +x:1 +大韩民国 1 +x:1 +技改 1 +x:1 +农林局 1 +x:1 +对外 1 +x:1 +得不偿失 1 +x:1 +井架 1 +x:1 +识 81 +x:81 +贪嘴 1 +x:1 +保鲜 1 +x:1 +联唱 1 +x:1 +汇集 1 +x:1 +桂阳县 1 +x:1 +有条不紊 1 +x:1 +补偿金 1 +x:1 +死物 1 +x:1 +鞠躬礼 1 +x:1 +鸫鸟 1 +x:1 +减数 1 +x:1 +灌包 1 +x:1 +灭口 1 +x:1 +训练部 1 +x:1 +紫草茸 1 +x:1 +公里数 1 +x:1 +草豆蔻 1 +x:1 +曙光上村 1 +x:1 +荤菜 1 +x:1 +沾边儿 1 +x:1 +圣子 1 +x:1 +阳性 1 +x:1 +大华行 1 +x:1 +精神百倍 1 +x:1 +膨出 1 +x:1 +款费 1 +x:1 +大逆不道 1 +x:1 +挚挚 1 +x:1 +莫名无言 1 +x:1 +二环 1 +x:1 +楠木 1 +x:1 +重在 1 +x:1 +鬼蜮伎俩 1 +x:1 +瞧得起 1 +x:1 +篮坛 1 +x:1 +国贸局 1 +x:1 +钢珠 1 +x:1 +不图 1 +x:1 +安仁村 1 +x:1 +添砖加瓦 1 +x:1 +纵观 1 +x:1 +集训期 1 +x:1 +荷枪实弹 1 +x:1 +伏狮形 1 +x:1 +被除数 1 +x:1 +好感 1 +x:1 +引发 1 +x:1 +发酵站 1 +x:1 +来回 1 +x:1 +船埠 1 +x:1 +人工岛 1 +x:1 +速报 1 +x:1 +情爱 1 +x:1 +霍邱县 1 +x:1 +气态 1 +x:1 +一人班 1 +x:1 +气恼 1 +x:1 +模拟化 1 +x:1 +湖泊 1 +x:1 +淮西 1 +x:1 +气息 1 +x:1 +维护费 1 +x:1 +八旗 1 +x:1 +眉纹石 1 +x:1 +链条厂 1 +x:1 +名过其实 1 +x:1 +耍花招 1 +x:1 +张家浜 1 +x:1 +的姐 1 +x:1 +宜阳 1 +x:1 +保鲜剂 1 +x:1 +来踪去迹 1 +x:1 +还贷额 1 +x:1 +八日 1 +x:1 +筑渠 1 +x:1 +保存率 1 +x:1 +戒烟 1 +x:1 +山西梆子 1 +x:1 +关念 1 +x:1 +铅白 1 +x:1 +重重 1 +x:1 +可好 1 +x:1 +八时 1 +x:1 +湖泽 1 +x:1 +小我 1 +x:1 +麟凤龟龙 1 +x:1 +赌钱 1 +x:1 +加塞儿 1 +x:1 +脏物 1 +x:1 +不合理性 1 +x:1 +速成 1 +x:1 +货运链 1 +x:1 +服饰 1 +x:1 +截除 1 +x:1 +直前 1 +x:1 +妊妇 1 +x:1 +无本之木 1 +x:1 +费尽周折 1 +x:1 +枪毙 1 +x:1 +安闲 1 +x:1 +十佳 1 +x:1 +重型 1 +x:1 +玉门镇 1 +x:1 +红树林 1 +x:1 +后脚 1 +x:1 +湖水 1 +x:1 +以法 1 +x:1 +后脑 1 +x:1 +关张 1 +x:1 +猫肉 1 +x:1 +扁 3 +x:3 +玻璃窗 1 +x:1 +疯人院 1 +x:1 +减摩 1 +x:1 +说得来 1 +x:1 +绢丝纺 1 +x:1 +香案 1 +x:1 +灌制 1 +x:1 +零花 1 +x:1 +影视局 1 +x:1 +调查科 1 +x:1 +后腿 1 +x:1 +后腰 1 +x:1 +工团主义 1 +x:1 +圣婴 1 +x:1 +编校 1 +x:1 +爱子教子 1 +x:1 +竟然 1 +x:1 +高升村 1 +x:1 +大出血 1 +x:1 +石麒麟 1 +x:1 +永康路 1 +x:1 +联同 1 +x:1 +联名 1 +x:1 +交接班 1 +x:1 +联合 1 +x:1 +好懂 1 +x:1 +公益金 1 +x:1 +哺 5 +x:5 +分分 1 +x:1 +圆括号 1 +x:1 +农林下路 1 +x:1 +气机 1 +x:1 +空目录 1 +x:1 +以此 1 +x:1 +蕉窗 1 +x:1 +加把劲 1 +x:1 +旱极 1 +x:1 +胎记 1 +x:1 +本乡本土 1 +x:1 +蹲坐者 1 +x:1 +宜城 1 +x:1 +盗窃案 1 +x:1 +好高骛远 1 +x:1 +体谅 1 +x:1 +大栅栏 1 +x:1 +东 511 +x:511 +库亚巴 1 +x:1 +小数 1 +x:1 +不准 1 +x:1 +煤焦油 1 +x:1 +马加丹州 1 +x:1 +减掉 1 +x:1 +创纪录 1 +x:1 +哭哭咧咧 1 +x:1 +大舌头 1 +x:1 +治教 1 +x:1 +臭骂 1 +x:1 +对待 1 +x:1 +软厢 1 +x:1 +阳朝乡 1 +x:1 +降尘量 1 +x:1 +雪面 1 +x:1 +太行红 1 +x:1 +四五点钟 1 +x:1 +孜本 1 +x:1 +情由 1 +x:1 +十进制 1 +x:1 +元宵节 1 +x:1 +根形 1 +x:1 +虎啸声 1 +x:1 +书迷 1 +x:1 +药剂学 1 +x:1 +书迹 1 +x:1 +体育法 1 +x:1 +以次 1 +x:1 +豆角角 1 +x:1 +八拐 1 +x:1 +交易部 1 +x:1 +房管局 1 +x:1 +量入为出 1 +x:1 +膘情 1 +x:1 +违 20 +x:20 +准确性 1 +x:1 +旱柳 1 +x:1 +莉 44 +x:44 +鄞县 1 +x:1 +不再 1 +x:1 +恭敬 1 +x:1 +玉田县 1 +x:1 +引咎 1 +x:1 +抠算 1 +x:1 +纵身 1 +x:1 +单身只影 1 +x:1 +结构美 1 +x:1 +趾 1 +x:1 +社科司 1 +x:1 +政史系 1 +x:1 +明知故犯 1 +x:1 +大孙各庄 1 +x:1 +倡议书 1 +x:1 +树干 1 +x:1 +尘事 1 +x:1 +商品粮棉 1 +x:1 +不公 1 +x:1 +妙入无声 1 +x:1 +殊 10 +x:10 +互谅互让 1 +x:1 +斥责 1 +x:1 +联危 1 +x:1 +说明书 1 +x:1 +气枪 1 +x:1 +夜猫子 1 +x:1 +职数 1 +x:1 +勇于 1 +x:1 +长距离 1 +x:1 +洗涤 1 +x:1 +出勤率 1 +x:1 +医药 1 +x:1 +对弈 1 +x:1 +抄袭者 1 +x:1 +腰果仁 1 +x:1 +散会 1 +x:1 +不免 1 +x:1 +对开 1 +x:1 +宪 17 +x:17 +不光 1 +x:1 +正副教授 1 +x:1 +将校 1 +x:1 +死理 1 +x:1 +福橘 1 +x:1 +瓷实 1 +x:1 +刁顽 1 +x:1 +职教 1 +x:1 +调查组 1 +x:1 +关塞 1 +x:1 +樱花瓣 1 +x:1 +敬爱 1 +x:1 +附着物 1 +x:1 +国典 1 +x:1 +优厚 1 +x:1 +裂化 1 +x:1 +编演 1 +x:1 +原原本本 1 +x:1 +速效 1 +x:1 +婀娜 1 +x:1 +蜻蜓 1 +x:1 +孰不可忍 1 +x:1 +气柜 1 +x:1 +柠檬黄 1 +x:1 +墨存 1 +x:1 +软卧 1 +x:1 +斥资 1 +x:1 +谁个 1 +x:1 +膏药旗 1 +x:1 +扯 37 +x:37 +永垂青史 1 +x:1 +街头剧 1 +x:1 +确定性 1 +x:1 +身边 1 +x:1 +丽江 1 +x:1 +阳春 1 +x:1 +多重 1 +x:1 +待会儿 1 +x:1 +倡议信 1 +x:1 +宁镇 1 +x:1 +策划人 1 +x:1 +情理 1 +x:1 +蜚声于世 1 +x:1 +普查 1 +x:1 +煎饼 1 +x:1 +弃邪归正 1 +x:1 +联勤 1 +x:1 +北岳区 1 +x:1 +指甲盖 1 +x:1 +套牢 1 +x:1 +姑子营村 1 +x:1 +制造家 1 +x:1 +科技园 1 +x:1 +闸盒 1 +x:1 +通情达理 1 +x:1 +对应 1 +x:1 +青光眼 1 +x:1 +闸皮 1 +x:1 +博拉 1 +x:1 +补血剂 1 +x:1 +鄯善 1 +x:1 +嫌怨 1 +x:1 +转瞬间 1 +x:1 +重兵 1 +x:1 +奸猾 1 +x:1 +心包 1 +x:1 +调查网 1 +x:1 +瓜仁 1 +x:1 +来 10292 +x:10292 +阳极 1 +x:1 +零落 1 +x:1 +黄热病 1 +x:1 +联办 1 +x:1 +读书报 1 +x:1 +水平仪 1 +x:1 +面人儿 1 +x:1 +通称 1 +x:1 +产莲区 1 +x:1 +校牌 1 +x:1 +交易量 1 +x:1 +如其 1 +x:1 +死症 1 +x:1 +贫油 1 +x:1 +考勤簿 1 +x:1 +浑重 1 +x:1 +镂刻 1 +x:1 +树影 1 +x:1 +芦丰 1 +x:1 +玄奥 1 +x:1 +廉正语 1 +x:1 +石门村 1 +x:1 +有失远迎 1 +x:1 +关外 1 +x:1 +炎 10 +x:10 +大宴宾客 1 +x:1 +树形 1 +x:1 +二甲 1 +x:1 +朗 16 +x:16 +哀痛 1 +x:1 +奴仆 1 +x:1 +联剧 1 +x:1 +处置费 1 +x:1 +真情 1 +x:1 +霜叶 1 +x:1 +正己率下 1 +x:1 +亡命之徒 1 +x:1 +资源型 1 +x:1 +犀利 1 +x:1 +剃度 1 +x:1 +关头 1 +x:1 +心痛病 1 +x:1 +魂不守舍 1 +x:1 +八一年 1 +x:1 +不停 1 +x:1 +三证一单 1 +x:1 +重写 1 +x:1 +眼珠儿 1 +x:1 +叙事 1 +x:1 +背靠背 1 +x:1 +联汇制 1 +x:1 +搞笑 1 +x:1 +寿终 1 +x:1 +可心 1 +x:1 +百尺竿头 1 +x:1 +阳朔 1 +x:1 +叩动 1 +x:1 +贫民 1 +x:1 +识者 1 +x:1 +圣山 1 +x:1 +玻璃粉 1 +x:1 +援款 1 +x:1 +洗涤剂 1 +x:1 +多多的 1 +x:1 +联创 1 +x:1 +优劣 1 +x:1 +敫 1 +x:1 +身躯 1 +x:1 +木质 1 +x:1 +麒麟盖 1 +x:1 +凌厉 1 +x:1 +橡树 1 +x:1 +保山市 1 +x:1 +说 17649 +x:17649 +身无长物 1 +x:1 +瓜乡 1 +x:1 +不足者 1 +x:1 +指手画脚 1 +x:1 +款识 1 +x:1 +核废料 1 +x:1 +大棚式 1 +x:1 +麻酱 1 +x:1 +堵塞 1 +x:1 +怄 2 +x:2 +数以百计 1 +x:1 +遂行 1 +x:1 +叩关 1 +x:1 +复杂性 1 +x:1 +重利 1 +x:1 +不只 1 +x:1 +通报会 1 +x:1 +折返 1 +x:1 +洋纱 1 +x:1 +战场 1 +x:1 +潮热 1 +x:1 +厦南 1 +x:1 +耍花枪 1 +x:1 +二氧化硫 1 +x:1 +不及 1 +x:1 +治权 1 +x:1 +夹生饭 1 +x:1 +宁陵 1 +x:1 +回音壁 1 +x:1 +麻 25 +x:25 +不平等性 1 +x:1 +盐酸 1 +x:1 +小村 1 +x:1 +坏血病 1 +x:1 +猛然间 1 +x:1 +蔓儿 1 +x:1 +袖标 1 +x:1 +尘砂 1 +x:1 +不成人子 1 +x:1 +法制化 1 +x:1 +华 592 +x:592 +出汤量 1 +x:1 +来去 1 +x:1 +集约经营 1 +x:1 +气壮山河 1 +x:1 +身负 1 +x:1 +小朱 1 +x:1 +治本 1 +x:1 +安逸 1 +x:1 +联农 1 +x:1 +联军 1 +x:1 +纸房乡 1 +x:1 +捐助人 1 +x:1 +太和殿 1 +x:1 +来历 1 +x:1 +关涉 1 +x:1 +高峰会 1 +x:1 +宁阳 1 +x:1 +重剑 1 +x:1 +征稿 1 +x:1 +隐约 1 +x:1 +赊欠 1 +x:1 +机船 1 +x:1 +燃料箱 1 +x:1 +尾水渠 1 +x:1 +长宁区 1 +x:1 +联共 1 +x:1 +诸国 1 +x:1 +小偷 1 +x:1 +黄梅雨 1 +x:1 +职权责 1 +x:1 +书账 1 +x:1 +书贩 1 +x:1 +联入 1 +x:1 +无抵押 1 +x:1 +来华 1 +x:1 +职权 1 +x:1 +中影 1 +x:1 +法制史 1 +x:1 +撬 22 +x:22 +陪审 1 +x:1 +不单 1 +x:1 +陪客 1 +x:1 +舞蹈节 1 +x:1 +重办 1 +x:1 +收棉款 1 +x:1 +重力 1 +x:1 +医务界 1 +x:1 +记事体 1 +x:1 +房改 1 +x:1 +小抄儿 1 +x:1 +保额 1 +x:1 +战威 1 +x:1 +相对论 1 +x:1 +出水量 1 +x:1 +减慢 1 +x:1 +软饮料业 1 +x:1 +缉私队 1 +x:1 +纵谈 1 +x:1 +著 80 +x:80 +居住区 1 +x:1 +写真照 1 +x:1 +踏足 1 +x:1 +韵白 1 +x:1 +沉沉 1 +x:1 +绿地率 1 +x:1 +治林 1 +x:1 +长短途 1 +x:1 +枝节 1 +x:1 +爆竹声 1 +x:1 +气旋 1 +x:1 +麻醉 1 +x:1 +试验性 1 +x:1 +救火队长 1 +x:1 +安邦 1 +x:1 +生机盎然 1 +x:1 +五角星 1 +x:1 +冻结令 1 +x:1 +高峰乡 1 +x:1 +竞买者 1 +x:1 +偷私渡 1 +x:1 +防雨罩 1 +x:1 +对岸 1 +x:1 +树巢 1 +x:1 +花生米 1 +x:1 +上海路 1 +x:1 +宁静 1 +x:1 +岳王路 1 +x:1 +普及本 1 +x:1 +猜测 1 +x:1 +锐气 1 +x:1 +呢喃 1 +x:1 +棉毛衫 1 +x:1 +毫无例外 1 +x:1 +防弹衣 1 +x:1 +分析员 1 +x:1 +自况体 1 +x:1 +十足 1 +x:1 +嫩蕊 1 +x:1 +织补工 1 +x:1 +差数 1 +x:1 +透剔 1 +x:1 +带菌者 1 +x:1 +天河 1 +x:1 +屋梁 1 +x:1 +玉山县 1 +x:1 +深情厚意 1 +x:1 +东北风 1 +x:1 +南靖县 1 +x:1 +淇 4 +x:4 +红星路 1 +x:1 +水利化 1 +x:1 +永志不忘 1 +x:1 +真分数 1 +x:1 +肉食品 1 +x:1 +意绪 1 +x:1 +金迷纸醉 1 +x:1 +来势 1 +x:1 +重印 1 +x:1 +联储 1 +x:1 +硬度 1 +x:1 +新洲县 1 +x:1 +伴生树 1 +x:1 +阳文 1 +x:1 +来劲 1 +x:1 +折身 1 +x:1 +巧 62 +x:62 +后藏 1 +x:1 +念念 1 +x:1 +堵头 1 +x:1 +快检仪 1 +x:1 +阳新 1 +x:1 +坐像 1 +x:1 +对峙 1 +x:1 +余姚市 1 +x:1 +双立人 1 +x:1 +兴利除弊 1 +x:1 +养病 1 +x:1 +坚强不屈 1 +x:1 +不力 1 +x:1 +誓死 1 +x:1 +阿是穴 1 +x:1 +独立国家 1 +x:1 +如故 1 +x:1 +涓滴成溪 1 +x:1 +名 6818 +x:6818 +差旅 1 +x:1 +直线型 1 +x:1 +足球队 1 +x:1 +校点 1 +x:1 +莘 1 +x:1 +小曲 1 +x:1 +温文尔雅 1 +x:1 +好斗 1 +x:1 +捧哏 1 +x:1 +余干 1 +x:1 +度 293 +x:293 +卑鄙 1 +x:1 +卫生学会 1 +x:1 +零蛋 1 +x:1 +养生 1 +x:1 +水利史 1 +x:1 +无所谓 1 +x:1 +分散 1 +x:1 +躬亲 1 +x:1 +狂乱 1 +x:1 +甲状腺肿 1 +x:1 +减息 1 +x:1 +科研型 1 +x:1 +编写组 1 +x:1 +其责 1 +x:1 +其败 1 +x:1 +法制办 1 +x:1 +接团表 1 +x:1 +关子 1 +x:1 +不利 1 +x:1 +大动大静 1 +x:1 +瓷壶 1 +x:1 +为虎傅翼 1 +x:1 +水利厅 1 +x:1 +国家机关 1 +x:1 +来到 1 +x:1 +传声筒 1 +x:1 +进行曲 1 +x:1 +重整 1 +x:1 +可巧 1 +x:1 +沧州 1 +x:1 +霜冻 1 +x:1 +炮车 1 +x:1 +养畜 1 +x:1 +南坪县 1 +x:1 +纵贯 1 +x:1 +秩序 1 +x:1 +调节型 1 +x:1 +炮轰 1 +x:1 +晋冀察 1 +x:1 +小暑 1 +x:1 +自来水笔 1 +x:1 +尤杯 1 +x:1 +不巧 1 +x:1 +交费人 1 +x:1 +车钱 1 +x:1 +以来 1 +x:1 +体育周 1 +x:1 +命笔 1 +x:1 +勇为 1 +x:1 +内向型 1 +x:1 +穷亲 1 +x:1 +不已 1 +x:1 +小楷 1 +x:1 +水利局 1 +x:1 +穷人 1 +x:1 +仙气 1 +x:1 +洋浦 1 +x:1 +整存 1 +x:1 +号码 1 +x:1 +十届二中 1 +x:1 +大道队 1 +x:1 +汗脚 1 +x:1 +醒者 1 +x:1 +小有名气 1 +x:1 +筹融资 1 +x:1 +资助者 1 +x:1 +瓷土 1 +x:1 +保险 1 +x:1 +联心 1 +x:1 +三叶形虫 1 +x:1 +血 186 +x:186 +八一厂 1 +x:1 +气死 1 +x:1 +优异 1 +x:1 +挂点户 1 +x:1 +对口 1 +x:1 +足球场 1 +x:1 +工头 1 +x:1 +娱乐厅 1 +x:1 +编排 1 +x:1 +插建 1 +x:1 +遮羞 1 +x:1 +琐事 1 +x:1 +明确化 1 +x:1 +对号 1 +x:1 +慢慢悠悠 1 +x:1 +平素 1 +x:1 +仰卧起坐 1 +x:1 +小河口镇 1 +x:1 +宁国 1 +x:1 +室内 1 +x:1 +优弧 1 +x:1 +恭楷 1 +x:1 +督战 1 +x:1 +可操作性 1 +x:1 +指点迷津 1 +x:1 +叩开 1 +x:1 +刁钻 1 +x:1 +一览无遗 1 +x:1 +赏赐 1 +x:1 +软式 1 +x:1 +蛛网 1 +x:1 +自物权 1 +x:1 +跷跷板 1 +x:1 +滋补品 1 +x:1 +全力以赴 1 +x:1 +教导师 1 +x:1 +院落 1 +x:1 +金钱龟 1 +x:1 +秒表 1 +x:1 +凋落 1 +x:1 +八渡 1 +x:1 +猜拳 1 +x:1 +根量 1 +x:1 +读书潮 1 +x:1 +胫骨 1 +x:1 +奸细 1 +x:1 +鼎锅 1 +x:1 +索誉 1 +x:1 +折腾 1 +x:1 +暴 12 +x:12 +看守所 1 +x:1 +折腰 1 +x:1 +东边沿 1 +x:1 +西服革履 1 +x:1 +软弱 1 +x:1 +房款 1 +x:1 +关员 1 +x:1 +裂开 1 +x:1 +蜜源 1 +x:1 +板上钉钉 1 +x:1 +拦击 1 +x:1 +优待 1 +x:1 +同情心 1 +x:1 +东北非 1 +x:1 +天高地厚 1 +x:1 +柔劲儿 1 +x:1 +自豪者 1 +x:1 +死硬 1 +x:1 +稳定器 1 +x:1 +烟头 1 +x:1 +福星 1 +x:1 +督抚 1 +x:1 +识货 1 +x:1 +清热泻火 1 +x:1 +亮色 1 +x:1 +保靖 1 +x:1 +刚烈 1 +x:1 +近忧 1 +x:1 +树叶 1 +x:1 +小桥 1 +x:1 +剃刀 1 +x:1 +商品生产 1 +x:1 +法制局 1 +x:1 +鼠类 1 +x:1 +对劲 1 +x:1 +供应科 1 +x:1 +争当 1 +x:1 +小桌 1 +x:1 +漓江 1 +x:1 +炎夏 1 +x:1 +迸裂 1 +x:1 +软度 1 +x:1 +阪 1 +x:1 +厚生省 1 +x:1 +注疏 1 +x:1 +栽赃 1 +x:1 +铜板纸 1 +x:1 +瓦戈庄镇 1 +x:1 +快单磁 1 +x:1 +调解剂 1 +x:1 +坦称 1 +x:1 +干河坝村 1 +x:1 +抱恨终身 1 +x:1 +漆雕 1 +x:1 +甜言蜜语 1 +x:1 +肃宁 1 +x:1 +河南团 1 +x:1 +含糊其词 1 +x:1 +冒冒失失 1 +x:1 +沈飞队 1 +x:1 +瓷器 1 +x:1 +张家村 1 +x:1 +治校 1 +x:1 +保需 1 +x:1 +小样 1 +x:1 +剧院团 1 +x:1 +固然 1 +x:1 +配系 1 +x:1 +书苑 1 +x:1 +近道 1 +x:1 +正当防卫 1 +x:1 +侧视图 1 +x:1 +编报 1 +x:1 +传神 1 +x:1 +冶炼厂 1 +x:1 +成其为 1 +x:1 +叶翠欲滴 1 +x:1 +来路不明 1 +x:1 +家电部 1 +x:1 +房檐 1 +x:1 +天主教派 1 +x:1 +恭桶 1 +x:1 +治标 1 +x:1 +后话 1 +x:1 +糙甸乡 1 +x:1 +可即 1 +x:1 +交响乐章 1 +x:1 +二秘 1 +x:1 +前列腺病 1 +x:1 +根部 1 +x:1 +柞丝绸 1 +x:1 +铅粉 1 +x:1 +被录用者 1 +x:1 +校级 1 +x:1 +沧县 1 +x:1 +标准音 1 +x:1 +近邻 1 +x:1 +蔓延 1 +x:1 +缩印本 1 +x:1 +撒手人寰 1 +x:1 +战列舰 1 +x:1 +集镇 1 +x:1 +凋蔽 1 +x:1 +音乐部 1 +x:1 +软席 1 +x:1 +专卖法 1 +x:1 +遗老 1 +x:1 +辐射点 1 +x:1 +永安村 1 +x:1 +不屈 1 +x:1 +吟就 1 +x:1 +西安市 1 +x:1 +两肋插刀 1 +x:1 +治检 1 +x:1 +不屑 1 +x:1 +小棚 1 +x:1 +耍花样 1 +x:1 +麻黄 1 +x:1 +追缉 1 +x:1 +果子露 1 +x:1 +货仓式 1 +x:1 +重工 1 +x:1 +拂逆 1 +x:1 +水獭皮 1 +x:1 +鼠粪 1 +x:1 +书艺 1 +x:1 +农学院 1 +x:1 +编成 1 +x:1 +四大皆空 1 +x:1 +号称 1 +x:1 +可取 1 +x:1 +博湖 1 +x:1 +分检机 1 +x:1 +小国 1 +x:1 +裂帛 1 +x:1 +可可 1 +x:1 +联合社 1 +x:1 +扬子鳄 1 +x:1 +套红 1 +x:1 +滴丸 1 +x:1 +宁馨 1 +x:1 +可口 1 +x:1 +死神 1 +x:1 +的卡 1 +x:1 +实际工资 1 +x:1 +性社会学 1 +x:1 +呢子 1 +x:1 +这年 1 +x:1 +集锦 1 +x:1 +青石狮子 1 +x:1 +进站口 1 +x:1 +近郊 1 +x:1 +美容热 1 +x:1 +载歌载舞 1 +x:1 +分担 1 +x:1 +好样 1 +x:1 +镂嵌 1 +x:1 +羽翼 1 +x:1 +含笑九泉 1 +x:1 +广播稿 1 +x:1 +倾向 1 +x:1 +科技委 1 +x:1 +油画像 1 +x:1 +透彻 1 +x:1 +供应站 1 +x:1 +芯片组 1 +x:1 +弓形 1 +x:1 +对冲 1 +x:1 +不必 1 +x:1 +行尸走肉 1 +x:1 +医务科 1 +x:1 +伯延村 1 +x:1 +枪托 1 +x:1 +老大不小 1 +x:1 +对内 1 +x:1 +致敬 1 +x:1 +羽翅 1 +x:1 +身腰 1 +x:1 +宜路镇 1 +x:1 +男装展 1 +x:1 +枪手 1 +x:1 +作呕 1 +x:1 +悬悬的 1 +x:1 +如常 1 +x:1 +锐意 1 +x:1 +空邮 1 +x:1 +刚玉 1 +x:1 +立 430 +x:430 +速比 1 +x:1 +余庆县 1 +x:1 +大儿子 1 +x:1 +弓弩 1 +x:1 +注目 1 +x:1 +夜总会式 1 +x:1 +准星 1 +x:1 +老虎钳 1 +x:1 +湘 54 +x:54 +晶体点阵 1 +x:1 +弓弦 1 +x:1 +大气层 1 +x:1 +枪战 1 +x:1 +套索 1 +x:1 +来往 1 +x:1 +劈柴 1 +x:1 +对准 1 +x:1 +不得 1 +x:1 +出品人 1 +x:1 +防抗灾 1 +x:1 +妻舅 1 +x:1 +决赛史 1 +x:1 +幸 16 +x:16 +来得 1 +x:1 +后裔 1 +x:1 +流行乐 1 +x:1 +刁难 1 +x:1 +阿谀奉承 1 +x:1 +核仁 1 +x:1 +太和村 1 +x:1 +潮籍 1 +x:1 +转向架 1 +x:1 +生物体 1 +x:1 +征婚者 1 +x:1 +鲢鱼 1 +x:1 +一统 1 +x:1 +农耕 1 +x:1 +单单 1 +x:1 +触动 1 +x:1 +常情 1 +x:1 +残编断简 1 +x:1 +照顾性 1 +x:1 +重庆 1 +x:1 +瓦尔德斯 1 +x:1 +猜想 1 +x:1 +肉丝 1 +x:1 +车铃 1 +x:1 +小毛 1 +x:1 +不当 1 +x:1 +贯彻始终 1 +x:1 +炮舰 1 +x:1 +书脊 1 +x:1 +气概 1 +x:1 +炼 12 +x:12 +调查点 1 +x:1 +芦花 1 +x:1 +橡木 1 +x:1 +配置 1 +x:1 +杀身之祸 1 +x:1 +刑房 1 +x:1 +炮艇 1 +x:1 +牢牢 1 +x:1 +怀来县 1 +x:1 +以方 1 +x:1 +工况法 1 +x:1 +云丝 1 +x:1 +点石成金 1 +x:1 +科技处 1 +x:1 +重建 1 +x:1 +对光 1 +x:1 +广播站 1 +x:1 +樱桃花 1 +x:1 +乱成一团 1 +x:1 +说明符 1 +x:1 +鲜花锦簇 1 +x:1 +羽缎 1 +x:1 +横竖 1 +x:1 +引导 1 +x:1 +保镖 1 +x:1 +风油精 1 +x:1 +逾期率 1 +x:1 +战斗员 1 +x:1 +白头翁 1 +x:1 +歇业 1 +x:1 +评先创优 1 +x:1 +朝乾夕惕 1 +x:1 +党支部 1 +x:1 +金陵乡 1 +x:1 +半停产 1 +x:1 +农学家 1 +x:1 +粥 7 +x:7 +受贿案 1 +x:1 +羽绒 1 +x:1 +节钱 1 +x:1 +乒乒乓乓 1 +x:1 +不廉 1 +x:1 +芦草 1 +x:1 +崎岖 1 +x:1 +贪心 1 +x:1 +尧子营村 1 +x:1 +羽纱 1 +x:1 +资 121 +x:121 +解放后 1 +x:1 +伍 197 +x:197 +重彩 1 +x:1 +运动装 1 +x:1 +树冠 1 +x:1 +关城 1 +x:1 +技法 1 +x:1 +体育场 1 +x:1 +高要市 1 +x:1 +柠檬酸 1 +x:1 +联委会 1 +x:1 +阑珊 1 +x:1 +齐齐哈尔 1 +x:1 +试电笔 1 +x:1 +海岸带区 1 +x:1 +民政党 1 +x:1 +月工资 1 +x:1 +念叨 1 +x:1 +驶 80 +x:80 +减法 1 +x:1 +出麦口 1 +x:1 +博泰 1 +x:1 +梁家坡 1 +x:1 +房梁 1 +x:1 +流行病 1 +x:1 +训练馆 1 +x:1 +销钉 1 +x:1 +标准间 1 +x:1 +五花肉 1 +x:1 +援敌 1 +x:1 +皇家宫苑 1 +x:1 +恒定 1 +x:1 +不平 1 +x:1 +题 278 +x:278 +来年 1 +x:1 +不幸 1 +x:1 +狂躁 1 +x:1 +丛谈 1 +x:1 +土茯苓 1 +x:1 +沉毅 1 +x:1 +因果 1 +x:1 +联展 1 +x:1 +树兜 1 +x:1 +南回归线 1 +x:1 +工本费 1 +x:1 +保育员 1 +x:1 +软尺 1 +x:1 +樟脑丸 1 +x:1 +湖塘镇 1 +x:1 +肝肠寸断 1 +x:1 +体操队 1 +x:1 +粤东北 1 +x:1 +纤检所 1 +x:1 +打群架 1 +x:1 +树儿 1 +x:1 +长沙县 1 +x:1 +曲阳县 1 +x:1 +赫哲族 1 +x:1 +压力机 1 +x:1 +协税护费 1 +x:1 +高都镇 1 +x:1 +非主导 1 +x:1 +分镜头 1 +x:1 +对偶 1 +x:1 +运动衫 1 +x:1 +触发 1 +x:1 +运动表 1 +x:1 +重心 1 +x:1 +征议期 1 +x:1 +运动衣 1 +x:1 +养神 1 +x:1 +二等 1 +x:1 +西直门 1 +x:1 +所有物 1 +x:1 +杳 1 +x:1 +贫户 1 +x:1 +好友 1 +x:1 +后襟 1 +x:1 +歌以咏志 1 +x:1 +触及 1 +x:1 +市蔬菜办 1 +x:1 +醒来 1 +x:1 +后身 1 +x:1 +全劳动力 1 +x:1 +伙同 1 +x:1 +可嘉 1 +x:1 +气儿 1 +x:1 +貉子 1 +x:1 +采莲船 1 +x:1 +识见 1 +x:1 +治印 1 +x:1 +紫铜 1 +x:1 +套筒 1 +x:1 +集安 1 +x:1 +投机倒把 1 +x:1 +权且 1 +x:1 +交易额 1 +x:1 +逆旅跋涉 1 +x:1 +资溪县 1 +x:1 +百里 1 +x:1 +手续费 1 +x:1 +清源 1 +x:1 +对垒 1 +x:1 +蛲虫 1 +x:1 +不妥 1 +x:1 +情有独钟 1 +x:1 +战斗化 1 +x:1 +椰子肉糖 1 +x:1 +不妨 1 +x:1 +漕河 1 +x:1 +胶印纸 1 +x:1 +空难 1 +x:1 +南城根 1 +x:1 +供应粮 1 +x:1 +田径赛 1 +x:1 +不如 1 +x:1 +配种 1 +x:1 +空调器 1 +x:1 +唢呐 1 +x:1 +重塑 1 +x:1 +空隙 1 +x:1 +垮台 1 +x:1 +裂宽 1 +x:1 +不妙 1 +x:1 +集邮 1 +x:1 +二簧 1 +x:1 +巴西木 1 +x:1 +怅怅 1 +x:1 +宜当 1 +x:1 +阶梯形 1 +x:1 +速洗 1 +x:1 +赶集日 1 +x:1 +肾结石 1 +x:1 +十拿九稳 1 +x:1 +阳湖 1 +x:1 +堵源截流 1 +x:1 +神学院 1 +x:1 +不好 1 +x:1 +呢帽 1 +x:1 +稍事停留 1 +x:1 +空降 1 +x:1 +瓷厂 1 +x:1 +三缄其口 1 +x:1 +千穗谷 1 +x:1 +送话器 1 +x:1 +鸡场主 1 +x:1 +茵 8 +x:8 +自给率 1 +x:1 +吻 11 +x:11 +膳食科 1 +x:1 +不大 1 +x:1 +直接推理 1 +x:1 +情况表 1 +x:1 +出类拔萃 1 +x:1 +关停 1 +x:1 +电讯业 1 +x:1 +逆之者 1 +x:1 +联程票 1 +x:1 +芦蒿 1 +x:1 +廊桥遗梦 1 +x:1 +忽明忽暗 1 +x:1 +来头 1 +x:1 +摘译 1 +x:1 +声震寰宇 1 +x:1 +二类 1 +x:1 +空防 1 +x:1 +广兴镇 1 +x:1 +本格拉 1 +x:1 +棋盘 1 +x:1 +巫峡镇 1 +x:1 +套管 1 +x:1 +米兰队 1 +x:1 +不复 1 +x:1 +孤旅 1 +x:1 +拉伸形变 1 +x:1 +娱乐场 1 +x:1 +不外 1 +x:1 +后刘乡 1 +x:1 +外文系 1 +x:1 +空阔 1 +x:1 +对坐 1 +x:1 +不够 1 +x:1 +狐朋狗友 1 +x:1 +将息 1 +x:1 +重大 1 +x:1 +地中海 1 +x:1 +山山水水 1 +x:1 +解放前 1 +x:1 +众寡悬殊 1 +x:1 +曲项 1 +x:1 +巴格达城 1 +x:1 +后边 1 +x:1 +治污 1 +x:1 +横穿 1 +x:1 +黄陂县 1 +x:1 +气温 1 +x:1 +坚定性 1 +x:1 +安魂 1 +x:1 +语义学 1 +x:1 +关内 1 +x:1 +含糊其辞 1 +x:1 +后辈 1 +x:1 +博古通今 1 +x:1 +藏医院 1 +x:1 +横空 1 +x:1 +娱乐园 1 +x:1 +重复 1 +x:1 +位于 1 +x:1 +亭 11 +x:11 +甲状旁腺 1 +x:1 +售书量 1 +x:1 +沿革 1 +x:1 +家竹箐 1 +x:1 +权位 1 +x:1 +帐外帐 1 +x:1 +愁事 1 +x:1 +大杂烩 1 +x:1 +愁云 1 +x:1 +枪支 1 +x:1 +乌兰诺娃 1 +x:1 +玻璃球 1 +x:1 +农电站 1 +x:1 +水利处 1 +x:1 +圣哲 1 +x:1 +解放初 1 +x:1 +半文盲 1 +x:1 +阳澄 1 +x:1 +清溪 1 +x:1 +戒绝 1 +x:1 +绘影绘声 1 +x:1 +试验段 1 +x:1 +后进 1 +x:1 +型心 1 +x:1 +钢丝 1 +x:1 +小气 1 +x:1 +调解国 1 +x:1 +霜寒 1 +x:1 +小注 1 +x:1 +利润额 1 +x:1 +督查 1 +x:1 +碎 50 +x:50 +捐建者 1 +x:1 +你家 1 +x:1 +啤酒杯 1 +x:1 +新店 1 +x:1 +拗不过 1 +x:1 +贪奢 1 +x:1 +树坑 1 +x:1 +玻璃瓶 1 +x:1 +亦然 1 +x:1 +治法 1 +x:1 +看风使舵 1 +x:1 +巴蓬式 1 +x:1 +气象卫星 1 +x:1 +铸币局 1 +x:1 +血肉相连 1 +x:1 +德班港 1 +x:1 +若无其事 1 +x:1 +平角 1 +x:1 +精神化 1 +x:1 +质因数 1 +x:1 +前置性 1 +x:1 +圣周 1 +x:1 +誓愿 1 +x:1 +战斗力 1 +x:1 +后轮 1 +x:1 +治治 1 +x:1 +当金山 1 +x:1 +不堪 1 +x:1 +自学 1 +x:1 +固疾 1 +x:1 +教育为本 1 +x:1 +愁丝 1 +x:1 +瓷勺 1 +x:1 +传讯台 1 +x:1 +气滞 1 +x:1 +打砸抢 1 +x:1 +绢 4 +x:4 +霜害 1 +x:1 +贪多 1 +x:1 +治沙 1 +x:1 +东山镇 1 +x:1 +绲边 1 +x:1 +托呼秋山 1 +x:1 +压力感 1 +x:1 +养鸡业 1 +x:1 +享有 1 +x:1 +宁连路 1 +x:1 +解难 1 +x:1 +大同世界 1 +x:1 +垂垂老矣 1 +x:1 +二级 1 +x:1 +蜜桔 1 +x:1 +联姻 1 +x:1 +歌乐舞 1 +x:1 +宜川 1 +x:1 +旱涝 1 +x:1 +带头雁 1 +x:1 +阳泉 1 +x:1 +情缘 1 +x:1 +狠心狼 1 +x:1 +曾孙女 1 +x:1 +岸防 1 +x:1 +二线 1 +x:1 +解放党 1 +x:1 +万里迢迢 1 +x:1 +羡 1 +x:1 +安顺 1 +x:1 +堤 48 +x:48 +登记书 1 +x:1 +可否 1 +x:1 +弓子 1 +x:1 +期望值 1 +x:1 +高密镇 1 +x:1 +套票 1 +x:1 +对喝 1 +x:1 +炎帝 1 +x:1 +港北区 1 +x:1 +信誉者 1 +x:1 +拉玛四路 1 +x:1 +寒酸气 1 +x:1 +刚石 1 +x:1 +数理学部 1 +x:1 +喀什 1 +x:1 +达标户 1 +x:1 +阳沟 1 +x:1 +库纳 1 +x:1 +影帝 1 +x:1 +妙高台 1 +x:1 +大作家 1 +x:1 +来客 1 +x:1 +单人舞 1 +x:1 +来宾 1 +x:1 +保送 1 +x:1 +恰到好处 1 +x:1 +开车 1 +x:1 +不容 1 +x:1 +小本生意 1 +x:1 +死结 1 +x:1 +来安 1 +x:1 +标准速 1 +x:1 +白台山 1 +x:1 +补救 1 +x:1 +二十四史 1 +x:1 +的哥 1 +x:1 +不安 1 +x:1 +维护者 1 +x:1 +供应线 1 +x:1 +莲子粥 1 +x:1 +劣作 1 +x:1 +不宜 1 +x:1 +煤饼炉 1 +x:1 +好汉 1 +x:1 +锐敏 1 +x:1 +不定 1 +x:1 +阳江 1 +x:1 +竞艳图 1 +x:1 +起始 1 +x:1 +套种 1 +x:1 +不省人事 1 +x:1 +广播线 1 +x:1 +决赛圈 1 +x:1 +腓骨 1 +x:1 +歧口 1 +x:1 +尘烟 1 +x:1 +贪婪 1 +x:1 +对唱 1 +x:1 +希伯伦 1 +x:1 +圣地 1 +x:1 +关切 1 +x:1 +计程车 1 +x:1 +春卷皮 1 +x:1 +拂面 1 +x:1 +养老院 1 +x:1 +音标 1 +x:1 +认同式 1 +x:1 +不情之请 1 +x:1 +不孕 1 +x:1 +简言之 1 +x:1 +▲ 114 +x:114 +圣土 1 +x:1 +煞是 1 +x:1 +达瓦纳吉 1 +x:1 +黄山新村 1 +x:1 +喜悦队 1 +x:1 +销量 1 +x:1 +阳气 1 +x:1 +化害为利 1 +x:1 +冗繁 1 +x:1 +排子车 1 +x:1 +联大 1 +x:1 +大起大落 1 +x:1 +将才 1 +x:1 +金胜村 1 +x:1 +好法 1 +x:1 +仪陇 1 +x:1 +浮雕像 1 +x:1 +白庙乡 1 +x:1 +赏识 1 +x:1 +竹枝词 1 +x:1 +忧思录 1 +x:1 +圣坛 1 +x:1 +蛰 1 +x:1 +囊中物 1 +x:1 +梅花节 1 +x:1 +头顶部 1 +x:1 +千里鹅毛 1 +x:1 +岁 2433 +x:2433 +空门 1 +x:1 +认同度 1 +x:1 +娱乐品 1 +x:1 +预制构件 1 +x:1 +势能 1 +x:1 +固氮菌 1 +x:1 +邕 2 +x:2 +鼠穴 1 +x:1 +救火队员 1 +x:1 +篮子 1 +x:1 +空闲 1 +x:1 +气氛 1 +x:1 +连体儿 1 +x:1 +年复一年 1 +x:1 +苏伊玛 1 +x:1 +督教 1 +x:1 +奋发进取 1 +x:1 +刚直 1 +x:1 +枪杆 1 +x:1 +乐游乐心 1 +x:1 +枪杀 1 +x:1 +小港 1 +x:1 +货真价实 1 +x:1 +有血有肉 1 +x:1 +蚌埠 1 +x:1 +后路 1 +x:1 +熬煎 1 +x:1 +速滑 1 +x:1 +贴金 1 +x:1 +栗子园 1 +x:1 +敏锐度 1 +x:1 +枪术 1 +x:1 +督政 1 +x:1 +樟脑 1 +x:1 +岳阳县队 1 +x:1 +破碎机 1 +x:1 +你好 1 +x:1 +东北部 1 +x:1 +贪官 1 +x:1 +摸透 1 +x:1 +引得 1 +x:1 +专修班 1 +x:1 +编撰 1 +x:1 +平米 1 +x:1 +重字 1 +x:1 +有棱有角 1 +x:1 +体育化 1 +x:1 +下不为例 1 +x:1 +浮游生物 1 +x:1 +后跟 1 +x:1 +竹 51 +x:51 +不堪设想 1 +x:1 +霜天 1 +x:1 +扣押款 1 +x:1 +分内事 1 +x:1 +后账 1 +x:1 +体育史 1 +x:1 +小号 1 +x:1 +可喜 1 +x:1 +保重 1 +x:1 +如实 1 +x:1 +冒进 1 +x:1 +粗粝 1 +x:1 +感 232 +x:232 +保释 1 +x:1 +死缓 1 +x:1 +对合 1 +x:1 +技校 1 +x:1 +堵击 1 +x:1 +宜山 1 +x:1 +全国性奖 1 +x:1 +眼珠子 1 +x:1 +北戴河 1 +x:1 +核竞赛 1 +x:1 +根雕 1 +x:1 +怜怜 1 +x:1 +儿 15 +x:15 +一潭死水 1 +x:1 +外侮内乱 1 +x:1 +皮辊棉 1 +x:1 +生猛海鲜 1 +x:1 +咚 1 +x:1 +谐戏 1 +x:1 +枪枪 1 +x:1 +内蓄力 1 +x:1 +死罪 1 +x:1 +对味 1 +x:1 +反垄断法 1 +x:1 +情结 1 +x:1 +后起 1 +x:1 +舞蹈诗 1 +x:1 +情绪 1 +x:1 +刑期 1 +x:1 +黑斑蚊 1 +x:1 +名特优新 1 +x:1 +龙舟界 1 +x:1 +愚民政策 1 +x:1 +欢笑 1 +x:1 +关卡 1 +x:1 +福居 1 +x:1 +果子酱 1 +x:1 +故土难移 1 +x:1 +发生率 1 +x:1 +阿鲁沙省 1 +x:1 +粗布 1 +x:1 +比绍 1 +x:1 +中央文件 1 +x:1 +小照 1 +x:1 +天下兴亡 1 +x:1 +湖羊 1 +x:1 +催 68 +x:68 +某个 1 +x:1 +情感 1 +x:1 +钢印 1 +x:1 +成就展 1 +x:1 +策划室 1 +x:1 +鼎足 1 +x:1 +配方 1 +x:1 +共管 1 +x:1 +权利 1 +x:1 +湖群 1 +x:1 +老虎团 1 +x:1 +情愫 1 +x:1 +愆 1 +x:1 +校服 1 +x:1 +整党 1 +x:1 +沥沥 1 +x:1 +情愿 1 +x:1 +贴身 1 +x:1 +法国史 1 +x:1 +配料 1 +x:1 +胜果 1 +x:1 +训练舱 1 +x:1 +训练舰 1 +x:1 +狂妄 1 +x:1 +巡逻哨 1 +x:1 +糖萝卜 1 +x:1 +坪石乡 1 +x:1 +锦标赛 1 +x:1 +套服 1 +x:1 +叶落归根 1 +x:1 +振兴期 1 +x:1 +泓 18 +x:18 +魔岩 1 +x:1 +证券化 1 +x:1 +穷国 1 +x:1 +粟城乡 1 +x:1 +冬运会 1 +x:1 +钢包 1 +x:1 +垭子口 1 +x:1 +受聘者 1 +x:1 +一年制 1 +x:1 +风土民情 1 +x:1 +班 283 +x:283 +交朋友 1 +x:1 +半信半疑 1 +x:1 +好片 1 +x:1 +细微处 1 +x:1 +白醋 1 +x:1 +渣滓 1 +x:1 +迎宾馆 1 +x:1 +国营企业 1 +x:1 +税制 1 +x:1 +体操赛 1 +x:1 +贱骨头 1 +x:1 +正无限 1 +x:1 +边塞诗 1 +x:1 +注水 1 +x:1 +心怵 1 +x:1 +奥什州 1 +x:1 +白蜘蛛 1 +x:1 +柳暗花明 1 +x:1 +专己者 1 +x:1 +寒酸状 1 +x:1 +养成 1 +x:1 +合家欢聚 1 +x:1 +习题册 1 +x:1 +自谋生路 1 +x:1 +戒指 1 +x:1 +权势 1 +x:1 +资江 1 +x:1 +穿射 1 +x:1 +年久月深 1 +x:1 +小楠树 1 +x:1 +蠢货 1 +x:1 +瓜子 1 +x:1 +突击团 1 +x:1 +顽痹 1 +x:1 +埋藏处 1 +x:1 +绶带鸟 1 +x:1 +侵权者 1 +x:1 +仔 8 +x:8 +颠儿 1 +x:1 +页心 1 +x:1 +百货 1 +x:1 +组合港 1 +x:1 +铁力木 1 +x:1 +钢厂 1 +x:1 +一窥全豹 1 +x:1 +淹死 1 +x:1 +顽痛 1 +x:1 +假想敌 1 +x:1 +顽症 1 +x:1 +近观 1 +x:1 +保育会 1 +x:1 +通知 1 +x:1 +条分缕析 1 +x:1 +旱獭 1 +x:1 +试用本 1 +x:1 +湿 67 +x:67 +朱古力 1 +x:1 +血压计 1 +x:1 +中核总 1 +x:1 +书记处 1 +x:1 +忘乎所以 1 +x:1 +情态 1 +x:1 +情怀 1 +x:1 +声势浩大 1 +x:1 +情思 1 +x:1 +三叠纪 1 +x:1 +堵住 1 +x:1 +半截子 1 +x:1 +小灶 1 +x:1 +位势 1 +x:1 +主办者 1 +x:1 +窝 36 +x:36 +敖包 1 +x:1 +贴边 1 +x:1 +情急 1 +x:1 +科恰班巴 1 +x:1 +白城市 1 +x:1 +踪 7 +x:7 +空话 1 +x:1 +身驱 1 +x:1 +略识之无 1 +x:1 +命根儿 1 +x:1 +钟乳石 1 +x:1 +涉嫌人 1 +x:1 +瓷业 1 +x:1 +马斯喀特 1 +x:1 +常务会 1 +x:1 +功在当代 1 +x:1 +抖威风 1 +x:1 +啤酒箱 1 +x:1 +湖绉 1 +x:1 +公用电话 1 +x:1 +美发厅 1 +x:1 +通知栏 1 +x:1 +柏 21 +x:21 +贴近 1 +x:1 +运算符 1 +x:1 +钢制 1 +x:1 +技监 1 +x:1 +空论 1 +x:1 +大道 1 +x:1 +辩护权 1 +x:1 +穿巡 1 +x:1 +消耗型 1 +x:1 +钢刀 1 +x:1 +写票处 1 +x:1 +玄学 1 +x:1 +盛衰荣辱 1 +x:1 +钉齿耙 1 +x:1 +谁家 1 +x:1 +选配 1 +x:1 +夫妻店 1 +x:1 +座谈 1 +x:1 +财富表 1 +x:1 +古仙洞 1 +x:1 +以苦为荣 1 +x:1 +配搭 1 +x:1 +错简 1 +x:1 +燃料油 1 +x:1 +独流镇 1 +x:1 +樵姑 1 +x:1 +医院 1 +x:1 +地市级 1 +x:1 +丕 1 +x:1 +降龙伏虎 1 +x:1 +雷厉风行 1 +x:1 +嚣张气焰 1 +x:1 +西藏区 1 +x:1 +好玩 1 +x:1 +瓷人 1 +x:1 +赏钱 1 +x:1 +可怜巴巴 1 +x:1 +欧 624 +x:624 +公德 1 +x:1 +垂暮之年 1 +x:1 +黄巾起义 1 +x:1 +位列 1 +x:1 +医务所 1 +x:1 +套曲 1 +x:1 +门脸房 1 +x:1 +被访问者 1 +x:1 +施工量 1 +x:1 +落拓 1 +x:1 +栅栏 1 +x:1 +立脚点 1 +x:1 +粗心 1 +x:1 +阳新县 1 +x:1 +情情 1 +x:1 +编程 1 +x:1 +登记册 1 +x:1 +差率 1 +x:1 +权变 1 +x:1 +白龙江 1 +x:1 +汇藏 1 +x:1 +好像 1 +x:1 +交感神经 1 +x:1 +我行我素 1 +x:1 +草食性 1 +x:1 +孤寒 1 +x:1 +经果林带 1 +x:1 +东岳庙 1 +x:1 +颠倒 1 +x:1 +栅格 1 +x:1 +春风化雨 1 +x:1 +追杀 1 +x:1 +露马脚 1 +x:1 +权台 1 +x:1 +新景观 1 +x:1 +顾乡屯 1 +x:1 +英吉沙县 1 +x:1 +展演团 1 +x:1 +瑟瑟 1 +x:1 +南码头路 1 +x:1 +绵阳市 1 +x:1 +蚂蜂 1 +x:1 +错码 1 +x:1 +刚毅 1 +x:1 +伊万科夫 1 +x:1 +搞法 1 +x:1 +气焰 1 +x:1 +炊事班 1 +x:1 +渣油 1 +x:1 +书刊社 1 +x:1 +断崖 1 +x:1 +崭露头角 1 +x:1 +速率 1 +x:1 +可怜虫 1 +x:1 +物理性质 1 +x:1 +坐班 1 +x:1 +服装 1 +x:1 +销账 1 +x:1 +销货 1 +x:1 +书香 1 +x:1 +舞蹈队 1 +x:1 +慈母村 1 +x:1 +双引擎 1 +x:1 +书馆 1 +x:1 +将级 1 +x:1 +忘记 1 +x:1 +神奇莫测 1 +x:1 +开山炮 1 +x:1 +漾 5 +x:5 +后部 1 +x:1 +空袭 1 +x:1 +运动量 1 +x:1 +碳酸丙烯 1 +x:1 +观象台 1 +x:1 +香菊片 1 +x:1 +酾 1 +x:1 +江汉关 1 +x:1 +马斯克林 1 +x:1 +会诊会 1 +x:1 +治穷 1 +x:1 +联营制 1 +x:1 +气煤 1 +x:1 +鲜奶费 1 +x:1 +誓约 1 +x:1 +值域 1 +x:1 +号手 1 +x:1 +近年来 1 +x:1 +规划部 1 +x:1 +登记制 1 +x:1 +金晃晃的 1 +x:1 +浑蛋 1 +x:1 +以为 1 +x:1 +炼石补天 1 +x:1 +庚申 1 +x:1 +水落管 1 +x:1 +小班 1 +x:1 +睥睨 1 +x:1 +关东 1 +x:1 +下笔成章 1 +x:1 +缉私艇 1 +x:1 +长三火箭 1 +x:1 +有生力量 1 +x:1 +功德无量 1 +x:1 +团代会 1 +x:1 +校方 1 +x:1 +安危祸福 1 +x:1 +吊唁 1 +x:1 +传播者 1 +x:1 +如期 1 +x:1 +交汇处 1 +x:1 +后退 1 +x:1 +两用车 1 +x:1 +谦虚 1 +x:1 +死战 1 +x:1 +配有 1 +x:1 +警区制 1 +x:1 +刚正 1 +x:1 +教职工 1 +x:1 +压根儿 1 +x:1 +关中 1 +x:1 +治贫 1 +x:1 +天才 1 +x:1 +重机 1 +x:1 +二战 1 +x:1 +敌营房 1 +x:1 +颠狂 1 +x:1 +库房 1 +x:1 +顽石 1 +x:1 +农用地 1 +x:1 +坦承 1 +x:1 +死扣 1 +x:1 +邵阳县 1 +x:1 +老太太 1 +x:1 +尘沙 1 +x:1 +关乎 1 +x:1 +生物圈 1 +x:1 +原主 1 +x:1 +宁芜 1 +x:1 +蚂蟥 1 +x:1 +二手 1 +x:1 +昆剧热 1 +x:1 +果园主 1 +x:1 +校旗 1 +x:1 +宗谅 1 +x:1 +知名度 1 +x:1 +得大自在 1 +x:1 +下莱茵省 1 +x:1 +断鸿声 1 +x:1 +绢画 1 +x:1 +登记卡 1 +x:1 +坦荡 1 +x:1 +玻璃橱 1 +x:1 +祖居地 1 +x:1 +通路率 1 +x:1 +编磬 1 +x:1 +斥骂 1 +x:1 +献技 1 +x:1 +宗谱 1 +x:1 +白送 1 +x:1 +三点钟 1 +x:1 +盗窃罪 1 +x:1 +歧义 1 +x:1 +进口商品 1 +x:1 +肾结核 1 +x:1 +夜不闭户 1 +x:1 +纂喜庐 1 +x:1 +母族国 1 +x:1 +额角 1 +x:1 +挤挤 1 +x:1 +待考 1 +x:1 +湖岸 1 +x:1 +顽癣 1 +x:1 +谣诼 1 +x:1 +微软科学 1 +x:1 +奏乐 1 +x:1 +保费 1 +x:1 +自由职业 1 +x:1 +铲运车 1 +x:1 +体育会 1 +x:1 +唯其如此 1 +x:1 +保质 1 +x:1 +债权者 1 +x:1 +异体字 1 +x:1 +蚂蚁 1 +x:1 +览胜 1 +x:1 +晾干 1 +x:1 +拖斗 1 +x:1 +坐牢 1 +x:1 +花生棵 1 +x:1 +碾子山区 1 +x:1 +劣势 1 +x:1 +夏洛特 1 +x:1 +顽皮 1 +x:1 +座垫 1 +x:1 +转祸为福 1 +x:1 +敌顽 1 +x:1 +邮政司 1 +x:1 +滑稽戏 1 +x:1 +贴费 1 +x:1 +情报 1 +x:1 +辨 31 +x:31 +职务 1 +x:1 +雪野 1 +x:1 +唯 57 +x:57 +正话 1 +x:1 +贫穷 1 +x:1 +蚂蚱 1 +x:1 +助困生 1 +x:1 +舞蹈鞋 1 +x:1 +堰塞湖 1 +x:1 +编码 1 +x:1 +书页 1 +x:1 +医改 1 +x:1 +配景 1 +x:1 +孤童 1 +x:1 +粗线条 1 +x:1 +名声大振 1 +x:1 +精毛纺厂 1 +x:1 +表嫂 1 +x:1 +产品名 1 +x:1 +松仁 1 +x:1 +怜悯 1 +x:1 +转悠 1 +x:1 +枪管 1 +x:1 +说得着 1 +x:1 +搞活 1 +x:1 +孤立 1 +x:1 +挤掉 1 +x:1 +试验田 1 +x:1 +招贤纳士 1 +x:1 +总公司 1 +x:1 +外营力 1 +x:1 +旱灾 1 +x:1 +蓄势 1 +x:1 +武侠片 1 +x:1 +泽土 1 +x:1 +质量战 1 +x:1 +升幂 1 +x:1 +运动鞋 1 +x:1 +气眼 1 +x:1 +质量日 1 +x:1 +邮电业 1 +x:1 +钢坯 1 +x:1 +测试盒 1 +x:1 +截至 1 +x:1 +严峻性 1 +x:1 +聊聊 1 +x:1 +麻药 1 +x:1 +帜 2 +x:2 +中国娃 1 +x:1 +欢情 1 +x:1 +后隋 1 +x:1 +奴役 1 +x:1 +喜怒无常 1 +x:1 +读书班 1 +x:1 +多能 1 +x:1 +收 771 +x:771 +保龄球 1 +x:1 +副产品 1 +x:1 +人士界 1 +x:1 +情敌 1 +x:1 +固氮 1 +x:1 +剩余产品 1 +x:1 +巴东栎 1 +x:1 +精耕细作 1 +x:1 +桃源村 1 +x:1 +专员公署 1 +x:1 +劳动部门 1 +x:1 +可乐 1 +x:1 +宇宙射线 1 +x:1 +遮掩 1 +x:1 +泄洪 1 +x:1 +亚马孙 1 +x:1 +三角洲 1 +x:1 +秒钟 1 +x:1 +乳制品界 1 +x:1 +喷锚网 1 +x:1 +小生 1 +x:1 +多肽 1 +x:1 +新加坡 1 +x:1 +偿还期 1 +x:1 +李家峡 1 +x:1 +坐力 1 +x:1 +海河湾 1 +x:1 +秒针 1 +x:1 +治则 1 +x:1 +速生 1 +x:1 +一神教 1 +x:1 +提督 1 +x:1 +睡眠疗法 1 +x:1 +俨然 1 +x:1 +亚美 1 +x:1 +坐功 1 +x:1 +倒打一耙 1 +x:1 +斗殴案 1 +x:1 +嫌疑 1 +x:1 +雌雄同体 1 +x:1 +湖笔 1 +x:1 +质量数 1 +x:1 +卫星城 1 +x:1 +党政不分 1 +x:1 +后防 1 +x:1 +磁浮 1 +x:1 +废奴令 1 +x:1 +利比里亚 1 +x:1 +凝灰岩 1 +x:1 +袖章 1 +x:1 +新生界 1 +x:1 +言者无罪 1 +x:1 +芤 1 +x:1 +麻洋镇 1 +x:1 +溜须 1 +x:1 +谣谚 1 +x:1 +可人 1 +x:1 +治病 1 +x:1 +鳖边 1 +x:1 +交易者 1 +x:1 +可亲 1 +x:1 +穷酸气 1 +x:1 +出油率 1 +x:1 +多者 1 +x:1 +后院 1 +x:1 +解除 1 +x:1 +帝都史 1 +x:1 +财 97 +x:97 +戒条 1 +x:1 +宁蒗 1 +x:1 +战败国 1 +x:1 +千山万壑 1 +x:1 +树丫 1 +x:1 +姚家村 1 +x:1 +近路 1 +x:1 +销售一空 1 +x:1 +强硬派 1 +x:1 +治疗 1 +x:1 +朱刘镇 1 +x:1 +宇航员 1 +x:1 +脑下垂体 1 +x:1 +树丛 1 +x:1 +近距 1 +x:1 +片马镇 1 +x:1 +竟是 1 +x:1 +矢志 1 +x:1 +固沙 1 +x:1 +座像 1 +x:1 +轻重缓急 1 +x:1 +完税率 1 +x:1 +规划院 1 +x:1 +广播操 1 +x:1 +煮鹤焚琴 1 +x:1 +特色牌 1 +x:1 +农电工 1 +x:1 +编织 1 +x:1 +座儿 1 +x:1 +坦方 1 +x:1 +户政 1 +x:1 +黄淮海 1 +x:1 +成就奖 1 +x:1 +编绘 1 +x:1 +传媒界 1 +x:1 +韵文 1 +x:1 +调解书 1 +x:1 +蟹状 1 +x:1 +辰阳 1 +x:1 +老犟头 1 +x:1 +金丝席 1 +x:1 +对于 1 +x:1 +房盖 1 +x:1 +遮拦 1 +x:1 +病案室 1 +x:1 +姑舅 1 +x:1 +试验班 1 +x:1 +圆明园 1 +x:1 +空运 1 +x:1 +追授 1 +x:1 +村规民约 1 +x:1 +质协 1 +x:1 +编纂 1 +x:1 +二日 1 +x:1 +芝兰 1 +x:1 +双管齐下 1 +x:1 +火上浇油 1 +x:1 +二时 1 +x:1 +号数 1 +x:1 +泄气 1 +x:1 +可体 1 +x:1 +程派 1 +x:1 +察 25 +x:25 +咬牙 1 +x:1 +篦子 1 +x:1 +生死不渝 1 +x:1 +产油量 1 +x:1 +古文献 1 +x:1 +掩埋 1 +x:1 +遮 32 +x:32 +对付 1 +x:1 +试车场 1 +x:1 +如林 1 +x:1 +肿 15 +x:15 +服输 1 +x:1 +套房 1 +x:1 +铸造焦 1 +x:1 +对仗 1 +x:1 +空转 1 +x:1 +消耗热 1 +x:1 +校报 1 +x:1 +杜拉村 1 +x:1 +不由自主 1 +x:1 +空车 1 +x:1 +批设 1 +x:1 +花容玉貌 1 +x:1 +怪声怪气 1 +x:1 +空载 1 +x:1 +植物人 1 +x:1 +保证 1 +x:1 +彩轿 1 +x:1 +标准语 1 +x:1 +甲状腺 1 +x:1 +滴剂 1 +x:1 +直面性 1 +x:1 +卫星国 1 +x:1 +不足道 1 +x:1 +山窝窝 1 +x:1 +眼见为实 1 +x:1 +有始无终 1 +x:1 +博爱 1 +x:1 +标准论 1 +x:1 +麻花 1 +x:1 +酒吧间 1 +x:1 +蠢蠢 1 +x:1 +调解人 1 +x:1 +魔头 1 +x:1 +羽总 1 +x:1 +娱乐业 1 +x:1 +零钱 1 +x:1 +肉鸡场 1 +x:1 +交费卡 1 +x:1 +原人 1 +x:1 +追捕 1 +x:1 +袖管 1 +x:1 +旦角 1 +x:1 +在野党 1 +x:1 +博物 1 +x:1 +精武建功 1 +x:1 +交费单 1 +x:1 +欢愉 1 +x:1 +可信 1 +x:1 +岁寒堂 1 +x:1 +队里 1 +x:1 +西番莲 1 +x:1 +耍赖皮 1 +x:1 +黄石市 1 +x:1 +姑苏 1 +x:1 +死敌 1 +x:1 +运载车 1 +x:1 +趋名舍实 1 +x:1 +追悼 1 +x:1 +短讯 1 +x:1 +吃光 1 +x:1 +气田 1 +x:1 +老大难 1 +x:1 +期期艾艾 1 +x:1 +李家庄 1 +x:1 +整备 1 +x:1 +体操课 1 +x:1 +宰客风 1 +x:1 +光敏电阻 1 +x:1 +贮备 1 +x:1 +比赛期 1 +x:1 +训练营 1 +x:1 +二十三日 1 +x:1 +献 318 +x:318 +锦衣玉食 1 +x:1 +好球 1 +x:1 +八点 1 +x:1 +比赛服 1 +x:1 +天球仪 1 +x:1 +一并了之 1 +x:1 +绝对量 1 +x:1 +读后感 1 +x:1 +蝶骨 1 +x:1 +截获 1 +x:1 +须臾 1 +x:1 +只只 1 +x:1 +羊布病 1 +x:1 +指教 1 +x:1 +安克雷奇 1 +x:1 +水警区 1 +x:1 +东北角 1 +x:1 +试验点 1 +x:1 +小看 1 +x:1 +惟妙惟肖 1 +x:1 +最少 1 +x:1 +重播 1 +x:1 +拦住 1 +x:1 +扬杜抑李 1 +x:1 +堰体 1 +x:1 +捐赠款 1 +x:1 +带头 1 +x:1 +规 18 +x:18 +安之若素 1 +x:1 +遗民 1 +x:1 +乐善好施 1 +x:1 +全民性 1 +x:1 +商务区 1 +x:1 +旱田 1 +x:1 +宝鸡市 1 +x:1 +款额 1 +x:1 +追思 1 +x:1 +奸情 1 +x:1 +以水救水 1 +x:1 +燕麦地组 1 +x:1 +公务员 1 +x:1 +追怀 1 +x:1 +塔夫绸 1 +x:1 +武汉关 1 +x:1 +成化五年 1 +x:1 +小瞧 1 +x:1 +高背椅 1 +x:1 +摘采 1 +x:1 +门面话 1 +x:1 +滴滴答答 1 +x:1 +唯物史观 1 +x:1 +全村人 1 +x:1 +军医大 1 +x:1 +空谷 1 +x:1 +不冷不热 1 +x:1 +空谈 1 +x:1 +校史 1 +x:1 +吊养 1 +x:1 +粗壮 1 +x:1 +指数 1 +x:1 +吊兰 1 +x:1 +抗雪救灾 1 +x:1 +空调 1 +x:1 +循环 1 +x:1 +水貂 1 +x:1 +念书 1 +x:1 +煤财字 1 +x:1 +寡言少语 1 +x:1 +评功论赏 1 +x:1 +忠于 1 +x:1 +怨不得 1 +x:1 +座区 1 +x:1 +汽油弹 1 +x:1 +目力表 1 +x:1 +表妹 1 +x:1 +责权利 1 +x:1 +复合元音 1 +x:1 +统计表 1 +x:1 +粗大 1 +x:1 +幸福三村 1 +x:1 +踵至 1 +x:1 +阳痿 1 +x:1 +好生 1 +x:1 +读书热 1 +x:1 +俯视式 1 +x:1 +正常者 1 +x:1 +倒金字塔 1 +x:1 +丧尽天良 1 +x:1 +双球菌 1 +x:1 +气球 1 +x:1 +宇宙地镇 1 +x:1 +后门 1 +x:1 +职分 1 +x:1 +搭拉 1 +x:1 +逝者如斯 1 +x:1 +喀城 1 +x:1 +清洁煤 1 +x:1 +庄家 1 +x:1 +值勤 1 +x:1 +泳协 1 +x:1 +差生 1 +x:1 +治瘫 1 +x:1 +赏鉴 1 +x:1 +无机物 1 +x:1 +一席之地 1 +x:1 +情景 1 +x:1 +③ 40 +x:40 +征购粮 1 +x:1 +致冷器 1 +x:1 +西便门 1 +x:1 +闯荡 1 +x:1 +拉延 1 +x:1 +信筒 1 +x:1 +奴 4 +x:4 +集训 1 +x:1 +治盲 1 +x:1 +艰辛备尝 1 +x:1 +券种 1 +x:1 +耍把戏 1 +x:1 +联合村 1 +x:1 +批评 1 +x:1 +配戴 1 +x:1 +装修费 1 +x:1 +岸边 1 +x:1 +动物学 1 +x:1 +福祸 1 +x:1 +谆谆告诫 1 +x:1 +浑茫 1 +x:1 +二机 1 +x:1 +医道 1 +x:1 +圣上 1 +x:1 +治监 1 +x:1 +南山区 1 +x:1 +福祉 1 +x:1 +亦 270 +x:270 +配戏 1 +x:1 +刑罚 1 +x:1 +慎密 1 +x:1 +出售关 1 +x:1 +羽扇 1 +x:1 +路堤式 1 +x:1 +掸 3 +x:3 +竟敢 1 +x:1 +标准规 1 +x:1 +小盐 1 +x:1 +座号 1 +x:1 +保存本 1 +x:1 +二来 1 +x:1 +身份证 1 +x:1 +一企两制 1 +x:1 +气瓶 1 +x:1 +贾汪区 1 +x:1 +令人不解 1 +x:1 +宣教室 1 +x:1 +死板 1 +x:1 +驾轻就熟 1 +x:1 +纺线线 1 +x:1 +减灾 1 +x:1 +集训班 1 +x:1 +善自为之 1 +x:1 +花生油 1 +x:1 +荣 226 +x:226 +联合机 1 +x:1 +巴西籍 1 +x:1 +支农 1 +x:1 +穿孔 1 +x:1 +用材林 1 +x:1 +下功夫 1 +x:1 +阳电 1 +x:1 +保存期 1 +x:1 +码头 1 +x:1 +僧侣 1 +x:1 +村山场 1 +x:1 +感悟 1 +x:1 +言过其实 1 +x:1 +科托尔湾 1 +x:1 +路桥区 1 +x:1 +官道李村 1 +x:1 +饥寒 1 +x:1 +套餐制 1 +x:1 +话茬儿 1 +x:1 +事迹展 1 +x:1 +职称 1 +x:1 +名誉扫地 1 +x:1 +咨询 1 +x:1 +拾捡 1 +x:1 +追溯 1 +x:1 +自主化 1 +x:1 +试验组 1 +x:1 +城市群 1 +x:1 +谋职者 1 +x:1 +联保 1 +x:1 +输送量 1 +x:1 +人寿保险 1 +x:1 +干线网 1 +x:1 +输配电 1 +x:1 +相比之下 1 +x:1 +藏医药 1 +x:1 +当机立断 1 +x:1 +协调费 1 +x:1 +赣榆县 1 +x:1 +蝶形花 1 +x:1 +樱花树 1 +x:1 +错爱 1 +x:1 +空芯 1 +x:1 +鲜鲜艳艳 1 +x:1 +兆 3 +x:3 +物力 1 +x:1 +劲旅 1 +x:1 +何月 1 +x:1 +借款国 1 +x:1 +恭祝 1 +x:1 +外来语 1 +x:1 +赛车场 1 +x:1 +心灰意懒 1 +x:1 +房管 1 +x:1 +审美力 1 +x:1 +戒毒 1 +x:1 +不修边幅 1 +x:1 +单干风 1 +x:1 +新秀战 1 +x:1 +气筒 1 +x:1 +端面 1 +x:1 +二棉 1 +x:1 +明净 1 +x:1 +自攻丝刀 1 +x:1 +根脚 1 +x:1 +医龄 1 +x:1 +愁容 1 +x:1 +减去 1 +x:1 +违法必究 1 +x:1 +优伶 1 +x:1 +想想 1 +x:1 +叙及 1 +x:1 +减缩 1 +x:1 +计出万全 1 +x:1 +轮胎厂 1 +x:1 +暴殄天物 1 +x:1 +被加数 1 +x:1 +甩花者 1 +x:1 +盲区 1 +x:1 +贪婪性 1 +x:1 +穷帽 1 +x:1 +绢纺 1 +x:1 +气管 1 +x:1 +闹笑话 1 +x:1 +销毁 1 +x:1 +记事儿 1 +x:1 +张榜镇 1 +x:1 +损益表 1 +x:1 +皴 1 +x:1 +潮湿 1 +x:1 +龙水镇 1 +x:1 +比比皆是 1 +x:1 +奸滑 1 +x:1 +减缓 1 +x:1 +刚愎 1 +x:1 +释 19 +x:19 +二档 1 +x:1 +矢口 1 +x:1 +涡虫 1 +x:1 +大胡笳 1 +x:1 +骚动 1 +x:1 +你们 1 +x:1 +红专村 1 +x:1 +浑象 1 +x:1 +枪炮 1 +x:1 +集萃 1 +x:1 +地平线 1 +x:1 +谦谦 1 +x:1 +劲敌 1 +x:1 +来万塞迪 1 +x:1 +尊容 1 +x:1 +麦加 1 +x:1 +联会 1 +x:1 +灾难性 1 +x:1 +政教处 1 +x:1 +多谢 1 +x:1 +差 508 +x:508 +招商引资 1 +x:1 +安身 1 +x:1 +位子 1 +x:1 +小商 1 +x:1 +物理量 1 +x:1 +初稿 1 +x:1 +尘暴 1 +x:1 +拾掇 1 +x:1 +除暴安良 1 +x:1 +钢化玻璃 1 +x:1 +黑色素瘤 1 +x:1 +渔夫 1 +x:1 +按说 1 +x:1 +冷暖型 1 +x:1 +融资券 1 +x:1 +三角恋 1 +x:1 +吊床 1 +x:1 +车险 1 +x:1 +懒腰 1 +x:1 +捧场 1 +x:1 +集藏 1 +x:1 +好笑 1 +x:1 +养殖 1 +x:1 +泄恨 1 +x:1 +双人 1 +x:1 +横行无忌 1 +x:1 +应验 1 +x:1 +汇费 1 +x:1 +照做不误 1 +x:1 +引擎 1 +x:1 +单弦儿 1 +x:1 +辐射性 1 +x:1 +按语 1 +x:1 +端阳 1 +x:1 +热血沸腾 1 +x:1 +孤灯 1 +x:1 +登记处 1 +x:1 +猜猜 1 +x:1 +院门 1 +x:1 +湖盐 1 +x:1 +花花世界 1 +x:1 +海军蓝 1 +x:1 +叙别 1 +x:1 +破壁飞去 1 +x:1 +醒酒 1 +x:1 +突尼斯 1 +x:1 +行者 1 +x:1 +瑟缩 1 +x:1 +策马急驰 1 +x:1 +州试 1 +x:1 +物华天宝 1 +x:1 +养母 1 +x:1 +销蚀 1 +x:1 +成建制 1 +x:1 +小磨 1 +x:1 +叩击 1 +x:1 +服药 1 +x:1 +遁世 1 +x:1 +瓜分 1 +x:1 +镰刀形 1 +x:1 +请战书 1 +x:1 +权宜 1 +x:1 +联书 1 +x:1 +校友 1 +x:1 +水江头村 1 +x:1 +计算机 1 +x:1 +原盐 1 +x:1 +横行作孽 1 +x:1 +气窗 1 +x:1 +旱稻 1 +x:1 +特大型 1 +x:1 +武汉市 1 +x:1 +天朗气清 1 +x:1 +蟑螂 1 +x:1 +没门 1 +x:1 +吊带 1 +x:1 +零食 1 +x:1 +东北虎 1 +x:1 +煞煞 1 +x:1 +审美化 1 +x:1 +苒 1 +x:1 +大熊座 1 +x:1 +商务局 1 +x:1 +诱导法 1 +x:1 +全委会 1 +x:1 +安边 1 +x:1 +安达 1 +x:1 +刚性 1 +x:1 +羁押 1 +x:1 +小碟 1 +x:1 +铁门关 1 +x:1 +除尘器 1 +x:1 +大熊猫 1 +x:1 +瓜分豆剖 1 +x:1 +压案 1 +x:1 +瓜农 1 +x:1 +固执 1 +x:1 +来信 1 +x:1 +众目睽睽 1 +x:1 +如上 1 +x:1 +如下 1 +x:1 +汽油券 1 +x:1 +且末 1 +x:1 +网开三面 1 +x:1 +砥砺 1 +x:1 +如东 1 +x:1 +西方化 1 +x:1 +荣华富贵 1 +x:1 +群龙无首 1 +x:1 +动物园 1 +x:1 +五好 1 +x:1 +霞 35 +x:35 +房租 1 +x:1 +值得 1 +x:1 +盈怀充栋 1 +x:1 +疲于奔命 1 +x:1 +姊妹篇 1 +x:1 +不俗 1 +x:1 +水市乡 1 +x:1 +关键 1 +x:1 +情歌 1 +x:1 +梦幻体 1 +x:1 +进步 1 +x:1 +水利业 1 +x:1 +人欢马叫 1 +x:1 +空肠 1 +x:1 +氢氧化钙 1 +x:1 +凋零 1 +x:1 +不便 1 +x:1 +又红又专 1 +x:1 +特意 1 +x:1 +根茎 1 +x:1 +大同市 1 +x:1 +中央军委 1 +x:1 +泥沙俱下 1 +x:1 +不依 1 +x:1 +染发剂 1 +x:1 +潮河 1 +x:1 +颢 1 +x:1 +安谧 1 +x:1 +蜜糖 1 +x:1 +狂升 1 +x:1 +耳濡目染 1 +x:1 +情殇 1 +x:1 +和而不同 1 +x:1 +身量 1 +x:1 +蠕形动物 1 +x:1 +一厢情愿 1 +x:1 +试验部 1 +x:1 +老太公 1 +x:1 +啤酒店 1 +x:1 +潮汐 1 +x:1 +穷尽 1 +x:1 +淋 13 +x:13 +潮汕 1 +x:1 +位处 1 +x:1 +渣 16 +x:16 +不但 1 +x:1 +翻译者 1 +x:1 +干儿子 1 +x:1 +生闷气 1 +x:1 +不住 1 +x:1 +发电场 1 +x:1 +代售点 1 +x:1 +法律处 1 +x:1 +九五之尊 1 +x:1 +麦迪亚省 1 +x:1 +注明 1 +x:1 +大饱耳福 1 +x:1 +无贷款 1 +x:1 +不佞 1 +x:1 +悼 6 +x:6 +弯曲形变 1 +x:1 +和气生财 1 +x:1 +甲午战争 1 +x:1 +搞搞 1 +x:1 +西岗区 1 +x:1 +非同小可 1 +x:1 +如今 1 +x:1 +赐稿 1 +x:1 +叙写 1 +x:1 +自选商场 1 +x:1 +重价 1 +x:1 +特雷扑托 1 +x:1 +湖畔 1 +x:1 +穷山 1 +x:1 +下肚 1 +x:1 +潮气 1 +x:1 +重任 1 +x:1 +蝶阀 1 +x:1 +三天两头 1 +x:1 +不知所措 1 +x:1 +劲松 1 +x:1 +牌品 1 +x:1 +特困县 1 +x:1 +不休 1 +x:1 +金顶寺 1 +x:1 +追求 1 +x:1 +自信度 1 +x:1 +瘪瘪的 1 +x:1 +潮水 1 +x:1 +套汇 1 +x:1 +重伤 1 +x:1 +三等舱 1 +x:1 +长乐市 1 +x:1 +教职员 1 +x:1 +船只 1 +x:1 +来件 1 +x:1 +追涨 1 +x:1 +宝鸡县 1 +x:1 +不仅 1 +x:1 +踏遍 1 +x:1 +毫不迟疑 1 +x:1 +摇唇鼓舌 1 +x:1 +实业部 1 +x:1 +钢塔 1 +x:1 +受教育率 1 +x:1 +直播室 1 +x:1 +庄子 1 +x:1 +金榜题名 1 +x:1 +以幻写真 1 +x:1 +电子器件 1 +x:1 +妇女部长 1 +x:1 +弯弯 1 +x:1 +潮涌 1 +x:1 +安贞 1 +x:1 +独立王国 1 +x:1 +张家界 1 +x:1 +深入人心 1 +x:1 +韵母 1 +x:1 +如何 1 +x:1 +太平街镇 1 +x:1 +姗 6 +x:6 +松鼠猴 1 +x:1 +外交部 1 +x:1 +蔬菜 1 +x:1 +大元帅 1 +x:1 +警备区 1 +x:1 +防盗门 1 +x:1 +总量 1 +x:1 +特困券 1 +x:1 +赫赫有名 1 +x:1 +不予 1 +x:1 +潮润 1 +x:1 +权奸 1 +x:1 +织就 1 +x:1 +多边 1 +x:1 +借刀杀人 1 +x:1 +金钱豹 1 +x:1 +治税 1 +x:1 +三元朱村 1 +x:1 +编录 1 +x:1 +卑贱 1 +x:1 +奸淫 1 +x:1 +忠义 1 +x:1 +广播段 1 +x:1 +潮流 1 +x:1 +红五连 1 +x:1 +卢沟桥 1 +x:1 +性价比 1 +x:1 +空腹 1 +x:1 +倭瓜 1 +x:1 +保藏 1 +x:1 +自信心 1 +x:1 +事倍功半 1 +x:1 +不久 1 +x:1 +魔块 1 +x:1 +不乏 1 +x:1 +糊里糊涂 1 +x:1 +布尔诺 1 +x:1 +珍禽异兽 1 +x:1 +造船系 1 +x:1 +小站 1 +x:1 +公检法司 1 +x:1 +贸工农 1 +x:1 +莱姆病 1 +x:1 +根苗 1 +x:1 +玄武岩流 1 +x:1 +透亮 1 +x:1 +孤独 1 +x:1 +程控 1 +x:1 +公而忘私 1 +x:1 +具象 1 +x:1 +索然无味 1 +x:1 +死死 1 +x:1 +校注 1 +x:1 +小窥 1 +x:1 +呕心沥血 1 +x:1 +结构性 1 +x:1 +闯进 1 +x:1 +胜景 1 +x:1 +来临 1 +x:1 +不丹 1 +x:1 +国宾馆 1 +x:1 +度日如年 1 +x:1 +市人大办 1 +x:1 +不一 1 +x:1 +慢行 1 +x:1 +担风险 1 +x:1 +折射线 1 +x:1 +维修部 1 +x:1 +连锅端 1 +x:1 +打字机 1 +x:1 +执政党 1 +x:1 +藏龙卧虎 1 +x:1 +圣洁 1 +x:1 +白驳风 1 +x:1 +试验站 1 +x:1 +水平型 1 +x:1 +气缸 1 +x:1 +核电机组 1 +x:1 +醉 49 +x:49 +资料 1 +x:1 +壁球 1 +x:1 +蓬荜增辉 1 +x:1 +镇江籍 1 +x:1 +寄生蜂 1 +x:1 +顽军 1 +x:1 +走村串寨 1 +x:1 +调节费 1 +x:1 +邮政局 1 +x:1 +聒噪 1 +x:1 +违法性 1 +x:1 +憩 1 +x:1 +龙吟虎啸 1 +x:1 +悠然自得 1 +x:1 +贴花 1 +x:1 +倚老卖老 1 +x:1 +香花镇 1 +x:1 +死沉 1 +x:1 +中国史 1 +x:1 +从始至终 1 +x:1 +踏青 1 +x:1 +吊客 1 +x:1 +动物像 1 +x:1 +忝列 1 +x:1 +词汇学 1 +x:1 +纵隔 1 +x:1 +淅川县 1 +x:1 +贪恋 1 +x:1 +卡式炉 1 +x:1 +扶犁人 1 +x:1 +没错 1 +x:1 +漕粮 1 +x:1 +东北菜 1 +x:1 +狂喜 1 +x:1 +汽油味 1 +x:1 +外来妹 1 +x:1 +且慢 1 +x:1 +剧作 1 +x:1 +从来不 1 +x:1 +标准舞 1 +x:1 +百无禁忌 1 +x:1 +持有人 1 +x:1 +微积分 1 +x:1 +砍掉 1 +x:1 +突发性 1 +x:1 +必不可少 1 +x:1 +紧要关头 1 +x:1 +绿茸茸 1 +x:1 +刚方 1 +x:1 +弧圈球 1 +x:1 +老典型 1 +x:1 +浑然一体 1 +x:1 +保苗 1 +x:1 +学徒工 1 +x:1 +死水 1 +x:1 +集聚 1 +x:1 +针灸术 1 +x:1 +行署 1 +x:1 +象形字 1 +x:1 +琛 8 +x:8 +商务处 1 +x:1 +古虫 1 +x:1 +垃圾箱 1 +x:1 +创口 1 +x:1 +粗劣 1 +x:1 +招待费 1 +x:1 +莫测高深 1 +x:1 +感生电流 1 +x:1 +互促共荣 1 +x:1 +文史馆 1 +x:1 +医魂 1 +x:1 +空虚 1 +x:1 +红星队 1 +x:1 +嫩黄 1 +x:1 +调虎离山 1 +x:1 +供认不讳 1 +x:1 +慢车 1 +x:1 +普拉卡区 1 +x:1 +啤酒瘾 1 +x:1 +尿素霜 1 +x:1 +法国式 1 +x:1 +资方 1 +x:1 +歌舞升平 1 +x:1 +书面 1 +x:1 +捕 20 +x:20 +尹堡寨村 1 +x:1 +足球赛 1 +x:1 +特派员 1 +x:1 +逸豫 1 +x:1 +二汽 1 +x:1 +计算所 1 +x:1 +影厅 1 +x:1 +上海队 1 +x:1 +石关村 1 +x:1 +候机厅 1 +x:1 +示范点 1 +x:1 +积分榜 1 +x:1 +栾城 1 +x:1 +裸 1 +x:1 +花生果 1 +x:1 +辩证论者 1 +x:1 +宇航局 1 +x:1 +惊羡 1 +x:1 +保质保量 1 +x:1 +保荐 1 +x:1 +尤物 1 +x:1 +婚龄 1 +x:1 +销售 1 +x:1 +娄底市 1 +x:1 +水汪汪 1 +x:1 +值得一提 1 +x:1 +咸兴市 1 +x:1 +瓦楞子 1 +x:1 +体质 1 +x:1 +小米 1 +x:1 +职系 1 +x:1 +暗中摸索 1 +x:1 +效能 1 +x:1 +国难当头 1 +x:1 +灾难日 1 +x:1 +庭 22 +x:22 +集团 1 +x:1 +编目 1 +x:1 +倒车镜 1 +x:1 +质量法 1 +x:1 +身陷 1 +x:1 +高邑县 1 +x:1 +山泉水 1 +x:1 +判若 1 +x:1 +调查权 1 +x:1 +恨死 1 +x:1 +外财 1 +x:1 +汩汩淙淙 1 +x:1 +转向灯 1 +x:1 +调查村 1 +x:1 +样本股 1 +x:1 +权当 1 +x:1 +供电系统 1 +x:1 +穷寇 1 +x:1 +鼠标 1 +x:1 +院里 1 +x:1 +训练车 1 +x:1 +穷富 1 +x:1 +宜人 1 +x:1 +彬 31 +x:31 +介绍 1 +x:1 +利生队 1 +x:1 +烙画 1 +x:1 +嗲味儿 1 +x:1 +月球车 1 +x:1 +出人意表 1 +x:1 +科技亭 1 +x:1 +咸水鸭 1 +x:1 +瓜园 1 +x:1 +利润表 1 +x:1 +迁入地 1 +x:1 +踏雪 1 +x:1 +死活 1 +x:1 +袖珍 1 +x:1 +摸摸索索 1 +x:1 +网页 1 +x:1 +劲态 1 +x:1 +缗 1 +x:1 +火箭队 1 +x:1 +机票 1 +x:1 +燮 4 +x:4 +烙痕 1 +x:1 +粗厚 1 +x:1 +夜帐 1 +x:1 +囊中 1 +x:1 +大兵团 1 +x:1 +稠密 1 +x:1 +锡剧 1 +x:1 +彩礼钱 1 +x:1 +压缩 1 +x:1 +聒耳 1 +x:1 +平底鞋 1 +x:1 +毁长城者 1 +x:1 +扶贫县 1 +x:1 +固氮酶 1 +x:1 +狂呼 1 +x:1 +科技书 1 +x:1 +张目 1 +x:1 +安详 1 +x:1 +死海 1 +x:1 +琐闻 1 +x:1 +天坛路 1 +x:1 +凶杀片 1 +x:1 +特大号 1 +x:1 +书院 1 +x:1 +检查院 1 +x:1 +卷尺 1 +x:1 +狂吟 1 +x:1 +联合派 1 +x:1 +滢 1 +x:1 +狂吠 1 +x:1 +耕牛 1 +x:1 +小粉 1 +x:1 +二流 1 +x:1 +十指关 1 +x:1 +舷外 1 +x:1 +赵元任 1 +x:1 +表墒 1 +x:1 +惊天动地 1 +x:1 +炮长 1 +x:1 +功不可没 1 +x:1 +市场经济 1 +x:1 +民友联 1 +x:1 +旋转乾坤 1 +x:1 +北界城 1 +x:1 +晾台 1 +x:1 +三角村 1 +x:1 +劣弧 1 +x:1 +啤酒瓶 1 +x:1 +归谬法 1 +x:1 +发电厂 1 +x:1 +吃现成饭 1 +x:1 +治罪 1 +x:1 +配殿 1 +x:1 +澡 4 +x:4 +预置 1 +x:1 +角落处 1 +x:1 +三角板 1 +x:1 +玻璃板 1 +x:1 +备齐 1 +x:1 +可欣赏性 1 +x:1 +羽毛 1 +x:1 +北务乡 1 +x:1 +引介 1 +x:1 +错开 1 +x:1 +商务客 1 +x:1 +春合厂 1 +x:1 +玻璃杯 1 +x:1 +贫矿 1 +x:1 +樟蚕 1 +x:1 +值守 1 +x:1 +航空业者 1 +x:1 +教长 1 +x:1 +刚构 1 +x:1 +土质 1 +x:1 +栅极 1 +x:1 +二滩 1 +x:1 +刚果 1 +x:1 +红十字会 1 +x:1 +权属 1 +x:1 +菘菜 1 +x:1 +雕刻家 1 +x:1 +大嗓门 1 +x:1 +四 2873 +x:2873 +照片儿 1 +x:1 +合理率 1 +x:1 +姚山乡 1 +x:1 +果木林 1 +x:1 +减势 1 +x:1 +情潮 1 +x:1 +时间性 1 +x:1 +跳虫 1 +x:1 +寸草不生 1 +x:1 +季节工 1 +x:1 +死滞 1 +x:1 +减租 1 +x:1 +配比 1 +x:1 +肯基亚克 1 +x:1 +慢跑 1 +x:1 +足球迷 1 +x:1 +考勤机 1 +x:1 +穿刺 1 +x:1 +马利布 1 +x:1 +玻璃柜 1 +x:1 +挤满 1 +x:1 +外来货 1 +x:1 +各谋其政 1 +x:1 +电讯局 1 +x:1 +颗粒 1 +x:1 +心甘情愿 1 +x:1 +县市级 1 +x:1 +庆典性 1 +x:1 +安装 1 +x:1 +扬扬自得 1 +x:1 +改名换姓 1 +x:1 +所剩无几 1 +x:1 +阅览室 1 +x:1 +好在 1 +x:1 +百草 1 +x:1 +生物学 1 +x:1 +蓄念 1 +x:1 +气门心 1 +x:1 +金钱观 1 +x:1 +石磨盘 1 +x:1 +黑板刷 1 +x:1 +摇头 1 +x:1 +慢走 1 +x:1 +大要案 1 +x:1 +好为人师 1 +x:1 +闯关夺隘 1 +x:1 +孤石 1 +x:1 +东北腔 1 +x:1 +软组织 1 +x:1 +安文镇 1 +x:1 +县政协 1 +x:1 +大丰港 1 +x:1 +牟罗兹 1 +x:1 +煞白 1 +x:1 +保育 1 +x:1 +简单化 1 +x:1 +三角架 1 +x:1 +人心惟危 1 +x:1 +三角枫 1 +x:1 +读书社 1 +x:1 +洋菜 1 +x:1 +盗窃犯 1 +x:1 +校校 1 +x:1 +色氨酸 1 +x:1 +它 4146 +x:4146 +急慢性 1 +x:1 +出风头 1 +x:1 +凉水 1 +x:1 +贴膏 1 +x:1 +其间 1 +x:1 +校样 1 +x:1 +解析几何 1 +x:1 +引信 1 +x:1 +校格 1 +x:1 +障碍物 1 +x:1 +平底锅 1 +x:1 +谢 544 +x:544 +安西 1 +x:1 +滴壶 1 +x:1 +蒙特利尔 1 +x:1 +航模 1 +x:1 +王鸽 1 +x:1 +训练费 1 +x:1 +通畅 1 +x:1 +堂姐妹 1 +x:1 +书钉 1 +x:1 +重工业 1 +x:1 +医风 1 +x:1 +旱粮 1 +x:1 +枪眼 1 +x:1 +职级 1 +x:1 +层 427 +x:427 +核基地 1 +x:1 +症 24 +x:24 +综合化 1 +x:1 +百花 1 +x:1 +力避通常 1 +x:1 +赵体 1 +x:1 +旦荣 1 +x:1 +西充县 1 +x:1 +腔 39 +x:39 +马德里 1 +x:1 +谦让 1 +x:1 +复杂化 1 +x:1 +钢尺 1 +x:1 +探险者 1 +x:1 +潜水员 1 +x:1 +固有 1 +x:1 +座子 1 +x:1 +平均数 1 +x:1 +减磅 1 +x:1 +肌麻痹 1 +x:1 +官逼民反 1 +x:1 +扬抑取舍 1 +x:1 +兴 354 +x:354 +灌云 1 +x:1 +夜尿症 1 +x:1 +弗罗拉市 1 +x:1 +祝酒歌 1 +x:1 +骏马 1 +x:1 +为富不仁 1 +x:1 +操心费 1 +x:1 +皆 185 +x:185 +养活 1 +x:1 +百色 1 +x:1 +残历碑 1 +x:1 +可有可无 1 +x:1 +农学会 1 +x:1 +洪水位 1 +x:1 +马銮湾 1 +x:1 +祯 1 +x:1 +非道德化 1 +x:1 +内引外联 1 +x:1 +空中楼阁 1 +x:1 +粒子流 1 +x:1 +纵长 1 +x:1 +个别生 1 +x:1 +灭亡 1 +x:1 +欢歌 1 +x:1 +小组 1 +x:1 +位尊 1 +x:1 +阱 1 +x:1 +镶嵌画 1 +x:1 +小结 1 +x:1 +欢欣 1 +x:1 +缘分 1 +x:1 +动物区 1 +x:1 +郊 7 +x:7 +裁量 1 +x:1 +顽童 1 +x:1 +招工桌 1 +x:1 +百般 1 +x:1 +小纺 1 +x:1 +中毒者 1 +x:1 +库仑计 1 +x:1 +位居 1 +x:1 +贫瘠 1 +x:1 +峒中 1 +x:1 +恭维 1 +x:1 +达标率 1 +x:1 +小可怜儿 1 +x:1 +山崩地裂 1 +x:1 +劲扬 1 +x:1 +灌丛 1 +x:1 +阴险毒辣 1 +x:1 +打场 1 +x:1 +达喀尔港 1 +x:1 +出来 1 +x:1 +缉毒 1 +x:1 +星期三 1 +x:1 +仙人洞 1 +x:1 +摒除 1 +x:1 +只用 1 +x:1 +佛光山寺 1 +x:1 +吸纳 1 +x:1 +画路 1 +x:1 +电热型 1 +x:1 +编者按 1 +x:1 +脚注 1 +x:1 +轻诺寡信 1 +x:1 +案例库 1 +x:1 +葡萄球菌 1 +x:1 +随想曲 1 +x:1 +昭陵 1 +x:1 +堆肥 1 +x:1 +丁烷 1 +x:1 +谈 1395 +x:1395 +吸 57 +x:57 +自然性 1 +x:1 +奥运 1 +x:1 +作物区 1 +x:1 +一推了之 1 +x:1 +人物奖 1 +x:1 +五六时 1 +x:1 +善男信女 1 +x:1 +睹奥 1 +x:1 +第三纪 1 +x:1 +儿童文学 1 +x:1 +方针论 1 +x:1 +肥乡县 1 +x:1 +花鼓舞 1 +x:1 +知 338 +x:338 +挣开 1 +x:1 +崞县 1 +x:1 +打坐 1 +x:1 +牡丹乡 1 +x:1 +爆绽 1 +x:1 +文粹 1 +x:1 +瞻望 1 +x:1 +有勇无谋 1 +x:1 +柳林村 1 +x:1 +接触面 1 +x:1 +野种 1 +x:1 +廿 1 +x:1 +海潮坝 1 +x:1 +肚量 1 +x:1 +洋鬼子 1 +x:1 +算命热 1 +x:1 +星期二 1 +x:1 +保不定 1 +x:1 +星期五 1 +x:1 +打垮 1 +x:1 +招商会 1 +x:1 +牡丹亭 1 +x:1 +辩论赛 1 +x:1 +轮机兵 1 +x:1 +在商明政 1 +x:1 +一字千金 1 +x:1 +芬 11 +x:11 +昭雪 1 +x:1 +评析性 1 +x:1 +挥写 1 +x:1 +万年县 1 +x:1 +代跋 1 +x:1 +酒囊饭袋 1 +x:1 +碧绿 1 +x:1 +所指 1 +x:1 +语义 1 +x:1 +遗臭万年 1 +x:1 +乙酰胆碱 1 +x:1 +嚣闹 1 +x:1 +窜逃 1 +x:1 +脚气 1 +x:1 +涨跌幅 1 +x:1 +画质 1 +x:1 +律政 1 +x:1 +引文 1 +x:1 +菌草业 1 +x:1 +领导班子 1 +x:1 +浓烟 1 +x:1 +打埝 1 +x:1 +飞针走线 1 +x:1 +雪粒 1 +x:1 +似懂非懂 1 +x:1 +浓烈 1 +x:1 +说胡话 1 +x:1 +星形 1 +x:1 +淫秽 1 +x:1 +师父 1 +x:1 +粘合剂 1 +x:1 +缪 62 +x:62 +目前 1 +x:1 +大题小做 1 +x:1 +爬犁 1 +x:1 +喷灯 1 +x:1 +闲居 1 +x:1 +租售率 1 +x:1 +蛔虫 1 +x:1 +极大化值 1 +x:1 +黄红颜鸟 1 +x:1 +茶商 1 +x:1 +自甘落后 1 +x:1 +大理石 1 +x:1 +种瓜得瓜 1 +x:1 +喷灌 1 +x:1 +壮健 1 +x:1 +外科性 1 +x:1 +丈夫 1 +x:1 +伴 83 +x:83 +障碍壁 1 +x:1 +星座 1 +x:1 +猝不及防 1 +x:1 +特警队 1 +x:1 +据说 1 +x:1 +信托局 1 +x:1 +临 111 +x:111 +蛟龙得水 1 +x:1 +嗓音 1 +x:1 +一等奖 1 +x:1 +禁忌 1 +x:1 +亲情 1 +x:1 +暗中斗黑 1 +x:1 +索韦托 1 +x:1 +变法 1 +x:1 +尖团音 1 +x:1 +感遇之恩 1 +x:1 +鞋跟 1 +x:1 +非分之想 1 +x:1 +会见厅 1 +x:1 +草坪坡 1 +x:1 +自得其乐 1 +x:1 +灶 27 +x:27 +受难 1 +x:1 +抵御 1 +x:1 +银沙湾 1 +x:1 +装袋 1 +x:1 +厂际 1 +x:1 +兽药厂 1 +x:1 +受降 1 +x:1 +外商会 1 +x:1 +馆庆 1 +x:1 +柴草 1 +x:1 +倡 7 +x:7 +如钗折股 1 +x:1 +通讯集 1 +x:1 +除掉 1 +x:1 +塑料套 1 +x:1 +台资 1 +x:1 +大中学校 1 +x:1 +说话声 1 +x:1 +众生相 1 +x:1 +车管所 1 +x:1 +圣水 1 +x:1 +学生司 1 +x:1 +国粹主义 1 +x:1 +画谱 1 +x:1 +人大代表 1 +x:1 +装装 1 +x:1 +江堤 1 +x:1 +上进心 1 +x:1 +目力 1 +x:1 +母音 1 +x:1 +头等 1 +x:1 +路过者 1 +x:1 +将头 1 +x:1 +南湖渠 1 +x:1 +年表 1 +x:1 +姑 5 +x:5 +右安门 1 +x:1 +大气候 1 +x:1 +头筹 1 +x:1 +机器油 1 +x:1 +低龄 1 +x:1 +二等奖 1 +x:1 +正常 1 +x:1 +异烟肼 1 +x:1 +杂货店 1 +x:1 +嗔怪 1 +x:1 +受阻 1 +x:1 +电热器 1 +x:1 +中科研 1 +x:1 +目光 1 +x:1 +那天 1 +x:1 +赋性 1 +x:1 +黑森州 1 +x:1 +在岗 1 +x:1 +那大 1 +x:1 +攫取 1 +x:1 +卖窗 1 +x:1 +扩能 1 +x:1 +洛美市 1 +x:1 +牵挂 1 +x:1 +橡塑 1 +x:1 +嚣 1 +x:1 +节次 1 +x:1 +全身性 1 +x:1 +线描 1 +x:1 +敞亮 1 +x:1 +候鸟型 1 +x:1 +见死不救 1 +x:1 +早早儿 1 +x:1 +柴胡 1 +x:1 +诈骗罪 1 +x:1 +霄壤之别 1 +x:1 +欧洲队 1 +x:1 +借欠款 1 +x:1 +文纛 1 +x:1 +供销社 1 +x:1 +项项 1 +x:1 +恕其所短 1 +x:1 +铁道 1 +x:1 +闲弃 1 +x:1 +除恶 1 +x:1 +田亩 1 +x:1 +急救室 1 +x:1 +舍去 1 +x:1 +改选 1 +x:1 +延庆县 1 +x:1 +玩具柜 1 +x:1 +篱笆墙 1 +x:1 +好书奖 1 +x:1 +种子粮 1 +x:1 +栖身 1 +x:1 +臭 33 +x:33 +举国上下 1 +x:1 +怨气 1 +x:1 +国合 1 +x:1 +胜利者 1 +x:1 +宝珠 1 +x:1 +诊察费 1 +x:1 +坚称 1 +x:1 +车棚 1 +x:1 +塘马村 1 +x:1 +只身一人 1 +x:1 +封闭型 1 +x:1 +可鄙 1 +x:1 +画轴 1 +x:1 +民法典 1 +x:1 +曼俄村 1 +x:1 +劝业 1 +x:1 +小咬 1 +x:1 +岔 2 +x:2 +中重型 1 +x:1 +闲心 1 +x:1 +抚养权 1 +x:1 +南阳镇 1 +x:1 +幼兔 1 +x:1 +录相机 1 +x:1 +装订 1 +x:1 +虚伪性 1 +x:1 +目击 1 +x:1 +奥赛 1 +x:1 +五六月 1 +x:1 +三氯甲烷 1 +x:1 +母钟 1 +x:1 +群体 1 +x:1 +牵掣 1 +x:1 +赵州 1 +x:1 +立项权 1 +x:1 +黑豆 1 +x:1 +短缺点 1 +x:1 +明火区 1 +x:1 +坦白从宽 1 +x:1 +加农炮 1 +x:1 +出新 1 +x:1 +中山狼 1 +x:1 +江 4006 +x:4006 +连 1090 +x:1090 +势所必至 1 +x:1 +松果体 1 +x:1 +建施 1 +x:1 +认领 1 +x:1 +货郎担 1 +x:1 +群众 1 +x:1 +挥发 1 +x:1 +旗忠村 1 +x:1 +亩均 1 +x:1 +公墓 1 +x:1 +慕田峪村 1 +x:1 +梯坎 1 +x:1 +寸步难行 1 +x:1 +致命伤 1 +x:1 +摇尾乞怜 1 +x:1 +股级 1 +x:1 +中空 1 +x:1 +膜拜 1 +x:1 +团十三大 1 +x:1 +结婚照 1 +x:1 +顾村镇 1 +x:1 +漂洋过海 1 +x:1 +打听 1 +x:1 +漕河泾 1 +x:1 +统计员 1 +x:1 +焦糊状 1 +x:1 +贵溪市 1 +x:1 +记名 1 +x:1 +宛田 1 +x:1 +三统一包 1 +x:1 +出摊 1 +x:1 +单晶河 1 +x:1 +斯 83 +x:83 +真名实姓 1 +x:1 +仙人渡 1 +x:1 +塘堰 1 +x:1 +蜂箱 1 +x:1 +硬脂 1 +x:1 +纳尔乡 1 +x:1 +打的费 1 +x:1 +广种薄收 1 +x:1 +华章锦绣 1 +x:1 +喜庆 1 +x:1 +嗓门 1 +x:1 +同期性 1 +x:1 +进口权 1 +x:1 +自知者 1 +x:1 +唐庄镇 1 +x:1 +涤荡 1 +x:1 +无头告示 1 +x:1 +支柱性 1 +x:1 +凉山州 1 +x:1 +地震波 1 +x:1 +飞白 1 +x:1 +友爱 1 +x:1 +普 14 +x:14 +老鼠会 1 +x:1 +牵扯 1 +x:1 +碳氢 1 +x:1 +两性人 1 +x:1 +高官贵爵 1 +x:1 +梯地 1 +x:1 +澄明 1 +x:1 +凶信 1 +x:1 +飘缈 1 +x:1 +售完 1 +x:1 +挥动 1 +x:1 +勤谨 1 +x:1 +莲花县 1 +x:1 +属下 1 +x:1 +喜幛 1 +x:1 +留守处 1 +x:1 +实物量 1 +x:1 +险象 1 +x:1 +依顺 1 +x:1 +乐器 1 +x:1 +过街桥 1 +x:1 +玠 5 +x:5 +小算盘 1 +x:1 +桃红 1 +x:1 +荣成市 1 +x:1 +应时 1 +x:1 +对答 1 +x:1 +乐滋滋 1 +x:1 +处暑 1 +x:1 +切中肯綮 1 +x:1 +亮闪闪 1 +x:1 +市场课 1 +x:1 +丫头 1 +x:1 +舍利 1 +x:1 +领先权 1 +x:1 +红三连 1 +x:1 +青年湖 1 +x:1 +惠西 1 +x:1 +何乐之有 1 +x:1 +坚硬 1 +x:1 +欧体 1 +x:1 +嗤 1 +x:1 +荫 11 +x:11 +轻重工业 1 +x:1 +窄带 1 +x:1 +打响 1 +x:1 +击节而歌 1 +x:1 +岂能 1 +x:1 +宝物 1 +x:1 +泸县 1 +x:1 +隋代 1 +x:1 +坚美 1 +x:1 +熊岳镇 1 +x:1 +祥禽瑞兽 1 +x:1 +胡扯 1 +x:1 +银箔衬 1 +x:1 +蘑菇云 1 +x:1 +名人赛 1 +x:1 +扩股 1 +x:1 +南潮村 1 +x:1 +薏米 1 +x:1 +查缴 1 +x:1 +仙乐 1 +x:1 +恒山 1 +x:1 +星宿 1 +x:1 +画角 1 +x:1 +多如牛毛 1 +x:1 +玻璃体 1 +x:1 +啭鸣 1 +x:1 +仙乡 1 +x:1 +装货 1 +x:1 +化学部 1 +x:1 +险诈 1 +x:1 +催缴 1 +x:1 +抉剔爬梳 1 +x:1 +四月份 1 +x:1 +忆旧 1 +x:1 +卫冕者 1 +x:1 +与世长辞 1 +x:1 +打包 1 +x:1 +赛马 1 +x:1 +抵抗力 1 +x:1 +节流 1 +x:1 +固习 1 +x:1 +打印 1 +x:1 +妻离子散 1 +x:1 +雄伟 1 +x:1 +倏然 1 +x:1 +亲族 1 +x:1 +记协 1 +x:1 +氟嗪酸 1 +x:1 +阴私 1 +x:1 +年轻力壮 1 +x:1 +主人翁 1 +x:1 +实物券式 1 +x:1 +爆竹 1 +x:1 +炫耀 1 +x:1 +头绳 1 +x:1 +非同一般 1 +x:1 +仙丹 1 +x:1 +急行军 1 +x:1 +头绪 1 +x:1 +娑罗双树 1 +x:1 +陪都 1 +x:1 +目地 1 +x:1 +虹吸现象 1 +x:1 +公子 1 +x:1 +排球赛 1 +x:1 +百家饭 1 +x:1 +抒情畅怀 1 +x:1 +饰品 1 +x:1 +尽义务 1 +x:1 +溜 24 +x:24 +官吏 1 +x:1 +亲政 1 +x:1 +札 5 +x:5 +番椒 1 +x:1 +战幔 1 +x:1 +大门口 1 +x:1 +遍尝 1 +x:1 +顽匪 1 +x:1 +举目可见 1 +x:1 +邮电所 1 +x:1 +矿工图 1 +x:1 +畜牧场 1 +x:1 +黄钟大吕 1 +x:1 +记取 1 +x:1 +煜 3 +x:3 +奶品 1 +x:1 +简陋 1 +x:1 +桥殿飞虹 1 +x:1 +飞燕 1 +x:1 +星子 1 +x:1 +从而 1 +x:1 +大西洋 1 +x:1 +边防队 1 +x:1 +沃尔特湖 1 +x:1 +莲蓬头 1 +x:1 +防污 1 +x:1 +出掌 1 +x:1 +记号 1 +x:1 +纲举目张 1 +x:1 +擅自 1 +x:1 +打发 1 +x:1 +平乐县 1 +x:1 +统舱 1 +x:1 +药歌 1 +x:1 +泰 146 +x:146 +仙人 1 +x:1 +办刊者 1 +x:1 +排放口 1 +x:1 +紫砂壶 1 +x:1 +改革 1 +x:1 +八大关 1 +x:1 +省情 1 +x:1 +文科 1 +x:1 +飞瀑 1 +x:1 +文秘 1 +x:1 +哺乳动物 1 +x:1 +宣示 1 +x:1 +头羊 1 +x:1 +莴笋 1 +x:1 +伤害案 1 +x:1 +文秀 1 +x:1 +惊惊慌慌 1 +x:1 +文种 1 +x:1 +新鲜期 1 +x:1 +居高临下 1 +x:1 +推销员 1 +x:1 +寂寥 1 +x:1 +纠集 1 +x:1 +烤炉 1 +x:1 +那布 1 +x:1 +助审员 1 +x:1 +赋有 1 +x:1 +节水 1 +x:1 +渭南市 1 +x:1 +白沙县 1 +x:1 +女犯 1 +x:1 +假门假事 1 +x:1 +西风带 1 +x:1 +打分 1 +x:1 +瞎扯 1 +x:1 +舷梯 1 +x:1 +烤烤 1 +x:1 +因公殉职 1 +x:1 +湖阳市 1 +x:1 +铁青 1 +x:1 +战平 1 +x:1 +悔之晚矣 1 +x:1 +省悟 1 +x:1 +那年 1 +x:1 +祸国殃民 1 +x:1 +宝瓶 1 +x:1 +南营镇 1 +x:1 +肥东县 1 +x:1 +自然数 1 +x:1 +经纪人 1 +x:1 +那幅 1 +x:1 +卷烟厂 1 +x:1 +烤烟 1 +x:1 +厅房 1 +x:1 +雄丽 1 +x:1 +出战 1 +x:1 +脱氮菌 1 +x:1 +和平区 1 +x:1 +鱼片 1 +x:1 +主动脉 1 +x:1 +注意 1 +x:1 +记功 1 +x:1 +机要局 1 +x:1 +打劫 1 +x:1 +襁褓 1 +x:1 +打动 1 +x:1 +舍命 1 +x:1 +和平北路 1 +x:1 +周长 1 +x:1 +不了了之 1 +x:1 +犬吠里 1 +x:1 +引子 1 +x:1 +只不过 1 +x:1 +出血点 1 +x:1 +丹阳县 1 +x:1 +快快乐乐 1 +x:1 +埃斯特角 1 +x:1 +瞎抓 1 +x:1 +节油 1 +x:1 +西陡岭村 1 +x:1 +烤火 1 +x:1 +星移斗转 1 +x:1 +家庭妇女 1 +x:1 +经纪业 1 +x:1 +百年树人 1 +x:1 +仙供 1 +x:1 +简约主义 1 +x:1 +宣称 1 +x:1 +案例学 1 +x:1 +须 292 +x:292 +发育期 1 +x:1 +云云 1 +x:1 +出血热 1 +x:1 +饮水 1 +x:1 +柬 132 +x:132 +宏道镇 1 +x:1 +诗评家 1 +x:1 +头罩 1 +x:1 +躲躲闪闪 1 +x:1 +显赫一时 1 +x:1 +血仇 1 +x:1 +私房钱 1 +x:1 +画说 1 +x:1 +受重 1 +x:1 +踌躇满志 1 +x:1 +马拉维 1 +x:1 +浆汁 1 +x:1 +杂技节 1 +x:1 +熊河村 1 +x:1 +坐垫 1 +x:1 +画语 1 +x:1 +深耕细作 1 +x:1 +检察官 1 +x:1 +赛项 1 +x:1 +遇阻 1 +x:1 +桃符 1 +x:1 +文竹 1 +x:1 +丁目 1 +x:1 +说梦话 1 +x:1 +地区行 1 +x:1 +文童 1 +x:1 +玉镯 1 +x:1 +西共体 1 +x:1 +传动轮 1 +x:1 +文章 1 +x:1 +熟石灰 1 +x:1 +沃尔特河 1 +x:1 +中吨位 1 +x:1 +山晕 1 +x:1 +木背 1 +x:1 +省掉 1 +x:1 +画论 1 +x:1 +了不相涉 1 +x:1 +粘土砖 1 +x:1 +残兵败将 1 +x:1 +迷惑不解 1 +x:1 +更高一筹 1 +x:1 +常家庄 1 +x:1 +打入 1 +x:1 +昭通 1 +x:1 +喜宴 1 +x:1 +夜班 1 +x:1 +宝石 1 +x:1 +水中捞月 1 +x:1 +宅基地 1 +x:1 +学风 1 +x:1 +血亲 1 +x:1 +沧江 1 +x:1 +重灾区 1 +x:1 +大众化 1 +x:1 +险要 1 +x:1 +沉降 1 +x:1 +隐秘 1 +x:1 +遇险 1 +x:1 +释怀慰情 1 +x:1 +囡囡 1 +x:1 +喜字 1 +x:1 +多余者 1 +x:1 +中拇指 1 +x:1 +批发部 1 +x:1 +铁钉 1 +x:1 +观看席 1 +x:1 +河北团 1 +x:1 +铁钎 1 +x:1 +诽谤 1 +x:1 +庙会 1 +x:1 +无所畏惧 1 +x:1 +用地观 1 +x:1 +东弗兰德 1 +x:1 +赛风 1 +x:1 +下弦月 1 +x:1 +亲朋 1 +x:1 +大半生 1 +x:1 +粲然 1 +x:1 +爆破 1 +x:1 +遍布 1 +x:1 +撑篙 1 +x:1 +遇难 1 +x:1 +敌舰 1 +x:1 +警笛声 1 +x:1 +午饭 1 +x:1 +亲本 1 +x:1 +巴儿狗 1 +x:1 +打击 1 +x:1 +午餐 1 +x:1 +操切 1 +x:1 +偏 473 +x:473 +铁匠铺 1 +x:1 +夏管 1 +x:1 +因小失大 1 +x:1 +各有所爱 1 +x:1 +统考 1 +x:1 +装运 1 +x:1 +血丝 1 +x:1 +中晚唐 1 +x:1 +钝顶 1 +x:1 +文稿 1 +x:1 +放生 1 +x:1 +村委会 1 +x:1 +松节油 1 +x:1 +苛责 1 +x:1 +铁铲 1 +x:1 +因特网节 1 +x:1 +万古留芳 1 +x:1 +低频 1 +x:1 +纠错 1 +x:1 +糟践 1 +x:1 +无法可循 1 +x:1 +铁链 1 +x:1 +铁锁 1 +x:1 +白眼珠 1 +x:1 +出息 1 +x:1 +铁锅 1 +x:1 +铁锈 1 +x:1 +灯塔工 1 +x:1 +摄食 1 +x:1 +磕磕绊绊 1 +x:1 +腿骨 1 +x:1 +铁锚 1 +x:1 +少小离家 1 +x:1 +铁锤 1 +x:1 +吉首市 1 +x:1 +沉陨 1 +x:1 +打倒 1 +x:1 +抵押品 1 +x:1 +肤皮潦草 1 +x:1 +浓眉 1 +x:1 +断层 1 +x:1 +铁锹 1 +x:1 +山木 1 +x:1 +主产县 1 +x:1 +披衣 1 +x:1 +山村 1 +x:1 +轻车简从 1 +x:1 +绶带 1 +x:1 +浆洗 1 +x:1 +自然村 1 +x:1 +改锥 1 +x:1 +界 48 +x:48 +拦截者 1 +x:1 +铁镐 1 +x:1 +宝盆 1 +x:1 +蒜瓣儿 1 +x:1 +工作法 1 +x:1 +兵城 1 +x:1 +年幼无知 1 +x:1 +七七事变 1 +x:1 +省报 1 +x:1 +非骨干 1 +x:1 +木槌 1 +x:1 +改错 1 +x:1 +铁镰 1 +x:1 +洲镇 1 +x:1 +膨体纱 1 +x:1 +柴薪 1 +x:1 +文管 1 +x:1 +人事部门 1 +x:1 +劳模 1 +x:1 +打假 1 +x:1 +山林 1 +x:1 +通讯部 1 +x:1 +缮写 1 +x:1 +师辈 1 +x:1 +昭金 1 +x:1 +被分解数 1 +x:1 +晕头晕脑 1 +x:1 +亲昵 1 +x:1 +山架 1 +x:1 +催粮 1 +x:1 +脚步 1 +x:1 +方程式 1 +x:1 +左右中 1 +x:1 +榻榻米 1 +x:1 +辰 2 +x:2 +主产区 1 +x:1 +双氧水 1 +x:1 +功惠 1 +x:1 +擂 6 +x:6 +有法可循 1 +x:1 +飞狐 1 +x:1 +猕猴 1 +x:1 +司书 1 +x:1 +喜娘 1 +x:1 +理性主义 1 +x:1 +营造尺 1 +x:1 +财产法 1 +x:1 +淀底 1 +x:1 +形黯魂销 1 +x:1 +段落 1 +x:1 +审计法 1 +x:1 +浆液 1 +x:1 +铢 55 +x:55 +伴游 1 +x:1 +铁门 1 +x:1 +产业群 1 +x:1 +延长线 1 +x:1 +燃烧费 1 +x:1 +挑大梁 1 +x:1 +亏损面 1 +x:1 +男生 1 +x:1 +铁闸 1 +x:1 +茶制品 1 +x:1 +名人腔 1 +x:1 +男童 1 +x:1 +母鸡 1 +x:1 +跳伞 1 +x:1 +攻击力 1 +x:1 +符号 1 +x:1 +亏损额 1 +x:1 +丹阳市 1 +x:1 +喜嗜 1 +x:1 +此项 1 +x:1 +变文 1 +x:1 +预算内外 1 +x:1 +龙井 1 +x:1 +链条式 1 +x:1 +师者 1 +x:1 +无籽西瓜 1 +x:1 +行文 1 +x:1 +伞罩 1 +x:1 +浸剂 1 +x:1 +可受性 1 +x:1 +凤仙花 1 +x:1 +电教室 1 +x:1 +回传 1 +x:1 +卖点 1 +x:1 +变新 1 +x:1 +搬迁户 1 +x:1 +经学院 1 +x:1 +代用品 1 +x:1 +女装展 1 +x:1 +举举手 1 +x:1 +记录 1 +x:1 +钢轨 1 +x:1 +售假 1 +x:1 +馆址 1 +x:1 +始创 1 +x:1 +山桃 1 +x:1 +回位 1 +x:1 +偏瘫症 1 +x:1 +自行车界 1 +x:1 +讲台 1 +x:1 +深水炸弹 1 +x:1 +交界线 1 +x:1 +塘南 1 +x:1 +劳改 1 +x:1 +壮夫 1 +x:1 +翥 17 +x:17 +四海为家 1 +x:1 +名人脸 1 +x:1 +铁马 1 +x:1 +攻守同盟 1 +x:1 +壮大 1 +x:1 +银闪闪 1 +x:1 +吸盘 1 +x:1 +发展观 1 +x:1 +出演 1 +x:1 +外痔 1 +x:1 +梅开四喜 1 +x:1 +疗养 1 +x:1 +嗽叭声 1 +x:1 +开化县 1 +x:1 +烁烁 1 +x:1 +记得 1 +x:1 +宏恩 1 +x:1 +怨曲 1 +x:1 +一炮打响 1 +x:1 +缉捕 1 +x:1 +山梁 1 +x:1 +唾沫 1 +x:1 +山梅 1 +x:1 +拦路人 1 +x:1 +民法学 1 +x:1 +电热式 1 +x:1 +牛市 1 +x:1 +鱼苗 1 +x:1 +平面化 1 +x:1 +铁骨 1 +x:1 +一而再 1 +x:1 +阴电 1 +x:1 +养尊处优 1 +x:1 +五加 1 +x:1 +译文 1 +x:1 +同盟者 1 +x:1 +平射炮 1 +x:1 +步调一致 1 +x:1 +何乐不为 1 +x:1 +里约 1 +x:1 +双峰驼 1 +x:1 +号 1227 +x:1227 +技物政 1 +x:1 +变故 1 +x:1 +排沙洞 1 +x:1 +文理 1 +x:1 +后事 1 +x:1 +记忆 1 +x:1 +头版 1 +x:1 +均量 1 +x:1 +前话 1 +x:1 +渗入 1 +x:1 +限电器 1 +x:1 +那双 1 +x:1 +落伍者 1 +x:1 +枣岭乡 1 +x:1 +石油大臣 1 +x:1 +垃圾 1 +x:1 +晚婚率 1 +x:1 +回信 1 +x:1 +变数 1 +x:1 +中风 1 +x:1 +母鼠 1 +x:1 +上场门 1 +x:1 +均速 1 +x:1 +男篮 1 +x:1 +沿江路 1 +x:1 +碧眼 1 +x:1 +零售价 1 +x:1 +家前屋后 1 +x:1 +建设乡 1 +x:1 +拟声词 1 +x:1 +婆家人 1 +x:1 +果仁 1 +x:1 +浸印 1 +x:1 +可复性 1 +x:1 +缉拿 1 +x:1 +干事长 1 +x:1 +弄巧成拙 1 +x:1 +引咎辞职 1 +x:1 +文莱队 1 +x:1 +颐老院 1 +x:1 +士多啤梨 1 +x:1 +颐养 1 +x:1 +陈列室 1 +x:1 +协会 1 +x:1 +科学主义 1 +x:1 +出港 1 +x:1 +粉丝 1 +x:1 +菇 6 +x:6 +打平 1 +x:1 +统辖 1 +x:1 +忠诚度 1 +x:1 +无论是 1 +x:1 +感染性 1 +x:1 +元/亩 1 +x:1 +山楂 1 +x:1 +出游 1 +x:1 +血流成河 1 +x:1 +小型 1 +x:1 +七里岗村 1 +x:1 +调皮 1 +x:1 +星图 1 +x:1 +好处费 1 +x:1 +公审 1 +x:1 +安国市 1 +x:1 +回乡 1 +x:1 +击 34 +x:34 +星团 1 +x:1 +家庭者 1 +x:1 +唾液 1 +x:1 +选择点 1 +x:1 +抓起 1 +x:1 +监管人 1 +x:1 +回事 1 +x:1 +册谱 1 +x:1 +撞见 1 +x:1 +低音 1 +x:1 +承德市 1 +x:1 +堡 1 +x:1 +所得税率 1 +x:1 +壮士 1 +x:1 +肆无忌惮 1 +x:1 +终盘 1 +x:1 +坐以待毙 1 +x:1 +吃吃 1 +x:1 +果乡 1 +x:1 +九霄云外 1 +x:1 +母龟 1 +x:1 +三撑峡 1 +x:1 +海鹞式 1 +x:1 +弹药箱 1 +x:1 +三育人 1 +x:1 +一季度 1 +x:1 +图片社 1 +x:1 +摄录机 1 +x:1 +果业 1 +x:1 +盗版商 1 +x:1 +宏愿 1 +x:1 +澄江 1 +x:1 +信箱 1 +x:1 +纹样 1 +x:1 +辩学 1 +x:1 +真经 1 +x:1 +文电 1 +x:1 +非进口 1 +x:1 +生火 1 +x:1 +蜂糕 1 +x:1 +不可开交 1 +x:1 +扯平 1 +x:1 +雪 401 +x:401 +坚牢 1 +x:1 +小五金店 1 +x:1 +售出 1 +x:1 +业内人士 1 +x:1 +各级 1 +x:1 +亏损饭 1 +x:1 +指骨 1 +x:1 +零售业 1 +x:1 +闲坐 1 +x:1 +封闭式 1 +x:1 +枉 13 +x:13 +发展论 1 +x:1 +群贤毕至 1 +x:1 +那儿 1 +x:1 +勇挑 1 +x:1 +除根 1 +x:1 +出浴 1 +x:1 +回黄转绿 1 +x:1 +出海 1 +x:1 +凸现 1 +x:1 +聚氨酯 1 +x:1 +赋格 1 +x:1 +胜利街 1 +x:1 +文盲 1 +x:1 +鼎足之势 1 +x:1 +午间 1 +x:1 +午门 1 +x:1 +女装 1 +x:1 +樊尧村 1 +x:1 +重振 1 +x:1 +三色堇 1 +x:1 +师范学院 1 +x:1 +饮水思源 1 +x:1 +崇尚 1 +x:1 +辩士 1 +x:1 +仪态万方 1 +x:1 +劳服 1 +x:1 +出活 1 +x:1 +形诸 1 +x:1 +区分符 1 +x:1 +亚足联 1 +x:1 +女王 1 +x:1 +九里山 1 +x:1 +珍品展 1 +x:1 +出洋 1 +x:1 +概莫能外 1 +x:1 +邈邈 1 +x:1 +绵里藏针 1 +x:1 +宇宙速度 1 +x:1 +高高的 1 +x:1 +淀区 1 +x:1 +小洞式 1 +x:1 +鱼胶 1 +x:1 +钮祜禄 1 +x:1 +风天 1 +x:1 +彩画 1 +x:1 +渗化 1 +x:1 +低产田 1 +x:1 +堂鼓 1 +x:1 +东大梁村 1 +x:1 +周口店 1 +x:1 +幼仔 1 +x:1 +页码 1 +x:1 +学委会 1 +x:1 +文登 1 +x:1 +掩目捕雀 1 +x:1 +代理费 1 +x:1 +监事 1 +x:1 +调研部 1 +x:1 +各组 1 +x:1 +硅橡胶 1 +x:1 +顿顿 1 +x:1 +渔乡 1 +x:1 +广而告之 1 +x:1 +正月初十 1 +x:1 +喷管 1 +x:1 +遗作 1 +x:1 +舒心 1 +x:1 +河口乡 1 +x:1 +海沟 1 +x:1 +制表 1 +x:1 +碧瓦 1 +x:1 +赤瓜礁 1 +x:1 +校貌 1 +x:1 +壮实 1 +x:1 +折算 1 +x:1 +付 178 +x:178 +打工 1 +x:1 +人物史 1 +x:1 +梯度 1 +x:1 +鱼肚 1 +x:1 +山地组 1 +x:1 +发情期 1 +x:1 +在所不惜 1 +x:1 +改频 1 +x:1 +绸 3 +x:3 +最好 1 +x:1 +急救包 1 +x:1 +鱼肉 1 +x:1 +廉洁风 1 +x:1 +逼上梁山 1 +x:1 +外销量 1 +x:1 +严于律己 1 +x:1 +半道 1 +x:1 +交换机 1 +x:1 +翻两番 1 +x:1 +马家坡村 1 +x:1 +鱼腮 1 +x:1 +师范 1 +x:1 +肝 20 +x:20 +馆名 1 +x:1 +制品 1 +x:1 +繁体字 1 +x:1 +幼体 1 +x:1 +鱼尾 1 +x:1 +顿首 1 +x:1 +琪 10 +x:10 +面条机 1 +x:1 +梯形 1 +x:1 +涯 10 +x:10 +墨法 1 +x:1 +乡下 1 +x:1 +车票款 1 +x:1 +谨慎 1 +x:1 +生产业 1 +x:1 +监理部 1 +x:1 +收雪车 1 +x:1 +帮扶户 1 +x:1 +庐峰 1 +x:1 +突突突 1 +x:1 +致残性 1 +x:1 +馆员 1 +x:1 +壮威 1 +x:1 +科尔特 1 +x:1 +选矿 1 +x:1 +常备军 1 +x:1 +煤耗 1 +x:1 +椰蓉 1 +x:1 +山歌 1 +x:1 +编者案 1 +x:1 +运动会 1 +x:1 +近现代化 1 +x:1 +遍及 1 +x:1 +肛门 1 +x:1 +出气 1 +x:1 +铁饼 1 +x:1 +变更 1 +x:1 +塑料厂 1 +x:1 +一年生 1 +x:1 +光合作用 1 +x:1 +近现代史 1 +x:1 +雪被 1 +x:1 +留党察看 1 +x:1 +办案费 1 +x:1 +忽忽不乐 1 +x:1 +变星 1 +x:1 +丙 3 +x:3 +小算盘儿 1 +x:1 +墨池 1 +x:1 +阴功 1 +x:1 +河沙堆 1 +x:1 +泗水河 1 +x:1 +四连版 1 +x:1 +等额选举 1 +x:1 +付账 1 +x:1 +防治 1 +x:1 +打岔 1 +x:1 +别有情趣 1 +x:1 +发电站 1 +x:1 +脚板 1 +x:1 +半部 1 +x:1 +敷衍了事 1 +x:1 +泄洪闸 1 +x:1 +墨汁 1 +x:1 +庐山 1 +x:1 +灰鲸鱼 1 +x:1 +节拍 1 +x:1 +格尔木 1 +x:1 +出没 1 +x:1 +德惠市 1 +x:1 +浦西 1 +x:1 +金银财宝 1 +x:1 +暖池区 1 +x:1 +脚本 1 +x:1 +阿雅克肖 1 +x:1 +关累镇 1 +x:1 +统购 1 +x:1 +领导人 1 +x:1 +腥气 1 +x:1 +山民 1 +x:1 +呆坐 1 +x:1 +大理站 1 +x:1 +开口杯 1 +x:1 +售后 1 +x:1 +鱼虾 1 +x:1 +乘兴而来 1 +x:1 +应时而变 1 +x:1 +有机染料 1 +x:1 +那场 1 +x:1 +塞军 1 +x:1 +相濡以沫 1 +x:1 +田东 1 +x:1 +建昌县 1 +x:1 +目录 1 +x:1 +铁鸟 1 +x:1 +研究员 1 +x:1 +从今 1 +x:1 +山水 1 +x:1 +昏沉沉 1 +x:1 +复隆镇 1 +x:1 +带工者 1 +x:1 +馆区 1 +x:1 +节支 1 +x:1 +怯头怯脑 1 +x:1 +头皮 1 +x:1 +名教授 1 +x:1 +多彩的 1 +x:1 +追光 1 +x:1 +诗碑廊 1 +x:1 +过街柳 1 +x:1 +抽风 1 +x:1 +缉查 1 +x:1 +竹园 1 +x:1 +圣水湖 1 +x:1 +卡丁车 1 +x:1 +党政工团 1 +x:1 +头盔 1 +x:1 +别针 1 +x:1 +除湿 1 +x:1 +经济法学 1 +x:1 +塘坝 1 +x:1 +超音速队 1 +x:1 +肚脐装 1 +x:1 +进口案 1 +x:1 +业余 1 +x:1 +集散地 1 +x:1 +芦沟桥 1 +x:1 +从事 1 +x:1 +己内酰胺 1 +x:1 +萨阿都 1 +x:1 +打字 1 +x:1 +里程 1 +x:1 +打孔 1 +x:1 +头目 1 +x:1 +做功 1 +x:1 +坂下村 1 +x:1 +户勤区 1 +x:1 +坨子 1 +x:1 +中条山 1 +x:1 +辂 3 +x:3 +多媒体化 1 +x:1 +绿洲学 1 +x:1 +里端 1 +x:1 +度假村 1 +x:1 +山沟 1 +x:1 +牵涉 1 +x:1 +盐霜 1 +x:1 +辙口 1 +x:1 +酿母菌 1 +x:1 +山河 1 +x:1 +飞禽 1 +x:1 +色拉油 1 +x:1 +榆林桥 1 +x:1 +壮工 1 +x:1 +山沿 1 +x:1 +国有化 1 +x:1 +公式化 1 +x:1 +用兵如神 1 +x:1 +马齿苋 1 +x:1 +文火 1 +x:1 +冒牌货 1 +x:1 +正屋 1 +x:1 +依存 1 +x:1 +翻译器 1 +x:1 +含沙量 1 +x:1 +从中 1 +x:1 +戎衣 1 +x:1 +从严 1 +x:1 +长驱直入 1 +x:1 +集流环 1 +x:1 +我辈 1 +x:1 +山泉 1 +x:1 +阻尼 1 +x:1 +进口棉 1 +x:1 +节日 1 +x:1 +感慨系之 1 +x:1 +从不 1 +x:1 +浏览 1 +x:1 +抵制 1 +x:1 +带兵人 1 +x:1 +空心砖 1 +x:1 +单科性 1 +x:1 +一则 1 +x:1 +平凉市 1 +x:1 +从业 1 +x:1 +分洪闸 1 +x:1 +枪响靶落 1 +x:1 +头癣 1 +x:1 +大特写 1 +x:1 +自个儿 1 +x:1 +行书 1 +x:1 +产业界 1 +x:1 +宏旨 1 +x:1 +赶下台 1 +x:1 +博茨瓦纳 1 +x:1 +山洞 1 +x:1 +锐 45 +x:45 +替身 1 +x:1 +侗 5 +x:5 +防渗墙 1 +x:1 +付讫 1 +x:1 +骥 13 +x:13 +油漆厂 1 +x:1 +小褂儿 1 +x:1 +形貌 1 +x:1 +贴剂 1 +x:1 +山洼 1 +x:1 +刻不容缓 1 +x:1 +强强联合 1 +x:1 +山洪 1 +x:1 +勤苦 1 +x:1 +毫米波 1 +x:1 +平面图 1 +x:1 +关系部 1 +x:1 +受骗 1 +x:1 +尖沙咀 1 +x:1 +委曲求全 1 +x:1 +遥不可及 1 +x:1 +腿部 1 +x:1 +劳总 1 +x:1 +李岗村 1 +x:1 +十进对数 1 +x:1 +宏文 1 +x:1 +商品化 1 +x:1 +钢瓶 1 +x:1 +蕻菜 1 +x:1 +照射率 1 +x:1 +子弟书 1 +x:1 +付诸 1 +x:1 +八大处 1 +x:1 +钩子 1 +x:1 +沈河区 1 +x:1 +例题 1 +x:1 +统计 1 +x:1 +唯名论 1 +x:1 +飞碟 1 +x:1 +变态 1 +x:1 +搦管恣肆 1 +x:1 +国有制 1 +x:1 +封闭墙 1 +x:1 +引来 1 +x:1 +各式各样 1 +x:1 +机要员 1 +x:1 +八大姨 1 +x:1 +钾肥厂 1 +x:1 +达科他州 1 +x:1 +无规律 1 +x:1 +倦鸟投林 1 +x:1 +激动不已 1 +x:1 +囹圄 1 +x:1 +搁置 1 +x:1 +叔母 1 +x:1 +山涧 1 +x:1 +盗走 1 +x:1 +组件 1 +x:1 +孜孜耕耘 1 +x:1 +飘然 1 +x:1 +碧玉 1 +x:1 +外电 1 +x:1 +形象 1 +x:1 +节操 1 +x:1 +圣雪绒队 1 +x:1 +浆果 1 +x:1 +雕饰 1 +x:1 +清心涤虑 1 +x:1 +乌审旗 1 +x:1 +编译程序 1 +x:1 +私有权 1 +x:1 +讲座式 1 +x:1 +油当量 1 +x:1 +漾濞 1 +x:1 +飕飕 1 +x:1 +和平宫 1 +x:1 +从优 1 +x:1 +不才 1 +x:1 +布朗运动 1 +x:1 +深入虎穴 1 +x:1 +画者 1 +x:1 +扎眼 1 +x:1 +盗贼 1 +x:1 +赛道 1 +x:1 +爆炒 1 +x:1 +别集 1 +x:1 +统裙 1 +x:1 +打头 1 +x:1 +怨恨 1 +x:1 +打夯 1 +x:1 +跏趺 1 +x:1 +关帝庙 1 +x:1 +泽宁根 1 +x:1 +康乾 1 +x:1 +节期 1 +x:1 +爱知县 1 +x:1 +排放处 1 +x:1 +木焦油 1 +x:1 +节本 1 +x:1 +退税率 1 +x:1 +操典 1 +x:1 +中心县 1 +x:1 +忘年情 1 +x:1 +羔羊 1 +x:1 +康乐 1 +x:1 +千分比 1 +x:1 +雨棚 1 +x:1 +潘溪渡 1 +x:1 +吸热 1 +x:1 +节材 1 +x:1 +见惯不惊 1 +x:1 +形迹 1 +x:1 +渔汛 1 +x:1 +交换所 1 +x:1 +学 1242 +x:1242 +山湾 1 +x:1 +栽培植物 1 +x:1 +翩 1 +x:1 +舍得 1 +x:1 +金枪鱼 1 +x:1 +吸烟 1 +x:1 +拍体 1 +x:1 +低速 1 +x:1 +抽验 1 +x:1 +堆积 1 +x:1 +闽 49 +x:49 +左云县 1 +x:1 +广为 1 +x:1 +生灵涂炭 1 +x:1 +壮心 1 +x:1 +运输日 1 +x:1 +含水云 1 +x:1 +斋饭 1 +x:1 +落英缤纷 1 +x:1 +志书 1 +x:1 +馆内 1 +x:1 +掌上舞 1 +x:1 +文牍 1 +x:1 +仙人掌 1 +x:1 +头球 1 +x:1 +壮志 1 +x:1 +抵偿 1 +x:1 +广东 1 +x:1 +陌生化 1 +x:1 +进村串户 1 +x:1 +脚扣 1 +x:1 +飞箭 1 +x:1 +益友 1 +x:1 +清心寡欲 1 +x:1 +山溪 1 +x:1 +文物 1 +x:1 +莫罗市 1 +x:1 +浓绿 1 +x:1 +单细胞 1 +x:1 +五原 1 +x:1 +软硬木 1 +x:1 +再版率 1 +x:1 +分崩离析 1 +x:1 +报关员 1 +x:1 +线路工 1 +x:1 +超然物外 1 +x:1 +望女成凰 1 +x:1 +项链 1 +x:1 +地质学家 1 +x:1 +绣像 1 +x:1 +赞歌 1 +x:1 +中长跑 1 +x:1 +堆放站 1 +x:1 +虚掩 1 +x:1 +落到实处 1 +x:1 +祁剧 1 +x:1 +抵债 1 +x:1 +变换 1 +x:1 +鸡毛 1 +x:1 +座谈会 1 +x:1 +志气 1 +x:1 +广义 1 +x:1 +冲翼艇 1 +x:1 +除法 1 +x:1 +邦交国 1 +x:1 +淡淡 1 +x:1 +煤城 1 +x:1 +后龛村 1 +x:1 +和平奖 1 +x:1 +清君侧 1 +x:1 +浓缩 1 +x:1 +指甲心儿 1 +x:1 +容态可掬 1 +x:1 +氮气 1 +x:1 +统观 1 +x:1 +梯子 1 +x:1 +青年报 1 +x:1 +头疼 1 +x:1 +僚 1 +x:1 +挥师 1 +x:1 +属国 1 +x:1 +行为 1 +x:1 +前无古人 1 +x:1 +俗尚 1 +x:1 +空域 1 +x:1 +产权法 1 +x:1 +贮水式 1 +x:1 +交流 1 +x:1 +科工贸 1 +x:1 +壮年 1 +x:1 +祁县 1 +x:1 +脚掌 1 +x:1 +受领 1 +x:1 +东丽区 1 +x:1 +筹借 1 +x:1 +党组会 1 +x:1 +灵活性 1 +x:1 +排水量 1 +x:1 +运动战 1 +x:1 +罗布大淖 1 +x:1 +出格 1 +x:1 +豺狼成性 1 +x:1 +隧 1 +x:1 +影视部 1 +x:1 +中外比 1 +x:1 +抗张强度 1 +x:1 +支系 1 +x:1 +硬账 1 +x:1 +硬货 1 +x:1 +符咒 1 +x:1 +出栏 1 +x:1 +殊死 1 +x:1 +宏构 1 +x:1 +猴皮筋儿 1 +x:1 +庞然 1 +x:1 +西坎里克 1 +x:1 +尼雅 1 +x:1 +人间相 1 +x:1 +环境日 1 +x:1 +赭黄色 1 +x:1 +走着瞧 1 +x:1 +惊慌失措 1 +x:1 +山潭 1 +x:1 +梨子树 1 +x:1 +文玩 1 +x:1 +墨梅 1 +x:1 +酿房 1 +x:1 +头生 1 +x:1 +油趸船 1 +x:1 +障子 1 +x:1 +产供销 1 +x:1 +衍生物 1 +x:1 +垂涎欲滴 1 +x:1 +鱼藤 1 +x:1 +遍地 1 +x:1 +厅棚 1 +x:1 +古义陵 1 +x:1 +变成 1 +x:1 +胜利路 1 +x:1 +撞过 1 +x:1 +破坏力 1 +x:1 +利国利民 1 +x:1 +穷追不舍 1 +x:1 +麦得克 1 +x:1 +利 270 +x:270 +勤者 1 +x:1 +巴马县 1 +x:1 +酿成 1 +x:1 +喜剧 1 +x:1 +乡科级 1 +x:1 +御笔 1 +x:1 +页 199 +x:199 +朗诵会 1 +x:1 +不成 1 +x:1 +叨登 1 +x:1 +代理行 1 +x:1 +严丝合缝 1 +x:1 +画船 1 +x:1 +武穴市 1 +x:1 +电老虎 1 +x:1 +画舫 1 +x:1 +劳技 1 +x:1 +喜忧参半 1 +x:1 +新诗史 1 +x:1 +田间管理 1 +x:1 +北孝义乡 1 +x:1 +行业 1 +x:1 +床榻 1 +x:1 +圣湖 1 +x:1 +户枢不蠹 1 +x:1 +符合 1 +x:1 +文献 1 +x:1 +除险 1 +x:1 +文法 1 +x:1 +四方脸 1 +x:1 +阄 1 +x:1 +改良 1 +x:1 +抵仗 1 +x:1 +群工 1 +x:1 +右下方 1 +x:1 +光通量 1 +x:1 +瞎眼 1 +x:1 +沉闷 1 +x:1 +方方面面 1 +x:1 +众议院 1 +x:1 +川马 1 +x:1 +香车宝马 1 +x:1 +敬请 1 +x:1 +炫 1 +x:1 +产业桥 1 +x:1 +阿科松博 1 +x:1 +催款 1 +x:1 +总汇 1 +x:1 +呵欠 1 +x:1 +贾 444 +x:444 +飘泊 1 +x:1 +新江路 1 +x:1 +兴奋剂 1 +x:1 +坚毅 1 +x:1 +小街乡 1 +x:1 +游泳界 1 +x:1 +社交圈 1 +x:1 +桐梓县 1 +x:1 +伊东市 1 +x:1 +肚脐 1 +x:1 +义责 1 +x:1 +商品业 1 +x:1 +羊倌 1 +x:1 +神秘性 1 +x:1 +查 297 +x:297 +心平气和 1 +x:1 +妞儿 1 +x:1 +生产商 1 +x:1 +文治 1 +x:1 +越挫越奋 1 +x:1 +抵京 1 +x:1 +擅长 1 +x:1 +劳累 1 +x:1 +邀功请赏 1 +x:1 +共产主义 1 +x:1 +山火 1 +x:1 +装饰 1 +x:1 +仿 27 +x:27 +球 608 +x:608 +绣花针 1 +x:1 +经商者 1 +x:1 +茂名 1 +x:1 +省界 1 +x:1 +接触眼镜 1 +x:1 +文汇 1 +x:1 +山窝地 1 +x:1 +摆阔 1 +x:1 +最低价 1 +x:1 +博得 1 +x:1 +省略 1 +x:1 +从前 1 +x:1 +支撑点 1 +x:1 +倘若 1 +x:1 +铁花 1 +x:1 +神巫 1 +x:1 +兴奋劲 1 +x:1 +山炮 1 +x:1 +校企 1 +x:1 +秆 2 +x:2 +十年浩劫 1 +x:1 +星体 1 +x:1 +旱害 1 +x:1 +大个子 1 +x:1 +叠印 1 +x:1 +飞旋 1 +x:1 +师风 1 +x:1 +回城 1 +x:1 +巴陵郡 1 +x:1 +拍击 1 +x:1 +清洁费 1 +x:1 +文水 1 +x:1 +汪塘 1 +x:1 +热火朝天 1 +x:1 +薯莨 1 +x:1 +反馈性 1 +x:1 +轰鸣声 1 +x:1 +积怨 1 +x:1 +果场 1 +x:1 +贝伦市 1 +x:1 +指针 1 +x:1 +毛兴村 1 +x:1 +获得 1 +x:1 +报告期 1 +x:1 +小账 1 +x:1 +从刑 1 +x:1 +于都 1 +x:1 +低轨 1 +x:1 +阴沟 1 +x:1 +叠加 1 +x:1 +压电效应 1 +x:1 +亲炙 1 +x:1 +财产税 1 +x:1 +预委会 1 +x:1 +挺举 1 +x:1 +换阅点 1 +x:1 +源源不断 1 +x:1 +贤台 1 +x:1 +妇女学 1 +x:1 +仙子 1 +x:1 +所得税款 1 +x:1 +亮氨酸 1 +x:1 +群峰 1 +x:1 +小集团 1 +x:1 +最低位 1 +x:1 +母蜂 1 +x:1 +墨盒 1 +x:1 +明水镇 1 +x:1 +影院 1 +x:1 +人类学系 1 +x:1 +赛车 1 +x:1 +山焦 1 +x:1 +广内 1 +x:1 +果园 1 +x:1 +馆中 1 +x:1 +究竟 1 +x:1 +敬而远之 1 +x:1 +龙城 1 +x:1 +组分 1 +x:1 +包间费 1 +x:1 +反切法 1 +x:1 +桃汛 1 +x:1 +竞放斗妍 1 +x:1 +拉网式 1 +x:1 +接济 1 +x:1 +桃江 1 +x:1 +光电效应 1 +x:1 +发展部 1 +x:1 +神秘感 1 +x:1 +学究气 1 +x:1 +梯次性 1 +x:1 +盖浇饭 1 +x:1 +组别 1 +x:1 +只说不做 1 +x:1 +世俗化 1 +x:1 +光顾 1 +x:1 +一路顺风 1 +x:1 +欧洲杯赛 1 +x:1 +群岛 1 +x:1 +均衡 1 +x:1 +恶 48 +x:48 +亲热 1 +x:1 +名教练 1 +x:1 +瓦斯灯 1 +x:1 +青年系 1 +x:1 +、 134293 +x:134293 +剪秋萝 1 +x:1 +慕田峪 1 +x:1 +音像店 1 +x:1 +写字 1 +x:1 +阿巴伊达 1 +x:1 +阴气 1 +x:1 +庙堂 1 +x:1 +悠悠 1 +x:1 +干丹省 1 +x:1 +累赘 1 +x:1 +飘洒 1 +x:1 +群山 1 +x:1 +文海 1 +x:1 +分组会 1 +x:1 +涨 48 +x:48 +群居 1 +x:1 +股民 1 +x:1 +女人岛 1 +x:1 +碧澄 1 +x:1 +飞播 1 +x:1 +厅直 1 +x:1 +孜孜 1 +x:1 +遁 3 +x:3 +小苏打 1 +x:1 +短视症 1 +x:1 +甩手掌柜 1 +x:1 +兵马俑 1 +x:1 +不象话 1 +x:1 +伊斯兰式 1 +x:1 +建校 1 +x:1 +语录 1 +x:1 +从医 1 +x:1 +可说是 1 +x:1 +知识卷 1 +x:1 +飘浮 1 +x:1 +回国 1 +x:1 +与众不同 1 +x:1 +上水井 1 +x:1 +文派 1 +x:1 +冒火 1 +x:1 +仙客 1 +x:1 +二十一年 1 +x:1 +银行部 1 +x:1 +威宁县 1 +x:1 +食茱萸 1 +x:1 +广元 1 +x:1 +从化 1 +x:1 +输出 1 +x:1 +着桩机 1 +x:1 +辽宁团 1 +x:1 +月牙湖 1 +x:1 +还施彼身 1 +x:1 +华俄 1 +x:1 +而 9891 +x:9891 +庙宇 1 +x:1 +段里 1 +x:1 +亲率 1 +x:1 +生产场 1 +x:1 +缉私 1 +x:1 +生产地 1 +x:1 +流觞曲水 1 +x:1 +出界 1 +x:1 +飞机 1 +x:1 +樟木板 1 +x:1 +译编 1 +x:1 +飘溢 1 +x:1 +迪化 1 +x:1 +弹片 1 +x:1 +只有 1 +x:1 +茶 139 +x:139 +麻山区 1 +x:1 +付钱 1 +x:1 +五年计划 1 +x:1 +高级中学 1 +x:1 +传染科 1 +x:1 +云头 1 +x:1 +参观记 1 +x:1 +云大 1 +x:1 +碧池 1 +x:1 +木桩 1 +x:1 +金鸡纳树 1 +x:1 +低谷 1 +x:1 +正电荷 1 +x:1 +低调 1 +x:1 +拍卖 1 +x:1 +西段乡 1 +x:1 +碳素 1 +x:1 +牡丹山 1 +x:1 +飞来 1 +x:1 +支撑物 1 +x:1 +满天飞 1 +x:1 +万马奔腾 1 +x:1 +中耳炎 1 +x:1 +打掩护 1 +x:1 +碧油 1 +x:1 +炫技式 1 +x:1 +果商 1 +x:1 +黄松峪乡 1 +x:1 +东营市 1 +x:1 +东里坟 1 +x:1 +中心会 1 +x:1 +接受函 1 +x:1 +音读 1 +x:1 +祁东 1 +x:1 +输入 1 +x:1 +编舞师 1 +x:1 +零售商 1 +x:1 +省督 1 +x:1 +生产型 1 +x:1 +灰 33 +x:33 +安然无恙 1 +x:1 +看护 1 +x:1 +飞架 1 +x:1 +飘渺 1 +x:1 +雄姿 1 +x:1 +濡染 1 +x:1 +名山大川 1 +x:1 +不胜枚举 1 +x:1 +吸气 1 +x:1 +男性 1 +x:1 +墨画 1 +x:1 +孤陋寡闻 1 +x:1 +在职员 1 +x:1 +祁义 1 +x:1 +仙境 1 +x:1 +碧波 1 +x:1 +电梯处 1 +x:1 +机绣 1 +x:1 +惠顾 1 +x:1 +范家梁村 1 +x:1 +岗底村 1 +x:1 +短小精悍 1 +x:1 +弟妹 1 +x:1 +随乡入乡 1 +x:1 +密码 1 +x:1 +麦饭石 1 +x:1 +二是二 1 +x:1 +既然如此 1 +x:1 +保卫局 1 +x:1 +麦尔登呢 1 +x:1 +钻心虫 1 +x:1 +肇事车 1 +x:1 +帅位 1 +x:1 +鱼饵 1 +x:1 +碧洲 1 +x:1 +达斡尔 1 +x:1 +福建省 1 +x:1 +陌生人 1 +x:1 +质询 1 +x:1 +监场 1 +x:1 +飙升 1 +x:1 +音阶 1 +x:1 +纪昌学射 1 +x:1 +棋类 1 +x:1 +只是 1 +x:1 +累进 1 +x:1 +莞籍 1 +x:1 +里数 1 +x:1 +果品 1 +x:1 +羊毛疔 1 +x:1 +广厦 1 +x:1 +里约州 1 +x:1 +浏阳 1 +x:1 +缀文 1 +x:1 +正言厉色 1 +x:1 +吸尘机 1 +x:1 +遮住 1 +x:1 +武陵区 1 +x:1 +疯 19 +x:19 +闲书 1 +x:1 +省直 1 +x:1 +结欠款 1 +x:1 +别说 1 +x:1 +山猫 1 +x:1 +看押 1 +x:1 +年发电量 1 +x:1 +低质 1 +x:1 +巫婆 1 +x:1 +山陡石峭 1 +x:1 +松溪县 1 +x:1 +藏 296 +x:296 +谢克尔 1 +x:1 +头槌 1 +x:1 +铁腕 1 +x:1 +眉高眼低 1 +x:1 +睫毛 1 +x:1 +低贱 1 +x:1 +勉勉强强 1 +x:1 +光复会 1 +x:1 +旅游区 1 +x:1 +碧浪 1 +x:1 +甘居中游 1 +x:1 +音节文字 1 +x:1 +回味 1 +x:1 +狗牯脑 1 +x:1 +上下联动 1 +x:1 +广发 1 +x:1 +诱因 1 +x:1 +精养育肥 1 +x:1 +从军 1 +x:1 +蕴含 1 +x:1 +快行道 1 +x:1 +交换网 1 +x:1 +铳伤 1 +x:1 +绣花鞋 1 +x:1 +赛跑 1 +x:1 +闸北区 1 +x:1 +大厦将倾 1 +x:1 +卷土重来 1 +x:1 +分离舱 1 +x:1 +柜组长 1 +x:1 +膜片 1 +x:1 +引导员 1 +x:1 +高桥镇 1 +x:1 +仙姑 1 +x:1 +桃源 1 +x:1 +雄壮 1 +x:1 +科利马 1 +x:1 +快译通队 1 +x:1 +重油 1 +x:1 +连丰村 1 +x:1 +秋老虎 1 +x:1 +新圩镇 1 +x:1 +擦眼而过 1 +x:1 +劳绩 1 +x:1 +医疗系 1 +x:1 +母树林 1 +x:1 +欧式 1 +x:1 +排水费 1 +x:1 +笑面虎 1 +x:1 +零售员 1 +x:1 +闲云 1 +x:1 +招商局 1 +x:1 +廉洁者 1 +x:1 +吸收光谱 1 +x:1 +英年早逝 1 +x:1 +生产国 1 +x:1 +恰帕斯 1 +x:1 +回响 1 +x:1 +洋浦港 1 +x:1 +知晓 1 +x:1 +怪里怪气 1 +x:1 +山珍 1 +x:1 +闲事 1 +x:1 +凯旋归来 1 +x:1 +头楼 1 +x:1 +五卅 1 +x:1 +广博 1 +x:1 +广南 1 +x:1 +闲人 1 +x:1 +首迎式 1 +x:1 +受让方 1 +x:1 +快餐盒 1 +x:1 +要不得 1 +x:1 +云影 1 +x:1 +劳神 1 +x:1 +番禺 1 +x:1 +散货轮 1 +x:1 +黑车 1 +x:1 +监管区 1 +x:1 +气壮如牛 1 +x:1 +彩旗猎猎 1 +x:1 +母舰 1 +x:1 +旋木雀 1 +x:1 +岛 180 +x:180 +亲疏 1 +x:1 +三塘湖 1 +x:1 +太行 1 +x:1 +空想家 1 +x:1 +申花队 1 +x:1 +扁率 1 +x:1 +写信人 1 +x:1 +里手 1 +x:1 +等价物 1 +x:1 +洑家村 1 +x:1 +胰蛋白酶 1 +x:1 +感人肺腑 1 +x:1 +治 503 +x:503 +专营 1 +x:1 +青史名垂 1 +x:1 +变种 1 +x:1 +叔父 1 +x:1 +回单 1 +x:1 +向钱看 1 +x:1 +青年科 1 +x:1 +农信联社 1 +x:1 +弹琴 1 +x:1 +回升 1 +x:1 +高能物理 1 +x:1 +出猎 1 +x:1 +遂平县 1 +x:1 +林业部长 1 +x:1 +那位 1 +x:1 +操之过急 1 +x:1 +表 147 +x:147 +乳虎 1 +x:1 +辗转 1 +x:1 +世界屋脊 1 +x:1 +墨玉 1 +x:1 +雄强 1 +x:1 +小姑 1 +x:1 +中三家镇 1 +x:1 +水电局 1 +x:1 +喂养量 1 +x:1 +钦差大臣 1 +x:1 +爱国人士 1 +x:1 +吕宋烟 1 +x:1 +建设史 1 +x:1 +离柳 1 +x:1 +被上诉人 1 +x:1 +职大 1 +x:1 +名护市 1 +x:1 +建设司 1 +x:1 +消渴病 1 +x:1 +栓 1 +x:1 +副职 1 +x:1 +何必当初 1 +x:1 +心悸 1 +x:1 +回历 1 +x:1 +文案 1 +x:1 +玉门 1 +x:1 +中路梆子 1 +x:1 +回去 1 +x:1 +小孙孙 1 +x:1 +景点费 1 +x:1 +旅游品 1 +x:1 +牟定县 1 +x:1 +亭亭玉立 1 +x:1 +眭 1 +x:1 +里拉 1 +x:1 +贯穿性 1 +x:1 +这会儿 1 +x:1 +药性气 1 +x:1 +涿县 1 +x:1 +酿祸 1 +x:1 +安华西里 1 +x:1 +如蚁附膻 1 +x:1 +监管司 1 +x:1 +撞针 1 +x:1 +名不符实 1 +x:1 +住读 1 +x:1 +股骨头 1 +x:1 +臂徽 1 +x:1 +盐湖 1 +x:1 +出现 1 +x:1 +成铁局 1 +x:1 +厂长 1 +x:1 +情深意长 1 +x:1 +半边 1 +x:1 +新安郡 1 +x:1 +跳台 1 +x:1 +果区 1 +x:1 +文核 1 +x:1 +忧伤 1 +x:1 +广告 1 +x:1 +建设厅 1 +x:1 +不甚起眼 1 +x:1 +学术部 1 +x:1 +棒儿香 1 +x:1 +上摊 1 +x:1 +防护堤 1 +x:1 +万户侯 1 +x:1 +生产值 1 +x:1 +桃树 1 +x:1 +粉剂 1 +x:1 +受苦 1 +x:1 +吸浆虫 1 +x:1 +出版 1 +x:1 +回到 1 +x:1 +只怕 1 +x:1 +鹿茸 1 +x:1 +拍合 1 +x:1 +译码 1 +x:1 +红安县 1 +x:1 +桃根 1 +x:1 +抒怀 1 +x:1 +左右岸 1 +x:1 +全始全终 1 +x:1 +画风 1 +x:1 +村支部 1 +x:1 +电影厂 1 +x:1 +雄师 1 +x:1 +电影厅 1 +x:1 +韵式 1 +x:1 +治学 1 +x:1 +发展链 1 +x:1 +球胆 1 +x:1 +千分点 1 +x:1 +习已为常 1 +x:1 +撞锁 1 +x:1 +借据 1 +x:1 +云顶岩 1 +x:1 +始发地 1 +x:1 +荤 6 +x:6 +另当别论 1 +x:1 +龙口 1 +x:1 +卖淫 1 +x:1 +母草 1 +x:1 +粉刷 1 +x:1 +阴森 1 +x:1 +欧姆 1 +x:1 +巫山 1 +x:1 +军事五项 1 +x:1 +咽喉炎 1 +x:1 +吸毒 1 +x:1 +吝啬 1 +x:1 +哀牢山系 1 +x:1 +征文栏 1 +x:1 +百家衣 1 +x:1 +低语 1 +x:1 +画页 1 +x:1 +虎背 1 +x:1 +二十八分 1 +x:1 +熘 1 +x:1 +出狱 1 +x:1 +男权 1 +x:1 +繁殖区 1 +x:1 +平行会 1 +x:1 +套近乎 1 +x:1 +组团 1 +x:1 +检修费 1 +x:1 +酵母片 1 +x:1 +介子 1 +x:1 +轻狂 1 +x:1 +洋教头 1 +x:1 +弹痕 1 +x:1 +黄刺玫 1 +x:1 +科研关 1 +x:1 +布拉格 1 +x:1 +元 9608 +x:9608 +引黄灌区 1 +x:1 +旅馆化 1 +x:1 +奶娘 1 +x:1 +湖田镇 1 +x:1 +劳碌 1 +x:1 +售奶亭 1 +x:1 +夹金山 1 +x:1 +说明文 1 +x:1 +巫峡 1 +x:1 +拍品 1 +x:1 +与民争利 1 +x:1 +手工艺品 1 +x:1 +龙卡 1 +x:1 +血崩 1 +x:1 +社情 1 +x:1 +抒情 1 +x:1 +外来工 1 +x:1 +茂兰 1 +x:1 +轱辘 1 +x:1 +猪娃 1 +x:1 +活该 1 +x:1 +丧家之犬 1 +x:1 +语境 1 +x:1 +监制 1 +x:1 +重新 1 +x:1 +大洋河 1 +x:1 +塑料件 1 +x:1 +宋集区 1 +x:1 +七色板 1 +x:1 +沈灶镇 1 +x:1 +午觉 1 +x:1 +侦察员 1 +x:1 +超高频 1 +x:1 +监利 1 +x:1 +怡养 1 +x:1 +译笔 1 +x:1 +头油 1 +x:1 +邦邦硬 1 +x:1 +一会儿 1 +x:1 +金齐园 1 +x:1 +获奖 1 +x:1 +电梯工 1 +x:1 +农牧厅 1 +x:1 +珠联璧合 1 +x:1 +电度表 1 +x:1 +代理量 1 +x:1 +痛改前非 1 +x:1 +阿通社 1 +x:1 +诱变 1 +x:1 +果农 1 +x:1 +济州道 1 +x:1 +摄要 1 +x:1 +超轻量 1 +x:1 +血库 1 +x:1 +滔天 1 +x:1 +莫不如 1 +x:1 +果决 1 +x:1 +云崖 1 +x:1 +果冻 1 +x:1 +售书 1 +x:1 +坪里 1 +x:1 +单线铁路 1 +x:1 +暖洋洋 1 +x:1 +碧桃 1 +x:1 +股比 1 +x:1 +过西镇 1 +x:1 +小行星 1 +x:1 +售予 1 +x:1 +旅游团 1 +x:1 +补课 1 +x:1 +野鼠 1 +x:1 +弥河镇 1 +x:1 +从命 1 +x:1 +退税款 1 +x:1 +焦渴 1 +x:1 +浆糊 1 +x:1 +丈人 1 +x:1 +段长 1 +x:1 +亲眷 1 +x:1 +唯有 1 +x:1 +亲眼 1 +x:1 +产权界 1 +x:1 +生产厂 1 +x:1 +画魂 1 +x:1 +半路 1 +x:1 +云巅 1 +x:1 +旨意 1 +x:1 +炮班 1 +x:1 +暗渡陈仓 1 +x:1 +见证者 1 +x:1 +体会 1 +x:1 +核查队 1 +x:1 +山盟 1 +x:1 +报摊儿 1 +x:1 +生产司 1 +x:1 +一去不返 1 +x:1 +每况愈下 1 +x:1 +人世间 1 +x:1 +跳出 1 +x:1 +座席 1 +x:1 +回击 1 +x:1 +回函 1 +x:1 +阿拉木图 1 +x:1 +果儿 1 +x:1 +鱼鲜 1 +x:1 +淘汰赛制 1 +x:1 +外高加索 1 +x:1 +修定 1 +x:1 +色粉 1 +x:1 +描眉画眼 1 +x:1 +托克逊县 1 +x:1 +预发 1 +x:1 +支脉河 1 +x:1 +售价 1 +x:1 +车斗 1 +x:1 +巫师 1 +x:1 +博士院 1 +x:1 +河口县 1 +x:1 +占优势 1 +x:1 +作 2621 +x:2621 +岳阳楼区 1 +x:1 +瀚 2 +x:2 +潭头镇 1 +x:1 +经院式 1 +x:1 +司乘人员 1 +x:1 +预备会 1 +x:1 +弹着 1 +x:1 +农网 1 +x:1 +星期天 1 +x:1 +木版 1 +x:1 +新鲜肉 1 +x:1 +云层 1 +x:1 +堂花 1 +x:1 +柴门 1 +x:1 +博尔西路 1 +x:1 +招议标 1 +x:1 +木化石 1 +x:1 +马龙 1 +x:1 +如狼似虎 1 +x:1 +欧安 1 +x:1 +矩尺 1 +x:1 +木牌 1 +x:1 +组合 1 +x:1 +摆列 1 +x:1 +涡旋 1 +x:1 +九九歌 1 +x:1 +黑龙港 1 +x:1 +旅游地 1 +x:1 +闽江口 1 +x:1 +捐助 1 +x:1 +青年站 1 +x:1 +男方 1 +x:1 +广域 1 +x:1 +增长量 1 +x:1 +辽宁厅 1 +x:1 +蓄滞洪区 1 +x:1 +摆制 1 +x:1 +劝导 1 +x:1 +龙凤 1 +x:1 +累计 1 +x:1 +反射线 1 +x:1 +切入口 1 +x:1 +秀发 1 +x:1 +飞扬 1 +x:1 +鸿雁 1 +x:1 +六七年 1 +x:1 +云峰 1 +x:1 +焚烧场 1 +x:1 +广场 1 +x:1 +瞎炮 1 +x:1 +犒劳 1 +x:1 +垒石弄 1 +x:1 +大洋洲 1 +x:1 +外汇局 1 +x:1 +匠心独运 1 +x:1 +结婚日 1 +x:1 +有利可图 1 +x:1 +统配 1 +x:1 +浓枯 1 +x:1 +锗 2 +x:2 +雄峙 1 +x:1 +骑士 1 +x:1 +节水型 1 +x:1 +受聘 1 +x:1 +供电量 1 +x:1 +节约 1 +x:1 +萨迦寺 1 +x:1 +鼓乐齐鸣 1 +x:1 +惊恐万状 1 +x:1 +说瞎话 1 +x:1 +堆积如山 1 +x:1 +商贾如云 1 +x:1 +飞抵 1 +x:1 +从商 1 +x:1 +纵火犯 1 +x:1 +文武 1 +x:1 +夏熟作物 1 +x:1 +群婚 1 +x:1 +雄峻 1 +x:1 +生产力 1 +x:1 +男男女女 1 +x:1 +纠葛 1 +x:1 +懒虫 1 +x:1 +五指山区 1 +x:1 +爱护 1 +x:1 +洋布 1 +x:1 +分秒必争 1 +x:1 +卦辞 1 +x:1 +受限 1 +x:1 +话务室 1 +x:1 +用武之地 1 +x:1 +择校生 1 +x:1 +越野跑 1 +x:1 +海豚泳 1 +x:1 +异形字 1 +x:1 +领导力 1 +x:1 +瞠目结舌 1 +x:1 +云岭 1 +x:1 +牛皮癣 1 +x:1 +加压釜 1 +x:1 +自花传粉 1 +x:1 +监发 1 +x:1 +格鲁派 1 +x:1 +足贴 1 +x:1 +眼馋 1 +x:1 +付酬 1 +x:1 +宇田 1 +x:1 +骑墙 1 +x:1 +孕穗 1 +x:1 +年检费 1 +x:1 +哗然 1 +x:1 +七机部 1 +x:1 +劝学 1 +x:1 +遍体 1 +x:1 +两证一书 1 +x:1 +坎坷多舛 1 +x:1 +宏编 1 +x:1 +轻 190 +x:190 +黔东南州 1 +x:1 +价费字 1 +x:1 +整饬一新 1 +x:1 +输导 1 +x:1 +飞洒 1 +x:1 +纠误 1 +x:1 +不得其详 1 +x:1 +农林水牧 1 +x:1 +逆命题 1 +x:1 +麦角胺 1 +x:1 +尖端放电 1 +x:1 +少白头 1 +x:1 +打伤 1 +x:1 +逝水 1 +x:1 +直来直去 1 +x:1 +打伞 1 +x:1 +赔付 1 +x:1 +和平乡 1 +x:1 +离业者 1 +x:1 +赋税 1 +x:1 +讶然于 1 +x:1 +话务员 1 +x:1 +泰山队 1 +x:1 +装配 1 +x:1 +必 248 +x:248 +调兵遣将 1 +x:1 +孟州市 1 +x:1 +回归 1 +x:1 +福建籍 1 +x:1 +输家 1 +x:1 +电梯厂 1 +x:1 +小家子气 1 +x:1 +验讫章 1 +x:1 +淫糜 1 +x:1 +一息尚存 1 +x:1 +奇缘 1 +x:1 +牛角尖 1 +x:1 +记住 1 +x:1 +十八日 1 +x:1 +定语 1 +x:1 +棋缘 1 +x:1 +金钟乡 1 +x:1 +乱砍滥伐 1 +x:1 +耿北村 1 +x:1 +中联部 1 +x:1 +旧历年 1 +x:1 +滑冰场 1 +x:1 +九里乡 1 +x:1 +打住 1 +x:1 +受辱 1 +x:1 +丹心 1 +x:1 +幼小 1 +x:1 +和盘托出 1 +x:1 +生活资料 1 +x:1 +迢迢地 1 +x:1 +改变 1 +x:1 +钢琴曲 1 +x:1 +老花镜 1 +x:1 +耦耕乡 1 +x:1 +坚持 1 +x:1 +文摘 1 +x:1 +人莫予毒 1 +x:1 +抽象 1 +x:1 +同位语 1 +x:1 +崇仁 1 +x:1 +匝 2 +x:2 +平民者 1 +x:1 +谣 3 +x:3 +崇仰 1 +x:1 +各有所求 1 +x:1 +响晴 1 +x:1 +强弱 1 +x:1 +飞涨 1 +x:1 +基性岩 1 +x:1 +多度津 1 +x:1 +坚挺 1 +x:1 +鸳鸯戏水 1 +x:1 +七扭八歪 1 +x:1 +挽 36 +x:36 +现代性 1 +x:1 +评价制 1 +x:1 +源目录 1 +x:1 +洪雅县 1 +x:1 +云县 1 +x:1 +股数 1 +x:1 +知情不举 1 +x:1 +雄厚 1 +x:1 +穗 24 +x:24 +拉耧 1 +x:1 +报纸 1 +x:1 +子坝 1 +x:1 +回忆 1 +x:1 +劝告 1 +x:1 +牡丹园 1 +x:1 +孕畜 1 +x:1 +透气 1 +x:1 +敬赠 1 +x:1 +哈丰角 1 +x:1 +楼群 1 +x:1 +代厂长 1 +x:1 +共 2278 +x:2278 +雄县 1 +x:1 +师部 1 +x:1 +工艺论典 1 +x:1 +抽调 1 +x:1 +血债 1 +x:1 +分站赛 1 +x:1 +龙年 1 +x:1 +叛逆 1 +x:1 +余波 1 +x:1 +墨绿 1 +x:1 +惊蛇入草 1 +x:1 +里潭 1 +x:1 +红小兵 1 +x:1 +回帖 1 +x:1 +血泪史 1 +x:1 +回师 1 +x:1 +仙人球 1 +x:1 +打中 1 +x:1 +少年老成 1 +x:1 +记下 1 +x:1 +庞杂 1 +x:1 +港胞 1 +x:1 +十年九旱 1 +x:1 +塔山乡 1 +x:1 +公正化 1 +x:1 +摘自 1 +x:1 +扶残济困 1 +x:1 +聊以卒岁 1 +x:1 +简讯 1 +x:1 +打下 1 +x:1 +鲜为人知 1 +x:1 +简记 1 +x:1 +别致 1 +x:1 +不尽然 1 +x:1 +农牧区 1 +x:1 +衡水市 1 +x:1 +简评 1 +x:1 +节灌 1 +x:1 +龙心 1 +x:1 +全局性 1 +x:1 +散货船 1 +x:1 +从容 1 +x:1 +兴趣班 1 +x:1 +打油诗 1 +x:1 +从宽 1 +x:1 +倾斜性 1 +x:1 +增上寺 1 +x:1 +党政军警 1 +x:1 +督察组 1 +x:1 +险隘 1 +x:1 +蝎子草 1 +x:1 +砚台 1 +x:1 +康复 1 +x:1 +四方街 1 +x:1 +生产局 1 +x:1 +零售店 1 +x:1 +宣教 1 +x:1 +输出方 1 +x:1 +桶 176 +x:176 +令人叹服 1 +x:1 +昕 9 +x:9 +双桥区 1 +x:1 +吃里爬外 1 +x:1 +由此 1 +x:1 +只求 1 +x:1 +偷逃税 1 +x:1 +坚戈 1 +x:1 +现代感 1 +x:1 +震撼力 1 +x:1 +炎黄 1 +x:1 +血光 1 +x:1 +省籍 1 +x:1 +文教 1 +x:1 +虎头崖 1 +x:1 +摸爬滚打 1 +x:1 +自助餐 1 +x:1 +广大 1 +x:1 +记事 1 +x:1 +亟待 1 +x:1 +红桥区 1 +x:1 +青中年 1 +x:1 +尤他 1 +x:1 +果干 1 +x:1 +吸服 1 +x:1 +数以万计 1 +x:1 +打井 1 +x:1 +邮电网 1 +x:1 +诬陷罪 1 +x:1 +旅游委 1 +x:1 +岔流 1 +x:1 +呵护 1 +x:1 +操神 1 +x:1 +璞 17 +x:17 +页岩石 1 +x:1 +节点 1 +x:1 +出菇率 1 +x:1 +铁证 1 +x:1 +险阻 1 +x:1 +素什锦 1 +x:1 +改订 1 +x:1 +节烈 1 +x:1 +再生棉 1 +x:1 +帮扶点 1 +x:1 +飞泉 1 +x:1 +回廊 1 +x:1 +出线 1 +x:1 +监工 1 +x:1 +记仇 1 +x:1 +师里 1 +x:1 +龙归 1 +x:1 +出纳 1 +x:1 +台风儿 1 +x:1 +飘散 1 +x:1 +厅级 1 +x:1 +大娄山脉 1 +x:1 +打仗 1 +x:1 +黑衣 1 +x:1 +濡沐 1 +x:1 +放火 1 +x:1 +外汇券 1 +x:1 +曾随 1 +x:1 +禁吸戒毒 1 +x:1 +雄劲 1 +x:1 +溧水县 1 +x:1 +幼年 1 +x:1 +杨芳乡 1 +x:1 +凶器 1 +x:1 +脚盆 1 +x:1 +果川 1 +x:1 +古今合璧 1 +x:1 +樱草 1 +x:1 +良法 1 +x:1 +同勉会 1 +x:1 +阴极 1 +x:1 +龙岩 1 +x:1 +蓄洪 1 +x:1 +证照牌 1 +x:1 +卖报 1 +x:1 +车管科 1 +x:1 +防火墙 1 +x:1 +扮演者 1 +x:1 +犯戒 1 +x:1 +飞漩 1 +x:1 +信儿 1 +x:1 +公元前 1 +x:1 +雄兵 1 +x:1 +雄关 1 +x:1 +铁血 1 +x:1 +圆盘耙 1 +x:1 +桃李 1 +x:1 +堆高 1 +x:1 +阴柔 1 +x:1 +雷达站 1 +x:1 +云儿 1 +x:1 +发现者 1 +x:1 +摆开 1 +x:1 +莲下镇 1 +x:1 +摆弄 1 +x:1 +低落 1 +x:1 +红2师 1 +x:1 +通讯费 1 +x:1 +书画院 1 +x:1 +抽身 1 +x:1 +摆式 1 +x:1 +正经事儿 1 +x:1 +印量 1 +x:1 +批判文 1 +x:1 +桃条 1 +x:1 +种闯田 1 +x:1 +皮短裤 1 +x:1 +不经意 1 +x:1 +拍子 1 +x:1 +士敏土 1 +x:1 +彪炳史册 1 +x:1 +飘曳 1 +x:1 +春雷声 1 +x:1 +幼师 1 +x:1 +诡计多端 1 +x:1 +亲笔 1 +x:1 +袖手旁观 1 +x:1 +山窝 1 +x:1 +股本 1 +x:1 +画面 1 +x:1 +献策 1 +x:1 +现代戏 1 +x:1 +桃果 1 +x:1 +高视阔步 1 +x:1 +桃林 1 +x:1 +自有 1 +x:1 +大个儿 1 +x:1 +虎头帽 1 +x:1 +村容村貌 1 +x:1 +同位角 1 +x:1 +改装 1 +x:1 +航天部 1 +x:1 +脚癣 1 +x:1 +二机部 1 +x:1 +信用化 1 +x:1 +钴 6 +x:6 +龙尾 1 +x:1 +文景 1 +x:1 +铀矿床 1 +x:1 +发卡量 1 +x:1 +华雷斯 1 +x:1 +气急败坏 1 +x:1 +塘桥镇 1 +x:1 +男校 1 +x:1 +浦项 1 +x:1 +灵长目 1 +x:1 +八宝菜 1 +x:1 +多闻者 1 +x:1 +文昌 1 +x:1 +敬业勤业 1 +x:1 +瑟 2 +x:2 +道士 1 +x:1 +股权 1 +x:1 +探亲假 1 +x:1 +项背 1 +x:1 +不同凡响 1 +x:1 +竹器 1 +x:1 +感染率 1 +x:1 +保卫员 1 +x:1 +改良主义 1 +x:1 +乘势而上 1 +x:1 +招蜂引蝶 1 +x:1 +受贿 1 +x:1 +云冈 1 +x:1 +科幻 1 +x:1 +不分彼此 1 +x:1 +卡宾枪 1 +x:1 +香椿林 1 +x:1 +简要 1 +x:1 +四荒 1 +x:1 +捐建 1 +x:1 +卖掉 1 +x:1 +吊 32 +x:32 +群团 1 +x:1 +番禺市 1 +x:1 +秉烛夜读 1 +x:1 +夏至草 1 +x:1 +里海 1 +x:1 +唯心论 1 +x:1 +中等 1 +x:1 +别出机杼 1 +x:1 +可以 1 +x:1 +邝 3 +x:3 +亩产 1 +x:1 +血口 1 +x:1 +摆平 1 +x:1 +希望赛 1 +x:1 +省市级 1 +x:1 +爬梯 1 +x:1 +雄健 1 +x:1 +仰天大笑 1 +x:1 +承销商 1 +x:1 +建设局 1 +x:1 +画集 1 +x:1 +广安 1 +x:1 +飞渡 1 +x:1 +地利人和 1 +x:1 +应变成 1 +x:1 +嫁 44 +x:44 +粉尘 1 +x:1 +点击数 1 +x:1 +血压 1 +x:1 +物品 1 +x:1 +摆布 1 +x:1 +龙川 1 +x:1 +绢纺厂 1 +x:1 +旋转翼 1 +x:1 +第三方 1 +x:1 +株式会社 1 +x:1 +省级 1 +x:1 +阴曹 1 +x:1 +退热药 1 +x:1 +力透纸背 1 +x:1 +太翁 1 +x:1 +变相 1 +x:1 +墨粉 1 +x:1 +权贵 1 +x:1 +顿觉 1 +x:1 +雪梨 1 +x:1 +雏形 1 +x:1 +学员队 1 +x:1 +铁西 1 +x:1 +阶级斗争 1 +x:1 +盗魁 1 +x:1 +防城市 1 +x:1 +辉煌夺目 1 +x:1 +空间局 1 +x:1 +不求甚解 1 +x:1 +季风性 1 +x:1 +老老实实 1 +x:1 +无时无刻 1 +x:1 +吸收 1 +x:1 +飞溅 1 +x:1 +杂食店 1 +x:1 +精疲力竭 1 +x:1 +四月八 1 +x:1 +罗里罗唆 1 +x:1 +鼓乐队 1 +x:1 +信函 1 +x:1 +戴戴 1 +x:1 +改观 1 +x:1 +致意 1 +x:1 +寄理于情 1 +x:1 +血印 1 +x:1 +火炉坪乡 1 +x:1 +水电厂 1 +x:1 +张家港市 1 +x:1 +示威者 1 +x:1 +大峡谷 1 +x:1 +挠骨 1 +x:1 +拦水坝 1 +x:1 +小品式 1 +x:1 +壶关县 1 +x:1 +霍然 1 +x:1 +编写者 1 +x:1 +血细胞 1 +x:1 +从头 1 +x:1 +樱花 1 +x:1 +指指 1 +x:1 +超常规 1 +x:1 +凶险 1 +x:1 +四脚蛇 1 +x:1 +康宁 1 +x:1 +团体操 1 +x:1 +中策 1 +x:1 +引为鉴戒 1 +x:1 +子孙万代 1 +x:1 +坐立不安 1 +x:1 +文本 1 +x:1 +康定 1 +x:1 +鹦哥 1 +x:1 +绿林起义 1 +x:1 +庶务 1 +x:1 +强颜欢笑 1 +x:1 +赞誉声 1 +x:1 +坚果 1 +x:1 +五颜六色 1 +x:1 +赛艇 1 +x:1 +舔 3 +x:3 +康山 1 +x:1 +蝇虎 1 +x:1 +申报单 1 +x:1 +广岛 1 +x:1 +优惠酬宾 1 +x:1 +旅游局 1 +x:1 +例规 1 +x:1 +生产处 1 +x:1 +战前 1 +x:1 +矛盾 1 +x:1 +节电 1 +x:1 +牵累 1 +x:1 +旅游展 1 +x:1 +珍重 1 +x:1 +二十八宿 1 +x:1 +毅然决然 1 +x:1 +银杯赛 1 +x:1 +扭力天平 1 +x:1 +废气 1 +x:1 +脚炉 1 +x:1 +西服呢 1 +x:1 +果实 1 +x:1 +重温 1 +x:1 +云片糕 1 +x:1 +弹簧 1 +x:1 +出笼 1 +x:1 +墨管 1 +x:1 +含水层 1 +x:1 +节略 1 +x:1 +黑袍 1 +x:1 +受训 1 +x:1 +喷洒 1 +x:1 +软骨病 1 +x:1 +进水闸 1 +x:1 +生产奖 1 +x:1 +雅座 1 +x:1 +专营店 1 +x:1 +鱼雷 1 +x:1 +零下 1 +x:1 +廊开府 1 +x:1 +果子 1 +x:1 +面结型 1 +x:1 +购房置业 1 +x:1 +简体字 1 +x:1 +回守 1 +x:1 +惠阳 1 +x:1 +岳南区 1 +x:1 +外皮 1 +x:1 +寡廉鲜耻 1 +x:1 +指数制 1 +x:1 +蒜薹 1 +x:1 +美大司 1 +x:1 +侧柏 1 +x:1 +失业率 1 +x:1 +节疤 1 +x:1 +脚灯 1 +x:1 +腿脚 1 +x:1 +薄弱者 1 +x:1 +毕肖 1 +x:1 +指挥 1 +x:1 +回家 1 +x:1 +获取 1 +x:1 +仙国 1 +x:1 +抽血 1 +x:1 +一病不起 1 +x:1 +维和旅 1 +x:1 +钓鱼税 1 +x:1 +制裁 1 +x:1 +瞌睡 1 +x:1 +脏器 1 +x:1 +文思 1 +x:1 +头晕 1 +x:1 +心惊 1 +x:1 +福井县 1 +x:1 +达西村 1 +x:1 +从师 1 +x:1 +喷涂 1 +x:1 +诱奸 1 +x:1 +山系 1 +x:1 +喷涌 1 +x:1 +墨笔 1 +x:1 +文学史 1 +x:1 +群儒 1 +x:1 +柴鸡 1 +x:1 +分清 1 +x:1 +节理 1 +x:1 +从快 1 +x:1 +幼女 1 +x:1 +小心谨慎 1 +x:1 +异型坯 1 +x:1 +婊子 1 +x:1 +拍就 1 +x:1 +进取心 1 +x:1 +边防连 1 +x:1 +三塘村 1 +x:1 +碧青碧青 1 +x:1 +群像 1 +x:1 +龙宫 1 +x:1 +催春 1 +x:1 +群贤毕集 1 +x:1 +凶兆 1 +x:1 +监外 1 +x:1 +澄碧 1 +x:1 +周刊社 1 +x:1 +弊害 1 +x:1 +防 203 +x:203 +蝎子 1 +x:1 +卖方 1 +x:1 +中庸 1 +x:1 +经销处 1 +x:1 +目下 1 +x:1 +学有所成 1 +x:1 +会东县 1 +x:1 +名存实亡 1 +x:1 +获利 1 +x:1 +一怒之下 1 +x:1 +喷水 1 +x:1 +揽活 1 +x:1 +学生会 1 +x:1 +语句 1 +x:1 +广州 1 +x:1 +小孔 1 +x:1 +师长 1 +x:1 +浓浓 1 +x:1 +从征 1 +x:1 +巫 13 +x:13 +只字未提 1 +x:1 +捐增 1 +x:1 +工段长 1 +x:1 +喷气 1 +x:1 +大处方 1 +x:1 +裹 44 +x:44 +说笑话 1 +x:1 +简单机械 1 +x:1 +飞桥 1 +x:1 +新郑市 1 +x:1 +修身养性 1 +x:1 +久别重逢 1 +x:1 +欠缺 1 +x:1 +汇兑商 1 +x:1 +云图 1 +x:1 +云团 1 +x:1 +群众性 1 +x:1 +芊芊 1 +x:1 +小说史家 1 +x:1 +穆尔拉 1 +x:1 +从影 1 +x:1 +肇事者 1 +x:1 +孜孜不倦 1 +x:1 +秘藏 1 +x:1 +关系者 1 +x:1 +截长补短 1 +x:1 +平白无故 1 +x:1 +陆航团 1 +x:1 +绯红 1 +x:1 +改过 1 +x:1 +例行 1 +x:1 +粉嫩 1 +x:1 +改进 1 +x:1 +组建 1 +x:1 +飞梭 1 +x:1 +一动 1 +x:1 +阴性 1 +x:1 +十月份 1 +x:1 +擎天 1 +x:1 +母语 1 +x:1 +木然 1 +x:1 +水彩 1 +x:1 +州督 1 +x:1 +股息 1 +x:1 +册页 1 +x:1 +清泉 1 +x:1 +不识抬举 1 +x:1 +龙子 1 +x:1 +浓淡 1 +x:1 +楣 1 +x:1 +愈益 1 +x:1 +牵系 1 +x:1 +推三阻四 1 +x:1 +羞于示人 1 +x:1 +凝固化 1 +x:1 +良种鸭 1 +x:1 +罢教 1 +x:1 +修正案 1 +x:1 +欧元 1 +x:1 +柔情似水 1 +x:1 +环注委 1 +x:1 +干涉性 1 +x:1 +尚沟里 1 +x:1 +冀西 1 +x:1 +头条 1 +x:1 +各税 1 +x:1 +社交 1 +x:1 +拍弦 1 +x:1 +骑兵 1 +x:1 +节省 1 +x:1 +圆 109 +x:109 +河北乡 1 +x:1 +剧烈 1 +x:1 +旅游年 1 +x:1 +断路器 1 +x:1 +康平 1 +x:1 +回复 1 +x:1 +广度 1 +x:1 +进口税 1 +x:1 +东弭河村 1 +x:1 +叠嶂 1 +x:1 +例证 1 +x:1 +脱皮树 1 +x:1 +萨吉德 1 +x:1 +氮素 1 +x:1 +蛙池 1 +x:1 +清话办 1 +x:1 +回头 1 +x:1 +催收 1 +x:1 +倔头倔脑 1 +x:1 +出神 1 +x:1 +宣战 1 +x:1 +险重 1 +x:1 +变现 1 +x:1 +违禁机 1 +x:1 +例话 1 +x:1 +群发 1 +x:1 +战斗部 1 +x:1 +宣扬 1 +x:1 +飘拂 1 +x:1 +圪台 1 +x:1 +劝募 1 +x:1 +分量感 1 +x:1 +比较文学 1 +x:1 +劣等 1 +x:1 +专利 1 +x:1 +飞歌 1 +x:1 +光度计 1 +x:1 +出示 1 +x:1 +通灵 1 +x:1 +统领 1 +x:1 +啼饥号寒 1 +x:1 +劝勉 1 +x:1 +绊 4 +x:4 +描述 1 +x:1 +喷漆 1 +x:1 +鸣凤镇 1 +x:1 +可恨 1 +x:1 +低者 1 +x:1 +奖勤罚懒 1 +x:1 +撑持 1 +x:1 +姑息养奸 1 +x:1 +高明市 1 +x:1 +天文 1 +x:1 +建设处 1 +x:1 +师院 1 +x:1 +低耗 1 +x:1 +终古不息 1 +x:1 +反咬一口 1 +x:1 +变速 1 +x:1 +亲缘 1 +x:1 +贴兜 1 +x:1 +住宿楼 1 +x:1 +指数值 1 +x:1 +转发器 1 +x:1 +地区部 1 +x:1 +大专学校 1 +x:1 +超高速 1 +x:1 +文才 1 +x:1 +公款吃喝 1 +x:1 +幼嫩 1 +x:1 +中科 1 +x:1 +获准 1 +x:1 +黑滔滔 1 +x:1 +饰件 1 +x:1 +股指 1 +x:1 +喷激 1 +x:1 +神经 1 +x:1 +组工 1 +x:1 +强有力 1 +x:1 +小跑 1 +x:1 +简谱 1 +x:1 +青霉素G 1 +x:1 +从属 1 +x:1 +人去楼空 1 +x:1 +呵斥 1 +x:1 +蛙泳 1 +x:1 +广布 1 +x:1 +毕节 1 +x:1 +飞毛 1 +x:1 +文成 1 +x:1 +中草药剂 1 +x:1 +依托 1 +x:1 +腕 16 +x:16 +可恶 1 +x:1 +文戏 1 +x:1 +栽跟头 1 +x:1 +缸缸坛坛 1 +x:1 +能源 1 +x:1 +户户 1 +x:1 +孤单 1 +x:1 +卡通城 1 +x:1 +从小 1 +x:1 +丸剂 1 +x:1 +轧钢 1 +x:1 +排名榜 1 +x:1 +舍生忘死 1 +x:1 +职官 1 +x:1 +坑坑洼洼 1 +x:1 +飞毯 1 +x:1 +官沱村 1 +x:1 +商品额 1 +x:1 +军人证 1 +x:1 +牛皮纸 1 +x:1 +广德 1 +x:1 +省立 1 +x:1 +发起组 1 +x:1 +顿足 1 +x:1 +永胜村 1 +x:1 +一望无垠 1 +x:1 +名列前茅 1 +x:1 +砚 14 +x:14 +理所当然 1 +x:1 +生物质能 1 +x:1 +幼子 1 +x:1 +叔祖 1 +x:1 +铁质 1 +x:1 +颠倒黑白 1 +x:1 +绣制 1 +x:1 +堕胎 1 +x:1 +纹络 1 +x:1 +如火如荼 1 +x:1 +茂密 1 +x:1 +看门 1 +x:1 +支撑网 1 +x:1 +涣散 1 +x:1 +血型 1 +x:1 +淘金者 1 +x:1 +下和村 1 +x:1 +舍亲 1 +x:1 +国土报 1 +x:1 +舍人 1 +x:1 +蔗渣 1 +x:1 +仗义疏财 1 +x:1 +星期六 1 +x:1 +花岗石 1 +x:1 +组展会 1 +x:1 +回填 1 +x:1 +爬泳 1 +x:1 +壮举 1 +x:1 +译版 1 +x:1 +找 994 +x:994 +东拼西凑 1 +x:1 +黑河市 1 +x:1 +德阳市 1 +x:1 +搁浅 1 +x:1 +飞檐 1 +x:1 +同音词 1 +x:1 +石景山 1 +x:1 +前呼后拥 1 +x:1 +险遭 1 +x:1 +雾里观花 1 +x:1 +奇松岛 1 +x:1 +磁性瓷 1 +x:1 +马拉松 1 +x:1 +山羊 1 +x:1 +独立宫 1 +x:1 +指控 1 +x:1 +牵线 1 +x:1 +头攻 1 +x:1 +象星村 1 +x:1 +阴户 1 +x:1 +东营区 1 +x:1 +十字路口 1 +x:1 +因人成事 1 +x:1 +监守 1 +x:1 +迪庆 1 +x:1 +龙头 1 +x:1 +广开 1 +x:1 +粉墙 1 +x:1 +排球队 1 +x:1 +能歌善舞 1 +x:1 +简赅 1 +x:1 +批判性 1 +x:1 +冰鞋跟 1 +x:1 +功成引退 1 +x:1 +睛 4 +x:4 +龙套 1 +x:1 +卫城山 1 +x:1 +喷溅 1 +x:1 +深成岩 1 +x:1 +假石林 1 +x:1 +瘠薄 1 +x:1 +回声 1 +x:1 +克原子 1 +x:1 +节目 1 +x:1 +越俎代庖 1 +x:1 +中药店 1 +x:1 +铁路 1 +x:1 +经销家 1 +x:1 +隋唐 1 +x:1 +家兔 1 +x:1 +三产型 1 +x:1 +云和 1 +x:1 +大脑皮层 1 +x:1 +晴雨伞 1 +x:1 +回望 1 +x:1 +坚守 1 +x:1 +沦陷 1 +x:1 +少见多怪 1 +x:1 +学生版 1 +x:1 +腊酒 1 +x:1 +服饰店 1 +x:1 +坚实 1 +x:1 +跳月 1 +x:1 +主人家 1 +x:1 +霉菌 1 +x:1 +坚定 1 +x:1 +鬓角 1 +x:1 +青霉素 1 +x:1 +建设村 1 +x:1 +青风寨乡 1 +x:1 +外交家 1 +x:1 +建设权 1 +x:1 +惯贼 1 +x:1 +连轧厂 1 +x:1 +哎哟 1 +x:1 +粉条 1 +x:1 +高利贷者 1 +x:1 +果林 1 +x:1 +校椅镇 1 +x:1 +低音提琴 1 +x:1 +果果 1 +x:1 +果枝 1 +x:1 +酒霸 1 +x:1 +深成指 1 +x:1 +林草 1 +x:1 +斗兽场 1 +x:1 +忘年交 1 +x:1 +寒夜 1 +x:1 +粒状 1 +x:1 +洽购 1 +x:1 +石洞源村 1 +x:1 +可言 1 +x:1 +团政委 1 +x:1 +礼部 1 +x:1 +儿孙满堂 1 +x:1 +跳板 1 +x:1 +面见 1 +x:1 +创业者 1 +x:1 +于事无补 1 +x:1 +捐料 1 +x:1 +林荫 1 +x:1 +猝死 1 +x:1 +小寒 1 +x:1 +三色版 1 +x:1 +粉末 1 +x:1 +凶气 1 +x:1 +回条 1 +x:1 +退避 1 +x:1 +绿 322 +x:322 +中晚餐 1 +x:1 +果材 1 +x:1 +行省 1 +x:1 +武二花 1 +x:1 +血案 1 +x:1 +渑池 1 +x:1 +飘尘 1 +x:1 +纺嫂 1 +x:1 +一泻千里 1 +x:1 +布吕肯街 1 +x:1 +口中 1 +x:1 +文山 1 +x:1 +哎呀 1 +x:1 +大老爷们 1 +x:1 +钓协 1 +x:1 +嵌镶 1 +x:1 +果条 1 +x:1 +法兰克福 1 +x:1 +林莽 1 +x:1 +营生 1 +x:1 +云母 1 +x:1 +罗萨里奥 1 +x:1 +爬升 1 +x:1 +创业股 1 +x:1 +笑掉大牙 1 +x:1 +吝惜 1 +x:1 +泽国镇 1 +x:1 +单晶体 1 +x:1 +主考官 1 +x:1 +刘村镇 1 +x:1 +血栓 1 +x:1 +劳务费 1 +x:1 +坎布斯 1 +x:1 +庞庄 1 +x:1 +开斋节 1 +x:1 +从戎 1 +x:1 +恍然大悟 1 +x:1 +拾人牙慧 1 +x:1 +组接 1 +x:1 +古庄店 1 +x:1 +礼遇 1 +x:1 +先租后股 1 +x:1 +血样 1 +x:1 +灰溜溜 1 +x:1 +忍耐力 1 +x:1 +果木 1 +x:1 +凌河 1 +x:1 +喜糖 1 +x:1 +议论声 1 +x:1 +粒细胞 1 +x:1 +报告团 1 +x:1 +双垂尾 1 +x:1 +绒裤 1 +x:1 +才高八斗 1 +x:1 +底 897 +x:897 +龙果 1 +x:1 +摆摆 1 +x:1 +提取物 1 +x:1 +裨益 1 +x:1 +摆摊 1 +x:1 +拖累 1 +x:1 +虞美人 1 +x:1 +兰村乡 1 +x:1 +飞吻 1 +x:1 +阿城 1 +x:1 +鹿群 1 +x:1 +转马 1 +x:1 +男双 1 +x:1 +男友 1 +x:1 +幼教 1 +x:1 +虚线 1 +x:1 +合阳 1 +x:1 +云岩区 1 +x:1 +星级 1 +x:1 +回春 1 +x:1 +竹马 1 +x:1 +游路 1 +x:1 +区分值 1 +x:1 +泉 34 +x:34 +产业处 1 +x:1 +剔庄货 1 +x:1 +处罚法 1 +x:1 +偷闲 1 +x:1 +正义感 1 +x:1 +组成 1 +x:1 +售票 1 +x:1 +头寸 1 +x:1 +萨迦派 1 +x:1 +金箍棒 1 +x:1 +宁河县 1 +x:1 +丁冬 1 +x:1 +敬老院 1 +x:1 +营帐 1 +x:1 +男厕 1 +x:1 +南北阁 1 +x:1 +轴 5 +x:5 +刻薄 1 +x:1 +移 148 +x:148 +理发店 1 +x:1 +洽谈 1 +x:1 +梯田 1 +x:1 +幼时 1 +x:1 +写实主义 1 +x:1 +抵押物 1 +x:1 +成像机 1 +x:1 +欧洲 1 +x:1 +骁勇 1 +x:1 +大老粗 1 +x:1 +消 36 +x:36 +战胜国 1 +x:1 +回暖 1 +x:1 +四里八乡 1 +x:1 +拖拖拉拉 1 +x:1 +天空 1 +x:1 +绒衣 1 +x:1 +纸鸢 1 +x:1 +赡养 1 +x:1 +起先 1 +x:1 +弹无虚发 1 +x:1 +贴付 1 +x:1 +滔滔 1 +x:1 +鹿儿岛县 1 +x:1 +大业乡 1 +x:1 +生殖道 1 +x:1 +男单 1 +x:1 +彩照 1 +x:1 +营利性 1 +x:1 +抵罪 1 +x:1 +国土局 1 +x:1 +吸引 1 +x:1 +打盹 1 +x:1 +众说纷纭 1 +x:1 +二中全会 1 +x:1 +揍 6 +x:6 +今 334 +x:334 +坐班制 1 +x:1 +头子 1 +x:1 +左右为难 1 +x:1 +交界地 1 +x:1 +电教片 1 +x:1 +惜乎 1 +x:1 +未知量 1 +x:1 +生产操 1 +x:1 +清江村 1 +x:1 +技战术 1 +x:1 +游赏 1 +x:1 +颤微微 1 +x:1 +寻花问柳 1 +x:1 +游资 1 +x:1 +男婚女嫁 1 +x:1 +龙爪槐 1 +x:1 +正确性 1 +x:1 +群氓 1 +x:1 +适龄 1 +x:1 +变例 1 +x:1 +劳作 1 +x:1 +西语系 1 +x:1 +昭 55 +x:55 +仙桃 1 +x:1 +汉水 1 +x:1 +输水线 1 +x:1 +街子乡 1 +x:1 +农茶场 1 +x:1 +停薪留职 1 +x:1 +郑州市 1 +x:1 +飞地 1 +x:1 +新英格兰 1 +x:1 +拥挤不堪 1 +x:1 +回收 1 +x:1 +专营性 1 +x:1 +衣冠不整 1 +x:1 +归属权 1 +x:1 +闲置 1 +x:1 +饰物 1 +x:1 +口信 1 +x:1 +首战告捷 1 +x:1 +回教 1 +x:1 +法定性 1 +x:1 +文库 1 +x:1 +蘑菇棚 1 +x:1 +急救箱 1 +x:1 +釜底游鱼 1 +x:1 +御园 1 +x:1 +逐鹿 1 +x:1 +文庙 1 +x:1 +果料 1 +x:1 +语法 1 +x:1 +煳 1 +x:1 +牡丹江 1 +x:1 +才能 1 +x:1 +奔腾激越 1 +x:1 +倏地 1 +x:1 +麻织品 1 +x:1 +铅丝 1 +x:1 +宝号 1 +x:1 +广招 1 +x:1 +宋集村 1 +x:1 +九九年 1 +x:1 +二十八日 1 +x:1 +白沙瓦 1 +x:1 +溅落 1 +x:1 +画廊业 1 +x:1 +回敬 1 +x:1 +记略 1 +x:1 +太浦河 1 +x:1 +果断 1 +x:1 +劳伤 1 +x:1 +游踪 1 +x:1 +早点 1 +x:1 +作坊业 1 +x:1 +膳食 1 +x:1 +工部局 1 +x:1 +劳保 1 +x:1 +作家群 1 +x:1 +密宗法要 1 +x:1 +语气 1 +x:1 +挨门 1 +x:1 +高材生 1 +x:1 +加里波第 1 +x:1 +拦截 1 +x:1 +青年会 1 +x:1 +跳方 1 +x:1 +食品学家 1 +x:1 +群英谱 1 +x:1 +撺弄 1 +x:1 +摄制组 1 +x:1 +二十五史 1 +x:1 +飘带 1 +x:1 +游客 1 +x:1 +政见者 1 +x:1 +果敢 1 +x:1 +猜先 1 +x:1 +喷发 1 +x:1 +慌里慌张 1 +x:1 +语汇 1 +x:1 +变位 1 +x:1 +运动鞋者 1 +x:1 +建设方 1 +x:1 +如愿以偿 1 +x:1 +回旋 1 +x:1 +商品粮 1 +x:1 +协 11 +x:11 +回族 1 +x:1 +讲坛 1 +x:1 +薄酒 1 +x:1 +油条 1 +x:1 +茎草 1 +x:1 +作到 1 +x:1 +那种 1 +x:1 +脚丫 1 +x:1 +进犯 1 +x:1 +尽心尽职 1 +x:1 +经血 1 +x:1 +凉山籍 1 +x:1 +自找麻烦 1 +x:1 +报道 1 +x:1 +晃荡 1 +x:1 +淫威 1 +x:1 +送子观音 1 +x:1 +经销权 1 +x:1 +数据舱 1 +x:1 +塑料篷 1 +x:1 +疗程 1 +x:1 +达尔文 1 +x:1 +改过迁善 1 +x:1 +尊干 1 +x:1 +劳乏 1 +x:1 +竹园镇 1 +x:1 +中山区 1 +x:1 +埃镑 1 +x:1 +隔阻 1 +x:1 +特赦令 1 +x:1 +重演 1 +x:1 +拍戏 1 +x:1 +牌价 1 +x:1 +浓化 1 +x:1 +中心线 1 +x:1 +外经贸部 1 +x:1 +排灌站 1 +x:1 +卖家 1 +x:1 +堆放地 1 +x:1 +打球 1 +x:1 +插件机 1 +x:1 +幼儿园 1 +x:1 +学有所用 1 +x:1 +堆放场 1 +x:1 +掌声雷动 1 +x:1 +青年人 1 +x:1 +中药房 1 +x:1 +税收额 1 +x:1 +中心组 1 +x:1 +肩部 1 +x:1 +神秘化 1 +x:1 +欢笑声 1 +x:1 +塑料管 1 +x:1 +摆明 1 +x:1 +合情合理 1 +x:1 +青葱可人 1 +x:1 +祛痰剂 1 +x:1 +心血来潮 1 +x:1 +价非字 1 +x:1 +打假办 1 +x:1 +拍手 1 +x:1 +活动费 1 +x:1 +龙文村 1 +x:1 +飘忽 1 +x:1 +交换体 1 +x:1 +变价 1 +x:1 +唇亡齿寒 1 +x:1 +主产省 1 +x:1 +掀 25 +x:25 +文录 1 +x:1 +浣濯 1 +x:1 +东南欧 1 +x:1 +歧路 1 +x:1 +男兵 1 +x:1 +宝刀 1 +x:1 +浓厚 1 +x:1 +申报法 1 +x:1 +股市 1 +x:1 +浸种 1 +x:1 +有备而来 1 +x:1 +头头 1 +x:1 +塑料筐 1 +x:1 +丁卯 1 +x:1 +出让方 1 +x:1 +变为 1 +x:1 +好好 1 +x:1 +含硫量 1 +x:1 +报告员 1 +x:1 +头天 1 +x:1 +地下道 1 +x:1 +宝剑 1 +x:1 +酒钱 1 +x:1 +敌 80 +x:80 +噬菌体 1 +x:1 +头套 1 +x:1 +入梦 1 +x:1 +胎生 1 +x:1 +怡红院 1 +x:1 +乡规民约 1 +x:1 +缺陷率 1 +x:1 +木棒 1 +x:1 +酒钢 1 +x:1 +罹难者 1 +x:1 +男儿 1 +x:1 +有说有笑 1 +x:1 +云梯 1 +x:1 +迪拜 1 +x:1 +幼林 1 +x:1 +透平机 1 +x:1 +打瓜 1 +x:1 +瓶颈 1 +x:1 +药补 1 +x:1 +机器人 1 +x:1 +悲喜交集 1 +x:1 +阴平 1 +x:1 +读秒声 1 +x:1 +漂白剂 1 +x:1 +座钟 1 +x:1 +恒 19 +x:19 +潘家蕃 1 +x:1 +变乱 1 +x:1 +皮糖 1 +x:1 +进馆 1 +x:1 +跳梁小丑 1 +x:1 +平行线 1 +x:1 +男团 1 +x:1 +血泊 1 +x:1 +会集 1 +x:1 +血泉 1 +x:1 +履历表 1 +x:1 +广播 1 +x:1 +朱书 1 +x:1 +濡养 1 +x:1 +普照 1 +x:1 +仙湖 1 +x:1 +实验鼠 1 +x:1 +中后场 1 +x:1 +血泡 1 +x:1 +血泪 1 +x:1 +长歌当哭 1 +x:1 +电荷 1 +x:1 +水电气 1 +x:1 +能说会道 1 +x:1 +目睹 1 +x:1 +餐餐 1 +x:1 +打猎 1 +x:1 +种子队 1 +x:1 +文士 1 +x:1 +坚忍 1 +x:1 +气冲霄汉 1 +x:1 +差价款 1 +x:1 +血沉 1 +x:1 +瘟猪疫 1 +x:1 +就诊者 1 +x:1 +西张镇 1 +x:1 +客舱 1 +x:1 +苍岩山 1 +x:1 +收入量 1 +x:1 +客船 1 +x:1 +谨严 1 +x:1 +总的说来 1 +x:1 +目眩 1 +x:1 +归属感 1 +x:1 +两弹一星 1 +x:1 +报告厅 1 +x:1 +跳跳蹦蹦 1 +x:1 +野营拉练 1 +x:1 +拯 7 +x:7 +荒凉 1 +x:1 +干梆梆 1 +x:1 +人行道 1 +x:1 +飞入 1 +x:1 +文墨 1 +x:1 +玉树州 1 +x:1 +半衰期 1 +x:1 +义安 1 +x:1 +头帕 1 +x:1 +叮当作响 1 +x:1 +邯山区 1 +x:1 +记者部 1 +x:1 +血汗 1 +x:1 +制定 1 +x:1 +鱼网阵 1 +x:1 +差价比 1 +x:1 +多伦多 1 +x:1 +血污 1 +x:1 +偷逃 1 +x:1 +游击队 1 +x:1 +售粮 1 +x:1 +咕哩寨 1 +x:1 +抒写 1 +x:1 +中心社 1 +x:1 +坚强 1 +x:1 +阴天 1 +x:1 +报告单 1 +x:1 +座座 1 +x:1 +薄露 1 +x:1 +乌克兰 1 +x:1 +输机 1 +x:1 +辩白 1 +x:1 +乌骨鸡 1 +x:1 +组构 1 +x:1 +还款数 1 +x:1 +宝商 1 +x:1 +轰隆 1 +x:1 +邓庄乡 1 +x:1 +统筹费 1 +x:1 +费转税 1 +x:1 +总的看来 1 +x:1 +字面 1 +x:1 +我校 1 +x:1 +色价 1 +x:1 +公伯峡 1 +x:1 +火漆印 1 +x:1 +游行 1 +x:1 +头年 1 +x:1 +伏案 1 +x:1 +回援 1 +x:1 +淀粉酶 1 +x:1 +信任投票 1 +x:1 +龙海市 1 +x:1 +血水 1 +x:1 +会阴 1 +x:1 +增色 1 +x:1 +护田林 1 +x:1 +文委 1 +x:1 +粉扑 1 +x:1 +生产性 1 +x:1 +营建 1 +x:1 +林 909 +x:909 +过不过时 1 +x:1 +超载 1 +x:1 +丑角 1 +x:1 +血淤 1 +x:1 +镇远县 1 +x:1 +面貌 1 +x:1 +剪贴 1 +x:1 +理儿 1 +x:1 +由表及里 1 +x:1 +非例行 1 +x:1 +诱惑 1 +x:1 +排名制 1 +x:1 +广旺 1 +x:1 +云游 1 +x:1 +不仅如此 1 +x:1 +种牛场 1 +x:1 +不择手段 1 +x:1 +降落伞 1 +x:1 +专营权 1 +x:1 +海淀区 1 +x:1 +归属性 1 +x:1 +经述 1 +x:1 +怏怏 1 +x:1 +拍摄 1 +x:1 +游览 1 +x:1 +电船 1 +x:1 +经过 1 +x:1 +刚果队 1 +x:1 +尼 32 +x:32 +薄雾 1 +x:1 +排名分 1 +x:1 +小儿调 1 +x:1 +喷吐 1 +x:1 +水稻种 1 +x:1 +腾云楼 1 +x:1 +回执 1 +x:1 +手工业者 1 +x:1 +血浆 1 +x:1 +文契 1 +x:1 +上升流 1 +x:1 +窖 3 +x:3 +从来 1 +x:1 +缜密 1 +x:1 +头式 1 +x:1 +上无片瓦 1 +x:1 +喧闹声 1 +x:1 +顽固派 1 +x:1 +如临大敌 1 +x:1 +如沐薰风 1 +x:1 +井陉县 1 +x:1 +掰 15 +x:15 +语次 1 +x:1 +十番乐 1 +x:1 +防火期 1 +x:1 +面谈 1 +x:1 +会面 1 +x:1 +内公切线 1 +x:1 +活动课 1 +x:1 +铜墙铁壁 1 +x:1 +补饲 1 +x:1 +长歌当啸 1 +x:1 +勘探局 1 +x:1 +董监事 1 +x:1 +从未 1 +x:1 +钢琴家 1 +x:1 +富岭村 1 +x:1 +防火板 1 +x:1 +目的 1 +x:1 +不声不响 1 +x:1 +出气儿 1 +x:1 +血洗 1 +x:1 +报告制 1 +x:1 +报靶 1 +x:1 +林蛙 1 +x:1 +庖丁解牛 1 +x:1 +迎宾处 1 +x:1 +残留量 1 +x:1 +遍体鳞伤 1 +x:1 +满腹不快 1 +x:1 +挺立 1 +x:1 +井陉矿区 1 +x:1 +普天同庆 1 +x:1 +红四军 1 +x:1 +世态相 1 +x:1 +头彩 1 +x:1 +官办 1 +x:1 +永定路 1 +x:1 +电话会议 1 +x:1 +土腥气 1 +x:1 +妻女 1 +x:1 +情真意长 1 +x:1 +漆 17 +x:17 +酒酿 1 +x:1 +塑料绳 1 +x:1 +光杆司令 1 +x:1 +刻苦 1 +x:1 +组教 1 +x:1 +票款 1 +x:1 +大凌河 1 +x:1 +谜 43 +x:43 +雄浑 1 +x:1 +活动表 1 +x:1 +先行点 1 +x:1 +弦 22 +x:22 +中药材 1 +x:1 +自成一家 1 +x:1 +幼托 1 +x:1 +维多利亚 1 +x:1 +退防 1 +x:1 +中山堂 1 +x:1 +圣战 1 +x:1 +鬼把戏 1 +x:1 +狂风 1 +x:1 +劳其筋骨 1 +x:1 +宏亮 1 +x:1 +刻花 1 +x:1 +两小无猜 1 +x:1 +塑料纸 1 +x:1 +悬赏 1 +x:1 +凶横 1 +x:1 +莲花白 1 +x:1 +电脑 1 +x:1 +东亚马孙 1 +x:1 +蕴意 1 +x:1 +面述 1 +x:1 +折回 1 +x:1 +拍板 1 +x:1 +桃子 1 +x:1 +现场感 1 +x:1 +打点费 1 +x:1 +飞升 1 +x:1 +绦子 1 +x:1 +拍杆 1 +x:1 +方程组 1 +x:1 +产业带 1 +x:1 +雍和宫 1 +x:1 +转会制 1 +x:1 +内容栏 1 +x:1 +周期律 1 +x:1 +美容师 1 +x:1 +农情 1 +x:1 +蛇纹石 1 +x:1 +尺有所短 1 +x:1 +苇屏 1 +x:1 +家鼠 1 +x:1 +代码费 1 +x:1 +木马 1 +x:1 +教学相长 1 +x:1 +沉溺 1 +x:1 +祖宗 1 +x:1 +账面 1 +x:1 +监护 1 +x:1 +太开路 1 +x:1 +御制 1 +x:1 +哗啦哗啦 1 +x:1 +叠放 1 +x:1 +秦风槐韵 1 +x:1 +头尾 1 +x:1 +约言 1 +x:1 +暖融融 1 +x:1 +宝地 1 +x:1 +药贩 1 +x:1 +广昌 1 +x:1 +横波 1 +x:1 +药费 1 +x:1 +汪清 1 +x:1 +酒量 1 +x:1 +香火 1 +x:1 +还款期 1 +x:1 +淫心 1 +x:1 +胄 18 +x:18 +北台 1 +x:1 +血清 1 +x:1 +鸿门宴 1 +x:1 +国际主义 1 +x:1 +灏 2 +x:2 +平方英尺 1 +x:1 +接受方 1 +x:1 +有备而战 1 +x:1 +科学技术 1 +x:1 +朝阳花 1 +x:1 +拍柄 1 +x:1 +高聚物 1 +x:1 +抒发 1 +x:1 +文娱 1 +x:1 +依附 1 +x:1 +戏馆 1 +x:1 +铝矾土 1 +x:1 +价函字 1 +x:1 +宝坻 1 +x:1 +股子 1 +x:1 +从小到大 1 +x:1 +瘫痪 1 +x:1 +奶头 1 +x:1 +湾中 1 +x:1 +豆类 1 +x:1 +输水管 1 +x:1 +电联 1 +x:1 +跟风 1 +x:1 +软硬件 1 +x:1 +外汇法 1 +x:1 +游记 1 +x:1 +摆手 1 +x:1 +秦镜高悬 1 +x:1 +价值规律 1 +x:1 +迎风 1 +x:1 +树种 1 +x:1 +用水量 1 +x:1 +排戏 1 +x:1 +丑话 1 +x:1 +十字镐 1 +x:1 +羊草 1 +x:1 +老君堂 1 +x:1 +扶风县 1 +x:1 +丑诋 1 +x:1 +栈房 1 +x:1 +感觉器官 1 +x:1 +文宗 1 +x:1 +诱拐 1 +x:1 +大计方针 1 +x:1 +砖壁 1 +x:1 +棉贩子 1 +x:1 +文宝 1 +x:1 +售罄 1 +x:1 +道路口 1 +x:1 +文官 1 +x:1 +打火 1 +x:1 +景颇族 1 +x:1 +喷嘴 1 +x:1 +建设性 1 +x:1 +仗义 1 +x:1 +中心站 1 +x:1 +从新 1 +x:1 +成才路 1 +x:1 +文安 1 +x:1 +头巾 1 +x:1 +文家 1 +x:1 +升级换代 1 +x:1 +欢悦 1 +x:1 +云气 1 +x:1 +无境界 1 +x:1 +庐 3 +x:3 +河北省 1 +x:1 +松花蛋 1 +x:1 +胖墩墩 1 +x:1 +旅游月 1 +x:1 +关帝矿 1 +x:1 +螟虫 1 +x:1 +取款 1 +x:1 +从学 1 +x:1 +偶氮染料 1 +x:1 +一纸空谈 1 +x:1 +寻问条 1 +x:1 +白食 1 +x:1 +庞大 1 +x:1 +文字 1 +x:1 +家鸡 1 +x:1 +打点 1 +x:1 +抚今追昔 1 +x:1 +卖弄 1 +x:1 +夜莺 1 +x:1 +衣冠禽兽 1 +x:1 +家鸭 1 +x:1 +文存 1 +x:1 +园中园 1 +x:1 +打炮 1 +x:1 +经费 1 +x:1 +经贸 1 +x:1 +百合种 1 +x:1 +御医 1 +x:1 +金口路 1 +x:1 +南北部 1 +x:1 +电能 1 +x:1 +后代人 1 +x:1 +落雁区 1 +x:1 +披阅 1 +x:1 +一蹶不振 1 +x:1 +嘶哑 1 +x:1 +医学会 1 +x:1 +报销 1 +x:1 +逝去 1 +x:1 +飞动 1 +x:1 +文学 1 +x:1 +薄膜 1 +x:1 +会长 1 +x:1 +闲章 1 +x:1 +总产 1 +x:1 +马失前蹄 1 +x:1 +欧登塞 1 +x:1 +药谷 1 +x:1 +热连轧 1 +x:1 +鸟儿 1 +x:1 +雄沉 1 +x:1 +不可告人 1 +x:1 +舍身忘死 1 +x:1 +绫椤绸缎 1 +x:1 +硬头 1 +x:1 +上班族 1 +x:1 +螟蛉 1 +x:1 +倾斜度 1 +x:1 +佛 32 +x:32 +一饱口福 1 +x:1 +瞎 22 +x:22 +换届会 1 +x:1 +东奔西窜 1 +x:1 +节令 1 +x:1 +螟蛾 1 +x:1 +主干线 1 +x:1 +喷嚏 1 +x:1 +朝晖 1 +x:1 +回想 1 +x:1 +引导性 1 +x:1 +宏伟 1 +x:1 +打烊 1 +x:1 +柞树 1 +x:1 +劝止 1 +x:1 +始终不渝 1 +x:1 +宝器 1 +x:1 +指桑骂槐 1 +x:1 +头功 1 +x:1 +组歌 1 +x:1 +台儿庄 1 +x:1 +符山镇 1 +x:1 +一以贯之 1 +x:1 +催化 1 +x:1 +科技节 1 +x:1 +出使 1 +x:1 +邮联 1 +x:1 +图面 1 +x:1 +高低型 1 +x:1 +职介网 1 +x:1 +浑然一色 1 +x:1 +虚拟化 1 +x:1 +情同手足 1 +x:1 +平凉站 1 +x:1 +始终不懈 1 +x:1 +素心梅 1 +x:1 +回漩 1 +x:1 +咸兴 1 +x:1 +演化说 1 +x:1 +面膜 1 +x:1 +电车 1 +x:1 +里带 1 +x:1 +法律 1 +x:1 +腥黑穗病 1 +x:1 +洋华堂 1 +x:1 +鸟类学家 1 +x:1 +喷头 1 +x:1 +高品位 1 +x:1 +沙田 1 +x:1 +晋安沟 1 +x:1 +同类题材 1 +x:1 +宣告 1 +x:1 +蜈蚣草 1 +x:1 +大麦 1 +x:1 +群文 1 +x:1 +家里 1 +x:1 +重样 1 +x:1 +转校生 1 +x:1 +市用制 1 +x:1 +回潮 1 +x:1 +出众 1 +x:1 +如醉如痴 1 +x:1 +储金 1 +x:1 +顽固性 1 +x:1 +塞尔维亚 1 +x:1 +一扫而过 1 +x:1 +迎面 1 +x:1 +专用性 1 +x:1 +季风区 1 +x:1 +招商月 1 +x:1 +分党委 1 +x:1 +置之不顾 1 +x:1 +男婴 1 +x:1 +订机 1 +x:1 +不幸者 1 +x:1 +文告 1 +x:1 +盗墓 1 +x:1 +鳟鱼 1 +x:1 +龙港 1 +x:1 +一面之交 1 +x:1 +署长 1 +x:1 +闻喜 1 +x:1 +阎良区 1 +x:1 +束水丁坝 1 +x:1 +泌尿器 1 +x:1 +本分人 1 +x:1 +打翻 1 +x:1 +毛线针 1 +x:1 +卖假 1 +x:1 +瞎信 1 +x:1 +草牧场 1 +x:1 +运转率 1 +x:1 +杨家村 1 +x:1 +立轴 1 +x:1 +大理市 1 +x:1 +应用面 1 +x:1 +龙湖 1 +x:1 +兴风作浪 1 +x:1 +里庄 1 +x:1 +男娃 1 +x:1 +非请莫入 1 +x:1 +辛亥革命 1 +x:1 +首里城 1 +x:1 +家酒 1 +x:1 +其实 1 +x:1 +龙湾 1 +x:1 +牛角沱 1 +x:1 +巨宝村 1 +x:1 +诗文论 1 +x:1 +仔虾 1 +x:1 +面肥 1 +x:1 +客车 1 +x:1 +雄才 1 +x:1 +立身 1 +x:1 +打假声 1 +x:1 +齐胸 1 +x:1 +马拉凯 1 +x:1 +戏院 1 +x:1 +欧方 1 +x:1 +说一不二 1 +x:1 +懦夫 1 +x:1 +壮硕 1 +x:1 +回游 1 +x:1 +天阉 1 +x:1 +出乎 1 +x:1 +存贮 1 +x:1 +馅饼 1 +x:1 +砖门 1 +x:1 +角美镇 1 +x:1 +存货 1 +x:1 +重整旗鼓 1 +x:1 +长葛市 1 +x:1 +朴 38 +x:38 +喷塑 1 +x:1 +欠债还钱 1 +x:1 +各科 1 +x:1 +存贷 1 +x:1 +闻名 1 +x:1 +里弦 1 +x:1 +焦作市 1 +x:1 +男客 1 +x:1 +复合材料 1 +x:1 +图阵 1 +x:1 +迈纳吉勒 1 +x:1 +头发 1 +x:1 +跟随 1 +x:1 +叔伯 1 +x:1 +抗拒感 1 +x:1 +齐肩 1 +x:1 +八仙过海 1 +x:1 +里弄 1 +x:1 +拍框 1 +x:1 +爱尔兰 1 +x:1 +长阁村 1 +x:1 +星相 1 +x:1 +哩 40 +x:40 +头号 1 +x:1 +投资部长 1 +x:1 +走后门 1 +x:1 +三大差别 1 +x:1 +分项 1 +x:1 +监测 1 +x:1 +出丑 1 +x:1 +心服口服 1 +x:1 +朝阳路 1 +x:1 +账页 1 +x:1 +水稻田 1 +x:1 +厂部 1 +x:1 +布拉吉 1 +x:1 +宾阳 1 +x:1 +从此 1 +x:1 +男孩 1 +x:1 +喷壶 1 +x:1 +月余 1 +x:1 +赔罪 1 +x:1 +出任 1 +x:1 +催办 1 +x:1 +战后 1 +x:1 +出价 1 +x:1 +豌豆 1 +x:1 +葡萄园 1 +x:1 +迎客松 1 +x:1 +桡动脉 1 +x:1 +催动 1 +x:1 +明日黄花 1 +x:1 +电流表 1 +x:1 +葡萄酒厂 1 +x:1 +客运 1 +x:1 +男子 1 +x:1 +图案色 1 +x:1 +泗水亭 1 +x:1 +图集 1 +x:1 +宝塔 1 +x:1 +世界语 1 +x:1 +浑俗和光 1 +x:1 +出产 1 +x:1 +特困生 1 +x:1 +哗众 1 +x:1 +长江天堑 1 +x:1 +规划区 1 +x:1 +产业军 1 +x:1 +叶面施肥 1 +x:1 +挺直 1 +x:1 +止痛药 1 +x:1 +报忧者 1 +x:1 +天险 1 +x:1 +出于 1 +x:1 +违章者 1 +x:1 +龙潭 1 +x:1 +叫苦 1 +x:1 +机载 1 +x:1 +官制 1 +x:1 +三六九等 1 +x:1 +聪敏 1 +x:1 +时尚 1 +x:1 +功亏一篑 1 +x:1 +股员 1 +x:1 +叔侄 1 +x:1 +叼 3 +x:3 +药膏 1 +x:1 +会风 1 +x:1 +热腾腾 1 +x:1 +三角函数 1 +x:1 +寿星 1 +x:1 +宝宝 1 +x:1 +男士 1 +x:1 +勘探史 1 +x:1 +立足 1 +x:1 +公正性 1 +x:1 +药膜 1 +x:1 +前童村 1 +x:1 +砖雕 1 +x:1 +男声 1 +x:1 +十一日 1 +x:1 +宝安 1 +x:1 +飞弹 1 +x:1 +攻击点 1 +x:1 +协办 1 +x:1 +牙组织 1 +x:1 +报领 1 +x:1 +南陵县 1 +x:1 +里屋 1 +x:1 +卖劲 1 +x:1 +牛角湾 1 +x:1 +获救 1 +x:1 +输出国 1 +x:1 +挥笔 1 +x:1 +抵押科 1 +x:1 +坚冰 1 +x:1 +坚决 1 +x:1 +龙泉 1 +x:1 +胆色素 1 +x:1 +夏邑县 1 +x:1 +陈词滥调 1 +x:1 +顺道儿 1 +x:1 +种 5155 +x:5155 +拟稿 1 +x:1 +和事老 1 +x:1 +冲天炮 1 +x:1 +头像 1 +x:1 +诵经 1 +x:1 +食变星 1 +x:1 +梗塞 1 +x:1 +浚 1 +x:1 +龙法 1 +x:1 +包保 1 +x:1 +狗屎堆 1 +x:1 +电贺 1 +x:1 +曲阳 1 +x:1 +游蛇 1 +x:1 +艰 2 +x:2 +电流计 1 +x:1 +养虾场 1 +x:1 +省便 1 +x:1 +毫不讳言 1 +x:1 +空间感 1 +x:1 +粉白色 1 +x:1 +吸吮 1 +x:1 +立账 1 +x:1 +清江水 1 +x:1 +倏忽 1 +x:1 +后卫 1 +x:1 +跃跃欲试 1 +x:1 +惟我独尊 1 +x:1 +飞往 1 +x:1 +列祖列宗 1 +x:1 +零零碎碎 1 +x:1 +存身 1 +x:1 +大半夜 1 +x:1 +咨询表 1 +x:1 +非当地 1 +x:1 +只得 1 +x:1 +聪明 1 +x:1 +浴血 1 +x:1 +外延性 1 +x:1 +冷嘲热讽 1 +x:1 +处罚权 1 +x:1 +悬臂 1 +x:1 +摈逐 1 +x:1 +援助 1 +x:1 +果洛 1 +x:1 +申报方 1 +x:1 +细纱机 1 +x:1 +防腐厂 1 +x:1 +凶暴 1 +x:1 +龙江 1 +x:1 +乙脑 1 +x:1 +省优 1 +x:1 +血战 1 +x:1 +省会 1 +x:1 +野山歌 1 +x:1 +双增双节 1 +x:1 +提名奖 1 +x:1 +梯级 1 +x:1 +旁门 1 +x:1 +雨涝 1 +x:1 +羔子 1 +x:1 +蔡甸区 1 +x:1 +薄饼 1 +x:1 +飞快 1 +x:1 +证件 1 +x:1 +吸呐 1 +x:1 +登记簿 1 +x:1 +枫 21 +x:21 +腮帮子 1 +x:1 +传统课 1 +x:1 +宠臣 1 +x:1 +一见如故 1 +x:1 +大理州 1 +x:1 +有把握 1 +x:1 +律令 1 +x:1 +可触摸性 1 +x:1 +回民 1 +x:1 +泡饭 1 +x:1 +自民 1 +x:1 +蛾眉月 1 +x:1 +防腐剂 1 +x:1 +转道 1 +x:1 +武工队 1 +x:1 +语料 1 +x:1 +骄 8 +x:8 +凶杀 1 +x:1 +劝架 1 +x:1 +马德里队 1 +x:1 +报馆 1 +x:1 +敞架 1 +x:1 +空间波 1 +x:1 +乏善可陈 1 +x:1 +猪年 1 +x:1 +庙子乡 1 +x:1 +律他 1 +x:1 +省价 1 +x:1 +强取豪夺 1 +x:1 +X 9 +x:9 +心肝宝贝 1 +x:1 +舞弊案 1 +x:1 +省份 1 +x:1 +法师 1 +x:1 +复查组 1 +x:1 +增养殖业 1 +x:1 +客货 1 +x:1 +绒花 1 +x:1 +转送 1 +x:1 +枞树 1 +x:1 +省事 1 +x:1 +教养员 1 +x:1 +乙肝 1 +x:1 +产业化 1 +x:1 +转速 1 +x:1 +谢拉罗 1 +x:1 +左下角 1 +x:1 +分斤掰两 1 +x:1 +葫瓜 1 +x:1 +涓滴 1 +x:1 +坐视不管 1 +x:1 +现代史 1 +x:1 +雄性 1 +x:1 +芦淞区 1 +x:1 +摆渡 1 +x:1 +柳 161 +x:161 +省亲 1 +x:1 +敌杀死 1 +x:1 +攻陷 1 +x:1 +杀人罪 1 +x:1 +湖北 1 +x:1 +文坛 1 +x:1 +汉寿县 1 +x:1 +求职者 1 +x:1 +男女 1 +x:1 +参保率 1 +x:1 +龙洞 1 +x:1 +星球 1 +x:1 +收入 1 +x:1 +头儿 1 +x:1 +小巴 1 +x:1 +防城港 1 +x:1 +乡级 1 +x:1 +经脉 1 +x:1 +接二连三 1 +x:1 +苞谷饭 1 +x:1 +首映式 1 +x:1 +一望无边 1 +x:1 +燕赵 1 +x:1 +清洗费 1 +x:1 +悲 18 +x:18 +应变力 1 +x:1 +咂咂 1 +x:1 +干枝 1 +x:1 +仄声 1 +x:1 +粉沙 1 +x:1 +诀 3 +x:3 +高高地 1 +x:1 +悬而未决 1 +x:1 +筋 6 +x:6 +脯子 1 +x:1 +涿河 1 +x:1 +绿叶丛 1 +x:1 +清江浦 1 +x:1 +面色 1 +x:1 +蹙 2 +x:2 +特委会 1 +x:1 +断炊 1 +x:1 +会餐 1 +x:1 +黄道吉日 1 +x:1 +监管法 1 +x:1 +信用所 1 +x:1 +宣城 1 +x:1 +桃园 1 +x:1 +集散点 1 +x:1 +世界观 1 +x:1 +文场 1 +x:1 +打糕 1 +x:1 +图钉 1 +x:1 +南河一村 1 +x:1 +硬弓 1 +x:1 +东倒西歪 1 +x:1 +输出地 1 +x:1 +浓密 1 +x:1 +美容厅 1 +x:1 +技巧运动 1 +x:1 +玉兰片 1 +x:1 +至多 1 +x:1 +塑料瓶 1 +x:1 +忙忙活活 1 +x:1 +五四运动 1 +x:1 +凶恶 1 +x:1 +七大姑 1 +x:1 +立论 1 +x:1 +延长 1 +x:1 +飞夺 1 +x:1 +阴冷 1 +x:1 +提蓄水 1 +x:1 +人物画 1 +x:1 +飞天 1 +x:1 +幼桃 1 +x:1 +货畅其流 1 +x:1 +云杉 1 +x:1 +咻 1 +x:1 +梳头 1 +x:1 +只好 1 +x:1 +坚城 1 +x:1 +云朵 1 +x:1 +酒鬼 1 +x:1 +厅局级 1 +x:1 +适量 1 +x:1 +飞奔 1 +x:1 +营业房 1 +x:1 +阴凉 1 +x:1 +瓜香 1 +x:1 +幼株 1 +x:1 +罢 68 +x:68 +广泛 1 +x:1 +迎风破浪 1 +x:1 +幼树 1 +x:1 +更换 1 +x:1 +轰鸣 1 +x:1 +谪守 1 +x:1 +大幅度 1 +x:1 +我一语 1 +x:1 +高空作业 1 +x:1 +日落而息 1 +x:1 +选段 1 +x:1 +广水 1 +x:1 +聚酯薄膜 1 +x:1 +倓 1 +x:1 +两三时 1 +x:1 +弹药库 1 +x:1 +图片展 1 +x:1 +圆周角 1 +x:1 +起跳台 1 +x:1 +除了 1 +x:1 +赋予 1 +x:1 +打算 1 +x:1 +保卫战 1 +x:1 +耳 63 +x:63 +旅游法 1 +x:1 +絮语 1 +x:1 +单行道 1 +x:1 +脏乱差 1 +x:1 +清闲自在 1 +x:1 +林边 1 +x:1 +高压线 1 +x:1 +广汽 1 +x:1 +嘶叫 1 +x:1 +红花岗区 1 +x:1 +除以 1 +x:1 +吊睛白额 1 +x:1 +狼嚎 1 +x:1 +嘉言 1 +x:1 +毁誉参半 1 +x:1 +等差级数 1 +x:1 +左半 1 +x:1 +圈儿 1 +x:1 +装饰品 1 +x:1 +五岔沟 1 +x:1 +云林 1 +x:1 +牛角梭 1 +x:1 +定地 1 +x:1 +无则加勉 1 +x:1 +凶悍 1 +x:1 +濉溪县 1 +x:1 +电讯 1 +x:1 +可能性 1 +x:1 +广汉 1 +x:1 +缺水区 1 +x:1 +牛角梳 1 +x:1 +七彩龟 1 +x:1 +卖命 1 +x:1 +游联 1 +x:1 +覃 24 +x:24 +艘次 1 +x:1 +喜烟 1 +x:1 +湖南 1 +x:1 +下陆区 1 +x:1 +冬练三九 1 +x:1 +宝岛 1 +x:1 +挑水者 1 +x:1 +水源地 1 +x:1 +心扉 1 +x:1 +因数 1 +x:1 +恣意妄为 1 +x:1 +腊鱼 1 +x:1 +瑞签 1 +x:1 +金闪闪 1 +x:1 +出口不凡 1 +x:1 +转院 1 +x:1 +购货者 1 +x:1 +苦木树 1 +x:1 +群情 1 +x:1 +念念有词 1 +x:1 +叨咕 1 +x:1 +立誓 1 +x:1 +演讲会 1 +x:1 +盾牌 1 +x:1 +德 370 +x:370 +文凭 1 +x:1 +折寿 1 +x:1 +助威声 1 +x:1 +爆发 1 +x:1 +龙母 1 +x:1 +双循环 1 +x:1 +农贷 1 +x:1 +打穴 1 +x:1 +商品猪 1 +x:1 +血斑 1 +x:1 +金沙萨 1 +x:1 +干休所 1 +x:1 +母公司 1 +x:1 +产权人 1 +x:1 +清一色 1 +x:1 +俄文楼 1 +x:1 +嘉许 1 +x:1 +实验院 1 +x:1 +龙潭湖 1 +x:1 +缙云山 1 +x:1 +淫 5 +x:5 +馥郁 1 +x:1 +中宁县 1 +x:1 +石头寨村 1 +x:1 +转阴 1 +x:1 +校内 1 +x:1 +坞乡集 1 +x:1 +坚固 1 +x:1 +福分 1 +x:1 +七彩鸟 1 +x:1 +大通河 1 +x:1 +符号串 1 +x:1 +一声令下 1 +x:1 +各有所好 1 +x:1 +农贸 1 +x:1 +曲艺队 1 +x:1 +股值 1 +x:1 +文具 1 +x:1 +文兴 1 +x:1 +适逢 1 +x:1 +钦 38 +x:38 +家鸽 1 +x:1 +身处 1 +x:1 +打窖 1 +x:1 +宣内 1 +x:1 +输出入 1 +x:1 +卖唱 1 +x:1 +荷衣面 1 +x:1 +蝎毒 1 +x:1 +朱中镇 1 +x:1 +违禁品 1 +x:1 +含嗔轻诉 1 +x:1 +头坝 1 +x:1 +隋末 1 +x:1 +大半年 1 +x:1 +赠品 1 +x:1 +会计证 1 +x:1 +棋赛 1 +x:1 +奎苏乡 1 +x:1 +许都 1 +x:1 +宁晋县 1 +x:1 +自查 1 +x:1 +蝎 4 +x:4 +大洋坝 1 +x:1 +劝慰 1 +x:1 +男式 1 +x:1 +刑名 1 +x:1 +堪称一绝 1 +x:1 +祈谷 1 +x:1 +机灵鬼 1 +x:1 +赔笑 1 +x:1 +转隶 1 +x:1 +八面威风 1 +x:1 +开拓进取 1 +x:1 +钢琴厂 1 +x:1 +沙荒地 1 +x:1 +赘述 1 +x:1 +接标 1 +x:1 +隋朝 1 +x:1 +吸储 1 +x:1 +挨饿 1 +x:1 +以东 1 +x:1 +公假 1 +x:1 +白条肉 1 +x:1 +山丘 1 +x:1 +缤纷 1 +x:1 +山东 1 +x:1 +颏 1 +x:1 +宣判 1 +x:1 +亲侄 1 +x:1 +美容器 1 +x:1 +哈蜜瓜 1 +x:1 +自民党 1 +x:1 +酗酒 1 +x:1 +阴历 1 +x:1 +酒饭 1 +x:1 +山下 1 +x:1 +山上 1 +x:1 +盈怀 1 +x:1 +飘动 1 +x:1 +中山市 1 +x:1 +天星堰村 1 +x:1 +山丹 1 +x:1 +才貌 1 +x:1 +诗书门第 1 +x:1 +巫术 1 +x:1 +游移 1 +x:1 +中山大学 1 +x:1 +浅成岩 1 +x:1 +塑料盆 1 +x:1 +评审费 1 +x:1 +将军 1 +x:1 +南娄乡 1 +x:1 +鲜鲜亮亮 1 +x:1 +从没 1 +x:1 +对立物 1 +x:1 +活动者 1 +x:1 +鳕鱼 1 +x:1 +猎物 1 +x:1 +双循环赛 1 +x:1 +弹丸 1 +x:1 +牵住 1 +x:1 +慢 127 +x:127 +小麦秆 1 +x:1 +促膝谈心 1 +x:1 +非税 1 +x:1 +知县 1 +x:1 +阴差阳错 1 +x:1 +莱州市 1 +x:1 +跳楼 1 +x:1 +默然 1 +x:1 +翼手龙 1 +x:1 +山乡 1 +x:1 +蔓蔓 1 +x:1 +土肥站 1 +x:1 +主叫方 1 +x:1 +亲信 1 +x:1 +铜筋铁骨 1 +x:1 +卖国 1 +x:1 +国土厅 1 +x:1 +爽爽然 1 +x:1 +语态 1 +x:1 +重温旧梦 1 +x:1 +武陵源 1 +x:1 +本镇 1 +x:1 +聚讼纷纭 1 +x:1 +指数性 1 +x:1 +有光纸 1 +x:1 +一专多能 1 +x:1 +头名 1 +x:1 +自行车厂 1 +x:1 +血晕 1 +x:1 +电视 1 +x:1 +浓度 1 +x:1 +下花园 1 +x:1 +八九月 1 +x:1 +黑压压 1 +x:1 +挪威队 1 +x:1 +群众化 1 +x:1 +寂灭 1 +x:1 +山人 1 +x:1 +用款国 1 +x:1 +肛管 1 +x:1 +钟点工 1 +x:1 +干支沟 1 +x:1 +团总支 1 +x:1 +村社党 1 +x:1 +珠贝 1 +x:1 +甲状软骨 1 +x:1 +壮美 1 +x:1 +雄文 1 +x:1 +边缘化 1 +x:1 +捐款 1 +x:1 +乐儿 1 +x:1 +游艺 1 +x:1 +野鹿 1 +x:1 +麦金西 1 +x:1 +全罗南道 1 +x:1 +跳槽 1 +x:1 +酒香 1 +x:1 +安达市 1 +x:1 +诮 1 +x:1 +酒馆 1 +x:1 +蓝领 1 +x:1 +筹 46 +x:46 +打私 1 +x:1 +维斯瓦 1 +x:1 +胖墩儿 1 +x:1 +懦弱 1 +x:1 +男工 1 +x:1 +宝库 1 +x:1 +修修改改 1 +x:1 +打破 1 +x:1 +拆迁 1 +x:1 +输注 1 +x:1 +延陵 1 +x:1 +小局 1 +x:1 +文友 1 +x:1 +亲事 1 +x:1 +文号 1 +x:1 +文史 1 +x:1 +亲亲 1 +x:1 +初试锋芒 1 +x:1 +供销员 1 +x:1 +急救盒 1 +x:1 +亲人 1 +x:1 +阻断性 1 +x:1 +嵩山 1 +x:1 +宝座 1 +x:1 +电表 1 +x:1 +随请随到 1 +x:1 +崇祯 1 +x:1 +拿下 1 +x:1 +黄澄澄 1 +x:1 +宣化 1 +x:1 +山体 1 +x:1 +渥太华市 1 +x:1 +埠 2 +x:2 +盘王节 1 +x:1 +才路 1 +x:1 +如醉如狂 1 +x:1 +嵌 18 +x:18 +深夜 1 +x:1 +监 7 +x:7 +里头 1 +x:1 +房屋基 1 +x:1 +最惠国 1 +x:1 +休渔 1 +x:1 +荒古 1 +x:1 +新华书店 1 +x:1 +文县 1 +x:1 +爆出 1 +x:1 +马龙县 1 +x:1 +车损险 1 +x:1 +律师 1 +x:1 +里外 1 +x:1 +监利县 1 +x:1 +御寒 1 +x:1 +除恶务尽 1 +x:1 +发起人 1 +x:1 +亲代 1 +x:1 +催命 1 +x:1 +翕动 1 +x:1 +黝黑 1 +x:1 +乌桕树 1 +x:1 +含炭量 1 +x:1 +语意 1 +x:1 +文博 1 +x:1 +宛如 1 +x:1 +丁当 1 +x:1 +招待会 1 +x:1 +喷墨 1 +x:1 +文协 1 +x:1 +上升村 1 +x:1 +菁华 1 +x:1 +手提袋 1 +x:1 +常青不衰 1 +x:1 +广漠 1 +x:1 +文卷 1 +x:1 +低级者 1 +x:1 +客观 1 +x:1 +股分 1 +x:1 +马拉坎 1 +x:1 +酒食 1 +x:1 +明珠投暗 1 +x:1 +打碎 1 +x:1 +水泊梁山 1 +x:1 +中左 1 +x:1 +文化 1 +x:1 +手到病除 1 +x:1 +殷殷然 1 +x:1 +果树 1 +x:1 +游荡 1 +x:1 +无从下手 1 +x:1 +输水 1 +x:1 +跳棋 1 +x:1 +打磨 1 +x:1 +上升期 1 +x:1 +西龙门村 1 +x:1 +准尉 1 +x:1 +输氧 1 +x:1 +大通港 1 +x:1 +过程论 1 +x:1 +摇把子 1 +x:1 +喜爱 1 +x:1 +如花似锦 1 +x:1 +宣誓者 1 +x:1 +大路坡 1 +x:1 +获悉 1 +x:1 +寂然 1 +x:1 +星火 1 +x:1 +爬山 1 +x:1 +宣发 1 +x:1 +为虎作伥 1 +x:1 +行驶证 1 +x:1 +猎奇者 1 +x:1 +跟进 1 +x:1 +戏车 1 +x:1 +* 180 +x:180 +忙里偷闲 1 +x:1 +军士长 1 +x:1 +爱理不理 1 +x:1 +举目四望 1 +x:1 +外蒙 1 +x:1 +营口 1 +x:1 +诟病 1 +x:1 +攒动 1 +x:1 +辩护 1 +x:1 +取长补短 1 +x:1 +龙马湖 1 +x:1 +归宿点 1 +x:1 +面馆 1 +x:1 +经验 1 +x:1 +后宰门 1 +x:1 +面馍 1 +x:1 +焚烧炉 1 +x:1 +墨城 1 +x:1 +监理 1 +x:1 +开口子 1 +x:1 +迎迓 1 +x:1 +气势磅礴 1 +x:1 +地区差价 1 +x:1 +零取 1 +x:1 +上周一 1 +x:1 +独立团 1 +x:1 +节奏 1 +x:1 +退职 1 +x:1 +蓝靛 1 +x:1 +出场 1 +x:1 +西五路 1 +x:1 +崇明 1 +x:1 +巫神 1 +x:1 +话剧史 1 +x:1 +通海 1 +x:1 +家规 1 +x:1 +发高烧 1 +x:1 +双画面 1 +x:1 +骑缝 1 +x:1 +颤巍巍 1 +x:1 +庄稼院 1 +x:1 +建设省 1 +x:1 +出土 1 +x:1 +小将 1 +x:1 +打杂 1 +x:1 +客队 1 +x:1 +扶优汰劣 1 +x:1 +吃 1447 +x:1447 +天青 1 +x:1 +树枝 1 +x:1 +旅游热 1 +x:1 +转诊 1 +x:1 +打架 1 +x:1 +步行区 1 +x:1 +打枪 1 +x:1 +伪政权 1 +x:1 +莫高窟 1 +x:1 +戏迷 1 +x:1 +逶迤 1 +x:1 +骨坏死病 1 +x:1 +书目型 1 +x:1 +那段 1 +x:1 +百折不回 1 +x:1 +场里 1 +x:1 +绵羊毛 1 +x:1 +誉称 1 +x:1 +亲儿 1 +x:1 +白条鸭 1 +x:1 +兴奋状 1 +x:1 +旁边 1 +x:1 +存钱 1 +x:1 +劳工 1 +x:1 +违约金 1 +x:1 +穷原竟委 1 +x:1 +杀风景 1 +x:1 +脚射 1 +x:1 +果真 1 +x:1 +广灵 1 +x:1 +苌 1 +x:1 +田径史 1 +x:1 +剥落 1 +x:1 +宜小则小 1 +x:1 +游鱼 1 +x:1 +脚尖 1 +x:1 +爱鸟护鸟 1 +x:1 +电压计 1 +x:1 +旅游点 1 +x:1 +惠 21 +x:21 +互助点 1 +x:1 +信札 1 +x:1 +转让 1 +x:1 +辩才 1 +x:1 +纸老虎 1 +x:1 +薄荷 1 +x:1 +金山区 1 +x:1 +录取率 1 +x:1 +和平权 1 +x:1 +伸手派 1 +x:1 +引航 1 +x:1 +弹入 1 +x:1 +素酒 1 +x:1 +井 165 +x:165 +群系 1 +x:1 +和平村 1 +x:1 +羞羞答答 1 +x:1 +阿莱曼 1 +x:1 +灌 28 +x:28 +味儿 1 +x:1 +粉白 1 +x:1 +洱海 1 +x:1 +朝阳镇 1 +x:1 +缀连 1 +x:1 +幼畜 1 +x:1 +生油层 1 +x:1 +面颊 1 +x:1 +墨囊 1 +x:1 +清汤 1 +x:1 +隔靴搔痒 1 +x:1 +缴 105 +x:105 +面额 1 +x:1 +孔明灯 1 +x:1 +喜泪 1 +x:1 +大有文章 1 +x:1 +刹车板 1 +x:1 +无神论者 1 +x:1 +庞伟 1 +x:1 +热交换 1 +x:1 +自然光 1 +x:1 +进口商 1 +x:1 +泡茶 1 +x:1 +除却 1 +x:1 +油炸鬼 1 +x:1 +强化 1 +x:1 +中巴 1 +x:1 +功夫片 1 +x:1 +月事 1 +x:1 +有灾必救 1 +x:1 +叫驴 1 +x:1 +果皮 1 +x:1 +雷利赞 1 +x:1 +面食 1 +x:1 +亚佩克 1 +x:1 +叫骂 1 +x:1 +得 5482 +x:5482 +集主 1 +x:1 +雄立 1 +x:1 +朝阳门 1 +x:1 +粉盒 1 +x:1 +舍 46 +x:46 +山农 1 +x:1 +嘉靖 1 +x:1 +出国 1 +x:1 +聂庄村 1 +x:1 +除去 1 +x:1 +山冈 1 +x:1 +成分论 1 +x:1 +会荒 1 +x:1 +法典 1 +x:1 +地震带 1 +x:1 +分会场 1 +x:1 +曾经沧海 1 +x:1 +走味儿 1 +x:1 +龙眼 1 +x:1 +团体票 1 +x:1 +泡菜 1 +x:1 +信马由缰 1 +x:1 +喜气 1 +x:1 +一颦一笑 1 +x:1 +宏大 1 +x:1 +法共 1 +x:1 +变局 1 +x:1 +廊 10 +x:10 +打更 1 +x:1 +为国捐躯 1 +x:1 +赔本 1 +x:1 +外长级 1 +x:1 +腊肉 1 +x:1 +泰达队 1 +x:1 +图像型 1 +x:1 +除号 1 +x:1 +用车者 1 +x:1 +雷达兵 1 +x:1 +山凹 1 +x:1 +舌面前音 1 +x:1 +宁武镇 1 +x:1 +医师法 1 +x:1 +跟踪 1 +x:1 +回目 1 +x:1 +粉皮 1 +x:1 +腊肠 1 +x:1 +康熙 1 +x:1 +家计 1 +x:1 +真善美 1 +x:1 +礼花 1 +x:1 +挥挥 1 +x:1 +余光 1 +x:1 +表象 1 +x:1 +混交林 1 +x:1 +家训 1 +x:1 +省城 1 +x:1 +哗哗 1 +x:1 +亲历 1 +x:1 +肃贪倡廉 1 +x:1 +药香 1 +x:1 +化 108 +x:108 +忆及 1 +x:1 +歉收 1 +x:1 +电镀 1 +x:1 +麻辣烫 1 +x:1 +家访 1 +x:1 +文件 1 +x:1 +如雷似火 1 +x:1 +漫不经心 1 +x:1 +还款率 1 +x:1 +连铸机 1 +x:1 +组照 1 +x:1 +静悄悄 1 +x:1 +遮风挡雨 1 +x:1 +回电 1 +x:1 +大杂院儿 1 +x:1 +特写大书 1 +x:1 +礼节 1 +x:1 +恶疾 1 +x:1 +救生舱 1 +x:1 +宣东 1 +x:1 +裆部 1 +x:1 +肩膀 1 +x:1 +力学会 1 +x:1 +篝火 1 +x:1 +救生艇 1 +x:1 +出售 1 +x:1 +变心 1 +x:1 +群群 1 +x:1 +沦落 1 +x:1 +正确率 1 +x:1 +一望无际 1 +x:1 +节子 1 +x:1 +树杈 1 +x:1 +桃体 1 +x:1 +润笔 1 +x:1 +高尔夫球 1 +x:1 +轻装简从 1 +x:1 +亲友 1 +x:1 +剧照 1 +x:1 +骆驼 1 +x:1 +鹅观草 1 +x:1 +退色 1 +x:1 +驰 17 +x:17 +电锯 1 +x:1 +电键 1 +x:1 +亲口 1 +x:1 +杂草丛生 1 +x:1 +肩臂 1 +x:1 +语系 1 +x:1 +痨病 1 +x:1 +戏路 1 +x:1 +输水渠 1 +x:1 +正投影 1 +x:1 +变异 1 +x:1 +粘结力 1 +x:1 +支撑力 1 +x:1 +小岭 1 +x:1 +延误 1 +x:1 +学习班 1 +x:1 +金属片 1 +x:1 +转角 1 +x:1 +会聚 1 +x:1 +螺旋藻 1 +x:1 +武秀才 1 +x:1 +颗粒剂 1 +x:1 +女神 1 +x:1 +积累性 1 +x:1 +躺柜 1 +x:1 +攥 15 +x:15 +电闸 1 +x:1 +打斜 1 +x:1 +打斗 1 +x:1 +山势 1 +x:1 +文书 1 +x:1 +电门 1 +x:1 +地图板 1 +x:1 +电闪 1 +x:1 +兴奋点 1 +x:1 +山道口 1 +x:1 +司机制 1 +x:1 +文丑 1 +x:1 +可敬可佩 1 +x:1 +可锻铸铁 1 +x:1 +文丛 1 +x:1 +会考 1 +x:1 +浊音 1 +x:1 +倒映成趣 1 +x:1 +棋技 1 +x:1 +大讲堂 1 +x:1 +弹劾 1 +x:1 +盘 292 +x:292 +南柯梦 1 +x:1 +僻 3 +x:3 +水电站 1 +x:1 +福建团 1 +x:1 +总编辑 1 +x:1 +变形 1 +x:1 +始发点 1 +x:1 +老夫子 1 +x:1 +亚戈迪纳 1 +x:1 +鸵鸟政策 1 +x:1 +打旋 1 +x:1 +弹力 1 +x:1 +琥珀酸 1 +x:1 +文中 1 +x:1 +筛骨 1 +x:1 +打砸抢烧 1 +x:1 +谬之千里 1 +x:1 +后盖板 1 +x:1 +文保 1 +x:1 +宣传 1 +x:1 +商水县 1 +x:1 +脚心 1 +x:1 +贵峰籍 1 +x:1 +山包 1 +x:1 +越南式 1 +x:1 +万发林 1 +x:1 +话不投机 1 +x:1 +那样 1 +x:1 +窃窃细语 1 +x:1 +塞克萨德 1 +x:1 +挥戈 1 +x:1 +再版书 1 +x:1 +山区 1 +x:1 +星河 1 +x:1 +左岸 1 +x:1 +干涉仪 1 +x:1 +社保局 1 +x:1 +欧美 1 +x:1 +崇敬 1 +x:1 +打搅 1 +x:1 +受援地 1 +x:1 +青瓦台 1 +x:1 +山南 1 +x:1 +壮戏 1 +x:1 +图谱 1 +x:1 +身不由己 1 +x:1 +得之不易 1 +x:1 +立地 1 +x:1 +监督 1 +x:1 +巴哈马 1 +x:1 +大兴寨村 1 +x:1 +抵消 1 +x:1 +股价 1 +x:1 +恢复系 1 +x:1 +弊病 1 +x:1 +信差 1 +x:1 +股份 1 +x:1 +出名 1 +x:1 +肩胛 1 +x:1 +血管 1 +x:1 +孝顺 1 +x:1 +挥手 1 +x:1 +塘桥 1 +x:1 +图谋 1 +x:1 +大港区 1 +x:1 +译意风 1 +x:1 +可耕地 1 +x:1 +戏谑 1 +x:1 +马到成功 1 +x:1 +书声 1 +x:1 +乌兰巴托 1 +x:1 +会文山房 1 +x:1 +备 89 +x:89 +闻人 1 +x:1 +笑纳 1 +x:1 +上周二 1 +x:1 +唧唧 1 +x:1 +农投 1 +x:1 +谕 2 +x:2 +捡漏 1 +x:1 +作坊式 1 +x:1 +南兴镇 1 +x:1 +轮机手 1 +x:1 +一事当前 1 +x:1 +含水率 1 +x:1 +电铃 1 +x:1 +关连 1 +x:1 +哗啦 1 +x:1 +自控 1 +x:1 +电铸 1 +x:1 +一丝不挂 1 +x:1 +出品 1 +x:1 +电铲 1 +x:1 +镇江 1 +x:1 +铜金矿 1 +x:1 +逐辆 1 +x:1 +降水量 1 +x:1 +小岛 1 +x:1 +行政部 1 +x:1 +龙电 1 +x:1 +漠不相关 1 +x:1 +彤云 1 +x:1 +画报社 1 +x:1 +电钟 1 +x:1 +面善 1 +x:1 +僻巷 1 +x:1 +地震局 1 +x:1 +扇状 1 +x:1 +唧啾 1 +x:1 +捋 5 +x:5 +围三缺一 1 +x:1 +揭碑 1 +x:1 +变幅 1 +x:1 +崇文 1 +x:1 +桃仙 1 +x:1 +山参 1 +x:1 +电针 1 +x:1 +星汉 1 +x:1 +丈母 1 +x:1 +挥拳 1 +x:1 +劳庄 1 +x:1 +挥拍 1 +x:1 +电钻 1 +x:1 +矛头 1 +x:1 +尚义县 1 +x:1 +强压 1 +x:1 +电钳 1 +x:1 +苦辣酸甜 1 +x:1 +变幻 1 +x:1 +山口 1 +x:1 +电钮 1 +x:1 +文传 1 +x:1 +打擂 1 +x:1 +养生功 1 +x:1 +总结会 1 +x:1 +没深没浅 1 +x:1 +专用车 1 +x:1 +冻干 1 +x:1 +接站车 1 +x:1 +操守 1 +x:1 +记挂 1 +x:1 +血糖 1 +x:1 +浸湿 1 +x:1 +平步青云 1 +x:1 +遏制 1 +x:1 +酒药 1 +x:1 +大粪球 1 +x:1 +戴月披星 1 +x:1 +山后 1 +x:1 +鱼腹 1 +x:1 +头人 1 +x:1 +农运 1 +x:1 +化学纤维 1 +x:1 +进口值 1 +x:1 +切入点 1 +x:1 +三塘乡 1 +x:1 +五环旗 1 +x:1 +转轨 1 +x:1 +心猿意马 1 +x:1 +转轴 1 +x:1 +一不为名 1 +x:1 +中药界 1 +x:1 +龙口市 1 +x:1 +出卖 1 +x:1 +悲惋 1 +x:1 +萨克森州 1 +x:1 +峭岐镇 1 +x:1 +省内 1 +x:1 +虚位以待 1 +x:1 +婴儿 1 +x:1 +网球队 1 +x:1 +线路板 1 +x:1 +血粉 1 +x:1 +刚柔并济 1 +x:1 +不可动摇 1 +x:1 +毕 111 +x:111 +宾语 1 +x:1 +天祝 1 +x:1 +推心置腹 1 +x:1 +包子铺 1 +x:1 +打捞 1 +x:1 +浸渍 1 +x:1 +坚信 1 +x:1 +老街旧邻 1 +x:1 +背毛 1 +x:1 +铁白粉 1 +x:1 +胆红素 1 +x:1 +宾词 1 +x:1 +禽畜产品 1 +x:1 +打捆 1 +x:1 +转过 1 +x:1 +家财 1 +x:1 +韵事 1 +x:1 +转迁 1 +x:1 +包教包会 1 +x:1 +图说 1 +x:1 +出口 1 +x:1 +僚气 1 +x:1 +危在旦夕 1 +x:1 +应河 1 +x:1 +黄泥洼镇 1 +x:1 +打探 1 +x:1 +目染 1 +x:1 +家贼 1 +x:1 +府 28 +x:28 +别无出路 1 +x:1 +织金县 1 +x:1 +偷者 1 +x:1 +变天 1 +x:1 +酒菜 1 +x:1 +抵押权 1 +x:1 +种鸡场 1 +x:1 +圭 3 +x:3 +泗水县 1 +x:1 +墨华 1 +x:1 +转述 1 +x:1 +辩明 1 +x:1 +过得硬 1 +x:1 +联络线 1 +x:1 +出发 1 +x:1 +旁证 1 +x:1 +备案单 1 +x:1 +党同伐异 1 +x:1 +催促 1 +x:1 +繇 1 +x:1 +图记 1 +x:1 +名副其实 1 +x:1 +咨询队 1 +x:1 +东湖村 1 +x:1 +出去 1 +x:1 +夜郎自大 1 +x:1 +山响 1 +x:1 +地震学 1 +x:1 +主通道 1 +x:1 +电视电话 1 +x:1 +中东社 1 +x:1 +引力能 1 +x:1 +出厂 1 +x:1 +艺术化 1 +x:1 +峰 75 +x:75 +转达 1 +x:1 +石山区 1 +x:1 +龙王 1 +x:1 +酒色 1 +x:1 +伫立 1 +x:1 +预示 1 +x:1 +邮电史 1 +x:1 +职介所 1 +x:1 +钟楼杯 1 +x:1 +可可西里 1 +x:1 +粉牌 1 +x:1 +管理科学 1 +x:1 +七彩虹 1 +x:1 +诸侯王 1 +x:1 +马放南山 1 +x:1 +哗变 1 +x:1 +毫无用处 1 +x:1 +慕田峪关 1 +x:1 +错误率 1 +x:1 +总是 1 +x:1 +无证无照 1 +x:1 +封闭性 1 +x:1 +如醉如梦 1 +x:1 +行政院 1 +x:1 +霉雨 1 +x:1 +瓦尔登湖 1 +x:1 +节尾 1 +x:1 +不虞之誉 1 +x:1 +钓鱼台 1 +x:1 +浸漫 1 +x:1 +大众性 1 +x:1 +纵深行 1 +x:1 +有增无减 1 +x:1 +总额度 1 +x:1 +栽培 1 +x:1 +挨个儿 1 +x:1 +打扰 1 +x:1 +籼米 1 +x:1 +校准 1 +x:1 +打扫 1 +x:1 +洲际 1 +x:1 +灵山岛 1 +x:1 +根治性 1 +x:1 +打扮 1 +x:1 +弹唱 1 +x:1 +捣蛋鬼 1 +x:1 +小古庄 1 +x:1 +不法分子 1 +x:1 +打打 1 +x:1 +洒热血 1 +x:1 +戏言 1 +x:1 +打手 1 +x:1 +横丹乡 1 +x:1 +出列 1 +x:1 +太守府 1 +x:1 +特许者 1 +x:1 +诗文集 1 +x:1 +引导牌 1 +x:1 +拓荒者 1 +x:1 +出勤 1 +x:1 +广电 1 +x:1 +同轴电缆 1 +x:1 +尊严感 1 +x:1 +滑轮组 1 +x:1 +果片 1 +x:1 +收入者 1 +x:1 +文人学士 1 +x:1 +遂川 1 +x:1 +兰山区 1 +x:1 +乡村式 1 +x:1 +机器声 1 +x:1 +超前性 1 +x:1 +打折 1 +x:1 +拖三拉四 1 +x:1 +叔叔 1 +x:1 +大西山 1 +x:1 +中心校 1 +x:1 +亲吻 1 +x:1 +就 16877 +x:16877 +渗水 1 +x:1 +温度计 1 +x:1 +百衲本 1 +x:1 +粉妆女子 1 +x:1 +信汇 1 +x:1 +云纱 1 +x:1 +共和派 1 +x:1 +出动 1 +x:1 +存量 1 +x:1 +数据链 1 +x:1 +打拳 1 +x:1 +疗法 1 +x:1 +羞耻心 1 +x:1 +噪声源 1 +x:1 +煤层气 1 +x:1 +书斋式 1 +x:1 +杂交种 1 +x:1 +找出路 1 +x:1 +转身 1 +x:1 +粉状 1 +x:1 +出力 1 +x:1 +脚头 1 +x:1 +旧石器 1 +x:1 +余江县 1 +x:1 +技委 1 +x:1 +机器字 1 +x:1 +缆 13 +x:13 +攻读 1 +x:1 +出入 1 +x:1 +薄薄 1 +x:1 +出典 1 +x:1 +升华 1 +x:1 +出兵 1 +x:1 +不好意思 1 +x:1 +出具 1 +x:1 +血统 1 +x:1 +杂交稻 1 +x:1 +水力 1 +x:1 +现代人 1 +x:1 +除名 1 +x:1 +山嘴 1 +x:1 +转赠 1 +x:1 +伦 7 +x:7 +青年宫 1 +x:1 +船头 1 +x:1 +不得要领 1 +x:1 +商品案 1 +x:1 +莹 20 +x:20 +中心段 1 +x:1 +镇江市 1 +x:1 +出兑 1 +x:1 +过节费 1 +x:1 +意见箱 1 +x:1 +淋巴腺 1 +x:1 +夸口 1 +x:1 +节录 1 +x:1 +监牢 1 +x:1 +瓶贴 1 +x:1 +攻讦 1 +x:1 +观驾山 1 +x:1 +川 93 +x:93 +普通班 1 +x:1 +血红 1 +x:1 +同等学历 1 +x:1 +应付款 1 +x:1 +克罗地亚 1 +x:1 +线性方程 1 +x:1 +挥杆 1 +x:1 +狂风怒号 1 +x:1 +匈奴 1 +x:1 +转贷 1 +x:1 +肆无忌弹 1 +x:1 +组画 1 +x:1 +卖价 1 +x:1 +主婚人 1 +x:1 +人类学家 1 +x:1 +省去 1 +x:1 +温度表 1 +x:1 +外文书 1 +x:1 +酒吧台 1 +x:1 +一品红 1 +x:1 +少生快富 1 +x:1 +吐谷浑 1 +x:1 +渗漏 1 +x:1 +怨声 1 +x:1 +浸泡 1 +x:1 +节律 1 +x:1 +集众思 1 +x:1 +电量 1 +x:1 +霍山 1 +x:1 +颇具匠心 1 +x:1 +出出 1 +x:1 +出击 1 +x:1 +发源地 1 +x:1 +图解 1 +x:1 +班门弄斧 1 +x:1 +监犯 1 +x:1 +资产额 1 +x:1 +齐齐 1 +x:1 +喜光植物 1 +x:1 +门诊室 1 +x:1 +目无 1 +x:1 +生产率 1 +x:1 +长袍儿 1 +x:1 +玮 5 +x:5 +商品棉 1 +x:1 +软刀子 1 +x:1 +省却 1 +x:1 +吃不起 1 +x:1 +省市区 1 +x:1 +房屋业 1 +x:1 +淳佑九年 1 +x:1 +监狱 1 +x:1 +手书字 1 +x:1 +泰姬陵 1 +x:1 +旁观 1 +x:1 +事不过三 1 +x:1 +郄 5 +x:5 +唱对台戏 1 +x:1 +坐待 1 +x:1 +货郎图 1 +x:1 +输电 1 +x:1 +许诺 1 +x:1 +皮鲁兹队 1 +x:1 +卖乖 1 +x:1 +僻壤 1 +x:1 +不出所料 1 +x:1 +博学院 1 +x:1 +变子 1 +x:1 +捐献 1 +x:1 +观音阁 1 +x:1 +圃 2 +x:2 +果然 1 +x:1 +浸沉 1 +x:1 +龙灯 1 +x:1 +土肥所 1 +x:1 +山国 1 +x:1 +茂物 1 +x:1 +地霉素 1 +x:1 +忠诚感 1 +x:1 +林间 1 +x:1 +喜欢 1 +x:1 +劳宣 1 +x:1 +语素 1 +x:1 +省区 1 +x:1 +河北杨 1 +x:1 +碳塑 1 +x:1 +戏衣 1 +x:1 +毒气弹头 1 +x:1 +图表 1 +x:1 +通气 1 +x:1 +叔公 1 +x:1 +祖母 1 +x:1 +天诛地灭 1 +x:1 +倚 14 +x:14 +永登县 1 +x:1 +大是大非 1 +x:1 +戏行 1 +x:1 +妖里妖气 1 +x:1 +小潢河 1 +x:1 +涓水之滨 1 +x:1 +粉灰 1 +x:1 +山场 1 +x:1 +甬 7 +x:7 +景阳岗 1 +x:1 +横渡 1 +x:1 +精神性 1 +x:1 +记性 1 +x:1 +龙沙 1 +x:1 +突马特 1 +x:1 +弹坑 1 +x:1 +谱表 1 +x:1 +自费生 1 +x:1 +霍州 1 +x:1 +淤地坝 1 +x:1 +塘水 1 +x:1 +导游员 1 +x:1 +生产物 1 +x:1 +宣炉 1 +x:1 +语种 1 +x:1 +执勤点 1 +x:1 +律动 1 +x:1 +古谣 1 +x:1 +滑 90 +x:90 +帮扶带 1 +x:1 +南梆子 1 +x:1 +拉塔基亚 1 +x:1 +最优化 1 +x:1 +零售点 1 +x:1 +司处级 1 +x:1 +山坳 1 +x:1 +保卫科 1 +x:1 +勘探井 1 +x:1 +敞篷 1 +x:1 +山坡 1 +x:1 +酒者 1 +x:1 +淫乱 1 +x:1 +回火 1 +x:1 +酒考 1 +x:1 +稳进快出 1 +x:1 +记恨 1 +x:1 +山坪 1 +x:1 +同等学力 1 +x:1 +重灾户 1 +x:1 +浸淫 1 +x:1 +节庆 1 +x:1 +福建厅 1 +x:1 +舌状花 1 +x:1 +柴米油盐 1 +x:1 +云系 1 +x:1 +肺结核 1 +x:1 +从略 1 +x:1 +溯源 1 +x:1 +克隆牛 1 +x:1 +自然型 1 +x:1 +回炉 1 +x:1 +磁路 1 +x:1 +捐物 1 +x:1 +旋光性 1 +x:1 +沂蒙 1 +x:1 +骞 9 +x:9 +美洲 1 +x:1 +币面 1 +x:1 +引导灯 1 +x:1 +暮气 1 +x:1 +戏装 1 +x:1 +精神病科 1 +x:1 +打成一片 1 +x:1 +国务委员 1 +x:1 +塘沽 1 +x:1 +谅山省 1 +x:1 +谨言慎行 1 +x:1 +大众报 1 +x:1 +不法之徒 1 +x:1 +哂 2 +x:2 +白色棉 1 +x:1 +健忘症 1 +x:1 +火管枪 1 +x:1 +浸润 1 +x:1 +马提尼克 1 +x:1 +运 268 +x:268 +千分制 1 +x:1 +血缘 1 +x:1 +大仁大智 1 +x:1 +天真烂漫 1 +x:1 +子弟兵 1 +x:1 +旧体诗 1 +x:1 +莼菜 1 +x:1 +西王母 1 +x:1 +三色旗 1 +x:1 +阴着儿 1 +x:1 +中英街 1 +x:1 +名不副实 1 +x:1 +输球 1 +x:1 +田家会镇 1 +x:1 +叭儿狗 1 +x:1 +俯伏 1 +x:1 +出彩 1 +x:1 +论坛会 1 +x:1 +胜算 1 +x:1 +知足常乐 1 +x:1 +律己 1 +x:1 +情侣 1 +x:1 +古交市 1 +x:1 +冷热水 1 +x:1 +来回来去 1 +x:1 +葡萄园主 1 +x:1 +陪同 1 +x:1 +敲打 1 +x:1 +杭州路 1 +x:1 +牵头 1 +x:1 +强买强卖 1 +x:1 +中沙镇 1 +x:1 +闲散 1 +x:1 +永 187 +x:187 +信尾 1 +x:1 +礼袋 1 +x:1 +统筹金 1 +x:1 +乡乡镇镇 1 +x:1 +测雨站 1 +x:1 +特许费 1 +x:1 +翅 7 +x:7 +山塘 1 +x:1 +外汇率 1 +x:1 +眉眼高低 1 +x:1 +标兵船 1 +x:1 +干云蔽日 1 +x:1 +血雨腥风 1 +x:1 +生出 1 +x:1 +体细胞 1 +x:1 +百感交集 1 +x:1 +救生衣 1 +x:1 +经七路 1 +x:1 +狗皮 1 +x:1 +目次 1 +x:1 +挺杆 1 +x:1 +库命令 1 +x:1 +礼治 1 +x:1 +无绳话机 1 +x:1 +桃江路 1 +x:1 +活地狱 1 +x:1 +漂染厂 1 +x:1 +三屉桌 1 +x:1 +替 115 +x:115 +星期 1 +x:1 +分公司 1 +x:1 +获知 1 +x:1 +锉 1 +x:1 +定向招生 1 +x:1 +始发站 1 +x:1 +变现性 1 +x:1 +建筑学 1 +x:1 +信赖感 1 +x:1 +柔情绰态 1 +x:1 +工资本 1 +x:1 +草底儿 1 +x:1 +剪报 1 +x:1 +弹壳 1 +x:1 +自打 1 +x:1 +黔南州 1 +x:1 +当阳市 1 +x:1 +挨近 1 +x:1 +闭关自守 1 +x:1 +控制点 1 +x:1 +扬眉吐气 1 +x:1 +挨边 1 +x:1 +追交 1 +x:1 +准 359 +x:359 +节减 1 +x:1 +患 276 +x:276 +山壁 1 +x:1 +闲文 1 +x:1 +地脚棉 1 +x:1 +攻击手 1 +x:1 +乐律 1 +x:1 +沥青路 1 +x:1 +理屈词穷 1 +x:1 +拖曳阵 1 +x:1 +铅化物 1 +x:1 +卒业 1 +x:1 +度假区 1 +x:1 +执法犯法 1 +x:1 +补益 1 +x:1 +声嘶力竭 1 +x:1 +孝文帝 1 +x:1 +哈哈镜 1 +x:1 +征管法 1 +x:1 +窃电者 1 +x:1 +鸣谢碑 1 +x:1 +南后街 1 +x:1 +报告会 1 +x:1 +忙音 1 +x:1 +红豆杉 1 +x:1 +出徒 1 +x:1 +雄牌 1 +x:1 +四面八方 1 +x:1 +问柳寻花 1 +x:1 +会诊 1 +x:1 +丑闻 1 +x:1 +选送 1 +x:1 +专制主义 1 +x:1 +进取篇 1 +x:1 +亮度 1 +x:1 +胸怀大局 1 +x:1 +会试 1 +x:1 +作曲家 1 +x:1 +车辆厂 1 +x:1 +车旅费 1 +x:1 +山头 1 +x:1 +控 39 +x:39 +引渡 1 +x:1 +反坦克雷 1 +x:1 +偷越 1 +x:1 +宛似 1 +x:1 +实验舱 1 +x:1 +红岩队 1 +x:1 +低迷 1 +x:1 +延聘 1 +x:1 +颖悟 1 +x:1 +译名 1 +x:1 +数据项 1 +x:1 +出席 1 +x:1 +节假 1 +x:1 +杂话 1 +x:1 +面部 1 +x:1 +商管委 1 +x:1 +压痛 1 +x:1 +报告人 1 +x:1 +败家子 1 +x:1 +报请 1 +x:1 +弹头 1 +x:1 +会议 1 +x:1 +出师 1 +x:1 +从简 1 +x:1 +现当代 1 +x:1 +会计 1 +x:1 +组稿 1 +x:1 +大白天 1 +x:1 +靴 2 +x:2 +非贤不肖 1 +x:1 +漩流 1 +x:1 +赋存 1 +x:1 +不教而诛 1 +x:1 +究办 1 +x:1 +星星 1 +x:1 +省局 1 +x:1 +书目库 1 +x:1 +报告书 1 +x:1 +私有化 1 +x:1 +尽心竭力 1 +x:1 +风兰 1 +x:1 +打铁趁热 1 +x:1 +颖 35 +x:35 +漩涡 1 +x:1 +窑业 1 +x:1 +除害 1 +x:1 +省属 1 +x:1 +校 203 +x:203 +忠实笃行 1 +x:1 +山妹 1 +x:1 +造纸术 1 +x:1 +获益 1 +x:1 +阿族人 1 +x:1 +桑象虫 1 +x:1 +封资修 1 +x:1 +跳级 1 +x:1 +收发货 1 +x:1 +出庭 1 +x:1 +券桥乡 1 +x:1 +人权观 1 +x:1 +交流日 1 +x:1 +吉安县 1 +x:1 +囊 2 +x:2 +劝留 1 +x:1 +瓮声瓮气 1 +x:1 +道心 1 +x:1 +千分尺 1 +x:1 +两三点 1 +x:1 +随想式 1 +x:1 +偷走 1 +x:1 +普卡拉姆 1 +x:1 +急转弯 1 +x:1 +衡 18 +x:18 +打滚 1 +x:1 +乃至于 1 +x:1 +绥棱县 1 +x:1 +跳绳 1 +x:1 +打滑 1 +x:1 +氯化铵 1 +x:1 +杀人洞 1 +x:1 +真象 1 +x:1 +墨市 1 +x:1 +变味 1 +x:1 +粉红 1 +x:1 +女郎 1 +x:1 +变型 1 +x:1 +省心 1 +x:1 +逝世 1 +x:1 +壮歌 1 +x:1 +天文历算 1 +x:1 +霓裳王国 1 +x:1 +星斗 1 +x:1 +电子层 1 +x:1 +山娃 1 +x:1 +送货人 1 +x:1 +显而易见 1 +x:1 +轻体房 1 +x:1 +亲家 1 +x:1 +猝然 1 +x:1 +裘皮 1 +x:1 +十字街 1 +x:1 +古曲 1 +x:1 +立方厘米 1 +x:1 +敲竹杠 1 +x:1 +景阳冈 1 +x:1 +售房 1 +x:1 +小子 1 +x:1 +自相惊扰 1 +x:1 +水力部 1 +x:1 +药量 1 +x:1 +坎门镇 1 +x:1 +坐立不稳 1 +x:1 +振业堂 1 +x:1 +老皇历 1 +x:1 +喜果 1 +x:1 +水利 1 +x:1 +德智体 1 +x:1 +乙醇 1 +x:1 +亲密 1 +x:1 +琐屑 1 +x:1 +已婚 1 +x:1 +矿溶水 1 +x:1 +钓鱼岛 1 +x:1 +小器作 1 +x:1 +宪队 1 +x:1 +赏光 1 +x:1 +欧盟 1 +x:1 +栽倒 1 +x:1 +里亚尔 1 +x:1 +青泥洼桥 1 +x:1 +河南畈村 1 +x:1 +木鼓 1 +x:1 +羊圈 1 +x:1 +也就是说 1 +x:1 +天狗螺 1 +x:1 +成分股 1 +x:1 +翡翠 1 +x:1 +出差 1 +x:1 +西伯利亚 1 +x:1 +出工 1 +x:1 +大西南 1 +x:1 +出巡 1 +x:1 +叫醒 1 +x:1 +一步到位 1 +x:1 +原产机 1 +x:1 +凶相 1 +x:1 +砚师 1 +x:1 +监纪 1 +x:1 +洲际性 1 +x:1 +钱坂村 1 +x:1 +初印 1 +x:1 +津 105 +x:105 +平乡镇 1 +x:1 +种子袋 1 +x:1 +笺证稿 1 +x:1 +打消 1 +x:1 +惜售 1 +x:1 +丑陋 1 +x:1 +海红蜜 1 +x:1 +大流乡 1 +x:1 +一刻千金 1 +x:1 +亲子 1 +x:1 +报表 1 +x:1 +挥毫 1 +x:1 +馆旗 1 +x:1 +大西北 1 +x:1 +驾车者 1 +x:1 +嘴啃泥 1 +x:1 +微分 1 +x:1 +酒趣 1 +x:1 +绘 54 +x:54 +诀窍 1 +x:1 +龙公岭子 1 +x:1 +药酒 1 +x:1 +中心村 1 +x:1 +拉斯曼 1 +x:1 +荣列 1 +x:1 +梅东村 1 +x:1 +应纳税额 1 +x:1 +开航 1 +x:1 +果糖 1 +x:1 +身心 1 +x:1 +监缴 1 +x:1 +陡陡仄仄 1 +x:1 +外流 1 +x:1 +狮子会 1 +x:1 +会见 1 +x:1 +御侮 1 +x:1 +厅属 1 +x:1 +仗义执言 1 +x:1 +出山 1 +x:1 +礼让 1 +x:1 +天线 1 +x:1 +欣欣然 1 +x:1 +出局 1 +x:1 +果系 1 +x:1 +打气 1 +x:1 +节制 1 +x:1 +节外生枝 1 +x:1 +啼鹃 1 +x:1 +除外 1 +x:1 +巴黎公社 1 +x:1 +唾弃 1 +x:1 +旁落 1 +x:1 +弹孔 1 +x:1 +放任自流 1 +x:1 +吻合器 1 +x:1 +居功不傲 1 +x:1 +酒谱 1 +x:1 +常胜不衰 1 +x:1 +鬼画符 1 +x:1 +节前 1 +x:1 +转而 1 +x:1 +目标 1 +x:1 +萨满教 1 +x:1 +混血儿 1 +x:1 +崇洋 1 +x:1 +省府 1 +x:1 +果粉 1 +x:1 +青年团 1 +x:1 +卡通片 1 +x:1 +姜糖水 1 +x:1 +石 666 +x:666 +偷运 1 +x:1 +子午线 1 +x:1 +进人关 1 +x:1 +闪灼 1 +x:1 +超限额 1 +x:1 +漏征漏管 1 +x:1 +儇 1 +x:1 +社科系 1 +x:1 +飞云 1 +x:1 +电鳗 1 +x:1 +亲娘 1 +x:1 +领导组 1 +x:1 +到会者 1 +x:1 +生产线 1 +x:1 +浦北县 1 +x:1 +日月 1 +x:1 +雕制品 1 +x:1 +盲从 1 +x:1 +风气之先 1 +x:1 +完结率 1 +x:1 +飞人 1 +x:1 +天长 1 +x:1 +瓶胆 1 +x:1 +做好 1 +x:1 +倒果为因 1 +x:1 +储藏量 1 +x:1 +磁卡式 1 +x:1 +退让 1 +x:1 +氯化钠 1 +x:1 +前段 1 +x:1 +新宅乡 1 +x:1 +锯齿 1 +x:1 +工作员 1 +x:1 +融资方 1 +x:1 +宏博 1 +x:1 +音乐节 1 +x:1 +丹 48 +x:48 +匹夫有责 1 +x:1 +有口难分 1 +x:1 +省市 1 +x:1 +五六年 1 +x:1 +拍竣 1 +x:1 +人民公社 1 +x:1 +闲暇 1 +x:1 +一鼓足气 1 +x:1 +放在眼里 1 +x:1 +棒材 1 +x:1 +亲笔信 1 +x:1 +淤 26 +x:26 +自私自利 1 +x:1 +生产组 1 +x:1 +山寺 1 +x:1 +坛子岭 1 +x:1 +打法 1 +x:1 +机构 1 +x:1 +感染力 1 +x:1 +自然寨 1 +x:1 +转育 1 +x:1 +此情此景 1 +x:1 +山寨 1 +x:1 +滥套子 1 +x:1 +恽 2 +x:2 +那末 1 +x:1 +卧薪尝胆 1 +x:1 +井盖 1 +x:1 +山尖 1 +x:1 +〈 64 +x:64 +偷袭 1 +x:1 +四到位 1 +x:1 +卡通画 1 +x:1 +省委 1 +x:1 +挺挺 1 +x:1 +龙窑 1 +x:1 +显花植物 1 +x:1 +土专家 1 +x:1 +厅子 1 +x:1 +组网 1 +x:1 +优树 1 +x:1 +回笼 1 +x:1 +运动场 1 +x:1 +尔虞我诈 1 +x:1 +铁矾土 1 +x:1 +马迹塘 1 +x:1 +从细 1 +x:1 +果篮 1 +x:1 +礼貌 1 +x:1 +群燕 1 +x:1 +曹甸镇 1 +x:1 +挥洒 1 +x:1 +双井村 1 +x:1 +叠翠 1 +x:1 +商品房 1 +x:1 +务工地 1 +x:1 +抵抗 1 +x:1 +墨家 1 +x:1 +粉笔 1 +x:1 +疗效 1 +x:1 +半劳动力 1 +x:1 +町长 1 +x:1 +山居 1 +x:1 +墨客 1 +x:1 +葡萄沟乡 1 +x:1 +男人 1 +x:1 +山山 1 +x:1 +抵押 1 +x:1 +墨宝 1 +x:1 +博士 1 +x:1 +仿生学 1 +x:1 +弹射 1 +x:1 +端 149 +x:149 +弊端 1 +x:1 +地震台 1 +x:1 +瞎子 1 +x:1 +灵活化 1 +x:1 +耄耋之年 1 +x:1 +应试者 1 +x:1 +喉癌 1 +x:1 +云石 1 +x:1 +林龄 1 +x:1 +大冶市 1 +x:1 +山岗 1 +x:1 +空中 1 +x:1 +山岙 1 +x:1 +山泉乡 1 +x:1 +亲家公 1 +x:1 +夸大 1 +x:1 +借鸡生蛋 1 +x:1 +居心不良 1 +x:1 +夸夸 1 +x:1 +鸭儿梨 1 +x:1 +拥政爱民 1 +x:1 +存额 1 +x:1 +骨朵儿 1 +x:1 +填写 1 +x:1 +夜游 1 +x:1 +箱管 1 +x:1 +山岳 1 +x:1 +杀人案 1 +x:1 +膝 12 +x:12 +跳箱 1 +x:1 +长啸 1 +x:1 +弭 6 +x:6 +夜丰颂 1 +x:1 +经阁 1 +x:1 +欣然命笔 1 +x:1 +游逛 1 +x:1 +本题 1 +x:1 +学位法 1 +x:1 +山岭 1 +x:1 +抵扣 1 +x:1 +魔王 1 +x:1 +惯量 1 +x:1 +生势 1 +x:1 +渴慕 1 +x:1 +正告 1 +x:1 +聪灵 1 +x:1 +男中 1 +x:1 +经院 1 +x:1 +顺其自然 1 +x:1 +樟村 1 +x:1 +调拨价 1 +x:1 +喜意 1 +x:1 +出家 1 +x:1 +残工委 1 +x:1 +禹州市 1 +x:1 +山峰 1 +x:1 +压弯 1 +x:1 +队方 1 +x:1 +游遍 1 +x:1 +梯梧 1 +x:1 +度假地 1 +x:1 +药面 1 +x:1 +山峡 1 +x:1 +叩头虫 1 +x:1 +差价率 1 +x:1 +凯内马 1 +x:1 +夸奖 1 +x:1 +西北街 1 +x:1 +实实在在 1 +x:1 +候选者 1 +x:1 +老虎机 1 +x:1 +山崖 1 +x:1 +北三环 1 +x:1 +节后 1 +x:1 +与之俱来 1 +x:1 +惜力 1 +x:1 +姨娘 1 +x:1 +威尼斯 1 +x:1 +回程 1 +x:1 +空间站 1 +x:1 +韶山路 1 +x:1 +血痕 1 +x:1 +破坏性 1 +x:1 +老脾气 1 +x:1 +监护人员 1 +x:1 +轰轰 1 +x:1 +兜风 1 +x:1 +白鲳 1 +x:1 +作业题 1 +x:1 +白炽电灯 1 +x:1 +饼 8 +x:8 +除开 1 +x:1 +守擂者 1 +x:1 +山崩 1 +x:1 +病理学 1 +x:1 +省境 1 +x:1 +声全息 1 +x:1 +退资 1 +x:1 +升力 1 +x:1 +赋彩 1 +x:1 +馆所 1 +x:1 +前额 1 +x:1 +添补 1 +x:1 +语音学 1 +x:1 +监票 1 +x:1 +赋役 1 +x:1 +古晋 1 +x:1 +会心处 1 +x:1 +黎明 1 +x:1 +城陵矶 1 +x:1 +迢迢万里 1 +x:1 +喜悦 1 +x:1 +至境 1 +x:1 +城北镇 1 +x:1 +防患化险 1 +x:1 +厕上 1 +x:1 +震天雷 1 +x:1 +果穗 1 +x:1 +霍巴特 1 +x:1 +彩纸 1 +x:1 +组织 1 +x:1 +组组 1 +x:1 +白鲢 1 +x:1 +汉代 1 +x:1 +产枣量 1 +x:1 +亚裔 1 +x:1 +志愿队 1 +x:1 +此岸性 1 +x:1 +翠微中里 1 +x:1 +灰叶猴 1 +x:1 +车辆场 1 +x:1 +攻击机 1 +x:1 +打孔术 1 +x:1 +出嫁 1 +x:1 +结业者 1 +x:1 +监禁 1 +x:1 +队旗 1 +x:1 +胰岛 1 +x:1 +浸染 1 +x:1 +惜别 1 +x:1 +赔款 1 +x:1 +绩优股 1 +x:1 +节哀 1 +x:1 +压缩空气 1 +x:1 +挥泪 1 +x:1 +鸦片战争 1 +x:1 +除忧 1 +x:1 +亲属 1 +x:1 +山川 1 +x:1 +立马 1 +x:1 +男伴 1 +x:1 +山巅 1 +x:1 +霍地 1 +x:1 +那曲 1 +x:1 +杨陵 1 +x:1 +防火罩 1 +x:1 +浣熊 1 +x:1 +礼赞 1 +x:1 +高中收入 1 +x:1 +商业楼 1 +x:1 +退路 1 +x:1 +喜性 1 +x:1 +脚儿 1 +x:1 +载驳船 1 +x:1 +二伏 1 +x:1 +挺拔 1 +x:1 +平阴县 1 +x:1 +抵挡 1 +x:1 +目测 1 +x:1 +图腾 1 +x:1 +牵引 1 +x:1 +史料性 1 +x:1 +酒西 1 +x:1 +报出地 1 +x:1 +填平补齐 1 +x:1 +宏图 1 +x:1 +劳协 1 +x:1 +亲征 1 +x:1 +主旨性 1 +x:1 +省察 1 +x:1 +开标 1 +x:1 +幼穗 1 +x:1 +牵强 1 +x:1 +出奇 1 +x:1 +机炉岛 1 +x:1 +双学 1 +x:1 +劳 50 +x:50 +三尸神 1 +x:1 +除尘 1 +x:1 +山带 1 +x:1 +出奔 1 +x:1 +真贫 1 +x:1 +止痛针 1 +x:1 +监税 1 +x:1 +畏强欺弱 1 +x:1 +番号 1 +x:1 +老老少少 1 +x:1 +真货 1 +x:1 +鬼斧神工 1 +x:1 +脚力 1 +x:1 +出头 1 +x:1 +广绣 1 +x:1 +商品性 1 +x:1 +喀布尔 1 +x:1 +喜出望外 1 +x:1 +讲师团 1 +x:1 +出处 1 +x:1 +导向型 1 +x:1 +幼稚 1 +x:1 +骨组织 1 +x:1 +惠阳市 1 +x:1 +出外 1 +x:1 +回廊式 1 +x:1 +脚劲 1 +x:1 +凶狠 1 +x:1 +救危 1 +x:1 +一定量 1 +x:1 +失业军 1 +x:1 +供货户 1 +x:1 +戛戛 1 +x:1 +下 8658 +x:8658 +中山亭 1 +x:1 +和平棋 1 +x:1 +血癌 1 +x:1 +零售票 1 +x:1 +幼童 1 +x:1 +夸张式 1 +x:1 +山庄 1 +x:1 +金牛岭 1 +x:1 +剪接 1 +x:1 +周口市 1 +x:1 +党组织 1 +x:1 +变化 1 +x:1 +自然庄 1 +x:1 +菱 7 +x:7 +建设科 1 +x:1 +茶话会 1 +x:1 +灌渠 1 +x:1 +肩负 1 +x:1 +踏平 1 +x:1 +养料 1 +x:1 +喜捧 1 +x:1 +食心虫 1 +x:1 +赔案 1 +x:1 +丁丁 1 +x:1 +刑场 1 +x:1 +会谈 1 +x:1 +跟脚 1 +x:1 +睢阳区 1 +x:1 +茄果类 1 +x:1 +同村 1 +x:1 +凶犯 1 +x:1 +丁丑 1 +x:1 +实话实说 1 +x:1 +书库 1 +x:1 +贪欲 1 +x:1 +旅游线 1 +x:1 +变卖 1 +x:1 +那时 1 +x:1 +省部级 1 +x:1 +沱茶 1 +x:1 +拨 169 +x:169 +变卦 1 +x:1 +应酬 1 +x:1 +组办 1 +x:1 +串亲戚 1 +x:1 +省厅级 1 +x:1 +歹 1 +x:1 +弹库 1 +x:1 +雨情 1 +x:1 +前事不忘 1 +x:1 +香港湾区 1 +x:1 +客饭 1 +x:1 +乐山 1 +x:1 +街头巷尾 1 +x:1 +疑问 1 +x:1 +熟 78 +x:78 +变动 1 +x:1 +立领 1 +x:1 +茨 1 +x:1 +家蚊 1 +x:1 +放线 1 +x:1 +熟视无睹 1 +x:1 +齐集 1 +x:1 +家蚕 1 +x:1 +上犹县 1 +x:1 +埃舍德 1 +x:1 +捐立 1 +x:1 +闲扯 1 +x:1 +妇女界 1 +x:1 +晾风 1 +x:1 +旱烟管 1 +x:1 +厅堂 1 +x:1 +反反复复 1 +x:1 +打桩 1 +x:1 +未婚妻 1 +x:1 +扑票者 1 +x:1 +山影 1 +x:1 +戏耍 1 +x:1 +转营 1 +x:1 +太师椅 1 +x:1 +镇安县 1 +x:1 +公务 1 +x:1 +梯次 1 +x:1 +喜报 1 +x:1 +力举 1 +x:1 +鸬鹚乡 1 +x:1 +信念 1 +x:1 +纾解民困 1 +x:1 +协进会 1 +x:1 +种子赛 1 +x:1 +商家退避 1 +x:1 +被上诉方 1 +x:1 +活动量 1 +x:1 +表达题 1 +x:1 +报账 1 +x:1 +话务班 1 +x:1 +哄然大笑 1 +x:1 +北郎中 1 +x:1 +监管 1 +x:1 +粒肥 1 +x:1 +宣判声 1 +x:1 +帮扶团 1 +x:1 +金刚努目 1 +x:1 +产权局 1 +x:1 +杂交率 1 +x:1 +宝丰 1 +x:1 +祁阳县 1 +x:1 +即 1657 +x:1657 +经销 1 +x:1 +半年前 1 +x:1 +受得了 1 +x:1 +妇女病 1 +x:1 +蹄子 1 +x:1 +贷 79 +x:79 +脚印 1 +x:1 +记者证 1 +x:1 +售架 1 +x:1 +劳力 1 +x:1 +积资 1 +x:1 +未婚夫 1 +x:1 +窠 2 +x:2 +信心 1 +x:1 +从紧 1 +x:1 +粉碎 1 +x:1 +反戈一击 1 +x:1 +交换台 1 +x:1 +退还 1 +x:1 +免不了 1 +x:1 +近在眼前 1 +x:1 +言之成理 1 +x:1 +事务主义 1 +x:1 +气溶胶 1 +x:1 +面陈 1 +x:1 +出境 1 +x:1 +孕前 1 +x:1 +劳动 1 +x:1 +会费 1 +x:1 +砖茶 1 +x:1 +温尼伯 1 +x:1 +万事大吉 1 +x:1 +捐税 1 +x:1 +成灾 1 +x:1 +分库 1 +x:1 +苦头 1 +x:1 +分店 1 +x:1 +包装 1 +x:1 +运筹 1 +x:1 +哀乐 1 +x:1 +洋兰 1 +x:1 +湿邪 1 +x:1 +提水站 1 +x:1 +夏收 1 +x:1 +心梗 1 +x:1 +高低压 1 +x:1 +太空梭 1 +x:1 +戍边人 1 +x:1 +蜀锦 1 +x:1 +此处 1 +x:1 +双簧管 1 +x:1 +分配数 1 +x:1 +如同 1 +x:1 +千斤顶 1 +x:1 +苦处 1 +x:1 +涟漪 1 +x:1 +此外 1 +x:1 +昙花林 1 +x:1 +重特大案 1 +x:1 +手感 1 +x:1 +市容 1 +x:1 +彰扬 1 +x:1 +研究院 1 +x:1 +安居乐教 1 +x:1 +恩施 1 +x:1 +怀恋 1 +x:1 +泄水渠 1 +x:1 +乒乓球桌 1 +x:1 +变态反应 1 +x:1 +衰竭性 1 +x:1 +中央政府 1 +x:1 +廉颇老矣 1 +x:1 +邪财 1 +x:1 +赞 62 +x:62 +塑管 1 +x:1 +医护 1 +x:1 +仿作 1 +x:1 +仿佛 1 +x:1 +证照 1 +x:1 +沅陵 1 +x:1 +胫 1 +x:1 +定造 1 +x:1 +扬 181 +x:181 +方家区 1 +x:1 +交道 1 +x:1 +款子 1 +x:1 +大无畏 1 +x:1 +丧生者 1 +x:1 +沅水 1 +x:1 +愚民 1 +x:1 +包袱 1 +x:1 +龙泉区 1 +x:1 +心浮意躁 1 +x:1 +初七 1 +x:1 +疫情 1 +x:1 +金边 1 +x:1 +游泳赛 1 +x:1 +黄土地 1 +x:1 +红河谷 1 +x:1 +温江县 1 +x:1 +分币 1 +x:1 +践踏 1 +x:1 +分布 1 +x:1 +做通 1 +x:1 +湘赣 1 +x:1 +有头有脑 1 +x:1 +心树 1 +x:1 +耳顺 1 +x:1 +吉祥如意 1 +x:1 +总装机 1 +x:1 +毗连区 1 +x:1 +丧生 1 +x:1 +专题性 1 +x:1 +横横竖竖 1 +x:1 +贪赃卖法 1 +x:1 +包衣 1 +x:1 +和婉 1 +x:1 +定都 1 +x:1 +前列 1 +x:1 +讲 2000 +x:2000 +爷 3 +x:3 +书讯 1 +x:1 +冰川学 1 +x:1 +淮河路 1 +x:1 +千钧一发 1 +x:1 +体育局 1 +x:1 +纪念亭 1 +x:1 +契 2 +x:2 +俄勒冈 1 +x:1 +象牙板 1 +x:1 +运管 1 +x:1 +武定侯 1 +x:1 +乘晕宁 1 +x:1 +雅俗 1 +x:1 +常山 1 +x:1 +渡槽 1 +x:1 +内黄县 1 +x:1 +三贤祠 1 +x:1 +签到簿 1 +x:1 +中亚 1 +x:1 +珍珠球 1 +x:1 +运算 1 +x:1 +驰去 1 +x:1 +烤烟叶 1 +x:1 +锤炼 1 +x:1 +横梁 1 +x:1 +朔风 1 +x:1 +潘圩村 1 +x:1 +碎石机 1 +x:1 +惊涛骇浪 1 +x:1 +观赏性 1 +x:1 +脑膜炎 1 +x:1 +殇 2 +x:2 +分得 1 +x:1 +诗经 1 +x:1 +中山陵园 1 +x:1 +安德里 1 +x:1 +禹日 1 +x:1 +孤立无援 1 +x:1 +难辨 1 +x:1 +固定汇率 1 +x:1 +音名 1 +x:1 +干酪素 1 +x:1 +催促式 1 +x:1 +保通社 1 +x:1 +盛举 1 +x:1 +兵种部 1 +x:1 +前去 1 +x:1 +前厅 1 +x:1 +赛璐玢 1 +x:1 +宁国府 1 +x:1 +岩 96 +x:96 +传达 1 +x:1 +许可费 1 +x:1 +食积 1 +x:1 +华埠 1 +x:1 +雅丹 1 +x:1 +拥有率 1 +x:1 +修饰 1 +x:1 +左锋 1 +x:1 +火上加油 1 +x:1 +屡次三番 1 +x:1 +证人席 1 +x:1 +驭手 1 +x:1 +扫帚星 1 +x:1 +海安县 1 +x:1 +分心 1 +x:1 +票据法 1 +x:1 +前台 1 +x:1 +怀慕 1 +x:1 +榆次市 1 +x:1 +拥戴 1 +x:1 +猎潜机 1 +x:1 +好戏 1 +x:1 +赛璐珞 1 +x:1 +短句 1 +x:1 +莒南 1 +x:1 +哀伤 1 +x:1 +能效比 1 +x:1 +墙上 1 +x:1 +电子钟 1 +x:1 +复活日 1 +x:1 +常州 1 +x:1 +常川 1 +x:1 +下半场 1 +x:1 +审判席 1 +x:1 +步频 1 +x:1 +教练车 1 +x:1 +难过 1 +x:1 +北固碾 1 +x:1 +欲速不达 1 +x:1 +定量 1 +x:1 +商丘站 1 +x:1 +雅事 1 +x:1 +星等 1 +x:1 +合江省 1 +x:1 +以党代政 1 +x:1 +分开 1 +x:1 +作业区 1 +x:1 +试想想 1 +x:1 +千古遗恨 1 +x:1 +定金 1 +x:1 +司线员 1 +x:1 +分式 1 +x:1 +处理费 1 +x:1 +狼道 1 +x:1 +义举 1 +x:1 +达成 1 +x:1 +农摊 1 +x:1 +纪 53 +x:53 +苦境 1 +x:1 +彝乡 1 +x:1 +夏旱 1 +x:1 +揭露 1 +x:1 +交通 1 +x:1 +宁国市 1 +x:1 +矮墩墩 1 +x:1 +空位 1 +x:1 +生育率 1 +x:1 +兼权熟计 1 +x:1 +前卫 1 +x:1 +递补 1 +x:1 +给定 1 +x:1 +幕 117 +x:117 +言志 1 +x:1 +音响 1 +x:1 +众目昭著 1 +x:1 +想见 1 +x:1 +枪子儿 1 +x:1 +农户家 1 +x:1 +采采 1 +x:1 +代售 1 +x:1 +征集组 1 +x:1 +落榜 1 +x:1 +为过 1 +x:1 +中国流 1 +x:1 +禽业 1 +x:1 +外专局 1 +x:1 +前南 1 +x:1 +啜泣 1 +x:1 +弥天盖地 1 +x:1 +余兴 1 +x:1 +审判庭 1 +x:1 +草煤 1 +x:1 +由此看来 1 +x:1 +金贵 1 +x:1 +映衬 1 +x:1 +海陆空 1 +x:1 +水蒸汽 1 +x:1 +先礼后兵 1 +x:1 +晃晃荡荡 1 +x:1 +金质 1 +x:1 +分配权 1 +x:1 +彩翼 1 +x:1 +本质性 1 +x:1 +手持 1 +x:1 +手指 1 +x:1 +肉饼 1 +x:1 +夺走 1 +x:1 +碌碌 1 +x:1 +衣着 1 +x:1 +书市 1 +x:1 +昌江县 1 +x:1 +曼俄 1 +x:1 +烈马 1 +x:1 +网袋 1 +x:1 +振奋人心 1 +x:1 +风骨 1 +x:1 +风口 1 +x:1 +舅妈 1 +x:1 +草狐 1 +x:1 +马拉尼昂 1 +x:1 +沙窝集镇 1 +x:1 +市委 1 +x:1 +自警自省 1 +x:1 +说和 1 +x:1 +笪公祠 1 +x:1 +苦学 1 +x:1 +泄殖腔 1 +x:1 +辩论会 1 +x:1 +跑马厅 1 +x:1 +日夜兼程 1 +x:1 +预审股 1 +x:1 +寒碜 1 +x:1 +被迫 1 +x:1 +台海 1 +x:1 +风骚 1 +x:1 +青云桥 1 +x:1 +吞没 1 +x:1 +水蒸气 1 +x:1 +清理工 1 +x:1 +亲和 1 +x:1 +涟涟 1 +x:1 +市话网 1 +x:1 +钱家峪 1 +x:1 +鸣谢 1 +x:1 +黑人 1 +x:1 +东丰县 1 +x:1 +分封 1 +x:1 +常常 1 +x:1 +青翠 1 +x:1 +牌楼 1 +x:1 +云冈矿 1 +x:1 +黑亮 1 +x:1 +耕作 1 +x:1 +字句 1 +x:1 +杨庙 1 +x:1 +木版画 1 +x:1 +广告栏 1 +x:1 +和谈 1 +x:1 +手掌 1 +x:1 +字号 1 +x:1 +怀抱 1 +x:1 +和谐 1 +x:1 +达意 1 +x:1 +健硕 1 +x:1 +风风火火 1 +x:1 +资金 1 +x:1 +舍利塔 1 +x:1 +簿 4 +x:4 +搭建 1 +x:1 +射阳县 1 +x:1 +抢掠 1 +x:1 +探索者 1 +x:1 +核电站 1 +x:1 +分属 1 +x:1 +分局 1 +x:1 +分层 1 +x:1 +分居 1 +x:1 +说合 1 +x:1 +政治学所 1 +x:1 +常平 1 +x:1 +跑鹅区 1 +x:1 +肉馅 1 +x:1 +常年 1 +x:1 +知了 1 +x:1 +苦寒 1 +x:1 +治愈 1 +x:1 +罩 21 +x:21 +女中音 1 +x:1 +开幕词 1 +x:1 +手提 1 +x:1 +禾秆 1 +x:1 +收藏史 1 +x:1 +老眼光 1 +x:1 +山水经 1 +x:1 +官阶 1 +x:1 +冷傲 1 +x:1 +襄阳县 1 +x:1 +玉米子 1 +x:1 +金谷 1 +x:1 +五粮液 1 +x:1 +小史店 1 +x:1 +三个之最 1 +x:1 +复合驱油 1 +x:1 +加急电报 1 +x:1 +格言式 1 +x:1 +当口 1 +x:1 +形式化 1 +x:1 +丁丁冬冬 1 +x:1 +有着 1 +x:1 +人和乡 1 +x:1 +巡回赛 1 +x:1 +米皇 1 +x:1 +常德 1 +x:1 +草率 1 +x:1 +财政部 1 +x:1 +益都 1 +x:1 +巧克力 1 +x:1 +文山里 1 +x:1 +败者 1 +x:1 +清真教 1 +x:1 +涟水 1 +x:1 +列车员 1 +x:1 +吉星乡 1 +x:1 +抢手 1 +x:1 +洪城 1 +x:1 +霸 18 +x:18 +磁铁矿 1 +x:1 +勃发生机 1 +x:1 +论黄数黑 1 +x:1 +机帆船 1 +x:1 +沉吟 1 +x:1 +卵用鸡 1 +x:1 +步骤 1 +x:1 +落款 1 +x:1 +深得民心 1 +x:1 +信阳 1 +x:1 +激素类 1 +x:1 +云龙乡 1 +x:1 +两税 1 +x:1 +好报 1 +x:1 +黑体 1 +x:1 +证物 1 +x:1 +木槿花 1 +x:1 +雕塑 1 +x:1 +龙胆草 1 +x:1 +四点半 1 +x:1 +自由体 1 +x:1 +秦始皇陵 1 +x:1 +东城区 1 +x:1 +鱼禽肉蛋 1 +x:1 +径直 1 +x:1 +篱园 1 +x:1 +数术 1 +x:1 +食管 1 +x:1 +两端 1 +x:1 +候诊椅 1 +x:1 +肉食 1 +x:1 +创演 1 +x:1 +青绿 1 +x:1 +雪松 1 +x:1 +拉路村 1 +x:1 +墒 8 +x:8 +壁毯 1 +x:1 +熏陶 1 +x:1 +杨柳岸 1 +x:1 +手抄 1 +x:1 +陈列馆 1 +x:1 +嘲讽 1 +x:1 +挫 11 +x:11 +写诗人 1 +x:1 +不怎么 1 +x:1 +关键字 1 +x:1 +铬铁矿 1 +x:1 +杈 2 +x:2 +氯丁橡胶 1 +x:1 +深加工 1 +x:1 +抢护 1 +x:1 +洋务 1 +x:1 +客家人 1 +x:1 +掐算 1 +x:1 +黑信 1 +x:1 +显绩 1 +x:1 +致命 1 +x:1 +向前乡 1 +x:1 +市郊 1 +x:1 +元坊村 1 +x:1 +前兆 1 +x:1 +前街后巷 1 +x:1 +无奈何 1 +x:1 +说唱 1 +x:1 +学部委员 1 +x:1 +冷藏 1 +x:1 +胡椒面 1 +x:1 +缔约方 1 +x:1 +后备箱 1 +x:1 +理事长 1 +x:1 +鞋业 1 +x:1 +疲软 1 +x:1 +诗篇 1 +x:1 +显示 1 +x:1 +棺器 1 +x:1 +水罐车 1 +x:1 +食糖 1 +x:1 +技术 1 +x:1 +有线广播 1 +x:1 +彭城王 1 +x:1 +奇才队 1 +x:1 +嫩苗 1 +x:1 +戴维营 1 +x:1 +安置国 1 +x:1 +信口雌黄 1 +x:1 +独自 1 +x:1 +磁电式 1 +x:1 +轻松感 1 +x:1 +段 1341 +x:1341 +抢救 1 +x:1 +依存性 1 +x:1 +心河 1 +x:1 +市徽 1 +x:1 +特等功 1 +x:1 +落水 1 +x:1 +杂 39 +x:39 +举锤 1 +x:1 +好性儿 1 +x:1 +总台 1 +x:1 +高锰酸钾 1 +x:1 +城南区 1 +x:1 +前围 1 +x:1 +抢收 1 +x:1 +市志 1 +x:1 +乜 1 +x:1 +抢攻 1 +x:1 +拥有 1 +x:1 +榜上无名 1 +x:1 +迷恋 1 +x:1 +货站 1 +x:1 +陇剧 1 +x:1 +食粮 1 +x:1 +官邸 1 +x:1 +某省 1 +x:1 +破涕为笑 1 +x:1 +泌阳县 1 +x:1 +想象 1 +x:1 +令人感动 1 +x:1 +神圣化 1 +x:1 +黄土区 1 +x:1 +花甲乡 1 +x:1 +肌瘤 1 +x:1 +断粮 1 +x:1 +黄檗罗树 1 +x:1 +凭栏 1 +x:1 +联产承包 1 +x:1 +诬告 1 +x:1 +起落 1 +x:1 +哉 31 +x:31 +夺路 1 +x:1 +少长咸集 1 +x:1 +官道 1 +x:1 +落泪 1 +x:1 +茫然无措 1 +x:1 +香椿芽 1 +x:1 +戳穿 1 +x:1 +帧 13 +x:13 +可谓 1 +x:1 +长春桥 1 +x:1 +似曾相识 1 +x:1 +藐视 1 +x:1 +真情实意 1 +x:1 +分娩 1 +x:1 +维誉至诚 1 +x:1 +太空水 1 +x:1 +防水层 1 +x:1 +沉厚 1 +x:1 +枪械 1 +x:1 +计分器 1 +x:1 +毒丸 1 +x:1 +优秀奖 1 +x:1 +审判官 1 +x:1 +补贴额 1 +x:1 +担保 1 +x:1 +狮子舞 1 +x:1 +始料未及 1 +x:1 +苦工 1 +x:1 +上座儿 1 +x:1 +隔离栏 1 +x:1 +儒艮 1 +x:1 +保不齐 1 +x:1 +苦差 1 +x:1 +孟县 1 +x:1 +源泉 1 +x:1 +米袋子 1 +x:1 +幽远 1 +x:1 +岔道 1 +x:1 +大清国 1 +x:1 +年代久远 1 +x:1 +万年青 1 +x:1 +沭阳 1 +x:1 +片瓦无存 1 +x:1 +包谷 1 +x:1 +自恃 1 +x:1 +落选者 1 +x:1 +定钱 1 +x:1 +看财奴 1 +x:1 +迷惘 1 +x:1 +急性 1 +x:1 +联欢会 1 +x:1 +电子部 1 +x:1 +和议 1 +x:1 +台生 1 +x:1 +牙渍 1 +x:1 +愚见 1 +x:1 +影星 1 +x:1 +积羽沉舟 1 +x:1 +增进 1 +x:1 +说及 1 +x:1 +市府 1 +x:1 +恩惠 1 +x:1 +处方权 1 +x:1 +北碚区 1 +x:1 +分家 1 +x:1 +诗章 1 +x:1 +提供者 1 +x:1 +梨狗 1 +x:1 +邪行 1 +x:1 +道林纸 1 +x:1 +了井塘村 1 +x:1 +死灭 1 +x:1 +生化 1 +x:1 +点 1792 +x:1792 +希伯伦城 1 +x:1 +恩情 1 +x:1 +坐而论道 1 +x:1 +举不胜举 1 +x:1 +陇南 1 +x:1 +除数 1 +x:1 +溺水者 1 +x:1 +难说 1 +x:1 +慷慨陈词 1 +x:1 +安置型 1 +x:1 +紧张万状 1 +x:1 +市廛 1 +x:1 +分销 1 +x:1 +健美 1 +x:1 +手摇 1 +x:1 +变动者 1 +x:1 +践诺 1 +x:1 +分寸 1 +x:1 +返回式 1 +x:1 +想起 1 +x:1 +海水面 1 +x:1 +莜麦 1 +x:1 +搭头 1 +x:1 +突防 1 +x:1 +肉鸭 1 +x:1 +肉鸡 1 +x:1 +煸 2 +x:2 +渡汛 1 +x:1 +关山 1 +x:1 +常委 1 +x:1 +安德镇 1 +x:1 +烟台港 1 +x:1 +下降调 1 +x:1 +市布 1 +x:1 +偃旗息鼓 1 +x:1 +矜持 1 +x:1 +倒转 1 +x:1 +湛蓝 1 +x:1 +初任 1 +x:1 +酷爱 1 +x:1 +市商委 1 +x:1 +荒地 1 +x:1 +抚 5 +x:5 +羚羊角 1 +x:1 +涡轮机 1 +x:1 +前场 1 +x:1 +草甸 1 +x:1 +认证书 1 +x:1 +产粮区 1 +x:1 +杆菌 1 +x:1 +望梅止渴 1 +x:1 +常备 1 +x:1 +诉状 1 +x:1 +本意 1 +x:1 +语录牌 1 +x:1 +下半叶 1 +x:1 +杂乱 1 +x:1 +客货轮船 1 +x:1 +武陟县 1 +x:1 +分子 1 +x:1 +企事业 1 +x:1 +晶莹剔透 1 +x:1 +收藏品 1 +x:1 +舍本求末 1 +x:1 +嘹亮 1 +x:1 +货签 1 +x:1 +弗罗阿 1 +x:1 +掩却 1 +x:1 +掩卷 1 +x:1 +清算组 1 +x:1 +恩怨 1 +x:1 +斗法 1 +x:1 +法办 1 +x:1 +音像 1 +x:1 +青农部 1 +x:1 +誉为 1 +x:1 +园长 1 +x:1 +混迹 1 +x:1 +民会 1 +x:1 +烟色 1 +x:1 +肉麻 1 +x:1 +霎时间 1 +x:1 +怀旧 1 +x:1 +好天儿 1 +x:1 +烧结砖 1 +x:1 +敛去 1 +x:1 +不由分说 1 +x:1 +出境部 1 +x:1 +灭蝗 1 +x:1 +市井气 1 +x:1 +惮 1 +x:1 +不分上下 1 +x:1 +担任 1 +x:1 +诗稿 1 +x:1 +贪吃 1 +x:1 +混进 1 +x:1 +蜀都 1 +x:1 +映象 1 +x:1 +普陀区 1 +x:1 +手术 1 +x:1 +此张 1 +x:1 +手本 1 +x:1 +千奇百怪 1 +x:1 +双百 1 +x:1 +手机 1 +x:1 +滤液 1 +x:1 +摇滚乐 1 +x:1 +瘠 2 +x:2 +油油亮亮 1 +x:1 +浮冀汾 1 +x:1 +怀春 1 +x:1 +人工降雨 1 +x:1 +引出 1 +x:1 +挽留 1 +x:1 +热转印机 1 +x:1 +敬佩 1 +x:1 +皖平 1 +x:1 +草皮 1 +x:1 +定陵 1 +x:1 +守约 1 +x:1 +青筋 1 +x:1 +办复率 1 +x:1 +钱排 1 +x:1 +苦役 1 +x:1 +以己度人 1 +x:1 +稍微 1 +x:1 +反毒网 1 +x:1 +蓑衣 1 +x:1 +机敏 1 +x:1 +音协 1 +x:1 +张掖 1 +x:1 +此役 1 +x:1 +洋场 1 +x:1 +都城史 1 +x:1 +手板 1 +x:1 +海河湾村 1 +x:1 +利息额 1 +x:1 +朴直 1 +x:1 +电影院 1 +x:1 +递进 1 +x:1 +广告法 1 +x:1 +如春 1 +x:1 +重唱 1 +x:1 +蝗区 1 +x:1 +商业城 1 +x:1 +民和县 1 +x:1 +开工率 1 +x:1 +沉凝 1 +x:1 +一生一世 1 +x:1 +达官贵人 1 +x:1 +双目 1 +x:1 +手枪 1 +x:1 +上下卷 1 +x:1 +1 3455 +x:3455 +两翼 1 +x:1 +转转 1 +x:1 +勒卡 1 +x:1 +幽趣 1 +x:1 +停车牌 1 +x:1 +千恩万谢 1 +x:1 +肠伤寒 1 +x:1 +肌理 1 +x:1 +鸿福 1 +x:1 +开幕辞 1 +x:1 +前大营 1 +x:1 +信托法 1 +x:1 +砒霜 1 +x:1 +哥德堡 1 +x:1 +前后 1 +x:1 +手足无措 1 +x:1 +短吨 1 +x:1 +怯 4 +x:4 +打牙祭 1 +x:1 +研究部 1 +x:1 +税务员 1 +x:1 +内外援 1 +x:1 +跑马坡 1 +x:1 +合口味 1 +x:1 +音变 1 +x:1 +嘉陵江 1 +x:1 +陋 5 +x:5 +前周 1 +x:1 +抢枪 1 +x:1 +践行 1 +x:1 +天翻地覆 1 +x:1 +禁止 1 +x:1 +雕工 1 +x:1 +俺家 1 +x:1 +跑马场 1 +x:1 +手柄 1 +x:1 +公墓区 1 +x:1 +追逐赛 1 +x:1 +跑马地 1 +x:1 +一亩泉 1 +x:1 +苦心 1 +x:1 +移位 1 +x:1 +三不用 1 +x:1 +耳鸣 1 +x:1 +此志 1 +x:1 +沉冤 1 +x:1 +牛犊子 1 +x:1 +株株 1 +x:1 +常客 1 +x:1 +怀有 1 +x:1 +青空 1 +x:1 +防守奖 1 +x:1 +败落 1 +x:1 +阿尔法星 1 +x:1 +外毒素 1 +x:1 +哄骗 1 +x:1 +起起落落 1 +x:1 +玉米面 1 +x:1 +无缝钢管 1 +x:1 +落潮 1 +x:1 +火柴厂 1 +x:1 +常安 1 +x:1 +黑瞎子 1 +x:1 +宕入 1 +x:1 +斗渠 1 +x:1 +两步走 1 +x:1 +农村 1 +x:1 +衣片 1 +x:1 +本位货币 1 +x:1 +抗议声 1 +x:1 +无票据 1 +x:1 +治安科 1 +x:1 +数据 1 +x:1 +自惜 1 +x:1 +苦干 1 +x:1 +分委 1 +x:1 +和解 1 +x:1 +酷热 1 +x:1 +滤波 1 +x:1 +贪贿风 1 +x:1 +金衡 1 +x:1 +停车率 1 +x:1 +金衢 1 +x:1 +贪色 1 +x:1 +诗碑 1 +x:1 +金表 1 +x:1 +双眼 1 +x:1 +聚 79 +x:79 +敬业 1 +x:1 +网路 1 +x:1 +驰名 1 +x:1 +专修科 1 +x:1 +肌病 1 +x:1 +大北直街 1 +x:1 +矫健 1 +x:1 +怀来 1 +x:1 +气象台站 1 +x:1 +青稞 1 +x:1 +酷烈 1 +x:1 +监视器 1 +x:1 +货种 1 +x:1 +正餐 1 +x:1 +金行 1 +x:1 +丧父 1 +x:1 +主观主义 1 +x:1 +分外 1 +x:1 +漆黑 1 +x:1 +三七开 1 +x:1 +青竹 1 +x:1 +鼎盛期 1 +x:1 +难褪 1 +x:1 +月牙 1 +x:1 +分处 1 +x:1 +灯谜队 1 +x:1 +评剧团 1 +x:1 +分头 1 +x:1 +烟幕 1 +x:1 +长风破浪 1 +x:1 +包车 1 +x:1 +伊利湖 1 +x:1 +敬仰 1 +x:1 +吴营 1 +x:1 +大展经纶 1 +x:1 +警务区 1 +x:1 +启明 1 +x:1 +市局 1 +x:1 +耳鼓 1 +x:1 +用药量 1 +x:1 +马绍尔 1 +x:1 +蒺藜丛 1 +x:1 +证监 1 +x:1 +怀柔 1 +x:1 +许可证 1 +x:1 +独舞 1 +x:1 +市属 1 +x:1 +鄢家河村 1 +x:1 +货票 1 +x:1 +他因 1 +x:1 +农广校 1 +x:1 +心潮 1 +x:1 +钻井 1 +x:1 +水泄不通 1 +x:1 +深圳队 1 +x:1 +数控 1 +x:1 +王家田 1 +x:1 +盲文版 1 +x:1 +长胫 1 +x:1 +他国 1 +x:1 +产蛋率 1 +x:1 +玉米须 1 +x:1 +御代表 1 +x:1 +倔强 1 +x:1 +鹦鹉学舌 1 +x:1 +质数 1 +x:1 +鲤鱼打挺 1 +x:1 +洪峰 1 +x:1 +缩水 1 +x:1 +洋奴 1 +x:1 +正副 1 +x:1 +天平集 1 +x:1 +二三流 1 +x:1 +精美绝伦 1 +x:1 +铺陈 1 +x:1 +大理 1 +x:1 +状貌 1 +x:1 +交谊舞 1 +x:1 +日以继夜 1 +x:1 +耳郭 1 +x:1 +铁皮大鼓 1 +x:1 +市县 1 +x:1 +责任感 1 +x:1 +郡 11 +x:11 +此公 1 +x:1 +独超 1 +x:1 +青田 1 +x:1 +开课 1 +x:1 +正剧 1 +x:1 +生吞活剥 1 +x:1 +心情 1 +x:1 +金 1144 +x:1144 +苍蝇拍子 1 +x:1 +愚蒙 1 +x:1 +元/吨 1 +x:1 +二苯基 1 +x:1 +栾城县 1 +x:1 +矫形 1 +x:1 +夹叙夹议 1 +x:1 +明山区 1 +x:1 +前嫌 1 +x:1 +纵论 1 +x:1 +湖滨 1 +x:1 +分团 1 +x:1 +吴语 1 +x:1 +妖猴 1 +x:1 +返程 1 +x:1 +心想 1 +x:1 +土头土脑 1 +x:1 +幽草 1 +x:1 +恍惚 1 +x:1 +独资 1 +x:1 +拉锯战 1 +x:1 +心态 1 +x:1 +旅业 1 +x:1 +煤矸石 1 +x:1 +洪山 1 +x:1 +一般化 1 +x:1 +注册名 1 +x:1 +市北 1 +x:1 +荥阳市 1 +x:1 +心思 1 +x:1 +草码 1 +x:1 +沉心 1 +x:1 +场记 1 +x:1 +秫米 1 +x:1 +藐藐 1 +x:1 +矿产部 1 +x:1 +银杏酮 1 +x:1 +心性 1 +x:1 +心急 1 +x:1 +因特网日 1 +x:1 +自民联 1 +x:1 +莲 13 +x:13 +阿摩尼亚 1 +x:1 +凝血因子 1 +x:1 +金融 1 +x:1 +广告战 1 +x:1 +洋姜 1 +x:1 +偌大 1 +x:1 +造纸局 1 +x:1 +董家河乡 1 +x:1 +门球场 1 +x:1 +东山乡 1 +x:1 +兑 134 +x:134 +定额 1 +x:1 +草质茎 1 +x:1 +吟哦 1 +x:1 +窑儿洼 1 +x:1 +总长 1 +x:1 +麦播 1 +x:1 +糖葫芦 1 +x:1 +苏公祠 1 +x:1 +岩蕊柱 1 +x:1 +质料 1 +x:1 +败诉 1 +x:1 +祝愿 1 +x:1 +点火器 1 +x:1 +颓垣断壁 1 +x:1 +开普敦 1 +x:1 +守灵 1 +x:1 +回天无力 1 +x:1 +顶撞 1 +x:1 +风速 1 +x:1 +瑞安市 1 +x:1 +蜂皇精 1 +x:1 +联苯胺 1 +x:1 +迷津 1 +x:1 +猪 185 +x:185 +恩泽 1 +x:1 +修配 1 +x:1 +雕刻 1 +x:1 +不言不语 1 +x:1 +烈酒 1 +x:1 +米粒 1 +x:1 +神经病学 1 +x:1 +山水画 1 +x:1 +铺面 1 +x:1 +轴箱 1 +x:1 +米粉 1 +x:1 +浑头浑脑 1 +x:1 +市办 1 +x:1 +亲见亲闻 1 +x:1 +创新 1 +x:1 +坦然 1 +x:1 +下降股 1 +x:1 +风量 1 +x:1 +妖物 1 +x:1 +打光棍儿 1 +x:1 +风采 1 +x:1 +杀伤性 1 +x:1 +甘蔗园 1 +x:1 +卜官庄村 1 +x:1 +伊循 1 +x:1 +区域性 1 +x:1 +监护人 1 +x:1 +雕刀 1 +x:1 +黄土庄 1 +x:1 +前定 1 +x:1 +争得 1 +x:1 +八沟路 1 +x:1 +麦收 1 +x:1 +牵头者 1 +x:1 +资历 1 +x:1 +储木场 1 +x:1 +农户区 1 +x:1 +包膜 1 +x:1 +草种 1 +x:1 +杜鹃 1 +x:1 +上元节 1 +x:1 +美人凤 1 +x:1 +挑战书 1 +x:1 +娇小玲珑 1 +x:1 +张扬 1 +x:1 +大曹庄 1 +x:1 +牌技 1 +x:1 +洁身 1 +x:1 +增补 1 +x:1 +这种 1 +x:1 +禁毒 1 +x:1 +农经系 1 +x:1 +米糠 1 +x:1 +教学区 1 +x:1 +对角线 1 +x:1 +青瓷 1 +x:1 +心意 1 +x:1 +排行表 1 +x:1 +抢险车 1 +x:1 +胡涂乱抹 1 +x:1 +美人儿 1 +x:1 +上呼吸道 1 +x:1 +钱江 1 +x:1 +电影馆 1 +x:1 +霸主 1 +x:1 +青瓦 1 +x:1 +购物额 1 +x:1 +正音 1 +x:1 +混莽 1 +x:1 +回老家 1 +x:1 +创收 1 +x:1 +棋王赛 1 +x:1 +有理有节 1 +x:1 +分场 1 +x:1 +桃力庙 1 +x:1 +看做 1 +x:1 +洮北区 1 +x:1 +霸业 1 +x:1 +氧分 1 +x:1 +市制 1 +x:1 +心愿 1 +x:1 +专用路 1 +x:1 +阖家团圆 1 +x:1 +赎金 1 +x:1 +步道 1 +x:1 +军事管制 1 +x:1 +孟庙 1 +x:1 +欢畅 1 +x:1 +卡尔沃格 1 +x:1 +沉底 1 +x:1 +黄龙山 1 +x:1 +鞠躬尽瘁 1 +x:1 +奋发上进 1 +x:1 +防守型 1 +x:1 +把盏 1 +x:1 +录像馆 1 +x:1 +两点 1 +x:1 +甘洛乡 1 +x:1 +蹦床 1 +x:1 +送葬 1 +x:1 +手检 1 +x:1 +稽留热 1 +x:1 +凛然 1 +x:1 +门 578 +x:578 +坚持不懈 1 +x:1 +城南庄 1 +x:1 +较为 1 +x:1 +估衡 1 +x:1 +金蛇 1 +x:1 +念头 1 +x:1 +稍候 1 +x:1 +不自由 1 +x:1 +出资国 1 +x:1 +市内 1 +x:1 +溃 3 +x:3 +草窝 1 +x:1 +食狗 1 +x:1 +塔形罐 1 +x:1 +挂历 1 +x:1 +字字 1 +x:1 +插曲奖 1 +x:1 +当儿 1 +x:1 +担保法 1 +x:1 +音强 1 +x:1 +北大派 1 +x:1 +青睐 1 +x:1 +承保者 1 +x:1 +原粮 1 +x:1 +肉酱 1 +x:1 +捞钱 1 +x:1 +质材 1 +x:1 +津贴费 1 +x:1 +市况 1 +x:1 +估计 1 +x:1 +重茬 1 +x:1 +残废证 1 +x:1 +质权 1 +x:1 +偏重 1 +x:1 +落户 1 +x:1 +川流不息 1 +x:1 +暖房 1 +x:1 +左侧 1 +x:1 +质朴 1 +x:1 +此卡 1 +x:1 +床板 1 +x:1 +冠军杯 1 +x:1 +助产师 1 +x:1 +落成 1 +x:1 +烧 155 +x:155 +至尊 1 +x:1 +停车线 1 +x:1 +独辫 1 +x:1 +折衷 1 +x:1 +狍子 1 +x:1 +重码率 1 +x:1 +麻栗坡县 1 +x:1 +飞蛾投火 1 +x:1 +青石 1 +x:1 +伊尔 1 +x:1 +喜怒哀乐 1 +x:1 +弥勒县 1 +x:1 +言和 1 +x:1 +英雄汉 1 +x:1 +音律 1 +x:1 +闲庭信步 1 +x:1 +把兄弟 1 +x:1 +涌浪 1 +x:1 +特异功能 1 +x:1 +手段 1 +x:1 +利害攸关 1 +x:1 +平绥路 1 +x:1 +造型艺术 1 +x:1 +表里如一 1 +x:1 +证管 1 +x:1 +盱眙县 1 +x:1 +米缸 1 +x:1 +分蓄洪区 1 +x:1 +草稿 1 +x:1 +碘化钾 1 +x:1 +西陲 1 +x:1 +财农事 1 +x:1 +院容 1 +x:1 +天气图 1 +x:1 +初保 1 +x:1 +收藏家 1 +x:1 +心房 1 +x:1 +他家 1 +x:1 +半掘浦 1 +x:1 +庸 15 +x:15 +战舰 1 +x:1 +某种 1 +x:1 +用电处 1 +x:1 +雕凿 1 +x:1 +味腴书室 1 +x:1 +纵横捭阖 1 +x:1 +陈列部 1 +x:1 +南丰村 1 +x:1 +迷途者 1 +x:1 +披麻戴孝 1 +x:1 +熠熠生辉 1 +x:1 +说尽 1 +x:1 +网联 1 +x:1 +姐 13 +x:13 +女儿岛 1 +x:1 +黎族 1 +x:1 +碘化银 1 +x:1 +食言而肥 1 +x:1 +苦参 1 +x:1 +外滩 1 +x:1 +户籍科 1 +x:1 +旁遮普省 1 +x:1 +抄家 1 +x:1 +手模 1 +x:1 +运输险 1 +x:1 +全员性 1 +x:1 +青白 1 +x:1 +建议案 1 +x:1 +迷漫 1 +x:1 +审判员 1 +x:1 +近东 1 +x:1 +联邦德国 1 +x:1 +此刻 1 +x:1 +皖南 1 +x:1 +裙子 1 +x:1 +材料科学 1 +x:1 +前妻 1 +x:1 +屁股 1 +x:1 +地热井 1 +x:1 +高压界 1 +x:1 +米纳 1 +x:1 +网膜 1 +x:1 +给养 1 +x:1 +编码夹 1 +x:1 +教学关 1 +x:1 +此列 1 +x:1 +医疗型 1 +x:1 +酥糖 1 +x:1 +音带 1 +x:1 +威胁论 1 +x:1 +动人 1 +x:1 +伊川 1 +x:1 +稍加 1 +x:1 +炎凉 1 +x:1 +酽酽 1 +x:1 +此剧 1 +x:1 +大行星 1 +x:1 +水泵头 1 +x:1 +叫好 1 +x:1 +阴转多云 1 +x:1 +皖北 1 +x:1 +信鸽 1 +x:1 +动产 1 +x:1 +海合会 1 +x:1 +玩具厂 1 +x:1 +冰温 1 +x:1 +田野工作 1 +x:1 +独身 1 +x:1 +路 1426 +x:1426 +前委 1 +x:1 +运输队 1 +x:1 +上下床 1 +x:1 +蚕箔 1 +x:1 +声震中外 1 +x:1 +取暖 1 +x:1 +短处 1 +x:1 +苦劳 1 +x:1 +青冈树 1 +x:1 +动乱 1 +x:1 +前天 1 +x:1 +前夫 1 +x:1 +不合 1 +x:1 +百花洲 1 +x:1 +前头 1 +x:1 +音序 1 +x:1 +长春村 1 +x:1 +动真格的 1 +x:1 +金融业 1 +x:1 +金蒙 1 +x:1 +敲敲打打 1 +x:1 +苦力 1 +x:1 +报道员 1 +x:1 +前夕 1 +x:1 +九宫山 1 +x:1 +古旧 1 +x:1 +市值 1 +x:1 +前夜 1 +x:1 +资兴 1 +x:1 +头版头条 1 +x:1 +达标 1 +x:1 +后嗣 1 +x:1 +淄 1 +x:1 +无忧无虑 1 +x:1 +释疑 1 +x:1 +衣纹 1 +x:1 +黑木耳 1 +x:1 +显目 1 +x:1 +攀援者 1 +x:1 +开味品 1 +x:1 +严词 1 +x:1 +证章 1 +x:1 +凭条 1 +x:1 +信望 1 +x:1 +黎方 1 +x:1 +前奏 1 +x:1 +场裁 1 +x:1 +雕像 1 +x:1 +工作室 1 +x:1 +斗拱 1 +x:1 +全能型 1 +x:1 +滩涂 1 +x:1 +讲课稿 1 +x:1 +严谨 1 +x:1 +掉头 1 +x:1 +心理学 1 +x:1 +天狼星 1 +x:1 +分力 1 +x:1 +显然 1 +x:1 +孟子 1 +x:1 +大千世界 1 +x:1 +短库 1 +x:1 +手活 1 +x:1 +风铲 1 +x:1 +投诉人 1 +x:1 +原料库 1 +x:1 +主权 1 +x:1 +菜子坝村 1 +x:1 +风铃 1 +x:1 +教授级 1 +x:1 +资源性 1 +x:1 +后肢 1 +x:1 +技校生 1 +x:1 +双簧 1 +x:1 +两用 1 +x:1 +城管 1 +x:1 +蝌蚪 1 +x:1 +摄影机 1 +x:1 +凹凸 1 +x:1 +售报亭 1 +x:1 +黑里寨 1 +x:1 +蜗壳状 1 +x:1 +市域 1 +x:1 +插科打诨 1 +x:1 +潜台词 1 +x:1 +质感 1 +x:1 +中国情 1 +x:1 +审判区 1 +x:1 +离岸价 1 +x:1 +青果协 1 +x:1 +金戈铁马 1 +x:1 +灶膛 1 +x:1 +移动靶 1 +x:1 +冲撞力 1 +x:1 +迷梦 1 +x:1 +分划 1 +x:1 +金莲 1 +x:1 +分列 1 +x:1 +密押 1 +x:1 +丧礼 1 +x:1 +步长 1 +x:1 +裁定书 1 +x:1 +常值 1 +x:1 +沉寂 1 +x:1 +弧线球 1 +x:1 +双肩包 1 +x:1 +忌妒心 1 +x:1 +炸肉 1 +x:1 +运输量 1 +x:1 +筋肉 1 +x:1 +双糖 1 +x:1 +圆圆满满 1 +x:1 +减量化 1 +x:1 +市地 1 +x:1 +把玩 1 +x:1 +征稽所 1 +x:1 +分别 1 +x:1 +助产士 1 +x:1 +斗方 1 +x:1 +一览无余 1 +x:1 +尽其所有 1 +x:1 +沉实 1 +x:1 +手淫 1 +x:1 +愚者 1 +x:1 +难色 1 +x:1 +将军林 1 +x:1 +前年 1 +x:1 +道 871 +x:871 +审判厅 1 +x:1 +贪心不足 1 +x:1 +惨象 1 +x:1 +货物 1 +x:1 +雪花膏 1 +x:1 +分割 1 +x:1 +草籽 1 +x:1 +贷款人 1 +x:1 +民和委 1 +x:1 +只 3901 +x:3901 +混蛋 1 +x:1 +伊克昭盟 1 +x:1 +日常用语 1 +x:1 +凯歌声 1 +x:1 +迂阔 1 +x:1 +金菊 1 +x:1 +烧夷弹 1 +x:1 +时有时停 1 +x:1 +名垂青史 1 +x:1 +青灰 1 +x:1 +独裁 1 +x:1 +篱墙 1 +x:1 +变动表 1 +x:1 +产奶率 1 +x:1 +风闸 1 +x:1 +分厂 1 +x:1 +风闻 1 +x:1 +龟兔赛跑 1 +x:1 +枪决 1 +x:1 +大打出手 1 +x:1 +致谢函 1 +x:1 +青灯 1 +x:1 +此间 1 +x:1 +此后 1 +x:1 +诚 57 +x:57 +高高挂起 1 +x:1 +吃后悔药 1 +x:1 +痴痴 1 +x:1 +都城墙 1 +x:1 +手气 1 +x:1 +投诉信 1 +x:1 +分发 1 +x:1 +苦味 1 +x:1 +说定 1 +x:1 +摆 459 +x:459 +食疗 1 +x:1 +米家沟 1 +x:1 +苦命 1 +x:1 +养兔场 1 +x:1 +有权有势 1 +x:1 +筋腱 1 +x:1 +监视屏 1 +x:1 +洛孜峰 1 +x:1 +血肉相联 1 +x:1 +核电界 1 +x:1 +分叉 1 +x:1 +迷楼 1 +x:1 +茶客 1 +x:1 +洋将 1 +x:1 +分号 1 +x:1 +左上臂 1 +x:1 +军需业 1 +x:1 +匕首 1 +x:1 +口盖 1 +x:1 +他山 1 +x:1 +分句 1 +x:1 +祸 14 +x:14 +说客 1 +x:1 +接头路 1 +x:1 +直燃型 1 +x:1 +函电 1 +x:1 +运输部 1 +x:1 +补贴金 1 +x:1 +斐然 1 +x:1 +分化 1 +x:1 +腱子 1 +x:1 +短式 1 +x:1 +诗牌 1 +x:1 +抢注 1 +x:1 +落日 1 +x:1 +分包 1 +x:1 +创意 1 +x:1 +惨败 1 +x:1 +家电业 1 +x:1 +分区 1 +x:1 +青烟 1 +x:1 +继任者 1 +x:1 +跑马山 1 +x:1 +索非亚 1 +x:1 +风镜 1 +x:1 +风镐 1 +x:1 +包蕴 1 +x:1 +怀涿 1 +x:1 +朴素 1 +x:1 +无可否认 1 +x:1 +嘎昌河 1 +x:1 +魂萦梦绕 1 +x:1 +避震器 1 +x:1 +对谈 1 +x:1 +言及 1 +x:1 +风锤 1 +x:1 +翌 2 +x:2 +魏 273 +x:273 +抽泣声 1 +x:1 +雪情 1 +x:1 +洪大 1 +x:1 +车摊 1 +x:1 +中下层 1 +x:1 +速描 1 +x:1 +设卡 1 +x:1 +张家口市 1 +x:1 +分卷 1 +x:1 +稍后 1 +x:1 +一次函数 1 +x:1 +森 36 +x:36 +葱 9 +x:9 +初版本 1 +x:1 +手法 1 +x:1 +食用 1 +x:1 +心数 1 +x:1 +燃油费 1 +x:1 +风雨 1 +x:1 +一 47278 +x:47278 +风雪 1 +x:1 +朦胧诗 1 +x:1 +狼狈为奸 1 +x:1 +水族箱 1 +x:1 +停车站 1 +x:1 +食盒 1 +x:1 +食盐 1 +x:1 +风雹 1 +x:1 +吴越 1 +x:1 +孔子 1 +x:1 +立等可取 1 +x:1 +板蓝根 1 +x:1 +责任险 1 +x:1 +此地 1 +x:1 +汗水淋漓 1 +x:1 +草纸 1 +x:1 +墒情点 1 +x:1 +约会室 1 +x:1 +字形 1 +x:1 +食相 1 +x:1 +风雅 1 +x:1 +搭配 1 +x:1 +无地自容 1 +x:1 +鱼肚白 1 +x:1 +札幌 1 +x:1 +正道 1 +x:1 +滤斗 1 +x:1 +三联单 1 +x:1 +惊心动魄 1 +x:1 +草约 1 +x:1 +滑稽剧团 1 +x:1 +山桃花 1 +x:1 +制作人 1 +x:1 +聚散无常 1 +x:1 +切骨之仇 1 +x:1 +泗 1 +x:1 +舆论界 1 +x:1 +运用 1 +x:1 +牡牛 1 +x:1 +广交朋友 1 +x:1 +草绿 1 +x:1 +烈阳 1 +x:1 +草绳 1 +x:1 +奏疏 1 +x:1 +猫头鹰 1 +x:1 +风障 1 +x:1 +黍子 1 +x:1 +穷兵黩武 1 +x:1 +心曲 1 +x:1 +正途 1 +x:1 +风险 1 +x:1 +肢解 1 +x:1 +显现 1 +x:1 +短小 1 +x:1 +全美 1 +x:1 +老本行 1 +x:1 +忘义 1 +x:1 +焕 3 +x:3 +下考乡 1 +x:1 +大康队 1 +x:1 +羽毛球拍 1 +x:1 +耳际 1 +x:1 +寨东 1 +x:1 +民主观 1 +x:1 +筋节 1 +x:1 +税务局 1 +x:1 +宿州市 1 +x:1 +分值 1 +x:1 +魄散魂飞 1 +x:1 +明晃晃 1 +x:1 +前尘 1 +x:1 +水泥砖 1 +x:1 +断头路 1 +x:1 +哭天哭地 1 +x:1 +意气用事 1 +x:1 +区旗 1 +x:1 +拈 7 +x:7 +输送带 1 +x:1 +能出能进 1 +x:1 +泽及后人 1 +x:1 +水口镇 1 +x:1 +衣箱 1 +x:1 +多发病 1 +x:1 +质控 1 +x:1 +佛拉明戈 1 +x:1 +笑话百出 1 +x:1 +制作业 1 +x:1 +双顶山 1 +x:1 +场上 1 +x:1 +栉比鳞次 1 +x:1 +场下 1 +x:1 +近代 1 +x:1 +钱款 1 +x:1 +心智 1 +x:1 +蝗害 1 +x:1 +壮观 1 +x:1 +青玉 1 +x:1 +苦口良药 1 +x:1 +字幅 1 +x:1 +目无表情 1 +x:1 +哐啷 1 +x:1 +暴风骤雨 1 +x:1 +正酣 1 +x:1 +冷空气 1 +x:1 +垂青史 1 +x:1 +两百 1 +x:1 +主机 1 +x:1 +分内 1 +x:1 +芥酸 1 +x:1 +分册 1 +x:1 +风韵 1 +x:1 +演奏者 1 +x:1 +常压 1 +x:1 +成竹在胸 1 +x:1 +哈尔盖 1 +x:1 +总政治部 1 +x:1 +八都镇 1 +x:1 +寒症 1 +x:1 +龙泉山 1 +x:1 +吱吱悠悠 1 +x:1 +熟字 1 +x:1 +借阅台 1 +x:1 +倒挂金钟 1 +x:1 +察察为明 1 +x:1 +深山 1 +x:1 +肝胆照人 1 +x:1 +医疗史 1 +x:1 +良方 1 +x:1 +介面 1 +x:1 +败象 1 +x:1 +状语 1 +x:1 +绿灯 1 +x:1 +群魔乱舞 1 +x:1 +进货员 1 +x:1 +饥饱无时 1 +x:1 +木头人 1 +x:1 +下半夜 1 +x:1 +演技 1 +x:1 +短工 1 +x:1 +金属罐 1 +x:1 +一月份 1 +x:1 +艇长 1 +x:1 +寒疟 1 +x:1 +大豆胶 1 +x:1 +沟沟坎坎 1 +x:1 +杰 230 +x:230 +高唐县 1 +x:1 +扳子 1 +x:1 +辅助货币 1 +x:1 +斗智 1 +x:1 +高脚屋 1 +x:1 +太空服 1 +x:1 +心服 1 +x:1 +风靡 1 +x:1 +痛心疾首 1 +x:1 +洁行 1 +x:1 +草编 1 +x:1 +过关斩将 1 +x:1 +大中城市 1 +x:1 +减收 1 +x:1 +双翼 1 +x:1 +电镀厂 1 +x:1 +喋血 1 +x:1 +石嘴山市 1 +x:1 +采矿业 1 +x:1 +扑面而来 1 +x:1 +对头 1 +x:1 +心机 1 +x:1 +严辞 1 +x:1 +搭台 1 +x:1 +圣维森 1 +x:1 +落架 1 +x:1 +万元户 1 +x:1 +质押 1 +x:1 +三边形 1 +x:1 +乙烯 1 +x:1 +馒头营乡 1 +x:1 +不均 1 +x:1 +医疗卡 1 +x:1 +字库 1 +x:1 +燔 1 +x:1 +游戏池 1 +x:1 +胼手胝足 1 +x:1 +分光 1 +x:1 +南通市 1 +x:1 +海连路 1 +x:1 +识别 1 +x:1 +预测处 1 +x:1 +达江 1 +x:1 +落果 1 +x:1 +凭据 1 +x:1 +大黄鱼 1 +x:1 +特等奖 1 +x:1 +风霜 1 +x:1 +洋底 1 +x:1 +一团糟 1 +x:1 +城砖 1 +x:1 +六言诗 1 +x:1 +青海 1 +x:1 +奉劝 1 +x:1 +高远 1 +x:1 +脚底 1 +x:1 +精雕细琢 1 +x:1 +走资派 1 +x:1 +鲅鱼圈区 1 +x:1 +水勘院 1 +x:1 +麻团 1 +x:1 +有勇有谋 1 +x:1 +青浦 1 +x:1 +自动化系 1 +x:1 +铁骑 1 +x:1 +聊聊天 1 +x:1 +潍县 1 +x:1 +冠盖云集 1 +x:1 +两居室 1 +x:1 +票房 1 +x:1 +白桦树 1 +x:1 +责任街 1 +x:1 +抗议信 1 +x:1 +货源 1 +x:1 +修补 1 +x:1 +独门 1 +x:1 +言中 1 +x:1 +气吞山河 1 +x:1 +分交 1 +x:1 +出差者 1 +x:1 +热闹非凡 1 +x:1 +分享 1 +x:1 +原生油 1 +x:1 +狂野 1 +x:1 +千头万绪 1 +x:1 +黑山 1 +x:1 +还原剂 1 +x:1 +青洲 1 +x:1 +钻头 1 +x:1 +望门寡 1 +x:1 +汽化热 1 +x:1 +国资委 1 +x:1 +觑 3 +x:3 +尖碑 1 +x:1 +干电池 1 +x:1 +运输费 1 +x:1 +数理 1 +x:1 +茌平 1 +x:1 +炸鱼 1 +x:1 +本专科 1 +x:1 +梨枣 1 +x:1 +诉权 1 +x:1 +担子 1 +x:1 +统 36 +x:36 +发言者 1 +x:1 +纪念币 1 +x:1 +八字步 1 +x:1 +争夺圈 1 +x:1 +郫 1 +x:1 +祭器 1 +x:1 +累教不改 1 +x:1 +儒雅 1 +x:1 +民族情 1 +x:1 +塘沽港 1 +x:1 +麦秆虫 1 +x:1 +秉公 1 +x:1 +幽魂 1 +x:1 +华容县 1 +x:1 +劫机 1 +x:1 +傻呵呵 1 +x:1 +钳口结舌 1 +x:1 +纪检组 1 +x:1 +概览表 1 +x:1 +誓师大会 1 +x:1 +和鸣 1 +x:1 +西堡村 1 +x:1 +办校 1 +x:1 +分业 1 +x:1 +风衣 1 +x:1 +民族性 1 +x:1 +列 326 +x:326 +洁静 1 +x:1 +科学院 1 +x:1 +风行 1 +x:1 +来料加工 1 +x:1 +贩 36 +x:36 +分为 1 +x:1 +金龟 1 +x:1 +家乡人 1 +x:1 +匆匆忙忙 1 +x:1 +干涧 1 +x:1 +萨罗夫市 1 +x:1 +交往史 1 +x:1 +户 1338 +x:1338 +扣发 1 +x:1 +正身 1 +x:1 +店主任 1 +x:1 +六七点钟 1 +x:1 +分乘 1 +x:1 +猜拳行令 1 +x:1 +麦精 1 +x:1 +拿三搬四 1 +x:1 +无所顾忌 1 +x:1 +摇头摆尾 1 +x:1 +惨遭 1 +x:1 +苗家社 1 +x:1 +分之 1 +x:1 +扣压 1 +x:1 +麦粒 1 +x:1 +正义之举 1 +x:1 +重围 1 +x:1 +孙媳妇 1 +x:1 +分析化学 1 +x:1 +抢险队 1 +x:1 +军需厂 1 +x:1 +送往迎来 1 +x:1 +拂尘 1 +x:1 +喜笑颜开 1 +x:1 +当轴处中 1 +x:1 +山核桃 1 +x:1 +净现金 1 +x:1 +喜新厌旧 1 +x:1 +铺轨 1 +x:1 +秉借 1 +x:1 +电力城 1 +x:1 +兼管 1 +x:1 +购物者 1 +x:1 +萎 2 +x:2 +金鸡 1 +x:1 +提前 1 +x:1 +圣地亚哥 1 +x:1 +恒星系 1 +x:1 +赖氨酸 1 +x:1 +深县 1 +x:1 +看得起 1 +x:1 +蜚声中外 1 +x:1 +寻甸 1 +x:1 +追根究底 1 +x:1 +食槽 1 +x:1 +投诉厅 1 +x:1 +钻塔 1 +x:1 +灌区 1 +x:1 +青江 1 +x:1 +无关宏旨 1 +x:1 +寒毛 1 +x:1 +变电所 1 +x:1 +芒萁 1 +x:1 +酷暑 1 +x:1 +车改 1 +x:1 +口头语 1 +x:1 +尾市 1 +x:1 +老半日 1 +x:1 +和龙 1 +x:1 +纪念张 1 +x:1 +丁步头 1 +x:1 +毒害 1 +x:1 +败亡 1 +x:1 +苗头性 1 +x:1 +分保 1 +x:1 +救命之恩 1 +x:1 +清洁度 1 +x:1 +投诉台 1 +x:1 +求同求异 1 +x:1 +示范店 1 +x:1 +影片 1 +x:1 +水泥柱 1 +x:1 +严酷 1 +x:1 +分子论 1 +x:1 +高收入者 1 +x:1 +缓流 1 +x:1 +祭坛 1 +x:1 +章目 1 +x:1 +报靶员 1 +x:1 +坎坎坷坷 1 +x:1 +画趣 1 +x:1 +开放 1 +x:1 +学校门 1 +x:1 +蜀葵 1 +x:1 +两栖 1 +x:1 +同悲 1 +x:1 +因时制宜 1 +x:1 +死火山 1 +x:1 +活龙活现 1 +x:1 +反客为主 1 +x:1 +荡荡 1 +x:1 +树花 1 +x:1 +搜索枯肠 1 +x:1 +似地 1 +x:1 +健步 1 +x:1 +安第斯 1 +x:1 +分会 1 +x:1 +床 130 +x:130 +风雨无阻 1 +x:1 +奉化 1 +x:1 +义师 1 +x:1 +教材 1 +x:1 +知识类 1 +x:1 +总的来说 1 +x:1 +包饭 1 +x:1 +步行 1 +x:1 +动员 1 +x:1 +感慨万端 1 +x:1 +抗议书 1 +x:1 +手炉 1 +x:1 +溪 15 +x:15 +铅矿 1 +x:1 +舟曲县 1 +x:1 +持之有故 1 +x:1 +壶盖 1 +x:1 +昨日 1 +x:1 +裙带风 1 +x:1 +耕层 1 +x:1 +排版费 1 +x:1 +分体 1 +x:1 +生成素 1 +x:1 +粗陋 1 +x:1 +因袭 1 +x:1 +象牙白 1 +x:1 +重病号 1 +x:1 +青沧 1 +x:1 +黑工 1 +x:1 +心神 1 +x:1 +动听 1 +x:1 +水泥板 1 +x:1 +总的来讲 1 +x:1 +抢点 1 +x:1 +缫丝 1 +x:1 +喧哗 1 +x:1 +示范带 1 +x:1 +福气 1 +x:1 +跨 1049 +x:1049 +动向 1 +x:1 +东门码头 1 +x:1 +茶花王 1 +x:1 +书口 1 +x:1 +栗色 1 +x:1 +孕产期 1 +x:1 +树大根深 1 +x:1 +自足感 1 +x:1 +斐济 1 +x:1 +成龙 1 +x:1 +尿素厂 1 +x:1 +心窍 1 +x:1 +渭 3 +x:3 +修车点 1 +x:1 +清洁工 1 +x:1 +绿洲 1 +x:1 +落空 1 +x:1 +常人 1 +x:1 +褒 2 +x:2 +黄色文学 1 +x:1 +心窝 1 +x:1 +满盘皆活 1 +x:1 +阿布迪斯 1 +x:1 +搭乘 1 +x:1 +上新世 1 +x:1 +常事 1 +x:1 +计时 1 +x:1 +高朋满座 1 +x:1 +战歌 1 +x:1 +斗笠 1 +x:1 +新生力量 1 +x:1 +双手 1 +x:1 +尖端 1 +x:1 +黑市 1 +x:1 +双打 1 +x:1 +纪念展 1 +x:1 +今晨 1 +x:1 +外文 1 +x:1 +雕塑史 1 +x:1 +待遇 1 +x:1 +无可厚非 1 +x:1 +曼德 1 +x:1 +保包制 1 +x:1 +草拟 1 +x:1 +朴拙 1 +x:1 +梳洗 1 +x:1 +讼法庭 1 +x:1 +常任 1 +x:1 +扣儿 1 +x:1 +审讯 1 +x:1 +太空站 1 +x:1 +创组 1 +x:1 +田纳西州 1 +x:1 +瘤 3 +x:3 +虹口区 1 +x:1 +纪念封 1 +x:1 +黑幕 1 +x:1 +衣服 1 +x:1 +楼兰学 1 +x:1 +着力点 1 +x:1 +贷款值 1 +x:1 +证据 1 +x:1 +寒梅 1 +x:1 +上交款 1 +x:1 +金融城 1 +x:1 +义工 1 +x:1 +重地 1 +x:1 +双拥 1 +x:1 +采矿区 1 +x:1 +分市场 1 +x:1 +紫蓝蓝 1 +x:1 +电影节 1 +x:1 +礼貌性 1 +x:1 +干洗 1 +x:1 +屡见不鲜 1 +x:1 +客源国 1 +x:1 +羞 14 +x:14 +仿造 1 +x:1 +草房 1 +x:1 +银两 1 +x:1 +赵集乡 1 +x:1 +北美 1 +x:1 +荷池 1 +x:1 +幽香 1 +x:1 +起止点 1 +x:1 +妙常 1 +x:1 +莱钢 1 +x:1 +双拐 1 +x:1 +衣柜 1 +x:1 +衷肠 1 +x:1 +丧服 1 +x:1 +数目 1 +x:1 +双抢 1 +x:1 +诳话 1 +x:1 +匠 7 +x:7 +米村 1 +x:1 +蹂躏 1 +x:1 +尾巴 1 +x:1 +森尼维尔 1 +x:1 +建协 1 +x:1 +大吉大利 1 +x:1 +衣架 1 +x:1 +城镇群 1 +x:1 +书友 1 +x:1 +动土 1 +x:1 +声东击西 1 +x:1 +电镀件 1 +x:1 +石花菜 1 +x:1 +顾虑重重 1 +x:1 +斗篷 1 +x:1 +国民军 1 +x:1 +民族所 1 +x:1 +名医药 1 +x:1 +独霸 1 +x:1 +杆子 1 +x:1 +西华营镇 1 +x:1 +起草组 1 +x:1 +明公正道 1 +x:1 +养牛户 1 +x:1 +绿水 1 +x:1 +刀锯 1 +x:1 +动因 1 +x:1 +协定国 1 +x:1 +心算 1 +x:1 +撰著 1 +x:1 +起起伏伏 1 +x:1 +常例 1 +x:1 +战死 1 +x:1 +贝壳馆 1 +x:1 +斩草除根 1 +x:1 +败退 1 +x:1 +荒无人烟 1 +x:1 +耳语 1 +x:1 +直肠癌 1 +x:1 +全立交 1 +x:1 +黑影 1 +x:1 +定窑 1 +x:1 +售票口 1 +x:1 +混饭 1 +x:1 +坦率 1 +x:1 +金鱼 1 +x:1 +奶声奶气 1 +x:1 +夯实 1 +x:1 +修改案 1 +x:1 +示范岗 1 +x:1 +售票台 1 +x:1 +玉覆面 1 +x:1 +搭伙 1 +x:1 +好意 1 +x:1 +单立人 1 +x:1 +落笔 1 +x:1 +求学者 1 +x:1 +磨杵成针 1 +x:1 +豪 4 +x:4 +闯 275 +x:275 +迥异 1 +x:1 +搭伴 1 +x:1 +鞋店 1 +x:1 +鞋底 1 +x:1 +广告科 1 +x:1 +身受 1 +x:1 +心篱 1 +x:1 +制作厂 1 +x:1 +场道 1 +x:1 +俺们 1 +x:1 +成问题 1 +x:1 +铺路 1 +x:1 +正路 1 +x:1 +长天 1 +x:1 +五严禁 1 +x:1 +白龟山 1 +x:1 +承发包 1 +x:1 +冠军级 1 +x:1 +因特网络 1 +x:1 +枣椰树 1 +x:1 +家什儿 1 +x:1 +笑容满面 1 +x:1 +绿荫丛 1 +x:1 +张单驼 1 +x:1 +彝山 1 +x:1 +下周 1 +x:1 +猫 49 +x:49 +终身制 1 +x:1 +常会 1 +x:1 +外向型 1 +x:1 +抗孕片 1 +x:1 +像模像样 1 +x:1 +遗传性 1 +x:1 +钙化 1 +x:1 +海岛岸线 1 +x:1 +场部 1 +x:1 +鞋带 1 +x:1 +鸡汤 1 +x:1 +雕塑刀 1 +x:1 +义展 1 +x:1 +鞋帮 1 +x:1 +易燃物品 1 +x:1 +烫金 1 +x:1 +缩短 1 +x:1 +勖 1 +x:1 +数字式 1 +x:1 +创造型 1 +x:1 +硝 3 +x:3 +监护员 1 +x:1 +仿真机 1 +x:1 +奉养 1 +x:1 +秘本 1 +x:1 +阖家幸福 1 +x:1 +花香鸟语 1 +x:1 +箱管费 1 +x:1 +食欲 1 +x:1 +老寿星 1 +x:1 +光乎乎 1 +x:1 +货流 1 +x:1 +虹 50 +x:50 +旱情 1 +x:1 +江南乡 1 +x:1 +积肥 1 +x:1 +左耳 1 +x:1 +填喂 1 +x:1 +青楼 1 +x:1 +妙境 1 +x:1 +哀婉 1 +x:1 +瘾头 1 +x:1 +画语录 1 +x:1 +争执点 1 +x:1 +选择会 1 +x:1 +粗制滥造 1 +x:1 +大雄宝殿 1 +x:1 +手电 1 +x:1 +靛水 1 +x:1 +垫片 1 +x:1 +败露 1 +x:1 +名评论员 1 +x:1 +邪沟村 1 +x:1 +法场 1 +x:1 +市侩 1 +x:1 +积极分子 1 +x:1 +伴生气 1 +x:1 +官能 1 +x:1 +书包 1 +x:1 +殊途同归 1 +x:1 +劫持 1 +x:1 +悲欢 1 +x:1 +给与 1 +x:1 +服兵役 1 +x:1 +场面 1 +x:1 +守法 1 +x:1 +无冬论夏 1 +x:1 +游泳馆 1 +x:1 +闲言闲语 1 +x:1 +哈密市 1 +x:1 +炉口 1 +x:1 +担当 1 +x:1 +行窃 1 +x:1 +开方 1 +x:1 +风貌 1 +x:1 +节庆日 1 +x:1 +食油 1 +x:1 +仿字 1 +x:1 +资产 1 +x:1 +官股 1 +x:1 +国际部 1 +x:1 +紫荆 1 +x:1 +交汇点 1 +x:1 +双柏县 1 +x:1 +屯昌县 1 +x:1 +补习班 1 +x:1 +雅安 1 +x:1 +碰碰车 1 +x:1 +官职 1 +x:1 +担待 1 +x:1 +颈 14 +x:14 +企鹅岛 1 +x:1 +诗歌 1 +x:1 +服 67 +x:67 +给付 1 +x:1 +归集率 1 +x:1 +游山玩水 1 +x:1 +堕入 1 +x:1 +色谱仪 1 +x:1 +手疾 1 +x:1 +自然选择 1 +x:1 +批准证 1 +x:1 +某某 1 +x:1 +政令 1 +x:1 +深南 1 +x:1 +丧 15 +x:15 +给以 1 +x:1 +出家为尼 1 +x:1 +贷款国 1 +x:1 +疙疙瘩瘩 1 +x:1 +愚顽 1 +x:1 +仿宋 1 +x:1 +小心眼 1 +x:1 +是役 1 +x:1 +气象万千 1 +x:1 +基因库 1 +x:1 +鞋帽部 1 +x:1 +灰眉土脸 1 +x:1 +给予 1 +x:1 +雷霆 1 +x:1 +义子 1 +x:1 +霸占 1 +x:1 +风谣 1 +x:1 +担心 1 +x:1 +绿毯 1 +x:1 +饶阳 1 +x:1 +肋巴骨 1 +x:1 +计息 1 +x:1 +身高马大 1 +x:1 +旅差费 1 +x:1 +盗版者 1 +x:1 +军兵种 1 +x:1 +劫掠 1 +x:1 +余家村 1 +x:1 +启用 1 +x:1 +合格率 1 +x:1 +担忧 1 +x:1 +数点 1 +x:1 +潍坊 1 +x:1 +手痒 1 +x:1 +浴室 1 +x:1 +南丰祠 1 +x:1 +售票员 1 +x:1 +法学家 1 +x:1 +典雅无华 1 +x:1 +输血器 1 +x:1 +黑头 1 +x:1 +雕塑品 1 +x:1 +进程 1 +x:1 +梯 12 +x:12 +滤纸 1 +x:1 +败阵 1 +x:1 +罪魁祸首 1 +x:1 +手球 1 +x:1 +导火线 1 +x:1 +马日事变 1 +x:1 +挤 198 +x:198 +滑坡体 1 +x:1 +两汉 1 +x:1 +古训 1 +x:1 +左脚 1 +x:1 +黑夜 1 +x:1 +除草剂 1 +x:1 +资信 1 +x:1 +栏目类 1 +x:1 +确认函 1 +x:1 +橡胶草 1 +x:1 +国房 1 +x:1 +大穗 1 +x:1 +黑奴 1 +x:1 +斑斑痕痕 1 +x:1 +钻尺 1 +x:1 +风趣 1 +x:1 +非蛋白 1 +x:1 +场院 1 +x:1 +左腿 1 +x:1 +生育期 1 +x:1 +烫面 1 +x:1 +含漱剂 1 +x:1 +棵棵 1 +x:1 +退役证 1 +x:1 +园 66 +x:66 +同甘共苦 1 +x:1 +国际纵队 1 +x:1 +建始县 1 +x:1 +享乐者 1 +x:1 +较劲 1 +x:1 +正副职 1 +x:1 +磨洋工 1 +x:1 +诞生地 1 +x:1 +青委会 1 +x:1 +用工权 1 +x:1 +金融债 1 +x:1 +正误 1 +x:1 +策源地 1 +x:1 +疫病 1 +x:1 +麦秸 1 +x:1 +货款 1 +x:1 +妙处 1 +x:1 +运动学 1 +x:1 +民 429 +x:429 +无可替代 1 +x:1 +怀疑 1 +x:1 +正课 1 +x:1 +王家村 1 +x:1 +拙译 1 +x:1 +青森 1 +x:1 +事在人为 1 +x:1 +官腔 1 +x:1 +组织者 1 +x:1 +修路 1 +x:1 +双旋 1 +x:1 +北七家镇 1 +x:1 +摄影组 1 +x:1 +邪风 1 +x:1 +麦秆 1 +x:1 +益虫 1 +x:1 +冷血动物 1 +x:1 +麦秋 1 +x:1 +麦种 1 +x:1 +制作商 1 +x:1 +自由港 1 +x:1 +捷足者 1 +x:1 +纪念室 1 +x:1 +殡葬工 1 +x:1 +赵县 1 +x:1 +调批权 1 +x:1 +正论 1 +x:1 +铺设 1 +x:1 +迷你裙 1 +x:1 +心中有鬼 1 +x:1 +桐柏路 1 +x:1 +国资局 1 +x:1 +双方 1 +x:1 +凭祥 1 +x:1 +尖尖角 1 +x:1 +Ⅳ 4 +x:4 +疫疠 1 +x:1 +长毛兔 1 +x:1 +致谢 1 +x:1 +象牙片 1 +x:1 +幽默 1 +x:1 +步调 1 +x:1 +青梅 1 +x:1 +肉身 1 +x:1 +祭台 1 +x:1 +亲爱 1 +x:1 +对话会 1 +x:1 +祭司 1 +x:1 +双料 1 +x:1 +解放军队 1 +x:1 +锂 13 +x:13 +含辛茹苦 1 +x:1 +收函字 1 +x:1 +正值 1 +x:1 +关键件 1 +x:1 +大冲黄 1 +x:1 +放心房 1 +x:1 +货梯 1 +x:1 +资源税 1 +x:1 +级别 1 +x:1 +手眼 1 +x:1 +难题 1 +x:1 +映 45 +x:45 +挽救 1 +x:1 +麦穗 1 +x:1 +邪魔 1 +x:1 +延长县 1 +x:1 +六百 1 +x:1 +纪念塔 1 +x:1 +造纸厂 1 +x:1 +人挪活 1 +x:1 +提水泵 1 +x:1 +找上门 1 +x:1 +曹杨新村 1 +x:1 +讨论者 1 +x:1 +金融司 1 +x:1 +雅奏 1 +x:1 +哲学史 1 +x:1 +金融史 1 +x:1 +爱委会 1 +x:1 +心细 1 +x:1 +树尖 1 +x:1 +抗菌血清 1 +x:1 +场长 1 +x:1 +抢眼 1 +x:1 +皖东 1 +x:1 +工资性 1 +x:1 +纪念堂 1 +x:1 +尺牍 1 +x:1 +情状 1 +x:1 +大浪区 1 +x:1 +惠而不费 1 +x:1 +车 1087 +x:1087 +和风 1 +x:1 +正月初五 1 +x:1 +坦 40 +x:40 +马萨诸塞 1 +x:1 +建发 1 +x:1 +技监局 1 +x:1 +肉质 1 +x:1 +正月初二 1 +x:1 +消息 1 +x:1 +消力池 1 +x:1 +双星 1 +x:1 +货样 1 +x:1 +物理学家 1 +x:1 +鄂温克 1 +x:1 +有目共赏 1 +x:1 +正巧 1 +x:1 +筋骨 1 +x:1 +救命车 1 +x:1 +浔南村 1 +x:1 +驱动桥 1 +x:1 +肤色 1 +x:1 +长青树 1 +x:1 +小张庄 1 +x:1 +瓦胡岛 1 +x:1 +变压器 1 +x:1 +此例 1 +x:1 +彝女 1 +x:1 +人情关 1 +x:1 +分配量 1 +x:1 +陈年旧规 1 +x:1 +网开一面 1 +x:1 +绽放 1 +x:1 +联组会 1 +x:1 +鞋子 1 +x:1 +临湖轩 1 +x:1 +齿鸟类 1 +x:1 +芗城 1 +x:1 +合作社部 1 +x:1 +导火索 1 +x:1 +三资企业 1 +x:1 +货栈 1 +x:1 +怀旧念故 1 +x:1 +杰伊汉 1 +x:1 +元白 1 +x:1 +康复会 1 +x:1 +创造力 1 +x:1 +自留山 1 +x:1 +此信 1 +x:1 +冰窟窿 1 +x:1 +奉告 1 +x:1 +自杀性 1 +x:1 +质管 1 +x:1 +和顺 1 +x:1 +慌手慌脚 1 +x:1 +黎母 1 +x:1 +寒气 1 +x:1 +修身 1 +x:1 +奉命 1 +x:1 +胤 1 +x:1 +人生在勤 1 +x:1 +颓败 1 +x:1 +通信卫星 1 +x:1 +义女 1 +x:1 +兴业县 1 +x:1 +饵 3 +x:3 +惰性 1 +x:1 +瞧见 1 +x:1 +檀香山 1 +x:1 +馈赠品 1 +x:1 +正月初一 1 +x:1 +凭空 1 +x:1 +丰乐镇 1 +x:1 +草果 1 +x:1 +双杠 1 +x:1 +衣扣 1 +x:1 +感兴趣者 1 +x:1 +苦主 1 +x:1 +沟河庄 1 +x:1 +黄州区 1 +x:1 +此举 1 +x:1 +寓理于情 1 +x:1 +一诺千金 1 +x:1 +责任车 1 +x:1 +悬崖峭壁 1 +x:1 +双杰 1 +x:1 +抢白 1 +x:1 +怄气 1 +x:1 +雕 29 +x:29 +威仪 1 +x:1 +撮箕 1 +x:1 +具体说来 1 +x:1 +落网 1 +x:1 +唐末五代 1 +x:1 +乍得 1 +x:1 +绿树 1 +x:1 +锰钢 1 +x:1 +严霜 1 +x:1 +纪念奖 1 +x:1 +傻劲儿 1 +x:1 +吴钩 1 +x:1 +两湖 1 +x:1 +国企办 1 +x:1 +手癣 1 +x:1 +怀着 1 +x:1 +中和乡 1 +x:1 +动势 1 +x:1 +悠悠荡荡 1 +x:1 +名闻遐迩 1 +x:1 +此书 1 +x:1 +反动性 1 +x:1 +镜泊湖 1 +x:1 +有气无力 1 +x:1 +动动 1 +x:1 +妖气 1 +x:1 +贸工部长 1 +x:1 +首屈一指 1 +x:1 +玉虚洞 1 +x:1 +苦乐 1 +x:1 +黑子 1 +x:1 +耳边 1 +x:1 +不违农时 1 +x:1 +温馨感 1 +x:1 +黑字 1 +x:1 +无家可归 1 +x:1 +引见 1 +x:1 +香港站 1 +x:1 +支座负筋 1 +x:1 +升降车 1 +x:1 +双月 1 +x:1 +义士 1 +x:1 +最高院 1 +x:1 +山水歌 1 +x:1 +节目组 1 +x:1 +引河桥 1 +x:1 +咂 4 +x:4 +风轮 1 +x:1 +损失量 1 +x:1 +评头品足 1 +x:1 +风车 1 +x:1 +层出不穷 1 +x:1 +船闸门 1 +x:1 +黑客 1 +x:1 +此人 1 +x:1 +振耳欲聋 1 +x:1 +弛 6 +x:6 +耿庄镇 1 +x:1 +抓紧 1 +x:1 +观众席 1 +x:1 +身分 1 +x:1 +此事 1 +x:1 +两路口 1 +x:1 +市容委 1 +x:1 +州区 1 +x:1 +金额 1 +x:1 +正视 1 +x:1 +正规 1 +x:1 +常年性 1 +x:1 +军需品 1 +x:1 +数珠 1 +x:1 +大冈镇 1 +x:1 +耳轮 1 +x:1 +杀身成仁 1 +x:1 +金领 1 +x:1 +钱物 1 +x:1 +为首 1 +x:1 +此井 1 +x:1 +苦于 1 +x:1 +运河 1 +x:1 +胶合板 1 +x:1 +再就业率 1 +x:1 +总工程师 1 +x:1 +尾声 1 +x:1 +滋养品 1 +x:1 +赤磷 1 +x:1 +一水之隔 1 +x:1 +夔门 1 +x:1 +禁渔期 1 +x:1 +大饱眼福 1 +x:1 +专横跋扈 1 +x:1 +稍为 1 +x:1 +秋海棠 1 +x:1 +玉米螟 1 +x:1 +民族村 1 +x:1 +苦仗 1 +x:1 +急湍湍 1 +x:1 +战胜 1 +x:1 +降雪量 1 +x:1 +卡塔尔 1 +x:1 +辽源市 1 +x:1 +钻床 1 +x:1 +阎罗 1 +x:1 +专兼职 1 +x:1 +双桥 1 +x:1 +钻具 1 +x:1 +一方面 1 +x:1 +陇东 1 +x:1 +退办单 1 +x:1 +双桨 1 +x:1 +承审员 1 +x:1 +多管齐下 1 +x:1 +灶间 1 +x:1 +风能 1 +x:1 +骗 79 +x:79 +耳背 1 +x:1 +不凡 1 +x:1 +痴情 1 +x:1 +动工 1 +x:1 +青救 1 +x:1 +拉锯状 1 +x:1 +巷池村 1 +x:1 +找油人 1 +x:1 +轰轰烈烈 1 +x:1 +信赖 1 +x:1 +挽歌 1 +x:1 +陇中 1 +x:1 +扣子 1 +x:1 +拼命三郎 1 +x:1 +出境费 1 +x:1 +巷战 1 +x:1 +草棚 1 +x:1 +误人子弟 1 +x:1 +畅销货 1 +x:1 +鉴戒 1 +x:1 +司空见惯 1 +x:1 +草棉 1 +x:1 +愚钝 1 +x:1 +更型换代 1 +x:1 +信贷 1 +x:1 +绿杨 1 +x:1 +劳动资料 1 +x:1 +祭幛 1 +x:1 +僧徒 1 +x:1 +来函 1 +x:1 +浴场 1 +x:1 +矩阵式 1 +x:1 +梦乡 1 +x:1 +闲嗑儿 1 +x:1 +说亲 1 +x:1 +心烦 1 +x:1 +俸禄 1 +x:1 +责任者 1 +x:1 +节约型 1 +x:1 +呆账 1 +x:1 +辑选 1 +x:1 +非应试 1 +x:1 +抖落 1 +x:1 +所在地 1 +x:1 +纪念园 1 +x:1 +耳聋 1 +x:1 +为难 1 +x:1 +缴送率 1 +x:1 +郎中 1 +x:1 +草根 1 +x:1 +协议价 1 +x:1 +克隆 1 +x:1 +肥囊囊 1 +x:1 +绿林 1 +x:1 +抢种 1 +x:1 +防疫站 1 +x:1 +莱里达市 1 +x:1 +耳聪 1 +x:1 +观测者 1 +x:1 +短篇卷 1 +x:1 +捐助国 1 +x:1 +毒剂 1 +x:1 +根腐病 1 +x:1 +说书 1 +x:1 +督察队 1 +x:1 +守恒 1 +x:1 +落点 1 +x:1 +包退 1 +x:1 +径流 1 +x:1 +草案 1 +x:1 +俭约 1 +x:1 +孵卵器 1 +x:1 +啪啪 1 +x:1 +莅临 1 +x:1 +把柄 1 +x:1 +刑法 1 +x:1 +心火 1 +x:1 +广告片 1 +x:1 +廉洁自律 1 +x:1 +毒刑 1 +x:1 +广告牌 1 +x:1 +裂口 1 +x:1 +寒战 1 +x:1 +迷糊 1 +x:1 +黟县 1 +x:1 +示范地 1 +x:1 +器量 1 +x:1 +器重 1 +x:1 +食性 1 +x:1 +心灰 1 +x:1 +光谱分析 1 +x:1 +示范场 1 +x:1 +明太鱼 1 +x:1 +怠慢 1 +x:1 +货架 1 +x:1 +金阳 1 +x:1 +保驾 1 +x:1 +蜂皇浆 1 +x:1 +定襄 1 +x:1 +顶风冒雪 1 +x:1 +棋校 1 +x:1 +谎 1 +x:1 +参赌者 1 +x:1 +老大夫 1 +x:1 +风致 1 +x:1 +羽毛球界 1 +x:1 +总装线 1 +x:1 +斐斐 1 +x:1 +示范园 1 +x:1 +建国村 1 +x:1 +孟买 1 +x:1 +定西 1 +x:1 +将才学 1 +x:1 +药学会 1 +x:1 +杏花雨 1 +x:1 +麦田 1 +x:1 +金陵 1 +x:1 +创痕 1 +x:1 +耳膜 1 +x:1 +创痛 1 +x:1 +两性 1 +x:1 +自治领 1 +x:1 +附本 1 +x:1 +季马市 1 +x:1 +岔路 1 +x:1 +纪念地 1 +x:1 +大呼小叫 1 +x:1 +黑啤 1 +x:1 +质言之 1 +x:1 +影片展 1 +x:1 +所在团 1 +x:1 +浴巾 1 +x:1 +羟基 1 +x:1 +习以为常 1 +x:1 +灵丘县 1 +x:1 +货柜 1 +x:1 +减排 1 +x:1 +独眼龙 1 +x:1 +皇天后土 1 +x:1 +奠立 1 +x:1 +显摆 1 +x:1 +钱粮 1 +x:1 +码 10 +x:10 +清洁器 1 +x:1 +保持者 1 +x:1 +绸面 1 +x:1 +碘片 1 +x:1 +恍然 1 +x:1 +钢管厂 1 +x:1 +石棉瓦 1 +x:1 +中国画 1 +x:1 +铜锣湾 1 +x:1 +水西沟 1 +x:1 +自益权 1 +x:1 +树荫 1 +x:1 +情节性 1 +x:1 +售票处 1 +x:1 +丧气 1 +x:1 +趋附 1 +x:1 +牌牌 1 +x:1 +监护席 1 +x:1 +心焦 1 +x:1 +蓬头垢面 1 +x:1 +空空荡荡 1 +x:1 +长明灯 1 +x:1 +瞬时速度 1 +x:1 +通晓 1 +x:1 +痴愚世延 1 +x:1 +共青团员 1 +x:1 +和面 1 +x:1 +覆盖 1 +x:1 +运抵 1 +x:1 +治政 1 +x:1 +沉井 1 +x:1 +恰穆拉镇 1 +x:1 +冉冉 1 +x:1 +苑家屯 1 +x:1 +级差 1 +x:1 +哞 2 +x:2 +奥里萨邦 1 +x:1 +毒化 1 +x:1 +金雕 1 +x:1 +藁城市 1 +x:1 +科技型 1 +x:1 +纪念型 1 +x:1 +掩体 1 +x:1 +铭志 1 +x:1 +能效 1 +x:1 +排沙简金 1 +x:1 +滩羊 1 +x:1 +幅员辽阔 1 +x:1 +沾沾自喜 1 +x:1 +米汤 1 +x:1 +春分点 1 +x:1 +圣卢西亚 1 +x:1 +游刃有余 1 +x:1 +清洌洌 1 +x:1 +半边山 1 +x:1 +哀告 1 +x:1 +青松 1 +x:1 +蓬松度 1 +x:1 +有的 1 +x:1 +脊椎骨 1 +x:1 +王家棚 1 +x:1 +造福一方 1 +x:1 +钟 281 +x:281 +家趁万贯 1 +x:1 +泰晤士报 1 +x:1 +鼎鼎大名 1 +x:1 +并网发电 1 +x:1 +等温线 1 +x:1 +鞋城 1 +x:1 +审判组 1 +x:1 +铁公鸡 1 +x:1 +抢答 1 +x:1 +雅者 1 +x:1 +担儿 1 +x:1 +豆瓣 1 +x:1 +描花扣 1 +x:1 +手笔 1 +x:1 +前不久 1 +x:1 +动心 1 +x:1 +青杏 1 +x:1 +升降舵 1 +x:1 +诗文 1 +x:1 +荆庄乡 1 +x:1 +同喜同乐 1 +x:1 +鞋垫 1 +x:1 +虎仔 1 +x:1 +国旗 1 +x:1 +反动派 1 +x:1 +洪亮 1 +x:1 +家地乡 1 +x:1 +塞舌尔 1 +x:1 +音位 1 +x:1 +创益 1 +x:1 +奏鸣曲 1 +x:1 +恩同再造 1 +x:1 +书刊 1 +x:1 +滩簧 1 +x:1 +扣头 1 +x:1 +翟坡村 1 +x:1 +惧 11 +x:11 +三清山 1 +x:1 +荒蔓 1 +x:1 +下费桥 1 +x:1 +原材料 1 +x:1 +工联会 1 +x:1 +纳 30 +x:30 +军需处 1 +x:1 +反革命 1 +x:1 +亲临感 1 +x:1 +营垒 1 +x:1 +风气者 1 +x:1 +雕塑家 1 +x:1 +牌照 1 +x:1 +哀哀 1 +x:1 +钻台 1 +x:1 +愚陋 1 +x:1 +遗留物 1 +x:1 +热风炉 1 +x:1 +刑事犯罪 1 +x:1 +摇摇晃晃 1 +x:1 +风色 1 +x:1 +橡皮筋 1 +x:1 +外向度 1 +x:1 +吟 26 +x:26 +纪念品 1 +x:1 +帕村 1 +x:1 +平平静静 1 +x:1 +场馆 1 +x:1 +上下位 1 +x:1 +有道是 1 +x:1 +纹理 1 +x:1 +心爱 1 +x:1 +传染病 1 +x:1 +户证科 1 +x:1 +醒豁 1 +x:1 +动弹 1 +x:1 +白暨豚 1 +x:1 +卢浮宫街 1 +x:1 +耕地 1 +x:1 +调馅 1 +x:1 +青枣 1 +x:1 +金门 1 +x:1 +羞与为伍 1 +x:1 +炸雷 1 +x:1 +阴丹士林 1 +x:1 +青果 1 +x:1 +坤宁宫 1 +x:1 +楠杆镇 1 +x:1 +银杏园 1 +x:1 +凸显 1 +x:1 +君子协定 1 +x:1 +货摊 1 +x:1 +批注 1 +x:1 +黑地 1 +x:1 +缓和 1 +x:1 +音专 1 +x:1 +凌辱 1 +x:1 +心率 1 +x:1 +鲜活欲滴 1 +x:1 +勒令 1 +x:1 +哀兵必胜 1 +x:1 +粘着剂 1 +x:1 +8 1097 +x:1097 +手稿 1 +x:1 +焜 1 +x:1 +半军事化 1 +x:1 +橡皮管 1 +x:1 +纷纭复杂 1 +x:1 +阎王 1 +x:1 +两手 1 +x:1 +渴求 1 +x:1 +炕洞 1 +x:1 +黑土 1 +x:1 +缩编 1 +x:1 +幻灭 1 +x:1 +显明 1 +x:1 +小旦 1 +x:1 +多发性 1 +x:1 +中顾委 1 +x:1 +函授 1 +x:1 +维护型 1 +x:1 +难闻 1 +x:1 +煞气 1 +x:1 +音乐 1 +x:1 +捉襟见肘 1 +x:1 +贮存 1 +x:1 +青春 1 +x:1 +音义 1 +x:1 +酥油 1 +x:1 +友谊林 1 +x:1 +噶尔丹 1 +x:1 +致贺 1 +x:1 +放射形 1 +x:1 +斗牛 1 +x:1 +瞻 12 +x:12 +左轮 1 +x:1 +育肥场 1 +x:1 +组织胺 1 +x:1 +长崎县 1 +x:1 +电气化率 1 +x:1 +重外孙女 1 +x:1 +妖怪 1 +x:1 +即使如此 1 +x:1 +商贸城 1 +x:1 +先进县 1 +x:1 +金钱 1 +x:1 +横征暴敛 1 +x:1 +阻击战 1 +x:1 +是味儿 1 +x:1 +下礼拜 1 +x:1 +左边 1 +x:1 +分销点 1 +x:1 +早稻 1 +x:1 +量子论 1 +x:1 +金钢 1 +x:1 +饮食部 1 +x:1 +软化 1 +x:1 +示范员 1 +x:1 +风荷 1 +x:1 +劫波 1 +x:1 +接货船 1 +x:1 +小马村 1 +x:1 +杂沓 1 +x:1 +质监 1 +x:1 +奉天 1 +x:1 +清洁员 1 +x:1 +镁光灯 1 +x:1 +祥瑞 1 +x:1 +幽邃 1 +x:1 +金针 1 +x:1 +科局级 1 +x:1 +凭眺 1 +x:1 +钻劲 1 +x:1 +尽职尽责 1 +x:1 +启程 1 +x:1 +绿萼梅 1 +x:1 +金银 1 +x:1 +农校 1 +x:1 +游泳队 1 +x:1 +法文学 1 +x:1 +肉肉 1 +x:1 +嫖 2 +x:2 +食指 1 +x:1 +采茶戏 1 +x:1 +诠 1 +x:1 +医师 1 +x:1 +真正 1 +x:1 +风范 1 +x:1 +突袭 1 +x:1 +不随意肌 1 +x:1 +定论 1 +x:1 +内外线 1 +x:1 +鹅卵 1 +x:1 +讳疾忌医 1 +x:1 +寒意 1 +x:1 +节目片 1 +x:1 +分色镜 1 +x:1 +多发期 1 +x:1 +双池 1 +x:1 +雄居 1 +x:1 +酸甜苦辣 1 +x:1 +等外路 1 +x:1 +一呼百应 1 +x:1 +停车棚 1 +x:1 +幢幢 1 +x:1 +音准 1 +x:1 +文武双全 1 +x:1 +正色 1 +x:1 +雅化 1 +x:1 +把持 1 +x:1 +奴隶社会 1 +x:1 +前人 1 +x:1 +集邮联 1 +x:1 +义县 1 +x:1 +怨 19 +x:19 +尺码 1 +x:1 +脊岭 1 +x:1 +修葺 1 +x:1 +双江 1 +x:1 +中国热 1 +x:1 +耳鼓膜 1 +x:1 +二把手 1 +x:1 +生拉硬拽 1 +x:1 +放心桥 1 +x:1 +闪光灯 1 +x:1 +旱浇田 1 +x:1 +作客思想 1 +x:1 +数码 1 +x:1 +空前绝后 1 +x:1 +梅园新村 1 +x:1 +黑褐色 1 +x:1 +局长级 1 +x:1 +姥爷 1 +x:1 +四站镇 1 +x:1 +生成点 1 +x:1 +前任 1 +x:1 +持卡者 1 +x:1 +单列 1 +x:1 +兰因絮果 1 +x:1 +草泽 1 +x:1 +寒暑 1 +x:1 +输血式 1 +x:1 +仿单 1 +x:1 +留学人员 1 +x:1 +幽静 1 +x:1 +方桥镇 1 +x:1 +耳聪目明 1 +x:1 +寒暄 1 +x:1 +集邮者 1 +x:1 +匀整 1 +x:1 +残缺不全 1 +x:1 +多付 1 +x:1 +示范县 1 +x:1 +孟公岭 1 +x:1 +人来人往 1 +x:1 +所在区 1 +x:1 +此际 1 +x:1 +原生态 1 +x:1 +肠结核 1 +x:1 +草民 1 +x:1 +邈 1 +x:1 +耕具 1 +x:1 +福全镇 1 +x:1 +叵耐 1 +x:1 +谷坊坝 1 +x:1 +以歌会友 1 +x:1 +双泾 1 +x:1 +突进 1 +x:1 +举报者 1 +x:1 +古北新村 1 +x:1 +中篇小说 1 +x:1 +官衔 1 +x:1 +顺产率 1 +x:1 +共产国际 1 +x:1 +直肠科 1 +x:1 +引水道 1 +x:1 +自由权 1 +x:1 +网队 1 +x:1 +两旁 1 +x:1 +状元村 1 +x:1 +沙田柚 1 +x:1 +写意画 1 +x:1 +怀才不遇 1 +x:1 +杜诗 1 +x:1 +不厌其烦 1 +x:1 +中学 1 +x:1 +义卖 1 +x:1 +开不开张 1 +x:1 +一日游 1 +x:1 +强劲 1 +x:1 +仿古 1 +x:1 +于今 1 +x:1 +禽肉 1 +x:1 +消极面 1 +x:1 +梦遗 1 +x:1 +原种 1 +x:1 +孺子亭路 1 +x:1 +冈陵 1 +x:1 +网际 1 +x:1 +凿 30 +x:30 +双沟 1 +x:1 +雅号 1 +x:1 +微观性 1 +x:1 +把握 1 +x:1 +示范区 1 +x:1 +三亚市 1 +x:1 +纪念卡 1 +x:1 +外胚层 1 +x:1 +整建 1 +x:1 +敬告 1 +x:1 +返潮 1 +x:1 +把戏 1 +x:1 +装束 1 +x:1 +墙 155 +x:155 +碘盐 1 +x:1 +坐位表 1 +x:1 +汊流 1 +x:1 +丛编 1 +x:1 +龙泉乡 1 +x:1 +欤 2 +x:2 +双流 1 +x:1 +本家儿 1 +x:1 +持机者 1 +x:1 +前例 1 +x:1 +邪道 1 +x:1 +牛角湾村 1 +x:1 +锰 9 +x:9 +上等兵 1 +x:1 +心疼 1 +x:1 +义务 1 +x:1 +外援 1 +x:1 +走南闯北 1 +x:1 +诗抄 1 +x:1 +臂膀 1 +x:1 +特优生 1 +x:1 +短促 1 +x:1 +正茬 1 +x:1 +头份厂 1 +x:1 +臂膊 1 +x:1 +心痛 1 +x:1 +建筑商 1 +x:1 +处理量 1 +x:1 +白金 1 +x:1 +传感器 1 +x:1 +把手 1 +x:1 +地老天荒 1 +x:1 +警戒线 1 +x:1 +轻量级 1 +x:1 +定购 1 +x:1 +人民战争 1 +x:1 +仰八叉 1 +x:1 +书册 1 +x:1 +基本电荷 1 +x:1 +定货 1 +x:1 +高黎贡山 1 +x:1 +定责 1 +x:1 +寒极 1 +x:1 +迷 44 +x:44 +端详 1 +x:1 +千手观音 1 +x:1 +守旧 1 +x:1 +采掘业 1 +x:1 +硅钢片 1 +x:1 +电子表 1 +x:1 +繁育 1 +x:1 +于是乎 1 +x:1 +堂妹 1 +x:1 +地地道道 1 +x:1 +臂腕 1 +x:1 +橄榄绿色 1 +x:1 +把把 1 +x:1 +腐殖质 1 +x:1 +湿货 1 +x:1 +迷离 1 +x:1 +美食节 1 +x:1 +黏着力 1 +x:1 +孟菲斯市 1 +x:1 +维修工 1 +x:1 +早晚市 1 +x:1 +短传 1 +x:1 +米格 1 +x:1 +哀叫 1 +x:1 +清洁剂 1 +x:1 +貌不惊人 1 +x:1 +斜 28 +x:28 +心画 1 +x:1 +同苦共乐 1 +x:1 +彝剧 1 +x:1 +作业会 1 +x:1 +十六国 1 +x:1 +哀号 1 +x:1 +鲁桥镇 1 +x:1 +哀叹 1 +x:1 +白沟镇 1 +x:1 +心电 1 +x:1 +挣扎状 1 +x:1 +打印纸 1 +x:1 +质点 1 +x:1 +收割 1 +x:1 +函数 1 +x:1 +牵线搭桥 1 +x:1 +喧声 1 +x:1 +最低 1 +x:1 +陈埠乡 1 +x:1 +肢骨 1 +x:1 +精纺城 1 +x:1 +坏主意 1 +x:1 +揣度 1 +x:1 +拜金主义 1 +x:1 +蒲扇 1 +x:1 +证法 1 +x:1 +夜战 1 +x:1 +守敌 1 +x:1 +抗宣 1 +x:1 +连鬓胡子 1 +x:1 +草浆 1 +x:1 +凭照 1 +x:1 +不战自败 1 +x:1 +讳疾 1 +x:1 +纪念厅 1 +x:1 +信袋 1 +x:1 +米桶 1 +x:1 +草海 1 +x:1 +褐铁矿 1 +x:1 +幽雅 1 +x:1 +前体 1 +x:1 +健朗 1 +x:1 +杏梅 1 +x:1 +民社党 1 +x:1 +点金成铁 1 +x:1 +争名夺利 1 +x:1 +松日队 1 +x:1 +非银行 1 +x:1 +金融家 1 +x:1 +抓 1518 +x:1518 +四十四分 1 +x:1 +反毒月 1 +x:1 +生长激素 1 +x:1 +剽窃者 1 +x:1 +贫富悬殊 1 +x:1 +喝 290 +x:290 +隐门 1 +x:1 +渠 40 +x:40 +意译 1 +x:1 +特雷维索 1 +x:1 +舌敝唇焦 1 +x:1 +连心路 1 +x:1 +先进团 1 +x:1 +括约肌 1 +x:1 +现代主义 1 +x:1 +摩托车者 1 +x:1 +拉郎配式 1 +x:1 +绿意 1 +x:1 +毒品 1 +x:1 +突起 1 +x:1 +麦片 1 +x:1 +摄影界 1 +x:1 +怵 5 +x:5 +斗眼 1 +x:1 +施 216 +x:216 +边角余料 1 +x:1 +动宾 1 +x:1 +玉石俱焚 1 +x:1 +雅克 1 +x:1 +督察部 1 +x:1 +碘缺乏病 1 +x:1 +煊 1 +x:1 +优质 1 +x:1 +电子论 1 +x:1 +公案 1 +x:1 +重申 1 +x:1 +央托 1 +x:1 +套版 1 +x:1 +长途车 1 +x:1 +钱箱 1 +x:1 +鞋厂 1 +x:1 +难以言表 1 +x:1 +飞驶 1 +x:1 +直翅目 1 +x:1 +风蚀 1 +x:1 +龙岗区 1 +x:1 +突贯 1 +x:1 +购物车 1 +x:1 +草滩 1 +x:1 +查清 1 +x:1 +汊港 1 +x:1 +雅典 1 +x:1 +王家沱 1 +x:1 +雅兴 1 +x:1 +台湾团 1 +x:1 +大笑不止 1 +x:1 +禽兽 1 +x:1 +不可知论 1 +x:1 +生成物 1 +x:1 +重蹈 1 +x:1 +承建者 1 +x:1 +城楼 1 +x:1 +为邻 1 +x:1 +核燃料 1 +x:1 +克当量 1 +x:1 +阙文者 1 +x:1 +水平井 1 +x:1 +煤管局 1 +x:1 +木构 1 +x:1 +信诊 1 +x:1 +仿冒 1 +x:1 +菇床 1 +x:1 +幽禁 1 +x:1 +吞灭 1 +x:1 +北京大学 1 +x:1 +郑店街 1 +x:1 +水泥桩 1 +x:1 +鞋匠 1 +x:1 +一手包办 1 +x:1 +幽闲 1 +x:1 +诗意 1 +x:1 +双溪 1 +x:1 +地热学 1 +x:1 +责任区制 1 +x:1 +侄孙 1 +x:1 +百科全书 1 +x:1 +损失额 1 +x:1 +下辈子 1 +x:1 +幽门 1 +x:1 +信访 1 +x:1 +金融学 1 +x:1 +蓬勃生机 1 +x:1 +裤 9 +x:9 +栖霞山 1 +x:1 +他俩 1 +x:1 +难道 1 +x:1 +汉晋 1 +x:1 +篙头 1 +x:1 +天星村 1 +x:1 +亚洲 1 +x:1 +如鬼似魅 1 +x:1 +诬为 1 +x:1 +资金流 1 +x:1 +文山路 1 +x:1 +通敌 1 +x:1 +诗情 1 +x:1 +二愣子 1 +x:1 +求购者 1 +x:1 +回顾性 1 +x:1 +耿直 1 +x:1 +贮运 1 +x:1 +引力场 1 +x:1 +健旺 1 +x:1 +衣橱 1 +x:1 +收藏业 1 +x:1 +图卡什 1 +x:1 +字书 1 +x:1 +约莫 1 +x:1 +随随便便 1 +x:1 +投机性 1 +x:1 +祭天 1 +x:1 +办理费 1 +x:1 +阿米巴 1 +x:1 +皱 8 +x:8 +头角峥嵘 1 +x:1 +尖石 1 +x:1 +诗想 1 +x:1 +惶惶然 1 +x:1 +商贸厅 1 +x:1 +三河市 1 +x:1 +迷笛 1 +x:1 +侄媳 1 +x:1 +酥梨 1 +x:1 +火辣辣 1 +x:1 +兼职团 1 +x:1 +人民团体 1 +x:1 +和尚头 1 +x:1 +运输船 1 +x:1 +共益权 1 +x:1 +优异者 1 +x:1 +诙谐 1 +x:1 +运输舰 1 +x:1 +长途跋涉 1 +x:1 +半边天 1 +x:1 +他乡 1 +x:1 +兆头 1 +x:1 +祭奠 1 +x:1 +阿克拉 1 +x:1 +拥簇 1 +x:1 +褚褐色 1 +x:1 +鹬蚌相争 1 +x:1 +长生不老 1 +x:1 +摇摆法 1 +x:1 +僵 7 +x:7 +杜衡 1 +x:1 +书画界 1 +x:1 +鸣金 1 +x:1 +覆灭 1 +x:1 +磨磨蹭蹭 1 +x:1 +比利时队 1 +x:1 +守望 1 +x:1 +岂 103 +x:103 +商贸区 1 +x:1 +板栗园 1 +x:1 +言归于好 1 +x:1 +萌芽 1 +x:1 +预约卡 1 +x:1 +警备 1 +x:1 +白桦林 1 +x:1 +随意肌 1 +x:1 +一唱三叹 1 +x:1 +窟窿眼儿 1 +x:1 +心眼 1 +x:1 +铁打江山 1 +x:1 +知人者 1 +x:1 +他人 1 +x:1 +颜料碟 1 +x:1 +清源乡 1 +x:1 +数字化 1 +x:1 +手绢 1 +x:1 +蓬乱 1 +x:1 +暨阳 1 +x:1 +方东村 1 +x:1 +洛河镇 1 +x:1 +手续 1 +x:1 +夯土 1 +x:1 +城根 1 +x:1 +黑口 1 +x:1 +鞋刷 1 +x:1 +洋人 1 +x:1 +诗思 1 +x:1 +市郊区 1 +x:1 +诗性 1 +x:1 +为重 1 +x:1 +抗坏血酸 1 +x:1 +信誉 1 +x:1 +是否 1 +x:1 +广告界 1 +x:1 +梨树 1 +x:1 +他们 1 +x:1 +纪念册 1 +x:1 +开枪 1 +x:1 +滑雪场 1 +x:1 +责任型 1 +x:1 +洋井 1 +x:1 +再宽限期 1 +x:1 +愚不可及 1 +x:1 +输者 1 +x:1 +长鼻目 1 +x:1 +右脚 1 +x:1 +联动 1 +x:1 +猫儿山 1 +x:1 +沛县 1 +x:1 +右脑 1 +x:1 +雪谷 1 +x:1 +丑婆子 1 +x:1 +橄榄球赛 1 +x:1 +中流砥柱 1 +x:1 +把式 1 +x:1 +常平镇 1 +x:1 +宽解 1 +x:1 +罹难日 1 +x:1 +学前教育 1 +x:1 +资不抵债 1 +x:1 +文池楼 1 +x:1 +主焦煤 1 +x:1 +截瘫康丸 1 +x:1 +粗纱机 1 +x:1 +不管怎样 1 +x:1 +开枰 1 +x:1 +政策史 1 +x:1 +分红 1 +x:1 +老交情 1 +x:1 +超爽型 1 +x:1 +门户之见 1 +x:1 +沉睡 1 +x:1 +双城镇 1 +x:1 +曲阜市 1 +x:1 +勤务员 1 +x:1 +肌力 1 +x:1 +省辖市 1 +x:1 +一一列举 1 +x:1 +铡 1 +x:1 +伊盟 1 +x:1 +雪豹 1 +x:1 +伯克兰 1 +x:1 +分给 1 +x:1 +排忧解难 1 +x:1 +城垣 1 +x:1 +喷薄欲出 1 +x:1 +右腕 1 +x:1 +敌进我伏 1 +x:1 +黄河路 1 +x:1 +分组 1 +x:1 +返利 1 +x:1 +班加西市 1 +x:1 +两头 1 +x:1 +完完全全 1 +x:1 +垄断资本 1 +x:1 +冗赘 1 +x:1 +完全小学 1 +x:1 +右腿 1 +x:1 +糟油 1 +x:1 +电话 1 +x:1 +掩盖 1 +x:1 +城垛 1 +x:1 +炮制 1 +x:1 +痹 8 +x:8 +不愧为 1 +x:1 +杏元屯村 1 +x:1 +非伙伴 1 +x:1 +仪节 1 +x:1 +行政公署 1 +x:1 +黑河 1 +x:1 +伊蚊 1 +x:1 +榆 2 +x:2 +忻州市 1 +x:1 +义演 1 +x:1 +青工 1 +x:1 +诗录 1 +x:1 +刨根问底 1 +x:1 +汉巴大桥 1 +x:1 +非船 1 +x:1 +普度众生 1 +x:1 +说白 1 +x:1 +羊齿植物 1 +x:1 +断面 1 +x:1 +谎言 1 +x:1 +青州 1 +x:1 +一步舞 1 +x:1 +黑沟 1 +x:1 +最甚者 1 +x:1 +采宝者 1 +x:1 +货币 1 +x:1 +粤西 1 +x:1 +平心而论 1 +x:1 +两委 1 +x:1 +激烈性 1 +x:1 +短片 1 +x:1 +监护权 1 +x:1 +锤骨 1 +x:1 +剽窃 1 +x:1 +满洲国 1 +x:1 +电烙铁 1 +x:1 +自语 1 +x:1 +晨晚练点 1 +x:1 +自诩 1 +x:1 +雕塑感 1 +x:1 +右臂 1 +x:1 +柚 2 +x:2 +食堂 1 +x:1 +休眠期 1 +x:1 +罗宾汉式 1 +x:1 +面粉票 1 +x:1 +年老多病 1 +x:1 +霸权 1 +x:1 +先进校 1 +x:1 +支气管炎 1 +x:1 +自诉 1 +x:1 +南北街村 1 +x:1 +自识 1 +x:1 +基 24 +x:24 +痴心妄想 1 +x:1 +联贫 1 +x:1 +遨游 1 +x:1 +闭馆 1 +x:1 +青山 1 +x:1 +洋火 1 +x:1 +鉴字 1 +x:1 +开诚布公 1 +x:1 +城固 1 +x:1 +如雷贯耳 1 +x:1 +小萝卜头 1 +x:1 +双关 1 +x:1 +梨园 1 +x:1 +沸反盈天 1 +x:1 +枝繁叶茂 1 +x:1 +昨夜 1 +x:1 +宽裕 1 +x:1 +志愿兵制 1 +x:1 +周期性 1 +x:1 +右耳 1 +x:1 +克利夫兰 1 +x:1 +双先 1 +x:1 +黑洞 1 +x:1 +军需所 1 +x:1 +足 209 +x:209 +报道组 1 +x:1 +边远 1 +x:1 +半导体 1 +x:1 +辨症 1 +x:1 +秉性 1 +x:1 +明斯特 1 +x:1 +掂量掂量 1 +x:1 +教练席 1 +x:1 +黑海 1 +x:1 +级数 1 +x:1 +易县 1 +x:1 +莱阳 1 +x:1 +市立 1 +x:1 +控制额 1 +x:1 +鞋油 1 +x:1 +安置率 1 +x:1 +谎说 1 +x:1 +科威特塔 1 +x:1 +汽联 1 +x:1 +蕾铃 1 +x:1 +水泥城 1 +x:1 +小马陵村 1 +x:1 +板栗树 1 +x:1 +大回转 1 +x:1 +山顶洞 1 +x:1 +引黄入晋 1 +x:1 +谎话 1 +x:1 +巷子 1 +x:1 +象声词 1 +x:1 +祥云 1 +x:1 +溢美 1 +x:1 +胸腔 1 +x:1 +说东道西 1 +x:1 +黑液 1 +x:1 +青峰 1 +x:1 +沁源县 1 +x:1 +守夜 1 +x:1 +野地 1 +x:1 +补码 1 +x:1 +组织部 1 +x:1 +拿腔拿调 1 +x:1 +绘画展 1 +x:1 +青峦 1 +x:1 +印花税 1 +x:1 +固体潮 1 +x:1 +守备 1 +x:1 +富阳 1 +x:1 +径向 1 +x:1 +右肺 1 +x:1 +宽街 1 +x:1 +正中 1 +x:1 +附表 1 +x:1 +深呼吸 1 +x:1 +镇日 1 +x:1 +重婚罪 1 +x:1 +人力车 1 +x:1 +动摇 1 +x:1 +殖民 1 +x:1 +此碑 1 +x:1 +接力赛 1 +x:1 +丧命 1 +x:1 +斑点 1 +x:1 +砖头 1 +x:1 +毛乎乎 1 +x:1 +扣押 1 +x:1 +青岭 1 +x:1 +妖媚 1 +x:1 +莱法州 1 +x:1 +青岩 1 +x:1 +大面儿上 1 +x:1 +玉皇顶 1 +x:1 +分署 1 +x:1 +望子成龙 1 +x:1 +城设通 1 +x:1 +单极 1 +x:1 +稽查队员 1 +x:1 +青山区 1 +x:1 +民族党 1 +x:1 +青岚 1 +x:1 +青岛 1 +x:1 +哨兵 1 +x:1 +整装待发 1 +x:1 +水泥块 1 +x:1 +哀求 1 +x:1 +挽具 1 +x:1 +大气压 1 +x:1 +薅 1 +x:1 +边线 1 +x:1 +附识 1 +x:1 +借债人 1 +x:1 +路服 1 +x:1 +边关 1 +x:1 +显影液 1 +x:1 +三位一体 1 +x:1 +中国人 1 +x:1 +秉持 1 +x:1 +两河镇 1 +x:1 +招标会 1 +x:1 +前点 1 +x:1 +贪生怕死 1 +x:1 +寒士 1 +x:1 +苦笑 1 +x:1 +拜访 1 +x:1 +铜版纸 1 +x:1 +首饰 1 +x:1 +房贷部 1 +x:1 +北大荒 1 +x:1 +警策 1 +x:1 +此笔 1 +x:1 +町 1 +x:1 +汤更浪队 1 +x:1 +丘陵 1 +x:1 +存贷款 1 +x:1 +有破有立 1 +x:1 +哀鸣 1 +x:1 +显影 1 +x:1 +传销 1 +x:1 +火柴盒 1 +x:1 +米埔 1 +x:1 +归纳法 1 +x:1 +显形 1 +x:1 +借出 1 +x:1 +沉甸 1 +x:1 +遗鸥 1 +x:1 +安置点 1 +x:1 +失败率 1 +x:1 +此等 1 +x:1 +满分者 1 +x:1 +服服帖帖 1 +x:1 +釉色 1 +x:1 +在商言商 1 +x:1 +拜读 1 +x:1 +消费额 1 +x:1 +附设 1 +x:1 +张截港 1 +x:1 +锦官城 1 +x:1 +贷款性 1 +x:1 +此策 1 +x:1 +尾流 1 +x:1 +冤枉钱 1 +x:1 +自策 1 +x:1 +附记 1 +x:1 +乱发 1 +x:1 +草创 1 +x:1 +胃扩张 1 +x:1 +纪实性 1 +x:1 +创世 1 +x:1 +投诉性 1 +x:1 +创业 1 +x:1 +代代不已 1 +x:1 +三评一考 1 +x:1 +大显身手 1 +x:1 +煤气费 1 +x:1 +显微 1 +x:1 +创下 1 +x:1 +匀实 1 +x:1 +朴刀 1 +x:1 +属区 1 +x:1 +质保 1 +x:1 +高空槽 1 +x:1 +理想 1 +x:1 +新西兰队 1 +x:1 +创举 1 +x:1 +显得 1 +x:1 +轿夫 1 +x:1 +毁灭论 1 +x:1 +肩周炎 1 +x:1 +名来利往 1 +x:1 +展销会 1 +x:1 +尿 21 +x:21 +养牛厂 1 +x:1 +动机 1 +x:1 +后妈 1 +x:1 +鸭绿江口 1 +x:1 +扬场机 1 +x:1 +双加 1 +x:1 +前灯 1 +x:1 +修订本 1 +x:1 +两审 1 +x:1 +首首 1 +x:1 +说理 1 +x:1 +雨衣 1 +x:1 +不出意外 1 +x:1 +华罗庚 1 +x:1 +王桥村 1 +x:1 +分米 1 +x:1 +彩 30 +x:30 +分类 1 +x:1 +紊乱 1 +x:1 +奔逐 1 +x:1 +温柔乡 1 +x:1 +救援车 1 +x:1 +废塑料 1 +x:1 +联防队 1 +x:1 +自觅 1 +x:1 +搭线 1 +x:1 +生物制品 1 +x:1 +行市 1 +x:1 +钓者 1 +x:1 +胶合剂 1 +x:1 +青年 1 +x:1 +抱薪救火 1 +x:1 +立足之地 1 +x:1 +朴厚 1 +x:1 +边路 1 +x:1 +字牌 1 +x:1 +汽船 1 +x:1 +喏 2 +x:2 +秦楼楚馆 1 +x:1 +荷花 1 +x:1 +分流口 1 +x:1 +名都 1 +x:1 +不可御遏 1 +x:1 +于焉 1 +x:1 +样装 1 +x:1 +洋片 1 +x:1 +双千 1 +x:1 +双十 1 +x:1 +回天之力 1 +x:1 +莫 197 +x:197 +后来者 1 +x:1 +尾气 1 +x:1 +蓝宝石 1 +x:1 +洋牌 1 +x:1 +话务 1 +x:1 +黑漂 1 +x:1 +证券 1 +x:1 +嘎秧舞 1 +x:1 +浴池 1 +x:1 +豪歌壮鼓 1 +x:1 +非集体 1 +x:1 +民族史 1 +x:1 +商业区 1 +x:1 +名邮 1 +x:1 +收藏版 1 +x:1 +劫后 1 +x:1 +噎 1 +x:1 +最为 1 +x:1 +肩扛手提 1 +x:1 +鹅毛 1 +x:1 +唤头 1 +x:1 +松明子 1 +x:1 +下半生 1 +x:1 +黑潮 1 +x:1 +食宿 1 +x:1 +早早 1 +x:1 +青山冲 1 +x:1 +秉承 1 +x:1 +他物 1 +x:1 +云龙湖 1 +x:1 +支委会 1 +x:1 +小说学 1 +x:1 +草叶 1 +x:1 +自行 1 +x:1 +焦躁 1 +x:1 +汽艇 1 +x:1 +名邑 1 +x:1 +鹿死谁手 1 +x:1 +回顾展 1 +x:1 +食客 1 +x:1 +高山湖 1 +x:1 +远近纵横 1 +x:1 +祭文 1 +x:1 +夯歌 1 +x:1 +创优 1 +x:1 +义气 1 +x:1 +痴子 1 +x:1 +听讲 1 +x:1 +自责 1 +x:1 +中猿乐町 1 +x:1 +慕尼黑 1 +x:1 +草包 1 +x:1 +名利观 1 +x:1 +深井式 1 +x:1 +民族化 1 +x:1 +自动化 1 +x:1 +腰酸背疼 1 +x:1 +建党 1 +x:1 +双双 1 +x:1 +劣马 1 +x:1 +星星之火 1 +x:1 +拍桌子 1 +x:1 +仲 34 +x:34 +谵 1 +x:1 +啄 5 +x:5 +创伤 1 +x:1 +无纺布 1 +x:1 +千军万马 1 +x:1 +小说家 1 +x:1 +蜜月团 1 +x:1 +弹道导弹 1 +x:1 +腰酸背痛 1 +x:1 +首领 1 +x:1 +新机场 1 +x:1 +苦竹 1 +x:1 +诈骗 1 +x:1 +附言 1 +x:1 +创作 1 +x:1 +边贸 1 +x:1 +拖 134 +x:134 +人文科学 1 +x:1 +寒天 1 +x:1 +拉都路 1 +x:1 +祭日 1 +x:1 +围脖儿 1 +x:1 +算井子 1 +x:1 +稍稍 1 +x:1 +鄜县 1 +x:1 +循序渐进 1 +x:1 +酥油灯 1 +x:1 +停车场 1 +x:1 +邮寄费 1 +x:1 +苏阿佩港 1 +x:1 +溧城 1 +x:1 +干眼症 1 +x:1 +禁渔区 1 +x:1 +意在言外 1 +x:1 +心烦意躁 1 +x:1 +栈 1 +x:1 +将军体 1 +x:1 +鞍 2 +x:2 +优先 1 +x:1 +小洋岙村 1 +x:1 +哈密顿圈 1 +x:1 +尾欠 1 +x:1 +守岁 1 +x:1 +广告人 1 +x:1 +伊犁 1 +x:1 +沸水 1 +x:1 +乌烟瘴气 1 +x:1 +双呆 1 +x:1 +贴题 1 +x:1 +放逐 1 +x:1 +扣杀 1 +x:1 +赤铜矿 1 +x:1 +减肥茶 1 +x:1 +长宁县 1 +x:1 +皇姑区 1 +x:1 +大兴安岭 1 +x:1 +秀屿镇 1 +x:1 +不可 1 +x:1 +青头 1 +x:1 +锋刃 1 +x:1 +某地 1 +x:1 +感召力 1 +x:1 +铅山县 1 +x:1 +收藏界 1 +x:1 +分站 1 +x:1 +绞肠痧 1 +x:1 +把子 1 +x:1 +自转 1 +x:1 +刚愎自用 1 +x:1 +青大 1 +x:1 +义母 1 +x:1 +砂金 1 +x:1 +劳动手段 1 +x:1 +健康 1 +x:1 +裤管 1 +x:1 +青天 1 +x:1 +雪衣 1 +x:1 +心无二用 1 +x:1 +毒源 1 +x:1 +信托业 1 +x:1 +劫匪 1 +x:1 +外秘级 1 +x:1 +祭扫 1 +x:1 +腮 6 +x:6 +荷藕 1 +x:1 +道木 1 +x:1 +减肥药 1 +x:1 +洪炉 1 +x:1 +双吐 1 +x:1 +创造性 1 +x:1 +花前月下 1 +x:1 +字画 1 +x:1 +幼 21 +x:21 +征地费 1 +x:1 +教学组 1 +x:1 +样车 1 +x:1 +洪灾 1 +x:1 +返国 1 +x:1 +鞋楦 1 +x:1 +单人独马 1 +x:1 +鹅冠草 1 +x:1 +遗风 1 +x:1 +京韵大鼓 1 +x:1 +倡议 1 +x:1 +把守 1 +x:1 +矿务局 1 +x:1 +广告主 1 +x:1 +云航 1 +x:1 +分工合作 1 +x:1 +返回 1 +x:1 +诗学 1 +x:1 +求真务实 1 +x:1 +计提 1 +x:1 +竹书纪年 1 +x:1 +自贡市 1 +x:1 +牌位 1 +x:1 +南沙 1 +x:1 +投机家 1 +x:1 +广告业 1 +x:1 +高山榕 1 +x:1 +城南 1 +x:1 +音值 1 +x:1 +布告栏 1 +x:1 +独生女 1 +x:1 +总指挥员 1 +x:1 +衣冠 1 +x:1 +自述 1 +x:1 +引力波 1 +x:1 +炮台 1 +x:1 +寒带 1 +x:1 +敌强我弱 1 +x:1 +喧闹 1 +x:1 +祭拜 1 +x:1 +直布罗陀 1 +x:1 +把门人 1 +x:1 +怨天怨地 1 +x:1 +自由式 1 +x:1 +沸泉 1 +x:1 +动感 1 +x:1 +逍遥自在 1 +x:1 +最高价 1 +x:1 +米兰 1 +x:1 +维琴察队 1 +x:1 +运往 1 +x:1 +滚动摩擦 1 +x:1 +米公 1 +x:1 +看家本领 1 +x:1 +护园人 1 +x:1 +城北 1 +x:1 +昂热市 1 +x:1 +雨季 1 +x:1 +中坚层 1 +x:1 +亮晶晶 1 +x:1 +哀歌 1 +x:1 +勤务兵 1 +x:1 +斋堂川 1 +x:1 +群体部 1 +x:1 +园丁 1 +x:1 +武士道 1 +x:1 +变电器 1 +x:1 +科威特尔 1 +x:1 +前瞻 1 +x:1 +倡言 1 +x:1 +市级 1 +x:1 +邮戳 1 +x:1 +水泥厂 1 +x:1 +健心 1 +x:1 +分销业 1 +x:1 +分管 1 +x:1 +健忘 1 +x:1 +监测网站 1 +x:1 +航空母舰 1 +x:1 +蝗灾 1 +x:1 +徒子徒孙 1 +x:1 +波尔多队 1 +x:1 +北大营 1 +x:1 +起因 1 +x:1 +工艺瓷 1 +x:1 +西南营村 1 +x:1 +攀缘茎 1 +x:1 +自由度 1 +x:1 +枫丹白露 1 +x:1 +较技 1 +x:1 +治安室 1 +x:1 +此类 1 +x:1 +圣徒 1 +x:1 +寒微 1 +x:1 +库涅茨克 1 +x:1 +联成一气 1 +x:1 +铁丝 1 +x:1 +商丘市 1 +x:1 +洋球 1 +x:1 +双唇 1 +x:1 +大石桥市 1 +x:1 +偿还 1 +x:1 +短短 1 +x:1 +锁骨 1 +x:1 +罗洪乡 1 +x:1 +药石 1 +x:1 +青堆 1 +x:1 +蹲 70 +x:70 +重创 1 +x:1 +捐助款 1 +x:1 +尚方剑 1 +x:1 +争夺战 1 +x:1 +典 9 +x:9 +秧田 1 +x:1 +接线牌 1 +x:1 +常温层 1 +x:1 +长途电话 1 +x:1 +拜谒 1 +x:1 +应用 1 +x:1 +怠工 1 +x:1 +车费 1 +x:1 +卷筒式 1 +x:1 +汽蒸 1 +x:1 +物欲化 1 +x:1 +独 98 +x:98 +某团 1 +x:1 +洋瓷 1 +x:1 +惊天地 1 +x:1 +预选赛 1 +x:1 +曲作者 1 +x:1 +坦直 1 +x:1 +毒潮 1 +x:1 +王家坝 1 +x:1 +病虫害 1 +x:1 +金融性 1 +x:1 +水利工程 1 +x:1 +溜坍 1 +x:1 +浮尘子 1 +x:1 +上涨率 1 +x:1 +建莲 1 +x:1 +后头 1 +x:1 +茬茬 1 +x:1 +挽回 1 +x:1 +王家坪 1 +x:1 +泔水桶 1 +x:1 +人口学家 1 +x:1 +酷刑 1 +x:1 +消音器 1 +x:1 +鸽 13 +x:13 +水泥化 1 +x:1 +丧偶 1 +x:1 +牙周 1 +x:1 +七零八碎 1 +x:1 +电灶 1 +x:1 +听证 1 +x:1 +幽寂 1 +x:1 +标准单位 1 +x:1 +一波三折 1 +x:1 +摇摆器 1 +x:1 +鞋样 1 +x:1 +气数 1 +x:1 +两岸 1 +x:1 +分等 1 +x:1 +黑洞洞 1 +x:1 +修改建 1 +x:1 +梢头 1 +x:1 +剥 24 +x:24 +一小二私 1 +x:1 +丙烯腈 1 +x:1 +动怒 1 +x:1 +牌上 1 +x:1 +丧假 1 +x:1 +安全史 1 +x:1 +淡红色 1 +x:1 +正乙祠 1 +x:1 +如闻其声 1 +x:1 +凌海市 1 +x:1 +双喜 1 +x:1 +动态 1 +x:1 +心事 1 +x:1 +昀 2 +x:2 +咸宁 1 +x:1 +自费 1 +x:1 +干血浆 1 +x:1 +苏干湖 1 +x:1 +无知者 1 +x:1 +名门 1 +x:1 +痴呆呆 1 +x:1 +上下班 1 +x:1 +哀悼日 1 +x:1 +清洁槽 1 +x:1 +康乃馨 1 +x:1 +米厂 1 +x:1 +弼时镇 1 +x:1 +车身 1 +x:1 +涝 12 +x:12 +自贡 1 +x:1 +附近 1 +x:1 +人满为患 1 +x:1 +自负 1 +x:1 +把头 1 +x:1 +聚众斗殴 1 +x:1 +冷轧厂 1 +x:1 +肯 121 +x:121 +材料 1 +x:1 +太空人 1 +x:1 +择捉 1 +x:1 +伪装 1 +x:1 +无意间 1 +x:1 +芗剧 1 +x:1 +木结构 1 +x:1 +旁若无人 1 +x:1 +杨楼庄 1 +x:1 +两强 1 +x:1 +丛集 1 +x:1 +两弹 1 +x:1 +径取 1 +x:1 +队规 1 +x:1 +显学 1 +x:1 +心仪 1 +x:1 +草图 1 +x:1 +医疗站 1 +x:1 +麻将桌 1 +x:1 +城内 1 +x:1 +上座率 1 +x:1 +左民党 1 +x:1 +纪念树 1 +x:1 +秧歌队 1 +x:1 +料理台 1 +x:1 +草团 1 +x:1 +茅山 1 +x:1 +落价 1 +x:1 +寒山 1 +x:1 +明黄 1 +x:1 +将军碑村 1 +x:1 +白磷 1 +x:1 +长沙市 1 +x:1 +旗开得胜 1 +x:1 +钙 25 +x:25 +思忖 1 +x:1 +夕 16 +x:16 +双困 1 +x:1 +城关 1 +x:1 +瞑目 1 +x:1 +结账会 1 +x:1 +加那利 1 +x:1 +双排座 1 +x:1 +心中 1 +x:1 +少壮派 1 +x:1 +膛线 1 +x:1 +天理教 1 +x:1 +投靠 1 +x:1 +汁液 1 +x:1 +恶魔 1 +x:1 +毒汁 1 +x:1 +党团员 1 +x:1 +诉冤 1 +x:1 +来源国 1 +x:1 +年产奶 1 +x:1 +车板 1 +x:1 +海红树 1 +x:1 +工资袋 1 +x:1 +冗词 1 +x:1 +新机制 1 +x:1 +棵子 1 +x:1 +赫赫功绩 1 +x:1 +慷慨 1 +x:1 +中台办 1 +x:1 +放映队 1 +x:1 +临西县 1 +x:1 +坐枋 1 +x:1 +叶公好龙 1 +x:1 +贵馆 1 +x:1 +尖东 1 +x:1 +梳妆 1 +x:1 +毒气 1 +x:1 +凭吊者 1 +x:1 +风雨衣 1 +x:1 +健将 1 +x:1 +遗骨 1 +x:1 +火居道士 1 +x:1 +冷暖自知 1 +x:1 +自致性 1 +x:1 +潋滟 1 +x:1 +转业军人 1 +x:1 +采矿权 1 +x:1 +遗骸 1 +x:1 +医疗箱 1 +x:1 +尾根 1 +x:1 +草垛 1 +x:1 +诗壁 1 +x:1 +哈拉雷 1 +x:1 +誉 19 +x:19 +科威特市 1 +x:1 +怀仁堂 1 +x:1 +来源地 1 +x:1 +覆盖面 1 +x:1 +舞剧院 1 +x:1 +蘖 2 +x:2 +于田 1 +x:1 +华欣 1 +x:1 +想头 1 +x:1 +痴心 1 +x:1 +示范棚 1 +x:1 +益气养阴 1 +x:1 +金币 1 +x:1 +落体 1 +x:1 +奉新 1 +x:1 +分离 1 +x:1 +政复 1 +x:1 +草垫 1 +x:1 +不规则 1 +x:1 +耿介 1 +x:1 +车辆 1 +x:1 +书费 1 +x:1 +显威 1 +x:1 +边角 1 +x:1 +中国银行 1 +x:1 +思念 1 +x:1 +分秒 1 +x:1 +诗境 1 +x:1 +河间市 1 +x:1 +喧扰 1 +x:1 +车迹 1 +x:1 +永恒性 1 +x:1 +摩苏尔 1 +x:1 +输送车 1 +x:1 +尾桨 1 +x:1 +正体 1 +x:1 +自豪 1 +x:1 +旅行包 1 +x:1 +绍丝印 1 +x:1 +工间操 1 +x:1 +恶骂 1 +x:1 +南关镇 1 +x:1 +四眼井 1 +x:1 +友谊宫 1 +x:1 +瞻前顾后 1 +x:1 +脊柱 1 +x:1 +新春伊始 1 +x:1 +棵 238 +x:238 +各项 1 +x:1 +落伍 1 +x:1 +签到室 1 +x:1 +得胜河 1 +x:1 +潇洒 1 +x:1 +撂 17 +x:17 +祖公 1 +x:1 +良种 1 +x:1 +斗争 1 +x:1 +挂彩 1 +x:1 +鬓 2 +x:2 +衣勾 1 +x:1 +贫嘴薄舌 1 +x:1 +基础理论 1 +x:1 +思考者 1 +x:1 +双基 1 +x:1 +青嫩 1 +x:1 +售票机 1 +x:1 +草场 1 +x:1 +双城 1 +x:1 +草地 1 +x:1 +宜兴 1 +x:1 +米制 1 +x:1 +分社 1 +x:1 +禁放者 1 +x:1 +树脂 1 +x:1 +联系面 1 +x:1 +净月潭 1 +x:1 +平息 1 +x:1 +草圣 1 +x:1 +准钓证 1 +x:1 +煤气表 1 +x:1 +车轴 1 +x:1 +伍伦贡 1 +x:1 +两度 1 +x:1 +耐读 1 +x:1 +车载 1 +x:1 +分神 1 +x:1 +重庆路 1 +x:1 +评委会 1 +x:1 +收容所 1 +x:1 +货运量 1 +x:1 +种养业 1 +x:1 +多面角 1 +x:1 +有益 1 +x:1 +车轮 1 +x:1 +示范校 1 +x:1 +九里山乡 1 +x:1 +色鬼 1 +x:1 +零敲碎打 1 +x:1 +联调 1 +x:1 +述 26 +x:26 +苦练 1 +x:1 +优惠待遇 1 +x:1 +开曼 1 +x:1 +发聋振聩 1 +x:1 +败走麦城 1 +x:1 +实施型 1 +x:1 +附中队 1 +x:1 +教学片 1 +x:1 +两全 1 +x:1 +因小见大 1 +x:1 +实证化 1 +x:1 +急起直追 1 +x:1 +绿地 1 +x:1 +青啤 1 +x:1 +敬慕 1 +x:1 +谎花 1 +x:1 +琅 7 +x:7 +姜芋 1 +x:1 +普通店村 1 +x:1 +主导权 1 +x:1 +听话 1 +x:1 +队组 1 +x:1 +多发区 1 +x:1 +莲花 1 +x:1 +西跨湖村 1 +x:1 +成药 1 +x:1 +双塔 1 +x:1 +自救费 1 +x:1 +音素 1 +x:1 +搭理 1 +x:1 +蹄 10 +x:10 +掉队 1 +x:1 +地面水 1 +x:1 +敬意 1 +x:1 +前端 1 +x:1 +此行 1 +x:1 +担保人 1 +x:1 +卒 11 +x:11 +城徽 1 +x:1 +干瘪瘪 1 +x:1 +外族 1 +x:1 +情欲 1 +x:1 +胖头鱼 1 +x:1 +关键点 1 +x:1 +举国体制 1 +x:1 +帮孤助残 1 +x:1 +大红人 1 +x:1 +自荐 1 +x:1 +复利率 1 +x:1 +联语 1 +x:1 +横路山 1 +x:1 +鉴别 1 +x:1 +哈洽会 1 +x:1 +背风处 1 +x:1 +前站 1 +x:1 +班克斯塘 1 +x:1 +附加费 1 +x:1 +大字报 1 +x:1 +义望 1 +x:1 +守候 1 +x:1 +优秀生 1 +x:1 +博斯腾湖 1 +x:1 +奔驶 1 +x:1 +救国团 1 +x:1 +可比价格 1 +x:1 +短程 1 +x:1 +黑钨矿 1 +x:1 +奔马 1 +x:1 +担保书 1 +x:1 +示范村 1 +x:1 +胃扩大症 1 +x:1 +仅此而已 1 +x:1 +驱动器 1 +x:1 +草堂 1 +x:1 +诗坛 1 +x:1 +一刀两断 1 +x:1 +株洲 1 +x:1 +处身 1 +x:1 +毒打 1 +x:1 +草堰 1 +x:1 +广采博纳 1 +x:1 +常理 1 +x:1 +前程 1 +x:1 +蒲圻 1 +x:1 +追回记 1 +x:1 +碳酸气 1 +x:1 +百花丛 1 +x:1 +短稿 1 +x:1 +大撒把 1 +x:1 +毒手 1 +x:1 +匀净 1 +x:1 +澳人治澳 1 +x:1 +小枣 1 +x:1 +草字头儿 1 +x:1 +夹丝玻璃 1 +x:1 +坦白 1 +x:1 +衡估 1 +x:1 +簇射波 1 +x:1 +女儿红 1 +x:1 +泛神论 1 +x:1 +釉里 1 +x:1 +勒索 1 +x:1 +忆苦思甜 1 +x:1 +马贼 1 +x:1 +查案 1 +x:1 +南通社 1 +x:1 +商丘县 1 +x:1 +以工代赈 1 +x:1 +诗圣 1 +x:1 +淮海中路 1 +x:1 +高山族 1 +x:1 +装饰帽 1 +x:1 +幽婉 1 +x:1 +先进性 1 +x:1 +树蛙 1 +x:1 +宁津镇 1 +x:1 +九连环 1 +x:1 +金融流 1 +x:1 +袁 356 +x:356 +守军 1 +x:1 +伤寒论 1 +x:1 +凛凛 1 +x:1 +铭心刻骨 1 +x:1 +造访 1 +x:1 +纪念杯 1 +x:1 +阶梯式 1 +x:1 +各队 1 +x:1 +纲领 1 +x:1 +翌日 1 +x:1 +仲裁案 1 +x:1 +谆谆教导 1 +x:1 +热轧厂 1 +x:1 +专业课 1 +x:1 +脸膛 1 +x:1 +斤斤计较 1 +x:1 +妙方 1 +x:1 +沉吟不决 1 +x:1 +诬称 1 +x:1 +狡赖 1 +x:1 +紧箍咒 1 +x:1 +闻名于世 1 +x:1 +小处着手 1 +x:1 +受难者 1 +x:1 +短篇 1 +x:1 +元配 1 +x:1 +莲菜 1 +x:1 +年初二 1 +x:1 +海红果 1 +x:1 +草委 1 +x:1 +卧铺 1 +x:1 +票管员 1 +x:1 +非诉 1 +x:1 +蒸汽机 1 +x:1 +车臣 1 +x:1 +生物课 1 +x:1 +传经授道 1 +x:1 +口语体 1 +x:1 +罗家组 1 +x:1 +邹庄村 1 +x:1 +特里尔 1 +x:1 +蟋蟀 1 +x:1 +右衽 1 +x:1 +翦 10 +x:10 +金融法 1 +x:1 +巴拉圭队 1 +x:1 +贵阳 1 +x:1 +过不去 1 +x:1 +晚会风 1 +x:1 +城府 1 +x:1 +雕版 1 +x:1 +蒲团 1 +x:1 +难言之隐 1 +x:1 +尊老爱幼 1 +x:1 +常用 1 +x:1 +镇国寺 1 +x:1 +黑方 1 +x:1 +兴中会 1 +x:1 +货场 1 +x:1 +发报量 1 +x:1 +脊椎 1 +x:1 +纪念柱 1 +x:1 +附聚 1 +x:1 +人口论 1 +x:1 +医家 1 +x:1 +黑斑 1 +x:1 +米尺 1 +x:1 +天桥区 1 +x:1 +亚麻油 1 +x:1 +食具 1 +x:1 +教学班 1 +x:1 +误认 1 +x:1 +铜版画 1 +x:1 +草头 1 +x:1 +双姓 1 +x:1 +唤取 1 +x:1 +南禅寺 1 +x:1 +遗闻 1 +x:1 +代外长 1 +x:1 +误诊 1 +x:1 +返家 1 +x:1 +误识 1 +x:1 +左嗓子 1 +x:1 +寒区 1 +x:1 +心理线 1 +x:1 +洋碱 1 +x:1 +龙泉窑 1 +x:1 +晤对 1 +x:1 +话家常 1 +x:1 +自若 1 +x:1 +运动 1 +x:1 +民办小学 1 +x:1 +后备军 1 +x:1 +半月形 1 +x:1 +人口证 1 +x:1 +英雄传 1 +x:1 +惘然若失 1 +x:1 +运力 1 +x:1 +城市 1 +x:1 +动气 1 +x:1 +宽者 1 +x:1 +愤而辞职 1 +x:1 +纪念林 1 +x:1 +前功尽弃 1 +x:1 +舅爷 1 +x:1 +劳不矜功 1 +x:1 +附耳 1 +x:1 +功率因数 1 +x:1 +雅曲 1 +x:1 +理论课 1 +x:1 +尺中 1 +x:1 +超 218 +x:218 +马革裹尸 1 +x:1 +反科学 1 +x:1 +清洁日 1 +x:1 +数九 1 +x:1 +惴惴不安 1 +x:1 +示范旗 1 +x:1 +图格里克 1 +x:1 +彝族 1 +x:1 +音缀 1 +x:1 +麦粒肿 1 +x:1 +罢论 1 +x:1 +洛阳镇 1 +x:1 +守势 1 +x:1 +丘鹬 1 +x:1 +纺丝 1 +x:1 +锁门 1 +x:1 +分化腺癌 1 +x:1 +篮协 1 +x:1 +锁闭 1 +x:1 +场办 1 +x:1 +递减率 1 +x:1 +毒情 1 +x:1 +基础科学 1 +x:1 +空谈者 1 +x:1 +脊檩 1 +x:1 +旗鼓相当 1 +x:1 +仿真度 1 +x:1 +黑晶 1 +x:1 +尾数 1 +x:1 +投机商 1 +x:1 +非机动 1 +x:1 +义旗 1 +x:1 +娘娘 1 +x:1 +两区 1 +x:1 +心脑病 1 +x:1 +梭落坪村 1 +x:1 +罢课 1 +x:1 +梅雷茨党 1 +x:1 +竭诚 1 +x:1 +丧志 1 +x:1 +字符 1 +x:1 +毛阳镇 1 +x:1 +僧 2 +x:2 +小姑子 1 +x:1 +韩 832 +x:832 +樽 1 +x:1 +宓 34 +x:34 +讼 1 +x:1 +书皮 1 +x:1 +发号机 1 +x:1 +货品 1 +x:1 +圭亚那 1 +x:1 +外围赛 1 +x:1 +示范方 1 +x:1 +言无不尽 1 +x:1 +三峡游 1 +x:1 +遗集 1 +x:1 +守则 1 +x:1 +杨振宁 1 +x:1 +遥遥 1 +x:1 +车船 1 +x:1 +弄相村 1 +x:1 +磨破嘴 1 +x:1 +尾断 1 +x:1 +分理 1 +x:1 +闻名中外 1 +x:1 +演出 1 +x:1 +迷人 1 +x:1 +证实 1 +x:1 +黑暗 1 +x:1 +中间轴 1 +x:1 +大轰大嗡 1 +x:1 +寒假 1 +x:1 +沈泉庄 1 +x:1 +之下 1 +x:1 +数以 1 +x:1 +纸 145 +x:145 +青城 1 +x:1 +放心店 1 +x:1 +义教 1 +x:1 +太阳灯 1 +x:1 +西葫芦 1 +x:1 +杉 4 +x:4 +世界 1 +x:1 +默默无闻 1 +x:1 +哈巴狗 1 +x:1 +组委会 1 +x:1 +肥美 1 +x:1 +非行 1 +x:1 +百里洲 1 +x:1 +洛克比 1 +x:1 +山水园 1 +x:1 +吃亏上当 1 +x:1 +葫芦藓 1 +x:1 +弹簧锁 1 +x:1 +王家堡 1 +x:1 +投诉案 1 +x:1 +超稳定 1 +x:1 +盲肠炎 1 +x:1 +思乡 1 +x:1 +大佛殿 1 +x:1 +欺下瞒上 1 +x:1 +教学点 1 +x:1 +二胡曲 1 +x:1 +朴实 1 +x:1 +浓缩稿 1 +x:1 +挖泥船 1 +x:1 +输电线 1 +x:1 +月琴 1 +x:1 +黑木 1 +x:1 +娘子 1 +x:1 +被服 1 +x:1 +一边 1 +x:1 +数位 1 +x:1 +色韵 1 +x:1 +涤棉 1 +x:1 +寒凝 1 +x:1 +圣庙 1 +x:1 +小姑娘 1 +x:1 +特困乡 1 +x:1 +云湾村 1 +x:1 +双子 1 +x:1 +苏联队 1 +x:1 +过眼烟云 1 +x:1 +书场 1 +x:1 +恩仇 1 +x:1 +锁链 1 +x:1 +恩人 1 +x:1 +弹簧钢 1 +x:1 +迷你 1 +x:1 +首选 1 +x:1 +黑板 1 +x:1 +黑松 1 +x:1 +左下方 1 +x:1 +学习类 1 +x:1 +衣帽 1 +x:1 +两制 1 +x:1 +上下级 1 +x:1 +六不六净 1 +x:1 +草寇 1 +x:1 +甜甜的 1 +x:1 +皇姑屯 1 +x:1 +钻戒 1 +x:1 +锁钥 1 +x:1 +地方话 1 +x:1 +迷住 1 +x:1 +此片 1 +x:1 +数传 1 +x:1 +前科 1 +x:1 +蟾蜍 1 +x:1 +名额 1 +x:1 +禽鸟 1 +x:1 +驻防 1 +x:1 +圆心 1 +x:1 +健全 1 +x:1 +纪念日 1 +x:1 +干涉现象 1 +x:1 +举起 1 +x:1 +等压线 1 +x:1 +自育 1 +x:1 +验电器 1 +x:1 +黑枣 1 +x:1 +炒 115 +x:115 +核电厂 1 +x:1 +米市 1 +x:1 +黑枪 1 +x:1 +膜 30 +x:30 +铅版 1 +x:1 +雨脚 1 +x:1 +焦虑 1 +x:1 +青狮潭 1 +x:1 +边缘 1 +x:1 +喉音 1 +x:1 +千岁爷 1 +x:1 +恩义 1 +x:1 +调入量 1 +x:1 +遗韵 1 +x:1 +原生地 1 +x:1 +路南区 1 +x:1 +习题 1 +x:1 +收容港 1 +x:1 +迷信 1 +x:1 +汉赋 1 +x:1 +肠穿孔 1 +x:1 +自立 1 +x:1 +炊事班长 1 +x:1 +草字 1 +x:1 +黎 269 +x:269 +民族学 1 +x:1 +健儿 1 +x:1 +空格符 1 +x:1 +盐化工业 1 +x:1 +分界 1 +x:1 +深明大义 1 +x:1 +团工委 1 +x:1 +响应者 1 +x:1 +新闻公报 1 +x:1 +反复无常 1 +x:1 +滑稽相 1 +x:1 +普安乡 1 +x:1 +数字机 1 +x:1 +守卫 1 +x:1 +塔兰托市 1 +x:1 +南甸镇 1 +x:1 +小袋装 1 +x:1 +朴学 1 +x:1 +小说史 1 +x:1 +娘家 1 +x:1 +庄严 1 +x:1 +效验 1 +x:1 +雪耻 1 +x:1 +医疗点 1 +x:1 +二把刀 1 +x:1 +诗友 1 +x:1 +春饼 1 +x:1 +瓜霸 1 +x:1 +前线 1 +x:1 +食品 1 +x:1 +诗句 1 +x:1 +双层 1 +x:1 +芸芸 1 +x:1 +绿化 1 +x:1 +洋荤 1 +x:1 +黑白片 1 +x:1 +此生 1 +x:1 +鲸吞 1 +x:1 +诗史 1 +x:1 +大智大趣 1 +x:1 +短线 1 +x:1 +三有三超 1 +x:1 +王家庄 1 +x:1 +走马上任 1 +x:1 +人保 1 +x:1 +车箱厂 1 +x:1 +外敷 1 +x:1 +光卤石 1 +x:1 +逍遥自得 1 +x:1 +哀戚 1 +x:1 +绿卡 1 +x:1 +陇穷 1 +x:1 +雾渡河 1 +x:1 +雨蛙 1 +x:1 +隧道 1 +x:1 +随心所欲 1 +x:1 +驱动力 1 +x:1 +双尊 1 +x:1 +作业组 1 +x:1 +世界大战 1 +x:1 +团小组 1 +x:1 +拈轻怕重 1 +x:1 +丧失 1 +x:1 +辽西 1 +x:1 +字字珠玑 1 +x:1 +匙尾子 1 +x:1 +神韵 1 +x:1 +寒噤 1 +x:1 +蒲包 1 +x:1 +西坑村 1 +x:1 +痴呆 1 +x:1 +得胜村 1 +x:1 +葛洪岩 1 +x:1 +用人之长 1 +x:1 +说穿 1 +x:1 +棵儿 1 +x:1 +东风村 1 +x:1 +梨子 1 +x:1 +南庄镇 1 +x:1 +撰 5 +x:5 +抑强扶弱 1 +x:1 +卯眼 1 +x:1 +荷负 1 +x:1 +灯火辉煌 1 +x:1 +越谷市 1 +x:1 +担架 1 +x:1 +运城 1 +x:1 +诊断室 1 +x:1 +邻里 1 +x:1 +流 249 +x:249 +货币资本 1 +x:1 +显出 1 +x:1 +迂 29 +x:29 +奢靡 1 +x:1 +草屑 1 +x:1 +绿叶 1 +x:1 +双岭 1 +x:1 +高压锅 1 +x:1 +诗化 1 +x:1 +水银灯 1 +x:1 +青冢 1 +x:1 +分片 1 +x:1 +分电器 1 +x:1 +公报私仇 1 +x:1 +五月份 1 +x:1 +关键球 1 +x:1 +推注法 1 +x:1 +沉箱 1 +x:1 +后河乡 1 +x:1 +大脖子病 1 +x:1 +苦痛 1 +x:1 +米奶 1 +x:1 +利差 1 +x:1 +双台子 1 +x:1 +公路站 1 +x:1 +整天价 1 +x:1 +右路 1 +x:1 +狂人 1 +x:1 +放风 1 +x:1 +闻喜县 1 +x:1 +函告 1 +x:1 +被骗者 1 +x:1 +法学所 1 +x:1 +影业 1 +x:1 +钓迷 1 +x:1 +大滚刀 1 +x:1 +日臻完善 1 +x:1 +斋期 1 +x:1 +花里胡哨 1 +x:1 +色釉 1 +x:1 +达产 1 +x:1 +医学家 1 +x:1 +罗赖马州 1 +x:1 +双找工 1 +x:1 +致富路 1 +x:1 +可观者 1 +x:1 +讨价还价 1 +x:1 +挽幛 1 +x:1 +密植 1 +x:1 +深谙 1 +x:1 +宿豫县 1 +x:1 +常熟 1 +x:1 +班车站 1 +x:1 +动检 1 +x:1 +千年虫 1 +x:1 +诗朗诵 1 +x:1 +国歌声 1 +x:1 +流量计 1 +x:1 +美人痣 1 +x:1 +镐 9 +x:9 +大惊失色 1 +x:1 +挽带 1 +x:1 +献血者 1 +x:1 +毒枭 1 +x:1 +总得 1 +x:1 +有色金属 1 +x:1 +南安市 1 +x:1 +塘沽区 1 +x:1 +闭闭 1 +x:1 +劣等生 1 +x:1 +沉稳 1 +x:1 +自虐 1 +x:1 +咨询员 1 +x:1 +市直 1 +x:1 +洪福 1 +x:1 +回报率 1 +x:1 +某师 1 +x:1 +义战 1 +x:1 +闭锁 1 +x:1 +色酒 1 +x:1 +梳棉机 1 +x:1 +纵横谈 1 +x:1 +生气勃勃 1 +x:1 +向 8369 +x:8369 +鸡鸣狗盗 1 +x:1 +琅琅上口 1 +x:1 +沿南乡 1 +x:1 +荒蛮 1 +x:1 +诗剧 1 +x:1 +把势 1 +x:1 +前缀 1 +x:1 +三清殿 1 +x:1 +仙山琼阁 1 +x:1 +建议价 1 +x:1 +梁平柚 1 +x:1 +边荒 1 +x:1 +赃官 1 +x:1 +前缘 1 +x:1 +短缺 1 +x:1 +导师制 1 +x:1 +健在 1 +x:1 +非站牌 1 +x:1 +民主人士 1 +x:1 +前置 1 +x:1 +顽抗 1 +x:1 +宣传员 1 +x:1 +说笑 1 +x:1 +众鸟蔽日 1 +x:1 +短网 1 +x:1 +邻邦 1 +x:1 +距离感 1 +x:1 +货单 1 +x:1 +藏污纳垢 1 +x:1 +洋粉 1 +x:1 +附营 1 +x:1 +体彩 1 +x:1 +体力型 1 +x:1 +比比看 1 +x:1 +满腹经纶 1 +x:1 +示范户 1 +x:1 +直传球 1 +x:1 +药到病除 1 +x:1 +猫鼠同眠 1 +x:1 +死伤者 1 +x:1 +市百 1 +x:1 +打针 1 +x:1 +黑户 1 +x:1 +旅行袋 1 +x:1 +开怀 1 +x:1 +短粗 1 +x:1 +芝罘区 1 +x:1 +重压 1 +x:1 +败兴 1 +x:1 +优秀率 1 +x:1 +决非 1 +x:1 +踱 3 +x:3 +青南 1 +x:1 +征地款 1 +x:1 +绘画史 1 +x:1 +是日 1 +x:1 +俯仰由人 1 +x:1 +怀中 1 +x:1 +水泥墙 1 +x:1 +噪音 1 +x:1 +政务 1 +x:1 +是时 1 +x:1 +喽 4 +x:4 +音符 1 +x:1 +白雪皑皑 1 +x:1 +西方人 1 +x:1 +双带 1 +x:1 +纪念性 1 +x:1 +政办 1 +x:1 +急急忙忙 1 +x:1 +外来人 1 +x:1 +哀怒 1 +x:1 +汽车 1 +x:1 +用人观 1 +x:1 +峡谷 1 +x:1 +诙 1 +x:1 +汽轮 1 +x:1 +初涉者 1 +x:1 +两地 1 +x:1 +绘画厅 1 +x:1 +俑坑 1 +x:1 +轻手轻脚 1 +x:1 +米寿 1 +x:1 +绿党 1 +x:1 +晃荡酒 1 +x:1 +哀怨 1 +x:1 +近郊区 1 +x:1 +把关 1 +x:1 +塬谷 1 +x:1 +烧结厂 1 +x:1 +化肥厂 1 +x:1 +莲蓬 1 +x:1 +下元皂村 1 +x:1 +黑手 1 +x:1 +釉面 1 +x:1 +哭闹 1 +x:1 +草帘 1 +x:1 +青史 1 +x:1 +抢修 1 +x:1 +货值 1 +x:1 +爱国者 1 +x:1 +雪花 1 +x:1 +田头乡 1 +x:1 +流量表 1 +x:1 +贵重 1 +x:1 +两基 1 +x:1 +篱笆 1 +x:1 +动武 1 +x:1 +上证所 1 +x:1 +武昌鱼 1 +x:1 +右边 1 +x:1 +音像业 1 +x:1 +草帽 1 +x:1 +匾额 1 +x:1 +雷鸣谷 1 +x:1 +音箱 1 +x:1 +十六日 1 +x:1 +幼蝎 1 +x:1 +市电 1 +x:1 +诗兴 1 +x:1 +草席 1 +x:1 +沉积 1 +x:1 +梓行 1 +x:1 +如痴如狂 1 +x:1 +曲径通幽 1 +x:1 +体形 1 +x:1 +双座 1 +x:1 +难以名状 1 +x:1 +科威特城 1 +x:1 +讲课声 1 +x:1 +荷载 1 +x:1 +排犹主义 1 +x:1 +城头 1 +x:1 +观音土 1 +x:1 +摩通社 1 +x:1 +棉铃虫 1 +x:1 +汽运 1 +x:1 +借口 1 +x:1 +梅农盖 1 +x:1 +腊月二十 1 +x:1 +扳 33 +x:33 +原料类 1 +x:1 +诗儿 1 +x:1 +伪者 1 +x:1 +一连 1 +x:1 +哀悼 1 +x:1 +执法车 1 +x:1 +差转台 1 +x:1 +强卖强买 1 +x:1 +训练伤 1 +x:1 +手中 1 +x:1 +运命 1 +x:1 +音程 1 +x:1 +毒日 1 +x:1 +平地而起 1 +x:1 +诈降 1 +x:1 +倚官仗势 1 +x:1 +捐资者 1 +x:1 +得心应手 1 +x:1 +雕琢 1 +x:1 +年假 1 +x:1 +手下 1 +x:1 +手上 1 +x:1 +雅性 1 +x:1 +幽默者 1 +x:1 +膝关节 1 +x:1 +友谊史 1 +x:1 +纵然 1 +x:1 +死苗率 1 +x:1 +大佛湾 1 +x:1 +雪茄 1 +x:1 +氯化物 1 +x:1 +城壕 1 +x:1 +莲藕 1 +x:1 +哀愁 1 +x:1 +启事 1 +x:1 +手书 1 +x:1 +无以替代 1 +x:1 +借阅率 1 +x:1 +守城 1 +x:1 +密封面 1 +x:1 +创造欲 1 +x:1 +怜爱 1 +x:1 +诸多不便 1 +x:1 +大事录 1 +x:1 +釉陶 1 +x:1 +城墙 1 +x:1 +鸡冠石 1 +x:1 +超文本 1 +x:1 +广元市 1 +x:1 +高速 1 +x:1 +糟损 1 +x:1 +震天动地 1 +x:1 +沂 6 +x:6 +耒阳 1 +x:1 +范公堤 1 +x:1 +锈钉 1 +x:1 +年产值 1 +x:1 +玻璃纸 1 +x:1 +野枸杞头 1 +x:1 +坐探 1 +x:1 +两国 1 +x:1 +轮滑鞋 1 +x:1 +猥亵 1 +x:1 +望 295 +x:295 +返工 1 +x:1 +总体组 1 +x:1 +接处警 1 +x:1 +显功 1 +x:1 +狡诈 1 +x:1 +缨帽 1 +x:1 +救援船 1 +x:1 +右身 1 +x:1 +墨西哥 1 +x:1 +装饰布 1 +x:1 +滑雪板 1 +x:1 +民族式 1 +x:1 +断顿 1 +x:1 +夏津 1 +x:1 +浙江省 1 +x:1 +狡计 1 +x:1 +被提名人 1 +x:1 +铁腕人物 1 +x:1 +抠 14 +x:14 +苦相 1 +x:1 +城堡 1 +x:1 +控制阀 1 +x:1 +籍 37 +x:37 +救援艇 1 +x:1 +荤腥 1 +x:1 +启东 1 +x:1 +江淮戏 1 +x:1 +悬浊液 1 +x:1 +绒山羊 1 +x:1 +雪菜 1 +x:1 +首钢 1 +x:1 +示范性 1 +x:1 +戳儿 1 +x:1 +烙画家 1 +x:1 +各部 1 +x:1 +纸捻 1 +x:1 +意想不到 1 +x:1 +科威特国 1 +x:1 +二氧化氯 1 +x:1 +元音 1 +x:1 +不得人心 1 +x:1 +饮茶 1 +x:1 +字纸 1 +x:1 +舅母 1 +x:1 +达县 1 +x:1 +心境 1 +x:1 +糟糕 1 +x:1 +待业 1 +x:1 +逆耳忠言 1 +x:1 +挎包 1 +x:1 +敬祖 1 +x:1 +埃拉特湾 1 +x:1 +渡头 1 +x:1 +嬉皮笑脸 1 +x:1 +轻工部 1 +x:1 +敬祝 1 +x:1 +售票点 1 +x:1 +英雄团 1 +x:1 +假象牙 1 +x:1 +抢先 1 +x:1 +抢光 1 +x:1 +沉积层 1 +x:1 +担笼 1 +x:1 +似的 1 +x:1 +严办 1 +x:1 +塞弗勒 1 +x:1 +名菜 1 +x:1 +糟糠 1 +x:1 +货价 1 +x:1 +艺术馆 1 +x:1 +黑米 1 +x:1 +附 1689 +x:1689 +仆仆风尘 1 +x:1 +哭诉 1 +x:1 +百花园 1 +x:1 +新中行 1 +x:1 +此楼 1 +x:1 +音效 1 +x:1 +治奢兴俭 1 +x:1 +消费群 1 +x:1 +检验费 1 +x:1 +影印 1 +x:1 +扎染 1 +x:1 +浴缸 1 +x:1 +汽酒 1 +x:1 +苦楚 1 +x:1 +理学院 1 +x:1 +德宏傣乡 1 +x:1 +汽配 1 +x:1 +敬礼 1 +x:1 +上下文 1 +x:1 +墓主人 1 +x:1 +导尿管 1 +x:1 +首评 1 +x:1 +尾羽 1 +x:1 +快棋赛 1 +x:1 +物是人非 1 +x:1 +名药 1 +x:1 +如前所述 1 +x:1 +货主 1 +x:1 +灯市口 1 +x:1 +被占领区 1 +x:1 +侈谈 1 +x:1 +优惠券 1 +x:1 +尖塔 1 +x:1 +司长 1 +x:1 +温吞水 1 +x:1 +掩映 1 +x:1 +诗作 1 +x:1 +税务所 1 +x:1 +麦茬儿 1 +x:1 +不管不顾 1 +x:1 +厘米/秒 1 +x:1 +超二级 1 +x:1 +吞并 1 +x:1 +手册 1 +x:1 +缔约国 1 +x:1 +思谋 1 +x:1 +敬称 1 +x:1 +政制 1 +x:1 +赚头 1 +x:1 +伊春 1 +x:1 +二里庄 1 +x:1 +动画 1 +x:1 +摄影家 1 +x:1 +尾翼 1 +x:1 +车顶 1 +x:1 +想象性 1 +x:1 +火地岛 1 +x:1 +说明 1 +x:1 +动用 1 +x:1 +名茶 1 +x:1 +较真 1 +x:1 +短打 1 +x:1 +色调 1 +x:1 +穷年累月 1 +x:1 +罗安达 1 +x:1 +文献学 1 +x:1 +书记员 1 +x:1 +董 715 +x:715 +纪实片 1 +x:1 +嗷嗷待哺 1 +x:1 +卡塔尔国 1 +x:1 +扣率 1 +x:1 +独出心裁 1 +x:1 +反刍动物 1 +x:1 +说是 1 +x:1 +金融界 1 +x:1 +尾翎 1 +x:1 +党政军群 1 +x:1 +黎民百姓 1 +x:1 +首访 1 +x:1 +寡妇 1 +x:1 +采矿点 1 +x:1 +宇 70 +x:70 +英雄城 1 +x:1 +处方单 1 +x:1 +帝王将相 1 +x:1 +冯湾村 1 +x:1 +中长线 1 +x:1 +演 173 +x:173 +休闲椅 1 +x:1 +把下 1 +x:1 +运钞车 1 +x:1 +此说 1 +x:1 +诗仙 1 +x:1 +横眉竖眼 1 +x:1 +落套 1 +x:1 +候诊室 1 +x:1 +投诉率 1 +x:1 +恍如 1 +x:1 +窟 2 +x:2 +平易 1 +x:1 +掉转 1 +x:1 +前排 1 +x:1 +阿达纳 1 +x:1 +应约 1 +x:1 +习舞 1 +x:1 +总体性 1 +x:1 +彰化 1 +x:1 +挂钩梯 1 +x:1 +滩地 1 +x:1 +高阳县 1 +x:1 +核试验区 1 +x:1 +倨傲不恭 1 +x:1 +宝安区 1 +x:1 +名花 1 +x:1 +升跌宝 1 +x:1 +习艺 1 +x:1 +毒箭 1 +x:1 +辣酱 1 +x:1 +平昔 1 +x:1 +杨浦 1 +x:1 +引伸义 1 +x:1 +建国会 1 +x:1 +精细化 1 +x:1 +棉梭织 1 +x:1 +上纲上线 1 +x:1 +鞋粉 1 +x:1 +强制性 1 +x:1 +新闻史 1 +x:1 +氯化氢 1 +x:1 +救国会 1 +x:1 +前提 1 +x:1 +影剧 1 +x:1 +诗人 1 +x:1 +人地生疏 1 +x:1 +皮猴儿 1 +x:1 +氯化法 1 +x:1 +论资排辈 1 +x:1 +衡器 1 +x:1 +平昌 1 +x:1 +高潮线 1 +x:1 +减员增效 1 +x:1 +桧仓郡 1 +x:1 +煤油灯 1 +x:1 +智利硝石 1 +x:1 +鞋类 1 +x:1 +此证 1 +x:1 +来复线 1 +x:1 +撼动 1 +x:1 +中点值 1 +x:1 +好说歹说 1 +x:1 +诗书 1 +x:1 +前指 1 +x:1 +穷鬼 1 +x:1 +叶绿体 1 +x:1 +蒸吨 1 +x:1 +罢选 1 +x:1 +此话 1 +x:1 +杆秤 1 +x:1 +开普顿 1 +x:1 +奉献 1 +x:1 +说来 1 +x:1 +心头 1 +x:1 +组织股 1 +x:1 +私车 1 +x:1 +调停人 1 +x:1 +药业界 1 +x:1 +萨安州 1 +x:1 +逐客令 1 +x:1 +说服 1 +x:1 +小矫情 1 +x:1 +见报稿 1 +x:1 +此诗 1 +x:1 +重要 1 +x:1 +庾家河乡 1 +x:1 +茶余酒后 1 +x:1 +吴家包村 1 +x:1 +摇摆 1 +x:1 +出难题 1 +x:1 +斗士 1 +x:1 +起源于 1 +x:1 +逊色 1 +x:1 +书目 1 +x:1 +为数很少 1 +x:1 +果匣子 1 +x:1 +货位 1 +x:1 +放射病 1 +x:1 +脏躁症 1 +x:1 +工作队 1 +x:1 +抢占 1 +x:1 +名臣 1 +x:1 +车箱 1 +x:1 +艰巨性 1 +x:1 +园艺区 1 +x:1 +此次 1 +x:1 +巴塞尔 1 +x:1 +专案组 1 +x:1 +中止点 1 +x:1 +投诉点 1 +x:1 +南岚镇 1 +x:1 +没事找事 1 +x:1 +启发 1 +x:1 +夜不成寐 1 +x:1 +对酒当歌 1 +x:1 +公用事业 1 +x:1 +摄影奖 1 +x:1 +雪鸟 1 +x:1 +卯榫 1 +x:1 +手包 1 +x:1 +字据 1 +x:1 +祝寿 1 +x:1 +分治 1 +x:1 +启口 1 +x:1 +恶运 1 +x:1 +大志 1 +x:1 +相映成趣 1 +x:1 +小虎队 1 +x:1 +子项目 1 +x:1 +酒石酸 1 +x:1 +分包人 1 +x:1 +天真无邪 1 +x:1 +电潜泵 1 +x:1 +督查队 1 +x:1 +职 205 +x:205 +瓢虫 1 +x:1 +手印 1 +x:1 +手卷 1 +x:1 +抗风力 1 +x:1 +小衣裳 1 +x:1 +分泌 1 +x:1 +利在千秋 1 +x:1 +动荡 1 +x:1 +吱呀 1 +x:1 +颐养天年 1 +x:1 +放虑 1 +x:1 +贵贱 1 +x:1 +纸制品 1 +x:1 +碳酸盐 1 +x:1 +宜宾 1 +x:1 +炸弹 1 +x:1 +助理 1 +x:1 +黑纱 1 +x:1 +弯矩 1 +x:1 +资源库 1 +x:1 +大版纸 1 +x:1 +连拱式 1 +x:1 +黑线 1 +x:1 +黑红 1 +x:1 +警戒具 1 +x:1 +规约性 1 +x:1 +斜心墙 1 +x:1 +邻近 1 +x:1 +斗室 1 +x:1 +激流汹涌 1 +x:1 +世情书 1 +x:1 +自首 1 +x:1 +淬火 1 +x:1 +胆大妄为 1 +x:1 +兆瓦 1 +x:1 +诈语 1 +x:1 +棉针织 1 +x:1 +首要 1 +x:1 +一方平安 1 +x:1 +黑绸 1 +x:1 +国交昌运 1 +x:1 +派会 1 +x:1 +车驾 1 +x:1 +警示录 1 +x:1 +定安里 1 +x:1 +车马 1 +x:1 +镌刻 1 +x:1 +奇文共赏 1 +x:1 +各路 1 +x:1 +泔水缸 1 +x:1 +缩回 1 +x:1 +佩 10 +x:10 +隔离带 1 +x:1 +演化 1 +x:1 +资格 1 +x:1 +毒砂 1 +x:1 +市楼 1 +x:1 +烟草商 1 +x:1 +布热津卡 1 +x:1 +心安 1 +x:1 +一片生机 1 +x:1 +名师傅 1 +x:1 +怀化 1 +x:1 +天下为公 1 +x:1 +后影 1 +x:1 +夜 313 +x:313 +夕阳西下 1 +x:1 +抡 17 +x:17 +焦黑 1 +x:1 +落子 1 +x:1 +玉米棒子 1 +x:1 +广采博收 1 +x:1 +回扣率 1 +x:1 +雕栏 1 +x:1 +失误者 1 +x:1 +焦黄 1 +x:1 +谐振 1 +x:1 +还原焰 1 +x:1 +教学楼 1 +x:1 +名胜 1 +x:1 +见机行事 1 +x:1 +意大利队 1 +x:1 +支吾其词 1 +x:1 +有感于 1 +x:1 +保留剧目 1 +x:1 +复苏术 1 +x:1 +王集乡 1 +x:1 +水暖组 1 +x:1 +战情 1 +x:1 +洋房 1 +x:1 +巴约纳 1 +x:1 +之际 1 +x:1 +启动 1 +x:1 +三连败 1 +x:1 +辨析 1 +x:1 +盘式机 1 +x:1 +卷心菜 1 +x:1 +说新 1 +x:1 +草库伦 1 +x:1 +处长 1 +x:1 +娃儿 1 +x:1 +肱骨 1 +x:1 +编译馆 1 +x:1 +缘起 1 +x:1 +奔腾 1 +x:1 +物本观 1 +x:1 +长生塔 1 +x:1 +说教 1 +x:1 +手动 1 +x:1 +敬立 1 +x:1 +禽类 1 +x:1 +蚩 1 +x:1 +尖子 1 +x:1 +风靡一时 1 +x:1 +炼钢 1 +x:1 +下半旗 1 +x:1 +赣西南 1 +x:1 +荒岛 1 +x:1 +手势 1 +x:1 +工农贸 1 +x:1 +加减法 1 +x:1 +敖东队 1 +x:1 +落寞 1 +x:1 +合格品 1 +x:1 +牛头马面 1 +x:1 +法学系 1 +x:1 +下半时 1 +x:1 +剪毛棚 1 +x:1 +粗毛皮 1 +x:1 +手力 1 +x:1 +拦蓄 1 +x:1 +分洪 1 +x:1 +遗迹 1 +x:1 +你争我夺 1 +x:1 +豁口 1 +x:1 +辽阳 1 +x:1 +布面鞋 1 +x:1 +烟草味 1 +x:1 +十九日 1 +x:1 +有权者 1 +x:1 +抢劫 1 +x:1 +分流 1 +x:1 +伊敏 1 +x:1 +时不我待 1 +x:1 +抒己见 1 +x:1 +心子 1 +x:1 +深宅 1 +x:1 +日喀则市 1 +x:1 +辽阔 1 +x:1 +法王洞 1 +x:1 +青云 1 +x:1 +对撞机 1 +x:1 +肇庆 1 +x:1 +落实 1 +x:1 +出台 1 +x:1 +炼铁 1 +x:1 +州界 1 +x:1 +臭腺 1 +x:1 +准谱儿 1 +x:1 +美人河 1 +x:1 +短暂 1 +x:1 +巷中 1 +x:1 +购销额 1 +x:1 +融 105 +x:105 +右锋 1 +x:1 +汽锤 1 +x:1 +拉玛古猿 1 +x:1 +租用者 1 +x:1 +氖灯 1 +x:1 +掩护 1 +x:1 +皖江 1 +x:1 +搭桥 1 +x:1 +霸王 1 +x:1 +下诹访市 1 +x:1 +护卫队长 1 +x:1 +非难 1 +x:1 +绿水长流 1 +x:1 +杨树 1 +x:1 +大中华区 1 +x:1 +运作 1 +x:1 +尖峰 1 +x:1 +怒发冲冠 1 +x:1 +夺眶而出 1 +x:1 +过五关 1 +x:1 +宵 2 +x:2 +字数 1 +x:1 +洋教 1 +x:1 +雕漆 1 +x:1 +恩准 1 +x:1 +弓形体 1 +x:1 +起诉者 1 +x:1 +坂 1 +x:1 +苦海 1 +x:1 +影坛 1 +x:1 +母亲河 1 +x:1 +学会市场 1 +x:1 +姜黄 1 +x:1 +农业工人 1 +x:1 +瓦房村 1 +x:1 +扣眼 1 +x:1 +照常 1 +x:1 +高脚杯 1 +x:1 +资源 1 +x:1 +问寒问暖 1 +x:1 +西单站 1 +x:1 +高不可攀 1 +x:1 +育儿袋 1 +x:1 +久盛不衰 1 +x:1 +蛤蟆 1 +x:1 +流星赶月 1 +x:1 +区间车 1 +x:1 +中长篇 1 +x:1 +依率 1 +x:1 +数值 1 +x:1 +气贯长虹 1 +x:1 +扁桃体炎 1 +x:1 +矫捷 1 +x:1 +布伦特 1 +x:1 +珊瑚岛 1 +x:1 +恩典 1 +x:1 +纪念章 1 +x:1 +壶口 1 +x:1 +雕塑界 1 +x:1 +痱子 1 +x:1 +满怀深情 1 +x:1 +积以时日 1 +x:1 +徇私枉法 1 +x:1 +脑垂体 1 +x:1 +洪恩 1 +x:1 +来说 1 +x:1 +虚套子 1 +x:1 +眷顾 1 +x:1 +湘妃竹 1 +x:1 +心尖 1 +x:1 +搭棚 1 +x:1 +惊险片 1 +x:1 +溜之大吉 1 +x:1 +含油量 1 +x:1 +嫌疑人 1 +x:1 +坍方 1 +x:1 +崩龙族 1 +x:1 +成不了 1 +x:1 +贴息贷款 1 +x:1 +地花鼓 1 +x:1 +被占领土 1 +x:1 +轻喜剧 1 +x:1 +衡南 1 +x:1 +保障 1 +x:1 +他方 1 +x:1 +流连忘返 1 +x:1 +放肆 1 +x:1 +杨梅 1 +x:1 +二元杂交 1 +x:1 +防总 1 +x:1 +前景 1 +x:1 +斯坦福 1 +x:1 +太空局 1 +x:1 +鉴于 1 +x:1 +圣诞老人 1 +x:1 +斗转星移 1 +x:1 +小聪明 1 +x:1 +默默无语 1 +x:1 +晃晃悠悠 1 +x:1 +影城 1 +x:1 +放权 1 +x:1 +舞台化 1 +x:1 +基因组 1 +x:1 +离瓣花冠 1 +x:1 +平山镇 1 +x:1 +放胆 1 +x:1 +丛葬 1 +x:1 +礼品 1 +x:1 +苦水 1 +x:1 +少数 1 +x:1 +蛤蚧 1 +x:1 +孵化 1 +x:1 +攻心战 1 +x:1 +支溪岙村 1 +x:1 +骑虎难下 1 +x:1 +四环路 1 +x:1 +原料林 1 +x:1 +楚剧团 1 +x:1 +色觉 1 +x:1 +勤俭星 1 +x:1 +塬面 1 +x:1 +分段 1 +x:1 +接踵而来 1 +x:1 +剥削阶级 1 +x:1 +历久不衰 1 +x:1 +短枪 1 +x:1 +遥远 1 +x:1 +默默无言 1 +x:1 +顾全大局 1 +x:1 +文理工 1 +x:1 +棺材 1 +x:1 +特征值 1 +x:1 +滩区 1 +x:1 +爆冷门 1 +x:1 +邬庙村 1 +x:1 +调剂室 1 +x:1 +旋 18 +x:18 +黑人区 1 +x:1 +技艺压群 1 +x:1 +赐 13 +x:13 +羞耻感 1 +x:1 +前柱 1 +x:1 +洗澡费 1 +x:1 +耐饥 1 +x:1 +创始 1 +x:1 +体统 1 +x:1 +丘脑 1 +x:1 +盖世无双 1 +x:1 +分母 1 +x:1 +掌权 1 +x:1 +圣马可 1 +x:1 +若 349 +x:349 +线条形 1 +x:1 +抢吃 1 +x:1 +孵卵 1 +x:1 +神交 1 +x:1 +印尼盾 1 +x:1 +发脾气 1 +x:1 +苦求 1 +x:1 +音息 1 +x:1 +三灾八难 1 +x:1 +小米辣 1 +x:1 +天理 1 +x:1 +摄影师 1 +x:1 +能进能出 1 +x:1 +蝗情 1 +x:1 +亲亲的 1 +x:1 +掉话 1 +x:1 +运价 1 +x:1 +神仙 1 +x:1 +洛宁县 1 +x:1 +就诊率 1 +x:1 +拉锯式 1 +x:1 +动火 1 +x:1 +木锹 1 +x:1 +警嫂 1 +x:1 +舞台剧 1 +x:1 +落差 1 +x:1 +前机 1 +x:1 +缩写 1 +x:1 +一哄而散 1 +x:1 +愣 25 +x:25 +彪炳千秋 1 +x:1 +岿然不动 1 +x:1 +扶贫帮困 1 +x:1 +恶行 1 +x:1 +瞬 1 +x:1 +包子 1 +x:1 +潮起潮落 1 +x:1 +前朝 1 +x:1 +看大门 1 +x:1 +前期 1 +x:1 +不可避免 1 +x:1 +步履维艰 1 +x:1 +健体 1 +x:1 +担纲 1 +x:1 +前来 1 +x:1 +交流馆 1 +x:1 +资源委 1 +x:1 +车桥厂 1 +x:1 +座无虚席 1 +x:1 +山摇地动 1 +x:1 +内骨骼 1 +x:1 +坐椅 1 +x:1 +平川市 1 +x:1 +订货量 1 +x:1 +润滑 1 +x:1 +火海刀山 1 +x:1 +绝对零度 1 +x:1 +丙烯酸 1 +x:1 +育雏 1 +x:1 +坐失良机 1 +x:1 +仿章 1 +x:1 +兔死狗烹 1 +x:1 +挑战者杯 1 +x:1 +郁积 1 +x:1 +僮 1 +x:1 +社会分工 1 +x:1 +前村 1 +x:1 +分步 1 +x:1 +缩减 1 +x:1 +附庸风雅 1 +x:1 +乌兹别克 1 +x:1 +黑种 1 +x:1 +服务网 1 +x:1 +巢鼠 1 +x:1 +断臂 1 +x:1 +紫药水 1 +x:1 +检波器 1 +x:1 +园艺场 1 +x:1 +三热爱 1 +x:1 +壶关 1 +x:1 +寿山石 1 +x:1 +联建 1 +x:1 +合格兵 1 +x:1 +说情 1 +x:1 +精雕细刻 1 +x:1 +软床 1 +x:1 +落幕 1 +x:1 +承受力 1 +x:1 +硬脂酸 1 +x:1 +质子 1 +x:1 +沛沛然 1 +x:1 +防疫员 1 +x:1 +邯 1 +x:1 +一荣俱荣 1 +x:1 +扣留 1 +x:1 +主题歌 1 +x:1 +苗岭 1 +x:1 +桑耶寺 1 +x:1 +创造物 1 +x:1 +来讲 1 +x:1 +恶计 1 +x:1 +谈笑 1 +x:1 +数列 1 +x:1 +遗言 1 +x:1 +钓钩 1 +x:1 +西子湖畔 1 +x:1 +哗 2 +x:2 +场租 1 +x:1 +菜料 1 +x:1 +鹅绒 1 +x:1 +二里塘 1 +x:1 +刚正不阿 1 +x:1 +氧化剂 1 +x:1 +小说书 1 +x:1 +祭灶 1 +x:1 +两会 1 +x:1 +一本正经 1 +x:1 +神圣感 1 +x:1 +右面 1 +x:1 +给水 1 +x:1 +守令 1 +x:1 +守业 1 +x:1 +选聘制 1 +x:1 +补偿费 1 +x:1 +北新街 1 +x:1 +角速度 1 +x:1 +收银台 1 +x:1 +镢头 1 +x:1 +慷然 1 +x:1 +判读 1 +x:1 +分标 1 +x:1 +郓城县 1 +x:1 +科学 1 +x:1 +少少许 1 +x:1 +政区 1 +x:1 +判词 1 +x:1 +奇 87 +x:87 +地方队 1 +x:1 +黑窝 1 +x:1 +龙门吊 1 +x:1 +杨楼乡 1 +x:1 +就诊点 1 +x:1 +葛藤 1 +x:1 +断腿 1 +x:1 +正面人物 1 +x:1 +礼花弹 1 +x:1 +零税率 1 +x:1 +宁缺毋滥 1 +x:1 +武隆县 1 +x:1 +汽化器 1 +x:1 +两侧 1 +x:1 +判认 1 +x:1 +赞美声 1 +x:1 +斗志 1 +x:1 +两便 1 +x:1 +落座 1 +x:1 +钱包 1 +x:1 +斯图加特 1 +x:1 +顽民 1 +x:1 +西昌市 1 +x:1 +心幕 1 +x:1 +工资额 1 +x:1 +中空化 1 +x:1 +奶糖饼 1 +x:1 +壶内 1 +x:1 +评委席 1 +x:1 +火树银花 1 +x:1 +软座 1 +x:1 +分档 1 +x:1 +晓畅 1 +x:1 +资水 1 +x:1 +削铁如泥 1 +x:1 +雅称 1 +x:1 +直升机场 1 +x:1 +心律 1 +x:1 +短文 1 +x:1 +伊武部 1 +x:1 +新房 1 +x:1 +担保函 1 +x:1 +二里头 1 +x:1 +麦季 1 +x:1 +轻佻 1 +x:1 +良策 1 +x:1 +创安 1 +x:1 +前方 1 +x:1 +损失 1 +x:1 +妙算 1 +x:1 +果酸 1 +x:1 +麦子 1 +x:1 +摄影展 1 +x:1 +前文 1 +x:1 +落归 1 +x:1 +移送 1 +x:1 +始终如一 1 +x:1 +中郎将 1 +x:1 +尾砂 1 +x:1 +永恒不变 1 +x:1 +各行 1 +x:1 +沉思 1 +x:1 +军机处 1 +x:1 +心心 1 +x:1 +缩印 1 +x:1 +灰化土 1 +x:1 +茶壶 1 +x:1 +队风 1 +x:1 +两为 1 +x:1 +放荡 1 +x:1 +心志 1 +x:1 +磁场 1 +x:1 +断肢 1 +x:1 +扣球 1 +x:1 +诱人 1 +x:1 +纪检委 1 +x:1 +创导 1 +x:1 +衡阳市 1 +x:1 +前旗 1 +x:1 +短时 1 +x:1 +葛营 1 +x:1 +二十九日 1 +x:1 +此湖 1 +x:1 +守信 1 +x:1 +利用率 1 +x:1 +遗证 1 +x:1 +姥姥 1 +x:1 +黑管 1 +x:1 +荷阵 1 +x:1 +动物 1 +x:1 +海防林带 1 +x:1 +市民 1 +x:1 +心怀叵测 1 +x:1 +违背 1 +x:1 +边饰 1 +x:1 +缛 1 +x:1 +妙笔 1 +x:1 +积贫积弱 1 +x:1 +氧气 1 +x:1 +家大业大 1 +x:1 +芥子气 1 +x:1 +内外勤 1 +x:1 +心弦 1 +x:1 +啥子 1 +x:1 +名著 1 +x:1 +短收 1 +x:1 +牙膏袋式 1 +x:1 +乘风扬帆 1 +x:1 +两院制 1 +x:1 +黑箍 1 +x:1 +纪检处 1 +x:1 +尾鳍 1 +x:1 +分配办 1 +x:1 +你追我赶 1 +x:1 +处里 1 +x:1 +矫情 1 +x:1 +好歹 1 +x:1 +常武 1 +x:1 +短效 1 +x:1 +所有权证 1 +x:1 +大名鼎鼎 1 +x:1 +麦客 1 +x:1 +男女排 1 +x:1 +毒素 1 +x:1 +出水孔 1 +x:1 +休闲式 1 +x:1 +影响 1 +x:1 +妙策 1 +x:1 +恶言 1 +x:1 +莫桑比克 1 +x:1 +褐斑病 1 +x:1 +禁核试 1 +x:1 +前敌 1 +x:1 +举办者 1 +x:1 +非文盲率 1 +x:1 +金融版 1 +x:1 +瘪三 1 +x:1 +大清早 1 +x:1 +马边 1 +x:1 +太湖 1 +x:1 +洪泽 1 +x:1 +缩尺 1 +x:1 +互动式 1 +x:1 +城信 1 +x:1 +元老 1 +x:1 +嘎那 1 +x:1 +恩巴 1 +x:1 +感慨万千 1 +x:1 +遗著 1 +x:1 +牌号 1 +x:1 +寿星峰 1 +x:1 +手头 1 +x:1 +尘 13 +x:13 +洋楼 1 +x:1 +达官 1 +x:1 +匿迹海外 1 +x:1 +流窜犯 1 +x:1 +名词 1 +x:1 +大烟泡 1 +x:1 +辩解性 1 +x:1 +牌友 1 +x:1 +此愁 1 +x:1 +放谈 1 +x:1 +名诗 1 +x:1 +四季度 1 +x:1 +可卑 1 +x:1 +缩小 1 +x:1 +煤管站 1 +x:1 +影子 1 +x:1 +鹄 1 +x:1 +梨树县 1 +x:1 +娃娃 1 +x:1 +豆腐粉 1 +x:1 +月牙形 1 +x:1 +音流 1 +x:1 +俄二战 1 +x:1 +翠亨镇 1 +x:1 +牙关 1 +x:1 +抢夺 1 +x:1 +复元膏 1 +x:1 +玉泉营 1 +x:1 +落拓不羁 1 +x:1 +协力集 1 +x:1 +五牛队 1 +x:1 +边隅 1 +x:1 +手套 1 +x:1 +襄阳棉 1 +x:1 +投诉站 1 +x:1 +遗落 1 +x:1 +蕾 21 +x:21 +撮合 1 +x:1 +满当当 1 +x:1 +透射 1 +x:1 +声望度 1 +x:1 +扣篮 1 +x:1 +勋章 1 +x:1 +踏 220 +x:220 +凭吊 1 +x:1 +沸点 1 +x:1 +自己人 1 +x:1 +稗 1 +x:1 +酷似 1 +x:1 +社会主义 1 +x:1 +红石乡 1 +x:1 +分明 1 +x:1 +有口皆碑 1 +x:1 +耕畜 1 +x:1 +黄龙洞 1 +x:1 +惊涛激越 1 +x:1 +涵蕴 1 +x:1 +边际 1 +x:1 +车速 1 +x:1 +水泥业 1 +x:1 +洋槐 1 +x:1 +吞噬 1 +x:1 +勒流 1 +x:1 +弄假 1 +x:1 +三协精机 1 +x:1 +大板车 1 +x:1 +布伦纳 1 +x:1 +高压脊 1 +x:1 +关键性 1 +x:1 +归宿 1 +x:1 +黑瓷 1 +x:1 +尾矿 1 +x:1 +洪水 1 +x:1 +纵向 1 +x:1 +汽笛声 1 +x:1 +耕田 1 +x:1 +实干家 1 +x:1 +慑 3 +x:3 +器物部 1 +x:1 +专题组 1 +x:1 +边防 1 +x:1 +车道 1 +x:1 +达孜 1 +x:1 +想尽 1 +x:1 +多标准论 1 +x:1 +硫 12 +x:12 +奖金额 1 +x:1 +高山病 1 +x:1 +内寄生 1 +x:1 +小树 1 +x:1 +邑馆 1 +x:1 +审计长 1 +x:1 +俺 60 +x:60 +总站 1 +x:1 +分析 1 +x:1 +浮雕感 1 +x:1 +追缴 1 +x:1 +放贷 1 +x:1 +落入 1 +x:1 +小报告 1 +x:1 +搭救 1 +x:1 +朔 6 +x:6 +后山 1 +x:1 +传记 1 +x:1 +边音 1 +x:1 +娃子 1 +x:1 +市报 1 +x:1 +照照 1 +x:1 +春华镇 1 +x:1 +撩 9 +x:9 +笔录体 1 +x:1 +有恃无恐 1 +x:1 +苦思 1 +x:1 +伊瓜苏市 1 +x:1 +剖视图 1 +x:1 +彩花灯 1 +x:1 +峻峭 1 +x:1 +他样 1 +x:1 +蹬腿 1 +x:1 +动量 1 +x:1 +字标 1 +x:1 +酸溜溜 1 +x:1 +出资方 1 +x:1 +柴汽车 1 +x:1 +放走 1 +x:1 +感慨万分 1 +x:1 +嘟囔 1 +x:1 +苦恼 1 +x:1 +亲痛仇快 1 +x:1 +山脚下 1 +x:1 +山西队 1 +x:1 +常时 1 +x:1 +市招 1 +x:1 +洪涝 1 +x:1 +车载斗量 1 +x:1 +首航 1 +x:1 +益气养血 1 +x:1 +名誉 1 +x:1 +梅雷兹党 1 +x:1 +黏胶纤维 1 +x:1 +字样 1 +x:1 +计程表 1 +x:1 +满面春风 1 +x:1 +沉渣 1 +x:1 +拽 20 +x:20 +字根 1 +x:1 +损益 1 +x:1 +嘟嘟 1 +x:1 +前次 1 +x:1 +炉况 1 +x:1 +提留款 1 +x:1 +绸纹纸 1 +x:1 +城乡 1 +x:1 +认证版 1 +x:1 +漫无边际 1 +x:1 +精明能干 1 +x:1 +浴盆 1 +x:1 +氧化焰 1 +x:1 +加卡乡 1 +x:1 +磨刀霍霍 1 +x:1 +分机 1 +x:1 +增速 1 +x:1 +心儿 1 +x:1 +阿谀逢迎 1 +x:1 +晕晕的 1 +x:1 +洪流 1 +x:1 +银泉市 1 +x:1 +反腐倡廉 1 +x:1 +城中 1 +x:1 +上下水 1 +x:1 +整体性 1 +x:1 +历历可数 1 +x:1 +控制者 1 +x:1 +联防费 1 +x:1 +分权 1 +x:1 +晕 8 +x:8 +分杈 1 +x:1 +常数 1 +x:1 +万死不辞 1 +x:1 +观赏处 1 +x:1 +雅韵 1 +x:1 +洪洞 1 +x:1 +城下 1 +x:1 +罗家湾 1 +x:1 +名言 1 +x:1 +侄 1 +x:1 +冒失鬼 1 +x:1 +此情 1 +x:1 +诊断仪 1 +x:1 +椰林湾 1 +x:1 +核查 1 +x:1 +市扰 1 +x:1 +苦情 1 +x:1 +太山庙 1 +x:1 +音波 1 +x:1 +尖儿 1 +x:1 +蚰蜒 1 +x:1 +仿画 1 +x:1 +装饰画 1 +x:1 +区域化 1 +x:1 +分派 1 +x:1 +流民 1 +x:1 +因特网址 1 +x:1 +说法 1 +x:1 +秉笔 1 +x:1 +开挖量 1 +x:1 +心力 1 +x:1 +成 3033 +x:3033 +王堡村 1 +x:1 +黑瘦 1 +x:1 +仿生 1 +x:1 +沉浸 1 +x:1 +心动 1 +x:1 +长春园 1 +x:1 +毒花花 1 +x:1 +花岗石材 1 +x:1 +断路 1 +x:1 +函大 1 +x:1 +储气瓶 1 +x:1 +售票窗 1 +x:1 +名角 1 +x:1 +哨声波 1 +x:1 +俺村 1 +x:1 +蒿 1 +x:1 +无论如何 1 +x:1 +苦捱 1 +x:1 +劳教所 1 +x:1 +呼朋唤友 1 +x:1 +滩尾 1 +x:1 +高脚楼 1 +x:1 +质地 1 +x:1 +黑白 1 +x:1 +行 878 +x:878 +恩德 1 +x:1 +志哀 1 +x:1 +首脑 1 +x:1 +园艺学 1 +x:1 +奔袭 1 +x:1 +赚取 1 +x:1 +迷幻 1 +x:1 +动群 1 +x:1 +伪钞 1 +x:1 +长毛绒 1 +x:1 +救国救民 1 +x:1 +吞咽 1 +x:1 +敬献 1 +x:1 +尺幅 1 +x:1 +阳武 1 +x:1 +铭刻 1 +x:1 +唏嘘 1 +x:1 +遂宁市 1 +x:1 +习惯性 1 +x:1 +机立窑 1 +x:1 +接力队 1 +x:1 +狡黠 1 +x:1 +社会形态 1 +x:1 +借用还 1 +x:1 +放射线 1 +x:1 +洋毫 1 +x:1 +尺度 1 +x:1 +生成器 1 +x:1 +医士 1 +x:1 +救生网 1 +x:1 +熙熙攘攘 1 +x:1 +含羞草 1 +x:1 +沉淀 1 +x:1 +鼓风炉 1 +x:1 +雪障 1 +x:1 +谦谦君子 1 +x:1 +禽畜 1 +x:1 +洪湖 1 +x:1 +职校 1 +x:1 +那霸市 1 +x:1 +翕张 1 +x:1 +不见天日 1 +x:1 +螺杆式 1 +x:1 +英雄山 1 +x:1 +洗理费 1 +x:1 +尖刀 1 +x:1 +渡口 1 +x:1 +诀要 1 +x:1 +军师职 1 +x:1 +噢噢 1 +x:1 +吞吐 1 +x:1 +惬意 1 +x:1 +拉乌舍 1 +x:1 +衡阳县 1 +x:1 +正角儿 1 +x:1 +工工整整 1 +x:1 +误食 1 +x:1 +哭腔 1 +x:1 +百花山 1 +x:1 +黎川县 1 +x:1 +分摊 1 +x:1 +吃住行 1 +x:1 +连拱坝 1 +x:1 +队长 1 +x:1 +纪检员 1 +x:1 +习见 1 +x:1 +天生 1 +x:1 +尾端 1 +x:1 +尖利 1 +x:1 +砂轮 1 +x:1 +自由体操 1 +x:1 +节目单 1 +x:1 +外事部 1 +x:1 +自重 1 +x:1 +示范田 1 +x:1 +仿真丝 1 +x:1 +尖刻 1 +x:1 +洋洲镇 1 +x:1 +虚弱不堪 1 +x:1 +边门 1 +x:1 +焦雷 1 +x:1 +茶花女 1 +x:1 +静脉注射 1 +x:1 +可变 1 +x:1 +桑葚 1 +x:1 +杨木 1 +x:1 +杂症 1 +x:1 +售票箱 1 +x:1 +黄龙溪 1 +x:1 +分文 1 +x:1 +仁爱 1 +x:1 +仿制品 1 +x:1 +资源地 1 +x:1 +苦战 1 +x:1 +尖叫 1 +x:1 +闹新房 1 +x:1 +政治学家 1 +x:1 +选择性 1 +x:1 +同性恋爱 1 +x:1 +煤管科 1 +x:1 +此战 1 +x:1 +报以 1 +x:1 +泸西县 1 +x:1 +说唱剧 1 +x:1 +丧事 1 +x:1 +书画热 1 +x:1 +麦地 1 +x:1 +市情 1 +x:1 +嘟哝 1 +x:1 +治理面 1 +x:1 +好比 1 +x:1 +缩影 1 +x:1 +尖厉 1 +x:1 +橄榄球队 1 +x:1 +水银柱 1 +x:1 +迷彩 1 +x:1 +乎 39 +x:39 +侯鸟 1 +x:1 +染 84 +x:84 +钱庄 1 +x:1 +怀孕 1 +x:1 +拥堵 1 +x:1 +言教 1 +x:1 +郝 102 +x:102 +美国之音 1 +x:1 +常柴 1 +x:1 +陇海 1 +x:1 +祥和 1 +x:1 +字模 1 +x:1 +心口 1 +x:1 +二氧化碳 1 +x:1 +杨村 1 +x:1 +米价 1 +x:1 +棺椁 1 +x:1 +出头之日 1 +x:1 +传经授艺 1 +x:1 +鞋饰 1 +x:1 +雨量 1 +x:1 +浏览者 1 +x:1 +解嘲 1 +x:1 +课后 1 +x:1 +四肢 1 +x:1 +落叶 1 +x:1 +放达 1 +x:1 +势派 1 +x:1 +杏黄色 1 +x:1 +音源 1 +x:1 +钓饵 1 +x:1 +十里堡 1 +x:1 +衡山 1 +x:1 +停车位 1 +x:1 +金融大街 1 +x:1 +二氧化硅 1 +x:1 +义理 1 +x:1 +一般性 1 +x:1 +锡金 1 +x:1 +证明书 1 +x:1 +燕麦 1 +x:1 +三部曲 1 +x:1 +作案人 1 +x:1 +医疗期 1 +x:1 +名街 1 +x:1 +鲁班尺 1 +x:1 +矫治 1 +x:1 +不少 1 +x:1 +分支 1 +x:1 +斗勇 1 +x:1 +搭构 1 +x:1 +上下游 1 +x:1 +铁规章 1 +x:1 +雪韵 1 +x:1 +艺术节 1 +x:1 +松江 1 +x:1 +钱币 1 +x:1 +兴义 1 +x:1 +着力处 1 +x:1 +竖 29 +x:29 +过滤嘴 1 +x:1 +榆林角 1 +x:1 +反犬旁儿 1 +x:1 +凭坚 1 +x:1 +分数 1 +x:1 +边锋 1 +x:1 +红螺山 1 +x:1 +出栏率 1 +x:1 +贴面 1 +x:1 +麦垛 1 +x:1 +首肯 1 +x:1 +乒乓球台 1 +x:1 +恩师 1 +x:1 +日文版 1 +x:1 +续展 1 +x:1 +限制法 1 +x:1 +储气田 1 +x:1 +沉没 1 +x:1 +看守内阁 1 +x:1 +郴州 1 +x:1 +费恩梅 1 +x:1 +商贸点 1 +x:1 +家乡戏 1 +x:1 +敬畏 1 +x:1 +杜菜园村 1 +x:1 +纪念物 1 +x:1 +辍 5 +x:5 +恶臭 1 +x:1 +护卫员 1 +x:1 +艾菲尔 1 +x:1 +无法无天 1 +x:1 +汉剧团 1 +x:1 +具象化 1 +x:1 +车钩 1 +x:1 +磁电机 1 +x:1 +洗池台 1 +x:1 +返乡 1 +x:1 +洋流 1 +x:1 +猛烈 1 +x:1 +幽径 1 +x:1 +断语 1 +x:1 +纪念版 1 +x:1 +掉色 1 +x:1 +纪念牌 1 +x:1 +正是 1 +x:1 +尚地义 1 +x:1 +营营 1 +x:1 +积分 1 +x:1 +明火点 1 +x:1 +文水县 1 +x:1 +朱墩村 1 +x:1 +小步 1 +x:1 +防守战 1 +x:1 +华衣 1 +x:1 +雨雾 1 +x:1 +冷战史 1 +x:1 +遗腹子 1 +x:1 +车铺 1 +x:1 +南盘江 1 +x:1 +青山秀水 1 +x:1 +雨雪 1 +x:1 +分支性 1 +x:1 +不快 1 +x:1 +选择权 1 +x:1 +分配处 1 +x:1 +扣缴 1 +x:1 +矫正 1 +x:1 +洋洋 1 +x:1 +转注 1 +x:1 +麻将牌 1 +x:1 +本草经 1 +x:1 +小铲岛 1 +x:1 +清洁率 1 +x:1 +饮 61 +x:61 +随想录 1 +x:1 +分拣 1 +x:1 +放行 1 +x:1 +零活儿 1 +x:1 +放血 1 +x:1 +落后 1 +x:1 +衡宝 1 +x:1 +下食堂村 1 +x:1 +分成 1 +x:1 +浓缩液 1 +x:1 +名车 1 +x:1 +住宅区 1 +x:1 +黑点 1 +x:1 +收音机 1 +x:1 +落霞 1 +x:1 +天工 1 +x:1 +面面观 1 +x:1 +下车伊始 1 +x:1 +直通率 1 +x:1 +凭借 1 +x:1 +可变性 1 +x:1 +黑炭 1 +x:1 +浮萍 1 +x:1 +高山反应 1 +x:1 +长颈鹿 1 +x:1 +法学班 1 +x:1 +昧 10 +x:10 +苦斗 1 +x:1 +糖尿病人 1 +x:1 +此文 1 +x:1 +常态 1 +x:1 +牌坊 1 +x:1 +分房 1 +x:1 +土豪 1 +x:1 +青山乡 1 +x:1 +冰川期 1 +x:1 +曼然 1 +x:1 +再衰三竭 1 +x:1 +百战不殆 1 +x:1 +手工 1 +x:1 +女人 1 +x:1 +毒瘾 1 +x:1 +传输网 1 +x:1 +毒瘤 1 +x:1 +错怪 1 +x:1 +此时 1 +x:1 +分手 1 +x:1 +手巾 1 +x:1 +进宫 1 +x:1 +分批 1 +x:1 +揪 23 +x:23 +宁阳县 1 +x:1 +头头脑脑 1 +x:1 +不忍 1 +x:1 +濒 2 +x:2 +桥台 1 +x:1 +苦旅 1 +x:1 +沿湖 1 +x:1 +界限量规 1 +x:1 +一扫而光 1 +x:1 +字汇 1 +x:1 +擂鼓 1 +x:1 +天塌地陷 1 +x:1 +缩头 1 +x:1 +九合村 1 +x:1 +扇子舞 1 +x:1 +唯物论者 1 +x:1 +迷失 1 +x:1 +公交线 1 +x:1 +蟾酥 1 +x:1 +逞 5 +x:5 +传输线 1 +x:1 +所向披靡 1 +x:1 +结症 1 +x:1 +怜恤 1 +x:1 +秧歌赛 1 +x:1 +轩轾 1 +x:1 +音校 1 +x:1 +小圈子 1 +x:1 +隐逸 1 +x:1 +主副业 1 +x:1 +车间 1 +x:1 +呆 74 +x:74 +耐酸 1 +x:1 +是的 1 +x:1 +参谋部 1 +x:1 +丈母娘 1 +x:1 +装饰物 1 +x:1 +涤纶 1 +x:1 +迥然 1 +x:1 +热衷于 1 +x:1 +主题性 1 +x:1 +莲韵 1 +x:1 +检验者 1 +x:1 +⑦ 3 +x:3 +创出 1 +x:1 +疏港路 1 +x:1 +续 50 +x:50 +审计部 1 +x:1 +杨舍河 1 +x:1 +因人制宜 1 +x:1 +优柔寡断 1 +x:1 +洋气 1 +x:1 +配套费 1 +x:1 +大功率 1 +x:1 +各色 1 +x:1 +异戊橡胶 1 +x:1 +伞降 1 +x:1 +分挑 1 +x:1 +影库 1 +x:1 +示范片 1 +x:1 +滑雪界 1 +x:1 +土地证 1 +x:1 +硬性 1 +x:1 +清真寺 1 +x:1 +怜惜 1 +x:1 +中外古今 1 +x:1 +接入网 1 +x:1 +返修 1 +x:1 +篱栅 1 +x:1 +多阵性 1 +x:1 +树蕨 1 +x:1 +特种兵 1 +x:1 +饮酒 1 +x:1 +媚 6 +x:6 +比例尺 1 +x:1 +重访 1 +x:1 +资材 1 +x:1 +认 97 +x:97 +助理级 1 +x:1 +胀鼓鼓 1 +x:1 +牛马司镇 1 +x:1 +义父 1 +x:1 +恃强凌弱 1 +x:1 +车锁 1 +x:1 +里海虎 1 +x:1 +院区 1 +x:1 +黑熊 1 +x:1 +一人得道 1 +x:1 +俄罗斯 1 +x:1 +脊索 1 +x:1 +宏观性 1 +x:1 +施展 1 +x:1 +断言 1 +x:1 +滤器 1 +x:1 +铆 3 +x:3 +某人 1 +x:1 +恙虫 1 +x:1 +启封 1 +x:1 +车长 1 +x:1 +寸有所长 1 +x:1 +襄樊市 1 +x:1 +资望 1 +x:1 +快中子 1 +x:1 +变电亭 1 +x:1 +洋油 1 +x:1 +创先 1 +x:1 +麦冬 1 +x:1 +爱国华侨 1 +x:1 +发计委 1 +x:1 +资本 1 +x:1 +蛀虫 1 +x:1 +浓缩法 1 +x:1 +放射科 1 +x:1 +某些 1 +x:1 +跑马水 1 +x:1 +市景 1 +x:1 +麦农 1 +x:1 +孙甘店乡 1 +x:1 +佳木斯市 1 +x:1 +肌体 1 +x:1 +某事 1 +x:1 +报到卡 1 +x:1 +耐量 1 +x:1 +柞蚕丝 1 +x:1 +豆奶机 1 +x:1 +踪迹 1 +x:1 +政治化 1 +x:1 +教唆犯 1 +x:1 +创办 1 +x:1 +交迭 1 +x:1 +苦木 1 +x:1 +前沿 1 +x:1 +羸弱 1 +x:1 +战成 1 +x:1 +添枝加叶 1 +x:1 +市斤 1 +x:1 +南丰县 1 +x:1 +直肠子 1 +x:1 +负效应 1 +x:1 +隘口 1 +x:1 +裁决 1 +x:1 +庸者 1 +x:1 +实心眼儿 1 +x:1 +有门道 1 +x:1 +耐磨 1 +x:1 +自销 1 +x:1 +塔尔寺 1 +x:1 +转寄 1 +x:1 +哗哗哗 1 +x:1 +穗选 1 +x:1 +此条 1 +x:1 +城镇化 1 +x:1 +黑牢 1 +x:1 +喉舌 1 +x:1 +明文规定 1 +x:1 +仿照 1 +x:1 +扣除 1 +x:1 +擦边球 1 +x:1 +达川 1 +x:1 +短波 1 +x:1 +变化万端 1 +x:1 +官桥湖 1 +x:1 +书背 1 +x:1 +降免职 1 +x:1 +启德 1 +x:1 +滦平县 1 +x:1 +滩堆 1 +x:1 +钻石 1 +x:1 +草丛 1 +x:1 +草业 1 +x:1 +哈密瓜 1 +x:1 +敢为人先 1 +x:1 +钓鱼 1 +x:1 +复线率 1 +x:1 +蜀犬吠日 1 +x:1 +上交所 1 +x:1 +三连胜 1 +x:1 +客容量 1 +x:1 +言悔 1 +x:1 +创刊 1 +x:1 +霭霭白云 1 +x:1 +蔡家坡 1 +x:1 +大清河 1 +x:1 +质变 1 +x:1 +瑶山乡 1 +x:1 +创制 1 +x:1 +友谊 1 +x:1 +苦果 1 +x:1 +道歉 1 +x:1 +车队 1 +x:1 +来源于 1 +x:1 +教研部 1 +x:1 +钱学 1 +x:1 +道格拉斯 1 +x:1 +创利 1 +x:1 +市政 1 +x:1 +浑黄 1 +x:1 +名贤 1 +x:1 +卒底炮 1 +x:1 +言情 1 +x:1 +九死不悔 1 +x:1 +双城记 1 +x:1 +名贵 1 +x:1 +自问 1 +x:1 +行洪区 1 +x:1 +双亲 1 +x:1 +铅字合金 1 +x:1 +民族乡 1 +x:1 +高分子 1 +x:1 +孙 1183 +x:1183 +蒙难者 1 +x:1 +伪造 1 +x:1 +推走 1 +x:1 +苟且偷生 1 +x:1 +手心 1 +x:1 +胜人一筹 1 +x:1 +非洲队 1 +x:1 +短池 1 +x:1 +黑狗 1 +x:1 +平摊 1 +x:1 +岗头镇 1 +x:1 +动笔 1 +x:1 +双争 1 +x:1 +捐助点 1 +x:1 +毒理 1 +x:1 +嗲 1 +x:1 +娘亲 1 +x:1 +东高埝村 1 +x:1 +草书 1 +x:1 +资源化 1 +x:1 +万事通 1 +x:1 +数字 1 +x:1 +断裂 1 +x:1 +矢车菊 1 +x:1 +网中之鱼 1 +x:1 +床位费 1 +x:1 +影射 1 +x:1 +仕女图 1 +x:1 +防风林 1 +x:1 +时刻表 1 +x:1 +侯马 1 +x:1 +传道 1 +x:1 +子句 1 +x:1 +日化厂 1 +x:1 +是是非非 1 +x:1 +奔跑 1 +x:1 +心魂 1 +x:1 +斗嘴 1 +x:1 +数学 1 +x:1 +双体 1 +x:1 +手帕 1 +x:1 +高气压区 1 +x:1 +祭礼 1 +x:1 +乒乓球场 1 +x:1 +定性处理 1 +x:1 +此景 1 +x:1 +影展 1 +x:1 +省军区 1 +x:1 +创叔 1 +x:1 +《 13013 +x:13013 +麦区 1 +x:1 +伊丽莎白 1 +x:1 +滩头 1 +x:1 +助消化 1 +x:1 +装饰灯 1 +x:1 +钦州南路 1 +x:1 +网中人 1 +x:1 +田园区 1 +x:1 +尾灯 1 +x:1 +耶稣教徒 1 +x:1 +不刊之论 1 +x:1 +晚香玉 1 +x:1 +桥栏杆 1 +x:1 +玩物丧志 1 +x:1 +居家 1 +x:1 +火光烛天 1 +x:1 +大巴车 1 +x:1 +证书 1 +x:1 +兆示 1 +x:1 +子母钟 1 +x:1 +沙暴 1 +x:1 +高黎贡 1 +x:1 +交运 1 +x:1 +队部 1 +x:1 +尺子 1 +x:1 +吊顶 1 +x:1 +邻舍 1 +x:1 +奶粉厂 1 +x:1 +世界广论 1 +x:1 +调整期 1 +x:1 +养牛人 1 +x:1 +奔赴 1 +x:1 +克敌制胜 1 +x:1 +迷宫 1 +x:1 +奔走 1 +x:1 +资源厅 1 +x:1 +麦口 1 +x:1 +心土 1 +x:1 +安陆市 1 +x:1 +中国区 1 +x:1 +多媒体 1 +x:1 +启幕 1 +x:1 +藕断丝连 1 +x:1 +双关性 1 +x:1 +抢建 1 +x:1 +招标办 1 +x:1 +绅士式 1 +x:1 +醋酸 1 +x:1 +宽限 1 +x:1 +得天独厚 1 +x:1 +比翼齐飞 1 +x:1 +日伪 1 +x:1 +附院 1 +x:1 +争霸战 1 +x:1 +愚妄 1 +x:1 +怀德 1 +x:1 +金融税 1 +x:1 +黑玉 1 +x:1 +可见一斑 1 +x:1 +开放度 1 +x:1 +沙坪坝 1 +x:1 +短浅 1 +x:1 +洋溢 1 +x:1 +听神经 1 +x:1 +心坎 1 +x:1 +民间舞团 1 +x:1 +草体 1 +x:1 +证今 1 +x:1 +押款 1 +x:1 +凭单 1 +x:1 +指环 1 +x:1 +大小腿 1 +x:1 +电子学家 1 +x:1 +尺寸 1 +x:1 +缝衣针 1 +x:1 +万寿无疆 1 +x:1 +质劣 1 +x:1 +祝嘏 1 +x:1 +广告商 1 +x:1 +宽阔 1 +x:1 +社办 1 +x:1 +放诞 1 +x:1 +明令禁止 1 +x:1 +牌名 1 +x:1 +隔离区 1 +x:1 +浙江村 1 +x:1 +土城镇 1 +x:1 +干戈四起 1 +x:1 +资政 1 +x:1 +农作物 1 +x:1 +和衷 1 +x:1 +怀念 1 +x:1 +象牙塔 1 +x:1 +馈赠 1 +x:1 +柔姿纱 1 +x:1 +沉静 1 +x:1 +民国元年 1 +x:1 +自欺 1 +x:1 +雪水 1 +x:1 +伊 534 +x:534 +益发 1 +x:1 +茂 13 +x:13 +和亲 1 +x:1 +授戒师 1 +x:1 +定做 1 +x:1 +为主 1 +x:1 +风声 1 +x:1 +奉节 1 +x:1 +伪满 1 +x:1 +难产 1 +x:1 +办理制 1 +x:1 +集邮展 1 +x:1 +惹是生非 1 +x:1 +万年历 1 +x:1 +口号声 1 +x:1 +炉火纯青 1 +x:1 +弟媳 1 +x:1 +色系 1 +x:1 +财政司 1 +x:1 +洋酒 1 +x:1 +难事 1 +x:1 +难于 1 +x:1 +圣保罗州 1 +x:1 +孙家庄乡 1 +x:1 +蟒蛇 1 +x:1 +女中 1 +x:1 +黑豹 1 +x:1 +看家戏 1 +x:1 +芦苇 1 +x:1 +财政厅 1 +x:1 +局域网 1 +x:1 +脊背 1 +x:1 +司炉 1 +x:1 +七星 1 +x:1 +粘堵 1 +x:1 +自此 1 +x:1 +理顺 1 +x:1 +让胡路区 1 +x:1 +莎草 1 +x:1 +洪钟 1 +x:1 +人口所 1 +x:1 +忠贞 1 +x:1 +金佛 1 +x:1 +抓大放小 1 +x:1 +联系点 1 +x:1 +大主教 1 +x:1 +放映点 1 +x:1 +理事国 1 +x:1 +渔场 1 +x:1 +老年斑 1 +x:1 +闹 103 +x:103 +红新月会 1 +x:1 +人口报 1 +x:1 +难为 1 +x:1 +餐饮业 1 +x:1 +墓园 1 +x:1 +地带性 1 +x:1 +覆 12 +x:12 +郭家店镇 1 +x:1 +突发 1 +x:1 +官员 1 +x:1 +为人 1 +x:1 +突变 1 +x:1 +地方性 1 +x:1 +示范车 1 +x:1 +滑雪衫 1 +x:1 +日照县 1 +x:1 +铁骨铮铮 1 +x:1 +崩 6 +x:6 +如屋漏痕 1 +x:1 +为了 1 +x:1 +钓手 1 +x:1 +烈士 1 +x:1 +黑貂 1 +x:1 +紧追不舍 1 +x:1 +元月份 1 +x:1 +小巷 1 +x:1 +解围 1 +x:1 +亡 46 +x:46 +尾追 1 +x:1 +龙街子 1 +x:1 +固安县 1 +x:1 +窄幅 1 +x:1 +正座 1 +x:1 +平行班 1 +x:1 +别别扭扭 1 +x:1 +车桥 1 +x:1 +扫描线 1 +x:1 +褒词 1 +x:1 +样款 1 +x:1 +供用电 1 +x:1 +财政化 1 +x:1 +自律性 1 +x:1 +突厥 1 +x:1 +铺床 1 +x:1 +拉法耶特 1 +x:1 +括 2 +x:2 +坐次 1 +x:1 +音问 1 +x:1 +空间图形 1 +x:1 +连绵不断 1 +x:1 +铺底 1 +x:1 +水旱灾 1 +x:1 +孽 4 +x:4 +大智大慧 1 +x:1 +脊膜 1 +x:1 +简易楼 1 +x:1 +原装货 1 +x:1 +放电 1 +x:1 +后 9533 +x:9533 +难侨 1 +x:1 +言情戏 1 +x:1 +洪门 1 +x:1 +上年末 1 +x:1 +黑账 1 +x:1 +为伴 1 +x:1 +甜角 1 +x:1 +偷骗税 1 +x:1 +求官者 1 +x:1 +双重性 1 +x:1 +为伍 1 +x:1 +囤积居奇 1 +x:1 +与世浮沉 1 +x:1 +烈女 1 +x:1 +妙趣 1 +x:1 +雪洗 1 +x:1 +金丝 1 +x:1 +主裁 1 +x:1 +沉陷 1 +x:1 +建材城 1 +x:1 +推涛作浪 1 +x:1 +棉织 1 +x:1 +恭贺新禧 1 +x:1 +正当 1 +x:1 +储备率 1 +x:1 +修女 1 +x:1 +狭小 1 +x:1 +七月 1 +x:1 +修复 1 +x:1 +焦油 1 +x:1 +雪海 1 +x:1 +铺张 1 +x:1 +正弦 1 +x:1 +附梁 1 +x:1 +金乡 1 +x:1 +鹿邑县 1 +x:1 +邳州市 1 +x:1 +毒计 1 +x:1 +强调 1 +x:1 +党外人士 1 +x:1 +船级社 1 +x:1 +志愿团 1 +x:1 +忘年之交 1 +x:1 +辽阳市 1 +x:1 +上等货 1 +x:1 +订户 1 +x:1 +正式 1 +x:1 +难保 1 +x:1 +小木车 1 +x:1 +铺开 1 +x:1 +趋于 1 +x:1 +算盘子儿 1 +x:1 +做出 1 +x:1 +哥德兰岛 1 +x:1 +为何 1 +x:1 +一边倒 1 +x:1 +产官学 1 +x:1 +华中 1 +x:1 +献血法 1 +x:1 +定准 1 +x:1 +名物 1 +x:1 +总体部 1 +x:1 +强击 1 +x:1 +近在咫尺 1 +x:1 +稍顷 1 +x:1 +尾身 1 +x:1 +利雅得 1 +x:1 +指日可待 1 +x:1 +寻觅 1 +x:1 +沉雄 1 +x:1 +唯一 1 +x:1 +互助社 1 +x:1 +名片 1 +x:1 +奄奄一息 1 +x:1 +准印证 1 +x:1 +名牌 1 +x:1 +沉雷 1 +x:1 +放疗 1 +x:1 +学友会 1 +x:1 +并行机 1 +x:1 +农民画 1 +x:1 +采矿者 1 +x:1 +和会 1 +x:1 +贷存 1 +x:1 +堕落 1 +x:1 +曼谷 1 +x:1 +前列腺癌 1 +x:1 +金价 1 +x:1 +死得其所 1 +x:1 +专户 1 +x:1 +诫勉 1 +x:1 +林荫处 1 +x:1 +中韩镇 1 +x:1 +弟子 1 +x:1 +金代 1 +x:1 +研究型 1 +x:1 +中上 1 +x:1 +风头 1 +x:1 +六三年 1 +x:1 +黑路 1 +x:1 +此风 1 +x:1 +依山临海 1 +x:1 +蒙学 1 +x:1 +巨 39 +x:39 +工房 1 +x:1 +鲁 186 +x:186 +烹调师 1 +x:1 +色素 1 +x:1 +三环桥 1 +x:1 +姨婆 1 +x:1 +头晕眼花 1 +x:1 +突兀 1 +x:1 +啪达 1 +x:1 +打马虎眼 1 +x:1 +温泉 1 +x:1 +八音盒 1 +x:1 +谋财害命 1 +x:1 +欧山楂 1 +x:1 +前邵 1 +x:1 +色织 1 +x:1 +永平镇 1 +x:1 +鹤望兰 1 +x:1 +橡塑厂 1 +x:1 +疲于 1 +x:1 +耐温 1 +x:1 +地方报 1 +x:1 +连史室 1 +x:1 +电子城 1 +x:1 +梅利达市 1 +x:1 +突入 1 +x:1 +选票 1 +x:1 +胡枝子 1 +x:1 +制服呢 1 +x:1 +鹰式 1 +x:1 +州政府 1 +x:1 +姨妈 1 +x:1 +甲级 1 +x:1 +判罚 1 +x:1 +铺展 1 +x:1 +令人生畏 1 +x:1 +件次 1 +x:1 +人情世故 1 +x:1 +招待所 1 +x:1 +侯月 1 +x:1 +前部 1 +x:1 +银鬃 1 +x:1 +募捐箱 1 +x:1 +非商品 1 +x:1 +贷款者 1 +x:1 +大营门 1 +x:1 +铺就 1 +x:1 +清供 1 +x:1 +辣手 1 +x:1 +初级类 1 +x:1 +处理价 1 +x:1 +冤枉 1 +x:1 +裂变 1 +x:1 +诱 4 +x:4 +大田县 1 +x:1 +愚人 1 +x:1 +砂石 1 +x:1 +定制 1 +x:1 +砂矿 1 +x:1 +缺失 1 +x:1 +果汁厂 1 +x:1 +夏威夷果 1 +x:1 +哥俩 1 +x:1 +青山堡村 1 +x:1 +喉结 1 +x:1 +蹬立 1 +x:1 +短途 1 +x:1 +糟蹋 1 +x:1 +债权额 1 +x:1 +雄心壮志 1 +x:1 +利通社 1 +x:1 +旱育稀植 1 +x:1 +蒙蒙亮 1 +x:1 +投诉者 1 +x:1 +小农经济 1 +x:1 +敬语 1 +x:1 +面具舞 1 +x:1 +侦察 1 +x:1 +前途 1 +x:1 +莫索湾 1 +x:1 +地方戏 1 +x:1 +砂眼 1 +x:1 +窃窃私语 1 +x:1 +突击 1 +x:1 +突出 1 +x:1 +做到 1 +x:1 +步子 1 +x:1 +义赛 1 +x:1 +嗓子眼 1 +x:1 +曲曲弯弯 1 +x:1 +左图 1 +x:1 +司机 1 +x:1 +密植园 1 +x:1 +短道 1 +x:1 +定力 1 +x:1 +娥眉 1 +x:1 +疲乏 1 +x:1 +罗家镇 1 +x:1 +重开 1 +x:1 +丢三忘四 1 +x:1 +辽朝 1 +x:1 +药饵 1 +x:1 +控制符 1 +x:1 +音韵 1 +x:1 +没心没肺 1 +x:1 +断电 1 +x:1 +定势 1 +x:1 +活质 1 +x:1 +边民 1 +x:1 +襄汾 1 +x:1 +保长 1 +x:1 +驰道 1 +x:1 +隐约可见 1 +x:1 +放眼 1 +x:1 +驸马 1 +x:1 +铁蚕豆 1 +x:1 +刺激剂 1 +x:1 +篱障 1 +x:1 +炸伤 1 +x:1 +利息差 1 +x:1 +继任人 1 +x:1 +明特优新 1 +x:1 +加速度 1 +x:1 +定单 1 +x:1 +空天飞机 1 +x:1 +妆 3 +x:3 +公使衔 1 +x:1 +水彩画 1 +x:1 +闽清县 1 +x:1 +矿产学 1 +x:1 +遗罪 1 +x:1 +木棉树 1 +x:1 +购物券 1 +x:1 +邪乎 1 +x:1 +小叔子 1 +x:1 +风寒 1 +x:1 +京戏票 1 +x:1 +巴拉圭籍 1 +x:1 +无功而返 1 +x:1 +随笔 1 +x:1 +美食展 1 +x:1 +草窝棚 1 +x:1 +动感画 1 +x:1 +一视同仁 1 +x:1 +右手 1 +x:1 +柔姿舞 1 +x:1 +葫芦池 1 +x:1 +篮板王 1 +x:1 +风害 1 +x:1 +肇事 1 +x:1 +台东区 1 +x:1 +自给 1 +x:1 +点头之交 1 +x:1 +大风村 1 +x:1 +伤残人员 1 +x:1 +各类 1 +x:1 +珐琅 1 +x:1 +假丑恶 1 +x:1 +遗缺 1 +x:1 +驱虫药 1 +x:1 +哥们 1 +x:1 +民航界 1 +x:1 +至矣尚矣 1 +x:1 +音障 1 +x:1 +进料加工 1 +x:1 +耳子 1 +x:1 +劳改犯 1 +x:1 +选择题 1 +x:1 +耳孔 1 +x:1 +两相情愿 1 +x:1 +车次 1 +x:1 +转赴 1 +x:1 +甄拔 1 +x:1 +醇香 1 +x:1 +榜 26 +x:26 +山 569 +x:569 +菏泽市 1 +x:1 +发言台 1 +x:1 +谨小慎微 1 +x:1 +七日 1 +x:1 +遥祝 1 +x:1 +代总理 1 +x:1 +处方 1 +x:1 +清水笋 1 +x:1 +七时 1 +x:1 +草莓棚 1 +x:1 +万载县 1 +x:1 +言说 1 +x:1 +宣武 1 +x:1 +音韵学 1 +x:1 +顺德县 1 +x:1 +样样 1 +x:1 +断面图 1 +x:1 +录像厅 1 +x:1 +整顿 1 +x:1 +叠 28 +x:28 +圣保罗市 1 +x:1 +诡诈 1 +x:1 +臂弯 1 +x:1 +崔嵬 1 +x:1 +罢手 1 +x:1 +官场 1 +x:1 +定县 1 +x:1 +牛尾巴 1 +x:1 +电影史 1 +x:1 +自检 1 +x:1 +自寻烦恼 1 +x:1 +烈属 1 +x:1 +如鸟兽散 1 +x:1 +阀 2 +x:2 +念及 1 +x:1 +左倾 1 +x:1 +官僚 1 +x:1 +抻面 1 +x:1 +定员 1 +x:1 +二甲苯 1 +x:1 +佛拉芒 1 +x:1 +挚 1 +x:1 +荷方 1 +x:1 +必要产品 1 +x:1 +张掖市 1 +x:1 +听讲者 1 +x:1 +座 1115 +x:1115 +辩证逻辑 1 +x:1 +蚝油 1 +x:1 +退二进三 1 +x:1 +洋镐 1 +x:1 +分骨 1 +x:1 +示范课 1 +x:1 +极权主义 1 +x:1 +茴香豆 1 +x:1 +就职 1 +x:1 +定名 1 +x:1 +制冷机 1 +x:1 +喧腾 1 +x:1 +奸妇 1 +x:1 +接力棒 1 +x:1 +处所 1 +x:1 +循环往复 1 +x:1 +首日 1 +x:1 +声泪俱下 1 +x:1 +速效肥料 1 +x:1 +创造者 1 +x:1 +混乱 1 +x:1 +次区域 1 +x:1 +需要量 1 +x:1 +优越 1 +x:1 +定向 1 +x:1 +桑塔木 1 +x:1 +出资额 1 +x:1 +电影周 1 +x:1 +公映 1 +x:1 +肺腑之言 1 +x:1 +弧度 1 +x:1 +黑油山 1 +x:1 +拆息 1 +x:1 +运输处 1 +x:1 +儋州 1 +x:1 +突地 1 +x:1 +土地爷 1 +x:1 +匾牌 1 +x:1 +峻 18 +x:18 +集资房 1 +x:1 +风岗 1 +x:1 +超短波 1 +x:1 +绿山富民 1 +x:1 +冈上 1 +x:1 +赎买 1 +x:1 +空白点 1 +x:1 +耳屏 1 +x:1 +微生物 1 +x:1 +放炮 1 +x:1 +紧急状态 1 +x:1 +涝洼塘 1 +x:1 +杨舍镇 1 +x:1 +称得上 1 +x:1 +雅训 1 +x:1 +右方 1 +x:1 +四点钟 1 +x:1 +西半球 1 +x:1 +军字号 1 +x:1 +美食家 1 +x:1 +混事 1 +x:1 +洪道 1 +x:1 +千篇一律 1 +x:1 +主治医生 1 +x:1 +噪音区 1 +x:1 +社会效益 1 +x:1 +宜林地 1 +x:1 +网上 1 +x:1 +飘飘扬扬 1 +x:1 +跨鹤西游 1 +x:1 +应者 1 +x:1 +莲湖 1 +x:1 +害兽 1 +x:1 +可变项 1 +x:1 +前院 1 +x:1 +自卑 1 +x:1 +美人鱼 1 +x:1 +余绪 1 +x:1 +音量 1 +x:1 +放热 1 +x:1 +锁边机 1 +x:1 +官倒 1 +x:1 +座位 1 +x:1 +篮板球 1 +x:1 +摩天 1 +x:1 +首群 1 +x:1 +砧子 1 +x:1 +思潮澎湃 1 +x:1 +黏着语 1 +x:1 +动脑 1 +x:1 +雨湖 1 +x:1 +风尘 1 +x:1 +风尚 1 +x:1 +动脉 1 +x:1 +闽侯县 1 +x:1 +自找苦吃 1 +x:1 +三翻四复 1 +x:1 +尾评 1 +x:1 +综 6 +x:6 +利用者 1 +x:1 +上座部 1 +x:1 +音速 1 +x:1 +动能 1 +x:1 +幽丽 1 +x:1 +名目 1 +x:1 +口罩 1 +x:1 +擂鼓墩 1 +x:1 +库底子 1 +x:1 +金融股 1 +x:1 +深耕 1 +x:1 +伪装物 1 +x:1 +死记硬背 1 +x:1 +顺风吹火 1 +x:1 +等外品 1 +x:1 +附注 1 +x:1 +遗祠 1 +x:1 +霖雨 1 +x:1 +跆拳道 1 +x:1 +肉干 1 +x:1 +草棚席 1 +x:1 +宽泛 1 +x:1 +本月底 1 +x:1 +洪量 1 +x:1 +蔫头蔫脑 1 +x:1 +买断式 1 +x:1 +铺子 1 +x:1 +遗祸 1 +x:1 +乔装打扮 1 +x:1 +丫杈 1 +x:1 +地热能 1 +x:1 +节日性 1 +x:1 +地方时 1 +x:1 +官军 1 +x:1 +揭发 1 +x:1 +毒辣 1 +x:1 +扫尾 1 +x:1 +援救 1 +x:1 +饮食业 1 +x:1 +核黄素 1 +x:1 +渔灯谣 1 +x:1 +紫藤 1 +x:1 +工资款 1 +x:1 +笼而统之 1 +x:1 +旅顺口 1 +x:1 +弟弟 1 +x:1 +帮办 1 +x:1 +燕鱼 1 +x:1 +步履 1 +x:1 +超导体 1 +x:1 +追索 1 +x:1 +丛生 1 +x:1 +滑雪赛 1 +x:1 +相对主义 1 +x:1 +丝 73 +x:73 +飘飘忽忽 1 +x:1 +臭氧层 1 +x:1 +洋铁 1 +x:1 +粽子 1 +x:1 +低音炮 1 +x:1 +商务 1 +x:1 +箱位 1 +x:1 +来水量 1 +x:1 +报国情 1 +x:1 +木已成舟 1 +x:1 +突围 1 +x:1 +嗜食 1 +x:1 +字链 1 +x:1 +牵强附会 1 +x:1 +总司令 1 +x:1 +金銮宝座 1 +x:1 +官兵 1 +x:1 +梯恩梯 1 +x:1 +老年性 1 +x:1 +有扬有弃 1 +x:1 +前面 1 +x:1 +顺店乡 1 +x:1 +肉库 1 +x:1 +言情片 1 +x:1 +肉店 1 +x:1 +磨砂玻璃 1 +x:1 +洋钱 1 +x:1 +小船浜 1 +x:1 +边款 1 +x:1 +四环素 1 +x:1 +自满 1 +x:1 +一系列 1 +x:1 +朔州 1 +x:1 +正安 1 +x:1 +月黑风高 1 +x:1 +朱坑乡 1 +x:1 +堆石坝 1 +x:1 +首级 1 +x:1 +点多面广 1 +x:1 +呆傻 1 +x:1 +车流 1 +x:1 +浓缩铀 1 +x:1 +官儿 1 +x:1 +笔名 1 +x:1 +本末 1 +x:1 +正宗 1 +x:1 +横冲直撞 1 +x:1 +橡胶厂 1 +x:1 +洋面 1 +x:1 +弹簧秤 1 +x:1 +左券 1 +x:1 +习用 1 +x:1 +稀里糊涂 1 +x:1 +官道沟 1 +x:1 +汽机 1 +x:1 +北流江 1 +x:1 +担负 1 +x:1 +开具 1 +x:1 +焦比 1 +x:1 +崽子 1 +x:1 +开幕会 1 +x:1 +F 34 +x:34 +边检 1 +x:1 +走样儿 1 +x:1 +新新旧旧 1 +x:1 +三九天 1 +x:1 +颠来倒去 1 +x:1 +鹦鹉热 1 +x:1 +论说文 1 +x:1 +书者 1 +x:1 +痴迷者 1 +x:1 +声名远播 1 +x:1 +记录片 1 +x:1 +二三月 1 +x:1 +纵目四顾 1 +x:1 +风度 1 +x:1 +紫胶虫 1 +x:1 +筠山 1 +x:1 +桓仁县 1 +x:1 +区域网 1 +x:1 +互助组 1 +x:1 +欺人太甚 1 +x:1 +放牧 1 +x:1 +驯熟 1 +x:1 +放牛 1 +x:1 +老处女 1 +x:1 +彦 34 +x:34 +氤氲 1 +x:1 +包产 1 +x:1 +电子厂 1 +x:1 +津津乐道 1 +x:1 +瞿家村 1 +x:1 +禾家村 1 +x:1 +遗稿 1 +x:1 +雪橇 1 +x:1 +涵管 1 +x:1 +揩油 1 +x:1 +信口 1 +x:1 +株数 1 +x:1 +说道 1 +x:1 +雨水 1 +x:1 +末代 1 +x:1 +指指点点 1 +x:1 +信史 1 +x:1 +沉重 1 +x:1 +信号 1 +x:1 +别有用心 1 +x:1 +广华堂 1 +x:1 +风干 1 +x:1 +同等 1 +x:1 +惶恐不安 1 +x:1 +硝酸钾 1 +x:1 +园林化 1 +x:1 +庸碌 1 +x:1 +救援款 1 +x:1 +躺椅 1 +x:1 +放射性 1 +x:1 +核桃林 1 +x:1 +减免税 1 +x:1 +边框 1 +x:1 +漱 1 +x:1 +诬陷 1 +x:1 +修建 1 +x:1 +字音 1 +x:1 +广电厅 1 +x:1 +多隆乡 1 +x:1 +早餐点 1 +x:1 +枝枝叶叶 1 +x:1 +元字符 1 +x:1 +各种 1 +x:1 +收费站卡 1 +x:1 +好八连 1 +x:1 +生产总值 1 +x:1 +风带 1 +x:1 +雅观 1 +x:1 +沉醉 1 +x:1 +常驻 1 +x:1 +尘埃传染 1 +x:1 +减污 1 +x:1 +敬辞 1 +x:1 +日内瓦 1 +x:1 +机电票 1 +x:1 +名画 1 +x:1 +唱片业 1 +x:1 +佛教史 1 +x:1 +管材业 1 +x:1 +风帆 1 +x:1 +起诉状 1 +x:1 +正墙 1 +x:1 +焚稿 1 +x:1 +莲池 1 +x:1 +同义语 1 +x:1 +电子化 1 +x:1 +草丰林长 1 +x:1 +伪标 1 +x:1 +烈度 1 +x:1 +步弓 1 +x:1 +毒谋 1 +x:1 +协约 1 +x:1 +警告信 1 +x:1 +锌 17 +x:17 +焚书坑儒 1 +x:1 +递交 1 +x:1 +三五九旅 1 +x:1 +名瓷 1 +x:1 +分馆 1 +x:1 +恶竹 1 +x:1 +供 351 +x:351 +神魂 1 +x:1 +拉帮结派 1 +x:1 +评剧院 1 +x:1 +包修 1 +x:1 +簇 11 +x:11 +广西团 1 +x:1 +妙计 1 +x:1 +欧佩克 1 +x:1 +窗明几净 1 +x:1 +初级社 1 +x:1 +官司 1 +x:1 +非斯 1 +x:1 +泱泱大国 1 +x:1 +漆黑一团 1 +x:1 +儿童片 1 +x:1 +正太 1 +x:1 +游兴 1 +x:1 +插队落户 1 +x:1 +移动局 1 +x:1 +妙诀 1 +x:1 +乌黑 1 +x:1 +响 216 +x:216 +前门 1 +x:1 +低级 1 +x:1 +官厅 1 +x:1 +人口数 1 +x:1 +好转率 1 +x:1 +铺头 1 +x:1 +匙子 1 +x:1 +岔口 1 +x:1 +妙语 1 +x:1 +争夺者 1 +x:1 +器乐 1 +x:1 +熨斗 1 +x:1 +张家口 1 +x:1 +巢湖 1 +x:1 +控制线 1 +x:1 +拨号盘 1 +x:1 +社发 1 +x:1 +奢糜 1 +x:1 +纲目 1 +x:1 +直管型 1 +x:1 +断点 1 +x:1 +姿 17 +x:17 +字集 1 +x:1 +蒂 1 +x:1 +检验章 1 +x:1 +地面站 1 +x:1 +圆点 1 +x:1 +湿地 1 +x:1 +示范街 1 +x:1 +康庄 1 +x:1 +沉郁 1 +x:1 +有所作为 1 +x:1 +公家人 1 +x:1 +落落寡合 1 +x:1 +步幅 1 +x:1 +三心二意 1 +x:1 +前锋 1 +x:1 +毒资 1 +x:1 +责任心 1 +x:1 +先墓 1 +x:1 +官印 1 +x:1 +三剑客 1 +x:1 +集邮家 1 +x:1 +修律 1 +x:1 +定型 1 +x:1 +寒酸 1 +x:1 +河沿庄村 1 +x:1 +器件 1 +x:1 +名琴 1 +x:1 +包伙 1 +x:1 +义行 1 +x:1 +多经林 1 +x:1 +舍车保帅 1 +x:1 +官化 1 +x:1 +毒贩 1 +x:1 +化入 1 +x:1 +沃田 1 +x:1 +两下子 1 +x:1 +正如 1 +x:1 +无酒精 1 +x:1 +黑话 1 +x:1 +上风 1 +x:1 +辽阳县 1 +x:1 +光谱 1 +x:1 +干白 1 +x:1 +喉管 1 +x:1 +喜唱乐听 1 +x:1 +饿 69 +x:69 +北角 1 +x:1 +分隔 1 +x:1 +针鼻 1 +x:1 +洼里乡 1 +x:1 +万溪冲 1 +x:1 +谎报 1 +x:1 +各省 1 +x:1 +揭底 1 +x:1 +雨披 1 +x:1 +进货关 1 +x:1 +氯化镁 1 +x:1 +鲸塘镇 1 +x:1 +娱乐城 1 +x:1 +非生产性 1 +x:1 +穿缝透窗 1 +x:1 +面带微笑 1 +x:1 +芒崖 1 +x:1 +风景林 1 +x:1 +湖沼 1 +x:1 +东团堡乡 1 +x:1 +短骨 1 +x:1 +微雕 1 +x:1 +头痛 1 +x:1 +记录簿 1 +x:1 +专销点 1 +x:1 +肢体 1 +x:1 +丝织版 1 +x:1 +自持 1 +x:1 +盐湖城 1 +x:1 +憨厚 1 +x:1 +归西 1 +x:1 +圣多明各 1 +x:1 +栓皮栎 1 +x:1 +林副产品 1 +x:1 +凑 76 +x:76 +下跌 1 +x:1 +广谋从众 1 +x:1 +二军大 1 +x:1 +贵省 1 +x:1 +护路林 1 +x:1 +氯化锌 1 +x:1 +苦酒 1 +x:1 +远光灯 1 +x:1 +代常委 1 +x:1 +狗叫屯 1 +x:1 +风雨如晦 1 +x:1 +故技重演 1 +x:1 +总装备部 1 +x:1 +奔突 1 +x:1 +留客 1 +x:1 +宽慰 1 +x:1 +步入 1 +x:1 +非议 1 +x:1 +分队 1 +x:1 +中医药 1 +x:1 +队服 1 +x:1 +揭帖 1 +x:1 +报道面 1 +x:1 +步兵 1 +x:1 +联欢节 1 +x:1 +一蹴而就 1 +x:1 +内疚感 1 +x:1 +分阴 1 +x:1 +盆地 1 +x:1 +风偏 1 +x:1 +羊角风 1 +x:1 +八·一三 1 +x:1 +谈判会 1 +x:1 +财政学 1 +x:1 +组织科 1 +x:1 +移锭 1 +x:1 +集邮品 1 +x:1 +有口无心 1 +x:1 +美颜 1 +x:1 +史学观点 1 +x:1 +先进者 1 +x:1 +揭幕 1 +x:1 +美食城 1 +x:1 +前驱 1 +x:1 +摹仿 1 +x:1 +栗子 1 +x:1 +碱金属 1 +x:1 +向例 1 +x:1 +紫薇 1 +x:1 +槐花蜜 1 +x:1 +祝家山村 1 +x:1 +中间派 1 +x:1 +中轴线 1 +x:1 +心里有数 1 +x:1 +县行 1 +x:1 +衫 2 +x:2 +前哨 1 +x:1 +非胰岛素 1 +x:1 +名笔 1 +x:1 +分院 1 +x:1 +凹镜 1 +x:1 +苦英英 1 +x:1 +沸沸扬扬 1 +x:1 +锁眼 1 +x:1 +金柜山 1 +x:1 +梁 525 +x:525 +曲靖市 1 +x:1 +名章 1 +x:1 +谈判人 1 +x:1 +山顶洞人 1 +x:1 +石浦港 1 +x:1 +炼渣 1 +x:1 +砂粒 1 +x:1 +盘桓 1 +x:1 +断绝 1 +x:1 +偷抗税 1 +x:1 +胡说八道 1 +x:1 +固县 1 +x:1 +风凉 1 +x:1 +源源 1 +x:1 +氧化铁皮 1 +x:1 +官差 1 +x:1 +矿容 1 +x:1 +断续 1 +x:1 +自成 1 +x:1 +自我 1 +x:1 +单性 1 +x:1 +财神老爷 1 +x:1 +修养 1 +x:1 +正字 1 +x:1 +毒菌 1 +x:1 +辣椒 1 +x:1 +龙泉驿 1 +x:1 +禽蛋 1 +x:1 +司法 1 +x:1 +样报 1 +x:1 +正在 1 +x:1 +辽河 1 +x:1 +敬老 1 +x:1 +肉刑 1 +x:1 +集体经济 1 +x:1 +扬州市 1 +x:1 +饮料 1 +x:1 +砂糖 1 +x:1 +沸腾 1 +x:1 +荆州 1 +x:1 +浓墨重彩 1 +x:1 +彭山县 1 +x:1 +风冷 1 +x:1 +蓝田猿人 1 +x:1 +以刚济柔 1 +x:1 +选稿 1 +x:1 +主权国 1 +x:1 +拉萨河畔 1 +x:1 +元煤 1 +x:1 +蜀山 1 +x:1 +名窑 1 +x:1 +定夺 1 +x:1 +忌 41 +x:41 +小金库 1 +x:1 +之江 1 +x:1 +审议会 1 +x:1 +站柜 1 +x:1 +沉默 1 +x:1 +揭开 1 +x:1 +韭黄 1 +x:1 +作家班 1 +x:1 +无可非议 1 +x:1 +蚊 5 +x:5 +尾蚴 1 +x:1 +耳光 1 +x:1 +不世之功 1 +x:1 +重任在肩 1 +x:1 +三庄乡 1 +x:1 +毒药 1 +x:1 +女童班 1 +x:1 +宽恕 1 +x:1 +附息 1 +x:1 +氯化银 1 +x:1 +泾阳县 1 +x:1 +圮 1 +x:1 +阿拉德市 1 +x:1 +惑人耳目 1 +x:1 +仕族 1 +x:1 +竞拍声 1 +x:1 +扎根绳 1 +x:1 +还原论 1 +x:1 +毒草 1 +x:1 +起名儿 1 +x:1 +黄水疮 1 +x:1 +铺垫 1 +x:1 +驰骛 1 +x:1 +黑藻 1 +x:1 +氯化钙 1 +x:1 +雌激素 1 +x:1 +韬略 1 +x:1 +陕 46 +x:46 +字频 1 +x:1 +三电办 1 +x:1 +驰骋 1 +x:1 +年初四 1 +x:1 +束 57 +x:57 +焉耆 1 +x:1 +得法 1 +x:1 +住宅业 1 +x:1 +艳丽 1 +x:1 +自拔 1 +x:1 +嗨 6 +x:6 +级距 1 +x:1 +氯化钾 1 +x:1 +讲话声 1 +x:1 +首犯 1 +x:1 +油印机 1 +x:1 +梦笔生花 1 +x:1 +广阔无垠 1 +x:1 +大堡镇 1 +x:1 +演习班 1 +x:1 +添麻烦 1 +x:1 +墓坑 1 +x:1 +辍学 1 +x:1 +涅 3 +x:3 +人山人海 1 +x:1 +酩浆 1 +x:1 +分钟 1 +x:1 +扣襻 1 +x:1 +儒 14 +x:14 +名称 1 +x:1 +定婚 1 +x:1 +矽钢 1 +x:1 +无国界 1 +x:1 +颐和园 1 +x:1 +贷款行 1 +x:1 +分钱 1 +x:1 +修剪 1 +x:1 +自感 1 +x:1 +色盲 1 +x:1 +审判长 1 +x:1 +色相 1 +x:1 +车技 1 +x:1 +犄角之势 1 +x:1 +迅疾 1 +x:1 +翡翠鱼 1 +x:1 +记里鼓车 1 +x:1 +随风倒 1 +x:1 +车把 1 +x:1 +动迁 1 +x:1 +家具厂 1 +x:1 +实习室 1 +x:1 +重印率 1 +x:1 +各界 1 +x:1 +责任制 1 +x:1 +简易房 1 +x:1 +市里 1 +x:1 +日上三竿 1 +x:1 +间不容发 1 +x:1 +自慰 1 +x:1 +控制率 1 +x:1 +官庄 1 +x:1 +焚毁 1 +x:1 +象牙 1 +x:1 +雪景 1 +x:1 +喻家湾村 1 +x:1 +官府 1 +x:1 +风势 1 +x:1 +精打细算 1 +x:1 +黑里寨镇 1 +x:1 +左右逢源 1 +x:1 +焦枯 1 +x:1 +简分数 1 +x:1 +油乎乎 1 +x:1 +正名 1 +x:1 +宪章派 1 +x:1 +矩 2 +x:2 +救助卡 1 +x:1 +机床厂 1 +x:1 +敬茶 1 +x:1 +邻省 1 +x:1 +风力 1 +x:1 +常设 1 +x:1 +盥洗 1 +x:1 +漯河 1 +x:1 +动辄 1 +x:1 +考级制 1 +x:1 +静脉 1 +x:1 +铁轨 1 +x:1 +炼液 1 +x:1 +姨儿 1 +x:1 +阿的里海 1 +x:1 +迷你型 1 +x:1 +救命卡 1 +x:1 +反映论 1 +x:1 +放纵 1 +x:1 +劐 1 +x:1 +动轮 1 +x:1 +放红 1 +x:1 +财政奖 1 +x:1 +安顺市 1 +x:1 +痛痒相关 1 +x:1 +扑克牌 1 +x:1 +车战 1 +x:1 +正品 1 +x:1 +乌鸡 1 +x:1 +救援机 1 +x:1 +医疗队 1 +x:1 +三叶虫 1 +x:1 +处治 1 +x:1 +纵剖面 1 +x:1 +监护费 1 +x:1 +真心诚意 1 +x:1 +蝉 3 +x:3 +凹面 1 +x:1 +莳花种草 1 +x:1 +占道费 1 +x:1 +互为因果 1 +x:1 +奉行 1 +x:1 +益处 1 +x:1 +场合 1 +x:1 +扛 58 +x:58 +前项 1 +x:1 +下疳 1 +x:1 +务工人员 1 +x:1 +解放区 1 +x:1 +云溪区 1 +x:1 +信徒 1 +x:1 +会话式 1 +x:1 +挂钩点 1 +x:1 +肉冠 1 +x:1 +车手 1 +x:1 +脸蛋儿 1 +x:1 +惠农县 1 +x:1 +涵盖 1 +x:1 +做官 1 +x:1 +定子 1 +x:1 +秦始皇帝 1 +x:1 +念奴娇 1 +x:1 +骡 1 +x:1 +打印稿 1 +x:1 +放缓 1 +x:1 +做客 1 +x:1 +踮 1 +x:1 +九九 1 +x:1 +内弟 1 +x:1 +芒市 1 +x:1 +群体组 1 +x:1 +兆赫 1 +x:1 +砂纸 1 +x:1 +咀嚼 1 +x:1 +丘布特河 1 +x:1 +呆帐 1 +x:1 +摔跤 1 +x:1 +雪板 1 +x:1 +走街串户 1 +x:1 +高田乡 1 +x:1 +孙公司 1 +x:1 +毒物 1 +x:1 +老党员 1 +x:1 +动身 1 +x:1 +放置 1 +x:1 +虫吃牙 1 +x:1 +风压 1 +x:1 +荡妇 1 +x:1 +联系箱 1 +x:1 +雪杖 1 +x:1 +唾手可得 1 +x:1 +湿寒 1 +x:1 +首汽 1 +x:1 +人情味 1 +x:1 +訾 3 +x:3 +官德 1 +x:1 +集邮圈 1 +x:1 +偿愿 1 +x:1 +氰化 1 +x:1 +波光潋滟 1 +x:1 +火车头 1 +x:1 +毒腺 1 +x:1 +炼油 1 +x:1 +煞风景 1 +x:1 +引人瞩目 1 +x:1 +密封环 1 +x:1 +见诸行动 1 +x:1 +老豆腐 1 +x:1 +瞬时 1 +x:1 +左徒 1 +x:1 +荒路 1 +x:1 +骑马人 1 +x:1 +风华 1 +x:1 +相容性 1 +x:1 +摁扣儿 1 +x:1 +生俘 1 +x:1 +电影室 1 +x:1 +亮 283 +x:283 +病故 1 +x:1 +放羊 1 +x:1 +东跑西颠 1 +x:1 +雨意 1 +x:1 +修史 1 +x:1 +砚山 1 +x:1 +岔开 1 +x:1 +电影家 1 +x:1 +铁桥镇 1 +x:1 +整年累月 1 +x:1 +卫生系 1 +x:1 +拜托 1 +x:1 +雪柳 1 +x:1 +承建商 1 +x:1 +冬暖夏凉 1 +x:1 +加速器 1 +x:1 +市道 1 +x:1 +恩情郡 1 +x:1 +弟兄 1 +x:1 +凹陷 1 +x:1 +骤 20 +x:20 +雪柜 1 +x:1 +小两口 1 +x:1 +光辐射 1 +x:1 +过氧化物 1 +x:1 +车损 1 +x:1 +涝洼地 1 +x:1 +常青 1 +x:1 +否认 1 +x:1 +成千上万 1 +x:1 +风化 1 +x:1 +宽旷 1 +x:1 +排山倒海 1 +x:1 +牛年马月 1 +x:1 +人贩子 1 +x:1 +总理级 1 +x:1 +非源 1 +x:1 +定居 1 +x:1 +毒蛾 1 +x:1 +定局 1 +x:1 +件数 1 +x:1 +四方面军 1 +x:1 +信女 1 +x:1 +万古留辉 1 +x:1 +人情化 1 +x:1 +耐性 1 +x:1 +宝玉 1 +x:1 +粉墨登场 1 +x:1 +正割 1 +x:1 +峡湾 1 +x:1 +借阅部 1 +x:1 +右派 1 +x:1 +国安队 1 +x:1 +信奉 1 +x:1 +剑阁县 1 +x:1 +焚烧 1 +x:1 +曲棍球队 1 +x:1 +随意化 1 +x:1 +㧟 1 +x:1 +拍手叫好 1 +x:1 +断简 1 +x:1 +验收关 1 +x:1 +电影局 1 +x:1 +多面手 1 +x:1 +莎车 1 +x:1 +怒容 1 +x:1 +工作团 1 +x:1 +秉赋 1 +x:1 +附料 1 +x:1 +里里外外 1 +x:1 +伪报 1 +x:1 +舍身取义 1 +x:1 +摘记 1 +x:1 +一揽子 1 +x:1 +此镇 1 +x:1 +今非昔比 1 +x:1 +庇护国 1 +x:1 +乐器室 1 +x:1 +咬紧牙关 1 +x:1 +描述性 1 +x:1 +地主家 1 +x:1 +选择面 1 +x:1 +老前辈 1 +x:1 +自杀 1 +x:1 +遗产地 1 +x:1 +信访室 1 +x:1 +先富 1 +x:1 +接口卡 1 +x:1 +将信将疑 1 +x:1 +互帮互学 1 +x:1 +协作会 1 +x:1 +矿产品 1 +x:1 +七坊镇 1 +x:1 +辣油 1 +x:1 +追究 1 +x:1 +小年夜 1 +x:1 +砂礓 1 +x:1 +样板 1 +x:1 +街谈巷语 1 +x:1 +风味 1 +x:1 +分支部 1 +x:1 +毒虫 1 +x:1 +教唆者 1 +x:1 +湟源县 1 +x:1 +豹头 1 +x:1 +领照费 1 +x:1 +宽敞 1 +x:1 +眷恋 1 +x:1 +毛集镇 1 +x:1 +市侩主义 1 +x:1 +闸北 1 +x:1 +和平鸽 1 +x:1 +华坪县 1 +x:1 +轻元素 1 +x:1 +公交车 1 +x:1 +苦闷 1 +x:1 +瞅瞅 1 +x:1 +样本 1 +x:1 +子母机 1 +x:1 +营运潮 1 +x:1 +雨景 1 +x:1 +喉炎 1 +x:1 +池水 1 +x:1 +哈萨克族 1 +x:1 +定岗 1 +x:1 +样机 1 +x:1 +妇唱夫随 1 +x:1 +市面 1 +x:1 +质感性 1 +x:1 +联系簿 1 +x:1 +当家的 1 +x:1 +磨蹭 1 +x:1 +漫游生物 1 +x:1 +办事 1 +x:1 +题解 1 +x:1 +功利主义 1 +x:1 +风向 1 +x:1 +雇佣军 1 +x:1 +占有权 1 +x:1 +盼 121 +x:121 +高压电 1 +x:1 +汽水 1 +x:1 +算术课 1 +x:1 +步哨 1 +x:1 +老生常谈 1 +x:1 +黑脸 1 +x:1 +驻点 1 +x:1 +志愿书 1 +x:1 +非一流 1 +x:1 +轻重倒置 1 +x:1 +色彩纷呈 1 +x:1 +芝麻 1 +x:1 +场主 1 +x:1 +日照市 1 +x:1 +遗照 1 +x:1 +哀荣 1 +x:1 +正午 1 +x:1 +泰国铢 1 +x:1 +烫伤 1 +x:1 +雨林 1 +x:1 +热力学 1 +x:1 +避雷器 1 +x:1 +一招一式 1 +x:1 +求助人 1 +x:1 +队报 1 +x:1 +跨区机 1 +x:1 +奉还 1 +x:1 +市集 1 +x:1 +右江 1 +x:1 +棚代客车 1 +x:1 +捞取 1 +x:1 +历历在目 1 +x:1 +奉迎 1 +x:1 +工头制 1 +x:1 +丢人 1 +x:1 +童 152 +x:152 +常量 1 +x:1 +做工 1 +x:1 +鸡窝寒 1 +x:1 +务农 1 +x:1 +五金件 1 +x:1 +雅雨堂 1 +x:1 +处死 1 +x:1 +风里来 1 +x:1 +吴令 1 +x:1 +正北 1 +x:1 +围垦区 1 +x:1 +集资款 1 +x:1 +六月六 1 +x:1 +枝繁果盛 1 +x:1 +尾花 1 +x:1 +信士 1 +x:1 +居多 1 +x:1 +汽油 1 +x:1 +地球仪 1 +x:1 +回扣费 1 +x:1 +定州 1 +x:1 +非法所得 1 +x:1 +起诉科 1 +x:1 +利在当代 1 +x:1 +典藏本 1 +x:1 +志在 1 +x:1 +正号 1 +x:1 +三座门 1 +x:1 +预警机 1 +x:1 +晃动 1 +x:1 +正反 1 +x:1 +摩托车厂 1 +x:1 +吴中 1 +x:1 +铺叙 1 +x:1 +首相 1 +x:1 +超极限 1 +x:1 +砂砾 1 +x:1 +姜末 1 +x:1 +交财字 1 +x:1 +制作费 1 +x:1 +畅行无阻 1 +x:1 +投诉车 1 +x:1 +常流水 1 +x:1 +焦急 1 +x:1 +污水源 1 +x:1 +政坛 1 +x:1 +仿若 1 +x:1 +督察处 1 +x:1 +山海关区 1 +x:1 +耕耘 1 +x:1 +说不清楚 1 +x:1 +亲上加亲 1 +x:1 +正厅 1 +x:1 +花色品种 1 +x:1 +如痴如醉 1 +x:1 +轻纺化 1 +x:1 +丢丑 1 +x:1 +耕者 1 +x:1 +秸 1 +x:1 +败仗 1 +x:1 +万佛塔 1 +x:1 +呆子 1 +x:1 +分米波 1 +x:1 +羽毛厂 1 +x:1 +组织罪 1 +x:1 +优惠价 1 +x:1 +储备粮 1 +x:1 +吹吹打打 1 +x:1 +电子对 1 +x:1 +湿度 1 +x:1 +编制数 1 +x:1 +挥之不去 1 +x:1 +非油 1 +x:1 +索 31 +x:31 +如来佛 1 +x:1 +勤政殿 1 +x:1 +四位一体 1 +x:1 +反犹主义 1 +x:1 +记录稿 1 +x:1 +红场 1 +x:1 +动词 1 +x:1 +局限性 1 +x:1 +幕后戏 1 +x:1 +流线型 1 +x:1 +吼 17 +x:17 +峡江 1 +x:1 +放空 1 +x:1 +黑色 1 +x:1 +法事 1 +x:1 +试制品 1 +x:1 +平时 1 +x:1 +非法 1 +x:1 +动议 1 +x:1 +三集中 1 +x:1 +毙 4 +x:4 +臂力 1 +x:1 +升降器 1 +x:1 +前泊林村 1 +x:1 +源东乡 1 +x:1 +哭鼻子 1 +x:1 +联系线 1 +x:1 +自救 1 +x:1 +届中 1 +x:1 +家具城 1 +x:1 +矫饰 1 +x:1 +录像带 1 +x:1 +彻里彻外 1 +x:1 +分部 1 +x:1 +保护膜 1 +x:1 +如临深渊 1 +x:1 +雕镂 1 +x:1 +管弦乐曲 1 +x:1 +电子学 1 +x:1 +宽松 1 +x:1 +自新 1 +x:1 +拜望 1 +x:1 +分送 1 +x:1 +资本额 1 +x:1 +腰鼓舞 1 +x:1 +雨搭 1 +x:1 +栾城镇 1 +x:1 +分选 1 +x:1 +奉调 1 +x:1 +自治体 1 +x:1 +浙江队 1 +x:1 +纠 19 +x:19 +估估 1 +x:1 +自料 1 +x:1 +朗布依埃 1 +x:1 +朱 2093 +x:2093 +赎回 1 +x:1 +交货 1 +x:1 +文锦渡 1 +x:1 +市镇 1 +x:1 +轧钢厂 1 +x:1 +附有 1 +x:1 +五花八门 1 +x:1 +严令 1 +x:1 +官威 1 +x:1 +黄榆树 1 +x:1 +饮酒者 1 +x:1 +总社 1 +x:1 +内分泌 1 +x:1 +苫盖 1 +x:1 +密执安州 1 +x:1 +土少石多 1 +x:1 +尽管如此 1 +x:1 +内当家 1 +x:1 +鸣沙山 1 +x:1 +壤 1 +x:1 +民间艺术 1 +x:1 +抖动 1 +x:1 +信守 1 +x:1 +密封盖 1 +x:1 +珀斯 1 +x:1 +陈列品 1 +x:1 +淋巴细胞 1 +x:1 +艳 57 +x:57 +阴沉沉 1 +x:1 +似血 1 +x:1 +萌发 1 +x:1 +雅致 1 +x:1 +市长 1 +x:1 +跋涉 1 +x:1 +土耳其 1 +x:1 +邂逅 1 +x:1 +摄取量 1 +x:1 +车架 1 +x:1 +黑茶 1 +x:1 +抉 1 +x:1 +塞纳河 1 +x:1 +理发师 1 +x:1 +戈阳县 1 +x:1 +汽渡 1 +x:1 +措大 1 +x:1 +通道式 1 +x:1 +定当 1 +x:1 +云干乡 1 +x:1 +研究员级 1 +x:1 +延津县 1 +x:1 +有时候 1 +x:1 +文山州 1 +x:1 +彩陶文化 1 +x:1 +亚硝化螺 1 +x:1 +估产 1 +x:1 +粤剧 1 +x:1 +人情债 1 +x:1 +焦拉 1 +x:1 +嚼舌 1 +x:1 +义肢 1 +x:1 +管委会 1 +x:1 +纲纪 1 +x:1 +厌烦 1 +x:1 +井底之蛙 1 +x:1 +定式 1 +x:1 +府厅发 1 +x:1 +广学会 1 +x:1 +溃于蚁穴 1 +x:1 +嘎查 1 +x:1 +控制数字 1 +x:1 +前营村 1 +x:1 +双学双比 1 +x:1 +舍己为人 1 +x:1 +元月 1 +x:1 +耳垂 1 +x:1 +日入而息 1 +x:1 +分野 1 +x:1 +分量 1 +x:1 +估价 1 +x:1 +反唇相讥 1 +x:1 +定弦 1 +x:1 +时有发生 1 +x:1 +毛利率 1 +x:1 +官室 1 +x:1 +切尔西队 1 +x:1 +红兮兮 1 +x:1 +耳垢 1 +x:1 +铬镍钢 1 +x:1 +官家 1 +x:1 +矿产地 1 +x:1 +殡仪馆 1 +x:1 +集邮史 1 +x:1 +海枯石烂 1 +x:1 +财政局 1 +x:1 +常备不懈 1 +x:1 +苦难 1 +x:1 +结案率 1 +x:1 +肉品 1 +x:1 +官子 1 +x:1 +视网膜 1 +x:1 +正凶 1 +x:1 +厚古薄今 1 +x:1 +鹁鸠 1 +x:1 +青铜峡市 1 +x:1 +写稿人 1 +x:1 +千花竞秀 1 +x:1 +洪魔 1 +x:1 +非洲 1 +x:1 +鹁鸪 1 +x:1 +不知不觉 1 +x:1 +寻亲访友 1 +x:1 +风成于上 1 +x:1 +耍手段 1 +x:1 +凑份子 1 +x:1 +耳坠 1 +x:1 +鹁鸽 1 +x:1 +核计划 1 +x:1 +正月十三 1 +x:1 +音高 1 +x:1 +独到 1 +x:1 +定律 1 +x:1 +掩饰 1 +x:1 +资费 1 +x:1 +箭在弦上 1 +x:1 +车条 1 +x:1 +成交额 1 +x:1 +苦雨 1 +x:1 +模压模 1 +x:1 +泰国队 1 +x:1 +分配 1 +x:1 +恒星级 1 +x:1 +风圈 1 +x:1 +大黄山 1 +x:1 +妙药 1 +x:1 +正册 1 +x:1 +真抓实干 1 +x:1 +坎大哈 1 +x:1 +半途而废 1 +x:1 +岔子 1 +x:1 +民众党 1 +x:1 +行政区域 1 +x:1 +风土 1 +x:1 +奉赠 1 +x:1 +胆固醇 1 +x:1 +酿 16 +x:16 +碳酸钠 1 +x:1 +碳酸钡 1 +x:1 +剔出 1 +x:1 +潞城 1 +x:1 +五金厂 1 +x:1 +弊 19 +x:19 +正书 1 +x:1 +餐饮店 1 +x:1 +下滑调 1 +x:1 +级次 1 +x:1 +动问 1 +x:1 +芸芸众生 1 +x:1 +场区 1 +x:1 +人情会 1 +x:1 +警告声 1 +x:1 +难度 1 +x:1 +老年症 1 +x:1 +正义 1 +x:1 +老年病 1 +x:1 +孙单驼 1 +x:1 +万木成林 1 +x:1 +等候席 1 +x:1 +色泽 1 +x:1 +漪 1 +x:1 +杜 508 +x:508 +叔祖母 1 +x:1 +定点店 1 +x:1 +产生量 1 +x:1 +驰荡 1 +x:1 +七百 1 +x:1 +输电网 1 +x:1 +洋腔 1 +x:1 +碳酸钙 1 +x:1 +败北 1 +x:1 +分身 1 +x:1 +纳西族 1 +x:1 +中餐馆 1 +x:1 +国法 1 +x:1 +光芒 1 +x:1 +自筹 1 +x:1 +样管 1 +x:1 +联交所 1 +x:1 +推土机 1 +x:1 +黑鱼 1 +x:1 +政调会 1 +x:1 +懒惰症 1 +x:1 +篆文 1 +x:1 +断枝 1 +x:1 +市话 1 +x:1 +毒贩子 1 +x:1 +边纵 1 +x:1 +耐火材料 1 +x:1 +无以言状 1 +x:1 +首次 1 +x:1 +正方形 1 +x:1 +三视图 1 +x:1 +祭陵 1 +x:1 +正业 1 +x:1 +第纳尔 1 +x:1 +三叉神经 1 +x:1 +防毒面具 1 +x:1 +有机化学 1 +x:1 +舍己为公 1 +x:1 +馆 101 +x:101 +恶浪 1 +x:1 +大板村 1 +x:1 +丘布特省 1 +x:1 +昏 24 +x:24 +佬 2 +x:2 +看家狗 1 +x:1 +前舱 1 +x:1 +橄榄球界 1 +x:1 +商议 1 +x:1 +教研组 1 +x:1 +房源 1 +x:1 +正价 1 +x:1 +有色 1 +x:1 +手指头 1 +x:1 +与年俱增 1 +x:1 +别有天地 1 +x:1 +网娘 1 +x:1 +协作区 1 +x:1 +胸中 1 +x:1 +产学研 1 +x:1 +婶子 1 +x:1 +狂欢夜 1 +x:1 +短舱 1 +x:1 +雪粉 1 +x:1 +酥油茶 1 +x:1 +弓弩手 1 +x:1 +黑鲈 1 +x:1 +遗泽 1 +x:1 +钡盐 1 +x:1 +呃 1 +x:1 +涵洞 1 +x:1 +更动 1 +x:1 +新街村 1 +x:1 +酥油草 1 +x:1 +小星星 1 +x:1 +绸带 1 +x:1 +受处分者 1 +x:1 +毒 105 +x:105 +和平 1 +x:1 +幽默感 1 +x:1 +败叶 1 +x:1 +正事 1 +x:1 +义齿 1 +x:1 +防风衣 1 +x:1 +绸布 1 +x:1 +状告 1 +x:1 +儿女情 1 +x:1 +断木 1 +x:1 +此见 1 +x:1 +摩拳擦掌 1 +x:1 +魁北克 1 +x:1 +莳秧行 1 +x:1 +独唱 1 +x:1 +轻纺业 1 +x:1 +煤气罐 1 +x:1 +尔诈我虞 1 +x:1 +年初一 1 +x:1 +收藏者 1 +x:1 +大酱汤 1 +x:1 +放放 1 +x:1 +土地权 1 +x:1 +年初三 1 +x:1 +两路镇 1 +x:1 +民主改革 1 +x:1 +嗓门儿 1 +x:1 +托举串 1 +x:1 +雌雄异体 1 +x:1 +拙作 1 +x:1 +名拳 1 +x:1 +控制棒 1 +x:1 +外听道 1 +x:1 +叛卖 1 +x:1 +铺位 1 +x:1 +信丰乡 1 +x:1 +聪明伶俐 1 +x:1 +小屋 1 +x:1 +隧洞 1 +x:1 +递增 1 +x:1 +移风易俗 1 +x:1 +难得 1 +x:1 +酥油花 1 +x:1 +纸型 1 +x:1 +嗟来之食 1 +x:1 +金市 1 +x:1 +耶 10 +x:10 +分辨 1 +x:1 +分辩 1 +x:1 +荫蔽 1 +x:1 +接风洗尘 1 +x:1 +名护 1 +x:1 +金平 1 +x:1 +组织性 1 +x:1 +苦衷 1 +x:1 +矿管办 1 +x:1 +名难副实 1 +x:1 +打头阵 1 +x:1 +后委会 1 +x:1 +仕 1 +x:1 +先发制人 1 +x:1 +汽灯 1 +x:1 +放散 1 +x:1 +年初九 1 +x:1 +综合派 1 +x:1 +镇巴县 1 +x:1 +难忘 1 +x:1 +上辛口乡 1 +x:1 +红河州 1 +x:1 +矮矮的 1 +x:1 +新饿乡 1 +x:1 +贵港 1 +x:1 +逐一 1 +x:1 +棉花包 1 +x:1 +占有率 1 +x:1 +苦行 1 +x:1 +藐小 1 +x:1 +带来 1 +x:1 +和弦 1 +x:1 +严冬 1 +x:1 +涵江 1 +x:1 +氧炔吹管 1 +x:1 +休眠芽 1 +x:1 +医疗费 1 +x:1 +名扬 1 +x:1 +幽媾 1 +x:1 +社文司 1 +x:1 +色浆 1 +x:1 +时间词 1 +x:1 +婶婶 1 +x:1 +言辞 1 +x:1 +匡庐奇秀 1 +x:1 +枇杷 1 +x:1 +赤铜色 1 +x:1 +金库 1 +x:1 +婶婆 1 +x:1 +和式 1 +x:1 +篱落 1 +x:1 +名手 1 +x:1 +战旗 1 +x:1 +检验法 1 +x:1 +益母草 1 +x:1 +打道回府 1 +x:1 +教学课 1 +x:1 +路透社 1 +x:1 +南面王 1 +x:1 +碳纤维 1 +x:1 +上湾乡 1 +x:1 +车祸 1 +x:1 +稳产田 1 +x:1 +黄岩区 1 +x:1 +禽鸭 1 +x:1 +海市蜃楼 1 +x:1 +分水岭 1 +x:1 +鳞 6 +x:6 +原料药 1 +x:1 +网子 1 +x:1 +失败者 1 +x:1 +誊写钢版 1 +x:1 +名戏 1 +x:1 +难当 1 +x:1 +三足鼎立 1 +x:1 +广昌县 1 +x:1 +里贾纳市 1 +x:1 +民航机 1 +x:1 +恶气 1 +x:1 +贵溪 1 +x:1 +婶娘 1 +x:1 +包头 1 +x:1 +溶胶 1 +x:1 +前肢 1 +x:1 +处理 1 +x:1 +言谈 1 +x:1 +坐标 1 +x:1 +六月份 1 +x:1 +黑鸦 1 +x:1 +扶优治劣 1 +x:1 +沙湾河 1 +x:1 +贮藏库 1 +x:1 +举报人 1 +x:1 +亲如一家 1 +x:1 +车窗 1 +x:1 +民庭 1 +x:1 +改日 1 +x:1 +倬 1 +x:1 +砂枪 1 +x:1 +春字头儿 1 +x:1 +各派 1 +x:1 +名不虚传 1 +x:1 +上航 1 +x:1 +蔺 4 +x:4 +蝗蝻 1 +x:1 +墓葬品 1 +x:1 +沿 211 +x:211 +第比利斯 1 +x:1 +巡洋舰 1 +x:1 +妇工委 1 +x:1 +投诉部 1 +x:1 +放晴 1 +x:1 +莘庄 1 +x:1 +伏牛山 1 +x:1 +克山 1 +x:1 +卖 857 +x:857 +无星级 1 +x:1 +五大三粗 1 +x:1 +稍许 1 +x:1 +回扣风 1 +x:1 +友情 1 +x:1 +国画家 1 +x:1 +车站 1 +x:1 +凹进 1 +x:1 +铁观音 1 +x:1 +磁县 1 +x:1 +孤行己见 1 +x:1 +捶 3 +x:3 +士 32 +x:32 +此议 1 +x:1 +此讯 1 +x:1 +雪线 1 +x:1 +蟒山 1 +x:1 +雪纺 1 +x:1 +邪念 1 +x:1 +破坏 1 +x:1 +零花钱 1 +x:1 +严加 1 +x:1 +此访 1 +x:1 +全家人 1 +x:1 +舞龙队 1 +x:1 +滑润油 1 +x:1 +黑麦 1 +x:1 +奉送 1 +x:1 +植物园 1 +x:1 +得票数 1 +x:1 +前者 1 +x:1 +旱冰鞋 1 +x:1 +器官 1 +x:1 +动静 1 +x:1 +一般无二 1 +x:1 +场内 1 +x:1 +邮资片 1 +x:1 +邀功 1 +x:1 +实战 1 +x:1 +掉泪 1 +x:1 +后事之师 1 +x:1 +误点 1 +x:1 +遇害者 1 +x:1 +塞浦路斯 1 +x:1 +车程 1 +x:1 +和尚 1 +x:1 +切纳洛市 1 +x:1 +邪心 1 +x:1 +少男少女 1 +x:1 +此语 1 +x:1 +做官者 1 +x:1 +惊叹声 1 +x:1 +苦读 1 +x:1 +自称 1 +x:1 +老尖沟 1 +x:1 +金工 1 +x:1 +齐街乡 1 +x:1 +附笔 1 +x:1 +惨剧 1 +x:1 +持卡人 1 +x:1 +黑黑 1 +x:1 +联系户 1 +x:1 +和局 1 +x:1 +乐于 1 +x:1 +吴兴 1 +x:1 +金川 1 +x:1 +金州 1 +x:1 +雒 1 +x:1 +志愿军 1 +x:1 +审计署 1 +x:1 +感奋 1 +x:1 +臣民 1 +x:1 +自私 1 +x:1 +滤波器 1 +x:1 +习性 1 +x:1 +解决率 1 +x:1 +妙龄 1 +x:1 +盒式带 1 +x:1 +车管 1 +x:1 +比附 1 +x:1 +储运部 1 +x:1 +图案画 1 +x:1 +智力型 1 +x:1 +记录本 1 +x:1 +言责 1 +x:1 +藏青果 1 +x:1 +搭车 1 +x:1 +言败 1 +x:1 +小河 1 +x:1 +玫 2 +x:2 +关键词 1 +x:1 +蝗虫 1 +x:1 +此言 1 +x:1 +阮 81 +x:81 +钢人 1 +x:1 +搭载 1 +x:1 +巡展 1 +x:1 +洛阳江 1 +x:1 +贵池 1 +x:1 +金山 1 +x:1 +竞相 1 +x:1 +身患重症 1 +x:1 +放松 1 +x:1 +车篷 1 +x:1 +遗漏 1 +x:1 +巢穴 1 +x:1 +惨叫 1 +x:1 +株距 1 +x:1 +谎称 1 +x:1 +人民政府 1 +x:1 +创刊词 1 +x:1 +吱吱 1 +x:1 +荠 1 +x:1 +惨变 1 +x:1 +进士 1 +x:1 +嗯 4 +x:4 +金属 1 +x:1 +运输业 1 +x:1 +宽窄 1 +x:1 +呆小症 1 +x:1 +包容 1 +x:1 +气性 1 +x:1 +掩藏 1 +x:1 +见财起意 1 +x:1 +进退两难 1 +x:1 +支持者 1 +x:1 +举报信 1 +x:1 +熟橡胶 1 +x:1 +吸尘器 1 +x:1 +掩蔽 1 +x:1 +网头 1 +x:1 +靠边儿站 1 +x:1 +分贝 1 +x:1 +印尼 1 +x:1 +持机人 1 +x:1 +袒 1 +x:1 +道法 1 +x:1 +军需部 1 +x:1 +优惠卡 1 +x:1 +贷款量 1 +x:1 +贵峰村 1 +x:1 +锐意进取 1 +x:1 +土地日 1 +x:1 +严厉 1 +x:1 +闭路电视 1 +x:1 +闻过则喜 1 +x:1 +有声有色 1 +x:1 +接踵而至 1 +x:1 +前脑 1 +x:1 +幽境 1 +x:1 +踏板式 1 +x:1 +友 73 +x:73 +前脚 1 +x:1 +常轨 1 +x:1 +字节 1 +x:1 +高枕无忧 1 +x:1 +愚弄 1 +x:1 +陨石雨 1 +x:1 +微循环 1 +x:1 +习惯 1 +x:1 +克己 1 +x:1 +分赃 1 +x:1 +胶木粉 1 +x:1 +叛匪 1 +x:1 +前腿 1 +x:1 +前言 1 +x:1 +切手机 1 +x:1 +分赴 1 +x:1 +洋芋 1 +x:1 +小剧场 1 +x:1 +言路 1 +x:1 +分赠 1 +x:1 +儒商 1 +x:1 +中篇卷 1 +x:1 +合理性 1 +x:1 +慰灵塔 1 +x:1 +克州 1 +x:1 +香远 1 +x:1 +清水河 1 +x:1 +葛村 1 +x:1 +半饥半饱 1 +x:1 +不平家 1 +x:1 +肉体 1 +x:1 +特别税 1 +x:1 +德才兼备 1 +x:1 +疖子 1 +x:1 +摹刻 1 +x:1 +青红皂白 1 +x:1 +拗口令 1 +x:1 +场场 1 +x:1 +无止无休 1 +x:1 +场地 1 +x:1 +拴心 1 +x:1 +元气 1 +x:1 +切切实实 1 +x:1 +网底 1 +x:1 +产 280 +x:280 +清水沙 1 +x:1 +场圃 1 +x:1 +理有固然 1 +x:1 +娴 7 +x:7 +分支行 1 +x:1 +谈判台 1 +x:1 +传染源 1 +x:1 +短粗的 1 +x:1 +断掉 1 +x:1 +苏 438 +x:438 +贸工 1 +x:1 +毒麦 1 +x:1 +首演 1 +x:1 +特马港 1 +x:1 +无可指责 1 +x:1 +护航型 1 +x:1 +鹜 1 +x:1 +踊跃 1 +x:1 +金子 1 +x:1 +败坏 1 +x:1 +场址 1 +x:1 +煮 49 +x:49 +耳朵垂 1 +x:1 +老蚌生珠 1 +x:1 +胡杨林 1 +x:1 +百年不遇 1 +x:1 +名果 1 +x:1 +鄙 1 +x:1 +愚味 1 +x:1 +突如其来 1 +x:1 +蜜桃 1 +x:1 +阿鲁巴 1 +x:1 +近卫军 1 +x:1 +金客 1 +x:1 +壮怀激烈 1 +x:1 +铅笔 1 +x:1 +活泼泼 1 +x:1 +无怨言 1 +x:1 +以销定产 1 +x:1 +合江 1 +x:1 +准备会 1 +x:1 +蔡公堂乡 1 +x:1 +不对 1 +x:1 +演奏家 1 +x:1 +无密码 1 +x:1 +独具 1 +x:1 +束手无策 1 +x:1 +续弦 1 +x:1 +吴圩 1 +x:1 +锁死 1 +x:1 +羞愧 1 +x:1 +截流 1 +x:1 +阖上 1 +x:1 +草料场 1 +x:1 +镁 4 +x:4 +此路 1 +x:1 +穿孔机 1 +x:1 +劝戒 1 +x:1 +胡杨木 1 +x:1 +老年医学 1 +x:1 +清水池 1 +x:1 +灶头 1 +x:1 +疲塌 1 +x:1 +日内瓦湖 1 +x:1 +外事组 1 +x:1 +泛滥成灾 1 +x:1 +公办侨助 1 +x:1 +丰田市 1 +x:1 +安顿 1 +x:1 +寥寥无几 1 +x:1 +坭 1 +x:1 +清水江 1 +x:1 +识花者 1 +x:1 +女色关 1 +x:1 +奉陪 1 +x:1 +舌咽神经 1 +x:1 +过滤器 1 +x:1 +总而言之 1 +x:1 +名望 1 +x:1 +最佳期 1 +x:1 +盘梯 1 +x:1 +哈尔滨 1 +x:1 +悲惨惨 1 +x:1 +洋葱 1 +x:1 +遵义市 1 +x:1 +易燃点 1 +x:1 +名曰 1 +x:1 +名曲 1 +x:1 +白热化 1 +x:1 +普耶普罗 1 +x:1 +巧干 1 +x:1 +短线型 1 +x:1 +黄岩城 1 +x:1 +像册 1 +x:1 +海校 1 +x:1 +判案 1 +x:1 +包工 1 +x:1 +偏居一隅 1 +x:1 +恶棍 1 +x:1 +分设 1 +x:1 +匮缺 1 +x:1 +苦调 1 +x:1 +督察官 1 +x:1 +碟 15 +x:15 +外来词 1 +x:1 +迥然有异 1 +x:1 +分装厂 1 +x:1 +恶梦 1 +x:1 +幽幽 1 +x:1 +日记账 1 +x:1 +古丈县 1 +x:1 +澳门币 1 +x:1 +克山病 1 +x:1 +摹印 1 +x:1 +分诊 1 +x:1 +扬店乡 1 +x:1 +香扑扑 1 +x:1 +上下肢 1 +x:1 +沉船 1 +x:1 +肉丸 1 +x:1 +雪神 1 +x:1 +吴国 1 +x:1 +拥 38 +x:38 +四处奔波 1 +x:1 +常见 1 +x:1 +常规 1 +x:1 +南关村 1 +x:1 +煤气站 1 +x:1 +克子 1 +x:1 +苦豆 1 +x:1 +暴虎冯河 1 +x:1 +地方病 1 +x:1 +队章 1 +x:1 +爱眼日 1 +x:1 +厄 66 +x:66 +鲜艳夺目 1 +x:1 +涤除 1 +x:1 +科钦 1 +x:1 +异亮氨酸 1 +x:1 +儒医 1 +x:1 +尾骨 1 +x:1 +乐东 1 +x:1 +友机 1 +x:1 +帝 11 +x:11 +乌鱼 1 +x:1 +为害 1 +x:1 +雅尔塔 1 +x:1 +过氧化氢 1 +x:1 +妙语解颐 1 +x:1 +友朋 1 +x:1 +游仙诗 1 +x:1 +胸无大志 1 +x:1 +姨丈 1 +x:1 +为官 1 +x:1 +朱砂梅 1 +x:1 +言论 1 +x:1 +绸子 1 +x:1 +牢固 1 +x:1 +多巴哥岛 1 +x:1 +微量元素 1 +x:1 +无神论 1 +x:1 +炼狱 1 +x:1 +败因 1 +x:1 +能言善辩 1 +x:1 +言词 1 +x:1 +被乘数 1 +x:1 +诬蔑 1 +x:1 +群体性 1 +x:1 +肢势 1 +x:1 +利索 1 +x:1 +自绝 1 +x:1 +状元 1 +x:1 +拥有量 1 +x:1 +鳄鱼眼泪 1 +x:1 +饮食店 1 +x:1 +健体强身 1 +x:1 +高压氧 1 +x:1 +言语 1 +x:1 +二·二八 1 +x:1 +科托努 1 +x:1 +不适感 1 +x:1 +义马 1 +x:1 +奔月 1 +x:1 +高蛋白 1 +x:1 +气浪 1 +x:1 +名星 1 +x:1 +油气流 1 +x:1 +洁净 1 +x:1 +风仪 1 +x:1 +名旦 1 +x:1 +较量 1 +x:1 +平罗县 1 +x:1 +脱缰之马 1 +x:1 +张家集镇 1 +x:1 +炼焦 1 +x:1 +冗笔 1 +x:1 +榕 7 +x:7 +祭祀 1 +x:1 +国破家亡 1 +x:1 +打印机 1 +x:1 +试飞组 1 +x:1 +右眼 1 +x:1 +情网 1 +x:1 +炯 52 +x:52 +恶毒 1 +x:1 +开幕式 1 +x:1 +独台 1 +x:1 +工艺美术 1 +x:1 +姿势 1 +x:1 +见诸 1 +x:1 +仰卧 1 +x:1 +行蓄洪区 1 +x:1 +疾苦 1 +x:1 +鹅黄 1 +x:1 +包庇 1 +x:1 +耐穿 1 +x:1 +言行 1 +x:1 +分裂 1 +x:1 +分装 1 +x:1 +和声 1 +x:1 +矿产业 1 +x:1 +器形 1 +x:1 +零用费 1 +x:1 +醉醺醺 1 +x:1 +鸣声 1 +x:1 +黑马 1 +x:1 +圣城 1 +x:1 +混居 1 +x:1 +精制品 1 +x:1 +金奖 1 +x:1 +朵朵 1 +x:1 +群威群胆 1 +x:1 +烈性酒 1 +x:1 +跃然 1 +x:1 +放手 1 +x:1 +车组 1 +x:1 +哈利斯科 1 +x:1 +风云 1 +x:1 +冈峦 1 +x:1 +慌慌忙忙 1 +x:1 +意见者 1 +x:1 +紧迫感 1 +x:1 +风习 1 +x:1 +风乡 1 +x:1 +预留户 1 +x:1 +狡狯 1 +x:1 +莎 18 +x:18 +责任令 1 +x:1 +难堪 1 +x:1 +名数 1 +x:1 +饶命 1 +x:1 +忍辱负重 1 +x:1 +正统派 1 +x:1 +雪窝 1 +x:1 +队礼 1 +x:1 +独占 1 +x:1 +常言 1 +x:1 +集资热 1 +x:1 +呕吐 1 +x:1 +前后台 1 +x:1 +动感情 1 +x:1 +主题词 1 +x:1 +洁具 1 +x:1 +北新桥 1 +x:1 +纯文学 1 +x:1 +包干 1 +x:1 +亲合力 1 +x:1 +雪竹 1 +x:1 +还原铁 1 +x:1 +责任人 1 +x:1 +风雨如磐 1 +x:1 +说者 1 +x:1 +分行 1 +x:1 +诱惑力 1 +x:1 +弥合 1 +x:1 +舞姿 1 +x:1 +包帮 1 +x:1 +葫芦科 1 +x:1 +舞蹈诗式 1 +x:1 +冈山 1 +x:1 +二拇指 1 +x:1 +得意洋洋 1 +x:1 +时报社 1 +x:1 +七点 1 +x:1 +营销额 1 +x:1 +混凝土 1 +x:1 +淮阴市 1 +x:1 +飞秒级 1 +x:1 +蝗莺 1 +x:1 +网屏 1 +x:1 +洛阳桥 1 +x:1 +立牌者 1 +x:1 +丛林 1 +x:1 +宽绰 1 +x:1 +市貌 1 +x:1 +借阅证 1 +x:1 +伪称 1 +x:1 +格老村 1 +x:1 +步代 1 +x:1 +嘲弄 1 +x:1 +丰南市 1 +x:1 +依然如故 1 +x:1 +想开 1 +x:1 +辑录 1 +x:1 +误用 1 +x:1 +贮藏室 1 +x:1 +明争暗斗 1 +x:1 +华西村 1 +x:1 +各校 1 +x:1 +马赛港 1 +x:1 +官迷心窍 1 +x:1 +摇摇曳曳 1 +x:1 +各样 1 +x:1 +球拍子 1 +x:1 +出资证 1 +x:1 +冷语 1 +x:1 +风俗 1 +x:1 +自古以来 1 +x:1 +大悟县 1 +x:1 +摘要 1 +x:1 +地方矿 1 +x:1 +荡荡乎 1 +x:1 +网巾 1 +x:1 +分规 1 +x:1 +邻摊 1 +x:1 +做 4513 +x:4513 +独力 1 +x:1 +聚酰亚胺 1 +x:1 +狡猾 1 +x:1 +后者 1 +x:1 +坠儿 1 +x:1 +哭泣 1 +x:1 +状态词 1 +x:1 +音色 1 +x:1 +为奇 1 +x:1 +常识 1 +x:1 +医疗证 1 +x:1 +分解 1 +x:1 +场员 1 +x:1 +国立市 1 +x:1 +侯爷 1 +x:1 +惊心触目 1 +x:1 +侯爵 1 +x:1 +恺 2 +x:2 +气绝身亡 1 +x:1 +珊树村 1 +x:1 +谍报 1 +x:1 +市府大楼 1 +x:1 +献血站 1 +x:1 +瓦窑堡 1 +x:1 +放映权 1 +x:1 +冈崎 1 +x:1 +不避艰险 1 +x:1 +追昔抚今 1 +x:1 +金墩 1 +x:1 +音节 1 +x:1 +网号 1 +x:1 +家具业 1 +x:1 +人民院 1 +x:1 +放排 1 +x:1 +研究会 1 +x:1 +洪荒 1 +x:1 +器底 1 +x:1 +摹写 1 +x:1 +中毒案 1 +x:1 +互异性 1 +x:1 +硕果累累 1 +x:1 +祭祖 1 +x:1 +难处 1 +x:1 +紧迫性 1 +x:1 +奔放 1 +x:1 +犯人照 1 +x:1 +易燃物 1 +x:1 +就诊量 1 +x:1 +风传 1 +x:1 +丛杂 1 +x:1 +凤翔县 1 +x:1 +襄阳南路 1 +x:1 +义塾 1 +x:1 +对话费 1 +x:1 +和好 1 +x:1 +繁忙 1 +x:1 +独创 1 +x:1 +想必 1 +x:1 +物镜 1 +x:1 +义项 1 +x:1 +鸣奏 1 +x:1 +姑娘群 1 +x:1 +资财 1 +x:1 +放浪 1 +x:1 +想念 1 +x:1 +搭讪 1 +x:1 +翰 3 +x:3 +减肥热 1 +x:1 +放映机 1 +x:1 +霸道 1 +x:1 +陈工 1 +x:1 +搭设 1 +x:1 +历久弥坚 1 +x:1 +长此下去 1 +x:1 +女网赛 1 +x:1 +黄梁梦 1 +x:1 +钓竿 1 +x:1 +放水 1 +x:1 +馨著 1 +x:1 +伏案疾书 1 +x:1 +棒子面 1 +x:1 +敬酒 1 +x:1 +鬼亲 1 +x:1 +调令 1 +x:1 +非科技 1 +x:1 +焦痕 1 +x:1 +罪因 1 +x:1 +未 1411 +x:1411 +独岛 1 +x:1 +转机建制 1 +x:1 +音质 1 +x:1 +洛阳村 1 +x:1 +光风霁月 1 +x:1 +扶扶 1 +x:1 +售票额 1 +x:1 +放眼看去 1 +x:1 +悬铃木 1 +x:1 +雪球 1 +x:1 +缸管 1 +x:1 +习武 1 +x:1 +山西省 1 +x:1 +令人振奋 1 +x:1 +电传 1 +x:1 +林甸县 1 +x:1 +器具 1 +x:1 +累牍连篇 1 +x:1 +不孝 1 +x:1 +本该 1 +x:1 +雅静 1 +x:1 +处理品 1 +x:1 +各村 1 +x:1 +斜视 1 +x:1 +骟驼 1 +x:1 +乡议局 1 +x:1 +油鞋 1 +x:1 +金块 1 +x:1 +金坛 1 +x:1 +交战团体 1 +x:1 +各条 1 +x:1 +狮子座 1 +x:1 +切身利益 1 +x:1 +无铅化 1 +x:1 +递减 1 +x:1 +场子 1 +x:1 +工社党 1 +x:1 +美学史 1 +x:1 +黑钱 1 +x:1 +乱哄哄 1 +x:1 +探索室 1 +x:1 +分蘖 1 +x:1 +意大利籍 1 +x:1 +敬重 1 +x:1 +裙装 1 +x:1 +非商业 1 +x:1 +七绝 1 +x:1 +上年纪 1 +x:1 +粘 18 +x:18 +盘查 1 +x:1 +水流量 1 +x:1 +可管理性 1 +x:1 +交流电 1 +x:1 +映荡 1 +x:1 +处级 1 +x:1 +捞一把 1 +x:1 +裙裤 1 +x:1 +沉迷 1 +x:1 +花墟街 1 +x:1 +裙裾 1 +x:1 +互助性 1 +x:1 +超逸 1 +x:1 +砂浆 1 +x:1 +万事如意 1 +x:1 +名次 1 +x:1 +刺刺不休 1 +x:1 +巧言令色 1 +x:1 +尾音 1 +x:1 +脑力劳动 1 +x:1 +姜片 1 +x:1 +插 108 +x:108 +想像 1 +x:1 +控制感 1 +x:1 +铳响 1 +x:1 +瓢泼 1 +x:1 +记录法 1 +x:1 +女儿身 1 +x:1 +名款 1 +x:1 +处结 1 +x:1 +纸上谈兵 1 +x:1 +车灯 1 +x:1 +红斑狼疮 1 +x:1 +彩涂 1 +x:1 +下半身 1 +x:1 +多见者 1 +x:1 +七级 1 +x:1 +入室弟子 1 +x:1 +转世灵童 1 +x:1 +实弹射击 1 +x:1 +金城 1 +x:1 +办公会议 1 +x:1 +放活 1 +x:1 +密锣紧鼓 1 +x:1 +雪花呢 1 +x:1 +自爱 1 +x:1 +单晶河村 1 +x:1 +电石气 1 +x:1 +辑入 1 +x:1 +隔热性 1 +x:1 +音调 1 +x:1 +耐用 1 +x:1 +遗教 1 +x:1 +教练场 1 +x:1 +新沂河 1 +x:1 +法学院 1 +x:1 +望子成材 1 +x:1 +解放军 1 +x:1 +遗族 1 +x:1 +黑锅 1 +x:1 +市花 1 +x:1 +子子孙孙 1 +x:1 +首批 1 +x:1 +短论 1 +x:1 +说辞 1 +x:1 +短评 1 +x:1 +相聚一堂 1 +x:1 +色斑 1 +x:1 +扫描术 1 +x:1 +雕艺 1 +x:1 +仁寿县 1 +x:1 +遥控 1 +x:1 +跃跃一试 1 +x:1 +君山 1 +x:1 +杏红 1 +x:1 +外来 1 +x:1 +网口 1 +x:1 +扫描机 1 +x:1 +处罚 1 +x:1 +糖弹 1 +x:1 +首战 1 +x:1 +雨珠 1 +x:1 +还我河山 1 +x:1 +讨论会 1 +x:1 +处置 1 +x:1 +七窍生烟 1 +x:1 +营养组 1 +x:1 +家徒四壁 1 +x:1 +短语 1 +x:1 +肥瘦儿 1 +x:1 +欢送会 1 +x:1 +一团和气 1 +x:1 +大自然 1 +x:1 +基酒 1 +x:1 +水到渠成 1 +x:1 +放流 1 +x:1 +网友 1 +x:1 +七零八落 1 +x:1 +裙褶 1 +x:1 +独居 1 +x:1 +变异型 1 +x:1 +哥哥 1 +x:1 +妥妥帖帖 1 +x:1 +单相思 1 +x:1 +雕花 1 +x:1 +雄峻挺拔 1 +x:1 +理事会 1 +x:1 +一元复始 1 +x:1 +獐狮荡乡 1 +x:1 +杏花岭区 1 +x:1 +接头处 1 +x:1 +再终字 1 +x:1 +下板城 1 +x:1 +样片 1 +x:1 +包公 1 +x:1 +侯马市 1 +x:1 +仇 15 +x:15 +洋装 1 +x:1 +片面 1 +x:1 +成议 1 +x:1 +故道区 1 +x:1 +楔子 1 +x:1 +孜孜以求 1 +x:1 +青春年少 1 +x:1 +吊丝竹 1 +x:1 +包养 1 +x:1 +色散 1 +x:1 +遗文 1 +x:1 +惊叹号 1 +x:1 +名模 1 +x:1 +总负责人 1 +x:1 +丁是丁 1 +x:1 +舅舅 1 +x:1 +虹桥 1 +x:1 +汾阳 1 +x:1 +开小差 1 +x:1 +农副食品 1 +x:1 +缝缝补补 1 +x:1 +占有物 1 +x:1 +高山铺 1 +x:1 +车照 1 +x:1 +年收入 1 +x:1 +天下太平 1 +x:1 +驰誉 1 +x:1 +饮用 1 +x:1 +课题组 1 +x:1 +杜仲 1 +x:1 +成群连片 1 +x:1 +镇公所 1 +x:1 +遥指 1 +x:1 +混双 1 +x:1 +控制性 1 +x:1 +疾恶如仇 1 +x:1 +苦胆 1 +x:1 +五味俱全 1 +x:1 +题辞 1 +x:1 +灶君 1 +x:1 +压缩疗法 1 +x:1 +网协 1 +x:1 +软卧票 1 +x:1 +稷山县 1 +x:1 +佛教会 1 +x:1 +雨点 1 +x:1 +黑阵 1 +x:1 +元戎 1 +x:1 +红衣主教 1 +x:1 +传奇 1 +x:1 +自然 1 +x:1 +品性 1 +x:1 +误码 1 +x:1 +智力库 1 +x:1 +白蒙蒙 1 +x:1 +舐 1 +x:1 +神龛 1 +x:1 +非洲狮 1 +x:1 +扣饰 1 +x:1 +正安县 1 +x:1 +民航法 1 +x:1 +信使 1 +x:1 +为名 1 +x:1 +邻村 1 +x:1 +涪江 1 +x:1 +为之一振 1 +x:1 +领头雁 1 +x:1 +所办 1 +x:1 +呼天抢地 1 +x:1 +诓骗 1 +x:1 +汽笛 1 +x:1 +半殖民地 1 +x:1 +无敌号 1 +x:1 +红头蝇 1 +x:1 +繁华似锦 1 +x:1 +脊骨 1 +x:1 +九曲回肠 1 +x:1 +场外 1 +x:1 +贺 180 +x:180 +官价 1 +x:1 +短装 1 +x:1 +此药 1 +x:1 +教练员 1 +x:1 +瓦解冰消 1 +x:1 +黑陶 1 +x:1 +尾随 1 +x:1 +桌 49 +x:49 +根除 1 +x:1 +包办 1 +x:1 +黄土路 1 +x:1 +衔接期 1 +x:1 +料峭 1 +x:1 +短裙 1 +x:1 +走样 1 +x:1 +短裤 1 +x:1 +剪板工 1 +x:1 +鸣响 1 +x:1 +营运科 1 +x:1 +官人 1 +x:1 +影格儿 1 +x:1 +似真似假 1 +x:1 +路基导弹 1 +x:1 +储备棉 1 +x:1 +买椟还珠 1 +x:1 +恶果 1 +x:1 +母亲节 1 +x:1 +断流 1 +x:1 +被罚者 1 +x:1 +空间 1 +x:1 +贵族 1 +x:1 +难听 1 +x:1 +元麻布 1 +x:1 +鸣吼 1 +x:1 +司署 1 +x:1 +名楼 1 +x:1 +上下车 1 +x:1 +矢口否认 1 +x:1 +三老四严 1 +x:1 +巧妇 1 +x:1 +菜市口 1 +x:1 +为官者 1 +x:1 +丰南县 1 +x:1 +艺术品部 1 +x:1 +延寿县 1 +x:1 +登峰造极 1 +x:1 +裳 2 +x:2 +和合 1 +x:1 +儒将 1 +x:1 +尸体堆 1 +x:1 +地方税 1 +x:1 +各方 1 +x:1 +驻有 1 +x:1 +细条条 1 +x:1 +狮子山 1 +x:1 +淄川区 1 +x:1 +洋话 1 +x:1 +无事生非 1 +x:1 +各族 1 +x:1 +花径踅 1 +x:1 +独异 1 +x:1 +蹬技 1 +x:1 +三金奖 1 +x:1 +花街柳巷 1 +x:1 +贷款额 1 +x:1 +说谎 1 +x:1 +丢失 1 +x:1 +必先予之 1 +x:1 +牛 311 +x:311 +忽冷忽热 1 +x:1 +九九归一 1 +x:1 +贵方 1 +x:1 +紧紧张张 1 +x:1 +袋装率 1 +x:1 +前行 1 +x:1 +连爬带滚 1 +x:1 +死对头 1 +x:1 +就便 1 +x:1 +喜不自禁 1 +x:1 +递升 1 +x:1 +处理器 1 +x:1 +督察员 1 +x:1 +东濑户 1 +x:1 +车牌 1 +x:1 +传染性 1 +x:1 +自燃 1 +x:1 +皮里抽肉 1 +x:1 +牛筋 1 +x:1 +分 2058 +x:2058 +畅销书 1 +x:1 +借古讽今 1 +x:1 +批斗会 1 +x:1 +选择者 1 +x:1 +罕有所闻 1 +x:1 +不懈努力 1 +x:1 +平常态 1 +x:1 +和善 1 +x:1 +移民局 1 +x:1 +信义 1 +x:1 +箫 5 +x:5 +片源 1 +x:1 +脑电图 1 +x:1 +文化节 1 +x:1 +首恶 1 +x:1 +终结 1 +x:1 +黑霉 1 +x:1 +伸 72 +x:72 +成语 1 +x:1 +磷酸钙盐 1 +x:1 +混入 1 +x:1 +短视 1 +x:1 +短见 1 +x:1 +湘江 1 +x:1 +为啥 1 +x:1 +司级 1 +x:1 +化合价 1 +x:1 +滤清器 1 +x:1 +信丰 1 +x:1 +黑面 1 +x:1 +为非作歹 1 +x:1 +焚林 1 +x:1 +混养 1 +x:1 +水利学 1 +x:1 +判明 1 +x:1 +鬓毛 1 +x:1 +审委会 1 +x:1 +推波助澜 1 +x:1 +巯 1 +x:1 +包厢 1 +x:1 +敛财 1 +x:1 +电子云 1 +x:1 +官位 1 +x:1 +电子书 1 +x:1 +信仰 1 +x:1 +独幕 1 +x:1 +纠风办 1 +x:1 +映出 1 +x:1 +鸣唱 1 +x:1 +突击性 1 +x:1 +救援 1 +x:1 +河清海晏 1 +x:1 +非礼 1 +x:1 +边界 1 +x:1 +毒酒 1 +x:1 +处理场 1 +x:1 +坎儿井 1 +x:1 +失踪者 1 +x:1 +严实 1 +x:1 +余味 1 +x:1 +众所共识 1 +x:1 +奈卜特山 1 +x:1 +住宅局 1 +x:1 +预审处 1 +x:1 +扶老携幼 1 +x:1 +主战场 1 +x:1 +名校 1 +x:1 +竞争法 1 +x:1 +网具 1 +x:1 +包包 1 +x:1 +深蓝 1 +x:1 +别的 1 +x:1 +幽僻 1 +x:1 +抒情诗 1 +x:1 +裁军会 1 +x:1 +苦苦 1 +x:1 +金哨 1 +x:1 +汗马功劳 1 +x:1 +适者生存 1 +x:1 +家乡话 1 +x:1 +说贴 1 +x:1 +严密 1 +x:1 +网兜 1 +x:1 +趋同 1 +x:1 +知情 1 +x:1 +天网恢恢 1 +x:1 +胡杨树 1 +x:1 +电子业 1 +x:1 +白鳍豚 1 +x:1 +前襟 1 +x:1 +一举四得 1 +x:1 +歇后语 1 +x:1 +快讯 1 +x:1 +二化螟 1 +x:1 +原版 1 +x:1 +澍 11 +x:11 +前身 1 +x:1 +色情 1 +x:1 +自治州 1 +x:1 +谈判室 1 +x:1 +田阳县 1 +x:1 +届届 1 +x:1 +草长莺飞 1 +x:1 +毒雨 1 +x:1 +发大财 1 +x:1 +劳教营 1 +x:1 +处变不惊 1 +x:1 +望子成才 1 +x:1 +三七节 1 +x:1 +一岗双责 1 +x:1 +自省 1 +x:1 +震波 1 +x:1 +下定决心 1 +x:1 +雪灾 1 +x:1 +冻干粉 1 +x:1 +备不住 1 +x:1 +五谷不分 1 +x:1 +长袖者 1 +x:1 +首月 1 +x:1 +命中率 1 +x:1 +广播网 1 +x:1 +金卡 1 +x:1 +脊鳍 1 +x:1 +哥儿 1 +x:1 +十万火急 1 +x:1 +扔 91 +x:91 +环保 1 +x:1 +耐火 1 +x:1 +金卫 1 +x:1 +淡 63 +x:63 +短训班 1 +x:1 +石钟乳 1 +x:1 +城庆 1 +x:1 +衡平法 1 +x:1 +膻气 1 +x:1 +氧化铁 1 +x:1 +娘家人 1 +x:1 +基金 1 +x:1 +澳门元 1 +x:1 +常胜 1 +x:1 +氧化铝 1 +x:1 +毛孩子 1 +x:1 +哈思山 1 +x:1 +敷衍塞责 1 +x:1 +釉料 1 +x:1 +独奏 1 +x:1 +丫鬟 1 +x:1 +是非 1 +x:1 +糖心 1 +x:1 +地应力 1 +x:1 +无牵 1 +x:1 +灶具 1 +x:1 +换肤霜 1 +x:1 +五金 1 +x:1 +天寒地冻 1 +x:1 +演奏厅 1 +x:1 +高频 1 +x:1 +蘧 1 +x:1 +您 586 +x:586 +M 5 +x:5 +契友 1 +x:1 +心跳声 1 +x:1 +宽畅 1 +x:1 +钰 22 +x:22 +疲倦 1 +x:1 +借书证 1 +x:1 +遥想 1 +x:1 +蹉跎岁月 1 +x:1 +为之一新 1 +x:1 +控制数 1 +x:1 +石灰 1 +x:1 +奢望 1 +x:1 +诬谄 1 +x:1 +原物 1 +x:1 +七窍 1 +x:1 +好整以暇 1 +x:1 +轧路机 1 +x:1 +迁移性 1 +x:1 +墓制 1 +x:1 +组织液 1 +x:1 +关口 1 +x:1 +严峻 1 +x:1 +检查单 1 +x:1 +自知 1 +x:1 +耐热 1 +x:1 +金发 1 +x:1 +挥斥方遒 1 +x:1 +丢开 1 +x:1 +自焚 1 +x:1 +包含 1 +x:1 +丢弃 1 +x:1 +鬣狗 1 +x:1 +演奏台 1 +x:1 +琼斯伯勒 1 +x:1 +独夫 1 +x:1 +黄岩市 1 +x:1 +恶意 1 +x:1 +穗状 1 +x:1 +一中全会 1 +x:1 +扳道夫 1 +x:1 +出资者 1 +x:1 +大屠杀 1 +x:1 +曼 2 +x:2 +恶感 1 +x:1 +儒家 1 +x:1 +说话 1 +x:1 +有孔虫 1 +x:1 +航运 1 +x:1 +撑 68 +x:68 +成人装 1 +x:1 +公担 1 +x:1 +非试点 1 +x:1 +颙 3 +x:3 +和县 1 +x:1 +前边 1 +x:1 +摔伤 1 +x:1 +大家庭制 1 +x:1 +样相 1 +x:1 +铝土矿 1 +x:1 +分获 1 +x:1 +说说 1 +x:1 +金刚 1 +x:1 +砂梨 1 +x:1 +前辈 1 +x:1 +视听室 1 +x:1 +锦绣前程 1 +x:1 +病根 1 +x:1 +掉换 1 +x:1 +纯利润 1 +x:1 +唐宋词 1 +x:1 +检验性 1 +x:1 +自白 1 +x:1 +排气管 1 +x:1 +盐水选种 1 +x:1 +深厚感 1 +x:1 +煎药锅 1 +x:1 +跋 6 +x:6 +趋动 1 +x:1 +江平镇 1 +x:1 +检疫 1 +x:1 +别具风采 1 +x:1 +前述 1 +x:1 +益事 1 +x:1 +知悉 1 +x:1 +字谜 1 +x:1 +趋势 1 +x:1 +焦炭 1 +x:1 +冬麦区 1 +x:1 +首映 1 +x:1 +盗车 1 +x:1 +左下 1 +x:1 +车痕 1 +x:1 +着色剂 1 +x:1 +焦炙 1 +x:1 +难受 1 +x:1 +朱比洛队 1 +x:1 +高风亮节 1 +x:1 +难友 1 +x:1 +船闸式 1 +x:1 +非贸易 1 +x:1 +遗愿 1 +x:1 +焦炉 1 +x:1 +穷途末路 1 +x:1 +单杜科村 1 +x:1 +呕心 1 +x:1 +大势所趋 1 +x:1 +噪声 1 +x:1 +复新剂 1 +x:1 +官事 1 +x:1 +可持续化 1 +x:1 +焦灼 1 +x:1 +诬赖 1 +x:1 +鸣哨 1 +x:1 +心花怒放 1 +x:1 +车用 1 +x:1 +纸袋 1 +x:1 +摩崖 1 +x:1 +楔形 1 +x:1 +保量 1 +x:1 +优秀者 1 +x:1 +病案 1 +x:1 +重载化 1 +x:1 +弥久益深 1 +x:1 +砂样 1 +x:1 +有头有尾 1 +x:1 +贪大求全 1 +x:1 +小意思 1 +x:1 +请来 1 +x:1 +厌战 1 +x:1 +结售汇 1 +x:1 +桑塔纳 1 +x:1 +长沙城 1 +x:1 +泾河 1 +x:1 +难却 1 +x:1 +非国大 1 +x:1 +儒学 1 +x:1 +坦缓 1 +x:1 +舟车 1 +x:1 +韵头 1 +x:1 +脊髓 1 +x:1 +迁移 1 +x:1 +老少边穷 1 +x:1 +认知率 1 +x:1 +黑金 1 +x:1 +皮脂腺 1 +x:1 +黄埔港 1 +x:1 +寸心 1 +x:1 +同步网 1 +x:1 +石铁院 1 +x:1 +网坛 1 +x:1 +元旦 1 +x:1 +骑马声 1 +x:1 +网址 1 +x:1 +老妈子 1 +x:1 +柴汽比 1 +x:1 +遥望 1 +x:1 +贵报 1 +x:1 +遗憾 1 +x:1 +美人蕉 1 +x:1 +审议官 1 +x:1 +上下课 1 +x:1 +灶口 1 +x:1 +莫托拉镇 1 +x:1 +宁都县 1 +x:1 +洗砚池头 1 +x:1 +编制法 1 +x:1 +汽缸 1 +x:1 +矽肺 1 +x:1 +灶台 1 +x:1 +电影业 1 +x:1 +自用 1 +x:1 +高压柜 1 +x:1 +奔波 1 +x:1 +色拉 1 +x:1 +捆扎 1 +x:1 +地方级 1 +x:1 +游泳史 1 +x:1 +若虫 1 +x:1 +疲劳 1 +x:1 +混同 1 +x:1 +安眠药 1 +x:1 +间奏曲 1 +x:1 +非粮 1 +x:1 +包围 1 +x:1 +金关 1 +x:1 +金具 1 +x:1 +定下 1 +x:1 +河流镇 1 +x:1 +插班生 1 +x:1 +不经之谈 1 +x:1 +篙 2 +x:2 +犁庭扫闾 1 +x:1 +儒士 1 +x:1 +银鹰 1 +x:1 +匀播耧 1 +x:1 +炕桌儿 1 +x:1 +车盖 1 +x:1 +呼伦贝尔 1 +x:1 +热热闹闹 1 +x:1 +麻风 1 +x:1 +独家 1 +x:1 +金元 1 +x:1 +正定 1 +x:1 +金光 1 +x:1 +菜市场 1 +x:1 +同胞 1 +x:1 +琇 1 +x:1 +控制权 1 +x:1 +杨花 1 +x:1 +附着 1 +x:1 +饮片 1 +x:1 +三无 1 +x:1 +金冠 1 +x:1 +车江窑 1 +x:1 +独子 1 +x:1 +小溪 1 +x:1 +程海乡 1 +x:1 +膀胱 1 +x:1 +名流 1 +x:1 +郎五庄村 1 +x:1 +汾酒 1 +x:1 +树挪死 1 +x:1 +音讯 1 +x:1 +控制板 1 +x:1 +盗案 1 +x:1 +三案 1 +x:1 +录像仪 1 +x:1 +定价 1 +x:1 +伴君 1 +x:1 +锚缆 1 +x:1 +饕餮之徒 1 +x:1 +脂粉气 1 +x:1 +光怪陆离 1 +x:1 +万顷 1 +x:1 +定于 1 +x:1 +气泵 1 +x:1 +信众 1 +x:1 +高压服 1 +x:1 +穷途潦倒 1 +x:1 +之 7366 +x:7366 +嘎登 1 +x:1 +金凤 1 +x:1 +邻接 1 +x:1 +滑雪队 1 +x:1 +招考办 1 +x:1 +磁峰镇 1 +x:1 +处理剂 1 +x:1 +发言人 1 +x:1 +吼三喝四 1 +x:1 +非导体 1 +x:1 +贸发 1 +x:1 +阖家团聚 1 +x:1 +棉花岛 1 +x:1 +右翼 1 +x:1 +游泳区 1 +x:1 +网员 1 +x:1 +风雨灯 1 +x:1 +东花市 1 +x:1 +永兴县 1 +x:1 +兵 246 +x:246 +定人 1 +x:1 +透热疗法 1 +x:1 +品艺录 1 +x:1 +定亲 1 +x:1 +斜对面 1 +x:1 +定位 1 +x:1 +打鼓儿的 1 +x:1 +贵恙 1 +x:1 +志向 1 +x:1 +放款 1 +x:1 +株系 1 +x:1 +结算卡 1 +x:1 +距谏者 1 +x:1 +文字改革 1 +x:1 +旁观者清 1 +x:1 +元朝 1 +x:1 +垛 4 +x:4 +汝城 1 +x:1 +物质性 1 +x:1 +圣克鲁斯 1 +x:1 +处理厂 1 +x:1 +泼陂河镇 1 +x:1 +贵州团 1 +x:1 +瓮城 1 +x:1 +检验所 1 +x:1 +老妈妈 1 +x:1 +败将 1 +x:1 +果子酒 1 +x:1 +溜肩膀 1 +x:1 +引资 1 +x:1 +习气 1 +x:1 +淮阴城 1 +x:1 +零零散散 1 +x:1 +气泡 1 +x:1 +辨识 1 +x:1 +布道台 1 +x:1 +阿德莱德 1 +x:1 +为公 1 +x:1 +闹钟 1 +x:1 +附加税 1 +x:1 +百步穿杨 1 +x:1 +火暴 1 +x:1 +地面战 1 +x:1 +撇嘴 1 +x:1 +短跑 1 +x:1 +泾渭 1 +x:1 +量角器 1 +x:1 +提手 1 +x:1 +腔肠动物 1 +x:1 +乘风破浪 1 +x:1 +辨认 1 +x:1 +苦虑 1 +x:1 +为先 1 +x:1 +承保商 1 +x:1 +土地法 1 +x:1 +留念 1 +x:1 +短路 1 +x:1 +桎梏 1 +x:1 +非国定 1 +x:1 +败局 1 +x:1 +化隆县 1 +x:1 +急病 1 +x:1 +奔涌 1 +x:1 +放歌 1 +x:1 +莘县 1 +x:1 +量子位 1 +x:1 +前贤 1 +x:1 +狐狸尾巴 1 +x:1 +三崎町 1 +x:1 +专机 1 +x:1 +天经地义 1 +x:1 +望尘比步 1 +x:1 +三级跳远 1 +x:1 +作业费 1 +x:1 +控诉书 1 +x:1 +弄潮儿 1 +x:1 +中药味 1 +x:1 +随来随办 1 +x:1 +断桥 1 +x:1 +吱声 1 +x:1 +刺激仪 1 +x:1 +断档 1 +x:1 +蒸馏 1 +x:1 +打头风 1 +x:1 +油亮 1 +x:1 +大田乡 1 +x:1 +内置式 1 +x:1 +十六铺 1 +x:1 +克军 1 +x:1 +名江 1 +x:1 +库缎 1 +x:1 +余物 1 +x:1 +煤气灯 1 +x:1 +抗议者 1 +x:1 +留待 1 +x:1 +难关 1 +x:1 +羊角辫 1 +x:1 +尾部 1 +x:1 +扑克机 1 +x:1 +和兴 1 +x:1 +形容词 1 +x:1 +心脏病 1 +x:1 +海滩 1 +x:1 +反常规 1 +x:1 +人间地狱 1 +x:1 +金城汤池 1 +x:1 +草袋 1 +x:1 +安置费 1 +x:1 +稻 19 +x:19 +泾源 1 +x:1 +大马哈鱼 1 +x:1 +为准 1 +x:1 +马赛曲 1 +x:1 +首播 1 +x:1 +波多黎各 1 +x:1 +状子 1 +x:1 +名气 1 +x:1 +栋梁材 1 +x:1 +难免 1 +x:1 +包场 1 +x:1 +恶战 1 +x:1 +约定俗成 1 +x:1 +驻扎 1 +x:1 +金像 1 +x:1 +风磨 1 +x:1 +各式 1 +x:1 +拉后腿 1 +x:1 +疲沓 1 +x:1 +各异 1 +x:1 +情意 1 +x:1 +名叫 1 +x:1 +暨南 1 +x:1 +名号 1 +x:1 +妖魔 1 +x:1 +抗 169 +x:169 +简便性 1 +x:1 +遗属 1 +x:1 +驴鸣狗吠 1 +x:1 +善策 1 +x:1 +专家级 1 +x:1 +隘路 1 +x:1 +牌证 1 +x:1 +婶母 1 +x:1 +缘簿 1 +x:1 +西北风 1 +x:1 +无起色 1 +x:1 +创刊号 1 +x:1 +手脚 1 +x:1 +棉花所 1 +x:1 +砚石 1 +x:1 +断垄 1 +x:1 +祭扫者 1 +x:1 +萦系 1 +x:1 +高兴劲 1 +x:1 +信用 1 +x:1 +心裁 1 +x:1 +有条有理 1 +x:1 +提成 1 +x:1 +蓝皮书 1 +x:1 +科 140 +x:140 +鲸须 1 +x:1 +人情网 1 +x:1 +山东梆子 1 +x:1 +遗少 1 +x:1 +佛教界 1 +x:1 +交城县 1 +x:1 +声望 1 +x:1 +这般 1 +x:1 +南美洲 1 +x:1 +朵儿 1 +x:1 +难吃 1 +x:1 +高温假 1 +x:1 +破财 1 +x:1 +惫 1 +x:1 +独断 1 +x:1 +丢掉 1 +x:1 +数落 1 +x:1 +近地点 1 +x:1 +第四纪 1 +x:1 +手腕 1 +x:1 +总指挥部 1 +x:1 +商场 1 +x:1 +八连冠 1 +x:1 +遗尸 1 +x:1 +队会 1 +x:1 +覆辙 1 +x:1 +养护 1 +x:1 +首富 1 +x:1 +歌王 1 +x:1 +分配型 1 +x:1 +意味着 1 +x:1 +善跑 1 +x:1 +肇东市 1 +x:1 +模塑 1 +x:1 +威胁性 1 +x:1 +挂钟 1 +x:1 +正经 1 +x:1 +尾闾 1 +x:1 +岁岁枯荣 1 +x:1 +浅绿 1 +x:1 +名单 1 +x:1 +发报声 1 +x:1 +擀面杖 1 +x:1 +正统 1 +x:1 +私营业者 1 +x:1 +禽流感 1 +x:1 +曲曲折折 1 +x:1 +胀 4 +x:4 +游园会 1 +x:1 +许可法 1 +x:1 +严惩 1 +x:1 +名匠 1 +x:1 +虚荣心 1 +x:1 +心血 1 +x:1 +怀胎 1 +x:1 +放哨 1 +x:1 +岳阳县 1 +x:1 +寒 37 +x:37 +正线 1 +x:1 +雪盲 1 +x:1 +鸡皮疙瘩 1 +x:1 +各显其能 1 +x:1 +闭塞 1 +x:1 +优惠性 1 +x:1 +观赏者 1 +x:1 +名医 1 +x:1 +举办地 1 +x:1 +手臂 1 +x:1 +中童 1 +x:1 +边上 1 +x:1 +单名数 1 +x:1 +油井 1 +x:1 +太空衣 1 +x:1 +抗生素 1 +x:1 +入库率 1 +x:1 +突现 1 +x:1 +定点 1 +x:1 +荆棘载途 1 +x:1 +民宗委 1 +x:1 +担心桥 1 +x:1 +摹本 1 +x:1 +青鱼 1 +x:1 +耳科 1 +x:1 +教育长 1 +x:1 +各市 1 +x:1 +读完 1 +x:1 +熠熠闪闪 1 +x:1 +场房 1 +x:1 +一超 1 +x:1 +青睐有加 1 +x:1 +集中区 1 +x:1 +南关区 1 +x:1 +伊豆 1 +x:1 +门房 1 +x:1 +一窍不通 1 +x:1 +儒林 1 +x:1 +炙手可热 1 +x:1 +永远 1 +x:1 +对虾 1 +x:1 +检验局 1 +x:1 +丧钟 1 +x:1 +狼烟 1 +x:1 +元大 1 +x:1 +贵平 1 +x:1 +鳔胶 1 +x:1 +脑电波 1 +x:1 +邻居 1 +x:1 +色差 1 +x:1 +锤子 1 +x:1 +粘粘糊糊 1 +x:1 +侦破 1 +x:1 +改好率 1 +x:1 +退稿费 1 +x:1 +广告语 1 +x:1 +人人皆知 1 +x:1 +物证 1 +x:1 +绕 85 +x:85 +练者 1 +x:1 +复辅音 1 +x:1 +草野 1 +x:1 +自力霉素 1 +x:1 +米铺 1 +x:1 +牢 32 +x:32 +短衣 1 +x:1 +东关村 1 +x:1 +揭短 1 +x:1 +诀别 1 +x:1 +广告词 1 +x:1 +场所 1 +x:1 +伤湿膏 1 +x:1 +排碱渠 1 +x:1 +煤矿局 1 +x:1 +流窜 1 +x:1 +正编 1 +x:1 +老 1637 +x:1637 +虞城县 1 +x:1 +名剧 1 +x:1 +知识者 1 +x:1 +前行者 1 +x:1 +毛家湾 1 +x:1 +儋 1 +x:1 +名特优稀 1 +x:1 +爱国会 1 +x:1 +细枝末节 1 +x:1 +羔 2 +x:2 +儒术 1 +x:1 +提拨 1 +x:1 +伪作 1 +x:1 +上当者 1 +x:1 +捐资人 1 +x:1 +军容镜 1 +x:1 +双重 1 +x:1 +毋庸讳言 1 +x:1 +城际 1 +x:1 +液压机 1 +x:1 +丢手 1 +x:1 +购物点 1 +x:1 +涪城 1 +x:1 +兼听博采 1 +x:1 +风神 1 +x:1 +手肘 1 +x:1 +总理 1 +x:1 +衣钩 1 +x:1 +蓄电池 1 +x:1 +名利 1 +x:1 +核政策 1 +x:1 +逆运算 1 +x:1 +米家沟村 1 +x:1 +贪大求洋 1 +x:1 +阿尔卑斯 1 +x:1 +咚咚 1 +x:1 +雅间 1 +x:1 +城防 1 +x:1 +名刹 1 +x:1 +厨刀 1 +x:1 +佟 35 +x:35 +铁甲舰 1 +x:1 +草酸 1 +x:1 +名分 1 +x:1 +提拔 1 +x:1 +早产 1 +x:1 +友协 1 +x:1 +中庸之道 1 +x:1 +潞城市 1 +x:1 +恶少 1 +x:1 +名列 1 +x:1 +败招 1 +x:1 +催人泪下 1 +x:1 +劫难 1 +x:1 +城门 1 +x:1 +质轻 1 +x:1 +溧阳 1 +x:1 +代扣代缴 1 +x:1 +船山乡 1 +x:1 +穷困 1 +x:1 +一汽人 1 +x:1 +乳制品 1 +x:1 +录像片 1 +x:1 +祝词 1 +x:1 +技术装备 1 +x:1 +沟 66 +x:66 +怒射 1 +x:1 +恶心 1 +x:1 +第四系 1 +x:1 +庆大霉素 1 +x:1 +伊通社 1 +x:1 +维生素 1 +x:1 +耕地者 1 +x:1 +金洞 1 +x:1 +肉票 1 +x:1 +泡桐花 1 +x:1 +竭尽所能 1 +x:1 +雪上 1 +x:1 +祝语 1 +x:1 +徐福镇 1 +x:1 +寒风 1 +x:1 +运输网 1 +x:1 +礼炮声 1 +x:1 +西二里 1 +x:1 +灵机一动 1 +x:1 +土地名 1 +x:1 +撰稿者 1 +x:1 +电影片 1 +x:1 +寒颤 1 +x:1 +海蛎子 1 +x:1 +蛙人 1 +x:1 +金浦 1 +x:1 +观赏节 1 +x:1 +讳言 1 +x:1 +足临泣穴 1 +x:1 +左传 1 +x:1 +粽粑 1 +x:1 +阴阳怪气 1 +x:1 +飧 1 +x:1 +名册 1 +x:1 +醴陵 1 +x:1 +内幕 1 +x:1 +天然气 1 +x:1 +色度 1 +x:1 +组织化 1 +x:1 +世世代代 1 +x:1 +突然 1 +x:1 +家产制 1 +x:1 +两鬓 1 +x:1 +严打 1 +x:1 +由此而言 1 +x:1 +君主国 1 +x:1 +贵州 1 +x:1 +雪人 1 +x:1 +狼獾 1 +x:1 +水箱 1 +x:1 +集贸市场 1 +x:1 +网格 1 +x:1 +菜系 1 +x:1 +网校 1 +x:1 +先入为主 1 +x:1 +信石 1 +x:1 +疫苗 1 +x:1 +丛刊 1 +x:1 +砂土 1 +x:1 +名典 1 +x:1 +锤声 1 +x:1 +辞 42 +x:42 +烟幕弹 1 +x:1 +东风湖 1 +x:1 +丛刻 1 +x:1 +难民 1 +x:1 +违者必究 1 +x:1 +焦作 1 +x:1 +城镇 1 +x:1 +戏马台 1 +x:1 +和气 1 +x:1 +网栅 1 +x:1 +饶恕 1 +x:1 +木袜楦 1 +x:1 +习军 1 +x:1 +解放军报 1 +x:1 +蚜虫 1 +x:1 +希思罗 1 +x:1 +人云亦云 1 +x:1 +泾县 1 +x:1 +大红大紫 1 +x:1 +宫廷政变 1 +x:1 +老年组 1 +x:1 +面貌一新 1 +x:1 +七言诗 1 +x:1 +各州 1 +x:1 +饮鸩止渴 1 +x:1 +电子眼 1 +x:1 +深闭固拒 1 +x:1 +洁身自律 1 +x:1 +名儿 1 +x:1 +兑汇处 1 +x:1 +核发证书 1 +x:1 +观赏船 1 +x:1 +时起时落 1 +x:1 +沉疴 1 +x:1 +肉禽 1 +x:1 +玛电 1 +x:1 +打印台 1 +x:1 +青龙 1 +x:1 +独木 1 +x:1 +笨家伙 1 +x:1 +色带 1 +x:1 +官瘾 1 +x:1 +囫囵 1 +x:1 +全兴队 1 +x:1 +米面 1 +x:1 +得寸进尺 1 +x:1 +隐忍 1 +x:1 +砚田 1 +x:1 +金淌 1 +x:1 +追击战 1 +x:1 +金水 1 +x:1 +油煎火燎 1 +x:1 +采药人 1 +x:1 +左眼 1 +x:1 +秤盘子 1 +x:1 +放在 1 +x:1 +研究界 1 +x:1 +伯塞达市 1 +x:1 +词作者 1 +x:1 +恳求 1 +x:1 +修筑 1 +x:1 +高温区 1 +x:1 +蜀中 1 +x:1 +金龙卡 1 +x:1 +狼狗 1 +x:1 +硬质合金 1 +x:1 +心计 1 +x:1 +水舀子 1 +x:1 +遗影 1 +x:1 +友军 1 +x:1 +解诗者 1 +x:1 +狼狈 1 +x:1 +研究生 1 +x:1 +顽疾 1 +x:1 +遗弃 1 +x:1 +俄国化 1 +x:1 +放映厅 1 +x:1 +视唱练耳 1 +x:1 +焦人 1 +x:1 +铁三角 1 +x:1 +口头禅 1 +x:1 +渔产品 1 +x:1 +金汤 1 +x:1 +风箱 1 +x:1 +冷门 1 +x:1 +见多识广 1 +x:1 +交流会 1 +x:1 +风沙区 1 +x:1 +权力 1 +x:1 +赞同 1 +x:1 +摩梭人 1 +x:1 +毛家沟 1 +x:1 +青鸟 1 +x:1 +怀药 1 +x:1 +绒绣 1 +x:1 +哭声 1 +x:1 +针油剂 1 +x:1 +群情激奋 1 +x:1 +鞭笞 1 +x:1 +静海县 1 +x:1 +永曲乡 1 +x:1 +笨手笨脚 1 +x:1 +妖风 1 +x:1 +遗志 1 +x:1 +坡坡坎坎 1 +x:1 +元宝 1 +x:1 +某部 1 +x:1 +装裱 1 +x:1 +遗忘 1 +x:1 +中间 1 +x:1 +中户 1 +x:1 +金沙 1 +x:1 +茫 2 +x:2 +友谊曲 1 +x:1 +暮 10 +x:10 +杉木 1 +x:1 +一动不动 1 +x:1 +风筝 1 +x:1 +两高 1 +x:1 +联系卡 1 +x:1 +自主经营 1 +x:1 +色彩 1 +x:1 +元宵 1 +x:1 +电解 1 +x:1 +心领神会 1 +x:1 +故智 1 +x:1 +叛乱 1 +x:1 +姘居 1 +x:1 +桑园乡 1 +x:1 +邻座 1 +x:1 +运输线 1 +x:1 +勺状软骨 1 +x:1 +幽森 1 +x:1 +强化食品 1 +x:1 +晋察冀区 1 +x:1 +甘休 1 +x:1 +抢手货 1 +x:1 +车票 1 +x:1 +同情者 1 +x:1 +应有尽有 1 +x:1 +独具匠心 1 +x:1 +儒教 1 +x:1 +柘城县 1 +x:1 +难测 1 +x:1 +倾盆 1 +x:1 +赞道 1 +x:1 +修箱 1 +x:1 +高尔夫 1 +x:1 +膻味 1 +x:1 +放债 1 +x:1 +题跋 1 +x:1 +艺术美 1 +x:1 +肠阻塞 1 +x:1 +贵子 1 +x:1 +牌迷 1 +x:1 +哈萨克 1 +x:1 +副本费 1 +x:1 +自治旗 1 +x:1 +自传 1 +x:1 +马鲛鱼 1 +x:1 +猎潜艇 1 +x:1 +自治日 1 +x:1 +名城 1 +x:1 +起笔 1 +x:1 +天门市 1 +x:1 +乙醛 1 +x:1 +旁 164 +x:164 +激动人心 1 +x:1 +二花脸 1 +x:1 +牙齿 1 +x:1 +匮乏 1 +x:1 +定理 1 +x:1 +侧蚀力 1 +x:1 +沁阳市 1 +x:1 +蹋腰 1 +x:1 +鲸鱼 1 +x:1 +槐秋 1 +x:1 +狼疮 1 +x:1 +移动网 1 +x:1 +锁定 1 +x:1 +荒野 1 +x:1 +谎价 1 +x:1 +辆数 1 +x:1 +诱惑性 1 +x:1 +缩聚 1 +x:1 +寂寞 1 +x:1 +偿付 1 +x:1 +主钢缆 1 +x:1 +判处 1 +x:1 +海涵 1 +x:1 +自体 1 +x:1 +百花苑 1 +x:1 +新街口 1 +x:1 +拙稿 1 +x:1 +系 401 +x:401 +亲合性 1 +x:1 +放假 1 +x:1 +升堂入室 1 +x:1 +鲸鲨 1 +x:1 +自便 1 +x:1 +霍 76 +x:76 +金殿 1 +x:1 +事关重大 1 +x:1 +姑息疗法 1 +x:1 +自侦 1 +x:1 +边疆 1 +x:1 +面不改色 1 +x:1 +单式编制 1 +x:1 +状态 1 +x:1 +灰山鹑 1 +x:1 +九十月份 1 +x:1 +墨 173 +x:173 +发酸 1 +x:1 +承受者 1 +x:1 +特重型 1 +x:1 +运输科 1 +x:1 +非同儿戏 1 +x:1 +两河口 1 +x:1 +为期不远 1 +x:1 +机枪手 1 +x:1 +贵定 1 +x:1 +米酒 1 +x:1 +瓦片子 1 +x:1 +除此外 1 +x:1 +坯子 1 +x:1 +双钩 1 +x:1 +王坡村 1 +x:1 +肉羊 1 +x:1 +化公为私 1 +x:1 +家给人足 1 +x:1 +下片 1 +x:1 +自信 1 +x:1 +艳服 1 +x:1 +自保 1 +x:1 +贵宾 1 +x:1 +猪肝脏 1 +x:1 +霄壤 1 +x:1 +杭 30 +x:30 +波尔多城 1 +x:1 +遗墨 1 +x:1 +挪威 1 +x:1 +元明清 1 +x:1 +贵客 1 +x:1 +均等化 1 +x:1 +狭路相遇 1 +x:1 +猪爪 1 +x:1 +湿疹 1 +x:1 +三明治 1 +x:1 +名园 1 +x:1 +义和庄 1 +x:1 +幽渺 1 +x:1 +岑 6 +x:6 +历久弥新 1 +x:1 +自个 1 +x:1 +内外联 1 +x:1 +张桥村 1 +x:1 +正视图 1 +x:1 +立此存照 1 +x:1 +赞助 1 +x:1 +坚如磐石 1 +x:1 +返青 1 +x:1 +搞清 1 +x:1 +广告辞 1 +x:1 +拉帮结伙 1 +x:1 +民航史 1 +x:1 +军大衣 1 +x:1 +场景 1 +x:1 +担 107 +x:107 +电影界 1 +x:1 +豆 21 +x:21 +为此 1 +x:1 +肯塔基州 1 +x:1 +劫机者 1 +x:1 +晤面 1 +x:1 +为止 1 +x:1 +北岚村 1 +x:1 +落败 1 +x:1 +创见 1 +x:1 +调储 1 +x:1 +启蒙 1 +x:1 +严整 1 +x:1 +乒乓球赛 1 +x:1 +自习 1 +x:1 +赵家井村 1 +x:1 +进货簿 1 +x:1 +拙笨 1 +x:1 +心路 1 +x:1 +千载一时 1 +x:1 +狭路相逢 1 +x:1 +谬论 1 +x:1 +自乐 1 +x:1 +喉头 1 +x:1 +王庄村 1 +x:1 +草门 1 +x:1 +遗失 1 +x:1 +滞纳金 1 +x:1 +包涵 1 +x:1 +酸 21 +x:21 +一团乱麻 1 +x:1 +巴结 1 +x:1 +递水 1 +x:1 +会聚透镜 1 +x:1 +难欺 1 +x:1 +粗茶淡饭 1 +x:1 +信件 1 +x:1 +风痛停 1 +x:1 +双门 1 +x:1 +落后性 1 +x:1 +脐部 1 +x:1 +健齿 1 +x:1 +宁肯 1 +x:1 +利利索索 1 +x:1 +渝 49 +x:49 +官佐 1 +x:1 +麦角 1 +x:1 +雨伞 1 +x:1 +挂线疗法 1 +x:1 +全家福 1 +x:1 +滑车神经 1 +x:1 +届时 1 +x:1 +微量 1 +x:1 +祸不单行 1 +x:1 +研究班 1 +x:1 +剧中人 1 +x:1 +自食其力 1 +x:1 +臣子 1 +x:1 +帽 9 +x:9 +黄岩村 1 +x:1 +放出 1 +x:1 +火急火燎 1 +x:1 +近视 1 +x:1 +探索期 1 +x:1 +矿山 1 +x:1 +农民党 1 +x:1 +首府 1 +x:1 +严守 1 +x:1 +避雷线 1 +x:1 +首度 1 +x:1 +赞美诗 1 +x:1 +饶有 1 +x:1 +和歌 1 +x:1 +热锭冷砸 1 +x:1 +椰子树 1 +x:1 +阿鲁沙 1 +x:1 +自从 1 +x:1 +来之不易 1 +x:1 +刊首语 1 +x:1 +凸 9 +x:9 +非竞赛类 1 +x:1 +双阳区 1 +x:1 +啁啾 1 +x:1 +苫布 1 +x:1 +南充市 1 +x:1 +正确 1 +x:1 +放到 1 +x:1 +高射炮 1 +x:1 +各处 1 +x:1 +露露脸 1 +x:1 +好路率 1 +x:1 +迷航 1 +x:1 +元帅 1 +x:1 +拳拳之心 1 +x:1 +代际 1 +x:1 +仙桃市 1 +x:1 +心身 1 +x:1 +司厅级 1 +x:1 +高锰酸盐 1 +x:1 +卫队长 1 +x:1 +联系国 1 +x:1 +桑皮纸 1 +x:1 +无理方程 1 +x:1 +摄影赛 1 +x:1 +作鸟兽散 1 +x:1 +臃肿 1 +x:1 +敬老车 1 +x:1 +后来居上 1 +x:1 +博采众长 1 +x:1 +风纪 1 +x:1 +屈吴山 1 +x:1 +车价 1 +x:1 +吴旗 1 +x:1 +君主制 1 +x:1 +全员 1 +x:1 +干红酒 1 +x:1 +匀齐 1 +x:1 +双阳 1 +x:1 +中侨 1 +x:1 +贵处 1 +x:1 +铺砌 1 +x:1 +斗车 1 +x:1 +输油管 1 +x:1 +法文版 1 +x:1 +成年累月 1 +x:1 +南辕北辙 1 +x:1 +桠杈 1 +x:1 +和棋 1 +x:1 +图尔卡纳 1 +x:1 +红12师 1 +x:1 +侦缉 1 +x:1 +搏动声 1 +x:1 +拳拳之忱 1 +x:1 +元年 1 +x:1 +议案 1 +x:1 +奔命 1 +x:1 +严令禁止 1 +x:1 +编制员 1 +x:1 +桠枫 1 +x:1 +车主 1 +x:1 +拜会 1 +x:1 +贵姓 1 +x:1 +自治权 1 +x:1 +总统 1 +x:1 +开司米 1 +x:1 +捞砂 1 +x:1 +话费单 1 +x:1 +附体 1 +x:1 +洗衣机厂 1 +x:1 +地球日 1 +x:1 +坡改梯 1 +x:1 +杜门谢客 1 +x:1 +鸣啭 1 +x:1 +宽体 1 +x:1 +车业 1 +x:1 +混沌 1 +x:1 +升降级 1 +x:1 +金榜 1 +x:1 +口服液 1 +x:1 +救命网 1 +x:1 +考研热 1 +x:1 +车上 1 +x:1 +质证 1 +x:1 +剪辑台 1 +x:1 +双城县 1 +x:1 +检验室 1 +x:1 +广西省 1 +x:1 +邻家 1 +x:1 +拜佛 1 +x:1 +子力 1 +x:1 +闭幕 1 +x:1 +前卫队 1 +x:1 +万国邮联 1 +x:1 +附会 1 +x:1 +贵妇 1 +x:1 +贵妃 1 +x:1 +折扣方 1 +x:1 +棋王战 1 +x:1 +渡过 1 +x:1 +断气 1 +x:1 +难言之处 1 +x:1 +难案 1 +x:1 +判定 1 +x:1 +三台山乡 1 +x:1 +判官 1 +x:1 +王家堡村 1 +x:1 +伯明翰 1 +x:1 +奸杀 1 +x:1 +霍山县 1 +x:1 +官爵 1 +x:1 +各奔前程 1 +x:1 +赎罪 1 +x:1 +连史纸 1 +x:1 +双面 1 +x:1 +城郭 1 +x:1 +遗孀 1 +x:1 +信物 1 +x:1 +诗风 1 +x:1 +迷茫 1 +x:1 +费用率 1 +x:1 +阿亚古兹 1 +x:1 +草鞋 1 +x:1 +数不着 1 +x:1 +定睛 1 +x:1 +青马 1 +x:1 +母权制 1 +x:1 +马赛市 1 +x:1 +遗存 1 +x:1 +肉类 1 +x:1 +遗孤 1 +x:1 +名品 1 +x:1 +友善 1 +x:1 +创设 1 +x:1 +举报箱 1 +x:1 +金栀 1 +x:1 +宽仁 1 +x:1 +附件 1 +x:1 +天平秤 1 +x:1 +届期 1 +x:1 +凭证 1 +x:1 +农用品 1 +x:1 +油然而生 1 +x:1 +五谷丰登 1 +x:1 +有所 1 +x:1 +玉茭皮 1 +x:1 +金桥 1 +x:1 +创评 1 +x:1 +反证法 1 +x:1 +做作 1 +x:1 +慧 19 +x:19 +修缮 1 +x:1 +合格者 1 +x:1 +苦 285 +x:285 +记录卡 1 +x:1 +中国话 1 +x:1 +轰 14 +x:14 +心迹 1 +x:1 +为政者 1 +x:1 +届末 1 +x:1 +城邑 1 +x:1 +楹联 1 +x:1 +首尾 1 +x:1 +所作所为 1 +x:1 +色子 1 +x:1 +矿岩 1 +x:1 +科考队 1 +x:1 +恫吓 1 +x:1 +基隆 1 +x:1 +失和 1 +x:1 +双音 1 +x:1 +舞剧团 1 +x:1 +隆誉 1 +x:1 +广告费 1 +x:1 +贺卡式 1 +x:1 +钢 99 +x:99 +电子版 1 +x:1 +尖轨 1 +x:1 +函数线 1 +x:1 +梁山县 1 +x:1 +正秀 1 +x:1 +趋向 1 +x:1 +起端 1 +x:1 +成见 1 +x:1 +彰武县 1 +x:1 +名树 1 +x:1 +鼻 17 +x:17 +相依相偎 1 +x:1 +首岁 1 +x:1 +附上 1 +x:1 +网海 1 +x:1 +不厌其详 1 +x:1 +蓬荜生辉 1 +x:1 +幸福一村 1 +x:1 +无处不在 1 +x:1 +宽严 1 +x:1 +精密度 1 +x:1 +单峰驼 1 +x:1 +校景 1 +x:1 +不绝于耳 1 +x:1 +节节胜利 1 +x:1 +混淆 1 +x:1 +附中 1 +x:1 +心软 1 +x:1 +尧 14 +x:14 +名吃 1 +x:1 +吵吵嚷嚷 1 +x:1 +太空车 1 +x:1 +伶仃洋 1 +x:1 +怪态 1 +x:1 +性感 1 +x:1 +不可抗力 1 +x:1 +附丽 1 +x:1 +遗害 1 +x:1 +乒乓球迷 1 +x:1 +惨杀 1 +x:1 +环行线 1 +x:1 +满洲里 1 +x:1 +车位 1 +x:1 +岢岚 1 +x:1 +素不相识 1 +x:1 +扫描器 1 +x:1 +真菌学 1 +x:1 +心肌 1 +x:1 +内外资 1 +x:1 +场次 1 +x:1 +肌骨 1 +x:1 +严格 1 +x:1 +卡亚尼 1 +x:1 +心肝 1 +x:1 +韭菜 1 +x:1 +处世 1 +x:1 +胡椒粉 1 +x:1 +宋杖子镇 1 +x:1 +名寺 1 +x:1 +广告节 1 +x:1 +邪教 1 +x:1 +鼓楼 1 +x:1 +金朝 1 +x:1 +落聘 1 +x:1 +制定者 1 +x:1 +七歪八扭 1 +x:1 +和暖 1 +x:1 +久负盛名 1 +x:1 +诗韵 1 +x:1 +资山镇 1 +x:1 +组织奖 1 +x:1 +体无完肤 1 +x:1 +所见所闻 1 +x:1 +高精尖 1 +x:1 +萌生 1 +x:1 +放射 1 +x:1 +同情话 1 +x:1 +各地 1 +x:1 +混战 1 +x:1 +龃龉 1 +x:1 +日本帝国 1 +x:1 +草食 1 +x:1 +七七 1 +x:1 +明石市 1 +x:1 +七一 1 +x:1 +心胆 1 +x:1 +垄坪乡 1 +x:1 +名家 1 +x:1 +马赛克 1 +x:1 +和田市 1 +x:1 +吞蚀 1 +x:1 +金杨 1 +x:1 +名宿 1 +x:1 +蛟 1 +x:1 +敞 4 +x:4 +名宅 1 +x:1 +比例规 1 +x:1 +七中 1 +x:1 +怀表 1 +x:1 +哭叫 1 +x:1 +内外贸 1 +x:1 +排行榜 1 +x:1 +肉猪 1 +x:1 +时滞 1 +x:1 +连心箱 1 +x:1 +官桥村 1 +x:1 +处于 1 +x:1 +檑石 1 +x:1 +名学 1 +x:1 +格罗宁根 1 +x:1 +杏花村 1 +x:1 +风灯 1 +x:1 +食道 1 +x:1 +咫尺之遥 1 +x:1 +瞧瞧 1 +x:1 +首发 1 +x:1 +烈烈 1 +x:1 +摘除 1 +x:1 +风灾 1 +x:1 +红白事 1 +x:1 +轻债国 1 +x:1 +吕祖庙 1 +x:1 +购票单 1 +x:1 +拟议 1 +x:1 +甩 48 +x:48 +恩赐 1 +x:1 +洛阳城 1 +x:1 +异质性 1 +x:1 +含苞 1 +x:1 +名字 1 +x:1 +处人 1 +x:1 +和易 1 +x:1 +离人 1 +x:1 +巴伐利亚 1 +x:1 +铺盖 1 +x:1 +正盐 1 +x:1 +伪君子 1 +x:1 +抱成一团 1 +x:1 +喉咙 1 +x:1 +吴起镇 1 +x:1 +无敌意 1 +x:1 +惊诧不已 1 +x:1 +网扣 1 +x:1 +广告色 1 +x:1 +影评 1 +x:1 +土地庙 1 +x:1 +难办 1 +x:1 +唯条件论 1 +x:1 +奢华 1 +x:1 +处以 1 +x:1 +以点概全 1 +x:1 +惨案 1 +x:1 +钱财 1 +x:1 +修炼 1 +x:1 +左右 1 +x:1 +客流量 1 +x:1 +诗集 1 +x:1 +肉牛 1 +x:1 +线速度 1 +x:1 +宣教科 1 +x:1 +食量 1 +x:1 +定神 1 +x:1 +趸船 1 +x:1 +电子系 1 +x:1 +听证会 1 +x:1 +衣鱼 1 +x:1 +遗恨 1 +x:1 +殊异于世 1 +x:1 +匀速 1 +x:1 +肉片 1 +x:1 +忽地 1 +x:1 +雷打不动 1 +x:1 +抢行 1 +x:1 +砂岩 1 +x:1 +金星 1 +x:1 +巴毛 1 +x:1 +克朗 1 +x:1 +天然村 1 +x:1 +神脑 1 +x:1 +离京 1 +x:1 +源于 1 +x:1 +金昌 1 +x:1 +检验员 1 +x:1 +发发 1 +x:1 +蜀籁 1 +x:1 +耳熟 1 +x:1 +炼乳 1 +x:1 +处刑 1 +x:1 +杏花村镇 1 +x:1 +手表 1 +x:1 +扪心自省 1 +x:1 +酥麻 1 +x:1 +痴醉 1 +x:1 +货机 1 +x:1 +首创 1 +x:1 +电影票 1 +x:1 +七伯 1 +x:1 +农民工 1 +x:1 +烈焰 1 +x:1 +滥竽充数 1 +x:1 +落脚 1 +x:1 +两通 1 +x:1 +集资 1 +x:1 +泸西 1 +x:1 +玉米秸 1 +x:1 +心脏 1 +x:1 +统一战线 1 +x:1 +金印 1 +x:1 +姨父 1 +x:1 +为副 1 +x:1 +后备金 1 +x:1 +冷链 1 +x:1 +洋货 1 +x:1 +心脑 1 +x:1 +贵国 1 +x:1 +粗放经营 1 +x:1 +青铜 1 +x:1 +非统 1 +x:1 +筋斗 1 +x:1 +青铁 1 +x:1 +贺家山 1 +x:1 +本质论 1 +x:1 +性解放 1 +x:1 +耿耿 1 +x:1 +斗胆 1 +x:1 +金曲 1 +x:1 +迷路 1 +x:1 +军令 1 +x:1 +金属带 1 +x:1 +比例表 1 +x:1 +蔡锷路 1 +x:1 +藏头露尾 1 +x:1 +颈淋巴 1 +x:1 +木地板 1 +x:1 +幻 11 +x:11 +首功 1 +x:1 +督察权 1 +x:1 +原油 1 +x:1 +城调队 1 +x:1 +恶名 1 +x:1 +一虎势单 1 +x:1 +心腹 1 +x:1 +天然林 1 +x:1 +闭关 1 +x:1 +元凶 1 +x:1 +油然 1 +x:1 +等而下之 1 +x:1 +吴榜 1 +x:1 +土地局 1 +x:1 +捷克队 1 +x:1 +首先 1 +x:1 +起程 1 +x:1 +显露 1 +x:1 +淳安县 1 +x:1 +军休 1 +x:1 +靴子 1 +x:1 +官绅 1 +x:1 +护卫艇 1 +x:1 +翌年 1 +x:1 +度量衡 1 +x:1 +蚊塘镇 1 +x:1 +满山红 1 +x:1 +财政科 1 +x:1 +包括 1 +x:1 +妙想迁得 1 +x:1 +青青 1 +x:1 +令箭荷花 1 +x:1 +瘦西湖 1 +x:1 +洋补品 1 +x:1 +辆次 1 +x:1 +铁杆儿 1 +x:1 +令人担忧 1 +x:1 +人情电 1 +x:1 +黑帮 1 +x:1 +责任牌 1 +x:1 +控制台 1 +x:1 +毛玻璃 1 +x:1 +恍若 1 +x:1 +背山起楼 1 +x:1 +砂心 1 +x:1 +包抄 1 +x:1 +黑道 1 +x:1 +银杏王 1 +x:1 +北川江 1 +x:1 +鸭嘴笔 1 +x:1 +产蛋鸡 1 +x:1 +习好 1 +x:1 +延安城 1 +x:1 +精密化 1 +x:1 +旁敲侧击 1 +x:1 +车江乡 1 +x:1 +护卫舰 1 +x:1 +掏心战 1 +x:1 +郫县 1 +x:1 +庸才 1 +x:1 +科威特 1 +x:1 +正理 1 +x:1 +洛子峰 1 +x:1 +辍笔 1 +x:1 +定稿 1 +x:1 +巷道 1 +x:1 +老太婆 1 +x:1 +遗嘱 1 +x:1 +吵嘴 1 +x:1 +实职 1 +x:1 +达观 1 +x:1 +官纱 1 +x:1 +夜空 1 +x:1 +夔 1 +x:1 +风物 1 +x:1 +包扎 1 +x:1 +象牙质 1 +x:1 +决定 1 +x:1 +民航局 1 +x:1 +中间体 1 +x:1 +个旧市 1 +x:1 +破落户 1 +x:1 +富含氢 1 +x:1 +说真的 1 +x:1 +西八里乡 1 +x:1 +手记 1 +x:1 +民国初年 1 +x:1 +饱经风霜 1 +x:1 +苏打 1 +x:1 +病字旁儿 1 +x:1 +学富五车 1 +x:1 +细菌 1 +x:1 +卡拉克泰 1 +x:1 +扩编 1 +x:1 +力辞 1 +x:1 +犯嘀咕 1 +x:1 +不可估量 1 +x:1 +太空船 1 +x:1 +搜查部 1 +x:1 +订货人 1 +x:1 +包扶 1 +x:1 +新河县 1 +x:1 +运量 1 +x:1 +逃亡者 1 +x:1 +元勋 1 +x:1 +责任状 1 +x:1 +落花 1 +x:1 +氧化铜 1 +x:1 +卓有成效 1 +x:1 +手语 1 +x:1 +高压包 1 +x:1 +电影站 1 +x:1 +为之一变 1 +x:1 +收割机 1 +x:1 +四季豆 1 +x:1 +组织家 1 +x:1 +影视 1 +x:1 +涡轮 1 +x:1 +干粮 1 +x:1 +离愁别绪 1 +x:1 +独断独行 1 +x:1 +板板整整 1 +x:1 +逃之夭夭 1 +x:1 +愚昧 1 +x:1 +麦蚜 1 +x:1 +草驴 1 +x:1 +高压区 1 +x:1 +包房 1 +x:1 +把门 1 +x:1 +贫瘠化 1 +x:1 +包户 1 +x:1 +金华 1 +x:1 +初访者 1 +x:1 +司仪 1 +x:1 +记录式 1 +x:1 +戆 1 +x:1 +渡航 1 +x:1 +清水县 1 +x:1 +司令 1 +x:1 +秋分点 1 +x:1 +为政 1 +x:1 +猛醒 1 +x:1 +名声 1 +x:1 +辽代 1 +x:1 +渡船 1 +x:1 +订货会 1 +x:1 +幽怨 1 +x:1 +互助县 1 +x:1 +之一 1 +x:1 +数轴 1 +x:1 +落荒 1 +x:1 +康安路 1 +x:1 +鳝鱼 1 +x:1 +阿拉善湾 1 +x:1 +釉制 1 +x:1 +碘胺 1 +x:1 +立等 1 +x:1 +奉节县 1 +x:1 +放开 1 +x:1 +缸 33 +x:33 +放弃 1 +x:1 +棱角 1 +x:1 +新光报 1 +x:1 +瓢形 1 +x:1 +青阳 1 +x:1 +自由邦 1 +x:1 +管辖 1 +x:1 +最佳奖 1 +x:1 +百花路 1 +x:1 +严正 1 +x:1 +棉纱锭 1 +x:1 +控制力 1 +x:1 +为数 1 +x:1 +正电 1 +x:1 +具体而微 1 +x:1 +首倡 1 +x:1 +惨毒 1 +x:1 +放映室 1 +x:1 +狼窝 1 +x:1 +步犁 1 +x:1 +克敌 1 +x:1 +关心 1 +x:1 +摄影者 1 +x:1 +饶平 1 +x:1 +耳环 1 +x:1 +突破 1 +x:1 +预报网 1 +x:1 +焦煤 1 +x:1 +梭子蟹 1 +x:1 +总起来讲 1 +x:1 +清产核资 1 +x:1 +色块 1 +x:1 +主副食 1 +x:1 +砂布 1 +x:1 +无敌手 1 +x:1 +邻国 1 +x:1 +建国门 1 +x:1 +桑拿浴 1 +x:1 +鸣放 1 +x:1 +天门冬 1 +x:1 +心中有数 1 +x:1 +高尔克 1 +x:1 +圣克鲁 1 +x:1 +处理机 1 +x:1 +外高桥 1 +x:1 +彩桥 1 +x:1 +富裕户 1 +x:1 +病源 1 +x:1 +氢氧根 1 +x:1 +种地人 1 +x:1 +领证率 1 +x:1 +贼船 1 +x:1 +惨死 1 +x:1 +一知半解 1 +x:1 +奔头 1 +x:1 +三令五申 1 +x:1 +吕望乡 1 +x:1 +延边队 1 +x:1 +绥靖区 1 +x:1 +和数 1 +x:1 +辽中 1 +x:1 +信纸 1 +x:1 +为时 1 +x:1 +鸿雁传书 1 +x:1 +严母 1 +x:1 +蜀绣 1 +x:1 +丢标 1 +x:1 +可视电话 1 +x:1 +名堂 1 +x:1 +挽额 1 +x:1 +辽东 1 +x:1 +小炒 1 +x:1 +幽情 1 +x:1 +闭卷 1 +x:1 +高兴处 1 +x:1 +克旗 1 +x:1 +民族魂 1 +x:1 +放心 1 +x:1 +唤醒 1 +x:1 +白湖乡 1 +x:1 +山豆根 1 +x:1 +分庭抗礼 1 +x:1 +电子秤 1 +x:1 +嘉年华会 1 +x:1 +金龙山 1 +x:1 +遥感学家 1 +x:1 +渔业大臣 1 +x:1 +消息报 1 +x:1 +抢走 1 +x:1 +衣饰 1 +x:1 +含片式 1 +x:1 +郑州省 1 +x:1 +宰客 1 +x:1 +泣诉 1 +x:1 +阴道炎 1 +x:1 +梅花鹿 1 +x:1 +名心 1 +x:1 +举报点 1 +x:1 +驻军 1 +x:1 +幽期 1 +x:1 +物质化 1 +x:1 +和刻本 1 +x:1 +隐睾症 1 +x:1 +住房率 1 +x:1 +加农炮弹 1 +x:1 +各区 1 +x:1 +戴 485 +x:485 +金指 1 +x:1 +调剂 1 +x:1 +尺蠖 1 +x:1 +水族馆 1 +x:1 +倔犟汉 1 +x:1 +克扣 1 +x:1 +蓟县 1 +x:1 +吹箫者 1 +x:1 +赞叹 1 +x:1 +落落 1 +x:1 +抢购 1 +x:1 +量才适用 1 +x:1 +晋冀豫 1 +x:1 +峡中 1 +x:1 +修理 1 +x:1 +看不上眼 1 +x:1 +剔 1 +x:1 +瞩目 1 +x:1 +赞叹不已 1 +x:1 +断定 1 +x:1 +巡 7 +x:7 +活菩萨 1 +x:1 +肉眼 1 +x:1 +刺激素 1 +x:1 +罚没款 1 +x:1 +矿棉 1 +x:1 +叫花子 1 +x:1 +白发苍苍 1 +x:1 +诈唬 1 +x:1 +各卷 1 +x:1 +讨论稿 1 +x:1 +政局 1 +x:1 +氨基酸 1 +x:1 +疲惫 1 +x:1 +误事 1 +x:1 +杉树 1 +x:1 +徐州 1 +x:1 +公网 1 +x:1 +独处 1 +x:1 +手足 1 +x:1 +为之一喜 1 +x:1 +难以为继 1 +x:1 +抢跳 1 +x:1 +像样 1 +x:1 +玉米糠 1 +x:1 +分配观 1 +x:1 +洋服 1 +x:1 +幽林 1 +x:1 +立竿见影 1 +x:1 +涵养 1 +x:1 +花团锦簇 1 +x:1 +金叶 1 +x:1 +合格证 1 +x:1 +名录 1 +x:1 +各县 1 +x:1 +副县级 1 +x:1 +借债者 1 +x:1 +抢跑 1 +x:1 +铁甲车 1 +x:1 +夹 60 +x:60 +芝麻官 1 +x:1 +蒙罗维亚 1 +x:1 +专利法 1 +x:1 +难找 1 +x:1 +放声 1 +x:1 +短平快 1 +x:1 +铐 2 +x:2 +长梁乡 1 +x:1 +黄表纸 1 +x:1 +利害得失 1 +x:1 +丘墓 1 +x:1 +风琴 1 +x:1 +判决 1 +x:1 +玉米粥 1 +x:1 +三连动 1 +x:1 +草鱼 1 +x:1 +影迷 1 +x:1 +玉米粒 1 +x:1 +克拉 1 +x:1 +阑珊处 1 +x:1 +枝枝蔓蔓 1 +x:1 +广空 1 +x:1 +平果县 1 +x:1 +梅里达 1 +x:1 +米饭 1 +x:1 +芒种 1 +x:1 +揭穿 1 +x:1 +火炉城 1 +x:1 +网架 1 +x:1 +邪恶 1 +x:1 +一路 1 +x:1 +湛江 1 +x:1 +空荡荡 1 +x:1 +外引内联 1 +x:1 +风痹 1 +x:1 +下一代 1 +x:1 +误会 1 +x:1 +自治法 1 +x:1 +阳朔县 1 +x:1 +放大 1 +x:1 +波尔多市 1 +x:1 +金戒 1 +x:1 +各别 1 +x:1 +奔忙 1 +x:1 +问题性 1 +x:1 +青民盟 1 +x:1 +愚懦 1 +x:1 +误伤 1 +x:1 +蒙古人种 1 +x:1 +演习场 1 +x:1 +误传 1 +x:1 +球心 1 +x:1 +潮安县 1 +x:1 +手谕 1 +x:1 +影踪 1 +x:1 +谢东村 1 +x:1 +拟于不伦 1 +x:1 +安葬 1 +x:1 +网柱 1 +x:1 +责任田 1 +x:1 +单义性 1 +x:1 +解放滩镇 1 +x:1 +脱保 1 +x:1 +分散性 1 +x:1 +脱卸式 1 +x:1 +果蔬室 1 +x:1 +葛布 1 +x:1 +风疹 1 +x:1 +领事馆 1 +x:1 +大吃大喝 1 +x:1 +贵刊 1 +x:1 +扶志 1 +x:1 +钱袋 1 +x:1 +惨淡 1 +x:1 +婴幼儿 1 +x:1 +种猪场 1 +x:1 +总的来看 1 +x:1 +高耗能 1 +x:1 +好事多磨 1 +x:1 +性急 1 +x:1 +沙沟村 1 +x:1 +捆儿 1 +x:1 +节粮型 1 +x:1 +注册人 1 +x:1 +守门 1 +x:1 +冷静 1 +x:1 +他山石 1 +x:1 +利息率 1 +x:1 +肉瘤 1 +x:1 +雪顿节 1 +x:1 +沿阶草 1 +x:1 +正班 1 +x:1 +船用 1 +x:1 +广西籍 1 +x:1 +彭 672 +x:672 +耳畔 1 +x:1 +难挨 1 +x:1 +乳臭未干 1 +x:1 +前湾 1 +x:1 +发动 1 +x:1 +左左右右 1 +x:1 +昝 5 +x:5 +色光 1 +x:1 +铁证如山 1 +x:1 +幽暗 1 +x:1 +讲用会 1 +x:1 +室 84 +x:84 +河滩地 1 +x:1 +衣食 1 +x:1 +集思广益 1 +x:1 +做菜 1 +x:1 +妖雾 1 +x:1 +葛店 1 +x:1 +寒露 1 +x:1 +乱弹琴 1 +x:1 +江浦县 1 +x:1 +筏 1 +x:1 +灾害点 1 +x:1 +寿山 1 +x:1 +白种人 1 +x:1 +风电 1 +x:1 +非但 1 +x:1 +奥新社 1 +x:1 +信贷处 1 +x:1 +名师 1 +x:1 +蕲春 1 +x:1 +横挑鼻子 1 +x:1 +风生 1 +x:1 +晚会局 1 +x:1 +和悦 1 +x:1 +肉畜 1 +x:1 +为怪 1 +x:1 +贵党 1 +x:1 +狭心症 1 +x:1 +两面 1 +x:1 +宁津县 1 +x:1 +哭喊 1 +x:1 +二面角 1 +x:1 +冕 7 +x:7 +愚拙 1 +x:1 +土坳村 1 +x:1 +货邮 1 +x:1 +精制油 1 +x:1 +启运 1 +x:1 +启迪 1 +x:1 +行侠仗义 1 +x:1 +一气之下 1 +x:1 +扎科帕内 1 +x:1 +臣僚 1 +x:1 +检验单 1 +x:1 +海气 1 +x:1 +耳目 1 +x:1 +变异性 1 +x:1 +莱家村 1 +x:1 +凌水河 1 +x:1 +天然性 1 +x:1 +手车 1 +x:1 +断井颓垣 1 +x:1 +四站村 1 +x:1 +腊 2 +x:2 +时刻处 1 +x:1 +把酒 1 +x:1 +电子管 1 +x:1 +麦冬草 1 +x:1 +狼群 1 +x:1 +藉以窥知 1 +x:1 +各党 1 +x:1 +高龄 1 +x:1 +关山重重 1 +x:1 +信笺 1 +x:1 +剔除 1 +x:1 +草黄 1 +x:1 +线规 1 +x:1 +花岗岩 1 +x:1 +搭腔 1 +x:1 +静净斋 1 +x:1 +器材 1 +x:1 +肉用 1 +x:1 +拳 30 +x:30 +说词 1 +x:1 +呆笨 1 +x:1 +货郎 1 +x:1 +年产量 1 +x:1 +摇曳多姿 1 +x:1 +行政部门 1 +x:1 +瞿河乡 1 +x:1 +铅条 1 +x:1 +覆膜 1 +x:1 +踪影 1 +x:1 +难怪 1 +x:1 +检验史 1 +x:1 +阅报室 1 +x:1 +手边 1 +x:1 +电击穴 1 +x:1 +政工 1 +x:1 +发言组 1 +x:1 +援粮 1 +x:1 +双黄 1 +x:1 +马普托 1 +x:1 +麦苗 1 +x:1 +大块文章 1 +x:1 +揭破 1 +x:1 +添加剂 1 +x:1 +断奶 1 +x:1 +抢运 1 +x:1 +罢休 1 +x:1 +锁具 1 +x:1 +中国画界 1 +x:1 +可持续性 1 +x:1 +英雄豪杰 1 +x:1 +右侧 1 +x:1 +届满 1 +x:1 +风瘫 1 +x:1 +首善 1 +x:1 +邻县 1 +x:1 +麦芽 1 +x:1 +小说集 1 +x:1 +三隐潭 1 +x:1 +马赛城 1 +x:1 +心虚 1 +x:1 +先决条件 1 +x:1 +沙溪 1 +x:1 +砂子 1 +x:1 +法律学 1 +x:1 +重起炉灶 1 +x:1 +手迹 1 +x:1 +汽修 1 +x:1 +联合报 1 +x:1 +麦芒 1 +x:1 +冷霜 1 +x:1 +轻工业 1 +x:1 +切实有力 1 +x:1 +定级 1 +x:1 +黑家鼠 1 +x:1 +先师 1 +x:1 +达赖 1 +x:1 +肝部 1 +x:1 +绿野 1 +x:1 +恶化 1 +x:1 +关令 1 +x:1 +精密型 1 +x:1 +荞麦窝 1 +x:1 +门门道道 1 +x:1 +万古流芳 1 +x:1 +断壁 1 +x:1 +萤火虫儿 1 +x:1 +蛀齿 1 +x:1 +运动队 1 +x:1 +八辛庄村 1 +x:1 +两院 1 +x:1 +右下 1 +x:1 +右上 1 +x:1 +土地奖 1 +x:1 +推迟 1 +x:1 +世 180 +x:180 +尼尔基 1 +x:1 +淘米箩 1 +x:1 +寒门 1 +x:1 +矿工 1 +x:1 +魔幻 1 +x:1 +环节税 1 +x:1 +罢了 1 +x:1 +平放 1 +x:1 +儿女式 1 +x:1 +中西亚 1 +x:1 +目光短浅 1 +x:1 +密封圈 1 +x:1 +财政系 1 +x:1 +火卫三 1 +x:1 +饮食摊 1 +x:1 +波通社 1 +x:1 +习尚 1 +x:1 +麦草 1 +x:1 +投保人 1 +x:1 +观念学 1 +x:1 +圣里斯特 1 +x:1 +搭腰 1 +x:1 +恶劣 1 +x:1 +判别 1 +x:1 +防疫费 1 +x:1 +各户 1 +x:1 +定编 1 +x:1 +麦茬 1 +x:1 +揭秘 1 +x:1 +放学 1 +x:1 +小提琴家 1 +x:1 +顾名思义 1 +x:1 +关上 1 +x:1 +判分 1 +x:1 +甘丹寺 1 +x:1 +益粮 1 +x:1 +难懂 1 +x:1 +辛酸处 1 +x:1 +想来 1 +x:1 +判刑 1 +x:1 +厌倦 1 +x:1 +鸣叫 1 +x:1 +就医点 1 +x:1 +放宽 1 +x:1 +多党制 1 +x:1 +研究科 1 +x:1 +迪恩街 1 +x:1 +好不容易 1 +x:1 +名山 1 +x:1 +二房 1 +x:1 +文昭关 1 +x:1 +字调 1 +x:1 +随之而来 1 +x:1 +包村 1 +x:1 +顺差额 1 +x:1 +数词 1 +x:1 +控制器 1 +x:1 +炸掉 1 +x:1 +砥 1 +x:1 +数说 1 +x:1 +耐旱性 1 +x:1 +白沟村 1 +x:1 +泣血 1 +x:1 +垃桶筒 1 +x:1 +颜 86 +x:86 +难愈 1 +x:1 +火卫二 1 +x:1 +延缓 1 +x:1 +北大仓 1 +x:1 +焦点 1 +x:1 +波流固村 1 +x:1 +贸易 1 +x:1 +白毛风 1 +x:1 +揭示 1 +x:1 +工农党 1 +x:1 +吴江 1 +x:1 +太平县城 1 +x:1 +守静 1 +x:1 +茉莉花 1 +x:1 +鹰潭市 1 +x:1 +采茶 1 +x:1 +祭堂 1 +x:1 +金乡县 1 +x:1 +民航处 1 +x:1 +诗选 1 +x:1 +两难 1 +x:1 +语体文 1 +x:1 +茶社 1 +x:1 +焚化 1 +x:1 +灶房 1 +x:1 +断堤 1 +x:1 +名将 1 +x:1 +仿制者 1 +x:1 +数论 1 +x:1 +偷税款 1 +x:1 +三连冠 1 +x:1 +工农兵 1 +x:1 +实名制 1 +x:1 +一睹芳容 1 +x:1 +包机 1 +x:1 +砣子 1 +x:1 +木姐 1 +x:1 +双龙 1 +x:1 +和约 1 +x:1 +谣言 1 +x:1 +清丰县 1 +x:1 +寡母 1 +x:1 +肋 3 +x:3 +语惊四座 1 +x:1 +泛金 1 +x:1 +贵体 1 +x:1 +吴王 1 +x:1 +脱逃率 1 +x:1 +苦瓜酒 1 +x:1 +痰祛湿 1 +x:1 +谚语 1 +x:1 +定息 1 +x:1 +肌节 1 +x:1 +大小事 1 +x:1 +误判 1 +x:1 +网窝 1 +x:1 +双联 1 +x:1 +旧社会 1 +x:1 +悬浮剂 1 +x:1 +践约 1 +x:1 +摆样子 1 +x:1 +脊椎炎 1 +x:1 +团州委 1 +x:1 +沙滩 1 +x:1 +各位 1 +x:1 +韬光养晦 1 +x:1 +钱排镇 1 +x:1 +锦上添花 1 +x:1 +雪山 1 +x:1 +显赫 1 +x:1 +返航 1 +x:1 +特性 1 +x:1 +测报站 1 +x:1 +青贮 1 +x:1 +进程表 1 +x:1 +模唱 1 +x:1 +双考 1 +x:1 +网站 1 +x:1 +烫 22 +x:22 +肉欲 1 +x:1 +自营 1 +x:1 +惨烈 1 +x:1 +实施者 1 +x:1 +命运感 1 +x:1 +雪层 1 +x:1 +工农业 1 +x:1 +光山县 1 +x:1 +扫描仪 1 +x:1 +娘胎 1 +x:1 +托运 1 +x:1 +鹜窝村 1 +x:1 +自家 1 +x:1 +业已 1 +x:1 +特搜部 1 +x:1 +庸人 1 +x:1 +集中度 1 +x:1 +彪形大汉 1 +x:1 +油路化 1 +x:1 +有去无回 1 +x:1 +中间商 1 +x:1 +自审 1 +x:1 +非分 1 +x:1 +白花花 1 +x:1 +宽套 1 +x:1 +自卫性 1 +x:1 +污水口 1 +x:1 +领带夹 1 +x:1 +定安县 1 +x:1 +掉价 1 +x:1 +坏东西 1 +x:1 +满盘皆输 1 +x:1 +全身像 1 +x:1 +尖顶 1 +x:1 +脑袋瓜 1 +x:1 +眷属 1 +x:1 +穗建 1 +x:1 +安邦定国 1 +x:1 +如释重负 1 +x:1 +寡弟媳 1 +x:1 +赵光镇 1 +x:1 +轰动性 1 +x:1 +双肩 1 +x:1 +危地马拉 1 +x:1 +钌铞儿 1 +x:1 +风格 1 +x:1 +作件 1 +x:1 +揭晓 1 +x:1 +此著 1 +x:1 +独生 1 +x:1 +兢兢业业 1 +x:1 +三审制 1 +x:1 +莲芰生烟 1 +x:1 +疏浚船 1 +x:1 +臣下 1 +x:1 +耳根 1 +x:1 +袖珍版 1 +x:1 +罢免 1 +x:1 +鱼冻 1 +x:1 +市话费 1 +x:1 +手里 1 +x:1 +不稳平衡 1 +x:1 +中外代 1 +x:1 +幽篁 1 +x:1 +前进 1 +x:1 +难分难解 1 +x:1 +梭子鱼 1 +x:1 +伪币 1 +x:1 +炸糕 1 +x:1 +网箱 1 +x:1 +心广体胖 1 +x:1 +大东区 1 +x:1 +辣椒酱 1 +x:1 +证者 1 +x:1 +遗 10 +x:10 +九曲溪 1 +x:1 +自娱 1 +x:1 +包租 1 +x:1 +贵乎 1 +x:1 +各业 1 +x:1 +雪崩 1 +x:1 +横峰县 1 +x:1 +爱民如子 1 +x:1 +双腿 1 +x:1 +木背椅 1 +x:1 +地方军 1 +x:1 +各个 1 +x:1 +右倾 1 +x:1 +处在 1 +x:1 +和美 1 +x:1 +友谊路 1 +x:1 +热销书 1 +x:1 +青豆 1 +x:1 +双腕 1 +x:1 +T 2 +x:2 +艇次 1 +x:1 +抢道 1 +x:1 +弗罗拉 1 +x:1 +妖言 1 +x:1 +兀 1 +x:1 +爱国心 1 +x:1 +蜗行牛步 1 +x:1 +征兵制 1 +x:1 +滕 38 +x:38 +微利价 1 +x:1 +网篮 1 +x:1 +黄壁庄 1 +x:1 +喜文嗜乐 1 +x:1 +英雄好汉 1 +x:1 +精雕细镂 1 +x:1 +墙围子 1 +x:1 +官方 1 +x:1 +心想事成 1 +x:1 +双脚 1 +x:1 +神色 1 +x:1 +票价 1 +x:1 +辣丝丝 1 +x:1 +风云变幻 1 +x:1 +财政所 1 +x:1 +左方 1 +x:1 +远走他乡 1 +x:1 +网笼 1 +x:1 +抗逆性 1 +x:1 +惊雷破柱 1 +x:1 +难缠 1 +x:1 +友谊赛 1 +x:1 +市运会 1 +x:1 +蜡花 1 +x:1 +无是非观 1 +x:1 +像头 1 +x:1 +双臂 1 +x:1 +包票 1 +x:1 +白日做梦 1 +x:1 +差点 1 +x:1 +刭 1 +x:1 +原生质 1 +x:1 +之和 1 +x:1 +厌世 1 +x:1 +各人 1 +x:1 +和缓 1 +x:1 +马钱子 1 +x:1 +洁白 1 +x:1 +无儿无女 1 +x:1 +映管 1 +x:1 +莲子 1 +x:1 +审计局 1 +x:1 +四季青 1 +x:1 +步校 1 +x:1 +怀里 1 +x:1 +惊人之举 1 +x:1 +货车 1 +x:1 +衡阳 1 +x:1 +羞怯 1 +x:1 +银杏树 1 +x:1 +承载力 1 +x:1 +货轮 1 +x:1 +丧葬 1 +x:1 +牛街 1 +x:1 +穷骨头 1 +x:1 +绸缎 1 +x:1 +鸡肠鼠肚 1 +x:1 +贵人 1 +x:1 +同案犯 1 +x:1 +橡胶林 1 +x:1 +再生产 1 +x:1 +上野 1 +x:1 +部署 1 +x:1 +酷虐 1 +x:1 +书记长 1 +x:1 +庸俗 1 +x:1 +鼻烟壶 1 +x:1 +信条 1 +x:1 +肌肤 1 +x:1 +蒸化机 1 +x:1 +平山县 1 +x:1 +街街巷巷 1 +x:1 +惨状 1 +x:1 +管中窥豹 1 +x:1 +交通船 1 +x:1 +迷阵 1 +x:1 +椒 2 +x:2 +分裂生殖 1 +x:1 +落马 1 +x:1 +严父 1 +x:1 +粟 13 +x:13 +遗书 1 +x:1 +探索热 1 +x:1 +汽化 1 +x:1 +返聘 1 +x:1 +谢顶 1 +x:1 +肌肉 1 +x:1 +电子柜 1 +x:1 +名湖 1 +x:1 +民族节 1 +x:1 +杉皮 1 +x:1 +散酒 1 +x:1 +草芥 1 +x:1 +刮 85 +x:85 +电子枪 1 +x:1 +砚斋 1 +x:1 +宽宽 1 +x:1 +以偏概全 1 +x:1 +组织法 1 +x:1 +宽容 1 +x:1 +短出出 1 +x:1 +娘舅 1 +x:1 +麦鸡 1 +x:1 +心髓 1 +x:1 +伏击战 1 +x:1 +遗业 1 +x:1 +诗趣 1 +x:1 +宫娥 1 +x:1 +毫无办法 1 +x:1 +续聘费 1 +x:1 +俩 184 +x:184 +拜寿 1 +x:1 +信服 1 +x:1 +老年型 1 +x:1 +盖州 1 +x:1 +右卫 1 +x:1 +草苫 1 +x:1 +钟祥市 1 +x:1 +宽宏 1 +x:1 +台球厅 1 +x:1 +正气 1 +x:1 +平山区 1 +x:1 +霍乱 1 +x:1 +锅 82 +x:82 +吠形吠声 1 +x:1 +步步 1 +x:1 +志大才疏 1 +x:1 +诗赋 1 +x:1 +两课 1 +x:1 +农业税费 1 +x:1 +风格各异 1 +x:1 +寒衣 1 +x:1 +做成 1 +x:1 +羚羊绒 1 +x:1 +厂证 1 +x:1 +挡 45 +x:45 +荷包 1 +x:1 +姜堰 1 +x:1 +芒果 1 +x:1 +民族舞 1 +x:1 +恶性 1 +x:1 +电子束 1 +x:1 +言行录 1 +x:1 +拥有者 1 +x:1 +黑棋 1 +x:1 +学无止境 1 +x:1 +正法 1 +x:1 +节资率 1 +x:1 +前轮 1 +x:1 +棉花点 1 +x:1 +卡拉巴尔 1 +x:1 +麦麸 1 +x:1 +色丝 1 +x:1 +遗事 1 +x:1 +打照面儿 1 +x:1 +迷雾 1 +x:1 +相差无几 1 +x:1 +食言 1 +x:1 +机播 1 +x:1 +罗镇乡 1 +x:1 +判例 1 +x:1 +边封 1 +x:1 +竹雕 1 +x:1 +小版 1 +x:1 +前大灯 1 +x:1 +色丹 1 +x:1 +边将 1 +x:1 +扑簌簌 1 +x:1 +挥金如土 1 +x:1 +产卵场 1 +x:1 +翻江倒海 1 +x:1 +筋络 1 +x:1 +非农 1 +x:1 +嘲笑 1 +x:1 +离退休 1 +x:1 +市辖区 1 +x:1 +草莓 1 +x:1 +正高 1 +x:1 +安徽省籍 1 +x:1 +眷念 1 +x:1 +定损 1 +x:1 +遗体 1 +x:1 +湿控 1 +x:1 +合办 1 +x:1 +肉桂 1 +x:1 +外事处 1 +x:1 +玉泉路 1 +x:1 +竭力 1 +x:1 +煤矿业 1 +x:1 +挽联 1 +x:1 +草莽 1 +x:1 +修正 1 +x:1 +修武 1 +x:1 +恶仗 1 +x:1 +办班费 1 +x:1 +运行 1 +x:1 +非单向 1 +x:1 +中阳县 1 +x:1 +多粒子 1 +x:1 +地方台 1 +x:1 +避税 1 +x:1 +雪影 1 +x:1 +● 306 +x:306 +通江县 1 +x:1 +正派 1 +x:1 +莱芒湖 1 +x:1 +函询 1 +x:1 +恶人 1 +x:1 +大智大勇 1 +x:1 +草菇 1 +x:1 +守诺 1 +x:1 +杯弓蛇影 1 +x:1 +风残 1 +x:1 +应有 1 +x:1 +遗传 1 +x:1 +汪 316 +x:316 +包管 1 +x:1 +肉样 1 +x:1 +观测站 1 +x:1 +被管理者 1 +x:1 +一碧如洗 1 +x:1 +绿豆 1 +x:1 +轻工厅 1 +x:1 +白手起家 1 +x:1 +官架 1 +x:1 +杂粮 1 +x:1 +黑社会 1 +x:1 +恶习 1 +x:1 +泳坛 1 +x:1 +道道儿 1 +x:1 +成千上百 1 +x:1 +肝脑涂地 1 +x:1 +黑陶文化 1 +x:1 +钓具 1 +x:1 +审计师 1 +x:1 +接力式 1 +x:1 +雨天 1 +x:1 +涵义 1 +x:1 +建国路 1 +x:1 +钓公 1 +x:1 +旧框框 1 +x:1 +队尾 1 +x:1 +环节动物 1 +x:1 +耐得 1 +x:1 +杜撰 1 +x:1 +记录槽 1 +x:1 +先兆 1 +x:1 +毛细血管 1 +x:1 +儒生 1 +x:1 +葫芦岛 1 +x:1 +皮 101 +x:101 +傻跑一气 1 +x:1 +巡航 1 +x:1 +独白 1 +x:1 +鼓声 1 +x:1 +利息流 1 +x:1 +责任段 1 +x:1 +终决权 1 +x:1 +非党 1 +x:1 +洋场气 1 +x:1 +官服 1 +x:1 +费用权 1 +x:1 +草荒 1 +x:1 +心魄 1 +x:1 +二十五日 1 +x:1 +治安费 1 +x:1 +权充 1 +x:1 +肌腱 1 +x:1 +车子 1 +x:1 +耕地量 1 +x:1 +政权党 1 +x:1 +赖账者 1 +x:1 +影都 1 +x:1 +财政性 1 +x:1 +耐心 1 +x:1 +南新路 1 +x:1 +姑娘家 1 +x:1 +茄克衣 1 +x:1 +草药 1 +x:1 +互救式 1 +x:1 +手锣 1 +x:1 +网纲 1 +x:1 +岫岩县 1 +x:1 +麦顶 1 +x:1 +手锤 1 +x:1 +网纹 1 +x:1 +边界线 1 +x:1 +风波 1 +x:1 +手锯 1 +x:1 +画地为牢 1 +x:1 +网线 1 +x:1 +运载 1 +x:1 +姜庄 1 +x:1 +如此一来 1 +x:1 +凌古铄金 1 +x:1 +狮子狗 1 +x:1 +红枣林 1 +x:1 +风泵 1 +x:1 +运转 1 +x:1 +奔泻 1 +x:1 +炼化 1 +x:1 +重庆市 1 +x:1 +邪祟 1 +x:1 +金笔 1 +x:1 +装卸 1 +x:1 +诗语 1 +x:1 +言者 1 +x:1 +奢侈 1 +x:1 +迷途 1 +x:1 +长吁短叹 1 +x:1 +雪堆 1 +x:1 +苦其心志 1 +x:1 +直盯盯 1 +x:1 +做操 1 +x:1 +宴请 1 +x:1 +健身 1 +x:1 +阿尔法镇 1 +x:1 +手镯 1 +x:1 +北流市 1 +x:1 +椎骨 1 +x:1 +自由 1 +x:1 +营养片 1 +x:1 +无污染 1 +x:1 +辣味 1 +x:1 +寅著 1 +x:1 +弗罗林 1 +x:1 +安企部法 1 +x:1 +径自 1 +x:1 +下月初 1 +x:1 +丝织业 1 +x:1 +教条化 1 +x:1 +网络 1 +x:1 +兮 24 +x:24 +风沙 1 +x:1 +汽轮机 1 +x:1 +兰家镇 1 +x:1 +一日之功 1 +x:1 +芝麻官儿 1 +x:1 +泻 17 +x:17 +贡嘎县 1 +x:1 +诗论 1 +x:1 +走街串巷 1 +x:1 +武阳镇 1 +x:1 +干练 1 +x:1 +禁放区 1 +x:1 +紧密型 1 +x:1 +米脂 1 +x:1 +雨带 1 +x:1 +没门儿 1 +x:1 +参谋处 1 +x:1 +怏怏不乐 1 +x:1 +黑油油 1 +x:1 +金箔 1 +x:1 +之内 1 +x:1 +春光明媚 1 +x:1 +肇祸 1 +x:1 +淮阴籍 1 +x:1 +车皮 1 +x:1 +自律 1 +x:1 +安安稳稳 1 +x:1 +候机室 1 +x:1 +幽美 1 +x:1 +包米 1 +x:1 +月息 1 +x:1 +怀铁 1 +x:1 +样张 1 +x:1 +增养 1 +x:1 +全民族 1 +x:1 +子母弹 1 +x:1 +举步维艰 1 +x:1 +曹 468 +x:468 +膘肥筋劲 1 +x:1 +当家人 1 +x:1 +把诊 1 +x:1 +非对抗性 1 +x:1 +风水 1 +x:1 +倡导 1 +x:1 +万年松 1 +x:1 +严师 1 +x:1 +运输 1 +x:1 +影音 1 +x:1 +会客室 1 +x:1 +车展 1 +x:1 +县试 1 +x:1 +样式 1 +x:1 +自忖 1 +x:1 +食谱 1 +x:1 +雨幕 1 +x:1 +误国 1 +x:1 +铭记碑 1 +x:1 +显见 1 +x:1 +揭批 1 +x:1 +甘蔗渣 1 +x:1 +翼根 1 +x:1 +炼制 1 +x:1 +边寨 1 +x:1 +四季海棠 1 +x:1 +伏尔加 1 +x:1 +信息 1 +x:1 +作案者 1 +x:1 +花落谁家 1 +x:1 +雪天 1 +x:1 +净赚 1 +x:1 +穗子 1 +x:1 +包团 1 +x:1 +面红耳赤 1 +x:1 +爽身粉 1 +x:1 +青衫 1 +x:1 +雪夜 1 +x:1 +谨忍 1 +x:1 +长期以来 1 +x:1 +决心书 1 +x:1 +氢氧基 1 +x:1 +通家口村 1 +x:1 +误场 1 +x:1 +步法 1 +x:1 +口条 1 +x:1 +金税 1 +x:1 +贪玩 1 +x:1 +做人 1 +x:1 +狮子王 1 +x:1 +日利率 1 +x:1 +精神衰弱 1 +x:1 +太史公 1 +x:1 +零二分 1 +x:1 +保持法 1 +x:1 +车工 1 +x:1 +经保处 1 +x:1 +焦墨 1 +x:1 +清清的 1 +x:1 +赵公元帅 1 +x:1 +凯鲁旺 1 +x:1 +罢哺 1 +x:1 +惨痛 1 +x:1 +德累斯顿 1 +x:1 +戳记 1 +x:1 +以弱胜强 1 +x:1 +两调 1 +x:1 +应聘 1 +x:1 +干 1499 +x:1499 +三方 1 +x:1 +附加值 1 +x:1 +突显 1 +x:1 +轰炸机 1 +x:1 +风浪 1 +x:1 +玄 3 +x:3 +站立者 1 +x:1 +谗言 1 +x:1 +贵州籍 1 +x:1 +痛哭流涕 1 +x:1 +附属 1 +x:1 +购销处 1 +x:1 +加班加点 1 +x:1 +函购 1 +x:1 +平常人 1 +x:1 +宇拓路 1 +x:1 +数量 1 +x:1 +内外部 1 +x:1 +主考 1 +x:1 +哭丧 1 +x:1 +藏药学 1 +x:1 +益智 1 +x:1 +好强 1 +x:1 +风流 1 +x:1 +平常事 1 +x:1 +糖史 1 +x:1 +迷醉 1 +x:1 +鸣笛 1 +x:1 +叉 4 +x:4 +自序 1 +x:1 +衣胞 1 +x:1 +守财 1 +x:1 +定时 1 +x:1 +首任 1 +x:1 +丽 51 +x:51 +造陆运动 1 +x:1 +曼哈顿岛 1 +x:1 +呆惯 1 +x:1 +损失率 1 +x:1 +附小 1 +x:1 +影雕 1 +x:1 +统筹兼顾 1 +x:1 +抗菌药 1 +x:1 +捏 34 +x:34 +宏远队 1 +x:1 +香葱 1 +x:1 +正殿 1 +x:1 +处变 1 +x:1 +影集 1 +x:1 +嫌犯 1 +x:1 +卫生纸 1 +x:1 +救命水 1 +x:1 +测报网 1 +x:1 +杜拉 1 +x:1 +网网 1 +x:1 +现金账 1 +x:1 +网罗 1 +x:1 +吐鲁番市 1 +x:1 +网罟 1 +x:1 +岌岌可危 1 +x:1 +手铐 1 +x:1 +羡慕 1 +x:1 +缩量 1 +x:1 +科巴县 1 +x:1 +侧道 1 +x:1 +教研室 1 +x:1 +生动性 1 +x:1 +招租 1 +x:1 +诉苦 1 +x:1 +保价信 1 +x:1 +小脚印 1 +x:1 +吞食 1 +x:1 +正桥 1 +x:1 +铺档 1 +x:1 +誓 10 +x:10 +车座 1 +x:1 +以信为本 1 +x:1 +厚薄规 1 +x:1 +司号 1 +x:1 +必修课 1 +x:1 +车库 1 +x:1 +车底 1 +x:1 +火烽村 1 +x:1 +独立型 1 +x:1 +击破 1 +x:1 +衡量 1 +x:1 +演出季 1 +x:1 +克维特绥 1 +x:1 +侯门如海 1 +x:1 +宽心 1 +x:1 +玉材 1 +x:1 +页岩 1 +x:1 +车床 1 +x:1 +奇效 1 +x:1 +责无旁贷 1 +x:1 +相关性 1 +x:1 +手面 1 +x:1 +寅虎 1 +x:1 +处理站 1 +x:1 +明面儿 1 +x:1 +解忧 1 +x:1 +队委 1 +x:1 +凭空捏造 1 +x:1 +文具厂 1 +x:1 +九六 1 +x:1 +歌舞伎 1 +x:1 +二星级 1 +x:1 +外事局 1 +x:1 +闹事区 1 +x:1 +算术题 1 +x:1 +吃请 1 +x:1 +边境 1 +x:1 +官报 1 +x:1 +不落窠臼 1 +x:1 +梨膏 1 +x:1 +牧马图 1 +x:1 +风源 1 +x:1 +研究性 1 +x:1 +左手 1 +x:1 +留兰香 1 +x:1 +婚配 1 +x:1 +浦南乡 1 +x:1 +冲动型 1 +x:1 +诗书画 1 +x:1 +花名册 1 +x:1 +风湿 1 +x:1 +瑞士法郎 1 +x:1 +附录 1 +x:1 +歌仔戏 1 +x:1 +膛 2 +x:2 +矮 26 +x:26 +欠债 1 +x:1 +辽南 1 +x:1 +约定期 1 +x:1 +拉拉队员 1 +x:1 +淅沥 1 +x:1 +功成名遂 1 +x:1 +逯 1 +x:1 +运距 1 +x:1 +弱 182 +x:182 +元人 1 +x:1 +车市 1 +x:1 +贵金属 1 +x:1 +该关 1 +x:1 +边塞 1 +x:1 +编译局 1 +x:1 +司南 1 +x:1 +使人昭昭 1 +x:1 +径赛 1 +x:1 +魂飞魄散 1 +x:1 +怀集 1 +x:1 +惨白 1 +x:1 +状物 1 +x:1 +力挽狂澜 1 +x:1 +姊 1 +x:1 +自己 1 +x:1 +自已 1 +x:1 +委员会制 1 +x:1 +天然碱 1 +x:1 +吐尔尕特 1 +x:1 +两边 1 +x:1 +彭畈乡 1 +x:1 +王家营 1 +x:1 +健谈 1 +x:1 +呱呱坠地 1 +x:1 +像片 1 +x:1 +预决算 1 +x:1 +诉至 1 +x:1 +酥脆 1 +x:1 +咯咯 1 +x:1 +梧桐树 1 +x:1 +高栏 1 +x:1 +金秀 1 +x:1 +经济史学 1 +x:1 +官房 1 +x:1 +金秋 1 +x:1 +活化资本 1 +x:1 +九流三教 1 +x:1 +元件 1 +x:1 +自尽 1 +x:1 +无私无畏 1 +x:1 +渡鸦 1 +x:1 +积石山 1 +x:1 +卤制品 1 +x:1 +抢险 1 +x:1 +鉴赏 1 +x:1 +住房梦 1 +x:1 +鸣禽 1 +x:1 +悉尼港 1 +x:1 +唤起 1 +x:1 +人身自由 1 +x:1 +正楷 1 +x:1 +澳门籍 1 +x:1 +使君子 1 +x:1 +蜃景 1 +x:1 +斗鸡 1 +x:1 +痴迷 1 +x:1 +独独 1 +x:1 +电影机 1 +x:1 +自治相 1 +x:1 +希斯罗 1 +x:1 +东张西望 1 +x:1 +信托 1 +x:1 +耳濡 1 +x:1 +古往今来 1 +x:1 +油点 1 +x:1 +单宁酸 1 +x:1 +住宅点 1 +x:1 +液氧箱 1 +x:1 +人情案 1 +x:1 +操 94 +x:94 +蒜头 1 +x:1 +宽度 1 +x:1 +特别奖 1 +x:1 +附加刑 1 +x:1 +寒趣 1 +x:1 +狗血喷头 1 +x:1 +归隐 1 +x:1 +绿衣 1 +x:1 +油炸 1 +x:1 +定本 1 +x:1 +做东 1 +x:1 +港九 1 +x:1 +兵小子 1 +x:1 +育苗场 1 +x:1 +禺 8 +x:8 +录像机 1 +x:1 +唯唯诺诺 1 +x:1 +补贴款 1 +x:1 +递给 1 +x:1 +之前 1 +x:1 +工作者 1 +x:1 +蜇伤 1 +x:1 +附庸 1 +x:1 +曹州 1 +x:1 +权势电 1 +x:1 +健健康康 1 +x:1 +落选率 1 +x:1 +黄花鱼 1 +x:1 +独具慧眼 1 +x:1 +死难者 1 +x:1 +互助会 1 +x:1 +网吧 1 +x:1 +风潮 1 +x:1 +宽广 1 +x:1 +诗行 1 +x:1 +港城镇 1 +x:1 +声援信 1 +x:1 +会计系 1 +x:1 +金碧 1 +x:1 +饮子 1 +x:1 +鱼缸型 1 +x:1 +包罗 1 +x:1 +拜师 1 +x:1 +好大喜功 1 +x:1 +急 236 +x:236 +禁忌症 1 +x:1 +全院性 1 +x:1 +贪青 1 +x:1 +宽幅 1 +x:1 +棱锥 1 +x:1 +精神抖擞 1 +x:1 +黑索今 1 +x:1 +报建率 1 +x:1 +处决 1 +x:1 +加害者 1 +x:1 +车影 1 +x:1 +罗伯特 1 +x:1 +背水阵 1 +x:1 +淅淅 1 +x:1 +松松垮垮 1 +x:1 +五毒俱全 1 +x:1 +棱镜 1 +x:1 +定果 1 +x:1 +宽带 1 +x:1 +手雷 1 +x:1 +洋洲村 1 +x:1 +聚众闹事 1 +x:1 +通过率 1 +x:1 +耐寒 1 +x:1 +拜年 1 +x:1 +愚笨 1 +x:1 +荒漠学 1 +x:1 +附带 1 +x:1 +米色 1 +x:1 +正字法 1 +x:1 +放心菜 1 +x:1 +电子战 1 +x:1 +绿装 1 +x:1 +归集部 1 +x:1 +守车 1 +x:1 +难倒 1 +x:1 +定案 1 +x:1 +简古 1 +x:1 +网状 1 +x:1 +渔樵 1 +x:1 +饮品 1 +x:1 +袋 77 +x:77 +茫茫然 1 +x:1 +发愤忘食 1 +x:1 +可不 1 +x:1 +移民署 1 +x:1 +工厂化 1 +x:1 +长篇小说 1 +x:1 +队型 1 +x:1 +橘黄色 1 +x:1 +窗 61 +x:61 +碍眼 1 +x:1 +锚张网 1 +x:1 +何方 1 +x:1 +食物中毒 1 +x:1 +南山堡村 1 +x:1 +共同市场 1 +x:1 +营运官 1 +x:1 +邹城 1 +x:1 +依达乡 1 +x:1 +掌管 1 +x:1 +风情 1 +x:1 +雪后 1 +x:1 +直理 1 +x:1 +肤泛 1 +x:1 +收兵 1 +x:1 +英雄主义 1 +x:1 +败笔 1 +x:1 +电击法 1 +x:1 +展销品 1 +x:1 +抖搂 1 +x:1 +口惠 1 +x:1 +履带式 1 +x:1 +新集镇 1 +x:1 +定标 1 +x:1 +美食村 1 +x:1 +可操左券 1 +x:1 +懑 1 +x:1 +责任性 1 +x:1 +荒 27 +x:27 +北朝鲜 1 +x:1 +梁沟村 1 +x:1 +手饺 1 +x:1 +太平无事 1 +x:1 +蓝筹股 1 +x:1 +泊车 1 +x:1 +散文史 1 +x:1 +职业病 1 +x:1 +食肴 1 +x:1 +马 1168 +x:1168 +定格 1 +x:1 +教条式 1 +x:1 +包点 1 +x:1 +转头 1 +x:1 +落选 1 +x:1 +烈性 1 +x:1 +煤炭法 1 +x:1 +雅重 1 +x:1 +酥软 1 +x:1 +好高鹜远 1 +x:1 +疑问词 1 +x:1 +寒色 1 +x:1 +祝酒 1 +x:1 +定检 1 +x:1 +雅量 1 +x:1 +抹香鲸 1 +x:1 +青藤 1 +x:1 +直属机关 1 +x:1 +滑动轴承 1 +x:1 +乔克西 1 +x:1 +贸然 1 +x:1 +抖擞 1 +x:1 +砧木 1 +x:1 +旁遮普 1 +x:1 +挽诗 1 +x:1 +鸡毛掸子 1 +x:1 +膦 1 +x:1 +上年底 1 +x:1 +玉米棒 1 +x:1 +伊朗队 1 +x:1 +电子流 1 +x:1 +抑郁寡欢 1 +x:1 +七建 1 +x:1 +玲 150 +x:150 +群力 1 +x:1 +更上层楼 1 +x:1 +上部 1 +x:1 +青藏 1 +x:1 +音译 1 +x:1 +天琴座 1 +x:1 +金石 1 +x:1 +夏威夷州 1 +x:1 +黄歇口镇 1 +x:1 +一花独放 1 +x:1 +油汽炉 1 +x:1 +涸泽而渔 1 +x:1 +肉排 1 +x:1 +大同江畔 1 +x:1 +透视缩影 1 +x:1 +金矿 1 +x:1 +贷户 1 +x:1 +民航业 1 +x:1 +潘集区 1 +x:1 +糊涂一时 1 +x:1 +气压表 1 +x:1 +自古 1 +x:1 +酱紫色 1 +x:1 +食者 1 +x:1 +痴者 1 +x:1 +繁花似锦 1 +x:1 +官气 1 +x:1 +自叙 1 +x:1 +缸盖 1 +x:1 +自发 1 +x:1 +蛾子 1 +x:1 +主火场 1 +x:1 +印本 1 +x:1 +恢宏壮观 1 +x:1 +纺锤形 1 +x:1 +耳性 1 +x:1 +墁 1 +x:1 +沟鼠 1 +x:1 +心醉 1 +x:1 +公祭 1 +x:1 +无仁无义 1 +x:1 +青葱 1 +x:1 +自制 1 +x:1 +忙乎劲儿 1 +x:1 +汉学家 1 +x:1 +栽斤头 1 +x:1 +内应 1 +x:1 +双流县 1 +x:1 +曹县 1 +x:1 +早餐会 1 +x:1 +代州长 1 +x:1 +纸花 1 +x:1 +十四行诗 1 +x:1 +七彩 1 +x:1 +断代 1 +x:1 +边城 1 +x:1 +多管闲事 1 +x:1 +妖艳 1 +x:1 +减肥带 1 +x:1 +寒菊 1 +x:1 +下淀乡 1 +x:1 +心里 1 +x:1 +蜀汉 1 +x:1 +调味 1 +x:1 +误字 1 +x:1 +蜀江 1 +x:1 +冗员 1 +x:1 +断交 1 +x:1 +莲叶 1 +x:1 +正月 1 +x:1 +楚才杯 1 +x:1 +景德镇 1 +x:1 +两者 1 +x:1 +为着 1 +x:1 +陵 4 +x:4 +三好生 1 +x:1 +随机应变 1 +x:1 +民族观 1 +x:1 +六弦琴 1 +x:1 +君子国 1 +x:1 +雨区 1 +x:1 +金犀牛 1 +x:1 +莱茵河 1 +x:1 +拜倒 1 +x:1 +芒河 1 +x:1 +渔产业 1 +x:1 +阿克萨 1 +x:1 +珥陵镇 1 +x:1 +烃 1 +x:1 +辣妹 1 +x:1 +松明牌 1 +x:1 +自动 1 +x:1 +自助 1 +x:1 +天然矿 1 +x:1 +快步流星 1 +x:1 +壮 55 +x:55 +理发室 1 +x:1 +山西团 1 +x:1 +保持性 1 +x:1 +自力 1 +x:1 +肤浅 1 +x:1 +严禁 1 +x:1 +难看 1 +x:1 +尖酸 1 +x:1 +天文数字 1 +x:1 +纤纤 1 +x:1 +七律 1 +x:1 +惨祸 1 +x:1 +龙骨坡 1 +x:1 +伽马射线 1 +x:1 +混珠 1 +x:1 +青蒿 1 +x:1 +违法案 1 +x:1 +映现 1 +x:1 +奶皮 1 +x:1 +元曲 1 +x:1 +家门 1 +x:1 +乳房 1 +x:1 +枢纽局 1 +x:1 +百年史 1 +x:1 +审计员 1 +x:1 +石拱桥 1 +x:1 +焚膏继晷 1 +x:1 +外事司 1 +x:1 +导水管 1 +x:1 +淮河 1 +x:1 +留言栏 1 +x:1 +民心所向 1 +x:1 +青蒜 1 +x:1 +旨 5 +x:5 +正极 1 +x:1 +停车费 1 +x:1 +样刊 1 +x:1 +北流县 1 +x:1 +误导 1 +x:1 +官派 1 +x:1 +龙胆科 1 +x:1 +正果 1 +x:1 +建言献策 1 +x:1 +荷塘 1 +x:1 +绵绵不绝 1 +x:1 +金田 1 +x:1 +幽然 1 +x:1 +估算 1 +x:1 +网点 1 +x:1 +陆委会 1 +x:1 +费工夫 1 +x:1 +联邦制 1 +x:1 +车务 1 +x:1 +趋同化 1 +x:1 +买断性 1 +x:1 +守节 1 +x:1 +嫌疑者 1 +x:1 +狼毫 1 +x:1 +起诉书 1 +x:1 +诊断费 1 +x:1 +狼毒 1 +x:1 +铺摊 1 +x:1 +曝晒 1 +x:1 +零零星星 1 +x:1 +健胃 1 +x:1 +详审 1 +x:1 +放下 1 +x:1 +抗拉强度 1 +x:1 +罢官 1 +x:1 +伪品 1 +x:1 +草生菌 1 +x:1 +任内 1 +x:1 +小秋收 1 +x:1 +黑黑苍苍 1 +x:1 +广告部 1 +x:1 +高深莫测 1 +x:1 +运输机 1 +x:1 +一分高下 1 +x:1 +直排式 1 +x:1 +丘东 1 +x:1 +策 64 +x:64 +修成 1 +x:1 +资信度 1 +x:1 +你一言 1 +x:1 +棣 4 +x:4 +胜任感 1 +x:1 +老资格 1 +x:1 +样册 1 +x:1 +宽厚 1 +x:1 +说到家 1 +x:1 +恶拳 1 +x:1 +金管局 1 +x:1 +三室一厅 1 +x:1 +真分式 1 +x:1 +加拉法德 1 +x:1 +海战 1 +x:1 +轧钢机 1 +x:1 +许家庙 1 +x:1 +篆体 1 +x:1 +偿债 1 +x:1 +相对湿度 1 +x:1 +研究法 1 +x:1 +梓山 1 +x:1 +自决 1 +x:1 +为数不少 1 +x:1 +平易近人 1 +x:1 +放亮 1 +x:1 +麦雨 1 +x:1 +巢县 1 +x:1 +金疮 1 +x:1 +次 9654 +x:9654 +报国志 1 +x:1 +神经过敏 1 +x:1 +定点球 1 +x:1 +交流团 1 +x:1 +仲春 1 +x:1 +呻吟 1 +x:1 +风扇 1 +x:1 +车刀 1 +x:1 +碘酸 1 +x:1 +科学学系 1 +x:1 +高迢险峻 1 +x:1 +亏困 1 +x:1 +指示植物 1 +x:1 +附印 1 +x:1 +放任 1 +x:1 +绿藻 1 +x:1 +面粉厂 1 +x:1 +煤气炉 1 +x:1 +工会界 1 +x:1 +侦探 1 +x:1 +说闲话 1 +x:1 +专段 1 +x:1 +烧火柴卖 1 +x:1 +雪团 1 +x:1 +羚羊皮 1 +x:1 +有神论 1 +x:1 +官渡 1 +x:1 +垣曲县 1 +x:1 +焦土 1 +x:1 +绵白糖 1 +x:1 +脱脂棉 1 +x:1 +领带卡 1 +x:1 +证言 1 +x:1 +香椿头 1 +x:1 +天鹰座 1 +x:1 +桤木 1 +x:1 +爆 21 +x:21 +天游观 1 +x:1 +青虾 1 +x:1 +不会儿 1 +x:1 +凡士林 1 +x:1 +洋快餐 1 +x:1 +逃学 1 +x:1 +工段 1 +x:1 +车厢 1 +x:1 +难分难舍 1 +x:1 +青虬 1 +x:1 +药罐子 1 +x:1 +正数 1 +x:1 +丧身 1 +x:1 +为由 1 +x:1 +污水塘 1 +x:1 +地方官 1 +x:1 +宫 42 +x:42 +冠军队 1 +x:1 +承建方 1 +x:1 +文化买办 1 +x:1 +正教 1 +x:1 +为生 1 +x:1 +牯牛 1 +x:1 +股肌 1 +x:1 +舍死忘生 1 +x:1 +幽灵 1 +x:1 +穆民 1 +x:1 +两航 1 +x:1 +砂仁 1 +x:1 +水泥路 1 +x:1 +店 330 +x:330 +放心车 1 +x:1 +正攻 1 +x:1 +单生花 1 +x:1 +器物 1 +x:1 +雨布 1 +x:1 +走头无路 1 +x:1 +盗牛者 1 +x:1 +沙河 1 +x:1 +外围层 1 +x:1 +链球菌 1 +x:1 +商家 1 +x:1 +冷处理 1 +x:1 +附加 1 +x:1 +外围展 1 +x:1 +幽默剧 1 +x:1 +伪善 1 +x:1 +司库 1 +x:1 +辣子 1 +x:1 +趋利性 1 +x:1 +北叉口村 1 +x:1 +非国家 1 +x:1 +弃 41 +x:41 +拍案叫绝 1 +x:1 +延河水 1 +x:1 +隔岸观火 1 +x:1 +大事记 1 +x:1 +双语 1 +x:1 +生育观 1 +x:1 +正旦 1 +x:1 +呆滞 1 +x:1 +运能 1 +x:1 +队名 1 +x:1 +化境 1 +x:1 +易涝区 1 +x:1 +栗树 1 +x:1 +清谈误国 1 +x:1 +车匪 1 +x:1 +双河镇 1 +x:1 +农 195 +x:195 +恶报 1 +x:1 +天衣无缝 1 +x:1 +聚烯烃 1 +x:1 +砚池 1 +x:1 +青蛙 1 +x:1 +钱学森 1 +x:1 +青蛇 1 +x:1 +吵 28 +x:28 +篆书 1 +x:1 +追截 1 +x:1 +返观 1 +x:1 +那么 1 +x:1 +车印 1 +x:1 +展销场 1 +x:1 +细账 1 +x:1 +丹青妙笔 1 +x:1 +队员 1 +x:1 +风挡 1 +x:1 +雨具 1 +x:1 +从 12825 +x:12825 +正方 1 +x:1 +附则 1 +x:1 +好人主义 1 +x:1 +金瓯 1 +x:1 +袜底儿 1 +x:1 +旧店镇 1 +x:1 +和畅 1 +x:1 +两节 1 +x:1 +创面 1 +x:1 +审判者 1 +x:1 +场磙 1 +x:1 +历史化 1 +x:1 +巧合 1 +x:1 +宰辅 1 +x:1 +酒精度 1 +x:1 +独秀 1 +x:1 +祖传秘方 1 +x:1 +绿茶 1 +x:1 +绿茵 1 +x:1 +侍 2 +x:2 +福坑口村 1 +x:1 +俄籍 1 +x:1 +反之亦然 1 +x:1 +势均力敌 1 +x:1 +友人 1 +x:1 +债利 1 +x:1 +正手 1 +x:1 +发达县 1 +x:1 +风操 1 +x:1 +肉松 1 +x:1 +温补 1 +x:1 +处所词 1 +x:1 +近湖镇 1 +x:1 +白百破 1 +x:1 +红霉素 1 +x:1 +熔解热 1 +x:1 +衣襟 1 +x:1 +南漳县 1 +x:1 +过意不去 1 +x:1 +语速 1 +x:1 +龙狮团 1 +x:1 +委以 1 +x:1 +罢工 1 +x:1 +思想体系 1 +x:1 +工资分 1 +x:1 +羊粪 1 +x:1 +绿荫 1 +x:1 +租金 1 +x:1 +邹县 1 +x:1 +做法 1 +x:1 +铺户 1 +x:1 +衣褶 1 +x:1 +网目 1 +x:1 +新都县 1 +x:1 +姜国 1 +x:1 +刷白 1 +x:1 +肉末 1 +x:1 +工资制 1 +x:1 +习作 1 +x:1 +基加利 1 +x:1 +隔离道 1 +x:1 +货舱 1 +x:1 +夔纹 1 +x:1 +货船 1 +x:1 +一无是处 1 +x:1 +编译器 1 +x:1 +略迹原情 1 +x:1 +长春道 1 +x:1 +创汇额 1 +x:1 +茶缸子 1 +x:1 +非常 1 +x:1 +干群 1 +x:1 +准备期 1 +x:1 +观赏鱼 1 +x:1 +诉讼 1 +x:1 +御寒衣 1 +x:1 +名位 1 +x:1 +摆龙门阵 1 +x:1 +湿气 1 +x:1 +盗版案 1 +x:1 +创造 1 +x:1 +质量 1 +x:1 +灰白色 1 +x:1 +编缉 1 +x:1 +金玉 1 +x:1 +名作 1 +x:1 +大东庄 1 +x:1 +煤气化 1 +x:1 +轻工局 1 +x:1 +从头至尾 1 +x:1 +会客厅 1 +x:1 +肉果 1 +x:1 +数额 1 +x:1 +辽大 1 +x:1 +奔丧 1 +x:1 +钢垫 1 +x:1 +蒲草 1 +x:1 +赡 1 +x:1 +诉诸 1 +x:1 +名企 1 +x:1 +摘录 1 +x:1 +毋庸置言 1 +x:1 +熨帖 1 +x:1 +桃溪镇 1 +x:1 +诉请 1 +x:1 +斗门 1 +x:1 +剪切力 1 +x:1 +习俗 1 +x:1 +名优 1 +x:1 +资源部 1 +x:1 +衣衫 1 +x:1 +猫儿腻 1 +x:1 +歧路亡羊 1 +x:1 +那阵子 1 +x:1 +非徒 1 +x:1 +笃 7 +x:7 +自嘲 1 +x:1 +非得 1 +x:1 +米袋 1 +x:1 +冲积平原 1 +x:1 +居庸关 1 +x:1 +铁道兵 1 +x:1 +开花结果 1 +x:1 +湿润 1 +x:1 +抽水马桶 1 +x:1 +青联 1 +x:1 +结草衔环 1 +x:1 +生成量 1 +x:1 +名仕 1 +x:1 +赫伦文 1 +x:1 +专案 1 +x:1 +歇凉 1 +x:1 +特支费 1 +x:1 +藏药史 1 +x:1 +大伙儿 1 +x:1 +赎救 1 +x:1 +当事者 1 +x:1 +落井投石 1 +x:1 +修整 1 +x:1 +双赛 1 +x:1 +灿烂夺目 1 +x:1 +附和 1 +x:1 +名亡 1 +x:1 +甘蔗林 1 +x:1 +雪具 1 +x:1 +绿色 1 +x:1 +断案 1 +x:1 +金合欢 1 +x:1 +真切感 1 +x:1 +蒲苇 1 +x:1 +协作组 1 +x:1 +幼林地 1 +x:1 +女子组 1 +x:1 +处子 1 +x:1 +名人 1 +x:1 +维拉猜 1 +x:1 +辽墓 1 +x:1 +遛遛弯儿 1 +x:1 +修改 1 +x:1 +晋朝 1 +x:1 +讳病忌医 1 +x:1 +金牌 1 +x:1 +风斗 1 +x:1 +回复率 1 +x:1 +群死群伤 1 +x:1 +无意义 1 +x:1 +队列 1 +x:1 +获奖项 1 +x:1 +灶火 1 +x:1 +网眼 1 +x:1 +衣裤 1 +x:1 +张望 1 +x:1 +衣裳 1 +x:1 +骚 1 +x:1 +揭批查 1 +x:1 +青翠欲滴 1 +x:1 +瞩望 1 +x:1 +引入 1 +x:1 +竹报平安 1 +x:1 +返还 1 +x:1 +沙坪镇 1 +x:1 +处室 1 +x:1 +名义 1 +x:1 +衣装 1 +x:1 +毛岛 1 +x:1 +摄影集 1 +x:1 +朴质 1 +x:1 +做活 1 +x:1 +竭尽 1 +x:1 +行洪道 1 +x:1 +直立人 1 +x:1 +诗艺 1 +x:1 +错综 1 +x:1 +过滤罐 1 +x:1 +过滤网 1 +x:1 +相位差 1 +x:1 +败绩 1 +x:1 +骨架 1 +x:1 +责任方 1 +x:1 +响彻云霄 1 +x:1 +尖锐 1 +x:1 +青肥 1 +x:1 +边区 1 +x:1 +明太祖 1 +x:1 +米行 1 +x:1 +资源量 1 +x:1 +秘 14 +x:14 +朝天门港 1 +x:1 +百无聊赖 1 +x:1 +荡漾 1 +x:1 +身经百战 1 +x:1 +树上 1 +x:1 +百折不挠 1 +x:1 +衣袍 1 +x:1 +绿苔 1 +x:1 +名下 1 +x:1 +队副 1 +x:1 +陈列柜 1 +x:1 +剃头刀 1 +x:1 +赏金 1 +x:1 +吹打乐 1 +x:1 +衣袖 1 +x:1 +难点 1 +x:1 +失之交臂 1 +x:1 +信步 1 +x:1 +鸣炮 1 +x:1 +大渡河 1 +x:1 +鱼雷艇 1 +x:1 +峡山 1 +x:1 +启发式 1 +x:1 +边僻 1 +x:1 +明察秋毫 1 +x:1 +本质 1 +x:1 +育种 1 +x:1 +编组 1 +x:1 +新沙 1 +x:1 +乒乓球队 1 +x:1 +株州 1 +x:1 +退税制 1 +x:1 +晤谈 1 +x:1 +举足轻重 1 +x:1 +手鼓 1 +x:1 +超群绝伦 1 +x:1 +板轧机 1 +x:1 +城角 1 +x:1 +宽城 1 +x:1 +青草 1 +x:1 +类风湿 1 +x:1 +古运河畔 1 +x:1 +步枪 1 +x:1 +玉米花 1 +x:1 +护卫队 1 +x:1 +治安股 1 +x:1 +酊 1 +x:1 +确确实实 1 +x:1 +洛克比镇 1 +x:1 +像章 1 +x:1 +做伴 1 +x:1 +服装业界 1 +x:1 +鳗 1 +x:1 +牛顿 1 +x:1 +银杏果 1 +x:1 +风暴 1 +x:1 +黄河口 1 +x:1 +掌握 1 +x:1 +单株独枝 1 +x:1 +包皮 1 +x:1 +人民路 1 +x:1 +联系人 1 +x:1 +橡胶树 1 +x:1 +正正反反 1 +x:1 +友谊花 1 +x:1 +辽宁 1 +x:1 +重工业部 1 +x:1 +毛混纺 1 +x:1 +奔流 1 +x:1 +老年学 1 +x:1 +耐劳 1 +x:1 +尺骨 1 +x:1 +源头 1 +x:1 +风景 1 +x:1 +丛丛 1 +x:1 +辣度 1 +x:1 +主干性 1 +x:1 +侦查 1 +x:1 +落雪 1 +x:1 +富国强兵 1 +x:1 +行李车 1 +x:1 +嘎嘎 1 +x:1 +分歧 1 +x:1 +青菜 1 +x:1 +耐力 1 +x:1 +开单 1 +x:1 +定例 1 +x:1 +协防 1 +x:1 +启齿 1 +x:1 +网球 1 +x:1 +一片狼藉 1 +x:1 +丛中 1 +x:1 +肉料 1 +x:1 +贵州省 1 +x:1 +偿命 1 +x:1 +包圆 1 +x:1 +模块 1 +x:1 +长梁山 1 +x:1 +冬奥运会 1 +x:1 +落难 1 +x:1 +电学 1 +x:1 +吆五喝六 1 +x:1 +放映业 1 +x:1 +厌恶 1 +x:1 +引进 1 +x:1 +观赏鸽 1 +x:1 +焦化 1 +x:1 +价外税 1 +x:1 +生命 1 +x:1 +过桥费 1 +x:1 +马格里布 1 +x:1 +老先生 1 +x:1 +君子兰 1 +x:1 +联合政府 1 +x:1 +疑为 1 +x:1 +闲 44 +x:44 +丛书 1 +x:1 +诱导性 1 +x:1 +随意性 1 +x:1 +青色 1 +x:1 +投机者 1 +x:1 +处处 1 +x:1 +牌铭 1 +x:1 +独立 1 +x:1 +双轨 1 +x:1 +混用 1 +x:1 +助残日 1 +x:1 +肉摊 1 +x:1 +哥特 1 +x:1 +帖 7 +x:7 +揭榜 1 +x:1 +处理率 1 +x:1 +治理区 1 +x:1 +朔望 1 +x:1 +样品 1 +x:1 +夜场 1 +x:1 +一整天 1 +x:1 +酥裂 1 +x:1 +附图 1 +x:1 +升降机 1 +x:1 +草辫 1 +x:1 +尖音 1 +x:1 +红梅赞 1 +x:1 +舆地学社 1 +x:1 +地表水 1 +x:1 +受训者 1 +x:1 +主会场 1 +x:1 +杉篙 1 +x:1 +自命 1 +x:1 +风枪 1 +x:1 +荡涤 1 +x:1 +定线员 1 +x:1 +午 1 +x:1 +说到底 1 +x:1 +返贫 1 +x:1 +败类 1 +x:1 +竞渡 1 +x:1 +紧密层 1 +x:1 +期货价 1 +x:1 +江米酒 1 +x:1 +剔红 1 +x:1 +黄庄乡 1 +x:1 +贷方 1 +x:1 +西交民巷 1 +x:1 +清真餐 1 +x:1 +大处落墨 1 +x:1 +伪军 1 +x:1 +非生产 1 +x:1 +七大 1 +x:1 +任务 1 +x:1 +阿克苏 1 +x:1 +地方志 1 +x:1 +亲姐妹 1 +x:1 +玉米芯 1 +x:1 +好看 1 +x:1 +穗儿 1 +x:1 +订金 1 +x:1 +展销厅 1 +x:1 +放毒 1 +x:1 +车城 1 +x:1 +闹鬼 1 +x:1 +器皿 1 +x:1 +艺不压身 1 +x:1 +车场 1 +x:1 +用长避短 1 +x:1 +涌 139 +x:139 +布褂 1 +x:1 +来来去去 1 +x:1 +住房性 1 +x:1 +计经委 1 +x:1 +餐饮具 1 +x:1 +荒漠化 1 +x:1 +绿肥 1 +x:1 +为数不多 1 +x:1 +事项 1 +x:1 +青苔 1 +x:1 +南来北往 1 +x:1 +青苗 1 +x:1 +接力区 1 +x:1 +罢市 1 +x:1 +旮旯 1 +x:1 +青苞 1 +x:1 +炉灰 1 +x:1 +并联式 1 +x:1 +不虚此行 1 +x:1 +自咎 1 +x:1 +审计制 1 +x:1 +交流史 1 +x:1 +期货业 1 +x:1 +马莲 1 +x:1 +秋色 1 +x:1 +荒漠区 1 +x:1 +躺倒 1 +x:1 +和煦 1 +x:1 +七妈 1 +x:1 +公开栏 1 +x:1 +青花 1 +x:1 +追缉战 1 +x:1 +原配机 1 +x:1 +徒步走 1 +x:1 +联系会 1 +x:1 +风机 1 +x:1 +修枝 1 +x:1 +边儿 1 +x:1 +门洞 1 +x:1 +双辽 1 +x:1 +双边 1 +x:1 +风月 1 +x:1 +误差 1 +x:1 +八股文 1 +x:1 +耐受 1 +x:1 +鲈鱼 1 +x:1 +石斑鱼 1 +x:1 +误工 1 +x:1 +内伶仃岛 1 +x:1 +耳朵 1 +x:1 +腿 151 +x:151 +特技 1 +x:1 +模型 1 +x:1 +误己 1 +x:1 +名句 1 +x:1 +佐治亚州 1 +x:1 +殃及 1 +x:1 +差旅费 1 +x:1 +半子 1 +x:1 +广育 1 +x:1 +功高权重 1 +x:1 +肚兜 1 +x:1 +低幼 1 +x:1 +年底 1 +x:1 +奈良县 1 +x:1 +礼炮 1 +x:1 +球门区 1 +x:1 +电杆 1 +x:1 +家禽 1 +x:1 +漯河站 1 +x:1 +超高产 1 +x:1 +电板 1 +x:1 +碧绿如茵 1 +x:1 +蝎虎 1 +x:1 +拔乎其萃 1 +x:1 +洗菜池 1 +x:1 +起义军 1 +x:1 +镇隆村 1 +x:1 +低幅 1 +x:1 +粉蝶 1 +x:1 +被特许者 1 +x:1 +截肢 1 +x:1 +描写 1 +x:1 +在野 1 +x:1 +挨着 1 +x:1 +贪污腐化 1 +x:1 +感慨不已 1 +x:1 +李家巷 1 +x:1 +勤俭 1 +x:1 +别墅 1 +x:1 +六里桥 1 +x:1 +血袋 1 +x:1 +改判 1 +x:1 +吭气 1 +x:1 +立柱 1 +x:1 +偏头痛 1 +x:1 +全境 1 +x:1 +游泳 1 +x:1 +商品鸡 1 +x:1 +只言片语 1 +x:1 +改制 1 +x:1 +跳蝻 1 +x:1 +实物券 1 +x:1 +惟利是图 1 +x:1 +打非 1 +x:1 +五棵松 1 +x:1 +尼姑 1 +x:1 +退火 1 +x:1 +烟道式 1 +x:1 +改则 1 +x:1 +三字经 1 +x:1 +数九寒天 1 +x:1 +氨氮化菌 1 +x:1 +电木 1 +x:1 +客星 1 +x:1 +苏家屯 1 +x:1 +一口气 1 +x:1 +立柜 1 +x:1 +脊柱炎 1 +x:1 +小球 1 +x:1 +悬殊 1 +x:1 +四季常青 1 +x:1 +霜霉病 1 +x:1 +毫不利己 1 +x:1 +盘库 1 +x:1 +红土地 1 +x:1 +群起 1 +x:1 +铁力 1 +x:1 +摄录 1 +x:1 +禾木旁儿 1 +x:1 +时报 1 +x:1 +低廉 1 +x:1 +简陋型 1 +x:1 +武岭 1 +x:1 +新河 1 +x:1 +喷薄而出 1 +x:1 +空气轴承 1 +x:1 +矿泉井 1 +x:1 +离子 1 +x:1 +笑盈盈 1 +x:1 +游民 1 +x:1 +奥体 1 +x:1 +摄影 1 +x:1 +家祠 1 +x:1 +理事会制 1 +x:1 +物换星移 1 +x:1 +出场费 1 +x:1 +龙虎 1 +x:1 +打音 1 +x:1 +群贤 1 +x:1 +蛟河市 1 +x:1 +临澧县 1 +x:1 +低度 1 +x:1 +正好 1 +x:1 +母国 1 +x:1 +传统性 1 +x:1 +商品麦 1 +x:1 +用字 1 +x:1 +企业化 1 +x:1 +退烧 1 +x:1 +经世济民 1 +x:1 +潞西市 1 +x:1 +规规矩矩 1 +x:1 +龙虾 1 +x:1 +寄物单 1 +x:1 +铁勺 1 +x:1 +经纬线 1 +x:1 +双峰县 1 +x:1 +打圈子 1 +x:1 +简历 1 +x:1 +电晕 1 +x:1 +打防 1 +x:1 +经纬网 1 +x:1 +自画像 1 +x:1 +淋巴瘤 1 +x:1 +淮剧 1 +x:1 +勤于 1 +x:1 +铁匠 1 +x:1 +遂心如意 1 +x:1 +工贸部 1 +x:1 +存放 1 +x:1 +母土 1 +x:1 +服软 1 +x:1 +废钢铁 1 +x:1 +名作家 1 +x:1 +难为情 1 +x:1 +顿号 1 +x:1 +肚脐眼儿 1 +x:1 +艾尔索普 1 +x:1 +经纬编 1 +x:1 +话务费 1 +x:1 +专一性 1 +x:1 +怒涛澎湃 1 +x:1 +客机 1 +x:1 +影后 1 +x:1 +威慑 1 +x:1 +险些 1 +x:1 +蔡塘村 1 +x:1 +塘马 1 +x:1 +码子 1 +x:1 +常温动物 1 +x:1 +淋巴癌 1 +x:1 +采茶戏团 1 +x:1 +着火点 1 +x:1 +机关委 1 +x:1 +滦河 1 +x:1 +立春 1 +x:1 +堂名 1 +x:1 +改口 1 +x:1 +危险物品 1 +x:1 +偷电 1 +x:1 +简化 1 +x:1 +粗实 1 +x:1 +小白菜 1 +x:1 +汽浮法 1 +x:1 +伟 208 +x:208 +构造地震 1 +x:1 +老公公 1 +x:1 +铁厢 1 +x:1 +秋水长天 1 +x:1 +随形就势 1 +x:1 +酒盅 1 +x:1 +勤业 1 +x:1 +险乎 1 +x:1 +住店 1 +x:1 +深怀不满 1 +x:1 +冲锋 1 +x:1 +跳蚤 1 +x:1 +图纸 1 +x:1 +诗文抄 1 +x:1 +会猎 1 +x:1 +沙参 1 +x:1 +鸡尾酒 1 +x:1 +别处 1 +x:1 +薄片 1 +x:1 +打雷 1 +x:1 +名厨 1 +x:1 +钦羡 1 +x:1 +清清楚楚 1 +x:1 +研究馆员 1 +x:1 +简单 1 +x:1 +实验站 1 +x:1 +∥ 2 +x:2 +受不了 1 +x:1 +庙街 1 +x:1 +阿昌族 1 +x:1 +大大咧咧 1 +x:1 +委内瑞拉 1 +x:1 +游走不定 1 +x:1 +开发行 1 +x:1 +宰杀 1 +x:1 +调研室 1 +x:1 +嘉木 1 +x:1 +无党派 1 +x:1 +多智善谋 1 +x:1 +写本 1 +x:1 +晋江市 1 +x:1 +近现代馆 1 +x:1 +过河拆桥 1 +x:1 +四方区 1 +x:1 +洪水乡 1 +x:1 +电教 1 +x:1 +俏皮 1 +x:1 +新华街 1 +x:1 +世界性 1 +x:1 +啧啧 1 +x:1 +滑冰赛 1 +x:1 +洋洋洒洒 1 +x:1 +望诊 1 +x:1 +撑竿跳高 1 +x:1 +立方 1 +x:1 +绒毯 1 +x:1 +幼虫 1 +x:1 +桦甸市 1 +x:1 +床单厂 1 +x:1 +木廊 1 +x:1 +因了 1 +x:1 +遇到 1 +x:1 +嘁嘁喳喳 1 +x:1 +手机费 1 +x:1 +互为表里 1 +x:1 +遇刺 1 +x:1 +绒毛 1 +x:1 +木匠活 1 +x:1 +无动于衷 1 +x:1 +获赔 1 +x:1 +鲁斯塔克 1 +x:1 +幼虎 1 +x:1 +抵押金 1 +x:1 +半夜 1 +x:1 +凡 282 +x:282 +江畔 1 +x:1 +纳木错湖 1 +x:1 +赔钱 1 +x:1 +梯队 1 +x:1 +计数器 1 +x:1 +立时 1 +x:1 +野山菊 1 +x:1 +遇剌 1 +x:1 +藻潮 1 +x:1 +甥女 1 +x:1 +旅游船 1 +x:1 +荣立者 1 +x:1 +信用证 1 +x:1 +股票商 1 +x:1 +日程 1 +x:1 +退伍兵 1 +x:1 +维也纳市 1 +x:1 +一如继往 1 +x:1 +低射 1 +x:1 +毛白杨 1 +x:1 +偷盗 1 +x:1 +注释 1 +x:1 +长啸贯林 1 +x:1 +半天 1 +x:1 +冠军赛 1 +x:1 +天赋人权 1 +x:1 +核武库 1 +x:1 +半大 1 +x:1 +后车之鉴 1 +x:1 +唔 1 +x:1 +持 329 +x:329 +赏罚分明 1 +x:1 +光化学 1 +x:1 +有事 1 +x:1 +与会者 1 +x:1 +广船 1 +x:1 +雄视 1 +x:1 +椴树 1 +x:1 +蕴藏 1 +x:1 +游游 1 +x:1 +逐级 1 +x:1 +齐步 1 +x:1 +低峰 1 +x:1 +落地式 1 +x:1 +推荐书 1 +x:1 +均安 1 +x:1 +忧愤交加 1 +x:1 +锥 4 +x:4 +铁五局 1 +x:1 +关系式 1 +x:1 +黑色金属 1 +x:1 +画作 1 +x:1 +延川县 1 +x:1 +但求无过 1 +x:1 +才思 1 +x:1 +浮动感 1 +x:1 +累年 1 +x:1 +后面 1 +x:1 +廉洁关 1 +x:1 +打闹 1 +x:1 +磁感应 1 +x:1 +电料 1 +x:1 +昭和 1 +x:1 +电缆厂 1 +x:1 +闺阁情 1 +x:1 +统筹款 1 +x:1 +画传 1 +x:1 +五脏六腑 1 +x:1 +打问 1 +x:1 +火树金花 1 +x:1 +电文 1 +x:1 +均富 1 +x:1 +礼物 1 +x:1 +无力回天 1 +x:1 +典论 1 +x:1 +旅游节 1 +x:1 +轰炸 1 +x:1 +滩涂式 1 +x:1 +从者 1 +x:1 +传统戏 1 +x:1 +果蔬 1 +x:1 +游湖 1 +x:1 +样子 1 +x:1 +屿 1 +x:1 +水煤气 1 +x:1 +平武县 1 +x:1 +仿真 1 +x:1 +存有 1 +x:1 +画价 1 +x:1 +内膛嫁接 1 +x:1 +绞丝旁儿 1 +x:1 +王 6084 +x:6084 +谊 6 +x:6 +交友 1 +x:1 +疾病谱 1 +x:1 +窑池 1 +x:1 +某县 1 +x:1 +无毒品 1 +x:1 +兴衰 1 +x:1 +概括性 1 +x:1 +简写 1 +x:1 +追风逐电 1 +x:1 +嘴皮 1 +x:1 +斋品 1 +x:1 +回落 1 +x:1 +存本 1 +x:1 +批发商 1 +x:1 +囚款 1 +x:1 +准产证 1 +x:1 +指令长 1 +x:1 +礼士路 1 +x:1 +电视机 1 +x:1 +图籍 1 +x:1 +绕圈子 1 +x:1 +简况 1 +x:1 +通讯员 1 +x:1 +可食菌 1 +x:1 +摩纳哥 1 +x:1 +淋巴球 1 +x:1 +绿莹莹 1 +x:1 +家童 1 +x:1 +药棉 1 +x:1 +冈山县 1 +x:1 +人情美 1 +x:1 +小提琴 1 +x:1 +厌食者 1 +x:1 +风湿病学 1 +x:1 +黑台镇 1 +x:1 +悬案 1 +x:1 +药检 1 +x:1 +边防军 1 +x:1 +果蒂 1 +x:1 +画亭 1 +x:1 +无中生有 1 +x:1 +轰然 1 +x:1 +亚太地区 1 +x:1 +队伍 1 +x:1 +接受者 1 +x:1 +必也正名 1 +x:1 +全文型 1 +x:1 +舞弊者 1 +x:1 +湿热型 1 +x:1 +录取者 1 +x:1 +打钻 1 +x:1 +囚歌 1 +x:1 +酒瓶 1 +x:1 +悬梁 1 +x:1 +游离钙 1 +x:1 +刻板 1 +x:1 +接物镜 1 +x:1 +天高气爽 1 +x:1 +敌视 1 +x:1 +窜升 1 +x:1 +画乡 1 +x:1 +别字 1 +x:1 +乌钢 1 +x:1 +经纪行 1 +x:1 +喜鹊 1 +x:1 +伪书 1 +x:1 +黑黑的 1 +x:1 +逊而不俗 1 +x:1 +新闻组 1 +x:1 +粒粒 1 +x:1 +藏家人 1 +x:1 +圣何塞 1 +x:1 +谱系 1 +x:1 +偷看 1 +x:1 +纠偏 1 +x:1 +锯条 1 +x:1 +畜产 1 +x:1 +财神庙 1 +x:1 +妇女观 1 +x:1 +组胺 1 +x:1 +北航 1 +x:1 +调合油 1 +x:1 +受命 1 +x:1 +允许量 1 +x:1 +勇攀高峰 1 +x:1 +次发展极 1 +x:1 +白沙镇 1 +x:1 +围棋手 1 +x:1 +加气水泥 1 +x:1 +连推带拉 1 +x:1 +刻本 1 +x:1 +毫不相干 1 +x:1 +烷烃 1 +x:1 +切分 1 +x:1 +贸发局 1 +x:1 +执法队 1 +x:1 +受听 1 +x:1 +存查 1 +x:1 +改写 1 +x:1 +黑嘴鸥 1 +x:1 +零钞 1 +x:1 +刻有 1 +x:1 +顽 3 +x:3 +敞车 1 +x:1 +地皮费 1 +x:1 +大红帆 1 +x:1 +外资股 1 +x:1 +煽情式 1 +x:1 +睚眦必报 1 +x:1 +果菜 1 +x:1 +无性系 1 +x:1 +预防注射 1 +x:1 +行政权 1 +x:1 +名震一时 1 +x:1 +烟夜蛾 1 +x:1 +骑警 1 +x:1 +科学性 1 +x:1 +梯道 1 +x:1 +千伶百俐 1 +x:1 +成长期 1 +x:1 +执飞 1 +x:1 +边防团 1 +x:1 +画饼充饥 1 +x:1 +据以 1 +x:1 +空想论 1 +x:1 +林木 1 +x:1 +瓶罐 1 +x:1 +监考 1 +x:1 +心慈手软 1 +x:1 +百家姓 1 +x:1 +掉价儿 1 +x:1 +闲饭 1 +x:1 +红小豆 1 +x:1 +举手之劳 1 +x:1 +经销者 1 +x:1 +天差地别 1 +x:1 +荣誉章 1 +x:1 +林权 1 +x:1 +愚公移山 1 +x:1 +顶班 1 +x:1 +总之 1 +x:1 +客户 1 +x:1 +档儿 1 +x:1 +数得着 1 +x:1 +苛例 1 +x:1 +原庄村 1 +x:1 +泛 29 +x:29 +客房 1 +x:1 +改嘴 1 +x:1 +辑 33 +x:33 +欧裔 1 +x:1 +灰喜鹊 1 +x:1 +喀嚓 1 +x:1 +铁器 1 +x:1 +事务室 1 +x:1 +帮会 1 +x:1 +午宴 1 +x:1 +雪杨柳 1 +x:1 +六·一 1 +x:1 +迷蒙 1 +x:1 +贫壤瘠土 1 +x:1 +本本分分 1 +x:1 +回荡 1 +x:1 +跳荡 1 +x:1 +捻度 1 +x:1 +鱼价 1 +x:1 +语言 1 +x:1 +住室 1 +x:1 +挑拨离间 1 +x:1 +家累 1 +x:1 +林林 1 +x:1 +通讯史 1 +x:1 +化雨春风 1 +x:1 +龙舟 1 +x:1 +龙舞 1 +x:1 +置于脑后 1 +x:1 +面洽 1 +x:1 +林果 1 +x:1 +神通广大 1 +x:1 +含糖度 1 +x:1 +付诸东流 1 +x:1 +获评 1 +x:1 +永定河 1 +x:1 +体性 1 +x:1 +住宅 1 +x:1 +轮机长 1 +x:1 +游标 1 +x:1 +退而不休 1 +x:1 +龙船 1 +x:1 +将心比心 1 +x:1 +惠东 1 +x:1 +下编 1 +x:1 +堂兄 1 +x:1 +蹇 2 +x:2 +追悔 1 +x:1 +上升调 1 +x:1 +坍 7 +x:7 +在逃 1 +x:1 +半径 1 +x:1 +油剂 1 +x:1 +守旧派 1 +x:1 +才智 1 +x:1 +果茶 1 +x:1 +腾达队 1 +x:1 +面浆 1 +x:1 +德宏州 1 +x:1 +雄辩 1 +x:1 +置之不理 1 +x:1 +填筑 1 +x:1 +恍恍忽忽 1 +x:1 +马粪纸 1 +x:1 +唯才是举 1 +x:1 +竞争者 1 +x:1 +电孕乡 1 +x:1 +砖砾 1 +x:1 +水电费 1 +x:1 +铁撬棍 1 +x:1 +跳舞 1 +x:1 +变天账 1 +x:1 +菱镁矿 1 +x:1 +抽击 1 +x:1 +抽出 1 +x:1 +浮皮儿 1 +x:1 +延米 1 +x:1 +礼部郎 1 +x:1 +山姆大叔 1 +x:1 +电扇 1 +x:1 +登山运动 1 +x:1 +药源 1 +x:1 +金沙江 1 +x:1 +泉塘村 1 +x:1 +新法 1 +x:1 +长兴县 1 +x:1 +生产者 1 +x:1 +企业团 1 +x:1 +粉色 1 +x:1 +河北镇 1 +x:1 +白居寺 1 +x:1 +赛季 1 +x:1 +回航 1 +x:1 +串 91 +x:91 +剪贴本 1 +x:1 +四面体 1 +x:1 +愚氓 1 +x:1 +语论 1 +x:1 +肛道 1 +x:1 +世界杯 1 +x:1 +图稿 1 +x:1 +报知 1 +x:1 +任县 1 +x:1 +白白胖胖 1 +x:1 +领导者 1 +x:1 +含水量 1 +x:1 +烟筒 1 +x:1 +雄踞 1 +x:1 +眉棱骨 1 +x:1 +语话 1 +x:1 +谈笑风生 1 +x:1 +告状信 1 +x:1 +方块字 1 +x:1 +流金铄石 1 +x:1 +代名词 1 +x:1 +卤 1 +x:1 +总务处 1 +x:1 +脐橙 1 +x:1 +检修工 1 +x:1 +中译本 1 +x:1 +受助 1 +x:1 +连裆裤 1 +x:1 +劝解 1 +x:1 +收益 1 +x:1 +航道区 1 +x:1 +缺点 1 +x:1 +毒源地 1 +x:1 +款项 1 +x:1 +先前 1 +x:1 +瓜子仁 1 +x:1 +经学家 1 +x:1 +图章 1 +x:1 +独龙族 1 +x:1 +转给 1 +x:1 +罚不当罪 1 +x:1 +节能剂 1 +x:1 +例假 1 +x:1 +最后通牒 1 +x:1 +秋冬种 1 +x:1 +药渣 1 +x:1 +振 30 +x:30 +团支部 1 +x:1 +探望者 1 +x:1 +生硬 1 +x:1 +微机室 1 +x:1 +雪窦山 1 +x:1 +才望 1 +x:1 +面汤 1 +x:1 +空袭案 1 +x:1 +麻脸 1 +x:1 +俯视图 1 +x:1 +捕鱼量 1 +x:1 +攻破 1 +x:1 +昭和四年 1 +x:1 +电抗 1 +x:1 +屑 2 +x:2 +马瑙斯 1 +x:1 +执委 1 +x:1 +捕获量 1 +x:1 +才杰 1 +x:1 +受刑 1 +x:1 +水电路 1 +x:1 +花笺传 1 +x:1 +题名录 1 +x:1 +碗柜 1 +x:1 +改型 1 +x:1 +血账 1 +x:1 +角黍 1 +x:1 +据传 1 +x:1 +有价证券 1 +x:1 +大夹街 1 +x:1 +受制 1 +x:1 +庆云县 1 +x:1 +受到 1 +x:1 +粉芡 1 +x:1 +刻意 1 +x:1 +大忙人 1 +x:1 +跳脚 1 +x:1 +例句 1 +x:1 +戏票 1 +x:1 +伊斯兰人 1 +x:1 +师专 1 +x:1 +档卡 1 +x:1 +受凉 1 +x:1 +警钟长鸣 1 +x:1 +丰收乡 1 +x:1 +受助生 1 +x:1 +目镜 1 +x:1 +黄菠萝 1 +x:1 +一点钟 1 +x:1 +挥霍 1 +x:1 +破瓦寒窑 1 +x:1 +孤寡病残 1 +x:1 +住处 1 +x:1 +硝化甘油 1 +x:1 +活动桥 1 +x:1 +黑脸种 1 +x:1 +括号 1 +x:1 +嘉惠 1 +x:1 +监舍 1 +x:1 +存户 1 +x:1 +残留物 1 +x:1 +七拐八弯 1 +x:1 +窃电线 1 +x:1 +保满路 1 +x:1 +龙胆 1 +x:1 +堂叔 1 +x:1 +砖窑 1 +x:1 +微醉 1 +x:1 +龙胜 1 +x:1 +列举 1 +x:1 +布木格 1 +x:1 +抽动 1 +x:1 +两法 1 +x:1 +受冤 1 +x:1 +礼盒 1 +x:1 +梧桐 1 +x:1 +悬浮 1 +x:1 +平平的 1 +x:1 +城市贫民 1 +x:1 +存执 1 +x:1 +纺线 1 +x:1 +置若罔闻 1 +x:1 +河北队 1 +x:1 +修造 1 +x:1 +受冻 1 +x:1 +全人类 1 +x:1 +追车族 1 +x:1 +助纣为虐 1 +x:1 +扬基债 1 +x:1 +围嘴儿 1 +x:1 +咨询摊 1 +x:1 +世袭 1 +x:1 +师事 1 +x:1 +碧湛湛 1 +x:1 +劝言 1 +x:1 +低声 1 +x:1 +决策人员 1 +x:1 +战创伤 1 +x:1 +戏称 1 +x:1 +箭步 1 +x:1 +幼苗 1 +x:1 +和平郡 1 +x:1 +错误者 1 +x:1 +忙前忙后 1 +x:1 +下颌骨 1 +x:1 +电视报 1 +x:1 +报国无门 1 +x:1 +果腹 1 +x:1 +痛下决心 1 +x:1 +颌下腺 1 +x:1 +摇头晃脑 1 +x:1 +生态乡 1 +x:1 +创建人 1 +x:1 +经气 1 +x:1 +铺集镇 1 +x:1 +薄田 1 +x:1 +祈望 1 +x:1 +关系学 1 +x:1 +指数表 1 +x:1 +夹竹桃 1 +x:1 +午夜 1 +x:1 +三月份 1 +x:1 +幼芽 1 +x:1 +二元论 1 +x:1 +木麻黄 1 +x:1 +国术会 1 +x:1 +师从 1 +x:1 +置装费 1 +x:1 +大都市 1 +x:1 +龙联 1 +x:1 +事关全局 1 +x:1 +盘山 1 +x:1 +装修 1 +x:1 +水浮莲 1 +x:1 +百慕大 1 +x:1 +直井 1 +x:1 +函授大学 1 +x:1 +腿子 1 +x:1 +税企 1 +x:1 +打量 1 +x:1 +果脯 1 +x:1 +药浴 1 +x:1 +翼上 1 +x:1 +林旺 1 +x:1 +弦声 1 +x:1 +标志处 1 +x:1 +洋绣球 1 +x:1 +云豹 1 +x:1 +幼稚病 1 +x:1 +彭德怀 1 +x:1 +功力者 1 +x:1 +种子田 1 +x:1 +教科研 1 +x:1 +风范犹存 1 +x:1 +打造 1 +x:1 +账目 1 +x:1 +申报表 1 +x:1 +果胶 1 +x:1 +打通 1 +x:1 +抽取 1 +x:1 +逐笔 1 +x:1 +浮渡河 1 +x:1 +咨询日 1 +x:1 +笨 14 +x:14 +播 51 +x:51 +蔬 2 +x:2 +赔金 1 +x:1 +监管者 1 +x:1 +横道河子 1 +x:1 +面源 1 +x:1 +黄皮寡瘦 1 +x:1 +选举法 1 +x:1 +债 81 +x:81 +山苍子 1 +x:1 +男子化 1 +x:1 +龙川县 1 +x:1 +优免证 1 +x:1 +黑 275 +x:275 +翼侧 1 +x:1 +寓存 1 +x:1 +淫荡 1 +x:1 +远地点 1 +x:1 +渎职罪 1 +x:1 +低头 1 +x:1 +阿图什市 1 +x:1 +果肉 1 +x:1 +劝说 1 +x:1 +劝诱 1 +x:1 +扫平 1 +x:1 +南钢队 1 +x:1 +欧洲区 1 +x:1 +敬 56 +x:56 +戏码 1 +x:1 +烽火连天 1 +x:1 +补牙法 1 +x:1 +建设者 1 +x:1 +劝诫 1 +x:1 +怀宁县 1 +x:1 +龙脉 1 +x:1 +印方 1 +x:1 +和平里 1 +x:1 +黄泥河 1 +x:1 +延续 1 +x:1 +防化学兵 1 +x:1 +婆婆妈妈 1 +x:1 +厅局长 1 +x:1 +枯水区 1 +x:1 +马儿山 1 +x:1 +延绵 1 +x:1 +工装裤 1 +x:1 +叠落 1 +x:1 +蒲圻市 1 +x:1 +同盟会 1 +x:1 +偷猎 1 +x:1 +扇子 1 +x:1 +桑果 1 +x:1 +糍粑 1 +x:1 +男 327 +x:327 +[ 8 +x:8 +木工 1 +x:1 +饱经忧患 1 +x:1 +主要方 1 +x:1 +自我标榜 1 +x:1 +半岛 1 +x:1 +意味隽永 1 +x:1 +英武 1 +x:1 +偷盗者 1 +x:1 +战绩 1 +x:1 +常用字 1 +x:1 +冀南 1 +x:1 +叫法 1 +x:1 +文艺批评 1 +x:1 +廉正风 1 +x:1 +经济 1 +x:1 +五环队 1 +x:1 +葭 1 +x:1 +改善 1 +x:1 +群言 1 +x:1 +红庙 1 +x:1 +白发翁 1 +x:1 +祛病除灾 1 +x:1 +执勤者 1 +x:1 +交互式 1 +x:1 +粉肠 1 +x:1 +彻 5 +x:5 +销货额 1 +x:1 +悬挂 1 +x:1 +打鼾 1 +x:1 +孙男嫡女 1 +x:1 +被盗案 1 +x:1 +延寿桃 1 +x:1 +办案人 1 +x:1 +纸屑 1 +x:1 +监察组 1 +x:1 +非财政 1 +x:1 +高城镇 1 +x:1 +枝江市 1 +x:1 +佑助 1 +x:1 +海枣 1 +x:1 +广袤 1 +x:1 +咎谴 1 +x:1 +住地 1 +x:1 +龙身 1 +x:1 +酒罐 1 +x:1 +砖瓦 1 +x:1 +养植 1 +x:1 +打鼓 1 +x:1 +会章 1 +x:1 +通讯录 1 +x:1 +抵雪 1 +x:1 +最低限 1 +x:1 +纠察 1 +x:1 +观测网 1 +x:1 +小伙儿 1 +x:1 +报端 1 +x:1 +迅 5 +x:5 +税收收入 1 +x:1 +报童 1 +x:1 +报名者 1 +x:1 +动真格 1 +x:1 +血肉 1 +x:1 +酒缸 1 +x:1 +报章 1 +x:1 +税收率 1 +x:1 +出头露面 1 +x:1 +轰隆轰隆 1 +x:1 +客游 1 +x:1 +城隍 1 +x:1 +非同凡响 1 +x:1 +风雨兼程 1 +x:1 +告示 1 +x:1 +吐 75 +x:75 +王营 1 +x:1 +上升股 1 +x:1 +洛阳市 1 +x:1 +酒缘 1 +x:1 +沼 1 +x:1 +邪气 1 +x:1 +影视城 1 +x:1 +回转 1 +x:1 +家燕 1 +x:1 +碗橱 1 +x:1 +抗癌药 1 +x:1 +求同克异 1 +x:1 +犒赏 1 +x:1 +血肿 1 +x:1 +企业家 1 +x:1 +红岩村 1 +x:1 +付与 1 +x:1 +客满 1 +x:1 +验 30 +x:30 +俊男靓女 1 +x:1 +东旧寨镇 1 +x:1 +捐赠 1 +x:1 +潼南县 1 +x:1 +土司 1 +x:1 +组诗 1 +x:1 +单间儿 1 +x:1 +跟着 1 +x:1 +堪忧 1 +x:1 +真人真事 1 +x:1 +改嫁 1 +x:1 +近现代 1 +x:1 +适用 1 +x:1 +三鹤村 1 +x:1 +军体拳 1 +x:1 +沼液叶喷 1 +x:1 +抽屉 1 +x:1 +回还 1 +x:1 +尼共 1 +x:1 +辩驳 1 +x:1 +摩天大楼 1 +x:1 +回返 1 +x:1 +衣裙 1 +x:1 +西航道 1 +x:1 +大得人心 1 +x:1 +国旗班 1 +x:1 +回迁 1 +x:1 +名功 1 +x:1 +统一 1 +x:1 +招引 1 +x:1 +佤族 1 +x:1 +组训 1 +x:1 +经手 1 +x:1 +选择 1 +x:1 +实验班 1 +x:1 +丹霞山 1 +x:1 +评书 1 +x:1 +妇女节 1 +x:1 +客源 1 +x:1 +婷 9 +x:9 +数九寒冬 1 +x:1 +东影村 1 +x:1 +种子站 1 +x:1 +新鲜度 1 +x:1 +炒豆子 1 +x:1 +巨黄色 1 +x:1 +授人以柄 1 +x:1 +辽宁路 1 +x:1 +巴勒斯坦 1 +x:1 +不计其数 1 +x:1 +报箱 1 +x:1 +盘式 1 +x:1 +摘金 1 +x:1 +铁东区 1 +x:1 +内夯 1 +x:1 +均值 1 +x:1 +渐开线 1 +x:1 +有售 1 +x:1 +存活 1 +x:1 +△ 50 +x:50 +代理人 1 +x:1 +化工部 1 +x:1 +综观 1 +x:1 +器械 1 +x:1 +点菜 1 +x:1 +活动月 1 +x:1 +宪政 1 +x:1 +统供 1 +x:1 +如花似玉 1 +x:1 +蓉 4 +x:4 +运销业 1 +x:1 +橄榄型 1 +x:1 +全市 1 +x:1 +馆际 1 +x:1 +足智多谋 1 +x:1 +活动期 1 +x:1 +低地 1 +x:1 +肩章 1 +x:1 +经援 1 +x:1 +冀州 1 +x:1 +格登山 1 +x:1 +耍流氓 1 +x:1 +赛地 1 +x:1 +乐迷 1 +x:1 +养路费 1 +x:1 +馆陶 1 +x:1 +喜钱 1 +x:1 +赛场 1 +x:1 +退票 1 +x:1 +起电盘 1 +x:1 +广角 1 +x:1 +庇护 1 +x:1 +出生证 1 +x:1 +摒弃 1 +x:1 +遮阳网 1 +x:1 +方糖 1 +x:1 +水程 1 +x:1 +戏目 1 +x:1 +树鹨 1 +x:1 +社仓 1 +x:1 +跑马卖解 1 +x:1 +渗透 1 +x:1 +销售场 1 +x:1 +彩布条 1 +x:1 +稍 165 +x:165 +标志型 1 +x:1 +忻州 1 +x:1 +代理业 1 +x:1 +七里塔 1 +x:1 +铁定 1 +x:1 +寂静 1 +x:1 +排除法 1 +x:1 +金溪 1 +x:1 +宜昌港 1 +x:1 +血腥 1 +x:1 +保修包换 1 +x:1 +踝关节 1 +x:1 +药房 1 +x:1 +声如银铃 1 +x:1 +回身 1 +x:1 +坪上 1 +x:1 +一望无涯 1 +x:1 +胎具 1 +x:1 +发现号 1 +x:1 +西河北 1 +x:1 +广西 1 +x:1 +一应俱全 1 +x:1 +忧愁 1 +x:1 +被保险人 1 +x:1 +血脉 1 +x:1 +电源 1 +x:1 +颜家屯村 1 +x:1 +堂屋 1 +x:1 +署理 1 +x:1 +群落 1 +x:1 +全年 1 +x:1 +南北纬 1 +x:1 +星际 1 +x:1 +菜 347 +x:347 +飞来峡 1 +x:1 +红头 1 +x:1 +贴补 1 +x:1 +警通队 1 +x:1 +闲钱 1 +x:1 +美学家 1 +x:1 +求索集 1 +x:1 +鄂伦春乡 1 +x:1 +带兵论 1 +x:1 +龙车 1 +x:1 +攻球 1 +x:1 +报答 1 +x:1 +水库区 1 +x:1 +这么样 1 +x:1 +雄花 1 +x:1 +航道局 1 +x:1 +自学成才 1 +x:1 +套数 1 +x:1 +寻衅滋事 1 +x:1 +糖块 1 +x:1 +退税 1 +x:1 +购货本 1 +x:1 +忆昔抚今 1 +x:1 +均匀 1 +x:1 +一席话 1 +x:1 +肚子 1 +x:1 +百依百顺 1 +x:1 +碧海 1 +x:1 +辩题 1 +x:1 +回贺 1 +x:1 +矿渣厂 1 +x:1 +全军覆灭 1 +x:1 +北安市 1 +x:1 +杂乱无章 1 +x:1 +面授 1 +x:1 +游泳池 1 +x:1 +关系型 1 +x:1 +舰 14 +x:14 +名下无虚 1 +x:1 +脱胎换骨 1 +x:1 +感受器 1 +x:1 +卡勒瓦 1 +x:1 +退稿 1 +x:1 +陆地 1 +x:1 +仃 8 +x:8 +图画 1 +x:1 +正电子 1 +x:1 +建设费 1 +x:1 +溢美之词 1 +x:1 +核装置 1 +x:1 +铁塔 1 +x:1 +钝响 1 +x:1 +庄稼汉 1 +x:1 +赚 168 +x:168 +添置 1 +x:1 +收发组 1 +x:1 +绣 17 +x:17 +协力会 1 +x:1 +浸透 1 +x:1 +圣人 1 +x:1 +监票人 1 +x:1 +罂粟 1 +x:1 +砖皮 1 +x:1 +馆长 1 +x:1 +客气 1 +x:1 +扰 5 +x:5 +粒界 1 +x:1 +踩鼓堂 1 +x:1 +繁荣富强 1 +x:1 +载客率 1 +x:1 +紫砂陶 1 +x:1 +汀线 1 +x:1 +不知者 1 +x:1 +核武器 1 +x:1 +明达 1 +x:1 +黄袍加身 1 +x:1 +才思敏捷 1 +x:1 +跳越 1 +x:1 +花场峪村 1 +x:1 +堂弟 1 +x:1 +环幕 1 +x:1 +南化塘镇 1 +x:1 +开县 1 +x:1 +水杨酸 1 +x:1 +政群 1 +x:1 +西固区 1 +x:1 +带分数 1 +x:1 +筛拣 1 +x:1 +祁阳 1 +x:1 +各自 1 +x:1 +一年一度 1 +x:1 +记者组 1 +x:1 +低哑 1 +x:1 +徽州市 1 +x:1 +通信站 1 +x:1 +势利眼 1 +x:1 +羯羊 1 +x:1 +祭祀坑 1 +x:1 +成因 1 +x:1 +企业处 1 +x:1 +三接头 1 +x:1 +茶叶花 1 +x:1 +曹娥江畔 1 +x:1 +逐户 1 +x:1 +硼钢 1 +x:1 +统供率 1 +x:1 +跳跃 1 +x:1 +会计法 1 +x:1 +支付卡 1 +x:1 +赤胆忠心 1 +x:1 +血性汉子 1 +x:1 +括弧 1 +x:1 +穆迪拉 1 +x:1 +灰黄霉素 1 +x:1 +血口喷人 1 +x:1 +地皮菜 1 +x:1 +那里 1 +x:1 +跳跳 1 +x:1 +提货人 1 +x:1 +非经营性 1 +x:1 +回路 1 +x:1 +砚雕 1 +x:1 +茶叶节 1 +x:1 +果质 1 +x:1 +中小企业 1 +x:1 +真实感 1 +x:1 +填鸭式 1 +x:1 +檄文 1 +x:1 +家犬 1 +x:1 +缝纫机 1 +x:1 +酒类 1 +x:1 +均分 1 +x:1 +原油价 1 +x:1 +专修 1 +x:1 +电汇 1 +x:1 +堂庙 1 +x:1 +三从一大 1 +x:1 +实话 1 +x:1 +通讯局 1 +x:1 +民族自治 1 +x:1 +林校 1 +x:1 +北大营村 1 +x:1 +字符集 1 +x:1 +记者网 1 +x:1 +别史 1 +x:1 +砖石 1 +x:1 +别号 1 +x:1 +铁头 1 +x:1 +销赃 1 +x:1 +硼镁 1 +x:1 +易地 1 +x:1 +炽 2 +x:2 +电池 1 +x:1 +喜雨 1 +x:1 +老规矩 1 +x:1 +改天 1 +x:1 +接管部 1 +x:1 +皮损 1 +x:1 +打鱼 1 +x:1 +电气 1 +x:1 +摊 57 +x:57 +哥伦布市 1 +x:1 +祖母绿 1 +x:1 +形单影只 1 +x:1 +欧洲式 1 +x:1 +城乡游 1 +x:1 +二宫乡 1 +x:1 +捐躯 1 +x:1 +故纸堆 1 +x:1 +净角 1 +x:1 +赖以生存 1 +x:1 +客死他乡 1 +x:1 +标新立异 1 +x:1 +烯烃厂 1 +x:1 +二话没说 1 +x:1 +坡岗地 1 +x:1 +展览城 1 +x:1 +超重者 1 +x:1 +石铲 1 +x:1 +论罪 1 +x:1 +擅于 1 +x:1 +庙舍 1 +x:1 +组装 1 +x:1 +铁厂 1 +x:1 +水利枢纽 1 +x:1 +受屈 1 +x:1 +闲雅 1 +x:1 +涉及面 1 +x:1 +报社 1 +x:1 +零3分 1 +x:1 +实证 1 +x:1 +义乌市 1 +x:1 +杂货铺 1 +x:1 +手背 1 +x:1 +盐碱土 1 +x:1 +群虎 1 +x:1 +退管 1 +x:1 +遇害 1 +x:1 +均势 1 +x:1 +酒糟 1 +x:1 +活动日 1 +x:1 +电泳 1 +x:1 +盐碱地 1 +x:1 +先导性 1 +x:1 +双增双提 1 +x:1 +育 84 +x:84 +抓住 1 +x:1 +输血 1 +x:1 +南锡国家 1 +x:1 +电波 1 +x:1 +北普陀 1 +x:1 +景行行止 1 +x:1 +十二生肖 1 +x:1 +二郎庙 1 +x:1 +酒精 1 +x:1 +松毛虫 1 +x:1 +波茨坦 1 +x:1 +裁 16 +x:16 +违章户 1 +x:1 +午后 1 +x:1 +铁委 1 +x:1 +相关度 1 +x:1 +大娄山区 1 +x:1 +金台西路 1 +x:1 +女友 1 +x:1 +嬉笑怒骂 1 +x:1 +岁月悠悠 1 +x:1 +光顾者 1 +x:1 +年轻人 1 +x:1 +会礼 1 +x:1 +闭幕式 1 +x:1 +春秋笔法 1 +x:1 +受尽 1 +x:1 +论理 1 +x:1 +斧头 1 +x:1 +存栏 1 +x:1 +引经据典 1 +x:1 +毫不费力 1 +x:1 +摄氏度 1 +x:1 +风和日暖 1 +x:1 +二环路 1 +x:1 +陆岛 1 +x:1 +那霸 1 +x:1 +受寒 1 +x:1 +隐士 1 +x:1 +摄取 1 +x:1 +花梨木 1 +x:1 +赛前 1 +x:1 +海盐县 1 +x:1 +鱼水情 1 +x:1 +钱内助 1 +x:1 +彩图 1 +x:1 +过世 1 +x:1 +跟班 1 +x:1 +存根 1 +x:1 +才源 1 +x:1 +展销价 1 +x:1 +应用率 1 +x:1 +南北对话 1 +x:1 +度德量力 1 +x:1 +里通外国 1 +x:1 +台阶式 1 +x:1 +岂但 1 +x:1 +晋江县 1 +x:1 +斋宫 1 +x:1 +雄蜂 1 +x:1 +影视史 1 +x:1 +祎 1 +x:1 +母婴 1 +x:1 +感人心者 1 +x:1 +铁幕 1 +x:1 +半圆 1 +x:1 +砂型 1 +x:1 +薄父母 1 +x:1 +例如 1 +x:1 +报经 1 +x:1 +赛制 1 +x:1 +无毒害 1 +x:1 +受宠 1 +x:1 +存档 1 +x:1 +六盘水 1 +x:1 +旱烟袋 1 +x:1 +麓 6 +x:6 +由始至终 1 +x:1 +白发皤然 1 +x:1 +下跌股 1 +x:1 +受害 1 +x:1 +乐曲声 1 +x:1 +转眼 1 +x:1 +叫板 1 +x:1 +兴辞 1 +x:1 +戏班 1 +x:1 +喜酒 1 +x:1 +齐整 1 +x:1 +丑恶 1 +x:1 +家用 1 +x:1 +铁床 1 +x:1 +- 15 +x:15 +不定根 1 +x:1 +广谱 1 +x:1 +牡丹节 1 +x:1 +段位 1 +x:1 +硬仗 1 +x:1 +受孕 1 +x:1 +改建 1 +x:1 +简帖 1 +x:1 +家电 1 +x:1 +识货者 1 +x:1 +襄樊 1 +x:1 +制造业界 1 +x:1 +淋巴管 1 +x:1 +峥嵘岁月 1 +x:1 +彩团 1 +x:1 +非意愿 1 +x:1 +酒篓 1 +x:1 +金玉满堂 1 +x:1 +浦东 1 +x:1 +不含糊 1 +x:1 +选举权 1 +x:1 +硬件 1 +x:1 +相应物 1 +x:1 +天作之合 1 +x:1 +主麻日 1 +x:1 +恩格斯 1 +x:1 +病倒 1 +x:1 +牡丹花 1 +x:1 +嚼 24 +x:24 +家生 1 +x:1 +十字线 1 +x:1 +社会名流 1 +x:1 +气度美 1 +x:1 +回话 1 +x:1 +水泥钉 1 +x:1 +静若处子 1 +x:1 +松果腺 1 +x:1 +解说员 1 +x:1 +海德拉巴 1 +x:1 +别名 1 +x:1 +与世无争 1 +x:1 +水禽 1 +x:1 +司令部 1 +x:1 +惯懒 1 +x:1 +柴一 1 +x:1 +药材 1 +x:1 +堂奥 1 +x:1 +千娇百媚 1 +x:1 +转瞬 1 +x:1 +香雪斋 1 +x:1 +下颌部 1 +x:1 +回请 1 +x:1 +丑态 1 +x:1 +监装 1 +x:1 +例外 1 +x:1 +输水道 1 +x:1 +敬老篷 1 +x:1 +家畜 1 +x:1 +木管乐器 1 +x:1 +起早摸黑 1 +x:1 +装箱人 1 +x:1 +微机化 1 +x:1 +石龙头村 1 +x:1 +土特产 1 +x:1 +岂不 1 +x:1 +东大街 1 +x:1 +青枯病 1 +x:1 +唐 629 +x:629 +笔墨纸砚 1 +x:1 +徒劳无益 1 +x:1 +瓦伦西亚 1 +x:1 +纠建 1 +x:1 +见高低 1 +x:1 +拉练 1 +x:1 +项圈 1 +x:1 +工时费 1 +x:1 +惯性 1 +x:1 +非体育 1 +x:1 +藻思 1 +x:1 +图版 1 +x:1 +薄纸 1 +x:1 +圆通 1 +x:1 +丝毫不少 1 +x:1 +图片 1 +x:1 +科学楼 1 +x:1 +统治区 1 +x:1 +近代化史 1 +x:1 +闲逛 1 +x:1 +中研部 1 +x:1 +张集矿 1 +x:1 +剥离 1 +x:1 +供应权 1 +x:1 +捣固焦 1 +x:1 +换言之 1 +x:1 +伤病员 1 +x:1 +委办局 1 +x:1 +赛区 1 +x:1 +杜甫 1 +x:1 +沿边儿 1 +x:1 +珲春 1 +x:1 +母子 1 +x:1 +发现地 1 +x:1 +铁锁链 1 +x:1 +次数 1 +x:1 +同性恋 1 +x:1 +立模 1 +x:1 +堂堂 1 +x:1 +多数派 1 +x:1 +杏林区 1 +x:1 +从轻 1 +x:1 +灵隐寺 1 +x:1 +合围 1 +x:1 +午前 1 +x:1 +祈求 1 +x:1 +转盘 1 +x:1 +赛史 1 +x:1 +抽奖 1 +x:1 +浓彩淡染 1 +x:1 +籽粒 1 +x:1 +新罗区 1 +x:1 +经期 1 +x:1 +群聚 1 +x:1 +瓶盖 1 +x:1 +釉子 1 +x:1 +羽绒被 1 +x:1 +打骂 1 +x:1 +监狱长 1 +x:1 +左面 1 +x:1 +病假 1 +x:1 +待字闺中 1 +x:1 +铁心 1 +x:1 +抗癌 1 +x:1 +道岔厂 1 +x:1 +拆洗 1 +x:1 +账簿 1 +x:1 +叙述体 1 +x:1 +红10师 1 +x:1 +触景伤情 1 +x:1 +称赞声 1 +x:1 +不露声色 1 +x:1 +平行面 1 +x:1 +遮阳篷 1 +x:1 +莫此为甚 1 +x:1 +酒窖 1 +x:1 +低压 1 +x:1 +劝劝 1 +x:1 +酒窝 1 +x:1 +嗓子 1 +x:1 +策勒 1 +x:1 +赞不绝口 1 +x:1 +喜逢 1 +x:1 +匍匐 1 +x:1 +讨 47 +x:47 +摄制 1 +x:1 +乐不思蜀 1 +x:1 +竺 3 +x:3 +松花江 1 +x:1 +偷窥 1 +x:1 +发呆 1 +x:1 +龙袍 1 +x:1 +恶霸地主 1 +x:1 +起伏跌宕 1 +x:1 +戏照 1 +x:1 +选举日 1 +x:1 +马泉河 1 +x:1 +调研员 1 +x:1 +文明礼貌 1 +x:1 +车把势 1 +x:1 +二月 1 +x:1 +去粗取精 1 +x:1 +汲冢镇 1 +x:1 +使性子 1 +x:1 +光通信 1 +x:1 +偷窃 1 +x:1 +拼音文字 1 +x:1 +人非草木 1 +x:1 +画具费 1 +x:1 +血印儿 1 +x:1 +结业率 1 +x:1 +意味 1 +x:1 +实验田 1 +x:1 +低做 1 +x:1 +衣袋 1 +x:1 +药方 1 +x:1 +身高 1 +x:1 +档子 1 +x:1 +别国 1 +x:1 +仪征人 1 +x:1 +涑水 1 +x:1 +杆 45 +x:45 +播撒地 1 +x:1 +铁屑 1 +x:1 +说笑声 1 +x:1 +关系史 1 +x:1 +电椅 1 +x:1 +麻酥酥 1 +x:1 +抑菌作用 1 +x:1 +草绿色 1 +x:1 +通讯处 1 +x:1 +斧子 1 +x:1 +水稻 1 +x:1 +引滦入津 1 +x:1 +客栈 1 +x:1 +转用 1 +x:1 +累加 1 +x:1 +林海 1 +x:1 +穴位 1 +x:1 +边防局 1 +x:1 +核物理所 1 +x:1 +嘉言懿行 1 +x:1 +受奖 1 +x:1 +商品部 1 +x:1 +信息员 1 +x:1 +控制室 1 +x:1 +衷爱 1 +x:1 +家眷 1 +x:1 +形似 1 +x:1 +输赢 1 +x:1 +分数线 1 +x:1 +林涛 1 +x:1 +征税人 1 +x:1 +早点摊儿 1 +x:1 +笃志好学 1 +x:1 +攻坚乡 1 +x:1 +桧仓 1 +x:1 +记者站 1 +x:1 +忍无可忍 1 +x:1 +偷税 1 +x:1 +摄入 1 +x:1 +铁岭 1 +x:1 +议 55 +x:55 +才气 1 +x:1 +保卫者 1 +x:1 +例子 1 +x:1 +茶叶蛋 1 +x:1 +分离式 1 +x:1 +打馅 1 +x:1 +制裁法 1 +x:1 +面条 1 +x:1 +感受力 1 +x:1 +药效 1 +x:1 +倨傲 1 +x:1 +简屋 1 +x:1 +耐久 1 +x:1 +警醒 1 +x:1 +仲家 1 +x:1 +独角戏 1 +x:1 +杂烩 1 +x:1 +估测 1 +x:1 +面板 1 +x:1 +馆里 1 +x:1 +已逝者 1 +x:1 +回视 1 +x:1 +攫鼠 1 +x:1 +平面镜 1 +x:1 +迎新面 1 +x:1 +先哲 1 +x:1 +贝加尔 1 +x:1 +一纸空文 1 +x:1 +温莎宫 1 +x:1 +箱包 1 +x:1 +旅游车 1 +x:1 +摄像 1 +x:1 +累及 1 +x:1 +昭然若揭 1 +x:1 +创业潮 1 +x:1 +硼酸 1 +x:1 +琼岛 1 +x:1 +心知肚明 1 +x:1 +危房 1 +x:1 +群英 1 +x:1 +刻毒 1 +x:1 +凝聚剂 1 +x:1 +经文 1 +x:1 +退缩 1 +x:1 +沭 1 +x:1 +贬 16 +x:16 +上水道 1 +x:1 +存款 1 +x:1 +羽毛缎 1 +x:1 +电桥 1 +x:1 +金枝玉叶 1 +x:1 +雷暴 1 +x:1 +全州 1 +x:1 +蚁穴 1 +x:1 +做月子 1 +x:1 +乔治王岛 1 +x:1 +通史展 1 +x:1 +滑冰者 1 +x:1 +是样儿 1 +x:1 +管护节 1 +x:1 +母女 1 +x:1 +群芳 1 +x:1 +广远 1 +x:1 +台式机 1 +x:1 +食道癌 1 +x:1 +前列腺 1 +x:1 +光电子学 1 +x:1 +旧刊本 1 +x:1 +起跑地 1 +x:1 +崮山镇 1 +x:1 +电话机 1 +x:1 +言传身教 1 +x:1 +就此而言 1 +x:1 +叶片锁 1 +x:1 +栅 1 +x:1 +爪儿 1 +x:1 +企业局 1 +x:1 +前巷队 1 +x:1 +注册厅 1 +x:1 +惯技 1 +x:1 +急救险 1 +x:1 +低凹 1 +x:1 +无名指 1 +x:1 +针打式 1 +x:1 +经改 1 +x:1 +三河尖 1 +x:1 +快艇 1 +x:1 +建军节 1 +x:1 +血液病学 1 +x:1 +馆邸 1 +x:1 +数据源 1 +x:1 +河务局 1 +x:1 +拾音器 1 +x:1 +商品量 1 +x:1 +走江湖 1 +x:1 +青口镇 1 +x:1 +立档 1 +x:1 +丸药 1 +x:1 +非结盟 1 +x:1 +种植户 1 +x:1 +枯水季 1 +x:1 +班主任 1 +x:1 +刻款 1 +x:1 +盗伐 1 +x:1 +农奴主 1 +x:1 +铁工 1 +x:1 +赛况 1 +x:1 +传宗接代 1 +x:1 +物 200 +x:200 +书杂费 1 +x:1 +立案 1 +x:1 +群舞 1 +x:1 +电梯 1 +x:1 +松花湖 1 +x:1 +面乎乎 1 +x:1 +扭曲仪 1 +x:1 +黝红 1 +x:1 +合伙人 1 +x:1 +拍卖场 1 +x:1 +凝聚力 1 +x:1 +萝芙木 1 +x:1 +进退留转 1 +x:1 +藤球队 1 +x:1 +精兵强将 1 +x:1 +装备 1 +x:1 +雄魂 1 +x:1 +珠环 1 +x:1 +于田城 1 +x:1 +画工 1 +x:1 +田东县 1 +x:1 +打蜡 1 +x:1 +酒杯 1 +x:1 +骈文 1 +x:1 +闲赋 1 +x:1 +窑罐 1 +x:1 +泰山市 1 +x:1 +人言可畏 1 +x:1 +转正 1 +x:1 +种草 1 +x:1 +竹种园 1 +x:1 +小票 1 +x:1 +星辰 1 +x:1 +密歇根州 1 +x:1 +珠玑 1 +x:1 +遗毒 1 +x:1 +切合 1 +x:1 +权威 1 +x:1 +过路财神 1 +x:1 +文理工科 1 +x:1 +收市 1 +x:1 +勤快 1 +x:1 +特效 1 +x:1 +撞倒 1 +x:1 +面积 1 +x:1 +上挂下联 1 +x:1 +增长图 1 +x:1 +祈使句 1 +x:1 +喜筵 1 +x:1 +匡扶 1 +x:1 +员 77 +x:77 +导磁率 1 +x:1 +演丰镇 1 +x:1 +电眼 1 +x:1 +云鬓 1 +x:1 +情真意挚 1 +x:1 +量子力学 1 +x:1 +视神经 1 +x:1 +省吃俭用 1 +x:1 +边角料 1 +x:1 +三官庙 1 +x:1 +艰苦创业 1 +x:1 +塑料袋 1 +x:1 +上山下乡 1 +x:1 +渎职案 1 +x:1 +四盐矿 1 +x:1 +三轮摩托 1 +x:1 +浩茫 1 +x:1 +焊接件 1 +x:1 +栖居 1 +x:1 +监票员 1 +x:1 +福相 1 +x:1 +会所 1 +x:1 +投书者 1 +x:1 +旅游部 1 +x:1 +跳鞋 1 +x:1 +矿坑 1 +x:1 +万里长城 1 +x:1 +满腹牢骚 1 +x:1 +多渠道 1 +x:1 +炼铁厂 1 +x:1 +点铁成金 1 +x:1 +紫台山 1 +x:1 +游击战 1 +x:1 +赌博业 1 +x:1 +小儿科 1 +x:1 +广通 1 +x:1 +甫入 1 +x:1 +老谋深算 1 +x:1 +电石 1 +x:1 +穷山僻壤 1 +x:1 +理念 1 +x:1 +松柏乡 1 +x:1 +树木园 1 +x:1 +险弹 1 +x:1 +自告奋勇 1 +x:1 +黄页 1 +x:1 +午休 1 +x:1 +红庙李村 1 +x:1 +拌 21 +x:21 +低产 1 +x:1 +会战 1 +x:1 +良种化 1 +x:1 +阿肯色州 1 +x:1 +赛事 1 +x:1 +硬功 1 +x:1 +独有 1 +x:1 +筝 1 +x:1 +药筒 1 +x:1 +柴刀 1 +x:1 +西红柿 1 +x:1 +④ 16 +x:16 +椰影 1 +x:1 +收入数 1 +x:1 +钢支柱 1 +x:1 +林班 1 +x:1 +回音 1 +x:1 +喜贺 1 +x:1 +早籼稻 1 +x:1 +挥臂 1 +x:1 +饱 47 +x:47 +一抢而光 1 +x:1 +志存高远 1 +x:1 +挺进 1 +x:1 +低云 1 +x:1 +配线架 1 +x:1 +知识点 1 +x:1 +抵近 1 +x:1 +退意 1 +x:1 +酒智 1 +x:1 +卧虎形 1 +x:1 +涓 3 +x:3 +下阳乡 1 +x:1 +济助星 1 +x:1 +普沃茨克 1 +x:1 +获鹿 1 +x:1 +解囊相助 1 +x:1 +硬卧 1 +x:1 +鞭挞 1 +x:1 +低位 1 +x:1 +鱼子 1 +x:1 +增长型 1 +x:1 +回防 1 +x:1 +毛孔 1 +x:1 +钳 2 +x:2 +面碗 1 +x:1 +纵 30 +x:30 +砖混 1 +x:1 +师大 1 +x:1 +据守 1 +x:1 +全年度 1 +x:1 +捐钱 1 +x:1 +电视界 1 +x:1 +寇 29 +x:29 +富拉尔基 1 +x:1 +努嘴 1 +x:1 +赛会 1 +x:1 +库务局 1 +x:1 +立目 1 +x:1 +硬化 1 +x:1 +浦口 1 +x:1 +露脐装 1 +x:1 +症候 1 +x:1 +据实 1 +x:1 +遮阳板 1 +x:1 +开天辟地 1 +x:1 +蝾螈 1 +x:1 +闲谈 1 +x:1 +牙音 1 +x:1 +电线杆 1 +x:1 +抵达 1 +x:1 +醉意 1 +x:1 +初中版 1 +x:1 +脑门穴 1 +x:1 +勤廉 1 +x:1 +折半 1 +x:1 +展览品 1 +x:1 +燃烧室 1 +x:1 +科学界 1 +x:1 +密闭式 1 +x:1 +雨花台 1 +x:1 +悬空 1 +x:1 +林特 1 +x:1 +虚无缥缈 1 +x:1 +酒曲 1 +x:1 +挺身 1 +x:1 +铁科院 1 +x:1 +戍 1 +x:1 +报酬率 1 +x:1 +沱江 1 +x:1 +勐腊县 1 +x:1 +炖 9 +x:9 +存疑 1 +x:1 +大通道 1 +x:1 +弟 17 +x:17 +中医 1 +x:1 +师妹 1 +x:1 +卡子湾 1 +x:1 +画展 1 +x:1 +浦北 1 +x:1 +孝义 1 +x:1 +不时之需 1 +x:1 +光复路 1 +x:1 +蛆枣儿 1 +x:1 +双曲拱桥 1 +x:1 +选中 1 +x:1 +矫枉过正 1 +x:1 +画屏 1 +x:1 +承贷承还 1 +x:1 +箭簇 1 +x:1 +伊士曼 1 +x:1 +刻画 1 +x:1 +私商 1 +x:1 +师姑 1 +x:1 +摆钟 1 +x:1 +赓 7 +x:7 +嘉峪关 1 +x:1 +报捷 1 +x:1 +部委级 1 +x:1 +黑页岩 1 +x:1 +拳头产品 1 +x:1 +停靠点 1 +x:1 +浦南 1 +x:1 +仪 165 +x:165 +展开式 1 +x:1 +齐山区 1 +x:1 +陶朗加市 1 +x:1 +柔柔 1 +x:1 +动手 1 +x:1 +师娘 1 +x:1 +卧虎山 1 +x:1 +巴雾峡 1 +x:1 +越规者 1 +x:1 +古尔邦节 1 +x:1 +双羊镇 1 +x:1 +色目人 1 +x:1 +非法人 1 +x:1 +运销商 1 +x:1 +龙钟 1 +x:1 +喜迁 1 +x:1 +喜迎 1 +x:1 +众议员 1 +x:1 +险工 1 +x:1 +北京团 1 +x:1 +成份股 1 +x:1 +逐渐 1 +x:1 +毕业 1 +x:1 +被盗物 1 +x:1 +前元庄 1 +x:1 +亚记联 1 +x:1 +鱼塘 1 +x:1 +纤维蛋白 1 +x:1 +僵蚕 1 +x:1 +双索面 1 +x:1 +输量 1 +x:1 +淋洗 1 +x:1 +夏乐宫 1 +x:1 +封建主义 1 +x:1 +国电债 1 +x:1 +生儿育女 1 +x:1 +发展司 1 +x:1 +龙飞凤舞 1 +x:1 +猪粪肥 1 +x:1 +传递力 1 +x:1 +痣点 1 +x:1 +监院 1 +x:1 +凡尔赛宫 1 +x:1 +稀释型 1 +x:1 +目脑 1 +x:1 +挺起 1 +x:1 +药科 1 +x:1 +安装费 1 +x:1 +明哲保身 1 +x:1 +掘进 1 +x:1 +礼拜 1 +x:1 +凭 227 +x:227 +家母 1 +x:1 +奋斗与共 1 +x:1 +咨询点 1 +x:1 +累人 1 +x:1 +原平县 1 +x:1 +保修期 1 +x:1 +徒手操 1 +x:1 +形变 1 +x:1 +实验楼 1 +x:1 +选举票 1 +x:1 +化学肥料 1 +x:1 +发声 1 +x:1 +闲远 1 +x:1 +固态 1 +x:1 +松岗镇 1 +x:1 +警报器 1 +x:1 +良种兔 1 +x:1 +流畅 1 +x:1 +造粒机 1 +x:1 +小帽 1 +x:1 +账据 1 +x:1 +金桦果 1 +x:1 +哨楼 1 +x:1 +堆制 1 +x:1 +树形图 1 +x:1 +自当 1 +x:1 +上方宝剑 1 +x:1 +喜车 1 +x:1 +左轮手枪 1 +x:1 +分外活 1 +x:1 +盗割 1 +x:1 +相命摊 1 +x:1 +依兰县 1 +x:1 +幼雏 1 +x:1 +威兴我荣 1 +x:1 +达 3535 +x:3535 +花花草草 1 +x:1 +超高层 1 +x:1 +代理商 1 +x:1 +电疗 1 +x:1 +南北方 1 +x:1 +死棋 1 +x:1 +收入权 1 +x:1 +统合 1 +x:1 +中前场 1 +x:1 +报关行 1 +x:1 +大到暴雨 1 +x:1 +北极圈 1 +x:1 +时新 1 +x:1 +跳闸 1 +x:1 +存目 1 +x:1 +烟灰缸 1 +x:1 +挨斗 1 +x:1 +面筋 1 +x:1 +卡拉巴赫 1 +x:1 +责令 1 +x:1 +剧中 1 +x:1 +小题大做 1 +x:1 +从速 1 +x:1 +先后 1 +x:1 +政策部 1 +x:1 +辽宁队 1 +x:1 +惠水县 1 +x:1 +险峻 1 +x:1 +打落 1 +x:1 +乐于助人 1 +x:1 +因循 1 +x:1 +险峰 1 +x:1 +棉纤维 1 +x:1 +威风扫地 1 +x:1 +盗取 1 +x:1 +虎头鞋 1 +x:1 +三岔路村 1 +x:1 +迎泽 1 +x:1 +遍访 1 +x:1 +生死存亡 1 +x:1 +白晃晃 1 +x:1 +都柏灵 1 +x:1 +关系人 1 +x:1 +实验校 1 +x:1 +肇事人 1 +x:1 +从重 1 +x:1 +果铺 1 +x:1 +少不了 1 +x:1 +盗号 1 +x:1 +化验员 1 +x:1 +生产队 1 +x:1 +挥舞 1 +x:1 +扩印 1 +x:1 +滂滂然 1 +x:1 +鸟瞰图 1 +x:1 +活字合金 1 +x:1 +宗法 1 +x:1 +鱼头 1 +x:1 +堂而皇之 1 +x:1 +黄计工 1 +x:1 +循声 1 +x:1 +薄情 1 +x:1 +干事会 1 +x:1 +一见钟情 1 +x:1 +外汇额 1 +x:1 +绝世无匹 1 +x:1 +匠户 1 +x:1 +戏水 1 +x:1 +五神河 1 +x:1 +祁连 1 +x:1 +退换 1 +x:1 +龙门 1 +x:1 +画店 1 +x:1 +推而广之 1 +x:1 +商德 1 +x:1 +林火 1 +x:1 +广通站 1 +x:1 +堆叠 1 +x:1 +值机员 1 +x:1 +白朗朗 1 +x:1 +楼 433 +x:433 +光荣院 1 +x:1 +鼓鼓 1 +x:1 +三迭纪 1 +x:1 +标识号 1 +x:1 +经社 1 +x:1 +形制 1 +x:1 +硬凑 1 +x:1 +阙 10 +x:10 +中性点 1 +x:1 +联邦化 1 +x:1 +壮苗 1 +x:1 +木兰县 1 +x:1 +男女老幼 1 +x:1 +包身工制 1 +x:1 +电瓶 1 +x:1 +驿站 1 +x:1 +生态学 1 +x:1 +画幅 1 +x:1 +联邦区 1 +x:1 +鳞次栉比 1 +x:1 +戏法 1 +x:1 +耀县 1 +x:1 +生物电流 1 +x:1 +会意 1 +x:1 +账户 1 +x:1 +无闲人 1 +x:1 +粉针 1 +x:1 +农奴制 1 +x:1 +诱降 1 +x:1 +五孔桥 1 +x:1 +快车道 1 +x:1 +自豪感 1 +x:1 +画帖 1 +x:1 +伸缩性 1 +x:1 +旁注 1 +x:1 +卫 43 +x:43 +聚集地 1 +x:1 +盗匪 1 +x:1 +画布 1 +x:1 +群鸟 1 +x:1 +筛管 1 +x:1 +输送 1 +x:1 +画师 1 +x:1 +星象 1 +x:1 +张三李四 1 +x:1 +嘀嘀 1 +x:1 +经纬 1 +x:1 +艺术局 1 +x:1 +经纪 1 +x:1 +练歌厅 1 +x:1 +莲花落 1 +x:1 +残留性 1 +x:1 +全尸 1 +x:1 +竣工 1 +x:1 +经线 1 +x:1 +监造 1 +x:1 +手艺 1 +x:1 +经纶 1 +x:1 +四医大 1 +x:1 +莫内塔 1 +x:1 +广钢 1 +x:1 +瓦莱塔 1 +x:1 +曾孙 1 +x:1 +畜禽业 1 +x:1 +癌细胞 1 +x:1 +聪颖 1 +x:1 +襄棉 1 +x:1 +仙鹤 1 +x:1 +耳闻 1 +x:1 +伉俪 1 +x:1 +影戏院 1 +x:1 +优良品率 1 +x:1 +化验单 1 +x:1 +平昌县 1 +x:1 +难舍难离 1 +x:1 +购物卡 1 +x:1 +团结湖 1 +x:1 +坪台 1 +x:1 +慎 30 +x:30 +叠音 1 +x:1 +打药 1 +x:1 +从难 1 +x:1 +减编 1 +x:1 +嚏喷 1 +x:1 +中心角 1 +x:1 +偷情 1 +x:1 +奔头儿 1 +x:1 +党风室 1 +x:1 +擅入 1 +x:1 +作物 1 +x:1 +刑律者 1 +x:1 +知心人 1 +x:1 +乔治亚岛 1 +x:1 +经络 1 +x:1 +鱼市 1 +x:1 +伟绩 1 +x:1 +刊授 1 +x:1 +逐案 1 +x:1 +暴饮暴食 1 +x:1 +广铁 1 +x:1 +路队制 1 +x:1 +佩雷斯 1 +x:1 +见怪不怪 1 +x:1 +僵蛰 1 +x:1 +活动站 1 +x:1 +那边 1 +x:1 +暖烘烘 1 +x:1 +珠光灯 1 +x:1 +特兴镇 1 +x:1 +软绵绵 1 +x:1 +赈济 1 +x:1 +翼展 1 +x:1 +发动机 1 +x:1 +老鼠洞 1 +x:1 +塘边 1 +x:1 +挨揍 1 +x:1 +大鱼大肉 1 +x:1 +肆虐无忌 1 +x:1 +康铜 1 +x:1 +电珠 1 +x:1 +制冷剂 1 +x:1 +会昌 1 +x:1 +椰子 1 +x:1 +大致说来 1 +x:1 +酚醛树脂 1 +x:1 +画夹 1 +x:1 +中签者 1 +x:1 +雕梁画栋 1 +x:1 +科学热 1 +x:1 +劳务社 1 +x:1 +嗖 2 +x:2 +值机台 1 +x:1 +麻辣 1 +x:1 +生产量 1 +x:1 +画外 1 +x:1 +耄耋高龄 1 +x:1 +格局 1 +x:1 +薄板 1 +x:1 +盛开 1 +x:1 +印象主义 1 +x:1 +发展商 1 +x:1 +良种场 1 +x:1 +半侧 1 +x:1 +改过自新 1 +x:1 +向声背实 1 +x:1 +挨批 1 +x:1 +东瓦窑 1 +x:1 +忙忙地 1 +x:1 +小型张 1 +x:1 +翠柏丛 1 +x:1 +游禽 1 +x:1 +太仓一粟 1 +x:1 +示范 1 +x:1 +骑马 1 +x:1 +联航队 1 +x:1 +雅加达市 1 +x:1 +广安县 1 +x:1 +识字班 1 +x:1 +综合科 1 +x:1 +内阁总理 1 +x:1 +泡杉 1 +x:1 +人困马乏 1 +x:1 +面粉 1 +x:1 +售货 1 +x:1 +胖小子 1 +x:1 +板卡 1 +x:1 +安阳市 1 +x:1 +痞 1 +x:1 +雄鹰 1 +x:1 +临街面 1 +x:1 +光子学 1 +x:1 +坦桑 1 +x:1 +鼓乐声 1 +x:1 +识字率 1 +x:1 +挨户 1 +x:1 +柴达木 1 +x:1 +香花 1 +x:1 +无定形碳 1 +x:1 +延水 1 +x:1 +战炮 1 +x:1 +探测站 1 +x:1 +衣钵相传 1 +x:1 +未知数 1 +x:1 +画墙 1 +x:1 +存照 1 +x:1 +面糊 1 +x:1 +皮肤学 1 +x:1 +画境 1 +x:1 +家法 1 +x:1 +硬着头皮 1 +x:1 +重提 1 +x:1 +药绳 1 +x:1 +控制区 1 +x:1 +迁 151 +x:151 +寄宿生 1 +x:1 +异同 1 +x:1 +娶亲 1 +x:1 +电影城 1 +x:1 +睾丸 1 +x:1 +音容笑貌 1 +x:1 +发扬光大 1 +x:1 +对照组 1 +x:1 +密山市 1 +x:1 +半价 1 +x:1 +智能卡 1 +x:1 +推荐奖 1 +x:1 +甩掉 1 +x:1 +孤苦伶丁 1 +x:1 +里外开花 1 +x:1 +代理制 1 +x:1 +链轨式 1 +x:1 +长子县 1 +x:1 +组建期 1 +x:1 +酃 1 +x:1 +贪小失大 1 +x:1 +礼数 1 +x:1 +十字架 1 +x:1 +猪牛羊肉 1 +x:1 +邢 70 +x:70 +努努 1 +x:1 +监控器 1 +x:1 +统包 1 +x:1 +叫绝 1 +x:1 +骑骑 1 +x:1 +一瓣心香 1 +x:1 +努力 1 +x:1 +丁基橡胶 1 +x:1 +丁家山 1 +x:1 +礼教 1 +x:1 +燃烧弹 1 +x:1 +画堂 1 +x:1 +中性盐 1 +x:1 +黎明村 1 +x:1 +多姿多彩 1 +x:1 +六九年 1 +x:1 +付印 1 +x:1 +逛来逛去 1 +x:1 +磅湛省 1 +x:1 +会操 1 +x:1 +内电路 1 +x:1 +丰收年 1 +x:1 +航天局 1 +x:1 +预见性 1 +x:1 +古人类学 1 +x:1 +生死立判 1 +x:1 +遍身 1 +x:1 +伤心 1 +x:1 +西十四村 1 +x:1 +纳塔尔市 1 +x:1 +虚伪 1 +x:1 +蜜罐 1 +x:1 +有禁不止 1 +x:1 +组长 1 +x:1 +初中生 1 +x:1 +中心论 1 +x:1 +发展型 1 +x:1 +云开日出 1 +x:1 +收发报 1 +x:1 +中心词 1 +x:1 +画家 1 +x:1 +倒班 1 +x:1 +文化衫 1 +x:1 +取精用弘 1 +x:1 +啼猿 1 +x:1 +海州湾 1 +x:1 +鱼尸 1 +x:1 +电视片 1 +x:1 +黄桷树 1 +x:1 +腊月 1 +x:1 +画室 1 +x:1 +洲界 1 +x:1 +火成岩 1 +x:1 +道破 1 +x:1 +鬻 2 +x:2 +中心语 1 +x:1 +组合柜 1 +x:1 +奥妙 1 +x:1 +龙潭镇 1 +x:1 +喜讯 1 +x:1 +酒意 1 +x:1 +孤身一人 1 +x:1 +比例制 1 +x:1 +持枪 1 +x:1 +果酒 1 +x:1 +久假不归 1 +x:1 +社区型 1 +x:1 +闲话 1 +x:1 +自视甚高 1 +x:1 +妊 1 +x:1 +攻歼 1 +x:1 +闲评 1 +x:1 +月塘村 1 +x:1 +嘀咕 1 +x:1 +分印点 1 +x:1 +分理处 1 +x:1 +急救车 1 +x:1 +闲说 1 +x:1 +游程 1 +x:1 +果酱 1 +x:1 +牙雕 1 +x:1 +瘫 10 +x:10 +广阔 1 +x:1 +盛宅村 1 +x:1 +胜利品 1 +x:1 +抵补 1 +x:1 +从政者 1 +x:1 +烘制 1 +x:1 +句容县 1 +x:1 +断后 1 +x:1 +秋高气爽 1 +x:1 +海洋学家 1 +x:1 +链钳子 1 +x:1 +广陵 1 +x:1 +滑冰馆 1 +x:1 +面罩 1 +x:1 +对 27688 +x:27688 +映山红 1 +x:1 +幽微 1 +x:1 +石雕 1 +x:1 +青麻 1 +x:1 +儿康宁 1 +x:1 +广院 1 +x:1 +回采 1 +x:1 +经籍 1 +x:1 +勤奋 1 +x:1 +报摊 1 +x:1 +葛仙米 1 +x:1 +线膨胀 1 +x:1 +秧子 1 +x:1 +珮 1 +x:1 +捻军 1 +x:1 +筛网 1 +x:1 +舆地书 1 +x:1 +师弟 1 +x:1 +药粉 1 +x:1 +摇摆性 1 +x:1 +蚱蜢舟 1 +x:1 +逐次 1 +x:1 +面纱 1 +x:1 +均一 1 +x:1 +跪拜礼 1 +x:1 +会旗 1 +x:1 +面纸 1 +x:1 +排放者 1 +x:1 +迎检 1 +x:1 +报文 1 +x:1 +发家 1 +x:1 +毅力 1 +x:1 +图案 1 +x:1 +电灯 1 +x:1 +绒织 1 +x:1 +抵触 1 +x:1 +箭竹 1 +x:1 +铺张浪费 1 +x:1 +工薪族 1 +x:1 +记联 1 +x:1 +珠 28 +x:28 +绒线 1 +x:1 +戏校 1 +x:1 +图样 1 +x:1 +开场白 1 +x:1 +箭窗 1 +x:1 +查验簿 1 +x:1 +忠心耿耿 1 +x:1 +完美无缺 1 +x:1 +报时 1 +x:1 +气势如虹 1 +x:1 +租 133 +x:133 +启航 1 +x:1 +天下大乱 1 +x:1 +匿影藏形 1 +x:1 +后过渡期 1 +x:1 +同仁 1 +x:1 +事业部 1 +x:1 +注文 1 +x:1 +付出 1 +x:1 +专注 1 +x:1 +梦华 1 +x:1 +场强 1 +x:1 +惠州 1 +x:1 +传动带 1 +x:1 +翁婿 1 +x:1 +图标 1 +x:1 +铁账本 1 +x:1 +长臂虾 1 +x:1 +拼命 1 +x:1 +旺旺 1 +x:1 +组团式 1 +x:1 +木刻 1 +x:1 +师徒 1 +x:1 +绣花厂 1 +x:1 +惯窃 1 +x:1 +埃默鲁市 1 +x:1 +辐 1 +x:1 +珠琴 1 +x:1 +招生数 1 +x:1 +重氢 1 +x:1 +对立论 1 +x:1 +建设部 1 +x:1 +白金汉宫 1 +x:1 +煮豆燃萁 1 +x:1 +擅动 1 +x:1 +赘疣 1 +x:1 +堆场 1 +x:1 +不可分割 1 +x:1 +师德 1 +x:1 +统共 1 +x:1 +电热 1 +x:1 +结壳 1 +x:1 +乙类 1 +x:1 +风笛 1 +x:1 +赵家岭村 1 +x:1 +雅士 1 +x:1 +礼服 1 +x:1 +非公务 1 +x:1 +大都会 1 +x:1 +雁窝岛 1 +x:1 +樱井 1 +x:1 +出让金 1 +x:1 +婉 4 +x:4 +渔政处 1 +x:1 +电炉 1 +x:1 +陈年老辞 1 +x:1 +友党 1 +x:1 +禁猎 1 +x:1 +奔走相告 1 +x:1 +报数 1 +x:1 +聚集区 1 +x:1 +报效 1 +x:1 +学术史 1 +x:1 +主台 1 +x:1 +旅游鞋 1 +x:1 +因子 1 +x:1 +洋地黄 1 +x:1 +璎珞 1 +x:1 +养育之恩 1 +x:1 +深文周纳 1 +x:1 +镁砖 1 +x:1 +药王 1 +x:1 +图板 1 +x:1 +电网 1 +x:1 +事不关己 1 +x:1 +咨询站 1 +x:1 +院校长 1 +x:1 +联产 1 +x:1 +监控室 1 +x:1 +精神病院 1 +x:1 +四六文 1 +x:1 +转换 1 +x:1 +新教派 1 +x:1 +惯用 1 +x:1 +海岸线 1 +x:1 +甘拜下风 1 +x:1 +筵席 1 +x:1 +踏踏实实 1 +x:1 +搜查 1 +x:1 +珠算 1 +x:1 +甘紫菜 1 +x:1 +炎症 1 +x:1 +投桃报李 1 +x:1 +博士奖 1 +x:1 +跳鼠 1 +x:1 +窄窄 1 +x:1 +戏本 1 +x:1 +庙里 1 +x:1 +细胞学 1 +x:1 +剑眉 1 +x:1 +海口市 1 +x:1 +图本 1 +x:1 +祈福 1 +x:1 +母乳 1 +x:1 +打转 1 +x:1 +电缆 1 +x:1 +椰城 1 +x:1 +社会教育 1 +x:1 +笆篱 1 +x:1 +覆盖物 1 +x:1 +倒卵形 1 +x:1 +茎秆 1 +x:1 +记载 1 +x:1 +适时 1 +x:1 +村小 1 +x:1 +批发业 1 +x:1 +装具 1 +x:1 +塘荷 1 +x:1 +唐庄乡 1 +x:1 +实实地 1 +x:1 +肥得鲁儿 1 +x:1 +固城乡 1 +x:1 +安阳县 1 +x:1 +祈祝 1 +x:1 +金张掖 1 +x:1 +对照班 1 +x:1 +宠物 1 +x:1 +段子 1 +x:1 +首字音 1 +x:1 +四脚八叉 1 +x:1 +受体 1 +x:1 +龙鸟 1 +x:1 +母亲 1 +x:1 +批发价 1 +x:1 +紧锣密鼓 1 +x:1 +千古风范 1 +x:1 +汀江 1 +x:1 +师傅 1 +x:1 +女巫 1 +x:1 +梭罗树 1 +x:1 +存粮 1 +x:1 +洗衣店 1 +x:1 +冒充 1 +x:1 +音尘 1 +x:1 +波恩市 1 +x:1 +祈祷 1 +x:1 +胃癌 1 +x:1 +宾朋 1 +x:1 +画商 1 +x:1 +团结报 1 +x:1 +三三制 1 +x:1 +重水 1 +x:1 +狂傲 1 +x:1 +科学系 1 +x:1 +阿里特纳 1 +x:1 +太平龙头 1 +x:1 +整除 1 +x:1 +水电部 1 +x:1 +铁壁铜墙 1 +x:1 +宠爱 1 +x:1 +记过 1 +x:1 +软件 1 +x:1 +雄鸡头者 1 +x:1 +万里长征 1 +x:1 +统帅 1 +x:1 +师出无名 1 +x:1 +报橱 1 +x:1 +红宴 1 +x:1 +记述 1 +x:1 +受伤 1 +x:1 +久拖不决 1 +x:1 +双塘村 1 +x:1 +发展奖 1 +x:1 +工委会 1 +x:1 +酱 9 +x:9 +止痛片 1 +x:1 +女工 1 +x:1 +无人机 1 +x:1 +用品 1 +x:1 +通式 1 +x:1 +涿鹿 1 +x:1 +恰恰相反 1 +x:1 +之中 1 +x:1 +辩论 1 +x:1 +那般 1 +x:1 +寅吃卯粮 1 +x:1 +币种 1 +x:1 +转手 1 +x:1 +窥豹一斑 1 +x:1 +凡堡村 1 +x:1 +抓差 1 +x:1 +擦身而过 1 +x:1 +门楣 1 +x:1 +十字步 1 +x:1 +例外论 1 +x:1 +面点 1 +x:1 +开怀大笑 1 +x:1 +树木影 1 +x:1 +风行一时 1 +x:1 +赔还 1 +x:1 +小型化 1 +x:1 +同盟军 1 +x:1 +不尚空谈 1 +x:1 +新鲜事 1 +x:1 +急乎乎 1 +x:1 +板刷 1 +x:1 +画品 1 +x:1 +村屯 1 +x:1 +坐困愁城 1 +x:1 +蓝墨水 1 +x:1 +匡正 1 +x:1 +文登市 1 +x:1 +血象 1 +x:1 +新运处 1 +x:1 +患难之交 1 +x:1 +受事 1 +x:1 +漩起 1 +x:1 +铜山县 1 +x:1 +形声 1 +x:1 +装做 1 +x:1 +大庆市 1 +x:1 +那色 1 +x:1 +师兄 1 +x:1 +塑料膜 1 +x:1 +柴胡店镇 1 +x:1 +三八节 1 +x:1 +惠及 1 +x:1 +碗筷 1 +x:1 +锦纶 1 +x:1 +师公 1 +x:1 +辩证 1 +x:1 +通讯业 1 +x:1 +庄浪籍 1 +x:1 +学生证 1 +x:1 +鱼台 1 +x:1 +看病票 1 +x:1 +统归 1 +x:1 +泰宁县 1 +x:1 +同友会 1 +x:1 +鱼口 1 +x:1 +龙鼓 1 +x:1 +戏曲 1 +x:1 +土 277 +x:277 +香港队 1 +x:1 +心窝窝 1 +x:1 +谱曲 1 +x:1 +回国率 1 +x:1 +重点论 1 +x:1 +航天史 1 +x:1 +印书馆 1 +x:1 +装傻 1 +x:1 +鱼叉 1 +x:1 +作茧自缚 1 +x:1 +药片 1 +x:1 +通缉令 1 +x:1 +林立 1 +x:1 +迎春 1 +x:1 +多数票 1 +x:1 +墟里 1 +x:1 +逐日 1 +x:1 +硬实 1 +x:1 +腊梅 1 +x:1 +大中学生 1 +x:1 +受业 1 +x:1 +转折 1 +x:1 +电线 1 +x:1 +转报 1 +x:1 +药物 1 +x:1 +加盖 1 +x:1 +同盟党 1 +x:1 +水上飞机 1 +x:1 +木材林 1 +x:1 +管标治本 1 +x:1 +兴趣 1 +x:1 +汀洲 1 +x:1 +散逸 1 +x:1 +惠卖 1 +x:1 +堆积层 1 +x:1 +核反应 1 +x:1 +疲弱 1 +x:1 +决死队 1 +x:1 +籽棉 1 +x:1 +画名 1 +x:1 +阳高县 1 +x:1 +问效 1 +x:1 +大众车 1 +x:1 +错判案 1 +x:1 +锡养堂 1 +x:1 +长话短说 1 +x:1 +口杰伊汉 1 +x:1 +印刷史 1 +x:1 +交口称誉 1 +x:1 +形容 1 +x:1 +打败 1 +x:1 +泥胎儿 1 +x:1 +观音竹 1 +x:1 +中英文 1 +x:1 +客籍 1 +x:1 +内防军 1 +x:1 +泡桐 1 +x:1 +受孕率 1 +x:1 +箭石 1 +x:1 +应用文 1 +x:1 +汪汪 1 +x:1 +跟斗 1 +x:1 +转意 1 +x:1 +新闻论 1 +x:1 +绍兴市 1 +x:1 +草铺 1 +x:1 +仙逝 1 +x:1 +衷曲 1 +x:1 +碟片 1 +x:1 +湘鄂川黔 1 +x:1 +违章率 1 +x:1 +平面几何 1 +x:1 +有空 1 +x:1 +青鲨 1 +x:1 +神职人员 1 +x:1 +软性 1 +x:1 +打赌 1 +x:1 +癫痫病 1 +x:1 +英姿飒爽 1 +x:1 +中小城 1 +x:1 +学生装 1 +x:1 +行政科 1 +x:1 +欧阳 1 +x:1 +偷渡 1 +x:1 +中东非 1 +x:1 +洗菜盆 1 +x:1 +阿斯旺 1 +x:1 +急救药 1 +x:1 +打趣 1 +x:1 +妇女部 1 +x:1 +创 583 +x:583 +胳肢窝 1 +x:1 +延揽 1 +x:1 +冀东 1 +x:1 +报栏 1 +x:1 +败 142 +x:142 +税源 1 +x:1 +画坛 1 +x:1 +置身事外 1 +x:1 +堂伯 1 +x:1 +劝阻 1 +x:1 +北农大 1 +x:1 +见习员 1 +x:1 +硬壳 1 +x:1 +原创性 1 +x:1 +缺斤短两 1 +x:1 +滩羊皮 1 +x:1 +下达河乡 1 +x:1 +人心思和 1 +x:1 +花溪乡 1 +x:1 +林种 1 +x:1 +会标 1 +x:1 +松江省 1 +x:1 +水火无情 1 +x:1 +即兴诗 1 +x:1 +发展学 1 +x:1 +劝降 1 +x:1 +默 8 +x:8 +馆藏 1 +x:1 +报案 1 +x:1 +运输户 1 +x:1 +戏文 1 +x:1 +欧陆 1 +x:1 +包河 1 +x:1 +烘干 1 +x:1 +例会 1 +x:1 +如诉如泣 1 +x:1 +图文 1 +x:1 +盗寇 1 +x:1 +鱼具 1 +x:1 +合唱 1 +x:1 +前茅 1 +x:1 +诈农案 1 +x:1 +残 60 +x:60 +画图 1 +x:1 +方城县 1 +x:1 +缘 55 +x:55 +钦敬 1 +x:1 +割让 1 +x:1 +延承 1 +x:1 +过把瘾 1 +x:1 +月殿 1 +x:1 +院长 1 +x:1 +达坂城 1 +x:1 +实验性 1 +x:1 +群集 1 +x:1 +停泊地 1 +x:1 +群雄 1 +x:1 +中川乡 1 +x:1 +脚步声 1 +x:1 +黑墨水 1 +x:1 +吨粮田 1 +x:1 +源远流长 1 +x:1 +百废具兴 1 +x:1 +锄头 1 +x:1 +群雕 1 +x:1 +退款 1 +x:1 +柳条湖 1 +x:1 +乙烷 1 +x:1 +下策 1 +x:1 +酒水 1 +x:1 +各奔东西 1 +x:1 +拍马 1 +x:1 +急性子 1 +x:1 +逐条 1 +x:1 +好望角 1 +x:1 +幼鼠 1 +x:1 +电视网 1 +x:1 +辩解 1 +x:1 +兜 17 +x:17 +酒气 1 +x:1 +风水宝地 1 +x:1 +逐村 1 +x:1 +艺术院团 1 +x:1 +退步 1 +x:1 +保不住 1 +x:1 +求仙记 1 +x:1 +正式化 1 +x:1 +损耗 1 +x:1 +朋友式 1 +x:1 +演播 1 +x:1 +堂上 1 +x:1 +于 8381 +x:8381 +苏铁科 1 +x:1 +两三点钟 1 +x:1 +收盘价 1 +x:1 +解析数论 1 +x:1 +立簿 1 +x:1 +望尘莫及 1 +x:1 +泰斗 1 +x:1 +逸话 1 +x:1 +谈古论今 1 +x:1 +训练课 1 +x:1 +和平路 1 +x:1 +敞露 1 +x:1 +名产 1 +x:1 +塘肥 1 +x:1 +弗里敦市 1 +x:1 +杭州湾 1 +x:1 +酒泉 1 +x:1 +堂主 1 +x:1 +置身世外 1 +x:1 +设想 1 +x:1 +黄浦区 1 +x:1 +堆存 1 +x:1 +褒誉 1 +x:1 +师友 1 +x:1 +棚户区 1 +x:1 +针鼹 1 +x:1 +售菜 1 +x:1 +科工委 1 +x:1 +赔账 1 +x:1 +对照点 1 +x:1 +数据站 1 +x:1 +簇簇 1 +x:1 +面片 1 +x:1 +浸膏 1 +x:1 +出出进进 1 +x:1 +砖木 1 +x:1 +幼龟 1 +x:1 +雨丝 1 +x:1 +白嘴鸦 1 +x:1 +冰道 1 +x:1 +有据可查 1 +x:1 +幼龄 1 +x:1 +康斯坦察 1 +x:1 +绵羊肉 1 +x:1 +风籁 1 +x:1 +家托 1 +x:1 +冲抵法 1 +x:1 +团结星 1 +x:1 +皇 2 +x:2 +咨询组 1 +x:1 +该场 1 +x:1 +安波汤 1 +x:1 +手握胜券 1 +x:1 +二元酸 1 +x:1 +电筒 1 +x:1 +含含糊糊 1 +x:1 +面疱 1 +x:1 +生生不已 1 +x:1 +钛 13 +x:13 +教书 1 +x:1 +叫真 1 +x:1 +时机 1 +x:1 +龙骨 1 +x:1 +天灾人祸 1 +x:1 +一语道破 1 +x:1 +世界一统 1 +x:1 +综机 1 +x:1 +梁园镇 1 +x:1 +主张者 1 +x:1 +绿草如茵 1 +x:1 +周水子 1 +x:1 +之上 1 +x:1 +航天器 1 +x:1 +央 1 +x:1 +改乘 1 +x:1 +基础论 1 +x:1 +座套 1 +x:1 +隐喻 1 +x:1 +铁丹 1 +x:1 +冰箱业 1 +x:1 +生力军 1 +x:1 +珠翠 1 +x:1 +奸污 1 +x:1 +脊梁骨 1 +x:1 +硬币 1 +x:1 +简介 1 +x:1 +训练有素 1 +x:1 +迎接 1 +x:1 +返程票 1 +x:1 +各家 1 +x:1 +引人深思 1 +x:1 +仔猪 1 +x:1 +林网 1 +x:1 +轻举妄动 1 +x:1 +赔小心 1 +x:1 +挨次 1 +x:1 +云霭 1 +x:1 +庙门 1 +x:1 +通今博古 1 +x:1 +礼法 1 +x:1 +转术 1 +x:1 +纨绔子弟 1 +x:1 +髯 5 +x:5 +家族 1 +x:1 +乐天知命 1 +x:1 +叵 1 +x:1 +动植物 1 +x:1 +时有 1 +x:1 +下小河 1 +x:1 +不可逾越 1 +x:1 +人权 1 +x:1 +画册 1 +x:1 +奇志 1 +x:1 +地下室 1 +x:1 +画具 1 +x:1 +适意 1 +x:1 +汨罗队 1 +x:1 +江河日下 1 +x:1 +世界级 1 +x:1 +心平气顺 1 +x:1 +继承者 1 +x:1 +改任 1 +x:1 +劝退 1 +x:1 +实验林 1 +x:1 +浑身 1 +x:1 +家政 1 +x:1 +手提箱 1 +x:1 +旁门左道 1 +x:1 +环靶 1 +x:1 +酒毒 1 +x:1 +太康县 1 +x:1 +旧雨重逢 1 +x:1 +吃不来 1 +x:1 +舞客 1 +x:1 +小试牛刀 1 +x:1 +耿介拔俗 1 +x:1 +揭牌 1 +x:1 +硕鼠 1 +x:1 +印刷厂 1 +x:1 +铁人 1 +x:1 +客站 1 +x:1 +啮合 1 +x:1 +吃不服 1 +x:1 +五棵树村 1 +x:1 +首规委 1 +x:1 +陇 12 +x:12 +朗润园 1 +x:1 +增删 1 +x:1 +电算 1 +x:1 +下笔 1 +x:1 +哗啦啦 1 +x:1 +化验室 1 +x:1 +家数 1 +x:1 +段式 1 +x:1 +民房 1 +x:1 +梁券 1 +x:1 +厮杀 1 +x:1 +太空日 1 +x:1 +椽子 1 +x:1 +意象篇 1 +x:1 +将门 1 +x:1 +百合花 1 +x:1 +曾厝 1 +x:1 +提炼 1 +x:1 +酌定 1 +x:1 +浸蚀 1 +x:1 +双关语 1 +x:1 +寒鸦 1 +x:1 +吸引力 1 +x:1 +面露难色 1 +x:1 +辅读班 1 +x:1 +玉兰花 1 +x:1 +悬石 1 +x:1 +家教 1 +x:1 +布头 1 +x:1 +石炭纪 1 +x:1 +师哥 1 +x:1 +阴湿 1 +x:1 +花好月圆 1 +x:1 +白话文学 1 +x:1 +稳定平衡 1 +x:1 +超高压 1 +x:1 +勤务 1 +x:1 +种植热 1 +x:1 +选任 1 +x:1 +油腻腻 1 +x:1 +寒鸭 1 +x:1 +闲职 1 +x:1 +自立者 1 +x:1 +泰山区 1 +x:1 +勤劳 1 +x:1 +闲聊 1 +x:1 +倘佯 1 +x:1 +雄险 1 +x:1 +情有可原 1 +x:1 +群蛇 1 +x:1 +养猪业 1 +x:1 +嘲 2 +x:2 +农村司 1 +x:1 +倘使 1 +x:1 +北四环 1 +x:1 +上阕 1 +x:1 +正词法 1 +x:1 +画像 1 +x:1 +简便 1 +x:1 +金州区 1 +x:1 +破坏者 1 +x:1 +新人王赛 1 +x:1 +学术奖 1 +x:1 +文化教育 1 +x:1 +赛羊会 1 +x:1 +玄明粉 1 +x:1 +矩阵 1 +x:1 +团结村 1 +x:1 +妹妹 1 +x:1 +平常心 1 +x:1 +亚文化 1 +x:1 +雄阔 1 +x:1 +万架次率 1 +x:1 +勤勉 1 +x:1 +永葆青春 1 +x:1 +想当然 1 +x:1 +搜索引擎 1 +x:1 +小富村 1 +x:1 +墨斗鱼 1 +x:1 +完善化 1 +x:1 +匠气 1 +x:1 +跳马 1 +x:1 +撞死 1 +x:1 +欧里 1 +x:1 +喜联 1 +x:1 +电站 1 +x:1 +地区司 1 +x:1 +抓好 1 +x:1 +咆 1 +x:1 +航天城 1 +x:1 +息烽县 1 +x:1 +煤水电费 1 +x:1 +寿命 1 +x:1 +云雾 1 +x:1 +版画史 1 +x:1 +人心思变 1 +x:1 +篮下 1 +x:1 +跟手 1 +x:1 +红三军 1 +x:1 +箱底 1 +x:1 +栾老寨 1 +x:1 +祝贺 1 +x:1 +罐头盒 1 +x:1 +折衷主义 1 +x:1 +完中 1 +x:1 +筵宴 1 +x:1 +白条猪 1 +x:1 +话务量 1 +x:1 +实装 1 +x:1 +拉各斯 1 +x:1 +面巾纸 1 +x:1 +呼吸道 1 +x:1 +香茗 1 +x:1 +云集 1 +x:1 +摩拉维亚 1 +x:1 +膏腴之地 1 +x:1 +长命百岁 1 +x:1 +妹夫 1 +x:1 +跳高 1 +x:1 +突破口 1 +x:1 +劝酒 1 +x:1 +几易其稿 1 +x:1 +基础课 1 +x:1 +交口称赞 1 +x:1 +简体 1 +x:1 +会演 1 +x:1 +炭火 1 +x:1 +初中组 1 +x:1 +迎战 1 +x:1 +发展局 1 +x:1 +企业主 1 +x:1 +绒球 1 +x:1 +扬其所长 1 +x:1 +一家之言 1 +x:1 +边境区 1 +x:1 +立体电影 1 +x:1 +泡汤 1 +x:1 +霆 1 +x:1 +酒楼 1 +x:1 +武义县 1 +x:1 +幼驹 1 +x:1 +大忙时节 1 +x:1 +和平街 1 +x:1 +龙颜 1 +x:1 +药疗 1 +x:1 +伟光乡 1 +x:1 +淋漓 1 +x:1 +肝风 1 +x:1 +面神经 1 +x:1 +自为 1 +x:1 +电梯间 1 +x:1 +粉饰 1 +x:1 +果树园 1 +x:1 +采风团 1 +x:1 +会泽 1 +x:1 +闲荡 1 +x:1 +药疹 1 +x:1 +苏铁类 1 +x:1 +商工 1 +x:1 +骄纵放任 1 +x:1 +热处理 1 +x:1 +斑马鱼 1 +x:1 +同盟国 1 +x:1 +云锣 1 +x:1 +装坛 1 +x:1 +云锦 1 +x:1 +片断 1 +x:1 +保卫部 1 +x:1 +习 21 +x:21 +千岛湖 1 +x:1 +挡箭牌 1 +x:1 +抗毒素 1 +x:1 +电示 1 +x:1 +数据网 1 +x:1 +凄凄惨惨 1 +x:1 +加人一等 1 +x:1 +阿房宫 1 +x:1 +拆线 1 +x:1 +晨 82 +x:82 +家居服 1 +x:1 +延期 1 +x:1 +泡泡 1 +x:1 +边境县 1 +x:1 +预 26 +x:26 +代理处 1 +x:1 +回首 1 +x:1 +回馈 1 +x:1 +仓盈粮丰 1 +x:1 +妹婿 1 +x:1 +积铢累寸 1 +x:1 +顷刻 1 +x:1 +奥兰 1 +x:1 +果饵 1 +x:1 +输气管 1 +x:1 +药用 1 +x:1 +经理 1 +x:1 +丑牛 1 +x:1 +形式 1 +x:1 +获释 1 +x:1 +安民乐业 1 +x:1 +申报量 1 +x:1 +烟客 1 +x:1 +居留证 1 +x:1 +捎马子 1 +x:1 +气度 1 +x:1 +泡沫 1 +x:1 +游牧 1 +x:1 +戏班子 1 +x:1 +专车 1 +x:1 +形影 1 +x:1 +浩然 1 +x:1 +分税制 1 +x:1 +元凤四年 1 +x:1 +排球场 1 +x:1 +箭猪 1 +x:1 +血防 1 +x:1 +活动点 1 +x:1 +非歧视 1 +x:1 +馆臣 1 +x:1 +推三托四 1 +x:1 +册子 1 +x:1 +平艮村 1 +x:1 +师团 1 +x:1 +仪征市 1 +x:1 +推荐分 1 +x:1 +血海深仇 1 +x:1 +酒桶 1 +x:1 +游玩 1 +x:1 +螺旋桨 1 +x:1 +诱骗 1 +x:1 +匈 23 +x:23 +面皮 1 +x:1 +客票 1 +x:1 +双承包制 1 +x:1 +亚太区 1 +x:1 +顺乎民意 1 +x:1 +窑火 1 +x:1 +非党员 1 +x:1 +省时 1 +x:1 +苦行僧 1 +x:1 +龙首 1 +x:1 +面的 1 +x:1 +钦慕 1 +x:1 +手指画 1 +x:1 +挨 56 +x:56 +金属元素 1 +x:1 +酒桌 1 +x:1 +宽帮镇 1 +x:1 +塔哈尔 1 +x:1 +卢萨卡 1 +x:1 +面目 1 +x:1 +整齐 1 +x:1 +舍身 1 +x:1 +邹 370 +x:370 +鱼松 1 +x:1 +同仇敌忾 1 +x:1 +节能型 1 +x:1 +窗口 1 +x:1 +生态型 1 +x:1 +诟骂 1 +x:1 +签到日 1 +x:1 +限定 1 +x:1 +面盆 1 +x:1 +销路 1 +x:1 +肉垛垛 1 +x:1 +诵读 1 +x:1 +退潮 1 +x:1 +福冈市 1 +x:1 +与日俱长 1 +x:1 +鱼唇 1 +x:1 +人本精神 1 +x:1 +潮汛 1 +x:1 +黑胶绸 1 +x:1 +能事 1 +x:1 +鹿特丹 1 +x:1 +剐 1 +x:1 +零售额 1 +x:1 +白粉病 1 +x:1 +如云 1 +x:1 +联邦式 1 +x:1 +崭亮 1 +x:1 +数据线 1 +x:1 +药理 1 +x:1 +不战而胜 1 +x:1 +畜力 1 +x:1 +放养 1 +x:1 +发展带 1 +x:1 +应用性 1 +x:1 +变动性 1 +x:1 +电磁 1 +x:1 +万达队 1 +x:1 +经由 1 +x:1 +惯犯 1 +x:1 +愚昧无知 1 +x:1 +切实可行 1 +x:1 +喜色 1 +x:1 +地下水 1 +x:1 +鲜货 1 +x:1 +银杯 1 +x:1 +岛内外 1 +x:1 +银钓 1 +x:1 +海了去了 1 +x:1 +环发 1 +x:1 +沂河 1 +x:1 +妹子 1 +x:1 +会海 1 +x:1 +荣誉感 1 +x:1 +乐山市 1 +x:1 +挠度 1 +x:1 +主供台 1 +x:1 +昏倒 1 +x:1 +适才 1 +x:1 +经略 1 +x:1 +朋友家 1 +x:1 +保险证 1 +x:1 +治国安民 1 +x:1 +旋转式 1 +x:1 +挺胸 1 +x:1 +草本植物 1 +x:1 +酒梢 1 +x:1 +土沥青 1 +x:1 +电缆井 1 +x:1 +粉领 1 +x:1 +自不量力 1 +x:1 +坪塘 1 +x:1 +公营事业 1 +x:1 +涟源市 1 +x:1 +土城 1 +x:1 +扩 142 +x:142 +转播 1 +x:1 +步履声 1 +x:1 +电碳 1 +x:1 +人工智能 1 +x:1 +会派 1 +x:1 +扔下 1 +x:1 +无房户 1 +x:1 +红三叶 1 +x:1 +画刊 1 +x:1 +全年候 1 +x:1 +先人 1 +x:1 +籽儿 1 +x:1 +今事 1 +x:1 +报务 1 +x:1 +被动免疫 1 +x:1 +薄厚 1 +x:1 +圆锥台 1 +x:1 +图形 1 +x:1 +格里芬湖 1 +x:1 +劳资 1 +x:1 +转学 1 +x:1 +改版 1 +x:1 +榨菜头 1 +x:1 +橄榄绿 1 +x:1 +民俗学家 1 +x:1 +图录 1 +x:1 +酒坛 1 +x:1 +瓶子 1 +x:1 +曲艺家 1 +x:1 +擅改 1 +x:1 +飞锭 1 +x:1 +头骨 1 +x:1 +腊八 1 +x:1 +浦东南路 1 +x:1 +新年伊始 1 +x:1 +酒坊 1 +x:1 +挡火墙 1 +x:1 +冬小麦 1 +x:1 +铁片 1 +x:1 +大头针 1 +x:1 +缺欠 1 +x:1 +廉洁率 1 +x:1 +花鼓戏 1 +x:1 +春寒料峭 1 +x:1 +差速器 1 +x:1 +义利观 1 +x:1 +摘 98 +x:98 +铁牛 1 +x:1 +外经贸厅 1 +x:1 +坐等 1 +x:1 +山苍籽 1 +x:1 +伤害费 1 +x:1 +总监督室 1 +x:1 +戏弄 1 +x:1 +会务 1 +x:1 +逐层 1 +x:1 +亲朋好友 1 +x:1 +蓬溪县 1 +x:1 +图式 1 +x:1 +呸 2 +x:2 +含硫分 1 +x:1 +鼠曲草 1 +x:1 +亲自 1 +x:1 +铁犁 1 +x:1 +会前 1 +x:1 +萃 5 +x:5 +政权 1 +x:1 +粘乎乎 1 +x:1 +偷听 1 +x:1 +蝈蝈儿 1 +x:1 +首席 1 +x:1 +细棋 1 +x:1 +聚义 1 +x:1 +古时候 1 +x:1 +柴扉 1 +x:1 +显通寺 1 +x:1 +报到 1 +x:1 +偷奸取巧 1 +x:1 +变质 1 +x:1 +实验室 1 +x:1 +报刊 1 +x:1 +上下左右 1 +x:1 +形意 1 +x:1 +抬 140 +x:140 +安波汤镇 1 +x:1 +图志 1 +x:1 +果林场 1 +x:1 +硬拼 1 +x:1 +大米饭 1 +x:1 +扇形 1 +x:1 +收发员 1 +x:1 +单个儿 1 +x:1 +漏网之鱼 1 +x:1 +会刊 1 +x:1 +狼子野心 1 +x:1 +注册地 1 +x:1 +画派 1 +x:1 +简牍 1 +x:1 +心跳 1 +x:1 +巨龙 1 +x:1 +家奴 1 +x:1 +册数 1 +x:1 +戏德 1 +x:1 +夫子自道 1 +x:1 +奇蹄目 1 +x:1 +航民村 1 +x:1 +报前 1 +x:1 +玉皇庙 1 +x:1 +经纬度 1 +x:1 +秦 269 +x:269 +檄书 1 +x:1 +侄孙子 1 +x:1 +中山郎 1 +x:1 +头马 1 +x:1 +碧黄 1 +x:1 +赛纪 1 +x:1 +浓郁 1 +x:1 +宇航 1 +x:1 +匡匡 1 +x:1 +里面 1 +x:1 +会友 1 +x:1 +职员 1 +x:1 +山脚 1 +x:1 +受益 1 +x:1 +险滩 1 +x:1 +脚跟 1 +x:1 +4 2166 +x:2166 +互惠待遇 1 +x:1 +山脉 1 +x:1 +山脊 1 +x:1 +酒器 1 +x:1 +生杀予夺 1 +x:1 +矫揉造作 1 +x:1 +西河北村 1 +x:1 +家境 1 +x:1 +社区性 1 +x:1 +画法 1 +x:1 +宏观 1 +x:1 +赛罢 1 +x:1 +别称 1 +x:1 +壁画库 1 +x:1 +口渴 1 +x:1 +弹腔 1 +x:1 +乳饮料 1 +x:1 +会厌 1 +x:1 +微机网 1 +x:1 +纪工委 1 +x:1 +百宝箱 1 +x:1 +鱼款 1 +x:1 +会厅 1 +x:1 +窑主 1 +x:1 +狱 4 +x:4 +结存 1 +x:1 +啰唆 1 +x:1 +电子光学 1 +x:1 +半程 1 +x:1 +退党 1 +x:1 +图带 1 +x:1 +山腰 1 +x:1 +一米板 1 +x:1 +报友 1 +x:1 +除草 1 +x:1 +一片冰心 1 +x:1 +雷公山 1 +x:1 +莘莘学子 1 +x:1 +深葬法 1 +x:1 +节 164 +x:164 +湾仔海 1 +x:1 +软科学 1 +x:1 +脚趾 1 +x:1 +佴 1 +x:1 +蚩尤寨 1 +x:1 +退兵 1 +x:1 +别离 1 +x:1 +退养 1 +x:1 +低缓 1 +x:1 +硬挺 1 +x:1 +绯色 1 +x:1 +情真意切 1 +x:1 +游击区 1 +x:1 +歃血结盟 1 +x:1 +老泪纵横 1 +x:1 +转嫁 1 +x:1 +监控户 1 +x:1 +变调 1 +x:1 +生生不息 1 +x:1 +童养媳 1 +x:1 +奋发向上 1 +x:1 +群英会 1 +x:1 +胡同口 1 +x:1 +亲者 1 +x:1 +粒度 1 +x:1 +各有所长 1 +x:1 +折扣率 1 +x:1 +冷眉冷眼 1 +x:1 +武夫 1 +x:1 +后生小子 1 +x:1 +详尽 1 +x:1 +亲耳 1 +x:1 +小牛犊 1 +x:1 +据此 1 +x:1 +滞销房 1 +x:1 +铁环 1 +x:1 +埃里斯特 1 +x:1 +增长期 1 +x:1 +啰嗦 1 +x:1 +水果摊 1 +x:1 +贵远贱近 1 +x:1 +五卅运动 1 +x:1 +无底洞 1 +x:1 +骑车人 1 +x:1 +延南 1 +x:1 +发起者 1 +x:1 +千古留芳 1 +x:1 +忧愁树 1 +x:1 +亲聆 1 +x:1 +展览厅 1 +x:1 +顺乎民心 1 +x:1 +新岁伊始 1 +x:1 +家塾 1 +x:1 +累累 1 +x:1 +报协 1 +x:1 +空耗 1 +x:1 +报升 1 +x:1 +墨尔本 1 +x:1 +邵刚乡 1 +x:1 +僻远 1 +x:1 +不怕牺牲 1 +x:1 +浓重 1 +x:1 +退出 1 +x:1 +苏黎世 1 +x:1 +枕木 1 +x:1 +盗拆 1 +x:1 +头额 1 +x:1 +家室 1 +x:1 +狗 67 +x:67 +账号 1 +x:1 +辉 127 +x:127 +皮山县 1 +x:1 +游人 1 +x:1 +家宴 1 +x:1 +头颈 1 +x:1 +英烈 1 +x:1 +头领 1 +x:1 +山高水长 1 +x:1 +头颅 1 +x:1 +收入型 1 +x:1 +航天桥 1 +x:1 +家宅 1 +x:1 +非生命 1 +x:1 +蒋家堰镇 1 +x:1 +演讲者 1 +x:1 +浮面 1 +x:1 +攻心 1 +x:1 +酒商 1 +x:1 +政敌 1 +x:1 +半票 1 +x:1 +大年初八 1 +x:1 +山航 1 +x:1 +家宝 1 +x:1 +薄冰 1 +x:1 +照理 1 +x:1 +得分王 1 +x:1 +样板戏 1 +x:1 +立体派 1 +x:1 +洞房花烛 1 +x:1 +逐年 1 +x:1 +息事宁人 1 +x:1 +变迁 1 +x:1 +报道社 1 +x:1 +得分率 1 +x:1 +刷拉拉 1 +x:1 +西邢村 1 +x:1 +前瓦村 1 +x:1 +以往 1 +x:1 +爬山越岭 1 +x:1 +危房棚 1 +x:1 +均等 1 +x:1 +藏红花 1 +x:1 +王加乡 1 +x:1 +牛皮菜 1 +x:1 +山色 1 +x:1 +盗抢 1 +x:1 +反比例 1 +x:1 +非公有 1 +x:1 +通城县 1 +x:1 +梁河县 1 +x:1 +宋庆龄 1 +x:1 +根艺 1 +x:1 +水仙花 1 +x:1 +冲锋枪 1 +x:1 +跺脚 1 +x:1 +窜犯 1 +x:1 +丑事 1 +x:1 +树林子 1 +x:1 +礼制 1 +x:1 +严家岗村 1 +x:1 +社劳党 1 +x:1 +主题 1 +x:1 +惯例 1 +x:1 +泛泛而论 1 +x:1 +叶舌 1 +x:1 +猪笼草 1 +x:1 +传动比 1 +x:1 +招干 1 +x:1 +耳提面命 1 +x:1 +盗打 1 +x:1 +张罗声 1 +x:1 +路政科 1 +x:1 +山芋 1 +x:1 +统摄 1 +x:1 +记者团 1 +x:1 +延寿 1 +x:1 +山花 1 +x:1 +惜贷 1 +x:1 +结业式 1 +x:1 +梅格 1 +x:1 +光辉 1 +x:1 +堆房 1 +x:1 +脚蹼 1 +x:1 +惜败 1 +x:1 +游丝 1 +x:1 +开发区 1 +x:1 +弯路 1 +x:1 +脚踏 1 +x:1 +故 106 +x:106 +文鸟 1 +x:1 +喀什市 1 +x:1 +辖段 1 +x:1 +侄孙女 1 +x:1 +相貌 1 +x:1 +脚踝 1 +x:1 +报偿 1 +x:1 +朝鲜队 1 +x:1 +装配式 1 +x:1 +适当 1 +x:1 +边角地 1 +x:1 +沥 1 +x:1 +攻坚战 1 +x:1 +右半 1 +x:1 +方块糖 1 +x:1 +变轨 1 +x:1 +走门子 1 +x:1 +夹壁墙 1 +x:1 +木兰拳 1 +x:1 +粉笔盒 1 +x:1 +盘存 1 +x:1 +受用 1 +x:1 +报停 1 +x:1 +代管权 1 +x:1 +肇事罪 1 +x:1 +关系网 1 +x:1 +鱼梁 1 +x:1 +吉祥寺 1 +x:1 +取之不尽 1 +x:1 +盛产期 1 +x:1 +放不放开 1 +x:1 +比阔气 1 +x:1 +捷报 1 +x:1 +堂皇 1 +x:1 +兴宁市 1 +x:1 +弹药 1 +x:1 +酒味 1 +x:1 +礼县 1 +x:1 +压 238 +x:238 +疏忽大意 1 +x:1 +适应 1 +x:1 +夜丰颂府 1 +x:1 +金凤还巢 1 +x:1 +嫁衣裳 1 +x:1 +讲叙 1 +x:1 +摊派款 1 +x:1 +水车前 1 +x:1 +适度 1 +x:1 +校时钟 1 +x:1 +郑家坊 1 +x:1 +山茶 1 +x:1 +台江区 1 +x:1 +定心丸 1 +x:1 +椰油 1 +x:1 +刷印科 1 +x:1 +付方 1 +x:1 +红皮书 1 +x:1 +瓶塞 1 +x:1 +质能 1 +x:1 +主顾 1 +x:1 +共利 1 +x:1 +酒吧 1 +x:1 +净利润率 1 +x:1 +宏论 1 +x:1 +报出 1 +x:1 +山草 1 +x:1 +大迈阿密 1 +x:1 +官名 1 +x:1 +盗掘 1 +x:1 +呀儿哟 1 +x:1 +南北向 1 +x:1 +银杏 1 +x:1 +图尔 1 +x:1 +放油区 1 +x:1 +退却 1 +x:1 +母畜 1 +x:1 +酒后 1 +x:1 +致信 1 +x:1 +倘然 1 +x:1 +估摸 1 +x:1 +山药 1 +x:1 +惯于 1 +x:1 +俯仰之间 1 +x:1 +调研科 1 +x:1 +来京 1 +x:1 +顿然 1 +x:1 +外三环 1 +x:1 +三圣桥 1 +x:1 +会元 1 +x:1 +里间 1 +x:1 +会党 1 +x:1 +肝气 1 +x:1 +钦差 1 +x:1 +神话 1 +x:1 +妙语连珠 1 +x:1 +藻井 1 +x:1 +獐子 1 +x:1 +轰击 1 +x:1 +氮肥 1 +x:1 +钦州 1 +x:1 +步行者 1 +x:1 +试纸 1 +x:1 +杂物堆 1 +x:1 +库尔德 1 +x:1 +形成 1 +x:1 +总任务 1 +x:1 +蒸汽型 1 +x:1 +形成期 1 +x:1 +太山庙村 1 +x:1 +受理 1 +x:1 +有口难言 1 +x:1 +师母 1 +x:1 +屋后 1 +x:1 +飞雁 1 +x:1 +山菊 1 +x:1 +冷轧板 1 +x:1 +报关 1 +x:1 +柱头 1 +x:1 +十字军 1 +x:1 +家婆 1 +x:1 +种植业 1 +x:1 +头饰 1 +x:1 +飞雨 1 +x:1 +飞雪 1 +x:1 +会儿 1 +x:1 +记者型 1 +x:1 +屋里 1 +x:1 +温度差 1 +x:1 +麦收地 1 +x:1 +谱子 1 +x:1 +下脚料 1 +x:1 +风雨同舟 1 +x:1 +地面孔 1 +x:1 +泡器 1 +x:1 +来人 1 +x:1 +退后 1 +x:1 +纵深处 1 +x:1 +低空 1 +x:1 +母爱 1 +x:1 +稔 1 +x:1 +文风 1 +x:1 +宾客 1 +x:1 +未来馆 1 +x:1 +姑老爷 1 +x:1 +幼稚园 1 +x:1 +伟人 1 +x:1 +抽烟 1 +x:1 +吼叫声 1 +x:1 +供电所 1 +x:1 +墨菊 1 +x:1 +统括 1 +x:1 +对照体 1 +x:1 +玄狐 1 +x:1 +磁效应 1 +x:1 +好好坏坏 1 +x:1 +酵母菌 1 +x:1 +梗阻 1 +x:1 +天生桥 1 +x:1 +珍爱 1 +x:1 +戏子 1 +x:1 +挑灯夜战 1 +x:1 +迎客 1 +x:1 +抽点 1 +x:1 +姘妇 1 +x:1 +报国 1 +x:1 +转车 1 +x:1 +飘飘 1 +x:1 +飘飞 1 +x:1 +吃得住 1 +x:1 +赛程 1 +x:1 +砖墙 1 +x:1 +北关区 1 +x:1 +湿渌渌 1 +x:1 +有起色 1 +x:1 +叫作 1 +x:1 +送货郎 1 +x:1 +唱诗班 1 +x:1 +粒子 1 +x:1 +形旁 1 +x:1 +硬是 1 +x:1 +自食其果 1 +x:1 +三马林达 1 +x:1 +爆破洞 1 +x:1 +简直 1 +x:1 +建德县 1 +x:1 +大选日 1 +x:1 +怨言 1 +x:1 +中建 1 +x:1 +镀膜 1 +x:1 +青滩 1 +x:1 +母牛 1 +x:1 +复活节 1 +x:1 +脚行 1 +x:1 +酒台 1 +x:1 +伟业 1 +x:1 +酒史 1 +x:1 +蚍蜉 1 +x:1 +赛站 1 +x:1 +延巫 1 +x:1 +墨荷 1 +x:1 +调研组 1 +x:1 +本味 1 +x:1 +拿波里 1 +x:1 +描画 1 +x:1 +谦辞 1 +x:1 +田家寨 1 +x:1 +线麻 1 +x:1 +多数百姓 1 +x:1 +黄浦江 1 +x:1 +垢 6 +x:6 +闻香 1 +x:1 +见证物 1 +x:1 +铁皮 1 +x:1 +印染厂 1 +x:1 +转念 1 +x:1 +别类 1 +x:1 +默哀 1 +x:1 +晴雨计 1 +x:1 +酒友 1 +x:1 +离婚率 1 +x:1 +出血量 1 +x:1 +铁盆 1 +x:1 +经书 1 +x:1 +师法 1 +x:1 +偷偷 1 +x:1 +一臂之力 1 +x:1 +挂果期 1 +x:1 +铁盒 1 +x:1 +天公 1 +x:1 +碣石 1 +x:1 +臂章 1 +x:1 +烷基 1 +x:1 +拉拉 1 +x:1 +永登 1 +x:1 +经久 1 +x:1 +标兵库 1 +x:1 +母狗 1 +x:1 +段木 1 +x:1 +酒厂 1 +x:1 +男队 1 +x:1 +漯河市 1 +x:1 +殖民者 1 +x:1 +示范林 1 +x:1 +宠信 1 +x:1 +通达街 1 +x:1 +刚才 1 +x:1 +宝丰县 1 +x:1 +母猪 1 +x:1 +飘香 1 +x:1 +拦洪坝 1 +x:1 +附信 1 +x:1 +十字坡 1 +x:1 +农事图 1 +x:1 +低等 1 +x:1 +统揽 1 +x:1 +排水管 1 +x:1 +胜利村 1 +x:1 +舞者 1 +x:1 +转年 1 +x:1 +渲 1 +x:1 +转干 1 +x:1 +延展 1 +x:1 +生机勃发 1 +x:1 +硬板 1 +x:1 +泛泛而谈 1 +x:1 +股额 1 +x:1 +较真儿 1 +x:1 +万县市 1 +x:1 +青年装 1 +x:1 +来书 1 +x:1 +出航 1 +x:1 +公益 1 +x:1 +月全食 1 +x:1 +夸胡 1 +x:1 +史家 1 +x:1 +穑稼 1 +x:1 +阴风 1 +x:1 +硬朗 1 +x:1 +悔过书 1 +x:1 +便民 1 +x:1 +选举人 1 +x:1 +实寄封 1 +x:1 +英灵 1 +x:1 +毛方 1 +x:1 +楚楚静立 1 +x:1 +晓园路 1 +x:1 +独揽 1 +x:1 +运销户 1 +x:1 +平方尺 1 +x:1 +庸庸碌碌 1 +x:1 +股票版 1 +x:1 +硬木 1 +x:1 +甩卖 1 +x:1 +鱼漂 1 +x:1 +烹 6 +x:6 +女式 1 +x:1 +吟风弄月 1 +x:1 +戆直 1 +x:1 +轻歌剧院 1 +x:1 +摩电灯 1 +x:1 +墨色 1 +x:1 +下寨村 1 +x:1 +会址 1 +x:1 +钠灯 1 +x:1 +宏赡 1 +x:1 +沙埔村 1 +x:1 +五音阶 1 +x:1 +旁边儿 1 +x:1 +耀斑 1 +x:1 +项羽 1 +x:1 +药业 1 +x:1 +膘 1 +x:1 +气管炎 1 +x:1 +戏迷角 1 +x:1 +翠青 1 +x:1 +已经 1 +x:1 +爆破法 1 +x:1 +文饰 1 +x:1 +夸耀 1 +x:1 +普罗旺斯 1 +x:1 +秋雨庵 1 +x:1 +堆放 1 +x:1 +家小 1 +x:1 +谱 42 +x:42 +取存款 1 +x:1 +深透 1 +x:1 +药丸 1 +x:1 +时风时雨 1 +x:1 +画案 1 +x:1 +探空仪 1 +x:1 +审查室 1 +x:1 +步行虫 1 +x:1 +祝辞 1 +x:1 +致使 1 +x:1 +碘钨灯 1 +x:1 +无知 1 +x:1 +畜棚 1 +x:1 +南征北战 1 +x:1 +出芽 1 +x:1 +乙丑 1 +x:1 +摈弃 1 +x:1 +渡轮 1 +x:1 +闷罐车 1 +x:1 +迎娶 1 +x:1 +国际台 1 +x:1 +酣 7 +x:7 +家居 1 +x:1 +锡伯族 1 +x:1 +药书 1 +x:1 +干结核量 1 +x:1 +兔娃 1 +x:1 +杰出 1 +x:1 +铁石 1 +x:1 +经作 1 +x:1 +十字型 1 +x:1 +前俯后仰 1 +x:1 +勺 5 +x:5 +铁矿 1 +x:1 +一代楷模 1 +x:1 +酒兴 1 +x:1 +夜阑人静 1 +x:1 +酒具 1 +x:1 +保修卡 1 +x:1 +自注式 1 +x:1 +饮用水 1 +x:1 +地道战 1 +x:1 +桃源梦 1 +x:1 +鱼池 1 +x:1 +适宜 1 +x:1 +淀粉厂 1 +x:1 +山神灵物 1 +x:1 +二修所 1 +x:1 +福塔莱萨 1 +x:1 +自主神经 1 +x:1 +卫冕战 1 +x:1 +南礼士路 1 +x:1 +鱼汛 1 +x:1 +发展极 1 +x:1 +图片集 1 +x:1 +清白 1 +x:1 +里道 1 +x:1 +抓拍 1 +x:1 +秘书局 1 +x:1 +文言文 1 +x:1 +保修单 1 +x:1 +博弈 1 +x:1 +但 8150 +x:8150 +酒儿 1 +x:1 +世界杯赛 1 +x:1 +项类 1 +x:1 +中山陵 1 +x:1 +城北乡 1 +x:1 +非警务 1 +x:1 +距 197 +x:197 +惠泽 1 +x:1 +国税 1 +x:1 +岂敢 1 +x:1 +心潮翻腾 1 +x:1 +西滨村 1 +x:1 +装潢 1 +x:1 +吸食 1 +x:1 +一省两地 1 +x:1 +攻守 1 +x:1 +快餐业 1 +x:1 +排难解纷 1 +x:1 +意识流 1 +x:1 +企业界 1 +x:1 +出自 1 +x:1 +隆宝滩 1 +x:1 +法网 1 +x:1 +仲裁庭 1 +x:1 +茔地 1 +x:1 +弑 1 +x:1 +救护队员 1 +x:1 +会员 1 +x:1 +气冲冲 1 +x:1 +岂料 1 +x:1 +库款 1 +x:1 +报名 1 +x:1 +剥削 1 +x:1 +志愿兵 1 +x:1 +发展期 1 +x:1 +皆大欢喜 1 +x:1 +抓手 1 +x:1 +传真件 1 +x:1 +沥青厂 1 +x:1 +会同 1 +x:1 +挨冻 1 +x:1 +会后 1 +x:1 +重修 1 +x:1 +会合 1 +x:1 +浓雾 1 +x:1 +虚汗 1 +x:1 +钓鱼者 1 +x:1 +束之高阁 1 +x:1 +云翳 1 +x:1 +鱼油 1 +x:1 +烘托 1 +x:1 +批发点 1 +x:1 +长驱 1 +x:1 +硬撑 1 +x:1 +税则 1 +x:1 +退回 1 +x:1 +礼器 1 +x:1 +龙肝凤髓 1 +x:1 +起跑线 1 +x:1 +单元化 1 +x:1 +毕竟 1 +x:1 +付息 1 +x:1 +夏至线 1 +x:1 +报告 1 +x:1 +遥岑 1 +x:1 +跟头 1 +x:1 +息 36 +x:36 +发展权 1 +x:1 +家当 1 +x:1 +根芽 1 +x:1 +专科学校 1 +x:1 +僧多粥少 1 +x:1 +面交 1 +x:1 +落地窗 1 +x:1 +浒山 1 +x:1 +阴骘 1 +x:1 +秋冬季 1 +x:1 +股骨 1 +x:1 +钍 2 +x:2 +家庭 1 +x:1 +救生圈 1 +x:1 +苏扎克区 1 +x:1 +冷藏室 1 +x:1 +迎声 1 +x:1 +爪牙 1 +x:1 +苏古笃 1 +x:1 +面人 1 +x:1 +平等权 1 +x:1 +褡包 1 +x:1 +小雨雪 1 +x:1 +不骄不躁 1 +x:1 +受热 1 +x:1 +郴州市 1 +x:1 +报喜 1 +x:1 +铁甲 1 +x:1 +家底 1 +x:1 +三三五五 1 +x:1 +退场 1 +x:1 +日就月将 1 +x:1 +铁画 1 +x:1 +福田 1 +x:1 +霍里霍川 1 +x:1 +名特优 1 +x:1 +记者区 1 +x:1 +直线式 1 +x:1 +镌 3 +x:3 +面价 1 +x:1 +改由 1 +x:1 +违章人 1 +x:1 +力气活 1 +x:1 +逐字 1 +x:1 +银朱 1 +x:1 +探头探脑 1 +x:1 +酒候 1 +x:1 +丘岗地 1 +x:1 +沙拐枣 1 +x:1 +油毛毡 1 +x:1 +细问 1 +x:1 +夜不能寐 1 +x:1 +晴雨表 1 +x:1 +进口药 1 +x:1 +殊荣 1 +x:1 +制衣厂 1 +x:1 +椰树 1 +x:1 +水阳镇 1 +x:1 +会商 1 +x:1 +迅敏 1 +x:1 +面临 1 +x:1 +西服厂 1 +x:1 +载货车 1 +x:1 +添加 1 +x:1 +宁河镇 1 +x:1 +家常 1 +x:1 +超长穗型 1 +x:1 +顿生 1 +x:1 +三岔路口 1 +x:1 +栖止 1 +x:1 +龙 265 +x:265 +花明楼 1 +x:1 +林牧业 1 +x:1 +救生垫 1 +x:1 +面上 1 +x:1 +例牌 1 +x:1 +挪威式 1 +x:1 +面世 1 +x:1 +桧柏 1 +x:1 +受灾 1 +x:1 +毕恭毕敬 1 +x:1 +舞弊 1 +x:1 +因此 1 +x:1 +名义权 1 +x:1 +转岗 1 +x:1 +伯仲之间 1 +x:1 +磨山镇 1 +x:1 +肚皮 1 +x:1 +来世 1 +x:1 +顶头上司 1 +x:1 +延庆 1 +x:1 +简略 1 +x:1 +九天 1 +x:1 +冰醋酸 1 +x:1 +报商 1 +x:1 +装满 1 +x:1 +黑色火药 1 +x:1 +物美价廉 1 +x:1 +记者厅 1 +x:1 +撤离 1 +x:1 +退堂 1 +x:1 +墨迹 1 +x:1 +出轨 1 +x:1 +亳州城 1 +x:1 +字母 1 +x:1 +宽余 1 +x:1 +喷饭 1 +x:1 +鲜水河 1 +x:1 +边防站 1 +x:1 +特格尔 1 +x:1 +番薯 1 +x:1 +遮阳帽 1 +x:1 +上装 1 +x:1 +林管局 1 +x:1 +乌云山村 1 +x:1 +产权证 1 +x:1 +创建性 1 +x:1 +罗盘报 1 +x:1 +被 7146 +x:7146 +受贿罪 1 +x:1 +结实 1 +x:1 +通讯网 1 +x:1 +看护房 1 +x:1 +应用型 1 +x:1 +西医大 1 +x:1 +实验区 1 +x:1 +增长源 1 +x:1 +供大于求 1 +x:1 +转包 1 +x:1 +旧城区 1 +x:1 +接触网 1 +x:1 +睁眼瞎子 1 +x:1 +转化 1 +x:1 +苎麻 1 +x:1 +亲见 1 +x:1 +客串 1 +x:1 +新安江 1 +x:1 +文格 1 +x:1 +相依相克 1 +x:1 +铁线蕨 1 +x:1 +简章 1 +x:1 +螺旋式 1 +x:1 +邛海 1 +x:1 +岂止 1 +x:1 +民俗学史 1 +x:1 +恨入骨髓 1 +x:1 +头头是道 1 +x:1 +缉获 1 +x:1 +稀释液 1 +x:1 +汪甸乡 1 +x:1 +院规 1 +x:1 +姘头 1 +x:1 +阴门 1 +x:1 +全训率 1 +x:1 +冀南区 1 +x:1 +溃疡 1 +x:1 +滹沱河 1 +x:1 +耍无赖 1 +x:1 +调 294 +x:294 +实验厂 1 +x:1 +说头儿 1 +x:1 +分毛沟 1 +x:1 +越战越勇 1 +x:1 +靛蓝 1 +x:1 +乘虚而入 1 +x:1 +嘉义 1 +x:1 +清洗业 1 +x:1 +玒 3 +x:3 +叶茎 1 +x:1 +铁窗 1 +x:1 +转发 1 +x:1 +堆栈 1 +x:1 +幽深 1 +x:1 +勤朴 1 +x:1 +受罚 1 +x:1 +转变 1 +x:1 +病包儿 1 +x:1 +转口 1 +x:1 +导游证 1 +x:1 +向往 1 +x:1 +庄稼人 1 +x:1 +受罪 1 +x:1 +汇聚 1 +x:1 +礼堂 1 +x:1 +叹为观止 1 +x:1 +转台 1 +x:1 +酒忌 1 +x:1 +多胚生殖 1 +x:1 +出运 1 +x:1 +台座 1 +x:1 +牵动力 1 +x:1 +臆 1 +x:1 +嫌 72 +x:72 +通光率 1 +x:1 +家具 1 +x:1 +住院费 1 +x:1 +客人 1 +x:1 +夏至点 1 +x:1 +抚养费 1 +x:1 +起跑点 1 +x:1 +匣子 1 +x:1 +刹那间 1 +x:1 +吸附 1 +x:1 +废纸屑 1 +x:1 +立体 1 +x:1 +夸赞 1 +x:1 +孙镇村 1 +x:1 +衣食住医 1 +x:1 +天长水阔 1 +x:1 +棉大衣 1 +x:1 +雷达表 1 +x:1 +喷香 1 +x:1 +夜盲症 1 +x:1 +纠章 1 +x:1 +明目张胆 1 +x:1 +立交 1 +x:1 +治疗费 1 +x:1 +沙漠化 1 +x:1 +巴伊亚州 1 +x:1 +节耗 1 +x:1 +铁笔 1 +x:1 +曦 25 +x:25 +毕生 1 +x:1 +橄榄石 1 +x:1 +客位 1 +x:1 +楚河州 1 +x:1 +昌平园 1 +x:1 +立于 1 +x:1 +进口货 1 +x:1 +棉株 1 +x:1 +立井 1 +x:1 +客体 1 +x:1 +中卫县 1 +x:1 +甩开 1 +x:1 +钓鱼迷 1 +x:1 +义正词严 1 +x:1 +铁笼 1 +x:1 +综上所述 1 +x:1 +电业 1 +x:1 +铁筋 1 +x:1 +穷抖阔 1 +x:1 +报导 1 +x:1 +丁香 1 +x:1 +酒席 1 +x:1 +爬高 1 +x:1 +烤 21 +x:21 +脉管炎 1 +x:1 +飞鱼 1 +x:1 +碧青 1 +x:1 +译著 1 +x:1 +编导者 1 +x:1 +感染者 1 +x:1 +会审 1 +x:1 +山西 1 +x:1 +国际周 1 +x:1 +转制 1 +x:1 +受纳 1 +x:1 +无独有偶 1 +x:1 +顶 261 +x:261 +熟年 1 +x:1 +写作组 1 +x:1 +低矮 1 +x:1 +贫病交迫 1 +x:1 +铁箍 1 +x:1 +校正 1 +x:1 +简笔 1 +x:1 +西服裙 1 +x:1 +临危 1 +x:1 +炕头儿 1 +x:1 +期 516 +x:516 +铁管 1 +x:1 +奇巧 1 +x:1 +浓香 1 +x:1 +通讯组 1 +x:1 +节肢 1 +x:1 +淫邪 1 +x:1 +电价 1 +x:1 +亏损社 1 +x:1 +母羊 1 +x:1 +节育 1 +x:1 +电仪 1 +x:1 +立业 1 +x:1 +锁头 1 +x:1 +题海战术 1 +x:1 +出身 1 +x:1 +星移斗换 1 +x:1 +建德市 1 +x:1 +人权委 1 +x:1 +烤鱼 1 +x:1 +收入层 1 +x:1 +署名 1 +x:1 +鸬鹚 1 +x:1 +艺无止境 1 +x:1 +茉莉 1 +x:1 +酒店 1 +x:1 +行善 1 +x:1 +因故 1 +x:1 +远道而来 1 +x:1 +闪烁生辉 1 +x:1 +转动 1 +x:1 +土生土长 1 +x:1 +文锦 1 +x:1 +赋诗 1 +x:1 +见习期 1 +x:1 +节能 1 +x:1 +时势 1 +x:1 +作文赛 1 +x:1 +掂斤播两 1 +x:1 +铁砂 1 +x:1 +豆浆机 1 +x:1 +急智 1 +x:1 +殷勤 1 +x:1 +外经贸委 1 +x:1 +文集 1 +x:1 +文雅 1 +x:1 +畦内 1 +x:1 +议和 1 +x:1 +细长 1 +x:1 +存世 1 +x:1 +重版本 1 +x:1 +转入 1 +x:1 +铁砧 1 +x:1 +出资 1 +x:1 +新建乡 1 +x:1 +单音词 1 +x:1 +签字 1 +x:1 +出赛 1 +x:1 +飞鼠 1 +x:1 +好容易 1 +x:1 +相形失色 1 +x:1 +红细胞 1 +x:1 +据悉 1 +x:1 +异端邪说 1 +x:1 +画架 1 +x:1 +张口结舌 1 +x:1 +池 41 +x:41 +心惊胆颤 1 +x:1 +记者席 1 +x:1 +家史 1 +x:1 +奥方 1 +x:1 +彩号 1 +x:1 +省辖 1 +x:1 +木双镇 1 +x:1 +添彩 1 +x:1 +制冰机 1 +x:1 +无奇不有 1 +x:1 +指示灯 1 +x:1 +家参 1 +x:1 +统治 1 +x:1 +师承 1 +x:1 +彩儿 1 +x:1 +吃亏论 1 +x:1 +吞吐量 1 +x:1 +默写 1 +x:1 +头部 1 +x:1 +一本初衷 1 +x:1 +飘零 1 +x:1 +勤政廉洁 1 +x:1 +飞龙 1 +x:1 +出路 1 +x:1 +新教徒 1 +x:1 +画板 1 +x:1 +肩头 1 +x:1 +校歌 1 +x:1 +勤政 1 +x:1 +硬棒 1 +x:1 +气罐 1 +x:1 +生态所 1 +x:1 +私有者 1 +x:1 +兵役 1 +x:1 +交易场 1 +x:1 +多姿多态 1 +x:1 +阴霾 1 +x:1 +女士 1 +x:1 +大巧若拙 1 +x:1 +小篆 1 +x:1 +攻坚 1 +x:1 +运行部 1 +x:1 +存亡 1 +x:1 +因明 1 +x:1 +安得拉 1 +x:1 +电视人 1 +x:1 +家化 1 +x:1 +讶异 1 +x:1 +刻 102 +x:102 +社主任 1 +x:1 +茹毛饮血 1 +x:1 +伤病率 1 +x:1 +上街 1 +x:1 +浅 50 +x:50 +以快制胜 1 +x:1 +多巴哥 1 +x:1 +芍药 1 +x:1 +城郊 1 +x:1 +会堂 1 +x:1 +柴树 1 +x:1 +汉人 1 +x:1 +橄榄球 1 +x:1 +母系 1 +x:1 +画本 1 +x:1 +源源而来 1 +x:1 +受累 1 +x:1 +出超 1 +x:1 +滨州市 1 +x:1 +影视界 1 +x:1 +图景 1 +x:1 +单元式 1 +x:1 +剑桥 1 +x:1 +地大物博 1 +x:1 +家务 1 +x:1 +阴晴寒暑 1 +x:1 +收入库 1 +x:1 +飞鸟 1 +x:1 +礼宾 1 +x:1 +良种棉 1 +x:1 +僖 1 +x:1 +投融资 1 +x:1 +烤麸 1 +x:1 +育才 1 +x:1 +优 166 +x:166 +潮卷浪涌 1 +x:1 +蜂王浆 1 +x:1 +伢儿 1 +x:1 +科学会 1 +x:1 +飞鸿 1 +x:1 +脂粉味 1 +x:1 +主销区 1 +x:1 +净重量 1 +x:1 +旁听 1 +x:1 +外逃 1 +x:1 +自幼 1 +x:1 +爆破手 1 +x:1 +遥相呼应 1 +x:1 +飞鸥 1 +x:1 +噘嘴 1 +x:1 +忤逆不孝 1 +x:1 +变蛋 1 +x:1 +龙盘虎踞 1 +x:1 +婺源县 1 +x:1 +酒尾 1 +x:1 +名人战 1 +x:1 +事实关 1 +x:1 +薄壁 1 +x:1 +头里 1 +x:1 +柳条帽 1 +x:1 +下文 1 +x:1 +有机玻璃 1 +x:1 +尚沟村 1 +x:1 +人权学 1 +x:1 +装扮 1 +x:1 +退学 1 +x:1 +慕名弃实 1 +x:1 +放映 1 +x:1 +飞鹰 1 +x:1 +时尚者 1 +x:1 +简称 1 +x:1 +进口车 1 +x:1 +图名 1 +x:1 +阴雨 1 +x:1 +受精 1 +x:1 +兼 867 +x:867 +烤鸭 1 +x:1 +泽村 1 +x:1 +节节 1 +x:1 +退守 1 +x:1 +文静 1 +x:1 +棕箱 1 +x:1 +吕 396 +x:396 +砖块 1 +x:1 +改称 1 +x:1 +报失 1 +x:1 +暖风机 1 +x:1 +麻雀声 1 +x:1 +定 504 +x:504 +改种 1 +x:1 +独来独往 1 +x:1 +阴阳 1 +x:1 +取乐 1 +x:1 +速决 1 +x:1 +文革 1 +x:1 +专攻 1 +x:1 +工读生 1 +x:1 +鄢陵县 1 +x:1 +杭州市 1 +x:1 +浆膜 1 +x:1 +方针性 1 +x:1 +吃穿住行 1 +x:1 +特科 1 +x:1 +松花 1 +x:1 +相亲相爱 1 +x:1 +乙 42 +x:42 +度假者 1 +x:1 +真实性 1 +x:1 +波兴浪涌 1 +x:1 +迎合 1 +x:1 +宜宾县 1 +x:1 +坏账 1 +x:1 +包换 1 +x:1 +逗逗乐乐 1 +x:1 +破产法 1 +x:1 +剥弃 1 +x:1 +雁门关 1 +x:1 +息影 1 +x:1 +阴险 1 +x:1 +宝马 1 +x:1 +上衣 1 +x:1 +步行街 1 +x:1 +巴库 1 +x:1 +脚背 1 +x:1 +大型机 1 +x:1 +各抒己见 1 +x:1 +纹路 1 +x:1 +宾县 1 +x:1 +攻击 1 +x:1 +出警 1 +x:1 +冷冰冰 1 +x:1 +连珠灯 1 +x:1 +天祝县 1 +x:1 +孔道 1 +x:1 +诗文体 1 +x:1 +转基因 1 +x:1 +只鳞片爪 1 +x:1 +评审会 1 +x:1 +心口如一 1 +x:1 +非儿戏 1 +x:1 +简约 1 +x:1 +能侃善聊 1 +x:1 +山谷 1 +x:1 +巡诊队 1 +x:1 +机砖厂 1 +x:1 +活猪 1 +x:1 +实验地 1 +x:1 +报废 1 +x:1 +洗衣粉厂 1 +x:1 +报应 1 +x:1 +钻 123 +x:123 +简练 1 +x:1 +满天星 1 +x:1 +尤尔科夫 1 +x:1 +退居 1 +x:1 +留声机 1 +x:1 +微薄 1 +x:1 +会庆 1 +x:1 +沐石河乡 1 +x:1 +转圈 1 +x:1 +窗上 1 +x:1 +灿烂辉煌 1 +x:1 +报建 1 +x:1 +劳动对象 1 +x:1 +头雁 1 +x:1 +长踞 1 +x:1 +报廊 1 +x:1 +休斯顿 1 +x:1 +蛙鸣 1 +x:1 +坚韧 1 +x:1 +企业群 1 +x:1 +股金 1 +x:1 +九头鸟 1 +x:1 +边防线 1 +x:1 +昌平县 1 +x:1 +记者堆 1 +x:1 +二青洞 1 +x:1 +攻关 1 +x:1 +情怀厅 1 +x:1 +圆锥形 1 +x:1 +魔掌 1 +x:1 +干鲜果 1 +x:1 +农村所 1 +x:1 +纵队 1 +x:1 +混浊 1 +x:1 +苛杂 1 +x:1 +政府 1 +x:1 +飘逝 1 +x:1 +年代学 1 +x:1 +牌手 1 +x:1 +芗 1 +x:1 +蚜 1 +x:1 +戏台 1 +x:1 +戏友 1 +x:1 +十有八九 1 +x:1 +谱号 1 +x:1 +铁纪 1 +x:1 +改组 1 +x:1 +氟利昂 1 +x:1 +铁纱 1 +x:1 +三长两短 1 +x:1 +飘逸 1 +x:1 +批发站 1 +x:1 +醒脑提神 1 +x:1 +攻克 1 +x:1 +中经网 1 +x:1 +铁线 1 +x:1 +薄弱 1 +x:1 +酒宴 1 +x:1 +酒家 1 +x:1 +会师 1 +x:1 +出让 1 +x:1 +项目 1 +x:1 +情深意浓 1 +x:1 +村班子 1 +x:1 +旁及 1 +x:1 +侦探小说 1 +x:1 +余兴未尽 1 +x:1 +伸缩式 1 +x:1 +言外之意 1 +x:1 +连续 1 +x:1 +荒废 1 +x:1 +咨询业 1 +x:1 +如上所述 1 +x:1 +伦敦帝国 1 +x:1 +瞎说 1 +x:1 +凤翔 1 +x:1 +文选 1 +x:1 +大盘股 1 +x:1 +刹时间 1 +x:1 +调换费 1 +x:1 +瞎诌 1 +x:1 +轩岗乡 1 +x:1 +谧静 1 +x:1 +妄想 1 +x:1 +落地煤 1 +x:1 +永新县 1 +x:1 +瞎话 1 +x:1 +口干舌燥 1 +x:1 +无人区 1 +x:1 +报幕 1 +x:1 +邦交 1 +x:1 +画意 1 +x:1 +捞刀河 1 +x:1 +延安市 1 +x:1 +廉洁经 1 +x:1 +五陵原 1 +x:1 +戏剧 1 +x:1 +小型机 1 +x:1 +秦俑学 1 +x:1 +会心 1 +x:1 +文采 1 +x:1 +腰岗山 1 +x:1 +连成一片 1 +x:1 +林东 1 +x:1 +林丛 1 +x:1 +林业 1 +x:1 +弹起 1 +x:1 +高坪区 1 +x:1 +打牌 1 +x:1 +窥 5 +x:5 +黄啤酒 1 +x:1 +林中 1 +x:1 +讲经说法 1 +x:1 +鱼杆 1 +x:1 +纠结 1 +x:1 +车票费 1 +x:1 +山货 1 +x:1 +成长性 1 +x:1 +金坛市 1 +x:1 +同工异曲 1 +x:1 +代言人 1 +x:1 +木锯厂 1 +x:1 +谱列 1 +x:1 +杨凌 1 +x:1 +实用主义 1 +x:1 +图制 1 +x:1 +细雨 1 +x:1 +没谱 1 +x:1 +冬去春来 1 +x:1 +纠纷 1 +x:1 +俗 19 +x:19 +旧城 1 +x:1 +裙 5 +x:5 +劳者 1 +x:1 +少年儿童 1 +x:1 +老成持重 1 +x:1 +籽屑 1 +x:1 +七彩帆 1 +x:1 +针纺织品 1 +x:1 +整队 1 +x:1 +延吉 1 +x:1 +出言 1 +x:1 +企业级 1 +x:1 +会徽 1 +x:1 +阴部 1 +x:1 +空对空 1 +x:1 +改编 1 +x:1 +手扳 1 +x:1 +拔尖儿 1 +x:1 +唯一性 1 +x:1 +件件 1 +x:1 +千分表 1 +x:1 +半盔 1 +x:1 +省行 1 +x:1 +甩手 1 +x:1 +跟前 1 +x:1 +简编 1 +x:1 +年少 1 +x:1 +林产 1 +x:1 +柏尼加队 1 +x:1 +应诊 1 +x:1 +丁苯吡 1 +x:1 +盘外 1 +x:1 +弹跃 1 +x:1 +简缩 1 +x:1 +卖锭 1 +x:1 +外经外贸 1 +x:1 +萱 8 +x:8 +蚱蜢 1 +x:1 +付款 1 +x:1 +事实型 1 +x:1 +黎平县 1 +x:1 +适值 1 +x:1 +通讯站 1 +x:1 +格登碑 1 +x:1 +局促不安 1 +x:1 +试生产 1 +x:1 +飞飞 1 +x:1 +逐出 1 +x:1 +人类学者 1 +x:1 +阴道 1 +x:1 +一面之词 1 +x:1 +财神 1 +x:1 +剥夺 1 +x:1 +脚脖 1 +x:1 +圆形 1 +x:1 +象牙者 1 +x:1 +吃老本 1 +x:1 +木材厂 1 +x:1 +朝夕相处 1 +x:1 +影视片 1 +x:1 +铁翼 1 +x:1 +山路 1 +x:1 +图典 1 +x:1 +突破性 1 +x:1 +缺水量 1 +x:1 +瓶啤 1 +x:1 +盘大 1 +x:1 +无中继 1 +x:1 +彩南 1 +x:1 +美容院 1 +x:1 +付梓 1 +x:1 +统检 1 +x:1 +忆述 1 +x:1 +攻取 1 +x:1 +邪说 1 +x:1 +曲桑寺 1 +x:1 +退席 1 +x:1 +芳 182 +x:182 +边防系 1 +x:1 +律诗 1 +x:1 +装机 1 +x:1 +容 50 +x:50 +颊骨 1 +x:1 +叉路口 1 +x:1 +百口泉 1 +x:1 +九七年 1 +x:1 +亲近 1 +x:1 +图儿 1 +x:1 +韩村河 1 +x:1 +酸文假醋 1 +x:1 +硬气 1 +x:1 +同位素 1 +x:1 +密闭性 1 +x:1 +地区性 1 +x:1 +通讯社 1 +x:1 +郭沫若 1 +x:1 +河晏水清 1 +x:1 +处理关 1 +x:1 +柴油 1 +x:1 +图书界 1 +x:1 +前沿科学 1 +x:1 +浮想翩翩 1 +x:1 +酱豆腐 1 +x:1 +柴河 1 +x:1 +谱儿 1 +x:1 +堆满 1 +x:1 +王村乡 1 +x:1 +红庙岭 1 +x:1 +夸诞 1 +x:1 +水陆空 1 +x:1 +濮阳 1 +x:1 +泸沽湖 1 +x:1 +低热 1 +x:1 +册次 1 +x:1 +霞浦县 1 +x:1 +顺口溜儿 1 +x:1 +礼帽 1 +x:1 +沧桑 1 +x:1 +倾慕 1 +x:1 +段家寨 1 +x:1 +退库 1 +x:1 +攻占 1 +x:1 +不可或缺 1 +x:1 +会展 1 +x:1 +制冷档 1 +x:1 +礼帖 1 +x:1 +匠心 1 +x:1 +骷髅 1 +x:1 +彻夜未眠 1 +x:1 +浇 84 +x:84 +爱才如命 1 +x:1 +丫 2 +x:2 +观景台 1 +x:1 +县 1638 +x:1638 +多彩重绘 1 +x:1 +金溪县 1 +x:1 +番茄 1 +x:1 +标志点 1 +x:1 +权欲熏心 1 +x:1 +摇蚊 1 +x:1 +二郎腿 1 +x:1 +牵连 1 +x:1 +许可 1 +x:1 +谱写 1 +x:1 +当阳街 1 +x:1 +妨碍 1 +x:1 +年近古稀 1 +x:1 +工薪层 1 +x:1 +爱好者 1 +x:1 +低点 1 +x:1 +库尔勒 1 +x:1 +创业人 1 +x:1 +新区带 1 +x:1 +高碳钢 1 +x:1 +家财卡 1 +x:1 +赣州市 1 +x:1 +羊毛衫 1 +x:1 +浓黑 1 +x:1 +苛政 1 +x:1 +浦江 1 +x:1 +万万岁 1 +x:1 +特混舰队 1 +x:1 +水俣病 1 +x:1 +分厘卡 1 +x:1 +军转办 1 +x:1 +二十二时 1 +x:1 +政府性 1 +x:1 +手袋 1 +x:1 +鸬鹚鸟 1 +x:1 +青年节 1 +x:1 +变节 1 +x:1 +言不及义 1 +x:1 +鲍 70 +x:70 +甩头 1 +x:1 +嘻嘻哈哈 1 +x:1 +三道河子 1 +x:1 +财神爷 1 +x:1 +失业者 1 +x:1 +出行 1 +x:1 +铁索 1 +x:1 +出血 1 +x:1 +山形县 1 +x:1 +海神节 1 +x:1 +大喜事 1 +x:1 +薯类 1 +x:1 +订书机 1 +x:1 +砺 2 +x:2 +险情 1 +x:1 +收发室 1 +x:1 +亲身 1 +x:1 +生态林 1 +x:1 +砖厂 1 +x:1 +班后 1 +x:1 +骨腾肉飞 1 +x:1 +攻势 1 +x:1 +家园 1 +x:1 +画押 1 +x:1 +妙手空空 1 +x:1 +这么些 1 +x:1 +车体 1 +x:1 +画报 1 +x:1 +薛埠镇 1 +x:1 +实验员 1 +x:1 +险患 1 +x:1 +秦俑头 1 +x:1 +半球 1 +x:1 +寻章摘句 1 +x:1 +简明版 1 +x:1 +黑龙队 1 +x:1 +包揽 1 +x:1 +飞驰 1 +x:1 +聚丙烯 1 +x:1 +匠师 1 +x:1 +画折 1 +x:1 +山轿 1 +x:1 +充充电 1 +x:1 +演讲赛 1 +x:1 +画技 1 +x:1 +泡崖 1 +x:1 +支撑轮 1 +x:1 +退役 1 +x:1 +昭示 1 +x:1 +酒壶 1 +x:1 +倚山傍势 1 +x:1 +生态村 1 +x:1 +散文诗 1 +x:1 +秦王峡 1 +x:1 +抽签 1 +x:1 +毕现 1 +x:1 +通宵达旦 1 +x:1 +大天鹅 1 +x:1 +刑二庭 1 +x:1 +洗 183 +x:183 +年尾 1 +x:1 +前前后后 1 +x:1 +拉马拉 1 +x:1 +释迦牟尼 1 +x:1 +叵测之心 1 +x:1 +镇原县 1 +x:1 +淘金热 1 +x:1 +铺平 1 +x:1 +低能儿 1 +x:1 +璀璨夺目 1 +x:1 +工会法 1 +x:1 +逐厂 1 +x:1 +枰 2 +x:2 +宝鸡 1 +x:1 +英名盖世 1 +x:1 +图像 1 +x:1 +画手 1 +x:1 +非机动车 1 +x:1 +劳苦 1 +x:1 +唯心主义 1 +x:1 +削 30 +x:30 +伤筋动骨 1 +x:1 +血防办 1 +x:1 +微观世界 1 +x:1 +地下层 1 +x:1 +逐句 1 +x:1 +中关村 1 +x:1 +审问 1 +x:1 +勤恳 1 +x:1 +库图佐夫 1 +x:1 +坐地客 1 +x:1 +童颜鹤发 1 +x:1 +画成 1 +x:1 +总经理部 1 +x:1 +奉化市 1 +x:1 +剩 63 +x:63 +落辉 1 +x:1 +奴颜卑膝 1 +x:1 +淫雨 1 +x:1 +和光同尘 1 +x:1 +马耳他 1 +x:1 +迎候 1 +x:1 +甘巴拉 1 +x:1 +电缆线 1 +x:1 +变色 1 +x:1 +改扩 1 +x:1 +霉变 1 +x:1 +电传机 1 +x:1 +闫 3 +x:3 +下港乡 1 +x:1 +餐风宿露 1 +x:1 +银质奖 1 +x:1 +劳务工 1 +x:1 +墨韵 1 +x:1 +棉毛裤 1 +x:1 +菟丝子 1 +x:1 +烤箱 1 +x:1 +忠言逆耳 1 +x:1 +票贩子 1 +x:1 +笔头儿 1 +x:1 +唉声叹气 1 +x:1 +简报 1 +x:1 +告老还乡 1 +x:1 +危机四伏 1 +x:1 +支链反应 1 +x:1 +硬物 1 +x:1 +火焰 1 +x:1 +懦者 1 +x:1 +弹道 1 +x:1 +尽心尽力 1 +x:1 +林区 1 +x:1 +才力 1 +x:1 +派 603 +x:603 +低温 1 +x:1 +山道 1 +x:1 +天蓝色 1 +x:1 +行政化 1 +x:1 +逝世者 1 +x:1 +开采业 1 +x:1 +沙特队 1 +x:1 +自行车赛 1 +x:1 +解剖 1 +x:1 +望而生畏 1 +x:1 +潘家园 1 +x:1 +垂帘听政 1 +x:1 +西滑封村 1 +x:1 +倘或 1 +x:1 +伯祖母 1 +x:1 +蓝黑色 1 +x:1 +例文 1 +x:1 +电场 1 +x:1 +涓涓 1 +x:1 +韦斯顿 1 +x:1 +简括 1 +x:1 +排比段式 1 +x:1 +使用证 1 +x:1 +私心杂念 1 +x:1 +同时代 1 +x:1 +拦污栅 1 +x:1 +祀殿 1 +x:1 +二话不说 1 +x:1 +开山祖师 1 +x:1 +受权 1 +x:1 +柱子 1 +x:1 +放浪形骸 1 +x:1 +宿营车 1 +x:1 +例数 1 +x:1 +立场 1 +x:1 +油盐 1 +x:1 +蛙苗 1 +x:1 +航天站 1 +x:1 +寨根乡 1 +x:1 +倾斜角 1 +x:1 +镇北堡 1 +x:1 +经纬仪 1 +x:1 +舍己救人 1 +x:1 +犬 5 +x:5 +催讨 1 +x:1 +南阳村 1 +x:1 +新泽西州 1 +x:1 +林县 1 +x:1 +苏拉威西 1 +x:1 +文豪 1 +x:1 +省长 1 +x:1 +激昂慷慨 1 +x:1 +坦克师 1 +x:1 +杂树杆 1 +x:1 +异教徒 1 +x:1 +拆借 1 +x:1 +科雷亚 1 +x:1 +谱例 1 +x:1 +实生苗 1 +x:1 +孝 7 +x:7 +阳羡 1 +x:1 +遐迩闻名 1 +x:1 +擂台 1 +x:1 +苏梅岛 1 +x:1 +哥伦布斯 1 +x:1 +抽搐 1 +x:1 +药学 1 +x:1 +斋月 1 +x:1 +一般地说 1 +x:1 +铁拳 1 +x:1 +图例 1 +x:1 +别样 1 +x:1 +齐备 1 +x:1 +组成部分 1 +x:1 +举轻若重 1 +x:1 +熟练工 1 +x:1 +币值 1 +x:1 +瓦工 1 +x:1 +凤响乡 1 +x:1 +齐声 1 +x:1 +木匠师 1 +x:1 +分外事 1 +x:1 +出险 1 +x:1 +塞族区 1 +x:1 +发展点 1 +x:1 +母本 1 +x:1 +受之有愧 1 +x:1 +改换 1 +x:1 +出院 1 +x:1 +樱桃 1 +x:1 +练兵场 1 +x:1 +脐带 1 +x:1 +钦佩 1 +x:1 +浑洒自如 1 +x:1 +图书 1 +x:1 +饱和溶液 1 +x:1 +本上有名 1 +x:1 +舢 1 +x:1 +埃里温 1 +x:1 +痒痒 1 +x:1 +脍炙人口 1 +x:1 +啼呜 1 +x:1 +希望村 1 +x:1 +出乎预料 1 +x:1 +庵 2 +x:2 +电器 1 +x:1 +欣逢 1 +x:1 +代购点 1 +x:1 +倡和 1 +x:1 +咨询台 1 +x:1 +世界化 1 +x:1 +降水区 1 +x:1 +蒙太奇 1 +x:1 +剂 14 +x:14 +三带走 1 +x:1 +伤员 1 +x:1 +篇 754 +x:754 +农副产品 1 +x:1 +滑铁卢 1 +x:1 +旋转门 1 +x:1 +人浪 1 +x:1 +穷经皓首 1 +x:1 +雉鸠 1 +x:1 +学术界 1 +x:1 +潘家埠 1 +x:1 +母板 1 +x:1 +东亚学系 1 +x:1 +沙害 1 +x:1 +立国 1 +x:1 +恒泰银号 1 +x:1 +抽斗 1 +x:1 +克星 1 +x:1 +火煤 1 +x:1 +解送 1 +x:1 +省钱 1 +x:1 +喂奶 1 +x:1 +滂沱 1 +x:1 +玄参 1 +x:1 +星罗棋布 1 +x:1 +闪动 1 +x:1 +客土 1 +x:1 +违规者 1 +x:1 +因素 1 +x:1 +宾主 1 +x:1 +换班 1 +x:1 +流离颠沛 1 +x:1 +碳黑 1 +x:1 +一夜间 1 +x:1 +图件 1 +x:1 +欢呼雀跃 1 +x:1 +浮动制 1 +x:1 +图们 1 +x:1 +阴谋 1 +x:1 +其实不然 1 +x:1 +堆焊 1 +x:1 +梃子 1 +x:1 +文赋 1 +x:1 +杂技界 1 +x:1 +水力学 1 +x:1 +曾经 1 +x:1 +污泥浊水 1 +x:1 +旁人 1 +x:1 +嘿嘿 1 +x:1 +建瓯市 1 +x:1 +减税 1 +x:1 +经学 1 +x:1 +住满 1 +x:1 +硬玉 1 +x:1 +中纪委 1 +x:1 +缝纫工 1 +x:1 +博士点 1 +x:1 +世界史 1 +x:1 +山里 1 +x:1 +山野 1 +x:1 +改掉 1 +x:1 +长途票 1 +x:1 +老红军 1 +x:1 +碗口 1 +x:1 +电流值 1 +x:1 +才华 1 +x:1 +文责 1 +x:1 +面塑 1 +x:1 +冷风 1 +x:1 +打假者 1 +x:1 +诼 1 +x:1 +心窝儿 1 +x:1 +浩浩然 1 +x:1 +斋日 1 +x:1 +喷药 1 +x:1 +摩天大厦 1 +x:1 +标识物 1 +x:1 +律韵 1 +x:1 +逐个 1 +x:1 +排水沟 1 +x:1 +面容 1 +x:1 +顿悟 1 +x:1 +爆破筒 1 +x:1 +燃器具 1 +x:1 +缺株 1 +x:1 +想当年 1 +x:1 +数据化 1 +x:1 +转经筒 1 +x:1 +厅长 1 +x:1 +金杯 1 +x:1 +受旱 1 +x:1 +海防线 1 +x:1 +上河城 1 +x:1 +无庸讳言 1 +x:1 +科干局 1 +x:1 +鸵鸟 1 +x:1 +爷们 1 +x:1 +齐家 1 +x:1 +浓艳 1 +x:1 +独裁者 1 +x:1 +必答题 1 +x:1 +丰功传绩 1 +x:1 +改性 1 +x:1 +飞蝗 1 +x:1 +铁红色 1 +x:1 +琴山村 1 +x:1 +金笔厂 1 +x:1 +面对 1 +x:1 +游廊 1 +x:1 +橄榄油 1 +x:1 +草浆碱 1 +x:1 +盗犯 1 +x:1 +盐碱滩 1 +x:1 +荒山秃岭 1 +x:1 +抗宣队 1 +x:1 +抽暇 1 +x:1 +出错 1 +x:1 +互不相让 1 +x:1 +扔掉 1 +x:1 +江西省 1 +x:1 +聊胜于无 1 +x:1 +实物性 1 +x:1 +创立 1 +x:1 +林内 1 +x:1 +祷告日 1 +x:1 +出门 1 +x:1 +金童玉女 1 +x:1 +催要 1 +x:1 +逐人 1 +x:1 +统筹学 1 +x:1 +循环赛制 1 +x:1 +受敌 1 +x:1 +注塑机 1 +x:1 +多数制 1 +x:1 +购房者 1 +x:1 +人工湖区 1 +x:1 +珠儿 1 +x:1 +缝纫店 1 +x:1 +纹丝不动 1 +x:1 +神兵天降 1 +x:1 +墨镜 1 +x:1 +林冠 1 +x:1 +寄宿制 1 +x:1 +经堂 1 +x:1 +林况 1 +x:1 +心胸 1 +x:1 +柴火 1 +x:1 +追歼 1 +x:1 +装箱 1 +x:1 +比邻 1 +x:1 +习字 1 +x:1 +畅 77 +x:77 +瞎闯 1 +x:1 +冀晋 1 +x:1 +头衔 1 +x:1 +天穹型 1 +x:1 +科学园 1 +x:1 +珠兰 1 +x:1 +批零价 1 +x:1 +拆分 1 +x:1 +墨锭 1 +x:1 +同路 1 +x:1 +啪哒啪哒 1 +x:1 +站点 1 +x:1 +高陵深谷 1 +x:1 +纸尿裤 1 +x:1 +电喷 1 +x:1 +临机应变 1 +x:1 +面孔 1 +x:1 +依山傍水 1 +x:1 +面子 1 +x:1 +币制 1 +x:1 +改悔 1 +x:1 +俾 2 +x:2 +依波沃村 1 +x:1 +筛子 1 +x:1 +沾花惹草 1 +x:1 +监控点 1 +x:1 +部委局 1 +x:1 +适于 1 +x:1 +招贤引才 1 +x:1 +浓茶 1 +x:1 +大小写 1 +x:1 +后起之秀 1 +x:1 +画绢 1 +x:1 +围墙 1 +x:1 +弄棍舞刀 1 +x:1 +电告 1 +x:1 +矿用车 1 +x:1 +生龙活虎 1 +x:1 +五荤 1 +x:1 +讨价声 1 +x:1 +处事 1 +x:1 +拆台 1 +x:1 +海碗 1 +x:1 +寝具 1 +x:1 +绰绰有余 1 +x:1 +谪 2 +x:2 +善纳雅言 1 +x:1 +九牛一毛 1 +x:1 +惯常 1 +x:1 +据称 1 +x:1 +挤眉弄眼 1 +x:1 +术科 1 +x:1 +滦平 1 +x:1 +文辞 1 +x:1 +上行线 1 +x:1 +画纸 1 +x:1 +头角 1 +x:1 +族 25 +x:25 +车务段 1 +x:1 +浓荫 1 +x:1 +舒前村 1 +x:1 +低洼 1 +x:1 +创业区 1 +x:1 +泳姿 1 +x:1 +叫号机 1 +x:1 +爆跌 1 +x:1 +嘉善 1 +x:1 +宜丰 1 +x:1 +生态箱 1 +x:1 +朝思暮想 1 +x:1 +蚂蚁社 1 +x:1 +夜长梦多 1 +x:1 +乡关 1 +x:1 +协议区 1 +x:1 +窄小 1 +x:1 +捧场话 1 +x:1 +民主德国 1 +x:1 +抓瞎 1 +x:1 +转弯 1 +x:1 +烤羊肉 1 +x:1 +特马市 1 +x:1 +经委 1 +x:1 +母教 1 +x:1 +逆函数 1 +x:1 +得分手 1 +x:1 +省际 1 +x:1 +彩屯 1 +x:1 +汤药 1 +x:1 +寥寥 1 +x:1 +五荒 1 +x:1 +自为阶级 1 +x:1 +分离户 1 +x:1 +创业史 1 +x:1 +基层队 1 +x:1 +研究组 1 +x:1 +陆海空 1 +x:1 +冀望 1 +x:1 +沙钻鱼 1 +x:1 +无可置疑 1 +x:1 +飞腾 1 +x:1 +莠 1 +x:1 +肚脐眼 1 +x:1 +拆卸 1 +x:1 +适中 1 +x:1 +极目远眺 1 +x:1 +对账单 1 +x:1 +穷竭心计 1 +x:1 +风向标 1 +x:1 +枯水期 1 +x:1 +伟大 1 +x:1 +因缘 1 +x:1 +鱼种 1 +x:1 +红香圃 1 +x:1 +落叶松 1 +x:1 +摄氏 1 +x:1 +心急火燎 1 +x:1 +许以 1 +x:1 +河南梆子 1 +x:1 +初轧厂 1 +x:1 +噙 10 +x:10 +出钱 1 +x:1 +无病害 1 +x:1 +仔岛 1 +x:1 +飞蛾 1 +x:1 +梧州 1 +x:1 +炼铁热 1 +x:1 +科学城 1 +x:1 +流毒 1 +x:1 +蓉城镇 1 +x:1 +师范学校 1 +x:1 +排沙量 1 +x:1 +泾渭分明 1 +x:1 +琥珀型 1 +x:1 +庇 2 +x:2 +经度 1 +x:1 +招工 1 +x:1 +省里 1 +x:1 +一不怕苦 1 +x:1 +逝者 1 +x:1 +浅棕 1 +x:1 +背景台 1 +x:1 +手提包 1 +x:1 +下机 1 +x:1 +洪汝河 1 +x:1 +购进价 1 +x:1 +转载 1 +x:1 +科尔沁 1 +x:1 +麦纳麦 1 +x:1 +伪科学 1 +x:1 +体格 1 +x:1 +薯条 1 +x:1 +咨询团 1 +x:1 +妖冶 1 +x:1 +瓶体 1 +x:1 +事实上 1 +x:1 +棺材式 1 +x:1 +林地 1 +x:1 +众矢之的 1 +x:1 +林场 1 +x:1 +尉官 1 +x:1 +名子 1 +x:1 +时涨时落 1 +x:1 +忍气吞声 1 +x:1 +漆膜 1 +x:1 +噌噌噌 1 +x:1 +六里屯 1 +x:1 +美术史 1 +x:1 +舒心美气 1 +x:1 +师爷气 1 +x:1 +转会 1 +x:1 +河东村 1 +x:1 +约束力 1 +x:1 +受控 1 +x:1 +焦虑不安 1 +x:1 +张皇失措 1 +x:1 +夸里 1 +x:1 +黔阳县 1 +x:1 +桨 8 +x:8 +驾车人 1 +x:1 +烘烤 1 +x:1 +亲闻 1 +x:1 +群众观 1 +x:1 +博士生 1 +x:1 +虎威 1 +x:1 +综治委 1 +x:1 +一拖再拖 1 +x:1 +团结乡 1 +x:1 +毡靴 1 +x:1 +吃不住 1 +x:1 +自觉性 1 +x:1 +捡破烂 1 +x:1 +正多边形 1 +x:1 +简明 1 +x:1 +拼力 1 +x:1 +老朋友 1 +x:1 +简易 1 +x:1 +胸径 1 +x:1 +经常 1 +x:1 +受损 1 +x:1 +宠幸 1 +x:1 +员外郎 1 +x:1 +硬盘 1 +x:1 +断开 1 +x:1 +销声匿迹 1 +x:1 +存储 1 +x:1 +纸醉金迷 1 +x:1 +经师 1 +x:1 +苏铁园 1 +x:1 +畜禽 1 +x:1 +霭 1 +x:1 +电台 1 +x:1 +一言不发 1 +x:1 +吭声 1 +x:1 +油泵 1 +x:1 +蜉蝣 1 +x:1 +尼洋 1 +x:1 +表面文章 1 +x:1 +立卡 1 +x:1 +暮生儿 1 +x:1 +客务 1 +x:1 +飘行 1 +x:1 +自然铜 1 +x:1 +保护油 1 +x:1 +四连败 1 +x:1 +黄鼠 1 +x:1 +经幡 1 +x:1 +立即 1 +x:1 +钻木取火 1 +x:1 +电压 1 +x:1 +笑吟吟 1 +x:1 +经年 1 +x:1 +轻装简行 1 +x:1 +列国 1 +x:1 +史无前例 1 +x:1 +电厂 1 +x:1 +固步自封 1 +x:1 +长龙 1 +x:1 +巧事 1 +x:1 +隔墙 1 +x:1 +受挫 1 +x:1 +上高县 1 +x:1 +塑料 1 +x:1 +悬念 1 +x:1 +宛若 1 +x:1 +鼠疮 1 +x:1 +毅锋 1 +x:1 +传为美谈 1 +x:1 +转义 1 +x:1 +苛细 1 +x:1 +奉公守法 1 +x:1 +药店 1 +x:1 +年月日 1 +x:1 +变频 1 +x:1 +考讪路 1 +x:1 +痄腮 1 +x:1 +窑河乡 1 +x:1 +劳顿 1 +x:1 +僧侣主义 1 +x:1 +烤肉 1 +x:1 +有凭有据 1 +x:1 +须要 1 +x:1 +丘岗 1 +x:1 +哲学界 1 +x:1 +立功 1 +x:1 +明溪口乡 1 +x:1 +遇救 1 +x:1 +润州 1 +x:1 +铁杉 1 +x:1 +恨不得 1 +x:1 +电刑 1 +x:1 +鱼缸 1 +x:1 +日全食 1 +x:1 +转世 1 +x:1 +乒 2 +x:2 +直抒己见 1 +x:1 +听其言 1 +x:1 +山镇 1 +x:1 +止息 1 +x:1 +统率 1 +x:1 +吹冷风 1 +x:1 +潘家口 1 +x:1 +转业 1 +x:1 +非主业 1 +x:1 +婆娑起舞 1 +x:1 +苴麻 1 +x:1 +白净净 1 +x:1 +皱纹 1 +x:1 +身长 1 +x:1 +刻写 1 +x:1 +熟门熟路 1 +x:1 +经心 1 +x:1 +随时随地 1 +x:1 +存入 1 +x:1 +临高县 1 +x:1 +孑遗 1 +x:1 +阜南县 1 +x:1 +改期 1 +x:1 +惹 40 +x:40 +转为 1 +x:1 +铁板 1 +x:1 +无机可乘 1 +x:1 +共轭点 1 +x:1 +金柚 1 +x:1 +著译 1 +x:1 +药师 1 +x:1 +诸宫调 1 +x:1 +药市 1 +x:1 +油星子 1 +x:1 +邮程 1 +x:1 +省道 1 +x:1 +出征 1 +x:1 +刻入 1 +x:1 +立刻 1 +x:1 +受托 1 +x:1 +中州 1 +x:1 +叫座 1 +x:1 +大路货 1 +x:1 +烤者 1 +x:1 +简本 1 +x:1 +鱼翅 1 +x:1 +简朴 1 +x:1 +铁架 1 +x:1 +少帅 1 +x:1 +低毒 1 +x:1 +永电 1 +x:1 +奋勇争先 1 +x:1 +同一个 1 +x:1 +银铜牌 1 +x:1 +只能 1 +x:1 +柏枝村 1 +x:1 +电力 1 +x:1 +太阳眼镜 1 +x:1 +痔疮 1 +x:1 +白条子 1 +x:1 +鱼群 1 +x:1 +八达岭 1 +x:1 +受戒 1 +x:1 +描摹 1 +x:1 +进口量 1 +x:1 +铁柜 1 +x:1 +急性病 1 +x:1 +银装 1 +x:1 +客厅 1 +x:1 +转交 1 +x:1 +人流 1 +x:1 +山间 1 +x:1 +赛段 1 +x:1 +活动室 1 +x:1 +关系案 1 +x:1 +土耳其队 1 +x:1 +依依恋恋 1 +x:1 +斋戒 1 +x:1 +否决权制 1 +x:1 +电动 1 +x:1 +山门 1 +x:1 +电务 1 +x:1 +简板 1 +x:1 +活动家 1 +x:1 +同车人 1 +x:1 +母性 1 +x:1 +全能性 1 +x:1 +鸣枪 1 +x:1 +卯是卯 1 +x:1 +低档 1 +x:1 +鱼类 1 +x:1 +立冬 1 +x:1 +悬崖 1 +x:1 +电光 1 +x:1 +增长点 1 +x:1 +落地 1 +x:1 +界线 1 +x:1 +砸饭碗 1 +x:1 +安家落户 1 +x:1 +长滩峡 1 +x:1 +方嘴鱼 1 +x:1 +梓潼县 1 +x:1 +山阴 1 +x:1 +伟岸 1 +x:1 +卖身 1 +x:1 +民族自决 1 +x:1 +曾祖 1 +x:1 +齐心 1 +x:1 +险种 1 +x:1 +奥秘 1 +x:1 +收缩 1 +x:1 +家信 1 +x:1 +蓝花楹 1 +x:1 +万向节 1 +x:1 +爆裂 1 +x:1 +拖不拖欠 1 +x:1 +跑表 1 +x:1 +确山 1 +x:1 +延伸 1 +x:1 +静压 1 +x:1 +魔力 1 +x:1 +爬藤 1 +x:1 +装置 1 +x:1 +山陵 1 +x:1 +股评 1 +x:1 +比较价格 1 +x:1 +低栏 1 +x:1 +药工 1 +x:1 +左上方 1 +x:1 +顺化乡 1 +x:1 +电视剧 1 +x:1 +碧血 1 +x:1 +山险 1 +x:1 +飞荡 1 +x:1 +主宰 1 +x:1 +单浴盆式 1 +x:1 +清名 1 +x:1 +分离机 1 +x:1 +七擒七纵 1 +x:1 +逛逛 1 +x:1 +希腊 1 +x:1 +卦爻 1 +x:1 +假设敌 1 +x:1 +创业园 1 +x:1 +休 41 +x:41 +坚贞 1 +x:1 +山隅 1 +x:1 +主帅 1 +x:1 +轻车 1 +x:1 +闻讯 1 +x:1 +殷钢 1 +x:1 +肤 6 +x:6 +抽打 1 +x:1 +奥利亚山 1 +x:1 +正常化 1 +x:1 +新鲜感 1 +x:1 +家伙 1 +x:1 +师级 1 +x:1 +寥廓 1 +x:1 +闪光 1 +x:1 +钧瓷 1 +x:1 +瘟神 1 +x:1 +北温带 1 +x:1 +刻刻 1 +x:1 +黄泥巴 1 +x:1 +锯刀 1 +x:1 +名专栏 1 +x:1 +山雀 1 +x:1 +福费庭 1 +x:1 +文言 1 +x:1 +风吹浪打 1 +x:1 +大天白日 1 +x:1 +唯模仿论 1 +x:1 +足校 1 +x:1 +戏而不谑 1 +x:1 +刻划 1 +x:1 +说唱文学 1 +x:1 +画笔 1 +x:1 +电冶 1 +x:1 +集体工业 1 +x:1 +灯 117 +x:117 +山雾 1 +x:1 +雾蒙蒙 1 +x:1 +绯闻 1 +x:1 +山雨 1 +x:1 +兼有 1 +x:1 +巅峰 1 +x:1 +鱼粉 1 +x:1 +盗用者 1 +x:1 +飞舞 1 +x:1 +家产 1 +x:1 +摸 99 +x:99 +翼翼 1 +x:1 +受惊 1 +x:1 +住校 1 +x:1 +象角村 1 +x:1 +宁武县 1 +x:1 +克服 1 +x:1 +画童 1 +x:1 +家人 1 +x:1 +通 370 +x:370 +山地茶 1 +x:1 +钞票 1 +x:1 +文说 1 +x:1 +劳驾 1 +x:1 +受惠 1 +x:1 +科学化 1 +x:1 +家事 1 +x:1 +锯口 1 +x:1 +劳联 1 +x:1 +为期 1 +x:1 +代理点 1 +x:1 +面庞 1 +x:1 +业主制 1 +x:1 +耀眼 1 +x:1 +出道 1 +x:1 +羊毛里 1 +x:1 +清凉山 1 +x:1 +顿时 1 +x:1 +叫屈 1 +x:1 +轻轨 1 +x:1 +甚高频 1 +x:1 +再其次 1 +x:1 +朝阳区 1 +x:1 +起用 1 +x:1 +形相 1 +x:1 +飞艇 1 +x:1 +家什 1 +x:1 +嗤之以鼻 1 +x:1 +集邮界 1 +x:1 +北娄村 1 +x:1 +立像 1 +x:1 +文论 1 +x:1 +出逃 1 +x:1 +古典式 1 +x:1 +传统型 1 +x:1 +大庭广众 1 +x:1 +天生丽质 1 +x:1 +御菜 1 +x:1 +秀水 1 +x:1 +马拉车 1 +x:1 +刻印 1 +x:1 +玉兔 1 +x:1 +屈辱史 1 +x:1 +静心思过 1 +x:1 +家中 1 +x:1 +改旧 1 +x:1 +横额 1 +x:1 +名人组 1 +x:1 +唉声叹息 1 +x:1 +治病救人 1 +x:1 +宣讲 1 +x:1 +山鞋 1 +x:1 +家丁 1 +x:1 +直音法 1 +x:1 +面市 1 +x:1 +蹭痒 1 +x:1 +霉味 1 +x:1 +嘉兴 1 +x:1 +焰 7 +x:7 +家丑 1 +x:1 +累死 1 +x:1 +家世 1 +x:1 +延付 1 +x:1 +叭儿 1 +x:1 +堂房 1 +x:1 +简政 1 +x:1 +家乡 1 +x:1 +惨不忍睹 1 +x:1 +科学司 1 +x:1 +熟石膏 1 +x:1 +绒帽 1 +x:1 +画稿 1 +x:1 +科学史 1 +x:1 +重伤者 1 +x:1 +宣读 1 +x:1 +赋闲 1 +x:1 +分子量 1 +x:1 +皮肤科 1 +x:1 +存取 1 +x:1 +堆积物 1 +x:1 +骨纤维 1 +x:1 +山韵 1 +x:1 +罗斯福 1 +x:1 +报告者 1 +x:1 +养气 1 +x:1 +累次 1 +x:1 +枕畔 1 +x:1 +齐市 1 +x:1 +无毒性 1 +x:1 +绒布 1 +x:1 +电视台 1 +x:1 +桓仁 1 +x:1 +春寒 1 +x:1 +统统 1 +x:1 +经一路 1 +x:1 +伟力 1 +x:1 +会计师 1 +x:1 +休耕地 1 +x:1 +畜生 1 +x:1 +常驻地 1 +x:1 +普通型 1 +x:1 +脚铃 1 +x:1 +积少成多 1 +x:1 +男子汉 1 +x:1 +抽泣 1 +x:1 +矿主 1 +x:1 +康庄大道 1 +x:1 +表达式 1 +x:1 +手提式 1 +x:1 +窑坑 1 +x:1 +飞贼 1 +x:1 +两 13710 +x:13710 +跳丧鼓 1 +x:1 +电影 1 +x:1 +头花 1 +x:1 +经办 1 +x:1 +洽商 1 +x:1 +舌下腺 1 +x:1 +溃烂 1 +x:1 +纸品 1 +x:1 +畜用 1 +x:1 +螺旋体 1 +x:1 +皮肤癌 1 +x:1 +药叉 1 +x:1 +鲁家峪村 1 +x:1 +沦为 1 +x:1 +一刹那 1 +x:1 +苦思冥想 1 +x:1 +皮袄 1 +x:1 +付给 1 +x:1 +叫卖 1 +x:1 +沦丧 1 +x:1 +秦腔 1 +x:1 +油箱盖 1 +x:1 +嘉庆 1 +x:1 +广汉县 1 +x:1 +原始人 1 +x:1 +迥 2 +x:2 +以丰补歉 1 +x:1 +山顶 1 +x:1 +蔽 6 +x:6 +群英图 1 +x:1 +十痨九死 1 +x:1 +时区 1 +x:1 +酒会 1 +x:1 +心窝子 1 +x:1 +办案组 1 +x:1 +立志 1 +x:1 +赘婿 1 +x:1 +草原学 1 +x:1 +黄源 1 +x:1 +电弧 1 +x:1 +六零六 1 +x:1 +允当 1 +x:1 +纠正 1 +x:1 +普洱茶 1 +x:1 +卖者 1 +x:1 +唉 9 +x:9 +甩亩 1 +x:1 +梅汕 1 +x:1 +飞越 1 +x:1 +排 427 +x:427 +企足而待 1 +x:1 +纹饰 1 +x:1 +齐全 1 +x:1 +堆砌 1 +x:1 +巴拿马城 1 +x:1 +燃烧物 1 +x:1 +鱼狗 1 +x:1 +萍水相逢 1 +x:1 +受潮 1 +x:1 +立式 1 +x:1 +窬 1 +x:1 +山颠 1 +x:1 +海岸带 1 +x:1 +水务局 1 +x:1 +飘落 1 +x:1 +曼彻斯特 1 +x:1 +畜疫 1 +x:1 +抽水 1 +x:1 +客座 1 +x:1 +粘接剂 1 +x:1 +仁怀市 1 +x:1 +飞跑 1 +x:1 +行政官 1 +x:1 +沦亡 1 +x:1 +填鸭法 1 +x:1 +面具 1 +x:1 +文萃 1 +x:1 +暂住证 1 +x:1 +代码卡 1 +x:1 +飞跃 1 +x:1 +交互性 1 +x:1 +山风 1 +x:1 +四不象 1 +x:1 +中山装 1 +x:1 +十里堡镇 1 +x:1 +屈曲 1 +x:1 +珠子 1 +x:1 +客店 1 +x:1 +叫号 1 +x:1 +得意门生 1 +x:1 +改正 1 +x:1 +亲题 1 +x:1 +节选 1 +x:1 +蚕 6 +x:6 +酒乡 1 +x:1 +答非所问 1 +x:1 +羽毛球 1 +x:1 +红岩嘴 1 +x:1 +天门县 1 +x:1 +所有权 1 +x:1 +脚门 1 +x:1 +掌 19 +x:19 +综采 1 +x:1 +经历 1 +x:1 +墨黑 1 +x:1 +酒乘 1 +x:1 +留任 1 +x:1 +电平 1 +x:1 +日珥 1 +x:1 +夏各庄乡 1 +x:1 +缓慢性 1 +x:1 +遮阳伞 1 +x:1 +课间餐 1 +x:1 +提前量 1 +x:1 +供电网 1 +x:1 +龙岩市 1 +x:1 +橄榄枝 1 +x:1 +隐显墨水 1 +x:1 +赛期 1 +x:1 +溅开 1 +x:1 +挨个 1 +x:1 +硬笔 1 +x:1 +巨头 1 +x:1 +壬酚 1 +x:1 +防护林带 1 +x:1 +竹瓦镇 1 +x:1 +信不过 1 +x:1 +监控站 1 +x:1 +僻静 1 +x:1 +安太堡矿 1 +x:1 +酒业 1 +x:1 +活动场 1 +x:1 +半截 1 +x:1 +经变 1 +x:1 +经受 1 +x:1 +哈哈哈 1 +x:1 +弗里敦 1 +x:1 +喂养 1 +x:1 +莲荷乡 1 +x:1 +达到 1 +x:1 +赌博机 1 +x:1 +宜昌市 1 +x:1 +李果园 1 +x:1 +同化力 1 +x:1 +就餐者 1 +x:1 +酒令 1 +x:1 +怎地 1 +x:1 +因由 1 +x:1 +深长 1 +x:1 +小强村 1 +x:1 +打斗片 1 +x:1 +特邀 1 +x:1 +戴者 1 +x:1 +法网恢恢 1 +x:1 +定远店 1 +x:1 +二道河乡 1 +x:1 +结婚证 1 +x:1 +脚镣 1 +x:1 +蓝田生玉 1 +x:1 +装点 1 +x:1 +纵断面 1 +x:1 +球结点 1 +x:1 +抢断 1 +x:1 +催芽 1 +x:1 +注目礼 1 +x:1 +才学 1 +x:1 +统编 1 +x:1 +药剂 1 +x:1 +阿灵顿县 1 +x:1 +封二 1 +x:1 +羊庄 1 +x:1 +颤颤 1 +x:1 +回族史 1 +x:1 +囚首垢面 1 +x:1 +胶体溶液 1 +x:1 +选举制 1 +x:1 +墨鸦 1 +x:1 +里边 1 +x:1 +体检 1 +x:1 +游商 1 +x:1 +决议案 1 +x:1 +双髻山 1 +x:1 +寝室 1 +x:1 +才子 1 +x:1 +影片奖 1 +x:1 +勘探者 1 +x:1 +寝宫 1 +x:1 +锲而不舍 1 +x:1 +点金术 1 +x:1 +全国性 1 +x:1 +确实 1 +x:1 +吐鲁番 1 +x:1 +南花小区 1 +x:1 +免提键 1 +x:1 +削果器 1 +x:1 +铁栏 1 +x:1 +铁树 1 +x:1 +党委 1 +x:1 +药农 1 +x:1 +铁饭碗 1 +x:1 +八家村 1 +x:1 +偷人 1 +x:1 +佼佼者 1 +x:1 +收发人 1 +x:1 +客居 1 +x:1 +男装 1 +x:1 +经济舱 1 +x:1 +势如破竹 1 +x:1 +排名赛 1 +x:1 +硬硬 1 +x:1 +午时 1 +x:1 +师爷 1 +x:1 +文蛤 1 +x:1 +瘟疫 1 +x:1 +浓浓淡淡 1 +x:1 +险症 1 +x:1 +心脾 1 +x:1 +翼状 1 +x:1 +练 137 +x:137 +盗窃 1 +x:1 +锯床 1 +x:1 +碧葱 1 +x:1 +游园 1 +x:1 +铁案 1 +x:1 +弃之不用 1 +x:1 +期盼 1 +x:1 +刻度 1 +x:1 +行政处 1 +x:1 +瘟病 1 +x:1 +会晤 1 +x:1 +四方步 1 +x:1 +代 1006 +x:1006 +铁桥 1 +x:1 +骄兵必败 1 +x:1 +朝阳市 1 +x:1 +数据字 1 +x:1 +斗智斗勇 1 +x:1 +燃烧点 1 +x:1 +卫士 1 +x:1 +飞轮 1 +x:1 +情由事显 1 +x:1 +绝对额 1 +x:1 +官商 1 +x:1 +冰激凌 1 +x:1 +精悍 1 +x:1 +忡忡 1 +x:1 +滩边 1 +x:1 +大约摸 1 +x:1 +清凉寺 1 +x:1 +现代舞 1 +x:1 +旋毛虫 1 +x:1 +涮羊肉 1 +x:1 +撰稿 1 +x:1 +田园 1 +x:1 +营养源 1 +x:1 +辣椒水 1 +x:1 +水牛 1 +x:1 +面包 1 +x:1 +螟害 1 +x:1 +别扭 1 +x:1 +胸墙 1 +x:1 +帷子 1 +x:1 +洗衣粉 1 +x:1 +搜索 1 +x:1 +仙人鞭 1 +x:1 +金沙县 1 +x:1 +杜绝 1 +x:1 +续完 1 +x:1 +系际 1 +x:1 +传 283 +x:283 +铁棍 1 +x:1 +块儿 1 +x:1 +铁棒 1 +x:1 +绝甘分少 1 +x:1 +蜂王精 1 +x:1 +飞过 1 +x:1 +尖脐 1 +x:1 +变革 1 +x:1 +九眼桥 1 +x:1 +老花眼 1 +x:1 +碧蓝 1 +x:1 +霉头 1 +x:1 +母法 1 +x:1 +机关报 1 +x:1 +何首乌 1 +x:1 +药典 1 +x:1 +美容节 1 +x:1 +卖艺 1 +x:1 +奚谷山 1 +x:1 +千佛山 1 +x:1 +煤核儿 1 +x:1 +乌七八糟 1 +x:1 +派出所 1 +x:1 +濑户 1 +x:1 +存异 1 +x:1 +贫雇农 1 +x:1 +城北区 1 +x:1 +女家 1 +x:1 +种植园 1 +x:1 +清华 1 +x:1 +湿漉漉 1 +x:1 +弘 26 +x:26 +探照灯 1 +x:1 +炝 1 +x:1 +低效 1 +x:1 +七个泉 1 +x:1 +课桌椅 1 +x:1 +传中球 1 +x:1 +评说者 1 +x:1 +放工 1 +x:1 +洲堤 1 +x:1 +添丁 1 +x:1 +中国货 1 +x:1 +带病 1 +x:1 +添乱 1 +x:1 +柔绵 1 +x:1 +珍宝岛 1 +x:1 +白琳镇 1 +x:1 +告 126 +x:126 +山地车 1 +x:1 +三自一包 1 +x:1 +经函 1 +x:1 +山魂 1 +x:1 +赵全营村 1 +x:1 +或然率 1 +x:1 +山魈 1 +x:1 +悬停 1 +x:1 +绦虫 1 +x:1 +标识符 1 +x:1 +画皮 1 +x:1 +柴禾 1 +x:1 +邓家庄村 1 +x:1 +堂堂皇皇 1 +x:1 +大显神通 1 +x:1 +钓大鱼 1 +x:1 +记者会 1 +x:1 +湘军 1 +x:1 +劳防 1 +x:1 +髂骨 1 +x:1 +色庆乡 1 +x:1 +仔后 1 +x:1 +却之不恭 1 +x:1 +升官 1 +x:1 +翼王 1 +x:1 +驾车 1 +x:1 +堆笑 1 +x:1 +墨鱼 1 +x:1 +拆字 1 +x:1 +小钱柜 1 +x:1 +盐池县 1 +x:1 +头脑 1 +x:1 +清单 1 +x:1 +杏仁 1 +x:1 +母液 1 +x:1 +青年队 1 +x:1 +强行军 1 +x:1 +催肥 1 +x:1 +赛时 1 +x:1 +愧 7 +x:7 +公共场所 1 +x:1 +意料之中 1 +x:1 +碳铵 1 +x:1 +各国 1 +x:1 +外电路 1 +x:1 +划界法 1 +x:1 +一抢而空 1 +x:1 +鹰首瓶 1 +x:1 +存心 1 +x:1 +爬行 1 +x:1 +皮肤病 1 +x:1 +早岁 1 +x:1 +标志旗 1 +x:1 +受气 1 +x:1 +才女 1 +x:1 +经典 1 +x:1 +伤心事 1 +x:1 +宠儿 1 +x:1 +因着 1 +x:1 +刷刷 1 +x:1 +算计 1 +x:1 +面前 1 +x:1 +立屏 1 +x:1 +阴虱 1 +x:1 +河柳 1 +x:1 +碳钢 1 +x:1 +险球 1 +x:1 +链 7 +x:7 +守望相助 1 +x:1 +报亭 1 +x:1 +撑腰 1 +x:1 +立审 1 +x:1 +母模 1 +x:1 +诸亲好友 1 +x:1 +鱼白 1 +x:1 +电子 1 +x:1 +姑表 1 +x:1 +尼斯 1 +x:1 +涡 1 +x:1 +三查三找 1 +x:1 +桃脯 1 +x:1 +土墙 1 +x:1 +光华四射 1 +x:1 +楼山乡 1 +x:1 +缺一不可 1 +x:1 +六盘山 1 +x:1 +拾贝集 1 +x:1 +乙基 1 +x:1 +抽检 1 +x:1 +挑三拣四 1 +x:1 +立定 1 +x:1 +争先创优 1 +x:1 +加通湖 1 +x:1 +装甲 1 +x:1 +药城 1 +x:1 +变量 1 +x:1 +谨防 1 +x:1 +清汤寡水 1 +x:1 +砼薄壁 1 +x:1 +平乡县 1 +x:1 +简牍史 1 +x:1 +报价 1 +x:1 +电视塔 1 +x:1 +电话线 1 +x:1 +嗜杀成性 1 +x:1 +恨 37 +x:37 +报仇 1 +x:1 +搜访 1 +x:1 +一贯性 1 +x:1 +担担面 1 +x:1 +白茫茫 1 +x:1 +扫盲率 1 +x:1 +文联 1 +x:1 +悬垂 1 +x:1 +烧制 1 +x:1 +进口额 1 +x:1 +劳金 1 +x:1 +农村片 1 +x:1 +嫉恶如仇 1 +x:1 +灵便 1 +x:1 +动人心魄 1 +x:1 +排球界 1 +x:1 +硬结 1 +x:1 +怯声怯气 1 +x:1 +文职 1 +x:1 +障 8 +x:8 +院友会 1 +x:1 +宝贵 1 +x:1 +邀请信 1 +x:1 +奉 53 +x:53 +公爵 1 +x:1 +圆锥体 1 +x:1 +供电站 1 +x:1 +报业 1 +x:1 +三盖沟村 1 +x:1 +抽样 1 +x:1 +齐唱 1 +x:1 +双行线 1 +x:1 +会上 1 +x:1 +电定 1 +x:1 +两袖清风 1 +x:1 +柳格乡 1 +x:1 +落叶树 1 +x:1 +示导性 1 +x:1 +活动力 1 +x:1 +才干 1 +x:1 +皱眉 1 +x:1 +软硬兼施 1 +x:1 +夸饰 1 +x:1 +乐都县 1 +x:1 +瞧不起 1 +x:1 +寝床 1 +x:1 +存瑞乡 1 +x:1 +低价 1 +x:1 +若耶溪 1 +x:1 +电容 1 +x:1 +哑门穴 1 +x:1 +饭庄 1 +x:1 +出人头地 1 +x:1 +酿酒 1 +x:1 +头虱 1 +x:1 +铰 1 +x:1 +窑厂 1 +x:1 +车辆险 1 +x:1 +路不拾遗 1 +x:1 +秩序性 1 +x:1 +乙地 1 +x:1 +沙门氏菌 1 +x:1 +译释 1 +x:1 +莴苣 1 +x:1 +一闪而过 1 +x:1 +出马 1 +x:1 +黄萎病 1 +x:1 +大阪府 1 +x:1 +腱子肉 1 +x:1 +骅 3 +x:3 +师生 1 +x:1 +托伦省 1 +x:1 +宪兵 1 +x:1 +取暖器 1 +x:1 +开考 1 +x:1 +简明性 1 +x:1 +臭名昭彰 1 +x:1 +半晌 1 +x:1 +硬网 1 +x:1 +无能为力 1 +x:1 +烟袋锅 1 +x:1 +林带 1 +x:1 +档案 1 +x:1 +思乡病 1 +x:1 +诈骗者 1 +x:1 +技改提高 1 +x:1 +诸侯 1 +x:1 +闻者 1 +x:1 +寒冷 1 +x:1 +青天阁 1 +x:1 +定惊 1 +x:1 +嘉定 1 +x:1 +魄 1 +x:1 +鱼眼 1 +x:1 +报信 1 +x:1 +曾父 1 +x:1 +游击 1 +x:1 +飞行 1 +x:1 +志 196 +x:196 +同型号 1 +x:1 +打棍子 1 +x:1 +心花 1 +x:1 +大年初一 1 +x:1 +安于现状 1 +x:1 +万绿园 1 +x:1 +住手 1 +x:1 +凝聚态 1 +x:1 +江北区 1 +x:1 +会计学 1 +x:1 +财产险 1 +x:1 +科学奖 1 +x:1 +邓家湾村 1 +x:1 +分离法 1 +x:1 +住所 1 +x:1 +沉沉的 1 +x:1 +活动区 1 +x:1 +下坡赛 1 +x:1 +圣太田 1 +x:1 +统管 1 +x:1 +七里河 1 +x:1 +午托 1 +x:1 +技研 1 +x:1 +翘鼻子 1 +x:1 +滚地皮 1 +x:1 +金婚 1 +x:1 +变通 1 +x:1 +装璜 1 +x:1 +庄浪 1 +x:1 +谄媚 1 +x:1 +会余 1 +x:1 +恬适 1 +x:1 +随大流 1 +x:1 +铺建 1 +x:1 +酿造 1 +x:1 +叫嚣 1 +x:1 +造粒 1 +x:1 +统筹 1 +x:1 +再婚者 1 +x:1 +浅笑声 1 +x:1 +会计室 1 +x:1 +水管员 1 +x:1 +乳罩 1 +x:1 +慷慨激昂 1 +x:1 +叫嚷 1 +x:1 +面向 1 +x:1 +珠帘 1 +x:1 +吨粮县 1 +x:1 +举重 1 +x:1 +大年初五 1 +x:1 +中山路 1 +x:1 +塌 32 +x:32 +客家 1 +x:1 +会会 1 +x:1 +电缆沟 1 +x:1 +部委办 1 +x:1 +文脉 1 +x:1 +外孙女 1 +x:1 +远去 1 +x:1 +交换量 1 +x:1 +行业界 1 +x:1 +趁势 1 +x:1 +客官 1 +x:1 +桃胶 1 +x:1 +齐名 1 +x:1 +游动 1 +x:1 +母校 1 +x:1 +文苑 1 +x:1 +低息 1 +x:1 +碳酐 1 +x:1 +顿河 1 +x:1 +人身事故 1 +x:1 +山鸟 1 +x:1 +母株 1 +x:1 +同命相连 1 +x:1 +股份制 1 +x:1 +戎装 1 +x:1 +一孔之见 1 +x:1 +无以复加 1 +x:1 +碳酸 1 +x:1 +翼盒 1 +x:1 +惯匪 1 +x:1 +叫唤 1 +x:1 +半数 1 +x:1 +美妙绝伦 1 +x:1 +倡言者 1 +x:1 +山鸡 1 +x:1 +马里亚纳 1 +x:1 +铁水 1 +x:1 +塔吉克族 1 +x:1 +胛骨 1 +x:1 +想当初 1 +x:1 +骨骼肌 1 +x:1 +桓 6 +x:6 +市场价 1 +x:1 +档次 1 +x:1 +连云港 1 +x:1 +空字符 1 +x:1 +电复 1 +x:1 +拓 25 +x:25 +三鹤洞社 1 +x:1 +文节 1 +x:1 +礼仪 1 +x:1 +发言稿 1 +x:1 +山鹰 1 +x:1 +墨香 1 +x:1 +展览局 1 +x:1 +唯我独尊 1 +x:1 +榜眼 1 +x:1 +开口销 1 +x:1 +有心无力 1 +x:1 +劫持犯 1 +x:1 +李卜村 1 +x:1 +油建 1 +x:1 +立委 1 +x:1 +偷懒 1 +x:1 +电大 1 +x:1 +中子 1 +x:1 +繁 20 +x:20 +山麓 1 +x:1 +运输省 1 +x:1 +任城区 1 +x:1 +忽阴忽晴 1 +x:1 +熊 154 +x:154 +抠抠搜搜 1 +x:1 +滦县 1 +x:1 +阴茎 1 +x:1 +高堂邃宇 1 +x:1 +丑剧 1 +x:1 +突破点 1 +x:1 +棉红蜘蛛 1 +x:1 +经合 1 +x:1 +游刃 1 +x:1 +猜疑 1 +x:1 +立夏 1 +x:1 +文艺 1 +x:1 +退亲 1 +x:1 +恩怨史 1 +x:1 +马肚 1 +x:1 +突变性 1 +x:1 +脱颖而出 1 +x:1 +半日 1 +x:1 +唾骂 1 +x:1 +半旧 1 +x:1 +畏惧感 1 +x:1 +发展署 1 +x:1 +只读 1 +x:1 +拉拉扯扯 1 +x:1 +劈头盖脸 1 +x:1 +诎 1 +x:1 +索还 1 +x:1 +角旗 1 +x:1 +慕 21 +x:21 +盘根错节 1 +x:1 +林州 1 +x:1 +种植 1 +x:1 +第三者 1 +x:1 +林工 1 +x:1 +劈头盖脑 1 +x:1 +惊魂未定 1 +x:1 +礼乐 1 +x:1 +胆小鬼 1 +x:1 +别是 1 +x:1 +牟家村 1 +x:1 +窑内 1 +x:1 +飞语 1 +x:1 +宏阔 1 +x:1 +大吃八喝 1 +x:1 +受检 1 +x:1 +会计处 1 +x:1 +批条子 1 +x:1 +洗衣社 1 +x:1 +行政局 1 +x:1 +退休 1 +x:1 +神效 1 +x:1 +出项 1 +x:1 +凤爪 1 +x:1 +排名表 1 +x:1 +退伙 1 +x:1 +纳塔尔省 1 +x:1 +企业法 1 +x:1 +人权会 1 +x:1 +天坍地陷 1 +x:1 +理欲观 1 +x:1 +条缕分明 1 +x:1 +首相府 1 +x:1 +立秋 1 +x:1 +岭 16 +x:16 +统称 1 +x:1 +出厂价 1 +x:1 +客套 1 +x:1 +高利贷式 1 +x:1 +斋棚 1 +x:1 +铁活 1 +x:1 +烘箱 1 +x:1 +中国画系 1 +x:1 +蜡笔 1 +x:1 +铁流 1 +x:1 +亿万斯年 1 +x:1 +面团 1 +x:1 +六里坪 1 +x:1 +诈取 1 +x:1 +尼曼 1 +x:1 +赌 27 +x:27 +药品 1 +x:1 +退位 1 +x:1 +珠峰 1 +x:1 +男足 1 +x:1 +住院 1 +x:1 +难眠之夜 1 +x:1 +科学学 1 +x:1 +阵管营 1 +x:1 +弹尽粮绝 1 +x:1 +礼俗 1 +x:1 +烘篮 1 +x:1 +文莱 1 +x:1 +主观臆断 1 +x:1 +宛西 1 +x:1 +嵬 3 +x:3 +情深意绵 1 +x:1 +德黑兰 1 +x:1 +畜牧 1 +x:1 +发展组 1 +x:1 +桃色 1 +x:1 +产枣区 1 +x:1 +艾 95 +x:95 +经售 1 +x:1 +药名 1 +x:1 +简洁 1 +x:1 +科学家 1 +x:1 +魏屯乡 1 +x:1 +山龟 1 +x:1 +书呆子 1 +x:1 +乳酶生 1 +x:1 +关系户 1 +x:1 +机器翻译 1 +x:1 +生津鲜美 1 +x:1 +锯子 1 +x:1 +刻字 1 +x:1 +数据库 1 +x:1 +先进村 1 +x:1 +电声 1 +x:1 +统收统支 1 +x:1 +帷幕 1 +x:1 +帷幔 1 +x:1 +画片 1 +x:1 +烘笼 1 +x:1 +客姓 1 +x:1 +直罗镇 1 +x:1 +桃花 1 +x:1 +公共积累 1 +x:1 +自上而下 1 +x:1 +柏梁镇 1 +x:1 +外孙子 1 +x:1 +无亲无故 1 +x:1 +缺医少药 1 +x:1 +复试 1 +x:1 +叫响 1 +x:1 +油杉木 1 +x:1 +拆开 1 +x:1 +麻袋 1 +x:1 +相加 1 +x:1 +屏条 1 +x:1 +匠人 1 +x:1 +人造纤维 1 +x:1 +退保 1 +x:1 +同谋犯 1 +x:1 +波 206 +x:206 +丑化 1 +x:1 +经商 1 +x:1 +研修生 1 +x:1 +洽办 1 +x:1 +经商潮 1 +x:1 +传统式 1 +x:1 +离休金 1 +x:1 +出题 1 +x:1 +外强中干 1 +x:1 +药味 1 +x:1 +僻野 1 +x:1 +机关枪 1 +x:1 +平定 1 +x:1 +平实 1 +x:1 +游乐园 1 +x:1 +涉 78 +x:78 +非专科 1 +x:1 +第二 1 +x:1 +纸带 1 +x:1 +独善其身 1 +x:1 +粉煤灰 1 +x:1 +平安 1 +x:1 +煤场 1 +x:1 +捉住 1 +x:1 +五级 1 +x:1 +俗话 1 +x:1 +通志 1 +x:1 +阿塞拜疆 1 +x:1 +脾性 1 +x:1 +咣 1 +x:1 +野青煤层 1 +x:1 +南营门街 1 +x:1 +俗语 1 +x:1 +农函 1 +x:1 +晨夕 1 +x:1 +倒海翻江 1 +x:1 +应予 1 +x:1 +间接肥料 1 +x:1 +一分为二 1 +x:1 +分中心 1 +x:1 +上税 1 +x:1 +转移 1 +x:1 +塑料壶 1 +x:1 +警察证 1 +x:1 +数学所 1 +x:1 +应价 1 +x:1 +新媳妇儿 1 +x:1 +通往 1 +x:1 +熟荒 1 +x:1 +服务队 1 +x:1 +路局 1 +x:1 +困境 1 +x:1 +瀛台 1 +x:1 +大竹县 1 +x:1 +体院 1 +x:1 +急驶 1 +x:1 +霎时 1 +x:1 +升起 1 +x:1 +当晚 1 +x:1 +五绝 1 +x:1 +公财 1 +x:1 +应付 1 +x:1 +太古菜 1 +x:1 +世纪 1 +x:1 +彪 75 +x:75 +作弄 1 +x:1 +起诉 1 +x:1 +五经 1 +x:1 +希罕 1 +x:1 +太空舱 1 +x:1 +公贿 1 +x:1 +迷迷糊糊 1 +x:1 +合成橡胶 1 +x:1 +公费 1 +x:1 +沟沟 1 +x:1 +世繁 1 +x:1 +百业兴旺 1 +x:1 +照水梅 1 +x:1 +第一 1 +x:1 +蝴蝶斑 1 +x:1 +二七区 1 +x:1 +蔽日 1 +x:1 +揣摸 1 +x:1 +小毛头 1 +x:1 +脚法 1 +x:1 +审核 1 +x:1 +犯颜直谏 1 +x:1 +槐角 1 +x:1 +农具 1 +x:1 +门架式 1 +x:1 +菜谱 1 +x:1 +庸俗化 1 +x:1 +公路 1 +x:1 +出票机 1 +x:1 +草料 1 +x:1 +国脚 1 +x:1 +盲童 1 +x:1 +融汇贯通 1 +x:1 +人民法院 1 +x:1 +圆木 1 +x:1 +洞 62 +x:62 +福音书 1 +x:1 +葡萄架 1 +x:1 +书画会 1 +x:1 +熟菜 1 +x:1 +中小城市 1 +x:1 +明确 1 +x:1 +吉尔吉斯 1 +x:1 +清明坊 1 +x:1 +菜豆 1 +x:1 +定性分析 1 +x:1 +说来话长 1 +x:1 +棉铃 1 +x:1 +机号 1 +x:1 +机台 1 +x:1 +油库 1 +x:1 +凑近 1 +x:1 +不知去向 1 +x:1 +开工 1 +x:1 +挑错 1 +x:1 +审案 1 +x:1 +普兰店市 1 +x:1 +挫裂伤 1 +x:1 +数以千计 1 +x:1 +采煤 1 +x:1 +神灯 1 +x:1 +悫 1 +x:1 +困难户 1 +x:1 +事事躬亲 1 +x:1 +阿曼 1 +x:1 +兼顾 1 +x:1 +丙稀 1 +x:1 +纸张 1 +x:1 +横峰 1 +x:1 +正大光明 1 +x:1 +咸阳市 1 +x:1 +挂斗 1 +x:1 +黄葛树 1 +x:1 +兼并额 1 +x:1 +机制 1 +x:1 +步话机 1 +x:1 +辖属 1 +x:1 +当期 1 +x:1 +游乐城 1 +x:1 +当朝 1 +x:1 +幸福村 1 +x:1 +行风 1 +x:1 +虽则 1 +x:1 +那化村 1 +x:1 +阻燃 1 +x:1 +繁峙县 1 +x:1 +当月 1 +x:1 +押送 1 +x:1 +羿 1 +x:1 +为时过早 1 +x:1 +开局 1 +x:1 +黄色工会 1 +x:1 +陪读 1 +x:1 +加工者 1 +x:1 +打基础 1 +x:1 +绳子 1 +x:1 +公谊 1 +x:1 +开屏 1 +x:1 +南丫岛 1 +x:1 +开展 1 +x:1 +体面 1 +x:1 +消费类 1 +x:1 +有效性 1 +x:1 +家庭型 1 +x:1 +黑粉病 1 +x:1 +重峦叠嶂 1 +x:1 +风险区 1 +x:1 +革 19 +x:19 +开山 1 +x:1 +行频 1 +x:1 +当权 1 +x:1 +北欧队 1 +x:1 +博野县 1 +x:1 +机动 1 +x:1 +圆梦 1 +x:1 +题录库 1 +x:1 +泰山压卵 1 +x:1 +需求量 1 +x:1 +副处 1 +x:1 +横山 1 +x:1 +国耻 1 +x:1 +钎 4 +x:4 +明示 1 +x:1 +茗 1 +x:1 +密告 1 +x:1 +辽河畔 1 +x:1 +普章乡 1 +x:1 +熠 1 +x:1 +治国者 1 +x:1 +失足者 1 +x:1 +侍郎 1 +x:1 +适用性 1 +x:1 +船蛆 1 +x:1 +国者 1 +x:1 +猪草 1 +x:1 +出版商 1 +x:1 +毡棚 1 +x:1 +怡人 1 +x:1 +菜贩 1 +x:1 +千岩万壑 1 +x:1 +拂 34 +x:34 +横尸 1 +x:1 +林苗圃 1 +x:1 +救起 1 +x:1 +克 168 +x:168 +酸枣糕 1 +x:1 +行李箱 1 +x:1 +专文 1 +x:1 +羊角 1 +x:1 +心不在焉 1 +x:1 +游乐场 1 +x:1 +豪夺巧取 1 +x:1 +弹性 1 +x:1 +困处 1 +x:1 +勘察队 1 +x:1 +制药 1 +x:1 +相互之间 1 +x:1 +孔洞 1 +x:1 +国联 1 +x:1 +穷山恶山 1 +x:1 +柳叶形 1 +x:1 +蛸蜞 1 +x:1 +扎得 1 +x:1 +甫 26 +x:26 +侧面 1 +x:1 +白云山 1 +x:1 +开开 1 +x:1 +舱单 1 +x:1 +俗见 1 +x:1 +开式 1 +x:1 +归来 1 +x:1 +通州 1 +x:1 +舵手 1 +x:1 +冷板 1 +x:1 +农友 1 +x:1 +公车 1 +x:1 +开张 1 +x:1 +国产化 1 +x:1 +典籍 1 +x:1 +公转 1 +x:1 +收紧 1 +x:1 +牌坊群 1 +x:1 +冷杉 1 +x:1 +大营盘乡 1 +x:1 +阿族 1 +x:1 +中科院 1 +x:1 +物种 1 +x:1 +农口 1 +x:1 +执委会 1 +x:1 +世系 1 +x:1 +美美 1 +x:1 +平妥 1 +x:1 +沟渠 1 +x:1 +犹他 1 +x:1 +棒冰 1 +x:1 +阿方 1 +x:1 +绿园区 1 +x:1 +早年 1 +x:1 +炕席 1 +x:1 +名士 1 +x:1 +侄子 1 +x:1 +机具 1 +x:1 +壕坡 1 +x:1 +机关 1 +x:1 +屏山顶 1 +x:1 +何台子村 1 +x:1 +防骄破满 1 +x:1 +起见 1 +x:1 +冲拳 1 +x:1 +阿斗 1 +x:1 +版纳 1 +x:1 +自勉 1 +x:1 +归期 1 +x:1 +深槽 1 +x:1 +毕业证 1 +x:1 +妖道 1 +x:1 +钟爱 1 +x:1 +罗滕堡 1 +x:1 +旱作区 1 +x:1 +汀河乡 1 +x:1 +毛驴子 1 +x:1 +血吸虫 1 +x:1 +凑足 1 +x:1 +开征 1 +x:1 +博山区 1 +x:1 +克郎球 1 +x:1 +原线圈 1 +x:1 +祖树 1 +x:1 +爸爸 1 +x:1 +辱没门庭 1 +x:1 +公开赛 1 +x:1 +平复 1 +x:1 +农协 1 +x:1 +细菌肥料 1 +x:1 +红澄澄 1 +x:1 +蚕食 1 +x:1 +公告栏 1 +x:1 +尊贵 1 +x:1 +河沙路 1 +x:1 +梧州港 1 +x:1 +普通话 1 +x:1 +平头 1 +x:1 +舱口 1 +x:1 +绳墨 1 +x:1 +班加罗尔 1 +x:1 +建材厂 1 +x:1 +北南向 1 +x:1 +降B大调 1 +x:1 +开心 1 +x:1 +教务长 1 +x:1 +采样管 1 +x:1 +和文 1 +x:1 +热线卡 1 +x:1 +秀美 1 +x:1 +冷枪 1 +x:1 +陪衬 1 +x:1 +蔬菜站 1 +x:1 +升迁 1 +x:1 +国药 1 +x:1 +涤浊扬清 1 +x:1 +蔚成 1 +x:1 +犯规者 1 +x:1 +地层 1 +x:1 +圆整 1 +x:1 +冷极 1 +x:1 +林网化 1 +x:1 +农区 1 +x:1 +五连版 1 +x:1 +困难性 1 +x:1 +陪行 1 +x:1 +神物 1 +x:1 +汴京 1 +x:1 +急飞 1 +x:1 +炕床 1 +x:1 +戈壁石 1 +x:1 +利税 1 +x:1 +麻卵石 1 +x:1 +开市 1 +x:1 +业界 1 +x:1 +云南马 1 +x:1 +国花 1 +x:1 +成年组 1 +x:1 +田黄石 1 +x:1 +标引词 1 +x:1 +布景钱 1 +x:1 +平假名 1 +x:1 +大婶儿 1 +x:1 +副官 1 +x:1 +口音 1 +x:1 +望天田 1 +x:1 +冲掉 1 +x:1 +花 978 +x:978 +原鸽 1 +x:1 +茅寮 1 +x:1 +潜水艇 1 +x:1 +明白卡 1 +x:1 +回辉村 1 +x:1 +挂架 1 +x:1 +暗无天日 1 +x:1 +红扑扑 1 +x:1 +风险关 1 +x:1 +棕熊队 1 +x:1 +体长 1 +x:1 +冲砂闸 1 +x:1 +农办 1 +x:1 +板场乡 1 +x:1 +长拳 1 +x:1 +奏响 1 +x:1 +开幕 1 +x:1 +曙 1 +x:1 +困守 1 +x:1 +古尔达拉 1 +x:1 +第一产业 1 +x:1 +嗵嗵 1 +x:1 +斡旋 1 +x:1 +横店 1 +x:1 +应者如云 1 +x:1 +楚国 1 +x:1 +中西医 1 +x:1 +知情权 1 +x:1 +犀浦镇 1 +x:1 +农务 1 +x:1 +雹 1 +x:1 +油布 1 +x:1 +平壤 1 +x:1 +守信用 1 +x:1 +富有者 1 +x:1 +通屏 1 +x:1 +渗透压 1 +x:1 +水烟 1 +x:1 +路径 1 +x:1 +地对空 1 +x:1 +务工证 1 +x:1 +棉鞋 1 +x:1 +一院制 1 +x:1 +软骨头 1 +x:1 +空心坝 1 +x:1 +支局长 1 +x:1 +宝刀不老 1 +x:1 +负 488 +x:488 +国航 1 +x:1 +遥遥茫茫 1 +x:1 +黄花岗 1 +x:1 +纽子 1 +x:1 +刀疤 1 +x:1 +萨马拉河 1 +x:1 +建筑法 1 +x:1 +光彩夺目 1 +x:1 +长成 1 +x:1 +樱 11 +x:11 +路徽 1 +x:1 +锡箔 1 +x:1 +横幅 1 +x:1 +通山 1 +x:1 +餐风宿雪 1 +x:1 +平塘 1 +x:1 +贫困带 1 +x:1 +威震 1 +x:1 +国色 1 +x:1 +泊 8 +x:8 +当时 1 +x:1 +纸工 1 +x:1 +动力机 1 +x:1 +腋毛 1 +x:1 +一来二去 1 +x:1 +刀痕 1 +x:1 +当日 1 +x:1 +排斥力 1 +x:1 +督 3 +x:3 +夜宵 1 +x:1 +无处 1 +x:1 +无烟火药 1 +x:1 +打硬仗 1 +x:1 +筹组 1 +x:1 +和衣而睡 1 +x:1 +冷暖 1 +x:1 +扁平 1 +x:1 +郑重 1 +x:1 +剿杀 1 +x:1 +天主 1 +x:1 +微秒 1 +x:1 +惊喜万分 1 +x:1 +冲撞 1 +x:1 +演化史 1 +x:1 +老干局 1 +x:1 +循规守旧 1 +x:1 +纱笼 1 +x:1 +开外 1 +x:1 +机场 1 +x:1 +揣想 1 +x:1 +清凉 1 +x:1 +财工发 1 +x:1 +洗手间 1 +x:1 +暴跳如雷 1 +x:1 +微生物学 1 +x:1 +壮凸 1 +x:1 +华晋 1 +x:1 +老年人 1 +x:1 +当成 1 +x:1 +刮金板 1 +x:1 +慈善性 1 +x:1 +梳 3 +x:3 +天上 1 +x:1 +长斋 1 +x:1 +动物纤维 1 +x:1 +开头 1 +x:1 +七星针 1 +x:1 +长文 1 +x:1 +天一 1 +x:1 +两姨亲 1 +x:1 +中间人 1 +x:1 +中小银行 1 +x:1 +总的讲 1 +x:1 +笔顺 1 +x:1 +刀片 1 +x:1 +择偶者 1 +x:1 +秘密 1 +x:1 +童话集 1 +x:1 +大圪村 1 +x:1 +无业游民 1 +x:1 +阿穆尔河 1 +x:1 +一四月 1 +x:1 +城东区 1 +x:1 +八九点钟 1 +x:1 +思恋 1 +x:1 +天书 1 +x:1 +择业 1 +x:1 +苦乐观 1 +x:1 +痹症 1 +x:1 +藓苔 1 +x:1 +夏吟 1 +x:1 +母大虫 1 +x:1 +起运 1 +x:1 +北麓 1 +x:1 +荣成 1 +x:1 +机坑 1 +x:1 +呈交 1 +x:1 +解放史 1 +x:1 +挂怀 1 +x:1 +茅屋 1 +x:1 +副将 1 +x:1 +典章 1 +x:1 +泰山鸿毛 1 +x:1 +广东团 1 +x:1 +安全法 1 +x:1 +困局 1 +x:1 +白叟黄童 1 +x:1 +叠床架屋 1 +x:1 +包探 1 +x:1 +高比例 1 +x:1 +城西乡 1 +x:1 +沟梁 1 +x:1 +执法权 1 +x:1 +备件 1 +x:1 +机型 1 +x:1 +生产基金 1 +x:1 +备份 1 +x:1 +渔港村 1 +x:1 +煤厂 1 +x:1 +大展身手 1 +x:1 +始而 1 +x:1 +嫩嫩的 1 +x:1 +绸料 1 +x:1 +滚沸 1 +x:1 +重犯者 1 +x:1 +剪刀 1 +x:1 +抒情性 1 +x:1 +采用 1 +x:1 +新华路 1 +x:1 +开始 1 +x:1 +感叹句 1 +x:1 +动力性 1 +x:1 +天价 1 +x:1 +燎 2 +x:2 +剪剪 1 +x:1 +感叹号 1 +x:1 +天仙 1 +x:1 +堰顶 1 +x:1 +闷闷不乐 1 +x:1 +拨浪鼓 1 +x:1 +乐此不疲 1 +x:1 +加密锁 1 +x:1 +硬骨头 1 +x:1 +道藏 1 +x:1 +长效 1 +x:1 +兹 7 +x:7 +安静村 1 +x:1 +双城市 1 +x:1 +威逼 1 +x:1 +驿 1 +x:1 +翅脉 1 +x:1 +造山运动 1 +x:1 +曲体 1 +x:1 +销货款 1 +x:1 +马尾区 1 +x:1 +起身 1 +x:1 +平底 1 +x:1 +录播 1 +x:1 +调整工 1 +x:1 +农民式 1 +x:1 +站住脚 1 +x:1 +版种 1 +x:1 +热镀锌 1 +x:1 +相劝 1 +x:1 +家庭史 1 +x:1 +卫生镇 1 +x:1 +平庄 1 +x:1 +鼓励类 1 +x:1 +平庸 1 +x:1 +口里 1 +x:1 +筹码 1 +x:1 +夺标 1 +x:1 +屈成 1 +x:1 +船艇 1 +x:1 +解放桥街 1 +x:1 +槐豆 1 +x:1 +阿拉 1 +x:1 +平度 1 +x:1 +思慕 1 +x:1 +施暴 1 +x:1 +机器 1 +x:1 +罚款单 1 +x:1 +痞子 1 +x:1 +炕头 1 +x:1 +肺泡 1 +x:1 +归总 1 +x:1 +船舸 1 +x:1 +洗车费 1 +x:1 +零2分 1 +x:1 +船舱 1 +x:1 +自尊心 1 +x:1 +江桥 1 +x:1 +船舷 1 +x:1 +船舶 1 +x:1 +择优 1 +x:1 +屡试不第 1 +x:1 +尽善尽美 1 +x:1 +颐指气使 1 +x:1 +择伐 1 +x:1 +天体 1 +x:1 +吃素 1 +x:1 +吃紧 1 +x:1 +战败 1 +x:1 +炉温 1 +x:1 +炉渣 1 +x:1 +宣传单 1 +x:1 +止境 1 +x:1 +如出一辙 1 +x:1 +翅膀 1 +x:1 +国营 1 +x:1 +禁运 1 +x:1 +基地式 1 +x:1 +取得 1 +x:1 +深渊 1 +x:1 +安排者 1 +x:1 +卡拉季 1 +x:1 +冬桃 1 +x:1 +永垂不朽 1 +x:1 +巅峰期 1 +x:1 +平常 1 +x:1 +壁室 1 +x:1 +支吾 1 +x:1 +神田 1 +x:1 +卫生间 1 +x:1 +胶卷盒 1 +x:1 +亲 138 +x:138 +电镜 1 +x:1 +超预算 1 +x:1 +从艺者 1 +x:1 +教科文 1 +x:1 +彩灯 1 +x:1 +丙纶 1 +x:1 +易发区 1 +x:1 +七溪岭 1 +x:1 +游乐区 1 +x:1 +绒 5 +x:5 +吏治 1 +x:1 +国葬 1 +x:1 +机械厂 1 +x:1 +机械厅 1 +x:1 +力争上游 1 +x:1 +沟槽 1 +x:1 +坠毁 1 +x:1 +古 474 +x:474 +挑逗 1 +x:1 +地心 1 +x:1 +平平 1 +x:1 +冷水域 1 +x:1 +国产品 1 +x:1 +溪口镇 1 +x:1 +肝条 1 +x:1 +冲散 1 +x:1 +家庭化 1 +x:1 +鳞波 1 +x:1 +幽 9 +x:9 +积累工 1 +x:1 +辗转反侧 1 +x:1 +夜幕 1 +x:1 +肥麦 1 +x:1 +订购粮 1 +x:1 +冻虾 1 +x:1 +入编费 1 +x:1 +长枪 1 +x:1 +明线 1 +x:1 +密友 1 +x:1 +金鸡路 1 +x:1 +窠臼 1 +x:1 +一分之差 1 +x:1 +秣马厉兵 1 +x:1 +荒村 1 +x:1 +遗尿病 1 +x:1 +巴尔干 1 +x:1 +检出率 1 +x:1 +大众呢 1 +x:1 +哑弹 1 +x:1 +离席 1 +x:1 +琢磨 1 +x:1 +券 11 +x:11 +卫生院 1 +x:1 +好胜心 1 +x:1 +平川 1 +x:1 +挂拍 1 +x:1 +克己为民 1 +x:1 +毁坏 1 +x:1 +易燃 1 +x:1 +毒品者 1 +x:1 +起跳 1 +x:1 +丹剧 1 +x:1 +邗江 1 +x:1 +艘 190 +x:190 +贫病交加 1 +x:1 +茅庐 1 +x:1 +深深 1 +x:1 +水浇地 1 +x:1 +采石 1 +x:1 +非实物 1 +x:1 +线轴儿 1 +x:1 +采矿 1 +x:1 +变脸 1 +x:1 +明细 1 +x:1 +农垦 1 +x:1 +起跑 1 +x:1 +丁字规 1 +x:1 +寄卡人 1 +x:1 +怡神 1 +x:1 +长机 1 +x:1 +公证 1 +x:1 +铁一局 1 +x:1 +俗赋 1 +x:1 +公诉 1 +x:1 +复兴门 1 +x:1 +年均 1 +x:1 +反文旁儿 1 +x:1 +锡纸 1 +x:1 +梦游症 1 +x:1 +长泰县 1 +x:1 +上套者 1 +x:1 +长期 1 +x:1 +刺针 1 +x:1 +核实率 1 +x:1 +淹没区 1 +x:1 +施教 1 +x:1 +草石蚕 1 +x:1 +服务部 1 +x:1 +筹算 1 +x:1 +归根究底 1 +x:1 +黄栗树 1 +x:1 +担保费 1 +x:1 +施政 1 +x:1 +强横霸道 1 +x:1 +镍 7 +x:7 +纽带 1 +x:1 +版税 1 +x:1 +滚滚 1 +x:1 +吨钢 1 +x:1 +火冒三丈 1 +x:1 +减人增效 1 +x:1 +长条 1 +x:1 +因 2274 +x:2274 +公认 1 +x:1 +荒林 1 +x:1 +通天 1 +x:1 +农地 1 +x:1 +公议 1 +x:1 +港墟沟 1 +x:1 +农场 1 +x:1 +郑铁 1 +x:1 +舒畅 1 +x:1 +挂扶 1 +x:1 +评奖费 1 +x:1 +改编权 1 +x:1 +公设 1 +x:1 +亚非拉 1 +x:1 +怪怪的 1 +x:1 +公论 1 +x:1 +商学院 1 +x:1 +开导 1 +x:1 +蜀 12 +x:12 +出版史 1 +x:1 +活立木 1 +x:1 +炕孵 1 +x:1 +计量行 1 +x:1 +禁赌 1 +x:1 +大陡山 1 +x:1 +怀诚 1 +x:1 +朝中社 1 +x:1 +深沉 1 +x:1 +禁赛 1 +x:1 +电镐 1 +x:1 +风动工具 1 +x:1 +助产 1 +x:1 +带路 1 +x:1 +贺兰县 1 +x:1 +远路 1 +x:1 +战车 1 +x:1 +消费税 1 +x:1 +世称 1 +x:1 +大写家 1 +x:1 +立功赎罪 1 +x:1 +谲 1 +x:1 +幸运感 1 +x:1 +处理权 1 +x:1 +忧郁 1 +x:1 +引以为鉴 1 +x:1 +农园 1 +x:1 +过得去 1 +x:1 +遭际 1 +x:1 +深泓 1 +x:1 +斗必十倍 1 +x:1 +下议院 1 +x:1 +代劳 1 +x:1 +求婚者 1 +x:1 +典礼 1 +x:1 +鸟类 1 +x:1 +成形术 1 +x:1 +有的放矢 1 +x:1 +顶芽 1 +x:1 +烦琐哲学 1 +x:1 +路子 1 +x:1 +模糊不清 1 +x:1 +宋庄 1 +x:1 +幸福感 1 +x:1 +不甘寂寞 1 +x:1 +晨幕 1 +x:1 +清嗓润肺 1 +x:1 +茶市 1 +x:1 +稽查所 1 +x:1 +糠秕 1 +x:1 +名编辑 1 +x:1 +忻 2 +x:2 +吃水量 1 +x:1 +这时 1 +x:1 +冷战 1 +x:1 +带走 1 +x:1 +物类 1 +x:1 +水灵 1 +x:1 +忌口 1 +x:1 +挂挂 1 +x:1 +左右翼 1 +x:1 +一丝不苟 1 +x:1 +世祖 1 +x:1 +巨石阵 1 +x:1 +冲服 1 +x:1 +长春 1 +x:1 +冷拼 1 +x:1 +湖前河 1 +x:1 +服务量 1 +x:1 +浩浩荡荡 1 +x:1 +平尾 1 +x:1 +华族 1 +x:1 +大吃一惊 1 +x:1 +麒麟 1 +x:1 +手足之情 1 +x:1 +决定论 1 +x:1 +花笺记 1 +x:1 +路宽 1 +x:1 +带资 1 +x:1 +典租 1 +x:1 +初显式微 1 +x:1 +西湖区 1 +x:1 +狗獾 1 +x:1 +卡拉奇 1 +x:1 +四言诗 1 +x:1 +薄型 1 +x:1 +杀烧淫掠 1 +x:1 +硅酸 1 +x:1 +长智 1 +x:1 +义务工 1 +x:1 +流水席 1 +x:1 +平展 1 +x:1 +空心化 1 +x:1 +冲杀 1 +x:1 +热乎乎 1 +x:1 +故作姿态 1 +x:1 +华新 1 +x:1 +平局 1 +x:1 +为民造福 1 +x:1 +第一把手 1 +x:1 +代书记 1 +x:1 +从轻发落 1 +x:1 +献计 1 +x:1 +开肠破肚 1 +x:1 +吴桥 1 +x:1 +三门县 1 +x:1 +机不可失 1 +x:1 +丁字街 1 +x:1 +纵切面 1 +x:1 +平山 1 +x:1 +楚剧 1 +x:1 +旬 15 +x:15 +牙根 1 +x:1 +鲛绡 1 +x:1 +机制纸 1 +x:1 +体量 1 +x:1 +体重 1 +x:1 +着陆点 1 +x:1 +中西北部 1 +x:1 +托罗累斯 1 +x:1 +冻融 1 +x:1 +章庄铺镇 1 +x:1 +路名 1 +x:1 +家禽业 1 +x:1 +很难说 1 +x:1 +明炮 1 +x:1 +农姑 1 +x:1 +配电房 1 +x:1 +五色缤纷 1 +x:1 +制艺 1 +x:1 +路向 1 +x:1 +不确定性 1 +x:1 +藏蓝色 1 +x:1 +煤炭部 1 +x:1 +大珠山镇 1 +x:1 +行里 1 +x:1 +新人奖 1 +x:1 +撑杆跳 1 +x:1 +山娃娃 1 +x:1 +夏塞 1 +x:1 +开唱 1 +x:1 +剪床 1 +x:1 +杏河乡 1 +x:1 +环境法 1 +x:1 +伯仲 1 +x:1 +忠清南道 1 +x:1 +平叛 1 +x:1 +五盼 1 +x:1 +活土层 1 +x:1 +香河园 1 +x:1 +军政权 1 +x:1 +位庄乡 1 +x:1 +卡脖子 1 +x:1 +晨兴 1 +x:1 +机械师 1 +x:1 +博大胸襟 1 +x:1 +中文系 1 +x:1 +务工者 1 +x:1 +平反 1 +x:1 +采种 1 +x:1 +重元素 1 +x:1 +爱厂如家 1 +x:1 +赞助费 1 +x:1 +自习课 1 +x:1 +叶面 1 +x:1 +坪 7 +x:7 +乐章 1 +x:1 +晨光 1 +x:1 +鸡头米 1 +x:1 +曼陀罗花 1 +x:1 +团伙处 1 +x:1 +申诉案 1 +x:1 +机子 1 +x:1 +安全性 1 +x:1 +阻碍 1 +x:1 +立案率 1 +x:1 +农药味 1 +x:1 +刺骨 1 +x:1 +冷淡 1 +x:1 +比合法 1 +x:1 +深挚 1 +x:1 +扩大会 1 +x:1 +削弱 1 +x:1 +真溶液 1 +x:1 +防护堆 1 +x:1 +黄山乡 1 +x:1 +拮抗剂 1 +x:1 +卫生防疫 1 +x:1 +伯乐 1 +x:1 +磁悬浮 1 +x:1 +农奴 1 +x:1 +棒子 1 +x:1 +纤 1 +x:1 +卧尔滋 1 +x:1 +熟记 1 +x:1 +机宜 1 +x:1 +出版局 1 +x:1 +庄稼 1 +x:1 +朵 93 +x:93 +祸患 1 +x:1 +船运 1 +x:1 +长椅 1 +x:1 +三门峡 1 +x:1 +羊肠 1 +x:1 +喾 1 +x:1 +峪口 1 +x:1 +熟话 1 +x:1 +明火 1 +x:1 +冷涡 1 +x:1 +明灯 1 +x:1 +炉排 1 +x:1 +非人 1 +x:1 +正版 1 +x:1 +一一道来 1 +x:1 +大不列颠 1 +x:1 +思泉 1 +x:1 +自缘 1 +x:1 +疑阵 1 +x:1 +预应力 1 +x:1 +花溪 1 +x:1 +熟读 1 +x:1 +贺兰山 1 +x:1 +牛肉面 1 +x:1 +机密 1 +x:1 +正牌 1 +x:1 +起草 1 +x:1 +农大 1 +x:1 +前半叶 1 +x:1 +困倦 1 +x:1 +待业青年 1 +x:1 +道观 1 +x:1 +笔铅 1 +x:1 +平卧 1 +x:1 +农夫 1 +x:1 +馒头 1 +x:1 +石灰道 1 +x:1 +正片 1 +x:1 +狙击战 1 +x:1 +窍 4 +x:4 +储备库 1 +x:1 +苟全性命 1 +x:1 +搏冰斗雪 1 +x:1 +弯翘 1 +x:1 +坠机 1 +x:1 +因变数 1 +x:1 +保康县 1 +x:1 +造纸 1 +x:1 +羊脂 1 +x:1 +热塑性 1 +x:1 +殆尽 1 +x:1 +禁药 1 +x:1 +冷汗 1 +x:1 +通国 1 +x:1 +笔锋 1 +x:1 +信口开河 1 +x:1 +强基固本 1 +x:1 +预备部 1 +x:1 +瞿 19 +x:19 +神秘 1 +x:1 +五矿 1 +x:1 +因袭性 1 +x:1 +安全感 1 +x:1 +夏天 1 +x:1 +平遥县 1 +x:1 +不测风云 1 +x:1 +打火机 1 +x:1 +策进会 1 +x:1 +冷水 1 +x:1 +臀尖 1 +x:1 +柴油机 1 +x:1 +东坝头村 1 +x:1 +玉米粉 1 +x:1 +情节线 1 +x:1 +心如死灰 1 +x:1 +教代会 1 +x:1 +公营 1 +x:1 +簇新 1 +x:1 +无脑儿 1 +x:1 +圆满 1 +x:1 +夏夜 1 +x:1 +候选国 1 +x:1 +中置同轴 1 +x:1 +羊膜 1 +x:1 +竹业 1 +x:1 +文韬武略 1 +x:1 +彩色电视 1 +x:1 +搬弄是非 1 +x:1 +平列 1 +x:1 +起航 1 +x:1 +开和 1 +x:1 +基地化 1 +x:1 +沿路 1 +x:1 +中青班 1 +x:1 +壁垒 1 +x:1 +埂子 1 +x:1 +政治 1 +x:1 +以彼之道 1 +x:1 +级 679 +x:679 +平分 1 +x:1 +揣测 1 +x:1 +密山 1 +x:1 +沟施 1 +x:1 +九月份 1 +x:1 +图法赫 1 +x:1 +模拟网 1 +x:1 +孔教 1 +x:1 +被调查者 1 +x:1 +营构 1 +x:1 +尼克斯队 1 +x:1 +冷泉 1 +x:1 +王大湾 1 +x:1 +模特儿 1 +x:1 +道袍 1 +x:1 +起舞 1 +x:1 +菜蔬 1 +x:1 +惨叫声 1 +x:1 +卫生香 1 +x:1 +狂犬病 1 +x:1 +船身 1 +x:1 +高中部 1 +x:1 +横吹 1 +x:1 +何须 1 +x:1 +大开眼界 1 +x:1 +撩乱 1 +x:1 +塬上 1 +x:1 +奋 14 +x:14 +无性生殖 1 +x:1 +剪影 1 +x:1 +密封 1 +x:1 +普通股 1 +x:1 +盲率 1 +x:1 +始起 1 +x:1 +剪彩 1 +x:1 +黄花园 1 +x:1 +浅海 1 +x:1 +神祇 1 +x:1 +伯伯 1 +x:1 +版画 1 +x:1 +勇进桥 1 +x:1 +欢蹦乱跳 1 +x:1 +绣球 1 +x:1 +堑壕战 1 +x:1 +横向 1 +x:1 +批准 1 +x:1 +制约性 1 +x:1 +长桌 1 +x:1 +柴 101 +x:101 +爬爬 1 +x:1 +跃进路 1 +x:1 +一家一户 1 +x:1 +幛子 1 +x:1 +史展 1 +x:1 +丹东港 1 +x:1 +菜蚜 1 +x:1 +温哥华 1 +x:1 +急造 1 +x:1 +流水号 1 +x:1 +反腐败 1 +x:1 +不可不 1 +x:1 +机头 1 +x:1 +槐荫 1 +x:1 +全攻全守 1 +x:1 +圈椅 1 +x:1 +纸厂 1 +x:1 +加信镇 1 +x:1 +禁飞区 1 +x:1 +杨家将 1 +x:1 +拼图 1 +x:1 +急速 1 +x:1 +别有风味 1 +x:1 +圆润 1 +x:1 +开场 1 +x:1 +拜年会 1 +x:1 +机外 1 +x:1 +次氯酸 1 +x:1 +南千岛 1 +x:1 +夺杯 1 +x:1 +热泪夺眶 1 +x:1 +冷漠 1 +x:1 +衬砌 1 +x:1 +方言词 1 +x:1 +急遽 1 +x:1 +粮田 1 +x:1 +平凉 1 +x:1 +大雨如注 1 +x:1 +国语 1 +x:1 +印把子 1 +x:1 +农安 1 +x:1 +保守派 1 +x:1 +悍将 1 +x:1 +长毛 1 +x:1 +月饼 1 +x:1 +攀枝花树 1 +x:1 +水产业 1 +x:1 +陨 4 +x:4 +夺权 1 +x:1 +战船 1 +x:1 +永吉街 1 +x:1 +动力源 1 +x:1 +贞 1 +x:1 +神童 1 +x:1 +人才济济 1 +x:1 +印钞厂 1 +x:1 +杨家岭 1 +x:1 +副刊 1 +x:1 +裂解 1 +x:1 +通商 1 +x:1 +深感 1 +x:1 +蹬 19 +x:19 +缺水 1 +x:1 +醒 48 +x:48 +流通额 1 +x:1 +金箔张 1 +x:1 +国力队 1 +x:1 +拔秧 1 +x:1 +花香菇 1 +x:1 +稚子 1 +x:1 +完好无损 1 +x:1 +深意 1 +x:1 +葱花 1 +x:1 +棉麻 1 +x:1 +导语 1 +x:1 +开垦 1 +x:1 +忠贞感 1 +x:1 +大巴山 1 +x:1 +侵略者 1 +x:1 +政治界 1 +x:1 +农学 1 +x:1 +冲模 1 +x:1 +家 4768 +x:4768 +Y 4 +x:4 +起脚 1 +x:1 +柔肤水 1 +x:1 +圆浑 1 +x:1 +老鹰队 1 +x:1 +审执 1 +x:1 +缎面 1 +x:1 +只争朝夕 1 +x:1 +园田地 1 +x:1 +审批 1 +x:1 +中心局 1 +x:1 +锦葵花 1 +x:1 +闷棍 1 +x:1 +仪仗 1 +x:1 +盲点 1 +x:1 +敝帚自珍 1 +x:1 +公子哥儿 1 +x:1 +双龙营乡 1 +x:1 +舱室 1 +x:1 +顷 13 +x:13 +观察使 1 +x:1 +率先垂范 1 +x:1 +食甘卧暖 1 +x:1 +线卷 1 +x:1 +局促 1 +x:1 +中产阶层 1 +x:1 +薄壳核桃 1 +x:1 +烟柳 1 +x:1 +有高有低 1 +x:1 +夏季 1 +x:1 +国标舞 1 +x:1 +神算 1 +x:1 +竞选 1 +x:1 +均匀率 1 +x:1 +牢记 1 +x:1 +空间结构 1 +x:1 +夜半 1 +x:1 +葱茏 1 +x:1 +江华站 1 +x:1 +稚嫩 1 +x:1 +冧 1 +x:1 +紫檀木 1 +x:1 +凤庄村 1 +x:1 +原阳 1 +x:1 +冷湖 1 +x:1 +坚壁清野 1 +x:1 +讲排场 1 +x:1 +煤尘 1 +x:1 +葡萄汁 1 +x:1 +招财进宝 1 +x:1 +茅台 1 +x:1 +红27军 1 +x:1 +财金 1 +x:1 +夙敌 1 +x:1 +马颈坳镇 1 +x:1 +明珠 1 +x:1 +伟业队 1 +x:1 +汪清县 1 +x:1 +闭合 1 +x:1 +窃钩窃国 1 +x:1 +路坝 1 +x:1 +疾风暴雨 1 +x:1 +畔 61 +x:61 +困厄 1 +x:1 +茅厕 1 +x:1 +身心健康 1 +x:1 +计算机界 1 +x:1 +毡房 1 +x:1 +预订量 1 +x:1 +冷清 1 +x:1 +尽力而为 1 +x:1 +孔林 1 +x:1 +煤层 1 +x:1 +不可救药 1 +x:1 +密度 1 +x:1 +慈善潮 1 +x:1 +不足为训 1 +x:1 +营救 1 +x:1 +煤屑 1 +x:1 +黔西南州 1 +x:1 +引风机 1 +x:1 +激将法 1 +x:1 +严治 1 +x:1 +通告 1 +x:1 +寒光 1 +x:1 +深思 1 +x:1 +深怀 1 +x:1 +普林斯顿 1 +x:1 +口齿 1 +x:1 +折返点 1 +x:1 +缠绵 1 +x:1 +肾上腺素 1 +x:1 +圈梁 1 +x:1 +夜叉 1 +x:1 +从五开始 1 +x:1 +塔院寺 1 +x:1 +成材率 1 +x:1 +后隋村 1 +x:1 +锦绣谷 1 +x:1 +心头病 1 +x:1 +取决 1 +x:1 +博卡区 1 +x:1 +缠绕 1 +x:1 +铷钟 1 +x:1 +当涂 1 +x:1 +荣宗耀祖 1 +x:1 +着装 1 +x:1 +一二·九 1 +x:1 +俗者 1 +x:1 +槐花 1 +x:1 +月食 1 +x:1 +新会 1 +x:1 +评奖者 1 +x:1 +夏收期 1 +x:1 +营养液 1 +x:1 +路域 1 +x:1 +雪魄 1 +x:1 +密布 1 +x:1 +收信连 1 +x:1 +牡丹 1 +x:1 +机声 1 +x:1 +通向 1 +x:1 +产褥热 1 +x:1 +机壳 1 +x:1 +国家室 1 +x:1 +祝贺信 1 +x:1 +葡萄沟 1 +x:1 +远洋船 1 +x:1 +扉页 1 +x:1 +农林牧 1 +x:1 +卓识 1 +x:1 +彩塑 1 +x:1 +碾坊 1 +x:1 +路基 1 +x:1 +储 27 +x:27 +批发 1 +x:1 +裕 9 +x:9 +取出 1 +x:1 +竹溪县 1 +x:1 +测绘法 1 +x:1 +丙烷 1 +x:1 +开国 1 +x:1 +国家局 1 +x:1 +长臂猿 1 +x:1 +运筹帷幄 1 +x:1 +粟子房镇 1 +x:1 +金属陶瓷 1 +x:1 +威风 1 +x:1 +即事 1 +x:1 +行间 1 +x:1 +长涪 1 +x:1 +纸制 1 +x:1 +中签号 1 +x:1 +条块结合 1 +x:1 +菜肴 1 +x:1 +柱廊 1 +x:1 +口风 1 +x:1 +甦 1 +x:1 +漳淮乡 1 +x:1 +脾气 1 +x:1 +通口 1 +x:1 +体膨胀 1 +x:1 +顶角 1 +x:1 +农工 1 +x:1 +平垣 1 +x:1 +通史 1 +x:1 +归心似箭 1 +x:1 +汀 1 +x:1 +勇擒 1 +x:1 +荒洲 1 +x:1 +投入率 1 +x:1 +忍 55 +x:55 +英石 1 +x:1 +副品 1 +x:1 +审讯表 1 +x:1 +长淮 1 +x:1 +按压 1 +x:1 +呼之欲出 1 +x:1 +晶莹 1 +x:1 +国路 1 +x:1 +帝豪 1 +x:1 +葱葱 1 +x:1 +珊瑚滩 1 +x:1 +升腾 1 +x:1 +彩虹灯 1 +x:1 +犹如 1 +x:1 +迭 19 +x:19 +笔道 1 +x:1 +战营 1 +x:1 +开关 1 +x:1 +通县 1 +x:1 +屡试不爽 1 +x:1 +冲泡 1 +x:1 +井下 1 +x:1 +秘史 1 +x:1 +即令 1 +x:1 +公平秤 1 +x:1 +中央 1 +x:1 +长活 1 +x:1 +国贼 1 +x:1 +簋 1 +x:1 +挖 222 +x:222 +降解剂 1 +x:1 +柳叶刀 1 +x:1 +湘剧 1 +x:1 +机徽 1 +x:1 +国货 1 +x:1 +急难 1 +x:1 +言谈举止 1 +x:1 +释义 1 +x:1 +光谱仪 1 +x:1 +行长 1 +x:1 +通卖 1 +x:1 +财工字 1 +x:1 +购书款 1 +x:1 +荒淫 1 +x:1 +尖端科学 1 +x:1 +华滋 1 +x:1 +言情式 1 +x:1 +楚天 1 +x:1 +点题 1 +x:1 +世物 1 +x:1 +平地 1 +x:1 +单摆浮搁 1 +x:1 +明理 1 +x:1 +鳞翅目 1 +x:1 +录制成 1 +x:1 +婚丧事 1 +x:1 +芴 1 +x:1 +体验 1 +x:1 +猪蹄 1 +x:1 +诲人不倦 1 +x:1 +盲目 1 +x:1 +第三系 1 +x:1 +明王朝 1 +x:1 +烟枪 1 +x:1 +东山后村 1 +x:1 +稻粱谋 1 +x:1 +市北区 1 +x:1 +该会 1 +x:1 +犹大 1 +x:1 +牧人 1 +x:1 +原野 1 +x:1 +沿袭 1 +x:1 +精力 1 +x:1 +道路 1 +x:1 +拿摩温 1 +x:1 +通化 1 +x:1 +欣慰 1 +x:1 +平均 1 +x:1 +取回 1 +x:1 +蕨类植物 1 +x:1 +康复站 1 +x:1 +行销 1 +x:1 +挂档 1 +x:1 +杨村浦路 1 +x:1 +符 146 +x:146 +机心 1 +x:1 +国资 1 +x:1 +她 5131 +x:5131 +开凿 1 +x:1 +长流 1 +x:1 +勇斗 1 +x:1 +火球 1 +x:1 +长治 1 +x:1 +死心眼儿 1 +x:1 +物探局 1 +x:1 +公职 1 +x:1 +长河 1 +x:1 +欣悦 1 +x:1 +五环 1 +x:1 +绳圈 1 +x:1 +香河县 1 +x:1 +刀笔 1 +x:1 +刺鼻 1 +x:1 +道谢 1 +x:1 +冲消 1 +x:1 +海棠树 1 +x:1 +取土 1 +x:1 +机师 1 +x:1 +长沙 1 +x:1 +列宁主义 1 +x:1 +厌氧池 1 +x:1 +爪 1 +x:1 +养殖业 1 +x:1 +急需 1 +x:1 +挑食 1 +x:1 +曜 2 +x:2 +井位 1 +x:1 +颞三针 1 +x:1 +香蕉叶 1 +x:1 +瓜达尔市 1 +x:1 +大山顶 1 +x:1 +战役式 1 +x:1 +归案 1 +x:1 +荒水 1 +x:1 +匹夫 1 +x:1 +白云区 1 +x:1 +乌咀乡 1 +x:1 +长泰 1 +x:1 +哑 6 +x:6 +阀体 1 +x:1 +数量词 1 +x:1 +兽面 1 +x:1 +泼皮 1 +x:1 +长波 1 +x:1 +枢机 1 +x:1 +日需求量 1 +x:1 +中委 1 +x:1 +长法 1 +x:1 +达观者 1 +x:1 +孪生子 1 +x:1 +按动 1 +x:1 +新邵县 1 +x:1 +冲淡 1 +x:1 +编织机 1 +x:1 +审验费 1 +x:1 +建材局 1 +x:1 +大槐树 1 +x:1 +原平市 1 +x:1 +灾 112 +x:112 +骆驼草 1 +x:1 +冲洗 1 +x:1 +禁止性 1 +x:1 +潭 15 +x:15 +长水 1 +x:1 +巧立名目 1 +x:1 +姿控 1 +x:1 +掌舵 1 +x:1 +古钱币 1 +x:1 +勇攀 1 +x:1 +审改 1 +x:1 +消费点 1 +x:1 +抗磨 1 +x:1 +炕几 1 +x:1 +现身说法 1 +x:1 +兵戎相见 1 +x:1 +机床 1 +x:1 +出版奖 1 +x:1 +倩 10 +x:10 +顾虑 1 +x:1 +一家多机 1 +x:1 +祖本 1 +x:1 +湖心亭 1 +x:1 +马赫主义 1 +x:1 +一见倾心 1 +x:1 +薰 3 +x:3 +伊萨尔 1 +x:1 +转赠给 1 +x:1 +改造 1 +x:1 +路况 1 +x:1 +先见之明 1 +x:1 +剪草除根 1 +x:1 +机库 1 +x:1 +亚排联 1 +x:1 +勇救 1 +x:1 +这部 1 +x:1 +消费热 1 +x:1 +盒 54 +x:54 +通则 1 +x:1 +即位 1 +x:1 +鲁鱼亥豕 1 +x:1 +敛 4 +x:4 +骨肉相连 1 +x:1 +群体处 1 +x:1 +长池 1 +x:1 +长江 1 +x:1 +应接不暇 1 +x:1 +即使 1 +x:1 +石花洞 1 +x:1 +荒沟 1 +x:1 +剪子 1 +x:1 +荒沙 1 +x:1 +国色天香 1 +x:1 +紫荆花 1 +x:1 +道不拾遗 1 +x:1 +冲浪 1 +x:1 +长汀 1 +x:1 +背书 1 +x:1 +毁弃 1 +x:1 +湮埋 1 +x:1 +五点 1 +x:1 +活跃期 1 +x:1 +取名 1 +x:1 +农忙 1 +x:1 +渔鼓 1 +x:1 +取向 1 +x:1 +中专班 1 +x:1 +开化 1 +x:1 +途 13 +x:13 +密密 1 +x:1 +高堡乡 1 +x:1 +交杯酒 1 +x:1 +矸石 1 +x:1 +伐木 1 +x:1 +唉叹 1 +x:1 +牙科 1 +x:1 +菜花 1 +x:1 +宋城 1 +x:1 +摇船 1 +x:1 +顾藉 1 +x:1 +闷气 1 +x:1 +通出 1 +x:1 +截然不同 1 +x:1 +艰难曲折 1 +x:1 +錾 1 +x:1 +骆驼肉 1 +x:1 +菜苗 1 +x:1 +横县 1 +x:1 +明目 1 +x:1 +优生优育 1 +x:1 +黑衣人 1 +x:1 +密实 1 +x:1 +道轨 1 +x:1 +荒漠 1 +x:1 +犬子 1 +x:1 +菊芋 1 +x:1 +碳氢化物 1 +x:1 +经理办 1 +x:1 +自然环境 1 +x:1 +庆贺寺乡 1 +x:1 +国运 1 +x:1 +庸医 1 +x:1 +察哈尔 1 +x:1 +夏布 1 +x:1 +菊花 1 +x:1 +槐蜜 1 +x:1 +表蒙子 1 +x:1 +临到 1 +x:1 +密室 1 +x:1 +开卷 1 +x:1 +燎原 1 +x:1 +辖区 1 +x:1 +评议员 1 +x:1 +采编 1 +x:1 +方木 1 +x:1 +性灵 1 +x:1 +浮沉荣枯 1 +x:1 +铩羽 1 +x:1 +横卧 1 +x:1 +版片 1 +x:1 +相对论性 1 +x:1 +守三村 1 +x:1 +孪生 1 +x:1 +希拉勒队 1 +x:1 +地幔 1 +x:1 +卡其村 1 +x:1 +忌嫉 1 +x:1 +钻井队 1 +x:1 +犹存 1 +x:1 +宋坑 1 +x:1 +掌权者 1 +x:1 +摸门儿 1 +x:1 +钼 2 +x:2 +通关 1 +x:1 +炉料 1 +x:1 +晋安区 1 +x:1 +横匾 1 +x:1 +缠管 1 +x:1 +茼山 1 +x:1 +机工 1 +x:1 +组织局 1 +x:1 +杜集区 1 +x:1 +陪葬 1 +x:1 +安非拉酮 1 +x:1 +单循环 1 +x:1 +明白 1 +x:1 +白纸坊 1 +x:1 +不识大体 1 +x:1 +单航次 1 +x:1 +织造厂 1 +x:1 +镯子 1 +x:1 +文武场 1 +x:1 +开口 1 +x:1 +菜色 1 +x:1 +韦 114 +x:114 +施洞 1 +x:1 +熟路 1 +x:1 +华沙 1 +x:1 +经理制 1 +x:1 +挂橱 1 +x:1 +繁殖率 1 +x:1 +锡盟 1 +x:1 +野三关镇 1 +x:1 +开刀 1 +x:1 +梅 180 +x:180 +碱土金属 1 +x:1 +熟谙 1 +x:1 +排污量 1 +x:1 +克隆人 1 +x:1 +耦色 1 +x:1 +机尾 1 +x:1 +塑钢 1 +x:1 +开列 1 +x:1 +平和 1 +x:1 +路北 1 +x:1 +开创 1 +x:1 +夜景灯 1 +x:1 +它山之石 1 +x:1 +开初 1 +x:1 +流落他乡 1 +x:1 +荒湖 1 +x:1 +采纳 1 +x:1 +煤堆 1 +x:1 +没事 1 +x:1 +兴平乡 1 +x:1 +碳酸氢铵 1 +x:1 +六八年 1 +x:1 +夙愿 1 +x:1 +去冬 1 +x:1 +久久不绝 1 +x:1 +报复性 1 +x:1 +化铁炉 1 +x:1 +审查 1 +x:1 +出版家 1 +x:1 +还乡河 1 +x:1 +檀郎 1 +x:1 +明知 1 +x:1 +葡萄核 1 +x:1 +屏山镇 1 +x:1 +邪不压正 1 +x:1 +农庄 1 +x:1 +年根儿 1 +x:1 +六腑 1 +x:1 +长滩 1 +x:1 +乖 3 +x:3 +路南 1 +x:1 +鱼尾纹 1 +x:1 +至诚至爱 1 +x:1 +横加 1 +x:1 +机械处 1 +x:1 +广纳 1 +x:1 +色米拉 1 +x:1 +菲律宾队 1 +x:1 +法理 1 +x:1 +各种各样 1 +x:1 +大家庭 1 +x:1 +多方位 1 +x:1 +滚杠 1 +x:1 +路卡 1 +x:1 +农药厂 1 +x:1 +政团 1 +x:1 +绕口令 1 +x:1 +马佐维茨 1 +x:1 +喷发物 1 +x:1 +争气机 1 +x:1 +华乐街 1 +x:1 +怅然之余 1 +x:1 +披星戴月 1 +x:1 +长游 1 +x:1 ++ 19 +x:19 +通假 1 +x:1 +透河井 1 +x:1 +红11师 1 +x:1 +打工者 1 +x:1 +出版学 1 +x:1 +尊者 1 +x:1 +补助货币 1 +x:1 +开办 1 +x:1 +荒滩 1 +x:1 +苗家人 1 +x:1 +箱体 1 +x:1 +糖醋鱼 1 +x:1 +茅坪 1 +x:1 +开动 1 +x:1 +葆 27 +x:27 +黄粱梦镇 1 +x:1 +力大无穷 1 +x:1 +民政科 1 +x:1 +公英 1 +x:1 +乌布苏 1 +x:1 +斯里兰卡 1 +x:1 +长湾 1 +x:1 +两世为人 1 +x:1 +稳健派 1 +x:1 +阿萨伊果 1 +x:1 +先修班 1 +x:1 +胡茬 1 +x:1 +韧性 1 +x:1 +清运量 1 +x:1 +卓 23 +x:23 +柚苗 1 +x:1 +圆桌 1 +x:1 +锡矿 1 +x:1 +唾液腺 1 +x:1 +槐蚕 1 +x:1 +长湖 1 +x:1 +阳光 1 +x:1 +路口 1 +x:1 +淬 2 +x:2 +夏征 1 +x:1 +学习会 1 +x:1 +长恨歌 1 +x:1 +桔梗 1 +x:1 +鉴貌辨色 1 +x:1 +物理 1 +x:1 +店面间 1 +x:1 +格斗术 1 +x:1 +正方体 1 +x:1 +精研细磨 1 +x:1 +壁上 1 +x:1 +建筑署 1 +x:1 +烟退云敛 1 +x:1 +国家标准 1 +x:1 +花大姐 1 +x:1 +荣登 1 +x:1 +碧头村 1 +x:1 +下乡 1 +x:1 +竹轮 1 +x:1 +中南欧 1 +x:1 +焖 3 +x:3 +尺动脉 1 +x:1 +通俗 1 +x:1 +生病 1 +x:1 +衬托 1 +x:1 +恩图曼 1 +x:1 +行规 1 +x:1 +天眼 1 +x:1 +测控船 1 +x:1 +鼻息 1 +x:1 +通信 1 +x:1 +纸业 1 +x:1 +堰 1 +x:1 +装设 1 +x:1 +鬼点子 1 +x:1 +笔谈 1 +x:1 +殷家山 1 +x:1 +笔调 1 +x:1 +移植 1 +x:1 +用球 1 +x:1 +刺绣组 1 +x:1 +铃 8 +x:8 +园旁 1 +x:1 +上方山 1 +x:1 +方庄镇 1 +x:1 +体虱 1 +x:1 +拿药 1 +x:1 +桐 4 +x:4 +煤科院 1 +x:1 +欧元区 1 +x:1 +文学馆 1 +x:1 +神情 1 +x:1 +混杂 1 +x:1 +班底 1 +x:1 +没准 1 +x:1 +建筑编 1 +x:1 +开水壶 1 +x:1 +水江乡 1 +x:1 +质次价高 1 +x:1 +肺科 1 +x:1 +贬者 1 +x:1 +神思 1 +x:1 +侍臣 1 +x:1 +雷动 1 +x:1 +拿获 1 +x:1 +纸人 1 +x:1 +放飞场 1 +x:1 +按住 1 +x:1 +神态 1 +x:1 +天文学部 1 +x:1 +牺牲 1 +x:1 +通体 1 +x:1 +即刻 1 +x:1 +现有 1 +x:1 +厝 1 +x:1 +秘传 1 +x:1 +名店 1 +x:1 +智圆行方 1 +x:1 +神怪 1 +x:1 +金水桥 1 +x:1 +安徽厅 1 +x:1 +庄户 1 +x:1 +五清 1 +x:1 +应市 1 +x:1 +莫先乎情 1 +x:1 +通佳 1 +x:1 +黄山嘴 1 +x:1 +子弹 1 +x:1 +综合国力 1 +x:1 +累西腓 1 +x:1 +贬职 1 +x:1 +物欲 1 +x:1 +竞试 1 +x:1 +军用机 1 +x:1 +牙缝 1 +x:1 +稳如泰山 1 +x:1 +警示牌 1 +x:1 +建筑群 1 +x:1 +炫人眼眸 1 +x:1 +矿上 1 +x:1 +腔模 1 +x:1 +闭合电路 1 +x:1 +国酒 1 +x:1 +吏禄 1 +x:1 +发令枪 1 +x:1 +老头子 1 +x:1 +拔掉 1 +x:1 +医药学界 1 +x:1 +娇好 1 +x:1 +谁 1262 +x:1262 +嘶鸣 1 +x:1 +曲子 1 +x:1 +入画 1 +x:1 +先富户 1 +x:1 +荒灾 1 +x:1 +美誉度 1 +x:1 +大马士革 1 +x:1 +移栽 1 +x:1 +核科学家 1 +x:1 +高利贷 1 +x:1 +原谅 1 +x:1 +自供 1 +x:1 +演艺界 1 +x:1 +荒火 1 +x:1 +阿盟 1 +x:1 +绿茵场 1 +x:1 +行装 1 +x:1 +当真 1 +x:1 +泼水花儿 1 +x:1 +应得 1 +x:1 +绿茵地 1 +x:1 +刀术 1 +x:1 +按价 1 +x:1 +道途 1 +x:1 +杨楼镇 1 +x:1 +纸伞 1 +x:1 +民政村 1 +x:1 +千层底 1 +x:1 +熏染 1 +x:1 +候选人 1 +x:1 +圆盒 1 +x:1 +铁岭市 1 +x:1 +东弓营村 1 +x:1 +圆盖 1 +x:1 +井区 1 +x:1 +国都 1 +x:1 +修行 1 +x:1 +仓惶 1 +x:1 +虚心 1 +x:1 +教管班 1 +x:1 +拉模 1 +x:1 +秀气 1 +x:1 +亡故 1 +x:1 +观察哨 1 +x:1 +通亮 1 +x:1 +万马齐喑 1 +x:1 +顶针 1 +x:1 +澳洲 1 +x:1 +通产 1 +x:1 +父亲 1 +x:1 +柿子 1 +x:1 +巳 1 +x:1 +即可 1 +x:1 +欺上瞒下 1 +x:1 +船队 1 +x:1 +涵养林 1 +x:1 +后来人 1 +x:1 +当着 1 +x:1 +壮族 1 +x:1 +高质 1 +x:1 +汴州 1 +x:1 +冀 65 +x:65 +纵横驰骋 1 +x:1 +阿登 1 +x:1 +林学院 1 +x:1 +呈子 1 +x:1 +雾滴 1 +x:1 +井台 1 +x:1 +井史 1 +x:1 +天宫 1 +x:1 +贪利者 1 +x:1 +拿手好戏 1 +x:1 +阅读者 1 +x:1 +斜拉式 1 +x:1 +外科学 1 +x:1 +井口 1 +x:1 +晖映 1 +x:1 +诱饵 1 +x:1 +打喷嚏 1 +x:1 +同类项 1 +x:1 +刀枪 1 +x:1 +宽限期 1 +x:1 +通书 1 +x:1 +菲律宾裔 1 +x:1 +十二属 1 +x:1 +作工 1 +x:1 +保洁队 1 +x:1 +环状软骨 1 +x:1 +何者 1 +x:1 +家具商 1 +x:1 +自吹自擂 1 +x:1 +通买 1 +x:1 +虚弱 1 +x:1 +天宇 1 +x:1 +狂 50 +x:50 +生存斗争 1 +x:1 +刀柄 1 +x:1 +量器 1 +x:1 +炉窑 1 +x:1 +许村乡 1 +x:1 +铝矾石 1 +x:1 +模拟机 1 +x:1 +楦板 1 +x:1 +观察员 1 +x:1 +笔路 1 +x:1 +枫林 1 +x:1 +相 1422 +x:1422 +枫果 1 +x:1 +湘桂 1 +x:1 +验电笔 1 +x:1 +岘港 1 +x:1 +国道 1 +x:1 +急诊 1 +x:1 +太仓港 1 +x:1 +秘书 1 +x:1 +旭日东升 1 +x:1 +人事权 1 +x:1 +腰堡乡 1 +x:1 +圯 1 +x:1 +消长 1 +x:1 +汇流处 1 +x:1 +计生户 1 +x:1 +路上 1 +x:1 +华灯 1 +x:1 +佐读 1 +x:1 +行语 1 +x:1 +虚岁 1 +x:1 +湖口县 1 +x:1 +采掘 1 +x:1 +园林 1 +x:1 +阻拦 1 +x:1 +船长 1 +x:1 +赵家条 1 +x:1 +开会 1 +x:1 +布琼布拉 1 +x:1 +媛 6 +x:6 +肝炎 1 +x:1 +刺耳 1 +x:1 +行评 1 +x:1 +二义性 1 +x:1 +办水热 1 +x:1 +战马 1 +x:1 +天堑 1 +x:1 +礼记 1 +x:1 +乡村级 1 +x:1 +佐证 1 +x:1 +上臂 1 +x:1 +模声拟态 1 +x:1 +天堂 1 +x:1 +安义县 1 +x:1 +原核 1 +x:1 +煤机厂 1 +x:1 +嗅 11 +x:11 +克莱维 1 +x:1 +懊悔 1 +x:1 +撼天动地 1 +x:1 +临湘市 1 +x:1 +曹峪村 1 +x:1 +樊城 1 +x:1 +仪器 1 +x:1 +移步 1 +x:1 +遭荒 1 +x:1 +大本子 1 +x:1 +深秋 1 +x:1 +冷眼 1 +x:1 +挂盘 1 +x:1 +综合篇 1 +x:1 +日 1839 +x:1839 +政治篇 1 +x:1 +连通器 1 +x:1 +包袱井 1 +x:1 +建安处 1 +x:1 +盐分 1 +x:1 +盲校 1 +x:1 +带领 1 +x:1 +奥地利 1 +x:1 +兽行 1 +x:1 +春假 1 +x:1 +雪域 1 +x:1 +急袭 1 +x:1 +六鲁 1 +x:1 +棉蚜 1 +x:1 +兼课 1 +x:1 +入网地 1 +x:1 +居民委 1 +x:1 +船闸 1 +x:1 +膨松粉 1 +x:1 +耳生 1 +x:1 +兼语 1 +x:1 +审稿 1 +x:1 +黑发人 1 +x:1 +懊恼 1 +x:1 +煮沸 1 +x:1 +菜鸽 1 +x:1 +邬 11 +x:11 +神户 1 +x:1 +路人 1 +x:1 +痛悼 1 +x:1 +举案齐眉 1 +x:1 +椽 4 +x:4 +无土栽培 1 +x:1 +可感 1 +x:1 +典法 1 +x:1 +太极图 1 +x:1 +执政府 1 +x:1 +印痕 1 +x:1 +成型机 1 +x:1 +闷热 1 +x:1 +罐内 1 +x:1 +傈僳族 1 +x:1 +可燃性 1 +x:1 +大戏院 1 +x:1 +菜鹅 1 +x:1 +阳陵泉 1 +x:1 +动滑轮 1 +x:1 +兼议 1 +x:1 +阻截 1 +x:1 +横传 1 +x:1 +天壤 1 +x:1 +助学 1 +x:1 +肖成林 1 +x:1 +锈迹 1 +x:1 +异客 1 +x:1 +祝贺团 1 +x:1 +严查 1 +x:1 +白马寺 1 +x:1 +应届 1 +x:1 +推动者 1 +x:1 +居奇牟利 1 +x:1 +口蘑 1 +x:1 +肝火 1 +x:1 +置之度外 1 +x:1 +硬腭 1 +x:1 +玷污 1 +x:1 +都政府 1 +x:1 +熟透 1 +x:1 +发球手 1 +x:1 +释减 1 +x:1 +定式化 1 +x:1 +开业 1 +x:1 +月老 1 +x:1 +嫌贫爱富 1 +x:1 +天大 1 +x:1 +孝子 1 +x:1 +肘部 1 +x:1 +各自为政 1 +x:1 +口碑载道 1 +x:1 +橡胶管 1 +x:1 +商贿官贪 1 +x:1 +崴 49 +x:49 +深碧 1 +x:1 +王老五 1 +x:1 +厨师班 1 +x:1 +牙粉 1 +x:1 +湛河 1 +x:1 +复读 1 +x:1 +政工师 1 +x:1 +岱庙 1 +x:1 +辖下 1 +x:1 +熟道 1 +x:1 +曲处 1 +x:1 +浔 3 +x:3 +新旧杂陈 1 +x:1 +何苦 1 +x:1 +滚筒 1 +x:1 +寡言 1 +x:1 +横亘 1 +x:1 +防暑降温 1 +x:1 +公鸡 1 +x:1 +卓尔不傲 1 +x:1 +叫 862 +x:862 +神户港 1 +x:1 +雾气 1 +x:1 +外景地 1 +x:1 +观察国 1 +x:1 +横事 1 +x:1 +蛹 1 +x:1 +起飞 1 +x:1 +庄稼活儿 1 +x:1 +日本队 1 +x:1 +一言难尽 1 +x:1 +仓房 1 +x:1 +建筑系 1 +x:1 +骆 32 +x:32 +奶酪 1 +x:1 +倾国倾城 1 +x:1 +五洲 1 +x:1 +白报纸 1 +x:1 +衣领 1 +x:1 +筹资额 1 +x:1 +翅鞘 1 +x:1 +支付日 1 +x:1 +忧患 1 +x:1 +抱屈 1 +x:1 +扩血管药 1 +x:1 +独木桥 1 +x:1 +圈点 1 +x:1 +释典 1 +x:1 +开交 1 +x:1 +桥牌赛 1 +x:1 +陪餐 1 +x:1 +平方里 1 +x:1 +奶酒 1 +x:1 +妙笔生花 1 +x:1 +仪型 1 +x:1 +助威 1 +x:1 +冷盘 1 +x:1 +窟窿 1 +x:1 +辍学率 1 +x:1 +魂飞西天 1 +x:1 +糊 10 +x:10 +爱乐者 1 +x:1 +海阔云舒 1 +x:1 +阻挡 1 +x:1 +阻挠 1 +x:1 +竹制品 1 +x:1 +长物 1 +x:1 +船钱 1 +x:1 +姜 464 +x:464 +挑灯苦读 1 +x:1 +下泄 1 +x:1 +即兴 1 +x:1 +盐厂 1 +x:1 +建井所 1 +x:1 +河北区 1 +x:1 +正点率 1 +x:1 +井冈 1 +x:1 +郁闷 1 +x:1 +权力观 1 +x:1 +排污费 1 +x:1 +威胁 1 +x:1 +跳跃式 1 +x:1 +悬空寺 1 +x:1 +各自为战 1 +x:1 +偷偷摸摸 1 +x:1 +养殖地 1 +x:1 +炉网 1 +x:1 +行路 1 +x:1 +养殖场 1 +x:1 +高谈阔论 1 +x:1 +显示钮 1 +x:1 +绳上 1 +x:1 +投入比 1 +x:1 +西凤酒 1 +x:1 +刀戟 1 +x:1 +周报制 1 +x:1 +逢山开路 1 +x:1 +高温带 1 +x:1 +嗟叹 1 +x:1 +电针疗法 1 +x:1 +虎门港 1 +x:1 +音源器 1 +x:1 +雷达 1 +x:1 +贵妇人 1 +x:1 +碳 10 +x:10 +孝学 1 +x:1 +乐观其成 1 +x:1 +毡笠 1 +x:1 +明沟 1 +x:1 +行距 1 +x:1 +芬兰队 1 +x:1 +天幸 1 +x:1 +没说的 1 +x:1 +评议书 1 +x:1 +自动铅笔 1 +x:1 +平保 1 +x:1 +血管性 1 +x:1 +天平 1 +x:1 +抱定 1 +x:1 +天年 1 +x:1 +政工处 1 +x:1 +卿卿我我 1 +x:1 +哲理 1 +x:1 +紧凑 1 +x:1 +事过境迁 1 +x:1 +绿黄色 1 +x:1 +博 38 +x:38 +助工 1 +x:1 +国门 1 +x:1 +服务舱 1 +x:1 +明泉 1 +x:1 +农艺园 1 +x:1 +金水河 1 +x:1 +深翻 1 +x:1 +沿途 1 +x:1 +天幕 1 +x:1 +冷焊 1 +x:1 +书画家 1 +x:1 +圆珠 1 +x:1 +产业资本 1 +x:1 +量变 1 +x:1 +公平感 1 +x:1 +平信 1 +x:1 +捺 4 +x:4 +吃水 1 +x:1 +扩大化 1 +x:1 +环境灯 1 +x:1 +卜辞 1 +x:1 +备感荣幸 1 +x:1 +天庭 1 +x:1 +录用 1 +x:1 +行走 1 +x:1 +安步当车 1 +x:1 +铁皮柜 1 +x:1 +一模一样 1 +x:1 +版框 1 +x:1 +吃法 1 +x:1 +在野派 1 +x:1 +长生 1 +x:1 +采收 1 +x:1 +瞒骗 1 +x:1 +闭门造车 1 +x:1 +保障型 1 +x:1 +急躁 1 +x:1 +俳 5 +x:5 +蚀本 1 +x:1 +冮 5 +x:5 +迫切性 1 +x:1 +牙签 1 +x:1 +量化 1 +x:1 +钩挂 1 +x:1 +华盖 1 +x:1 +优点 1 +x:1 +公馆 1 +x:1 +时过境迁 1 +x:1 +劳动局长 1 +x:1 +小五金 1 +x:1 +十二大 1 +x:1 +新楼 1 +x:1 +行贩 1 +x:1 +剿灭 1 +x:1 +肝癌 1 +x:1 +二项式 1 +x:1 +路由器 1 +x:1 +卤族 1 +x:1 +敞篷车 1 +x:1 +取代 1 +x:1 +慰缭子 1 +x:1 +沃里克郡 1 +x:1 +目睹记 1 +x:1 +挂灯 1 +x:1 +后延 1 +x:1 +种粮食 1 +x:1 +有心人 1 +x:1 +曲度 1 +x:1 +参政议政 1 +x:1 +姆塞克瓦 1 +x:1 +行负 1 +x:1 +荒疏 1 +x:1 +拉动性 1 +x:1 +藻类 1 +x:1 +武力 1 +x:1 +桦树皮 1 +x:1 +口臭 1 +x:1 +挚友 1 +x:1 +顶部 1 +x:1 +东直门 1 +x:1 +非公经济 1 +x:1 +共振点 1 +x:1 +菜馆 1 +x:1 +虚实 1 +x:1 +诸侯国 1 +x:1 +脉脉含情 1 +x:1 +到手 1 +x:1 +曝光度 1 +x:1 +一拥而起 1 +x:1 +武功 1 +x:1 +督导团 1 +x:1 +晴天霹雳 1 +x:1 +采撷 1 +x:1 +移民 1 +x:1 +裤袋 1 +x:1 +圆状 1 +x:1 +军事基地 1 +x:1 +横 93 +x:93 +环 178 +x:178 +葡萄牙 1 +x:1 +公顷 1 +x:1 +深红 1 +x:1 +量力 1 +x:1 +张集镇 1 +x:1 +晓市 1 +x:1 +平产 1 +x:1 +似 260 +x:260 +公平性 1 +x:1 +不失时宜 1 +x:1 +井场 1 +x:1 +舒曼 1 +x:1 +质保书 1 +x:1 +菏 1 +x:1 +贤内助 1 +x:1 +捐款人 1 +x:1 +亲戚 1 +x:1 +立交化 1 +x:1 +曲式 1 +x:1 +雇佣观点 1 +x:1 +阻断 1 +x:1 +塞 122 +x:122 +电磁场 1 +x:1 +深绵 1 +x:1 +厉鬼 1 +x:1 +裤裆 1 +x:1 +平价 1 +x:1 +深绿 1 +x:1 +琼 40 +x:40 +德宏 1 +x:1 +国铁 1 +x:1 +蚊虫 1 +x:1 +珊瑚石 1 +x:1 +贫困区 1 +x:1 +兰陵镇 1 +x:1 +净增额 1 +x:1 +忧色 1 +x:1 +冷热 1 +x:1 +冷烫 1 +x:1 +纯数学 1 +x:1 +只见 1 +x:1 +闪击战 1 +x:1 +猪革 1 +x:1 +报仇雪恨 1 +x:1 +冠名 1 +x:1 +欧元国 1 +x:1 +张家沟 1 +x:1 +停电日 1 +x:1 +鹰窠顶 1 +x:1 +主旋律 1 +x:1 +油油的 1 +x:1 +孤儿村 1 +x:1 +管道 1 +x:1 +影壁 1 +x:1 +王坚固村 1 +x:1 +有假 1 +x:1 +明洞 1 +x:1 +瑞金 1 +x:1 +北窖镇 1 +x:1 +量刑 1 +x:1 +口腔 1 +x:1 +急迫 1 +x:1 +阿爸 1 +x:1 +阿爷 1 +x:1 +手软 1 +x:1 +古语词 1 +x:1 +钛白粉 1 +x:1 +采摘 1 +x:1 +摧崖拍岸 1 +x:1 +安徽团 1 +x:1 +工人贵族 1 +x:1 +当班 1 +x:1 +鬼使神差 1 +x:1 +笔触 1 +x:1 +各尽所长 1 +x:1 +虚字 1 +x:1 +没命 1 +x:1 +取保 1 +x:1 +冷点 1 +x:1 +九寨沟 1 +x:1 +有偿 1 +x:1 +菜饼 1 +x:1 +野炊 1 +x:1 +急进 1 +x:1 +移泊 1 +x:1 +平乡 1 +x:1 +菜饭 1 +x:1 +再进一步 1 +x:1 +直观性 1 +x:1 +太平水缸 1 +x:1 +男高音 1 +x:1 +训词 1 +x:1 +地上权 1 +x:1 +圆熟 1 +x:1 +民乐曲 1 +x:1 +蚀斑 1 +x:1 +行述 1 +x:1 +筹款 1 +x:1 +训话 1 +x:1 +搬运工 1 +x:1 +肠梗阻 1 +x:1 +笞 1 +x:1 +花池 1 +x:1 +计生星 1 +x:1 +仪刑 1 +x:1 +训诫 1 +x:1 +肾衰竭 1 +x:1 +决一高低 1 +x:1 +赤手空拳 1 +x:1 +战鹰 1 +x:1 +蚕豆 1 +x:1 +克隆型 1 +x:1 +建业队 1 +x:1 +喊冤叫屈 1 +x:1 +没事儿 1 +x:1 +岱宗 1 +x:1 +天山 1 +x:1 +蛋 97 +x:97 +长石 1 +x:1 +花费 1 +x:1 +应声 1 +x:1 +长短 1 +x:1 +小寨沟 1 +x:1 +服务者 1 +x:1 +庄园 1 +x:1 +基础教育 1 +x:1 +小品剧 1 +x:1 +肥城市 1 +x:1 +大衣呢 1 +x:1 +长矛 1 +x:1 +驾驶证 1 +x:1 +竞走 1 +x:1 +神曲 1 +x:1 +睦 3 +x:3 +湘剧院 1 +x:1 +头破血流 1 +x:1 +曲尺 1 +x:1 +太极剑 1 +x:1 +十字街头 1 +x:1 +审结 1 +x:1 +罚单 1 +x:1 +局势 1 +x:1 +行车 1 +x:1 +露才扬己 1 +x:1 +下届 1 +x:1 +明渠 1 +x:1 +体育 1 +x:1 +孔穴 1 +x:1 +等不及 1 +x:1 +带鱼 1 +x:1 +天岭 1 +x:1 +副业 1 +x:1 +神明 1 +x:1 +冻雪 1 +x:1 +冻雨 1 +x:1 +困乏 1 +x:1 +长眠 1 +x:1 +好言好语 1 +x:1 +方寸之地 1 +x:1 +优裕 1 +x:1 +坑坑塘塘 1 +x:1 +棉花 1 +x:1 +完人 1 +x:1 +甭 13 +x:13 +明清 1 +x:1 +开架式 1 +x:1 +宋体 1 +x:1 +原议 1 +x:1 +半壁江山 1 +x:1 +庆祝会 1 +x:1 +溢发 1 +x:1 +河西镇 1 +x:1 +物流 1 +x:1 +别无二致 1 +x:1 +衙内 1 +x:1 +恢宏率意 1 +x:1 +郁郁 1 +x:1 +原话 1 +x:1 +体能 1 +x:1 +挂牌 1 +x:1 +专修点 1 +x:1 +威舍 1 +x:1 +亲眼目睹 1 +x:1 +腌制 1 +x:1 +释名 1 +x:1 +海关法 1 +x:1 +识时务 1 +x:1 +原诉 1 +x:1 +量具 1 +x:1 +放飞关 1 +x:1 +施用 1 +x:1 +批件 1 +x:1 +神智 1 +x:1 +泼洒 1 +x:1 +抱头 1 +x:1 +口舌 1 +x:1 +七国集团 1 +x:1 +精兵简政 1 +x:1 +难以 1 +x:1 +影 52 +x:52 +挂牵 1 +x:1 +新希望党 1 +x:1 +易位 1 +x:1 +招标 1 +x:1 +有穷国 1 +x:1 +自食其言 1 +x:1 +明湖 1 +x:1 +宋代 1 +x:1 +采暖 1 +x:1 +圣保罗 1 +x:1 +安全网 1 +x:1 +当然 1 +x:1 +观察力 1 +x:1 +盲流 1 +x:1 +最轻量级 1 +x:1 +购书点 1 +x:1 +回龙村 1 +x:1 +插花型 1 +x:1 +明澈 1 +x:1 +彭电 1 +x:1 +多云转晴 1 +x:1 +肥 69 +x:69 +被征服者 1 +x:1 +游历 1 +x:1 +缠手 1 +x:1 +仪化 1 +x:1 +运输班 1 +x:1 +审美 1 +x:1 +东却村 1 +x:1 +学潮 1 +x:1 +革命性 1 +x:1 +亲手 1 +x:1 +纸板 1 +x:1 +挑花 1 +x:1 +苏维埃 1 +x:1 +录相 1 +x:1 +长相 1 +x:1 +嫉 1 +x:1 +鳃裂 1 +x:1 +曾几何时 1 +x:1 +肝病 1 +x:1 +孙庄矿 1 +x:1 +重于泰山 1 +x:1 +牙碜 1 +x:1 +贸 18 +x:18 +道院 1 +x:1 +假模假式 1 +x:1 +半夜三更 1 +x:1 +羊齿 1 +x:1 +徒有虚名 1 +x:1 +盐土 1 +x:1 +体腔 1 +x:1 +居住户 1 +x:1 +船速 1 +x:1 +晶 32 +x:32 +借题发挥 1 +x:1 +隋炀帝 1 +x:1 +准入关 1 +x:1 +疝气 1 +x:1 +界面 1 +x:1 +国防 1 +x:1 +饴糖 1 +x:1 +守 145 +x:145 +包乘组 1 +x:1 +笔记 1 +x:1 +文明线 1 +x:1 +量值 1 +x:1 +皮褥子 1 +x:1 +督导员 1 +x:1 +卑躬屈膝 1 +x:1 +蝙蝠 1 +x:1 +阿比让市 1 +x:1 +中师生 1 +x:1 +虚夸 1 +x:1 +槐黄 1 +x:1 +裁判长 1 +x:1 +进水塔 1 +x:1 +盐城 1 +x:1 +万嘱咐 1 +x:1 +长白 1 +x:1 +惠灵顿 1 +x:1 +牢靠 1 +x:1 +执政官 1 +x:1 +分身术 1 +x:1 +井喷 1 +x:1 +子帅 1 +x:1 +行踪 1 +x:1 +临时代办 1 +x:1 +升高 1 +x:1 +郁金 1 +x:1 +笔误 1 +x:1 +革命情 1 +x:1 +宗教观 1 +x:1 +神权 1 +x:1 +锋线 1 +x:1 +卓见 1 +x:1 +熟铁 1 +x:1 +朱色 1 +x:1 +东欧司 1 +x:1 +小胡桃 1 +x:1 +敌骑兵 1 +x:1 +笔试 1 +x:1 +营私 1 +x:1 +养法 1 +x:1 +笔译 1 +x:1 +国际 1 +x:1 +牧工商 1 +x:1 +滚翻 1 +x:1 +采景 1 +x:1 +版次 1 +x:1 +消心痛 1 +x:1 +血红蛋白 1 +x:1 +座位表 1 +x:1 +用兵一时 1 +x:1 +吴江市 1 +x:1 +掌鞭 1 +x:1 +肥肠 1 +x:1 +安道尔 1 +x:1 +动力系 1 +x:1 +王位 1 +x:1 +肥育 1 +x:1 +肥肉 1 +x:1 +丝织品 1 +x:1 +春兰 1 +x:1 +水产局 1 +x:1 +曲剧 1 +x:1 +莺歌燕舞 1 +x:1 +安全灯 1 +x:1 +褶 2 +x:2 +卫生衣 1 +x:1 +新风 1 +x:1 +希望 1 +x:1 +奎文区 1 +x:1 +天分 1 +x:1 +行李房 1 +x:1 +机械业 1 +x:1 +春去秋来 1 +x:1 +杨家乡 1 +x:1 +肺燥 1 +x:1 +相思树 1 +x:1 +养殖学 1 +x:1 +恐 23 +x:23 +鸭绒被 1 +x:1 +督导室 1 +x:1 +物探 1 +x:1 +山海关 1 +x:1 +独门独院 1 +x:1 +居民区 1 +x:1 +新米节 1 +x:1 +不求有功 1 +x:1 +平鲁区 1 +x:1 +竖起 1 +x:1 +肥胖 1 +x:1 +菽 2 +x:2 +煤体 1 +x:1 +振臂一呼 1 +x:1 +亚麻布 1 +x:1 +吃惊 1 +x:1 +庄 128 +x:128 +挑起 1 +x:1 +华章 1 +x:1 +神树 1 +x:1 +复议 1 +x:1 +夏枯草 1 +x:1 +准确度 1 +x:1 +电机系 1 +x:1 +长石岭 1 +x:1 +逛 72 +x:72 +局属 1 +x:1 +冲破 1 +x:1 +斑马线 1 +x:1 +挑战性 1 +x:1 +绥阳县 1 +x:1 +情报部 1 +x:1 +行腔 1 +x:1 +备勤 1 +x:1 +祖父 1 +x:1 +撩开 1 +x:1 +卫生裤 1 +x:1 +空无一人 1 +x:1 +幸福线 1 +x:1 +呈列 1 +x:1 +乏 11 +x:11 +胁从 1 +x:1 +葱郁 1 +x:1 +限值 1 +x:1 +滚热 1 +x:1 +机械人 1 +x:1 +滚烫 1 +x:1 +阿布哈兹 1 +x:1 +船龄 1 +x:1 +侠辣 1 +x:1 +血流如注 1 +x:1 +游乐业 1 +x:1 +危禁品 1 +x:1 +营盘 1 +x:1 +黄山市 1 +x:1 +备加 1 +x:1 +古脊椎 1 +x:1 +狗腿子 1 +x:1 +城东乡 1 +x:1 +急茬 1 +x:1 +帮接工 1 +x:1 +有长有短 1 +x:1 +祖率 1 +x:1 +农民战争 1 +x:1 +量度 1 +x:1 +探戈舞 1 +x:1 +归类 1 +x:1 +经济收益 1 +x:1 +揽客 1 +x:1 +协税 1 +x:1 +肺炎 1 +x:1 +罗湾村 1 +x:1 +成型法 1 +x:1 +典权 1 +x:1 +簌簌 1 +x:1 +拆散 1 +x:1 +军军 1 +x:1 +文学部 1 +x:1 +抱团 1 +x:1 +煤业 1 +x:1 +北师店乡 1 +x:1 +服务车 1 +x:1 +海港区 1 +x:1 +兼职 1 +x:1 +电磁学 1 +x:1 +壁 17 +x:17 +择医 1 +x:1 +苹果园 1 +x:1 +原著 1 +x:1 +花花点子 1 +x:1 +歌 341 +x:341 +天南星 1 +x:1 +阿约 1 +x:1 +蚕茧 1 +x:1 +战友情 1 +x:1 +大头小尾 1 +x:1 +东平湖 1 +x:1 +洗手袋 1 +x:1 +前仆后继 1 +x:1 +机制性 1 +x:1 +天南 1 +x:1 +应城 1 +x:1 +冲积 1 +x:1 +明正典刑 1 +x:1 +备受 1 +x:1 +馆子 1 +x:1 +刺议 1 +x:1 +贵冶 1 +x:1 +进球数 1 +x:1 +火花队 1 +x:1 +贬褒 1 +x:1 +土山 1 +x:1 +亚历山大 1 +x:1 +貌似 1 +x:1 +地图册 1 +x:1 +采样 1 +x:1 +断头 1 +x:1 +不道德 1 +x:1 +旋儿 1 +x:1 +恢复器 1 +x:1 +平平常常 1 +x:1 +择取 1 +x:1 +被打者 1 +x:1 +择友 1 +x:1 +政府法 1 +x:1 +五月 1 +x:1 +案 243 +x:243 +煤井 1 +x:1 +代乳粉 1 +x:1 +户籍地 1 +x:1 +野火 1 +x:1 +明慧 1 +x:1 +多劳多得 1 +x:1 +宁土勿腐 1 +x:1 +杭州 1 +x:1 +浔尾 1 +x:1 +中埠 1 +x:1 +费丹 1 +x:1 +澳方 1 +x:1 +苏联 1 +x:1 +博克兰 1 +x:1 +罗布麻 1 +x:1 +揽存 1 +x:1 +驻华 1 +x:1 +革故鼎新 1 +x:1 +储备局 1 +x:1 +凑集 1 +x:1 +罗平站 1 +x:1 +差异性 1 +x:1 +代市长 1 +x:1 +乌干达 1 +x:1 +双滦区 1 +x:1 +扑通 1 +x:1 +喘嘘嘘 1 +x:1 +牙病 1 +x:1 +溢彩 1 +x:1 +伎 1 +x:1 +一不做 1 +x:1 +冲突 1 +x:1 +聘 61 +x:61 +提出者 1 +x:1 +开门红 1 +x:1 +力 239 +x:239 +苦尽甜来 1 +x:1 +归罪 1 +x:1 +计 236 +x:236 +模拟法 1 +x:1 +猪食 1 +x:1 +座向 1 +x:1 +饼子 1 +x:1 +先行官 1 +x:1 +住宅房 1 +x:1 +没完 1 +x:1 +革命派 1 +x:1 +长途汽车 1 +x:1 +密信 1 +x:1 +建筑界 1 +x:1 +即墨 1 +x:1 +抻 5 +x:5 +中医界 1 +x:1 +施秉 1 +x:1 +牢骚 1 +x:1 +孙中山 1 +x:1 +东月湖 1 +x:1 +百业俱兴 1 +x:1 +巅 14 +x:14 +出版人 1 +x:1 +冷缩 1 +x:1 +主动型 1 +x:1 +建筑用 1 +x:1 +业师 1 +x:1 +防洪法 1 +x:1 +消费权 1 +x:1 +局座 1 +x:1 +起重 1 +x:1 +影调 1 +x:1 +翠鸟 1 +x:1 +煲 2 +x:2 +中队长 1 +x:1 +秀朴 1 +x:1 +平台式 1 +x:1 +长篇 1 +x:1 +牙疳 1 +x:1 +酒逢知己 1 +x:1 +乳牛 1 +x:1 +矿工服 1 +x:1 +物极必反 1 +x:1 +激励力 1 +x:1 +易 273 +x:273 +老头儿 1 +x:1 +金玉其外 1 +x:1 +富莱堡 1 +x:1 +城巴 1 +x:1 +冲程 1 +x:1 +粗粗拉拉 1 +x:1 +汪洋大海 1 +x:1 +长笛 1 +x:1 +顶呱呱 1 +x:1 +马那瓜 1 +x:1 +炮楼 1 +x:1 +密使 1 +x:1 +体貌 1 +x:1 +挡墙 1 +x:1 +诵 9 +x:9 +井壁 1 +x:1 +穿堂儿 1 +x:1 +店里 1 +x:1 +安培计 1 +x:1 +火力圈 1 +x:1 +花棍舞 1 +x:1 +靖江市 1 +x:1 +鸽市 1 +x:1 +肥西县 1 +x:1 +刀法 1 +x:1 +救险 1 +x:1 +横冲直闯 1 +x:1 +农管局 1 +x:1 +拟态 1 +x:1 +作梗 1 +x:1 +思维 1 +x:1 +主渠道 1 +x:1 +定罪 1 +x:1 +如皋市 1 +x:1 +出版业 1 +x:1 +丁字镐 1 +x:1 +实心实意 1 +x:1 +产棉省 1 +x:1 +国魂 1 +x:1 +党员 1 +x:1 +张新矿 1 +x:1 +黄牌警告 1 +x:1 +柔 16 +x:16 +地瓜秧 1 +x:1 +堂 63 +x:63 +耄耋 1 +x:1 +五方 1 +x:1 +击中要害 1 +x:1 +怪不得 1 +x:1 +世族 1 +x:1 +正直者 1 +x:1 +禁酒 1 +x:1 +撕 20 +x:20 +隽语 1 +x:1 +口述 1 +x:1 +救亡运动 1 +x:1 +助力 1 +x:1 +密件 1 +x:1 +神殿 1 +x:1 +急人所急 1 +x:1 +威迫 1 +x:1 +五保 1 +x:1 +典故 1 +x:1 +掸帚 1 +x:1 +鳞爪 1 +x:1 +仪式 1 +x:1 +密令 1 +x:1 +备付金 1 +x:1 +楚人 1 +x:1 +电控柜 1 +x:1 +抹黑 1 +x:1 +合久必分 1 +x:1 +捐助费 1 +x:1 +敬老爱老 1 +x:1 +超水平 1 +x:1 +六镇 1 +x:1 +单一论 1 +x:1 +采 108 +x:108 +升限 1 +x:1 +五时 1 +x:1 +贬词 1 +x:1 +天兵 1 +x:1 +天全 1 +x:1 +拐脖儿 1 +x:1 +主研人 1 +x:1 +给 5485 +x:5485 +升降 1 +x:1 +五日 1 +x:1 +鳞片 1 +x:1 +步行机 1 +x:1 +服务费 1 +x:1 +捞稻草 1 +x:1 +现场会 1 +x:1 +警察部 1 +x:1 +火卫一 1 +x:1 +天光 1 +x:1 +旋涡星云 1 +x:1 +原虫 1 +x:1 +唧唧喳喳 1 +x:1 +天元 1 +x:1 +技校队 1 +x:1 +辈数 1 +x:1 +世故 1 +x:1 +惩罚性 1 +x:1 +深宅大院 1 +x:1 +施教者 1 +x:1 +骆驼镇 1 +x:1 +公雉 1 +x:1 +晋宁县 1 +x:1 +归绥 1 +x:1 +行色 1 +x:1 +版权 1 +x:1 +锈蚀 1 +x:1 +环境署 1 +x:1 +锟 1 +x:1 +日用 1 +x:1 +葡萄糖 1 +x:1 +拿粗挟细 1 +x:1 +执行人 1 +x:1 +归结 1 +x:1 +菜霸 1 +x:1 +爱 960 +x:960 +裤腰带 1 +x:1 +雪溪图 1 +x:1 +昭昭 1 +x:1 +恒量 1 +x:1 +仪征 1 +x:1 +服务路 1 +x:1 +多此一举 1 +x:1 +吃掉 1 +x:1 +长空 1 +x:1 +羚羊 1 +x:1 +归纳 1 +x:1 +一户侯 1 +x:1 +木牌子 1 +x:1 +互联网页 1 +x:1 +半拉子 1 +x:1 +拥塞 1 +x:1 +那务镇 1 +x:1 +物性 1 +x:1 +行船 1 +x:1 +深灰 1 +x:1 +思翼 1 +x:1 +滚珠 1 +x:1 +陪酒 1 +x:1 +哪 343 +x:343 +稽查组 1 +x:1 +夜泊 1 +x:1 +武口 1 +x:1 +呵 46 +x:46 +版本 1 +x:1 +无话可说 1 +x:1 +助剂 1 +x:1 +限产压库 1 +x:1 +喜好 1 +x:1 +一溜烟 1 +x:1 +宝山区 1 +x:1 +功能钮 1 +x:1 +进水口 1 +x:1 +西六乡 1 +x:1 +决胜盘 1 +x:1 +香 143 +x:143 +朝鲜式 1 +x:1 +高歌猛进 1 +x:1 +爱上 1 +x:1 +应力 1 +x:1 +编选者 1 +x:1 +鳞甲 1 +x:1 +笔耕 1 +x:1 +产褥期 1 +x:1 +炳 1 +x:1 +最大者 1 +x:1 +信稿 1 +x:1 +机会 1 +x:1 +特困户 1 +x:1 +笔者 1 +x:1 +当空 1 +x:1 +旋动 1 +x:1 +肺痨 1 +x:1 +阿巴鸟 1 +x:1 +典型性 1 +x:1 +沟灌 1 +x:1 +纺织品 1 +x:1 +迥然不同 1 +x:1 +孚 2 +x:2 +尚集镇 1 +x:1 +书画厅 1 +x:1 +口袋 1 +x:1 +机位 1 +x:1 +水乡村 1 +x:1 +肺病 1 +x:1 +苗头 1 +x:1 +军刀 1 +x:1 +麦金利峰 1 +x:1 +蒲苇片 1 +x:1 +会员录 1 +x:1 +棉衣 1 +x:1 +隔膜感 1 +x:1 +机体 1 +x:1 +农艺师 1 +x:1 +蚕蛹 1 +x:1 +颗 297 +x:297 +洋财 1 +x:1 +各执一词 1 +x:1 +吸铁石 1 +x:1 +神气 1 +x:1 +鸡头梗 1 +x:1 +哀牢山 1 +x:1 +撷拾 1 +x:1 +棉袄 1 +x:1 +魂牵梦萦 1 +x:1 +荣立 1 +x:1 +阀座 1 +x:1 +审理 1 +x:1 +大面积 1 +x:1 +圆笼 1 +x:1 +妮 1 +x:1 +落矶山 1 +x:1 +棉被 1 +x:1 +自由市场 1 +x:1 +大林村 1 +x:1 +苦心经营 1 +x:1 +购置税 1 +x:1 +股票 1 +x:1 +排异性 1 +x:1 +物权 1 +x:1 +黄麻起义 1 +x:1 +讥笑 1 +x:1 +芬花芳蕾 1 +x:1 +西里村 1 +x:1 +机修 1 +x:1 +记叙 1 +x:1 +天国 1 +x:1 +拔地而起 1 +x:1 +华约 1 +x:1 +槎 3 +x:3 +裤腿 1 +x:1 +先导论 1 +x:1 +牟 25 +x:25 +保密法 1 +x:1 +稽查科 1 +x:1 +井底 1 +x:1 +井店 1 +x:1 +配电盘 1 +x:1 +带队 1 +x:1 +蚕蚁 1 +x:1 +棉裤 1 +x:1 +非交易所 1 +x:1 +应县 1 +x:1 +春分 1 +x:1 +明断 1 +x:1 +消费性 1 +x:1 +国际音标 1 +x:1 +美国籍 1 +x:1 +曲坛 1 +x:1 +乐丰村 1 +x:1 +公道 1 +x:1 +局委 1 +x:1 +机主 1 +x:1 +卤水 1 +x:1 +橡皮船 1 +x:1 +杭大 1 +x:1 +机上 1 +x:1 +精加工 1 +x:1 +新野 1 +x:1 +截 37 +x:37 +采油 1 +x:1 +多头管理 1 +x:1 +监示器 1 +x:1 +腰椎骨 1 +x:1 +输油管道 1 +x:1 +南开区 1 +x:1 +隔音墙 1 +x:1 +口角 1 +x:1 +蛮干 1 +x:1 +棉褥 1 +x:1 +明早 1 +x:1 +偃师市 1 +x:1 +溢于言表 1 +x:1 +晕色 1 +x:1 +明日 1 +x:1 +诏 1 +x:1 +公选 1 +x:1 +应召 1 +x:1 +兼营 1 +x:1 +电磁式 1 +x:1 +人心浮动 1 +x:1 +怨尤 1 +x:1 +填海区 1 +x:1 +街垒战 1 +x:1 +冷砸 1 +x:1 +卫生费 1 +x:1 +天坛 1 +x:1 +橡皮艇 1 +x:1 +应变 1 +x:1 +嗝儿 1 +x:1 +会期 1 +x:1 +铱 6 +x:6 +农合工 1 +x:1 +被盗 1 +x:1 +华容镇 1 +x:1 +经验主义 1 +x:1 +盐巴 1 +x:1 +〉 65 +x:65 +避难权 1 +x:1 +服务证 1 +x:1 +为数甚少 1 +x:1 +顶顶 1 +x:1 +户籍卡 1 +x:1 +枯饼 1 +x:1 +驾驶者 1 +x:1 +饮食疗法 1 +x:1 +小姨子 1 +x:1 +镇痛剂 1 +x:1 +油嘴滑舌 1 +x:1 +何谓 1 +x:1 +物质文明 1 +x:1 +梗直 1 +x:1 +挑衅 1 +x:1 +机井 1 +x:1 +永嘉县 1 +x:1 +要命 1 +x:1 +带露 1 +x:1 +行营 1 +x:1 +睿智 1 +x:1 +笔致 1 +x:1 +间接推理 1 +x:1 +菜园子 1 +x:1 +局外 1 +x:1 +机件 1 +x:1 +独立主义 1 +x:1 +春风满面 1 +x:1 +插箭节 1 +x:1 +阐发 1 +x:1 +华美 1 +x:1 +种子公司 1 +x:1 +三星级 1 +x:1 +原胶 1 +x:1 +起降 1 +x:1 +广域网 1 +x:1 +体词 1 +x:1 +一条龙 1 +x:1 +乘务组 1 +x:1 +热核武器 1 +x:1 +水果湖 1 +x:1 +舱体 1 +x:1 +世情 1 +x:1 +寓理于事 1 +x:1 +纲常 1 +x:1 +秀水村 1 +x:1 +憋闷 1 +x:1 +顾问 1 +x:1 +管电员 1 +x:1 +舱位 1 +x:1 +服务行 1 +x:1 +枕边风 1 +x:1 +月费 1 +x:1 +华籍 1 +x:1 +枫桥 1 +x:1 +启蒙运动 1 +x:1 +长方体 1 +x:1 +纫 1 +x:1 +冲线 1 +x:1 +阻滞 1 +x:1 +登机牌 1 +x:1 +机制板 1 +x:1 +寒暄语 1 +x:1 +望天树 1 +x:1 +纪律性 1 +x:1 +曲周 1 +x:1 +庄河 1 +x:1 +观察家 1 +x:1 +长翼 1 +x:1 +深痕 1 +x:1 +营火 1 +x:1 +拿走 1 +x:1 +押车 1 +x:1 +尊重 1 +x:1 +冻鸡 1 +x:1 +体表 1 +x:1 +速冻室 1 +x:1 +雨势 1 +x:1 +打下手 1 +x:1 +物料 1 +x:1 +防倒轮 1 +x:1 +步伐 1 +x:1 +亟须 1 +x:1 +利民之举 1 +x:1 +冲绳 1 +x:1 +电饭煲 1 +x:1 +长翎 1 +x:1 +原子能 1 +x:1 +白皮松 1 +x:1 +秀挺 1 +x:1 +记分 1 +x:1 +掸子 1 +x:1 +超临界 1 +x:1 +战阵 1 +x:1 +焊丝 1 +x:1 +筹措 1 +x:1 +名山事业 1 +x:1 +数易其稿 1 +x:1 +明摆着 1 +x:1 +节衣缩食 1 +x:1 +后八家村 1 +x:1 +夏令 1 +x:1 +夏代 1 +x:1 +笔芯 1 +x:1 +复兴路 1 +x:1 +备品 1 +x:1 +长缨 1 +x:1 +霹雳 1 +x:1 +璜 5 +x:5 +霹雷 1 +x:1 +富国兴邦 1 +x:1 +鸡内金 1 +x:1 +明昌 1 +x:1 +明明 1 +x:1 +长编 1 +x:1 +抱养 1 +x:1 +橡皮膏 1 +x:1 +刀梯 1 +x:1 +断简残编 1 +x:1 +席卷而来 1 +x:1 +明星 1 +x:1 +起锚 1 +x:1 +明晨 1 +x:1 +世态 1 +x:1 +排污者 1 +x:1 +艰苦卓绝 1 +x:1 +虚假 1 +x:1 +农会 1 +x:1 +募兵制 1 +x:1 +神湖 1 +x:1 +菲薄 1 +x:1 +明智 1 +x:1 +大家伙 1 +x:1 +盐度 1 +x:1 +明晰 1 +x:1 +杂事 1 +x:1 +苻 1 +x:1 +战例 1 +x:1 +印花布 1 +x:1 +爷儿俩 1 +x:1 +摧 5 +x:5 +釜山 1 +x:1 +出手 1 +x:1 +长武县 1 +x:1 +十四日 1 +x:1 +城阳区 1 +x:1 +体裁 1 +x:1 +兼融 1 +x:1 +浮山后 1 +x:1 +千红万紫 1 +x:1 +长线 1 +x:1 +饼干 1 +x:1 +口语 1 +x:1 +等值线 1 +x:1 +呼幺喝六 1 +x:1 +秀才 1 +x:1 +锦鳞 1 +x:1 +贬辞 1 +x:1 +歪歪扭扭 1 +x:1 +非金融 1 +x:1 +来宾席 1 +x:1 +酒埠江 1 +x:1 +口说 1 +x:1 +晓君 1 +x:1 +逆水行舟 1 +x:1 +建材业 1 +x:1 +归根到底 1 +x:1 +粳米 1 +x:1 +多方式 1 +x:1 +口诀 1 +x:1 +采收率 1 +x:1 +断裂面 1 +x:1 +极端主义 1 +x:1 +隈 1 +x:1 +口译 1 +x:1 +心功能 1 +x:1 +口试 1 +x:1 +八卦阵 1 +x:1 +勉 7 +x:7 +助困 1 +x:1 +长绳 1 +x:1 +早霜冻 1 +x:1 +红学界 1 +x:1 +饮料厂 1 +x:1 +当票 1 +x:1 +合唱团 1 +x:1 +外经贸 1 +x:1 +农事 1 +x:1 +阵痛期 1 +x:1 +蚕蔟 1 +x:1 +禁锢 1 +x:1 +择 28 +x:28 +怵头 1 +x:1 +机务处 1 +x:1 +农人 1 +x:1 +原色 1 +x:1 +农产 1 +x:1 +锡杖 1 +x:1 +千瓦时 1 +x:1 +不怕累 1 +x:1 +归程 1 +x:1 +屡屡 1 +x:1 +收秋 1 +x:1 +一路上 1 +x:1 +消费报 1 +x:1 +怡悦 1 +x:1 +运钞 1 +x:1 +井巷 1 +x:1 +收割机手 1 +x:1 +局子 1 +x:1 +服务观 1 +x:1 +驾驶舱 1 +x:1 +播种者 1 +x:1 +湖心岛 1 +x:1 +温故求新 1 +x:1 +明月 1 +x:1 +头高头低 1 +x:1 +推 253 +x:253 +国鸟 1 +x:1 +阵脚 1 +x:1 +禁闭 1 +x:1 +成材林 1 +x:1 +明朝 1 +x:1 +文学院 1 +x:1 +中青旅 1 +x:1 +炉瓦 1 +x:1 +挑战权 1 +x:1 +速生蝎 1 +x:1 +农专 1 +x:1 +农业 1 +x:1 +拔河 1 +x:1 +穹 4 +x:4 +大权独揽 1 +x:1 +绣房 1 +x:1 +纵令 1 +x:1 +飚 6 +x:6 +肺癌 1 +x:1 +爷儿们 1 +x:1 +谈判桌 1 +x:1 +筹拍 1 +x:1 +孝女 1 +x:1 +农丰 1 +x:1 +幽愤 1 +x:1 +十二分 1 +x:1 +房地产部 1 +x:1 +中国画理 1 +x:1 +地区 1 +x:1 +贝尔蒙 1 +x:1 +折扣票 1 +x:1 +应允 1 +x:1 +强的松 1 +x:1 +调职 1 +x:1 +鸽子笼 1 +x:1 +鼓励奖 1 +x:1 +采写 1 +x:1 +一箭之地 1 +x:1 +弹拨乐 1 +x:1 +治保会 1 +x:1 +资料费 1 +x:1 +增长 1 +x:1 +孟什维克 1 +x:1 +结膜 1 +x:1 +建筑体 1 +x:1 +平箩 1 +x:1 +师资 1 +x:1 +仅仅只 1 +x:1 +斜面 1 +x:1 +癔病 1 +x:1 +信报箱 1 +x:1 +常太镇 1 +x:1 +五建 1 +x:1 +巡航导弹 1 +x:1 +建造 1 +x:1 +显贵 1 +x:1 +视导员 1 +x:1 +铁面 1 +x:1 +曲轴箱 1 +x:1 +峭拔冷峻 1 +x:1 +烫洗店 1 +x:1 +神像 1 +x:1 +捐款箱 1 +x:1 +揽括 1 +x:1 +大屯村 1 +x:1 +厌弃 1 +x:1 +铣 2 +x:2 +频哪酮 1 +x:1 +汴水 1 +x:1 +罪 148 +x:148 +衰 20 +x:20 +聋子 1 +x:1 +雪白 1 +x:1 +犹疑 1 +x:1 +汤田中 1 +x:1 +废除 1 +x:1 +建部 1 +x:1 +五常 1 +x:1 +环视 1 +x:1 +貌似公正 1 +x:1 +即或 1 +x:1 +建都 1 +x:1 +五带 1 +x:1 +骨坏死 1 +x:1 +丰润县 1 +x:1 +模拟器 1 +x:1 +五帝 1 +x:1 +飘移 1 +x:1 +机率 1 +x:1 +平西府 1 +x:1 +结脉 1 +x:1 +宋祖 1 +x:1 +中和 1 +x:1 +经济部长 1 +x:1 +壁纸 1 +x:1 +量杯 1 +x:1 +岫山村 1 +x:1 +保健品厂 1 +x:1 +通缉 1 +x:1 +吹毛求疵 1 +x:1 +磁县都 1 +x:1 +瑶 17 +x:17 +丙寅 1 +x:1 +木讷 1 +x:1 +夙仇 1 +x:1 +阻值 1 +x:1 +煤矿 1 +x:1 +平等 1 +x:1 +自由词 1 +x:1 +摹山范水 1 +x:1 +采光 1 +x:1 +臀疣 1 +x:1 +密电 1 +x:1 +狗吠 1 +x:1 +不孕籽 1 +x:1 +镜头感 1 +x:1 +湖光塔影 1 +x:1 +汴河 1 +x:1 +鹤峰县 1 +x:1 +穷根究底 1 +x:1 +养殖户 1 +x:1 +环行 1 +x:1 +神农 1 +x:1 +五连冠 1 +x:1 +阻击 1 +x:1 +生还者 1 +x:1 +醋 12 +x:12 +攻其不备 1 +x:1 +通络 1 +x:1 +取笑 1 +x:1 +磁鼓 1 +x:1 +仓储 1 +x:1 +民盟 1 +x:1 +特拉维夫 1 +x:1 +隐身 1 +x:1 +结肠 1 +x:1 +吃零食 1 +x:1 +由此可知 1 +x:1 +兰西 1 +x:1 +拔剑 1 +x:1 +捐款站 1 +x:1 +高级神经 1 +x:1 +铁道部长 1 +x:1 +五律 1 +x:1 +风行草偃 1 +x:1 +典当 1 +x:1 +懒觉 1 +x:1 +棒状 1 +x:1 +木煤气 1 +x:1 +划一不二 1 +x:1 +次生林 1 +x:1 +通纂 1 +x:1 +信教 1 +x:1 +柬王国 1 +x:1 +变形虫 1 +x:1 +自由诗 1 +x:1 +迟 376 +x:376 +在天有灵 1 +x:1 +消费层 1 +x:1 +新坝镇 1 +x:1 +感闻 1 +x:1 +勘误 1 +x:1 +野葡萄 1 +x:1 +通约 1 +x:1 +毁灭 1 +x:1 +通红 1 +x:1 +淳 4 +x:4 +痛哭 1 +x:1 +永世长存 1 +x:1 +一级品 1 +x:1 +软和 1 +x:1 +局方 1 +x:1 +电排站 1 +x:1 +小品文 1 +x:1 +明天 1 +x:1 +澳州 1 +x:1 +黄山松 1 +x:1 +园后 1 +x:1 +寿辰 1 +x:1 +寿诞 1 +x:1 +昭通市 1 +x:1 +梦语 1 +x:1 +张湾镇 1 +x:1 +冠 56 +x:56 +载重量 1 +x:1 +神儿 1 +x:1 +平稳 1 +x:1 +贵会 1 +x:1 +明处 1 +x:1 +梦话 1 +x:1 +年年岁岁 1 +x:1 +乒乓球 1 +x:1 +调入地 1 +x:1 +吹 203 +x:203 +探寻 1 +x:1 +出版界 1 +x:1 +不置可否 1 +x:1 +臀 1 +x:1 +太仓市 1 +x:1 +怀想 1 +x:1 +承包权 1 +x:1 +装检团 1 +x:1 +不见经传 1 +x:1 +场内外 1 +x:1 +凉风 1 +x:1 +户拥有率 1 +x:1 +新浦区 1 +x:1 +万木争翠 1 +x:1 +十六中 1 +x:1 +善良 1 +x:1 +大世界 1 +x:1 +贩运 1 +x:1 +扭 36 +x:36 +铁姑娘 1 +x:1 +天母 1 +x:1 +决议 1 +x:1 +红薯面 1 +x:1 +学以致用 1 +x:1 +限产 1 +x:1 +取码 1 +x:1 +虽然 1 +x:1 +神功 1 +x:1 +机焦 1 +x:1 +五岳 1 +x:1 +表面 1 +x:1 +明媒正娶 1 +x:1 +掌握者 1 +x:1 +衮州 1 +x:1 +倾销地 1 +x:1 +煤田 1 +x:1 +备案 1 +x:1 +日见增多 1 +x:1 +居民楼 1 +x:1 +浑然不知 1 +x:1 +十四大 1 +x:1 +明媚 1 +x:1 +白干儿 1 +x:1 +奖惩制 1 +x:1 +结莎 1 +x:1 +不成文法 1 +x:1 +小关路口 1 +x:1 +调色 1 +x:1 +涵盖面 1 +x:1 +模式论 1 +x:1 +主页 1 +x:1 +采取 1 +x:1 +旅 185 +x:185 +江华县 1 +x:1 +么 34 +x:34 +困窘 1 +x:1 +指头 1 +x:1 +可供热率 1 +x:1 +聋女 1 +x:1 +开罗 1 +x:1 +虞城 1 +x:1 +天桥 1 +x:1 +神勇 1 +x:1 +平移 1 +x:1 +暂且 1 +x:1 +开罪 1 +x:1 +板角 1 +x:1 +酸碱度 1 +x:1 +变样 1 +x:1 +泼妇 1 +x:1 +小家鼠 1 +x:1 +居住地 1 +x:1 +水化物 1 +x:1 +世局 1 +x:1 +花明楼镇 1 +x:1 +定性 1 +x:1 +世居 1 +x:1 +园圃 1 +x:1 +世风日下 1 +x:1 +蓝剑队 1 +x:1 +新郑 1 +x:1 +天梯 1 +x:1 +紧追权 1 +x:1 +决裂 1 +x:1 +总府 1 +x:1 +峰顶 1 +x:1 +英国式 1 +x:1 +扬眉万里 1 +x:1 +计生办 1 +x:1 +采区 1 +x:1 +共计 1 +x:1 +五小 1 +x:1 +参加者 1 +x:1 +园地 1 +x:1 +一府两院 1 +x:1 +废钢 1 +x:1 +路经 1 +x:1 +牛仔服 1 +x:1 +废铜 1 +x:1 +母子团 1 +x:1 +冰糖葫芦 1 +x:1 +共诛 1 +x:1 +姨母 1 +x:1 +共话 1 +x:1 +隔音板 1 +x:1 +养鹿场 1 +x:1 +曲梁 1 +x:1 +共识 1 +x:1 +助正 1 +x:1 +盒子枪 1 +x:1 +释怀 1 +x:1 +立陶宛 1 +x:1 +废铁 1 +x:1 +结荚 1 +x:1 +天棚 1 +x:1 +仓卒 1 +x:1 +诡辩式 1 +x:1 +仓单 1 +x:1 +物外 1 +x:1 +新人王 1 +x:1 +一文不名 1 +x:1 +怂 1 +x:1 +保障性 1 +x:1 +采办 1 +x:1 +操控 1 +x:1 +耿饼 1 +x:1 +个人化 1 +x:1 +版心 1 +x:1 +村公所 1 +x:1 +八宿县 1 +x:1 +整齐划一 1 +x:1 +盲女 1 +x:1 +自强不息 1 +x:1 +嗜砚者 1 +x:1 +煤球 1 +x:1 +希少 1 +x:1 +结节 1 +x:1 +豪商巨贾 1 +x:1 +肖像画 1 +x:1 +风卷残云 1 +x:1 +聂 84 +x:84 +神户市 1 +x:1 +毁版 1 +x:1 +肠骨 1 +x:1 +孺子可数 1 +x:1 +调控者 1 +x:1 +评议票 1 +x:1 +初赛 1 +x:1 +别有见地 1 +x:1 +拉动型 1 +x:1 +铱星 1 +x:1 +北京路 1 +x:1 +裙带菜 1 +x:1 +机灵 1 +x:1 +王公 1 +x:1 +恪信 1 +x:1 +路网 1 +x:1 +咨文 1 +x:1 +神台 1 +x:1 +耐人玩味 1 +x:1 +赴 607 +x:607 +园囿 1 +x:1 +藤 14 +x:14 +元/户 1 +x:1 +光芒四射 1 +x:1 +机炮 1 +x:1 +腕骨 1 +x:1 +加油量 1 +x:1 +依此类推 1 +x:1 +善者 1 +x:1 +脊神经 1 +x:1 +神化 1 +x:1 +高架道路 1 +x:1 +顶视图 1 +x:1 +缄口结舌 1 +x:1 +雄图 1 +x:1 +巨龙头 1 +x:1 +拷纱 1 +x:1 +丝光布 1 +x:1 +神医 1 +x:1 +筹委会 1 +x:1 +饭店业 1 +x:1 +没戏 1 +x:1 +梦见 1 +x:1 +脏话 1 +x:1 +松散层 1 +x:1 +曼苏里 1 +x:1 +权 359 +x:359 +秘籍 1 +x:1 +经济账 1 +x:1 +救治金 1 +x:1 +肺脓肿 1 +x:1 +微结构 1 +x:1 +损兵折将 1 +x:1 +肝炎病 1 +x:1 +约贝州 1 +x:1 +筹建 1 +x:1 +佃租 1 +x:1 +版式 1 +x:1 +释愁 1 +x:1 +直通式 1 +x:1 +拷绸 1 +x:1 +尚俭去奢 1 +x:1 +雾岚 1 +x:1 +样稿 1 +x:1 +轮盘 1 +x:1 +娇娆 1 +x:1 +接修部 1 +x:1 +翼 15 +x:15 +有的是 1 +x:1 +银耳 1 +x:1 +棱柱体 1 +x:1 +渔农业 1 +x:1 +绣帕 1 +x:1 +园内 1 +x:1 +刀刃 1 +x:1 +革命化 1 +x:1 +中青年 1 +x:1 +炉体 1 +x:1 +通篇 1 +x:1 +标准公顷 1 +x:1 +摇鹅毛扇 1 +x:1 +在编 1 +x:1 +2 1688 +x:1688 +木轮 1 +x:1 +跋山涉水 1 +x:1 +木车 1 +x:1 +驾驭力 1 +x:1 +香芋丝 1 +x:1 +捐钱者 1 +x:1 +昏头转向 1 +x:1 +拟建 1 +x:1 +盲干 1 +x:1 +祖产 1 +x:1 +苍穹 1 +x:1 +筹备 1 +x:1 +秀女 1 +x:1 +碾碎 1 +x:1 +丝绸之路 1 +x:1 +督考团 1 +x:1 +仪态 1 +x:1 +荧光 1 +x:1 +存包处 1 +x:1 +佚文 1 +x:1 +舷 2 +x:2 +阿布贾 1 +x:1 +蔬菜局 1 +x:1 +勾通 1 +x:1 +五星级 1 +x:1 +锡山 1 +x:1 +白日梦 1 +x:1 +刀山剑林 1 +x:1 +编织业 1 +x:1 +神品 1 +x:1 +蹦迪 1 +x:1 +隐语 1 +x:1 +麻店村 1 +x:1 +兰谱 1 +x:1 +智能 1 +x:1 +事故率 1 +x:1 +开票 1 +x:1 +涤瑕荡秽 1 +x:1 +面如土色 1 +x:1 +深信 1 +x:1 +报晓 1 +x:1 +派出所长 1 +x:1 +五嫂 1 +x:1 +迸发 1 +x:1 +开禁 1 +x:1 +横祸 1 +x:1 +喉擦音 1 +x:1 +平缓 1 +x:1 +东平县 1 +x:1 +农畜 1 +x:1 +调蓄 1 +x:1 +南蛮子 1 +x:1 +参 51 +x:51 +长幼有序 1 +x:1 +没收 1 +x:1 +抱歉 1 +x:1 +祖业 1 +x:1 +酪素 1 +x:1 +路碑 1 +x:1 +环路 1 +x:1 +半遮半掩 1 +x:1 +俄亥俄州 1 +x:1 +抢断王 1 +x:1 +些微 1 +x:1 +中唱 1 +x:1 +环跳 1 +x:1 +首发式 1 +x:1 +评定证 1 +x:1 +滔滔不绝 1 +x:1 +钼矿 1 +x:1 +壁立 1 +x:1 +公告书 1 +x:1 +舒坦 1 +x:1 +港湾式 1 +x:1 +中文机 1 +x:1 +板车 1 +x:1 +边带 1 +x:1 +汴梁 1 +x:1 +评议组 1 +x:1 +革命史 1 +x:1 +针头线脑 1 +x:1 +农田 1 +x:1 +磨 65 +x:65 +素馨花 1 +x:1 +杨柳风 1 +x:1 +警世之作 1 +x:1 +感情用事 1 +x:1 +漂离 1 +x:1 +情节化 1 +x:1 +即景 1 +x:1 +雪里红 1 +x:1 +油母页岩 1 +x:1 +民政办 1 +x:1 +政府军 1 +x:1 +筹委 1 +x:1 +农用 1 +x:1 +深井 1 +x:1 +樊 59 +x:59 +学习日 1 +x:1 +至上 1 +x:1 +渔鼓词 1 +x:1 +取缔 1 +x:1 +共谋 1 +x:1 +尼龙 1 +x:1 +马尔凯 1 +x:1 +胡麻 1 +x:1 +互励 1 +x:1 +脸颊 1 +x:1 +至为 1 +x:1 +平纹 1 +x:1 +美发店 1 +x:1 +五官 1 +x:1 +人事厅 1 +x:1 +群山起伏 1 +x:1 +打假保真 1 +x:1 +深交 1 +x:1 +天漏 1 +x:1 +案语 1 +x:1 +圣埃蒂安 1 +x:1 +教练组 1 +x:1 +贝加尔湖 1 +x:1 +叶鞘 1 +x:1 +月城镇 1 +x:1 +层报 1 +x:1 +平绒 1 +x:1 +培养费 1 +x:1 +直瞪瞪 1 +x:1 +唐家会村 1 +x:1 +撩拨 1 +x:1 +荣归故里 1 +x:1 +立案庭 1 +x:1 +西里西亚 1 +x:1 +卤味 1 +x:1 +挡板 1 +x:1 +阴暗处 1 +x:1 +聋哑人 1 +x:1 +批办制 1 +x:1 +孤芳自赏 1 +x:1 +澳头 1 +x:1 +连衣裙 1 +x:1 +明州 1 +x:1 +纸筒 1 +x:1 +茶陵县 1 +x:1 +即期 1 +x:1 +汛情 1 +x:1 +带状林 1 +x:1 +送气量 1 +x:1 +复谈 1 +x:1 +罚款率 1 +x:1 +至于 1 +x:1 +进修部 1 +x:1 +纸箱 1 +x:1 +彩色片 1 +x:1 +阴毒 1 +x:1 +东河南镇 1 +x:1 +楠竹 1 +x:1 +助民 1 +x:1 +老婆子 1 +x:1 +玛滩镇 1 +x:1 +莱西 1 +x:1 +资金户 1 +x:1 +理念层 1 +x:1 +枫叶 1 +x:1 +美发师 1 +x:1 +增值 1 +x:1 +深中 1 +x:1 +纸箔 1 +x:1 +至交 1 +x:1 +初试 1 +x:1 +不多时 1 +x:1 +回马枪 1 +x:1 +遛弯儿 1 +x:1 +开磅 1 +x:1 +声韵学 1 +x:1 +刀叉 1 +x:1 +血亏 1 +x:1 +初评 1 +x:1 +初识 1 +x:1 +临沭 1 +x:1 +涵养区 1 +x:1 +蹦蹦 1 +x:1 +转眼间 1 +x:1 +肖厝 1 +x:1 +初诊 1 +x:1 +刀口 1 +x:1 +民政厅 1 +x:1 +地矿部 1 +x:1 +南安普敦 1 +x:1 +衬垫 1 +x:1 +队形 1 +x:1 +秦风 1 +x:1 +纸篓 1 +x:1 +总局长 1 +x:1 +直属处 1 +x:1 +压卷之作 1 +x:1 +路程 1 +x:1 +楚王 1 +x:1 +骶骨 1 +x:1 +挚情 1 +x:1 +曲江 1 +x:1 +枯叶蛾 1 +x:1 +天水 1 +x:1 +乱送 1 +x:1 +橡胶板 1 +x:1 +剑戟 1 +x:1 +对局 1 +x:1 +机电 1 +x:1 +凌厉感 1 +x:1 +崇文门 1 +x:1 +毁真 1 +x:1 +酸软 1 +x:1 +纽结 1 +x:1 +天气 1 +x:1 +辱 9 +x:9 +商业部 1 +x:1 +曲池 1 +x:1 +爸 22 +x:22 +问长问短 1 +x:1 +唬人 1 +x:1 +滂沱大雨 1 +x:1 +拉动力 1 +x:1 +天汽 1 +x:1 +江湖骗子 1 +x:1 +金盏花 1 +x:1 +革命党 1 +x:1 +复印社 1 +x:1 +镰刀 1 +x:1 +纽约 1 +x:1 +审价 1 +x:1 +天池 1 +x:1 +问候信 1 +x:1 +寿衣 1 +x:1 +曲水 1 +x:1 +希奇 1 +x:1 +初衷 1 +x:1 +定向天线 1 +x:1 +飞潜动植 1 +x:1 +大小便 1 +x:1 +惯 58 +x:58 +雷庄村 1 +x:1 +余姚 1 +x:1 +笤帚 1 +x:1 +秤盘 1 +x:1 +滚滚圆 1 +x:1 +装车 1 +x:1 +钩儿 1 +x:1 +门类 1 +x:1 +避难层 1 +x:1 +子实 1 +x:1 +革命军 1 +x:1 +笔记本 1 +x:1 +勤杂人员 1 +x:1 +纪念辑 1 +x:1 +扎达县 1 +x:1 +出版物 1 +x:1 +浮夸风 1 +x:1 +州里 1 +x:1 +装潢业 1 +x:1 +植胶 1 +x:1 +装载 1 +x:1 +通票 1 +x:1 +正向 1 +x:1 +天沟 1 +x:1 +没有 1 +x:1 +饥饿感 1 +x:1 +精囊 1 +x:1 +有偿性 1 +x:1 +免战牌 1 +x:1 +开箱 1 +x:1 +自动化所 1 +x:1 +忽而 1 +x:1 +夏盔 1 +x:1 +个头 1 +x:1 +扩资 1 +x:1 +抱残守缺 1 +x:1 +备注 1 +x:1 +开篇 1 +x:1 +汇 98 +x:98 +原棉 1 +x:1 +太极拳 1 +x:1 +槌 3 +x:3 +货币量 1 +x:1 +忧患与共 1 +x:1 +敌阵 1 +x:1 +彼岸 1 +x:1 +庄员 1 +x:1 +稗子 1 +x:1 +天波 1 +x:1 +明年 1 +x:1 +路端 1 +x:1 +垂丝柳 1 +x:1 +惊喜交集 1 +x:1 +自封 1 +x:1 +横笛 1 +x:1 +女色 1 +x:1 +百卉吐艳 1 +x:1 +拟就 1 +x:1 +神器 1 +x:1 +斜拉桥 1 +x:1 +歹话 1 +x:1 +断然 1 +x:1 +皇宫戏 1 +x:1 +新穴 1 +x:1 +病理性 1 +x:1 +辉腾锡勒 1 +x:1 +决赛 1 +x:1 +流沙量 1 +x:1 +赔偿 1 +x:1 +丁零声 1 +x:1 +支前 1 +x:1 +邦长 1 +x:1 +星夜 1 +x:1 +神经质 1 +x:1 +斗 67 +x:67 +外交大臣 1 +x:1 +天津 1 +x:1 +科摩罗 1 +x:1 +钓友 1 +x:1 +隔膜 1 +x:1 +渔歌唱晚 1 +x:1 +艾绒 1 +x:1 +职员会 1 +x:1 +机管局 1 +x:1 +一文不值 1 +x:1 +一番 1 +x:1 +自作主张 1 +x:1 +麻利儿 1 +x:1 +红人 1 +x:1 +喷 32 +x:32 +医卫组 1 +x:1 +绳索 1 +x:1 +移师 1 +x:1 +木豆 1 +x:1 +刀儿 1 +x:1 +误区 1 +x:1 +纸票 1 +x:1 +明快 1 +x:1 +休闲化 1 +x:1 +煤火 1 +x:1 +整险 1 +x:1 +夏眠 1 +x:1 +悍然 1 +x:1 +香水梨 1 +x:1 +晖 48 +x:48 +流水线 1 +x:1 +释文 1 +x:1 +湖泗乡 1 +x:1 +煤灰 1 +x:1 +犬牙 1 +x:1 +牡技 1 +x:1 +水准仪 1 +x:1 +嫩 13 +x:13 +五委 1 +x:1 +下巴颏儿 1 +x:1 +即时 1 +x:1 +输尿管 1 +x:1 +副翼 1 +x:1 +刀具 1 +x:1 +刀兵 1 +x:1 +翻 258 +x:258 +即日 1 +x:1 +登山队员 1 +x:1 +煤炭 1 +x:1 +胞兄弟 1 +x:1 +舱盖 1 +x:1 +加扎省 1 +x:1 +楚汉相争 1 +x:1 +软骨素 1 +x:1 +开窍 1 +x:1 +开窗 1 +x:1 +天涯 1 +x:1 +五大 1 +x:1 +大包大揽 1 +x:1 +阿比让港 1 +x:1 +捆绑式 1 +x:1 +蓄水量 1 +x:1 +国际裁判 1 +x:1 +煤炉 1 +x:1 +法制 1 +x:1 +灞水 1 +x:1 +江油市 1 +x:1 +脯 1 +x:1 +功名榜 1 +x:1 +行乞业 1 +x:1 +东洋车 1 +x:1 +神圣 1 +x:1 +二流子 1 +x:1 +蛇形 1 +x:1 +怀柔县 1 +x:1 +海鲜楼 1 +x:1 +神坛 1 +x:1 +大中小 1 +x:1 +隐衷 1 +x:1 +观察所 1 +x:1 +诈 6 +x:6 +主人公 1 +x:1 +不谙世事 1 +x:1 +华池村 1 +x:1 +原索动物 1 +x:1 +鸡飞蛋打 1 +x:1 +初见 1 +x:1 +吏人 1 +x:1 +乱采 1 +x:1 +秀媚 1 +x:1 +血书 1 +x:1 +陡 34 +x:34 +释放 1 +x:1 +大村镇 1 +x:1 +开端 1 +x:1 +话数站 1 +x:1 +煤烟 1 +x:1 +隐血 1 +x:1 +昨天 1 +x:1 +初解 1 +x:1 +棒球 1 +x:1 +晨练 1 +x:1 +刀凿 1 +x:1 +刀币 1 +x:1 +剪纸 1 +x:1 +农科 1 +x:1 +中南区 1 +x:1 +十二日 1 +x:1 +【 2 +x:2 +十字街村 1 +x:1 +披垂感 1 +x:1 +当中 1 +x:1 +缩头缩脑 1 +x:1 +十二时 1 +x:1 +舜 1 +x:1 +黑沉沉 1 +x:1 +魔术队 1 +x:1 +天成 1 +x:1 +当世 1 +x:1 +多数党 1 +x:1 +当下 1 +x:1 +月弯街 1 +x:1 +腌法 1 +x:1 +穷家富路 1 +x:1 +激励性 1 +x:1 +一助一 1 +x:1 +侮辱 1 +x:1 +扬眉捋须 1 +x:1 +阐明 1 +x:1 +央告 1 +x:1 +善诈 1 +x:1 +分期付款 1 +x:1 +不可靠性 1 +x:1 +疰夏 1 +x:1 +僧人 1 +x:1 +备战 1 +x:1 +伴郎 1 +x:1 +兰考 1 +x:1 +世态百味 1 +x:1 +农丰里 1 +x:1 +哈雷彗星 1 +x:1 +位列前茅 1 +x:1 +干冰 1 +x:1 +澳联社 1 +x:1 +狗岛 1 +x:1 +农民协会 1 +x:1 +宝山村 1 +x:1 +虎啸 1 +x:1 +冬作物 1 +x:1 +阉人 1 +x:1 +叹词 1 +x:1 +五四 1 +x:1 +草鸡蛋 1 +x:1 +市编委 1 +x:1 +弯度 1 +x:1 +货运 1 +x:1 +国产化率 1 +x:1 +油基 1 +x:1 +稳步前进 1 +x:1 +稳健 1 +x:1 +黄巢起义 1 +x:1 +宾 4 +x:4 +催吐剂 1 +x:1 +呈报 1 +x:1 +鞭炮 1 +x:1 +养蝎场 1 +x:1 +银蝶 1 +x:1 +狗屁 1 +x:1 +铁丝网 1 +x:1 +创业维艰 1 +x:1 +秤砣 1 +x:1 +同屋 1 +x:1 +荣任 1 +x:1 +排气型 1 +x:1 +为时过晚 1 +x:1 +目无国法 1 +x:1 +神堂 1 +x:1 +阿佤 1 +x:1 +机箱 1 +x:1 +分赛场 1 +x:1 +废麻 1 +x:1 +大快人心 1 +x:1 +同声相应 1 +x:1 +乱麻 1 +x:1 +阻塞 1 +x:1 +浅析 1 +x:1 +当事 1 +x:1 +出色 1 +x:1 +建井处 1 +x:1 +石羊河 1 +x:1 +拦网奖 1 +x:1 +一部分 1 +x:1 +疾 7 +x:7 +屡次 1 +x:1 +废黜 1 +x:1 +木莲 1 +x:1 +曲折 1 +x:1 +心浮气动 1 +x:1 +应景 1 +x:1 +舒城县 1 +x:1 +候机者 1 +x:1 +肖店 1 +x:1 +当代 1 +x:1 +落汤鸡 1 +x:1 +三桥村 1 +x:1 +拟制 1 +x:1 +赫然而怒 1 +x:1 +物化 1 +x:1 +当今 1 +x:1 +作业点 1 +x:1 +缓降器 1 +x:1 +纸盒 1 +x:1 +胳肢窝儿 1 +x:1 +盲动 1 +x:1 +阿 1 +x:1 +开球 1 +x:1 +安民告示 1 +x:1 +虚构 1 +x:1 +馋 14 +x:14 +衬字 1 +x:1 +通盘 1 +x:1 +小铲 1 +x:1 +车头 1 +x:1 +购书人 1 +x:1 +业 140 +x:140 +源流同清 1 +x:1 +总量性 1 +x:1 +僧俗 1 +x:1 +政论 1 +x:1 +肖形 1 +x:1 +屋子 1 +x:1 +支教 1 +x:1 +女足 1 +x:1 +绣品 1 +x:1 +百分之百 1 +x:1 +当众 1 +x:1 +拍案而起 1 +x:1 +一吐为快 1 +x:1 +荧屏 1 +x:1 +路由 1 +x:1 +木船 1 +x:1 +葡萄串 1 +x:1 +共聚 1 +x:1 +秋田县 1 +x:1 +锡兰 1 +x:1 +不孕症 1 +x:1 +拟压 1 +x:1 +以观后效 1 +x:1 +巴拉丁山 1 +x:1 +枭雄 1 +x:1 +观察法 1 +x:1 +田字草 1 +x:1 +曲高和众 1 +x:1 +变温层 1 +x:1 +杨柳镇 1 +x:1 +当作 1 +x:1 +佳妙无双 1 +x:1 +盘中餐 1 +x:1 +居民户 1 +x:1 +生命力者 1 +x:1 +人造石油 1 +x:1 +智者 1 +x:1 +分洪道 1 +x:1 +有名有实 1 +x:1 +忠奸分明 1 +x:1 +大小凉山 1 +x:1 +白云石 1 +x:1 +踅 1 +x:1 +女贞 1 +x:1 +柳叶眉 1 +x:1 +善言 1 +x:1 +北郊区 1 +x:1 +明儿 1 +x:1 +发包方 1 +x:1 +办证 1 +x:1 +唯利唯金 1 +x:1 +微词 1 +x:1 +夏种 1 +x:1 +共育 1 +x:1 +湮灭 1 +x:1 +调解 1 +x:1 +挂号费 1 +x:1 +蜜饯 1 +x:1 +肠道 1 +x:1 +塔西南 1 +x:1 +公信力 1 +x:1 +尹 163 +x:163 +商业 1 +x:1 +总医院 1 +x:1 +园居 1 +x:1 +农研 1 +x:1 +检查门 1 +x:1 +横琴 1 +x:1 +败血症 1 +x:1 +败血病 1 +x:1 +销售科 1 +x:1 +鹅黄色 1 +x:1 +有感而发 1 +x:1 +平版 1 +x:1 +希图 1 +x:1 +摇摆舞 1 +x:1 +王子型 1 +x:1 +弯弓 1 +x:1 +积金 1 +x:1 +神奇 1 +x:1 +淘粪者 1 +x:1 +典型 1 +x:1 +不失时机 1 +x:1 +计生委 1 +x:1 +增储上产 1 +x:1 +大安山乡 1 +x:1 +神女 1 +x:1 +巴伦西亚 1 +x:1 +针针 1 +x:1 +冠状动脉 1 +x:1 +社里 1 +x:1 +弃权票 1 +x:1 +播洒 1 +x:1 +开云见日 1 +x:1 +模拟式 1 +x:1 +狗崽 1 +x:1 +舒婉 1 +x:1 +结论 1 +x:1 +仓容 1 +x:1 +欠缺型 1 +x:1 +通病 1 +x:1 +期终 1 +x:1 +缎 2 +x:2 +御花园 1 +x:1 +布雷 1 +x:1 +刀尖 1 +x:1 +限作 1 +x:1 +抛 97 +x:97 +聋儿 1 +x:1 +天性 1 +x:1 +吃剩 1 +x:1 +版图 1 +x:1 +招法 1 +x:1 +蔽体 1 +x:1 +民政局 1 +x:1 +感性认识 1 +x:1 +思想史 1 +x:1 +周三 1 +x:1 +淋漓尽致 1 +x:1 +海堤围 1 +x:1 +享受期 1 +x:1 +操作者 1 +x:1 +归位 1 +x:1 +不唯书 1 +x:1 +开眼 1 +x:1 +详文 1 +x:1 +贾鲁河 1 +x:1 +花棚 1 +x:1 +白鹿原 1 +x:1 +繁殖场 1 +x:1 +繁殖地 1 +x:1 +国家税 1 +x:1 +浪花 1 +x:1 +不唯上 1 +x:1 +自修 1 +x:1 +创编者 1 +x:1 +结语 1 +x:1 +网球手 1 +x:1 +电容器 1 +x:1 +苛 1 +x:1 +机制化 1 +x:1 +啦啦队 1 +x:1 +工 137 +x:137 +提笔 1 +x:1 +东便门 1 +x:1 +善解 1 +x:1 +胜芳镇 1 +x:1 +挂件 1 +x:1 +嫉贤妒能 1 +x:1 +墨尔本市 1 +x:1 +银白杨 1 +x:1 +艳史 1 +x:1 +结识 1 +x:1 +挂任 1 +x:1 +中低产田 1 +x:1 +决胜 1 +x:1 +植胶国 1 +x:1 +磁针 1 +x:1 +年光 1 +x:1 +盛赞 1 +x:1 +隐蔽 1 +x:1 +防不胜防 1 +x:1 +饕餮 1 +x:1 +军命 1 +x:1 +支取 1 +x:1 +神威 1 +x:1 +年兄 1 +x:1 +平平齐齐 1 +x:1 +扭亏解困 1 +x:1 +机械系 1 +x:1 +磁钢 1 +x:1 +双眼皮 1 +x:1 +思亲 1 +x:1 +互质数 1 +x:1 +消费型 1 +x:1 +工作部 1 +x:1 +一晃儿 1 +x:1 +三都镇 1 +x:1 +救世军 1 +x:1 +土砖房 1 +x:1 +亢进 1 +x:1 +磁铁 1 +x:1 +体能型 1 +x:1 +狗市 1 +x:1 +复员费 1 +x:1 +脸面 1 +x:1 +经作站 1 +x:1 +五味 1 +x:1 +大子儿 1 +x:1 +吃力 1 +x:1 +金绿 1 +x:1 +归侨 1 +x:1 +扣篮王 1 +x:1 +网球拍 1 +x:1 +燃动局 1 +x:1 +机种 1 +x:1 +兰花 1 +x:1 +通用 1 +x:1 +十二月 1 +x:1 +人事局 1 +x:1 +加热炉 1 +x:1 +查血钾 1 +x:1 +香蕉园 1 +x:1 +铁锨 1 +x:1 +头发菜 1 +x:1 +吃劲 1 +x:1 +开矿 1 +x:1 +锡匠 1 +x:1 +较 2957 +x:2957 +察哈尔省 1 +x:1 +砂石料 1 +x:1 +憔悴 1 +x:1 +虚文 1 +x:1 +投入品 1 +x:1 +慈善会 1 +x:1 +年关 1 +x:1 +平炉 1 +x:1 +核子能 1 +x:1 +贷款 1 +x:1 +猪鬃 1 +x:1 +兰草 1 +x:1 +执政权 1 +x:1 +神宇 1 +x:1 +阻寒 1 +x:1 +荧幕 1 +x:1 +锁业 1 +x:1 +土特产品 1 +x:1 +稚童 1 +x:1 +跳跃性 1 +x:1 +年过半百 1 +x:1 +渠县 1 +x:1 +蔬菜区 1 +x:1 +物像 1 +x:1 +壁画 1 +x:1 +无人问津 1 +x:1 +舒声 1 +x:1 +化学工业 1 +x:1 +吃喝费 1 +x:1 +备感 1 +x:1 +木耳 1 +x:1 +演艺会 1 +x:1 +团组织 1 +x:1 +蒸气机 1 +x:1 +仙 5 +x:5 +明史 1 +x:1 +走过场 1 +x:1 +板胡 1 +x:1 +站站 1 +x:1 +发包权 1 +x:1 +船期费 1 +x:1 +密纹 1 +x:1 +毫 3 +x:3 +虚无 1 +x:1 +卖身投靠 1 +x:1 +倡廉 1 +x:1 +蕴 1 +x:1 +密约 1 +x:1 +腊八粥 1 +x:1 +头疼脑热 1 +x:1 +小燕子 1 +x:1 +宰相 1 +x:1 +出版署 1 +x:1 +希特勒 1 +x:1 +版块 1 +x:1 +无名小卒 1 +x:1 +蠕滑力 1 +x:1 +工作量 1 +x:1 +援助者 1 +x:1 +移动 1 +x:1 +海堤坝 1 +x:1 +调试 1 +x:1 +助战 1 +x:1 +晓悟 1 +x:1 +花梗 1 +x:1 +煤粉 1 +x:1 +川棉 1 +x:1 +冠名权 1 +x:1 +单行本 1 +x:1 +团体性 1 +x:1 +榴霰弹 1 +x:1 +善行 1 +x:1 +唯金牌论 1 +x:1 +长安街 1 +x:1 +抓获 1 +x:1 +环节 1 +x:1 +归人 1 +x:1 +油坊 1 +x:1 +拉动式 1 +x:1 +中前 1 +x:1 +农税 1 +x:1 +必然王国 1 +x:1 +开盘 1 +x:1 +消费国 1 +x:1 +按理 1 +x:1 +物候 1 +x:1 +相思歌 1 +x:1 +碉堡式 1 +x:1 +寿险业 1 +x:1 +调训 1 +x:1 +刀工 1 +x:1 +鸣冤叫屈 1 +x:1 +金水区 1 +x:1 +助跑道 1 +x:1 +路矿 1 +x:1 +助手 1 +x:1 +动力伞 1 +x:1 +蔬菜史 1 +x:1 +归于 1 +x:1 +恰帕雷 1 +x:1 +虚数 1 +x:1 +双曲线 1 +x:1 +儿童伞 1 +x:1 +造船 1 +x:1 +意气风发 1 +x:1 +制式 1 +x:1 +永和县 1 +x:1 +繁殖关 1 +x:1 +盐池 1 +x:1 +夜总会 1 +x:1 +越野车 1 +x:1 +大老婆 1 +x:1 +自夸 1 +x:1 +虎跃龙腾 1 +x:1 +嗷嗷叫 1 +x:1 +孕产妇 1 +x:1 +五力 1 +x:1 +虚报 1 +x:1 +投入口 1 +x:1 +赜 1 +x:1 +协作办 1 +x:1 +晓月 1 +x:1 +机缘 1 +x:1 +山杏 1 +x:1 +政府奖 1 +x:1 +天明 1 +x:1 +华乐 1 +x:1 +奇山异水 1 +x:1 +明珠暗投 1 +x:1 +复员证 1 +x:1 +大中型 1 +x:1 +漳浦县 1 +x:1 +饭后 1 +x:1 +衬布 1 +x:1 +盐水 1 +x:1 +调调 1 +x:1 +慧眼 1 +x:1 +新声路 1 +x:1 +一帆风顺 1 +x:1 +虚拟 1 +x:1 +和和气气 1 +x:1 +华丽 1 +x:1 +评论者 1 +x:1 +调谐 1 +x:1 +江珧柱 1 +x:1 +以旧翻新 1 +x:1 +看热闹 1 +x:1 +路灯 1 +x:1 +纸版 1 +x:1 +论 249 +x:249 +纸牌 1 +x:1 +狂放不羁 1 +x:1 +纸片 1 +x:1 +雾化 1 +x:1 +中签率 1 +x:1 +协作 1 +x:1 +华东 1 +x:1 +房 286 +x:286 +轮作制 1 +x:1 +太仓县 1 +x:1 +萨摩亚队 1 +x:1 +备而不用 1 +x:1 +合并案 1 +x:1 +助攻 1 +x:1 +吸烟客 1 +x:1 +机群 1 +x:1 +脑心通 1 +x:1 +球轴承 1 +x:1 +锑 5 +x:5 +冀晋区 1 +x:1 +炎黄子孙 1 +x:1 +舒张 1 +x:1 +结账 1 +x:1 +无粮户 1 +x:1 +分赛区 1 +x:1 +自大 1 +x:1 +漠视 1 +x:1 +几内亚湾 1 +x:1 +应战 1 +x:1 +革命家 1 +x:1 +初芽 1 +x:1 +谫 1 +x:1 +花瓣儿 1 +x:1 +本位主义 1 +x:1 +三元桥 1 +x:1 +五刑 1 +x:1 +明君 1 +x:1 +珊瑚丸 1 +x:1 +盐泉 1 +x:1 +肠镜 1 +x:1 +风姿 1 +x:1 +夏粮 1 +x:1 +检查部 1 +x:1 +华亭 1 +x:1 +青云直上 1 +x:1 +岭上 1 +x:1 +机翼 1 +x:1 +华人 1 +x:1 +衬底 1 +x:1 +旁系亲属 1 +x:1 +犬科 1 +x:1 +为我所用 1 +x:1 +助教 1 +x:1 +泣鬼神 1 +x:1 +铁丝笼 1 +x:1 +难民营 1 +x:1 +烨 45 +x:45 +军品 1 +x:1 +预备队 1 +x:1 +狄塞耳机 1 +x:1 +稿本 1 +x:1 +反射角 1 +x:1 +伯母 1 +x:1 +天机 1 +x:1 +九运 1 +x:1 +戊 1 +x:1 +调资 1 +x:1 +肖子 1 +x:1 +永安河 1 +x:1 +世叔 1 +x:1 +咯 1 +x:1 +澳元 1 +x:1 +没治 1 +x:1 +青岛队 1 +x:1 +躯体 1 +x:1 +体弱者 1 +x:1 +会集区 1 +x:1 +定场白 1 +x:1 +一无所长 1 +x:1 +天朝 1 +x:1 +鲨鱼 1 +x:1 +包治百病 1 +x:1 +峻伟 1 +x:1 +时久天长 1 +x:1 +借还款 1 +x:1 +角膜炎 1 +x:1 +碎银 1 +x:1 +别无良策 1 +x:1 +工作面 1 +x:1 +针织裤 1 +x:1 +锅底状 1 +x:1 +隽 1 +x:1 +眼 335 +x:335 +脸部 1 +x:1 +择机 1 +x:1 +神州 1 +x:1 +社长 1 +x:1 +臭老九 1 +x:1 +到资额 1 +x:1 +五台 1 +x:1 +天南地北 1 +x:1 +蝴蝶瓦 1 +x:1 +刀子 1 +x:1 +天条 1 +x:1 +卖国求荣 1 +x:1 +言行一致 1 +x:1 +五口 1 +x:1 +备有 1 +x:1 +抱抱 1 +x:1 +自备 1 +x:1 +择期 1 +x:1 +徐 1061 +x:1061 +刚柔相济 1 +x:1 +开火 1 +x:1 +卡通人 1 +x:1 +平直 1 +x:1 +责权 1 +x:1 +五反 1 +x:1 +没法 1 +x:1 +跑步器 1 +x:1 +抓药 1 +x:1 +复印机厂 1 +x:1 +隐头花序 1 +x:1 +共葬 1 +x:1 +施事 1 +x:1 +大青山 1 +x:1 +东圃镇 1 +x:1 +蔗 2 +x:2 +奢起贫兆 1 +x:1 +曲柄 1 +x:1 +欧安组织 1 +x:1 +燎灼 1 +x:1 +暮鼓 1 +x:1 +通牒 1 +x:1 +弯子 1 +x:1 +吉人天相 1 +x:1 +行政性 1 +x:1 +教管会 1 +x:1 +灿朗 1 +x:1 +昏黄 1 +x:1 +开炮 1 +x:1 +增辉添色 1 +x:1 +撷取 1 +x:1 +备查 1 +x:1 +攻无不克 1 +x:1 +天极 1 +x:1 +凡夫俗子 1 +x:1 +新沟北村 1 +x:1 +雨声 1 +x:1 +昏黑 1 +x:1 +煤窑 1 +x:1 +华侨 1 +x:1 +装甲艇 1 +x:1 +天柱 1 +x:1 +双岭村 1 +x:1 +仓山 1 +x:1 +施主 1 +x:1 +出版社 1 +x:1 +搏斗 1 +x:1 +托克托 1 +x:1 +胜诉率 1 +x:1 +吃喝 1 +x:1 +机务段 1 +x:1 +楦子 1 +x:1 +平白 1 +x:1 +荷叶 1 +x:1 +机组 1 +x:1 +化学元素 1 +x:1 +猿岩龙岫 1 +x:1 +店铺 1 +x:1 +娩 1 +x:1 +披沙拣金 1 +x:1 +狮泉河 1 +x:1 +世医 1 +x:1 +白 668 +x:668 +六神无主 1 +x:1 +神庙 1 +x:1 +牛肝菌 1 +x:1 +神府 1 +x:1 +蒇 1 +x:1 +论断 1 +x:1 +绣口 1 +x:1 +非同寻常 1 +x:1 +现成 1 +x:1 +评税单 1 +x:1 +伴随 1 +x:1 +秤纽 1 +x:1 +慷慨陈辞 1 +x:1 +金属膜 1 +x:1 +咸丰 1 +x:1 +大本本 1 +x:1 +社队 1 +x:1 +越野赛 1 +x:1 +立交桥 1 +x:1 +享 32 +x:32 +民歌风 1 +x:1 +白坯布 1 +x:1 +茅盾 1 +x:1 +追星族 1 +x:1 +一面儿理 1 +x:1 +下沉 1 +x:1 +园容 1 +x:1 +事故科 1 +x:1 +疏浚 1 +x:1 +路牌 1 +x:1 +商业额 1 +x:1 +井水 1 +x:1 +仁安村 1 +x:1 +莱芜 1 +x:1 +磁道 1 +x:1 +燕 49 +x:49 +叶轮 1 +x:1 +纬线 1 +x:1 +收割机厂 1 +x:1 +社院 1 +x:1 +澳分 1 +x:1 +长信 1 +x:1 +电位仪 1 +x:1 +汉寿 1 +x:1 +观看 1 +x:1 +安定门 1 +x:1 +寿联 1 +x:1 +卷帙浩繁 1 +x:1 +壁灯 1 +x:1 +抱憾 1 +x:1 +略图 1 +x:1 +珊瑚礁区 1 +x:1 +凉面 1 +x:1 +盐渍 1 +x:1 +花树 1 +x:1 +平生 1 +x:1 +纪游诗 1 +x:1 +认定书 1 +x:1 +壁炉 1 +x:1 +申诉人 1 +x:1 +电磁法 1 +x:1 +筑造 1 +x:1 +凉鞋 1 +x:1 +防洪堤 1 +x:1 +记忆力 1 +x:1 +盐滩 1 +x:1 +全传 1 +x:1 +长传 1 +x:1 +粉刷工 1 +x:1 +夜盲 1 +x:1 +希冀 1 +x:1 +官架子 1 +x:1 +拉德方斯 1 +x:1 +侦破率 1 +x:1 +冰箱门 1 +x:1 +鹭鹚 1 +x:1 +电磁波 1 +x:1 +按照 1 +x:1 +雾凇 1 +x:1 +采录 1 +x:1 +鞍山市 1 +x:1 +摇 59 +x:59 +叛逃 1 +x:1 +移民区 1 +x:1 +木薯 1 +x:1 +结转 1 +x:1 +谢天谢地 1 +x:1 +一差二错 1 +x:1 +骨结核 1 +x:1 +雪糕 1 +x:1 +版刻 1 +x:1 +九谷 1 +x:1 +煤种 1 +x:1 +积雪 1 +x:1 +国家级 1 +x:1 +计算机网 1 +x:1 +迎生曲 1 +x:1 +开班 1 +x:1 +长住 1 +x:1 +孢子 1 +x:1 +纸烟 1 +x:1 +蔚为 1 +x:1 +五假 1 +x:1 +备播 1 +x:1 +性关系 1 +x:1 +明白纸 1 +x:1 +庄山 1 +x:1 +欢欢乐乐 1 +x:1 +办赛 1 +x:1 +评定者 1 +x:1 +荒乱 1 +x:1 +抱佛脚 1 +x:1 +五冶 1 +x:1 +维修队 1 +x:1 +长亲 1 +x:1 +道具车 1 +x:1 +长亭 1 +x:1 +盛装 1 +x:1 +朦胧 1 +x:1 +神往 1 +x:1 +农经 1 +x:1 +鹤嘴镐 1 +x:1 +鼠 26 +x:26 +玉叶金枝 1 +x:1 +简洁明了 1 +x:1 +调转 1 +x:1 +仓库 1 +x:1 +金墩乡 1 +x:1 +长于 1 +x:1 +巴蜀 1 +x:1 +刀头 1 +x:1 +地学部 1 +x:1 +煤砖 1 +x:1 +筹划 1 +x:1 +闪耀 1 +x:1 +两部一办 1 +x:1 +核桃仁 1 +x:1 +要 20607 +x:20607 +拉 565 +x:565 +天数 1 +x:1 +器械科 1 +x:1 +神志 1 +x:1 +迎来 1 +x:1 +仓廪 1 +x:1 +大发雷霆 1 +x:1 +辽八厂 1 +x:1 +养殖池 1 +x:1 +湖 118 +x:118 +扮鬼脸 1 +x:1 +呈文 1 +x:1 +机米 1 +x:1 +缰绳 1 +x:1 +花样 1 +x:1 +勐仑镇 1 +x:1 +拔尖 1 +x:1 +咕嘟嘟 1 +x:1 +荒丘 1 +x:1 +伴音 1 +x:1 +有产者 1 +x:1 +忽视 1 +x:1 +天敌 1 +x:1 +并 10496 +x:10496 +大余县 1 +x:1 +彩虹厅 1 +x:1 +焊缝 1 +x:1 +世兄 1 +x:1 +授 24 +x:24 +乳胶厂 1 +x:1 +冰淇淋 1 +x:1 +夏 374 +x:374 +弄口 1 +x:1 +调进 1 +x:1 +颇具规模 1 +x:1 +版协 1 +x:1 +格杀勿论 1 +x:1 +惊恐 1 +x:1 +闯祸者 1 +x:1 +神异 1 +x:1 +调运 1 +x:1 +择日 1 +x:1 +信号弹 1 +x:1 +盛行 1 +x:1 +长丝 1 +x:1 +盛衰 1 +x:1 +毁约 1 +x:1 +人事处 1 +x:1 +厨 7 +x:7 +张牙舞爪 1 +x:1 +工作间 1 +x:1 +名报名刊 1 +x:1 +紫河车 1 +x:1 +长上 1 +x:1 +长三 1 +x:1 +筹办 1 +x:1 +抱恨 1 +x:1 +消费力 1 +x:1 +廓清 1 +x:1 +蚀尽 1 +x:1 +诸暨市 1 +x:1 +防护网 1 +x:1 +单刀赴会 1 +x:1 +武丑 1 +x:1 +铩羽而归 1 +x:1 +济源 1 +x:1 +备料 1 +x:1 +天时 1 +x:1 +申诉信 1 +x:1 +绿树成荫 1 +x:1 +大哥大 1 +x:1 +秧鸡 1 +x:1 +丝光剂 1 +x:1 +天日 1 +x:1 +夹道村 1 +x:1 +舒展 1 +x:1 +扣除率 1 +x:1 +莱茵 1 +x:1 +恢复性 1 +x:1 +典册 1 +x:1 +泽被子孙 1 +x:1 +弯月形 1 +x:1 +锡城 1 +x:1 +皓月 1 +x:1 +筹募 1 +x:1 +保障法 1 +x:1 +班师回营 1 +x:1 +抱怨 1 +x:1 +长久 1 +x:1 +弯头 1 +x:1 +自我陶醉 1 +x:1 +女警 1 +x:1 +板羽球 1 +x:1 +煤末 1 +x:1 +勘验 1 +x:1 +世仇 1 +x:1 +炉子 1 +x:1 +劳教 1 +x:1 +批核 1 +x:1 +煤机 1 +x:1 +财大气粗 1 +x:1 +茅棚 1 +x:1 +学习热 1 +x:1 +五交 1 +x:1 +世代 1 +x:1 +国境点 1 +x:1 +马戏厅 1 +x:1 +调遣 1 +x:1 +创建者 1 +x:1 +营市 1 +x:1 +城东村 1 +x:1 +砰 5 +x:5 +更迭 1 +x:1 +铭记 1 +x:1 +风言风语 1 +x:1 +逸韵 1 +x:1 +粉体 1 +x:1 +天穹 1 +x:1 +冒顶 1 +x:1 +叛逆者 1 +x:1 +翩翩少年 1 +x:1 +独身汉 1 +x:1 +调适 1 +x:1 +世事 1 +x:1 +长凳 1 +x:1 +油刷 1 +x:1 +安贫乐道 1 +x:1 +防范性 1 +x:1 +寝 2 +x:2 +五代 1 +x:1 +婚姻观 1 +x:1 +孤立化 1 +x:1 +足银 1 +x:1 +世交 1 +x:1 +加厚型 1 +x:1 +戛纳节 1 +x:1 +救火车 1 +x:1 +地球化学 1 +x:1 +死路一条 1 +x:1 +十时 1 +x:1 +自如 1 +x:1 +拷 4 +x:4 +夜校 1 +x:1 +红红谷 1 +x:1 +知情者 1 +x:1 +世人 1 +x:1 +勇士 1 +x:1 +施压 1 +x:1 +阔 19 +x:19 +典仪 1 +x:1 +恪尽 1 +x:1 +的 358151 +x:358151 +至宝 1 +x:1 +试金石 1 +x:1 +挂名 1 +x:1 +葫芦巴 1 +x:1 +路沟 1 +x:1 +五中 1 +x:1 +北京鸭 1 +x:1 +圆圆 1 +x:1 +圆圈 1 +x:1 +大动脉 1 +x:1 +罗平县 1 +x:1 +莫过于 1 +x:1 +原始股 1 +x:1 +海盗 1 +x:1 +阿坝 1 +x:1 +五业 1 +x:1 +终末 1 +x:1 +安全壳 1 +x:1 +圆场 1 +x:1 +寿终正寝 1 +x:1 +天窗 1 +x:1 +江西腊 1 +x:1 +路沿 1 +x:1 +冒领 1 +x:1 +阀状 1 +x:1 +今夕 1 +x:1 +堪予 1 +x:1 +以逸待劳 1 +x:1 +隔阂 1 +x:1 +横流 1 +x:1 +五一 1 +x:1 +天竹 1 +x:1 +天竺 1 +x:1 +雄 39 +x:39 +房建队 1 +x:1 +世上 1 +x:1 +长兴 1 +x:1 +必需品 1 +x:1 +晏 8 +x:8 +荒冢 1 +x:1 +精诚所至 1 +x:1 +录入 1 +x:1 +马关县 1 +x:1 +煤柱 1 +x:1 +滴水穿石 1 +x:1 +单片机 1 +x:1 +秧脚 1 +x:1 +永河区 1 +x:1 +反叛者 1 +x:1 +茅根 1 +x:1 +热蒸现卖 1 +x:1 +确定者 1 +x:1 +热情劲 1 +x:1 +平正 1 +x:1 +暮色 1 +x:1 +长兄 1 +x:1 +一相情愿 1 +x:1 +贩黄 1 +x:1 +当场 1 +x:1 +阿国 1 +x:1 +调配 1 +x:1 +燎泡 1 +x:1 +当地 1 +x:1 +合并症 1 +x:1 +静 101 +x:101 +机房 1 +x:1 +西医学界 1 +x:1 +检查费 1 +x:1 +开气 1 +x:1 +世俗 1 +x:1 +鹰子咀 1 +x:1 +阿囡 1 +x:1 +剪枝 1 +x:1 +匹敌 1 +x:1 +冲决 1 +x:1 +本来面目 1 +x:1 +四五月份 1 +x:1 +环顾 1 +x:1 +羽毛未丰 1 +x:1 +苹果 1 +x:1 +开水 1 +x:1 +梦魇 1 +x:1 +便 1697 +x:1697 +华南 1 +x:1 +烁 2 +x:2 +遗产 1 +x:1 +牙床 1 +x:1 +晋安河 1 +x:1 +问候声 1 +x:1 +漂漂亮亮 1 +x:1 +隔音 1 +x:1 +挂职支教 1 +x:1 +争分夺秒 1 +x:1 +金融资本 1 +x:1 +施加 1 +x:1 +尸 6 +x:6 +照相 1 +x:1 +小到中雪 1 +x:1 +冲凉 1 +x:1 +抄抄写写 1 +x:1 +擤 1 +x:1 +跛足 1 +x:1 +Ⅰ 3 +x:3 +打开 1 +x:1 +帮衬 1 +x:1 +机手 1 +x:1 +酸乳类 1 +x:1 +冲击 1 +x:1 +阿嚏 1 +x:1 +轩 34 +x:34 +录像 1 +x:1 +耕耘者 1 +x:1 +磁轴 1 +x:1 +建筑师 1 +x:1 +双喜临门 1 +x:1 +中发 1 +x:1 +执法办 1 +x:1 +华北 1 +x:1 +紫外光 1 +x:1 +肠衣 1 +x:1 +化险为夷 1 +x:1 +忌日 1 +x:1 +阅 26 +x:26 +协助 1 +x:1 +果然如此 1 +x:1 +局界 1 +x:1 +荒僻 1 +x:1 +环食 1 +x:1 +配电室 1 +x:1 +岭南 1 +x:1 +军政府 1 +x:1 +五伦 1 +x:1 +工作证 1 +x:1 +惊险频出 1 +x:1 +丝竹管弦 1 +x:1 +养蝎业 1 +x:1 +学生娃 1 +x:1 +勇夺 1 +x:1 +穷山恶水 1 +x:1 +喇叭口 1 +x:1 +提手旁 1 +x:1 +协力 1 +x:1 +红学家 1 +x:1 +一手 1 +x:1 +大雨倾盆 1 +x:1 +勇夫 1 +x:1 +铅笔盒 1 +x:1 +野荠菜 1 +x:1 +画中有诗 1 +x:1 +花枝 1 +x:1 +兰香 1 +x:1 +天篷 1 +x:1 +韧带 1 +x:1 +国际馆 1 +x:1 +武义 1 +x:1 +祖孙 1 +x:1 +昏花 1 +x:1 +大围山 1 +x:1 +心驰 1 +x:1 +作息时间 1 +x:1 +整旧如新 1 +x:1 +问讯处 1 +x:1 +银蛇 1 +x:1 +设立 1 +x:1 +世伯 1 +x:1 +蜜饯厂 1 +x:1 +紧巴巴 1 +x:1 +长假 1 +x:1 +归咎 1 +x:1 +干柴 1 +x:1 +闷倦 1 +x:1 +中国队 1 +x:1 +欠款额 1 +x:1 +师职 1 +x:1 +太夫人 1 +x:1 +同帧 1 +x:1 +痞气 1 +x:1 +冲力 1 +x:1 +秋毫无犯 1 +x:1 +禅静 1 +x:1 +开演 1 +x:1 +冷水性 1 +x:1 +雪弹 1 +x:1 +严重者 1 +x:1 +邦联 1 +x:1 +单行线 1 +x:1 +冲劲 1 +x:1 +铅笔画 1 +x:1 +明斯克 1 +x:1 +边沿 1 +x:1 +末梢神经 1 +x:1 +犹太区 1 +x:1 +毡子 1 +x:1 +河滨 1 +x:1 +取样 1 +x:1 +冲动 1 +x:1 +椭圆 1 +x:1 +病 465 +x:465 +长叹 1 +x:1 +密林 1 +x:1 +反射面 1 +x:1 +中小学 1 +x:1 +海誓山盟 1 +x:1 +长台 1 +x:1 +当周 1 +x:1 +小家电 1 +x:1 +冷场 1 +x:1 +毁损 1 +x:1 +圈养 1 +x:1 +孔府 1 +x:1 +田园诗 1 +x:1 +至好 1 +x:1 +孔庙 1 +x:1 +经营性 1 +x:1 +打手势 1 +x:1 +录取 1 +x:1 +风险性 1 +x:1 +长发 1 +x:1 +饥饿症 1 +x:1 +有机可乘 1 +x:1 +挂图 1 +x:1 +有害 1 +x:1 +农推 1 +x:1 +梧州市 1 +x:1 +信达所 1 +x:1 +西德队 1 +x:1 +一统天下 1 +x:1 +女队 1 +x:1 +总工 1 +x:1 +毁掉 1 +x:1 +罗马帝国 1 +x:1 +悌 2 +x:2 +对抗性 1 +x:1 +矿工会 1 +x:1 +专 189 +x:189 +深处 1 +x:1 +处分者 1 +x:1 +少男 1 +x:1 +长篇卷 1 +x:1 +武侠小说 1 +x:1 +火力网 1 +x:1 +冲刷 1 +x:1 +一清早 1 +x:1 +藻种 1 +x:1 +摇身一变 1 +x:1 +冲刺 1 +x:1 +放大镜 1 +x:1 +鸳 1 +x:1 +绳梯 1 +x:1 +夺得 1 +x:1 +智者见智 1 +x:1 +民族主义 1 +x:1 +摊位费 1 +x:1 +井点 1 +x:1 +脸软 1 +x:1 +古杉 1 +x:1 +长卷 1 +x:1 +背 219 +x:219 +长印 1 +x:1 +得步进步 1 +x:1 +新进党 1 +x:1 +冲剂 1 +x:1 +割接法 1 +x:1 +耻辱感 1 +x:1 +澳人 1 +x:1 +木香 1 +x:1 +抖擞精神 1 +x:1 +肥牛场 1 +x:1 +晾衣篮 1 +x:1 +荒原 1 +x:1 +渗出 1 +x:1 +深奥 1 +x:1 +囿 18 +x:18 +茶饭不思 1 +x:1 +东三环 1 +x:1 +瓤子 1 +x:1 +班子 1 +x:1 +长势 1 +x:1 +冲厕 1 +x:1 +搓板 1 +x:1 +昏聩 1 +x:1 +批次 1 +x:1 +制订 1 +x:1 +走熊 1 +x:1 +窃案 1 +x:1 +横滨 1 +x:1 +那曲镇 1 +x:1 +楚汉之争 1 +x:1 +闷儿 1 +x:1 +九里 1 +x:1 +阿哥 1 +x:1 +中原 1 +x:1 +冲压 1 +x:1 +不仅仅 1 +x:1 +开渠 1 +x:1 +至亲至爱 1 +x:1 +横滚 1 +x:1 +投机取巧 1 +x:1 +开宗明义 1 +x:1 +禅院 1 +x:1 +献礼 1 +x:1 +蛋白 1 +x:1 +白河 1 +x:1 +焊接 1 +x:1 +审定 1 +x:1 +人流量 1 +x:1 +遂 79 +x:79 +西雅图市 1 +x:1 +隔间 1 +x:1 +井然 1 +x:1 +撰述 1 +x:1 +志趣 1 +x:1 +高年级 1 +x:1 +黄瓜秧 1 +x:1 +农技 1 +x:1 +亢阳 1 +x:1 +演艺圈 1 +x:1 +横溢 1 +x:1 +忽闪 1 +x:1 +撇缆枪 1 +x:1 +列克星顿 1 +x:1 +自来水 1 +x:1 +天神 1 +x:1 +双鸭山 1 +x:1 +昏者 1 +x:1 +纸浆 1 +x:1 +君臣 1 +x:1 +学习率 1 +x:1 +蔚县 1 +x:1 +半月刊 1 +x:1 +成年人 1 +x:1 +轮次 1 +x:1 +登堂入室 1 +x:1 +孔径 1 +x:1 +卖鱼处 1 +x:1 +审察 1 +x:1 +秀丽 1 +x:1 +社论 1 +x:1 +善选 1 +x:1 +乙状结肠 1 +x:1 +归国 1 +x:1 +录制 1 +x:1 +耍 16 +x:16 +政工组 1 +x:1 +铠甲 1 +x:1 +开源 1 +x:1 +已决犯 1 +x:1 +归因 1 +x:1 +工作观 1 +x:1 +曲种 1 +x:1 +备种 1 +x:1 +开溜 1 +x:1 +制造业 1 +x:1 +珍珠熊 1 +x:1 +肝儿 1 +x:1 +入境问俗 1 +x:1 +娱 8 +x:8 +曝光表 1 +x:1 +出版权 1 +x:1 +十万大山 1 +x:1 +天禀 1 +x:1 +优胜者 1 +x:1 +贿 5 +x:5 +离合器 1 +x:1 +迷魂阵 1 +x:1 +玉环 1 +x:1 +相安无事 1 +x:1 +思域 1 +x:1 +欣幸 1 +x:1 +长剧 1 +x:1 +虎 405 +x:405 +禅隐 1 +x:1 +华冶 1 +x:1 +呈示 1 +x:1 +农户 1 +x:1 +开滦 1 +x:1 +皮革厂 1 +x:1 +农房 1 +x:1 +释然 1 +x:1 +钻进 1 +x:1 +初始条件 1 +x:1 +长剑 1 +x:1 +有效率 1 +x:1 +墒情 1 +x:1 +通水 1 +x:1 +社评 1 +x:1 +大家族 1 +x:1 +路标 1 +x:1 +以柔制刚 1 +x:1 +北隅 1 +x:1 +忌恨 1 +x:1 +归入 1 +x:1 +机械手 1 +x:1 +机机 1 +x:1 +订购人 1 +x:1 +仁人君子 1 +x:1 +安全局 1 +x:1 +忠县 1 +x:1 +仰仗 1 +x:1 +农时 1 +x:1 +拟任 1 +x:1 +大中修 1 +x:1 +当初 1 +x:1 +安全山 1 +x:1 +维修费 1 +x:1 +上一年 1 +x:1 +冷光 1 +x:1 +安徽省 1 +x:1 +炕桌 1 +x:1 +耻辱柱 1 +x:1 +白内障 1 +x:1 +忠厚 1 +x:1 +呀 198 +x:198 +殖民主义 1 +x:1 +上蹿下跳 1 +x:1 +机杼 1 +x:1 +作鬼 1 +x:1 +深心 1 +x:1 +订购价 1 +x:1 +咸味 1 +x:1 +书法界 1 +x:1 +出言不慎 1 +x:1 +圆台 1 +x:1 +荒唐 1 +x:1 +拟人 1 +x:1 +龙凤鸟 1 +x:1 +楼堂馆所 1 +x:1 +病魔缠身 1 +x:1 +路桥 1 +x:1 +典医监 1 +x:1 +监察法 1 +x:1 +壁橱 1 +x:1 +教科文卫 1 +x:1 +当前 1 +x:1 +大面儿 1 +x:1 +以情感人 1 +x:1 +救济型 1 +x:1 +民歌节 1 +x:1 +态势 1 +x:1 +代表法 1 +x:1 +冲向 1 +x:1 +机枪 1 +x:1 +农救 1 +x:1 +祖师 1 +x:1 +没用 1 +x:1 +驿动 1 +x:1 +机枢 1 +x:1 +文京区 1 +x:1 +黄渡镇 1 +x:1 +选调 1 +x:1 +机架 1 +x:1 +曲终 1 +x:1 +寒暑表 1 +x:1 +挥 57 +x:57 +讲话者 1 +x:1 +阿南 1 +x:1 +姜冯营村 1 +x:1 +物体 1 +x:1 +非成员国 1 +x:1 +井盐 1 +x:1 +左权 1 +x:1 +有理分式 1 +x:1 +樟木 1 +x:1 +冷凝 1 +x:1 +参与 1 +x:1 +手推车 1 +x:1 +安全岛 1 +x:1 +敌营 1 +x:1 +开罗市 1 +x:1 +夙嫌 1 +x:1 +宝瓶座 1 +x:1 +建筑家 1 +x:1 +沟壕 1 +x:1 +下流 1 +x:1 +廉耻 1 +x:1 +沟壑 1 +x:1 +路检 1 +x:1 +献给 1 +x:1 +戴盆望天 1 +x:1 +彩笛卷 1 +x:1 +花期 1 +x:1 +非凡 1 +x:1 +冷冻 1 +x:1 +普格县 1 +x:1 +炕梢 1 +x:1 +渔农处 1 +x:1 +曲线 1 +x:1 +盲人 1 +x:1 +存车费 1 +x:1 +存续期 1 +x:1 +虚空 1 +x:1 +产肉量 1 +x:1 +伯父 1 +x:1 +伯爵 1 +x:1 +丢盔卸甲 1 +x:1 +挚爱 1 +x:1 +胁持 1 +x:1 +焊料 1 +x:1 +雨水管 1 +x:1 +丝包线 1 +x:1 +诸如 1 +x:1 +开栏 1 +x:1 +物价 1 +x:1 +物件 1 +x:1 +职业制 1 +x:1 +救世主 1 +x:1 +告别厅 1 +x:1 +还乡团 1 +x:1 +搏杀 1 +x:1 +马奇诺 1 +x:1 +挂冠 1 +x:1 +荣华 1 +x:1 +荣升 1 +x:1 +观察点 1 +x:1 +本外币 1 +x:1 +阿穆尔州 1 +x:1 +深度 1 +x:1 +铜车马 1 +x:1 +顶效镇 1 +x:1 +煤成 1 +x:1 +寓于 1 +x:1 +马戏团 1 +x:1 +盐田 1 +x:1 +当即 1 +x:1 +鳞屑 1 +x:1 +平滑 1 +x:1 +调销 1 +x:1 +劳方 1 +x:1 +芬芳娇艳 1 +x:1 +农林牧业 1 +x:1 +机智 1 +x:1 +天罡 1 +x:1 +煽风点火 1 +x:1 +物产 1 +x:1 +千粒重 1 +x:1 +遗俗 1 +x:1 +出租汽车 1 +x:1 +湮没 1 +x:1 +长堤路 1 +x:1 +溪流 1 +x:1 +坠子 1 +x:1 +走人 1 +x:1 +杨伙盘 1 +x:1 +帆布床 1 +x:1 +交相辉映 1 +x:1 +特惠关税 1 +x:1 +轼 3 +x:3 +衣蛾 1 +x:1 +拟作 1 +x:1 +红砂岩 1 +x:1 +方整化 1 +x:1 +夏日 1 +x:1 +锅贴儿 1 +x:1 +旅行者 1 +x:1 +西画系 1 +x:1 +板鸭 1 +x:1 +深市 1 +x:1 +水标 1 +x:1 +聋人 1 +x:1 +冷僻 1 +x:1 +格格不入 1 +x:1 +却步 1 +x:1 +湖云塘 1 +x:1 +调门 1 +x:1 +岭坡 1 +x:1 +夜深 1 +x:1 +药物部 1 +x:1 +高红村 1 +x:1 +二硫基苯 1 +x:1 +违诺 1 +x:1 +准确率 1 +x:1 +纲 32 +x:32 +望风而逃 1 +x:1 +定型机 1 +x:1 +等速运动 1 +x:1 +挂儿 1 +x:1 +仓储场 1 +x:1 +扁桃 1 +x:1 +个人所有 1 +x:1 +布雷顿 1 +x:1 +洞净杆赛 1 +x:1 +细石器 1 +x:1 +氯地孕酮 1 +x:1 +平湖 1 +x:1 +剿共 1 +x:1 +晚晴 1 +x:1 +肢 2 +x:2 +急诊费 1 +x:1 +花木 1 +x:1 +大中专 1 +x:1 +不丹王国 1 +x:1 +硬皮病 1 +x:1 +伸出 1 +x:1 +物业 1 +x:1 +猛不防 1 +x:1 +衩 1 +x:1 +应答 1 +x:1 +深广 1 +x:1 +横栏 1 +x:1 +岭地 1 +x:1 +横标 1 +x:1 +肖像 1 +x:1 +蟹肉 1 +x:1 +保守党 1 +x:1 +明亮 1 +x:1 +审度 1 +x:1 +国产机 1 +x:1 +埃菲社 1 +x:1 +侑 1 +x:1 +蔬菜业 1 +x:1 +明人 1 +x:1 +冷却 1 +x:1 +荒坡 1 +x:1 +熔断器 1 +x:1 +溅 18 +x:18 +机收 1 +x:1 +长垣 1 +x:1 +基本词汇 1 +x:1 +明来暗往 1 +x:1 +明了 1 +x:1 +倚天仗剑 1 +x:1 +取水 1 +x:1 +烟 130 +x:130 +三脚架 1 +x:1 +落地钟 1 +x:1 +吃现成 1 +x:1 +余孽 1 +x:1 +锡业 1 +x:1 +农林 1 +x:1 +刺儿头 1 +x:1 +独孤求败 1 +x:1 +通榆 1 +x:1 +明代 1 +x:1 +明令 1 +x:1 +家破人亡 1 +x:1 +调阅 1 +x:1 +深州 1 +x:1 +中医大 1 +x:1 +歼击机 1 +x:1 +东三省 1 +x:1 +甩花手 1 +x:1 +黄牛党 1 +x:1 +测绘兵 1 +x:1 +平添 1 +x:1 +当做 1 +x:1 +敢 444 +x:444 +炒鱿鱼 1 +x:1 +深巷 1 +x:1 +安全帽 1 +x:1 +协商 1 +x:1 +新婚户 1 +x:1 +锡乌 1 +x:1 +提灌站 1 +x:1 +洞总杆赛 1 +x:1 +长城 1 +x:1 +密探 1 +x:1 +划 118 +x:118 +马驹桥镇 1 +x:1 +天籁 1 +x:1 +调防 1 +x:1 +平淡 1 +x:1 +安全带 1 +x:1 +机械性 1 +x:1 +尼那 1 +x:1 +刃 8 +x:8 +享用 1 +x:1 +叫好声 1 +x:1 +阿其 1 +x:1 +澄沙 1 +x:1 +决胜局 1 +x:1 +调集 1 +x:1 +政经分离 1 +x:1 +按钮式 1 +x:1 +不乏其人 1 +x:1 +明丽 1 +x:1 +毁林 1 +x:1 +参保 1 +x:1 +占款 1 +x:1 +拷扁榄 1 +x:1 +老远 1 +x:1 +秤星 1 +x:1 +绝伦 1 +x:1 +草荐 1 +x:1 +粮划署 1 +x:1 +杂物间 1 +x:1 +自查自省 1 +x:1 +谴责 1 +x:1 +平津 1 +x:1 +吃亏 1 +x:1 +祖居 1 +x:1 +忆 38 +x:38 +工程师室 1 +x:1 +审干 1 +x:1 +取法 1 +x:1 +长安镇 1 +x:1 +刑侦局 1 +x:1 +机时 1 +x:1 +电位器 1 +x:1 +什刹海 1 +x:1 +花青素 1 +x:1 +草草 1 +x:1 +遁入 1 +x:1 +书画社 1 +x:1 +绍兴酒 1 +x:1 +闷响 1 +x:1 +青岛路 1 +x:1 +农机 1 +x:1 +土管员 1 +x:1 +多快好省 1 +x:1 +薄板坯 1 +x:1 +志贺 1 +x:1 +无伤大雅 1 +x:1 +防护林 1 +x:1 +傅 356 +x:356 +木鱼 1 +x:1 +歌曲集 1 +x:1 +至少 1 +x:1 +老一辈 1 +x:1 +正中下怀 1 +x:1 +幸运儿 1 +x:1 +疗 15 +x:15 +中长距离 1 +x:1 +荣光 1 +x:1 +协同 1 +x:1 +平河 1 +x:1 +舛讹 1 +x:1 +欲笑无声 1 +x:1 +有得有失 1 +x:1 +华商 1 +x:1 +共鸣 1 +x:1 +恪守 1 +x:1 +焊枪 1 +x:1 +冲垮 1 +x:1 +各具特色 1 +x:1 +夏末 1 +x:1 +兄 12 +x:12 +井田 1 +x:1 +当兵 1 +x:1 +奋斗史 1 +x:1 +重刑犯 1 +x:1 +癖 3 +x:3 +精确性 1 +x:1 +毡帽 1 +x:1 +大屯营乡 1 +x:1 +乘务员 1 +x:1 +工作费 1 +x:1 +思危 1 +x:1 +碰簧锁 1 +x:1 +疱疹 1 +x:1 +环境厅 1 +x:1 +白皮书 1 +x:1 +乱腾 1 +x:1 +毡帐 1 +x:1 +夏朝 1 +x:1 +挂号 1 +x:1 +密报 1 +x:1 +舛误 1 +x:1 +结集 1 +x:1 +初级小学 1 +x:1 +挂包 1 +x:1 +高举 1 +x:1 +取消 1 +x:1 +平民 1 +x:1 +长嘴 1 +x:1 +抒情化 1 +x:1 +农林业 1 +x:1 +违规 1 +x:1 +直升飞机 1 +x:1 +剿匪 1 +x:1 +移交 1 +x:1 +有胆有识 1 +x:1 +结队 1 +x:1 +学时 1 +x:1 +包笼 1 +x:1 +鄯 1 +x:1 +虚礼 1 +x:1 +过目难忘 1 +x:1 +防务展 1 +x:1 +资产者 1 +x:1 +服装类 1 +x:1 +精工细作 1 +x:1 +路段 1 +x:1 +另册 1 +x:1 +更衣 1 +x:1 +破冰船 1 +x:1 +非专业 1 +x:1 +通栏 1 +x:1 +平江 1 +x:1 +军乐管 1 +x:1 +赛利浦乡 1 +x:1 +平汉 1 +x:1 +深层 1 +x:1 +芋头 1 +x:1 +山海经 1 +x:1 +电费单 1 +x:1 +程林庄 1 +x:1 +秤杆 1 +x:1 +归功 1 +x:1 +党代表 1 +x:1 +嗬 32 +x:32 +电机厂 1 +x:1 +荣军 1 +x:1 +思古 1 +x:1 +挂印 1 +x:1 +思口 1 +x:1 +洪湖市 1 +x:1 +胺 1 +x:1 +焊条 1 +x:1 +娑罗树 1 +x:1 +困惑 1 +x:1 +呜乎哀哉 1 +x:1 +喉 9 +x:9 +深厚 1 +x:1 +寿阳 1 +x:1 +天父 1 +x:1 +荣幸 1 +x:1 +葡萄形 1 +x:1 +熠熠流彩 1 +x:1 +外 1765 +x:1765 +曲牌 1 +x:1 +设问句 1 +x:1 +配额制 1 +x:1 +高碑店 1 +x:1 +建行 1 +x:1 +沣 1 +x:1 +出版法 1 +x:1 +自强 1 +x:1 +通查 1 +x:1 +宗路区 1 +x:1 +开支 1 +x:1 +电火花 1 +x:1 +知人论世 1 +x:1 +处分 1 +x:1 +欣喜 1 +x:1 +困惫 1 +x:1 +佃户 1 +x:1 +蒋 607 +x:607 +路摊 1 +x:1 +深受 1 +x:1 +执法室 1 +x:1 +氯醇 1 +x:1 +圈子 1 +x:1 +白不呲咧 1 +x:1 +当年 1 +x:1 +绿帽子 1 +x:1 +积聚 1 +x:1 +寿险 1 +x:1 +一带而过 1 +x:1 +帮腔 1 +x:1 +横斜 1 +x:1 +献物 1 +x:1 +天牛 1 +x:1 +安全值 1 +x:1 +态度 1 +x:1 +牙垢 1 +x:1 +社联 1 +x:1 +切近 1 +x:1 +帆布厂 1 +x:1 +乘车人 1 +x:1 +初院 1 +x:1 +梨 17 +x:17 +助燃 1 +x:1 +杨家湖 1 +x:1 +圈定 1 +x:1 +徐龙区 1 +x:1 +掩眼法 1 +x:1 +机运连 1 +x:1 +深化 1 +x:1 +开斋 1 +x:1 +子夜 1 +x:1 +长头 1 +x:1 +海原县 1 +x:1 +当庭 1 +x:1 +长大 1 +x:1 +防护栏 1 +x:1 +动委会 1 +x:1 +礼纪镇 1 +x:1 +苍翠 1 +x:1 +豆腐块 1 +x:1 +长夜 1 +x:1 +井站 1 +x:1 +交 740 +x:740 +间接税 1 +x:1 +北京队 1 +x:1 +炉台 1 +x:1 +归州 1 +x:1 +生殖 1 +x:1 +通条 1 +x:1 +小业主 1 +x:1 +利国乡 1 +x:1 +谈笑自若 1 +x:1 +头班 1 +x:1 +副总 1 +x:1 +硝酸银 1 +x:1 +认贼作父 1 +x:1 +圆弧 1 +x:1 +无绩效者 1 +x:1 +耻 9 +x:9 +长处 1 +x:1 +感谢 1 +x:1 +□ 3 +x:3 +横放 1 +x:1 +盐碱 1 +x:1 +黄 1310 +x:1310 +按期 1 +x:1 +涩味 1 +x:1 +挂屏 1 +x:1 +长女 1 +x:1 +勇做 1 +x:1 +至友 1 +x:1 +中革军委 1 +x:1 +锻锤 1 +x:1 +含尘量 1 +x:1 +调频 1 +x:1 +里应外合 1 +x:1 +阿弟 1 +x:1 +革吉县 1 +x:1 +地址 1 +x:1 +天狗 1 +x:1 +阿式 1 +x:1 +登杆塔 1 +x:1 +芝麻酱 1 +x:1 +戒急用忍 1 +x:1 +广渠门 1 +x:1 +弯弯处 1 +x:1 +初雪 1 +x:1 +葡萄干 1 +x:1 +量纪 1 +x:1 +纸本 1 +x:1 +量级 1 +x:1 +平抑 1 +x:1 +煤渣 1 +x:1 +优中择优 1 +x:1 +软土区 1 +x:1 +维修者 1 +x:1 +初霁 1 +x:1 +刀会 1 +x:1 +帚 1 +x:1 +营地 1 +x:1 +瞟 2 +x:2 +白云村 1 +x:1 +肠胃 1 +x:1 +隐隐 1 +x:1 +姚 222 +x:222 +勇决 1 +x:1 +刀伤 1 +x:1 +初露 1 +x:1 +归属 1 +x:1 +第 9 +x:9 +井筒 1 +x:1 +路政 1 +x:1 +子课题 1 +x:1 +锻铁 1 +x:1 +巧言如簧 1 +x:1 +婴孩 1 +x:1 +磁 13 +x:13 +都江堰 1 +x:1 +病入膏肓 1 +x:1 +国药城 1 +x:1 +纸条 1 +x:1 +平拉 1 +x:1 +新鲜 1 +x:1 +门神 1 +x:1 +寿面 1 +x:1 +特急件 1 +x:1 +】 2 +x:2 +冷射 1 +x:1 +技高一筹 1 +x:1 +农械 1 +x:1 +当当 1 +x:1 +当归 1 +x:1 +呈现 1 +x:1 +搓洗 1 +x:1 +核桃壳 1 +x:1 +稽查局 1 +x:1 +和裁会 1 +x:1 +作品展 1 +x:1 +绝活儿 1 +x:1 +钢绞线 1 +x:1 +代替论 1 +x:1 +壁板 1 +x:1 +路数 1 +x:1 +平战 1 +x:1 +倒刺 1 +x:1 +农桑 1 +x:1 +庆祝性 1 +x:1 +冷峭 1 +x:1 +参体 1 +x:1 +禁酒令 1 +x:1 +深切 1 +x:1 +长堤 1 +x:1 +冷峻 1 +x:1 +冠子 1 +x:1 +基建队 1 +x:1 +壕沟 1 +x:1 +麦角酸 1 +x:1 +平房 1 +x:1 +玉林井村 1 +x:1 +深刻 1 +x:1 +粤东 1 +x:1 +开播 1 +x:1 +天王 1 +x:1 +亭长 1 +x:1 +冲天 1 +x:1 +煤源 1 +x:1 +详情 1 +x:1 +通明 1 +x:1 +嫂 5 +x:5 +覆盆之冤 1 +x:1 +实测值 1 +x:1 +钙剂 1 +x:1 +编织厂 1 +x:1 +平手 1 +x:1 +曲率 1 +x:1 +万难不却 1 +x:1 +法力 1 +x:1 +勇克 1 +x:1 +壁柜 1 +x:1 +古城镇 1 +x:1 +更年期 1 +x:1 +中继者 1 +x:1 +源口 1 +x:1 +草标儿 1 +x:1 +怔忡 1 +x:1 +音乐迷 1 +x:1 +壁柱 1 +x:1 +得陇望蜀 1 +x:1 +呈献 1 +x:1 +单纯词 1 +x:1 +法律部 1 +x:1 +当心 1 +x:1 +国产棉 1 +x:1 +阿市 1 +x:1 +宁 225 +x:225 +伐区 1 +x:1 +滚雪球 1 +x:1 +义务性 1 +x:1 +伊埃纳宫 1 +x:1 +抱病 1 +x:1 +开朗 1 +x:1 +中医药界 1 +x:1 +铁矿石 1 +x:1 +有眼无珠 1 +x:1 +琉璃 1 +x:1 +邮政编码 1 +x:1 +信丰县 1 +x:1 +赘物 1 +x:1 +丹东市 1 +x:1 +深冷 1 +x:1 +长官 1 +x:1 +聪明才智 1 +x:1 +珍宝馆 1 +x:1 +缠住 1 +x:1 +开本 1 +x:1 +按时 1 +x:1 +秘方 1 +x:1 +长安 1 +x:1 +胸口 1 +x:1 +棒槌 1 +x:1 +毛细现象 1 +x:1 +神 157 +x:157 +深冬 1 +x:1 +长宁 1 +x:1 +长寿 1 +x:1 +主谋者 1 +x:1 +开杆 1 +x:1 +耐穿透性 1 +x:1 +天灾 1 +x:1 +屠戮 1 +x:1 +圈套 1 +x:1 +扁柏 1 +x:1 +气轮机 1 +x:1 +批批 1 +x:1 +下周三 1 +x:1 +天火 1 +x:1 +天灯 1 +x:1 +粘土矿 1 +x:1 +下周一 1 +x:1 +煤海 1 +x:1 +肺叶 1 +x:1 +铅垂线 1 +x:1 +询问者 1 +x:1 +耻辱榜 1 +x:1 +协奏 1 +x:1 +预定金 1 +x:1 +秘旨 1 +x:1 +毡包 1 +x:1 +局级 1 +x:1 +眼药水 1 +x:1 +开来 1 +x:1 +建言 1 +x:1 +荣将 1 +x:1 +取息 1 +x:1 +成套率 1 +x:1 +凉药 1 +x:1 +现存量 1 +x:1 +当局 1 +x:1 +科迪亚克 1 +x:1 +灿烂 1 +x:1 +伴舞 1 +x:1 +挂帅 1 +x:1 +后现代 1 +x:1 +审判 1 +x:1 +降价年 1 +x:1 +选例板 1 +x:1 +报关单 1 +x:1 +锰矿 1 +x:1 +挂帐 1 +x:1 +纽扣 1 +x:1 +电动势 1 +x:1 +9 626 +x:626 +农歌 1 +x:1 +净菜行 1 +x:1 +困扰 1 +x:1 +滚动 1 +x:1 +姓名论 1 +x:1 +荒寒 1 +x:1 +安分守己 1 +x:1 +挂席 1 +x:1 +机械泵 1 +x:1 +阳 83 +x:83 +呆愣愣 1 +x:1 +开架 1 +x:1 +杨家沟 1 +x:1 +归心 1 +x:1 +负罪感 1 +x:1 +横杆 1 +x:1 +躯壳 1 +x:1 +杭纺 1 +x:1 +灿灿 1 +x:1 +副手 1 +x:1 +凉菜 1 +x:1 +当头棒喝 1 +x:1 +僧尼 1 +x:1 +长衫族 1 +x:1 +畜群 1 +x:1 +劳民伤财 1 +x:1 +青花盘 1 +x:1 +闪闪 1 +x:1 +尼姑庵 1 +x:1 +急不可待 1 +x:1 +仁人志士 1 +x:1 +敷料单 1 +x:1 +长孙 1 +x:1 +长存 1 +x:1 +良苦用心 1 +x:1 +上上下下 1 +x:1 +旅行车 1 +x:1 +臭虫 1 +x:1 +长子 1 +x:1 +勰 12 +x:12 +茅房 1 +x:1 +夜报 1 +x:1 +深入 1 +x:1 +团体照 1 +x:1 +多半数 1 +x:1 +归并 1 +x:1 +砂 24 +x:24 +成型件 1 +x:1 +村村寨寨 1 +x:1 +军政后 1 +x:1 +建警 1 +x:1 +开明 1 +x:1 +天然 1 +x:1 +猩猩 1 +x:1 +闷头 1 +x:1 +冷干 1 +x:1 +隔音纸 1 +x:1 +衣来伸手 1 +x:1 +粮食点 1 +x:1 +这项 1 +x:1 +台山市 1 +x:1 +知无不言 1 +x:1 +开春 1 +x:1 +雨帽 1 +x:1 +哲学 1 +x:1 +铁合金 1 +x:1 +钵 3 +x:3 +百态纷呈 1 +x:1 +贩销 1 +x:1 +煤气 1 +x:1 +乱购 1 +x:1 +耗子 1 +x:1 +致辞 1 +x:1 +生气 1 +x:1 +秤毫 1 +x:1 +挂心 1 +x:1 +横暴 1 +x:1 +锋利 1 +x:1 +虚症 1 +x:1 +路权 1 +x:1 +华大 1 +x:1 +沟坎 1 +x:1 +车尾 1 +x:1 +样本量 1 +x:1 +吏制 1 +x:1 +回避制 1 +x:1 +安全区 1 +x:1 +脸蛋 1 +x:1 +冷布 1 +x:1 +臧 17 +x:17 +华夏 1 +x:1 +测绘局 1 +x:1 +路条 1 +x:1 +以诚相见 1 +x:1 +挂念 1 +x:1 +归帆 1 +x:1 +孔型 1 +x:1 +不由得 1 +x:1 +外运量 1 +x:1 +批捕 1 +x:1 +虚化 1 +x:1 +净收入 1 +x:1 +灿然 1 +x:1 +樟树 1 +x:1 +行若无事 1 +x:1 +主罚 1 +x:1 +策士 1 +x:1 +坎伯岚 1 +x:1 +煤油 1 +x:1 +烦心事 1 +x:1 +机械 1 +x:1 +黔西南 1 +x:1 +晨报 1 +x:1 +炕柜 1 +x:1 +三民主义 1 +x:1 +腺细胞 1 +x:1 +小三轮 1 +x:1 +芦 2 +x:2 +巴利阿里 1 +x:1 +水漂 1 +x:1 +退机率 1 +x:1 +挡热层 1 +x:1 +混纺 1 +x:1 +按摩 1 +x:1 +乱跑 1 +x:1 +建议 1 +x:1 +马桶盖 1 +x:1 +冲子 1 +x:1 +相会 1 +x:1 +煤泥 1 +x:1 +目鱼 1 +x:1 +建设 1 +x:1 +当差 1 +x:1 +异兽 1 +x:1 +没空 1 +x:1 +摄谱仪 1 +x:1 +居民点 1 +x:1 +圆山 1 +x:1 +佣 1 +x:1 +千真万确 1 +x:1 +马鞍山 1 +x:1 +阿尔 1 +x:1 +机检 1 +x:1 +冷床 1 +x:1 +养鹿业 1 +x:1 +冷库 1 +x:1 +中西部 1 +x:1 +果品厂 1 +x:1 +钻探机 1 +x:1 +安全员 1 +x:1 +营利 1 +x:1 +平果 1 +x:1 +炉坑 1 +x:1 +盐类 1 +x:1 +扩音 1 +x:1 +中西药业 1 +x:1 +木靶 1 +x:1 +下意识 1 +x:1 +话里有话 1 +x:1 +如此这般 1 +x:1 +空心棒 1 +x:1 +有朝一日 1 +x:1 +超自然 1 +x:1 +火墙子 1 +x:1 +华年 1 +x:1 +寄托感 1 +x:1 +婴幼 1 +x:1 +澄澈 1 +x:1 +检查者 1 +x:1 +牙口 1 +x:1 +黄山站 1 +x:1 +稽查处 1 +x:1 +按揭 1 +x:1 +益阳 1 +x:1 +组编 1 +x:1 +忠实 1 +x:1 +躯干 1 +x:1 +局 717 +x:717 +一忽儿 1 +x:1 +沤粪 1 +x:1 +大包干 1 +x:1 +癞皮狗 1 +x:1 +冷天 1 +x:1 +卢沟桥乡 1 +x:1 +零配件 1 +x:1 +圆寂 1 +x:1 +妖魔鬼怪 1 +x:1 +年过花甲 1 +x:1 +显要 1 +x:1 +长工 1 +x:1 +万鼓催春 1 +x:1 +归天 1 +x:1 +芦柞乡 1 +x:1 +代办 1 +x:1 +取景 1 +x:1 +警世钟 1 +x:1 +攀枝花市 1 +x:1 +灶神 1 +x:1 +彗星队 1 +x:1 +圈形 1 +x:1 +归复 1 +x:1 +一中一台 1 +x:1 +祖国 1 +x:1 +卓尔不群 1 +x:1 +铀 9 +x:9 +夺冠 1 +x:1 +井绳 1 +x:1 +平朔 1 +x:1 +柿皮 1 +x:1 +畹町河 1 +x:1 +客户群 1 +x:1 +平服 1 +x:1 +昏迷 1 +x:1 +曲直 1 +x:1 +深圳 1 +x:1 +壁报 1 +x:1 +养车户 1 +x:1 +速战速决 1 +x:1 +养家活口 1 +x:1 +磁芯 1 +x:1 +译本 1 +x:1 +迂夫子 1 +x:1 +长崎 1 +x:1 +井组 1 +x:1 +曲目 1 +x:1 +蔚山 1 +x:1 +天皇 1 +x:1 +圆子 1 +x:1 +醉生梦死 1 +x:1 +光谱线 1 +x:1 +祝福词 1 +x:1 +马鞍子 1 +x:1 +积蓄 1 +x:1 +晨时 1 +x:1 +残局 1 +x:1 +一星半点 1 +x:1 +晓得 1 +x:1 +苔 2 +x:2 +楚楚 1 +x:1 +天目 1 +x:1 +冷水滩 1 +x:1 +风险源 1 +x:1 +金篾 1 +x:1 +夏河 1 +x:1 +板面 1 +x:1 +失眠病 1 +x:1 +盐粒 1 +x:1 +基民盟 1 +x:1 +平方毫米 1 +x:1 +失而复得 1 +x:1 +平板 1 +x:1 +惨 12 +x:12 +二轻 1 +x:1 +农活 1 +x:1 +丹顶鹤 1 +x:1 +牙医 1 +x:1 +华府 1 +x:1 +飞禽走兽 1 +x:1 +楹 4 +x:4 +杯 200 +x:200 +懊丧 1 +x:1 +煤毒 1 +x:1 +量筒 1 +x:1 +华彩 1 +x:1 +交警队 1 +x:1 +壁挂 1 +x:1 +荒山 1 +x:1 +潺潺流水 1 +x:1 +虚玄 1 +x:1 +秘技 1 +x:1 +开班式 1 +x:1 +涂膜剂 1 +x:1 +批改 1 +x:1 +调整日 1 +x:1 +长岭 1 +x:1 +营区 1 +x:1 +公明镇 1 +x:1 +建起 1 +x:1 +上梅洲 1 +x:1 +板障 1 +x:1 +长岛 1 +x:1 +天真 1 +x:1 +心急者 1 +x:1 +蔽塞 1 +x:1 +明枪暗箭 1 +x:1 +涎皮赖脸 1 +x:1 +络 6 +x:6 +务虚会 1 +x:1 +吏员 1 +x:1 +告别室 1 +x:1 +放虎归山 1 +x:1 +新寮镇 1 +x:1 +韧劲 1 +x:1 +嵩县 1 +x:1 +佃权 1 +x:1 +建账 1 +x:1 +九龙 1 +x:1 +取材 1 +x:1 +北威州 1 +x:1 +感觉 1 +x:1 +十二点 1 +x:1 +电位差 1 +x:1 +感观 1 +x:1 +竞技体操 1 +x:1 +直溜溜 1 +x:1 +新叶村 1 +x:1 +拔丝 1 +x:1 +评议权 1 +x:1 +舌根音 1 +x:1 +通报 1 +x:1 +开恩 1 +x:1 +神魂颠倒 1 +x:1 +僧官 1 +x:1 +火力点 1 +x:1 +感触 1 +x:1 +积蕴 1 +x:1 +响水 1 +x:1 +树枝状 1 +x:1 +通才 1 +x:1 +建路 1 +x:1 +大写意 1 +x:1 +当家 1 +x:1 +声如洪钟 1 +x:1 +斐 24 +x:24 +骨干 1 +x:1 +曲高和寡 1 +x:1 +笔记簿 1 +x:1 +邦迪 1 +x:1 +保障线 1 +x:1 +当官 1 +x:1 +量程 1 +x:1 +漠风 1 +x:1 +总价值 1 +x:1 +批文 1 +x:1 +木雕 1 +x:1 +副攻 1 +x:1 +挂失 1 +x:1 +沉积岩 1 +x:1 +爱国志士 1 +x:1 +阿婆 1 +x:1 +批斗 1 +x:1 +敖汉旗 1 +x:1 +废话 1 +x:1 +热柯党乡 1 +x:1 +农民 1 +x:1 +一败如水 1 +x:1 +邦达 1 +x:1 +锻造 1 +x:1 +养蚕业 1 +x:1 +稚气 1 +x:1 +荒岭 1 +x:1 +知心话 1 +x:1 +九鼎 1 +x:1 +和颜悦色 1 +x:1 +祖坟 1 +x:1 +农水 1 +x:1 +音乐课 1 +x:1 +一溜儿 1 +x:1 +风气 1 +x:1 +全军覆没 1 +x:1 +动力处 1 +x:1 +绝对真理 1 +x:1 +牙刷 1 +x:1 +长局 1 +x:1 +医药学家 1 +x:1 +初速 1 +x:1 +夜晚 1 +x:1 +施工 1 +x:1 +夏湾 1 +x:1 +开挖 1 +x:1 +猢狲 1 +x:1 +阿姨 1 +x:1 +华山 1 +x:1 +初选 1 +x:1 +冲床 1 +x:1 +国境线 1 +x:1 +窘迫 1 +x:1 +平方 1 +x:1 +华屋 1 +x:1 +华居 1 +x:1 +阿姐 1 +x:1 +任人摆布 1 +x:1 +当堂 1 +x:1 +天球 1 +x:1 +克隆羊 1 +x:1 +长征 1 +x:1 +没羞 1 +x:1 +纺织娘 1 +x:1 +共青 1 +x:1 +阿妹 1 +x:1 +美国式 1 +x:1 +国际队 1 +x:1 +传送 1 +x:1 +夺占 1 +x:1 +有名有利 1 +x:1 +簿记 1 +x:1 +违者 1 +x:1 +正步 1 +x:1 +献瑞 1 +x:1 +板门 1 +x:1 +冒险 1 +x:1 +班长鞋 1 +x:1 +那会儿 1 +x:1 +呜呼 1 +x:1 +枯木 1 +x:1 +樊篱 1 +x:1 +横排 1 +x:1 +冷水江 1 +x:1 +支座 1 +x:1 +情人 1 +x:1 +阿妈 1 +x:1 +仓促 1 +x:1 +平日 1 +x:1 +畏首畏尾 1 +x:1 +娃 19 +x:19 +采伐 1 +x:1 +青衣 1 +x:1 +商业街 1 +x:1 +编织品 1 +x:1 +木门 1 +x:1 +浇地费 1 +x:1 +虎骨酒 1 +x:1 +河沟 1 +x:1 +开掘 1 +x:1 +峻岭 1 +x:1 +感言 1 +x:1 +养伤 1 +x:1 +饭店化 1 +x:1 +呜咽 1 +x:1 +崭 1 +x:1 +埃夫拉特 1 +x:1 +吃喝风 1 +x:1 +板锉 1 +x:1 +山道年 1 +x:1 +休火山 1 +x:1 +堞 1 +x:1 +环音 1 +x:1 +牙具 1 +x:1 +楚歌 1 +x:1 +条形码 1 +x:1 +瓜子脸 1 +x:1 +冷宫 1 +x:1 +产棉区 1 +x:1 +长影 1 +x:1 +麦盖提乡 1 +x:1 +通感 1 +x:1 +冷害 1 +x:1 +大少爷 1 +x:1 +华岳 1 +x:1 +冒雨 1 +x:1 +名声鹊起 1 +x:1 +豁出 1 +x:1 +优胜赛 1 +x:1 +虚火 1 +x:1 +三洞桥 1 +x:1 +北京道 1 +x:1 +平整 1 +x:1 +扩销 1 +x:1 +夺取 1 +x:1 +精卫填海 1 +x:1 +磁能 1 +x:1 +皮革店 1 +x:1 +宋朝 1 +x:1 +咸乎乎 1 +x:1 +荒年 1 +x:1 +中国馆 1 +x:1 +北轻汽 1 +x:1 +沟北 1 +x:1 +滚圆 1 +x:1 +载重车 1 +x:1 +天电 1 +x:1 +当头 1 +x:1 +彩色棉 1 +x:1 +当天 1 +x:1 +致词 1 +x:1 +中农 1 +x:1 +长座 1 +x:1 +长度 1 +x:1 +开战 1 +x:1 +圈将 1 +x:1 +不用说 1 +x:1 +温病学 1 +x:1 +晨星 1 +x:1 +另外 1 +x:1 +当夜 1 +x:1 +一等功 1 +x:1 +叛臣 1 +x:1 +横拍 1 +x:1 +斯特鲁加 1 +x:1 +晨昏 1 +x:1 +长庆 1 +x:1 +北道区 1 +x:1 +扁担 1 +x:1 +坠入 1 +x:1 +批条 1 +x:1 +咽峡炎 1 +x:1 +溪沟 1 +x:1 +唯物论 1 +x:1 +营养 1 +x:1 +圈层 1 +x:1 +桥 192 +x:192 +营具 1 +x:1 +短尾猴 1 +x:1 +北面 1 +x:1 +安全地 1 +x:1 +感说 1 +x:1 +晨晖 1 +x:1 +大五金 1 +x:1 +助益 1 +x:1 +拷打 1 +x:1 +长廊 1 +x:1 +友好路 1 +x:1 +口哨声 1 +x:1 +安徽籍 1 +x:1 +备用 1 +x:1 +登机口 1 +x:1 +九一年 1 +x:1 +横批 1 +x:1 +青壮年人 1 +x:1 +到期日 1 +x:1 +动力学 1 +x:1 +华工 1 +x:1 +冲开 1 +x:1 +机油 1 +x:1 +横扫 1 +x:1 +伯祖 1 +x:1 +命乖运蹇 1 +x:1 +横执 1 +x:1 +茅村 1 +x:1 +渡 49 +x:49 +慈善家 1 +x:1 +副本 1 +x:1 +神似 1 +x:1 +原产地 1 +x:1 +娇艳欲滴 1 +x:1 +隐退 1 +x:1 +珍藏版 1 +x:1 +绳断 1 +x:1 +伊比利亚 1 +x:1 +神伤 1 +x:1 +匹比 1 +x:1 +刊物 1 +x:1 +尼克松 1 +x:1 +梨花 1 +x:1 +渑池县 1 +x:1 +操作间 1 +x:1 +长年 1 +x:1 +亮亮堂堂 1 +x:1 +孕期 1 +x:1 +开拍 1 +x:1 +安全型 1 +x:1 +新建路 1 +x:1 +神位 1 +x:1 +开拔 1 +x:1 +兔唇 1 +x:1 +脸色 1 +x:1 +晨曦 1 +x:1 +水准器 1 +x:1 +苟安 1 +x:1 +通性 1 +x:1 +施射 1 +x:1 +隐遁 1 +x:1 +走捷径 1 +x:1 +沟口 1 +x:1 +墨守成规 1 +x:1 +曲沃县 1 +x:1 +许家坝 1 +x:1 +九龙杯 1 +x:1 +怀 97 +x:97 +缝缝 1 +x:1 +小瓶装 1 +x:1 +中等级 1 +x:1 +啊啊 1 +x:1 +手不释卷 1 +x:1 +侮 1 +x:1 +媒质 1 +x:1 +沈厅 1 +x:1 +火控 1 +x:1 +谷城 1 +x:1 +终究 1 +x:1 +售蛋亭 1 +x:1 +贻患无穷 1 +x:1 +洲际导弹 1 +x:1 +述古 1 +x:1 +兵营 1 +x:1 +闹醒 1 +x:1 +公安军 1 +x:1 +千刀万剐 1 +x:1 +蝇粪点玉 1 +x:1 +睦邻 1 +x:1 +憨劲 1 +x:1 +事典 1 +x:1 +流离失所 1 +x:1 +宫刑 1 +x:1 +全副 1 +x:1 +乳母 1 +x:1 +全剧 1 +x:1 +逆风 1 +x:1 +红唇 1 +x:1 +快车 1 +x:1 +软环境 1 +x:1 +鲜花 1 +x:1 +消防费 1 +x:1 +竹黄 1 +x:1 +孔孟之道 1 +x:1 +绘图 1 +x:1 +铧犁 1 +x:1 +赭色 1 +x:1 +乌龟 1 +x:1 +台侨 1 +x:1 +灯绳 1 +x:1 +季世 1 +x:1 +揳入 1 +x:1 +乌龙 1 +x:1 +油腔滑调 1 +x:1 +海欣 1 +x:1 +终竟 1 +x:1 +枝蔓 1 +x:1 +竹鸡 1 +x:1 +死亡线 1 +x:1 +老调 1 +x:1 +公关部 1 +x:1 +颐 1 +x:1 +虔敬 1 +x:1 +缕 23 +x:23 +新龙华 1 +x:1 +了如指掌 1 +x:1 +赅 1 +x:1 +主表 1 +x:1 +全力 1 +x:1 +鼻子 1 +x:1 +鲜艳 1 +x:1 +鼻孔 1 +x:1 +贯流式 1 +x:1 +聚乙烯 1 +x:1 +胡兰村 1 +x:1 +谷坊 1 +x:1 +是 66090 +x:66090 +脱氧剂 1 +x:1 +天疱疮 1 +x:1 +烟火 1 +x:1 +终端 1 +x:1 +鸡首 1 +x:1 +浩繁 1 +x:1 +咸 12 +x:12 +微露 1 +x:1 +非石油 1 +x:1 +不变资本 1 +x:1 +垂拂 1 +x:1 +飞翔 1 +x:1 +卷舌音 1 +x:1 +静者 1 +x:1 +例行公事 1 +x:1 +北街 1 +x:1 +潮白河畔 1 +x:1 +台企 1 +x:1 +巨轮 1 +x:1 +屏 3 +x:3 +谷地 1 +x:1 +驳杂 1 +x:1 +愿谢 1 +x:1 +全勤 1 +x:1 +大力士 1 +x:1 +唐诗 1 +x:1 +上饶 1 +x:1 +照章办事 1 +x:1 +要目 1 +x:1 +清查 1 +x:1 +玉溪 1 +x:1 +详细 1 +x:1 +火捻 1 +x:1 +向上 1 +x:1 +闲杂人员 1 +x:1 +自动线 1 +x:1 +单轨 1 +x:1 +全区 1 +x:1 +理工大 1 +x:1 +上颚 1 +x:1 +交通警 1 +x:1 +火把 1 +x:1 +鲜菜 1 +x:1 +上颌 1 +x:1 +鲜菇 1 +x:1 +日高峰 1 +x:1 +作战区 1 +x:1 +太岳区 1 +x:1 +主角 1 +x:1 +亭台楼榭 1 +x:1 +单车 1 +x:1 +法治 1 +x:1 +叶肉 1 +x:1 +中省直 1 +x:1 +台份 1 +x:1 +主观 1 +x:1 +主见 1 +x:1 +试试看 1 +x:1 +先天性 1 +x:1 +生母 1 +x:1 +团伙 1 +x:1 +现实主义 1 +x:1 +绝倒 1 +x:1 +买路钱 1 +x:1 +假面舞 1 +x:1 +三倍体 1 +x:1 +读书 1 +x:1 +幕天席地 1 +x:1 +虚 100 +x:100 +先斩后奏 1 +x:1 +科教文 1 +x:1 +害处 1 +x:1 +管见 1 +x:1 +外盘期货 1 +x:1 +五间坊村 1 +x:1 +忙碌不堪 1 +x:1 +隆起 1 +x:1 +大公报 1 +x:1 +梵净山 1 +x:1 +持械 1 +x:1 +主要 1 +x:1 +奇士谋臣 1 +x:1 +团体 1 +x:1 +遍地开花 1 +x:1 +校准器 1 +x:1 +全县 1 +x:1 +合宜 1 +x:1 +称做 1 +x:1 +扫雷器 1 +x:1 +家属楼 1 +x:1 +撒玛拉 1 +x:1 +逸彩 1 +x:1 +慈利县 1 +x:1 +颓靡 1 +x:1 +鲜草 1 +x:1 +琴房 1 +x:1 +合容 1 +x:1 +戊寅年 1 +x:1 +思考题 1 +x:1 +缝线 1 +x:1 +合家 1 +x:1 +陈兵 1 +x:1 +欢乐树 1 +x:1 +评估组 1 +x:1 +谈心站 1 +x:1 +拉环 1 +x:1 +全厂 1 +x:1 +烟煤 1 +x:1 +加布罗沃 1 +x:1 +缝纫 1 +x:1 +雇用 1 +x:1 +乌鸦 1 +x:1 +墓场 1 +x:1 +火扇 1 +x:1 +微降 1 +x:1 +燎原之势 1 +x:1 +墓地 1 +x:1 +前 5107 +x:5107 +海运界 1 +x:1 +中山站 1 +x:1 +翔 31 +x:31 +伀法 1 +x:1 +台上 1 +x:1 +台下 1 +x:1 +远东局 1 +x:1 +支持率 1 +x:1 +灯罩 1 +x:1 +登联 1 +x:1 +所在 1 +x:1 +基本矛盾 1 +x:1 +骨气 1 +x:1 +称之为 1 +x:1 +波浪鼓 1 +x:1 +贼赃 1 +x:1 +定日 1 +x:1 +甲日乡 1 +x:1 +千言万语 1 +x:1 +台中 1 +x:1 +布告 1 +x:1 +门楣子 1 +x:1 +沈农 1 +x:1 +冠以 1 +x:1 +便捷 1 +x:1 +丈 17 +x:17 +业经 1 +x:1 +济世之志 1 +x:1 +圆周 1 +x:1 +公安县 1 +x:1 +窗帘 1 +x:1 +公安厅 1 +x:1 +称号 1 +x:1 +犯罪感 1 +x:1 +鲜能 1 +x:1 +江米 1 +x:1 +模式 1 +x:1 +值日生 1 +x:1 +残毒 1 +x:1 +悼唁 1 +x:1 +升升降降 1 +x:1 +消防艇 1 +x:1 +受损失者 1 +x:1 +宝窟 1 +x:1 +驳斥 1 +x:1 +菁 13 +x:13 +消防船 1 +x:1 +达令港 1 +x:1 +南极圈 1 +x:1 +薪水 1 +x:1 +钟鼓 1 +x:1 +无名氏 1 +x:1 +狐臊 1 +x:1 +抱头痛哭 1 +x:1 +月利率 1 +x:1 +快赛 1 +x:1 +浸入 1 +x:1 +华盛顿州 1 +x:1 +鲜肉 1 +x:1 +国债率 1 +x:1 +微闭 1 +x:1 +抬杠 1 +x:1 +大整大肃 1 +x:1 +兴国县 1 +x:1 +忠贞不二 1 +x:1 +天元战 1 +x:1 +政治性 1 +x:1 +红土 1 +x:1 +券别 1 +x:1 +巨贾 1 +x:1 +滞后 1 +x:1 +发布会 1 +x:1 +空阔无垠 1 +x:1 +飞舟 1 +x:1 +剩饭 1 +x:1 +张弓 1 +x:1 +掖 5 +x:5 +巨财 1 +x:1 +烟卷店 1 +x:1 +下同 1 +x:1 +荒烟 1 +x:1 +基音 1 +x:1 +沙棘丛 1 +x:1 +硕学耆老 1 +x:1 +候审 1 +x:1 +兴致 1 +x:1 +抬枪 1 +x:1 +绝句 1 +x:1 +日进斗金 1 +x:1 +开发者 1 +x:1 +绝口 1 +x:1 +拉炮 1 +x:1 +二甲胺 1 +x:1 +评法批儒 1 +x:1 +校门口 1 +x:1 +航空界 1 +x:1 +马家窑 1 +x:1 +高涧 1 +x:1 +辜负 1 +x:1 +陈列 1 +x:1 +油嘴 1 +x:1 +水果盘 1 +x:1 +英才 1 +x:1 +边上市 1 +x:1 +缺字 1 +x:1 +农牧业部 1 +x:1 +合声 1 +x:1 +兜揽 1 +x:1 +滥伐 1 +x:1 +层林 1 +x:1 +百老汇 1 +x:1 +为人注意 1 +x:1 +赝本 1 +x:1 +巨资 1 +x:1 +国际公法 1 +x:1 +西八间房 1 +x:1 +国画室 1 +x:1 +同声 1 +x:1 +窗式 1 +x:1 +纠风 1 +x:1 +主课 1 +x:1 +打尖 1 +x:1 +犯罪性 1 +x:1 +崔 272 +x:272 +叶酸 1 +x:1 +牛脾气 1 +x:1 +银须 1 +x:1 +石阶道 1 +x:1 +主语 1 +x:1 +委靡 1 +x:1 +火患 1 +x:1 +飞来石 1 +x:1 +执业资格 1 +x:1 +凉开水 1 +x:1 +训导员 1 +x:1 +标的额 1 +x:1 +手链 1 +x:1 +巩义 1 +x:1 +万鹤 1 +x:1 +孟 290 +x:290 +心腹之患 1 +x:1 +装船 1 +x:1 +主词 1 +x:1 +便所 1 +x:1 +照样 1 +x:1 +主讲 1 +x:1 +底儿 1 +x:1 +五年期 1 +x:1 +火情 1 +x:1 +海棠 1 +x:1 +提携 1 +x:1 +全关 1 +x:1 +藏书票 1 +x:1 +特此 1 +x:1 +支队长 1 +x:1 +合奏 1 +x:1 +全党 1 +x:1 +蒙彼利埃 1 +x:1 +喝声 1 +x:1 +长线产品 1 +x:1 +新闻部 1 +x:1 +留置权 1 +x:1 +先入者 1 +x:1 +口陈肝胆 1 +x:1 +无心恋战 1 +x:1 +爱岗敬业 1 +x:1 +学生处 1 +x:1 +晒台 1 +x:1 +请客 1 +x:1 +风雨凄凄 1 +x:1 +旅客量 1 +x:1 +诸暨 1 +x:1 +提擢 1 +x:1 +制衣 1 +x:1 +修润 1 +x:1 +震毁 1 +x:1 +全权代表 1 +x:1 +全军 1 +x:1 +圣 14 +x:14 +特殊 1 +x:1 +火性 1 +x:1 +火急 1 +x:1 +到此一游 1 +x:1 +粪 26 +x:26 +奋发 1 +x:1 +荒滩地 1 +x:1 +半途 1 +x:1 +别开生面 1 +x:1 +西坡柏乡 1 +x:1 +毒理学 1 +x:1 +耽心 1 +x:1 +粤南 1 +x:1 +溪口 1 +x:1 +溯至 1 +x:1 +火烧山 1 +x:1 +免除 1 +x:1 +停止不前 1 +x:1 +碎语 1 +x:1 +宫内 1 +x:1 +泉沟镇 1 +x:1 +裸机 1 +x:1 +沟通者 1 +x:1 +展 131 +x:131 +言听计从 1 +x:1 +迢迢渺渺 1 +x:1 +毛巾被 1 +x:1 +瓮中捉鳖 1 +x:1 +蛤蟆街 1 +x:1 +名优特产 1 +x:1 +上马 1 +x:1 +底册 1 +x:1 +含苞待放 1 +x:1 +七十二行 1 +x:1 +多普尔 1 +x:1 +粤北 1 +x:1 +一不小心 1 +x:1 +收费路 1 +x:1 +晒烟 1 +x:1 +谷口 1 +x:1 +南极光 1 +x:1 +无冬眠 1 +x:1 +新仇旧恨 1 +x:1 +运走 1 +x:1 +细胞 1 +x:1 +公估行 1 +x:1 +不可多得 1 +x:1 +俗体字 1 +x:1 +非职业 1 +x:1 +鲜蛋 1 +x:1 +桥岩山 1 +x:1 +旦夕存亡 1 +x:1 +扎兰屯市 1 +x:1 +从轮 1 +x:1 +拉动 1 +x:1 +火枪 1 +x:1 +旧故 1 +x:1 +亲爱的 1 +x:1 +售卖 1 +x:1 +眺望 1 +x:1 +襄城县 1 +x:1 +区 857 +x:857 +保险者 1 +x:1 +红党 1 +x:1 +银鼠 1 +x:1 +陆战队 1 +x:1 +污垢 1 +x:1 +传送带 1 +x:1 +大脑炎 1 +x:1 +经营科 1 +x:1 +哆来咪 1 +x:1 +老黄历 1 +x:1 +杀伤 1 +x:1 +沈城 1 +x:1 +前胸袋 1 +x:1 +信据 1 +x:1 +紧缩型 1 +x:1 +挛缩 1 +x:1 +庙宇镇 1 +x:1 +填表权 1 +x:1 +绝唱 1 +x:1 +继 272 +x:272 +翠菊 1 +x:1 +合并 1 +x:1 +浙江省乡 1 +x:1 +巧妙 1 +x:1 +视力表 1 +x:1 +透明体 1 +x:1 +火柱 1 +x:1 +火柴 1 +x:1 +玉帛 1 +x:1 +警风 1 +x:1 +可离性 1 +x:1 +务在 1 +x:1 +偷税案 1 +x:1 +银花霓影 1 +x:1 +仍旧 1 +x:1 +探测车 1 +x:1 +麦穗儿 1 +x:1 +琴棋书画 1 +x:1 +两面派 1 +x:1 +烛光 1 +x:1 +半斤八两 1 +x:1 +胡须 1 +x:1 +红净 1 +x:1 +历史者 1 +x:1 +表现欲 1 +x:1 +拌种 1 +x:1 +登山路 1 +x:1 +审计官 1 +x:1 +祸起萧墙 1 +x:1 +矿床 1 +x:1 +风动石 1 +x:1 +快论 1 +x:1 +绘制 1 +x:1 +江底 1 +x:1 +稿 94 +x:94 +嘉黎县 1 +x:1 +美男子 1 +x:1 +芭蕾舞 1 +x:1 +全国 1 +x:1 +泪滴 1 +x:1 +海潮 1 +x:1 +不攻自破 1 +x:1 +教科省 1 +x:1 +外长 1 +x:1 +钢球 1 +x:1 +细者 1 +x:1 +全园 1 +x:1 +全团 1 +x:1 +爬墙虎 1 +x:1 +皮艇 1 +x:1 +鼻弯 1 +x:1 +合建 1 +x:1 +终线 1 +x:1 +摩纳哥队 1 +x:1 +拉直 1 +x:1 +排水闸 1 +x:1 +主调 1 +x:1 +责罚 1 +x:1 +国画展 1 +x:1 +布势 1 +x:1 +一语中的 1 +x:1 +主谋 1 +x:1 +喝彩 1 +x:1 +红军 1 +x:1 +全场 1 +x:1 +合浦还珠 1 +x:1 +发痧 1 +x:1 +交通车 1 +x:1 +社兰村 1 +x:1 +血液病 1 +x:1 +窗外 1 +x:1 +小商贩 1 +x:1 +族人 1 +x:1 +英文 1 +x:1 +特派 1 +x:1 +合开 1 +x:1 +主跨 1 +x:1 +涎水 1 +x:1 +前卫镇 1 +x:1 +正儿八经 1 +x:1 +细致 1 +x:1 +英方 1 +x:1 +汤锅 1 +x:1 +灯管 1 +x:1 +浅红 1 +x:1 +史书 1 +x:1 +不锈钢板 1 +x:1 +海源 1 +x:1 +专权 1 +x:1 +大政方针 1 +x:1 +伊万诺夫 1 +x:1 +灯箱 1 +x:1 +电冰箱 1 +x:1 +工本 1 +x:1 +澄清 1 +x:1 +便携 1 +x:1 +稿纸 1 +x:1 +火灼灼 1 +x:1 +吉莱巴 1 +x:1 +光溜溜 1 +x:1 +星期一 1 +x:1 +布包 1 +x:1 +海滨 1 +x:1 +土豪劣绅 1 +x:1 +令人称奇 1 +x:1 +企划部 1 +x:1 +稿约 1 +x:1 +摔交 1 +x:1 +直管 1 +x:1 +实船 1 +x:1 +底土 1 +x:1 +善罢甘休 1 +x:1 +业务部 1 +x:1 +载弹量 1 +x:1 +甬路 1 +x:1 +合影 1 +x:1 +垂杨 1 +x:1 +河顺镇 1 +x:1 +巴伦支海 1 +x:1 +嵩 5 +x:5 +布匹 1 +x:1 +沈园 1 +x:1 +史中 1 +x:1 +小桥流水 1 +x:1 +值日牌 1 +x:1 +灭荒县 1 +x:1 +特效药 1 +x:1 +海港 1 +x:1 +海温 1 +x:1 +黑下脸 1 +x:1 +绝品 1 +x:1 +回水沟 1 +x:1 +绝响 1 +x:1 +制空权 1 +x:1 +朝圣者 1 +x:1 +料件 1 +x:1 +火星 1 +x:1 +奥胜队 1 +x:1 +贵南县 1 +x:1 +陈家屯 1 +x:1 +专柜 1 +x:1 +细腻 1 +x:1 +大风大浪 1 +x:1 +称呼 1 +x:1 +中龄林 1 +x:1 +灯笼 1 +x:1 +黑麦草 1 +x:1 +去冬今春 1 +x:1 +陈家山 1 +x:1 +跌进 1 +x:1 +墓区 1 +x:1 +满堂红 1 +x:1 +运费 1 +x:1 +往年 1 +x:1 +免遭 1 +x:1 +布厂 1 +x:1 +寸木岑楼 1 +x:1 +用血量 1 +x:1 +清朴 1 +x:1 +傻帽儿 1 +x:1 +海湾 1 +x:1 +工架 1 +x:1 +史事 1 +x:1 +时装展 1 +x:1 +摆件 1 +x:1 +券商 1 +x:1 +烟田 1 +x:1 +字码儿 1 +x:1 +都港区 1 +x:1 +系统论 1 +x:1 +全城 1 +x:1 +长长地 1 +x:1 +菌斑 1 +x:1 +大而化之 1 +x:1 +首当其冲 1 +x:1 +张贴者 1 +x:1 +一斑窥豹 1 +x:1 +洁霉素 1 +x:1 +九五年 1 +x:1 +菌料 1 +x:1 +使势 1 +x:1 +水天一色 1 +x:1 +切当 1 +x:1 +泪水 1 +x:1 +长抽短吊 1 +x:1 +管身 1 +x:1 +石河子市 1 +x:1 +烟盒 1 +x:1 +主题曲 1 +x:1 +河畔 1 +x:1 +叙 99 +x:99 +情绪链 1 +x:1 +震情室 1 +x:1 +战 440 +x:440 +汤阴 1 +x:1 +玉桂 1 +x:1 +劳逸结合 1 +x:1 +便条 1 +x:1 +啃书本 1 +x:1 +裙带关系 1 +x:1 +兵船 1 +x:1 +海涂 1 +x:1 +矿尘 1 +x:1 +剑羚 1 +x:1 +兵舰 1 +x:1 +债市 1 +x:1 +小孩儿 1 +x:1 +请帖 1 +x:1 +微醺 1 +x:1 +付费 1 +x:1 +举世闻名 1 +x:1 +爱卫办 1 +x:1 +全名 1 +x:1 +三青团 1 +x:1 +海涛 1 +x:1 +布偶 1 +x:1 +军中 1 +x:1 +军乐 1 +x:1 +气压计 1 +x:1 +牛心白 1 +x:1 +球市 1 +x:1 +示警 1 +x:1 +虎伥 1 +x:1 +像 1992 +x:1992 +种质 1 +x:1 +细节 1 +x:1 +冒尖户 1 +x:1 +切开 1 +x:1 +墙角 1 +x:1 +玉林市 1 +x:1 +红包 1 +x:1 +谷内 1 +x:1 +绝地 1 +x:1 +海淀 1 +x:1 +举荐 1 +x:1 +非武力 1 +x:1 +模子 1 +x:1 +便服 1 +x:1 +叹 51 +x:51 +收费表 1 +x:1 +邻鄂乡 1 +x:1 +矿层 1 +x:1 +矿局 1 +x:1 +筑路 1 +x:1 +快要 1 +x:1 +巡警班 1 +x:1 +院务 1 +x:1 +红叶 1 +x:1 +扫雷兵 1 +x:1 +红史 1 +x:1 +军事 1 +x:1 +海派 1 +x:1 +切忌 1 +x:1 +柔波 1 +x:1 +英明 1 +x:1 +罐体 1 +x:1 +红参 1 +x:1 +新老朋友 1 +x:1 +军人 1 +x:1 +海洋 1 +x:1 +风餐露宿 1 +x:1 +心力交瘁 1 +x:1 +惊惶失措 1 +x:1 +参观点 1 +x:1 +含糖量 1 +x:1 +线装 1 +x:1 +专擅 1 +x:1 +肿瘤学家 1 +x:1 +毛石 1 +x:1 +震源 1 +x:1 +加入者 1 +x:1 +迟缓 1 +x:1 +海浪 1 +x:1 +苗条素 1 +x:1 +椅背 1 +x:1 +互信 1 +x:1 +印象分 1 +x:1 +总流量 1 +x:1 +乳浆 1 +x:1 +仿古砖 1 +x:1 +烟瘾 1 +x:1 +线袜 1 +x:1 +海流 1 +x:1 +避孕套 1 +x:1 +久闻其名 1 +x:1 +哨所 1 +x:1 +红原 1 +x:1 +德才 1 +x:1 +滚 55 +x:55 +海沧 1 +x:1 +鸡鸣 1 +x:1 +恶性循环 1 +x:1 +细菜 1 +x:1 +互为 1 +x:1 +饶阳县 1 +x:1 +狸藻 1 +x:1 +海河 1 +x:1 +布兜 1 +x:1 +工整 1 +x:1 +方山村 1 +x:1 +时装店 1 +x:1 +表扬话 1 +x:1 +作响 1 +x:1 +工效 1 +x:1 +球形 1 +x:1 +冤情 1 +x:1 +神圣同盟 1 +x:1 +遗失物 1 +x:1 +北辰 1 +x:1 +闭幕词 1 +x:1 +互不 1 +x:1 +梨园镇 1 +x:1 +北边 1 +x:1 +军体 1 +x:1 +视频 1 +x:1 +儿科病 1 +x:1 +专政 1 +x:1 +海波 1 +x:1 +重拳 1 +x:1 +返璞归真 1 +x:1 +永顺县 1 +x:1 +汤面 1 +x:1 +红利 1 +x:1 +晒场 1 +x:1 +窗子 1 +x:1 +交通费 1 +x:1 +梧桐花镇 1 +x:1 +分摊金 1 +x:1 +大难临头 1 +x:1 +桔黄 1 +x:1 +普天下 1 +x:1 +百听不厌 1 +x:1 +兴衰与共 1 +x:1 +下吴村 1 +x:1 +邀请展 1 +x:1 +闷 12 +x:12 +进出口业 1 +x:1 +直隶省 1 +x:1 +披麻带孝 1 +x:1 +跌跤 1 +x:1 +帐篷街 1 +x:1 +地动山摇 1 +x:1 +樯桅 1 +x:1 +监察界 1 +x:1 +综艺 1 +x:1 +膀大腰圆 1 +x:1 +泪液 1 +x:1 +储血 1 +x:1 +湘阴县队 1 +x:1 +海水 1 +x:1 +沈后 1 +x:1 +工时 1 +x:1 +谝 1 +x:1 +艺界 1 +x:1 +殚精竭虑 1 +x:1 +铲雪车 1 +x:1 +皮里阳秋 1 +x:1 +结结巴巴 1 +x:1 +村提留 1 +x:1 +大明镇 1 +x:1 +隶 4 +x:4 +窗格子 1 +x:1 +强词夺理 1 +x:1 +德冲寺 1 +x:1 +枝城市 1 +x:1 +缟素 1 +x:1 +残渣 1 +x:1 +皱巴巴 1 +x:1 +布军 1 +x:1 +银鲳 1 +x:1 +专断 1 +x:1 +柔润 1 +x:1 +乳汁 1 +x:1 +版画家 1 +x:1 +罐中 1 +x:1 +英杰 1 +x:1 +鼻尖 1 +x:1 +殉葬品 1 +x:1 +布冧 1 +x:1 +菌林 1 +x:1 +该社 1 +x:1 +工料 1 +x:1 +挺身而出 1 +x:1 +北轻 1 +x:1 +手工业 1 +x:1 +饱餐 1 +x:1 +沃 8 +x:8 +遐想 1 +x:1 +瞠目 1 +x:1 +布幅 1 +x:1 +龙洞村 1 +x:1 +合刊 1 +x:1 +兵谏 1 +x:1 +冲赛康 1 +x:1 +拉稀 1 +x:1 +举贤 1 +x:1 +机车组 1 +x:1 +孱弱 1 +x:1 +泰拳 1 +x:1 +旋耕机 1 +x:1 +交通艇 1 +x:1 +现眼 1 +x:1 +警钟 1 +x:1 +切入 1 +x:1 +香蒿 1 +x:1 +仰山村 1 +x:1 +香蒲 1 +x:1 +务实 1 +x:1 +灯盏 1 +x:1 +震怒 1 +x:1 +藉 3 +x:3 +布市 1 +x:1 +领头人 1 +x:1 +不可捉摸 1 +x:1 +布帛 1 +x:1 +专横 1 +x:1 +监测船 1 +x:1 +布帘 1 +x:1 +离群索居 1 +x:1 +抽象化 1 +x:1 +合剂 1 +x:1 +遗作展 1 +x:1 +菌核 1 +x:1 +请假 1 +x:1 +骨料 1 +x:1 +北胡 1 +x:1 +巨蟒 1 +x:1 +烟碱 1 +x:1 +警铃 1 +x:1 +布帽 1 +x:1 +罕见 1 +x:1 +合力 1 +x:1 +烟硝 1 +x:1 +浩白 1 +x:1 +海挡 1 +x:1 +准字号 1 +x:1 +饲养量 1 +x:1 +帅哥儿 1 +x:1 +偶数 1 +x:1 +震情 1 +x:1 +营养物 1 +x:1 +无缝门 1 +x:1 +震惊 1 +x:1 +矿务 1 +x:1 +公安处 1 +x:1 +熔化 1 +x:1 +港 450 +x:450 +鱼虫 1 +x:1 +乌青 1 +x:1 +目标区 1 +x:1 +巨蜂 1 +x:1 +岸 45 +x:45 +所幸 1 +x:1 +功法 1 +x:1 +班主 1 +x:1 +疑虑 1 +x:1 +悼念 1 +x:1 +头重脚轻 1 +x:1 +仲秋 1 +x:1 +阅看 1 +x:1 +特惠 1 +x:1 +绝妙 1 +x:1 +夜中学 1 +x:1 +扑腾 1 +x:1 +名目繁多 1 +x:1 +水果糖 1 +x:1 +迎难而上 1 +x:1 +蔽日遮天 1 +x:1 +趁机 1 +x:1 +催眠 1 +x:1 +兴许 1 +x:1 +没皮没脸 1 +x:1 +这边 1 +x:1 +加固费 1 +x:1 +人人喊打 1 +x:1 +海损 1 +x:1 +光导管 1 +x:1 +亚行 1 +x:1 +抗拒 1 +x:1 +保险费 1 +x:1 +海报 1 +x:1 +矿区 1 +x:1 +震慑 1 +x:1 +耆 2 +x:2 +便桶 1 +x:1 +静观 1 +x:1 +鲑鱼 1 +x:1 +财迷 1 +x:1 +终审 1 +x:1 +红山 1 +x:1 +饺子皮 1 +x:1 +线列 1 +x:1 +便桥 1 +x:1 +专武 1 +x:1 +清仓 1 +x:1 +独往独来 1 +x:1 +乳腺癌 1 +x:1 +底孔 1 +x:1 +璀璨 1 +x:1 +档案袋 1 +x:1 +墓志 1 +x:1 +底子 1 +x:1 +清代 1 +x:1 +航空线 1 +x:1 +版权业 1 +x:1 +财运 1 +x:1 +猿叶虫 1 +x:1 +东四合村 1 +x:1 +香薷 1 +x:1 +芙蓉 1 +x:1 +受污染区 1 +x:1 +专款 1 +x:1 +登山者 1 +x:1 +震感 1 +x:1 +微黄 1 +x:1 +澄浆泥 1 +x:1 +嗓 4 +x:4 +所得 1 +x:1 +学院 1 +x:1 +深色纹 1 +x:1 +合十 1 +x:1 +竹韵 1 +x:1 +奠 1 +x:1 +清亮 1 +x:1 +有效期 1 +x:1 +安老 1 +x:1 +绍籍 1 +x:1 +清产 1 +x:1 +淡妆 1 +x:1 +抗压强度 1 +x:1 +热心肠 1 +x:1 +元代 1 +x:1 +谷底 1 +x:1 +海拔 1 +x:1 +球儿 1 +x:1 +清人 1 +x:1 +盘山道 1 +x:1 +红尘 1 +x:1 +正梁 1 +x:1 +新兴村 1 +x:1 +垂死 1 +x:1 +唐花 1 +x:1 +一晃 1 +x:1 +豆美丝 1 +x:1 +全家 1 +x:1 +两面性 1 +x:1 +财产权 1 +x:1 +绝壁 1 +x:1 +上选 1 +x:1 +边检站 1 +x:1 +上送 1 +x:1 +班会 1 +x:1 +鸥 1 +x:1 +不堪重负 1 +x:1 +变化图 1 +x:1 +江心 1 +x:1 +共同语 1 +x:1 +照拂 1 +x:1 +一脉相通 1 +x:1 +岐阜县 1 +x:1 +庭长 1 +x:1 +奋发有为 1 +x:1 +香蕉 1 +x:1 +香蕈 1 +x:1 +注册证 1 +x:1 +害农 1 +x:1 +热心者 1 +x:1 +契约型 1 +x:1 +红岩 1 +x:1 +玉林 1 +x:1 +警长 1 +x:1 +全寨 1 +x:1 +烧伤 1 +x:1 +怠惰 1 +x:1 +绝境 1 +x:1 +视阈 1 +x:1 +三姑六婆 1 +x:1 +量出为入 1 +x:1 +买价 1 +x:1 +海扇 1 +x:1 +主脑 1 +x:1 +宫室 1 +x:1 +防疫针 1 +x:1 +合叶 1 +x:1 +育空 1 +x:1 +清丽 1 +x:1 +璀瑰 1 +x:1 +照抄 1 +x:1 +阜阳市 1 +x:1 +石板镇 1 +x:1 +熔剂 1 +x:1 +清丰 1 +x:1 +系词 1 +x:1 +磁谱仪 1 +x:1 +登记 1 +x:1 +油纸 1 +x:1 +河神 1 +x:1 +综述 1 +x:1 +非加太 1 +x:1 +熔冶 1 +x:1 +布局 1 +x:1 +永兴岛 1 +x:1 +新开岭 1 +x:1 +彷徨 1 +x:1 +双轨制 1 +x:1 +一无所获 1 +x:1 +债券 1 +x:1 +作协 1 +x:1 +鲜牛奶 1 +x:1 +布展 1 +x:1 +流失 1 +x:1 +R 1 +x:1 +有待 1 +x:1 +到点 1 +x:1 +牛奶业 1 +x:1 +绝学 1 +x:1 +练达 1 +x:1 +盛气凌人 1 +x:1 +外环线 1 +x:1 +证 140 +x:140 +留学者 1 +x:1 +带勤率 1 +x:1 +燃气体 1 +x:1 +孰知 1 +x:1 +工校 1 +x:1 +蛇根草 1 +x:1 +n 4 +x:4 +特批 1 +x:1 +盛名之下 1 +x:1 +形 103 +x:103 +北苑 1 +x:1 +男盗女娼 1 +x:1 +柔性 1 +x:1 +考古队 1 +x:1 +布尔 1 +x:1 +富源县 1 +x:1 +全盘皆输 1 +x:1 +并购案 1 +x:1 +专任 1 +x:1 +贝布托 1 +x:1 +邱县 1 +x:1 +歌坛 1 +x:1 +实质 1 +x:1 +相片 1 +x:1 +造成 1 +x:1 +育秧 1 +x:1 +专栏 1 +x:1 +黄蜂队 1 +x:1 +投稿人 1 +x:1 +承销 1 +x:1 +恳挚 1 +x:1 +男朋友 1 +x:1 +特需品 1 +x:1 +犀 1 +x:1 +天井式 1 +x:1 +硬纸板 1 +x:1 +初具规模 1 +x:1 +债务 1 +x:1 +底壳 1 +x:1 +切变 1 +x:1 +俊才 1 +x:1 +绝密 1 +x:1 +歪曲 1 +x:1 +恩重如山 1 +x:1 +鲜血 1 +x:1 +独幕剧 1 +x:1 +闽中 1 +x:1 +乙酸 1 +x:1 +货架子 1 +x:1 +所属 1 +x:1 +时装化 1 +x:1 +乌镇 1 +x:1 +烛影 1 +x:1 +红心 1 +x:1 +闽东 1 +x:1 +骨材 1 +x:1 +绝对 1 +x:1 +便毒 1 +x:1 +警队 1 +x:1 +英模 1 +x:1 +嘶 2 +x:2 +洋里洋气 1 +x:1 +切口 1 +x:1 +王国 1 +x:1 +砷 2 +x:2 +工棚 1 +x:1 +请功 1 +x:1 +酸雨区 1 +x:1 +柔情 1 +x:1 +残损 1 +x:1 +沈大 1 +x:1 +解甲沟村 1 +x:1 +松江路 1 +x:1 +邱北 1 +x:1 +痛史 1 +x:1 +打零工 1 +x:1 +鼻儿 1 +x:1 +骨朵 1 +x:1 +狐 7 +x:7 +骨木 1 +x:1 +共同语言 1 +x:1 +现症 1 +x:1 +请勿 1 +x:1 +宫墙 1 +x:1 +邀请函 1 +x:1 +一展雄姿 1 +x:1 +慰劳 1 +x:1 +终点 1 +x:1 +聚会党 1 +x:1 +温汤浸种 1 +x:1 +买方 1 +x:1 +底墒 1 +x:1 +特招 1 +x:1 +酽 1 +x:1 +信手 1 +x:1 +买断 1 +x:1 +中南 1 +x:1 +财路 1 +x:1 +支持票 1 +x:1 +阿比让 1 +x:1 +拜年钱 1 +x:1 +全天 1 +x:1 +嫦娥 1 +x:1 +鲜见 1 +x:1 +工楷 1 +x:1 +新军屯镇 1 +x:1 +切削 1 +x:1 +绵邃 1 +x:1 +频繁 1 +x:1 +轴线 1 +x:1 +大队人马 1 +x:1 +切割 1 +x:1 +自立军 1 +x:1 +特指 1 +x:1 +主菜 1 +x:1 +宫女 1 +x:1 +发展费 1 +x:1 +自小 1 +x:1 +坍缩星 1 +x:1 +有张有弛 1 +x:1 +纹 11 +x:11 +参与面 1 +x:1 +全备 1 +x:1 +全处 1 +x:1 +泵站 1 +x:1 +临江楼 1 +x:1 +提水 1 +x:1 +细辛 1 +x:1 +转换率 1 +x:1 +春熙路 1 +x:1 +血丝乎拉 1 +x:1 +切切 1 +x:1 +火棒 1 +x:1 +铕 1 +x:1 +牝牛 1 +x:1 +佘 18 +x:18 +空白符 1 +x:1 +红帆 1 +x:1 +陈宿 1 +x:1 +合共 1 +x:1 +全套 1 +x:1 +肉汤 1 +x:1 +小户 1 +x:1 +见风是雨 1 +x:1 +底处 1 +x:1 +犯罪案 1 +x:1 +完好无缺 1 +x:1 +超级稻 1 +x:1 +合写 1 +x:1 +矿冶 1 +x:1 +四世同堂 1 +x:1 +暗自 1 +x:1 +翠谷 1 +x:1 +犹太化 1 +x:1 +世态炎凉 1 +x:1 +直愣愣 1 +x:1 +遮蔽 1 +x:1 +不公正性 1 +x:1 +营销部 1 +x:1 +提法 1 +x:1 +探险片 1 +x:1 +驯兽 1 +x:1 +远谋 1 +x:1 +演出票 1 +x:1 +沽名钓誉 1 +x:1 +球台 1 +x:1 +冼 8 +x:8 +细软 1 +x:1 +粘合 1 +x:1 +水法 1 +x:1 +需要 1 +x:1 +美玉 1 +x:1 +理工科 1 +x:1 +鉴别仪 1 +x:1 +危崖之巅 1 +x:1 +旗帜鲜明 1 +x:1 +纯净水 1 +x:1 +龙吴港 1 +x:1 +呕 1 +x:1 +还 10551 +x:10551 +数学系 1 +x:1 +财贸 1 +x:1 +冤家路窄 1 +x:1 +万难 1 +x:1 +讯问室 1 +x:1 +巨著 1 +x:1 +全委 1 +x:1 +手杖 1 +x:1 +定期 1 +x:1 +腰板儿 1 +x:1 +险象环生 1 +x:1 +冤气 1 +x:1 +购买力 1 +x:1 +估价师 1 +x:1 +翘尾巴 1 +x:1 +分线规 1 +x:1 +公有性 1 +x:1 +代表组 1 +x:1 +通信团 1 +x:1 +河网 1 +x:1 +年薪制 1 +x:1 +球员 1 +x:1 +因而 1 +x:1 +全席 1 +x:1 +成人者 1 +x:1 +半音 1 +x:1 +芟 1 +x:1 +争嘴 1 +x:1 +香肠 1 +x:1 +踬 1 +x:1 +营养盐 1 +x:1 +沈微 1 +x:1 +红契 1 +x:1 +厄方 1 +x:1 +笛箫 1 +x:1 +谦虚谨慎 1 +x:1 +警声大作 1 +x:1 +金银花 1 +x:1 +综览 1 +x:1 +堆金积玉 1 +x:1 +海查 1 +x:1 +独木舟队 1 +x:1 +提款 1 +x:1 +迟疑 1 +x:1 +共同纲领 1 +x:1 +和合雅俗 1 +x:1 +津南区 1 +x:1 +模具 1 +x:1 +岩画区 1 +x:1 +马鞍山乡 1 +x:1 +小孩子 1 +x:1 +诗刊社 1 +x:1 +有形 1 +x:1 +务必 1 +x:1 +哨棒 1 +x:1 +美甲天下 1 +x:1 +红外 1 +x:1 +旺期 1 +x:1 +上门 1 +x:1 +鼓楼区 1 +x:1 +铁路线 1 +x:1 +潢川 1 +x:1 +单褂 1 +x:1 +侨领 1 +x:1 +其貌不扬 1 +x:1 +浩特 1 +x:1 +柔曼 1 +x:1 +安第斯山 1 +x:1 +火漆 1 +x:1 +万金 1 +x:1 +张集乡 1 +x:1 +统招生 1 +x:1 +陈展 1 +x:1 +受灾面 1 +x:1 +帆布 1 +x:1 +这话 1 +x:1 +实词 1 +x:1 +直略河 1 +x:1 +倾羡 1 +x:1 +阿里山 1 +x:1 +主著 1 +x:1 +陈屿 1 +x:1 +拉线 1 +x:1 +人际关系 1 +x:1 +旆 1 +x:1 +喜气洋洋 1 +x:1 +残敌 1 +x:1 +宫廷 1 +x:1 +革职 1 +x:1 +谷子 1 +x:1 +钞本 1 +x:1 +秸子 1 +x:1 +赞皇 1 +x:1 +拉纤 1 +x:1 +爿 6 +x:6 +满意率 1 +x:1 +环氧树脂 1 +x:1 +巧儿 1 +x:1 +拉绒 1 +x:1 +售票人 1 +x:1 +出殡 1 +x:1 +庆阳 1 +x:1 +书摊儿 1 +x:1 +浙东 1 +x:1 +主营 1 +x:1 +自居 1 +x:1 +海松 1 +x:1 +底座 1 +x:1 +亮晃晃 1 +x:1 +榕江县 1 +x:1 +药用菌 1 +x:1 +海杆 1 +x:1 +改换门庭 1 +x:1 +浙中 1 +x:1 +震撼 1 +x:1 +滨湖 1 +x:1 +静谧 1 +x:1 +诉说 1 +x:1 +出肉率 1 +x:1 +东西 1 +x:1 +鱼水深情 1 +x:1 +子题目 1 +x:1 +柔板 1 +x:1 +水泡状 1 +x:1 +工潮 1 +x:1 +陈州 1 +x:1 +矿场 1 +x:1 +宫灯 1 +x:1 +矿地 1 +x:1 +煤烟型 1 +x:1 +火源 1 +x:1 +老八路 1 +x:1 +茅草房 1 +x:1 +薛 255 +x:255 +飞沙走石 1 +x:1 +经营点 1 +x:1 +微型车 1 +x:1 +蒙皮 1 +x:1 +多普勒 1 +x:1 +上钩 1 +x:1 +鲜迭 1 +x:1 +放慢 1 +x:1 +上钢 1 +x:1 +倾 71 +x:71 +电话杆 1 +x:1 +绝少 1 +x:1 +拉网 1 +x:1 +斌 156 +x:156 +柔术 1 +x:1 +慰唁 1 +x:1 +航空站 1 +x:1 +上铁 1 +x:1 +墓室 1 +x:1 +历史观 1 +x:1 +科艺楼 1 +x:1 +上铺 1 +x:1 +孝亲 1 +x:1 +淋淋 1 +x:1 +买房 1 +x:1 +误 110 +x:110 +特教 1 +x:1 +数 575 +x:575 +举行 1 +x:1 +江猪 1 +x:1 +谈不上 1 +x:1 +照明 1 +x:1 +批评声 1 +x:1 +红壤 1 +x:1 +东昌府区 1 +x:1 +驻马店市 1 +x:1 +创立者 1 +x:1 +打孔器 1 +x:1 +巨舰 1 +x:1 +甚嚣尘上 1 +x:1 +铁路网 1 +x:1 +拉美 1 +x:1 +遐思 1 +x:1 +平江县队 1 +x:1 +腮腺炎 1 +x:1 +日臻成熟 1 +x:1 +现状 1 +x:1 +反馈簿 1 +x:1 +火温 1 +x:1 +墓子 1 +x:1 +龙门镇 1 +x:1 +绵阳 1 +x:1 +卫生设备 1 +x:1 +求医者 1 +x:1 +死亡率 1 +x:1 +海星 1 +x:1 +画 599 +x:599 +闭会 1 +x:1 +羊胡子草 1 +x:1 +蝇 6 +x:6 +海景 1 +x:1 +体制性 1 +x:1 +桉树苗 1 +x:1 +异味 1 +x:1 +望平台 1 +x:1 +淋浴 1 +x:1 +挪威王国 1 +x:1 +骨性 1 +x:1 +莒南县 1 +x:1 +委任状 1 +x:1 +帆影 1 +x:1 +酌处 1 +x:1 +公安局 1 +x:1 +哦 21 +x:21 +孤单单 1 +x:1 +浅白 1 +x:1 +齐头并进 1 +x:1 +了解 1 +x:1 +推荐者 1 +x:1 +油茶籽 1 +x:1 +红墙 1 +x:1 +堪市 1 +x:1 +切块 1 +x:1 +红学 1 +x:1 +事无巨细 1 +x:1 +医卫界 1 +x:1 +滨河 1 +x:1 +噬脐莫及 1 +x:1 +造景 1 +x:1 +乐观者 1 +x:1 +称心 1 +x:1 +乌斯塔夏 1 +x:1 +合同 1 +x:1 +翻斗车 1 +x:1 +樘 2 +x:2 +视野 1 +x:1 +泛音 1 +x:1 +克拉玛依 1 +x:1 +纺纱机 1 +x:1 +钧 25 +x:25 +兴起 1 +x:1 +无线电 1 +x:1 +蝴蝶结 1 +x:1 +凌云之志 1 +x:1 +声誉鹊起 1 +x:1 +鼓鼓掌 1 +x:1 +内司委 1 +x:1 +年逾花甲 1 +x:1 +激酶 1 +x:1 +颓风 1 +x:1 +乌金 1 +x:1 +批评家 1 +x:1 +称快 1 +x:1 +一月 1 +x:1 +拉簧 1 +x:1 +底层 1 +x:1 +苇锥子 1 +x:1 +务工 1 +x:1 +窗前 1 +x:1 +综论 1 +x:1 +银锭 1 +x:1 +瞬息万变 1 +x:1 +正仪镇 1 +x:1 +杏五区 1 +x:1 +太岳山 1 +x:1 +保有量 1 +x:1 +茬儿 1 +x:1 +遵化市 1 +x:1 +跌落 1 +x:1 +论斤计两 1 +x:1 +陈庄 1 +x:1 +找茬儿 1 +x:1 +地役权 1 +x:1 +全属 1 +x:1 +人道主义 1 +x:1 +地质所 1 +x:1 +言情小说 1 +x:1 +大嫂子 1 +x:1 +巨臂 1 +x:1 +全局 1 +x:1 +独特 1 +x:1 +务川 1 +x:1 +蚁社 1 +x:1 +恳望 1 +x:1 +攻击型 1 +x:1 +奇珍异宝 1 +x:1 +沼气式 1 +x:1 +洋模特 1 +x:1 +奈何 1 +x:1 +照旧 1 +x:1 +墙脚 1 +x:1 +合咏 1 +x:1 +当选者 1 +x:1 +海政 1 +x:1 +挣扎 1 +x:1 +成人节 1 +x:1 +残杀 1 +x:1 +吧 435 +x:435 +环颈鸫 1 +x:1 +模压 1 +x:1 +陈年 1 +x:1 +火洲 1 +x:1 +果林业 1 +x:1 +工法 1 +x:1 +一朝 1 +x:1 +侄女婿 1 +x:1 +黄鱼村 1 +x:1 +战无不胜 1 +x:1 +持有 1 +x:1 +登载 1 +x:1 +残本 1 +x:1 +坑 69 +x:69 +货位费 1 +x:1 +巧匠 1 +x:1 +广电局 1 +x:1 +风景树 1 +x:1 +领事部 1 +x:1 +绵长 1 +x:1 +浩瀚 1 +x:1 +灯火 1 +x:1 +滨江 1 +x:1 +批评学 1 +x:1 +残月 1 +x:1 +红安 1 +x:1 +垂泪 1 +x:1 +数学科 1 +x:1 +海庄村 1 +x:1 +廊坊籍 1 +x:1 +蟾宫 1 +x:1 +火海 1 +x:1 +恩恩怨怨 1 +x:1 +劳动部 1 +x:1 +举证 1 +x:1 +香艳 1 +x:1 +头昏脑胀 1 +x:1 +调度室 1 +x:1 +上面 1 +x:1 +彼时 1 +x:1 +侵食 1 +x:1 +如坐云雾 1 +x:1 +三教堂 1 +x:1 +成人之美 1 +x:1 +露天浴 1 +x:1 +球坛 1 +x:1 +实行 1 +x:1 +走马疳 1 +x:1 +议购粮 1 +x:1 +呆板 1 +x:1 +消防车 1 +x:1 +布套 1 +x:1 +大秋作物 1 +x:1 +特有 1 +x:1 +细说 1 +x:1 +犯罪 1 +x:1 +汨罗江畔 1 +x:1 +助 118 +x:118 +买卖人 1 +x:1 +壳质 1 +x:1 +谷壑 1 +x:1 +提案 1 +x:1 +细语 1 +x:1 +绿绿的 1 +x:1 +知情达理 1 +x:1 +装 263 +x:263 +巧劲 1 +x:1 +微风 1 +x:1 +身外之物 1 +x:1 +国防系 1 +x:1 +竭尽全力 1 +x:1 +香菇 1 +x:1 +拨贷款 1 +x:1 +遵行 1 +x:1 +欢乐曲 1 +x:1 +香菜 1 +x:1 +残暴 1 +x:1 +照搬 1 +x:1 +历史课 1 +x:1 +灵山卫镇 1 +x:1 +晕菜 1 +x:1 +骨折 1 +x:1 +漂白粉 1 +x:1 +特权 1 +x:1 +泰方 1 +x:1 +脸盘儿 1 +x:1 +藏书界 1 +x:1 +宴饮 1 +x:1 +球场 1 +x:1 +献艺 1 +x:1 +望远镜 1 +x:1 +黑石礁湾 1 +x:1 +红娘 1 +x:1 +粗花呢 1 +x:1 +闲聊天 1 +x:1 +拼争 1 +x:1 +腹心区 1 +x:1 +磺胺 1 +x:1 +境界 1 +x:1 +滨洲 1 +x:1 +开发费 1 +x:1 +垂涎 1 +x:1 +香茅 1 +x:1 +火气 1 +x:1 +底工 1 +x:1 +圆通山 1 +x:1 +购买国 1 +x:1 +萝 1 +x:1 +打短工 1 +x:1 +镜真楼 1 +x:1 +河系 1 +x:1 +冤案 1 +x:1 +五人制 1 +x:1 +上阵 1 +x:1 +俊杰 1 +x:1 +布依族 1 +x:1 +加利利 1 +x:1 +公文纸 1 +x:1 +扬李抑杜 1 +x:1 +洣江 1 +x:1 +张高 1 +x:1 +表现性 1 +x:1 +香草 1 +x:1 +近中期 1 +x:1 +脏污 1 +x:1 +上限 1 +x:1 +滨海 1 +x:1 +遏止 1 +x:1 +银钱 1 +x:1 +冷眼旁观 1 +x:1 +涉外 1 +x:1 +人心房 1 +x:1 +劳动量 1 +x:1 +谷堆 1 +x:1 +犯罪法 1 +x:1 +乳腺炎 1 +x:1 +旧村 1 +x:1 +烟缸 1 +x:1 +银针 1 +x:1 +宦 3 +x:3 +鸡雏 1 +x:1 +烃类 1 +x:1 +兵头官尾 1 +x:1 +汉朝 1 +x:1 +提梁 1 +x:1 +造林 1 +x:1 +窗台 1 +x:1 +大沽口 1 +x:1 +污尘 1 +x:1 +上院 1 +x:1 +鉴赏者 1 +x:1 +脂肪醇 1 +x:1 +国泰民安 1 +x:1 +璃 1 +x:1 +高支纱 1 +x:1 +江湖 1 +x:1 +纵火案 1 +x:1 +懂法 1 +x:1 +歌曲 1 +x:1 +深灰色 1 +x:1 +宝 86 +x:86 +邯钢 1 +x:1 +马头山 1 +x:1 +科普栏 1 +x:1 +扇骨子 1 +x:1 +三湘四水 1 +x:1 +诡奇 1 +x:1 +拼凑 1 +x:1 +万安县 1 +x:1 +偷渡梦 1 +x:1 +人老珠黄 1 +x:1 +主食 1 +x:1 +精工 1 +x:1 +史学 1 +x:1 +专版 1 +x:1 +垂爱 1 +x:1 +高产年 1 +x:1 +曙色 1 +x:1 +警貌 1 +x:1 +椎间盘 1 +x:1 +窗纱 1 +x:1 +北风 1 +x:1 +后掠角 1 +x:1 +拉手 1 +x:1 +桦南县 1 +x:1 +艺体 1 +x:1 +团干 1 +x:1 +乌达 1 +x:1 +飘洋过海 1 +x:1 +虎头 1 +x:1 +中信队 1 +x:1 +鸡西 1 +x:1 +主频 1 +x:1 +瓦当 1 +x:1 +白庙子乡 1 +x:1 +前沿性 1 +x:1 +寒苦 1 +x:1 +拼写 1 +x:1 +昆山市 1 +x:1 +首付款 1 +x:1 +拉扯 1 +x:1 +遣返 1 +x:1 +上解 1 +x:1 +后勤部 1 +x:1 +财院 1 +x:1 +文过饰非 1 +x:1 +灾危 1 +x:1 +主项 1 +x:1 +加勒比低 1 +x:1 +财险 1 +x:1 +激进 1 +x:1 +流动资金 1 +x:1 +观赏植物 1 +x:1 +基藏 1 +x:1 +薪给 1 +x:1 +勉励 1 +x:1 +忠贞不屈 1 +x:1 +海绵体 1 +x:1 +薪炭林 1 +x:1 +犯罪率 1 +x:1 +江滩 1 +x:1 +江滨 1 +x:1 +次内阁级 1 +x:1 +振兴图强 1 +x:1 +灾区 1 +x:1 +浩渺 1 +x:1 +喘息甫定 1 +x:1 +罐头 1 +x:1 +袅袅 1 +x:1 +史实 1 +x:1 +扬声器 1 +x:1 +史官 1 +x:1 +季度 1 +x:1 +人财物 1 +x:1 +江源 1 +x:1 +地质系 1 +x:1 +孕情 1 +x:1 +照管 1 +x:1 +闹腾 1 +x:1 +铁杵成针 1 +x:1 +薪级 1 +x:1 +逆行 1 +x:1 +台式 1 +x:1 +中奖人 1 +x:1 +山南海北 1 +x:1 +财阀 1 +x:1 +蛤 1 +x:1 +浩 54 +x:54 +匿名信 1 +x:1 +值班室 1 +x:1 +管理课 1 +x:1 +变流器 1 +x:1 +耗子药 1 +x:1 +告慰 1 +x:1 +军士 1 +x:1 +歌星 1 +x:1 +拉拢 1 +x:1 +空空导弹 1 +x:1 +政治犯 1 +x:1 +场馆处 1 +x:1 +沼气池 1 +x:1 +土尔扈特 1 +x:1 +大职校 1 +x:1 +瑕玷 1 +x:1 +南非队 1 +x:1 +地躺拳 1 +x:1 +阳春面 1 +x:1 +饮泣 1 +x:1 +军备 1 +x:1 +乳突 1 +x:1 +俊秀 1 +x:1 +实际 1 +x:1 +两回事 1 +x:1 +火烧云 1 +x:1 +占有额 1 +x:1 +义不容辞 1 +x:1 +吮 1 +x:1 +囊括 1 +x:1 +向心 1 +x:1 +骨伤 1 +x:1 +万象 1 +x:1 +低工资制 1 +x:1 +终止 1 +x:1 +思想库 1 +x:1 +阿斯匹林 1 +x:1 +峥嵘 1 +x:1 +卡 131 +x:131 +写实派 1 +x:1 +马头崖 1 +x:1 +天山南北 1 +x:1 +苍 2 +x:2 +记分册 1 +x:1 +运载火箭 1 +x:1 +弋阳 1 +x:1 +火狐 1 +x:1 +新颜 1 +x:1 +麻木树 1 +x:1 +军事编 1 +x:1 +侵蚀 1 +x:1 +大部头 1 +x:1 +哲人 1 +x:1 +项目部 1 +x:1 +扑食 1 +x:1 +辉钴矿 1 +x:1 +骨粉 1 +x:1 +打官腔 1 +x:1 +四分五裂 1 +x:1 +洛杉矶 1 +x:1 +重点性 1 +x:1 +工班 1 +x:1 +避孕丸 1 +x:1 +育成 1 +x:1 +火爆 1 +x:1 +节汇率 1 +x:1 +坯布 1 +x:1 +教科所 1 +x:1 +竞赛题 1 +x:1 +提货单 1 +x:1 +建功立业 1 +x:1 +团徽 1 +x:1 +垃圾场 1 +x:1 +主饮 1 +x:1 +浙南 1 +x:1 +提盒 1 +x:1 +抢 197 +x:197 +波特兰 1 +x:1 +钮 24 +x:24 +簇拥 1 +x:1 +单功能 1 +x:1 +烧坏 1 +x:1 +地武 1 +x:1 +老娘 1 +x:1 +膑 2 +x:2 +烟感 1 +x:1 +中河 1 +x:1 +军委 1 +x:1 +筑成 1 +x:1 +歌本 1 +x:1 +火版 1 +x:1 +小站稻 1 +x:1 +上行 1 +x:1 +台布 1 +x:1 +台币 1 +x:1 +技术部长 1 +x:1 +残破 1 +x:1 +有理数 1 +x:1 +特种 1 +x:1 +木板房 1 +x:1 +研究史 1 +x:1 +军姿 1 +x:1 +造福 1 +x:1 +鬼针草 1 +x:1 +垃圾坑 1 +x:1 +北伐战争 1 +x:1 +草本 1 +x:1 +使 8224 +x:8224 +适航司 1 +x:1 +讽诵 1 +x:1 +明角灯 1 +x:1 +小企 1 +x:1 +听其自然 1 +x:1 +双千户 1 +x:1 +师 199 +x:199 +专人 1 +x:1 +自卫 1 +x:1 +台州 1 +x:1 +激赏 1 +x:1 +菌物 1 +x:1 +块块 1 +x:1 +军威 1 +x:1 +利比亚 1 +x:1 +江汉 1 +x:1 +食肆 1 +x:1 +早晚市儿 1 +x:1 +现洋 1 +x:1 +无名 1 +x:1 +西瓜籽 1 +x:1 +上访 1 +x:1 +残篇 1 +x:1 +海禁 1 +x:1 +擦洗 1 +x:1 +兵阵 1 +x:1 +玉米 1 +x:1 +提留 1 +x:1 +新高 1 +x:1 +宰狗刀 1 +x:1 +畜肥 1 +x:1 +激起 1 +x:1 +灯油 1 +x:1 +虎子 1 +x:1 +屏息 1 +x:1 +牟平县 1 +x:1 +红烧肉 1 +x:1 +永隆乡 1 +x:1 +上诉 1 +x:1 +开发部 1 +x:1 +胸有成竹 1 +x:1 +海百合 1 +x:1 +上证 1 +x:1 +糟 12 +x:12 +兽力车 1 +x:1 +上课 1 +x:1 +有情人 1 +x:1 +江永 1 +x:1 +萋萋 1 +x:1 +高升镇 1 +x:1 +答应 1 +x:1 +江水 1 +x:1 +手电筒 1 +x:1 +灯泡 1 +x:1 +玉簪 1 +x:1 +年老体衰 1 +x:1 +斯洛伐克 1 +x:1 +付汇联 1 +x:1 +满山遍野 1 +x:1 +青草娃 1 +x:1 +恻隐之心 1 +x:1 +嗡嗡 1 +x:1 +豁 12 +x:12 +宣和镇 1 +x:1 +双乙酰 1 +x:1 +生财有道 1 +x:1 +班吉 1 +x:1 +硬指标 1 +x:1 +聚礼会 1 +x:1 +玖 1 +x:1 +职业化 1 +x:1 +东行 1 +x:1 +蝴蝶扣 1 +x:1 +华东局 1 +x:1 +罐子 1 +x:1 +腐烂河 1 +x:1 +执行局 1 +x:1 +电动式 1 +x:1 +收尘率 1 +x:1 +游击战争 1 +x:1 +优化制 1 +x:1 +管风琴 1 +x:1 +到校 1 +x:1 +萤火虫 1 +x:1 +小试锋芒 1 +x:1 +十 1417 +x:1417 +明清式 1 +x:1 +激越 1 +x:1 +享福 1 +x:1 +砟子 1 +x:1 +溢美之辞 1 +x:1 +军嫂 1 +x:1 +工点 1 +x:1 +块垒 1 +x:1 +应城市 1 +x:1 +乌贼 1 +x:1 +班员 1 +x:1 +拉卜楞寺 1 +x:1 +捡 60 +x:60 +代表性 1 +x:1 +采访行 1 +x:1 +道德观 1 +x:1 +江河 1 +x:1 +浩气 1 +x:1 +天演论 1 +x:1 +颓萎 1 +x:1 +叙述者 1 +x:1 +原班人马 1 +x:1 +海神 1 +x:1 +旺 81 +x:81 +清响 1 +x:1 +巨鲸 1 +x:1 +争强斗胜 1 +x:1 +浩淼 1 +x:1 +江浙 1 +x:1 +不人道 1 +x:1 +哽咽 1 +x:1 +要饭 1 +x:1 +火炉 1 +x:1 +乐极生悲 1 +x:1 +核二院 1 +x:1 +宽打窄用 1 +x:1 +火炕 1 +x:1 +谢落 1 +x:1 +幸免于难 1 +x:1 +英王 1 +x:1 +双脑包村 1 +x:1 +江流 1 +x:1 +冠心 1 +x:1 +组佩玉饰 1 +x:1 +乌塌菜 1 +x:1 +江海 1 +x:1 +劳动费 1 +x:1 +金华阳 1 +x:1 +银行 1 +x:1 +火炮 1 +x:1 +火炭 1 +x:1 +不连惯性 1 +x:1 +杯沿 1 +x:1 +等高线 1 +x:1 +在行 1 +x:1 +应战书 1 +x:1 +汗如雨下 1 +x:1 +火点 1 +x:1 +股灾 1 +x:1 +休养 1 +x:1 +火炽 1 +x:1 +粮票 1 +x:1 +毫无顾虑 1 +x:1 +拼劲 1 +x:1 +涨跌 1 +x:1 +提琴 1 +x:1 +穆 45 +x:45 +台岛 1 +x:1 +汇编程序 1 +x:1 +若有所思 1 +x:1 +棱锥台 1 +x:1 +窗体 1 +x:1 +现汇 1 +x:1 +火烛 1 +x:1 +金属探伤 1 +x:1 +藏书楼 1 +x:1 +特等 1 +x:1 +截留 1 +x:1 +垂照 1 +x:1 +火烧 1 +x:1 +百年之后 1 +x:1 +虎娃 1 +x:1 +饭店 1 +x:1 +火热 1 +x:1 +谋杀案 1 +x:1 +寄人篱下 1 +x:1 +质问 1 +x:1 +江津 1 +x:1 +瓦屋 1 +x:1 +发达国家 1 +x:1 +道德街 1 +x:1 +纺机 1 +x:1 +教职员工 1 +x:1 +乞丐 1 +x:1 +军官 1 +x:1 +台属 1 +x:1 +浩浩 1 +x:1 +下毒手 1 +x:1 +梭镖 1 +x:1 +导轮 1 +x:1 +症结 1 +x:1 +财长 1 +x:1 +导轨 1 +x:1 +记分卡 1 +x:1 +泵房 1 +x:1 +台山 1 +x:1 +波形 1 +x:1 +军容 1 +x:1 +沪 186 +x:186 +天柱山 1 +x:1 +购销两旺 1 +x:1 +江淮 1 +x:1 +变阻器 1 +x:1 +刷卡机 1 +x:1 +扶助会 1 +x:1 +杯水 1 +x:1 +独秀一枝 1 +x:1 +人生路 1 +x:1 +拼制 1 +x:1 +录音带 1 +x:1 +江涛 1 +x:1 +北魏 1 +x:1 +闲言碎语 1 +x:1 +小三峡 1 +x:1 +物归原主 1 +x:1 +警车 1 +x:1 +虚浮 1 +x:1 +残稿 1 +x:1 +江涂 1 +x:1 +模仿 1 +x:1 +东江镇 1 +x:1 +应用科学 1 +x:1 +目 64 +x:64 +驱 7 +x:7 +野麻 1 +x:1 +丹寨县 1 +x:1 +风景画 1 +x:1 +兴邦 1 +x:1 +抽水泵 1 +x:1 +火灾 1 +x:1 +系里 1 +x:1 +入园率 1 +x:1 +育林 1 +x:1 +书楼 1 +x:1 +搏浪 1 +x:1 +酒渣鼻 1 +x:1 +黏度 1 +x:1 +白砂糖 1 +x:1 +无垠 1 +x:1 +答声 1 +x:1 +高血脂 1 +x:1 +思想家 1 +x:1 +合一 1 +x:1 +完好无恙 1 +x:1 +搠 1 +x:1 +红蜘蛛 1 +x:1 +侨胞 1 +x:1 +矿业 1 +x:1 +技改局 1 +x:1 +骨科 1 +x:1 +现款 1 +x:1 +意欲 1 +x:1 +紫罗兰 1 +x:1 +阿美利加 1 +x:1 +经办人员 1 +x:1 +制贩 1 +x:1 +细部 1 +x:1 +姿态 1 +x:1 +许许多多 1 +x:1 +罕闻 1 +x:1 +鸦片 1 +x:1 +军属 1 +x:1 +兵道 1 +x:1 +泳区 1 +x:1 +儿研所 1 +x:1 +合乎 1 +x:1 +虎崽 1 +x:1 +附具 1 +x:1 +登门 1 +x:1 +休克 1 +x:1 +纯净率 1 +x:1 +饱蕴 1 +x:1 +品酒员 1 +x:1 +笼统 1 +x:1 +笼络 1 +x:1 +进气口 1 +x:1 +火石 1 +x:1 +清县 1 +x:1 +上路 1 +x:1 +穴 13 +x:13 +基脚 1 +x:1 +宝坻县 1 +x:1 +阴雨寡照 1 +x:1 +视讯 1 +x:1 +居危思危 1 +x:1 +布拉图西 1 +x:1 +台子 1 +x:1 +史志 1 +x:1 +通信员 1 +x:1 +捉迷藏 1 +x:1 +诺言 1 +x:1 +厕所间 1 +x:1 +盘锦市 1 +x:1 +义务服务 1 +x:1 +班列 1 +x:1 +财经类 1 +x:1 +烟摊 1 +x:1 +催生 1 +x:1 +矿产 1 +x:1 +记分员 1 +x:1 +育有 1 +x:1 +娟 22 +x:22 +海缆 1 +x:1 +广交 1 +x:1 +泛起 1 +x:1 +成名作 1 +x:1 +东大桥站 1 +x:1 +矿井 1 +x:1 +末药 1 +x:1 +歌手 1 +x:1 +侨联 1 +x:1 +非政府 1 +x:1 +日报 1 +x:1 +柔细 1 +x:1 +上账 1 +x:1 +莺 11 +x:11 +火眼 1 +x:1 +鄂温克旗 1 +x:1 +提现 1 +x:1 +乌篷船 1 +x:1 +嫣 3 +x:3 +盘山路 1 +x:1 +班前 1 +x:1 +秦都 1 +x:1 +婀娜多姿 1 +x:1 +租售比价 1 +x:1 +购销员 1 +x:1 +没奈何 1 +x:1 +顺水人情 1 +x:1 +跨步 1 +x:1 +庇护所 1 +x:1 +警衔 1 +x:1 +乌沙村 1 +x:1 +陋规 1 +x:1 +自圆其说 1 +x:1 +一顺儿 1 +x:1 +微电脑 1 +x:1 +垂直 1 +x:1 +爆炸 1 +x:1 +绵软 1 +x:1 +兵部 1 +x:1 +借古喻今 1 +x:1 +塔兰托 1 +x:1 +合伙 1 +x:1 +江岸区 1 +x:1 +特殊性 1 +x:1 +神女峰 1 +x:1 +汇拨款 1 +x:1 +向导 1 +x:1 +掏 108 +x:108 +虎山 1 +x:1 +反对者 1 +x:1 +冤狱 1 +x:1 +班厦 1 +x:1 +屐痕 1 +x:1 +冰雕群 1 +x:1 +粱 1 +x:1 +缭乱 1 +x:1 +部属处 1 +x:1 +辉钼矿 1 +x:1 +三提高 1 +x:1 +必然 1 +x:1 +邀请书 1 +x:1 +末节 1 +x:1 +拔苗助长 1 +x:1 +火盆 1 +x:1 +合作 1 +x:1 +烟斗 1 +x:1 +合体 1 +x:1 +中准价 1 +x:1 +班友 1 +x:1 +中界岭 1 +x:1 +眼防所 1 +x:1 +海绵 1 +x:1 +电话网 1 +x:1 +虎尾 1 +x:1 +黄海 1 +x:1 +蚁战 1 +x:1 +离家背井 1 +x:1 +拉杂 1 +x:1 +通许县 1 +x:1 +拉杆 1 +x:1 +保证金 1 +x:1 +叶蜂 1 +x:1 +浅滩 1 +x:1 +淋病 1 +x:1 +岳阳 1 +x:1 +赛内外 1 +x:1 +矿体 1 +x:1 +垦利县 1 +x:1 +虎将 1 +x:1 +执行官 1 +x:1 +喝令 1 +x:1 +团子 1 +x:1 +警视 1 +x:1 +警觉 1 +x:1 +艺林 1 +x:1 +露天矿 1 +x:1 +青少年 1 +x:1 +到处 1 +x:1 +上谕 1 +x:1 +军事篇 1 +x:1 +留神 1 +x:1 +溺水 1 +x:1 +工矿 1 +x:1 +互 110 +x:110 +老牛破车 1 +x:1 +撒播 1 +x:1 +南明区 1 +x:1 +邀请人 1 +x:1 +一帆顺风 1 +x:1 +上调 1 +x:1 +烧卖 1 +x:1 +垃圾包 1 +x:1 +剑气 1 +x:1 +免考 1 +x:1 +帛画 1 +x:1 +河曲 1 +x:1 +新平镇 1 +x:1 +扁圆形 1 +x:1 +走俏 1 +x:1 +轰轰隆隆 1 +x:1 +清剿 1 +x:1 +二手机 1 +x:1 +种植史 1 +x:1 +活 580 +x:580 +艺术 1 +x:1 +住院楼 1 +x:1 +基肥 1 +x:1 +清分 1 +x:1 +大静脉 1 +x:1 +清初 1 +x:1 +在身 1 +x:1 +清创 1 +x:1 +开房率 1 +x:1 +兴隆 1 +x:1 +泛谈 1 +x:1 +演出服 1 +x:1 +笼罩 1 +x:1 +经办人 1 +x:1 +义冢 1 +x:1 +流体力学 1 +x:1 +到头 1 +x:1 +粮站 1 +x:1 +保险金 1 +x:1 +虎岁 1 +x:1 +江段 1 +x:1 +优越论 1 +x:1 +分娩期 1 +x:1 +劳动课 1 +x:1 +无外乎 1 +x:1 +柔美 1 +x:1 +轴承厂 1 +x:1 +人造毛 1 +x:1 +答复 1 +x:1 +住房款 1 +x:1 +军工 1 +x:1 +买路者 1 +x:1 +香饵 1 +x:1 +拼合 1 +x:1 +最低值 1 +x:1 +茶鸡蛋 1 +x:1 +视角 1 +x:1 +军帐 1 +x:1 +瓦头 1 +x:1 +八所 1 +x:1 +议案组 1 +x:1 +重点村 1 +x:1 +清净 1 +x:1 +那不勒斯 1 +x:1 +快餐 1 +x:1 +上辈 1 +x:1 +惰性元素 1 +x:1 +债主 1 +x:1 +视觉 1 +x:1 +军师 1 +x:1 +车况 1 +x:1 +上达 1 +x:1 +灌云县 1 +x:1 +侏罗系 1 +x:1 +上边 1 +x:1 +小管流 1 +x:1 +排除万难 1 +x:1 +军帽 1 +x:1 +大犬座 1 +x:1 +针芒 1 +x:1 +摩啰街 1 +x:1 +垒砌 1 +x:1 +羊肉串 1 +x:1 +电话簿 1 +x:1 +概念股 1 +x:1 +胡台镇 1 +x:1 +哭笑不得 1 +x:1 +清册 1 +x:1 +烂仔巷 1 +x:1 +录音室 1 +x:1 +银苗 1 +x:1 +上进 1 +x:1 +银质 1 +x:1 +疯狂性 1 +x:1 +秦皇岛市 1 +x:1 +奏折 1 +x:1 +作兴 1 +x:1 +近 3515 +x:3515 +左派 1 +x:1 +清军 1 +x:1 +银贷 1 +x:1 +银贸 1 +x:1 +残羹 1 +x:1 +疆界 1 +x:1 +消防队 1 +x:1 +诡异 1 +x:1 +义形于色 1 +x:1 +东西区 1 +x:1 +多聚糖 1 +x:1 +上述 1 +x:1 +清冽 1 +x:1 +铺板 1 +x:1 +风景点 1 +x:1 +两厢情愿 1 +x:1 +弥补性 1 +x:1 +虚脱 1 +x:1 +蒙混 1 +x:1 +区庆 1 +x:1 +亨源纸 1 +x:1 +台套 1 +x:1 +灯标 1 +x:1 +扑鼻 1 +x:1 +特级 1 +x:1 +特约 1 +x:1 +孝敬乡 1 +x:1 +安东市 1 +x:1 +陡山沱组 1 +x:1 +提货员 1 +x:1 +出以公心 1 +x:1 +拘谨 1 +x:1 +考察团 1 +x:1 +倾斜 1 +x:1 +双赢制 1 +x:1 +养猪场 1 +x:1 +赤字额 1 +x:1 +贝多芬 1 +x:1 +火电 1 +x:1 +汉白玉 1 +x:1 +魏善庄 1 +x:1 +消毒包 1 +x:1 +漫谈 1 +x:1 +恢恢 1 +x:1 +心电图 1 +x:1 +非殖民化 1 +x:1 +中消 1 +x:1 +佑 1 +x:1 +屈原镇 1 +x:1 +闽剧 1 +x:1 +城里 1 +x:1 +异国 1 +x:1 +残缺 1 +x:1 +蒙浓 1 +x:1 +值班员 1 +x:1 +人造棉 1 +x:1 +害人 1 +x:1 +惧怕 1 +x:1 +嗣后 1 +x:1 +租费 1 +x:1 +斯托克顿 1 +x:1 +微处理器 1 +x:1 +旅游业 1 +x:1 +城垣史 1 +x:1 +镭 2 +x:2 +震级 1 +x:1 +互忆 1 +x:1 +导言 1 +x:1 +台安县 1 +x:1 +蔗农 1 +x:1 +上车 1 +x:1 +罐式 1 +x:1 +迟滞 1 +x:1 +厌学症 1 +x:1 +答对 1 +x:1 +瑕疵 1 +x:1 +海粮 1 +x:1 +顶天立地 1 +x:1 +歌唱 1 +x:1 +导读 1 +x:1 +了井塘 1 +x:1 +对接点 1 +x:1 +捷径 1 +x:1 +乳粉 1 +x:1 +疯了呱几 1 +x:1 +解甲 1 +x:1 +球体 1 +x:1 +互帮 1 +x:1 +替续器 1 +x:1 +虎年 1 +x:1 +提灯 1 +x:1 +基色 1 +x:1 +警讯 1 +x:1 +历算论点 1 +x:1 +刹车片 1 +x:1 +愤 8 +x:8 +巨额 1 +x:1 +饱蘸 1 +x:1 +阑尾炎 1 +x:1 +阿富汗 1 +x:1 +持续 1 +x:1 +微肥 1 +x:1 +烟柱 1 +x:1 +田埠乡 1 +x:1 +静水压 1 +x:1 +互市 1 +x:1 +上身 1 +x:1 +朗县 1 +x:1 +跃兔 1 +x:1 +导诊 1 +x:1 +提灌 1 +x:1 +中质协 1 +x:1 +旺盛期 1 +x:1 +郅 18 +x:18 +犁市镇 1 +x:1 +石埠乡 1 +x:1 +导论 1 +x:1 +乳糖 1 +x:1 +专电 1 +x:1 +俊美 1 +x:1 +专用 1 +x:1 +密苏里 1 +x:1 +专心一志 1 +x:1 +警诫 1 +x:1 +警语 1 +x:1 +增减额 1 +x:1 +覃研精思 1 +x:1 +莲盛镇 1 +x:1 +无一例外 1 +x:1 +艺文 1 +x:1 +哭 106 +x:106 +核清 1 +x:1 +朱桥村 1 +x:1 +蛇口 1 +x:1 +信江 1 +x:1 +见势不妙 1 +x:1 +切中 1 +x:1 +暌违 1 +x:1 +横生枝节 1 +x:1 +所用 1 +x:1 +瘁 1 +x:1 +姻亲 1 +x:1 +驯服 1 +x:1 +台塑 1 +x:1 +绞包针 1 +x:1 +红猩猩 1 +x:1 +购机款 1 +x:1 +向好 1 +x:1 +果断性 1 +x:1 +静静 1 +x:1 +购买价 1 +x:1 +人生观 1 +x:1 +理论部 1 +x:1 +舒适型 1 +x:1 +谓语 1 +x:1 +硫黄岛 1 +x:1 +请便 1 +x:1 +日本餐 1 +x:1 +专业者 1 +x:1 +新大陆 1 +x:1 +闽北 1 +x:1 +毛细管 1 +x:1 +看不惯 1 +x:1 +服装界 1 +x:1 +正本 1 +x:1 +时装业 1 +x:1 +矿种 1 +x:1 +军徽 1 +x:1 +只管 1 +x:1 +清偿 1 +x:1 +灯笼裤 1 +x:1 +跨栏 1 +x:1 +谓词 1 +x:1 +振起 1 +x:1 +便盆 1 +x:1 +鉴别力 1 +x:1 +烧光 1 +x:1 +超正常 1 +x:1 +兜盖 1 +x:1 +太子参 1 +x:1 +呼呼地 1 +x:1 +东嘎镇 1 +x:1 +野鸟 1 +x:1 +海南岛 1 +x:1 +军心 1 +x:1 +使假 1 +x:1 +眼科 1 +x:1 +海米 1 +x:1 +北齐 1 +x:1 +目的地 1 +x:1 +教历 1 +x:1 +购买人 1 +x:1 +鸿篇巨制 1 +x:1 +闽南 1 +x:1 +毛用 1 +x:1 +灰质炎 1 +x:1 +线香 1 +x:1 +蒙污 1 +x:1 +团委 1 +x:1 +登陆 1 +x:1 +逆转 1 +x:1 +骨痹 1 +x:1 +上膘 1 +x:1 +上膛 1 +x:1 +朱明 1 +x:1 +蛇岛 1 +x:1 +现期 1 +x:1 +清心 1 +x:1 +平衡杆 1 +x:1 +军警宪特 1 +x:1 +侵蚀量 1 +x:1 +春天颂 1 +x:1 +微辞 1 +x:1 +奖价 1 +x:1 +台城 1 +x:1 +后记 1 +x:1 +经营方 1 +x:1 +剩菜 1 +x:1 +档案馆 1 +x:1 +所以 1 +x:1 +台基 1 +x:1 +震灾 1 +x:1 +到底 1 +x:1 +火箭 1 +x:1 +奖励 1 +x:1 +领导有方 1 +x:1 +满堂彩 1 +x:1 +瓦圈 1 +x:1 +燕尾鱼 1 +x:1 +执白 1 +x:1 +详明 1 +x:1 +骨病 1 +x:1 +专稿 1 +x:1 +杀虫率 1 +x:1 +洑家 1 +x:1 +布丁 1 +x:1 +灾害 1 +x:1 +不过尔尔 1 +x:1 +北郊 1 +x:1 +布业 1 +x:1 +注射费 1 +x:1 +张贴 1 +x:1 +以 14931 +x:14931 +直译 1 +x:1 +馅子 1 +x:1 +清徐 1 +x:1 +工稳 1 +x:1 +恩泽沁溢 1 +x:1 +铡刀 1 +x:1 +财金处 1 +x:1 +工程 1 +x:1 +瓦块 1 +x:1 +南中街 1 +x:1 +老汉 1 +x:1 +北部 1 +x:1 +专程 1 +x:1 +安居工程 1 +x:1 +风景线 1 +x:1 +杭锦旗 1 +x:1 +火篾 1 +x:1 +垃圾带 1 +x:1 +玉盘 1 +x:1 +朝三暮四 1 +x:1 +残照 1 +x:1 +蹼泳 1 +x:1 +台坛 1 +x:1 +杈子 1 +x:1 +布什 1 +x:1 +海猪 1 +x:1 +绘业 1 +x:1 +种养殖业 1 +x:1 +清廉者 1 +x:1 +警营 1 +x:1 +单车道 1 +x:1 +免费 1 +x:1 +非职务 1 +x:1 +北马集村 1 +x:1 +逆耳 1 +x:1 +便秘 1 +x:1 +蛇尾 1 +x:1 +线雕 1 +x:1 +海得拉巴 1 +x:1 +河西走廊 1 +x:1 +割 70 +x:70 +瓦垄 1 +x:1 +奖券 1 +x:1 +莫逆之交 1 +x:1 +剌叶栎 1 +x:1 +火笼 1 +x:1 +布于 1 +x:1 +团团 1 +x:1 +海獭 1 +x:1 +杂多 1 +x:1 +小报 1 +x:1 +凝汽油剂 1 +x:1 +甬道 1 +x:1 +饱览 1 +x:1 +呵痒 1 +x:1 +欣赏热 1 +x:1 +用钱 1 +x:1 +杯杯 1 +x:1 +台地 1 +x:1 +微软 1 +x:1 +墙面 1 +x:1 +蝴蝶树 1 +x:1 +河段 1 +x:1 +龙井茶 1 +x:1 +君主立宪 1 +x:1 +仿宋体 1 +x:1 +珲 2 +x:2 +龙眼树 1 +x:1 +馆中馆 1 +x:1 +失人者 1 +x:1 +沙土所 1 +x:1 +农发行 1 +x:1 +毛纺厂 1 +x:1 +广角镜头 1 +x:1 +清廉 1 +x:1 +星光 1 +x:1 +逆 13 +x:13 +预可行性 1 +x:1 +资治通鉴 1 +x:1 +喉气管 1 +x:1 +银色 1 +x:1 +三配套 1 +x:1 +史前 1 +x:1 +飘飘欲仙 1 +x:1 +团场 1 +x:1 +团圆 1 +x:1 +照片 1 +x:1 +希伯来人 1 +x:1 +复垦费 1 +x:1 +清廷 1 +x:1 +上肢 1 +x:1 +疏而不漏 1 +x:1 +教条主义 1 +x:1 +海狮 1 +x:1 +银碗赛 1 +x:1 +北里 1 +x:1 +谈何容易 1 +x:1 +甲级队 1 +x:1 +布伞 1 +x:1 +人造板 1 +x:1 +海狸 1 +x:1 +强押 1 +x:1 +舍弃 1 +x:1 +孝媳 1 +x:1 +徽 5 +x:5 +柯枝 1 +x:1 +障眼法 1 +x:1 +基调 1 +x:1 +海狗 1 +x:1 +文工团 1 +x:1 +优惠票 1 +x:1 +癌变 1 +x:1 +重点校 1 +x:1 +工笔 1 +x:1 +自动机 1 +x:1 +灯柱 1 +x:1 +惋惜 1 +x:1 +族别 1 +x:1 +坦诚相见 1 +x:1 +有求于 1 +x:1 +篮排球 1 +x:1 +出于无奈 1 +x:1 +联席会议 1 +x:1 +国议会 1 +x:1 +卫检 1 +x:1 +昆虫学家 1 +x:1 +军内 1 +x:1 +上者 1 +x:1 +全息照相 1 +x:1 +以色列队 1 +x:1 +采菜节 1 +x:1 +物理变化 1 +x:1 +航空港 1 +x:1 +掩盖剂 1 +x:1 +指路 1 +x:1 +产业工人 1 +x:1 +鸡肉 1 +x:1 +鸡肋 1 +x:1 +菌种 1 +x:1 +振荡 1 +x:1 +清幽 1 +x:1 +叉子 1 +x:1 +责成 1 +x:1 +常见病 1 +x:1 +侨资 1 +x:1 +提纲 1 +x:1 +闹表 1 +x:1 +登顶 1 +x:1 +上联 1 +x:1 +戎马倥偬 1 +x:1 +唯心史观 1 +x:1 +银花 1 +x:1 +燕子垭 1 +x:1 +提级 1 +x:1 +鸡胸 1 +x:1 +泪珠 1 +x:1 +提纯 1 +x:1 +攀枝花 1 +x:1 +五丰镇 1 +x:1 +延年益寿 1 +x:1 +兰花指 1 +x:1 +不锈钢管 1 +x:1 +团城 1 +x:1 +自动枪 1 +x:1 +医圣 1 +x:1 +避 43 +x:43 +豹 7 +x:7 +发布周 1 +x:1 +海牛 1 +x:1 +海牙 1 +x:1 +军列 1 +x:1 +沾边 1 +x:1 +烟雾弥漫 1 +x:1 +标本室 1 +x:1 +蛊惑人心 1 +x:1 +清川 1 +x:1 +张大庄 1 +x:1 +五公祠 1 +x:1 +清规戒律 1 +x:1 +恢河 1 +x:1 +基轴 1 +x:1 +咔唑 1 +x:1 +政论家 1 +x:1 +军制 1 +x:1 +昨 4 +x:4 +末路 1 +x:1 +海熊 1 +x:1 +垒球 1 +x:1 +杂声 1 +x:1 +特种工艺 1 +x:1 +便笺 1 +x:1 +苜蓿草 1 +x:1 +梭鲈 1 +x:1 +火种 1 +x:1 +金银铜 1 +x:1 +大部分 1 +x:1 +裸线 1 +x:1 +鹤山市 1 +x:1 +侵越 1 +x:1 +娟秀 1 +x:1 +大部制 1 +x:1 +黑匣子 1 +x:1 +折价 1 +x:1 +共鸣说 1 +x:1 +诠释 1 +x:1 +奏效 1 +x:1 +硬 256 +x:256 +藤蔓 1 +x:1 +海燕 1 +x:1 +警务 1 +x:1 +油客轮 1 +x:1 +红伞 1 +x:1 +团员 1 +x:1 +公司税 1 +x:1 +卫国 1 +x:1 +参展者 1 +x:1 +和睦 1 +x:1 +后顾之忧 1 +x:1 +军力 1 +x:1 +交通部 1 +x:1 +虎口 1 +x:1 +军功 1 +x:1 +台商 1 +x:1 +隆隆 1 +x:1 +进出口司 1 +x:1 +革除 1 +x:1 +铁路桥 1 +x:1 +黎城 1 +x:1 +河槽 1 +x:1 +木板楼 1 +x:1 +春江 1 +x:1 +巴特农 1 +x:1 +故弄玄虚 1 +x:1 +军务 1 +x:1 +哥伦比亚 1 +x:1 +样 73 +x:73 +解困房 1 +x:1 +核讹诈 1 +x:1 +梭鱼 1 +x:1 +百年一遇 1 +x:1 +必经 1 +x:1 +春汛 1 +x:1 +罐区 1 +x:1 +指鸡骂狗 1 +x:1 +墨彩画 1 +x:1 +喇嘛 1 +x:1 +艺校 1 +x:1 +共青城 1 +x:1 +诌 1 +x:1 +抑扬顿挫 1 +x:1 +拐 23 +x:23 +委身 1 +x:1 +经营权 1 +x:1 +匡 8 +x:8 +火神 1 +x:1 +险胜 1 +x:1 +现时 1 +x:1 +哺乳纲 1 +x:1 +基辅 1 +x:1 +快门 1 +x:1 +鼎力相助 1 +x:1 +知音者 1 +x:1 +第五组 1 +x:1 +丰台站 1 +x:1 +遮挡 1 +x:1 +揪心 1 +x:1 +歌剧 1 +x:1 +情投意合 1 +x:1 +针织 1 +x:1 +边地 1 +x:1 +庙 22 +x:22 +互利 1 +x:1 +洄水段 1 +x:1 +令人信服 1 +x:1 +晚清四王 1 +x:1 +辣 10 +x:10 +坩埚 1 +x:1 +巨钟 1 +x:1 +而言 1 +x:1 +军医 1 +x:1 +军区 1 +x:1 +鸡舍 1 +x:1 +众长凝一 1 +x:1 +朗德 1 +x:1 +火碱 1 +x:1 +坟 18 +x:18 +在职 1 +x:1 +直接肥料 1 +x:1 +鼓鼓的 1 +x:1 +乌蓝 1 +x:1 +骨盆 1 +x:1 +干头 1 +x:1 +针对性 1 +x:1 +白衣使者 1 +x:1 +军博 1 +x:1 +实验组 1 +x:1 +营销者 1 +x:1 +看走眼 1 +x:1 +卫城 1 +x:1 +东进 1 +x:1 +适逢其会 1 +x:1 +上苍 1 +x:1 +牙买加 1 +x:1 +骂不绝口 1 +x:1 +人琴俱亡 1 +x:1 +柱洞 1 +x:1 +拾级而上 1 +x:1 +蝉翼 1 +x:1 +享受性 1 +x:1 +下里巴人 1 +x:1 +暗访组 1 +x:1 +登高 1 +x:1 +表意文字 1 +x:1 +红专 1 +x:1 +迟报 1 +x:1 +香韵 1 +x:1 +泥巴路 1 +x:1 +乌蒙 1 +x:1 +政治科 1 +x:1 +责怪 1 +x:1 +巩固 1 +x:1 +活化石 1 +x:1 +步态 1 +x:1 +微调 1 +x:1 +下影线 1 +x:1 +我 13411 +x:13411 +歌海 1 +x:1 +品酒室 1 +x:1 +火砖 1 +x:1 +互动 1 +x:1 +互助 1 +x:1 +电磁感应 1 +x:1 +工种 1 +x:1 +奥陶纪 1 +x:1 +棉麻局 1 +x:1 +残片 1 +x:1 +指甲 1 +x:1 +专科 1 +x:1 +交通量 1 +x:1 +座位图 1 +x:1 +爱卫会 1 +x:1 +实惠主义 1 +x:1 +心酸 1 +x:1 +日历牌 1 +x:1 +骨癌 1 +x:1 +十里八乡 1 +x:1 +工科 1 +x:1 +场站 1 +x:1 +练鹊 1 +x:1 +碧云天 1 +x:1 +社会观 1 +x:1 +电码 1 +x:1 +腐植酸 1 +x:1 +红亮 1 +x:1 +泛舟 1 +x:1 +立邦漆 1 +x:1 +擦擦 1 +x:1 +控辩式 1 +x:1 +考察官 1 +x:1 +虎劲 1 +x:1 +沽售 1 +x:1 +火硝 1 +x:1 +军史 1 +x:1 +共青团 1 +x:1 +背光性 1 +x:1 +军号 1 +x:1 +沟沟岔岔 1 +x:1 +摔倒 1 +x:1 +转制率 1 +x:1 +浙大 1 +x:1 +绮 2 +x:2 +奋起拼搏 1 +x:1 +世相百态 1 +x:1 +鸡苗 1 +x:1 +平顶山 1 +x:1 +互勉 1 +x:1 +挠力河 1 +x:1 +瑕线 1 +x:1 +布朗托姆 1 +x:1 +米珠薪桂 1 +x:1 +笑脸相迎 1 +x:1 +无翼鸟 1 +x:1 +瓦匠 1 +x:1 +工兵连 1 +x:1 +孝心 1 +x:1 +文文雅雅 1 +x:1 +广为传颂 1 +x:1 +菌类 1 +x:1 +竹芋 1 +x:1 +激荡 1 +x:1 +一两点钟 1 +x:1 +北钢 1 +x:1 +水米无交 1 +x:1 +竹节 1 +x:1 +贲张 1 +x:1 +打假惩劣 1 +x:1 +迟早 1 +x:1 +照着 1 +x:1 +马鞍山市 1 +x:1 +称心如意 1 +x:1 +丹江口市 1 +x:1 +红山区 1 +x:1 +烟波 1 +x:1 +烟泡 1 +x:1 +用量 1 +x:1 +嶙峋 1 +x:1 +防蛀剂 1 +x:1 +答案 1 +x:1 +抬轿子 1 +x:1 +台历 1 +x:1 +清官 1 +x:1 +篡改 1 +x:1 +用稿量 1 +x:1 +茅草屋 1 +x:1 +全乡 1 +x:1 +全书 1 +x:1 +残疾 1 +x:1 +参与者 1 +x:1 +笼盖 1 +x:1 +季刊 1 +x:1 +冰冻三尺 1 +x:1 +部族 1 +x:1 +江户 1 +x:1 +英系 1 +x:1 +宫中 1 +x:1 +花样翻新 1 +x:1 +块头 1 +x:1 +急匆匆 1 +x:1 +底下 1 +x:1 +朗声 1 +x:1 +自然美 1 +x:1 +照看 1 +x:1 +范 298 +x:298 +台南 1 +x:1 +乌药 1 +x:1 +底价 1 +x:1 +各色人等 1 +x:1 +法理学 1 +x:1 +状纸 1 +x:1 +劳动节 1 +x:1 +委管局 1 +x:1 +硬质 1 +x:1 +刻印员 1 +x:1 +尚家大堰 1 +x:1 +提篮 1 +x:1 +官庄镇 1 +x:1 +和魂洋才 1 +x:1 +澡堂 1 +x:1 +保险额 1 +x:1 +碧幽幽 1 +x:1 +工细 1 +x:1 +刷洗 1 +x:1 +台卡 1 +x:1 +安定团结 1 +x:1 +客流 1 +x:1 +残留 1 +x:1 +垂线 1 +x:1 +向前 1 +x:1 +溘然辞世 1 +x:1 +羊肠道儿 1 +x:1 +提箱 1 +x:1 +专线 1 +x:1 +台北 1 +x:1 +三费一款 1 +x:1 +烈 19 +x:19 +烟气 1 +x:1 +全价 1 +x:1 +烟民 1 +x:1 +火网 1 +x:1 +火罐 1 +x:1 +偶然 1 +x:1 +香道 1 +x:1 +抽象美 1 +x:1 +英籍 1 +x:1 +务使 1 +x:1 +抬秤 1 +x:1 +读取 1 +x:1 +台区 1 +x:1 +旧杂式 1 +x:1 +烟水 1 +x:1 +松滋市 1 +x:1 +稳妥 1 +x:1 +读友 1 +x:1 +澡塘 1 +x:1 +牾 2 +x:2 +残生 1 +x:1 +坐收渔利 1 +x:1 +泪眼 1 +x:1 +特用 1 +x:1 +导致 1 +x:1 +诈骗犯 1 +x:1 +羊八井 1 +x:1 +瓦刺 1 +x:1 +香醇 1 +x:1 +煤灰堆 1 +x:1 +意大利式 1 +x:1 +卫冕 1 +x:1 +合练 1 +x:1 +东宋镇 1 +x:1 +事迹 1 +x:1 +英国籍 1 +x:1 +孝廉 1 +x:1 +全会 1 +x:1 +火红 1 +x:1 +全优 1 +x:1 +勉强 1 +x:1 +清嫩 1 +x:1 +河湾 1 +x:1 +用地量 1 +x:1 +实而不华 1 +x:1 +保护主义 1 +x:1 +现房 1 +x:1 +瓦刀 1 +x:1 +中凹型 1 +x:1 +章鱼 1 +x:1 +评估所 1 +x:1 +陶艺史 1 +x:1 +废元钢 1 +x:1 +火线 1 +x:1 +军售 1 +x:1 +复写纸 1 +x:1 +袖珍本 1 +x:1 +陈庄村 1 +x:1 +台办 1 +x:1 +无能者 1 +x:1 +造田 1 +x:1 +陶瓷质 1 +x:1 +骨炭 1 +x:1 +海相 1 +x:1 +海盆 1 +x:1 +卖弄聪明 1 +x:1 +得空 1 +x:1 +全体 1 +x:1 +羽毛球赛 1 +x:1 +先天不足 1 +x:1 +北门 1 +x:1 +火绳 1 +x:1 +语言性 1 +x:1 +一斑 1 +x:1 +河港 1 +x:1 +海监 1 +x:1 +海盐 1 +x:1 +满意房 1 +x:1 +冠军 1 +x:1 +似神非神 1 +x:1 +河渠 1 +x:1 +转捩点 1 +x:1 +孝幔 1 +x:1 +沈丘 1 +x:1 +照直 1 +x:1 +珍之惜之 1 +x:1 +微言 1 +x:1 +骨灰 1 +x:1 +灾年 1 +x:1 +到期 1 +x:1 +打拍子 1 +x:1 +瓦加 1 +x:1 +俯首 1 +x:1 +油漆 1 +x:1 +浅易 1 +x:1 +台前 1 +x:1 +张裂 1 +x:1 +使坏 1 +x:1 +平安南道 1 +x:1 +蛇头 1 +x:1 +不义之财 1 +x:1 +信息源 1 +x:1 +烟海 1 +x:1 +洋弟子 1 +x:1 +万能 1 +x:1 +自养 1 +x:1 +蒙昧 1 +x:1 +黏土 1 +x:1 +河滩 1 +x:1 +浅显 1 +x:1 +旺盛 1 +x:1 +栽子 1 +x:1 +攻 126 +x:126 +参事官 1 +x:1 +肾 25 +x:25 +水蜜桃 1 +x:1 +持球 1 +x:1 +堪为 1 +x:1 +封建社会 1 +x:1 +岳麓 1 +x:1 +河源 1 +x:1 +拼死拼活 1 +x:1 +合同额 1 +x:1 +野餐 1 +x:1 +实验 1 +x:1 +乌玉村 1 +x:1 +团史 1 +x:1 +抽签式 1 +x:1 +终极 1 +x:1 +隆重 1 +x:1 +专群 1 +x:1 +大酒店 1 +x:1 +玉玺 1 +x:1 +乳白 1 +x:1 +回天乏术 1 +x:1 +松松散散 1 +x:1 +达拉特旗 1 +x:1 +卫兵 1 +x:1 +到来 1 +x:1 +北石店乡 1 +x:1 +贩毒者 1 +x:1 +一手遮天 1 +x:1 +菌种场 1 +x:1 +深刻性 1 +x:1 +杂牌军 1 +x:1 +缺席 1 +x:1 +细高 1 +x:1 +纹枯病 1 +x:1 +亲戚家 1 +x:1 +铁路法 1 +x:1 +多吃多占 1 +x:1 +劳动者 1 +x:1 +发布厅 1 +x:1 +薪火 1 +x:1 +绵薄 1 +x:1 +河流 1 +x:1 +服装系 1 +x:1 +海疆 1 +x:1 +己方 1 +x:1 +悉数 1 +x:1 +提神 1 +x:1 +一新 1 +x:1 +无名火 1 +x:1 +蒙方 1 +x:1 +钥匙 1 +x:1 +屏气 1 +x:1 +脑外科 1 +x:1 +清妍 1 +x:1 +奖品 1 +x:1 +雇农 1 +x:1 +蒙族 1 +x:1 +提示 1 +x:1 +旱改水 1 +x:1 +微观 1 +x:1 +这些 1 +x:1 +主隧 1 +x:1 +抬筐 1 +x:1 +种子核 1 +x:1 +呜 1 +x:1 +长江局 1 +x:1 +财预 1 +x:1 +自动性 1 +x:1 +卫勤 1 +x:1 +玻利维亚 1 +x:1 +收汇 1 +x:1 +免诉 1 +x:1 +毫米汞柱 1 +x:1 +有头无尾 1 +x:1 +免试 1 +x:1 +兵马 1 +x:1 +仙苑奇蔬 1 +x:1 +瓣膜 1 +x:1 +军器 1 +x:1 +河津 1 +x:1 +慈城镇 1 +x:1 +除臭剂 1 +x:1 +称作 1 +x:1 +新亚型 1 +x:1 +剑术 1 +x:1 +垃圾堆 1 +x:1 +系统部 1 +x:1 +鲜鱼 1 +x:1 +卓有建树 1 +x:1 +提租 1 +x:1 +董鄂河 1 +x:1 +分隔符 1 +x:1 +海生 1 +x:1 +舒适度 1 +x:1 +烧塌 1 +x:1 +串连 1 +x:1 +痔漏 1 +x:1 +碎雪 1 +x:1 +名列榜首 1 +x:1 +读出 1 +x:1 +桌前 1 +x:1 +集腋成裘 1 +x:1 +觅食 1 +x:1 +扑面 1 +x:1 +论功行赏 1 +x:1 +袋装化 1 +x:1 +导航 1 +x:1 +铜 85 +x:85 +蛤蟆镜 1 +x:1 +寂寂 1 +x:1 +王官 1 +x:1 +⑧ 1 +x:1 +售粮者 1 +x:1 +主队 1 +x:1 +德州市 1 +x:1 +军团 1 +x:1 +北陵 1 +x:1 +眸神 1 +x:1 +稳扎稳打 1 +x:1 +主音 1 +x:1 +争奇斗妍 1 +x:1 +表姐妹 1 +x:1 +鹅掌风 1 +x:1 +处 1268 +x:1268 +声色俱厉 1 +x:1 +吃一堑 1 +x:1 +万世永存 1 +x:1 +要死不活 1 +x:1 +河汊 1 +x:1 +以色列 1 +x:1 +黄豆粉 1 +x:1 +语言所 1 +x:1 +屁滚尿流 1 +x:1 +营养日 1 +x:1 +抗腐性 1 +x:1 +快速 1 +x:1 +固定资金 1 +x:1 +情人楼 1 +x:1 +从长计议 1 +x:1 +军地 1 +x:1 +治理 1 +x:1 +陋舍 1 +x:1 +阿克苏河 1 +x:1 +闽宁 1 +x:1 +核试验 1 +x:1 +喇叭 1 +x:1 +河池 1 +x:1 +片状林 1 +x:1 +玉照 1 +x:1 +绝世 1 +x:1 +黑龙江团 1 +x:1 +争光 1 +x:1 +颤悠悠 1 +x:1 +张家堡乡 1 +x:1 +青草地 1 +x:1 +鸡虱 1 +x:1 +逸闻 1 +x:1 +绝不 1 +x:1 +矛 7 +x:7 +登山队 1 +x:1 +冠县 1 +x:1 +开办费 1 +x:1 +到时 1 +x:1 +司务长 1 +x:1 +汇编语言 1 +x:1 +大辂椎轮 1 +x:1 +峭 2 +x:2 +河水 1 +x:1 +侵袭 1 +x:1 +迟暮 1 +x:1 +北韵 1 +x:1 +跷 7 +x:7 +万般 1 +x:1 +须疮 1 +x:1 +社会活动 1 +x:1 +月 1902 +x:1902 +个子 1 +x:1 +虎园 1 +x:1 +党棍 1 +x:1 +炮舰外交 1 +x:1 +答卷 1 +x:1 +后悔不迭 1 +x:1 +唐钢 1 +x:1 +碘酒 1 +x:1 +聚义厅 1 +x:1 +虎图 1 +x:1 +碚 3 +x:3 +候客室 1 +x:1 +新绛县 1 +x:1 +波兰队 1 +x:1 +在制品 1 +x:1 +接唱 1 +x:1 +财务科 1 +x:1 +经营户 1 +x:1 +子结构 1 +x:1 +班头 1 +x:1 +狙击 1 +x:1 +军垦 1 +x:1 +骨牌 1 +x:1 +不名一文 1 +x:1 +丰功伟绩 1 +x:1 +五六点 1 +x:1 +河泥 1 +x:1 +终日 1 +x:1 +贩毒船 1 +x:1 +上虞 1 +x:1 +倾泻 1 +x:1 +微行 1 +x:1 +耍心眼儿 1 +x:1 +淌 22 +x:22 +复习题 1 +x:1 +倾注 1 +x:1 +子刊 1 +x:1 +国储棉 1 +x:1 +隔海相望 1 +x:1 +主持者 1 +x:1 +北非 1 +x:1 +经营所 1 +x:1 +收费量 1 +x:1 +外族人 1 +x:1 +河沿 1 +x:1 +火中取栗 1 +x:1 +中山服 1 +x:1 +称为 1 +x:1 +泪痕 1 +x:1 +鸡蛋 1 +x:1 +黄河 1 +x:1 +季军 1 +x:1 +绝交 1 +x:1 +绝产 1 +x:1 +主震 1 +x:1 +检察院 1 +x:1 +时有所闻 1 +x:1 +伯利恒 1 +x:1 +拾 48 +x:48 +标记原子 1 +x:1 +鹤壁市 1 +x:1 +河南 1 +x:1 +康健 1 +x:1 +拄杖 1 +x:1 +读者节 1 +x:1 +索雄 1 +x:1 +牵涉面 1 +x:1 +灯座 1 +x:1 +预付款 1 +x:1 +江干 1 +x:1 +拉制 1 +x:1 +底牌 1 +x:1 +军校 1 +x:1 +等离子 1 +x:1 +安享清福 1 +x:1 +底版 1 +x:1 +块数 1 +x:1 +舒适性 1 +x:1 +皮花 1 +x:1 +底片 1 +x:1 +失聪 1 +x:1 +宽 284 +x:284 +语序 1 +x:1 +跨径 1 +x:1 +省农办 1 +x:1 +直辖 1 +x:1 +晶亮亮 1 +x:1 +河北 1 +x:1 +篡夺 1 +x:1 +倾心尽力 1 +x:1 +法庭罪 1 +x:1 +直达 1 +x:1 +绝然 1 +x:1 +主席台 1 +x:1 +嘴巴 1 +x:1 +现役 1 +x:1 +猴年马月 1 +x:1 +合署 1 +x:1 +哥们儿 1 +x:1 +无条件 1 +x:1 +酶 16 +x:16 +京西 1 +x:1 +红生 1 +x:1 +全片 1 +x:1 +赈济款 1 +x:1 +嘉年华 1 +x:1 +拉力 1 +x:1 +镖师 1 +x:1 +反躬 1 +x:1 +灯市 1 +x:1 +惟恐 1 +x:1 +版画系 1 +x:1 +鹦鹉山 1 +x:1 +引 243 +x:243 +灯帘 1 +x:1 +深水港 1 +x:1 +全能化 1 +x:1 +军械 1 +x:1 +托托拉镇 1 +x:1 +揪斗 1 +x:1 +稿子 1 +x:1 +叽叽喳喳 1 +x:1 +弹力呢 1 +x:1 +老区办 1 +x:1 +至善至真 1 +x:1 +河口 1 +x:1 +少奶奶 1 +x:1 +深孚众望 1 +x:1 +浑水摸鱼 1 +x:1 +砥柱中流 1 +x:1 +批评界 1 +x:1 +证词 1 +x:1 +际遇 1 +x:1 +目的性 1 +x:1 +雇员 1 +x:1 +清朝 1 +x:1 +厦门岛 1 +x:1 +军棋 1 +x:1 +板桥酒 1 +x:1 +清朗 1 +x:1 +时事性 1 +x:1 +宣教局 1 +x:1 +五山镇 1 +x:1 +清末 1 +x:1 +五塘镇 1 +x:1 +枇杷膏 1 +x:1 +参观团 1 +x:1 +冰雪节 1 +x:1 +代表制 1 +x:1 +鸡爪疯 1 +x:1 +兵荒马乱 1 +x:1 +军交运输 1 +x:1 +防火办 1 +x:1 +杯影 1 +x:1 +舒适感 1 +x:1 +心得 1 +x:1 +墓石 1 +x:1 +黑眼珠 1 +x:1 +样儿 1 +x:1 +粘结 1 +x:1 +鼻端 1 +x:1 +请示 1 +x:1 +滕王阁 1 +x:1 +球票 1 +x:1 +到家 1 +x:1 +稳中有增 1 +x:1 +转卖 1 +x:1 +朗斯 1 +x:1 +抛头颅 1 +x:1 +头面人物 1 +x:1 +玉佩 1 +x:1 +东明县 1 +x:1 +铁路史 1 +x:1 +绝灭 1 +x:1 +付之东流 1 +x:1 +有意 1 +x:1 +监察司 1 +x:1 +余利 1 +x:1 +监察厅 1 +x:1 +烟农 1 +x:1 +水果商 1 +x:1 +反转 1 +x:1 +清暇 1 +x:1 +等角 1 +x:1 +灯心 1 +x:1 +东瑁洲 1 +x:1 +负重 1 +x:1 +腰花 1 +x:1 +演出厅 1 +x:1 +鼻窦 1 +x:1 +预测局 1 +x:1 +碘化钠 1 +x:1 +烧林 1 +x:1 +百鸟之王 1 +x:1 +胶元病 1 +x:1 +现年 1 +x:1 +为民请命 1 +x:1 +买主 1 +x:1 +语重心长 1 +x:1 +红松洼 1 +x:1 +色彩缤纷 1 +x:1 +自销权 1 +x:1 +新郑县 1 +x:1 +上梅洲村 1 +x:1 +稞麦 1 +x:1 +从动 1 +x:1 +薪俸 1 +x:1 +藏书室 1 +x:1 +污物 1 +x:1 +南风 1 +x:1 +海丰 1 +x:1 +合算 1 +x:1 +鼓鼓囊囊 1 +x:1 +谈论 1 +x:1 +藏书家 1 +x:1 +烧杯 1 +x:1 +营养学 1 +x:1 +比不上 1 +x:1 +切磋 1 +x:1 +田舍 1 +x:1 +奖次 1 +x:1 +劢 1 +x:1 +清晨 1 +x:1 +豆蔻年华 1 +x:1 +烟具 1 +x:1 +台湾 1 +x:1 +望闻问切 1 +x:1 +落花流水 1 +x:1 +清晰 1 +x:1 +曲终奏雅 1 +x:1 +班机 1 +x:1 +业务量 1 +x:1 +杂说 1 +x:1 +清明 1 +x:1 +务牧 1 +x:1 +徐缓 1 +x:1 +脑血栓 1 +x:1 +一哄而上 1 +x:1 +铎 30 +x:30 +豫剧团 1 +x:1 +全班 1 +x:1 +累计额 1 +x:1 +满意度 1 +x:1 +显微镜 1 +x:1 +河势 1 +x:1 +G 8 +x:8 +灯彩 1 +x:1 +航空器 1 +x:1 +农副业 1 +x:1 +模糊 1 +x:1 +眉飞色舞 1 +x:1 +动情处 1 +x:1 +教育部长 1 +x:1 +驯养 1 +x:1 +风凉话 1 +x:1 +一木难支 1 +x:1 +习惯法 1 +x:1 +疲乏不堪 1 +x:1 +可怜兮兮 1 +x:1 +灯影 1 +x:1 +皮肉 1 +x:1 +蚁啃 1 +x:1 +选贤任能 1 +x:1 +同工同酬 1 +x:1 +拉倒 1 +x:1 +帮贫致富 1 +x:1 +公文包 1 +x:1 +剑客 1 +x:1 +底火 1 +x:1 +回教徒 1 +x:1 +驼马 1 +x:1 +诿过于人 1 +x:1 +映照 1 +x:1 +怒形于色 1 +x:1 +失色 1 +x:1 +清早 1 +x:1 +新风星 1 +x:1 +反调 1 +x:1 +茶钱 1 +x:1 +皮股 1 +x:1 +基金委 1 +x:1 +皮肤 1 +x:1 +江山 1 +x:1 +直路 1 +x:1 +有失公允 1 +x:1 +冷不丁 1 +x:1 +矿砂 1 +x:1 +殴 1 +x:1 +发展金 1 +x:1 +独立日 1 +x:1 +防微杜渐 1 +x:1 +雪地 1 +x:1 +宣汉 1 +x:1 +厦门市 1 +x:1 +组织员 1 +x:1 +拼接 1 +x:1 +时隐时现 1 +x:1 +红眼 1 +x:1 +称王 1 +x:1 +名传千古 1 +x:1 +歌咏 1 +x:1 +弃暗投明 1 +x:1 +人烟稀少 1 +x:1 +扣球奖 1 +x:1 +暗色 1 +x:1 +叶榭镇 1 +x:1 +氰化物 1 +x:1 +藕汁 1 +x:1 +清新 1 +x:1 +聚合醇类 1 +x:1 +迈进 1 +x:1 +碱荒 1 +x:1 +湖西河 1 +x:1 +攀越 1 +x:1 +作曲 1 +x:1 +貂熊 1 +x:1 +呐喊助威 1 +x:1 +记不清 1 +x:1 +贯穿辐射 1 +x:1 +简易师范 1 +x:1 +红石 1 +x:1 +碱草 1 +x:1 +红矾 1 +x:1 +才疏学浅 1 +x:1 +中江村 1 +x:1 +鼻祖 1 +x:1 +爆满 1 +x:1 +育儿 1 +x:1 +责备 1 +x:1 +购销型 1 +x:1 +猎户座 1 +x:1 +暗花 1 +x:1 +随军 1 +x:1 +蒙头 1 +x:1 +龙竹坪 1 +x:1 +江岛 1 +x:1 +镐头 1 +x:1 +孝感 1 +x:1 +大洲岛 1 +x:1 +失节 1 +x:1 +露珠 1 +x:1 +灯展 1 +x:1 +河内 1 +x:1 +反目为仇 1 +x:1 +江岸 1 +x:1 +白话诗 1 +x:1 +歌名 1 +x:1 +亚尔乡 1 +x:1 +发明者 1 +x:1 +整肃 1 +x:1 +常见于 1 +x:1 +歌吟 1 +x:1 +清收 1 +x:1 +忠贞不渝 1 +x:1 +赤金 1 +x:1 +东街 1 +x:1 +大刀阔斧 1 +x:1 +告捷 1 +x:1 +息息相通 1 +x:1 +智残人 1 +x:1 +东风乡 1 +x:1 +攀谈 1 +x:1 +大盖帽 1 +x:1 +全然 1 +x:1 +远途 1 +x:1 +捏造 1 +x:1 +骑 118 +x:118 +邓底村 1 +x:1 +孝昌 1 +x:1 +窗缝 1 +x:1 +绝版 1 +x:1 +踞 35 +x:35 +业余教育 1 +x:1 +烟叶 1 +x:1 +倾倒 1 +x:1 +废耕地 1 +x:1 +偷渡客 1 +x:1 +烟台 1 +x:1 +张店区 1 +x:1 +个别差异 1 +x:1 +铜鼓乡 1 +x:1 +斩头去尾 1 +x:1 +知遇之恩 1 +x:1 +灾情 1 +x:1 +牙防 1 +x:1 +沉沦 1 +x:1 +数百上千 1 +x:1 +参照物 1 +x:1 +雁荡路 1 +x:1 +蚁后 1 +x:1 +瓦池 1 +x:1 +现局 1 +x:1 +懂得 1 +x:1 +拼抢 1 +x:1 +污点 1 +x:1 +胸椎 1 +x:1 +偶人 1 +x:1 +灾患 1 +x:1 +阿北乡 1 +x:1 +烟厂 1 +x:1 +寓教于乐 1 +x:1 +军歌 1 +x:1 +跑道 1 +x:1 +管钳子 1 +x:1 +重金属 1 +x:1 +杀气 1 +x:1 +烧料 1 +x:1 +歌喉 1 +x:1 +终天 1 +x:1 +郁郁不乐 1 +x:1 +秀水坪村 1 +x:1 +争鸣 1 +x:1 +跑遍 1 +x:1 +赤道 1 +x:1 +乾隆 1 +x:1 +芙蓉区 1 +x:1 +小钢炮 1 +x:1 +江州 1 +x:1 +向海 1 +x:1 +心向往之 1 +x:1 +台江 1 +x:1 +朗朗 1 +x:1 +泪汪汪 1 +x:1 +达赖喇嘛 1 +x:1 +不如说 1 +x:1 +画梅集 1 +x:1 +纯金 1 +x:1 +铁老大 1 +x:1 +养猪户 1 +x:1 +夹藏 1 +x:1 +烟卷 1 +x:1 +车号 1 +x:1 +掩面而泣 1 +x:1 +绘画 1 +x:1 +刻骨铭心 1 +x:1 +千依百顺 1 +x:1 +下塘村 1 +x:1 +空港区 1 +x:1 +红盘 1 +x:1 +菜篮子 1 +x:1 +加勒比 1 +x:1 +体工大队 1 +x:1 +田联 1 +x:1 +格林威治 1 +x:1 +卖官者 1 +x:1 +棍 5 +x:5 +一代人 1 +x:1 +白瓜子 1 +x:1 +枇杷花 1 +x:1 +航空员 1 +x:1 +水烟筒 1 +x:1 +国债券 1 +x:1 +境外 1 +x:1 +赟 2 +x:2 +西门口 1 +x:1 +完璧归赵 1 +x:1 +胆大包天 1 +x:1 +弗罗阿登 1 +x:1 +读法 1 +x:1 +合称 1 +x:1 +沈灶 1 +x:1 +抬举 1 +x:1 +马雄山 1 +x:1 +决算期 1 +x:1 +产出率 1 +x:1 +境头 1 +x:1 +红煤 1 +x:1 +搀 5 +x:5 +军民 1 +x:1 +直话 1 +x:1 +莅 3 +x:3 +河坝 1 +x:1 +簇坐 1 +x:1 +少数派 1 +x:1 +互派 1 +x:1 +布片 1 +x:1 +憨直 1 +x:1 +鼻翼 1 +x:1 +废品率 1 +x:1 +墓 83 +x:83 +中转 1 +x:1 +割裂 1 +x:1 +电话业 1 +x:1 +吠 1 +x:1 +代表团 1 +x:1 +直通车 1 +x:1 +买卖方 1 +x:1 +以理服人 1 +x:1 +直说 1 +x:1 +设计费 1 +x:1 +终年 1 +x:1 +雪坡 1 +x:1 +球类 1 +x:1 +演出团 1 +x:1 +膘肥肉厚 1 +x:1 +东轮 1 +x:1 +东软 1 +x:1 +河坡 1 +x:1 +台毯 1 +x:1 +到庭 1 +x:1 +长长的 1 +x:1 +小命 1 +x:1 +皮蛋 1 +x:1 +推行 1 +x:1 +滇 19 +x:19 +销售者 1 +x:1 +现存 1 +x:1 +赤面 1 +x:1 +陌 1 +x:1 +绍兴 1 +x:1 +味觉 1 +x:1 +阵发性 1 +x:1 +剪刀差 1 +x:1 +终市 1 +x:1 +国画系 1 +x:1 +异彩纷呈 1 +x:1 +身心交瘁 1 +x:1 +土著人 1 +x:1 +剑川 1 +x:1 +照会 1 +x:1 +古生物学 1 +x:1 +借贷者 1 +x:1 +互济 1 +x:1 +航空史 1 +x:1 +减震器 1 +x:1 +下落不明 1 +x:1 +亏心事 1 +x:1 +源头者 1 +x:1 +现实 1 +x:1 +班戈 1 +x:1 +有形损耗 1 +x:1 +绝症 1 +x:1 +悉心 1 +x:1 +电子琴 1 +x:1 +钠 17 +x:17 +卫校 1 +x:1 +底盘 1 +x:1 +晚班 1 +x:1 +电话亭 1 +x:1 +自发性 1 +x:1 +西班牙 1 +x:1 +余波未停 1 +x:1 +贱 11 +x:11 +藏书库 1 +x:1 +烛照 1 +x:1 +秋耕 1 +x:1 +台步 1 +x:1 +跑鞋 1 +x:1 +合约 1 +x:1 +笼下 1 +x:1 +务真 1 +x:1 +卡那霉素 1 +x:1 +军法 1 +x:1 +解困局 1 +x:1 +板桥镇 1 +x:1 +不徇私情 1 +x:1 +编创人员 1 +x:1 +积压品 1 +x:1 +渔养业 1 +x:1 +希腊队 1 +x:1 +孝服 1 +x:1 +球粒 1 +x:1 +写道 1 +x:1 +茶针 1 +x:1 +杯子 1 +x:1 +中外方 1 +x:1 +全盛 1 +x:1 +全盘 1 +x:1 +矢 5 +x:5 +政变案 1 +x:1 +全盟 1 +x:1 +续订 1 +x:1 +叛国罪 1 +x:1 +全盔 1 +x:1 +东边 1 +x:1 +台次 1 +x:1 +崭新 1 +x:1 +营养师 1 +x:1 +草甸子 1 +x:1 +照例 1 +x:1 +密特朗 1 +x:1 +海产 1 +x:1 +江孜 1 +x:1 +灰锰氧 1 +x:1 +股海 1 +x:1 +大头菜 1 +x:1 +终归 1 +x:1 +应缴款 1 +x:1 +红灯 1 +x:1 +合编 1 +x:1 +红火 1 +x:1 +技不如人 1 +x:1 +享乐 1 +x:1 +草菅人命 1 +x:1 +手术钳 1 +x:1 +清拖 1 +x:1 +等闲之辈 1 +x:1 +三七 1 +x:1 +电话会 1 +x:1 +阅报 1 +x:1 +镖客 1 +x:1 +石英钟 1 +x:1 +迎新 1 +x:1 +东洞山 1 +x:1 +同呼吸 1 +x:1 +诸事缠身 1 +x:1 +鱼骨 1 +x:1 +长水村 1 +x:1 +边花闲草 1 +x:1 +南门湾 1 +x:1 +全省 1 +x:1 +录音棚 1 +x:1 +砾 2 +x:2 +千里马 1 +x:1 +集体所有 1 +x:1 +松辽 1 +x:1 +工程车 1 +x:1 +照主 1 +x:1 +东鳞西爪 1 +x:1 +动脉血 1 +x:1 +白山市 1 +x:1 +喀拉拉邦 1 +x:1 +自傲 1 +x:1 +机车厂 1 +x:1 +歌厅 1 +x:1 +阜阳 1 +x:1 +团歌 1 +x:1 +主席国 1 +x:1 +触 25 +x:25 +承重 1 +x:1 +泄水闸 1 +x:1 +虫胶 1 +x:1 +骚乱者 1 +x:1 +虎气 1 +x:1 +烧掉 1 +x:1 +秦陵编 1 +x:1 +乳业 1 +x:1 +红烧 1 +x:1 +楔形文字 1 +x:1 +和田 1 +x:1 +争食 1 +x:1 +老黄牛 1 +x:1 +谷物 1 +x:1 +一端 1 +x:1 +缭绕 1 +x:1 +胡闹 1 +x:1 +松软 1 +x:1 +洛 2 +x:2 +宣泄 1 +x:1 +辜 47 +x:47 +瓦檐 1 +x:1 +清扬 1 +x:1 +清扫 1 +x:1 +烧损 1 +x:1 +摄影部 1 +x:1 +貂皮 1 +x:1 +乾道 1 +x:1 +同代人 1 +x:1 +海上 1 +x:1 +详实 1 +x:1 +正时 1 +x:1 +引号 1 +x:1 +台橡 1 +x:1 +艺坛 1 +x:1 +烛火 1 +x:1 +一字一顿 1 +x:1 +纯音 1 +x:1 +合群 1 +x:1 +红烛 1 +x:1 +全矿 1 +x:1 +暗藏 1 +x:1 +江安 1 +x:1 +提货期 1 +x:1 +接通率 1 +x:1 +九 1576 +x:1576 +锁麟囊 1 +x:1 +江宁 1 +x:1 +接合 1 +x:1 +权益部 1 +x:1 +灾星 1 +x:1 +享享 1 +x:1 +粘稠 1 +x:1 +反诉 1 +x:1 +账户卡 1 +x:1 +倾囊 1 +x:1 +详密 1 +x:1 +演算 1 +x:1 +反话 1 +x:1 +拼搏 1 +x:1 +阅书报室 1 +x:1 +家委会 1 +x:1 +水果刀 1 +x:1 +团校 1 +x:1 +持券人 1 +x:1 +驼鹿 1 +x:1 +直角 1 +x:1 +龙型 1 +x:1 +唇齿音 1 +x:1 +连心桥 1 +x:1 +特为 1 +x:1 +肺鱼 1 +x:1 +艾滋病 1 +x:1 +灯墙 1 +x:1 +直觉 1 +x:1 +直视 1 +x:1 +终局 1 +x:1 +脚 260 +x:260 +直观 1 +x:1 +英伦三岛 1 +x:1 +史海 1 +x:1 +洋车 1 +x:1 +以卵投石 1 +x:1 +终将 1 +x:1 +姻缘 1 +x:1 +教养 1 +x:1 +烟囱 1 +x:1 +语言学 1 +x:1 +特业 1 +x:1 +污痕 1 +x:1 +特殊化 1 +x:1 +全球 1 +x:1 +军港 1 +x:1 +单件性 1 +x:1 +反衬 1 +x:1 +从句 1 +x:1 +习武者 1 +x:1 +星云 1 +x:1 +万人空巷 1 +x:1 +始祖鸟 1 +x:1 +河唇 1 +x:1 +汜 1 +x:1 +用户量 1 +x:1 +己巳 1 +x:1 +标语牌 1 +x:1 +拉呱 1 +x:1 +破裂音 1 +x:1 +秦皇岛港 1 +x:1 +瓦楞 1 +x:1 +所盗物 1 +x:1 +陈皮 1 +x:1 +招领箱 1 +x:1 +上岩洞 1 +x:1 +灯壶 1 +x:1 +八角茴香 1 +x:1 +东购 1 +x:1 +灯壳 1 +x:1 +攀西 1 +x:1 +台榭 1 +x:1 +负队 1 +x:1 +村里人 1 +x:1 +标金 1 +x:1 +散兵游勇 1 +x:1 +何足挂齿 1 +x:1 +阴沉 1 +x:1 +咸水湖 1 +x:1 +特产 1 +x:1 +儿马 1 +x:1 +驾驶证者 1 +x:1 +寻踪 1 +x:1 +标量 1 +x:1 +荮 1 +x:1 +监察员 1 +x:1 +不得已 1 +x:1 +特事 1 +x:1 +特二 1 +x:1 +簧 1 +x:1 +期交所 1 +x:1 +江声 1 +x:1 +钱串子 1 +x:1 +艺员 1 +x:1 +矿粉 1 +x:1 +电风扇 1 +x:1 +观念形态 1 +x:1 +残余 1 +x:1 +细胞膜 1 +x:1 +购买群 1 +x:1 +养猪村 1 +x:1 +转氨基酶 1 +x:1 +阅处 1 +x:1 +虫草 1 +x:1 +政治委员 1 +x:1 +网 191 +x:191 +珹 1 +x:1 +迎送 1 +x:1 +灯塔 1 +x:1 +震中 1 +x:1 +特价 1 +x:1 +艺名 1 +x:1 +激进派别 1 +x:1 +岔南乡 1 +x:1 +充饥 1 +x:1 +认知科学 1 +x:1 +烟嘴 1 +x:1 +布点 1 +x:1 +擦肩而过 1 +x:1 +航空兵 1 +x:1 +伽利略 1 +x:1 +经营学 1 +x:1 +蚁 1 +x:1 +娱乐 1 +x:1 +总理室 1 +x:1 +送餐费 1 +x:1 +井冈山 1 +x:1 +罪孽深重 1 +x:1 +走漏风声 1 +x:1 +请缨 1 +x:1 +娇柔 1 +x:1 +倾听 1 +x:1 +球网 1 +x:1 +球罐 1 +x:1 +黏液 1 +x:1 +红牌 1 +x:1 +迟延 1 +x:1 +望风披靡 1 +x:1 +直裰 1 +x:1 +自然经济 1 +x:1 +讳 1 +x:1 +毙命 1 +x:1 +一满意 1 +x:1 +拼板 1 +x:1 +受资国 1 +x:1 +造作 1 +x:1 +绍剧 1 +x:1 +增值率 1 +x:1 +共和国院 1 +x:1 +固墙镇 1 +x:1 +闭合性 1 +x:1 +请罪 1 +x:1 +杯壁 1 +x:1 +棕色 1 +x:1 +增加值 1 +x:1 +通古斯 1 +x:1 +揪扯 1 +x:1 +全州县 1 +x:1 +特使 1 +x:1 +考察期 1 +x:1 +哭喊者 1 +x:1 +毅然 1 +x:1 +悉尼 1 +x:1 +雅温得 1 +x:1 +四平市 1 +x:1 +秋菊 1 +x:1 +返聘者 1 +x:1 +屠宰 1 +x:1 +厕所 1 +x:1 +裹进 1 +x:1 +荧光灯 1 +x:1 +冷板凳 1 +x:1 +合肥市 1 +x:1 +防反术 1 +x:1 +造价 1 +x:1 +一破了之 1 +x:1 +持久 1 +x:1 +侍应生 1 +x:1 +转运费 1 +x:1 +巴德梅 1 +x:1 +诗词 1 +x:1 +正文 1 +x:1 +莫斯科市 1 +x:1 +中央门 1 +x:1 +直行 1 +x:1 +吸收量 1 +x:1 +总的看 1 +x:1 +前人种树 1 +x:1 +台桌 1 +x:1 +唐沟村 1 +x:1 +特例 1 +x:1 +使唤 1 +x:1 +省纪委 1 +x:1 +社会课 1 +x:1 +鸡零狗碎 1 +x:1 +红狐 1 +x:1 +莱西县 1 +x:1 +微处理机 1 +x:1 +灯头 1 +x:1 +旗袍 1 +x:1 +族民 1 +x:1 +烟土 1 +x:1 +原判 1 +x:1 +害羞 1 +x:1 +大南门 1 +x:1 +双学双争 1 +x:1 +南麓 1 +x:1 +惟有 1 +x:1 +烟圈 1 +x:1 +厉行改革 1 +x:1 +雷米特杯 1 +x:1 +新安镇 1 +x:1 +读诗班 1 +x:1 +浩大 1 +x:1 +叶腋 1 +x:1 +穴施 1 +x:1 +健 252 +x:252 +瑞士制 1 +x:1 +史河 1 +x:1 +切线 1 +x:1 +冲绳馆 1 +x:1 +如诗如画 1 +x:1 +下城区 1 +x:1 +骨 33 +x:33 +蒙山 1 +x:1 +学贯中西 1 +x:1 +负面 1 +x:1 +文冠果 1 +x:1 +全稿 1 +x:1 +数一数二 1 +x:1 +榴弹炮 1 +x:1 +科研费 1 +x:1 +课表 1 +x:1 +失血 1 +x:1 +丰隆 1 +x:1 +入学量 1 +x:1 +七六年 1 +x:1 +读本 1 +x:1 +数米而炊 1 +x:1 +称称 1 +x:1 +室内赛 1 +x:1 +现场 1 +x:1 +烟壶 1 +x:1 +江苏队 1 +x:1 +外在化 1 +x:1 +躯 10 +x:10 +失衡 1 +x:1 +‰ 1 +x:1 +螃蟹 1 +x:1 +公文夹 1 +x:1 +东荡 1 +x:1 +桑寄生 1 +x:1 +现在 1 +x:1 +篡党 1 +x:1 +有名儿 1 +x:1 +彝良 1 +x:1 +底稿 1 +x:1 +饥肠辘辘 1 +x:1 +清澈 1 +x:1 +清澄 1 +x:1 +索道 1 +x:1 +瓦松 1 +x:1 +天有一算 1 +x:1 +京腔 1 +x:1 +矿物 1 +x:1 +孝敬 1 +x:1 +蒙受 1 +x:1 +肆扰 1 +x:1 +近代化 1 +x:1 +闩 1 +x:1 +绘绣 1 +x:1 +铸模 1 +x:1 +拜物教 1 +x:1 +摊头 1 +x:1 +豁出去 1 +x:1 +公安科 1 +x:1 +水气热 1 +x:1 +饶 33 +x:33 +晋园队 1 +x:1 +自在 1 +x:1 +京二胡 1 +x:1 +灾殃 1 +x:1 +近代史 1 +x:1 +南里 1 +x:1 +回忆录 1 +x:1 +滇东南 1 +x:1 +商亭 1 +x:1 +搏击 1 +x:1 +威虎山 1 +x:1 +绝种 1 +x:1 +嘴唇 1 +x:1 +药引子 1 +x:1 +可变电容 1 +x:1 +喀若拉 1 +x:1 +休斯敦 1 +x:1 +胖乎乎 1 +x:1 +台板 1 +x:1 +代表者 1 +x:1 +中质油 1 +x:1 +枕心 1 +x:1 +男排 1 +x:1 +接力赛跑 1 +x:1 +剑兰 1 +x:1 +农工商贸 1 +x:1 +愧色 1 +x:1 +东莞 1 +x:1 +铁四局 1 +x:1 +不甚了了 1 +x:1 +钉鞋 1 +x:1 +军情 1 +x:1 +博极群书 1 +x:1 +海运局 1 +x:1 +经营商 1 +x:1 +匿迹销声 1 +x:1 +全站 1 +x:1 +味蕾 1 +x:1 +须德海 1 +x:1 +东莱 1 +x:1 +提供 1 +x:1 +闽江 1 +x:1 +校注者 1 +x:1 +底窑 1 +x:1 +叶绿素 1 +x:1 +国贸 1 +x:1 +布线 1 +x:1 +基干民兵 1 +x:1 +发人深省 1 +x:1 +台本 1 +x:1 +燃眉之急 1 +x:1 +俗言俚语 1 +x:1 +鱼跃龙门 1 +x:1 +羊皮感 1 +x:1 +终南 1 +x:1 +洁牙剂 1 +x:1 +奖掖 1 +x:1 +设计者 1 +x:1 +连锁 1 +x:1 +布置 1 +x:1 +嗣母 1 +x:1 +争先恐后 1 +x:1 +团服 1 +x:1 +市百一店 1 +x:1 +氮 31 +x:31 +下不了台 1 +x:1 +中残联 1 +x:1 +托老院 1 +x:1 +之外 1 +x:1 +需求 1 +x:1 +坡 54 +x:54 +上镜率 1 +x:1 +台路沟乡 1 +x:1 +南退 1 +x:1 +畛域 1 +x:1 +诡怪 1 +x:1 +屎 13 +x:13 +枕席 1 +x:1 +土产 1 +x:1 +绿苞儿 1 +x:1 +知者 1 +x:1 +海南戏 1 +x:1 +南通 1 +x:1 +祠 3 +x:3 +监察室 1 +x:1 +代表室 1 +x:1 +湖西村 1 +x:1 +丰韵 1 +x:1 +看货费 1 +x:1 +宏定位 1 +x:1 +浍史村 1 +x:1 +老汤 1 +x:1 +雇工 1 +x:1 +珍珠梅 1 +x:1 +狩猎 1 +x:1 +栋号 1 +x:1 +东航 1 +x:1 +内讧 1 +x:1 +空白处 1 +x:1 +印度支那 1 +x:1 +提价 1 +x:1 +推陈出新 1 +x:1 +吹糠见米 1 +x:1 +南郊 1 +x:1 +答数 1 +x:1 +江城 1 +x:1 +向来 1 +x:1 +稷山 1 +x:1 +往返票 1 +x:1 +内包装 1 +x:1 +清湖 1 +x:1 +中国部 1 +x:1 +纳溪区 1 +x:1 +摔打 1 +x:1 +南部 1 +x:1 +红糖 1 +x:1 +收官战 1 +x:1 +是非观 1 +x:1 +轮值 1 +x:1 +广播电台 1 +x:1 +恢弘 1 +x:1 +提亲 1 +x:1 +幼儿教育 1 +x:1 +清清 1 +x:1 +精品课 1 +x:1 +沙俄 1 +x:1 +互惠 1 +x:1 +红粱 1 +x:1 +裹腿 1 +x:1 +毡幕 1 +x:1 +驱逐舰 1 +x:1 +默默不语 1 +x:1 +购买点 1 +x:1 +不得劲 1 +x:1 +当地人 1 +x:1 +京胡 1 +x:1 +等腰 1 +x:1 +憨笑 1 +x:1 +闽浙 1 +x:1 +红粉 1 +x:1 +切点 1 +x:1 +滴定管 1 +x:1 +江垭 1 +x:1 +总加 1 +x:1 +阴离子 1 +x:1 +壶 15 +x:15 +大兴土木 1 +x:1 +队友 1 +x:1 +全篇 1 +x:1 +睿 2 +x:2 +为政之道 1 +x:1 +皮袋 1 +x:1 +莱西市 1 +x:1 +连队 1 +x:1 +橙红色 1 +x:1 +堪称 1 +x:1 +徒然 1 +x:1 +细胞质 1 +x:1 +经营型 1 +x:1 +蒙军 1 +x:1 +坯料 1 +x:1 +正点 1 +x:1 +太清宫 1 +x:1 +污秽 1 +x:1 +秋荔亭 1 +x:1 +清淤 1 +x:1 +该罪 1 +x:1 +清淡 1 +x:1 +蒙冤 1 +x:1 +讣闻 1 +x:1 +装箱单 1 +x:1 +伪劣 1 +x:1 +绝笔 1 +x:1 +读数 1 +x:1 +中外文 1 +x:1 +边检处 1 +x:1 +皮装 1 +x:1 +紫禁城 1 +x:1 +矿灯 1 +x:1 +失言 1 +x:1 +受益匪浅 1 +x:1 +连降 1 +x:1 +互换 1 +x:1 +长眠不醒 1 +x:1 +医械 1 +x:1 +近期 1 +x:1 +高频电波 1 +x:1 +扁平足 1 +x:1 +函授生 1 +x:1 +若有所失 1 +x:1 +英吉利 1 +x:1 +0 70 +x:70 +福鼎市 1 +x:1 +奖惩 1 +x:1 +台方 1 +x:1 +说到做到 1 +x:1 +轮 830 +x:830 +俊俏 1 +x:1 +拙朴 1 +x:1 +底码 1 +x:1 +安守本分 1 +x:1 +管家务乡 1 +x:1 +魔鬼 1 +x:1 +毒气室 1 +x:1 +枕巾 1 +x:1 +塞擦音 1 +x:1 +矿点 1 +x:1 +黏性 1 +x:1 +清流 1 +x:1 +拼死 1 +x:1 +一着不慎 1 +x:1 +妖蜮 1 +x:1 +栗 8 +x:8 +滞期 1 +x:1 +强权 1 +x:1 +电动机 1 +x:1 +艺专人 1 +x:1 +瓦斯 1 +x:1 +郡县制 1 +x:1 +台数 1 +x:1 +商界 1 +x:1 +必亡 1 +x:1 +热气腾腾 1 +x:1 +纸马轿 1 +x:1 +势在必进 1 +x:1 +致歉 1 +x:1 +遮天盖地 1 +x:1 +增白剂 1 +x:1 +导航站 1 +x:1 +风口浪尖 1 +x:1 +烧水 1 +x:1 +垃圾池 1 +x:1 +骤减 1 +x:1 +清洁 1 +x:1 +弹力布 1 +x:1 +冀城县 1 +x:1 +清洗 1 +x:1 +俗成于下 1 +x:1 +录音机 1 +x:1 +杠铃 1 +x:1 +谢湖村 1 +x:1 +手工艺 1 +x:1 +链式反应 1 +x:1 +清津 1 +x:1 +流传于世 1 +x:1 +褂衫 1 +x:1 +倾吐 1 +x:1 +逐步 1 +x:1 +平等党 1 +x:1 +苦菜花 1 +x:1 +杏子 1 +x:1 +稳中有升 1 +x:1 +球状 1 +x:1 +东联 1 +x:1 +河塘 1 +x:1 +全社 1 +x:1 +三伏 1 +x:1 +结肠炎 1 +x:1 +谷糠 1 +x:1 +资助面 1 +x:1 +切片 1 +x:1 +监察委 1 +x:1 +户主名 1 +x:1 +呜呼哀哉 1 +x:1 +赞美 1 +x:1 +乐安县 1 +x:1 +益田村 1 +x:1 +蒿子 1 +x:1 +冶炼 1 +x:1 +缝合 1 +x:1 +肆意 1 +x:1 +繁荣昌盛 1 +x:1 +朝秦暮楚 1 +x:1 +伟晶岩 1 +x:1 +鼻烟 1 +x:1 +立翁终于 1 +x:1 +清波 1 +x:1 +化学当量 1 +x:1 +熔炉 1 +x:1 +庹 1 +x:1 +清泰 1 +x:1 +餐盒 1 +x:1 +被采访者 1 +x:1 +详备 1 +x:1 +散 129 +x:129 +境内 1 +x:1 +拌嘴 1 +x:1 +躬逢其盛 1 +x:1 +潘 390 +x:390 +变化球 1 +x:1 +阳石隘 1 +x:1 +特立尼达 1 +x:1 +吹牛皮 1 +x:1 +鲠直 1 +x:1 +育壮 1 +x:1 +牛马 1 +x:1 +烽 3 +x:3 +鼻炎 1 +x:1 +境况 1 +x:1 +河堤 1 +x:1 +一小撮 1 +x:1 +抢修队 1 +x:1 +黄褐斑 1 +x:1 +溢流坝段 1 +x:1 +东胜 1 +x:1 +掩蔽体 1 +x:1 +烟子 1 +x:1 +刑 33 +x:33 +清江 1 +x:1 +固始县 1 +x:1 +毛峰茶 1 +x:1 +执行数 1 +x:1 +红绸 1 +x:1 +争雄 1 +x:1 +跳水赛 1 +x:1 +暗计 1 +x:1 +跑题 1 +x:1 +步数 1 +x:1 +孤本 1 +x:1 +军控 1 +x:1 +全福 1 +x:1 +暗记 1 +x:1 +暗访 1 +x:1 +裸体 1 +x:1 +失误 1 +x:1 +球王 1 +x:1 +团日 1 +x:1 +丰镐 1 +x:1 +监察处 1 +x:1 +代表处 1 +x:1 +成员国 1 +x:1 +搏动 1 +x:1 +全称 1 +x:1 +指挥室 1 +x:1 +航空局 1 +x:1 +承上启下 1 +x:1 +红纱 1 +x:1 +队医 1 +x:1 +航空展 1 +x:1 +红线 1 +x:1 +红松林 1 +x:1 +春灌水 1 +x:1 +豢养 1 +x:1 +准谱 1 +x:1 +必修 1 +x:1 +饱和量 1 +x:1 +经编业 1 +x:1 +亚洲型 1 +x:1 +暗语 1 +x:1 +冠有 1 +x:1 +迟到 1 +x:1 +抬价 1 +x:1 +团旗 1 +x:1 +⑵ 6 +x:6 +作战科 1 +x:1 +哨位 1 +x:1 +清水 1 +x:1 +松脂 1 +x:1 +杂差 1 +x:1 +溃疡病 1 +x:1 +交光互影 1 +x:1 +博弈论 1 +x:1 +马塘村 1 +x:1 +红票 1 +x:1 +塔塔尔族 1 +x:1 +缝包 1 +x:1 +愤然 1 +x:1 +碧水 1 +x:1 +避孕环 1 +x:1 +心灵史 1 +x:1 +暗花儿 1 +x:1 +谐谑 1 +x:1 +秦淮河 1 +x:1 +起居厅 1 +x:1 +乃堆拉 1 +x:1 +大宁河 1 +x:1 +儿郎 1 +x:1 +无线局 1 +x:1 +麻豆腐 1 +x:1 +雄奇 1 +x:1 +逮捕令 1 +x:1 +笺 4 +x:4 +避孕率 1 +x:1 +索骥 1 +x:1 +非成员 1 +x:1 +蒙城 1 +x:1 +元古界 1 +x:1 +叙家常 1 +x:1 +病人 1 +x:1 +捎带 1 +x:1 +工丽 1 +x:1 +耿镇 1 +x:1 +浩劫 1 +x:1 +憷头 1 +x:1 +王庆坨镇 1 +x:1 +六五年 1 +x:1 +纲领性 1 +x:1 +衣角 1 +x:1 +自励 1 +x:1 +直系亲属 1 +x:1 +法文 1 +x:1 +专业 1 +x:1 +团扇 1 +x:1 +互救 1 +x:1 +侧枝 1 +x:1 +准许 1 +x:1 +拉平 1 +x:1 +遗址性 1 +x:1 +杯口 1 +x:1 +慨叹 1 +x:1 +红金龙队 1 +x:1 +供热率 1 +x:1 +欲望化 1 +x:1 +半山区 1 +x:1 +善款 1 +x:1 +工业 1 +x:1 +樟柳碱 1 +x:1 +屏幕 1 +x:1 +专一 1 +x:1 +轻骑队 1 +x:1 +跨区 1 +x:1 +全线 1 +x:1 +协作网 1 +x:1 +地域性 1 +x:1 +玉米油 1 +x:1 +墓穴 1 +x:1 +互斥 1 +x:1 +函授班 1 +x:1 +阿克莫拉 1 +x:1 +数学家 1 +x:1 +河心 1 +x:1 +工价 1 +x:1 +工件 1 +x:1 +将计就计 1 +x:1 +戟 1 +x:1 +货色 1 +x:1 +嘴儿 1 +x:1 +掰掰 1 +x:1 +粤籍 1 +x:1 +装门面 1 +x:1 +火伤 1 +x:1 +陈米 1 +x:1 +产业群体 1 +x:1 +鸡爪爪 1 +x:1 +拉康 1 +x:1 +南门 1 +x:1 +中原区 1 +x:1 +驼铃 1 +x:1 +松虎 1 +x:1 +下北 1 +x:1 +阅卷 1 +x:1 +底细 1 +x:1 +廊坊市 1 +x:1 +收益者 1 +x:1 +富婆 1 +x:1 +底线 1 +x:1 +笛子 1 +x:1 +底纹 1 +x:1 +江天 1 +x:1 +大袋蛾 1 +x:1 +工交 1 +x:1 +享受型 1 +x:1 +工亡 1 +x:1 +季报 1 +x:1 +商用 1 +x:1 +民惟邦本 1 +x:1 +工人 1 +x:1 +新芬党外 1 +x:1 +利率差 1 +x:1 +变化率 1 +x:1 +删节 1 +x:1 +工于 1 +x:1 +工事 1 +x:1 +充其量 1 +x:1 +松蘑 1 +x:1 +族权 1 +x:1 +清欠 1 +x:1 +矿盐 1 +x:1 +连部 1 +x:1 +辩 11 +x:11 +恳 1 +x:1 +团拜 1 +x:1 +时装界 1 +x:1 +倾心 1 +x:1 +直通 1 +x:1 +服装业 1 +x:1 +浩叹 1 +x:1 +小老婆 1 +x:1 +师生比 1 +x:1 +专使 1 +x:1 +高温多雨 1 +x:1 +肉 162 +x:162 +死亡区 1 +x:1 +海联会 1 +x:1 +俭汤乡 1 +x:1 +流域库坝 1 +x:1 +宏 46 +x:46 +瓦房 1 +x:1 +江华 1 +x:1 +请电 1 +x:1 +境域 1 +x:1 +婆婆 1 +x:1 +汇款单 1 +x:1 +拉开 1 +x:1 +工位 1 +x:1 +胡言乱语 1 +x:1 +缝制 1 +x:1 +合眼 1 +x:1 +埋植术 1 +x:1 +现券 1 +x:1 +恢宏 1 +x:1 +环认委 1 +x:1 +外贸局 1 +x:1 +佛莱芒 1 +x:1 +氟里昂 1 +x:1 +工余 1 +x:1 +折扣价 1 +x:1 +烧毁 1 +x:1 +艰险 1 +x:1 +工体 1 +x:1 +婆娑 1 +x:1 +到厂价 1 +x:1 +查阅制 1 +x:1 +江北 1 +x:1 +工伤 1 +x:1 +废品站 1 +x:1 +查全率 1 +x:1 +歌宴 1 +x:1 +富宁县 1 +x:1 +垂体 1 +x:1 +分色片 1 +x:1 +高度酒 1 +x:1 +木板床 1 +x:1 +委任制 1 +x:1 +经得住 1 +x:1 +扶正祛邪 1 +x:1 +鸭嘴兽 1 +x:1 +全网 1 +x:1 +工企 1 +x:1 +红砖 1 +x:1 +失败 1 +x:1 +红砒 1 +x:1 +保健院 1 +x:1 +糊口 1 +x:1 +块根 1 +x:1 +灯台 1 +x:1 +食火鸡 1 +x:1 +阿克苏市 1 +x:1 +挽辞 1 +x:1 +证明信 1 +x:1 +重槌 1 +x:1 +烧死 1 +x:1 +沙土地 1 +x:1 +谐趣 1 +x:1 +红磷 1 +x:1 +台扇 1 +x:1 +读报 1 +x:1 +不舍昼夜 1 +x:1 +复耕 1 +x:1 +班次 1 +x:1 +口粮田 1 +x:1 +海相沉积 1 +x:1 +到场 1 +x:1 +军方 1 +x:1 +鲇鱼 1 +x:1 +现势 1 +x:1 +全羊 1 +x:1 +喜结良缘 1 +x:1 +舵 4 +x:4 +歌子 1 +x:1 +功利性 1 +x:1 +所筹 1 +x:1 +布篷 1 +x:1 +资助金 1 +x:1 +打鱼郎 1 +x:1 +结肠癌 1 +x:1 +杀头 1 +x:1 +班歌 1 +x:1 +矿石 1 +x:1 +河底 1 +x:1 +河床 1 +x:1 +连里 1 +x:1 +军旅 1 +x:1 +参照系 1 +x:1 +失足 1 +x:1 +婆媳 1 +x:1 +南钢 1 +x:1 +瓦 48 +x:48 +内斜视 1 +x:1 +批销费率 1 +x:1 +艰难 1 +x:1 +大辩论 1 +x:1 +奖杯 1 +x:1 +直航 1 +x:1 +琴书 1 +x:1 +磁共振 1 +x:1 +境地 1 +x:1 +避孕片 1 +x:1 +衰耗值 1 +x:1 +磺胺噻唑 1 +x:1 +评估关 1 +x:1 +商品肥料 1 +x:1 +夹衣 1 +x:1 +粤绣 1 +x:1 +云天 1 +x:1 +麦苗儿 1 +x:1 +混合金 1 +x:1 +歌声 1 +x:1 +陈绍 1 +x:1 +南非 1 +x:1 +褚 91 +x:91 +不屑一顾 1 +x:1 +红筹 1 +x:1 +有褒有贬 1 +x:1 +犹豫不前 1 +x:1 +进出口权 1 +x:1 +安稳感 1 +x:1 +南面 1 +x:1 +不辞辛劳 1 +x:1 +反而 1 +x:1 +谷种 1 +x:1 +高梁米 1 +x:1 +秸秆 1 +x:1 +直至 1 +x:1 +让利者 1 +x:1 +念兹在兹 1 +x:1 +国庆日 1 +x:1 +各司其职 1 +x:1 +于洪区 1 +x:1 +严紧 1 +x:1 +营养品 1 +x:1 +礼泉县 1 +x:1 +儒释道兵 1 +x:1 +山东团 1 +x:1 +绝缘 1 +x:1 +窗牖 1 +x:1 +谢却 1 +x:1 +号码机 1 +x:1 +亚欧大陆 1 +x:1 +拉屎 1 +x:1 +龙胆紫 1 +x:1 +屏山 1 +x:1 +古里古怪 1 +x:1 +攸县 1 +x:1 +驼队 1 +x:1 +墓碑 1 +x:1 +冥诞 1 +x:1 +方块 1 +x:1 +预测卡 1 +x:1 +抽象画 1 +x:1 +失踪 1 +x:1 +菌业 1 +x:1 +呼 53 +x:53 +新开河 1 +x:1 +渥京 1 +x:1 +桌面 1 +x:1 +河州 1 +x:1 +难道说 1 +x:1 +铁路局 1 +x:1 +檐子 1 +x:1 +打主意 1 +x:1 +航空处 1 +x:1 +经营化 1 +x:1 +卫戍 1 +x:1 +战术学 1 +x:1 +凡间 1 +x:1 +浙江 1 +x:1 +清楚 1 +x:1 +自欺欺人 1 +x:1 +息怒 1 +x:1 +经营区 1 +x:1 +庙东营 1 +x:1 +结算量 1 +x:1 +垦 15 +x:15 +人造行星 1 +x:1 +英主 1 +x:1 +孪井滩 1 +x:1 +桑顿区 1 +x:1 +南韩 1 +x:1 +锌钡白 1 +x:1 +出生 1 +x:1 +幽默画 1 +x:1 +乌龙球 1 +x:1 +婆姨 1 +x:1 +艺展 1 +x:1 +合璧 1 +x:1 +河工 1 +x:1 +仲裁费 1 +x:1 +跨年度 1 +x:1 +夹被 1 +x:1 +轧道机 1 +x:1 +遗产部 1 +x:1 +直角坐标 1 +x:1 +田赛 1 +x:1 +滋味儿 1 +x:1 +史料 1 +x:1 +自办 1 +x:1 +垃圾桶 1 +x:1 +选出 1 +x:1 +底粪 1 +x:1 +割舍 1 +x:1 +机器人学 1 +x:1 +土机器 1 +x:1 +跨入 1 +x:1 +赈款 1 +x:1 +松萝 1 +x:1 +反胃 1 +x:1 +卷叶虫 1 +x:1 +现出 1 +x:1 +摘葡萄 1 +x:1 +夹袄 1 +x:1 +中心庄村 1 +x:1 +定滑轮 1 +x:1 +底粉 1 +x:1 +帛书 1 +x:1 +麻痹大意 1 +x:1 +硕 5 +x:5 +失身 1 +x:1 +保靖县 1 +x:1 +躁 14 +x:14 +广纳博取 1 +x:1 +松藻 1 +x:1 +倾尽 1 +x:1 +苦丁茶 1 +x:1 +片言只语 1 +x:1 +歌儿 1 +x:1 +卫家湾 1 +x:1 +宁缺勿滥 1 +x:1 +军服 1 +x:1 +桂山镇 1 +x:1 +蟾光 1 +x:1 +军机 1 +x:1 +河山 1 +x:1 +遗产税 1 +x:1 +决 64 +x:64 +现值 1 +x:1 +合用 1 +x:1 +育婴堂 1 +x:1 +允许 1 +x:1 +嫖娼 1 +x:1 +活动证 1 +x:1 +丰功伟业 1 +x:1 +宫廷部 1 +x:1 +嘤鸣 1 +x:1 +军权 1 +x:1 +评断 1 +x:1 +丰采 1 +x:1 +胡萝卜素 1 +x:1 +奖旗 1 +x:1 +模特 1 +x:1 +丰饶 1 +x:1 +古建筑学 1 +x:1 +相电压 1 +x:1 +豪放不羁 1 +x:1 +笛声 1 +x:1 +圆鼓鼓 1 +x:1 +模版 1 +x:1 +写实化 1 +x:1 +反观 1 +x:1 +不可言传 1 +x:1 +赚钱 1 +x:1 +无故障 1 +x:1 +高发区 1 +x:1 +东营 1 +x:1 +南阳 1 +x:1 +反腐 1 +x:1 +允诺 1 +x:1 +怯生生 1 +x:1 +直肠 1 +x:1 +大别山区 1 +x:1 +丁 606 +x:606 +转波台 1 +x:1 +摩登 1 +x:1 +南雄 1 +x:1 +姿容 1 +x:1 +按捺不住 1 +x:1 +思想性 1 +x:1 +习习 1 +x:1 +姣好 1 +x:1 +人造冰 1 +x:1 +失迎 1 +x:1 +皮质 1 +x:1 +象脚鼓 1 +x:1 +遗患 1 +x:1 +蚕蛹油 1 +x:1 +恢复 1 +x:1 +切盼 1 +x:1 +北教场 1 +x:1 +免疫针 1 +x:1 +松蕈 1 +x:1 +批评稿 1 +x:1 +对讲机 1 +x:1 +英伦 1 +x:1 +病假条 1 +x:1 +夹角 1 +x:1 +名利双收 1 +x:1 +南隅 1 +x:1 +桅 4 +x:4 +便人 1 +x:1 +创作面 1 +x:1 +刘楼村 1 +x:1 +标题 1 +x:1 +酵母 1 +x:1 +师宗县 1 +x:1 +磐田队 1 +x:1 +河岸 1 +x:1 +延时赛 1 +x:1 +灾民 1 +x:1 +油气 1 +x:1 +便于 1 +x:1 +故乡人 1 +x:1 +忍痛 1 +x:1 +联合战线 1 +x:1 +灯具 1 +x:1 +便了 1 +x:1 +清样 1 +x:1 +搭桥会 1 +x:1 +勾 27 +x:27 +雕栏画栋 1 +x:1 +南襄 1 +x:1 +慈江道 1 +x:1 +军研 1 +x:1 +弥塞亚 1 +x:1 +业务者 1 +x:1 +双日 1 +x:1 +旺季 1 +x:1 +海宴 1 +x:1 +擦伤 1 +x:1 +垮 52 +x:52 +无机肥料 1 +x:1 +彭阳县 1 +x:1 +布景 1 +x:1 +底托 1 +x:1 +海宁 1 +x:1 +兜儿 1 +x:1 +龙吻 1 +x:1 +海安 1 +x:1 +人造丝 1 +x:1 +梅家坞 1 +x:1 +花朝月夕 1 +x:1 +浓浓的 1 +x:1 +北冶乡 1 +x:1 +大宝镇 1 +x:1 +红教 1 +x:1 +鲁西 1 +x:1 +冷水江市 1 +x:1 +江东 1 +x:1 +悬崖勒马 1 +x:1 +欧币 1 +x:1 +法扎巴德 1 +x:1 +兜兜 1 +x:1 +冈比亚河 1 +x:1 +分光仪 1 +x:1 +无名帖 1 +x:1 +丧偶者 1 +x:1 +潸然泪下 1 +x:1 +海寇 1 +x:1 +全托 1 +x:1 +晤 4 +x:4 +南箕北斗 1 +x:1 +航行预试 1 +x:1 +嘭嘭 1 +x:1 +地质局 1 +x:1 +专列 1 +x:1 +评估会 1 +x:1 +专刊 1 +x:1 +争购 1 +x:1 +全才 1 +x:1 +毛织 1 +x:1 +全所 1 +x:1 +玉带 1 +x:1 +红日 1 +x:1 +便函 1 +x:1 +团级 1 +x:1 +工勤 1 +x:1 +露一手 1 +x:1 +硬手 1 +x:1 +诡称 1 +x:1 +灯丝 1 +x:1 +火化 1 +x:1 +柔嫩 1 +x:1 +负者 1 +x:1 +季朗村 1 +x:1 +鲇腹 1 +x:1 +赤子情 1 +x:1 +红旗 1 +x:1 +窗沿 1 +x:1 +撸 2 +x:2 +中晚 1 +x:1 +脚丫子 1 +x:1 +笔耕者 1 +x:1 +采集者 1 +x:1 +甚而 1 +x:1 +曹娥江 1 +x:1 +甚者 1 +x:1 +工务 1 +x:1 +现地 1 +x:1 +渔翁得利 1 +x:1 +倒计时牌 1 +x:1 +清真 1 +x:1 +台柱 1 +x:1 +冤沉海底 1 +x:1 +塘市镇 1 +x:1 +跳水队 1 +x:1 +称意 1 +x:1 +巴茅茨 1 +x:1 +储洪 1 +x:1 +不识时变 1 +x:1 +柔媚 1 +x:1 +涝害 1 +x:1 +伊宁市 1 +x:1 +团练 1 +x:1 +照实 1 +x:1 +杨树街 1 +x:1 +博物馆 1 +x:1 +工办 1 +x:1 +近体诗 1 +x:1 +工力 1 +x:1 +海子 1 +x:1 +考察点 1 +x:1 +问心有愧 1 +x:1 +院友 1 +x:1 +现世 1 +x:1 +英军 1 +x:1 +南行 1 +x:1 +特大 1 +x:1 +南街 1 +x:1 +赝品 1 +x:1 +清盘 1 +x:1 +服装史 1 +x:1 +火力 1 +x:1 +窗洞 1 +x:1 +石鼓文 1 +x:1 +粘滑 1 +x:1 +赞方 1 +x:1 +残壁 1 +x:1 +全程 1 +x:1 +布条 1 +x:1 +专卖 1 +x:1 +琮 8 +x:8 +委任书 1 +x:1 +边卡 1 +x:1 +特多 1 +x:1 +连贯 1 +x:1 +合欢 1 +x:1 +东马 1 +x:1 +火势 1 +x:1 +栎林 1 +x:1 +专区 1 +x:1 +半山上 1 +x:1 +驳回 1 +x:1 +大湖型 1 +x:1 +工匠 1 +x:1 +仪仗兵 1 +x:1 +结尾处 1 +x:1 +泰宁 1 +x:1 +泌阳 1 +x:1 +工区 1 +x:1 +泰安 1 +x:1 +赤色 1 +x:1 +联运站 1 +x:1 +自动伞 1 +x:1 +帐篷顶 1 +x:1 +阴森森 1 +x:1 +外交特权 1 +x:1 +服装厂 1 +x:1 +史稿 1 +x:1 +问卷调查 1 +x:1 +工青妇 1 +x:1 +绵 3 +x:3 +垂危 1 +x:1 +盛情难却 1 +x:1 +逛荡 1 +x:1 +初露锋芒 1 +x:1 +震天 1 +x:1 +评估价 1 +x:1 +乳娘 1 +x:1 +陕西梆子 1 +x:1 +抢救性 1 +x:1 +鱼虾蟹贝 1 +x:1 +专号 1 +x:1 +筒裤 1 +x:1 +灯伞 1 +x:1 +于心何忍 1 +x:1 +老两口 1 +x:1 +新娘节 1 +x:1 +不识时务 1 +x:1 +失重 1 +x:1 +擦亮 1 +x:1 +日见明朗 1 +x:1 +耶鲁 1 +x:1 +杯中 1 +x:1 +赤芍 1 +x:1 +当地国 1 +x:1 +工友 1 +x:1 +政治司 1 +x:1 +河坊村 1 +x:1 +筒裙 1 +x:1 +跨上 1 +x:1 +柏林墙 1 +x:1 +烧着 1 +x:1 +徇情枉法 1 +x:1 +适逢其时 1 +x:1 +粗初加工 1 +x:1 +趋炎附势 1 +x:1 +自由王国 1 +x:1 +卡巴胂 1 +x:1 +申购 1 +x:1 +瞻榆乡 1 +x:1 +所有 1 +x:1 +才 3648 +x:3648 +费边主义 1 +x:1 +仔仔细细 1 +x:1 +心肌梗塞 1 +x:1 +亚硫酸 1 +x:1 +现今 1 +x:1 +乞求 1 +x:1 +梁峁沟壑 1 +x:1 +有意无意 1 +x:1 +姗姗来迟 1 +x:1 +码多分址 1 +x:1 +现价 1 +x:1 +笼子 1 +x:1 +水漫金山 1 +x:1 +清瘦 1 +x:1 +工厂 1 +x:1 +现代 1 +x:1 +偶尔 1 +x:1 +莱比锡 1 +x:1 +抓阄 1 +x:1 +窟口 1 +x:1 +特委 1 +x:1 +全总 1 +x:1 +蹲苗 1 +x:1 +不知死活 1 +x:1 +地质带 1 +x:1 +锭子 1 +x:1 +玉屏 1 +x:1 +农副工 1 +x:1 +木人石心 1 +x:1 +脉诀 1 +x:1 +红松 1 +x:1 +价差费 1 +x:1 +推诿 1 +x:1 +守护林 1 +x:1 +渺小 1 +x:1 +大别山乡 1 +x:1 +合格 1 +x:1 +浪淘沙 1 +x:1 +贪 41 +x:41 +红杉 1 +x:1 +回吐 1 +x:1 +惟独 1 +x:1 +赤脚 1 +x:1 +蛇皮 1 +x:1 +充足 1 +x:1 +尊 70 +x:70 +空前未有 1 +x:1 +率由旧章 1 +x:1 +大吵大闹 1 +x:1 +秋雨 1 +x:1 +红木 1 +x:1 +毛纱 1 +x:1 +虎符 1 +x:1 +懂事 1 +x:1 +残害 1 +x:1 +抑郁症 1 +x:1 +购买欲 1 +x:1 +全息 1 +x:1 +英勇 1 +x:1 +田野 1 +x:1 +田里 1 +x:1 +回合 1 +x:1 +脑满肠肥 1 +x:1 +澡盆 1 +x:1 +成员体 1 +x:1 +团籍 1 +x:1 +寒蝉 1 +x:1 +一清二白 1 +x:1 +割麦 1 +x:1 +文献集 1 +x:1 +持家 1 +x:1 +粘液 1 +x:1 +管弦乐团 1 +x:1 +敢做敢为 1 +x:1 +海大 1 +x:1 +衣被 1 +x:1 +圆滑 1 +x:1 +粮食作物 1 +x:1 +记分牌 1 +x:1 +过头粮 1 +x:1 +蒙古 1 +x:1 +秋阳 1 +x:1 +红柱 1 +x:1 +红柳 1 +x:1 +改进型 1 +x:1 +判别式 1 +x:1 +一锅端 1 +x:1 +赤膊 1 +x:1 +额 64 +x:64 +团粉 1 +x:1 +乳头 1 +x:1 +海外 1 +x:1 +散布式 1 +x:1 +块石 1 +x:1 +加勒比海 1 +x:1 +团粒 1 +x:1 +底情 1 +x:1 +大支援 1 +x:1 +残存 1 +x:1 +火儿 1 +x:1 +东首 1 +x:1 +导向性 1 +x:1 +群言堂 1 +x:1 +红枣 1 +x:1 +袁家岭 1 +x:1 +火光 1 +x:1 +罐笼 1 +x:1 +争辉 1 +x:1 +粪箕子 1 +x:1 +角 121 +x:121 +血脂 1 +x:1 +弹雨 1 +x:1 +真实化 1 +x:1 +肢残人 1 +x:1 +培训局 1 +x:1 +古庄店乡 1 +x:1 +报收 1 +x:1 +争辩 1 +x:1 +管弦乐器 1 +x:1 +红林 1 +x:1 +火具 1 +x:1 +电话声 1 +x:1 +垂死挣扎 1 +x:1 +红果 1 +x:1 +憨态 1 +x:1 +抢修车 1 +x:1 +里尔街 1 +x:1 +妇 7 +x:7 +专兼 1 +x:1 +梅江区 1 +x:1 +乘方 1 +x:1 +痛处 1 +x:1 +自以为是 1 +x:1 +眉欢眼笑 1 +x:1 +债款 1 +x:1 +罅隙 1 +x:1 +远离 1 +x:1 +工兵 1 +x:1 +丰台区 1 +x:1 +工具 1 +x:1 +虎穴 1 +x:1 +造孽 1 +x:1 +丰足 1 +x:1 +今晚报 1 +x:1 +堡安村 1 +x:1 +包购包销 1 +x:1 +存活率 1 +x:1 +红晕 1 +x:1 +质优价廉 1 +x:1 +工党 1 +x:1 +变线 1 +x:1 +虹彩 1 +x:1 +药价 1 +x:1 +维尔纽斯 1 +x:1 +发昏 1 +x:1 +婆 1 +x:1 +后江村 1 +x:1 +憨憨 1 +x:1 +科研院 1 +x:1 +便利 1 +x:1 +波特率 1 +x:1 +长城镇 1 +x:1 +大公储 1 +x:1 +松香 1 +x:1 +喷洒剂 1 +x:1 +连载 1 +x:1 +壶嘴 1 +x:1 +骨库 1 +x:1 +连轴 1 +x:1 +众议长 1 +x:1 +很快 1 +x:1 +鼻梁 1 +x:1 +随物赋形 1 +x:1 +殊死战 1 +x:1 +布放 1 +x:1 +儿辈 1 +x:1 +投鞭断流 1 +x:1 +东施效颦 1 +x:1 +提名 1 +x:1 +经营业 1 +x:1 +笼头 1 +x:1 +海堤 1 +x:1 +京昆剧院 1 +x:1 +专函 1 +x:1 +从无到有 1 +x:1 +如此而已 1 +x:1 +联络部 1 +x:1 +绝招 1 +x:1 +库亚巴市 1 +x:1 +岩松 1 +x:1 +蠕虫 1 +x:1 +一九九七 1 +x:1 +东风 1 +x:1 +火候 1 +x:1 +耐人思索 1 +x:1 +永丰 1 +x:1 +瓜果皮核 1 +x:1 +台籍 1 +x:1 +笼外 1 +x:1 +印藏者 1 +x:1 +牵牛 1 +x:1 +直言进谏 1 +x:1 +穆棱市 1 +x:1 +鲁山县 1 +x:1 +逭 1 +x:1 +联合公报 1 +x:1 +艾单驼 1 +x:1 +特定 1 +x:1 +照壁 1 +x:1 +名丑 1 +x:1 +玉工 1 +x:1 +安多县 1 +x:1 +连连 1 +x:1 +替罪羊 1 +x:1 +清理 1 +x:1 +盗码者 1 +x:1 +盲从者 1 +x:1 +适销品 1 +x:1 +布料 1 +x:1 +汕 4 +x:4 +绝技 1 +x:1 +裸地 1 +x:1 +英华 1 +x:1 +石轿村 1 +x:1 +公安所 1 +x:1 +复合肥料 1 +x:1 +果珍杯 1 +x:1 +负荷 1 +x:1 +照墙 1 +x:1 +风霜雨雪 1 +x:1 +工农 1 +x:1 +方山县 1 +x:1 +丰赡 1 +x:1 +总煤师 1 +x:1 +布施 1 +x:1 +粮柜 1 +x:1 +海塘 1 +x:1 +一手一足 1 +x:1 +硬环境 1 +x:1 +族群 1 +x:1 +照彻 1 +x:1 +犟劲 1 +x:1 +生生息息 1 +x:1 +布托 1 +x:1 +拿来主义 1 +x:1 +尊老敬老 1 +x:1 +解说词 1 +x:1 +眼目 1 +x:1 +矿渣 1 +x:1 +小市民 1 +x:1 +照录 1 +x:1 +酌情 1 +x:1 +提单 1 +x:1 +疆场 1 +x:1 +赞皇县 1 +x:1 +喜事 1 +x:1 +污染 1 +x:1 +八点钟 1 +x:1 +提升 1 +x:1 +兜售 1 +x:1 +窗格 1 +x:1 +窗框 1 +x:1 +织 45 +x:45 +对接口 1 +x:1 +当地化 1 +x:1 +造就 1 +x:1 +全景 1 +x:1 +反驳 1 +x:1 +盅子 1 +x:1 +军籍 1 +x:1 +摩润 1 +x:1 +南货 1 +x:1 +绝收 1 +x:1 +请求 1 +x:1 +一口咬定 1 +x:1 +护岸林 1 +x:1 +到任 1 +x:1 +惹事生非 1 +x:1 +跟随者 1 +x:1 +阴间多云 1 +x:1 +婴 7 +x:7 +陈庄乡 1 +x:1 +提包 1 +x:1 +法兰绒 1 +x:1 +把脉 1 +x:1 +布拉 1 +x:1 +包 384 +x:384 +海弯 1 +x:1 +喜人 1 +x:1 +九龙口 1 +x:1 +南京路 1 +x:1 +憎 3 +x:3 +禄位 1 +x:1 +把握性 1 +x:1 +连袂 1 +x:1 +英名 1 +x:1 +布拖 1 +x:1 +提取 1 +x:1 +一九九九 1 +x:1 +做贡献期 1 +x:1 +装模作样 1 +x:1 +绝无 1 +x:1 +急转直下 1 +x:1 +火场 1 +x:1 +军粮 1 +x:1 +务期 1 +x:1 +参差不齐 1 +x:1 +团章 1 +x:1 +窗棂 1 +x:1 +蒙住 1 +x:1 +渝水 1 +x:1 +艰辛 1 +x:1 +广安门 1 +x:1 +拼画 1 +x:1 +骨头 1 +x:1 +疆域 1 +x:1 +豁达大度 1 +x:1 +泰币 1 +x:1 +终于 1 +x:1 +源流 1 +x:1 +松鸡 1 +x:1 +终了 1 +x:1 +沙土乡 1 +x:1 +买家 1 +x:1 +群山万壑 1 +x:1 +溶菌素 1 +x:1 +国奥队 1 +x:1 +买客 1 +x:1 +柏林州 1 +x:1 +杀气腾腾 1 +x:1 +底板 1 +x:1 +皮鞋 1 +x:1 +高中低档 1 +x:1 +暗锁 1 +x:1 +课长 1 +x:1 +颉 1 +x:1 +稿件 1 +x:1 +磨合期 1 +x:1 +交叉有致 1 +x:1 +合演 1 +x:1 +切汇 1 +x:1 +模样 1 +x:1 +大袋鼠 1 +x:1 +穿小鞋 1 +x:1 +政经 1 +x:1 +浅亮 1 +x:1 +皮鞭 1 +x:1 +无病呻吟 1 +x:1 +服装城 1 +x:1 +海床 1 +x:1 +岱 4 +x:4 +鳄鱼 1 +x:1 +密匝匝 1 +x:1 +九台市 1 +x:1 +大公国 1 +x:1 +享年 1 +x:1 +陈旧 1 +x:1 +栾 11 +x:11 +循环小数 1 +x:1 +三岔路 1 +x:1 +燃 28 +x:28 +宿迁市 1 +x:1 +连襟 1 +x:1 +出仁率 1 +x:1 +柔弱 1 +x:1 +责任 1 +x:1 +灯市西口 1 +x:1 +工场 1 +x:1 +公检法 1 +x:1 +工地 1 +x:1 +无话不说 1 +x:1 +获奖者 1 +x:1 +班班 1 +x:1 +浅令 1 +x:1 +己任 1 +x:1 +全村 1 +x:1 +秋野 1 +x:1 +春情 1 +x:1 +滨城 1 +x:1 +鲁谷 1 +x:1 +全权 1 +x:1 +很多 1 +x:1 +海带 1 +x:1 +伢仔 1 +x:1 +到会 1 +x:1 +干什么 1 +x:1 +课间 1 +x:1 +岭南派 1 +x:1 +之所以 1 +x:1 +敞开 1 +x:1 +烧杀抢掠 1 +x:1 +明查暗访 1 +x:1 +拦河坝 1 +x:1 +逃税 1 +x:1 +田阳 1 +x:1 +躬行实践 1 +x:1 +赈灾 1 +x:1 +直驶 1 +x:1 +北较场 1 +x:1 +循环圈赛 1 +x:1 +预科系 1 +x:1 +包乘制 1 +x:1 +朗然 1 +x:1 +依恃 1 +x:1 +脉象 1 +x:1 +除夕夜 1 +x:1 +失闪 1 +x:1 +史绩 1 +x:1 +陕西 1 +x:1 +东麓 1 +x:1 +掠 11 +x:11 +特工 1 +x:1 +丢三落四 1 +x:1 +照度 1 +x:1 +填补 1 +x:1 +不得了 1 +x:1 +恭亲王 1 +x:1 +松鼠 1 +x:1 +奖罚 1 +x:1 +科研部 1 +x:1 +到位 1 +x:1 +朗照 1 +x:1 +皮革 1 +x:1 +耻笑 1 +x:1 +照应 1 +x:1 +陈放 1 +x:1 +轧 21 +x:21 +蒙乡 1 +x:1 +皮面 1 +x:1 +火器 1 +x:1 +布控 1 +x:1 +暗门 1 +x:1 +清爽 1 +x:1 +研究生班 1 +x:1 +风景区 1 +x:1 +口腔科 1 +x:1 +军事家 1 +x:1 +皮靴 1 +x:1 +缩略语 1 +x:1 +组氨酸 1 +x:1 +参照本 1 +x:1 +堂哥哥 1 +x:1 +长年累月 1 +x:1 +剑侠 1 +x:1 +筒车 1 +x:1 +烧烤 1 +x:1 +阳信县 1 +x:1 +绝杀 1 +x:1 +受惠人 1 +x:1 +顺城区 1 +x:1 +刘 3775 +x:3775 +粤曲 1 +x:1 +准重 1 +x:1 +免疫费 1 +x:1 +垃圾点 1 +x:1 +专员 1 +x:1 +失陷 1 +x:1 +法条 1 +x:1 +篡位 1 +x:1 +残忍 1 +x:1 +所想 1 +x:1 +台怀镇 1 +x:1 +台秤 1 +x:1 +常识课 1 +x:1 +夹道 1 +x:1 +失陪 1 +x:1 +闻名遐迩 1 +x:1 +电话局 1 +x:1 +丰裕 1 +x:1 +绝望 1 +x:1 +魏公村 1 +x:1 +衔 6 +x:6 +烧炭 1 +x:1 +反顾 1 +x:1 +所悟 1 +x:1 +桌边 1 +x:1 +鼻涕 1 +x:1 +专向 1 +x:1 +英国 1 +x:1 +五年制 1 +x:1 +压库 1 +x:1 +马马虎虎 1 +x:1 +非织造 1 +x:1 +专名 1 +x:1 +效率卡 1 +x:1 +抽象派 1 +x:1 +芜湖 1 +x:1 +账页纸 1 +x:1 +混声 1 +x:1 +鲁迅 1 +x:1 +南迁 1 +x:1 +提出 1 +x:1 +无坚不摧 1 +x:1 +德高望重 1 +x:1 +多弹头 1 +x:1 +埃及队 1 +x:1 +氢能 1 +x:1 +骨学 1 +x:1 +罐罐 1 +x:1 +卡诺 1 +x:1 +洋河村 1 +x:1 +氧 32 +x:32 +侦 10 +x:10 +骨子 1 +x:1 +非领导 1 +x:1 +玉壶 1 +x:1 +诞纪 1 +x:1 +军级 1 +x:1 +铺张矫饰 1 +x:1 +西庄村 1 +x:1 +朗爽 1 +x:1 +服装员 1 +x:1 +柱网 1 +x:1 +皴法 1 +x:1 +鸟语林 1 +x:1 +工字形 1 +x:1 +政出多口 1 +x:1 +无电户 1 +x:1 +军统 1 +x:1 +方始 1 +x:1 +合法 1 +x:1 +冤孽账 1 +x:1 +平淡无奇 1 +x:1 +黏米 1 +x:1 +所思 1 +x:1 +读秒 1 +x:1 +水日 1 +x:1 +红掌 1 +x:1 +癫 1 +x:1 +棒 28 +x:28 +赞扬 1 +x:1 +法权 1 +x:1 +矿泉 1 +x:1 +冤仇 1 +x:1 +为所欲为 1 +x:1 +核威胁 1 +x:1 +非互惠 1 +x:1 +栽培法 1 +x:1 +南边 1 +x:1 +笼屉 1 +x:1 +造形 1 +x:1 +德胜门 1 +x:1 +负氧离子 1 +x:1 +四平乡 1 +x:1 +主攻手 1 +x:1 +海岭 1 +x:1 +泰州 1 +x:1 +底数 1 +x:1 +瓦砾 1 +x:1 +大铁罐 1 +x:1 +字符串 1 +x:1 +造影 1 +x:1 +实际上 1 +x:1 +史籍 1 +x:1 +一秘 1 +x:1 +海岸 1 +x:1 +候温 1 +x:1 +东华门 1 +x:1 +檩 2 +x:2 +玉女 1 +x:1 +工商 1 +x:1 +回忆人 1 +x:1 +拼盘 1 +x:1 +柏林市 1 +x:1 +高高壮壮 1 +x:1 +待业者 1 +x:1 +统销 1 +x:1 +海岛 1 +x:1 +海峡 1 +x:1 +范式化 1 +x:1 +全数 1 +x:1 +地质学 1 +x:1 +处境 1 +x:1 +改进剂 1 +x:1 +提倡 1 +x:1 +充裕 1 +x:1 +哨口 1 +x:1 +合流 1 +x:1 +文痞 1 +x:1 +放牛娃 1 +x:1 +胥 15 +x:15 +住房部 1 +x:1 +稳中转好 1 +x:1 +红通通 1 +x:1 +四稳四进 1 +x:1 +杂志 1 +x:1 +清点 1 +x:1 +舍生取义 1 +x:1 +矿浆 1 +x:1 +直颤 1 +x:1 +残废 1 +x:1 +原料 1 +x:1 +槲鸫 1 +x:1 +社会存在 1 +x:1 +轻闲 1 +x:1 +禄丰县 1 +x:1 +驳倒 1 +x:1 +全新 1 +x:1 +陈村 1 +x:1 +日月如梭 1 +x:1 +施政权 1 +x:1 +残年 1 +x:1 +序言 1 +x:1 +明珠弹雀 1 +x:1 +男女平等 1 +x:1 +储灰场 1 +x:1 +失音 1 +x:1 +淡出 1 +x:1 +特征 1 +x:1 +孔雀舞 1 +x:1 +跨国 1 +x:1 +反馈 1 +x:1 +持平 1 +x:1 +自交系 1 +x:1 +清真东寺 1 +x:1 +全文 1 +x:1 +遗传物质 1 +x:1 +泉勇街 1 +x:1 +谐音 1 +x:1 +特快 1 +x:1 +走亲访友 1 +x:1 +殡车 1 +x:1 +纪传体 1 +x:1 +充血 1 +x:1 +进进出出 1 +x:1 +族类 1 +x:1 +连词 1 +x:1 +增储 1 +x:1 +时隐时显 1 +x:1 +哨卡 1 +x:1 +所感 1 +x:1 +全日 1 +x:1 +残币 1 +x:1 +乳山 1 +x:1 +蝶阀厂 1 +x:1 +块状 1 +x:1 +敷 6 +x:6 +太平洋区 1 +x:1 +浙电 1 +x:1 +上诉费 1 +x:1 +助学金 1 +x:1 +删除 1 +x:1 +合成 1 +x:1 +必将 1 +x:1 +臭氧洞 1 +x:1 +表现型 1 +x:1 +闽粤 1 +x:1 +红海 1 +x:1 +减摩合金 1 +x:1 +中期 1 +x:1 +多米尼加 1 +x:1 +巩留 1 +x:1 +班级 1 +x:1 +保健茶 1 +x:1 +烧结 1 +x:1 +鱼鹰 1 +x:1 +杂念 1 +x:1 +琴家 1 +x:1 +节奏感 1 +x:1 +思南路 1 +x:1 +湿渍 1 +x:1 +跑马 1 +x:1 +玉器 1 +x:1 +污毒 1 +x:1 +阳春白雪 1 +x:1 +锄草机 1 +x:1 +海原 1 +x:1 +数学会 1 +x:1 +连营 1 +x:1 +斜坡形 1 +x:1 +班组 1 +x:1 +裸岩 1 +x:1 +海口 1 +x:1 +黄帝陵 1 +x:1 +巴卡尼 1 +x:1 +幼儿部 1 +x:1 +坊 3 +x:3 +害怕 1 +x:1 +烧纸 1 +x:1 +翻来覆去 1 +x:1 +成果展 1 +x:1 +有趣儿 1 +x:1 +草桥 1 +x:1 +一孩户 1 +x:1 +五星红旗 1 +x:1 +歌人 1 +x:1 +电瓶车 1 +x:1 +海参 1 +x:1 +马头琴 1 +x:1 +藩 1 +x:1 +连长 1 +x:1 +求大同 1 +x:1 +拨动 1 +x:1 +航空信 1 +x:1 +粮猪型 1 +x:1 +耽搁 1 +x:1 +军火 1 +x:1 +如坐针毡 1 +x:1 +蹒蹒跚跚 1 +x:1 +南极洲 1 +x:1 +如坐春风 1 +x:1 +湿湿 1 +x:1 +等速 1 +x:1 +八纵八横 1 +x:1 +横七竖八 1 +x:1 +乳化 1 +x:1 +球情 1 +x:1 +沟沟壑壑 1 +x:1 +云彩 1 +x:1 +陈案 1 +x:1 +互贸区 1 +x:1 +享受 1 +x:1 +电极 1 +x:1 +残兵 1 +x:1 +想得到 1 +x:1 +海区 1 +x:1 +创作者 1 +x:1 +矩形 1 +x:1 +照发 1 +x:1 +窗式机 1 +x:1 +布满 1 +x:1 +合抱 1 +x:1 +慌慌张张 1 +x:1 +造像 1 +x:1 +海北 1 +x:1 +泰剧 1 +x:1 +陈辞旧语 1 +x:1 +唯命是从 1 +x:1 +沸 1 +x:1 +驼背 1 +x:1 +直面 1 +x:1 +帆樯 1 +x:1 +红润 1 +x:1 +烈暑 1 +x:1 +奖牌 1 +x:1 +蚌埠市 1 +x:1 +不共戴天 1 +x:1 +脉脉 1 +x:1 +土党参 1 +x:1 +合拍 1 +x:1 +序跋 1 +x:1 +遛 2 +x:2 +名扬四海 1 +x:1 +鹿回头 1 +x:1 +课题 1 +x:1 +是非题 1 +x:1 +钉螺 1 +x:1 +寻枝摘叶 1 +x:1 +海协 1 +x:1 +海华 1 +x:1 +功败垂成 1 +x:1 +直露 1 +x:1 +遮羞布 1 +x:1 +海南 1 +x:1 +瓦垄子 1 +x:1 +史 299 +x:299 +赤诚 1 +x:1 +时已隔世 1 +x:1 +答理 1 +x:1 +清缴 1 +x:1 +半死 1 +x:1 +溘然而逝 1 +x:1 +提干 1 +x:1 +弱智 1 +x:1 +跑门串门 1 +x:1 +推重比 1 +x:1 +工学 1 +x:1 +台盟 1 +x:1 +惠风和畅 1 +x:1 +消耗品 1 +x:1 +请愿 1 +x:1 +反霸 1 +x:1 +片麻岩 1 +x:1 +一锅煮 1 +x:1 +别具特色 1 +x:1 +荷包蛋 1 +x:1 +庆贺 1 +x:1 +大声疾呼 1 +x:1 +垃圾羊 1 +x:1 +双新村 1 +x:1 +无棣县 1 +x:1 +顺丁橡胶 1 +x:1 +政治学 1 +x:1 +烛泪 1 +x:1 +红汞 1 +x:1 +海力 1 +x:1 +纯净度 1 +x:1 +擦脂抹粉 1 +x:1 +全歼 1 +x:1 +反面 1 +x:1 +隆起带 1 +x:1 +接见厅 1 +x:1 +电话单 1 +x:1 +昔阳县 1 +x:1 +球感 1 +x:1 +等量 1 +x:1 +挂牌率 1 +x:1 +中界点 1 +x:1 +正面 1 +x:1 +处士 1 +x:1 +光脚板子 1 +x:1 +楠 46 +x:46 +清纯 1 +x:1 +直隶 1 +x:1 +替死鬼 1 +x:1 +英姿 1 +x:1 +答疑 1 +x:1 +练集镇 1 +x:1 +领头羊 1 +x:1 +两年制 1 +x:1 +四面开花 1 +x:1 +杀虫剂 1 +x:1 +天府之国 1 +x:1 +铆钉 1 +x:1 +答谢辞 1 +x:1 +承贷 1 +x:1 +便壶 1 +x:1 +天昏地暗 1 +x:1 +全段 1 +x:1 +社会党人 1 +x:1 +主视图 1 +x:1 +承购 1 +x:1 +锡拉特市 1 +x:1 +便士 1 +x:1 +航空业 1 +x:1 +联立方程 1 +x:1 +卫生 1 +x:1 +暗香 1 +x:1 +北爱党 1 +x:1 +承负 1 +x:1 +演绎 1 +x:1 +主要矛盾 1 +x:1 +分歧点 1 +x:1 +印油 1 +x:1 +夫 23 +x:23 +弈 4 +x:4 +预产期 1 +x:1 +特写 1 +x:1 +驾校业 1 +x:1 +艰苦 1 +x:1 +语气词 1 +x:1 +抓斗 1 +x:1 +宜宾市 1 +x:1 +水球赛 1 +x:1 +无产阶级 1 +x:1 +一辈子 1 +x:1 +京郊 1 +x:1 +专家 1 +x:1 +烧缸 1 +x:1 +建章立制 1 +x:1 +多音字 1 +x:1 +红河 1 +x:1 +山亭乡 1 +x:1 +乳剂 1 +x:1 +了然于胸 1 +x:1 +俊儿 1 +x:1 +排名 1 +x:1 +政治家 1 +x:1 +偶合 1 +x:1 +照办 1 +x:1 +蜀道之难 1 +x:1 +印象派 1 +x:1 +专守 1 +x:1 +一面 1 +x:1 +瓦盆 1 +x:1 +祸心 1 +x:1 +设计部 1 +x:1 +京都 1 +x:1 +宫殿 1 +x:1 +板 53 +x:53 +球手 1 +x:1 +特别 1 +x:1 +驼色 1 +x:1 +名称栏 1 +x:1 +红潮 1 +x:1 +模本 1 +x:1 +纯血 1 +x:1 +公安段 1 +x:1 +海况 1 +x:1 +盗印案 1 +x:1 +海冰 1 +x:1 +水果业 1 +x:1 +全校 1 +x:1 +底档 1 +x:1 +特制 1 +x:1 +海内 1 +x:1 +特刊 1 +x:1 +射线 1 +x:1 +国务部 1 +x:1 +苇芽 1 +x:1 +上秦镇 1 +x:1 +雇人 1 +x:1 +N 1 +x:1 +深河村 1 +x:1 +回水区 1 +x:1 +冠盖 1 +x:1 +切换 1 +x:1 +军警民 1 +x:1 +桌菜 1 +x:1 +海军 1 +x:1 +心脑血管 1 +x:1 +请战 1 +x:1 +酒徒 1 +x:1 +小本经营 1 +x:1 +兜子 1 +x:1 +倩影 1 +x:1 +帘布 1 +x:1 +契合点 1 +x:1 +杨枝鱼 1 +x:1 +内政部长 1 +x:1 +青艺 1 +x:1 +一己官欲 1 +x:1 +尉犁 1 +x:1 +明尼苏达 1 +x:1 +哟 40 +x:40 +办结率 1 +x:1 +诡 1 +x:1 +玫瑰花 1 +x:1 +拉客 1 +x:1 +计时赛 1 +x:1 +塬 1 +x:1 +铜子儿 1 +x:1 +赘言 1 +x:1 +余值法 1 +x:1 +镜面 1 +x:1 +大西洋城 1 +x:1 +啤酒 1 +x:1 +滚动式 1 +x:1 +灾祸 1 +x:1 +因人而异 1 +x:1 +瓜剖豆分 1 +x:1 +邳州 1 +x:1 +南菁 1 +x:1 +特务 1 +x:1 +谏 3 +x:3 +山明水秀 1 +x:1 +是非曲直 1 +x:1 +耸耸 1 +x:1 +先声夺人 1 +x:1 +学有专攻 1 +x:1 +考察站 1 +x:1 +直镇 1 +x:1 +鲁菜 1 +x:1 +平安庭 1 +x:1 +玫瑰色 1 +x:1 +乳儿 1 +x:1 +必要劳动 1 +x:1 +火夫 1 +x:1 +欺软怕硬 1 +x:1 +雇主 1 +x:1 +蓉花山镇 1 +x:1 +锜 1 +x:1 +割除 1 +x:1 +照准 1 +x:1 +高岭土 1 +x:1 +暮气沉沉 1 +x:1 +特功 1 +x:1 +火头 1 +x:1 +细长细长 1 +x:1 +军犬 1 +x:1 +隔三差五 1 +x:1 +工程部 1 +x:1 +残匪 1 +x:1 +球技 1 +x:1 +特勤 1 +x:1 +走路 1 +x:1 +暖武里府 1 +x:1 +海关 1 +x:1 +地质图 1 +x:1 +金文 1 +x:1 +海兰 1 +x:1 +海兽 1 +x:1 +造势 1 +x:1 +直销 1 +x:1 +合情 1 +x:1 +古筝曲 1 +x:1 +便宜 1 +x:1 +过云雨 1 +x:1 +内蒙 1 +x:1 +悲喜剧 1 +x:1 +鲁莽 1 +x:1 +震动 1 +x:1 +布测 1 +x:1 +底楼 1 +x:1 +东道 1 +x:1 +阴极射线 1 +x:1 +禹门口 1 +x:1 +芑 1 +x:1 +特区 1 +x:1 +合意 1 +x:1 +上个月 1 +x:1 +火墙 1 +x:1 +林科院 1 +x:1 +直链 1 +x:1 +立锥之地 1 +x:1 +驳岸 1 +x:1 +反锁 1 +x:1 +家用机 1 +x:1 +鉴证费 1 +x:1 +博学多才 1 +x:1 +垂头 1 +x:1 +白大褂 1 +x:1 +调剂金 1 +x:1 +新宅村 1 +x:1 +怒火 1 +x:1 +垫上运动 1 +x:1 +亲生 1 +x:1 +全楼 1 +x:1 +毋 3 +x:3 +雄心 1 +x:1 +摔炮 1 +x:1 +荐 10 +x:10 +非林地 1 +x:1 +趁人之危 1 +x:1 +卫矛 1 +x:1 +发糕 1 +x:1 +广丰县 1 +x:1 +龙王塘村 1 +x:1 +地安门 1 +x:1 +大观镇 1 +x:1 +车型 1 +x:1 +抽象性 1 +x:1 +承还 1 +x:1 +英寸 1 +x:1 +匪首 1 +x:1 +贫困户 1 +x:1 +南航 1 +x:1 +琴声 1 +x:1 +承运 1 +x:1 +内行人 1 +x:1 +高钛型 1 +x:1 +如东县 1 +x:1 +造化 1 +x:1 +二不怕死 1 +x:1 +滚动轴承 1 +x:1 +白山黑水 1 +x:1 +高产田 1 +x:1 +伦理学界 1 +x:1 +蒙古袍 1 +x:1 +悠哉游哉 1 +x:1 +火堆 1 +x:1 +造句 1 +x:1 +残剩 1 +x:1 +姆西拉 1 +x:1 +骨器 1 +x:1 +咔叽 1 +x:1 +虎狼 1 +x:1 +理科生 1 +x:1 +南苑 1 +x:1 +必得 1 +x:1 +东郊 1 +x:1 +攀钢 1 +x:1 +摩托 1 +x:1 +泰兴 1 +x:1 +兹罗提 1 +x:1 +白蜡虫 1 +x:1 +国民收入 1 +x:1 +震叹 1 +x:1 +造反 1 +x:1 +索赔 1 +x:1 +服装奖 1 +x:1 +照像 1 +x:1 +工委 1 +x:1 +诅咒 1 +x:1 +东部 1 +x:1 +谒陵 1 +x:1 +承载 1 +x:1 +鲜艳艳 1 +x:1 +建陶厂 1 +x:1 +反问 1 +x:1 +茫茫大千 1 +x:1 +家属区 1 +x:1 +台球 1 +x:1 +赝币 1 +x:1 +赤裸 1 +x:1 +做媒 1 +x:1 +火塘 1 +x:1 +苇草 1 +x:1 +工程量 1 +x:1 +唯实 1 +x:1 +特变 1 +x:1 +唢呐曲 1 +x:1 +雇佣 1 +x:1 +迸 3 +x:3 +侵占者 1 +x:1 +买卖 1 +x:1 +东非 1 +x:1 +专干 1 +x:1 +转体 1 +x:1 +椰树林 1 +x:1 +锑矿 1 +x:1 +水月寺镇 1 +x:1 +承袭 1 +x:1 +垂帐 1 +x:1 +全港 1 +x:1 +铁十一局 1 +x:1 +红楼 1 +x:1 +国际公制 1 +x:1 +西班牙队 1 +x:1 +提子 1 +x:1 +想着 1 +x:1 +国家裁判 1 +x:1 +泰国 1 +x:1 +工程队 1 +x:1 +抬头 1 +x:1 +东面 1 +x:1 +欺 9 +x:9 +垂幅 1 +x:1 +疾言厉色 1 +x:1 +心神不定 1 +x:1 +河套 1 +x:1 +哨声 1 +x:1 +包干儿 1 +x:1 +工程院 1 +x:1 +蒸汽 1 +x:1 +虎画 1 +x:1 +海南省 1 +x:1 +心神不安 1 +x:1 +艺人 1 +x:1 +跑车 1 +x:1 +冤家 1 +x:1 +震后 1 +x:1 +清算 1 +x:1 +安宁市 1 +x:1 +季父 1 +x:1 +报章杂志 1 +x:1 +西瓜刀 1 +x:1 +嘉善县 1 +x:1 +阿里河 1 +x:1 +海埂 1 +x:1 +烧窑 1 +x:1 +呛鼻 1 +x:1 +法医学 1 +x:1 +秋风 1 +x:1 +绝活 1 +x:1 +一线 1 +x:1 +服装店 1 +x:1 +法兰盘 1 +x:1 +海域 1 +x:1 +代表人 1 +x:1 +垃圾站 1 +x:1 +虹储 1 +x:1 +购买日 1 +x:1 +解困办 1 +x:1 +张家界市 1 +x:1 +投降主义 1 +x:1 +暂缓 1 +x:1 +琴弓 1 +x:1 +评点 1 +x:1 +手术费 1 +x:1 +标识 1 +x:1 +老区人 1 +x:1 +冤孽 1 +x:1 +名垂史册 1 +x:1 +伪冒 1 +x:1 +变幻无常 1 +x:1 +站台票 1 +x:1 +改头换面 1 +x:1 +虎痴 1 +x:1 +杨宋镇 1 +x:1 +国务院 1 +x:1 +粤汉 1 +x:1 +探险史 1 +x:1 +英尺 1 +x:1 +伶仃孤苦 1 +x:1 +造响 1 +x:1 +田鼠 1 +x:1 +方便面碗 1 +x:1 +琴弦 1 +x:1 +标语 1 +x:1 +社旗县 1 +x:1 +故城县 1 +x:1 +虎疫 1 +x:1 +萨克斯管 1 +x:1 +保级战 1 +x:1 +井然不紊 1 +x:1 +殡葬 1 +x:1 +心音 1 +x:1 +提审 1 +x:1 +知人之明 1 +x:1 +受难日 1 +x:1 +专座 1 +x:1 +支持人 1 +x:1 +购买方 1 +x:1 +借贷额 1 +x:1 +工序 1 +x:1 +标记 1 +x:1 +外寇 1 +x:1 +方村镇 1 +x:1 +南洋虎 1 +x:1 +哨塔 1 +x:1 +处女 1 +x:1 +运动迷 1 +x:1 +汽车业界 1 +x:1 +流动 1 +x:1 +红榜 1 +x:1 +眸子 1 +x:1 +狐疑不决 1 +x:1 +艺专 1 +x:1 +表现力 1 +x:1 +红桥 1 +x:1 +罐瓶 1 +x:1 +非诉讼 1 +x:1 +诞生 1 +x:1 +必备 1 +x:1 +载波 1 +x:1 +总共 1 +x:1 +瓷都 1 +x:1 +霓灯 1 +x:1 +济困助学 1 +x:1 +水烟斗 1 +x:1 +短网队 1 +x:1 +摩擦 1 +x:1 +宫腔镜 1 +x:1 +残品 1 +x:1 +东陵 1 +x:1 +晒太阳 1 +x:1 +周城镇 1 +x:1 +负债率 1 +x:1 +混合苯 1 +x:1 +红案 1 +x:1 +水深火热 1 +x:1 +轻武器 1 +x:1 +偶像 1 +x:1 +咱 148 +x:148 +业务费 1 +x:1 +指纹图 1 +x:1 +军用 1 +x:1 +拉伤 1 +x:1 +台独 1 +x:1 +自营性 1 +x:1 +及格 1 +x:1 +秃 4 +x:4 +河东 1 +x:1 +索讨 1 +x:1 +赛中 1 +x:1 +江夏区 1 +x:1 +河下 1 +x:1 +成果奖 1 +x:1 +红样 1 +x:1 +大公府 1 +x:1 +归集额 1 +x:1 +田黄 1 +x:1 +淋巴 1 +x:1 +红格 1 +x:1 +海图 1 +x:1 +读物 1 +x:1 +军事化 1 +x:1 +军界 1 +x:1 +屏住 1 +x:1 +东阳 1 +x:1 +东阿 1 +x:1 +收益金 1 +x:1 +等闲 1 +x:1 +茶庄 1 +x:1 +主席令 1 +x:1 +红树 1 +x:1 +瓦片 1 +x:1 +请教 1 +x:1 +决策者 1 +x:1 +乞怜 1 +x:1 +争胜 1 +x:1 +非艺术 1 +x:1 +那洪镇 1 +x:1 +丰茂 1 +x:1 +脓 1 +x:1 +修桥补路 1 +x:1 +南隔堤 1 +x:1 +琴师 1 +x:1 +研制者 1 +x:1 +有误者 1 +x:1 +代表作 1 +x:1 +南霸天 1 +x:1 +请方 1 +x:1 +变压器厂 1 +x:1 +州立 1 +x:1 +丰茸 1 +x:1 +教科书 1 +x:1 +红棉 1 +x:1 +田鸡 1 +x:1 +群蚁附膻 1 +x:1 +荣辱观 1 +x:1 +诠释者 1 +x:1 +宜牧则牧 1 +x:1 +负责 1 +x:1 +宫廷舞 1 +x:1 +答谢话 1 +x:1 +寄 336 +x:336 +味道 1 +x:1 +杨士岗镇 1 +x:1 +滴管 1 +x:1 +买办 1 +x:1 +矿柱 1 +x:1 +土默川 1 +x:1 +雪原 1 +x:1 +湾仔修顿 1 +x:1 +犹太教 1 +x:1 +代表会 1 +x:1 +胎位 1 +x:1 +红梅 1 +x:1 +主权者 1 +x:1 +吃回扣 1 +x:1 +擦 79 +x:79 +巧思 1 +x:1 +闲事儿 1 +x:1 +污渍 1 +x:1 +闰 1 +x:1 +清稿 1 +x:1 +丧心病狂 1 +x:1 +垃圾筒 1 +x:1 +火并 1 +x:1 +田鹨 1 +x:1 +布段 1 +x:1 +初高中 1 +x:1 +赤贫 1 +x:1 +清秋 1 +x:1 +那个 1 +x:1 +事 1823 +x:1823 +猖狂 1 +x:1 +白邑乡 1 +x:1 +政治局 1 +x:1 +公有制 1 +x:1 +熔断 1 +x:1 +娘 54 +x:54 +哀呼 1 +x:1 +逢先必争 1 +x:1 +专属 1 +x:1 +泸水县 1 +x:1 +宵禁 1 +x:1 +全民 1 +x:1 +便当 1 +x:1 +窗户 1 +x:1 +偶发 1 +x:1 +北平道 1 +x:1 +候机 1 +x:1 +况 5 +x:5 +重化工 1 +x:1 +总书记 1 +x:1 +灯芯绒 1 +x:1 +垂尾 1 +x:1 +窗扇 1 +x:1 +清福 1 +x:1 +烧碱 1 +x:1 +争霸 1 +x:1 +底水 1 +x:1 +烟云 1 +x:1 +球星 1 +x:1 +联 141 +x:141 +委托费 1 +x:1 +工尺 1 +x:1 +葡方 1 +x:1 +瑜 35 +x:35 +泰和 1 +x:1 +伍伦贡市 1 +x:1 +演职人员 1 +x:1 +内生 1 +x:1 +底气 1 +x:1 +乞援 1 +x:1 +通电话 1 +x:1 +松针 1 +x:1 +息烽 1 +x:1 +杜梨 1 +x:1 +高跟儿鞋 1 +x:1 +儿艺 1 +x:1 +征象 1 +x:1 +著作权法 1 +x:1 +独一无二 1 +x:1 +月月红 1 +x:1 +东语系 1 +x:1 +招标制 1 +x:1 +底泥 1 +x:1 +陷落 1 +x:1 +演奏员 1 +x:1 +赤足 1 +x:1 +邀请方 1 +x:1 +首发站 1 +x:1 +黑龙江省 1 +x:1 +污浊 1 +x:1 +进化论 1 +x:1 +服装展 1 +x:1 +逾越 1 +x:1 +议政日 1 +x:1 +香赵庄乡 1 +x:1 +灰绿色 1 +x:1 +东门 1 +x:1 +谛听 1 +x:1 +烟丝 1 +x:1 +甘南藏区 1 +x:1 +娘儿们 1 +x:1 +黑龙江 1 +x:1 +村 1258 +x:1258 +芥 1 +x:1 +冤头 1 +x:1 +预计 1 +x:1 +海啸 1 +x:1 +重男轻女 1 +x:1 +烧砖 1 +x:1 +前郭县 1 +x:1 +种猪 1 +x:1 +多项式 1 +x:1 +骨化 1 +x:1 +亡国奴 1 +x:1 +钉锤 1 +x:1 +柔和 1 +x:1 +京韵 1 +x:1 +高产点 1 +x:1 +陈渣 1 +x:1 +公寓楼 1 +x:1 +大体量 1 +x:1 +班禅 1 +x:1 +自治县委 1 +x:1 +紧缩法 1 +x:1 +污泥 1 +x:1 +判别力 1 +x:1 +布楚 1 +x:1 +资格证 1 +x:1 +博物院 1 +x:1 +买假 1 +x:1 +特地 1 +x:1 +帘子 1 +x:1 +承认 1 +x:1 +省力化 1 +x:1 +京阙 1 +x:1 +草坝 1 +x:1 +相沿成习 1 +x:1 +军眷 1 +x:1 +蕲春县 1 +x:1 +基本粒子 1 +x:1 +玉兰 1 +x:1 +争艳 1 +x:1 +拒载 1 +x:1 +核工业城 1 +x:1 +钉耙 1 +x:1 +便帽 1 +x:1 +田鳖 1 +x:1 +承诺 1 +x:1 +耳机 1 +x:1 +往后 1 +x:1 +抽油机 1 +x:1 +计时表 1 +x:1 +大力村 1 +x:1 +乳品 1 +x:1 +复活节岛 1 +x:1 +枉费 1 +x:1 +骨力 1 +x:1 +镜鉴 1 +x:1 +可亲可近 1 +x:1 +滨州 1 +x:1 +索要 1 +x:1 +赤豆 1 +x:1 +合数 1 +x:1 +债权 1 +x:1 +设计院 1 +x:1 +凌波仙子 1 +x:1 +着落 1 +x:1 +布罗特比 1 +x:1 +自收自支 1 +x:1 +币 29 +x:29 +兜底 1 +x:1 +泵业 1 +x:1 +工巧 1 +x:1 +闻风丧胆 1 +x:1 +公费生 1 +x:1 +萨尔图区 1 +x:1 +芜杂 1 +x:1 +专差 1 +x:1 +乳名 1 +x:1 +必定 1 +x:1 +肺动脉 1 +x:1 +墚 1 +x:1 +英式 1 +x:1 +称王称霸 1 +x:1 +特型 1 +x:1 +满园春色 1 +x:1 +带班人 1 +x:1 +九龙壁 1 +x:1 +南蛮 1 +x:1 +不辞劳苦 1 +x:1 +枸杞子 1 +x:1 +幼儿 1 +x:1 +座次 1 +x:1 +落 434 +x:434 +台灯 1 +x:1 +重特大 1 +x:1 +饭来张口 1 +x:1 +骨刺 1 +x:1 +一字排开 1 +x:1 +硅 6 +x:6 +锱铢必较 1 +x:1 +虎皮 1 +x:1 +虹口 1 +x:1 +请柬 1 +x:1 +互相 1 +x:1 +赤身露体 1 +x:1 +刚察县 1 +x:1 +橹 1 +x:1 +海味 1 +x:1 +污水 1 +x:1 +球果 1 +x:1 +远东所 1 +x:1 +亚原子 1 +x:1 +熄灯 1 +x:1 +负载 1 +x:1 +务求 1 +x:1 +熄火 1 +x:1 +丰腴 1 +x:1 +发人深思 1 +x:1 +造型 1 +x:1 +哨子 1 +x:1 +中华民国 1 +x:1 +夹馅 1 +x:1 +粘性 1 +x:1 +火山 1 +x:1 +反省式 1 +x:1 +海 431 +x:431 +模拟 1 +x:1 +海员 1 +x:1 +满打满算 1 +x:1 +布陈 1 +x:1 +漳州 1 +x:1 +扶正培本 1 +x:1 +公用局 1 +x:1 +后宅镇 1 +x:1 +自然界 1 +x:1 +换句话说 1 +x:1 +历险地 1 +x:1 +秋播 1 +x:1 +密密地 1 +x:1 +肆言 1 +x:1 +烙 10 +x:10 +劳动布 1 +x:1 +鸡头 1 +x:1 +失恋 1 +x:1 +称量 1 +x:1 +黑黢黢 1 +x:1 +委员 1 +x:1 +琐言赘语 1 +x:1 +市政局 1 +x:1 +价值计 1 +x:1 +银子 1 +x:1 +萧县 1 +x:1 +港澳台侨 1 +x:1 +打天下 1 +x:1 +难以置信 1 +x:1 +多彩生活 1 +x:1 +事务 1 +x:1 +国事访问 1 +x:1 +咯吱吱 1 +x:1 +军衔 1 +x:1 +可缩性 1 +x:1 +瘟疹 1 +x:1 +迟疑不决 1 +x:1 +门头沟区 1 +x:1 +失态 1 +x:1 +粉刺 1 +x:1 +年限 1 +x:1 +小郭庄村 1 +x:1 +绵密 1 +x:1 +湘东乡 1 +x:1 +鱼鼓 1 +x:1 +耸立 1 +x:1 +文字学 1 +x:1 +除 828 +x:828 +恐龙队 1 +x:1 +马其顿 1 +x:1 +固定资产 1 +x:1 +蹲点 1 +x:1 +军衣 1 +x:1 +东欧 1 +x:1 +新闻台 1 +x:1 +职业 1 +x:1 +布防 1 +x:1 +新闻司 1 +x:1 +事功 1 +x:1 +冈比亚 1 +x:1 +布阵 1 +x:1 +玉皇大帝 1 +x:1 +史诗 1 +x:1 +竹席 1 +x:1 +球风 1 +x:1 +清洌 1 +x:1 +史话 1 +x:1 +骑车 1 +x:1 +实体法 1 +x:1 +租子 1 +x:1 +史评 1 +x:1 +主心骨 1 +x:1 +比肩而立 1 +x:1 +而况 1 +x:1 +竹帽 1 +x:1 +运送者 1 +x:1 +羊皮袄 1 +x:1 +直销式 1 +x:1 +筹备会 1 +x:1 +道德家 1 +x:1 +傀儡 1 +x:1 +保健箱 1 +x:1 +上头 1 +x:1 +发布费 1 +x:1 +涨落 1 +x:1 +事前 1 +x:1 +债额 1 +x:1 +各向同性 1 +x:1 +台车 1 +x:1 +上天 1 +x:1 +知交 1 +x:1 +牛磺酸 1 +x:1 +南移 1 +x:1 +无限度 1 +x:1 +咏春 1 +x:1 +郡级 1 +x:1 +导尿 1 +x:1 +稚拙 1 +x:1 +云帆 1 +x:1 +在家 1 +x:1 +乌龙驹 1 +x:1 +酱菜 1 +x:1 +开倒车 1 +x:1 +陋巷 1 +x:1 +军装 1 +x:1 +胳膊肘儿 1 +x:1 +三一律 1 +x:1 +墙体 1 +x:1 +答谢 1 +x:1 +门坎精 1 +x:1 +发布权 1 +x:1 +茴鱼 1 +x:1 +东段 1 +x:1 +愣住 1 +x:1 +囤 4 +x:4 +巨作 1 +x:1 +苍南县 1 +x:1 +史论 1 +x:1 +兴师动众 1 +x:1 +暗想 1 +x:1 +噼噼叭叭 1 +x:1 +军裤 1 +x:1 +收费仪 1 +x:1 +史训 1 +x:1 +老佛爷 1 +x:1 +铴锣 1 +x:1 +女朋友 1 +x:1 +巨人 1 +x:1 +改弦易辙 1 +x:1 +秭归县 1 +x:1 +皮掌 1 +x:1 +丝丝入扣 1 +x:1 +签字权 1 +x:1 +禁毒署 1 +x:1 +谷雨 1 +x:1 +工程款 1 +x:1 +民力 1 +x:1 +夹板 1 +x:1 +接上头 1 +x:1 +沙枣面 1 +x:1 +冯桥乡 1 +x:1 +丰美 1 +x:1 +锅炉界 1 +x:1 +阿鲁巴岛 1 +x:1 +兴源镇 1 +x:1 +报警点 1 +x:1 +人格 1 +x:1 +万山 1 +x:1 +杞县 1 +x:1 +布面 1 +x:1 +张先村 1 +x:1 +夹杂 1 +x:1 +斋月灯 1 +x:1 +核工程 1 +x:1 +殿堂式 1 +x:1 +事发 1 +x:1 +高科技化 1 +x:1 +扭转形变 1 +x:1 +羊皮褥 1 +x:1 +罐装 1 +x:1 +今归仁村 1 +x:1 +事变 1 +x:1 +侧芽 1 +x:1 +耻辱 1 +x:1 +河东区 1 +x:1 +秋日 1 +x:1 +购买率 1 +x:1 +勍 1 +x:1 +陈醋 1 +x:1 +秋旱 1 +x:1 +快乐 1 +x:1 +学社 1 +x:1 +血统工人 1 +x:1 +槲栎 1 +x:1 +全自动 1 +x:1 +根德拉 1 +x:1 +没心拉肠 1 +x:1 +骄纵 1 +x:1 +快书 1 +x:1 +社会青年 1 +x:1 +启动型 1 +x:1 +上声 1 +x:1 +蔫头耷脑 1 +x:1 +嗅到 1 +x:1 +整合型 1 +x:1 +低纬度 1 +x:1 +茶座 1 +x:1 +反潜 1 +x:1 +参考价 1 +x:1 +乌拉圭队 1 +x:1 +忿 1 +x:1 +胪岗镇 1 +x:1 +称道 1 +x:1 +皮衣 1 +x:1 +★ 14 +x:14 +波浪形 1 +x:1 +瘫痪病 1 +x:1 +陈酒 1 +x:1 +厌 14 +x:14 +女界 1 +x:1 +藻多糖 1 +x:1 +秋收 1 +x:1 +写生 1 +x:1 +咄咄怪事 1 +x:1 +赌风 1 +x:1 +龙王庙 1 +x:1 +巨业 1 +x:1 +祈愿诗 1 +x:1 +红铜 1 +x:1 +待工证 1 +x:1 +气呼呼 1 +x:1 +布鞋 1 +x:1 +借贷方 1 +x:1 +保证率 1 +x:1 +自弃 1 +x:1 +保健站 1 +x:1 +球馆 1 +x:1 +京棉 1 +x:1 +神态自若 1 +x:1 +标的 1 +x:1 +万岁 1 +x:1 +胖 29 +x:29 +现代派 1 +x:1 +投亲靠友 1 +x:1 +叶县 1 +x:1 +几 5204 +x:5204 +过从甚密 1 +x:1 +乌市 1 +x:1 +花柳病 1 +x:1 +蒙头转向 1 +x:1 +读报员 1 +x:1 +波浪式 1 +x:1 +参考书 1 +x:1 +亲切感 1 +x:1 +电化教育 1 +x:1 +付之一炬 1 +x:1 +快件 1 +x:1 +碱性 1 +x:1 +绅士协定 1 +x:1 +情绪化 1 +x:1 +齿 7 +x:7 +投审会 1 +x:1 +熔炼 1 +x:1 +中短传 1 +x:1 +动态性 1 +x:1 +指不定 1 +x:1 +侨团 1 +x:1 +启动器 1 +x:1 +失手 1 +x:1 +与虎谋皮 1 +x:1 +那些 1 +x:1 +上宾 1 +x:1 +小媳妇 1 +x:1 +全速 1 +x:1 +准时 1 +x:1 +上家 1 +x:1 +熔点 1 +x:1 +基址 1 +x:1 +狠抓 1 +x:1 +竹岛 1 +x:1 +跳动 1 +x:1 +炷 2 +x:2 +竹岐 1 +x:1 +退管会 1 +x:1 +示众 1 +x:1 +蜚声 1 +x:1 +肯干 1 +x:1 +视差 1 +x:1 +红靛 1 +x:1 +室内机 1 +x:1 +孔雀石 1 +x:1 +摄 1932 +x:1932 +大街小巷 1 +x:1 +价值观 1 +x:1 +定货量 1 +x:1 +诨号 1 +x:1 +劳动局 1 +x:1 +工兵农 1 +x:1 +生产工具 1 +x:1 +旅游者 1 +x:1 +基地 1 +x:1 +匪患 1 +x:1 +正厅级 1 +x:1 +党委制 1 +x:1 +暗扣 1 +x:1 +媒体 1 +x:1 +非样本 1 +x:1 +爵爷 1 +x:1 +电机 1 +x:1 +汤剂 1 +x:1 +合页 1 +x:1 +广电部 1 +x:1 +草店村 1 +x:1 +考察船 1 +x:1 +红霞 1 +x:1 +鸡犬不留 1 +x:1 +鼻饲 1 +x:1 +予 85 +x:85 +互访 1 +x:1 +警帽 1 +x:1 +汤加 1 +x:1 +效应器 1 +x:1 +倍数 1 +x:1 +耗 22 +x:22 +饱历 1 +x:1 +互让 1 +x:1 +直流 1 +x:1 +秦巴山 1 +x:1 +事假 1 +x:1 +利纳雷斯 1 +x:1 +示例 1 +x:1 +共鸣区 1 +x:1 +五节芒 1 +x:1 +烂泥塘 1 +x:1 +蒙混过关 1 +x:1 +军挎 1 +x:1 +松桃 1 +x:1 +电动车 1 +x:1 +饱受 1 +x:1 +全都 1 +x:1 +连结 1 +x:1 +秋景 1 +x:1 +赛马场 1 +x:1 +作战部 1 +x:1 +互感器 1 +x:1 +全部 1 +x:1 +秒 391 +x:391 +汤勺 1 +x:1 +负片 1 +x:1 +岩心 1 +x:1 +轻工业部 1 +x:1 +竹屋 1 +x:1 +尖锐化 1 +x:1 +有蹄类 1 +x:1 +远镇 1 +x:1 +馍馍 1 +x:1 +松树 1 +x:1 +连绵 1 +x:1 +互评 1 +x:1 +转化率 1 +x:1 +泗水 1 +x:1 +台账 1 +x:1 +崂山 1 +x:1 +驻 1545 +x:1545 +游法 1 +x:1 +好 8876 +x:8876 +导师 1 +x:1 +上季 1 +x:1 +曙光 1 +x:1 +兑现 1 +x:1 +苇箔 1 +x:1 +卫辉 1 +x:1 +警徽 1 +x:1 +高银巷 1 +x:1 +窑 26 +x:26 +轻而易举 1 +x:1 +连缀 1 +x:1 +反派 1 +x:1 +团费 1 +x:1 +表扬信 1 +x:1 +周初 1 +x:1 +垣 3 +x:3 +万年 1 +x:1 +红陌 1 +x:1 +米亚瓦 1 +x:1 +万幸 1 +x:1 +微咸 1 +x:1 +斑竹 1 +x:1 +分裂症 1 +x:1 +警惕心 1 +x:1 +竭泽而渔 1 +x:1 +白首穷经 1 +x:1 +南空 1 +x:1 +袁家岗 1 +x:1 +棉被褥 1 +x:1 +栗钙土 1 +x:1 +连网 1 +x:1 +旅馆区 1 +x:1 +筐 18 +x:18 +夹攻 1 +x:1 +清蒙 1 +x:1 +泄漏 1 +x:1 +答辩 1 +x:1 +研制组 1 +x:1 +玻利瓦尔 1 +x:1 +可调节性 1 +x:1 +打遍天下 1 +x:1 +留连忘返 1 +x:1 +鸡婆 1 +x:1 +否决票 1 +x:1 +议军会 1 +x:1 +曲江县 1 +x:1 +从艺 1 +x:1 +枉然 1 +x:1 +记者 1 +x:1 +朦朦胧胧 1 +x:1 +一版再版 1 +x:1 +军警 1 +x:1 +来稿者 1 +x:1 +纯然 1 +x:1 +族裔 1 +x:1 +明火执仗 1 +x:1 +蛇蜕 1 +x:1 +泥人儿 1 +x:1 +振奋 1 +x:1 +秋末 1 +x:1 +基因 1 +x:1 +基团 1 +x:1 +事关 1 +x:1 +水源林 1 +x:1 +写真 1 +x:1 +程家峪村 1 +x:1 +分队长 1 +x:1 +南站 1 +x:1 +简则 1 +x:1 +暗探 1 +x:1 +到位关 1 +x:1 +南端 1 +x:1 +事先 1 +x:1 +翠绿色 1 +x:1 +以柔克刚 1 +x:1 +奈良 1 +x:1 +等次 1 +x:1 +所长 1 +x:1 +军训 1 +x:1 +连翘 1 +x:1 +赤热 1 +x:1 +血衣 1 +x:1 +临别赠言 1 +x:1 +骨干网 1 +x:1 +末后 1 +x:1 +闹剧 1 +x:1 +导弹 1 +x:1 +纯熟 1 +x:1 +法兰西 1 +x:1 +姿影 1 +x:1 +打官司 1 +x:1 +蛇蝎 1 +x:1 +桐木 1 +x:1 +事儿 1 +x:1 +导引 1 +x:1 +莫可名状 1 +x:1 +颓唐 1 +x:1 +桥儿沟 1 +x:1 +全票 1 +x:1 +闭幕会 1 +x:1 +驱逐机 1 +x:1 +泗洲 1 +x:1 +失控 1 +x:1 +厉行节约 1 +x:1 +陶瓷厂 1 +x:1 +媒介 1 +x:1 +事因 1 +x:1 +免冠 1 +x:1 +汤头镇 1 +x:1 +视察 1 +x:1 +考古学家 1 +x:1 +极乐鸟 1 +x:1 +渝中区 1 +x:1 +被冲击方 1 +x:1 +导士 1 +x:1 +台词 1 +x:1 +国宾 1 +x:1 +逸事 1 +x:1 +全队 1 +x:1 +药款 1 +x:1 +底限 1 +x:1 +周刊 1 +x:1 +心电图仪 1 +x:1 +托运人 1 +x:1 +纯白 1 +x:1 +晴间多云 1 +x:1 +末叶 1 +x:1 +红酒 1 +x:1 +京派 1 +x:1 +园林师 1 +x:1 +铁氧体 1 +x:1 +超逸尘 1 +x:1 +敌占区 1 +x:1 +反对党 1 +x:1 +颓势 1 +x:1 +乌审 1 +x:1 +癌 23 +x:23 +野生虎 1 +x:1 +全院 1 +x:1 +银弹 1 +x:1 +宫阙 1 +x:1 +包背装 1 +x:1 +逮捕 1 +x:1 +沉重感 1 +x:1 +游人如织 1 +x:1 +书本费 1 +x:1 +咬牙切齿 1 +x:1 +沈音 1 +x:1 +打动力 1 +x:1 +加格达奇 1 +x:1 +反诉费 1 +x:1 +粮食厅 1 +x:1 +香港岛 1 +x:1 +棍子 1 +x:1 +不畏强暴 1 +x:1 +上工 1 +x:1 +交通业 1 +x:1 +清莱 1 +x:1 +监测仪 1 +x:1 +种蝎 1 +x:1 +珞璜 1 +x:1 +注射液 1 +x:1 +丰稔 1 +x:1 +改动 1 +x:1 +体工队 1 +x:1 +象山县 1 +x:1 +士气 1 +x:1 +陶冶性情 1 +x:1 +急公好义 1 +x:1 +呢喃细语 1 +x:1 +侵华 1 +x:1 +文献性 1 +x:1 +卖出价 1 +x:1 +璠 1 +x:1 +砰砰 1 +x:1 +硬笔字 1 +x:1 +金典秘笈 1 +x:1 +食而不化 1 +x:1 +基准 1 +x:1 +欠妥 1 +x:1 +史迹 1 +x:1 +氰化钾 1 +x:1 +洱 1 +x:1 +氰化钠 1 +x:1 +内乌肯省 1 +x:1 +在心 1 +x:1 +待业率 1 +x:1 +侵占 1 +x:1 +罢免权 1 +x:1 +空城计 1 +x:1 +田村 1 +x:1 +仲裁权 1 +x:1 +爬坡越岭 1 +x:1 +千古绝响 1 +x:1 +读读 1 +x:1 +九重霄 1 +x:1 +海蜇皮 1 +x:1 +微升 1 +x:1 +三高队 1 +x:1 +攀比 1 +x:1 +戈壁 1 +x:1 +标王 1 +x:1 +赤石 1 +x:1 +中老年 1 +x:1 +鲁西南 1 +x:1 +泻盐 1 +x:1 +黑猩猩 1 +x:1 +出谋划策 1 +x:1 +莹明 1 +x:1 +眉目传情 1 +x:1 +卡通式 1 +x:1 +合照 1 +x:1 +清河 1 +x:1 +博雅塔 1 +x:1 +闪电战 1 +x:1 +清茶 1 +x:1 +全集 1 +x:1 +羞答答 1 +x:1 +紫外 1 +x:1 +东湖 1 +x:1 +中旅 1 +x:1 +汲取 1 +x:1 +茴香 1 +x:1 +上岗 1 +x:1 +大岭镇 1 +x:1 +正本求源 1 +x:1 +县乡镇 1 +x:1 +头道场 1 +x:1 +衣钵 1 +x:1 +失效 1 +x:1 +没意思 1 +x:1 +标牌 1 +x:1 +马角坝 1 +x:1 +超阶段 1 +x:1 +荆沙市 1 +x:1 +上岸 1 +x:1 +课课 1 +x:1 +晦暗 1 +x:1 +而后 1 +x:1 +耍脾气 1 +x:1 +军费 1 +x:1 +清苦 1 +x:1 +儿科 1 +x:1 +聚沙成塔 1 +x:1 +失散 1 +x:1 +息讼 1 +x:1 +银幕 1 +x:1 +附配件 1 +x:1 +出世作 1 +x:1 +年老体弱 1 +x:1 +饱含 1 +x:1 +千古绝唱 1 +x:1 +园林式 1 +x:1 +乐观主义 1 +x:1 +凸面镜 1 +x:1 +臃 1 +x:1 +精武卫国 1 +x:1 +卫视 1 +x:1 +虫情 1 +x:1 +幸灾乐祸 1 +x:1 +桥梁厂 1 +x:1 +呼机 1 +x:1 +纯真 1 +x:1 +借入方 1 +x:1 +诡谲 1 +x:1 +军资 1 +x:1 +全面 1 +x:1 +祈愿 1 +x:1 +新闻团 1 +x:1 +清芬 1 +x:1 +知根知底 1 +x:1 +中长途 1 +x:1 +心醉神迷 1 +x:1 +绵延 1 +x:1 +上峰 1 +x:1 +沙柳丛 1 +x:1 +冰雪期 1 +x:1 +东渡 1 +x:1 +东港 1 +x:1 +逆差 1 +x:1 +在建 1 +x:1 +诱发 1 +x:1 +合龙 1 +x:1 +影碟 1 +x:1 +霓裳 1 +x:1 +殖民地 1 +x:1 +概念化 1 +x:1 +课时 1 +x:1 +微创 1 +x:1 +光头党 1 +x:1 +上尉 1 +x:1 +镇流器 1 +x:1 +援助处 1 +x:1 +铁法官 1 +x:1 +上将 1 +x:1 +饱和 1 +x:1 +果不其然 1 +x:1 +松潘 1 +x:1 +微利 1 +x:1 +烧荒 1 +x:1 +谷类 1 +x:1 +负电 1 +x:1 +秋意 1 +x:1 +冥思 1 +x:1 +抽芽 1 +x:1 +发明权 1 +x:1 +急流勇进 1 +x:1 +蓑衣草 1 +x:1 +挂牌车 1 +x:1 +桑兰西党 1 +x:1 +东滩 1 +x:1 +近当代 1 +x:1 +生死与共 1 +x:1 +样子沟 1 +x:1 +代行 1 +x:1 +东源 1 +x:1 +银座 1 +x:1 +全音 1 +x:1 +阴雨连绵 1 +x:1 +哈医大 1 +x:1 +保准儿 1 +x:1 +百战百胜 1 +x:1 +唐代 1 +x:1 +庭外 1 +x:1 +百废待兴 1 +x:1 +上届 1 +x:1 +槽灌 1 +x:1 +团课 1 +x:1 +泥疗 1 +x:1 +吸收率 1 +x:1 +注射法 1 +x:1 +南粤 1 +x:1 +山里人 1 +x:1 +皮条 1 +x:1 +零部件 1 +x:1 +上山 1 +x:1 +药 299 +x:299 +反比 1 +x:1 +拘役 1 +x:1 +反毒 1 +x:1 +竹子 1 +x:1 +电枢 1 +x:1 +军路 1 +x:1 +过头话 1 +x:1 +课文 1 +x:1 +台角 1 +x:1 +不偏不倚 1 +x:1 +丰碑 1 +x:1 +高音区 1 +x:1 +激奋 1 +x:1 +绝非 1 +x:1 +复员军人 1 +x:1 +陶瓷器 1 +x:1 +实用类 1 +x:1 +布道 1 +x:1 +搏击赛 1 +x:1 +愚 11 +x:11 +北亚 1 +x:1 +免去 1 +x:1 +暗昧 1 +x:1 +东海 1 +x:1 +党 5204 +x:5204 +管事 1 +x:1 +北京 1 +x:1 +等因奉此 1 +x:1 +标煤 1 +x:1 +管井 1 +x:1 +通电率 1 +x:1 +内容各异 1 +x:1 +车船票 1 +x:1 +伪随机码 1 +x:1 +迈步 1 +x:1 +寻常 1 +x:1 +害鸟 1 +x:1 +块茎 1 +x:1 +夯土层 1 +x:1 +主产 1 +x:1 +被服务者 1 +x:1 +北仑 1 +x:1 +私邸 1 +x:1 +侨务 1 +x:1 +东洋 1 +x:1 +上心 1 +x:1 +创作组 1 +x:1 +原故 1 +x:1 +侨办 1 +x:1 +径流量 1 +x:1 +航海家 1 +x:1 +寝食不安 1 +x:1 +园林局 1 +x:1 +张北 1 +x:1 +碘钙片 1 +x:1 +新德里 1 +x:1 +签 112 +x:112 +张口 1 +x:1 +代数和 1 +x:1 +张古 1 +x:1 +辆 680 +x:680 +北上 1 +x:1 +暗暗 1 +x:1 +莫可指数 1 +x:1 +罐车 1 +x:1 +骚扰 1 +x:1 +折 112 +x:112 +赶锥 1 +x:1 +总户数 1 +x:1 +天荒地老 1 +x:1 +急刹车 1 +x:1 +墓道 1 +x:1 +起承转合 1 +x:1 +等温 1 +x:1 +翻刻本 1 +x:1 +清腾 1 +x:1 +侵入 1 +x:1 +主义 1 +x:1 +南翼 1 +x:1 +银川 1 +x:1 +紫杉 1 +x:1 +语声 1 +x:1 +别墅式 1 +x:1 +微光 1 +x:1 +舰种 1 +x:1 +海绵田 1 +x:1 +丰硕 1 +x:1 +诡辩 1 +x:1 +南美 1 +x:1 +清脆 1 +x:1 +赤痢 1 +x:1 +鲁美 1 +x:1 +齑 1 +x:1 +免却 1 +x:1 +乌头 1 +x:1 +瓦解 1 +x:1 +万宁 1 +x:1 +方略图 1 +x:1 +昆士兰 1 +x:1 +获奖率 1 +x:1 +万安 1 +x:1 +续航力 1 +x:1 +耳听八方 1 +x:1 +鸡心 1 +x:1 +总支出 1 +x:1 +赏心亭 1 +x:1 +北乡 1 +x:1 +张厅 1 +x:1 +无形中 1 +x:1 +主业 1 +x:1 +虫 40 +x:40 +松气 1 +x:1 +事后 1 +x:1 +管乐 1 +x:1 +硅钢 1 +x:1 +倍感 1 +x:1 +末儿 1 +x:1 +心魂俱醉 1 +x:1 +丰镇 1 +x:1 +蛇莓 1 +x:1 +脉络 1 +x:1 +东江 1 +x:1 +全市性 1 +x:1 +重金 1 +x:1 +所里 1 +x:1 +刎 1 +x:1 +银山 1 +x:1 +答语 1 +x:1 +敦实 1 +x:1 +称雄 1 +x:1 +解困扶贫 1 +x:1 +答询 1 +x:1 +主修 1 +x:1 +东汉 1 +x:1 +北侧 1 +x:1 +考古学 1 +x:1 +答话 1 +x:1 +呼救 1 +x:1 +警官 1 +x:1 +热身赛 1 +x:1 +东汽 1 +x:1 +银屏 1 +x:1 +冷若冰霜 1 +x:1 +殳 1 +x:1 +答词 1 +x:1 +论说体 1 +x:1 +邮折 1 +x:1 +阶 2 +x:2 +标灯 1 +x:1 +元素 1 +x:1 +复垦区 1 +x:1 +上座 1 +x:1 +上庠 1 +x:1 +广袤无际 1 +x:1 +杀 128 +x:128 +读取头 1 +x:1 +松子 1 +x:1 +邀集 1 +x:1 +全长 1 +x:1 +北极光 1 +x:1 +暗杀 1 +x:1 +失望 1 +x:1 +防风固沙 1 +x:1 +品茗杯 1 +x:1 +直落 1 +x:1 +课本 1 +x:1 +大观楼 1 +x:1 +红道道 1 +x:1 +生长期 1 +x:1 +历史学家 1 +x:1 +庭室 1 +x:1 +松涛 1 +x:1 +庭审 1 +x:1 +璜土镇 1 +x:1 +课期 1 +x:1 +哓哓 1 +x:1 +圩子 1 +x:1 +军援 1 +x:1 +警察 1 +x:1 +发给 1 +x:1 +军车 1 +x:1 +虎踞 1 +x:1 +管保 1 +x:1 +必备书 1 +x:1 +间歇热 1 +x:1 +上帝 1 +x:1 +连音 1 +x:1 +解铃系铃 1 +x:1 +看 3781 +x:3781 +主使 1 +x:1 +笔墨官司 1 +x:1 +为时不晚 1 +x:1 +洞若观火 1 +x:1 +稚拙性 1 +x:1 +北伐 1 +x:1 +九曲八拐 1 +x:1 +阴性植物 1 +x:1 +浅酌醉吟 1 +x:1 +恶贯满盈 1 +x:1 +主体 1 +x:1 +诞辰 1 +x:1 +宫门 1 +x:1 +梅县 1 +x:1 +不至于 1 +x:1 +宫闱 1 +x:1 +外宣 1 +x:1 +大发横财 1 +x:1 +四五点 1 +x:1 +争端 1 +x:1 +公安队 1 +x:1 +拉各斯港 1 +x:1 +硬通货 1 +x:1 +标本虫 1 +x:1 +玩赏 1 +x:1 +券面 1 +x:1 +东沟 1 +x:1 +松洲 1 +x:1 +维尔京 1 +x:1 +鱼鳔 1 +x:1 +奖赏 1 +x:1 +驼群 1 +x:1 +新市乡 1 +x:1 +肯定 1 +x:1 +叶喷 1 +x:1 +抗病力 1 +x:1 +激增 1 +x:1 +艺外 1 +x:1 +各口村 1 +x:1 +直根 1 +x:1 +上年 1 +x:1 +寨 19 +x:19 +南纬 1 +x:1 +前卫型 1 +x:1 +卫生部长 1 +x:1 +标点 1 +x:1 +拘留所 1 +x:1 +鱼鳞 1 +x:1 +松脆 1 +x:1 +张力 1 +x:1 +南纺 1 +x:1 +分子结构 1 +x:1 +人声鼎沸 1 +x:1 +怡然自乐 1 +x:1 +全知全能 1 +x:1 +反映 1 +x:1 +遣散 1 +x:1 +讯问 1 +x:1 +反是 1 +x:1 +实体 1 +x:1 +连通 1 +x:1 +上册 1 +x:1 +逐 57 +x:57 +清还 1 +x:1 +球道 1 +x:1 +新闻官 1 +x:1 +清运 1 +x:1 +连理 1 +x:1 +绽裂 1 +x:1 +优抚金 1 +x:1 +微微 1 +x:1 +上冻 1 +x:1 +神经科学 1 +x:1 +北极带 1 +x:1 +运杂费 1 +x:1 +溯 7 +x:7 +砀山县 1 +x:1 +而外 1 +x:1 +黑手党 1 +x:1 +宴席 1 +x:1 +课桌 1 +x:1 +工艺流程 1 +x:1 +委屈 1 +x:1 +桁架 1 +x:1 +水曲柳 1 +x:1 +暗格 1 +x:1 +胃溃疡 1 +x:1 +道德化 1 +x:1 +银匠 1 +x:1 +秋波 1 +x:1 +财产 1 +x:1 +清辉 1 +x:1 +上中农 1 +x:1 +丰盛 1 +x:1 +接生员 1 +x:1 +受灾县 1 +x:1 +金铃果 1 +x:1 +供职者 1 +x:1 +球速 1 +x:1 +国定 1 +x:1 +丰盈 1 +x:1 +乏味 1 +x:1 +军职 1 +x:1 +前三门 1 +x:1 +鱼鳍 1 +x:1 +颓废 1 +x:1 +鹤 13 +x:13 +振动 1 +x:1 +参天大树 1 +x:1 +祥虎送福 1 +x:1 +坚贞不渝 1 +x:1 +上诉状 1 +x:1 +中央税 1 +x:1 +可逆反应 1 +x:1 +彻夜不眠 1 +x:1 +大麻子 1 +x:1 +鸡冠 1 +x:1 +撒欢 1 +x:1 +库马西市 1 +x:1 +同场竞技 1 +x:1 +娱乐性 1 +x:1 +歇绝 1 +x:1 +签名 1 +x:1 +佳节 1 +x:1 +淫逸 1 +x:1 +松扣 1 +x:1 +老姐儿 1 +x:1 +免疫率 1 +x:1 +简史 1 +x:1 +乐不可支 1 +x:1 +侨属 1 +x:1 +免烫剂 1 +x:1 +单根独苗 1 +x:1 +豁免权 1 +x:1 +镇定 1 +x:1 +粮所 1 +x:1 +松手 1 +x:1 +摩配 1 +x:1 +购买金 1 +x:1 +鲸 6 +x:6 +途径 1 +x:1 +侨居 1 +x:1 +种兔场 1 +x:1 +上党 1 +x:1 +蕉 1 +x:1 +介休站 1 +x:1 +孤寡老人 1 +x:1 +换流站 1 +x:1 +实例 1 +x:1 +上光 1 +x:1 +汤壶 1 +x:1 +财主 1 +x:1 +老大劲儿 1 +x:1 +新闻学 1 +x:1 +导向 1 +x:1 +警员 1 +x:1 +阿帕网 1 +x:1 +二次方程 1 +x:1 +弟妇 1 +x:1 +小肠串气 1 +x:1 +侏罗纪 1 +x:1 +陈屿镇 1 +x:1 +财东 1 +x:1 +警告 1 +x:1 +候选 1 +x:1 +这么 1 +x:1 +领主 1 +x:1 +大明寺 1 +x:1 +精精神神 1 +x:1 +翠亨 1 +x:1 +助学情 1 +x:1 +健在者 1 +x:1 +咪表 1 +x:1 +红鱼 1 +x:1 +汤头 1 +x:1 +实乃 1 +x:1 +冥河 1 +x:1 +静摩擦力 1 +x:1 +绝顶 1 +x:1 +蛇足 1 +x:1 +啾啾 1 +x:1 +海椒市街 1 +x:1 +谐调 1 +x:1 +基层 1 +x:1 +连用 1 +x:1 +江苏省 1 +x:1 +吁请 1 +x:1 +实习 1 +x:1 +财保 1 +x:1 +跑程 1 +x:1 +实业 1 +x:1 +这不 1 +x:1 +充盈 1 +x:1 +持球者 1 +x:1 +麦门冬 1 +x:1 +真迹 1 +x:1 +称颂 1 +x:1 +国庆节 1 +x:1 +编年史 1 +x:1 +遵义 1 +x:1 +银制 1 +x:1 +张灯结彩 1 +x:1 +互联 1 +x:1 +实为 1 +x:1 +这个 1 +x:1 +末座 1 +x:1 +进出口者 1 +x:1 +电信法 1 +x:1 +代数学 1 +x:1 +连番 1 +x:1 +枇杷树 1 +x:1 +幼功 1 +x:1 +割断 1 +x:1 +鱼米之乡 1 +x:1 +事实 1 +x:1 +事宜 1 +x:1 +非君莫属 1 +x:1 +简便易行 1 +x:1 +棕油 1 +x:1 +史苑 1 +x:1 +具体地说 1 +x:1 +否决率 1 +x:1 +防火员 1 +x:1 +绝食 1 +x:1 +悖 8 +x:8 +完 681 +x:681 +高头大马 1 +x:1 +由此观之 1 +x:1 +祸从天降 1 +x:1 +联邦院 1 +x:1 +火山地震 1 +x:1 +蜂窝状 1 +x:1 +陕甘 1 +x:1 +清粼粼 1 +x:1 +楼兰王国 1 +x:1 +寻见 1 +x:1 +虎胆 1 +x:1 +实价 1 +x:1 +木麻黄树 1 +x:1 +原子尘 1 +x:1 +末年 1 +x:1 +邻乡 1 +x:1 +镇宁 1 +x:1 +鳝塘村 1 +x:1 +垃圾车 1 +x:1 +阅历 1 +x:1 +基岩 1 +x:1 +并行不悖 1 +x:1 +收益数 1 +x:1 +门多萨 1 +x:1 +麦穗鱼 1 +x:1 +邕宁 1 +x:1 +布龙 1 +x:1 +实事 1 +x:1 +赤竹 1 +x:1 +逆光 1 +x:1 +业务科 1 +x:1 +虎肉 1 +x:1 +兵不厌诈 1 +x:1 +班车 1 +x:1 +财企 1 +x:1 +标线 1 +x:1 +班轮 1 +x:1 +失调 1 +x:1 +窗门 1 +x:1 +企划局 1 +x:1 +屹 2 +x:2 +禁赛期 1 +x:1 +整流器 1 +x:1 +总指挥 1 +x:1 +财会 1 +x:1 +妇产科 1 +x:1 +虎坊桥 1 +x:1 +梅李镇 1 +x:1 +工程性 1 +x:1 +有鉴 1 +x:1 +合适 1 +x:1 +西客厅 1 +x:1 +兵丁 1 +x:1 +异口同声 1 +x:1 +祷文 1 +x:1 +保险业 1 +x:1 +保险丝 1 +x:1 +夜来香 1 +x:1 +上去 1 +x:1 +庭园 1 +x:1 +兵临 1 +x:1 +军船 1 +x:1 +互感应 1 +x:1 +空语句 1 +x:1 +免得 1 +x:1 +非公有制 1 +x:1 +夹江 1 +x:1 +穿梭机 1 +x:1 +出奇制胜 1 +x:1 +皮棉 1 +x:1 +罗营乡 1 +x:1 +安家镇 1 +x:1 +满面笑容 1 +x:1 +清越 1 +x:1 +行列式 1 +x:1 +惨绝人寰 1 +x:1 +付之一笑 1 +x:1 +平心静气 1 +x:1 +承继 1 +x:1 +有助于 1 +x:1 +国际联盟 1 +x:1 +脉率 1 +x:1 +入学率 1 +x:1 +篡 1 +x:1 +援助国 1 +x:1 +张开 1 +x:1 +上司 1 +x:1 +军艺 1 +x:1 +兵乱 1 +x:1 +绝无仅有 1 +x:1 +潮 111 +x:111 +洞庭湖 1 +x:1 +温尼伯市 1 +x:1 +蜂窝煤 1 +x:1 +饱学 1 +x:1 +上古 1 +x:1 +张弛 1 +x:1 +风级 1 +x:1 +兵书 1 +x:1 +五体投地 1 +x:1 +用餐 1 +x:1 +河湾里村 1 +x:1 +上口 1 +x:1 +夹注 1 +x:1 +罅漏 1 +x:1 +保险人 1 +x:1 +辐射源 1 +x:1 +组员 1 +x:1 +新闻处 1 +x:1 +准集约型 1 +x:1 +冬剪 1 +x:1 +阙如 1 +x:1 +哈哈大笑 1 +x:1 +广泛性 1 +x:1 +盘山县 1 +x:1 +伙 44 +x:44 +紫堇 1 +x:1 +了事 1 +x:1 +曳动 1 +x:1 +镜架 1 +x:1 +复印件 1 +x:1 +跳水池 1 +x:1 +低微 1 +x:1 +南珠 1 +x:1 +有奖销售 1 +x:1 +造影剂 1 +x:1 +版画集 1 +x:1 +大不了 1 +x:1 +首脑级 1 +x:1 +芰 1 +x:1 +举例 1 +x:1 +胳膊肘子 1 +x:1 +充电 1 +x:1 +中兴 1 +x:1 +银冠 1 +x:1 +龙门刨 1 +x:1 +泛化 1 +x:1 +喝酒 1 +x:1 +充畅 1 +x:1 +宫颈 1 +x:1 +细丝 1 +x:1 +上午 1 +x:1 +城山镇 1 +x:1 +上半 1 +x:1 +矿部 1 +x:1 +吉大港 1 +x:1 +夹河 1 +x:1 +上升 1 +x:1 +毫无顾忌 1 +x:1 +视唱 1 +x:1 +幼儿所 1 +x:1 +全食 1 +x:1 +清贫 1 +x:1 +泛区 1 +x:1 +清账 1 +x:1 +清财 1 +x:1 +重见天日 1 +x:1 +人际网 1 +x:1 +清费 1 +x:1 +别墅区 1 +x:1 +在册 1 +x:1 +石蕊试纸 1 +x:1 +兽 6 +x:6 +纯碱 1 +x:1 +两极 1 +x:1 +红鹤 1 +x:1 +出入院 1 +x:1 +霓虹 1 +x:1 +圩场 1 +x:1 +死里逃生 1 +x:1 +鲁版 1 +x:1 +拨冗 1 +x:1 +象形 1 +x:1 +每桶 1 +x:1 +贸促会 1 +x:1 +依我看 1 +x:1 +鼻部 1 +x:1 +反攻 1 +x:1 +南洋杉 1 +x:1 +举业 1 +x:1 +航海图 1 +x:1 +编组站 1 +x:1 +求田问舍 1 +x:1 +举世 1 +x:1 +松懈 1 +x:1 +百孔千疮 1 +x:1 +避孕针 1 +x:1 +治国 1 +x:1 +南特 1 +x:1 +孔雀绿 1 +x:1 +亚马孙河 1 +x:1 +电业局 1 +x:1 +前呼后应 1 +x:1 +设计所 1 +x:1 +目的论 1 +x:1 +哕 1 +x:1 +阳刚雄强 1 +x:1 +连着 1 +x:1 +删改 1 +x:1 +主汛期 1 +x:1 +羡慕者 1 +x:1 +微不足道 1 +x:1 +香港厅 1 +x:1 +狠毒 1 +x:1 +拜占庭 1 +x:1 +拉床 1 +x:1 +上勤 1 +x:1 +都 12202 +x:12202 +汤子 1 +x:1 +圩垸 1 +x:1 +纯种 1 +x:1 +远东队 1 +x:1 +陷阱 1 +x:1 +微小 1 +x:1 +占有者 1 +x:1 +上列 1 +x:1 +细作 1 +x:1 +价值者 1 +x:1 +写作者 1 +x:1 +喔 1 +x:1 +基建 1 +x:1 +负笈 1 +x:1 +鸡虫得失 1 +x:1 +孝行 1 +x:1 +基廷 1 +x:1 +反方 1 +x:1 +木马计 1 +x:1 +争相 1 +x:1 +领事 1 +x:1 +蓝旗营 1 +x:1 +导坑 1 +x:1 +总督府 1 +x:1 +万国 1 +x:1 +钝角 1 +x:1 +阿拉伯 1 +x:1 +裹挟 1 +x:1 +振兴 1 +x:1 +全馆 1 +x:1 +枝丫 1 +x:1 +租借 1 +x:1 +铜梁县 1 +x:1 +油画家 1 +x:1 +喝道 1 +x:1 +拆 106 +x:106 +基座 1 +x:1 +清调 1 +x:1 +讽刺 1 +x:1 +上前 1 +x:1 +射箭 1 +x:1 +谁是谁非 1 +x:1 +增压器 1 +x:1 +俘 6 +x:6 +务须 1 +x:1 +曲射炮 1 +x:1 +视同 1 +x:1 +随耕 1 +x:1 +红麻 1 +x:1 +张庄 1 +x:1 +语委 1 +x:1 +改厕 1 +x:1 +练习 1 +x:1 +调味品 1 +x:1 +瓦蓝 1 +x:1 +张店 1 +x:1 +收益权 1 +x:1 +基底 1 +x:1 +柴草堆 1 +x:1 +视听 1 +x:1 +末尾 1 +x:1 +鼻音 1 +x:1 +东村 1 +x:1 +开发人 1 +x:1 +南界 1 +x:1 +清话 1 +x:1 +披肝沥胆 1 +x:1 +朝觐者 1 +x:1 +万元 1 +x:1 +清正 1 +x:1 +反作用 1 +x:1 +自讨苦吃 1 +x:1 +海瑞墓 1 +x:1 +人格化 1 +x:1 +油画展 1 +x:1 +高新产品 1 +x:1 +标签 1 +x:1 +手头字 1 +x:1 +暗沉沉 1 +x:1 +求职 1 +x:1 +青苔村 1 +x:1 +小杨屯村 1 +x:1 +军营 1 +x:1 +乌发 1 +x:1 +京政 1 +x:1 +县人委 1 +x:1 +反战 1 +x:1 +万全 1 +x:1 +肆虐 1 +x:1 +代顿市 1 +x:1 +兴会 1 +x:1 +张大 1 +x:1 +蛇 31 +x:31 +条幅 1 +x:1 +科研楼 1 +x:1 +主办方 1 +x:1 +讽喻 1 +x:1 +藕色 1 +x:1 +激化 1 +x:1 +刮漆 1 +x:1 +礁林 1 +x:1 +轰动 1 +x:1 +诊断法 1 +x:1 +鸡啼 1 +x:1 +兴企 1 +x:1 +签注 1 +x:1 +受制于人 1 +x:1 +黄褐色 1 +x:1 +银圆 1 +x:1 +啦 115 +x:115 +反手 1 +x:1 +日记本 1 +x:1 +红餐 1 +x:1 +素菜 1 +x:1 +基多 1 +x:1 +鲜亮 1 +x:1 +直接 1 +x:1 +逆向 1 +x:1 +绵土 1 +x:1 +官麓村 1 +x:1 +参展国 1 +x:1 +宣讲会 1 +x:1 +劳动力 1 +x:1 +升旗手 1 +x:1 +反击战 1 +x:1 +竹刻 1 +x:1 +末子 1 +x:1 +主体观 1 +x:1 +常用语 1 +x:1 +参展团 1 +x:1 +五短身材 1 +x:1 +舟 44 +x:44 +中技 1 +x:1 +舷窗 1 +x:1 +直捷 1 +x:1 +己所不欲 1 +x:1 +设计方 1 +x:1 +兴修 1 +x:1 +反抗 1 +x:1 +暗河 1 +x:1 +棕榈 1 +x:1 +白话文 1 +x:1 +反折 1 +x:1 +南疆 1 +x:1 +拼贴 1 +x:1 +寻衅 1 +x:1 +初掌帅印 1 +x:1 +京族 1 +x:1 +屋 123 +x:123 +东枝 1 +x:1 +怒目而视 1 +x:1 +谐波 1 +x:1 +耍嘴皮子 1 +x:1 +巴厘巴板 1 +x:1 +而已 1 +x:1 +直指 1 +x:1 +呼图壁 1 +x:1 +中央级 1 +x:1 +纯纯 1 +x:1 +桐树 1 +x:1 +胆绿素 1 +x:1 +巩膜 1 +x:1 +季节 1 +x:1 +反拉 1 +x:1 +内生肌肝 1 +x:1 +海裳杯 1 +x:1 +叶序 1 +x:1 +拴 30 +x:30 +攀援 1 +x:1 +镏金 1 +x:1 +碱法 1 +x:1 +代数式 1 +x:1 +悉 9 +x:9 +饱尝 1 +x:1 +现实性 1 +x:1 +蔗林 1 +x:1 +直拍 1 +x:1 +沏茶 1 +x:1 +触景生情 1 +x:1 +饲养员 1 +x:1 +东晋 1 +x:1 +涉险 1 +x:1 +雪窦寺 1 +x:1 +棕树 1 +x:1 +污黑 1 +x:1 +好事者 1 +x:1 +城乡村 1 +x:1 +军操 1 +x:1 +俯拾皆是 1 +x:1 +松柏 1 +x:1 +冬暖式 1 +x:1 +瓦舍 1 +x:1 +逾 145 +x:145 +失节事大 1 +x:1 +兴业 1 +x:1 +激切 1 +x:1 +暗流 1 +x:1 +慈 3 +x:3 +视力 1 +x:1 +庆祝 1 +x:1 +仓管处 1 +x:1 +岳丈 1 +x:1 +治危策 1 +x:1 +东明 1 +x:1 +衡水 1 +x:1 +曝 3 +x:3 +上品 1 +x:1 +竹叶 1 +x:1 +承租 1 +x:1 +萧萧 1 +x:1 +松果 1 +x:1 +婆家 1 +x:1 +烃原岩 1 +x:1 +后杭爱省 1 +x:1 +戈兰 1 +x:1 +剪 47 +x:47 +生津止渴 1 +x:1 +松林 1 +x:1 +压面机 1 +x:1 +牦牛肉 1 +x:1 +无资格 1 +x:1 +东映 1 +x:1 +守护神 1 +x:1 +考察费 1 +x:1 +研究者 1 +x:1 +麻子 1 +x:1 +银团 1 +x:1 +候补委员 1 +x:1 +赤红 1 +x:1 +则 2228 +x:2228 +焓 1 +x:1 +导入 1 +x:1 +劳动厅 1 +x:1 +独具特色 1 +x:1 +海参崴队 1 +x:1 +锦宴 1 +x:1 +攀折 1 +x:1 +南瓜 1 +x:1 +标立 1 +x:1 +果 150 +x:150 +教书育人 1 +x:1 +球门 1 +x:1 +标竿 1 +x:1 +射击场 1 +x:1 +混合物 1 +x:1 +巧遇 1 +x:1 +松杉 1 +x:1 +热敏电阻 1 +x:1 +慰问 1 +x:1 +最底层 1 +x:1 +种族 1 +x:1 +样板房 1 +x:1 +警具 1 +x:1 +请问 1 +x:1 +闽西 1 +x:1 +窗里 1 +x:1 +欢欣鼓舞 1 +x:1 +指导价 1 +x:1 +松木 1 +x:1 +等效 1 +x:1 +独山子区 1 +x:1 +陉阳驿 1 +x:1 +上告 1 +x:1 +平头正脸 1 +x:1 +选购节 1 +x:1 +碱水 1 +x:1 +暗淡 1 +x:1 +创作界 1 +x:1 +反对声 1 +x:1 +激动 1 +x:1 +店张镇 1 +x:1 +不苟言笑 1 +x:1 +领事司 1 +x:1 +旅游城 1 +x:1 +规正 1 +x:1 +激励 1 +x:1 +上周 1 +x:1 +红颜 1 +x:1 +摆勺 1 +x:1 +内疚 1 +x:1 +兴亡 1 +x:1 +息肉 1 +x:1 +营销商 1 +x:1 +清规 1 +x:1 +黄锈病 1 +x:1 +激光 1 +x:1 +镊子 1 +x:1 +万博 1 +x:1 +微妙 1 +x:1 +万千 1 +x:1 +所失者 1 +x:1 +晦涩 1 +x:1 +棍儿 1 +x:1 +鸡场 1 +x:1 +依附性 1 +x:1 +咧 4 +x:4 +非上市 1 +x:1 +制黄 1 +x:1 +警力 1 +x:1 +村党委 1 +x:1 +极右派 1 +x:1 +闭关锁国 1 +x:1 +江南 1 +x:1 +激进主义 1 +x:1 +切面 1 +x:1 +委婉 1 +x:1 +反思 1 +x:1 +负约 1 +x:1 +瓦脊 1 +x:1 +向背 1 +x:1 +才情 1 +x:1 +勇创 1 +x:1 +肯切 1 +x:1 +斤斤 1 +x:1 +飏 1 +x:1 +球队 1 +x:1 +重要性 1 +x:1 +抽象代数 1 +x:1 +卡奥沃斯 1 +x:1 +胆战心惊 1 +x:1 +连片 1 +x:1 +离散 1 +x:1 +掂 6 +x:6 +团职 1 +x:1 +标示 1 +x:1 +干脆利落 1 +x:1 +昏头胀脑 1 +x:1 +咽喉片 1 +x:1 +抢修班 1 +x:1 +党卫军 1 +x:1 +斤斗 1 +x:1 +喝问 1 +x:1 +饲养场 1 +x:1 +演奏会 1 +x:1 +炮弹箱 1 +x:1 +火井 1 +x:1 +杯中物 1 +x:1 +邃远 1 +x:1 +负担率 1 +x:1 +受者 1 +x:1 +邀请 1 +x:1 +乌共 1 +x:1 +静乐 1 +x:1 +益寿延年 1 +x:1 +窑洞 1 +x:1 +新苗 1 +x:1 +夹棍 1 +x:1 +花纱布 1 +x:1 +说不过去 1 +x:1 +襟怀坦白 1 +x:1 +上地 1 +x:1 +微电子 1 +x:1 +川奈 1 +x:1 +反悔 1 +x:1 +万古 1 +x:1 +乏力 1 +x:1 +写稿 1 +x:1 +罗马式 1 +x:1 +织绣 1 +x:1 +直感 1 +x:1 +野雀儿 1 +x:1 +上坟 1 +x:1 +消防人 1 +x:1 +报警网 1 +x:1 +业务组 1 +x:1 +万历 1 +x:1 +非此即彼 1 +x:1 +瓣儿 1 +x:1 +少林寺 1 +x:1 +合同商 1 +x:1 +进寸退尺 1 +x:1 +上坂 1 +x:1 +售房款 1 +x:1 +势在必行 1 +x:1 +棕毛 1 +x:1 +侵夺 1 +x:1 +万县 1 +x:1 +应选人 1 +x:1 +肇庆市 1 +x:1 +执行者 1 +x:1 +暗滩 1 +x:1 +东方 1 +x:1 +茂南 1 +x:1 +由是 1 +x:1 +纯粹 1 +x:1 +神炮手 1 +x:1 +上坡 1 +x:1 +孝情 1 +x:1 +贫下中农 1 +x:1 +冶钢 1 +x:1 +史著 1 +x:1 +地主阶级 1 +x:1 +军政 1 +x:1 +异体 1 +x:1 +台胞 1 +x:1 +细胞株 1 +x:1 +靖边楼 1 +x:1 +橘红色 1 +x:1 +边缘型 1 +x:1 +面点师 1 +x:1 +不一而足 1 +x:1 +视像 1 +x:1 +无情无义 1 +x:1 +语调 1 +x:1 +工作 1 +x:1 +球面 1 +x:1 +单晶硅 1 +x:1 +掳 1 +x:1 +切除 1 +x:1 +勤俭持家 1 +x:1 +读者 1 +x:1 +碱滩 1 +x:1 +反感 1 +x:1 +参展商 1 +x:1 +荧光粉 1 +x:1 +矿长 1 +x:1 +班规 1 +x:1 +上回 1 +x:1 +熔铸 1 +x:1 +警号 1 +x:1 +警司 1 +x:1 +劳动党 1 +x:1 +山石 1 +x:1 +几何体 1 +x:1 +万分 1 +x:1 +敬业爱岗 1 +x:1 +仲裁法 1 +x:1 +晨光熹微 1 +x:1 +警句 1 +x:1 +扭扭捏捏 1 +x:1 +竹凳 1 +x:1 +除虫菊 1 +x:1 +负翁 1 +x:1 +业务网 1 +x:1 +上图 1 +x:1 +鱼塘乡 1 +x:1 +心事重重 1 +x:1 +获胜者 1 +x:1 +各有所持 1 +x:1 +腐败风 1 +x:1 +畜皮 1 +x:1 +乡试录 1 +x:1 +巷 19 +x:19 +截煤机 1 +x:1 +朗读 1 +x:1 +行政诉讼 1 +x:1 +逗笑儿 1 +x:1 +台联 1 +x:1 +登临 1 +x:1 +警区 1 +x:1 +蕴藉 1 +x:1 +装殓 1 +x:1 +因为 1 +x:1 +函授部 1 +x:1 +转租 1 +x:1 +南盟 1 +x:1 +松散 1 +x:1 +跳蚤市场 1 +x:1 +新出办 1 +x:1 +晦气 1 +x:1 +浙赣 1 +x:1 +闹市 1 +x:1 +事出有因 1 +x:1 +戒严法 1 +x:1 +婆娘 1 +x:1 +镜报 1 +x:1 +卡巴纳 1 +x:1 +庶 2 +x:2 +琉璃河 1 +x:1 +老龙头 1 +x:1 +割据 1 +x:1 +下天 1 +x:1 +球鞋 1 +x:1 +坦诚相待 1 +x:1 +新闻局 1 +x:1 +导医 1 +x:1 +奏 56 +x:56 +大片大片 1 +x:1 +摆动 1 +x:1 +警卫 1 +x:1 +征收局 1 +x:1 +丸子 1 +x:1 +苞 6 +x:6 +委实 1 +x:1 +罗柴冲 1 +x:1 +业户 1 +x:1 +百鸟园 1 +x:1 +再者说 1 +x:1 +南皮 1 +x:1 +陆丰市 1 +x:1 +市政厅 1 +x:1 +碱渣 1 +x:1 +拉依喀乡 1 +x:1 +负罪 1 +x:1 +连珠 1 +x:1 +卟啉铁 1 +x:1 +水烟袋 1 +x:1 +财团 1 +x:1 +学生部 1 +x:1 +下头 1 +x:1 +民权主义 1 +x:1 +底色 1 +x:1 +标杆 1 +x:1 +里丁屿 1 +x:1 +粘连 1 +x:1 +半公开 1 +x:1 +攀缘 1 +x:1 +季鹰 1 +x:1 +导航者 1 +x:1 +这块 1 +x:1 +球衫 1 +x:1 +支技者 1 +x:1 +竹事 1 +x:1 +艺德 1 +x:1 +失灵 1 +x:1 +头状花序 1 +x:1 +球衣 1 +x:1 +扩军备战 1 +x:1 +获奖数 1 +x:1 +翎翅 1 +x:1 +开发办 1 +x:1 +丰溢 1 +x:1 +展示板 1 +x:1 +隆尧 1 +x:1 +清韵 1 +x:1 +失火 1 +x:1 +南楼 1 +x:1 +清音 1 +x:1 +终场 1 +x:1 +黏稠度 1 +x:1 +兵员 1 +x:1 +部长会议 1 +x:1 +兴化 1 +x:1 +底舱 1 +x:1 +庵东镇 1 +x:1 +快当 1 +x:1 +翎羽 1 +x:1 +不慌不忙 1 +x:1 +流芳百世 1 +x:1 +东笋 1 +x:1 +平潭县 1 +x:1 +保险员 1 +x:1 +狗爪子花 1 +x:1 +抽噎 1 +x:1 +转运站 1 +x:1 +实地 1 +x:1 +兵味 1 +x:1 +湖南省 1 +x:1 +实在 1 +x:1 +丰满 1 +x:1 +八大山人 1 +x:1 +标本 1 +x:1 +红藤 1 +x:1 +润湿性 1 +x:1 +演讲稿 1 +x:1 +视作 1 +x:1 +底特律市 1 +x:1 +议定书 1 +x:1 +棒子面粥 1 +x:1 +宫苑 1 +x:1 +清静 1 +x:1 +青饲料 1 +x:1 +劝和 1 +x:1 +红藻 1 +x:1 +使团长 1 +x:1 +唐宗 1 +x:1 +兴叹 1 +x:1 +脑血管病 1 +x:1 +球裤 1 +x:1 +保温屋 1 +x:1 +恐龙蛋 1 +x:1 +竹丝 1 +x:1 +发泡镍 1 +x:1 +通缉犯 1 +x:1 +味素 1 +x:1 +一卡通 1 +x:1 +竹乡 1 +x:1 +异乡人 1 +x:1 +工会 1 +x:1 +静候 1 +x:1 +鹰爪 1 +x:1 +删节号 1 +x:1 +之后 1 +x:1 +茂名南路 1 +x:1 +军风 1 +x:1 +兴县 1 +x:1 +桌椅 1 +x:1 +云南 1 +x:1 +快快 1 +x:1 +内外夹攻 1 +x:1 +新贵 1 +x:1 +流水不腐 1 +x:1 +揭幕战 1 +x:1 +权益日 1 +x:1 +内耳 1 +x:1 +濮阳县 1 +x:1 +标枪 1 +x:1 +凤眼莲 1 +x:1 +堆 136 +x:136 +清雅 1 +x:1 +多种多样 1 +x:1 +上代人 1 +x:1 +内胎 1 +x:1 +榴莲果 1 +x:1 +南桐 1 +x:1 +阿拉善 1 +x:1 +线形 1 +x:1 +股 538 +x:538 +葛武镇 1 +x:1 +总务科 1 +x:1 +鲁桥 1 +x:1 +味精 1 +x:1 +好逸恶劳 1 +x:1 +规避 1 +x:1 +初见端倪 1 +x:1 +意旨 1 +x:1 +长三甲 1 +x:1 +充溢 1 +x:1 +三班倒 1 +x:1 +漆树籽 1 +x:1 +俞 184 +x:184 +红外灯 1 +x:1 +开发史 1 +x:1 +内胆 1 +x:1 +仁兄 1 +x:1 +刘浩营村 1 +x:1 +犯罪人 1 +x:1 +彼得堡 1 +x:1 +争气 1 +x:1 +握手言欢 1 +x:1 +伊达尔戈 1 +x:1 +出险率 1 +x:1 +潮白河 1 +x:1 +千古罪人 1 +x:1 +标明 1 +x:1 +标高 1 +x:1 +山里娃 1 +x:1 +腠 1 +x:1 +渐入佳境 1 +x:1 +创联部 1 +x:1 +红萍 1 +x:1 +印度洋 1 +x:1 +励人 1 +x:1 +充满 1 +x:1 +每年度 1 +x:1 +佯攻 1 +x:1 +管委 1 +x:1 +乌云 1 +x:1 +佛蒙特州 1 +x:1 +智 60 +x:60 +咨询性 1 +x:1 +田独 1 +x:1 +保险商 1 +x:1 +铮铮可闻 1 +x:1 +罐顶 1 +x:1 +日本式 1 +x:1 +乌孜别克 1 +x:1 +鲜卑 1 +x:1 +槽牙 1 +x:1 +陈腐 1 +x:1 +小川町 1 +x:1 +东站 1 +x:1 +艺术观 1 +x:1 +金海湖 1 +x:1 +息鼓 1 +x:1 +称职 1 +x:1 +北大 1 +x:1 +巨帙 1 +x:1 +清除 1 +x:1 +南郭村 1 +x:1 +桌案 1 +x:1 +牛郎 1 +x:1 +开垦费 1 +x:1 +静养 1 +x:1 +北头 1 +x:1 +合议 1 +x:1 +害病 1 +x:1 +加饭酒 1 +x:1 +荒山坡 1 +x:1 +合订 1 +x:1 +东端 1 +x:1 +合计 1 +x:1 +皮猴 1 +x:1 +重阳节 1 +x:1 +反质子 1 +x:1 +兴办 1 +x:1 +淤泥 1 +x:1 +屡败屡战 1 +x:1 +尚无先例 1 +x:1 +合译 1 +x:1 +擎 17 +x:17 +平仄 1 +x:1 +两手空空 1 +x:1 +攀绕 1 +x:1 +想入非非 1 +x:1 +乌丹 1 +x:1 +则已 1 +x:1 +阴影 1 +x:1 +绝育 1 +x:1 +视为 1 +x:1 +庭院 1 +x:1 +承救 1 +x:1 +单淘汰制 1 +x:1 +该病 1 +x:1 +筒状花 1 +x:1 +跌宕 1 +x:1 +小蒋庄村 1 +x:1 +投保额 1 +x:1 +祸福相倚 1 +x:1 +麻城市 1 +x:1 +应聘者 1 +x:1 +轿 4 +x:4 +进出口额 1 +x:1 +花枝招展 1 +x:1 +郑油坊村 1 +x:1 +丰沛 1 +x:1 +穴道 1 +x:1 +杨花台村 1 +x:1 +入会者 1 +x:1 +争功诿过 1 +x:1 +示弱 1 +x:1 +阴错阳差 1 +x:1 +作战者 1 +x:1 +优质优价 1 +x:1 +划清 1 +x:1 +洪 198 +x:198 +庆春 1 +x:1 +挽词 1 +x:1 +失物 1 +x:1 +鹿厂镇 1 +x:1 +安家费 1 +x:1 +清闲 1 +x:1 +万众 1 +x:1 +逸士 1 +x:1 +狠狠 1 +x:1 +登台 1 +x:1 +万安渡 1 +x:1 +档案史 1 +x:1 +合行 1 +x:1 +团鱼 1 +x:1 +负担 1 +x:1 +地图集 1 +x:1 +巧辩 1 +x:1 +握 75 +x:75 +平地楼台 1 +x:1 +怕羞 1 +x:1 +准入 1 +x:1 +干热风 1 +x:1 +意志篇 1 +x:1 +割线 1 +x:1 +不管 1 +x:1 +兵器 1 +x:1 +产业性 1 +x:1 +狗爬犁 1 +x:1 +解答 1 +x:1 +军马 1 +x:1 +劣质品 1 +x:1 +风翔县 1 +x:1 +写明 1 +x:1 +纯情 1 +x:1 +搏 22 +x:22 +丹参素 1 +x:1 +渔都 1 +x:1 +常沅村 1 +x:1 +逗 16 +x:16 +墓葬 1 +x:1 +军旗 1 +x:1 +除害者 1 +x:1 +切诊 1 +x:1 +警世 1 +x:1 +主婚 1 +x:1 +东移 1 +x:1 +挑毛拣刺 1 +x:1 +权欲狂 1 +x:1 +妲 1 +x:1 +交通壕 1 +x:1 +增长额 1 +x:1 +败絮其中 1 +x:1 +上饶市 1 +x:1 +比热戈斯 1 +x:1 +雁翎队 1 +x:1 +虫眼 1 +x:1 +兴农 1 +x:1 +冠鸡 1 +x:1 +全能 1 +x:1 +临安段 1 +x:1 +天文钟 1 +x:1 +巧计 1 +x:1 +雷坪乡 1 +x:1 +人海战 1 +x:1 +瓦口 1 +x:1 +档案卷 1 +x:1 +底肥 1 +x:1 +泥炭土 1 +x:1 +枣藤 1 +x:1 +红螺 1 +x:1 +参与人 1 +x:1 +佛头着粪 1 +x:1 +全胜 1 +x:1 +标新 1 +x:1 +庭中 1 +x:1 +项目卡 1 +x:1 +南段 1 +x:1 +跟踪单 1 +x:1 +陋俗 1 +x:1 +登山家 1 +x:1 +奖项 1 +x:1 +四五时 1 +x:1 +香干 1 +x:1 +粘贴 1 +x:1 +兵团 1 +x:1 +入市者 1 +x:1 +老骥伏枥 1 +x:1 +空落落 1 +x:1 +碳素钢 1 +x:1 +北宋 1 +x:1 +志节 1 +x:1 +北安 1 +x:1 +主导 1 +x:1 +锦江畔 1 +x:1 +毛笋 1 +x:1 +成人式 1 +x:1 +充沛 1 +x:1 +宫腔 1 +x:1 +隙 5 +x:5 +香椿树 1 +x:1 +良有以此 1 +x:1 +跑道儿 1 +x:1 +碧云里 1 +x:1 +直系 1 +x:1 +绝色 1 +x:1 +收视率 1 +x:1 +四人帮 1 +x:1 +平平整整 1 +x:1 +绝艺 1 +x:1 +幽幽浓浓 1 +x:1 +南极虾 1 +x:1 +粤菜 1 +x:1 +丰润 1 +x:1 +混合泳 1 +x:1 +全脂 1 +x:1 +愿心 1 +x:1 +千折百回 1 +x:1 +兵圣 1 +x:1 +拜科努尔 1 +x:1 +贩毒人 1 +x:1 +陋习 1 +x:1 +伸手 1 +x:1 +委托性 1 +x:1 +肥皂粉 1 +x:1 +缥缥缈缈 1 +x:1 +万万 1 +x:1 +军魂 1 +x:1 +新平县 1 +x:1 +万一 1 +x:1 +前苏联队 1 +x:1 +遵命 1 +x:1 +太原省 1 +x:1 +弹丸之地 1 +x:1 +荔枝 1 +x:1 +毛绒 1 +x:1 +交通处 1 +x:1 +主官 1 +x:1 +乡政府 1 +x:1 +优势仗 1 +x:1 +贼心 1 +x:1 +夹生 1 +x:1 +药械 1 +x:1 +中北路 1 +x:1 +承销团 1 +x:1 +孝道 1 +x:1 +川妹 1 +x:1 +愚鲁 1 +x:1 +托运处 1 +x:1 +三军思奋 1 +x:1 +充气 1 +x:1 +仁厚 1 +x:1 +规行矩步 1 +x:1 +蕉岭县 1 +x:1 +主子 1 +x:1 +导体 1 +x:1 +隆德 1 +x:1 +主存 1 +x:1 +静卧 1 +x:1 +红蛋 1 +x:1 +鼻血 1 +x:1 +等第 1 +x:1 +目送 1 +x:1 +能征惯战 1 +x:1 +虫瘿 1 +x:1 +虎骨 1 +x:1 +航海业 1 +x:1 +西市区 1 +x:1 +举国 1 +x:1 +等等 1 +x:1 +兑换 1 +x:1 +涉案人员 1 +x:1 +埘 1 +x:1 +联络点 1 +x:1 +万事 1 +x:1 +序目 1 +x:1 +自有率 1 +x:1 +官本位 1 +x:1 +废碎料 1 +x:1 +能文能武 1 +x:1 +产量型 1 +x:1 +呈缴本 1 +x:1 +尽收眼底 1 +x:1 +兵工厂 1 +x:1 +管子 1 +x:1 +烧锅 1 +x:1 +紫云村 1 +x:1 +消防厅 1 +x:1 +班长 1 +x:1 +工程科 1 +x:1 +主峰 1 +x:1 +匪相 1 +x:1 +深思熟虑 1 +x:1 +遵化 1 +x:1 +酿造业 1 +x:1 +南浔 1 +x:1 +居安思危 1 +x:1 +测验 1 +x:1 +营销体 1 +x:1 +南浦 1 +x:1 +跌幅 1 +x:1 +苇河 1 +x:1 +取暖油 1 +x:1 +新趣 1 +x:1 +松绑 1 +x:1 +匪盗 1 +x:1 +嘬 1 +x:1 +冒名顶替 1 +x:1 +南海 1 +x:1 +布艺 1 +x:1 +北岳 1 +x:1 +堤堰 1 +x:1 +半壁店 1 +x:1 +多样化 1 +x:1 +北岸 1 +x:1 +饥不择食 1 +x:1 +冰晶石 1 +x:1 +财务 1 +x:1 +赤杨 1 +x:1 +承前启后 1 +x:1 +鉴赏家 1 +x:1 +晌 1 +x:1 +赤松 1 +x:1 +委托机 1 +x:1 +耻骨 1 +x:1 +势在必然 1 +x:1 +足协杯赛 1 +x:1 +银企 1 +x:1 +答题 1 +x:1 +茶泡饭 1 +x:1 +理论化 1 +x:1 +疟原虫 1 +x:1 +年代 1 +x:1 +练出 1 +x:1 +壳 18 +x:18 +地极 1 +x:1 +巨富 1 +x:1 +财办 1 +x:1 +一转眼 1 +x:1 +液状 1 +x:1 +财力 1 +x:1 +函授课 1 +x:1 +咀 1 +x:1 +碎岭 1 +x:1 +花花哨哨 1 +x:1 +理论史 1 +x:1 +晋城市 1 +x:1 +缘由 1 +x:1 +兴城 1 +x:1 +松江县 1 +x:1 +附赠物 1 +x:1 +月桂树 1 +x:1 +剩余 1 +x:1 +简而言之 1 +x:1 +八方支援 1 +x:1 +合理 1 +x:1 +很早以前 1 +x:1 +谷草 1 +x:1 +张格庄镇 1 +x:1 +合身 1 +x:1 +媒妁 1 +x:1 +棕熊 1 +x:1 +别家 1 +x:1 +重复话 1 +x:1 +举出 1 +x:1 +怀化市 1 +x:1 +波罗的海 1 +x:1 +飘摇 1 +x:1 +千里冰封 1 +x:1 +举凡 1 +x:1 +赤柱 1 +x:1 +南涧 1 +x:1 +谒祖 1 +x:1 +静听 1 +x:1 +巨子 1 +x:1 +卫护 1 +x:1 +绘艺 1 +x:1 +酸扒菜 1 +x:1 +主将 1 +x:1 +岭峻石险 1 +x:1 +恐龙节 1 +x:1 +枕套 1 +x:1 +练兵 1 +x:1 +嫖妓式 1 +x:1 +南汇 1 +x:1 +举债 1 +x:1 +绚丽夺目 1 +x:1 +绵亘 1 +x:1 +文从字顺 1 +x:1 +浮动性 1 +x:1 +球赛 1 +x:1 +法律学系 1 +x:1 +直立 1 +x:1 +南江 1 +x:1 +搅 23 +x:23 +谋职 1 +x:1 +儿戏 1 +x:1 +湛河区 1 +x:1 +垫脚石 1 +x:1 +预展 1 +x:1 +举借 1 +x:1 +租价 1 +x:1 +大成者 1 +x:1 +大同小异 1 +x:1 +火力发电 1 +x:1 +谷苗 1 +x:1 +兑换券 1 +x:1 +布局谋篇 1 +x:1 +在乎 1 +x:1 +星期四 1 +x:1 +开发型 1 +x:1 +费解 1 +x:1 +盘根究底 1 +x:1 +实则 1 +x:1 +洛渍岔 1 +x:1 +管工 1 +x:1 +灾难 1 +x:1 +道德乡 1 +x:1 +祈 5 +x:5 +灶王爷 1 +x:1 +银丰 1 +x:1 +五角场 1 +x:1 +壅水 1 +x:1 +矿车 1 +x:1 +嚎 1 +x:1 +花鸟画 1 +x:1 +工程署 1 +x:1 +保证期 1 +x:1 +在业 1 +x:1 +药检所 1 +x:1 +溜须拍马 1 +x:1 +毫不动摇 1 +x:1 +在世 1 +x:1 +可 4369 +x:4369 +城隍庙 1 +x:1 +实利 1 +x:1 +战争史 1 +x:1 +曲线美 1 +x:1 +纯朴 1 +x:1 +在任 1 +x:1 +随处 1 +x:1 +称著 1 +x:1 +写意 1 +x:1 +挺拔高古 1 +x:1 +振作 1 +x:1 +爽口 1 +x:1 +腿带 1 +x:1 +东经 1 +x:1 +纯种马 1 +x:1 +铁军 1 +x:1 +京粤 1 +x:1 +兴国 1 +x:1 +球路 1 +x:1 +扫雷艇 1 +x:1 +镇赉县 1 +x:1 +药栓 1 +x:1 +拘传 1 +x:1 +蹒跚 1 +x:1 +半壁 1 +x:1 +屈曲位 1 +x:1 +守护者 1 +x:1 +唐庄 1 +x:1 +扑将 1 +x:1 +暗疾 1 +x:1 +实力 1 +x:1 +蛇酒 1 +x:1 +通风报信 1 +x:1 +巨婴 1 +x:1 +慵懒 1 +x:1 +白蜡树 1 +x:1 +俱乐部队 1 +x:1 +域名 1 +x:1 +天崩地裂 1 +x:1 +国防部长 1 +x:1 +终吹点 1 +x:1 +红肿 1 +x:1 +资本主义 1 +x:1 +革大 1 +x:1 +五重奏 1 +x:1 +苇海 1 +x:1 +舌面后音 1 +x:1 +大 14538 +x:14538 +东线 1 +x:1 +实劲 1 +x:1 +负数 1 +x:1 +参演者 1 +x:1 +尽心尽意 1 +x:1 +编年体 1 +x:1 +在于 1 +x:1 +悬梯 1 +x:1 +实务 1 +x:1 +务虚 1 +x:1 +寝不安席 1 +x:1 +虫灾 1 +x:1 +南油 1 +x:1 +倒计时钟 1 +x:1 +拼音 1 +x:1 +陷没 1 +x:1 +上供 1 +x:1 +红药 1 +x:1 +脂肪型 1 +x:1 +合谋 1 +x:1 +和平门 1 +x:1 +海王星 1 +x:1 +寄件人 1 +x:1 +修士 1 +x:1 +焚 12 +x:12 +兵刃 1 +x:1 +坐具 1 +x:1 +交通局 1 +x:1 +碱石 1 +x:1 +静园 1 +x:1 +管庄 1 +x:1 +斜角 1 +x:1 +阿弥陀佛 1 +x:1 +军鸽 1 +x:1 +可塑性 1 +x:1 +你死我活 1 +x:1 +逆产 1 +x:1 +保险刀 1 +x:1 +移动式 1 +x:1 +香港仔 1 +x:1 +等级 1 +x:1 +蜡像馆 1 +x:1 +领导层 1 +x:1 +预提 1 +x:1 +雍正 1 +x:1 +登基 1 +x:1 +清醇 1 +x:1 +专储 1 +x:1 +有理函数 1 +x:1 +光前裕后 1 +x:1 +俑 2 +x:2 +声浪 1 +x:1 +红茶 1 +x:1 +浙沪 1 +x:1 +桔 3 +x:3 +不成方圆 1 +x:1 +考察队 1 +x:1 +清醒 1 +x:1 +香嫩 1 +x:1 +一落千丈 1 +x:1 +枝叶 1 +x:1 +肝硬变 1 +x:1 +皮瓣 1 +x:1 +锅炉房 1 +x:1 +吉伦特省 1 +x:1 +廷杖 1 +x:1 +闪电河乡 1 +x:1 +南漳 1 +x:1 +秦腔戏 1 +x:1 +这儿 1 +x:1 +灵石县 1 +x:1 +承担 1 +x:1 +邀请赛 1 +x:1 +启示性 1 +x:1 +筹备处 1 +x:1 +今古奇闻 1 +x:1 +旁观者 1 +x:1 +失盗 1 +x:1 +登场 1 +x:1 +狂奔 1 +x:1 +皮球 1 +x:1 +人来疯 1 +x:1 +核试区 1 +x:1 +清澈见底 1 +x:1 +草台班子 1 +x:1 +课目 1 +x:1 +煞有介事 1 +x:1 +紫红色 1 +x:1 +无外贸 1 +x:1 +巨大 1 +x:1 +伊斯兰 1 +x:1 +骤增 1 +x:1 +海和会 1 +x:1 +艰深 1 +x:1 +肝硬化 1 +x:1 +季风 1 +x:1 +谧 1 +x:1 +等离子体 1 +x:1 +平均值 1 +x:1 +称羡 1 +x:1 +芽眼 1 +x:1 +双鸭山市 1 +x:1 +墙头 1 +x:1 +球瘾 1 +x:1 +蒙古族 1 +x:1 +剃 6 +x:6 +痂 1 +x:1 +历史剧 1 +x:1 +斯文 1 +x:1 +细则 1 +x:1 +疲态 1 +x:1 +上体 1 +x:1 +设备室 1 +x:1 +上位 1 +x:1 +奋翅展翼 1 +x:1 +工程系 1 +x:1 +暗盒 1 +x:1 +细分 1 +x:1 +烧造 1 +x:1 +势不可挡 1 +x:1 +板桥村 1 +x:1 +主席 1 +x:1 +扣 161 +x:161 +菌丝 1 +x:1 +圣洁感 1 +x:1 +侦查员制 1 +x:1 +阜新 1 +x:1 +承托 1 +x:1 +贵专栏 1 +x:1 +中常委 1 +x:1 +阜成门 1 +x:1 +巨奖 1 +x:1 +实况 1 +x:1 +上佳 1 +x:1 +污蔑 1 +x:1 +高新产业 1 +x:1 +北平 1 +x:1 +垃圾道 1 +x:1 +交通岗 1 +x:1 +交通岛 1 +x:1 +细别 1 +x:1 +贲门 1 +x:1 +合阳县 1 +x:1 +春风顺意 1 +x:1 +细发 1 +x:1 +耶稣 1 +x:1 +研究生会 1 +x:1 +鄄 1 +x:1 +琉璃球 1 +x:1 +底蕴 1 +x:1 +乘骑者 1 +x:1 +南湖 1 +x:1 +练功 1 +x:1 +才华横溢 1 +x:1 +红色 1 +x:1 +红艳 1 +x:1 +渗出性 1 +x:1 +承接 1 +x:1 +纵贪张奢 1 +x:1 +台风 1 +x:1 +负极 1 +x:1 +有险必抢 1 +x:1 +冰雪界 1 +x:1 +战时 1 +x:1 +巨增 1 +x:1 +河川 1 +x:1 +上人 1 +x:1 +监察局 1 +x:1 +示威 1 +x:1 +主心 1 +x:1 +皮疹 1 +x:1 +上交 1 +x:1 +南湾 1 +x:1 +石炼化 1 +x:1 +鸡丝 1 +x:1 +隆中 1 +x:1 +紫胶 1 +x:1 +徘徊 1 +x:1 +着 10092 +x:10092 +承揽 1 +x:1 +唐山 1 +x:1 +殷 76 +x:76 +理论值 1 +x:1 +墙壁 1 +x:1 +泛亚 1 +x:1 +线头 1 +x:1 +失真 1 +x:1 +兵卒 1 +x:1 +资助款 1 +x:1 +总方针 1 +x:1 +保险卡 1 +x:1 +碎影 1 +x:1 +战斗 1 +x:1 +三·一五 1 +x:1 +退伍费 1 +x:1 +合资 1 +x:1 +指导员 1 +x:1 +日记簿 1 +x:1 +烛花 1 +x:1 +了却 1 +x:1 +上任 1 +x:1 +垃圾量 1 +x:1 +保险单 1 +x:1 +子房山 1 +x:1 +失眠 1 +x:1 +媒婆 1 +x:1 +无保证 1 +x:1 +财金队 1 +x:1 +竞标路 1 +x:1 +上代 1 +x:1 +和蔼可亲 1 +x:1 +朋 8 +x:8 +心悦诚服 1 +x:1 +举动 1 +x:1 +长命富贵 1 +x:1 +负有 1 +x:1 +军龄 1 +x:1 +隆安 1 +x:1 +耽误 1 +x:1 +上万 1 +x:1 +尝 122 +x:122 +罄 2 +x:2 +顶门儿 1 +x:1 +烧酒 1 +x:1 +举办 1 +x:1 +返青肥 1 +x:1 +裁判官 1 +x:1 +谈心会 1 +x:1 +百事待兴 1 +x:1 +儿歌 1 +x:1 +间歇性 1 +x:1 +百育乡 1 +x:1 +氽 1 +x:1 +打乱 1 +x:1 +锯机 1 +x:1 +保健法 1 +x:1 +月份牌 1 +x:1 +搞关系 1 +x:1 +上乘 1 +x:1 +兵变 1 +x:1 +细化 1 +x:1 +扣人心弦 1 +x:1 +扎沙村 1 +x:1 +清退 1 +x:1 +保险号 1 +x:1 +主张 1 +x:1 +红花 1 +x:1 +设计组 1 +x:1 +底薪 1 +x:1 +虫牙 1 +x:1 +打铁 1 +x:1 +进气道 1 +x:1 +岩层 1 +x:1 +金丝小枣 1 +x:1 +得分制 1 +x:1 +现况 1 +x:1 +琉璃瓦 1 +x:1 +桔树 1 +x:1 +草头儿 1 +x:1 +卫理公会 1 +x:1 +北影 1 +x:1 +以文会友 1 +x:1 +永发村 1 +x:1 +上书 1 +x:1 +跑操 1 +x:1 +阎罗王 1 +x:1 +平安无事 1 +x:1 +传经送宝 1 +x:1 +抗滑桩 1 +x:1 +实录 1 +x:1 +数学课 1 +x:1 +蝮蛇 1 +x:1 +耐 65 +x:65 +初出茅庐 1 +x:1 +行政村 1 +x:1 +枕 5 +x:5 +湖州市 1 +x:1 +大行其道 1 +x:1 +定边县 1 +x:1 +广播体操 1 +x:1 +欢 24 +x:24 +述说 1 +x:1 +多样式 1 +x:1 +墙垣 1 +x:1 +建平县 1 +x:1 +标本馆 1 +x:1 +吟颂 1 +x:1 +巨型 1 +x:1 +审编 1 +x:1 +兴学 1 +x:1 +不请自到 1 +x:1 +团队 1 +x:1 +罐里 1 +x:1 +鲜嫩 1 +x:1 +红货 1 +x:1 +中国化 1 +x:1 +邛崃市 1 +x:1 +了局 1 +x:1 +阅兵 1 +x:1 +国将不国 1 +x:1 +跑步 1 +x:1 +奖 464 +x:464 +招商团 1 +x:1 +写法 1 +x:1 +监测制 1 +x:1 +非营利性 1 +x:1 +实弹 1 +x:1 +桔果 1 +x:1 +暖气团 1 +x:1 +微俯 1 +x:1 +早 1098 +x:1098 +西约克郡 1 +x:1 +崇洋媚外 1 +x:1 +裁判员 1 +x:1 +侵侮 1 +x:1 +植入数 1 +x:1 +眼眸 1 +x:1 +日本国 1 +x:1 +保险局 1 +x:1 +身临其境 1 +x:1 +私房话 1 +x:1 +生活会 1 +x:1 +革命 1 +x:1 +什 1 +x:1 +匪穴 1 +x:1 +代收代缴 1 +x:1 +唐县 1 +x:1 +空舍清野 1 +x:1 +财年 1 +x:1 +五十九中 1 +x:1 +富丽堂皇 1 +x:1 +田笋 1 +x:1 +实心 1 +x:1 +德语区 1 +x:1 +喝茶 1 +x:1 +巴山蜀水 1 +x:1 +悼辞 1 +x:1 +哼哈二将 1 +x:1 +窑址 1 +x:1 +饿殍遍野 1 +x:1 +台面 1 +x:1 +捐弃前嫌 1 +x:1 +遵循 1 +x:1 +不管部 1 +x:1 +※ 6 +x:6 +军邮 1 +x:1 +住户 1 +x:1 +青壮年 1 +x:1 +读音 1 +x:1 +向阳 1 +x:1 +兴宝 1 +x:1 +大田庄乡 1 +x:1 +镉 4 +x:4 +域外 1 +x:1 +反目 1 +x:1 +毛巾厂 1 +x:1 +争斗 1 +x:1 +烧鸡 1 +x:1 +兴安 1 +x:1 +跌势 1 +x:1 +安魂曲 1 +x:1 +细小 1 +x:1 +令 1329 +x:1329 +手压井 1 +x:1 +支部 1 +x:1 +岳家 1 +x:1 +破击战 1 +x:1 +氯碱厂 1 +x:1 +斟茶 1 +x:1 +扑克 1 +x:1 +军部 1 +x:1 +富水街村 1 +x:1 +财帛 1 +x:1 +宴会 1 +x:1 +丰林 1 +x:1 +暗礁 1 +x:1 +儿时 1 +x:1 +高耸入云 1 +x:1 +自珍 1 +x:1 +能力型 1 +x:1 +纤毛虫 1 +x:1 +振奋感 1 +x:1 +晴到多云 1 +x:1 +答问 1 +x:1 +途中 1 +x:1 +田赋 1 +x:1 +双唇音 1 +x:1 +胜利果实 1 +x:1 +陈规 1 +x:1 +蓄势期 1 +x:1 +桉油 1 +x:1 +红豆 1 +x:1 +准绳 1 +x:1 +反省 1 +x:1 +类固醇 1 +x:1 +微亮 1 +x:1 +皮管 1 +x:1 +实干 1 +x:1 +纯正 1 +x:1 +滑轮车 1 +x:1 +互通 1 +x:1 +唐初 1 +x:1 +长胜村 1 +x:1 +水上居民 1 +x:1 +叱咤 1 +x:1 +快嘴 1 +x:1 +印度教 1 +x:1 +皮箱 1 +x:1 +摇摇欲坠 1 +x:1 +暗示 1 +x:1 +杠杠 1 +x:1 +学画 1 +x:1 +末了 1 +x:1 +矿物油 1 +x:1 +回应 1 +x:1 +独占鳌头 1 +x:1 +保健所 1 +x:1 +鱼腥草 1 +x:1 +逸史 1 +x:1 +重机关枪 1 +x:1 +棒棰柳 1 +x:1 +购买者 1 +x:1 +杠杆 1 +x:1 +侵人 1 +x:1 +春夏秋冬 1 +x:1 +后勤处 1 +x:1 +准线 1 +x:1 +夹缝 1 +x:1 +线圈 1 +x:1 +攀登 1 +x:1 +乌龙茶 1 +x:1 +骂 78 +x:78 +迪瓦市 1 +x:1 +一抓到底 1 +x:1 +愿者上钩 1 +x:1 +佳利宝 1 +x:1 +地板 1 +x:1 +害臊 1 +x:1 +企业型 1 +x:1 +跃变层 1 +x:1 +混为一谈 1 +x:1 +爽快 1 +x:1 +主公 1 +x:1 +直白 1 +x:1 +严 325 +x:325 +肥滚滚 1 +x:1 +档案堆 1 +x:1 +泰和县 1 +x:1 +拨弦 1 +x:1 +种苗 1 +x:1 +小康县 1 +x:1 +镇定自若 1 +x:1 +脉息 1 +x:1 +练就 1 +x:1 +招牌 1 +x:1 +无锡市 1 +x:1 +宝莲灯 1 +x:1 +人均收入 1 +x:1 +憋足劲 1 +x:1 +主儿 1 +x:1 +一般见识 1 +x:1 +失禁 1 +x:1 +平顺县 1 +x:1 +团音 1 +x:1 +和风桥 1 +x:1 +煎 16 +x:16 +竞争力 1 +x:1 +交通厅 1 +x:1 +全诗 1 +x:1 +兵差 1 +x:1 +北关 1 +x:1 +兵工 1 +x:1 +反驳者 1 +x:1 +虎林 1 +x:1 +堪言 1 +x:1 +连日 1 +x:1 +大行政区 1 +x:1 +档案室 1 +x:1 +鲍峡镇 1 +x:1 +波导管 1 +x:1 +薛庄村 1 +x:1 +磁场强度 1 +x:1 +兴奋 1 +x:1 +争权 1 +x:1 +学生 1 +x:1 +线呢 1 +x:1 +评测 1 +x:1 +零打碎敲 1 +x:1 +白血球 1 +x:1 +北务 1 +x:1 +群星璀璨 1 +x:1 +充斥 1 +x:1 +棕编 1 +x:1 +球艺 1 +x:1 +运营 1 +x:1 +革囊 1 +x:1 +助学班 1 +x:1 +台门 1 +x:1 +权威性 1 +x:1 +定日县 1 +x:1 +黑石礁 1 +x:1 +价值量 1 +x:1 +同一性 1 +x:1 +血清病 1 +x:1 +收费员 1 +x:1 +灌注桩 1 +x:1 +活灵活现 1 +x:1 +委中 1 +x:1 +瑞万多 1 +x:1 +不可一世 1 +x:1 +主动 1 +x:1 +拨开 1 +x:1 +毡 2 +x:2 +急流勇退 1 +x:1 +方巾气 1 +x:1 +称许 1 +x:1 +主办 1 +x:1 +红萝卜 1 +x:1 +置 81 +x:81 +褊狭 1 +x:1 +课程 1 +x:1 +跌倒 1 +x:1 +卷轴装 1 +x:1 +课税 1 +x:1 +见利忘义 1 +x:1 +布谷 1 +x:1 +金文辞 1 +x:1 +周率 1 +x:1 +词作家 1 +x:1 +委任 1 +x:1 +纯棉 1 +x:1 +嘱咐 1 +x:1 +矿用 1 +x:1 +氏 7 +x:7 +新市区 1 +x:1 +赈济金 1 +x:1 +竞标者 1 +x:1 +送 1799 +x:1799 +逃税者 1 +x:1 +长袖善舞 1 +x:1 +管制 1 +x:1 +料豆儿 1 +x:1 +卫队 1 +x:1 +读报会 1 +x:1 +鼻腔 1 +x:1 +宏病毒 1 +x:1 +台长 1 +x:1 +冲 278 +x:278 +红运 1 +x:1 +黄鼠狼 1 +x:1 +合肥 1 +x:1 +魁 2 +x:2 +益 27 +x:27 +档案学 1 +x:1 +尼加拉瓜 1 +x:1 +钡餐 1 +x:1 +著作权 1 +x:1 +隆回 1 +x:1 +篆刻 1 +x:1 +所谓 1 +x:1 +失窃 1 +x:1 +懒 23 +x:23 +带兵官 1 +x:1 +陈言 1 +x:1 +放小 1 +x:1 +甬剧 1 +x:1 +团省委 1 +x:1 +国棉厂 1 +x:1 +煽惑 1 +x:1 +电信网 1 +x:1 +过街天桥 1 +x:1 +磬 3 +x:3 +赛马会 1 +x:1 +煽情 1 +x:1 +女高音 1 +x:1 +肌纤维 1 +x:1 +主刊 1 +x:1 +球花 1 +x:1 +巨商 1 +x:1 +充数 1 +x:1 +封山育林 1 +x:1 +合脚 1 +x:1 +免交 1 +x:1 +北厅 1 +x:1 +跌入 1 +x:1 +窝赃 1 +x:1 +实属 1 +x:1 +失策 1 +x:1 +静寂 1 +x:1 +住宿费 1 +x:1 +耶里镇 1 +x:1 +抑 5 +x:5 +细心 1 +x:1 +暗笑 1 +x:1 +芜菁 1 +x:1 +主叫 1 +x:1 +平喘药 1 +x:1 +求实 1 +x:1 +小戏 1 +x:1 +鼋鱼 1 +x:1 +布赫 1 +x:1 +侣 1 +x:1 +硝石 1 +x:1 +踢法 1 +x:1 +投井下石 1 +x:1 +巴青 1 +x:1 +免于 1 +x:1 +免予 1 +x:1 +陈说 1 +x:1 +习字帖 1 +x:1 +动脉瘤 1 +x:1 +矿脉 1 +x:1 +新军 1 +x:1 +矿脂 1 +x:1 +红领章 1 +x:1 +球茎 1 +x:1 +大度包容 1 +x:1 +东瀛 1 +x:1 +忧虑线 1 +x:1 +捐 227 +x:227 +映射 1 +x:1 +护城河 1 +x:1 +议政者 1 +x:1 +鲜妍 1 +x:1 +本命年 1 +x:1 +连杆 1 +x:1 +伯乐相马 1 +x:1 +汉诺威 1 +x:1 +勒石记痛 1 +x:1 +布质 1 +x:1 +陈设 1 +x:1 +残酷性 1 +x:1 +仁学 1 +x:1 +总的说 1 +x:1 +苍梧县 1 +x:1 +未老先衰 1 +x:1 +胸牌 1 +x:1 +基业 1 +x:1 +巨响 1 +x:1 +邢台 1 +x:1 +几何学 1 +x:1 +能 9038 +x:9038 +拳打脚踢 1 +x:1 +细微 1 +x:1 +布贴 1 +x:1 +宫观 1 +x:1 +龙形 1 +x:1 +匪祸 1 +x:1 +聘任期 1 +x:1 +了得 1 +x:1 +练市 1 +x:1 +钊 13 +x:13 +暗算 1 +x:1 +黔江县 1 +x:1 +执行长 1 +x:1 +逐人逐户 1 +x:1 +云龙风虎 1 +x:1 +管区 1 +x:1 +美丽岛 1 +x:1 +棕红 1 +x:1 +鲜奶 1 +x:1 +污血 1 +x:1 +丰收 1 +x:1 +光声控 1 +x:1 +访贫问苦 1 +x:1 +濑户内海 1 +x:1 +暗箭 1 +x:1 +砭 1 +x:1 +底角 1 +x:1 +桑榆景 1 +x:1 +军法系 1 +x:1 +暗箱 1 +x:1 +广众益 1 +x:1 +陈集乡 1 +x:1 +北区 1 +x:1 +标注 1 +x:1 +布隆迪 1 +x:1 +文弱书生 1 +x:1 +失算 1 +x:1 +高纬度 1 +x:1 +棕绷 1 +x:1 +松蓝 1 +x:1 +棕绳 1 +x:1 +无形化 1 +x:1 +蓝湿皮 1 +x:1 +交会点 1 +x:1 +忘 346 +x:346 +细胞系 1 +x:1 +小广播 1 +x:1 +细弱 1 +x:1 +基于 1 +x:1 +白血病 1 +x:1 +切花 1 +x:1 +枝干 1 +x:1 +破破烂烂 1 +x:1 +学界 1 +x:1 +祖鲁王国 1 +x:1 +阜城县 1 +x:1 +增收节支 1 +x:1 +濠江 1 +x:1 +仁寿 1 +x:1 +实存 1 +x:1 +血缘型 1 +x:1 +牙白口清 1 +x:1 +监测器 1 +x:1 +腐败论 1 +x:1 +恰穆拉 1 +x:1 +硝烟 1 +x:1 +举头 1 +x:1 +实字 1 +x:1 +紫菀 1 +x:1 +彩票潮 1 +x:1 +事件 1 +x:1 +洗心革面 1 +x:1 +污迹 1 +x:1 +地税所 1 +x:1 +巨厦 1 +x:1 +功 133 +x:133 +大中院校 1 +x:1 +遵奉 1 +x:1 +桌旁 1 +x:1 +后勤局 1 +x:1 +夹板气 1 +x:1 +皮纸 1 +x:1 +非武装 1 +x:1 +熔融 1 +x:1 +艳情 1 +x:1 +累计数 1 +x:1 +大惊小怪 1 +x:1 +磁导率 1 +x:1 +消防局 1 +x:1 +抿 3 +x:3 +赤潮 1 +x:1 +枉渚 1 +x:1 +雇 34 +x:34 +花样游泳 1 +x:1 +污辱 1 +x:1 +扑嗤 1 +x:1 +溺爱 1 +x:1 +直率 1 +x:1 +设计界 1 +x:1 +巨变 1 +x:1 +泻湖 1 +x:1 +填埋场 1 +x:1 +事事 1 +x:1 +荷花嘴乡 1 +x:1 +虎门 1 +x:1 +面无血色 1 +x:1 +纤维素 1 +x:1 +巨匾 1 +x:1 +柯西金街 1 +x:1 +半路出家 1 +x:1 +负气 1 +x:1 +称赞 1 +x:1 +好消息 1 +x:1 +遵守 1 +x:1 +开发带 1 +x:1 +叙事文 1 +x:1 +巨匠 1 +x:1 +允当寨 1 +x:1 +普天间 1 +x:1 +交通图 1 +x:1 +一拍即合 1 +x:1 +刀光血影 1 +x:1 +辞职书 1 +x:1 +河汊子 1 +x:1 +答道 1 +x:1 +晕倒 1 +x:1 +由 7542 +x:7542 +合同号 1 +x:1 +白斑病 1 +x:1 +龙岗 1 +x:1 +红角 1 +x:1 +金银制 1 +x:1 +意犹未尽 1 +x:1 +南旺 1 +x:1 +海内外 1 +x:1 +初级线圈 1 +x:1 +长城站 1 +x:1 +北仑区 1 +x:1 +获奖榜 1 +x:1 +招投标 1 +x:1 +理论家 1 +x:1 +快反 1 +x:1 +染桶 1 +x:1 +痛苦状 1 +x:1 +高六房 1 +x:1 +避孕药 1 +x:1 +事主 1 +x:1 +有情者 1 +x:1 +能掐会算 1 +x:1 +改行 1 +x:1 +标段 1 +x:1 +武侯墓 1 +x:1 +宋江起义 1 +x:1 +驿道 1 +x:1 +荔树 1 +x:1 +竞争型 1 +x:1 +拍手称快 1 +x:1 +兵士 1 +x:1 +事业 1 +x:1 +悼词 1 +x:1 +朝觐部 1 +x:1 +这家 1 +x:1 +韩岗镇 1 +x:1 +旗袍裙 1 +x:1 +快刀 1 +x:1 +阴魂 1 +x:1 +红衣 1 +x:1 +后脑勺 1 +x:1 +登岸 1 +x:1 +排队机 1 +x:1 +昂首阔步 1 +x:1 +清高 1 +x:1 +托老所 1 +x:1 +礁盘 1 +x:1 +四座宾朋 1 +x:1 +辞职信 1 +x:1 +石英沙 1 +x:1 +月明风清 1 +x:1 +到 18289 +x:18289 +财富 1 +x:1 +民族之林 1 +x:1 +奋勇当先 1 +x:1 +田二河镇 1 +x:1 +读者群 1 +x:1 +保险处 1 +x:1 +脚踝部 1 +x:1 +相形 1 +x:1 +方形 1 +x:1 +凡是 1 +x:1 +签字笔 1 +x:1 +菏泽 1 +x:1 +潆洄 1 +x:1 +扑哧 1 +x:1 +郎才女貌 1 +x:1 +系统化 1 +x:1 +养蜂人 1 +x:1 +鉴赏力 1 +x:1 +别动队 1 +x:1 +事例 1 +x:1 +军长 1 +x:1 +秋种 1 +x:1 +收费卡 1 +x:1 +一年到头 1 +x:1 +栽花养草 1 +x:1 +田夫野老 1 +x:1 +财宝 1 +x:1 +练声 1 +x:1 +中碳钢 1 +x:1 +砂轮机 1 +x:1 +小康型 1 +x:1 +滚珠轴承 1 +x:1 +桉树 1 +x:1 +东盟 1 +x:1 +巨制 1 +x:1 +东盛 1 +x:1 +无的放矢 1 +x:1 +梭子 1 +x:1 +收费厅 1 +x:1 +新闻业 1 +x:1 +窗膜 1 +x:1 +鼓楼苑 1 +x:1 +傅村镇 1 +x:1 +转化法 1 +x:1 +红装 1 +x:1 +搅拌器 1 +x:1 +兴建 1 +x:1 +联络组 1 +x:1 +智慧型 1 +x:1 +推本溯源 1 +x:1 +宫廷戏 1 +x:1 +事体 1 +x:1 +檀皮纸 1 +x:1 +登封 1 +x:1 +爵 2 +x:2 +现浇板 1 +x:1 +隆冬 1 +x:1 +开发式 1 +x:1 +养蜂业 1 +x:1 +称谓 1 +x:1 +登山 1 +x:1 +底边 1 +x:1 +均 1387 +x:1387 +细处 1 +x:1 +脉搏 1 +x:1 +索款 1 +x:1 +虎钳 1 +x:1 +仁川 1 +x:1 +档案局 1 +x:1 +欧行 1 +x:1 +全连 1 +x:1 +红袍 1 +x:1 +族际 1 +x:1 +烈士陵园 1 +x:1 +常识性 1 +x:1 +称谢 1 +x:1 +痰 21 +x:21 +红袖 1 +x:1 +布设 1 +x:1 +殡敛 1 +x:1 +本小利大 1 +x:1 +执行部 1 +x:1 +刑事罪 1 +x:1 +仁布 1 +x:1 +福尔马林 1 +x:1 +布行 1 +x:1 +连成 1 +x:1 +南李 1 +x:1 +桐竹 1 +x:1 +军队 1 +x:1 +护壁桩 1 +x:1 +鲁村 1 +x:1 +赞誉 1 +x:1 +军阀 1 +x:1 +鸡西市 1 +x:1 +南村 1 +x:1 +皮货 1 +x:1 +模范 1 +x:1 +军阶 1 +x:1 +军阵 1 +x:1 +天文馆 1 +x:1 +布衣 1 +x:1 +抬头纹 1 +x:1 +贸易局 1 +x:1 +害虫 1 +x:1 +值班长 1 +x:1 +萨吉诺镇 1 +x:1 +细嫩 1 +x:1 +乡土味 1 +x:1 +合营 1 +x:1 +宫调 1 +x:1 +征答 1 +x:1 +学监 1 +x:1 +底谷 1 +x:1 +班风 1 +x:1 +维琴查队 1 +x:1 +合著 1 +x:1 +批评话 1 +x:1 +清香 1 +x:1 +国民性 1 +x:1 +争持 1 +x:1 +南朝 1 +x:1 +实处 1 +x:1 +不可偏废 1 +x:1 +卞 33 +x:33 +这天 1 +x:1 +清馨 1 +x:1 +富饶 1 +x:1 +恐龙 1 +x:1 +合葬 1 +x:1 +里氏 1 +x:1 +诹 1 +x:1 +北图 1 +x:1 +北国 1 +x:1 +纯水 1 +x:1 +镜花岭 1 +x:1 +岳州 1 +x:1 +康拜因 1 +x:1 +枉法 1 +x:1 +举家 1 +x:1 +墓表 1 +x:1 +窘 1 +x:1 +读卡器 1 +x:1 +角质率 1 +x:1 +赵杏村 1 +x:1 +暗红 1 +x:1 +萧 90 +x:90 +跟踪式 1 +x:1 +绝迹 1 +x:1 +鲤 1 +x:1 +形式参数 1 +x:1 +窗花 1 +x:1 +荒山野岭 1 +x:1 +计会科 1 +x:1 +大南沟 1 +x:1 +兴工 1 +x:1 +绊脚石 1 +x:1 +布袋 1 +x:1 +枝子 1 +x:1 +单倍体 1 +x:1 +中子弹 1 +x:1 +标榜 1 +x:1 +团部 1 +x:1 +衍文 1 +x:1 +一展风采 1 +x:1 +长蛇阵 1 +x:1 +南枝 1 +x:1 +练字 1 +x:1 +商贸部 1 +x:1 +爷爷 1 +x:1 +舍身为国 1 +x:1 +割爱 1 +x:1 +登录 1 +x:1 +精华游 1 +x:1 +自 1988 +x:1988 +开发局 1 +x:1 +半年 1 +x:1 +世代相传 1 +x:1 +设备厂 1 +x:1 +失约 1 +x:1 +暗绿 1 +x:1 +松球 1 +x:1 +退烧针 1 +x:1 +远近闻名 1 +x:1 +清风 1 +x:1 +撞伤 1 +x:1 +静心 1 +x:1 +成人化 1 +x:1 +蒙马特 1 +x:1 +天荒坪 1 +x:1 +书香门第 1 +x:1 +衽衩口 1 +x:1 +细密 1 +x:1 +赤水 1 +x:1 +仕和集 1 +x:1 +恒丰裕行 1 +x:1 +仁弟 1 +x:1 +项目库 1 +x:1 +赞许 1 +x:1 +蛀心虫 1 +x:1 +闹事 1 +x:1 +陈迹 1 +x:1 +入会费 1 +x:1 +糖瓜 1 +x:1 +陈述 1 +x:1 +愧疚 1 +x:1 +兴山 1 +x:1 +财委 1 +x:1 +而且 1 +x:1 +档案库 1 +x:1 +四人制 1 +x:1 +私语 1 +x:1 +财文字 1 +x:1 +包打天下 1 +x:1 +收益率 1 +x:1 +标桩 1 +x:1 +堤坝路 1 +x:1 +汇聚一堂 1 +x:1 +鲁昂 1 +x:1 +平潭岛 1 +x:1 +收缴率 1 +x:1 +南明 1 +x:1 +南昌 1 +x:1 +纯洁 1 +x:1 +砍伐一空 1 +x:1 +底质 1 +x:1 +隆升 1 +x:1 +底账 1 +x:1 +装神弄鬼 1 +x:1 +工程界 1 +x:1 +参展 1 +x:1 +标格 1 +x:1 +烧香 1 +x:1 +管城 1 +x:1 +赞语 1 +x:1 +蓬户瓮牖 1 +x:1 +称身 1 +x:1 +兵学 1 +x:1 +嚎啕 1 +x:1 +全资 1 +x:1 +碎块 1 +x:1 +普法办 1 +x:1 +山和尚 1 +x:1 +妄 7 +x:7 +良莠不齐 1 +x:1 +烧饼 1 +x:1 +鞋拔子 1 +x:1 +风采录 1 +x:1 +下龙湾 1 +x:1 +不言自明 1 +x:1 +吝 1 +x:1 +平方厘米 1 +x:1 +欺人之谈 1 +x:1 +兵家 1 +x:1 +出粪口 1 +x:1 +主坝 1 +x:1 +参考值 1 +x:1 +语词 1 +x:1 +仁德 1 +x:1 +黑龙江队 1 +x:1 +谐美 1 +x:1 +连接 1 +x:1 +准确 1 +x:1 +财大 1 +x:1 +历史学 1 +x:1 +流动形 1 +x:1 +照排机 1 +x:1 +麦子港 1 +x:1 +启动力 1 +x:1 +全路 1 +x:1 +联筹会 1 +x:1 +种菜 1 +x:1 +保健操 1 +x:1 +尼罗河 1 +x:1 +黑热病 1 +x:1 +仁忠 1 +x:1 +葡萄 1 +x:1 +北坡 1 +x:1 +团里 1 +x:1 +而今 1 +x:1 +矿藏 1 +x:1 +用助剂 1 +x:1 +屈尊纡贵 1 +x:1 +生物防治 1 +x:1 +起 5812 +x:5812 +巴尔的摩 1 +x:1 +争抢 1 +x:1 +仁怀 1 +x:1 +挂 409 +x:409 +兰考县 1 +x:1 +成人气 1 +x:1 +造表 1 +x:1 +北盘江 1 +x:1 +免疫 1 +x:1 +借助于 1 +x:1 +蛙池子 1 +x:1 +徕 1 +x:1 +勃郎宁 1 +x:1 +实权 1 +x:1 +瑞金县 1 +x:1 +有声片 1 +x:1 +职业中学 1 +x:1 +造血 1 +x:1 +泛称 1 +x:1 +紫貂皮 1 +x:1 +叶片 1 +x:1 +香油 1 +x:1 +建教字 1 +x:1 +试探性 1 +x:1 +两专一基 1 +x:1 +磅礴 1 +x:1 +委托单 1 +x:1 +大莫古乡 1 +x:1 +免疫学 1 +x:1 +尽人皆知 1 +x:1 +玩花招 1 +x:1 +高度层 1 +x:1 +实有 1 +x:1 +烟尘 1 +x:1 +苗 126 +x:126 +中承拱 1 +x:1 +荆江 1 +x:1 +笛音 1 +x:1 +金银滩 1 +x:1 +纯利 1 +x:1 +服装节 1 +x:1 +巩 23 +x:23 +氢化油 1 +x:1 +南太 1 +x:1 +反之 1 +x:1 +南头 1 +x:1 +香泽 1 +x:1 +微山湖 1 +x:1 +曼海姆队 1 +x:1 +其 5219 +x:5219 +贵宾房 1 +x:1 +反过来说 1 +x:1 +主心骨儿 1 +x:1 +饿虎扑食 1 +x:1 +塔斯社 1 +x:1 +龙母镇 1 +x:1 +买进 1 +x:1 +事物 1 +x:1 +烟道 1 +x:1 +直体 1 +x:1 +赤县 1 +x:1 +信用卡 1 +x:1 +饲养科 1 +x:1 +主桥 1 +x:1 +引敌他顾 1 +x:1 +英山县 1 +x:1 +香气 1 +x:1 +白萝卜 1 +x:1 +负值 1 +x:1 +吸收国 1 +x:1 +负债 1 +x:1 +管标 1 +x:1 +稀巴烂 1 +x:1 +管树 1 +x:1 +保健室 1 +x:1 +西沟村 1 +x:1 +香水 1 +x:1 +喉塞音 1 +x:1 +海警 1 +x:1 +菌肥 1 +x:1 +改土 1 +x:1 +静态 1 +x:1 +主根 1 +x:1 +俊 156 +x:156 +苇塘 1 +x:1 +兵操 1 +x:1 +骨质 1 +x:1 +静思 1 +x:1 +香江 1 +x:1 +香榭丽舍 1 +x:1 +充当 1 +x:1 +二十七日 1 +x:1 +庸人自扰 1 +x:1 +前马家村 1 +x:1 +表白 1 +x:1 +承蒙 1 +x:1 +丰年 1 +x:1 +磅秤 1 +x:1 +雪道 1 +x:1 +火药 1 +x:1 +儿少 1 +x:1 +腋下 1 +x:1 +诲 1 +x:1 +银箔 1 +x:1 +专节 1 +x:1 +高高兴兴 1 +x:1 +直传 1 +x:1 +垂范 1 +x:1 +药性 1 +x:1 +主槽 1 +x:1 +定向培养 1 +x:1 +陷害 1 +x:1 +文明 1 +x:1 +影印件 1 +x:1 +蒙骗 1 +x:1 +富士山 1 +x:1 +平舆县 1 +x:1 +入伙人 1 +x:1 +鸟粪层 1 +x:1 +责骂 1 +x:1 +共鸣点 1 +x:1 +火花 1 +x:1 +梭柱 1 +x:1 +实景 1 +x:1 +大体上 1 +x:1 +泰语 1 +x:1 +中央区 1 +x:1 +子项 1 +x:1 +故去 1 +x:1 +仁慈 1 +x:1 +柔婉 1 +x:1 +到位率 1 +x:1 +火苗 1 +x:1 +乌纱 1 +x:1 +清净无为 1 +x:1 +晚 607 +x:607 +艳羡 1 +x:1 +疑信 1 +x:1 +爽朗 1 +x:1 +手套厂 1 +x:1 +钉帽 1 +x:1 +移花接木 1 +x:1 +视线 1 +x:1 +特殊钢 1 +x:1 +文字窍 1 +x:1 +兜肚 1 +x:1 +烟酒 1 +x:1 +火舌 1 +x:1 +航空队 1 +x:1 +扬长避短 1 +x:1 +种禽站 1 +x:1 +细故 1 +x:1 +跑动 1 +x:1 +王家坝村 1 +x:1 +烤火炉 1 +x:1 +林产品 1 +x:1 +财权 1 +x:1 +宜渔则渔 1 +x:1 +尽早 1 +x:1 +颠扑不破 1 +x:1 +钟佳桥 1 +x:1 +表态会 1 +x:1 +客货运输 1 +x:1 +撮 1 +x:1 +攀亲 1 +x:1 +奚落 1 +x:1 +筒壁 1 +x:1 +侨界 1 +x:1 +密密的 1 +x:1 +密密层层 1 +x:1 +了断 1 +x:1 +挑毛病 1 +x:1 +竹编 1 +x:1 +乌鲁木齐 1 +x:1 +海绵刷 1 +x:1 +新闻片 1 +x:1 +对症下药 1 +x:1 +享誉 1 +x:1 +哎 10 +x:10 +北仑港 1 +x:1 +龙山 1 +x:1 +标点符号 1 +x:1 +白日作梦 1 +x:1 +燠 1 +x:1 +低迷不振 1 +x:1 +缴费 1 +x:1 +自来水管 1 +x:1 +豪壮 1 +x:1 +了无 1 +x:1 +创作奖 1 +x:1 +展演 1 +x:1 +中央厅 1 +x:1 +持证 1 +x:1 +朝连岛 1 +x:1 +银票 1 +x:1 +棒棰岛 1 +x:1 +上算 1 +x:1 +基督 1 +x:1 +大姑儿 1 +x:1 +东辛房 1 +x:1 +租种 1 +x:1 +遣使 1 +x:1 +火膛 1 +x:1 +地税局 1 +x:1 +警纪 1 +x:1 +鸡笼 1 +x:1 +英花 1 +x:1 +香溪 1 +x:1 +筒子 1 +x:1 +岚光氤氲 1 +x:1 +邮费 1 +x:1 +代表部 1 +x:1 +谣言惑众 1 +x:1 +监察部 1 +x:1 +晚育率 1 +x:1 +蒸蒸日上 1 +x:1 +垂耷 1 +x:1 +好吃懒做 1 +x:1 +巨涌 1 +x:1 +霈 1 +x:1 +快活 1 +x:1 +工联 1 +x:1 +连带 1 +x:1 +癞蛤蟆 1 +x:1 +奖章 1 +x:1 +导纳 1 +x:1 +弄假成真 1 +x:1 +导线 1 +x:1 +举杯 1 +x:1 +松不得手 1 +x:1 +护齿素 1 +x:1 +骨脆性 1 +x:1 +侄孙女儿 1 +x:1 +激素 1 +x:1 +二进制 1 +x:1 +报警台 1 +x:1 +遮荫蔽日 1 +x:1 +恳请 1 +x:1 +息息相关 1 +x:1 +败也萧何 1 +x:1 +农一师 1 +x:1 +标签机 1 +x:1 +氢氰酸 1 +x:1 +家常便饭 1 +x:1 +蛋白质 1 +x:1 +雕栏玉砌 1 +x:1 +兑制 1 +x:1 +大荔县 1 +x:1 +吏 2 +x:2 +无核国家 1 +x:1 +日界线 1 +x:1 +河里 1 +x:1 +负分 1 +x:1 +乾坤 1 +x:1 +基石 1 +x:1 +照亮 1 +x:1 +香港 1 +x:1 +新人口论 1 +x:1 +草黄色 1 +x:1 +实时 1 +x:1 +菌苗 1 +x:1 +一哄而起 1 +x:1 +球面镜 1 +x:1 +拱跨径 1 +x:1 +圹 1 +x:1 +彭山 1 +x:1 +英航 1 +x:1 +巡演 1 +x:1 +聚珍版 1 +x:1 +湟水河 1 +x:1 +电功率 1 +x:1 +南宁 1 +x:1 +收费法 1 +x:1 +上策 1 +x:1 +哨响 1 +x:1 +南宋 1 +x:1 +南安 1 +x:1 +巨浪 1 +x:1 +上等 1 +x:1 +热功当量 1 +x:1 +枝杈 1 +x:1 +生产师 1 +x:1 +阿比托 1 +x:1 +苏铁林 1 +x:1 +到顶 1 +x:1 +实施 1 +x:1 +宇称 1 +x:1 +南宫 1 +x:1 +这方 1 +x:1 +花言巧语 1 +x:1 +枝条 1 +x:1 +冲绳岛 1 +x:1 +艺途 1 +x:1 +活性 1 +x:1 +巨流 1 +x:1 +火腿 1 +x:1 +创作室 1 +x:1 +黄花晚节 1 +x:1 +洗耳恭听 1 +x:1 +河道 1 +x:1 +拘禁 1 +x:1 +铁架子 1 +x:1 +台网 1 +x:1 +应聘人 1 +x:1 +登报 1 +x:1 +短斤缺两 1 +x:1 +叮当 1 +x:1 +指导性 1 +x:1 +账单子 1 +x:1 +逢集 1 +x:1 +细柳 1 +x:1 +橱窗 1 +x:1 +驼子 1 +x:1 +一股脑儿 1 +x:1 +菌草 1 +x:1 +北段 1 +x:1 +生理盐水 1 +x:1 +各显身手 1 +x:1 +新闻点 1 +x:1 +谷饶镇 1 +x:1 +竹筐 1 +x:1 +灰鹤 1 +x:1 +同一天 1 +x:1 +怕人 1 +x:1 +主殿 1 +x:1 +碎步 1 +x:1 +转氨酶 1 +x:1 +特警 1 +x:1 +子 125 +x:125 +糕 2 +x:2 +暖风 1 +x:1 +保险杯 1 +x:1 +供种量 1 +x:1 +保险杠 1 +x:1 +考古学系 1 +x:1 +兵权 1 +x:1 +月中 1 +x:1 +财文 1 +x:1 +计时员 1 +x:1 +新人新事 1 +x:1 +兑取 1 +x:1 +负号 1 +x:1 +侵权案 1 +x:1 +微瓦 1 +x:1 +洋洋万言 1 +x:1 +玉质 1 +x:1 +上端 1 +x:1 +又哭又闹 1 +x:1 +依稀可见 1 +x:1 +学到老 1 +x:1 +标吨 1 +x:1 +造诣 1 +x:1 +出手不凡 1 +x:1 +进攻方 1 +x:1 +市南区 1 +x:1 +业务厅 1 +x:1 +蝉蜕 1 +x:1 +纯净 1 +x:1 +特许 1 +x:1 +纯凝 1 +x:1 +检疫证 1 +x:1 +头昏脑涨 1 +x:1 +退堂鼓 1 +x:1 +特设 1 +x:1 +工致 1 +x:1 +绝命书 1 +x:1 +北欧 1 +x:1 +用户名 1 +x:1 +遣散费 1 +x:1 +抗日战争 1 +x:1 +紫葳 1 +x:1 +手术刀 1 +x:1 +坐骨神经 1 +x:1 +房改价 1 +x:1 +鸡窝 1 +x:1 +连忙 1 +x:1 +等量齐观 1 +x:1 +苇子 1 +x:1 +征服 1 +x:1 +动粗耍野 1 +x:1 +侨眷 1 +x:1 +欣赏课 1 +x:1 +砧骨 1 +x:1 +电报 1 +x:1 +主次 1 +x:1 +波士顿 1 +x:1 +财改 1 +x:1 +修鞋摊 1 +x:1 +拘票 1 +x:1 +保险柜 1 +x:1 +上空 1 +x:1 +蛮 17 +x:17 +橱 2 +x:2 +乾嘉 1 +x:1 +以防万一 1 +x:1 +葱白儿 1 +x:1 +银碗 1 +x:1 +日本海 1 +x:1 +小偷小摸 1 +x:1 +成果者 1 +x:1 +钉子 1 +x:1 +日记体 1 +x:1 +慷慨就义 1 +x:1 +颓 3 +x:3 +充实 1 +x:1 +东佃 1 +x:1 +绵羊 1 +x:1 +乱摊子 1 +x:1 +管治 1 +x:1 +同一年 1 +x:1 +整月 1 +x:1 +蜂窝式 1 +x:1 +海边 1 +x:1 +蓄水池 1 +x:1 +进攻战 1 +x:1 +笆斗 1 +x:1 +委以重任 1 +x:1 +库面 1 +x:1 +女性 1 +x:1 +北河 1 +x:1 +工程业 1 +x:1 +实据 1 +x:1 +愧于 1 +x:1 +启示力 1 +x:1 +管沟 1 +x:1 +造谣 1 +x:1 +登时 1 +x:1 +主治 1 +x:1 +推延 1 +x:1 +同舟共济 1 +x:1 +屏除 1 +x:1 +噌 4 +x:4 +地躺鞭 1 +x:1 +千姿百态 1 +x:1 +国际私法 1 +x:1 +依然故我 1 +x:1 +业务员 1 +x:1 +诡秘 1 +x:1 +海绵垫 1 +x:1 +西风东渐 1 +x:1 +做贼心虚 1 +x:1 +铆劲 1 +x:1 +争夺 1 +x:1 +三头六臂 1 +x:1 +快步 1 +x:1 +微珠 1 +x:1 +双高型 1 +x:1 +赤坂 1 +x:1 +武安市 1 +x:1 +进攻手 1 +x:1 +海运 1 +x:1 +裁判桌 1 +x:1 +指导权 1 +x:1 +难遂人意 1 +x:1 +茅 20 +x:20 +大放厥词 1 +x:1 +驼峰 1 +x:1 +第三国际 1 +x:1 +阜城 1 +x:1 +年租金 1 +x:1 +标号 1 +x:1 +代表院 1 +x:1 +监察院 1 +x:1 +南巡 1 +x:1 +言差语错 1 +x:1 +桔子 1 +x:1 +手工课 1 +x:1 +登攀 1 +x:1 +情笃意深 1 +x:1 +工农分子 1 +x:1 +玺 1 +x:1 +恰哈尔村 1 +x:1 +残货 1 +x:1 +屈原村 1 +x:1 +取法乎中 1 +x:1 +海轮 1 +x:1 +今儿个 1 +x:1 +垂手可得 1 +x:1 +蝉联 1 +x:1 +北汉 1 +x:1 +用户卡 1 +x:1 +必胜 1 +x:1 +争妍 1 +x:1 +北江 1 +x:1 +甬江 1 +x:1 +云居寺 1 +x:1 +烙饼 1 +x:1 +北极狐 1 +x:1 +倦怠 1 +x:1 +承做 1 +x:1 +内聚力 1 +x:1 +连声 1 +x:1 +胡张乡 1 +x:1 +结论性 1 +x:1 +招聘制 1 +x:1 +取法乎上 1 +x:1 +东侧 1 +x:1 +菠萝蜜叶 1 +x:1 +相辅相成 1 +x:1 +氢原子 1 +x:1 +北汽 1 +x:1 +晾 11 +x:11 +项目数 1 +x:1 +箭靶子 1 +x:1 +特质 1 +x:1 +芙蓉镇 1 +x:1 +鱼鳞松 1 +x:1 +连夜 1 +x:1 +经营额 1 +x:1 +竹管 1 +x:1 +丰实 1 +x:1 +电慰 1 +x:1 +写写 1 +x:1 +柔软 1 +x:1 +丰宁 1 +x:1 +民办教师 1 +x:1 +巧舌如簧 1 +x:1 +涛 340 +x:340 +过张乏弛 1 +x:1 +定向培育 1 +x:1 +梗概 1 +x:1 +香榭 1 +x:1 +绵纸 1 +x:1 +竹简 1 +x:1 +香榧 1 +x:1 +红方 1 +x:1 +鲁山 1 +x:1 +连天 1 +x:1 +索取 1 +x:1 +一览表 1 +x:1 +南山 1 +x:1 +东乡 1 +x:1 +咏叹调 1 +x:1 +仁政 1 +x:1 +胚胎学家 1 +x:1 +专力 1 +x:1 +殡工 1 +x:1 +视窗 1 +x:1 +魔高一丈 1 +x:1 +浅黄 1 +x:1 +脉络膜 1 +x:1 +中级 1 +x:1 +好莱坞 1 +x:1 +阳奉阴违 1 +x:1 +香槟 1 +x:1 +易爆物 1 +x:1 +呼吸器 1 +x:1 +仝 3 +x:3 +城工委 1 +x:1 +丰富 1 +x:1 +东三 1 +x:1 +探测室 1 +x:1 +秘而不宣 1 +x:1 +绵绸 1 +x:1 +朱桥镇 1 +x:1 +画院 1 +x:1 +庆典 1 +x:1 +东丽 1 +x:1 +东主 1 +x:1 +工蜂 1 +x:1 +走 3712 +x:3712 +杠子 1 +x:1 +檀板 1 +x:1 +水陆坦克 1 +x:1 +不懂装懂 1 +x:1 +租约 1 +x:1 +微型机 1 +x:1 +拉面 1 +x:1 +匠心独具 1 +x:1 +警种 1 +x:1 +实招 1 +x:1 +惺忪 1 +x:1 +淡妆浓抹 1 +x:1 +球虫药 1 +x:1 +鸡粪 1 +x:1 +北洋 1 +x:1 +图示 1 +x:1 +线毯 1 +x:1 +簇集 1 +x:1 +劲节 1 +x:1 +恳谈 1 +x:1 +实拍 1 +x:1 +邳苍 1 +x:1 +消防日 1 +x:1 +收奶车 1 +x:1 +传家宝 1 +x:1 +驳船 1 +x:1 +步进制 1 +x:1 +烂醉如泥 1 +x:1 +暂时 1 +x:1 +抬肩 1 +x:1 +经委会 1 +x:1 +火印 1 +x:1 +香椿 1 +x:1 +门坎 1 +x:1 +骨血 1 +x:1 +闻名遐尔 1 +x:1 +碾 4 +x:4 +天竺鼠 1 +x:1 +提花 1 +x:1 +性健康 1 +x:1 +广告学系 1 +x:1 +潇 1 +x:1 +斤两 1 +x:1 +团结 1 +x:1 +东亚 1 +x:1 +柏油路 1 +x:1 +基点 1 +x:1 +竹签 1 +x:1 +国民宫 1 +x:1 +东嘎村 1 +x:1 +短期化 1 +x:1 +鲜有 1 +x:1 +皑皑 1 +x:1 +第八屯 1 +x:1 +同一律 1 +x:1 +竹筏 1 +x:1 +食草动物 1 +x:1 +郡守 1 +x:1 +南岭 1 +x:1 +东人 1 +x:1 +承兑 1 +x:1 +油笔 1 +x:1 +北海 1 +x:1 +开发权 1 +x:1 +被采访人 1 +x:1 +东京 1 +x:1 +东亭 1 +x:1 +南岸 1 +x:1 +随葬品 1 +x:1 +李灶村 1 +x:1 +灯颈 1 +x:1 +隋 24 +x:24 +示波器 1 +x:1 +兵戎 1 +x:1 +兵戈 1 +x:1 +等于 1 +x:1 +残迹 1 +x:1 +旺起 1 +x:1 +食古不化 1 +x:1 +承办 1 +x:1 +标兵 1 +x:1 +剑龙 1 +x:1 +专著 1 +x:1 +中泗河村 1 +x:1 +傲 19 +x:19 +校领导 1 +x:1 +烟雨 1 +x:1 +倾销 1 +x:1 +垂落 1 +x:1 +查获记 1 +x:1 +基督教 1 +x:1 +争学 1 +x:1 +竞聘者 1 +x:1 +囿养 1 +x:1 +唐海 1 +x:1 +利益均沾 1 +x:1 +南开 1 +x:1 +海路 1 +x:1 +儿媳 1 +x:1 +疾首蹙额 1 +x:1 +叶黄素 1 +x:1 +爽性 1 +x:1 +前三合村 1 +x:1 +塔 95 +x:95 +改名 1 +x:1 +泛美 1 +x:1 +厄运 1 +x:1 +叶球 1 +x:1 +等份 1 +x:1 +安企部 1 +x:1 +等价 1 +x:1 +耸峙 1 +x:1 +上下水道 1 +x:1 +高速路 1 +x:1 +保险所 1 +x:1 +筒式 1 +x:1 +思南县 1 +x:1 +未名湖畔 1 +x:1 +海货 1 +x:1 +凤梧乡 1 +x:1 +承制 1 +x:1 +上编 1 +x:1 +仰韶文化 1 +x:1 +苇帘 1 +x:1 +自然免疫 1 +x:1 +标准 1 +x:1 +举措 1 +x:1 +越野赛跑 1 +x:1 +香樟 1 +x:1 +现下 1 +x:1 +袅绕 1 +x:1 +西洋画 1 +x:1 +吉萨省 1 +x:1 +一挥而就 1 +x:1 +主宰者 1 +x:1 +筐子 1 +x:1 +河闸 1 +x:1 +兴旺 1 +x:1 +上缴 1 +x:1 +历史戏 1 +x:1 +威尔士 1 +x:1 +河间 1 +x:1 +堂号 1 +x:1 +罕有 1 +x:1 +北极点 1 +x:1 +艰巨 1 +x:1 +逸民 1 +x:1 +爬桌 1 +x:1 +逸气 1 +x:1 +锭子油 1 +x:1 +蛀 5 +x:5 +扃 1 +x:1 +燃化部 1 +x:1 +关麓村 1 +x:1 +上网 1 +x:1 +新闻界 1 +x:1 +香橙 1 +x:1 +铁架床 1 +x:1 +送信儿 1 +x:1 +索债 1 +x:1 +凑热闹 1 +x:1 +气步枪 1 +x:1 +历史所 1 +x:1 +鸡翅 1 +x:1 +事理 1 +x:1 +二十六日 1 +x:1 +巽 1 +x:1 +文件名 1 +x:1 +七叶树 1 +x:1 +乌沙镇 1 +x:1 +香橼 1 +x:1 +桂山岛 1 +x:1 +支会 1 +x:1 +镇静药 1 +x:1 +设计业 1 +x:1 +开发方 1 +x:1 +剑麻 1 +x:1 +多样性 1 +x:1 +鲜艳度 1 +x:1 +阳江市 1 +x:1 +俊迈 1 +x:1 +检举信 1 +x:1 +京东 1 +x:1 +军礼 1 +x:1 +信德省 1 +x:1 +上线 1 +x:1 +缓刑期 1 +x:1 +水仙簪 1 +x:1 +捏合 1 +x:1 +基片 1 +x:1 +仁术 1 +x:1 +承压 1 +x:1 +拉锯 1 +x:1 +根指数 1 +x:1 +上级 1 +x:1 +电话费 1 +x:1 +兽中之王 1 +x:1 +储运费 1 +x:1 +系数 1 +x:1 +情 576 +x:576 +南市 1 +x:1 +星火带 1 +x:1 +嘤嘤 1 +x:1 +视碟 1 +x:1 +上坡路 1 +x:1 +保健局 1 +x:1 +导管 1 +x:1 +莆田县 1 +x:1 +京九 1 +x:1 +理论性 1 +x:1 +咸宁市 1 +x:1 +采油工 1 +x:1 +拉长 1 +x:1 +吃得消 1 +x:1 +承受 1 +x:1 +标值 1 +x:1 +存折 1 +x:1 +举手 1 +x:1 +凡尔 1 +x:1 +线手套 1 +x:1 +白宰鸡 1 +x:1 +问问答答 1 +x:1 +新历 1 +x:1 +爽意 1 +x:1 +甚至 1 +x:1 +女篮赛 1 +x:1 +临安市 1 +x:1 +无生命 1 +x:1 +北极熊 1 +x:1 +事略 1 +x:1 +粼粼 1 +x:1 +修辞 1 +x:1 +军事观 1 +x:1 +有机磷类 1 +x:1 +庆历 1 +x:1 +科学报 1 +x:1 +肚 14 +x:14 +举报 1 +x:1 +比绍城 1 +x:1 +张狂 1 +x:1 +冤 11 +x:11 +儿孙 1 +x:1 +只乐乡 1 +x:1 +警笛 1 +x:1 +儿子 1 +x:1 +单比例 1 +x:1 +主持国 1 +x:1 +特辑 1 +x:1 +承包 1 +x:1 +能多能少 1 +x:1 +尽 506 +x:506 +情感史 1 +x:1 +死不瞑目 1 +x:1 +海象 1 +x:1 +工薪 1 +x:1 +快棋 1 +x:1 +乡土气息 1 +x:1 +承印 1 +x:1 +事由 1 +x:1 +充塞 1 +x:1 +解放战争 1 +x:1 +可生物 1 +x:1 +海豹 1 +x:1 +倒休 1 +x:1 +遥 24 +x:24 +桌布 1 +x:1 +充填 1 +x:1 +主演 1 +x:1 +塞阿拉州 1 +x:1 +银粉 1 +x:1 +油菜王 1 +x:1 +绿衣使者 1 +x:1 +火葬 1 +x:1 +报警器 1 +x:1 +拉门 1 +x:1 +骗赔 1 +x:1 +甘苦与共 1 +x:1 +海豚 1 +x:1 +写卷 1 +x:1 +灯饰 1 +x:1 +丙磺舒 1 +x:1 +桌几 1 +x:1 +立意 1 +x:1 +事端 1 +x:1 +准保 1 +x:1 +苯乙烯 1 +x:1 +多事之秋 1 +x:1 +连同 1 +x:1 +乌石 1 +x:1 +巡游 1 +x:1 +油菜籽 1 +x:1 +一概而论 1 +x:1 +残臂 1 +x:1 +艰危 1 +x:1 +泻药 1 +x:1 +江陵 1 +x:1 +惠安县 1 +x:1 +保健医 1 +x:1 +南关 1 +x:1 +南共 1 +x:1 +仑吉 1 +x:1 +新厦 1 +x:1 +小康户 1 +x:1 +妇孺皆知 1 +x:1 +细沙 1 +x:1 +驳运 1 +x:1 +混合型 1 +x:1 +无假货 1 +x:1 +监测房 1 +x:1 +法桐 1 +x:1 +线春 1 +x:1 +采伐业 1 +x:1 +大公让 1 +x:1 +汲纳 1 +x:1 +江阴 1 +x:1 +军民共建 1 +x:1 +赏心性 1 +x:1 +戒毒所 1 +x:1 +特聘 1 +x:1 +财源 1 +x:1 +奶 60 +x:60 +赤字 1 +x:1 +海菜 1 +x:1 +快板 1 +x:1 +赤子 1 +x:1 +大姑子 1 +x:1 +标志 1 +x:1 +凡尔赛门 1 +x:1 +桉树林 1 +x:1 +泪花 1 +x:1 +隐君子 1 +x:1 +岳母 1 +x:1 +甘石桥 1 +x:1 +煽动 1 +x:1 +洋娃娃 1 +x:1 +长城人 1 +x:1 +江雾 1 +x:1 +跑官 1 +x:1 +秆子 1 +x:1 +雷神庙 1 +x:1 +探测器 1 +x:1 +杀虫药 1 +x:1 +托运房 1 +x:1 +爵士 1 +x:1 +便览 1 +x:1 +木莲桥 1 +x:1 +对立统一 1 +x:1 +上焦 1 +x:1 +罪责 1 +x:1 +庆岭 1 +x:1 +水性杨花 1 +x:1 +擦音 1 +x:1 +影影绰绰 1 +x:1 +造肥 1 +x:1 +兵法 1 +x:1 +风光一时 1 +x:1 +多雨区 1 +x:1 +歌鸫 1 +x:1 +成本会计 1 +x:1 +叶锈病 1 +x:1 +叮咚 1 +x:1 +叮咛 1 +x:1 +遏 2 +x:2 +慈溪市 1 +x:1 +护校 1 +x:1 +五彩池 1 +x:1 +宗旨 1 +x:1 +无形性 1 +x:1 +收获期 1 +x:1 +叮咬 1 +x:1 +火警 1 +x:1 +入手处 1 +x:1 +保险法 1 +x:1 +海草 1 +x:1 +菲 143 +x:143 +杵 1 +x:1 +驯顺 1 +x:1 +碌碌无为 1 +x:1 +叶窗 1 +x:1 +泰航 1 +x:1 +接机者 1 +x:1 +签字人 1 +x:1 +缉私队员 1 +x:1 +线板 1 +x:1 +强壮剂 1 +x:1 +采油厂 1 +x:1 +师生员工 1 +x:1 +考古界 1 +x:1 +业务处 1 +x:1 +下叔村 1 +x:1 +担架车 1 +x:1 +香料 1 +x:1 +桔园 1 +x:1 +大白话 1 +x:1 +校董会 1 +x:1 +骄奢祸程 1 +x:1 +便衣 1 +x:1 +线条 1 +x:1 +线束 1 +x:1 +盛极一时 1 +x:1 +中远途 1 +x:1 +倦 9 +x:9 +百花齐放 1 +x:1 +叶筋 1 +x:1 +银牌 1 +x:1 +线材 1 +x:1 +专家队 1 +x:1 +学科点 1 +x:1 +加拿大队 1 +x:1 +褐马鸡 1 +x:1 +大姑娘 1 +x:1 +乌盟 1 +x:1 +绝不为过 1 +x:1 +江面 1 +x:1 +便血 1 +x:1 +人造革 1 +x:1 +名缰利锁 1 +x:1 +诚惶诚恐 1 +x:1 +武安区 1 +x:1 +革新 1 +x:1 +一古脑儿 1 +x:1 +综治 1 +x:1 +微细 1 +x:1 +收费权 1 +x:1 +伍家 1 +x:1 +吸收式 1 +x:1 +泥牛入海 1 +x:1 +解困金 1 +x:1 +丰城 1 +x:1 +调资费 1 +x:1 +练法 1 +x:1 +宝元队 1 +x:1 +不屈不挠 1 +x:1 +万全之策 1 +x:1 +篡逆 1 +x:1 +支气管 1 +x:1 +仙女 1 +x:1 +争吵 1 +x:1 +细润 1 +x:1 +四五年 1 +x:1 +幺 1 +x:1 +矿 137 +x:137 +灯会 1 +x:1 +甚为可惜 1 +x:1 +愣是 1 +x:1 +嘉勉 1 +x:1 +粮棉 1 +x:1 +御手 1 +x:1 +缝隙 1 +x:1 +海航 1 +x:1 +细流 1 +x:1 +警用 1 +x:1 +骨董 1 +x:1 +工号 1 +x:1 +海船 1 +x:1 +铁蹄 1 +x:1 +专诚 1 +x:1 +巨星 1 +x:1 +玉蟾 1 +x:1 +神田区 1 +x:1 +核辐射 1 +x:1 +银狐 1 +x:1 +残联 1 +x:1 +便装 1 +x:1 +免疫力 1 +x:1 +新闻稿 1 +x:1 +专论 1 +x:1 +标底 1 +x:1 +抢修员 1 +x:1 +专访 1 +x:1 +准东 1 +x:1 +清癯 1 +x:1 +庆州 1 +x:1 +图书业 1 +x:1 +原本 1 +x:1 +政治史 1 +x:1 +十传百 1 +x:1 +旅交会 1 +x:1 +信贷资金 1 +x:1 +倒班制 1 +x:1 +垂询 1 +x:1 +细活 1 +x:1 +做主 1 +x:1 +途经 1 +x:1 +启示录 1 +x:1 +文字狱 1 +x:1 +上火 1 +x:1 +紫外线 1 +x:1 +警界 1 +x:1 +香喷喷 1 +x:1 +毁约率 1 +x:1 +管护 1 +x:1 +长三丙 1 +x:1 +手术室 1 +x:1 +. 6 +x:6 +桌号 1 +x:1 +此路不通 1 +x:1 +实测 1 +x:1 +万里无云 1 +x:1 +梗 7 +x:7 +工行 1 +x:1 +没齿难忘 1 +x:1 +微电子学 1 +x:1 +提赔 1 +x:1 +跑外 1 +x:1 +唪 1 +x:1 +驱逐令 1 +x:1 +实证主义 1 +x:1 +肄业生 1 +x:1 +快攻 1 +x:1 +逼良为娼 1 +x:1 +苍山县 1 +x:1 +创作力 1 +x:1 +毁 165 +x:165 +承建 1 +x:1 +长三乙 1 +x:1 +光天化日 1 +x:1 +黄豆角 1 +x:1 +南北 1 +x:1 +厦门队 1 +x:1 +酒 441 +x:441 +提货 1 +x:1 +鲁北 1 +x:1 +恣意 1 +x:1 +特色 1 +x:1 +声情并茂 1 +x:1 +寡 10 +x:10 +警监 1 +x:1 +缺劳户 1 +x:1 +庆幸 1 +x:1 +衬 8 +x:8 +郡吏 1 +x:1 +西段屯村 1 +x:1 +上班 1 +x:1 +理性认识 1 +x:1 +乳臭 1 +x:1 +叮嘱 1 +x:1 +南区 1 +x:1 +直统统 1 +x:1 +江铜 1 +x:1 +庆应 1 +x:1 +盖世 1 +x:1 +千虑一得 1 +x:1 +境遇 1 +x:1 +兵源 1 +x:1 +小 3834 +x:3834 +共和国宫 1 +x:1 +东中西部 1 +x:1 +免缴 1 +x:1 +慌神儿 1 +x:1 +桐乡 1 +x:1 +管户 1 +x:1 +研讨性 1 +x:1 +工业体系 1 +x:1 +视界 1 +x:1 +飞车 1 +x:1 +主打 1 +x:1 +心驰神往 1 +x:1 +南口 1 +x:1 +工装 1 +x:1 +贼星 1 +x:1 +势不可当 1 +x:1 +南召 1 +x:1 +钻空子 1 +x:1 +弹 63 +x:63 +罩袍 1 +x:1 +新闻社 1 +x:1 +患得患失 1 +x:1 +惨无人道 1 +x:1 +山冈子 1 +x:1 +卸甲庄村 1 +x:1 +生不逢时 1 +x:1 +黑黑压压 1 +x:1 +总会屋 1 +x:1 +钟表 1 +x:1 +咖啡茶 1 +x:1 +廉江市 1 +x:1 +照片集 1 +x:1 +特屈儿 1 +x:1 +体验型 1 +x:1 +计时工 1 +x:1 +以其昏昏 1 +x:1 +柔肠 1 +x:1 +乳腺 1 +x:1 +泊机位 1 +x:1 +驯马 1 +x:1 +南厢 1 +x:1 +莆田市 1 +x:1 +一百 1 +x:1 +考古学界 1 +x:1 +花环 1 +x:1 +南县 1 +x:1 +千差万别 1 +x:1 +清清亮亮 1 +x:1 +翘首以待 1 +x:1 +明火执杖 1 +x:1 +仪器厂 1 +x:1 +管控 1 +x:1 +瓣瓣 1 +x:1 +今生今世 1 +x:1 +生父母 1 +x:1 +特茹 1 +x:1 +委罪 1 +x:1 +基金部 1 +x:1 +微粒 1 +x:1 +北控 1 +x:1 +千百万 1 +x:1 +连场 1 +x:1 +浙西区 1 +x:1 +投笔从戎 1 +x:1 +室内乐 1 +x:1 +图卢兹 1 +x:1 +军种 1 +x:1 +震荡 1 +x:1 +非法定 1 +x:1 +卡库马 1 +x:1 +敬祖台 1 +x:1 +特药 1 +x:1 +牛鼎烹鸡 1 +x:1 +云豆 1 +x:1 +三岔口 1 +x:1 +二 2793 +x:2793 +海蜇头 1 +x:1 +香柚 1 +x:1 +主控 1 +x:1 +相映成辉 1 +x:1 +元延三年 1 +x:1 +蹲守 1 +x:1 +竞争性 1 +x:1 +春姑娘 1 +x:1 +巨擘 1 +x:1 +血迹 1 +x:1 +浅部 1 +x:1 +头昏 1 +x:1 +智残者 1 +x:1 +标尺 1 +x:1 +晕染 1 +x:1 +爽洁 1 +x:1 +火剪 1 +x:1 +柔脆 1 +x:1 +爽洌 1 +x:1 +撸子 1 +x:1 +英语 1 +x:1 +方法论 1 +x:1 +澄江县 1 +x:1 +万盛 1 +x:1 +桔味 1 +x:1 +保温杯 1 +x:1 +缝针 1 +x:1 +泪膜 1 +x:1 +工人运动 1 +x:1 +电信业 1 +x:1 +仆役 1 +x:1 +灵武市 1 +x:1 +静止 1 +x:1 +雷山村 1 +x:1 +错落有致 1 +x:1 +领口 1 +x:1 +菜窖 1 +x:1 +集装箱 1 +x:1 +厚厚实实 1 +x:1 +油橄榄 1 +x:1 +河沙 1 +x:1 +戈矛 1 +x:1 +陷入 1 +x:1 +贾夫纳 1 +x:1 +飞将军 1 +x:1 +耸入 1 +x:1 +上牌 1 +x:1 +实沉 1 +x:1 +基线 1 +x:1 +连城 1 +x:1 +农工商业 1 +x:1 +扑打 1 +x:1 +烟鬼 1 +x:1 +湍流 1 +x:1 +亚硫酐 1 +x:1 +承当 1 +x:1 +而立 1 +x:1 +赤壁 1 +x:1 +主持 1 +x:1 +特菜 1 +x:1 +收费日 1 +x:1 +微米 1 +x:1 +走门串户 1 +x:1 +丰富化 1 +x:1 +药贴 1 +x:1 +充压 1 +x:1 +烧瓶 1 +x:1 +四则运算 1 +x:1 +五子棋 1 +x:1 +丰功 1 +x:1 +夜班车 1 +x:1 +育龄 1 +x:1 +介休市 1 +x:1 +毫无道理 1 +x:1 +感染症 1 +x:1 +齐白石 1 +x:1 +导热 1 +x:1 +肺泡液 1 +x:1 +海螺 1 +x:1 +保有率 1 +x:1 +火辣 1 +x:1 +示意 1 +x:1 +壮阔 1 +x:1 +危崖 1 +x:1 +千虑一失 1 +x:1 +驼员 1 +x:1 +唐朝 1 +x:1 +误导性 1 +x:1 +年事已高 1 +x:1 +翻天复地 1 +x:1 +奎塔 1 +x:1 +宁官屯 1 +x:1 +势 112 +x:112 +朱寨镇 1 +x:1 +新莱昂 1 +x:1 +词藻 1 +x:1 +复制件 1 +x:1 +囿养地 1 +x:1 +复名数 1 +x:1 +发明人 1 +x:1 +嘴里 1 +x:1 +治安员 1 +x:1 +海蟹 1 +x:1 +折叠伞 1 +x:1 +造物主 1 +x:1 +骨膜 1 +x:1 +畦 5 +x:5 +这次 1 +x:1 +朽 5 +x:5 +吸储揽存 1 +x:1 +反对票 1 +x:1 +想 2414 +x:2414 +快捷 1 +x:1 +五彩棉 1 +x:1 +德能勤绩 1 +x:1 +联络会 1 +x:1 +免租 1 +x:1 +指战员 1 +x:1 +超历史 1 +x:1 +皮件 1 +x:1 +桢楠树 1 +x:1 +皮下 1 +x:1 +提请 1 +x:1 +铁面无私 1 +x:1 +总结性 1 +x:1 +总状花序 1 +x:1 +便路 1 +x:1 +棕榈油 1 +x:1 +微笛 1 +x:1 +微笑 1 +x:1 +鸣不平 1 +x:1 +摩登舞 1 +x:1 +保健型 1 +x:1 +银矿 1 +x:1 +海蜇 1 +x:1 +敲钟人 1 +x:1 +八面风 1 +x:1 +鸡犬不宁 1 +x:1 +罗牛山 1 +x:1 +离合悲欢 1 +x:1 +冰雕玉琢 1 +x:1 +海蜒 1 +x:1 +气锅鸡 1 +x:1 +浅露 1 +x:1 +彝海结盟 1 +x:1 +深入浅出 1 +x:1 +免票 1 +x:1 +入门处 1 +x:1 +地质师 1 +x:1 +斥 14 +x:14 +疑难 1 +x:1 +提议 1 +x:1 +衣冠楚楚 1 +x:1 +警灯 1 +x:1 +扑救 1 +x:1 +西瓜节 1 +x:1 +火车 1 +x:1 +纯度 1 +x:1 +赤心 1 +x:1 +竹片 1 +x:1 +搅拌机 1 +x:1 +杀一儆百 1 +x:1 +福兴寺 1 +x:1 +独具一格 1 +x:1 +死而复生 1 +x:1 +争冠 1 +x:1 +英豪 1 +x:1 +争做 1 +x:1 +音响效果 1 +x:1 +渺茫 1 +x:1 +丰厚 1 +x:1 +唇齿相依 1 +x:1 +骨胶 1 +x:1 +北斗 1 +x:1 +异曲同工 1 +x:1 +如誓如约 1 +x:1 +沈 313 +x:313 +斛 2 +x:2 +主旨 1 +x:1 +蜜 10 +x:10 +线损 1 +x:1 +阜平 1 +x:1 +海蚀 1 +x:1 +绞尽脑汁 1 +x:1 +末端 1 +x:1 +丰县 1 +x:1 +天元赛 1 +x:1 +计次制 1 +x:1 +田产 1 +x:1 +蒙难 1 +x:1 +喻 42 +x:42 +孟良崮 1 +x:1 +奥勒松 1 +x:1 +北方 1 +x:1 +贩毒点 1 +x:1 +迟钝 1 +x:1 +钢帘线 1 +x:1 +快手 1 +x:1 +兴渔 1 +x:1 +乏煤 1 +x:1 +滴水不漏 1 +x:1 +南向 1 +x:1 +仆妇 1 +x:1 +达马托 1 +x:1 +小康村 1 +x:1 +门坎儿 1 +x:1 +基本法 1 +x:1 +丰台 1 +x:1 +脑积水 1 +x:1 +向壁虚构 1 +x:1 +北无 1 +x:1 +艺龄 1 +x:1 +海蛎 1 +x:1 +花溪区 1 +x:1 +骨肉 1 +x:1 +玉茭 1 +x:1 +档案法 1 +x:1 +形式各异 1 +x:1 +刽子手 1 +x:1 +屈原滩 1 +x:1 +真真假假 1 +x:1 +悦人耳目 1 +x:1 +连接线 1 +x:1 +静流 1 +x:1 +充分 1 +x:1 +必要 1 +x:1 +己队 1 +x:1 +田七 1 +x:1 +老丈人 1 +x:1 +仲裁业 1 +x:1 +瑞金市 1 +x:1 +悦目性 1 +x:1 +歌魂 1 +x:1 +快报 1 +x:1 +分系统 1 +x:1 +田主 1 +x:1 +主教 1 +x:1 +可维修性 1 +x:1 +钟厂 1 +x:1 +江苏厅 1 +x:1 +莽莽 1 +x:1 +使眼色 1 +x:1 +崔马镇 1 +x:1 +其实难副 1 +x:1 +航海灯 1 +x:1 +锻 1 +x:1 +默克莱 1 +x:1 +静海 1 +x:1 +韵部 1 +x:1 +侨社 1 +x:1 +评 234 +x:234 +希腊式 1 +x:1 +主攻 1 +x:1 +此消彼长 1 +x:1 +主政 1 +x:1 +子承父业 1 +x:1 +冲绳县 1 +x:1 +跑腿 1 +x:1 +灰姑娘 1 +x:1 +海虾 1 +x:1 +春蕾班 1 +x:1 +四部丛刊 1 +x:1 +火奴鲁鲁 1 +x:1 +阜康 1 +x:1 +为数众多 1 +x:1 +会道门 1 +x:1 +专辑 1 +x:1 +愿意 1 +x:1 +巨手 1 +x:1 +混合制 1 +x:1 +修订案 1 +x:1 +枝桠 1 +x:1 +陷坑 1 +x:1 +止推阀 1 +x:1 +管教 1 +x:1 +揭幕式 1 +x:1 +和平谈判 1 +x:1 +南坎 1 +x:1 +美味可口 1 +x:1 +快意 1 +x:1 +快言快语 1 +x:1 +墨竹 1 +x:1 +〔 35 +x:35 +充军 1 +x:1 +鹰洋 1 +x:1 +便车 1 +x:1 +叶类 1 +x:1 +警犬 1 +x:1 +鸡眼 1 +x:1 +研制厂 1 +x:1 +虔诚 1 +x:1 +暗中 1 +x:1 +南坪 1 +x:1 +男低音 1 +x:1 +中央局 1 +x:1 +砖石塔 1 +x:1 +玫瑰园 1 +x:1 +复员退伍 1 +x:1 +赂 1 +x:1 +跑方员 1 +x:1 +营养钵 1 +x:1 +失业 1 +x:1 +测量 1 +x:1 +联材字 1 +x:1 +现行犯 1 +x:1 +闹翻 1 +x:1 +卡诺州 1 +x:1 +线性 1 +x:1 +举止 1 +x:1 +海藻 1 +x:1 +举步 1 +x:1 +碧萝春 1 +x:1 +捞 70 +x:70 +快慢 1 +x:1 +课业 1 +x:1 +药水 1 +x:1 +歌颂 1 +x:1 +开发法 1 +x:1 +朝气蓬勃 1 +x:1 +负担卡 1 +x:1 +路线图 1 +x:1 +系统性 1 +x:1 +俯冲 1 +x:1 +赞曰 1 +x:1 +快慰 1 +x:1 +传销商品 1 +x:1 +著作史 1 +x:1 +倒下 1 +x:1 +北昆 1 +x:1 +无条者 1 +x:1 +岳阳楼 1 +x:1 +南城 1 +x:1 +西戎村 1 +x:1 +争取 1 +x:1 +租界 1 +x:1 +一路风尘 1 +x:1 +幸存者 1 +x:1 +北约克区 1 +x:1 +排中律 1 +x:1 +主景 1 +x:1 +课以 1 +x:1 +热血 1 +x:1 +江都 1 +x:1 +业务庭 1 +x:1 +黑绿黑绿 1 +x:1 +悲痛欲绝 1 +x:1 +防锈 1 +x:1 +军火商 1 +x:1 +聘任制 1 +x:1 +一无所有 1 +x:1 +连动 1 +x:1 +鹅掌楸 1 +x:1 +甚广 1 +x:1 +官庄村 1 +x:1 +葛洲坝 1 +x:1 +富商 1 +x:1 +现金 1 +x:1 +夺关斩将 1 +x:1 +财校 1 +x:1 +鄂伦春 1 +x:1 +充充 1 +x:1 +迫不及待 1 +x:1 +住舍 1 +x:1 +慧眼独具 1 +x:1 +钢花呢 1 +x:1 +失事 1 +x:1 +免签 1 +x:1 +新日铁 1 +x:1 +握手言和 1 +x:1 +充公 1 +x:1 +味道儿 1 +x:1 +柳行镇 1 +x:1 +新市村 1 +x:1 +大摇大摆 1 +x:1 +孜孜追求 1 +x:1 +回绝 1 +x:1 +主星 1 +x:1 +宫腔镜检 1 +x:1 +传为佳话 1 +x:1 +民生主义 1 +x:1 +提要 1 +x:1 +租用 1 +x:1 +解甲归田 1 +x:1 +碎末 1 +x:1 +验印 1 +x:1 +北极 1 +x:1 +南昌起义 1 +x:1 +细毛 1 +x:1 +溯流 1 +x:1 +税 313 +x:313 +写实 1 +x:1 +屡禁不绝 1 +x:1 +北枝 1 +x:1 +高度化 1 +x:1 +课余 1 +x:1 +索姆 1 +x:1 +暗伤 1 +x:1 +其他人 1 +x:1 +河鱼 1 +x:1 +工资 1 +x:1 +国民党 1 +x:1 +直销点 1 +x:1 +硼镁石 1 +x:1 +础石 1 +x:1 +憾事 1 +x:1 +管林 1 +x:1 +激灵 1 +x:1 +对夹式 1 +x:1 +万物 1 +x:1 +写家 1 +x:1 +狗皮膏药 1 +x:1 +这栋 1 +x:1 +曼德拉 1 +x:1 +巴拿马 1 +x:1 +顺服 1 +x:1 +着眼点 1 +x:1 +管柱 1 +x:1 +工贼 1 +x:1 +明知故问 1 +x:1 +到此为止 1 +x:1 +工贸 1 +x:1 +买者 1 +x:1 +专责 1 +x:1 +经得起 1 +x:1 +烟龄 1 +x:1 +甚微 1 +x:1 +银球 1 +x:1 +上相 1 +x:1 +邮轮 1 +x:1 +搁置不前 1 +x:1 +视点 1 +x:1 +奇货可居 1 +x:1 +朱顶雀 1 +x:1 +主枝 1 +x:1 +眼压 1 +x:1 +失传 1 +x:1 +一体机 1 +x:1 +毫不留情 1 +x:1 +政治账 1 +x:1 +骨节 1 +x:1 +新闻系 1 +x:1 +海蓝 1 +x:1 +在理 1 +x:1 +汤罐 1 +x:1 +饲料稻 1 +x:1 +布点网 1 +x:1 +无行李 1 +x:1 +弋 1 +x:1 +五子歌 1 +x:1 +主板 1 +x:1 +鸡皮 1 +x:1 +核动力 1 +x:1 +接生率 1 +x:1 +邮车 1 +x:1 +隘 1 +x:1 +其乐融融 1 +x:1 +庆安 1 +x:1 +北朝 1 +x:1 +表现者 1 +x:1 +上瘾 1 +x:1 +研究室 1 +x:1 +夏时制 1 +x:1 +南团 1 +x:1 +陕北 1 +x:1 +免税 1 +x:1 +凡响 1 +x:1 +谢世 1 +x:1 +失信 1 +x:1 +基站 1 +x:1 +垂足 1 +x:1 +产量比 1 +x:1 +南国 1 +x:1 +保卫处 1 +x:1 +三元杂交 1 +x:1 +失修 1 +x:1 +官渡区 1 +x:1 +半渡击 1 +x:1 +确乎 1 +x:1 +读卡机 1 +x:1 +碱业 1 +x:1 +义诊 1 +x:1 +蒙巴萨 1 +x:1 +海葵 1 +x:1 +拘留 1 +x:1 +保健品 1 +x:1 +坐蔸 1 +x:1 +参与率 1 +x:1 +饱经 1 +x:1 +委管 1 +x:1 +田集乡 1 +x:1 +光明磊落 1 +x:1 +奎宁 1 +x:1 +连史 1 +x:1 +鲜活 1 +x:1 +增加额 1 +x:1 +探险队 1 +x:1 +体体面面 1 +x:1 +帮贫济困 1 +x:1 +稳中有降 1 +x:1 +荧光屏 1 +x:1 +管束 1 +x:1 +香粉 1 +x:1 +竹溪 1 +x:1 +应承 1 +x:1 +星细胞 1 +x:1 +侵染 1 +x:1 +北极星 1 +x:1 +松嫩 1 +x:1 +桩板墙 1 +x:1 +团年饭 1 +x:1 +红外光 1 +x:1 +有眉目 1 +x:1 +基数 1 +x:1 +反常 1 +x:1 +年轻化 1 +x:1 +满意车 1 +x:1 +细瓷 1 +x:1 +拙词 1 +x:1 +看摊 1 +x:1 +探测仪 1 +x:1 +河药 1 +x:1 +丰产 1 +x:1 +闰日 1 +x:1 +反帝 1 +x:1 +藕粉 1 +x:1 +香粳 1 +x:1 +难割难舍 1 +x:1 +讽 2 +x:2 +艺苑 1 +x:1 +碎砖 1 +x:1 +设计奖 1 +x:1 +菱形块 1 +x:1 +相继 1 +x:1 +祷念 1 +x:1 +有人 1 +x:1 +擦车 1 +x:1 +南柯一梦 1 +x:1 +郡主 1 +x:1 +化粪池 1 +x:1 +下课铃 1 +x:1 +匹马当先 1 +x:1 +胡力斯台 1 +x:1 +主碑 1 +x:1 +北平市 1 +x:1 +蒙语 1 +x:1 +好心人 1 +x:1 +端端正正 1 +x:1 +龙王潭 1 +x:1 +交通税 1 +x:1 +惩 11 +x:11 +梨园戏 1 +x:1 +整鞍备马 1 +x:1 +宿迁 1 +x:1 +担架队 1 +x:1 +浅说 1 +x:1 +跨过 1 +x:1 +巨翅 1 +x:1 +爽直 1 +x:1 +大放异彩 1 +x:1 +微服 1 +x:1 +娇 13 +x:13 +琉璃厂 1 +x:1 +评先树优 1 +x:1 +万象更新 1 +x:1 +乌托邦 1 +x:1 +免收 1 +x:1 +墙缝 1 +x:1 +钢研所 1 +x:1 +混合体 1 +x:1 +荒谬绝伦 1 +x:1 +过家家 1 +x:1 +侵权 1 +x:1 +骨密度 1 +x:1 +警民 1 +x:1 +微末 1 +x:1 +新衣 1 +x:1 +黄帝庙 1 +x:1 +东寺 1 +x:1 +秋后 1 +x:1 +妖言惑众 1 +x:1 +反应 1 +x:1 +微机 1 +x:1 +女低音 1 +x:1 +品牌战 1 +x:1 +交通站 1 +x:1 +签字国 1 +x:1 +狗崽子 1 +x:1 +龙骧虎步 1 +x:1 +细琐 1 +x:1 +政出多门 1 +x:1 +涸辙之鲋 1 +x:1 +异邦 1 +x:1 +兜里 1 +x:1 +末期 1 +x:1 +田协 1 +x:1 +倍场 1 +x:1 +东家 1 +x:1 +日K线图 1 +x:1 +海魂 1 +x:1 +白唇鹿 1 +x:1 +完整 1 +x:1 +明久乡 1 +x:1 +震颤 1 +x:1 +笛箫埙 1 +x:1 +香米 1 +x:1 +东宫 1 +x:1 +航海法 1 +x:1 +元鱼 1 +x:1 +反弹 1 +x:1 +股骨颈 1 +x:1 +暴力 1 +x:1 +主科 1 +x:1 +精品化 1 +x:1 +皓首穷经 1 +x:1 +轴对称 1 +x:1 +便道 1 +x:1 +到访 1 +x:1 +墙纸 1 +x:1 +项目点 1 +x:1 +预备 1 +x:1 +天蝎座 1 +x:1 +动态化 1 +x:1 +提防 1 +x:1 +筹备组 1 +x:1 +人造磁铁 1 +x:1 +增压泵 1 +x:1 +万民 1 +x:1 +通统 1 +x:1 +工程学 1 +x:1 +收购站 1 +x:1 +拍 253 +x:253 +愧对 1 +x:1 +上吐下泻 1 +x:1 +管路 1 +x:1 +上棉 1 +x:1 +镜屏 1 +x:1 +森木绿 1 +x:1 +英里 1 +x:1 +农田水利 1 +x:1 +漳河 1 +x:1 +法医院 1 +x:1 +器械体操 1 +x:1 +保险界 1 +x:1 +充任 1 +x:1 +线缆 1 +x:1 +唾 1 +x:1 +巨细 1 +x:1 +呼号 1 +x:1 +抓饭 1 +x:1 +工程室 1 +x:1 +购机费 1 +x:1 +土腥味 1 +x:1 +实益 1 +x:1 +金针虫 1 +x:1 +呼叫 1 +x:1 +终评 1 +x:1 +春 323 +x:323 +皮匠 1 +x:1 +中游 1 +x:1 +感受 1 +x:1 +漱口 1 +x:1 +唐突 1 +x:1 +山坡坡 1 +x:1 +导流 1 +x:1 +现身 1 +x:1 +快纸 1 +x:1 +上校 1 +x:1 +特首 1 +x:1 +详述 1 +x:1 +狸猫 1 +x:1 +耄耋老人 1 +x:1 +兵痞 1 +x:1 +凹面镜 1 +x:1 +哨长 1 +x:1 +委方 1 +x:1 +益智性 1 +x:1 +鼠窃狗偷 1 +x:1 +海马 1 +x:1 +等奖 1 +x:1 +上桌 1 +x:1 +汤杯赛 1 +x:1 +利益观 1 +x:1 +蚁蚕 1 +x:1 +返 73 +x:73 +南 873 +x:873 +苦口婆心 1 +x:1 +按质论价 1 +x:1 +寓所 1 +x:1 +山坡地 1 +x:1 +江边 1 +x:1 +吹风 1 +x:1 +相纸 1 +x:1 +胶 17 +x:17 +摹 2 +x:2 +鸵鸟场 1 +x:1 +购书卡 1 +x:1 +乳香 1 +x:1 +激流 1 +x:1 +柔顺 1 +x:1 +江豚 1 +x:1 +婚丧嫁娶 1 +x:1 +紊 1 +x:1 +左撇子 1 +x:1 +服装部 1 +x:1 +狠劲 1 +x:1 +借读 1 +x:1 +喷泉 1 +x:1 +捧杯 1 +x:1 +地窖 1 +x:1 +意趣 1 +x:1 +大黄山市 1 +x:1 +反射 1 +x:1 +末日 1 +x:1 +嘴边 1 +x:1 +激浪 1 +x:1 +展销 1 +x:1 +失魂落魄 1 +x:1 +平安队 1 +x:1 +跨越 1 +x:1 +香纸 1 +x:1 +直拉 1 +x:1 +张村 1 +x:1 +一下 1 +x:1 +现货 1 +x:1 +蔑视 1 +x:1 +详谈 1 +x:1 +九狮苑 1 +x:1 +管家婆 1 +x:1 +基材 1 +x:1 +礼服呢 1 +x:1 +细目 1 +x:1 +基本 1 +x:1 +清肺利胆 1 +x:1 +特马 1 +x:1 +蝴蝶花 1 +x:1 +指挥舱 1 +x:1 +管端 1 +x:1 +己见 1 +x:1 +临港型 1 +x:1 +侧重点 1 +x:1 +碱厂 1 +x:1 +失分 1 +x:1 +电动力学 1 +x:1 +迈开 1 +x:1 +开发热 1 +x:1 +北站 1 +x:1 +亏损声 1 +x:1 +东夷 1 +x:1 +东头 1 +x:1 +交会处 1 +x:1 +跨距 1 +x:1 +北端 1 +x:1 +涨价率 1 +x:1 +悠悠扬扬 1 +x:1 +烟花 1 +x:1 +实用 1 +x:1 +东大 1 +x:1 +基期 1 +x:1 +失利 1 +x:1 +激活 1 +x:1 +博德鲁姆 1 +x:1 +借贷国 1 +x:1 +香豆素 1 +x:1 +管弦乐队 1 +x:1 +一身是胆 1 +x:1 +连云 1 +x:1 +双特生 1 +x:1 +委曲 1 +x:1 +如饥似渴 1 +x:1 +乌海 1 +x:1 +灯谜 1 +x:1 +稿酬 1 +x:1 +空袭日 1 +x:1 +提问 1 +x:1 +京官 1 +x:1 +实症 1 +x:1 +静物 1 +x:1 +上款 1 +x:1 +设计家 1 +x:1 +泰顺 1 +x:1 +亨 2 +x:2 +细白 1 +x:1 +吃闭门羹 1 +x:1 +碱卤 1 +x:1 +设计室 1 +x:1 +珠泪盈眶 1 +x:1 +政治部 1 +x:1 +厉行节俭 1 +x:1 +胡兰镇 1 +x:1 +月泉 1 +x:1 +从早到晚 1 +x:1 +贵义重利 1 +x:1 +容纳量 1 +x:1 +劳动法 1 +x:1 +碱化 1 +x:1 +导游 1 +x:1 +连介 1 +x:1 +杯赛 1 +x:1 +紫萍 1 +x:1 +成人组 1 +x:1 +斤头 1 +x:1 +荡 20 +x:20 +寻寻觅觅 1 +x:1 +事态 1 +x:1 +下中农 1 +x:1 +党纪 1 +x:1 +拜泉县 1 +x:1 +基极 1 +x:1 +失势 1 +x:1 +走私者 1 +x:1 +回车 1 +x:1 +南澳岛 1 +x:1 +蛋白胨 1 +x:1 +谷城县 1 +x:1 +摆架子 1 +x:1 +管管 1 +x:1 +谈天说地 1 +x:1 +婵娟 1 +x:1 +呼兰 1 +x:1 +照顾 1 +x:1 +农发所 1 +x:1 +簇聚 1 +x:1 +东塘 1 +x:1 +分线盒 1 +x:1 +疑念 1 +x:1 +姜家泊 1 +x:1 +预谋 1 +x:1 +从军记 1 +x:1 +走形 1 +x:1 +国计民生 1 +x:1 +失却 1 +x:1 +赶跑 1 +x:1 +工程处 1 +x:1 +育肥 1 +x:1 +在案 1 +x:1 +保护关税 1 +x:1 +劳动路 1 +x:1 +云岫庵 1 +x:1 +问好 1 +x:1 +无的放失 1 +x:1 +连作 1 +x:1 +线材厂 1 +x:1 +哨音 1 +x:1 +连体 1 +x:1 +有教无类 1 +x:1 +五彩石 1 +x:1 +假面具 1 +x:1 +主管 1 +x:1 +火药枪 1 +x:1 +法 889 +x:889 +豪宅 1 +x:1 +银根 1 +x:1 +残骸 1 +x:1 +线索 1 +x:1 +一霎时 1 +x:1 +沙丁鱼 1 +x:1 +囊肿 1 +x:1 +镜平 1 +x:1 +匪军 1 +x:1 +海风 1 +x:1 +逸秀 1 +x:1 +华清池 1 +x:1 +克什若瓦 1 +x:1 +克里雅河 1 +x:1 +捎脚 1 +x:1 +现象 1 +x:1 +锆包壳 1 +x:1 +参考系 1 +x:1 +工程奖 1 +x:1 +药品量 1 +x:1 +灭绝人性 1 +x:1 +组诛 1 +x:1 +直属 1 +x:1 +科教文卫 1 +x:1 +匪兵 1 +x:1 +馋猫子 1 +x:1 +均安镇 1 +x:1 +马驹桥 1 +x:1 +秋地 1 +x:1 +田湖镇 1 +x:1 +南沱镇 1 +x:1 +耶市 1 +x:1 +火速 1 +x:1 +死顽固 1 +x:1 +墙报 1 +x:1 +法学会 1 +x:1 +新闻性 1 +x:1 +闹戏 1 +x:1 +却 3158 +x:3158 +财界 1 +x:1 +特点 1 +x:1 +攀岩 1 +x:1 +倭 1 +x:1 +充气式 1 +x:1 +交通科 1 +x:1 +皮儿 1 +x:1 +乌江 1 +x:1 +吐儿齐 1 +x:1 +草房子 1 +x:1 +求贤若渴 1 +x:1 +泰餐 1 +x:1 +浴具 1 +x:1 +烟草局 1 +x:1 +以色列籍 1 +x:1 +反差 1 +x:1 +职代会 1 +x:1 +举目 1 +x:1 +裸露 1 +x:1 +直射 1 +x:1 +细看 1 +x:1 +轮抗六号 1 +x:1 +礁堡 1 +x:1 +八点半 1 +x:1 +导演 1 +x:1 +陨铁 1 +x:1 +直尺 1 +x:1 +浅表 1 +x:1 +主笔 1 +x:1 +桔产区 1 +x:1 +失去 1 +x:1 +阴暗 1 +x:1 +竹浆 1 +x:1 +藏书角 1 +x:1 +提款机 1 +x:1 +鸭蛋青 1 +x:1 +亟待解决 1 +x:1 +效应期 1 +x:1 +联民党 1 +x:1 +河肥 1 +x:1 +皮具 1 +x:1 +警械 1 +x:1 +老狐狸 1 +x:1 +夹剪 1 +x:1 +厅 113 +x:113 +秋韵 1 +x:1 +坡头镇 1 +x:1 +冥冥 1 +x:1 +雍容华贵 1 +x:1 +暗合 1 +x:1 +上涌 1 +x:1 +楼子营镇 1 +x:1 +眈眈 1 +x:1 +上消 1 +x:1 +兜销 1 +x:1 +年成交额 1 +x:1 +中心思想 1 +x:1 +园洲镇 1 +x:1 +副线圈 1 +x:1 +两败俱伤 1 +x:1 +课员 1 +x:1 +兵油子 1 +x:1 +镜头 1 +x:1 +工程师 1 +x:1 +陷于 1 +x:1 +呼噜 1 +x:1 +翠玉 1 +x:1 +断编残简 1 +x:1 +金针菜 1 +x:1 +玉 65 +x:65 +倍受 1 +x:1 +利川市 1 +x:1 +上涨 1 +x:1 +阅读 1 +x:1 +植皮术 1 +x:1 +海龟 1 +x:1 +海龙 1 +x:1 +侨情 1 +x:1 +石岛镇 1 +x:1 +指挥员 1 +x:1 +捐资 1 +x:1 +合资企业 1 +x:1 +绊马索 1 +x:1 +嘴角 1 +x:1 +谌 3 +x:3 +田埂 1 +x:1 +保险灯 1 +x:1 +碎米 1 +x:1 +浅近 1 +x:1 +烟蒂 1 +x:1 +偷税额 1 +x:1 +① 44 +x:44 +椅披 1 +x:1 +文如其人 1 +x:1 +素描室 1 +x:1 +琴韵 1 +x:1 +泰然处之 1 +x:1 +宣传日 1 +x:1 +驴 9 +x:9 +对簿公堂 1 +x:1 +双特班 1 +x:1 +肿胀 1 +x:1 +被访者 1 +x:1 +警棍 1 +x:1 +金铃子 1 +x:1 +惧色 1 +x:1 +海鼠 1 +x:1 +上帝观 1 +x:1 +阿尔金山 1 +x:1 +财物 1 +x:1 +龙门汤 1 +x:1 +海角天涯 1 +x:1 +赤脚医生 1 +x:1 +警校 1 +x:1 +违法不究 1 +x:1 +出洋相 1 +x:1 +拂衣而去 1 +x:1 +便门 1 +x:1 +小莲庄 1 +x:1 +煽亮 1 +x:1 +歌艺 1 +x:1 +知冷知热 1 +x:1 +上诉书 1 +x:1 +巨笛 1 +x:1 +田地 1 +x:1 +逆水 1 +x:1 +无名之辈 1 +x:1 +柴林头村 1 +x:1 +跳远 1 +x:1 +上洲 1 +x:1 +曲意逢迎 1 +x:1 +凡俗 1 +x:1 +哭叫声 1 +x:1 +翎子 1 +x:1 +掺 21 +x:21 +库斯科省 1 +x:1 +专集 1 +x:1 +谐和 1 +x:1 +言下之意 1 +x:1 +喷火器 1 +x:1 +宣誓书 1 +x:1 +田块 1 +x:1 +甜蜜蜜 1 +x:1 +田坛 1 +x:1 +收费站 1 +x:1 +黄花闺女 1 +x:1 +祖父母 1 +x:1 +东往 1 +x:1 +东征 1 +x:1 +丫形 1 +x:1 +上浆 1 +x:1 +脚脖子 1 +x:1 +田坎 1 +x:1 +上流 1 +x:1 +交通线 1 +x:1 +狠命 1 +x:1 +红星 1 +x:1 +乳齿 1 +x:1 +禁驶区 1 +x:1 +天方夜谭 1 +x:1 +实现 1 +x:1 +凡例 1 +x:1 +上海 1 +x:1 +新闻杯 1 +x:1 +拜年歌 1 +x:1 +导标 1 +x:1 +上浮 1 +x:1 +一举多得 1 +x:1 +歌舞 1 +x:1 +经管站 1 +x:1 +伊河路 1 +x:1 +清冷 1 +x:1 +泛泛 1 +x:1 +残羹剩饭 1 +x:1 +功名利禄 1 +x:1 +条条框框 1 +x:1 +松快 1 +x:1 +罕克拉 1 +x:1 +金银箔 1 +x:1 +哥伦布 1 +x:1 +低聘 1 +x:1 +东平 1 +x:1 +了然 1 +x:1 +庐江县 1 +x:1 +声明 1 +x:1 +撩人心动 1 +x:1 +南达沟 1 +x:1 +重点户 1 +x:1 +维吾尔族 1 +x:1 +交通网 1 +x:1 +实物 1 +x:1 +银湖 1 +x:1 +要览 1 +x:1 +扑粉 1 +x:1 +监测网 1 +x:1 +传统校 1 +x:1 +核工业 1 +x:1 +胆战心寒 1 +x:1 +天青石 1 +x:1 +倍加 1 +x:1 +毛手毛脚 1 +x:1 +奈 1 +x:1 +屈打成招 1 +x:1 +钵子 1 +x:1 +兼收并蓄 1 +x:1 +设计局 1 +x:1 +奢靡之始 1 +x:1 +宽窄行 1 +x:1 +有鬼 1 +x:1 +三挂钩 1 +x:1 +灯语 1 +x:1 +糟行 1 +x:1 +习惯线 1 +x:1 +制胜之道 1 +x:1 +秋凉 1 +x:1 +言论集 1 +x:1 +美术室 1 +x:1 +誓俭草 1 +x:1 +锦心绣口 1 +x:1 +泗宿 1 +x:1 +嫩黄色 1 +x:1 +长城卡 1 +x:1 +三阳 1 +x:1 +开鲁县 1 +x:1 +热情洋溢 1 +x:1 +海鸥 1 +x:1 +庞然大物 1 +x:1 +兴盛 1 +x:1 +粗壮者 1 +x:1 +银滩 1 +x:1 +苍劲 1 +x:1 +待岗者 1 +x:1 +冶核 1 +x:1 +铮黑 1 +x:1 +曲线形 1 +x:1 +暗喜 1 +x:1 +窟内 1 +x:1 +事权 1 +x:1 +解数 1 +x:1 +叶柄 1 +x:1 +乳鸽 1 +x:1 +上水 1 +x:1 +侵扰 1 +x:1 +贩毒案 1 +x:1 +永久磁铁 1 +x:1 +进化史观 1 +x:1 +囊虫 1 +x:1 +海鸟 1 +x:1 +贻 3 +x:3 +暗喻 1 +x:1 +青基会 1 +x:1 +蒸食 1 +x:1 +英镑 1 +x:1 +发明地 1 +x:1 +收缴处 1 +x:1 +准则 1 +x:1 +靖边县 1 +x:1 +西洋景 1 +x:1 +售粮款 1 +x:1 +河蚌 1 +x:1 +事机 1 +x:1 +白驹过隙 1 +x:1 +凡人 1 +x:1 +反对 1 +x:1 +洋技术 1 +x:1 +上汽 1 +x:1 +松弛 1 +x:1 +兵燹 1 +x:1 +箩筐 1 +x:1 +火险 1 +x:1 +赭石 1 +x:1 +副教授 1 +x:1 +松开 1 +x:1 +殖民权 1 +x:1 +山里红 1 +x:1 +进军号 1 +x:1 +平安里 1 +x:1 +迟迟 1 +x:1 +阅览 1 +x:1 +万念俱灰 1 +x:1 +种畜场 1 +x:1 +呼呼 1 +x:1 +莲花乡 1 +x:1 +高帽子 1 +x:1 +笛膜 1 +x:1 +闸口乡 1 +x:1 +银海 1 +x:1 +资费处 1 +x:1 +年复利 1 +x:1 +管线 1 +x:1 +高价生 1 +x:1 +委托 1 +x:1 +吕剧团 1 +x:1 +北纬 1 +x:1 +免掉 1 +x:1 +小恩小惠 1 +x:1 +拉萨 1 +x:1 +破 263 +x:263 +里根 1 +x:1 +鄙弃 1 +x:1 +款留 1 +x:1 +灯笼椒 1 +x:1 +呵气成霜 1 +x:1 +镜子 1 +x:1 +鹿蹄草 1 +x:1 +皮品 1 +x:1 +呼吼 1 +x:1 +殡仪 1 +x:1 +巡逻艇 1 +x:1 +姿色 1 +x:1 +呼吸 1 +x:1 +英雄 1 +x:1 +左满舵 1 +x:1 +小合唱 1 +x:1 +古潭州 1 +x:1 +侨报 1 +x:1 +稳中有进 1 +x:1 +椭圆形 1 +x:1 +南传 1 +x:1 +银洋 1 +x:1 +堡口村 1 +x:1 +工程局 1 +x:1 +复制品 1 +x:1 +油料作物 1 +x:1 +万欣 1 +x:1 +呼吁 1 +x:1 +遵照 1 +x:1 +尚方宝剑 1 +x:1 +灾害学 1 +x:1 +进攻点 1 +x:1 +火锅 1 +x:1 +上演 1 +x:1 +松山 1 +x:1 +直奔 1 +x:1 +往届 1 +x:1 +项目省 1 +x:1 +诱导 1 +x:1 +竹根 1 +x:1 +呼哧 1 +x:1 +垂钓 1 +x:1 +呼哨 1 +x:1 +东巴 1 +x:1 +秋分 1 +x:1 +脚钱 1 +x:1 +琴键 1 +x:1 +刻苦耐劳 1 +x:1 +香稻 1 +x:1 +析理 1 +x:1 +君主专制 1 +x:1 +概念性 1 +x:1 +秋初 1 +x:1 +含铅量 1 +x:1 +雀 8 +x:8 +巨祸 1 +x:1 +孰料 1 +x:1 +可逆性 1 +x:1 +稿费 1 +x:1 +竹桥 1 +x:1 +碱土 1 +x:1 +香港游 1 +x:1 +肩窝 1 +x:1 +倍儿 1 +x:1 +工钱 1 +x:1 +糜 2 +x:2 +荟要 1 +x:1 +火镜 1 +x:1 +提醒 1 +x:1 +碱地 1 +x:1 +歌者 1 +x:1 +足掌 1 +x:1 +自禁 1 +x:1 +共鸣板 1 +x:1 +版权局 1 +x:1 +以战养战 1 +x:1 +便鞋 1 +x:1 +愣神 1 +x:1 +虫卵 1 +x:1 +曲沟乡 1 +x:1 +智三针 1 +x:1 +当代史 1 +x:1 +专长 1 +x:1 +两点论 1 +x:1 +而是 1 +x:1 +薪饷 1 +x:1 +京师 1 +x:1 +戎 7 +x:7 +呼啦 1 +x:1 +屏蔽 1 +x:1 +南乐 1 +x:1 +设计师 1 +x:1 +等待 1 +x:1 +穷凶极恶 1 +x:1 +夹具 1 +x:1 +深山区 1 +x:1 +同床共枕 1 +x:1 +基扎 1 +x:1 +官庄组 1 +x:1 +火浣布 1 +x:1 +东山 1 +x:1 +反复 1 +x:1 +骨髓 1 +x:1 +皇叔 1 +x:1 +心黑手辣 1 +x:1 +细珠 1 +x:1 +害 114 +x:114 +上溯 1 +x:1 +泛滥 1 +x:1 +暗地 1 +x:1 +拦河闸 1 +x:1 +众口一词 1 +x:1 +海鲜 1 +x:1 +棋错一着 1 +x:1 +经济基础 1 +x:1 +昭彰 1 +x:1 +秋口 1 +x:1 +汤杯 1 +x:1 +爽然 1 +x:1 +阳泉市 1 +x:1 +骨骼 1 +x:1 +自卸车 1 +x:1 +南下 1 +x:1 +加油站长 1 +x:1 +耘锄 1 +x:1 +血小板 1 +x:1 +呼唤 1 +x:1 +秋叶 1 +x:1 +磅湛 1 +x:1 +震害 1 +x:1 +暗坝 1 +x:1 +有良心者 1 +x:1 +现行 1 +x:1 +失地 1 +x:1 +王单驼 1 +x:1 +海鳃 1 +x:1 +Ⅴ 8 +x:8 +克分子 1 +x:1 +马桥镇 1 +x:1 +提速 1 +x:1 +海鳗 1 +x:1 +蜷伏 1 +x:1 +瓦房化 1 +x:1 +削面 1 +x:1 +旷 4 +x:4 +南丰 1 +x:1 +京广 1 +x:1 +外版书 1 +x:1 +孔雀店村 1 +x:1 +低能 1 +x:1 +阁 13 +x:13 +油砂 1 +x:1 +熄 9 +x:9 +檐水 1 +x:1 +饱暖 1 +x:1 +支票 1 +x:1 +演示会 1 +x:1 +免戴 1 +x:1 +夹击 1 +x:1 +专门 1 +x:1 +等式 1 +x:1 +主罪 1 +x:1 +望虞河 1 +x:1 +北缘 1 +x:1 +紧缩性 1 +x:1 +援助款 1 +x:1 +呼嗒 1 +x:1 +商州市 1 +x:1 +事故 1 +x:1 +红土坡矿 1 +x:1 +南江县 1 +x:1 +登山绳 1 +x:1 +曾祖父 1 +x:1 +猪婆龙 1 +x:1 +乌桕 1 +x:1 +到货 1 +x:1 +罗里乡 1 +x:1 +动用量 1 +x:1 +缺口处 1 +x:1 +形影不离 1 +x:1 +戈比 1 +x:1 +濯锦 1 +x:1 +生殖洄游 1 +x:1 +竹楼 1 +x:1 +到资 1 +x:1 +有板有眼 1 +x:1 +海鱼 1 +x:1 +少林拳 1 +x:1 +南亚 1 +x:1 +仲裁员 1 +x:1 +秋千 1 +x:1 +上中游 1 +x:1 +主编 1 +x:1 +踢踏舞 1 +x:1 +南京 1 +x:1 +桌上 1 +x:1 +桌下 1 +x:1 +东岸 1 +x:1 +至理明言 1 +x:1 +管网 1 +x:1 +详见 1 +x:1 +修订版 1 +x:1 +棍棒 1 +x:1 +罗特尔队 1 +x:1 +呼喊 1 +x:1 +子孙饭 1 +x:1 +安慰剂 1 +x:1 +梭织 1 +x:1 +东单 1 +x:1 +舒心畅怀 1 +x:1 +持重 1 +x:1 +烟波浩渺 1 +x:1 +保温瓶 1 +x:1 +东升 1 +x:1 +便饭 1 +x:1 +微澜 1 +x:1 +下脚货 1 +x:1 +东华 1 +x:1 +核工业部 1 +x:1 +可歌可泣 1 +x:1 +微微克 1 +x:1 +暗堡 1 +x:1 +反对派 1 +x:1 +财经 1 +x:1 +庆安县 1 +x:1 +出租 1 +x:1 +拘押 1 +x:1 +蝴蝶装 1 +x:1 +莽 10 +x:10 +村村户户 1 +x:1 +东北 1 +x:1 +造造 1 +x:1 +主城区 1 +x:1 +乌枣 1 +x:1 +吃刀子 1 +x:1 +巨石 1 +x:1 +松劲 1 +x:1 +雨敞坪镇 1 +x:1 +遍采 1 +x:1 +夹带 1 +x:1 +松动 1 +x:1 +烟袋 1 +x:1 +香瓜 1 +x:1 +溘然长逝 1 +x:1 +祖 19 +x:19 +历史系 1 +x:1 +疆土 1 +x:1 +文文静静 1 +x:1 +招聘人 1 +x:1 +民粹派 1 +x:1 +明阳屯 1 +x:1 +东区 1 +x:1 +便餐 1 +x:1 +晚报社 1 +x:1 +仍然 1 +x:1 +按劳付酬 1 +x:1 +人格权 1 +x:1 +翠翘 1 +x:1 +细粮 1 +x:1 +等候 1 +x:1 +喷灌机 1 +x:1 +遍野 1 +x:1 +切 135 +x:135 +拖泥带水 1 +x:1 +偷渡者 1 +x:1 +帅劲儿 1 +x:1 +玉雕 1 +x:1 +汇合处 1 +x:1 +誓词 1 +x:1 +残酷 1 +x:1 +舢板 1 +x:1 +友邻 1 +x:1 +失声 1 +x:1 +等值 1 +x:1 +外包装盒 1 +x:1 +受惠者 1 +x:1 +黑石寨 1 +x:1 +自源性 1 +x:1 +超稠油 1 +x:1 +可不可能 1 +x:1 +终久 1 +x:1 +侨汇 1 +x:1 +民防局 1 +x:1 +谐声 1 +x:1 +失墒 1 +x:1 +枕边 1 +x:1 +大观园 1 +x:1 +旬刊 1 +x:1 +乌木 1 +x:1 +迟脉 1 +x:1 +火魔 1 +x:1 +俊逸 1 +x:1 +滤 4 +x:4 +蒙药 1 +x:1 +注药管 1 +x:1 +侨民 1 +x:1 +管灌 1 +x:1 +垂髫 1 +x:1 +倾诉 1 +x:1 +土岭乡 1 +x:1 +东厢 1 +x:1 +就是 1 +x:1 +高头讲章 1 +x:1 +联络官 1 +x:1 +惹麻烦 1 +x:1 +代表证 1 +x:1 +暗处 1 +x:1 +丝氨酸 1 +x:1 +警方 1 +x:1 +残部 1 +x:1 +演出证 1 +x:1 +歌迷 1 +x:1 +皮实 1 +x:1 +思考性 1 +x:1 +铜川市 1 +x:1 +松口 1 +x:1 +劳动服 1 +x:1 +求证 1 +x:1 +经商处 1 +x:1 +墙皮 1 +x:1 +剑齿虎 1 +x:1 +艺诀 1 +x:1 +上穷碧落 1 +x:1 +标书 1 +x:1 +竹枝 1 +x:1 +工程化 1 +x:1 +鱼钩 1 +x:1 +张江 1 +x:1 +竹林 1 +x:1 +激昂 1 +x:1 +齐阁村 1 +x:1 +发明家 1 +x:1 +板报栏 1 +x:1 +综采队 1 +x:1 +迈向 1 +x:1 +研讨班 1 +x:1 +劳动权 1 +x:1 +修配厂 1 +x:1 +从警 1 +x:1 +上情 1 +x:1 +美英式 1 +x:1 +利率表 1 +x:1 +挺 110 +x:110 +飘扬 1 +x:1 +松原 1 +x:1 +探险家 1 +x:1 +课外 1 +x:1 +视死如归 1 +x:1 +骨针 1 +x:1 +新岁 1 +x:1 +常山县 1 +x:1 +新农村乡 1 +x:1 +谭派 1 +x:1 +缺心少肺 1 +x:1 +柿 2 +x:2 +检验科 1 +x:1 +自然资源 1 +x:1 +竹木 1 +x:1 +临场发挥 1 +x:1 +卒子 1 +x:1 +武当山 1 +x:1 +香甜 1 +x:1 +炸豆腐 1 +x:1 +财综字 1 +x:1 +地心引力 1 +x:1 +氟 9 +x:9 +标价 1 +x:1 +跳帮组 1 +x:1 +可卡因 1 +x:1 +夹心 1 +x:1 +连年来 1 +x:1 +粮 255 +x:255 +木器厂 1 +x:1 +实绩 1 +x:1 +视若无睹 1 +x:1 +捉拿归案 1 +x:1 +狐群狗党 1 +x:1 +国务卿 1 +x:1 +招聘会 1 +x:1 +医史 1 +x:1 +受灾户 1 +x:1 +在押 1 +x:1 +表扬电 1 +x:1 +暂定名 1 +x:1 +预购 1 +x:1 +褂子 1 +x:1 +字 823 +x:823 +皮子 1 +x:1 +扑火 1 +x:1 +圩日 1 +x:1 +拘捕 1 +x:1 +租房 1 +x:1 +夜幕低垂 1 +x:1 +软弱无力 1 +x:1 +特重 1 +x:1 +敦化 1 +x:1 +叛乱者 1 +x:1 +租户 1 +x:1 +警教 1 +x:1 +卡路里 1 +x:1 +电信展 1 +x:1 +闪电式 1 +x:1 +扎堆 1 +x:1 +白布篷 1 +x:1 +神人 1 +x:1 +妇孺皆晓 1 +x:1 +电信局 1 +x:1 +靛青 1 +x:1 +黄帝城 1 +x:1 +浅色 1 +x:1 +专项 1 +x:1 +冷不防 1 +x:1 +香皂 1 +x:1 +优亲厚友 1 +x:1 +上排 1 +x:1 +非体力 1 +x:1 +吉卜赛人 1 +x:1 +一往直前 1 +x:1 +碗 110 +x:110 +仆从 1 +x:1 +微涨 1 +x:1 +车夫 1 +x:1 +东兴 1 +x:1 +河西 1 +x:1 +东关 1 +x:1 +逢迎 1 +x:1 +夹层 1 +x:1 +柔道 1 +x:1 +卫东区 1 +x:1 +看不起 1 +x:1 +代数根 1 +x:1 +肩摩踵接 1 +x:1 +反向 1 +x:1 +道德感 1 +x:1 +汇报会 1 +x:1 +坚贞不屈 1 +x:1 +逆作法 1 +x:1 +连环套 1 +x:1 +匡算 1 +x:1 +深入性 1 +x:1 +京华 1 +x:1 +测力计 1 +x:1 +裸麦 1 +x:1 +平平展展 1 +x:1 +做文章 1 +x:1 +仲裁委 1 +x:1 +无例外 1 +x:1 +高价票 1 +x:1 +烤鸭店 1 +x:1 +主犯 1 +x:1 +铟 1 +x:1 +乌方 1 +x:1 +细纱 1 +x:1 +太原市 1 +x:1 +酒经 1 +x:1 +蔺草 1 +x:1 +承付 1 +x:1 +海量 1 +x:1 +仆人 1 +x:1 +海里 1 +x:1 +氟石 1 +x:1 +碎片 1 +x:1 +单工槽 1 +x:1 +民防部 1 +x:1 +在意 1 +x:1 +颅 2 +x:2 +隐患 1 +x:1 +巨画 1 +x:1 +末流 1 +x:1 +用脑 1 +x:1 +呼声 1 +x:1 +栩栩如生 1 +x:1 +静穆 1 +x:1 +→ 2 +x:2 +巴塞罗那 1 +x:1 +南伞镇 1 +x:1 +戊戌变法 1 +x:1 +等分 1 +x:1 +宜章 1 +x:1 +消防站 1 +x:1 +田头 1 +x:1 +屡禁不止 1 +x:1 +等到 1 +x:1 +三跑田 1 +x:1 +一生 1 +x:1 +限额制 1 +x:1 +并购额 1 +x:1 +北爱 1 +x:1 +亲临其境 1 +x:1 +头痛医头 1 +x:1 +倾覆 1 +x:1 +江蓠 1 +x:1 +月色 1 +x:1 +了结 1 +x:1 +歌谣 1 +x:1 +虹雯 1 +x:1 +换气扇 1 +x:1 +艺委会 1 +x:1 +晓 25 +x:25 +泛指 1 +x:1 +融会贯通 1 +x:1 +歌谱 1 +x:1 +炮筒子 1 +x:1 +西洋楼 1 +x:1 +到职 1 +x:1 +反哺 1 +x:1 +汲水 1 +x:1 +乳酸 1 +x:1 +管片 1 +x:1 +反响 1 +x:1 +指导科 1 +x:1 +倾角 1 +x:1 +家家户户 1 +x:1 +帕尔马 1 +x:1 +普利茅斯 1 +x:1 +乳酪 1 +x:1 +大猫熊 1 +x:1 +中稻 1 +x:1 +屈原祠 1 +x:1 +壮乡 1 +x:1 +跺 3 +x:3 +华山路 1 +x:1 +倾视 1 +x:1 +丈量 1 +x:1 +无上光荣 1 +x:1 +醇 1 +x:1 +永别 1 +x:1 +歌路 1 +x:1 +总务司 1 +x:1 +道德性 1 +x:1 +莨菪 1 +x:1 +参与权 1 +x:1 +警枪 1 +x:1 +预审 1 +x:1 +抗干扰性 1 +x:1 +秋征 1 +x:1 +抄录 1 +x:1 +省略号 1 +x:1 +专业面 1 +x:1 +意志力 1 +x:1 +失学 1 +x:1 +上报 1 +x:1 +寄存包 1 +x:1 +乘法 1 +x:1 +练练 1 +x:1 +人面兽心 1 +x:1 +雄才大略 1 +x:1 +承修 1 +x:1 +大地回春 1 +x:1 +南阳市 1 +x:1 +着慌 1 +x:1 +工程兵 1 +x:1 +荟萃 1 +x:1 +京剧 1 +x:1 +汤歌 1 +x:1 +香港中路 1 +x:1 +载有 1 +x:1 +微波 1 +x:1 +亚音速 1 +x:1 +巡逻车 1 +x:1 +蒙胧 1 +x:1 +黄米 1 +x:1 +饲养户 1 +x:1 +总务厅 1 +x:1 +笼里 1 +x:1 +低垂 1 +x:1 +林产业 1 +x:1 +远涉重洋 1 +x:1 +切磋琢磨 1 +x:1 +一品锅 1 +x:1 +乾乾 1 +x:1 +讳莫如深 1 +x:1 +贼眼 1 +x:1 +失察 1 +x:1 +异物感 1 +x:1 +晕眩 1 +x:1 +失密 1 +x:1 +淋巴结 1 +x:1 +文绉绉 1 +x:1 +发明奖 1 +x:1 +暗室 1 +x:1 +专名号 1 +x:1 +歌赋 1 +x:1 +现象学 1 +x:1 +皮夹 1 +x:1 +暗害 1 +x:1 +壮丁 1 +x:1 +歌赞 1 +x:1 +葡萄牙队 1 +x:1 +警服 1 +x:1 +老伴 1 +x:1 +暗密 1 +x:1 +仁化县 1 +x:1 +鼷鼠 1 +x:1 +裸鼠 1 +x:1 +失实 1 +x:1 +以资代劳 1 +x:1 +一脉相承 1 +x:1 +英魂 1 +x:1 +写作 1 +x:1 +准将 1 +x:1 +上手 1 +x:1 +暗察 1 +x:1 +失守 1 +x:1 +夸夸其谈 1 +x:1 +田塍 1 +x:1 +割地 1 +x:1 +习书 1 +x:1 +祷告 1 +x:1 +面包块 1 +x:1 +上扬 1 +x:1 +失宠 1 +x:1 +大器晚成 1 +x:1 +劳动日 1 +x:1 +举组 1 +x:1 +专馆 1 +x:1 +手工钱 1 +x:1 +和谐感 1 +x:1 +宅 6 +x:6 +惹不起 1 +x:1 +灯节 1 +x:1 +实策 1 +x:1 +登山界 1 +x:1 +喷珠泻玉 1 +x:1 +照面 1 +x:1 +田径 1 +x:1 +火龙 1 +x:1 +上文 1 +x:1 +波密县 1 +x:1 +犟 5 +x:5 +谠 1 +x:1 +上方 1 +x:1 +保证书 1 +x:1 +反刍 1 +x:1 +输水管线 1 +x:1 +镜 24 +x:24 +先知先觉 1 +x:1 +科研处 1 +x:1 +首善之区 1 +x:1 +上中旬 1 +x:1 +东坡 1 +x:1 +感光片 1 +x:1 +迈入 1 +x:1 +刘海儿 1 +x:1 +嚣张 1 +x:1 +西门豹 1 +x:1 +心急如焚 1 +x:1 +汤汤 1 +x:1 +乌 122 +x:122 +汤池 1 +x:1 +弹力袜 1 +x:1 +劳动所 1 +x:1 +提及 1 +x:1 +海韵 1 +x:1 +原峰村 1 +x:1 +香烟 1 +x:1 +灯苗 1 +x:1 +浅浅的 1 +x:1 +微毒 1 +x:1 +红领巾 1 +x:1 +细碎 1 +x:1 +倾轧 1 +x:1 +在望 1 +x:1 +译稿 1 +x:1 +高帽儿 1 +x:1 +两全其美 1 +x:1 +警惕 1 +x:1 +敦 2 +x:2 +除此之外 1 +x:1 +室内外 1 +x:1 +上旬 1 +x:1 +入梅 1 +x:1 +鲜红 1 +x:1 +警情 1 +x:1 +末段 1 +x:1 +瓯海 1 +x:1 +跑位 1 +x:1 +红砖黛瓦 1 +x:1 +亚洲象 1 +x:1 +收益值 1 +x:1 +龙井村 1 +x:1 +西 424 +x:424 +绣墩草 1 +x:1 +特钢 1 +x:1 +葫芦岛市 1 +x:1 +反动 1 +x:1 +专制 1 +x:1 +江苏 1 +x:1 +灯舞 1 +x:1 +怒海 1 +x:1 +等同 1 +x:1 +人造花 1 +x:1 +直升 1 +x:1 +神经末梢 1 +x:1 +一无所画 1 +x:1 +迈出 1 +x:1 +精品库 1 +x:1 +菇种 1 +x:1 +精品店 1 +x:1 +嘴脸 1 +x:1 +管理 1 +x:1 +电流 1 +x:1 +上收 1 +x:1 +冤魂 1 +x:1 +皮带 1 +x:1 +怜 4 +x:4 +唱 396 +x:396 +中药师 1 +x:1 +皮帽 1 +x:1 +翩然而至 1 +x:1 +用膳 1 +x:1 +飓风 1 +x:1 +商厦队 1 +x:1 +地质部 1 +x:1 +一枕黄粱 1 +x:1 +海面 1 +x:1 +暖气片 1 +x:1 +蝴蝶谷 1 +x:1 +工程团 1 +x:1 +着意 1 +x:1 +警惕性 1 +x:1 +匪帮 1 +x:1 +派遣军 1 +x:1 +真相者 1 +x:1 +侨校 1 +x:1 +科技兴农 1 +x:1 +呼应 1 +x:1 +明信片 1 +x:1 +汤泉 1 +x:1 +财税 1 +x:1 +系统 1 +x:1 +火坑 1 +x:1 +快班 1 +x:1 +铜陵市 1 +x:1 +生离死别 1 +x:1 +主理 1 +x:1 +香灰 1 +x:1 +保证人 1 +x:1 +工字钢 1 +x:1 +张榜 1 +x:1 +毛织品 1 +x:1 +北疆 1 +x:1 +中环线 1 +x:1 +汗津津 1 +x:1 +离石市 1 +x:1 +委托书 1 +x:1 +手腕子 1 +x:1 +田庄 1 +x:1 +尖 19 +x:19 +海难 1 +x:1 +燕山街 1 +x:1 +霜 20 +x:20 +乏意 1 +x:1 +蒙昧主义 1 +x:1 +实空 1 +x:1 +亲日派 1 +x:1 +歌诀 1 +x:1 +一般说来 1 +x:1 +歌词 1 +x:1 +激扬 1 +x:1 +乌拉 1 +x:1 +钱 2985 +x:2985 +际会 1 +x:1 +升旗台 1 +x:1 +积压货 1 +x:1 +夹子 1 +x:1 +竹排 1 +x:1 +回购 1 +x:1 +由浅入深 1 +x:1 +参与感 1 +x:1 +刑释解教 1 +x:1 +先 990 +x:990 +设计员 1 +x:1 +概念比 1 +x:1 +科普站 1 +x:1 +语言者 1 +x:1 +巨狮 1 +x:1 +特长 1 +x:1 +鲜美 1 +x:1 +基金会 1 +x:1 +汤浴 1 +x:1 +翠竹 1 +x:1 +携起手来 1 +x:1 +解 175 +x:175 +免检 1 +x:1 +如锥镗沙 1 +x:1 +鸡摊 1 +x:1 +沉水植物 1 +x:1 +匪徒 1 +x:1 +拍凤裕庭 1 +x:1 +铬矿砂 1 +x:1 +惊为天人 1 +x:1 +历史科 1 +x:1 +京味 1 +x:1 +一锅粥 1 +x:1 +拉车 1 +x:1 +指导线 1 +x:1 +选 493 +x:493 +管用 1 +x:1 +秋天 1 +x:1 +违法乱纪 1 +x:1 +东四 1 +x:1 +东映像 1 +x:1 +清热利肺 1 +x:1 +海防 1 +x:1 +南朝鲜 1 +x:1 +浩荡 1 +x:1 +柔韧 1 +x:1 +铅玻璃 1 +x:1 +经营者 1 +x:1 +火鸡 1 +x:1 +偶遇 1 +x:1 +提高 1 +x:1 +宣传期 1 +x:1 +遣词用句 1 +x:1 +放牛郎 1 +x:1 +读报栏 1 +x:1 +柳杨堡 1 +x:1 +北电 1 +x:1 +绣球风 1 +x:1 +东园 1 +x:1 +砚山县 1 +x:1 +名位观 1 +x:1 +百年大计 1 +x:1 +睇 1 +x:1 +谭概 1 +x:1 +拉近 1 +x:1 +枝形 1 +x:1 +兵种 1 +x:1 +海陵 1 +x:1 +海印队 1 +x:1 +委托人 1 +x:1 +反右 1 +x:1 +老边区 1 +x:1 +删去 1 +x:1 +潜留 1 +x:1 +南澳县 1 +x:1 +随访 1 +x:1 +烟费 1 +x:1 +二手车 1 +x:1 +退休返聘 1 +x:1 +天台乌药 1 +x:1 +管界 1 +x:1 +远处 1 +x:1 +潜热 1 +x:1 +河身 1 +x:1 +耗子屎 1 +x:1 +拘板 1 +x:1 +烟贩 1 +x:1 +皮影 1 +x:1 +杂志费 1 +x:1 +指导组 1 +x:1 +巨片 1 +x:1 +反叛 1 +x:1 +知难而进 1 +x:1 +考古所 1 +x:1 +指挥者 1 +x:1 +大有作为 1 +x:1 +浅薄 1 +x:1 +上林 1 +x:1 +负于 1 +x:1 +住院日 1 +x:1 +镀金 1 +x:1 +— 1865 +x:1865 +俊雅 1 +x:1 +校运会 1 +x:1 +多 18209 +x:18209 +避重就轻 1 +x:1 +定补面 1 +x:1 +在教 1 +x:1 +措词 1 +x:1 +镜匾 1 +x:1 +上架 1 +x:1 +兰州市 1 +x:1 +赛后 1 +x:1 +虫害 1 +x:1 +详考 1 +x:1 +镜匣 1 +x:1 +死亡者 1 +x:1 +反倒 1 +x:1 +淡路岛 1 +x:1 +半山腰 1 +x:1 +一无所知 1 +x:1 +过时 1 +x:1 +硬着陆 1 +x:1 +待岗证 1 +x:1 +黑白分明 1 +x:1 +海门 1 +x:1 +柑 6 +x:6 +冥寿 1 +x:1 +导报 1 +x:1 +成人版 1 +x:1 +热值 1 +x:1 +慢镜头 1 +x:1 +悬梁刺股 1 +x:1 +别具一格 1 +x:1 +反假 1 +x:1 +鸡杂 1 +x:1 +配备率 1 +x:1 +激愤 1 +x:1 +快煤 1 +x:1 +璐 10 +x:10 +兑付 1 +x:1 +旺销 1 +x:1 +采育镇 1 +x:1 +不辞辛苦 1 +x:1 +禄劝 1 +x:1 +乙丙橡胶 1 +x:1 +两院一堂 1 +x:1 +精品屋 1 +x:1 +七·七 1 +x:1 +厄音 1 +x:1 +上期 1 +x:1 +甚么 1 +x:1 +心劲 1 +x:1 +醒目 1 +x:1 +亭台楼阁 1 +x:1 +助推器 1 +x:1 +上月 1 +x:1 +家属院 1 +x:1 +一号机 1 +x:1 +出走 1 +x:1 +练笔 1 +x:1 +杀菌率 1 +x:1 +警戒 1 +x:1 +军事部 1 +x:1 +细究 1 +x:1 +开诚相见 1 +x:1 +萨雷沙干 1 +x:1 +收费点 1 +x:1 +后勤组 1 +x:1 +符庄村 1 +x:1 +皮尺 1 +x:1 +蒙蔽 1 +x:1 +一声不响 1 +x:1 +俯视 1 +x:1 +下丘脑 1 +x:1 +人多势众 1 +x:1 +兵站 1 +x:1 +电话铃 1 +x:1 +京城 1 +x:1 +诗作品 1 +x:1 +皮层 1 +x:1 +部门 1 +x:1 +香片 1 +x:1 +回赠 1 +x:1 +虫子 1 +x:1 +割刀 1 +x:1 +准备 1 +x:1 +雪地车 1 +x:1 +瓜 49 +x:49 +毛演堡村 1 +x:1 +准头 1 +x:1 +镜台 1 +x:1 +函 73 +x:73 +增盈减亏 1 +x:1 +语言学家 1 +x:1 +硅二极管 1 +x:1 +夹墙 1 +x:1 +上杭 1 +x:1 +邮坛 1 +x:1 +克制 1 +x:1 +甚为 1 +x:1 +皮山 1 +x:1 +征南战北 1 +x:1 +河豚 1 +x:1 +失当 1 +x:1 +军事学 1 +x:1 +细密画 1 +x:1 +翠碧 1 +x:1 +爱琴海 1 +x:1 +残雪 1 +x:1 +独山子 1 +x:1 +手术产 1 +x:1 +爵位 1 +x:1 +警探 1 +x:1 +宜果则果 1 +x:1 +莫尔特克 1 +x:1 +吹鼓手 1 +x:1 +婉而多讽 1 +x:1 +海底 1 +x:1 +乳钵 1 +x:1 +惶恐 1 +x:1 +海钓 1 +x:1 +报警亭 1 +x:1 +纤维板 1 +x:1 +兵符 1 +x:1 +东周 1 +x:1 +彀 1 +x:1 +乙双吗啉 1 +x:1 +冰雪崩 1 +x:1 +黄泥岗镇 1 +x:1 +买通 1 +x:1 +堡子村 1 +x:1 +人生感 1 +x:1 +激怒 1 +x:1 +例言 1 +x:1 +反共 1 +x:1 +值日表 1 +x:1 +微电子业 1 +x:1 +图尔库 1 +x:1 +留学生 1 +x:1 +现职 1 +x:1 +注射器 1 +x:1 +雇请 1 +x:1 +末梢 1 +x:1 +东吴 1 +x:1 +北辰区 1 +x:1 +河谷 1 +x:1 +反先 1 +x:1 +经常化 1 +x:1 +报警仪 1 +x:1 +日复一日 1 +x:1 +混 43 +x:43 +碱度 1 +x:1 +海流河乡 1 +x:1 +倍增 1 +x:1 +隐藏所 1 +x:1 +反党 1 +x:1 +叫苦不迭 1 +x:1 +修订稿 1 +x:1 +禄 5 +x:5 +视察团 1 +x:1 +激情 1 +x:1 +保险箱 1 +x:1 +小天鹅 1 +x:1 +提到 1 +x:1 +早报 1 +x:1 +哭喊声 1 +x:1 +头数 1 +x:1 +惶惶 1 +x:1 +失忆 1 +x:1 +理直气壮 1 +x:1 +蹲位 1 +x:1 +上昆 1 +x:1 +利己主义 1 +x:1 +二手货 1 +x:1 +片言只字 1 +x:1 +删减 1 +x:1 +多子多孙 1 +x:1 +惶惑 1 +x:1 +微格 1 +x:1 +久慕盛名 1 +x:1 +溶 9 +x:9 +快点 1 +x:1 +负伤 1 +x:1 +上映 1 +x:1 +甚佳 1 +x:1 +秋季 1 +x:1 +经济核算 1 +x:1 +硝化 1 +x:1 +枞阳县 1 +x:1 +庐山路 1 +x:1 +银碟 1 +x:1 +跌 230 +x:230 +巨灵 1 +x:1 +残阳 1 +x:1 +房改办 1 +x:1 +仁义道德 1 +x:1 +财礼 1 +x:1 +碎石 1 +x:1 +反击 1 +x:1 +上晃 1 +x:1 +补 224 +x:224 +信标 1 +x:1 +细胞壁 1 +x:1 +底本 1 +x:1 +演出费 1 +x:1 +投资法 1 +x:1 +设计图 1 +x:1 +饱满 1 +x:1 +客货运量 1 +x:1 +墙灰 1 +x:1 +撒欢儿 1 +x:1 +口哨 1 +x:1 +六一 1 +x:1 +农金 1 +x:1 +何况 1 +x:1 +高次方程 1 +x:1 +证婚 1 +x:1 +副题 1 +x:1 +朱文 1 +x:1 +三绝 1 +x:1 +蛮荒 1 +x:1 +联盟制 1 +x:1 +国家教委 1 +x:1 +血色 1 +x:1 +了无惧色 1 +x:1 +恶劣性 1 +x:1 +笔尖 1 +x:1 +打眼 1 +x:1 +刺刀 1 +x:1 +薄礼 1 +x:1 +公开信 1 +x:1 +流通券 1 +x:1 +不得不 1 +x:1 +兰桥 1 +x:1 +服务器 1 +x:1 +密闭 1 +x:1 +堰岭 1 +x:1 +复兴区 1 +x:1 +肥壮 1 +x:1 +坊会 1 +x:1 +案源 1 +x:1 +沤肥 1 +x:1 +纸鹤 1 +x:1 +副食 1 +x:1 +泡辣椒 1 +x:1 +走失 1 +x:1 +月华 1 +x:1 +目睹式 1 +x:1 +地狱谷 1 +x:1 +鹭江道 1 +x:1 +爻 1 +x:1 +透不过气 1 +x:1 +进修生 1 +x:1 +瓣 16 +x:16 +六书 1 +x:1 +癫痫 1 +x:1 +调性 1 +x:1 +果柄 1 +x:1 +催泪弹 1 +x:1 +兼备 1 +x:1 +底气十足 1 +x:1 +履穿踵决 1 +x:1 +一放了之 1 +x:1 +商机 1 +x:1 +即若 1 +x:1 +愁 83 +x:83 +金属漆 1 +x:1 +工作站 1 +x:1 +核物理 1 +x:1 +超社会 1 +x:1 +新生 1 +x:1 +豹纹 1 +x:1 +公休日 1 +x:1 +入情入理 1 +x:1 +5 2486 +x:2486 +九所 1 +x:1 +口味 1 +x:1 +没脸 1 +x:1 +或褒或贬 1 +x:1 +月历 1 +x:1 +泄 9 +x:9 +启发性 1 +x:1 +自暴自弃 1 +x:1 +便后 1 +x:1 +国际象棋 1 +x:1 +困顿 1 +x:1 +捅捅 1 +x:1 +服务团 1 +x:1 +不治之症 1 +x:1 +贬值 1 +x:1 +休戚相关 1 +x:1 +轻视 1 +x:1 +可兑换性 1 +x:1 +淄博市 1 +x:1 +富阳市 1 +x:1 +头胸部 1 +x:1 +何其 1 +x:1 +威名 1 +x:1 +地质学界 1 +x:1 +落叶归根 1 +x:1 +废盐 1 +x:1 +口吻 1 +x:1 +威吓 1 +x:1 +录 46 +x:46 +剪除 1 +x:1 +阿尔甘德 1 +x:1 +板正 1 +x:1 +盛服 1 +x:1 +惊弓之鸟 1 +x:1 +飞虎队 1 +x:1 +先售后股 1 +x:1 +商末 1 +x:1 +先导型 1 +x:1 +汇编本 1 +x:1 +利农村 1 +x:1 +口吃 1 +x:1 +唱主角 1 +x:1 +月台 1 +x:1 +输液厅 1 +x:1 +拉合尔 1 +x:1 +学习者 1 +x:1 +铜钵村 1 +x:1 +楚河汉界 1 +x:1 +违约 1 +x:1 +副项 1 +x:1 +挑唆 1 +x:1 +自杀者 1 +x:1 +办报 1 +x:1 +诺萨斯 1 +x:1 +违纪 1 +x:1 +林茂粮丰 1 +x:1 +社社 1 +x:1 +月初 1 +x:1 +中篇 1 +x:1 +乱真 1 +x:1 +月刊 1 +x:1 +卡面 1 +x:1 +虽生弗生 1 +x:1 +小名头 1 +x:1 +君王 1 +x:1 +攘 2 +x:2 +致病 1 +x:1 +合同工 1 +x:1 +房地产业 1 +x:1 +女方 1 +x:1 +田畴 1 +x:1 +炉前工 1 +x:1 +善报 1 +x:1 +呈请 1 +x:1 +尊亲 1 +x:1 +高桥堰村 1 +x:1 +棕绿色 1 +x:1 +月利 1 +x:1 +臼齿 1 +x:1 +竖吹 1 +x:1 +夜饭 1 +x:1 +急诊科 1 +x:1 +胁 2 +x:2 +旷日持久 1 +x:1 +垛子 1 +x:1 +有翅蚜 1 +x:1 +夜餐 1 +x:1 +垃圾猪 1 +x:1 +缓冲器 1 +x:1 +乍暖还寒 1 +x:1 +晶亮 1 +x:1 +含沙射影 1 +x:1 +相交处 1 +x:1 +龙卷风 1 +x:1 +银鱼 1 +x:1 +关税壁垒 1 +x:1 +体坛 1 +x:1 +气象学家 1 +x:1 +郑南 1 +x:1 +堆积体 1 +x:1 +顽固不化 1 +x:1 +应运 1 +x:1 +跳 229 +x:229 +化石群 1 +x:1 +单行路 1 +x:1 +雨 297 +x:297 +水尺 1 +x:1 +侍候 1 +x:1 +积毁销骨 1 +x:1 +膀 1 +x:1 +麦哲伦 1 +x:1 +宗教徒 1 +x:1 +凉碟 1 +x:1 +不念旧恶 1 +x:1 +肥大 1 +x:1 +咎 1 +x:1 +结怨 1 +x:1 +善战 1 +x:1 +愣神儿 1 +x:1 +壁龛 1 +x:1 +西二环路 1 +x:1 +中国海 1 +x:1 +橡树叶 1 +x:1 +揶揄 1 +x:1 +致畸 1 +x:1 +备课 1 +x:1 +卧地磐石 1 +x:1 +候机楼 1 +x:1 +防范金 1 +x:1 +身价百倍 1 +x:1 +体型 1 +x:1 +悠久 1 +x:1 +尊严 1 +x:1 +先行者 1 +x:1 +硬骨鱼 1 +x:1 +盛景 1 +x:1 +豆腐脑儿 1 +x:1 +怯场 1 +x:1 +漳平 1 +x:1 +隔板 1 +x:1 +阐述 1 +x:1 +哗众取宠 1 +x:1 +拒绝率 1 +x:1 +酋 1 +x:1 +总鳍鱼 1 +x:1 +团中央 1 +x:1 +十八时 1 +x:1 +嵌入式 1 +x:1 +穆斯林 1 +x:1 +结息 1 +x:1 +科索沃省 1 +x:1 +敌焰 1 +x:1 +蚕室 1 +x:1 +服务型 1 +x:1 +柞绢 1 +x:1 +刺史 1 +x:1 +磐安 1 +x:1 +乱石 1 +x:1 +电视大学 1 +x:1 +社科 1 +x:1 +一误再误 1 +x:1 +小春 1 +x:1 +刺参 1 +x:1 +毫无二致 1 +x:1 +纱厂 1 +x:1 +晨风 1 +x:1 +弱视者 1 +x:1 +宇宙尘 1 +x:1 +呼饥号寒 1 +x:1 +扁鱼 1 +x:1 +笔帽 1 +x:1 +服务员 1 +x:1 +救人 1 +x:1 +侍卫 1 +x:1 +社稷 1 +x:1 +兼学 1 +x:1 +萎陷疗法 1 +x:1 +桩桩 1 +x:1 +扭身 1 +x:1 +嵊州籍 1 +x:1 +中型机 1 +x:1 +复兴党 1 +x:1 +后继者 1 +x:1 +双曲面 1 +x:1 +琤 1 +x:1 +田字格 1 +x:1 +根深叶茂 1 +x:1 +公使 1 +x:1 +同床异梦 1 +x:1 +泠泠 1 +x:1 +肠管 1 +x:1 +肥嫩 1 +x:1 +体味 1 +x:1 +槟榔 1 +x:1 +行宫 1 +x:1 +行家 1 +x:1 +公众 1 +x:1 +月光 1 +x:1 +公休 1 +x:1 +昏然 1 +x:1 +升位 1 +x:1 +单亲 1 +x:1 +公会 1 +x:1 +菜价 1 +x:1 +七步之才 1 +x:1 +身败名裂 1 +x:1 +拆毁 1 +x:1 +揽胜 1 +x:1 +决定书 1 +x:1 +天街 1 +x:1 +原子武器 1 +x:1 +流放者 1 +x:1 +绚丽多姿 1 +x:1 +新币 1 +x:1 +海狸鼠 1 +x:1 +禅机 1 +x:1 +温水村 1 +x:1 +原形 1 +x:1 +木椅 1 +x:1 +舻舳蔽水 1 +x:1 +女星 1 +x:1 +专用纸 1 +x:1 +建设期 1 +x:1 +避其所短 1 +x:1 +专用线 1 +x:1 +矮子 1 +x:1 +志丹县 1 +x:1 +高档化 1 +x:1 +摆放 1 +x:1 +栽种 1 +x:1 +专用章 1 +x:1 +敌特 1 +x:1 +中童装 1 +x:1 +暴潮 1 +x:1 +没什么 1 +x:1 +调拨 1 +x:1 +电磁能 1 +x:1 +公修 1 +x:1 +馓子 1 +x:1 +容错性 1 +x:1 +泸定桥 1 +x:1 +刑讯室 1 +x:1 +木槎 1 +x:1 +内乡县 1 +x:1 +尿崩症 1 +x:1 +变性 1 +x:1 +先民 1 +x:1 +公例 1 +x:1 +抱负 1 +x:1 +兼容 1 +x:1 +玉带桥 1 +x:1 +遭受 1 +x:1 +胎 22 +x:22 +知详者 1 +x:1 +取食 1 +x:1 +吗啡 1 +x:1 +检查组 1 +x:1 +盛放 1 +x:1 +回来 1 +x:1 +非理性 1 +x:1 +既有线 1 +x:1 +相隔 1 +x:1 +偷 138 +x:138 +大河岸 1 +x:1 +恢复费 1 +x:1 +驾驶座 1 +x:1 +见怪 1 +x:1 +思贤若渴 1 +x:1 +脸红 1 +x:1 +梭 6 +x:6 +秘鲁 1 +x:1 +木桶 1 +x:1 +隔断 1 +x:1 +密集 1 +x:1 +服务商 1 +x:1 +国际歌 1 +x:1 +一方有难 1 +x:1 +攀高 1 +x:1 +木桥 1 +x:1 +排龙乡到 1 +x:1 +晚上 1 +x:1 +鉴定界 1 +x:1 +调换 1 +x:1 +面筋质 1 +x:1 +潜移默化 1 +x:1 +牡蛎 1 +x:1 +挟洋自重 1 +x:1 +肥实 1 +x:1 +贴 185 +x:185 +木桌 1 +x:1 +中继站 1 +x:1 +木框 1 +x:1 +费尽心机 1 +x:1 +锦绣河山 1 +x:1 +传习所 1 +x:1 +楚雄 1 +x:1 +简单易行 1 +x:1 +卫生化 1 +x:1 +池杉株 1 +x:1 +姓名牌 1 +x:1 +音乐界 1 +x:1 +转益多师 1 +x:1 +隔日 1 +x:1 +一言九鼎 1 +x:1 +走极端 1 +x:1 +口型 1 +x:1 +振聋发聩 1 +x:1 +史纲 1 +x:1 +秧 13 +x:13 +暖乎乎 1 +x:1 +机遇 1 +x:1 +原平 1 +x:1 +旨在 1 +x:1 +联盟党 1 +x:1 +捐款额 1 +x:1 +浴 10 +x:10 +大鼻子 1 +x:1 +感知 1 +x:1 +平度市 1 +x:1 +公主 1 +x:1 +木栅 1 +x:1 +公仆 1 +x:1 +棉垛 1 +x:1 +柱基 1 +x:1 +对立面 1 +x:1 +裤带 1 +x:1 +力不从心 1 +x:1 +工作科 1 +x:1 +五音不全 1 +x:1 +缎带 1 +x:1 +财政危机 1 +x:1 +小气鬼 1 +x:1 +押加 1 +x:1 +商业界 1 +x:1 +风险金 1 +x:1 +初涉 1 +x:1 +佩纳斯科 1 +x:1 +辉锑矿 1 +x:1 +军转民 1 +x:1 +窦 28 +x:28 +板栗 1 +x:1 +结成 1 +x:1 +岳麓山 1 +x:1 +欧安会 1 +x:1 +遭劫 1 +x:1 +肉豆蔻 1 +x:1 +团扇鳐 1 +x:1 +昌图县 1 +x:1 +木棉 1 +x:1 +曲解 1 +x:1 +垸 1 +x:1 +正门 1 +x:1 +杨家门 1 +x:1 +单件 1 +x:1 +叹息 1 +x:1 +木梳 1 +x:1 +维修站 1 +x:1 +公事 1 +x:1 +木梯 1 +x:1 +备要 1 +x:1 +女权 1 +x:1 +板桥 1 +x:1 +卫生厅 1 +x:1 +公产 1 +x:1 +公交 1 +x:1 +女板 1 +x:1 +单复数 1 +x:1 +单一化 1 +x:1 +河池市 1 +x:1 +女杰 1 +x:1 +调控 1 +x:1 +公亩 1 +x:1 +悉尼市 1 +x:1 +结扎 1 +x:1 +善恶 1 +x:1 +公人 1 +x:1 +笔心 1 +x:1 +航星队 1 +x:1 +卫生员 1 +x:1 +利息 1 +x:1 +秤钩 1 +x:1 +番茄丁 1 +x:1 +体制 1 +x:1 +昏睡 1 +x:1 +牺牲品 1 +x:1 +竞开 1 +x:1 +原处 1 +x:1 +古城子镇 1 +x:1 +农闲 1 +x:1 +梦湖 1 +x:1 +禁书 1 +x:1 +瓜州 1 +x:1 +涟水县 1 +x:1 +焊钳 1 +x:1 +开夜车 1 +x:1 +泄愤 1 +x:1 +熹 2 +x:2 +四季青村 1 +x:1 +胸章 1 +x:1 +农门 1 +x:1 +钻天猴 1 +x:1 +翁牛特旗 1 +x:1 +月坛 1 +x:1 +禅意 1 +x:1 +翰林 1 +x:1 +昏眩 1 +x:1 +浆 11 +x:11 +梦游 1 +x:1 +牺牲者 1 +x:1 +音乐版 1 +x:1 +三不做 1 +x:1 +质 120 +x:120 +加格拉 1 +x:1 +共济 1 +x:1 +目无余子 1 +x:1 +冒汗 1 +x:1 +引人入胜 1 +x:1 +服务制 1 +x:1 +童话国 1 +x:1 +汨罗 1 +x:1 +虚度年华 1 +x:1 +开饭 1 +x:1 +购画者 1 +x:1 +废物 1 +x:1 +时年 1 +x:1 +单性花 1 +x:1 +湾内 1 +x:1 +美其名曰 1 +x:1 +国际法 1 +x:1 +都匀 1 +x:1 +开馆 1 +x:1 +链轮 1 +x:1 +翩跹起舞 1 +x:1 +晴转多云 1 +x:1 +助贫 1 +x:1 +笔墨 1 +x:1 +货币率 1 +x:1 +搬运车 1 +x:1 +锦功 1 +x:1 +工作组 1 +x:1 +体力 1 +x:1 +善本 1 +x:1 +进贤县 1 +x:1 +叹服 1 +x:1 +老同事 1 +x:1 +起伏 1 +x:1 +无从谈起 1 +x:1 +舱门 1 +x:1 +赞成度 1 +x:1 +满目荆榛 1 +x:1 +帅印 1 +x:1 +路风 1 +x:1 +立法 1 +x:1 +江海区 1 +x:1 +紫苏 1 +x:1 +堰塘 1 +x:1 +目录厅 1 +x:1 +石龙子 1 +x:1 +工业学系 1 +x:1 +冒泡 1 +x:1 +评奖会 1 +x:1 +绚丽多彩 1 +x:1 +私货 1 +x:1 +飨 22 +x:22 +损害 1 +x:1 +马滴达乡 1 +x:1 +片尾 1 +x:1 +酹 1 +x:1 +隔扇 1 +x:1 +公之于众 1 +x:1 +中州韵 1 +x:1 +婿 1 +x:1 +参资 1 +x:1 +急弯 1 +x:1 +琼枝 1 +x:1 +笔头 1 +x:1 +岁首 1 +x:1 +娄烦县 1 +x:1 +万元郎 1 +x:1 +调教 1 +x:1 +甚焉者 1 +x:1 +通高 1 +x:1 +提兜 1 +x:1 +情理之中 1 +x:1 +结晶水 1 +x:1 +出言不逊 1 +x:1 +机防 1 +x:1 +洒脱 1 +x:1 +积累 1 +x:1 +横飞 1 +x:1 +匹配 1 +x:1 +庄禾集村 1 +x:1 +花斑癣 1 +x:1 +起事 1 +x:1 +绿茵茵 1 +x:1 +服务卡 1 +x:1 +虚设 1 +x:1 +机队 1 +x:1 +初次 1 +x:1 +纽 2 +x:2 +算式 1 +x:1 +出版量 1 +x:1 +开裆裤 1 +x:1 +飘泊者 1 +x:1 +虚词 1 +x:1 +敬老爱幼 1 +x:1 +观后感 1 +x:1 +斯尔比察 1 +x:1 +服务化 1 +x:1 +网球赛 1 +x:1 +海鞘 1 +x:1 +钻井工 1 +x:1 +铅中毒 1 +x:1 +天轴 1 +x:1 +平民化 1 +x:1 +起价 1 +x:1 +私费 1 +x:1 +虚诞 1 +x:1 +脏活 1 +x:1 +安葬地 1 +x:1 +天轮 1 +x:1 +专用票 1 +x:1 +应该 1 +x:1 +西红门镇 1 +x:1 +楼梯式 1 +x:1 +靳村乡 1 +x:1 +天车 1 +x:1 +板滞 1 +x:1 +序曲 1 +x:1 +亭榭 1 +x:1 +笔套 1 +x:1 +夏锄 1 +x:1 +高中层 1 +x:1 +初步 1 +x:1 +宗教学 1 +x:1 +外祖母 1 +x:1 +体协 1 +x:1 +应诉 1 +x:1 +锚喷 1 +x:1 +防护门 1 +x:1 +走读 1 +x:1 +天边 1 +x:1 +菲央行 1 +x:1 +棉农 1 +x:1 +廓落 1 +x:1 +陪伴 1 +x:1 +秤锤 1 +x:1 +单个 1 +x:1 +凉粉 1 +x:1 +银小丑 1 +x:1 +献辞 1 +x:1 +慧黠 1 +x:1 +医药品 1 +x:1 +开题 1 +x:1 +分散型 1 +x:1 +没落 1 +x:1 +踩高跷 1 +x:1 +空谷足音 1 +x:1 +初段 1 +x:1 +服务台 1 +x:1 +总统府 1 +x:1 +弧 3 +x:3 +百货大楼 1 +x:1 +台北县 1 +x:1 +臀部 1 +x:1 +印次 1 +x:1 +腌腊 1 +x:1 +评理 1 +x:1 +躲 70 +x:70 +绍兴戏 1 +x:1 +龙蟠虎踞 1 +x:1 +上周四 1 +x:1 +参赛 1 +x:1 +焊锡 1 +x:1 +培养液 1 +x:1 +泰顺县 1 +x:1 +顾主 1 +x:1 +常务董事 1 +x:1 +三不准 1 +x:1 +交叉步 1 +x:1 +禁例 1 +x:1 +盟 31 +x:31 +缺斤少两 1 +x:1 +俗世 1 +x:1 +调料 1 +x:1 +西东 1 +x:1 +服务厅 1 +x:1 +侥幸 1 +x:1 +失落感 1 +x:1 +馋嘴 1 +x:1 +瞻瞩 1 +x:1 +氯气 1 +x:1 +九月 1 +x:1 +行将 1 +x:1 +会理县 1 +x:1 +天远 1 +x:1 +贩毒 1 +x:1 +平方公里 1 +x:1 +起义 1 +x:1 +生殖细胞 1 +x:1 +电泵 1 +x:1 +急忙 1 +x:1 +喷雾器 1 +x:1 +公之于世 1 +x:1 +检查科 1 +x:1 +驾驶室 1 +x:1 +迪拜港 1 +x:1 +肥度 1 +x:1 +对抗战 1 +x:1 +时常 1 +x:1 +忽悠 1 +x:1 +庶人 1 +x:1 +木浦 1 +x:1 +初样 1 +x:1 +善断 1 +x:1 +夜鹰 1 +x:1 +肥床 1 +x:1 +人身 1 +x:1 +战书 1 +x:1 +够交情 1 +x:1 +沃壤 1 +x:1 +舱面 1 +x:1 +谈话人 1 +x:1 +群众关系 1 +x:1 +不同点 1 +x:1 +木浆 1 +x:1 +炔诺酮 1 +x:1 +避免 1 +x:1 +柘城 1 +x:1 +夜鸟 1 +x:1 +乡局级 1 +x:1 +机长 1 +x:1 +曲调 1 +x:1 +天象 1 +x:1 +威力 1 +x:1 +鹤立鸡群 1 +x:1 +国家队 1 +x:1 +商业点 1 +x:1 +田间 1 +x:1 +利津县 1 +x:1 +冰灯展 1 +x:1 +郁金香 1 +x:1 +胯 1 +x:1 +桌子 1 +x:1 +洗车业 1 +x:1 +隐情 1 +x:1 +衢州市 1 +x:1 +寿桃 1 +x:1 +领养者 1 +x:1 +威势 1 +x:1 +副处级 1 +x:1 +燥热 1 +x:1 +裕后村 1 +x:1 +原定 1 +x:1 +乒协杯 1 +x:1 +厂报 1 +x:1 +预料 1 +x:1 +何地 1 +x:1 +冬不拉 1 +x:1 +进修班 1 +x:1 +何在 1 +x:1 +有法可依 1 +x:1 +磁碟 1 +x:1 +极乐世界 1 +x:1 +花卉园 1 +x:1 +初来乍到 1 +x:1 +液体 1 +x:1 +移居 1 +x:1 +机械部 1 +x:1 +行当 1 +x:1 +量脑 1 +x:1 +圆珠笔 1 +x:1 +战争 1 +x:1 +寿棺 1 +x:1 +团体赛 1 +x:1 +席卷一空 1 +x:1 +丰宁县 1 +x:1 +软骨鱼 1 +x:1 +白果树 1 +x:1 +战云 1 +x:1 +盛意 1 +x:1 +兼得 1 +x:1 +结束 1 +x:1 +解危济困 1 +x:1 +操作法 1 +x:1 +宦官 1 +x:1 +羊价 1 +x:1 +摧折 1 +x:1 +住宿 1 +x:1 +相片儿 1 +x:1 +陇穷村 1 +x:1 +检查站 1 +x:1 +后坐力 1 +x:1 +兰溪 1 +x:1 +歹毒 1 +x:1 +裤子 1 +x:1 +静电感应 1 +x:1 +兼并 1 +x:1 +通风 1 +x:1 +全球化史 1 +x:1 +指示牌 1 +x:1 +卜少 1 +x:1 +口口 1 +x:1 +女排 1 +x:1 +无坐力炮 1 +x:1 +兴义市 1 +x:1 +观测仪 1 +x:1 +中研院 1 +x:1 +槐乡 1 +x:1 +盛情 1 +x:1 +环湖 1 +x:1 +社会保险 1 +x:1 +口号 1 +x:1 +宿诺 1 +x:1 +眠 13 +x:13 +棉区 1 +x:1 +扁骨 1 +x:1 +艺海 1 +x:1 +晓谕 1 +x:1 +秧盘 1 +x:1 +九日 1 +x:1 +赞成 1 +x:1 +粮棉油 1 +x:1 +单元楼 1 +x:1 +腌菜 1 +x:1 +流下 1 +x:1 +癫狂 1 +x:1 +拓扑图 1 +x:1 +青岛籍 1 +x:1 +手无分文 1 +x:1 +粟子 1 +x:1 +东顺城街 1 +x:1 +万三蹄 1 +x:1 +旗 89 +x:89 +物探队 1 +x:1 +挑动 1 +x:1 +中继线 1 +x:1 +叛离 1 +x:1 +抛妻别子 1 +x:1 +娱心 1 +x:1 +战伤 1 +x:1 +蒋坝镇 1 +x:1 +喳喳 1 +x:1 +天赋 1 +x:1 +歙县 1 +x:1 +环游 1 +x:1 +托辞 1 +x:1 +部内 1 +x:1 +天资 1 +x:1 +策略师 1 +x:1 +塑就 1 +x:1 +何去何从 1 +x:1 +用汽量 1 +x:1 +横驶 1 +x:1 +行年 1 +x:1 +卫生城 1 +x:1 +天趣 1 +x:1 +社群 1 +x:1 +阡 3 +x:3 +冷藏柜 1 +x:1 +挑剔 1 +x:1 +马哈林诺 1 +x:1 +烧火 1 +x:1 +弱化 1 +x:1 +难民潮 1 +x:1 +调查 1 +x:1 +通顺 1 +x:1 +异种 1 +x:1 +楹联厅 1 +x:1 +体内 1 +x:1 +舒眉展眼 1 +x:1 +勘测 1 +x:1 +金属框 1 +x:1 +羊肚蕈 1 +x:1 +行帮 1 +x:1 +普通人 1 +x:1 +结晶 1 +x:1 +杭菊 1 +x:1 +口区 1 +x:1 +标致 1 +x:1 +挪用 1 +x:1 +天路 1 +x:1 +三不变 1 +x:1 +防伪字 1 +x:1 +网球迷 1 +x:1 +误诊记 1 +x:1 +牺牲地 1 +x:1 +束流线 1 +x:1 +盐铁论 1 +x:1 +菇类 1 +x:1 +云南府 1 +x:1 +种鸽场 1 +x:1 +锚地 1 +x:1 +玻璃缸 1 +x:1 +蓦地 1 +x:1 +兼具 1 +x:1 +开销 1 +x:1 +羊皮纸 1 +x:1 +懒惰 1 +x:1 +开锅 1 +x:1 +掷杯 1 +x:1 +流风余韵 1 +x:1 +认认真真 1 +x:1 +损坏 1 +x:1 +天地人 1 +x:1 +宗派主义 1 +x:1 +台北市 1 +x:1 +何妨 1 +x:1 +侍女 1 +x:1 +邱吉尔 1 +x:1 +开错 1 +x:1 +混流式 1 +x:1 +开锣 1 +x:1 +船位 1 +x:1 +服务年 1 +x:1 +调档 1 +x:1 +草蜻蛉 1 +x:1 +侍奉 1 +x:1 +曲艺 1 +x:1 +初春 1 +x:1 +约定 1 +x:1 +塑厂 1 +x:1 +内毒素 1 +x:1 +船体 1 +x:1 +接龙舞 1 +x:1 +决战 1 +x:1 +宣化区 1 +x:1 +邈远 1 +x:1 +磁场环 1 +x:1 +区划图 1 +x:1 +急剧 1 +x:1 +天色 1 +x:1 +蚊子 1 +x:1 +竞卖 1 +x:1 +群臣 1 +x:1 +社火 1 +x:1 +伪证 1 +x:1 +军纪 1 +x:1 +浴衣 1 +x:1 +专品 1 +x:1 +开镜 1 +x:1 +竞升 1 +x:1 +挪窝 1 +x:1 +半元音 1 +x:1 +佛教徒 1 +x:1 +游乐 1 +x:1 +低碳钢 1 +x:1 +礼金 1 +x:1 +玻璃窗门 1 +x:1 +恰 65 +x:65 +国际性 1 +x:1 +操作手 1 +x:1 +非地震 1 +x:1 +行军 1 +x:1 +积灰 1 +x:1 +入网费 1 +x:1 +镁砂 1 +x:1 +麸皮 1 +x:1 +天花 1 +x:1 +地震仪 1 +x:1 +急务 1 +x:1 +社民党 1 +x:1 +家风 1 +x:1 +肥胖儿 1 +x:1 +工作狂 1 +x:1 +迹地 1 +x:1 +引桥 1 +x:1 +波峰浪谷 1 +x:1 +及格率 1 +x:1 +定界符 1 +x:1 +废纸 1 +x:1 +瞪 17 +x:17 +难预测性 1 +x:1 +月宫 1 +x:1 +机炮舱 1 +x:1 +卓有成就 1 +x:1 +老干部 1 +x:1 +何处 1 +x:1 +有名无实 1 +x:1 +一次方程 1 +x:1 +光导纤维 1 +x:1 +酪酸 1 +x:1 +糜子 1 +x:1 +拷问 1 +x:1 +十全十美 1 +x:1 +偶 21 +x:21 +桂圆 1 +x:1 +鹏 1679 +x:1679 +拉手连心 1 +x:1 +毛估估 1 +x:1 +石龙坑 1 +x:1 +龙泉驿区 1 +x:1 +朦朦 1 +x:1 +分至点 1 +x:1 +内切圆 1 +x:1 +配套件 1 +x:1 +润物无声 1 +x:1 +木排 1 +x:1 +开门 1 +x:1 +信任 1 +x:1 +连续光谱 1 +x:1 +开间 1 +x:1 +防沙林 1 +x:1 +开闸 1 +x:1 +寝食难安 1 +x:1 +壮烈 1 +x:1 +剑桥市 1 +x:1 +备荒 1 +x:1 +蚕卵 1 +x:1 +电工室 1 +x:1 +初期 1 +x:1 +兽医 1 +x:1 +盎司 1 +x:1 +原名 1 +x:1 +避暑 1 +x:1 +寿木 1 +x:1 +尖扎县 1 +x:1 +板报 1 +x:1 +小名儿 1 +x:1 +怒潮 1 +x:1 +不知所终 1 +x:1 +财政资本 1 +x:1 +懒懒 1 +x:1 +勘探 1 +x:1 +共总 1 +x:1 +基本面 1 +x:1 +套色版 1 +x:1 +镪水 1 +x:1 +空无所有 1 +x:1 +体式 1 +x:1 +共性 1 +x:1 +法律性 1 +x:1 +走老路 1 +x:1 +梆子 1 +x:1 +易拉罐 1 +x:1 +嘴皮子 1 +x:1 +纸面 1 +x:1 +出席证 1 +x:1 +束手就擒 1 +x:1 +井岸镇 1 +x:1 +船主 1 +x:1 +争论 1 +x:1 +原告 1 +x:1 +影视厅 1 +x:1 +怀德县 1 +x:1 +药液 1 +x:1 +船上 1 +x:1 +波澜不惊 1 +x:1 +肠炎 1 +x:1 +可接受性 1 +x:1 +寿材 1 +x:1 +废置 1 +x:1 +船东 1 +x:1 +雪绒花 1 +x:1 +爱因斯坦 1 +x:1 +结核 1 +x:1 +清 465 +x:465 +商业网 1 +x:1 +肖 319 +x:319 +负电荷 1 +x:1 +在手 1 +x:1 +黄巷楼 1 +x:1 +臀鳍 1 +x:1 +石牌岭 1 +x:1 +迷魂汤 1 +x:1 +贩枪 1 +x:1 +制作者 1 +x:1 +凉炎 1 +x:1 +夜里 1 +x:1 +林芝 1 +x:1 +案板 1 +x:1 +维修点 1 +x:1 +机务连 1 +x:1 +楼梯口 1 +x:1 +花青色 1 +x:1 +家兴业旺 1 +x:1 +助老 1 +x:1 +冬春季 1 +x:1 +老弱病残 1 +x:1 +预支 1 +x:1 +铭牌 1 +x:1 +电工学 1 +x:1 +漠河 1 +x:1 +考评制 1 +x:1 +沃土 1 +x:1 +水合物 1 +x:1 +香榧子 1 +x:1 +女流 1 +x:1 +耗电量 1 +x:1 +狡兔三窟 1 +x:1 +磊落 1 +x:1 +批量 1 +x:1 +多神教 1 +x:1 +钙华池 1 +x:1 +浅尝辄止 1 +x:1 +磁石 1 +x:1 +结案 1 +x:1 +挑射 1 +x:1 +余干县 1 +x:1 +堂姐 1 +x:1 +游离态 1 +x:1 +中立党 1 +x:1 +驾驶员 1 +x:1 +立陶宛队 1 +x:1 +滞纳 1 +x:1 +威立队 1 +x:1 +竞赛奖 1 +x:1 +月夜 1 +x:1 +山洪暴发 1 +x:1 +棉帐 1 +x:1 +鼎 11 +x:11 +办案 1 +x:1 +服务局 1 +x:1 +操作性 1 +x:1 +同乡会 1 +x:1 +信得过 1 +x:1 +棉布 1 +x:1 +神经性 1 +x:1 +平台车 1 +x:1 +审 76 +x:76 +花乡 1 +x:1 +棉帽 1 +x:1 +体尝 1 +x:1 +偏心轮 1 +x:1 +马来熊 1 +x:1 +不大不小 1 +x:1 +始于 1 +x:1 +原地 1 +x:1 +赶浪头 1 +x:1 +肥力 1 +x:1 +悉尼城 1 +x:1 +颜面 1 +x:1 +瘤子 1 +x:1 +医药学 1 +x:1 +备耕 1 +x:1 +打封闭 1 +x:1 +平金 1 +x:1 +中短期 1 +x:1 +万象纷呈 1 +x:1 +取道 1 +x:1 +辅料展 1 +x:1 +倡办 1 +x:1 +蚬子 1 +x:1 +招 164 +x:164 +工务段 1 +x:1 +原址 1 +x:1 +空页 1 +x:1 +竖形 1 +x:1 +夏津县 1 +x:1 +受审 1 +x:1 +器 3 +x:3 +轶事 1 +x:1 +主园区 1 +x:1 +东交民巷 1 +x:1 +秘闻 1 +x:1 +天职 1 +x:1 +兼并史 1 +x:1 +体层 1 +x:1 +打的 1 +x:1 +悉尼型 1 +x:1 +铿 7 +x:7 +梦想 1 +x:1 +中食协 1 +x:1 +授课费 1 +x:1 +宁为玉碎 1 +x:1 +泰山压顶 1 +x:1 +建章 1 +x:1 +高级品 1 +x:1 +敌穴 1 +x:1 +路障 1 +x:1 +原型 1 +x:1 +小水村 1 +x:1 +主干路 1 +x:1 +严严实实 1 +x:1 +纸钱 1 +x:1 +矛盾律 1 +x:1 +积犯 1 +x:1 +建立 1 +x:1 +花面狸 1 +x:1 +槌响 1 +x:1 +顶住 1 +x:1 +壁钱 1 +x:1 +两麦一薯 1 +x:1 +嘉陵区 1 +x:1 +经警 1 +x:1 +木江坪乡 1 +x:1 +兼及 1 +x:1 +吓人 1 +x:1 +危亡之渐 1 +x:1 +炸火腿肠 1 +x:1 +领唱 1 +x:1 +鼾声 1 +x:1 +险段 1 +x:1 +红红的 1 +x:1 +瑰宝 1 +x:1 +动物淀粉 1 +x:1 +消费不起 1 +x:1 +日榨量 1 +x:1 +拓扑学 1 +x:1 +行包 1 +x:1 +吃得来 1 +x:1 +闷嘴葫芦 1 +x:1 +儒林村 1 +x:1 +兰报 1 +x:1 +维修班 1 +x:1 +自然科学 1 +x:1 +逢凶化吉 1 +x:1 +射阳湖镇 1 +x:1 +特异 1 +x:1 +脸皮 1 +x:1 +平邑 1 +x:1 +追源溯流 1 +x:1 +临江会 1 +x:1 +热地 1 +x:1 +建湖县 1 +x:1 +执教 1 +x:1 +开阔 1 +x:1 +驳壳枪 1 +x:1 +刺头 1 +x:1 +凉爽 1 +x:1 +象棋界 1 +x:1 +友谊馆 1 +x:1 +铁二局 1 +x:1 +宛城 1 +x:1 +开阳 1 +x:1 +撵 9 +x:9 +通铺 1 +x:1 +喀斯特 1 +x:1 +以火救火 1 +x:1 +帮爱 1 +x:1 +建筑 1 +x:1 +卫生学 1 +x:1 +暮秋 1 +x:1 +煤炭厅 1 +x:1 +权力关 1 +x:1 +首位 1 +x:1 +剡溪 1 +x:1 +茂敦 1 +x:1 +行动 1 +x:1 +寿数 1 +x:1 +再生稻 1 +x:1 +脸相 1 +x:1 +决意 1 +x:1 +崇高 1 +x:1 +铺盖卷 1 +x:1 +国产马 1 +x:1 +淙淙 1 +x:1 +胀大 1 +x:1 +开除 1 +x:1 +身宽体胖 1 +x:1 +顶事 1 +x:1 +脸盆 1 +x:1 +路面 1 +x:1 +口径 1 +x:1 +淡而无味 1 +x:1 +脸盘 1 +x:1 +侧室 1 +x:1 +整 140 +x:140 +按钮 1 +x:1 +急兔 1 +x:1 +塑像 1 +x:1 +一干打手 1 +x:1 +口形 1 +x:1 +砍 118 +x:118 +省人大 1 +x:1 +古马乡 1 +x:1 +阴山 1 +x:1 +食宿费 1 +x:1 +钤印 1 +x:1 +水墨画 1 +x:1 +承台梁 1 +x:1 +被窝儿 1 +x:1 +行前 1 +x:1 +非智力 1 +x:1 +寿斑 1 +x:1 +包村组 1 +x:1 +外经委 1 +x:1 +阴间 1 +x:1 +综合厂 1 +x:1 +合成纤维 1 +x:1 +标志牌 1 +x:1 +体己 1 +x:1 +口弦 1 +x:1 +拂逆众意 1 +x:1 +剑 73 +x:73 +志如磐石 1 +x:1 +辛德勒 1 +x:1 +踉踉跄跄 1 +x:1 +宽宽的 1 +x:1 +椽檩 1 +x:1 +横行霸道 1 +x:1 +体工 1 +x:1 +赞助人 1 +x:1 +蚕农 1 +x:1 +横队 1 +x:1 +消极性 1 +x:1 +左翼 1 +x:1 +兼办 1 +x:1 +困兽犹斗 1 +x:1 +顶上 1 +x:1 +亮亮的 1 +x:1 +导 19 +x:19 +行列 1 +x:1 +吃独食 1 +x:1 +葵 5 +x:5 +糌粑 1 +x:1 +百强县 1 +x:1 +卫生室 1 +x:1 +平遥 1 +x:1 +原因 1 +x:1 +没趣 1 +x:1 +取阅 1 +x:1 +童话库 1 +x:1 +意识形态 1 +x:1 +滞销品 1 +x:1 +希 24 +x:24 +切肤之感 1 +x:1 +卫生局 1 +x:1 +木条 1 +x:1 +板枣 1 +x:1 +棉堆 1 +x:1 +清炖 1 +x:1 +歹意 1 +x:1 +卫生山 1 +x:1 +区划办 1 +x:1 +乒乓馆 1 +x:1 +转折点 1 +x:1 +小洞不补 1 +x:1 +颍泉区 1 +x:1 +禹 8 +x:8 +领导权 1 +x:1 +修辞格 1 +x:1 +孤孤单单 1 +x:1 +凤凰村 1 +x:1 +共教 1 +x:1 +天花板 1 +x:1 +忧容 1 +x:1 +永安路 1 +x:1 +擢升 1 +x:1 +低薪者 1 +x:1 +木本 1 +x:1 +原先 1 +x:1 +执政者 1 +x:1 +路道 1 +x:1 +匀称 1 +x:1 +阿巴丹 1 +x:1 +量词 1 +x:1 +回销粮 1 +x:1 +数理学 1 +x:1 +黄漠漠 1 +x:1 +俭 12 +x:12 +授课证 1 +x:1 +冷气团 1 +x:1 +自由党 1 +x:1 +悄无声息 1 +x:1 +调水 1 +x:1 +立正 1 +x:1 +造血式 1 +x:1 +木柱 1 +x:1 +木柴 1 +x:1 +参会者 1 +x:1 +服务嫂 1 +x:1 +来来回回 1 +x:1 +稀饭 1 +x:1 +张午乡 1 +x:1 +游息 1 +x:1 +行商 1 +x:1 +长治县 1 +x:1 +木柜 1 +x:1 +废弃物 1 +x:1 +凉白开 1 +x:1 +迢迢长路 1 +x:1 +照射 1 +x:1 +旅行社 1 +x:1 +页岩砖 1 +x:1 +女校 1 +x:1 +转播权 1 +x:1 +平静 1 +x:1 +低劣 1 +x:1 +开采 1 +x:1 +天蛾 1 +x:1 +临城县 1 +x:1 +木架 1 +x:1 +心里话 1 +x:1 +开金 1 +x:1 +高祖母 1 +x:1 +犟头犟脑 1 +x:1 +挑夫 1 +x:1 +樊西 1 +x:1 +猩红热 1 +x:1 +岳麓区 1 +x:1 +箱根 1 +x:1 +部 1366 +x:1366 +初露端倪 1 +x:1 +板材 1 +x:1 +宣布 1 +x:1 +裤兜 1 +x:1 +行唐 1 +x:1 +风光旖旎 1 +x:1 +平面 1 +x:1 +违犯 1 +x:1 +鸡蛋黄 1 +x:1 +剿 3 +x:3 +雨花台区 1 +x:1 +灰蒙蒙 1 +x:1 +豹猫 1 +x:1 +歉疚 1 +x:1 +英国队 1 +x:1 +同性恋者 1 +x:1 +操作机 1 +x:1 +调流 1 +x:1 +乘胜前进 1 +x:1 +用事 1 +x:1 +热作所 1 +x:1 +棉帐篷 1 +x:1 +挚诚 1 +x:1 +堰内 1 +x:1 +开通 1 +x:1 +医药局 1 +x:1 +钻井液 1 +x:1 +原值 1 +x:1 +排污口 1 +x:1 +左海平湖 1 +x:1 +它们 1 +x:1 +牛仔裤 1 +x:1 +推销嫂 1 +x:1 +增田町 1 +x:1 +大本营 1 +x:1 +万象新 1 +x:1 +夏常服 1 +x:1 +请君入瓮 1 +x:1 +暴洪 1 +x:1 +紫菜苔 1 +x:1 +尾砂滩 1 +x:1 +评议面 1 +x:1 +食品业 1 +x:1 +棉套 1 +x:1 +测出 1 +x:1 +开道 1 +x:1 +照耀 1 +x:1 +高级化 1 +x:1 +循循诱人 1 +x:1 +清徐县 1 +x:1 +木星 1 +x:1 +油类 1 +x:1 +勘查 1 +x:1 +曲里拐弯 1 +x:1 +收教所 1 +x:1 +调派 1 +x:1 +油籽 1 +x:1 +囤仓 1 +x:1 +紧要期 1 +x:1 +伴生 1 +x:1 +东滩矿 1 +x:1 +磕碰 1 +x:1 +平阔 1 +x:1 +河西乡 1 +x:1 +亚运会 1 +x:1 +核蛋白 1 +x:1 +挡边 1 +x:1 +生产观 1 +x:1 +止步不前 1 +x:1 +何尝 1 +x:1 +翁当村 1 +x:1 +晨钟 1 +x:1 +卫生巾 1 +x:1 +平阳 1 +x:1 +沃卡 1 +x:1 +土堆儿 1 +x:1 +磁环 1 +x:1 +平阴 1 +x:1 +初探 1 +x:1 +通鉴 1 +x:1 +曲蟮 1 +x:1 +月度 1 +x:1 +权力型 1 +x:1 +买壳 1 +x:1 +磁探仪 1 +x:1 +水文站 1 +x:1 +春秋季 1 +x:1 +起起浮浮 1 +x:1 +滦南县 1 +x:1 +厌烦感 1 +x:1 +南张家 1 +x:1 +平陆 1 +x:1 +大局观 1 +x:1 +口头 1 +x:1 +腻体 1 +x:1 +战战兢兢 1 +x:1 +兰新 1 +x:1 +第二产业 1 +x:1 +体察 1 +x:1 +宗教史 1 +x:1 +整体而言 1 +x:1 +世青赛 1 +x:1 +重婚案 1 +x:1 +培养料 1 +x:1 +虚荣 1 +x:1 +高度计 1 +x:1 +曲 252 +x:252 +兽医站 1 +x:1 +对象性 1 +x:1 +结汇 1 +x:1 +仪观 1 +x:1 +平除 1 +x:1 +茶素 1 +x:1 +出人命 1 +x:1 +通量 1 +x:1 +撇 6 +x:6 +晨露 1 +x:1 +眼泡 1 +x:1 +透明胶 1 +x:1 +两面三刀 1 +x:1 +乱码 1 +x:1 +郁郁而终 1 +x:1 +冒昧 1 +x:1 +倔 1 +x:1 +按量 1 +x:1 +老把式 1 +x:1 +板斧 1 +x:1 +保障费 1 +x:1 +超声波 1 +x:1 +恩德培 1 +x:1 +案情 1 +x:1 +肥胖型 1 +x:1 +枝万段 1 +x:1 +板料 1 +x:1 +狼心狗肺 1 +x:1 +修缮处 1 +x:1 +批阅 1 +x:1 +双星队 1 +x:1 +向心力 1 +x:1 +高炮旅 1 +x:1 +果蔬脆片 1 +x:1 +没辙 1 +x:1 +投劳折资 1 +x:1 +疤痕 1 +x:1 +猪油果 1 +x:1 +匾 16 +x:16 +年历片 1 +x:1 +竖子 1 +x:1 +机收队 1 +x:1 +天葬 1 +x:1 +驾驶台 1 +x:1 +虚胖 1 +x:1 +电排闸 1 +x:1 +初恋 1 +x:1 +纳米比亚 1 +x:1 +侍弄 1 +x:1 +办水 1 +x:1 +芽秧 1 +x:1 +伞架 1 +x:1 +素食 1 +x:1 +前瞻性 1 +x:1 +何必 1 +x:1 +愤懑 1 +x:1 +卫生带 1 +x:1 +笔势 1 +x:1 +按 1765 +x:1765 +九江 1 +x:1 +交叉性 1 +x:1 +办法 1 +x:1 +罚款额 1 +x:1 +译作 1 +x:1 +扩散 1 +x:1 +平销 1 +x:1 +讲话稿 1 +x:1 +徐海 1 +x:1 +箱橱 1 +x:1 +挑子 1 +x:1 +树碑立传 1 +x:1 +仰人鼻息 1 +x:1 +笔力 1 +x:1 +行址 1 +x:1 +撑开 1 +x:1 +军令状 1 +x:1 +林业站 1 +x:1 +国优 1 +x:1 +国会 1 +x:1 +青阳县 1 +x:1 +国企 1 +x:1 +教务处 1 +x:1 +突然性 1 +x:1 +引以为戒 1 +x:1 +虚职 1 +x:1 +小米粥 1 +x:1 +木方 1 +x:1 +妒贤嫉能 1 +x:1 +平镜 1 +x:1 +都镇湾镇 1 +x:1 +城近郊区 1 +x:1 +光学录音 1 +x:1 +飞身 1 +x:1 +批零 1 +x:1 +滚柱轴承 1 +x:1 +矍铄 1 +x:1 +木料 1 +x:1 +声援 1 +x:1 +国体 1 +x:1 +大家鼠 1 +x:1 +原被告 1 +x:1 +流体 1 +x:1 +直抒胸臆 1 +x:1 +唐河县 1 +x:1 +一·二一 1 +x:1 +佳木斯 1 +x:1 +畜牧业 1 +x:1 +原初 1 +x:1 +兰村 1 +x:1 +原创 1 +x:1 +剪纸片 1 +x:1 +原则 1 +x:1 +服务奖 1 +x:1 +晨阳 1 +x:1 +国人 1 +x:1 +国交 1 +x:1 +国产 1 +x:1 +平针 1 +x:1 +胆矾 1 +x:1 +一念之差 1 +x:1 +黄绒绒的 1 +x:1 +收录机 1 +x:1 +偏听则暗 1 +x:1 +最大化 1 +x:1 +缠 23 +x:23 +双楼乡 1 +x:1 +固态氢 1 +x:1 +体外 1 +x:1 +驴打滚 1 +x:1 +陡坡地 1 +x:1 +竞 66 +x:66 +建网 1 +x:1 +国事 1 +x:1 +赔不是 1 +x:1 +威宁 1 +x:1 +操作数 1 +x:1 +天后庙 1 +x:1 +身先士卒 1 +x:1 +痛哭声 1 +x:1 +不顾一切 1 +x:1 +神机妙算 1 +x:1 +服务处 1 +x:1 +加工业 1 +x:1 +冻伤 1 +x:1 +槌儿 1 +x:1 +六中全会 1 +x:1 +调演 1 +x:1 +通邮 1 +x:1 +肥城 1 +x:1 +恢复肥 1 +x:1 +近墨者黑 1 +x:1 +犬马 1 +x:1 +月山 1 +x:1 +银白色 1 +x:1 +为人师表 1 +x:1 +武装力量 1 +x:1 +偎倚 1 +x:1 +口实 1 +x:1 +废票 1 +x:1 +薄纱 1 +x:1 +解愁 1 +x:1 +对流层 1 +x:1 +道人 1 +x:1 +致富线 1 +x:1 +云南团 1 +x:1 +油桐花 1 +x:1 +输变电 1 +x:1 +调整面 1 +x:1 +善气 1 +x:1 +肥地 1 +x:1 +通道 1 +x:1 +鸡 160 +x:160 +疗养院 1 +x:1 +宣州市 1 +x:1 +原始群 1 +x:1 +指路标 1 +x:1 +实用性 1 +x:1 +肠癌 1 +x:1 +一二月 1 +x:1 +蕉源村 1 +x:1 +摧毁 1 +x:1 +凉皮 1 +x:1 +加工件 1 +x:1 +口子 1 +x:1 +考评员 1 +x:1 +叹气 1 +x:1 +执著 1 +x:1 +晨雾 1 +x:1 +何年 1 +x:1 +决斗 1 +x:1 +挡路 1 +x:1 +何干 1 +x:1 +国书 1 +x:1 +通通 1 +x:1 +通途 1 +x:1 +预见 1 +x:1 +拔河绳 1 +x:1 +本州 1 +x:1 +国乐 1 +x:1 +芤脉 1 +x:1 +体委 1 +x:1 +丰水期 1 +x:1 +俗趣 1 +x:1 +笔友 1 +x:1 +决断 1 +x:1 +植检证 1 +x:1 +夸父追日 1 +x:1 +摧残 1 +x:1 +舫 20 +x:20 +假眉三道 1 +x:1 +收摊儿 1 +x:1 +农科技术 1 +x:1 +棚舍 1 +x:1 +报送 1 +x:1 +新建户 1 +x:1 +问津者 1 +x:1 +滞洪办 1 +x:1 +休息室 1 +x:1 +起家 1 +x:1 +横跨 1 +x:1 +庚寅年 1 +x:1 +行政区划 1 +x:1 +赤豆粥 1 +x:1 +赞助商 1 +x:1 +布拖县 1 +x:1 +敌情 1 +x:1 +原始性 1 +x:1 +国军 1 +x:1 +国内 1 +x:1 +木筏 1 +x:1 +柴沟门村 1 +x:1 +船坞 1 +x:1 +虚情假意 1 +x:1 +拷贝 1 +x:1 +涉案人 1 +x:1 +芝麻秆 1 +x:1 +杨柳池 1 +x:1 +电烤箱 1 +x:1 +有天没日 1 +x:1 +宝匣 1 +x:1 +积案 1 +x:1 +领航 1 +x:1 +联营厂 1 +x:1 +道具 1 +x:1 +过年节 1 +x:1 +扫帚菜 1 +x:1 +平诊 1 +x:1 +食品包 1 +x:1 +测风站 1 +x:1 +开赛 1 +x:1 +顾客 1 +x:1 +组队 1 +x:1 +人民 1 +x:1 +孤 23 +x:23 +遥遥无期 1 +x:1 +钻天杨 1 +x:1 +掌心 1 +x:1 +苍头 1 +x:1 +呼之欲跃 1 +x:1 +永安里 1 +x:1 +木笔 1 +x:1 +俗家 1 +x:1 +开走 1 +x:1 +开赴 1 +x:1 +夏耘 1 +x:1 +认出 1 +x:1 +损伤 1 +x:1 +北园镇 1 +x:1 +陪嫁 1 +x:1 +主办权 1 +x:1 +蜡嘴 1 +x:1 +冻僵 1 +x:1 +定场诗 1 +x:1 +三叠系 1 +x:1 +徊 1 +x:1 +文学奖 1 +x:1 +盐都 1 +x:1 +俗字 1 +x:1 +臭气 1 +x:1 +荡气回肠 1 +x:1 +调整表 1 +x:1 +无支柱 1 +x:1 +战士 1 +x:1 +臭氧 1 +x:1 +公差 1 +x:1 +通车 1 +x:1 +脚下 1 +x:1 +初级 1 +x:1 +怡怡然 1 +x:1 +盗名欺世 1 +x:1 +花椰菜 1 +x:1 +功夫茶 1 +x:1 +天骄 1 +x:1 +涤痰开窍 1 +x:1 +虔州 1 +x:1 +国共 1 +x:1 +河西区 1 +x:1 +散步者 1 +x:1 +虏 1 +x:1 +无孔不入 1 +x:1 +横贯 1 +x:1 +何 1061 +x:1061 +食品厂 1 +x:1 +中政委 1 +x:1 +横财 1 +x:1 +州 148 +x:148 +国家股 1 +x:1 +船型 1 +x:1 +诱杀 1 +x:1 +波斯尼亚 1 +x:1 +开路 1 +x:1 +贪污罪 1 +x:1 +偎依 1 +x:1 +起子 1 +x:1 +钻天柳 1 +x:1 +检查法 1 +x:1 +木简 1 +x:1 +夜袭 1 +x:1 +六建 1 +x:1 +工委纪委 1 +x:1 +结点 1 +x:1 +石柱县 1 +x:1 +小摊 1 +x:1 +憋 28 +x:28 +公屋 1 +x:1 +直音 1 +x:1 +田园梦 1 +x:1 +操作符 1 +x:1 +数量型 1 +x:1 +甘 80 +x:80 +机舱 1 +x:1 +龟 54 +x:54 +葱头 1 +x:1 +播种人 1 +x:1 +雁栖湖 1 +x:1 +黛绿 1 +x:1 +路费 1 +x:1 +不足为凭 1 +x:1 +土建 1 +x:1 +郁 49 +x:49 +上虞市 1 +x:1 +开豁 1 +x:1 +绒头绳 1 +x:1 +芭蕉 1 +x:1 +冻儿 1 +x:1 +带宽 1 +x:1 +一官半职 1 +x:1 +牛派 1 +x:1 +乱杂 1 +x:1 +叱咤风云 1 +x:1 +吓唬 1 +x:1 +中花脸 1 +x:1 +齐心协力 1 +x:1 +翟 76 +x:76 +众口一声 1 +x:1 +界内 1 +x:1 +照相术 1 +x:1 +通身 1 +x:1 +普救寺 1 +x:1 +晚疫病 1 +x:1 +羊奶 1 +x:1 +结晶硅 1 +x:1 +乱来 1 +x:1 +门径 1 +x:1 +公尺 1 +x:1 +氯碱 1 +x:1 +机芯 1 +x:1 +女生 1 +x:1 +三元镇 1 +x:1 +动手动脚 1 +x:1 +国债 1 +x:1 +夜视 1 +x:1 +广货 1 +x:1 +不干不净 1 +x:1 +走向 1 +x:1 +尊师 1 +x:1 +网球馆 1 +x:1 +北 340 +x:340 +丰城市 1 +x:1 +夏至 1 +x:1 +脸水 1 +x:1 +永吉县 1 +x:1 +带子 1 +x:1 +本金额 1 +x:1 +坐堂义诊 1 +x:1 +嵩明县 1 +x:1 +达人知命 1 +x:1 +旦夕祸福 1 +x:1 +机械运动 1 +x:1 +昏招 1 +x:1 +办班 1 +x:1 +空包弹 1 +x:1 +诚心诚意 1 +x:1 +局长 1 +x:1 +臭活 1 +x:1 +棋盘坨 1 +x:1 +取证 1 +x:1 +凉棚 1 +x:1 +掀风鼓浪 1 +x:1 +扁豆 1 +x:1 +腋 1 +x:1 +窘态 1 +x:1 +决算 1 +x:1 +展期 1 +x:1 +华乐团 1 +x:1 +路距 1 +x:1 +挪挪 1 +x:1 +神采奕奕 1 +x:1 +开放日 1 +x:1 +路路 1 +x:1 +石龙乡 1 +x:1 +敌意 1 +x:1 +八 1394 +x:1394 +集体照 1 +x:1 +木窗 1 +x:1 +凤凰竹 1 +x:1 +积弱积贫 1 +x:1 +菜店 1 +x:1 +严重性 1 +x:1 +松山乡 1 +x:1 +各 4288 +x:4288 +打入冷宫 1 +x:1 +氢氧吹管 1 +x:1 +阵地化 1 +x:1 +拍巴掌 1 +x:1 +结环 1 +x:1 +训保 1 +x:1 +纯天然 1 +x:1 +女皇 1 +x:1 +借花献佛 1 +x:1 +通路 1 +x:1 +救应 1 +x:1 +亟盼 1 +x:1 +焊花 1 +x:1 +宋词 1 +x:1 +贝桑松 1 +x:1 +扩种 1 +x:1 +笔下 1 +x:1 +横过 1 +x:1 +同话异境 1 +x:1 +犍牛 1 +x:1 +观测室 1 +x:1 +国号 1 +x:1 +原作 1 +x:1 +秦齐郡 1 +x:1 +椴木 1 +x:1 +公开 1 +x:1 +国史 1 +x:1 +公式 1 +x:1 +女监 1 +x:1 +羽毛球队 1 +x:1 +评议表 1 +x:1 +李 8285 +x:8285 +邕宁县 1 +x:1 +原位 1 +x:1 +建房 1 +x:1 +外联司 1 +x:1 +对照表 1 +x:1 +平视 1 +x:1 +芭蕾 1 +x:1 +国发 1 +x:1 +总路线 1 +x:1 +九点 1 +x:1 +目无法纪 1 +x:1 +乱坟岗 1 +x:1 +铅刀一割 1 +x:1 +坂仔镇 1 +x:1 +粮垛 1 +x:1 +加工区 1 +x:1 +身处牢笼 1 +x:1 +建成 1 +x:1 +违法 1 +x:1 +道县 1 +x:1 +公心 1 +x:1 +醍醐灌顶 1 +x:1 +肌 6 +x:6 +国医 1 +x:1 +羔羊皮 1 +x:1 +俗套 1 +x:1 +局限 1 +x:1 +起头 1 +x:1 +菜市 1 +x:1 +案籍 1 +x:1 +尊崇 1 +x:1 +开辟 1 +x:1 +畜牧厅 1 +x:1 +敌手 1 +x:1 +接轨点 1 +x:1 +凉苏苏 1 +x:1 +闪闪烁烁 1 +x:1 +相间 1 +x:1 +声色犬马 1 +x:1 +辩证法观 1 +x:1 +农药 1 +x:1 +奉命唯谨 1 +x:1 +黑不溜秋 1 +x:1 +晨课 1 +x:1 +重臂 1 +x:1 +道号 1 +x:1 +界别 1 +x:1 +加工厂 1 +x:1 +事不宜迟 1 +x:1 +凑巧 1 +x:1 +取 270 +x:270 +道口 1 +x:1 +开进 1 +x:1 +祝 241 +x:241 +短篇小说 1 +x:1 +平西 1 +x:1 +金山岭 1 +x:1 +通货 1 +x:1 +猪倌 1 +x:1 +按质 1 +x:1 +保障金 1 +x:1 +北京籍 1 +x:1 +敌我 1 +x:1 +译丛 1 +x:1 +摇钱树 1 +x:1 +助人为乐 1 +x:1 +群策群力 1 +x:1 +贻祸无穷 1 +x:1 +适 32 +x:32 +反义词 1 +x:1 +贫血病 1 +x:1 +计量局 1 +x:1 +阿尔泰 1 +x:1 +国势 1 +x:1 +慨然 1 +x:1 +灵通卡 1 +x:1 +道别 1 +x:1 +国务 1 +x:1 +参变量 1 +x:1 +巡查 1 +x:1 +腥风血雨 1 +x:1 +训令 1 +x:1 +影视剧 1 +x:1 +笔会 1 +x:1 +前赴后继 1 +x:1 +榴弹 1 +x:1 +口是心非 1 +x:1 +国办 1 +x:1 +桃城区 1 +x:1 +国力 1 +x:1 +积欠 1 +x:1 +穿堂风 1 +x:1 +船员 1 +x:1 +吓坏 1 +x:1 +公平 1 +x:1 +机耕 1 +x:1 +夏荒 1 +x:1 +寄养 1 +x:1 +副词 1 +x:1 +柿饼 1 +x:1 +敌探 1 +x:1 +公布 1 +x:1 +运输车 1 +x:1 +感染 1 +x:1 +新声 1 +x:1 +钥匙牌 1 +x:1 +升幅 1 +x:1 +菜心 1 +x:1 +灵长类 1 +x:1 +樊集 1 +x:1 +平装 1 +x:1 +劳资处 1 +x:1 +单位制 1 +x:1 +升平 1 +x:1 +同年底 1 +x:1 +路轨 1 +x:1 +行李架 1 +x:1 +笔体 1 +x:1 +巡逻队 1 +x:1 +打理 1 +x:1 +出人预料 1 +x:1 +认养 1 +x:1 +天文学史 1 +x:1 +克己奉公 1 +x:1 +女真 1 +x:1 +丁字尺 1 +x:1 +废料 1 +x:1 +连环记 1 +x:1 +夜话 1 +x:1 +地政局 1 +x:1 +国际篇 1 +x:1 +保留区 1 +x:1 +文部大臣 1 +x:1 +升序 1 +x:1 +国别 1 +x:1 +局面 1 +x:1 +羹匙 1 +x:1 +脚踏实地 1 +x:1 +笔供 1 +x:1 +氢酸 1 +x:1 +国强民富 1 +x:1 +农艺 1 +x:1 +中盘 1 +x:1 +路边 1 +x:1 +原产 1 +x:1 +村务实情 1 +x:1 +秘谱 1 +x:1 +公建 1 +x:1 +监规 1 +x:1 +通谍 1 +x:1 +猪儿 1 +x:1 +批语 1 +x:1 +纤夫 1 +x:1 +路过 1 +x:1 +监视 1 +x:1 +忽略 1 +x:1 +机能 1 +x:1 +称职者 1 +x:1 +东亚区 1 +x:1 +顶嘴 1 +x:1 +曝光栏 1 +x:1 +平行 1 +x:1 +多层板 1 +x:1 +农舍 1 +x:1 +常州市 1 +x:1 +城口县 1 +x:1 +原价 1 +x:1 +原件 1 +x:1 +冻原 1 +x:1 +神经科 1 +x:1 +焊药 1 +x:1 +晓风 1 +x:1 +废旧 1 +x:1 +平衡 1 +x:1 +熟土 1 +x:1 +八方来客 1 +x:1 +战局 1 +x:1 +氢氧化铵 1 +x:1 +通话 1 +x:1 +平辈 1 +x:1 +令人注目 1 +x:1 +判决案 1 +x:1 +写 1717 +x:1717 +雄蕊 1 +x:1 +通译 1 +x:1 +开放性 1 +x:1 +林间地 1 +x:1 +升头 1 +x:1 +密致 1 +x:1 +金属管 1 +x:1 +结构力学 1 +x:1 +社民 1 +x:1 +强直性 1 +x:1 +谈仙岭 1 +x:1 +熟地 1 +x:1 +工日 1 +x:1 +三台山 1 +x:1 +井陉 1 +x:1 +龙旗 1 +x:1 +帮派 1 +x:1 +通读 1 +x:1 +积水 1 +x:1 +升天 1 +x:1 +顶冠 1 +x:1 +针叶树 1 +x:1 +批准权 1 +x:1 +纤度 1 +x:1 +劳身焦思 1 +x:1 +秘诀 1 +x:1 +战将 1 +x:1 +调理 1 +x:1 +肠液 1 +x:1 +枉费心机 1 +x:1 +漠然 1 +x:1 +新婚者 1 +x:1 +星系 1 +x:1 +感情 1 +x:1 +氢氧化钠 1 +x:1 +清明菜 1 +x:1 +治国安邦 1 +x:1 +蚕丝 1 +x:1 +北京站 1 +x:1 +井队 1 +x:1 +通讯 1 +x:1 +除冰液 1 +x:1 +吓倒 1 +x:1 +湟水 1 +x:1 +感想 1 +x:1 +牙周病 1 +x:1 +亏盈相抵 1 +x:1 +通论 1 +x:1 +缺吃少穿 1 +x:1 +史实性 1 +x:1 +攻坚仗 1 +x:1 +天麻 1 +x:1 +神经线 1 +x:1 +药料 1 +x:1 +决绝 1 +x:1 +盐铺 1 +x:1 +城固县 1 +x:1 +腰肢 1 +x:1 +转来转去 1 +x:1 +普通工 1 +x:1 +船台 1 +x:1 +带卧车 1 +x:1 +肿瘤性 1 +x:1 +感怀 1 +x:1 +热泵 1 +x:1 +急于 1 +x:1 +相提并论 1 +x:1 +交存人 1 +x:1 +急事 1 +x:1 +道喜 1 +x:1 +暮春 1 +x:1 +搜 18 +x:18 +安太堡 1 +x:1 +感性 1 +x:1 +更正 1 +x:1 +流水账 1 +x:1 +卅 1 +x:1 +拍打 1 +x:1 +勤政为民 1 +x:1 +可选择性 1 +x:1 +社会意识 1 +x:1 +约法三章 1 +x:1 +奶嘴 1 +x:1 +江门 1 +x:1 +急件 1 +x:1 +开解 1 +x:1 +计量室 1 +x:1 +串串 1 +x:1 +永安镇 1 +x:1 +船厂 1 +x:1 +美展 1 +x:1 +界限路 1 +x:1 +唱红脸 1 +x:1 +国商 1 +x:1 +出版者 1 +x:1 +感恩 1 +x:1 +腹 18 +x:18 +那么些 1 +x:1 +抽穗期 1 +x:1 +平车 1 +x:1 +证人 1 +x:1 +清明节 1 +x:1 +三元里 1 +x:1 +远嫁 1 +x:1 +矿物质 1 +x:1 +瓦哈卡 1 +x:1 +凉气 1 +x:1 +局里 1 +x:1 +山光水色 1 +x:1 +升堂 1 +x:1 +少先队员 1 +x:1 +平躺 1 +x:1 +入籍 1 +x:1 +没白没黑 1 +x:1 +小马青村 1 +x:1 +大喜之日 1 +x:1 +大丽花 1 +x:1 +青岛港 1 +x:1 +起床 1 +x:1 +设计量 1 +x:1 +以毒攻毒 1 +x:1 +建教 1 +x:1 +僚机 1 +x:1 +危城 1 +x:1 +沿儿 1 +x:1 +燕麦草 1 +x:1 +小方帽 1 +x:1 +公堂 1 +x:1 +巴拿马籍 1 +x:1 +贫血率 1 +x:1 +婚姻法 1 +x:1 +步步为营 1 +x:1 +开行 1 +x:1 +芝麻糖 1 +x:1 +郁南 1 +x:1 +单位名 1 +x:1 +初等 1 +x:1 +敌方 1 +x:1 +昏昏 1 +x:1 +乡镇长 1 +x:1 +带徒 1 +x:1 +调用 1 +x:1 +预期 1 +x:1 +竞买 1 +x:1 +板结 1 +x:1 +神经网 1 +x:1 +周庄镇 1 +x:1 +加油机 1 +x:1 +不祧之祖 1 +x:1 +市声鼎沸 1 +x:1 +欧委会 1 +x:1 +选煤厂 1 +x:1 +防卫厅 1 +x:1 +数量化 1 +x:1 +五彩缤纷 1 +x:1 +六安 1 +x:1 +加工品 1 +x:1 +竞争 1 +x:1 +珠海市 1 +x:1 +种族歧视 1 +x:1 +天龙 1 +x:1 +一整两反 1 +x:1 +知识库 1 +x:1 +国君 1 +x:1 +横行 1 +x:1 +氢氧化镍 1 +x:1 +恒心 1 +x:1 +国名 1 +x:1 +泗阳 1 +x:1 +臭椿 1 +x:1 +国后 1 +x:1 +苦尽甘来 1 +x:1 +开裂 1 +x:1 +养老金 1 +x:1 +木纹 1 +x:1 +猪场 1 +x:1 +船务 1 +x:1 +长者团 1 +x:1 +路规 1 +x:1 +填垫地 1 +x:1 +相容 1 +x:1 +积淀 1 +x:1 +君权 1 +x:1 +合拢 1 +x:1 +弊政 1 +x:1 +澄北镇 1 +x:1 +始兴 1 +x:1 +清热解暑 1 +x:1 +拳联 1 +x:1 +此画 1 +x:1 +纤弱 1 +x:1 +丧德败行 1 +x:1 +法律系 1 +x:1 +桩 66 +x:66 +辨证 1 +x:1 +厉害 1 +x:1 +始先 1 +x:1 +大容山 1 +x:1 +响起 1 +x:1 +急促 1 +x:1 +竞价 1 +x:1 +质检站 1 +x:1 +佛口蛇心 1 +x:1 +感慨 1 +x:1 +昏暗 1 +x:1 +羊工 1 +x:1 +一二级 1 +x:1 +道场 1 +x:1 +通览 1 +x:1 +船公 1 +x:1 +助攻王 1 +x:1 +茼蒿 1 +x:1 +通观 1 +x:1 +郊区县 1 +x:1 +主发射机 1 +x:1 +晚生代 1 +x:1 +顶叶 1 +x:1 +振兴中华 1 +x:1 +私见 1 +x:1 +羊市 1 +x:1 +战幕 1 +x:1 +公学 1 +x:1 +车载式 1 +x:1 +积温 1 +x:1 +淤土 1 +x:1 +平足 1 +x:1 +打工妹 1 +x:1 +老板娘 1 +x:1 +卧铺车 1 +x:1 +毛乌素 1 +x:1 +舸 42 +x:42 +鱼儿沟 1 +x:1 +音乐性 1 +x:1 +评头论足 1 +x:1 +硬茬地 1 +x:1 +因人施教 1 +x:1 +拱石桥 1 +x:1 +神经类 1 +x:1 +结石 1 +x:1 +毛驴车 1 +x:1 +一串红 1 +x:1 +竣 2 +x:2 +尊姓 1 +x:1 +铁背鱼 1 +x:1 +隔热 1 +x:1 +船儿 1 +x:1 +道高一尺 1 +x:1 +柚子 1 +x:1 +办理 1 +x:1 +扬子江 1 +x:1 +一拥而上 1 +x:1 +羊年 1 +x:1 +断裂带 1 +x:1 +心潮难平 1 +x:1 +茶卤儿 1 +x:1 +升学 1 +x:1 +隐私 1 +x:1 +加工场 1 +x:1 +绿泥石 1 +x:1 +时兴 1 +x:1 +互动性 1 +x:1 +通产相 1 +x:1 +计划单列 1 +x:1 +喂 75 +x:75 +银条菜 1 +x:1 +报酬 1 +x:1 +枣椰林 1 +x:1 +形影相对 1 +x:1 +博格达峰 1 +x:1 +发愤图强 1 +x:1 +赞扬声 1 +x:1 +公寓 1 +x:1 +电磁铁 1 +x:1 +行使 1 +x:1 +网络结构 1 +x:1 +扇贝丁 1 +x:1 +乙方 1 +x:1 +郧西县 1 +x:1 +机械能 1 +x:1 +善用 1 +x:1 +晰 1 +x:1 +硕大无比 1 +x:1 +厉声 1 +x:1 +国土 1 +x:1 +开讲 1 +x:1 +肥东 1 +x:1 +晨辉 1 +x:1 +辐射 1 +x:1 +肥业 1 +x:1 +爱沙尼亚 1 +x:1 +开设 1 +x:1 +废坑塘 1 +x:1 +合股 1 +x:1 +开评 1 +x:1 +加工型 1 +x:1 +开诊 1 +x:1 +圆锥花序 1 +x:1 +公安 1 +x:1 +南锣鼓巷 1 +x:1 +甘之如饴 1 +x:1 +磁棒 1 +x:1 +尊奉 1 +x:1 +兼并体 1 +x:1 +不廉则败 1 +x:1 +十八年 1 +x:1 +千层饼 1 +x:1 +纤小 1 +x:1 +打工女 1 +x:1 +党员秤 1 +x:1 +俦 1 +x:1 +喜迎春 1 +x:1 +急危难 1 +x:1 +湘剧团 1 +x:1 +奶名 1 +x:1 +平方和 1 +x:1 +公家 1 +x:1 +商丘 1 +x:1 +国际级 1 +x:1 +云梢 1 +x:1 +公害 1 +x:1 +纤尘 1 +x:1 +大势已去 1 +x:1 +商业性 1 +x:1 +洗车店 1 +x:1 +公婆 1 +x:1 +寿礼 1 +x:1 +音乐感 1 +x:1 +纤巧 1 +x:1 +畏缩不前 1 +x:1 +云梦 1 +x:1 +片区 1 +x:1 +郏县 1 +x:1 +坚不可摧 1 +x:1 +殓 1 +x:1 +谒 7 +x:7 +皮乌拉省 1 +x:1 +铁刷把 1 +x:1 +满堂喝彩 1 +x:1 +空心菜 1 +x:1 +傅村 1 +x:1 +六大 1 +x:1 +油漆匠 1 +x:1 +致富星 1 +x:1 +夜车 1 +x:1 +变色镜 1 +x:1 +战役 1 +x:1 +界域 1 +x:1 +食管癌 1 +x:1 +建材 1 +x:1 +触摸池 1 +x:1 +案秤 1 +x:1 +吃哑巴亏 1 +x:1 +引吭高歌 1 +x:1 +装机费 1 +x:1 +多方面 1 +x:1 +批转 1 +x:1 +冻场 1 +x:1 +风剥雨蚀 1 +x:1 +公开墙 1 +x:1 +电磁锁 1 +x:1 +暴力式 1 +x:1 +行人 1 +x:1 +滑翔 1 +x:1 +结盟 1 +x:1 +趁 55 +x:55 +护照者 1 +x:1 +路警 1 +x:1 +冻土 1 +x:1 +行事 1 +x:1 +磕打 1 +x:1 +党学委 1 +x:1 +拍拍 1 +x:1 +始发 1 +x:1 +新宁 1 +x:1 +骗子手 1 +x:1 +氯纶 1 +x:1 +问卷 1 +x:1 +总面积 1 +x:1 +通行 1 +x:1 +忽然 1 +x:1 +软骨质 1 +x:1 +夜运 1 +x:1 +拼盘式 1 +x:1 +恭 5 +x:5 +绿城 1 +x:1 +兼任 1 +x:1 +沿台 1 +x:1 +药衡 1 +x:1 +原始林 1 +x:1 +皖 32 +x:32 +环绕 1 +x:1 +丁字堤 1 +x:1 +非司机 1 +x:1 +柏树林 1 +x:1 +词曲牌 1 +x:1 +含羞带笑 1 +x:1 +攀附 1 +x:1 +憋屈 1 +x:1 +平谷 1 +x:1 +通衢 1 +x:1 +难民署 1 +x:1 +界块 1 +x:1 +白云观 1 +x:1 +针织物 1 +x:1 +行乞 1 +x:1 +蛋鸡场 1 +x:1 +肺 31 +x:31 +海商法 1 +x:1 +座上宾 1 +x:1 +肥佬 1 +x:1 +警察局 1 +x:1 +菜子 1 +x:1 +偷猎者 1 +x:1 +养殖链 1 +x:1 +火花塞 1 +x:1 +定海神针 1 +x:1 +谈话录 1 +x:1 +寡人 1 +x:1 +敌机 1 +x:1 +国器 1 +x:1 +初秋 1 +x:1 +游戏 1 +x:1 +起居 1 +x:1 +参政 1 +x:1 +建构 1 +x:1 +阀门 1 +x:1 +写字楼 1 +x:1 +环线 1 +x:1 +贩私 1 +x:1 +行东 1 +x:1 +驰名中外 1 +x:1 +警察厅 1 +x:1 +饼饵 1 +x:1 +第十甫路 1 +x:1 +察言观色 1 +x:1 +中产阶级 1 +x:1 +夏衣 1 +x:1 +取舍 1 +x:1 +建档 1 +x:1 +地铁票 1 +x:1 +昏死 1 +x:1 +分流港 1 +x:1 +凉意 1 +x:1 +一二点 1 +x:1 +隐瞒 1 +x:1 +铁锈病 1 +x:1 +史册 1 +x:1 +道外 1 +x:1 +知识化 1 +x:1 +副肾 1 +x:1 +顾及 1 +x:1 +计征科 1 +x:1 +被救者 1 +x:1 +坂子矶 1 +x:1 +工务科 1 +x:1 +废渣 1 +x:1 +自习室 1 +x:1 +通融 1 +x:1 +带劲 1 +x:1 +道好 1 +x:1 +奥斯马奇 1 +x:1 +煤车 1 +x:1 +机警 1 +x:1 +服务业 1 +x:1 +先拔头筹 1 +x:1 +壁虎 1 +x:1 +豇豆 1 +x:1 +打翻身仗 1 +x:1 +办税 1 +x:1 +菜品 1 +x:1 +带动 1 +x:1 +平菇 1 +x:1 +玉渊潭 1 +x:1 +示意图 1 +x:1 +挡驾 1 +x:1 +行唐县 1 +x:1 +唱高调 1 +x:1 +泣 11 +x:11 +隔绝 1 +x:1 +米非司酮 1 +x:1 +毛刺儿 1 +x:1 +无油迹 1 +x:1 +金属矿 1 +x:1 +建树 1 +x:1 +礁 2 +x:2 +西湖调 1 +x:1 +结社 1 +x:1 +参拜 1 +x:1 +客场 1 +x:1 +青苗费 1 +x:1 +金灿灿 1 +x:1 +清热解毒 1 +x:1 +肘子 1 +x:1 +沛 4 +x:4 +铂 4 +x:4 +戴罪立功 1 +x:1 +如梦初醒 1 +x:1 +赫拉特 1 +x:1 +国外 1 +x:1 +墨绿色 1 +x:1 +狐狸崽 1 +x:1 +打工地 1 +x:1 +格拉斯哥 1 +x:1 +夏装 1 +x:1 +枪 91 +x:91 +一体 1 +x:1 +宅子 1 +x:1 +体事 1 +x:1 +蓄谋已久 1 +x:1 +磁暴 1 +x:1 +建棚 1 +x:1 +总 1962 +x:1962 +熟客 1 +x:1 +兔王 1 +x:1 +带到 1 +x:1 +虽说 1 +x:1 +待人接物 1 +x:1 +组 600 +x:600 +阿杜瓦 1 +x:1 +沿岸 1 +x:1 +伴奏声 1 +x:1 +招生办 1 +x:1 +救命 1 +x:1 +不务正业 1 +x:1 +闪石 1 +x:1 +呼啦啦 1 +x:1 +簪缨 1 +x:1 +烂乎乎 1 +x:1 +切肤之痛 1 +x:1 +共生矿 1 +x:1 +手枪钻 1 +x:1 +民主刚果 1 +x:1 +求本溯源 1 +x:1 +吕梁 1 +x:1 +道姑 1 +x:1 +冒烟 1 +x:1 +兰炼 1 +x:1 +暂住地 1 +x:1 +行李袋 1 +x:1 +苟同 1 +x:1 +袁巷乡 1 +x:1 +防护衣 1 +x:1 +乒乓赛 1 +x:1 +六国 1 +x:1 +拐弯抹角 1 +x:1 +七月份 1 +x:1 +煤运 1 +x:1 +杂物箱 1 +x:1 +冒然 1 +x:1 +平芜 1 +x:1 +轧钢线 1 +x:1 +板状 1 +x:1 +淤积 1 +x:1 +公告 1 +x:1 +起动 1 +x:1 +顶峰 1 +x:1 +风流韵事 1 +x:1 +起劲 1 +x:1 +嘶嘶 1 +x:1 +兵库县 1 +x:1 +八机部 1 +x:1 +奢侈浪费 1 +x:1 +书画集 1 +x:1 +字帖儿 1 +x:1 +更替 1 +x:1 +剪辑 1 +x:1 +肿骨鹿 1 +x:1 +计量器 1 +x:1 +牛溲马勃 1 +x:1 +维修性 1 +x:1 +国境 1 +x:1 +为 28856 +x:28856 +战具 1 +x:1 +霭空 1 +x:1 +整合率 1 +x:1 +船帮 1 +x:1 +党八股 1 +x:1 +出土文物 1 +x:1 +用餐费 1 +x:1 +星系团 1 +x:1 +随州市 1 +x:1 +告示牌 1 +x:1 +国士 1 +x:1 +磁条 1 +x:1 +人影儿 1 +x:1 +四乡八村 1 +x:1 +周四 1 +x:1 +一举 1 +x:1 +榕树 1 +x:1 +船帆 1 +x:1 +体位 1 +x:1 +顶岗 1 +x:1 +形影相吊 1 +x:1 +禁区 1 +x:1 +伽师 1 +x:1 +自营率 1 +x:1 +磁极 1 +x:1 +犹豫 1 +x:1 +鸽子花 1 +x:1 +单冷型 1 +x:1 +不足为奇 1 +x:1 +供联财字 1 +x:1 +摆设 1 +x:1 +歉意 1 +x:1 +起到 1 +x:1 +敌楼 1 +x:1 +黄土层 1 +x:1 +克什米尔 1 +x:1 +寄居蟹 1 +x:1 +顶层 1 +x:1 +濒危种 1 +x:1 +宪法学 1 +x:1 +恒发 1 +x:1 +知己 1 +x:1 +体例 1 +x:1 +电气化 1 +x:1 +关门主义 1 +x:1 +起初 1 +x:1 +第四营村 1 +x:1 +开开心 1 +x:1 +秀 21 +x:21 +逐项 1 +x:1 +形体 1 +x:1 +九运会 1 +x:1 +轻蔑 1 +x:1 +榜样性 1 +x:1 +菜商 1 +x:1 +没顶 1 +x:1 +密谈 1 +x:1 +基础代谢 1 +x:1 +密谋 1 +x:1 +慨当以慷 1 +x:1 +油漆工 1 +x:1 +软着陆 1 +x:1 +大眼贼 1 +x:1 +板牙 1 +x:1 +胁迫 1 +x:1 +自卫军 1 +x:1 +虚靡 1 +x:1 +调离 1 +x:1 +织物 1 +x:1 +顶尖 1 +x:1 +府南河 1 +x:1 +卢森堡 1 +x:1 +木犁 1 +x:1 +船底 1 +x:1 +战况 1 +x:1 +新沂市 1 +x:1 +国宴 1 +x:1 +国家 1 +x:1 +棉丝 1 +x:1 +射 86 +x:86 +煤质 1 +x:1 +不足挂齿 1 +x:1 +闪电 1 +x:1 +射戟台 1 +x:1 +农话 1 +x:1 +隐疾 1 +x:1 +六合 1 +x:1 +绵竹县 1 +x:1 +口令 1 +x:1 +鸩 1 +x:1 +楚辞 1 +x:1 +观测台 1 +x:1 +民政局长 1 +x:1 +调门儿 1 +x:1 +评议者 1 +x:1 +躲藏 1 +x:1 +夜色 1 +x:1 +扯动 1 +x:1 +国宝 1 +x:1 +逐村逐户 1 +x:1 +废水 1 +x:1 +结算 1 +x:1 +常州城 1 +x:1 +国宅 1 +x:1 +知州 1 +x:1 +困苦 1 +x:1 +楚边 1 +x:1 +社戏 1 +x:1 +女红 1 +x:1 +通力合作 1 +x:1 +房地产商 1 +x:1 +纳—卡 1 +x:1 +欢迎会 1 +x:1 +战刀 1 +x:1 +救国 1 +x:1 +建模 1 +x:1 +红果儿 1 +x:1 +竖体 1 +x:1 +祁东县 1 +x:1 +麦迪逊县 1 +x:1 +始建 1 +x:1 +护照费 1 +x:1 +道学 1 +x:1 +备选 1 +x:1 +麦收区 1 +x:1 +隐痛 1 +x:1 +天道 1 +x:1 +道子 1 +x:1 +更新 1 +x:1 +染色体 1 +x:1 +宝山镇 1 +x:1 +硕大无朋 1 +x:1 +冒牌 1 +x:1 +菜园 1 +x:1 +夜航 1 +x:1 +菲律宾 1 +x:1 +槐叶 1 +x:1 +白关镇 1 +x:1 +不毛之地 1 +x:1 +船工 1 +x:1 +道家 1 +x:1 +害人不浅 1 +x:1 +顾全 1 +x:1 +专卖柜 1 +x:1 +建材计 1 +x:1 +管理部 1 +x:1 +铭感 1 +x:1 +冒犯 1 +x:1 +快马加鞭 1 +x:1 +相称 1 +x:1 +恭恭敬敬 1 +x:1 +安定感 1 +x:1 +浔江 1 +x:1 +废油 1 +x:1 +中微子 1 +x:1 +留有余地 1 +x:1 +机要 1 +x:1 +铁板大鼓 1 +x:1 +道教徒 1 +x:1 +襟江带湖 1 +x:1 +科协组 1 +x:1 +抽屉式 1 +x:1 +秧歌 1 +x:1 +茅舍 1 +x:1 +玉垒 1 +x:1 +春小麦 1 +x:1 +忽米 1 +x:1 +呈递 1 +x:1 +一日千里 1 +x:1 +帆板 1 +x:1 +腌鸭 1 +x:1 +缀染 1 +x:1 +起兵 1 +x:1 +国学 1 +x:1 +已往 1 +x:1 +战功 1 +x:1 +论证关 1 +x:1 +守财奴 1 +x:1 +呈送 1 +x:1 +取胜 1 +x:1 +弥留之际 1 +x:1 +懦 1 +x:1 +环环 1 +x:1 +棚菜 1 +x:1 +导弹艇 1 +x:1 +威严 1 +x:1 +早先 1 +x:1 +更改 1 +x:1 +棉价 1 +x:1 +挡风 1 +x:1 +瞒哄 1 +x:1 +特出 1 +x:1 +志愿 1 +x:1 +甘露园 1 +x:1 +草刺儿 1 +x:1 +喜冲冲 1 +x:1 +曲酒 1 +x:1 +初生 1 +x:1 +翼手目 1 +x:1 +横蛮 1 +x:1 +论证会 1 +x:1 +活命钱 1 +x:1 +轮休 1 +x:1 +槎溪镇 1 +x:1 +纳巴提亚 1 +x:1 +致癌物 1 +x:1 +计量员 1 +x:1 +威信 1 +x:1 +东不压桥 1 +x:1 +红三军团 1 +x:1 +凉房 1 +x:1 +湾仔 1 +x:1 +务工卡 1 +x:1 +黛瓦 1 +x:1 +侵略军 1 +x:1 +扎伊尔 1 +x:1 +凑合 1 +x:1 +饮茶观 1 +x:1 +暴力化 1 +x:1 +帮手 1 +x:1 +来龙去脉 1 +x:1 +黑老九 1 +x:1 +游离状 1 +x:1 +一二 1 +x:1 +船尾 1 +x:1 +残篇断简 1 +x:1 +调笑 1 +x:1 +锦囊 1 +x:1 +感激 1 +x:1 +美容 1 +x:1 +奶妈 1 +x:1 +依依惜别 1 +x:1 +育苗 1 +x:1 +决然 1 +x:1 +伞状 1 +x:1 +检查权 1 +x:1 +口供 1 +x:1 +专用权 1 +x:1 +顶底 1 +x:1 +责任事故 1 +x:1 +土里土气 1 +x:1 +界定 1 +x:1 +帮扶 1 +x:1 +阶段 1 +x:1 +战友 1 +x:1 +茅草 1 +x:1 +带兵 1 +x:1 +毁誉 1 +x:1 +简谐运动 1 +x:1 +热滚滚 1 +x:1 +中趾 1 +x:1 +带入 1 +x:1 +奶奶 1 +x:1 +邮民 1 +x:1 +功能区 1 +x:1 +电烤灯 1 +x:1 +平者 1 +x:1 +加冕礼 1 +x:1 +蒋李集镇 1 +x:1 +公团 1 +x:1 +菜地 1 +x:1 +公园 1 +x:1 +菜场 1 +x:1 +防患未然 1 +x:1 +新婚 1 +x:1 +国威 1 +x:1 +战史 1 +x:1 +相互作用 1 +x:1 +公国 1 +x:1 +凑和 1 +x:1 +政 123 +x:123 +杨柳枝 1 +x:1 +冻害 1 +x:1 +夏训 1 +x:1 +天文学家 1 +x:1 +女网 1 +x:1 +口传 1 +x:1 +冷藏箱 1 +x:1 +储存 1 +x:1 +集约型 1 +x:1 +凉拌 1 +x:1 +忌辰 1 +x:1 +木炭 1 +x:1 +禁军 1 +x:1 +釜 1 +x:1 +动力学家 1 +x:1 +松坪村 1 +x:1 +葱叶 1 +x:1 +歌会 1 +x:1 +抹布 1 +x:1 +案由 1 +x:1 +捐款者 1 +x:1 +治外法权 1 +x:1 +地膜棉 1 +x:1 +汉堡包 1 +x:1 +呼风唤雨 1 +x:1 +汤阴县 1 +x:1 +环状 1 +x:1 +商用化 1 +x:1 +三台县 1 +x:1 +羊口 1 +x:1 +安非他明 1 +x:1 +隐现 1 +x:1 +红其拉甫 1 +x:1 +公元 1 +x:1 +公允 1 +x:1 +寿爷 1 +x:1 +草莽英雄 1 +x:1 +黄庄村 1 +x:1 +浑然不觉 1 +x:1 +输入法 1 +x:1 +共生 1 +x:1 +流通业 1 +x:1 +纸船 1 +x:1 +国产货 1 +x:1 +酚醛 1 +x:1 +妙 58 +x:58 +备降 1 +x:1 +公公 1 +x:1 +新堡子乡 1 +x:1 +受援国 1 +x:1 +带回 1 +x:1 +调类 1 +x:1 +刺丝 1 +x:1 +开脱 1 +x:1 +公关 1 +x:1 +公共 1 +x:1 +无聊者 1 +x:1 +共用 1 +x:1 +白鲑 1 +x:1 +巴比伦 1 +x:1 +莱切队 1 +x:1 +营山县 1 +x:1 +聚精会神 1 +x:1 +祝福歌 1 +x:1 +曲阜 1 +x:1 +机车 1 +x:1 +界岭 1 +x:1 +板石 1 +x:1 +防潮堤 1 +x:1 +侵略国 1 +x:1 +帮教 1 +x:1 +法律界 1 +x:1 +开腔 1 +x:1 +初版 1 +x:1 +九纵 1 +x:1 +二叠纪 1 +x:1 +善委会 1 +x:1 +曲阿 1 +x:1 +蓝湿革 1 +x:1 +升入 1 +x:1 +永丰县 1 +x:1 +案犯 1 +x:1 +人情 1 +x:1 +开腹 1 +x:1 +天际 1 +x:1 +雅趣 1 +x:1 +板眼 1 +x:1 +通草 1 +x:1 +倒蛋鬼 1 +x:1 +外祖父 1 +x:1 +闪现 1 +x:1 +农资 1 +x:1 +明矾 1 +x:1 +香菌 1 +x:1 +开膛 1 +x:1 +结素 1 +x:1 +拳拳 1 +x:1 +茶罐 1 +x:1 +债户 1 +x:1 +里加 1 +x:1 +一路货 1 +x:1 +威武不屈 1 +x:1 +骆马湖 1 +x:1 +转折性 1 +x:1 +楚乐宫 1 +x:1 +知识型 1 +x:1 +初犯 1 +x:1 +公函 1 +x:1 +公出 1 +x:1 +不在少数 1 +x:1 +违抗 1 +x:1 +巴侨 1 +x:1 +源地 1 +x:1 +巧布新阵 1 +x:1 +顶天 1 +x:1 +大帽子 1 +x:1 +彩绣 1 +x:1 +租卖亭 1 +x:1 +毫不犹豫 1 +x:1 +酚酞 1 +x:1 +亚太经济 1 +x:1 +顶头 1 +x:1 +拔 41 +x:41 +古典主义 1 +x:1 +公开化 1 +x:1 +万仙楼 1 +x:1 +界尺 1 +x:1 +船家 1 +x:1 +毛骨悚然 1 +x:1 +感叹词 1 +x:1 +步 744 +x:744 +黄花菜 1 +x:1 +椁木 1 +x:1 +密执安 1 +x:1 +转载者 1 +x:1 +童叟无欺 1 +x:1 +扎耳朵 1 +x:1 +公决 1 +x:1 +不思进取 1 +x:1 +豫南 1 +x:1 +顶多 1 +x:1 +天霸 1 +x:1 +曲靖 1 +x:1 +小小子 1 +x:1 +绩效低者 1 +x:1 +混血人 1 +x:1 +刺伤 1 +x:1 +菜农 1 +x:1 +板皮 1 +x:1 +舞文弄墨 1 +x:1 +林海镇 1 +x:1 +分总支 1 +x:1 +自吸型 1 +x:1 +冒用 1 +x:1 +积攒 1 +x:1 +句子成分 1 +x:1 +柿霜 1 +x:1 +净增值 1 +x:1 +升值 1 +x:1 +贪污犯 1 +x:1 +格外村 1 +x:1 +曲面 1 +x:1 +吨位 1 +x:1 +闪爆 1 +x:1 +钱塘江 1 +x:1 +可赞 1 +x:1 +灾种 1 +x:1 +巴里洛切 1 +x:1 +善终 1 +x:1 +南纬线 1 +x:1 +环球 1 +x:1 +胸怀大志 1 +x:1 +锻炼 1 +x:1 +公开办 1 +x:1 +做媒者 1 +x:1 +休戚与共 1 +x:1 +工作服 1 +x:1 +畜牧局 1 +x:1 +电棒 1 +x:1 +坜 1 +x:1 +社教 1 +x:1 +兰田 1 +x:1 +通用字 1 +x:1 +上周三 1 +x:1 +三文鱼 1 +x:1 +更何况 1 +x:1 +禁地 1 +x:1 +横肉 1 +x:1 +治疗室 1 +x:1 +公债 1 +x:1 +废止 1 +x:1 +积数 1 +x:1 +搂搂 1 +x:1 +机身 1 +x:1 +杂交棉 1 +x:1 +熊皮帽 1 +x:1 +拜伦多 1 +x:1 +积木 1 +x:1 +月亏 1 +x:1 +要者 1 +x:1 +阿尔托 1 +x:1 +一条心 1 +x:1 +道岔 1 +x:1 +月亮 1 +x:1 +比哈尔邦 1 +x:1 +亦可 1 +x:1 +观测员 1 +x:1 +碳60 1 +x:1 +诧异 1 +x:1 +食品店 1 +x:1 +开胃 1 +x:1 +洁身自爱 1 +x:1 +救兵 1 +x:1 +图象诗 1 +x:1 +埃里克市 1 +x:1 +农谚 1 +x:1 +声讯台 1 +x:1 +铁西区 1 +x:1 +个体经济 1 +x:1 +小轿车 1 +x:1 +门巴 1 +x:1 +白介素 1 +x:1 +堂兄弟 1 +x:1 +水淹七军 1 +x:1 +膀胱癌 1 +x:1 +搬运队 1 +x:1 +雅俗共赏 1 +x:1 +机械论 1 +x:1 +诤 1 +x:1 +通航 1 +x:1 +月份 1 +x:1 +恩 35 +x:35 +蜿蜒 1 +x:1 +社旗 1 +x:1 +违控 1 +x:1 +盲 4 +x:4 +变色龙 1 +x:1 +上周五 1 +x:1 +异类 1 +x:1 +虽 682 +x:682 +侏儒 1 +x:1 +月令 1 +x:1 +公升 1 +x:1 +铭文 1 +x:1 +璇 12 +x:12 +国徽 1 +x:1 +切割机 1 +x:1 +平措林寺 1 +x:1 +交叉点 1 +x:1 +穿堂门 1 +x:1 +救助 1 +x:1 +伴奏带 1 +x:1 +发刊词 1 +x:1 +磁性 1 +x:1 +六安市 1 +x:1 +特用林 1 +x:1 +杂技团 1 +x:1 +模板 1 +x:1 +公卿 1 +x:1 +建湖 1 +x:1 +货币地租 1 +x:1 +带响 1 +x:1 +应邀 1 +x:1 +底栖生物 1 +x:1 +船夫 1 +x:1 +桑白皮 1 +x:1 +介 4 +x:4 +藕节儿 1 +x:1 +开荒 1 +x:1 +中南美 1 +x:1 +国产车 1 +x:1 +花卉业 1 +x:1 +二七路 1 +x:1 +顶宽 1 +x:1 +飘流 1 +x:1 +卫生丸 1 +x:1 +赢 155 +x:155 +通膨 1 +x:1 +时分 1 +x:1 +警报灯 1 +x:1 +馓 2 +x:2 +大有可为 1 +x:1 +肘关节 1 +x:1 +环眼 1 +x:1 +禁吸 1 +x:1 +剪裁 1 +x:1 +女童 1 +x:1 +鸭子 1 +x:1 +禁品 1 +x:1 +伴星 1 +x:1 +青运史 1 +x:1 +道德 1 +x:1 +送饭制 1 +x:1 +链子 1 +x:1 +对此 1 +x:1 +菜刀 1 +x:1 +升压 1 +x:1 +服药者 1 +x:1 +中小学校 1 +x:1 +巴丹吉林 1 +x:1 +宣传部长 1 +x:1 +结缘 1 +x:1 +夜蛾 1 +x:1 +道徒 1 +x:1 +追根求源 1 +x:1 +顶子 1 +x:1 +循经 1 +x:1 +暴力团 1 +x:1 +姓名 1 +x:1 +应选 1 +x:1 +公司 1 +x:1 +摇动 1 +x:1 +公历 1 +x:1 +阿巴岛 1 +x:1 +七里塔村 1 +x:1 +升发 1 +x:1 +河街乡 1 +x:1 +一传 1 +x:1 +贬义 1 +x:1 +勾漏令 1 +x:1 +公厕 1 +x:1 +百鸟呈祥 1 +x:1 +二传奖 1 +x:1 +公厘 1 +x:1 +冻库 1 +x:1 +挡车工 1 +x:1 +布达拉宫 1 +x:1 +徐家乡 1 +x:1 +低职高挂 1 +x:1 +原告方 1 +x:1 +执掌 1 +x:1 +开 1885 +x:1885 +隔离 1 +x:1 +分进合击 1 +x:1 +何人 1 +x:1 +走私案 1 +x:1 +通胀 1 +x:1 +现政权 1 +x:1 +伞盖 1 +x:1 +三个一 1 +x:1 +国度 1 +x:1 +劣根性 1 +x:1 +鳌泉村 1 +x:1 +以法治赛 1 +x:1 +漠 1 +x:1 +球拍 1 +x:1 +国库 1 +x:1 +机谋 1 +x:1 +功能型 1 +x:1 +关注点 1 +x:1 +教练机 1 +x:1 +国庆 1 +x:1 +何事 1 +x:1 +牲口 1 +x:1 +揭竿而起 1 +x:1 +瑞典队 1 +x:1 +开船 1 +x:1 +天锅 1 +x:1 +爱尔兰裔 1 +x:1 +公分 1 +x:1 +日惹市 1 +x:1 +列宁格勒 1 +x:1 +集约化 1 +x:1 +养殖鱼 1 +x:1 +木琴 1 +x:1 +限流阀 1 +x:1 +摒 1 +x:1 +致残 1 +x:1 +何以 1 +x:1 +翅子 1 +x:1 +菜叶 1 +x:1 +商检 1 +x:1 +公判 1 +x:1 +起哄 1 +x:1 +万泉河 1 +x:1 +摩尔多瓦 1 +x:1 +建漆 1 +x:1 +禁售 1 +x:1 +公制 1 +x:1 +女篮 1 +x:1 +木球 1 +x:1 +战地 1 +x:1 +小鸟儿 1 +x:1 +伪县长 1 +x:1 +托克逊 1 +x:1 +审讯室 1 +x:1 +闪点 1 +x:1 +忌语 1 +x:1 +观测器 1 +x:1 +平方差 1 +x:1 +积极 1 +x:1 +伴有 1 +x:1 +船壳 1 +x:1 +巴伊亚 1 +x:1 +扁舟 1 +x:1 +致死 1 +x:1 +木瓜 1 +x:1 +合唱队 1 +x:1 +升势 1 +x:1 +起名 1 +x:1 +侍从 1 +x:1 +菜区 1 +x:1 +撞击 1 +x:1 +暗喻化 1 +x:1 +何不 1 +x:1 +研究 1 +x:1 +开花 1 +x:1 +浮山镇 1 +x:1 +码分多址 1 +x:1 +板球 1 +x:1 +工作日 1 +x:1 +船墩 1 +x:1 +猪崽 1 +x:1 +菜单 1 +x:1 +一马当先 1 +x:1 +贬低 1 +x:1 +珈 1 +x:1 +俗名 1 +x:1 +连年 1 +x:1 +髌骨 1 +x:1 +通考 1 +x:1 +天门 1 +x:1 +羊城 1 +x:1 +忌讳 1 +x:1 +天问 1 +x:1 +公办 1 +x:1 +隐火 1 +x:1 +沉鱼落雁 1 +x:1 +执棒 1 +x:1 +昆仑山 1 +x:1 +掌勺儿 1 +x:1 +昏沉 1 +x:1 +神经痛 1 +x:1 +杂技场 1 +x:1 +对抗赛 1 +x:1 +箱笼 1 +x:1 +公助 1 +x:1 +略逊一筹 1 +x:1 +调羹 1 +x:1 +日心说 1 +x:1 +仪式性 1 +x:1 +阐释 1 +x:1 +神经病 1 +x:1 +棺 3 +x:3 +风和日丽 1 +x:1 +闪烁 1 +x:1 +孔 287 +x:287 +青天白日 1 +x:1 +北京人 1 +x:1 +沟河庄村 1 +x:1 +救治 1 +x:1 +石花胶 1 +x:1 +感咏 1 +x:1 +已故 1 +x:1 +初一 1 +x:1 +船板 1 +x:1 +脖 1 +x:1 +棉球 1 +x:1 +初三 1 +x:1 +圆融 1 +x:1 +致哀 1 +x:1 +外语系 1 +x:1 +磁带 1 +x:1 +沟谷 1 +x:1 +案件 1 +x:1 +菜油 1 +x:1 +公海 1 +x:1 +魔术师 1 +x:1 +然 73 +x:73 +初中 1 +x:1 +终点站 1 +x:1 +棕色棉 1 +x:1 +傍晚 1 +x:1 +华航 1 +x:1 +自愿者 1 +x:1 +初九 1 +x:1 +深证 1 +x:1 +挪动 1 +x:1 +腔骨 1 +x:1 +体癣 1 +x:1 +姐夫 1 +x:1 +话 1351 +x:1351 +帮套 1 +x:1 +按摩厅 1 +x:1 +华舍 1 +x:1 +示踪物 1 +x:1 +粟米 1 +x:1 +延安路 1 +x:1 +安身立命 1 +x:1 +船期 1 +x:1 +公派 1 +x:1 +为画者 1 +x:1 +窘况 1 +x:1 +初五 1 +x:1 +神通 1 +x:1 +文责自负 1 +x:1 +党中央 1 +x:1 +神速 1 +x:1 +耐热合金 1 +x:1 +涩谷 1 +x:1 +双酚A 1 +x:1 +吃食 1 +x:1 +赤峰市 1 +x:1 +初二 1 +x:1 +大中小型 1 +x:1 +七嘴八舌 1 +x:1 +被代理人 1 +x:1 +救民 1 +x:1 +心诚之至 1 +x:1 +姐姐 1 +x:1 +咸肉 1 +x:1 +牙轮 1 +x:1 +顶效 1 +x:1 +条块状 1 +x:1 +熔古铄今 1 +x:1 +循 38 +x:38 +湾畔 1 +x:1 +初交 1 +x:1 +知春路 1 +x:1 +不怕苦 1 +x:1 +雀巢咖啡 1 +x:1 +猪手 1 +x:1 +写信者 1 +x:1 +归藏 1 +x:1 +阻遏 1 +x:1 +隐伏 1 +x:1 +至诚 1 +x:1 +起步 1 +x:1 +摩挲 1 +x:1 +羊棚 1 +x:1 +菇子 1 +x:1 +昏厥 1 +x:1 +姐妹 1 +x:1 +东庞矿 1 +x:1 +人事院 1 +x:1 +崇文区 1 +x:1 +制酒厂 1 +x:1 +血管钳 1 +x:1 +罕 2 +x:2 +冷却塔 1 +x:1 +行礼 1 +x:1 +胖大海 1 +x:1 +口琴 1 +x:1 +案主 1 +x:1 +郁夏 1 +x:1 +回扣 1 +x:1 +欣赏 1 +x:1 +茶镜 1 +x:1 +绒绒的 1 +x:1 +专司 1 +x:1 +景 86 +x:86 +优质棉 1 +x:1 +菜汤 1 +x:1 +招贴牌 1 +x:1 +天赐良机 1 +x:1 +热那亚 1 +x:1 +肥硕 1 +x:1 +铸 69 +x:69 +音乐团 1 +x:1 +脾胃 1 +x:1 +不足为怪 1 +x:1 +巾 4 +x:4 +刺猬 1 +x:1 +诵经台 1 +x:1 +纤毫 1 +x:1 +华药 1 +x:1 +核桃肉 1 +x:1 +社头 1 +x:1 +博大胸怀 1 +x:1 +专卖局 1 +x:1 +出米率 1 +x:1 +怅惘 1 +x:1 +锚拉式 1 +x:1 +初伏 1 +x:1 +建兰 1 +x:1 +马戏节 1 +x:1 +肠壁 1 +x:1 +面谢 1 +x:1 +吃饭 1 +x:1 +吴县市 1 +x:1 +棉田 1 +x:1 +车轱辘话 1 +x:1 +拒腐防变 1 +x:1 +废地 1 +x:1 +竖琴 1 +x:1 +纤毛 1 +x:1 +程林街 1 +x:1 +脾脏 1 +x:1 +公汽 1 +x:1 +叛徒 1 +x:1 +拒谏饰非 1 +x:1 +口疮 1 +x:1 +升汞 1 +x:1 +娟好 1 +x:1 +赢利 1 +x:1 +销货车 1 +x:1 +案例 1 +x:1 +原籍 1 +x:1 +思想界 1 +x:1 +熟手 1 +x:1 +公民 1 +x:1 +冷落 1 +x:1 +补偏救弊 1 +x:1 +俟 1 +x:1 +神采 1 +x:1 +北非洲 1 +x:1 +槐树 1 +x:1 +友好史 1 +x:1 +审视 1 +x:1 +照猫画虎 1 +x:1 +牵动型 1 +x:1 +猪排 1 +x:1 +国情 1 +x:1 +主句 1 +x:1 +禁欲 1 +x:1 +荒老 1 +x:1 +咫尺 1 +x:1 +会昌县 1 +x:1 +遭灾 1 +x:1 +文学梦 1 +x:1 +敌军 1 +x:1 +常州沟 1 +x:1 +荫凉 1 +x:1 +史菜园队 1 +x:1 +远遁千年 1 +x:1 +刺玫 1 +x:1 +救活 1 +x:1 +未决犯 1 +x:1 +璎 1 +x:1 +林权证 1 +x:1 +闪亮 1 +x:1 +公法 1 +x:1 +违心 1 +x:1 +思想解放 1 +x:1 +安全观 1 +x:1 +橡皮线 1 +x:1 +阶段性 1 +x:1 +晋东南 1 +x:1 +热效率 1 +x:1 +气味相投 1 +x:1 +改编者 1 +x:1 +长者 1 +x:1 +长老 1 +x:1 +磁心 1 +x:1 +三天三夜 1 +x:1 +赫—伯法 1 +x:1 +镁光 1 +x:1 +原糖 1 +x:1 +客体化 1 +x:1 +一举数得 1 +x:1 +伴奏 1 +x:1 +吃香 1 +x:1 +橡皮绳 1 +x:1 +监控台 1 +x:1 +饥寒交加 1 +x:1 +红4师 1 +x:1 +一侧 1 +x:1 +话音 1 +x:1 +赤角 1 +x:1 +冲腾 1 +x:1 +毡袍 1 +x:1 +建农 1 +x:1 +建军 1 +x:1 +施舍 1 +x:1 +营运 1 +x:1 +道情 1 +x:1 +救济 1 +x:1 +外骨骼 1 +x:1 +从权 1 +x:1 +赵湾乡 1 +x:1 +减负办 1 +x:1 +绿宝石 1 +x:1 +顶柱 1 +x:1 +卡特尔 1 +x:1 +面谕 1 +x:1 +讥薄 1 +x:1 +柏枝 1 +x:1 +考评科 1 +x:1 +柏林 1 +x:1 +道指 1 +x:1 +荒草 1 +x:1 +失泄密 1 +x:1 +思虑 1 +x:1 +蹈 9 +x:9 +汪洋 1 +x:1 +支行 1 +x:1 +坎 8 +x:8 +公演 1 +x:1 +肝胆 1 +x:1 +帮子 1 +x:1 +建制 1 +x:1 +政策性 1 +x:1 +舍已为公 1 +x:1 +亭亭 1 +x:1 +惘然 1 +x:1 +回报 1 +x:1 +磁山 1 +x:1 +南北朝 1 +x:1 +原罪 1 +x:1 +禁核 1 +x:1 +筑就 1 +x:1 +吕贝克市 1 +x:1 +伴娘 1 +x:1 +巴马科 1 +x:1 +大琴村 1 +x:1 +葡萄藤 1 +x:1 +迟缓率 1 +x:1 +牢房 1 +x:1 +海基导弹 1 +x:1 +顶板 1 +x:1 +不负众望 1 +x:1 +超稀植 1 +x:1 +抹杀 1 +x:1 +悬 53 +x:53 +肠子 1 +x:1 +览 7 +x:7 +臭帽 1 +x:1 +塔龙佳 1 +x:1 +会务组 1 +x:1 +虾兵蟹将 1 +x:1 +淀粉 1 +x:1 +截击机 1 +x:1 +编织袋 1 +x:1 +脸形 1 +x:1 +三二联防 1 +x:1 +摇滚 1 +x:1 +青灯枝笔 1 +x:1 +揖 3 +x:3 +废品 1 +x:1 +江西区 1 +x:1 +牙质 1 +x:1 +挪借 1 +x:1 +闷胀 1 +x:1 +玄武 1 +x:1 +俄央行 1 +x:1 +独立自主 1 +x:1 +跋扈 1 +x:1 +疾病 1 +x:1 +磁峰 1 +x:1 +行笔 1 +x:1 +建功 1 +x:1 +风化砂 1 +x:1 +元器件 1 +x:1 +叶 618 +x:618 +袁派 1 +x:1 +柏村 1 +x:1 +审计 1 +x:1 +审订 1 +x:1 +锻件 1 +x:1 +训练 1 +x:1 +刀锋 1 +x:1 +建卡 1 +x:1 +来安县 1 +x:1 +审议 1 +x:1 +厂 1035 +x:1035 +敌台 1 +x:1 +情节链 1 +x:1 +键盘乐器 1 +x:1 +顶替 1 +x:1 +国投 1 +x:1 +建华 1 +x:1 +逢 94 +x:94 +荆条 1 +x:1 +志士 1 +x:1 +敌友 1 +x:1 +钩针 1 +x:1 +禽产品 1 +x:1 +脸庞 1 +x:1 +吉隆坡 1 +x:1 +梯云岭 1 +x:1 +中莲花村 1 +x:1 +丑类 1 +x:1 +升温 1 +x:1 +庄里 1 +x:1 +庄重 1 +x:1 +挑选 1 +x:1 +急诊室 1 +x:1 +青菜头 1 +x:1 +春色满园 1 +x:1 +服务生 1 +x:1 +纤公里 1 +x:1 +施肥 1 +x:1 +筑巢 1 +x:1 +糜烂 1 +x:1 +积存 1 +x:1 +蛙 6 +x:6 +审读 1 +x:1 +社学 1 +x:1 +星空 1 +x:1 +审证 1 +x:1 +涩进 1 +x:1 +鲁艺 1 +x:1 +审评 1 +x:1 +旅行团 1 +x:1 +庶母 1 +x:1 +接话人 1 +x:1 +港人治港 1 +x:1 +备抵金 1 +x:1 +五海村 1 +x:1 +赞成票 1 +x:1 +盹 1 +x:1 +加工户 1 +x:1 +兼程 1 +x:1 +性命交关 1 +x:1 +始末 1 +x:1 +阿尔山 1 +x:1 +衬里 1 +x:1 +倍 758 +x:758 +纠纷案 1 +x:1 +三汇镇 1 +x:1 +翅果 1 +x:1 +歹人 1 +x:1 +长航 1 +x:1 +熟悉 1 +x:1 +多姆斯特 1 +x:1 +肝脏 1 +x:1 +养生学 1 +x:1 +洗浴液 1 +x:1 +工夫 1 +x:1 +家长味 1 +x:1 +体疗 1 +x:1 +携家带口 1 +x:1 +抚顺市 1 +x:1 +蚕种 1 +x:1 +开放型 1 +x:1 +舒适 1 +x:1 +欺世惑众 1 +x:1 +民勤县 1 +x:1 +海制品 1 +x:1 +工大 1 +x:1 +物理化学 1 +x:1 +淮安城 1 +x:1 +羊毛 1 +x:1 +人革党 1 +x:1 +彭州市 1 +x:1 +常州港 1 +x:1 +听之任之 1 +x:1 +何物 1 +x:1 +专卖店 1 +x:1 +敌区 1 +x:1 +安全论 1 +x:1 +赫赫巍巍 1 +x:1 +渔人得利 1 +x:1 +枢要 1 +x:1 +执法者 1 +x:1 +购买户 1 +x:1 +荒芜 1 +x:1 +得宠 1 +x:1 +行程 1 +x:1 +建厂 1 +x:1 +冻土带 1 +x:1 +再生力 1 +x:1 +酒柜 1 +x:1 +橡皮糖 1 +x:1 +咸菜 1 +x:1 +羊毫 1 +x:1 +深表 1 +x:1 +短缺型 1 +x:1 +国手 1 +x:1 +小家庭 1 +x:1 +竞骥图 1 +x:1 +独生子 1 +x:1 +货币化 1 +x:1 +神针 1 +x:1 +蔚蓝 1 +x:1 +逆风球 1 +x:1 +医药界 1 +x:1 +思考 1 +x:1 +布洒 1 +x:1 +服务牌 1 +x:1 +排污站 1 +x:1 +引资国 1 +x:1 +欠款人 1 +x:1 +笔砚 1 +x:1 +单弹头 1 +x:1 +膝伤 1 +x:1 +羊水 1 +x:1 +玎玎玲玲 1 +x:1 +沙特王国 1 +x:1 +深达 1 +x:1 +国文 1 +x:1 +柘塘镇 1 +x:1 +魂牵梦系 1 +x:1 +园里 1 +x:1 +菜棚 1 +x:1 +深远 1 +x:1 +凯鲁旺城 1 +x:1 +盲人摸象 1 +x:1 +触摸式 1 +x:1 +灵敏度 1 +x:1 +决不 1 +x:1 +卫生球 1 +x:1 +恒温 1 +x:1 +厚积薄发 1 +x:1 +神经纤维 1 +x:1 +道教 1 +x:1 +口炎 1 +x:1 +工作帽 1 +x:1 +欣见 1 +x:1 +断涌期 1 +x:1 +国旅 1 +x:1 +簿册 1 +x:1 +重债国 1 +x:1 +肝蛭 1 +x:1 +老板桌 1 +x:1 +柴火垛 1 +x:1 +音乐剧 1 +x:1 +必恭必敬 1 +x:1 +发酵仓 1 +x:1 +唐菖蒲 1 +x:1 +省时省力 1 +x:1 +植物群落 1 +x:1 +大决战 1 +x:1 +国政 1 +x:1 +邦国 1 +x:1 +震区 1 +x:1 +压岁钱 1 +x:1 +杂稗壳 1 +x:1 +何用 1 +x:1 +孤儿院 1 +x:1 +战法 1 +x:1 +河西村 1 +x:1 +冬泳者 1 +x:1 +奋斗者 1 +x:1 +羊油 1 +x:1 +王沟村 1 +x:1 +艰苦奋斗 1 +x:1 +庶民 1 +x:1 +珠宝商 1 +x:1 +弹性体 1 +x:1 +购油量 1 +x:1 +借书者 1 +x:1 +乱动 1 +x:1 +地老虎 1 +x:1 +泪光 1 +x:1 +互动力 1 +x:1 +捅 20 +x:20 +蚕纸 1 +x:1 +凉州 1 +x:1 +挂职 1 +x:1 +面票 1 +x:1 +民族英雄 1 +x:1 +搜刮 1 +x:1 +博兴县 1 +x:1 +学学 1 +x:1 +体现者 1 +x:1 +炉边 1 +x:1 +珊瑚虫 1 +x:1 +山基土 1 +x:1 +敌后 1 +x:1 +月石 1 +x:1 +大革命 1 +x:1 +国教 1 +x:1 +帮工 1 +x:1 +野蚕 1 +x:1 +国故 1 +x:1 +奶昔 1 +x:1 +报批 1 +x:1 +僧舍 1 +x:1 +秫秸 1 +x:1 +穿 503 +x:503 +划破 1 +x:1 +谭德下村 1 +x:1 +青岛市 1 +x:1 +祖辈 1 +x:1 +胜境 1 +x:1 +凖 1 +x:1 +感冒 1 +x:1 +杰作 1 +x:1 +刺眼 1 +x:1 +恨之入骨 1 +x:1 +摇椅 1 +x:1 +时口 1 +x:1 +卫生界 1 +x:1 +邦坦 1 +x:1 +拔除 1 +x:1 +富山乡 1 +x:1 +致函 1 +x:1 +跋文 1 +x:1 +睡帽 1 +x:1 +升格 1 +x:1 +理智型 1 +x:1 +致死率 1 +x:1 +坚韧不拔 1 +x:1 +槐汁 1 +x:1 +起源 1 +x:1 +马图林 1 +x:1 +周而复始 1 +x:1 +志庆 1 +x:1 +坪坝 1 +x:1 +重瓣胃 1 +x:1 +开卷有益 1 +x:1 +清泉铺山 1 +x:1 +珏 3 +x:3 +急不可耐 1 +x:1 +湄公河 1 +x:1 +物种数 1 +x:1 +鱼汤 1 +x:1 +西峰山 1 +x:1 +崛起 1 +x:1 +选修课 1 +x:1 +潜 15 +x:15 +船户 1 +x:1 +木业 1 +x:1 +采银 1 +x:1 +冷者 1 +x:1 +低于 1 +x:1 +磁学 1 +x:1 +凉山 1 +x:1 +法西斯 1 +x:1 +外层 1 +x:1 +祖述 1 +x:1 +乱占 1 +x:1 +背心装 1 +x:1 +升档 1 +x:1 +宾馆 1 +x:1 +人性爱 1 +x:1 +豹子 1 +x:1 +麸子 1 +x:1 +彼 14 +x:14 +实干者 1 +x:1 +顾 363 +x:363 +四叠体 1 +x:1 +捷克 1 +x:1 +体现 1 +x:1 +电暖气 1 +x:1 +杀人犯 1 +x:1 +兽群 1 +x:1 +整备所 1 +x:1 +打靶场 1 +x:1 +油灰 1 +x:1 +沂蒙山 1 +x:1 +音乐厅 1 +x:1 +葡萄苗 1 +x:1 +房委会 1 +x:1 +普通法 1 +x:1 +中汽 1 +x:1 +知识源 1 +x:1 +恳切 1 +x:1 +全身心 1 +x:1 +掺杂使假 1 +x:1 +自行车 1 +x:1 +大手大脚 1 +x:1 +上半年度 1 +x:1 +服务班 1 +x:1 +抱石怀沙 1 +x:1 +竞绘 1 +x:1 +饱眼福 1 +x:1 +二传手 1 +x:1 +新泰市 1 +x:1 +所得税 1 +x:1 +商业化 1 +x:1 +月盈 1 +x:1 +阿航 1 +x:1 +感光 1 +x:1 +再贴现率 1 +x:1 +板书 1 +x:1 +赛 199 +x:199 +荣获 1 +x:1 +大跌眼镜 1 +x:1 +胶南市 1 +x:1 +冷肆 1 +x:1 +家长制 1 +x:1 +永州市 1 +x:1 +长葛 1 +x:1 +异位症 1 +x:1 +音乐史 1 +x:1 +专家组 1 +x:1 +夙诺 1 +x:1 +不言而喻 1 +x:1 +明显化 1 +x:1 +鹦鹉 1 +x:1 +乱叫 1 +x:1 +违宪 1 +x:1 +竹园村 1 +x:1 +冷荤 1 +x:1 +世风 1 +x:1 +铁板一块 1 +x:1 +脸容 1 +x:1 +拔河场 1 +x:1 +研 33 +x:33 +通用性 1 +x:1 +敌国 1 +x:1 +逆行者 1 +x:1 +唱反调 1 +x:1 +脏乱 1 +x:1 +奖罚分明 1 +x:1 +大敌当前 1 +x:1 +峰峰 1 +x:1 +公正 1 +x:1 +宣礼塔 1 +x:1 +幸运者 1 +x:1 +节余 1 +x:1 +慢悠悠 1 +x:1 +峰峦 1 +x:1 +挂花 1 +x:1 +感动 1 +x:1 +伯克利 1 +x:1 +忠臣 1 +x:1 +人事部 1 +x:1 +致力 1 +x:1 +继发性 1 +x:1 +羊湖 1 +x:1 +沙湾村 1 +x:1 +兽类 1 +x:1 +考据学 1 +x:1 +经管 1 +x:1 +月界 1 +x:1 +文件库 1 +x:1 +托 116 +x:116 +抹掉 1 +x:1 +救火扬沸 1 +x:1 +拔锚 1 +x:1 +雾气腾腾 1 +x:1 +阻隔 1 +x:1 +门将 1 +x:1 +荣耀 1 +x:1 +魂牵梦绕 1 +x:1 +姐弟 1 +x:1 +风尘仆仆 1 +x:1 +防备 1 +x:1 +加工机 1 +x:1 +公款 1 +x:1 +积年 1 +x:1 +瞒案 1 +x:1 +结晶体 1 +x:1 +峰岭 1 +x:1 +建园 1 +x:1 +对口词 1 +x:1 +熟料 1 +x:1 +警世书 1 +x:1 +地矿厅 1 +x:1 +华蓥 1 +x:1 +民政部 1 +x:1 +河北梆子 1 +x:1 +建国 1 +x:1 +公比 1 +x:1 +郁悒 1 +x:1 +汕尾 1 +x:1 +国本 1 +x:1 +国术 1 +x:1 +弯道 1 +x:1 +志士仁人 1 +x:1 +钙质 1 +x:1 +扉画 1 +x:1 +留意 1 +x:1 +开放办 1 +x:1 +空防区 1 +x:1 +感到 1 +x:1 +榕城 1 +x:1 +姓氏 1 +x:1 +索购 1 +x:1 +致富型 1 +x:1 +硼砂 1 +x:1 +战胜者 1 +x:1 +冷菜 1 +x:1 +深购 1 +x:1 +购置者 1 +x:1 +社庆 1 +x:1 +彭城 1 +x:1 +瓷 10 +x:10 +恒河 1 +x:1 +河渠乡 1 +x:1 +帮忙 1 +x:1 +现政府 1 +x:1 +叶冠 1 +x:1 +撇开 1 +x:1 +奏章 1 +x:1 +舞蹈家 1 +x:1 +宫粉梅 1 +x:1 +百业待兴 1 +x:1 +拍马屁 1 +x:1 +铺盖卷儿 1 +x:1 +雕像头 1 +x:1 +服务点 1 +x:1 +歉年 1 +x:1 +凉快 1 +x:1 +更夫 1 +x:1 +国权 1 +x:1 +经团联 1 +x:1 +平均利润 1 +x:1 +脸孔 1 +x:1 +最 6681 +x:6681 +开放区 1 +x:1 +积弊 1 +x:1 +江西团 1 +x:1 +阿胶 1 +x:1 +水鳖子 1 +x:1 +思茅 1 +x:1 +触摸屏 1 +x:1 +冷艳 1 +x:1 +冷色 1 +x:1 +峰巅 1 +x:1 +家荠菜 1 +x:1 +食品摊 1 +x:1 +原稿 1 +x:1 +玩具商 1 +x:1 +小打小闹 1 +x:1 +示性类 1 +x:1 +商业主义 1 +x:1 +帮帮 1 +x:1 +五香 1 +x:1 +笔笔 1 +x:1 +帮带 1 +x:1 +洗手盆 1 +x:1 +凉席 1 +x:1 +磁头 1 +x:1 +头发丝 1 +x:1 +窘困 1 +x:1 +积弱 1 +x:1 +行约 1 +x:1 +标石 1 +x:1 +起泡 1 +x:1 +靓女 1 +x:1 +当腰 1 +x:1 +氮肥厂 1 +x:1 +国际会 1 +x:1 +采集 1 +x:1 +心理学家 1 +x:1 +百鸟衣 1 +x:1 +归航 1 +x:1 +滚轮 1 +x:1 +多云转阴 1 +x:1 +乱兵 1 +x:1 +煤 171 +x:171 +感叹 1 +x:1 +愁眉不展 1 +x:1 +笔答 1 +x:1 +印度半岛 1 +x:1 +笔筒 1 +x:1 +借此机会 1 +x:1 +高级社 1 +x:1 +感召 1 +x:1 +昏君 1 +x:1 +铜仁市 1 +x:1 +陶 249 +x:249 +维新派 1 +x:1 +音频 1 +x:1 +外伶仃岛 1 +x:1 +跛子 1 +x:1 +大可不必 1 +x:1 +感化 1 +x:1 +高中级 1 +x:1 +鏊子 1 +x:1 +公告费 1 +x:1 +官房长官 1 +x:1 +堂皇正大 1 +x:1 +肥缺 1 +x:1 +共事 1 +x:1 +暂存处 1 +x:1 +靠海吃海 1 +x:1 +建城 1 +x:1 +应急 1 +x:1 +购书者 1 +x:1 +深谷 1 +x:1 +硅光板 1 +x:1 +笔算 1 +x:1 +摆勺村 1 +x:1 +麻雀战 1 +x:1 +检查官 1 +x:1 +滚边 1 +x:1 +保留期 1 +x:1 +葡萄胎 1 +x:1 +共享 1 +x:1 +海棠花 1 +x:1 +晁 4 +x:4 +首脑会 1 +x:1 +塔科马市 1 +x:1 +精致 1 +x:1 +狱警 1 +x:1 +中试厂 1 +x:1 +荣膺 1 +x:1 +俗气 1 +x:1 +长虫 1 +x:1 +棕黄 1 +x:1 +威猛 1 +x:1 +票房价值 1 +x:1 +危旧房 1 +x:1 +求胜心切 1 +x:1 +配套厂 1 +x:1 +高中组 1 +x:1 +核桃虫 1 +x:1 +吉隆县 1 +x:1 +肇始 1 +x:1 +道听途说 1 +x:1 +地瓜蔓 1 +x:1 +氯丹 1 +x:1 +憋气 1 +x:1 +棉珠 1 +x:1 +从那之后 1 +x:1 +刺痒 1 +x:1 +原生 1 +x:1 +竞猜 1 +x:1 +流通税 1 +x:1 +公敌 1 +x:1 +吃水线 1 +x:1 +动荡不定 1 +x:1 +序 62 +x:62 +相遇 1 +x:1 +音乐师 1 +x:1 +低估 1 +x:1 +聚居地 1 +x:1 +冯村 1 +x:1 +动荡不安 1 +x:1 +沿江 1 +x:1 +的黎波里 1 +x:1 +曝光台 1 +x:1 +阴山背后 1 +x:1 +叛国 1 +x:1 +男尊女卑 1 +x:1 +线形动物 1 +x:1 +净增支 1 +x:1 +瘴疠 1 +x:1 +由此及彼 1 +x:1 +冷货 1 +x:1 +镁砂厂 1 +x:1 +吃透 1 +x:1 +口粮 1 +x:1 +房地产权 1 +x:1 +建堤 1 +x:1 +冷贮 1 +x:1 +中华路 1 +x:1 +摇摇 1 +x:1 +遐 1 +x:1 +雾霭 1 +x:1 +仙真岩 1 +x:1 +器材厂 1 +x:1 +施训 1 +x:1 +乘务警 1 +x:1 +胶南县 1 +x:1 +棉籽 1 +x:1 +国槐 1 +x:1 +十七日 1 +x:1 +工作制 1 +x:1 +小汤山镇 1 +x:1 +何种 1 +x:1 +邦威 1 +x:1 +幸福林 1 +x:1 +检查员 1 +x:1 +掌柜 1 +x:1 +横街镇 1 +x:1 +协议 1 +x:1 +陪房 1 +x:1 +功能性 1 +x:1 +唏嘘落泪 1 +x:1 +须水镇 1 +x:1 +界桩 1 +x:1 +拉丁 1 +x:1 +海洋生物 1 +x:1 +服务组 1 +x:1 +永丰村 1 +x:1 +憧憬 1 +x:1 +服务经 1 +x:1 +心静 1 +x:1 +过继 1 +x:1 +肺脏 1 +x:1 +纤手 1 +x:1 +隔世 1 +x:1 +味醇 1 +x:1 +摇撼 1 +x:1 +典雅 1 +x:1 +相逢 1 +x:1 +中提琴 1 +x:1 +器乐曲 1 +x:1 +狗鱼 1 +x:1 +都斛镇 1 +x:1 +公文 1 +x:1 +仄 1 +x:1 +测控站 1 +x:1 +盛会 1 +x:1 +五陵 1 +x:1 +沿河 1 +x:1 +绚烂 1 +x:1 +可靠率 1 +x:1 +显著 1 +x:1 +存小异 1 +x:1 +徐庄村 1 +x:1 +三三两两 1 +x:1 +魔术团 1 +x:1 +臆说 1 +x:1 +编委会 1 +x:1 +肠儿 1 +x:1 +锈病 1 +x:1 +界标 1 +x:1 +公斤 1 +x:1 +残渣余孽 1 +x:1 +线坯子 1 +x:1 +腥味儿 1 +x:1 +公断 1 +x:1 +活劳动 1 +x:1 +山珍海味 1 +x:1 +盛传 1 +x:1 +铭印 1 +x:1 +臭味 1 +x:1 +圆轨 1 +x:1 +并驾齐驱 1 +x:1 +从井救人 1 +x:1 +明道 1 +x:1 +肺腑 1 +x:1 +帮凶 1 +x:1 +常春藤 1 +x:1 +笔画 1 +x:1 +功道杯 1 +x:1 +杨屯镇 1 +x:1 +沿海 1 +x:1 +演职员 1 +x:1 +六月 1 +x:1 +工作单 1 +x:1 +柏油 1 +x:1 +六朝 1 +x:1 +原理 1 +x:1 +废弃 1 +x:1 +黄连木 1 +x:1 +西城区 1 +x:1 +长袖 1 +x:1 +遁身 1 +x:1 +长袍 1 +x:1 +隽秀 1 +x:1 +寻人 1 +x:1 +序时账 1 +x:1 +检阅 1 +x:1 +奶毛 1 +x:1 +淮委会 1 +x:1 +青梅竹马 1 +x:1 +窘境 1 +x:1 +建大 1 +x:1 +五音 1 +x:1 +奋斗路 1 +x:1 +家访组 1 +x:1 +鲁殿灵光 1 +x:1 +起拱 1 +x:1 +勋努达美 1 +x:1 +盛事 1 +x:1 +采风 1 +x:1 +长裤 1 +x:1 +外公切线 1 +x:1 +道桥 1 +x:1 +风风雨雨 1 +x:1 +体罚 1 +x:1 +农林部 1 +x:1 +长裙 1 +x:1 +兼并热 1 +x:1 +起拍 1 +x:1 +胡编乱造 1 +x:1 +恒指 1 +x:1 +盛产 1 +x:1 +棉絮 1 +x:1 +建外 1 +x:1 +国棉 1 +x:1 +玄想 1 +x:1 +寒意料峭 1 +x:1 +不遗余力 1 +x:1 +华语 1 +x:1 +吃重 1 +x:1 +国格 1 +x:1 +沙卵石 1 +x:1 +潢川县 1 +x:1 +骨肉相残 1 +x:1 +间歇 1 +x:1 +虚构者 1 +x:1 +闲置费 1 +x:1 +玄思 1 +x:1 +祖茔 1 +x:1 +任何人 1 +x:1 +蔚秀园 1 +x:1 +兽环 1 +x:1 +伴儿 1 +x:1 +挂账 1 +x:1 +拔高 1 +x:1 +建始 1 +x:1 +工作史 1 +x:1 +工作台 1 +x:1 +归去来兮 1 +x:1 +专门利人 1 +x:1 +国标 1 +x:1 +澳门 1 +x:1 +帝王 1 +x:1 +华诞 1 +x:1 +荣将镇 1 +x:1 +建委 1 +x:1 +形象镜 1 +x:1 +兽王 1 +x:1 +积冰 1 +x:1 +君子 1 +x:1 +盛世 1 +x:1 +黄粱一梦 1 +x:1 +另选人 1 +x:1 +肥煤 1 +x:1 +无头案 1 +x:1 +口紧 1 +x:1 +岩丛 1 +x:1 +席卷而逃 1 +x:1 +长衫 1 +x:1 +荣辱 1 +x:1 +长衣 1 +x:1 +氮氧化物 1 +x:1 +变造 1 +x:1 +救救 1 +x:1 +深色 1 +x:1 +新野县 1 +x:1 +安乐椅 1 +x:1 +长街 1 +x:1 +废弃地 1 +x:1 +楫 2 +x:2 +梦 281 +x:281 +筑坝 1 +x:1 +彩虹门 1 +x:1 +志利 1 +x:1 +不可收拾 1 +x:1 +民歌式 1 +x:1 +心潮澎湃 1 +x:1 +轻伤者 1 +x:1 +思路 1 +x:1 +伴入 1 +x:1 +文学性 1 +x:1 +冷轧 1 +x:1 +下狠心 1 +x:1 +公杂 1 +x:1 +沙庆乡 1 +x:1 +淮安市 1 +x:1 +陶利嘎查 1 +x:1 +感应 1 +x:1 +鳞茎 1 +x:1 +电盲 1 +x:1 +苏州府志 1 +x:1 +润肤霜 1 +x:1 +坠落 1 +x:1 +管 715 +x:715 +脸型 1 +x:1 +原眼 1 +x:1 +柚木 1 +x:1 +尤 74 +x:74 +忙忙碌碌 1 +x:1 +血淋淋 1 +x:1 +公开日 1 +x:1 +磕磕巴巴 1 +x:1 +肥胖率 1 +x:1 +国殇 1 +x:1 +巴巴多斯 1 +x:1 +御厨 1 +x:1 +非良性 1 +x:1 +株连九族 1 +x:1 +河田镇 1 +x:1 +凑数 1 +x:1 +软乎乎 1 +x:1 +礼 67 +x:67 +口红 1 +x:1 +干瞪眼 1 +x:1 +公有 1 +x:1 +干净利落 1 +x:1 +摇晃 1 +x:1 +寸土不让 1 +x:1 +打工族 1 +x:1 +平方根 1 +x:1 +建账率 1 +x:1 +女仆 1 +x:1 +田庄乡 1 +x:1 +绣鞋 1 +x:1 +防伪盖 1 +x:1 +长话 1 +x:1 +深致 1 +x:1 +丙酮 1 +x:1 +长诗 1 +x:1 +法门寺 1 +x:1 +血肉横飞 1 +x:1 +奇耻大辱 1 +x:1 +流水作业 1 +x:1 +海城 1 +x:1 +刀枪不入 1 +x:1 +低俗 1 +x:1 +梆硬 1 +x:1 +刀鱼 1 +x:1 +围棋 1 +x:1 +卫生站 1 +x:1 +万事俱备 1 +x:1 +奥希金斯 1 +x:1 +注册费 1 +x:1 +侵略性 1 +x:1 +徒手 1 +x:1 +丙醇 1 +x:1 +提篮小卖 1 +x:1 +糌巴 1 +x:1 +昌宁县 1 +x:1 +金盏乡 1 +x:1 +维修厂 1 +x:1 +商业局 1 +x:1 +贫穷帽 1 +x:1 +道路以目 1 +x:1 +帮厨 1 +x:1 +摁钉儿 1 +x:1 +棉纺 1 +x:1 +棉线 1 +x:1 +茶汤壶 1 +x:1 +棉纱 1 +x:1 +过来 1 +x:1 +荒诞 1 +x:1 +归还 1 +x:1 +救星 1 +x:1 +连锁式 1 +x:1 +敌击我隐 1 +x:1 +完毕 1 +x:1 +碧天 1 +x:1 +守林员 1 +x:1 +优胜处 1 +x:1 +华裔 1 +x:1 +师姐 1 +x:1 +体系 1 +x:1 +炉膛 1 +x:1 +笔直 1 +x:1 +棉绒 1 +x:1 +检查团 1 +x:1 +群星荟萃 1 +x:1 +街 304 +x:304 +毖 1 +x:1 +新桥镇 1 +x:1 +战抖 1 +x:1 +藕片 1 +x:1 +阿贡 1 +x:1 +掌故 1 +x:1 +憨态可掬 1 +x:1 +军团长 1 +x:1 +赔付率 1 +x:1 +凉台 1 +x:1 +喜眉笑眼 1 +x:1 +应用题 1 +x:1 +将错就错 1 +x:1 +峰值 1 +x:1 +战报 1 +x:1 +尊敬 1 +x:1 +全民公决 1 +x:1 +生产链 1 +x:1 +何等 1 +x:1 +肥牛 1 +x:1 +国歌 1 +x:1 +八卦掌 1 +x:1 +佐料 1 +x:1 +侃 13 +x:13 +罗马 1 +x:1 +冻死 1 +x:1 +自生堰村 1 +x:1 +萨克斯 1 +x:1 +八二年 1 +x:1 +华西 1 +x:1 +新月村 1 +x:1 +沙石灰 1 +x:1 +敌对 1 +x:1 +敌寇 1 +x:1 +团团伙伙 1 +x:1 +囚 4 +x:4 +顾惜 1 +x:1 +主设计者 1 +x:1 +肥王 1 +x:1 +荒水面 1 +x:1 +未眠 1 +x:1 +宗教画 1 +x:1 +增订本 1 +x:1 +世间 1 +x:1 +开放式 1 +x:1 +判若鸿沟 1 +x:1 +女侠 1 +x:1 +小岗村 1 +x:1 +花花公子 1 +x:1 +差别性 1 +x:1 +别树一帜 1 +x:1 +决定权 1 +x:1 +威士忌酒 1 +x:1 +主席会 1 +x:1 +行状 1 +x:1 +丢官 1 +x:1 +水文局 1 +x:1 +希伯莱 1 +x:1 +敌害 1 +x:1 +农调队 1 +x:1 +宗教界 1 +x:1 +货币局 1 +x:1 +学业有成 1 +x:1 +高中版 1 +x:1 +膀阔腰圆 1 +x:1 +红绿灯 1 +x:1 +感念 1 +x:1 +布置一新 1 +x:1 +善本库 1 +x:1 +挂号信 1 +x:1 +琳琅满目 1 +x:1 +天蚕蛾 1 +x:1 +船民 1 +x:1 +繁难 1 +x:1 +病原菌 1 +x:1 +医药站 1 +x:1 +购置费 1 +x:1 +海晏县 1 +x:1 +积压 1 +x:1 +八卦拳 1 +x:1 +肥猪 1 +x:1 +海地 1 +x:1 +动力车 1 +x:1 +光板儿 1 +x:1 +施用量 1 +x:1 +建寺 1 +x:1 +文学所 1 +x:1 +罗布泊 1 +x:1 +荒诞剧 1 +x:1 +粥样 1 +x:1 +帮助 1 +x:1 +C 93 +x:93 +船泊 1 +x:1 +肝吸虫 1 +x:1 +沾光 1 +x:1 +防震棚 1 +x:1 +镶嵌 1 +x:1 +感觉神经 1 +x:1 +女伴 1 +x:1 +舱 34 +x:34 +版面 1 +x:1 +施行 1 +x:1 +修好 1 +x:1 +思辩 1 +x:1 +思辨 1 +x:1 +竖线 1 +x:1 +暗号 1 +x:1 +俗态 1 +x:1 +崔巷 1 +x:1 +无所作为 1 +x:1 +建客 1 +x:1 +擎接 1 +x:1 +更名 1 +x:1 +借书车 1 +x:1 +日见其大 1 +x:1 +公布牌 1 +x:1 +中南部 1 +x:1 +神魄 1 +x:1 +惠存 1 +x:1 +盎然 1 +x:1 +六日 1 +x:1 +绑 22 +x:22 +挂车 1 +x:1 +辣妹子 1 +x:1 +执罚队 1 +x:1 +条条缕缕 1 +x:1 +菜板 1 +x:1 +眼线 1 +x:1 +板擦儿 1 +x:1 +筹集 1 +x:1 +挂轴 1 +x:1 +锋芒 1 +x:1 +六时 1 +x:1 +氢镍 1 +x:1 +女佣 1 +x:1 +挂载 1 +x:1 +齐整整 1 +x:1 +桦树街 1 +x:1 +阿谀 1 +x:1 +浇筑量 1 +x:1 +气喘吁吁 1 +x:1 +遽然 1 +x:1 +尖草坪 1 +x:1 +磕头 1 +x:1 +独门独户 1 +x:1 +长足 1 +x:1 +无骨架 1 +x:1 +讥讽 1 +x:1 +拖后腿 1 +x:1 +组配 1 +x:1 +聚居区 1 +x:1 +典鉴 1 +x:1 +沅江 1 +x:1 +船歌 1 +x:1 +锦 19 +x:19 +变频管 1 +x:1 +棉纺织厂 1 +x:1 +决定性 1 +x:1 +八卦教 1 +x:1 +滚落 1 +x:1 +高中生 1 +x:1 +巴恩市 1 +x:1 +妹 32 +x:32 +九五 1 +x:1 +讥诮 1 +x:1 +辛集市 1 +x:1 +轻者 1 +x:1 +噶厦 1 +x:1 +闹情绪者 1 +x:1 +公意 1 +x:1 +人民警察 1 +x:1 +遁词 1 +x:1 +荒败 1 +x:1 +平肝熄风 1 +x:1 +仁和区 1 +x:1 +界河 1 +x:1 +供方 1 +x:1 +大宛齐 1 +x:1 +养狐场 1 +x:1 +社员 1 +x:1 +公愤 1 +x:1 +通天尽人 1 +x:1 +恒星 1 +x:1 +广为人知 1 +x:1 +长跑 1 +x:1 +肥胖症 1 +x:1 +子叶 1 +x:1 +私盐案 1 +x:1 +水文学 1 +x:1 +河津市 1 +x:1 +大中小学 1 +x:1 +忠诚 1 +x:1 +货币学 1 +x:1 +口碑 1 +x:1 +原煤 1 +x:1 +严重度 1 +x:1 +泄私愤 1 +x:1 +大中企业 1 +x:1 +以邻为壑 1 +x:1 +服务站 1 +x:1 +业务 1 +x:1 +瞒报 1 +x:1 +伴同 1 +x:1 +用种量 1 +x:1 +救急 1 +x:1 +广柑 1 +x:1 +磁力 1 +x:1 +兽皮 1 +x:1 +顶楼 1 +x:1 +聚居县 1 +x:1 +布政使 1 +x:1 +喽罗 1 +x:1 +瓦隆人 1 +x:1 +重庆团 1 +x:1 +以身殉职 1 +x:1 +菇场 1 +x:1 +寒暑假 1 +x:1 +繁殖量 1 +x:1 +贞操 1 +x:1 +主厅 1 +x:1 +兴致勃勃 1 +x:1 +灯光 1 +x:1 +徐悲鸿 1 +x:1 +茶房 1 +x:1 +硬设备 1 +x:1 +起来 1 +x:1 +石柱湾 1 +x:1 +服务窗 1 +x:1 +监考员 1 +x:1 +熔铁铄金 1 +x:1 +刺绣 1 +x:1 +按部就班 1 +x:1 +威信扫地 1 +x:1 +九七 1 +x:1 +试营业 1 +x:1 +防伪灯 1 +x:1 +集贤县 1 +x:1 +层峦迭嶂 1 +x:1 +荣誉 1 +x:1 +丁金村 1 +x:1 +挂表 1 +x:1 +萦思 1 +x:1 +消费量 1 +x:1 +玩具店 1 +x:1 +长赋 1 +x:1 +哪怕 1 +x:1 +迫在眉睫 1 +x:1 +狗尾草 1 +x:1 +暮年 1 +x:1 +善于 1 +x:1 +善事 1 +x:1 +被毁灭者 1 +x:1 +愈 105 +x:105 +马前卒 1 +x:1 +叛变 1 +x:1 +倒买倒卖 1 +x:1 +磁化 1 +x:1 +者 347 +x:347 +不称职者 1 +x:1 +平方海里 1 +x:1 +山耳东村 1 +x:1 +长野市 1 +x:1 +阿尔勒 1 +x:1 +讯 4046 +x:4046 +活动类 1 +x:1 +善人 1 +x:1 +伤天害理 1 +x:1 +不完全叶 1 +x:1 +姐告 1 +x:1 +顶棚 1 +x:1 +一劳永逸 1 +x:1 +乱子 1 +x:1 +国泰 1 +x:1 +船模 1 +x:1 +朗朗上口 1 +x:1 +特许权 1 +x:1 +荒谬 1 +x:1 +宽宽敞敞 1 +x:1 +慈眉善目 1 +x:1 +蚕眠 1 +x:1 +禁期 1 +x:1 +磁卡 1 +x:1 +灰尘肺 1 +x:1 +见示 1 +x:1 +口福 1 +x:1 +写字台 1 +x:1 +工作地 1 +x:1 +围桌 1 +x:1 +福州市人 1 +x:1 +坞修 1 +x:1 +凑手 1 +x:1 +音乐季 1 +x:1 +更加 1 +x:1 +现代式 1 +x:1 +磁厂 1 +x:1 +俭省 1 +x:1 +海安市 1 +x:1 +蜇 1 +x:1 +建工 1 +x:1 +化淤 1 +x:1 +独步天下 1 +x:1 +发展史 1 +x:1 +京门 1 +x:1 +违反 1 +x:1 +清运率 1 +x:1 +肥田 1 +x:1 +羚角 1 +x:1 +带材 1 +x:1 +忠言 1 +x:1 +国民 1 +x:1 +原点 1 +x:1 +各执一端 1 +x:1 +丁坝 1 +x:1 +中宣部 1 +x:1 +氧原子 1 +x:1 +音乐家 1 +x:1 +伴唱 1 +x:1 +善举 1 +x:1 +新 14101 +x:14101 +冲账 1 +x:1 +音乐宫 1 +x:1 +善为 1 +x:1 +长谈 1 +x:1 +沾化县 1 +x:1 +牙色 1 +x:1 +长调 1 +x:1 +乘着 1 +x:1 +柏树 1 +x:1 +无牌照 1 +x:1 +吱吱喳喳 1 +x:1 +诸旅 1 +x:1 +带机 1 +x:1 +艺丛 1 +x:1 +不可名状 1 +x:1 +瓦尔米吉 1 +x:1 +无误 1 +x:1 +海巡队 1 +x:1 +月终 1 +x:1 +辐条 1 +x:1 +棉种 1 +x:1 +月经 1 +x:1 +昏庸 1 +x:1 +荣记 1 +x:1 +电喷车 1 +x:1 +棉秆 1 +x:1 +服务箱 1 +x:1 +冲走 1 +x:1 +西阳城 1 +x:1 +化石区 1 +x:1 +锚索 1 +x:1 +探测船 1 +x:1 +漫漶 1 +x:1 +明镜 1 +x:1 +华辞 1 +x:1 +元/车 1 +x:1 +阿訇 1 +x:1 +带有 1 +x:1 +脱出症 1 +x:1 +杂务事 1 +x:1 +长安乡 1 +x:1 +投入量 1 +x:1 +橛子 1 +x:1 +蓦然 1 +x:1 +交割单 1 +x:1 +溪乾 1 +x:1 +公捕 1 +x:1 +救护 1 +x:1 +领班人 1 +x:1 +大青杨 1 +x:1 +建平 1 +x:1 +从教 1 +x:1 +军用犬 1 +x:1 +身 428 +x:428 +称法 1 +x:1 +肥皂 1 +x:1 +艾利逊 1 +x:1 +工作周 1 +x:1 +成文法 1 +x:1 +长辈 1 +x:1 +超低空 1 +x:1 +旅行家 1 +x:1 +深仇大恨 1 +x:1 +圆角 1 +x:1 +猪油 1 +x:1 +牙膏 1 +x:1 +稠乎乎 1 +x:1 +普通机 1 +x:1 +红4军 1 +x:1 +保军转民 1 +x:1 +圆规 1 +x:1 +加里曼丹 1 +x:1 +电工系 1 +x:1 +奶油 1 +x:1 +郁江 1 +x:1 +玛多县 1 +x:1 +深藏 1 +x:1 +长远 1 +x:1 +长进 1 +x:1 +听课率 1 +x:1 +演义 1 +x:1 +云南省 1 +x:1 +遭罪 1 +x:1 +懵 6 +x:6 +可批性 1 +x:1 +僧袍 1 +x:1 +另行 1 +x:1 +废墟 1 +x:1 +涂 59 +x:59 +鼓浪屿 1 +x:1 +神鸟 1 +x:1 +金光灿灿 1 +x:1 +收发报机 1 +x:1 +肥瘦 1 +x:1 +大中镇 1 +x:1 +结伴 1 +x:1 +世道 1 +x:1 +无伤大体 1 +x:1 +仓鼠 1 +x:1 +蒜 16 +x:16 +高丽参 1 +x:1 +结伙 1 +x:1 +阿穆尔虎 1 +x:1 +更其 1 +x:1 +更具 1 +x:1 +押运费 1 +x:1 +购 181 +x:181 +肾囊 1 +x:1 +簿子 1 +x:1 +调任 1 +x:1 +大循环 1 +x:1 +玄机 1 +x:1 +内道 1 +x:1 +银奖 1 +x:1 +调价 1 +x:1 +滚蛋 1 +x:1 +法不责众 1 +x:1 +起敬 1 +x:1 +胳膊腕子 1 +x:1 +种地 1 +x:1 +奶水 1 +x:1 +红雁池 1 +x:1 +凉城 1 +x:1 +病原虫 1 +x:1 +社团 1 +x:1 +建康 1 +x:1 +丑八怪 1 +x:1 +结余 1 +x:1 +深蕴 1 +x:1 +神鹿 1 +x:1 +结体 1 +x:1 +公推 1 +x:1 +河曲县 1 +x:1 +调人 1 +x:1 +冻土区 1 +x:1 +观测期 1 +x:1 +臭味相投 1 +x:1 +权力电 1 +x:1 +船桨 1 +x:1 +卤鸭 1 +x:1 +急用 1 +x:1 +感官 1 +x:1 +卫生网 1 +x:1 +结亲 1 +x:1 +专用区 1 +x:1 +从政 1 +x:1 +卤鸡 1 +x:1 +中科健A 1 +x:1 +致富 1 +x:1 +三台村 1 +x:1 +育人 1 +x:1 +急电 1 +x:1 +结交 1 +x:1 +张 7355 +x:7355 +孔菜 1 +x:1 +峰峰镇 1 +x:1 +油盘 1 +x:1 +劳动保险 1 +x:1 +协调 1 +x:1 +对台戏 1 +x:1 +火筷子 1 +x:1 +舵轮 1 +x:1 +挂记 1 +x:1 +避难间 1 +x:1 +重丘区 1 +x:1 +襄 15 +x:15 +乱套 1 +x:1 +塑瓶 1 +x:1 +叛军 1 +x:1 +含混不清 1 +x:1 +靠水吃水 1 +x:1 +音乐奖 1 +x:1 +解毒 1 +x:1 +调休 1 +x:1 +法文化 1 +x:1 +华贵 1 +x:1 +切割器 1 +x:1 +一股了之 1 +x:1 +观察镜 1 +x:1 +战术 1 +x:1 +毛毯 1 +x:1 +百花争艳 1 +x:1 +服务社 1 +x:1 +战机 1 +x:1 +转型 1 +x:1 +倒轮闸 1 +x:1 +受调查者 1 +x:1 +界面学 1 +x:1 +社址 1 +x:1 +公房 1 +x:1 +结仇 1 +x:1 +臻乎 1 +x:1 +禁放 1 +x:1 +结为 1 +x:1 +电解铜 1 +x:1 +笔简意深 1 +x:1 +雾都 1 +x:1 +叛党 1 +x:1 +杂税 1 +x:1 +千钧重负 1 +x:1 +腰包 1 +x:1 +掺杂 1 +x:1 +财迷心窍 1 +x:1 +包刷处 1 +x:1 +断代史 1 +x:1 +三不管 1 +x:1 +结业 1 +x:1 +扶养 1 +x:1 +叛兵 1 +x:1 +男中音 1 +x:1 +原状 1 +x:1 +核实验 1 +x:1 +幸福观 1 +x:1 +小循环 1 +x:1 +臻于 1 +x:1 +世所少见 1 +x:1 +犁耕层 1 +x:1 +心尖儿 1 +x:1 +调侃 1 +x:1 +吃零嘴 1 +x:1 +竖立 1 +x:1 +见世面 1 +x:1 +离退休金 1 +x:1 +体积 1 +x:1 +战果 1 +x:1 +钻探 1 +x:1 +棚 22 +x:22 +商业处 1 +x:1 +幡 1 +x:1 +沙市区 1 +x:1 +公报 1 +x:1 +徒步 1 +x:1 +公开性 1 +x:1 +急症 1 +x:1 +曲轴 1 +x:1 +俄族人 1 +x:1 +帮困 1 +x:1 +祝福声 1 +x:1 +涪 1 +x:1 +靓丽 1 +x:1 +多毛类 1 +x:1 +当阳 1 +x:1 +结冰 1 +x:1 +冻灾 1 +x:1 +荚果 1 +x:1 +共处 1 +x:1 +锻工 1 +x:1 +调停 1 +x:1 +骆驼绒 1 +x:1 +娜 10 +x:10 +自习率 1 +x:1 +长安县 1 +x:1 +板实 1 +x:1 +离职金 1 +x:1 +嘲笑声 1 +x:1 +涩 6 +x:6 +挂钩 1 +x:1 +拔草 1 +x:1 +韭芽 1 +x:1 +晒谷场 1 +x:1 +血制品 1 +x:1 +闪开 1 +x:1 +缓冲期 1 +x:1 +扩容 1 +x:1 +牙龈 1 +x:1 +扩宽 1 +x:1 +幼雀 1 +x:1 +板对 1 +x:1 +吧台 1 +x:1 +勇飞 1 +x:1 +同温层 1 +x:1 +案底 1 +x:1 +办刊 1 +x:1 +嫩叶 1 +x:1 +隐忧 1 +x:1 +善变 1 +x:1 +原浆 1 +x:1 +菜糊 1 +x:1 +牲粉 1 +x:1 +初年 1 +x:1 +马里兰州 1 +x:1 +计生联 1 +x:1 +办到 1 +x:1 +冷锋 1 +x:1 +筹资 1 +x:1 +利禄 1 +x:1 +长野 1 +x:1 +金粟兰 1 +x:1 +清费治乱 1 +x:1 +调值 1 +x:1 +孤儿节 1 +x:1 +蔡塘 1 +x:1 +挂链 1 +x:1 +遣送 1 +x:1 +倒胃口 1 +x:1 +老江湖 1 +x:1 +瓦店镇 1 +x:1 +结儿 1 +x:1 +笔油 1 +x:1 +播散力 1 +x:1 +羊 224 +x:224 +槟子 1 +x:1 +行楷 1 +x:1 +点票站 1 +x:1 +报恩 1 +x:1 +执行率 1 +x:1 +七老八十 1 +x:1 +党代会 1 +x:1 +征地 1 +x:1 +莱山 1 +x:1 +六级 1 +x:1 +大泽山 1 +x:1 +侪 1 +x:1 +原液 1 +x:1 +初度 1 +x:1 +委托方 1 +x:1 +海测之声 1 +x:1 +奶牙 1 +x:1 +北京市 1 +x:1 +奶牛 1 +x:1 +制造费 1 +x:1 +接茬儿 1 +x:1 +噶伦 1 +x:1 +降冰量 1 +x:1 +六经 1 +x:1 +军事区 1 +x:1 +隐形 1 +x:1 +神聊 1 +x:1 +那达慕 1 +x:1 +神职 1 +x:1 +玷辱 1 +x:1 +名扬天下 1 +x:1 +注塑模 1 +x:1 +饭费 1 +x:1 +蹦子 1 +x:1 +九制 1 +x:1 +文学社 1 +x:1 +敌百虫 1 +x:1 +盛产地 1 +x:1 +墩子 1 +x:1 +笔法 1 +x:1 +电工所 1 +x:1 +肥桃 1 +x:1 +板子 1 +x:1 +丧葬费 1 +x:1 +代英县 1 +x:1 +被动式 1 +x:1 +怅然 1 +x:1 +寄信人 1 +x:1 +当雄 1 +x:1 +冒头 1 +x:1 +国际奖 1 +x:1 +特古米亚 1 +x:1 +冒失 1 +x:1 +兽欲 1 +x:1 +秀水街 1 +x:1 +进而言之 1 +x:1 +公开组 1 +x:1 +原动力 1 +x:1 +吆喝 1 +x:1 +莱州 1 +x:1 +勘定 1 +x:1 +东亭区 1 +x:1 +印发 1 +x:1 +战神 1 +x:1 +星系级 1 +x:1 +阚 7 +x:7 +潜江县 1 +x:1 +针织品 1 +x:1 +筹谋 1 +x:1 +笔洗 1 +x:1 +皇城根 1 +x:1 +劭 1 +x:1 +调入 1 +x:1 +调养 1 +x:1 +该日 1 +x:1 +战祸 1 +x:1 +宝盖头 1 +x:1 +封建王朝 1 +x:1 +三化螟 1 +x:1 +泥质灰岩 1 +x:1 +圆雕 1 +x:1 +急步 1 +x:1 +总务长 1 +x:1 +吞服 1 +x:1 +服务期 1 +x:1 +高中档 1 +x:1 +磁体 1 +x:1 +勘察 1 +x:1 +孤寂感 1 +x:1 +沿用 1 +x:1 +当面 1 +x:1 +冲量 1 +x:1 +原汁 1 +x:1 +胡 1587 +x:1587 +新兴县 1 +x:1 +捍卫者 1 +x:1 +灵验 1 +x:1 +扯秧 1 +x:1 +英格兰队 1 +x:1 +起立 1 +x:1 +枪杀案 1 +x:1 +认命 1 +x:1 +拿手 1 +x:1 +兰大 1 +x:1 +瑰怪 1 +x:1 +选调生 1 +x:1 +拟订 1 +x:1 +刀螂 1 +x:1 +硬货币 1 +x:1 +调减 1 +x:1 +挂锁 1 +x:1 +办发 1 +x:1 +瘴气 1 +x:1 +刺探 1 +x:1 +僧面 1 +x:1 +操作室 1 +x:1 +公布栏 1 +x:1 +食文化 1 +x:1 +梦寐 1 +x:1 +长逝 1 +x:1 +等级分制 1 +x:1 +颁奖 1 +x:1 +长途 1 +x:1 +常州籍 1 +x:1 +陪笑 1 +x:1 +二五眼 1 +x:1 +调出 1 +x:1 +棉纺织业 1 +x:1 +修复师 1 +x:1 +眯瞪 1 +x:1 +盛器 1 +x:1 +荒郊 1 +x:1 +月报 1 +x:1 +拿拿 1 +x:1 +净 157 +x:157 +恩古巴尼 1 +x:1 +学术团 1 +x:1 +环境 1 +x:1 +兼并案 1 +x:1 +哥特式 1 +x:1 +选料 1 +x:1 +拙劣 1 +x:1 +钩虫 1 +x:1 +神经系统 1 +x:1 +办厂 1 +x:1 +猪猡 1 +x:1 +违例 1 +x:1 +阿队 1 +x:1 +拢 23 +x:23 +更为 1 +x:1 +豆奶粉 1 +x:1 +公粮 1 +x:1 +牙克西 1 +x:1 +烟消云散 1 +x:1 +行栈 1 +x:1 +门可罗雀 1 +x:1 +加工点 1 +x:1 +晋察冀 1 +x:1 +拔节 1 +x:1 +拔腿 1 +x:1 +冷面 1 +x:1 +饲料厂 1 +x:1 +助攻型 1 +x:1 +竖有 1 +x:1 +失之空洞 1 +x:1 +硝酸 1 +x:1 +贬抑 1 +x:1 +卫生所 1 +x:1 +初小 1 +x:1 +大山村 1 +x:1 +环子 1 +x:1 +出乖露丑 1 +x:1 +萦绕 1 +x:1 +油头滑脑 1 +x:1 +伪团长 1 +x:1 +蚕桑 1 +x:1 +审验 1 +x:1 +流通性 1 +x:1 +公署 1 +x:1 +核对者 1 +x:1 +· 238 +x:238 +俗称 1 +x:1 +判决书 1 +x:1 +国王 1 +x:1 +利税额 1 +x:1 +地上茎 1 +x:1 +欲壑难平 1 +x:1 +共存 1 +x:1 +小家伙 1 +x:1 +木头 1 +x:1 +电炉子 1 +x:1 +东拉西扯 1 +x:1 +肝郁 1 +x:1 +牢狱 1 +x:1 +那么样 1 +x:1 +排污沟 1 +x:1 +基建工 1 +x:1 +超计划 1 +x:1 +船电 1 +x:1 +结句 1 +x:1 +类新星 1 +x:1 +竖条 1 +x:1 +心乱如麻 1 +x:1 +罗湖 1 +x:1 +等客上门 1 +x:1 +帐幕 1 +x:1 +挂零 1 +x:1 +饲 2 +x:2 +佩奇 1 +x:1 +女团 1 +x:1 +军事史 1 +x:1 +调制 1 +x:1 +决堤 1 +x:1 +羊窝 1 +x:1 +行止 1 +x:1 +促膝长谈 1 +x:1 +五谷 1 +x:1 +卤莽 1 +x:1 +豆腐夭村 1 +x:1 +宾格尔省 1 +x:1 +兼毫 1 +x:1 +征用 1 +x:1 +修鞋匠 1 +x:1 +世象 1 +x:1 +霉烂 1 +x:1 +明言 1 +x:1 +界牌 1 +x:1 +乔其纱 1 +x:1 +炬 2 +x:2 +圆锥 1 +x:1 +自开生面 1 +x:1 +平平淡淡 1 +x:1 +福清市 1 +x:1 +歹徒 1 +x:1 +宽城街 1 +x:1 +当铺 1 +x:1 +钓鱼人 1 +x:1 +检查仪 1 +x:1 +莫明其妙 1 +x:1 +加工率 1 +x:1 +推动性 1 +x:1 +纪纲 1 +x:1 +道班 1 +x:1 +行款 1 +x:1 +剿除 1 +x:1 +扩大 1 +x:1 +调动 1 +x:1 +字纸篓 1 +x:1 +冰球馆 1 +x:1 +歹心 1 +x:1 +目视 1 +x:1 +友谊座 1 +x:1 +机制论 1 +x:1 +卤菜 1 +x:1 +梦境 1 +x:1 +从化市 1 +x:1 +体操 1 +x:1 +采药 1 +x:1 +横线 1 +x:1 +至亲好友 1 +x:1 +拱北关 1 +x:1 +要价 1 +x:1 +体改 1 +x:1 +圈速 1 +x:1 +女垒 1 +x:1 +糖 69 +x:69 +调升 1 +x:1 +壮锦 1 +x:1 +坑农 1 +x:1 +归除 1 +x:1 +黄连素 1 +x:1 +适销 1 +x:1 +菜羊 1 +x:1 +竞标 1 +x:1 +罗田县 1 +x:1 +结办 1 +x:1 +板墙 1 +x:1 +药碾 1 +x:1 +躁动不安 1 +x:1 +稽查队 1 +x:1 +悠闲自得 1 +x:1 +文物者 1 +x:1 +保留率 1 +x:1 +耆宿 1 +x:1 +归附 1 +x:1 +圆钢 1 +x:1 +办公 1 +x:1 +狐狸皮 1 +x:1 +顶盖 1 +x:1 +脏字 1 +x:1 +归降 1 +x:1 +先富者 1 +x:1 +离退休费 1 +x:1 +差错率 1 +x:1 +尕斯库勒 1 +x:1 +诸葛村 1 +x:1 +服役期 1 +x:1 +十四行 1 +x:1 +调匀 1 +x:1 +牙鲆 1 +x:1 +身陷囹圄 1 +x:1 +赔 52 +x:52 +枯立木 1 +x:1 +正传 1 +x:1 +月经带 1 +x:1 +馨香 1 +x:1 +锦城苑 1 +x:1 +扩增 1 +x:1 +明证 1 +x:1 +循化 1 +x:1 +归队 1 +x:1 +晶粒 1 +x:1 +黑咕隆冬 1 +x:1 +高运价率 1 +x:1 +诗词史 1 +x:1 +棉条 1 +x:1 +音乐室 1 +x:1 +中环 1 +x:1 +板壁 1 +x:1 +威权 1 +x:1 +国父 1 +x:1 +悉尼湾 1 +x:1 +姑息迁就 1 +x:1 +冷雨 1 +x:1 +尤杯赛 1 +x:1 +蛎饼 1 +x:1 +四仰八叉 1 +x:1 +红小鬼 1 +x:1 +调取 1 +x:1 +脸上 1 +x:1 +华释 1 +x:1 +华里 1 +x:1 +办函 1 +x:1 +起码 1 +x:1 +间皮瘤 1 +x:1 +神茶 1 +x:1 +膀粗腰圆 1 +x:1 +升级 1 +x:1 +归集 1 +x:1 +异词 1 +x:1 +人头攒动 1 +x:1 +食不果腹 1 +x:1 +拂袖而去 1 +x:1 +调号 1 +x:1 +南蒲 1 +x:1 +橡皮泥 1 +x:1 +蜜瓜 1 +x:1 +腐败 1 +x:1 +快速化 1 +x:1 +乘务部 1 +x:1 +等米下锅 1 +x:1 +贬损 1 +x:1 +威望 1 +x:1 +颜料 1 +x:1 +盛名 1 +x:1 +公约 1 +x:1 +草花蜜 1 +x:1 +捻子 1 +x:1 +挂靠 1 +x:1 +林计 1 +x:1 +挂面 1 +x:1 +生死攸关 1 +x:1 +泪 92 +x:92 +手无寸铁 1 +x:1 +富贵病 1 +x:1 +隐居 1 +x:1 +世贸 1 +x:1 +大排档 1 +x:1 +满负荷 1 +x:1 +环境部 1 +x:1 +动力部 1 +x:1 +麻醉性 1 +x:1 +绍兴县 1 +x:1 +拉下水 1 +x:1 +梦幻 1 +x:1 +昌 14 +x:14 +冷酷 1 +x:1 +服务所 1 +x:1 +月月 1 +x:1 +干鲜果品 1 +x:1 +国际局 1 +x:1 +熙 7 +x:7 +纤维 1 +x:1 +冒尖 1 +x:1 +兰山 1 +x:1 +账 173 +x:173 +纤细 1 +x:1 +复兴村 1 +x:1 +肥沃 1 +x:1 +月末 1 +x:1 +结喉 1 +x:1 +兼济 1 +x:1 +鹞 1 +x:1 +画库 1 +x:1 +央行 1 +x:1 +阿森纳队 1 +x:1 +服务战 1 +x:1 +上周末 1 +x:1 +何时 1 +x:1 +参加国 1 +x:1 +狗肉 1 +x:1 +初婚 1 +x:1 +长安城 1 +x:1 +猪皮 1 +x:1 +泼辣 1 +x:1 +何日 1 +x:1 +当家做主 1 +x:1 +华阳 1 +x:1 +债务率 1 +x:1 +大阪市 1 +x:1 +醉鬼 1 +x:1 +急湍 1 +x:1 +已然 1 +x:1 +反射光 1 +x:1 +臆见 1 +x:1 +淡褐色 1 +x:1 +全堂镇 1 +x:1 +短 326 +x:326 +勃然 1 +x:1 +河卵石 1 +x:1 +公社 1 +x:1 +加工电 1 +x:1 +整合式 1 +x:1 +惹人注目 1 +x:1 +小富即安 1 +x:1 +熟睡 1 +x:1 +不来梅 1 +x:1 +纯洁性 1 +x:1 +顶煤 1 +x:1 +公私 1 +x:1 +轺车 1 +x:1 +国画 1 +x:1 +莱塞 1 +x:1 +跨平台 1 +x:1 +翩翩起舞 1 +x:1 +肥水 1 +x:1 +厚 105 +x:105 +禁绝 1 +x:1 +奶白 1 +x:1 +损毁 1 +x:1 +晏下村 1 +x:1 +扇 39 +x:39 +高林村镇 1 +x:1 +轻嘴薄舌 1 +x:1 +含 323 +x:323 +板式 1 +x:1 +幌子 1 +x:1 +抹煞 1 +x:1 +长长 1 +x:1 +剀切 1 +x:1 +调和 1 +x:1 +指路卡 1 +x:1 +闷雷 1 +x:1 +扩张 1 +x:1 +炉龄 1 +x:1 +畜牧病 1 +x:1 +船王 1 +x:1 +猪瘟 1 +x:1 +月柿 1 +x:1 +心浮气躁 1 +x:1 +禁约 1 +x:1 +多面体 1 +x:1 +等距离 1 +x:1 +鼓掌声 1 +x:1 +新纪元 1 +x:1 +鸳鸯 1 +x:1 +警察署 1 +x:1 +盗鸟 1 +x:1 +何故 1 +x:1 +国界 1 +x:1 +熟知 1 +x:1 +异读 1 +x:1 +槐米 1 +x:1 +扩建 1 +x:1 +北票市 1 +x:1 +三明市 1 +x:1 +催发 1 +x:1 +五讲 1 +x:1 +菊科 1 +x:1 +伫望 1 +x:1 +入场券 1 +x:1 +顾绣 1 +x:1 +长钢 1 +x:1 +圈阅 1 +x:1 +冷遇 1 +x:1 +文学系 1 +x:1 +贬斥 1 +x:1 +半封建 1 +x:1 +史略 1 +x:1 +原样 1 +x:1 +火烧眉毛 1 +x:1 +多孩率 1 +x:1 +中灶 1 +x:1 +世说 1 +x:1 +板床 1 +x:1 +有警必接 1 +x:1 +活化剂 1 +x:1 +比上不足 1 +x:1 +叫菜 1 +x:1 +道理 1 +x:1 +工作会 1 +x:1 +岗地 1 +x:1 +小卜冒 1 +x:1 +退掉 1 +x:1 +白家庄 1 +x:1 +周城 1 +x:1 +居住者 1 +x:1 +买入 1 +x:1 +描 9 +x:9 +月晕 1 +x:1 +三星队 1 +x:1 +箱内 1 +x:1 +街亭失守 1 +x:1 +顶点 1 +x:1 +悠荡 1 +x:1 +保暖房 1 +x:1 +血性 1 +x:1 +归途 1 +x:1 +八公桥 1 +x:1 +办场 1 +x:1 +剧 85 +x:85 +盗卖 1 +x:1 +贩子 1 +x:1 +刺杀 1 +x:1 +缔约 1 +x:1 +冥王星 1 +x:1 +某日 1 +x:1 +初学 1 +x:1 +头发屑 1 +x:1 +叶尔羌河 1 +x:1 +富山市 1 +x:1 +五证 1 +x:1 +帅才 1 +x:1 +的笃班 1 +x:1 +食品盒 1 +x:1 +案子 1 +x:1 +寿宴 1 +x:1 +兰州 1 +x:1 +帖子 1 +x:1 +冲销 1 +x:1 +决心 1 +x:1 +抹灰 1 +x:1 +价值连城 1 +x:1 +虞者 1 +x:1 +增 499 +x:499 +文学类 1 +x:1 +女儿 1 +x:1 +宣传组 1 +x:1 +西夏区 1 +x:1 +隆化县 1 +x:1 +结实率 1 +x:1 +结合 1 +x:1 +初审 1 +x:1 +柔韧性 1 +x:1 +国球 1 +x:1 +贴膏剂 1 +x:1 +墩布 1 +x:1 +卫生日 1 +x:1 +寿宁 1 +x:1 +监守自盗 1 +x:1 +峰会 1 +x:1 +明着说 1 +x:1 +破产方 1 +x:1 +木康 1 +x:1 +央视 1 +x:1 +烧砖人 1 +x:1 +环岛 1 +x:1 +安庆市 1 +x:1 +挑战赛 1 +x:1 +思量 1 +x:1 +冻疮 1 +x:1 +中标 1 +x:1 +维他命 1 +x:1 +刺柏 1 +x:1 +寂无一人 1 +x:1 +大腹便便 1 +x:1 +那曲县 1 +x:1 +女兵 1 +x:1 +木床 1 +x:1 +夺食 1 +x:1 +口感 1 +x:1 +需求方 1 +x:1 +志丹 1 +x:1 +体总 1 +x:1 +祖鲁 1 +x:1 +垢污 1 +x:1 +威拉 1 +x:1 +闪失 1 +x:1 +文不对题 1 +x:1 +斗烟丝 1 +x:1 +长鞭 1 +x:1 +世裔 1 +x:1 +调出量 1 +x:1 +奶瓶 1 +x:1 +咸阳 1 +x:1 +浮屠 1 +x:1 +洪洞县 1 +x:1 +柘林 1 +x:1 +制革厂 1 +x:1 +葡萄酒 1 +x:1 +快车化 1 +x:1 +环形 1 +x:1 +汉源县 1 +x:1 +当选 1 +x:1 +阿里 1 +x:1 +自感应 1 +x:1 +周恩来 1 +x:1 +验明正身 1 +x:1 +另选 1 +x:1 +体态 1 +x:1 +喇叭筒 1 +x:1 +肥源 1 +x:1 +康复者 1 +x:1 +款 273 +x:273 +黑咕隆咚 1 +x:1 +卫生星 1 +x:1 +乘务长 1 +x:1 +施官镇 1 +x:1 +盗印 1 +x:1 +柱石 1 +x:1 +录音 1 +x:1 +商水 1 +x:1 +谈店乡 1 +x:1 +针织厂 1 +x:1 +带粮 1 +x:1 +体恤 1 +x:1 +吧嗒 1 +x:1 +盛况 1 +x:1 +当道 1 +x:1 +长须鲸 1 +x:1 +口技 1 +x:1 +尊称 1 +x:1 +夺魁 1 +x:1 +顿挫疗法 1 +x:1 +积习 1 +x:1 +操作层 1 +x:1 +魅力四射 1 +x:1 +服务性 1 +x:1 +原武 1 +x:1 +新会市 1 +x:1 +摇窗 1 +x:1 +上周日 1 +x:1 +嬉 4 +x:4 +复员兵 1 +x:1 +世行 1 +x:1 +雾里看花 1 +x:1 +洁身自好 1 +x:1 +女刊 1 +x:1 +竖排 1 +x:1 +环志 1 +x:1 +服务行业 1 +x:1 +俭开福源 1 +x:1 +史画 1 +x:1 +费尽心力 1 +x:1 +鲜 67 +x:67 +积云 1 +x:1 +先来后到 1 +x:1 +计量秤 1 +x:1 +体悟 1 +x:1 +口才 1 +x:1 +耗时 1 +x:1 +扶优打劣 1 +x:1 +盛典 1 +x:1 +锭 63 +x:63 +包藏祸心 1 +x:1 +灰黑色 1 +x:1 +吉马良斯 1 +x:1 +隐处 1 +x:1 +阿根廷 1 +x:1 +伞形 1 +x:1 +基建处 1 +x:1 +物资 1 +x:1 +物贸 1 +x:1 +尊神 1 +x:1 +普惠制 1 +x:1 +譬如 1 +x:1 +刀背 1 +x:1 +物质 1 +x:1 +忧愤 1 +x:1 +何来 1 +x:1 +菇农 1 +x:1 +西萨摩亚 1 +x:1 +遵纪爱民 1 +x:1 +俭汤 1 +x:1 +无明火 1 +x:1 +蚕沙 1 +x:1 +卷进 1 +x:1 +浴佛礼 1 +x:1 +兼并潮 1 +x:1 +郁热 1 +x:1 +长青 1 +x:1 +葱绿 1 +x:1 +通产省 1 +x:1 +五行 1 +x:1 +战线 1 +x:1 +警报声 1 +x:1 +规定 1 +x:1 +腔调 1 +x:1 +问询 1 +x:1 +明辨 1 +x:1 +破土动工 1 +x:1 +制止 1 +x:1 +阵型 1 +x:1 +女贞子 1 +x:1 +客观主义 1 +x:1 +西器 1 +x:1 +天义站 1 +x:1 +女厕 1 +x:1 +维修业 1 +x:1 +挑拣 1 +x:1 +南木林 1 +x:1 +革命者 1 +x:1 +界石 1 +x:1 +板岩 1 +x:1 +红沙岩 1 +x:1 +长隧 1 +x:1 +挑拨 1 +x:1 +初夏 1 +x:1 +货柜车 1 +x:1 +考察组 1 +x:1 +社会 1 +x:1 +吸烟者 1 +x:1 +有赖于 1 +x:1 +箱号 1 +x:1 +战罢 1 +x:1 +木屐 1 +x:1 +木屑 1 +x:1 +长随 1 +x:1 +木屋 1 +x:1 +拆解 1 +x:1 +挑担 1 +x:1 +橡皮树 1 +x:1 +社企 1 +x:1 +伴侣 1 +x:1 +何曾 1 +x:1 +务实求真 1 +x:1 +道白 1 +x:1 +朝文系 1 +x:1 +卤虾 1 +x:1 +梅岭山 1 +x:1 +女双 1 +x:1 +广纳善策 1 +x:1 +美国队 1 +x:1 +潜泳 1 +x:1 +口授 1 +x:1 +吧哒 1 +x:1 +凤凰山 1 +x:1 +女史 1 +x:1 +社体 1 +x:1 +急流 1 +x:1 +升空 1 +x:1 +收税人 1 +x:1 +非学历 1 +x:1 +居住舱 1 +x:1 +舌战 1 +x:1 +菜篮 1 +x:1 +百舌鸟 1 +x:1 +珠光宝气 1 +x:1 +善后 1 +x:1 +衔命持节 1 +x:1 +遁逃 1 +x:1 +羊羔 1 +x:1 +交警岗 1 +x:1 +长阳 1 +x:1 +公立 1 +x:1 +脏 83 +x:83 +陈家村 1 +x:1 +檀树 1 +x:1 +亭子 1 +x:1 +物象 1 +x:1 +根深蒂固 1 +x:1 +长队 1 +x:1 +伴伺 1 +x:1 +羊羹 1 +x:1 +公章 1 +x:1 +交叉处 1 +x:1 +卢旺达 1 +x:1 +扩展 1 +x:1 +刺斜 1 +x:1 +凉亭 1 +x:1 +共度 1 +x:1 +羊群 1 +x:1 +郑家庄村 1 +x:1 +凤凰岭 1 +x:1 +顶牛 1 +x:1 +檀栾 1 +x:1 +值勤点 1 +x:1 +弯腰 1 +x:1 +嫩嫩枯枯 1 +x:1 +绷硬 1 +x:1 +南号村 1 +x:1 +菜筐 1 +x:1 +咬文嚼字 1 +x:1 +下大力 1 +x:1 +推销性 1 +x:1 +女单 1 +x:1 +龙潭乡 1 +x:1 +普通级 1 +x:1 +南木村 1 +x:1 +撇下 1 +x:1 +初始 1 +x:1 +忧怨 1 +x:1 +载入 1 +x:1 +抵账 1 +x:1 +社保 1 +x:1 +撷要 1 +x:1 +男家 1 +x:1 +挑战 1 +x:1 +忧思 1 +x:1 +共建 1 +x:1 +零用钱 1 +x:1 +案头 1 +x:1 +手拉手 1 +x:1 +葱翠 1 +x:1 +当量 1 +x:1 +教科文部 1 +x:1 +摇篮 1 +x:1 +副性征 1 +x:1 +园艺 1 +x:1 +废丝 1 +x:1 +梅河口市 1 +x:1 +诗 377 +x:377 +乱世 1 +x:1 +转播台 1 +x:1 +大屿山 1 +x:1 +幽兰 1 +x:1 +亏 78 +x:78 +体温 1 +x:1 +发酵剂 1 +x:1 +黑幽幽 1 +x:1 +男宾 1 +x:1 +溽热 1 +x:1 +公畜 1 +x:1 +具体劳动 1 +x:1 +化为灰烬 1 +x:1 +战火 1 +x:1 +创研部 1 +x:1 +斩 15 +x:15 +营养性 1 +x:1 +开水桶 1 +x:1 +客气话 1 +x:1 +营队 1 +x:1 +扩及 1 +x:1 +下有小 1 +x:1 +晕乎乎 1 +x:1 +受试者 1 +x:1 +外果皮 1 +x:1 +代考者 1 +x:1 +数量级 1 +x:1 +破产案 1 +x:1 +乡下人 1 +x:1 +单冷 1 +x:1 +领袖像 1 +x:1 +指示器 1 +x:1 +带状 1 +x:1 +菜瓜 1 +x:1 +营院 1 +x:1 +欣闻 1 +x:1 +才识 1 +x:1 +灭菌奶 1 +x:1 +相依为命 1 +x:1 +水滴石穿 1 +x:1 +明胶 1 +x:1 +文渊阁 1 +x:1 +训斥 1 +x:1 +合作期 1 +x:1 +遍燃 1 +x:1 +勇者 1 +x:1 +公用 1 +x:1 +千方百计 1 +x:1 +被动型 1 +x:1 +礁长 1 +x:1 +毕分办 1 +x:1 +界碑 1 +x:1 +查准率 1 +x:1 +揽 33 +x:33 +中立性 1 +x:1 +播种期 1 +x:1 +小嗓儿 1 +x:1 +挑战者 1 +x:1 +云水洞 1 +x:1 +国礼 1 +x:1 +肥性 1 +x:1 +木叶 1 +x:1 +杂木片 1 +x:1 +歌曲奖 1 +x:1 +原文 1 +x:1 +女将 1 +x:1 +狸子 1 +x:1 +天后楼 1 +x:1 +音乐人 1 +x:1 +女尸 1 +x:1 +废人 1 +x:1 +播种机 1 +x:1 +凤凰县 1 +x:1 +檀木 1 +x:1 +另一方面 1 +x:1 +伞兵 1 +x:1 +安全部 1 +x:1 +一试身手 1 +x:1 +经纱 1 +x:1 +英山 1 +x:1 +经协办 1 +x:1 +滚瓜溜圆 1 +x:1 +动魄惊心 1 +x:1 +小卜少 1 +x:1 +拖儿带女 1 +x:1 +乱仗 1 +x:1 +初四 1 +x:1 +忻口 1 +x:1 +郁结 1 +x:1 +洗车点 1 +x:1 +剃须刀 1 +x:1 +银婚 1 +x:1 +拉油点 1 +x:1 +出世 1 +x:1 +内需 1 +x:1 +口水 1 +x:1 +奈良市 1 +x:1 +调控室 1 +x:1 +无烟 1 +x:1 +徐家桥 1 +x:1 +陡增 1 +x:1 +阿瓦拉山 1 +x:1 +口气 1 +x:1 +音乐会 1 +x:1 +智勇 1 +x:1 +公明党 1 +x:1 +通州区 1 +x:1 +姜农 1 +x:1 +熟稔 1 +x:1 +梦寐以求 1 +x:1 +中医院 1 +x:1 +特困 1 +x:1 +忽微 1 +x:1 +困难重重 1 +x:1 +带班 1 +x:1 +堪培拉 1 +x:1 +行情 1 +x:1 +颠三倒四 1 +x:1 +狐狸精 1 +x:1 +马王堆 1 +x:1 +木剑 1 +x:1 +渺 2 +x:2 +俄亥俄 1 +x:1 +办学 1 +x:1 +宝盖儿 1 +x:1 +公理 1 +x:1 +同乡籍 1 +x:1 +肺部 1 +x:1 +与时俯仰 1 +x:1 +不知所云 1 +x:1 +忽忽 1 +x:1 +蒙尔赞镇 1 +x:1 +木制 1 +x:1 +调处 1 +x:1 +策略性 1 +x:1 +式 123 +x:123 +肘窝 1 +x:1 +神学 1 +x:1 +超声室 1 +x:1 +考试员 1 +x:1 +观测点 1 +x:1 +域 3 +x:3 +建筑队 1 +x:1 +备付率 1 +x:1 +湾沟 1 +x:1 +沿条儿 1 +x:1 +青少年宫 1 +x:1 +核子力 1 +x:1 +长风 1 +x:1 +邹平县 1 +x:1 +北京城 1 +x:1 +干劲冲天 1 +x:1 +互联网站 1 +x:1 +九宫 1 +x:1 +调头 1 +x:1 +积极性 1 +x:1 +伽师县 1 +x:1 +帅 164 +x:164 +牲畜 1 +x:1 +细读 1 +x:1 +物色 1 +x:1 +食品站 1 +x:1 +走势 1 +x:1 +菱角 1 +x:1 +非专职 1 +x:1 +竞技 1 +x:1 +登机闸 1 +x:1 +柘树 1 +x:1 +保送生 1 +x:1 +起爆 1 +x:1 +神经原 1 +x:1 +菜田 1 +x:1 +盛年 1 +x:1 +宛 5 +x:5 +后继无人 1 +x:1 +沙里淘金 1 +x:1 +救生 1 +x:1 +乘机人 1 +x:1 +社木铺村 1 +x:1 +威海 1 +x:1 +药铺 1 +x:1 +决口 1 +x:1 +隔开 1 +x:1 +操作台 1 +x:1 +长须 1 +x:1 +挑水 1 +x:1 +长项 1 +x:1 +高等学校 1 +x:1 +敢死队 1 +x:1 +多足类 1 +x:1 +发酵厂 1 +x:1 +竞拍 1 +x:1 +羽毛丰满 1 +x:1 +独木舟 1 +x:1 +采行 1 +x:1 +得人者 1 +x:1 +茶馆 1 +x:1 +实足 1 +x:1 +永暑礁 1 +x:1 +毛竹林 1 +x:1 +初基 1 +x:1 +菜畦 1 +x:1 +扩刊 1 +x:1 +中牟县 1 +x:1 +何案 1 +x:1 +试 154 +x:154 +兴林 1 +x:1 +物竞天择 1 +x:1 +凝固点 1 +x:1 +坞墙 1 +x:1 +略论稿 1 +x:1 +小娘子 1 +x:1 +急急 1 +x:1 +法律化 1 +x:1 +木兰 1 +x:1 +叠韵 1 +x:1 +铁汉子 1 +x:1 +镇平县 1 +x:1 +暴力片 1 +x:1 +兽性 1 +x:1 +痹论 1 +x:1 +原有 1 +x:1 +媲美 1 +x:1 +拯救 1 +x:1 +环卫 1 +x:1 +感人 1 +x:1 +一分为四 1 +x:1 +采访 1 +x:1 +衬衫 1 +x:1 +邪门歪道 1 +x:1 +坞墩 1 +x:1 +偷天换日 1 +x:1 +纯小数 1 +x:1 +原木 1 +x:1 +致以 1 +x:1 +园边 1 +x:1 +孔雀 1 +x:1 +摇篮曲 1 +x:1 +毕业班 1 +x:1 +结对 1 +x:1 +刀豆 1 +x:1 +善始 1 +x:1 +吃瓜人 1 +x:1 +陈 3235 +x:3235 +回溯 1 +x:1 +板凳 1 +x:1 +有惠 1 +x:1 +低 1404 +x:1404 +苦肉计 1 +x:1 +报告文学 1 +x:1 +蕃茄 1 +x:1 +深重 1 +x:1 +治国篇 1 +x:1 +毒蛇 1 +x:1 +扩军 1 +x:1 +国际制 1 +x:1 +玛达咪 1 +x:1 +孔隙 1 +x:1 +超低温 1 +x:1 +始终 1 +x:1 +红药水 1 +x:1 +感仰 1 +x:1 +抛头露面 1 +x:1 +回笼率 1 +x:1 +深海 1 +x:1 +监测点 1 +x:1 +原来 1 +x:1 +刺桐 1 +x:1 +安乐窝 1 +x:1 +名古屋 1 +x:1 +电炉厂 1 +x:1 +服务法 1 +x:1 +遭殃 1 +x:1 +木凳 1 +x:1 +知更鸟 1 +x:1 +模式化 1 +x:1 +女师 1 +x:1 +牢稳 1 +x:1 +檐 4 +x:4 +白垅村 1 +x:1 +养父母 1 +x:1 +抱有 1 +x:1 +芝川镇 1 +x:1 +禁烟 1 +x:1 +衬裙 1 +x:1 +衬裤 1 +x:1 +油板栗 1 +x:1 +小推车 1 +x:1 +扎根树 1 +x:1 +吃苦 1 +x:1 +黟山 1 +x:1 +高古曼妙 1 +x:1 +十年寒窗 1 +x:1 +黔驴技穷 1 +x:1 +扩充 1 +x:1 +鹅毛大雪 1 +x:1 +晓以利害 1 +x:1 +渗灌 1 +x:1 +中煤 1 +x:1 +刚好 1 +x:1 +避难者 1 +x:1 +印共 1 +x:1 +案后 1 +x:1 +欧风 1 +x:1 +氯化 1 +x:1 +明艳 1 +x:1 +伞包 1 +x:1 +何止 1 +x:1 +芽球 1 +x:1 +国策 1 +x:1 +战犯 1 +x:1 +结子 1 +x:1 +共商国是 1 +x:1 +华领 1 +x:1 +滑行 1 +x:1 +平顶山市 1 +x:1 +盲肠 1 +x:1 +爱康 1 +x:1 +柔柔的 1 +x:1 +譬喻 1 +x:1 +初唐 1 +x:1 +任期 1 +x:1 +木偶 1 +x:1 +蒋介石 1 +x:1 +登封市 1 +x:1 +深邃 1 +x:1 +笔札 1 +x:1 +大口井 1 +x:1 +长骨 1 +x:1 +磙子 1 +x:1 +调子 1 +x:1 +起点 1 +x:1 +对象国 1 +x:1 +蠢 6 +x:6 +吃药 1 +x:1 +刀枪街 1 +x:1 +预选 1 +x:1 +营销 1 +x:1 +菊石 1 +x:1 +报春 1 +x:1 +仁至义尽 1 +x:1 +六甲 1 +x:1 +老中青年 1 +x:1 +信息司 1 +x:1 +油瓜 1 +x:1 +国际化 1 +x:1 +禅师 1 +x:1 +贪欲熏心 1 +x:1 +顶级 1 +x:1 +民政部门 1 +x:1 +过剩论 1 +x:1 +营长 1 +x:1 +办复 1 +x:1 +归真返璞 1 +x:1 +六畜 1 +x:1 +海防林 1 +x:1 +打竹舞 1 +x:1 +加里卜角 1 +x:1 +糜棱 1 +x:1 +该村 1 +x:1 +出事 1 +x:1 +紫荆山 1 +x:1 +恩将仇报 1 +x:1 +锡山市 1 +x:1 +笔杆 1 +x:1 +深部 1 +x:1 +翰墨 1 +x:1 +饮料罐 1 +x:1 +国立 1 +x:1 +神经元 1 +x:1 +瓦灰 1 +x:1 +倭寇 1 +x:1 +往访国 1 +x:1 +善本书 1 +x:1 +笔架 1 +x:1 +体液 1 +x:1 +反射度 1 +x:1 +包干制 1 +x:1 +调寄 1 +x:1 +拇指 1 +x:1 +丙肝 1 +x:1 +塑性 1 +x:1 +化验台 1 +x:1 +牢笼 1 +x:1 +隐含 1 +x:1 +踟蹰 1 +x:1 +兼并战 1 +x:1 +生 559 +x:559 +敬民如父 1 +x:1 +奔波如梭 1 +x:1 +典藏 1 +x:1 +基特加 1 +x:1 +电气焊 1 +x:1 +深造 1 +x:1 +紧绷绷 1 +x:1 +净菜社 1 +x:1 +选举署 1 +x:1 +少年队 1 +x:1 +防伪服 1 +x:1 +感伤 1 +x:1 +封斋 1 +x:1 +冒号 1 +x:1 +妙香山 1 +x:1 +缠身 1 +x:1 +玛纳斯 1 +x:1 +起火 1 +x:1 +冬季两项 1 +x:1 +扑 119 +x:119 +布雷器 1 +x:1 +法兰西堡 1 +x:1 +辐照 1 +x:1 +共勉 1 +x:1 +帅气 1 +x:1 +漏报率 1 +x:1 +针织布 1 +x:1 +箱式 1 +x:1 +刀距 1 +x:1 +结婚 1 +x:1 +差一点 1 +x:1 +除此以外 1 +x:1 +三军医大 1 +x:1 +并轨生 1 +x:1 +新沙乡镇 1 +x:1 +物耗 1 +x:1 +翅翼 1 +x:1 +感佩 1 +x:1 +破折号 1 +x:1 +置放 1 +x:1 +刺槐 1 +x:1 +臼 1 +x:1 +粮棉型 1 +x:1 +沟通 1 +x:1 +卤质 1 +x:1 +冷饮 1 +x:1 +惴惴 1 +x:1 +善待 1 +x:1 +渌 1 +x:1 +初创 1 +x:1 +原意 1 +x:1 +槟城 1 +x:1 +东亚系 1 +x:1 +善徙 1 +x:1 +家庭副业 1 +x:1 +暮云 1 +x:1 +亮眼人 1 +x:1 +扯皮电 1 +x:1 +眼科界 1 +x:1 +龌龊 1 +x:1 +木块 1 +x:1 +初刻 1 +x:1 +亢奋 1 +x:1 +禁脔 1 +x:1 +邳 2 +x:2 +筛糠 1 +x:1 +冒名 1 +x:1 +降价风 1 +x:1 +兼收 1 +x:1 +当仁不让 1 +x:1 +商 142 +x:142 +弹冠相庆 1 +x:1 +宗教局 1 +x:1 +掌班 1 +x:1 +善心 1 +x:1 +结巴 1 +x:1 +白开水 1 +x:1 +咸鱼 1 +x:1 +共商 1 +x:1 +棉桃 1 +x:1 +衔接 1 +x:1 +兰后 1 +x:1 +牢系 1 +x:1 +明辨是非 1 +x:1 +相扑 1 +x:1 +盛宴 1 +x:1 +女声 1 +x:1 +太学 1 +x:1 +公然 1 +x:1 +罗马数字 1 +x:1 +氯喹 1 +x:1 +冷餐 1 +x:1 +粗心大意 1 +x:1 +费改税 1 +x:1 +玩具业 1 +x:1 +布鲁塞尔 1 +x:1 +退耕还田 1 +x:1 +瞻仰 1 +x:1 +钻营 1 +x:1 +谋 145 +x:145 +致贫 1 +x:1 +卫生法 1 +x:1 +隐匿 1 +x:1 +印儿 1 +x:1 +文学界 1 +x:1 +案前 1 +x:1 +核潜艇 1 +x:1 +塑木 1 +x:1 +起眼 1 +x:1 +船篷 1 +x:1 +智利 1 +x:1 +潜江市 1 +x:1 +存放场 1 +x:1 +中油 1 +x:1 +君临 1 +x:1 +君主 1 +x:1 +打紧 1 +x:1 +用棉量 1 +x:1 +簪子 1 +x:1 +宿舍 1 +x:1 +养精蓄锐 1 +x:1 +刺溜 1 +x:1 +潜望镜 1 +x:1 +毕业生 1 +x:1 +采购 1 +x:1 +调峰 1 +x:1 +潮乎乎 1 +x:1 +王屋山 1 +x:1 +歌剧院 1 +x:1 +富贵竹 1 +x:1 +净菜业 1 +x:1 +救灾 1 +x:1 +板坯 1 +x:1 +大潮山 1 +x:1 +求知若渴 1 +x:1 +徐家汇 1 +x:1 +行政 1 +x:1 +救火 1 +x:1 +栓塞 1 +x:1 +忠魂 1 +x:1 +板块 1 +x:1 +畲族乡 1 +x:1 +瀑布 1 +x:1 +关公路 1 +x:1 +祖陵 1 +x:1 +一二月份 1 +x:1 +承 12 +x:12 +顾盼 1 +x:1 +小龙潭村 1 +x:1 +滚烫烫 1 +x:1 +乘车证 1 +x:1 +起皮 1 +x:1 +忠骨 1 +x:1 +案发 1 +x:1 +国粹 1 +x:1 +归顺 1 +x:1 +作画 1 +x:1 +木器 1 +x:1 +高炮团 1 +x:1 +共同 1 +x:1 +昏乱 1 +x:1 +基建办 1 +x:1 +宝贝儿 1 +x:1 +挑棒 1 +x:1 +消费者 1 +x:1 +绝大部分 1 +x:1 +航 22 +x:22 +战略 1 +x:1 +笔意 1 +x:1 +肥料 1 +x:1 +扯后腿 1 +x:1 +加工类 1 +x:1 +竞春 1 +x:1 +利令智昏 1 +x:1 +肝胆相照 1 +x:1 +印相纸 1 +x:1 +门票费 1 +x:1 +德雷西塔 1 +x:1 +阿布扎比 1 +x:1 +每 2015 +x:2015 +交叉口 1 +x:1 +初十 1 +x:1 +东孝乡 1 +x:1 +批准书 1 +x:1 +不着边际 1 +x:1 +斯科普里 1 +x:1 +烟熏火燎 1 +x:1 +典范 1 +x:1 +歌功颂德 1 +x:1 +贩卖 1 +x:1 +押汇 1 +x:1 +作用 1 +x:1 +统制 1 +x:1 +勇闯 1 +x:1 +互联网络 1 +x:1 +糠菜 1 +x:1 +瑶学会 1 +x:1 +寿县 1 +x:1 +悍然不顾 1 +x:1 +公开牌 1 +x:1 +结尾 1 +x:1 +震 110 +x:110 +九归 1 +x:1 +奶罩 1 +x:1 +培育者 1 +x:1 +腻烦 1 +x:1 +用布 1 +x:1 +白皮蒜 1 +x:1 +中流 1 +x:1 +一分为八 1 +x:1 +蒲公英 1 +x:1 +共和 1 +x:1 +挪作 1 +x:1 +因变量 1 +x:1 +要不是 1 +x:1 +黄粱梦村 1 +x:1 +焦头烂额 1 +x:1 +案卷 1 +x:1 +俭朴 1 +x:1 +金属制 1 +x:1 +刮目相看 1 +x:1 +囚徒 1 +x:1 +外科学术 1 +x:1 +冷食 1 +x:1 +阴乎乎 1 +x:1 +女大 1 +x:1 +隽永 1 +x:1 +小买卖 1 +x:1 +羊痘 1 +x:1 +寿司 1 +x:1 +雨露 1 +x:1 +舞美师 1 +x:1 +容光焕发 1 +x:1 +欣 42 +x:42 +仇湖镇 1 +x:1 +低三下四 1 +x:1 +方位 1 +x:1 +镛 2 +x:2 +柔声细语 1 +x:1 +熟练 1 +x:1 +图画文字 1 +x:1 +体毛 1 +x:1 +畜牧系 1 +x:1 +初叶 1 +x:1 +肥效 1 +x:1 +深陷 1 +x:1 +热水型 1 +x:1 +同化政策 1 +x:1 +休伦湖 1 +x:1 +刺激 1 +x:1 +泰兴市 1 +x:1 +温州市 1 +x:1 +颗粒物 1 +x:1 +食品级 1 +x:1 +悬腕 1 +x:1 +始祖 1 +x:1 +国籍 1 +x:1 +结局 1 +x:1 +船票 1 +x:1 +滚瓜烂熟 1 +x:1 +反潜机 1 +x:1 +窘促 1 +x:1 +营造 1 +x:1 +调幅 1 +x:1 +平方米 1 +x:1 +寓情于物 1 +x:1 +怔 6 +x:6 +顶篷 1 +x:1 +一线生机 1 +x:1 +体校 1 +x:1 +丁苯橡胶 1 +x:1 +扯皮 1 +x:1 +竞放 1 +x:1 +该柜 1 +x:1 +绵羊绒衫 1 +x:1 +初值 1 +x:1 +实报实销 1 +x:1 +豫州 1 +x:1 +宗教性 1 +x:1 +平展展 1 +x:1 +奶糖 1 +x:1 +调干 1 +x:1 +削球 1 +x:1 +绪言 1 +x:1 +阿齐兹 1 +x:1 +哥本哈根 1 +x:1 +彼岸性 1 +x:1 +前些时 1 +x:1 +相握 1 +x:1 +锈损 1 +x:1 +璧山 1 +x:1 +执行期 1 +x:1 +滋 2 +x:2 +去秋 1 +x:1 +猪粪 1 +x:1 +电费 1 +x:1 +安全阀 1 +x:1 +裱糊 1 +x:1 +敌人 1 +x:1 +非耕地 1 +x:1 +达马托法 1 +x:1 +起病 1 +x:1 +游离 1 +x:1 +嚓嚓 1 +x:1 +奶粉 1 +x:1 +操作员 1 +x:1 +深闺 1 +x:1 +葱白 1 +x:1 +指定权 1 +x:1 +外星人 1 +x:1 +澳航 1 +x:1 +知识界 1 +x:1 +笔手 1 +x:1 +建业 1 +x:1 +锻压 1 +x:1 +月浦 1 +x:1 +贩假 1 +x:1 +隔壁 1 +x:1 +环城 1 +x:1 +居住证 1 +x:1 +番 221 +x:221 +亭前 1 +x:1 +二酉斋 1 +x:1 +坚信不疑 1 +x:1 +女娃 1 +x:1 +行板 1 +x:1 +奶类 1 +x:1 +九屋 1 +x:1 +九届 1 +x:1 +冻结 1 +x:1 +报架 1 +x:1 +审阅 1 +x:1 +行李 1 +x:1 +女娲 1 +x:1 +缠诉 1 +x:1 +长鼓 1 +x:1 +食品城 1 +x:1 +附属国 1 +x:1 +羊皮 1 +x:1 +安葬法 1 +x:1 +住读生 1 +x:1 +禅寺 1 +x:1 +不孝之子 1 +x:1 +六点 1 +x:1 +撼 11 +x:11 +笔技 1 +x:1 +格林尼治 1 +x:1 +薄暮 1 +x:1 +磷 22 +x:22 +建交 1 +x:1 +对象化 1 +x:1 +菜牛 1 +x:1 +来安乡 1 +x:1 +湘泉酒 1 +x:1 +明虾 1 +x:1 +救物 1 +x:1 +禅宗 1 +x:1 +盛夏 1 +x:1 +建于 1 +x:1 +女婿 1 +x:1 +案值 1 +x:1 +五联 1 +x:1 +调度 1 +x:1 +冷藏库 1 +x:1 +女婴 1 +x:1 +审限 1 +x:1 +迷途知返 1 +x:1 +珊瑚鱼 1 +x:1 +盛大 1 +x:1 +挨打 1 +x:1 +行期 1 +x:1 +冬春汛 1 +x:1 +癖好 1 +x:1 +未雨绸缪 1 +x:1 +缀 14 +x:14 +笔挺 1 +x:1 +提克里特 1 +x:1 +九州 1 +x:1 +顶端 1 +x:1 +毒理学家 1 +x:1 +修鞋店 1 +x:1 +修辞学 1 +x:1 +录放像机 1 +x:1 +强震群 1 +x:1 +公牛 1 +x:1 +跑上跑下 1 +x:1 +敲锭 1 +x:1 +食品类 1 +x:1 +国无宁日 1 +x:1 +公物 1 +x:1 +秀色 1 +x:1 +桑干河 1 +x:1 +亭台 1 +x:1 +燕塞湖 1 +x:1 +兰坪 1 +x:1 +真峰村 1 +x:1 +背负式 1 +x:1 +洒水机 1 +x:1 +文学家 1 +x:1 +调式 1 +x:1 +院舍 1 +x:1 +熄灭 1 +x:1 +五自 1 +x:1 +绣花 1 +x:1 +北影厂 1 +x:1 +特命 1 +x:1 +初具 1 +x:1 +蔡坂 1 +x:1 +抗美援朝 1 +x:1 +禁用 1 +x:1 +国际场 1 +x:1 +脏土 1 +x:1 +不足称道 1 +x:1 +寿光 1 +x:1 +初六 1 +x:1 +模式图 1 +x:1 +美目盼兮 1 +x:1 +急救 1 +x:1 +初八 1 +x:1 +公爹 1 +x:1 +埃雷兹 1 +x:1 +箱子 1 +x:1 +珞珈山 1 +x:1 +绪论 1 +x:1 +培养基 1 +x:1 +扬水站 1 +x:1 +牙周带 1 +x:1 +钻井机 1 +x:1 +瓯海区 1 +x:1 +庖 1 +x:1 +就事论事 1 +x:1 +长鸣 1 +x:1 +隔夜 1 +x:1 +威武 1 +x:1 +军屯村 1 +x:1 +阳浦 1 +x:1 +乌苏里虎 1 +x:1 +夯 5 +x:5 +五脏 1 +x:1 +尾砂尘 1 +x:1 +西宁市 1 +x:1 +初冬 1 +x:1 +环围 1 +x:1 +带田 1 +x:1 +配电间 1 +x:1 +吃派饭 1 +x:1 +带电 1 +x:1 +高等院校 1 +x:1 +果海 1 +x:1 +投入者 1 +x:1 +又 8529 +x:8529 +女子 1 +x:1 +敌伪 1 +x:1 +心明眼亮 1 +x:1 +核聚变能 1 +x:1 +五四式 1 +x:1 +忠顺 1 +x:1 +组阁 1 +x:1 +国际型 1 +x:1 +乡 757 +x:757 +营里 1 +x:1 +道统 1 +x:1 +圆顶 1 +x:1 +融水 1 +x:1 +房地产热 1 +x:1 +圆顺 1 +x:1 +结幕 1 +x:1 +女孩 1 +x:1 +道经 1 +x:1 +棉毯 1 +x:1 +鸷鸟 1 +x:1 +行星 1 +x:1 +有变 1 +x:1 +新锐 1 +x:1 +火烈鸟 1 +x:1 +假借 1 +x:1 +无妨 1 +x:1 +还要 1 +x:1 +天高云淡 1 +x:1 +书写体 1 +x:1 +精装本 1 +x:1 +铁法市 1 +x:1 +载力 1 +x:1 +制茶 1 +x:1 +探幽 1 +x:1 +新干线 1 +x:1 +忍俊不禁 1 +x:1 +难免论 1 +x:1 +浊流 1 +x:1 +缔造 1 +x:1 +金带扣 1 +x:1 +稳固 1 +x:1 +三建 1 +x:1 +励志 1 +x:1 +特有种 1 +x:1 +河山村 1 +x:1 +度汛 1 +x:1 +电路 1 +x:1 +淳朴 1 +x:1 +过密型 1 +x:1 +笋子 1 +x:1 +训练组 1 +x:1 +单薄 1 +x:1 +救济式 1 +x:1 +过境国 1 +x:1 +美编 1 +x:1 +串联 1 +x:1 +雪中送炭 1 +x:1 +鄙陋 1 +x:1 +三废 1 +x:1 +博士后 1 +x:1 +浅吟低唱 1 +x:1 +取而代之 1 +x:1 +积温区 1 +x:1 +后生可畏 1 +x:1 +送风机 1 +x:1 +订阅 1 +x:1 +细水长流 1 +x:1 +卢 423 +x:423 +董事局 1 +x:1 +承包商 1 +x:1 +统一论 1 +x:1 +西藏 1 +x:1 +逆境 1 +x:1 +绞转 1 +x:1 +无委 1 +x:1 +效益观 1 +x:1 +阵营 1 +x:1 +消化道 1 +x:1 +税法 1 +x:1 +绞车 1 +x:1 +磨砺 1 +x:1 +兴利 1 +x:1 +晚清 1 +x:1 +流失生 1 +x:1 +入睡 1 +x:1 +涅槃 1 +x:1 +老虎 1 +x:1 +围住 1 +x:1 +武邑县 1 +x:1 +无头 1 +x:1 +鸭绒 1 +x:1 +耐人寻味 1 +x:1 +雄鸡 1 +x:1 +程序法 1 +x:1 +偷窃者 1 +x:1 +得计 1 +x:1 +盐业 1 +x:1 +储罐 1 +x:1 +丹参 1 +x:1 +信息窗 1 +x:1 +侗家 1 +x:1 +预备金 1 +x:1 +瓜果皮 1 +x:1 +冶 7 +x:7 +规范化 1 +x:1 +雪帽山 1 +x:1 +户口本 1 +x:1 +欺瞒 1 +x:1 +花子儿 1 +x:1 +得识 1 +x:1 +惹火 1 +x:1 +聚苯乙烯 1 +x:1 +盐阜 1 +x:1 +阿联酋 1 +x:1 +入眠 1 +x:1 +维持会 1 +x:1 +作痛 1 +x:1 +豁子 1 +x:1 +食用量 1 +x:1 +德国队 1 +x:1 +收回成命 1 +x:1 +邮递 1 +x:1 +陡然 1 +x:1 +中常会 1 +x:1 +胞衣 1 +x:1 +枯涩 1 +x:1 +新闻 1 +x:1 +无奈 1 +x:1 +坐南朝北 1 +x:1 +停建 1 +x:1 +海洋学 1 +x:1 +营销学 1 +x:1 +天竺葵 1 +x:1 +养兔业 1 +x:1 +看管人 1 +x:1 +粮贩子 1 +x:1 +黎塘 1 +x:1 +三带 1 +x:1 +听而不闻 1 +x:1 +拳会 1 +x:1 +试点区 1 +x:1 +假嗓子 1 +x:1 +苗族 1 +x:1 +刘桥 1 +x:1 +命根 1 +x:1 +三志 1 +x:1 +餐 45 +x:45 +豫皖 1 +x:1 +芯块 1 +x:1 +劳动强度 1 +x:1 +众鹊登枝 1 +x:1 +坎坷 1 +x:1 +暴举 1 +x:1 +治疗仪 1 +x:1 +鸽子 1 +x:1 +卢克索 1 +x:1 +萋萋芳华 1 +x:1 +五边形 1 +x:1 +承办者 1 +x:1 +古脊椎所 1 +x:1 +入盟 1 +x:1 +大沙河 1 +x:1 +时令性 1 +x:1 +钟锤 1 +x:1 +访求 1 +x:1 +有力 1 +x:1 +触手 1 +x:1 +停当 1 +x:1 +有功 1 +x:1 +占据 1 +x:1 +进口价 1 +x:1 +上固乡 1 +x:1 +铝业 1 +x:1 +去年初 1 +x:1 +假充 1 +x:1 +异姓 1 +x:1 +毁家纾难 1 +x:1 +英雄气短 1 +x:1 +枣树 1 +x:1 +消化酶 1 +x:1 +通信连 1 +x:1 +腰杆子 1 +x:1 +浊水 1 +x:1 +有劳 1 +x:1 +有劲 1 +x:1 +图书区 1 +x:1 +三德 1 +x:1 +旱秧田 1 +x:1 +有助 1 +x:1 +倒装 1 +x:1 +诸葛亮 1 +x:1 +精减 1 +x:1 +有加 1 +x:1 +枯水 1 +x:1 +命案 1 +x:1 +柬方 1 +x:1 +腐干 1 +x:1 +蕴涵 1 +x:1 +海关厅 1 +x:1 +假冒 1 +x:1 +忐忑不安 1 +x:1 +涅而不缁 1 +x:1 +三春柳 1 +x:1 +窥伺 1 +x:1 +新钞 1 +x:1 +奶白菜 1 +x:1 +学派 1 +x:1 +异物 1 +x:1 +工业处 1 +x:1 +夫贵妻荣 1 +x:1 +淄川 1 +x:1 +贿赂罪 1 +x:1 +信息箱 1 +x:1 +恋人 1 +x:1 +技术作物 1 +x:1 +山青水秀 1 +x:1 +组雕 1 +x:1 +无所不知 1 +x:1 +热中 1 +x:1 +三彩 1 +x:1 +但凡 1 +x:1 +热带雨林 1 +x:1 +年迈体弱 1 +x:1 +精典 1 +x:1 +继电 1 +x:1 +学海 1 +x:1 +岩鹰 1 +x:1 +热乎 1 +x:1 +伤残人 1 +x:1 +精兵 1 +x:1 +怨艾 1 +x:1 +精美 1 +x:1 +检讨书 1 +x:1 +东大寺 1 +x:1 +鸭群 1 +x:1 +三强 1 +x:1 +西葛 1 +x:1 +检讨 1 +x:1 +垫支性 1 +x:1 +有利 1 +x:1 +精光 1 +x:1 +有别 1 +x:1 +孤掌难鸣 1 +x:1 +古诗词 1 +x:1 +高活性 1 +x:1 +三弦 1 +x:1 +茶斋 1 +x:1 +胞弟 1 +x:1 +发钞行 1 +x:1 +老实巴交 1 +x:1 +本溪市 1 +x:1 +语文 1 +x:1 +无害 1 +x:1 +统一观 1 +x:1 +承包地 1 +x:1 +线袜子 1 +x:1 +无宁 1 +x:1 +壳舾 1 +x:1 +磨窝 1 +x:1 +谢词 1 +x:1 +支团 1 +x:1 +欺生 1 +x:1 +一样 1 +x:1 +照妖镜 1 +x:1 +三峡 1 +x:1 +农业法 1 +x:1 +所 5816 +x:5816 +原始公社 1 +x:1 +万流景仰 1 +x:1 +甜竹笋 1 +x:1 +年后 1 +x:1 +西洋参 1 +x:1 +良好率 1 +x:1 +花消 1 +x:1 +华埠镇 1 +x:1 +无声手枪 1 +x:1 +一档 1 +x:1 +衰弱 1 +x:1 +深亚微米 1 +x:1 +床边柜 1 +x:1 +锌版 1 +x:1 +润滑油 1 +x:1 +孤军作战 1 +x:1 +千米 1 +x:1 +条次 1 +x:1 +军史部 1 +x:1 +寸口 1 +x:1 +计划法 1 +x:1 +精到 1 +x:1 +越 1025 +x:1025 +春风骀荡 1 +x:1 +试管婴儿 1 +x:1 +精制 1 +x:1 +预配 1 +x:1 +扮作 1 +x:1 +补救性 1 +x:1 +生产部 1 +x:1 +疟疾 1 +x:1 +花海 1 +x:1 +谭家乡 1 +x:1 +有关 1 +x:1 +生活品 1 +x:1 +假劣 1 +x:1 +部室 1 +x:1 +挪威海 1 +x:1 +独门儿 1 +x:1 +庆龄码头 1 +x:1 +远航 1 +x:1 +次地区 1 +x:1 +马蜂窝 1 +x:1 +一棉 1 +x:1 +木偶剧 1 +x:1 +铜仁路 1 +x:1 +子弦 1 +x:1 +三小 1 +x:1 +招贴画 1 +x:1 +银本位 1 +x:1 +集团案 1 +x:1 +侧门 1 +x:1 +老营 1 +x:1 +新韵 1 +x:1 +弱点 1 +x:1 +子弟 1 +x:1 +油页岩 1 +x:1 +众院 1 +x:1 +征纳 1 +x:1 +菱形 1 +x:1 +宁静致远 1 +x:1 +无存 1 +x:1 +衰微 1 +x:1 +穿山龙 1 +x:1 +环保界 1 +x:1 +中小学生 1 +x:1 +臆测 1 +x:1 +作怪 1 +x:1 +检测仪 1 +x:1 +人高马大 1 +x:1 +红啤酒 1 +x:1 +养兵千日 1 +x:1 +筑巢引凤 1 +x:1 +逞凶 1 +x:1 +魅力 1 +x:1 +堤顶 1 +x:1 +初生态 1 +x:1 +跳水 1 +x:1 +拐杖 1 +x:1 +衰年 1 +x:1 +天之骄子 1 +x:1 +受赠者 1 +x:1 +景群 1 +x:1 +经济团 1 +x:1 +接待组 1 +x:1 +致癌 1 +x:1 +虾仁 1 +x:1 +三轮车 1 +x:1 +民间语 1 +x:1 +蒸化 1 +x:1 +进步党 1 +x:1 +信报箱群 1 +x:1 +丰产村 1 +x:1 +煌 13 +x:13 +风火墙 1 +x:1 +喇叭声 1 +x:1 +冷言冷语 1 +x:1 +美籍 1 +x:1 +解释权 1 +x:1 +辛酸 1 +x:1 +定植 1 +x:1 +征缴 1 +x:1 +构件 1 +x:1 +吴茱萸 1 +x:1 +钟面 1 +x:1 +一概 1 +x:1 +相持 1 +x:1 +检视 1 +x:1 +褴褛 1 +x:1 +笋壳 1 +x:1 +3 3213 +x:3213 +实地调查 1 +x:1 +水鼠皮 1 +x:1 +河源市 1 +x:1 +指示信 1 +x:1 +一榜 1 +x:1 +鸭舌帽 1 +x:1 +测量部 1 +x:1 +美术部 1 +x:1 +苗条 1 +x:1 +耳听为虚 1 +x:1 +精化 1 +x:1 +轨枕 1 +x:1 +记 470 +x:470 +辩称 1 +x:1 +会馆 1 +x:1 +纱灯 1 +x:1 +投资率 1 +x:1 +虾丸 1 +x:1 +抗热合金 1 +x:1 +假发 1 +x:1 +壳菜 1 +x:1 +精印 1 +x:1 +越剧院 1 +x:1 +游艺机 1 +x:1 +大沙湖 1 +x:1 +新集 1 +x:1 +西南部 1 +x:1 +白三烯 1 +x:1 +苗期 1 +x:1 +马驹子 1 +x:1 +嘱事 1 +x:1 +协兴镇 1 +x:1 +湖北村 1 +x:1 +常用对数 1 +x:1 +行不通 1 +x:1 +凄惨 1 +x:1 +浩浩汤汤 1 +x:1 +芳纶 1 +x:1 +入球 1 +x:1 +苗木 1 +x:1 +停工 1 +x:1 +精华 1 +x:1 +西南郊 1 +x:1 +阴囊 1 +x:1 +纺织厂 1 +x:1 +蒸发 1 +x:1 +制胜 1 +x:1 +灾荒 1 +x:1 +张庄村 1 +x:1 +名团 1 +x:1 +四面楚歌 1 +x:1 +苗情 1 +x:1 +免职 1 +x:1 +绘图仪 1 +x:1 +解释性 1 +x:1 +赌注 1 +x:1 +标志物 1 +x:1 +年前 1 +x:1 +要端 1 +x:1 +得奖 1 +x:1 +竹板书 1 +x:1 +假名 1 +x:1 +水资源 1 +x:1 +黄村 1 +x:1 +同道者 1 +x:1 +黄杨 1 +x:1 +竹帘 1 +x:1 +竹帛 1 +x:1 +黄杠 1 +x:1 +液肥 1 +x:1 +人武部 1 +x:1 +大方向 1 +x:1 +寒来暑往 1 +x:1 +吹腔 1 +x:1 +盯住 1 +x:1 +年初 1 +x:1 +受精卵 1 +x:1 +匆忙 1 +x:1 +无已 1 +x:1 +凄惶 1 +x:1 +年刊 1 +x:1 +参议院 1 +x:1 +宅第 1 +x:1 +西南非 1 +x:1 +词牌 1 +x:1 +作孽 1 +x:1 +角套 1 +x:1 +搓澡工 1 +x:1 +老花 1 +x:1 +纯碱厂 1 +x:1 +年利 1 +x:1 +精品 1 +x:1 +学棍 1 +x:1 +倒贴 1 +x:1 +子女 1 +x:1 +丹砂 1 +x:1 +安装队 1 +x:1 +枯槁 1 +x:1 +出乎意料 1 +x:1 +学校 1 +x:1 +皇权 1 +x:1 +坑蒙拐骗 1 +x:1 +相变式 1 +x:1 +论理学 1 +x:1 +篇眉 1 +x:1 +作家 1 +x:1 +胞妹 1 +x:1 +无边 1 +x:1 +浪里白条 1 +x:1 +原生矿物 1 +x:1 +麦迪霉素 1 +x:1 +还账 1 +x:1 +恼火 1 +x:1 +八六年 1 +x:1 +作客 1 +x:1 +脊索动物 1 +x:1 +整存整取 1 +x:1 +还贷 1 +x:1 +采购部 1 +x:1 +老舅 1 +x:1 +士绅 1 +x:1 +喇叭形 1 +x:1 +皇朝 1 +x:1 +巴国 1 +x:1 +辛集 1 +x:1 +晗 4 +x:4 +鸾凤 1 +x:1 +税案 1 +x:1 +内涝 1 +x:1 +费事 1 +x:1 +信息组 1 +x:1 +正题 1 +x:1 +臀痛穴 1 +x:1 +不值一提 1 +x:1 +倒梯形 1 +x:1 +圣殿 1 +x:1 +作对 1 +x:1 +故事链 1 +x:1 +赌气 1 +x:1 +市场观 1 +x:1 +陷 26 +x:26 +淮海戏 1 +x:1 +本部 1 +x:1 +行之有效 1 +x:1 +党群干群 1 +x:1 +滑头 1 +x:1 +架不住 1 +x:1 +餐房 1 +x:1 +诞辰日 1 +x:1 +年华 1 +x:1 +笋干 1 +x:1 +扇面儿 1 +x:1 +黄晕 1 +x:1 +入狱 1 +x:1 +状况 1 +x:1 +占有 1 +x:1 +美术院 1 +x:1 +算账者 1 +x:1 +土家女 1 +x:1 +探子 1 +x:1 +支出 1 +x:1 +假道学 1 +x:1 +音素文字 1 +x:1 +除颤器 1 +x:1 +辟谣 1 +x:1 +子系统 1 +x:1 +黄昏 1 +x:1 +三定 1 +x:1 +三宝 1 +x:1 +过 5095 +x:5095 +上好 1 +x:1 +现代化 1 +x:1 +生活区 1 +x:1 +快信 1 +x:1 +转弯子 1 +x:1 +没准儿 1 +x:1 +答 299 +x:299 +测量队 1 +x:1 +枯树 1 +x:1 +珍珠米 1 +x:1 +生活化 1 +x:1 +软缎 1 +x:1 +灭蟑药 1 +x:1 +震旦纪 1 +x:1 +春装 1 +x:1 +科普性 1 +x:1 +异己 1 +x:1 +信息网 1 +x:1 +规费 1 +x:1 +三审 1 +x:1 +篇目 1 +x:1 +求生欲 1 +x:1 +暹粒 1 +x:1 +傻瓜机 1 +x:1 +漏误 1 +x:1 +生活史 1 +x:1 +考量 1 +x:1 +亚鹤类 1 +x:1 +败诉方 1 +x:1 +三子 1 +x:1 +鹤群 1 +x:1 +果汁 1 +x:1 +三字 1 +x:1 +防意如城 1 +x:1 +图书城 1 +x:1 +广饶县 1 +x:1 +无尽 1 +x:1 +吡 1 +x:1 +漏诊 1 +x:1 +濮家村 1 +x:1 +新邵 1 +x:1 +年号 1 +x:1 +煌煌 1 +x:1 +吃不消 1 +x:1 +冽冽 1 +x:1 +盯人 1 +x:1 +肾脏 1 +x:1 +无尚 1 +x:1 +探察 1 +x:1 +新邮 1 +x:1 +室主任 1 +x:1 +三学 1 +x:1 +天伦之乐 1 +x:1 +痴痴地 1 +x:1 +涉农 1 +x:1 +谢谢 1 +x:1 +宠 8 +x:8 +臭豆腐 1 +x:1 +探家 1 +x:1 +顺治九年 1 +x:1 +迂缓 1 +x:1 +年历 1 +x:1 +官房长 1 +x:1 +优越感 1 +x:1 +小猫熊 1 +x:1 +新郎 1 +x:1 +献计献策 1 +x:1 +疏漏 1 +x:1 +老茧 1 +x:1 +滇西 1 +x:1 +舒舒服服 1 +x:1 +锯蛋白 1 +x:1 +福山区 1 +x:1 +新都 1 +x:1 +试种 1 +x:1 +破土而出 1 +x:1 +巨舰形 1 +x:1 +海洋年 1 +x:1 +五倍子 1 +x:1 +唐山市 1 +x:1 +警钟篇 1 +x:1 +睡裤 1 +x:1 +殉 2 +x:2 +灼灼 1 +x:1 +电焊 1 +x:1 +品名 1 +x:1 +气垫鞋 1 +x:1 +通信局 1 +x:1 +停堆 1 +x:1 +勤杂员 1 +x:1 +杨公庙乡 1 +x:1 +一气 1 +x:1 +黄教 1 +x:1 +皇族 1 +x:1 +巴蛇 1 +x:1 +漠不关心 1 +x:1 +劣 40 +x:40 +名人式 1 +x:1 +邮亭 1 +x:1 +答辩会 1 +x:1 +三声 1 +x:1 +疏泄 1 +x:1 +大陆架 1 +x:1 +儿童书 1 +x:1 +畦沟 1 +x:1 +抽水机 1 +x:1 +丰 94 +x:94 +邮人 1 +x:1 +枯死 1 +x:1 +不一会儿 1 +x:1 +醉乡 1 +x:1 +统一路 1 +x:1 +国民经济 1 +x:1 +试穿 1 +x:1 +一丘之貉 1 +x:1 +有喜 1 +x:1 +缴付 1 +x:1 +征程 1 +x:1 +难以忘怀 1 +x:1 +拣 36 +x:36 +征税 1 +x:1 +二部制 1 +x:1 +灾荒史 1 +x:1 +子宫 1 +x:1 +富丽 1 +x:1 +智育 1 +x:1 +合成类 1 +x:1 +无心 1 +x:1 +不见得 1 +x:1 +摊主 1 +x:1 +睡袋 1 +x:1 +睡袍 1 +x:1 +野老 1 +x:1 +文物商 1 +x:1 +品味 1 +x:1 +磨练 1 +x:1 +景地 1 +x:1 +征稽 1 +x:1 +邮件 1 +x:1 +一汽 1 +x:1 +三塘 1 +x:1 +睡衣 1 +x:1 +品咂 1 +x:1 +自愿 1 +x:1 +纺织图 1 +x:1 +东营村 1 +x:1 +京剧院 1 +x:1 +登记在册 1 +x:1 +核准权 1 +x:1 +三塔 1 +x:1 +抄送 1 +x:1 +子学 1 +x:1 +合资厂 1 +x:1 +中专处 1 +x:1 +根目录 1 +x:1 +灼热 1 +x:1 +削壁 1 +x:1 +山青水绿 1 +x:1 +魂兮归来 1 +x:1 +无异 1 +x:1 +廉政勤政 1 +x:1 +韧劲儿 1 +x:1 +子孙 1 +x:1 +校勘者 1 +x:1 +尽瘁 1 +x:1 +异常 1 +x:1 +铜质 1 +x:1 +防身 1 +x:1 +无形 1 +x:1 +继父 1 +x:1 +花椒 1 +x:1 +老者 1 +x:1 +远因 1 +x:1 +远虑 1 +x:1 +丝瓜 1 +x:1 +铝型材厂 1 +x:1 +西药 1 +x:1 +倒车 1 +x:1 +温饱型 1 +x:1 +别人 1 +x:1 +美称 1 +x:1 +富人 1 +x:1 +浪荡 1 +x:1 +黄斑 1 +x:1 +合成系 1 +x:1 +欢歌笑语 1 +x:1 +水污染 1 +x:1 +富于 1 +x:1 +相悖 1 +x:1 +无归 1 +x:1 +琅玳 1 +x:1 +华界 1 +x:1 +侧重 1 +x:1 +情牵魂系 1 +x:1 +星城镇 1 +x:1 +顿 155 +x:155 +野外工作 1 +x:1 +无度 1 +x:1 +卖卖 1 +x:1 +西芹 1 +x:1 +等同于 1 +x:1 +知天命 1 +x:1 +疏淤 1 +x:1 +三委 1 +x:1 +趾骨 1 +x:1 +摊位 1 +x:1 +验证 1 +x:1 +陡直 1 +x:1 +涉华 1 +x:1 +西医 1 +x:1 +无庸 1 +x:1 +编辑股 1 +x:1 +承包制 1 +x:1 +誊写 1 +x:1 +灰色 1 +x:1 +震旦系 1 +x:1 +雪地鞋 1 +x:1 +中草药材 1 +x:1 +分小组 1 +x:1 +史学家 1 +x:1 +睡觉 1 +x:1 +印章费 1 +x:1 +无序 1 +x:1 +条/公里 1 +x:1 +锯片 1 +x:1 +甲勾炎 1 +x:1 +耳坠子 1 +x:1 +祖上 1 +x:1 +一派 1 +x:1 +议题 1 +x:1 +富余 1 +x:1 +星期日 1 +x:1 +哑女 1 +x:1 +一流 1 +x:1 +参议长 1 +x:1 +恃才 1 +x:1 +异心 1 +x:1 +火山岛 1 +x:1 +连累 1 +x:1 +新希望 1 +x:1 +量 116 +x:116 +探头 1 +x:1 +寄生 1 +x:1 +异志 1 +x:1 +输液瓶 1 +x:1 +恰切 1 +x:1 +坎儿 1 +x:1 +申领 1 +x:1 +即将 1 +x:1 +入炉 1 +x:1 +小本微利 1 +x:1 +可不可以 1 +x:1 +西苑 1 +x:1 +扮 11 +x:11 +武庄村 1 +x:1 +选举者 1 +x:1 +悔过 1 +x:1 +火山岩 1 +x:1 +莱切市 1 +x:1 +浪船 1 +x:1 +高能低就 1 +x:1 +木炭画 1 +x:1 +鸭种 1 +x:1 +单舱 1 +x:1 +直溜 1 +x:1 +头关 1 +x:1 +慢性子 1 +x:1 +涉及 1 +x:1 +税款 1 +x:1 +吹台 1 +x:1 +一业 1 +x:1 +无常 1 +x:1 +试管 1 +x:1 +内务部 1 +x:1 +三好 1 +x:1 +直情径行 1 +x:1 +群星 1 +x:1 +宪章 1 +x:1 +有味 1 +x:1 +涉史 1 +x:1 +千禧 1 +x:1 +卓越 1 +x:1 +删繁就简 1 +x:1 +相知恨晚 1 +x:1 +芬芳 1 +x:1 +纬纱 1 +x:1 +爹 5 +x:5 +明目警心 1 +x:1 +偶蹄目 1 +x:1 +观樱会 1 +x:1 +销售权 1 +x:1 +藏民 1 +x:1 +编辑者 1 +x:1 +千秋 1 +x:1 +自知之明 1 +x:1 +生生死死 1 +x:1 +海洋局 1 +x:1 +半壁店村 1 +x:1 +荷花淀派 1 +x:1 +单色 1 +x:1 +锦鸡 1 +x:1 +年册 1 +x:1 +有名 1 +x:1 +学步 1 +x:1 +三夏 1 +x:1 +年内 1 +x:1 +淳情 1 +x:1 +征管 1 +x:1 +阴韵 1 +x:1 +凤 20 +x:20 +涉县 1 +x:1 +互补 1 +x:1 +寻食 1 +x:1 +军警靴 1 +x:1 +及第 1 +x:1 +脚爪 1 +x:1 +条案 1 +x:1 +老脸 1 +x:1 +培道 1 +x:1 +三大 1 +x:1 +有否 1 +x:1 +电池板 1 +x:1 +输液管 1 +x:1 +勉为其难 1 +x:1 +磨炼 1 +x:1 +不无道理 1 +x:1 +礼仪之邦 1 +x:1 +花柄 1 +x:1 +光芒万丈 1 +x:1 +花柱 1 +x:1 +年幼 1 +x:1 +三国 1 +x:1 +灌河口 1 +x:1 +游览者 1 +x:1 +一对一 1 +x:1 +年年 1 +x:1 +三丁锡 1 +x:1 +招揽 1 +x:1 +贮 9 +x:9 +火山口 1 +x:1 +失意 1 +x:1 +增转化 1 +x:1 +和睦相处 1 +x:1 +承托运 1 +x:1 +北龙 1 +x:1 +花枕 1 +x:1 +照射法 1 +x:1 +达沃斯 1 +x:1 +侃侃 1 +x:1 +摈 1 +x:1 +凄风苦雨 1 +x:1 +花果 1 +x:1 +参事 1 +x:1 +篇篇 1 +x:1 +八路军 1 +x:1 +银环蛇 1 +x:1 +埕 1 +x:1 +精壮 1 +x:1 +作坊 1 +x:1 +从弱到强 1 +x:1 +拨付 1 +x:1 +椅垫 1 +x:1 +奥委会 1 +x:1 +田林县 1 +x:1 +坎市 1 +x:1 +初教处 1 +x:1 +拚命 1 +x:1 +流舍村 1 +x:1 +灰质 1 +x:1 +花枪 1 +x:1 +严刑 1 +x:1 +晚明 1 +x:1 +纱筒 1 +x:1 +浪费 1 +x:1 +一把 1 +x:1 +百事通 1 +x:1 +恰州 1 +x:1 +花束 1 +x:1 +支局 1 +x:1 +补给船 1 +x:1 +繁杂 1 +x:1 +恐爪龙 1 +x:1 +单质 1 +x:1 +匆匆 1 +x:1 +党委会 1 +x:1 +黄洲乡 1 +x:1 +胆气 1 +x:1 +黄毒 1 +x:1 +西贡 1 +x:1 +杳渺 1 +x:1 +系列赛 1 +x:1 +老父亲 1 +x:1 +° 4 +x:4 +恰巧 1 +x:1 +施氏鲟 1 +x:1 +散软瘫 1 +x:1 +入网 1 +x:1 +腐坏 1 +x:1 +撕裂 1 +x:1 +外村人 1 +x:1 +环保署 1 +x:1 +易碎性 1 +x:1 +倒腾 1 +x:1 +上士 1 +x:1 +扭伤 1 +x:1 +授衔 1 +x:1 +制诰 1 +x:1 +无关 1 +x:1 +一拖 1 +x:1 +苗民 1 +x:1 +磨灭 1 +x:1 +远行 1 +x:1 +宝珠寺 1 +x:1 +词组 1 +x:1 +晚景 1 +x:1 +花朵 1 +x:1 +牧 67 +x:67 +许屯镇 1 +x:1 +普普通通 1 +x:1 +丝竹 1 +x:1 +望风捕影 1 +x:1 +惰 3 +x:3 +推选 1 +x:1 +年度 1 +x:1 +秽行 1 +x:1 +录放机 1 +x:1 +入编 1 +x:1 +花术 1 +x:1 +勃兴 1 +x:1 +度数 1 +x:1 +参选率 1 +x:1 +百废待举 1 +x:1 +乔治城 1 +x:1 +足下生辉 1 +x:1 +招招 1 +x:1 +老迈 1 +x:1 +戛然而止 1 +x:1 +不可限量 1 +x:1 +试用 1 +x:1 +三城 1 +x:1 +氟骨病 1 +x:1 +畜产品 1 +x:1 +噼啪 1 +x:1 +暴风雨 1 +x:1 +暴风雪 1 +x:1 +精妙 1 +x:1 +三基 1 +x:1 +多灾多难 1 +x:1 +词缀 1 +x:1 +传销者 1 +x:1 +吸力 1 +x:1 +账本 1 +x:1 +热水瓶 1 +x:1 +快事 1 +x:1 +霸王战 1 +x:1 +无疑 1 +x:1 +寻阅 1 +x:1 +推重 1 +x:1 +飞行点 1 +x:1 +侃价 1 +x:1 +巴解 1 +x:1 +坏帐 1 +x:1 +名胜地 1 +x:1 +防腐 1 +x:1 +纱窗 1 +x:1 +老辈 1 +x:1 +阵势 1 +x:1 +远视 1 +x:1 +灰调 1 +x:1 +鞣酸 1 +x:1 +远见 1 +x:1 +崖沟 1 +x:1 +村主任 1 +x:1 +老辣 1 +x:1 +超级大国 1 +x:1 +品学 1 +x:1 +哈铁局 1 +x:1 +内外有别 1 +x:1 +北东端 1 +x:1 +耶路撒冷 1 +x:1 +学而不厌 1 +x:1 +贝类 1 +x:1 +大巴山区 1 +x:1 +一言堂 1 +x:1 +篇章 1 +x:1 +身无分文 1 +x:1 +决策 1 +x:1 +优哉游哉 1 +x:1 +连环保 1 +x:1 +叶叶 1 +x:1 +肆 1 +x:1 +稳当 1 +x:1 +浪谷 1 +x:1 +慈联 1 +x:1 +忽闪忽闪 1 +x:1 +引人关注 1 +x:1 +晚期 1 +x:1 +津巴布韦 1 +x:1 +假如 1 +x:1 +税政 1 +x:1 +招手 1 +x:1 +毅 110 +x:110 +斯塔万格 1 +x:1 +税收 1 +x:1 +藏戏 1 +x:1 +巴西 1 +x:1 +夜深人静 1 +x:1 +异想天开 1 +x:1 +有悖于 1 +x:1 +葵花 1 +x:1 +发祥之地 1 +x:1 +成交价 1 +x:1 +解疑释惑 1 +x:1 +致公党 1 +x:1 +单调 1 +x:1 +以此类推 1 +x:1 +利马市 1 +x:1 +牟平城 1 +x:1 +黄檀 1 +x:1 +遑 3 +x:3 +惹祸 1 +x:1 +参众 1 +x:1 +粪肥 1 +x:1 +美盲 1 +x:1 +自由电子 1 +x:1 +无偿 1 +x:1 +参会 1 +x:1 +拳手 1 +x:1 +日报社 1 +x:1 +媚骨 1 +x:1 +测评 1 +x:1 +作图 1 +x:1 +人有千算 1 +x:1 +图书室 1 +x:1 +测试 1 +x:1 +别提 1 +x:1 +展望台 1 +x:1 +系列谈 1 +x:1 +大陆桥 1 +x:1 +恰当 1 +x:1 +单边 1 +x:1 +枯杉 1 +x:1 +亚运村 1 +x:1 +团圆饭 1 +x:1 +钴胺素 1 +x:1 +意见 1 +x:1 +辙 6 +x:6 +继续 1 +x:1 +换气 1 +x:1 +障碍 1 +x:1 +预交 1 +x:1 +守口如瓶 1 +x:1 +供给证 1 +x:1 +子埝 1 +x:1 +黄楼 1 +x:1 +文物处 1 +x:1 +竹篮 1 +x:1 +花旦 1 +x:1 +威胁利诱 1 +x:1 +乐融融 1 +x:1 +下花桥镇 1 +x:1 +分钟时段 1 +x:1 +参量 1 +x:1 +浪迹 1 +x:1 +探听 1 +x:1 +无可 1 +x:1 +南昌街 1 +x:1 +时紧时松 1 +x:1 +烈日 1 +x:1 +预付 1 +x:1 +支店 1 +x:1 +打招呼 1 +x:1 +勃发 1 +x:1 +有如 1 +x:1 +早出晚归 1 +x:1 +词类 1 +x:1 +经社会 1 +x:1 +千里迢迢 1 +x:1 +西进 1 +x:1 +栏圈 1 +x:1 +财雄势大 1 +x:1 +侨商 1 +x:1 +啪 5 +x:5 +芭蕉扇 1 +x:1 +撒拉族 1 +x:1 +疑者 1 +x:1 +绷子 1 +x:1 +小拇指 1 +x:1 +铜臭 1 +x:1 +入场证 1 +x:1 +平顺 1 +x:1 +导引车 1 +x:1 +程 369 +x:369 +桃花垠 1 +x:1 +有奖 1 +x:1 +盖帘 1 +x:1 +葬法 1 +x:1 +东山再起 1 +x:1 +终生不愈 1 +x:1 +个人展 1 +x:1 +信息点 1 +x:1 +粤 63 +x:63 +优越性 1 +x:1 +三味 1 +x:1 +通常 1 +x:1 +八中 1 +x:1 +合规性 1 +x:1 +大规模 1 +x:1 +呆坏账 1 +x:1 +译电员 1 +x:1 +单眼 1 +x:1 +米粮川 1 +x:1 +韶钢 1 +x:1 +还草 1 +x:1 +民间舞 1 +x:1 +三吐 1 +x:1 +美术馆 1 +x:1 +公安人员 1 +x:1 +豁免 1 +x:1 +调度局 1 +x:1 +翎 4 +x:4 +沔阳县 1 +x:1 +枯枝 1 +x:1 +三同 1 +x:1 +钙维片 1 +x:1 +糖果厂 1 +x:1 +盖菜 1 +x:1 +燃化局 1 +x:1 +年岁 1 +x:1 +弱碱 1 +x:1 +全日制 1 +x:1 +智谋 1 +x:1 +有失 1 +x:1 +守门人 1 +x:1 +无华 1 +x:1 +千瓦 1 +x:1 +翻箱倒柜 1 +x:1 +明孝陵 1 +x:1 +役 22 +x:22 +质高量足 1 +x:1 +争权夺利 1 +x:1 +装帧 1 +x:1 +图书奖 1 +x:1 +大气磅礴 1 +x:1 +阿斯马拉 1 +x:1 +词素 1 +x:1 +无助 1 +x:1 +碍 15 +x:15 +规模型 1 +x:1 +钟鼎 1 +x:1 +辉煌 1 +x:1 +单身 1 +x:1 +防范 1 +x:1 +罗山县 1 +x:1 +业绩 1 +x:1 +有声 1 +x:1 +招惹 1 +x:1 +黄桥 1 +x:1 +圣特莱萨 1 +x:1 +老路 1 +x:1 +走家串户 1 +x:1 +品头 1 +x:1 +试看 1 +x:1 +子囊 1 +x:1 +无力 1 +x:1 +通信兵 1 +x:1 +疏懒 1 +x:1 +制衡 1 +x:1 +黄栌 1 +x:1 +围捕 1 +x:1 +经济型 1 +x:1 +勃勃 1 +x:1 +进步奖 1 +x:1 +规范 1 +x:1 +滑坡 1 +x:1 +核扩散 1 +x:1 +秽语 1 +x:1 +黄栗 1 +x:1 +明细账 1 +x:1 +授课 1 +x:1 +联合国城 1 +x:1 +自产自销 1 +x:1 +贼 27 +x:27 +英 561 +x:561 +景芝镇 1 +x:1 +吉凶祸福 1 +x:1 +姊妹 1 +x:1 +贾拉瓦 1 +x:1 +精密 1 +x:1 +百 918 +x:918 +真凭实据 1 +x:1 +丁家村 1 +x:1 +黄棉 1 +x:1 +假定 1 +x:1 +林口县 1 +x:1 +异化 1 +x:1 +春光曲 1 +x:1 +举鼎绝膑 1 +x:1 +花摊 1 +x:1 +胸无城府 1 +x:1 +喷云吐雾 1 +x:1 +学术 1 +x:1 +盟长 1 +x:1 +黑龙江街 1 +x:1 +淤堵 1 +x:1 +税服 1 +x:1 +制毒 1 +x:1 +学期 1 +x:1 +出证 1 +x:1 +音域 1 +x:1 +不可向迩 1 +x:1 +云西 1 +x:1 +形势 1 +x:1 +黄梅 1 +x:1 +干戈扰攘 1 +x:1 +媚颜 1 +x:1 +鞍花 1 +x:1 +作品 1 +x:1 +得胜 1 +x:1 +万岭 1 +x:1 +知不知道 1 +x:1 +青花瓷 1 +x:1 +吕屯村 1 +x:1 +黄梨 1 +x:1 +老账 1 +x:1 +精子 1 +x:1 +丹墀 1 +x:1 +有优有劣 1 +x:1 +军史馆 1 +x:1 +潘塔诺 1 +x:1 +报话机 1 +x:1 +西南风 1 +x:1 +赤狐 1 +x:1 +格致诚正 1 +x:1 +怯阵 1 +x:1 +老马车社 1 +x:1 +非工程性 1 +x:1 +尸骨 1 +x:1 +花插 1 +x:1 +动员部 1 +x:1 +弄堂 1 +x:1 +有志 1 +x:1 +警探伪装 1 +x:1 +疑 11 +x:11 +尸骸 1 +x:1 +综论编 1 +x:1 +滴里嘟噜 1 +x:1 +有心 1 +x:1 +游者 1 +x:1 +停刊 1 +x:1 +四季如春 1 +x:1 +售货棚 1 +x:1 +邮电局 1 +x:1 +划时代 1 +x:1 +救济化 1 +x:1 +辅轨 1 +x:1 +晚报 1 +x:1 +恰好 1 +x:1 +敏感 1 +x:1 +目标化 1 +x:1 +景点 1 +x:1 +多云到阴 1 +x:1 +纺织局 1 +x:1 +除旧迎新 1 +x:1 +有忧 1 +x:1 +周村镇 1 +x:1 +乳化术 1 +x:1 +三力 1 +x:1 +学农 1 +x:1 +有虚有实 1 +x:1 +汇报展 1 +x:1 +敦雷 1 +x:1 +自尊 1 +x:1 +缺血 1 +x:1 +身强体壮 1 +x:1 +哑剧 1 +x:1 +玄之又玄 1 +x:1 +龟爪儿 1 +x:1 +定居点 1 +x:1 +胞兄 1 +x:1 +求业 1 +x:1 +招架 1 +x:1 +高高大大 1 +x:1 +冰清玉洁 1 +x:1 +公言报 1 +x:1 +回避 1 +x:1 +程序性 1 +x:1 +杲 5 +x:5 +摈除 1 +x:1 +中标人 1 +x:1 +影响面 1 +x:1 +勿 46 +x:46 +过犹不及 1 +x:1 +疲惫不堪 1 +x:1 +藏本 1 +x:1 +试点 1 +x:1 +考风 1 +x:1 +有缘 1 +x:1 +停办 1 +x:1 +税性 1 +x:1 +蔓生植物 1 +x:1 +贼亮 1 +x:1 +新馆 1 +x:1 +支塘 1 +x:1 +巴豆 1 +x:1 +衰减 1 +x:1 +拐棒 1 +x:1 +诗选集 1 +x:1 +丝纶 1 +x:1 +间接经验 1 +x:1 +顾问业 1 +x:1 +藏有 1 +x:1 +皮桶子 1 +x:1 +顺治二年 1 +x:1 +丝线 1 +x:1 +丝纹 1 +x:1 +躬 11 +x:11 +正人君子 1 +x:1 +三副 1 +x:1 +坏官 1 +x:1 +纱罩 1 +x:1 +疗济众生 1 +x:1 +吹角 1 +x:1 +皮影戏 1 +x:1 +拐棍 1 +x:1 +严气正色 1 +x:1 +部类 1 +x:1 +公证人员 1 +x:1 +词章 1 +x:1 +丝绒 1 +x:1 +凤尾竹 1 +x:1 +条件刺激 1 +x:1 +南堰村 1 +x:1 +恰如 1 +x:1 +丝织 1 +x:1 +考题 1 +x:1 +自我牺牲 1 +x:1 +媳妇 1 +x:1 +险境 1 +x:1 +农业户 1 +x:1 +丝绵 1 +x:1 +窑炉 1 +x:1 +获票率 1 +x:1 +腐化 1 +x:1 +白头偕老 1 +x:1 +名烟 1 +x:1 +湟中县 1 +x:1 +丝绸 1 +x:1 +集群式 1 +x:1 +三制 1 +x:1 +作古 1 +x:1 +供排水 1 +x:1 +夜鹭鸟 1 +x:1 +惠川 1 +x:1 +招术 1 +x:1 +东楼 1 +x:1 +求人 1 +x:1 +一树百获 1 +x:1 +三变 1 +x:1 +天公作美 1 +x:1 +研制 1 +x:1 +花招 1 +x:1 +墨西哥队 1 +x:1 +养目镜 1 +x:1 +三叉 1 +x:1 +三反 1 +x:1 +穷源溯流 1 +x:1 +单被 1 +x:1 +支委 1 +x:1 +老话 1 +x:1 +一期 1 +x:1 +民初字 1 +x:1 +芯子 1 +x:1 +花拳 1 +x:1 +远足 1 +x:1 +垧 1 +x:1 +签名册 1 +x:1 +单循环赛 1 +x:1 +双女户 1 +x:1 +牟平区 1 +x:1 +基联会 1 +x:1 +坎子 1 +x:1 +家长 1 +x:1 +稳定 1 +x:1 +丝网 1 +x:1 +粮种 1 +x:1 +三原 1 +x:1 +名胜区 1 +x:1 +有底 1 +x:1 +鸽场 1 +x:1 +讴歌 1 +x:1 +睡莲 1 +x:1 +孙女婿 1 +x:1 +有序 1 +x:1 +蚀 8 +x:8 +单裤 1 +x:1 +精巢 1 +x:1 +西裤 1 +x:1 +堤防 1 +x:1 +机关刊物 1 +x:1 +探区 1 +x:1 +精巧 1 +x:1 +保家卫国 1 +x:1 +交管局 1 +x:1 +一来 1 +x:1 +烩 2 +x:2 +环保站 1 +x:1 +粮秣 1 +x:1 +花押 1 +x:1 +纱线 1 +x:1 +基坑 1 +x:1 +老记 1 +x:1 +形而下 1 +x:1 +形而上 1 +x:1 +德保县 1 +x:1 +西装 1 +x:1 +聆听 1 +x:1 +此起彼落 1 +x:1 +有度 1 +x:1 +滑冰 1 +x:1 +新颖 1 +x:1 +钟馗 1 +x:1 +花托 1 +x:1 +响亮 1 +x:1 +三单 1 +x:1 +削发 1 +x:1 +肠系膜 1 +x:1 +以备不测 1 +x:1 +疏松 1 +x:1 +破浪前进 1 +x:1 +棉铃虫蛹 1 +x:1 +麻木不仁 1 +x:1 +刘家堡 1 +x:1 +涂层 1 +x:1 +有点儿 1 +x:1 +魁伟 1 +x:1 +年寿 1 +x:1 +笨拙 1 +x:1 +文物库 1 +x:1 +江郎才尽 1 +x:1 +三危 1 +x:1 +熨 5 +x:5 +辉石 1 +x:1 +就业办 1 +x:1 +发光剂 1 +x:1 +领事局 1 +x:1 +晋剧团 1 +x:1 +豁嘴 1 +x:1 +品德 1 +x:1 +天然磁铁 1 +x:1 +静脉曲张 1 +x:1 +远别 1 +x:1 +国内法 1 +x:1 +帐篷 1 +x:1 +悄悄话 1 +x:1 +停发 1 +x:1 +三墩营村 1 +x:1 +采选业 1 +x:1 +三北 1 +x:1 +三化 1 +x:1 +难得一见 1 +x:1 +无味 1 +x:1 +去年底 1 +x:1 +三包 1 +x:1 +单衣 1 +x:1 +蟊贼 1 +x:1 +盖度 1 +x:1 +远走 1 +x:1 +袅娜 1 +x:1 +极致 1 +x:1 +去年度 1 +x:1 +年宵 1 +x:1 +花房 1 +x:1 +哺乳类 1 +x:1 +单行 1 +x:1 +朱砂 1 +x:1 +疏朗 1 +x:1 +推销 1 +x:1 +流浪者 1 +x:1 +无功受禄 1 +x:1 +年审 1 +x:1 +图书展 1 +x:1 +寄籍 1 +x:1 +办报人 1 +x:1 +身残志坚 1 +x:1 +假帐 1 +x:1 +掉 521 +x:521 +以强凌弱 1 +x:1 +子口 1 +x:1 +学报 1 +x:1 +假币 1 +x:1 +村部 1 +x:1 +品尝 1 +x:1 +部级 1 +x:1 +精度 1 +x:1 +入秋 1 +x:1 +拥护者 1 +x:1 +黄浦 1 +x:1 +肆行 1 +x:1 +坏处 1 +x:1 +继站 1 +x:1 +明细表 1 +x:1 +学技 1 +x:1 +执针者 1 +x:1 +餐椅 1 +x:1 +管窥所及 1 +x:1 +胃液 1 +x:1 +收入额 1 +x:1 +增殖堆 1 +x:1 +图鉴 1 +x:1 +停停 1 +x:1 +巍 30 +x:30 +轧机 1 +x:1 +鹅行鸭步 1 +x:1 +随便 1 +x:1 +天然免疫 1 +x:1 +桤树林 1 +x:1 +福州戏 1 +x:1 +起死回生 1 +x:1 +敏捷 1 +x:1 +演事 1 +x:1 +藏族 1 +x:1 +指挥权 1 +x:1 +磨盘 1 +x:1 +娃娃脸 1 +x:1 +丝米 1 +x:1 +卓著 1 +x:1 +单刀 1 +x:1 +单词 1 +x:1 +心直口快 1 +x:1 +远在 1 +x:1 +类地行星 1 +x:1 +计划性 1 +x:1 +盟邦 1 +x:1 +异图 1 +x:1 +持股会 1 +x:1 +单证 1 +x:1 +防虫 1 +x:1 +才略 1 +x:1 +主场 1 +x:1 +族规 1 +x:1 +粮税 1 +x:1 +吹动 1 +x:1 +衰变 1 +x:1 +圣母 1 +x:1 +保护期 1 +x:1 +涉嫌 1 +x:1 +老街 1 +x:1 +滑动 1 +x:1 +自制率 1 +x:1 +新干县 1 +x:1 +百分表 1 +x:1 +黄淮 1 +x:1 +辅路 1 +x:1 +招数 1 +x:1 +信手拈来 1 +x:1 +老表 1 +x:1 +签约人 1 +x:1 +假座 1 +x:1 +单元房 1 +x:1 +入神 1 +x:1 +华铜海式 1 +x:1 +子午 1 +x:1 +特燃处 1 +x:1 +丝糕 1 +x:1 +棘手 1 +x:1 +眉山县 1 +x:1 +平衡木 1 +x:1 +开国史 1 +x:1 +考验 1 +x:1 +景片 1 +x:1 +精干 1 +x:1 +扶贫 1 +x:1 +防蛀 1 +x:1 +小人儿 1 +x:1 +贞洁 1 +x:1 +喜怒相通 1 +x:1 +顺眼 1 +x:1 +招收 1 +x:1 +景物 1 +x:1 +作出 1 +x:1 +暂时性 1 +x:1 +个人崇拜 1 +x:1 +七沟八梁 1 +x:1 +绷带 1 +x:1 +城工部 1 +x:1 +熙宁 1 +x:1 +有分寸 1 +x:1 +密苏里州 1 +x:1 +异型 1 +x:1 +牙 39 +x:39 +淄博 1 +x:1 +精微 1 +x:1 +目标值 1 +x:1 +害群之马 1 +x:1 +濡沫相对 1 +x:1 +文明牌 1 +x:1 +糖馅 1 +x:1 +随从 1 +x:1 +环保碑 1 +x:1 +琮琮 1 +x:1 +粮管 1 +x:1 +绞手 1 +x:1 +进门票卡 1 +x:1 +勾股形 1 +x:1 +国防绿 1 +x:1 +舍珠买椟 1 +x:1 +净化论 1 +x:1 +尸首 1 +x:1 +仁 14 +x:14 +三军 1 +x:1 +里子 1 +x:1 +远近 1 +x:1 +磨石 1 +x:1 +远远 1 +x:1 +秽迹 1 +x:1 +镇子梁乡 1 +x:1 +瓦釜雷鸣 1 +x:1 +作假 1 +x:1 +芝罘湾 1 +x:1 +白马垅 1 +x:1 +替补 1 +x:1 +异域 1 +x:1 +骑手 1 +x:1 +格穆苏村 1 +x:1 +文物展 1 +x:1 +沾连 1 +x:1 +盲字 1 +x:1 +顺水推舟 1 +x:1 +年头 1 +x:1 +扫盲 1 +x:1 +伪造罪 1 +x:1 +订餐 1 +x:1 +文物局 1 +x:1 +精心 1 +x:1 +咂摸 1 +x:1 +凡尔赛 1 +x:1 +餐桌 1 +x:1 +底部 1 +x:1 +史观 1 +x:1 +磨眼 1 +x:1 +黄泉 1 +x:1 +土地改革 1 +x:1 +疏散 1 +x:1 +滑县 1 +x:1 +漂砾群 1 +x:1 +三光 1 +x:1 +官报私仇 1 +x:1 +规模化 1 +x:1 +削减 1 +x:1 +赞许者 1 +x:1 +个人奖 1 +x:1 +三元 1 +x:1 +支子 1 +x:1 +三养 1 +x:1 +随之 1 +x:1 +五倍子虫 1 +x:1 +木制品 1 +x:1 +黄泥 1 +x:1 +勤杂工 1 +x:1 +部长级 1 +x:1 +三八 1 +x:1 +发号施令 1 +x:1 +异地 1 +x:1 +三公 1 +x:1 +巴音郭楞 1 +x:1 +一方 1 +x:1 +里下河 1 +x:1 +含盐量 1 +x:1 +与此同时 1 +x:1 +一旁 1 +x:1 +床边橱 1 +x:1 +长治久安 1 +x:1 +赌本 1 +x:1 +精彩 1 +x:1 +瓒 1 +x:1 +反面教材 1 +x:1 +黄沙 1 +x:1 +猎鹰 1 +x:1 +盼归 1 +x:1 +小车费 1 +x:1 +甄别 1 +x:1 +授受 1 +x:1 +醉翁亭 1 +x:1 +一无 1 +x:1 +一旦 1 +x:1 +一日 1 +x:1 +穷极无聊 1 +x:1 +精当 1 +x:1 +衰势 1 +x:1 +准备金 1 +x:1 +紫阳 1 +x:1 +丁丁当当 1 +x:1 +选委会 1 +x:1 +黄油 1 +x:1 +税捐 1 +x:1 +突飞猛进 1 +x:1 +命 100 +x:100 +美院附中 1 +x:1 +测距 1 +x:1 +险崖老林 1 +x:1 +外务部 1 +x:1 +征求 1 +x:1 +守门员 1 +x:1 +停业 1 +x:1 +串通 1 +x:1 +拳师 1 +x:1 +老雕 1 +x:1 +寄托 1 +x:1 +福州籍 1 +x:1 +科普界 1 +x:1 +视距 1 +x:1 +停下 1 +x:1 +低声下气 1 +x:1 +灯心草 1 +x:1 +作伴 1 +x:1 +眼底 1 +x:1 +粮播 1 +x:1 +馆牌 1 +x:1 +不远万里 1 +x:1 +申述 1 +x:1 +远邻 1 +x:1 +年均值 1 +x:1 +键 8 +x:8 +限制口 1 +x:1 +新蔡 1 +x:1 +扁桃腺 1 +x:1 +随到随收 1 +x:1 +作伪 1 +x:1 +绮筵 1 +x:1 +三亚 1 +x:1 +热心 1 +x:1 +单间 1 +x:1 +不堪一击 1 +x:1 +南导堤 1 +x:1 +强人所难 1 +x:1 +晚练 1 +x:1 +不谋而同 1 +x:1 +喷射 1 +x:1 +不谋而合 1 +x:1 +西门 1 +x:1 +银妆素裹 1 +x:1 +大慧寺 1 +x:1 +远郊 1 +x:1 +望月湖 1 +x:1 +邛崃 1 +x:1 +赞颂声 1 +x:1 +有线 1 +x:1 +芳洲 1 +x:1 +护村队 1 +x:1 +新蕾 1 +x:1 +盖饭 1 +x:1 +童男童女 1 +x:1 +申辩 1 +x:1 +主体化 1 +x:1 +热忱 1 +x:1 +亿万 1 +x:1 +三产 1 +x:1 +景泰 1 +x:1 +预后 1 +x:1 +诡计 1 +x:1 +丰顺县 1 +x:1 +三九 1 +x:1 +三K党 1 +x:1 +远逝 1 +x:1 +暴徒 1 +x:1 +富士 1 +x:1 +锦西 1 +x:1 +三义 1 +x:1 +计划组 1 +x:1 +谆谆 1 +x:1 +小石城 1 +x:1 +振兴史 1 +x:1 +景气 1 +x:1 +浴血奋战 1 +x:1 +窜 25 +x:25 +矮胖 1 +x:1 +雅加达 1 +x:1 +造谣中伤 1 +x:1 +辉长岩 1 +x:1 +转炉 1 +x:1 +三乱 1 +x:1 +靠背轮 1 +x:1 +削价 1 +x:1 +贝方 1 +x:1 +眼帘 1 +x:1 +华东师大 1 +x:1 +停产 1 +x:1 +汾西县 1 +x:1 +离子化 1 +x:1 +惹怒 1 +x:1 +农转非 1 +x:1 +三业 1 +x:1 +预告 1 +x:1 +远道 1 +x:1 +黄玉 1 +x:1 +作保 1 +x:1 +检验 1 +x:1 +就地正法 1 +x:1 +研修 1 +x:1 +三不 1 +x:1 +惹恼 1 +x:1 +探亲 1 +x:1 +词曲 1 +x:1 +虎林园 1 +x:1 +防风 1 +x:1 +Ⅱ 8 +x:8 +匈牙利队 1 +x:1 +试法 1 +x:1 +吸取 1 +x:1 +绿矾 1 +x:1 +掺假 1 +x:1 +求助 1 +x:1 +探井 1 +x:1 +三中 1 +x:1 +千里驹 1 +x:1 +高梁面 1 +x:1 +三严 1 +x:1 +学籍 1 +x:1 +黄牌 1 +x:1 +今是昨非 1 +x:1 +堕胎法 1 +x:1 +生存型 1 +x:1 +黄片 1 +x:1 +作东 1 +x:1 +作业 1 +x:1 +赤卫军 1 +x:1 +配餐部 1 +x:1 +巴金 1 +x:1 +褐 2 +x:2 +红男绿女 1 +x:1 +患难与共 1 +x:1 +黄牛 1 +x:1 +西南航 1 +x:1 +党群关系 1 +x:1 +食用者 1 +x:1 +大型化 1 +x:1 +疏篱 1 +x:1 +公路口 1 +x:1 +计划署 1 +x:1 +热度 1 +x:1 +围建 1 +x:1 +珍异 1 +x:1 +收付汇 1 +x:1 +作为 1 +x:1 +作主 1 +x:1 +走读生 1 +x:1 +凝入 1 +x:1 +支出单 1 +x:1 +掷 14 +x:14 +茭白 1 +x:1 +腊玛古猿 1 +x:1 +铜骨 1 +x:1 +淤斑 1 +x:1 +探伤 1 +x:1 +苗疆 1 +x:1 +单链 1 +x:1 +词条 1 +x:1 +新著 1 +x:1 +作乐 1 +x:1 +敦请 1 +x:1 +无所不有 1 +x:1 +一等 1 +x:1 +村道 1 +x:1 +火石岗村 1 +x:1 +肿大 1 +x:1 +窝藏 1 +x:1 +亲王 1 +x:1 +研习 1 +x:1 +面熟 1 +x:1 +签约关 1 +x:1 +锡矿山 1 +x:1 +作乱 1 +x:1 +花纹 1 +x:1 +花纸 1 +x:1 +发烧式 1 +x:1 +花红 1 +x:1 +拆资 1 +x:1 +普法教育 1 +x:1 +一筹 1 +x:1 +景深 1 +x:1 +求医 1 +x:1 +有嘴无心 1 +x:1 +腐乳 1 +x:1 +一意孤行 1 +x:1 +领 190 +x:190 +五光十色 1 +x:1 +尸蜡 1 +x:1 +响动 1 +x:1 +涧磁村 1 +x:1 +部务会 1 +x:1 +灰铁 1 +x:1 +日产量 1 +x:1 +三低 1 +x:1 +物品表 1 +x:1 +预售 1 +x:1 +脑组织 1 +x:1 +热带 1 +x:1 +梯度性 1 +x:1 +芳泽 1 +x:1 +本片 1 +x:1 +食欲不振 1 +x:1 +融铸 1 +x:1 +粮改 1 +x:1 +专家局 1 +x:1 +抛秧 1 +x:1 +电池组 1 +x:1 +翻砂工 1 +x:1 +三优 1 +x:1 +啃 56 +x:56 +暗红色 1 +x:1 +飘飘然 1 +x:1 +等价交换 1 +x:1 +入春 1 +x:1 +美满 1 +x:1 +指挥官 1 +x:1 +面包车 1 +x:1 +紫茉莉 1 +x:1 +高台县 1 +x:1 +皮帽耳 1 +x:1 +无可取代 1 +x:1 +粉碎车 1 +x:1 +酸黄瓜 1 +x:1 +上学 1 +x:1 +皇爷 1 +x:1 +作价 1 +x:1 +城管局 1 +x:1 +一业为主 1 +x:1 +指挥家 1 +x:1 +雷利赞省 1 +x:1 +凝冻 1 +x:1 +常言道 1 +x:1 +下小河村 1 +x:1 +三伯 1 +x:1 +笑哈哈 1 +x:1 +标兵户 1 +x:1 +渔翁 1 +x:1 +石漫滩 1 +x:1 +参场 1 +x:1 +灰青 1 +x:1 +赔偿案 1 +x:1 +挠头 1 +x:1 +指挥塔 1 +x:1 +应试 1 +x:1 +随口 1 +x:1 +路口镇 1 +x:1 +稳油期 1 +x:1 +舌头 1 +x:1 +滨海区 1 +x:1 +专业村 1 +x:1 +雷电交加 1 +x:1 +考虑 1 +x:1 +入时 1 +x:1 +烛 1 +x:1 +围巾 1 +x:1 +翎毛 1 +x:1 +旗语 1 +x:1 +翁源村 1 +x:1 +工薪阶层 1 +x:1 +打车 1 +x:1 +求偶 1 +x:1 +崖石 1 +x:1 +修修 1 +x:1 +不冻港 1 +x:1 +化整为零 1 +x:1 +老铺 1 +x:1 +火药桶 1 +x:1 +催眠术 1 +x:1 +超世之才 1 +x:1 +答茬儿 1 +x:1 +扫毒 1 +x:1 +以迄于今 1 +x:1 +序论 1 +x:1 +环保日 1 +x:1 +黄焖 1 +x:1 +预算案 1 +x:1 +热工 1 +x:1 +龙门寺 1 +x:1 +阵阵 1 +x:1 +畜力车 1 +x:1 +针法 1 +x:1 +装入 1 +x:1 +子侄 1 +x:1 +另眼相看 1 +x:1 +赌窝 1 +x:1 +乎夫楼 1 +x:1 +学经 1 +x:1 +少儿部 1 +x:1 +滨海县 1 +x:1 +做手脚 1 +x:1 +随即 1 +x:1 +烯 1 +x:1 +宋双党 1 +x:1 +烹制 1 +x:1 +眼尖 1 +x:1 +随叫随到 1 +x:1 +撤 59 +x:59 +杳无人烟 1 +x:1 +商酌 1 +x:1 +横扫千军 1 +x:1 +腹水 1 +x:1 +卢湾区 1 +x:1 +阵雨 1 +x:1 +疮痍满目 1 +x:1 +擒敌 1 +x:1 +苏中区 1 +x:1 +呼和浩特 1 +x:1 +花絮 1 +x:1 +半自耕农 1 +x:1 +还魂 1 +x:1 +褐藻 1 +x:1 +结膜炎 1 +x:1 +食用菌 1 +x:1 +抄件 1 +x:1 +有染 1 +x:1 +订阅费 1 +x:1 +层级制 1 +x:1 +破竹之势 1 +x:1 +马头琴声 1 +x:1 +萨那 1 +x:1 +西面 1 +x:1 +单面 1 +x:1 +西非 1 +x:1 +坑道 1 +x:1 +英姿焕发 1 +x:1 +绿肥作物 1 +x:1 +仨 5 +x:5 +型式 1 +x:1 +西青 1 +x:1 +舞台 1 +x:1 +无限大 1 +x:1 +区别点 1 +x:1 +份儿饭 1 +x:1 +土家人 1 +x:1 +见证人 1 +x:1 +制造 1 +x:1 +花糕 1 +x:1 +胃炎 1 +x:1 +毛毛草草 1 +x:1 +鞍马 1 +x:1 +略见一斑 1 +x:1 +摊子 1 +x:1 +推说 1 +x:1 +贞烈 1 +x:1 +子代 1 +x:1 +薪资 1 +x:1 +千里香 1 +x:1 +琚 1 +x:1 +辅道 1 +x:1 +絮叨 1 +x:1 +娃娃鱼 1 +x:1 +聪慧 1 +x:1 +添油加醋 1 +x:1 +栓子 1 +x:1 +求全 1 +x:1 +哈博罗内 1 +x:1 +柜 8 +x:8 +贾楼乡 1 +x:1 +锥栗 1 +x:1 +陈陈相因 1 +x:1 +增长带 1 +x:1 +财税厅 1 +x:1 +董事会 1 +x:1 +推论 1 +x:1 +寄意 1 +x:1 +灰阑 1 +x:1 +擂主 1 +x:1 +磁通量 1 +x:1 +汤匙 1 +x:1 +邮寄 1 +x:1 +慌 21 +x:21 +比如说 1 +x:1 +程序模块 1 +x:1 +推让 1 +x:1 +疏离 1 +x:1 +词数 1 +x:1 +花粉 1 +x:1 +宝山 1 +x:1 +高架桥 1 +x:1 +陶泥家 1 +x:1 +亦喜亦忧 1 +x:1 +阶层 1 +x:1 +不郎不秀 1 +x:1 +清风两袖 1 +x:1 +国防报 1 +x:1 +窥视 1 +x:1 +窥见 1 +x:1 +桐柏 1 +x:1 +小生产 1 +x:1 +慈光 1 +x:1 +构建 1 +x:1 +围岩 1 +x:1 +猎苑 1 +x:1 +嫁接式 1 +x:1 +湾 5 +x:5 +观世音 1 +x:1 +克丝钳子 1 +x:1 +死乞白赖 1 +x:1 +鄙薄 1 +x:1 +那盆 1 +x:1 +围屏 1 +x:1 +灰雀 1 +x:1 +子书 1 +x:1 +围屋 1 +x:1 +射击区 1 +x:1 +催眠曲 1 +x:1 +喧嚷 1 +x:1 +红皮症 1 +x:1 +花籽 1 +x:1 +背叛 1 +x:1 +气垫船 1 +x:1 +齐国 1 +x:1 +烂 47 +x:47 +缴存 1 +x:1 +西陵 1 +x:1 +粮权 1 +x:1 +词旨 1 +x:1 +集市贸易 1 +x:1 +富家 1 +x:1 +挨骂 1 +x:1 +一江之隔 1 +x:1 +望洋兴叹 1 +x:1 +花簇 1 +x:1 +距离 1 +x:1 +筛 5 +x:5 +公生明 1 +x:1 +罗庄乡 1 +x:1 +富宁 1 +x:1 +浑然无垠 1 +x:1 +眼高手低 1 +x:1 +惟它独尊 1 +x:1 +限制值 1 +x:1 +打折风 1 +x:1 +商品率 1 +x:1 +分门别类 1 +x:1 +衰亡 1 +x:1 +磨歌 1 +x:1 +缺衣少食 1 +x:1 +触发器 1 +x:1 +地磁力 1 +x:1 +油菜地 1 +x:1 +信息港 1 +x:1 +试样 1 +x:1 +帐房 1 +x:1 +侗寨 1 +x:1 +关门大吉 1 +x:1 +申诉 1 +x:1 +大田作物 1 +x:1 +至此 1 +x:1 +佘家湾村 1 +x:1 +东方队 1 +x:1 +高个儿 1 +x:1 +营林 1 +x:1 +掺和 1 +x:1 +光学玻璃 1 +x:1 +收贷员 1 +x:1 +欠资 1 +x:1 +国防日 1 +x:1 +灭草剂 1 +x:1 +申请 1 +x:1 +樱桃园乡 1 +x:1 +申说 1 +x:1 +说情人 1 +x:1 +供给部 1 +x:1 +藏羚 1 +x:1 +齐抓共建 1 +x:1 +牙牙学语 1 +x:1 +花篮 1 +x:1 +性滥交 1 +x:1 +寄居 1 +x:1 +欠账 1 +x:1 +暖呼呼 1 +x:1 +暴动 1 +x:1 +考考 1 +x:1 +制革 1 +x:1 +精神文明 1 +x:1 +盟誓 1 +x:1 +匆促 1 +x:1 +通信业 1 +x:1 +跨度 1 +x:1 +紧固件 1 +x:1 +市场饭 1 +x:1 +欠费 1 +x:1 +鹿泉市 1 +x:1 +安丰乡 1 +x:1 +参加 1 +x:1 +重焕生机 1 +x:1 +零存 1 +x:1 +利古里亚 1 +x:1 +署 27 +x:27 +画栋雕梁 1 +x:1 +老广 1 +x:1 +理想化 1 +x:1 +不耻下问 1 +x:1 +花箭 1 +x:1 +求富若渴 1 +x:1 +花筒 1 +x:1 +鹤溪 1 +x:1 +铜鼓 1 +x:1 +蔚蓝色 1 +x:1 +恩纳村 1 +x:1 +寻访 1 +x:1 +围子 1 +x:1 +中质 1 +x:1 +同流合污 1 +x:1 +直方图 1 +x:1 +猖獗 1 +x:1 +铜鼎 1 +x:1 +老帅 1 +x:1 +格拉茨 1 +x:1 +非天然气 1 +x:1 +争金夺银 1 +x:1 +前一天 1 +x:1 +忐忑 1 +x:1 +一级 1 +x:1 +女足赛 1 +x:1 +五优先 1 +x:1 +蛋白尿 1 +x:1 +晚稻 1 +x:1 +埃拉特 1 +x:1 +固执己见 1 +x:1 +暴客 1 +x:1 +黄石 1 +x:1 +辅音 1 +x:1 +指认 1 +x:1 +贾维茨 1 +x:1 +邮局 1 +x:1 +号啕大哭 1 +x:1 +着哪 1 +x:1 +一经 1 +x:1 +暴富 1 +x:1 +时令病 1 +x:1 +乘警队 1 +x:1 +串铃 1 +x:1 +网状林 1 +x:1 +红墨水 1 +x:1 +宇宙船 1 +x:1 +一大早 1 +x:1 +隆庆二年 1 +x:1 +受众 1 +x:1 +热学 1 +x:1 +农业税 1 +x:1 +花笺 1 +x:1 +救生伞 1 +x:1 +违犯者 1 +x:1 +村里 1 +x:1 +锦绣江山 1 +x:1 +济南市 1 +x:1 +销 174 +x:174 +和好如初 1 +x:1 +凶手 1 +x:1 +西邻 1 +x:1 +桐油树 1 +x:1 +擒拿 1 +x:1 +透析机 1 +x:1 +增长年 1 +x:1 +党委办 1 +x:1 +执笔人 1 +x:1 +略表 1 +x:1 +营房部 1 +x:1 +侧 33 +x:33 +童装展 1 +x:1 +豁亮 1 +x:1 +灾害源 1 +x:1 +稳操左券 1 +x:1 +勐腊 1 +x:1 +踱步 1 +x:1 +扬沙 1 +x:1 +呆矿 1 +x:1 +褐色 1 +x:1 +紫貂 1 +x:1 +撰写 1 +x:1 +奄奄待毙 1 +x:1 +拨号 1 +x:1 +秽闻 1 +x:1 +皇皇 1 +x:1 +形成层 1 +x:1 +宣纸 1 +x:1 +媒人 1 +x:1 +革新迷 1 +x:1 +西部 1 +x:1 +肾小球 1 +x:1 +学科 1 +x:1 +随和 1 +x:1 +税种 1 +x:1 +侗乡 1 +x:1 +拨发 1 +x:1 +传呼机 1 +x:1 +限定词 1 +x:1 +香会 1 +x:1 +西郊 1 +x:1 +远门 1 +x:1 +持币人 1 +x:1 +掀开 1 +x:1 +小丰营村 1 +x:1 +甲种射线 1 +x:1 +妈 43 +x:43 +假分数 1 +x:1 +主道 1 +x:1 +深层格 1 +x:1 +参半 1 +x:1 +亚洲司 1 +x:1 +远销 1 +x:1 +与日俱增 1 +x:1 +板兰根 1 +x:1 +虾塘 1 +x:1 +钢材厂 1 +x:1 +入手 1 +x:1 +榨 4 +x:4 +费心 1 +x:1 +戴高帽子 1 +x:1 +低等动物 1 +x:1 +糊味 1 +x:1 +撒哈拉 1 +x:1 +新股 1 +x:1 +畲乡 1 +x:1 +随员 1 +x:1 +珍宝 1 +x:1 +云岗 1 +x:1 +续集 1 +x:1 +富川 1 +x:1 +东兴市 1 +x:1 +税票 1 +x:1 +堤身 1 +x:1 +预先 1 +x:1 +武进县 1 +x:1 +预兆 1 +x:1 +新河乡 1 +x:1 +业态 1 +x:1 +曾家岩 1 +x:1 +哑嗓 1 +x:1 +入户 1 +x:1 +清爽型 1 +x:1 +康乐球 1 +x:1 +随后 1 +x:1 +主程序 1 +x:1 +随同 1 +x:1 +肾盂炎 1 +x:1 +三公开 1 +x:1 +润滑剂 1 +x:1 +价值形式 1 +x:1 +新霉素 1 +x:1 +里庄村 1 +x:1 +头班车 1 +x:1 +按摩院 1 +x:1 +峨边县 1 +x:1 +串门 1 +x:1 +苏木里 1 +x:1 +火化率 1 +x:1 +词性 1 +x:1 +先驱 1 +x:1 +鱼卷 1 +x:1 +底金 1 +x:1 +萌 12 +x:12 +求告 1 +x:1 +曲谱 1 +x:1 +党纪政纪 1 +x:1 +花种 1 +x:1 +济阳 1 +x:1 +新茶 1 +x:1 +让 3499 +x:3499 +慢慢来 1 +x:1 +参训者 1 +x:1 +化为泡影 1 +x:1 +合成氨 1 +x:1 +政协办 1 +x:1 +历经 1 +x:1 +求同 1 +x:1 +泥污 1 +x:1 +胃病 1 +x:1 +展现 1 +x:1 +苏格兰队 1 +x:1 +费尽 1 +x:1 +学童 1 +x:1 +国防林 1 +x:1 +枷锁 1 +x:1 +坐井观天 1 +x:1 +老祖宗 1 +x:1 +闭 54 +x:54 +赞叹声 1 +x:1 +舒 159 +x:159 +南竹 1 +x:1 +一类 1 +x:1 +新药 1 +x:1 +黄田 1 +x:1 +逆子 1 +x:1 +淳熙 1 +x:1 +只字 1 +x:1 +您好 1 +x:1 +继承 1 +x:1 +邮币 1 +x:1 +邮市 1 +x:1 +哺乳期 1 +x:1 +花神 1 +x:1 +深层次 1 +x:1 +老道 1 +x:1 +侵吞 1 +x:1 +税稽 1 +x:1 +格拉夫屋 1 +x:1 +可可油 1 +x:1 +健身法 1 +x:1 +赔偿法 1 +x:1 +漏风 1 +x:1 +蛐蛐 1 +x:1 +虾子 1 +x:1 +巴陵 1 +x:1 +热天 1 +x:1 +音乐声 1 +x:1 +凝固 1 +x:1 +贿赂案 1 +x:1 +预制 1 +x:1 +苏禄省 1 +x:1 +粮户 1 +x:1 +昏昏沉沉 1 +x:1 +绿化率 1 +x:1 +学究 1 +x:1 +预算法 1 +x:1 +求和 1 +x:1 +命令主义 1 +x:1 +异义 1 +x:1 +交办会 1 +x:1 +富庶 1 +x:1 +南北湖 1 +x:1 +夹道欢迎 1 +x:1 +摊床 1 +x:1 +勘 4 +x:4 +蜗牛 1 +x:1 +新菏 1 +x:1 +随地 1 +x:1 +北运菜 1 +x:1 +珞珈 1 +x:1 +异乡 1 +x:1 +签约国 1 +x:1 +鸭梨 1 +x:1 +雪污 1 +x:1 +顺义镇 1 +x:1 +福海县 1 +x:1 +议局 1 +x:1 +胶着状态 1 +x:1 +黄疸 1 +x:1 +铁脚板 1 +x:1 +乃至 1 +x:1 +工具箱 1 +x:1 +厚厚的 1 +x:1 +科特迪瓦 1 +x:1 +搅拌 1 +x:1 +侧耳 1 +x:1 +诸端 1 +x:1 +输卵管 1 +x:1 +税管 1 +x:1 +占用 1 +x:1 +认识史 1 +x:1 +失掉 1 +x:1 +随国 1 +x:1 +真空泵 1 +x:1 +嗓子眼儿 1 +x:1 +复吸率 1 +x:1 +无人 1 +x:1 +查缉 1 +x:1 +培育 1 +x:1 +众乡亲 1 +x:1 +颁证会 1 +x:1 +推进 1 +x:1 +喜马拉雅 1 +x:1 +金湖 1 +x:1 +广东音乐 1 +x:1 +祁连山 1 +x:1 +军婚 1 +x:1 +桓台县 1 +x:1 +有伤风化 1 +x:1 +七上八下 1 +x:1 +词意 1 +x:1 +株 181 +x:181 +科普特 1 +x:1 +拳头 1 +x:1 +舌尖 1 +x:1 +新航 1 +x:1 +珍珠港 1 +x:1 +重足而立 1 +x:1 +经营 1 +x:1 +晚秋 1 +x:1 +抛光剂 1 +x:1 +老醋 1 +x:1 +同系物 1 +x:1 +拳套 1 +x:1 +滔天罪恶 1 +x:1 +编辑部 1 +x:1 +肖家洼 1 +x:1 +无价 1 +x:1 +骒马 1 +x:1 +大有裨益 1 +x:1 +台上村 1 +x:1 +分子力 1 +x:1 +参军 1 +x:1 +预埋件 1 +x:1 +珍奇 1 +x:1 +推辞 1 +x:1 +信息流 1 +x:1 +求售 1 +x:1 +无从 1 +x:1 +可重构性 1 +x:1 +寄放 1 +x:1 +嘉义镇 1 +x:1 +游船 1 +x:1 +咕噜噜 1 +x:1 +贝宁 1 +x:1 +公正无私 1 +x:1 +百刻图 1 +x:1 +计划科 1 +x:1 +畅想曲 1 +x:1 +扫清 1 +x:1 +教师节 1 +x:1 +评论部 1 +x:1 +餐点 1 +x:1 +缆车道 1 +x:1 +美梦 1 +x:1 +海阔天空 1 +x:1 +茶麸 1 +x:1 +黄瓜 1 +x:1 +老酒 1 +x:1 +无为 1 +x:1 +凡此等等 1 +x:1 +醉心 1 +x:1 +推车 1 +x:1 +防龋 1 +x:1 +跳动声 1 +x:1 +校友会 1 +x:1 +枯竭 1 +x:1 +货 187 +x:187 +胯骨 1 +x:1 +延性 1 +x:1 +无不 1 +x:1 +砸锅卖铁 1 +x:1 +无业 1 +x:1 +装假 1 +x:1 +文明史 1 +x:1 +伦理 1 +x:1 +花砖 1 +x:1 +远非 1 +x:1 +二十大 1 +x:1 +责任书 1 +x:1 +亡灵 1 +x:1 +农业社 1 +x:1 +张三营镇 1 +x:1 +无限小 1 +x:1 +拟人化 1 +x:1 +侧刀儿 1 +x:1 +蛛丝马迹 1 +x:1 +围堵 1 +x:1 +苗猪 1 +x:1 +围堰 1 +x:1 +向斜层 1 +x:1 +阳谷县 1 +x:1 +志同道合 1 +x:1 +围堤 1 +x:1 +讼词 1 +x:1 +摸得着 1 +x:1 +讼诉 1 +x:1 +禁 85 +x:85 +尸身 1 +x:1 +远射 1 +x:1 +美术 1 +x:1 +围城 1 +x:1 +合同书 1 +x:1 +字儿 1 +x:1 +压缩饼干 1 +x:1 +迂拙 1 +x:1 +求婚 1 +x:1 +田林 1 +x:1 +花石 1 +x:1 +勾股定理 1 +x:1 +坑骗 1 +x:1 +心脏病学 1 +x:1 +掀动 1 +x:1 +亡羊 1 +x:1 +电报局 1 +x:1 +肿瘤学 1 +x:1 +粮油 1 +x:1 +美军 1 +x:1 +巴基斯坦 1 +x:1 +虎林市 1 +x:1 +搅混 1 +x:1 +参建 1 +x:1 +信息战 1 +x:1 +改装厂 1 +x:1 +铝土 1 +x:1 +从江 1 +x:1 +东太河村 1 +x:1 +一个劲 1 +x:1 +指挥刀 1 +x:1 +年下 1 +x:1 +撂荒 1 +x:1 +满腔热情 1 +x:1 +糸满市 1 +x:1 +铝圈 1 +x:1 +佤 1 +x:1 +取信于民 1 +x:1 +黄柿乡 1 +x:1 +勘测院 1 +x:1 +长清镇 1 +x:1 +公倍数 1 +x:1 +年中 1 +x:1 +韵 35 +x:35 +动之以情 1 +x:1 +支流 1 +x:1 +含苞欲放 1 +x:1 +围垦 1 +x:1 +止跌 1 +x:1 +武进市 1 +x:1 +稳产 1 +x:1 +伸脚展腰 1 +x:1 +丹田村 1 +x:1 +奥兰多 1 +x:1 +尘埃落定 1 +x:1 +绿葱坡镇 1 +x:1 +曼妙无比 1 +x:1 +围坐 1 +x:1 +没精打采 1 +x:1 +试播 1 +x:1 +搓 21 +x:21 +豺狼虎豹 1 +x:1 +临阵脱逃 1 +x:1 +热土 1 +x:1 +饮料业 1 +x:1 +卷扬机 1 +x:1 +残砖碎瓦 1 +x:1 +俯身 1 +x:1 +屏锦镇 1 +x:1 +甜叶菊 1 +x:1 +老鹰 1 +x:1 +美术课 1 +x:1 +词源 1 +x:1 +学理 1 +x:1 +大沙田 1 +x:1 +算总账 1 +x:1 +联户办 1 +x:1 +部标 1 +x:1 +增值税 1 +x:1 +星条旗 1 +x:1 +震撼人心 1 +x:1 +母体 1 +x:1 +盖里 1 +x:1 +皴染 1 +x:1 +疏爽 1 +x:1 +年事 1 +x:1 +遵纪守法 1 +x:1 +费劲 1 +x:1 +臻 19 +x:19 +案值数 1 +x:1 +最低点 1 +x:1 +围场 1 +x:1 +执 39 +x:39 +老鸦 1 +x:1 +老鸨 1 +x:1 +红3军团 1 +x:1 +祁连县 1 +x:1 +花眼 1 +x:1 +费力 1 +x:1 +压轴戏 1 +x:1 +老鸹 1 +x:1 +年产 1 +x:1 +摩顶放踵 1 +x:1 +摭闻 1 +x:1 +花盒 1 +x:1 +邮册 1 +x:1 +紫石英 1 +x:1 +花盘 1 +x:1 +脐 1 +x:1 +葛巾羽扇 1 +x:1 +宗 94 +x:94 +花盆 1 +x:1 +呆坏帐 1 +x:1 +求学 1 +x:1 +错填率 1 +x:1 +驶近 1 +x:1 +想得开 1 +x:1 +及时 1 +x:1 +胃窦 1 +x:1 +围困 1 +x:1 +科普类 1 +x:1 +松滋 1 +x:1 +及早 1 +x:1 +几内亚 1 +x:1 +拳坛 1 +x:1 +三核一派 1 +x:1 +适可而止 1 +x:1 +年会 1 +x:1 +老龄 1 +x:1 +世界市场 1 +x:1 +美景 1 +x:1 +拦腰 1 +x:1 +坏书 1 +x:1 +入夏 1 +x:1 +天球瓶 1 +x:1 +洛铜 1 +x:1 +禁行线 1 +x:1 +平衡点 1 +x:1 +猪头肉 1 +x:1 +糙 1 +x:1 +望月村 1 +x:1 +大年三十 1 +x:1 +一干二净 1 +x:1 +平和县 1 +x:1 +入主出奴 1 +x:1 +摊儿 1 +x:1 +稳便 1 +x:1 +红白喜事 1 +x:1 +万不得已 1 +x:1 +猎装 1 +x:1 +眉骨 1 +x:1 +老牌子 1 +x:1 +发烧圈 1 +x:1 +均衡性 1 +x:1 +顾此失彼 1 +x:1 +重义轻利 1 +x:1 +绘图卡 1 +x:1 +验货 1 +x:1 +年迈 1 +x:1 +伤胃毁身 1 +x:1 +漏 84 +x:84 +游艇 1 +x:1 +肉用型 1 +x:1 +智齿 1 +x:1 +稳住 1 +x:1 +坏人 1 +x:1 +挡风遮雨 1 +x:1 +侧身 1 +x:1 +新貌 1 +x:1 +狼狈不堪 1 +x:1 +纱橱 1 +x:1 +指挥台 1 +x:1 +坏事 1 +x:1 +跺跺脚 1 +x:1 +铁铺 1 +x:1 +花白 1 +x:1 +粉黄 1 +x:1 +红眼病 1 +x:1 +倒退 1 +x:1 +晚眺 1 +x:1 +黄竹 1 +x:1 +春意盎然 1 +x:1 +趸 5 +x:5 +检测员 1 +x:1 +人 16955 +x:16955 +油辣 1 +x:1 +拨弄 1 +x:1 +专递费 1 +x:1 +五龙潭 1 +x:1 +一笔勾销 1 +x:1 +高山流水 1 +x:1 +核算点 1 +x:1 +推脱 1 +x:1 +邮兜 1 +x:1 +前宋村 1 +x:1 +掩盖体 1 +x:1 +誊黄 1 +x:1 +外部性 1 +x:1 +商队 1 +x:1 +济困扶危 1 +x:1 +老鼠 1 +x:1 +浣 4 +x:4 +淤浊 1 +x:1 +无限制 1 +x:1 +藏版 1 +x:1 +金城川 1 +x:1 +灰鲸 1 +x:1 +链子崖 1 +x:1 +死灰复燃 1 +x:1 +遥无期 1 +x:1 +正选 1 +x:1 +儿女情长 1 +x:1 +阴森可怖 1 +x:1 +富农 1 +x:1 +木鱼石 1 +x:1 +信息性 1 +x:1 +丝栗 1 +x:1 +文明村 1 +x:1 +科普网 1 +x:1 +合同费 1 +x:1 +宝应 1 +x:1 +芳村 1 +x:1 +墨迹未干 1 +x:1 +雨中曲 1 +x:1 +摊前 1 +x:1 +斑状 1 +x:1 +支付 1 +x:1 +粮源 1 +x:1 +利落 1 +x:1 +寓刚于柔 1 +x:1 +试映 1 +x:1 +紫菜 1 +x:1 +还债 1 +x:1 +警士 1 +x:1 +远大 1 +x:1 +驻足不前 1 +x:1 +邮务 1 +x:1 +儿童剧 1 +x:1 +雪亮 1 +x:1 +编译语言 1 +x:1 +栓剂 1 +x:1 +血气 1 +x:1 +总人口 1 +x:1 +税目 1 +x:1 +乌迪内市 1 +x:1 +扫描 1 +x:1 +涉世 1 +x:1 +秋毫之末 1 +x:1 +测定 1 +x:1 +税盲 1 +x:1 +触目惊心 1 +x:1 +粮官 1 +x:1 +词汇 1 +x:1 +躺 108 +x:108 +现代型 1 +x:1 +一往无前 1 +x:1 +供给制 1 +x:1 +恰似 1 +x:1 +大黑汀 1 +x:1 +炒作 1 +x:1 +灰鼠 1 +x:1 +循环不断 1 +x:1 +新车 1 +x:1 +停车率降 1 +x:1 +黄种 1 +x:1 +名符其实 1 +x:1 +磕头虫 1 +x:1 +紫草 1 +x:1 +淤渣 1 +x:1 +美方 1 +x:1 +砍头疮 1 +x:1 +赢洲 1 +x:1 +沤 2 +x:2 +斩钉截铁 1 +x:1 +支书 1 +x:1 +百日咳 1 +x:1 +美文 1 +x:1 +巴马 1 +x:1 +电 7381 +x:7381 +花畦 1 +x:1 +华南虎 1 +x:1 +一点 1 +x:1 +虾场 1 +x:1 +新近 1 +x:1 +二硫化碳 1 +x:1 +一刻钟 1 +x:1 +软塌塌 1 +x:1 +分子式 1 +x:1 +知工科 1 +x:1 +花生 1 +x:1 +浅黄色 1 +x:1 +滩堆乡 1 +x:1 +疏瀹 1 +x:1 +增创 1 +x:1 +协议会 1 +x:1 +花甲 1 +x:1 +珍品 1 +x:1 +韬 17 +x:17 +意谓 1 +x:1 +胡桃肉 1 +x:1 +爆冷 1 +x:1 +余家湖 1 +x:1 +人定胜天 1 +x:1 +变速器 1 +x:1 +西南角 1 +x:1 +词法 1 +x:1 +砍头痈 1 +x:1 +环卫处 1 +x:1 +事必躬亲 1 +x:1 +一展无垠 1 +x:1 +寒舍 1 +x:1 +童装厂 1 +x:1 +讷河市 1 +x:1 +暴君 1 +x:1 +沙蚕科 1 +x:1 +热和 1 +x:1 +角角落落 1 +x:1 +军管组 1 +x:1 +岙山卫镇 1 +x:1 +短袖 1 +x:1 +用工者 1 +x:1 +弥渡县 1 +x:1 +灰鹅 1 +x:1 +得逞 1 +x:1 +斯潘塞 1 +x:1 +耳目一新 1 +x:1 +花瓶 1 +x:1 +参差 1 +x:1 +西麓 1 +x:1 +文句 1 +x:1 +扶风 1 +x:1 +青春型 1 +x:1 +花瓣 1 +x:1 +俯贻 1 +x:1 +鄙俗 1 +x:1 +报刊业 1 +x:1 +塑管厂 1 +x:1 +指出 1 +x:1 +统一部 1 +x:1 +振幅 1 +x:1 +数来宝 1 +x:1 +订货 1 +x:1 +得遂 1 +x:1 +性生活 1 +x:1 +蛋白酶 1 +x:1 +订购 1 +x:1 +黄砂 1 +x:1 +规定者 1 +x:1 +书香气 1 +x:1 +邮发 1 +x:1 +油车 1 +x:1 +年年月月 1 +x:1 +紫芝 1 +x:1 +恍如隔世 1 +x:1 +因噎废食 1 +x:1 +环保法 1 +x:1 +跌价 1 +x:1 +枯瘦 1 +x:1 +麦糠 1 +x:1 +铜都 1 +x:1 +构图 1 +x:1 +苛刻 1 +x:1 +坦佩雷市 1 +x:1 +成气候 1 +x:1 +吨谷镇 1 +x:1 +灰鸭 1 +x:1 +千克 1 +x:1 +柳荫街 1 +x:1 +与生俱来 1 +x:1 +检测器 1 +x:1 +发钞量 1 +x:1 +输油 1 +x:1 +承包人 1 +x:1 +晚生 1 +x:1 +黑鹰队 1 +x:1 +灰黄 1 +x:1 +日喀则 1 +x:1 +跻身 1 +x:1 +牡丹卡 1 +x:1 +洛阳 1 +x:1 +东源县 1 +x:1 +民主主义 1 +x:1 +农业界 1 +x:1 +推荐 1 +x:1 +骁将 1 +x:1 +试析 1 +x:1 +户口簿 1 +x:1 +千斤 1 +x:1 +支使 1 +x:1 +紫色 1 +x:1 +配件厂 1 +x:1 +魁夷 1 +x:1 +黄磷 1 +x:1 +侃山 1 +x:1 +奶制品 1 +x:1 +亚布力 1 +x:1 +嗅觉 1 +x:1 +大总统 1 +x:1 +陉 1 +x:1 +内勤 1 +x:1 +花球 1 +x:1 +抽水站 1 +x:1 +响声 1 +x:1 +自叹弗如 1 +x:1 +飞短流长 1 +x:1 +富县 1 +x:1 +野青煤 1 +x:1 +承包价 1 +x:1 +追根问底 1 +x:1 +价格表 1 +x:1 +少儿馆 1 +x:1 +措辞 1 +x:1 +贱义重利 1 +x:1 +磨损 1 +x:1 +扫扫 1 +x:1 +组拼 1 +x:1 +痴 14 +x:14 +旗舰 1 +x:1 +热呼 1 +x:1 +荻 17 +x:17 +绿化线 1 +x:1 +疏目 1 +x:1 +看朱成碧 1 +x:1 +培训 1 +x:1 +热压 1 +x:1 +十二圩镇 1 +x:1 +斑 5 +x:5 +店小二 1 +x:1 +自选 1 +x:1 +起飞线 1 +x:1 +曲水县 1 +x:1 +儿童周 1 +x:1 +蹈常袭故 1 +x:1 +售电量 1 +x:1 +章丘市 1 +x:1 +疲疲沓沓 1 +x:1 +兼而有之 1 +x:1 +眼力 1 +x:1 +随州 1 +x:1 +丹佛 1 +x:1 +如数家珍 1 +x:1 +迂曲 1 +x:1 +段委 1 +x:1 +脾 12 +x:12 +天鹅绒 1 +x:1 +以物抵债 1 +x:1 +寅 3 +x:3 +诺丁汉 1 +x:1 +邮品 1 +x:1 +赵北村 1 +x:1 +富含 1 +x:1 +莎车县 1 +x:1 +倒闭 1 +x:1 +预备费 1 +x:1 +磨擦 1 +x:1 +加班费 1 +x:1 +响彻 1 +x:1 +关区 1 +x:1 +铜韵 1 +x:1 +飞行日 1 +x:1 +轮椅车 1 +x:1 +历尽沧桑 1 +x:1 +逞暴 1 +x:1 +罩袖 1 +x:1 +呵呵 1 +x:1 +砂洗厂 1 +x:1 +工业部 1 +x:1 +洋饮料 1 +x:1 +辉映 1 +x:1 +拉家常 1 +x:1 +入殓 1 +x:1 +还原 1 +x:1 +有余 1 +x:1 +非党人士 1 +x:1 +历险记 1 +x:1 +铁十八局 1 +x:1 +埂 1 +x:1 +侧记 1 +x:1 +繁殖 1 +x:1 +跌交 1 +x:1 +老祖公 1 +x:1 +罩衫 1 +x:1 +阵风 1 +x:1 +槭树 1 +x:1 +太庙乡 1 +x:1 +罩衣 1 +x:1 +富有 1 +x:1 +占线 1 +x:1 +瓜廖尔市 1 +x:1 +巴鱼 1 +x:1 +枯燥 1 +x:1 +五里雾 1 +x:1 +西餐 1 +x:1 +畜圈 1 +x:1 +密不透风 1 +x:1 +热区 1 +x:1 +汗牛充栋 1 +x:1 +黄羊 1 +x:1 +添漫梁乡 1 +x:1 +杯水车薪 1 +x:1 +整薯坑 1 +x:1 +试想 1 +x:1 +暴发 1 +x:1 +邮员 1 +x:1 +广学博识 1 +x:1 +贯通 1 +x:1 +铝厂 1 +x:1 +炯炯 1 +x:1 +电器厂 1 +x:1 +验血 1 +x:1 +二十分 1 +x:1 +制备 1 +x:1 +安营扎寨 1 +x:1 +新解 1 +x:1 +鳄 1 +x:1 +芝加哥 1 +x:1 +一直 1 +x:1 +一等舱 1 +x:1 +眼前 1 +x:1 +墨笔画 1 +x:1 +市 2154 +x:2154 +老当益壮 1 +x:1 +舞后 1 +x:1 +任家村 1 +x:1 +赔偿权 1 +x:1 +苗种 1 +x:1 +书报刊 1 +x:1 +赌棍 1 +x:1 +向阳村 1 +x:1 +投 317 +x:317 +柳子戏 1 +x:1 +国防法 1 +x:1 +车马盈门 1 +x:1 +供电局 1 +x:1 +欧共体 1 +x:1 +信息机 1 +x:1 +热力 1 +x:1 +星火计划 1 +x:1 +包月制 1 +x:1 +四围 1 +x:1 +磨料 1 +x:1 +灰顶 1 +x:1 +重头戏 1 +x:1 +股利 1 +x:1 +平谷县 1 +x:1 +暴利 1 +x:1 +记账 1 +x:1 +不好过 1 +x:1 +一眼 1 +x:1 +敬启 1 +x:1 +有些 1 +x:1 +铜雕 1 +x:1 +东门礁 1 +x:1 +求异 1 +x:1 +品位 1 +x:1 +校纪录 1 +x:1 +预算权 1 +x:1 +陡河 1 +x:1 +藏相 1 +x:1 +中塘镇 1 +x:1 +果皮箱 1 +x:1 +宇宙论 1 +x:1 +饥劳 1 +x:1 +西飞 1 +x:1 +岩下山 1 +x:1 +铝制 1 +x:1 +聊以自慰 1 +x:1 +海底捞针 1 +x:1 +锐减 1 +x:1 +白巴乡 1 +x:1 +水轮船 1 +x:1 +西风 1 +x:1 +人命关天 1 +x:1 +孰能无情 1 +x:1 +丹东 1 +x:1 +杜鹃花 1 +x:1 +一睹 1 +x:1 +盛极而衰 1 +x:1 +热切 1 +x:1 +出游者 1 +x:1 +锦葵 1 +x:1 +层峦叠嶂 1 +x:1 +冈 1 +x:1 +面料 1 +x:1 +腊黄 1 +x:1 +士林 1 +x:1 +接壤区 1 +x:1 +船老大 1 +x:1 +一老一少 1 +x:1 +语感 1 +x:1 +主管道 1 +x:1 +围剿 1 +x:1 +费城 1 +x:1 +憨 7 +x:7 +一瞬 1 +x:1 +辛辣 1 +x:1 +响应 1 +x:1 +载文 1 +x:1 +发烧友 1 +x:1 +统一院 1 +x:1 +检疫费 1 +x:1 +五色塔 1 +x:1 +果皮筒 1 +x:1 +灰颓 1 +x:1 +单项 1 +x:1 +鞍钢 1 +x:1 +储户 1 +x:1 +邮商 1 +x:1 +古建筑 1 +x:1 +猎豹 1 +x:1 +求得 1 +x:1 +灰领 1 +x:1 +新装 1 +x:1 +逸乐 1 +x:1 +大至暴雨 1 +x:1 +市场部 1 +x:1 +铜陵 1 +x:1 +无因性 1 +x:1 +棚代客 1 +x:1 +岁岁年年 1 +x:1 +稼穑 1 +x:1 +拳台 1 +x:1 +商南县 1 +x:1 +白公馆 1 +x:1 +笑容可掬 1 +x:1 +佳音 1 +x:1 +对内搞活 1 +x:1 +裤衩 1 +x:1 +稼禾 1 +x:1 +联优化劣 1 +x:1 +规则 1 +x:1 +无政府 1 +x:1 +巴黎 1 +x:1 +干巴巴 1 +x:1 +环卫工 1 +x:1 +编 143 +x:143 +办公费 1 +x:1 +工副业 1 +x:1 +词根 1 +x:1 +新疆厅 1 +x:1 +抄袭 1 +x:1 +中药费 1 +x:1 +脊椎动物 1 +x:1 +美意 1 +x:1 +莩 1 +x:1 +新低 1 +x:1 +寻踪游 1 +x:1 +需者 1 +x:1 +年届花甲 1 +x:1 +极光 1 +x:1 +晚点 1 +x:1 +但书 1 +x:1 +美感 1 +x:1 +载明 1 +x:1 +聚焦点 1 +x:1 +质朴无华 1 +x:1 +朱墨 1 +x:1 +八分音符 1 +x:1 +抗日史 1 +x:1 +野蔷薇 1 +x:1 +旅顺口区 1 +x:1 +空座位 1 +x:1 +征战 1 +x:1 +奚 20 +x:20 +一减一增 1 +x:1 +纺织业 1 +x:1 +云蒸霞蔚 1 +x:1 +娓娓道来 1 +x:1 +茵茵 1 +x:1 +文卫 1 +x:1 +琵琶 1 +x:1 +硬通货币 1 +x:1 +井岗霉素 1 +x:1 +令人 1 +x:1 +暴腌肉 1 +x:1 +亏本儿 1 +x:1 +铜门 1 +x:1 +公路局 1 +x:1 +磴口县 1 +x:1 +反躬自问 1 +x:1 +赔礼 1 +x:1 +热门 1 +x:1 +铜锅 1 +x:1 +藏画 1 +x:1 +铜锁 1 +x:1 +大发慈悲 1 +x:1 +富国 1 +x:1 +未央路 1 +x:1 +天水围 1 +x:1 +铜锈 1 +x:1 +棘爪 1 +x:1 +精业 1 +x:1 +分子学 1 +x:1 +大萝卜 1 +x:1 +新论 1 +x:1 +儿童团 1 +x:1 +铜锤 1 +x:1 +铜锣 1 +x:1 +行吟者 1 +x:1 +埋入 1 +x:1 +倒霉 1 +x:1 +新训 1 +x:1 +扩散式 1 +x:1 +新诗 1 +x:1 +双人滑 1 +x:1 +催人奋进 1 +x:1 +铜镜 1 +x:1 +教师证 1 +x:1 +招生 1 +x:1 +贮点红 1 +x:1 +西南路 1 +x:1 +热恋 1 +x:1 +糊弄 1 +x:1 +吸入 1 +x:1 +新词 1 +x:1 +烤面包器 1 +x:1 +经济法制 1 +x:1 +新说 1 +x:1 +疏理 1 +x:1 +西魏 1 +x:1 +精义 1 +x:1 +假以 1 +x:1 +得闲 1 +x:1 +酌量 1 +x:1 +招用 1 +x:1 +九十七中 1 +x:1 +聿 10 +x:10 +罚球 1 +x:1 +席地 1 +x:1 +精神不振 1 +x:1 +铜钟 1 +x:1 +花烛 1 +x:1 +澳众院 1 +x:1 +浮动价 1 +x:1 +彪炳 1 +x:1 +防震 1 +x:1 +预定 1 +x:1 +主营业务 1 +x:1 +济州岛 1 +x:1 +工兵团 1 +x:1 +钝 3 +x:3 +京剧迷 1 +x:1 +戏剧节 1 +x:1 +保质期 1 +x:1 +谢集 1 +x:1 +宇宙观 1 +x:1 +铜钱 1 +x:1 +肿块 1 +x:1 +名词委 1 +x:1 +怪 81 +x:81 +单骑 1 +x:1 +腹背受敌 1 +x:1 +税率 1 +x:1 +净化师 1 +x:1 +继母 1 +x:1 +城管办 1 +x:1 +狼烟四起 1 +x:1 +喊 156 +x:156 +红道 1 +x:1 +士敏 1 +x:1 +觏 1 +x:1 +铜铙 1 +x:1 +决策论 1 +x:1 +铜铃 1 +x:1 +悲观主义 1 +x:1 +文明戏 1 +x:1 +满 725 +x:725 +敢情 1 +x:1 +耐火黏土 1 +x:1 +桥梁史 1 +x:1 +文明户 1 +x:1 +定音鼓 1 +x:1 +假使 1 +x:1 +交界处 1 +x:1 +古竹村 1 +x:1 +偶函数 1 +x:1 +右 240 +x:240 +睡醒 1 +x:1 +普天之下 1 +x:1 +皇粮 1 +x:1 +葬礼 1 +x:1 +花炮 1 +x:1 +畦田 1 +x:1 +往 678 +x:678 +邓 2186 +x:2186 +广土众民 1 +x:1 +眼儿 1 +x:1 +考证 1 +x:1 +密码箱 1 +x:1 +街巷战 1 +x:1 +生死线 1 +x:1 +考评 1 +x:1 +计算中心 1 +x:1 +血本 1 +x:1 +悠闲自在 1 +x:1 +毛泽东 1 +x:1 +报样 1 +x:1 +考试 1 +x:1 +试探 1 +x:1 +驴皮胶 1 +x:1 +反正 1 +x:1 +迷走神经 1 +x:1 +一大溜 1 +x:1 +环卫局 1 +x:1 +倒阁 1 +x:1 +直上云霄 1 +x:1 +柜面 1 +x:1 +笔杆子 1 +x:1 +花灯 1 +x:1 +油滑 1 +x:1 +等比数列 1 +x:1 +家常事 1 +x:1 +议会上院 1 +x:1 +随带 1 +x:1 +入校 1 +x:1 +命相 1 +x:1 +鄙视 1 +x:1 +供给型 1 +x:1 +擒 7 +x:7 +釜底抽薪 1 +x:1 +猛犸象 1 +x:1 +俯角 1 +x:1 +拳击 1 +x:1 +镜框 1 +x:1 +黄骨髓 1 +x:1 +次要方 1 +x:1 +突尼斯队 1 +x:1 +管辖区 1 +x:1 +刨花板 1 +x:1 +构剧 1 +x:1 +金花菜 1 +x:1 +参天 1 +x:1 +五星村 1 +x:1 +眼光 1 +x:1 +春夏季 1 +x:1 +分子病 1 +x:1 +斑驳 1 +x:1 +黄骠马 1 +x:1 +精炼 1 +x:1 +梅仙镇 1 +x:1 +爱财如命 1 +x:1 +滞缓 1 +x:1 +实践观 1 +x:1 +杀人越货 1 +x:1 +上演税 1 +x:1 +老屯 1 +x:1 +承包田 1 +x:1 +紧身 1 +x:1 +斑马 1 +x:1 +老山 1 +x:1 +美式 1 +x:1 +钟亭 1 +x:1 +缴械 1 +x:1 +七彩花 1 +x:1 +个量 1 +x:1 +滴鼻剂 1 +x:1 +计划书 1 +x:1 +磨嘴皮 1 +x:1 +环保型 1 +x:1 +试射 1 +x:1 +大梦初醒 1 +x:1 +出门在外 1 +x:1 +摊档 1 +x:1 +征兆 1 +x:1 +限于 1 +x:1 +本溪籍 1 +x:1 +兽医院 1 +x:1 +银币 1 +x:1 +凝思 1 +x:1 +呼吸相通 1 +x:1 +繁重 1 +x:1 +品牌 1 +x:1 +传入期 1 +x:1 +人迹 1 +x:1 +国防军 1 +x:1 +征尘 1 +x:1 +报刊界 1 +x:1 +宣传费 1 +x:1 +无私 1 +x:1 +相随 1 +x:1 +三线 1 +x:1 +史学系 1 +x:1 +叠现 1 +x:1 +受骗者 1 +x:1 +资本金 1 +x:1 +茶道 1 +x:1 +作罢 1 +x:1 +云量 1 +x:1 +任其自流 1 +x:1 +锥子 1 +x:1 +三级 1 +x:1 +就近 1 +x:1 +花体 1 +x:1 +摊棚 1 +x:1 +重回 1 +x:1 +基本词 1 +x:1 +市政处 1 +x:1 +觉醒 1 +x:1 +安全面 1 +x:1 +忠厚老实 1 +x:1 +藏家 1 +x:1 +作美 1 +x:1 +签名簿 1 +x:1 +无礼 1 +x:1 +美德 1 +x:1 +代议制 1 +x:1 +嫁接法 1 +x:1 +酒液 1 +x:1 +计划价 1 +x:1 +伊夫岛 1 +x:1 +沁园春 1 +x:1 +秭归城 1 +x:1 +豌豆角 1 +x:1 +对外贸易 1 +x:1 +闪烁其辞 1 +x:1 +草茉莉 1 +x:1 +内核 1 +x:1 +见证 1 +x:1 +回眸 1 +x:1 +见识 1 +x:1 +利诱 1 +x:1 +盖碗茶 1 +x:1 +花会 1 +x:1 +精灵 1 +x:1 +白三叶 1 +x:1 +账款 1 +x:1 +满目生机 1 +x:1 +入场 1 +x:1 +玉环市 1 +x:1 +顺耳 1 +x:1 +随意 1 +x:1 +话梅 1 +x:1 +妙手回春 1 +x:1 +过载 1 +x:1 +热潮 1 +x:1 +弱势 1 +x:1 +随感 1 +x:1 +入土 1 +x:1 +敢当 1 +x:1 +天地会 1 +x:1 +丰产沟 1 +x:1 +经社文 1 +x:1 +景山 1 +x:1 +铜元 1 +x:1 +英语系 1 +x:1 +帮丘河 1 +x:1 +文明展 1 +x:1 +人公里 1 +x:1 +避讳 1 +x:1 +共产党员 1 +x:1 +入团 1 +x:1 +扫墓 1 +x:1 +继嗣 1 +x:1 +热源 1 +x:1 +避让 1 +x:1 +结束符 1 +x:1 +寄卖 1 +x:1 +入围 1 +x:1 +文具盒 1 +x:1 +随想 1 +x:1 +广东省 1 +x:1 +文明山 1 +x:1 +花价 1 +x:1 +柏里村 1 +x:1 +绑匪 1 +x:1 +老岩岗 1 +x:1 +千张 1 +x:1 +无碍 1 +x:1 +百岁堂 1 +x:1 +唐人 1 +x:1 +轴衬 1 +x:1 +美帝 1 +x:1 +检测法 1 +x:1 +有则改之 1 +x:1 +美中不足 1 +x:1 +搅和 1 +x:1 +多边形 1 +x:1 +澜沧江 1 +x:1 +展读 1 +x:1 +视若无人 1 +x:1 +展诵 1 +x:1 +鸽笼 1 +x:1 +初生之犊 1 +x:1 +住宅楼 1 +x:1 +控制程序 1 +x:1 +晚自习 1 +x:1 +坡耕地 1 +x:1 +士子 1 +x:1 +暮色四合 1 +x:1 +费款 1 +x:1 +五台县 1 +x:1 +石炭系 1 +x:1 +紧迫 1 +x:1 +子粒 1 +x:1 +春华秋实 1 +x:1 +个体性 1 +x:1 +瓜田李下 1 +x:1 +大恩大德 1 +x:1 +无所不在 1 +x:1 +豫园 1 +x:1 +聊复尔耳 1 +x:1 +抽丝 1 +x:1 +热固性 1 +x:1 +灼圃 1 +x:1 +展评 1 +x:1 +投递处 1 +x:1 +稳中求进 1 +x:1 +护轨 1 +x:1 +印字店 1 +x:1 +三网 1 +x:1 +拍照 1 +x:1 +葛镇 1 +x:1 +电路图 1 +x:1 +袒护 1 +x:1 +胆魄 1 +x:1 +晚会 1 +x:1 +丝厂 1 +x:1 +虾池 1 +x:1 +笋竹 1 +x:1 +士官 1 +x:1 +篇制 1 +x:1 +书法展 1 +x:1 +硫化氢 1 +x:1 +传呼台 1 +x:1 +从犯 1 +x:1 +压轴子 1 +x:1 +六龄童 1 +x:1 +求援 1 +x:1 +洗茶 1 +x:1 +铁蒺藜 1 +x:1 +母夜叉 1 +x:1 +国民政府 1 +x:1 +开足马力 1 +x:1 +文明岗 1 +x:1 +争妍斗丽 1 +x:1 +天旋地转 1 +x:1 +花丛 1 +x:1 +花业 1 +x:1 +花丝 1 +x:1 +粮商 1 +x:1 +生存权 1 +x:1 +黄赌毒 1 +x:1 +试工 1 +x:1 +饥渴 1 +x:1 +精煤 1 +x:1 +正定镇 1 +x:1 +研讨会 1 +x:1 +天地上 1 +x:1 +令人瞩目 1 +x:1 +面目可憎 1 +x:1 +站区 1 +x:1 +顺脚 1 +x:1 +沈阳 1 +x:1 +超规定 1 +x:1 +盛誉 1 +x:1 +杂交米 1 +x:1 +学人 1 +x:1 +句容市 1 +x:1 +议会宫 1 +x:1 +清政府 1 +x:1 +年赛 1 +x:1 +洗肠 1 +x:1 +热涨 1 +x:1 +条鳎 1 +x:1 +新业 1 +x:1 +亳 1 +x:1 +国防司 1 +x:1 +翘尾 1 +x:1 +打谱 1 +x:1 +栏网 1 +x:1 +胸襟 1 +x:1 +没有规矩 1 +x:1 +玉环岛 1 +x:1 +凝成 1 +x:1 +最次品 1 +x:1 +过堂风 1 +x:1 +诨名 1 +x:1 +假牙 1 +x:1 +新宁县 1 +x:1 +换 548 +x:548 +眼波 1 +x:1 +自查自纠 1 +x:1 +× 50 +x:50 +排遣 1 +x:1 +卫国干城 1 +x:1 +一点一滴 1 +x:1 +眼泪 1 +x:1 +国家栋梁 1 +x:1 +皇姑井村 1 +x:1 +整改率 1 +x:1 +不善言辞 1 +x:1 +昨儿个 1 +x:1 +异端 1 +x:1 +粮囤 1 +x:1 +储油构造 1 +x:1 +实践论 1 +x:1 +民意测验 1 +x:1 +深谋远虑 1 +x:1 +过路 1 +x:1 +更胜一筹 1 +x:1 +求情 1 +x:1 +人质 1 +x:1 +马丁炉 1 +x:1 +千岁 1 +x:1 +去留 1 +x:1 +分指数 1 +x:1 +坏疽 1 +x:1 +衰翁 1 +x:1 +盯 86 +x:86 +游览区 1 +x:1 +囊中之物 1 +x:1 +软绵 1 +x:1 +三类 1 +x:1 +练习赛 1 +x:1 +征集表 1 +x:1 +诸位 1 +x:1 +官僚主义 1 +x:1 +零枝碎叶 1 +x:1 +莱芜市 1 +x:1 +营溪乡 1 +x:1 +过账 1 +x:1 +暴涨 1 +x:1 +诸体 1 +x:1 +部分 1 +x:1 +海狮队 1 +x:1 +东港镇 1 +x:1 +见见 1 +x:1 +热流 1 +x:1 +蓄 23 +x:23 +美差 1 +x:1 +试建 1 +x:1 +挞伐 1 +x:1 +木本水源 1 +x:1 +一个样 1 +x:1 +曼荼罗 1 +x:1 +美工 1 +x:1 +城 584 +x:584 +学习 1 +x:1 +声调 1 +x:1 +火灾区 1 +x:1 +传之久远 1 +x:1 +部副 1 +x:1 +啸傲 1 +x:1 +唐山站 1 +x:1 +萨洛尼卡 1 +x:1 +扮演 1 +x:1 +修理费 1 +x:1 +见解 1 +x:1 +声谱 1 +x:1 +望眼欲穿 1 +x:1 +许昌 1 +x:1 +无羁无束 1 +x:1 +木偶片 1 +x:1 +热浪 1 +x:1 +匿名 1 +x:1 +石子路 1 +x:1 +睹 27 +x:27 +折戟沉沙 1 +x:1 +独步清流 1 +x:1 +新闻部长 1 +x:1 +预算外 1 +x:1 +扭结 1 +x:1 +傍 9 +x:9 +乌鲁瓦提 1 +x:1 +回头是岸 1 +x:1 +预算处 1 +x:1 +鹩哥 1 +x:1 +身份证者 1 +x:1 +收购量 1 +x:1 +装填 1 +x:1 +信息处 1 +x:1 +有损 1 +x:1 +龙南县 1 +x:1 +告申庭 1 +x:1 +河狸 1 +x:1 +在座 1 +x:1 +天下客 1 +x:1 +上层 1 +x:1 +热河 1 +x:1 +景德 1 +x:1 +远客 1 +x:1 +妇代会 1 +x:1 +提线木偶 1 +x:1 +主体性 1 +x:1 +探索 1 +x:1 +向阳处 1 +x:1 +可消化率 1 +x:1 +热泉 1 +x:1 +无端 1 +x:1 +犹然 1 +x:1 +竑 1 +x:1 +福山路 1 +x:1 +内错角 1 +x:1 +非西方 1 +x:1 +电报机 1 +x:1 +三湖 1 +x:1 +丝光 1 +x:1 +逐月 1 +x:1 +定盘星 1 +x:1 +有点 1 +x:1 +诸事 1 +x:1 +播出量 1 +x:1 +崇武镇 1 +x:1 +年画 1 +x:1 +紧跟 1 +x:1 +承包方 1 +x:1 +浙昆 1 +x:1 +热泪 1 +x:1 +士女 1 +x:1 +个体户 1 +x:1 +展览 1 +x:1 +捕风捉影 1 +x:1 +起落架 1 +x:1 +紧贴 1 +x:1 +泥雨 1 +x:1 +教书郎 1 +x:1 +新乐 1 +x:1 +文物点 1 +x:1 +长春沟村 1 +x:1 +热气 1 +x:1 +上下其手 1 +x:1 +写照 1 +x:1 +便携式 1 +x:1 +救济粮 1 +x:1 +通信科 1 +x:1 +敏于 1 +x:1 +湖南队 1 +x:1 +随手 1 +x:1 +深山老林 1 +x:1 +联名信 1 +x:1 +地下茎 1 +x:1 +学会 1 +x:1 +盯梢 1 +x:1 +热水 1 +x:1 +闭门思过 1 +x:1 +参数 1 +x:1 +洗脱 1 +x:1 +鱼儿 1 +x:1 +后视图 1 +x:1 +洗脸 1 +x:1 +石井乡 1 +x:1 +睦邻友好 1 +x:1 +非情节化 1 +x:1 +无穷 1 +x:1 +征得 1 +x:1 +枯井 1 +x:1 +哀辞 1 +x:1 +羊绒 1 +x:1 +热汤 1 +x:1 +租赁本 1 +x:1 +高速档 1 +x:1 +旷野 1 +x:1 +扬鞭 1 +x:1 +无害化 1 +x:1 +哪里 1 +x:1 +赞比亚 1 +x:1 +限制性 1 +x:1 +包心菜 1 +x:1 +饥民 1 +x:1 +学位 1 +x:1 +排释 1 +x:1 +片面性 1 +x:1 +一一 1 +x:1 +林格尔县 1 +x:1 +芯片 1 +x:1 +嘉陵 1 +x:1 +工农差别 1 +x:1 +石油部 1 +x:1 +入口 1 +x:1 +醉汉 1 +x:1 +探究 1 +x:1 +一世 1 +x:1 +合资方 1 +x:1 +槽钢 1 +x:1 +上市量 1 +x:1 +随时 1 +x:1 +姐妹节 1 +x:1 +盗宝 1 +x:1 +探空 1 +x:1 +值不值得 1 +x:1 +卓刀泉 1 +x:1 +一个 1 +x:1 +输液型 1 +x:1 +排队 1 +x:1 +谅解 1 +x:1 +一中 1 +x:1 +主任 1 +x:1 +异样 1 +x:1 +中行 1 +x:1 +> 4 +x:4 +生活版 1 +x:1 +低烧 1 +x:1 +人语 1 +x:1 +作答 1 +x:1 +糊料 1 +x:1 +招供 1 +x:1 +业内 1 +x:1 +日理万机 1 +x:1 +响杨 1 +x:1 +美学 1 +x:1 +锥形 1 +x:1 +排除 1 +x:1 +斑鸠 1 +x:1 +拨拨 1 +x:1 +羞耻 1 +x:1 +洒满 1 +x:1 +声誉 1 +x:1 +排险 1 +x:1 +主光轴 1 +x:1 +疏于 1 +x:1 +播麦 1 +x:1 +句 895 +x:895 +人证 1 +x:1 +首创性 1 +x:1 +生态县 1 +x:1 +自生自灭 1 +x:1 +拨拉 1 +x:1 +支点 1 +x:1 +富民 1 +x:1 +入厕 1 +x:1 +纱垫 1 +x:1 +预想 1 +x:1 +竿 4 +x:4 +迷信风 1 +x:1 +粮倌 1 +x:1 +文明委 1 +x:1 +立面 1 +x:1 +免于一死 1 +x:1 +藏传 1 +x:1 +徽班 1 +x:1 +豫北 1 +x:1 +同志式 1 +x:1 +一些 1 +x:1 +就诊 1 +x:1 +凸字形 1 +x:1 +儿童 1 +x:1 +魁星 1 +x:1 +燃运部 1 +x:1 +利辛 1 +x:1 +福塞特 1 +x:1 +一产 1 +x:1 +欺压 1 +x:1 +鹤庆 1 +x:1 +居家湾村 1 +x:1 +弱国 1 +x:1 +音 76 +x:76 +翘足引领 1 +x:1 +停滞 1 +x:1 +周末版 1 +x:1 +信息库 1 +x:1 +受精率 1 +x:1 +新书 1 +x:1 +扬都 1 +x:1 +泥金 1 +x:1 +活脱 1 +x:1 +排雷 1 +x:1 +售假者 1 +x:1 +雌 11 +x:11 +声言 1 +x:1 +哑童 1 +x:1 +赶时髦 1 +x:1 +火药库 1 +x:1 +魏塘镇 1 +x:1 +参战 1 +x:1 +执迷不悟 1 +x:1 +一代 1 +x:1 +泰州市 1 +x:1 +拨打 1 +x:1 +信息廊 1 +x:1 +品目 1 +x:1 +通信线 1 +x:1 +熙来攘往 1 +x:1 +知之甚少 1 +x:1 +有备无患 1 +x:1 +所部 1 +x:1 +离子束 1 +x:1 +昂 11 +x:11 +仙鹤草 1 +x:1 +腐竹 1 +x:1 +后汉书 1 +x:1 +熙熙 1 +x:1 +辕马 1 +x:1 +环委会 1 +x:1 +深沟墩台 1 +x:1 +粮农 1 +x:1 +藏人 1 +x:1 +柑桔园 1 +x:1 +通信网 1 +x:1 +情之切切 1 +x:1 +喂食 1 +x:1 +长篇大论 1 +x:1 +茶锈 1 +x:1 +疑凶 1 +x:1 +愉快 1 +x:1 +纺织界 1 +x:1 +花式 1 +x:1 +出租车 1 +x:1 +令人起敬 1 +x:1 +蓄能器 1 +x:1 +签证 1 +x:1 +女作家 1 +x:1 +核子反应 1 +x:1 +膀臂 1 +x:1 +南海街 1 +x:1 +明星队 1 +x:1 +无所不包 1 +x:1 +亲兵 1 +x:1 +棉 55 +x:55 +仿效 1 +x:1 +一低 1 +x:1 +屡战屡败 1 +x:1 +车流量 1 +x:1 +士录 1 +x:1 +招事 1 +x:1 +签订 1 +x:1 +传接球 1 +x:1 +留尼旺 1 +x:1 +槽门 1 +x:1 +磨工 1 +x:1 +摊派 1 +x:1 +家喻户晓 1 +x:1 +征战史 1 +x:1 +屯河 1 +x:1 +主从 1 +x:1 +年猪 1 +x:1 +绮丽 1 +x:1 +声讨 1 +x:1 +大脑库 1 +x:1 +声讯 1 +x:1 +听者 1 +x:1 +解剖麻雀 1 +x:1 +掂掂 1 +x:1 +扫射 1 +x:1 +呈贡县 1 +x:1 +阍 1 +x:1 +车架厂 1 +x:1 +三等 1 +x:1 +预感 1 +x:1 +承包点 1 +x:1 +帽盔儿 1 +x:1 +寻踪者 1 +x:1 +总行 1 +x:1 +众口一辞 1 +x:1 +伤亡者 1 +x:1 +素色 1 +x:1 +杳无音讯 1 +x:1 +创新者 1 +x:1 +景天 1 +x:1 +声 400 +x:400 +众望 1 +x:1 +郎当嫂 1 +x:1 +白塔镇 1 +x:1 +腮腺 1 +x:1 +藏东 1 +x:1 +无关大局 1 +x:1 +主人 1 +x:1 +曲尽其妙 1 +x:1 +探源 1 +x:1 +饰词 1 +x:1 +豪放派 1 +x:1 +民富国强 1 +x:1 +词句 1 +x:1 +攸县籍 1 +x:1 +天外有天 1 +x:1 +榆树市 1 +x:1 +藏书 1 +x:1 +输液器 1 +x:1 +鸽群 1 +x:1 +黄旗镇 1 +x:1 +乘胜 1 +x:1 +年率 1 +x:1 +一俟 1 +x:1 +无籽 1 +x:1 +殖民地化 1 +x:1 +逞强 1 +x:1 +豫剧 1 +x:1 +研究院所 1 +x:1 +坦坦荡荡 1 +x:1 +致幻剂 1 +x:1 +下访团 1 +x:1 +速写式 1 +x:1 +未能 1 +x:1 +锚定墩 1 +x:1 +滑稽 1 +x:1 +芳草 1 +x:1 +三结合 1 +x:1 +征婚 1 +x:1 +千手佛 1 +x:1 +预报 1 +x:1 +专心致志 1 +x:1 +磨床 1 +x:1 +芹菜 1 +x:1 +湖东乡 1 +x:1 +砌缝 1 +x:1 +青藤花杯 1 +x:1 +书法家 1 +x:1 +入冬 1 +x:1 +面议 1 +x:1 +急腹症 1 +x:1 +行伍 1 +x:1 +砌置 1 +x:1 +富港 1 +x:1 +虚饰 1 +x:1 +相邻 1 +x:1 +茶陵 1 +x:1 +丹田 1 +x:1 +老将迟暮 1 +x:1 +美女 1 +x:1 +圣彼得堡 1 +x:1 +洒泪 1 +x:1 +鹤山 1 +x:1 +洗煤厂 1 +x:1 +歌山镇 1 +x:1 +精盐 1 +x:1 +停薪 1 +x:1 +枕上 1 +x:1 +春大麦 1 +x:1 +探研 1 +x:1 +贝卡 1 +x:1 +一枝独秀 1 +x:1 +投资者 1 +x:1 +地板胶 1 +x:1 +文物界 1 +x:1 +陡坡 1 +x:1 +才尽其用 1 +x:1 +连锁店 1 +x:1 +大购大销 1 +x:1 +永乐乡 1 +x:1 +止血带 1 +x:1 +施暴者 1 +x:1 +假意 1 +x:1 +牟取暴利 1 +x:1 +宣传词 1 +x:1 +序而不变 1 +x:1 +无影无踪 1 +x:1 +菊展 1 +x:1 +铜活字 1 +x:1 +漫山遍野 1 +x:1 +精瘦 1 +x:1 +而立之年 1 +x:1 +准考证 1 +x:1 +找齐 1 +x:1 +生存性 1 +x:1 +秋后算账 1 +x:1 +免受 1 +x:1 +美妙 1 +x:1 +入党 1 +x:1 +鹤岗 1 +x:1 +无缘 1 +x:1 +比试 1 +x:1 +无缝 1 +x:1 +有生 1 +x:1 +无罪 1 +x:1 +拳棒 1 +x:1 +滑竿 1 +x:1 +广饶路 1 +x:1 +就要 1 +x:1 +路霸 1 +x:1 +彭泽县 1 +x:1 +藻类植物 1 +x:1 +随机 1 +x:1 +作秀 1 +x:1 +拘 2 +x:2 +灵慧 1 +x:1 +鹤峰 1 +x:1 +欺凌 1 +x:1 +蹩脚 1 +x:1 +酥 5 +x:5 +提 405 +x:405 +三破 1 +x:1 +假相 1 +x:1 +乳糜 1 +x:1 +信誓旦旦 1 +x:1 +富源 1 +x:1 +火土灰 1 +x:1 +美姑 1 +x:1 +赌业 1 +x:1 +储备 1 +x:1 +蜜柚苗 1 +x:1 +万古千秋 1 +x:1 +慷慨解囊 1 +x:1 +金刚钻 1 +x:1 +见谅 1 +x:1 +鞋 123 +x:123 +鞑靼 1 +x:1 +景宁 1 +x:1 +东坑乡 1 +x:1 +惯盗 1 +x:1 +三秋 1 +x:1 +求救 1 +x:1 +生活照 1 +x:1 +命中 1 +x:1 +词儿 1 +x:1 +年利率 1 +x:1 +求教 1 +x:1 +代办费 1 +x:1 +千夫 1 +x:1 +国防园 1 +x:1 +铝桶 1 +x:1 +枣庄乡 1 +x:1 +交通工具 1 +x:1 +相重 1 +x:1 +堪 29 +x:29 +乘船 1 +x:1 +预售方 1 +x:1 +紧要 1 +x:1 +贝利 1 +x:1 +起早贪黑 1 +x:1 +河源站 1 +x:1 +精矿 1 +x:1 +排长 1 +x:1 +咨询费 1 +x:1 +凝望 1 +x:1 +中远期 1 +x:1 +无绳 1 +x:1 +精短 1 +x:1 +涉猎 1 +x:1 +钨钢 1 +x:1 +词典 1 +x:1 +话锋 1 +x:1 +跤 12 +x:12 +搅动 1 +x:1 +出租费 1 +x:1 +满腔热忱 1 +x:1 +俾路支省 1 +x:1 +茌平县 1 +x:1 +中标方 1 +x:1 +闲气 1 +x:1 +草坪村 1 +x:1 +核算价 1 +x:1 +润滑性 1 +x:1 +阶梯 1 +x:1 +随到随办 1 +x:1 +扫帚 1 +x:1 +篇名 1 +x:1 +永川市 1 +x:1 +纬度 1 +x:1 +垠 1 +x:1 +大书特书 1 +x:1 +委会 1 +x:1 +贝劳 1 +x:1 +傻高 1 +x:1 +缶掌 1 +x:1 +炫目 1 +x:1 +粮区 1 +x:1 +慈利 1 +x:1 +艾美特队 1 +x:1 +湿地松 1 +x:1 +刹 30 +x:30 +高句丽 1 +x:1 +探秘 1 +x:1 +构筑物 1 +x:1 +衰竭 1 +x:1 +农总行 1 +x:1 +耶和华 1 +x:1 +坐冷板凳 1 +x:1 +粉扑扑 1 +x:1 +耒阳市 1 +x:1 +南部斋 1 +x:1 +命令 1 +x:1 +体系化 1 +x:1 +研磨 1 +x:1 +美声 1 +x:1 +驼绒 1 +x:1 +锌基 1 +x:1 +有理 1 +x:1 +人行 1 +x:1 +副食店 1 +x:1 +冰球队 1 +x:1 +纸杯 1 +x:1 +电解铝 1 +x:1 +单打独斗 1 +x:1 +地雷战 1 +x:1 +物极而反 1 +x:1 +成群结对 1 +x:1 +张黄镇 1 +x:1 +求新 1 +x:1 +籽 4 +x:4 +酸管 1 +x:1 +絮棉 1 +x:1 +首都在线 1 +x:1 +铝材 1 +x:1 +春暖花开 1 +x:1 +试听 1 +x:1 +指挥所 1 +x:1 +稳练 1 +x:1 +子痫 1 +x:1 +说了算 1 +x:1 +饲养 1 +x:1 +活路 1 +x:1 +厚道 1 +x:1 +哑巴亏 1 +x:1 +三相 1 +x:1 +土疙瘩 1 +x:1 +警威 1 +x:1 +餐会 1 +x:1 +自顾自 1 +x:1 +三盲 1 +x:1 +识破天机 1 +x:1 +活跃 1 +x:1 +赢得 1 +x:1 +小石潭 1 +x:1 +跫然 1 +x:1 +用户证 1 +x:1 +大操大办 1 +x:1 +杂醇油 1 +x:1 +傻 34 +x:34 +榆树叶 1 +x:1 +见缝就钻 1 +x:1 +烟斗丝 1 +x:1 +罗锅 1 +x:1 +入微 1 +x:1 +行会 1 +x:1 +辊道 1 +x:1 +圣但尼市 1 +x:1 +词干 1 +x:1 +醉态 1 +x:1 +三皇 1 +x:1 +报喜者 1 +x:1 +勤俭节约 1 +x:1 +电阻 1 +x:1 +富态 1 +x:1 +布纹纸 1 +x:1 +高技术化 1 +x:1 +炫示 1 +x:1 +赔偿制 1 +x:1 +敌众我寡 1 +x:1 +许愿 1 +x:1 +阒寂无声 1 +x:1 +乌兰牧旗 1 +x:1 +测评表 1 +x:1 +说法不一 1 +x:1 +卡尔加里 1 +x:1 +非农业 1 +x:1 +匆猝 1 +x:1 +图书站 1 +x:1 +吓 39 +x:39 +年终 1 +x:1 +淮南调 1 +x:1 +高技术司 1 +x:1 +排骨 1 +x:1 +南昌市 1 +x:1 +热望 1 +x:1 +珍罕 1 +x:1 +残酷无情 1 +x:1 +屡战屡胜 1 +x:1 +条陈 1 +x:1 +词序 1 +x:1 +齐心合力 1 +x:1 +入彀 1 +x:1 +子畜 1 +x:1 +乐山川 1 +x:1 +开元区 1 +x:1 +响鼻 1 +x:1 +大权在握 1 +x:1 +骄阳 1 +x:1 +天灵盖 1 +x:1 +挥发油 1 +x:1 +窝囊废 1 +x:1 +进步站 1 +x:1 +直流电 1 +x:1 +汤团 1 +x:1 +精确 1 +x:1 +上当 1 +x:1 +洒扫 1 +x:1 +外币 1 +x:1 +扫入 1 +x:1 +芯级 1 +x:1 +杨水湖 1 +x:1 +芯线 1 +x:1 +多角度 1 +x:1 +泪流满面 1 +x:1 +年纪 1 +x:1 +占卜 1 +x:1 +扫兴 1 +x:1 +年级 1 +x:1 +亡佚 1 +x:1 +线胀系数 1 +x:1 +茶食 1 +x:1 +饮料机 1 +x:1 +慢性病 1 +x:1 +珍本 1 +x:1 +禁行令 1 +x:1 +研究所 1 +x:1 +每股 1 +x:1 +入境案 1 +x:1 +讲情面 1 +x:1 +纱嫂 1 +x:1 +寄存 1 +x:1 +亡人 1 +x:1 +毛选 1 +x:1 +陡壁 1 +x:1 +餐业 1 +x:1 +沙沙沙 1 +x:1 +住宿部 1 +x:1 +信息化 1 +x:1 +拳术 1 +x:1 +多角形 1 +x:1 +承运人 1 +x:1 +信息卡 1 +x:1 +词形 1 +x:1 +丢盔弃甲 1 +x:1 +入座 1 +x:1 +马列主义 1 +x:1 +暴晒 1 +x:1 +茶饭 1 +x:1 +被害者 1 +x:1 +士卒 1 +x:1 +芳名 1 +x:1 +海洛因 1 +x:1 +虹吸管 1 +x:1 +服丧期 1 +x:1 +银行街 1 +x:1 +人性论 1 +x:1 +都市人 1 +x:1 +爆炸品 1 +x:1 +人蛇 1 +x:1 +阳安乡 1 +x:1 +部委 1 +x:1 +鸱尾 1 +x:1 +化学武器 1 +x:1 +利港镇 1 +x:1 +大名县 1 +x:1 +互连 1 +x:1 +入库 1 +x:1 +融通 1 +x:1 +厚重 1 +x:1 +弹涂鱼 1 +x:1 +登陆舰 1 +x:1 +潜隐 1 +x:1 +滑润 1 +x:1 +部头 1 +x:1 +上影 1 +x:1 +计价器 1 +x:1 +茶汤 1 +x:1 +探矿 1 +x:1 +寄寓 1 +x:1 +不闻不问 1 +x:1 +日用百货 1 +x:1 +通信班 1 +x:1 +典守者 1 +x:1 +邦 28 +x:28 +泥鳅 1 +x:1 +汉堡市 1 +x:1 +织锦 1 +x:1 +茶馓 1 +x:1 +云端 1 +x:1 +忙里忙外 1 +x:1 +电笔 1 +x:1 +茶香 1 +x:1 +纺 14 +x:14 +柏各庄镇 1 +x:1 +入席 1 +x:1 +怡 47 +x:47 +特务连 1 +x:1 +预测 1 +x:1 +过虑 1 +x:1 +实践者 1 +x:1 +磨具 1 +x:1 +锡耶纳 1 +x:1 +参演 1 +x:1 +一审 1 +x:1 +美国 1 +x:1 +信息台 1 +x:1 +假种 1 +x:1 +史学界 1 +x:1 +发散透镜 1 +x:1 +精神 1 +x:1 +塑钢窗 1 +x:1 +坏绅 1 +x:1 +入市 1 +x:1 +寄宿 1 +x:1 +磨光 1 +x:1 +刀耕火种 1 +x:1 +吞武里 1 +x:1 +电流强度 1 +x:1 +暧昧 1 +x:1 +有种 1 +x:1 +外伤性 1 +x:1 +塘 28 +x:28 +粮库 1 +x:1 +裁员量 1 +x:1 +新奇劲儿 1 +x:1 +粮店 1 +x:1 +暴政 1 +x:1 +手忙脚乱 1 +x:1 +譬如说 1 +x:1 +魁梧 1 +x:1 +匦 1 +x:1 +农机院 1 +x:1 +洗被 1 +x:1 +邮报 1 +x:1 +听辨 1 +x:1 +异状 1 +x:1 +警容 1 +x:1 +构架 1 +x:1 +强身健魄 1 +x:1 +滞留 1 +x:1 +温岭市 1 +x:1 +暴敛 1 +x:1 +荆 14 +x:14 +均衡化 1 +x:1 +鬼头鬼脑 1 +x:1 +吉卜赛 1 +x:1 +富户 1 +x:1 +烽燧 1 +x:1 +箭鱼 1 +x:1 +梅子树 1 +x:1 +虚构性 1 +x:1 +传销商 1 +x:1 +珍摄 1 +x:1 +栋栋 1 +x:1 +售货亭 1 +x:1 +培训者 1 +x:1 +人工免疫 1 +x:1 +乘车 1 +x:1 +美商 1 +x:1 +支线 1 +x:1 +万维网 1 +x:1 +飞行史 1 +x:1 +不远处 1 +x:1 +扬黄 1 +x:1 +硬席 1 +x:1 +候鸟 1 +x:1 +有神 1 +x:1 +墨水 1 +x:1 +年糕 1 +x:1 +生产方式 1 +x:1 +暧暧 1 +x:1 +凤山镇 1 +x:1 +叙事诗 1 +x:1 +印象至深 1 +x:1 +郸城 1 +x:1 +啸声 1 +x:1 +云霞 1 +x:1 +狂风恶浪 1 +x:1 +苗乡 1 +x:1 +公路桥 1 +x:1 +醉拳 1 +x:1 +走婚制 1 +x:1 +笠头村 1 +x:1 +泻珠溅玉 1 +x:1 +兼容并包 1 +x:1 +双龙镇 1 +x:1 +豁然 1 +x:1 +磨刀 1 +x:1 +飞行区 1 +x:1 +云霄 1 +x:1 +试图 1 +x:1 +播送 1 +x:1 +美不胜收 1 +x:1 +泥足巨人 1 +x:1 +话题 1 +x:1 +张庄乡 1 +x:1 +前所未有 1 +x:1 +缄默 1 +x:1 +参看 1 +x:1 +栋梁 1 +x:1 +洗衣 1 +x:1 +围攻 1 +x:1 +耕作层 1 +x:1 +血钾 1 +x:1 +淤土地 1 +x:1 +考试场 1 +x:1 +汤圆 1 +x:1 +热敷 1 +x:1 +雀斑 1 +x:1 +班组长 1 +x:1 +令人寒心 1 +x:1 +电火花机 1 +x:1 +齐岳山 1 +x:1 +检测期 1 +x:1 +花明柳暗 1 +x:1 +见者 1 +x:1 +二十日 1 +x:1 +预留 1 +x:1 +产销量 1 +x:1 +少工委 1 +x:1 +蒸笼 1 +x:1 +演讲台 1 +x:1 +二十时 1 +x:1 +胆小如鼠 1 +x:1 +子目 1 +x:1 +颤音 1 +x:1 +斟 10 +x:10 +胆量 1 +x:1 +三军团 1 +x:1 +侧压力 1 +x:1 +停电 1 +x:1 +美名 1 +x:1 +老人节 1 +x:1 +袭 51 +x:51 +患者 1 +x:1 +精算 1 +x:1 +糖尿病 1 +x:1 +法国法郎 1 +x:1 +平战时 1 +x:1 +凝止 1 +x:1 +精简 1 +x:1 +秦坊村 1 +x:1 +眼罩 1 +x:1 +玉米塘村 1 +x:1 +破铜烂铁 1 +x:1 +磨叽 1 +x:1 +自考 1 +x:1 +书报摊 1 +x:1 +奔马图 1 +x:1 +停留 1 +x:1 +顺访 1 +x:1 +有碍 1 +x:1 +探由 1 +x:1 +美味 1 +x:1 +中西 1 +x:1 +晞 14 +x:14 +湛蓝湛蓝 1 +x:1 +烽烟 1 +x:1 +龟鉴 1 +x:1 +妙趣横生 1 +x:1 +欢乐与共 1 +x:1 +红褐色 1 +x:1 +士兵 1 +x:1 +继往 1 +x:1 +丰产期 1 +x:1 +软武器 1 +x:1 +漏勺 1 +x:1 +栏目 1 +x:1 +谅 4 +x:4 +议会制 1 +x:1 +非企业 1 +x:1 +形体美 1 +x:1 +落筒机 1 +x:1 +预算内 1 +x:1 +文化部长 1 +x:1 +预演 1 +x:1 +管辖权 1 +x:1 +探病 1 +x:1 +火山灰 1 +x:1 +青春期 1 +x:1 +胆酸 1 +x:1 +洗净度 1 +x:1 +热水器 1 +x:1 +伦理学 1 +x:1 +高粱酒 1 +x:1 +文明园 1 +x:1 +滑石 1 +x:1 +脉脉传情 1 +x:1 +笺注 1 +x:1 +燃烧器 1 +x:1 +扬威 1 +x:1 +崖下 1 +x:1 +品种 1 +x:1 +粗放型 1 +x:1 +万古长存 1 +x:1 +主辅修制 1 +x:1 +胞波 1 +x:1 +烽火 1 +x:1 +转运 1 +x:1 +米扁虫 1 +x:1 +拒报 1 +x:1 +险 78 +x:78 +三田 1 +x:1 +三甲 1 +x:1 +三电 1 +x:1 +南半球 1 +x:1 +游艺会 1 +x:1 +丰产林 1 +x:1 +干国之器 1 +x:1 +环保局 1 +x:1 +无限性 1 +x:1 +鬼哭神嚎 1 +x:1 +配色 1 +x:1 +历音 1 +x:1 +非盈利性 1 +x:1 +精粹 1 +x:1 +阿肯色 1 +x:1 +纷然 1 +x:1 +挥洒自如 1 +x:1 +报刊社 1 +x:1 +覆膜机 1 +x:1 +摊摊 1 +x:1 +过境站 1 +x:1 +迂回 1 +x:1 +无把握 1 +x:1 +封建割据 1 +x:1 +火山石 1 +x:1 +龙王塘 1 +x:1 +病殃殃 1 +x:1 +由衷 1 +x:1 +变性酒精 1 +x:1 +回生 1 +x:1 +丝带 1 +x:1 +攻防 1 +x:1 +狼牙山 1 +x:1 +无配料表 1 +x:1 +砸 102 +x:102 +争芳斗艳 1 +x:1 +美化 1 +x:1 +情景剧 1 +x:1 +听见 1 +x:1 +瞄准 1 +x:1 +入室 1 +x:1 +奥博 1 +x:1 +听觉 1 +x:1 +弱币 1 +x:1 +血液 1 +x:1 +就范 1 +x:1 +征候 1 +x:1 +法国杯赛 1 +x:1 +糊涂 1 +x:1 +呱呱 1 +x:1 +隐姓埋名 1 +x:1 +面生 1 +x:1 +金福村 1 +x:1 +美协 1 +x:1 +梯度差 1 +x:1 +烈日当空 1 +x:1 +牙克石 1 +x:1 +合成器 1 +x:1 +齐东野语 1 +x:1 +无痛 1 +x:1 +鸟语花香 1 +x:1 +社交界 1 +x:1 +种养殖 1 +x:1 +大客厅 1 +x:1 +着火 1 +x:1 +脉 8 +x:8 +无用 1 +x:1 +入学 1 +x:1 +欺客 1 +x:1 +贸委会 1 +x:1 +淆杂 1 +x:1 +无由 1 +x:1 +祖庙 1 +x:1 +最近 1 +x:1 +掺水 1 +x:1 +皇位 1 +x:1 +毫无疑义 1 +x:1 +朝 265 +x:265 +声色 1 +x:1 +富国墩 1 +x:1 +黑货 1 +x:1 +血站 1 +x:1 +金台里 1 +x:1 +品级 1 +x:1 +济铁 1 +x:1 +三牲 1 +x:1 +战略家 1 +x:1 +油公司 1 +x:1 +整容镜 1 +x:1 +磨合 1 +x:1 +织造 1 +x:1 +凝注 1 +x:1 +热心人 1 +x:1 +放录像 1 +x:1 +楚楚动人 1 +x:1 +护航 1 +x:1 +科研所 1 +x:1 +预案 1 +x:1 +铝排 1 +x:1 +位 5797 +x:5797 +济钢 1 +x:1 +精米 1 +x:1 +留尼汪 1 +x:1 +停水 1 +x:1 +修正主义 1 +x:1 +三年期 1 +x:1 +反转片 1 +x:1 +投递员 1 +x:1 +类人猿 1 +x:1 +四方八面 1 +x:1 +糠 3 +x:3 +棘皮动物 1 +x:1 +部属 1 +x:1 +白煞煞 1 +x:1 +金圆区 1 +x:1 +俱乐部制 1 +x:1 +稳稳 1 +x:1 +业大 1 +x:1 +无畏 1 +x:1 +全镇 1 +x:1 +淤塞 1 +x:1 +勇往直前 1 +x:1 +美发 1 +x:1 +军转 1 +x:1 +乌光 1 +x:1 +盆子 1 +x:1 +顺路 1 +x:1 +奥波莱市 1 +x:1 +佚事 1 +x:1 +学府 1 +x:1 +费难 1 +x:1 +陡峭 1 +x:1 +布鲁氏菌 1 +x:1 +文科生 1 +x:1 +不稳定性 1 +x:1 +藏品展 1 +x:1 +过节 1 +x:1 +动心忍性 1 +x:1 +陡峻 1 +x:1 +客车队 1 +x:1 +暴戾 1 +x:1 +吉泊村 1 +x:1 +向阳坡 1 +x:1 +瞧 52 +x:52 +潮阳市 1 +x:1 +油光光 1 +x:1 +美分 1 +x:1 +风光 1 +x:1 +盗卖案 1 +x:1 +丝弦 1 +x:1 +征兵 1 +x:1 +报幕员 1 +x:1 +播音 1 +x:1 +实现者 1 +x:1 +承包期 1 +x:1 +景况 1 +x:1 +王府井站 1 +x:1 +围拢 1 +x:1 +糊泡 1 +x:1 +肺心病 1 +x:1 +埃斯波市 1 +x:1 +硬座 1 +x:1 +找钱 1 +x:1 +千升 1 +x:1 +辩证法 1 +x:1 +尽责 1 +x:1 +理工大学 1 +x:1 +宣传者 1 +x:1 +播映 1 +x:1 +玉环县 1 +x:1 +帐子 1 +x:1 +韧 2 +x:2 +千卡 1 +x:1 +占位 1 +x:1 +查错程序 1 +x:1 +工业园区 1 +x:1 +黄浦江畔 1 +x:1 +支离 1 +x:1 +西辛庄 1 +x:1 +三环 1 +x:1 +围护 1 +x:1 +构想 1 +x:1 +柜门 1 +x:1 +有约 1 +x:1 +栅网 1 +x:1 +技不压身 1 +x:1 +拨款 1 +x:1 +居留权 1 +x:1 +知人善任 1 +x:1 +构思 1 +x:1 +云浮市 1 +x:1 +卷帘门 1 +x:1 +热战 1 +x:1 +绘图板 1 +x:1 +玉米花儿 1 +x:1 +无理 1 +x:1 +小花棘豆 1 +x:1 +流氓气 1 +x:1 +及其 1 +x:1 +信息型 1 +x:1 +民工潮 1 +x:1 +词宗 1 +x:1 +活血 1 +x:1 +副食品 1 +x:1 +上市 1 +x:1 +蛹期 1 +x:1 +邮政 1 +x:1 +纱帐 1 +x:1 +险区 1 +x:1 +纱帘 1 +x:1 +绘图本 1 +x:1 +篇幅 1 +x:1 +人艺 1 +x:1 +飞行员 1 +x:1 +皇上 1 +x:1 +供给方 1 +x:1 +涉禽 1 +x:1 +职业队 1 +x:1 +贝壳 1 +x:1 +市委办 1 +x:1 +纱帽 1 +x:1 +琥珀 1 +x:1 +千古 1 +x:1 +邂逅相逢 1 +x:1 +无瑕 1 +x:1 +宣传股 1 +x:1 +无所不容 1 +x:1 +有史以来 1 +x:1 +千叶 1 +x:1 +噪杂 1 +x:1 +盘缠 1 +x:1 +精纺 1 +x:1 +书法史 1 +x:1 +求求 1 +x:1 +民族形式 1 +x:1 +试制 1 +x:1 +珍珠圆 1 +x:1 +打散 1 +x:1 +确乎不拔 1 +x:1 +芳华 1 +x:1 +洗精煤 1 +x:1 +公路法 1 +x:1 +嗬哟 1 +x:1 +创新论 1 +x:1 +灰乌乌 1 +x:1 +犁镜 1 +x:1 +活话 1 +x:1 +充足率 1 +x:1 +三热 1 +x:1 +外接圆 1 +x:1 +试刊 1 +x:1 +免刑 1 +x:1 +火药味 1 +x:1 +茂盛 1 +x:1 +辛未 1 +x:1 +遮丑 1 +x:1 +文明化 1 +x:1 +护肩 1 +x:1 +冷风型 1 +x:1 +药皂 1 +x:1 +活计 1 +x:1 +克边疆区 1 +x:1 +长跑队 1 +x:1 +楚 47 +x:47 +弱小 1 +x:1 +戒坛院 1 +x:1 +美元 1 +x:1 +乘警 1 +x:1 +寺沟乡 1 +x:1 +听说 1 +x:1 +置之脑后 1 +x:1 +企获 1 +x:1 +听课 1 +x:1 +品类 1 +x:1 +精练 1 +x:1 +异相 1 +x:1 +停火 1 +x:1 +精细 1 +x:1 +试剂 1 +x:1 +北土城 1 +x:1 +住房 1 +x:1 +凝滞 1 +x:1 +血流 1 +x:1 +剥蚀 1 +x:1 +馆陶县 1 +x:1 +求法 1 +x:1 +年利税 1 +x:1 +双人床 1 +x:1 +人脸 1 +x:1 +五台山 1 +x:1 +回收期 1 +x:1 +金豹黄 1 +x:1 +热感 1 +x:1 +父老兄弟 1 +x:1 +哑炮 1 +x:1 +A 433 +x:433 +试办 1 +x:1 +景别 1 +x:1 +文明号 1 +x:1 +挡泥板 1 +x:1 +馆舍 1 +x:1 +抵扣率 1 +x:1 +扫地 1 +x:1 +阻 7 +x:7 +新舰 1 +x:1 +人脑 1 +x:1 +阿尔及尔 1 +x:1 +引以 1 +x:1 +染色 1 +x:1 +三来一补 1 +x:1 +潇水 1 +x:1 +绝对高度 1 +x:1 +砌石 1 +x:1 +荦荦 1 +x:1 +欺蒙 1 +x:1 +球龄 1 +x:1 +护耳 1 +x:1 +葫芦 1 +x:1 +离子流 1 +x:1 +无着 1 +x:1 +饥 10 +x:10 +若即若离 1 +x:1 +索然 1 +x:1 +过腹 1 +x:1 +入夜 1 +x:1 +荡检逾闲 1 +x:1 +动手术 1 +x:1 +珍惜 1 +x:1 +品系 1 +x:1 +东大桥 1 +x:1 +横断面 1 +x:1 +求治 1 +x:1 +三中全会 1 +x:1 +娘娘巷 1 +x:1 +嘱托 1 +x:1 +笺校 1 +x:1 +秦家沟 1 +x:1 +词头 1 +x:1 +繁茂 1 +x:1 +潜逃 1 +x:1 +父母官 1 +x:1 +儿童村 1 +x:1 +入声 1 +x:1 +置换 1 +x:1 +余派 1 +x:1 +夹山寺 1 +x:1 +法郎区 1 +x:1 +倪 85 +x:85 +腐烂 1 +x:1 +薄脆 1 +x:1 +缴枪 1 +x:1 +年票 1 +x:1 +连篇 1 +x:1 +钽 3 +x:3 +改作 1 +x:1 +热情 1 +x:1 +汉族人 1 +x:1 +试卷 1 +x:1 +聊 64 +x:64 +督访行 1 +x:1 +求洋 1 +x:1 +丹参酮 1 +x:1 +中东部 1 +x:1 +孟加拉队 1 +x:1 +年礼 1 +x:1 +千金一诺 1 +x:1 +无益 1 +x:1 +隐没 1 +x:1 +装甲车 1 +x:1 +入境 1 +x:1 +说大话 1 +x:1 +护膝 1 +x:1 +重机枪 1 +x:1 +入境游 1 +x:1 +自制力 1 +x:1 +寨主 1 +x:1 +打断 1 +x:1 +声腔 1 +x:1 +星空图 1 +x:1 +顺车 1 +x:1 +延请 1 +x:1 +熠熠 1 +x:1 +融雪 1 +x:1 +乡乡村村 1 +x:1 +护腿 1 +x:1 +园中 1 +x:1 +离子水 1 +x:1 +以泪洗面 1 +x:1 +当之无愧 1 +x:1 +报刊架 1 +x:1 +构成 1 +x:1 +费时 1 +x:1 +乱 538 +x:538 +犁铧 1 +x:1 +子牙 1 +x:1 +征召 1 +x:1 +景区 1 +x:1 +防水坝 1 +x:1 +直言不讳 1 +x:1 +笋瓜 1 +x:1 +秦皇岛 1 +x:1 +文明办 1 +x:1 +财政寡头 1 +x:1 +涂脂抹粉 1 +x:1 +哒 1 +x:1 +债务人 1 +x:1 +扮成 1 +x:1 +六边形 1 +x:1 +丹粉 1 +x:1 +演绎者 1 +x:1 +温饱线 1 +x:1 +秤 37 +x:37 +鉴定费 1 +x:1 +飞行器 1 +x:1 +丝巾 1 +x:1 +巫山县 1 +x:1 +访问率 1 +x:1 +磨坊 1 +x:1 +彩蝶飞舞 1 +x:1 +维持性 1 +x:1 +护脚 1 +x:1 +离到任 1 +x:1 +三焦 1 +x:1 +鬼天气 1 +x:1 +大陆军 1 +x:1 +笸箩 1 +x:1 +慈和 1 +x:1 +银卡 1 +x:1 +车匪路霸 1 +x:1 +千万 1 +x:1 +滑溜 1 +x:1 +哪般 1 +x:1 +花心 1 +x:1 +眼红 1 +x:1 +报考 1 +x:1 +黄南 1 +x:1 +活门 1 +x:1 +清迈 1 +x:1 +学岗 1 +x:1 +济南站 1 +x:1 +假性 1 +x:1 +年景 1 +x:1 +人龙 1 +x:1 +在即 1 +x:1 +姐妹篇 1 +x:1 +三滤 1 +x:1 +召集人 1 +x:1 +榜首 1 +x:1 +糕饼 1 +x:1 +真心话 1 +x:1 +屈 37 +x:37 +辩护律师 1 +x:1 +皇历 1 +x:1 +招安 1 +x:1 +锣鼓声 1 +x:1 +支撑 1 +x:1 +蜂产品 1 +x:1 +四体书 1 +x:1 +柿椒 1 +x:1 +清远 1 +x:1 +清爽爽 1 +x:1 +尽速 1 +x:1 +九华灯 1 +x:1 +坎昆 1 +x:1 +苘山镇 1 +x:1 +求爱 1 +x:1 +制假者 1 +x:1 +肯尼迪 1 +x:1 +木箱 1 +x:1 +组曲 1 +x:1 +三湘 1 +x:1 +招子 1 +x:1 +融解 1 +x:1 +洱源 1 +x:1 +高鼻子 1 +x:1 +羊崽 1 +x:1 +晚市 1 +x:1 +围网 1 +x:1 +精怪 1 +x:1 +应运而生 1 +x:1 +佣金 1 +x:1 +展项 1 +x:1 +核战争 1 +x:1 +售货员 1 +x:1 +黄发 1 +x:1 +花影 1 +x:1 +一钱不值 1 +x:1 +金匮要略 1 +x:1 +地黄牛 1 +x:1 +有感 1 +x:1 +旅游性 1 +x:1 +三湾 1 +x:1 +温故知新 1 +x:1 +边民证 1 +x:1 +电灯泡 1 +x:1 +顺遂 1 +x:1 +吴旗县 1 +x:1 +心腹大患 1 +x:1 +奈曼旗 1 +x:1 +自成一体 1 +x:1 +黄叶 1 +x:1 +顺道 1 +x:1 +奋不顾身 1 +x:1 +黄历 1 +x:1 +藏学 1 +x:1 +针灸学会 1 +x:1 +妙趣横溢 1 +x:1 +沉甸甸 1 +x:1 +藻 4 +x:4 +彪形 1 +x:1 +大辛阁区 1 +x:1 +连阴雨 1 +x:1 +传销员 1 +x:1 +假想 1 +x:1 +破伤风 1 +x:1 +可消化性 1 +x:1 +凝炼 1 +x:1 +颠簸车 1 +x:1 +黄县 1 +x:1 +一展身手 1 +x:1 +刘公岛 1 +x:1 +拉孜县 1 +x:1 +晚年 1 +x:1 +研习班 1 +x:1 +血丝虫病 1 +x:1 +贮藏 1 +x:1 +千伏 1 +x:1 +渗透战 1 +x:1 +围绕 1 +x:1 +无梭 1 +x:1 +上网费 1 +x:1 +梆子腔 1 +x:1 +疏导 1 +x:1 +美丽 1 +x:1 +胆识 1 +x:1 +全反射 1 +x:1 +旬阳县 1 +x:1 +花廊 1 +x:1 +矛盾体 1 +x:1 +资产率 1 +x:1 +干道路 1 +x:1 +制度 1 +x:1 +音长 1 +x:1 +索绕 1 +x:1 +疏密 1 +x:1 +开户行 1 +x:1 +围绳 1 +x:1 +改革家 1 +x:1 +掠取 1 +x:1 +美丑 1 +x:1 +热线 1 +x:1 +美专 1 +x:1 +初中级 1 +x:1 +无棣 1 +x:1 +柜角 1 +x:1 +花店 1 +x:1 +千手堂 1 +x:1 +畴昔 1 +x:1 +教8飞机 1 +x:1 +过江之鲫 1 +x:1 +爬山虎 1 +x:1 +不知进退 1 +x:1 +利马 1 +x:1 +年月 1 +x:1 +镍都 1 +x:1 +热络 1 +x:1 +亡国 1 +x:1 +个股 1 +x:1 +花序 1 +x:1 +红十字 1 +x:1 +桦 34 +x:34 +齐抓共管 1 +x:1 +但愿 1 +x:1 +桃花汛 1 +x:1 +进口国 1 +x:1 +天涯地角 1 +x:1 +年末 1 +x:1 +播讲 1 +x:1 +话茬 1 +x:1 +离职 1 +x:1 +翠屏峰 1 +x:1 +听风是雨 1 +x:1 +演绎法 1 +x:1 +阶级 1 +x:1 +互通式 1 +x:1 +虾米 1 +x:1 +熙攘 1 +x:1 +美人 1 +x:1 +东京湾 1 +x:1 +五不准 1 +x:1 +舞艺 1 +x:1 +一定 1 +x:1 +喘 18 +x:18 +无核 1 +x:1 +起手回春 1 +x:1 +美事 1 +x:1 +茅草街 1 +x:1 +藏娃 1 +x:1 +一家 1 +x:1 +尽量 1 +x:1 +校董事会 1 +x:1 +羊肉 1 +x:1 +桐油 1 +x:1 +东京港 1 +x:1 +茶苗 1 +x:1 +不瞒你说 1 +x:1 +花布 1 +x:1 +花市 1 +x:1 +喜滋滋 1 +x:1 +恰如其当 1 +x:1 +李圪塔乡 1 +x:1 +龟裂 1 +x:1 +晚归 1 +x:1 +肉搏战 1 +x:1 +邮票 1 +x:1 +登陆艇 1 +x:1 +切尔米斯 1 +x:1 +檐口 1 +x:1 +统购统销 1 +x:1 +调研 1 +x:1 +躲避 1 +x:1 +召 9 +x:9 +缺血性 1 +x:1 +花带 1 +x:1 +石刀山 1 +x:1 +书写纸 1 +x:1 +一对 1 +x:1 +花席 1 +x:1 +翠屏山 1 +x:1 +勤工俭学 1 +x:1 +国内化 1 +x:1 +三法 1 +x:1 +崖城 1 +x:1 +一早 1 +x:1 +计划局 1 +x:1 +视听产品 1 +x:1 +小花袄 1 +x:1 +黄蒿梁 1 +x:1 +赞助者 1 +x:1 +熙暖 1 +x:1 +双十二 1 +x:1 +夕烟 1 +x:1 +口信儿 1 +x:1 +探求 1 +x:1 +云雀 1 +x:1 +作派 1 +x:1 +公私章 1 +x:1 +不减当年 1 +x:1 +花工 1 +x:1 +蔗糖 1 +x:1 +进步性 1 +x:1 +黯然 1 +x:1 +阴有小雨 1 +x:1 +转行 1 +x:1 +潜质 1 +x:1 +征丁 1 +x:1 +景从 1 +x:1 +解释器 1 +x:1 +要约 1 +x:1 +展看 1 +x:1 +见不得人 1 +x:1 +饲养场主 1 +x:1 +皇军 1 +x:1 +假托 1 +x:1 +茶色 1 +x:1 +面试 1 +x:1 +福州市 1 +x:1 +长城湾 1 +x:1 +茶艺 1 +x:1 +阴云 1 +x:1 +假手 1 +x:1 +东环路 1 +x:1 +排联 1 +x:1 +捷足先登 1 +x:1 +⑤ 10 +x:10 +三沿 1 +x:1 +抽样调查 1 +x:1 +不实之词 1 +x:1 +三河 1 +x:1 +浪 102 +x:102 +式调 1 +x:1 +一阵风 1 +x:1 +无毒 1 +x:1 +避风 1 +x:1 +几近 1 +x:1 +宁河 1 +x:1 +无比 1 +x:1 +皇冠 1 +x:1 +假扮 1 +x:1 +作浪 1 +x:1 +絮状 1 +x:1 +景仰 1 +x:1 +素有 1 +x:1 +三江 1 +x:1 +一水 1 +x:1 +柞蚕 1 +x:1 +缴税 1 +x:1 +茶花 1 +x:1 +谰言 1 +x:1 +密不可分 1 +x:1 +助耕队 1 +x:1 +无欺 1 +x:1 +试产 1 +x:1 +素服 1 +x:1 +南长山镇 1 +x:1 +人物 1 +x:1 +促生产 1 +x:1 +木偶戏 1 +x:1 +生产关系 1 +x:1 +农业局 1 +x:1 +命官 1 +x:1 +繁芜 1 +x:1 +反应器 1 +x:1 +墙头草 1 +x:1 +优等品 1 +x:1 +律师费 1 +x:1 +过街通道 1 +x:1 +学年 1 +x:1 +黄冈 1 +x:1 +茼山镇 1 +x:1 +披毛犀 1 +x:1 +大悲大喜 1 +x:1 +诸强 1 +x:1 +度度 1 +x:1 +泥螺 1 +x:1 +疏堵 1 +x:1 +停泊 1 +x:1 +繁荣 1 +x:1 +帝都 1 +x:1 +滨 30 +x:30 +畦塄 1 +x:1 +筷子 1 +x:1 +有愧 1 +x:1 +牵制 1 +x:1 +万家寨 1 +x:1 +文物性 1 +x:1 +无以 1 +x:1 +毛边纸 1 +x:1 +制约力 1 +x:1 +猫子哥 1 +x:1 +窃取 1 +x:1 +暖情 1 +x:1 +学徒 1 +x:1 +禁毒委 1 +x:1 +一大 1 +x:1 +禁不住 1 +x:1 +蓄积量 1 +x:1 +探测 1 +x:1 +繁花 1 +x:1 +地脚 1 +x:1 +一头 1 +x:1 +绳锯木断 1 +x:1 +邮箱 1 +x:1 +尖嘴薄舌 1 +x:1 +展馆 1 +x:1 +桫椤树 1 +x:1 +支柱 1 +x:1 +新民市 1 +x:1 +婺剧 1 +x:1 +赌客 1 +x:1 +花岛 1 +x:1 +费神 1 +x:1 +弄权 1 +x:1 +有悖 1 +x:1 +三消 1 +x:1 +茶荷 1 +x:1 +繁苛 1 +x:1 +渗透性 1 +x:1 +回收站 1 +x:1 +密不通风 1 +x:1 +丘陵岗 1 +x:1 +连环画 1 +x:1 +占先 1 +x:1 +满分 1 +x:1 +民事权利 1 +x:1 +酬 11 +x:11 +乘除 1 +x:1 +三生有幸 1 +x:1 +一骨碌 1 +x:1 +支架 1 +x:1 +含英咀华 1 +x:1 +乾 14 +x:14 +一如 1 +x:1 +指挥科 1 +x:1 +疾阻 1 +x:1 +花展 1 +x:1 +风儿 1 +x:1 +规范性 1 +x:1 +秋水 1 +x:1 +衰滞 1 +x:1 +听阈 1 +x:1 +乘隙 1 +x:1 +社会工作 1 +x:1 +三流 1 +x:1 +夕照 1 +x:1 +德清县 1 +x:1 +张冠李戴 1 +x:1 +温 373 +x:373 +有恩 1 +x:1 +东南亚虎 1 +x:1 +有息 1 +x:1 +木字旁儿 1 +x:1 +心肌炎 1 +x:1 +作法 1 +x:1 +苗圃 1 +x:1 +菱湖 1 +x:1 +森林队 1 +x:1 +条贯 1 +x:1 +半推半就 1 +x:1 +人鱼 1 +x:1 +真诚以待 1 +x:1 +球部 1 +x:1 +邮筒 1 +x:1 +铝粉 1 +x:1 +疏失 1 +x:1 +双十佳 1 +x:1 +异步 1 +x:1 +单精度 1 +x:1 +征伐 1 +x:1 +文明人 1 +x:1 +灭 65 +x:65 +油渍 1 +x:1 +有怨 1 +x:1 +巴 926 +x:926 +都行 1 +x:1 +收贷率 1 +x:1 +有性 1 +x:1 +一市 1 +x:1 +排水 1 +x:1 +飞檐翘角 1 +x:1 +送检 1 +x:1 +破马张飞 1 +x:1 +花石乡 1 +x:1 +皇城 1 +x:1 +司法部 1 +x:1 +灌馅麻糖 1 +x:1 +鱼味 1 +x:1 +腮部 1 +x:1 +融资 1 +x:1 +小组会 1 +x:1 +一带 1 +x:1 +珍稀 1 +x:1 +银发 1 +x:1 +总览 1 +x:1 +唐古拉山 1 +x:1 +眼窝 1 +x:1 +狂想曲 1 +x:1 +广东戏 1 +x:1 +叫卖声 1 +x:1 +神道碑 1 +x:1 +信息业 1 +x:1 +风雪帽 1 +x:1 +联赛史 1 +x:1 +厚谊 1 +x:1 +加盟费 1 +x:1 +刘家桥村 1 +x:1 +拍片 1 +x:1 +年成 1 +x:1 +黄土 1 +x:1 +皖维 1 +x:1 +招待 1 +x:1 +微弱 1 +x:1 +孝感市 1 +x:1 +产奶量 1 +x:1 +学士 1 +x:1 +开户费 1 +x:1 +二工乡 1 +x:1 +预热 1 +x:1 +云月湖 1 +x:1 +去年末 1 +x:1 +巴彦浩特 1 +x:1 +租期 1 +x:1 +洗雪 1 +x:1 +察右旗 1 +x:1 +一干 1 +x:1 +红景天 1 +x:1 +卡萨芒斯 1 +x:1 +砀山 1 +x:1 +一并 1 +x:1 +花室 1 +x:1 +躲闪 1 +x:1 +大藏相 1 +x:1 +同志会 1 +x:1 +淳厚 1 +x:1 +水调歌头 1 +x:1 +招录 1 +x:1 +屯扎 1 +x:1 +氧分子 1 +x:1 +黄埃 1 +x:1 +个人所 1 +x:1 +禾本科 1 +x:1 +马尾松 1 +x:1 +一应 1 +x:1 +指挥组 1 +x:1 +黄埔 1 +x:1 +缝 45 +x:45 +疏干 1 +x:1 +滑梯 1 +x:1 +藏式 1 +x:1 +磷酸铵 1 +x:1 +颜色 1 +x:1 +影印本 1 +x:1 +赌局 1 +x:1 +难上加难 1 +x:1 +户口区 1 +x:1 +龟足 1 +x:1 +稳压器 1 +x:1 +受灾区 1 +x:1 +花季 1 +x:1 +航天员 1 +x:1 +餐厅 1 +x:1 +士人 1 +x:1 +有望 1 +x:1 +小书贩 1 +x:1 +有期 1 +x:1 +中华龟 1 +x:1 +承重墙 1 +x:1 +嬉皮士 1 +x:1 +磷酸钙 1 +x:1 +新品 1 +x:1 +入口处 1 +x:1 +生活报 1 +x:1 +晚婚 1 +x:1 +排雷员 1 +x:1 +山桐子 1 +x:1 +屹立 1 +x:1 +有机 1 +x:1 +进门费 1 +x:1 +占领军 1 +x:1 +疏布 1 +x:1 +延吉路 1 +x:1 +户口卡 1 +x:1 +织补 1 +x:1 +年利息 1 +x:1 +文侩 1 +x:1 +有术 1 +x:1 +一建 1 +x:1 +平地风波 1 +x:1 +皇储 1 +x:1 +人骨 1 +x:1 +供不应求 1 +x:1 +镍钢 1 +x:1 +餐券 1 +x:1 +生存率 1 +x:1 +茶渍 1 +x:1 +疏忽 1 +x:1 +文体 1 +x:1 +敢作敢为 1 +x:1 +笑逐颜开 1 +x:1 +长跑赛 1 +x:1 +无沿 1 +x:1 +谢里夫派 1 +x:1 +精料 1 +x:1 +恰恰 1 +x:1 +苍东村 1 +x:1 +后富户 1 +x:1 +澧 1 +x:1 +门牌号 1 +x:1 +放冷风 1 +x:1 +晚宴 1 +x:1 +重振旗鼓 1 +x:1 +油茶 1 +x:1 +隔墙有耳 1 +x:1 +停歇 1 +x:1 +单克隆 1 +x:1 +求真 1 +x:1 +进步权 1 +x:1 +茶蕾 1 +x:1 +观其行 1 +x:1 +真情难觅 1 +x:1 +学委 1 +x:1 +栏栅 1 +x:1 +狮豹头 1 +x:1 +亲切 1 +x:1 +停止 1 +x:1 +效益型 1 +x:1 +无法 1 +x:1 +口令声 1 +x:1 +添 153 +x:153 +砼面板 1 +x:1 +盖州市 1 +x:1 +返光镜 1 +x:1 +南苑乡 1 +x:1 +一律 1 +x:1 +发动者 1 +x:1 +光绪帝 1 +x:1 +亡魂丧胆 1 +x:1 +总数 1 +x:1 +求援者 1 +x:1 +玫瑰红 1 +x:1 +长阳县 1 +x:1 +打秋风 1 +x:1 +集团式 1 +x:1 +罗裙 1 +x:1 +搡 5 +x:5 +求知 1 +x:1 +泥胎 1 +x:1 +硬水 1 +x:1 +汉口 1 +x:1 +小高陵村 1 +x:1 +山楂果 1 +x:1 +莫力达瓦 1 +x:1 +乐平市 1 +x:1 +甲吾拉 1 +x:1 +腥味 1 +x:1 +库尔勒市 1 +x:1 +无氟 1 +x:1 +琢磨不透 1 +x:1 +人马 1 +x:1 +泼水节 1 +x:1 +刮风 1 +x:1 +泥肥 1 +x:1 +简述 1 +x:1 +野生 1 +x:1 +学好 1 +x:1 +淮海区 1 +x:1 +路口处 1 +x:1 +高素质 1 +x:1 +接访日 1 +x:1 +踢皮球 1 +x:1 +生日卡 1 +x:1 +牛羊肉 1 +x:1 +瓶装 1 +x:1 +葡 127 +x:127 +潇潇 1 +x:1 +匡世济民 1 +x:1 +枯墨 1 +x:1 +溢流坝 1 +x:1 +疏开 1 +x:1 +假日 1 +x:1 +计划室 1 +x:1 +税契 1 +x:1 +排污 1 +x:1 +制约型 1 +x:1 +连锁业 1 +x:1 +朝奉郎 1 +x:1 +一小 1 +x:1 +铝合金 1 +x:1 +慢车道 1 +x:1 +康乐城 1 +x:1 +户口册 1 +x:1 +找还 1 +x:1 +头等功 1 +x:1 +有旱 1 +x:1 +天下人 1 +x:1 +芽苞 1 +x:1 +枯季 1 +x:1 +缴纳 1 +x:1 +有时 1 +x:1 +年息 1 +x:1 +洗钱 1 +x:1 +用米 1 +x:1 +私家车 1 +x:1 +曲别针 1 +x:1 +借水行舟 1 +x:1 +牵动 1 +x:1 +就餐 1 +x:1 +声频 1 +x:1 +餐具 1 +x:1 +喜获 1 +x:1 +运行图 1 +x:1 +定活两便 1 +x:1 +占领区 1 +x:1 +作文簿 1 +x:1 +姹紫嫣红 1 +x:1 +乐 231 +x:231 +糊状物 1 +x:1 +一展 1 +x:1 +大使馆 1 +x:1 +古竹乡 1 +x:1 +有方 1 +x:1 +桃花源 1 +x:1 +穿针引线 1 +x:1 +皮带轮 1 +x:1 +支护 1 +x:1 +泥范 1 +x:1 +股东 1 +x:1 +选材 1 +x:1 +鹰 26 +x:26 +原模原样 1 +x:1 +亚欧 1 +x:1 +宫殿式 1 +x:1 +但是 1 +x:1 +霁 6 +x:6 +赤心报国 1 +x:1 +老宋体 1 +x:1 +枯寂 1 +x:1 +儿童组 1 +x:1 +亚热区 1 +x:1 +未遭 1 +x:1 +投资部 1 +x:1 +醚 1 +x:1 +总领馆 1 +x:1 +鼓吹者 1 +x:1 +指挥系 1 +x:1 +有数 1 +x:1 +傻话 1 +x:1 +十七孔桥 1 +x:1 +相聚 1 +x:1 +爱尔福特 1 +x:1 +向日葵 1 +x:1 +精明 1 +x:1 +公干 1 +x:1 +诸子 1 +x:1 +暗器 1 +x:1 +三桥 1 +x:1 +桃仁 1 +x:1 +未遂 1 +x:1 +装机量 1 +x:1 +人饮 1 +x:1 +送者 1 +x:1 +久仰大名 1 +x:1 +奇谈怪论 1 +x:1 +童言无忌 1 +x:1 +丹方 1 +x:1 +集团层 1 +x:1 +飞行体 1 +x:1 +示范带头 1 +x:1 +裔 2 +x:2 +游艺场 1 +x:1 +构筑 1 +x:1 +寻欢作乐 1 +x:1 +腥 1 +x:1 +花头 1 +x:1 +个人性 1 +x:1 +病秧子 1 +x:1 +羞涩 1 +x:1 +扬花 1 +x:1 +甲壳动物 1 +x:1 +塔西河 1 +x:1 +大陆坡 1 +x:1 +孽生 1 +x:1 +课 200 +x:200 +运行率 1 +x:1 +采伐量 1 +x:1 +学家 1 +x:1 +假期 1 +x:1 +珍珠业 1 +x:1 +回弹性 1 +x:1 +税容 1 +x:1 +无火焰 1 +x:1 +视图 1 +x:1 +侗民 1 +x:1 +画卷 1 +x:1 +鸡口牛后 1 +x:1 +承包户 1 +x:1 +医卫体 1 +x:1 +迎薰亭 1 +x:1 +叶子 1 +x:1 +葬入 1 +x:1 +拐卖 1 +x:1 +条规 1 +x:1 +亡命 1 +x:1 +胶板纸 1 +x:1 +冯 448 +x:448 +税官 1 +x:1 +变速箱 1 +x:1 +捆绑 1 +x:1 +眼福 1 +x:1 +支援 1 +x:1 +洼 4 +x:4 +马埂村 1 +x:1 +辽宁省 1 +x:1 +纺织机 1 +x:1 +枣庄市 1 +x:1 +警绩 1 +x:1 +花墙 1 +x:1 +抛光片 1 +x:1 +夫唱妇随 1 +x:1 +林田村 1 +x:1 +左臂 1 +x:1 +计划处 1 +x:1 +潜血 1 +x:1 +过路人 1 +x:1 +求生 1 +x:1 +海洋法 1 +x:1 +交错带 1 +x:1 +作案 1 +x:1 +次区域级 1 +x:1 +练习题 1 +x:1 +贸洽会 1 +x:1 +司法部长 1 +x:1 +石炭酸 1 +x:1 +五规范 1 +x:1 +天香国色 1 +x:1 +凝眸 1 +x:1 +生活感 1 +x:1 +凝眺 1 +x:1 +游艺厅 1 +x:1 +蹩 1 +x:1 +记要 1 +x:1 +赌徒 1 +x:1 +假条 1 +x:1 +一朝一夕 1 +x:1 +荣誉室 1 +x:1 +山羊肉 1 +x:1 +白鳞鱼 1 +x:1 +战俘营 1 +x:1 +崇 13 +x:13 +假果 1 +x:1 +地板砖 1 +x:1 +债务国 1 +x:1 +游艺卡 1 +x:1 +稳慎 1 +x:1 +珍禽 1 +x:1 +扬菜 1 +x:1 +疤瘌眼儿 1 +x:1 +嘛 70 +x:70 +双职工 1 +x:1 +豌豆黄 1 +x:1 +科技园区 1 +x:1 +参照 1 +x:1 +秋月当空 1 +x:1 +便宴 1 +x:1 +富翁 1 +x:1 +雨鞋 1 +x:1 +映入 1 +x:1 +图书日 1 +x:1 +响器 1 +x:1 +金庄村 1 +x:1 +租赁者 1 +x:1 +童装组 1 +x:1 +脱粒机 1 +x:1 +投资量 1 +x:1 +对称性 1 +x:1 +夏历 1 +x:1 +日出而作 1 +x:1 +芽茶 1 +x:1 +手榴弹 1 +x:1 +支持 1 +x:1 +鹰队 1 +x:1 +增长区 1 +x:1 +拳种 1 +x:1 +皇后 1 +x:1 +学子 1 +x:1 +清波微澜 1 +x:1 +眼神 1 +x:1 +山羊胡 1 +x:1 +生长量 1 +x:1 +强奸罪 1 +x:1 +轨范 1 +x:1 +随笔集 1 +x:1 +司法部门 1 +x:1 +挤奶房 1 +x:1 +皮毛 1 +x:1 +崖刻 1 +x:1 +苗区 1 +x:1 +国内外 1 +x:1 +农业园 1 +x:1 +一切 1 +x:1 +魏茨 1 +x:1 +有毒 1 +x:1 +引河 1 +x:1 +接收者 1 +x:1 +农业国 1 +x:1 +旺苍县 1 +x:1 +眼皮 1 +x:1 +参统 1 +x:1 +无憾 1 +x:1 +花城 1 +x:1 +顺风 1 +x:1 +歙砚 1 +x:1 +藏历 1 +x:1 +意具神足 1 +x:1 +假根 1 +x:1 +藏原 1 +x:1 +生存线 1 +x:1 +张嘴 1 +x:1 +熙和恬静 1 +x:1 +一刻 1 +x:1 +兴化市 1 +x:1 +救济款 1 +x:1 +投保者 1 +x:1 +程序名 1 +x:1 +深过冷 1 +x:1 +呈 283 +x:283 +无名英雄 1 +x:1 +声障 1 +x:1 +赎 4 +x:4 +北黑石村 1 +x:1 +必要条件 1 +x:1 +哄吵声 1 +x:1 +饮食起居 1 +x:1 +花型 1 +x:1 +无纸化 1 +x:1 +假案 1 +x:1 +皇家 1 +x:1 +止 114 +x:114 +干着急 1 +x:1 +过来人 1 +x:1 +探明 1 +x:1 +词义 1 +x:1 +涉水 1 +x:1 +禁毒办 1 +x:1 +作登乡 1 +x:1 +意图 1 +x:1 +皇室 1 +x:1 +扶优扶强 1 +x:1 +无所不为 1 +x:1 +皇宫 1 +x:1 +爆发音 1 +x:1 +欺侮 1 +x:1 +甘怡 1 +x:1 +无愧 1 +x:1 +皇子 1 +x:1 +响箭 1 +x:1 +互聘 1 +x:1 +花坛 1 +x:1 +寨头 1 +x:1 +藏匿 1 +x:1 +三晋 1 +x:1 +轴重 1 +x:1 +藏医 1 +x:1 +藏区 1 +x:1 +顺顺 1 +x:1 +崇礼乡 1 +x:1 +一力 1 +x:1 +围着 1 +x:1 +词人 1 +x:1 +昏定晨省 1 +x:1 +订 127 +x:127 +税名 1 +x:1 +税后 1 +x:1 +王者师 1 +x:1 +铝矿 1 +x:1 +托莱多 1 +x:1 +芽豆 1 +x:1 +黄寺 1 +x:1 +活字印刷 1 +x:1 +藏北 1 +x:1 +鑫光 1 +x:1 +年满 1 +x:1 +词令 1 +x:1 +蜗居 1 +x:1 +片 920 +x:920 +杂志社 1 +x:1 +腐朽 1 +x:1 +花圃 1 +x:1 +阶石 1 +x:1 +痛苦期 1 +x:1 +灼亮 1 +x:1 +花圈 1 +x:1 +抛物 1 +x:1 +藏印 1 +x:1 +入伍 1 +x:1 +入伏 1 +x:1 +摊点 1 +x:1 +学员 1 +x:1 +花场 1 +x:1 +金寨县 1 +x:1 +转轮 1 +x:1 +硼肥 1 +x:1 +入伙 1 +x:1 +入会 1 +x:1 +藏南 1 +x:1 +多角亭 1 +x:1 +存而不论 1 +x:1 +三昧 1 +x:1 +沿着 1 +x:1 +葡萄酒业 1 +x:1 +围盘 1 +x:1 +凝神 1 +x:1 +招募 1 +x:1 +戒 58 +x:58 +算 509 +x:509 +高 6253 +x:6253 +送还 1 +x:1 +中道 1 +x:1 +声音 1 +x:1 +声韵 1 +x:1 +鲜明性 1 +x:1 +停机 1 +x:1 +花团 1 +x:1 +相连 1 +x:1 +单季 1 +x:1 +无悔 1 +x:1 +桌灯 1 +x:1 +入仕 1 +x:1 +切断 1 +x:1 +欺世 1 +x:1 +律管司 1 +x:1 +花园 1 +x:1 +民心亭 1 +x:1 +一半 1 +x:1 +下雪天 1 +x:1 +俱佳 1 +x:1 +獭兔 1 +x:1 +灼伤 1 +x:1 +张贴物 1 +x:1 +峙 21 +x:21 +傻傻的 1 +x:1 +孕妇 1 +x:1 +开户者 1 +x:1 +电离 1 +x:1 +无情 1 +x:1 +克音河乡 1 +x:1 +若果 1 +x:1 +大会计 1 +x:1 +富民路 1 +x:1 +斑茅 1 +x:1 +加盟者 1 +x:1 +武周山 1 +x:1 +粗放式 1 +x:1 +探望 1 +x:1 +眼眶 1 +x:1 +探查 1 +x:1 +涅像 1 +x:1 +眼眵 1 +x:1 +集团化 1 +x:1 +海洋戏 1 +x:1 +话话 1 +x:1 +编辑奖 1 +x:1 +不甘落后 1 +x:1 +区党委 1 +x:1 +每逢 1 +x:1 +伏 36 +x:36 +高人一等 1 +x:1 +赌具 1 +x:1 +笺纸 1 +x:1 +人阵 1 +x:1 +篮 8 +x:8 +人防 1 +x:1 +豫东 1 +x:1 +话说 1 +x:1 +心头肉 1 +x:1 +招徕 1 +x:1 +三板 1 +x:1 +北郎中村 1 +x:1 +环保业 1 +x:1 +遮阳棚 1 +x:1 +藏刀 1 +x:1 +晚场 1 +x:1 +话语 1 +x:1 +王舍人镇 1 +x:1 +溺 1 +x:1 +眼看 1 +x:1 +大多数 1 +x:1 +高人一筹 1 +x:1 +小河坝村 1 +x:1 +白衣天使 1 +x:1 +灯泡厂 1 +x:1 +三期 1 +x:1 +海洋所 1 +x:1 +繁衍 1 +x:1 +无息 1 +x:1 +大脚洞 1 +x:1 +三月 1 +x:1 +龟背 1 +x:1 +入主 1 +x:1 +真空管 1 +x:1 +旷课 1 +x:1 +计划型 1 +x:1 +天亮 1 +x:1 +薪酬 1 +x:1 +三机 1 +x:1 +专科生 1 +x:1 +高雄市 1 +x:1 +眼睑 1 +x:1 +人际 1 +x:1 +不挑不拣 1 +x:1 +小麦量 1 +x:1 +费率 1 +x:1 +支派 1 +x:1 +阴柔之美 1 +x:1 +摄入量 1 +x:1 +刊误表 1 +x:1 +无恙 1 +x:1 +楚庄乡 1 +x:1 +入出境 1 +x:1 +回收率 1 +x:1 +前程锦绣 1 +x:1 +皇姑 1 +x:1 +计划员 1 +x:1 +孤注一掷 1 +x:1 +漫天风雪 1 +x:1 +小界岭 1 +x:1 +摊牌 1 +x:1 +醒狮 1 +x:1 +正比 1 +x:1 +后台老板 1 +x:1 +怏然 1 +x:1 +资本论 1 +x:1 +主机房 1 +x:1 +枯坐 1 +x:1 +苇丛 1 +x:1 +诸城 1 +x:1 +农业品 1 +x:1 +墙头诗 1 +x:1 +百废俱兴 1 +x:1 +强奸犯 1 +x:1 +造假 1 +x:1 +贝伦 1 +x:1 +边 636 +x:636 +继从 1 +x:1 +五个好 1 +x:1 +品格 1 +x:1 +热病 1 +x:1 +严要求 1 +x:1 +热症 1 +x:1 +知识青年 1 +x:1 +苗床 1 +x:1 +阵子 1 +x:1 +辱骂 1 +x:1 +马拉松赛 1 +x:1 +无援 1 +x:1 +羞意 1 +x:1 +人间 1 +x:1 +秋叶原 1 +x:1 +粮仓 1 +x:1 +凝 9 +x:9 +学园 1 +x:1 +前款罪 1 +x:1 +山盖沟村 1 +x:1 +南平镇 1 +x:1 +中到大雪 1 +x:1 +上集乡 1 +x:1 +龙狮 1 +x:1 +唇吻 1 +x:1 +以民为本 1 +x:1 +作者 1 +x:1 +西西里路 1 +x:1 +排行 1 +x:1 +过问 1 +x:1 +桃花村 1 +x:1 +故障率 1 +x:1 +粮价 1 +x:1 +寻梦者 1 +x:1 +作家卷 1 +x:1 +过错 1 +x:1 +作料 1 +x:1 +国有股 1 +x:1 +黄姜 1 +x:1 +外行人 1 +x:1 +绿化志 1 +x:1 +肿瘤科 1 +x:1 +寓公 1 +x:1 +哥萨克人 1 +x:1 +潜滋暗长 1 +x:1 +咕哩村 1 +x:1 +健身车 1 +x:1 +薪 25 +x:25 +热电 1 +x:1 +栏柜 1 +x:1 +眼球 1 +x:1 +修修补补 1 +x:1 +教体委 1 +x:1 +继之 1 +x:1 +气势恢宏 1 +x:1 +五雷轰顶 1 +x:1 +郭镇 1 +x:1 +长跑节 1 +x:1 +反过来 1 +x:1 +异才 1 +x:1 +餐巾 1 +x:1 +烤面包片 1 +x:1 +俎 1 +x:1 +柬帖 1 +x:1 +泰山 1 +x:1 +潜藏 1 +x:1 +暴病 1 +x:1 +瞎眼树 1 +x:1 +相谈 1 +x:1 +技术学校 1 +x:1 +漏光 1 +x:1 +寨子 1 +x:1 +精辟 1 +x:1 +招儿 1 +x:1 +漂浮物 1 +x:1 +支渠 1 +x:1 +遵从 1 +x:1 +锥体 1 +x:1 +鸡毛蒜皮 1 +x:1 +另眼相待 1 +x:1 +用粮 1 +x:1 +印有 1 +x:1 +赤铁矿 1 +x:1 +无损 1 +x:1 +图画课 1 +x:1 +起重船 1 +x:1 +羊肠线 1 +x:1 +花子 1 +x:1 +集团军 1 +x:1 +窃密 1 +x:1 +残疾金 1 +x:1 +哄吓 1 +x:1 +导流明渠 1 +x:1 +千伏安 1 +x:1 +优选 1 +x:1 +尚 641 +x:641 +修理铺 1 +x:1 +疟 1 +x:1 +沂水 1 +x:1 +两脚规 1 +x:1 +三旱 1 +x:1 +费工 1 +x:1 +丹桂 1 +x:1 +泥沼化 1 +x:1 +哄堂大笑 1 +x:1 +三时 1 +x:1 +扮相 1 +x:1 +密码式 1 +x:1 +相距 1 +x:1 +花哨 1 +x:1 +声门 1 +x:1 +三日 1 +x:1 +特邀函 1 +x:1 +一元 1 +x:1 +粘土 1 +x:1 +崇拜 1 +x:1 +宣传队 1 +x:1 +滑板 1 +x:1 +暌 1 +x:1 +翼城 1 +x:1 +税基 1 +x:1 +虾皮 1 +x:1 +生殖腺 1 +x:1 +拐弯 1 +x:1 +弄潮 1 +x:1 +精毛 1 +x:1 +绿化带 1 +x:1 +厚茧 1 +x:1 +眼病 1 +x:1 +滑杆 1 +x:1 +高蹈派 1 +x:1 +三教 1 +x:1 +柳林县 1 +x:1 +答辩状 1 +x:1 +亚热带 1 +x:1 +那口子 1 +x:1 +科技局 1 +x:1 +一再 1 +x:1 +秋庄稼 1 +x:1 +掐 12 +x:12 +助残椅 1 +x:1 +预编 1 +x:1 +蜂巢状 1 +x:1 +晚唐 1 +x:1 +逻辑推理 1 +x:1 +眼用 1 +x:1 +轿子山镇 1 +x:1 +戏说 1 +x:1 +蔚然兴起 1 +x:1 +舌炎 1 +x:1 +罗布淖尔 1 +x:1 +黄壤 1 +x:1 +小花脸 1 +x:1 +花呢 1 +x:1 +羞惭 1 +x:1 +访华团 1 +x:1 +继位 1 +x:1 +赌博 1 +x:1 +九华山 1 +x:1 +风吹日晒 1 +x:1 +禁用品 1 +x:1 +一准 1 +x:1 +龟苗 1 +x:1 +蓝点鲅 1 +x:1 +戏词 1 +x:1 +风俗画 1 +x:1 +活鸡 1 +x:1 +抚今忆昔 1 +x:1 +排解 1 +x:1 +掠夺 1 +x:1 +一度 1 +x:1 +潇湘 1 +x:1 +芭蕉叶 1 +x:1 +三改 1 +x:1 +送货 1 +x:1 +受精法 1 +x:1 +共产党人 1 +x:1 +子星 1 +x:1 +勾肩搭背 1 +x:1 +业主 1 +x:1 +眼界 1 +x:1 +卧蚕眉 1 +x:1 +避难 1 +x:1 +引以自豪 1 +x:1 +丝丝 1 +x:1 +穷光蛋 1 +x:1 +出神入化 1 +x:1 +停战 1 +x:1 +任其自然 1 +x:1 +涉案 1 +x:1 +天从人愿 1 +x:1 +察觉 1 +x:1 +健翔桥 1 +x:1 +旧县镇 1 +x:1 +无方 1 +x:1 +花台 1 +x:1 +轻舟 1 +x:1 +类义词 1 +x:1 +花叶 1 +x:1 +面相 1 +x:1 +岫 2 +x:2 +学堂 1 +x:1 +甲种粒子 1 +x:1 +商埠 1 +x:1 +修理点 1 +x:1 +度假 1 +x:1 +核 250 +x:250 +蒸气 1 +x:1 +车门 1 +x:1 +腮颊 1 +x:1 +绿化处 1 +x:1 +无日 1 +x:1 +珍物 1 +x:1 +戕害 1 +x:1 +氧分压 1 +x:1 +封建把头 1 +x:1 +无时 1 +x:1 +学僧 1 +x:1 +被减数 1 +x:1 +每间 1 +x:1 +停手 1 +x:1 +集体股 1 +x:1 +见面 1 +x:1 +鬼门关 1 +x:1 +回顾 1 +x:1 +剧毒级 1 +x:1 +文学革命 1 +x:1 +储电量 1 +x:1 +探戈 1 +x:1 +弱冷空气 1 +x:1 +花县 1 +x:1 +洋洋自得 1 +x:1 +赌咒 1 +x:1 +寄主 1 +x:1 +三言两语 1 +x:1 +无可辩驳 1 +x:1 +轻金属 1 +x:1 +拿 1240 +x:1240 +唯我主义 1 +x:1 +堃 1 +x:1 +双林队 1 +x:1 +气度不凡 1 +x:1 +灰心丧气 1 +x:1 +建华路 1 +x:1 +作比 1 +x:1 +反应塔 1 +x:1 +谷贱伤农 1 +x:1 +三手 1 +x:1 +鲜红色 1 +x:1 +非结晶 1 +x:1 +绿化委 1 +x:1 +花卉 1 +x:1 +星号 1 +x:1 +冰球赛 1 +x:1 +规模性 1 +x:1 +夜景 1 +x:1 +花卷 1 +x:1 +发放量 1 +x:1 +精气 1 +x:1 +无尽无休 1 +x:1 +守土有责 1 +x:1 +罗致 1 +x:1 +特尼河 1 +x:1 +国难日 1 +x:1 +型焦 1 +x:1 +寄予 1 +x:1 +海洋权 1 +x:1 +个贷 1 +x:1 +丘陵区 1 +x:1 +抛砖引玉 1 +x:1 +围猎 1 +x:1 +无数 1 +x:1 +军舰 1 +x:1 +学塾 1 +x:1 +避险 1 +x:1 +药瓶 1 +x:1 +免征 1 +x:1 +名正言顺 1 +x:1 +非会员 1 +x:1 +反应堆 1 +x:1 +泠 6 +x:6 +不可思议 1 +x:1 +无故 1 +x:1 +无效 1 +x:1 +无敌 1 +x:1 +花匠 1 +x:1 +富港村 1 +x:1 +采煤工 1 +x:1 +银光 1 +x:1 +科学部 1 +x:1 +初见成效 1 +x:1 +公社化 1 +x:1 +电池厂 1 +x:1 +骄艳 1 +x:1 +崖壁 1 +x:1 +救济户 1 +x:1 +情景交融 1 +x:1 +作成 1 +x:1 +精液 1 +x:1 +作战 1 +x:1 +农业司 1 +x:1 +铝片 1 +x:1 +糊糊 1 +x:1 +集团型 1 +x:1 +巴格达 1 +x:1 +丢 142 +x:142 +相识 1 +x:1 +在先 1 +x:1 +黄广 1 +x:1 +支槽 1 +x:1 +雪挂 1 +x:1 +猴 7 +x:7 +自助式 1 +x:1 +命名 1 +x:1 +兴城市 1 +x:1 +大分子 1 +x:1 +电视部 1 +x:1 +藏园 1 +x:1 +鹂 3 +x:3 +火车头队 1 +x:1 +精深 1 +x:1 +异族 1 +x:1 +潜艇 1 +x:1 +热狗 1 +x:1 +黄帝 1 +x:1 +富甲 1 +x:1 +一块 1 +x:1 +羞明 1 +x:1 +篇什 1 +x:1 +检测点 1 +x:1 +言犹未尽 1 +x:1 +预科 1 +x:1 +任贤 1 +x:1 +糊精 1 +x:1 +茶资 1 +x:1 +片马丫口 1 +x:1 +窃听 1 +x:1 +农业厅 1 +x:1 +儿童画 1 +x:1 +畦埂 1 +x:1 +黄帽 1 +x:1 +制动器 1 +x:1 +疾风 1 +x:1 +藤壶 1 +x:1 +石首市 1 +x:1 +旻 3 +x:3 +花剑 1 +x:1 +内服 1 +x:1 +哪边 1 +x:1 +活页 1 +x:1 +一型 1 +x:1 +珍玩 1 +x:1 +张张 1 +x:1 +展露 1 +x:1 +拳王 1 +x:1 +易懂 1 +x:1 +掠影 1 +x:1 +患难 1 +x:1 +战备 1 +x:1 +连篇累牍 1 +x:1 +写经 1 +x:1 +科罗拉多 1 +x:1 +计划司 1 +x:1 +济柴 1 +x:1 +对攻战 1 +x:1 +虚惊 1 +x:1 +新德里市 1 +x:1 +急功近利 1 +x:1 +寄信 1 +x:1 +宣传部 1 +x:1 +苗女 1 +x:1 +闭门羹 1 +x:1 +盖然性 1 +x:1 +壁峰相连 1 +x:1 +邮电 1 +x:1 +稳步 1 +x:1 +攻打 1 +x:1 +学兵 1 +x:1 +普速 1 +x:1 +武威 1 +x:1 +厚薄 1 +x:1 +皇帝 1 +x:1 +学养 1 +x:1 +哓哓不休 1 +x:1 +空车费 1 +x:1 +步人后尘 1 +x:1 +农业区 1 +x:1 +捕渔业 1 +x:1 +游猎 1 +x:1 +徐都 1 +x:1 +矜 4 +x:4 +象 16 +x:16 +想到 1 +x:1 +年报 1 +x:1 +兴庆宫 1 +x:1 +育草 1 +x:1 +候工室 1 +x:1 +含磷量 1 +x:1 +公路费 1 +x:1 +滞拨 1 +x:1 +香蕉水 1 +x:1 +高枕而卧 1 +x:1 +接连不断 1 +x:1 +牵 78 +x:78 +效益化 1 +x:1 +桃花节 1 +x:1 +旷远 1 +x:1 +毛湖村 1 +x:1 +厉 45 +x:45 +税务 1 +x:1 +紧邻 1 +x:1 +一同 1 +x:1 +热熔 1 +x:1 +一向 1 +x:1 +承包款 1 +x:1 +迎头赶上 1 +x:1 +脸谱化 1 +x:1 +大鸣门桥 1 +x:1 +玉簪记 1 +x:1 +惹事 1 +x:1 +双江村 1 +x:1 +学力 1 +x:1 +砌有 1 +x:1 +访华 1 +x:1 +饿殍 1 +x:1 +声部 1 +x:1 +腾骧 1 +x:1 +见机而行 1 +x:1 +无果 1 +x:1 +电磨 1 +x:1 +生产大队 1 +x:1 +扬言 1 +x:1 +灼圃乡 1 +x:1 +随群 1 +x:1 +部件 1 +x:1 +花农 1 +x:1 +贺岁喜剧 1 +x:1 +奇冤 1 +x:1 +罐头瓶 1 +x:1 +过量 1 +x:1 +过重 1 +x:1 +眼热 1 +x:1 +羊饲养业 1 +x:1 +占居 1 +x:1 +海防区 1 +x:1 +占地 1 +x:1 +花冠 1 +x:1 +恍恍惚惚 1 +x:1 +和生行 1 +x:1 +新界乡 1 +x:1 +漆器业 1 +x:1 +停息 1 +x:1 +不切实际 1 +x:1 +见长 1 +x:1 +税利 1 +x:1 +凝结 1 +x:1 +沙蚕属 1 +x:1 +上台 1 +x:1 +紧逼 1 +x:1 +送行 1 +x:1 +神冈町 1 +x:1 +黄州 1 +x:1 +珲春市 1 +x:1 +爱岗争优 1 +x:1 +悔 16 +x:16 +凝练 1 +x:1 +蜂窝煤厂 1 +x:1 +无机 1 +x:1 +国统矿 1 +x:1 +浅井村 1 +x:1 +就里 1 +x:1 +年检 1 +x:1 +冶金 1 +x:1 +亚运史 1 +x:1 +棘刺 1 +x:1 +部下 1 +x:1 +浦东区 1 +x:1 +访友 1 +x:1 +学分 1 +x:1 +枯叶 1 +x:1 +学刊 1 +x:1 +无期 1 +x:1 +道歉不迭 1 +x:1 +一品 1 +x:1 +三思 1 +x:1 +侗族 1 +x:1 +兔肉 1 +x:1 +三怕 1 +x:1 +声速 1 +x:1 +东西南北 1 +x:1 +全译本 1 +x:1 +栓皮 1 +x:1 +简阳市 1 +x:1 +比下有余 1 +x:1 +集体舞 1 +x:1 +无权 1 +x:1 +平衡圈 1 +x:1 +税前 1 +x:1 +某 665 +x:665 +融融 1 +x:1 +鳇鱼 1 +x:1 +花儿 1 +x:1 +投资额 1 +x:1 +有洪 1 +x:1 +一元方程 1 +x:1 +邪门儿 1 +x:1 +献花者 1 +x:1 +厚今薄古 1 +x:1 +见闻 1 +x:1 +披发左衽 1 +x:1 +旅游界 1 +x:1 +三性 1 +x:1 +新民县 1 +x:1 +御林军 1 +x:1 +重点定位 1 +x:1 +正本清源 1 +x:1 +温得和克 1 +x:1 +直喷式 1 +x:1 +修理部 1 +x:1 +热炕 1 +x:1 +滞胀 1 +x:1 +胡家圩村 1 +x:1 +预算 1 +x:1 +三懂 1 +x:1 +奥斯威辛 1 +x:1 +屹然 1 +x:1 +罹下 1 +x:1 +无暇 1 +x:1 +眼熟 1 +x:1 +相见 1 +x:1 +旱伞 1 +x:1 +听骨 1 +x:1 +苗寨 1 +x:1 +孟加拉虎 1 +x:1 +转型期 1 +x:1 +常绿植物 1 +x:1 +丹江 1 +x:1 +四川队 1 +x:1 +热点 1 +x:1 +黄山 1 +x:1 +皇岗 1 +x:1 +费用 1 +x:1 +空穴来风 1 +x:1 +不入流 1 +x:1 +学号 1 +x:1 +智勇双全 1 +x:1 +解释学 1 +x:1 +热烈 1 +x:1 +游艺室 1 +x:1 +单耳旁儿 1 +x:1 +起点站 1 +x:1 +黄尘 1 +x:1 +种植业史 1 +x:1 +几何级数 1 +x:1 +原稿纸 1 +x:1 +程序化 1 +x:1 +作恶 1 +x:1 +栉风沐雨 1 +x:1 +长海县 1 +x:1 +子棉 1 +x:1 +蛋白石 1 +x:1 +醉眼 1 +x:1 +求索 1 +x:1 +雁过留声 1 +x:1 +话费 1 +x:1 +藏品 1 +x:1 +一统志 1 +x:1 +苗家 1 +x:1 +镣铐 1 +x:1 +麻竹坪 1 +x:1 +油脂厂 1 +x:1 +学友 1 +x:1 +专科率 1 +x:1 +宇宙飞船 1 +x:1 +基辅市 1 +x:1 +白马村 1 +x:1 +腐恶 1 +x:1 +兵事 1 +x:1 +唇 3 +x:3 +过速 1 +x:1 +大藏省 1 +x:1 +学区 1 +x:1 +人造 1 +x:1 +主力舰 1 +x:1 +亲如手足 1 +x:1 +耕 33 +x:33 +侦破组 1 +x:1 +苗子 1 +x:1 +富矿 1 +x:1 +单衣服 1 +x:1 +同形词 1 +x:1 +续期 1 +x:1 +部会 1 +x:1 +侠 15 +x:15 +部优 1 +x:1 +人选 1 +x:1 +误餐费 1 +x:1 +无期限 1 +x:1 +招呼 1 +x:1 +农业党 1 +x:1 +换机 1 +x:1 +瓦岗军 1 +x:1 +兴高彩烈 1 +x:1 +○ 34 +x:34 +过道 1 +x:1 +单纸张 1 +x:1 +蓝点颏 1 +x:1 +修订会 1 +x:1 +渗透法 1 +x:1 +税卡 1 +x:1 +老人院 1 +x:1 +子房 1 +x:1 +疾驶 1 +x:1 +准自传体 1 +x:1 +调嘴弄舌 1 +x:1 +黄岛 1 +x:1 +暴烈 1 +x:1 +名牌车 1 +x:1 +赌场 1 +x:1 +文物法 1 +x:1 +播放 1 +x:1 +边海防 1 +x:1 +三愿 1 +x:1 +黄岩 1 +x:1 +过火 1 +x:1 +潜能 1 +x:1 +铿锵有力 1 +x:1 +热火 1 +x:1 +硫化物 1 +x:1 +家长会 1 +x:1 +铲 36 +x:36 +姐妹饭 1 +x:1 +部位 1 +x:1 +瘸子 1 +x:1 +税单 1 +x:1 +有氧 1 +x:1 +人道 1 +x:1 +娴熟 1 +x:1 +作难 1 +x:1 +冠名者 1 +x:1 +结论书 1 +x:1 +钳子 1 +x:1 +达瓦卡 1 +x:1 +光泽度 1 +x:1 +励精图治 1 +x:1 +鸳鸯桥 1 +x:1 +类推 1 +x:1 +车船费 1 +x:1 +骧 1 +x:1 +噩运 1 +x:1 +京都市 1 +x:1 +非现金 1 +x:1 +法餐 1 +x:1 +紫金鱼袋 1 +x:1 +成分 1 +x:1 +马山 1 +x:1 +讲授团 1 +x:1 +人多嘴杂 1 +x:1 +秦栏 1 +x:1 +预习 1 +x:1 +捂 13 +x:13 +熊牛 1 +x:1 +准格尔旗 1 +x:1 +太平梯 1 +x:1 +微重力 1 +x:1 +交媾 1 +x:1 +雁塔 1 +x:1 +电脑房 1 +x:1 +有生以来 1 +x:1 +一瞥 1 +x:1 +背兜 1 +x:1 +整机 1 +x:1 +酿酒部 1 +x:1 +完全式 1 +x:1 +鸟音 1 +x:1 +夹层墙 1 +x:1 +蹈袭 1 +x:1 +马尾 1 +x:1 +罪过 1 +x:1 +本分 1 +x:1 +破土 1 +x:1 +转子 1 +x:1 +用人权 1 +x:1 +乐陵 1 +x:1 +本刊 1 +x:1 +评选办 1 +x:1 +藏学家 1 +x:1 +玛札塔格 1 +x:1 +傣家 1 +x:1 +弥足 1 +x:1 +科巴 1 +x:1 +捣蛋 1 +x:1 +楷式 1 +x:1 +就位 1 +x:1 +尚武 1 +x:1 +核爆 1 +x:1 +成功 1 +x:1 +本利 1 +x:1 +次氯酸钠 1 +x:1 +教育会 1 +x:1 +停步 1 +x:1 +京都府 1 +x:1 +分体机 1 +x:1 +昏迷不醒 1 +x:1 +插手 1 +x:1 +整枝 1 +x:1 +保护神 1 +x:1 +泽州县 1 +x:1 +协派 1 +x:1 +呆头呆脑 1 +x:1 +甜岛 1 +x:1 +重头之作 1 +x:1 +傧相 1 +x:1 +博物馆界 1 +x:1 +掀翻 1 +x:1 +马岛 1 +x:1 +缘木求鱼 1 +x:1 +层次化 1 +x:1 +本剧 1 +x:1 +收集 1 +x:1 +等比级数 1 +x:1 +凭祥市 1 +x:1 +抢劫案 1 +x:1 +乐队 1 +x:1 +镇平 1 +x:1 +农垦区 1 +x:1 +飞扬跋扈 1 +x:1 +新闻奖 1 +x:1 +令人发指 1 +x:1 +捏腔拿调 1 +x:1 +元氏 1 +x:1 +大猩猩 1 +x:1 +乐音 1 +x:1 +钟琴 1 +x:1 +本厂 1 +x:1 +乐韵 1 +x:1 +南头镇 1 +x:1 +饱经沧桑 1 +x:1 +千禧龙 1 +x:1 +温泉镇 1 +x:1 +分类造册 1 +x:1 +血流变 1 +x:1 +本原 1 +x:1 +烂摊子 1 +x:1 +也好 1 +x:1 +告饶 1 +x:1 +如饥如渴 1 +x:1 +熟食品 1 +x:1 +表明 1 +x:1 +磋商权 1 +x:1 +熊猫 1 +x:1 +本县 1 +x:1 +木生菌 1 +x:1 +水力发电 1 +x:1 +暖水域 1 +x:1 +碳酰基 1 +x:1 +邢台市 1 +x:1 +厂址 1 +x:1 +瞳人 1 +x:1 +凋 5 +x:5 +深圳岭 1 +x:1 +心潮起伏 1 +x:1 +芷江 1 +x:1 +蓝布 1 +x:1 +武术界 1 +x:1 +鸟雀 1 +x:1 +外交辞令 1 +x:1 +家谱 1 +x:1 +通商部 1 +x:1 +浮冰 1 +x:1 +热气球 1 +x:1 +美丝丝 1 +x:1 +画蛇添足 1 +x:1 +偏材 1 +x:1 +上卷 1 +x:1 +助力泵 1 +x:1 +从心所欲 1 +x:1 +章凤镇 1 +x:1 +前程似锦 1 +x:1 +图强 1 +x:1 +冷冻厂 1 +x:1 +贵宾楼 1 +x:1 +书面语 1 +x:1 +独唱家 1 +x:1 +异化期 1 +x:1 +南天门 1 +x:1 +畸变 1 +x:1 +放长线 1 +x:1 +表征 1 +x:1 +没得说的 1 +x:1 +古天文学 1 +x:1 +塔里木 1 +x:1 +本区 1 +x:1 +交子 1 +x:1 +卷筒 1 +x:1 +驱寒 1 +x:1 +催产 1 +x:1 +埃元 1 +x:1 +光子 1 +x:1 +造型光 1 +x:1 +熊集镇 1 +x:1 +圆球 1 +x:1 +大师级 1 +x:1 +长镜头 1 +x:1 +基层网 1 +x:1 +雷声 1 +x:1 +周转性 1 +x:1 +就业观 1 +x:1 +特长生 1 +x:1 +扶贫助困 1 +x:1 +妇教所 1 +x:1 +广州省 1 +x:1 +航向 1 +x:1 +航后 1 +x:1 +沂南 1 +x:1 +卷 296 +x:296 +十三日 1 +x:1 +雹子 1 +x:1 +在内 1 +x:1 +光学 1 +x:1 +奋笔疾书 1 +x:1 +益气活血 1 +x:1 +北海道 1 +x:1 +旅者 1 +x:1 +厂名 1 +x:1 +落落大方 1 +x:1 +粘液层 1 +x:1 +闺女 1 +x:1 +小小的 1 +x:1 +垦荒 1 +x:1 +举手投足 1 +x:1 +整整 1 +x:1 +埃加 1 +x:1 +千家峒 1 +x:1 +整数 1 +x:1 +马年 1 +x:1 +京戏 1 +x:1 +禽 23 +x:23 +格律 1 +x:1 +成倍 1 +x:1 +以工代干 1 +x:1 +推进器 1 +x:1 +茶毛虫 1 +x:1 +演艺 1 +x:1 +畏罪 1 +x:1 +浊 10 +x:10 +盔甲 1 +x:1 +翩然 1 +x:1 +浮力 1 +x:1 +形象战 1 +x:1 +稀稀拉拉 1 +x:1 +生石灰 1 +x:1 +复线 1 +x:1 +浮动 1 +x:1 +醇芳 1 +x:1 +犬儒主义 1 +x:1 +整改 1 +x:1 +马帮 1 +x:1 +比尔 1 +x:1 +补报机 1 +x:1 +玉色 1 +x:1 +临危不惧 1 +x:1 +投票率 1 +x:1 +水疗 1 +x:1 +脑海 1 +x:1 +一心 1 +x:1 +桑椹 1 +x:1 +陶瓷 1 +x:1 +到岸价 1 +x:1 +褪色 1 +x:1 +雷害 1 +x:1 +父权 1 +x:1 +荷兰猪 1 +x:1 +公会堂 1 +x:1 +悄然无声 1 +x:1 +薄薄的 1 +x:1 +县域 1 +x:1 +鸳鸯树 1 +x:1 +止降 1 +x:1 +一了百了 1 +x:1 +农技员 1 +x:1 +歌剧团 1 +x:1 +五角形 1 +x:1 +县城 1 +x:1 +昂然 1 +x:1 +基干 1 +x:1 +脑浆 1 +x:1 +格式 1 +x:1 +剖示 1 +x:1 +弧形槽 1 +x:1 +闲机 1 +x:1 +进出境 1 +x:1 +萨其马 1 +x:1 +讲道 1 +x:1 +瘦骨嶙峋 1 +x:1 +民营 1 +x:1 +糅进 1 +x:1 +盟约 1 +x:1 +失血性 1 +x:1 +马庙 1 +x:1 +浮利 1 +x:1 +水饺 1 +x:1 +艺术照 1 +x:1 +靠泊 1 +x:1 +监督会 1 +x:1 +谙知 1 +x:1 +抗雪 1 +x:1 +甜度 1 +x:1 +是可忍 1 +x:1 +乳 4 +x:4 +斯希波尔 1 +x:1 +赵 1495 +x:1495 +抗震 1 +x:1 +良师益友 1 +x:1 +德行 1 +x:1 +复合型 1 +x:1 +云谲波诡 1 +x:1 +鸭黄 1 +x:1 +代代 1 +x:1 +港情 1 +x:1 +二极管 1 +x:1 +经济特区 1 +x:1 +农资办 1 +x:1 +痰盂 1 +x:1 +冲锋陷阵 1 +x:1 +波斯菊 1 +x:1 +来信人 1 +x:1 +不绝如缕 1 +x:1 +自认倒霉 1 +x:1 +选本 1 +x:1 +代价 1 +x:1 +经济学说 1 +x:1 +架线 1 +x:1 +葱葱郁郁 1 +x:1 +桑梓 1 +x:1 +离经叛道 1 +x:1 +蓝山 1 +x:1 +颈前 1 +x:1 +温吞 1 +x:1 +横说竖说 1 +x:1 +H 11 +x:11 +蓬蓬 1 +x:1 +适应力 1 +x:1 +黏膜 1 +x:1 +干热 1 +x:1 +劲升 1 +x:1 +撅臀 1 +x:1 +交委 1 +x:1 +攻心为上 1 +x:1 +埃及 1 +x:1 +厂商 1 +x:1 +擂鼓筛锣 1 +x:1 +航运界 1 +x:1 +型砂 1 +x:1 +监督人 1 +x:1 +塔河 1 +x:1 +雅盖隆 1 +x:1 +代交 1 +x:1 +不辨菽麦 1 +x:1 +水龙吟 1 +x:1 +强项 1 +x:1 +成全 1 +x:1 +葚 1 +x:1 +撒谎 1 +x:1 +台球赛 1 +x:1 +矣 50 +x:50 +约会 1 +x:1 +脚夫 1 +x:1 +鸟铳 1 +x:1 +德文版 1 +x:1 +储油轮 1 +x:1 +朔城区 1 +x:1 +心理 1 +x:1 +鞭花 1 +x:1 +两厨一厕 1 +x:1 +寄宿式 1 +x:1 +游牧人 1 +x:1 +大金塔 1 +x:1 +烟火食 1 +x:1 +国管局 1 +x:1 +布吉镇 1 +x:1 +浮华 1 +x:1 +蜂拥而来 1 +x:1 +涛澜 1 +x:1 +延安 1 +x:1 +交好 1 +x:1 +光复 1 +x:1 +偏方 1 +x:1 +九江市 1 +x:1 +断层湖 1 +x:1 +代买 1 +x:1 +预防性 1 +x:1 +桑树 1 +x:1 +推进型 1 +x:1 +满篇 1 +x:1 +老师傅 1 +x:1 +光头 1 +x:1 +开拓者队 1 +x:1 +脑汁 1 +x:1 +东南西北 1 +x:1 +新址 1 +x:1 +温和 1 +x:1 +香烟盒纸 1 +x:1 +针砭 1 +x:1 +本儿 1 +x:1 +紧身恤 1 +x:1 +成册 1 +x:1 +面无人色 1 +x:1 +勇挑重担 1 +x:1 +脓肿 1 +x:1 +疗养员 1 +x:1 +交大 1 +x:1 +代为 1 +x:1 +哄劝 1 +x:1 +圪台子 1 +x:1 +春和景明 1 +x:1 +就业证 1 +x:1 +芥兰 1 +x:1 +凶吉难卜 1 +x:1 +深圳市 1 +x:1 +强风 1 +x:1 +胡涂 1 +x:1 +通达 1 +x:1 +双多向 1 +x:1 +天壤之别 1 +x:1 +偏旁 1 +x:1 +拉丁派 1 +x:1 +望桥 1 +x:1 +刘家 1 +x:1 +多义字 1 +x:1 +靠模 1 +x:1 +插曲 1 +x:1 +水龙 1 +x:1 +溶岩 1 +x:1 +璋 3 +x:3 +参赛者 1 +x:1 +语法学 1 +x:1 +购煤款 1 +x:1 +马塞 1 +x:1 +狐火 1 +x:1 +水龄 1 +x:1 +箅子 1 +x:1 +共同社 1 +x:1 +哈尔滨市 1 +x:1 +厥 1 +x:1 +赴死 1 +x:1 +曼曼地 1 +x:1 +储存量 1 +x:1 +安 366 +x:366 +对外商 1 +x:1 +凤岗镇 1 +x:1 +峨嵋岭 1 +x:1 +水龙卷 1 +x:1 +上下齐心 1 +x:1 +光度 1 +x:1 +材料费 1 +x:1 +黄继光连 1 +x:1 +联防队员 1 +x:1 +油气田 1 +x:1 +偏执 1 +x:1 +次大陆 1 +x:1 +淡如逝水 1 +x:1 +八音匣子 1 +x:1 +电势差 1 +x:1 +莫不 1 +x:1 +江东村 1 +x:1 +宣传站 1 +x:1 +营业厅 1 +x:1 +成器 1 +x:1 +商工人 1 +x:1 +跃然而起 1 +x:1 +三棉 1 +x:1 +礼宾司 1 +x:1 +无庸置疑 1 +x:1 +休宁县 1 +x:1 +本园 1 +x:1 +愧悔 1 +x:1 +久经沙场 1 +x:1 +蓬莱 1 +x:1 +凹 4 +x:4 +秦汉 1 +x:1 +本国 1 +x:1 +罪证 1 +x:1 +温升 1 +x:1 +石煤 1 +x:1 +散热 1 +x:1 +看护者 1 +x:1 +名誉权 1 +x:1 +米字形 1 +x:1 +下关区 1 +x:1 +燕京 1 +x:1 +严管 1 +x:1 +谙熟 1 +x:1 +千分号 1 +x:1 +交并 1 +x:1 +厂办 1 +x:1 +格外 1 +x:1 +另眼看待 1 +x:1 +温厚 1 +x:1 +厂务 1 +x:1 +綦 1 +x:1 +翻供 1 +x:1 +彼一时 1 +x:1 +视 170 +x:170 +留尼汪岛 1 +x:1 +直播 1 +x:1 +出关 1 +x:1 +望城乡 1 +x:1 +欧罗巴洲 1 +x:1 +擀 12 +x:12 +浮吊 1 +x:1 +浮名 1 +x:1 +民船 1 +x:1 +温台 1 +x:1 +代理权 1 +x:1 +计日程功 1 +x:1 +莫云 1 +x:1 +民航 1 +x:1 +两栖舰 1 +x:1 +格套 1 +x:1 +稻树 1 +x:1 +一笔带过 1 +x:1 +行世 1 +x:1 +喟叹 1 +x:1 +强化剂 1 +x:1 +峨嵋山 1 +x:1 +六道轮回 1 +x:1 +光年 1 +x:1 +农垦场 1 +x:1 +证婚人 1 +x:1 +港机 1 +x:1 +雷州 1 +x:1 +珺 33 +x:33 +南岛 1 +x:1 +瑶族 1 +x:1 +解放思想 1 +x:1 +举人 1 +x:1 +电脑板 1 +x:1 +果苗 1 +x:1 +中等教育 1 +x:1 +针纺 1 +x:1 +术语 1 +x:1 +针线 1 +x:1 +层面 1 +x:1 +墩 4 +x:4 +泥炭全肥 1 +x:1 +媳 1 +x:1 +浩如烟海 1 +x:1 +抗敌素 1 +x:1 +不亚于 1 +x:1 +措施法 1 +x:1 +发麻 1 +x:1 +常开不败 1 +x:1 +频谱 1 +x:1 +青海省 1 +x:1 +迭创新高 1 +x:1 +平畴沃野 1 +x:1 +扶持 1 +x:1 +弥补 1 +x:1 +莫伊 1 +x:1 +绵延不断 1 +x:1 +无妄之灾 1 +x:1 +实验费 1 +x:1 +百看不厌 1 +x:1 +驾驶 1 +x:1 +表扬 1 +x:1 +核军备 1 +x:1 +滴溜溜 1 +x:1 +激发源 1 +x:1 +派生词 1 +x:1 +甜头 1 +x:1 +院 390 +x:390 +交待 1 +x:1 +马夫 1 +x:1 +交往 1 +x:1 +马头 1 +x:1 +邮递员 1 +x:1 +沁水 1 +x:1 +凤毛麟角 1 +x:1 +以儆效尤 1 +x:1 +逃脱 1 +x:1 +马夹 1 +x:1 +搁 22 +x:22 +水鸟 1 +x:1 +桑芽儿 1 +x:1 +厂厂 1 +x:1 +财贸办 1 +x:1 +综合楼 1 +x:1 +干劲 1 +x:1 +脚踏式 1 +x:1 +桥板 1 +x:1 +插条 1 +x:1 +完成率 1 +x:1 +本土 1 +x:1 +反间计 1 +x:1 +表报 1 +x:1 +东宝区 1 +x:1 +巴林右旗 1 +x:1 +沙河市 1 +x:1 +童仆 1 +x:1 +酒垆 1 +x:1 +填鸭 1 +x:1 +农技协 1 +x:1 +狭谷 1 +x:1 +本地 1 +x:1 +审批人 1 +x:1 +成型 1 +x:1 +本场 1 +x:1 +贿赂 1 +x:1 +光弦 1 +x:1 +表彰会 1 +x:1 +萎靡 1 +x:1 +成培 1 +x:1 +支援性 1 +x:1 +杆儿 1 +x:1 +婕 4 +x:4 +替代品 1 +x:1 +大家伙儿 1 +x:1 +扫帚声 1 +x:1 +秦淮 1 +x:1 +乐亭县 1 +x:1 +水鹿 1 +x:1 +贡献率 1 +x:1 +闰年 1 +x:1 +光影 1 +x:1 +见见面 1 +x:1 +香蕉林 1 +x:1 +太平洋 1 +x:1 +光彩 1 +x:1 +乐悠悠 1 +x:1 +厂史 1 +x:1 +就业路 1 +x:1 +水鹤 1 +x:1 +西行路 1 +x:1 +瑰丽 1 +x:1 +往复 1 +x:1 +令人作呕 1 +x:1 +帐 3 +x:3 +抢镜头 1 +x:1 +左安门 1 +x:1 +工休日 1 +x:1 +秦港 1 +x:1 +胡桃 1 +x:1 +田径界 1 +x:1 +霞石 1 +x:1 +断 312 +x:312 +敏感区 1 +x:1 +成名 1 +x:1 +转账 1 +x:1 +洗衣机 1 +x:1 +清除率 1 +x:1 +鼻青脸肿 1 +x:1 +纵横有序 1 +x:1 +滁州 1 +x:1 +成命 1 +x:1 +控制法 1 +x:1 +种果 1 +x:1 +插播 1 +x:1 +淡泊名利 1 +x:1 +绿杨乡 1 +x:1 +乳燕营巢 1 +x:1 +备用金 1 +x:1 +推进剂 1 +x:1 +成员 1 +x:1 +鬼哭狼嚎 1 +x:1 +俱 36 +x:36 +保税区 1 +x:1 +被选举权 1 +x:1 +港方 1 +x:1 +硬功夫 1 +x:1 +合格证费 1 +x:1 +蓝天 1 +x:1 +物以类聚 1 +x:1 +塔楼 1 +x:1 +结业证 1 +x:1 +债务缠身 1 +x:1 +花池子 1 +x:1 +本名 1 +x:1 +保护编 1 +x:1 +资料箱 1 +x:1 +退休日 1 +x:1 +波斯虎 1 +x:1 +僵持 1 +x:1 +日光灯 1 +x:1 +乐道 1 +x:1 +烟酸 1 +x:1 +杏元屯 1 +x:1 +资环局 1 +x:1 +南市区 1 +x:1 +阜平县 1 +x:1 +两河三湖 1 +x:1 +综合治理 1 +x:1 +球类室 1 +x:1 +发火点 1 +x:1 +拖家带口 1 +x:1 +农牧渔业 1 +x:1 +钳工 1 +x:1 +县县 1 +x:1 +合金 1 +x:1 +干冷 1 +x:1 +名优特 1 +x:1 +苏桥 1 +x:1 +指令性 1 +x:1 +艺术界 1 +x:1 +越冬场 1 +x:1 +刘庄 1 +x:1 +格学 1 +x:1 +化脓 1 +x:1 +四轴挠性 1 +x:1 +发财梦 1 +x:1 +晴空万里 1 +x:1 +冷冻品 1 +x:1 +甚笃 1 +x:1 +喘气 1 +x:1 +周转期 1 +x:1 +霸州市 1 +x:1 +半空 1 +x:1 +挫败 1 +x:1 +光山 1 +x:1 +石灰窑 1 +x:1 +高等级 1 +x:1 +本周 1 +x:1 +转轮手枪 1 +x:1 +成品 1 +x:1 +怀疑者 1 +x:1 +资料篇 1 +x:1 +贾庄镇 1 +x:1 +交差 1 +x:1 +枕戈待旦 1 +x:1 +超乎 1 +x:1 +干草垛 1 +x:1 +墙报栏 1 +x:1 +交工 1 +x:1 +熏 14 +x:14 +增长极 1 +x:1 +特长班 1 +x:1 +捣腾 1 +x:1 +拜多阿 1 +x:1 +石荷州 1 +x:1 +勃然大怒 1 +x:1 +逃荒 1 +x:1 +留言簿 1 +x:1 +藤箱 1 +x:1 +游速 1 +x:1 +德恒所 1 +x:1 +靠椅 1 +x:1 +皎洁 1 +x:1 +四明山 1 +x:1 +有救 1 +x:1 +外国籍 1 +x:1 +比奇 1 +x:1 +表态 1 +x:1 +偷抗税案 1 +x:1 +凉茶铺 1 +x:1 +诺迪奥队 1 +x:1 +蓬勃向上 1 +x:1 +褐红色 1 +x:1 +愈演愈烈 1 +x:1 +画影像 1 +x:1 +螺口 1 +x:1 +寓 28 +x:28 +石版 1 +x:1 +遗弃者 1 +x:1 +本嗓 1 +x:1 +基层科 1 +x:1 +救护神 1 +x:1 +浇灌 1 +x:1 +石片 1 +x:1 +航务 1 +x:1 +蔷薇 1 +x:1 +坠 16 +x:16 +化肥 1 +x:1 +风云录 1 +x:1 +否定 1 +x:1 +鼻梁儿 1 +x:1 +水晶体 1 +x:1 +胡椒 1 +x:1 +哈欠 1 +x:1 +双层床 1 +x:1 +表演系 1 +x:1 +未卜先知 1 +x:1 +舟桥团 1 +x:1 +议事堂 1 +x:1 +蔓萝 1 +x:1 +贿选案 1 +x:1 +承先启后 1 +x:1 +核电 1 +x:1 +探囊取物 1 +x:1 +节地率 1 +x:1 +云头儿 1 +x:1 +末 422 +x:422 +蹊跷 1 +x:1 +不堪回首 1 +x:1 +芮 14 +x:14 +封建迷信 1 +x:1 +沁入心扉 1 +x:1 +举重若轻 1 +x:1 +就业 1 +x:1 +抽筋 1 +x:1 +沁源 1 +x:1 +戏园子 1 +x:1 +说不来 1 +x:1 +浮土 1 +x:1 +架空 1 +x:1 +汝 16 +x:16 +泗阳县 1 +x:1 +禁毒展 1 +x:1 +胳膊肘 1 +x:1 +坤 36 +x:36 +超交 1 +x:1 +超产 1 +x:1 +价重字 1 +x:1 +中高档 1 +x:1 +罪行 1 +x:1 +互联网 1 +x:1 +石狮 1 +x:1 +超人 1 +x:1 +兵机策 1 +x:1 +比如 1 +x:1 +藤筐 1 +x:1 +表情 1 +x:1 +姚伏 1 +x:1 +复瓣 1 +x:1 +塔柱 1 +x:1 +枕头箱 1 +x:1 +泌乳期 1 +x:1 +随着 1 +x:1 +就业者 1 +x:1 +锐不可当 1 +x:1 +文艺路 1 +x:1 +溆水 1 +x:1 +甜味 1 +x:1 +世博园 1 +x:1 +合作部 1 +x:1 +神奈川 1 +x:1 +琨 12 +x:12 +甘柒乡 1 +x:1 +摩擦点 1 +x:1 +表演 1 +x:1 +以次充好 1 +x:1 +拆除 1 +x:1 +侨声 1 +x:1 +见 1168 +x:1168 +云烟 1 +x:1 +塔架 1 +x:1 +圣科莫镇 1 +x:1 +西辛庄村 1 +x:1 +交加 1 +x:1 +投中 1 +x:1 +主动脉弓 1 +x:1 +特贫村 1 +x:1 +两系法 1 +x:1 +告退 1 +x:1 +虚无主义 1 +x:1 +卵白 1 +x:1 +卖主 1 +x:1 +类比 1 +x:1 +成婚 1 +x:1 +塔林 1 +x:1 +保荐人 1 +x:1 +交办 1 +x:1 +川剧团 1 +x:1 +相联 1 +x:1 +延迟 1 +x:1 +塔松 1 +x:1 +生产班 1 +x:1 +厂庆 1 +x:1 +比国 1 +x:1 +空怀 1 +x:1 +收麦 1 +x:1 +肉联厂 1 +x:1 +老毛病 1 +x:1 +被里 1 +x:1 +甜品 1 +x:1 +垫付 1 +x:1 +交割 1 +x:1 +赞颂 1 +x:1 +溆河 1 +x:1 +质管员 1 +x:1 +傣历 1 +x:1 +围塘机 1 +x:1 +居功自傲 1 +x:1 +驱动 1 +x:1 +安大略省 1 +x:1 +助人 1 +x:1 +四会 1 +x:1 +硅片 1 +x:1 +四优 1 +x:1 +主持台 1 +x:1 +花露水 1 +x:1 +埃塞 1 +x:1 +老塔村 1 +x:1 +隆回县 1 +x:1 +投产 1 +x:1 +雷击 1 +x:1 +螺山 1 +x:1 +受宠若惊 1 +x:1 +越盾 1 +x:1 +单眼皮 1 +x:1 +单纤细度 1 +x:1 +投井 1 +x:1 +平均主义 1 +x:1 +武术系 1 +x:1 +竹节虫 1 +x:1 +万山岛 1 +x:1 +折叠椅 1 +x:1 +陶瓷展 1 +x:1 +偻 1 +x:1 +追索权 1 +x:1 +胡来 1 +x:1 +磐石 1 +x:1 +胡杨 1 +x:1 +全织物 1 +x:1 +交口 1 +x:1 +交叠 1 +x:1 +光压 1 +x:1 +平衡表 1 +x:1 +延边 1 +x:1 +价格 1 +x:1 +一衣带水 1 +x:1 +温带 1 +x:1 +民运 1 +x:1 +八廓街 1 +x:1 +缤 1 +x:1 +交叉 1 +x:1 +大别山 1 +x:1 +民进 1 +x:1 +可解析性 1 +x:1 +本家 1 +x:1 +盒装 1 +x:1 +夜曲 1 +x:1 +被关爱者 1 +x:1 +交变 1 +x:1 +为政不廉 1 +x:1 +粹 2 +x:2 +火区 1 +x:1 +逃走 1 +x:1 +核算 1 +x:1 +政见 1 +x:1 +古装片 1 +x:1 +满族镇 1 +x:1 +灰沉沉 1 +x:1 +玲珑 1 +x:1 +始 103 +x:103 +桑拿 1 +x:1 +昂立 1 +x:1 +上浮率 1 +x:1 +桥段 1 +x:1 +叶枝 1 +x:1 +联体窑 1 +x:1 +配种站 1 +x:1 +渣土地 1 +x:1 +闹剧式 1 +x:1 +水龙带 1 +x:1 +焚烧厂 1 +x:1 +钳制 1 +x:1 +碰面 1 +x:1 +百般刁难 1 +x:1 +农机具馆 1 +x:1 +溆浦 1 +x:1 +郎溪县 1 +x:1 +政要 1 +x:1 +在场 1 +x:1 +黑绿色 1 +x:1 +辄 6 +x:6 +万寿寺 1 +x:1 +节气 1 +x:1 +邯郸学步 1 +x:1 +阳电子 1 +x:1 +核符 1 +x:1 +四九 1 +x:1 +雷锋 1 +x:1 +瀑 5 +x:5 +石粉 1 +x:1 +金柱村 1 +x:1 +商品流通 1 +x:1 +有机酸 1 +x:1 +交卷 1 +x:1 +逃跑 1 +x:1 +温度 1 +x:1 +投保 1 +x:1 +进出口 1 +x:1 +逃路 1 +x:1 +光荣牌 1 +x:1 +议而不决 1 +x:1 +蓝图 1 +x:1 +黄苓 1 +x:1 +温床 1 +x:1 +四书 1 +x:1 +扫把 1 +x:1 +靠枕 1 +x:1 +成安 1 +x:1 +鸟鸣 1 +x:1 +冷冻室 1 +x:1 +光棍儿 1 +x:1 +久 278 +x:278 +溶入 1 +x:1 +无可奈何 1 +x:1 +保安法 1 +x:1 +本字 1 +x:1 +本子 1 +x:1 +旌旗招展 1 +x:1 +四下 1 +x:1 +仇敌 1 +x:1 +四不 1 +x:1 +形态 1 +x:1 +大大小小 1 +x:1 +成寐 1 +x:1 +哈方 1 +x:1 +怜贫惜老 1 +x:1 +有言在先 1 +x:1 +一心一德 1 +x:1 +薄利 1 +x:1 +卵石 1 +x:1 +偏激 1 +x:1 +浮夸 1 +x:1 +法郎 1 +x:1 +主轴 1 +x:1 +信浓町 1 +x:1 +亏耗 1 +x:1 +复生 1 +x:1 +芥子 1 +x:1 +四中 1 +x:1 +有计划 1 +x:1 +双差生 1 +x:1 +保浇地 1 +x:1 +石缝 1 +x:1 +崖葬 1 +x:1 +黄陵县 1 +x:1 +总领事 1 +x:1 +皓 7 +x:7 +红花草头 1 +x:1 +列车长 1 +x:1 +涌现 1 +x:1 +复盲 1 +x:1 +雨靴 1 +x:1 +价款 1 +x:1 +理事 1 +x:1 +保护率 1 +x:1 +理亏 1 +x:1 +稠 6 +x:6 +洪江市 1 +x:1 +电脑桌 1 +x:1 +八宝山 1 +x:1 +透亮性 1 +x:1 +矿院 1 +x:1 +成堆 1 +x:1 +复盐 1 +x:1 +制造部 1 +x:1 +探戈曲 1 +x:1 +逼 115 +x:115 +旅行 1 +x:1 +桥梯 1 +x:1 +含咀 1 +x:1 +海伦市 1 +x:1 +清川江 1 +x:1 +威士忌 1 +x:1 +平泉县 1 +x:1 +娇贵 1 +x:1 +事与愿违 1 +x:1 +水量 1 +x:1 +借词 1 +x:1 +清议 1 +x:1 +强酸 1 +x:1 +痛经宁 1 +x:1 +橘子 1 +x:1 +购房户 1 +x:1 +反收购 1 +x:1 +生资 1 +x:1 +整洁 1 +x:1 +张祠乡 1 +x:1 +生意网 1 +x:1 +多躁少静 1 +x:1 +德意志 1 +x:1 +核磁 1 +x:1 +桥梁 1 +x:1 +任重道远 1 +x:1 +马嘶 1 +x:1 +检察部 1 +x:1 +卧伏 1 +x:1 +老松 1 +x:1 +大锅饭 1 +x:1 +纺锭 1 +x:1 +桥桩 1 +x:1 +松泉牌 1 +x:1 +紫砂 1 +x:1 +纺锤 1 +x:1 +螺帽 1 +x:1 +智术 1 +x:1 +救火队 1 +x:1 +侵害 1 +x:1 +田径馆 1 +x:1 +火电厂 1 +x:1 +曹庵镇 1 +x:1 +实效 1 +x:1 +喘息 1 +x:1 +电力部 1 +x:1 +县志 1 +x:1 +筏养底播 1 +x:1 +氯 4 +x:4 +越冬作物 1 +x:1 +风急浪大 1 +x:1 +投票箱 1 +x:1 +散结 1 +x:1 +反扑 1 +x:1 +中西餐 1 +x:1 +人书 1 +x:1 +垄坎 1 +x:1 +县徽 1 +x:1 +蹈舞 1 +x:1 +山地 1 +x:1 +曼哈顿 1 +x:1 +审核员 1 +x:1 +水酒 1 +x:1 +构造运动 1 +x:1 +民谣 1 +x:1 +温差 1 +x:1 +里程碑式 1 +x:1 +桥栏 1 +x:1 +粉蒸肉 1 +x:1 +温州 1 +x:1 +装卸量 1 +x:1 +滴水村 1 +x:1 +民谚 1 +x:1 +民调 1 +x:1 +插标 1 +x:1 +悠悠然 1 +x:1 +五线谱 1 +x:1 +箬竹 1 +x:1 +心安理得 1 +x:1 +传习 1 +x:1 +柳丝 1 +x:1 +强对流 1 +x:1 +药王庙 1 +x:1 +羊庄镇 1 +x:1 +喷灌区 1 +x:1 +县处级 1 +x:1 +清词丽句 1 +x:1 +万吨级 1 +x:1 +交出 1 +x:1 +游击队员 1 +x:1 +苏方 1 +x:1 +巡回演出 1 +x:1 +复矿 1 +x:1 +成天 1 +x:1 +抱 245 +x:245 +进出关 1 +x:1 +个体主义 1 +x:1 +单刀直入 1 +x:1 +脓血 1 +x:1 +促 168 +x:168 +洞体 1 +x:1 +阻燃网 1 +x:1 +歌剧式 1 +x:1 +西双坦村 1 +x:1 +轻型车 1 +x:1 +道义感 1 +x:1 +越界 1 +x:1 +河北村 1 +x:1 +传主 1 +x:1 +靖远 1 +x:1 +运河畔 1 +x:1 +嗜痂成癖 1 +x:1 +成套 1 +x:1 +坝沿 1 +x:1 +偏流 1 +x:1 +轻裘肥马 1 +x:1 +激发 1 +x:1 +传世 1 +x:1 +尿床 1 +x:1 +酸甜 1 +x:1 +引水员 1 +x:1 +马场 1 +x:1 +堂堂正正 1 +x:1 +木本植物 1 +x:1 +科室 1 +x:1 +传代 1 +x:1 +交公 1 +x:1 +绪 2 +x:2 +传令 1 +x:1 +绑架 1 +x:1 +昉 1 +x:1 +龟壳 1 +x:1 +理会 1 +x:1 +石灰石 1 +x:1 +演讲 1 +x:1 +石制品 1 +x:1 +上晃上晃 1 +x:1 +暗沟 1 +x:1 +温岭 1 +x:1 +飞黄腾达 1 +x:1 +强邻 1 +x:1 +浮子 1 +x:1 +政警 1 +x:1 +黑水 1 +x:1 +率先 1 +x:1 +不买账 1 +x:1 +真相大白 1 +x:1 +石纹 1 +x:1 +成都市 1 +x:1 +自决权 1 +x:1 +中成药 1 +x:1 +雷劈 1 +x:1 +渊流 1 +x:1 +酸痛 1 +x:1 +代表大会 1 +x:1 +敏感度 1 +x:1 +赫然 1 +x:1 +柳亭 1 +x:1 +字卷 1 +x:1 +竹制 1 +x:1 +洒红节 1 +x:1 +难 1493 +x:1493 +增供 1 +x:1 +比喻 1 +x:1 +相思子 1 +x:1 +谙练 1 +x:1 +水道 1 +x:1 +光光 1 +x:1 +报单 1 +x:1 +民财 1 +x:1 +石经 1 +x:1 +痔 1 +x:1 +酸疼 1 +x:1 +仇杀 1 +x:1 +传人 1 +x:1 +民质 1 +x:1 +山坞 1 +x:1 +捧腹大笑 1 +x:1 +芳溪镇 1 +x:1 +投票站 1 +x:1 +平面波 1 +x:1 +针灸 1 +x:1 +单摆 1 +x:1 +石绿 1 +x:1 +整治 1 +x:1 +报之以李 1 +x:1 +马里兰 1 +x:1 +修理业 1 +x:1 +激发态 1 +x:1 +演词 1 +x:1 +靠旗 1 +x:1 +冰封雪裹 1 +x:1 +生意经 1 +x:1 +尿布 1 +x:1 +开发业 1 +x:1 +古蔺县 1 +x:1 +人工授精 1 +x:1 +黄渡 1 +x:1 +高于 1 +x:1 +高二 1 +x:1 +横格纸 1 +x:1 +核红 1 +x:1 +调色板 1 +x:1 +八仙包 1 +x:1 +爆发力 1 +x:1 +海流图乡 1 +x:1 +诺曼第 1 +x:1 +汉语系 1 +x:1 +高云 1 +x:1 +省力 1 +x:1 +按劳取酬 1 +x:1 +庭院式 1 +x:1 +酝酿期 1 +x:1 +青出于蓝 1 +x:1 +高亢 1 +x:1 +强震 1 +x:1 +桑枝 1 +x:1 +高产 1 +x:1 +高人 1 +x:1 +冰球史 1 +x:1 +广州站 1 +x:1 +动人魂魄 1 +x:1 +措手不及 1 +x:1 +派送 1 +x:1 +欲罢不能 1 +x:1 +纬书 1 +x:1 +成年 1 +x:1 +马倌 1 +x:1 +铅灰色 1 +x:1 +膳费 1 +x:1 +生产区 1 +x:1 +钱旺村乡 1 +x:1 +生铁 1 +x:1 +塌方 1 +x:1 +坝段 1 +x:1 +浮岩 1 +x:1 +照相馆 1 +x:1 +妄语 1 +x:1 +载体 1 +x:1 +靠手 1 +x:1 +千古一人 1 +x:1 +比划 1 +x:1 +洪熙官 1 +x:1 +公诸于众 1 +x:1 +归公 1 +x:1 +比分 1 +x:1 +光团 1 +x:1 +港澳 1 +x:1 +高价 1 +x:1 +高下 1 +x:1 +高三 1 +x:1 +本市 1 +x:1 +家家 1 +x:1 +本币 1 +x:1 +望望 1 +x:1 +高一 1 +x:1 +郭庄镇 1 +x:1 +翩翩 1 +x:1 +完全叶 1 +x:1 +鄂豫皖 1 +x:1 +艺术编 1 +x:1 +高专 1 +x:1 +望月 1 +x:1 +温室 1 +x:1 +高个 1 +x:1 +弯弯的 1 +x:1 +主单位 1 +x:1 +水霸 1 +x:1 +品数 1 +x:1 +借贷 1 +x:1 +辉铜矿 1 +x:1 +酉阳 1 +x:1 +县委 1 +x:1 +孙桥 1 +x:1 +飞鸿堂 1 +x:1 +出借 1 +x:1 +菲尼克斯 1 +x:1 +高丽 1 +x:1 +浮山 1 +x:1 +金华戏 1 +x:1 +知名演员 1 +x:1 +仇怨 1 +x:1 +靠拢 1 +x:1 +浮船坞 1 +x:1 +广开才路 1 +x:1 +江当乡 1 +x:1 +售饭机 1 +x:1 +修车摊 1 +x:1 +埃居 1 +x:1 +浮尘 1 +x:1 +法门 1 +x:1 +水东江 1 +x:1 +亚族人 1 +x:1 +高乔 1 +x:1 +强音 1 +x:1 +变废为宝 1 +x:1 +林牧局 1 +x:1 +尚未 1 +x:1 +先锋 1 +x:1 +水靴 1 +x:1 +跌宕起伏 1 +x:1 +越狱 1 +x:1 +黄龙伞盖 1 +x:1 +本年 1 +x:1 +商交所 1 +x:1 +塔指 1 +x:1 +水面 1 +x:1 +绊绊磕磕 1 +x:1 +邢台县 1 +x:1 +仇恨 1 +x:1 +破釜沉舟 1 +x:1 +潜研堂 1 +x:1 +鼻梁子 1 +x:1 +大凉山 1 +x:1 +近作选 1 +x:1 +畸形 1 +x:1 +饶有风趣 1 +x:1 +马克 1 +x:1 +足以 1 +x:1 +单人旁儿 1 +x:1 +石砌 1 +x:1 +客客气气 1 +x:1 +计划委 1 +x:1 +圆珠笔芯 1 +x:1 +交城 1 +x:1 +铸就 1 +x:1 +招展 1 +x:1 +经验型 1 +x:1 +三极管 1 +x:1 +月租费 1 +x:1 +香辅料 1 +x:1 +砸门声 1 +x:1 +马关 1 +x:1 +粉身碎骨 1 +x:1 +装卸队 1 +x:1 +烦乱 1 +x:1 +否决 1 +x:1 +份额油 1 +x:1 +本心 1 +x:1 +悠悠的 1 +x:1 +阵法 1 +x:1 +怀疑论 1 +x:1 +大后方 1 +x:1 +偏正 1 +x:1 +专管组 1 +x:1 +北甸子乡 1 +x:1 +厂子 1 +x:1 +磷虾 1 +x:1 +窒息 1 +x:1 +达尼洛娃 1 +x:1 +内蒙古 1 +x:1 +经济昆虫 1 +x:1 +水雷 1 +x:1 +宏农村 1 +x:1 +温婉 1 +x:1 +斗心眼儿 1 +x:1 +杨柳 1 +x:1 +后防线 1 +x:1 +邢台制 1 +x:1 +马儿 1 +x:1 +哲学部 1 +x:1 +国 5511 +x:5511 +硅石 1 +x:1 +五角大楼 1 +x:1 +舞狮队 1 +x:1 +积分学 1 +x:1 +石碓 1 +x:1 +以假充真 1 +x:1 +石碑 1 +x:1 +妄言 1 +x:1 +光圈 1 +x:1 +油罐车 1 +x:1 +针鼻儿 1 +x:1 +生锈 1 +x:1 +借调 1 +x:1 +超固态 1 +x:1 +倾斜仪 1 +x:1 +尝新 1 +x:1 +张北镇 1 +x:1 +共同点 1 +x:1 +吩咐 1 +x:1 +石碴 1 +x:1 +乐魂 1 +x:1 +港湾 1 +x:1 +厂家 1 +x:1 +邮编 1 +x:1 +高估 1 +x:1 +急脉缓灸 1 +x:1 +若隐若现 1 +x:1 +厂容 1 +x:1 +楷则 1 +x:1 +控价 1 +x:1 +喊话 1 +x:1 +石磙 1 +x:1 +多元性 1 +x:1 +高低 1 +x:1 +松明 1 +x:1 +秦时 1 +x:1 +雕塑热 1 +x:1 +快热式 1 +x:1 +南屏街 1 +x:1 +垂涎三尺 1 +x:1 +百货业 1 +x:1 +臧否 1 +x:1 +本当 1 +x:1 +社会学所 1 +x:1 +水陆 1 +x:1 +光电子 1 +x:1 +西北侧 1 +x:1 +硕学 1 +x:1 +封阻 1 +x:1 +螺丝起子 1 +x:1 +生长 1 +x:1 +半导体场 1 +x:1 +南安普顿 1 +x:1 +成心 1 +x:1 +回款额 1 +x:1 +石磨 1 +x:1 +足球界 1 +x:1 +石磬 1 +x:1 +长生果 1 +x:1 +离谱儿 1 +x:1 +一场春梦 1 +x:1 +成就 1 +x:1 +小青年 1 +x:1 +星点 1 +x:1 +怎生 1 +x:1 +石笔 1 +x:1 +石笋 1 +x:1 +终端台 1 +x:1 +一般来说 1 +x:1 +甘雨 1 +x:1 +雷场 1 +x:1 +佛罗里达 1 +x:1 +被面 1 +x:1 +望新 1 +x:1 +九江县 1 +x:1 +水富站 1 +x:1 +尚无 1 +x:1 +谬 1 +x:1 +佛罗伦萨 1 +x:1 +喜上加喜 1 +x:1 +娓娓动听 1 +x:1 +夺 216 +x:216 +光敏剂 1 +x:1 +宁折不弯 1 +x:1 +比值 1 +x:1 +马刀 1 +x:1 +摸底关 1 +x:1 +硅氧烷 1 +x:1 +间隔 1 +x:1 +四安镇 1 +x:1 +雷坪 1 +x:1 +麦迪亚 1 +x:1 +硕士 1 +x:1 +望族 1 +x:1 +创造期 1 +x:1 +横结肠 1 +x:1 +核裂变 1 +x:1 +水闸 1 +x:1 +紫金牛 1 +x:1 +灵丹妙药 1 +x:1 +项庄舞剑 1 +x:1 +升船机 1 +x:1 +甜水村 1 +x:1 +通什市 1 +x:1 +水门 1 +x:1 +英文版 1 +x:1 +水龙头 1 +x:1 +阿佤山 1 +x:1 +根据地 1 +x:1 +绑扎 1 +x:1 +哔叽 1 +x:1 +椅 7 +x:7 +远走高飞 1 +x:1 +居者 1 +x:1 +松柯 1 +x:1 +流动量 1 +x:1 +率员 1 +x:1 +鬃毛 1 +x:1 +隐 18 +x:18 +丝绸业 1 +x:1 +水锈 1 +x:1 +破处 1 +x:1 +日银 1 +x:1 +凤阳 1 +x:1 +横路山镇 1 +x:1 +意蕴 1 +x:1 +金小丑 1 +x:1 +罗源县 1 +x:1 +顺平县 1 +x:1 +日铁 1 +x:1 +健美操 1 +x:1 +膏血 1 +x:1 +花样队 1 +x:1 +游仙 1 +x:1 +说不清 1 +x:1 +感激不尽 1 +x:1 +花园口 1 +x:1 +满盘 1 +x:1 +水锤 1 +x:1 +民行 1 +x:1 +盐渍化 1 +x:1 +宇宙火箭 1 +x:1 +丰富多彩 1 +x:1 +垦边 1 +x:1 +本届 1 +x:1 +财贸委 1 +x:1 +袋中 1 +x:1 +终端区 1 +x:1 +马力 1 +x:1 +心灰意冷 1 +x:1 +欲念 1 +x:1 +藤牌 1 +x:1 +巢 23 +x:23 +僵死 1 +x:1 +齐鸣 1 +x:1 +否则 1 +x:1 +双蹦灯 1 +x:1 +东道主 1 +x:1 +汽车连 1 +x:1 +继往开来 1 +x:1 +中药 1 +x:1 +事务部长 1 +x:1 +化装 1 +x:1 +表格 1 +x:1 +忠良 1 +x:1 +尖兵 1 +x:1 +龙翔凤翥 1 +x:1 +福 75 +x:75 +安全系数 1 +x:1 +散热管 1 +x:1 +水针 1 +x:1 +胡作非为 1 +x:1 +无期徒刑 1 +x:1 +秋 152 +x:152 +高新科技 1 +x:1 +师团职 1 +x:1 +有理式 1 +x:1 +寒武纪 1 +x:1 +胸怀坦荡 1 +x:1 +秦朝 1 +x:1 +基础性 1 +x:1 +吮吸 1 +x:1 +墨守陈规 1 +x:1 +旅费 1 +x:1 +山城 1 +x:1 +水钢 1 +x:1 +座盘秤 1 +x:1 +紧紧巴巴 1 +x:1 +堆沟港 1 +x:1 +失道寡助 1 +x:1 +复现 1 +x:1 +傣味 1 +x:1 +预算额 1 +x:1 +犄角 1 +x:1 +满眼 1 +x:1 +起动机 1 +x:1 +法院 1 +x:1 +新城子区 1 +x:1 +含冤 1 +x:1 +水银 1 +x:1 +价重发 1 +x:1 +叹观止矣 1 +x:1 +破壳 1 +x:1 +腰眼 1 +x:1 +老视眼 1 +x:1 +正黄旗 1 +x:1 +对牛弹琴 1 +x:1 +织布 1 +x:1 +艺术系 1 +x:1 +马匹 1 +x:1 +终生 1 +x:1 +重归于好 1 +x:1 +石窟 1 +x:1 +港汊 1 +x:1 +上有老 1 +x:1 +石窑 1 +x:1 +抚躬自问 1 +x:1 +咒 4 +x:4 +农垦局 1 +x:1 +日间 1 +x:1 +硕大 1 +x:1 +塘泥 1 +x:1 +金家村 1 +x:1 +淘气 1 +x:1 +先验论 1 +x:1 +久演不衰 1 +x:1 +超尘绝俗 1 +x:1 +漫 33 +x:33 +旅趣 1 +x:1 +扣帽子 1 +x:1 +知难而上 1 +x:1 +敌敌畏 1 +x:1 +逃课 1 +x:1 +交售 1 +x:1 +沪浙皖 1 +x:1 +马厂 1 +x:1 +浮式 1 +x:1 +科明区 1 +x:1 +雁城 1 +x:1 +钟点儿 1 +x:1 +皮长公里 1 +x:1 +大麻类 1 +x:1 +参赛证 1 +x:1 +他 19823 +x:19823 +无柄叶 1 +x:1 +账单 1 +x:1 +检察长 1 +x:1 +石竹 1 +x:1 +走下坡路 1 +x:1 +演进 1 +x:1 +噩耗 1 +x:1 +烦言 1 +x:1 +痴人说梦 1 +x:1 +桥洞 1 +x:1 +巴罗克式 1 +x:1 +绶 1 +x:1 +驹 1 +x:1 +柳城县 1 +x:1 +淘汰 1 +x:1 +石章 1 +x:1 +金三角 1 +x:1 +偏瘫 1 +x:1 +酸性岩 1 +x:1 +合议庭 1 +x:1 +非饱和 1 +x:1 +社情民意 1 +x:1 +稻糠 1 +x:1 +教育学家 1 +x:1 +艨艟 1 +x:1 +杂拌儿 1 +x:1 +流动车 1 +x:1 +氨 8 +x:8 +仙居县 1 +x:1 +翠微微 1 +x:1 +开停机 1 +x:1 +惦挂 1 +x:1 +小前提 1 +x:1 +自作自受 1 +x:1 +贵 174 +x:174 +驾舆乘辇 1 +x:1 +童子 1 +x:1 +单月 1 +x:1 +核拨 1 +x:1 +传唤 1 +x:1 +石灰水 1 +x:1 +胸膈 1 +x:1 +填词 1 +x:1 +水溶液 1 +x:1 +借重 1 +x:1 +传唱 1 +x:1 +衮衮诸公 1 +x:1 +叶甜菜 1 +x:1 +基础网 1 +x:1 +敕勒川 1 +x:1 +康熙岭 1 +x:1 +灵寿绿 1 +x:1 +松枝 1 +x:1 +杂花生树 1 +x:1 +刺细胞 1 +x:1 +被褥 1 +x:1 +着迷 1 +x:1 +水晶塔 1 +x:1 +超大 1 +x:1 +赤小豆 1 +x:1 +自治机关 1 +x:1 +矿化水 1 +x:1 +竞技场 1 +x:1 +漫画化 1 +x:1 +推行面 1 +x:1 +特种部队 1 +x:1 +稻米 1 +x:1 +石料 1 +x:1 +遣怀 1 +x:1 +颈椎病 1 +x:1 +比价 1 +x:1 +石斑 1 +x:1 +高分 1 +x:1 +琦玉县 1 +x:1 +被角 1 +x:1 +似龙非龙 1 +x:1 +理合 1 +x:1 +强记 1 +x:1 +痼癖 1 +x:1 +桥牌 1 +x:1 +石方 1 +x:1 +高利 1 +x:1 +借记卡 1 +x:1 +关禁闭 1 +x:1 +胸膛 1 +x:1 +标题音乐 1 +x:1 +敲边鼓 1 +x:1 +淘汰赛 1 +x:1 +地下党 1 +x:1 +建委会 1 +x:1 +内阴型 1 +x:1 +崩溃 1 +x:1 +红筹股 1 +x:1 +甘肃团 1 +x:1 +微分学 1 +x:1 +民防 1 +x:1 +民阵 1 +x:1 +被覆 1 +x:1 +散播 1 +x:1 +纺车 1 +x:1 +水晶壶 1 +x:1 +大锅菜 1 +x:1 +病毒清 1 +x:1 +院务处 1 +x:1 +陶仓 1 +x:1 +繁华 1 +x:1 +报名点 1 +x:1 +链球 1 +x:1 +携手并肩 1 +x:1 +何尝不可 1 +x:1 +阿托品 1 +x:1 +楷体 1 +x:1 +招商 1 +x:1 +水警 1 +x:1 +法规 1 +x:1 +枪杆子 1 +x:1 +褒义 1 +x:1 +高压 1 +x:1 +散散 1 +x:1 +书坛史 1 +x:1 +涤纶厂 1 +x:1 +旧习惯 1 +x:1 +高原 1 +x:1 +插班 1 +x:1 +传呼 1 +x:1 +讯息 1 +x:1 +入保 1 +x:1 +比作 1 +x:1 +繁博 1 +x:1 +松松 1 +x:1 +胖瘦 1 +x:1 +忍痛割爱 1 +x:1 +北半球 1 +x:1 +四国 1 +x:1 +单杠 1 +x:1 +独立连 1 +x:1 +新加坡队 1 +x:1 +锅台 1 +x:1 +股评家 1 +x:1 +令人钦佩 1 +x:1 +雅 31 +x:31 +化隆 1 +x:1 +水粉画 1 +x:1 +高参 1 +x:1 +勋绩 1 +x:1 +垫圈 1 +x:1 +招聘处 1 +x:1 +醇醚 1 +x:1 +专场 1 +x:1 +植树造林 1 +x:1 +散放 1 +x:1 +照 202 +x:202 +高发 1 +x:1 +腰椎 1 +x:1 +落水狗 1 +x:1 +布娃娃 1 +x:1 +监督岗 1 +x:1 +每周日 1 +x:1 +筒瓦 1 +x:1 +兔儿爷 1 +x:1 +洗发膏 1 +x:1 +头顶 1 +x:1 +胡编 1 +x:1 +冷暖空气 1 +x:1 +高台 1 +x:1 +物构所 1 +x:1 +发颤 1 +x:1 +日语 1 +x:1 +烦劳 1 +x:1 +电脑班 1 +x:1 +发布者 1 +x:1 +被装 1 +x:1 +摆脱 1 +x:1 +尿毒症 1 +x:1 +曼海姆 1 +x:1 +疯狂 1 +x:1 +颚裂 1 +x:1 +树 672 +x:672 +迫力 1 +x:1 +黑森林 1 +x:1 +愁眉苦脸 1 +x:1 +可变资本 1 +x:1 +疯狗 1 +x:1 +参编部 1 +x:1 +气体云 1 +x:1 +坦桑尼亚 1 +x:1 +六一年 1 +x:1 +民青 1 +x:1 +寻死觅活 1 +x:1 +兴衰成败 1 +x:1 +澄海市 1 +x:1 +监督局 1 +x:1 +醇酣 1 +x:1 +高浓度 1 +x:1 +郎酒 1 +x:1 +超声 1 +x:1 +楷书 1 +x:1 +虚怀若谷 1 +x:1 +青冈县 1 +x:1 +地产股 1 +x:1 +被袋 1 +x:1 +新知 1 +x:1 +万紫千红 1 +x:1 +世博会 1 +x:1 +一上午 1 +x:1 +发送量 1 +x:1 +复派 1 +x:1 +顾问团 1 +x:1 +复活 1 +x:1 +频频 1 +x:1 +功课 1 +x:1 +表盘 1 +x:1 +昂扬 1 +x:1 +散文 1 +x:1 +瓮 1 +x:1 +原子能系 1 +x:1 +湖南路 1 +x:1 +演释 1 +x:1 +比例 1 +x:1 +赴约 1 +x:1 +衣锦还乡 1 +x:1 +高危 1 +x:1 +皮克鱼 1 +x:1 +易太镇 1 +x:1 +刀 154 +x:154 +鄂 52 +x:52 +芒廷维尤 1 +x:1 +电脑灯 1 +x:1 +不平则鸣 1 +x:1 +证券类 1 +x:1 +衢粮 1 +x:1 +参赛队 1 +x:1 +万能胶 1 +x:1 +入侵 1 +x:1 +旅途 1 +x:1 +翻天 1 +x:1 +筛选 1 +x:1 +童女 1 +x:1 +秃岭 1 +x:1 +马乡 1 +x:1 +被褥者 1 +x:1 +裴刘乡 1 +x:1 +易行 1 +x:1 +高傲 1 +x:1 +七弦琴 1 +x:1 +万劫不渝 1 +x:1 +游侠 1 +x:1 +上访办 1 +x:1 +预售处 1 +x:1 +石材 1 +x:1 +马上 1 +x:1 +塔秀寺 1 +x:1 +赶尽杀绝 1 +x:1 +拨给 1 +x:1 +木匠 1 +x:1 +文艺语言 1 +x:1 +法警 1 +x:1 +文人 1 +x:1 +石板 1 +x:1 +石松 1 +x:1 +警 110 +x:110 +公诸于世 1 +x:1 +代征 1 +x:1 +投向 1 +x:1 +高僧 1 +x:1 +地铁局 1 +x:1 +物资局 1 +x:1 +光荣榜 1 +x:1 +周转率 1 +x:1 +挖方 1 +x:1 +鄄城县 1 +x:1 +联谊会 1 +x:1 +水解 1 +x:1 +洗漱池 1 +x:1 +危害面 1 +x:1 +杜尚别 1 +x:1 +乘机 1 +x:1 +九湖镇 1 +x:1 +绝处逢生 1 +x:1 +石林 1 +x:1 +贪吃人 1 +x:1 +炉顶 1 +x:1 +马仔 1 +x:1 +元丰 1 +x:1 +富庶乡 1 +x:1 +钢筋网 1 +x:1 +散曲 1 +x:1 +民本观 1 +x:1 +烦冗 1 +x:1 +鬓发 1 +x:1 +燕东园 1 +x:1 +东苌池村 1 +x:1 +抛锚 1 +x:1 +超导 1 +x:1 +小时 1 +x:1 +二人转 1 +x:1 +非价格 1 +x:1 +日裔 1 +x:1 +人生在世 1 +x:1 +皮之不存 1 +x:1 +终 145 +x:145 +法语 1 +x:1 +垄作 1 +x:1 +柳城 1 +x:1 +喻特曼科 1 +x:1 +中秋节 1 +x:1 +硕士生 1 +x:1 +龙虎潭 1 +x:1 +窑尾 1 +x:1 +毛菇坝村 1 +x:1 +旅部 1 +x:1 +准许证 1 +x:1 +石柱 1 +x:1 +代开 1 +x:1 +反败为胜 1 +x:1 +足球报 1 +x:1 +平 579 +x:579 +逃难 1 +x:1 +收货人 1 +x:1 +格位 1 +x:1 +卵泡 1 +x:1 +普罗迪 1 +x:1 +吞吞吐吐 1 +x:1 +儒法道墨 1 +x:1 +古交西曲 1 +x:1 +民间 1 +x:1 +跳羚 1 +x:1 +水袖 1 +x:1 +燕头 1 +x:1 +私盖 1 +x:1 +百姓家 1 +x:1 +石油城 1 +x:1 +就是说 1 +x:1 +马体 1 +x:1 +容姿 1 +x:1 +欲盖弥彰 1 +x:1 +黔江 1 +x:1 +牵肠挂肚 1 +x:1 +气动力 1 +x:1 +沆瀣一气 1 +x:1 +老少无欺 1 +x:1 +山墙 1 +x:1 +碧波万顷 1 +x:1 +暑假 1 +x:1 +告警 1 +x:1 +欣欣向荣 1 +x:1 +生计 1 +x:1 +举 176 +x:176 +埃 128 +x:128 +农展馆 1 +x:1 +熹微 1 +x:1 +痼疾 1 +x:1 +救生袋 1 +x:1 +形形色色 1 +x:1 +获得者 1 +x:1 +生词 1 +x:1 +海拉尔 1 +x:1 +不成想 1 +x:1 +茶匙 1 +x:1 +整理 1 +x:1 +成熟林 1 +x:1 +谙晓 1 +x:1 +韩城市 1 +x:1 +什邡县 1 +x:1 +强行 1 +x:1 +法官法 1 +x:1 +代序 1 +x:1 +龙虎滩 1 +x:1 +停滞论 1 +x:1 +僵直 1 +x:1 +社会学系 1 +x:1 +化钱 1 +x:1 +参赛面 1 +x:1 +十年一剑 1 +x:1 +坡梁地 1 +x:1 +冠脉 1 +x:1 +积水潭 1 +x:1 +垄三 1 +x:1 +闺房 1 +x:1 +查询表 1 +x:1 +平定镇 1 +x:1 +旬末 1 +x:1 +所到之处 1 +x:1 +力量型 1 +x:1 +局部 1 +x:1 +告诉 1 +x:1 +水晶宫 1 +x:1 +茶卤 1 +x:1 +月度奖 1 +x:1 +童声 1 +x:1 +经年累月 1 +x:1 +营 84 +x:84 +非核心 1 +x:1 +艺术性 1 +x:1 +猝 1 +x:1 +电阻器 1 +x:1 +日见 1 +x:1 +容奇 1 +x:1 +诰命 1 +x:1 +南华队 1 +x:1 +文体室 1 +x:1 +告诫 1 +x:1 +直截 1 +x:1 +四周 1 +x:1 +传回 1 +x:1 +莫如 1 +x:1 +苍翠欲滴 1 +x:1 +放过 1 +x:1 +徐州市 1 +x:1 +入住 1 +x:1 +文艺队 1 +x:1 +近似值 1 +x:1 +异性 1 +x:1 +散架 1 +x:1 +劝业场 1 +x:1 +西北军 1 +x:1 +出落 1 +x:1 +教育局 1 +x:1 +内视反听 1 +x:1 +填表 1 +x:1 +万般无奈 1 +x:1 +收藏 1 +x:1 +水表 1 +x:1 +亳州市 1 +x:1 +教育展 1 +x:1 +高兴 1 +x:1 +卧具 1 +x:1 +天主堂 1 +x:1 +私有制 1 +x:1 +工作日制 1 +x:1 +传入 1 +x:1 +逃遁 1 +x:1 +交代 1 +x:1 +隐形眼镜 1 +x:1 +无意 1 +x:1 +麻旺区 1 +x:1 +山重水复 1 +x:1 +隗 6 +x:6 +萱草 1 +x:1 +黄铁矿 1 +x:1 +六机部 1 +x:1 +超标准 1 +x:1 +教育家 1 +x:1 +滋润 1 +x:1 +自做主张 1 +x:1 +复检 1 +x:1 +水边 1 +x:1 +枪林弹雨 1 +x:1 +对号入座 1 +x:1 +翻开 1 +x:1 +逃避 1 +x:1 +交付 1 +x:1 +法国梧桐 1 +x:1 +硅藻土 1 +x:1 +受款方 1 +x:1 +越橘 1 +x:1 +战场坪村 1 +x:1 +橄榄 1 +x:1 +龙须沟 1 +x:1 +水运 1 +x:1 +香港团 1 +x:1 +跑 575 +x:575 +文体局 1 +x:1 +抗联 1 +x:1 +挖掘 1 +x:1 +衷心 1 +x:1 +保暖棚 1 +x:1 +竟 471 +x:471 +龙须河 1 +x:1 +高教委 1 +x:1 +有门儿 1 +x:1 +交予 1 +x:1 +水迹 1 +x:1 +可交换性 1 +x:1 +枕骨 1 +x:1 +渊深 1 +x:1 +学名 1 +x:1 +借问 1 +x:1 +逃逸 1 +x:1 +扶残助残 1 +x:1 +交井 1 +x:1 +交互 1 +x:1 +话儿 1 +x:1 +圪节 1 +x:1 +巴厘虎 1 +x:1 +弦外之音 1 +x:1 +淡旺季 1 +x:1 +强辩 1 +x:1 +妥甸镇 1 +x:1 +只限 1 +x:1 +茨菰 1 +x:1 +周末游 1 +x:1 +四千 1 +x:1 +几朝几夕 1 +x:1 +仁以恤民 1 +x:1 +传出 1 +x:1 +抗药性 1 +x:1 +冠绝群伦 1 +x:1 +赤岗村 1 +x:1 +三星 1 +x:1 +润 25 +x:25 +膝盖骨 1 +x:1 +办证费 1 +x:1 +港督 1 +x:1 +光临 1 +x:1 +童心 1 +x:1 +逆温层 1 +x:1 +强辞 1 +x:1 +组织疗法 1 +x:1 +钳修 1 +x:1 +可看性 1 +x:1 +豺狼当道 1 +x:1 +脑筋 1 +x:1 +表率 1 +x:1 +物尽其用 1 +x:1 +白骨精 1 +x:1 +偏狭 1 +x:1 +四化 1 +x:1 +强迫 1 +x:1 +金田村 1 +x:1 +投劳 1 +x:1 +无产者 1 +x:1 +粮食部 1 +x:1 +生殖力 1 +x:1 +似虎非虎 1 +x:1 +复根 1 +x:1 +复核 1 +x:1 +整个儿 1 +x:1 +可信性 1 +x:1 +智斗 1 +x:1 +长影厂 1 +x:1 +涌流 1 +x:1 +成熟性 1 +x:1 +渊海 1 +x:1 +乐舞 1 +x:1 +棍儿茶 1 +x:1 +排头兵 1 +x:1 +面前坡村 1 +x:1 +水车 1 +x:1 +载 239 +x:239 +罪魁 1 +x:1 +井井有条 1 +x:1 +公牛队 1 +x:1 +朝天区 1 +x:1 +青纱帐 1 +x:1 +原始积累 1 +x:1 +辛辛苦苦 1 +x:1 +三明 1 +x:1 +垃圾袋 1 +x:1 +增光 1 +x:1 +稻秧 1 +x:1 +豪言壮语 1 +x:1 +整版 1 +x:1 +信贷部 1 +x:1 +童年 1 +x:1 +走形式 1 +x:1 +踯躅 1 +x:1 +相似形 1 +x:1 +渔猎 1 +x:1 +电灌站 1 +x:1 +容忍 1 +x:1 +文艺部 1 +x:1 +白领阶层 1 +x:1 +大白菜 1 +x:1 +增兵 1 +x:1 +咯咯吱吱 1 +x:1 +袍子 1 +x:1 +核果 1 +x:1 +余音绕梁 1 +x:1 +发送键 1 +x:1 +生趣 1 +x:1 +稻种 1 +x:1 +告负 1 +x:1 +高城 1 +x:1 +棠 1 +x:1 +暹罗湾 1 +x:1 +变质岩 1 +x:1 +保护法 1 +x:1 +狭鳕 1 +x:1 +满洲 1 +x:1 +极目远望 1 +x:1 +绑票 1 +x:1 +宁乡县 1 +x:1 +疯瘫 1 +x:1 +卧倒 1 +x:1 +颂扬 1 +x:1 +鸭河口 1 +x:1 +驱风油 1 +x:1 +驱使 1 +x:1 +提案组 1 +x:1 +生路 1 +x:1 +主治医师 1 +x:1 +满头大汗 1 +x:1 +⑶ 5 +x:5 +旧地重游 1 +x:1 +份 1234 +x:1234 +螳螂山 1 +x:1 +血渍 1 +x:1 +海战史 1 +x:1 +强身 1 +x:1 +鸣锣开道 1 +x:1 +动人心弦 1 +x:1 +大檐帽 1 +x:1 +笑里藏刀 1 +x:1 +烦嚣 1 +x:1 +光伏 1 +x:1 +收获 1 +x:1 +卫戍区 1 +x:1 +五斗柜 1 +x:1 +依赖感 1 +x:1 +吃不开 1 +x:1 +油纸伞 1 +x:1 +藤椅 1 +x:1 +稻神 1 +x:1 +彻夜 1 +x:1 +高平市 1 +x:1 +仁义 1 +x:1 +游伴 1 +x:1 +高地 1 +x:1 +横水乡 1 +x:1 +生财 1 +x:1 +率众 1 +x:1 +机修厂 1 +x:1 +治水 1 +x:1 +金川市 1 +x:1 +架桥 1 +x:1 +有机质 1 +x:1 +纯中药 1 +x:1 +四则 1 +x:1 +自理 1 +x:1 +流入国 1 +x:1 +拆迁户 1 +x:1 +颈椎炎 1 +x:1 +智敏 1 +x:1 +功过 1 +x:1 +以身试法 1 +x:1 +秃子 1 +x:1 +高坪 1 +x:1 +高坨 1 +x:1 +日辉 1 +x:1 +制品厂 1 +x:1 +梯河 1 +x:1 +高坡 1 +x:1 +赢余 1 +x:1 +喷红欲燃 1 +x:1 +高邮市 1 +x:1 +交会 1 +x:1 +理入 1 +x:1 +少怀壮志 1 +x:1 +阴鸷 1 +x:1 +甜甜蜜蜜 1 +x:1 +光源感 1 +x:1 +恤金 1 +x:1 +伏跗室 1 +x:1 +病怏怏 1 +x:1 +泥浆状 1 +x:1 +黄曲霉菌 1 +x:1 +骨疏松症 1 +x:1 +僻地 1 +x:1 +啧啧声 1 +x:1 +替补队员 1 +x:1 +扛鼎之作 1 +x:1 +曲艺节 1 +x:1 +散手 1 +x:1 +朱庄 1 +x:1 +篷布 1 +x:1 +益阳市 1 +x:1 +托儿所 1 +x:1 +原则性 1 +x:1 +燕尔 1 +x:1 +刘乡 1 +x:1 +假票 1 +x:1 +生身 1 +x:1 +传单 1 +x:1 +散打 1 +x:1 +叩响 1 +x:1 +道党委 1 +x:1 +比翼竞飞 1 +x:1 +白俄罗斯 1 +x:1 +上访团 1 +x:1 +嫁祸于人 1 +x:1 +投票权 1 +x:1 +刘一 1 +x:1 +度过 1 +x:1 +贝母 1 +x:1 +桐乡县 1 +x:1 +增刊 1 +x:1 +酸根 1 +x:1 +监督室 1 +x:1 +漳县 1 +x:1 +散户 1 +x:1 +大丈夫 1 +x:1 +郊县 1 +x:1 +满清 1 +x:1 +会话 1 +x:1 +别妻离子 1 +x:1 +忱 2 +x:2 +发人深醒 1 +x:1 +超强 1 +x:1 +燕居 1 +x:1 +收聚 1 +x:1 +主观性 1 +x:1 +栈桥 1 +x:1 +满满 1 +x:1 +架次 1 +x:1 +哈站 1 +x:1 +名噪一时 1 +x:1 +童工 1 +x:1 +疯病 1 +x:1 +小龙坎 1 +x:1 +龙凤乡 1 +x:1 +政院 1 +x:1 +四免 1 +x:1 +盖章人 1 +x:1 +蜡 6 +x:6 +稻穗 1 +x:1 +防毒 1 +x:1 +存栏数 1 +x:1 +水费 1 +x:1 +近似商 1 +x:1 +桩子 1 +x:1 +教育处 1 +x:1 +氙气 1 +x:1 +水质 1 +x:1 +水货 1 +x:1 +膺 1 +x:1 +喷绘 1 +x:1 +旋风装 1 +x:1 +冤假错案 1 +x:1 +叶尖 1 +x:1 +络子 1 +x:1 +偃虹堤 1 +x:1 +颅底 1 +x:1 +权利人 1 +x:1 +查询费 1 +x:1 +谋利者 1 +x:1 +硅单晶 1 +x:1 +举世无双 1 +x:1 +弹奏 1 +x:1 +郊区 1 +x:1 +增势 1 +x:1 +怡然自得 1 +x:1 +柳叶 1 +x:1 +酸梅 1 +x:1 +约旦河谷 1 +x:1 +颠倒是非 1 +x:1 +团聚 1 +x:1 +高呼 1 +x:1 +民选 1 +x:1 +黑山县 1 +x:1 +弹着点 1 +x:1 +教育奖 1 +x:1 +高喊 1 +x:1 +会员证 1 +x:1 +列车表 1 +x:1 +涌溢 1 +x:1 +渊源 1 +x:1 +鸡血藤 1 +x:1 +转增 1 +x:1 +胰脂酶 1 +x:1 +主存储器 1 +x:1 +生辉 1 +x:1 +投入 1 +x:1 +居首 1 +x:1 +童山 1 +x:1 +礼仪馆 1 +x:1 +党纪国法 1 +x:1 +萨拉热窝 1 +x:1 +雷丁 1 +x:1 +凤辇 1 +x:1 +生命不息 1 +x:1 +地学界 1 +x:1 +汽车队 1 +x:1 +酸楚 1 +x:1 +复比 1 +x:1 +炮制者 1 +x:1 +化学反应 1 +x:1 +茸 1 +x:1 +万头攒动 1 +x:1 +健美素 1 +x:1 +理发 1 +x:1 +籁 4 +x:4 +键位 1 +x:1 +硕士点 1 +x:1 +人迹罕至 1 +x:1 +日货 1 +x:1 +米饭粒 1 +x:1 +名留青史 1 +x:1 +超市 1 +x:1 +横贡缎 1 +x:1 +易货 1 +x:1 +相近 1 +x:1 +三·一八 1 +x:1 +里程表 1 +x:1 +全天候 1 +x:1 +腈纶 1 +x:1 +旅长 1 +x:1 +超常 1 +x:1 +备用胎 1 +x:1 +控告 1 +x:1 +在场者 1 +x:1 +异花传粉 1 +x:1 +萎蔫 1 +x:1 +鹿场 1 +x:1 +理化 1 +x:1 +增发 1 +x:1 +霞晖 1 +x:1 +四假 1 +x:1 +形式逻辑 1 +x:1 +经院科学 1 +x:1 +酸槽 1 +x:1 +高唐 1 +x:1 +核收 1 +x:1 +三保地 1 +x:1 +恬淡 1 +x:1 +胰腺 1 +x:1 +东西部 1 +x:1 +斩尽杀绝 1 +x:1 +比萨屋 1 +x:1 +高唱 1 +x:1 +检验关 1 +x:1 +定向生 1 +x:1 +告辞 1 +x:1 +名车者 1 +x:1 +度日 1 +x:1 +价目 1 +x:1 +传动 1 +x:1 +印欧语 1 +x:1 +抢劫罪 1 +x:1 +插画 1 +x:1 +佤族人 1 +x:1 +碰见 1 +x:1 +宇宙 1 +x:1 +引线人 1 +x:1 +立定脚跟 1 +x:1 +疣鼻天鹅 1 +x:1 +石担 1 +x:1 +燕川 1 +x:1 +蟠 1 +x:1 +上场 1 +x:1 +日趋 1 +x:1 +整点 1 +x:1 +石拱 1 +x:1 +冰棍儿 1 +x:1 +拖配 1 +x:1 +说不着 1 +x:1 +洪水猛兽 1 +x:1 +耿耿不忘 1 +x:1 +帕尔马市 1 +x:1 +参评率 1 +x:1 +南科西嘉 1 +x:1 +石洞 1 +x:1 +日经指数 1 +x:1 +生肖 1 +x:1 +扶贫助优 1 +x:1 +剧作家 1 +x:1 +四心 1 +x:1 +暑季 1 +x:1 +工联主义 1 +x:1 +破例 1 +x:1 +生肉 1 +x:1 +抑蒸减耗 1 +x:1 +受热面 1 +x:1 +龙虎斗 1 +x:1 +扑热息痛 1 +x:1 +拉拉杂杂 1 +x:1 +感谢信 1 +x:1 +亏量 1 +x:1 +名画家 1 +x:1 +淘箩 1 +x:1 +岗美镇 1 +x:1 +长虹桥 1 +x:1 +落水管 1 +x:1 +生育 1 +x:1 +政风 1 +x:1 +出海人 1 +x:1 +越是 1 +x:1 +瞵 1 +x:1 +阴 47 +x:47 +四快 1 +x:1 +苏皖 1 +x:1 +敲诈勒索 1 +x:1 +芡实 1 +x:1 +垫布 1 +x:1 +翻印 1 +x:1 +翻卷 1 +x:1 +有机肥 1 +x:1 +票价表 1 +x:1 +整编 1 +x:1 +丰赡鲜活 1 +x:1 +褒恤 1 +x:1 +剜 1 +x:1 +散水 1 +x:1 +满怀 1 +x:1 +形同 1 +x:1 +蒸汽费 1 +x:1 +千日红 1 +x:1 +西店刘村 1 +x:1 +鸟迷 1 +x:1 +审批卡 1 +x:1 +着色率 1 +x:1 +投师 1 +x:1 +消炎片 1 +x:1 +译员 1 +x:1 +救济品 1 +x:1 +客轮 1 +x:1 +别内河 1 +x:1 +石浦 1 +x:1 +空勤团 1 +x:1 +强击机 1 +x:1 +投建 1 +x:1 +针 86 +x:86 +义侠记 1 +x:1 +中央委员 1 +x:1 +海外版 1 +x:1 +野猫 1 +x:1 +广州湾 1 +x:1 +避而不谈 1 +x:1 +彪炳春秋 1 +x:1 +盒饭 1 +x:1 +生者 1 +x:1 +活鲜 1 +x:1 +挖潜 1 +x:1 +几时 1 +x:1 +潦倒 1 +x:1 +复摆 1 +x:1 +渺无声息 1 +x:1 +童友 1 +x:1 +诊疗所 1 +x:1 +书评版 1 +x:1 +超凡 1 +x:1 +豆芽儿 1 +x:1 +摩擦性 1 +x:1 +石涯 1 +x:1 +超出 1 +x:1 +十字架形 1 +x:1 +爆炸波 1 +x:1 +尉氏县 1 +x:1 +广州港 1 +x:1 +中北区 1 +x:1 +合作者 1 +x:1 +清污剂 1 +x:1 +水荒 1 +x:1 +价廉物美 1 +x:1 +大锅话 1 +x:1 +剧艺社 1 +x:1 +有约在先 1 +x:1 +现时代 1 +x:1 +门槛儿 1 +x:1 +垫底 1 +x:1 +水草 1 +x:1 +漫画家 1 +x:1 +生机勃勃 1 +x:1 +几维鸟 1 +x:1 +有增无已 1 +x:1 +黔南 1 +x:1 +世乒赛 1 +x:1 +覆盖度 1 +x:1 +就业部 1 +x:1 +蓊蓊郁郁 1 +x:1 +原子价 1 +x:1 +札记 1 +x:1 +贿选 1 +x:1 +网络迷 1 +x:1 +送达 1 +x:1 +检索室 1 +x:1 +复旧 1 +x:1 +复旦 1 +x:1 +牧羊人 1 +x:1 +弄 171 +x:171 +水冲式 1 +x:1 +翻刻 1 +x:1 +超假 1 +x:1 +投影 1 +x:1 +照护 1 +x:1 +制服 1 +x:1 +高官 1 +x:1 +厂休 1 +x:1 +相同点 1 +x:1 +议员团 1 +x:1 +沙坪坝区 1 +x:1 +监督哨 1 +x:1 +频遭 1 +x:1 +蓊郁 1 +x:1 +无性 1 +x:1 +许多 1 +x:1 +频道 1 +x:1 +瑕不掩瑜 1 +x:1 +讲讲 1 +x:1 +沉住气 1 +x:1 +锑华 1 +x:1 +贿金 1 +x:1 +水花 1 +x:1 +综合症 1 +x:1 +无怪 1 +x:1 +检查室 1 +x:1 +学术性 1 +x:1 +凝神专注 1 +x:1 +油 212 +x:212 +破产 1 +x:1 +嘉定区 1 +x:1 +审批制 1 +x:1 +江川县 1 +x:1 +伊瓜苏 1 +x:1 +对不住 1 +x:1 +平步登天 1 +x:1 +万能论 1 +x:1 +涅瓦河 1 +x:1 +投弹 1 +x:1 +芦苇丛 1 +x:1 +中学部 1 +x:1 +讲话 1 +x:1 +教育团 1 +x:1 +高密 1 +x:1 +摆摊者 1 +x:1 +土家族 1 +x:1 +讲评 1 +x:1 +报修单 1 +x:1 +容县 1 +x:1 +如见其人 1 +x:1 +高寒 1 +x:1 +温习 1 +x:1 +复方 1 +x:1 +收载 1 +x:1 +温书 1 +x:1 +望城县 1 +x:1 +复文 1 +x:1 +笃行不倦 1 +x:1 +讲课 1 +x:1 +星虫 1 +x:1 +满意 1 +x:1 +碰钉子 1 +x:1 +匪气 1 +x:1 +江界市 1 +x:1 +理工 1 +x:1 +请 1199 +x:1199 +古装戏 1 +x:1 +浸 20 +x:20 +聚心成业 1 +x:1 +清秀 1 +x:1 +零工 1 +x:1 +管道网 1 +x:1 +精明强干 1 +x:1 +龄 12 +x:12 +材料部 1 +x:1 +伪麻黄碱 1 +x:1 +复数 1 +x:1 +整组 1 +x:1 +翻动 1 +x:1 +锅子 1 +x:1 +四平 1 +x:1 +石油 1 +x:1 +按图索骥 1 +x:1 +巴解组织 1 +x:1 +监督员 1 +x:1 +O 1 +x:1 +百花莲 1 +x:1 +收辑 1 +x:1 +动不动 1 +x:1 +蚕宝宝 1 +x:1 +保护性 1 +x:1 +嘉定县 1 +x:1 +雄狮 1 +x:1 +稻田 1 +x:1 +幅 502 +x:502 +上坪 1 +x:1 +颅内 1 +x:1 +酸枣 1 +x:1 +核武 1 +x:1 +脑瘤 1 +x:1 +就业量 1 +x:1 +走马灯 1 +x:1 +脑瘫 1 +x:1 +光荣户 1 +x:1 +动画部 1 +x:1 +超储 1 +x:1 +整纸 1 +x:1 +提案牌 1 +x:1 +水色 1 +x:1 +一表人材 1 +x:1 +隆福寺 1 +x:1 +奶山羊 1 +x:1 +直辖市 1 +x:1 +整纪 1 +x:1 +尖刀组 1 +x:1 +理应 1 +x:1 +浇洒 1 +x:1 +医政路 1 +x:1 +功耗 1 +x:1 +陌路 1 +x:1 +抢劫犯 1 +x:1 +四川 1 +x:1 +七运会 1 +x:1 +高墙 1 +x:1 +血青素 1 +x:1 +脏言 1 +x:1 +增幅 1 +x:1 +昼长夜短 1 +x:1 +瑞方 1 +x:1 +架构 1 +x:1 +卧铺票 1 +x:1 +荒碱地 1 +x:1 +意见簿 1 +x:1 +优胜劣败 1 +x:1 +贪天之功 1 +x:1 +后陈庄村 1 +x:1 +玩世不恭 1 +x:1 +意味深长 1 +x:1 +斜拉索桥 1 +x:1 +航标灯 1 +x:1 +苏瓦 1 +x:1 +整个 1 +x:1 +水臌 1 +x:1 +水月庵村 1 +x:1 +建阳市 1 +x:1 +暑天 1 +x:1 +价签 1 +x:1 +牛痘苗 1 +x:1 +塞规 1 +x:1 +搬进 1 +x:1 +磷酸 1 +x:1 +高士 1 +x:1 +传开 1 +x:1 +循章摘句 1 +x:1 +眩晕 1 +x:1 +浅水 1 +x:1 +泼冷水 1 +x:1 +旅顺 1 +x:1 +凌乱 1 +x:1 +投射 1 +x:1 +高声 1 +x:1 +眼眉 1 +x:1 +轻口薄舌 1 +x:1 +大葆台 1 +x:1 +同气相求 1 +x:1 +徽章 1 +x:1 +洗染店 1 +x:1 +高堂 1 +x:1 +资料架 1 +x:1 +古今中外 1 +x:1 +掏空 1 +x:1 +基里巴斯 1 +x:1 +热泪盈眶 1 +x:1 +膀子 1 +x:1 +增建 1 +x:1 +满拉 1 +x:1 +螺丝 1 +x:1 +财革法 1 +x:1 +鹿娃 1 +x:1 +胡瓜 1 +x:1 +观庙乡 1 +x:1 +乐谱 1 +x:1 +拄杖者 1 +x:1 +盈 20 +x:20 +独立营 1 +x:1 +宣 39 +x:39 +十三经 1 +x:1 +降半旗 1 +x:1 +要略 1 +x:1 +社会学界 1 +x:1 +招远县 1 +x:1 +高塔 1 +x:1 +资料柜 1 +x:1 +三有 1 +x:1 +功能 1 +x:1 +伶仃 1 +x:1 +无核武器 1 +x:1 +乌台诗 1 +x:1 +核桃 1 +x:1 +复明 1 +x:1 +海盗船 1 +x:1 +一发 1 +x:1 +光荣感 1 +x:1 +职务工资 1 +x:1 +公安部 1 +x:1 +艺术楼 1 +x:1 +蜈蚣式 1 +x:1 +复查 1 +x:1 +燕儿 1 +x:1 +新立村 1 +x:1 +长白参 1 +x:1 +沪港机 1 +x:1 +收购 1 +x:1 +浮皮潦草 1 +x:1 +挖法 1 +x:1 +辅助性 1 +x:1 +收贷 1 +x:1 +坐视不救 1 +x:1 +收费 1 +x:1 +皎然 1 +x:1 +水肿 1 +x:1 +火油炉 1 +x:1 +浇水 1 +x:1 +谨慎者 1 +x:1 +恭城县 1 +x:1 +强者 1 +x:1 +定价权 1 +x:1 +脑瓜 1 +x:1 +厄瓜多尔 1 +x:1 +推进会 1 +x:1 +南加州 1 +x:1 +责任人员 1 +x:1 +轻率 1 +x:1 +水肥 1 +x:1 +刃具 1 +x:1 +评判者 1 +x:1 +散漫 1 +x:1 +心 869 +x:869 +生菜 1 +x:1 +鸠江区 1 +x:1 +油菜子 1 +x:1 +西山区 1 +x:1 +饽饽 1 +x:1 +兴凯湖 1 +x:1 +互济性 1 +x:1 +石湖 1 +x:1 +乐趣 1 +x:1 +鹿寨 1 +x:1 +增开 1 +x:1 +挖沙 1 +x:1 +至死不悟 1 +x:1 +游府西街 1 +x:1 +富集区 1 +x:1 +传布 1 +x:1 +增强 1 +x:1 +水能 1 +x:1 +粉线 1 +x:1 +操行 1 +x:1 +屋内 1 +x:1 +红壤陶 1 +x:1 +扒开 1 +x:1 +县上 1 +x:1 +讲解 1 +x:1 +居间 1 +x:1 +专业法 1 +x:1 +复来 1 +x:1 +县份 1 +x:1 +日光浴 1 +x:1 +藤木 1 +x:1 +河南坠子 1 +x:1 +旅馆 1 +x:1 +高处 1 +x:1 +散文集 1 +x:1 +气脉贯畅 1 +x:1 +变速运动 1 +x:1 +冥冥之中 1 +x:1 +投工 1 +x:1 +保税仓 1 +x:1 +城厢镇 1 +x:1 +素可泰 1 +x:1 +用稿 1 +x:1 +表演性 1 +x:1 +作威作福 1 +x:1 +梢 1 +x:1 +谥 1 +x:1 +越方 1 +x:1 +绿头巾 1 +x:1 +复杂 1 +x:1 +孩子 1 +x:1 +高大 1 +x:1 +抗辩 1 +x:1 +秋毫 1 +x:1 +油价 1 +x:1 +袋子 1 +x:1 +秦王 1 +x:1 +面目全非 1 +x:1 +南湾里 1 +x:1 +书包带 1 +x:1 +走村串户 1 +x:1 +理当 1 +x:1 +高奏 1 +x:1 +地头虎 1 +x:1 +复本 1 +x:1 +应税面 1 +x:1 +生荒 1 +x:1 +藤条 1 +x:1 +冰封雪飘 1 +x:1 +磷都 1 +x:1 +四小 1 +x:1 +中山东路 1 +x:1 +复机 1 +x:1 +查询者 1 +x:1 +入世 1 +x:1 +钟点 1 +x:1 +天葬场 1 +x:1 +法苑 1 +x:1 +市政区 1 +x:1 +生药 1 +x:1 +桐乡市 1 +x:1 +斯温登 1 +x:1 +天长日久 1 +x:1 +功臣 1 +x:1 +土腥味儿 1 +x:1 +上海交大 1 +x:1 +浇注 1 +x:1 +理墒 1 +x:1 +翻地 1 +x:1 +越战 1 +x:1 +引擎盖 1 +x:1 +四体不勤 1 +x:1 +成为 1 +x:1 +巡防 1 +x:1 +平均价 1 +x:1 +小店乡 1 +x:1 +本事 1 +x:1 +华员会 1 +x:1 +剖析 1 +x:1 +高庙 1 +x:1 +青海湖 1 +x:1 +类群 1 +x:1 +砘 1 +x:1 +水螅 1 +x:1 +巡逻 1 +x:1 +石椅 1 +x:1 +逻辑值 1 +x:1 +鹿岛 1 +x:1 +迫导向 1 +x:1 +塞达 1 +x:1 +庄重性 1 +x:1 +高度 1 +x:1 +教育厅 1 +x:1 +珠穆朗玛 1 +x:1 +养路工 1 +x:1 +本人 1 +x:1 +水田区 1 +x:1 +赊账单 1 +x:1 +姬路市 1 +x:1 +弄清 1 +x:1 +三合板 1 +x:1 +救护所 1 +x:1 +颂歌 1 +x:1 +四定 1 +x:1 +教育司 1 +x:1 +成习 1 +x:1 +成书 1 +x:1 +教育台 1 +x:1 +技能班 1 +x:1 +教育史 1 +x:1 +四害 1 +x:1 +栏板 1 +x:1 +漫画式 1 +x:1 +抗衡 1 +x:1 +监察部门 1 +x:1 +薄地 1 +x:1 +诗情画意 1 +x:1 +石楠 1 +x:1 +夜大学 1 +x:1 +成亲 1 +x:1 +容器 1 +x:1 +肿物 1 +x:1 +喆 8 +x:8 +成人 1 +x:1 +蓝绿色 1 +x:1 +平淡淡 1 +x:1 +手术组 1 +x:1 +成交 1 +x:1 +合议制 1 +x:1 +网围栏 1 +x:1 +新开河街 1 +x:1 +类编 1 +x:1 +觉着 1 +x:1 +保暖性 1 +x:1 +统战 1 +x:1 +朗诵 1 +x:1 +石榴 1 +x:1 +四季 1 +x:1 +格拉玛 1 +x:1 +发财狂 1 +x:1 +无核白 1 +x:1 +高帽 1 +x:1 +绥芬河 1 +x:1 +指腹为婚 1 +x:1 +贿赂公行 1 +x:1 +表演机 1 +x:1 +霞浦 1 +x:1 +保洁权 1 +x:1 +双优 1 +x:1 +理塘 1 +x:1 +郊外 1 +x:1 +同病相连 1 +x:1 +出发地 1 +x:1 +本义 1 +x:1 +燕园 1 +x:1 +寻呼台 1 +x:1 +夜市街 1 +x:1 +烦忧 1 +x:1 +新墨西哥 1 +x:1 +丝绸展 1 +x:1 +本书 1 +x:1 +针松 1 +x:1 +混淆视听 1 +x:1 +石槽 1 +x:1 +本乡 1 +x:1 +南岭村 1 +x:1 +库存量 1 +x:1 +预约 1 +x:1 +烦心 1 +x:1 +线桥 1 +x:1 +天涯海角 1 +x:1 +高干 1 +x:1 +高平 1 +x:1 +狭长 1 +x:1 +中果皮 1 +x:1 +塞车 1 +x:1 +讲辞 1 +x:1 +俭从何来 1 +x:1 +石栗 1 +x:1 +垫子 1 +x:1 +石栏 1 +x:1 +超员 1 +x:1 +高徒 1 +x:1 +资料性 1 +x:1 +水蚀 1 +x:1 +庄重感 1 +x:1 +峨眉山 1 +x:1 +针灸学 1 +x:1 +畸低 1 +x:1 +消夜 1 +x:1 +容城 1 +x:1 +阳刚 1 +x:1 +镇定剂 1 +x:1 +投子 1 +x:1 +乐评 1 +x:1 +连理枝 1 +x:1 +共同性 1 +x:1 +水蚤 1 +x:1 +约克 1 +x:1 +视做 1 +x:1 +增多 1 +x:1 +百货店 1 +x:1 +共产党 1 +x:1 +察右前旗 1 +x:1 +薄坯 1 +x:1 +气密性 1 +x:1 +化验 1 +x:1 +寇仇 1 +x:1 +周转粮 1 +x:1 +舀子 1 +x:1 +羊腥汤 1 +x:1 +捣鬼 1 +x:1 +水蛇 1 +x:1 +痛 85 +x:85 +石骨铁硬 1 +x:1 +欢迎辞 1 +x:1 +信贷额 1 +x:1 +主谈手 1 +x:1 +讲述 1 +x:1 +父母亲 1 +x:1 +咕咚 1 +x:1 +磴口 1 +x:1 +水蛭 1 +x:1 +日久天长 1 +x:1 +年青 1 +x:1 +独创性 1 +x:1 +出租人 1 +x:1 +石桥 1 +x:1 +增大 1 +x:1 +植入 1 +x:1 +王家畈乡 1 +x:1 +老羞成怒 1 +x:1 +大队长 1 +x:1 +收讫 1 +x:1 +政务官 1 +x:1 +制假术 1 +x:1 +早已 1 +x:1 +高弟 1 +x:1 +勋爵 1 +x:1 +最前线 1 +x:1 +证券班 1 +x:1 +熹光 1 +x:1 +痰桶 1 +x:1 +油葵 1 +x:1 +满族 1 +x:1 +号召者 1 +x:1 +高强 1 +x:1 +简化汉字 1 +x:1 +收烘站 1 +x:1 +成例 1 +x:1 +整章 1 +x:1 +投宿 1 +x:1 +选举会 1 +x:1 +冷飕飕 1 +x:1 +畏惧 1 +x:1 +本位 1 +x:1 +鬣 1 +x:1 +凿空 1 +x:1 +葫蔓藤 1 +x:1 +石棉 1 +x:1 +邯农 1 +x:1 +本体 1 +x:1 +北横东街 1 +x:1 +水虿 1 +x:1 +主创者 1 +x:1 +早米苋 1 +x:1 +满文 1 +x:1 +干燥箱 1 +x:1 +翻回 1 +x:1 +水虱 1 +x:1 +壮志凌云 1 +x:1 +僵硬 1 +x:1 +乙醚 1 +x:1 +非关税 1 +x:1 +中年级 1 +x:1 +表示 1 +x:1 +窃 42 +x:42 +监督台 1 +x:1 +黄金时代 1 +x:1 +七人制 1 +x:1 +监督司 1 +x:1 +保护林 1 +x:1 +油泉子 1 +x:1 +世妇会 1 +x:1 +代号 1 +x:1 +日常 1 +x:1 +消极怠工 1 +x:1 +无声无息 1 +x:1 +娼妓 1 +x:1 +牙买加队 1 +x:1 +日光棚 1 +x:1 +阳关村 1 +x:1 +民食 1 +x:1 +娼妇 1 +x:1 +休息日 1 +x:1 +代发 1 +x:1 +邻接权 1 +x:1 +西北局 1 +x:1 +民风 1 +x:1 +哇 17 +x:17 +中子流 1 +x:1 +草药店 1 +x:1 +连环 1 +x:1 +酸性 1 +x:1 +莫名 1 +x:1 +日落 1 +x:1 +银根菜 1 +x:1 +役使 1 +x:1 +浮云 1 +x:1 +罗马市 1 +x:1 +公诉人 1 +x:1 +宣传栏 1 +x:1 +水藻 1 +x:1 +砖瓦窑 1 +x:1 +夸张 1 +x:1 +哄传 1 +x:1 +高峻 1 +x:1 +次方米 1 +x:1 +枸杞 1 +x:1 +油门线 1 +x:1 +袋底 1 +x:1 +髋关节 1 +x:1 +参赛马 1 +x:1 +磊磊落落 1 +x:1 +微血管 1 +x:1 +中到大雨 1 +x:1 +桑田 1 +x:1 +淘汰药 1 +x:1 +高小 1 +x:1 +自负盈亏 1 +x:1 +高射 1 +x:1 +高尚 1 +x:1 +泊位 1 +x:1 +监督卡 1 +x:1 +黑啤酒 1 +x:1 +西雅图 1 +x:1 +百叶箱 1 +x:1 +代印 1 +x:1 +借 395 +x:395 +呜呜 1 +x:1 +熊河 1 +x:1 +累月经年 1 +x:1 +余杭市 1 +x:1 +民乐队 1 +x:1 +秦皇 1 +x:1 +有效 1 +x:1 +不成体统 1 +x:1 +塞责 1 +x:1 +代卖 1 +x:1 +国贸科 1 +x:1 +毛难族 1 +x:1 +众叛亲离 1 +x:1 +高层 1 +x:1 +丰姿 1 +x:1 +桥梁处 1 +x:1 +举例来说 1 +x:1 +卧室 1 +x:1 +传家 1 +x:1 +咳声叹气 1 +x:1 +四处 1 +x:1 +老调重弹 1 +x:1 +遥控器 1 +x:1 +什邡市 1 +x:1 +公猪 1 +x:1 +阿根廷队 1 +x:1 +宝象河 1 +x:1 +病毒性 1 +x:1 +四大 1 +x:1 +过门 1 +x:1 +架棚 1 +x:1 +饮誉中外 1 +x:1 +散步 1 +x:1 +四壁 1 +x:1 +腰杆 1 +x:1 +狐步 1 +x:1 +腊味 1 +x:1 +狭隘 1 +x:1 +宁海县 1 +x:1 +熊派 1 +x:1 +四声 1 +x:1 +扒子 1 +x:1 +投奔 1 +x:1 +承船厢 1 +x:1 +乐观 1 +x:1 +百万言 1 +x:1 +漫画展 1 +x:1 +锅巴 1 +x:1 +诸葛亮会 1 +x:1 +寝食 1 +x:1 +中堡村 1 +x:1 +门市部 1 +x:1 +宝钢 1 +x:1 +高州 1 +x:1 +林林总总 1 +x:1 +不堪造就 1 +x:1 +你 2817 +x:2817 +作文 1 +x:1 +满月 1 +x:1 +聪 18 +x:18 +千里之堤 1 +x:1 +围界 1 +x:1 +高工 1 +x:1 +官能团 1 +x:1 +复排 1 +x:1 +钎子 1 +x:1 +式子 1 +x:1 +满期 1 +x:1 +脑炎 1 +x:1 +袋形 1 +x:1 +蔓草 1 +x:1 +持旗人 1 +x:1 +低眉顺眼 1 +x:1 +自然而然 1 +x:1 +朱仙庄 1 +x:1 +卑尔根 1 +x:1 +水萍 1 +x:1 +偏离 1 +x:1 +窑门 1 +x:1 +门票 1 +x:1 +发行科 1 +x:1 +病虫 1 +x:1 +充气灯泡 1 +x:1 +冠家堡 1 +x:1 +拥护 1 +x:1 +刀山火海 1 +x:1 +吵闹 1 +x:1 +新华社 1 +x:1 +功放厂 1 +x:1 +抗议 1 +x:1 +书评界 1 +x:1 +兔饲料 1 +x:1 +无核武区 1 +x:1 +恒河沙数 1 +x:1 +书业界 1 +x:1 +监督制 1 +x:1 +镇 395 +x:395 +抗诉 1 +x:1 +偏移 1 +x:1 +廖 203 +x:203 +凤蝶 1 +x:1 +基本上 1 +x:1 +宰风 1 +x:1 +地理学家 1 +x:1 +增容 1 +x:1 +屈指可数 1 +x:1 +医学院 1 +x:1 +招兵 1 +x:1 +收视 1 +x:1 +顺藤摸瓜 1 +x:1 +迁徙期 1 +x:1 +水葱 1 +x:1 +传媒 1 +x:1 +水晶城 1 +x:1 +恐龙馆 1 +x:1 +理学 1 +x:1 +詹 38 +x:38 +牵引车 1 +x:1 +鸡公岭村 1 +x:1 +三德坊 1 +x:1 +胡乱 1 +x:1 +分分秒秒 1 +x:1 +高抗 1 +x:1 +赠送 1 +x:1 +晨钟暮鼓 1 +x:1 +浇地 1 +x:1 +中华街 1 +x:1 +核力 1 +x:1 +美洲豹 1 +x:1 +县界 1 +x:1 +侵 3 +x:3 +技术篇 1 +x:1 +太阳膜 1 +x:1 +传教 1 +x:1 +居心叵测 1 +x:1 +想不开 1 +x:1 +紫金山 1 +x:1 +提早 1 +x:1 +十室九空 1 +x:1 +岳南 1 +x:1 +痰喘 1 +x:1 +盏 63 +x:63 +高招 1 +x:1 +审核组 1 +x:1 +渔叉 1 +x:1 +超阶级 1 +x:1 +攻击性 1 +x:1 +生发油 1 +x:1 +枕头 1 +x:1 +訇然 1 +x:1 +满堂 1 +x:1 +那莫乡 1 +x:1 +收缩率 1 +x:1 +语言学界 1 +x:1 +证券业 1 +x:1 +成牛 1 +x:1 +披红挂彩 1 +x:1 +干肥 1 +x:1 +艺术史 1 +x:1 +接连 1 +x:1 +成片 1 +x:1 +临门 1 +x:1 +工力悉敌 1 +x:1 +雷神 1 +x:1 +如履平地 1 +x:1 +接近 1 +x:1 +接运 1 +x:1 +指南车 1 +x:1 +抗救灾 1 +x:1 +苏中 1 +x:1 +总支部 1 +x:1 +武乡县 1 +x:1 +反目成仇 1 +x:1 +精饲料 1 +x:1 +主讲者 1 +x:1 +挖坑 1 +x:1 +阴郁 1 +x:1 +巴新 1 +x:1 +苏丹 1 +x:1 +再接再厉 1 +x:1 +罗曼史 1 +x:1 +简短 1 +x:1 +有滋有味 1 +x:1 +无机盐 1 +x:1 +非政治性 1 +x:1 +风纪扣 1 +x:1 +桅樯 1 +x:1 +平邑县 1 +x:1 +约法 1 +x:1 +临深履薄 1 +x:1 +荞麦蜜 1 +x:1 +械 1 +x:1 +苏东 1 +x:1 +义和团 1 +x:1 +浮灰 1 +x:1 +甜糯 1 +x:1 +田秀才 1 +x:1 +高手 1 +x:1 +木樨地 1 +x:1 +通行证 1 +x:1 +接轨 1 +x:1 +极限值 1 +x:1 +水晶棺 1 +x:1 +无据 1 +x:1 +酸度 1 +x:1 +保护套 1 +x:1 +本版 1 +x:1 +威斯林 1 +x:1 +石灰岩 1 +x:1 +果园区 1 +x:1 +桌椅板凳 1 +x:1 +竞投人 1 +x:1 +系列 1 +x:1 +塞格曼说 1 +x:1 +四月 1 +x:1 +挖土 1 +x:1 +交税 1 +x:1 +高扬 1 +x:1 +翻毛 1 +x:1 +多罗米蒂 1 +x:1 +考核卡 1 +x:1 +雪茄烟 1 +x:1 +业务性 1 +x:1 +水秀园 1 +x:1 +达荷美 1 +x:1 +扬长补短 1 +x:1 +复工 1 +x:1 +歌剧界 1 +x:1 +频 17 +x:17 +人心果 1 +x:1 +余角 1 +x:1 +违禁 1 +x:1 +大年初四 1 +x:1 +四级品 1 +x:1 +齐刷刷 1 +x:1 +同调 1 +x:1 +土鲮鱼 1 +x:1 +同谋 1 +x:1 +佐餐 1 +x:1 +乡风 1 +x:1 +小麦线虫 1 +x:1 +教课 1 +x:1 +教诲 1 +x:1 +垫板 1 +x:1 +牧草 1 +x:1 +烦扰 1 +x:1 +水磨工夫 1 +x:1 +投机 1 +x:1 +满天 1 +x:1 +杂耍 1 +x:1 +超标 1 +x:1 +篆字 1 +x:1 +学科群 1 +x:1 +交管 1 +x:1 +纸壳箱 1 +x:1 +满头 1 +x:1 +太阳能 1 +x:1 +经传 1 +x:1 +含羞 1 +x:1 +教训 1 +x:1 +满处 1 +x:1 +破相 1 +x:1 +烽火台 1 +x:1 +苏俄 1 +x:1 +拭 1 +x:1 +增收 1 +x:1 +分析仪 1 +x:1 +大灰狼 1 +x:1 +代沟 1 +x:1 +增支 1 +x:1 +内源性 1 +x:1 +核发 1 +x:1 +争奇斗艳 1 +x:1 +比翼 1 +x:1 +琵琶曲 1 +x:1 +容止 1 +x:1 +光笔 1 +x:1 +原形毕露 1 +x:1 +不可终日 1 +x:1 +诗礼之家 1 +x:1 +受测人 1 +x:1 +全无氟 1 +x:1 +绞杀战 1 +x:1 +接踵 1 +x:1 +盘鼓 1 +x:1 +指甲盖儿 1 +x:1 +高挑 1 +x:1 +画龙点睛 1 +x:1 +翻身仗 1 +x:1 +蒋镇 1 +x:1 +荆州市 1 +x:1 +考核制 1 +x:1 +制度性 1 +x:1 +掬 7 +x:7 +众多 1 +x:1 +钎料 1 +x:1 +勋业 1 +x:1 +路线 1 +x:1 +佯降 1 +x:1 +观潮派 1 +x:1 +伏辩 1 +x:1 +岳北 1 +x:1 +四星 1 +x:1 +双 456 +x:456 +专务 1 +x:1 +传播 1 +x:1 +干脆 1 +x:1 +塔中 1 +x:1 +追随型 1 +x:1 +投枪 1 +x:1 +好家伙 1 +x:1 +南食店 1 +x:1 +四明 1 +x:1 +扎针 1 +x:1 +杂肥 1 +x:1 +五道沟村 1 +x:1 +王者 1 +x:1 +展会 1 +x:1 +比美 1 +x:1 +选购 1 +x:1 +皇天 1 +x:1 +笔迹 1 +x:1 +风暴潮 1 +x:1 +闸 34 +x:34 +厂矿 1 +x:1 +王府港 1 +x:1 +龙虎山 1 +x:1 +社会关系 1 +x:1 +传来 1 +x:1 +刻肌刻骨 1 +x:1 +含糊 1 +x:1 +病退 1 +x:1 +伏象 1 +x:1 +生意场 1 +x:1 +病逝 1 +x:1 +四旁 1 +x:1 +邹城市 1 +x:1 +艰难险阻 1 +x:1 +暖水瓶 1 +x:1 +鼓面 1 +x:1 +万埠镇 1 +x:1 +复建 1 +x:1 +删 12 +x:12 +鄢 16 +x:16 +四时 1 +x:1 +高悬 1 +x:1 +黄骅县 1 +x:1 +兀自 1 +x:1 +制片商 1 +x:1 +仇人 1 +x:1 +观雪 1 +x:1 +眼疾 1 +x:1 +娘子关镇 1 +x:1 +四无 1 +x:1 +四旧 1 +x:1 +殉葬 1 +x:1 +四日 1 +x:1 +土邦 1 +x:1 +超巨型 1 +x:1 +画框 1 +x:1 +石坝 1 +x:1 +汉译 1 +x:1 +变化有致 1 +x:1 +都市 1 +x:1 +石块 1 +x:1 +拉达乡 1 +x:1 +汉诗 1 +x:1 +柳杉 1 +x:1 +圆领衫 1 +x:1 +石坎 1 +x:1 +沙金 1 +x:1 +金融寡头 1 +x:1 +罚金 1 +x:1 +出苗 1 +x:1 +识文断字 1 +x:1 +南屏乡 1 +x:1 +四方 1 +x:1 +背脊 1 +x:1 +牧者 1 +x:1 +汉语 1 +x:1 +经济危机 1 +x:1 +柳条 1 +x:1 +崩岸 1 +x:1 +抗税 1 +x:1 +汉丰镇 1 +x:1 +雷管 1 +x:1 +老实话 1 +x:1 +羁绊 1 +x:1 +柳林 1 +x:1 +淡路 1 +x:1 +彩陶 1 +x:1 +武鸣 1 +x:1 +布老虎 1 +x:1 +上访户 1 +x:1 +部长 1 +x:1 +浮物 1 +x:1 +凤台县 1 +x:1 +卧柜 1 +x:1 +闺秀 1 +x:1 +佳绩 1 +x:1 +同辈 1 +x:1 +同辉 1 +x:1 +四散 1 +x:1 +传染 1 +x:1 +圣但尼 1 +x:1 +唠嗑 1 +x:1 +中山门 1 +x:1 +讯号 1 +x:1 +迁坟还耕 1 +x:1 +棋 121 +x:121 +花花肠子 1 +x:1 +感谢电 1 +x:1 +土道 1 +x:1 +地方主义 1 +x:1 +表演奖 1 +x:1 +揎拳捋袖 1 +x:1 +石城 1 +x:1 +锋芒所向 1 +x:1 +女主人 1 +x:1 +台笔 1 +x:1 +矿化度 1 +x:1 +高息 1 +x:1 +理智 1 +x:1 +挤而后工 1 +x:1 +执行 1 +x:1 +稍胜一筹 1 +x:1 +总调 1 +x:1 +停放 1 +x:1 +保洁女 1 +x:1 +孤老户 1 +x:1 +南邦府 1 +x:1 +麦芽糖 1 +x:1 +使用者 1 +x:1 +石埠 1 +x:1 +南中国海 1 +x:1 +休息天 1 +x:1 +哈佛 1 +x:1 +腰子 1 +x:1 +寒号虫 1 +x:1 +奇花异草 1 +x:1 +干菜 1 +x:1 +依赖型 1 +x:1 +彩韵 1 +x:1 +教规 1 +x:1 +前些年 1 +x:1 +装法 1 +x:1 +王英 1 +x:1 +锥形帽 1 +x:1 +大专院校 1 +x:1 +猪仔 1 +x:1 +父老 1 +x:1 +勾心斗角 1 +x:1 +星小目 1 +x:1 +太阳节 1 +x:1 +仕途 1 +x:1 +轻水 1 +x:1 +舐犊之情 1 +x:1 +投敌 1 +x:1 +药品费 1 +x:1 +观音 1 +x:1 +直言 1 +x:1 +厂甸 1 +x:1 +就读 1 +x:1 +戴眼镜者 1 +x:1 +投放 1 +x:1 +大海捞针 1 +x:1 +虬茎 1 +x:1 +烦恼 1 +x:1 +散场 1 +x:1 +除旧布新 1 +x:1 +正色片 1 +x:1 +弹子 1 +x:1 +装潢费 1 +x:1 +光秃 1 +x:1 +伏贴 1 +x:1 +比索 1 +x:1 +除夕 1 +x:1 +铬钢 1 +x:1 +核减 1 +x:1 +肽 1 +x:1 +核准 1 +x:1 +死不认账 1 +x:1 +替代物 1 +x:1 +石器 1 +x:1 +泵 3 +x:3 +浮现 1 +x:1 +翻案 1 +x:1 +教育法 1 +x:1 +语病 1 +x:1 +追思会 1 +x:1 +监狱法 1 +x:1 +轧制 1 +x:1 +三 6829 +x:6829 +殴斗 1 +x:1 +县直 1 +x:1 +海拉法 1 +x:1 +核儿 1 +x:1 +宏观世界 1 +x:1 +不期而遇 1 +x:1 +干草 1 +x:1 +学岗制 1 +x:1 +时 8182 +x:8182 +内驱力 1 +x:1 +专有名称 1 +x:1 +仙游县 1 +x:1 +主格调 1 +x:1 +临阵 1 +x:1 +光明村 1 +x:1 +资料库 1 +x:1 +论文选 1 +x:1 +一机连 1 +x:1 +复归 1 +x:1 +叫价 1 +x:1 +头昏眼花 1 +x:1 +职业装 1 +x:1 +萍聚 1 +x:1 +病重 1 +x:1 +接待费 1 +x:1 +会场 1 +x:1 +火电站 1 +x:1 +雄黄酒 1 +x:1 +黑豆峪村 1 +x:1 +监摄仪 1 +x:1 +政治处 1 +x:1 +总责 1 +x:1 +陆埠镇 1 +x:1 +总账 1 +x:1 +米花岭 1 +x:1 +甜美 1 +x:1 +桔黄色 1 +x:1 +井底蛙 1 +x:1 +群轻折轴 1 +x:1 +科纳克里 1 +x:1 +复式 1 +x:1 +心地 1 +x:1 +石围 1 +x:1 +信阳市 1 +x:1 +彩色 1 +x:1 +家属 1 +x:1 +小日子 1 +x:1 +帆船 1 +x:1 +幸福乡 1 +x:1 +卵巢 1 +x:1 +腥臭 1 +x:1 +鹊鹞 1 +x:1 +超浅 1 +x:1 +咋 44 +x:44 +复壮 1 +x:1 +泽当 1 +x:1 +痰凝 1 +x:1 +瑞安 1 +x:1 +接访 1 +x:1 +大鹿岛村 1 +x:1 +军事体育 1 +x:1 +玥 2 +x:2 +光线 1 +x:1 +翻演 1 +x:1 +交织 1 +x:1 +沙头角 1 +x:1 +光辉灿烂 1 +x:1 +妙不可言 1 +x:1 +南京城 1 +x:1 +交给 1 +x:1 +踏花被 1 +x:1 +光纤 1 +x:1 +拍卖金 1 +x:1 +新娘子 1 +x:1 +成百 1 +x:1 +殴打 1 +x:1 +归 264 +x:264 +蒸 20 +x:20 +洗礼地 1 +x:1 +军区队 1 +x:1 +百货架 1 +x:1 +宁死不屈 1 +x:1 +病险 1 +x:1 +接诊 1 +x:1 +稳妥感 1 +x:1 +九三年 1 +x:1 +暑期 1 +x:1 +病院 1 +x:1 +适应症 1 +x:1 +光绪 1 +x:1 +役畜 1 +x:1 +燹 1 +x:1 +淮阳 1 +x:1 +淮阴 1 +x:1 +传感 1 +x:1 +本相 1 +x:1 +剖开 1 +x:1 +戏曲队 1 +x:1 +高明 1 +x:1 +高昌 1 +x:1 +高昂 1 +x:1 +唠叨 1 +x:1 +压路机 1 +x:1 +小青瓦 1 +x:1 +肘 2 +x:2 +成皮 1 +x:1 +伤风 1 +x:1 +排尾 1 +x:1 +奋起直追 1 +x:1 +床边 1 +x:1 +埃松省 1 +x:1 +役龄 1 +x:1 +板门店 1 +x:1 +药都 1 +x:1 +投拍 1 +x:1 +面辅料 1 +x:1 +理性 1 +x:1 +投拆 1 +x:1 +负责者 1 +x:1 +选点 1 +x:1 +九通一平 1 +x:1 +红薯 1 +x:1 +扬剧 1 +x:1 +接警 1 +x:1 +灯心绒 1 +x:1 +植株 1 +x:1 +果园场 1 +x:1 +收集卡 1 +x:1 +憎称 1 +x:1 +植根 1 +x:1 +相像 1 +x:1 +遣 8 +x:8 +石凳 1 +x:1 +下坡路 1 +x:1 +不声不吭 1 +x:1 +制片厂 1 +x:1 +救护车队 1 +x:1 +植树 1 +x:1 +二月份 1 +x:1 +营养学家 1 +x:1 +副局级 1 +x:1 +费伦堡 1 +x:1 +力量感 1 +x:1 +简 48 +x:48 +温爱 1 +x:1 +颁行 1 +x:1 +空地导弹 1 +x:1 +散养 1 +x:1 +提案人 1 +x:1 +牧羊犬 1 +x:1 +赣西 1 +x:1 +笔 516 +x:516 +悔不当初 1 +x:1 +休息廊 1 +x:1 +散兵 1 +x:1 +逼肖 1 +x:1 +散光 1 +x:1 +彩金 1 +x:1 +万劫不复 1 +x:1 +彩釉 1 +x:1 +武馆 1 +x:1 +总评 1 +x:1 +高架 1 +x:1 +相赠 1 +x:1 +体检表 1 +x:1 +思索 1 +x:1 +所区 1 +x:1 +强化班 1 +x:1 +感谢状 1 +x:1 +沙漠王 1 +x:1 +虫媒花 1 +x:1 +教辅 1 +x:1 +卵子 1 +x:1 +翘首 1 +x:1 +计划表 1 +x:1 +航炮 1 +x:1 +万灯耀园 1 +x:1 +纳谏 1 +x:1 +北洋军阀 1 +x:1 +早造 1 +x:1 +铁案如山 1 +x:1 +抗震棚 1 +x:1 +艺术团 1 +x:1 +尘封日久 1 +x:1 +早逝 1 +x:1 +印度河 1 +x:1 +乞哀告怜 1 +x:1 +票 433 +x:433 +尿炕 1 +x:1 +装潢门面 1 +x:1 +土音 1 +x:1 +兴高采烈 1 +x:1 +反求诸己 1 +x:1 +粉糊 1 +x:1 +磁力线 1 +x:1 +早退 1 +x:1 +袋料 1 +x:1 +绽 8 +x:8 +论文集 1 +x:1 +必争之地 1 +x:1 +哈德逊 1 +x:1 +尚义 1 +x:1 +本省 1 +x:1 +硫酸钠 1 +x:1 +努美阿 1 +x:1 +锋 751 +x:751 +马种 1 +x:1 +鱼水 1 +x:1 +立项 1 +x:1 +灵石 1 +x:1 +商客居 1 +x:1 +本真 1 +x:1 +杏花 1 +x:1 +邬庙 1 +x:1 +水蛇腰 1 +x:1 +嗜欲 1 +x:1 +传情 1 +x:1 +尚书 1 +x:1 +敏感点 1 +x:1 +凶杀案 1 +x:1 +金家疃村 1 +x:1 +病毒学 1 +x:1 +产业链 1 +x:1 +叽里咕噜 1 +x:1 +床身 1 +x:1 +新西兰 1 +x:1 +阿勒泰 1 +x:1 +本着 1 +x:1 +光网 1 +x:1 +投掷 1 +x:1 +四战 1 +x:1 +高杆 1 +x:1 +成矿 1 +x:1 +南沙镇 1 +x:1 +香山 1 +x:1 +含笑 1 +x:1 +石像 1 +x:1 +浮生 1 +x:1 +尚且 1 +x:1 +饭菜 1 +x:1 +保护局 1 +x:1 +硫酸铵 1 +x:1 +每周六 1 +x:1 +小卖店 1 +x:1 +疏导岗 1 +x:1 +翻滚 1 +x:1 +议院 1 +x:1 +无债务 1 +x:1 +青冈林 1 +x:1 +管理科 1 +x:1 +硫酸铜 1 +x:1 +作教科 1 +x:1 +眼生 1 +x:1 +套话连篇 1 +x:1 +木刻水印 1 +x:1 +保苗率 1 +x:1 +异彩 1 +x:1 +关于 1 +x:1 +石化 1 +x:1 +杀菌 1 +x:1 +航班 1 +x:1 +殉职 1 +x:1 +致 287 +x:287 +学法 1 +x:1 +秦中 1 +x:1 +清唱剧 1 +x:1 +层层叠叠 1 +x:1 +年楚河 1 +x:1 +赠阅 1 +x:1 +宽大 1 +x:1 +喟然 1 +x:1 +交糅 1 +x:1 +六年制 1 +x:1 +情恳意切 1 +x:1 +痛苦 1 +x:1 +母线槽 1 +x:1 +市场准入 1 +x:1 +洄水 1 +x:1 +石匠 1 +x:1 +通行费 1 +x:1 +旱魃为虐 1 +x:1 +扒手 1 +x:1 +交粮 1 +x:1 +音乐史家 1 +x:1 +任人唯贤 1 +x:1 +接触 1 +x:1 +石南 1 +x:1 +高跟鞋 1 +x:1 +壁挂式 1 +x:1 +清清爽爽 1 +x:1 +指导制 1 +x:1 +沙门 1 +x:1 +满布 1 +x:1 +保洁工 1 +x:1 +搅乱 1 +x:1 +石印 1 +x:1 +接见 1 +x:1 +健步走 1 +x:1 +严惩不贷 1 +x:1 +限额 1 +x:1 +马稷 1 +x:1 +腰带 1 +x:1 +崩塌 1 +x:1 +靶 16 +x:16 +正误表 1 +x:1 +冷气 1 +x:1 +虑及 1 +x:1 +枧坝镇 1 +x:1 +小炉儿匠 1 +x:1 +颁证 1 +x:1 +沼液 1 +x:1 +治安警 1 +x:1 +沙锅 1 +x:1 +十条 1 +x:1 +代步 1 +x:1 +鹈鹕 1 +x:1 +超级市场 1 +x:1 +资料室 1 +x:1 +脚圈 1 +x:1 +气乎乎 1 +x:1 +越境 1 +x:1 +马童 1 +x:1 +有生之年 1 +x:1 +玻璃纤维 1 +x:1 +绥芬河市 1 +x:1 +滴香流蜜 1 +x:1 +甜竹 1 +x:1 +四慢 1 +x:1 +腊月廿一 1 +x:1 +等 17314 +x:17314 +辉银矿 1 +x:1 +复婚 1 +x:1 +满座 1 +x:1 +传接 1 +x:1 +歉 6 +x:6 +抗震歌 1 +x:1 +茶树王 1 +x:1 +伏击圈 1 +x:1 +五门堰 1 +x:1 +娘子军 1 +x:1 +购房人 1 +x:1 +坐标轴 1 +x:1 +菩提树 1 +x:1 +诊疗 1 +x:1 +清宫 1 +x:1 +新兵连 1 +x:1 +阿尔泰省 1 +x:1 +孩 5 +x:5 +监察 1 +x:1 +传授 1 +x:1 +主委 1 +x:1 +核呆 1 +x:1 +腊月廿九 1 +x:1 +架子 1 +x:1 +花园里 1 +x:1 +议长 1 +x:1 +成田 1 +x:1 +牧羊点 1 +x:1 +莫测 1 +x:1 +渺无人迹 1 +x:1 +传扬 1 +x:1 +汇合点 1 +x:1 +盘香 1 +x:1 +县政府 1 +x:1 +顾问性 1 +x:1 +石刀 1 +x:1 +酸奶 1 +x:1 +传承 1 +x:1 +石刻 1 +x:1 +选读 1 +x:1 +尽如人意 1 +x:1 +香香的 1 +x:1 +石制 1 +x:1 +有用 1 +x:1 +满当 1 +x:1 +荇草 1 +x:1 +偷车贼 1 +x:1 +薄唇 1 +x:1 +高新 1 +x:1 +浮石 1 +x:1 +上冶镇 1 +x:1 +也罢 1 +x:1 +少量 1 +x:1 +难度表 1 +x:1 +余辉 1 +x:1 +艺术品 1 +x:1 +复审 1 +x:1 +卧房 1 +x:1 +新城子 1 +x:1 +忍饥受冻 1 +x:1 +今貌 1 +x:1 +温火 1 +x:1 +长涝池村 1 +x:1 +色拉寺 1 +x:1 +破烂 1 +x:1 +白溜溜 1 +x:1 +胜券在握 1 +x:1 +富裕中农 1 +x:1 +恸哭声 1 +x:1 +罗非鱼 1 +x:1 +瑞士 1 +x:1 +文房四宝 1 +x:1 +土门 1 +x:1 +开盘价 1 +x:1 +白银市 1 +x:1 +复学 1 +x:1 +能谱 1 +x:1 +醋劲儿 1 +x:1 +嗫嚅 1 +x:1 +山南镇 1 +x:1 +高攀 1 +x:1 +毫针 1 +x:1 +针尖 1 +x:1 +庐江 1 +x:1 +隔音符号 1 +x:1 +粒 63 +x:63 +满心 1 +x:1 +高支 1 +x:1 +尼玛县 1 +x:1 +马奶酒 1 +x:1 +增援 1 +x:1 +南联盟 1 +x:1 +抑郁 1 +x:1 +富民政策 1 +x:1 +尿片 1 +x:1 +散发 1 +x:1 +轰响 1 +x:1 +土拨鼠 1 +x:1 +高效 1 +x:1 +雁翅 1 +x:1 +构造柱 1 +x:1 +迁西县 1 +x:1 +沼泽 1 +x:1 +高龄者 1 +x:1 +纳雍 1 +x:1 +高教 1 +x:1 +温热 1 +x:1 +欠产 1 +x:1 +梦幻泡影 1 +x:1 +一鳞半爪 1 +x:1 +秦俑 1 +x:1 +传抄 1 +x:1 +滹沱河畔 1 +x:1 +受访者 1 +x:1 +被特赦者 1 +x:1 +竹林镇 1 +x:1 +武魂 1 +x:1 +破灭 1 +x:1 +藤子 1 +x:1 +马坡岭 1 +x:1 +约摸 1 +x:1 +稀罕 1 +x:1 +石崖 1 +x:1 +杀跌 1 +x:1 +武钢 1 +x:1 +胶靴 1 +x:1 +启明星 1 +x:1 +干裂 1 +x:1 +金鸡沙村 1 +x:1 +光荣史 1 +x:1 +泡桐树 1 +x:1 +搭档 1 +x:1 +寻呼机 1 +x:1 +水南关村 1 +x:1 +偏下 1 +x:1 +龙曲集 1 +x:1 +水冲港 1 +x:1 +超车 1 +x:1 +吨 1304 +x:1304 +少安毋躁 1 +x:1 +艺术宫 1 +x:1 +娇生惯养 1 +x:1 +衬衣 1 +x:1 +散居 1 +x:1 +乡野 1 +x:1 +艺术家 1 +x:1 +增污 1 +x:1 +绥靖 1 +x:1 +马球 1 +x:1 +直线 1 +x:1 +经 1506 +x:1506 +街谈 1 +x:1 +默默 1 +x:1 +冤错案 1 +x:1 +芦城乡 1 +x:1 +军饷 1 +x:1 +涌出 1 +x:1 +本站 1 +x:1 +举一反三 1 +x:1 +大塘乡 1 +x:1 +针叶 1 +x:1 +突出者 1 +x:1 +散射 1 +x:1 +打私办 1 +x:1 +池屋 1 +x:1 +绿化奖 1 +x:1 +宝塔山 1 +x:1 +冰球场 1 +x:1 +珊瑚 1 +x:1 +奋身 1 +x:1 +候补 1 +x:1 +甜瓜 1 +x:1 +梅陇站 1 +x:1 +完蛋 1 +x:1 +背诵 1 +x:1 +累积 1 +x:1 +副作用 1 +x:1 +代数 1 +x:1 +新民党 1 +x:1 +寺里 1 +x:1 +厂级 1 +x:1 +呼救者 1 +x:1 +蓝矾 1 +x:1 +厂纪 1 +x:1 +环行路 1 +x:1 +整修 1 +x:1 +歌剧系 1 +x:1 +颂德 1 +x:1 +冰河期 1 +x:1 +主妇 1 +x:1 +复员 1 +x:1 +表侄 1 +x:1 +贡献度 1 +x:1 +涌入 1 +x:1 +街貌 1 +x:1 +余者 1 +x:1 +留言台 1 +x:1 +悠然 1 +x:1 +选萃 1 +x:1 +耳闻目见 1 +x:1 +尿素 1 +x:1 +艺术季 1 +x:1 +艺术学 1 +x:1 +林隙地 1 +x:1 +广州市 1 +x:1 +教育权 1 +x:1 +复合 1 +x:1 +心电图室 1 +x:1 +汶阳镇 1 +x:1 +非自身 1 +x:1 +教育村 1 +x:1 +更弦易辙 1 +x:1 +石工 1 +x:1 +约数 1 +x:1 +细伢崽 1 +x:1 +交班 1 +x:1 +不近人情 1 +x:1 +天各一方 1 +x:1 +邑 2 +x:2 +解阵党 1 +x:1 +利物浦 1 +x:1 +自纠 1 +x:1 +约敦 1 +x:1 +沙 128 +x:128 +子虚乌有 1 +x:1 +绿皮书 1 +x:1 +古装剧 1 +x:1 +滞后期 1 +x:1 +牡石化 1 +x:1 +尿糖 1 +x:1 +乳酸菌 1 +x:1 +米脂县 1 +x:1 +核定 1 +x:1 +代总裁 1 +x:1 +光环 1 +x:1 +比拉米德 1 +x:1 +硌 3 +x:3 +籍贯 1 +x:1 +养鸭户 1 +x:1 +柳江 1 +x:1 +卵块 1 +x:1 +叔婆 1 +x:1 +核对 1 +x:1 +石屏 1 +x:1 +病魔 1 +x:1 +天主教 1 +x:1 +脱毛症 1 +x:1 +洪音迭传 1 +x:1 +绥阳 1 +x:1 +渐近线 1 +x:1 +马蹄形 1 +x:1 +成筐 1 +x:1 +破绽 1 +x:1 +资料员 1 +x:1 +增派 1 +x:1 +石山 1 +x:1 +奖励制 1 +x:1 +升旗 1 +x:1 +授予权 1 +x:1 +浪费性 1 +x:1 +诉诸武力 1 +x:1 +拍片子 1 +x:1 +马甲 1 +x:1 +死心塌地 1 +x:1 +官僚资本 1 +x:1 +蓝盔 1 +x:1 +成箱 1 +x:1 +表亲 1 +x:1 +雷炮 1 +x:1 +募捐 1 +x:1 +同蒲 1 +x:1 +称兄道弟 1 +x:1 +阳台 1 +x:1 +亚 405 +x:405 +诺曼底 1 +x:1 +啥 135 +x:135 +增添 1 +x:1 +成算 1 +x:1 +冷冻箱 1 +x:1 +草木灰 1 +x:1 +蓝盾 1 +x:1 +乡道 1 +x:1 +充 30 +x:30 +线桄子 1 +x:1 +二医大 1 +x:1 +胖人 1 +x:1 +打比方 1 +x:1 +余脉 1 +x:1 +秃杉 1 +x:1 +甘草榄 1 +x:1 +高歌 1 +x:1 +胆 14 +x:14 +回答 1 +x:1 +包身工 1 +x:1 +招贤 1 +x:1 +富 319 +x:319 +偏信 1 +x:1 +四清 1 +x:1 +针剂 1 +x:1 +坝上 1 +x:1 +整人 1 +x:1 +盘面 1 +x:1 +成都籍 1 +x:1 +命赴黄泉 1 +x:1 +石峰 1 +x:1 +计划生育 1 +x:1 +痛责 1 +x:1 +电感 1 +x:1 +锦缎 1 +x:1 +筷 2 +x:2 +棕榈树 1 +x:1 +奋进 1 +x:1 +花厅 1 +x:1 +核子 1 +x:1 +甲苯 1 +x:1 +降伏 1 +x:1 +润饰 1 +x:1 +美洲虎 1 +x:1 +渊厚 1 +x:1 +高梁 1 +x:1 +西亚区 1 +x:1 +吐气扬眉 1 +x:1 +大饭厅 1 +x:1 +摩擦力 1 +x:1 +议员日 1 +x:1 +设身处地 1 +x:1 +螺纹 1 +x:1 +开创者 1 +x:1 +通辽市 1 +x:1 +酸味 1 +x:1 +惭疚 1 +x:1 +演戏 1 +x:1 +紫花地丁 1 +x:1 +依赖度 1 +x:1 +尉犁县 1 +x:1 +豆腐花 1 +x:1 +循名责实 1 +x:1 +单枪匹马 1 +x:1 +马登 1 +x:1 +蒸发器 1 +x:1 +亚锦赛 1 +x:1 +高棉 1 +x:1 +进攻型 1 +x:1 +分立式 1 +x:1 +航运局 1 +x:1 +高检 1 +x:1 +问心无愧 1 +x:1 +教育日 1 +x:1 +阴到多云 1 +x:1 +白面书生 1 +x:1 +建筑史 1 +x:1 +交点 1 +x:1 +这 23299 +x:23299 +逼迫 1 +x:1 +哄笑 1 +x:1 +孢子植物 1 +x:1 +可信度 1 +x:1 +樽俎 1 +x:1 +蓝田 1 +x:1 +虫唱 1 +x:1 +散布 1 +x:1 +逼进 1 +x:1 +增温 1 +x:1 +光热 1 +x:1 +教育 1 +x:1 +说鬼话 1 +x:1 +交火 1 +x:1 +高标 1 +x:1 +美 3385 +x:3385 +四流 1 +x:1 +使用表 1 +x:1 +理清 1 +x:1 +马盟 1 +x:1 +法王庙村 1 +x:1 +大球场 1 +x:1 +石径 1 +x:1 +保护区 1 +x:1 +四海 1 +x:1 +差点儿 1 +x:1 +高校 1 +x:1 +年高德劭 1 +x:1 +顷刻间 1 +x:1 +监督权 1 +x:1 +存项 1 +x:1 +驮篮山 1 +x:1 +畸重畸轻 1 +x:1 +北池子 1 +x:1 +晕头转向 1 +x:1 +言犹在耳 1 +x:1 +指挥若定 1 +x:1 +武陵 1 +x:1 +渊博 1 +x:1 +被诉人 1 +x:1 +投河 1 +x:1 +白杨树 1 +x:1 +空吊板 1 +x:1 +日晒雨淋 1 +x:1 +光明港 1 +x:1 +路径名 1 +x:1 +摩擦剂 1 +x:1 +雹灾 1 +x:1 +白白绿绿 1 +x:1 +蜂拥而上 1 +x:1 +淡薄 1 +x:1 +难觅 1 +x:1 +高档 1 +x:1 +推进组 1 +x:1 +高桥 1 +x:1 +破絮 1 +x:1 +扎龙 1 +x:1 +光火 1 +x:1 +杂记 1 +x:1 +马会杯 1 +x:1 +业精于勤 1 +x:1 +蒸汽化 1 +x:1 +伤脑筋 1 +x:1 +保安业 1 +x:1 +恰如其分 1 +x:1 +涌动 1 +x:1 +功放机 1 +x:1 +甲者 1 +x:1 +代替 1 +x:1 +明窗净几 1 +x:1 +街车 1 +x:1 +跨越性 1 +x:1 +豫西南 1 +x:1 +约束 1 +x:1 +无先例 1 +x:1 +背街 1 +x:1 +铺路石 1 +x:1 +粟子树 1 +x:1 +囟门 1 +x:1 +僵亡 1 +x:1 +精神损耗 1 +x:1 +瘾 25 +x:25 +通山县 1 +x:1 +复垦 1 +x:1 +斯姆哈纳 1 +x:1 +珍珠鸡 1 +x:1 +简政放权 1 +x:1 +尼日利亚 1 +x:1 +汨罗江 1 +x:1 +可用资金 1 +x:1 +角动量 1 +x:1 +本科 1 +x:1 +劲头儿 1 +x:1 +不外乎 1 +x:1 +出芽生殖 1 +x:1 +征税期 1 +x:1 +盘问 1 +x:1 +充放电 1 +x:1 +汉英 1 +x:1 +杀身 1 +x:1 +散开 1 +x:1 +讨厌 1 +x:1 +立身行事 1 +x:1 +整顿村 1 +x:1 +职业者 1 +x:1 +各尽所能 1 +x:1 +渔法 1 +x:1 +豁朗 1 +x:1 +治散治滥 1 +x:1 +浮筏 1 +x:1 +把酒言欢 1 +x:1 +呼玛 1 +x:1 +止渴 1 +x:1 +石床 1 +x:1 +阿尔萨斯 1 +x:1 +皮尔森型 1 +x:1 +控梢 1 +x:1 +超拔 1 +x:1 +挛 1 +x:1 +奎文 1 +x:1 +阳刚之美 1 +x:1 +能耗 1 +x:1 +能耐 1 +x:1 +为人处事 1 +x:1 +散心 1 +x:1 +光焰 1 +x:1 +古木参天 1 +x:1 +尚书学史 1 +x:1 +能者 1 +x:1 +兄长 1 +x:1 +干警 1 +x:1 +合运动 1 +x:1 +画匠 1 +x:1 +本社 1 +x:1 +医 65 +x:65 +动势中 1 +x:1 +淡蓝 1 +x:1 +坏死 1 +x:1 +推旧出新 1 +x:1 +圈圈 1 +x:1 +病毒唑 1 +x:1 +大米粥 1 +x:1 +长江路 1 +x:1 +扁形动物 1 +x:1 +格登 1 +x:1 +配股权 1 +x:1 +中文名 1 +x:1 +颊囊 1 +x:1 +保护剂 1 +x:1 +寸阴 1 +x:1 +良药 1 +x:1 +郊游 1 +x:1 +势单力薄 1 +x:1 +贺年卡 1 +x:1 +每份 1 +x:1 +奔驰 1 +x:1 +商业部长 1 +x:1 +清阳 1 +x:1 +高楼 1 +x:1 +控检 1 +x:1 +刑侦组 1 +x:1 +赫兹 1 +x:1 +巨幅 1 +x:1 +永无宁日 1 +x:1 +光照 1 +x:1 +隐藏 1 +x:1 +听诊器 1 +x:1 +插件 1 +x:1 +逻辑性 1 +x:1 +上吊 1 +x:1 +比特 1 +x:1 +定性关 1 +x:1 +余蓄 1 +x:1 +姗姗 1 +x:1 +陛下 1 +x:1 +雷电 1 +x:1 +年青人 1 +x:1 +早饭 1 +x:1 +乡间 1 +x:1 +交相 1 +x:1 +无赤字 1 +x:1 +贪得无厌 1 +x:1 +轮训班 1 +x:1 +打气站 1 +x:1 +熊市 1 +x:1 +翻本 1 +x:1 +闭口龟 1 +x:1 +率直 1 +x:1 +街衢 1 +x:1 +农技站 1 +x:1 +东征军 1 +x:1 +马灯 1 +x:1 +湿淋淋 1 +x:1 +本纪 1 +x:1 +石头 1 +x:1 +齿冷 1 +x:1 +胃穿孔 1 +x:1 +略胜一筹 1 +x:1 +满员 1 +x:1 +长话市话 1 +x:1 +光盘 1 +x:1 +本组 1 +x:1 +定向井 1 +x:1 +无计名 1 +x:1 +审批权 1 +x:1 +喜闻乐见 1 +x:1 +普宁寺 1 +x:1 +土黄 1 +x:1 +童服 1 +x:1 +嫁衣 1 +x:1 +杂货 1 +x:1 +冲昏头脑 1 +x:1 +黔北 1 +x:1 +选育 1 +x:1 +神与物游 1 +x:1 +散堆 1 +x:1 +四十五分 1 +x:1 +逼视 1 +x:1 +叶芽 1 +x:1 +电脑业 1 +x:1 +游途 1 +x:1 +鹿泉 1 +x:1 +气 283 +x:283 +超收 1 +x:1 +翘舌音 1 +x:1 +杂费 1 +x:1 +鸟枪换炮 1 +x:1 +接茬 1 +x:1 +含片 1 +x:1 +血球 1 +x:1 +阳原 1 +x:1 +土崩瓦解 1 +x:1 +特遣部队 1 +x:1 +雏鸡 1 +x:1 +类似 1 +x:1 +褡裢 1 +x:1 +成约 1 +x:1 +铁片大鼓 1 +x:1 +远念 1 +x:1 +乡长 1 +x:1 +高温 1 +x:1 +层子 1 +x:1 +培训费 1 +x:1 +缱绻 1 +x:1 +高渺 1 +x:1 +帷 1 +x:1 +锣鼓 1 +x:1 +逐日者 1 +x:1 +超时 1 +x:1 +越加 1 +x:1 +表演场 1 +x:1 +义卖会 1 +x:1 +惦念 1 +x:1 +大河上下 1 +x:1 +卧榻 1 +x:1 +译制 1 +x:1 +应收款 1 +x:1 +咋样 1 +x:1 +翻查 1 +x:1 +露地 1 +x:1 +连日来 1 +x:1 +防潮 1 +x:1 +雏鹰 1 +x:1 +遂昌县 1 +x:1 +难以忍受 1 +x:1 +桥下 1 +x:1 +旷世之作 1 +x:1 +甜点 1 +x:1 +高湿 1 +x:1 +菜子油 1 +x:1 +力夺 1 +x:1 +容易 1 +x:1 +寺 11 +x:11 +营火会 1 +x:1 +杂豆 1 +x:1 +营业站 1 +x:1 +柳树 1 +x:1 +省外 1 +x:1 +想不到 1 +x:1 +青铜器 1 +x:1 +复函 1 +x:1 +黔剧 1 +x:1 +痛觉 1 +x:1 +定价关 1 +x:1 +石堆 1 +x:1 +食口性 1 +x:1 +复出 1 +x:1 +营业区 1 +x:1 +铲土机 1 +x:1 +走私品 1 +x:1 +光电管 1 +x:1 +石堰 1 +x:1 +运河区 1 +x:1 +膳 2 +x:2 +朴素无华 1 +x:1 +科雷姆 1 +x:1 +干路 1 +x:1 +生殖器 1 +x:1 +石堤 1 +x:1 +汹涌澎湃 1 +x:1 +越南 1 +x:1 +杂谈 1 +x:1 +尿碱 1 +x:1 +石塔 1 +x:1 +柳桃 1 +x:1 +散失 1 +x:1 +巴村 1 +x:1 +众说不一 1 +x:1 +终端点 1 +x:1 +胜利日 1 +x:1 +核心 1 +x:1 +童星 1 +x:1 +合气道 1 +x:1 +扇面 1 +x:1 +乡土文学 1 +x:1 +轻吃重玩 1 +x:1 +垫款 1 +x:1 +奇险 1 +x:1 +甲虫 1 +x:1 +石墙 1 +x:1 +犹太人 1 +x:1 +蓝狐 1 +x:1 +艺术师 1 +x:1 +彩饰 1 +x:1 +凉溲溲 1 +x:1 +把 10301 +x:10301 +坷垃 1 +x:1 +复兴 1 +x:1 +解散 1 +x:1 +昏昏然 1 +x:1 +街角 1 +x:1 +成群 1 +x:1 +相关 1 +x:1 +峨眉泉 1 +x:1 +马尼拉麻 1 +x:1 +桥位 1 +x:1 +申报率 1 +x:1 +抗震性 1 +x:1 +永胜县 1 +x:1 +总后勤部 1 +x:1 +沙鸡 1 +x:1 +努 1 +x:1 +军调处 1 +x:1 +石墨 1 +x:1 +人民代表 1 +x:1 +悄然 1 +x:1 +柳梢 1 +x:1 +展陈 1 +x:1 +情不自禁 1 +x:1 +率真 1 +x:1 +干贝 1 +x:1 +门首 1 +x:1 +越发 1 +x:1 +石壕 1 +x:1 +察尔汗 1 +x:1 +索马里 1 +x:1 +营业税 1 +x:1 +现洋钱 1 +x:1 +监督性 1 +x:1 +类书 1 +x:1 +石壁 1 +x:1 +中年人 1 +x:1 +装饰柜 1 +x:1 +破空 1 +x:1 +八宝箱 1 +x:1 +教育所 1 +x:1 +乱蓬蓬 1 +x:1 +哈军工 1 +x:1 +干货 1 +x:1 +疯人 1 +x:1 +深居简出 1 +x:1 +比率 1 +x:1 +南京市 1 +x:1 +江洋大盗 1 +x:1 +血痂 1 +x:1 +吹拂 1 +x:1 +蜕化变质 1 +x:1 +竹叶青 1 +x:1 +壮汉 1 +x:1 +健步如飞 1 +x:1 +乡音 1 +x:1 +异文 1 +x:1 +乡韵 1 +x:1 +抓捕 1 +x:1 +滞后性 1 +x:1 +津贴 1 +x:1 +法理学界 1 +x:1 +白塔路 1 +x:1 +歪斜 1 +x:1 +涂鸦 1 +x:1 +险案 1 +x:1 +有线电报 1 +x:1 +微服私访 1 +x:1 +核岛 1 +x:1 +贪官污吏 1 +x:1 +印刻 1 +x:1 +投案 1 +x:1 +V 4 +x:4 +鼓魂 1 +x:1 +平装本 1 +x:1 +南欧 1 +x:1 +低潮 1 +x:1 +能见度 1 +x:1 +六七月 1 +x:1 +土鳖 1 +x:1 +石子 1 +x:1 +信阳县 1 +x:1 +超期 1 +x:1 +手球馆 1 +x:1 +满嘴 1 +x:1 +航管 1 +x:1 +高法 1 +x:1 +巧智 1 +x:1 +价位 1 +x:1 +巨佛 1 +x:1 +芸豆 1 +x:1 +天一池 1 +x:1 +藏学界 1 +x:1 +雷轰电闪 1 +x:1 +背负 1 +x:1 +投标 1 +x:1 +二道沟村 1 +x:1 +翻新 1 +x:1 +少顷 1 +x:1 +代换 1 +x:1 +满园 1 +x:1 +实效性 1 +x:1 +比热 1 +x:1 +赳赳雄姿 1 +x:1 +多级火箭 1 +x:1 +欢聚一堂 1 +x:1 +腰围 1 +x:1 +保护地 1 +x:1 +选色 1 +x:1 +石宫 1 +x:1 +霞彩 1 +x:1 +菖蒲 1 +x:1 +偏光镜 1 +x:1 +表演唱 1 +x:1 +说不上 1 +x:1 +石棺盖 1 +x:1 +集团公司 1 +x:1 +石室 1 +x:1 +柳毛 1 +x:1 +止步 1 +x:1 +天津队 1 +x:1 +捉 31 +x:31 +复利 1 +x:1 +键盘 1 +x:1 +复制 1 +x:1 +税警 1 +x:1 +盘道 1 +x:1 +苦大仇深 1 +x:1 +退货 1 +x:1 +瑞典 1 +x:1 +水东乡 1 +x:1 +奋发自救 1 +x:1 +畏友 1 +x:1 +瑞兽 1 +x:1 +烽火山 1 +x:1 +商奥会 1 +x:1 +奇闻 1 +x:1 +打雪仗 1 +x:1 +高汤 1 +x:1 +复刊 1 +x:1 +博物馆学 1 +x:1 +政绩观 1 +x:1 +复句 1 +x:1 +复古 1 +x:1 +牵就 1 +x:1 +滞弹性 1 +x:1 +寺院 1 +x:1 +扰流板 1 +x:1 +破碎 1 +x:1 +复叶 1 +x:1 +比照 1 +x:1 +约据 1 +x:1 +同船 1 +x:1 +高涨 1 +x:1 +新城区 1 +x:1 +航站 1 +x:1 +老奶奶 1 +x:1 +朝天椒 1 +x:1 +勐来村 1 +x:1 +农技科 1 +x:1 +复合管 1 +x:1 +贡献奖 1 +x:1 +受理费 1 +x:1 +复发 1 +x:1 +文献片 1 +x:1 +修武县 1 +x:1 +粗加工 1 +x:1 +限量 1 +x:1 +焊痕 1 +x:1 +开后门 1 +x:1 +田口乡 1 +x:1 +道貌岸然 1 +x:1 +背谬 1 +x:1 +心仪已久 1 +x:1 +满地 1 +x:1 +鄂托克 1 +x:1 +瓢 11 +x:11 +政绩表 1 +x:1 +睡椅 1 +x:1 +满场 1 +x:1 +群众组织 1 +x:1 +暑气 1 +x:1 +保护国 1 +x:1 +绿杨村 1 +x:1 +纳巴谷 1 +x:1 +三峰驼 1 +x:1 +阳历 1 +x:1 +代议长 1 +x:1 +复原 1 +x:1 +高深 1 +x:1 +五角状 1 +x:1 +采油树 1 +x:1 +航空 1 +x:1 +代扣 1 +x:1 +可获性 1 +x:1 +高洁 1 +x:1 +紫金县 1 +x:1 +佣工 1 +x:1 +教育性 1 +x:1 +相让 1 +x:1 +莫旗 1 +x:1 +复印 1 +x:1 +烟渍 1 +x:1 +农牧渔机 1 +x:1 +黄骅市 1 +x:1 +砂轮厂 1 +x:1 +安息堂 1 +x:1 +展览馆 1 +x:1 +芽包 1 +x:1 +复升 1 +x:1 +橘红 1 +x:1 +氨化池 1 +x:1 +伫 1 +x:1 +光电 1 +x:1 +满城 1 +x:1 +越冬 1 +x:1 +县立 1 +x:1 +打靶 1 +x:1 +乳山市 1 +x:1 +荣誉奖 1 +x:1 +炭山乡 1 +x:1 +德文本 1 +x:1 +使用费 1 +x:1 +麻拉热 1 +x:1 +散客 1 +x:1 +耦合度 1 +x:1 +清源西里 1 +x:1 +营运处 1 +x:1 +拼音字母 1 +x:1 +艺术展 1 +x:1 +保洁员 1 +x:1 +交电 1 +x:1 +交由 1 +x:1 +凶焰 1 +x:1 +南水关 1 +x:1 +童子军 1 +x:1 +元江 1 +x:1 +一天到晚 1 +x:1 +辅助品 1 +x:1 +大师傅 1 +x:1 +保护器 1 +x:1 +崖墓 1 +x:1 +沙鱼 1 +x:1 +延 22 +x:22 +破案率 1 +x:1 +莫方 1 +x:1 +保守主义 1 +x:1 +越东 1 +x:1 +马拉松式 1 +x:1 +从从容容 1 +x:1 +退赔 1 +x:1 +褐矮星 1 +x:1 +传略 1 +x:1 +鼠肚鸡肠 1 +x:1 +胶轮 1 +x:1 +华阳镇 1 +x:1 +泥饭碗 1 +x:1 +秦堤 1 +x:1 +党小组 1 +x:1 +粗加工品 1 +x:1 +椰林 1 +x:1 +怪话 1 +x:1 +怪诞 1 +x:1 +本报 1 +x:1 +表土 1 +x:1 +瞎子摸象 1 +x:1 +港口 1 +x:1 +坝基 1 +x:1 +拥军路 1 +x:1 +正阳县 1 +x:1 +目空一切 1 +x:1 +四知 1 +x:1 +瑞丽市 1 +x:1 +江东区 1 +x:1 +门当户对 1 +x:1 +干部 1 +x:1 +出车 1 +x:1 +烟墩乡 1 +x:1 +港台 1 +x:1 +县政 1 +x:1 +画院派 1 +x:1 +项目区 1 +x:1 +怪论 1 +x:1 +步步高升 1 +x:1 +成批 1 +x:1 +敲定 1 +x:1 +顺风耳 1 +x:1 +余额 1 +x:1 +东南麓 1 +x:1 +培训量 1 +x:1 +六里镇 1 +x:1 +电位 1 +x:1 +甜水 1 +x:1 +浮悬 1 +x:1 +不知凡几 1 +x:1 +破绽百出 1 +x:1 +尿斑 1 +x:1 +油气藏 1 +x:1 +绚丽 1 +x:1 +止痒 1 +x:1 +休馆 1 +x:1 +成才 1 +x:1 +港协 1 +x:1 +干道 1 +x:1 +本戏 1 +x:1 +重孙女 1 +x:1 +不尽人意 1 +x:1 +候诊 1 +x:1 +盘踞 1 +x:1 +坝址 1 +x:1 +理理 1 +x:1 +下三交镇 1 +x:1 +塔形 1 +x:1 +燕窝 1 +x:1 +精疲力尽 1 +x:1 +家庭教育 1 +x:1 +寺观 1 +x:1 +绥远 1 +x:1 +卧病 1 +x:1 +真理性 1 +x:1 +金华市 1 +x:1 +综合局 1 +x:1 +挟带 1 +x:1 +绿影扶疏 1 +x:1 +爱花者 1 +x:1 +流涕者 1 +x:1 +学龄儿童 1 +x:1 +望孔 1 +x:1 +昔时 1 +x:1 +泥浆味 1 +x:1 +昔日 1 +x:1 +气化率 1 +x:1 +日常性 1 +x:1 +坝地 1 +x:1 +殉难 1 +x:1 +狂妄自大 1 +x:1 +温柔 1 +x:1 +塔式 1 +x:1 +港区 1 +x:1 +教育网 1 +x:1 +肯定论 1 +x:1 +洋车夫 1 +x:1 +润色 1 +x:1 +眄 1 +x:1 +理疗 1 +x:1 +臭名昭著 1 +x:1 +装糊涂 1 +x:1 +垄沟 1 +x:1 +插口 1 +x:1 +南阜村 1 +x:1 +上线人 1 +x:1 +价值 1 +x:1 +甚或 1 +x:1 +多愁善感 1 +x:1 +硕果 1 +x:1 +甘肃省 1 +x:1 +椰枣 1 +x:1 +插叙 1 +x:1 +柳琴 1 +x:1 +三仙湖镇 1 +x:1 +成指 1 +x:1 +休风 1 +x:1 +保安员 1 +x:1 +狗尾巴草 1 +x:1 +南水北调 1 +x:1 +露馅儿 1 +x:1 +汰旧换新 1 +x:1 +东奔西走 1 +x:1 +懋 1 +x:1 +由点到面 1 +x:1 +深圳河 1 +x:1 +八家户 1 +x:1 +引航道 1 +x:1 +莫里纳 1 +x:1 +塔座 1 +x:1 +糙米 1 +x:1 +霏霏 1 +x:1 +传球 1 +x:1 +承办人 1 +x:1 +差之毫厘 1 +x:1 +写景 1 +x:1 +螺旋 1 +x:1 +蹭蹬 1 +x:1 +切记 1 +x:1 +狭 2 +x:2 +法人股 1 +x:1 +港务 1 +x:1 +嫖娼案 1 +x:1 +公路网 1 +x:1 +胎膜 1 +x:1 +年龄段 1 +x:1 +童稚 1 +x:1 +目录学 1 +x:1 +培训部 1 +x:1 +书信集 1 +x:1 +管理篇 1 +x:1 +海水浴 1 +x:1 +适得其反 1 +x:1 +民改联 1 +x:1 +分析师 1 +x:1 +荒时暴月 1 +x:1 +适应性 1 +x:1 +懂中文者 1 +x:1 +淮菜 1 +x:1 +文学语言 1 +x:1 +土窟洞 1 +x:1 +狗牙草 1 +x:1 +苏式 1 +x:1 +龙羊峡 1 +x:1 +瑞丽 1 +x:1 +海桐花 1 +x:1 +街门 1 +x:1 +沙船 1 +x:1 +巴哈马籍 1 +x:1 +甲骨 1 +x:1 +断层山 1 +x:1 +干酪 1 +x:1 +玩艺儿 1 +x:1 +病菌 1 +x:1 +非虚构型 1 +x:1 +痕迹 1 +x:1 +吾国 1 +x:1 +毛坝乡 1 +x:1 +破晓 1 +x:1 +交款 1 +x:1 +荒诞不经 1 +x:1 +罗源 1 +x:1 +皱褶 1 +x:1 +尽可能 1 +x:1 +东奔西跑 1 +x:1 +彼得格勒 1 +x:1 +平分秋色 1 +x:1 +键槽 1 +x:1 +捷 71 +x:71 +言之有物 1 +x:1 +儋州市 1 +x:1 +穿山甲 1 +x:1 +高炉 1 +x:1 +改稿 1 +x:1 +教风 1 +x:1 +棉籽油 1 +x:1 +特宽幅 1 +x:1 +随风而去 1 +x:1 +柳眉 1 +x:1 +拉三扯四 1 +x:1 +绑带 1 +x:1 +一盘散沙 1 +x:1 +良骑 1 +x:1 +削球手 1 +x:1 +吱 1 +x:1 +难兄难弟 1 +x:1 +高炮 1 +x:1 +厂主 1 +x:1 +鹧鸪 1 +x:1 +渠道 1 +x:1 +证券局 1 +x:1 +位高权重 1 +x:1 +乡试 1 +x:1 +扬尘 1 +x:1 +白沙利亚 1 +x:1 +热爱 1 +x:1 +凭高望远 1 +x:1 +偏向 1 +x:1 +复交 1 +x:1 +锅炉 1 +x:1 +要犯 1 +x:1 +吨/小时 1 +x:1 +纱包线 1 +x:1 +共同体 1 +x:1 +令人羡慕 1 +x:1 +靠山 1 +x:1 +光棍 1 +x:1 +语气助词 1 +x:1 +哈市 1 +x:1 +无往不胜 1 +x:1 +综合店 1 +x:1 +文钱 1 +x:1 +高热 1 +x:1 +砸烂 1 +x:1 +高烧 1 +x:1 +立功奖 1 +x:1 +脑溢血 1 +x:1 +尝鼎一脔 1 +x:1 +梦魂萦绕 1 +x:1 +珊溪 1 +x:1 +马口铁 1 +x:1 +塌实 1 +x:1 +破旧 1 +x:1 +安家立业 1 +x:1 +传真 1 +x:1 +投球 1 +x:1 +彩虹 1 +x:1 +挺括 1 +x:1 +扶残 1 +x:1 +奎松 1 +x:1 +管家 1 +x:1 +港元 1 +x:1 +八乡四邻 1 +x:1 +小尾寒羊 1 +x:1 +杀青 1 +x:1 +传石 1 +x:1 +增益 1 +x:1 +东海县 1 +x:1 +喜怒 1 +x:1 +靠岸 1 +x:1 +报嫂 1 +x:1 +光栅 1 +x:1 +光标 1 +x:1 +珍珠 1 +x:1 +本性 1 +x:1 +监督网 1 +x:1 +斗牛场 1 +x:1 +垄断者 1 +x:1 +地角天涯 1 +x:1 +怔住 1 +x:1 +生产队长 1 +x:1 +诿责 1 +x:1 +学具 1 +x:1 +航材 1 +x:1 +启 27 +x:27 +饭钵 1 +x:1 +定州市 1 +x:1 +张茹集村 1 +x:1 +饭钱 1 +x:1 +谬误 1 +x:1 +锅灶 1 +x:1 +真假难辨 1 +x:1 +总产值 1 +x:1 +英格兰 1 +x:1 +液泡 1 +x:1 +丝绸版 1 +x:1 +教文体委 1 +x:1 +线束用 1 +x:1 +乐陵市 1 +x:1 +奇观 1 +x:1 +汉魏 1 +x:1 +指鹿为马 1 +x:1 +平板仪 1 +x:1 +历史主义 1 +x:1 +代缴 1 +x:1 +彩蘑 1 +x:1 +本息 1 +x:1 +收效甚微 1 +x:1 +飞跃性 1 +x:1 +信教者 1 +x:1 +喜形于色 1 +x:1 +预祝 1 +x:1 +含水 1 +x:1 +侄媳妇 1 +x:1 +复业 1 +x:1 +饭锅 1 +x:1 +尼泊尔籍 1 +x:1 +复信 1 +x:1 +容积 1 +x:1 +( 23888 +x:23888 +露宿风餐 1 +x:1 +水产场 1 +x:1 +觊觎 1 +x:1 +瓶口 1 +x:1 +剂子 1 +x:1 +内流河 1 +x:1 +金家寨 1 +x:1 +街面 1 +x:1 +吉水县 1 +x:1 +木芙蓉 1 +x:1 +冰冻期 1 +x:1 +翻砂 1 +x:1 +使用量 1 +x:1 +首尾相应 1 +x:1 +监督组 1 +x:1 +龙凤区 1 +x:1 +盈鼻 1 +x:1 +贵宾室 1 +x:1 +繁复 1 +x:1 +舶 1 +x:1 +沙湾镇 1 +x:1 +教育系 1 +x:1 +整合 1 +x:1 +付清 1 +x:1 +坚忍不拔 1 +x:1 +架份 1 +x:1 +蓝水 1 +x:1 +称多县 1 +x:1 +樵夫 1 +x:1 +歌剧本 1 +x:1 +十点 1 +x:1 +蒋墅镇 1 +x:1 +琼浆玉露 1 +x:1 +苏州 1 +x:1 +毗河 1 +x:1 +矿业权 1 +x:1 +省柴灶 1 +x:1 +串并联 1 +x:1 +片假名 1 +x:1 +衢州 1 +x:1 +葺 1 +x:1 +摩天楼 1 +x:1 +适应房 1 +x:1 +流转 1 +x:1 +防寒服 1 +x:1 +背部 1 +x:1 +塔山 1 +x:1 +插入 1 +x:1 +及时雨 1 +x:1 +笛 3 +x:3 +秦宫 1 +x:1 +暑热 1 +x:1 +母线 1 +x:1 +箢箕 1 +x:1 +复位 1 +x:1 +架上 1 +x:1 +地形图 1 +x:1 +豚鼠 1 +x:1 +盘货 1 +x:1 +析出 1 +x:1 +过夜 1 +x:1 +蒙城县 1 +x:1 +孙陆村 1 +x:1 +桥党 1 +x:1 +善教者 1 +x:1 +奇袭 1 +x:1 +园艺节 1 +x:1 +厂方 1 +x:1 +滁县 1 +x:1 +望塔 1 +x:1 +袋猫 1 +x:1 +掘开 1 +x:1 +蒙古图村 1 +x:1 +白色恐怖 1 +x:1 +层次性 1 +x:1 +解放中路 1 +x:1 +送行人 1 +x:1 +议联 1 +x:1 +表哥 1 +x:1 +哄抬 1 +x:1 +产业部 1 +x:1 +橘子园 1 +x:1 +塔尖 1 +x:1 +抗拉力 1 +x:1 +交椅 1 +x:1 +哄抢 1 +x:1 +高照 1 +x:1 +复合板 1 +x:1 +喝六呼么 1 +x:1 +理睬 1 +x:1 +主任室 1 +x:1 +复会 1 +x:1 +港城 1 +x:1 +背面 1 +x:1 +光溜 1 +x:1 +蛾眉 1 +x:1 +尝尝 1 +x:1 +光源 1 +x:1 +土蚕 1 +x:1 +小口径 1 +x:1 +平房院 1 +x:1 +街道 1 +x:1 +主题团会 1 +x:1 +倘 25 +x:25 +尚志 1 +x:1 +硝酸盐 1 +x:1 +无言以答 1 +x:1 +三合会 1 +x:1 +接 420 +x:420 +代种 1 +x:1 +僵冷 1 +x:1 +明星赛 1 +x:1 +马桩 1 +x:1 +马桶 1 +x:1 +分析家 1 +x:1 +单立人儿 1 +x:1 +类型 1 +x:1 +温室群 1 +x:1 +厂房 1 +x:1 +瓮安县 1 +x:1 +辛店村 1 +x:1 +秦山 1 +x:1 +以貌取人 1 +x:1 +光敏核 1 +x:1 +光滑 1 +x:1 +免费餐 1 +x:1 +非工作 1 +x:1 +正式工 1 +x:1 +脑室 1 +x:1 +容纳 1 +x:1 +液氮 1 +x:1 +系主任 1 +x:1 +半圆形 1 +x:1 +进出港 1 +x:1 +金矿脉 1 +x:1 +光滩 1 +x:1 +存款单 1 +x:1 +武装 1 +x:1 +沼气 1 +x:1 +作假者 1 +x:1 +四环 1 +x:1 +整取 1 +x:1 +货主方 1 +x:1 +退格符 1 +x:1 +太平山 1 +x:1 +马棚 1 +x:1 +秦岭 1 +x:1 +温控 1 +x:1 +用餐室 1 +x:1 +选项 1 +x:1 +脑子 1 +x:1 +克勤克俭 1 +x:1 +脑存 1 +x:1 +注音字母 1 +x:1 +透亮度 1 +x:1 +猫哭老鼠 1 +x:1 +不及格者 1 +x:1 +投资人 1 +x:1 +掣肘 1 +x:1 +地图学家 1 +x:1 +电解质 1 +x:1 +信宜市 1 +x:1 +仓满库盈 1 +x:1 +插嘴 1 +x:1 +观者 1 +x:1 +侧翼 1 +x:1 +乡贤 1 +x:1 +断层处 1 +x:1 +访谈录 1 +x:1 +轮换制 1 +x:1 +浑 10 +x:10 +垂手而得 1 +x:1 +成家立业 1 +x:1 +交游 1 +x:1 +时代感 1 +x:1 +万隆 1 +x:1 +涛声 1 +x:1 +枪榴弹 1 +x:1 +正手球 1 +x:1 +鼓膜 1 +x:1 +地铁站 1 +x:1 +赴宴 1 +x:1 +宰牲节 1 +x:1 +奇迹 1 +x:1 +坝区 1 +x:1 +上议院 1 +x:1 +灭顶之灾 1 +x:1 +助残 1 +x:1 +太阳镜 1 +x:1 +武行 1 +x:1 +嘉奖令 1 +x:1 +银装素裹 1 +x:1 +清风明月 1 +x:1 +黄檗罗 1 +x:1 +徇 1 +x:1 +埃文 1 +x:1 +猪苗 1 +x:1 +溶液 1 +x:1 +验伪机 1 +x:1 +警觉性 1 +x:1 +桥基 1 +x:1 +比武 1 +x:1 +统治阶级 1 +x:1 +牌匾 1 +x:1 +与世沉浮 1 +x:1 +成本 1 +x:1 +池座 1 +x:1 +罗宾岛 1 +x:1 +大庄矿 1 +x:1 +胡子 1 +x:1 +埃方 1 +x:1 +股长 1 +x:1 +常青藤 1 +x:1 +红十一团 1 +x:1 +三合一 1 +x:1 +金家巷 1 +x:1 +小店村 1 +x:1 +刘海 1 +x:1 +王铜 1 +x:1 +镀 14 +x:14 +三提五统 1 +x:1 +记忆犹新 1 +x:1 +背包带 1 +x:1 +雷池 1 +x:1 +郧县 1 +x:1 +法会 1 +x:1 +干燥化 1 +x:1 +教龄 1 +x:1 +背阴 1 +x:1 +电信 1 +x:1 +小分队 1 +x:1 +财贸所 1 +x:1 +似理非理 1 +x:1 +高矗 1 +x:1 +公民院 1 +x:1 +成材 1 +x:1 +高矮 1 +x:1 +难以言状 1 +x:1 +桥型 1 +x:1 +切碎机 1 +x:1 +暑瘟 1 +x:1 +高知 1 +x:1 +扇车 1 +x:1 +满期者 1 +x:1 +陀螺 1 +x:1 +雷汞 1 +x:1 +休息亭 1 +x:1 +吁 2 +x:2 +仇外 1 +x:1 +谢意 1 +x:1 +楷模 1 +x:1 +猪苓 1 +x:1 +格格 1 +x:1 +属吏 1 +x:1 +破戒 1 +x:1 +本月 1 +x:1 +传热 1 +x:1 +正中要害 1 +x:1 +价工发 1 +x:1 +骄傲自满 1 +x:1 +留言人 1 +x:1 +本期 1 +x:1 +营业所 1 +x:1 +土蜂 1 +x:1 +伊春市 1 +x:1 +二不图利 1 +x:1 +政党法 1 +x:1 +偏压 1 +x:1 +表功 1 +x:1 +胰 1 +x:1 +比比 1 +x:1 +桥址 1 +x:1 +成果 1 +x:1 +盲棋 1 +x:1 +述职 1 +x:1 +颤颤巍巍 1 +x:1 +蜈蚣 1 +x:1 +县情 1 +x:1 +马槽 1 +x:1 +靠实 1 +x:1 +卸甲坪乡 1 +x:1 +溶洞 1 +x:1 +从谏如流 1 +x:1 +桑干 1 +x:1 +秦巴 1 +x:1 +茶色素厂 1 +x:1 +林家屯乡 1 +x:1 +土蝗 1 +x:1 +审批组 1 +x:1 +刨冰 1 +x:1 +早育 1 +x:1 +或然性 1 +x:1 +将功赎罪 1 +x:1 +本村 1 +x:1 +三和土 1 +x:1 +一业化 1 +x:1 +偏右 1 +x:1 +被领导者 1 +x:1 +接驳 1 +x:1 +临泽县 1 +x:1 +朱膘色 1 +x:1 +沙虫 1 +x:1 +本来 1 +x:1 +四爷 1 +x:1 +时代性 1 +x:1 +乡谈 1 +x:1 +代码 1 +x:1 +乡谊 1 +x:1 +秦川 1 +x:1 +秦州 1 +x:1 +试举 1 +x:1 +应征 1 +x:1 +丁腈橡胶 1 +x:1 +综合处 1 +x:1 +孙儿 1 +x:1 +五柳街 1 +x:1 +福至心灵 1 +x:1 +尚兴村 1 +x:1 +涨势 1 +x:1 +苏子 1 +x:1 +控申 1 +x:1 +心心相印 1 +x:1 +简明扼要 1 +x:1 +无水害 1 +x:1 +金霉素 1 +x:1 +红艳艳 1 +x:1 +桂元 1 +x:1 +渐 89 +x:89 +合众国 1 +x:1 +主棺 1 +x:1 +朱槿 1 +x:1 +溶溶 1 +x:1 +鼓荡 1 +x:1 +助长 1 +x:1 +漫画界 1 +x:1 +肿瘤 1 +x:1 +五保户 1 +x:1 +乐得 1 +x:1 +入海口 1 +x:1 +省宝 1 +x:1 +难以启齿 1 +x:1 +一得之见 1 +x:1 +奋发图强 1 +x:1 +瞎奶 1 +x:1 +新颖性 1 +x:1 +交法 1 +x:1 +监督箱 1 +x:1 +全天然 1 +x:1 +老字号 1 +x:1 +代管 1 +x:1 +三四季度 1 +x:1 +螺髻山 1 +x:1 +约稿 1 +x:1 +螺丝钉 1 +x:1 +超编 1 +x:1 +超标率 1 +x:1 +五里桥乡 1 +x:1 +偏偏 1 +x:1 +抽油烟机 1 +x:1 +光泽 1 +x:1 +倾向性 1 +x:1 +外厂 1 +x:1 +诩 1 +x:1 +一批 1 +x:1 +恋爱 1 +x:1 +总额 1 +x:1 +地形区 1 +x:1 +翱 1 +x:1 +柜内 1 +x:1 +蝶 13 +x:13 +球蛋白 1 +x:1 +教育科 1 +x:1 +刨刀 1 +x:1 +光波 1 +x:1 +庄河市 1 +x:1 +无量数 1 +x:1 +保护伞 1 +x:1 +婴戏纹 1 +x:1 +港商 1 +x:1 +大朝山 1 +x:1 +苏堤 1 +x:1 +光气 1 +x:1 +斥之为 1 +x:1 +汤峪镇 1 +x:1 +茶夹 1 +x:1 +刑事犯 1 +x:1 +表冠 1 +x:1 +九年制 1 +x:1 +实 361 +x:361 +莱阳市 1 +x:1 +孕穗期 1 +x:1 +一味 1 +x:1 +交汇 1 +x:1 +雷击火 1 +x:1 +小先生 1 +x:1 +表册 1 +x:1 +杂音 1 +x:1 +彩船 1 +x:1 +厂情 1 +x:1 +津门 1 +x:1 +盘行 1 +x:1 +土著 1 +x:1 +炔雌醚 1 +x:1 +偏僻 1 +x:1 +焉 48 +x:48 +满人 1 +x:1 +桥名 1 +x:1 +童心未泯 1 +x:1 +既 2128 +x:2128 +布莱夏 1 +x:1 +整冻 1 +x:1 +侮辱性 1 +x:1 +拓荒 1 +x:1 +理工学院 1 +x:1 +土葬 1 +x:1 +少者 1 +x:1 +本体论 1 +x:1 +远在天边 1 +x:1 +代笔 1 +x:1 +武装带 1 +x:1 +本文 1 +x:1 +脑壳 1 +x:1 +坛子 1 +x:1 +声道 1 +x:1 +扇贝 1 +x:1 +杂陈 1 +x:1 +宅院 1 +x:1 +奇谈 1 +x:1 +烦琐 1 +x:1 +仇家 1 +x:1 +学制 1 +x:1 +杂院 1 +x:1 +直板 1 +x:1 +监督站 1 +x:1 +国库部 1 +x:1 +宏昌里 1 +x:1 +电脑商 1 +x:1 +蓝桥 1 +x:1 +永济市 1 +x:1 +顺杆儿爬 1 +x:1 +四热 1 +x:1 +光润 1 +x:1 +成数 1 +x:1 +武说 1 +x:1 +袈裟 1 +x:1 +八仙桌 1 +x:1 +胡天 1 +x:1 +太阳雨 1 +x:1 +小宝宝 1 +x:1 +添设 1 +x:1 +林州市 1 +x:1 +毓 1 +x:1 +君山区队 1 +x:1 +教育学系 1 +x:1 +行车者 1 +x:1 +三门河乡 1 +x:1 +偏关 1 +x:1 +巨野县 1 +x:1 +赵州桥 1 +x:1 +万籁俱寂 1 +x:1 +接风 1 +x:1 +玉泉村 1 +x:1 +鼓舞 1 +x:1 +偏光 1 +x:1 +交涉 1 +x:1 +投其所好 1 +x:1 +四点 1 +x:1 +成教 1 +x:1 +渤海湾 1 +x:1 +保护价 1 +x:1 +腰伤 1 +x:1 +戛 1 +x:1 +成效 1 +x:1 +鬃刷 1 +x:1 +予以 1 +x:1 +一举一动 1 +x:1 +寸草寸金 1 +x:1 +成方 1 +x:1 +婴儿车 1 +x:1 +维生素甲 1 +x:1 +袭用 1 +x:1 +超绝 1 +x:1 +光洋 1 +x:1 +打折扣 1 +x:1 +王陵 1 +x:1 +建校费 1 +x:1 +光洁 1 +x:1 +哈密 1 +x:1 +马毛 1 +x:1 +雄风 1 +x:1 +稻子 1 +x:1 +证券委 1 +x:1 +疑问句 1 +x:1 +成料 1 +x:1 +挡风墙 1 +x:1 +干靠 1 +x:1 +分子筛 1 +x:1 +白银丸 1 +x:1 +高田 1 +x:1 +太阳队 1 +x:1 +璞河镇 1 +x:1 +高息揽存 1 +x:1 +乌蒙山 1 +x:1 +饭量 1 +x:1 +凶狂 1 +x:1 +质量上乘 1 +x:1 +晚秋作物 1 +x:1 +政治课 1 +x:1 +武警 1 +x:1 +盖 262 +x:262 +扎花 1 +x:1 +悠游 1 +x:1 +我厂 1 +x:1 +轮奸案 1 +x:1 +璜塘镇 1 +x:1 +板胡曲 1 +x:1 +本格拉省 1 +x:1 +超级 1 +x:1 +市地行 1 +x:1 +摆地摊 1 +x:1 +锨把 1 +x:1 +盘西 1 +x:1 +本数 1 +x:1 +营业性 1 +x:1 +温情 1 +x:1 +怪调 1 +x:1 +海城市 1 +x:1 +寡不敌众 1 +x:1 +名胜古迹 1 +x:1 +塔基 1 +x:1 +饮马锦江 1 +x:1 +一览 1 +x:1 +刃片 1 +x:1 +早起 1 +x:1 +格方 1 +x:1 +字字句句 1 +x:1 +航运业 1 +x:1 +狐狸 1 +x:1 +脱离速度 1 +x:1 +拘于 1 +x:1 +牧马 1 +x:1 +三合堡村 1 +x:1 +摔跟头 1 +x:1 +疯子 1 +x:1 +格斗 1 +x:1 +垄断 1 +x:1 +沁入 1 +x:1 +人身险 1 +x:1 +议议 1 +x:1 +辰光杯 1 +x:1 +一门心思 1 +x:1 +小熊猫 1 +x:1 +塔城 1 +x:1 +议论 1 +x:1 +总集 1 +x:1 +棕榈科 1 +x:1 +西泠 1 +x:1 +整形 1 +x:1 +腺体 1 +x:1 +技能型 1 +x:1 +致病菌 1 +x:1 +桑叶 1 +x:1 +居功自恃 1 +x:1 +表彰 1 +x:1 +降旗队 1 +x:1 +猫猫关 1 +x:1 +世面 1 +x:1 +干预 1 +x:1 +淡露 1 +x:1 +虔 2 +x:2 +无望 1 +x:1 +望台 1 +x:1 +休渔期 1 +x:1 +帘内 1 +x:1 +港客 1 +x:1 +一片哗然 1 +x:1 +柳絮 1 +x:1 +岩盐 1 +x:1 +蓝本 1 +x:1 +交投 1 +x:1 +椴木丛村 1 +x:1 +高程 1 +x:1 +大慈大悲 1 +x:1 +子母扣儿 1 +x:1 +胎衣 1 +x:1 +白肩雕 1 +x:1 +发财图 1 +x:1 +分体式 1 +x:1 +总院 1 +x:1 +警长制 1 +x:1 +建管局 1 +x:1 +控管 1 +x:1 +主教团 1 +x:1 +力尽筋疲 1 +x:1 +备付金率 1 +x:1 +东风路 1 +x:1 +交手 1 +x:1 +超薄型 1 +x:1 +浮桥 1 +x:1 +偏废 1 +x:1 +航测 1 +x:1 +费 242 +x:242 +刀斫斧砍 1 +x:1 +汉中门 1 +x:1 +祁 26 +x:26 +涂装 1 +x:1 +鼓足 1 +x:1 +枯枝败叶 1 +x:1 +孙桥镇 1 +x:1 +浮标 1 +x:1 +锒铛入狱 1 +x:1 +玛雅 1 +x:1 +吻别 1 +x:1 +尼龙伞 1 +x:1 +富集点 1 +x:1 +中村梁子 1 +x:1 +消防员 1 +x:1 +应价者 1 +x:1 +逾期 1 +x:1 +总队 1 +x:1 +临走 1 +x:1 +高空 1 +x:1 +机器厂 1 +x:1 +交战 1 +x:1 +非行政性 1 +x:1 +花榈木 1 +x:1 +信宜县 1 +x:1 +洗手不干 1 +x:1 +恶鬼 1 +x:1 +缄 1 +x:1 +引航人 1 +x:1 +主副食品 1 +x:1 +驴子 1 +x:1 +偷鸡摸狗 1 +x:1 +温温 1 +x:1 +航标区 1 +x:1 +性欲 1 +x:1 +约略 1 +x:1 +流氓罪 1 +x:1 +表带 1 +x:1 +嫩白 1 +x:1 +西装革履 1 +x:1 +伤 215 +x:215 +榨菜 1 +x:1 +感人至深 1 +x:1 +政企不分 1 +x:1 +整年 1 +x:1 +江门市 1 +x:1 +真面目 1 +x:1 +侧线 1 +x:1 +哭天喊地 1 +x:1 +血本无归 1 +x:1 +哪家 1 +x:1 +干馕 1 +x:1 +土话 1 +x:1 +白葡萄酒 1 +x:1 +航油 1 +x:1 +温湿 1 +x:1 +适合 1 +x:1 +如泣如诉 1 +x:1 +交接 1 +x:1 +滴水成冰 1 +x:1 +谢恩 1 +x:1 +腐 20 +x:20 +精湛 1 +x:1 +成武 1 +x:1 +保安局 1 +x:1 +目高于顶 1 +x:1 +玄武湖 1 +x:1 +酱紫 1 +x:1 +举目无亲 1 +x:1 +奇艳 1 +x:1 +投缘 1 +x:1 +四纵 1 +x:1 +太阳风 1 +x:1 +家蝇 1 +x:1 +竭 2 +x:2 +龙眠河 1 +x:1 +土语 1 +x:1 +四级 1 +x:1 +制片业 1 +x:1 +阿西西 1 +x:1 +分析图 1 +x:1 +池洞镇 1 +x:1 +太平军 1 +x:1 +险景 1 +x:1 +靠垫 1 +x:1 +观赏 1 +x:1 +交换 1 +x:1 +特拉华河 1 +x:1 +众望所归 1 +x:1 +花红叶绿 1 +x:1 +岳阳道 1 +x:1 +攀高枝 1 +x:1 +护送 1 +x:1 +神龙 1 +x:1 +刨工 1 +x:1 +插孔 1 +x:1 +信皮儿 1 +x:1 +淡雅 1 +x:1 +僵尸 1 +x:1 +本次 1 +x:1 +东南面 1 +x:1 +归行率 1 +x:1 +执行庭 1 +x:1 +一体化 1 +x:1 +加里萨 1 +x:1 +虎牙 1 +x:1 +燕王 1 +x:1 +桥孔 1 +x:1 +古人类 1 +x:1 +退伍军人 1 +x:1 +五官科 1 +x:1 +去伪存真 1 +x:1 +魁北克省 1 +x:1 +高等 1 +x:1 +水稻所 1 +x:1 +自由放任 1 +x:1 +南洋 1 +x:1 +含有 1 +x:1 +前车牌 1 +x:1 +电脑室 1 +x:1 +知识量 1 +x:1 +小动作 1 +x:1 +颠颠簸簸 1 +x:1 +不管部长 1 +x:1 +制片人 1 +x:1 +安次区 1 +x:1 +高筒 1 +x:1 +木勺 1 +x:1 +僵局 1 +x:1 +乡老 1 +x:1 +联想式 1 +x:1 +佛牙 1 +x:1 +价值论 1 +x:1 +红莹莹 1 +x:1 +老K 1 +x:1 +杏黄 1 +x:1 +偏心 1 +x:1 +分析器 1 +x:1 +青春片 1 +x:1 +无核区 1 +x:1 +生理学 1 +x:1 +威廉斯堡 1 +x:1 +嗜睡 1 +x:1 +酒店业 1 +x:1 +顾问组 1 +x:1 +吃大户 1 +x:1 +马方 1 +x:1 +稀 28 +x:28 +翻然 1 +x:1 +资金额 1 +x:1 +柳编 1 +x:1 +烟云过眼 1 +x:1 +伯 2 +x:2 +每周五 1 +x:1 +五道岗 1 +x:1 +散乱 1 +x:1 +肺静脉 1 +x:1 +孩童 1 +x:1 +选集 1 +x:1 +透透的 1 +x:1 +赠言 1 +x:1 +财势 1 +x:1 +砸碎 1 +x:1 +胸内外科 1 +x:1 +红脸 1 +x:1 +交情 1 +x:1 +敲击 1 +x:1 +类如 1 +x:1 +心照不宣 1 +x:1 +通车量 1 +x:1 +开户 1 +x:1 +推介会 1 +x:1 +非提速 1 +x:1 +桥墩 1 +x:1 +精气神儿 1 +x:1 +啊 398 +x:398 +孙庄 1 +x:1 +甲酚 1 +x:1 +临近 1 +x:1 +电令 1 +x:1 +胡吹 1 +x:1 +沙角 1 +x:1 +义务劳动 1 +x:1 +司售人员 1 +x:1 +汤 196 +x:196 +满满当当 1 +x:1 +芭蕾舞史 1 +x:1 +甲酸 1 +x:1 +胡同 1 +x:1 +甘肃籍 1 +x:1 +价字 1 +x:1 +能量 1 +x:1 +甲酯 1 +x:1 +与共 1 +x:1 +未成年人 1 +x:1 +每周三 1 +x:1 +经验性 1 +x:1 +剧艺学 1 +x:1 +本栏 1 +x:1 +花池村 1 +x:1 +每周一 1 +x:1 +甲醚 1 +x:1 +甲醛 1 +x:1 +安安静静 1 +x:1 +甲醇 1 +x:1 +嫂子 1 +x:1 +兴地 1 +x:1 +青梅市 1 +x:1 +自行其事 1 +x:1 +散件 1 +x:1 +格木 1 +x:1 +输变电站 1 +x:1 +翔飞 1 +x:1 +本校 1 +x:1 +狐仙 1 +x:1 +时代潮 1 +x:1 +竞投品 1 +x:1 +皇太后 1 +x:1 +壤土 1 +x:1 +镇压 1 +x:1 +永济厂 1 +x:1 +猫腻 1 +x:1 +帐房村 1 +x:1 +内避套 1 +x:1 +章法 1 +x:1 +自强心 1 +x:1 +拐子 1 +x:1 +本案 1 +x:1 +黑山羊 1 +x:1 +同音 1 +x:1 +花园路 1 +x:1 +部手机 1 +x:1 +子午卯酉 1 +x:1 +定海 1 +x:1 +终端机 1 +x:1 +高硕 1 +x:1 +杀鸡吓猴 1 +x:1 +桅灯 1 +x:1 +婉转 1 +x:1 +教育界 1 +x:1 +仪仗队 1 +x:1 +光电池 1 +x:1 +抽紧 1 +x:1 +亚松森 1 +x:1 +刨床 1 +x:1 +明水 1 +x:1 +发行所 1 +x:1 +美洲隼 1 +x:1 +无锡县 1 +x:1 +贼眉鼠眼 1 +x:1 +沁县 1 +x:1 +农家肥 1 +x:1 +沙袋 1 +x:1 +嫂嫂 1 +x:1 +银信 1 +x:1 +相视 1 +x:1 +仰天长叹 1 +x:1 +温水 1 +x:1 +外乡人 1 +x:1 +莱沃恰 1 +x:1 +加枝添叶 1 +x:1 +自然观 1 +x:1 +学位办 1 +x:1 +马来 1 +x:1 +说不定 1 +x:1 +审核方 1 +x:1 +赏心悦目 1 +x:1 +励 15 +x:15 +怪胎 1 +x:1 +证券商 1 +x:1 +管道工 1 +x:1 +翠林村 1 +x:1 +散体 1 +x:1 +同队 1 +x:1 +和服 1 +x:1 +显 159 +x:159 +五显镇 1 +x:1 +先遣组 1 +x:1 +出发点 1 +x:1 +滋阳湖 1 +x:1 +各负其责 1 +x:1 +下湖村 1 +x:1 +弦乐队 1 +x:1 +增编 1 +x:1 +宝顶 1 +x:1 +养机户 1 +x:1 +炮兵部 1 +x:1 +中段水 1 +x:1 +得鱼忘筌 1 +x:1 +高科 1 +x:1 +笔端 1 +x:1 +腽肭脐 1 +x:1 +四舍五入 1 +x:1 +价电子 1 +x:1 +贵宾厅 1 +x:1 +温江 1 +x:1 +先赋 1 +x:1 +超标车 1 +x:1 +马术 1 +x:1 +相持不下 1 +x:1 +印 651 +x:651 +散伙 1 +x:1 +炸药桶 1 +x:1 +表层 1 +x:1 +驹子 1 +x:1 +综合型 1 +x:1 +赠订 1 +x:1 +小麦面 1 +x:1 +鸦雀无声 1 +x:1 +蓝兮兮 1 +x:1 +嘉 34 +x:34 +了不得 1 +x:1 +热电效应 1 +x:1 +甜柚 1 +x:1 +悠扬 1 +x:1 +生意人 1 +x:1 +职业部 1 +x:1 +挂空档 1 +x:1 +趁火打劫 1 +x:1 +猛 99 +x:99 +彩车 1 +x:1 +三机局 1 +x:1 +地理系 1 +x:1 +饰演 1 +x:1 +背风 1 +x:1 +甜柿 1 +x:1 +芸香 1 +x:1 +灯笼罩 1 +x:1 +炒作者 1 +x:1 +冷溲溲 1 +x:1 +面对面 1 +x:1 +传统 1 +x:1 +插头 1 +x:1 +偏差 1 +x:1 +尝受 1 +x:1 +被叫方 1 +x:1 +比方 1 +x:1 +偏巧 1 +x:1 +三官庙矿 1 +x:1 +艄公 1 +x:1 +航港 1 +x:1 +导出 1 +x:1 +知难而退 1 +x:1 +校尉营 1 +x:1 +桥头 1 +x:1 +遗物 1 +x:1 +高祖 1 +x:1 +航渡 1 +x:1 +太平区 1 +x:1 +好日子 1 +x:1 +有限花序 1 +x:1 +捶胸顿足 1 +x:1 +九王庄村 1 +x:1 +拦 44 +x:44 +狼吞虎咽 1 +x:1 +港堤 1 +x:1 +马枪 1 +x:1 +毁灭性 1 +x:1 +孟加拉 1 +x:1 +马架 1 +x:1 +塔吊 1 +x:1 +甜枣 1 +x:1 +呼盟 1 +x:1 +咫步之遥 1 +x:1 +影落波摇 1 +x:1 +芭蕾舞剧 1 +x:1 +行走不便 1 +x:1 +千载难逢 1 +x:1 +休闲 1 +x:1 +牲口棚 1 +x:1 +传票 1 +x:1 +治疗学 1 +x:1 +塔台 1 +x:1 +交替 1 +x:1 +浮泛 1 +x:1 +本源 1 +x:1 +墙根 1 +x:1 +痛风 1 +x:1 +彩裙 1 +x:1 +高红 1 +x:1 +本溪 1 +x:1 +高级 1 +x:1 +今音 1 +x:1 +磁偏角 1 +x:1 +界定量 1 +x:1 +翻看 1 +x:1 +横贡呢 1 +x:1 +弋取 1 +x:1 +浮沉 1 +x:1 +投稿 1 +x:1 +餐费 1 +x:1 +教育班 1 +x:1 +盗版 1 +x:1 +平铺直叙 1 +x:1 +砌 27 +x:27 +胖子 1 +x:1 +超生 1 +x:1 +插座 1 +x:1 +童眸 1 +x:1 +婺城区 1 +x:1 +望城 1 +x:1 +募 4 +x:4 +棋逢对手 1 +x:1 +上下半场 1 +x:1 +伤者 1 +x:1 +表字 1 +x:1 +童真 1 +x:1 +教子有方 1 +x:1 +专题 1 +x:1 +余钱 1 +x:1 +兼听则明 1 +x:1 +江河水 1 +x:1 +高维 1 +x:1 +腾 45 +x:45 +金东里 1 +x:1 +坝子 1 +x:1 +疆 20 +x:20 +黄萝卜 1 +x:1 +求同存异 1 +x:1 +八十中 1 +x:1 +光明 1 +x:1 +拍片人 1 +x:1 +四等 1 +x:1 +塔卡 1 +x:1 +比拟 1 +x:1 +增加 1 +x:1 +病身 1 +x:1 +本港 1 +x:1 +移山填海 1 +x:1 +纳闷 1 +x:1 +传种 1 +x:1 +沈泉庄村 1 +x:1 +左海 1 +x:1 +山形 1 +x:1 +武者 1 +x:1 +打游击 1 +x:1 +螺栓 1 +x:1 +价工 1 +x:1 +嗡嗡嘤嘤 1 +x:1 +苏剧 1 +x:1 +价差 1 +x:1 +吐露真情 1 +x:1 +身历目睹 1 +x:1 +交映 1 +x:1 +入海处 1 +x:1 +救 182 +x:182 +佣人 1 +x:1 +休息 1 +x:1 +作息 1 +x:1 +褒扬 1 +x:1 +胸 46 +x:46 +弹弓 1 +x:1 +伯尔萨 1 +x:1 +临西 1 +x:1 +衣 67 +x:67 +凶猛 1 +x:1 +武联 1 +x:1 +替补席 1 +x:1 +仕进 1 +x:1 +整容 1 +x:1 +同里 1 +x:1 +学有所长 1 +x:1 +光景 1 +x:1 +武职 1 +x:1 +交易 1 +x:1 +劳务市场 1 +x:1 +乌纱帽 1 +x:1 +众口交赞 1 +x:1 +患难夫妻 1 +x:1 +热汤面 1 +x:1 +早衰 1 +x:1 +漫笔 1 +x:1 +观览 1 +x:1 +许身 1 +x:1 +勋劳 1 +x:1 +预言家 1 +x:1 +雕红漆 1 +x:1 +福庇子孙 1 +x:1 +衢县 1 +x:1 +灵寿县 1 +x:1 +故事稿 1 +x:1 +中纬度 1 +x:1 +小平车 1 +x:1 +时时处处 1 +x:1 +禁闭室 1 +x:1 +默认 1 +x:1 +赠与税 1 +x:1 +利钱 1 +x:1 +默许 1 +x:1 +如履薄冰 1 +x:1 +危险率 1 +x:1 +酿制 1 +x:1 +李子 1 +x:1 +十三大 1 +x:1 +出岔子 1 +x:1 +尿检 1 +x:1 +憎恨 1 +x:1 +理科 1 +x:1 +少许 1 +x:1 +胡匪 1 +x:1 +湘春路 1 +x:1 +黄金葛 1 +x:1 +渔户主 1 +x:1 +港府 1 +x:1 +尺幅千里 1 +x:1 +大全册 1 +x:1 +桑园 1 +x:1 +憎恶 1 +x:1 +苏欧司 1 +x:1 +言必有中 1 +x:1 +教鞭 1 +x:1 +西北缘 1 +x:1 +电脑式 1 +x:1 +析 15 +x:15 +光柱 1 +x:1 +慨 7 +x:7 +脑力 1 +x:1 +延河 1 +x:1 +错失良机 1 +x:1 +默读 1 +x:1 +斗牛士 1 +x:1 +干扰者 1 +x:1 +同道 1 +x:1 +轮转工 1 +x:1 +劳苦功高 1 +x:1 +变则通 1 +x:1 +低年级 1 +x:1 +默诵 1 +x:1 +封 398 +x:398 +千古佳话 1 +x:1 +果园乡 1 +x:1 +藤本植物 1 +x:1 +犊 3 +x:3 +浮浅 1 +x:1 +投篮 1 +x:1 +岬角 1 +x:1 +苏区 1 +x:1 +通脱木 1 +x:1 +战利品 1 +x:1 +目极千古 1 +x:1 +偏安 1 +x:1 +兀鹫 1 +x:1 +鸭 42 +x:42 +七纵八横 1 +x:1 +苏北 1 +x:1 +孙女 1 +x:1 +痛饮 1 +x:1 +刍议 1 +x:1 +古镇镇 1 +x:1 +光束 1 +x:1 +尾毛 1 +x:1 +尿样 1 +x:1 +临街 1 +x:1 +血枯病 1 +x:1 +港币 1 +x:1 +临行 1 +x:1 +虎虎生风 1 +x:1 +拍卖行 1 +x:1 +航校 1 +x:1 +丢面子 1 +x:1 +编采播 1 +x:1 +翻盖 1 +x:1 +展览证 1 +x:1 +翻盘 1 +x:1 +山东队 1 +x:1 +市政协 1 +x:1 +枣糕 1 +x:1 +拉丁区 1 +x:1 +苏南 1 +x:1 +茅家村 1 +x:1 +航标 1 +x:1 +东南郊 1 +x:1 +贵宾团 1 +x:1 +脑血管 1 +x:1 +馅 11 +x:11 +马扎 1 +x:1 +定义域 1 +x:1 +腰酸腿痛 1 +x:1 +胜任者 1 +x:1 +表头 1 +x:1 +千人一面 1 +x:1 +宜春市 1 +x:1 +目录名 1 +x:1 +钢铁长城 1 +x:1 +接待部 1 +x:1 +直贡帖寺 1 +x:1 +总部 1 +x:1 +常规赛 1 +x:1 +镀锡铁 1 +x:1 +东南部 1 +x:1 +波及 1 +x:1 +航母 1 +x:1 +斗牛宫 1 +x:1 +县歌 1 +x:1 +润资 1 +x:1 +预订款 1 +x:1 +专有物 1 +x:1 +高粱 1 +x:1 +电脑展 1 +x:1 +旧都 1 +x:1 +米字旗 1 +x:1 +整夜 1 +x:1 +马戏 1 +x:1 +丝绸组 1 +x:1 +柳筐 1 +x:1 +砂布厂 1 +x:1 +武鸣县 1 +x:1 +痛骂 1 +x:1 +本法 1 +x:1 +童画 1 +x:1 +代储员 1 +x:1 +翻番 1 +x:1 +童男 1 +x:1 +领导人员 1 +x:1 +马战 1 +x:1 +风啸子 1 +x:1 +厂桥 1 +x:1 +胸中有数 1 +x:1 +兽医局 1 +x:1 +病象 1 +x:1 +强龙型 1 +x:1 +不落征帆 1 +x:1 +滞期费 1 +x:1 +整天 1 +x:1 +呼吸系统 1 +x:1 +爝火 1 +x:1 +阴暗面 1 +x:1 +打歌舞 1 +x:1 +采蒂涅 1 +x:1 +腹稿 1 +x:1 +助跳道 1 +x:1 +功成名就 1 +x:1 +植物 1 +x:1 +通透式 1 +x:1 +宫外孕 1 +x:1 +生产过剩 1 +x:1 +上甬村 1 +x:1 +桥山 1 +x:1 +胖妞 1 +x:1 +营业楼 1 +x:1 +沙质 1 +x:1 +惭愧 1 +x:1 +点钞机 1 +x:1 +知觉 1 +x:1 +爆发性 1 +x:1 +小时/元 1 +x:1 +疾驰 1 +x:1 +坡道 1 +x:1 +鼓词 1 +x:1 +主裁判 1 +x:1 +再造术 1 +x:1 +奴隶制度 1 +x:1 +插屏 1 +x:1 +家无担石 1 +x:1 +土豚 1 +x:1 +希拉里 1 +x:1 +厂棍 1 +x:1 +武艺 1 +x:1 +秦国 1 +x:1 +失曹河 1 +x:1 +嚷嚷 1 +x:1 +打哈哈 1 +x:1 +土豆 1 +x:1 +饭食 1 +x:1 +航次 1 +x:1 +十人制 1 +x:1 +一损俱损 1 +x:1 +终身伴侣 1 +x:1 +坝头 1 +x:1 +论文赛 1 +x:1 +傣族 1 +x:1 +土豹 1 +x:1 +成法 1 +x:1 +表姐 1 +x:1 +浮渣 1 +x:1 +浮游 1 +x:1 +多元化 1 +x:1 +卖粥嫂 1 +x:1 +郴 2 +x:2 +扒窃 1 +x:1 +当断不断 1 +x:1 +吻合 1 +x:1 +奋飞 1 +x:1 +秦地 1 +x:1 +从天而降 1 +x:1 +斩六将 1 +x:1 +光斑 1 +x:1 +成活 1 +x:1 +三四月 1 +x:1 +棉纺锭 1 +x:1 +综合司 1 +x:1 +胡兰 1 +x:1 +主场地 1 +x:1 +投票 1 +x:1 +轻言细语 1 +x:1 +手表式 1 +x:1 +六里地屯 1 +x:1 +敲响 1 +x:1 +偶一为之 1 +x:1 +坛 8 +x:8 +偏失 1 +x:1 +芡粉 1 +x:1 +余恨 1 +x:1 +刨子 1 +x:1 +瀛州镇 1 +x:1 +毛纺锭 1 +x:1 +少见 1 +x:1 +沧海桑田 1 +x:1 +接待量 1 +x:1 +苏军 1 +x:1 +赃款 1 +x:1 +脆骨 1 +x:1 +余音 1 +x:1 +查号台 1 +x:1 +余韵 1 +x:1 +尾水平台 1 +x:1 +吉德万 1 +x:1 +大将军 1 +x:1 +佯装 1 +x:1 +南宁市 1 +x:1 +爱鸟 1 +x:1 +偏好 1 +x:1 +港岛 1 +x:1 +活生生 1 +x:1 +交方 1 +x:1 +童琴 1 +x:1 +宽大为怀 1 +x:1 +铝 18 +x:18 +螺母 1 +x:1 +纤维植物 1 +x:1 +先睹为快 1 +x:1 +姣妍 1 +x:1 +寄食 1 +x:1 +口头文学 1 +x:1 +土路 1 +x:1 +多义性 1 +x:1 +驱散 1 +x:1 +亚平宁 1 +x:1 +键板 1 +x:1 +芭蕾舞团 1 +x:1 +大失所望 1 +x:1 +坝墩 1 +x:1 +奇葩 1 +x:1 +汉阙 1 +x:1 +鬃 2 +x:2 +饭馆 1 +x:1 +慌乱 1 +x:1 +水灵灵 1 +x:1 +男子组 1 +x:1 +撒 71 +x:71 +顺义县 1 +x:1 +军委会 1 +x:1 +孙子 1 +x:1 +入出库 1 +x:1 +所以然 1 +x:1 +直贯而下 1 +x:1 +破格 1 +x:1 +龙港镇 1 +x:1 +汉阳 1 +x:1 +背鳍 1 +x:1 +接送 1 +x:1 +汉阴 1 +x:1 +容留 1 +x:1 +尖叫声 1 +x:1 +逵 9 +x:9 +塞拉利昂 1 +x:1 +接通 1 +x:1 +土货 1 +x:1 +歪理 1 +x:1 +太阳鸟 1 +x:1 +投票人 1 +x:1 +疑惑 1 +x:1 +苏公 1 +x:1 +铁索桥 1 +x:1 +稻区 1 +x:1 +马掌 1 +x:1 +横断山 1 +x:1 +含意 1 +x:1 +余震 1 +x:1 +剂型 1 +x:1 +光棍村 1 +x:1 +消除 1 +x:1 +交攻 1 +x:1 +破案 1 +x:1 +劳务 1 +x:1 +苏共 1 +x:1 +任人唯钱 1 +x:1 +活命之恩 1 +x:1 +来信版 1 +x:1 +温棚 1 +x:1 +床铺 1 +x:1 +费县 1 +x:1 +汉陵 1 +x:1 +机动权 1 +x:1 +价廉 1 +x:1 +加温器 1 +x:1 +盘腿 1 +x:1 +件 1894 +x:1894 +德阳 1 +x:1 +机电部 1 +x:1 +县长 1 +x:1 +居于 1 +x:1 +爱慕 1 +x:1 +影视业 1 +x:1 +眯细 1 +x:1 +乐团 1 +x:1 +老君庙 1 +x:1 +螺钿 1 +x:1 +被套 1 +x:1 +生境 1 +x:1 +乐园 1 +x:1 +黑色素 1 +x:1 +防护 1 +x:1 +药柜 1 +x:1 +高级小学 1 +x:1 +螺钉 1 +x:1 +五敛子 1 +x:1 +事无大小 1 +x:1 +绝 109 +x:109 +椰胡 1 +x:1 +水害 1 +x:1 +赣江 1 +x:1 +下马村 1 +x:1 +芥蓝菜 1 +x:1 +立方米 1 +x:1 +眼圈 1 +x:1 +将帅论 1 +x:1 +合作声 1 +x:1 +牧户 1 +x:1 +淡漠 1 +x:1 +玉版纸 1 +x:1 +玛湖 1 +x:1 +剧终 1 +x:1 +雏 2 +x:2 +干扰素 1 +x:1 +水富 1 +x:1 +恩施市 1 +x:1 +乐而忘返 1 +x:1 +一场空 1 +x:1 +杂感 1 +x:1 +爱意 1 +x:1 +盘绕 1 +x:1 +丰富多采 1 +x:1 +暴露无遗 1 +x:1 +驱驾 1 +x:1 +冷冷的 1 +x:1 +水寨 1 +x:1 +被头 1 +x:1 +强子 1 +x:1 +把关者 1 +x:1 +网络型 1 +x:1 +长平乡 1 +x:1 +巫头村 1 +x:1 +杀敌 1 +x:1 +塞北 1 +x:1 +马鳖 1 +x:1 +武举制 1 +x:1 +狗头军师 1 +x:1 +强家 1 +x:1 +割离 1 +x:1 +无着落 1 +x:1 +居中 1 +x:1 +树苗种 1 +x:1 +积食不化 1 +x:1 +上访者 1 +x:1 +在下 1 +x:1 +郎酒厂 1 +x:1 +要不然 1 +x:1 +循循善诱 1 +x:1 +童话 1 +x:1 +杏林 1 +x:1 +螺丝扣 1 +x:1 +病状 1 +x:1 +真理道 1 +x:1 +土牛 1 +x:1 +代购 1 +x:1 +选民 1 +x:1 +使用户 1 +x:1 +字库量 1 +x:1 +震耳欲聋 1 +x:1 +小腿肚子 1 +x:1 +临界 1 +x:1 +尼雅河 1 +x:1 +术业 1 +x:1 +怦怦 1 +x:1 +医药业 1 +x:1 +枣阳市 1 +x:1 +爱憎 1 +x:1 +翻译 1 +x:1 +作价员 1 +x:1 +不自禁 1 +x:1 +土特 1 +x:1 +阿拉伯式 1 +x:1 +土物 1 +x:1 +沙獾 1 +x:1 +扑朔迷离 1 +x:1 +彩球 1 +x:1 +收回 1 +x:1 +戈兰区 1 +x:1 +渝北 1 +x:1 +滑石片 1 +x:1 +内衣厂 1 +x:1 +市地级 1 +x:1 +什么样 1 +x:1 +斜塔 1 +x:1 +碑 116 +x:116 +合辙 1 +x:1 +带动力 1 +x:1 +蒙 111 +x:111 +收场 1 +x:1 +有信仰者 1 +x:1 +易学 1 +x:1 +后院起火 1 +x:1 +病猪 1 +x:1 +强威 1 +x:1 +慢吞吞 1 +x:1 +包裹 1 +x:1 +检察室 1 +x:1 +新旧交替 1 +x:1 +日子 1 +x:1 +渝南 1 +x:1 +生姜 1 +x:1 +淡紫 1 +x:1 +犯有 1 +x:1 +父执 1 +x:1 +九十月 1 +x:1 +立克次体 1 +x:1 +秦树乡 1 +x:1 +爱怜 1 +x:1 +调压井 1 +x:1 +容许 1 +x:1 +开采权 1 +x:1 +随遇而安 1 +x:1 +有来有往 1 +x:1 +风驰电掣 1 +x:1 +浅蓝 1 +x:1 +燃气灶 1 +x:1 +稀释 1 +x:1 +复合门 1 +x:1 +长江村 1 +x:1 +痛斥 1 +x:1 +街政 1 +x:1 +同江 1 +x:1 +字典 1 +x:1 +容人之短 1 +x:1 +炮击 1 +x:1 +集线器 1 +x:1 +爱惜 1 +x:1 +衣食行 1 +x:1 +爱情 1 +x:1 +操劳 1 +x:1 +凤头 1 +x:1 +对外部 1 +x:1 +同治 1 +x:1 +锣 7 +x:7 +梨花大鼓 1 +x:1 +乐坛 1 +x:1 +日寇 1 +x:1 +中隔墩 1 +x:1 +教武 1 +x:1 +西二乡 1 +x:1 +拥挤 1 +x:1 +坚挺度 1 +x:1 +操办 1 +x:1 +脸谱 1 +x:1 +居住 1 +x:1 +三棱镜 1 +x:1 +代谢 1 +x:1 +合作处 1 +x:1 +彩电 1 +x:1 +坏 214 +x:214 +马刀舞 1 +x:1 +眯缝 1 +x:1 +大礼服 1 +x:1 +胶纸 1 +x:1 +宪法 1 +x:1 +岔路河镇 1 +x:1 +选派 1 +x:1 +朝不保夕 1 +x:1 +乐土 1 +x:1 +沙特 1 +x:1 +筒 4 +x:4 +四合房 1 +x:1 +破除 1 +x:1 +兴冲冲 1 +x:1 +印经院 1 +x:1 +天津站 1 +x:1 +舀 6 +x:6 +强夯 1 +x:1 +跃脚板 1 +x:1 +牵引力 1 +x:1 +能者为师 1 +x:1 +土炕 1 +x:1 +强大 1 +x:1 +收听 1 +x:1 +猫科 1 +x:1 +被子 1 +x:1 +光电钟 1 +x:1 +散文体 1 +x:1 +摆摊子 1 +x:1 +贫困帽子 1 +x:1 +华盖木 1 +x:1 +街景 1 +x:1 +容装 1 +x:1 +迈阿密 1 +x:1 +土炮 1 +x:1 +座落 1 +x:1 +化纤厂 1 +x:1 +伏汛 1 +x:1 +烈士园 1 +x:1 +过往 1 +x:1 +尸位素餐 1 +x:1 +隐恶扬善 1 +x:1 +宋 767 +x:767 +涂片 1 +x:1 +纺工 1 +x:1 +赠物 1 +x:1 +礼品盒 1 +x:1 +率领 1 +x:1 +袍谷 1 +x:1 +寒窗 1 +x:1 +强奸 1 +x:1 +波动性 1 +x:1 +布朗族 1 +x:1 +野桑 1 +x:1 +犷悍 1 +x:1 +法学 1 +x:1 +概不负责 1 +x:1 +船形帽 1 +x:1 +寥寥可数 1 +x:1 +高胡 1 +x:1 +法子 1 +x:1 +稔子 1 +x:1 +破门 1 +x:1 +高能 1 +x:1 +马鸾 1 +x:1 +病灶 1 +x:1 +怀恨 1 +x:1 +剖腹产 1 +x:1 +趟趟 1 +x:1 +教案 1 +x:1 +杀杀 1 +x:1 +皮奥伊 1 +x:1 +标 60 +x:60 +乳浊液 1 +x:1 +高考 1 +x:1 +法家 1 +x:1 +引咎自责 1 +x:1 +高者 1 +x:1 +接洽 1 +x:1 +教育费 1 +x:1 +休止 1 +x:1 +初级中学 1 +x:1 +干才 1 +x:1 +零备件 1 +x:1 +喃字 1 +x:1 +猫神 1 +x:1 +生威 1 +x:1 +法宝 1 +x:1 +再三 1 +x:1 +沪剧 1 +x:1 +干扰 1 +x:1 +索菲亚 1 +x:1 +法定 1 +x:1 +不良率 1 +x:1 +水头 1 +x:1 +珠江 1 +x:1 +魔法师 1 +x:1 +高耸 1 +x:1 +办 2183 +x:2183 +增值税率 1 +x:1 +伏法 1 +x:1 +现实感 1 +x:1 +中巴车 1 +x:1 +呢制服 1 +x:1 +宝应县 1 +x:1 +高职 1 +x:1 +知情人 1 +x:1 +灯塔市 1 +x:1 +蚰蜒草 1 +x:1 +成都 1 +x:1 +此奖 1 +x:1 +大拇指 1 +x:1 +百子炮 1 +x:1 +银亮 1 +x:1 +奇秀 1 +x:1 +使用性 1 +x:1 +干戈 1 +x:1 +节能灯 1 +x:1 +黄衫 1 +x:1 +洗劫一空 1 +x:1 +五世同堂 1 +x:1 +鸟啼 1 +x:1 +淘汰式 1 +x:1 +鄯善国 1 +x:1 +苇浆 1 +x:1 +歌舞厅 1 +x:1 +土灶 1 +x:1 +万斤户 1 +x:1 +被害 1 +x:1 +日增 1 +x:1 +杀机 1 +x:1 +白眼傲物 1 +x:1 +鼠害 1 +x:1 +塞入 1 +x:1 +汉武 1 +x:1 +购假者 1 +x:1 +溉 1 +x:1 +歌舞剧 1 +x:1 +深不可测 1 +x:1 +燕子 1 +x:1 +或 4326 +x:4326 +苏州市 1 +x:1 +企鹅 1 +x:1 +余毒 1 +x:1 +东郊镇 1 +x:1 +源流有自 1 +x:1 +餐费票 1 +x:1 +刑侦队 1 +x:1 +止蚀 1 +x:1 +学分制 1 +x:1 +伏流 1 +x:1 +功夫 1 +x:1 +牡丹江市 1 +x:1 +水墨 1 +x:1 +生客 1 +x:1 +鸾 1 +x:1 +共建点 1 +x:1 +中长传 1 +x:1 +土燕 1 +x:1 +保皇派 1 +x:1 +有线电连 1 +x:1 +满载而归 1 +x:1 +淡水 1 +x:1 +本金 1 +x:1 +日头 1 +x:1 +稻花香 1 +x:1 +干掉 1 +x:1 +形式学 1 +x:1 +毛茶 1 +x:1 +不甘示弱 1 +x:1 +爱戴 1 +x:1 +水壶 1 +x:1 +洧川 1 +x:1 +水声 1 +x:1 +日夜 1 +x:1 +邪路 1 +x:1 +备用品 1 +x:1 +设计系 1 +x:1 +雏燕 1 +x:1 +盖房 1 +x:1 +观瞻 1 +x:1 +配图量 1 +x:1 +花园口镇 1 +x:1 +储存器 1 +x:1 +铸补 1 +x:1 +册 298 +x:298 +恩施州 1 +x:1 +缓 106 +x:106 +控股 1 +x:1 +告密 1 +x:1 +墓茔 1 +x:1 +徐汇区 1 +x:1 +不敢当 1 +x:1 +团结党 1 +x:1 +抱头鼠窜 1 +x:1 +童装 1 +x:1 +朱顶 1 +x:1 +淡泊 1 +x:1 +活性炭 1 +x:1 +剩下 1 +x:1 +奋斗 1 +x:1 +趴 15 +x:15 +同源 1 +x:1 +土焦 1 +x:1 +伴随着 1 +x:1 +乡党委 1 +x:1 +剧作者 1 +x:1 +庾 3 +x:3 +杂抄 1 +x:1 +强壮 1 +x:1 +杂技 1 +x:1 +水塘 1 +x:1 +生存 1 +x:1 +生字 1 +x:1 +水塔 1 +x:1 +爱抚 1 +x:1 +遍 238 +x:238 +生子 1 +x:1 +寰球 1 +x:1 +大部头儿 1 +x:1 +眼花缭乱 1 +x:1 +流动岗 1 +x:1 +地厅级 1 +x:1 +鼓风机 1 +x:1 +高腔 1 +x:1 +时代队 1 +x:1 +蚂蟥钉 1 +x:1 +光饼 1 +x:1 +史诗性 1 +x:1 +徇私舞弊 1 +x:1 +重蹈覆辙 1 +x:1 +厂门 1 +x:1 +蓝鲸 1 +x:1 +左顾右盼 1 +x:1 +绉纱 1 +x:1 +背悔 1 +x:1 +门阵列 1 +x:1 +碰巧 1 +x:1 +余款 1 +x:1 +鳄鱼衫 1 +x:1 +作业机 1 +x:1 +择菜 1 +x:1 +翻身 1 +x:1 +胆大心细 1 +x:1 +带动型 1 +x:1 +先进 1 +x:1 +童车 1 +x:1 +父本 1 +x:1 +驱鸟 1 +x:1 +痛惜 1 +x:1 +收到 1 +x:1 +草履虫 1 +x:1 +枪帆长 1 +x:1 +严肃 1 +x:1 +强强 1 +x:1 +转借 1 +x:1 +网络化 1 +x:1 +背板 1 +x:1 +纳流 1 +x:1 +时与 1 +x:1 +操场 1 +x:1 +病瘫 1 +x:1 +围歼 1 +x:1 +岁初 1 +x:1 +抗倭 1 +x:1 +笪 14 +x:14 +王族 1 +x:1 +奇缺 1 +x:1 +托漂 1 +x:1 +粉乎乎 1 +x:1 +停机场 1 +x:1 +袢子 1 +x:1 +呵佛骂祖 1 +x:1 +凤岗 1 +x:1 +奋战 1 +x:1 +稀缺性 1 +x:1 +妄自菲薄 1 +x:1 +太阳日 1 +x:1 +容身 1 +x:1 +揭阳 1 +x:1 +痛悔 1 +x:1 +假定性 1 +x:1 +植被 1 +x:1 +隆隆声 1 +x:1 +太阳时 1 +x:1 +翻车 1 +x:1 +教育课 1 +x:1 +伤破 1 +x:1 +体温表 1 +x:1 +禁制品 1 +x:1 +翻转 1 +x:1 +顺风球 1 +x:1 +停机坪 1 +x:1 +治沙办 1 +x:1 +易帜 1 +x:1 +细细 1 +x:1 +网络卡 1 +x:1 +展示会 1 +x:1 +焰口 1 +x:1 +敞开儿 1 +x:1 +捏一把汗 1 +x:1 +沙石 1 +x:1 +股本金 1 +x:1 +观点 1 +x:1 +易帅 1 +x:1 +公民权 1 +x:1 +还愿 1 +x:1 +误工费 1 +x:1 +磐 1 +x:1 +尿酸 1 +x:1 +甜食 1 +x:1 +功底 1 +x:1 +鲜品 1 +x:1 +资源法 1 +x:1 +合作局 1 +x:1 +凤尾 1 +x:1 +选案 1 +x:1 +怪罪 1 +x:1 +本队 1 +x:1 +片儿警 1 +x:1 +良民 1 +x:1 +唯恐 1 +x:1 +藏胞 1 +x:1 +天 3634 +x:3634 +生就 1 +x:1 +鄱阳湖畔 1 +x:1 +县里 1 +x:1 +经验之谈 1 +x:1 +沙眼 1 +x:1 +痛恨 1 +x:1 +四药 1 +x:1 +胶管 1 +x:1 +杂文 1 +x:1 +少爷 1 +x:1 +超越 1 +x:1 +颇感 1 +x:1 +默片 1 +x:1 +鸟协 1 +x:1 +强忍 1 +x:1 +本院 1 +x:1 +早熟 1 +x:1 +挫伤 1 +x:1 +爱方 1 +x:1 +葫 3 +x:3 +老马识途 1 +x:1 +搬兵 1 +x:1 +翻过 1 +x:1 +太子湾 1 +x:1 +创汇 1 +x:1 +规土局 1 +x:1 +乐台 1 +x:1 +献血量 1 +x:1 +法尺 1 +x:1 +背景 1 +x:1 +水底 1 +x:1 +派头 1 +x:1 +水库 1 +x:1 +沙皇 1 +x:1 +同样 1 +x:1 +投药 1 +x:1 +黄金时间 1 +x:1 +五莲县 1 +x:1 +乐句 1 +x:1 +茶室 1 +x:1 +日影 1 +x:1 +盘算 1 +x:1 +乞讨 1 +x:1 +下不来 1 +x:1 +黄土坡 1 +x:1 +干旱 1 +x:1 +同步性 1 +x:1 +甜饼 1 +x:1 +县道 1 +x:1 +肖形虎 1 +x:1 +如梦方醒 1 +x:1 +病眼 1 +x:1 +换算 1 +x:1 +去岁 1 +x:1 +治乱减负 1 +x:1 +内燃机车 1 +x:1 +省地级 1 +x:1 +撷 1 +x:1 +损人利己 1 +x:1 +有线电视 1 +x:1 +短剧 1 +x:1 +沙盆 1 +x:1 +沙盘 1 +x:1 +梁上君子 1 +x:1 +弥天大谎 1 +x:1 +义合堡 1 +x:1 +及时性 1 +x:1 +区外 1 +x:1 +武科 1 +x:1 +彩云飞 1 +x:1 +塞国 1 +x:1 +优胜劣汰 1 +x:1 +同桌 1 +x:1 +土石 1 +x:1 +同案 1 +x:1 +化纤品 1 +x:1 +兖石 1 +x:1 +急于求成 1 +x:1 +生工 1 +x:1 +兖矿 1 +x:1 +证交所 1 +x:1 +代表 1 +x:1 +水帘 1 +x:1 +息风 1 +x:1 +汉民 1 +x:1 +饶舌 1 +x:1 +强度 1 +x:1 +续篇 1 +x:1 +济阳集 1 +x:1 +得悟 1 +x:1 +水师 1 +x:1 +报头 1 +x:1 +井田制 1 +x:1 +监督表 1 +x:1 +鹿儿岛 1 +x:1 +白米饭 1 +x:1 +赞美歌 1 +x:1 +刺状物 1 +x:1 +观照 1 +x:1 +地产品 1 +x:1 +功德 1 +x:1 +分辨率 1 +x:1 +增至 1 +x:1 +尿道 1 +x:1 +热转印 1 +x:1 +胜仗 1 +x:1 +航道 1 +x:1 +约见 1 +x:1 +无声片 1 +x:1 +县郊 1 +x:1 +脆性 1 +x:1 +水带 1 +x:1 +胃口 1 +x:1 +日志 1 +x:1 +萨尔诺 1 +x:1 +使用权 1 +x:1 +大石碑 1 +x:1 +报复 1 +x:1 +鼓点 1 +x:1 +汉江 1 +x:1 +枝繁花多 1 +x:1 +鸡公车 1 +x:1 +奇绝 1 +x:1 +济阳县 1 +x:1 +痛感 1 +x:1 +甜香 1 +x:1 +昭觉寺 1 +x:1 +宇宙空间 1 +x:1 +弹词 1 +x:1 +农展会 1 +x:1 +注入式 1 +x:1 +政者 1 +x:1 +心中无数 1 +x:1 +玩火自焚 1 +x:1 +使用期 1 +x:1 +策略 1 +x:1 +自在性 1 +x:1 +可相容性 1 +x:1 +姨 5 +x:5 +水平 1 +x:1 +填平 1 +x:1 +收发 1 +x:1 +收取 1 +x:1 +收受 1 +x:1 +干支 1 +x:1 +抗击 1 +x:1 +伤天害命 1 +x:1 +潼关 1 +x:1 +金瓶梅 1 +x:1 +病理 1 +x:1 +三十五分 1 +x:1 +电力局 1 +x:1 +甚低频 1 +x:1 +冀中南 1 +x:1 +代课 1 +x:1 +怪模怪样 1 +x:1 +出生率 1 +x:1 +讲和 1 +x:1 +油压机 1 +x:1 +砖坯 1 +x:1 +教法 1 +x:1 +浮雕 1 +x:1 +本钢 1 +x:1 +哲学家 1 +x:1 +代词 1 +x:1 +势利小人 1 +x:1 +运兵车 1 +x:1 +麦海 1 +x:1 +铰链 1 +x:1 +亘古 1 +x:1 +胎盘 1 +x:1 +法式 1 +x:1 +本钱 1 +x:1 +四自 1 +x:1 +马驹 1 +x:1 +制呢厂 1 +x:1 +地震台站 1 +x:1 +同步 1 +x:1 +夷 5 +x:5 +张马乡 1 +x:1 +谈虎色变 1 +x:1 +杀掉 1 +x:1 +透明度 1 +x:1 +频传 1 +x:1 +歪路 1 +x:1 +辛店镇 1 +x:1 +二乙胺基 1 +x:1 +利辛县 1 +x:1 +满洲里市 1 +x:1 +容貌 1 +x:1 +水巷 1 +x:1 +教育观 1 +x:1 +振荡器 1 +x:1 +柳荫 1 +x:1 +童贞 1 +x:1 +危辞耸听 1 +x:1 +汾酒厂 1 +x:1 +水工 1 +x:1 +投考 1 +x:1 +痛打 1 +x:1 +超迈 1 +x:1 +还手 1 +x:1 +收储 1 +x:1 +临猗 1 +x:1 +超过 1 +x:1 +馋涎欲滴 1 +x:1 +培训期 1 +x:1 +垫背 1 +x:1 +背时 1 +x:1 +超远 1 +x:1 +轨迹 1 +x:1 +早班 1 +x:1 +良渚 1 +x:1 +五道林 1 +x:1 +南特港 1 +x:1 +候车 1 +x:1 +殉情 1 +x:1 +麦浪 1 +x:1 +王权 1 +x:1 +柳莺 1 +x:1 +租佃制 1 +x:1 +泪痕斑斑 1 +x:1 +渔歌 1 +x:1 +威舍镇 1 +x:1 +插翅难飞 1 +x:1 +找到 1 +x:1 +王村 1 +x:1 +虬曲 1 +x:1 +选拔赛 1 +x:1 +太谷 1 +x:1 +白虎星 1 +x:1 +幻想国 1 +x:1 +捋抚 1 +x:1 +成立会 1 +x:1 +民主党派 1 +x:1 +雷龙 1 +x:1 +装卸工 1 +x:1 +武穴 1 +x:1 +档级 1 +x:1 +民乐乡 1 +x:1 +童趣 1 +x:1 +总校 1 +x:1 +碰壁 1 +x:1 +倾盆大雨 1 +x:1 +教民 1 +x:1 +储存区 1 +x:1 +湛 4 +x:4 +褥套 1 +x:1 +检察局 1 +x:1 +修改稿 1 +x:1 +余温 1 +x:1 +鸟兽 1 +x:1 +比额 1 +x:1 +嫩芽头 1 +x:1 +多变性 1 +x:1 +马骡 1 +x:1 +垫肩 1 +x:1 +良梨镇 1 +x:1 +生平 1 +x:1 +审看 1 +x:1 +鼓王 1 +x:1 +背斗 1 +x:1 +同比 1 +x:1 +太阳村 1 +x:1 +背斜 1 +x:1 +王朝 1 +x:1 +雷鸣 1 +x:1 +叠层石 1 +x:1 +主干 1 +x:1 +苏常柴 1 +x:1 +屠宰点 1 +x:1 +飞机票 1 +x:1 +主跑道 1 +x:1 +逼报 1 +x:1 +逼抢 1 +x:1 +锴 2 +x:2 +传艺 1 +x:1 +彩珠 1 +x:1 +纽约港 1 +x:1 +高薪 1 +x:1 +乡绅 1 +x:1 +兵力 1 +x:1 +碰头 1 +x:1 +羽翼渐丰 1 +x:1 +强将 1 +x:1 +法帖 1 +x:1 +大大方方 1 +x:1 +搬动 1 +x:1 +四胡 1 +x:1 +磁合金 1 +x:1 +营业部 1 +x:1 +无机酸 1 +x:1 +枣红 1 +x:1 +雷鸟 1 +x:1 +法币 1 +x:1 +先驱者 1 +x:1 +节食 1 +x:1 +雁头 1 +x:1 +犯意 1 +x:1 +篷车 1 +x:1 +嫣然一笑 1 +x:1 +千古奇文 1 +x:1 +马鬃 1 +x:1 +卧舱 1 +x:1 +干果 1 +x:1 +村落 1 +x:1 +博览会 1 +x:1 +成长 1 +x:1 +童谣 1 +x:1 +一脉相传 1 +x:1 +万国宫 1 +x:1 +有线电话 1 +x:1 +别出心裁 1 +x:1 +干极 1 +x:1 +垫脚 1 +x:1 +子宫颈 1 +x:1 +收养 1 +x:1 +酸罐 1 +x:1 +自然课 1 +x:1 +靠 1482 +x:1482 +各个击破 1 +x:1 +强局 1 +x:1 +沙瓤 1 +x:1 +盘秤 1 +x:1 +收兑 1 +x:1 +干枯 1 +x:1 +种养加 1 +x:1 +约请 1 +x:1 +日工 1 +x:1 +杀手 1 +x:1 +照料 1 +x:1 +柳园村 1 +x:1 +歌舞团 1 +x:1 +法庭 1 +x:1 +国民新党 1 +x:1 +体温计 1 +x:1 +法规性 1 +x:1 +抗原 1 +x:1 +法度 1 +x:1 +噎嗝 1 +x:1 +床沿 1 +x:1 +克孜勒苏 1 +x:1 +柳芽 1 +x:1 +柳花 1 +x:1 +框 15 +x:15 +含山县 1 +x:1 +登革热病 1 +x:1 +动画人 1 +x:1 +准将城 1 +x:1 +制冷量 1 +x:1 +金小蜂 1 +x:1 +好意思 1 +x:1 +干杯 1 +x:1 +频仍 1 +x:1 +魏武帝 1 +x:1 +派对 1 +x:1 +佝偻病 1 +x:1 +放眼世界 1 +x:1 +需要者 1 +x:1 +渲染 1 +x:1 +厂里 1 +x:1 +病症 1 +x:1 +隶字 1 +x:1 +狭义 1 +x:1 +田田 1 +x:1 +白铁皮 1 +x:1 +杀戒 1 +x:1 +约计 1 +x:1 +戏曲界 1 +x:1 +天理不容 1 +x:1 +病痛 1 +x:1 +管帅 1 +x:1 +虬枝 1 +x:1 +水层 1 +x:1 +厉行 1 +x:1 +鲜味 1 +x:1 +红头文件 1 +x:1 +报奖 1 +x:1 +毫瓦 1 +x:1 +奉若神明 1 +x:1 +红得发紫 1 +x:1 +油画笔 1 +x:1 +巡视 1 +x:1 +杀戮 1 +x:1 +南沈灶镇 1 +x:1 +民事案 1 +x:1 +教派 1 +x:1 +硫酸盐 1 +x:1 +短发 1 +x:1 +满城县 1 +x:1 +拓片 1 +x:1 +土公路 1 +x:1 +网络式 1 +x:1 +法儿 1 +x:1 +四运 1 +x:1 +病程 1 +x:1 +箍 3 +x:3 +土窑 1 +x:1 +乌龙入珠 1 +x:1 +独立国 1 +x:1 +查询台 1 +x:1 +水压 1 +x:1 +强区 1 +x:1 +五讲四美 1 +x:1 +捣乱 1 +x:1 +告假 1 +x:1 +水厂 1 +x:1 +日前 1 +x:1 +销售点 1 +x:1 +民仓 1 +x:1 +寻根究底 1 +x:1 +袋装 1 +x:1 +雅乐 1 +x:1 +淡村 1 +x:1 +功利 1 +x:1 +方便之门 1 +x:1 +沙箱 1 +x:1 +十样锦 1 +x:1 +韧皮部 1 +x:1 +追踪 1 +x:1 +老拳挥舞 1 +x:1 +新筑镇 1 +x:1 +是个儿 1 +x:1 +强占 1 +x:1 +焰心 1 +x:1 +难进 1 +x:1 +半工半读 1 +x:1 +休憩 1 +x:1 +增调 1 +x:1 +巴林国 1 +x:1 +派员 1 +x:1 +和合学 1 +x:1 +生僻 1 +x:1 +日刊 1 +x:1 +便利店 1 +x:1 +淡月 1 +x:1 +四边 1 +x:1 +乐府 1 +x:1 +浮 41 +x:41 +彩粉 1 +x:1 +余悸 1 +x:1 +制糖业 1 +x:1 +秀城区 1 +x:1 +驱逐 1 +x:1 +尔等 1 +x:1 +自觉 1 +x:1 +事业部制 1 +x:1 +民事 1 +x:1 +攀禽 1 +x:1 +超脱 1 +x:1 +水口 1 +x:1 +苏格兰 1 +x:1 +乐平 1 +x:1 +乘积 1 +x:1 +功力 1 +x:1 +查询卡 1 +x:1 +湛江港 1 +x:1 +水化 1 +x:1 +华侨界 1 +x:1 +相映生辉 1 +x:1 +强县 1 +x:1 +量体裁衣 1 +x:1 +四轮车 1 +x:1 +出毛病 1 +x:1 +成骨 1 +x:1 +化作 1 +x:1 +我中有你 1 +x:1 +窄窄的 1 +x:1 +民乐 1 +x:1 +螺丝攻 1 +x:1 +水区 1 +x:1 +莫若 1 +x:1 +数八法 1 +x:1 +良性 1 +x:1 +卢克索市 1 +x:1 +哼唱 1 +x:1 +功劳 1 +x:1 +短号 1 +x:1 +据为己有 1 +x:1 +探赜索隐 1 +x:1 +十指连心 1 +x:1 +伊图里河 1 +x:1 +免费日 1 +x:1 +四轮 1 +x:1 +收废 1 +x:1 +民丰 1 +x:1 +同日 1 +x:1 +上告人 1 +x:1 +塞子 1 +x:1 +滚针轴承 1 +x:1 +民主 1 +x:1 +分忧 1 +x:1 +载畜量 1 +x:1 +鸦胆子 1 +x:1 +同时 1 +x:1 +纪念会 1 +x:1 +呓 1 +x:1 +阿万达罗 1 +x:1 +功勋 1 +x:1 +投身 1 +x:1 +畸 1 +x:1 +石门镇 1 +x:1 +余怒 1 +x:1 +九江镇 1 +x:1 +改造权 1 +x:1 +超标费 1 +x:1 +马钢 1 +x:1 +同族 1 +x:1 +刘邦 1 +x:1 +父母 1 +x:1 +水印 1 +x:1 +拥军田 1 +x:1 +川剧院 1 +x:1 +科索沃 1 +x:1 +干校 1 +x:1 +绝对值 1 +x:1 +乐师 1 +x:1 +狼 34 +x:34 +控诉 1 +x:1 +态 17 +x:17 +休想 1 +x:1 +红莲 1 +x:1 +小间式 1 +x:1 +虎虎生气 1 +x:1 +翻船 1 +x:1 +纳恐 1 +x:1 +凤冠 1 +x:1 +人身权 1 +x:1 +兄弟团 1 +x:1 +震慑力 1 +x:1 +沙窝 1 +x:1 +物欲横流 1 +x:1 +通气会 1 +x:1 +颅腔 1 +x:1 +强制 1 +x:1 +检察厅 1 +x:1 +增资 1 +x:1 +黑芝麻糊 1 +x:1 +赠礼 1 +x:1 +搞 1644 +x:1644 +水势 1 +x:1 +提格雷州 1 +x:1 +民俗 1 +x:1 +生冷 1 +x:1 +淘汰品 1 +x:1 +马镫 1 +x:1 +收式 1 +x:1 +高论 1 +x:1 +金吾村 1 +x:1 +牧歌 1 +x:1 +土管 1 +x:1 +鲫鱼 1 +x:1 +热炒 1 +x:1 +教授 1 +x:1 +莒县 1 +x:1 +仅 1825 +x:1825 +全世界 1 +x:1 +杂七杂八 1 +x:1 +风急浪高 1 +x:1 +东南极 1 +x:1 +化二 1 +x:1 +欺骗性 1 +x:1 +纹银 1 +x:1 +接替 1 +x:1 +火头上 1 +x:1 +赘 1 +x:1 +颅脑 1 +x:1 +凤凰 1 +x:1 +绥 6 +x:6 +马锣 1 +x:1 +合法权 1 +x:1 +鹿角 1 +x:1 +奇特 1 +x:1 +增质 1 +x:1 +收归 1 +x:1 +收录 1 +x:1 +宝中之宝 1 +x:1 +盘石 1 +x:1 +诗刊 1 +x:1 +日化 1 +x:1 +仁者见仁 1 +x:1 +引火烧身 1 +x:1 +理路 1 +x:1 +厂龄 1 +x:1 +议程 1 +x:1 +饵料 1 +x:1 +身披 1 +x:1 +皱皱巴巴 1 +x:1 +啭 1 +x:1 +强加 1 +x:1 +/ 397 +x:397 +强势 1 +x:1 +怪物 1 +x:1 +四蹄 1 +x:1 +水分 1 +x:1 +懈怠 1 +x:1 +东南村 1 +x:1 +触目皆是 1 +x:1 +鼠标器 1 +x:1 +土木工程 1 +x:1 +扎糊 1 +x:1 +两极管 1 +x:1 +北斗星 1 +x:1 +伤病 1 +x:1 +投运 1 +x:1 +题画诗 1 +x:1 +武生 1 +x:1 +理财 1 +x:1 +伤痛 1 +x:1 +强力 1 +x:1 +子民 1 +x:1 +南澳 1 +x:1 +伤痕 1 +x:1 +爽 17 +x:17 +修机班 1 +x:1 +善始善终 1 +x:1 +红缨枪 1 +x:1 +理赔 1 +x:1 +斯方 1 +x:1 +蹲马步 1 +x:1 +总机 1 +x:1 +伤疤 1 +x:1 +天目山 1 +x:1 +胶皮 1 +x:1 +区委 1 +x:1 +生光 1 +x:1 +接壤处 1 +x:1 +奎 47 +x:47 +结结实实 1 +x:1 +单项式 1 +x:1 +示范乡 1 +x:1 +艰涩 1 +x:1 +生养 1 +x:1 +阴德 1 +x:1 +民众 1 +x:1 +珍珠镇 1 +x:1 +日历 1 +x:1 +鬼话连篇 1 +x:1 +泼 26 +x:26 +想象力 1 +x:1 +所向无敌 1 +x:1 +讲学 1 +x:1 +一瞬间 1 +x:1 +抄表员 1 +x:1 +摩泽尔河 1 +x:1 +化为 1 +x:1 +军战史 1 +x:1 +能手 1 +x:1 +普者黑 1 +x:1 +本领 1 +x:1 +彩绸 1 +x:1 +守法性 1 +x:1 +水军 1 +x:1 +法医 1 +x:1 +州民 1 +x:1 +翻脸 1 +x:1 +风帽 1 +x:1 +卧车 1 +x:1 +接方 1 +x:1 +被单 1 +x:1 +免费权 1 +x:1 +同机 1 +x:1 +收尾 1 +x:1 +金东村 1 +x:1 +激越奋进 1 +x:1 +彩绘 1 +x:1 +唇舌 1 +x:1 +被卧 1 +x:1 +斯大林 1 +x:1 +选曲 1 +x:1 +同月 1 +x:1 +与时俱进 1 +x:1 +辛家庄 1 +x:1 +被卷 1 +x:1 +开创性 1 +x:1 +里丁屿市 1 +x:1 +生动 1 +x:1 +同期 1 +x:1 +彩练 1 +x:1 +四跨 1 +x:1 +非官方 1 +x:1 +值 137 +x:137 +急支糖浆 1 +x:1 +蕨类 1 +x:1 +敞开式 1 +x:1 +该车 1 +x:1 +定购粮 1 +x:1 +福华路 1 +x:1 +被包 1 +x:1 +猫熊 1 +x:1 +雅人 1 +x:1 +翻腾 1 +x:1 +偷渡船 1 +x:1 +日值 1 +x:1 +豆芽菜 1 +x:1 +推广员 1 +x:1 +温泉市 1 +x:1 +水准 1 +x:1 +马队 1 +x:1 +密云不雨 1 +x:1 +黄果树 1 +x:1 +爱欲 1 +x:1 +强光 1 +x:1 +卦 2 +x:2 +中转港 1 +x:1 +偷工减料 1 +x:1 +嫉恨 1 +x:1 +驱遣 1 +x:1 +告别 1 +x:1 +选优淘劣 1 +x:1 +投票点 1 +x:1 +鸟巢 1 +x:1 +搬弄 1 +x:1 +宽厚仁德 1 +x:1 +光速 1 +x:1 +白刃战 1 +x:1 +学校部长 1 +x:1 +土砖 1 +x:1 +塞外 1 +x:1 +一展歌喉 1 +x:1 +讲堂 1 +x:1 +生分 1 +x:1 +犯法 1 +x:1 +接收 1 +x:1 +伏特计 1 +x:1 +水儿 1 +x:1 +四起 1 +x:1 +诈骗案 1 +x:1 +新篇章 1 +x:1 +被叫 1 +x:1 +罗坊镇 1 +x:1 +赫罗诺夫 1 +x:1 +花样刀 1 +x:1 +强农 1 +x:1 +新华村 1 +x:1 +强军 1 +x:1 +豆腐房 1 +x:1 +驱邪 1 +x:1 +阿勒菲 1 +x:1 +老油子 1 +x:1 +水晶节 1 +x:1 +良才 1 +x:1 +鸭廊 1 +x:1 +填充 1 +x:1 +摄录像 1 +x:1 +武城县 1 +x:1 +法号 1 +x:1 +定于一尊 1 +x:1 +毫秒 1 +x:1 +生前 1 +x:1 +白雪公主 1 +x:1 +水光 1 +x:1 +秧歌剧 1 +x:1 +易太乡 1 +x:1 +风流云散 1 +x:1 +小史店镇 1 +x:1 +管径 1 +x:1 +核裁军 1 +x:1 +逃亡 1 +x:1 +水兵 1 +x:1 +成飞 1 +x:1 +油气罐 1 +x:1 +传输 1 +x:1 +收音 1 +x:1 +填具 1 +x:1 +匣体 1 +x:1 +合作制 1 +x:1 +打电话 1 +x:1 +语音室 1 +x:1 +成风 1 +x:1 +义乌 1 +x:1 +访谈 1 +x:1 +鸟岛 1 +x:1 +马尔代夫 1 +x:1 +高要 1 +x:1 +兴味 1 +x:1 +沙碛 1 +x:1 +生厌 1 +x:1 +跪倒 1 +x:1 +接待日 1 +x:1 +南定镇 1 +x:1 +日共 1 +x:1 +音品 1 +x:1 +罗新社 1 +x:1 +经意 1 +x:1 +法则 1 +x:1 +冰凌花 1 +x:1 +营养餐 1 +x:1 +闰月 1 +x:1 +拥抱 1 +x:1 +预报处 1 +x:1 +日元 1 +x:1 +马靴 1 +x:1 +投资 1 +x:1 +玻 7 +x:7 +合作史 1 +x:1 +倒骑驴 1 +x:1 +护航舰 1 +x:1 +强健 1 +x:1 +高见 1 +x:1 +生发 1 +x:1 +上流式 1 +x:1 +土种 1 +x:1 +临终 1 +x:1 +鼓浪屿港 1 +x:1 +拉萨市 1 +x:1 +合成树脂 1 +x:1 +哀哀哭泣 1 +x:1 +冒险家 1 +x:1 +私营化 1 +x:1 +新闻署 1 +x:1 +中式盐 1 +x:1 +磨光面 1 +x:1 +东南方 1 +x:1 +内外交困 1 +x:1 +榫眼 1 +x:1 +袂 1 +x:1 +纪念邮票 1 +x:1 +盱眙 1 +x:1 +首都 1 +x:1 +告发 1 +x:1 +低回 1 +x:1 +分毫不差 1 +x:1 +满目荒凉 1 +x:1 +鸟尊 1 +x:1 +日出 1 +x:1 +节骨眼儿 1 +x:1 +二等功 1 +x:1 +法务 1 +x:1 +伏旱 1 +x:1 +交配 1 +x:1 +两手抓 1 +x:1 +抗御 1 +x:1 +空桐树 1 +x:1 +三星村 1 +x:1 +沙漠地 1 +x:1 +奇点 1 +x:1 +西北角 1 +x:1 +不为已甚 1 +x:1 +沙砾 1 +x:1 +涮洗 1 +x:1 +限界 1 +x:1 +病种 1 +x:1 +万能夹 1 +x:1 +三反五反 1 +x:1 +收工 1 +x:1 +凭卡价 1 +x:1 +总攻 1 +x:1 +马鞍 1 +x:1 +总政 1 +x:1 +玄孙 1 +x:1 +技压群雄 1 +x:1 +增辉 1 +x:1 +山之内町 1 +x:1 +总支 1 +x:1 +出诊 1 +x:1 +油脂 1 +x:1 +日内 1 +x:1 +休战 1 +x:1 +被动 1 +x:1 +香日德镇 1 +x:1 +合作区 1 +x:1 +日军 1 +x:1 +日冕 1 +x:1 +潦草 1 +x:1 +奇热 1 +x:1 +防波堤 1 +x:1 +透明化 1 +x:1 +长 1764 +x:1764 +全球性 1 +x:1 +干法 1 +x:1 +石料厂 1 +x:1 +不惑之年 1 +x:1 +怪石 1 +x:1 +悠闲 1 +x:1 +脂 1 +x:1 +谕旨 1 +x:1 +分化瓦解 1 +x:1 +栖息 1 +x:1 +选情 1 +x:1 +汉文 1 +x:1 +总括 1 +x:1 +拉巴斯 1 +x:1 +碰到 1 +x:1 +畏缩 1 +x:1 +土纸 1 +x:1 +交集 1 +x:1 +同意 1 +x:1 +晒晒 1 +x:1 +鸟害 1 +x:1 +袭击者 1 +x:1 +刘猴镇 1 +x:1 +褐家鼠 1 +x:1 +讲座 1 +x:1 +饲养业 1 +x:1 +纷 4 +x:4 +生意眼 1 +x:1 +冷冻鸡 1 +x:1 +同感 1 +x:1 +水垢 1 +x:1 +慷慨大方 1 +x:1 +哈尔滨队 1 +x:1 +水域 1 +x:1 +喃喃 1 +x:1 +烈士墓 1 +x:1 +猪舍 1 +x:1 +制盐业 1 +x:1 +水城 1 +x:1 +酒足饭饱 1 +x:1 +雷根市 1 +x:1 +汉族 1 +x:1 +北海市 1 +x:1 +清晰度 1 +x:1 +通榆县 1 +x:1 +陈旧感 1 +x:1 +排序 1 +x:1 +水基 1 +x:1 +告吹 1 +x:1 +甲板 1 +x:1 +特奥会 1 +x:1 +倒算法 1 +x:1 +核威慑 1 +x:1 +顶尖级 1 +x:1 +法商 1 +x:1 +艺品 1 +x:1 +水土 1 +x:1 +开拓 1 +x:1 +患难者 1 +x:1 +休整 1 +x:1 +铭 21 +x:21 +纠缠 1 +x:1 +置于 1 +x:1 +水圈 1 +x:1 +先贤祠 1 +x:1 +讲师 1 +x:1 +悠长 1 +x:1 +王浆 1 +x:1 +键钮 1 +x:1 +贼寇 1 +x:1 +床架 1 +x:1 +交际 1 +x:1 +光阴 1 +x:1 +水地 1 +x:1 +景遇 1 +x:1 +笨活儿 1 +x:1 +旅人 1 +x:1 +讲席 1 +x:1 +翻车鱼 1 +x:1 +翼城县 1 +x:1 +全 2007 +x:2007 +今朝 1 +x:1 +水坝 1 +x:1 +生员 1 +x:1 +超薄 1 +x:1 +约分 1 +x:1 +捍卫 1 +x:1 +水坑 1 +x:1 +镑 7 +x:7 +明贴袋 1 +x:1 +测速仪 1 +x:1 +饱嗝儿 1 +x:1 +武火 1 +x:1 +行家里手 1 +x:1 +代脉 1 +x:1 +总成 1 +x:1 +奇石 1 +x:1 +操心 1 +x:1 +豫 40 +x:40 +平坝县 1 +x:1 +出访 1 +x:1 +鼻梁骨 1 +x:1 +猫眼 1 +x:1 +沁 2 +x:2 +同性 1 +x:1 +甜酒 1 +x:1 +接报 1 +x:1 +被告 1 +x:1 +柱身 1 +x:1 +精益求精 1 +x:1 +总揽 1 +x:1 +政苑 1 +x:1 +良料 1 +x:1 +厨师 1 +x:1 +春播期 1 +x:1 +六合拳 1 +x:1 +总吨位 1 +x:1 +抗大 1 +x:1 +扎花女 1 +x:1 +张午 1 +x:1 +滞销 1 +x:1 +胶片 1 +x:1 +胶版 1 +x:1 +日均 1 +x:1 +溶媒 1 +x:1 +法名 1 +x:1 +盐卤 1 +x:1 +高达 1 +x:1 +头陀 1 +x:1 +王法 1 +x:1 +胎死腹中 1 +x:1 +海军省 1 +x:1 +旅伴 1 +x:1 +游标卡尺 1 +x:1 +太阳沟 1 +x:1 +簸箕 1 +x:1 +爱民 1 +x:1 +高迈 1 +x:1 +七八点钟 1 +x:1 +多谋善断 1 +x:1 +无线电台 1 +x:1 +金饰品 1 +x:1 +派兵 1 +x:1 +主格 1 +x:1 +智囊团 1 +x:1 +盐汽水 1 +x:1 +温驯 1 +x:1 +日场 1 +x:1 +果料儿 1 +x:1 +琅琅的 1 +x:1 +干涉 1 +x:1 +西楚 1 +x:1 +吴官屯 1 +x:1 +幢 119 +x:119 +放行率 1 +x:1 +防洪工程 1 +x:1 +无机化学 1 +x:1 +独立厅 1 +x:1 +干涸 1 +x:1 +闺阁 1 +x:1 +许可证费 1 +x:1 +停滞不前 1 +x:1 +理解 1 +x:1 +锅边 1 +x:1 +阖家 1 +x:1 +乐安 1 +x:1 +干涩 1 +x:1 +收审 1 +x:1 +胰子 1 +x:1 +盈利 1 +x:1 +上上 1 +x:1 +今晚 1 +x:1 +痛楚 1 +x:1 +马里 1 +x:1 +上下 1 +x:1 +彩票 1 +x:1 +投影机 1 +x:1 +乐学 1 +x:1 +干流 1 +x:1 +昭觉县 1 +x:1 +拱圈 1 +x:1 +爱泉 1 +x:1 +脱贫史 1 +x:1 +停机库 1 +x:1 +镀锡板 1 +x:1 +轻喜剧片 1 +x:1 +颂古非今 1 +x:1 +代职 1 +x:1 +教条 1 +x:1 +干性油 1 +x:1 +怪癖 1 +x:1 +汞溴红 1 +x:1 +来信者 1 +x:1 +烦躁 1 +x:1 +投诉 1 +x:1 +血色素 1 +x:1 +也门 1 +x:1 +收官 1 +x:1 +余数 1 +x:1 +屠宰税 1 +x:1 +消痛贴 1 +x:1 +派出 1 +x:1 +岐山 1 +x:1 +彩礼 1 +x:1 +管制区 1 +x:1 +今昔 1 +x:1 +强国 1 +x:1 +姆贝基 1 +x:1 +强固 1 +x:1 +王水 1 +x:1 +损 38 +x:38 +怅然若失 1 +x:1 +中小型 1 +x:1 +爱河 1 +x:1 +同情 1 +x:1 +止血 1 +x:1 +教本 1 +x:1 +接手 1 +x:1 +代考 1 +x:1 +非全日制 1 +x:1 +干活 1 +x:1 +龙池山 1 +x:1 +整套 1 +x:1 +监督者 1 +x:1 +观礼 1 +x:1 +今春 1 +x:1 +光面 1 +x:1 +美轮美奂 1 +x:1 +四角 1 +x:1 +乐声 1 +x:1 +层层 1 +x:1 +犯案 1 +x:1 +津津 1 +x:1 +红塔队 1 +x:1 +选拔 1 +x:1 +演丰 1 +x:1 +阐 1 +x:1 +功名 1 +x:1 +派别 1 +x:1 +溜冰场 1 +x:1 +控购 1 +x:1 +赛事化 1 +x:1 +昨晚 1 +x:1 +浅绿色 1 +x:1 +垫补 1 +x:1 +红苕 1 +x:1 +泰王国 1 +x:1 +搬家 1 +x:1 +投行 1 +x:1 +盘点 1 +x:1 +雁阵 1 +x:1 +今日 1 +x:1 +单身者 1 +x:1 +艇员队 1 +x:1 +渠江 1 +x:1 +球茎甘蓝 1 +x:1 +方向盘 1 +x:1 +刺绣工 1 +x:1 +绰源 1 +x:1 +燃气罐 1 +x:1 +温饱 1 +x:1 +饭桌 1 +x:1 +津浦 1 +x:1 +成鱼 1 +x:1 +漏管户 1 +x:1 +巴厘岛 1 +x:1 +汉柏 1 +x:1 +螺髻 1 +x:1 +今文 1 +x:1 +演习 1 +x:1 +泡影 1 +x:1 +日后 1 +x:1 +牧民 1 +x:1 +白纸黑字 1 +x:1 +珩 8 +x:8 +球迷 1 +x:1 +插翅难逃 1 +x:1 +饭桶 1 +x:1 +政事 1 +x:1 +易名 1 +x:1 +不可置疑 1 +x:1 +上下一心 1 +x:1 +佯称 1 +x:1 +快递 1 +x:1 +过冬作物 1 +x:1 +高调 1 +x:1 +苗家社人 1 +x:1 +甲状腺病 1 +x:1 +温馨 1 +x:1 +选手 1 +x:1 +感谢饭 1 +x:1 +传说 1 +x:1 +传诵 1 +x:1 +政书 1 +x:1 +津液 1 +x:1 +汉中市 1 +x:1 +圪塔 1 +x:1 +事后性 1 +x:1 +干湿 1 +x:1 +甲方 1 +x:1 +搜捕 1 +x:1 +汉末 1 +x:1 +东源村 1 +x:1 +杀死 1 +x:1 +远涉 1 +x:1 +传话 1 +x:1 +奇痒 1 +x:1 +检察员 1 +x:1 +草 240 +x:240 +传讯 1 +x:1 +土籍 1 +x:1 +百分比 1 +x:1 +乌当区 1 +x:1 +干渴 1 +x:1 +风俗人情 1 +x:1 +弹拨乐器 1 +x:1 +垫被 1 +x:1 +神妙莫测 1 +x:1 +沙河镇 1 +x:1 +引水量 1 +x:1 +三四点钟 1 +x:1 +干渠 1 +x:1 +三叶人 1 +x:1 +小调儿 1 +x:1 +自给有余 1 +x:1 +私法 1 +x:1 +赠给 1 +x:1 +厚颜无耻 1 +x:1 +塞岛 1 +x:1 +千里之行 1 +x:1 +马架子 1 +x:1 +教育股 1 +x:1 +含量 1 +x:1 +百货公司 1 +x:1 +高超 1 +x:1 +公积金 1 +x:1 +点面结合 1 +x:1 +沙粒 1 +x:1 +金银奖 1 +x:1 +剖腹藏珠 1 +x:1 +瘦 47 +x:47 +核算室 1 +x:1 +汽车业 1 +x:1 +日商 1 +x:1 +收复 1 +x:1 +通胀率 1 +x:1 +夭折 1 +x:1 +钢钎 1 +x:1 +新田村 1 +x:1 +高足 1 +x:1 +八宝饭 1 +x:1 +松紧 1 +x:1 +杏树 1 +x:1 +国会山 1 +x:1 +营业额 1 +x:1 +苟延残喘 1 +x:1 +温顺 1 +x:1 +画情 1 +x:1 +分类箱 1 +x:1 +缺心眼儿 1 +x:1 +百二河 1 +x:1 +法器 1 +x:1 +凤城 1 +x:1 +音型 1 +x:1 +传言 1 +x:1 +演奏法 1 +x:1 +关停令 1 +x:1 +鸟声 1 +x:1 +毫米 1 +x:1 +垦丁 1 +x:1 +农机具 1 +x:1 +管理局长 1 +x:1 +借以 1 +x:1 +江口 1 +x:1 +毗邻 1 +x:1 +高跷 1 +x:1 +金橘 1 +x:1 +生土 1 +x:1 +良朋 1 +x:1 +太阳渡 1 +x:1 +单项奖 1 +x:1 +较之于 1 +x:1 +只顾 1 +x:1 +南溪 1 +x:1 +津沽 1 +x:1 +钒 9 +x:9 +〕 35 +x:35 +炮声 1 +x:1 +开原市 1 +x:1 +假冒伪劣 1 +x:1 +塞尺 1 +x:1 +硅砖 1 +x:1 +塞尼 1 +x:1 +坤表 1 +x:1 +咝儿 1 +x:1 +政体 1 +x:1 +教育者 1 +x:1 +生地 1 +x:1 +比量 1 +x:1 +化纤布 1 +x:1 +比重 1 +x:1 +独立党 1 +x:1 +良机 1 +x:1 +于林庄村 1 +x:1 +来亨鸡 1 +x:1 +雷障 1 +x:1 +以情动人 1 +x:1 +报忧 1 +x:1 +高贵 1 +x:1 +法国 1 +x:1 +宋体字 1 +x:1 +开发商 1 +x:1 +开关柜 1 +x:1 +洋参 1 +x:1 +滑石粉 1 +x:1 +渝州 1 +x:1 +上楼 1 +x:1 +雷雨 1 +x:1 +萍水 1 +x:1 +乌洽会 1 +x:1 +古镇村 1 +x:1 +抗寒 1 +x:1 +鸢尾 1 +x:1 +乐天 1 +x:1 +淘汰制 1 +x:1 +忠 85 +x:85 +彩笛 1 +x:1 +交锋 1 +x:1 +增设 1 +x:1 +切身 1 +x:1 +证券法 1 +x:1 +新沂站 1 +x:1 +彩笔 1 +x:1 +教改 1 +x:1 +弃械投降 1 +x:1 +中江县 1 +x:1 +阳性率 1 +x:1 +水周 1 +x:1 +交错 1 +x:1 +伛偻病 1 +x:1 +锅贴 1 +x:1 +调角器 1 +x:1 +曝皮 1 +x:1 +洋行 1 +x:1 +默祷 1 +x:1 +政企 1 +x:1 +厮守 1 +x:1 +中际 1 +x:1 +非教师 1 +x:1 +于心不忍 1 +x:1 +金鸡纳霜 1 +x:1 +民国 1 +x:1 +廉生威 1 +x:1 +帝位 1 +x:1 +民团 1 +x:1 +钱板 1 +x:1 +碰上 1 +x:1 +毗连 1 +x:1 +眚 1 +x:1 +洞嘎乡 1 +x:1 +草炭 1 +x:1 +总结 1 +x:1 +追觅 1 +x:1 +选系 1 +x:1 +淮扬 1 +x:1 +骇人听闻 1 +x:1 +牧牛 1 +x:1 +日食 1 +x:1 +鹿邑 1 +x:1 +投降 1 +x:1 +上影线 1 +x:1 +病房 1 +x:1 +斗殴 1 +x:1 +居庸 1 +x:1 +逃命 1 +x:1 +接羔 1 +x:1 +闭市价 1 +x:1 +甘肃队 1 +x:1 +成色 1 +x:1 +不信任感 1 +x:1 +汽车兵 1 +x:1 +气功班 1 +x:1 +柴河镇 1 +x:1 +火炉子 1 +x:1 +总线 1 +x:1 +雁行 1 +x:1 +射洪县 1 +x:1 +秋粮 1 +x:1 +三拇指 1 +x:1 +空手道 1 +x:1 +甲等 1 +x:1 +曲艺团 1 +x:1 +文人相轻 1 +x:1 +红灯区 1 +x:1 +整日 1 +x:1 +无可挑剔 1 +x:1 +凸轮轴 1 +x:1 +临时 1 +x:1 +磁力计 1 +x:1 +墙垛 1 +x:1 +兀现 1 +x:1 +扩音器 1 +x:1 +政务院 1 +x:1 +浮肿 1 +x:1 +校译本 1 +x:1 +湘乡市 1 +x:1 +材料处 1 +x:1 +危险源 1 +x:1 +脓包 1 +x:1 +交界 1 +x:1 +述评 1 +x:1 +榆中县 1 +x:1 +万和镇 1 +x:1 +土戏 1 +x:1 +搭话 1 +x:1 +侄女 1 +x:1 +自觉自愿 1 +x:1 +在天之灵 1 +x:1 +传闻 1 +x:1 +才俊 1 +x:1 +早日 1 +x:1 +心诚 1 +x:1 +土房 1 +x:1 +整料 1 +x:1 +观摩 1 +x:1 +四面 1 +x:1 +改 676 +x:676 +青果巷 1 +x:1 +麦迪逊 1 +x:1 +教程 1 +x:1 +珂 6 +x:6 +时好时坏 1 +x:1 +医学奖 1 +x:1 +纳福 1 +x:1 +奥斯卡史 1 +x:1 +挪方 1 +x:1 +饭盒 1 +x:1 +独吞 1 +x:1 +牧犬 1 +x:1 +依东县 1 +x:1 +秃鹫 1 +x:1 +沈铁 1 +x:1 +迪 2 +x:2 +州直 1 +x:1 +金字招牌 1 +x:1 +武江 1 +x:1 +本色 1 +x:1 +武汉 1 +x:1 +借入 1 +x:1 +痛痒 1 +x:1 +疯牛病 1 +x:1 +霄 38 +x:38 +松洲街 1 +x:1 +高速公路 1 +x:1 +父爱 1 +x:1 +接线 1 +x:1 +鞋袜 1 +x:1 +痛症 1 +x:1 +纯 96 +x:96 +千条万条 1 +x:1 +荞麦皮 1 +x:1 +就业处 1 +x:1 +马赛 1 +x:1 +接纳 1 +x:1 +彩旦 1 +x:1 +维修 1 +x:1 +锁缝机 1 +x:1 +有始有终 1 +x:1 +培训点 1 +x:1 +丢脸 1 +x:1 +痛痹 1 +x:1 +太阳炉 1 +x:1 +彩旗 1 +x:1 +干燥 1 +x:1 +宿敌 1 +x:1 +健康房 1 +x:1 +短距离 1 +x:1 +持旗者 1 +x:1 +迎宾 1 +x:1 +接续 1 +x:1 +实中求新 1 +x:1 +旅协 1 +x:1 +溶解 1 +x:1 +糖茶 1 +x:1 +混装 1 +x:1 +定时炸弹 1 +x:1 +竞技队 1 +x:1 +巡警队 1 +x:1 +破蛋 1 +x:1 +浑然谐调 1 +x:1 +同类 1 +x:1 +人心惶惶 1 +x:1 +消亡 1 +x:1 +四难 1 +x:1 +上访量 1 +x:1 +妄图 1 +x:1 +芥菜 1 +x:1 +威海卫 1 +x:1 +黄金档 1 +x:1 +大有益处 1 +x:1 +使用率 1 +x:1 +培训热 1 +x:1 +药箱 1 +x:1 +总署 1 +x:1 +票友会 1 +x:1 +垄 5 +x:5 +用活 1 +x:1 +交警 1 +x:1 +嵊泗 1 +x:1 +科佳 1 +x:1 +郎舅 1 +x:1 +国家制式 1 +x:1 +弹跳 1 +x:1 +塑胶粒 1 +x:1 +灭蚊片 1 +x:1 +锁链子 1 +x:1 +借债 1 +x:1 +信贷员 1 +x:1 +马路 1 +x:1 +炮台镇 1 +x:1 +封顶价 1 +x:1 +鲱鱼 1 +x:1 +健康报 1 +x:1 +恨事 1 +x:1 +早操 1 +x:1 +格调 1 +x:1 +明溪县 1 +x:1 +术式 1 +x:1 +淡红 1 +x:1 +际 7 +x:7 +严苛 1 +x:1 +怦然 1 +x:1 +鹅蛋脸 1 +x:1 +线务员 1 +x:1 +超额 1 +x:1 +制盐厂 1 +x:1 +柳铁 1 +x:1 +崇拜者 1 +x:1 +寸水 1 +x:1 +冲锋号 1 +x:1 +总编 1 +x:1 +临摹 1 +x:1 +监督关 1 +x:1 +浑天仪 1 +x:1 +脱逃 1 +x:1 +车满为患 1 +x:1 +唐卡 1 +x:1 +荷 84 +x:84 +个展 1 +x:1 +少有 1 +x:1 +旸 2 +x:2 +一往情深 1 +x:1 +洛杉矶市 1 +x:1 +比较 1 +x:1 +四马台村 1 +x:1 +马蹄 1 +x:1 +鼓板 1 +x:1 +温蔼 1 +x:1 +花骨朵 1 +x:1 +雌雄异株 1 +x:1 +评选者 1 +x:1 +汽车区 1 +x:1 +病态 1 +x:1 +裹尸马革 1 +x:1 +组派 1 +x:1 +涕 2 +x:2 +培训率 1 +x:1 +今秋 1 +x:1 +汉简 1 +x:1 +高邑 1 +x:1 +救助者 1 +x:1 +建研会 1 +x:1 +求医问药 1 +x:1 +高邮 1 +x:1 +睢宁 1 +x:1 +民品 1 +x:1 +弗纶 1 +x:1 +宝藏 1 +x:1 +凝听者 1 +x:1 +鹊桥 1 +x:1 +深根固蒂 1 +x:1 +游击式 1 +x:1 +临柜 1 +x:1 +散文式 1 +x:1 +汨罗镇 1 +x:1 +垦区 1 +x:1 +兴牧富民 1 +x:1 +震中区 1 +x:1 +祭天坛 1 +x:1 +疏 37 +x:37 +菜圃 1 +x:1 +演剧 1 +x:1 +国宝级 1 +x:1 +海商 1 +x:1 +蹴球 1 +x:1 +瓦加杜古 1 +x:1 +螺蛳 1 +x:1 +手戳 1 +x:1 +欺骗 1 +x:1 +吟诵 1 +x:1 +满族乡 1 +x:1 +纵坐标 1 +x:1 +苌池乡 1 +x:1 +觅 35 +x:35 +容颜 1 +x:1 +灰飞烟灭 1 +x:1 +高都 1 +x:1 +富营养化 1 +x:1 +本能 1 +x:1 +培训班 1 +x:1 +严父慈母 1 +x:1 +比萨饼 1 +x:1 +校党委 1 +x:1 +垄断性 1 +x:1 +可传达性 1 +x:1 +暮云春树 1 +x:1 +生肖物 1 +x:1 +民命 1 +x:1 +临朐 1 +x:1 +储油库 1 +x:1 +五九年 1 +x:1 +西北部 1 +x:1 +拓本 1 +x:1 +四联单 1 +x:1 +三爱 1 +x:1 +埃航 1 +x:1 +交行 1 +x:1 +人工气胸 1 +x:1 +二十一中 1 +x:1 +逼真 1 +x:1 +观景 1 +x:1 +王府井 1 +x:1 +汽车厂 1 +x:1 +墙基 1 +x:1 +高逾 1 +x:1 +武清 1 +x:1 +西北郊 1 +x:1 +土性 1 +x:1 +浮艳 1 +x:1 +涂抹 1 +x:1 +务 15 +x:15 +开关站 1 +x:1 +文印部 1 +x:1 +中阳 1 +x:1 +病情 1 +x:1 +六六年 1 +x:1 +本职 1 +x:1 +院貌 1 +x:1 +学者卷 1 +x:1 +肛肠科 1 +x:1 +观星 1 +x:1 +教研 1 +x:1 +区块 1 +x:1 +颅骨 1 +x:1 +参赛国 1 +x:1 +密密麻麻 1 +x:1 +干爸 1 +x:1 +马身 1 +x:1 +盐务局 1 +x:1 +下苦功夫 1 +x:1 +福海 1 +x:1 +梁子湖区 1 +x:1 +私营者 1 +x:1 +桅顶 1 +x:1 +控释 1 +x:1 +流入量 1 +x:1 +国务院令 1 +x:1 +亭榭画廊 1 +x:1 +病愈 1 +x:1 +少时 1 +x:1 +杂牌 1 +x:1 +比起 1 +x:1 +咨询会 1 +x:1 +宝应拾屯 1 +x:1 +主桥墩 1 +x:1 +早晨 1 +x:1 +抡斧伐桂 1 +x:1 +神来之笔 1 +x:1 +陆防区 1 +x:1 +天老爷 1 +x:1 +马车 1 +x:1 +人工气腹 1 +x:1 +早晚 1 +x:1 +比赛 1 +x:1 +政变 1 +x:1 +超音速 1 +x:1 +授戒 1 +x:1 +杂物 1 +x:1 +政发 1 +x:1 +索罟湾 1 +x:1 +代付 1 +x:1 +借助 1 +x:1 +交角 1 +x:1 +文工团员 1 +x:1 +可比价 1 +x:1 +麦角新碱 1 +x:1 +图索骥式 1 +x:1 +听话者 1 +x:1 +入国问禁 1 +x:1 +植保 1 +x:1 +东西向 1 +x:1 +胶水 1 +x:1 +纳税 1 +x:1 +饥寒交迫 1 +x:1 +选美 1 +x:1 +南缘 1 +x:1 +早春 1 +x:1 +经济学家 1 +x:1 +常规性 1 +x:1 +脖颈儿 1 +x:1 +传阅 1 +x:1 +歪风 1 +x:1 +派位 1 +x:1 +同级 1 +x:1 +胶泥 1 +x:1 +鼓曲 1 +x:1 +犯病 1 +x:1 +漓 2 +x:2 +马拉开波 1 +x:1 +超高 1 +x:1 +褒贬 1 +x:1 +比较性 1 +x:1 +扎曲 1 +x:1 +铁栅栏 1 +x:1 +螳臂当车 1 +x:1 +天马行空 1 +x:1 +浮荡 1 +x:1 +厨子 1 +x:1 +审核费 1 +x:1 +贬值率 1 +x:1 +忧心忡忡 1 +x:1 +王牌 1 +x:1 +政协 1 +x:1 +盘活 1 +x:1 +蔚成新风 1 +x:1 +翻领 1 +x:1 +民商 1 +x:1 +东方村 1 +x:1 +褒扬状 1 +x:1 +钟祥 1 +x:1 +错综复杂 1 +x:1 +马迹 1 +x:1 +醇化 1 +x:1 +渑水燕 1 +x:1 +令行禁止 1 +x:1 +读书界 1 +x:1 +害胺 1 +x:1 +化合 1 +x:1 +调质处理 1 +x:1 +化名 1 +x:1 +选编 1 +x:1 +朝天门 1 +x:1 +诏书 1 +x:1 +王爷 1 +x:1 +长此以往 1 +x:1 +抛掷 1 +x:1 +古墓群 1 +x:1 +犯疑 1 +x:1 +观望 1 +x:1 +干扰源 1 +x:1 +同组 1 +x:1 +罚息 1 +x:1 +谏壁口 1 +x:1 +演变 1 +x:1 +也许 1 +x:1 +形象思维 1 +x:1 +机电系 1 +x:1 +土壤层 1 +x:1 +体检组 1 +x:1 +翻飞 1 +x:1 +和解派 1 +x:1 +积石 1 +x:1 +融安县 1 +x:1 +马达 1 +x:1 +爱犬 1 +x:1 +购房款 1 +x:1 +体胀系数 1 +x:1 +功业 1 +x:1 +教练 1 +x:1 +接管 1 +x:1 +穿透力 1 +x:1 +教给 1 +x:1 +博览局 1 +x:1 +郊野 1 +x:1 +沙果 1 +x:1 +装有 1 +x:1 +炮兵群 1 +x:1 +早慧 1 +x:1 +血肉之躯 1 +x:1 +接待站 1 +x:1 +出游率 1 +x:1 +背着 1 +x:1 +除弊 1 +x:1 +街灯 1 +x:1 +破获 1 +x:1 +沙枣 1 +x:1 +复合肥 1 +x:1 +马表 1 +x:1 +健康机 1 +x:1 +高难 1 +x:1 +北海港 1 +x:1 +芦苇荡 1 +x:1 +水保 1 +x:1 +占 2663 +x:2663 +健康权 1 +x:1 +压舱石 1 +x:1 +股权证 1 +x:1 +高雄 1 +x:1 +高雅 1 +x:1 +增选 1 +x:1 +不思悔改 1 +x:1 +电力业 1 +x:1 +延续性 1 +x:1 +摸黑儿 1 +x:1 +就业局 1 +x:1 +成虫 1 +x:1 +醇和 1 +x:1 +成长史 1 +x:1 +日丰 1 +x:1 +回归线 1 +x:1 +燕峒乡 1 +x:1 +演员 1 +x:1 +余粮 1 +x:1 +痛点 1 +x:1 +杂用 1 +x:1 +民办 1 +x:1 +千疮百孔 1 +x:1 +立方根 1 +x:1 +迎击 1 +x:1 +床罩 1 +x:1 +沙柱 1 +x:1 +沙柳 1 +x:1 +象牙之塔 1 +x:1 +州牧 1 +x:1 +土星 1 +x:1 +接线员 1 +x:1 +戏 335 +x:335 +鬓间 1 +x:1 +武校 1 +x:1 +逆浪回冲 1 +x:1 +再审 1 +x:1 +多义词 1 +x:1 +寸楷 1 +x:1 +射流技术 1 +x:1 +马裤 1 +x:1 +判断力 1 +x:1 +重祖父 1 +x:1 +凤城市 1 +x:1 +利民村 1 +x:1 +蜻蜓点水 1 +x:1 +被冤枉者 1 +x:1 +大嗓门儿 1 +x:1 +黯然失色 1 +x:1 +高阳 1 +x:1 +文艺兵 1 +x:1 +分工 1 +x:1 +罪孽 1 +x:1 +青风寨 1 +x:1 +毛纺织 1 +x:1 +严寒 1 +x:1 +格西 1 +x:1 +日产 1 +x:1 +水体 1 +x:1 +水位 1 +x:1 +腾空而起 1 +x:1 +沙村 1 +x:1 +毋庸置疑 1 +x:1 +软化剂 1 +x:1 +棉纺织 1 +x:1 +高院 1 +x:1 +鑫 19 +x:19 +同种 1 +x:1 +民初 1 +x:1 +龛图 1 +x:1 +易事 1 +x:1 +易于 1 +x:1 +沙松 1 +x:1 +总程 1 +x:1 +化医 1 +x:1 +高陵 1 +x:1 +土果 1 +x:1 +蓬勃 1 +x:1 +独领风骚 1 +x:1 +线装本 1 +x:1 +协议书 1 +x:1 +将来 1 +x:1 +水井 1 +x:1 +吃干榨净 1 +x:1 +三季稻 1 +x:1 +能级 1 +x:1 +选种 1 +x:1 +青丝帕 1 +x:1 +营业员 1 +x:1 +头钱 1 +x:1 +如臂使指 1 +x:1 +常明灯 1 +x:1 +光边 1 +x:1 +妄动 1 +x:1 +沾溉 1 +x:1 +纳米 1 +x:1 +居室 1 +x:1 +传遍 1 +x:1 +落井下石 1 +x:1 +电熨斗 1 +x:1 +库诺维采 1 +x:1 +土枪 1 +x:1 +交还 1 +x:1 +水产 1 +x:1 +昔者 1 +x:1 +装卸业 1 +x:1 +涂改 1 +x:1 +逃兵 1 +x:1 +储量 1 +x:1 +大舅子 1 +x:1 +马褂 1 +x:1 +水仙 1 +x:1 +总管 1 +x:1 +津百 1 +x:1 +基本建设 1 +x:1 +普渡众生 1 +x:1 +尿肥 1 +x:1 +云块 1 +x:1 +坐标系 1 +x:1 +宰割 1 +x:1 +水份 1 +x:1 +总算 1 +x:1 +比肩而邻 1 +x:1 +抑或 1 +x:1 +水价 1 +x:1 +储采 1 +x:1 +传递 1 +x:1 +趟马 1 +x:1 +平定县 1 +x:1 +驱车 1 +x:1 +郡县 1 +x:1 +高音 1 +x:1 +造反派 1 +x:1 +伏笔 1 +x:1 +祷告声 1 +x:1 +用品部 1 +x:1 +评判人 1 +x:1 +屠宰户 1 +x:1 +熊熊 1 +x:1 +溶质 1 +x:1 +弯弯曲曲 1 +x:1 +家族式 1 +x:1 +芙蓉城 1 +x:1 +水专 1 +x:1 +烦难 1 +x:1 +怒气攻心 1 +x:1 +结扎户 1 +x:1 +定兴县 1 +x:1 +重生父母 1 +x:1 +水上 1 +x:1 +水下 1 +x:1 +强人 1 +x:1 +增量 1 +x:1 +淡竹 1 +x:1 +陆家嘴 1 +x:1 +涂料 1 +x:1 +白璧无瑕 1 +x:1 +打麦场 1 +x:1 +破船 1 +x:1 +白果塔村 1 +x:1 +漫画集 1 +x:1 +盟军 1 +x:1 +杀灭 1 +x:1 +胎教 1 +x:1 +台特玛湖 1 +x:1 +区域 1 +x:1 +土木 1 +x:1 +政商 1 +x:1 +思前想后 1 +x:1 +反攻倒算 1 +x:1 +哞哞 1 +x:1 +强令 1 +x:1 +妯娌 1 +x:1 +土村 1 +x:1 +甲组 1 +x:1 +学位制 1 +x:1 +蹊径 1 +x:1 +观感 1 +x:1 +香味 1 +x:1 +陋室 1 +x:1 +飞 446 +x:446 +② 42 +x:42 +空手棍 1 +x:1 +纳粹 1 +x:1 +脚踏车 1 +x:1 +限 83 +x:83 +罗布林卡 1 +x:1 +商贸会 1 +x:1 +耐受力 1 +x:1 +腰缠万贯 1 +x:1 +乡民 1 +x:1 +云梯车 1 +x:1 +东柏坡 1 +x:1 +喊叫 1 +x:1 +接穗 1 +x:1 +会计学系 1 +x:1 +水乡 1 +x:1 +仰角 1 +x:1 +扎 129 +x:129 +张家川村 1 +x:1 +射手榜 1 +x:1 +化减 1 +x:1 +生于 1 +x:1 +生事 1 +x:1 +阵地战 1 +x:1 +鼓捣 1 +x:1 +彻骨 1 +x:1 +四野 1 +x:1 +墟 1 +x:1 +主凶 1 +x:1 +唯独 1 +x:1 +生人 1 +x:1 +覆没 1 +x:1 +装腔作势 1 +x:1 +亏心 1 +x:1 +听 899 +x:899 +教育馆 1 +x:1 +芥蒂 1 +x:1 +力创 1 +x:1 +一年四季 1 +x:1 +生产 1 +x:1 +硝酸铵 1 +x:1 +文艺史 1 +x:1 +有色人种 1 +x:1 +悠远 1 +x:1 +锅铲 1 +x:1 +接收器 1 +x:1 +束米甸村 1 +x:1 +鳇 1 +x:1 +灯光师 1 +x:1 +坚毅不屈 1 +x:1 +贫民区 1 +x:1 +穹隆式 1 +x:1 +哭天抢地 1 +x:1 +戮力同心 1 +x:1 +透明人 1 +x:1 +修车款 1 +x:1 +盐化 1 +x:1 +失神 1 +x:1 +彩报 1 +x:1 +接种 1 +x:1 +耳闻目睹 1 +x:1 +居士 1 +x:1 +亏待 1 +x:1 +适口 1 +x:1 +卉 2 +x:2 +硝酸钠 1 +x:1 +投递 1 +x:1 +罗案 1 +x:1 +睿智者 1 +x:1 +光大 1 +x:1 +亏得 1 +x:1 +默想 1 +x:1 +软皮条 1 +x:1 +化冻 1 +x:1 +投送 1 +x:1 +直性子 1 +x:1 +生丝 1 +x:1 +创牌子 1 +x:1 +生业 1 +x:1 +杂和菜 1 +x:1 +世博行 1 +x:1 +中青 1 +x:1 +开机 1 +x:1 +浪里去 1 +x:1 +红原县 1 +x:1 +敌围我散 1 +x:1 +被俘 1 +x:1 +怎样 1 +x:1 +米赫巴 1 +x:1 +确定无疑 1 +x:1 +唯物 1 +x:1 +经验谈 1 +x:1 +千家街 1 +x:1 +美茵河 1 +x:1 +指关节 1 +x:1 +爱知 1 +x:1 +鞋行 1 +x:1 +法例 1 +x:1 +议政 1 +x:1 +闲不住 1 +x:1 +芸 5 +x:5 +榨汁 1 +x:1 +背痛 1 +x:1 +鸦岭乡 1 +x:1 +瓮安 1 +x:1 +发球奖 1 +x:1 +火头军 1 +x:1 +超龄 1 +x:1 +饰演者 1 +x:1 +得数 1 +x:1 +提示型 1 +x:1 +静电计 1 +x:1 +管内 1 +x:1 +观战 1 +x:1 +猫洞 1 +x:1 +强制力 1 +x:1 +毫无 1 +x:1 +交谊 1 +x:1 +交谈 1 +x:1 +淋巴液 1 +x:1 +干瘦 1 +x:1 +天津港 1 +x:1 +鼓掌 1 +x:1 +频律 1 +x:1 +直直 1 +x:1 +汽车城 1 +x:1 +散文家 1 +x:1 +总称 1 +x:1 +帆 47 +x:47 +大窑湾 1 +x:1 +奋然 1 +x:1 +赠机 1 +x:1 +接碴 1 +x:1 +防暑 1 +x:1 +扎手 1 +x:1 +土方 1 +x:1 +埋怨声 1 +x:1 +牧畜 1 +x:1 +成衣店 1 +x:1 +美好 1 +x:1 +鼓手 1 +x:1 +藩篱 1 +x:1 +手挥千军 1 +x:1 +轻型化 1 +x:1 +豆腐羹 1 +x:1 +对二甲苯 1 +x:1 +细工 1 +x:1 +生保 1 +x:1 +露采坑 1 +x:1 +双赛制 1 +x:1 +细巧 1 +x:1 +衣食住行 1 +x:1 +土族 1 +x:1 +诓 2 +x:2 +手写板 1 +x:1 +岔曲儿 1 +x:1 +频带 1 +x:1 +居委 1 +x:1 +丛台区 1 +x:1 +抽空 1 +x:1 +驱走 1 +x:1 +盐田港区 1 +x:1 +驱赶 1 +x:1 +四邻 1 +x:1 +彩排 1 +x:1 +归口 1 +x:1 +凯 41 +x:41 +甲类 1 +x:1 +逃匿 1 +x:1 +随风转舵 1 +x:1 +唐宋 1 +x:1 +再婚 1 +x:1 +野葫芦引 1 +x:1 +有期徒刑 1 +x:1 +间作 1 +x:1 +民兵 1 +x:1 +临战 1 +x:1 +法人 1 +x:1 +居处 1 +x:1 +种衣剂 1 +x:1 +济困 1 +x:1 +垦团 1 +x:1 +玛瑙杏 1 +x:1 +良缘 1 +x:1 +化做 1 +x:1 +绥棱 1 +x:1 +公务车 1 +x:1 +伏秋 1 +x:1 +瑶族乡 1 +x:1 +土改 1 +x:1 +五位一体 1 +x:1 +同窗 1 +x:1 +投量 1 +x:1 +一败涂地 1 +x:1 +湖人队 1 +x:1 +格言 1 +x:1 +晋材楚用 1 +x:1 +民先 1 +x:1 +防暴 1 +x:1 +航船 1 +x:1 +嵇 6 +x:6 +洪家嘴乡 1 +x:1 +交账 1 +x:1 +四通 1 +x:1 +交财 1 +x:1 +抽穗 1 +x:1 +拎 32 +x:32 +拍卖所 1 +x:1 +汽车团 1 +x:1 +朱寨村 1 +x:1 +弧形 1 +x:1 +频度 1 +x:1 +法令 1 +x:1 +丑小鸭 1 +x:1 +外劳 1 +x:1 +给水团 1 +x:1 +颤 10 +x:10 +奇女子 1 +x:1 +攻城掠地 1 +x:1 +伤残 1 +x:1 +黑胡椒 1 +x:1 +干眼 1 +x:1 +材料库 1 +x:1 +天地良心 1 +x:1 +酯 3 +x:3 +余缺 1 +x:1 +红灿灿 1 +x:1 +心宽体胖 1 +x:1 +胶条 1 +x:1 +花红树绿 1 +x:1 +好声好气 1 +x:1 +中至大雨 1 +x:1 +乱七八糟 1 +x:1 +民建 1 +x:1 +爱神 1 +x:1 +横路乡 1 +x:1 +生鲜 1 +x:1 +远游 1 +x:1 +余烟 1 +x:1 +盟兄弟 1 +x:1 +缚 6 +x:6 +总目 1 +x:1 +总监 1 +x:1 +生造字 1 +x:1 +余热 1 +x:1 +余烬 1 +x:1 +小心眼儿 1 +x:1 +渺无人烟 1 +x:1 +分类法 1 +x:1 +小手指头 1 +x:1 +田蓬镇 1 +x:1 +热门儿 1 +x:1 +堆渣 1 +x:1 +扩产 1 +x:1 +嘴 91 +x:91 +突击队员 1 +x:1 +一跃而起 1 +x:1 +同甘 1 +x:1 +胶木 1 +x:1 +顺德市 1 +x:1 +成都路 1 +x:1 +简支梁 1 +x:1 +死于非命 1 +x:1 +高高 1 +x:1 +晔 8 +x:8 +温软 1 +x:1 +正当年 1 +x:1 +长丰县 1 +x:1 +统揽全局 1 +x:1 +航天 1 +x:1 +乐亭 1 +x:1 +感谢辞 1 +x:1 +磷协 1 +x:1 +自考办 1 +x:1 +浩瀚无垠 1 +x:1 +学生林 1 +x:1 +絮 4 +x:4 +石清沟村 1 +x:1 +绿头鸭 1 +x:1 +总的 1 +x:1 +盘曲 1 +x:1 +乐事 1 +x:1 +妄念 1 +x:1 +通车率 1 +x:1 +超重 1 +x:1 +超量 1 +x:1 +赤裸裸 1 +x:1 +兴隆片林 1 +x:1 +杂种 1 +x:1 +刁钻古怪 1 +x:1 +频出 1 +x:1 +太上老君 1 +x:1 +失礼 1 +x:1 +络绎不绝 1 +x:1 +牧童 1 +x:1 +厉兵秣马 1 +x:1 +自然规律 1 +x:1 +长二捆 1 +x:1 +背篼 1 +x:1 +马蓝 1 +x:1 +超金 1 +x:1 +爱称 1 +x:1 +余火 1 +x:1 +专题片 1 +x:1 +监督镜 1 +x:1 +临洮 1 +x:1 +邰 2 +x:2 +罚款 1 +x:1 +背篓 1 +x:1 +饭纲 1 +x:1 +实至名归 1 +x:1 +虚虚实实 1 +x:1 +土模 1 +x:1 +教育面 1 +x:1 +邦典村 1 +x:1 +宽容度 1 +x:1 +各就各位 1 +x:1 +鼓涨 1 +x:1 +消防处 1 +x:1 +毫毛 1 +x:1 +音儿 1 +x:1 +白木耳 1 +x:1 +高青县 1 +x:1 +乡愁 1 +x:1 +犯纪 1 +x:1 +豆腐干儿 1 +x:1 +乐业 1 +x:1 +临海 1 +x:1 +代销 1 +x:1 +接着 1 +x:1 +投影片 1 +x:1 +借风使船 1 +x:1 +使用税 1 +x:1 +家长里短 1 +x:1 +文体部 1 +x:1 +拼 75 +x:75 +总枢百端 1 +x:1 +表演史 1 +x:1 +拥军优属 1 +x:1 +糅合 1 +x:1 +兀立 1 +x:1 +脖颈子 1 +x:1 +硫酸根 1 +x:1 +扭扭曲曲 1 +x:1 +民忧 1 +x:1 +临沂 1 +x:1 +武断 1 +x:1 +同理 1 +x:1 +乡情 1 +x:1 +洼田 1 +x:1 +怪招 1 +x:1 +关上村 1 +x:1 +政委 1 +x:1 +民心 1 +x:1 +怒涛震海 1 +x:1 +鞭声 1 +x:1 +氯氟烃 1 +x:1 +易熔合金 1 +x:1 +化建 1 +x:1 +领奖台 1 +x:1 +造型观 1 +x:1 +老校 1 +x:1 +主典 1 +x:1 +拍卖法 1 +x:1 +民德 1 +x:1 +忍让 1 +x:1 +扶余县 1 +x:1 +真理观 1 +x:1 +超速 1 +x:1 +武旦 1 +x:1 +奇才 1 +x:1 +人杰地灵 1 +x:1 +回归率 1 +x:1 +压缩机 1 +x:1 +临泽 1 +x:1 +滥 83 +x:83 +交通台 1 +x:1 +陌于 1 +x:1 +法书 1 +x:1 +甘井子区 1 +x:1 +安江乡 1 +x:1 +鼓气 1 +x:1 +半瓶醋 1 +x:1 +螺距 1 +x:1 +一轻局 1 +x:1 +芒 8 +x:8 +接盘 1 +x:1 +脑上体 1 +x:1 +本诸 1 +x:1 +管理点 1 +x:1 +糅和 1 +x:1 +径 4 +x:4 +病残 1 +x:1 +肮脏 1 +x:1 +聚合力 1 +x:1 +消费观 1 +x:1 +厨具 1 +x:1 +文艺局 1 +x:1 +观测 1 +x:1 +总督 1 +x:1 +家族化 1 +x:1 +被子植物 1 +x:1 +爱书者 1 +x:1 +初 1103 +x:1103 +责 52 +x:52 +雷霆万钧 1 +x:1 +旅客 1 +x:1 +怪才 1 +x:1 +图册 1 +x:1 +早泄 1 +x:1 +乌邦寺 1 +x:1 +临江 1 +x:1 +鹅 10 +x:10 +呼图克图 1 +x:1 +成说 1 +x:1 +杂碎 1 +x:1 +住 1276 +x:1276 +宁海镇 1 +x:1 +山莨菪碱 1 +x:1 +线粒体 1 +x:1 +频催 1 +x:1 +临朐县 1 +x:1 +病毒 1 +x:1 +临汾 1 +x:1 +王码 1 +x:1 +受礼 1 +x:1 +明石海峡 1 +x:1 +陌上 1 +x:1 +限期 1 +x:1 +选用 1 +x:1 +危险期 1 +x:1 +三明路 1 +x:1 +台球城 1 +x:1 +吞噬细胞 1 +x:1 +光荣 1 +x:1 +乡思 1 +x:1 +宪兵队 1 +x:1 +弧光 1 +x:1 +回头客 1 +x:1 +航迹 1 +x:1 +含蓄 1 +x:1 +马虎 1 +x:1 +高领 1 +x:1 +断流期 1 +x:1 +汉王 1 +x:1 +高额 1 +x:1 +睢县 1 +x:1 +痛经 1 +x:1 +化州 1 +x:1 +借宿 1 +x:1 +潜伏地 1 +x:1 +低下 1 +x:1 +化工 1 +x:1 +磁倾角 1 +x:1 +病株 1 +x:1 +亚特兰大 1 +x:1 +验管 1 +x:1 +俯卧撑 1 +x:1 +夹心糖 1 +x:1 +百里挑一 1 +x:1 +存亡未卜 1 +x:1 +温泉乡 1 +x:1 +回归热 1 +x:1 +临澧 1 +x:1 +朝朝暮暮 1 +x:1 +水田镇 1 +x:1 +瓦隆 1 +x:1 +转告 1 +x:1 +玛瑙 1 +x:1 +提供量 1 +x:1 +成衣 1 +x:1 +土棍 1 +x:1 +共悲共愤 1 +x:1 +方框图 1 +x:1 +光能 1 +x:1 +鹤发鸡皮 1 +x:1 +磷光 1 +x:1 +中医药学 1 +x:1 +医学史 1 +x:1 +弥坚 1 +x:1 +成行 1 +x:1 +运营权 1 +x:1 +外错角 1 +x:1 +塞音 1 +x:1 +接用 1 +x:1 +空手枪 1 +x:1 +地道 1 +x:1 +厂貌 1 +x:1 +暮霭 1 +x:1 +南斯拉夫 1 +x:1 +抗争 1 +x:1 +不起眼 1 +x:1 +县局级 1 +x:1 +用油 1 +x:1 +头奖 1 +x:1 +鞭子 1 +x:1 +饭粒 1 +x:1 +光耀 1 +x:1 +东方学系 1 +x:1 +频发 1 +x:1 +选登 1 +x:1 +盒子 1 +x:1 +三圣庙村 1 +x:1 +破费 1 +x:1 +自行车队 1 +x:1 +皮筏 1 +x:1 +临漳 1 +x:1 +蓝藻 1 +x:1 +关系法 1 +x:1 +接生 1 +x:1 +核反应堆 1 +x:1 +民居 1 +x:1 +受气包 1 +x:1 +阴历年 1 +x:1 +破败 1 +x:1 +武昌 1 +x:1 +术后 1 +x:1 +说动 1 +x:1 +和乐 1 +x:1 +本行 1 +x:1 +闯江湖 1 +x:1 +逃废 1 +x:1 +荷兰病 1 +x:1 +老鼠过街 1 +x:1 +背离 1 +x:1 +陨星 1 +x:1 +佚名 1 +x:1 +临潼 1 +x:1 +交底 1 +x:1 +找回 1 +x:1 +卧龙 1 +x:1 +自纠自查 1 +x:1 +悄声 1 +x:1 +燕郊 1 +x:1 +材料厂 1 +x:1 +末世 1 +x:1 +马蝇 1 +x:1 +非歧视性 1 +x:1 +限时 1 +x:1 +对不起 1 +x:1 +沙梁 1 +x:1 +赞赏 1 +x:1 +照相仪 1 +x:1 +民工 1 +x:1 +民乐县 1 +x:1 +明出大卖 1 +x:1 +彩蝴蝶 1 +x:1 +旅外 1 +x:1 +赠款 1 +x:1 +沙梨 1 +x:1 +容量 1 +x:1 +武林 1 +x:1 +官宦 1 +x:1 +言简意赅 1 +x:1 +胎毛 1 +x:1 +掺沙子 1 +x:1 +胎毒 1 +x:1 +奇怪 1 +x:1 +休养生息 1 +x:1 +盘旋 1 +x:1 +果仁儿 1 +x:1 +马蜂 1 +x:1 +游戏机 1 +x:1 +甜蜜 1 +x:1 +序盘 1 +x:1 +作弊 1 +x:1 +沙棘 1 +x:1 +抗体 1 +x:1 +台阶 1 +x:1 +政客 1 +x:1 +政审 1 +x:1 +雁荡 1 +x:1 +板儿车 1 +x:1 +冲渣池 1 +x:1 +人武部长 1 +x:1 +有章可依 1 +x:1 +着凉 1 +x:1 +抽冷子 1 +x:1 +总司令部 1 +x:1 +干管 1 +x:1 +密切 1 +x:1 +大百科 1 +x:1 +独展芳容 1 +x:1 +朱张桥 1 +x:1 +稍有不慎 1 +x:1 +颂 44 +x:44 +光脑 1 +x:1 +绿色植物 1 +x:1 +议标 1 +x:1 +监督院 1 +x:1 +流出地 1 +x:1 +武术 1 +x:1 +人亡物在 1 +x:1 +台柱子 1 +x:1 +冲压机 1 +x:1 +观潮 1 +x:1 +接球 1 +x:1 +足额 1 +x:1 +罪名 1 +x:1 +结对数 1 +x:1 +病榻 1 +x:1 +含蕴 1 +x:1 +小叶儿茶 1 +x:1 +积分赛 1 +x:1 +心气 1 +x:1 +白口铁 1 +x:1 +捷通社 1 +x:1 +字画区 1 +x:1 +限收 1 +x:1 +干笑 1 +x:1 +逃往 1 +x:1 +衍 21 +x:21 +武松 1 +x:1 +太阳穴 1 +x:1 +坡田 1 +x:1 +莲子居 1 +x:1 +拙笔 1 +x:1 +甲骨学 1 +x:1 +罗列 1 +x:1 +甲烷 1 +x:1 +奇想 1 +x:1 +年份 1 +x:1 +文教局 1 +x:1 +自卸式 1 +x:1 +吗啡剂 1 +x:1 +歪道 1 +x:1 +顺便 1 +x:1 +私拿 1 +x:1 +成规 1 +x:1 +拉巴特 1 +x:1 +同盟 1 +x:1 +万花筒 1 +x:1 +盘整 1 +x:1 +彩漆 1 +x:1 +踏头草 1 +x:1 +教益 1 +x:1 +大肚汉 1 +x:1 +南沙沟 1 +x:1 +老天爷 1 +x:1 +转向 1 +x:1 +锡朱德 1 +x:1 +观棋 1 +x:1 +居功 1 +x:1 +抑止 1 +x:1 +钳蝎 1 +x:1 +伏特 1 +x:1 +募集 1 +x:1 +整理者 1 +x:1 +威海市 1 +x:1 +硝盐 1 +x:1 +彩棚 1 +x:1 +讥 3 +x:3 +血友病 1 +x:1 +挪 30 +x:30 +本身 1 +x:1 +干系 1 +x:1 +彩棉 1 +x:1 +过街老鼠 1 +x:1 +超长 1 +x:1 +露 74 +x:74 +伏牛 1 +x:1 +提倡者 1 +x:1 +乡旗 1 +x:1 +民旺村 1 +x:1 +代金 1 +x:1 +八仙茶 1 +x:1 +接班 1 +x:1 +弥天大错 1 +x:1 +停机位 1 +x:1 +枣强县 1 +x:1 +吊销期 1 +x:1 +奇材 1 +x:1 +教皇 1 +x:1 +破译 1 +x:1 +一墙之隔 1 +x:1 +撑竿跳 1 +x:1 +中办 1 +x:1 +拍卖槌 1 +x:1 +干粉 1 +x:1 +彩梦 1 +x:1 +巨型机 1 +x:1 +渝水区 1 +x:1 +讲价 1 +x:1 +涂污 1 +x:1 +放荡不羁 1 +x:1 +糅入 1 +x:1 +逼租 1 +x:1 +梳篦 1 +x:1 +提纲挈领 1 +x:1 +支支吾吾 1 +x:1 +瓜熟蒂落 1 +x:1 +操作 1 +x:1 +盘尼西林 1 +x:1 +光带 1 +x:1 +进行期 1 +x:1 +小舅子 1 +x:1 +回旋曲 1 +x:1 +沙漏 1 +x:1 +马背 1 +x:1 +怪杰 1 +x:1 +大获全胜 1 +x:1 +丰收期 1 +x:1 +碘 42 +x:42 +旅店 1 +x:1 +分动箱 1 +x:1 +长话费 1 +x:1 +童音 1 +x:1 +千军台 1 +x:1 +巨款 1 +x:1 +津美 1 +x:1 +楷范 1 +x:1 +化学 1 +x:1 +聚蚊成雷 1 +x:1 +沙漠 1 +x:1 +伤情 1 +x:1 +无私有弊 1 +x:1 +低压网 1 +x:1 +土温 1 +x:1 +西阳城乡 1 +x:1 +多用型 1 +x:1 +保险带 1 +x:1 +土渠 1 +x:1 +褪尽 1 +x:1 +莫隆 1 +x:1 +温课 1 +x:1 +炼钢炉 1 +x:1 +泛太平洋 1 +x:1 +文艺处 1 +x:1 +描绘 1 +x:1 +荣誉军人 1 +x:1 +柒 2 +x:2 +潜意识 1 +x:1 +绿篱 1 +x:1 +上告信 1 +x:1 +工交司 1 +x:1 +伤悲 1 +x:1 +讲义 1 +x:1 +伤心树 1 +x:1 +公因式 1 +x:1 +成团 1 +x:1 +档 25 +x:25 +国大党 1 +x:1 +吵嚷 1 +x:1 +松烟 1 +x:1 +骄阳似火 1 +x:1 +疯枝 1 +x:1 +西北麓 1 +x:1 +山东省 1 +x:1 +普列茨克 1 +x:1 +讲习 1 +x:1 +超采 1 +x:1 +寥若晨星 1 +x:1 +扶沟 1 +x:1 +燕雀 1 +x:1 +主航道 1 +x:1 +关联度 1 +x:1 +严酷性 1 +x:1 +髋骨 1 +x:1 +犯罪分子 1 +x:1 +浪漫史 1 +x:1 +润湿 1 +x:1 +茔 1 +x:1 +本辑 1 +x:1 +塔伊兹 1 +x:1 +沙源 1 +x:1 +爱恋 1 +x:1 +库存值 1 +x:1 +莫非 1 +x:1 +逃奔 1 +x:1 +沉湖镇 1 +x:1 +洪福齐天 1 +x:1 +县衙 1 +x:1 +蓝色 1 +x:1 +肩 68 +x:68 +煤炭局 1 +x:1 +三放一联 1 +x:1 +天鹅 1 +x:1 +渠网 1 +x:1 +翻阅 1 +x:1 +谶 1 +x:1 +心血管 1 +x:1 +前秦 1 +x:1 +气昂昂 1 +x:1 +声乐家 1 +x:1 +民家 1 +x:1 +桡骨 1 +x:1 +性器官 1 +x:1 +性别比 1 +x:1 +扎根 1 +x:1 +毒魔 1 +x:1 +中医药局 1 +x:1 +纽芬兰 1 +x:1 +高教部 1 +x:1 +险恶 1 +x:1 +马脚 1 +x:1 +太阳系 1 +x:1 +无权无势 1 +x:1 +龛影 1 +x:1 +交融 1 +x:1 +汽车展 1 +x:1 +伤愈 1 +x:1 +哈乙亥村 1 +x:1 +乓乓 1 +x:1 +财经委 1 +x:1 +掠走 1 +x:1 +取景点 1 +x:1 +伤感 1 +x:1 +民宅 1 +x:1 +知名人士 1 +x:1 +甲癣 1 +x:1 +奇景 1 +x:1 +嫁祸 1 +x:1 +冷冻车 1 +x:1 +洋 100 +x:100 +芽孢 1 +x:1 +楠溪江 1 +x:1 +运斤成风 1 +x:1 +塞上 1 +x:1 +愚蠢 1 +x:1 +民舞 1 +x:1 +层见叠出 1 +x:1 +养狐栏 1 +x:1 +厂训 1 +x:1 +胶拍 1 +x:1 +锥齿轮 1 +x:1 +航行 1 +x:1 +束手待毙 1 +x:1 +爱憎分明 1 +x:1 +紫癜 1 +x:1 +尿血 1 +x:1 +耶城 1 +x:1 +迷惑 1 +x:1 +平型关 1 +x:1 +台球史 1 +x:1 +流出入 1 +x:1 +六六六 1 +x:1 +牧群 1 +x:1 +圣诞票 1 +x:1 +余生 1 +x:1 +叹惜 1 +x:1 +熄灯号 1 +x:1 +刘源坑 1 +x:1 +阿飞 1 +x:1 +沙湖 1 +x:1 +传颂 1 +x:1 +脑充血 1 +x:1 +软体动物 1 +x:1 +盘据 1 +x:1 +香炉 1 +x:1 +本轮 1 +x:1 +浮财 1 +x:1 +争长论短 1 +x:1 +醇雅 1 +x:1 +述要 1 +x:1 +礼仪卡 1 +x:1 +送奖者 1 +x:1 +冲脉乡 1 +x:1 +早梅 1 +x:1 +牧羊 1 +x:1 +民声 1 +x:1 +禅 5 +x:5 +慢性期 1 +x:1 +干结 1 +x:1 +于无声处 1 +x:1 +祷告厅 1 +x:1 +设置关 1 +x:1 +延伸性 1 +x:1 +6 1471 +x:1471 +池馆台榭 1 +x:1 +造币机 1 +x:1 +碧油油 1 +x:1 +麦蚜虫 1 +x:1 +互帮互利 1 +x:1 +货箱 1 +x:1 +豆腐皮 1 +x:1 +管教所 1 +x:1 +救人者 1 +x:1 +芦山县 1 +x:1 +眼冒金星 1 +x:1 +养牛业 1 +x:1 +荣军院 1 +x:1 +文化展 1 +x:1 +廉洁奉公 1 +x:1 +大窑村 1 +x:1 +接待点 1 +x:1 +黄金村 1 +x:1 +化妆 1 +x:1 +旅居 1 +x:1 +浮躁 1 +x:1 +土法 1 +x:1 +新北乡 1 +x:1 +一丁点儿 1 +x:1 +非暴力 1 +x:1 +淡然 1 +x:1 +太阳翼 1 +x:1 +散文化 1 +x:1 +法规科 1 +x:1 +复仇者 1 +x:1 +奇数 1 +x:1 +揩 4 +x:4 +原素 1 +x:1 +四定两审 1 +x:1 +干线 1 +x:1 +马航 1 +x:1 +主力 1 +x:1 +中医师 1 +x:1 +绰约 1 +x:1 +超霸 1 +x:1 +干红 1 +x:1 +文艺家 1 +x:1 +教育金 1 +x:1 +执法关 1 +x:1 +压缩性 1 +x:1 +破解 1 +x:1 +增高 1 +x:1 +新郎官 1 +x:1 +各持己见 1 +x:1 +社 114 +x:114 +积分表 1 +x:1 +土气 1 +x:1 +聚集一堂 1 +x:1 +饭碗 1 +x:1 +坚劲 1 +x:1 +酿酒业 1 +x:1 +指导奖 1 +x:1 +针棉织品 1 +x:1 +渠系 1 +x:1 +报到处 1 +x:1 +中转站 1 +x:1 +鹿鸣 1 +x:1 +速 44 +x:44 +投食 1 +x:1 +互帮互助 1 +x:1 +文艺学 1 +x:1 +晒 48 +x:48 +两关 1 +x:1 +拍卖款 1 +x:1 +乡村 1 +x:1 +褒者 1 +x:1 +神采飞扬 1 +x:1 +中北镇 1 +x:1 +伦琴射线 1 +x:1 +去污粉 1 +x:1 +沙洲 1 +x:1 +栀子 1 +x:1 +兴安省 1 +x:1 +实力派 1 +x:1 +武戏 1 +x:1 +培训网 1 +x:1 +今生 1 +x:1 +全行 1 +x:1 +危险性 1 +x:1 +同班 1 +x:1 +无所事事 1 +x:1 +沙浆 1 +x:1 +少校 1 +x:1 +休眠 1 +x:1 +文体西村 1 +x:1 +润润 1 +x:1 +比肩 1 +x:1 +机顶盒 1 +x:1 +草原法 1 +x:1 +拭目以待 1 +x:1 +爱美 1 +x:1 +甘孜州 1 +x:1 +勘探系 1 +x:1 +武打 1 +x:1 +临死 1 +x:1 +馄饨 1 +x:1 +甜花 1 +x:1 +迎头痛击 1 +x:1 +扩音声 1 +x:1 +喊声 1 +x:1 +沙浦 1 +x:1 +温觉 1 +x:1 +复种 1 +x:1 +津津有味 1 +x:1 +一得之愚 1 +x:1 +临武 1 +x:1 +盒式 1 +x:1 +土池 1 +x:1 +长发镇 1 +x:1 +男孩梦 1 +x:1 +蠹虫 1 +x:1 +孤儿寡母 1 +x:1 +靖安 1 +x:1 +育人者 1 +x:1 +交心 1 +x:1 +沙沙 1 +x:1 +淡灰 1 +x:1 +接点 1 +x:1 +沙沟 1 +x:1 +成败 1 +x:1 +吉他手 1 +x:1 +汉皇 1 +x:1 +殊不知 1 +x:1 +厮咬 1 +x:1 +民委 1 +x:1 +活性氧 1 +x:1 +代总统 1 +x:1 +罚没 1 +x:1 +弧垂 1 +x:1 +储油区 1 +x:1 +冷冻货 1 +x:1 +淮海 1 +x:1 +教育部 1 +x:1 +复合词 1 +x:1 +政德 1 +x:1 +日臻完美 1 +x:1 +勘探队 1 +x:1 +长岛县 1 +x:1 +令人捧腹 1 +x:1 +糖膏 1 +x:1 +破裂 1 +x:1 +盒底 1 +x:1 +兴安盟 1 +x:1 +枝柯 1 +x:1 +海牛队 1 +x:1 +良知 1 +x:1 +比较法 1 +x:1 +饭票 1 +x:1 +集结地 1 +x:1 +厂区 1 +x:1 +沉思默想 1 +x:1 +绳圈式 1 +x:1 +地产业 1 +x:1 +鳜鱼 1 +x:1 +棒打鸳鸯 1 +x:1 +不动产业 1 +x:1 +辙叉 1 +x:1 +民女 1 +x:1 +中标率 1 +x:1 +甜菜 1 +x:1 +金碧辉煌 1 +x:1 +润泽 1 +x:1 +万寿路 1 +x:1 +牧场主 1 +x:1 +果香 1 +x:1 +骨头架子 1 +x:1 +侨乡 1 +x:1 +自耕农 1 +x:1 +冰风暴 1 +x:1 +穷追猛打 1 +x:1 +至今 1 +x:1 +率尔操觚 1 +x:1 +赤练蛇 1 +x:1 +技压群芳 1 +x:1 +求药者 1 +x:1 +刘源坑村 1 +x:1 +弧圈 1 +x:1 +厂规 1 +x:1 +袋鼠 1 +x:1 +居先 1 +x:1 +命名日 1 +x:1 +赃证 1 +x:1 +管状花 1 +x:1 +犯禁 1 +x:1 +必然性 1 +x:1 +盒带 1 +x:1 +夏庄镇 1 +x:1 +东半球 1 +x:1 +父系 1 +x:1 +本赛 1 +x:1 +健康法 1 +x:1 +售房方 1 +x:1 +检方 1 +x:1 +洋县 1 +x:1 +容错 1 +x:1 +使领馆 1 +x:1 +婴儿期 1 +x:1 +暨 150 +x:150 +弥勒 1 +x:1 +亚细亚 1 +x:1 +管理率 1 +x:1 +总价 1 +x:1 +雷山 1 +x:1 +同舟垂钓 1 +x:1 +工分 1 +x:1 +有机磷 1 +x:1 +封建礼教 1 +x:1 +畅所欲言 1 +x:1 +石锁 1 +x:1 +违心之论 1 +x:1 +敲诈 1 +x:1 +负债表 1 +x:1 +脑瓜子 1 +x:1 +吴岳村 1 +x:1 +疯药 1 +x:1 +红古堡 1 +x:1 +润南 1 +x:1 +掮客 1 +x:1 +刀光剑影 1 +x:1 +节能办 1 +x:1 +卖官鬻爵 1 +x:1 +鸟瞰 1 +x:1 +涿 1 +x:1 +渴 18 +x:18 +沙县 1 +x:1 +成长林 1 +x:1 +政情 1 +x:1 +这样一来 1 +x:1 +制药业 1 +x:1 +水管 1 +x:1 +名篇 1 +x:1 +毫升 1 +x:1 +插花 1 +x:1 +掌舵人 1 +x:1 +危险度 1 +x:1 +化学性质 1 +x:1 +东南亚 1 +x:1 +减产量 1 +x:1 +东郊区 1 +x:1 +限度 1 +x:1 +出面 1 +x:1 +土地权属 1 +x:1 +沙发 1 +x:1 +肉鸽 1 +x:1 +童子鸡 1 +x:1 +沭阳县 1 +x:1 +燃气具 1 +x:1 +润化 1 +x:1 +林化 1 +x:1 +告破 1 +x:1 +碌翁 1 +x:1 +八七年 1 +x:1 +马首是瞻 1 +x:1 +作战处 1 +x:1 +驼 2 +x:2 +半壁河山 1 +x:1 +嵊州 1 +x:1 +大喜过望 1 +x:1 +力帆厂 1 +x:1 +诗论家 1 +x:1 +屠宰场 1 +x:1 +水笔 1 +x:1 +民智 1 +x:1 +沙包 1 +x:1 +塔轮 1 +x:1 +股票机 1 +x:1 +重晶石 1 +x:1 +水笋 1 +x:1 +文峰区 1 +x:1 +毫厘 1 +x:1 +神枪 1 +x:1 +沙化 1 +x:1 +衡南县 1 +x:1 +学问家 1 +x:1 +阪神 1 +x:1 +报到机 1 +x:1 +土制 1 +x:1 +无往不利 1 +x:1 +消炎药 1 +x:1 +发迹 1 +x:1 +病势 1 +x:1 +沙区 1 +x:1 +武将 1 +x:1 +蓬松 1 +x:1 +严以律己 1 +x:1 +武山 1 +x:1 +派系 1 +x:1 +稻谷 1 +x:1 +奇寒 1 +x:1 +晚邮报 1 +x:1 +留者 1 +x:1 +坦克团 1 +x:1 +水筒 1 +x:1 +疏勒河 1 +x:1 +毫发 1 +x:1 +永久性 1 +x:1 +日语科 1 +x:1 +拍卖商 1 +x:1 +左上角 1 +x:1 +临商 1 +x:1 +卵黄 1 +x:1 +绥德 1 +x:1 +酡 1 +x:1 +闲来无事 1 +x:1 +门墙桃李 1 +x:1 +电脑节 1 +x:1 +超需求 1 +x:1 +风土人情 1 +x:1 +证监会 1 +x:1 +飞机库 1 +x:1 +收监 1 +x:1 +石门 1 +x:1 +收盘 1 +x:1 +健康史 1 +x:1 +化机 1 +x:1 +满额 1 +x:1 +招降纳叛 1 +x:1 +膏药 1 +x:1 +工一师 1 +x:1 +水窖 1 +x:1 +酮症 1 +x:1 +两极化 1 +x:1 +间种 1 +x:1 +无所适从 1 +x:1 +类芦 1 +x:1 +竞速赛 1 +x:1 +纺纱 1 +x:1 +淮南 1 +x:1 +大石山 1 +x:1 +扩音机 1 +x:1 +逃散 1 +x:1 +收看 1 +x:1 +夹七夹八 1 +x:1 +椰 2 +x:2 +被选举者 1 +x:1 +太平角 1 +x:1 +病区 1 +x:1 +少城 1 +x:1 +鼓吹 1 +x:1 +活性剂 1 +x:1 +胶带 1 +x:1 +发运 1 +x:1 +主刑 1 +x:1 +拍卖品 1 +x:1 +纺绸 1 +x:1 +武工 1 +x:1 +接任 1 +x:1 +灭鼠药 1 +x:1 +淮北 1 +x:1 +千丝万缕 1 +x:1 +大石庙镇 1 +x:1 +胶布 1 +x:1 +间离 1 +x:1 +芥末 1 +x:1 +水竹 1 +x:1 +哲学系 1 +x:1 +药害 1 +x:1 +纺织 1 +x:1 +武川 1 +x:1 +土台 1 +x:1 +表演区 1 +x:1 +檩子 1 +x:1 +中后期 1 +x:1 +单双杠 1 +x:1 +病危 1 +x:1 +伏休 1 +x:1 +网市镇 1 +x:1 +止疼除痹 1 +x:1 +构 8 +x:8 +机电井 1 +x:1 +戏曲化 1 +x:1 +病历 1 +x:1 +脑门子 1 +x:1 +管制署 1 +x:1 +非功利性 1 +x:1 +病原 1 +x:1 +罚则 1 +x:1 +雁翅镇 1 +x:1 +包赔 1 +x:1 +吗啡样 1 +x:1 +榨季 1 +x:1 +土包 1 +x:1 +靠边 1 +x:1 +思潮起伏 1 +x:1 +总体 1 +x:1 +蹄灯 1 +x:1 +注册处 1 +x:1 +垤 1 +x:1 +农家娃 1 +x:1 +梵蒂冈 1 +x:1 +荆门市 1 +x:1 +民权 1 +x:1 +谈兴未尽 1 +x:1 +土匪 1 +x:1 +辕门 1 +x:1 +文教星 1 +x:1 +目不识丁 1 +x:1 +挂果率 1 +x:1 +影片儿 1 +x:1 +抗病 1 +x:1 +病友 1 +x:1 +民机 1 +x:1 +邯大西街 1 +x:1 +漫画 1 +x:1 +苏轼 1 +x:1 +病变 1 +x:1 +胎儿 1 +x:1 +写真帖 1 +x:1 +石铁 1 +x:1 +民本 1 +x:1 +港航 1 +x:1 +黄金壳 1 +x:1 +病句 1 +x:1 +切莫 1 +x:1 +显示图 1 +x:1 +合作社 1 +x:1 +靠近 1 +x:1 +胶底 1 +x:1 +石铭 1 +x:1 +女扮男装 1 +x:1 +填空 1 +x:1 +病号 1 +x:1 +暗记儿 1 +x:1 +病史 1 +x:1 +免疫性 1 +x:1 +燃气化 1 +x:1 +任职期 1 +x:1 +弥漫 1 +x:1 +七百乡 1 +x:1 +乡寨 1 +x:1 +武术队 1 +x:1 +落后者 1 +x:1 +同伴 1 +x:1 +粤语 1 +x:1 +二锅头 1 +x:1 +存栏量 1 +x:1 +含碳量 1 +x:1 +光量子 1 +x:1 +矮个儿 1 +x:1 +拓垦 1 +x:1 +巴西利亚 1 +x:1 +升旗日 1 +x:1 +晶莹明彻 1 +x:1 +武库 1 +x:1 +赞辞 1 +x:1 +胡豆 1 +x:1 +策动 1 +x:1 +武庙 1 +x:1 +十点钟 1 +x:1 +奇大 1 +x:1 +策励 1 +x:1 +涂刷 1 +x:1 +上下议院 1 +x:1 +岐王 1 +x:1 +议决 1 +x:1 +同会 1 +x:1 +砼 4 +x:4 +同伙 1 +x:1 +胎动 1 +x:1 +伙伴儿 1 +x:1 +五黄六月 1 +x:1 +石炭 1 +x:1 +毫克 1 +x:1 +石青 1 +x:1 +武建 1 +x:1 +赊 8 +x:8 +望见 1 +x:1 +质检 1 +x:1 +浩瀚无涯 1 +x:1 +选人 1 +x:1 +消化系统 1 +x:1 +藤黄 1 +x:1 +行政区 1 +x:1 +面制品 1 +x:1 +绒线衫 1 +x:1 +武术院 1 +x:1 +赣东 1 +x:1 +石面 1 +x:1 +热敏性 1 +x:1 +技 22 +x:22 +胶工 1 +x:1 +奇妙 1 +x:1 +交响 1 +x:1 +策划 1 +x:1 +无日无夜 1 +x:1 +老战士 1 +x:1 +恋歌 1 +x:1 +居民 1 +x:1 +草畜 1 +x:1 +出生地 1 +x:1 +加 580 +x:580 +临场 1 +x:1 +青石桥 1 +x:1 +骨囊肿 1 +x:1 +武帝 1 +x:1 +数典忘祖 1 +x:1 +武师 1 +x:1 +不可磨灭 1 +x:1 +胶州 1 +x:1 +告竣 1 +x:1 +水神 1 +x:1 +马蹄铁 1 +x:1 +武平 1 +x:1 +频段 1 +x:1 +密歇根 1 +x:1 +亏欠 1 +x:1 +农家女 1 +x:1 +驴肉 1 +x:1 +法人化 1 +x:1 +借阅处 1 +x:1 +瓤 1 +x:1 +选举 1 +x:1 +土偶 1 +x:1 +优礼有加 1 +x:1 +咄咄逼人 1 +x:1 +邵阳 1 +x:1 +阿拉德 1 +x:1 +乐理 1 +x:1 +马蹄银 1 +x:1 +主导论 1 +x:1 +陌生 1 +x:1 +庆太村 1 +x:1 +东西方 1 +x:1 +武德 1 +x:1 +争 417 +x:417 +怪声 1 +x:1 +水碓 1 +x:1 +分组赛 1 +x:1 +鼓噪 1 +x:1 +生搬硬套 1 +x:1 +亚硝酸盐 1 +x:1 +一山之隔 1 +x:1 +遥遥领先 1 +x:1 +飘飞回荡 1 +x:1 +水碾 1 +x:1 +胶层 1 +x:1 +同一 1 +x:1 +同上 1 +x:1 +石阶 1 +x:1 +石阵 1 +x:1 +水碱 1 +x:1 +病儿 1 +x:1 +日神 1 +x:1 +非教派 1 +x:1 +选修 1 +x:1 +脑勺 1 +x:1 +胎发 1 +x:1 +千秋业 1 +x:1 +同业 1 +x:1 +民族 1 +x:1 +强硬 1 +x:1 +发球法 1 +x:1 +同乡 1 +x:1 +山山岭岭 1 +x:1 +艾佛莱特 1 +x:1 +策反 1 +x:1 +坏人坏事 1 +x:1 +选例 1 +x:1 +俊发飘逸 1 +x:1 +参赛权 1 +x:1 +香气扑鼻 1 +x:1 +心浮 1 +x:1 +艺术部 1 +x:1 +马桑树 1 +x:1 +港股 1 +x:1 +蒲石村 1 +x:1 +戈登堂 1 +x:1 +凝胶体 1 +x:1 +富士通 1 +x:1 +退休者 1 +x:1 +水磨 1 +x:1 +收留 1 +x:1 +未遂案 1 +x:1 +化石 1 +x:1 +关联性 1 +x:1 +桑皮俄沼 1 +x:1 +武强 1 +x:1 +求亲告友 1 +x:1 +达孜县 1 +x:1 +落水者 1 +x:1 +雏儿 1 +x:1 +弓 13 +x:13 +云雾飘渺 1 +x:1 +鞭打 1 +x:1 +一时一刻 1 +x:1 +活血化淤 1 +x:1 +同人 1 +x:1 +强碱 1 +x:1 +西花厅 1 +x:1 +垦拓 1 +x:1 +琥 1 +x:1 +同于 1 +x:1 +准宾语 1 +x:1 +南沙区 1 +x:1 +抉择 1 +x:1 +质问声 1 +x:1 +祖荫 1 +x:1 +等差数列 1 +x:1 +公安部队 1 +x:1 +沽源县 1 +x:1 +病况 1 +x:1 +无核化 1 +x:1 +气哼哼 1 +x:1 +被窃 1 +x:1 +浪漫派 1 +x:1 +油茶树 1 +x:1 +屎壳郎 1 +x:1 +民政 1 +x:1 +台钟 1 +x:1 +背包袱 1 +x:1 +核酸 1 +x:1 +才分 1 +x:1 +金黄色 1 +x:1 +奠基 1 +x:1 +条法司 1 +x:1 +金盆盆 1 +x:1 +正当时 1 +x:1 +被窝 1 +x:1 +哈达 1 +x:1 +奖金 1 +x:1 +挤挤挨挨 1 +x:1 +浇铸 1 +x:1 +移山倒海 1 +x:1 +政指 1 +x:1 +法人制 1 +x:1 +久治不愈 1 +x:1 +常年累月 1 +x:1 +伤心地 1 +x:1 +热振寺 1 +x:1 +杭二棉 1 +x:1 +宁城 1 +x:1 +歌乐山 1 +x:1 +钋 2 +x:2 +实力型 1 +x:1 +兄嫂 1 +x:1 +麻烦事 1 +x:1 +空间点阵 1 +x:1 +奇异 1 +x:1 +暗 64 +x:64 +稚气未脱 1 +x:1 +毛纺业 1 +x:1 +耘 2 +x:2 +沙垒 1 +x:1 +人头马 1 +x:1 +聪明一世 1 +x:1 +团长 1 +x:1 +滨江道 1 +x:1 +借方 1 +x:1 +地产界 1 +x:1 +冲压线 1 +x:1 +屠宰厂 1 +x:1 +嚷 11 +x:11 +洋坪 1 +x:1 +花灯戏 1 +x:1 +新增额 1 +x:1 +棉纺业 1 +x:1 +油花花 1 +x:1 +中和西乡 1 +x:1 +投影仪 1 +x:1 +渔池村 1 +x:1 +台钳 1 +x:1 +单双打 1 +x:1 +三总部 1 +x:1 +产销合同 1 +x:1 +床位 1 +x:1 +茂南区 1 +x:1 +泥腿子 1 +x:1 +手札 1 +x:1 +行书体 1 +x:1 +兵役法 1 +x:1 +武士 1 +x:1 +军调部 1 +x:1 +那霸港 1 +x:1 +胡言 1 +x:1 +扶持金 1 +x:1 +化控 1 +x:1 +分析语 1 +x:1 +帮贫助困 1 +x:1 +轻柔 1 +x:1 +大通铺式 1 +x:1 +齐奏 1 +x:1 +弄弄坪 1 +x:1 +一腔热血 1 +x:1 +壮劳力 1 +x:1 +台钻 1 +x:1 +抗灾 1 +x:1 +岳阳市 1 +x:1 +教义 1 +x:1 +澧县 1 +x:1 +团伙化 1 +x:1 +沙土 1 +x:1 +不辞而别 1 +x:1 +陈述句 1 +x:1 +三纲五常 1 +x:1 +日经 1 +x:1 +赫鸠 1 +x:1 +假药案 1 +x:1 +水缸 1 +x:1 +言而无信 1 +x:1 +核阅 1 +x:1 +借支 1 +x:1 +觉悟社 1 +x:1 +沙场 1 +x:1 +查询网 1 +x:1 +分辨力 1 +x:1 +杨树浦 1 +x:1 +沙地 1 +x:1 +资料馆 1 +x:1 +冥顽不灵 1 +x:1 +恃 1 +x:1 +冥思苦索 1 +x:1 +小提琴手 1 +x:1 +音区 1 +x:1 +捍 1 +x:1 +戴胸签者 1 +x:1 +水罐 1 +x:1 +水网 1 +x:1 +忒 4 +x:4 +曼妙弦音 1 +x:1 +沙坑 1 +x:1 +借故 1 +x:1 +沙坪 1 +x:1 +抗热 1 +x:1 +绥宁 1 +x:1 +病因 1 +x:1 +电力线 1 +x:1 +差转站 1 +x:1 +教主 1 +x:1 +伯尔尼 1 +x:1 +甲信 1 +x:1 +功绩 1 +x:1 +时装节 1 +x:1 +挽力 1 +x:1 +怪异 1 +x:1 +旁压力 1 +x:1 +─ 1 +x:1 +渥太华 1 +x:1 +自传式 1 +x:1 +疑窦 1 +x:1 +区内外 1 +x:1 +河网化 1 +x:1 +能人 1 +x:1 +一怒而去 1 +x:1 +悄悄 1 +x:1 +蜂拥而至 1 +x:1 +鸡血石 1 +x:1 +哈瓦那 1 +x:1 +正面图 1 +x:1 +地区级 1 +x:1 +电力网 1 +x:1 +猫儿山巅 1 +x:1 +水线 1 +x:1 +齐天 1 +x:1 +佯动 1 +x:1 +野景 1 +x:1 +盘龙江 1 +x:1 +千辛万苦 1 +x:1 +鼓号队 1 +x:1 +拿破仑 1 +x:1 +舍我其谁 1 +x:1 +水红 1 +x:1 +甲骨文 1 +x:1 +表舅 1 +x:1 +大柳树 1 +x:1 +点头哈腰 1 +x:1 +网络版 1 +x:1 +抑制 1 +x:1 +石道 1 +x:1 +哲理性 1 +x:1 +武姿 1 +x:1 +仇视 1 +x:1 +不惜工本 1 +x:1 +坚持不渝 1 +x:1 +孙膑 1 +x:1 +玉版宣 1 +x:1 +草灰 1 +x:1 +照相点 1 +x:1 +黄金屋 1 +x:1 +健康器 1 +x:1 +武委 1 +x:1 +黄金山 1 +x:1 +今人 1 +x:1 +表兄弟 1 +x:1 +善与人同 1 +x:1 +伤处 1 +x:1 +水绵 1 +x:1 +奇幻 1 +x:1 +成衣法 1 +x:1 +法籍 1 +x:1 +功罪 1 +x:1 +榫头 1 +x:1 +埃米尔 1 +x:1 +萁 1 +x:1 +久经考验 1 +x:1 +伙伴国 1 +x:1 +武夷 1 +x:1 +证券课 1 +x:1 +观光 1 +x:1 +少卿 1 +x:1 +派驻 1 +x:1 +胡说 1 +x:1 +武大 1 +x:1 +教体 1 +x:1 +流动站 1 +x:1 +县区 1 +x:1 +基价 1 +x:1 +安德鲁斯 1 +x:1 +政教 1 +x:1 +收率 1 +x:1 +胡诌 1 +x:1 +土地 1 +x:1 +诉 39 +x:39 +面套 1 +x:1 +甲亢 1 +x:1 +武备 1 +x:1 +网络状 1 +x:1 +出鞘 1 +x:1 +胡话 1 +x:1 +大骨节病 1 +x:1 +土坟 1 +x:1 +银武威 1 +x:1 +危害性 1 +x:1 +法系 1 +x:1 +土块 1 +x:1 +今世 1 +x:1 +土坑 1 +x:1 +天冬草 1 +x:1 +化成 1 +x:1 +土坎 1 +x:1 +草原 1 +x:1 +教会 1 +x:1 +盘子 1 +x:1 +任人唯亲 1 +x:1 +踌躇不前 1 +x:1 +艺术院 1 +x:1 +翻越 1 +x:1 +检察署 1 +x:1 +土坯 1 +x:1 +府芒市 1 +x:1 +土坪 1 +x:1 +专题会 1 +x:1 +省市长 1 +x:1 +民主革命 1 +x:1 +土坡 1 +x:1 +瑞香 1 +x:1 +尤卡坦 1 +x:1 +郭庄 1 +x:1 +奇崛 1 +x:1 +沙善 1 +x:1 +寸寸 1 +x:1 +畹町 1 +x:1 +同方向 1 +x:1 +珥陵 1 +x:1 +展容 1 +x:1 +连枷 1 +x:1 +一睹为快 1 +x:1 +关联方 1 +x:1 +日籍 1 +x:1 +临县 1 +x:1 +宽利队 1 +x:1 +等级分 1 +x:1 +被罩 1 +x:1 +上压力 1 +x:1 +梁平县 1 +x:1 +搬 209 +x:209 +项次 1 +x:1 +民情 1 +x:1 +拆迁量 1 +x:1 +久闻大名 1 +x:1 +南拳 1 +x:1 +潘帕斯 1 +x:1 +讨饭贼 1 +x:1 +等积形 1 +x:1 +证券行 1 +x:1 +园区型 1 +x:1 +创三安 1 +x:1 +雌鼠 1 +x:1 +克通社 1 +x:1 +导向管 1 +x:1 +宽容性 1 +x:1 +病员 1 +x:1 +阳刚之气 1 +x:1 +杖 3 +x:3 +逃成 1 +x:1 +乡徽 1 +x:1 +多元论 1 +x:1 +拍卖台 1 +x:1 +观鸟亭 1 +x:1 +复验 1 +x:1 +法罗 1 +x:1 +见所未见 1 +x:1 +绝对湿度 1 +x:1 +丝丝缕缕 1 +x:1 +同化作用 1 +x:1 +台球桌 1 +x:1 +东风区 1 +x:1 +法工委 1 +x:1 +节能器 1 +x:1 +掣动 1 +x:1 +油气区 1 +x:1 +暴露文学 1 +x:1 +主机厂 1 +x:1 +口崇仁路 1 +x:1 +鼓号 1 +x:1 +丘疹 1 +x:1 +吃吃喝喝 1 +x:1 +讲理 1 +x:1 +告终 1 +x:1 +男孩儿 1 +x:1 +潜能值 1 +x:1 +农改办 1 +x:1 +达旗 1 +x:1 +嘉永二年 1 +x:1 +南徐城村 1 +x:1 +康定城 1 +x:1 +碰碰 1 +x:1 +阿根廷湖 1 +x:1 +借机 1 +x:1 +果园镇 1 +x:1 +万宁城 1 +x:1 +下坪村 1 +x:1 +汉传 1 +x:1 +母机 1 +x:1 +转让人 1 +x:1 +爱不释手 1 +x:1 +演替 1 +x:1 +余下 1 +x:1 +娴静 1 +x:1 +细环饼 1 +x:1 +刨花 1 +x:1 +议商 1 +x:1 +轻松 1 +x:1 +倚晴楼 1 +x:1 +庄稼地 1 +x:1 +多类型 1 +x:1 +民怨 1 +x:1 +佣钱 1 +x:1 +天津市 1 +x:1 +五马分尸 1 +x:1 +涪陵市 1 +x:1 +见危授命 1 +x:1 +恭喜发财 1 +x:1 +回款率 1 +x:1 +休会 1 +x:1 +土味 1 +x:1 +得克萨斯 1 +x:1 +刮垢磨光 1 +x:1 +肋间肌 1 +x:1 +玉林井 1 +x:1 +豆腐乳 1 +x:1 +润喉 1 +x:1 +借条 1 +x:1 +光晕 1 +x:1 +倒行逆施 1 +x:1 +综合课 1 +x:1 +羊绒衫 1 +x:1 +阿比林市 1 +x:1 +化妆品 1 +x:1 +呆呆地 1 +x:1 +大块头 1 +x:1 +榫子 1 +x:1 +搂抱 1 +x:1 +水粉 1 +x:1 +告罄 1 +x:1 +综合语 1 +x:1 +天道酬勤 1 +x:1 +咖啡 1 +x:1 +牵制力 1 +x:1 +存款者 1 +x:1 +带 1460 +x:1460 +武官 1 +x:1 +轰隆隆 1 +x:1 +修械所 1 +x:1 +发送机 1 +x:1 +尔后 1 +x:1 +规律性 1 +x:1 +侦查员 1 +x:1 +武安 1 +x:1 +政柄 1 +x:1 +出敌不意 1 +x:1 +得过且过 1 +x:1 +腰鼓 1 +x:1 +不过如此 1 +x:1 +老派 1 +x:1 +彻底性 1 +x:1 +明眸皓齿 1 +x:1 +沙哑 1 +x:1 +净度 1 +x:1 +娴雅 1 +x:1 +坦克兵 1 +x:1 +扎制 1 +x:1 +噩梦 1 +x:1 +温恭谦和 1 +x:1 +水系 1 +x:1 +告缺 1 +x:1 +荣辱与共 1 +x:1 +文艺报 1 +x:1 +漳州市 1 +x:1 +公公正正 1 +x:1 +兄妹 1 +x:1 +雌鸟 1 +x:1 +脑袋 1 +x:1 +下行线 1 +x:1 +敷衍 1 +x:1 +少共 1 +x:1 +法线 1 +x:1 +保护鸟 1 +x:1 +贵宾车 1 +x:1 +斗牛舞 1 +x:1 +彩印 1 +x:1 +彩卷 1 +x:1 +临刑 1 +x:1 +主文 1 +x:1 +二进宫 1 +x:1 +法纪 1 +x:1 +五湖四海 1 +x:1 +合作网 1 +x:1 +里程碑 1 +x:1 +汉丹 1 +x:1 +雌黄 1 +x:1 +荷兰队 1 +x:1 +漂亮话 1 +x:1 +死脑筋 1 +x:1 +核销 1 +x:1 +照相版 1 +x:1 +科研组 1 +x:1 +激烈 1 +x:1 +月相 1 +x:1 +汉中 1 +x:1 +临别 1 +x:1 +形式美 1 +x:1 +前臂 1 +x:1 +伤寒 1 +x:1 +既来之 1 +x:1 +种子地 1 +x:1 +航运量 1 +x:1 +便宜货 1 +x:1 +鼓劲 1 +x:1 +鼓励 1 +x:1 +少儿 1 +x:1 +议员 1 +x:1 +马蹄金 1 +x:1 +鼓动 1 +x:1 +民愤 1 +x:1 +胖胖 1 +x:1 +士大夫 1 +x:1 +背囊 1 +x:1 +伤害 1 +x:1 +来来往往 1 +x:1 +老实事 1 +x:1 +易水 1 +x:1 +法统 1 +x:1 +醇朴 1 +x:1 +奇峰 1 +x:1 +休业 1 +x:1 +老实人 1 +x:1 +佩罗里纳 1 +x:1 +民愁 1 +x:1 +咖喱 1 +x:1 +后遗症 1 +x:1 +罪案 1 +x:1 +寺庙 1 +x:1 +零 163 +x:163 +特 176 +x:176 +焰火 1 +x:1 +海珍品 1 +x:1 +民意 1 +x:1 +汉书 1 +x:1 +后发优势 1 +x:1 +变更关 1 +x:1 +杰里科 1 +x:1 +坚土流沙 1 +x:1 +逃汇 1 +x:1 +浪漫曲 1 +x:1 +议官 1 +x:1 +议定 1 +x:1 +出阵 1 +x:1 +救护队 1 +x:1 +会 6134 +x:6134 +曝光 1 +x:1 +保安费 1 +x:1 +碴儿 1 +x:1 +粘菌 1 +x:1 +核验 1 +x:1 +合不拢嘴 1 +x:1 +老搭档 1 +x:1 +影戏 1 +x:1 +不锈钢 1 +x:1 +过廊 1 +x:1 +欺世盗名 1 +x:1 +齿唇音 1 +x:1 +花园式 1 +x:1 +整车 1 +x:1 +贿情 1 +x:1 +鸟群 1 +x:1 +两栖动物 1 +x:1 +临川 1 +x:1 +吸隔音 1 +x:1 +弥散 1 +x:1 +命运攸关 1 +x:1 +内侄女 1 +x:1 +信心百倍 1 +x:1 +宋家庄村 1 +x:1 +可用地 1 +x:1 +鸟翅 1 +x:1 +剖面图 1 +x:1 +直供直销 1 +x:1 +胶圈 1 +x:1 +徭役 1 +x:1 +风华正茂 1 +x:1 +满不在乎 1 +x:1 +渺无音信 1 +x:1 +银碟赛 1 +x:1 +矮个子 1 +x:1 +运思精妙 1 +x:1 +生烧 1 +x:1 +资山 1 +x:1 +易爆 1 +x:1 +水珠 1 +x:1 +恐惧 1 +x:1 +煞费心机 1 +x:1 +酸雨 1 +x:1 +表达 1 +x:1 +少年 1 +x:1 +毫安 1 +x:1 +肩胛骨 1 +x:1 +轻描淡写 1 +x:1 +观展 1 +x:1 +疯话 1 +x:1 +收纳 1 +x:1 +酸雾 1 +x:1 +塌腰 1 +x:1 +洙 1 +x:1 +稔熟 1 +x:1 +州人 1 +x:1 +咨 1 +x:1 +奋争 1 +x:1 +讲稿 1 +x:1 +万应锭 1 +x:1 +退休证 1 +x:1 +老毡筒 1 +x:1 +腰部 1 +x:1 +扇动 1 +x:1 +严阵以待 1 +x:1 +宣言 1 +x:1 +院务会 1 +x:1 +表述 1 +x:1 +起拍价 1 +x:1 +天长市 1 +x:1 +郐 1 +x:1 +外包装 1 +x:1 +鬼迷心窍 1 +x:1 +沙子 1 +x:1 +有利于 1 +x:1 +拜 59 +x:59 +改用 1 +x:1 +靖江 1 +x:1 +莲峰乡 1 +x:1 +讲究 1 +x:1 +佳人 1 +x:1 +回光镜 1 +x:1 +辨别 1 +x:1 +欣喜若狂 1 +x:1 +粮食法 1 +x:1 +生灵 1 +x:1 +音叉 1 +x:1 +尽瘁鞠躬 1 +x:1 +护坡墙 1 +x:1 +播散期 1 +x:1 +水獭 1 +x:1 +插言 1 +x:1 +犯人 1 +x:1 +颊上添毫 1 +x:1 +漂移 1 +x:1 +有识之士 1 +x:1 +不动产 1 +x:1 +红岩坡 1 +x:1 +收缴 1 +x:1 +胡蝶 1 +x:1 +恐惧感 1 +x:1 +文艺法 1 +x:1 +紫金锭 1 +x:1 +有苦难言 1 +x:1 +望花 1 +x:1 +酸碱 1 +x:1 +傣家人 1 +x:1 +派生 1 +x:1 +戏曲家 1 +x:1 +插话 1 +x:1 +有效分蘖 1 +x:1 +榨取 1 +x:1 +礁石 1 +x:1 +阳关道 1 +x:1 +傻乎乎 1 +x:1 +玉泉区 1 +x:1 +重水堆型 1 +x:1 +分餐制 1 +x:1 +放贷人 1 +x:1 +收编 1 +x:1 +准迁证 1 +x:1 +偏转 1 +x:1 +聆 3 +x:3 +早就 1 +x:1 +进度表 1 +x:1 +鱼石脂 1 +x:1 +飞机场 1 +x:1 +挫折 1 +x:1 +救难船 1 +x:1 +新城镇 1 +x:1 +历城 1 +x:1 +验收 1 +x:1 +胡蜂 1 +x:1 +病孩 1 +x:1 +格子 1 +x:1 +了不起 1 +x:1 +优缺点 1 +x:1 +收网 1 +x:1 +瑞雪 1 +x:1 +少待 1 +x:1 +篷 3 +x:3 +收罗 1 +x:1 +拴马桩 1 +x:1 +小小说 1 +x:1 +默念 1 +x:1 +日班 1 +x:1 +澄 3 +x:3 +奇功 1 +x:1 +手把手 1 +x:1 +表身 1 +x:1 +电脑课 1 +x:1 +功率 1 +x:1 +宜林则林 1 +x:1 +蜂拥而起 1 +x:1 +摆式列车 1 +x:1 +啼哭 1 +x:1 +无业者 1 +x:1 +病室 1 +x:1 +胶囊 1 +x:1 +台前县 1 +x:1 +发展前途 1 +x:1 +一醉方休 1 +x:1 +病容 1 +x:1 +黑叶猴 1 +x:1 +病家 1 +x:1 +病害 1 +x:1 +弥撒 1 +x:1 +淮安 1 +x:1 +墓中人 1 +x:1 +风鸟 1 +x:1 +保命田 1 +x:1 +曲折性 1 +x:1 +紫微八卦 1 +x:1 +短命 1 +x:1 +水牌 1 +x:1 +古戏楼 1 +x:1 +诗社 1 +x:1 +纸煤儿 1 +x:1 +淘 36 +x:36 +东风岗 1 +x:1 +厮打 1 +x:1 +六角形 1 +x:1 +迥然相异 1 +x:1 +预算表 1 +x:1 +胃下垂 1 +x:1 +多层次性 1 +x:1 +巧夺天工 1 +x:1 +拓展 1 +x:1 +偏远 1 +x:1 +地税征管 1 +x:1 +戏曲学 1 +x:1 +水牢 1 +x:1 +舍不得 1 +x:1 +配合力 1 +x:1 +负责人 1 +x:1 +加气站 1 +x:1 +衣分 1 +x:1 +石鼓 1 +x:1 +大石坝 1 +x:1 +潜伏期 1 +x:1 +昂首 1 +x:1 +毛里求斯 1 +x:1 +躲债 1 +x:1 +悬雍垂 1 +x:1 +采价点 1 +x:1 +鞭毛 1 +x:1 +京昆室 1 +x:1 +民法 1 +x:1 +告特 1 +x:1 +深深浅浅 1 +x:1 +秩序井然 1 +x:1 +乡友 1 +x:1 +危险品 1 +x:1 +逼供 1 +x:1 +大功告成 1 +x:1 +] 8 +x:8 +退职金 1 +x:1 +土石方 1 +x:1 +石鼠 1 +x:1 +镔铁 1 +x:1 +全额票 1 +x:1 +党支书 1 +x:1 +调换者 1 +x:1 +三面红旗 1 +x:1 +破损 1 +x:1 +蕊 3 +x:3 +升温法 1 +x:1 +仕女 1 +x:1 +太平花 1 +x:1 +脱贫记 1 +x:1 +掩饰剂 1 +x:1 +奇兵 1 +x:1 +有错必究 1 +x:1 +肯辛顿宫 1 +x:1 +独苗 1 +x:1 +土壶 1 +x:1 +脑瓜儿 1 +x:1 +出疆棉 1 +x:1 +临快 1 +x:1 +鲜花业 1 +x:1 +鲜花丛 1 +x:1 +异教 1 +x:1 +土壤 1 +x:1 +整财 1 +x:1 +檀 3 +x:3 +三制一体 1 +x:1 +石龟 1 +x:1 +蹄筋 1 +x:1 +有机物 1 +x:1 +叩门声 1 +x:1 +奖励金 1 +x:1 +储藏室 1 +x:1 +藏马 1 +x:1 +要是 1 +x:1 +土堆 1 +x:1 +辛 63 +x:63 +借款 1 +x:1 +心心相连 1 +x:1 +生父 1 +x:1 +脚指头 1 +x:1 +谯 1 +x:1 +亏损 1 +x:1 +储存罐 1 +x:1 +福田乡 1 +x:1 +急中生智 1 +x:1 +西关村 1 +x:1 +嫁人 1 +x:1 +土堡 1 +x:1 +厨房 1 +x:1 +逼使 1 +x:1 +言无二价 1 +x:1 +桑腾 1 +x:1 +日炽 1 +x:1 +褥单 1 +x:1 +人性化 1 +x:1 +武器 1 +x:1 +收储费 1 +x:1 +休工期 1 +x:1 +彩带 1 +x:1 +少少 1 +x:1 +许昌县 1 +x:1 +早籼 1 +x:1 +民气 1 +x:1 +垦殖 1 +x:1 +冤枉事 1 +x:1 +告状 1 +x:1 +双季稻 1 +x:1 +区域游 1 +x:1 +寸土 1 +x:1 +生物 1 +x:1 +少将 1 +x:1 +少尉 1 +x:1 +神奈川县 1 +x:1 +少小 1 +x:1 +彩帆 1 +x:1 +常宁 1 +x:1 +合成词 1 +x:1 +怪僻 1 +x:1 +日照 1 +x:1 +匀速运动 1 +x:1 +师范生 1 +x:1 +小伙子 1 +x:1 +辉耀村 1 +x:1 +临床 1 +x:1 +复音 1 +x:1 +烟墩镇 1 +x:1 +球磨机 1 +x:1 +大肚子 1 +x:1 +八家户村 1 +x:1 +更仆难数 1 +x:1 +病夫 1 +x:1 +损公肥私 1 +x:1 +家败人亡 1 +x:1 +防御区 1 +x:1 +油气库 1 +x:1 +腽肭兽 1 +x:1 +观念 1 +x:1 +杀价 1 +x:1 +聚合性 1 +x:1 +北后 1 +x:1 +去 4092 +x:4092 +医马论典 1 +x:1 +脆亮 1 +x:1 +孙辈 1 +x:1 +嵌刻 1 +x:1 +昆士兰州 1 +x:1 +帝号 1 +x:1 +在劫难逃 1 +x:1 +蹄窝 1 +x:1 +哑铃型 1 +x:1 +锣声 1 +x:1 +照相纸 1 +x:1 +书斋 1 +x:1 +洋琴 1 +x:1 +临建 1 +x:1 +全身 1 +x:1 +胶合 1 +x:1 +简简单单 1 +x:1 +逼仄 1 +x:1 +鼓师 1 +x:1 +说短论长 1 +x:1 +杀人 1 +x:1 +早市 1 +x:1 +宇宙服 1 +x:1 +抽查 1 +x:1 +法典化 1 +x:1 +十三辙 1 +x:1 +临帖 1 +x:1 +武场 1 +x:1 +荷兰盾 1 +x:1 +净流量 1 +x:1 +畏难 1 +x:1 +桥西 1 +x:1 +强点 1 +x:1 +拍卖师 1 +x:1 +小卖部 1 +x:1 +虹鳟鱼 1 +x:1 +七七式 1 +x:1 +登字头儿 1 +x:1 +危言耸听 1 +x:1 +脆丽 1 +x:1 +死也不放 1 +x:1 +噪音源 1 +x:1 +生猪 1 +x:1 +校园网 1 +x:1 +累活 1 +x:1 +紧身衣 1 +x:1 +甘棠镇 1 +x:1 +佛珠 1 +x:1 +简捷 1 +x:1 +附城镇 1 +x:1 +枝头 1 +x:1 +锦标 1 +x:1 +怀疑派 1 +x:1 +枕头顶 1 +x:1 +巴山雨夜 1 +x:1 +鼓座 1 +x:1 +水灾 1 +x:1 +有性杂交 1 +x:1 +配器法 1 +x:1 +强烈 1 +x:1 +水灶 1 +x:1 +武坛 1 +x:1 +颇为 1 +x:1 +豆制品 1 +x:1 +肺水肿 1 +x:1 +水火 1 +x:1 +分类式 1 +x:1 +泥瓦匠 1 +x:1 +由小到大 1 +x:1 +山南头 1 +x:1 +礼尚往来 1 +x:1 +私枪 1 +x:1 +可预防性 1 +x:1 +常导 1 +x:1 +回转仪 1 +x:1 +年间 1 +x:1 +胶印 1 +x:1 +神秘兮兮 1 +x:1 +朋比为奸 1 +x:1 +胶卷 1 +x:1 +喀左县 1 +x:1 +秋收起义 1 +x:1 +吆喝声 1 +x:1 +感天动地 1 +x:1 +政法 1 +x:1 +匪 7 +x:7 +苔藓植物 1 +x:1 +收税 1 +x:1 +胶粘剂 1 +x:1 +旅游 1 +x:1 +康 141 +x:141 +胶南 1 +x:1 +奖励面 1 +x:1 +赔礼道歉 1 +x:1 +恰帕斯州 1 +x:1 +老官堡乡 1 +x:1 +苦辣辛酸 1 +x:1 +暖瓶 1 +x:1 +桥身 1 +x:1 +烈士碑 1 +x:1 +牧主 1 +x:1 +微波灶 1 +x:1 +青 272 +x:272 +寰宇 1 +x:1 +武僧 1 +x:1 +束运线 1 +x:1 +绝路 1 +x:1 +苟 21 +x:21 +汇总表 1 +x:1 +东西欧 1 +x:1 +蒋墅 1 +x:1 +呦鹿 1 +x:1 +修身齐家 1 +x:1 +牧业 1 +x:1 +天福山 1 +x:1 +目不转睛 1 +x:1 +野牛草 1 +x:1 +绥北 1 +x:1 +绥化 1 +x:1 +渝长 1 +x:1 +巴厘纱 1 +x:1 +冒险主义 1 +x:1 +月季花 1 +x:1 +病床 1 +x:1 +表记 1 +x:1 +顿开茅塞 1 +x:1 +石首 1 +x:1 +临夏 1 +x:1 +仇者 1 +x:1 +每家 1 +x:1 +生理 1 +x:1 +土布 1 +x:1 +新月 1 +x:1 +南宁路 1 +x:1 +鸟笼 1 +x:1 +真格的 1 +x:1 +化武 1 +x:1 +日益 1 +x:1 +沙家浜 1 +x:1 +莺啼燕唱 1 +x:1 +临头 1 +x:1 +羽绒衫 1 +x:1 +沙弥 1 +x:1 +酉 1 +x:1 +微波炉 1 +x:1 +市政府 1 +x:1 +越来越 1 +x:1 +桃 18 +x:18 +限制 1 +x:1 +东海路 1 +x:1 +聚伞花序 1 +x:1 +视角篇 1 +x:1 +居所 1 +x:1 +爱心卡 1 +x:1 +拉丁舞 1 +x:1 +事中 1 +x:1 +表语 1 +x:1 +势所必然 1 +x:1 +小儿子 1 +x:1 +恋恋不舍 1 +x:1 +剖面 1 +x:1 +层级 1 +x:1 +西邑乡 1 +x:1 +淡黄 1 +x:1 +们 4891 +x:4891 +盘剥 1 +x:1 +紫毫 1 +x:1 +整训 1 +x:1 +怪圈 1 +x:1 +口角炎 1 +x:1 +螺丝母 1 +x:1 +鸟窝 1 +x:1 +国界线 1 +x:1 +生疑 1 +x:1 +生疏 1 +x:1 +洞开 1 +x:1 +黄洞乡 1 +x:1 +斯人长逝 1 +x:1 +新余市 1 +x:1 +伤兵 1 +x:1 +恬静 1 +x:1 +用劲 1 +x:1 +贼喊捉贼 1 +x:1 +生疼 1 +x:1 +桑蚕 1 +x:1 +马尼拉市 1 +x:1 +咖啡壶 1 +x:1 +塞纳 1 +x:1 +圆凳 1 +x:1 +黑芝麻 1 +x:1 +盘县 1 +x:1 +畏途 1 +x:1 +病弱 1 +x:1 +脆生 1 +x:1 +五·一 1 +x:1 +不辱使命 1 +x:1 +虚张声势 1 +x:1 +腰锅 1 +x:1 +水盆 1 +x:1 +恐怖 1 +x:1 +铈 1 +x:1 +报名费 1 +x:1 +周围神经 1 +x:1 +拍卖声 1 +x:1 +工业级 1 +x:1 +明治神宫 1 +x:1 +恐怕 1 +x:1 +盘古 1 +x:1 +生痰 1 +x:1 +一得之功 1 +x:1 +默对 1 +x:1 +兰亭序 1 +x:1 +肉鳍 1 +x:1 +生生 1 +x:1 +萎缩 1 +x:1 +出展 1 +x:1 +文教卫生 1 +x:1 +萍乡 1 +x:1 +严细 1 +x:1 +满门 1 +x:1 +沙市 1 +x:1 +病征 1 +x:1 +操纵 1 +x:1 +武术馆 1 +x:1 +鼓动性 1 +x:1 +表演队 1 +x:1 +皇太子 1 +x:1 +北周 1 +x:1 +电脑迷 1 +x:1 +规程 1 +x:1 +少子 1 +x:1 +尝试 1 +x:1 +议席 1 +x:1 +捣毁 1 +x:1 +中 26074 +x:26074 +主江堤 1 +x:1 +佛祖像 1 +x:1 +野心勃勃 1 +x:1 +青石板 1 +x:1 +架通 1 +x:1 +民歌 1 +x:1 +任用制 1 +x:1 +偏误 1 +x:1 +政派 1 +x:1 +基督徒 1 +x:1 +化妆师 1 +x:1 +项桥 1 +x:1 +彩头 1 +x:1 +生畏 1 +x:1 +脱钩 1 +x:1 +分立 1 +x:1 +危险区 1 +x:1 +强直 1 +x:1 +音势 1 +x:1 +塌落 1 +x:1 +眼见得 1 +x:1 +操练 1 +x:1 +蒸发量 1 +x:1 +宴 13 +x:13 +吵架 1 +x:1 +脱贫率 1 +x:1 +股票数 1 +x:1 +南方 1 +x:1 +强盛 1 +x:1 +街谈巷议 1 +x:1 +强盗 1 +x:1 +金茶花 1 +x:1 +法眼 1 +x:1 +看不顺眼 1 +x:1 +拓宽 1 +x:1 +涂布 1 +x:1 +土岗 1 +x:1 +立党为公 1 +x:1 +寺坡 1 +x:1 +文山会海 1 +x:1 +揪人心肺 1 +x:1 +策应 1 +x:1 +趴下 1 +x:1 +黑色化 1 +x:1 +临安 1 +x:1 +一语惊人 1 +x:1 +硕儒 1 +x:1 +悟 23 +x:23 +少壮 1 +x:1 +告白 1 +x:1 +出院者 1 +x:1 +稻苗 1 +x:1 +土岸 1 +x:1 +区别 1 +x:1 +抚恤金 1 +x:1 +雄鸟 1 +x:1 +水疱 1 +x:1 +主讲人 1 +x:1 +炉 21 +x:21 +治体 1 +x:1 +临客 1 +x:1 +稻花 1 +x:1 +举棋不定 1 +x:1 +水痘 1 +x:1 +揉 16 +x:16 +退休费 1 +x:1 +王侯 1 +x:1 +各家各户 1 +x:1 +贵港市 1 +x:1 +胡家滩 1 +x:1 +爸爸日 1 +x:1 +庞贝城 1 +x:1 +石魂 1 +x:1 +海军呢 1 +x:1 +干事 1 +x:1 +井湾子 1 +x:1 +中上层 1 +x:1 +干亲 1 +x:1 +叩 11 +x:11 +化学地雷 1 +x:1 +淘汰率 1 +x:1 +脑膜 1 +x:1 +起居室 1 +x:1 +粉碎法 1 +x:1 +你报 1 +x:1 +钟鼎文 1 +x:1 +预防费 1 +x:1 +水生 1 +x:1 +大石队 1 +x:1 +液相 1 +x:1 +港资 1 +x:1 +新板 1 +x:1 +百色市 1 +x:1 +莞 4 +x:4 +牌坊店 1 +x:1 +波斯湾 1 +x:1 +国子监 1 +x:1 +水电 1 +x:1 +柱花草 1 +x:1 +水田 1 +x:1 +招摇过市 1 +x:1 +实践 1 +x:1 +故伎重演 1 +x:1 +若干 1 +x:1 +偏袒 1 +x:1 +南天竹 1 +x:1 +层系 1 +x:1 +亏本 1 +x:1 +勃李乡 1 +x:1 +嘉兴市 1 +x:1 +青山绿水 1 +x:1 +伤势 1 +x:1 +水界 1 +x:1 +土屋 1 +x:1 +武剧 1 +x:1 +表解 1 +x:1 +土层 1 +x:1 +元宝枫 1 +x:1 +嵊县 1 +x:1 +亏月 1 +x:1 +文身 1 +x:1 +靠背 1 +x:1 +江东路 1 +x:1 +早安 1 +x:1 +爱侣 1 +x:1 +软饮料 1 +x:1 +吴桥县 1 +x:1 +籟传十 1 +x:1 +扎实 1 +x:1 +任用关 1 +x:1 +刻度尺 1 +x:1 +乡土 1 +x:1 +托塔尔 1 +x:1 +佛学院 1 +x:1 +农救会 1 +x:1 +昆 179 +x:179 +锰矿砂 1 +x:1 +馏 1 +x:1 +盘内 1 +x:1 +酸酸 1 +x:1 +孙八案 1 +x:1 +秀才人情 1 +x:1 +遗弃案 1 +x:1 +观察 1 +x:1 +最新型 1 +x:1 +早婚 1 +x:1 +沙岭 1 +x:1 +各向异性 1 +x:1 +勤政廉政 1 +x:1 +榫卯 1 +x:1 +綦江 1 +x:1 +四邻八村 1 +x:1 +钟塔 1 +x:1 +邓州市 1 +x:1 +酸中毒 1 +x:1 +功用 1 +x:1 +鹦哥绿 1 +x:1 +酸酐 1 +x:1 +所说 1 +x:1 +老态龙钟 1 +x:1 +插足 1 +x:1 +褒奖 1 +x:1 +脓水 1 +x:1 +电脑费 1 +x:1 +表表 1 +x:1 +入托 1 +x:1 +田纳西 1 +x:1 +瑞郎 1 +x:1 +闻者足戒 1 +x:1 +抢购一空 1 +x:1 +兖州 1 +x:1 +类风湿性 1 +x:1 +摩擦音 1 +x:1 +掩耳盗铃 1 +x:1 +钩心斗角 1 +x:1 +偏襟 1 +x:1 +机械化 1 +x:1 +少妇 1 +x:1 +石马 1 +x:1 +美色关 1 +x:1 +沙峰 1 +x:1 +土工 1 +x:1 +水瓢 1 +x:1 +万宁市 1 +x:1 +树大招风 1 +x:1 +少女 1 +x:1 +山羊皮 1 +x:1 +采石场 1 +x:1 +伤口 1 +x:1 +怪味 1 +x:1 +沙尘 1 +x:1 +鬼剃头 1 +x:1 +否决权 1 +x:1 +烧火棍 1 +x:1 +洗漱间 1 +x:1 +伤号 1 +x:1 +保护阀 1 +x:1 +整装 1 +x:1 +水球 1 +x:1 +分类学 1 +x:1 +雌雄 1 +x:1 +林农 1 +x:1 +净资产 1 +x:1 +邓州府 1 +x:1 +雪车 1 +x:1 +龙须面 1 +x:1 +奠定 1 +x:1 +告知 1 +x:1 +稻草 1 +x:1 +迫击炮 1 +x:1 +干休 1 +x:1 +容器厂 1 +x:1 +黄铜矿 1 +x:1 +罪恶 1 +x:1 +沙层 1 +x:1 +法盲 1 +x:1 +越野 1 +x:1 +拉西乡 1 +x:1 +老糊涂 1 +x:1 +默契 1 +x:1 +常规岛 1 +x:1 +杂交 1 +x:1 +翠 16 +x:16 +窜扰 1 +x:1 +啧 1 +x:1 +武南 1 +x:1 +四流中路 1 +x:1 +欲擒故纵 1 +x:1 +爱人 1 +x:1 +偏见 1 +x:1 +妖精 1 +x:1 +沙山 1 +x:1 +王业 1 +x:1 +武协 1 +x:1 +乐曲 1 +x:1 +限价 1 +x:1 +凤梨 1 +x:1 +下坡处 1 +x:1 +表露 1 +x:1 +凤梧 1 +x:1 +枢机主教 1 +x:1 +天老儿 1 +x:1 +萝卜花 1 +x:1 +畹町桥 1 +x:1 +限令 1 +x:1 +他处 1 +x:1 +西胡同村 1 +x:1 +操持 1 +x:1 +鸟龙 1 +x:1 +人名册 1 +x:1 +接待 1 +x:1 +谨 41 +x:41 +内服药 1 +x:1 +返修率 1 +x:1 +满都海 1 +x:1 +杂八 1 +x:1 +周转量 1 +x:1 +胶体 1 +x:1 +鸟枪 1 +x:1 +满街 1 +x:1 +憨外秀中 1 +x:1 +民益 1 +x:1 +功模 1 +x:1 +王冠 1 +x:1 +坡度 1 +x:1 +非图书 1 +x:1 +汉姓 1 +x:1 +床子 1 +x:1 +解脱 1 +x:1 +石蕊 1 +x:1 +水母 1 +x:1 +灼人心扉 1 +x:1 +乔 390 +x:390 +散落 1 +x:1 +旋转体 1 +x:1 +琼剧院 1 +x:1 +常熟市 1 +x:1 +重叠 1 +x:1 +呼救声 1 +x:1 +水毁 1 +x:1 +背包 1 +x:1 +总店 1 +x:1 +今宵 1 +x:1 +啮 1 +x:1 +去污剂 1 +x:1 +淳熙六年 1 +x:1 +伏帖 1 +x:1 +獠牙 1 +x:1 +掘土机 1 +x:1 +精致化 1 +x:1 +文艺界 1 +x:1 +王八 1 +x:1 +聘书 1 +x:1 +长汀县 1 +x:1 +生树 1 +x:1 +排量 1 +x:1 +备勤组 1 +x:1 +外国语 1 +x:1 +辞典 1 +x:1 +送货上门 1 +x:1 +哄 23 +x:23 +汉诺威市 1 +x:1 +甑子 1 +x:1 +投书 1 +x:1 +殉国 1 +x:1 +生根 1 +x:1 +盘中 1 +x:1 +去污力 1 +x:1 +材料科 1 +x:1 +腾越 1 +x:1 +存乎一心 1 +x:1 +不可逆转 1 +x:1 +淡忘 1 +x:1 +牵引性 1 +x:1 +繁分数 1 +x:1 +怒冲冲 1 +x:1 +犯困 1 +x:1 +戏剧者 1 +x:1 +机内码 1 +x:1 +郧阳 1 +x:1 +验钞器 1 +x:1 +字斟句酌 1 +x:1 +民瘼 1 +x:1 +饭囊 1 +x:1 +品种性 1 +x:1 +试错性 1 +x:1 +螺丝刀 1 +x:1 +脂肪 1 +x:1 +怎么 1 +x:1 +汉奸 1 +x:1 +复调 1 +x:1 +饭团 1 +x:1 +太阳光 1 +x:1 +发行 1 +x:1 +扩张主义 1 +x:1 +孑孓 1 +x:1 +总师 1 +x:1 +能屈能伸 1 +x:1 +太阳党 1 +x:1 +新石器 1 +x:1 +投票者 1 +x:1 +法核 1 +x:1 +强横 1 +x:1 +常沅 1 +x:1 +汉墓 1 +x:1 +爱滋病 1 +x:1 +胶乳 1 +x:1 +干净 1 +x:1 +大兴岛 1 +x:1 +讲授 1 +x:1 +亚二局 1 +x:1 +梦想成真 1 +x:1 +十二属相 1 +x:1 +发球线 1 +x:1 +醉马草 1 +x:1 +背地里 1 +x:1 +教导 1 +x:1 +戒骄戒躁 1 +x:1 +接应 1 +x:1 +逼和 1 +x:1 +绥中 1 +x:1 +收条 1 +x:1 +蛮横无理 1 +x:1 +盅 3 +x:3 +下半年 1 +x:1 +低沉 1 +x:1 +王储 1 +x:1 +牧区 1 +x:1 +库里村 1 +x:1 +石灰质 1 +x:1 +教官 1 +x:1 +金本位 1 +x:1 +逃生 1 +x:1 +橘子洲 1 +x:1 +胶丸 1 +x:1 +韩商 1 +x:1 +雨后春笋 1 +x:1 +脆响 1 +x:1 +教宗 1 +x:1 +救护车 1 +x:1 +同居 1 +x:1 +同层 1 +x:1 +减速剂 1 +x:1 +勘验系泊 1 +x:1 +教室 1 +x:1 +乐果 1 +x:1 +义合镇 1 +x:1 +绥东 1 +x:1 +越轨 1 +x:1 +法案 1 +x:1 +采纳率 1 +x:1 +窃玉偷香 1 +x:1 +东海道 1 +x:1 +煤炉子 1 +x:1 +收束 1 +x:1 +作文课 1 +x:1 +瞄 5 +x:5 +石蒜 1 +x:1 +三季度 1 +x:1 +复起 1 +x:1 +之乎者也 1 +x:1 +良多 1 +x:1 +教子 1 +x:1 +冀州市 1 +x:1 +教字 1 +x:1 +狗仗人势 1 +x:1 +总归 1 +x:1 +槽 3 +x:3 +慰藉 1 +x:1 +手舞足蹈 1 +x:1 +同岁 1 +x:1 +苏州河 1 +x:1 +矜夸 1 +x:1 +教学 1 +x:1 +呼兰县 1 +x:1 +万锦滩 1 +x:1 +赣州 1 +x:1 +随风而逝 1 +x:1 +汉堡 1 +x:1 +倾箱倒箧 1 +x:1 +藏经洞 1 +x:1 +复赛 1 +x:1 +朱柱 1 +x:1 +雷公 1 +x:1 +撒切尔 1 +x:1 +爱斯基摩 1 +x:1 +上中下游 1 +x:1 +东海郡 1 +x:1 +菌 19 +x:19 +杏 3 +x:3 +光灿灿 1 +x:1 +州城 1 +x:1 +救护连 1 +x:1 +水橇 1 +x:1 +越过 1 +x:1 +山茱萸 1 +x:1 +桂平市 1 +x:1 +唯唯 1 +x:1 +抗日 1 +x:1 +化瘤 1 +x:1 +架豆 1 +x:1 +黑穗病 1 +x:1 +毁容 1 +x:1 +恶霸 1 +x:1 +铮 12 +x:12 +酸辛 1 +x:1 +良好 1 +x:1 +财经界 1 +x:1 +资金卡 1 +x:1 +马仁区 1 +x:1 +寒流 1 +x:1 +余头 1 +x:1 +资力 1 +x:1 +罗氏沼虾 1 +x:1 +武人 1 +x:1 +关停率 1 +x:1 +话匣子 1 +x:1 +正阳 1 +x:1 +太平天国 1 +x:1 +同心同德 1 +x:1 +养虾户 1 +x:1 +刨除 1 +x:1 +爱印 1 +x:1 +教士 1 +x:1 +同异 1 +x:1 +天人合一 1 +x:1 +床头 1 +x:1 +管制法 1 +x:1 +石头寨 1 +x:1 +苏鲁 1 +x:1 +大师赛 1 +x:1 +化痰 1 +x:1 +水榭 1 +x:1 +正负 1 +x:1 +石蜡 1 +x:1 +格 48 +x:48 +挑肥拣瘦 1 +x:1 +养护费 1 +x:1 +伙食费 1 +x:1 +富锦市 1 +x:1 +克拉根福 1 +x:1 +坡岭 1 +x:1 +古北新区 1 +x:1 +呱呱叫 1 +x:1 +招飞 1 +x:1 +断断续续 1 +x:1 +讲情 1 +x:1 +郗 4 +x:4 +核能 1 +x:1 +埙 2 +x:2 +坡岸 1 +x:1 +淘金 1 +x:1 +≠ 1 +x:1 +水槽 1 +x:1 +父兄 1 +x:1 +公民党 1 +x:1 +武 195 +x:195 +十三陵 1 +x:1 +培训司 1 +x:1 +收摊 1 +x:1 +资助 1 +x:1 +形状 1 +x:1 +奋发努力 1 +x:1 +绳 40 +x:40 +总收入 1 +x:1 +吴忠市 1 +x:1 +许家坝区 1 +x:1 +勘探队员 1 +x:1 +电脑部 1 +x:1 +洛社镇 1 +x:1 +尹湾 1 +x:1 +小雨夹雪 1 +x:1 +岳庙 1 +x:1 +五显岗 1 +x:1 +胡思乱想 1 +x:1 +休学 1 +x:1 +石菖蒲 1 +x:1 +退休金 1 +x:1 +协理员 1 +x:1 +系念 1 +x:1 +忧国忧民 1 +x:1 +能够 1 +x:1 +破烂不堪 1 +x:1 +津冀 1 +x:1 +出生入死 1 +x:1 +抗暴 1 +x:1 +杂史 1 +x:1 +霞美镇 1 +x:1 +冲突点 1 +x:1 +今夜 1 +x:1 +影子内阁 1 +x:1 +余威 1 +x:1 +汉子 1 +x:1 +手 937 +x:937 +教堂 1 +x:1 +客商 1 +x:1 +汉字 1 +x:1 +伤亡 1 +x:1 +海月水母 1 +x:1 +武乡 1 +x:1 +今夏 1 +x:1 +非关键 1 +x:1 +厅里 1 +x:1 +照相机 1 +x:1 +湖北队 1 +x:1 +同心 1 +x:1 +胸膜炎 1 +x:1 +化用 1 +x:1 +文教界 1 +x:1 +比萨 1 +x:1 +同志 1 +x:1 +虬劲 1 +x:1 +今天 1 +x:1 +杀场 1 +x:1 +垂钓者 1 +x:1 +基线量 1 +x:1 +是因为 1 +x:1 +汉学 1 +x:1 +狭窄 1 +x:1 +保安队 1 +x:1 +奇花异卉 1 +x:1 +琼海市 1 +x:1 +同病相怜 1 +x:1 +图尔比勒 1 +x:1 +街坊 1 +x:1 +北坡洋县 1 +x:1 +收支 1 +x:1 +武侠 1 +x:1 +提示牌 1 +x:1 +狐蝠 1 +x:1 +复述 1 +x:1 +中兽医 1 +x:1 +立方体 1 +x:1 +余寒 1 +x:1 +教委 1 +x:1 +字头 1 +x:1 +杂剧 1 +x:1 +偏锋 1 +x:1 +绰号 1 +x:1 +年高体衰 1 +x:1 +塑胶带 1 +x:1 +打击乐器 1 +x:1 +复返 1 +x:1 +学龄 1 +x:1 +良宵 1 +x:1 +颁布 1 +x:1 +心怀 1 +x:1 +微贱 1 +x:1 +总产量 1 +x:1 +储油罐 1 +x:1 +同年 1 +x:1 +直爽 1 +x:1 +平板车 1 +x:1 +大提琴 1 +x:1 +宾至如归 1 +x:1 +收效 1 +x:1 +新华门 1 +x:1 +获得性 1 +x:1 +二进位 1 +x:1 +人头费 1 +x:1 +育林费 1 +x:1 +复辟 1 +x:1 +收敛 1 +x:1 +余家 1 +x:1 +同座 1 +x:1 +东坡塔 1 +x:1 +复转 1 +x:1 +嫉妒 1 +x:1 +选录 1 +x:1 +至关紧要 1 +x:1 +力图 1 +x:1 +生肖印 1 +x:1 +紫檀 1 +x:1 +亏空 1 +x:1 +收方 1 +x:1 +望文生义 1 +x:1 +林荫道 1 +x:1 +同庆 1 +x:1 +卡纳塔克 1 +x:1 +汹涌 1 +x:1 +收文 1 +x:1 +水样 1 +x:1 +带动性 1 +x:1 +大麻者 1 +x:1 +城门头 1 +x:1 +表针 1 +x:1 +化合物 1 +x:1 +伤俘 1 +x:1 +教女 1 +x:1 +连成一气 1 +x:1 +目中无人 1 +x:1 +成果率 1 +x:1 +届 4824 +x:4824 +表链 1 +x:1 +七巧板 1 +x:1 +氧化 1 +x:1 +腌 12 +x:12 +灵童 1 +x:1 +中西方 1 +x:1 +街垒 1 +x:1 +名信片 1 +x:1 +棕榈林 1 +x:1 +民用 1 +x:1 +碟子 1 +x:1 +电磁辐射 1 +x:1 +生死 1 +x:1 +杂务 1 +x:1 +甲壳 1 +x:1 +水桶 1 +x:1 +以德报怨 1 +x:1 +农贸市场 1 +x:1 +民生 1 +x:1 +波斯猫 1 +x:1 +如实地 1 +x:1 +教头 1 +x:1 +淡季 1 +x:1 +入海量 1 +x:1 +座标 1 +x:1 +奇伟 1 +x:1 +咄咄 1 +x:1 +非官守 1 +x:1 +联绵字 1 +x:1 +蚕食鲸吞 1 +x:1 +休工 1 +x:1 +铁树开花 1 +x:1 +承印点 1 +x:1 +热流量 1 +x:1 +抗性 1 +x:1 +超国家 1 +x:1 +力所能及 1 +x:1 +生油 1 +x:1 +初犯者 1 +x:1 +领唱者 1 +x:1 +收成 1 +x:1 +嫌疑犯 1 +x:1 +总成绩 1 +x:1 +教廷 1 +x:1 +里昂 1 +x:1 +汉川 1 +x:1 +饭前 1 +x:1 +土卫六 1 +x:1 +桥隧 1 +x:1 +冤屈 1 +x:1 +假冒者 1 +x:1 +纵虎归山 1 +x:1 +膏状 1 +x:1 +茬 34 +x:34 +同好 1 +x:1 +罗定市 1 +x:1 +掏钱 1 +x:1 +掐头去尾 1 +x:1 +双胞胎 1 +x:1 +伊基克 1 +x:1 +干咳 1 +x:1 +日清 1 +x:1 +三顾茅庐 1 +x:1 +东海镇 1 +x:1 +演唱 1 +x:1 +单斜层 1 +x:1 +主因 1 +x:1 +市区 1 +x:1 +岗南乡 1 +x:1 +汽车界 1 +x:1 +日渐 1 +x:1 +划水 1 +x:1 +坐北朝南 1 +x:1 +经典之作 1 +x:1 +毛装 1 +x:1 +检 64 +x:64 +良将 1 +x:1 +杀光 1 +x:1 +范楼村 1 +x:1 +生民 1 +x:1 +石膏 1 +x:1 +潺潺 1 +x:1 +讲明 1 +x:1 +小金洞乡 1 +x:1 += 6 +x:6 +梁子湖畔 1 +x:1 +颇具 1 +x:1 +万顺路 1 +x:1 +保护费 1 +x:1 +法规化 1 +x:1 +杀入 1 +x:1 +铸件 1 +x:1 +生水 1 +x:1 +火车站 1 +x:1 +借用 1 +x:1 +奋力 1 +x:1 +乐手 1 +x:1 +关税区 1 +x:1 +教师 1 +x:1 +收拢 1 +x:1 +干吗 1 +x:1 +塔什干 1 +x:1 +瓮福 1 +x:1 +病源体 1 +x:1 +寡头政治 1 +x:1 +滁州市 1 +x:1 +五一路 1 +x:1 +鱼龙 1 +x:1 +琉球 1 +x:1 +收拾 1 +x:1 +列车段 1 +x:1 +津城 1 +x:1 +奋勇 1 +x:1 +石臼 1 +x:1 +耳福 1 +x:1 +石山镇 1 +x:1 +插队 1 +x:1 +冰消瓦解 1 +x:1 +纽约州 1 +x:1 +水潭 1 +x:1 +核子武器 1 +x:1 +同姓 1 +x:1 +民爆 1 +x:1 +肉墩墩 1 +x:1 +减速运动 1 +x:1 +使命感 1 +x:1 +出操 1 +x:1 +北海村 1 +x:1 +弗如 1 +x:1 +苯甲酸 1 +x:1 +势单力孤 1 +x:1 +桑麻 1 +x:1 +平等互利 1 +x:1 +伏季 1 +x:1 +强渡 1 +x:1 +水源 1 +x:1 +怎 106 +x:106 +兴安岭 1 +x:1 +边境线 1 +x:1 +调压站 1 +x:1 +熊蜂 1 +x:1 +农家人 1 +x:1 +超现实 1 +x:1 +星火村 1 +x:1 +脑髓 1 +x:1 +同堂 1 +x:1 +挖苦 1 +x:1 +痛击 1 +x:1 +废液 1 +x:1 +奇丽 1 +x:1 +揭东县 1 +x:1 +高潮迭起 1 +x:1 +生涯 1 +x:1 +床帮 1 +x:1 +生涩 1 +x:1 +有据可依 1 +x:1 +遗弃物 1 +x:1 +怪人 1 +x:1 +牧地 1 +x:1 +牧场 1 +x:1 +收据 1 +x:1 +私改 1 +x:1 +交通员 1 +x:1 +接待室 1 +x:1 +纸页 1 +x:1 +教徒 1 +x:1 +东乡县 1 +x:1 +皮囊 1 +x:1 +术箩 1 +x:1 +鱼秧 1 +x:1 +水滴 1 +x:1 +固若金汤 1 +x:1 +奇书 1 +x:1 +鬼灵精 1 +x:1 +怪事 1 +x:1 +医学系 1 +x:1 +饭厅 1 +x:1 +杂品 1 +x:1 +曲周县 1 +x:1 +高位池 1 +x:1 +逼债 1 +x:1 +桥面 1 +x:1 +老住户 1 +x:1 +三教九流 1 +x:1 +价钱 1 +x:1 +政略 1 +x:1 +小家碧玉 1 +x:1 +奇事 1 +x:1 +武器库 1 +x:1 +狐臭 1 +x:1 +钻研 1 +x:1 +生活 1 +x:1 +折桂人 1 +x:1 +今年 1 +x:1 +化物 1 +x:1 +煞 26 +x:26 +嘭 4 +x:4 +奇人 1 +x:1 +机耕路 1 +x:1 +马蹄莲 1 +x:1 +政界 1 +x:1 +富水镇 1 +x:1 +石头山 1 +x:1 +炮兵师 1 +x:1 +水温 1 +x:1 +官官相护 1 +x:1 +庞 77 +x:77 +水渠 1 +x:1 +长江口 1 +x:1 +能干 1 +x:1 +长二丙 1 +x:1 +两新两高 1 +x:1 +入不敷出 1 +x:1 +似乎 1 +x:1 +满足 1 +x:1 +四大发明 1 +x:1 +嗖嗖 1 +x:1 +趋光性 1 +x:1 +大礼包 1 +x:1 +希腊字母 1 +x:1 +辞旧迎新 1 +x:1 +伏安 1 +x:1 +亲兄弟 1 +x:1 +王后 1 +x:1 +专题式 1 +x:1 +保安部 1 +x:1 +南大街 1 +x:1 +农家乐 1 +x:1 +二台子乡 1 +x:1 +渭源县 1 +x:1 +营养素 1 +x:1 +医学类 1 +x:1 +裾 1 +x:1 +鸭广梨 1 +x:1 +内 3375 +x:3375 +粘膜 1 +x:1 +输液 1 +x:1 +弧线 1 +x:1 +事情 1 +x:1 +日光能 1 +x:1 +生源 1 +x:1 +自相鱼肉 1 +x:1 +豆腐店 1 +x:1 +洒 84 +x:84 +完成者 1 +x:1 +架设 1 +x:1 +抗战 1 +x:1 +证监委 1 +x:1 +海协会 1 +x:1 +收买 1 +x:1 +李遂 1 +x:1 +断线风筝 1 +x:1 +助理员 1 +x:1 +琬 5 +x:5 +罗定山 1 +x:1 +疯长 1 +x:1 +衍化 1 +x:1 +双柳河 1 +x:1 +乡俗 1 +x:1 +建言献计 1 +x:1 +水涡 1 +x:1 +同学 1 +x:1 +渔捞 1 +x:1 +同季 1 +x:1 +强心剂 1 +x:1 +油墨 1 +x:1 +科学型 1 +x:1 +萧山市 1 +x:1 +收息 1 +x:1 +鸣锣登场 1 +x:1 +塞族 1 +x:1 +外国货 1 +x:1 +私交 1 +x:1 +局部性 1 +x:1 +李逵 1 +x:1 +水淀 1 +x:1 +酸梅汤 1 +x:1 +贡献者 1 +x:1 +侏罗世 1 +x:1 +三纵两横 1 +x:1 +脸膛儿 1 +x:1 +瓮中之鳖 1 +x:1 +太阳城 1 +x:1 +失职 1 +x:1 +水深 1 +x:1 +石药 1 +x:1 +灵霍介 1 +x:1 +水洞 1 +x:1 +同室 1 +x:1 +水泉县 1 +x:1 +面料商 1 +x:1 +良师 1 +x:1 +水洗 1 +x:1 +调和漆 1 +x:1 +私挖滥采 1 +x:1 +负责制 1 +x:1 +新文化 1 +x:1 +源 112 +x:112 +根本法 1 +x:1 +武术节 1 +x:1 +鞍湖镇 1 +x:1 +接头 1 +x:1 +电力法 1 +x:1 +有限公司 1 +x:1 +伊甸园 1 +x:1 +收悉 1 +x:1 +却说 1 +x:1 +悬壁 1 +x:1 +兆位 1 +x:1 +大肠菌 1 +x:1 +南特市 1 +x:1 +敌我矛盾 1 +x:1 +幻想曲 1 +x:1 +保洁费 1 +x:1 +硅谷 1 +x:1 +拘泥 1 +x:1 +余年 1 +x:1 +有惊无险 1 +x:1 +全心全意 1 +x:1 +水浜 1 +x:1 +对应物 1 +x:1 +县属 1 +x:1 +布里斯班 1 +x:1 +满身 1 +x:1 +分外妖娆 1 +x:1 +人文主义 1 +x:1 +雕花竹 1 +x:1 +痛切 1 +x:1 +脓疮 1 +x:1 +测年技术 1 +x:1 +鼓乐喧天 1 +x:1 +储油站 1 +x:1 +表演赛 1 +x:1 +水流 1 +x:1 +乡企 1 +x:1 +可行性 1 +x:1 +织布机 1 +x:1 +逃犯 1 +x:1 +米粽 1 +x:1 +上瘾者 1 +x:1 +快餐店 1 +x:1 +江东门 1 +x:1 +合理合法 1 +x:1 +乐思 1 +x:1 +几经周折 1 +x:1 +姚坪乡 1 +x:1 +种牛 1 +x:1 +表里 1 +x:1 +豆腐干 1 +x:1 +望都县 1 +x:1 +腰身 1 +x:1 +崩裂 1 +x:1 +水沟 1 +x:1 +索桥 1 +x:1 +三机部 1 +x:1 +良径 1 +x:1 +技术界 1 +x:1 +膏 5 +x:5 +参赛费 1 +x:1 +刚强 1 +x:1 +复课 1 +x:1 +满载 1 +x:1 +火车票 1 +x:1 +复评 1 +x:1 +盒盖 1 +x:1 +一尘不染 1 +x:1 +垫 22 +x:22 +教工 1 +x:1 +水河 1 +x:1 +复诊 1 +x:1 +石舫 1 +x:1 +预防针 1 +x:1 +纽约市 1 +x:1 +八月十五 1 +x:1 +隆丰镇 1 +x:1 +选定 1 +x:1 +伏天 1 +x:1 +会试录 1 +x:1 +复训 1 +x:1 +接壤 1 +x:1 +尼龙绳 1 +x:1 +良心 1 +x:1 +包产到户 1 +x:1 +一时之困 1 +x:1 +乡亲 1 +x:1 +水泊 1 +x:1 +宏命令 1 +x:1 +武器展 1 +x:1 +乡人 1 +x:1 +休庭 1 +x:1 +今岁 1 +x:1 +专委会 1 +x:1 +硫酸锌 1 +x:1 +水泽 1 +x:1 +中学组 1 +x:1 +水泻 1 +x:1 +背后 1 +x:1 +石色 1 +x:1 +水泵 1 +x:1 +质子—M 1 +x:1 +强求 1 +x:1 +支援法 1 +x:1 +脑颅 1 +x:1 +自写像 1 +x:1 +见钱眼开 1 +x:1 +水泥 1 +x:1 +水波 1 +x:1 +街区 1 +x:1 +水泡 1 +x:1 +乡乡 1 +x:1 +塔顶 1 +x:1 +水气 1 +x:1 +洋白菜 1 +x:1 +拉巴布 1 +x:1 +生漆 1 +x:1 +警钟常鸣 1 +x:1 +岭叠岭 1 +x:1 +被约见人 1 +x:1 +街口 1 +x:1 +牵引机 1 +x:1 +令人鼓舞 1 +x:1 +爱国 1 +x:1 +叫声 1 +x:1 +堵 102 +x:102 +劫杀案 1 +x:1 +科头乡 1 +x:1 +时断时续 1 +x:1 +赤子之心 1 +x:1 +材料组 1 +x:1 +选学 1 +x:1 +干细胞 1 +x:1 +多难兴邦 1 +x:1 +气缸盖 1 +x:1 +坡头 1 +x:1 +宝塔菜 1 +x:1 +万有引力 1 +x:1 +马歇尔 1 +x:1 +小字辈 1 +x:1 +衣衣不舍 1 +x:1 +供过于求 1 +x:1 +水汽 1 +x:1 +赫赫 1 +x:1 +石英 1 +x:1 +乡上 1 +x:1 +功德碑 1 +x:1 +乐感 1 +x:1 +福田区 1 +x:1 +余弦 1 +x:1 +插销 1 +x:1 +太平鼓 1 +x:1 +批 2513 +x:2513 +接待处 1 +x:1 +乐意 1 +x:1 +水池 1 +x:1 +方形盘 1 +x:1 +传教士 1 +x:1 +中航技 1 +x:1 +旅程 1 +x:1 +水排 1 +x:1 +一通百通 1 +x:1 +烘炉 1 +x:1 +前导 1 +x:1 +疯魔 1 +x:1 +定购价 1 +x:1 +平坝村 1 +x:1 +爱女 1 +x:1 +滔天大罪 1 +x:1 +萨 7 +x:7 +爱好 1 +x:1 +剩余物 1 +x:1 +取用 1 +x:1 +易手 1 +x:1 +羊肠小道 1 +x:1 +石质 1 +x:1 +日托 1 +x:1 +心狠手辣 1 +x:1 +艺术论 1 +x:1 +未成年 1 +x:1 +纳入 1 +x:1 +抑低 1 +x:1 +私 80 +x:80 +烟卷儿 1 +x:1 +魂 71 +x:71 +全貌 1 +x:1 +床单 1 +x:1 +圜丘 1 +x:1 +转让费 1 +x:1 +汽车票 1 +x:1 +战区 1 +x:1 +甲午 1 +x:1 +产妇术 1 +x:1 +日戳 1 +x:1 +王妃 1 +x:1 +温泉水 1 +x:1 +红灯笼 1 +x:1 +教务 1 +x:1 +怀旧感 1 +x:1 +人才出众 1 +x:1 +山东厅 1 +x:1 +肉弹 1 +x:1 +父子 1 +x:1 +弥留 1 +x:1 +刺激性 1 +x:1 +告急 1 +x:1 +艺术课 1 +x:1 +少于 1 +x:1 +惦记 1 +x:1 +稀烂 1 +x:1 +蒸馏水 1 +x:1 +化身 1 +x:1 +州府 1 +x:1 +硅微条 1 +x:1 +陶陶然 1 +x:1 +生怕 1 +x:1 +节俭 1 +x:1 +键入 1 +x:1 +纳凉 1 +x:1 +能匠 1 +x:1 +甲厂 1 +x:1 +首 2500 +x:2500 +哈铁 1 +x:1 +接地 1 +x:1 +生态 1 +x:1 +背对 1 +x:1 +南极 1 +x:1 +有感于此 1 +x:1 +湛江市 1 +x:1 +藤萝 1 +x:1 +生性 1 +x:1 +同喜 1 +x:1 +不索何获 1 +x:1 +面目皆非 1 +x:1 +相接处 1 +x:1 +寂 2 +x:2 +受过 1 +x:1 +瘦骨棱棱 1 +x:1 +榨豆浆机 1 +x:1 +透明性 1 +x:1 +代步器 1 +x:1 +佯作 1 +x:1 +幡然 1 +x:1 +化缘 1 +x:1 +沮丧 1 +x:1 +不正之风 1 +x:1 +族长 1 +x:1 +复萌 1 +x:1 +爱妻 1 +x:1 +基本形 1 +x:1 +叶脉 1 +x:1 +生息 1 +x:1 +静默 1 +x:1 +乐清 1 +x:1 +太太节 1 +x:1 +驴骡 1 +x:1 +较之 1 +x:1 +教友 1 +x:1 +书香人家 1 +x:1 +演示 1 +x:1 +圆形动物 1 +x:1 +快餐具 1 +x:1 +核订 1 +x:1 +不相上下 1 +x:1 +核计 1 +x:1 +逼岸 1 +x:1 +独弦琴 1 +x:1 +容城县 1 +x:1 +满腹 1 +x:1 +成家 1 +x:1 +双轮架车 1 +x:1 +能动 1 +x:1 +猛龙队 1 +x:1 +吞 22 +x:22 +温泉浴 1 +x:1 +涣 1 +x:1 +填报 1 +x:1 +颔首 1 +x:1 +同名 1 +x:1 +丝挂子 1 +x:1 +抗洪 1 +x:1 +能力 1 +x:1 +内江市 1 +x:1 +量才录用 1 +x:1 +央求 1 +x:1 +满腔 1 +x:1 +宜昌县 1 +x:1 +脱贫村 1 +x:1 +展览会 1 +x:1 +后卫线 1 +x:1 +窈窕 1 +x:1 +昨儿 1 +x:1 +风声鹤唳 1 +x:1 +猫耳洞 1 +x:1 +散货 1 +x:1 +武术赛 1 +x:1 +少侠 1 +x:1 +高碑店市 1 +x:1 +无限期 1 +x:1 +良田 1 +x:1 +满脸 1 +x:1 +光荣花 1 +x:1 +干妈 1 +x:1 +杏干 1 +x:1 +周转额 1 +x:1 +相对高度 1 +x:1 +化纤 1 +x:1 +层次 1 +x:1 +强手 1 +x:1 +抗浮 1 +x:1 +二十一日 1 +x:1 +活动分子 1 +x:1 +聚合物 1 +x:1 +碰杯 1 +x:1 +日不暇给 1 +x:1 +核试 1 +x:1 +坡坡 1 +x:1 +犯忌 1 +x:1 +水战 1 +x:1 +游士 1 +x:1 +剂量 1 +x:1 +功德圆满 1 +x:1 +子程序 1 +x:1 +生意 1 +x:1 +余党 1 +x:1 +流云 1 +x:1 +未遂犯 1 +x:1 +滨江路 1 +x:1 +抗涝 1 +x:1 +凶神恶煞 1 +x:1 +拦路虎 1 +x:1 +保护者 1 +x:1 +水房 1 +x:1 +棉纺厂 1 +x:1 +购房量 1 +x:1 +怆然 1 +x:1 +窝窝头 1 +x:1 +陵东乡 1 +x:1 +特立独行 1 +x:1 +再就是 1 +x:1 +坡坎 1 +x:1 +街巷 1 +x:1 +寻死 1 +x:1 +小囊 1 +x:1 +脑际 1 +x:1 +文艺类 1 +x:1 +休假 1 +x:1 +组织关系 1 +x:1 +价额 1 +x:1 +填房 1 +x:1 +强抑 1 +x:1 +管制权 1 +x:1 +政社 1 +x:1 +电化 1 +x:1 +总场 1 +x:1 +接待地 1 +x:1 +武装部 1 +x:1 +坡地 1 +x:1 +水手 1 +x:1 +嗦嗦 1 +x:1 +沪西 1 +x:1 +少掌柜 1 +x:1 +拉萨河 1 +x:1 +叫苦连天 1 +x:1 +万世流芳 1 +x:1 +教区 1 +x:1 +战事 1 +x:1 +因情制宜 1 +x:1 +给排水 1 +x:1 +高效化 1 +x:1 +爱子 1 +x:1 +抗清 1 +x:1 +兴安县 1 +x:1 +爱孙 1 +x:1 +同在 1 +x:1 +变电站 1 +x:1 +犯属 1 +x:1 +硫胺素 1 +x:1 +被捕 1 +x:1 +脑门 1 +x:1 +同场 1 +x:1 +面巾 1 +x:1 +鸭子坝 1 +x:1 +小满 1 +x:1 +九尾狐 1 +x:1 +宣传处 1 +x:1 +岌岌 1 +x:1 +痰迹 1 +x:1 +咔嚓 1 +x:1 +组方 1 +x:1 +沅江市 1 +x:1 +硅肺 1 +x:1 +纳卡 1 +x:1 +飞车走壁 1 +x:1 +不在乎 1 +x:1 +金丝鸟 1 +x:1 +杏城乡 1 +x:1 +街市 1 +x:1 +王室 1 +x:1 +王宫 1 +x:1 +一举两得 1 +x:1 +余力 1 +x:1 +父女 1 +x:1 +王家 1 +x:1 +何许人也 1 +x:1 +忙 390 +x:390 +细察 1 +x:1 +立身处世 1 +x:1 +鼓槌 1 +x:1 +膏粱 1 +x:1 +讲棋 1 +x:1 +酸枣汁 1 +x:1 +腿肚子 1 +x:1 +沈丘县 1 +x:1 +彩云 1 +x:1 +易怒 1 +x:1 +马路新闻 1 +x:1 +苏铁 1 +x:1 +实在论 1 +x:1 +今冬 1 +x:1 +老寨村 1 +x:1 +梁洼镇 1 +x:1 +侃侃而谈 1 +x:1 +提示符 1 +x:1 +总和 1 +x:1 +针脚 1 +x:1 +插页 1 +x:1 +听凭 1 +x:1 +类风湿病 1 +x:1 +蠡园乡 1 +x:1 +拍卖会 1 +x:1 +碰撞 1 +x:1 +中专生 1 +x:1 +生成 1 +x:1 +乐池 1 +x:1 +鞭策 1 +x:1 +收油 1 +x:1 +收治 1 +x:1 +龋齿 1 +x:1 +综合险 1 +x:1 +白苍苍 1 +x:1 +脆弱 1 +x:1 +有案可查 1 +x:1 +接待员 1 +x:1 +心慌 1 +x:1 +平利县 1 +x:1 +原子弹 1 +x:1 +王子 1 +x:1 +绿色化 1 +x:1 +王孙 1 +x:1 +余割 1 +x:1 +间或 1 +x:1 +干娘 1 +x:1 +余切 1 +x:1 +炸毁 1 +x:1 +中转库 1 +x:1 +生手 1 +x:1 +汉华 1 +x:1 +讲桌 1 +x:1 +话里带刺 1 +x:1 +燃气轮机 1 +x:1 +汉语言 1 +x:1 +今儿 1 +x:1 +其它 1 +x:1 +综合队 1 +x:1 +汉印 1 +x:1 +鸟浴 1 +x:1 +区政府 1 +x:1 +杂家 1 +x:1 +单方面 1 +x:1 +乘兴 1 +x:1 +频率 1 +x:1 +剖腹 1 +x:1 +总后 1 +x:1 +谷类作物 1 +x:1 +圆领儿 1 +x:1 +牧女 1 +x:1 +民怨沸腾 1 +x:1 +流动摊 1 +x:1 +光华 1 +x:1 +唯心 1 +x:1 +逃 120 +x:120 +龙须菜 1 +x:1 +痛心 1 +x:1 +漫游费 1 +x:1 +年鉴 1 +x:1 +天目溪 1 +x:1 +临了 1 +x:1 +玛 1 +x:1 +杨树林 1 +x:1 +小手指 1 +x:1 +鼓书 1 +x:1 +丰富性 1 +x:1 +发言 1 +x:1 +拍卖人 1 +x:1 +鼓乐 1 +x:1 +独木赤烈 1 +x:1 +旅社 1 +x:1 +风华绝代 1 +x:1 +深证所 1 +x:1 +脆度 1 +x:1 +痛快 1 +x:1 +临产 1 +x:1 +平地处 1 +x:1 +水患 1 +x:1 +粑粑 1 +x:1 +良友 1 +x:1 +接哨 1 +x:1 +做饭 1 +x:1 +就寝 1 +x:1 +忠告 1 +x:1 +磷火 1 +x:1 +动画片 1 +x:1 +选型 1 +x:1 +冰塔林 1 +x:1 +水情 1 +x:1 +胰液 1 +x:1 +塔钟 1 +x:1 +拍卖价 1 +x:1 +粘胶 1 +x:1 +望都 1 +x:1 +早上 1 +x:1 +青云堂 1 +x:1 +干审 1 +x:1 +间接 1 +x:1 +良史 1 +x:1 +高出一筹 1 +x:1 +接听 1 +x:1 +表演者 1 +x:1 +街心 1 +x:1 +争战 1 +x:1 +拍卖业 1 +x:1 +怒不可遏 1 +x:1 +接吻 1 +x:1 +开关厂 1 +x:1 +选址 1 +x:1 +龙须草 1 +x:1 +就业率 1 +x:1 +强悍 1 +x:1 +身后名 1 +x:1 +施治 1 +x:1 +没完没了 1 +x:1 +齐街镇 1 +x:1 +痛彻 1 +x:1 +适度从紧 1 +x:1 +晶状体 1 +x:1 +威慑力 1 +x:1 +乍浦港 1 +x:1 +头晕目眩 1 +x:1 +良医 1 +x:1 +五一节 1 +x:1 +北城 1 +x:1 +水性 1 +x:1 +屏风 1 +x:1 +教具 1 +x:1 +器背 1 +x:1 +造谣生事 1 +x:1 +观众 1 +x:1 +居留 1 +x:1 +套 881 +x:881 +雌花 1 +x:1 +文教类 1 +x:1 +青贮法 1 +x:1 +为辅 1 +x:1 +早些 1 +x:1 +选场 1 +x:1 +品学兼优 1 +x:1 +镜片 1 +x:1 +保护色 1 +x:1 +汽车站 1 +x:1 +光杆儿 1 +x:1 +熨衣板 1 +x:1 +与人无争 1 +x:1 +台 1276 +x:1276 +考核表 1 +x:1 +扭亏为盈 1 +x:1 +汉剧 1 +x:1 +赞词 1 +x:1 +水果 1 +x:1 +旧州镇 1 +x:1 +湄洲湾 1 +x:1 +被救 1 +x:1 +褂 1 +x:1 +天趣巧成 1 +x:1 +显眼 1 +x:1 +日晷 1 +x:1 +箴言 1 +x:1 +派性 1 +x:1 +甲地 1 +x:1 +土人 1 +x:1 +雌蕊 1 +x:1 +信贷科 1 +x:1 +操演 1 +x:1 +渊薮 1 +x:1 +木雕泥塑 1 +x:1 +水枪 1 +x:1 +日晕 1 +x:1 +亲家母 1 +x:1 +作伪者 1 +x:1 +日晒 1 +x:1 +水柜 1 +x:1 +踏雪寻梅 1 +x:1 +副厂级 1 +x:1 +独立报 1 +x:1 +生擒 1 +x:1 +接口 1 +x:1 +六合县 1 +x:1 +总务 1 +x:1 +日显 1 +x:1 +次级线圈 1 +x:1 +龙游县 1 +x:1 +纳克法 1 +x:1 +接待办 1 +x:1 +石西 1 +x:1 +背弃 1 +x:1 +怜香惜玉 1 +x:1 +慢慢吞吞 1 +x:1 +水柱 1 +x:1 +淡化 1 +x:1 +华灯初上 1 +x:1 +接受 1 +x:1 +同党 1 +x:1 +修车铺 1 +x:1 +牧师 1 +x:1 +法方 1 +x:1 +土丘 1 +x:1 +汉唐 1 +x:1 +鞘翅目 1 +x:1 +达江乡 1 +x:1 +爱鸟周 1 +x:1 +议会 1 +x:1 +黑颈鹤 1 +x:1 +寒热 1 +x:1 +澜 4 +x:4 +禁烟牌 1 +x:1 +多元酸 1 +x:1 +甲型 1 +x:1 +水机 1 +x:1 +刨食 1 +x:1 +复职 1 +x:1 +丰满区 1 +x:1 +散装 1 +x:1 +雷区 1 +x:1 +剑拔弩张 1 +x:1 +爱巢 1 +x:1 +床垫 1 +x:1 +弥足珍贵 1 +x:1 +鼠目寸光 1 +x:1 +到来之际 1 +x:1 +相溶性 1 +x:1 +中学生 1 +x:1 +偏听偏信 1 +x:1 +祖籍 1 +x:1 +胶东区 1 +x:1 +绰尔 1 +x:1 +颂词 1 +x:1 +新名优 1 +x:1 +洗发水 1 +x:1 +菩萨顶 1 +x:1 +名花异草 1 +x:1 +成名成家 1 +x:1 +水杏 1 +x:1 +干将 1 +x:1 +颂诗 1 +x:1 +法旨 1 +x:1 +水杉 1 +x:1 +磷矿 1 +x:1 +淡去 1 +x:1 +万花山 1 +x:1 +磷脂 1 +x:1 +车身险 1 +x:1 +京白 1 +x:1 +功曹 1 +x:1 +螺丝帽 1 +x:1 +颂语 1 +x:1 +总则 1 +x:1 +甲基 1 +x:1 +旧货业 1 +x:1 +文艺社 1 +x:1 +水杯 1 +x:1 +总分 1 +x:1 +水杨 1 +x:1 +父志 1 +x:1 +诺 9 +x:9 +清道夫 1 +x:1 +无线 1 +x:1 +福如东海 1 +x:1 +杂居 1 +x:1 +议事 1 +x:1 +萧条 1 +x:1 +生料 1 +x:1 +水暖 1 +x:1 +遗容 1 +x:1 +罪状 1 +x:1 +良善 1 +x:1 +太平门 1 +x:1 +毫不 1 +x:1 +栎 1 +x:1 +太平间 1 +x:1 +罪犯 1 +x:1 +厉庄镇 1 +x:1 +根本点 1 +x:1 +病休 1 +x:1 +收款 1 +x:1 +玩意儿 1 +x:1 +披头散发 1 +x:1 +畜种 1 +x:1 +牧归 1 +x:1 +会议室 1 +x:1 +日杂 1 +x:1 +总参 1 +x:1 +杀声 1 +x:1 +接办 1 +x:1 +接力 1 +x:1 +心上人 1 +x:1 +间日 1 +x:1 +在所不计 1 +x:1 +太阳岛 1 +x:1 +背带 1 +x:1 +日本 1 +x:1 +纳巴市 1 +x:1 +乐段 1 +x:1 +四合庄 1 +x:1 +民管 1 +x:1 +蓬窗 1 +x:1 +金达莱 1 +x:1 +爱将 1 +x:1 +盐都县 1 +x:1 +炮兵团 1 +x:1 +病体 1 +x:1 +下马威 1 +x:1 +投影城 1 +x:1 +时效处理 1 +x:1 +总厂 1 +x:1 +日期 1 +x:1 +街头 1 +x:1 +合作方 1 +x:1 +扶眉 1 +x:1 +接待厅 1 +x:1 +生日 1 +x:1 +流动房 1 +x:1 +议价 1 +x:1 +讲演 1 +x:1 +水星 1 +x:1 +星城村 1 +x:1 +病例 1 +x:1 +嫁妆 1 +x:1 +莘塍镇 1 +x:1 +被担保人 1 +x:1 +伍员山 1 +x:1 +沙丘 1 +x:1 +教坛 1 +x:1 +街委 1 +x:1 +强暴 1 +x:1 +杀出重围 1 +x:1 +接到 1 +x:1 +气功师 1 +x:1 +太平镇 1 +x:1 +散文热 1 +x:1 +经济学界 1 +x:1 +制药厂 1 +x:1 +箭头 1 +x:1 +缓兵之计 1 +x:1 +功架 1 +x:1 +散见 1 +x:1 +私密性 1 +x:1 +席 149 +x:149 +伐木工 1 +x:1 +柳体 1 +x:1 +收殓 1 +x:1 +阉割 1 +x:1 +酸菜 1 +x:1 +土伦 1 +x:1 +青幽幽 1 +x:1 +报废站 1 +x:1 +乐歌 1 +x:1 +以势压人 1 +x:1 +爱岗 1 +x:1 +汽车系 1 +x:1 +土体 1 +x:1 +发誓 1 +x:1 +东方学家 1 +x:1 +生效 1 +x:1 +一笑置之 1 +x:1 +昏头昏脑 1 +x:1 +团结一心 1 +x:1 +开花期 1 +x:1 +检察权 1 +x:1 +红彤彤 1 +x:1 +痛失 1 +x:1 +艺术科 1 +x:1 +水晶 1 +x:1 +暗乎乎 1 +x:1 +四步曲 1 +x:1 +可比性 1 +x:1 +逃离 1 +x:1 +水景 1 +x:1 +荷兰豆 1 +x:1 +同僚 1 +x:1 +歪歪斜斜 1 +x:1 +饭堂 1 +x:1 +路伊盟 1 +x:1 +石头城 1 +x:1 +赣剧 1 +x:1 +总参谋长 1 +x:1 +翔山 1 +x:1 +法术 1 +x:1 +攒 27 +x:27 +政绩 1 +x:1 +强攻 1 +x:1 +水文 1 +x:1 +填料 1 +x:1 +东瓦 1 +x:1 +枫桥镇 1 +x:1 +复苏 1 +x:1 +赠与 1 +x:1 +整饰 1 +x:1 +同化 1 +x:1 +整饬 1 +x:1 +酸枣树 1 +x:1 +小数点 1 +x:1 +嫁娶 1 +x:1 +填方 1 +x:1 +敲门 1 +x:1 +脑量 1 +x:1 +大兴县 1 +x:1 +讲法 1 +x:1 +赠书 1 +x:1 +秦陵 1 +x:1 +打交道 1 +x:1 +珉 6 +x:6 +政纲 1 +x:1 +扫黄打非 1 +x:1 +金碧路 1 +x:1 +水族 1 +x:1 +政纪 1 +x:1 +汉城 1 +x:1 +胡搅 1 +x:1 +戍边 1 +x:1 +强敌 1 +x:1 +钟意 1 +x:1 +金字塔式 1 +x:1 +雌蜂 1 +x:1 +收案 1 +x:1 +马蹄表 1 +x:1 +载货 1 +x:1 +各取所需 1 +x:1 +水旱 1 +x:1 +杀害 1 +x:1 +家里人 1 +x:1 +佶 1 +x:1 +采通科 1 +x:1 +粮食局 1 +x:1 +妄称 1 +x:1 +翩跹 1 +x:1 +凄美 1 +x:1 +校风 1 +x:1 +塑胶厂 1 +x:1 +近些年 1 +x:1 +颁发 1 +x:1 +教员 1 +x:1 +爱心 1 +x:1 +石头块 1 +x:1 +生意计 1 +x:1 +证券部 1 +x:1 +郭庄村 1 +x:1 +约稿信 1 +x:1 +喑哑 1 +x:1 +水政 1 +x:1 +可的松 1 +x:1 +偏颇 1 +x:1 +赠予 1 +x:1 +题名 1 +x:1 +昂贵 1 +x:1 +中餐 1 +x:1 +书房村 1 +x:1 +法规处 1 +x:1 +偏题 1 +x:1 +生长区 1 +x:1 +汉正街 1 +x:1 +耿 43 +x:43 +一决雌雄 1 +x:1 +对得起 1 +x:1 +笼络人心 1 +x:1 +爱徒 1 +x:1 +呼救器 1 +x:1 +接入 1 +x:1 +独立性 1 +x:1 +阴干 1 +x:1 +总值 1 +x:1 +选刊 1 +x:1 +无公害 1 +x:1 +同台 1 +x:1 +逃窜 1 +x:1 +报 858 +x:858 +大礼堂 1 +x:1 +置备 1 +x:1 +临立会 1 +x:1 +治保 1 +x:1 +新文学 1 +x:1 +捣碎 1 +x:1 +斜切 1 +x:1 +收棉 1 +x:1 +鱼网 1 +x:1 +偏食 1 +x:1 +铜线 1 +x:1 +突眼症 1 +x:1 +演练 1 +x:1 +纽约城 1 +x:1 +人名录 1 +x:1 +增长率 1 +x:1 +层流 1 +x:1 +明镜高悬 1 +x:1 +选取 1 +x:1 +长江头 1 +x:1 +刚直不阿 1 +x:1 +拖拉机 1 +x:1 +脑部 1 +x:1 +伏兵 1 +x:1 +虎虎生威 1 +x:1 +日数 1 +x:1 +功放 1 +x:1 +有志者 1 +x:1 +大锅水 1 +x:1 +保皇党 1 +x:1 +榆叶梅 1 +x:1 +橡皮图章 1 +x:1 +同心同力 1 +x:1 +中子谱 1 +x:1 +赣南 1 +x:1 +苏醒 1 +x:1 +诗界 1 +x:1 +王座 1 +x:1 +眉目 1 +x:1 +尼龙袋 1 +x:1 +灞河滩 1 +x:1 +工期 1 +x:1 +寂寞者 1 +x:1 +豆花儿 1 +x:1 +功效 1 +x:1 +醇美 1 +x:1 +张集 1 +x:1 +以苦为乐 1 +x:1 +叶斑病 1 +x:1 +专利费 1 +x:1 +名垂千古 1 +x:1 +流动性 1 +x:1 +石羊 1 +x:1 +间架 1 +x:1 +恪 1 +x:1 +该局 1 +x:1 +积 127 +x:127 +成熟论 1 +x:1 +硅藻 1 +x:1 +手写体 1 +x:1 +预收费 1 +x:1 +赣北 1 +x:1 +腊质膜 1 +x:1 +王府 1 +x:1 +跳伞塔 1 +x:1 +敏竹寺 1 +x:1 +总兵 1 +x:1 +酸臭 1 +x:1 +日日 1 +x:1 +红外线 1 +x:1 +学有所得 1 +x:1 +整风 1 +x:1 +塌陷 1 +x:1 +牧工 1 +x:1 +能否 1 +x:1 +伏击 1 +x:1 +王年 1 +x:1 +怒目圆睁 1 +x:1 +间杂 1 +x:1 +喜 190 +x:190 +联结端 1 +x:1 +坝顶 1 +x:1 +生机 1 +x:1 +为之动容 1 +x:1 +自流井 1 +x:1 +李大钊 1 +x:1 +一体性 1 +x:1 +随声附和 1 +x:1 +居然 1 +x:1 +存款额 1 +x:1 +炼钢厂 1 +x:1 +路易港 1 +x:1 +抗毁 1 +x:1 +凝聚 1 +x:1 +全景式 1 +x:1 +始祖马 1 +x:1 +州委 1 +x:1 +沙尘暴 1 +x:1 +教唆 1 +x:1 +太阳年 1 +x:1 +碎步子 1 +x:1 +今后 1 +x:1 +良性肿瘤 1 +x:1 +日方 1 +x:1 +硝烟滚滚 1 +x:1 +坚苦卓绝 1 +x:1 +散记 1 +x:1 +不在话下 1 +x:1 +黑糊糊 1 +x:1 +选区 1 +x:1 +动作 1 +x:1 +包扎带 1 +x:1 +战天斗地 1 +x:1 +日文 1 +x:1 +前堂 1 +x:1 +贫民窟 1 +x:1 +核资 1 +x:1 +老少咸宜 1 +x:1 +慢腾腾 1 +x:1 +显像仪 1 +x:1 +赤水河 1 +x:1 +余地 1 +x:1 +生来 1 +x:1 +惠州市 1 +x:1 +日斑 1 +x:1 +街容 1 +x:1 +未曾 1 +x:1 +邮袋 1 +x:1 +建管用 1 +x:1 +跃然纸上 1 +x:1 +掘进史 1 +x:1 +利欲 1 +x:1 +破天荒 1 +x:1 +紧压茶 1 +x:1 +广为流传 1 +x:1 +办公区 1 +x:1 +中上游 1 +x:1 +扶贫点 1 +x:1 +广学博采 1 +x:1 +围追 1 +x:1 +殷殷 1 +x:1 +支链 1 +x:1 +排爆 1 +x:1 +条绒 1 +x:1 +左右开弓 1 +x:1 +假造 1 +x:1 +充气垫 1 +x:1 +精邃 1 +x:1 +面包店 1 +x:1 +广东队 1 +x:1 +西柏林 1 +x:1 +蒙古包 1 +x:1 +食物 1 +x:1 +条约 1 +x:1 +悟偕 1 +x:1 +美艳者 1 +x:1 +线电压 1 +x:1 +修车房 1 +x:1 +加加林 1 +x:1 +过激 1 +x:1 +条纹 1 +x:1 +武清县 1 +x:1 +护肤油 1 +x:1 +武夷宫 1 +x:1 +磨米坊 1 +x:1 +粉碎毛 1 +x:1 +拳击赛 1 +x:1 +扬琴 1 +x:1 +采购员 1 +x:1 +品鉴 1 +x:1 +乘数 1 +x:1 +排版 1 +x:1 +睡乡 1 +x:1 +越瓜 1 +x:1 +通城 1 +x:1 +棒曲霉素 1 +x:1 +桑巴舞 1 +x:1 +贺岁片 1 +x:1 +工艺 1 +x:1 +排犹 1 +x:1 +新喜 1 +x:1 +盘扣服 1 +x:1 +纺织部 1 +x:1 +新喀 1 +x:1 +目不见睫 1 +x:1 +浏阳籍 1 +x:1 +恋家 1 +x:1 +柿子椒 1 +x:1 +年集 1 +x:1 +茶点 1 +x:1 +码头区 1 +x:1 +土霉素 1 +x:1 +辛劳 1 +x:1 +除非 1 +x:1 +面包师 1 +x:1 +一家人 1 +x:1 +办公厅 1 +x:1 +存养 1 +x:1 +岁秩 1 +x:1 +茶炉 1 +x:1 +尽情 1 +x:1 +精选 1 +x:1 +农机系 1 +x:1 +富裕 1 +x:1 +强盗窝 1 +x:1 +培土 1 +x:1 +精透 1 +x:1 +厘米 1 +x:1 +贺年片 1 +x:1 +灌溉区 1 +x:1 +人潮 1 +x:1 +集贸 1 +x:1 +造 198 +x:198 +零基预算 1 +x:1 +洗手 1 +x:1 +乒乓球拍 1 +x:1 +委培生 1 +x:1 +渭源 1 +x:1 +体改委 1 +x:1 +病虫草害 1 +x:1 +透光 1 +x:1 +检测费 1 +x:1 +猎具 1 +x:1 +援手 1 +x:1 +热轧 1 +x:1 +金台路 1 +x:1 +优良率 1 +x:1 +精道 1 +x:1 +四氯化碳 1 +x:1 +山城堡 1 +x:1 +点点滴滴 1 +x:1 +辛勤 1 +x:1 +机会主义 1 +x:1 +俱全 1 +x:1 +染汁 1 +x:1 +银边席 1 +x:1 +踏青节 1 +x:1 +防御战 1 +x:1 +租车费 1 +x:1 +扬长而去 1 +x:1 +多维性 1 +x:1 +眩目 1 +x:1 +康采恩 1 +x:1 +政研处 1 +x:1 +涝河桥村 1 +x:1 +相知 1 +x:1 +审计费 1 +x:1 +龅牙 1 +x:1 +馅儿饼 1 +x:1 +异香 1 +x:1 +空当子 1 +x:1 +受惠额 1 +x:1 +出借方 1 +x:1 +同室操戈 1 +x:1 +热身 1 +x:1 +榄球赛 1 +x:1 +无题 1 +x:1 +娃娃书 1 +x:1 +人源 1 +x:1 +入境者 1 +x:1 +溶剂 1 +x:1 +干预性 1 +x:1 +铜矿村 1 +x:1 +窥寻 1 +x:1 +桃花鱼 1 +x:1 +七八点 1 +x:1 +蘖枝 1 +x:1 +土山村 1 +x:1 +见异思迁 1 +x:1 +未果 1 +x:1 +叙事性 1 +x:1 +袋花 1 +x:1 +透视图 1 +x:1 +套房率 1 +x:1 +澎湃 1 +x:1 +礼林镇 1 +x:1 +厚礼 1 +x:1 +胆管 1 +x:1 +过滤 1 +x:1 +精量 1 +x:1 +尽意 1 +x:1 +早期白话 1 +x:1 +澎湖 1 +x:1 +任命书 1 +x:1 +象征性 1 +x:1 +企求 1 +x:1 +舰队团 1 +x:1 +琉球王国 1 +x:1 +健力宝队 1 +x:1 +瘦子 1 +x:1 +中书舍人 1 +x:1 +亩产量 1 +x:1 +未来 1 +x:1 +社区 1 +x:1 +贻害无穷 1 +x:1 +暴躁 1 +x:1 +厚积 1 +x:1 +新鲜菜 1 +x:1 +无稽之谈 1 +x:1 +骗局 1 +x:1 +森严壁垒 1 +x:1 +术 16 +x:16 +石油界 1 +x:1 +天意 1 +x:1 +费话 1 +x:1 +襟泪 1 +x:1 +过渡 1 +x:1 +大展宏图 1 +x:1 +谋略家 1 +x:1 +重合 1 +x:1 +矮凳 1 +x:1 +渔码头 1 +x:1 +从头到尾 1 +x:1 +美誉 1 +x:1 +下苦功 1 +x:1 +洋洋大观 1 +x:1 +塑 22 +x:22 +灾害性 1 +x:1 +务实性 1 +x:1 +鬼鬼祟祟 1 +x:1 +无须 1 +x:1 +假释 1 +x:1 +蓊郁郁 1 +x:1 +榜样 1 +x:1 +提炼厂 1 +x:1 +寻甸县 1 +x:1 +粘力 1 +x:1 +呕血 1 +x:1 +未有 1 +x:1 +锦州湾 1 +x:1 +返校 1 +x:1 +增产 1 +x:1 +潜绩 1 +x:1 +形神妙肖 1 +x:1 +洪都拉斯 1 +x:1 +太湖石 1 +x:1 +人人自危 1 +x:1 +携带 1 +x:1 +品透 1 +x:1 +海洋馆 1 +x:1 +思来想去 1 +x:1 +韶山 1 +x:1 +鄙吝 1 +x:1 +罗网 1 +x:1 +生理学家 1 +x:1 +情报学 1 +x:1 +骄奢淫逸 1 +x:1 +凤阳县 1 +x:1 +受害人 1 +x:1 +拳谱 1 +x:1 +万贯家财 1 +x:1 +声波 1 +x:1 +买官者 1 +x:1 +竞赛场 1 +x:1 +护法 1 +x:1 +克比里省 1 +x:1 +游牧民 1 +x:1 +求者 1 +x:1 +万箭穿心 1 +x:1 +排灰 1 +x:1 +说情风 1 +x:1 +一言一行 1 +x:1 +泰安市 1 +x:1 +稚气可掬 1 +x:1 +雄心勃勃 1 +x:1 +伤残费 1 +x:1 +护沿 1 +x:1 +廓 1 +x:1 +学历 1 +x:1 +滩海 1 +x:1 +白令海 1 +x:1 +收购点 1 +x:1 +以讹传讹 1 +x:1 +窝囊 1 +x:1 +每每 1 +x:1 +胆碱 1 +x:1 +上移 1 +x:1 +车船税 1 +x:1 +子龟 1 +x:1 +展开 1 +x:1 +渭水 1 +x:1 +碰锁 1 +x:1 +偏护 1 +x:1 +排灌 1 +x:1 +四顾无人 1 +x:1 +神创论 1 +x:1 +猎取 1 +x:1 +手急眼快 1 +x:1 +众所周知 1 +x:1 +检测车 1 +x:1 +雁北 1 +x:1 +芽白 1 +x:1 +地空导弹 1 +x:1 +常规武器 1 +x:1 +滇东 1 +x:1 +每次 1 +x:1 +翠柏 1 +x:1 +笑 373 +x:373 +旗子 1 +x:1 +新型 1 +x:1 +排炮 1 +x:1 +泥石 1 +x:1 +龙头乡 1 +x:1 +建筑学家 1 +x:1 +康家沟 1 +x:1 +顺手 1 +x:1 +聪明人 1 +x:1 +鸽食 1 +x:1 +过活 1 +x:1 +七星拳 1 +x:1 +消化力 1 +x:1 +基藏库 1 +x:1 +一团漆黑 1 +x:1 +以史为鉴 1 +x:1 +郭洼 1 +x:1 +流落江湖 1 +x:1 +防御性 1 +x:1 +声气 1 +x:1 +径情直遂 1 +x:1 +偏振光 1 +x:1 +支队 1 +x:1 +接收站 1 +x:1 +渗透量 1 +x:1 +封建主 1 +x:1 +察看 1 +x:1 +人海 1 +x:1 +新城 1 +x:1 +饼干桶 1 +x:1 +活期 1 +x:1 +维持费 1 +x:1 +进益 1 +x:1 +渭河 1 +x:1 +乌贼鱼 1 +x:1 +文物量 1 +x:1 +价格关 1 +x:1 +舍本逐末 1 +x:1 +贯串 1 +x:1 +怯弱 1 +x:1 +北吴村 1 +x:1 +推导 1 +x:1 +播种 1 +x:1 +狂飙运动 1 +x:1 +丧心语 1 +x:1 +侧吹 1 +x:1 +狂欢节 1 +x:1 +珍贵 1 +x:1 +北爱尔兰 1 +x:1 +永久化 1 +x:1 +照说 1 +x:1 +人治 1 +x:1 +求富者 1 +x:1 +壮伟 1 +x:1 +涉温泉 1 +x:1 +趟 100 +x:100 +登陆点 1 +x:1 +年长 1 +x:1 +泼水花 1 +x:1 +缨 3 +x:3 +求之不得 1 +x:1 +催逼 1 +x:1 +广汉市 1 +x:1 +由来 1 +x:1 +燕莎桥 1 +x:1 +堤塘 1 +x:1 +金华县 1 +x:1 +侧后 1 +x:1 +任意球 1 +x:1 +迢遥 1 +x:1 +过法 1 +x:1 +眼跳 1 +x:1 +转产 1 +x:1 +岩峰 1 +x:1 +越剧团 1 +x:1 +苏里南 1 +x:1 +柜员制 1 +x:1 +广角镜 1 +x:1 +品酒 1 +x:1 +华表 1 +x:1 +万舍村 1 +x:1 +优惠证 1 +x:1 +矮化 1 +x:1 +闻香杯 1 +x:1 +评审团 1 +x:1 +几经 1 +x:1 +考场 1 +x:1 +学武 1 +x:1 +主客场制 1 +x:1 +罗织 1 +x:1 +索本求源 1 +x:1 +藩国 1 +x:1 +聋哑学校 1 +x:1 +句句 1 +x:1 +伪中队长 1 +x:1 +明明白白 1 +x:1 +天兵天将 1 +x:1 +爬虫 1 +x:1 +灵光 1 +x:1 +卷儿 1 +x:1 +僵滞 1 +x:1 +北门东 1 +x:1 +句号 1 +x:1 +娄底 1 +x:1 +狗吃屎 1 +x:1 +莫沙夫 1 +x:1 +制盐 1 +x:1 +一清二楚 1 +x:1 +人氏 1 +x:1 +有理无情 1 +x:1 +猎刀 1 +x:1 +推子 1 +x:1 +中关工委 1 +x:1 +菜团子 1 +x:1 +斑秃 1 +x:1 +司法权 1 +x:1 +人气 1 +x:1 +八卦三路 1 +x:1 +拉丁文 1 +x:1 +魏碑 1 +x:1 +水磨沟 1 +x:1 +膑足 1 +x:1 +领花 1 +x:1 +义 104 +x:104 +荷尔蒙 1 +x:1 +玻方 1 +x:1 +投资方 1 +x:1 +发表期 1 +x:1 +乾坤袋 1 +x:1 +子鸡 1 +x:1 +头颈部 1 +x:1 +贯众 1 +x:1 +脏兮兮 1 +x:1 +采血车 1 +x:1 +汽技改 1 +x:1 +沉心静气 1 +x:1 +望果节 1 +x:1 +睡魔 1 +x:1 +疼痛 1 +x:1 +郇封村 1 +x:1 +送电 1 +x:1 +罗纱 1 +x:1 +耐药性 1 +x:1 +掳掠 1 +x:1 +罗纹 1 +x:1 +上付村 1 +x:1 +三高 1 +x:1 +疼爱 1 +x:1 +菱香 1 +x:1 +泥煤 1 +x:1 +富豪 1 +x:1 +办公地 1 +x:1 +分行业 1 +x:1 +使团 1 +x:1 +前所未见 1 +x:1 +老少皆知 1 +x:1 +合同化 1 +x:1 +奥迪车 1 +x:1 +千吨级 1 +x:1 +锦州 1 +x:1 +梳理 1 +x:1 +就此 1 +x:1 +持久性 1 +x:1 +悲剧性 1 +x:1 +疑义 1 +x:1 +逸 17 +x:17 +播绿 1 +x:1 +丹青 1 +x:1 +丁香花 1 +x:1 +芫荽 1 +x:1 +岩寺 1 +x:1 +菅 1 +x:1 +集大成者 1 +x:1 +生石膏 1 +x:1 +新党 1 +x:1 +出果期 1 +x:1 +金刚石 1 +x:1 +特优卡 1 +x:1 +首创者 1 +x:1 +新建县 1 +x:1 +侧卧 1 +x:1 +新元 1 +x:1 +此前 1 +x:1 +得体 1 +x:1 +跻入 1 +x:1 +古兰经 1 +x:1 +抗敌 1 +x:1 +山禾队 1 +x:1 +热诚 1 +x:1 +停驶 1 +x:1 +人母 1 +x:1 +黄腊石 1 +x:1 +新兴 1 +x:1 +新兵 1 +x:1 +母丁香 1 +x:1 +长白猪 1 +x:1 +鲁鱼帝虎 1 +x:1 +没得说 1 +x:1 +支那 1 +x:1 +汽修点 1 +x:1 +亲如兄弟 1 +x:1 +染棍 1 +x:1 +灸 1 +x:1 +考古系 1 +x:1 +检举 1 +x:1 +年富力强 1 +x:1 +邮电部 1 +x:1 +统一体 1 +x:1 +假钞 1 +x:1 +趾头 1 +x:1 +人次 1 +x:1 +道不明 1 +x:1 +戚墅堰 1 +x:1 +徒 26 +x:26 +来日无多 1 +x:1 +首饰厂 1 +x:1 +不能自己 1 +x:1 +不能自已 1 +x:1 +卡拉OK 1 +x:1 +人欲 1 +x:1 +乱云飞渡 1 +x:1 +银行方 1 +x:1 +综放 1 +x:1 +冰球界 1 +x:1 +伤残证 1 +x:1 +正切 1 +x:1 +流石滩 1 +x:1 +桐柏县 1 +x:1 +混合式 1 +x:1 +收容 1 +x:1 +站柜台 1 +x:1 +大步流星 1 +x:1 +人武 1 +x:1 +巍峨 1 +x:1 +小熊座 1 +x:1 +不同寻常 1 +x:1 +精气神 1 +x:1 +相爱 1 +x:1 +母怀 1 +x:1 +疑云 1 +x:1 +铠 1 +x:1 +饭碗子 1 +x:1 +天祥楼 1 +x:1 +左 385 +x:385 +主角奖 1 +x:1 +出尘脱俗 1 +x:1 +走马赴任 1 +x:1 +市盈率 1 +x:1 +县市 1 +x:1 +损失费 1 +x:1 +认识者 1 +x:1 +应激反应 1 +x:1 +五里亭 1 +x:1 +牧业税 1 +x:1 +房地产 1 +x:1 +自然灾害 1 +x:1 +尽数 1 +x:1 +复合式 1 +x:1 +猪羊肉 1 +x:1 +合同制 1 +x:1 +化妆室 1 +x:1 +磷肥 1 +x:1 +阳平关 1 +x:1 +悲剧感 1 +x:1 +摔跤赛 1 +x:1 +羊栏镇 1 +x:1 +玉池乡 1 +x:1 +小港村 1 +x:1 +顺时 1 +x:1 +疾患 1 +x:1 +重量级 1 +x:1 +声母 1 +x:1 +之类 1 +x:1 +健身热 1 +x:1 +考入 1 +x:1 +蒸锅 1 +x:1 +订单 1 +x:1 +模范村 1 +x:1 +指挥车 1 +x:1 +侦探片 1 +x:1 +得主 1 +x:1 +情报局 1 +x:1 +笋鸡 1 +x:1 +原料处 1 +x:1 +利湿 1 +x:1 +军工部 1 +x:1 +爹爹 1 +x:1 +漪汾苑 1 +x:1 +富贵 1 +x:1 +洗染 1 +x:1 +铜仁 1 +x:1 +富贾 1 +x:1 +反潮流 1 +x:1 +丹阳 1 +x:1 +拒之门外 1 +x:1 +彭水县 1 +x:1 +铜价 1 +x:1 +补袜板 1 +x:1 +兵连祸结 1 +x:1 +邮路 1 +x:1 +俯卧 1 +x:1 +展示台 1 +x:1 +相率 1 +x:1 +恰逢 1 +x:1 +晴纶 1 +x:1 +摊贩 1 +x:1 +正月十五 1 +x:1 +盗卖者 1 +x:1 +得了 1 +x:1 +支配 1 +x:1 +随葬 1 +x:1 +修造船 1 +x:1 +童子痨 1 +x:1 +创新性 1 +x:1 +有限 1 +x:1 +铜丝 1 +x:1 +下世纪 1 +x:1 +指挥连 1 +x:1 +尽日 1 +x:1 +繁琐 1 +x:1 +瀛州 1 +x:1 +携妻 1 +x:1 +尼日尔州 1 +x:1 +顺数 1 +x:1 +和蔼 1 +x:1 +超过者 1 +x:1 +农函大 1 +x:1 +伪气功 1 +x:1 +邮购 1 +x:1 +蘑菇战术 1 +x:1 +精锐 1 +x:1 +营业局 1 +x:1 +濮阳市 1 +x:1 +代远年湮 1 +x:1 +检修 1 +x:1 +文凭者 1 +x:1 +抽抽 1 +x:1 +砚池河 1 +x:1 +旗山 1 +x:1 +高寒区 1 +x:1 +新四军 1 +x:1 +锦屏 1 +x:1 +泥炭 1 +x:1 +衰颓 1 +x:1 +生命学 1 +x:1 +营养型 1 +x:1 +没你好 1 +x:1 +邮资 1 +x:1 +泥点 1 +x:1 +富足 1 +x:1 +远 626 +x:626 +我国 1 +x:1 +正月十七 1 +x:1 +得以 1 +x:1 +电解盐 1 +x:1 +巍巍 1 +x:1 +鉴定机 1 +x:1 +千叮咛 1 +x:1 +验光 1 +x:1 +芫花 1 +x:1 +青州市 1 +x:1 +空空落落 1 +x:1 +参茸 1 +x:1 +推崇 1 +x:1 +台州市 1 +x:1 +新化 1 +x:1 +考前 1 +x:1 +京剧团 1 +x:1 +持久战 1 +x:1 +悔罪 1 +x:1 +下汤镇 1 +x:1 +文博院 1 +x:1 +同 4312 +x:4312 +严防 1 +x:1 +夏商周 1 +x:1 +按扣儿 1 +x:1 +三风 1 +x:1 +苦功 1 +x:1 +围观 1 +x:1 +恼恨 1 +x:1 +作废 1 +x:1 +新区 1 +x:1 +漂亮 1 +x:1 +戏剧家 1 +x:1 +排球 1 +x:1 +竞赛区 1 +x:1 +惯子 1 +x:1 +民资 1 +x:1 +溶化 1 +x:1 +此起彼伏 1 +x:1 +考分 1 +x:1 +食不甘味 1 +x:1 +观者如堵 1 +x:1 +柔软剂 1 +x:1 +柜组 1 +x:1 +投资性 1 +x:1 +苦涩 1 +x:1 +言喻 1 +x:1 +泥猴 1 +x:1 +新华 1 +x:1 +傻笑 1 +x:1 +参议员 1 +x:1 +恼怒 1 +x:1 +参股 1 +x:1 +要子 1 +x:1 +停顿 1 +x:1 +斯文扫地 1 +x:1 +安享晚年 1 +x:1 +扪心自问 1 +x:1 +眼裂 1 +x:1 +猥辞 1 +x:1 +构配件 1 +x:1 +金字塔 1 +x:1 +景德镇市 1 +x:1 +顺景 1 +x:1 +推广 1 +x:1 +走檐飞翘 1 +x:1 +生存者 1 +x:1 +中腹之战 1 +x:1 +农机站 1 +x:1 +猎场 1 +x:1 +闻所未闻 1 +x:1 +颔 2 +x:2 +塑钢门 1 +x:1 +存贮器 1 +x:1 +丛 39 +x:39 +高粱米 1 +x:1 +羁押室 1 +x:1 +利润 1 +x:1 +膝头 1 +x:1 +判断 1 +x:1 +电视剧部 1 +x:1 +新县 1 +x:1 +考勤 1 +x:1 +画虎类狗 1 +x:1 +司法所 1 +x:1 +俱在 1 +x:1 +活捉 1 +x:1 +倒伏 1 +x:1 +宴会席 1 +x:1 +演说 1 +x:1 +荷兰 1 +x:1 +保证卡 1 +x:1 +鼻韵母 1 +x:1 +粪便 1 +x:1 +参考 1 +x:1 +墨西哥州 1 +x:1 +脑贫血 1 +x:1 +侧击 1 +x:1 +走走 1 +x:1 +民贼 1 +x:1 +培养 1 +x:1 +响头 1 +x:1 +无头表 1 +x:1 +决策制 1 +x:1 +苘 1 +x:1 +著名者 1 +x:1 +驮戥村 1 +x:1 +条码 1 +x:1 +护栏 1 +x:1 +木栏 1 +x:1 +茶盅 1 +x:1 +历演不衰 1 +x:1 +修道院 1 +x:1 +平林镇 1 +x:1 +熔岩 1 +x:1 +画廊 1 +x:1 +茶盘 1 +x:1 +护树 1 +x:1 +三趾马 1 +x:1 +潜研 1 +x:1 +人梯 1 +x:1 +月城 1 +x:1 +试行期 1 +x:1 +围裙 1 +x:1 +盟委 1 +x:1 +羊三木 1 +x:1 +过梁 1 +x:1 +复眼 1 +x:1 +新刊 1 +x:1 +比翼鸟 1 +x:1 +利民 1 +x:1 +电器行 1 +x:1 +千金一掷 1 +x:1 +连城村 1 +x:1 +电器街 1 +x:1 +流泪 1 +x:1 +蒸霞 1 +x:1 +锥度 1 +x:1 +传销业 1 +x:1 +考卷 1 +x:1 +防伪 1 +x:1 +恐吓信 1 +x:1 +徐公祠 1 +x:1 +外联处 1 +x:1 +的确良 1 +x:1 +竹节石 1 +x:1 +减 348 +x:348 +怡情养性 1 +x:1 +暴行 1 +x:1 +激流勇进 1 +x:1 +庄浪县 1 +x:1 +嘈杂 1 +x:1 +繁盛 1 +x:1 +眼角 1 +x:1 +有钱 1 +x:1 +染毒 1 +x:1 +尽期 1 +x:1 +草签 1 +x:1 +扑空 1 +x:1 +私娼 1 +x:1 +考区 1 +x:1 +天一阁 1 +x:1 +新剧 1 +x:1 +茅坑 1 +x:1 +眼见 1 +x:1 +还价 1 +x:1 +邮迷 1 +x:1 +议事组 1 +x:1 +说长道短 1 +x:1 +拼死一搏 1 +x:1 +全方位 1 +x:1 +年金 1 +x:1 +铜钱眼 1 +x:1 +争名谋位 1 +x:1 +草台岗 1 +x:1 +天下无双 1 +x:1 +人样 1 +x:1 +考取 1 +x:1 +物理诊断 1 +x:1 +中短波 1 +x:1 +长野县 1 +x:1 +丹铁 1 +x:1 +考古 1 +x:1 +围衬 1 +x:1 +核磁共振 1 +x:1 +伙伴 1 +x:1 +检疫场 1 +x:1 +序幕 1 +x:1 +宁安乡 1 +x:1 +武夷山 1 +x:1 +疳疮 1 +x:1 +上次 1 +x:1 +推弹 1 +x:1 +倒买 1 +x:1 +规例 1 +x:1 +遇见 1 +x:1 +靠边站 1 +x:1 +传销价 1 +x:1 +免烧砖 1 +x:1 +堤岸 1 +x:1 +作风 1 +x:1 +亚候鸟 1 +x:1 +旗帜 1 +x:1 +珠唇 1 +x:1 +兰特 1 +x:1 +珍视 1 +x:1 +棉衣被 1 +x:1 +电击 1 +x:1 +句型 1 +x:1 +母子公司 1 +x:1 +还乡 1 +x:1 +鼓翼欲飞 1 +x:1 +股交所 1 +x:1 +热衷 1 +x:1 +未愈 1 +x:1 +掀起 1 +x:1 +叶猴 1 +x:1 +推开 1 +x:1 +行车执照 1 +x:1 +防线 1 +x:1 +光盘厂 1 +x:1 +送终 1 +x:1 +探险 1 +x:1 +条目 1 +x:1 +发动机盖 1 +x:1 +申城 1 +x:1 +纯化 1 +x:1 +送给 1 +x:1 +官风 1 +x:1 +美术字 1 +x:1 +茨城县 1 +x:1 +家常饭 1 +x:1 +盟国 1 +x:1 +阿达纳市 1 +x:1 +机理 1 +x:1 +敦劝 1 +x:1 +测量学 1 +x:1 +捅娄子 1 +x:1 +茶砖 1 +x:1 +大花脸 1 +x:1 +堤南 1 +x:1 +个私 1 +x:1 +丝柏 1 +x:1 +铣床 1 +x:1 +乡镇级 1 +x:1 +相约 1 +x:1 +老二 1 +x:1 +斯托蒙特 1 +x:1 +宣誓 1 +x:1 +大浪淘沙 1 +x:1 +锅烟子 1 +x:1 +老五 1 +x:1 +智人 1 +x:1 +扭转乾坤 1 +x:1 +供给者 1 +x:1 +洗洗涮涮 1 +x:1 +富者 1 +x:1 +满目生辉 1 +x:1 +代办所 1 +x:1 +三难 1 +x:1 +周 4623 +x:4623 +指挥船 1 +x:1 +无量 1 +x:1 +钟山 1 +x:1 +忙而不乱 1 +x:1 +参政员 1 +x:1 +老亲 1 +x:1 +不致于 1 +x:1 +目不忍睹 1 +x:1 +罗田 1 +x:1 +红种人 1 +x:1 +老人 1 +x:1 +亡羊补牢 1 +x:1 +罗甸 1 +x:1 +人本 1 +x:1 +雅砻江 1 +x:1 +当年度 1 +x:1 +岩场 1 +x:1 +办公室 1 +x:1 +豪放者 1 +x:1 +过期 1 +x:1 +入网证 1 +x:1 +入盟期 1 +x:1 +预调 1 +x:1 +茶碱 1 +x:1 +探雷 1 +x:1 +千代田区 1 +x:1 +人机 1 +x:1 +东街村 1 +x:1 +老九 1 +x:1 +窥到 1 +x:1 +验尸 1 +x:1 +报审制 1 +x:1 +老乡 1 +x:1 +扳机 1 +x:1 +移民局长 1 +x:1 +紧凑型 1 +x:1 +岩土 1 +x:1 +西峡县 1 +x:1 +决策层 1 +x:1 +通俗性 1 +x:1 +利己 1 +x:1 +诗话 1 +x:1 +三陪 1 +x:1 +人望 1 +x:1 +防汛办 1 +x:1 +撼人心魄 1 +x:1 +百分之 1 +x:1 +不痛不痒 1 +x:1 +茶碟 1 +x:1 +定规 1 +x:1 +艇 26 +x:26 +罗庄镇 1 +x:1 +老三 1 +x:1 +新州 1 +x:1 +压制型 1 +x:1 +矮墙 1 +x:1 +团团转 1 +x:1 +点源 1 +x:1 +未央宫 1 +x:1 +人杰 1 +x:1 +主体论 1 +x:1 +苟刻 1 +x:1 +悔过自新 1 +x:1 +淝河 1 +x:1 +推倒 1 +x:1 +老三样 1 +x:1 +岩块 1 +x:1 +猎奇 1 +x:1 +清香味 1 +x:1 +新巧 1 +x:1 +智业 1 +x:1 +惜墨如金 1 +x:1 +企改 1 +x:1 +美术家 1 +x:1 +人材 1 +x:1 +大彰山 1 +x:1 +推出 1 +x:1 +森林法 1 +x:1 +芳草地 1 +x:1 +农机界 1 +x:1 +唇枪舌剑 1 +x:1 +话筒 1 +x:1 +苟取 1 +x:1 +练习曲 1 +x:1 +没齿不忘 1 +x:1 +分光镜 1 +x:1 +活泼 1 +x:1 +条石 1 +x:1 +五指山 1 +x:1 +犁牛 1 +x:1 +勺海 1 +x:1 +轴径 1 +x:1 +捞油水 1 +x:1 +排笔 1 +x:1 +染料 1 +x:1 +覆盖率 1 +x:1 +D 131 +x:131 +活法 1 +x:1 +藩属 1 +x:1 +敦厚 1 +x:1 +更有甚者 1 +x:1 +中央台 1 +x:1 +精馏 1 +x:1 +刚构桥 1 +x:1 +伦理学家 1 +x:1 +残垣断壁 1 +x:1 +老例 1 +x:1 +暴虐 1 +x:1 +蒸饺 1 +x:1 +一筹莫展 1 +x:1 +骄矜 1 +x:1 +水星队 1 +x:1 +蒸饼 1 +x:1 +新居 1 +x:1 +定见 1 +x:1 +不问自明 1 +x:1 +董事长 1 +x:1 +产销率 1 +x:1 +相通 1 +x:1 +日历表 1 +x:1 +新山 1 +x:1 +彤 33 +x:33 +踅子 1 +x:1 +助阵 1 +x:1 +国有民助 1 +x:1 +窝工 1 +x:1 +规约 1 +x:1 +拢子 1 +x:1 +停靠 1 +x:1 +窝巢 1 +x:1 +护林 1 +x:1 +排筏 1 +x:1 +作陪 1 +x:1 +五味子 1 +x:1 +登陆站 1 +x:1 +影响力 1 +x:1 +小商品 1 +x:1 +替人 1 +x:1 +耀目 1 +x:1 +人心向背 1 +x:1 +求诊 1 +x:1 +菲方 1 +x:1 +凝视 1 +x:1 +白莲教 1 +x:1 +钦南区 1 +x:1 +众生 1 +x:1 +叮 5 +x:5 +排箫 1 +x:1 +随行 1 +x:1 +见报 1 +x:1 +浇筑 1 +x:1 +穷当益坚 1 +x:1 +棺木 1 +x:1 +椰岛 1 +x:1 +傻瓜 1 +x:1 +不负重望 1 +x:1 +刻刀 1 +x:1 +非离子氨 1 +x:1 +植保站 1 +x:1 +酒绿灯红 1 +x:1 +限产保价 1 +x:1 +完备化 1 +x:1 +航站楼 1 +x:1 +稀土元素 1 +x:1 +赃 1 +x:1 +德国式 1 +x:1 +沙溪桥 1 +x:1 +活水 1 +x:1 +光秃秃 1 +x:1 +粱洼镇 1 +x:1 +老吾老 1 +x:1 +部省级 1 +x:1 +魏善庄乡 1 +x:1 +预赛 1 +x:1 +潦倒终身 1 +x:1 +年龄 1 +x:1 +鲲鹏 1 +x:1 +替代 1 +x:1 +防雹网 1 +x:1 +前邵村 1 +x:1 +编目卡 1 +x:1 +活气 1 +x:1 +实践性 1 +x:1 +吹奏者 1 +x:1 +蜂巢胃 1 +x:1 +老伯 1 +x:1 +接送车 1 +x:1 +黄潭村 1 +x:1 +舌苔 1 +x:1 +耳针 1 +x:1 +无遗 1 +x:1 +整流 1 +x:1 +绺 2 +x:2 +南池子 1 +x:1 +谋略史 1 +x:1 +时新日异 1 +x:1 +子音 1 +x:1 +圣意 1 +x:1 +茆 1 +x:1 +就教 1 +x:1 +棠梨 1 +x:1 +杀回马枪 1 +x:1 +拉锁 1 +x:1 +雄姿英发 1 +x:1 +新异 1 +x:1 +首倡国 1 +x:1 +西侧 1 +x:1 +混成旅 1 +x:1 +四国岛 1 +x:1 +鞣制 1 +x:1 +派遣 1 +x:1 +办公处 1 +x:1 +罗河镇 1 +x:1 +要路 1 +x:1 +真才实学 1 +x:1 +人文 1 +x:1 +家用电器 1 +x:1 +旗号 1 +x:1 +内格夫 1 +x:1 +雀鹰 1 +x:1 +笔底下 1 +x:1 +拟 129 +x:129 +羹 2 +x:2 +邮花 1 +x:1 +碱渣堆场 1 +x:1 +棠棣 1 +x:1 +周村区 1 +x:1 +紫穗槐 1 +x:1 +捆 47 +x:47 +美术处 1 +x:1 +凤尾鱼 1 +x:1 +著称 1 +x:1 +养儿防老 1 +x:1 +四星级 1 +x:1 +傻眼 1 +x:1 +甜面酱 1 +x:1 +推动 1 +x:1 +腊味店 1 +x:1 +二三月份 1 +x:1 +切题 1 +x:1 +奶羊 1 +x:1 +推力 1 +x:1 +新影 1 +x:1 +贯家堡村 1 +x:1 +组阁权 1 +x:1 +精髓 1 +x:1 +渌头江 1 +x:1 +送粮 1 +x:1 +收回率 1 +x:1 +临漳县 1 +x:1 +低平 1 +x:1 +滑降 1 +x:1 +厚爱 1 +x:1 +过早 1 +x:1 +勤政者 1 +x:1 +丁丑年 1 +x:1 +心结 1 +x:1 +盟员 1 +x:1 +修脚 1 +x:1 +法定人数 1 +x:1 +灰霉病 1 +x:1 +西游记宫 1 +x:1 +徐娘半老 1 +x:1 +保坪乡 1 +x:1 +七拼八凑 1 +x:1 +斯威士兰 1 +x:1 +展性 1 +x:1 +前廊 1 +x:1 +菽栗 1 +x:1 +尾闸乡 1 +x:1 +通信部 1 +x:1 +戏剧场 1 +x:1 +工矿业 1 +x:1 +笃信 1 +x:1 +巡特警 1 +x:1 +潮汐能 1 +x:1 +邮船 1 +x:1 +皮帽子 1 +x:1 +推前 1 +x:1 +常抓不懈 1 +x:1 +同乐日 1 +x:1 +别具匠心 1 +x:1 +印辙 1 +x:1 +旱烟 1 +x:1 +双低型 1 +x:1 +飞船 1 +x:1 +双学位 1 +x:1 +儿童节 1 +x:1 +放射性束 1 +x:1 +掘进头 1 +x:1 +参谋 1 +x:1 +黄委会 1 +x:1 +定居证 1 +x:1 +相簿 1 +x:1 +过敏 1 +x:1 +一语破的 1 +x:1 +企望 1 +x:1 +滑雪 1 +x:1 +人数 1 +x:1 +大使级 1 +x:1 +柞绸 1 +x:1 +雀麦 1 +x:1 +锦化 1 +x:1 +条理 1 +x:1 +孢子粉 1 +x:1 +罗浮宫 1 +x:1 +探针 1 +x:1 +单体 1 +x:1 +濮 8 +x:8 +单位 1 +x:1 +哑铃 1 +x:1 +人教 1 +x:1 +武官处 1 +x:1 +太阴历 1 +x:1 +体改司 1 +x:1 +阵亡 1 +x:1 +安隆汶 1 +x:1 +阳曲 1 +x:1 +西人 1 +x:1 +浪人 1 +x:1 +单人 1 +x:1 +该组 1 +x:1 +较重者 1 +x:1 +桐柏山 1 +x:1 +阵位 1 +x:1 +声旁 1 +x:1 +宴会厅 1 +x:1 +金桔 1 +x:1 +拉坎多纳 1 +x:1 +扬名天下 1 +x:1 +单产 1 +x:1 +笺谱 1 +x:1 +轴承 1 +x:1 +辛夷 1 +x:1 +西亚 1 +x:1 +媳妇儿 1 +x:1 +押款箱 1 +x:1 +单井 1 +x:1 +缴获 1 +x:1 +青山常在 1 +x:1 +火柴盒式 1 +x:1 +吹牛 1 +x:1 +推及 1 +x:1 +三门 1 +x:1 +子集 1 +x:1 +分则 1 +x:1 +尺 62 +x:62 +句子 1 +x:1 +人墙 1 +x:1 +面面俱到 1 +x:1 +阿特拉 1 +x:1 +擦黑 1 +x:1 +单价 1 +x:1 +空当儿 1 +x:1 +艰难困苦 1 +x:1 +寻呼 1 +x:1 +钠玻璃 1 +x:1 +亲和力 1 +x:1 +虞 24 +x:24 +新平 1 +x:1 +基本性 1 +x:1 +活源 1 +x:1 +音信全无 1 +x:1 +委靡不振 1 +x:1 +新年 1 +x:1 +矾土 1 +x:1 +乘胜追击 1 +x:1 +坚持者 1 +x:1 +品饮 1 +x:1 +大腿骨 1 +x:1 +气派 1 +x:1 +心急如火 1 +x:1 +场边 1 +x:1 +爱面子 1 +x:1 +推卸 1 +x:1 +求见 1 +x:1 +血气胸 1 +x:1 +参赌 1 +x:1 +探问 1 +x:1 +京剧学 1 +x:1 +推却 1 +x:1 +西丰 1 +x:1 +说服性 1 +x:1 +每户 1 +x:1 +参赞 1 +x:1 +体改办 1 +x:1 +三镇 1 +x:1 +罗盘 1 +x:1 +昏天黑地 1 +x:1 +求解 1 +x:1 +无师自通 1 +x:1 +要害 1 +x:1 +菌蛋白 1 +x:1 +选择型 1 +x:1 +瘦肉型 1 +x:1 +金刚砂 1 +x:1 +单一 1 +x:1 +都灵 1 +x:1 +桃花雪 1 +x:1 +滑音 1 +x:1 +联动机 1 +x:1 +八平柴 1 +x:1 +汛限 1 +x:1 +妈祖 1 +x:1 +顺次 1 +x:1 +签收 1 +x:1 +稳稳当当 1 +x:1 +条田 1 +x:1 +祝楼乡 1 +x:1 +句容 1 +x:1 +一飞冲天 1 +x:1 +哑门 1 +x:1 +染杠 1 +x:1 +改改 1 +x:1 +老人手 1 +x:1 +针眼 1 +x:1 +单独 1 +x:1 +新建 1 +x:1 +珍藏 1 +x:1 +高中 1 +x:1 +见惯 1 +x:1 +西乐 1 +x:1 +列支法 1 +x:1 +毛毛虫 1 +x:1 +钨砂 1 +x:1 +业务司 1 +x:1 +精魂 1 +x:1 +掀腾 1 +x:1 +处世经 1 +x:1 +图文并茂 1 +x:1 +眼花 1 +x:1 +寻医 1 +x:1 +坑人 1 +x:1 +斑白 1 +x:1 +堤坡 1 +x:1 +总序 1 +x:1 +辅佐 1 +x:1 +乐清市 1 +x:1 +患有 1 +x:1 +子金 1 +x:1 +坑井 1 +x:1 +上杭县 1 +x:1 +茉莉花茶 1 +x:1 +月球 1 +x:1 +龟甲 1 +x:1 +林蛙油 1 +x:1 +制伏 1 +x:1 +精炼厂 1 +x:1 +枝枝 1 +x:1 +瘢块 1 +x:1 +双江镇 1 +x:1 +生命力 1 +x:1 +老人斑 1 +x:1 +存单 1 +x:1 +扶保 1 +x:1 +订婚 1 +x:1 +代部长 1 +x:1 +沪东 1 +x:1 +囊空如洗 1 +x:1 +宗室 1 +x:1 +矮小 1 +x:1 +每日 1 +x:1 +预装 1 +x:1 +骄狂 1 +x:1 +榜文 1 +x:1 +圆白菜 1 +x:1 +班集体 1 +x:1 +完整性 1 +x:1 +铣工 1 +x:1 +无间 1 +x:1 +顺治 1 +x:1 +西丰县 1 +x:1 +舌蝇 1 +x:1 +滑道 1 +x:1 +东方乡 1 +x:1 +中枢 1 +x:1 +家仇 1 +x:1 +辱没 1 +x:1 +加深 1 +x:1 +市场 1 +x:1 +取静集 1 +x:1 +利权 1 +x:1 +制作 1 +x:1 +无锡 1 +x:1 +从古至今 1 +x:1 +里脊 1 +x:1 +开歇业 1 +x:1 +啬 1 +x:1 +垒 24 +x:24 +新妆 1 +x:1 +新妇 1 +x:1 +耶稣教 1 +x:1 +子丑寅卯 1 +x:1 +展映 1 +x:1 +茶精 1 +x:1 +辅修 1 +x:1 +吴淞口 1 +x:1 +司法厅 1 +x:1 +烹调 1 +x:1 +投诉书 1 +x:1 +堤埂 1 +x:1 +京 1335 +x:1335 +热茶 1 +x:1 +测井 1 +x:1 +扶余 1 +x:1 +爱丽舍宫 1 +x:1 +官样文章 1 +x:1 +东方人 1 +x:1 +饥荒 1 +x:1 +检疫局 1 +x:1 +眼色 1 +x:1 +雅瑶乡 1 +x:1 +发言权 1 +x:1 +一勘局 1 +x:1 +试行法 1 +x:1 +山毛榉 1 +x:1 +紧扣 1 +x:1 +都督 1 +x:1 +联动性 1 +x:1 +墨西哥城 1 +x:1 +助视器 1 +x:1 +萨格勒布 1 +x:1 +航运站 1 +x:1 +扭结处 1 +x:1 +话线 1 +x:1 +推向 1 +x:1 +新姿 1 +x:1 +钟声 1 +x:1 +和歌山 1 +x:1 +实数 1 +x:1 +推后 1 +x:1 +渔轮 1 +x:1 +排练 1 +x:1 +扶优 1 +x:1 +以我为主 1 +x:1 +顺民 1 +x:1 +送稿 1 +x:1 +化敌为友 1 +x:1 +参评 1 +x:1 +鹧鸪菜 1 +x:1 +汇率制 1 +x:1 +参证 1 +x:1 +束手束脚 1 +x:1 +教义式 1 +x:1 +参试 1 +x:1 +紧接 1 +x:1 +携儿 1 +x:1 +盟友 1 +x:1 +团圆年 1 +x:1 +就手 1 +x:1 +一绝 1 +x:1 +素 35 +x:35 +新堰 1 +x:1 +洽谈会 1 +x:1 +情报员 1 +x:1 +洗澡 1 +x:1 +不久前 1 +x:1 +钟头 1 +x:1 +眨 6 +x:6 +韶华 1 +x:1 +路堤 1 +x:1 +印象 1 +x:1 +抵 207 +x:207 +美术年 1 +x:1 +欠员 1 +x:1 +规定值 1 +x:1 +美术师 1 +x:1 +申办 1 +x:1 +应力场 1 +x:1 +千帆竞发 1 +x:1 +新塘 1 +x:1 +专职 1 +x:1 +过招 1 +x:1 +电视厅 1 +x:1 +书生气 1 +x:1 +生命史 1 +x:1 +衰退 1 +x:1 +厚生 1 +x:1 +肉孜节 1 +x:1 +紧握 1 +x:1 +辅业 1 +x:1 +投资款 1 +x:1 +黑桦 1 +x:1 +悟析 1 +x:1 +襟怀 1 +x:1 +展柜 1 +x:1 +看门人 1 +x:1 +欢天喜地 1 +x:1 +参训 1 +x:1 +参政党 1 +x:1 +金刚经 1 +x:1 +闻 163 +x:163 +参访 1 +x:1 +珠三角 1 +x:1 +虚幻 1 +x:1 +日隆 1 +x:1 +镍氢 1 +x:1 +生机蓬勃 1 +x:1 +差之甚远 1 +x:1 +内果皮 1 +x:1 +白马镇 1 +x:1 +休闲服 1 +x:1 +堤围 1 +x:1 +四周围 1 +x:1 +; 16336 +x:16336 +求进 1 +x:1 +过户 1 +x:1 +窝头 1 +x:1 +艳妆 1 +x:1 +相等 1 +x:1 +展望 1 +x:1 +逆时针 1 +x:1 +辅以 1 +x:1 +三落实 1 +x:1 +外省人 1 +x:1 +朝廷树 1 +x:1 +承包额 1 +x:1 +批量化 1 +x:1 +逢冠必夺 1 +x:1 +用地 1 +x:1 +猿 9 +x:9 +俄通社 1 +x:1 +牌坊店村 1 +x:1 +嗑 1 +x:1 +懈 1 +x:1 +轧花机 1 +x:1 +相符 1 +x:1 +丹麦 1 +x:1 +扳手 1 +x:1 +下奥州 1 +x:1 +一两点 1 +x:1 +眼药 1 +x:1 +过手 1 +x:1 +人才 1 +x:1 +活树 1 +x:1 +星星峡 1 +x:1 +人手 1 +x:1 +门静脉 1 +x:1 +痰迷心窍 1 +x:1 +随调 1 +x:1 +狼山鸡 1 +x:1 +护持 1 +x:1 +构成性 1 +x:1 +飞花 1 +x:1 +怂恿 1 +x:1 +射击赛 1 +x:1 +高官厚禄 1 +x:1 +天燃气 1 +x:1 +石砚 1 +x:1 +上湖村 1 +x:1 +国转非 1 +x:1 +吝啬鬼 1 +x:1 +展播 1 +x:1 +授予 1 +x:1 +手术台 1 +x:1 +预备役 1 +x:1 +皱缬 1 +x:1 +小册子 1 +x:1 +远亲 1 +x:1 +几率 1 +x:1 +胆瓶 1 +x:1 +旌旗 1 +x:1 +回流 1 +x:1 +小山子 1 +x:1 +小住 1 +x:1 +合同处 1 +x:1 +锦城 1 +x:1 +听到 1 +x:1 +匪夷所思 1 +x:1 +见效 1 +x:1 +扬程 1 +x:1 +欧盟史 1 +x:1 +抽气机 1 +x:1 +积极向上 1 +x:1 +暴腌 1 +x:1 +羊踯躅 1 +x:1 +见教 1 +x:1 +赤膊上阵 1 +x:1 +相碰 1 +x:1 +三段论式 1 +x:1 +扶贫组 1 +x:1 +家业 1 +x:1 +左联 1 +x:1 +军令如山 1 +x:1 +巴人 1 +x:1 +贡扇 1 +x:1 +话簿 1 +x:1 +后发制人 1 +x:1 +企划厅 1 +x:1 +戏剧史 1 +x:1 +板桥口 1 +x:1 +眉峰 1 +x:1 +撕下 1 +x:1 +内伤 1 +x:1 +时光荏苒 1 +x:1 +申冤 1 +x:1 +授业 1 +x:1 +骑马找马 1 +x:1 +染房 1 +x:1 +冬令营 1 +x:1 +振兴路 1 +x:1 +洒落 1 +x:1 +远东 1 +x:1 +戏剧化 1 +x:1 +镀膜钛 1 +x:1 +预言 1 +x:1 +喧声四起 1 +x:1 +学科史 1 +x:1 +紧急 1 +x:1 +人愿 1 +x:1 +石砂 1 +x:1 +伶牙俐齿 1 +x:1 +繁缛 1 +x:1 +新安 1 +x:1 +柜体 1 +x:1 +无需 1 +x:1 +人意 1 +x:1 +家书 1 +x:1 +嫁接苗 1 +x:1 +每月 1 +x:1 +新宾 1 +x:1 +伊宁 1 +x:1 +每期 1 +x:1 +佛光寺 1 +x:1 +新宠 1 +x:1 +岑寂 1 +x:1 +松塔儿 1 +x:1 +魂不附体 1 +x:1 +警组 1 +x:1 +源代码 1 +x:1 +铸字机 1 +x:1 +声息 1 +x:1 +奇遇 1 +x:1 +近视眼 1 +x:1 +巴东 1 +x:1 +三通 1 +x:1 +秽乱 1 +x:1 +围脖 1 +x:1 +游学 1 +x:1 +声态 1 +x:1 +晏家镇 1 +x:1 +紫绀型 1 +x:1 +三送 1 +x:1 +疾步 1 +x:1 +前往 1 +x:1 +祥 14 +x:14 +救济金 1 +x:1 +嘉峪关市 1 +x:1 +俐 3 +x:3 +跫音 1 +x:1 +怀洪 1 +x:1 +巴中 1 +x:1 +舍近求远 1 +x:1 +痊愈 1 +x:1 +楔形带 1 +x:1 +无非 1 +x:1 +筋脉 1 +x:1 +偿 8 +x:8 +运行面 1 +x:1 +拳脚 1 +x:1 +雷同 1 +x:1 +参见 1 +x:1 +参观 1 +x:1 +新娘 1 +x:1 +串会 1 +x:1 +洗消 1 +x:1 +韶关 1 +x:1 +东京都 1 +x:1 +三野 1 +x:1 +茶缸 1 +x:1 +糙子 1 +x:1 +陆丰县 1 +x:1 +电视业 1 +x:1 +护头 1 +x:1 +鄙夫 1 +x:1 +窝家 1 +x:1 +热肠 1 +x:1 +部门法 1 +x:1 +村村落落 1 +x:1 +韶光 1 +x:1 +预订 1 +x:1 +考学 1 +x:1 +药学系 1 +x:1 +预设 1 +x:1 +鸽镇 1 +x:1 +年饭 1 +x:1 +无差别 1 +x:1 +洗液 1 +x:1 +满城风雨 1 +x:1 +茶缘 1 +x:1 +溢流式 1 +x:1 +土黄色 1 +x:1 +排泄物 1 +x:1 +浦项队 1 +x:1 +鄙夷 1 +x:1 +一身清白 1 +x:1 +宣传战 1 +x:1 +随身 1 +x:1 +热胀 1 +x:1 +调包计 1 +x:1 +认识论 1 +x:1 +壳体 1 +x:1 +修长 1 +x:1 +眼疾手快 1 +x:1 +册封使 1 +x:1 +举架 1 +x:1 +元谋猿人 1 +x:1 +瑞士队 1 +x:1 +冀中 1 +x:1 +装机容量 1 +x:1 +求贤 1 +x:1 +句式 1 +x:1 +白化病 1 +x:1 +求购 1 +x:1 +枯骨 1 +x:1 +求质 1 +x:1 +丘乾村 1 +x:1 +流化床 1 +x:1 +热能 1 +x:1 +西南局 1 +x:1 +热者 1 +x:1 +团区委 1 +x:1 +围聚 1 +x:1 +盟党 1 +x:1 +洗洁 1 +x:1 +人性 1 +x:1 +横坐标 1 +x:1 +串供 1 +x:1 +洗洗 1 +x:1 +苍莽 1 +x:1 +斑痣 1 +x:1 +金色 1 +x:1 +考察 1 +x:1 +矬子 1 +x:1 +区议会 1 +x:1 +小说界 1 +x:1 +塔里木河 1 +x:1 +饧糖 1 +x:1 +知识分子 1 +x:1 +斑痕 1 +x:1 +罩子 1 +x:1 +心旌 1 +x:1 +草产业 1 +x:1 +慕名 1 +x:1 +蒲 43 +x:43 +胆略 1 +x:1 +老人星 1 +x:1 +绿孔雀 1 +x:1 +染指 1 +x:1 +冬训 1 +x:1 +激 18 +x:18 +忙碌 1 +x:1 +萧山 1 +x:1 +顾影自怜 1 +x:1 +扶贫网 1 +x:1 +灰椋鸟 1 +x:1 +考定 1 +x:1 +考官 1 +x:1 +鱼鳞坑 1 +x:1 +橙 5 +x:5 +含垢忍辱 1 +x:1 +黑漆漆 1 +x:1 +自由主义 1 +x:1 +游子 1 +x:1 +暴胀 1 +x:1 +尖草坪区 1 +x:1 +成形 1 +x:1 +三义墓 1 +x:1 +无际 1 +x:1 +预警 1 +x:1 +瓦戈庄村 1 +x:1 +无限 1 +x:1 +洗浴 1 +x:1 +趋向性 1 +x:1 +每晚 1 +x:1 +主设备 1 +x:1 +考核组 1 +x:1 +您老 1 +x:1 +送礼 1 +x:1 +就坐 1 +x:1 +人群 1 +x:1 +朴朴素素 1 +x:1 +慈姑 1 +x:1 +爆炸声 1 +x:1 +见笑 1 +x:1 +且 405 +x:405 +崭崭 1 +x:1 +老四 1 +x:1 +难解难分 1 +x:1 +排成 1 +x:1 +别情 1 +x:1 +智囊 1 +x:1 +备忘录 1 +x:1 +气候学家 1 +x:1 +展窗 1 +x:1 +黄鹤楼 1 +x:1 +大湖镇 1 +x:1 +售 190 +x:190 +盖头 1 +x:1 +寻机 1 +x:1 +肉用鸡 1 +x:1 +丹荔 1 +x:1 +水平如镜 1 +x:1 +含情脉脉 1 +x:1 +照见 1 +x:1 +潜潜 1 +x:1 +台板厂 1 +x:1 +洛川 1 +x:1 +药厂 1 +x:1 +侵略 1 +x:1 +各行各业 1 +x:1 +国防观 1 +x:1 +文质彬彬 1 +x:1 +望花区 1 +x:1 +笑语声喧 1 +x:1 +签约 1 +x:1 +声纳 1 +x:1 +无视 1 +x:1 +总包人 1 +x:1 +眉县 1 +x:1 +肉皮 1 +x:1 +亚洲队 1 +x:1 +萨尔诺市 1 +x:1 +浏阳河 1 +x:1 +睡床 1 +x:1 +雯 72 +x:72 +念 99 +x:99 +声级 1 +x:1 +衰败 1 +x:1 +艺道 1 +x:1 +冲水式 1 +x:1 +昔 8 +x:8 +品节 1 +x:1 +刑法典 1 +x:1 +雪龙船 1 +x:1 +冰盖层 1 +x:1 +护围 1 +x:1 +半部论语 1 +x:1 +探 59 +x:59 +参院 1 +x:1 +此一时 1 +x:1 +图书馆 1 +x:1 +叮叮当当 1 +x:1 +随意型 1 +x:1 +面包业 1 +x:1 +并用 1 +x:1 +人缘 1 +x:1 +假肢 1 +x:1 +志峰队 1 +x:1 +听由 1 +x:1 +盟书 1 +x:1 +中短篇 1 +x:1 +屑微 1 +x:1 +敬若神明 1 +x:1 +参阅 1 +x:1 +密麻麻 1 +x:1 +工业展 1 +x:1 +相映 1 +x:1 +探身 1 +x:1 +北美洲 1 +x:1 +哥老会 1 +x:1 +图书节 1 +x:1 +大会战 1 +x:1 +思新求变 1 +x:1 +工业局 1 +x:1 +心口不一 1 +x:1 +盟主 1 +x:1 +泉声 1 +x:1 +无花果 1 +x:1 +偶发性 1 +x:1 +制发 1 +x:1 +制取 1 +x:1 +古冶区 1 +x:1 +纯水厂 1 +x:1 +代办站 1 +x:1 +金花 1 +x:1 +健身操 1 +x:1 +消夏厅 1 +x:1 +间距 1 +x:1 +罗汉 1 +x:1 +老城 1 +x:1 +排挤 1 +x:1 +护翼 1 +x:1 +万盛区 1 +x:1 +品茗 1 +x:1 +未知 1 +x:1 +常德市 1 +x:1 +修理组 1 +x:1 +必需 1 +x:1 +大鱼洞 1 +x:1 +地理学 1 +x:1 +潜游 1 +x:1 +品茶 1 +x:1 +一个劲儿 1 +x:1 +无名肿毒 1 +x:1 +享清福 1 +x:1 +发纵指示 1 +x:1 +利空 1 +x:1 +车尔臣河 1 +x:1 +异见 1 +x:1 +高尔基路 1 +x:1 +扶助 1 +x:1 +铺锦叠翠 1 +x:1 +纸龙舞 1 +x:1 +外耳 1 +x:1 +平平稳稳 1 +x:1 +过细 1 +x:1 +坑口 1 +x:1 +蒸腾 1 +x:1 +种仁 1 +x:1 +万福街 1 +x:1 +三边 1 +x:1 +制剂 1 +x:1 +决策法 1 +x:1 +傻气 1 +x:1 +友好 1 +x:1 +厢式 1 +x:1 +收款机 1 +x:1 +悲喜交加 1 +x:1 +停车 1 +x:1 +选书者 1 +x:1 +抓举 1 +x:1 +一身正气 1 +x:1 +市场局 1 +x:1 +欲望 1 +x:1 +粪堆 1 +x:1 +放 738 +x:738 +征集箱 1 +x:1 +寻亲 1 +x:1 +录用者 1 +x:1 +资本性 1 +x:1 +觉悟 1 +x:1 +护罩 1 +x:1 +制动 1 +x:1 +高效益 1 +x:1 +签署 1 +x:1 +民警 1 +x:1 +定义 1 +x:1 +紧缺 1 +x:1 +凝重 1 +x:1 +检察 1 +x:1 +紧缩 1 +x:1 +脚钉 1 +x:1 +清幽谷 1 +x:1 +吹响 1 +x:1 +排排 1 +x:1 +南昌县 1 +x:1 +电视屏 1 +x:1 +单向 1 +x:1 +眯 7 +x:7 +单名 1 +x:1 +主管局 1 +x:1 +挟持 1 +x:1 +西吉 1 +x:1 +三轮 1 +x:1 +司法界 1 +x:1 +就绪 1 +x:1 +客帮 1 +x:1 +登陆战 1 +x:1 +平起平坐 1 +x:1 +连任 1 +x:1 +乙厂 1 +x:1 +配套化 1 +x:1 +相机 1 +x:1 +西周 1 +x:1 +检定 1 +x:1 +个性 1 +x:1 +结束语 1 +x:1 +老土 1 +x:1 +滑跑 1 +x:1 +坏蛋 1 +x:1 +符合率 1 +x:1 +春和镇 1 +x:1 +生命体 1 +x:1 +相望 1 +x:1 +头盖骨 1 +x:1 +倒塌 1 +x:1 +老场 1 +x:1 +串列 1 +x:1 +动员令 1 +x:1 +实践篇 1 +x:1 +林子 1 +x:1 +救济费 1 +x:1 +独辟蹊径 1 +x:1 +迟效肥料 1 +x:1 +四级一户 1 +x:1 +倒客 1 +x:1 +无论 1 +x:1 +信风 1 +x:1 +驱除 1 +x:1 +火炬 1 +x:1 +作贱 1 +x:1 +可叹 1 +x:1 +哑谜 1 +x:1 +配装 1 +x:1 +斑桃 1 +x:1 +鞍子 1 +x:1 +得失 1 +x:1 +辅具 1 +x:1 +洗炼 1 +x:1 +西垂 1 +x:1 +光宗耀祖 1 +x:1 +发展科 1 +x:1 +单循环制 1 +x:1 +了望 1 +x:1 +就地 1 +x:1 +精英 1 +x:1 +勘测局 1 +x:1 +海洋观 1 +x:1 +灰土 1 +x:1 +盖子 1 +x:1 +授勋 1 +x:1 +仓 16 +x:16 +扶善疾恶 1 +x:1 +潜流 1 +x:1 +构成美 1 +x:1 +新海 1 +x:1 +西域 1 +x:1 +潜海 1 +x:1 +政资 1 +x:1 +港澳办 1 +x:1 +每篇 1 +x:1 +西城 1 +x:1 +生存链 1 +x:1 +委派制 1 +x:1 +相撞 1 +x:1 +茶托 1 +x:1 +系列型 1 +x:1 +扶农 1 +x:1 +望湖楼 1 +x:1 +从古到今 1 +x:1 +传销客 1 +x:1 +未了轩 1 +x:1 +异言 1 +x:1 +喝彩声 1 +x:1 +园林学家 1 +x:1 +海参崴 1 +x:1 +家常菜 1 +x:1 +益鸟 1 +x:1 +值勤警 1 +x:1 +制冷 1 +x:1 +骨灰堂 1 +x:1 +骄气 1 +x:1 +顺境 1 +x:1 +非船舶 1 +x:1 +棚外 1 +x:1 +活活 1 +x:1 +茶技 1 +x:1 +三秦 1 +x:1 +襟翼 1 +x:1 +成大海 1 +x:1 +拖鞋兰 1 +x:1 +高位 1 +x:1 +扶贫户 1 +x:1 +胡志明市 1 +x:1 +挟荔宫 1 +x:1 +石嘴山 1 +x:1 +齿轮厂 1 +x:1 +新浦 1 +x:1 +伏龙桥 1 +x:1 +瀚海 1 +x:1 +预防 1 +x:1 +讼事 1 +x:1 +透湿 1 +x:1 +讼争 1 +x:1 +铜奖 1 +x:1 +本主儿 1 +x:1 +无水草场 1 +x:1 +茶拨 1 +x:1 +噤口痢 1 +x:1 +精良 1 +x:1 +破旧立新 1 +x:1 +浓眉大眼 1 +x:1 +老河口市 1 +x:1 +毛举细故 1 +x:1 +浇底乡 1 +x:1 +作践 1 +x:1 +柜橱 1 +x:1 +净化器 1 +x:1 +牛年 1 +x:1 +专业科 1 +x:1 +西坑 1 +x:1 +柏埔镇 1 +x:1 +玻璃 1 +x:1 +假若 1 +x:1 +桃花运 1 +x:1 +地炮旅 1 +x:1 +咆哮 1 +x:1 +惊雷 1 +x:1 +雷锋式 1 +x:1 +港澳台 1 +x:1 +孟家庄镇 1 +x:1 +铜墙 1 +x:1 +履舄交错 1 +x:1 +不慌不乱 1 +x:1 +营部 1 +x:1 +消解性 1 +x:1 +开平市 1 +x:1 +军科院 1 +x:1 +潜水 1 +x:1 +绞尽 1 +x:1 +异议 1 +x:1 +炭 12 +x:12 +律师法 1 +x:1 +洗熨 1 +x:1 +参政会 1 +x:1 +欧航局 1 +x:1 +评论员 1 +x:1 +力竭声嘶 1 +x:1 +水保局 1 +x:1 +得到 1 +x:1 +板壁房 1 +x:1 +潜江 1 +x:1 +背带式 1 +x:1 +停赛 1 +x:1 +喇叭裤 1 +x:1 +剩磁 1 +x:1 +不肖子孙 1 +x:1 +硫化黑 1 +x:1 +崆峒岛 1 +x:1 +现在时 1 +x:1 +滑轮 1 +x:1 +铜壶 1 +x:1 +巴县 1 +x:1 +西四 1 +x:1 +交通部长 1 +x:1 +制假 1 +x:1 +要好 1 +x:1 +何许人 1 +x:1 +阵地 1 +x:1 +吹嘘 1 +x:1 +远古 1 +x:1 +长期化 1 +x:1 +假药 1 +x:1 +制做 1 +x:1 +口哨儿 1 +x:1 +染缸 1 +x:1 +竞职者 1 +x:1 +投诉量 1 +x:1 +展示 1 +x:1 +探路 1 +x:1 +富存区 1 +x:1 +柞林 1 +x:1 +紧紧 1 +x:1 +洛市 1 +x:1 +防守 1 +x:1 +三资 1 +x:1 +无言 1 +x:1 +内陆国 1 +x:1 +老弱残兵 1 +x:1 +荷兰籍 1 +x:1 +踩 83 +x:83 +三走 1 +x:1 +智商 1 +x:1 +沾化 1 +x:1 +潜油 1 +x:1 +落入者 1 +x:1 +宰 33 +x:33 +贯彻 1 +x:1 +腿腕子 1 +x:1 +相救 1 +x:1 +修理厂 1 +x:1 +远南 1 +x:1 +地雷阵 1 +x:1 +佟麟阁 1 +x:1 +安康市 1 +x:1 +防寒 1 +x:1 +练习簿 1 +x:1 +水险 1 +x:1 +自讨没趣 1 +x:1 +燕尾服 1 +x:1 +察明 1 +x:1 +三仙村 1 +x:1 +单家独户 1 +x:1 +人类 1 +x:1 +岂有此理 1 +x:1 +乡邻 1 +x:1 +萨军 1 +x:1 +洗煤 1 +x:1 +浸人心脾 1 +x:1 +洞悉 1 +x:1 +县境 1 +x:1 +遭 202 +x:202 +三贷 1 +x:1 +勘测工 1 +x:1 +越权 1 +x:1 +年薪 1 +x:1 +规定价 1 +x:1 +动员会 1 +x:1 +样书 1 +x:1 +展线 1 +x:1 +逊克县 1 +x:1 +中子态 1 +x:1 +袒露 1 +x:1 +远房亲戚 1 +x:1 +面授机宜 1 +x:1 +寒山寺 1 +x:1 +防霜林 1 +x:1 +四边地 1 +x:1 +防尘 1 +x:1 +过场 1 +x:1 +精诚团结 1 +x:1 +签章 1 +x:1 +老勘 1 +x:1 +个旧 1 +x:1 +张茹集乡 1 +x:1 +临汾市 1 +x:1 +英语角 1 +x:1 +上岗者 1 +x:1 +榨菜量 1 +x:1 +子规 1 +x:1 +圆溜溜 1 +x:1 +青春颂 1 +x:1 +耸 9 +x:9 +织梭 1 +x:1 +后方 1 +x:1 +豁达 1 +x:1 +生活舱 1 +x:1 +常务 1 +x:1 +银行界 1 +x:1 +制造商 1 +x:1 +令人神往 1 +x:1 +砌起 1 +x:1 +基金额 1 +x:1 +得当 1 +x:1 +曲水流觞 1 +x:1 +融洽 1 +x:1 +猿声 1 +x:1 +扩张式 1 +x:1 +相抵 1 +x:1 +厥词 1 +x:1 +长老塔 1 +x:1 +送报 1 +x:1 +四重唱 1 +x:1 +串味 1 +x:1 +英资 1 +x:1 +誊印 1 +x:1 +洪山乡 1 +x:1 +芬兰 1 +x:1 +智力 1 +x:1 +陈规陋习 1 +x:1 +缆车厢 1 +x:1 +财贸处 1 +x:1 +幸福 1 +x:1 +报警器业 1 +x:1 +中选 1 +x:1 +宣传科 1 +x:1 +源程序 1 +x:1 +个数 1 +x:1 +住居 1 +x:1 +农机棚 1 +x:1 +研讨 1 +x:1 +荒淫无耻 1 +x:1 +桐庐县 1 +x:1 +目标论 1 +x:1 +林庄乡 1 +x:1 +骄横 1 +x:1 +下压力 1 +x:1 +分拣机 1 +x:1 +山峦 1 +x:1 +求雨 1 +x:1 +凝铸 1 +x:1 +风火轮 1 +x:1 +凯鲁万市 1 +x:1 +查结率 1 +x:1 +画画 1 +x:1 +白毛女 1 +x:1 +善善恶恶 1 +x:1 +模分布论 1 +x:1 +精萃 1 +x:1 +顾忌 1 +x:1 +百分制 1 +x:1 +侍应 1 +x:1 +高效率 1 +x:1 +研读 1 +x:1 +就算 1 +x:1 +单兵 1 +x:1 +苟且 1 +x:1 +西关 1 +x:1 +基因羊 1 +x:1 +夕阳 1 +x:1 +得志 1 +x:1 +化解 1 +x:1 +体循环 1 +x:1 +响音 1 +x:1 +作证 1 +x:1 +兴师问罪 1 +x:1 +比做 1 +x:1 +作词 1 +x:1 +年节 1 +x:1 +奥勒松市 1 +x:1 +民工队 1 +x:1 +护税 1 +x:1 +愤世嫉俗 1 +x:1 +授命 1 +x:1 +羞辱 1 +x:1 +大堤脚 1 +x:1 +挥汗如雨 1 +x:1 +老到 1 +x:1 +通俗类 1 +x:1 +无赖 1 +x:1 +汇珍楼 1 +x:1 +耦合 1 +x:1 +颤栗 1 +x:1 +杏仁露 1 +x:1 +车行道 1 +x:1 +单元 1 +x:1 +百分号 1 +x:1 +西撒哈拉 1 +x:1 +阂 1 +x:1 +对顶角 1 +x:1 +酸牛奶 1 +x:1 +老友 1 +x:1 +绝对温度 1 +x:1 +撂下 1 +x:1 +扶困 1 +x:1 +明细单 1 +x:1 +鸭嘴龙 1 +x:1 +鞍山 1 +x:1 +检录 1 +x:1 +三证 1 +x:1 +三评 1 +x:1 +老叟 1 +x:1 +融汇 1 +x:1 +挥发酚 1 +x:1 +济济 1 +x:1 +异趣 1 +x:1 +承包者 1 +x:1 +雄图大略 1 +x:1 +骨架子 1 +x:1 +智取 1 +x:1 +保险费用 1 +x:1 +漏子 1 +x:1 +掉以轻心 1 +x:1 +外销额 1 +x:1 +相接 1 +x:1 +史学观 1 +x:1 +横栏镇 1 +x:1 +完全性 1 +x:1 +三论 1 +x:1 +离乡背井 1 +x:1 +前进不懈 1 +x:1 +山重山 1 +x:1 +四川籍 1 +x:1 +三讲 1 +x:1 +西园乡 1 +x:1 +话机 1 +x:1 +敦促 1 +x:1 +学术类 1 +x:1 +脱口道出 1 +x:1 +展翅 1 +x:1 +话本 1 +x:1 +胶鞋厂 1 +x:1 +巴黎城 1 +x:1 +踺子 1 +x:1 +年菜 1 +x:1 +犬牙交错 1 +x:1 +探询 1 +x:1 +内存储器 1 +x:1 +关塔港 1 +x:1 +融注 1 +x:1 +百思不解 1 +x:1 +三禁 1 +x:1 +话柄 1 +x:1 +大包小袋 1 +x:1 +铜币 1 +x:1 +活火 1 +x:1 +全封闭式 1 +x:1 +过程 1 +x:1 +排枪 1 +x:1 +贺岁杯 1 +x:1 +生长率 1 +x:1 +顺畅 1 +x:1 +签筒 1 +x:1 +间隙 1 +x:1 +异质 1 +x:1 +收购权 1 +x:1 +无谓 1 +x:1 +疑心 1 +x:1 +撕碎 1 +x:1 +节骨眼 1 +x:1 +正逢 1 +x:1 +花鸟 1 +x:1 +衍生 1 +x:1 +农字号 1 +x:1 +毒饵 1 +x:1 +内部化 1 +x:1 +中短线 1 +x:1 +营业执照 1 +x:1 +养鱼池 1 +x:1 +农业队 1 +x:1 +支脉 1 +x:1 +泉州 1 +x:1 +护符 1 +x:1 +情文并茂 1 +x:1 +东方城 1 +x:1 +探讨 1 +x:1 +排查 1 +x:1 +白糖水 1 +x:1 +老化 1 +x:1 +时评 1 +x:1 +探访 1 +x:1 +哑语 1 +x:1 +制图 1 +x:1 +条款 1 +x:1 +马列 1 +x:1 +停课 1 +x:1 +牦牛 1 +x:1 +豌豆粉 1 +x:1 +弄臣 1 +x:1 +八三年 1 +x:1 +太极拳队 1 +x:1 +女 2352 +x:2352 +年莫 1 +x:1 +绥宁县 1 +x:1 +老区 1 +x:1 +银号 1 +x:1 +音响展 1 +x:1 +胜进村 1 +x:1 +博尔伦格 1 +x:1 +单县 1 +x:1 +西去 1 +x:1 +助力车 1 +x:1 +制售 1 +x:1 +阵前 1 +x:1 +欠佳 1 +x:1 +新民 1 +x:1 +谢忱 1 +x:1 +马尾藻 1 +x:1 +慈心 1 +x:1 +说三道四 1 +x:1 +西厢 1 +x:1 +任性 1 +x:1 +大藏经 1 +x:1 +伤亡率 1 +x:1 +平头楼村 1 +x:1 +扬扬 1 +x:1 +浙江团 1 +x:1 +推介 1 +x:1 +媾和 1 +x:1 +正常性 1 +x:1 +会务费 1 +x:1 +紧张症 1 +x:1 +押运 1 +x:1 +无辜 1 +x:1 +单厂 1 +x:1 +勃 8 +x:8 +活现 1 +x:1 +无理根 1 +x:1 +紧缺性 1 +x:1 +阵列 1 +x:1 +铜川 1 +x:1 +斟酒 1 +x:1 +彼得保罗 1 +x:1 +市场学 1 +x:1 +斟酌 1 +x:1 +古道热肠 1 +x:1 +敖拜淖尔 1 +x:1 +茶晶 1 +x:1 +顶牛儿 1 +x:1 +式样 1 +x:1 +一定会计 1 +x:1 +酚 4 +x:4 +西口 1 +x:1 +年老 1 +x:1 +企管 1 +x:1 +人种 1 +x:1 +琅环 1 +x:1 +窑壁 1 +x:1 +无过 1 +x:1 +利在子孙 1 +x:1 +一步登天 1 +x:1 +个人股 1 +x:1 +租者 1 +x:1 +过秤 1 +x:1 +人秘 1 +x:1 +几比 1 +x:1 +托拉司 1 +x:1 +药力 1 +x:1 +原型机 1 +x:1 +饥馑 1 +x:1 +引进者 1 +x:1 +停表 1 +x:1 +省 1890 +x:1890 +灰发 1 +x:1 +磷酸盐 1 +x:1 +西区 1 +x:1 +阅览证 1 +x:1 +赤卫队 1 +x:1 +警署 1 +x:1 +腮片 1 +x:1 +胆汁 1 +x:1 +饥饿 1 +x:1 +凝集 1 +x:1 +漏壶 1 +x:1 +帛 2 +x:2 +酶类 1 +x:1 +生长点 1 +x:1 +投资热 1 +x:1 +拨通 1 +x:1 +快攻型 1 +x:1 +西北 1 +x:1 +西化 1 +x:1 +条桌 1 +x:1 +倒弄 1 +x:1 +骂架 1 +x:1 +射击队 1 +x:1 +集训队员 1 +x:1 +设 481 +x:481 +票面 1 +x:1 +坎肩 1 +x:1 +净化剂 1 +x:1 +推举 1 +x:1 +倒影 1 +x:1 +小个子 1 +x:1 +流莺 1 +x:1 +无轨 1 +x:1 +参选 1 +x:1 +寄生虫 1 +x:1 +精虫 1 +x:1 +人祸 1 +x:1 +李树 1 +x:1 +得州 1 +x:1 +品蓝 1 +x:1 +倒彩 1 +x:1 +结帮拉派 1 +x:1 +寞 1 +x:1 +菜粉蝶 1 +x:1 +着眼 1 +x:1 +系列化 1 +x:1 +西南 1 +x:1 +核糖 1 +x:1 +西单 1 +x:1 +热饮 1 +x:1 +七八月 1 +x:1 +西华 1 +x:1 +二连星 1 +x:1 +厚实实 1 +x:1 +蓉园 1 +x:1 +相思 1 +x:1 +两重性 1 +x:1 +庄园主 1 +x:1 +茹苦含辛 1 +x:1 +开封县 1 +x:1 +竹纸 1 +x:1 +没日没夜 1 +x:1 +排放 1 +x:1 +三角 1 +x:1 +浪劲 1 +x:1 +电缆桥 1 +x:1 +核武器化 1 +x:1 +如影随形 1 +x:1 +三观 1 +x:1 +睡姿 1 +x:1 +雇佣劳动 1 +x:1 +倒底 1 +x:1 +声称 1 +x:1 +财政 1 +x:1 +南线堤 1 +x:1 +中西医界 1 +x:1 +工业家 1 +x:1 +匹马单枪 1 +x:1 +作用力 1 +x:1 +微瑕 1 +x:1 +文艺复兴 1 +x:1 +社会科学 1 +x:1 +沽 1 +x:1 +盖帽 1 +x:1 +文本化 1 +x:1 +撞钟 1 +x:1 +雁 86 +x:86 +浔阳城 1 +x:1 +他律 1 +x:1 +万绿丛中 1 +x:1 +热风 1 +x:1 +安理会 1 +x:1 +茶杯 1 +x:1 +芽接 1 +x:1 +展厅 1 +x:1 +过磅 1 +x:1 +利刀 1 +x:1 +三要 1 +x:1 +满目 1 +x:1 +老农 1 +x:1 +日温月痕 1 +x:1 +谢庄 1 +x:1 +靳三针 1 +x:1 +铮亮 1 +x:1 +惯性力 1 +x:1 +光合 1 +x:1 +莲华经 1 +x:1 +藏琼玛 1 +x:1 +送料口 1 +x:1 +瑕瑜互见 1 +x:1 +短少 1 +x:1 +旗人 1 +x:1 +无绳机 1 +x:1 +都水 1 +x:1 +液化 1 +x:1 +腐朽性 1 +x:1 +老兄 1 +x:1 +工矿区 1 +x:1 +淹城 1 +x:1 +小人儿书 1 +x:1 +紫乌 1 +x:1 +排斥 1 +x:1 +效益带 1 +x:1 +单利 1 +x:1 +系列剧 1 +x:1 +活物 1 +x:1 +文化日 1 +x:1 +脚后跟 1 +x:1 +上下学 1 +x:1 +繁星 1 +x:1 +扳回 1 +x:1 +割伤 1 +x:1 +探视 1 +x:1 +远郊区 1 +x:1 +三西 1 +x:1 +西刘 1 +x:1 +秽土 1 +x:1 +顺着 1 +x:1 +审时度势 1 +x:1 +谢幕 1 +x:1 +鲲 6 +x:6 +老兵 1 +x:1 +防御 1 +x:1 +根特市 1 +x:1 +乱糟糟 1 +x:1 +发放站 1 +x:1 +基本系 1 +x:1 +襟章 1 +x:1 +支配权 1 +x:1 +数十亿计 1 +x:1 +规律 1 +x:1 +防疫法 1 +x:1 +不鸣则已 1 +x:1 +掂量 1 +x:1 +行为法 1 +x:1 +音容 1 +x:1 +展台 1 +x:1 +暴风 1 +x:1 +娇滴滴 1 +x:1 +蓉城 1 +x:1 +无愧于 1 +x:1 +串城 1 +x:1 +宁安市 1 +x:1 +上市户 1 +x:1 +蟠桃 1 +x:1 +推优 1 +x:1 +房地局 1 +x:1 +敲敲 1 +x:1 +响铃 1 +x:1 +铜山 1 +x:1 +舌鳎 1 +x:1 +片儿 1 +x:1 +瘘管 1 +x:1 +异轨 1 +x:1 +先遣队 1 +x:1 +健身房 1 +x:1 +谢帖 1 +x:1 +分光计 1 +x:1 +五虎岭 1 +x:1 +过硬 1 +x:1 +脑栓塞 1 +x:1 +老儿 1 +x:1 +报纸者 1 +x:1 +剖析性 1 +x:1 +增购 1 +x:1 +修造厂 1 +x:1 +秋吉台 1 +x:1 +滑落 1 +x:1 +用典 1 +x:1 +飞檐走壁 1 +x:1 +承包费 1 +x:1 +报刊费 1 +x:1 +杂乱不堪 1 +x:1 +工业病 1 +x:1 +四重奏 1 +x:1 +滑头滑脑 1 +x:1 +跨越式 1 +x:1 +石家庄市 1 +x:1 +大湖地村 1 +x:1 +戈壁滩 1 +x:1 +前所未闻 1 +x:1 +泥浆 1 +x:1 +暴露 1 +x:1 +有请 1 +x:1 +征收率 1 +x:1 +茶树 1 +x:1 +未经 1 +x:1 +巴士 1 +x:1 +有误 1 +x:1 +不无裨益 1 +x:1 +面大量多 1 +x:1 +护盒 1 +x:1 +大许屯 1 +x:1 +老庄 1 +x:1 +叶芽儿 1 +x:1 +庄户人 1 +x:1 +申请者 1 +x:1 +价目表 1 +x:1 +济 29 +x:29 +防假 1 +x:1 +老底 1 +x:1 +茶桶 1 +x:1 +半死不活 1 +x:1 +西工 1 +x:1 +工业品 1 +x:1 +眉宇 1 +x:1 +播报 1 +x:1 +仓山区 1 +x:1 +宣传画 1 +x:1 +居委会 1 +x:1 +穷则思变 1 +x:1 +抗旱 1 +x:1 +衰颜老态 1 +x:1 +茶桌 1 +x:1 +难者 1 +x:1 +蒺藜 1 +x:1 +还击 1 +x:1 +抛开 1 +x:1 +取款机 1 +x:1 +异能 1 +x:1 +精装 1 +x:1 +上档次 1 +x:1 +西崽 1 +x:1 +眦决嘴裂 1 +x:1 +经货联盟 1 +x:1 +正邪 1 +x:1 +鞭炮声 1 +x:1 +会费额 1 +x:1 +肴馔 1 +x:1 +蓄积性 1 +x:1 +人眼 1 +x:1 +露出 1 +x:1 +邮通 1 +x:1 +订价 1 +x:1 +参选人 1 +x:1 +台联会 1 +x:1 +寄生蟹 1 +x:1 +细木工板 1 +x:1 +缴送 1 +x:1 +坐享其成 1 +x:1 +照转 1 +x:1 +合瓣花冠 1 +x:1 +在此一举 1 +x:1 +铜匾 1 +x:1 +播扬 1 +x:1 +过眼 1 +x:1 +水磨石 1 +x:1 +中编办 1 +x:1 +追究制 1 +x:1 +辅导 1 +x:1 +琳 87 +x:87 +鄙人 1 +x:1 +老年 1 +x:1 +铜匠 1 +x:1 +藏装 1 +x:1 +泥淖 1 +x:1 +制宜 1 +x:1 +老幼 1 +x:1 +利率 1 +x:1 +孤儿 1 +x:1 +老师 1 +x:1 +安全电压 1 +x:1 +太阳历 1 +x:1 +白细胞 1 +x:1 +水岸线 1 +x:1 +倒入 1 +x:1 +假装 1 +x:1 +玻纤 1 +x:1 +制导 1 +x:1 +乳白色 1 +x:1 +牛奶 1 +x:1 +给面子 1 +x:1 +老帮 1 +x:1 +双凤山 1 +x:1 +眼际 1 +x:1 +大山包乡 1 +x:1 +石油气 1 +x:1 +精血 1 +x:1 +更生 1 +x:1 +宛转 1 +x:1 +罗方 1 +x:1 +俯仰 1 +x:1 +投资署 1 +x:1 +得分 1 +x:1 +坑害 1 +x:1 +护短 1 +x:1 +西岸 1 +x:1 +西岳 1 +x:1 +凯里市 1 +x:1 +千变万化 1 +x:1 +仪表美 1 +x:1 +高楼大厦 1 +x:1 +亵渎 1 +x:1 +车模 1 +x:1 +热障 1 +x:1 +喇叭花 1 +x:1 +颜体 1 +x:1 +支路 1 +x:1 +交战国 1 +x:1 +亥 1 +x:1 +年轻 1 +x:1 +硫化钠 1 +x:1 +教七楼 1 +x:1 +西岗 1 +x:1 +得利 1 +x:1 +年轮 1 +x:1 +钢瓶厂 1 +x:1 +探究反射 1 +x:1 +击弦机 1 +x:1 +型钢 1 +x:1 +围障 1 +x:1 +厚意 1 +x:1 +灰尘 1 +x:1 +县宝 1 +x:1 +扒 18 +x:18 +河面 1 +x:1 +泥水 1 +x:1 +殷纣王 1 +x:1 +大吹大擂 1 +x:1 +茶楼 1 +x:1 +西峡 1 +x:1 +无能 1 +x:1 +晚霜 1 +x:1 +东方学 1 +x:1 +柑桔 1 +x:1 +晋 79 +x:79 +县官 1 +x:1 +招展团 1 +x:1 +衰落 1 +x:1 +腐蚀 1 +x:1 +测字 1 +x:1 +过目 1 +x:1 +染病 1 +x:1 +条条 1 +x:1 +雀跃 1 +x:1 +痛定思痛 1 +x:1 +糕点 1 +x:1 +麻经儿 1 +x:1 +与生俱有 1 +x:1 +过门儿 1 +x:1 +牛鼻子 1 +x:1 +面值 1 +x:1 +乌礁湾 1 +x:1 +轻声 1 +x:1 +供给量 1 +x:1 +童装部 1 +x:1 +细布 1 +x:1 +无耻 1 +x:1 +热队 1 +x:1 +陈埭镇 1 +x:1 +得力 1 +x:1 +铜制 1 +x:1 +羽绒厂 1 +x:1 +系列展 1 +x:1 +悦 31 +x:31 +过瘾 1 +x:1 +浪尖 1 +x:1 +防冻 1 +x:1 +通经活络 1 +x:1 +候船室 1 +x:1 +泥泞 1 +x:1 +后继有人 1 +x:1 +得劲 1 +x:1 +见状 1 +x:1 +得势 1 +x:1 +忘恩负义 1 +x:1 +漂儿 1 +x:1 +烹饪 1 +x:1 +品评 1 +x:1 +圣迭戈 1 +x:1 +扩张力 1 +x:1 +授奖 1 +x:1 +西山 1 +x:1 +泥沼 1 +x:1 +在途资金 1 +x:1 +年辈 1 +x:1 +出租率 1 +x:1 +防凌 1 +x:1 +有言 1 +x:1 +老弟 1 +x:1 +谱架 1 +x:1 +排比 1 +x:1 +斯土 1 +x:1 +统一制 1 +x:1 +老弦 1 +x:1 +无聊 1 +x:1 +死心眼 1 +x:1 +涉足 1 +x:1 +电建 1 +x:1 +无职 1 +x:1 +大河乡 1 +x:1 +泥沙 1 +x:1 +暴雨 1 +x:1 +尸体 1 +x:1 +品读 1 +x:1 +沙头角镇 1 +x:1 +单层 1 +x:1 +泥潭 1 +x:1 +试漂 1 +x:1 +发案地 1 +x:1 +追名逐利 1 +x:1 +竹竿 1 +x:1 +词曲论 1 +x:1 +西德 1 +x:1 +投资类 1 +x:1 +哪样 1 +x:1 +蓉花山 1 +x:1 +下半 1 +x:1 +沏 2 +x:2 +鼓点子 1 +x:1 +送法 1 +x:1 +顺风转舵 1 +x:1 +假言 1 +x:1 +徙 1 +x:1 +七手八脚 1 +x:1 +无限量 1 +x:1 +集装箱船 1 +x:1 +菌落 1 +x:1 +虚构论 1 +x:1 +金圆券 1 +x:1 +迫不得已 1 +x:1 +十年树木 1 +x:1 +新传 1 +x:1 +山羊洼 1 +x:1 +铜冠 1 +x:1 +哑然无声 1 +x:1 +清虚观 1 +x:1 +考上 1 +x:1 +手到擒来 1 +x:1 +倒台 1 +x:1 +新余 1 +x:1 +条播 1 +x:1 +品行 1 +x:1 +新作 1 +x:1 +时调 1 +x:1 +决策人 1 +x:1 +排档 1 +x:1 +南瓜子 1 +x:1 +妇委会 1 +x:1 +气流 1 +x:1 +规划 1 +x:1 +工业国 1 +x:1 +宁安县 1 +x:1 +爆炸力 1 +x:1 +还口 1 +x:1 +安口镇 1 +x:1 +杀手锏 1 +x:1 +年谱 1 +x:1 +工业园 1 +x:1 +忙活 1 +x:1 +铝锭 1 +x:1 +微音器 1 +x:1 +沪指 1 +x:1 +热闹 1 +x:1 +鱼摊 1 +x:1 +远祖 1 +x:1 +热销 1 +x:1 +京剧院团 1 +x:1 +闹病 1 +x:1 +老屋 1 +x:1 +通电 1 +x:1 +单弱 1 +x:1 +说情者 1 +x:1 +统一党 1 +x:1 +家常话 1 +x:1 +灰心 1 +x:1 +徐谷店村 1 +x:1 +慈协 1 +x:1 +活罪 1 +x:1 +单弦 1 +x:1 +单张 1 +x:1 +代办点 1 +x:1 +棋牌室 1 +x:1 +过电 1 +x:1 +勐仑 1 +x:1 +收购案 1 +x:1 +争鲜斗艳 1 +x:1 +热键 1 +x:1 +窝主 1 +x:1 +西式 1 +x:1 +单式 1 +x:1 +人生 1 +x:1 +漂到 1 +x:1 +防务 1 +x:1 +人尽其材 1 +x:1 +芨芨草 1 +x:1 +指挥部 1 +x:1 +市场型 1 +x:1 +出气筒 1 +x:1 +中国字 1 +x:1 +新鲜事儿 1 +x:1 +老将 1 +x:1 +电解槽 1 +x:1 +绍酒 1 +x:1 +百分尺 1 +x:1 +老小 1 +x:1 +南岗区 1 +x:1 +老少 1 +x:1 +规劝 1 +x:1 +送气 1 +x:1 +八重樱 1 +x:1 +报时钟 1 +x:1 +一总 1 +x:1 +泉勇 1 +x:1 +无影灯 1 +x:1 +人界 1 +x:1 +工业界 1 +x:1 +倒卖 1 +x:1 +听罢 1 +x:1 +深更半夜 1 +x:1 +练习生 1 +x:1 +护理 1 +x:1 +坑塘 1 +x:1 +复种指数 1 +x:1 +雷锋团 1 +x:1 +眉头 1 +x:1 +屯 2 +x:2 +通信股 1 +x:1 +一声不吭 1 +x:1 +伽马仪 1 +x:1 +洒遍 1 +x:1 +三营 1 +x:1 +得出 1 +x:1 +胆怯 1 +x:1 +土油灯 1 +x:1 +无理数 1 +x:1 +防化 1 +x:1 +疑兵 1 +x:1 +生长素 1 +x:1 +防办 1 +x:1 +专病 1 +x:1 +西康 1 +x:1 +圈 151 +x:151 +喃语 1 +x:1 +经卷 1 +x:1 +新丁 1 +x:1 +三藏 1 +x:1 +魁首 1 +x:1 +无形损耗 1 +x:1 +历史性 1 +x:1 +年资 1 +x:1 +基本功 1 +x:1 +活结 1 +x:1 +新丰 1 +x:1 +老巢 1 +x:1 +合兴乡 1 +x:1 +两性生殖 1 +x:1 +木 73 +x:73 +单店 1 +x:1 +格律体 1 +x:1 +防区 1 +x:1 +活络 1 +x:1 +排椅 1 +x:1 +求饶 1 +x:1 +吴家营乡 1 +x:1 +相伴 1 +x:1 +老巷 1 +x:1 +特教班 1 +x:1 +西庄 1 +x:1 +企盼 1 +x:1 +阵形 1 +x:1 +开封市 1 +x:1 +精读 1 +x:1 +串子 1 +x:1 +生活费 1 +x:1 +特异质 1 +x:1 +壳子 1 +x:1 +钟体 1 +x:1 +新泰 1 +x:1 +降雨 1 +x:1 +熔于一炉 1 +x:1 +灰市 1 +x:1 +阵式 1 +x:1 +养痈遗患 1 +x:1 +铜像 1 +x:1 +条施 1 +x:1 +精详 1 +x:1 +炎陵县 1 +x:1 +经济主义 1 +x:1 +条文 1 +x:1 +柑橘 1 +x:1 +久而久之 1 +x:1 +茶歌 1 +x:1 +一字一句 1 +x:1 +条斑 1 +x:1 +一成不变 1 +x:1 +新乡 1 +x:1 +海洋能 1 +x:1 +毛毛雨 1 +x:1 +支边 1 +x:1 +年货 1 +x:1 +转弯处 1 +x:1 +沟门乡 1 +x:1 +防卫 1 +x:1 +老官地乡 1 +x:1 +市厅县级 1 +x:1 +降雪 1 +x:1 +齐步走 1 +x:1 +好言相劝 1 +x:1 +蓝白色 1 +x:1 +装运量 1 +x:1 +单帮 1 +x:1 +个人赛 1 +x:1 +科头跣足 1 +x:1 +区段 1 +x:1 +非可溶性 1 +x:1 +平谷县镇 1 +x:1 +话闸子 1 +x:1 +炸药 1 +x:1 +够朋友 1 +x:1 +波光云影 1 +x:1 +阿拉伯湾 1 +x:1 +扶贫款 1 +x:1 +累放 1 +x:1 +新人 1 +x:1 +假设 1 +x:1 +织机 1 +x:1 +安科纳 1 +x:1 +职能性 1 +x:1 +新交 1 +x:1 +西师 1 +x:1 +洗礼 1 +x:1 +萨姆 1 +x:1 +西市 1 +x:1 +空政 1 +x:1 +遮风避雨 1 +x:1 +千里光 1 +x:1 +跨学科 1 +x:1 +假话 1 +x:1 +明末清初 1 +x:1 +西平 1 +x:1 +冥思苦想 1 +x:1 +单干 1 +x:1 +无色 1 +x:1 +良种稻 1 +x:1 +尽管 1 +x:1 +岩爆 1 +x:1 +假证 1 +x:1 +无声无臭 1 +x:1 +精警 1 +x:1 +假说 1 +x:1 +节假日 1 +x:1 +刮目 1 +x:1 +字帖 1 +x:1 +新任 1 +x:1 +眼镜 1 +x:1 +交头接耳 1 +x:1 +尘埃云 1 +x:1 +独当一面 1 +x:1 +过境费 1 +x:1 +构陷 1 +x:1 +基本点 1 +x:1 +上荣下辱 1 +x:1 +辛丑 1 +x:1 +派发 1 +x:1 +有违 1 +x:1 +娄 23 +x:23 +东方市 1 +x:1 +真儿 1 +x:1 +修理班 1 +x:1 +伊始 1 +x:1 +编辑家 1 +x:1 +桥涵 1 +x:1 +茶水 1 +x:1 +鉴定组 1 +x:1 +鱼水情浓 1 +x:1 +一刀切 1 +x:1 +眉心 1 +x:1 +编辑室 1 +x:1 +交变电场 1 +x:1 +符号论 1 +x:1 +未竟 1 +x:1 +坑底 1 +x:1 +吹奏 1 +x:1 +朱庄乡 1 +x:1 +汉武帝 1 +x:1 +学有专长 1 +x:1 +岁数 1 +x:1 +屏障 1 +x:1 +已 10060 +x:10060 +屯头村 1 +x:1 +办公会 1 +x:1 +停航 1 +x:1 +警铃声 1 +x:1 +洗练 1 +x:1 +刑满释放 1 +x:1 +一目了然 1 +x:1 +铜城 1 +x:1 +四边形 1 +x:1 +粉红色 1 +x:1 +三节 1 +x:1 +可圈可点 1 +x:1 +慈善 1 +x:1 +异国他乡 1 +x:1 +根瘤菌 1 +x:1 +叶盛 1 +x:1 +滑联 1 +x:1 +古北口 1 +x:1 +案发地 1 +x:1 +老媪 1 +x:1 +三段论 1 +x:1 +假象 1 +x:1 +团圆会 1 +x:1 +衣物 1 +x:1 +敢于 1 +x:1 +左膀右臂 1 +x:1 +流动率 1 +x:1 +强强改造 1 +x:1 +测度 1 +x:1 +老婆 1 +x:1 +浪头 1 +x:1 +虾酱 1 +x:1 +西头 1 +x:1 +层高 1 +x:1 +人猿 1 +x:1 +西太 1 +x:1 +西天 1 +x:1 +酚醛塑料 1 +x:1 +茶油 1 +x:1 +媚俗 1 +x:1 +活祭 1 +x:1 +话外音 1 +x:1 +孝敬日 1 +x:1 +签名者 1 +x:1 +非亲胜亲 1 +x:1 +对称轴 1 +x:1 +运球 1 +x:1 +小个儿 1 +x:1 +卡介苗 1 +x:1 +巴山 1 +x:1 +西夏 1 +x:1 +有轨 1 +x:1 +栽种期 1 +x:1 +辛亥 1 +x:1 +巴黎市 1 +x:1 +鱼水情深 1 +x:1 +活动周 1 +x:1 +种棉节 1 +x:1 +迢迢 1 +x:1 +流浪儿 1 +x:1 +区内 1 +x:1 +碱渣土 1 +x:1 +风扇车 1 +x:1 +胆星 1 +x:1 +全方向 1 +x:1 +舌音 1 +x:1 +评论家 1 +x:1 +扩张型 1 +x:1 +扶强 1 +x:1 +叙事学 1 +x:1 +诗体 1 +x:1 +资料片 1 +x:1 +妈湾 1 +x:1 +交战区 1 +x:1 +乱石山村 1 +x:1 +集体性 1 +x:1 +因式 1 +x:1 +拉拉队 1 +x:1 +脱粒 1 +x:1 +大案要案 1 +x:1 +非市场 1 +x:1 +坏话 1 +x:1 +西奈 1 +x:1 +清远市 1 +x:1 +战争贩子 1 +x:1 +卖猪者 1 +x:1 +充分性 1 +x:1 +巴州 1 +x:1 +线路 1 +x:1 +人犯 1 +x:1 +迎头 1 +x:1 +尚书学 1 +x:1 +总理府 1 +x:1 +绞刑 1 +x:1 +骂不还口 1 +x:1 +科班出身 1 +x:1 +万福 1 +x:1 +坐地分赃 1 +x:1 +绞刀 1 +x:1 +制帽 1 +x:1 +排演 1 +x:1 +参议会 1 +x:1 +完税 1 +x:1 +爆肚儿 1 +x:1 +老寨 1 +x:1 +巴巴 1 +x:1 +假货 1 +x:1 +占上风 1 +x:1 +阴凉处 1 +x:1 +正月十四 1 +x:1 +代表队 1 +x:1 +核素 1 +x:1 +相比 1 +x:1 +姨表 1 +x:1 +老宅 1 +x:1 +滑腻 1 +x:1 +地灵人杰 1 +x:1 +辅币 1 +x:1 +抢滩 1 +x:1 +通论式 1 +x:1 +高风险 1 +x:1 +衰老 1 +x:1 +部门级 1 +x:1 +人性美 1 +x:1 +中文版 1 +x:1 +老实 1 +x:1 +三轮儿 1 +x:1 +魏晋 1 +x:1 +少儿式 1 +x:1 +实践史 1 +x:1 +无余量 1 +x:1 +好人家 1 +x:1 +易门 1 +x:1 +老家 1 +x:1 +检场 1 +x:1 +封锁线 1 +x:1 +前南峪村 1 +x:1 +聘用期 1 +x:1 +西壁 1 +x:1 +加德满都 1 +x:1 +通常国会 1 +x:1 +北大西洋 1 +x:1 +病原体 1 +x:1 +袜子 1 +x:1 +制件 1 +x:1 +三荒 1 +x:1 +渍 4 +x:4 +精贵 1 +x:1 +条据 1 +x:1 +老子 1 +x:1 +喝斥 1 +x:1 +因巴巴区 1 +x:1 +耳穴 1 +x:1 +奥克兰 1 +x:1 +谡 1 +x:1 +刀马旦 1 +x:1 +最前沿 1 +x:1 +少儿心 1 +x:1 +吉萨 1 +x:1 +每球 1 +x:1 +构造 1 +x:1 +功劳簿 1 +x:1 +轴瓦 1 +x:1 +宠辱不惊 1 +x:1 +怎么办 1 +x:1 +足够 1 +x:1 +屁 1 +x:1 +裸子植物 1 +x:1 +混合 1 +x:1 +运货舱 1 +x:1 +分光膜 1 +x:1 +心满意足 1 +x:1 +肉铺 1 +x:1 +校勘学 1 +x:1 +胞胎 1 +x:1 +心术 1 +x:1 +偷梁换柱 1 +x:1 +精赤 1 +x:1 +呼吁书 1 +x:1 +旁遮普邦 1 +x:1 +正规军 1 +x:1 +污 24 +x:24 +宣传点 1 +x:1 +海庄 1 +x:1 +捷报频传 1 +x:1 +单塔 1 +x:1 +导电性 1 +x:1 +过牧 1 +x:1 +关 464 +x:464 +利益 1 +x:1 +石沉大海 1 +x:1 +铜器 1 +x:1 +铜矿砂 1 +x:1 +起重机 1 +x:1 +农机手 1 +x:1 +议事权 1 +x:1 +九点钟 1 +x:1 +三胞 1 +x:1 +西家 1 +x:1 +竹箫 1 +x:1 +扁桃体 1 +x:1 +利用 1 +x:1 +屈折语 1 +x:1 +西宫 1 +x:1 +破堰 1 +x:1 +辉耀 1 +x:1 +冷却器 1 +x:1 +漫无止境 1 +x:1 +新合村 1 +x:1 +衰草 1 +x:1 +交道口 1 +x:1 +腐臭 1 +x:1 +排气 1 +x:1 +市场化 1 +x:1 +多多益善 1 +x:1 +三能 1 +x:1 +四川省 1 +x:1 +语义哲学 1 +x:1 +粪坑 1 +x:1 +集体拳 1 +x:1 +箭垛 1 +x:1 +西安 1 +x:1 +伶 2 +x:2 +土窑洞 1 +x:1 +制法 1 +x:1 +西宁 1 +x:1 +太平村 1 +x:1 +参预 1 +x:1 +老境 1 +x:1 +拳道 1 +x:1 +岁月 1 +x:1 +热量 1 +x:1 +护肘 1 +x:1 +明月山村 1 +x:1 +旁听生 1 +x:1 +摔跤队 1 +x:1 +六仙桌 1 +x:1 +无理性 1 +x:1 +播撒 1 +x:1 +停职 1 +x:1 +粪土 1 +x:1 +岁末 1 +x:1 +走火入魔 1 +x:1 +入超 1 +x:1 +颤抖 1 +x:1 +如获至宝 1 +x:1 +有趣 1 +x:1 +重度 1 +x:1 +农机户 1 +x:1 +印第安纳 1 +x:1 +倒地 1 +x:1 +织成 1 +x:1 +品貌 1 +x:1 +竹箱 1 +x:1 +长清县 1 +x:1 +重建论 1 +x:1 +莫斯科 1 +x:1 +风起云涌 1 +x:1 +护灵 1 +x:1 +富集 1 +x:1 +知彼知己 1 +x:1 +临桂县 1 +x:1 +据点 1 +x:1 +优胜奖 1 +x:1 +树行子 1 +x:1 +丰宏 1 +x:1 +编图者 1 +x:1 +入场式 1 +x:1 +礼赞图 1 +x:1 +洛南 1 +x:1 +铁桶 1 +x:1 +盖城 1 +x:1 +市场司 1 +x:1 +笃定 1 +x:1 +不亢不卑 1 +x:1 +听筒 1 +x:1 +笃实 1 +x:1 +挖沙者 1 +x:1 +费钱 1 +x:1 +西学 1 +x:1 +三者 1 +x:1 +游览图 1 +x:1 +无可讳言 1 +x:1 +东莞市 1 +x:1 +中央集权 1 +x:1 +披红戴花 1 +x:1 +打落水狗 1 +x:1 +单孔 1 +x:1 +单字 1 +x:1 +浪子 1 +x:1 +单子 1 +x:1 +患病 1 +x:1 +西子 1 +x:1 +排泄 1 +x:1 +音乐周 1 +x:1 +黄包车 1 +x:1 +送样 1 +x:1 +集体户 1 +x:1 +倒坍 1 +x:1 +有责 1 +x:1 +非金属 1 +x:1 +席梦思 1 +x:1 +避雷针 1 +x:1 +支词 1 +x:1 +授徒 1 +x:1 +甲乙级 1 +x:1 +审校 1 +x:1 +逊 12 +x:12 +胰岛素 1 +x:1 +扎什伦布 1 +x:1 +猎人 1 +x:1 +醒狮贺岁 1 +x:1 +宣传牌 1 +x:1 +故事会 1 +x:1 +远征 1 +x:1 +融智 1 +x:1 +维妙维肖 1 +x:1 +防地 1 +x:1 +萌动 1 +x:1 +下酒 1 +x:1 +品质 1 +x:1 +柿子皮 1 +x:1 +指挥长 1 +x:1 +茶漏 1 +x:1 +接收机 1 +x:1 +三自 1 +x:1 +电器道 1 +x:1 +黄泥冲 1 +x:1 +陨落 1 +x:1 +远志 1 +x:1 +一点儿 1 +x:1 +外翼 1 +x:1 +老妇 1 +x:1 +品赏 1 +x:1 +刮片 1 +x:1 +油市 1 +x:1 +正规化 1 +x:1 +厚望 1 +x:1 +展示窗 1 +x:1 +肋膜炎 1 +x:1 +岁星 1 +x:1 +雨花区 1 +x:1 +精进 1 +x:1 +反冲力 1 +x:1 +老妪 1 +x:1 +工业史 1 +x:1 +人烟 1 +x:1 +晓之以利 1 +x:1 +厚朴 1 +x:1 +铁砂弹 1 +x:1 +眼里 1 +x:1 +撕开 1 +x:1 +滇北 1 +x:1 +袜套 1 +x:1 +恸哭 1 +x:1 +暴走族 1 +x:1 +护照 1 +x:1 +工业化 1 +x:1 +声名狼藉 1 +x:1 +怕 347 +x:347 +枳实 1 +x:1 +马厩 1 +x:1 +贪便宜 1 +x:1 +责任区 1 +x:1 +人尽其才 1 +x:1 +工业区 1 +x:1 +蜥脚类 1 +x:1 +眉山 1 +x:1 +排涝 1 +x:1 +K 3 +x:3 +手下人 1 +x:1 +柜机 1 +x:1 +副博士 1 +x:1 +胆敢 1 +x:1 +生活观 1 +x:1 +准备金率 1 +x:1 +巴彦 1 +x:1 +鲜果 1 +x:1 +还嘴 1 +x:1 +滇南 1 +x:1 +怨天尤人 1 +x:1 +客观性 1 +x:1 +东窗事发 1 +x:1 +泉城 1 +x:1 +手到擒拿 1 +x:1 +捕捞业 1 +x:1 +防城 1 +x:1 +特赦 1 +x:1 +尊老爱老 1 +x:1 +逗逗哏 1 +x:1 +净利润 1 +x:1 +斑斑 1 +x:1 +斑斓 1 +x:1 +艺术类 1 +x:1 +阵容 1 +x:1 +老大 1 +x:1 +老天 1 +x:1 +老夫 1 +x:1 +老太 1 +x:1 +骄慢 1 +x:1 +岁暮 1 +x:1 +老头 1 +x:1 +抗极压性 1 +x:1 +飞毛腿 1 +x:1 +无虞 1 +x:1 +湘鄂赣 1 +x:1 +眼明手快 1 +x:1 +西施 1 +x:1 +单方 1 +x:1 +西方 1 +x:1 +煅石灰 1 +x:1 +黄荆 1 +x:1 +农机局 1 +x:1 +竹篾 1 +x:1 +客套话 1 +x:1 +西新 1 +x:1 +推磨 1 +x:1 +杆塔 1 +x:1 +后视镜 1 +x:1 +生命线 1 +x:1 +人才辈出 1 +x:1 +心碎 1 +x:1 +学阀 1 +x:1 +排列 1 +x:1 +声价 1 +x:1 +河贵乡 1 +x:1 +贯注 1 +x:1 +讨人喜欢 1 +x:1 +铜殿 1 +x:1 +龟头 1 +x:1 +托拉斯 1 +x:1 +浓 134 +x:134 +话剧 1 +x:1 +岩羊 1 +x:1 +筑巢者 1 +x:1 +西文 1 +x:1 +都安 1 +x:1 +凤凰岭村 1 +x:1 +原装 1 +x:1 +长期性 1 +x:1 +情报社 1 +x:1 +扬名 1 +x:1 +无实物 1 +x:1 +电工 1 +x:1 +玉石 1 +x:1 +大马力 1 +x:1 +志在必得 1 +x:1 +居高不下 1 +x:1 +单日 1 +x:1 +爹地 1 +x:1 +宁城县 1 +x:1 +新界 1 +x:1 +徜徉 1 +x:1 +益菌 1 +x:1 +统帅部 1 +x:1 +教书匠 1 +x:1 +花边 1 +x:1 +市厅级 1 +x:1 +冗杂 1 +x:1 +无可比拟 1 +x:1 +绵绵 1 +x:1 +规格 1 +x:1 +肖形印 1 +x:1 +悔棋 1 +x:1 +招认 1 +x:1 +双休日 1 +x:1 +人俑 1 +x:1 +话别 1 +x:1 +李白 1 +x:1 +拌和机 1 +x:1 +声乐 1 +x:1 +繁文缛节 1 +x:1 +测报 1 +x:1 +迂者 1 +x:1 +人伦 1 +x:1 +译音 1 +x:1 +新疆 1 +x:1 +罗赖马 1 +x:1 +袁州 1 +x:1 +美术班 1 +x:1 +厢 6 +x:6 +呈缴 1 +x:1 +花轴 1 +x:1 +保定市 1 +x:1 +诲淫诲盗 1 +x:1 +积重难返 1 +x:1 +茭 1 +x:1 +侵犯 1 +x:1 +花轿 1 +x:1 +中文台 1 +x:1 +粗腿病 1 +x:1 +欢迎词 1 +x:1 +花车 1 +x:1 +个儿 1 +x:1 +赢面 1 +x:1 +赫泽普丁 1 +x:1 +找头 1 +x:1 +单数 1 +x:1 +弦切角 1 +x:1 +沾恩 1 +x:1 +哂笑 1 +x:1 +没头没脑 1 +x:1 +收购制 1 +x:1 +平英团 1 +x:1 +迎 236 +x:236 +竹篓 1 +x:1 +红水河畔 1 +x:1 +明治维新 1 +x:1 +要强 1 +x:1 +越剧界 1 +x:1 +香蕉苹果 1 +x:1 +人工呼吸 1 +x:1 +痴情不移 1 +x:1 +老是 1 +x:1 +西敏 1 +x:1 +从容不迫 1 +x:1 +黄莺 1 +x:1 +一局制 1 +x:1 +凶 10 +x:10 +寻旧 1 +x:1 +物有所值 1 +x:1 +人体 1 +x:1 +推移 1 +x:1 +粲然可观 1 +x:1 +晚辈 1 +x:1 +兑换点 1 +x:1 +美术片 1 +x:1 +人亡 1 +x:1 +根雕家 1 +x:1 +诽谤罪 1 +x:1 +扫频 1 +x:1 +灼面 1 +x:1 +损失险 1 +x:1 +人人 1 +x:1 +就义 1 +x:1 +过于 1 +x:1 +小心翼翼 1 +x:1 +多云间阴 1 +x:1 +洛河 1 +x:1 +国防部 1 +x:1 +集体工 1 +x:1 +图雷斯基 1 +x:1 +人事 1 +x:1 +过人 1 +x:1 +制成 1 +x:1 +油田 1 +x:1 +罗山 1 +x:1 +竹笠 1 +x:1 +黄色 1 +x:1 +警示 1 +x:1 +季风气候 1 +x:1 +人们 1 +x:1 +一穷二白 1 +x:1 +排印 1 +x:1 +儿女 1 +x:1 +欢眉喜眼 1 +x:1 +二连冠 1 +x:1 +独院儿 1 +x:1 +一表人才 1 +x:1 +考生 1 +x:1 +茶具 1 +x:1 +撑杆跳高 1 +x:1 +过从 1 +x:1 +贞节 1 +x:1 +老枝 1 +x:1 +式式 1 +x:1 +门庭冷落 1 +x:1 +债务者 1 +x:1 +司门前镇 1 +x:1 +戏剧系 1 +x:1 +不自量力 1 +x:1 +痈疽 1 +x:1 +龙凤呈祥 1 +x:1 +睹物思人 1 +x:1 +无脊椎 1 +x:1 +紧促 1 +x:1 +部里 1 +x:1 +批林批孔 1 +x:1 +紧俏 1 +x:1 +排协 1 +x:1 +无理式 1 +x:1 +竹笼 1 +x:1 +胆子 1 +x:1 +人中 1 +x:1 +条形 1 +x:1 +下酒菜 1 +x:1 +学费 1 +x:1 +打草惊蛇 1 +x:1 +入院 1 +x:1 +税贸 1 +x:1 +税费 1 +x:1 +车轱辘 1 +x:1 +授意 1 +x:1 +人为 1 +x:1 +博洛尼亚 1 +x:1 +打情骂俏 1 +x:1 +眉批 1 +x:1 +霉天 1 +x:1 +北美局 1 +x:1 +倒树 1 +x:1 +窑坡 1 +x:1 +出警率 1 +x:1 +就任 1 +x:1 +扶手 1 +x:1 +话中有话 1 +x:1 +人丁 1 +x:1 +贺岁卡 1 +x:1 +流浪汉 1 +x:1 +劣等者 1 +x:1 +福州路 1 +x:1 +税负 1 +x:1 +人世 1 +x:1 +茶农 1 +x:1 +老板 1 +x:1 +疏通 1 +x:1 +比利时 1 +x:1 +式微 1 +x:1 +旷古 1 +x:1 +价格牌 1 +x:1 +苏绣 1 +x:1 +死扣儿 1 +x:1 +竹笋 1 +x:1 +被告席 1 +x:1 +词韵 1 +x:1 +药具 1 +x:1 +乡镇场 1 +x:1 +排口 1 +x:1 +侧目 1 +x:1 +萦心触怀 1 +x:1 +画眉 1 +x:1 +一话 1 +x:1 +札幌市 1 +x:1 +市场法 1 +x:1 +税赋 1 +x:1 +黄芪 1 +x:1 +黄芩 1 +x:1 +晚车 1 +x:1 +入阁 1 +x:1 +老本 1 +x:1 +一准儿 1 +x:1 +入队 1 +x:1 +种植圃 1 +x:1 +众生百态 1 +x:1 +固 42 +x:42 +老朽 1 +x:1 +撤资 1 +x:1 +黄花 1 +x:1 +远投 1 +x:1 +鱼死网破 1 +x:1 +入门 1 +x:1 +扶贫办 1 +x:1 +国统区 1 +x:1 +峡江县 1 +x:1 +音乐指导 1 +x:1 +单线 1 +x:1 +咏 24 +x:24 +收款员 1 +x:1 +遗传工程 1 +x:1 +撕扯 1 +x:1 +慈母 1 +x:1 +疗养团 1 +x:1 +祝福 1 +x:1 +浩子口 1 +x:1 +西枝 1 +x:1 +自顾不暇 1 +x:1 +戈家沟村 1 +x:1 +活蹦乱跳 1 +x:1 +竹笛 1 +x:1 +估量 1 +x:1 +盟旗 1 +x:1 +新面型 1 +x:1 +兑换率 1 +x:1 +疑案 1 +x:1 +泥块 1 +x:1 +泥坑 1 +x:1 +排偶 1 +x:1 +故事片 1 +x:1 +袍 2 +x:2 +一行 1 +x:1 +寄送 1 +x:1 +结 246 +x:246 +统管共用 1 +x:1 +漏水 1 +x:1 +吼叫 1 +x:1 +明镜儿 1 +x:1 +姚坪 1 +x:1 +相和 1 +x:1 +历史感 1 +x:1 +规模 1 +x:1 +泥土 1 +x:1 +清晰可见 1 +x:1 +以期 1 +x:1 +犁头 1 +x:1 +骗赔案 1 +x:1 +漏气 1 +x:1 +克雅氏症 1 +x:1 +征鸿 1 +x:1 +老办法 1 +x:1 +趋利避害 1 +x:1 +集疏运 1 +x:1 +县联社 1 +x:1 +单机 1 +x:1 +金蔷薇 1 +x:1 +上党梆子 1 +x:1 +闻鸡起舞 1 +x:1 +巴扎 1 +x:1 +胃脘 1 +x:1 +浪木 1 +x:1 +窥破 1 +x:1 +在线 1 +x:1 +陆架区 1 +x:1 +少儿情 1 +x:1 +钤 1 +x:1 +猎猎 1 +x:1 +老百姓 1 +x:1 +远房 1 +x:1 +织带 1 +x:1 +西服 1 +x:1 +个协 1 +x:1 +还款 1 +x:1 +老干部局 1 +x:1 +歇斯底里 1 +x:1 +碾米厂 1 +x:1 +悲剧式 1 +x:1 +送命 1 +x:1 +线段 1 +x:1 +联帮 1 +x:1 +无座力炮 1 +x:1 +单板 1 +x:1 +硫酸钾 1 +x:1 +屉子 1 +x:1 +系列机 1 +x:1 +开发性 1 +x:1 +泥垢 1 +x:1 +滑车 1 +x:1 +花铲 1 +x:1 +三家村 1 +x:1 +圆乎乎 1 +x:1 +浏阳市 1 +x:1 +单条 1 +x:1 +锯末 1 +x:1 +芳龄 1 +x:1 +南岗 1 +x:1 +相合 1 +x:1 +加班率 1 +x:1 +相同 1 +x:1 +小村子 1 +x:1 +丝都 1 +x:1 +西村 1 +x:1 +胃腺 1 +x:1 +白蛇传 1 +x:1 +花账 1 +x:1 +花贩 1 +x:1 +牛郎织女 1 +x:1 +相向 1 +x:1 +投诚 1 +x:1 +傻干 1 +x:1 +蒿子秆 1 +x:1 +哪儿 1 +x:1 +猎犬 1 +x:1 +要得 1 +x:1 +液果 1 +x:1 +疏解 1 +x:1 +骸骨 1 +x:1 +里斯本 1 +x:1 +货区楼 1 +x:1 +转悲为喜 1 +x:1 +花链 1 +x:1 +老旦 1 +x:1 +老早 1 +x:1 +弱酸 1 +x:1 +胃肠 1 +x:1 +乌土沟 1 +x:1 +词锋 1 +x:1 +轻工业品 1 +x:1 +生还 1 +x:1 +防欠 1 +x:1 +哆嗦 1 +x:1 +洛溪 1 +x:1 +紫竹 1 +x:1 +银线 1 +x:1 +含义 1 +x:1 +择业观 1 +x:1 +磐田 1 +x:1 +掘进点 1 +x:1 +罗布 1 +x:1 +隔河岩 1 +x:1 +南三环 1 +x:1 +千伏级 1 +x:1 +酌 6 +x:6 +傻帽 1 +x:1 +业障 1 +x:1 +排入 1 +x:1 +巴掌 1 +x:1 +四通八达 1 +x:1 +湖南团 1 +x:1 +紫苏叶 1 +x:1 +学运 1 +x:1 +绿绿葱葱 1 +x:1 +上钩者 1 +x:1 +快攻手 1 +x:1 +潜山 1 +x:1 +计划费 1 +x:1 +扶贫史 1 +x:1 +理论 1 +x:1 +欠税 1 +x:1 +推算 1 +x:1 +新港 1 +x:1 +荫翳 1 +x:1 +漏洞 1 +x:1 +防止 1 +x:1 +酝酿 1 +x:1 +慌忙 1 +x:1 +扬场 1 +x:1 +猎狗 1 +x:1 +二号机 1 +x:1 +百分数 1 +x:1 +写入 1 +x:1 +老爷子 1 +x:1 +市长级 1 +x:1 +错 193 +x:193 +夜明星 1 +x:1 +摩托船 1 +x:1 +大会党 1 +x:1 +多位点型 1 +x:1 +扶贫区 1 +x:1 +收息率 1 +x:1 +情报站 1 +x:1 +茶厅 1 +x:1 +容北村 1 +x:1 +健身器 1 +x:1 +称霸 1 +x:1 +相商 1 +x:1 +一箭双雕 1 +x:1 +乘幂 1 +x:1 +西昌 1 +x:1 +送料机 1 +x:1 +尘埃盘 1 +x:1 +大坝标 1 +x:1 +无计可施 1 +x:1 +贝雕 1 +x:1 +京山县 1 +x:1 +围栏 1 +x:1 +行车证 1 +x:1 +灰暗 1 +x:1 +柜子 1 +x:1 +大踏步 1 +x:1 +疗养地 1 +x:1 +化疗 1 +x:1 +单晶 1 +x:1 +一角 1 +x:1 +寐 1 +x:1 +厚实 1 +x:1 +无与伦比 1 +x:1 +茶叶 1 +x:1 +个别 1 +x:1 +盈眶 1 +x:1 +企业 1 +x:1 +铜案 1 +x:1 +花谱 1 +x:1 +竹筒 1 +x:1 +棘轮 1 +x:1 +新科学 1 +x:1 +打算盘 1 +x:1 +济宁 1 +x:1 +农安县 1 +x:1 +摩托艇 1 +x:1 +金龙 1 +x:1 +西晋 1 +x:1 +胆大 1 +x:1 +报价声 1 +x:1 +茶密村 1 +x:1 +疾风劲草 1 +x:1 +招远 1 +x:1 +污染源 1 +x:1 +叫做 1 +x:1 +菊花脑 1 +x:1 +防水 1 +x:1 +判 92 +x:92 +地头蛇 1 +x:1 +兴教 1 +x:1 +窝点 1 +x:1 +泉水 1 +x:1 +万户千家 1 +x:1 +向隅而泣 1 +x:1 +老拳 1 +x:1 +香喷的 1 +x:1 +不信任案 1 +x:1 +錾刀 1 +x:1 +汉城市 1 +x:1 +公交化 1 +x:1 +相助 1 +x:1 +冷却水 1 +x:1 +出租业 1 +x:1 +不预则废 1 +x:1 +黄蜂 1 +x:1 +探索性 1 +x:1 +潜存 1 +x:1 +防汛 1 +x:1 +桐子花 1 +x:1 +电视机厂 1 +x:1 +流失量 1 +x:1 +替换 1 +x:1 +盏盏 1 +x:1 +吕庄村 1 +x:1 +残疾人 1 +x:1 +富裕兵 1 +x:1 +依依难舍 1 +x:1 +日切村 1 +x:1 +黄蜡 1 +x:1 +轲 6 +x:6 +商检局 1 +x:1 +辅机 1 +x:1 +泉池 1 +x:1 +阵性 1 +x:1 +邯峰 1 +x:1 +预备生 1 +x:1 +乌合之众 1 +x:1 +播幅 1 +x:1 +允 6 +x:6 +考 80 +x:80 +妥协性 1 +x:1 +展主 1 +x:1 +内饰件 1 +x:1 +骄娇 1 +x:1 +老手 1 +x:1 +九死一生 1 +x:1 +决一死战 1 +x:1 +防沙 1 +x:1 +办公桌 1 +x:1 +鲍鱼 1 +x:1 +液态 1 +x:1 +中西药 1 +x:1 +糖衣炮弹 1 +x:1 +进攻性 1 +x:1 +塞伦盖蒂 1 +x:1 +安全玻璃 1 +x:1 +三步一踏 1 +x:1 +笑罗汉 1 +x:1 +武打片 1 +x:1 +一身 1 +x:1 +宽以待己 1 +x:1 +运城市 1 +x:1 +年夜饭 1 +x:1 +岁差 1 +x:1 +黄明胶 1 +x:1 +几多 1 +x:1 +芳香 1 +x:1 +返抵 1 +x:1 +烟雾 1 +x:1 +非作战 1 +x:1 +目指气使 1 +x:1 +避乱 1 +x:1 +老成 1 +x:1 +探空火箭 1 +x:1 +略 199 +x:199 +以一当十 1 +x:1 +千赫 1 +x:1 +金光闪闪 1 +x:1 +试飞 1 +x:1 +学衔 1 +x:1 +跑断腿 1 +x:1 +仅只 1 +x:1 +送别 1 +x:1 +相切 1 +x:1 +禁用语 1 +x:1 +懒汉式 1 +x:1 +考点 1 +x:1 +倒流 1 +x:1 +龟巢 1 +x:1 +窝火 1 +x:1 +知识性 1 +x:1 +攀 47 +x:47 +收款单 1 +x:1 +太 1254 +x:1254 +藏身 1 +x:1 +骂名 1 +x:1 +餐船 1 +x:1 +工运史 1 +x:1 +排场 1 +x:1 +『 4064 +x:4064 +湖色 1 +x:1 +科布多省 1 +x:1 +粪池 1 +x:1 +唠 2 +x:2 +冒险者 1 +x:1 +相反 1 +x:1 +远方 1 +x:1 +火字旁儿 1 +x:1 +疏远 1 +x:1 +年中报 1 +x:1 +上案制 1 +x:1 +防洪 1 +x:1 +疏运 1 +x:1 +糯米纸 1 +x:1 +副团职 1 +x:1 +面包篮 1 +x:1 +授旗 1 +x:1 +考试题 1 +x:1 +奶牛场 1 +x:1 +魔 8 +x:8 +矮生 1 +x:1 +回车键 1 +x:1 +政通 1 +x:1 +赞赏不已 1 +x:1 +见习 1 +x:1 +紫云英 1 +x:1 +忧 113 +x:113 +巴方 1 +x:1 +留一手 1 +x:1 +油品店 1 +x:1 +龟山 1 +x:1 +排坛 1 +x:1 +蛤蟆泉村 1 +x:1 +容电器 1 +x:1 +租赁业 1 +x:1 +告一段落 1 +x:1 +庸劣 1 +x:1 +一轻 1 +x:1 +地下党员 1 +x:1 +岁尾 1 +x:1 +倒水 1 +x:1 +效益水 1 +x:1 +三胞胎 1 +x:1 +利人 1 +x:1 +半山 1 +x:1 +情报系 1 +x:1 +活塞杆 1 +x:1 +防涝 1 +x:1 +只身 1 +x:1 +皮划艇 1 +x:1 +见于 1 +x:1 +速生林 1 +x:1 +漂洗 1 +x:1 +泉涌 1 +x:1 +同路人 1 +x:1 +坑木 1 +x:1 +扶智 1 +x:1 +翻涌 1 +x:1 +四合院 1 +x:1 +青龙峪村 1 +x:1 +征缴率 1 +x:1 +赌资 1 +x:1 +私车族 1 +x:1 +京剧界 1 +x:1 +收款台 1 +x:1 +馨 18 +x:18 +实感 1 +x:1 +衣料 1 +x:1 +况味 1 +x:1 +条子 1 +x:1 +济州 1 +x:1 +利于 1 +x:1 +继配 1 +x:1 +全麦草浆 1 +x:1 +明星团 1 +x:1 +赌账 1 +x:1 +洛桑 1 +x:1 +制霉菌素 1 +x:1 +漂流 1 +x:1 +结核菌素 1 +x:1 +蔚为壮观 1 +x:1 +瘸腿 1 +x:1 +演职员工 1 +x:1 +老挝 1 +x:1 +骄子 1 +x:1 +双宾语 1 +x:1 +织女 1 +x:1 +异化作用 1 +x:1 +漂浮 1 +x:1 +建筑学系 1 +x:1 +刀斧手 1 +x:1 +展位 1 +x:1 +全等形 1 +x:1 +椭圆体 1 +x:1 +旁听人 1 +x:1 +阔阔的 1 +x:1 +美术界 1 +x:1 +影壁山村 1 +x:1 +防渗 1 +x:1 +消磁界 1 +x:1 +控制 1 +x:1 +吹捧 1 +x:1 +情报署 1 +x:1 +苗苗 1 +x:1 +正轨 1 +x:1 +脚面 1 +x:1 +咕噜 1 +x:1 +法政 1 +x:1 +傻子 1 +x:1 +雕塑像 1 +x:1 +煤焦 1 +x:1 +书简 1 +x:1 +箩 2 +x:2 +急风暴雨 1 +x:1 +先归 1 +x:1 +情报网 1 +x:1 +征马 1 +x:1 +三门峡市 1 +x:1 +单排 1 +x:1 +妈咪 1 +x:1 +古生物 1 +x:1 +一锤定音 1 +x:1 +萧规曹随 1 +x:1 +眶 1 +x:1 +美餐 1 +x:1 +纱门 1 +x:1 +子午莲 1 +x:1 +家父 1 +x:1 +凝脂 1 +x:1 +太湖县 1 +x:1 +苗节 1 +x:1 +睡梦 1 +x:1 +晚装 1 +x:1 +市县级 1 +x:1 +踹 4 +x:4 +会议所 1 +x:1 +乙种粒子 1 +x:1 +褐煤 1 +x:1 +阅报栏 1 +x:1 +美饰 1 +x:1 +阵线 1 +x:1 +空管史 1 +x:1 +胜负手 1 +x:1 +无假冒 1 +x:1 +万众瞩目 1 +x:1 +羌族 1 +x:1 +静晤室 1 +x:1 +物价局 1 +x:1 +旭 49 +x:49 +买 1325 +x:1325 +十字花科 1 +x:1 +严以自律 1 +x:1 +扶贫团 1 +x:1 +盂县 1 +x:1 +风调雨顺 1 +x:1 +察南 1 +x:1 +泉源 1 +x:1 +头等舱 1 +x:1 +妇人 1 +x:1 +葵涌 1 +x:1 +唇裂 1 +x:1 +钨丝灯 1 +x:1 +他妈的 1 +x:1 +方兴未艾 1 +x:1 +检波 1 +x:1 +部队 1 +x:1 +金条 1 +x:1 +铜活 1 +x:1 +多用机 1 +x:1 +试验 1 +x:1 +巡回 1 +x:1 +收购员 1 +x:1 +柔软体操 1 +x:1 +老态 1 +x:1 +累垮 1 +x:1 +寓言 1 +x:1 +察北 1 +x:1 +经销商 1 +x:1 +阿拉伯化 1 +x:1 +租赁 1 +x:1 +茶园 1 +x:1 +心神不宁 1 +x:1 +繁育期 1 +x:1 +单据 1 +x:1 +辅料 1 +x:1 +剖宫产率 1 +x:1 +五味瓶 1 +x:1 +花红柳绿 1 +x:1 +罗定 1 +x:1 +胆小 1 +x:1 +五里河 1 +x:1 +化为乌有 1 +x:1 +每位 1 +x:1 +入 942 +x:942 +命运 1 +x:1 +招贴 1 +x:1 +厚度 1 +x:1 +沪东厂 1 +x:1 +鱼 251 +x:251 +乔治敦 1 +x:1 +松紧带 1 +x:1 +冯家镇 1 +x:1 +拉普拉斯 1 +x:1 +文风不动 1 +x:1 +远景 1 +x:1 +老总 1 +x:1 +纱锭 1 +x:1 +轧辊 1 +x:1 +各展所长 1 +x:1 +部际 1 +x:1 +延吉市 1 +x:1 +推翻 1 +x:1 +茧丝绸 1 +x:1 +表现 1 +x:1 +党工委 1 +x:1 +每亩 1 +x:1 +检测 1 +x:1 +型 71 +x:71 +秭归 1 +x:1 +怎么样 1 +x:1 +锦绣 1 +x:1 +每人 1 +x:1 +高妙 1 +x:1 +茶场 1 +x:1 +播州 1 +x:1 +谈情说爱 1 +x:1 +轮换工 1 +x:1 +干审处 1 +x:1 +衣不蔽体 1 +x:1 +正定县 1 +x:1 +一贯 1 +x:1 +丝锥 1 +x:1 +潜堤 1 +x:1 +旗绳 1 +x:1 +登机 1 +x:1 +漆包线 1 +x:1 +吹打 1 +x:1 +黄葵 1 +x:1 +教师爷 1 +x:1 +继任 1 +x:1 +木栓层 1 +x:1 +羊毛绒 1 +x:1 +学说 1 +x:1 +评论性 1 +x:1 +扫黄 1 +x:1 +巴林 1 +x:1 +汽修厂 1 +x:1 +单拳 1 +x:1 +厘定 1 +x:1 +扫黑 1 +x:1 +新片 1 +x:1 +失之偏颇 1 +x:1 +拉煤车 1 +x:1 +新版 1 +x:1 +环保部 1 +x:1 +自放电率 1 +x:1 +紫红 1 +x:1 +心眼儿 1 +x:1 +万夫莫当 1 +x:1 +为人作嫁 1 +x:1 +相册 1 +x:1 +茶坊 1 +x:1 +沾染 1 +x:1 +讪笑 1 +x:1 +野 61 +x:61 +致密 1 +x:1 +慈溪 1 +x:1 +紫荆堤 1 +x:1 +一起 1 +x:1 +学识 1 +x:1 +花被 1 +x:1 +沪市 1 +x:1 +隶圣 1 +x:1 +每个 1 +x:1 +相公 1 +x:1 +气雾剂 1 +x:1 +远期 1 +x:1 +智慧 1 +x:1 +远望 1 +x:1 +还清 1 +x:1 +堕 2 +x:2 +罹难 1 +x:1 +柜式 1 +x:1 +富余票 1 +x:1 +北医大 1 +x:1 +褐炭 1 +x:1 +鞠 35 +x:35 +全区性 1 +x:1 +胜出一筹 1 +x:1 +送入 1 +x:1 +德化县 1 +x:1 +紧 312 +x:312 +雍容 1 +x:1 +捐助式 1 +x:1 +精力充沛 1 +x:1 +随行就市 1 +x:1 +爽目 1 +x:1 +花衫 1 +x:1 +巴望 1 +x:1 +川黄液 1 +x:1 +厚待 1 +x:1 +增加量 1 +x:1 +岁序 1 +x:1 +生角 1 +x:1 +宣叙调 1 +x:1 +万古长青 1 +x:1 +条头 1 +x:1 +授权 1 +x:1 +临朐镇 1 +x:1 +入选 1 +x:1 +措玛 1 +x:1 +萧瑟 1 +x:1 +加盟店 1 +x:1 +花里胡梢 1 +x:1 +单打 1 +x:1 +被害人 1 +x:1 +山东快书 1 +x:1 +黄蒿 1 +x:1 +测旗 1 +x:1 +秦代 1 +x:1 +美食 1 +x:1 +骄女 1 +x:1 +融入 1 +x:1 +眉毛 1 +x:1 +铜排 1 +x:1 +军管会 1 +x:1 +看破红尘 1 +x:1 +同学录 1 +x:1 +农机员 1 +x:1 +灰浆 1 +x:1 +紫燕 1 +x:1 +不结之缘 1 +x:1 +盱江镇 1 +x:1 +悔悟 1 +x:1 +茶堂 1 +x:1 +爵溪镇 1 +x:1 +浪涛 1 +x:1 +棉坯布 1 +x:1 +区间 1 +x:1 +一般 1 +x:1 +兽医师 1 +x:1 +滥觞 1 +x:1 +法衣 1 +x:1 +抄纸 1 +x:1 +交通法 1 +x:1 +邻 13 +x:13 +命脉 1 +x:1 +潜在 1 +x:1 +红五军团 1 +x:1 +发案数 1 +x:1 +前哨战 1 +x:1 +养羊业 1 +x:1 +岩石 1 +x:1 +胆力 1 +x:1 +逻辑 1 +x:1 +飞行量 1 +x:1 +餐车 1 +x:1 +聘用制 1 +x:1 +织品 1 +x:1 +走马观花 1 +x:1 +绞杀 1 +x:1 +苇席 1 +x:1 +小河镇 1 +x:1 +投资业 1 +x:1 +河外星系 1 +x:1 +填方路基 1 +x:1 +题海 1 +x:1 +部风 1 +x:1 +申诉状 1 +x:1 +未了 1 +x:1 +绿化费 1 +x:1 +相应 1 +x:1 +客车厂 1 +x:1 +扶正 1 +x:1 +人之常情 1 +x:1 +哪个 1 +x:1 +议论纷纷 1 +x:1 +泥工 1 +x:1 +趾甲 1 +x:1 +报人 1 +x:1 +分久必合 1 +x:1 +巴桑 1 +x:1 +魏县 1 +x:1 +征聘 1 +x:1 +相干 1 +x:1 +泥巴 1 +x:1 +繁多 1 +x:1 +芜 1 +x:1 +红口白舌 1 +x:1 +石油局 1 +x:1 +任命权 1 +x:1 +来势汹汹 1 +x:1 +仙后座 1 +x:1 +肾气 1 +x:1 +绞架 1 +x:1 +液氧 1 +x:1 +西洋 1 +x:1 +净化水 1 +x:1 +液氢 1 +x:1 +笃深 1 +x:1 +鄞 1 +x:1 +藏药 1 +x:1 +估斤算两 1 +x:1 +订约 1 +x:1 +大煞风景 1 +x:1 +西海 1 +x:1 +惨重 1 +x:1 +花蜜 1 +x:1 +戏剧界 1 +x:1 +液汁 1 +x:1 +悔恨 1 +x:1 +脚部 1 +x:1 +爆炸性 1 +x:1 +迎面而来 1 +x:1 +违法者 1 +x:1 +糙粮 1 +x:1 +无限花序 1 +x:1 +煤气灶 1 +x:1 +纳百川 1 +x:1 +葬身 1 +x:1 +老港 1 +x:1 +民间性 1 +x:1 +蚩尤北寨 1 +x:1 +生死观 1 +x:1 +东街口 1 +x:1 +束管 1 +x:1 +沧海横流 1 +x:1 +恶作剧者 1 +x:1 +开放电路 1 +x:1 +亡身 1 +x:1 +西河 1 +x:1 +播及 1 +x:1 +焐 5 +x:5 +夏秋季 1 +x:1 +巍然 1 +x:1 +播发 1 +x:1 +住持 1 +x:1 +受益户 1 +x:1 +倒悬 1 +x:1 +誊清 1 +x:1 +律师团 1 +x:1 +工业革命 1 +x:1 +醇酒 1 +x:1 +西沟 1 +x:1 +大佛像 1 +x:1 +西沙 1 +x:1 +咳嗽病 1 +x:1 +部首 1 +x:1 +大足县 1 +x:1 +泥层 1 +x:1 +曲突徙薪 1 +x:1 +试销 1 +x:1 +大西门 1 +x:1 +枯萎 1 +x:1 +膝盖 1 +x:1 +有限性 1 +x:1 +吼声 1 +x:1 +美院 1 +x:1 +上茭道村 1 +x:1 +得手 1 +x:1 +园艺点 1 +x:1 +进化史 1 +x:1 +葵扇 1 +x:1 +灌溉站 1 +x:1 +塞阿拉 1 +x:1 +熊掌 1 +x:1 +排字 1 +x:1 +拼杀 1 +x:1 +玉带海雕 1 +x:1 +慈悲 1 +x:1 +飞行部 1 +x:1 +拉链 1 +x:1 +一药 1 +x:1 +武家坡 1 +x:1 +济源市 1 +x:1 +别无选择 1 +x:1 +包裹单 1 +x:1 +碰头会 1 +x:1 +孝昌三年 1 +x:1 +表皮 1 +x:1 +竞赛类 1 +x:1 +区别词 1 +x:1 +他物权 1 +x:1 +浪水 1 +x:1 +牲畜头数 1 +x:1 +猴手猴脚 1 +x:1 +矮秆 1 +x:1 +后会有期 1 +x:1 +民革 1 +x:1 +效益性 1 +x:1 +石嘴村 1 +x:1 +扬州 1 +x:1 +霸王花 1 +x:1 +甘桃片 1 +x:1 +一掷千金 1 +x:1 +排定 1 +x:1 +职教组 1 +x:1 +笨蛋 1 +x:1 +练摊 1 +x:1 +条块 1 +x:1 +寻的 1 +x:1 +相当 1 +x:1 +达林顿 1 +x:1 +芽苗菜 1 +x:1 +美雨 1 +x:1 +以防不测 1 +x:1 +光盘版 1 +x:1 +收件人 1 +x:1 +彭泽鲫 1 +x:1 +软软的 1 +x:1 +灰沙 1 +x:1 +扩胸器 1 +x:1 +滥采乱伐 1 +x:1 +树挂 1 +x:1 +大家风范 1 +x:1 +试问 1 +x:1 +京剧社 1 +x:1 +钟鼓楼 1 +x:1 +磨刀石 1 +x:1 +工长 1 +x:1 +人口 1 +x:1 +西江 1 +x:1 +嵇中散集 1 +x:1 +易腐 1 +x:1 +内陆河 1 +x:1 +诬 3 +x:3 +空管局 1 +x:1 +骂声 1 +x:1 +药学院 1 +x:1 +西汉 1 +x:1 +崖谷 1 +x:1 +载重 1 +x:1 +半月 1 +x:1 +载量 1 +x:1 +建 1281 +x:1281 +回访 1 +x:1 +篇首 1 +x:1 +新编 1 +x:1 +得意 1 +x:1 +大宇队 1 +x:1 +国库券 1 +x:1 +西澳 1 +x:1 +关长 1 +x:1 +得愈 1 +x:1 +资本家 1 +x:1 +成群结队 1 +x:1 +食用笋 1 +x:1 +贞观 1 +x:1 +先决性 1 +x:1 +招致 1 +x:1 +弱项 1 +x:1 +出借人 1 +x:1 +力气 1 +x:1 +黎巴嫩 1 +x:1 +越通社 1 +x:1 +眼中 1 +x:1 +指指戳戳 1 +x:1 +听便 1 +x:1 +无核国 1 +x:1 +生花之笔 1 +x:1 +扬帆 1 +x:1 +金凤凰 1 +x:1 +慕光性 1 +x:1 +繁密 1 +x:1 +缩写本 1 +x:1 +缸砖 1 +x:1 +活便 1 +x:1 +罗圈 1 +x:1 +紫铜色 1 +x:1 +太阳电池 1 +x:1 +忿忿不平 1 +x:1 +三房巷 1 +x:1 +该 2485 +x:2485 +检疫站 1 +x:1 +铁饭碗式 1 +x:1 +无人不晓 1 +x:1 +试院 1 +x:1 +柑子 1 +x:1 +研究生院 1 +x:1 +倒插 1 +x:1 +听信 1 +x:1 +欧空局 1 +x:1 +疏肝 1 +x:1 +融化 1 +x:1 +爬格子 1 +x:1 +和林格尔 1 +x:1 +岩画 1 +x:1 +征集 1 +x:1 +拾主 1 +x:1 +罗城 1 +x:1 +出纳员 1 +x:1 +许昌市 1 +x:1 +听众 1 +x:1 +十七路军 1 +x:1 +扣动 1 +x:1 +甭提 1 +x:1 +浪漫 1 +x:1 +花蕊 1 +x:1 +养鱼区 1 +x:1 +活体 1 +x:1 +考绩 1 +x:1 +孩儿 1 +x:1 +活佛 1 +x:1 +道外区 1 +x:1 +月租金 1 +x:1 +塌棵菜 1 +x:1 +花蕾 1 +x:1 +合金质 1 +x:1 +山河村 1 +x:1 +倒挂 1 +x:1 +涠西南 1 +x:1 +时效性 1 +x:1 +易记 1 +x:1 +议事厅 1 +x:1 +觉察 1 +x:1 +大会堂 1 +x:1 +蛮横 1 +x:1 +高升 1 +x:1 +浪潮 1 +x:1 +间离法 1 +x:1 +老气 1 +x:1 +倒换 1 +x:1 +由于 1 +x:1 +桀骜不驯 1 +x:1 +考纪 1 +x:1 +协约国 1 +x:1 +疏者 1 +x:1 +考级 1 +x:1 +扶植 1 +x:1 +新翼 1 +x:1 +修 343 +x:343 +厚势 1 +x:1 +黄血盐 1 +x:1 +经营不善 1 +x:1 +浮土层 1 +x:1 +死气沉沉 1 +x:1 +排头 1 +x:1 +西西里岛 1 +x:1 +相差 1 +x:1 +龙庆乡 1 +x:1 +搅黄 1 +x:1 +相左 1 +x:1 +内陆湖 1 +x:1 +妈妈 1 +x:1 +温情脉脉 1 +x:1 +上纲 1 +x:1 +时缺时剩 1 +x:1 +疾亡 1 +x:1 +无字句 1 +x:1 +淮海路 1 +x:1 +骂娘 1 +x:1 +排外 1 +x:1 +同步卫星 1 +x:1 +蜕变 1 +x:1 +亡党 1 +x:1 +陪审制 1 +x:1 +在 78485 +x:78485 +一隅 1 +x:1 +日记 1 +x:1 +书法集 1 +x:1 +宝贝 1 +x:1 +长白山 1 +x:1 +蓬蓬勃勃 1 +x:1 +南平 1 +x:1 +水压机 1 +x:1 +贝克萨区 1 +x:1 +阿曼湾 1 +x:1 +济南 1 +x:1 +严重 1 +x:1 +扬弃 1 +x:1 +茶学 1 +x:1 +始料不及 1 +x:1 +听从 1 +x:1 +活人 1 +x:1 +双月刊 1 +x:1 +扶梯 1 +x:1 +花蒂 1 +x:1 +百发百中 1 +x:1 +特内哈帕 1 +x:1 +漏收 1 +x:1 +无烟煤 1 +x:1 +温控型 1 +x:1 +一致性 1 +x:1 +话头 1 +x:1 +吟唱 1 +x:1 +不祥之兆 1 +x:1 +柜台 1 +x:1 +求种者 1 +x:1 +同事 1 +x:1 +校场口 1 +x:1 +电路板 1 +x:1 +骊山 1 +x:1 +妻姐 1 +x:1 +拱 11 +x:11 +灰渣 1 +x:1 +招股 1 +x:1 +扩张性 1 +x:1 +眉梢 1 +x:1 +听任 1 +x:1 +阿兰山 1 +x:1 +劳师动众 1 +x:1 +浪游 1 +x:1 +刘家山交 1 +x:1 +招聘 1 +x:1 +应声虫 1 +x:1 +得悉 1 +x:1 +鱼目 1 +x:1 +玄武岩 1 +x:1 +大会奖 1 +x:1 +赔偿金 1 +x:1 +负离子 1 +x:1 +轨辙 1 +x:1 +中医学 1 +x:1 +鬼语神话 1 +x:1 +苯丙胺类 1 +x:1 +软枣 1 +x:1 +扶桑 1 +x:1 +新约 1 +x:1 +美钞 1 +x:1 +创新业 1 +x:1 +谩骂 1 +x:1 +撕毁 1 +x:1 +金黄 1 +x:1 +圣园 1 +x:1 +汉阳区 1 +x:1 +通话费 1 +x:1 +竞赛组 1 +x:1 +轧花 1 +x:1 +银灰色 1 +x:1 +王母娘娘 1 +x:1 +新绛 1 +x:1 +征鞍 1 +x:1 +绊倒 1 +x:1 +招考 1 +x:1 +命苦 1 +x:1 +厚厚 1 +x:1 +倒扣 1 +x:1 +流芳千古 1 +x:1 +阻止 1 +x:1 +槽孔 1 +x:1 +篇页 1 +x:1 +槽子 1 +x:1 +信息量 1 +x:1 +西湖 1 +x:1 +蜕化 1 +x:1 +花萼 1 +x:1 +乘以 1 +x:1 +平原乡 1 +x:1 +统一性 1 +x:1 +一致 1 +x:1 +日坛 1 +x:1 +漏斗 1 +x:1 +族长式 1 +x:1 +新绩 1 +x:1 +敦煌 1 +x:1 +蠕动 1 +x:1 +随遇平衡 1 +x:1 +沾沾 1 +x:1 +围魏救赵 1 +x:1 +巧手 1 +x:1 +花菜 1 +x:1 +晚节 1 +x:1 +无理取闹 1 +x:1 +翻修 1 +x:1 +磨砂皮 1 +x:1 +花菇 1 +x:1 +俏皮话 1 +x:1 +测量网 1 +x:1 +胆囊 1 +x:1 +进 2134 +x:2134 +接种率 1 +x:1 +叶画 1 +x:1 +牛羊奶 1 +x:1 +主力军 1 +x:1 +水牛儿 1 +x:1 +倾家荡产 1 +x:1 +情报界 1 +x:1 +总代理 1 +x:1 +炸鸡 1 +x:1 +束缚 1 +x:1 +贯悉 1 +x:1 +米林 1 +x:1 +疮痂 1 +x:1 +锥面 1 +x:1 +茶山 1 +x:1 +明星式 1 +x:1 +征途 1 +x:1 +革新家 1 +x:1 +粮食 1 +x:1 +泥头 1 +x:1 +打埋伏 1 +x:1 +茫茫无际 1 +x:1 +假山 1 +x:1 +考研 1 +x:1 +旱冰场 1 +x:1 +得来 1 +x:1 +引而不发 1 +x:1 +车流声 1 +x:1 +鉴定人 1 +x:1 +只要 1 +x:1 +纳塔尔 1 +x:1 +犁地 1 +x:1 +故事类 1 +x:1 +都城 1 +x:1 +不夜城 1 +x:1 +装甲兵 1 +x:1 +蒙特勒 1 +x:1 +疮疤 1 +x:1 +黄连 1 +x:1 +瞒 17 +x:17 +等离子态 1 +x:1 +毁于一旦 1 +x:1 +花草 1 +x:1 +检索法 1 +x:1 +白塔山 1 +x:1 +为国分忧 1 +x:1 +畸形儿 1 +x:1 +敬孝 1 +x:1 +税者 1 +x:1 +日衰 1 +x:1 +学者 1 +x:1 +鉴定书 1 +x:1 +入魔 1 +x:1 +东钱湖 1 +x:1 +对外开放 1 +x:1 +武装部队 1 +x:1 +花药 1 +x:1 +亲密无间 1 +x:1 +西楼 1 +x:1 +倒数 1 +x:1 +铜材 1 +x:1 +轻机枪 1 +x:1 +白玉兰 1 +x:1 +漏报 1 +x:1 +鱼讯 1 +x:1 +优于 1 +x:1 +柜员 1 +x:1 +欢声笑语 1 +x:1 +偿债率 1 +x:1 +新秀 1 +x:1 +宽心丸儿 1 +x:1 +睡房 1 +x:1 +花茎 1 +x:1 +骨关节 1 +x:1 +借尸还魂 1 +x:1 +学联 1 +x:1 +彻底 1 +x:1 +花茶 1 +x:1 +铜板 1 +x:1 +鬲 1 +x:1 +黑帖 1 +x:1 +研究生部 1 +x:1 +核准费 1 +x:1 +钟磬 1 +x:1 +宣传册 1 +x:1 +建管委 1 +x:1 +排牙山 1 +x:1 +推理 1 +x:1 +隶属 1 +x:1 +运动健将 1 +x:1 +花苗 1 +x:1 +天罗地网 1 +x:1 +老母 1 +x:1 +水中 1 +x:1 +花苞 1 +x:1 +市场性 1 +x:1 +相对 1 +x:1 +前黄寨村 1 +x:1 +大厂县 1 +x:1 +蹲坑 1 +x:1 +既得利益 1 +x:1 +县委会 1 +x:1 +鸢 1 +x:1 +出纳台 1 +x:1 +掠过 1 +x:1 +斑块 1 +x:1 +怀远县 1 +x:1 +俱精 1 +x:1 +卓有 1 +x:1 +劫数 1 +x:1 +排开 1 +x:1 +泥塘 1 +x:1 +规整 1 +x:1 +国风 1 +x:1 +泥塑 1 +x:1 +勃勃生机 1 +x:1 +西梁 1 +x:1 +水保所 1 +x:1 +外型 1 +x:1 +父母官儿 1 +x:1 +入骨 1 +x:1 +陪审员 1 +x:1 +远渡重洋 1 +x:1 +得知 1 +x:1 +高差叠落 1 +x:1 +无怪乎 1 +x:1 +三仙姑 1 +x:1 +南涧县 1 +x:1 +繁峙 1 +x:1 +红1军团 1 +x:1 +送审 1 +x:1 +送客 1 +x:1 +荷兰王国 1 +x:1 +智残 1 +x:1 +錾子 1 +x:1 +肾上腺 1 +x:1 +定居者 1 +x:1 +花芽 1 +x:1 +融合 1 +x:1 +爹娘 1 +x:1 +扬头 1 +x:1 +相宜 1 +x:1 +访者 1 +x:1 +道里 1 +x:1 +共价键 1 +x:1 +齿轮油 1 +x:1 +单核 1 +x:1 +考种 1 +x:1 +悔改 1 +x:1 +美术组 1 +x:1 +潜力 1 +x:1 +运行费 1 +x:1 +入驻 1 +x:1 +单株 1 +x:1 +三皇五帝 1 +x:1 +灰棉 1 +x:1 +远洋 1 +x:1 +挟 8 +x:8 +拐角 1 +x:1 +花色 1 +x:1 +眼睛 1 +x:1 +检查 1 +x:1 +潜势 1 +x:1 +出资人 1 +x:1 +实情 1 +x:1 +地磁极 1 +x:1 +硬碰硬 1 +x:1 +联系汇率 1 +x:1 +咒骂 1 +x:1 +达川市 1 +x:1 +窃走 1 +x:1 +匿 2 +x:2 +排律 1 +x:1 +汁 2 +x:2 +名演员 1 +x:1 +江户湾 1 +x:1 +温存 1 +x:1 +悻悻 1 +x:1 +鉴定会 1 +x:1 +推车人 1 +x:1 +验票 1 +x:1 +齿轮泵 1 +x:1 +魏国 1 +x:1 +大双覆 1 +x:1 +始于足下 1 +x:1 +闭口价 1 +x:1 +浪桥 1 +x:1 +花舌 1 +x:1 +茶巾 1 +x:1 +钟秀 1 +x:1 +屡 81 +x:81 +远海 1 +x:1 +防旱 1 +x:1 +漏掉 1 +x:1 +放射器 1 +x:1 +融和 1 +x:1 +跑前跑后 1 +x:1 +产销地 1 +x:1 +千秋大业 1 +x:1 +国省道 1 +x:1 +泥墙 1 +x:1 +窃贼 1 +x:1 +试采 1 +x:1 +粮饷 1 +x:1 +寨边 1 +x:1 +磨难 1 +x:1 +枯草 1 +x:1 +远征军 1 +x:1 +窝窝 1 +x:1 +盖有 1 +x:1 +西段 1 +x:1 +排尿 1 +x:1 +稳重 1 +x:1 +美航 1 +x:1 +罗南 1 +x:1 +史各庄镇 1 +x:1 +分包村 1 +x:1 +相声 1 +x:1 +顺价 1 +x:1 +通约性 1 +x:1 +还林 1 +x:1 +时运 1 +x:1 +顺从 1 +x:1 +恋春 1 +x:1 +玩 144 +x:144 +老三件 1 +x:1 +枯荣 1 +x:1 +焦化厂 1 +x:1 +歪门邪道 1 +x:1 +送声 1 +x:1 +玫瑰 1 +x:1 +见微知著 1 +x:1 +铮铮誓言 1 +x:1 +无所用心 1 +x:1 +骄傲 1 +x:1 +考究 1 +x:1 +晚育 1 +x:1 +槽床 1 +x:1 +老梅 1 +x:1 +颤动 1 +x:1 +小组长 1 +x:1 +一霎 1 +x:1 +职教社 1 +x:1 +实惠 1 +x:1 +凝重感 1 +x:1 +辅洞 1 +x:1 +得救 1 +x:1 +尼安萨省 1 +x:1 +沾满 1 +x:1 +一针见血 1 +x:1 +正规战 1 +x:1 +马尼托巴 1 +x:1 +铁栏杆 1 +x:1 +设项 1 +x:1 +苟且偷安 1 +x:1 +单比 1 +x:1 +羞赧 1 +x:1 +腻腻歪歪 1 +x:1 +潜入 1 +x:1 +重中之重 1 +x:1 +隔离线 1 +x:1 +美酒 1 +x:1 +饺 1 +x:1 +盖板 1 +x:1 +企 30 +x:30 +莲蓬子儿 1 +x:1 +还有 1 +x:1 +花腔 1 +x:1 +手术器 1 +x:1 +上藏马村 1 +x:1 +印第安人 1 +x:1 +府城镇 1 +x:1 +觉得 1 +x:1 +铁栏架 1 +x:1 +置信度 1 +x:1 +声名显赫 1 +x:1 +赫鲁晓夫 1 +x:1 +西欧 1 +x:1 +常驻程序 1 +x:1 +养鱼场 1 +x:1 +深南路 1 +x:1 +织制 1 +x:1 +顺乎 1 +x:1 +罗口 1 +x:1 +顺义 1 +x:1 +还本 1 +x:1 +封店村 1 +x:1 +公证处 1 +x:1 +陨石坑 1 +x:1 +词频 1 +x:1 +茶店 1 +x:1 +一党制 1 +x:1 +学舌 1 +x:1 +泰米尔 1 +x:1 +偃松 1 +x:1 +学艺 1 +x:1 +摩托车 1 +x:1 +新篁 1 +x:1 +新篇 1 +x:1 +农机办 1 +x:1 +猞猁 1 +x:1 +标准化法 1 +x:1 +睡态 1 +x:1 +爹妈 1 +x:1 +奥 63 +x:63 +海底捞月 1 +x:1 +广太乡 1 +x:1 +花脸 1 +x:1 +官方类 1 +x:1 +缔结 1 +x:1 +锅炉厂 1 +x:1 +象征体 1 +x:1 +美金 1 +x:1 +黑乎乎 1 +x:1 +灿 9 +x:9 +盖柿 1 +x:1 +嘉手纳 1 +x:1 +条几 1 +x:1 +应对 1 +x:1 +邮币卡 1 +x:1 +向阳镇 1 +x:1 +赤兔马 1 +x:1 +黄豆 1 +x:1 +律 15 +x:15 +拨云见日 1 +x:1 +强作解人 1 +x:1 +老槐 1 +x:1 +条凳 1 +x:1 +银行业 1 +x:1 +秦都区 1 +x:1 +多科性 1 +x:1 +验箱 1 +x:1 +瘦肉猪 1 +x:1 +新程 1 +x:1 +广水市 1 +x:1 +鸳鸯松 1 +x:1 +锦盒 1 +x:1 +克/听 1 +x:1 +麦克风 1 +x:1 +潜值 1 +x:1 +高倍 1 +x:1 +干道口 1 +x:1 +验算 1 +x:1 +通化市 1 +x:1 +急就章 1 +x:1 +乔庄村 1 +x:1 +咽 11 +x:11 +德黑兰市 1 +x:1 +众参 1 +x:1 +以此为戒 1 +x:1 +首富乡 1 +x:1 +按需分配 1 +x:1 +班里 1 +x:1 +四平八稳 1 +x:1 +镍价 1 +x:1 +收款处 1 +x:1 +翻云覆雨 1 +x:1 +农机化 1 +x:1 +武斗 1 +x:1 +众口 1 +x:1 +判断句 1 +x:1 +浏阳县 1 +x:1 +民用机 1 +x:1 +扫雪 1 +x:1 +洋相 1 +x:1 +古浪县 1 +x:1 +冷却期 1 +x:1 +扫雷 1 +x:1 +啼 6 +x:6 +湖光秀色 1 +x:1 +罗勇 1 +x:1 +孟加拉国 1 +x:1 +西樵 1 +x:1 +坑洼 1 +x:1 +泉林 1 +x:1 +七八年 1 +x:1 +市场报 1 +x:1 +报修 1 +x:1 +倒映 1 +x:1 +相好 1 +x:1 +娓娓而谈 1 +x:1 +倒是 1 +x:1 +单模 1 +x:1 +木墙裙 1 +x:1 +报警 1 +x:1 +药囊 1 +x:1 +龠 1 +x:1 +砖瓦厂 1 +x:1 +胸腹腔 1 +x:1 +环城路 1 +x:1 +镀锌铁 1 +x:1 +波涌涛起 1 +x:1 +游行者 1 +x:1 +坑洞 1 +x:1 +袜楦 1 +x:1 +瘦肉率 1 +x:1 +广宁省 1 +x:1 +美术系 1 +x:1 +上甘岭 1 +x:1 +重庆城 1 +x:1 +傻劲 1 +x:1 +旷工 1 +x:1 +作业队 1 +x:1 +选民证 1 +x:1 +金刚山 1 +x:1 +农机厂 1 +x:1 +小四轮 1 +x:1 +集体化 1 +x:1 +唇膏 1 +x:1 +千金 1 +x:1 +赈灾款 1 +x:1 +武装部长 1 +x:1 +沉默少语 1 +x:1 +黑店 1 +x:1 +扫除 1 +x:1 +阳畦 1 +x:1 +新竹 1 +x:1 +睡意 1 +x:1 +儿皇帝 1 +x:1 +防查 1 +x:1 +新章 1 +x:1 +名震中外 1 +x:1 +测评会 1 +x:1 +宣腿 1 +x:1 +物茂粮丰 1 +x:1 +陪审团 1 +x:1 +漫味儿 1 +x:1 +报本坊 1 +x:1 +铜箔 1 +x:1 +景貌 1 +x:1 +条令 1 +x:1 +轴套 1 +x:1 +大年初三 1 +x:1 +货比三家 1 +x:1 +南充 1 +x:1 +及锋而试 1 +x:1 +组展 1 +x:1 +渔 26 +x:26 +出点子 1 +x:1 +条件 1 +x:1 +温冷线 1 +x:1 +潜伏 1 +x:1 +听喜 1 +x:1 +生平展 1 +x:1 +紧张度 1 +x:1 +合同期 1 +x:1 +帝制 1 +x:1 +载流子 1 +x:1 +故事性 1 +x:1 +储运 1 +x:1 +洗劫 1 +x:1 +新政 1 +x:1 +雅琪队 1 +x:1 +骄人 1 +x:1 +铜管 1 +x:1 +悟性 1 +x:1 +老相 1 +x:1 +煤卫 1 +x:1 +陆栖动物 1 +x:1 +征调 1 +x:1 +扫视 1 +x:1 +新教 1 +x:1 +型号 1 +x:1 +愉愉快快 1 +x:1 +婚外情 1 +x:1 +真 978 +x:978 +钟摆 1 +x:1 +森林狼队 1 +x:1 +装扮一新 1 +x:1 +此 3031 +x:3031 +大客车 1 +x:1 +侧束 1 +x:1 +嘉宾 1 +x:1 +林果业 1 +x:1 +人心 1 +x:1 +黄花鱼苗 1 +x:1 +避嫌 1 +x:1 +寨里 1 +x:1 +御览 1 +x:1 +串灯 1 +x:1 +孤苦伶仃 1 +x:1 +沁人心脾 1 +x:1 +外分泌 1 +x:1 +西画 1 +x:1 +每天 1 +x:1 +利害 1 +x:1 +靖西县 1 +x:1 +一阵子 1 +x:1 +防水表 1 +x:1 +投资国 1 +x:1 +投资团 1 +x:1 +招魂 1 +x:1 +谓 30 +x:30 +祭品 1 +x:1 +悄悄的 1 +x:1 +地震震级 1 +x:1 +充气机 1 +x:1 +耸然 1 +x:1 +党训班 1 +x:1 +司法员 1 +x:1 +洗刷 1 +x:1 +胶粒面 1 +x:1 +西柏坡 1 +x:1 +还礼 1 +x:1 +缴库单 1 +x:1 +均衡解 1 +x:1 +顶礼膜拜 1 +x:1 +慈祥 1 +x:1 +大河村 1 +x:1 +花鼓 1 +x:1 +扑火战 1 +x:1 +人形 1 +x:1 +惯偷 1 +x:1 +憩息 1 +x:1 +排位 1 +x:1 +谢礼 1 +x:1 +一高 1 +x:1 +堤段 1 +x:1 +倒票 1 +x:1 +人影 1 +x:1 +细致入微 1 +x:1 +休息椅 1 +x:1 +景象 1 +x:1 +老套子 1 +x:1 +卓立 1 +x:1 +是夜 1 +x:1 +声带 1 +x:1 +碧草 1 +x:1 +一路平安 1 +x:1 +潜修 1 +x:1 +宫颈癌 1 +x:1 +控股权 1 +x:1 +唱票员 1 +x:1 +展宽 1 +x:1 +尽兴 1 +x:1 +隅 3 +x:3 +洋枪队 1 +x:1 +不翼而飞 1 +x:1 +肯尼亚 1 +x:1 +栗子店村 1 +x:1 +俯望 1 +x:1 +指令 1 +x:1 +展室 1 +x:1 +一手点 1 +x:1 +办公房 1 +x:1 +验方 1 +x:1 +南平市 1 +x:1 +乃是 1 +x:1 +近在眉睫 1 +x:1 +知错 1 +x:1 +骨灰箱 1 +x:1 +过度 1 +x:1 +获 902 +x:902 +文法学 1 +x:1 +打斗招式 1 +x:1 +欣赏者 1 +x:1 +密码锁 1 +x:1 +尽先 1 +x:1 +漏网 1 +x:1 +先驱新党 1 +x:1 +肯尼亚队 1 +x:1 +洄游 1 +x:1 +死水一潭 1 +x:1 +预备性 1 +x:1 +空中小姐 1 +x:1 +小淘气 1 +x:1 +明智之举 1 +x:1 +大使库 1 +x:1 +力挫 1 +x:1 +乘员 1 +x:1 +克拉科夫 1 +x:1 +受 1739 +x:1739 +无实据 1 +x:1 +被告人 1 +x:1 +慕仪乡 1 +x:1 +单瓣 1 +x:1 +治水改土 1 +x:1 +双林寺 1 +x:1 +活塞环 1 +x:1 +西瓜 1 +x:1 +制片 1 +x:1 +制版 1 +x:1 +条例 1 +x:1 +征购 1 +x:1 +避寒 1 +x:1 +修理店 1 +x:1 +诸如此类 1 +x:1 +咨询处 1 +x:1 +险仗 1 +x:1 +玉米秆 1 +x:1 +范畴 1 +x:1 +道河乡 1 +x:1 +肾病 1 +x:1 +旅游圈 1 +x:1 +团队票 1 +x:1 +多彩缤纷 1 +x:1 +锦州市 1 +x:1 +阵痛 1 +x:1 +沃野千里 1 +x:1 +渐进式 1 +x:1 +活命 1 +x:1 +价格战 1 +x:1 +黄粱梦 1 +x:1 +拉近乎 1 +x:1 +疟蚊 1 +x:1 +紧张 1 +x:1 +验放 1 +x:1 +惠安 1 +x:1 +信息论 1 +x:1 +鹅卵石 1 +x:1 +百家争鸣 1 +x:1 +旧调重弹 1 +x:1 +抄本 1 +x:1 +维生素D 1 +x:1 +以权谋私 1 +x:1 +光彩耀目 1 +x:1 +听听 1 +x:1 +命题 1 +x:1 +生长型 1 +x:1 +间作地 1 +x:1 +灰瓦 1 +x:1 +计划经济 1 +x:1 +以退为进 1 +x:1 +银屑病 1 +x:1 +连台本戏 1 +x:1 +措施 1 +x:1 +饯行 1 +x:1 +疾呼 1 +x:1 +试跳 1 +x:1 +桑 30 +x:30 +培智 1 +x:1 +良好者 1 +x:1 +模范县 1 +x:1 +凌源市 1 +x:1 +人平 1 +x:1 +苗锦 1 +x:1 +律师业 1 +x:1 +过年 1 +x:1 +碱集料 1 +x:1 +甜甜地 1 +x:1 +扳平 1 +x:1 +避孕 1 +x:1 +怒目横眉 1 +x:1 +乙烯厂 1 +x:1 +声张 1 +x:1 +检箱 1 +x:1 +斜风细雨 1 +x:1 +就座 1 +x:1 +洗印 1 +x:1 +听命 1 +x:1 +国内部 1 +x:1 +桃花丛 1 +x:1 +袋口 1 +x:1 +修理工 1 +x:1 +相思鸟 1 +x:1 +双人舞 1 +x:1 +谅必 1 +x:1 +寮步镇 1 +x:1 +轴子 1 +x:1 +宠坏 1 +x:1 +收文簿 1 +x:1 +鲜明 1 +x:1 +见外 1 +x:1 +千回百转 1 +x:1 +森林城 1 +x:1 +黄酒 1 +x:1 +洛美 1 +x:1 +老人家 1 +x:1 +剖宫产 1 +x:1 +二季度 1 +x:1 +倒算 1 +x:1 +新机 1 +x:1 +创新型 1 +x:1 +粪筐 1 +x:1 +评论界 1 +x:1 +患处 1 +x:1 +肩上 1 +x:1 +文明车 1 +x:1 +滇红 1 +x:1 +藏香 1 +x:1 +组合音响 1 +x:1 +绞索 1 +x:1 +还箱 1 +x:1 +芯片业 1 +x:1 +众人 1 +x:1 +黄酱 1 +x:1 +苛求 1 +x:1 +双程 1 +x:1 +新村 1 +x:1 +利好 1 +x:1 +网状脉 1 +x:1 +所局级 1 +x:1 +打折票 1 +x:1 +人工 1 +x:1 +大中专班 1 +x:1 +滓 1 +x:1 +顺势 1 +x:1 +弱者 1 +x:1 +护岸 1 +x:1 +工业组 1 +x:1 +西瓜霜 1 +x:1 +乘坐 1 +x:1 +欠款 1 +x:1 +瞒心昧己 1 +x:1 +五合板 1 +x:1 +宣传弹 1 +x:1 +谐趣感 1 +x:1 +凸凸凹凹 1 +x:1 +路旁 1 +x:1 +银行卡 1 +x:1 +泰然自若 1 +x:1 +抛却 1 +x:1 +新松 1 +x:1 +酒肉朋友 1 +x:1 +防空 1 +x:1 +慎选 1 +x:1 +昧心 1 +x:1 +寸土寸金 1 +x:1 +实践家 1 +x:1 +肾盂 1 +x:1 +度量 1 +x:1 +见好 1 +x:1 +倒掉 1 +x:1 +勺园 1 +x:1 +脉冲 1 +x:1 +云阳镇 1 +x:1 +三十一日 1 +x:1 +藤制品 1 +x:1 +一槌定音 1 +x:1 +侧方 1 +x:1 +新枝 1 +x:1 +消防栓 1 +x:1 +利国 1 +x:1 +测点 1 +x:1 +黄金 1 +x:1 +崖面 1 +x:1 +岩洞 1 +x:1 +验明 1 +x:1 +别 304 +x:304 +壳状 1 +x:1 +规章 1 +x:1 +粪篓 1 +x:1 +制药队 1 +x:1 +懵懵懂懂 1 +x:1 +景洪市 1 +x:1 +无坟堆 1 +x:1 +路人皆知 1 +x:1 +审审改改 1 +x:1 +售票厅 1 +x:1 +顺利 1 +x:1 +结党营私 1 +x:1 +曳光弹 1 +x:1 +藉藉无名 1 +x:1 +每季 1 +x:1 +储贷 1 +x:1 +得益 1 +x:1 +授牌 1 +x:1 +擦拭 1 +x:1 +游入 1 +x:1 +场地费 1 +x:1 +产出量 1 +x:1 +热科院 1 +x:1 +甭管 1 +x:1 +均衡论 1 +x:1 +售后服务 1 +x:1 +防病 1 +x:1 +年增长率 1 +x:1 +话把儿 1 +x:1 +大年初二 1 +x:1 +尽力 1 +x:1 +护封 1 +x:1 +胃酸 1 +x:1 +几何 1 +x:1 +滑子蘑 1 +x:1 +猎捕 1 +x:1 +岩浆 1 +x:1 +促销员 1 +x:1 +厕身 1 +x:1 +舟楫如梭 1 +x:1 +护工 1 +x:1 +新星 1 +x:1 +顺口 1 +x:1 +西皮 1 +x:1 +肺气肿 1 +x:1 +订数 1 +x:1 +概而言之 1 +x:1 +南海市 1 +x:1 +灵魂界 1 +x:1 +黄道 1 +x:1 +新昌 1 +x:1 +美谈 1 +x:1 +代办处 1 +x:1 +傻乐 1 +x:1 +哒哒 1 +x:1 +检票 1 +x:1 +泅渡 1 +x:1 +灰白 1 +x:1 +投资商 1 +x:1 +摄成 1 +x:1 +新春 1 +x:1 +新实在论 1 +x:1 +链霉素 1 +x:1 +携 51 +x:51 +匀细 1 +x:1 +趿 1 +x:1 +银行制 1 +x:1 +年逾古稀 1 +x:1 +紧巴 1 +x:1 +马村区 1 +x:1 +瓜子皮 1 +x:1 +媚态 1 +x:1 +众朝官 1 +x:1 +考期 1 +x:1 +招领 1 +x:1 +诗歌节 1 +x:1 +试车 1 +x:1 +邯郸市 1 +x:1 +中伤式 1 +x:1 +西盟 1 +x:1 +胃部 1 +x:1 +断发性 1 +x:1 +先烈 1 +x:1 +公 151 +x:151 +种龟 1 +x:1 +成交量 1 +x:1 +寿比南山 1 +x:1 +手下留情 1 +x:1 +曾用名 1 +x:1 +新景 1 +x:1 +倒立 1 +x:1 +世俗主义 1 +x:1 +风尚奖 1 +x:1 +柱础石 1 +x:1 +长期班 1 +x:1 +智略 1 +x:1 +枯黄 1 +x:1 +讲习班 1 +x:1 +恣肆 1 +x:1 +玉米地 1 +x:1 +单瘫 1 +x:1 +上岗证 1 +x:1 +油枯 1 +x:1 +戒烟日 1 +x:1 +股份公司 1 +x:1 +猎户 1 +x:1 +美貌 1 +x:1 +樟树市 1 +x:1 +竹艺 1 +x:1 +蒙玻利埃 1 +x:1 +决策权 1 +x:1 +考查 1 +x:1 +攀比风 1 +x:1 +灿若星河 1 +x:1 +铁八局 1 +x:1 +无线电波 1 +x:1 +抄收 1 +x:1 +感性化 1 +x:1 +光盘案 1 +x:1 +微缩 1 +x:1 +误入歧途 1 +x:1 +失眠症 1 +x:1 +充要条件 1 +x:1 +赌鬼 1 +x:1 +拣到 1 +x:1 +老生 1 +x:1 +盖章 1 +x:1 +后帮跟 1 +x:1 +猎手 1 +x:1 +寻法 1 +x:1 +人居 1 +x:1 +保福乡 1 +x:1 +新曹 1 +x:1 +几乎 1 +x:1 +工业署 1 +x:1 +串珠 1 +x:1 +翻山越岭 1 +x:1 +傻事 1 +x:1 +死 549 +x:549 +自取灭亡 1 +x:1 +老古董 1 +x:1 +彩板型 1 +x:1 +结核杆菌 1 +x:1 +灯心条 1 +x:1 +舌尖音 1 +x:1 +珍珠贝 1 +x:1 +摩洛哥队 1 +x:1 +皱痕 1 +x:1 +人家 1 +x:1 +新意 1 +x:1 +听写 1 +x:1 +窑具 1 +x:1 +并网 1 +x:1 +无霜期 1 +x:1 +儒门 1 +x:1 +短兵相接 1 +x:1 +护嫂 1 +x:1 +学额 1 +x:1 +利弊 1 +x:1 +书法观 1 +x:1 +税额 1 +x:1 +肾炎 1 +x:1 +就学 1 +x:1 +绿池 1 +x:1 +擒获 1 +x:1 +布鼓雷门 1 +x:1 +地对地 1 +x:1 +整数型 1 +x:1 +脐儿 1 +x:1 +写就 1 +x:1 +人寿 1 +x:1 +里表 1 +x:1 +莫大 1 +x:1 +不期而至 1 +x:1 +人寰 1 +x:1 +试衣 1 +x:1 +顺和 1 +x:1 +漏税 1 +x:1 +税风 1 +x:1 +轨道 1 +x:1 +天象仪 1 +x:1 +连云港市 1 +x:1 +得罪 1 +x:1 +思蒙镇 1 +x:1 +试行 1 +x:1 +展廊 1 +x:1 +圆桌面 1 +x:1 +讼案 1 +x:1 +模范团 1 +x:1 +入药 1 +x:1 +部落 1 +x:1 +膨胀性 1 +x:1 +老牌 1 +x:1 +花魁 1 +x:1 +崇皇乡 1 +x:1 +老牛 1 +x:1 +与其说 1 +x:1 +鸡皮鹤发 1 +x:1 +折反跑 1 +x:1 +吃闲饭 1 +x:1 +定量分析 1 +x:1 +那扎村 1 +x:1 +都会 1 +x:1 +眉睫 1 +x:1 +霸王龙 1 +x:1 +爱国主义 1 +x:1 +地板刷 1 +x:1 +西南极 1 +x:1 +掘进机 1 +x:1 +订报 1 +x:1 +平阳县 1 +x:1 +乘凉 1 +x:1 +出租店 1 +x:1 +乔然山 1 +x:1 +决策性 1 +x:1 +人学 1 +x:1 +防撞性 1 +x:1 +活儿 1 +x:1 +标志性 1 +x:1 +全盘皆活 1 +x:1 +牵牛星 1 +x:1 +税项 1 +x:1 +替班 1 +x:1 +声威 1 +x:1 +过路费 1 +x:1 +蓬莱仙境 1 +x:1 +换心人 1 +x:1 +钟情 1 +x:1 +彝 3 +x:3 +名角儿 1 +x:1 +眉眼 1 +x:1 +市场科 1 +x:1 +帝国 1 +x:1 +田径运动 1 +x:1 +从此以后 1 +x:1 +专章 1 +x:1 +老爷 1 +x:1 +老父 1 +x:1 +人孔 1 +x:1 +老爸 1 +x:1 +继而 1 +x:1 +顺向 1 +x:1 +展徽 1 +x:1 +草坝村 1 +x:1 +仪表厂 1 +x:1 +西点 1 +x:1 +本地化 1 +x:1 +潍坊市 1 +x:1 +阜宁 1 +x:1 +黄陂 1 +x:1 +日薄西山 1 +x:1 +诊断 1 +x:1 +支公司 1 +x:1 +三黑一塌 1 +x:1 +单炮 1 +x:1 +扶直 1 +x:1 +绿水青山 1 +x:1 +合二为一 1 +x:1 +无理函数 1 +x:1 +群英争雄 1 +x:1 +浠政 1 +x:1 +创编 1 +x:1 +灰灰 1 +x:1 +正处级 1 +x:1 +美言 1 +x:1 +团县委 1 +x:1 +各得其所 1 +x:1 +阔别 1 +x:1 +琳琅 1 +x:1 +书生味 1 +x:1 +地久天长 1 +x:1 +黄陵 1 +x:1 +活像 1 +x:1 +府南河畔 1 +x:1 +安道尔队 1 +x:1 +机关干部 1 +x:1 +验卡点 1 +x:1 +投资区 1 +x:1 +瑞气 1 +x:1 +景观 1 +x:1 +热水袋 1 +x:1 +一齐 1 +x:1 +左膀 1 +x:1 +蘑菇罐头 1 +x:1 +父权制 1 +x:1 +茶业 1 +x:1 +四大名著 1 +x:1 +签定 1 +x:1 +旁听席 1 +x:1 +怀安县 1 +x:1 +铜绿 1 +x:1 +墨西哥湾 1 +x:1 +跃马 1 +x:1 +防御型 1 +x:1 +言之无物 1 +x:1 +拭泪 1 +x:1 +百分率 1 +x:1 +紧密 1 +x:1 +秋风过耳 1 +x:1 +喧嚣 1 +x:1 +翻跟头 1 +x:1 +持异议者 1 +x:1 +增城 1 +x:1 +吸血鬼 1 +x:1 +远生 1 +x:1 +投资司 1 +x:1 +卷吸作用 1 +x:1 +增氧机 1 +x:1 +杭剧 1 +x:1 +自警 1 +x:1 +养虎遗患 1 +x:1 +秋后算帐 1 +x:1 +禅房 1 +x:1 +听候 1 +x:1 +托出 1 +x:1 +皇陵 1 +x:1 +行为人 1 +x:1 +签子 1 +x:1 +邋里邋蹋 1 +x:1 +雪上加霜 1 +x:1 +锦江 1 +x:1 +推测 1 +x:1 +声学 1 +x:1 +高小生 1 +x:1 +东莱街 1 +x:1 +科普部 1 +x:1 +宪制 1 +x:1 +灰烬 1 +x:1 +避开 1 +x:1 +瑁 1 +x:1 +墙板 1 +x:1 +业者 1 +x:1 +柔柔地 1 +x:1 +稀稀落落 1 +x:1 +割草机 1 +x:1 +热泵式 1 +x:1 +质监站 1 +x:1 +丹凤眼 1 +x:1 +一代风流 1 +x:1 +境内外 1 +x:1 +矛盾论 1 +x:1 +白求恩 1 +x:1 +指东说西 1 +x:1 +超巨星 1 +x:1 +陶土 1 +x:1 +新沂 1 +x:1 +催眠药 1 +x:1 +巴盟 1 +x:1 +猎枪 1 +x:1 +郑重其事 1 +x:1 +护士 1 +x:1 +力戒 1 +x:1 +东港区 1 +x:1 +帝君 1 +x:1 +活口 1 +x:1 +防癌 1 +x:1 +单环 1 +x:1 +粉细砂 1 +x:1 +霖 2 +x:2 +四呼 1 +x:1 +声声 1 +x:1 +扶病 1 +x:1 +脑袋瓜儿 1 +x:1 +救死扶伤 1 +x:1 +平原县 1 +x:1 +视盘 1 +x:1 +人妖 1 +x:1 +欢城镇 1 +x:1 +晚风 1 +x:1 +南海子 1 +x:1 +鞭炮瘾 1 +x:1 +葬送 1 +x:1 +花香 1 +x:1 +嗉子 1 +x:1 +百分点 1 +x:1 +增值链 1 +x:1 +听取 1 +x:1 +顺序 1 +x:1 +坐吃山空 1 +x:1 +议事会 1 +x:1 +柜员机 1 +x:1 +私刑 1 +x:1 +小组赛 1 +x:1 +客堂 1 +x:1 +煞费苦心 1 +x:1 +携手 1 +x:1 +夜明珠 1 +x:1 +扶疏 1 +x:1 +淡巴巴 1 +x:1 +护墙 1 +x:1 +腺 1 +x:1 +预备期 1 +x:1 +融会 1 +x:1 +太古界 1 +x:1 +西南方 1 +x:1 +人夫 1 +x:1 +鉴定员 1 +x:1 +兑换机 1 +x:1 +人大 1 +x:1 +过多 1 +x:1 +谢罪 1 +x:1 +每张 1 +x:1 +活宝 1 +x:1 +送暖 1 +x:1 +人头 1 +x:1 +全力争冠 1 +x:1 +挂车费 1 +x:1 +轴心 1 +x:1 +喜盈盈 1 +x:1 +花饰 1 +x:1 +过头 1 +x:1 +巴登 1 +x:1 +过失 1 +x:1 +内燃机 1 +x:1 +平原区 1 +x:1 +岁修 1 +x:1 +贯穿 1 +x:1 +哭天抹泪 1 +x:1 +高检院 1 +x:1 +主 139 +x:139 +柜中 1 +x:1 +嘉平镇 1 +x:1 +无所不能 1 +x:1 +过奖 1 +x:1 +万全县 1 +x:1 +朱印 1 +x:1 +文论集 1 +x:1 +护堤 1 +x:1 +逗趣儿 1 +x:1 +高架路 1 +x:1 +胃镜 1 +x:1 +倒置 1 +x:1 +农行 1 +x:1 +奇装异服 1 +x:1 +疮口 1 +x:1 +利川 1 +x:1 +活化 1 +x:1 +白乎乎 1 +x:1 +成熟期 1 +x:1 +猎杀 1 +x:1 +美观 1 +x:1 +席面 1 +x:1 +肉袋 1 +x:1 +隧道局 1 +x:1 +尊卑 1 +x:1 +立体几何 1 +x:1 +常温 1 +x:1 +连唱 1 +x:1 +避居 1 +x:1 +每当 1 +x:1 +乘号 1 +x:1 +香獐子 1 +x:1 +鄙意 1 +x:1 +持久化 1 +x:1 +能源业 1 +x:1 +寻根 1 +x:1 +有源之水 1 +x:1 +采煤队 1 +x:1 +过境 1 +x:1 +不依不饶 1 +x:1 +听力 1 +x:1 +信息费 1 +x:1 +秦汉唐 1 +x:1 +泸州市 1 +x:1 +考据 1 +x:1 +自治州委 1 +x:1 +悄悄然 1 +x:1 +入胜 1 +x:1 +花石村 1 +x:1 +通话量 1 +x:1 +木筏子 1 +x:1 +叫喊 1 +x:1 +谢绝 1 +x:1 +创新力 1 +x:1 +毫无疑问 1 +x:1 +青莲色 1 +x:1 +昙花一现 1 +x:1 +无微不至 1 +x:1 +半旗 1 +x:1 +人士 1 +x:1 +河马 1 +x:1 +入股 1 +x:1 +未决 1 +x:1 +巍然屹立 1 +x:1 +还给 1 +x:1 +隧道工 1 +x:1 +形态各异 1 +x:1 +维继 1 +x:1 +新手 1 +x:1 +锦溪 1 +x:1 +活动 1 +x:1 +人声 1 +x:1 +私刻 1 +x:1 +常住 1 +x:1 +检索 1 +x:1 +坑痕 1 +x:1 +分子溶液 1 +x:1 +宽宏大量 1 +x:1 +活力 1 +x:1 +红极一时 1 +x:1 +平江县 1 +x:1 +特护队 1 +x:1 +赔偿费 1 +x:1 +飘舞 1 +x:1 +西狄 1 +x:1 +修订 1 +x:1 +精武门 1 +x:1 +选举年 1 +x:1 +借鉴 1 +x:1 +试讲 1 +x:1 +试训 1 +x:1 +九节鞭 1 +x:1 +黄铜 1 +x:1 +装饰一新 1 +x:1 +活剧 1 +x:1 +过堂 1 +x:1 +晚餐 1 +x:1 +征询 1 +x:1 +手板儿 1 +x:1 +找乐 1 +x:1 +朝鲜族 1 +x:1 +花须 1 +x:1 +乘务 1 +x:1 +远眺 1 +x:1 +黑心 1 +x:1 +无所不至 1 +x:1 +未免 1 +x:1 +尴尬 1 +x:1 +紧处 1 +x:1 +乘势 1 +x:1 +系列片 1 +x:1 +船 297 +x:297 +鼓角 1 +x:1 +拳拳情意 1 +x:1 +顺平 1 +x:1 +粮草 1 +x:1 +心内外科 1 +x:1 +争芳斗妍 1 +x:1 +秦篆 1 +x:1 +则救之 1 +x:1 +龙争虎斗 1 +x:1 +手疾眼快 1 +x:1 +凄风楚雨 1 +x:1 +心胆俱裂 1 +x:1 +怒江州 1 +x:1 +动摇不定 1 +x:1 +泾河乡 1 +x:1 +活字 1 +x:1 +粮荒 1 +x:1 +每年 1 +x:1 +皴裂 1 +x:1 +入耳 1 +x:1 +晚饭 1 +x:1 +申根 1 +x:1 +征订 1 +x:1 +载运 1 +x:1 +窥测 1 +x:1 +宽以待人 1 +x:1 +试试 1 +x:1 +征讨 1 +x:1 +外务省 1 +x:1 +情报源 1 +x:1 +湖北省 1 +x:1 +宣传台 1 +x:1 +峡山镇 1 +x:1 +九四年 1 +x:1 +防卫局 1 +x:1 +活分 1 +x:1 +弹簧厂 1 +x:1 +污七八糟 1 +x:1 +馁 1 +x:1 +视紫质 1 +x:1 +老练 1 +x:1 +鲁南区 1 +x:1 +流入地 1 +x:1 +比色计 1 +x:1 +推想 1 +x:1 +南岸区 1 +x:1 +柴米 1 +x:1 +准予 1 +x:1 +护国 1 +x:1 +勿施于人 1 +x:1 +水磨坊 1 +x:1 +目不暇接 1 +x:1 +住家 1 +x:1 +睡相 1 +x:1 +入迷 1 +x:1 +丐帮 1 +x:1 +苏木 1 +x:1 +亦步亦趋 1 +x:1 +日夜辛劳 1 +x:1 +新派 1 +x:1 +鉴湖 1 +x:1 +因村制宜 1 +x:1 +侧漏 1 +x:1 +餐馆 1 +x:1 +失忆症 1 +x:1 +敏锐 1 +x:1 +硅胶 1 +x:1 +撕破 1 +x:1 +紧固 1 +x:1 +相交 1 +x:1 +专有 1 +x:1 +运动论 1 +x:1 +行车道 1 +x:1 +下九路 1 +x:1 +钓杆 1 +x:1 +花鞋 1 +x:1 +税银 1 +x:1 +同学会 1 +x:1 +随机性 1 +x:1 +一低一高 1 +x:1 +送交 1 +x:1 +防灾 1 +x:1 +峰回路转 1 +x:1 +水轮机 1 +x:1 +南涝北旱 1 +x:1 +送亲 1 +x:1 +实像 1 +x:1 +沦陷区 1 +x:1 +相互 1 +x:1 +防火 1 +x:1 +卖力 1 +x:1 +咏叹 1 +x:1 +短斤少两 1 +x:1 +涣然冰释 1 +x:1 +中药学 1 +x:1 +卫士长 1 +x:1 +鸭蛋 1 +x:1 +访问 1 +x:1 +安乡县 1 +x:1 +天下者 1 +x:1 +脱收台 1 +x:1 +欺辱 1 +x:1 +丁亥年 1 +x:1 +恰卡奥市 1 +x:1 +声光化电 1 +x:1 +种植区 1 +x:1 +磨耗 1 +x:1 +相乘 1 +x:1 +麾下 1 +x:1 +司法局 1 +x:1 +偏爱 1 +x:1 +药商 1 +x:1 +抽击力 1 +x:1 +押 13 +x:13 +家门口 1 +x:1 +耳细胞 1 +x:1 +练习场 1 +x:1 +坑穴 1 +x:1 +相中 1 +x:1 +肃杀逼人 1 +x:1 +从未有过 1 +x:1 +杳无音信 1 +x:1 +疑犯 1 +x:1 +案发率 1 +x:1 +花露 1 +x:1 +相与 1 +x:1 +挖肉补疮 1 +x:1 +托偶 1 +x:1 +瓦岗集 1 +x:1 +人均 1 +x:1 +收款人 1 +x:1 +数目字 1 +x:1 +向阳花 1 +x:1 +琶音 1 +x:1 +土暖气 1 +x:1 +一举成名 1 +x:1 +炒手 1 +x:1 +涌涌 1 +x:1 +葳蕤 1 +x:1 +老翁 1 +x:1 +凯巴布 1 +x:1 +花雕 1 +x:1 +匿迹 1 +x:1 +忙乎 1 +x:1 +尽好 1 +x:1 +相信 1 +x:1 +欠息 1 +x:1 +窥探 1 +x:1 +触类旁通 1 +x:1 +信息茶 1 +x:1 +可可茶 1 +x:1 +民营化 1 +x:1 +日暮途穷 1 +x:1 +巴里港 1 +x:1 +伦理观 1 +x:1 +送信 1 +x:1 +命途 1 +x:1 +溥 4 +x:4 +舔砖 1 +x:1 +说服力 1 +x:1 +遥感图 1 +x:1 +漏着 1 +x:1 +宣传周 1 +x:1 +见到 1 +x:1 +光脆性 1 +x:1 +山北村 1 +x:1 +慷慨悲歌 1 +x:1 +忙乱 1 +x:1 +未必 1 +x:1 +利刃 1 +x:1 +恋战 1 +x:1 +尽头 1 +x:1 +汊河镇 1 +x:1 +入围奖 1 +x:1 +护垫 1 +x:1 +不三不四 1 +x:1 +光亮 1 +x:1 +花障 1 +x:1 +宏天伟地 1 +x:1 +隧道口 1 +x:1 +山阳区 1 +x:1 +晓之以理 1 +x:1 +学问 1 +x:1 +缆车线 1 +x:1 +仿纸 1 +x:1 +利剑 1 +x:1 +单簧管 1 +x:1 +光彩照人 1 +x:1 +尽处 1 +x:1 +时至 1 +x:1 +水害区 1 +x:1 +相依 1 +x:1 +东直门桥 1 +x:1 +狼藉 1 +x:1 +编辑组 1 +x:1 +从善如流 1 +x:1 +石破天惊 1 +x:1 +龙庆峡 1 +x:1 +粉碎机 1 +x:1 +展区 1 +x:1 +图片库 1 +x:1 +巡回制 1 +x:1 +护坡 1 +x:1 +练习器 1 +x:1 +扶危济困 1 +x:1 +晚霞 1 +x:1 +禾山乡 1 +x:1 +宣传品 1 +x:1 +文正公 1 +x:1 +磕磕碰碰 1 +x:1 +睡着 1 +x:1 +清正廉洁 1 +x:1 +寄语 1 +x:1 +唇音 1 +x:1 +相位 1 +x:1 +乔迁之喜 1 +x:1 +内窥镜式 1 +x:1 +弯 46 +x:46 +岔道儿 1 +x:1 +护坝 1 +x:1 +测算 1 +x:1 +扭力 1 +x:1 +精忠报国 1 +x:1 +羹材 1 +x:1 +童便 1 +x:1 +空口无凭 1 +x:1 +绞盘 1 +x:1 +睡眠 1 +x:1 +划得来 1 +x:1 +忙于 1 +x:1 +仅仅 1 +x:1 +相传 1 +x:1 +黄骅 1 +x:1 +寨顶 1 +x:1 +漂亮者 1 +x:1 +学长 1 +x:1 +清清白白 1 +x:1 +铜片 1 +x:1 +申明 1 +x:1 +相似 1 +x:1 +扶贫乡 1 +x:1 +授权点 1 +x:1 +铜牌 1 +x:1 +绚 1 +x:1 +睡眼 1 +x:1 +铜版 1 +x:1 +教师法 1 +x:1 +生命权 1 +x:1 +赣 32 +x:32 +森森 1 +x:1 +约堡 1 +x:1 +声场 1 +x:1 +恳谈会 1 +x:1 +展卖 1 +x:1 +斑驳陆离 1 +x:1 +有喜有忧 1 +x:1 +国别性 1 +x:1 +美蛙 1 +x:1 +地脚螺丝 1 +x:1 +倒灌 1 +x:1 +南龙崮村 1 +x:1 +庆功 1 +x:1 +沂源县 1 +x:1 +人心所向 1 +x:1 +东莞站 1 +x:1 +推拿 1 +x:1 +二十二日 1 +x:1 +包租费 1 +x:1 +祸从口出 1 +x:1 +饶桥镇 1 +x:1 +得票率 1 +x:1 +患儿 1 +x:1 +沮 1 +x:1 +声响 1 +x:1 +东门外 1 +x:1 +马大哈 1 +x:1 +方格呢 1 +x:1 +逞能 1 +x:1 +秉公为政 1 +x:1 +疾徐 1 +x:1 +增值额 1 +x:1 +眼角膜 1 +x:1 +先进岗 1 +x:1 +投资局 1 +x:1 +欺负 1 +x:1 +收费局 1 +x:1 +储藏 1 +x:1 +搭架 1 +x:1 +无以为继 1 +x:1 +航天界 1 +x:1 +玻纤厂 1 +x:1 +硝镪水 1 +x:1 +娃娃生 1 +x:1 +门庭若市 1 +x:1 +俱毁 1 +x:1 +一道 1 +x:1 +彝家 1 +x:1 +膝旁 1 +x:1 +老粗 1 +x:1 +洛山基 1 +x:1 +沙坨地 1 +x:1 +退伍 1 +x:1 +办公楼 1 +x:1 +钻石婚 1 +x:1 +听忧 1 +x:1 +寻救 1 +x:1 +青椒 1 +x:1 +提交 1 +x:1 +扬中 1 +x:1 +银行学 1 +x:1 +十星级 1 +x:1 +求援信 1 +x:1 +新潮 1 +x:1 +申斥 1 +x:1 +打抱不平 1 +x:1 +丝袜 1 +x:1 +花镜 1 +x:1 +导电 1 +x:1 +爆炸物 1 +x:1 +淮南市 1 +x:1 +软磨硬泡 1 +x:1 +五分制 1 +x:1 +远程 1 +x:1 +防冻棚 1 +x:1 +修理商 1 +x:1 +推托 1 +x:1 +占领 1 +x:1 +漂流记 1 +x:1 +负荆请罪 1 +x:1 +不满足感 1 +x:1 +神理 1 +x:1 +欠揍 1 +x:1 +签呈 1 +x:1 +推手 1 +x:1 +锵 3 +x:3 +入赘 1 +x:1 +老泪横流 1 +x:1 +德艺双馨 1 +x:1 +石头子儿 1 +x:1 +银行家 1 +x:1 +按理说 1 +x:1 +票钱 1 +x:1 +一机部 1 +x:1 +货郎鼓 1 +x:1 +疑点 1 +x:1 +入账 1 +x:1 +武安县 1 +x:1 +花销 1 +x:1 +汽修业 1 +x:1 +敕 2 +x:2 +重安江 1 +x:1 +龙固镇 1 +x:1 +十冬腊月 1 +x:1 +森林式 1 +x:1 +声名 1 +x:1 +补给品 1 +x:1 +未尝 1 +x:1 +扫荡 1 +x:1 +苗鸡 1 +x:1 +一部 1 +x:1 +制种 1 +x:1 +助听器 1 +x:1 +文部省 1 +x:1 +乐天派 1 +x:1 +标本兼治 1 +x:1 +检点 1 +x:1 +辽东湾 1 +x:1 +西线 1 +x:1 +糕干 1 +x:1 +买入价 1 +x:1 +纱裙 1 +x:1 +大河家乡 1 +x:1 +花都市 1 +x:1 +基藏本 1 +x:1 +卓然 1 +x:1 +水成岩 1 +x:1 +单纯 1 +x:1 +寻思 1 +x:1 +携机 1 +x:1 +报复主义 1 +x:1 +各有所识 1 +x:1 +西纠 1 +x:1 +人和 1 +x:1 +综治办 1 +x:1 +晒图纸 1 +x:1 +黄金树 1 +x:1 +褴褛不堪 1 +x:1 +尽孝 1 +x:1 +后半辈子 1 +x:1 +龙尾山 1 +x:1 +下结论 1 +x:1 +东港市 1 +x:1 +同调者 1 +x:1 +劳工部 1 +x:1 +远交近攻 1 +x:1 +情报所 1 +x:1 +储蓄 1 +x:1 +企图 1 +x:1 +增殖率 1 +x:1 +载荷 1 +x:1 +寒湿 1 +x:1 +乳猪 1 +x:1 +展出 1 +x:1 +碎冰机 1 +x:1 +各色各样 1 +x:1 +大中专生 1 +x:1 +未始 1 +x:1 +吉伦特 1 +x:1 +推推 1 +x:1 +泥丸 1 +x:1 +珠岛 1 +x:1 +少儿社 1 +x:1 +漏电 1 +x:1 +障碍赛跑 1 +x:1 +花钱 1 +x:1 +多存多贷 1 +x:1 +顺安 1 +x:1 +阿拉伯人 1 +x:1 +恋恋 1 +x:1 +府前路 1 +x:1 +人品 1 +x:1 +西经 1 +x:1 +联动型 1 +x:1 +巡访团 1 +x:1 +错漏填率 1 +x:1 +晚间 1 +x:1 +单组 1 +x:1 +虾 39 +x:39 +倒爷 1 +x:1 +钻工 1 +x:1 +呼喊声 1 +x:1 +结缔组织 1 +x:1 +旗手 1 +x:1 +开小灶 1 +x:1 +迂腐 1 +x:1 +浦东队 1 +x:1 +挖空心思 1 +x:1 +过后 1 +x:1 +鼯鼠 1 +x:1 +工业省 1 +x:1 +通俗化 1 +x:1 +人名 1 +x:1 +个人 1 +x:1 +芽体 1 +x:1 +索引 1 +x:1 +市优 1 +x:1 +雨花石 1 +x:1 +现 540 +x:540 +洗头 1 +x:1 +自动步枪 1 +x:1 +翠湖 1 +x:1 +不能自拔 1 +x:1 +开福区 1 +x:1 +漏疮 1 +x:1 +慌张 1 +x:1 +自然天成 1 +x:1 +中放 1 +x:1 +招示牌 1 +x:1 +人命 1 +x:1 +癖性 1 +x:1 +泥人 1 +x:1 +磕头机 1 +x:1 +转任 1 +x:1 +正离子 1 +x:1 +红葡萄酒 1 +x:1 +恋情 1 +x:1 +无人不知 1 +x:1 +主意 1 +x:1 +合同法 1 +x:1 +慈爱 1 +x:1 +慈父 1 +x:1 +还牧 1 +x:1 +儿媳妇 1 +x:1 +漏税者 1 +x:1 +染坊 1 +x:1 +森林带 1 +x:1 +初四五 1 +x:1 +人员 1 +x:1 +间 1611 +x:1611 +捻 4 +x:4 +新滩 1 +x:1 +合同款 1 +x:1 +粮袋 1 +x:1 +文笔 1 +x:1 +乐平籍 1 +x:1 +脑神经 1 +x:1 +睡狮 1 +x:1 +过厅 1 +x:1 +授粉 1 +x:1 +浠水 1 +x:1 +收购价 1 +x:1 +中部委 1 +x:1 +美茵 1 +x:1 +升级型 1 +x:1 +提起 1 +x:1 +风钻 1 +x:1 +罩棚 1 +x:1 +工作处 1 +x:1 +锦旗 1 +x:1 +门巴族 1 +x:1 +怯懦 1 +x:1 +过去 1 +x:1 +无言以对 1 +x:1 +畜 93 +x:93 +正三角形 1 +x:1 +见地 1 +x:1 +硬汉子 1 +x:1 +二醋酸 1 +x:1 +一阵 1 +x:1 +芦笙场 1 +x:1 +鞋套 1 +x:1 +腮壳 1 +x:1 +金鸡独立 1 +x:1 +西移 1 +x:1 +悻然 1 +x:1 +司号员 1 +x:1 +脑袋瓜子 1 +x:1 +骨灰盒 1 +x:1 +分委会 1 +x:1 +机械性能 1 +x:1 +窝棚 1 +x:1 +展园 1 +x:1 +收购人 1 +x:1 +看人下菜 1 +x:1 +老窖 1 +x:1 +学部 1 +x:1 +展团 1 +x:1 +沙滩装 1 +x:1 +黄鼬 1 +x:1 +反躬自省 1 +x:1 +图画书 1 +x:1 +序文 1 +x:1 +铜矿 1 +x:1 +就医 1 +x:1 +警报 1 +x:1 +声势 1 +x:1 +人参 1 +x:1 +独断专行 1 +x:1 +考核 1 +x:1 +白洋淀 1 +x:1 +乌海市 1 +x:1 +奔走呼号 1 +x:1 +宁家坡 1 +x:1 +韭菜岭 1 +x:1 +鲁南 1 +x:1 +折返跑 1 +x:1 +半导体业 1 +x:1 +新芬党 1 +x:1 +巴籍 1 +x:1 +面包房 1 +x:1 +老三届 1 +x:1 +驮 12 +x:12 +麋鹿 1 +x:1 +面包户 1 +x:1 +序数 1 +x:1 +矢口抵赖 1 +x:1 +活契 1 +x:1 +铁道部 1 +x:1 +下工夫 1 +x:1 +未婚 1 +x:1 +哪些 1 +x:1 +遇难者 1 +x:1 +纬 6 +x:6 +额手称庆 1 +x:1 +光盘机 1 +x:1 +句法 1 +x:1 +人化 1 +x:1 +漏犯 1 +x:1 +人卫 1 +x:1 +签到 1 +x:1 +多拍球 1 +x:1 +寄费 1 +x:1 +艺风 1 +x:1 +基本型 1 +x:1 +索取权 1 +x:1 +谢电 1 +x:1 +满贯 1 +x:1 +教育学 1 +x:1 +鹗 1 +x:1 +黄龙 1 +x:1 +咒语 1 +x:1 +推搡 1 +x:1 +坝 19 +x:19 +过半 1 +x:1 +彩印厂 1 +x:1 +排他 1 +x:1 +亡魂 1 +x:1 +欺诈 1 +x:1 +歌似潮 1 +x:1 +旦 10 +x:10 +上传下达 1 +x:1 +咖啡渍 1 +x:1 +淤血 1 +x:1 +正经八百 1 +x:1 +间谍 1 +x:1 +收购业 1 +x:1 +创新奖 1 +x:1 +测绘 1 +x:1 +藏青 1 +x:1 +顺差 1 +x:1 +扶绥 1 +x:1 +弃糟取精 1 +x:1 +订正 1 +x:1 +黄鹂 1 +x:1 +塘公索 1 +x:1 +麇集 1 +x:1 +渭南 1 +x:1 +犯不着 1 +x:1 +招集 1 +x:1 +哈拉兹 1 +x:1 +驳 7 +x:7 +择优录用 1 +x:1 +侣伴 1 +x:1 +力排众议 1 +x:1 +踢 170 +x:170 +未央湖 1 +x:1 +规定性 1 +x:1 +正版率 1 +x:1 +签发 1 +x:1 +及至 1 +x:1 +普兰店 1 +x:1 +随机数 1 +x:1 +人力 1 +x:1 +铜皮 1 +x:1 +张罗 1 +x:1 +宅舍 1 +x:1 +在押犯 1 +x:1 +幂 1 +x:1 +银行局 1 +x:1 +天知道 1 +x:1 +糟踏 1 +x:1 +寻找 1 +x:1 +年龄组 1 +x:1 +利器 1 +x:1 +渭北 1 +x:1 +资中 1 +x:1 +推断 1 +x:1 +鱼花 1 +x:1 +美色 1 +x:1 +美艳 1 +x:1 +寻扯 1 +x:1 +热泵型 1 +x:1 +眉纹 1 +x:1 +钟楼 1 +x:1 +由头 1 +x:1 +未定 1 +x:1 +游医 1 +x:1 +分裂主义 1 +x:1 +兼容并蓄 1 +x:1 +南瓜籽 1 +x:1 +间谷 1 +x:1 +税金 1 +x:1 +景致 1 +x:1 +申报 1 +x:1 +莫愁湖 1 +x:1 +伊加特 1 +x:1 +疲顿 1 +x:1 +袜筒 1 +x:1 +护卫 1 +x:1 +制约 1 +x:1 +展场 1 +x:1 +推敲 1 +x:1 +排便 1 +x:1 +不 30314 +x:30314 +眨眼 1 +x:1 +过分 1 +x:1 +申扎 1 +x:1 +横剖面 1 +x:1 +词讼 1 +x:1 +维生素E 1 +x:1 +颠沛流离 1 +x:1 +维生素C 1 +x:1 +维生素B 1 +x:1 +维生素A 1 +x:1 +水轮 1 +x:1 +护兵 1 +x:1 +灌溉渠 1 +x:1 +食用油 1 +x:1 +增强型 1 +x:1 +秋令 1 +x:1 +永乐镇 1 +x:1 +活塞 1 +x:1 +千里眼 1 +x:1 +鞣料 1 +x:1 +岩性 1 +x:1 +崖顶 1 +x:1 +城近郊 1 +x:1 +戏剧性 1 +x:1 +非手术 1 +x:1 +防疫 1 +x:1 +忿忿 1 +x:1 +命在旦夕 1 +x:1 +南瓜糊 1 +x:1 +投资家 1 +x:1 +每周 1 +x:1 +词语 1 +x:1 +模拟制式 1 +x:1 +恋曲 1 +x:1 +堕胎者 1 +x:1 +新棉 1 +x:1 +过客 1 +x:1 +烟霞 1 +x:1 +钨丝 1 +x:1 +双人跳 1 +x:1 +脉压 1 +x:1 +就势 1 +x:1 +就是了 1 +x:1 +辅线 1 +x:1 +船营区 1 +x:1 +千瓦小时 1 +x:1 +黄麻 1 +x:1 +证据关 1 +x:1 +词话 1 +x:1 +编著者 1 +x:1 +所见者 1 +x:1 +义学 1 +x:1 +过剩 1 +x:1 +门路 1 +x:1 +承天殿 1 +x:1 +农业部 1 +x:1 +欠条 1 +x:1 +主报 1 +x:1 +企及 1 +x:1 +酒酣耳热 1 +x:1 +疾家 1 +x:1 +当局者 1 +x:1 +落耳坡村 1 +x:1 +染动 1 +x:1 +训练场地 1 +x:1 +试航 1 +x:1 +顺延 1 +x:1 +声像 1 +x:1 +束流 1 +x:1 +证据力 1 +x:1 +企口 1 +x:1 +加方 1 +x:1 +石子儿 1 +x:1 +掩 24 +x:24 +强身健体 1 +x:1 +鱼秧子 1 +x:1 +加速运动 1 +x:1 +新款 1 +x:1 +草菇场 1 +x:1 +新欢 1 +x:1 +始作俑者 1 +x:1 +大而无当 1 +x:1 +建筑学术 1 +x:1 +过冬 1 +x:1 +审判权 1 +x:1 +麦禾营镇 1 +x:1 +主抓 1 +x:1 +风雨交加 1 +x:1 +单程 1 +x:1 +苏呼米市 1 +x:1 +红铃虫 1 +x:1 +以农为本 1 +x:1 +词表 1 +x:1 +虐 1 +x:1 +外源性 1 +x:1 +珠东乡 1 +x:1 +总危机 1 +x:1 +渌头江村 1 +x:1 +海兴县 1 +x:1 +餐饮 1 +x:1 +徐行 1 +x:1 +膝下 1 +x:1 +市井 1 +x:1 +展示室 1 +x:1 +繁丽 1 +x:1 +欠有 1 +x:1 +芒果树 1 +x:1 +拳击手 1 +x:1 +无军籍 1 +x:1 +转椅 1 +x:1 +新步 1 +x:1 +顺应 1 +x:1 +单篇 1 +x:1 +展品 1 +x:1 +代办员 1 +x:1 +玻壳 1 +x:1 +旗杆 1 +x:1 +花酒 1 +x:1 +双数 1 +x:1 +胭脂 1 +x:1 +足音 1 +x:1 +一针 1 +x:1 +白塔乡 1 +x:1 +茶亭 1 +x:1 +企协 1 +x:1 +藤球 1 +x:1 +人儿 1 +x:1 +躲开 1 +x:1 +每场 1 +x:1 +中子星 1 +x:1 +月明如镜 1 +x:1 +懒洋洋 1 +x:1 +限定性 1 +x:1 +粉碎性 1 +x:1 +橙黄色 1 +x:1 +洗尘 1 +x:1 +宣传司 1 +x:1 +既成事实 1 +x:1 +架空层 1 +x:1 +培植 1 +x:1 +乘客 1 +x:1 +芳菲 1 +x:1 +串线 1 +x:1 +用工方 1 +x:1 +个体 1 +x:1 +个位 1 +x:1 +锣鼓队 1 +x:1 +不名誉 1 +x:1 +发案率 1 +x:1 +笨重 1 +x:1 +计划部 1 +x:1 +黑岛镇 1 +x:1 +得病 1 +x:1 +防盗 1 +x:1 +恋旧 1 +x:1 +市局级 1 +x:1 +隶书 1 +x:1 +吹管 1 +x:1 +陨石 1 +x:1 +顺带 1 +x:1 +复馆 1 +x:1 +鸭肉 1 +x:1 +东借西凑 1 +x:1 +人仰马翻 1 +x:1 +繁体 1 +x:1 +独立词 1 +x:1 +外委会 1 +x:1 +珞 1 +x:1 +邯郸县 1 +x:1 +过关 1 +x:1 +拐骗 1 +x:1 +防盲 1 +x:1 +防腐蚀 1 +x:1 +无触点 1 +x:1 +毒副作用 1 +x:1 +琅琊乡 1 +x:1 +窨水井 1 +x:1 +炉条 1 +x:1 +每块 1 +x:1 +漂白 1 +x:1 +光盘数 1 +x:1 +豫西 1 +x:1 +景色 1 +x:1 +钩 18 +x:18 +微波通信 1 +x:1 +出其不意 1 +x:1 +刮刀 1 +x:1 +例 289 +x:289 +实现制 1 +x:1 +腕儿 1 +x:1 +侧根 1 +x:1 +觉世 1 +x:1 +驯化 1 +x:1 +襟前 1 +x:1 +总论 1 +x:1 +农林厅 1 +x:1 +虎口余生 1 +x:1 +此法 1 +x:1 +连阴天 1 +x:1 +总协定 1 +x:1 +泉眼 1 +x:1 +浩浩淼淼 1 +x:1 +耪 1 +x:1 +花都 1 +x:1 +福安市 1 +x:1 +寄赠 1 +x:1 +顺心 1 +x:1 +黄鱼 1 +x:1 +利名 1 +x:1 +更进一步 1 +x:1 +减税额 1 +x:1 +有志之士 1 +x:1 +茶会 1 +x:1 +勺子 1 +x:1 +丝质 1 +x:1 +充气棒 1 +x:1 +花繁叶茂 1 +x:1 +东门屿 1 +x:1 +炼丹术 1 +x:1 +紫雪 1 +x:1 +极坐标 1 +x:1 +西端 1 +x:1 +试药 1 +x:1 +格式化 1 +x:1 +顺德 1 +x:1 +价格法 1 +x:1 +司法宫 1 +x:1 +人像 1 +x:1 +主攻点 1 +x:1 +西站 1 +x:1 +稀疏 1 +x:1 +染发 1 +x:1 +原封不动 1 +x:1 +司法官 1 +x:1 +民管会 1 +x:1 +护农 1 +x:1 +长治市 1 +x:1 +弱败 1 +x:1 +滔天罪行 1 +x:1 +弱质 1 +x:1 +睡熟 1 +x:1 +飘荡 1 +x:1 +首倡者 1 +x:1 +扳倒 1 +x:1 +马仰人翻 1 +x:1 +餐食 1 +x:1 +牧医系 1 +x:1 +黄鳝 1 +x:1 +尽忠 1 +x:1 +索性 1 +x:1 +亘 1 +x:1 +护具 1 +x:1 +美育 1 +x:1 +声光 1 +x:1 +美肴 1 +x:1 +尽快 1 +x:1 +榫接式 1 +x:1 +左上 1 +x:1 +镍币 1 +x:1 +规矩 1 +x:1 +红十字日 1 +x:1 +染化 1 +x:1 +光解作用 1 +x:1 +尽职 1 +x:1 +尽心 1 +x:1 +灼见 1 +x:1 +一有 1 +x:1 +推杆 1 +x:1 +傣乡 1 +x:1 +顺当 1 +x:1 +正房 1 +x:1 +展板 1 +x:1 +独木难支 1 +x:1 +宣传办 1 +x:1 +珍珠城 1 +x:1 +况且 1 +x:1 +生平厅 1 +x:1 +个中 1 +x:1 +略知一二 1 +x:1 +企划 1 +x:1 +个个 1 +x:1 +于都县 1 +x:1 +无烟日 1 +x:1 +番茄酱 1 +x:1 +取决于 1 +x:1 +雷锋班 1 +x:1 +槽体 1 +x:1 +配给 1 +x:1 +声儿 1 +x:1 +拿手戏 1 +x:1 +哲 11 +x:11 +外行话 1 +x:1 +海斯队 1 +x:1 +丝路 1 +x:1 +令人心悸 1 +x:1 +回库 1 +x:1 +入库 1 +x:1 +出库 1 +x:1 +进库 1 +x:1 diff --git a/src/tokenizer/etc/unigram.txt.uni b/src/tokenizer/etc/unigram.txt.uni new file mode 100644 index 0000000000000000000000000000000000000000..adc821a2ad0123979e9047c56ce63164a9f3e6d7 GIT binary patch literal 3729280 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

fowo+?qhOA!c%_+tSJeO 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%0DD0gkn{$?RteiC^-=XHRm;r$984!td6@5Dh- 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

c!x2 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 z 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

  • UOk3ZhjhN< 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

    wJpq8Pql31 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%0DSUIzQ6D5X4U9&A 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

    }tI!2ukq68LML|Ar4p>cI?OA*-J$udz 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 literal 0 HcmV?d00001 diff --git a/src/tokenizer/etc/wwsearch_mmseg.ini b/src/tokenizer/etc/wwsearch_mmseg.ini new file mode 100644 index 00000000000..86695e7c212 --- /dev/null +++ b/src/tokenizer/etc/wwsearch_mmseg.ini @@ -0,0 +1,5 @@ +[mmseg] +merge_number_and_ascii=1; ;合并英文和数字 abc123/x +number_and_ascii_joint=; ;定义可以连接英文和数字的字符 +compress_space=1; ;暂不支持 +seperate_number_ascii=0; ;就是将字母和数字打散 diff --git a/src/tokenizer/etc/wwsearch_mmseg_uni.lib b/src/tokenizer/etc/wwsearch_mmseg_uni.lib new file mode 100644 index 0000000000000000000000000000000000000000..2b28c3ff5536f7941d7ff83271031358cca847c9 GIT binary patch literal 3730552 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®)T9*Z&STMy$8j+2-0n_t0*k$0Fx?z4~Y9@z4{fIoI@revqD9@pWNL zXY|bJS%7!0d--ku*W=keb0zxR)AQ5d$lVL+Nx53oMnu2fyQn?!mQe35W520q^3E~#oB5s6(}>t_=6?DnFpgMOM&6wD zrlHrN&A@MLUcU;zKH?jRr{ep7-r6f*&Kd6aF<5U)Y)!u!oM%pLhi)flZ}P9>KLhWo z0cd)<&}+>*awzJ0bKSw8oo7z(X>Jj@52LRqv3q-dy|v!xJ5kp=uTSI_lV1l*AU$8< zotK_H_#NQ7{;cy(oM0U4-Dd1eXAMT3VZYur&X^9H;A{92tPiI)3ciV)J?70>v)480 z{l-ME@m4qj_TNu_9PB0j7E-@C*O;@%HTGCP5Srd|B6V}l)9=Kej!q75UY`p-r6#Y! zkC2Jn^r+dVPqioT=Ye^>IxBLnn*-S*ub&HNN36I1Y1AJ3t*NIz_M8tdLOyVv-kkkM zIcEv<)$r*Ig~@LK`>nkO<-j<3*BLKHPlLbdmv>>g3uGg=Hl2Dl* z?@jMUwOy!Z_q_JoyB>;0tpAz5Qs^eg9(lccr*po8cMs!_p)R;4FO+Bf58&TG)!zlx zJyqAJ%|kCj-P7|pOWhv21N98{w4uj))4eZ-^tiXPdRJ+4VlmZtyBn#Ol1Lf(FJ-bu#U z@qHto{Al8wRMWSnr&3P#H=7aVQ=2^U1l^Ip#V*dhW&BYmfdmmU!&XwE-&2$WJ0}gx`#x5PjE1UlY_juP1r$Jk`5RO^>~<^=IOD zP0u>~7HCCX@4kAqHM)e{9k2-OTOGOrod?$R>G=Zhnup*?=*$drN5S>ZHK%q7?TU(f z?1K3)KK#3=>o&q(@NOJ~o=(5{^!Sb5gudkM_3XY+w&-&|Ykn)ggR|VjGuU?!zJu@K zQ8*nYhPSo~teqG0hN9-2t5=7i;x`(J`p)L{>L~PCa=*Ztc+a0J)ZAex5%Cecb=UX} zPJPabzW*;z?CeL;A5h7JcVBbA6X%F{5-R2vfZsAJ=YdUHP#n>!TwXUMs39=ea*g%Lj&`aEjQZ>BE^*6f{+`VC#L&r5E7 z%v})qS5dv+R`0i6jOGE?={-YwkEM}chT3xh=!<|gzrDT!q~}fiY2Y_W-^rZw*PvBl z5BnBI&&c3imd^h5w;5W((eoyP>E&{*R)zAx0 zgtx9&{|fyZ^$gB%rh8gHiQ3~g$$TAupCg}qLt=aUCiZ8c$GzO!IGZuwyEw76>(Gaw zIp}-9+2qaHuRj<3w#NDkU;^>o%qbW7lxrVxZhCwN&p8M>Kt6JM=jhEP3G_CY2-b^6&Nb%jHD8>(@8)~=hN+P+`F|*T59lxFKK{Q!B@rz&6ww|kNp?Hh zk@nsciBzcUN@yx=iT08-L?kN7NKq-uvm*zNoxKel;A3dcUaOj}8EThuE)Qhd&(g1H|?^dl39tbH?92 zLr`DS|b2H$~`QQv{8JKUMB6L|LwjTz_l>M%4fwV9x|_fyD*e+KmS>D6ada))3s zoI#v&$A~|J@#K=XCl~mxbl%z${O_;_^gF{(p{94I=e6IQIu&)sygnbCe&sg@XV9|- z@`U=XGX4>)&jEYgt5@fuXF(2dxA$2XIqUkx;0|N`ulP$)<5y63xL0rOH8e9=Pu~0c z?%M*Z@WrC8|D4>#XuYWGt3r{el?}fZ)jR7x_nTV>7e%ap56+EPzn8s*P$>$fB6nGM z_iVx!gxXLa_A%4w6mQKQXVT?8J*W3lw}CV6)BlGZ*P(U87Y}cJ2mUwo3$z6^hTY+< z>(wt&X#iJ16WANxy8dHyA9@5jKyB{pJJ5T3F5hX!-qSOD2lc@D_3Q#C~?4PZ#I}O`&^m z0V>u;gY&0fSsR?3@&5YfIG4Y}8$vHIpPjszOV_!?p251_cU#Gb&m+DM-v&IBXLgrr z&9ht(J(KaC%RT1qz>k6a;mzv@vA;6;LU?D)>pS8{MqHR!e+}rZ=?4bh=W_Bdpw8>n zV(4AuMnUqW$jypAeHj=LvA#SECzffEH|M@9P+3IY9q#p>-rwAVaQgKWxfj9ttC_t9 zW=E_yXHUAUO@|xFuZ})_HCP_8-ZOiDd)%L{rT7)#{c6)E<~G1GxP@46U0)w2M4Y^R zW8tmHH=^e@_>g!dSl<|G&0hD};~72At5JUlb;fsNU(~*q^r@{-ao2p92iEkyBL|?T zU+IXXo?W1z&?TX9m%0F3mV^uFgpQ`X4nOg37z}y$rv@ z639sISvZWh_5oN^3y@cD3at}*edtzd?#fB5y33rqPJs7yw>lD)U&((DXGDGsnuB;Q zSaa?YSRCFn+N(}P525bU|AzP8=In8oyWa+D2jC}ofxO;1y*dLGKcn$XG#ebG?;X%P z>#lVD6Seu&iU;PLH&+yXCiY$V9@GwfHELziv!iD-H8JPBJ)aPlM$duVup+#5eHGY3 zk2QO9p;;oQF9-J6|0XKt8q@m)q-zh}@3cwebKuQ+Z_k&mns{p!sO^J$Lq~=BXVkpE zE7WD7A2H*s=g?Oo{~h?wQ_XLQ`lskN@Mp@r-kLvaekXoEw?h-Kz5{J`O1u+aA>utz zyODbwjr*8$#vSSU2JcLBNPEq>e?KbL(p4RA-*=$5Pk#q=49-Nmfm#vlKmAIzywsd^ z&o5{Ls03ZX9VwS5au1>IYr|*q9holQg~rah(`V^(s{zio2=9IV#rFpH3=JI{>NE8D zoY|1yhp7Gftl*5X-W~274vnEiczJ=;jQVQ+_^2WJ|uf%({ z2g#R5pN6(D9$G^|di3V(y$bBHrgx7$lkiiZD)vi`)dL3vC+yfatQKMeJEd3{uG&HdKg?fml4HsL#< zPk?<@>C-<0kHDi~PXE6y-+8U5KMC$%66y}`u{~mUd9OO`v)B9Sd*WY*bMVgVN5jU@ z|8?JS)ScY``lih5-K%d2ZxP=K?)oge@5a0E*39|NGj`6IT;Ms<^#y(xlsqlpf!LaJ z`cB|yH`e=(8%*q<4b`1$Woqj6p?8O-`+Z666&MA2_w}Mj?Tzk^`se5-NS8h4?D_hX z{PTEczJgD{8F#y{KfV9KuY$>-H)pRq>^%Y>z!36!cevAeb5rpLz#ez#e}JuE?bq;6 z(yMn)uMS0hH~KsIY*4d=zKouL-$8HxGxR&-&(t4L`yM?8*32!0qmV9Z=F;^%ea_f( z5Zr4n6D%e6o_j(6Eu0ZG`=;W}Ij6UF`c;73KI&^g{|}l26>~Ymr@6V&<9_{ou*X=h zEL zM`C*m!wqnlSYHwH!@BVH>+?WfFn$mHiT+C>-hi63$NKwdY4Fd8HGN&E2i8AC#oXu6 z5InPI^(?Aq@J!a+3PFbO>1@`n4lYIQakhPE zJ5=wP|016eHD|B8%0e-)=I2Y7IeU+QJ)T3~n7*v&kI+5xdh0)-BciVF302^3_$|DB zdi8fydIa{R>o5E@V4waXXanBU=j3j+8d&Qb{^IaAqql=`^)4&q0muJ|KqRiszURYrX_o=dM@67jXZCZoz;BDZ-g-+^rboUtegNK|AwP?ApMW`cx%;)qIp2|-+6nCnGpTux zH^96(dz?wvQ}{jLcagrQJMf;tIp0M?QQtYLyZu>q-`#lMHRiq7_uww|b#V8lh%?h` z{;P;{M!b>OUO%hPw{GOygx((Nne6qxgYoK+(1%gI_cH%zeqEH;tY&!RwQFC7Z7GwZp zz4|sPS>gX)c=wqr3+tg8*srevwIkk$iaG0^$zJEuRSRDZtbY{xG5RUg2XppVH&+iD zLV36qJ_mEw_0C#LR~>vou)Y%&b4}pl;26(M>Jon)HT(7IUR3wJ$I{}FmL z^cX5P2Av~+9JSZ;rR!h3e`ejI?+^LGcckx2ciKNJ;s$tod=@^Jbh+EUv-mvrxKFQU zN8Rat{GDD5HP;mN9cSDg`oj6-_0H*Y!+jC!+u?`874YOKKAj_J{^)g&z99HJ#8~g| z{wl%fg!*7JcT5!MKR^&J{-=A@?#o1tZ}$FlW7V^p!#Fb-o{r z26N-l3aB~z^@H$p!C7}!iJb4kM#R1gRr{^^jxlZy?n`G#&n2n%v?pC_@Dl>_)!Ajv zy?V6<`VP5uk*`I(7C#%Tc|UXZ+=BYM);ay@S3`2nTGy+MP?)la# zFY-O{cfyK@^&jAmMBJPBO#BnzXZ3TY%N_1dm%YyRL${*dPd@;b6U!TsH}@bMB9@dl zx1IRi=o>`*J^t^AhY*Xoboq>Yets6ubS_MTCy9N>c@Dk1+?^TC3QvLFx?UZDitoS! z^zMUE;jNFvtLAo4%YlxAOi+S&Ay_w;5f&4dioE_GaEG(L6PKaIK`k4aK3DCC52EgJ z@AS|YP`x$%xsWcOz29HDW>d=r&g<1Vp>t6w0Y5YIA6OXPKK)`iLEczj4!;R*4YhVD zdEb5J)8#Yq9g?oM@qbeH-v2!h-nwU3&8Y>+e-56>*cta1jo5Rz>pHjz)`d5(SKmd? z1Lqru_6of_v_ojqP-ncyR&e%aaQ^Ag!J%KH*6)b;iBRwB?0pe8KubUh=nC(H`|WKE_FMY} zdcYT8{hd&AmB4pkcGO+Xz&U5sUs3T{Uky3Id)apvn6vL#=%1+Gn!SEE>1vLD2<-ny z1#=ns&mVqw=JlDu@6cGE1^n*1an2%Z>~Q6k%-SG7IQB%UmQLCI-j~f z6W&kX27iCVxrv{{kBvAlv3>ba-;usA{mgz&^B0kK#vS%Ldoel~btc`%Tqkl}plJAO z@b;P0yU*I?;LoP9UM+@-`In(Tlp@w!*O!GSh<$g~h`c%L<euhHGAu!=Iqz|ouud906&%5TDS-NGuDRO22`F0f7jlL`VLcl zcd5R!RL|mB-Q~P9eFJxI4DXq|hv)DfYogXZym@^`*b{wv^PSLHW=K6rY3$lXmQS;{d!aEV`zrsHQ1M#a+-<>1S954zt!|z~^ z-aYnii~M+0@2tDh^*7$yCeVKd?s5JR=J!S3_%UL0_6|es&4k)-&0hPgJq6Z`_4BFy z0iVJa7)?&^J8>?0DX7-$b_vu%FJ;wS~V6U;h9<*z4{62J+14@K)SBO7Xa^VJzdAyYt8u`==IR> zl=?n=4e(yhxl=W#rkRJ><2%Gzce>A6^_$TBsC0&!&=#!S0O>l6x8|JwC+G4A$)}k8cXTGku5Zo5ShXXzFFj zw+3gP4u1hV^zPGN3huubo{xNfa$>G9dKW5B!bBJk&ReS%Ipa%+Rd;qHKNLp7V6bMc zIBL#5y*u4e3hy&FuUAW>?x+oOU;$Jhr|$>%fjxTrtu4ks1HL00py_IicfU3L)zRym zenjLaq575ZI@|{4lE0B&YtHGbfj=Y0dbN6JjnJCtoAk5;y+2EDgE`-k9Z}zrYP#&T zuL1q`x>w&Q=8g4DU{lnS-$FbYmPh_Jdh~aL-kN?j+ym=jBWwrvwxUOGO>fP7TYP)) zXVh5lXZ7^^(4!m0DaiS5~YN}sud5uX|TIYWIn`o7E_@hH@t?$`Tnv~D~m@?%5Cq2|1o_3`-U z!Fw3%)rsg|_P}&}25^UGdJnAGljiJkxAlLa2;P|k_)Msu_dHkw-qXHx%^`Ni`|8!X zsI%T{A^u`8_hH5T6gs*<;nC( zD;0gE(Pv|yIsIT54c7GYVKG!B*1KP?RtmimmHyPLqVrH|?(<#QDCVraf`0@&tDmJM zm~+3dG2_iO<6tOIKk!dtgykGXVB!n?02 zdA)sl^;Yx)a+~0d(9P%+NVWU$<~|1dwt%^|%+5x|ocqjugx?x*`?yaBbOE^mp!Z%& zA?2KLzAH6ntlfdWhi(J!yFS!DYb%Mrg}+Y8_a>hS?7tU%6I~9kfxGqgIO`sJ{)7J& zyqA6bBWGRz6FK*#>p^lp3+sCIA#^Z!Mq|D2NZ*A;KuuT1h$o|--B~~5MlknB_!q)| zkLokhr+5ETcrmxi9E`^Qg029cfw|AY++J|bp0VI(GS;ug?}w?8FN$9RK0BZ9B=Whz zo*%%ul>3_4dw5Ut?l^+q2j0`Oy$j~-^!YXeKo*)d=}oiUi}=ETi^@09n9<1ov2&|U&3WzUSAxFfbYg*&?WRZT9*7h z5&w;*UTf*M=)Ir*47dV1g|8pJ2YM!S2K}$$&DrC;xj&#A_!+&Q z`IPh7H-}zO9j*mGvwePM)z75n1A8;v_W$*obDufimHDm5<(Zx90^TPJJv~wT^>^a$ ziZ~l_cCgpF-kd!pVG#6zCQv5)!{{&=&3#Lu*6hv0oVCS~cb_?Xot;gbk9Y{a9khbs z@Cg0BBMVS7=bXL@-d=n3SHlDt7k+Yh`!AutC$Z1do=4$+7y;JoEsmPAU*8Y^0+b4G zUSAHTkoU9u{Pcany0z~x<B#ZN@1@VReAt()`R zmf~xPtHUDd_Bw0MolBr)@H}ddIrlhYZW;`PH{dn)c0jws%HUbl-@)d6N2#Y@epegG zj{#@>%*N?@J8Hj1{YyUJ>f~ogLotWc|Cye;To8 z_A_13>SVn$y~~I%k2qWFlX>@8^Rw@R$0GkkXu~!q`|7nlsa-<%hq}|buV6ns9{#8B zhufW;`-s?FU+$&%zIyduRMwLJ0Y<_o_&WF*{U&nnb~w53ijF7Mci~uSha&zSZ~rgg zt^?rgqwF{5Zgbw(+;qG%pMc(X=2Z0eh{tp~d7tz>{!QNAmqC9fJM_E4yZ0G#=fE6t zdTRw?9#jtf7WE$X==Xv%<3aBp{n@aGcm?c+*TJ06%I7`}pX-z!{e|GXwF}@NeX<&? zxg%ZX&L!t=pWB<@OjgjlXEt7r5{tETU4+jI_ANk5M(j@aEs30Ueg3E)r}iN@W#DDOwZ!4C#59bEjwc5w67Vf;w)v*1A(5%GtiJ|myOyAjU}Elu8;JrR39b9*B$hj*8Gy;>d}L~b7R zhx@^t{>rG?r+!21zORkcb~ou_#GMRJ%e-hx@$eW2-Z7L7jr%vpK}-DnNinozz>PI8?oN+ z`hBpr4b1HiZ;!R!s5$SWACC8D;xo{j??e9M$R(eiXFqB`MW5dO`%zg*ejw_1YhJHD zfIb9%N5*<}5Ngfu{$bSb&b*)0!p2e9R=;@a^ zcjWS`UZ^wH+~+Q9t3HQj1 z9)a3mzh3=B(@0pV42TV#IoLbpq$Be#2k?qYuIjaCfNlf8y1@LXV^7 z>@|M^y#SmU0)qo{b)g{K5#G=4=T4V3XWZ>RcdHNbxeKG7+4G&vU#Gdl`{~sjs0@w# zx#5Qq=f^*Swg&I_6qxs2SPu1fvFh(`)n{v;&ro%jGwyKC`?+&e#OeGON6xxlEsV-= zdS8SIF@Gt!YLR;!?E%HfJrUlT^X5uJFJhmq&%;?~tXq2qKMuTy=bIO?_43p!fH`CR z6R3Z!+lbs^7!UQ~6)`+gFAW6(45jmcYcW(BMQYsS`` z$&9)$S7=Mr-b*5Ozqwb*-3QA?s)PyKp4=D*km*blRSU^g90oc$Vr>_pF}%N3b@Oyxw!`Kf?QLUjqF%;h&+F zH85wtIn}csB$ov}6SBj&@Jq?3nrE`#+IaA1z*s*C{-y4$Gy3nM-`Z-tKPzvb=b_F` zMbCk~rgRQ6uzX_zV&!@1FAnOYFCE0_XfBT?D1#r7_;ifV9j~`-{k#SG~R+< z2(@5)_|A0mDKkg!((s{6AptxQIQgXKWJlWl?*& zMeG?oYr1L^+w&dhJ&!&UxZ_8t33q_GYoSutz8dGB4>~9&c>*@mjmdvRCiq<$>ubY15$kUTzY}vKBX4dQzEdzC6~B{-VC~NEjp=*%Ucz?p+m{eh%-A+?%LA%`C*5b5A?=bbz-a)|;~@U0sP66Wil`oHN%Q-i=sq zkM-ejDDrni&nv{Q!qTYO_arQbZ^K)2c6H>Ob;kSMi&yVM_4XLwk2m)ovAf)R82p(Z z8-7Q`_O8MI5w%~!&p`FRfpfoyy8qGG?Ota;fTM5(tm)G=oY;Fgr?D>Nc*2=4z16?6N+-QLSH_-;G__F4Py4Dq4pGq3*+ytlDl zJ&cO?t_$6uDYS*`V9vgu&_2)}{sQ|`k2Pn02Yc+--vmA3Sa|b#_0Ldu`S%a}d!_$C z7pMid8k09?ues)sAL_w{U~diR4L!h|-kx5Nu6}rD&*JZ|>fNi)0iB8Mb*FiA9r3qC zd@k`0^8P*CyU5)M=IpUQ7yfCUweL;;z0UqU-j?{g!CLZH5D$W9pa6NjId{6poLUgQ zhTQYu+5BAhfODh4THo+h!#|Dcow3gy&P)SqC5ZLz*H6a31S2_jO|(qptm~g5Hye!0 z5sSGCiT!)mbMOP;ad;8ljks0hhN3S(3$XWUX3V)yKNY_cuEVcFTZ1|4=G5y^ce}%0 z)%;E5-R-@ceHrZaK6-cAWBk9ah15EM@4T+)YB1;i`pk+suEH`>>l`dqxT=~{&UBI@m9PY2Xqcj@1VdT0CsygMF- z#qfD}&tPp?P4_Y9E_=MEXGqtt(dRpI1m4f&=iVLp)ORG}|AhV=u zHqgHreqwmvon!C^!SnnQn)ZHAZ13aTcOB|Gatf-q=5w_6BzPuceMWF!;m`y4o$xfV zK2zlFH>W;>il4=JBz`pbnT+*i!M$gMULI=wIlMX^6+ctesJqL(>9W^nG!^wTJEvEt zq4G8P6VBjg!8dqwKfoHWmYclZn%;SP)!C@{EarjF!n|IckN(J9p@GZuDL0PWSsRH1-{*-WuxsXVkrC zGx!4Pf%h=BZqD7t>B@q?7-~TgaECq4+V>4utHFJaLyu7RSyT6;S3;$T5280h4M;U} zSAqS9QSX)R?R~Pso!}1hZNZ$q?sC??7GUi*&XEIk#{8YcInmRveB_*I0QbW)^!dJg zDb#n4u{C>7zcTXAMLFxa^=c+`06Fj5CNxXrtn2TMyuF^W30ww)!WR$U3hf8y(WieN z+-uGr_gQ-(^11Qe)4aX_c&`C`4&RghZcyE!P6>TA^iZht&Z-4b&*o>+dxq)I4XhU- zHwNDw^wz3_xf##}ij&vdQw^LmXU*Ohp?Bm99XkQKM~%CyTbcS{a!qa=RN)Uh@8DG*!dnR z=Dd%&ZTKC~CcI~Lk9Biu+t7BXekXPPA~aoHiPsQYbKY9oW6eF?P+3eZUAyr9>^W=y zvWR^rK8Zj5>chMnyTfx^Q|-6rj!odZa4MPsRCj%fiv8}=pJ2{^=JFW+6L>cKxX|?Z-EVCrJ;$LC z%!4uHPN3HHnehuFc86#6e$MO$d%uKlAsh8cpm$z>A!LVX;qCRF*3F%XUj^wpC*ohw zT-09zz5ROiWmJxkpMzc$`Q!@`r)vTJ;;8Ev!TAyE-Qj)A{e@qO{u%ev=Yjn2T6piT zFAN#Lcm=u&DnzVzhx@GAYb`I7gYxipc+ci}-D55v6pi?u&~>PkfDMoptl8^a%AG}A z8S20X;jQa^M;-)sc>fFFJ7Vh}*jXD?Gfwkai$^M1onM}iaB?>;~J<1`@`F(KL{nkSl;I(SKO^3o+?_Bs^j6f|EVvsUhbb_Y=U5x{9jChU3DliWg6}Hx>GHerd%F#0osv)W zq*d7CJv^u0dwPaz@t(1NXKh*JSE6g7Cb_9m*LTNT`v}}; zZ7v*&_ziRv+yi>|)?@BH{A@_x8F%?C{C=9!?ZoY$+p z&;hWIyzj>0Xn9bxlXve~5!VUz9rrBWSwHV#_zm3cdB%e|_q$sih-M=<4&DcQvPYaD z)OUgPbUnh%A!6tCp3&KK<-$*cLZRNnp8?-7=JQAXDe`_-?$JLDJ~Lzev*2en){lWb z)a5VuBGkII=fGSB)Vg_duSV{h=uhW7LToKRJ$m~mlg8D{vmT+s|Xoedfx5_p_%Mlz=~|Zwkzv4fYj? z+8g2h-TNuj3iWr0vA@ey_u88YP7qf`ccAZ}nZsMtTeIKVP4w)BbZsE#8OlOBuerVS zn5zzT19N5IAoy-mTZVQC{SkGhG~5E8hWGw@b!*h@)t7^-;d-#X9TjuCpd#3l&S$PD zTmtrgiHf;)P#*S%x2{+Bq1E7KXb_s7L#lljwLzRMBi=c4p27QPgEnvu+!)?{`YwSz zEkHf}x{jQ)_keSEgSlhjTXEl9c<*bj7Pu=<`1;{}_g#SZcdcswKPub?Pewl7-<-1r z!FxXpj|Jwk^1pvF=N|oMsQ;U(+|ZxA??&H~{!UZDML9*z3IhMf_Np6q@>rMa@2a?dYk4 zjsoAAzDM;FAzgZVp9gzi4qt&C`p3chx!0Up5q&W7X^%O3t3=H{{WUO{yzjhQV~;uC zea61)RNon@y|W=*3-NEl_|O{6nsdKit%<%%ZaL`fy*YAI@Xp(3PQ3+PNp2+c0R3Xv z1lF9l)*YG>r<%Rao3rNbKCm8q_w_>OM9#kE^v#d>v#8yN>ZigBfjN84Z3br^2>)vM zEvUXTeR}un)h?)K@N??tp*_&IqEG)3{$Rv+5busyZ!KMYqUMhD+{~>bJ_1KWQ~xu> z*8T%O2j)gc&NH}YN8|>vYa?FF4UXM@4r{8phrxRp>(xg>9}RsB_1!p~zU_bV@Bb&x z4j&Sq8+v7EI&ab?^w>KRG6mbnO~ae_e%79c{p96ryl3!Souh@3@pVHx&*=pWc4Y@IAQ$k$-_$%>50&!P}>J&u|zr#QZGOdwCXf_L{S2KKeWA zee?^#XJxFn=KgeLB=<-3zk>e+Ul_d#{t9nhZ_OTORz{C|^{b&wkOMVuPJIKtp4qLS zKM$^hFNiMz-;;X3%Ty~D_3}~o8TxrQ!1>@_y}A+I49@2PXU*xYTl<#zYG{#Dd|rII z>O^fTs&`I*Dddm%Gjs=(0KGN)%-sY9;W+mxi|&q`b-nr}>TC2-wxc7lUVOw{S3T&%7f2xT*Mbp8-2aSmJ*7Z$bUc`FyP0?-Sdc&en z{fn?3HbDz|^!Dq`^@SzitUJA5%Jsvqfv-UCF6(#ccK-;KT}{TWrghgzB*wQ*?gP|xIf-vWDIgXM4^b-nxbhw#?FgJ&TdIb;1%C>*hV zEldD+CZ8+nUz2l(dxww{bN|95_%ZyG&!A_4 zefq3$jQptZ=Jo1mRQznd^A^&V1Jvx~cA-nd?+rhZd=79vd245r`y0)KEt_>Hi?-&w@S9EQ?%T z{AS1>>N88v)1D&WT)Of`d=Yv%tOorJV4wFh_XYc$Jr6#|XNlZRsJwWYmz?n-z&71od z+JLd%-TA?1;PWz{iGPQQJvYOd_)d{ezCQ8o&9Qqk}dyTIpREgxATNv&XzS@9kNpfIHpoS<>a~NaEV4 zJqjh(CuXH^`>~7zIqfvX;z`O7k_^var zcb7Hq;eKbmhrL5k&tzVI0RJaE8s5DAadA!$&ZjSZ`fF0)C2EzYV_? z=EF`%*Ao1xHRnguKNb#CGuH3M?*ePdJ8MrqaueZOy#2|WPuK6%3J|{l`paP%_}Tp2 z&RKgA&IV)sOYlw9^>eHdn>zwNgEar&8gp~$@w1yRhA#!?^o!s^aKHXTdM-z$H27?s zI}X+glFJOm!Q3aHH>Y>c3j8X_3C8+!AUnJn-X3>ZH+LyihHRnEdjEI8ntl5Bz#c!d z&(plQjZhQ(EGciU8tkL@`taq@vO?|!>ga64WJQ} z1bfnDkGb7okG<}8&YWlVbEm5%z6R_Cy?y$dxu@^RW}(^n2V3@&KLV}bhtT@eGlegY zHUYJ1sQa9G@|4)wtDq9x6Zv$WU!vxm{x@)^vA!ELhaS)(I1d$T={kT15rCPJsd3)6}Q1P=FXNi1PRQ!zDQ9qM)eSdss$Qj-l=lj7h zu+LhV$Qhqc?2NfQ_@U9Kx1KjNA9^LVkzkMetPMnagS7$S??9h|bUACT2x^ae^)KVE z37$dS{WPS@-QFi%58$0~z6A50-Or}CmaaPZc`zOHeZ%|itc_2X@2q;nS21so?=EBC zRjThO)%)4wPR}zc^jdQI)e+lgu65-6On#mT@EBC1rk@1q`!H7vo{Ju5$3S~V7*K9bw$^bn-A{x9Mmt|2|mTgvv_jN4yzzPH)ax3W&mzr@z{em0-m95lC{yk4D)%8$`MKk^GuKa+FbTlH+JJw;&|lmvT? z|9eko*lX=dI7Yl3^edqtSl6qoB9{?uMBiticg9+#;1aY()YIqmv)l-tUHxBIacXCS zXFRp9JahZO-wCQeJE}i3s-IPLM*ReJm*>{2ThL0>et-+{*GGOE>a%gyzR%IiBX-7K z^IxE;)|?%`!DZ3+HLC9!`3jMD&YHS6bRXJ0>hAPj)|~kktl4AioVj$ynSb%m{}VTX zittnTIuYL#>YTNn5qCpdLyL%iL(SQz{{!4%tXGes;!fi~RdB~se9pY6zw=dV-pf9F z20~}Z*#4w9uOC3}LFg1ZGBiun?9;1R(Wz0N9QqJiA7(|oF!c4%(|@jVv%{IUqwY@6 z;C^drp3uCgzAbfW1Eaz7z8YGHx@X=H@u#8gv8G;(&WpS|{jBdr+#MYRmy!3g*{^>X z-wT|zr$pqe>(!E>rBJ=kq#QZ{{R%v%eJM9M;wxgV0;>1f*;fhw%_(!0i9d_@QFM0n zT}^&R{>#2DrN>{Qtc=FjEyg=RQ=- zwS&5FD7^PdpWB@8P~WHCJLM1K-E#!>U6?iEAJBeK8+><}uLFK&d-cxxGiOhBNY@?s zYa^#W2JZ4cdiBrHztA4w-Wj2{pm%~jdi(!H?}kS37}!57bXlmo>>0#)3!%2OlB zqJAdtH2~^^@5sy0!Qj53FbK}0SHB$0KN0FaYrYFhky{aYcf0ech&PAYpO0EWc!b>B zk@vHBj&TwDZmf*AzaYJ8A+$faNpLBC4C=0)=p67|_E}SlqJCEQrr9U)Pe)&IYBM9& zTPqzo=k@OP^B2Y6g;qfQPCUDL&)|9Nw^j-KE{yfQ6Ma`2S0-M7p8)z{Xw}GB*Ix^> zqF-n-PoPH zIlse3sNb1=`X=CaW~}$@e!koAekbPjx5LK~>&-V0ZGp;1)O{EFjYA^a;M|+35$DC^Jb85SxPk8hC zzVJPHWBnWWFC)H>_p_ucnG^bI9%&t78B=5z5(sx#)FLARmq(~pYSntkTY{e$;+{StGLA4}{z zb3XAGVD0bl*7Ot6bHP1&@8w?4<~>forjtKT-hTZII1#blU7jOdN2&b=v&iY4)2p-5 zd2k81(>e3zto=@|3akh3VcmC=vF{qSZm7L!ekpyK;S6x!GIS*r0q